summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore274
-rw-r--r--BUILD/FINISH.sh9
-rw-r--r--BUILD/Makefile.am44
-rw-r--r--BUILD/SETUP.sh26
-rwxr-xr-xBUILD/compile-alpha-cxx10
-rwxr-xr-xBUILD/compile-alpha-debug7
-rwxr-xr-xBUILD/compile-ia64-debug-max13
-rwxr-xr-xBUILD/compile-irix-mips64-mipspro84
-rwxr-xr-xBUILD/compile-pentium-debug2
-rwxr-xr-xBUILD/compile-pentium-debug-max2
-rwxr-xr-xBUILD/compile-pentium-debug-no-bdb2
-rwxr-xr-xBUILD/compile-pentium-debug-openssl13
-rwxr-xr-xBUILD/compile-pentium-gcov1
-rwxr-xr-xBUILD/compile-pentium-max3
-rwxr-xr-xBUILD/compile-pentium-mysqlfs-debug13
-rwxr-xr-xBUILD/compile-pentium-pgcc23
-rwxr-xr-xBUILD/compile-pentium-symbols15
-rwxr-xr-xBUILD/compile-pentium-valgrind-max28
-rwxr-xr-xBUILD/compile-solaris-sparc2
-rwxr-xr-xBUILD/compile-solaris-sparc-debug16
-rwxr-xr-xBUILD/compile-solaris-sparc-forte39
-rwxr-xr-xBUILD/compile-solaris-sparc-fortre19
-rwxr-xr-xBUILD/compile-solaris-sparc-purify19
-rw-r--r--BitKeeper/etc/config2
-rw-r--r--BitKeeper/etc/gone1252
-rw-r--r--BitKeeper/etc/logging_ok88
-rw-r--r--BitKeeper/etc/skipkeys1
-rwxr-xr-xBitKeeper/triggers/post-commit26
-rwxr-xr-xBuild-tools/Bootstrap425
-rwxr-xr-xBuild-tools/Do-all-build-steps8
-rwxr-xr-xBuild-tools/Do-compile46
-rwxr-xr-xBuild-tools/Do-linux-build3
-rwxr-xr-xBuild-tools/Do-patch-file4
-rwxr-xr-xBuild-tools/Do-pkg304
-rwxr-xr-xBuild-tools/Do-rpm475
-rwxr-xr-xBuild-tools/Do-win-build82
-rw-r--r--Build-tools/logger.pm105
-rw-r--r--Docs/Flags/argentina.eps149
-rw-r--r--Docs/Flags/argentina.gifbin348 -> 187 bytes
-rw-r--r--Docs/Flags/argentina.pdfbin0 -> 923 bytes
-rw-r--r--Docs/Flags/armenia.eps256
-rwxr-xr-xDocs/Flags/armenia.gifbin0 -> 117 bytes
-rw-r--r--Docs/Flags/armenia.txt (renamed from Docs/Flags/island.eps)0
-rw-r--r--Docs/Flags/australia.eps145
-rw-r--r--Docs/Flags/australia.gifbin689 -> 663 bytes
-rw-r--r--Docs/Flags/australia.pdfbin0 -> 1382 bytes
-rw-r--r--Docs/Flags/austria.eps109
-rw-r--r--Docs/Flags/austria.gifbin132 -> 132 bytes
-rw-r--r--Docs/Flags/austria.pdfbin0 -> 816 bytes
-rw-r--r--Docs/Flags/belgium.eps98
-rw-r--r--Docs/Flags/belgium.gifbin0 -> 116 bytes
-rw-r--r--Docs/Flags/belgium.pdfbin0 -> 790 bytes
-rw-r--r--Docs/Flags/belgium.txt (renamed from Docs/Flags/island.gif)0
-rw-r--r--Docs/Flags/bulgaria.eps109
-rw-r--r--Docs/Flags/bulgaria.gifbin141 -> 141 bytes
-rw-r--r--Docs/Flags/bulgaria.pdfbin0 -> 821 bytes
-rw-r--r--Docs/Flags/canada.eps149
-rw-r--r--Docs/Flags/canada.gifbin407 -> 411 bytes
-rw-r--r--Docs/Flags/canada.pdfbin0 -> 1103 bytes
-rw-r--r--Docs/Flags/chile.eps115
-rw-r--r--Docs/Flags/chile.gifbin370 -> 256 bytes
-rw-r--r--Docs/Flags/chile.pdfbin0 -> 978 bytes
-rw-r--r--Docs/Flags/china.eps93
-rw-r--r--Docs/Flags/china.gifbin224 -> 227 bytes
-rw-r--r--Docs/Flags/china.pdfbin0 -> 945 bytes
-rw-r--r--Docs/Flags/costa-rica.eps98
-rw-r--r--Docs/Flags/costa-rica.gifbin0 -> 147 bytes
-rw-r--r--Docs/Flags/costa-rica.pdfbin0 -> 845 bytes
-rw-r--r--Docs/Flags/costa-rica.txt (renamed from Docs/Flags/island.txt)0
-rw-r--r--Docs/Flags/czech-republic.eps137
-rw-r--r--Docs/Flags/czech-republic.gifbin248 -> 180 bytes
-rw-r--r--Docs/Flags/czech-republic.pdfbin0 -> 936 bytes
-rw-r--r--Docs/Flags/denmark.eps149
-rw-r--r--Docs/Flags/denmark.gifbin253 -> 204 bytes
-rw-r--r--Docs/Flags/denmark.pdfbin0 -> 1011 bytes
-rw-r--r--Docs/Flags/estonia.eps103
-rw-r--r--Docs/Flags/estonia.gifbin126 -> 126 bytes
-rw-r--r--Docs/Flags/estonia.pdfbin0 -> 820 bytes
-rw-r--r--Docs/Flags/finland.eps149
-rw-r--r--Docs/Flags/finland.gifbin192 -> 131 bytes
-rw-r--r--Docs/Flags/finland.pdfbin0 -> 834 bytes
-rw-r--r--Docs/Flags/france.eps149
-rw-r--r--Docs/Flags/france.gifbin158 -> 146 bytes
-rw-r--r--Docs/Flags/france.pdfbin0 -> 796 bytes
-rw-r--r--Docs/Flags/germany.eps79
-rw-r--r--Docs/Flags/germany.gifbin126 -> 126 bytes
-rw-r--r--Docs/Flags/germany.pdfbin0 -> 804 bytes
-rw-r--r--Docs/Flags/great-britain.eps141
-rw-r--r--Docs/Flags/great-britain.gifbin1193 -> 511 bytes
-rw-r--r--Docs/Flags/great-britain.pdfbin0 -> 1348 bytes
-rw-r--r--Docs/Flags/greece.eps149
-rw-r--r--Docs/Flags/greece.gifbin282 -> 267 bytes
-rw-r--r--Docs/Flags/greece.pdfbin0 -> 1006 bytes
-rw-r--r--Docs/Flags/hungary.eps109
-rw-r--r--Docs/Flags/hungary.gifbin141 -> 141 bytes
-rw-r--r--Docs/Flags/hungary.pdfbin0 -> 822 bytes
-rw-r--r--Docs/Flags/iceland.eps141
-rw-r--r--Docs/Flags/iceland.gifbin197 -> 159 bytes
-rw-r--r--Docs/Flags/iceland.pdfbin0 -> 867 bytes
-rw-r--r--Docs/Flags/indonesia.eps98
-rw-r--r--Docs/Flags/indonesia.gifbin133 -> 113 bytes
-rw-r--r--Docs/Flags/indonesia.pdfbin0 -> 804 bytes
-rw-r--r--Docs/Flags/ireland.eps149
-rw-r--r--Docs/Flags/ireland.gifbin158 -> 146 bytes
-rw-r--r--Docs/Flags/ireland.pdfbin0 -> 794 bytes
-rw-r--r--Docs/Flags/italy.eps149
-rw-r--r--Docs/Flags/italy.gifbin158 -> 146 bytes
-rw-r--r--Docs/Flags/italy.pdfbin0 -> 794 bytes
-rw-r--r--Docs/Flags/japan.eps149
-rw-r--r--Docs/Flags/japan.gifbin357 -> 192 bytes
-rw-r--r--Docs/Flags/japan.pdfbin0 -> 971 bytes
-rw-r--r--Docs/Flags/latvia.eps137
-rw-r--r--Docs/Flags/latvia.gifbin117 -> 126 bytes
-rw-r--r--Docs/Flags/latvia.pdfbin0 -> 819 bytes
-rw-r--r--Docs/Flags/mexico.eps98
-rw-r--r--Docs/Flags/mexico.gifbin0 -> 615 bytes
-rw-r--r--Docs/Flags/mexico.pdfbin0 -> 1072 bytes
-rw-r--r--Docs/Flags/mexico.txt (renamed from Docs/Flags/kroatia.eps)0
-rw-r--r--Docs/Flags/netherlands.eps143
-rw-r--r--Docs/Flags/netherlands.gifbin141 -> 141 bytes
-rw-r--r--Docs/Flags/netherlands.pdfbin0 -> 824 bytes
-rw-r--r--Docs/Flags/new-zealand.eps98
-rw-r--r--Docs/Flags/new-zealand.gifbin0 -> 661 bytes
-rw-r--r--Docs/Flags/new-zealand.pdfbin0 -> 1331 bytes
-rw-r--r--Docs/Flags/new-zealand.txt (renamed from Docs/Flags/kroatia.gif)0
-rwxr-xr-xDocs/Flags/norway.eps98
-rwxr-xr-xDocs/Flags/norway.gifbin0 -> 159 bytes
-rw-r--r--Docs/Flags/norway.pdfbin0 -> 864 bytes
-rw-r--r--Docs/Flags/norway.txt (renamed from Docs/Flags/kroatia.txt)0
-rw-r--r--Docs/Flags/philippines.eps98
-rw-r--r--Docs/Flags/philippines.gifbin0 -> 620 bytes
-rw-r--r--Docs/Flags/philippines.pdfbin0 -> 1197 bytes
-rw-r--r--Docs/Flags/philippines.txt (renamed from Docs/Flags/south-africa1.txt)0
-rw-r--r--Docs/Flags/poland.eps115
-rw-r--r--Docs/Flags/poland.gifbin132 -> 113 bytes
-rw-r--r--Docs/Flags/poland.pdfbin0 -> 809 bytes
-rw-r--r--Docs/Flags/portugal.eps147
-rw-r--r--Docs/Flags/portugal.gifbin633 -> 628 bytes
-rw-r--r--Docs/Flags/portugal.pdfbin0 -> 1189 bytes
-rw-r--r--Docs/Flags/romania.eps149
-rw-r--r--Docs/Flags/romania.gifbin158 -> 158 bytes
-rw-r--r--Docs/Flags/romania.pdfbin0 -> 798 bytes
-rw-r--r--Docs/Flags/russia.eps143
-rw-r--r--Docs/Flags/russia.gifbin141 -> 141 bytes
-rw-r--r--Docs/Flags/russia.pdfbin0 -> 829 bytes
-rw-r--r--Docs/Flags/singapore.eps149
-rw-r--r--Docs/Flags/singapore.gifbin389 -> 377 bytes
-rw-r--r--Docs/Flags/singapore.pdfbin0 -> 1056 bytes
-rwxr-xr-xDocs/Flags/slovenia.eps98
-rw-r--r--Docs/Flags/slovenia.gifbin0 -> 609 bytes
-rw-r--r--Docs/Flags/slovenia.pdfbin0 -> 1133 bytes
-rwxr-xr-x[-rw-r--r--]Docs/Flags/slovenia.txt (renamed from mit-pthreads/machdep/linux-2.0/extra/bits/pthreadtypes.h)0
-rw-r--r--Docs/Flags/south-africa.eps141
-rw-r--r--Docs/Flags/south-africa.gifbin650 -> 415 bytes
-rw-r--r--Docs/Flags/south-africa.pdfbin0 -> 1151 bytes
-rw-r--r--Docs/Flags/south-africa1.eps87
-rw-r--r--Docs/Flags/south-africa1.gifbin650 -> 0 bytes
-rw-r--r--Docs/Flags/south-korea.eps149
-rw-r--r--Docs/Flags/south-korea.gifbin663 -> 669 bytes
-rw-r--r--Docs/Flags/south-korea.pdfbin0 -> 1444 bytes
-rw-r--r--Docs/Flags/spain.eps111
-rw-r--r--Docs/Flags/spain.gifbin138 -> 132 bytes
-rw-r--r--Docs/Flags/spain.pdfbin0 -> 809 bytes
-rw-r--r--Docs/Flags/sweden.eps145
-rw-r--r--Docs/Flags/sweden.gifbin193 -> 131 bytes
-rw-r--r--Docs/Flags/sweden.pdfbin0 -> 837 bytes
-rw-r--r--Docs/Flags/switzerland.eps121
-rw-r--r--Docs/Flags/switzerland.gifbin237 -> 135 bytes
-rw-r--r--Docs/Flags/switzerland.pdfbin0 -> 844 bytes
-rw-r--r--Docs/Flags/taiwan.eps115
-rw-r--r--Docs/Flags/taiwan.gifbin377 -> 371 bytes
-rw-r--r--Docs/Flags/taiwan.pdfbin0 -> 1050 bytes
-rw-r--r--Docs/Flags/turkey.eps98
-rw-r--r--Docs/Flags/turkey.gifbin0 -> 344 bytes
-rw-r--r--Docs/Flags/turkey.pdfbin0 -> 987 bytes
-rw-r--r--Docs/Flags/turkey.txt (renamed from mit-pthreads/machdep/linux-2.0/socketcall.h)0
-rw-r--r--Docs/Flags/ukraine.eps133
-rw-r--r--Docs/Flags/ukraine.gifbin132 -> 113 bytes
-rw-r--r--Docs/Flags/ukraine.pdfbin0 -> 810 bytes
-rw-r--r--Docs/Flags/usa.eps145
-rw-r--r--Docs/Flags/usa.gifbin731 -> 717 bytes
-rw-r--r--Docs/Flags/usa.pdfbin0 -> 1444 bytes
-rw-r--r--Docs/Flags/yugoslavia.eps98
-rw-r--r--Docs/Flags/yugoslavia.gifbin250 -> 141 bytes
-rw-r--r--Docs/Flags/yugoslavia.pdfbin0 -> 829 bytes
-rw-r--r--Docs/Images/mysql-logo.gifbin3082 -> 13197 bytes
-rw-r--r--Docs/Makefile.am132
-rwxr-xr-xDocs/Support/colspec-fix.pl78
-rwxr-xr-xDocs/Support/docbook-fixup.pl200
-rwxr-xr-xDocs/Support/docbook-prefix.pl50
-rwxr-xr-xDocs/Support/docbook-split70
-rwxr-xr-xDocs/Support/generate-flag-images46
-rwxr-xr-xDocs/Support/generate-text-files.pl9
-rwxr-xr-xDocs/Support/make-docbook29
-rwxr-xr-xDocs/Support/test-make-manual-de137
-rw-r--r--Docs/Support/trivial-makeinfo-4.0c.patch11
-rwxr-xr-xDocs/Support/update-reserved-words.pl98
-rwxr-xr-xDocs/Support/xwf67
-rw-r--r--Docs/bk.txt10
-rw-r--r--Docs/manual.de.texi107
-rw-r--r--Docs/manual.ja.texi4
-rw-r--r--Docs/manual_toc.html9
-rw-r--r--Docs/mirrors.texi446
-rw-r--r--Docs/my_sys.txt140
-rw-r--r--Docs/mysqld_error.txt128
-rw-r--r--Docs/section.Infolinks.texi880
-rw-r--r--Docs/section.Testimonials.texi31
-rw-r--r--Docs/section.Users.texi414
-rw-r--r--Images/.cvsignore1
-rw-r--r--Makefile.am41
-rw-r--r--README18
-rw-r--r--SSL/NOTES376
-rw-r--r--SSL/cacert.pem21
-rw-r--r--SSL/client-cert.pem67
-rw-r--r--SSL/client-key.pem15
-rw-r--r--SSL/client-req.pem12
-rwxr-xr-xSSL/run-client10
-rwxr-xr-xSSL/run-server9
-rw-r--r--SSL/server-cert.pem67
-rw-r--r--SSL/server-key.pem15
-rw-r--r--SSL/server-req.pem12
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/Component Definitions/.fgl37
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/Component Definitions/Default.cdf192
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/File Groups/Clients and Tools.fgl35
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/File Groups/Default.fdf82
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/File Groups/Default.fgl4
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/File Groups/Development.fgl190
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/File Groups/Documentation.fgl98
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/File Groups/Servers.fgl183
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/MySQL 3.23.com.ipr51
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.rul641
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt24
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/String Tables/0009-English/value.shl23
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/String Tables/Default.shl74
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/Text Substitutions/Build.tsb56
-rw-r--r--VC++Files/InstallShield/3.23.XX-com/Text Substitutions/Setup.tsb76
-rw-r--r--VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/.fgl37
-rw-r--r--VC++Files/InstallShield/3.23.XX-gpl/File Groups/Clients and Tools.fgl35
-rw-r--r--VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fgl4
-rw-r--r--VC++Files/InstallShield/3.23.XX-gpl/File Groups/Development.fgl191
-rw-r--r--VC++Files/InstallShield/3.23.XX-gpl/File Groups/Servers.fgl184
-rw-r--r--VC++Files/InstallShield/3.23.XX-gpl/MySQL 3.23.XX-GPL.ipr51
-rw-r--r--VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.rul641
-rw-r--r--VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt24
-rw-r--r--VC++Files/InstallShield/3.23.XX-gpl/String Tables/0009-English/value.shl23
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-classic/4.0.XX-classic.ipr51
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Component Definitions/Default.cdf (renamed from VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.cdf)0
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Component Definitions/Default.fgl (renamed from VC++Files/InstallShield/3.23.XX-com/Component Definitions/Default.fgl)0
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-classic/File Groups/Clients and Tools.fgl31
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/File Groups/Default.fdf (renamed from VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fdf)0
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-classic/File Groups/Development.fgl239
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/File Groups/Documentation.fgl (renamed from VC++Files/InstallShield/3.23.XX-gpl/File Groups/Documentation.fgl)0
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/File Groups/Grant Tables.fgl (renamed from VC++Files/InstallShield/3.23.XX-com/File Groups/Grant Tables.fgl)0
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-classic/File Groups/Servers.fgl226
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Registry Entries/Default.rge (renamed from VC++Files/InstallShield/3.23.XX-com/Registry Entries/Default.rge)0
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.dbg (renamed from VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.dbg)bin28458 -> 28458 bytes
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.ino (renamed from VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.ino)bin58611 -> 58611 bytes
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.ins (renamed from VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.ins)bin57122 -> 57122 bytes
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.obs (renamed from VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.obs)bin65611 -> 65611 bytes
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.rul640
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-classic/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt25
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Setup Files/Uncompressed Files/Language Independent/OS Independent/setup.bmp (renamed from VC++Files/InstallShield/3.23.XX-com/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP)bin15694 -> 15694 bytes
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Shell Objects/Default.shl (renamed from VC++Files/InstallShield/3.23.XX-com/Shell Objects/Default.shl)0
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-classic/String Tables/0009-English/value.shl23
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/String Tables/Default.shl (renamed from VC++Files/InstallShield/3.23.XX-gpl/String Tables/Default.shl)0
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Text Substitutions/Build.tsb (renamed from VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Build.tsb)0
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-classic/Text Substitutions/Setup.tsb (renamed from VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Setup.tsb)0
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/4.0.XX-gpl.ipr51
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/Component Definitions/Default.cdf192
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-gpl/Component Definitions/Default.fgl (renamed from VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.fgl)0
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/File Groups/Clients and Tools.fgl31
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/File Groups/Default.fdf82
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/File Groups/Development.fgl241
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/File Groups/Documentation.fgl101
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-gpl/File Groups/Grant Tables.fgl (renamed from VC++Files/InstallShield/3.23.XX-gpl/File Groups/Grant Tables.fgl)0
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/File Groups/Servers.fgl229
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-gpl/Registry Entries/Default.rge (renamed from VC++Files/InstallShield/3.23.XX-gpl/Registry Entries/Default.rge)0
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.dbg (renamed from VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.dbg)bin28458 -> 28458 bytes
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.ino (renamed from VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ino)bin58611 -> 58611 bytes
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.ins (renamed from VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ins)bin57122 -> 57122 bytes
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.obs (renamed from VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.obs)bin65611 -> 65611 bytes
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.rul640
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt25
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-gpl/Setup Files/Uncompressed Files/Language Independent/OS Independent/setup.bmp (renamed from VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP)bin15694 -> 15694 bytes
-rwxr-xr-x[-rw-r--r--]VC++Files/InstallShield/4.0.XX-gpl/Shell Objects/Default.shl (renamed from VC++Files/InstallShield/3.23.XX-gpl/Shell Objects/Default.shl)0
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/String Tables/0009-English/value.shl23
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/String Tables/Default.shl74
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/Text Substitutions/Build.tsb56
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-gpl/Text Substitutions/Setup.tsb76
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/4.0.XX-pro.ipr52
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Component Definitions/Default.cdf192
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Component Definitions/Default.fgl42
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/File Groups/Clients and Tools.fgl31
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/File Groups/Default.fdf82
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/File Groups/Development.fgl239
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/File Groups/Documentation.fgl99
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/File Groups/Grant Tables.fgl36
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/File Groups/Servers.fgl226
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Registry Entries/Default.rge4
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.dbgbin0 -> 28458 bytes
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.inobin0 -> 58611 bytes
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.insbin0 -> 57122 bytes
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.obsbin0 -> 65611 bytes
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.rul640
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt25
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Setup Files/Uncompressed Files/Language Independent/OS Independent/setup.bmpbin0 -> 15694 bytes
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Shell Objects/Default.shl12
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/String Tables/0009-English/value.shl23
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/String Tables/Default.shl74
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Text Substitutions/Build.tsb56
-rwxr-xr-xVC++Files/InstallShield/4.0.XX-pro/Text Substitutions/Setup.tsb76
-rw-r--r--VC++Files/InstallShield/Script Files/Setup.dbgbin0 -> 28458 bytes
-rw-r--r--VC++Files/InstallShield/Script Files/Setup.inobin0 -> 58611 bytes
-rw-r--r--VC++Files/InstallShield/Script Files/Setup.insbin0 -> 57122 bytes
-rw-r--r--VC++Files/InstallShield/Script Files/Setup.obsbin0 -> 65611 bytes
-rw-r--r--VC++Files/InstallShield/Script Files/Setup.rul640
-rw-r--r--VC++Files/bdb/bdb.dsp1360
-rw-r--r--VC++Files/bdb/build_win32/Berkeley_DB.dsw1
-rw-r--r--VC++Files/bdb/build_win32/db_archive.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_buildall.dsp16
-rw-r--r--VC++Files/bdb/build_win32/db_checkpoint.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_deadlock.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_dll.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_dump.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_java.dsp58
-rw-r--r--VC++Files/bdb/build_win32/db_load.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_printlog.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_recover.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_stat.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_static.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_static1.dsp85
-rw-r--r--VC++Files/bdb/build_win32/db_tcl.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_test.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_upgrade.dsp14
-rw-r--r--VC++Files/bdb/build_win32/db_verify.dsp14
-rw-r--r--VC++Files/bdb/build_win32/ex_access.dsp14
-rw-r--r--VC++Files/bdb/build_win32/ex_btrec.dsp14
-rw-r--r--VC++Files/bdb/build_win32/ex_env.dsp14
-rw-r--r--VC++Files/bdb/build_win32/ex_lock.dsp14
-rw-r--r--VC++Files/bdb/build_win32/ex_mpool.dsp14
-rw-r--r--VC++Files/bdb/build_win32/ex_tpcb.dsp14
-rw-r--r--VC++Files/bdb/build_win32/excxx_access.dsp14
-rw-r--r--VC++Files/bdb/build_win32/excxx_btrec.dsp14
-rw-r--r--VC++Files/bdb/build_win32/excxx_env.dsp14
-rw-r--r--VC++Files/bdb/build_win32/excxx_lock.dsp14
-rw-r--r--VC++Files/bdb/build_win32/excxx_mpool.dsp14
-rw-r--r--VC++Files/bdb/build_win32/excxx_tpcb.dsp14
-rw-r--r--VC++Files/bdb/build_win32/libdb.def151
-rw-r--r--VC++Files/bdb/build_win32/libdb_tcl.def35
-rw-r--r--VC++Files/client/mysql.dsp29
-rw-r--r--VC++Files/client/mysqladmin.dsp23
-rw-r--r--VC++Files/client/mysqlcheck.dsp12
-rw-r--r--VC++Files/client/mysqlclient.dsp91
-rw-r--r--VC++Files/client/mysqlclient.dsw1
-rw-r--r--VC++Files/client/mysqldump.dsp27
-rw-r--r--VC++Files/client/mysqlimport.dsp23
-rw-r--r--VC++Files/client/mysqlshow.dsp25
-rw-r--r--VC++Files/comp_err/comp_err.dsp20
-rw-r--r--VC++Files/contrib/asm386/zlibvc.dsp76
-rw-r--r--VC++Files/contrib/asm386/zlibvc.dsw1
-rw-r--r--VC++Files/contrib/minizip/zlibvc.dsp76
-rw-r--r--VC++Files/contrib/minizip/zlibvc.dsw1
-rw-r--r--VC++Files/dbug/dbug.dsp14
-rw-r--r--VC++Files/dbug/dbug.dsw1
-rw-r--r--VC++Files/heap/heap.dsp16
-rw-r--r--VC++Files/innobase/innobase.dsp111
-rw-r--r--VC++Files/isam/isam.dsp14
-rw-r--r--VC++Files/isam/isam.dsw1
-rw-r--r--VC++Files/isamchk/isamchk.dsp23
-rw-r--r--VC++Files/libmysql/libmySQL.dsp440
-rw-r--r--VC++Files/libmysql/libmysql.dsp489
-rw-r--r--VC++Files/libmysql/libmysql.dsw3
-rw-r--r--VC++Files/libmysqld/examples/test_libmysqld.dsp66
-rw-r--r--VC++Files/libmysqld/libmysqld.def65
-rw-r--r--VC++Files/libmysqld/libmysqld.dsp409
-rw-r--r--VC++Files/libmysqltest/myTest-package.dsp92
-rw-r--r--VC++Files/libmysqltest/myTest.dsp23
-rw-r--r--VC++Files/libmysqltest/mytest.c339
-rw-r--r--VC++Files/libmysqltest/mytest.dsw1
-rw-r--r--VC++Files/merge/merge.dsp46
-rw-r--r--VC++Files/merge/merge.dsw1
-rw-r--r--VC++Files/my_print_defaults/my_print_defaults.dsp36
-rw-r--r--VC++Files/myisam/myisam.dsp24
-rw-r--r--VC++Files/myisamchk/myisamchk.dsp14
-rw-r--r--VC++Files/myisamlog/myisamlog.dsp24
-rw-r--r--VC++Files/myisammrg/myisammrg.dsp22
-rw-r--r--VC++Files/myisampack/myisampack.dsp14
-rw-r--r--VC++Files/mysql.dsp16
-rw-r--r--VC++Files/mysql.dsw181
-rw-r--r--VC++Files/mysqlbinlog/mysqlbinlog.dsp32
-rw-r--r--VC++Files/mysqlcheck/mysqlcheck.dsp102
-rw-r--r--VC++Files/mysqldemb/mysqldemb.dsp386
-rw-r--r--VC++Files/mysqlmanager/CHILDFRM.CPP65
-rw-r--r--VC++Files/mysqlmanager/CHILDFRM.H52
-rw-r--r--VC++Files/mysqlmanager/MAINFRM.CPP137
-rw-r--r--VC++Files/mysqlmanager/MAINFRM.H69
-rw-r--r--VC++Files/mysqlmanager/MySqlManager.dsp23
-rw-r--r--VC++Files/mysqlmanager/MySqlManager.mak327
-rw-r--r--VC++Files/mysqlmanager/README.TXT102
-rw-r--r--VC++Files/mysqlmanager/RES/BITMAP1.BMPbin0 -> 630 bytes
-rw-r--r--VC++Files/mysqlmanager/RES/BITMAP3.BMPbin0 -> 630 bytes
-rw-r--r--VC++Files/mysqlmanager/RES/BMP00001.BMPbin0 -> 246 bytes
-rw-r--r--VC++Files/mysqlmanager/RES/BMP00002.BMPbin0 -> 238 bytes
-rw-r--r--VC++Files/mysqlmanager/RES/DATABASE.BMPbin0 -> 238 bytes
-rw-r--r--VC++Files/mysqlmanager/RES/FONTD.BMPbin0 -> 246 bytes
-rw-r--r--VC++Files/mysqlmanager/RES/FONTU.BMPbin0 -> 246 bytes
-rw-r--r--VC++Files/mysqlmanager/RES/QUERY_EX.BMPbin0 -> 246 bytes
-rw-r--r--VC++Files/mysqlmanager/RES/TOOLBAR.BMPbin0 -> 1078 bytes
-rw-r--r--VC++Files/mysqlmanager/RES/mysqlmanager.icobin0 -> 1078 bytes
-rw-r--r--VC++Files/mysqlmanager/RES/mysqlmanager.rc213
-rw-r--r--VC++Files/mysqlmanager/RES/mysqlmanagerdoc.icobin0 -> 1078 bytes
-rw-r--r--VC++Files/mysqlmanager/RESOURCE.H55
-rw-r--r--VC++Files/mysqlmanager/STDAFX.CPP5
-rw-r--r--VC++Files/mysqlmanager/STDAFX.H28
-rw-r--r--VC++Files/mysqlmanager/TOOLSQL.CPP687
-rw-r--r--VC++Files/mysqlmanager/TOOLSQL.H102
-rw-r--r--VC++Files/mysqlmanager/cresource.h134
-rw-r--r--VC++Files/mysqlmanager/mysqlmanager.cpp168
-rw-r--r--VC++Files/mysqlmanager/mysqlmanager.dsw1
-rw-r--r--VC++Files/mysqlmanager/mysqlmanager.h50
-rw-r--r--VC++Files/mysqlmanager/mysqlmanager.rc572
-rw-r--r--VC++Files/mysqlmanager/mysqlmanagerdoc.cpp84
-rw-r--r--VC++Files/mysqlmanager/mysqlmanagerdoc.h57
-rw-r--r--VC++Files/mysqlmanager/mysqlmanagerview.cpp849
-rw-r--r--VC++Files/mysqlmanager/mysqlmanagerview.h89
-rw-r--r--VC++Files/mysqlmanager/registerserver.cpp51
-rw-r--r--VC++Files/mysqlmanager/registerserver.h50
-rw-r--r--VC++Files/mysqlmanager/toolsqlquery.cpp110
-rw-r--r--VC++Files/mysqlmanager/toolsqlquery.h60
-rw-r--r--VC++Files/mysqlmanager/toolsqlresults.cpp73
-rw-r--r--VC++Files/mysqlmanager/toolsqlresults.h53
-rw-r--r--VC++Files/mysqlmanager/toolsqlstatus.cpp50
-rw-r--r--VC++Files/mysqlmanager/toolsqlstatus.h47
-rw-r--r--VC++Files/mysqlserver/mysqlserver.dsp84
-rw-r--r--VC++Files/mysqlshutdown/myshutdown.dsp14
-rw-r--r--VC++Files/mysqlshutdown/mysqlshutdown.dsp24
-rw-r--r--VC++Files/mysqlwatch/mysqlwatch.dsp12
-rw-r--r--VC++Files/mysys/mysys.dsp91
-rw-r--r--VC++Files/mysys/mysys.dsw1
-rw-r--r--VC++Files/pack_isam/pack_isam.dsp23
-rw-r--r--VC++Files/perror/perror.dsp30
-rwxr-xr-xVC++Files/prepare104
-rw-r--r--VC++Files/regex/regex.dsp14
-rw-r--r--VC++Files/regex/regex.dsw1
-rw-r--r--VC++Files/replace/replace.dsp23
-rw-r--r--VC++Files/sql/mysqld.dsp187
-rw-r--r--VC++Files/sql/mysqld.dsw1
-rw-r--r--VC++Files/sql/mysqldmax.dsp112
-rw-r--r--VC++Files/sql/old/mysqld.dsw28
-rw-r--r--VC++Files/strings/MASM6x/strings.dsp18
-rw-r--r--VC++Files/strings/MASM6x/strings.dsw1
-rw-r--r--VC++Files/strings/backup/strings.dsp244
-rw-r--r--VC++Files/strings/backup/strings.dsw28
-rw-r--r--VC++Files/strings/noMASM/strings.dsp18
-rw-r--r--VC++Files/strings/noMASM/strings.dsw1
-rw-r--r--VC++Files/strings/strings.dsp248
-rw-r--r--VC++Files/strings/strings.dsw1
-rw-r--r--VC++Files/test1/mysql_thr.c255
-rw-r--r--VC++Files/test1/test1.dsp24
-rw-r--r--VC++Files/thr_insert_test/thr_insert_test.dsp14
-rw-r--r--VC++Files/thr_test/thr_test.dsp25
-rw-r--r--VC++Files/vio/vio.dsp108
-rw-r--r--VC++Files/winmysqladmin/db.cpp80
-rw-r--r--VC++Files/winmysqladmin/db.h32
-rw-r--r--VC++Files/winmysqladmin/images/Goahead.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/HELP.ICObin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/INFO.ICObin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Info.bmpbin0 -> 644 bytes
-rw-r--r--VC++Files/winmysqladmin/images/MYINI.ICObin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Myini.bmpbin0 -> 644 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Noentry.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/SETUP.BMPbin0 -> 86878 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Setup 16.bmpbin0 -> 86880 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Table.icobin0 -> 1078 bytes
-rw-r--r--VC++Files/winmysqladmin/images/Working.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/database.icobin0 -> 1078 bytes
-rw-r--r--VC++Files/winmysqladmin/images/find.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/green.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/help.bmpbin0 -> 644 bytes
-rw-r--r--VC++Files/winmysqladmin/images/initsetup.cpp42
-rw-r--r--VC++Files/winmysqladmin/images/killdb.icobin0 -> 1078 bytes
-rw-r--r--VC++Files/winmysqladmin/images/logo.icobin0 -> 2022 bytes
-rw-r--r--VC++Files/winmysqladmin/images/multitrg.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/mysql-07.bmpbin0 -> 9618 bytes
-rw-r--r--VC++Files/winmysqladmin/images/mysql-17.bmpbin0 -> 3806 bytes
-rw-r--r--VC++Files/winmysqladmin/images/mysql.BMPbin0 -> 8760 bytes
-rw-r--r--VC++Files/winmysqladmin/images/red.icobin0 -> 766 bytes
-rw-r--r--VC++Files/winmysqladmin/images/red22.BMPbin0 -> 2104 bytes
-rw-r--r--VC++Files/winmysqladmin/images/see.bmpbin0 -> 644 bytes
-rw-r--r--VC++Files/winmysqladmin/initsetup.cpp40
-rw-r--r--VC++Files/winmysqladmin/initsetup.h38
-rw-r--r--VC++Files/winmysqladmin/main.cpp2529
-rw-r--r--VC++Files/winmysqladmin/main.h314
-rw-r--r--VC++Files/winmysqladmin/mysql.h293
-rw-r--r--VC++Files/winmysqladmin/mysql_com.h242
-rw-r--r--VC++Files/winmysqladmin/mysql_version.h20
-rw-r--r--VC++Files/winmysqladmin/winmysqladmin.cpp38
-rw-r--r--VC++Files/zlib/contrib/asm386/zlibvc.dsp651
-rw-r--r--VC++Files/zlib/contrib/asm386/zlibvc.dsw41
-rw-r--r--VC++Files/zlib/zlib.dsp22
-rw-r--r--acconfig.h23
-rw-r--r--acinclude.m4391
-rwxr-xr-xbdb/dist/s_symlink80
-rw-r--r--bdb/include/btree_ext.h122
-rw-r--r--bdb/include/clib_ext.h38
-rw-r--r--bdb/include/common_ext.h44
-rw-r--r--bdb/include/env_ext.h35
-rw-r--r--bdb/include/hash_ext.h106
-rw-r--r--bdb/include/lock_ext.h39
-rw-r--r--bdb/include/log_ext.h33
-rw-r--r--bdb/include/mp_ext.h33
-rw-r--r--bdb/include/os_ext.h62
-rw-r--r--bdb/include/qam_ext.h56
-rw-r--r--bdb/include/tcl_ext.h89
-rw-r--r--bdb/include/txn_ext.h24
-rw-r--r--bdb/include/xa_ext.h17
-rw-r--r--bdb/os/os_handle.c2
-rwxr-xr-xbuild-tags11
-rw-r--r--client/Makefile.am6
-rw-r--r--client/client_priv.h25
-rw-r--r--client/completion_hash.cc75
-rw-r--r--client/completion_hash.h33
-rw-r--r--client/connect_test.c29
-rw-r--r--client/errmsg.c110
-rw-r--r--client/get_password.c57
-rw-r--r--client/insert_test.c37
-rw-r--r--client/list_test.c42
-rw-r--r--client/my_readline.h29
-rw-r--r--client/mysql.cc1509
-rw-r--r--client/mysqladmin.c462
-rw-r--r--client/mysqlbinlog.cc751
-rw-r--r--client/mysqlcheck.c451
-rw-r--r--client/mysqldump.c883
-rw-r--r--client/mysqlimport.c316
-rw-r--r--client/mysqlmanager-pwgen.c161
-rw-r--r--client/mysqlmanagerc.c174
-rw-r--r--client/mysqlshow.c276
-rw-r--r--client/mysqltest.c1987
-rw-r--r--client/password.c192
-rw-r--r--client/readline.cc50
-rw-r--r--client/select_test.c28
-rw-r--r--client/showdb_test.c22
-rw-r--r--client/sql_string.cc31
-rw-r--r--client/sql_string.h29
-rw-r--r--client/ssl_test.c22
-rw-r--r--client/thimble.cc20
-rw-r--r--client/thread_test.c201
-rw-r--r--client/violite.c394
-rwxr-xr-xconfig.guess554
-rwxr-xr-xconfig.sub301
-rw-r--r--configure.in553
-rw-r--r--dbug/dbug.c40
-rwxr-xr-xdbug/dbug_add_tags.pl73
-rw-r--r--dbug/dbug_analyze.c2
-rw-r--r--dbug/example1.c2
-rw-r--r--dbug/example2.c2
-rw-r--r--dbug/example3.c2
-rw-r--r--dbug/factorial.c2
-rw-r--r--dbug/main.c2
-rw-r--r--dbug/sanity.c2
-rw-r--r--div/deadlock_test.c16
-rw-r--r--extra/Makefile.am2
-rw-r--r--extra/comp_err.c35
-rw-r--r--extra/my_print_defaults.c151
-rw-r--r--extra/mysql_install.c218
-rw-r--r--extra/mysql_waitpid.c117
-rw-r--r--extra/perror.c150
-rw-r--r--extra/replace.c31
-rw-r--r--extra/resolve_stack_dump.c252
-rw-r--r--extra/resolveip.c79
-rw-r--r--fs/CorbaFS.idl38
-rw-r--r--fs/Makefile.am93
-rw-r--r--fs/README58
-rwxr-xr-xfs/RunServer.sh2
-rw-r--r--fs/database.c628
-rw-r--r--fs/dump.sql28
-rw-r--r--fs/korbit-kernel-2.4.1-patch35661
-rw-r--r--fs/libmysqlfs.c151
-rw-r--r--fs/libmysqlfs.h81
-rw-r--r--fs/my.cnf5
-rw-r--r--fs/mysqlcorbafs.c998
-rw-r--r--fs/mysqlcorbafs.h157
-rw-r--r--fs/mysqlcorbafs_test.c92
-rwxr-xr-xfs/mysqlfsck11
-rw-r--r--heap/_check.c69
-rw-r--r--heap/_rectest.c6
-rw-r--r--heap/heapdef.h7
-rw-r--r--heap/hp_block.c6
-rw-r--r--heap/hp_clear.c8
-rw-r--r--heap/hp_close.c12
-rw-r--r--heap/hp_create.c44
-rw-r--r--heap/hp_delete.c16
-rw-r--r--heap/hp_extra.c6
-rw-r--r--heap/hp_hash.c94
-rw-r--r--heap/hp_info.c21
-rw-r--r--heap/hp_open.c17
-rw-r--r--heap/hp_panic.c6
-rw-r--r--heap/hp_rename.c6
-rw-r--r--heap/hp_rfirst.c6
-rw-r--r--heap/hp_rkey.c8
-rw-r--r--heap/hp_rlast.c6
-rw-r--r--heap/hp_rnext.c8
-rw-r--r--heap/hp_rprev.c6
-rw-r--r--heap/hp_rrnd.c6
-rw-r--r--heap/hp_rsame.c6
-rw-r--r--heap/hp_scan.c7
-rw-r--r--heap/hp_static.c6
-rw-r--r--heap/hp_test1.c8
-rw-r--r--heap/hp_test2.c51
-rw-r--r--heap/hp_update.c10
-rw-r--r--heap/hp_write.c18
-rw-r--r--include/Makefile.am34
-rw-r--r--include/config-netware.h85
-rw-r--r--include/config-os2.h56
-rw-r--r--include/config-win.h133
-rw-r--r--include/dbug.h94
-rw-r--r--include/errmsg.h43
-rw-r--r--include/ft_global.h44
-rw-r--r--include/getopt.h135
-rw-r--r--include/global.h1006
-rw-r--r--include/hash.h30
-rw-r--r--include/heap.h38
-rw-r--r--include/m_ctype.h96
-rw-r--r--include/m_string.h42
-rw-r--r--include/md5.h93
-rw-r--r--include/merge.h29
-rw-r--r--include/my_aes.h66
-rw-r--r--include/my_alarm.h29
-rw-r--r--include/my_alloc.h52
-rw-r--r--include/my_base.h101
-rw-r--r--include/my_bitmap.h29
-rw-r--r--include/my_dbug.h93
-rw-r--r--include/my_dir.h40
-rw-r--r--include/my_getopt.h54
-rw-r--r--include/my_global.h1138
-rw-r--r--include/my_list.h29
-rw-r--r--include/my_net.h97
-rw-r--r--include/my_no_pthread.h29
-rw-r--r--include/my_nosys.h29
-rw-r--r--include/my_pthread.h102
-rw-r--r--include/my_semaphore.h64
-rw-r--r--include/my_sys.h401
-rw-r--r--include/my_tree.h52
-rw-r--r--include/myisam.h236
-rw-r--r--include/myisammrg.h49
-rw-r--r--include/myisampack.h33
-rw-r--r--include/mysql.h323
-rw-r--r--include/mysql_com.h116
-rw-r--r--include/mysql_embed.h34
-rw-r--r--include/mysql_version.h.in11
-rw-r--r--include/mysqld_error.h23
-rw-r--r--include/mysys_err.h48
-rw-r--r--include/nisam.h29
-rw-r--r--include/queues.h36
-rw-r--r--include/raid.h43
-rw-r--r--include/rijndael.h42
-rw-r--r--include/sha1.h67
-rw-r--r--include/sslopt-case.h53
-rw-r--r--include/sslopt-longopts.h60
-rw-r--r--include/sslopt-usage.h25
-rw-r--r--include/sslopt-vars.h30
-rw-r--r--include/t_ctype.h20
-rw-r--r--include/thr_alarm.h64
-rw-r--r--include/thr_lock.h36
-rw-r--r--include/violite.h217
-rw-r--r--innobase/btr/Makefile.am2
-rw-r--r--innobase/btr/btr0btr.c205
-rw-r--r--innobase/btr/btr0cur.c282
-rw-r--r--innobase/btr/btr0pcur.c8
-rw-r--r--innobase/btr/btr0sea.c116
-rw-r--r--innobase/buf/Makefile.am2
-rw-r--r--innobase/buf/buf0buf.c225
-rw-r--r--innobase/buf/buf0flu.c92
-rw-r--r--innobase/buf/buf0lru.c77
-rw-r--r--innobase/com/Makefile.am2
-rw-r--r--innobase/com/com0shm.c9
-rw-r--r--innobase/configure.in25
-rw-r--r--innobase/data/Makefile.am2
-rw-r--r--innobase/data/data0data.c32
-rw-r--r--innobase/data/data0type.c2
-rw-r--r--innobase/dict/Makefile.am2
-rw-r--r--innobase/dict/dict0boot.c109
-rw-r--r--innobase/dict/dict0crea.c66
-rw-r--r--innobase/dict/dict0dict.c1333
-rw-r--r--innobase/dict/dict0load.c101
-rw-r--r--innobase/dict/dict0mem.c15
-rw-r--r--innobase/dyn/Makefile.am2
-rw-r--r--innobase/eval/Makefile.am2
-rw-r--r--innobase/eval/eval0eval.c8
-rw-r--r--innobase/fil/Makefile.am2
-rw-r--r--innobase/fil/fil0fil.c61
-rw-r--r--innobase/fsp/Makefile.am2
-rw-r--r--innobase/fsp/fsp0fsp.c129
-rw-r--r--innobase/fut/Makefile.am2
-rw-r--r--innobase/ha/Makefile.am2
-rw-r--r--innobase/ha/ha0ha.c8
-rw-r--r--innobase/ibuf/Makefile.am2
-rw-r--r--innobase/ibuf/ibuf0ibuf.c61
-rw-r--r--innobase/include/Makefile.am2
-rw-r--r--innobase/include/Makefile.i4
-rw-r--r--innobase/include/btr0btr.h13
-rw-r--r--innobase/include/btr0btr.ic6
-rw-r--r--innobase/include/btr0cur.h32
-rw-r--r--innobase/include/btr0pcur.h8
-rw-r--r--innobase/include/btr0pcur.ic18
-rw-r--r--innobase/include/btr0sea.h14
-rw-r--r--innobase/include/buf0buf.h48
-rw-r--r--innobase/include/buf0buf.ic7
-rw-r--r--innobase/include/buf0lru.h25
-rw-r--r--innobase/include/data0data.h10
-rw-r--r--innobase/include/data0data.ic25
-rw-r--r--innobase/include/data0type.h66
-rw-r--r--innobase/include/data0type.ic35
-rw-r--r--innobase/include/db0err.h11
-rw-r--r--innobase/include/dict0dict.h86
-rw-r--r--innobase/include/dict0dict.ic3
-rw-r--r--innobase/include/dict0mem.h39
-rw-r--r--innobase/include/dyn0dyn.h1
-rw-r--r--innobase/include/fil0fil.h17
-rw-r--r--innobase/include/ha0ha.ic2
-rw-r--r--innobase/include/lock0lock.h68
-rw-r--r--innobase/include/log0log.h85
-rw-r--r--innobase/include/log0recv.h3
-rw-r--r--innobase/include/mem0mem.h14
-rw-r--r--innobase/include/mem0mem.ic7
-rw-r--r--innobase/include/os0file.h39
-rw-r--r--innobase/include/os0proc.h9
-rw-r--r--innobase/include/os0sync.h86
-rw-r--r--innobase/include/os0sync.ic1
-rw-r--r--innobase/include/os0thread.h22
-rw-r--r--innobase/include/page0cur.h7
-rw-r--r--innobase/include/page0page.h19
-rw-r--r--innobase/include/que0que.h8
-rw-r--r--innobase/include/read0read.h8
-rw-r--r--innobase/include/rem0cmp.h16
-rw-r--r--innobase/include/rem0rec.h12
-rw-r--r--innobase/include/rem0rec.ic18
-rw-r--r--innobase/include/row0ins.h1
-rw-r--r--innobase/include/row0mysql.h64
-rw-r--r--innobase/include/row0mysql.ic7
-rw-r--r--innobase/include/row0row.h7
-rw-r--r--innobase/include/row0sel.h21
-rw-r--r--innobase/include/row0upd.h64
-rw-r--r--innobase/include/row0vers.ic2
-rw-r--r--innobase/include/srv0srv.h49
-rw-r--r--innobase/include/srv0start.h10
-rw-r--r--innobase/include/sync0rw.h3
-rw-r--r--innobase/include/sync0rw.ic3
-rw-r--r--innobase/include/sync0sync.h6
-rw-r--r--innobase/include/trx0purge.h3
-rw-r--r--innobase/include/trx0roll.h64
-rw-r--r--innobase/include/trx0sys.h18
-rw-r--r--innobase/include/trx0sys.ic10
-rw-r--r--innobase/include/trx0trx.h149
-rw-r--r--innobase/include/trx0trx.ic19
-rw-r--r--innobase/include/trx0types.h1
-rw-r--r--innobase/include/univ.i19
-rw-r--r--innobase/include/ut0dbg.h36
-rw-r--r--innobase/include/ut0mem.h4
-rw-r--r--innobase/include/ut0mem.ic2
-rw-r--r--innobase/lock/Makefile.am2
-rw-r--r--innobase/lock/lock0lock.c833
-rw-r--r--innobase/log/Makefile.am2
-rw-r--r--innobase/log/log0log.c332
-rw-r--r--innobase/log/log0recv.c104
-rw-r--r--innobase/mach/Makefile.am2
-rw-r--r--innobase/mem/Makefile.am2
-rw-r--r--innobase/mem/mem0dbg.c18
-rw-r--r--innobase/mem/mem0pool.c93
-rw-r--r--innobase/mtr/Makefile.am2
-rw-r--r--innobase/mtr/mtr0mtr.c8
-rw-r--r--innobase/odbc/Makefile.am2
-rw-r--r--innobase/odbc/odbc0odbc.c2
-rw-r--r--innobase/os/Makefile.am2
-rw-r--r--innobase/os/os0file.c586
-rw-r--r--innobase/os/os0proc.c17
-rw-r--r--innobase/os/os0sync.c327
-rw-r--r--innobase/os/os0thread.c53
-rw-r--r--innobase/page/Makefile.am2
-rw-r--r--innobase/page/page0cur.c122
-rw-r--r--innobase/page/page0page.c337
-rw-r--r--innobase/pars/Makefile.am2
-rw-r--r--innobase/pars/lexyy.c11
-rw-r--r--innobase/pars/pars0grm.c3
-rw-r--r--innobase/pars/pars0grm.y2
-rw-r--r--innobase/pars/pars0lex.l3
-rw-r--r--innobase/pars/pars0opt.c13
-rw-r--r--innobase/pars/pars0pars.c10
-rw-r--r--innobase/que/Makefile.am2
-rw-r--r--innobase/que/que0que.c70
-rw-r--r--innobase/read/Makefile.am2
-rw-r--r--innobase/read/read0read.c22
-rw-r--r--innobase/rem/Makefile.am2
-rw-r--r--innobase/rem/rem0cmp.c119
-rw-r--r--innobase/rem/rem0rec.c4
-rw-r--r--innobase/row/Makefile.am2
-rw-r--r--innobase/row/row0ins.c832
-rw-r--r--innobase/row/row0mysql.c546
-rw-r--r--innobase/row/row0purge.c41
-rw-r--r--innobase/row/row0row.c92
-rw-r--r--innobase/row/row0sel.c760
-rw-r--r--innobase/row/row0uins.c8
-rw-r--r--innobase/row/row0umod.c131
-rw-r--r--innobase/row/row0undo.c20
-rw-r--r--innobase/row/row0upd.c283
-rw-r--r--innobase/row/row0vers.c56
-rw-r--r--innobase/srv/Makefile.am2
-rw-r--r--innobase/srv/srv0srv.c489
-rw-r--r--innobase/srv/srv0start.c365
-rw-r--r--innobase/sync/Makefile.am2
-rw-r--r--innobase/sync/sync0arr.c2
-rw-r--r--innobase/sync/sync0rw.c9
-rw-r--r--innobase/sync/sync0sync.c42
-rw-r--r--innobase/thr/Makefile.am2
-rw-r--r--innobase/thr/thr0loc.c1
-rw-r--r--innobase/trx/Makefile.am2
-rw-r--r--innobase/trx/trx0purge.c22
-rw-r--r--innobase/trx/trx0rec.c29
-rw-r--r--innobase/trx/trx0roll.c287
-rw-r--r--innobase/trx/trx0sys.c135
-rw-r--r--innobase/trx/trx0trx.c162
-rw-r--r--innobase/trx/trx0undo.c8
-rw-r--r--innobase/usr/Makefile.am2
-rw-r--r--innobase/ut/Makefile.am2
-rw-r--r--innobase/ut/ut0mem.c28
-rw-r--r--innobase/ut/ut0ut.c15
-rw-r--r--isam/_cache.c20
-rw-r--r--isam/_dbug.c6
-rw-r--r--isam/_dynrec.c26
-rw-r--r--isam/_key.c6
-rw-r--r--isam/_locking.c8
-rw-r--r--isam/_packrec.c12
-rw-r--r--isam/_page.c6
-rw-r--r--isam/_search.c6
-rw-r--r--isam/_statrec.c8
-rw-r--r--isam/changed.c6
-rw-r--r--isam/close.c6
-rw-r--r--isam/create.c18
-rw-r--r--isam/delete.c8
-rw-r--r--isam/extra.c23
-rw-r--r--isam/info.c6
-rw-r--r--isam/isamchk.c398
-rw-r--r--isam/isamdef.h6
-rw-r--r--isam/isamlog.c12
-rw-r--r--isam/log.c6
-rw-r--r--isam/open.c6
-rw-r--r--isam/pack_isam.c233
-rw-r--r--isam/panic.c6
-rw-r--r--isam/range.c6
-rw-r--r--isam/rfirst.c6
-rw-r--r--isam/rkey.c6
-rw-r--r--isam/rlast.c6
-rw-r--r--isam/rnext.c6
-rw-r--r--isam/rprev.c6
-rw-r--r--isam/rrnd.c6
-rw-r--r--isam/rsame.c6
-rw-r--r--isam/rsamepos.c6
-rw-r--r--isam/sort.c6
-rw-r--r--isam/static.c8
-rw-r--r--isam/test1.c8
-rw-r--r--isam/test2.c22
-rw-r--r--isam/test3.c26
-rw-r--r--isam/update.c6
-rw-r--r--isam/write.c8
-rw-r--r--libmysql/Makefile.am25
-rw-r--r--libmysql/Makefile.shared28
-rw-r--r--libmysql/conf_to_src.c29
-rw-r--r--libmysql/dll.c44
-rw-r--r--libmysql/errmsg.c96
-rw-r--r--libmysql/get_password.c54
-rw-r--r--libmysql/libmysql.c1151
-rw-r--r--libmysql/libmysql.def129
-rw-r--r--libmysql/manager.c268
-rw-r--r--libmysql/password.c192
-rw-r--r--libmysql/violite.c443
-rw-r--r--libmysql_r/Makefile.am4
-rw-r--r--libmysqld/Makefile.am123
-rw-r--r--libmysqld/copyright14
-rw-r--r--libmysqld/embedded_priv.h31
-rw-r--r--libmysqld/examples/Makefile.am28
-rw-r--r--libmysqld/examples/builder-sample/emb_sample.bpr192
-rw-r--r--libmysqld/examples/builder-sample/emb_sample.cpp23
-rw-r--r--libmysqld/examples/builder-sample/emb_sample.tdsbin0 -> 2293760 bytes
-rw-r--r--libmysqld/examples/builder-sample/emb_samples.cpp283
-rw-r--r--libmysqld/examples/builder-sample/emb_samples.dfmbin0 -> 15895 bytes
-rw-r--r--libmysqld/examples/builder-sample/emb_samples.h61
-rw-r--r--libmysqld/examples/builder-sample/images/db.icobin0 -> 318 bytes
-rw-r--r--libmysqld/examples/builder-sample/images/find.icobin0 -> 766 bytes
-rw-r--r--libmysqld/examples/builder-sample/images/logo.icobin0 -> 2022 bytes
-rw-r--r--libmysqld/examples/builder-sample/images/mysql.bmpbin0 -> 8760 bytes
-rw-r--r--libmysqld/examples/builder-sample/images/net.icobin0 -> 766 bytes
-rw-r--r--libmysqld/examples/builder-sample/libmysqld.libbin0 -> 7168 bytes
-rw-r--r--libmysqld/examples/builder-sample/snapshot.jpgbin0 -> 36274 bytes
-rwxr-xr-xlibmysqld/examples/test-run138
-rw-r--r--libmysqld/lib_sql.cc663
-rw-r--r--libmysqld/lib_vio.c226
-rw-r--r--libmysqld/libmysqld.c2103
-rw-r--r--libmysqld/libmysqld.def65
-rw-r--r--ltmain.sh2728
-rw-r--r--man/Makefile.am23
-rwxr-xr-xman/isamchk.1140
-rw-r--r--man/isamchk.1.in145
-rw-r--r--man/isamlog.1103
-rw-r--r--man/isamlog.1.in107
-rw-r--r--man/mysql.1150
-rw-r--r--man/mysql.1.in160
-rw-r--r--man/mysql_fix_privilege_tables.1.in40
-rw-r--r--man/mysql_zap.134
-rw-r--r--man/mysql_zap.1.in52
-rwxr-xr-xman/mysqlaccess.1121
-rw-r--r--man/mysqlaccess.1.in126
-rwxr-xr-xman/mysqladmin.1208
-rw-r--r--man/mysqladmin.1.in209
-rwxr-xr-xman/mysqld.1230
-rw-r--r--man/mysqld.1.in234
-rw-r--r--man/mysqld_multi.190
-rw-r--r--man/mysqld_multi.1.in94
-rw-r--r--man/mysqld_safe.1.in91
-rwxr-xr-xman/mysqldump.1273
-rw-r--r--man/mysqldump.1.in278
-rwxr-xr-xman/mysqlshow.193
-rw-r--r--man/mysqlshow.1.in98
-rwxr-xr-xman/perror.153
-rw-r--r--man/perror.1.in58
-rw-r--r--man/replace.168
-rw-r--r--man/replace.1.in73
-rwxr-xr-xman/safe_mysqld.188
-rw-r--r--man/which.22
-rw-r--r--merge/Makefile.am8
-rw-r--r--merge/_locking.c33
-rw-r--r--merge/close.c40
-rw-r--r--merge/create.c61
-rw-r--r--merge/delete.c29
-rw-r--r--merge/extra.c46
-rw-r--r--merge/info.c60
-rw-r--r--merge/mrg_close.c40
-rw-r--r--merge/mrg_create.c61
-rw-r--r--merge/mrg_def.h29
-rw-r--r--merge/mrg_delete.c29
-rw-r--r--merge/mrg_extra.c46
-rw-r--r--merge/mrg_info.c60
-rw-r--r--merge/mrg_locking.c33
-rw-r--r--merge/mrg_open.c150
-rw-r--r--merge/mrg_panic.c47
-rw-r--r--merge/mrg_rrnd.c110
-rw-r--r--merge/mrg_rsame.c36
-rw-r--r--merge/mrg_static.c26
-rw-r--r--merge/mrg_update.c31
-rw-r--r--merge/mrgdef.h29
-rw-r--r--merge/open.c144
-rw-r--r--merge/panic.c47
-rw-r--r--merge/rrnd.c110
-rw-r--r--merge/rsame.c36
-rw-r--r--merge/static.c26
-rw-r--r--merge/update.c31
-rw-r--r--mit-pthreads/.cvsignore6
-rw-r--r--mit-pthreads/COPYRIGHT31
-rw-r--r--mit-pthreads/Changes-mysql237
-rw-r--r--mit-pthreads/FAQ122
-rw-r--r--mit-pthreads/GNUmakefile129
-rw-r--r--mit-pthreads/NOTES59
-rw-r--r--mit-pthreads/NOTES_OSR5_BUILD_SKUNKWARE9745
-rw-r--r--mit-pthreads/README40
-rw-r--r--mit-pthreads/TODO-mysql4
-rw-r--r--mit-pthreads/Whats_New198
-rw-r--r--mit-pthreads/bin/.cvsignore1
-rw-r--r--mit-pthreads/bin/Makefile.in48
-rw-r--r--mit-pthreads/bin/finger/.cvsignore1
-rwxr-xr-xmit-pthreads/bin/finger/Makefile.in60
-rwxr-xr-xmit-pthreads/bin/finger/finger.c231
-rwxr-xr-xmit-pthreads/bin/finger/net.c189
-rwxr-xr-xmit-pthreads/config/COPYING.GNU339
-rwxr-xr-xmit-pthreads/config/COPYRIGHT4
-rwxr-xr-xmit-pthreads/config/GNUmakefile.in129
-rw-r--r--mit-pthreads/config/Makefile.in56
-rw-r--r--mit-pthreads/config/acconfig.h73
-rwxr-xr-xmit-pthreads/config/aclocal.m494
-rwxr-xr-xmit-pthreads/config/config.flags.in80
-rwxr-xr-xmit-pthreads/config/config.guess505
-rwxr-xr-xmit-pthreads/config/config.h.in324
-rwxr-xr-xmit-pthreads/config/config.sub794
-rwxr-xr-xmit-pthreads/config/configure3336
-rwxr-xr-xmit-pthreads/config/configure.in745
-rwxr-xr-xmit-pthreads/config/configure.org2874
-rwxr-xr-xmit-pthreads/config/install-sh238
-rwxr-xr-xmit-pthreads/configure18
-rwxr-xr-xmit-pthreads/gen/GNUmakefile.inc9
-rw-r--r--mit-pthreads/gen/Makefile.inc24
-rw-r--r--mit-pthreads/gen/ctime.c1315
-rw-r--r--mit-pthreads/gen/difftime.c46
-rw-r--r--mit-pthreads/gen/directory.c322
-rw-r--r--mit-pthreads/gen/eprintf.c18
-rw-r--r--mit-pthreads/gen/getcwd.c248
-rw-r--r--mit-pthreads/gen/getpwent.c109
-rw-r--r--mit-pthreads/gen/getpwnamuid.c138
-rw-r--r--mit-pthreads/gen/getwd.c57
-rw-r--r--mit-pthreads/gen/isatty.c95
-rw-r--r--mit-pthreads/gen/popen.c117
-rw-r--r--mit-pthreads/gen/pwd_internal.c97
-rw-r--r--mit-pthreads/gen/pwd_internal.h29
-rw-r--r--mit-pthreads/gen/syslog.c216
-rw-r--r--mit-pthreads/gen/time.c51
-rw-r--r--mit-pthreads/gen/ttyname.c147
-rw-r--r--mit-pthreads/include/Makefile.inc30
-rwxr-xr-xmit-pthreads/include/arpa/inet.h61
-rwxr-xr-xmit-pthreads/include/arpa/nameser.h279
-rw-r--r--mit-pthreads/include/dirent.h97
-rw-r--r--mit-pthreads/include/endian.h95
-rw-r--r--mit-pthreads/include/errno.h52
-rw-r--r--mit-pthreads/include/math.h85
-rw-r--r--mit-pthreads/include/netdb.h146
-rw-r--r--mit-pthreads/include/pthread.h371
-rw-r--r--mit-pthreads/include/pthread/ac-types.h10
-rwxr-xr-xmit-pthreads/include/pthread/cleanup.h59
-rwxr-xr-xmit-pthreads/include/pthread/cond.h102
-rw-r--r--mit-pthreads/include/pthread/config.h5
-rwxr-xr-xmit-pthreads/include/pthread/debug_out.h44
-rwxr-xr-xmit-pthreads/include/pthread/fd.h122
-rwxr-xr-xmit-pthreads/include/pthread/fd_pipe.h54
-rwxr-xr-xmit-pthreads/include/pthread/kernel.h71
-rwxr-xr-xmit-pthreads/include/pthread/kthread.h67
-rwxr-xr-xmit-pthreads/include/pthread/mutex.h102
-rw-r--r--mit-pthreads/include/pthread/paths.h12
-rwxr-xr-xmit-pthreads/include/pthread/prio_queue.h78
-rwxr-xr-xmit-pthreads/include/pthread/pthread_attr.h122
-rwxr-xr-xmit-pthreads/include/pthread/pthread_once.h58
-rwxr-xr-xmit-pthreads/include/pthread/queue.h67
-rwxr-xr-xmit-pthreads/include/pthread/sleep.h63
-rwxr-xr-xmit-pthreads/include/pthread/specific.h66
-rwxr-xr-xmit-pthreads/include/pthread/state.def64
-rwxr-xr-xmit-pthreads/include/pthread/types.h46
-rwxr-xr-xmit-pthreads/include/pthread/unistd.h159
-rwxr-xr-xmit-pthreads/include/pthread/util.h89
-rwxr-xr-xmit-pthreads/include/pthread/version.h43
-rwxr-xr-xmit-pthreads/include/pthread/xtypes.h13
-rw-r--r--mit-pthreads/include/pwd.h93
-rw-r--r--mit-pthreads/include/resolv.h179
-rw-r--r--mit-pthreads/include/sched.h57
-rw-r--r--mit-pthreads/include/signal.h81
-rw-r--r--mit-pthreads/include/stdio.h371
-rw-r--r--mit-pthreads/include/stdlib.h127
-rw-r--r--mit-pthreads/include/string.h85
-rw-r--r--mit-pthreads/include/syslog.h101
-rw-r--r--mit-pthreads/include/time.h102
-rw-r--r--mit-pthreads/include/timers.h45
-rw-r--r--mit-pthreads/include/tzfile.h154
-rw-r--r--mit-pthreads/include/unistd.h183
-rw-r--r--mit-pthreads/lib/.cvsignore1
-rw-r--r--mit-pthreads/lib/Makefile.in48
-rw-r--r--mit-pthreads/lib/libpthreadutil/.cvsignore1
-rwxr-xr-xmit-pthreads/lib/libpthreadutil/Makefile.in65
-rwxr-xr-xmit-pthreads/lib/libpthreadutil/pthread_atexit.c135
-rwxr-xr-xmit-pthreads/lib/libpthreadutil/pthread_tad.c170
-rwxr-xr-xmit-pthreads/lib/libpthreadutil/pthreadutil.h75
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__math.h16
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__signal.h106
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__stdio.h13
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__stdlib.h3
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__string.h19
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__time.h21
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/__unistd.h6
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/cdefs.h62
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/compat.h1
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/dirent.h7
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/signal.h3
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/socket.h296
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/timers.h60
-rwxr-xr-xmit-pthreads/machdep/alpha-osf1/uio.h12
-rwxr-xr-xmit-pthreads/machdep/bsdi-1.1/compat.h43
-rwxr-xr-xmit-pthreads/machdep/bsdi-1.1/dirent.h73
-rwxr-xr-xmit-pthreads/machdep/bsdi-1.1/errno.h160
-rwxr-xr-xmit-pthreads/machdep/bsdi-1.1/socket.h277
-rwxr-xr-xmit-pthreads/machdep/bsdi-1.1/timers.h59
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__math.h6
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__path.h13
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__signal.h7
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__stdio.h7
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__stdlib.h60
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__string.h19
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__time.h63
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/__unistd.h109
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/compat.h65
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/dirent.h65
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/errno.h162
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/time.h6
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/timers.h45
-rwxr-xr-xmit-pthreads/machdep/bsdi-2.0/wait.h159
-rw-r--r--mit-pthreads/machdep/engine-alpha-netbsd-1.1.c196
-rw-r--r--mit-pthreads/machdep/engine-alpha-netbsd-1.1.h111
-rw-r--r--mit-pthreads/machdep/engine-alpha-netbsd-1.3.c204
-rw-r--r--mit-pthreads/machdep/engine-alpha-netbsd-1.3.h114
-rw-r--r--mit-pthreads/machdep/engine-alpha-osf1.c207
-rw-r--r--mit-pthreads/machdep/engine-alpha-osf1.h110
-rw-r--r--mit-pthreads/machdep/engine-arm32-netbsd-1.3.c203
-rw-r--r--mit-pthreads/machdep/engine-arm32-netbsd-1.3.h102
-rw-r--r--mit-pthreads/machdep/engine-hppa-hpux-10.20.c169
-rw-r--r--mit-pthreads/machdep/engine-hppa-hpux-10.20.h143
-rw-r--r--mit-pthreads/machdep/engine-hppa-hpux-9.03.c153
-rw-r--r--mit-pthreads/machdep/engine-hppa-hpux-9.03.h141
-rw-r--r--mit-pthreads/machdep/engine-i386-bsdi-1.1.c180
-rw-r--r--mit-pthreads/machdep/engine-i386-bsdi-1.1.h84
-rw-r--r--mit-pthreads/machdep/engine-i386-bsdi-2.0.c210
-rw-r--r--mit-pthreads/machdep/engine-i386-bsdi-2.0.h98
-rw-r--r--mit-pthreads/machdep/engine-i386-freebsd-1.1.c179
-rw-r--r--mit-pthreads/machdep/engine-i386-freebsd-1.1.h83
-rw-r--r--mit-pthreads/machdep/engine-i386-freebsd-2.0.c208
-rw-r--r--mit-pthreads/machdep/engine-i386-freebsd-2.0.h97
-rw-r--r--mit-pthreads/machdep/engine-i386-linux-1.0.c503
-rw-r--r--mit-pthreads/machdep/engine-i386-linux-1.0.h98
-rw-r--r--mit-pthreads/machdep/engine-i386-linux-2.0.c504
-rw-r--r--mit-pthreads/machdep/engine-i386-linux-2.0.h99
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-0.9.c155
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-0.9.h83
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-1.0.c218
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-1.0.h97
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-1.3.c225
-rw-r--r--mit-pthreads/machdep/engine-i386-netbsd-1.3.h98
-rw-r--r--mit-pthreads/machdep/engine-i386-openbsd-2.0.c215
-rw-r--r--mit-pthreads/machdep/engine-i386-openbsd-2.0.h97
-rwxr-xr-xmit-pthreads/machdep/engine-i386-sco-3.2v5.c1072
-rw-r--r--mit-pthreads/machdep/engine-i386-sco-3.2v5.h104
-rw-r--r--mit-pthreads/machdep/engine-ip22-irix-5.2.c225
-rw-r--r--mit-pthreads/machdep/engine-ip22-irix-5.2.h108
-rw-r--r--mit-pthreads/machdep/engine-m68000-netbsd.c256
-rw-r--r--mit-pthreads/machdep/engine-m68000-netbsd.h107
-rw-r--r--mit-pthreads/machdep/engine-powerpc-netbsd.c227
-rw-r--r--mit-pthreads/machdep/engine-powerpc-netbsd.h109
-rw-r--r--mit-pthreads/machdep/engine-r2000-ultrix-4.2.c209
-rw-r--r--mit-pthreads/machdep/engine-r2000-ultrix-4.2.h107
-rw-r--r--mit-pthreads/machdep/engine-romp-bsd.c99
-rw-r--r--mit-pthreads/machdep/engine-romp-bsd.h100
-rw-r--r--mit-pthreads/machdep/engine-sparc-netbsd-1.3.c232
-rw-r--r--mit-pthreads/machdep/engine-sparc-netbsd-1.3.h106
-rw-r--r--mit-pthreads/machdep/engine-sparc-sunos-4.1.3.c227
-rw-r--r--mit-pthreads/machdep/engine-sparc-sunos-4.1.3.h105
-rw-r--r--mit-pthreads/machdep/engine-sparc-sunos-5.3.c308
-rw-r--r--mit-pthreads/machdep/engine-sparc-sunos-5.3.h129
-rwxr-xr-xmit-pthreads/machdep/freebsd-1.1/compat.h43
-rwxr-xr-xmit-pthreads/machdep/freebsd-1.1/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/freebsd-1.1/socket.h267
-rwxr-xr-xmit-pthreads/machdep/freebsd-1.1/timers.h68
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__math.h6
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__path.h14
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__signal.h8
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__stdio.h8
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__stdlib.h66
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__string.h21
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__time.h70
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/__unistd.h113
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/compat.h43
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/errno.h160
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/timers.h45
-rwxr-xr-xmit-pthreads/machdep/freebsd-2.0/wait.h162
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__math.h3
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__signal.h28
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__stdio.h11
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__stdlib.h24
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__string.h20
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__time.h31
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/__unistd.h68
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/cdefs.h67
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/compat.h45
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/dirent.h61
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/socket.h171
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/stdtypes.h74
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/time.h228
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/timers.h71
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/uio.h25
-rwxr-xr-xmit-pthreads/machdep/hpux-10.20/wait.h92
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__math.h3
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__signal.h28
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__stdio.h8
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__stdlib.h24
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__string.h20
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__time.h31
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/__unistd.h66
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/cdefs.h61
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/compat.h45
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/dirent.h61
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/socket.h171
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/stdtypes.h74
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/time.h228
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/timers.h68
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/uio.h25
-rwxr-xr-xmit-pthreads/machdep/hpux-9.03/wait.h92
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__math.h4
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__signal.h15
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__stdio.h6
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__stdlib.h30
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__string.h5
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__time.h21
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/__unistd.h8
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/compat.h45
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/dirent.h21
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/socket.h304
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/timers.h18
-rwxr-xr-xmit-pthreads/machdep/irix-5.2/wait.h104
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__math.h4
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__path.h14
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__signal.h24
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__stdio.h7
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__stdlib.h20
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__string.h18
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__time.h72
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/__unistd.h56
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/cdefs.h23
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/compat.h47
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/dirent.h27
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/errno.h12
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/socket.h193
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/timers.h71
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/uio.h15
-rwxr-xr-xmit-pthreads/machdep/linux-1.0/wait.h98
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__math.h4
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__path.h14
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__signal.h86
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__stdio.h12
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__stdlib.h20
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__string.h18
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__time.h78
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/__unistd.h62
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/cdefs.h36
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/compat.h47
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/dirent.h27
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/errno.h12
-rw-r--r--mit-pthreads/machdep/linux-2.0/extra/bits/local_lim.h15
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/extra/bits/socket.h198
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/socket.h13
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/timers.h71
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/uio.h15
-rwxr-xr-xmit-pthreads/machdep/linux-2.0/wait.h98
-rwxr-xr-xmit-pthreads/machdep/netbsd-0.9/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__math.h6
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__path.h14
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__signal.h8
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__stdio.h8
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__stdlib.h60
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__string.h20
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__time.h69
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/__unistd.h107
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/compat.h43
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/errno.h160
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/time.h125
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/timers.h45
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.0/wait.h158
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__math.h6
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__path.h14
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__signal.h27
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__stdio.h8
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__stdlib.h60
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__string.h20
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__time.h69
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/__unistd.h107
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/compat.h43
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/dirent.h95
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/errno.h170
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/time.h153
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/timers.h45
-rwxr-xr-xmit-pthreads/machdep/netbsd-1.1/wait.h163
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__math.h6
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__path.h14
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__signal.h8
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__stdio.h8
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__stdlib.h66
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__string.h21
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__time.h70
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/__unistd.h109
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/compat.h43
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/errno.h160
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/timers.h45
-rwxr-xr-xmit-pthreads/machdep/openbsd-2.0/wait.h162
-rw-r--r--mit-pthreads/machdep/posix-alpha-osf1.h7
-rw-r--r--mit-pthreads/machdep/posix-bsdi-1.1.h34
-rw-r--r--mit-pthreads/machdep/posix-bsdi-2.0.h34
-rw-r--r--mit-pthreads/machdep/posix-freebsd-1.1.h33
-rw-r--r--mit-pthreads/machdep/posix-freebsd-2.0.h31
-rw-r--r--mit-pthreads/machdep/posix-hpux-10.20.h23
-rw-r--r--mit-pthreads/machdep/posix-hpux-9.03.h23
-rw-r--r--mit-pthreads/machdep/posix-i386-sco-3.2v5.h35
-rw-r--r--mit-pthreads/machdep/posix-irix-5.2.h31
-rw-r--r--mit-pthreads/machdep/posix-linux-1.0.h31
-rw-r--r--mit-pthreads/machdep/posix-linux-2.0.h31
-rw-r--r--mit-pthreads/machdep/posix-netbsd-0.9.h22
-rw-r--r--mit-pthreads/machdep/posix-netbsd-1.0.h31
-rw-r--r--mit-pthreads/machdep/posix-netbsd-1.1.h31
-rw-r--r--mit-pthreads/machdep/posix-openbsd-2.0.h31
-rw-r--r--mit-pthreads/machdep/posix-romp-bsd.h33
-rw-r--r--mit-pthreads/machdep/posix-sco-3.2v5.h35
-rw-r--r--mit-pthreads/machdep/posix-sunos-4.1.3.h27
-rw-r--r--mit-pthreads/machdep/posix-sunos-5.3.h22
-rw-r--r--mit-pthreads/machdep/posix-sunos-5.5.h22
-rw-r--r--mit-pthreads/machdep/posix-ultrix-4.2.h24
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__math.h5
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__path.h12
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__signal.h11
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__stdio.h4
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__stdlib.h28
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__string.h14
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__time.h2
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/__unistd.h73
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/cdefs.h61
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/compat.h45
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/fcntlcom.h163
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/signal.h98
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/stat.h94
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/time.h69
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/timers.h68
-rwxr-xr-xmit-pthreads/machdep/sunos-4.1.3/wait.h22
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__math.h16
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__signal.h19
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__stdio.h6
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__stdlib.h27
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__string.h12
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__time.h69
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/__unistd.h47
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/cdefs.h59
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/compat.h45
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/socket.h180
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/timers.h72
-rwxr-xr-xmit-pthreads/machdep/sunos-5.3/uio.h40
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__math.h16
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__signal.h19
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__stdio.h6
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__stdlib.h27
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__string.h12
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__time.h69
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/__unistd.h47
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/cdefs.h59
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/compat.h45
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/dirent.h64
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/socket.h180
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/timers.h70
-rwxr-xr-xmit-pthreads/machdep/sunos-5.5/uio.h40
-rw-r--r--mit-pthreads/machdep/syscall-alpha-netbsd-1.1.S206
-rw-r--r--mit-pthreads/machdep/syscall-alpha-netbsd-1.3.S228
-rw-r--r--mit-pthreads/machdep/syscall-alpha-osf1.S97
-rw-r--r--mit-pthreads/machdep/syscall-arm32-netbsd-1.3.S193
-rw-r--r--mit-pthreads/machdep/syscall-hppa-hpux-10.20.S23
-rw-r--r--mit-pthreads/machdep/syscall-hppa-hpux-9.03.S23
-rw-r--r--mit-pthreads/machdep/syscall-i386-bsdi-1.1.S288
-rw-r--r--mit-pthreads/machdep/syscall-i386-bsdi-2.0.S294
-rw-r--r--mit-pthreads/machdep/syscall-i386-freebsd-1.1.S293
-rw-r--r--mit-pthreads/machdep/syscall-i386-freebsd-2.0.S240
-rw-r--r--mit-pthreads/machdep/syscall-i386-linux-1.0.S406
-rw-r--r--mit-pthreads/machdep/syscall-i386-linux-2.0.S389
-rw-r--r--mit-pthreads/machdep/syscall-i386-netbsd-0.9.S229
-rw-r--r--mit-pthreads/machdep/syscall-i386-netbsd-1.0.S158
-rw-r--r--mit-pthreads/machdep/syscall-i386-netbsd-1.1.S181
-rw-r--r--mit-pthreads/machdep/syscall-i386-netbsd-1.3.S200
-rw-r--r--mit-pthreads/machdep/syscall-i386-openbsd-2.0.S237
-rw-r--r--mit-pthreads/machdep/syscall-i386-sco-3.2v5.S442
-rw-r--r--mit-pthreads/machdep/syscall-ip22-irix-5.2.S106
-rw-r--r--mit-pthreads/machdep/syscall-m68000-netbsd.S83
-rw-r--r--mit-pthreads/machdep/syscall-powerpc-netbsd.S185
-rw-r--r--mit-pthreads/machdep/syscall-r2000-ultrix-4.2.S166
-rw-r--r--mit-pthreads/machdep/syscall-romp-bsd.S327
-rw-r--r--mit-pthreads/machdep/syscall-sparc-netbsd-1.1.S102
-rw-r--r--mit-pthreads/machdep/syscall-sparc-netbsd-1.3.S172
-rw-r--r--mit-pthreads/machdep/syscall-sparc-sunos-4.1.3.S113
-rw-r--r--mit-pthreads/machdep/syscall-sparc-sunos-5.3.S65
-rw-r--r--mit-pthreads/machdep/syscall-sparc-sunos4.S113
-rw-r--r--mit-pthreads/machdep/syscall-template-alpha-netbsd-1.1.S46
-rw-r--r--mit-pthreads/machdep/syscall-template-alpha-netbsd-1.3.S53
-rw-r--r--mit-pthreads/machdep/syscall-template-alpha-osf1.S46
-rw-r--r--mit-pthreads/machdep/syscall-template-arm32-netbsd-1.3.S55
-rw-r--r--mit-pthreads/machdep/syscall-template-hppa-hpux-10.20.S27
-rw-r--r--mit-pthreads/machdep/syscall-template-hppa-hpux-9.03.S27
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-bsdi-2.0.S48
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-freebsd-2.0.S59
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-netbsd-1.1.S49
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-netbsd-1.3.S56
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-netbsd1.0.S49
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-openbsd-2.0.S48
-rw-r--r--mit-pthreads/machdep/syscall-template-i386-sco-3.2v5.S67
-rw-r--r--mit-pthreads/machdep/syscall-template-ip22-irix-5.2.S51
-rw-r--r--mit-pthreads/machdep/syscall-template-m68000-netbsd.S43
-rw-r--r--mit-pthreads/machdep/syscall-template-powerpc-netbsd.S45
-rw-r--r--mit-pthreads/machdep/syscall-template-r2000-ultrix-4.2.S77
-rw-r--r--mit-pthreads/machdep/syscall-template-sparc-netbsd-1.1.S40
-rw-r--r--mit-pthreads/machdep/syscall-template-sparc-netbsd-1.3.S48
-rw-r--r--mit-pthreads/machdep/syscall-template-sparc-sunos-5.3.S45
-rw-r--r--mit-pthreads/machdep/syscall-template-sparc-sunos4.S40
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__math.h2
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__signal.h66
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__stdio.h7
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__stdlib.h21
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__string.h17
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__time.h69
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/__unistd.h51
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/cdefs.h66
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/compat.h45
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/dirent.h61
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/errno.h180
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/time.h83
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/timers.h68
-rwxr-xr-xmit-pthreads/machdep/ultrix-4.2/wait.h121
-rw-r--r--mit-pthreads/machdep/unistd-i386-freebsd-1.1.h178
-rw-r--r--mit-pthreads/machdep/unistd-i386-linux-1.0.h59
-rw-r--r--mit-pthreads/machdep/unistd-i386-linux-2.0.h59
-rw-r--r--mit-pthreads/machdep/unistd-sparc-sunos-4.1.3.h215
-rw-r--r--mit-pthreads/net/GNUmakefile.inc14
-rw-r--r--mit-pthreads/net/Makefile.inc13
-rw-r--r--mit-pthreads/net/gethostbyaddr.c161
-rw-r--r--mit-pthreads/net/gethostbyname.c167
-rw-r--r--mit-pthreads/net/gethostent.c162
-rw-r--r--mit-pthreads/net/gethostname.c22
-rw-r--r--mit-pthreads/net/getnetbyaddr.c65
-rw-r--r--mit-pthreads/net/getnetbyname.c72
-rw-r--r--mit-pthreads/net/getnetent.c145
-rw-r--r--mit-pthreads/net/getproto.c65
-rw-r--r--mit-pthreads/net/getprotoent.c143
-rw-r--r--mit-pthreads/net/getprotoname.c73
-rw-r--r--mit-pthreads/net/getservbyname.c76
-rw-r--r--mit-pthreads/net/getservbyport.c68
-rw-r--r--mit-pthreads/net/getservent.c146
-rw-r--r--mit-pthreads/net/herror.c92
-rw-r--r--mit-pthreads/net/inet_addr.c156
-rw-r--r--mit-pthreads/net/inet_lnaof.c61
-rw-r--r--mit-pthreads/net/inet_makeaddr.c64
-rw-r--r--mit-pthreads/net/inet_netof.c60
-rw-r--r--mit-pthreads/net/inet_network.c98
-rw-r--r--mit-pthreads/net/inet_ntoa.c85
-rw-r--r--mit-pthreads/net/net_internal.c78
-rw-r--r--mit-pthreads/net/net_internal.h58
-rw-r--r--mit-pthreads/net/proto_internal.c78
-rw-r--r--mit-pthreads/net/proto_internal.h58
-rw-r--r--mit-pthreads/net/res_comp.c340
-rw-r--r--mit-pthreads/net/res_debug.c749
-rw-r--r--mit-pthreads/net/res_init.c55
-rw-r--r--mit-pthreads/net/res_internal.c576
-rw-r--r--mit-pthreads/net/res_internal.h85
-rw-r--r--mit-pthreads/net/res_mkquery.c212
-rw-r--r--mit-pthreads/net/res_query.c97
-rw-r--r--mit-pthreads/net/res_querydomain.c66
-rw-r--r--mit-pthreads/net/res_search.c168
-rw-r--r--mit-pthreads/net/res_send.c313
-rw-r--r--mit-pthreads/net/serv_internal.c80
-rw-r--r--mit-pthreads/net/serv_internal.h58
-rwxr-xr-xmit-pthreads/patches/Streepy.html2873
-rwxr-xr-xmit-pthreads/patches/Streepy2.html93
-rwxr-xr-xmit-pthreads/patches/bill_lear70
-rwxr-xr-xmit-pthreads/patches/chris_demetriou149
-rwxr-xr-xmit-pthreads/patches/mevans642
-rwxr-xr-xmit-pthreads/patches/p15390
-rwxr-xr-xmit-pthreads/patches/p15596
-rw-r--r--mit-pthreads/pthreads/GNUmakefile.inc46
-rw-r--r--mit-pthreads/pthreads/Makefile.inc75
-rw-r--r--mit-pthreads/pthreads/_exit.c80
-rw-r--r--mit-pthreads/pthreads/cleanup.c84
-rw-r--r--mit-pthreads/pthreads/cond.c437
-rw-r--r--mit-pthreads/pthreads/condattr.c90
-rw-r--r--mit-pthreads/pthreads/dump_state.c88
-rw-r--r--mit-pthreads/pthreads/errno.c53
-rw-r--r--mit-pthreads/pthreads/fd.c1083
-rw-r--r--mit-pthreads/pthreads/fd_kern.c1950
-rw-r--r--mit-pthreads/pthreads/fd_pipe.c257
-rw-r--r--mit-pthreads/pthreads/fd_sysv.c897
-rw-r--r--mit-pthreads/pthreads/file.c129
-rw-r--r--mit-pthreads/pthreads/globals.c85
-rw-r--r--mit-pthreads/pthreads/info.c77
-rw-r--r--mit-pthreads/pthreads/init.cc9
-rw-r--r--mit-pthreads/pthreads/malloc.c383
-rw-r--r--mit-pthreads/pthreads/mutex.c371
-rw-r--r--mit-pthreads/pthreads/mutexattr.c90
-rw-r--r--mit-pthreads/pthreads/panic.c58
-rw-r--r--mit-pthreads/pthreads/prio_queue.c176
-rw-r--r--mit-pthreads/pthreads/process.c208
-rw-r--r--mit-pthreads/pthreads/pthread.c293
-rw-r--r--mit-pthreads/pthreads/pthread_attr.c255
-rw-r--r--mit-pthreads/pthreads/pthread_cancel.c258
-rw-r--r--mit-pthreads/pthreads/pthread_detach.c92
-rw-r--r--mit-pthreads/pthreads/pthread_init.c135
-rw-r--r--mit-pthreads/pthreads/pthread_join.c139
-rw-r--r--mit-pthreads/pthreads/pthread_kill.c93
-rw-r--r--mit-pthreads/pthreads/pthread_once.c59
-rw-r--r--mit-pthreads/pthreads/queue.c143
-rw-r--r--mit-pthreads/pthreads/readv.c85
-rw-r--r--mit-pthreads/pthreads/schedparam.c170
-rw-r--r--mit-pthreads/pthreads/select.c255
-rw-r--r--mit-pthreads/pthreads/sig.c452
-rw-r--r--mit-pthreads/pthreads/signal.c653
-rw-r--r--mit-pthreads/pthreads/sleep.c367
-rw-r--r--mit-pthreads/pthreads/specific.c198
-rw-r--r--mit-pthreads/pthreads/stat.c116
-rw-r--r--mit-pthreads/pthreads/wait.c159
-rw-r--r--mit-pthreads/pthreads/wrapper.c149
-rw-r--r--mit-pthreads/pthreads/writev.c89
-rwxr-xr-xmit-pthreads/scripts/GNUmakefile.inc24
-rw-r--r--mit-pthreads/scripts/Makefile.inc30
-rwxr-xr-xmit-pthreads/scripts/pgcc.sh32
-rwxr-xr-xmit-pthreads/stdio/GNUmakefile.inc26
-rw-r--r--mit-pthreads/stdio/Makefile.inc20
-rwxr-xr-xmit-pthreads/stdio/README41
-rw-r--r--mit-pthreads/stdio/clrerr.c51
-rw-r--r--mit-pthreads/stdio/fclose.c73
-rw-r--r--mit-pthreads/stdio/fdopen.c93
-rw-r--r--mit-pthreads/stdio/feof.c55
-rw-r--r--mit-pthreads/stdio/ferror.c55
-rw-r--r--mit-pthreads/stdio/fflush.c98
-rw-r--r--mit-pthreads/stdio/fgetc.c65
-rw-r--r--mit-pthreads/stdio/fgetline.c170
-rw-r--r--mit-pthreads/stdio/fgetpos.c85
-rw-r--r--mit-pthreads/stdio/fgets.c110
-rw-r--r--mit-pthreads/stdio/fileno.c55
-rw-r--r--mit-pthreads/stdio/findfp.c161
-rw-r--r--mit-pthreads/stdio/flags.c93
-rw-r--r--mit-pthreads/stdio/floatio.h47
-rw-r--r--mit-pthreads/stdio/fopen.c90
-rw-r--r--mit-pthreads/stdio/fprintf.c71
-rw-r--r--mit-pthreads/stdio/fpurge.c73
-rw-r--r--mit-pthreads/stdio/fputc.c73
-rw-r--r--mit-pthreads/stdio/fputs.c67
-rw-r--r--mit-pthreads/stdio/fread.c84
-rw-r--r--mit-pthreads/stdio/freopen.c149
-rw-r--r--mit-pthreads/stdio/fscanf.c73
-rw-r--r--mit-pthreads/stdio/fseek.c248
-rw-r--r--mit-pthreads/stdio/fsetpos.c54
-rw-r--r--mit-pthreads/stdio/ftell.c90
-rw-r--r--mit-pthreads/stdio/funopen.c105
-rw-r--r--mit-pthreads/stdio/fvwrite.c190
-rw-r--r--mit-pthreads/stdio/fvwrite.h54
-rw-r--r--mit-pthreads/stdio/fwalk.c132
-rw-r--r--mit-pthreads/stdio/fwrite.c80
-rw-r--r--mit-pthreads/stdio/getc.c58
-rw-r--r--mit-pthreads/stdio/getc_unlocked.c55
-rw-r--r--mit-pthreads/stdio/getchar.c58
-rw-r--r--mit-pthreads/stdio/getchar_unlocked.c54
-rw-r--r--mit-pthreads/stdio/gets.c71
-rw-r--r--mit-pthreads/stdio/getw.c51
-rw-r--r--mit-pthreads/stdio/glue.h49
-rw-r--r--mit-pthreads/stdio/local.h90
-rw-r--r--mit-pthreads/stdio/makebuf.c122
-rw-r--r--mit-pthreads/stdio/mktemp.c126
-rw-r--r--mit-pthreads/stdio/perror.c67
-rw-r--r--mit-pthreads/stdio/printf.c56
-rw-r--r--mit-pthreads/stdio/putc.c60
-rw-r--r--mit-pthreads/stdio/putc_unlocked.c56
-rw-r--r--mit-pthreads/stdio/putchar.c60
-rw-r--r--mit-pthreads/stdio/putchar_unlocked.c56
-rw-r--r--mit-pthreads/stdio/puts.c71
-rw-r--r--mit-pthreads/stdio/putw.c64
-rw-r--r--mit-pthreads/stdio/refill.c189
-rw-r--r--mit-pthreads/stdio/remove.c50
-rw-r--r--mit-pthreads/stdio/rewind.c55
-rw-r--r--mit-pthreads/stdio/rget.c58
-rw-r--r--mit-pthreads/stdio/scanf.c72
-rw-r--r--mit-pthreads/stdio/setbuf.c52
-rw-r--r--mit-pthreads/stdio/setbuffer.c64
-rw-r--r--mit-pthreads/stdio/setvbuf.c154
-rw-r--r--mit-pthreads/stdio/snprintf.c79
-rw-r--r--mit-pthreads/stdio/sprintf.c78
-rw-r--r--mit-pthreads/stdio/sscanf.c79
-rw-r--r--mit-pthreads/stdio/stdio.c104
-rw-r--r--mit-pthreads/stdio/strerror.c72
-rw-r--r--mit-pthreads/stdio/tempnam.c87
-rw-r--r--mit-pthreads/stdio/tmpfile.c80
-rw-r--r--mit-pthreads/stdio/tmpnam.c55
-rw-r--r--mit-pthreads/stdio/ungetc.c155
-rw-r--r--mit-pthreads/stdio/vfprintf.c788
-rw-r--r--mit-pthreads/stdio/vfscanf.c750
-rw-r--r--mit-pthreads/stdio/vprintf.c51
-rw-r--r--mit-pthreads/stdio/vscanf.c55
-rw-r--r--mit-pthreads/stdio/vsnprintf.c65
-rw-r--r--mit-pthreads/stdio/vsprintf.c62
-rw-r--r--mit-pthreads/stdio/vsscanf.c62
-rw-r--r--mit-pthreads/stdio/wbuf.c89
-rw-r--r--mit-pthreads/stdio/wsetup.c91
-rw-r--r--mit-pthreads/stdio/xprintf.c883
-rwxr-xr-xmit-pthreads/stdlib/GNUmakefile.inc7
-rw-r--r--mit-pthreads/stdlib/Makefile.inc10
-rw-r--r--mit-pthreads/stdlib/abort.c67
-rw-r--r--mit-pthreads/stdlib/atexit.h46
-rw-r--r--mit-pthreads/stdlib/exit.c89
-rw-r--r--mit-pthreads/stdlib/getopt.c135
-rw-r--r--mit-pthreads/stdlib/rand.c64
-rw-r--r--mit-pthreads/stdlib/random.c389
-rw-r--r--mit-pthreads/stdlib/strtod.c178
-rw-r--r--mit-pthreads/stdlib/strtol.c131
-rw-r--r--mit-pthreads/stdlib/strtoul.c109
-rw-r--r--mit-pthreads/stdlib/system.c83
-rwxr-xr-xmit-pthreads/string/GNUmakefile.inc7
-rw-r--r--mit-pthreads/string/Makefile.inc8
-rw-r--r--mit-pthreads/string/strtok.c119
-rw-r--r--mit-pthreads/tests/.cvsignore1
-rw-r--r--mit-pthreads/tests/Makefile.in164
-rwxr-xr-xmit-pthreads/tests/README26
-rw-r--r--mit-pthreads/tests/bench_fcntl.c82
-rw-r--r--mit-pthreads/tests/bench_pipe.c115
-rw-r--r--mit-pthreads/tests/bench_read.c88
-rw-r--r--mit-pthreads/tests/p_bench_getpid.c78
-rw-r--r--mit-pthreads/tests/p_bench_mutex.c78
-rw-r--r--mit-pthreads/tests/p_bench_pthread_create.c92
-rw-r--r--mit-pthreads/tests/p_bench_read.c103
-rw-r--r--mit-pthreads/tests/p_bench_semaphore.c82
-rw-r--r--mit-pthreads/tests/p_bench_yield.c123
-rw-r--r--mit-pthreads/tests/test_create.c35
-rw-r--r--mit-pthreads/tests/test_cwd.c11
-rw-r--r--mit-pthreads/tests/test_execve.c57
-rw-r--r--mit-pthreads/tests/test_fcntl.c32
-rw-r--r--mit-pthreads/tests/test_fork.c60
-rw-r--r--mit-pthreads/tests/test_netdb.c110
-rw-r--r--mit-pthreads/tests/test_pause.c19
-rw-r--r--mit-pthreads/tests/test_preemption.c38
-rw-r--r--mit-pthreads/tests/test_preemption_float.c98
-rw-r--r--mit-pthreads/tests/test_pthread_cond_timedwait.c93
-rw-r--r--mit-pthreads/tests/test_pthread_join.c78
-rw-r--r--mit-pthreads/tests/test_pthread_mutex.c221
-rw-r--r--mit-pthreads/tests/test_pw.c20
-rw-r--r--mit-pthreads/tests/test_readdir.c42
-rw-r--r--mit-pthreads/tests/test_select.c115
-rw-r--r--mit-pthreads/tests/test_setjmp.c13
-rw-r--r--mit-pthreads/tests/test_sleep.c46
-rw-r--r--mit-pthreads/tests/test_sock_1.c204
-rw-r--r--mit-pthreads/tests/test_sock_2.c116
-rw-r--r--mit-pthreads/tests/test_sock_2a.c87
-rw-r--r--mit-pthreads/tests/test_stdio_1.c124
-rw-r--r--mit-pthreads/tests/test_switch.c97
-rw-r--r--myisam/Makefile.am21
-rw-r--r--myisam/ft_boolean_search.c655
-rw-r--r--myisam/ft_eval.c169
-rw-r--r--myisam/ft_eval.h7
-rw-r--r--myisam/ft_nlq_search.c291
-rw-r--r--myisam/ft_parser.c165
-rw-r--r--myisam/ft_search.c231
-rw-r--r--myisam/ft_static.c59
-rw-r--r--myisam/ft_stem.c7
-rw-r--r--myisam/ft_stopwords.c82
-rw-r--r--myisam/ft_test1.c110
-rw-r--r--myisam/ft_test1.h7
-rw-r--r--myisam/ft_update.c233
-rw-r--r--myisam/ftdefs.h79
-rw-r--r--myisam/fulltext.h1
-rw-r--r--myisam/mi_cache.c73
-rw-r--r--myisam/mi_changed.c8
-rw-r--r--myisam/mi_check.c1460
-rw-r--r--myisam/mi_checksum.c6
-rw-r--r--myisam/mi_close.c14
-rw-r--r--myisam/mi_create.c122
-rw-r--r--myisam/mi_dbug.c12
-rw-r--r--myisam/mi_delete.c15
-rw-r--r--myisam/mi_delete_all.c19
-rw-r--r--myisam/mi_delete_table.c10
-rw-r--r--myisam/mi_dynrec.c362
-rw-r--r--myisam/mi_extra.c107
-rw-r--r--myisam/mi_info.c20
-rw-r--r--myisam/mi_key.c118
-rw-r--r--myisam/mi_locking.c101
-rw-r--r--myisam/mi_log.c6
-rw-r--r--myisam/mi_open.c180
-rw-r--r--myisam/mi_packrec.c44
-rw-r--r--myisam/mi_page.c12
-rw-r--r--myisam/mi_panic.c6
-rw-r--r--myisam/mi_range.c25
-rw-r--r--myisam/mi_rename.c10
-rw-r--r--myisam/mi_rfirst.c6
-rw-r--r--myisam/mi_rkey.c50
-rw-r--r--myisam/mi_rlast.c6
-rw-r--r--myisam/mi_rnext.c4
-rw-r--r--myisam/mi_rnext_same.c13
-rw-r--r--myisam/mi_rprev.c4
-rw-r--r--myisam/mi_rrnd.c6
-rw-r--r--myisam/mi_rsame.c11
-rw-r--r--myisam/mi_rsamepos.c6
-rw-r--r--myisam/mi_scan.c6
-rw-r--r--myisam/mi_search.c1308
-rw-r--r--myisam/mi_static.c18
-rw-r--r--myisam/mi_statrec.c65
-rw-r--r--myisam/mi_test1.c291
-rw-r--r--myisam/mi_test2.c205
-rw-r--r--myisam/mi_test3.c30
-rw-r--r--myisam/mi_test_all.res90
-rwxr-xr-xmyisam/mi_test_all.sh22
-rw-r--r--myisam/mi_unique.c16
-rw-r--r--myisam/mi_update.c61
-rw-r--r--myisam/mi_write.c299
-rw-r--r--myisam/myisam_ftdump.c274
-rw-r--r--myisam/myisamchk.c874
-rw-r--r--myisam/myisamdef.h162
-rw-r--r--myisam/myisamlog.c29
-rw-r--r--myisam/myisampack.c239
-rw-r--r--myisam/sort.c691
-rw-r--r--myisammrg/Makefile.am4
-rw-r--r--myisammrg/mymrgdef.h31
-rw-r--r--myisammrg/myrg_close.c8
-rw-r--r--myisammrg/myrg_create.c18
-rw-r--r--myisammrg/myrg_def.h33
-rw-r--r--myisammrg/myrg_delete.c17
-rw-r--r--myisammrg/myrg_extra.c28
-rw-r--r--myisammrg/myrg_info.c19
-rw-r--r--myisammrg/myrg_locking.c12
-rw-r--r--myisammrg/myrg_open.c80
-rw-r--r--myisammrg/myrg_panic.c8
-rw-r--r--myisammrg/myrg_queue.c14
-rw-r--r--myisammrg/myrg_range.c41
-rw-r--r--myisammrg/myrg_rfirst.c4
-rw-r--r--myisammrg/myrg_rkey.c6
-rw-r--r--myisammrg/myrg_rlast.c4
-rw-r--r--myisammrg/myrg_rnext.c4
-rw-r--r--myisammrg/myrg_rprev.c4
-rw-r--r--myisammrg/myrg_rrnd.c12
-rw-r--r--myisammrg/myrg_rsame.c18
-rw-r--r--myisammrg/myrg_static.c12
-rw-r--r--myisammrg/myrg_update.c11
-rw-r--r--myisammrg/myrg_write.c30
-rw-r--r--mysql-test/Makefile.am4
-rwxr-xr-xmysql-test/create-test-result4
-rwxr-xr-xmysql-test/fix-result22
-rw-r--r--mysql-test/include/check_var_limit.inc9
-rw-r--r--mysql-test/include/have_bdb.inc2
-rw-r--r--mysql-test/include/have_crypt.inc4
-rw-r--r--mysql-test/include/have_gemini.inc2
-rw-r--r--mysql-test/include/have_innodb.inc2
-rw-r--r--mysql-test/include/have_isam.inc2
-rw-r--r--mysql-test/include/have_openssl.inc4
-rw-r--r--mysql-test/include/have_openssl_1.inc4
-rw-r--r--mysql-test/include/have_query_cache.inc4
-rw-r--r--mysql-test/include/master-slave.inc13
-rw-r--r--mysql-test/include/not_embedded.inc5
-rw-r--r--mysql-test/install_test_db.sh55
-rw-r--r--mysql-test/mysql-test-run.sh1107
-rw-r--r--mysql-test/r/alias.result71
-rw-r--r--mysql-test/r/alter_table.result318
-rw-r--r--mysql-test/r/analyse.result18
-rw-r--r--mysql-test/r/ansi.result10
-rw-r--r--mysql-test/r/auto_increment.result95
-rw-r--r--mysql-test/r/backup.result32
-rw-r--r--mysql-test/r/bdb-alter-table-1.result7
-rw-r--r--mysql-test/r/bdb-alter-table-2.result2
-rw-r--r--mysql-test/r/bdb-crash.result29
-rw-r--r--mysql-test/r/bdb-deadlock.result21
-rw-r--r--mysql-test/r/bdb.result700
-rw-r--r--mysql-test/r/bdb_cache.result100
-rw-r--r--mysql-test/r/bench_count_distinct.result4
-rw-r--r--mysql-test/r/big_test.require2
-rw-r--r--mysql-test/r/bigint.result74
-rw-r--r--mysql-test/r/binary.result45
-rw-r--r--mysql-test/r/bool.result74
-rw-r--r--mysql-test/r/bulk_replace.result11
-rw-r--r--mysql-test/r/case.result27
-rw-r--r--mysql-test/r/cast.result39
-rw-r--r--mysql-test/r/check.result5
-rw-r--r--mysql-test/r/check_var_limit.require2
-rw-r--r--mysql-test/r/comments.result13
-rw-r--r--mysql-test/r/compare.result10
-rw-r--r--mysql-test/r/constraints.result16
-rw-r--r--mysql-test/r/convert.result17
-rw-r--r--mysql-test/r/count_distinct.result44
-rw-r--r--mysql-test/r/count_distinct2.result129
-rw-r--r--mysql-test/r/create.result169
-rw-r--r--mysql-test/r/ctype_cp1251.result24
-rw-r--r--mysql-test/r/ctype_latin1_de.result269
-rw-r--r--mysql-test/r/ctype_tis620.result18
-rw-r--r--mysql-test/r/ctype_ujis.result8
-rw-r--r--mysql-test/r/delayed.result21
-rw-r--r--mysql-test/r/delete.result48
-rw-r--r--mysql-test/r/dirty-close.result4
-rw-r--r--mysql-test/r/dirty_close.result9
-rw-r--r--mysql-test/r/distinct.result268
-rw-r--r--mysql-test/r/drop.result37
-rw-r--r--mysql-test/r/drop_temp_table.result18
-rw-r--r--mysql-test/r/empty_table.result6
-rw-r--r--mysql-test/r/errors.result25
-rw-r--r--mysql-test/r/explain.result35
-rw-r--r--mysql-test/r/flush.result24
-rw-r--r--mysql-test/r/foreign_key.result15
-rw-r--r--mysql-test/r/fulltext.result267
-rw-r--r--mysql-test/r/fulltext_cache.result54
-rw-r--r--mysql-test/r/fulltext_distinct.result43
-rw-r--r--mysql-test/r/fulltext_left_join.result49
-rw-r--r--mysql-test/r/fulltext_multi.result25
-rw-r--r--mysql-test/r/fulltext_order_by.result79
-rw-r--r--mysql-test/r/fulltext_update.result20
-rw-r--r--mysql-test/r/fulltext_var.result7
-rw-r--r--mysql-test/r/func_concat.result15
-rw-r--r--mysql-test/r/func_crypt.result17
-rw-r--r--mysql-test/r/func_date_add.result35
-rw-r--r--mysql-test/r/func_encrypt.result136
-rw-r--r--mysql-test/r/func_equal.result14
-rw-r--r--mysql-test/r/func_group.result184
-rw-r--r--mysql-test/r/func_if.result19
-rw-r--r--mysql-test/r/func_in.result14
-rw-r--r--mysql-test/r/func_isnull.result6
-rw-r--r--mysql-test/r/func_like.result41
-rw-r--r--mysql-test/r/func_math.result29
-rw-r--r--mysql-test/r/func_misc.result14
-rw-r--r--mysql-test/r/func_op.result23
-rw-r--r--mysql-test/r/func_regexp.result29
-rw-r--r--mysql-test/r/func_set.result12
-rw-r--r--mysql-test/r/func_str.result183
-rw-r--r--mysql-test/r/func_system.result6
-rw-r--r--mysql-test/r/func_test.result37
-rw-r--r--mysql-test/r/func_time.result223
-rw-r--r--mysql-test/r/func_timestamp.result8
-rw-r--r--mysql-test/r/gcc296.result15
-rw-r--r--mysql-test/r/gemini.result370
-rw-r--r--mysql-test/r/grant.result133
-rw-r--r--mysql-test/r/grant_cache.result154
-rw-r--r--mysql-test/r/group_by.result517
-rw-r--r--mysql-test/r/handler.result193
-rw-r--r--mysql-test/r/have_crypt.require2
-rw-r--r--mysql-test/r/have_gemini.require2
-rw-r--r--mysql-test/r/have_met_timezone.require2
-rw-r--r--mysql-test/r/have_openssl.require2
-rw-r--r--mysql-test/r/have_openssl_1.require2
-rw-r--r--mysql-test/r/have_query_cache.require2
-rw-r--r--mysql-test/r/have_symlink.require2
-rw-r--r--mysql-test/r/having.result74
-rw-r--r--mysql-test/r/heap.result144
-rw-r--r--mysql-test/r/innodb-deadlock.result20
-rw-r--r--mysql-test/r/innodb.result839
-rw-r--r--mysql-test/r/innodb_cache.result110
-rw-r--r--mysql-test/r/innodb_handler.result151
-rw-r--r--mysql-test/r/ins000001.result4
-rw-r--r--mysql-test/r/insert.result80
-rw-r--r--mysql-test/r/insert_select.result581
-rw-r--r--mysql-test/r/isam.result241
-rw-r--r--mysql-test/r/isolation.result61
-rw-r--r--mysql-test/r/join.result326
-rw-r--r--mysql-test/r/join_crash.result109
-rw-r--r--mysql-test/r/join_outer.result381
-rw-r--r--mysql-test/r/key.result160
-rw-r--r--mysql-test/r/key_diff.result15
-rw-r--r--mysql-test/r/key_primary.result11
-rw-r--r--mysql-test/r/keywords.result12
-rw-r--r--mysql-test/r/kill.result7
-rw-r--r--mysql-test/r/limit.result44
-rw-r--r--mysql-test/r/loaddata.result46
-rw-r--r--mysql-test/r/lock.result47
-rw-r--r--mysql-test/r/lock_multi.result26
-rw-r--r--mysql-test/r/lock_tables_lost_commit.result8
-rw-r--r--mysql-test/r/lowercase2.require2
-rw-r--r--mysql-test/r/lowercase_table.result41
-rw-r--r--mysql-test/r/lowercase_table2.result108
-rw-r--r--mysql-test/r/merge.result478
-rw-r--r--mysql-test/r/mix_innodb_myisam_binlog.result180
-rw-r--r--mysql-test/r/multi_update.result362
-rw-r--r--mysql-test/r/myisam-blob.result27
-rw-r--r--mysql-test/r/myisam.result401
-rw-r--r--mysql-test/r/mysqlbinlog.result83
-rw-r--r--mysql-test/r/mysqldump.result37
-rw-r--r--mysql-test/r/not_embedded.require2
-rw-r--r--mysql-test/r/null.result83
-rw-r--r--mysql-test/r/null_key.result166
-rw-r--r--mysql-test/r/odbc.result9
-rw-r--r--mysql-test/r/olap.result27
-rw-r--r--mysql-test/r/openssl_1.result32
-rw-r--r--mysql-test/r/openssl_2.result2
-rw-r--r--mysql-test/r/order_by.result422
-rw-r--r--mysql-test/r/order_fill_sortbuf.result10
-rw-r--r--mysql-test/r/overflow.result2
-rw-r--r--mysql-test/r/packet.result25
-rw-r--r--mysql-test/r/query_cache.result690
-rw-r--r--mysql-test/r/query_cache_merge.result20
-rw-r--r--mysql-test/r/raid.result192
-rw-r--r--mysql-test/r/range.result248
-rw-r--r--mysql-test/r/rename.result25
-rw-r--r--mysql-test/r/repair.result15
-rw-r--r--mysql-test/r/repair_part2.result8
-rw-r--r--mysql-test/r/replace.result23
-rw-r--r--mysql-test/r/rollback.result9
-rw-r--r--mysql-test/r/rpl000001.result70
-rw-r--r--mysql-test/r/rpl000002.result24
-rw-r--r--mysql-test/r/rpl000003.result13
-rw-r--r--mysql-test/r/rpl000004.result29
-rw-r--r--mysql-test/r/rpl000005.result15
-rw-r--r--mysql-test/r/rpl000006.result25
-rw-r--r--mysql-test/r/rpl000007.result2
-rw-r--r--mysql-test/r/rpl000008.result23
-rw-r--r--mysql-test/r/rpl000009.result119
-rw-r--r--mysql-test/r/rpl000010.result13
-rw-r--r--mysql-test/r/rpl000011.result14
-rw-r--r--mysql-test/r/rpl000012.result26
-rw-r--r--mysql-test/r/rpl000013.result18
-rw-r--r--mysql-test/r/rpl000014.result16
-rw-r--r--mysql-test/r/rpl000015.result33
-rw-r--r--mysql-test/r/rpl000017.result9
-rw-r--r--mysql-test/r/rpl000018.result9
-rw-r--r--mysql-test/r/rpl_EE_error.result16
-rw-r--r--mysql-test/r/rpl_alter.result17
-rw-r--r--mysql-test/r/rpl_chain_temp_table.result30
-rw-r--r--mysql-test/r/rpl_change_master.result32
-rw-r--r--mysql-test/r/rpl_do_grant.result26
-rw-r--r--mysql-test/r/rpl_empty_master_crash.result15
-rw-r--r--mysql-test/r/rpl_error_ignored_table.result15
-rw-r--r--mysql-test/r/rpl_failsafe.result34
-rw-r--r--mysql-test/r/rpl_flush_log_loop.result17
-rw-r--r--mysql-test/r/rpl_get_lock.result22
-rw-r--r--mysql-test/r/rpl_heap.result29
-rw-r--r--mysql-test/r/rpl_ignore_grant.result37
-rw-r--r--mysql-test/r/rpl_insert_id.result56
-rw-r--r--mysql-test/r/rpl_loaddata.result68
-rw-r--r--mysql-test/r/rpl_loaddata_rule_m.result14
-rw-r--r--mysql-test/r/rpl_loaddata_rule_s.result14
-rw-r--r--mysql-test/r/rpl_loaddatalocal.result14
-rw-r--r--mysql-test/r/rpl_log.result101
-rw-r--r--mysql-test/r/rpl_log_pos.result46
-rw-r--r--mysql-test/r/rpl_master_pos_wait.result13
-rw-r--r--mysql-test/r/rpl_max_relay_size.result61
-rw-r--r--mysql-test/r/rpl_multi_delete.result22
-rw-r--r--mysql-test/r/rpl_multi_update.result27
-rw-r--r--mysql-test/r/rpl_mystery22.result19
-rw-r--r--mysql-test/r/rpl_redirect.result43
-rw-r--r--mysql-test/r/rpl_relayspace.result19
-rw-r--r--mysql-test/r/rpl_replicate_do.result28
-rw-r--r--mysql-test/r/rpl_reset_slave.result32
-rw-r--r--mysql-test/r/rpl_rotate_logs.result67
-rw-r--r--mysql-test/r/rpl_skip_error.result12
-rw-r--r--mysql-test/r/rpl_sporadic_master.result19
-rw-r--r--mysql-test/r/rpl_trunc_binlog.result13
-rw-r--r--mysql-test/r/sel000001.result19
-rw-r--r--mysql-test/r/sel000002.result5
-rw-r--r--mysql-test/r/sel000003.result5
-rw-r--r--mysql-test/r/sel000031.result8
-rw-r--r--mysql-test/r/sel000032.result8
-rw-r--r--mysql-test/r/sel000033.result6
-rw-r--r--mysql-test/r/sel000100.result36
-rw-r--r--mysql-test/r/select.result571
-rw-r--r--mysql-test/r/select_found.result190
-rw-r--r--mysql-test/r/select_safe.result71
-rw-r--r--mysql-test/r/show_check.result205
-rw-r--r--mysql-test/r/slave-running.result1
-rw-r--r--mysql-test/r/slave-stopped.result1
-rw-r--r--mysql-test/r/status.result13
-rw-r--r--mysql-test/r/symlink.result86
-rw-r--r--mysql-test/r/tablelock.result36
-rw-r--r--mysql-test/r/temp_table.result71
-rw-r--r--mysql-test/r/timezone.result40
-rw-r--r--mysql-test/r/truncate.result30
-rw-r--r--mysql-test/r/type_blob.result346
-rw-r--r--mysql-test/r/type_date.result51
-rw-r--r--mysql-test/r/type_datetime.result63
-rw-r--r--mysql-test/r/type_decimal.result459
-rw-r--r--mysql-test/r/type_enum.result24
-rw-r--r--mysql-test/r/type_float.result33
-rw-r--r--mysql-test/r/type_ranges.result154
-rw-r--r--mysql-test/r/type_set.result7
-rw-r--r--mysql-test/r/type_time.result13
-rw-r--r--mysql-test/r/type_timestamp.result142
-rw-r--r--mysql-test/r/type_uint.result6
-rw-r--r--mysql-test/r/type_year.result13
-rw-r--r--mysql-test/r/union.result429
-rw-r--r--mysql-test/r/update.result127
-rw-r--r--mysql-test/r/user_var.result106
-rw-r--r--mysql-test/r/varbinary.result22
-rw-r--r--mysql-test/r/variables.result354
-rw-r--r--mysql-test/r/warnings.result10
-rwxr-xr-xmysql-test/resolve-stack8
-rw-r--r--mysql-test/std_data/des_key_file4
-rw-r--r--mysql-test/std_data/gemini.dat5
-rw-r--r--mysql-test/std_data/init_file.dat1
-rw-r--r--mysql-test/std_data/loaddata1.dat3
-rw-r--r--mysql-test/std_data/loaddata2.dat5
-rw-r--r--mysql-test/std_data/loaddata3.dat6
-rw-r--r--mysql-test/std_data/loaddata4.dat1
-rw-r--r--mysql-test/std_data/master-bin.001bin113 -> 98 bytes
-rw-r--r--mysql-test/std_data/rpl_loaddata.dat2
-rw-r--r--mysql-test/std_data/rpl_loaddata2.dat8
-rw-r--r--mysql-test/std_data/trunc_binlog.001bin0 -> 119 bytes
-rw-r--r--mysql-test/std_data/words.dat60
-rw-r--r--mysql-test/t/alias.test21
-rw-r--r--mysql-test/t/alter_table.test128
-rw-r--r--mysql-test/t/analyse.test2
-rw-r--r--mysql-test/t/ansi-master.opt1
-rw-r--r--mysql-test/t/ansi.test17
-rw-r--r--mysql-test/t/auto_increment.test42
-rw-r--r--mysql-test/t/backup.test5
-rw-r--r--mysql-test/t/bdb-alter-table-1.test7
-rw-r--r--mysql-test/t/bdb-alter-table-2-master.opt2
-rw-r--r--mysql-test/t/bdb-alter-table-2.test7
-rw-r--r--mysql-test/t/bdb-crash.test2
-rw-r--r--mysql-test/t/bdb.test64
-rw-r--r--mysql-test/t/bdb_cache-master.opt1
-rw-r--r--mysql-test/t/bdb_cache.test50
-rw-r--r--mysql-test/t/bench_count_distinct.test3
-rw-r--r--mysql-test/t/bigint.test49
-rw-r--r--mysql-test/t/binary.test12
-rw-r--r--mysql-test/t/bool.test51
-rw-r--r--mysql-test/t/bulk_replace.test14
-rw-r--r--mysql-test/t/case.test8
-rw-r--r--mysql-test/t/cast.test22
-rw-r--r--mysql-test/t/check.test5
-rw-r--r--mysql-test/t/constraints.test21
-rw-r--r--mysql-test/t/convert.test11
-rw-r--r--mysql-test/t/count_distinct.test10
-rw-r--r--mysql-test/t/count_distinct2-master.opt1
-rw-r--r--mysql-test/t/count_distinct2.test79
-rw-r--r--mysql-test/t/create.test124
-rw-r--r--mysql-test/t/ctype_cp1251-master.opt2
-rw-r--r--mysql-test/t/ctype_cp1251.test17
-rw-r--r--mysql-test/t/ctype_latin1_de-master.opt2
-rw-r--r--mysql-test/t/ctype_latin1_de.test74
-rw-r--r--mysql-test/t/ctype_tis620-master.opt1
-rw-r--r--mysql-test/t/ctype_tis620.test23
-rw-r--r--mysql-test/t/ctype_ujis-master.opt1
-rw-r--r--mysql-test/t/ctype_ujis.test13
-rw-r--r--mysql-test/t/delayed.test1
-rw-r--r--mysql-test/t/delete.test6
-rw-r--r--mysql-test/t/dirty_close.test (renamed from mysql-test/t/dirty-close.test)0
-rw-r--r--mysql-test/t/distinct.test79
-rw-r--r--mysql-test/t/drop.test44
-rw-r--r--mysql-test/t/drop_temp_table.test19
-rw-r--r--mysql-test/t/err000001.test19
-rw-r--r--mysql-test/t/errors.test32
-rw-r--r--mysql-test/t/explain.test15
-rw-r--r--mysql-test/t/flush.test24
-rw-r--r--mysql-test/t/flush_table.test1
-rw-r--r--mysql-test/t/fulltext.test157
-rw-r--r--mysql-test/t/fulltext_cache.test14
-rw-r--r--mysql-test/t/fulltext_distinct.test41
-rw-r--r--mysql-test/t/fulltext_left_join.test17
-rw-r--r--mysql-test/t/fulltext_multi.test2
-rw-r--r--mysql-test/t/fulltext_order_by.test22
-rw-r--r--mysql-test/t/fulltext_var.test5
-rw-r--r--mysql-test/t/func_crypt.test13
-rw-r--r--mysql-test/t/func_encrypt-master.opt1
-rw-r--r--mysql-test/t/func_encrypt.test67
-rw-r--r--mysql-test/t/func_group.test59
-rw-r--r--mysql-test/t/func_in.test1
-rw-r--r--mysql-test/t/func_like.test29
-rw-r--r--mysql-test/t/func_math.test6
-rw-r--r--mysql-test/t/func_misc.test10
-rw-r--r--mysql-test/t/func_op.test9
-rw-r--r--mysql-test/t/func_set.test1
-rw-r--r--mysql-test/t/func_str.test73
-rw-r--r--mysql-test/t/func_system.test2
-rw-r--r--mysql-test/t/func_test.test14
-rw-r--r--mysql-test/t/func_time.test44
-rw-r--r--mysql-test/t/gemini.test355
-rw-r--r--mysql-test/t/grant.test91
-rw-r--r--mysql-test/t/grant_cache-master.opt1
-rw-r--r--mysql-test/t/grant_cache.test112
-rw-r--r--mysql-test/t/group_by.test161
-rw-r--r--mysql-test/t/handler.test125
-rw-r--r--mysql-test/t/having.test18
-rw-r--r--mysql-test/t/heap.test47
-rw-r--r--mysql-test/t/init_file-master.opt1
-rw-r--r--mysql-test/t/init_file.test7
-rw-r--r--mysql-test/t/innodb-deadlock.test38
-rw-r--r--mysql-test/t/innodb.test388
-rw-r--r--mysql-test/t/innodb_cache-master.opt1
-rw-r--r--mysql-test/t/innodb_cache.test57
-rw-r--r--mysql-test/t/innodb_handler.test82
-rw-r--r--mysql-test/t/ins000001.test9
-rw-r--r--mysql-test/t/insert.test76
-rw-r--r--mysql-test/t/insert_select.test120
-rw-r--r--mysql-test/t/isam.test59
-rw-r--r--mysql-test/t/isolation.test208
-rw-r--r--mysql-test/t/join.test71
-rw-r--r--mysql-test/t/join_outer.test50
-rw-r--r--mysql-test/t/key.test34
-rw-r--r--mysql-test/t/key_primary.test1
-rw-r--r--mysql-test/t/keywords.test4
-rw-r--r--mysql-test/t/kill.test8
-rw-r--r--mysql-test/t/limit.test24
-rw-r--r--mysql-test/t/loaddata.test31
-rw-r--r--mysql-test/t/lock.test46
-rw-r--r--mysql-test/t/lock_multi.test70
-rw-r--r--mysql-test/t/lock_tables_lost_commit-master.opt1
-rw-r--r--mysql-test/t/lock_tables_lost_commit.test18
-rw-r--r--mysql-test/t/lowercase_table-master.opt1
-rw-r--r--mysql-test/t/lowercase_table.test32
-rw-r--r--mysql-test/t/lowercase_table2-master.opt1
-rw-r--r--mysql-test/t/lowercase_table2.test80
-rw-r--r--mysql-test/t/merge.test123
-rw-r--r--mysql-test/t/mix_innodb_myisam_binlog.test178
-rw-r--r--mysql-test/t/multi_update-master.opt1
-rw-r--r--mysql-test/t/multi_update.test305
-rw-r--r--mysql-test/t/myisam-blob-master.opt1
-rw-r--r--mysql-test/t/myisam-blob.test30
-rw-r--r--mysql-test/t/myisam.test143
-rw-r--r--mysql-test/t/mysqlbinlog-master.opt1
-rw-r--r--mysql-test/t/mysqlbinlog.test103
-rw-r--r--mysql-test/t/mysqldump.test32
-rw-r--r--mysql-test/t/null.test46
-rw-r--r--mysql-test/t/odbc.test1
-rw-r--r--mysql-test/t/olap.test27
-rw-r--r--mysql-test/t/openssl_1.test43
-rw-r--r--mysql-test/t/order_by.test123
-rw-r--r--mysql-test/t/order_fill_sortbuf-master.opt1
-rw-r--r--mysql-test/t/order_fill_sortbuf.test21
-rw-r--r--mysql-test/t/packet.test31
-rw-r--r--mysql-test/t/query_cache.test509
-rw-r--r--mysql-test/t/query_cache_merge.test38
-rw-r--r--mysql-test/t/raid.test6
-rw-r--r--mysql-test/t/range.test164
-rw-r--r--mysql-test/t/rename.test16
-rw-r--r--mysql-test/t/repair.test19
-rw-r--r--mysql-test/t/repair_part2-master.sh1
-rw-r--r--mysql-test/t/repair_part2.test7
-rw-r--r--mysql-test/t/rpl000001.test77
-rw-r--r--mysql-test/t/rpl000002.test5
-rw-r--r--mysql-test/t/rpl000003.test1
-rw-r--r--mysql-test/t/rpl000004.test3
-rw-r--r--mysql-test/t/rpl000005.test1
-rw-r--r--mysql-test/t/rpl000006.test1
-rw-r--r--mysql-test/t/rpl000007-slave.opt1
-rw-r--r--mysql-test/t/rpl000007.test26
-rw-r--r--mysql-test/t/rpl000009.test120
-rw-r--r--mysql-test/t/rpl000011.test2
-rw-r--r--mysql-test/t/rpl000013.test1
-rw-r--r--mysql-test/t/rpl000014.test35
-rw-r--r--mysql-test/t/rpl000015.slave-mi2
-rw-r--r--mysql-test/t/rpl000015.test15
-rw-r--r--mysql-test/t/rpl000016-slave.opt1
-rwxr-xr-xmysql-test/t/rpl000017-slave.sh3
-rw-r--r--mysql-test/t/rpl000017.test8
-rwxr-xr-xmysql-test/t/rpl000018-master.sh3
-rw-r--r--mysql-test/t/rpl000018.test9
-rw-r--r--mysql-test/t/rpl_EE_error.test30
-rw-r--r--mysql-test/t/rpl_alter.test2
-rw-r--r--mysql-test/t/rpl_chain_temp_table.test99
-rw-r--r--mysql-test/t/rpl_change_master.test28
-rw-r--r--mysql-test/t/rpl_do_grant.test46
-rw-r--r--mysql-test/t/rpl_empty_master_crash.test11
-rw-r--r--mysql-test/t/rpl_error_ignored_table-slave.opt1
-rw-r--r--mysql-test/t/rpl_error_ignored_table.test25
-rw-r--r--mysql-test/t/rpl_failsafe.test24
-rw-r--r--mysql-test/t/rpl_flush_log_loop-master.opt1
-rwxr-xr-xmysql-test/t/rpl_flush_log_loop-master.sh5
-rw-r--r--mysql-test/t/rpl_flush_log_loop-slave.opt1
-rwxr-xr-xmysql-test/t/rpl_flush_log_loop-slave.sh4
-rw-r--r--mysql-test/t/rpl_flush_log_loop.test21
-rw-r--r--mysql-test/t/rpl_get_lock.test9
-rw-r--r--mysql-test/t/rpl_heap.test47
-rw-r--r--mysql-test/t/rpl_ignore_grant-slave.opt1
-rw-r--r--mysql-test/t/rpl_ignore_grant.test57
-rw-r--r--mysql-test/t/rpl_insert_id.test33
-rw-r--r--mysql-test/t/rpl_loaddata.test129
-rw-r--r--mysql-test/t/rpl_loaddata_rule_m-master.opt1
-rw-r--r--mysql-test/t/rpl_loaddata_rule_m.test18
-rw-r--r--mysql-test/t/rpl_loaddata_rule_s-slave.opt1
-rw-r--r--mysql-test/t/rpl_loaddata_rule_s.test20
-rw-r--r--mysql-test/t/rpl_loaddatalocal.test36
-rw-r--r--mysql-test/t/rpl_log-master.opt1
-rw-r--r--mysql-test/t/rpl_log-slave.opt1
-rw-r--r--mysql-test/t/rpl_log.test98
-rw-r--r--mysql-test/t/rpl_log_pos.test47
-rw-r--r--mysql-test/t/rpl_master_pos_wait.test15
-rw-r--r--mysql-test/t/rpl_max_relay_size.test88
-rw-r--r--mysql-test/t/rpl_multi_delete-slave.opt1
-rw-r--r--mysql-test/t/rpl_multi_delete.test23
-rw-r--r--mysql-test/t/rpl_multi_update.test25
-rw-r--r--mysql-test/t/rpl_mystery22.test4
-rw-r--r--mysql-test/t/rpl_redirect.test41
-rw-r--r--mysql-test/t/rpl_relayspace-slave.opt1
-rw-r--r--mysql-test/t/rpl_relayspace.test32
-rw-r--r--mysql-test/t/rpl_replicate_do-slave.opt1
-rw-r--r--mysql-test/t/rpl_replicate_do.test30
-rw-r--r--mysql-test/t/rpl_reset_slave.test44
-rw-r--r--mysql-test/t/rpl_rotate_logs-master.opt2
-rwxr-xr-xmysql-test/t/rpl_rotate_logs-slave.sh1
-rw-r--r--mysql-test/t/rpl_rotate_logs.test56
-rw-r--r--mysql-test/t/rpl_skip_error.test2
-rw-r--r--mysql-test/t/rpl_sporadic_master.test11
-rw-r--r--mysql-test/t/rpl_trunc_binlog.test25
-rw-r--r--mysql-test/t/sel000001.test13
-rw-r--r--mysql-test/t/sel000100.test15
-rw-r--r--mysql-test/t/select.test162
-rw-r--r--mysql-test/t/select_found.test101
-rw-r--r--mysql-test/t/select_safe.test50
-rw-r--r--mysql-test/t/show_check.test84
-rw-r--r--mysql-test/t/status.test10
-rw-r--r--mysql-test/t/symlink.test114
-rw-r--r--mysql-test/t/tablelock.test7
-rw-r--r--mysql-test/t/temp_table.test22
-rw-r--r--mysql-test/t/timezone-master.opt1
-rw-r--r--mysql-test/t/timezone.test47
-rw-r--r--mysql-test/t/truncate.test26
-rw-r--r--mysql-test/t/type_blob.test77
-rw-r--r--mysql-test/t/type_date.test1
-rw-r--r--mysql-test/t/type_datetime.test17
-rw-r--r--mysql-test/t/type_decimal.test48
-rw-r--r--mysql-test/t/type_enum.test12
-rw-r--r--mysql-test/t/type_ranges.test4
-rw-r--r--mysql-test/t/type_set.test1
-rw-r--r--mysql-test/t/type_time.test1
-rw-r--r--mysql-test/t/type_timestamp.test74
-rw-r--r--mysql-test/t/type_year.test11
-rw-r--r--mysql-test/t/union.test236
-rw-r--r--mysql-test/t/update.test49
-rw-r--r--mysql-test/t/user_var.test43
-rw-r--r--mysql-test/t/varbinary.test17
-rw-r--r--mysql-test/t/variables-master.opt1
-rw-r--r--mysql-test/t/variables.test237
-rw-r--r--mysql-test/t/warnings.test2
-rw-r--r--mysql-test/xml/README74
-rw-r--r--mysql-test/xml/tests/sel000001.xml21
-rw-r--r--mysql-test/xml/tests/sel000002.xml20
-rw-r--r--mysql-test/xml/tests/sel000003.xml21
-rw-r--r--mysql-test/xml/tests/sel000004.xml17
-rw-r--r--mysql-test/xml/tests/sel000005.xml17
-rw-r--r--mysql-test/xml/tests/sel000006.xml17
-rw-r--r--mysql-test/xml/tests/sel000007.xml17
-rw-r--r--mysql-test/xml/tests/sel000008.xml17
-rw-r--r--mysql-test/xml/tests/sel000009.xml17
-rw-r--r--mysql-test/xml/tests/sel000010.xml17
-rw-r--r--mysql-test/xml/tests/sel000011.xml17
-rw-r--r--mysql-test/xml/tests/sel000012.xml16
-rw-r--r--mysql-test/xml/tests/sel000013.xml16
-rw-r--r--mysql-test/xml/tests/sel000014.xml17
-rw-r--r--mysql-test/xml/tests/sel000015.xml17
-rw-r--r--mysql-test/xml/tests/sel000016.xml17
-rw-r--r--mysql-test/xml/tests/sel000017.xml17
-rw-r--r--mysql-test/xml/tests/sel000018.xml17
-rw-r--r--mysql-test/xml/tests/sel000019.xml17
-rw-r--r--mysql-test/xml/tests/sel000020.xml17
-rw-r--r--mysql-test/xml/tests/sel000021.xml17
-rw-r--r--mysql-test/xml/tests/sel000022.xml17
-rw-r--r--mysql-test/xml/tests/sel000023.xml17
-rw-r--r--mysql-test/xml/tests/sel000024.xml17
-rw-r--r--mysql-test/xml/tests/sel000025.xml17
-rw-r--r--mysql-test/xml/tests/sel000026.xml17
-rw-r--r--mysql-test/xml/tests/sel000027.xml17
-rw-r--r--mysql-test/xml/tests/sel000028.xml17
-rw-r--r--mysql-test/xml/tests/sel000029.xml17
-rw-r--r--mysql-test/xml/tests/sel000030.xml17
-rw-r--r--mysql-test/xml/xsl/README4
-rw-r--r--mysql-test/xml/xsl/mysqltest.xsl59
-rw-r--r--mysys/Makefile.am41
-rw-r--r--mysys/array.c145
-rw-r--r--mysys/charset.c206
-rw-r--r--mysys/checksum.c45
-rw-r--r--mysys/default.c264
-rw-r--r--mysys/errors.c37
-rw-r--r--mysys/getopt.c750
-rw-r--r--mysys/getopt1.c170
-rw-r--r--mysys/getvar.c112
-rw-r--r--mysys/hash.c49
-rw-r--r--mysys/list.c29
-rw-r--r--mysys/make-conf.c31
-rw-r--r--mysys/md5.c369
-rw-r--r--mysys/mf_brkhant.c29
-rw-r--r--mysys/mf_cache.c23
-rw-r--r--mysys/mf_casecnv.c80
-rw-r--r--mysys/mf_dirname.c124
-rw-r--r--mysys/mf_fn_ext.c52
-rw-r--r--mysys/mf_format.c130
-rw-r--r--mysys/mf_getdate.c29
-rw-r--r--mysys/mf_iocache.c957
-rw-r--r--mysys/mf_iocache2.c152
-rw-r--r--mysys/mf_keycache.c259
-rw-r--r--mysys/mf_loadpath.c32
-rw-r--r--mysys/mf_pack.c89
-rw-r--r--mysys/mf_pack2.c53
-rw-r--r--mysys/mf_path.c32
-rw-r--r--mysys/mf_qsort2.c29
-rw-r--r--mysys/mf_radix.c29
-rw-r--r--mysys/mf_same.c29
-rw-r--r--mysys/mf_sleep.c36
-rw-r--r--mysys/mf_sort.c31
-rw-r--r--mysys/mf_soundex.c29
-rw-r--r--mysys/mf_strip.c29
-rw-r--r--mysys/mf_tempfile.c51
-rw-r--r--mysys/mf_unixpath.c29
-rw-r--r--mysys/mf_util.c29
-rw-r--r--mysys/mf_wcomp.c29
-rw-r--r--mysys/mf_wfile.c29
-rw-r--r--mysys/mulalloc.c43
-rw-r--r--mysys/my_aes.c228
-rw-r--r--mysys/my_alarm.c29
-rw-r--r--mysys/my_alloc.c242
-rw-r--r--mysys/my_append.c31
-rw-r--r--mysys/my_bit.c73
-rw-r--r--mysys/my_bitmap.c33
-rw-r--r--mysys/my_chsize.c157
-rw-r--r--mysys/my_clock.c35
-rw-r--r--mysys/my_compress.c76
-rw-r--r--mysys/my_copy.c33
-rw-r--r--mysys/my_create.c29
-rw-r--r--mysys/my_delete.c30
-rw-r--r--mysys/my_div.c37
-rw-r--r--mysys/my_dup.c39
-rw-r--r--mysys/my_error.c61
-rw-r--r--mysys/my_fopen.c29
-rw-r--r--mysys/my_fstream.c34
-rw-r--r--mysys/my_gethostbyname.c5
-rw-r--r--mysys/my_getopt.c810
-rw-r--r--mysys/my_getwd.c31
-rw-r--r--mysys/my_init.c146
-rw-r--r--mysys/my_lib.c387
-rw-r--r--mysys/my_lock.c81
-rw-r--r--mysys/my_lockmem.c29
-rw-r--r--mysys/my_lread.c29
-rw-r--r--mysys/my_lwrite.c29
-rw-r--r--mysys/my_malloc.c43
-rw-r--r--mysys/my_messnc.c33
-rw-r--r--mysys/my_mkdir.c29
-rw-r--r--mysys/my_net.c29
-rw-r--r--mysys/my_netware.c151
-rw-r--r--mysys/my_new.cc4
-rw-r--r--mysys/my_once.c49
-rw-r--r--mysys/my_open.c62
-rw-r--r--mysys/my_os2cond.c1
-rw-r--r--mysys/my_os2dirsrch.c192
-rw-r--r--mysys/my_os2dirsrch.h57
-rw-r--r--mysys/my_os2file64.c389
-rw-r--r--mysys/my_os2mutex.c53
-rw-r--r--mysys/my_os2thread.c3
-rw-r--r--mysys/my_os2tls.c201
-rw-r--r--mysys/my_pread.c29
-rw-r--r--mysys/my_pthread.c73
-rw-r--r--mysys/my_quick.c29
-rw-r--r--mysys/my_read.c62
-rw-r--r--mysys/my_realloc.c29
-rw-r--r--mysys/my_redel.c33
-rw-r--r--mysys/my_rename.c29
-rw-r--r--mysys/my_seek.c41
-rw-r--r--mysys/my_semaphore.c104
-rw-r--r--mysys/my_sleep.c38
-rw-r--r--mysys/my_static.c47
-rw-r--r--mysys/my_static.h60
-rw-r--r--mysys/my_symlink.c37
-rw-r--r--mysys/my_symlink2.c60
-rw-r--r--mysys/my_sync.c60
-rw-r--r--mysys/my_tempnam.c43
-rw-r--r--mysys/my_thr_init.c138
-rw-r--r--mysys/my_vsnprintf.c59
-rw-r--r--mysys/my_wincond.c29
-rw-r--r--mysys/my_winsem.c406
-rw-r--r--mysys/my_winthread.c29
-rw-r--r--mysys/my_write.c29
-rw-r--r--mysys/mysys_priv.h37
-rw-r--r--mysys/ptr_cmp.c32
-rw-r--r--mysys/queues.c93
-rw-r--r--mysys/raid.cc166
-rw-r--r--mysys/rijndael.c1397
-rw-r--r--mysys/safemalloc.c634
-rw-r--r--mysys/sha1.c392
-rw-r--r--mysys/string.c31
-rw-r--r--mysys/test_charset.c33
-rw-r--r--mysys/test_dir.c29
-rw-r--r--mysys/test_fn.c29
-rw-r--r--mysys/testhash.c49
-rw-r--r--mysys/thr_alarm.c338
-rw-r--r--mysys/thr_lock.c98
-rw-r--r--mysys/thr_mutex.c160
-rw-r--r--mysys/thr_rwlock.c122
-rw-r--r--mysys/tree.c115
-rw-r--r--mysys/typelib.c32
-rw-r--r--mytest-old.c169
-rwxr-xr-xnetware/BUILD/apply-patch41
-rwxr-xr-xnetware/BUILD/compile-AUTOTOOLS22
-rwxr-xr-xnetware/BUILD/compile-linux-tools58
-rwxr-xr-xnetware/BUILD/compile-netware-END41
-rwxr-xr-xnetware/BUILD/compile-netware-START26
-rwxr-xr-xnetware/BUILD/compile-netware-all15
-rwxr-xr-xnetware/BUILD/compile-netware-debug21
-rw-r--r--netware/BUILD/compile-netware-max23
-rw-r--r--netware/BUILD/compile-netware-max-debug23
-rw-r--r--netware/BUILD/compile-netware-src36
-rwxr-xr-xnetware/BUILD/compile-netware-standard21
-rwxr-xr-xnetware/BUILD/create-patch56
-rwxr-xr-xnetware/BUILD/cron-build46
-rwxr-xr-xnetware/BUILD/crontab4
-rw-r--r--netware/BUILD/knetware.imp2
-rwxr-xr-xnetware/BUILD/mwasmnlm8
-rwxr-xr-xnetware/BUILD/mwccnlm10
-rwxr-xr-xnetware/BUILD/mwenv29
-rwxr-xr-xnetware/BUILD/mwldnlm8
-rwxr-xr-xnetware/BUILD/nwbootstrap187
-rw-r--r--netware/BUILD/openssl.imp9
-rwxr-xr-xnetware/BUILD/save-patch56
-rw-r--r--netware/Makefile.am48
-rw-r--r--netware/comp_err.def10
-rw-r--r--netware/init_db.sql25
-rw-r--r--netware/install_test_db.ncf1
-rw-r--r--netware/isamchk.def12
-rw-r--r--netware/isamlog.def10
-rw-r--r--netware/libmysql.def11
-rw-r--r--netware/libmysql.imp85
-rw-r--r--netware/libmysqlmain.c38
-rw-r--r--netware/my_manage.c478
-rw-r--r--netware/my_manage.h87
-rw-r--r--netware/my_print_defaults.def10
-rw-r--r--netware/myisamchk.def12
-rw-r--r--netware/myisamlog.def11
-rw-r--r--netware/myisampack.def11
-rw-r--r--netware/mysql.def12
-rw-r--r--netware/mysql.xdcbin0 -> 128 bytes
-rw-r--r--netware/mysql_fix_privilege_tables.pl125
-rw-r--r--netware/mysql_install.def10
-rw-r--r--netware/mysql_install_db.c428
-rw-r--r--netware/mysql_install_db.def11
-rw-r--r--netware/mysql_secure_installation.pl219
-rw-r--r--netware/mysql_test_run.c1237
-rw-r--r--netware/mysql_test_run.def11
-rw-r--r--netware/mysqladmin.def11
-rw-r--r--netware/mysqlbinlog.def11
-rw-r--r--netware/mysqlcheck.def11
-rw-r--r--netware/mysqld.def12
-rw-r--r--netware/mysqld_safe.c712
-rw-r--r--netware/mysqld_safe.def12
-rw-r--r--netware/mysqldump.def11
-rw-r--r--netware/mysqlimport.def11
-rw-r--r--netware/mysqlshow.def11
-rw-r--r--netware/mysqltest.def10
-rw-r--r--netware/pack_isam.def10
-rw-r--r--netware/perror.def10
-rw-r--r--netware/replace.def10
-rw-r--r--netware/resolveip.def10
-rw-r--r--netware/test_db.sql20
-rw-r--r--pstack/Makefile.am36
-rw-r--r--pstack/aout/Makefile.am1
-rw-r--r--pstack/aout/aout64.h475
-rw-r--r--pstack/aout/stab.def264
-rw-r--r--pstack/aout/stab_gnu.h37
-rw-r--r--pstack/bucomm.c238
-rw-r--r--pstack/bucomm.h85
-rw-r--r--pstack/budbg.h58
-rw-r--r--pstack/debug.c3509
-rw-r--r--pstack/debug.h798
-rw-r--r--pstack/demangle.h90
-rw-r--r--pstack/filemode.c266
-rw-r--r--pstack/ieee.c7602
-rw-r--r--pstack/ieee.h138
-rw-r--r--pstack/libiberty.h180
-rw-r--r--pstack/linuxthreads.c90
-rw-r--r--pstack/linuxthreads.h28
-rw-r--r--pstack/pstack.c2745
-rw-r--r--pstack/pstack.h22
-rw-r--r--pstack/pstacktrace.h24
-rw-r--r--pstack/rddbg.c462
-rw-r--r--pstack/stabs.c5082
-rw-r--r--readline/bind.c65
-rw-r--r--readline/callback.c1
-rw-r--r--readline/complete.c33
-rw-r--r--readline/display.c22
-rw-r--r--readline/funmap.c12
-rw-r--r--readline/histexpand.c15
-rw-r--r--readline/histfile.c8
-rw-r--r--readline/history.c2
-rw-r--r--readline/history.h6
-rw-r--r--readline/histsearch.c2
-rw-r--r--readline/input.c2
-rw-r--r--readline/isearch.c6
-rw-r--r--readline/kill.c34
-rw-r--r--readline/macro.c19
-rw-r--r--readline/readline.c63
-rw-r--r--readline/readline.h38
-rw-r--r--readline/rlstdc.h4
-rw-r--r--readline/rltty.c11
-rw-r--r--readline/search.c20
-rw-r--r--readline/shell.c1
-rw-r--r--readline/terminal.c21
-rw-r--r--readline/tilde.c12
-rw-r--r--readline/tilde.h4
-rw-r--r--readline/undo.c9
-rw-r--r--readline/util.c14
-rw-r--r--readline/vi_mode.c72
-rw-r--r--regex/cclass.h6
-rw-r--r--regex/cname.h4
-rw-r--r--regex/debug.c2
-rw-r--r--regex/main.c18
-rw-r--r--regex/regcomp.c74
-rw-r--r--regex/regcomp.ih2
-rw-r--r--regex/regerror.c10
-rw-r--r--regex/regexec.c2
-rw-r--r--regex/regexp.c2
-rw-r--r--regex/regfree.c2
-rw-r--r--regex/reginit.c14
-rw-r--r--regex/split.c2
-rw-r--r--repl-tests/README12
-rw-r--r--repl-tests/include/master-slave.inc2
-rwxr-xr-xrepl-tests/run-all-tests9
-rwxr-xr-xrepl-tests/test-auto-inc/run.test10
-rw-r--r--repl-tests/test-auto-inc/x.master4
-rwxr-xr-xrepl-tests/test-bad-query/run.test10
-rw-r--r--repl-tests/test-bad-query/x.master4
-rw-r--r--repl-tests/test-dump/run.test25
-rw-r--r--repl-tests/test-dump/table-dump-check.master2
-rw-r--r--repl-tests/test-dump/table-dump-select.master2
-rw-r--r--repl-tests/test-repl-alter/run.test12
-rw-r--r--repl-tests/test-repl-alter/test.master4
-rw-r--r--repl-tests/test-repl-ts/repl-timestamp.master2
-rw-r--r--repl-tests/test-repl-ts/repl-timestamp.master.reject2
-rw-r--r--repl-tests/test-repl-ts/run.test17
-rw-r--r--repl-tests/test-repl/foo-dump-master.master3
-rw-r--r--repl-tests/test-repl/foo-dump-slave.master3
-rwxr-xr-xrepl-tests/test-repl/run.test24
-rw-r--r--repl-tests/test-repl/sum-wlen-master.master2
-rw-r--r--repl-tests/test-repl/sum-wlen-slave.master2
-rw-r--r--scripts/Makefile.am23
-rw-r--r--scripts/make_binary_distribution.sh183
-rw-r--r--scripts/make_sharedlib_distribution.sh117
-rwxr-xr-xscripts/make_win_src_distribution.sh25
-rw-r--r--scripts/mysql_config.sh35
-rw-r--r--scripts/mysql_explain_log.sh392
-rw-r--r--scripts/mysql_fix_privilege_tables.sh105
-rw-r--r--scripts/mysql_fix_privilege_tables.sql137
-rw-r--r--scripts/mysql_install_db.sh74
-rw-r--r--scripts/mysql_secure_installation.sh312
-rw-r--r--scripts/mysql_setpermission.sh233
-rw-r--r--scripts/mysql_tableinfo.sh476
-rw-r--r--scripts/mysql_zap.sh2
-rw-r--r--scripts/mysqlaccess.sh2
-rw-r--r--scripts/mysqlbug.sh4
-rw-r--r--scripts/mysqld_multi.sh46
-rw-r--r--scripts/mysqld_safe-watch.sh150
-rw-r--r--scripts/mysqld_safe.sh352
-rw-r--r--scripts/mysqlhotcopy.sh152
-rw-r--r--scripts/safe_mysqld-watch.sh150
-rw-r--r--scripts/safe_mysqld.sh287
-rw-r--r--sql-bench/Comments/interbase18
-rw-r--r--sql-bench/Makefile.am17
-rw-r--r--sql-bench/Results/ATIS-mysql-Linux_2.4.16_64GB_SMP_i68620
-rw-r--r--sql-bench/Results/ATIS-mysql-Linux_2.4.4_SMP_alpha20
-rw-r--r--sql-bench/Results/RUN-mysql-Linux_2.4.16_64GB_SMP_i686109
-rw-r--r--sql-bench/Results/RUN-mysql-Linux_2.4.4_SMP_alpha109
-rw-r--r--sql-bench/Results/alter-table-mysql-Linux_2.4.16_64GB_SMP_i68616
-rw-r--r--sql-bench/Results/alter-table-mysql-Linux_2.4.4_SMP_alpha16
-rw-r--r--sql-bench/Results/big-tables-mysql-Linux_2.4.16_64GB_SMP_i68619
-rw-r--r--sql-bench/Results/big-tables-mysql-Linux_2.4.4_SMP_alpha19
-rw-r--r--sql-bench/Results/connect-mysql-Linux_2.4.16_64GB_SMP_i68635
-rw-r--r--sql-bench/Results/connect-mysql-Linux_2.4.4_SMP_alpha35
-rw-r--r--sql-bench/Results/create-mysql-Linux_2.4.16_64GB_SMP_i68618
-rw-r--r--sql-bench/Results/create-mysql-Linux_2.4.4_SMP_alpha18
-rw-r--r--sql-bench/Results/insert-mysql-Linux_2.4.16_64GB_SMP_i686106
-rw-r--r--sql-bench/Results/insert-mysql-Linux_2.4.4_SMP_alpha106
-rw-r--r--sql-bench/Results/select-mysql-Linux_2.4.16_64GB_SMP_i68630
-rw-r--r--sql-bench/Results/select-mysql-Linux_2.4.4_SMP_alpha30
-rw-r--r--sql-bench/Results/transactions-mysql-Linux_2.4.16_64GB_SMP_i6863
-rw-r--r--sql-bench/Results/transactions-mysql-Linux_2.4.4_SMP_alpha3
-rw-r--r--sql-bench/Results/wisconsin-mysql-Linux_2.4.16_64GB_SMP_i68614
-rw-r--r--sql-bench/Results/wisconsin-mysql-Linux_2.4.4_SMP_alpha14
-rw-r--r--sql-bench/as3ap.sh637
-rw-r--r--sql-bench/bench-count-distinct.sh259
-rw-r--r--sql-bench/bench-init.pl.sh62
-rw-r--r--sql-bench/copy-db.sh3
-rw-r--r--sql-bench/crash-me.sh2097
-rw-r--r--sql-bench/innotest1.sh3
-rw-r--r--sql-bench/innotest1a.sh3
-rw-r--r--sql-bench/innotest1b.sh3
-rw-r--r--sql-bench/innotest2.sh3
-rw-r--r--sql-bench/innotest2a.sh3
-rw-r--r--sql-bench/innotest2b.sh3
-rw-r--r--sql-bench/limits/db2.cfg270
-rw-r--r--sql-bench/limits/interbase-dialect1.cfg514
-rw-r--r--sql-bench/limits/interbase-dialect3.cfg514
-rw-r--r--sql-bench/limits/interbase-superserver.cfg514
-rw-r--r--sql-bench/limits/mysql.cfg6597
-rw-r--r--sql-bench/run-all-tests.sh23
-rw-r--r--sql-bench/server-cfg.sh739
-rw-r--r--sql-bench/test-ATIS.sh20
-rw-r--r--sql-bench/test-alter-table.sh62
-rw-r--r--sql-bench/test-big-tables.sh19
-rw-r--r--sql-bench/test-connect.sh91
-rw-r--r--sql-bench/test-create.sh3
-rw-r--r--sql-bench/test-insert.sh128
-rw-r--r--sql-bench/test-select.sh45
-rw-r--r--sql-bench/test-transactions.sh298
-rw-r--r--sql-bench/test-wisconsin.sh71
-rw-r--r--sql/ChangeLog3302
-rw-r--r--sql/Makefile.am51
-rw-r--r--sql/cache_manager.cc12
-rw-r--r--sql/cache_manager.h10
-rw-r--r--sql/convert.cc28
-rw-r--r--sql/custom_conf.h6
-rw-r--r--sql/derror.cc47
-rw-r--r--sql/des_key_file.cc118
-rw-r--r--sql/field.cc1065
-rw-r--r--sql/field.h271
-rw-r--r--sql/field_conv.cc41
-rw-r--r--sql/filesort.cc391
-rw-r--r--sql/frm_crypt.cc6
-rw-r--r--sql/gen_lex_hash.cc126
-rw-r--r--sql/ha_berkeley.cc136
-rw-r--r--sql/ha_berkeley.h22
-rw-r--r--sql/ha_gemini.cc3630
-rw-r--r--sql/ha_gemini.h208
-rw-r--r--sql/ha_hash.h31
-rw-r--r--sql/ha_heap.cc58
-rw-r--r--sql/ha_heap.h33
-rw-r--r--sql/ha_innobase.cc3876
-rw-r--r--sql/ha_innobase.h203
-rw-r--r--sql/ha_innodb.cc4863
-rw-r--r--sql/ha_innodb.h240
-rw-r--r--sql/ha_isam.cc42
-rw-r--r--sql/ha_isam.h33
-rw-r--r--sql/ha_isammrg.cc28
-rw-r--r--sql/ha_isammrg.h12
-rw-r--r--sql/ha_myisam.cc377
-rw-r--r--sql/ha_myisam.h49
-rw-r--r--sql/ha_myisammrg.cc144
-rw-r--r--sql/ha_myisammrg.h28
-rw-r--r--sql/handler.cc531
-rw-r--r--sql/handler.h228
-rw-r--r--sql/hash_filo.cc6
-rw-r--r--sql/hash_filo.h12
-rw-r--r--sql/hostname.cc15
-rw-r--r--sql/init.cc8
-rw-r--r--sql/item.cc109
-rw-r--r--sql/item.h171
-rw-r--r--sql/item_buff.cc6
-rw-r--r--sql/item_cmpfunc.cc546
-rw-r--r--sql/item_cmpfunc.h99
-rw-r--r--sql/item_create.cc98
-rw-r--r--sql/item_create.h19
-rw-r--r--sql/item_func.cc881
-rw-r--r--sql/item_func.h253
-rw-r--r--sql/item_strfunc.cc623
-rw-r--r--sql/item_strfunc.h110
-rw-r--r--sql/item_sum.cc462
-rw-r--r--sql/item_sum.h123
-rw-r--r--sql/item_timefunc.cc123
-rw-r--r--sql/item_timefunc.h151
-rw-r--r--sql/item_uniq.cc6
-rw-r--r--sql/item_uniq.h10
-rw-r--r--sql/key.cc18
-rw-r--r--sql/lex.h108
-rw-r--r--sql/lex_symbol.h6
-rw-r--r--sql/lock.cc249
-rw-r--r--sql/log.cc1810
-rw-r--r--sql/log_event.cc2476
-rw-r--r--sql/log_event.h816
-rw-r--r--sql/matherr.c8
-rw-r--r--sql/md5.c351
-rw-r--r--sql/md5.h80
-rw-r--r--sql/mf_iocache.cc644
-rw-r--r--sql/mini_client.cc928
-rw-r--r--sql/mini_client.h55
-rw-r--r--sql/my_lock.c10
-rw-r--r--sql/mysql_priv.h487
-rw-r--r--sql/mysqld.cc4415
-rw-r--r--sql/net_pkg.cc73
-rw-r--r--sql/net_serv.cc790
-rw-r--r--sql/nt_servc.cc4
-rw-r--r--sql/opt_ft.cc8
-rw-r--r--sql/opt_ft.h7
-rw-r--r--sql/opt_range.cc619
-rw-r--r--sql/opt_range.h55
-rw-r--r--sql/opt_sum.cc201
-rw-r--r--sql/password.c22
-rw-r--r--sql/procedure.cc6
-rw-r--r--sql/procedure.h10
-rw-r--r--sql/records.cc50
-rw-r--r--sql/repl_failsafe.cc945
-rw-r--r--sql/repl_failsafe.h37
-rw-r--r--sql/set_var.cc1607
-rw-r--r--sql/set_var.h506
-rw-r--r--sql/share/Makefile.am6
-rw-r--r--sql/share/charsets/Index4
-rw-r--r--sql/share/czech/errmsg.txt29
-rw-r--r--sql/share/danish/errmsg.txt27
-rw-r--r--sql/share/dutch/errmsg.txt62
-rw-r--r--sql/share/english/errmsg.txt37
-rw-r--r--sql/share/estonian/errmsg.txt372
-rw-r--r--sql/share/french/errmsg.txt29
-rw-r--r--sql/share/german/errmsg.txt27
-rw-r--r--sql/share/greek/errmsg.txt27
-rw-r--r--sql/share/hungarian/errmsg.txt29
-rw-r--r--sql/share/italian/errmsg.txt29
-rw-r--r--sql/share/japanese/errmsg.txt29
-rw-r--r--sql/share/korean/errmsg.txt29
-rw-r--r--sql/share/norwegian-ny/errmsg.txt29
-rw-r--r--sql/share/norwegian/errmsg.txt29
-rw-r--r--sql/share/polish/errmsg.txt27
-rw-r--r--sql/share/portuguese/errmsg.txt27
-rw-r--r--sql/share/romanian/errmsg.txt27
-rw-r--r--sql/share/russian/errmsg.txt428
-rw-r--r--sql/share/slovak/errmsg.txt29
-rw-r--r--sql/share/spanish/errmsg.txt29
-rw-r--r--sql/share/swedish/errmsg.OLD20
-rw-r--r--sql/share/swedish/errmsg.txt173
-rw-r--r--sql/share/ukrainian/errmsg.txt27
-rw-r--r--sql/slave.cc3947
-rw-r--r--sql/slave.h464
-rw-r--r--sql/sql_acl.cc1372
-rw-r--r--sql/sql_acl.h137
-rw-r--r--sql/sql_analyse.cc121
-rw-r--r--sql/sql_analyse.h37
-rw-r--r--sql/sql_base.cc709
-rw-r--r--sql/sql_cache.cc3596
-rw-r--r--sql/sql_cache.h407
-rw-r--r--sql/sql_class.cc375
-rw-r--r--sql/sql_class.h603
-rw-r--r--sql/sql_crypt.cc12
-rw-r--r--sql/sql_crypt.h6
-rw-r--r--sql/sql_db.cc316
-rw-r--r--sql/sql_delete.cc655
-rw-r--r--sql/sql_do.cc2
-rw-r--r--sql/sql_handler.cc305
-rw-r--r--sql/sql_insert.cc355
-rw-r--r--sql/sql_lex.cc127
-rw-r--r--sql/sql_lex.h145
-rw-r--r--sql/sql_list.cc23
-rw-r--r--sql/sql_list.h125
-rw-r--r--sql/sql_load.cc304
-rw-r--r--sql/sql_manager.cc10
-rw-r--r--sql/sql_map.cc6
-rw-r--r--sql/sql_map.h6
-rw-r--r--sql/sql_olap.cc194
-rw-r--r--sql/sql_parse.cc2720
-rw-r--r--sql/sql_rename.cc54
-rw-r--r--sql/sql_repl.cc1326
-rw-r--r--sql/sql_repl.h60
-rw-r--r--sql/sql_select.cc2690
-rw-r--r--sql/sql_select.h70
-rw-r--r--sql/sql_show.cc570
-rw-r--r--sql/sql_sort.h55
-rw-r--r--sql/sql_string.cc136
-rw-r--r--sql/sql_string.h30
-rw-r--r--sql/sql_table.cc1019
-rw-r--r--sql/sql_test.cc59
-rw-r--r--sql/sql_udf.cc111
-rw-r--r--sql/sql_udf.h6
-rw-r--r--sql/sql_union.cc326
-rw-r--r--sql/sql_update.cc895
-rw-r--r--sql/sql_yacc.yy2786
-rw-r--r--sql/stacktrace.c20
-rw-r--r--sql/structs.h59
-rw-r--r--sql/table.cc191
-rw-r--r--sql/table.h74
-rw-r--r--sql/thr_malloc.cc10
-rw-r--r--sql/time.cc321
-rw-r--r--sql/udf_example.cc63
-rw-r--r--sql/uniques.cc173
-rw-r--r--sql/unireg.cc37
-rw-r--r--sql/unireg.h32
-rw-r--r--sql/violite.c443
-rw-r--r--strings/Makefile.am15
-rw-r--r--strings/atof.c31
-rw-r--r--strings/bchange.c34
-rw-r--r--strings/bcmp.c48
-rw-r--r--strings/bcopy-duff.c29
-rw-r--r--strings/bfill.c2
-rw-r--r--strings/bmove.c2
-rw-r--r--strings/bmove512.c31
-rw-r--r--strings/bmove_upp-sparc.s4
-rw-r--r--strings/bmove_upp.c31
-rw-r--r--strings/bzero.c16
-rw-r--r--strings/conf_to_src.c29
-rw-r--r--strings/ctype-big5.c33
-rw-r--r--strings/ctype-czech.c33
-rw-r--r--strings/ctype-euc_kr.c31
-rw-r--r--strings/ctype-gb2312.c31
-rw-r--r--strings/ctype-gbk.c35
-rw-r--r--strings/ctype-latin1_de.c302
-rw-r--r--strings/ctype-sjis.c31
-rw-r--r--strings/ctype-tis620.c322
-rw-r--r--strings/ctype-ujis.c2
-rw-r--r--strings/ctype.c33
-rw-r--r--strings/do_ctype.c39
-rw-r--r--strings/int2str.c31
-rw-r--r--strings/is_prefix.c31
-rw-r--r--strings/llstr.c31
-rw-r--r--strings/longlong2str.c31
-rw-r--r--strings/memcmp.c29
-rw-r--r--strings/memcpy.c29
-rw-r--r--strings/memset.c18
-rw-r--r--strings/r_strinstr.c31
-rw-r--r--strings/str2int.c34
-rw-r--r--strings/str_test.c34
-rw-r--r--strings/strappend-sparc.s14
-rw-r--r--strings/strappend.c33
-rw-r--r--strings/strcat.c16
-rw-r--r--strings/strcend.c31
-rw-r--r--strings/strchr.c16
-rw-r--r--strings/strcmp.c16
-rw-r--r--strings/strcont.c31
-rw-r--r--strings/strend-sparc.s6
-rw-r--r--strings/strend.c2
-rw-r--r--strings/strfill.c31
-rw-r--r--strings/strings-not-used.h18
-rw-r--r--strings/strinstr.c31
-rw-r--r--strings/strlen.c16
-rw-r--r--strings/strmake-sparc.s8
-rw-r--r--strings/strmake.c33
-rw-r--r--strings/strmov-sparc.s6
-rw-r--r--strings/strmov.c31
-rw-r--r--strings/strnlen.c31
-rw-r--r--strings/strnmov-sparc.s8
-rw-r--r--strings/strnmov.c31
-rw-r--r--strings/strrchr.c16
-rw-r--r--strings/strstr-sparc.s18
-rw-r--r--strings/strstr.c2
-rw-r--r--strings/strto.c38
-rw-r--r--strings/strtol.c31
-rw-r--r--strings/strtoll.c34
-rw-r--r--strings/strtoul.c31
-rw-r--r--strings/strtoull.c32
-rw-r--r--strings/strxmov-sparc.s17
-rw-r--r--strings/strxmov.c2
-rw-r--r--strings/strxnmov.c2
-rw-r--r--strings/t_ctype.h28
-rw-r--r--strings/udiv.c31
-rw-r--r--support-files/MacOSX/Description.plist.sh14
-rw-r--r--support-files/MacOSX/Info.plist.sh38
-rw-r--r--support-files/MacOSX/Makefile.am57
-rwxr-xr-xsupport-files/MacOSX/MySQL53
-rw-r--r--support-files/MacOSX/StartupItem.Description.plist15
-rw-r--r--support-files/MacOSX/StartupItem.Info.plist38
-rwxr-xr-xsupport-files/MacOSX/StartupItem.postinstall36
-rw-r--r--support-files/MacOSX/StartupParameters.plist.sh19
-rw-r--r--support-files/MacOSX/make_mysql_pkg.pl475
-rw-r--r--support-files/MacOSX/postinstall.sh21
-rw-r--r--support-files/MacOSX/preinstall.sh18
-rw-r--r--support-files/Makefile.am11
-rw-r--r--support-files/MySQL-shared-compat.spec.sh72
-rwxr-xr-xsupport-files/SCO/INSTALL.sh (renamed from support-files/PKG/INSTALL.sh)0
-rw-r--r--support-files/SCO/compile.sh (renamed from support-files/PKG/compile.sh)0
-rw-r--r--support-files/SCO/doc.sh (renamed from support-files/PKG/doc.sh)0
-rw-r--r--support-files/SCO/mkpkg.sh (renamed from support-files/PKG/mkpkg.sh)0
-rw-r--r--support-files/SCO/patch (renamed from support-files/PKG/patch)0
-rw-r--r--support-files/SCO/pkginfo.ini (renamed from support-files/PKG/pkginfo.ini)0
-rw-r--r--support-files/SCO/postinstall (renamed from support-files/PKG/postinstall)0
-rw-r--r--support-files/SCO/preinstall (renamed from support-files/PKG/preinstall)0
-rw-r--r--support-files/SCO/preremove (renamed from support-files/PKG/preremove)0
-rw-r--r--support-files/SCO/prototype.ini (renamed from support-files/PKG/prototype.ini)0
-rw-r--r--support-files/SCO/version (renamed from support-files/PKG/version)0
-rw-r--r--support-files/binary-configure.sh2
-rwxr-xr-xsupport-files/build-tags9
-rw-r--r--support-files/make_mysql_pkg.pl414
-rw-r--r--support-files/my-huge.cnf.sh121
-rw-r--r--support-files/my-innodb-heavy-4G.cnf.sh509
-rw-r--r--support-files/my-large.cnf.sh129
-rw-r--r--support-files/my-medium.cnf.sh116
-rw-r--r--support-files/my-small.cnf.sh44
-rw-r--r--support-files/mysql-max.spec.sh4
-rw-r--r--support-files/mysql-multi.server.sh8
-rw-r--r--support-files/mysql.server.sh67
-rw-r--r--support-files/mysql.spec.sh556
-rw-r--r--tests/Makefile.am2
-rwxr-xr-xtests/big_record.pl88
-rwxr-xr-xtests/fork2_test.pl2
-rwxr-xr-xtests/fork_big.pl2
-rw-r--r--tests/function.res6
-rw-r--r--tests/function.tst2
-rw-r--r--tests/grant.pl157
-rw-r--r--tests/grant.res330
-rwxr-xr-xtests/insert_and_repair.pl2
-rwxr-xr-xtests/mail_to_db.pl114
-rw-r--r--tests/myisam-big-rows.tst72
-rwxr-xr-xtests/rename_test.pl2
-rwxr-xr-xtests/table_types.pl35
-rwxr-xr-xtests/test_delayed_insert.pl2
-rwxr-xr-xtests/truncate.pl125
-rw-r--r--tools/Makefile.am10
-rw-r--r--tools/managertest1.nc16
-rw-r--r--tools/mysqlmanager-sample.pwd1
-rw-r--r--tools/mysqlmanager.c1848
-rw-r--r--vio/Makefile.am32
-rw-r--r--vio/Vio.cc23
-rw-r--r--vio/Vio.h64
-rw-r--r--vio/VioAcceptorFd.cc18
-rw-r--r--vio/VioAcceptorFd.h23
-rw-r--r--vio/VioConnectorFd.cc22
-rw-r--r--vio/VioConnectorFd.h19
-rw-r--r--vio/VioFd.cc156
-rw-r--r--vio/VioFd.h38
-rw-r--r--vio/VioPipe.cc25
-rw-r--r--vio/VioPipe.h38
-rw-r--r--vio/VioSSL.cc292
-rw-r--r--vio/VioSSL.h54
-rw-r--r--vio/VioSSLAcceptorFd.cc4
-rw-r--r--vio/VioSSLFactoriesFd.cc360
-rw-r--r--vio/VioSSLFactoriesFd.h64
-rw-r--r--vio/VioSocket.cc326
-rw-r--r--vio/VioSocket.h55
-rw-r--r--vio/docs/COPYING.dbug29
-rw-r--r--vio/docs/COPYING.mysql193
-rw-r--r--vio/docs/CodingStyle8
-rw-r--r--vio/docs/README18
-rw-r--r--vio/test-ssl.c150
-rw-r--r--vio/test-sslclient.c102
-rw-r--r--vio/test-sslserver.c156
-rw-r--r--vio/version.cc7
-rw-r--r--vio/vio-global.h33
-rw-r--r--vio/vio.c133
-rw-r--r--vio/vio_priv.h54
-rw-r--r--vio/vioelitexx.cc26
-rw-r--r--vio/violite.h101
-rw-r--r--vio/viosocket.c335
-rw-r--r--vio/viossl.c403
-rw-r--r--vio/viosslfactories.c360
-rw-r--r--vio/viotest-ssl.c152
-rw-r--r--vio/viotest-ssl.cc104
-rw-r--r--vio/viotypes.h32
2882 files changed, 236563 insertions, 147894 deletions
diff --git a/.bzrignore b/.bzrignore
index b2c877e16c5..79a4d5b1ffd 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -7,6 +7,7 @@
*.la
*.lo
*.o
+*.reject
*.spec
*/*_pure_*warnings
*/.pure
@@ -20,6 +21,8 @@
.out
.snprj/*
.vimrc
+50
+=6
BitKeeper/etc/config
BitKeeper/etc/csets
BitKeeper/etc/csets-in
@@ -32,11 +35,18 @@ BitKeeper/tmp/bkr3sAHD
BitKeeper/tmp/gone
COPYING
COPYING.LIB
+Docs/#manual.texi#
Docs/INSTALL-BINARY
Docs/include.texi
+Docs/internals.html
+Docs/internals.info
+Docs/internals.pdf
+Docs/internals.txt
+Docs/internals_toc.html
Docs/manual.aux
Docs/manual.cp
Docs/manual.cps
+Docs/manual.de.log
Docs/manual.dvi
Docs/manual.fn
Docs/manual.fns
@@ -54,6 +64,10 @@ Docs/manual_letter.ps
Docs/manual_toc.html
Docs/my_sys.doc
Docs/mysql.info
+Docs/mysql.xml
+Docs/safe-mysql.xml
+Docs/tex.fmt
+Docs/texi2dvi.out
INSTALL-SOURCE
Logs/*
MIRRORS
@@ -63,6 +77,13 @@ Makefile.in'
PENDING/*
TAGS
aclocal.m4
+autom4te-2.53.cache/output.0
+autom4te-2.53.cache/requests
+autom4te-2.53.cache/traces.0
+autom4te.cache/*
+autom4te.cache/output.0
+autom4te.cache/requests
+autom4te.cache/traces.0
bdb/README
bdb/btree/btree_auto.c
bdb/build_unix/*
@@ -100,6 +121,13 @@ bdb/build_win32/include.tcl
bdb/build_win32/libdb.rc
bdb/db/crdel_auto.c
bdb/db/db_auto.c
+bdb/dist/autom4te-2.53.cache/output.0
+bdb/dist/autom4te-2.53.cache/requests
+bdb/dist/autom4te-2.53.cache/traces.0
+bdb/dist/autom4te.cache/*
+bdb/dist/autom4te.cache/output.0
+bdb/dist/autom4te.cache/requests
+bdb/dist/autom4te.cache/traces.0
bdb/dist/config.hin
bdb/dist/configure
bdb/dist/tags
@@ -115,17 +143,32 @@ bdb/dist/template/rec_txn
bdb/examples_java
bdb/hash/hash_auto.c
bdb/include/btree_auto.h
+bdb/include/btree_ext.h
+bdb/include/clib_ext.h
+bdb/include/common_ext.h
bdb/include/crdel_auto.h
bdb/include/db_auto.h
+bdb/include/db_ext.h
bdb/include/db_server.h
+bdb/include/env_ext.h
bdb/include/gen_client_ext.h
bdb/include/gen_server_ext.h
bdb/include/hash_auto.h
+bdb/include/hash_ext.h
+bdb/include/lock_ext.h
bdb/include/log_auto.h
+bdb/include/log_ext.h
+bdb/include/mp_ext.h
+bdb/include/mutex_ext.h
+bdb/include/os_ext.h
bdb/include/qam_auto.h
+bdb/include/qam_ext.h
bdb/include/rpc_client_ext.h
bdb/include/rpc_server_ext.h
+bdb/include/tcl_ext.h
bdb/include/txn_auto.h
+bdb/include/txn_ext.h
+bdb/include/xa_ext.h
bdb/java/src/com/sleepycat/db/DbConstants.java
bdb/log/log_auto.c
bdb/qam/qam_auto.c
@@ -140,6 +183,8 @@ bdb/test/include.tcl
bdb/test/logtrack.list
bdb/txn/txn_auto.c
binary/*
+bkpull.log
+build.log
client/insert_test
client/log_event.cc
client/log_event.h
@@ -151,6 +196,8 @@ client/mysqlbinlog
client/mysqlcheck
client/mysqldump
client/mysqlimport
+client/mysqlmanager-pwgen
+client/mysqlmanagerc
client/mysqlshow
client/mysqltest
client/mysys_priv.h
@@ -163,24 +210,41 @@ config.h.in
config.log
config.status
configure
+configure.lineno
core
+core.2430
db-*.*.*
dbug/user.t
+depcomp
extra/comp_err
extra/my_print_defaults
+extra/mysql_install
+extra/mysql_waitpid
extra/perror
extra/replace
extra/resolve_stack_dump
extra/resolveip
gmon.out
+hardcopy.0
heap/hp_test1
heap/hp_test2
include/my_config.h
include/my_global.h
include/mysql_version.h
include/widec.h
+innobase/autom4te-2.53.cache/output.0
+innobase/autom4te-2.53.cache/requests
+innobase/autom4te-2.53.cache/traces.0
+innobase/autom4te.cache/*
+innobase/autom4te.cache/output.0
+innobase/autom4te.cache/requests
+innobase/autom4te.cache/traces.0
+innobase/configure.lineno
+innobase/conftest.s1
+innobase/conftest.subs
innobase/ib_config.h
innobase/ib_config.h.in
+innobase/stamp-h1
isam/isamchk
isam/isamlog
isam/pack_isam
@@ -191,17 +255,133 @@ libmysql/*.c
libmysql/conf_to_src
libmysql/my_static.h
libmysql/mysys_priv.h
+libmysql/net.c
+libmysql/vio_priv.h
libmysql_r/*.c
libmysql_r/acconfig.h
libmysql_r/conf_to_src
libmysql_r/my_static.h
libmysql_r/mysys_priv.h
+libmysql_r/vio_priv.h
+libmysqld/backup_dir
+libmysqld/convert.cc
+libmysqld/derror.cc
+libmysqld/errmsg.c
+libmysqld/examples/completion_hash.cc
+libmysqld/examples/completion_hash.h
+libmysqld/examples/link_sources
+libmysqld/examples/my_readline.h
+libmysqld/examples/mysql
+libmysqld/examples/mysql.cc
+libmysqld/examples/mysqltest
+libmysqld/examples/mysqltest.c
+libmysqld/examples/readline.cc
+libmysqld/examples/sql_string.cc
+libmysqld/examples/sql_string.h
+libmysqld/examples/test-gdbinit
+libmysqld/field.cc
+libmysqld/field_conv.cc
+libmysqld/filesort.cc
+libmysqld/get_password.c
+libmysqld/ha_berkeley.cc
+libmysqld/ha_heap.cc
+libmysqld/ha_innobase.cc
+libmysqld/ha_innodb.cc
+libmysqld/ha_isam.cc
+libmysqld/ha_isammrg.cc
+libmysqld/ha_myisam.cc
+libmysqld/ha_myisammrg.cc
+libmysqld/handler.cc
+libmysqld/hash_filo.cc
+libmysqld/hostname.cc
+libmysqld/init.cc
+libmysqld/item.cc
+libmysqld/item_buff.cc
+libmysqld/item_cmpfunc.cc
+libmysqld/item_create.cc
+libmysqld/item_func.cc
+libmysqld/item_strfunc.cc
+libmysqld/item_sum.cc
+libmysqld/item_timefunc.cc
+libmysqld/item_uniq.cc
+libmysqld/key.cc
+libmysqld/lock.cc
+libmysqld/log.cc
+libmysqld/log_event.cc
+libmysqld/md5.c
+libmysqld/mf_iocache.cc
+libmysqld/mini_client.cc
+libmysqld/net_pkg.cc
+libmysqld/net_serv.cc
+libmysqld/opt_ft.cc
+libmysqld/opt_range.cc
+libmysqld/opt_sum.cc
+libmysqld/password.c
+libmysqld/procedure.cc
+libmysqld/records.cc
+libmysqld/repl_failsafe.cc
+libmysqld/set_var.cc
+libmysqld/simple-test
+libmysqld/slave.cc
+libmysqld/sql_acl.cc
+libmysqld/sql_analyse.cc
+libmysqld/sql_base.cc
+libmysqld/sql_cache.cc
+libmysqld/sql_class.cc
+libmysqld/sql_command
+libmysqld/sql_crypt.cc
+libmysqld/sql_db.cc
+libmysqld/sql_delete.cc
+libmysqld/sql_do.cc
+libmysqld/sql_handler.cc
+libmysqld/sql_insert.cc
+libmysqld/sql_lex.cc
+libmysqld/sql_list.cc
+libmysqld/sql_load.cc
+libmysqld/sql_manager.cc
+libmysqld/sql_map.cc
+libmysqld/sql_olap.cc
+libmysqld/sql_parse.cc
+libmysqld/sql_rename.cc
+libmysqld/sql_repl.cc
+libmysqld/sql_select.cc
+libmysqld/sql_show.cc
+libmysqld/sql_string.cc
+libmysqld/sql_table.cc
+libmysqld/sql_test.cc
+libmysqld/sql_udf.cc
+libmysqld/sql_union.cc
+libmysqld/sql_unions.cc
+libmysqld/sql_update.cc
+libmysqld/sql_yacc.cc
+libmysqld/stacktrace.c
+libmysqld/table.cc
+libmysqld/thr_malloc.cc
+libmysqld/time.cc
+libmysqld/uniques.cc
+libmysqld/unireg.cc
libtool
linked_client_sources
linked_include_sources
linked_libmysql_r_sources
linked_libmysql_sources
+linked_libmysqld_sources
+linked_libmysqldex_sources
linked_server_sources
+linked_tools_sources
+locked
+man/*.1
+mit-pthreads/config.flags
+mit-pthreads/include/bits
+mit-pthreads/include/pthread/machdep.h
+mit-pthreads/include/pthread/posix.h
+mit-pthreads/include/sys
+mit-pthreads/machdep.c
+mit-pthreads/pg++
+mit-pthreads/pgcc
+mit-pthreads/syscall.S
+myisam/FT1.MYD
+myisam/FT1.MYI
myisam/ft_dump
myisam/ft_eval
myisam/ft_test1
@@ -209,26 +389,48 @@ myisam/mi_test1
myisam/mi_test2
myisam/mi_test3
myisam/mi_test_all
+myisam/myisam.log
+myisam/myisam_ftdump
myisam/myisamchk
myisam/myisamlog
myisam/myisampack
myisam/test1.MYD
myisam/test1.MYI
+myisam/test2.MYD
+myisam/test2.MYI
+mysql-4.0.2-alpha-pc-linux-gnu-i686.tar.gz
+mysql-4.0.2-alpha.tar.gz
+mysql-max-4.0.2-alpha-pc-linux-gnu-i686.tar.gz
mysql-test/gmon.out
mysql-test/install_test_db
mysql-test/mysql-test-run
mysql-test/r/*.reject
+mysql-test/r/rpl000001.eval
+mysql-test/r/rpl000002.eval
+mysql-test/r/rpl000014.eval
+mysql-test/r/rpl000015.eval
+mysql-test/r/rpl000016.eval
+mysql-test/r/rpl_log.eval
+mysql-test/r/slave-running.eval
+mysql-test/r/slave-stopped.eval
mysql-test/share/mysql
mysql-test/var/*
mysql.kdevprj
mysql.proj
mysqld.S
mysqld.sym
+mysys/#mf_iocache.c#
+mysys/getopt.c
+mysys/getopt1.c
+mysys/ste5KbMa
mysys/test_charset
mysys/test_dir
+mysys/test_io_cache
mysys/test_thr_alarm
mysys/test_thr_lock
+mysys/test_vsnprintf
mysys/testhash
+pull.log
regex/re
repl-tests/test-repl-ts/repl-timestamp.master.reject
repl-tests/test-repl/foo-dump-slave.master.
@@ -236,21 +438,29 @@ repl-tests/test-repl/sum-wlen-slave.master.
repl-tests/test-repl/sum-wlen-slave.master.re
repl-tests/test-repl/sum-wlen-slave.master.reje
scripts/make_binary_distribution
+scripts/make_sharedlib_distribution
+scripts/make_win_src_distribution
scripts/msql2mysql
scripts/mysql_config
scripts/mysql_convert_table_format
+scripts/mysql_explain_log
scripts/mysql_find_rows
+scripts/mysql_fix_extensions
scripts/mysql_fix_privilege_tables
scripts/mysql_install_db
+scripts/mysql_secure_installation
scripts/mysql_setpermission
+scripts/mysql_tableinfo
scripts/mysql_zap
scripts/mysqlaccess
scripts/mysqlbug
scripts/mysqld_multi
+scripts/mysqld_safe
scripts/mysqldumpslow
scripts/mysqlhotcopy
scripts/safe_mysqld
sql-bench/Results-linux/ATIS-mysql_bdb-Linux_2.2.14_my_SMP_i686
+sql-bench/bench-count-distinct
sql-bench/bench-init.pl
sql-bench/compare-results
sql-bench/compare-results-all
@@ -258,6 +468,12 @@ sql-bench/copy-db
sql-bench/crash-me
sql-bench/gif/*
sql-bench/graph-compare-results
+sql-bench/innotest1
+sql-bench/innotest1a
+sql-bench/innotest1b
+sql-bench/innotest2
+sql-bench/innotest2a
+sql-bench/innotest2b
sql-bench/output/*
sql-bench/run-all-tests
sql-bench/server-cfg
@@ -269,6 +485,7 @@ sql-bench/test-connect
sql-bench/test-create
sql-bench/test-insert
sql-bench/test-select
+sql-bench/test-transactions
sql-bench/test-wisconsin
sql/.gdbinit
sql/gen_lex_hash
@@ -277,17 +494,32 @@ sql/lex_hash.h
sql/mini_client_errors.c
sql/mysqlbinlog
sql/mysqld
+sql/mysqld-purecov
+sql/mysqld-purify
+sql/mysqld-quantify
+sql/new.cc
sql/share/*.sys
sql/share/charsets/gmon.out
sql/share/gmon.out
+sql/share/mysql
sql/share/norwegian-ny/errmsg.sys
sql/share/norwegian/errmsg.sys
+sql/sql_select.cc.orig
sql/sql_yacc.cc
sql/sql_yacc.h
+sql/udf_example.so
stamp-h
+stamp-h.in
+stamp-h1
strings/conf_to_src
strings/ctype_autoconf.c
strings/ctype_extra_sources.c
+support-files/MacOSX/Description.plist
+support-files/MacOSX/Info.plist
+support-files/MacOSX/ReadMe.txt
+support-files/MacOSX/StartupParameters.plist
+support-files/MacOSX/postinstall
+support-files/MacOSX/preinstall
support-files/binary-configure
support-files/my-huge.cnf
support-files/my-large.cnf
@@ -303,37 +535,11 @@ support-files/mysql.server
support-files/mysql.spec
tags
tmp/*
-bdb/include/db_ext.h
-bdb/include/mutex_ext.h
-mit-pthreads/syscall.S
-mit-pthreads/config.flags
-stamp-h.in
-mit-pthreads/include/bits
-mit-pthreads/include/pthread/machdep.h
-mit-pthreads/include/pthread/posix.h
-mit-pthreads/include/sys
-mit-pthreads/machdep.c
-mit-pthreads/pg++
-mit-pthreads/pgcc
-sql-bench/innotest1
-sql-bench/innotest1a
-sql-bench/innotest1b
-sql-bench/innotest2
-sql-bench/innotest2a
-sql-bench/innotest2b
-depcomp
-autom4te.cache/output.0
-autom4te.cache/requests
-autom4te.cache/traces.0
-bdb/dist/autom4te.cache/output.0
-bdb/dist/autom4te.cache/requests
-bdb/dist/autom4te.cache/traces.0
-innobase/autom4te.cache/output.0
-innobase/autom4te.cache/requests
-innobase/autom4te.cache/traces.0
-innobase/stamp-h1
-stamp-h1
-configure.lineno
-innobase/configure.lineno
-sql/udf_example.so
-scripts/make_win_src_distribution
+tools/my_vsnprintf.c
+tools/mysqlmanager
+tools/mysqlmngd
+tools/mysys_priv.h
+vio/test-ssl
+vio/test-sslclient
+vio/test-sslserver
+vio/viotest-ssl
diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh
index fbeaf1e3c68..32a4efefdfb 100644
--- a/BUILD/FINISH.sh
+++ b/BUILD/FINISH.sh
@@ -1,5 +1,6 @@
cflags="$c_warnings $extra_flags"
cxxflags="$cxx_warnings $base_cxxflags $extra_flags"
+extra_configs="$extra_configs $local_infile_configs"
configure="./configure $base_configs $extra_configs"
for arg
do
@@ -10,9 +11,13 @@ done
commands="\
$make -k clean || true
-/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache
+/bin/rm -rf */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache bdb/dist/autom4te.cache autom4te.cache innobase/autom4te.cache;
-aclocal && autoheader && aclocal && automake && autoconf
+aclocal || (echo \"Can't execute aclocal\" && exit 1)
+autoheader || (echo \"Can't execute autoheader\" && exit 1)
+aclocal || (echo \"Can't execute aclocal\" && exit 1)
+automake || (echo \"Can't execute automake\" && exit 1)
+autoconf || (echo \"Can't execute autoconf\" && exit 1)
(cd bdb/dist && sh s_all)
(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
if [ -d gemini ]
diff --git a/BUILD/Makefile.am b/BUILD/Makefile.am
new file mode 100644
index 00000000000..9c1ab24fde7
--- /dev/null
+++ b/BUILD/Makefile.am
@@ -0,0 +1,44 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+
+## Process this file with automake to create Makefile.in
+
+EXTRA_DIST = FINISH.sh \
+ SETUP.sh \
+ compile-alpha \
+ compile-alpha-ccc \
+ compile-alpha-cxx \
+ compile-alpha-debug \
+ compile-ia64-debug-max \
+ compile-pentium \
+ compile-pentium-debug \
+ compile-pentium-debug-max \
+ compile-pentium-debug-no-bdb \
+ compile-pentium-debug-openssl \
+ compile-pentium-gcov \
+ compile-pentium-gprof \
+ compile-pentium-max \
+ compile-pentium-myodbc \
+ compile-pentium-mysqlfs-debug \
+ compile-pentium-pgcc \
+ compile-solaris-sparc \
+ compile-solaris-sparc-debug \
+ compile-solaris-sparc-forte \
+ compile-solaris-sparc-purify
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 52fe960e3a5..150f9e28b41 100644
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -48,7 +48,7 @@ fast_cflags="-O3 -fno-omit-frame-pointer"
# this is one is for someone who thinks 1% speedup is worth not being
# able to backtrace
reckless_cflags="-O3 -fomit-frame-pointer "
-debug_cflags="-DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DSAFE_MUTEX -O1"
+debug_cflags="-DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX -O1 -Wuninitialized"
base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti"
@@ -57,6 +57,10 @@ static_link="--with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static
alpha_configs="" # Not used yet
pentium_configs=""
sparc_configs=""
+# we need local-infile in all binaries for rpl000001
+# if you need to disable local-infile in the client, write a build script
+# and unset local_infile_configs
+local_infile_configs="--enable-local-infile"
debug_configs="--with-debug"
@@ -67,4 +71,22 @@ else
make=make
fi
-CXX=gcc
+if test -z "$CXX" ; then
+ CXX=gcc
+fi
+
+# If ccache (a compiler cache which reduces build time)
+# (http://samba.org/ccache) is installed, use it.
+# We use 'grep' and hope 'grep' will work as expected
+# (returns 0 if finds lines)
+if ccache -V > /dev/null 2>&1
+then
+ if ! (echo "$CC" | grep "ccache" > /dev/null)
+ then
+ CC="ccache $CC"
+ fi
+ if ! (echo "$CXX" | grep "ccache" > /dev/null)
+ then
+ CXX="ccache $CXX"
+ fi
+fi
diff --git a/BUILD/compile-alpha-cxx b/BUILD/compile-alpha-cxx
index 2992604644b..a342d927868 100755
--- a/BUILD/compile-alpha-cxx
+++ b/BUILD/compile-alpha-cxx
@@ -1,17 +1,17 @@
/bin/rm -f */.deps/*.P */*.o
make -k clean
/bin/rm -f */.deps/*.P */*.o
-/bin/rm -f config.cache mysql-*.tar.gz
+/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache mysql-*.tar.gz
aclocal; autoheader; aclocal; automake; autoconf
-CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
+CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared --without-extra-tools --disable-dependency-tracking
-make
-rm */.deps/*
+make -j2
+find . -name ".deps" | xargs rm -r
make
if [ $? = 0 ]
then
- rm */.deps/*
+ find . -name ".deps" | xargs rm -r
bin/mysqladmin shutdown
sur make install
if [ $? = 0 ]
diff --git a/BUILD/compile-alpha-debug b/BUILD/compile-alpha-debug
index 6672027445e..60d1b9af659 100755
--- a/BUILD/compile-alpha-debug
+++ b/BUILD/compile-alpha-debug
@@ -1,7 +1,8 @@
+/bin/rm -f */.deps/*.P */*.o
make -k clean
-/bin/rm -f */.deps/*.P
-/bin/rm -f config.cache
+/bin/rm -f */.deps/*.P */*.o
+/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache mysql-*.tar.gz
aclocal; autoheader; aclocal; automake; autoconf
-CFLAGS=-O6 CXX=gcc CXXFLAGS="-O6 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug
+CFLAGS=-O1 CC=gcc CXX=gcc CXXFLAGS="-O1 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug --with-extra-charsets=complex --without-extra-tools
make
diff --git a/BUILD/compile-ia64-debug-max b/BUILD/compile-ia64-debug-max
new file mode 100755
index 00000000000..9cd54de428d
--- /dev/null
+++ b/BUILD/compile-ia64-debug-max
@@ -0,0 +1,13 @@
+gmake -k clean || true
+/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache
+
+aclocal && autoheader && aclocal && automake && autoconf
+(cd bdb/dist && sh s_all)
+(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
+if [ -d gemini ]
+then
+ (cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
+fi
+
+CC=ecc CFLAGS="-w1 -DEXTRA_DEBUG -DSAFEMALLOC -DSAFE_MUTEX -O2" CXX=ecc CXXFLAGS="-w1 -DEXTRA_DEBUG -DSAFEMALLOC -DSAFE_MUTEX -O2" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static --with-debug --with-innodb --with-embedded-server
+gmake
diff --git a/BUILD/compile-irix-mips64-mipspro b/BUILD/compile-irix-mips64-mipspro
new file mode 100755
index 00000000000..d8107ad73c0
--- /dev/null
+++ b/BUILD/compile-irix-mips64-mipspro
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+if [ ! -f "sql/mysqld.cc" ]; then
+ echo "You must run this script from the MySQL top-level directory."
+ exit 1
+fi
+
+cflags="-64 -mips4"
+
+if [ "$#" != 0 ]; then
+ case "$1" in
+ --help)
+ echo "Usage: $0 [options]"
+ echo "Options:"
+ echo "--help print this message"
+ echo "-32 build 32-bit binary"
+ echo "-64 build 64-bit binary [default]"
+ exit 0
+ ;;
+ -64)
+ echo "Building 64-bit binary"
+ ;;
+ -32)
+ echo "Building 32-bit binary"
+ cflags=""
+ ;;
+ *)
+ echo "$0: invalid option '$1'; use --help to show usage"
+ exit 1
+ ;;
+ esac
+else
+ echo "Building 64-bit binary"
+fi
+
+set -x
+make distclean
+aclocal
+autoheader
+libtoolize --automake --force
+automake --force --add-missing
+autoconf
+
+(cd bdb/dist && sh s_all)
+(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
+
+# C options:
+# -apo - auto-parallize for multiprocessors (implies -mp)
+# -mp - generate multiprocessor code
+# These two common optimization options apparently use 'sproc' model of
+# threading, which is not compatible with PTHREADS: don't add them unless you
+# know what you're doing.
+#
+# -c99 - enable C features standardized in C99, such as long long,
+# strtoll, stroull etc.
+# This option is vital to compile MySQL.
+# -woff - turn off some warnings
+# -64 - generate 64 bit object (implies -mips4)
+# -mips4 - produce code for MIPS R10000, MIPS R12000 and further 64 bit
+# processors
+# -OPT:Olimit=0 - no limits exists to size of function for compiler to optimize
+# it
+nowarn="-woff 1064,1188,1460,1552,1681,1682,3303"
+cflags="$cflags $nowarn -O3 -c99 -OPT:Olimit=0"
+
+# C++ only options:
+# -LANG:exceptions=OFF - don't generate exception handling code
+# MySQL doesn't use exceptions.
+# -LANG:std=OFF - don't link standard C++ library, such as
+# <iostream>, <complex>, etc.
+# -LANG:libc_in_namespace_std=OFF - libstdc functions can be
+# declared in namespace 'std', when included
+# into C++ code. Switch this feature off.
+# This option is vital to compile MySQL
+
+cxxflags="$cflags -LANG:exceptions=OFF -LANG:std=OFF"
+cxxflags="$cxxflags -LANG:libc_in_namespace_std=OFF"
+
+CC=cc CXX=CC CFLAGS="$cflags" CXXFLAGS="$cxxflags" \
+./configure --prefix=/usr/local/mysql --disable-shared \
+ --with-extra-charsets=complex --enable-thread-safe-client \
+ --without-extra-tools --disable-dependency-tracking
+
+make
diff --git a/BUILD/compile-pentium-debug b/BUILD/compile-pentium-debug
index 7d25ac4a406..d8a6b60809b 100755
--- a/BUILD/compile-pentium-debug
+++ b/BUILD/compile-pentium-debug
@@ -6,7 +6,7 @@ path=`dirname $0`
extra_flags="$pentium_cflags $debug_cflags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
-extra_configs="$pentium_configs $debug_configs"
+extra_configs="$pentium_configs $debug_configs $static_link"
extra_configs="$extra_configs "
diff --git a/BUILD/compile-pentium-debug-max b/BUILD/compile-pentium-debug-max
index 993c48565b8..1684686ce8c 100755
--- a/BUILD/compile-pentium-debug-max
+++ b/BUILD/compile-pentium-debug-max
@@ -8,6 +8,6 @@ c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs"
-extra_configs="$extra_configs --with-berkeley-db --with-innodb --enable-local-infile"
+extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-embedded-server --with-openssl"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-debug-no-bdb b/BUILD/compile-pentium-debug-no-bdb
index fad58bec437..d7e70f868cc 100755
--- a/BUILD/compile-pentium-debug-no-bdb
+++ b/BUILD/compile-pentium-debug-no-bdb
@@ -4,6 +4,6 @@ path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium_cflags $debug_cflags"
-extra_configs="$pentium_configs $debug_configs --without-berkeley-db"
+extra_configs="$pentium_configs $debug_configs --without-berkeley-db $static_link"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-debug-openssl b/BUILD/compile-pentium-debug-openssl
new file mode 100755
index 00000000000..5de1c18a5d7
--- /dev/null
+++ b/BUILD/compile-pentium-debug-openssl
@@ -0,0 +1,13 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_flags="$pentium_cflags $debug_cflags"
+c_warnings="$c_warnings $debug_extra_warnings"
+cxx_warnings="$cxx_warnings $debug_extra_warnings"
+extra_configs="$pentium_configs $debug_configs"
+
+extra_configs="$extra_configs --with-debug=full --with-vio --with-openssl --without-innodb"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-gcov b/BUILD/compile-pentium-gcov
index 0bc7eb2a8fa..39c0e0591e8 100755
--- a/BUILD/compile-pentium-gcov
+++ b/BUILD/compile-pentium-gcov
@@ -5,5 +5,6 @@ path=`dirname $0`
extra_flags="$pentium_cflags -O2 -fprofile-arcs -ftest-coverage -fmessage-length=0 "
extra_configs="$pentium_configs $debug_configs --disable-shared $static_link"
+extra_configs="$extra_configs --with-innodb --with-berkeley-db"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-max b/BUILD/compile-pentium-max
index 55f88ef4748..34a497807df 100755
--- a/BUILD/compile-pentium-max
+++ b/BUILD/compile-pentium-max
@@ -8,6 +8,7 @@ extra_configs="$pentium_configs"
strip=yes
extra_configs="$extra_configs --with-innodb --with-berkeley-db \
- --enable-thread-safe-client"
+ --with-embedded-server --enable-thread-safe-client \
+ --with-openssl --with-vio --with-raid"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-mysqlfs-debug b/BUILD/compile-pentium-mysqlfs-debug
new file mode 100755
index 00000000000..6643553d943
--- /dev/null
+++ b/BUILD/compile-pentium-mysqlfs-debug
@@ -0,0 +1,13 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_flags="$pentium_cflags $debug_cflags"
+c_warnings="$c_warnings $debug_extra_warnings"
+cxx_warnings="$cxx_warnings $debug_extra_warnings"
+extra_configs="$pentium_configs $debug_configs $static_link"
+
+extra_configs="$extra_configs --with-debug=full --with-mysqlfs --without-server --without-pstack"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-pgcc b/BUILD/compile-pentium-pgcc
index ee70fd2bde0..2d806009b21 100755
--- a/BUILD/compile-pentium-pgcc
+++ b/BUILD/compile-pentium-pgcc
@@ -1,10 +1,21 @@
AM_MAKEFLAGS="-j 2"
-make -k clean
+gmake -k clean || true
/bin/rm -f */.deps/*.P config.cache
-
-aclocal; autoheader; aclocal; automake; autoconf
-
+
+aclocal && autoheader && aclocal && automake && autoconf
+(cd bdb/dist && sh s_all)
+(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
+if [ -d gemini ]
+then
+ (cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
+fi
+
export PATH=/usr/local/pgcc/bin:$PATH
-CFLAGS="-O6 -mpentiumpro -fomit-frame-pointer -mstack-align-double" CXX=gcc CXXFLAGS="-O6 -mpentiumpro -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -mstack-align-double" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-extra-charsets=complex --enable-thread-safe-client
-make -j 2
+CFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O6 -mpentiumpro -fomit-frame-pointer -mstack-align-double" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O6 -fomit-frame-pointer -mpentiumpro -mstack-align-double" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static
+
+gmake -j 4
+
+mkdir -p tmp
+nm --numeric-sort sql/mysqld > tmp/mysqld.sym
+objdump -d sql/mysqld > tmp/mysqld.S
strip sql/mysqld
diff --git a/BUILD/compile-pentium-symbols b/BUILD/compile-pentium-symbols
deleted file mode 100755
index 4f63763606f..00000000000
--- a/BUILD/compile-pentium-symbols
+++ /dev/null
@@ -1,15 +0,0 @@
-#! /bin/sh
-
-path=`dirname $0`
-. "$path/SETUP.sh"
-
-extra_flags="$pentium_cflags $fast_cflags -g"
-extra_configs="$pentium_configs"
-
-# Use the optimized version if it exists
-if test -d /usr/local/BerkeleyDB-opt/
-then
- extra_configs="$extra_configs --with-berkeley-db=/usr/local/BerkeleyDB-opt/"
-fi
-
-. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-valgrind-max b/BUILD/compile-pentium-valgrind-max
index d58ee723aee..0201001c959 100755
--- a/BUILD/compile-pentium-valgrind-max
+++ b/BUILD/compile-pentium-valgrind-max
@@ -1,13 +1,37 @@
#! /bin/sh
+echo "\
+********************************************************************************
+Note that by default BUILD/compile-pentium-valgrind-max calls 'configure' with
+--enable-assembler. When Valgrind detects an error involving an assembly
+function (for example an uninitialized value used as an argument of an assembly
+function), Valgrind will not print the stacktrace and 'valgrind
+--gdb-attach=yes' will not work either. If you need a stacktrace in those cases,
+you have to run BUILD/compile-pentium-valgrind-max with the --disable-assembler
+argument.
+********************************************************************************
+"
+
path=`dirname $0`
. "$path/SETUP.sh"
-extra_flags="$pentium_cflags $debug_cflags -DHAVE_purify"
+extra_flags="$pentium_cflags $debug_cflags -USAFEMALLOC -DHAVE_purify"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs"
-extra_configs="$extra_configs"
+extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-embedded-server --with-openssl"
. "$path/FINISH.sh"
+
+echo "\
+********************************************************************************
+Note that by default BUILD/compile-pentium-valgrind-max calls 'configure' with
+--enable-assembler. When Valgrind detects an error involving an assembly
+function (for example an uninitialized value used as an argument of an assembly
+function), Valgrind will not print the stacktrace and 'valgrind
+--gdb-attach=yes' will not work either. If you need a stacktrace in those cases,
+you have to run BUILD/compile-pentium-valgrind-max with the --disable-assembler
+argument.
+********************************************************************************
+"
diff --git a/BUILD/compile-solaris-sparc b/BUILD/compile-solaris-sparc
index af7c4bc5bc5..143a4b7867d 100755
--- a/BUILD/compile-solaris-sparc
+++ b/BUILD/compile-solaris-sparc
@@ -11,6 +11,6 @@ then
(cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
fi
-CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
gmake -j 4
diff --git a/BUILD/compile-solaris-sparc-debug b/BUILD/compile-solaris-sparc-debug
new file mode 100755
index 00000000000..527f135ac62
--- /dev/null
+++ b/BUILD/compile-solaris-sparc-debug
@@ -0,0 +1,16 @@
+#! /bin/sh
+
+gmake -k clean || true
+/bin/rm -f */.deps/*.P config.cache
+
+aclocal && autoheader && aclocal && automake && autoconf
+(cd bdb/dist && sh s_all)
+(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
+if [ -d gemini ]
+then
+ (cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
+fi
+
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-debug
+
+gmake -j 4
diff --git a/BUILD/compile-solaris-sparc-forte b/BUILD/compile-solaris-sparc-forte
new file mode 100755
index 00000000000..afd106afc67
--- /dev/null
+++ b/BUILD/compile-solaris-sparc-forte
@@ -0,0 +1,39 @@
+#! /bin/sh
+
+gmake -k clean || true
+/bin/rm -f */.deps/*.P config.cache
+
+aclocal && autoheader && aclocal && automake && autoconf
+(cd bdb/dist && sh s_all)
+(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
+if [ -d gemini ]
+then
+ (cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
+fi
+
+
+# Assume Forte is installed in /opt/SUNWSpro
+
+PATH=/opt/SUNWspro/bin/:$PATH
+
+# For "optimal" code for this computer add -fast to EXTRA
+# To compile 64 bit, add -xarch=v9 to EXTRA_64_BIT
+
+EXTRA_64_BIT="-xarch=v9" # Remove comment to get 64 bit binaries
+EXTRA="-fast" # Remove comment to target current machine
+
+#
+# The following should not need to be touched
+#
+
+STD="-mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT"
+ASFLAGS="$EXTRA_64_BIT" \
+CC=cc-5.0 CFLAGS="-Xa -xstrconst $STD" \
+CXX=CC CXXFLAGS="-noex $STD" \
+./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
+
+gmake -j 4
+if [ $? = 0 ]
+then
+ make test
+fi
diff --git a/BUILD/compile-solaris-sparc-fortre b/BUILD/compile-solaris-sparc-fortre
deleted file mode 100755
index dca0412c979..00000000000
--- a/BUILD/compile-solaris-sparc-fortre
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /bin/sh
-
-gmake -k clean || true
-/bin/rm -f */.deps/*.P config.cache
-
-aclocal && autoheader && aclocal && automake && autoconf
-(cd bdb/dist && sh s_all)
-(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
-if [ -d gemini ]
-then
- (cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
-fi
-
-PATH=/opt/SUNWspro/bin/:$PATH
-CC=cc CFLAGS="-Xa -fast -xO4 -native -xstrconst -mt -D_FORTREC_" \
-CXX=CC CXXFLAGS="-noex -xO4 -mt" \
-./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
-
-gmake -j 4
diff --git a/BUILD/compile-solaris-sparc-purify b/BUILD/compile-solaris-sparc-purify
index d73d817dd6c..71a60e45cb0 100755
--- a/BUILD/compile-solaris-sparc-purify
+++ b/BUILD/compile-solaris-sparc-purify
@@ -1,17 +1,30 @@
#! /bin/sh
+
+while test $# -gt 0
+do
+ case "$1" in
+ --debug) EXTRA_CONFIG_FLAGS=--with-debug; shift ;;
+ -h | --help ) cat <<EOF; exit 0 ;;
+Usage: $0 [-h|-n] [configure-options]
+ --debug Compile with DBUG enabled
+EOF
+ *) echo "No such option '$1'" ; exit ;;
+ esac
+done
+
gmake -k clean || true
/bin/rm -f */.deps/*.P config.cache
-
aclocal && autoheader && aclocal && automake && autoconf
(cd bdb/dist && sh s_all)
(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
-CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -DHAVE_purify -DEXTRA_DEBUG -O2" CXX=gcc CXXLD=g++ CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -DHAVE_purify -DEXTRA_DEBUG -O2" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-berkeley-db --with-innodb
+CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -DHAVE_purify -DEXTRA_DEBUG -O2" CXX=gcc CXXLD=g++ CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -DHAVE_purify -DEXTRA_DEBUG -O2" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-berkeley-db --with-innodb $EXTRA_CONFIG_FLAGS
gmake -j 4
-cd sql ; rm mysqld ;
+cd sql ; mv mysqld mysqld-org ;
make CXXLD="purify -best-effort g++" mysqld ; mv mysqld mysqld-purify
make CXXLD="quantify -best-effort g++" mysqld ; mv mysqld mysqld-quantify
make CXXLD="purecov -best-effort g++" mysqld ; mv mysqld mysqld-purecov
+mv mysqld-org mysqld
diff --git a/BitKeeper/etc/config b/BitKeeper/etc/config
index 1faf57416f5..9df006ac7d5 100644
--- a/BitKeeper/etc/config
+++ b/BitKeeper/etc/config
@@ -51,7 +51,7 @@ contact: sys@mysql.com
# response from anyone else at your location after 90 days, then open logging
# will be implicitly approved.
#
-email: sys@mysql.com
+email: sys@mysql.com
#
# Add your street address if you like, it is optional.
#
diff --git a/BitKeeper/etc/gone b/BitKeeper/etc/gone
index 6d4da9062d2..ad2ffda4d6e 100644
--- a/BitKeeper/etc/gone
+++ b/BitKeeper/etc/gone
@@ -1,8 +1,27 @@
BK|Build-tools/Do-compile-all|19700101030959|00060|f119832ce3aca102
+BK|Docs/Attic/myisam.doc|19700101030959|00502|519bb06ecc870298
+BK|Docs/Flags/island.eps|19700101030959|00181|8cec5a55768bc59e
+BK|Docs/Flags/island.gif|19700101030959|00142|e274d5e96ee0975a
+BK|Docs/Flags/island.txt|19700101030959|00220|301ede0f81c5f3e1
+BK|Docs/Flags/kroatia.eps|19700101030959|00185|f50fcd444e7efceb
+BK|Docs/Flags/kroatia.gif|19700101030959|00146|bea7bbe0316d462d
+BK|Docs/Flags/kroatia.txt|19700101030959|00224|dde7f89f25d616b2
+BK|Docs/Flags/south-africa1.eps|19700101030959|00193|111e4f92f4562e9d
+BK|Docs/Flags/south-africa1.gif|19700101030959|00154|1ea38de5a535f732
+BK|Docs/Flags/south-africa1.txt|19700101030959|00232|87a53fdcd2149c6e
+BK|client/Attic/libmysql.c|19700101030959|00582|72949a7043113807
+BK|client/Attic/net.c|19700101030959|00583|c18042da6fa4e693
BK|client/mysql-test.c|19700101030959|00560|809ade45d58e28ab
+BK|client/violite.c|19700101030959|00561|afa871b4aab14371
BK|config.h.in|19700101030959|00050|aecae693cca472c
+BK|extra/Attic/print_defaults.c|19700101030959|01513|362952979aa7b330
+BK|include/Attic/config-win32.h|19700101030959|00116|65db818ec7e8f21b
+BK|include/Attic/m_ctype.h.in|19700101030959|00114|f671e3c2d611ba97
+BK|include/Attic/mysql_com.h.in|19700101030959|00115|85b1ea7ced528c32
BK|include/my_global.h|19700101030959|00105|f657f708961a4632
BK|libmysql/acconfig.h|19700101030959|02604|7b620dbd69ea6074
+BK|libmysql/configure.in|19700101030959|02603|c6fc04d4e3d6e291
+BK|libmysql/violite.c|19700101030959|02600|984c09cffe14a11b
BK|mit-pthreads/config.flags|19700101030959|00594|dcec5296ef811cd6
BK|mit-pthreads/machdep/i386-sco-3.2v5/__math.h|19700101030959|01011|79d9a37715f2c7fe
BK|mit-pthreads/machdep/i386-sco-3.2v5/__signal.h|19700101030959|01012|45332b2a56f62580
@@ -32,9 +51,15 @@ BK|mit-pthreads/machdep/sco-3.2v5/socket.h|19700101030959|00980|1b409f3f1fcbbf7a
BK|mit-pthreads/machdep/sco-3.2v5/syscall.h|19700101030959|00981|c69bd58eba4d5076
BK|mit-pthreads/machdep/sco-3.2v5/timers.h|19700101030959|00982|4907a958151368ed
BK|mit-pthreads/machdep/sco-3.2v5/trash.can|19700101030959|00983|7eecac9fc944ade2
+BK|mit-pthreads/pg++|19700101030959|00597|3beac0502025d766
+BK|mit-pthreads/pgcc|19700101030959|00596|154a03d0c1a0a600
+BK|myisam/Attic/ft_global.h|19700101030959|01673|fe46fb515f1e375
BK|myisam/common_words|19700101030959|01665|13c10ef32aaa7537
+BK|myisam/ft_search.c|19700101030959|01642|c011cb6e8041bb59
BK|myisam/mi_test_all|19700101030959|01666|ae7a366c45527b4e
+BK|mysql.proj|19700101030959|00071|3e34edc585d18be8
BK|mysys/mf_reccache.c|19700101030959|01419|f8191c8485e158fe
+BK|mysys/test_vsnprintf.c|19700101030959|01502|e3d568aca62dc81e
BK|sql-bench/Results-linux/ATIS-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02361|6a0a837742a861bb
BK|sql-bench/Results-linux/ATIS-interbase-Linux_2.2.14_5.0_i686|19700101030959|02348|e87091e2a6dce931
BK|sql-bench/Results-linux/ATIS-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02326|70981cb1dd58d3fb
@@ -161,12 +186,23 @@ BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.2.12_20smp_i686|1970010103095
BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02347|ad7babd436f26841
BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02442|74b238eca114dbbe
BK|sql-bench/Results-linux/wisconsin-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02451|6ad065fe4c6b4fa9
+BK|sql-bench/Results-win32/ATIS-mysql-win98|19700101030959|02523|cd0705815d3af451
+BK|sql-bench/Results-win32/RUN-mysql-win98|19700101030959|02526|7f09e396772a8665
+BK|sql-bench/Results-win32/alter-table-mysql-win98|19700101030959|02529|e8743982f790462
+BK|sql-bench/Results-win32/big-tables-mysql-win98|19700101030959|02532|99a1882effebbdf2
+BK|sql-bench/Results-win32/connect-mysql-win98|19700101030959|02535|2a11d5e3dfc0bc67
+BK|sql-bench/Results-win32/create-mysql-win98|19700101030959|02538|f66c2cb2909c4792
+BK|sql-bench/Results-win32/insert-mysql-win98|19700101030959|02541|6d6cafc85a6c837
+BK|sql-bench/Results-win32/select-mysql-win98|19700101030959|02544|f370fac2d66a9faf
+BK|sql-bench/Results-win32/wisconsin-mysql-win98|19700101030959|02547|8b3da9c5c5d2365b
+BK|sql-bench/Results/ATIS-mysql-3.21-Linux_2.2.1_i686|19700101030959|02022|660fb76ed6ccfb6f
BK|sql-bench/Results/ATIS-mysql-Linux_2.2.10_i686|19700101030959|02025|3fa4d167cceff7e8
BK|sql-bench/Results/ATIS-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02312|84ca3b85ff306133
BK|sql-bench/Results/ATIS-mysql-Linux_2.2.14_i686_xeon|19700101030959|02044|3e820c28bf4af63a
BK|sql-bench/Results/ATIS-mysql-SunOS_5.5.1_sun4u|19700101030959|02031|dfb4c5f6b6db3b49
BK|sql-bench/Results/ATIS-mysql-SunOS_5.6_sun4m|19700101030959|02032|62028e0375b3b8b
BK|sql-bench/Results/ATIS-mysql-SunOS_5.7_sun4u|19700101030959|02034|be0d9789776c5ed7
+BK|sql-bench/Results/ATIS-mysql_3.21-Linux_2.0.35_i686|19700101030959|02036|c25425e045ca8dfc
BK|sql-bench/Results/ATIS-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02304|cbe120d860296d2f
BK|sql-bench/Results/ATIS-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02027|a74e7b82d3908fa9
BK|sql-bench/Results/ATIS-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02313|8c6fc2968f78773
@@ -225,90 +261,309 @@ BK|sql-bench/Results/Attic/wisconsin-mysql-Linux_2.2.1_i686-cmp-mysql,pg|1970010
BK|sql-bench/Results/Attic/wisconsin-mysql_fast-Linux_2.2.10_i686-cmp-mysql,pg|19700101030959|02218|b4e89cdac0620cba
BK|sql-bench/Results/Attic/wisconsin-pg-Linux_2.2.10_i686-cmp-mysql,pg|19700101030959|02219|7d641554f51cf45a
BK|sql-bench/Results/Attic/wisconsin-pg_fast-Linux_2.2.10_i686-cmp-mysql,pg|19700101030959|02220|db31ec971b4c5051
+BK|sql-bench/Results/RUN-mysql-3.21-Linux_2.2.1_i686|19700101030959|02050|f6fdd64859e11de9
BK|sql-bench/Results/RUN-mysql-Linux_2.2.10_i686|19700101030959|02041|712f52be5d195406
BK|sql-bench/Results/RUN-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02038|8ee87b26b91c86fe
BK|sql-bench/Results/RUN-mysql-Linux_2.2.14_i686_xeon|19700101030959|02055|17854e751e1d9d1d
BK|sql-bench/Results/RUN-mysql-SunOS_5.5.1_sun4u|19700101030959|02058|afbba182428e20df
BK|sql-bench/Results/RUN-mysql-SunOS_5.6_sun4m|19700101030959|02059|eafc8188345e262b
BK|sql-bench/Results/RUN-mysql-SunOS_5.7_sun4u|19700101030959|02061|86e1dc0e25a8b8f
+BK|sql-bench/Results/RUN-mysql_3.21-Linux_2.0.35_i686|19700101030959|02064|ea8672d8473435
BK|sql-bench/Results/RUN-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02310|a902e1a967d79c42
BK|sql-bench/Results/RUN-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02030|413ab3b8a99e61e9
BK|sql-bench/Results/RUN-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02046|a910a9b3fde431e1
BK|sql-bench/Results/RUN-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02165|e0f060fdbf92325e
+BK|sql-bench/Results/alter-table-mysql-3.21-Linux_2.2.1_i686|19700101030959|02073|f6f7ccd7b3c35f97
BK|sql-bench/Results/alter-table-mysql-Linux_2.2.10_i686|19700101030959|02081|93b78a85b720a186
BK|sql-bench/Results/alter-table-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02314|4ae4b989301df98b
BK|sql-bench/Results/alter-table-mysql-Linux_2.2.14_i686_xeon|19700101030959|02057|64cc4b874cd6fabf
BK|sql-bench/Results/alter-table-mysql-SunOS_5.5.1_sun4u|19700101030959|02087|9d7e75667fcb29ec
BK|sql-bench/Results/alter-table-mysql-SunOS_5.6_sun4m|19700101030959|02088|8a1bd6589a189890
BK|sql-bench/Results/alter-table-mysql-SunOS_5.7_sun4u|19700101030959|02090|ce74c2f623d3bb3
+BK|sql-bench/Results/alter-table-mysql_3.21-Linux_2.0.35_i686|19700101030959|02092|762639f2560976bd
BK|sql-bench/Results/alter-table-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02316|1390155aad5b6e86
BK|sql-bench/Results/alter-table-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02317|9090bebb62ef164b
BK|sql-bench/Results/alter-table-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02094|4e02d36dc17ecbfa
BK|sql-bench/Results/alter-table-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02233|b8721431b356177
+BK|sql-bench/Results/big-tables-mysql-3.21-Linux_2.2.1_i686|19700101030959|02106|baa649caba113497
BK|sql-bench/Results/big-tables-mysql-Linux_2.2.10_i686|19700101030959|02109|99daa1c5370d077d
BK|sql-bench/Results/big-tables-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02315|2804ec3c95be436a
BK|sql-bench/Results/big-tables-mysql-Linux_2.2.14_i686_xeon|19700101030959|02074|290c2c3de9d8e6b
BK|sql-bench/Results/big-tables-mysql-SunOS_5.5.1_sun4u|19700101030959|02115|7d7b6c0bf58b9b79
BK|sql-bench/Results/big-tables-mysql-SunOS_5.6_sun4m|19700101030959|02116|f351a7f3e1e2257e
BK|sql-bench/Results/big-tables-mysql-SunOS_5.7_sun4u|19700101030959|02118|ebc379b231312bbe
+BK|sql-bench/Results/big-tables-mysql_3.21-Linux_2.0.35_i686|19700101030959|02120|190e827e569c99a4
BK|sql-bench/Results/big-tables-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02318|c5eabcb89ceac698
BK|sql-bench/Results/big-tables-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02319|856d503725373684
BK|sql-bench/Results/big-tables-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02122|a442a8aff47fae20
BK|sql-bench/Results/big-tables-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02235|e5a33639e51290fd
+BK|sql-bench/Results/connect-mysql-3.21-Linux_2.2.1_i686|19700101030959|02134|c0c26d4320182d85
BK|sql-bench/Results/connect-mysql-Linux_2.2.10_i686|19700101030959|02137|c92505d77e19d5ec
BK|sql-bench/Results/connect-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02084|e7e2959b7387251f
BK|sql-bench/Results/connect-mysql-Linux_2.2.14_i686_xeon|19700101030959|02071|ea19dc3ec55b3618
BK|sql-bench/Results/connect-mysql-SunOS_5.5.1_sun4u|19700101030959|02142|a9493110fe62e0b1
BK|sql-bench/Results/connect-mysql-SunOS_5.6_sun4m|19700101030959|02143|a10e3ddfa26a3e7f
BK|sql-bench/Results/connect-mysql-SunOS_5.7_sun4u|19700101030959|02145|c67beb9e9d2cf32e
+BK|sql-bench/Results/connect-mysql_3.21-Linux_2.0.35_i686|19700101030959|02146|650abd213e6828c6
BK|sql-bench/Results/connect-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02320|ce69cc65bc827b5c
BK|sql-bench/Results/connect-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02066|f801e08429a4f7c6
BK|sql-bench/Results/connect-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02086|1d95d36fd717990
BK|sql-bench/Results/connect-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02244|f6ab4d00b0ae09c1
+BK|sql-bench/Results/create-mysql-3.21-Linux_2.2.1_i686|19700101030959|02158|51581b24f45e0f5c
BK|sql-bench/Results/create-mysql-Linux_2.2.10_i686|19700101030959|02161|9e7822f66df6aa76
BK|sql-bench/Results/create-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02102|34ded91c5fc25de9
BK|sql-bench/Results/create-mysql-Linux_2.2.14_i686_xeon|19700101030959|02139|50d15991293030ef
BK|sql-bench/Results/create-mysql-SunOS_5.5.1_sun4u|19700101030959|02166|bbb5de66fc56de7b
BK|sql-bench/Results/create-mysql-SunOS_5.6_sun4m|19700101030959|02221|9233114ae6f8c5f
BK|sql-bench/Results/create-mysql-SunOS_5.7_sun4u|19700101030959|02223|7ee13bfcafeab498
+BK|sql-bench/Results/create-mysql_3.21-Linux_2.0.35_i686|19700101030959|02225|df1b037d17b33587
BK|sql-bench/Results/create-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02321|e985e71d552ff09e
BK|sql-bench/Results/create-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02099|483dcf223d5abf81
BK|sql-bench/Results/create-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02112|a140e5e229a53b7b
BK|sql-bench/Results/create-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02246|177fd39cc1d298a8
+BK|sql-bench/Results/insert-mysql-3.21-Linux_2.2.1_i686|19700101030959|02239|fd082017c7c57a6
BK|sql-bench/Results/insert-mysql-Linux_2.2.10_i686|19700101030959|02242|763edf9aec633f51
BK|sql-bench/Results/insert-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02130|5be3d6f299738a31
BK|sql-bench/Results/insert-mysql-Linux_2.2.14_i686_xeon|19700101030959|02141|c683ee4b9d214298
BK|sql-bench/Results/insert-mysql-SunOS_5.5.1_sun4u|19700101030959|02247|8a9ae41f9a79f79
BK|sql-bench/Results/insert-mysql-SunOS_5.6_sun4m|19700101030959|02248|3402d060ae20e19
BK|sql-bench/Results/insert-mysql-SunOS_5.7_sun4u|19700101030959|02250|78efa132c6e252b9
+BK|sql-bench/Results/insert-mysql_3.21-Linux_2.0.35_i686|19700101030959|02252|60c0965dff31db07
BK|sql-bench/Results/insert-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02322|ed252140ff399961
BK|sql-bench/Results/insert-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02114|29a3b8a1ca8aa9d
BK|sql-bench/Results/insert-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02148|e65dd14f2ed9abbf
BK|sql-bench/Results/insert-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02259|b5bf77586c18d2b5
+BK|sql-bench/Results/select-mysql-3.21-Linux_2.2.1_i686|19700101030959|02265|ed3687e713ff0571
BK|sql-bench/Results/select-mysql-Linux_2.2.10_i686|19700101030959|02268|a2e264d777b787d
BK|sql-bench/Results/select-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02227|308117295c3bc096
BK|sql-bench/Results/select-mysql-Linux_2.2.14_i686_xeon|19700101030959|02152|ead3f11b46ac626f
BK|sql-bench/Results/select-mysql-SunOS_5.5.1_sun4u|19700101030959|02273|c9a1a498a052e268
BK|sql-bench/Results/select-mysql-SunOS_5.6_sun4m|19700101030959|02274|4da215905bce988d
BK|sql-bench/Results/select-mysql-SunOS_5.7_sun4u|19700101030959|02276|632c92971c61e34a
+BK|sql-bench/Results/select-mysql_3.21-Linux_2.0.35_i686|19700101030959|02278|5fadbac5f98696a
BK|sql-bench/Results/select-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02323|e8c0871a668a610d
BK|sql-bench/Results/select-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02127|963a98ed526e2be4
BK|sql-bench/Results/select-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02254|f9ab7726ff14ea90
BK|sql-bench/Results/select-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02261|188d6b5b72d8e0a
+BK|sql-bench/Results/wisconsin-mysql-3.21-Linux_2.2.1_i686|19700101030959|02290|8147dc16a1dc6c47
BK|sql-bench/Results/wisconsin-mysql-Linux_2.2.10_i686|19700101030959|02288|301a82b12a84922b
BK|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02280|d01900af34fb33b8
BK|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_i686_xeon|19700101030959|02154|7525b23938631801
BK|sql-bench/Results/wisconsin-mysql-SunOS_5.5.1_sun4u|19700101030959|02297|379705afa2e12378
BK|sql-bench/Results/wisconsin-mysql-SunOS_5.6_sun4m|19700101030959|02298|ec61b14072715dc8
BK|sql-bench/Results/wisconsin-mysql-SunOS_5.7_sun4u|19700101030959|02300|f27927f8c64ea8ad
+BK|sql-bench/Results/wisconsin-mysql_3.21-Linux_2.0.35_i686|19700101030959|02302|31703d40ea6b4f66
BK|sql-bench/Results/wisconsin-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02324|ec075a89dbdbbe6a
BK|sql-bench/Results/wisconsin-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02325|233d5aa529979990
BK|sql-bench/Results/wisconsin-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02295|ec361eee4f4128cd
BK|sql-bench/Results/wisconsin-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02270|ef201ca14f635c57
+BK|sql/Attic/lex_hash.h|19700101030959|01912|14f912771118b50c
+BK|sql/Attic/mini_client.c|19700101030959|01910|9a3778c387d06a81
+BK|sql/Attic/mini_client_errors.c|19700101030959|01909|29edad51a5d0b068
+BK|sql/Attic/mybinlogdump.cc|19700101030959|01908|5dbdd2bde98d6169
+BK|sql/Attic/net_serv.c|19700101030959|01911|52dabcd773a39e10
+BK|sql/ha_hash.h|19700101030959|01902|27e36916116beb3e
+BK|sql/share/czech/errmsg.sys|19700101030959|01828|93104a2bd5c732a
+BK|sql/share/danish/errmsg.sys|19700101030959|01831|3a6d0fb8451a3313
+BK|sql/share/dutch/errmsg.sys|19700101030959|01833|b5aff4d08478bafd
+BK|sql/share/english/errmsg.sys|19700101030959|01834|f29bd4ea5aaf54c8
+BK|sql/share/estonia/errmsg.sys|19700101030959|01836|83b86d7ed4cdd5d0
+BK|sql/share/french/errmsg.sys|19700101030959|01838|9f024dc5e6fe50f5
+BK|sql/share/german/errmsg.sys|19700101030959|01840|1ea60675399c84c
+BK|sql/share/greek/errmsg.sys|19700101030959|01842|fedf585fa73e7cf1
+BK|sql/share/hungarian/errmsg.sys|19700101030959|01845|aff82c16a77fc800
+BK|sql/share/italian/errmsg.sys|19700101030959|01846|c5108ecb850b79a
+BK|sql/share/japanese/errmsg.sys|19700101030959|01848|302478c84697dc00
+BK|sql/share/korean/errmsg.sys|19700101030959|01850|a30e3687ae75a7c9
+BK|sql/share/norwegian-ny/.cvsignore|19700101030959|01855|469064b5190d703d
+BK|sql/share/norwegian/.cvsignore|19700101030959|01853|a91d63182f0b2366
+BK|sql/share/polish/errmsg.sys|19700101030959|01857|126b03af92054f0f
+BK|sql/share/portuguese/errmsg.sys|19700101030959|01859|c0187322f8c9d805
+BK|sql/share/romania/errmsg.sys|19700101030959|01871|e08aa93bae96d25e
BK|sql/share/romanian/errmsg.sys|19700101030959|01869|9d8282efb437e8cc
BK|sql/share/romanian/errmsg.txt|19700101030959|01870|2c64fb13a8f104ad
+BK|sql/share/russian/errmsg.sys|19700101030959|01860|72688df0beeabcb3
+BK|sql/share/slovak/errmsg.sys|19700101030959|01862|148510616ae825cf
+BK|sql/share/spanish/errmsg.sys|19700101030959|01865|10c8f32da39070b2
+BK|sql/share/swedish/errmsg.sys|19700101030959|01866|dd772e93db859993
+BK|sql/violite.c|19700101030959|01738|d7b85be615595ace
+BK|strings/Attic/bootstrap-ctype.c|19700101030959|01360|6d2a8cda2d6a35ff
+BK|strings/Attic/ct_init.c|19700101030959|01338|f0948bdd35ceedc3
+BK|strings/Attic/ctype-cp1251.c|19700101030959|01339|cdf74b9168408b3
+BK|strings/Attic/ctype-cp1257.c|19700101030959|01340|732611cbc74aeafc
+BK|strings/Attic/ctype-croat.c|19700101030959|01341|d2d805ee6f10cbcc
+BK|strings/Attic/ctype-danish.c|19700101030959|01342|dc5451066eb272ae
+BK|strings/Attic/ctype-dec8.c|19700101030959|01343|68f257dd2202d0c7
+BK|strings/Attic/ctype-dos.c|19700101030959|01344|f77bd08acf13a8c1
+BK|strings/Attic/ctype-estonia.c|19700101030959|01345|fc8a69424f7cb66b
+BK|strings/Attic/ctype-german1.c|19700101030959|01346|f7830c509bb358f7
+BK|strings/Attic/ctype-greek.c|19700101030959|01347|90acdff1195209ca
+BK|strings/Attic/ctype-hebrew.c|19700101030959|01348|d3b4a000d51e76dc
+BK|strings/Attic/ctype-hp8.c|19700101030959|01349|749e1be0f028d349
+BK|strings/Attic/ctype-hungarian.c|19700101030959|01350|5cf0bf7fa0312637
+BK|strings/Attic/ctype-koi8_ru.c|19700101030959|01351|8ff4188c642c9bd
+BK|strings/Attic/ctype-koi8_ukr.c|19700101030959|01352|a04aa14a6d62335a
+BK|strings/Attic/ctype-latin1.c|19700101030959|01353|cc63880f19c2303e
+BK|strings/Attic/ctype-latin2.c|19700101030959|01354|31895c4b83654342
+BK|strings/Attic/ctype-swe7.c|19700101030959|01355|bb1b012225d7d02c
+BK|strings/Attic/ctype-usa7.c|19700101030959|01356|d19d859dca5675f
+BK|strings/Attic/ctype-win1250.c|19700101030959|01357|1ce7a24255780a1
+BK|strings/Attic/ctype-win1251.c|19700101030959|01358|762607f4fd7d52ad
+BK|strings/Attic/ctype-win1251ukr.c|19700101030959|01359|b5a7cca889bbef58
+BK|strings/Attic/ctype.c.in|19700101030959|01361|8bf48d4bcbc5f675
+BK|strings/Attic/memory.h|19700101030959|01336|450f586e82a26d99
+BK|strings/Attic/ptr_cmp.c|19700101030959|01337|57e682a26e769597
+BK|strings/READ-ME|19700101030959|01362|ed6c5184d4bf6b7c
+BK|support-files/Attic/my-example.cnf.sh|19700101030959|02584|87a7e1f4d24b62a9
+BK|support-files/Attic/my-huge.cfg.sh|19700101030959|02585|589bdcd2d2c4360b
+BK|support-files/Attic/my-large.cfg.sh|19700101030959|02586|842c8e76253c9396
+BK|support-files/Attic/my-medium.cfg.sh|19700101030959|02587|c49880d26ef0648e
+BK|support-files/Attic/my-small.cfg.sh|19700101030959|02588|85023c559a1d96c
+BK|tests/fork3_test.pl|19700101030959|01947|c4a7bffb4f8e813c
+BK|tests/fork_test.pl|19700101030959|01945|3d3535329ed8cd5e
+BK|vio/Vio.cc|19700101030959|00003|60737ce02ab2bc25
+BK|vio/Vio.h|19700101030959|00004|f4416b2949647602
+BK|vio/VioAcceptorFd.cc|19700101030959|00005|a5a08947a31f88de
+BK|vio/VioAcceptorFd.h|19700101030959|00006|7f9c4358477ba9a3
+BK|vio/VioConnectorFd.cc|19700101030959|00007|ddbd7821c43c83a2
+BK|vio/VioConnectorFd.h|19700101030959|00008|58bc11cdc885b951
+BK|vio/VioFd.cc|19700101030959|00009|6e444647affef63b
+BK|vio/VioFd.h|19700101030959|00010|8294293a88c7b4b8
+BK|vio/VioPipe.cc|19700101030959|00011|12cf83b9a2f48f6c
+BK|vio/VioPipe.h|19700101030959|00012|21cebbe61a1da546
+BK|vio/VioSSL.cc|19700101030959|00013|6e85340b11fa42a8
+BK|vio/VioSSL.h|19700101030959|00014|70d367b7ec8cac3e
+BK|vio/VioSSLAcceptorFd.cc|19700101030959|00015|4c828f3688ed74ec
+BK|vio/VioSSLFactoriesFd.cc|19700101030959|00016|89f6bf5073937947
+BK|vio/VioSSLFactoriesFd.h|19700101030959|00017|1d63ae149a63f85
+BK|vio/VioSocket.cc|19700101030959|00018|71c615783f29b5e1
+BK|vio/VioSocket.h|19700101030959|00019|a26d535bd5a1a6
+BK|vio/version.cc|19700101030959|00020|7237acf12bed4a97
+BK|vio/vio-global.h|19700101030959|00021|c261412c01b2f4
+BK|vio/vioelitexx.cc|19700101030959|00022|3eaba70da792a7fc
+BK|vio/violite.h|19700101030959|00023|58d2942a52ea7a83
+BK|vio/viotypes.h|19700101030959|00027|f5a38e7326bd50f3
+BitKeeper/deleted/SCCS/s..del-makefile.w32
+Sinisa@sinisa.nasamreza.org|=6|20010818122920|53462|33f33b0a159dc5d5
+Sinisa@sinisa.nasamreza.org|mysql-test/r/sel000004.result|20020522121240|20995|360af2095c88cb8c
+Sinisa@sinisa.nasamreza.org|mysql-test/r/sel000004.result|20020522133259|25000|4b5fbc60d0d9754f
+Sinisa@sinisa.nasamreza.org|mysql-test/t/sel000004.test|20020522133300|08911|21904fbd1c95cb1
+Sinisa@sinisa.nasamreza.org|mysql-test/t/sel000004.test|20020522133624|23665|445526a8a20de101
+Sinisa@sinisa.nasamreza.org|scripts/mysql_new_fix_privilege_tables.sh|20011226144909|43765|b1664b401375eece
+arjen@co3064164-a.bitbike.com|BitKeeper/etc/logging_ok|20011212060636|33009
+arjen@co3064164-a.bitbike.com|Docs/section.Comparisons.texi|20011108043647|22614|692b647b
+arjen@fred.bitbike.com|scripts/mysql_fix_extensions.sh|20020516001337|12363|f1048a78f4759b4d
+ccarkner@nslinuxw10.bedford.progress.com|mysql-test/r/isolation.result|20010327145543|25059|4da11e109a3d93a9
+ccarkner@nslinuxw10.bedford.progress.com|mysql-test/t/isolation.test|20010327145543|39049|6a39e4138dd4a456
+jani@hynda.mysql.fi|client/mysqlcheck|20010419221207|26716|363e3278166d84ec
jcole@tetra.bedford.progress.com|BitKeeper/etc/logging_ok|20001004201211|30554
+miguel@hegel.local|zlib/ChangeLog|20020319032513|28917|5d5425fc84737083
+miguel@hegel.local|zlib/Make_vms.com|20020319032513|57151|35050a50ec612bbf
+miguel@hegel.local|zlib/Makefile.riscos|20020319032513|63798|8ab53f195fe429af
+miguel@hegel.local|zlib/adler32.c|20020319032513|04487|f98728c6da1ac164
+miguel@hegel.local|zlib/algorithm.txt|20020319032513|12903|fbc4dda3d31c2005
+miguel@hegel.local|zlib/amiga/Makefile.pup|20020319032513|19225|6a9ee8128d11541f
+miguel@hegel.local|zlib/amiga/Makefile.sas|20020319032513|25562|d7128ac7e0946f0b
+miguel@hegel.local|zlib/compress.c|20020319032513|32512|70bccb304651dba9
+miguel@hegel.local|zlib/contrib/README.contrib|20020319032514|04353|24cb75bee0a061fb
+miguel@hegel.local|zlib/contrib/asm386/gvmat32.asm|20020319032514|12654|31093c1a846dfdc7
+miguel@hegel.local|zlib/contrib/asm386/gvmat32c.c|20020319032514|19182|2a8eba5481c46eab
+miguel@hegel.local|zlib/contrib/asm386/mkgvmt32.bat|20020319032514|25425|422cbe16a6e74695
+miguel@hegel.local|zlib/contrib/asm386/zlibvc.def|20020319032514|31637|605ee23b8a4a6a1a
+miguel@hegel.local|zlib/contrib/asm386/zlibvc.dsp|20020319032514|38372|a1c6749052ce48a
+miguel@hegel.local|zlib/contrib/asm386/zlibvc.dsw|20020319032514|44870|3209982720f131ab
+miguel@hegel.local|zlib/contrib/asm586/match.s|20020319032514|51538|dc1a34b5eb2a7c11
+miguel@hegel.local|zlib/contrib/asm586/readme.586|20020319032514|57815|f60bfeefb27217d
+miguel@hegel.local|zlib/contrib/asm686/match.s|20020319032514|64199|4164951e8e19f116
+miguel@hegel.local|zlib/contrib/asm686/readme.686|20020319032514|04933|15e2bf4653b71f3e
+miguel@hegel.local|zlib/contrib/delphi/zlib.mak|20020319032514|11153|7b97eb8cf290a42
+miguel@hegel.local|zlib/contrib/delphi/zlibdef.pas|20020319032514|18918|658cb04db561e3db
+miguel@hegel.local|zlib/contrib/delphi2/d_zlib.bpr|20020319032514|25335|c267d77cc2e2a2c8
+miguel@hegel.local|zlib/contrib/delphi2/d_zlib.cpp|20020319032514|31641|d6f37620ac7b27fa
+miguel@hegel.local|zlib/contrib/delphi2/readme.txt|20020319032515|03494|65d16837f8579e23
+miguel@hegel.local|zlib/contrib/delphi2/zlib.bpg|20020319032515|09768|93c030edcca1838
+miguel@hegel.local|zlib/contrib/delphi2/zlib.bpr|20020319032515|16113|7a2fa98af2345144
+miguel@hegel.local|zlib/contrib/delphi2/zlib.cpp|20020319032515|22372|4257437d415259e2
+miguel@hegel.local|zlib/contrib/delphi2/zlib.pas|20020319032515|28965|3c94d3f5262cbbdd
+miguel@hegel.local|zlib/contrib/delphi2/zlib32.bpr|20020319032515|35585|41ac53acb8008ff7
+miguel@hegel.local|zlib/contrib/delphi2/zlib32.cpp|20020319032515|41979|3b0f51435e880afe
+miguel@hegel.local|zlib/contrib/iostream/test.cpp|20020319032515|48225|a2ea8d4d7c66cf71
+miguel@hegel.local|zlib/contrib/iostream/zfstream.cpp|20020319032515|55262|dce18d1a5d7096b7
+miguel@hegel.local|zlib/contrib/iostream/zfstream.h|20020319032515|61553|2b4d88acc2d3b714
+miguel@hegel.local|zlib/contrib/iostream2/zstream.h|20020319032515|02537|351f26518ea48196
+miguel@hegel.local|zlib/contrib/iostream2/zstream_test.cpp|20020319032515|08848|63f635d540de8c48
+miguel@hegel.local|zlib/contrib/minizip/ChangeLogUnzip|20020319032515|15183|50464416f4a3768f
+miguel@hegel.local|zlib/contrib/minizip/miniunz.c|20020319032515|21943|6a80009b319b1b9e
+miguel@hegel.local|zlib/contrib/minizip/minizip.c|20020319032515|28588|97181367a7bc47d8
+miguel@hegel.local|zlib/contrib/minizip/readme.txt|20020319032516|00611|7547b986c067c008
+miguel@hegel.local|zlib/contrib/minizip/unzip.c|20020319032516|07891|c66c95e17321206d
+miguel@hegel.local|zlib/contrib/minizip/unzip.def|20020319032516|14456|b4162b8c833ab6c7
+miguel@hegel.local|zlib/contrib/minizip/unzip.h|20020319032516|21001|bac981086af91a30
+miguel@hegel.local|zlib/contrib/minizip/zip.c|20020319032516|27911|e82bf7774e1ece95
+miguel@hegel.local|zlib/contrib/minizip/zip.def|20020319032516|34413|e9bda2081d65c22e
+miguel@hegel.local|zlib/contrib/minizip/zip.h|20020319032516|40925|17fd39ccb4ea294c
+miguel@hegel.local|zlib/contrib/minizip/zlibvc.def|20020319032516|47259|6dc42f99d2d55cad
+miguel@hegel.local|zlib/contrib/minizip/zlibvc.dsp|20020319032516|54044|ec35fd54c9b49987
+miguel@hegel.local|zlib/contrib/minizip/zlibvc.dsw|20020319032516|60515|17f28194a5cd80ea
+miguel@hegel.local|zlib/contrib/untgz/makefile.w32|20020319032516|01267|2c584f05a16db4ba
+miguel@hegel.local|zlib/contrib/untgz/untgz.c|20020319032516|07726|b74e9dde74642756
+miguel@hegel.local|zlib/contrib/visual-basic.txt|20020319032516|14096|cd461e762199bb09
+miguel@hegel.local|zlib/crc32.c|20020319032516|20397|b327da5b8cf9eae8
+miguel@hegel.local|zlib/deflate.c|20020319032516|26978|e22894a54233bc25
+miguel@hegel.local|zlib/deflate.h|20020319032516|33700|3a012bc1f5dfbc74
+miguel@hegel.local|zlib/descrip.mms|20020319032517|08063|7d61d33062ef53ec
+miguel@hegel.local|zlib/example.c|20020319032517|14327|490f57a4a9440dfa
+miguel@hegel.local|zlib/faq|20020319032517|20799|b0d0840d3b9faf07
+miguel@hegel.local|zlib/gzio.c|20020319032517|27098|e02d23e656c19359
+miguel@hegel.local|zlib/index|20020319032517|33542|5443c9f841db4a47
+miguel@hegel.local|zlib/infblock.c|20020319032517|39853|540cc1b743be5f58
+miguel@hegel.local|zlib/infblock.h|20020319032517|46202|4526bc327b4160ab
+miguel@hegel.local|zlib/infcodes.c|20020319032517|52620|dffb42fdf2fb2372
+miguel@hegel.local|zlib/infcodes.h|20020319032517|58960|3a02220a89c9a4fa
+miguel@hegel.local|zlib/inffast.c|20020319032517|65269|bf247ff4aa2bf54b
+miguel@hegel.local|zlib/inffast.h|20020319032517|06651|215e4a4ccfc886fc
+miguel@hegel.local|zlib/inffixed.h|20020319032517|12923|e86ef8e2efe23f77
+miguel@hegel.local|zlib/inflate.c|20020319032517|19311|fb22a3a1ab6fb1a0
+miguel@hegel.local|zlib/inftrees.c|20020319032517|25758|4fcb97357cdbc40
+miguel@hegel.local|zlib/inftrees.h|20020319032517|32227|ffcbe51816466e5c
+miguel@hegel.local|zlib/infutil.c|20020319032518|05244|a9b414f0f4ea0868
+miguel@hegel.local|zlib/infutil.h|20020319032518|12977|13089e09be34788c
+miguel@hegel.local|zlib/maketree.c|20020319032518|19299|7f281aef3547fee
+miguel@hegel.local|zlib/minigzip.c|20020319032518|25601|37f8eacb80c7f8fc
+miguel@hegel.local|zlib/msdos/Makefile.b32|20020319032518|33760|86772037f3344353
+miguel@hegel.local|zlib/msdos/Makefile.bor|20020319032518|40099|7aa9edaac099cdb9
+miguel@hegel.local|zlib/msdos/Makefile.dj2|20020319032518|46371|ca26f5fe96e3e999
+miguel@hegel.local|zlib/msdos/Makefile.emx|20020319032518|52757|64efbf8cedc146b5
+miguel@hegel.local|zlib/msdos/Makefile.msc|20020319032518|59050|1bb69abdddf390f2
+miguel@hegel.local|zlib/msdos/Makefile.tc|20020319032518|65341|2a9dff916115ae77
+miguel@hegel.local|zlib/msdos/Makefile.w32|20020319032518|06083|8d84523c1dcdc0f7
+miguel@hegel.local|zlib/msdos/Makefile.wat|20020319032518|12471|82f8714d825e97e3
+miguel@hegel.local|zlib/msdos/zlib.def|20020319032518|18787|165cd7dcff6ac9f
+miguel@hegel.local|zlib/msdos/zlib.rc|20020319032518|25240|f8a286fa8371ee09
+miguel@hegel.local|zlib/nt/Makefile.emx|20020319032518|31715|7e9fcf6f5ad2e51a
+miguel@hegel.local|zlib/nt/Makefile.gcc|20020319032519|03630|351fa8bd15c704b9
+miguel@hegel.local|zlib/nt/Makefile.nt|20020319032519|09990|ee461a3dd393a061
+miguel@hegel.local|zlib/nt/zlib.dnt|20020319032519|16279|22a0ed3b86ff8c2
+miguel@hegel.local|zlib/os2/Makefile.os2|20020319032519|22554|7a05f2a27812703a
+miguel@hegel.local|zlib/os2/zlib.def|20020319032519|28842|1166a95d83c5f52c
+miguel@hegel.local|zlib/readme|20020319032519|35257|80a41fc822f5f4
+miguel@hegel.local|zlib/trees.c|20020319032519|43770|4fbd4d005e26d38
+miguel@hegel.local|zlib/trees.h|20020319032519|50674|87161133bc2155fd
+miguel@hegel.local|zlib/uncompr.c|20020319032519|57111|82eac43195d1222c
+miguel@hegel.local|zlib/zconf.h|20020319032519|63437|c6b6b636c7e88d90
+miguel@hegel.local|zlib/zlib.3|20020319032519|04298|ec5cb4f64476f6a
+miguel@hegel.local|zlib/zlib.dsp|20020319032519|12016|6eec436fab260061
+miguel@hegel.local|zlib/zlib.html|20020319032519|31060|7a635f4ac95fc56b
+miguel@hegel.local|zlib/zlib.h|20020319032519|20598|fbec7833981c782f
+miguel@hegel.local|zlib/zutil.c|20020319032520|05372|6f0d1763c5deb409
+miguel@hegel.local|zlib/zutil.h|20020319032520|12556|1e431b0173278fb2
+mikef@nslinux.bedford.progress.com|mysql-test/include/have_gemini.inc|20010321203410|40631|42f94f0dfd0f7b18
+mikef@nslinux.bedford.progress.com|mysql-test/r/have_gemini.require|20010321203410|47052|206702c48b2e206b
+monty@donna.mysql.com|innobase/ib_config.h.in|20010217121901|07616|9e57db8504e55b7
+monty@donna.mysql.com|innobase/ib_config.h|20010217121901|04019|7539e26ffc614439
monty@donna.mysql.com|myisam/mi_debug.c|20000829092809|23459|873a6e7d6ff8297c
+monty@donna.mysql.com|mysql-test/include/have_default_master.inc|20010104005638|23980|a54c86e65a6c4af
+monty@donna.mysql.com|mysql-test/r/have_default_master.require|20010104005638|27332|1465255ffdaf82f
monty@donna.mysql.com|sql-bench/Results-linux/ATIS-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|34755|45d7837423db243f
monty@donna.mysql.com|sql-bench/Results-linux/ATIS-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|37262|2274651e29d38b07
monty@donna.mysql.com|sql-bench/Results-linux/RUN-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|39831|a6ef8229d40b75d1
@@ -327,8 +582,98 @@ monty@donna.mysql.com|sql-bench/Results-linux/select-mysql_dbug-Linux_2.2.14_my_
monty@donna.mysql.com|sql-bench/Results-linux/select-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|07610|cffd7d282a90113a
monty@donna.mysql.com|sql-bench/Results-linux/wisconsin-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|10615|8dcd7271a9137341
monty@donna.mysql.com|sql-bench/Results-linux/wisconsin-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|13213|4398328883aa75da
+monty@donna.mysql.com|sql-bench/Results/ATIS-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|14134|cf0d806760eefef2
+monty@donna.mysql.com|sql-bench/Results/ATIS-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|14777|e625af7f600bf930
+monty@donna.mysql.com|sql-bench/Results/RUN-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|15344|d922a0fcc1009130
+monty@donna.mysql.com|sql-bench/Results/RUN-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|15933|840503a555e420ec
+monty@donna.mysql.com|sql-bench/Results/alter-table-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|16525|2f516d2c108a9e05
+monty@donna.mysql.com|sql-bench/Results/alter-table-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|17106|6e532c1936df1737
+monty@donna.mysql.com|sql-bench/Results/big-tables-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|17709|6d8209bf72b663ed
+monty@donna.mysql.com|sql-bench/Results/big-tables-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|18309|c87333d6fe04433e
+monty@donna.mysql.com|sql-bench/Results/connect-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|18910|7ed15d6fd1a5944c
+monty@donna.mysql.com|sql-bench/Results/connect-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|19522|ab58fffa30dce97e
+monty@donna.mysql.com|sql-bench/Results/create-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|20136|241c337935ae1524
+monty@donna.mysql.com|sql-bench/Results/create-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|20766|4e5a2ab4907748d4
+monty@donna.mysql.com|sql-bench/Results/insert-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|22042|27b7a557c3cb07a
+monty@donna.mysql.com|sql-bench/Results/insert-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|22723|a85a6f0477c13f83
+monty@donna.mysql.com|sql-bench/Results/select-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|23395|8ef771713f89e1
+monty@donna.mysql.com|sql-bench/Results/select-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|24071|4f7795c27eaab86b
+monty@donna.mysql.com|sql-bench/Results/wisconsin-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|24748|6a468dcd3e6f5405
+monty@donna.mysql.com|sql-bench/Results/wisconsin-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|25437|24a02e007a58bf73
+monty@donna.mysql.fi|sql/violite.c|20010523223654|08838|53d4251a69d3c
+monty@hundin.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|32241|dd306b2e583ebde4
+monty@hundin.mysql.fi|sql-bench/Results/ATIS-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|59551|d002b0bc548ff8b3
+monty@hundin.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|35759|11038a44f73070e7
+monty@hundin.mysql.fi|sql-bench/Results/RUN-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|63204|e938a858bd12aa8d
+monty@hundin.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|39143|662b96bc66bc91b6
+monty@hundin.mysql.fi|sql-bench/Results/alter-table-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|01419|14360865bbba479f
+monty@hundin.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|42711|788ad492867b1226
+monty@hundin.mysql.fi|sql-bench/Results/big-tables-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|05113|b6be70bb51013cad
+monty@hundin.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|46284|5316add301edb60
+monty@hundin.mysql.fi|sql-bench/Results/connect-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|08804|1b715c6fd72e913e
+monty@hundin.mysql.fi|sql-bench/Results/create-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|49804|26e09af61f88d8c9
+monty@hundin.mysql.fi|sql-bench/Results/create-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|12309|f3b1d326092bf44
+monty@hundin.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|53328|fd2699adb3190d07
+monty@hundin.mysql.fi|sql-bench/Results/insert-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|15984|a0143553cccb54e2
+monty@hundin.mysql.fi|sql-bench/Results/select-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|56860|b01175ad38fd12b6
+monty@hundin.mysql.fi|sql-bench/Results/select-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|19688|4ffc9cf4be665ea2
+monty@hundin.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|60398|8ba598d217450157
+monty@hundin.mysql.fi|sql-bench/Results/wisconsin-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|23386|1ed1dc6abd24e7e3
+monty@hundin.mysql.fi|support-files/make_mysql_pkg.sh|20010915122456|03682|c616a18bed4b9c2
+monty@narttu.mysql.com|sql-bench/Results/ATIS-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|04677|f761da5546f0d362
+monty@narttu.mysql.com|sql-bench/Results/ATIS-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|07879|2ac8fe298953d43
+monty@narttu.mysql.com|sql-bench/Results/RUN-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|09727|79ac0482599eace1
+monty@narttu.mysql.com|sql-bench/Results/RUN-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171904|13285|a88e954bc8de5460
+monty@narttu.mysql.com|sql-bench/Results/alter-table-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|11725|dfc480becae45236
+monty@narttu.mysql.com|sql-bench/Results/alter-table-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|13605|ee94f987797ca948
+monty@narttu.mysql.com|sql-bench/Results/big-tables-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|15583|a2a77f37b689cd63
+monty@narttu.mysql.com|sql-bench/Results/big-tables-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|17580|28b688e2cd4b6bb3
+monty@narttu.mysql.com|sql-bench/Results/connect-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|19531|7dd5ac726f86cf0b
+monty@narttu.mysql.com|sql-bench/Results/connect-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|21574|1cf5d5f0d70a3fa0
+monty@narttu.mysql.com|sql-bench/Results/create-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|23516|441a6aefd381e319
+monty@narttu.mysql.com|sql-bench/Results/create-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|25516|fc207468e871ff69
+monty@narttu.mysql.com|sql-bench/Results/insert-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|27509|d12a7edef05d7185
+monty@narttu.mysql.com|sql-bench/Results/insert-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|29606|975e26cac59161fa
+monty@narttu.mysql.com|sql-bench/Results/select-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|33684|ddcf36cdf3f72e8c
+monty@narttu.mysql.com|sql-bench/Results/select-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|35818|34a39fbcb58d8945
+monty@narttu.mysql.com|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|37931|2db07249379f36
+monty@narttu.mysql.com|sql-bench/Results/wisconsin-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|40155|8101a5823c17e58a
+monty@narttu.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.2.13_SMP_alpha|20001014001004|08145|21ddf9425cbdd58
+monty@narttu.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|06287|d275df58a04737c8
+monty@narttu.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.2.13_SMP_alpha|20001014001004|13092|583091e05a25fb6
+monty@narttu.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|21374|d4766c7f8e70d7a2
+monty@narttu.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.2.13_SMP_alpha|20001014001004|15829|6c20c9ef46f82241
+monty@narttu.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|25875|155a83b53c0e9d6
+monty@narttu.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.2.13_SMP_alpha|20001014001004|18602|e8cc899bb933532f
+monty@narttu.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|30548|f1127add9307098b
+monty@narttu.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.2.13_SMP_alpha|20001014001004|21372|84df7c6446e51e26
+monty@narttu.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|00237|45d2cdf9bea9cc37
+monty@narttu.mysql.fi|sql-bench/Results/create-mysql-Linux_2.2.13_SMP_alpha|20001014001004|23947|2c9af91e9771f618
+monty@narttu.mysql.fi|sql-bench/Results/create-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|04134|d46860c29c5d51ee
+monty@narttu.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.2.13_SMP_alpha|20001014001004|26814|688809eb8ea77b3d
+monty@narttu.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|07880|e1771e0a164bc310
+monty@narttu.mysql.fi|sql-bench/Results/select-mysql-Linux_2.2.13_SMP_alpha|20001014001004|29737|db59425a7f4aa93f
+monty@narttu.mysql.fi|sql-bench/Results/select-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|11605|ee2a063d66a183d
+monty@narttu.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.2.13_SMP_alpha|20001014001004|32465|fc410754151d622c
+monty@narttu.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|15116|b7552710d35202b6
+monty@work.mysql.com|fs/fsck.mysql|20010411110350|07619|87170d4358b50d60
+monty@work.mysql.com|libmysqld/README|20010411110351|24268|434e9cae5fa9a4c4
+monty@work.mysql.com|libmysqld/WHITEPAPER|20010411110351|28263|da1226799debcf3f
+mwagner@cash.mwagner.org|Docs/include.de.texi|20020223092123|06028|112aac21b3489888
+mwagner@evoq.home.mwagner.org|Docs/Books/algor.eps|20001231203219|20480|481984607c98d715
+mwagner@evoq.home.mwagner.org|Docs/Books/dbi.eps|20001231203219|30594|6ad58f9457e2a564
+mwagner@evoq.home.mwagner.org|Docs/Books/dubois.eps|20001231203219|33725|aa3d9c08bbcc149b
+mwagner@evoq.home.mwagner.org|Docs/Books/ecomm.eps|20001231203220|02445|58ae914b5d5ea49
+mwagner@evoq.home.mwagner.org|Docs/Books/in_21.eps|20001231203220|05743|83a7604251d68ebd
+mwagner@evoq.home.mwagner.org|Docs/Books/manual.eps|20001231203220|09365|2a7145f88960c7ec
+mwagner@evoq.home.mwagner.org|Docs/Books/msql.eps|20001231203220|12487|ffe7d62847663250
+mwagner@evoq.home.mwagner.org|Docs/Books/prof.eps|20001231203220|15779|dc69b039543a57d7
+mwagner@evoq.home.mwagner.org|Docs/Books/pthreads.eps|20001231203220|18899|d60ad51891ef4c49
+mwagner@evoq.home.mwagner.org|Docs/Books/realmen.eps|20001231203220|22075|1ceb4839e835dad4
+mwagner@evoq.home.mwagner.org|Docs/Books/sql-99.eps|20001231203220|25230|cec4ae16fee4c640
mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.res|20001014084759|41327|1295456b9394876
mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.res|20001014084759|41327|1295456b93948768
+mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.tst|20001013104933|54568|2e626fa07144d2c8
mwagner@evoq.home.mwagner.org|mysql-test/mybin/start-mysqld|20001016055648|54840|9c8f21a7ab97793a
mwagner@evoq.home.mwagner.org|mysql-test/mybin/stop-mysqld|20001016055653|20710|89a1194045f05d1c
mwagner@evoq.home.mwagner.org|mysql-test/mybin/translate-tests|20001018130217|00206|3869c1fdf0a5ea1a
@@ -368,9 +713,46 @@ mwagner@evoq.home.mwagner.org|mysql-test/var/lib/README|20001009213643|15351|3b6
mwagner@evoq.home.mwagner.org|mysql-test/var/log/README|20001009213643|16203|df5481fdbe6e5b6e
mwagner@evoq.home.mwagner.org|mysql-test/var/run/README|20001009213643|17062|acb305e4c2ed5990
mwagner@evoq.home.mwagner.org|mysql-test/var/tmp/README|20001009213643|17904|b32d866bfd50e72e
+mwagner@evoq.home.mwagner.org|mysql-test/xml/README|20001013051440|12362|877d76bcd19f7193
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000001.xml|20001013051507|22498|f0eb64c0346366db
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000002.xml|20001013074610|25702|8cd06da5293a7147
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000003.xml|20001013074610|26659|1a622b8d30d7ade8
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000004.xml|20001017133600|56955|515488ef221523d9
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000005.xml|20001017133618|09973|a6344e46ba572dc3
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000006.xml|20001017133623|51441|8ad8f44f49b21246
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000007.xml|20001017133625|48163|bfcb6d85276be7e8
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000008.xml|20001017133627|18273|1d6082f0905c51b6
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000009.xml|20001017133629|19814|8677613dc624cb0c
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000010.xml|20001017133713|64368|9b98c9cce8fac145
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000011.xml|20001017133713|00331|432156d127cbd22f
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000012.xml|20001017133713|01909|a410d08dc4cfee11
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000013.xml|20001017133713|03416|2717cbfbe5730174
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000014.xml|20001017133713|05036|bcf55df6a036bd8f
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000015.xml|20001017133749|30814|b72689a8f9b21372
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000016.xml|20001017133713|07087|32f1ef2e3d214be0
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000017.xml|20001017133713|08762|81423597605ff77f
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000018.xml|20001017133713|10435|82e2e7bde83f56d8
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000019.xml|20001017133713|12133|c0f0b05e481b90e7
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000020.xml|20001017133713|13843|8849bbf91a4fd5ec
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000021.xml|20001017133713|15460|2763b87c1549ba87
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000022.xml|20001017133713|17202|da2083ef423ae39a
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000023.xml|20001017133713|20719|11993b379b9838be
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000024.xml|20001017133713|22352|dd067aa28220fa4c
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000025.xml|20001017133713|24071|3e766aa1e43b303
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000026.xml|20001017133713|25860|15145e496417646f
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000027.xml|20001017133713|27519|95e7de3e9934b570
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000028.xml|20001017133713|29282|c72bfec6600949b
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000029.xml|20001017133713|31058|3aba1eb23ef86c9e
+mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000030.xml|20001017133600|63205|c2b25781eefaee9
+mwagner@evoq.home.mwagner.org|mysql-test/xml/xsl/README|20001013051514|26509|cd4bb681e5a0cd10
+mwagner@evoq.home.mwagner.org|mysql-test/xml/xsl/mysqltest.xsl|20001013051514|27425|1b8f6ec4f1b5f634
mwagner@work.mysql.com|mysql-test/r/3.23/sel000001.result|20001010091454|28284|383913ae4505ec86
mwagner@work.mysql.com|mysql-test/r/3.23/sel000002.result|20001010091454|29230|d1787e6fd5dbc1cc
+nick@nick.leippe.com|mysql-test/r/rpl_empty_master_crash.result|20020531235552|47718|615f521be2132141
+nick@nick.leippe.com|mysql-test/t/rpl_empty_master_crash.test|20020531235552|52328|99464e737639ccc6
sasha@mysql.sashanet.com|BitKeeper/etc/logging_ok|20000801000905|12967|5b7d847a2158554
+sasha@mysql.sashanet.com|build-tags|20011125054855|05181|7afb7e785b80f97
+sasha@mysql.sashanet.com|build-tags|20011201050944|25384|b6f6fff142121618
sasha@mysql.sashanet.com|libmysql_r/acconfig.h|20001128060846|51084|65f1202b3b5c345f
sasha@mysql.sashanet.com|mysql-test/README.gcov|20001012045950|28177|5a6da067a30780ce
sasha@mysql.sashanet.com|mysql-test/README.gcov|20001214012355|41825|2de7575ca81155e5
@@ -397,13 +779,883 @@ sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000013.status.result|2000120217115
sasha@mysql.sashanet.com|mysql-test/r/3.23/sel000003.result|20001011230020|64653|d7b657b1e3a286a7
sasha@mysql.sashanet.com|mysql-test/r/3.23/sel000100.res|20001205131218|23520|84ed46856cb3a69f
sasha@mysql.sashanet.com|mysql-test/r/3.23/shw000001.result|20001121234128|16652|8b20b03d8319b9a5
+sasha@mysql.sashanet.com|mysql-test/r/binlog-backup-restore.result|20010424233926|16010|605de78abda64d27
+sasha@mysql.sashanet.com|mysql-test/r/df_crash.result|20010406010433|59989|4a3dbee64843953d
+sasha@mysql.sashanet.com|mysql-test/r/identity.result|20010910233028|16331|e41453a364242503
+sasha@mysql.sashanet.com|mysql-test/r/mrg000002.result|20001212152450|11492|745be0854aaaaf5e
sasha@mysql.sashanet.com|mysql-test/r/slave-running.result|20001208141122|24303|f73e49462cf59e1f
sasha@mysql.sashanet.com|mysql-test/r/slave-stopped.result|20001208141122|28916|25c134b1a4f1993a
+sasha@mysql.sashanet.com|mysql-test/std_data/m.MRG|20001212152450|17736|3f5632c37af00f18
+sasha@mysql.sashanet.com|mysql-test/std_data/m.frm|20001212152450|13897|e351dfe0b6824c0c
sasha@mysql.sashanet.com|mysql-test/std_data/select-key.master|20001009234916|07315|e6b83af25df0ce5
sasha@mysql.sashanet.com|mysql-test/std_data/simple-select.master|20001009234916|08299|6f3eb98812926caf
+sasha@mysql.sashanet.com|mysql-test/t/3.23/alt000001.test|20001122072330|31588|633aed61c4bad94c
+sasha@mysql.sashanet.com|mysql-test/t/3.23/sel000004.test|20001103140433|32471|daf9ad4a1a31cd3c
+sasha@mysql.sashanet.com|mysql-test/t/3.23/sel000005.test|20001103140433|36002|982fde89a4d6d886
sasha@mysql.sashanet.com|mysql-test/t/3.23/select-key.test|20001009234859|21197|5d785cef5c02c070
+sasha@mysql.sashanet.com|mysql-test/t/3.23/shw000001.test|20001121234128|21322|770d96a2c1c65b20
sasha@mysql.sashanet.com|mysql-test/t/3.23/simple-select.test|20001009234859|26291|71f98293e1dc65
+sasha@mysql.sashanet.com|mysql-test/t/binlog-backup-restore.test|20010424233926|25316|d5b0b9bd83738a9f
+sasha@mysql.sashanet.com|mysql-test/t/df_crash.test|20010406010433|65180|4c365178fe437f6
+sasha@mysql.sashanet.com|mysql-test/t/fulltext_join.test|20010730234357|20865|e347c8f04405c916
+sasha@mysql.sashanet.com|mysql-test/t/identity.test|20010910233028|36116|326f469b59105404
sasha@mysql.sashanet.com|mysql-test/t/include/master-slave.inc|20001118030458|01636|556fd038c3a3d54
+sasha@mysql.sashanet.com|mysql-test/t/mrg000002.test|20001212152450|20137|16b3a176adc0f311
+sasha@mysql.sashanet.com|mysql-test/t/rpl000018-master.sh|20010127223331|13256|bc8072e13b26b005
+sasha@mysql.sashanet.com|sounds/compilation_finished.au.gz|20010814034002|63992|70bd14095a918139
+sasha@mysql.sashanet.com|vio/test-ssl|20010828000105|24508|ed0a50364f2a51d7
sasha@work.mysql.com|BitKeeper/etc/logging_ok|20001214015456|29919|32b6551b8288c2fa
serg@serg.mysql.com|mysql-test/r/3.23/mrg000001.dummy.result|20001206231604|05053|bf7e6d609f22b897
serg@serg.mysql.com|mysql-test/r/3.23/mrg000001.result|20001206231609|46662|db2ef2e717ab8332
+serg@serg.mysql.com|mysql-test/r/ft0000001.a.result|20001211130756|05199|3d17aff15fa5a9f1
+serg@serg.mysql.com|mysql-test/r/ft0000001.b.result|20001211130756|10153|505c4c00a0bddfc4
+serg@serg.mysql.com|mysql-test/r/ft0000001.c.result|20001211130756|14950|1040289a75243a92
+serg@serg.mysql.com|mysql-test/r/ft0000001.d.result|20001211130756|19773|7c549555fbc7663e
+serg@serg.mysql.com|mysql-test/r/ft0000001.e.result|20001212121413|40468|c58d30fd7fe86f4f
+serg@serg.mysql.com|mysql-test/r/ft0000002.a.result|20001212120058|27306|a89b4db1db19f944
+serg@serg.mysql.com|mysql-test/r/ft0000002.b.result|20001212120058|34425|5de41ce15ae1cedb
+serg@serg.mysql.com|mysql-test/r/ft0000002.c.result|20001212120059|07173|cd66b90918a87531
+serg@serg.mysql.com|mysql-test/t/3.23/mrg000001.test|20001206231615|27540|e0327f9d1e6cb4e
+serg@serg.mysql.com|mysql-test/t/sel000006.test|20001211130730|19922|291cc6c8d85e51df
+serg@serg.mysql.com|mysql-test/t/sel000007.test|20001211130730|24336|f431e4f4739a24c3
+serg@serg.mysql.com|mysql-test/t/sel000008.test|20001211130730|28581|b338ef585cadf7ae
+serg@serg.mysql.com|mysql-test/t/sel000009.test|20001211130730|33139|a455c38f5c942cd1
+serg@serg.mysql.com|mysql-test/t/sel000010.test|20001211130731|03554|ca07085ae92255f1
+serg@serg.mysql.com|mysql-test/t/sel000011.test|20001211130731|08373|c2a971726c9d18d6
+serg@serg.mysql.com|mysql-test/t/sel000012.test|20001211130731|13215|ae64bff363c42e92
+serg@serg.mysql.com|mysql-test/t/sel000013.test|20001211130731|18090|ce8aa504ba4f74ba
+serg@serg.mysql.com|mysql-test/t/sel000014.test|20001211130731|22977|74cb8c70f1d73fcc
+serg@serg.mysql.com|mysql-test/t/sel000015.test|20001211130731|27841|7442bf9cbc96fe07
+serg@serg.mysql.com|mysql-test/t/sel000016.test|20001211130731|32739|f495235f14c47ec
+serg@serg.mysql.com|mysql-test/t/sel000017.test|20001211130731|37659|7c39f2b45a6aa780
+serg@serg.mysql.com|mysql-test/t/sel000018.test|20001211130731|42584|16207f3ad74de75e
+serg@serg.mysql.com|mysql-test/t/sel000019.test|20001211130731|47552|8fd63c8dc6be8dbc
+serg@serg.mysql.com|mysql-test/t/sel000020.test|20001211130731|52532|c5758ad18a6dff1e
+serg@serg.mysql.com|mysql-test/t/sel000021.test|20001211130731|57561|94dd47de2872264a
+serg@serg.mysql.com|mysql-test/t/sel000022.test|20001211130731|62553|6e3e5435e66875e9
+serg@serg.mysql.com|mysql-test/t/sel000023.test|20001211130731|02042|7bdfcfaa278f837d
+serg@serg.mysql.com|mysql-test/t/sel000024.test|20001211130731|07099|849f47e6cbdc4fe3
+serg@serg.mysql.com|mysql-test/t/sel000025.test|20001211130731|12136|65b32b4b67e4c77
+serg@serg.mysql.com|mysql-test/t/sel000026.test|20001211130731|17211|d8aa2d614f23b1
+serg@serg.mysql.com|mysql-test/t/sel000027.test|20001211130731|23677|ab44bb57a580de9
+serg@serg.mysql.com|mysql-test/t/sel000028.test|20001211130731|28317|db9bfc0a808fb629
+serg@serg.mysql.com|mysql-test/t/sel000029.test|20001211130731|32917|6aae34dbb3ee86d9
+serg@serg.mysql.com|mysql-test/t/sel000030.test|20001211130732|03110|a29683eac3e7b706
+tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.eps|20020228162345|64529|31ade79a89683616
+tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.gif|20020228162348|36945|364ca7338682f71
+tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.txt|20020228162350|33044|e155c53c10374ff
+tim@cane.mysql.fi|mysql-test/r/delete.result|20001221095802|20463|e866a6678e29f186
+tim@cane.mysql.fi|mysql-test/t/delete.test|20001221095802|36821|389410e29f2cebe5
+tim@threads.polyesthetic.msg|bdb/btree/btree_auto.c|20010305004134|12592|a683156a176761f
+tim@threads.polyesthetic.msg|bdb/build_vxworks/db_int.h|20010305004134|18702|40ba51edce41403f
+tim@threads.polyesthetic.msg|bdb/build_win32/db_archive.dsp|20010305004134|25535|e3da826e91bb086
+tim@threads.polyesthetic.msg|bdb/build_win32/db_checkpoint.dsp|20010305004134|26943|8071af22db95b1db
+tim@threads.polyesthetic.msg|bdb/build_win32/db_deadlock.dsp|20010305004134|28374|befd45d29eaeb672
+tim@threads.polyesthetic.msg|bdb/build_win32/db_dll.dsp|20010305004134|29137|4e9dda53c84511b6
+tim@threads.polyesthetic.msg|bdb/build_win32/db_dump.dsp|20010305004134|29985|e07d2a82708b61
+tim@threads.polyesthetic.msg|bdb/build_win32/db_int.h|20010305004134|30736|9ee5645850a336a0
+tim@threads.polyesthetic.msg|bdb/build_win32/db_java.dsp|20010305004134|31520|e3941d5a9810b360
+tim@threads.polyesthetic.msg|bdb/build_win32/db_load.dsp|20010305004134|32237|e83a2af8e24a715d
+tim@threads.polyesthetic.msg|bdb/build_win32/db_printlog.dsp|20010305004134|32975|163f6e1073a5f396
+tim@threads.polyesthetic.msg|bdb/build_win32/db_recover.dsp|20010305004134|34274|835c32ab73359256
+tim@threads.polyesthetic.msg|bdb/build_win32/db_stat.dsp|20010305004135|00560|f77417f5d9984986
+tim@threads.polyesthetic.msg|bdb/build_win32/db_static.dsp|20010305004135|01425|78ea414467defc70
+tim@threads.polyesthetic.msg|bdb/build_win32/db_tcl.dsp|20010305004135|02285|5ad951d774e41520
+tim@threads.polyesthetic.msg|bdb/build_win32/db_upgrade.dsp|20010305004135|03711|90fd250190af4984
+tim@threads.polyesthetic.msg|bdb/build_win32/db_verify.dsp|20010305004135|04464|e9a4938542f86cea
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_access.dsp|20010305004135|07926|8dd6017efffae14e
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_btrec.dsp|20010305004135|08710|c87137287d8d67dc
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_env.dsp|20010305004135|09533|1732d5e41efda77
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_lock.dsp|20010305004135|10303|286d2566e786dde
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_mpool.dsp|20010305004135|11076|9eb937bc70c1573
+tim@threads.polyesthetic.msg|bdb/build_win32/ex_tpcb.dsp|20010305004135|11838|644b38dae8b38152
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_access.dsp|20010305004135|12614|31e87b6228470681
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_btrec.dsp|20010305004135|13384|61b563f4ac1f73eb
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_env.dsp|20010305004135|14159|b0bf2649a4c797ac
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_lock.dsp|20010305004135|14943|257abf03544f6270
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_mpool.dsp|20010305004135|15715|d17a5d09f09f5217
+tim@threads.polyesthetic.msg|bdb/build_win32/excxx_tpcb.dsp|20010305004135|16510|159c727e2c15105e
+tim@threads.polyesthetic.msg|bdb/build_win32/include.tcl|20010305004135|17284|f8bffb5e2510f229
+tim@threads.polyesthetic.msg|bdb/build_win32/libdb.rc|20010305004135|20964|906f4936ec6a8398
+tim@threads.polyesthetic.msg|bdb/db/crdel_auto.c|20010305004136|27298|ee4146a08fd175c1
+tim@threads.polyesthetic.msg|bdb/db/db_auto.c|20010305004136|32432|3186e950cc321ae7
+tim@threads.polyesthetic.msg|bdb/dist/build/chk.define|20010305004137|15254|aa9a626e58631003
+tim@threads.polyesthetic.msg|bdb/dist/build/chk.def|20010305004137|13920|bb65b471d09f7c58
+tim@threads.polyesthetic.msg|bdb/dist/build/chk.offt|20010305004137|16371|25759c9294db634e
+tim@threads.polyesthetic.msg|bdb/dist/build/chk.srcfiles|20010305004137|18056|ae884700cd110cbf
+tim@threads.polyesthetic.msg|bdb/dist/build/chk.tags|20010305004137|19101|7a5b14d33d4078cc
+tim@threads.polyesthetic.msg|bdb/dist/config.guess|20010305004136|14678|ead1d91caeaa748c
+tim@threads.polyesthetic.msg|bdb/dist/config.hin|20010305004136|15955|fdecb7a06fa137a7
+tim@threads.polyesthetic.msg|bdb/dist/config.sub|20010305004136|16944|17e9990a298261a
+tim@threads.polyesthetic.msg|bdb/dist/install-sh|20010305004136|21695|1858c24340b72628
+tim@threads.polyesthetic.msg|bdb/dist/template/db_server_proc|20010305004137|21042|2e8b49d42aefab55
+tim@threads.polyesthetic.msg|bdb/dist/template/gen_client_ret|20010305004137|22087|786a5e65119b3991
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_btree|20010305004137|23131|65d6b0b2f5b7a6d2
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_crdel|20010305004137|24191|58795c0c5232f80d
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_db|20010305004137|25141|52c5797539878fca
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_hash|20010305004137|26120|dcbdd106ae17b865
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_log|20010305004137|27185|3fe6d62c43bc553a
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_qam|20010305004137|28066|6eecf6833de0af98
+tim@threads.polyesthetic.msg|bdb/dist/template/rec_txn|20010305004137|29072|1ff22b797deb0e1b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/c_index.html|20010305004143|28133|1a854fa55012906
+tim@threads.polyesthetic.msg|bdb/docs/api_c/c_pindex.html|20010305004145|05766|697acebf58a8db4
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_close.html|20010305004144|26254|fda0b4dfa946f44e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_create.html|20010305004143|29368|a87157ea60c82ee2
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_cursor.html|20010305004144|27133|7431dd96ed3492c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_del.html|20010305004144|11427|e8bffcf9be371317
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_err.html|20010305004143|33003|3696088bd85eeda3
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_fd.html|20010305004144|28004|15a01776b340a959
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get.html|20010305004144|29265|7e0018b93ee31eba
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get_byteswapped.html|20010305004144|30478|bcab4145183a7be2
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get_type.html|20010305004144|31538|d66aa1642a4d20e2
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_join.html|20010305004144|32446|a58c2d81ecfea5b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_key_range.html|20010305004144|33389|1060761b1e359d85
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_lsn.html|20010305004143|34135|5edb9bce1118feae
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_open.html|20010305004144|34314|59dfa6e5198c382e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_put.html|20010305004144|35267|ea78709ffb6cd7e8
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_remove.html|20010305004144|36184|668fa1d67a4f6941
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_rename.html|20010305004144|37128|36796ad9e106c3f0
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_append_recno.html|20010305004144|38070|bdf0130e642f74fa
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_bt_compare.html|20010305004144|39551|e55a311bb0be93a8
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_bt_minkey.html|20010305004144|40498|e2d52ba2d0174432
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_bt_prefix.html|20010305004144|41420|d6e443a7e47c9b3a
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_cachesize.html|20010305004144|02131|47a3c8ca486eb013
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_dup_compare.html|20010305004144|03068|a833bfc727a794e7
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errcall.html|20010305004144|04030|faf92be4ee8bc634
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errfile.html|20010305004144|00766|f07d3c57bb3c8fbd
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errpfx.html|20010305004144|05859|756b9b73dd28b8d9
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_feedback.html|20010305004144|06786|90d495e78318a332
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_flags.html|20010305004144|07758|4cd3700ae4387d22
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_ffactor.html|20010305004144|08766|41352ddf74ccc338
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_hash.html|20010305004144|09702|73f14897664d9d08
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_nelem.html|20010305004144|10635|bd8371e033b15c8f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_lorder.html|20010305004144|11587|e24ae76325374653
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_malloc.html|20010305004144|01594|3581879fef5af695
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_pagesize.html|20010305004144|12535|9644fa0f538cde17
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_paniccall.html|20010305004144|02405|ac7f63325b4499ce
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_q_extentsize.html|20010305004144|13496|f2fe41a5d8c46658
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_delim.html|20010305004144|14446|e0a7face764111b9
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_len.html|20010305004144|15420|f30d68257bd60e1e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_pad.html|20010305004144|16373|8a1de721eb6fc53f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_source.html|20010305004144|17353|6d12ac12652acc31
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_realloc.html|20010305004144|03204|a9be244baf966892
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_stat.html|20010305004144|18351|578f6f99f8e247ff
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_sync.html|20010305004144|19394|7a067029b6e1496b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_upgrade.html|20010305004144|20363|5e6210d6f09a0c3e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/db_verify.html|20010305004144|21372|cf80f5ba845eac2e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_close.html|20010305004144|22419|a3ad4ea563bafc42
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_count.html|20010305004144|23385|c3cd00c48b4babf5
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_del.html|20010305004144|24335|2685f75d28e4ad99
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_dup.html|20010305004144|25301|3bdf8b0a687b43f3
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_get.html|20010305004144|26284|4bf7579a92c35195
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_put.html|20010305004144|27355|a2c4a52329376657
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbm.html|20010305004144|04019|ebf1d8e329b06bba
+tim@threads.polyesthetic.msg|bdb/docs/api_c/dbt.html|20010305004144|04896|ae7a81c9c5f574f6
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_close.html|20010305004144|28399|a8e722cbb66c9d7b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_create.html|20010305004144|05736|3e73dd35fe5dcc8
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_open.html|20010305004144|29421|e4c9706220a4cd9b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_remove.html|20010305004144|31547|a71d5e1ca41324a7
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_cachesize.html|20010305004144|32567|f4c341d3f2c09469
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_data_dir.html|20010305004144|33569|437cec65e441c60
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errcall.html|20010305004145|00341|ba09eec1ba15f15f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errfile.html|20010305004144|06564|3b6b0822f29fc3d4
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errpfx.html|20010305004145|01527|806c8c438d0ee36c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_feedback.html|20010305004145|02860|87a78f97ba545aba
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_flags.html|20010305004145|03778|b2a1f3c8498e6d95
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_bsize.html|20010305004145|04625|1eb03c137a42e80f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_dir.html|20010305004145|05444|26be310214a2ff8f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_max.html|20010305004145|06288|319c24b5245b0685
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_conflicts.html|20010305004145|07137|58d9f7179bc864a3
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_detect.html|20010305004145|07983|d9ed73495defdc19
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max.html|20010305004145|08849|a2dc11fa8b2f1c9
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_lockers.html|20010305004145|24923|f22d5d4640436efe
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_locks.html|20010305004145|09704|1baf2d63a6fb418d
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_objects.html|20010305004145|25791|1a428bbee06cb5cc
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_mp_mmapsize.html|20010305004145|26668|21f27997f00accfe
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_mutexlocks.html|20010305004145|27540|85bbd53b877cafe1
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_pageyield.html|20010305004145|28418|8aa4a6cb2f18cad7
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_paniccall.html|20010305004144|07360|97a1d58189199453
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_panicstate.html|20010305004145|29311|43228366ca64363c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_rec_init.html|20010305004145|30192|bf7da051ef6689ba
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_region_init.html|20010305004145|31081|2ca19f76ee1ae790
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_server.html|20010305004145|31969|c13b793b525d504b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_shm_key.html|20010305004145|32880|cf5aaa6a995cbf55
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tas_spins.html|20010305004145|33848|91c7091deca3d97f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tmp_dir.html|20010305004145|34771|b563e87af5431824
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tx_max.html|20010305004145|35672|71a739e46faf33a9
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tx_recover.html|20010305004145|36580|8dd351545b444a24
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tx_timestamp.html|20010305004145|37492|ddb77d7dfb531085
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_verbose.html|20010305004145|38421|344f5119536cae0
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_strerror.html|20010305004145|39331|7f090bf26bdd4dc
+tim@threads.polyesthetic.msg|bdb/docs/api_c/env_version.html|20010305004145|40251|9bf7f99fefacc2bf
+tim@threads.polyesthetic.msg|bdb/docs/api_c/hsearch.html|20010305004144|08165|a8b76d897a8216d8
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_detect.html|20010305004145|41159|8fe406dce10e0bb
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_get.html|20010305004145|42084|63399d204f1885fa
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_id.html|20010305004145|43025|c9ee776f928a38f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_put.html|20010305004145|44022|f5bc2f52e55f16e1
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_stat.html|20010305004145|44954|d9a98bb949070b
+tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_vec.html|20010305004145|45892|cc79e33b82b7a275
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_archive.html|20010305004145|46850|490428ce45f9f918
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_compare.html|20010305004145|47782|4f12fdf04d30ab94
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_file.html|20010305004145|48705|574444b46b801f9c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_flush.html|20010305004145|49632|bb8bc4fc43c9f63d
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_get.html|20010305004145|50583|24cdf17ba55cbecf
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_put.html|20010305004145|51546|11a1bec49bb90419
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_register.html|20010305004145|52499|5381c1fad82d6527
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_stat.html|20010305004145|53440|36b87b19ee2c5bba
+tim@threads.polyesthetic.msg|bdb/docs/api_c/log_unregister.html|20010305004145|54401|45b8f9d3f8eb3d80
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fclose.html|20010305004145|55335|b52c7d599d83c26
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fget.html|20010305004145|56294|460714b5c2e3e1c5
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fopen.html|20010305004145|57267|d032a963a0103472
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fput.html|20010305004145|58291|4a7aace7db01ee15
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fset.html|20010305004145|59241|ecb97931b222568d
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fsync.html|20010305004145|60192|a95ab802bb28646f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_register.html|20010305004145|61165|8b9dff9b5043da58
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_stat.html|20010305004145|62160|55a9521fe04b03bd
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_sync.html|20010305004145|63168|b387035a94c20c50
+tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_trickle.html|20010305004145|64180|8b1adf1404d7a5f
+tim@threads.polyesthetic.msg|bdb/docs/api_c/pindex.src|20010305004143|31726|d1ecd116c42e0e23
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_close.html|20010305004144|08984|8981d16589844161
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_dirfree.html|20010305004144|09784|d59f36547c7b5384
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_dirlist.html|20010305004144|10606|24e75ccc86809023
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_exists.html|20010305004144|12261|23f077e82ca8f827
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_free.html|20010305004144|13076|ed61d2dfea9e069e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_fsync.html|20010305004144|13884|f59339ff63d95e7d
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_ioinfo.html|20010305004144|14713|80365bb8c66ae84c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_malloc.html|20010305004144|15535|5579a0604e14e1e7
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_map.html|20010305004144|16369|d90bbc8462ef43a6
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_open.html|20010305004144|17474|8c812591efc8abe6
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_read.html|20010305004144|18372|c8f6ece1ed408bf8
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_realloc.html|20010305004144|19375|e8e78e57c005c7c4
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_rename.html|20010305004144|20199|3f8c7b6674cda105
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_seek.html|20010305004144|21048|fdf1b31d3f6c7473
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_sleep.html|20010305004144|21928|4b962c8b82989d8c
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_unlink.html|20010305004144|22800|c42b13fd26f2e90
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_unmap.html|20010305004144|23658|d85790692f3b536e
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_write.html|20010305004144|24518|63567be42d586fde
+tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_yield.html|20010305004144|25375|ca5e359bcbeca7fd
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_abort.html|20010305004145|65162|a53425dd70214619
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_begin.html|20010305004145|00608|557b34fd3e7363
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_checkpoint.html|20010305004145|01607|4a1704dbfcaad5dc
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_commit.html|20010305004145|02592|8950b5e11c8b0778
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_id.html|20010305004144|04952|1e71088a7e8f6678
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_prepare.html|20010305004145|03605|19f84203db4e6608
+tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_stat.html|20010305004145|04637|f57a656bfbac12bf
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/cxx_index.html|20010305004145|07331|a0bc165de8a0554c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/cxx_pindex.html|20010305004147|08181|9ff6b69b56f988dd
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_class.html|20010305004145|08391|3129ff8c53721fe8
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_close.html|20010305004145|28189|cc570e65ac7d22f
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_cursor.html|20010305004145|29241|4f0225f98f4a11c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_del.html|20010305004145|31220|43fa05f2dfa86dbc
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_err.html|20010305004145|10496|77022bd5af575696
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_fd.html|20010305004145|33050|99ec316575f80428
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get.html|20010305004145|34357|3b6e6005f3f17f2a
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get_byteswapped.html|20010305004146|00979|a44d5d57d050b466
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get_type.html|20010305004146|01846|398668783c4070db
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_join.html|20010305004146|02717|9c4819679501ad6e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_key_range.html|20010305004146|03630|d79b373af096cb7
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_open.html|20010305004146|04518|ab95c48ac26ad3f7
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_put.html|20010305004146|05435|2792034e8c83c56
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_remove.html|20010305004146|06326|8c537fc5e326293b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_rename.html|20010305004146|07200|9c0a820e864220b3
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_append_recno.html|20010305004146|08075|a158b1fdba756ce
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_compare.html|20010305004146|08946|d888d1ebe056bc6b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_minkey.html|20010305004146|09837|d6181e52342005c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_prefix.html|20010305004146|11627|ecd8f927371a5dbd
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_cachesize.html|20010305004146|12541|3befdbaf98d5a04e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_dup_compare.html|20010305004146|13472|91f36955a213e0f4
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errcall.html|20010305004146|10727|28a7a1fa2b3b73ee
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errfile.html|20010305004145|11465|f6eddb9ab7ef07d0
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errpfx.html|20010305004146|14381|1f26e7b0bb5a067f
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_feedback.html|20010305004146|15263|a08620d86f05ec8c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_flags.html|20010305004146|16174|1146625feeb3bb0b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_ffactor.html|20010305004146|17155|a67084c644c38114
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_hash.html|20010305004146|18078|afe952f65389d93b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_nelem.html|20010305004146|19017|1829bc583d9c7554
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_lorder.html|20010305004146|19980|a46750a29588268c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_malloc.html|20010305004145|12423|b0aa5802da5bef4d
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_pagesize.html|20010305004146|20914|b8d544ec3e102c6c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_paniccall.html|20010305004145|13411|6bc911c9d64e9237
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_q_extentsize.html|20010305004146|21826|b17e340a68ede3ac
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_delim.html|20010305004146|22753|81d9df93c3511df3
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_len.html|20010305004146|23672|e09bb30e40208dfb
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_pad.html|20010305004146|24627|f2e0c2c2c3806a97
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_source.html|20010305004146|25550|46998978715ccc1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_realloc.html|20010305004145|14370|64d967a58c328957
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_stat.html|20010305004146|26537|3473827de856d680
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_sync.html|20010305004146|27538|dadf1f745e44faa7
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_upgrade.html|20010305004146|28493|c6231eb2f9989284
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_verify.html|20010305004146|29479|14db455da528229d
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_class.html|20010305004145|15353|2a31b398c37d674b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_close.html|20010305004146|30462|2adba79b482ee157
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_count.html|20010305004146|31395|bc025b8894450525
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_del.html|20010305004146|32671|424fc0ebb3b4c5cf
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_dup.html|20010305004146|33708|75df863b4bc13aaa
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_get.html|20010305004146|34739|36e2dbe65e3442e3
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_put.html|20010305004146|35761|11e6aa2492dd1032
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbenv_class.html|20010305004145|16297|5ab8aaf8a531f76b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbt_class.html|20010305004145|17281|fb91648586c1aa77
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_close.html|20010305004146|36778|5cc705b97b86972c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_open.html|20010305004146|37756|66ac1ae7fa67ca4a
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_remove.html|20010305004146|38809|5efece7ecdfc4df7
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_cachesize.html|20010305004146|39807|b82ed49a47415fec
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_data_dir.html|20010305004146|40779|9176f081597e4f27
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errcall.html|20010305004146|41745|bae25b45b0196773
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errfile.html|20010305004145|18322|f9543c9e65ed6a1d
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_error_stream.html|20010305004145|19317|a4101c1d68559fa2
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errpfx.html|20010305004146|42728|d26da4bab9538234
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_feedback.html|20010305004146|43755|1d5bd8dfe2d8034e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_flags.html|20010305004146|44734|8136e8e1ae16dc02
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_bsize.html|20010305004146|45706|7fd917bea6b163bf
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_dir.html|20010305004146|46674|c08aac264e7faa97
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_max.html|20010305004146|47638|4f7ba5f02c66c0de
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_conflicts.html|20010305004146|48615|5bba88df4cc6dfba
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_detect.html|20010305004146|49591|13e53300b722cf1e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max.html|20010305004146|50580|52ac3c4ca2876de
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_lockers.html|20010305004146|52578|ebb61fd669c2eefb
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_locks.html|20010305004146|51576|bbde4ffbcc607f61
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_objects.html|20010305004146|53572|c47424e4d13d5327
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_mp_mmapsize.html|20010305004146|54573|c21e3f9c5a29b0ab
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_mutexlocks.html|20010305004146|55575|f73e7ffdd2d8d62f
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_pageyield.html|20010305004146|56583|db4e5bdf71e171c0
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_paniccall.html|20010305004145|20292|2080056f15faa516
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_panicstate.html|20010305004146|57577|ad2d38e398cafd31
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_rec_init.html|20010305004146|58586|77916e00d1361c7b
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_region_init.html|20010305004146|59589|2d70678382bbbf9a
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_server.html|20010305004146|60631|bb74806839e8eb58
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_shm_key.html|20010305004146|62685|65b2c2f848ddf31e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tas_spins.html|20010305004146|64671|a107049f4776b358
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tmp_dir.html|20010305004146|00169|6c815da1fad27537
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_max.html|20010305004146|01212|910d1c17dd000729
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_recover.html|20010305004146|02235|cdf13797131b2d97
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_timestamp.html|20010305004146|03286|6396a1145f8e41c1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_verbose.html|20010305004146|04365|e804a65368b5cdc1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_strerror.html|20010305004146|05414|7e1cbfbd096ca
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_version.html|20010305004146|06444|1cff25c44cbea934
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/except_class.html|20010305004145|21277|59839667e43592e
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/get_errno.html|20010305004145|22249|e1a57c1c5f1d2695
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_class.html|20010305004145|23233|ed88ab78cccbef8d
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_detect.html|20010305004146|07495|bb50519c431233ed
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_get.html|20010305004146|61648|527d63a8526f336c
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_id.html|20010305004146|08539|b3c7995efbe12c16
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_put.html|20010305004146|09587|9eb85a1c9e88621
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_stat.html|20010305004146|10635|2112ceb0894b34d8
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_vec.html|20010305004146|11739|c55deaa5173a3323
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_archive.html|20010305004146|12836|d47f39e6dad7ee50
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_compare.html|20010305004146|13902|3225b4c32016c9b1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_file.html|20010305004146|14965|9a724b41d84e0c31
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_flush.html|20010305004146|16027|3976f77e905f35eb
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_get.html|20010305004146|17104|aee6162219c71617
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_put.html|20010305004146|18207|66077da9630fa8c2
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_register.html|20010305004146|19292|55470e0d79382beb
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_stat.html|20010305004146|20379|dc2d4ffe7950fc09
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_unregister.html|20010305004146|21535|8fa1fe691751d6ad
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lsn_class.html|20010305004145|24210|34809f73e15540ad
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fclose.html|20010305004146|22608|cc4a5776ac69d660
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fget.html|20010305004146|23710|bfe74f8c299c2995
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fopen.html|20010305004146|24842|abfef0a4db99c8e1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fput.html|20010305004146|26004|7ee8cda6287dee81
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fset.html|20010305004146|27124|e52fa0488faa893
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fsync.html|20010305004146|28227|76d47da7c5dc8932
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_register.html|20010305004146|29358|cba6f572fe27c7a
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_stat.html|20010305004146|31867|d370717a78971be1
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_sync.html|20010305004146|33235|253961279934d3c8
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_trickle.html|20010305004146|34409|c9df8540b9ebc898
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/mempfile_class.html|20010305004145|25191|672b4aa787b4aeca
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/pindex.src|20010305004145|09392|d65361c4acfcef06
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_abort.html|20010305004147|01091|81177bcb2e5f4502
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_begin.html|20010305004147|02053|3a2d1488ec9d8655
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_checkpoint.html|20010305004147|02999|173930473e76d008
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_class.html|20010305004145|26179|5e57abe095aceca9
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_commit.html|20010305004147|03924|65afb8caf9c470ae
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_id.html|20010305004147|04873|162661f4c2dc09d6
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_prepare.html|20010305004147|05797|818b4163518bace5
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_stat.html|20010305004147|06751|e8e25f86f8541696
+tim@threads.polyesthetic.msg|bdb/docs/api_cxx/what.html|20010305004145|27185|a64f42c697273c44
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_class.html|20010305004147|09609|b957a4d2b77acb1e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_close.html|20010305004147|24101|21595167f4fdbe88
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_cursor.html|20010305004147|25020|2181d652bd1c1ff
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_del.html|20010305004147|25922|f4f15b362b114506
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_fd.html|20010305004147|26830|1f70020c37023baa
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get.html|20010305004147|27733|87b8316c55b24739
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get_byteswapped.html|20010305004147|28706|edbc66a9d5491a1
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get_type.html|20010305004147|29592|4cfb6f09cbe0b8ae
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_join.html|20010305004147|30506|a3a6dead9cae65f9
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_key_range.html|20010305004147|31461|8834de5873a6acb5
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_open.html|20010305004147|32409|bfc13736b96ac509
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_put.html|20010305004147|33389|c476abe5599f21cf
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_remove.html|20010305004147|34343|49d3b8c7e5a5b000
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_rename.html|20010305004147|35341|19b20feaa815bc27
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_append_recno.html|20010305004147|36282|d28bf857803b93a2
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_compare.html|20010305004147|37206|e972f964d042b35e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_minkey.html|20010305004147|38144|c7e1f184bdca25fa
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_prefix.html|20010305004147|39088|a3269aad23e6dbc
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_cachesize.html|20010305004147|40035|22d172a2d29f276b
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_dup_compare.html|20010305004147|40992|3dabd840a1d9e5f3
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_errcall.html|20010305004147|41930|4e4743f5b4277199
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_errpfx.html|20010305004147|42881|c446da51277796df
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_feedback.html|20010305004147|45141|69b4c07b3dbe383
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_flags.html|20010305004147|46212|b6b9d271bd42a94e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_ffactor.html|20010305004147|47226|edcc10024104d57e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_hash.html|20010305004147|48174|c6eb825c706a9548
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_nelem.html|20010305004147|49144|fc6f22a4c285fcef
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_lorder.html|20010305004147|50103|f64cbdd62bbbdd7c
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_pagesize.html|20010305004147|51079|d899ea90b20b7b31
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_q_extentsize.html|20010305004147|52035|6ac26239fc538cb
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_delim.html|20010305004147|53019|78fcf2d750fb26ef
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_len.html|20010305004147|53997|8448826ea78c630e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_pad.html|20010305004147|54985|2729c192747ac7af
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_source.html|20010305004147|55969|b29827dbf47537d1
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_stat.html|20010305004147|57008|bc253f0883e9c82b
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_sync.html|20010305004147|58064|42391f7d5f200b90
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_upgrade.html|20010305004147|59076|782fa4cc6c633990
+tim@threads.polyesthetic.msg|bdb/docs/api_java/db_verify.html|20010305004147|60082|20873ab17f6ed922
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_class.html|20010305004147|11473|8ee03c40ae0dbcb8
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_close.html|20010305004147|61116|e3bf1f36bc0e8e7e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_count.html|20010305004147|62108|9c239575f4550756
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_del.html|20010305004147|63111|6ec2b8a4b8dde996
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_dup.html|20010305004147|64103|aa141014c4d7f9b0
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_get.html|20010305004147|65144|e66e387b83681e73
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_put.html|20010305004147|00700|da0f0fa974385abd
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbenv_class.html|20010305004147|12326|92c7a4a6c22090c7
+tim@threads.polyesthetic.msg|bdb/docs/api_java/dbt_class.html|20010305004147|13192|f6b04ff142e332f8
+tim@threads.polyesthetic.msg|bdb/docs/api_java/deadlock_class.html|20010305004147|14282|b587b2d8c9e5d0b0
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_close.html|20010305004147|01809|c4e2ec77d7d14d4f
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_open.html|20010305004147|02873|2df0f0ef544da715
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_remove.html|20010305004147|04039|e92277e3dfd9bba1
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_cachesize.html|20010305004147|05132|f3700cd19856f14e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_data_dir.html|20010305004147|06162|b7b3f35e96804650
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_errcall.html|20010305004147|07189|4e206d08cbb39ab7
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_error_stream.html|20010305004147|15677|a738119910b452b8
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_errpfx.html|20010305004147|08227|a3b9a09670f6912
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_feedback.html|20010305004147|09255|9748745e65f070d5
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_flags.html|20010305004147|10283|690847bb5e205c21
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_bsize.html|20010305004147|11335|6c67beed877df84c
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_dir.html|20010305004147|12366|484cad2123994e14
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_max.html|20010305004147|13429|c9f705492162e175
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_conflicts.html|20010305004147|14497|8951eb975a90918b
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_detect.html|20010305004147|15549|9fc15a1a95b0dfa1
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max.html|20010305004147|16607|12b6e34ac5a53281
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_lockers.html|20010305004147|18755|7896265ea77829b3
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_locks.html|20010305004147|17677|f0114205b169de39
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_objects.html|20010305004147|19812|d1ed194631ffeb2a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_mp_mmapsize.html|20010305004147|20894|b7dea9108fa65dfa
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_mutexlocks.html|20010305004147|21961|aad8e4a059075bb6
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_pageyield.html|20010305004147|23054|774b3da0306a6767
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_panicstate.html|20010305004147|24142|72846d9a97cb80bb
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_rec_init.html|20010305004147|25237|1fdb2c5fc3b6407
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_region_init.html|20010305004147|26379|30534afa94cbf54e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_server.html|20010305004147|27545|d901cdab9698605d
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_shm_key.html|20010305004147|28699|8c576698882f0edc
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tas_spins.html|20010305004147|30425|2f9963827fbcb3f
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tmp_dir.html|20010305004147|32251|f23e4f614f6d975a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_max.html|20010305004147|33999|70f356b8b67782fe
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_recover.html|20010305004148|00983|40280da113fc9d2b
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_timestamp.html|20010305004148|02804|457eeb135f1f8bc0
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_verbose.html|20010305004148|03690|9dcda0399c8256e7
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_strerror.html|20010305004148|04588|fceebaa94cf9aafd
+tim@threads.polyesthetic.msg|bdb/docs/api_java/env_version.html|20010305004148|05599|854d26806930cab6
+tim@threads.polyesthetic.msg|bdb/docs/api_java/except_class.html|20010305004147|16978|195c00e4a7cbe648
+tim@threads.polyesthetic.msg|bdb/docs/api_java/get_errno.html|20010305004147|17836|89a89f8efe3a9360
+tim@threads.polyesthetic.msg|bdb/docs/api_java/java_index.html|20010305004147|18736|8ecfcef4a702011d
+tim@threads.polyesthetic.msg|bdb/docs/api_java/java_pindex.html|20010305004148|35859|f8bc0811d8eda8e9
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_class.html|20010305004147|19738|880aa614d1469304
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_detect.html|20010305004148|06490|14d4e7c7dca0dad7
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_get.html|20010305004148|07401|fd52de261831f9b5
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_id.html|20010305004148|08326|737cf8d8dc74084e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_put.html|20010305004148|09226|5af89e4cbf29c694
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_stat.html|20010305004148|10140|71b81d8567befc43
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_vec.html|20010305004148|11077|df5eb838fdbe1eab
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_archive.html|20010305004148|11996|b4a9483dbb5a2b58
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_compare.html|20010305004148|12947|756622b42572ecb
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_file.html|20010305004148|13857|74a49bae2532199a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_flush.html|20010305004148|14794|1691d6a3c8cc284e
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_get.html|20010305004148|15736|5fbbbd4baa60e052
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_put.html|20010305004148|16729|ad7e9f382abde491
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_register.html|20010305004148|17668|c68fc6fb22dd594a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_stat.html|20010305004148|18608|d186a08662046aba
+tim@threads.polyesthetic.msg|bdb/docs/api_java/log_unregister.html|20010305004148|19590|eee284e0da176d0a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/lsn_class.html|20010305004147|20619|b1458208b6c81016
+tim@threads.polyesthetic.msg|bdb/docs/api_java/mem_class.html|20010305004147|21486|2e5052b5b2bea584
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fclose.html|20010305004148|20518|d08f0c134361f802
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fget.html|20010305004148|21431|ca84dee01997eb89
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fopen.html|20010305004148|22355|f7cf58725aa1c406
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fput.html|20010305004148|23268|6ba75e517a259703
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fset.html|20010305004148|24178|5c5371a93b83275
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fsync.html|20010305004148|25118|e767b233fe7730a2
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_register.html|20010305004148|26052|8331390a1c66fefd
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_stat.html|20010305004148|27008|4628462474db62b4
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_sync.html|20010305004148|27969|5b401daadc7261eb
+tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_trickle.html|20010305004148|28912|4d5c4e83a4a5c638
+tim@threads.polyesthetic.msg|bdb/docs/api_java/pindex.src|20010305004147|10521|de828917f041d27b
+tim@threads.polyesthetic.msg|bdb/docs/api_java/runrec_class.html|20010305004147|22358|49c5cb3efe0c201
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_abort.html|20010305004148|29858|ec9a3517748bfa3
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_begin.html|20010305004148|30859|553bf78bd7fc3e0a
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_checkpoint.html|20010305004148|31832|2565ac892d04b63d
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_class.html|20010305004147|23221|c7bb2a3393ca9488
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_commit.html|20010305004148|32812|c265042f3340baa1
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_id.html|20010305004148|01920|798720b73cc9391
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_prepare.html|20010305004148|33784|510a245c80e715c
+tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_stat.html|20010305004148|34772|9a6ef8c262f218f9
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_close.html|20010305004148|38213|f40794b17e0fe443
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_count.html|20010305004148|40010|4812f3756a75437
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_cursor.html|20010305004148|40924|e035b3c11a91c5d6
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_del.html|20010305004148|41829|400c7a72fb10d6f4
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get.html|20010305004148|42753|127bd361ee695c71
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get_join.html|20010305004148|43762|1c737805c2c49cf9
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get_type.html|20010305004148|44686|7202f3ca793e6ec3
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_is_byteswapped.html|20010305004148|45596|8fb9e2c58051c769
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_join.html|20010305004148|46525|cb3eb61ed17a1f8
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_open.html|20010305004148|47486|f588cc9bc694cbf0
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_put.html|20010305004148|48549|380c7caeced55512
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_remove.html|20010305004148|50431|3b2be4b0b1b3dc98
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_rename.html|20010305004148|49486|909bc643d5455b54
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_stat.html|20010305004148|51363|3bb57be2de907fd2
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_sync.html|20010305004148|52310|3b615ca64d934602
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_close.html|20010305004148|53244|ef431e58d72accc3
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_del.html|20010305004148|54185|7e94f9f01e7e4453
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_dup.html|20010305004148|55139|325121689412d70b
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_get.html|20010305004148|56098|5bbb80cf51aff594
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_put.html|20010305004148|57122|290ecb1275d4270
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_close.html|20010305004148|58109|bf191b2673a2b19e
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_open.html|20010305004148|59088|39b63925d45a637e
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_remove.html|20010305004148|60117|9090900413ff0280
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/pindex.src|20010305004148|39123|f8754fff24f2cb24
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/tcl_index.html|20010305004148|61088|443e6b9a10ef4139
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/tcl_pindex.html|20010305004148|00553|259f0e062eee63c7
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn.html|20010305004148|62085|8e345950e6029230
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn_abort.html|20010305004148|63068|8cc23b6ef6f457d2
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn_commit.html|20010305004148|64051|25150b20b84cd519
+tim@threads.polyesthetic.msg|bdb/docs/api_tcl/version.html|20010305004148|65038|eeb51f4de1bbfe8e
+tim@threads.polyesthetic.msg|bdb/docs/images/api.gif|20010305004148|02578|dec2d4fe5f39dffe
+tim@threads.polyesthetic.msg|bdb/docs/images/next.gif|20010305004148|03600|ddab96466674135b
+tim@threads.polyesthetic.msg|bdb/docs/images/prev.gif|20010305004148|04639|9448d24755d708a0
+tim@threads.polyesthetic.msg|bdb/docs/images/ps.gif|20010305004148|05648|f6b1b372cb2cda4c
+tim@threads.polyesthetic.msg|bdb/docs/images/ref.gif|20010305004148|06650|add30c753dc1972d
+tim@threads.polyesthetic.msg|bdb/docs/images/sleepycat.gif|20010305004148|07668|ea63aaaa508ef096
+tim@threads.polyesthetic.msg|bdb/docs/index.html|20010305004143|26935|450dd5db21a9bb64
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/close.html|20010305004148|10227|ed6f7427edc0431
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/count.html|20010305004148|11236|8fd8daf2e2cbd7c7
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/curclose.html|20010305004148|12231|8b6b8442fc8382f7
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/curdel.html|20010305004148|13236|39bf0a8cba99c064
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/curdup.html|20010305004148|14243|5c855e1f5b99d990
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/curget.html|20010305004148|15271|d7dd42affcd54073
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/curput.html|20010305004148|16324|c7e4fa0a68170c3d
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/cursor.html|20010305004148|17350|6dbcdb3b7d552f58
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/delete.html|20010305004148|18364|9195664374690b24
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/error.html|20010305004148|19390|45ac854e68196844
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/get.html|20010305004148|20425|96c9c9a01c32d16
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/join.html|20010305004148|22331|acc16686a78a732
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/open.html|20010305004148|23468|c9a7e23579a5e93a
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/opensub.html|20010305004148|24500|81c79cce793fb343
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/ops.html|20010305004148|25566|9b24db9ba4f45724
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/partial.html|20010305004148|26629|db4a970c839b3051
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/put.html|20010305004148|28752|8e18b0af61eb7f0f
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/stability.html|20010305004148|30129|a92faac934d69cef
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/stat.html|20010305004148|32050|fafc0f88571d9395
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/sync.html|20010305004148|33751|381722c07c9d8825
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/upgrade.html|20010305004149|00532|c7499736f03c1a1c
+tim@threads.polyesthetic.msg|bdb/docs/ref/am/verify.html|20010305004149|01382|badaeba91bda50e1
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_compare.html|20010305004149|18156|c1e847e651704c89
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_minkey.html|20010305004149|19013|b4708e561be92b83
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_prefix.html|20010305004149|19903|4e7602aa68d50fe1
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_recnum.html|20010305004149|20770|f081f10254e86e75
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/byteorder.html|20010305004149|21617|999a22f727e2dae0
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/cachesize.html|20010305004149|22486|99dcd466dc881093
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/dup.html|20010305004149|23371|523731632fca7343
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/extentsize.html|20010305004149|24263|fdcfb5572974545c
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_ffactor.html|20010305004149|25120|5eb87b7ce99f3362
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_hash.html|20010305004149|25978|3a0174586fbcfcdf
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_nelem.html|20010305004149|26871|979995db477052ad
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/intro.html|20010305004149|27745|dd1647202258ee28
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/logrec.html|20010305004149|28646|5edeb34d63936e2
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/malloc.html|20010305004149|29537|cb0e6d7e9448d93e
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/pagesize.html|20010305004149|30437|eb4800704ae1131b
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/re_source.html|20010305004149|31346|b000d11ca4a0f9a
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/recno.html|20010305004149|32283|c2ae722138309e95
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/renumber.html|20010305004149|33199|b7df79bf32240b5c
+tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/select.html|20010305004149|34120|57b1c99f6a8ea93f
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/apis.html|20010305004149|36488|a84570e410b11a6a
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/bigpic.gif|20010305004149|41251|fe43e7415b3bbdb0
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/bigpic.html|20010305004149|37519|ab5254bc99af0d5c
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/progmodel.html|20010305004149|38491|caa422dc155b6370
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/script.html|20010305004149|39400|6796fd0a63161a0c
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/smallpic.gif|20010305004149|42169|fdf77055d7e711
+tim@threads.polyesthetic.msg|bdb/docs/ref/arch/utilities.html|20010305004149|40326|54d7014fab332c7a
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/aix.html|20010305004149|44137|e8ae448bdb85fa22
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/conf.html|20010305004149|45053|d0378c69618b790b
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/flags.html|20010305004149|46003|a739404f90eb8c3d
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/freebsd.html|20010305004149|46918|8ed2a42e1668004c
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/hpux.html|20010305004149|47818|d34942564699608
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/install.html|20010305004149|48752|660222dd1feffc4
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/intro.html|20010305004149|49652|f261022c26987d7f
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/irix.html|20010305004149|50564|95833aedc3a82f0
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/linux.html|20010305004149|51464|f9f2d09dc6df75e
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/notes.html|20010305004149|52391|97e9b52853db15ea
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/osf1.html|20010305004149|53358|9d4ebabfe3af8970
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/qnx.html|20010305004149|54263|6d2849a8e8038dc9
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/sco.html|20010305004149|55174|e25f6271a1b753d0
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/shlib.html|20010305004149|56099|7168ed40f2e1155d
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/solaris.html|20010305004149|57063|3a85fb541538d0d7
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/sunos.html|20010305004149|58008|fc41965e9d95985c
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/test.html|20010305004149|58940|b2c2f275a0c3e783
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/ultrix.html|20010305004149|59865|a1dd780edcde11f6
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/faq.html|20010305004149|61835|cdb7646d3d2e6374
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/intro.html|20010305004149|62808|2eed15d25078711
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/notes.html|20010305004149|63758|7e53a042c5c4d350
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/faq.html|20010305004149|65331|34704a907168cea7
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/intro.html|20010305004149|00770|2975a07b53b12046
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/notes.html|20010305004149|01764|4058bf968f287f7
+tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/test.html|20010305004149|02729|84090b57cb7f0cf8
+tim@threads.polyesthetic.msg|bdb/docs/ref/cam/intro.html|20010305004149|04558|4c497b1a18c4c7f5
+tim@threads.polyesthetic.msg|bdb/docs/ref/debug/common.html|20010305004149|07598|607061232e2532df
+tim@threads.polyesthetic.msg|bdb/docs/ref/debug/compile.html|20010305004149|08609|12785e3091b78bfd
+tim@threads.polyesthetic.msg|bdb/docs/ref/debug/intro.html|20010305004149|06616|57ef29f26341ea
+tim@threads.polyesthetic.msg|bdb/docs/ref/debug/printlog.html|20010305004149|09591|9fa9894f839fad95
+tim@threads.polyesthetic.msg|bdb/docs/ref/debug/runtime.html|20010305004149|10629|d50f2fea4a8e58c
+tim@threads.polyesthetic.msg|bdb/docs/ref/distrib/layout.html|20010305004149|12589|5aeb292fbd987cf8
+tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/format.html|20010305004149|13995|9fa10ca3c7ae6751
+tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/text.html|20010305004149|14998|88b57a73860b423
+tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/utility.html|20010305004149|15969|8fc100fdb58adb3c
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/create.html|20010305004149|17402|9f454cb1910df0b8
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/error.html|20010305004149|18447|acbbdb848c9fe70f
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/intro.html|20010305004149|19435|96dd1090729e06b
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/naming.html|20010305004149|20447|1f041789686cc8a0
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/open.html|20010305004149|21520|37a6e67d520d6c00
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/region.html|20010305004149|22506|cc94139c8daa7f6a
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/remote.html|20010305004149|23518|52a3a79fdff8f7bd
+tim@threads.polyesthetic.msg|bdb/docs/ref/env/security.html|20010305004149|24507|e455f95aee7f5cd2
+tim@threads.polyesthetic.msg|bdb/docs/ref/install/file.html|20010305004150|21159|d4ba2317db7c064b
+tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.s5.be.txt|20010305004150|22805|cf7d25e758432ab6
+tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.s5.le.txt|20010305004150|23615|528ef76418c8b45c
+tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.txt|20010305004150|21985|3894a46ea11ce25a
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/data.html|20010305004149|26092|33fbf7496c58cf63
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/dbis.html|20010305004149|28303|e672b7615d70be2c
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/dbisnot.html|20010305004149|29466|5ce7aed7ce41c9e6
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/distrib.html|20010305004149|30742|84b56709310017f2
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/need.html|20010305004149|31743|43950806e35d71f
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/products.html|20010305004149|32785|f37221772a3b589d
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/terrain.html|20010305004149|33850|b396d6447a59435f
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/what.html|20010305004150|00539|dd70b9e6e085725d
+tim@threads.polyesthetic.msg|bdb/docs/ref/intro/where.html|20010305004150|01442|6cb9ec27f19ecbbb
+tim@threads.polyesthetic.msg|bdb/docs/ref/java/compat.html|20010305004150|25581|b39d173789bbf70d
+tim@threads.polyesthetic.msg|bdb/docs/ref/java/conf.html|20010305004150|26401|ef560bcf13a71cd5
+tim@threads.polyesthetic.msg|bdb/docs/ref/java/faq.html|20010305004150|27218|7ca2474ba1f6676f
+tim@threads.polyesthetic.msg|bdb/docs/ref/java/program.html|20010305004150|28026|e9bbc08bccf5d396
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/am_conv.html|20010305004150|30986|3bab32d969f21b77
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/cam_conv.html|20010305004150|31862|63844ff6fa95f0c
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/config.html|20010305004150|32692|a593ea4c87467ddd
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/dead.html|20010305004150|33535|f5c7debd9ba739bb
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/intro.html|20010305004150|34434|e1e07e71f3198be
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/max.html|20010305004150|35299|f0fb32ebc251f636
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/nondb.html|20010305004150|36156|863fe076a46378d7
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/notxn.html|20010305004150|37003|beec805d9f05e2bc
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/page.html|20010305004150|37863|d56876b2565cbee
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/stdmode.html|20010305004150|38797|4048a052ea129ca3
+tim@threads.polyesthetic.msg|bdb/docs/ref/lock/twopl.html|20010305004150|39650|b3f3aee667bc381d
+tim@threads.polyesthetic.msg|bdb/docs/ref/log/config.html|20010305004150|41449|aedc53caf49c51c9
+tim@threads.polyesthetic.msg|bdb/docs/ref/log/intro.html|20010305004150|42339|31e7055d83ca8757
+tim@threads.polyesthetic.msg|bdb/docs/ref/log/limits.html|20010305004150|43198|26fac1e32387b7c9
+tim@threads.polyesthetic.msg|bdb/docs/ref/mp/config.html|20010305004150|46018|771c2c91fc0b6b17
+tim@threads.polyesthetic.msg|bdb/docs/ref/mp/intro.html|20010305004150|45138|34937731cafcf1b1
+tim@threads.polyesthetic.msg|bdb/docs/ref/perl/intro.html|20010305004150|47570|ce7e794e619e1e1d
+tim@threads.polyesthetic.msg|bdb/docs/ref/pindex.src|20010305004149|02223|7d74723f9fd25801
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/appsignals.html|20010305004150|48930|3ab63bf9399d7ead
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/byteorder.html|20010305004150|49835|f7fa52b53e4c8838
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/compatible.html|20010305004150|50729|237b98e6a6d7ed35
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/copy.html|20010305004150|51641|bcf5ff9656fafcd3
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/dbsizes.html|20010305004150|52571|d70da530573b9b38
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/diskspace.html|20010305004150|53502|959508f155721ee8
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/environ.html|20010305004150|54494|dc4a48aa531bd399
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/errorret.html|20010305004150|55412|23491397d7e704e9
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/extending.html|20010305004150|56407|6a86a40872d6b8bc
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/mt.html|20010305004150|57429|552ab570b657fc0e
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/namespace.html|20010305004150|58394|182f8f762343bdc1
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/recimp.html|20010305004150|60288|bbdb0feb7d467a80
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/runtime.html|20010305004150|61233|6853fdbfe15df788
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/scope.html|20010305004150|59326|2987f97781410bc1
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/solaris.txt|20010305004150|63135|8b6bb29de0d58ffe
+tim@threads.polyesthetic.msg|bdb/docs/ref/program/version.html|20010305004150|62172|d266e819d1531df8
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/bdb_usenix.html|20010305004150|00758|bad2247b4f8c582b
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/bdb_usenix.ps|20010305004150|02162|9851f6cdeff17481
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/embedded.html|20010305004150|03865|d25b9719d24df88c
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/hash_usenix.ps|20010305004150|05408|11cad226b0aa012b
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/libtp_usenix.ps|20010305004150|08667|73329b041f7e8c41
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/refs.html|20010305004150|64422|30490b237ba9b61
+tim@threads.polyesthetic.msg|bdb/docs/ref/refs/witold.html|20010305004150|65330|ad6c866cf48734b5
+tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/client.html|20010305004150|12568|824178f8626e45b7
+tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/intro.html|20010305004150|13549|ad16bc20623e1192
+tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/server.html|20010305004150|14510|79f560205494295
+tim@threads.polyesthetic.msg|bdb/docs/ref/sendmail/intro.html|20010305004150|16532|ecac45d7e2bcf51c
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/close.html|20010305004150|18046|1fe3a82f28e7ed32
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/del.html|20010305004150|19030|514a1bd568ed4c1d
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/errors.html|20010305004150|19994|be11ff6410e1db2c
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/example.txt|20010305004150|28042|9ff88f22565208bf
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/get.html|20010305004150|20970|211de230d6a6cbc5
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/handles.html|20010305004150|21935|18a14f4a50e7bad0
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/intro.html|20010305004150|22878|7544c4688623a54c
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/keydata.html|20010305004150|23810|530b1581aeba63ca
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/open.html|20010305004150|24776|5d6eb5c3df68eeee
+tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/put.html|20010305004150|25774|bdd2629c212af471
+tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/error.html|20010305004151|21581|37b817c57777b460
+tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/faq.html|20010305004151|22367|f8433900f7f85400
+tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/intro.html|20010305004151|20749|d66c6c398e2ace0b
+tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/program.html|20010305004151|23138|2f5bf497ae226ed5
+tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/using.html|20010305004151|23908|28856d8c72d0660b
+tim@threads.polyesthetic.msg|bdb/docs/ref/test/faq.html|20010305004151|38444|f95038006d18229
+tim@threads.polyesthetic.msg|bdb/docs/ref/test/run.html|20010305004151|39305|63c0398e7e2a29e2
+tim@threads.polyesthetic.msg|bdb/docs/ref/toc.html|20010305004148|08788|ab1fa294d5ef4b69
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/admin.html|20010305004151|41323|cf867ed0b00cccef
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/app.html|20010305004151|42111|6dc3c82982164fa8
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/archival.html|20010305004151|42978|7631314d840be181
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/checkpoint.html|20010305004151|43948|29e077c954369ed
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/cursor.html|20010305004151|44775|824b2f28c9e8d610
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/data_open.html|20010305004151|45592|413c1d8aba9d8018
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/deadlock.html|20010305004151|46421|34914b9dc6b01703
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/env_open.html|20010305004151|47233|c8d61102658c3bbf
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/filesys.html|20010305004151|48077|ebee24f726f99bf6
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/inc.html|20010305004151|48911|5ea32b4e2a2107b3
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/intro.html|20010305004151|49773|22096cea9fe159ac
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/logfile.html|20010305004151|50590|1c3002fcb6581e8c
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/put.html|20010305004151|51420|8cc785aeecff8535
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/read.html|20010305004151|52265|fc8b056380e09887
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/reclimit.html|20010305004151|53098|5f54174bf6026bd5
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/recovery.html|20010305004151|53956|6e3a0c07b997c3b2
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/term.html|20010305004151|54819|d6f3fa4fc5a630ec
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/throughput.html|20010305004151|55655|8a7d5a958df7f91a
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/transapp.txt|20010305004151|57368|337576ea2aae23b0
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/why.html|20010305004151|56525|c941c1a56a0adbaf
+tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/writetest.txt|20010305004151|58289|4de1fc39894cd760
+tim@threads.polyesthetic.msg|bdb/docs/ref/txn/config.html|20010305004151|59874|c7337cb30f9bf66
+tim@threads.polyesthetic.msg|bdb/docs/ref/txn/intro.html|20010305004151|60722|85fabd5518fb26be
+tim@threads.polyesthetic.msg|bdb/docs/ref/txn/limits.html|20010305004151|61583|3004b7a93dab148b
+tim@threads.polyesthetic.msg|bdb/docs/ref/txn/nested.html|20010305004151|62443|6860bbf2f29aa93b
+tim@threads.polyesthetic.msg|bdb/docs/ref/txn/other.html|20010305004151|63311|4991722636b3a46d
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/convert.html|20010305004151|00512|d7f18eb34c1b6ae
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/disk.html|20010305004151|01410|94dc4e6e3668e613
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/intro.html|20010305004151|02261|8bfd3804a2da1598
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/system.html|20010305004151|03146|eae0256a127c3c89
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/toc.html|20010305004151|04069|670791f294a61494
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/close.html|20010305004151|05457|c79c866b393785cc
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/cxx.html|20010305004151|06323|7f3bfc9bba854d48
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/db.html|20010305004151|07207|e7d63f4bb8e989e8
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/db_cxx.html|20010305004151|08078|5c17d6a360205140
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbenv.html|20010305004151|08972|f9863847dc1ed617
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbenv_cxx.html|20010305004151|09872|7f4fd0ebace36d8e
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbinfo.html|20010305004151|10780|7529af7145c0680a
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/disk.html|20010305004151|11685|eb79d1157ef44d3c
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/eacces.html|20010305004151|12569|f0299373d8b2f65c
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/eagain.html|20010305004151|13462|920800d8eb450f79
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/envopen.html|20010305004151|14369|5e768fd180f471e4
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/func.html|20010305004151|15332|c06e5bc63ddf7a64
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/intro.html|20010305004151|16219|7ecd16967b0bc868
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/java.html|20010305004151|17120|300acccbb633e335
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/join.html|20010305004151|18031|ec21d874caa0654
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/jump_set.html|20010305004151|18936|718c098a91db9dba
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_detect.html|20010305004151|19846|fb307b10156762ca
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_notheld.html|20010305004151|20761|ed6853b6daa5531b
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_put.html|20010305004151|21664|fd9ed0b04b465af
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_stat.html|20010305004151|22568|c49716e693ce225b
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/log_register.html|20010305004151|23513|399320e965adf598
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/log_stat.html|20010305004151|24428|20b5898ba061557d
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/memp_stat.html|20010305004151|25363|79e1141c63f7357
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/open.html|20010305004151|27357|8b1e2a969e97069a
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/rmw.html|20010305004151|28431|992b0143d13a3ec0
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/stat.html|20010305004151|29377|775d75e3ba02d15c
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/toc.html|20010305004151|30301|16e7d8e76496cbc9
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_begin.html|20010305004151|31307|53512180de5fec80
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_commit.html|20010305004151|32241|e1debf9ea769426c
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_stat.html|20010305004151|33181|516f1870c6127351
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/value_set.html|20010305004151|34118|f0b0c770a81b90b6
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/xa.html|20010305004152|00602|1af042e462ab829
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/btstat.html|20010305004152|37584|40a76aef8b25a948
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/config.html|20010305004152|38401|d2ace28f39ab0f8d
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/disk.html|20010305004152|39192|2abdaf9059265ba9
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/dup.html|20010305004152|40004|911018877c118b45
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/env.html|20010305004152|40827|381e366a9c9c9a37
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/intro.html|20010305004152|41719|64592a50b1c634d6
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/log_register.html|20010305004152|42524|7177eeb2fc099317
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/logalloc.html|20010305004152|43372|30563c544b8ddd54
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/memp_register.html|20010305004152|44171|7d92464a1029d53e
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/put.html|20010305004152|44997|961a1a689be6ce
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_feedback.html|20010305004152|45815|6d7de50be92a5488
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_paniccall.html|20010305004152|46636|8f9741244fb6e9f6
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_tx_recover.html|20010305004152|47442|ada65907ba98eee8
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/sysmem.html|20010305004152|48282|3d088eb0ef1b27e0
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/tcl.html|20010305004152|49096|f5c85b09c33bda4
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/tmp.html|20010305004152|50733|ef3450f6fa89f2dc
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/toc.html|20010305004152|49908|af1a24798980ad1
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/txn_check.html|20010305004152|51549|2405b25bc92cc476
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/callback.html|20010305004152|53656|64a2b2b85cc253c1
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/db_dump.html|20010305004152|54477|7d1cac3358c0482e
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/disk.html|20010305004152|55280|61799ebebe78ebb2
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/handle.html|20010305004152|56086|bb8a73b74d4399ae
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/incomplete.html|20010305004152|56914|af86a649a878a124
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/intro.html|20010305004152|57734|984a9f7dd07e0c14
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/mutexlock.html|20010305004152|58567|972b710c5bdba67c
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/notfound.html|20010305004152|59393|dc91c094aba92838
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/renumber.html|20010305004152|60219|d6cd798434da81aa
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/set_flags.html|20010305004152|61061|213809ca8d7802d0
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/toc.html|20010305004152|61902|9c94c533ada43c1a
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/tx_recover.html|20010305004152|62754|132a354cde7a8286
+tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade/process.html|20010305004151|64704|78f9ca966a587234
+tim@threads.polyesthetic.msg|bdb/docs/ref/xa/config.html|20010305004152|64479|3f3f449c305e66b4
+tim@threads.polyesthetic.msg|bdb/docs/ref/xa/faq.html|20010305004152|65373|7aa890c7b70f1293
+tim@threads.polyesthetic.msg|bdb/docs/ref/xa/intro.html|20010305004152|00728|8ac020ffb869e9a8
+tim@threads.polyesthetic.msg|bdb/docs/sleepycat/contact.html|20010305004152|04402|55b4da3d7bf7655b
+tim@threads.polyesthetic.msg|bdb/docs/sleepycat/legal.html|20010305004152|02616|7388af4c578cacf6
+tim@threads.polyesthetic.msg|bdb/docs/sleepycat/license.html|20010305004152|03483|9371001bbf0ba2dd
+tim@threads.polyesthetic.msg|bdb/docs/utility/berkeley_db_svc.html|20010305004152|06576|91fe012778882ce4
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_archive.html|20010305004152|07446|ab2c66e01b3e3626
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_checkpoint.html|20010305004152|08309|c040e4424edcc451
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_deadlock.html|20010305004152|09191|f23f99911c3e5784
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_dump.html|20010305004152|10062|5de7ade427f20332
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_load.html|20010305004152|10976|981095940db0197
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_printlog.html|20010305004152|11895|fcc4075ad0232842
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_recover.html|20010305004152|12771|1b63f2acdc0b0af7
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_stat.html|20010305004152|13652|9582c327964e1f9
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_upgrade.html|20010305004152|14532|6444f26a93f77ea
+tim@threads.polyesthetic.msg|bdb/docs/utility/db_verify.html|20010305004152|15424|4fee9bfa2f9ab41a
+tim@threads.polyesthetic.msg|bdb/docs/utility/index.html|20010305004152|05717|66c82ee036c1b369
+tim@threads.polyesthetic.msg|bdb/hash/hash_auto.c|20010305004137|61459|d17c6a6ed4f181d1
+tim@threads.polyesthetic.msg|bdb/include/btree_auto.h|20010305004137|17274|84d4451c78faf67e
+tim@threads.polyesthetic.msg|bdb/include/btree_ext.h|20010305004137|18246|5d53d710f170c6b6
+tim@threads.polyesthetic.msg|bdb/include/clib_ext.h|20010305004137|19207|ed9d9f7965f0e1d3
+tim@threads.polyesthetic.msg|bdb/include/common_ext.h|20010305004137|20146|35c8aab64ee3b8fd
+tim@threads.polyesthetic.msg|bdb/include/crdel_auto.h|20010305004137|21088|1b8255da47550ece
+tim@threads.polyesthetic.msg|bdb/include/db_auto.h|20010305004137|26350|994ddc84db334345
+tim@threads.polyesthetic.msg|bdb/include/db_ext.h|20010305004137|29469|a1e210bbd0de0a48
+tim@threads.polyesthetic.msg|bdb/include/db_server.h|20010305004137|34247|61a33aa05bf368a7
+tim@threads.polyesthetic.msg|bdb/include/env_ext.h|20010305004138|05832|33a5fdef1aeecefd
+tim@threads.polyesthetic.msg|bdb/include/gen_client_ext.h|20010305004138|06647|5c621cacb18b38
+tim@threads.polyesthetic.msg|bdb/include/gen_server_ext.h|20010305004138|07539|fd7bcfe6bbca8bcb
+tim@threads.polyesthetic.msg|bdb/include/hash_auto.h|20010305004138|09216|1b79cdd426d7ef25
+tim@threads.polyesthetic.msg|bdb/include/hash_ext.h|20010305004138|10079|5b31ff8413481606
+tim@threads.polyesthetic.msg|bdb/include/lock_ext.h|20010305004138|11814|ccd0785bb206933f
+tim@threads.polyesthetic.msg|bdb/include/log_auto.h|20010305004138|13513|8d52dd0884d03051
+tim@threads.polyesthetic.msg|bdb/include/log_ext.h|20010305004138|14339|2988f11d4545c76b
+tim@threads.polyesthetic.msg|bdb/include/mp_ext.h|20010305004138|17070|a528b772d42d6455
+tim@threads.polyesthetic.msg|bdb/include/mutex_ext.h|20010305004138|19006|f20f47ddc346598b
+tim@threads.polyesthetic.msg|bdb/include/os_ext.h|20010305004138|20730|a1771032b4d2d53b
+tim@threads.polyesthetic.msg|bdb/include/qam_auto.h|20010305004138|24568|96f6c045fd0d6cab
+tim@threads.polyesthetic.msg|bdb/include/qam_ext.h|20010305004138|25430|9993db1fb3428b6d
+tim@threads.polyesthetic.msg|bdb/include/rpc_client_ext.h|20010305004138|28220|85436ca9b5691338
+tim@threads.polyesthetic.msg|bdb/include/rpc_server_ext.h|20010305004138|29091|952741fb85de2b80
+tim@threads.polyesthetic.msg|bdb/include/tcl_ext.h|20010305004138|31857|6759d22aa2ff5f39
+tim@threads.polyesthetic.msg|bdb/include/txn_auto.h|20010305004138|33645|e3f49e94fd291c45
+tim@threads.polyesthetic.msg|bdb/include/txn_ext.h|20010305004138|34549|9db24c14f204890c
+tim@threads.polyesthetic.msg|bdb/include/xa_ext.h|20010305004138|36449|50918e5ef9f095b6
+tim@threads.polyesthetic.msg|bdb/java/src/com/sleepycat/db/DbConstants.java|20010305004138|56622|15fa87eda6b72302
+tim@threads.polyesthetic.msg|bdb/log/log_auto.c|20010305004137|49459|fe8c0369965f7151
+tim@threads.polyesthetic.msg|bdb/qam/qam_auto.c|20010305004141|31764|361954d3f149feb0
+tim@threads.polyesthetic.msg|bdb/rpc_client/db_server_clnt.c|20010305004141|41933|b548b860f765c597
+tim@threads.polyesthetic.msg|bdb/rpc_client/gen_client.c|20010305004141|43060|ad86f092d0996a68
+tim@threads.polyesthetic.msg|bdb/rpc_server/db_server.x|20010305004141|47705|811aeb6b630fe7aa
+tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_proc.sed|20010305004141|49906|1a9af8e5b051acbd
+tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_svc.c|20010305004141|50897|35804eb82b953f49
+tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_xdr.c|20010305004141|53794|336ef020b4a22c05
+tim@threads.polyesthetic.msg|bdb/rpc_server/gen_db_server.c|20010305004141|54931|d5602f9bd5c930e
+tim@threads.polyesthetic.msg|bdb/test/include.tcl|20010305004141|34016|20fc297b040cbe2
+tim@threads.polyesthetic.msg|bdb/test/logtrack.list|20010305004142|05743|7f4f1382b37d98e5
+tim@threads.polyesthetic.msg|bdb/txn/txn_auto.c|20010305004143|19863|6eb282f016f606d9
+tonu@x3.internalnet|include/vio.h|20010520213124|42404|c62fd2b86c03da7d
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 11a8f3b8fcd..e6bfe0ceb36 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -1,47 +1,135 @@
+Administrador@light.
+Administrator@co3064164-a.
+Administrator@co3064164-a.rochd1.qld.optushome.com.au
+Administrator@fred.
Miguel@light.local
Sinisa@sinisa.nasamreza.org
+ahlentz@co3064164-a.rochd1.qld.optusnet.com.au
+akishkin@work.mysql.com
+arjen@co3064164-a.bitbike.com
arjen@fred.bitbike.com
+arjen@george.bitbike.com
+bar@bar.intranet.mysql.r18.ru
bar@bar.mysql.r18.ru
bar@bar.udmsearch.izhnet.ru
+bell@laptop.sanja.is.com.ua
bell@sanja.is.com.ua
bk@admin.bk
+carsten@tsort.bitbybit.dk
+davida@isil.mysql.com
+dlenev@build.mysql.com
+dlenev@mysql.com
+gerberb@ou800.zenez.com
+gluh@gluh.(none)
+gluh@gluh.mysql.r18.ru
greg@gcw.ath.cx
greg@mysql.com
guilhem@mysql.com
+gweir@build.mysql.com
+gweir@work.mysql.com
heikki@donna.mysql.fi
heikki@hundin.mysql.fi
+heikki@rescue.
+heikki@work.mysql.com
+hf@deer.(none)
+hf@deer.mysql.r18.ru
+hf@genie.(none)
+igor@hundin.mysql.fi
+igor@rurik.mysql.com
+jani@dsl-jkl1657.dial.inet.fi
+jani@hynda.(none)
jani@hynda.mysql.fi
+jani@janikt.pp.saunalahti.fi
+jani@rhols221.adsl.netsonic.fi
+jani@rhols221.arenanet.fi
+jani@ua126d19.elisa.omakaista.fi
+jani@ua141d10.elisa.omakaista.fi
+jcole@abel.spaceapes.com
+jcole@main.burghcom.com
+jcole@mugatu.spaceapes.com
+jcole@sarvik.tfr.cafe.ee
+jcole@tetra.spaceapes.com
jorge@linux.jorge.mysql.com
+kaj@work.mysql.com
konstantin@mysql.com
+kostja@oak.local
+lenz@kallisto.mysql.com
lenz@mysql.com
miguel@hegel.(none)
miguel@hegel.br
miguel@hegel.local
+miguel@light.
miguel@light.local
miguel@sartre.local
+mmatthew@markslaptop.
monty@bitch.mysql.fi
+monty@butch.
monty@donna.mysql.fi
monty@hundin.mysql.fi
+monty@mashka.(none)
monty@mashka.mysql.fi
monty@mishka.mysql.fi
+monty@mysql.com
monty@narttu.
monty@narttu.mysql.fi
+monty@rescue.
monty@tik.
monty@tik.mysql.fi
+monty@tramp.mysql.fi
monty@work.mysql.com
mwagner@cash.mwagner.org
+mwagner@evoq.mwagner.org
+mwagner@work.mysql.com
+mysqldev@build.mysql2.com
nick@mysql.com
nick@nick.leippe.com
paul@central.snake.net
+paul@ice.local
+paul@ice.snake.net
paul@teton.kitebird.com
+pem@mysql.com
+peter@linux.local
+peter@mysql.com
+peterg@mysql.com
+pgulutzan@linux.local
+ram@gw.mysql.r18.ru
+ram@mysql.r18.ru
+ram@ram.(none)
+ranger@regul.home.lan
+root@x3.internalnet
salle@geopard.(none)
salle@geopard.online.bg
+salle@vafla.home
+salle@vafla.online.bg
sasha@mysql.sashanet.com
serg@build.mysql2.com
serg@serg.mylan
serg@serg.mysql.com
+serg@sergbook.mylan
serg@sergbook.mysql.com
+sergefp@mysql.com
sinisa@rhols221.adsl.netsonic.fi
+tfr@beta.frontier86.ee
+tfr@indrek.tfr.cafe.ee
+tfr@sarvik.tfr.cafe.ee
+tim@bitch.mysql.fi
+tim@black.box
+tim@hundin.mysql.fi
+tim@threads.polyesthetic.msg
+tim@white.box
+tim@work.mysql.com
+tom@basil-firewall.home.com
+tonu@hundin.mysql.fi
+tonu@volk.internalnet
+tonu@x153.internalnet
+tonu@x3.internalnet
+venu@work.mysql.com
vva@eagle.mysql.r18.ru
+vva@genie.(none)
+walrus@kishkin.ru
walrus@mysql.com
+wax@mysql.com
+worm@altair.is.lan
zak@balfor.local
+zak@linux.local
+zgreant@mysql.com
diff --git a/BitKeeper/etc/skipkeys b/BitKeeper/etc/skipkeys
index 9f29647d38a..36b38ab1c21 100644
--- a/BitKeeper/etc/skipkeys
+++ b/BitKeeper/etc/skipkeys
@@ -1,4 +1,5 @@
BK|scripts/safe_mysqld.sh|19700101030959|01930|d0a3cc73fd1b0d8d tim@localhost.polyesthetic.msg|scripts/safe_mysqld.sh|20000802235627|38519
+bk@work.mysql.com|BitKeeper/etc/logging_ok|20000731192914|03271|5e19f6258f804ffe arjen@co3064164-a.bitbike.com|BitKeeper/etc/logging_ok|20011212060636|33009
bk@work.mysql.com|BitKeeper/etc/logging_ok|20000731192914|03271|5e19f6258f804ffe jcole@tetra.bedford.progress.com|BitKeeper/etc/logging_ok|20001004201211|30554
bk@work.mysql.com|BitKeeper/etc/logging_ok|20000731192914|03271|5e19f6258f804ffe sasha@work.mysql.com|BitKeeper/etc/logging_ok|20000802223223|24242
bk@work.mysql.com|BitKeeper/etc/logging_ok|20000731192914|03271|5e19f6258f804ffe tim@localhost.polyesthetic.msg|BitKeeper/etc/logging_ok|20000802235640|27343
diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit
index d060c59ab39..2dfefb5deb3 100755
--- a/BitKeeper/triggers/post-commit
+++ b/BitKeeper/triggers/post-commit
@@ -18,30 +18,38 @@ BK_STATUS=$BK_STATUS$BK_COMMIT
if [ "$BK_STATUS" = OK ]
then
- CHANGESET=`bk -R prs -r+ -h -d':I:' ChangeSet`
+CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet`
+
+#++
+# dev-public@
+#--
echo "Commit successful, notifying developers at $TO"
(
cat <<EOF
-List-ID: <bk.mysql>
+List-ID: <bk.mysql-4.0>
From: $FROM
To: $TO
-Subject: bk commit into 3.23 tree ($CHANGESET)
+Subject: bk commit - 4.0 tree ($CHANGESET)
EOF
bk changes -v -r+
bk cset -r+ -d
) | head -n $LIMIT | /usr/sbin/sendmail -t
+
+#++
+# internals@ mail
+#--
echo "Notifying internals list at $INTERNALS"
(
cat <<EOF
-List-ID: <bk.mysql>
+List-ID: <bk.mysql-4.0>
From: $FROM
To: $INTERNALS
-Subject: bk commit into 3.23 tree ($CHANGESET)
+Subject: bk commit into 4.0 tree ($CHANGESET)
Below is the list of changes that have just been committed into a local
-3.23 repository of $USER. When $USER does a push these changes will
+4.0 repository of $USER. When $USER does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
@@ -62,10 +70,10 @@ EOF
echo "Notifying docs list at $DOCS"
(
cat <<EOF
-List-ID: <bk.mysql-3.23>
+List-ID: <bk.mysql-4.0>
From: $FROM
To: $DOCS
-Subject: bk commit - 3.23 tree (Manual) ($CHANGESET)
+Subject: bk commit - 4.0 tree (Manual) ($CHANGESET)
EOF
bk changes -v -r+
@@ -74,5 +82,5 @@ EOF
fi
else
- echo "commit failed because '$BK_STATUS', you may need to re-clone..."
+ echo "commit failed because '$BK_STATUS', you may need to re-clone..."
fi
diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap
new file mode 100755
index 00000000000..a46d83ca91c
--- /dev/null
+++ b/Build-tools/Bootstrap
@@ -0,0 +1,425 @@
+#!/usr/bin/perl -w
+#
+# Bootstrap
+#
+# Script to export a given BK source tree into a separate directory
+# and create the source distribution to be used for all binary builds
+#
+# Use the "--help" option for more info!
+#
+# written by Lenz Grimmer <lenz@mysql.com>
+#
+
+use Cwd;
+use Getopt::Long;
+Getopt::Long::Configure ("bundling");
+
+# Include helper functions
+$LOGGER= "$ENV{HOME}/bin/logger.pm";
+if (-f $LOGGER)
+{
+ do "$LOGGER";
+}
+else
+{
+ die "ERROR: $LOGGER cannot be found!\n";
+}
+
+# Some predefined settings
+$build_command= "BUILD/compile-pentium-max";
+$PWD= cwd();
+$LOGFILE= $PWD . "/Bootstrap.log";
+$opt_docdir= $PWD . "/mysqldoc";
+$opt_build_command= undef;
+$opt_changelog= undef;
+$opt_delete= undef;
+$opt_directory= $PWD;
+$opt_dry_run= undef;
+$opt_export_only= undef;
+$opt_help= $opt_verbose= 0;
+$opt_log= undef;
+$opt_mail= "";
+$opt_pull= undef;
+$opt_revision= undef;
+$opt_suffix= "";
+$opt_test= undef;
+$opt_skip_check= undef;
+$opt_skip_manual= undef;
+$opt_win_dist= undef;
+$version= "unknown";
+$major=$minor=$release=0;
+
+GetOptions(
+ "build-command|b=s",
+ "changelog|c:s",
+ "directory|d=s",
+ "delete",
+ "docdir=s",
+ "dry-run",
+ "export-only|e",
+ "help|h",
+ "log|l:s",
+ "mail|m=s",
+ "pull|p",
+ "revision|r=s",
+ "skip-check|s",
+ "skip-manual",
+ "suffix=s",
+ "test|t",
+ "verbose|v",
+ "win-dist|w"
+) || print_help("");
+
+#
+# Override predefined Log file name
+#
+if (defined $opt_log)
+{
+ if ($opt_log ne "")
+ {
+ if ($opt_log =~ /^\/.*/)
+ {
+ $LOGFILE= $opt_log;
+ }
+ else
+ {
+ $LOGFILE= $PWD . "/" . $opt_log;
+ }
+ }
+}
+
+#
+# Override predefined build command
+#
+if (defined $opt_build_command)
+{
+ $build_command= $opt_build_command;
+}
+
+print_help("") if ($opt_help);
+defined($REPO=$ARGV[0]) || print_help("Please enter the BK repository to be used!");
+
+$subject= "Bootstrap of $REPO failed" if $opt_mail;
+
+&logger("Starting build");
+&abort("The directory \"$REPO\" could not be found!") if (!-d $REPO);
+&logger("Using $REPO as the BK parent repository");
+system ("bk help > /dev/null") == 0 or &abort("Cannot execute BitKeeper binary!");
+system ("bk root $REPO > /dev/null 2>&1") == 0 or &abort("$REPO does not seem to be a valid BK repository!");
+
+if (($opt_directory ne $PWD) && (!-d $opt_directory && !$opt_dry_run))
+{
+ &abort("Could not find target directory \"$opt_directory\"!");
+}
+
+&logger("Logging to $LOGFILE") if (defined $opt_log);
+
+#
+# Pull recent changes first
+#
+if ($opt_pull)
+{
+ &logger("Updating BK tree $REPO to latest ChangeSet first");
+ $command= "cd $REPO; bk pull; cd ..";
+ &run_command($command, "Could not update $REPO!");
+
+ unless ($opt_skip_manual)
+ {
+ &logger("Updating manual tree in $opt_docdir");
+ $command= "cd $opt_docdir; bk pull; cd ..";
+ &run_command($command, "Could not update $opt_docdir!");
+ }
+}
+
+#
+# Use a temporary name until we know the version number
+#
+$target_dir= $opt_directory . "/mysql-" . $$ . "-" . time() . ".tmp";
+&logger("Using temporary directory $target_dir");
+&abort("Target directory $target_dir already exists!") if (-d $target_dir && !$opt_dry_run);
+
+#
+# Export the BK tree
+#
+$command= "bk export ";
+$command.= "-r " . $opt_revision . " " if $opt_revision;
+$command.= "-v " if ($opt_verbose || defined $opt_log);
+$command.= $REPO . " " . $target_dir;
+&logger("Exporting $REPO");
+&run_command($command, "Could not create $target_dir!");
+
+#
+# Make sure we can write all files
+#
+$command= "find $target_dir -type f -print0 | xargs --null chmod u+w";
+&run_command($command, "Failed to fix file permissions!");
+
+#
+# Try to obtain version number from newly extracted configure.in
+#
+$CONF="$target_dir/configure.in";
+&abort("Could not find \"$CONF\" to determine version!") if (!-f $CONF && !$opt_dry_run);
+
+#
+# The following can only be done, if the tree has actually been
+# exported - it cannot be performed in a dry run.
+#
+if (!$opt_dry_run)
+{
+ open (CONF, $CONF) or &abort("Unable to open \"$CONF\": $!");
+ @conf= <CONF>;
+ close CONF;
+
+ foreach (@conf)
+ {
+ m/^AM_INIT_AUTOMAKE\(mysql, ([1-9]\.[0-9]{1,2}\.[0-9]{1,2}.*)\)/;
+ $version= $1;
+ ($major, $minor, $release) = split(/\./,$version);
+ }
+ &logger("Found version string: $version");
+
+ #
+ # Add suffix to version string and write out the modified file
+ #
+ if ($opt_suffix)
+ {
+ $opt_suffix= "-" . &ymd() if ($opt_suffix eq "YMD");
+
+ &logger("Replacing $version with $version$opt_suffix");
+ foreach (@conf)
+ {
+ s/^AM_INIT_AUTOMAKE.*/AM_INIT_AUTOMAKE\(mysql, $version$opt_suffix\)/;
+ }
+ open(CONF,">$CONF") or &abort("Unable to open \"$CONF\": $!");
+ print CONF @conf;
+ close(CONF);
+ }
+}
+
+#
+# Rename directory according to the version number found in configure.in
+# of the extracted tree (plus suffix, if requested)
+#
+$temp_name= $target_dir;
+$target_dir= $opt_directory . "/mysql-" . $version . $opt_suffix . "-build";
+if (-d $target_dir)
+{
+ &logger("Target directory $target_dir already exists!");
+ if ($opt_delete)
+ {
+ &logger("Deleting $target_dir...");
+ $command= "rm ";
+ $command.= "-v " if ($opt_verbose || defined $opt_log);
+ $command.= "$target_dir";
+ &run_command($command, "Could not delete $target_dir!");
+ }
+ else
+ {
+ &logger("Renaming $target_dir to $target_dir.old." . $$);
+ $command= "mv ";
+ $command.= "-v " if ($opt_verbose || defined $opt_log);
+ $command.= "$target_dir $target_dir.old." . $$;
+ &run_command($command, "Could not rename $target_dir!");
+ }
+}
+
+&logger("Renaming temporary directory to $target_dir");
+$command= "mv ";
+$command.= "-v " if ($opt_verbose || defined $opt_log);
+$command.= "$temp_name $target_dir";
+&run_command($command, "Could not rename $temp_name!");
+
+#
+# Add a ChangeLog (make dist will pick it up automatically)
+#
+if (defined $opt_changelog)
+{
+ #
+ # Use some magic to obtain the correct ChangeSet number that identifies
+ # the last tagged ChangeSet (this relies heavily on our current tagging
+ # practice!)
+ #
+ my $revision= "";
+ if ($opt_changelog eq "last")
+ {
+ if (!$opt_revision)
+ {
+ $revision= `bk changes -t -d':REV:::TAG:' -n $REPO | grep mysql-$major.$minor | head -1 | cut -f1 -d ":"`;
+ }
+ else
+ {
+ $revision= `bk changes -r..$opt_revision -t -d':REV:' -n $REPO | head -2 | tail -1`;
+ }
+ chomp($revision);
+ $opt_changelog= $revision;
+ }
+
+ $msg= "Adding $target_dir/ChangeLog";
+ $msg.= " (down to revision $opt_changelog)" if $opt_changelog ne "";
+ &logger($msg);
+ $command= "bk changes -mv";
+ $command.= " -r" if ($opt_changelog ne "" || $opt_revision);
+ $command.= $opt_changelog if $opt_changelog ne "";
+ $command.= ".." if ($opt_changelog ne "" && !$opt_revision);
+ $command.= ".." . $opt_revision if $opt_revision;
+ $command.= " " . $REPO . " > $target_dir/ChangeLog";
+ &logger($command);
+ # We cannot use run_command here because of output redirection
+ if (!$opt_dry_run)
+ {
+ system($command) == 0 or &abort("Could not create $target_dir/ChangeLog!");
+ }
+}
+
+#
+# Add the latest manual from the mysqldoc tree
+#
+unless ($opt_skip_manual)
+{
+ $msg= "Updating manual files";
+ &logger($msg);
+ foreach $file qw/internals manual reservedwords/
+ {
+ system ("bk cat $opt_docdir/Docs/$file.texi > $target_dir/Docs/$file.texi") == 0
+ or &abort("Could not update $file.texi in $target_dir/Docs/!");
+ }
+}
+
+#
+# Abort here, if we just wanted to export the tree
+#
+if ($opt_export_only)
+{
+ &logger("SUCCESS: Export finished successfully.");
+ exit 0;
+}
+
+#
+# Enter the target directory first
+#
+&logger("Entering $target_dir");
+if (!$opt_dry_run)
+{
+ chdir($target_dir) or &abort("Cannot chdir to $target_dir: $!");
+}
+
+#
+# Now build the source distribution
+#
+&logger("Compiling");
+$command= $build_command;
+&run_command($command, "Compilation failed!");
+
+#
+# Testing the built binary by running "make test" (optional)
+#
+if ($opt_test)
+{
+ &logger ("Running test suite");
+ $command= "make test";
+ &run_command($command, "\"make test\" failed!");
+}
+
+#
+# Pack it all up
+#
+&logger("Creating source distribution");
+$command= "make dist";
+&run_command($command, "make dist failed!");
+
+#
+# Package the Windows source
+#
+if ($opt_win_dist)
+{
+ &logger ("Creating Windows source package");
+ $command= "./scripts/make_win_src_distribution --tar --zip";
+ &run_command($command, "make_win_src_distribution failed!");
+}
+
+#
+# Run "make distcheck" to verify the source archive
+#
+if (!$opt_skip_check)
+{
+ &logger ("Checking source distribution");
+ $command= "make distcheck";
+ &run_command($command, "make distcheck failed!");
+}
+
+#
+# All done when we came down here
+#
+&logger("SUCCESS: Build finished successfully.") if (!$opt_dry_run);
+exit 0;
+
+#
+# Print the help text message (with an optional message on top)
+#
+sub print_help
+{
+ my $message= $_[0];
+ if ($message ne "")
+ {
+ print "\n";
+ print "ERROR: $message\n";
+ }
+ print <<EOF;
+
+Usage: Bootstrap [options] <bk repository>
+
+Creates a MySQL source distribution to be used for the release builds.
+
+It checks out (exports) a clear-text version of the given local BitKeeper
+repository, creates and adds a Changelog file (if requested), adds the
+latest manual files from the mysqldoc BK tree and builds a source
+distribution (*.tar.gz) file. Optionally, the test suite and the
+distribution check can be run before the source archive is being created.
+
+Options:
+
+-b, --build-command=<cmd> Use <cmd> to compile the sources before packing
+ the distribution.
+ (default is "$build_command")
+-c, --changelog[=<rev>] Add a ChangeLog [down to revision <rev>]
+ This will automatically be included in the source
+ distribution. To get a ChangeLog down to the last
+ tagged Changeset, simply use "last" as the revision
+ number.
+--delete Delete an already existing distribution directory
+ in the target directory instead of renaming it.
+-d, --directory=<dir> Specify the target directory
+ (default is "$opt_directory")
+--docdir=<dir> Use the MySQL documentation BK tree located
+ in <dir>
+ (default is "$opt_docdir")
+--dry-run Dry run without executing
+-e, --export-only Just export (and add the ChangeLog, if requested),
+ do not build or test the source distribution
+-h, --help Print this help message
+-l, --log[=<filename>] Write a log file [to <filename>]
+ (default is "$LOGFILE")
+-m, --mail=<address> Mail a failure report to the given address (and
+ include a log file snippet, if logging is enabled)
+ Note that the \@-Sign needs to be quoted!
+ Example: --mail=user\\\@domain.com
+-p, --pull Update the source BK trees before building
+-r, --revision=<rev> Export the tree as of revision <rev>
+ (default is up to the latest revision)
+-s, --skip-check Skip checking the distribution with "make distcheck"
+--skip-manual Skip updating the manual from the mysqldoc tree
+--suffix=<suffix> Append <suffix> to the version number in
+ configure.in. Using the special suffix "YMD" will
+ add the current date as the suffix
+ (e.g. "-20020518").
+-t, --test Run the test suite after build
+-v, --verbose Be verbose
+-w, --win-dist Also make Windows source distribution
+
+Example:
+
+ Bootstrap -c last -v -l -- mysql-4.0
+
+EOF
+ exit 1;
+}
diff --git a/Build-tools/Do-all-build-steps b/Build-tools/Do-all-build-steps
index eb14b7105cd..8ff8851aecd 100755
--- a/Build-tools/Do-all-build-steps
+++ b/Build-tools/Do-all-build-steps
@@ -63,9 +63,13 @@ aclocal; autoheader; aclocal; automake; autoconf
--with-low-memory \
--with-mit-threads=yes $EXTRA_CONFIG \
--enable-thread-safe-client \
- --with-berkeley-db \
--enable-local-infile \
- --with-innodb
+ --with-berkeley-db \
+ --with-innodb \
+ --with-vio \
+ --without-pstack \
+ --with-extra-tools \
+ --with-embedded-server
gmake -j 2
diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile
index 9b26a93d100..bd6c89d7ded 100755
--- a/Build-tools/Do-compile
+++ b/Build-tools/Do-compile
@@ -1,6 +1,8 @@
#!/usr/bin/perl -w
+use File::Basename;
use Getopt::Long;
+use Sys::Hostname;
@config_options= ();
@make_options= ();
@@ -8,7 +10,7 @@ use Getopt::Long;
$opt_distribution=$opt_user=$opt_config_env="";
$opt_dbd_options=$opt_perl_options=$opt_config_options=$opt_make_options=$opt_suffix="";
$opt_tmp=$opt_version_suffix="";
-$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=0;
+$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=0;
$opt_innodb=$opt_bdb=$opt_raid=$opt_libwrap=0;
GetOptions(
@@ -51,6 +53,7 @@ GetOptions(
"with-low-memory",
"with-other-libc=s",
"with-small-disk",
+ "without-embedded",
) || usage();
usage() if ($opt_help);
@@ -74,7 +77,7 @@ if (@config_env > 0)
$opt_config_env= join(" ", @config_env);
}
-chomp($host=`hostname`);
+$host= hostname();
chomp($uname=`uname`);
$full_host_name=$host;
$connect_option= ($opt_tcpip ? "--host=$host" : "");
@@ -82,7 +85,7 @@ $host =~ /^([^.-]*)/;
$host=$1 . $opt_suffix;
$email="$opt_user\@mysql.com";
chomp($pwd = `pwd`);
-$VER= `basename $opt_distribution`; chop $VER;
+$VER= basename($opt_distribution);
$VER=~ /mysql.*-([1-9]\.[0-9]{1,2}\.[0-9]{1,2}.*)\.tar*/; $version=$1;
($major, $minor, $release) = split(/\./,$version);
$log="$pwd/Logs/$host-$major.$minor$opt_version_suffix.log";
@@ -109,7 +112,7 @@ if (defined($gcc_version) && ! $opt_config_env)
$new_opt_tmp=0;
if ($opt_tmp)
{
- if (! -d $opt_tmp)
+ unless (-d $opt_tmp)
{
safe_system("mkdir $opt_tmp");
$new_opt_tmp=1;
@@ -132,7 +135,8 @@ $ENV{'MYSQL_TCP_PORT'}= $mysql_tcp_port= 3334 + $opt_build_thread*2;
$ENV{'MYSQL_UNIX_PORT'}=$mysql_unix_port="$opt_tmp/mysql$opt_suffix.build";
$ENV{"PERL5LIB"}="$pwd/$host/perl5:$pwd/$host/perl5/site_perl";
$slave_port=$mysql_tcp_port+16;
-$mysqladmin_args="--no-defaults -u root";
+$manager_port=$mysql_tcp_port+1;
+$mysqladmin_args="--no-defaults -u root --connect_timeout=5 --shutdown_timeout=20";
if ($opt_stage == 0)
{
@@ -158,7 +162,7 @@ if (-x "$host/bin/mysqladmin")
log_system("$host/bin/mysqladmin $mysqladmin_args -P 9306 -h $host -s shutdown");
log_system("$host/bin/mysqladmin $mysqladmin_args -P 9307 -h $host -s shutdown");
}
-
+kill_all("mysqlmanager");
#
# Kill all old processes that are in the build directories
# This is to find any old mysqld servers left from previous builds
@@ -229,6 +233,7 @@ if ($opt_stage <= 1)
$opt_config_options.= " --with-low-memory" if ($opt_with_low_memory);
$opt_config_options.= " --with-mysqld-ldflags=-all-static" if ($opt_static_server);
$opt_config_options.= " --with-raid" if ($opt_raid);
+ $opt_config_options.= " --with-embedded-server" unless ($opt_without_embedded);
# Only enable InnoDB when requested (required to be able to
# build the "Classic" packages that do not include InnoDB)
@@ -247,7 +252,8 @@ if ($opt_stage <= 1)
$opt_config_options.= $opt_with_other_libc;
}
- check_system("$opt_config_env ./configure --prefix=/usr/local/mysql --with-comment=\"Official MySQL$opt_version_suffix binary\" --with-extra-charsets=complex --with-server-suffix=\"$opt_version_suffix\" --enable-thread-safe-client --enable-local-infile $opt_config_options","Thank you for choosing MySQL");
+ $prefix="/usr/local/mysql";
+ check_system("$opt_config_env ./configure --prefix=$prefix --localstatedir=$prefix/data --libexecdir=$prefix/bin --with-comment=\"Official MySQL$opt_version_suffix binary\" --with-extra-charsets=complex --with-server-suffix=\"$opt_version_suffix\" --enable-thread-safe-client --enable-local-infile $opt_config_options","Thank you for choosing MySQL");
if (-d "$pwd/$host/include-mysql")
{
safe_system("cp -r $pwd/$host/include-mysql/* $pwd/$host/$ver/include");
@@ -274,12 +280,16 @@ if ($opt_stage <= 3)
{
my $flags= "";
log_timestamp();
- log_system("rm -fr mysql-3* mysql-4* $pwd/$host/*.tar.gz");
- log_system("nm -n sql/mysqld | gzip -9 -v 2>&1 > sql/mysqld.sym.gz | cat");
+ log_system("rm -fr mysql-{3,4,5}* $pwd/$host/mysql*.t*gz");
+ # No need to add the debug symbols, if the binaries are not stripped (saves space)
+ unless ($opt_with_debug || $opt_no_strip)
+ {
+ log_system("nm -n sql/mysqld | gzip -9 -v 2>&1 > sql/mysqld.sym.gz | cat");
+ }
$flags.= "--no-strip" if ($opt_no_strip || $opt_with_debug);
check_system("scripts/make_binary_distribution --tmp=$opt_tmp --suffix=$opt_suffix $flags",".tar.gz created");
- safe_system("mv mysql*.tar.gz $pwd/$host");
+ safe_system("mv mysql*.t*gz $pwd/$host");
if (-f "client/.libs/mysqladmin")
{
safe_system("cp client/.libs/mysqladmin $pwd/$host/bin");
@@ -291,11 +301,8 @@ if ($opt_stage <= 3)
safe_system("$make clean") if ($opt_with_small_disk);
}
-$tar_file=<$pwd/$host/*.tar.gz>;
-if (!defined($tar_file))
-{
- $tar_file=<$pwd/$host/*.tgz>;
-}
+$tar_file=<$pwd/$host/mysql*.t*gz>;
+abort ("Could not find tarball!") unless ($tar_file);
#
# Unpack the binary distribution
@@ -308,7 +315,7 @@ if ($opt_stage <= 4 && !$opt_no_test)
safe_system("gunzip < $tar_file | $tar xf -");
}
-$tar_file =~ /(mysql[^\/]*)\.tar/;
+$tar_file =~ /(mysql[^\/]*)\.(tar\.gz|tgz)/;
$ver=$1;
$test_dir="$pwd/$host/test/$ver";
$ENV{"LD_LIBRARY_PATH"}= ("$test_dir/lib" .
@@ -322,7 +329,7 @@ if ($opt_stage <= 5 && !$opt_no_test && !$opt_no_mysqltest)
log_timestamp();
system("mkdir $bench_tmpdir") if (! -d $bench_tmpdir);
safe_cd("${test_dir}/mysql-test");
- check_system("./mysql-test-run --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --sleep=10", "tests were successful");
+ check_system("./mysql-test-run --warnings --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --manager-port=$manager_port --no-manager --sleep=10", "tests were successful");
}
#
@@ -339,7 +346,7 @@ if (!$opt_no_test && !$opt_no_benchmark)
$extra="";
if ($opt_bdb)
{
- $extra.=" -O bdb_cache_size=16M";
+ $extra.=" --bdb_cache_size=16M --bdb_max_lock=60000"
}
if ($opt_innodb)
{
@@ -545,6 +552,9 @@ non-standard location overriding default.
--with-small-disk
Clean up the build environment before testing the binary distribution
(to save disk space)
+
+--without-embedded
+Don't compile the embedded server.
EOF
exit 1;
}
diff --git a/Build-tools/Do-linux-build b/Build-tools/Do-linux-build
index 60cbf3426a8..44a9ad05fa2 100755
--- a/Build-tools/Do-linux-build
+++ b/Build-tools/Do-linux-build
@@ -3,7 +3,8 @@
set -e -x
# Only use the "--with-other-libc" parameter, if another libc actually
-# exists at this location
+# exists, since this will also force static linking, which does not work
+# together with OpenSSL
OTHER_LIBC_DIR=/usr/local/mysql-glibc
OTHER_LIBC=""
if [ -d OTHER_LIBC_DIR ] ; then
diff --git a/Build-tools/Do-patch-file b/Build-tools/Do-patch-file
index 975c10c6b0e..7e6d4c493d8 100755
--- a/Build-tools/Do-patch-file
+++ b/Build-tools/Do-patch-file
@@ -13,8 +13,8 @@ NEW="mysql-$VER.tar.gz"
OLD="mysql-$PVER.tar.gz"
RESULT="mysql-$PVER-$VER.patch.gz"
PATCH_DIR=/my/web/Downloads-live/Patches
-RESULT_DIR=/my/web/Downloads-live/MySQL-3.23
-RESULT_DIR_MAX=/my/web/Downloads-live/MySQL-Max-3.23
+RESULT_DIR=/my/web/Downloads-live/MySQL-4.0
+RESULT_DIR_MAX=/my/web/Downloads-live/MySQL-Max-4.0
if test ! -f $NEWDIR/$NEW
then
diff --git a/Build-tools/Do-pkg b/Build-tools/Do-pkg
new file mode 100755
index 00000000000..4d0f120c6e3
--- /dev/null
+++ b/Build-tools/Do-pkg
@@ -0,0 +1,304 @@
+#!/usr/bin/perl -w
+#
+# Do-pkg - convert a binary distribution into a Mac OS X PKG and put it
+# inside a Disk Image (.dmg). Additionally, add a separate package,
+# including the required Startup Item to automatically start MySQL on
+# bootup.
+#
+# The script currently assumes the following environment (which should exist
+# like that, if the Do-compile script was used to build the binary
+# distribution)
+#
+# - there must be a binary distribution (*.tar.gz) in the directory
+# `hostname` of the current directory
+# - the extracted and compiled source tree should be located in the
+# `hostname` directory, too
+#
+# Use the "--help" option for more info!
+#
+# written by Lenz Grimmer <lenz@mysql.com>
+#
+
+use Cwd;
+use File::Basename;
+use File::Copy;
+use Getopt::Long;
+Getopt::Long::Configure ("bundling");
+use Sys::Hostname;
+
+$opt_dry_run= undef;
+$opt_help= undef;
+$opt_log= undef;
+$opt_mail= "";
+$opt_skip_dmg= undef;
+$opt_skip_si= undef;
+$opt_suffix= undef;
+$opt_verbose= undef;
+$opt_version= undef;
+
+GetOptions(
+ "dry-run",
+ "help|h",
+ "log|l:s",
+ "mail|m=s",
+ "skip-dmg|skip-disk-image|s",
+ "skip-si|skip-startup-item",
+ "suffix=s",
+ "verbose|v",
+ "version=s",
+) || &print_help;
+
+# Include helper functions
+$PWD= cwd();
+$LOGGER= "$PWD/logger.pm";
+if (-f "$LOGGER")
+{
+ do "$LOGGER";
+}
+else
+{
+ die "ERROR: $LOGGER cannot be found!\n";
+}
+
+$PM= "/Developer/Applications/PackageMaker.app/Contents/MacOS/PackageMaker";
+$TMP= $ENV{TMPDIR};
+$TMP eq "" ? $TMP= $TMP . "/PKGBUILD.$$": $TMP= "/tmp/PKGBUILD.$$";
+$PKGROOT= "$TMP/PMROOT";
+$PKGDEST= "$TMP/PKG";
+$RESOURCE_DIR= "$TMP/Resources";
+$SUFFIX= $opt_suffix;
+$VERSION= $opt_version;
+($MAJOR, $MINOR, $RELEASE)= split(/\./, $VERSION);
+$NAME= "mysql$SUFFIX-$VERSION";
+$HOST= hostname();
+$ID= getpwuid($>);
+$HOST=~ /^([^.-]*)/;
+$HOST= $1;
+$LOGFILE= "$PWD/Logs/$HOST-$MAJOR.$MINOR$SUFFIX.log";
+$BUILDDIR= "$PWD/$HOST";
+$SRCBASEDIR= <$BUILDDIR/mysql*-$VERSION>;
+$SUPFILEDIR= <$SRCBASEDIR/support-files/MacOSX>;
+$TAR= <$BUILDDIR/$NAME-apple-darwin*-powerpc.tar.gz>;
+$INFO= <$SUPFILEDIR/Info.plist>;
+$DESC= <$SUPFILEDIR/Description.plist>;
+$SI_INFO= <$SUPFILEDIR/StartupItem.Info.plist>;
+$SI_DESC= <$SUPFILEDIR/StartupItem.Description.plist>;
+$SI_PARAMS= <$SUPFILEDIR/StartupParameters.plist>;
+$SI_POST= <$SUPFILEDIR/StartupItem.postinstall>;
+$SI_NAME= "MySQLStartupItem";
+$SI_SCRIPT= <$SUPFILEDIR/MySQL>;
+@RESOURCES= qw/ ReadMe.txt postinstall preinstall /;
+@LICENSES= ("$SRCBASEDIR/COPYING","$SRCBASEDIR/MySQLEULA.txt");
+
+&print_help("") if ($opt_help || !$opt_suffix || !$opt_version);
+
+#
+# Override predefined Log file name
+#
+if (defined $opt_log)
+{
+ if ($opt_log ne "")
+ {
+ if ($opt_log =~ /^\/.*/)
+ {
+ $LOGFILE= $opt_log;
+ }
+ else
+ {
+ $LOGFILE= $PWD . "/" . $opt_log;
+ }
+ }
+}
+
+# Creating the UFS disk image requires root privileges
+die("You must be root to run this script!") if ($ID ne "root" && !$opt_dry_run);
+
+@files= ($TAR, $INFO, $DESC);
+@files= (@files, $SI_INFO, $SI_DESC, $SI_POST, $SI_SCRIPT) unless $opt_skip_si;
+foreach $file (@files)
+{
+ &abort("Unable to find $file!") unless (-f "$file");
+}
+
+# Remove old temporary build directories first
+&logger("Cleaning up temporary build directories");
+&run_command("rm -rf $TMP", "Could not clean up $TMP!");
+&logger("Creating temp directories");
+foreach $dir ($TMP, $PKGROOT, $PKGDEST, $RESOURCE_DIR)
+{
+ if (!-d $dir)
+ {
+ &logger("Creating directory $dir!");
+ unless($opt_dry_run)
+ {
+ mkdir($dir) or &abort("Could not make directory $dir!");
+ }
+ }
+}
+
+foreach $resfile (@RESOURCES)
+{
+ &logger("Copying $SUPFILEDIR/$resfile to $RESOURCE_DIR");
+ unless($opt_dry_run)
+ {
+ copy("$SUPFILEDIR/$resfile", "$RESOURCE_DIR") or
+ &abort("Error while copying $SUPFILEDIR/$resfile to $RESOURCE_DIR");
+ }
+}
+
+# Search for license file
+foreach $license (@LICENSES)
+{
+ if (-f "$license")
+ {
+ &logger("Copy $license to $RESOURCE_DIR/License.txt");
+ unless($opt_dry_run)
+ {
+ copy("$license", "$RESOURCE_DIR/License.txt") or
+ &abort("Error while copying $license to $RESOURCE_DIR");
+ }
+ }
+}
+
+&abort("Could not find a license file!")
+unless (-f "$RESOURCE_DIR/License.txt");
+
+# Extract the binary tarball and create the "mysql" symlink
+&logger("Extracting $TAR to $PKGROOT");
+&run_command("gnutar zxf $TAR -C $PKGROOT", "Unable to extract $TAR!");
+&run_command("cd $PKGROOT ; ln -s mysql* ./mysql", "Unable to create symlink!");
+&run_command("chown -R root.wheel $PKGROOT/*", "Cannot chown $PKGROOT!");
+
+# Now build the PGK using PackageMaker
+# The "|| true" is a nasty hack to work around a problem with Package Maker
+# returning a non-zero value, even though the package was created correctly
+&logger("Running PackageMaker");
+$command= "$PM -build -p $PKGDEST/$NAME.pkg -f $PKGROOT -r $RESOURCE_DIR -i $INFO -d $DESC || true";
+&run_command($command, "Error while building package $NAME.pkg!");
+
+#
+# Build the Startup Item PKG
+#
+unless ($opt_skip_si)
+{
+ &logger("Cleaning up $PKGROOT");
+ &run_command("rm -rf $PKGROOT/*", "Unable to clean up $PKGROOT!");
+ &logger("Cleaning up $RESOURCE_DIR");
+ &run_command("rm -rf $RESOURCE_DIR/*", "Unable to clean up $RESOURCE_DIR!");
+
+ &logger("Installing MySQL StartupItem files into $PKGROOT/MySQL");
+ unless($opt_dry_run)
+ {
+ mkdir("$PKGROOT/MySQL") or &abort("Error creating $PKGROOT/MySQL");
+ copy("$SI_SCRIPT", "$PKGROOT/MySQL/")
+ or &abort("Error copying $SI_SCRIPT!");
+ chmod(0755, "$PKGROOT/MySQL/" . basename("$SI_SCRIPT"));
+ copy("$SI_PARAMS", "$PKGROOT/MySQL/")
+ or &abort("Error copying $SI_PARAMS!");
+ chmod(0644, "$PKGROOT/MySQL/" . basename("$SI_PARAMS"));
+ &run_command("chown -R root.wheel $PKGROOT/*", "Cannot chown $PKGROOT!");
+ copy("$SI_POST", "$RESOURCE_DIR/postinstall")
+ or &abort("Error copying $SI_POST!");
+ chmod(0644, "$RESOURCE_DIR/postinstall");
+ }
+
+ &logger("Building $SI_NAME.pkg using PackageMaker");
+ $command= "$PM -build -p $PKGDEST/$SI_NAME.pkg -f $PKGROOT -r $RESOURCE_DIR -i $SI_INFO -d $SI_DESC || true";
+ &run_command($command, "Error while building package $SI_NAME.pkg!");
+}
+
+if ($opt_skip_dmg)
+{
+ &logger("SUCCESS: Package $PKGDEST/$NAME.pkg created");
+ exit 0;
+}
+
+# Determine the size of the Disk image to be created and add a 5% safety
+# margin for filesystem overhead
+&logger("Determining required disk image size for $PKGDEST");
+unless($opt_dry_run)
+{
+ chomp($_= `du -sk $PKGDEST`);
+ @size= split();
+ $size= int($size[0]+($size[0]*0.05));
+ &logger("Disk image size: $size KB");
+}
+
+unless($opt_dry_run)
+{
+ &abort("Zero bytes? Something is wrong here!") if ($size == 0);
+}
+
+# Now create and mount the disk image
+$TMPNAME= $NAME . ".tmp";
+&logger("Creating temporary Disk image $TMPNAME.dmg");
+$command= "hdiutil create $TMPNAME -size ${size}k -ov -fs UFS -volname $NAME";
+&run_command($command, "Unable to create disk image $TMPNAME.dmg!");
+&logger("Attaching Disk image $TMPNAME.dmg");
+&run_command("hdid $TMPNAME.dmg", "Unable to attach $TMPNAME.dmg!");
+
+# Install the PKG into the .dmg
+chomp($mountpoint=`mount | grep "\/Volumes\/$NAME" | cut -f3 -d" "`) if (!$opt_dry_run);
+&logger("Copying $PKGDEST/$NAME.pkg to Disk image /Volumes/$NAME");
+&run_command("ditto $PKGDEST /Volumes/$NAME", "Could not copy $PKGDEST to /Volumes/$NAME!");
+&run_command("ditto $SUPFILEDIR/ReadMe.txt /Volumes/$NAME", "Could not copy $SPFILEDIR/ReadMe.txt to /Volumes/$NAME!");
+chomp($mountpoint=`mount | grep "\/Volumes\/$NAME" | cut -f1 -d" "`) if (!$opt_dry_run);
+&abort("/Volumes/$NAME not attached!") if (!$mountpoint && !$opt_dry_run);
+&logger("Unmounting $mountpoint");
+&run_command("hdiutil detach $mountpoint", "Unable to detach $mountpoint");
+&run_command("rm -f $NAME.dmg", "Unable to remove $NAME.dmg!") if (-f "$NAME.dmg");
+&logger("Compressing disk image");
+$command= "hdiutil convert $TMPNAME.dmg -format UDZO -imagekey zlib-level=9 -o $NAME.dmg";
+&run_command($command, "Unable to compress disk image!");
+
+# Final cleanups
+&logger("Removing $TMPNAME.dmg");
+&run_command("rm -f $TMPNAME.dmg", "Unable to remove $TMPNAME.dmg!");
+&logger("Removing $TMP");
+&run_command("rm -rf $TMP", "Unable to remove $TMP!");
+
+&logger("SUCCESS: $NAME.dmg created.") if (!$opt_dry_run);
+exit 0;
+
+sub print_help
+{
+ my $message= $_[0];
+ if ($message ne "")
+ {
+ print "\n";
+ print "ERROR: $message\n";
+ }
+ print <<EOF;
+
+Usage: Do-pkg <options> --suffix=<suffix> --version=<version>
+
+Creates a Mac OS X installation package (PKG) and stores it inside
+a Disk Image (.dmg) file. You need to create a binary distribution
+tarball with scripts/make_binary_distribution first!
+
+NOTE: You need to run this script with root privileges (required
+ to create the disk image)
+
+Options:
+
+ --dry-run Dry run without executing
+-h, --help Print this help
+-l, --log[=<filename>] Write a log file [to <filename>]
+ (default is "$LOGFILE")
+-m, --mail=<address> Mail a failure report to the given
+ address (and include a log file snippet,
+ if logging is enabled)
+ Note that the \@-Sign needs to be quoted!
+ Example: --mail=user\\\@domain.com
+-s, --skip-disk-image, --skip-dmg Just build the PKGs, don't put it into a
+ disk image afterwards
+ --skip-startup-item, --skip-si Skip the creation of the StartupItem PKG
+ --suffix=<suffix> The package suffix
+ (e.g. "-standard" or "-pro)
+ --version=<version> The MySQL version number
+ (e.g. 4.0.11-gamma)
+-v, --verbose Verbose execution
+
+EOF
+ exit 1;
+}
diff --git a/Build-tools/Do-rpm b/Build-tools/Do-rpm
index e80cb3f2028..7da8b022031 100755
--- a/Build-tools/Do-rpm
+++ b/Build-tools/Do-rpm
@@ -1,248 +1,249 @@
-#!/bin/bash
+#!/usr/bin/perl -w
+#
+# Do-rpm - compile RPM packages out of a source tarball and move the
+# resulting RPM packages into the current directory.
+#
+# The script currently assumes the following environment:
+#
+# - there must be a source distribution (mysql-<version>.tar.gz)
+# in the current directory
+# - You must provide the name of an RPM spec file (mysql-<version>.spec)
+# as the argument
+#
+# Use the "--help" option for more info!
+#
+# written by Lenz Grimmer <lenz@mysql.com>
+#
+
+use Cwd;
+use File::Basename;
+use File::Copy;
+use Getopt::Long;
+Getopt::Long::Configure ("bundling");
+use Sys::Hostname;
+
+$opt_cc= undef;
+$opt_cflags= undef;
+$opt_clean= undef;
+$opt_cxx= undef;
+$opt_cxxflags= undef;
+$opt_dry_run= undef;
+$opt_help= undef;
+$opt_log= undef;
+$opt_mail= "";
+$opt_verbose= undef;
+
+# Set a dummy version until we know the correct one
+$VERSION= "x.y.z";
+$MAJOR= $MINOR= $RELEASE= 0;
+$SUFFIX= "";
+
+GetOptions(
+ "cc=s",
+ "cflags=s",
+ "clean|c",
+ "cxx=s",
+ "cxxflags=s",
+ "dry-run|t",
+ "help|h",
+ "log|l:s",
+ "mail|m=s",
+ "verbose|v",
+) || &print_help;
+
+&print_help("") if ($opt_help);
+
+defined($SPECFILE=$ARGV[0]) || print_help("Please provide the spec file name!");
+
+# Include helper functions
+$PWD= cwd();
+$LOGGER= "$PWD/logger.pm";
+if (-f "$LOGGER")
+{
+ do "$LOGGER";
+}
+else
+{
+ die "ERROR: $LOGGER cannot be found!\n";
+}
+
+$subject= "RPM build for $SPECFILE failed" if $opt_mail;
+
+# Open the spec file and extract the version number
+open(SPEC, $SPECFILE) or &abort("Unable to open \"$ARGV[0]\": $!");
+@spec= <SPEC>;
+close SPEC;
+
+foreach (@spec)
+{
+ if (m/^%define\s*mysql_version\s*(.*)/)
+ {
+ $VERSION= $1;
+ ($MAJOR, $MINOR, $RELEASE)= split(/\./,$VERSION);
+ ($RELEASE, $SUFFIX)= split(/\-/,$RELEASE);
+ $SUFFIX= "-" . $SUFFIX if ($SUFFIX);
+ }
+}
+
+$HOST= hostname();
+$HOST=~ /^([^.-]*)/;
+$HOST= $1;
+$LOGFILE= "$PWD/Logs/Do-rpm-$HOST-$MAJOR.$MINOR.log";
+&logger("Using spec file for version: $VERSION");
+
+#
+# Override predefined Log file name
+#
+if (defined $opt_log)
+{
+ if ($opt_log ne "")
+ {
+ if ($opt_log =~ /^\/.*/)
+ {
+ $LOGFILE= $opt_log;
+ }
+ else
+ {
+ $LOGFILE= $PWD . "/" . $opt_log;
+ }
+ }
+}
-#helper functions
+#
+# Newer RPM versions ship with a separate tool "rpmbuild" to build RPMs
+#
+if (-x "/usr/bin/rpmbuild")
+{
+ $RPM= "/usr/bin/rpmbuild";
+ $RMSOURCE= "--rmsource --rmspec";
+}
+else
+{
+ $RPM= "/bin/rpm";
+ $RMSOURCE= "--rmspec";
+}
-function copy_to_bmachine
+if ($RPM)
+{
+ &logger("Found rpm binary: $RPM");
+}
+else
{
- if [ x$local_build = x1 ]; then
- cp $1 $2
- else
- scp $1 $owner@$bmachine:$2
- fi
+ &abort("Unable to find RPM binary!");
}
-function copy_from_bmachine
+#
+# determine some RPM settings for this host
+#
+chomp($RPMARCH= `$RPM --eval "%{_arch}" 2> /dev/null`);
+chomp($RPMDIR= `$RPM --eval "%{_rpmdir}" 2> /dev/null`);
+chomp($SOURCEDIR= `$RPM --eval "%{_sourcedir}" 2> /dev/null`);
+chomp($SPECDIR= `$RPM --eval "%{_specdir}" 2> /dev/null`);
+chomp($SRCRPMDIR= `$RPM --eval "%{_srcrpmdir}" 2> /dev/null`);
+
+$SOURCEFILE= glob "mysql*-$VERSION.tar.gz";
+
+&logger("Starting RPM build of MySQL-$VERSION on $HOST");
+
+foreach $file ($SOURCEFILE, $SPECFILE)
{
- if [ x$local_build = x1 ]; then
- cp $1 $2
- else
- scp $owner@$bmachine:$1 $2
- fi
+ &abort("Unable to find $file!") unless (-f "$file");
}
-function run_command
+#
+# Install source and spec file
+#
+&logger("Copying SOURCE and SPEC file to build directories.");
+unless ($opt_dry_run)
{
- if [ x$local_build = x1 ]; then
- bash $1
- else
- cat $1 | ssh $owner@$bmachine bash
- fi
+ copy($SOURCEFILE, $SOURCEDIR)
+ or &abort("Unable to copy $SOURCEFILE to $SOURCEDIR!");
+ copy($SPECFILE, $SPECDIR)
+ or &abort("Unable to copy $SPECFILE to $SPECDIR!");
}
-#Supply defaults
-
-# We built on one of two machines
-bmachine=work
-smachine=work
-owner=my
-
-# Hard path!!
-bpath=`/bin/pwd`
-
-for d in /usr/src/redhat /usr/src/packages ; do
-if test -d "$d"
-then
- rpmdir=$d
-fi
-done
-
-if test -z "$rpmdir"
-then
- echo "Could not find suitable rpmdir on this system"
- exit 1
-fi
-
-
-logdir="$bpath/Logs"
-
-###### Perl STUFF #####
-
-# Perl version numbers. Should be autodetected from the files in the
-# Perl-mysql-modules/ directory.
-DBI_VERSION="1.14"
-DATA_SHOWTABLE_VERSION="3.3"
-DBD_MYSQL_VERSION="1.2215"
-MAKERPM="$rpmdir/SOURCES/makerpm.pl"
-
-#######################
-AM_MAKEFLAGS="-j 2"
-
-VER=`grep "AM_INIT_AUTOMAKE(mysql, " $bpath/configure.in | \
- sed -e 's;AM_INIT_AUTOMAKE(mysql, ;;' -e 's;);;'`
-VER_NO_DASH=`echo $VER | sed -e "s|-.*$||"`
-tarball=$bpath/mysql-$VER.tar.gz
-
-while test $# -gt 0; do
- case "$1" in
- --rpmdir=*)
- rpmdir=`echo $1 | sed -e "s;--rpmdir=;;"`
- ;;
- --smachine=*)
- smachine=`echo $1 | sed -e "s;--smachine=;;"`
- ;;
- --bmachine=*)
- bmachine=`echo $1 | sed -e "s;--bmachine=;;"`
- ;;
- --owner=*)
- owner=`echo $1 | sed -e "s;--owner=;;"`
- ;;
- --tarball=*)
- tarball=`echo $1 | sed -e "s;--tarball=;;"`
- ;;
- --logdir=*)
- logdir=`echo $1 | sed -e "s;--logdir=;;"`
- ;;
- --local )
- local_build=1
- ;;
- --skip-perl )
- skip_perl=1
- ;;
- * ) break ;;
- esac
- shift
-done
-
-echo "Removing old MySQL packages"
-rm -rf $rpmdir/BUILD/mysql-*
-rm -f $rpmdir/SOURCES/mysql-*
-rm -f $rpmdir/SRPMS/MySQL-*
-rm -f $rpmdir/SPEC/mysql-*
-
-if [ ! -d "$logdir" ]; then
- echo "$logdir does not exist, creating"
- mkdir -p $logdir
-fi
-
-if [ ! -f "$tarball" ]; then
- echo "Tarball file $tarball does not exist, please make one first"
- exit 1
-fi
-
-echo "Building RPM for MySQL version $VER on $bmachine"
-
-log=$logdir/Log-RPM-`date +%y%m%d-%H%M`
-
-(
-set -x
-# Copy MySQL source and spec files
-
-#Sasha: I left the scp stuff commented out instead of deleted to make it
-#easy to revert in a hurry, if there is a need. Once everything is tested
-#and works perfectly, the scp stuff should be deleted to avoid confusion
-
-#scp $bpath/mysql-$VER.tar.gz $owner@$bmachine:$rpmdir/SOURCES
-copy_to_bmachine $tarball $rpmdir/SOURCES
-#scp $bpath/Docs/Images/mysql-logo.gif $owner@$bmachine:$rpmdir/SOURCES/mysql.gif
-copy_to_bmachine $bpath/Docs/Images/mysql-logo.gif $rpmdir/SOURCES/mysql.gif
-#scp $bpath/support-files/mysql-$VER.spec $owner@$bmachine:$rpmdir/SPECS
-copy_to_bmachine $bpath/support-files/mysql-$VER.spec $rpmdir/SPECS
-
-# Copy perl things. Has to be uncompressed since Compress.pm is not
-# installed yet. Set CEXT to .gz when we support compression.
-CEXT=
-#scp $bpath/Perl-mysql-modules/To-SOURCES/* $owner@$bmachine:$rpmdir/SOURCES
-
-# This had to be installed on the target machince!
-# http://www.perl.com/CPAN/modules/by-module/Archive/Archive-Tar-0.21.tar.gz
-# cd /usr/lib/perl5/site_perl/5.005; ln -s ../* .; rm -f 5.005
-
-TMP_SCRIPT_MYSQL=00-temp-for-do-rpm.$$
-cat > $logdir/$TMP_SCRIPT_MYSQL <<END
-set -x
-
-# Check environment
-#export MYSQL_BUILD_PATH="/usr/local/bin:/my/gnu/bin:/usr/bin:/bin"
-#export MYSQL_BUILD_CFLAGS="-O6 -fno-omit-frame-pointer -mcpu=pentiumpro"
-#export MYSQL_BUILD_CXXFLAGS="-O6 -fno-omit-frame-pointer \
-# -felide-constructors -fno-exceptions -fno-rtti -mcpu=pentiumpro"
-export MYSQL_BUILD_PATH="/usr/bin:/bin"
-export MYSQL_BUILD_CFLAGS="-O6 -fno-omit-frame-pointer -mpentium"
-export MYSQL_BUILD_CXXFLAGS="-O6 -fno-omit-frame-pointer \
- -felide-constructors -fno-exceptions -fno-rtti -mpentium"
-gcc -v
-
-# Make RPM
-rpm -ba $rpmdir/SPECS/mysql-$VER.spec
-rm -f /tmp/$TMP_SCRIPT_MYSQL
-END
-
-if [ ! x$skip_perl=x1 ]; then
-
- TMP_SCRIPT_PERL=00-temp-for-perl-rpm.$$
- cat > $logdir/$TMP_SCRIPT_PERL <<END
- set -x
-
- # First clean up so we do not get old versions when wildcard matching
- rm -f $rpmdir/SOURCES/DBI-*.spec
- rm -f $rpmdir/RPMS/i386/Perl-*.rpm
- rm -f $rpmdir/SRPMS/Perl-*.rpm
- rm -f $rpmdir/RPMS/i386/MySQL*-$VER_NO_DASH*.rpm
- rm -f $rpmdir/SRPMS/MySQL*-$VER_NO_DASH*.rpm
-
- chmod a+x ${MAKERPM}
- rm
-
- ${MAKERPM} --verbose --package-name=DBI --package-version ${DBI_VERSION} \
- --specs --source=DBI-${DBI_VERSION}.tar$CEXT
-
- rpm -ba $rpmdir/SPECS/DBI-${DBI_VERSION}.spec
-
- ${MAKERPM} --verbose --package-name=Data-ShowTable \
- --package-version ${DATA_SHOWTABLE_VERSION} \
- --specs --source=Data-ShowTable-${DATA_SHOWTABLE_VERSION}.tar$CEXT
-
- rpm -ba $rpmdir/SPECS/Data-ShowTable-${DATA_SHOWTABLE_VERSION}.spec
-
- for v in ${DBD_MYSQL_VERSION}; do
- ${MAKERPM}
- --specs \
- --source=Msql-Mysql-modules-$v.tar$CEXT \
- --setup-dir=Msql-Mysql-modules-$v \
- --package-name=DBD-mysql \
- --package-version=$v \
- --makemakeropts='--noprompt --mysql-install --mysql-install-nodbd \
- --nomsql-install --nomsql1-install' \
- --require=perl-Data-ShowTable --require=perl-DBI
- rpm -ba $rpmdir/SPECS/DBD-mysql-$v.spec
- done
-
- for srcrpm in $rpmdir/SRPMS/perl-*.src.rpm
- do
- rpm --rebuild $srcrpm
- done
-
- rm -f /tmp/$TMP_SCRIPT_PERL
-END
-fi
-
- # scp $bpath/Logs/$TMP_SCRIPT_MYSQL $owner@$bmachine:/tmp/$TMP_SCRIPT_MYSQL
-
-# ssh $bmachine -l $owner bash $bpath/Logs/$TMP_SCRIPT_MYSQL
-
-cmd=$logdir/$TMP_SCRIPT_MYSQL
-run_command $cmd
-
-if [ $? != 0 ]; then
- echo "$cmd failed, perhaps the following will help figure out why:"
- tail $log
-fi
-
-if [ x$local_build != x1 ]; then
-
- # Build perl RPM (we currently need to be root to do this and that is
- # not possible)
-
- #scp $bpath/Logs/$TMP_SCRIPT_PERL $owner@$bmachine:/tmp/$TMP_SCRIPT_PERL
- #ssh $bmachine -l root bash /tmp/$TMP_SCRIPT_PERL
-
- # Copy RPMs back to the source dir. We must do this here since the
- # $bmachine may not have permission to access $smachine.
- scp $owner@$bmachine:$rpmdir/RPMS/i386/MySQL*-$VER_NO_DASH*.rpm $bpath/NEW-RPMS
- scp $owner@$bmachine:$rpmdir/SRPMS/MySQL*-$VER_NO_DASH*.rpm $bpath/NEW-RPMS
-
- # And the perl ones
- #scp $owner@$bmachine:$rpmdir/RPMS/i386/Perl*-*.rpm $bpath/NEW-RPMS
- #scp $owner@$bmachine:$rpmdir/SRPMS/Perl*-*.rpm $bpath/NEW-RPMS
-fi
-) > $log 2>&1
+#
+# Set environment variables - these are being used in the
+# official MySQL RPM spec file
+#
+&logger("Setting special build environment variables")
+if ($opt_cc) or ($opt_cflags) or ($opt_cxxflags) or ($opt_cxx);
+$ENV{MYSQL_BUILD_CC}=$opt_cc if ($opt_cc);
+$ENV{MYSQL_BUILD_CFLAGS}=$opt_cflags if ($opt_cflags);
+$ENV{MYSQL_BUILD_CXXFLAGS}=$opt_cxxflags if ($opt_cxxflags);
+$ENV{MYSQL_BUILD_CXX}=$opt_cxx if ($opt_cxx);
+
+#
+# Build the RPMs
+#
+$command= "$RPM";
+$command.= " -v" if ($opt_verbose);
+$command.= " -ba";
+$command.= " --clean $RMSOURCE" if $opt_clean;
+$command.= " $SPECDIR/";
+$command.= basename($SPECFILE);
+&logger("Building RPM.");
+&run_command($command, "Error while building the RPMs!");
+
+#
+# Move the resulting RPMs into the pwd
+#
+$command= "mv";
+$command.= " -v " if ($opt_verbose);
+$command.= " $SRCRPMDIR/MySQL*$VERSION*.src.rpm $PWD";
+&logger("Moving source RPM to current dir.");
+&run_command($command, "Error moving source RPM!");
+
+$command= "mv";
+$command.= " -v " if ($opt_verbose);
+$command.= " $RPMDIR/$RPMARCH/MySQL*$VERSION*.$RPMARCH.rpm $PWD";
+&logger("Moving binary RPMs to current dir.");
+&run_command($command, "Error moving binary RPMs!");
+
+&logger("SUCCESS: RPM files successfully created.") unless ($opt_dry_run);
+exit 0;
+
+sub print_help
+{
+ my $message= $_[0];
+ if ($message ne "")
+ {
+ print "\n";
+ print "ERROR: $message\n\n}";
+ }
+ print <<EOF;
+
+Usage: Do-rpm [options] <specfile>
+
+Creates a binary RPM package out of a MySQL source distribution and moves
+the resulting RPMs into the current directory. <specfile> is the MySQL RPM
+spec file to use (e.g. mysql-4.0.17.spec).
+
+This script expects to find the required MySQL source distribution
+(mysql-<version>.tar.gz) in the current directory.
+
+Options:
+
+ --cc=<compiler> Use <compiler> to compile C code
+ --ccflags=<flags> Use special C compiler flags
+ --cxx=<compiler> Use <compiler> to compile C++ code
+ --cxxflags=<flags> Use special C++ compiler flags
+-c, --clean Clean up after the build
+-t, --dry-run Dry run without executing
+-h, --help Print this help
+-l, --log[=<filename>] Write a log file [to <filename>]
+ (default is "$LOGFILE")
+-m, --mail=<address> Mail a failure report to the given address
+ (and include a log file snippet, if logging
+ is enabled)
+ Note that the \@-Sign needs to be quoted!
+ Example: --mail=user\\\@domain.com
+-v, --verbose Verbose execution
+
+Example:
+
+ Do-rpm -cv mysql-4.0.17.spec
+
+EOF
+ exit 1;
+}
diff --git a/Build-tools/Do-win-build b/Build-tools/Do-win-build
new file mode 100755
index 00000000000..b446ba6f601
--- /dev/null
+++ b/Build-tools/Do-win-build
@@ -0,0 +1,82 @@
+#!/usr/bin/perl -w
+
+use Getopt::Long;
+
+$opt_help=0;
+$opt_tarball=$opt_builddir="";
+
+GetOptions(
+ "help",
+ "tarball=s",
+ "builddir=s",
+) || print_help();
+
+print_help() if ($opt_help);
+
+chomp($MSDEV=`which msdev`);
+
+if (!$opt_builddir) {
+ $opt_builddir = "/cygdrive/c/mysql-win-build";
+}
+
+$opt_tarball =~ /(mysql[^\/]*)-win-src\.tar/;
+$mysqlver=$1;
+$basedir = "$opt_builddir/$mysqlver";
+
+# Make sure build dir exists
+mkdir($opt_builddir);
+# Clean out any previous build
+system("rm -rf $basedir");
+mkdir($basedir);
+mkdir("$basedir/tarball");
+
+system("cp $opt_tarball $basedir/tarball");
+
+if (!chdir($basedir))
+{
+ print "Do-win-build error: Could not change to $opt_builddir";
+ exit 1;
+}
+
+mkdir("build");
+chdir("build");
+
+system("tar -zxvf ../tarball/$mysqlver-win-src.tar.gz");
+
+chdir($mysqlver);
+
+system("\"$MSDEV\" mysql.dsw /MAKE \"ALL\" /OUT $mysqlver-build.log");
+
+#
+# Print a help text message
+#
+sub print_help
+{
+ print <<EOF;
+Usage: Do-compile-win [options] source-tarball
+
+Unpacks a Windows source distribution on the local machine and
+compiles it using VC++ 6.0.
+
+This script is intended for Cygwin Perl. You must have a working
+MSDEV.EXE in your path for compilation.
+
+
+Options:
+
+--help
+Print this text.
+
+--builddir=<dir>
+Set the Cygwin path to build under; the tarball will actually
+be moved to <builddir>/mysql-<version>/tarball and extracted under
+<builddir>/mysql-<version>/build.
+Default: /cygdrive/c/mysql-win-build
+
+--tarball=<file>
+Windows source tarball to use for this build. Must be of the form
+mysql[com]-x.x.x-win-src.tar.gz (REQUIRED)
+
+EOF
+ exit 1;
+}
diff --git a/Build-tools/logger.pm b/Build-tools/logger.pm
new file mode 100644
index 00000000000..835d8014aa0
--- /dev/null
+++ b/Build-tools/logger.pm
@@ -0,0 +1,105 @@
+# Helper functions
+
+#
+# Create a log entry
+#
+sub logger
+{
+ my $message=$_[0];
+ print timestamp() . " " . $message . "\n" if $opt_verbose;
+ if (defined $opt_log && !$opt_dry_run)
+ {
+ open LOG, ">>$LOGFILE" or die "Can't open logfile $LOGFILE!";
+ print LOG timestamp() . " " . $message . "\n";
+ close LOG;
+ }
+}
+
+#
+# run_command(<command>,<error message>)
+# Execute the given command or die with the respective error message
+# Just print out the command when doing a dry run
+#
+sub run_command
+{
+ my $command= $_[0];
+ my $errormsg= $_[1];
+ if ($opt_dry_run)
+ {
+ print "$command\n";
+ }
+ else
+ {
+ &logger($command);
+ $command.= " >> $LOGFILE 2>&1" if defined $opt_log;
+ $command.= " > /dev/null" if (!$opt_verbose && !$opt_log);
+ system($command) == 0 or &abort("$errormsg\n");
+ }
+}
+
+#
+# abort(<message>)
+# Exit with giving out the given error message or by sending
+# it via email to the given mail address (including a log file snippet,
+# if available)
+#
+sub abort
+{
+ my $message= $_[0];
+ my $messagefile;
+ $message= "ERROR: " . $message;
+ &logger($message);
+
+ if ($opt_mail && !$opt_dry_run)
+ {
+ $messagefile= "/tmp/message.$$";
+ open(TMP,">$messagefile");
+ print TMP "$message\n\n";
+ close TMP;
+ if (defined $opt_log)
+ {
+ system("tail -n 40 $LOGFILE >> $messagefile");
+ }
+ system("mail -s \"$subject\" $opt_mail < $messagefile");
+ unlink($messagefile);
+ }
+
+ exit 1;
+}
+
+# Create a time stamp for logging purposes
+sub timestamp
+{
+ return &ymd() . " " . &hms();
+}
+
+#
+# return the current time as a string (HH:MM:SS)
+#
+sub hms
+{
+ my @ta= localtime(time());
+ my $h= $ta[2];
+ $h= "0" . "$h" if ($h <= 9);
+ my $m= $ta[1];
+ $m= "0" . "$m" if ($m <= 9);
+ my $s= $ta[0];
+ $s="0" . "$s" if ($s <= 9);
+
+ return "$h:$m:$s";
+}
+
+#
+# return the current date as a string (YYYYMMDD)
+#
+sub ymd
+{
+ my @ta=localtime(time());
+ my $d=$ta[3];
+ $d="0" . "$d" if ($d <= 9);
+ my $m=$ta[4]+1;
+ $m="0" . "$m" if ($m <= 9);
+ my $y=1900+$ta[5];
+
+ return "$y$m$d";
+}
diff --git a/Docs/Flags/argentina.eps b/Docs/Flags/argentina.eps
index 840e24188ad..c0a9dae067e 100644
--- a/Docs/Flags/argentina.eps
+++ b/Docs/Flags/argentina.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: argentina.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-676767676767676767676767676767676767676767676767676767676767
-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
-f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2
-f7f7f7f7f7f7f7f7f7f7f7f7f7f8f9f9f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f5f3f2f6f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7e6cdc5eef7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f8fafdfdfaf7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f5f0f2f2f1f6f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7e79441419eebf7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f9fdf3eefdf8f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f3f3eee9f1f3f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7c93f00004fd5f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f9fde9edfdf8f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f2f3e4eaf2f3f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7c43e00014ed0f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7fafdfdfaf7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f6f1f1f2f1f6f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7ec9b4c4ca4f1f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f8f9f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f5f3f2f6f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7e9d5cdf1f7f7f7f7f7f7f7f7f7f7f7f7f7
-585858585858585858585858585858585858585858585858585858585858
-c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00001818181818181818181818181818181818
+181818181818181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefef
+efefefefefefefefefefefefefefefefef00001818181818181818181818
+181818181818181818181818181818181818180000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefef
+efefefefefefefefefefefefefefefefefefefefefefef00001818181818
+181818181818181818181818181818181818181818181818180000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00006161616161616161616161616161616161
+616161616161616161616161610000cacacacacacacacacacacacacacaca
+cacacacacacacacacacacacacacaca0000f2f2f2f2f2f2f2f2f2f2f2f2f2
+f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f20000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f9f9f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f6f3f3f6f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7eccbccecf7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7fafdfdfaf7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f6f0f2f2f0f6f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7ec9b45459becf7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f9fdf2eefdf9f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f3f2ede9f2f3f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7cb45000045cbf7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f9fdebeafdf9f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f3f2e7e7f2f3f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7cb45000045cbf7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7fafdfdfa
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f6f1f2
+f2f1f6f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7ec
+9b45459becf7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f9f9f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f6f3f3f6f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7eccbcbecf7f7f7f7f7f7f7f7f7f7f7f7f700006363636363
+636363636363636363636363636363636363636363636363630000cbcbcb
+cbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb0000f2
+f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f200
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00001818181818181818181818181818181818
+181818181818181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefef
+efefefefefefefefefefefefefefefefef00001818181818181818181818
+181818181818181818181818181818181818180000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefef
+efefefefefefefefefefefefefefefefefefefefefefef00001818181818
+181818181818181818181818181818181818181818181818180000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/argentina.gif b/Docs/Flags/argentina.gif
index 8fef5c3f455..b1bba9778cc 100644
--- a/Docs/Flags/argentina.gif
+++ b/Docs/Flags/argentina.gif
Binary files differ
diff --git a/Docs/Flags/argentina.pdf b/Docs/Flags/argentina.pdf
new file mode 100644
index 00000000000..4ccb26eec76
--- /dev/null
+++ b/Docs/Flags/argentina.pdf
Binary files differ
diff --git a/Docs/Flags/armenia.eps b/Docs/Flags/armenia.eps
new file mode 100644
index 00000000000..dad5ef59c31
--- /dev/null
+++ b/Docs/Flags/armenia.eps
@@ -0,0 +1,256 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Creator: Adobe Photoshop Version 5.5
+%%Title: armenia.eps
+%%CreationDate: Sun Mar 24 2002 12:12:59
+%%BoundingBox: 0 0 32 22
+%%HiResBoundingBox: 0 0 32 22
+%%SuppressDotGainCompensation
+%%EndComments
+%%BeginProlog
+%%EndProlog
+%%BeginSetup
+%%EndSetup
+%ImageData: 32 22 8 3 1 32 2 "beginimage"
+%BeginPhotoshop: 1288
+% 3842494D03ED000000000010004800000001000200480000000100023842494D
+% 040D000000000004000000783842494D03F30000000000080000000000000000
+% 3842494D040A00000000000100003842494D271000000000000A000100000000
+% 000000023842494D03F5000000000048002F66660001006C6666000600000000
+% 0001002F6666000100A1999A0006000000000001003200000001005A00000006
+% 000000000001003500000001002D000000060000000000013842494D03F80000
+% 000000700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E80000
+% 0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFF
+% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFFFFFF
+% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800003842494D0408000000000010
+% 000000010000024000000240000000003842494D041400000000000400000001
+% 3842494D040C0000000003890000000100000020000000160000006000000840
+% 0000036D00180001FFD8FFE000104A46494600010201004800480000FFEE000E
+% 41646F626500648000000001FFDB0084000C08080809080C09090C110B0A0B11
+% 150F0C0C0F1518131315131318110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C
+% 0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C010D0B0B0D0E0D100E0E10140E0E0E
+% 14140E0E0E0E14110C0C0C0C0C11110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C
+% 0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC0001108001600200301220002
+% 1101031101FFDD00040002FFC4013F0000010501010101010100000000000000
+% 030001020405060708090A0B0100010501010101010100000000000000010002
+% 030405060708090A0B1000010401030204020507060805030C33010002110304
+% 211231054151611322718132061491A1B14223241552C16233347282D1430725
+% 9253F0E1F163733516A2B283264493546445C2A3743617D255E265F2B384C3D3
+% 75E3F3462794A485B495C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F637
+% 475767778797A7B7C7D7E7F71100020201020404030405060707060535010002
+% 1103213112044151617122130532819114A1B14223C152D1F0332462E1728292
+% 435315637334F1250616A2B283072635C2D2449354A317644555367465E2F2B3
+% 84C3D375E3F34694A485B495C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6
+% F62737475767778797A7B7C7FFDA000C03010002110311003F00E171D98271EA
+% 2E6D5BB6377486CCC7744F4FA7FEED3F73558C3FA9BF59327128C8A70F7D5756
+% CB2B77A95096B9A1EC743AD0EFA251BFE637D69FFB85FF0082D3FF00A554E395
+% F841172F8AE18C8FCD139F07A65D63FCE3AB1F8AE58C40FB9C0D002F865AFF00
+% CD68FA7D3FF769FB9A8790CC118F696B6ADDB1DB6036663B2D2FF98DF5A7FEE1
+% 7FE0B4FF00E9541CCFA9BF5931B12FC8BB0F6554D6FB2C77A95186B5A5EF7436
+% D2EFA2123CAFC200B8FC570CA43E588CF83D52E91FE7152F8AE59448FB9C0582
+% 2F865A7FCD7FFFD0D2E81D47319D0BA731BD2F2AC6B716802C6BB1435C056CF7
+% B7D4CC659B5DFCB62BFF00B533BFF2A333FCFC4FFDEE5E1292E1737B7EEE4FE6
+% BE797FE28FDE74E37C23E6DBFA8FBB7ED4CEFF00CA8CCFF3F13FF7B950EBFD47
+% 31FD0BA8B1DD2F2AB6BB16F06C73B14B5A0D6FF7BBD3CC7D9B5BFC862F18492C
+% 3EDFBB8FF9AF9E3FF8A3F7952BE13F36DFD47FFFD9003842494D03FD00000000
+% 0006000000000000
+%EndPhotoshop
+gsave % EPS gsave
+/hascolor
+/deviceinfo where
+{pop deviceinfo /Colors known
+{deviceinfo /Colors get exec 1 gt}
+{false} ifelse}
+{/statusdict where
+{pop statusdict /processcolors known
+{statusdict /processcolors get exec 1 gt}
+{false} ifelse}
+{false} ifelse}
+ifelse
+def
+40 dict begin
+/_image systemdict /image get def
+/_setgray systemdict /setgray get def
+/_currentgray systemdict /currentgray get def
+/_settransfer systemdict /settransfer get def
+/_currenttransfer systemdict /currenttransfer get def
+/blank 0 _currenttransfer exec
+1 _currenttransfer exec eq def
+/negative blank
+{0 _currenttransfer exec 0.5 lt}
+{0 _currenttransfer exec 1 _currenttransfer exec gt}
+ifelse def
+/inverted? negative def
+/level2 systemdict /languagelevel known
+{languagelevel 2 ge} {false} ifelse def
+/level3 systemdict /languagelevel known
+{languagelevel 3 ge} {false} ifelse def
+/foureq {4 index eq 8 1 roll
+4 index eq 8 1 roll
+4 index eq 8 1 roll
+4 index eq 8 1 roll
+pop pop pop pop and and and} def
+hascolor {/band 0 def} {/band 5 def} ifelse
+/setcmykcolor where {pop
+1 0 0 0 setcmykcolor _currentgray 1 exch sub
+0 1 0 0 setcmykcolor _currentgray 1 exch sub
+0 0 1 0 setcmykcolor _currentgray 1 exch sub
+0 0 0 1 setcmykcolor _currentgray 1 exch sub
+4 {4 copy} repeat
+1 0 0 0 foureq {/band 1 store} if
+0 1 0 0 foureq {/band 2 store} if
+0 0 1 0 foureq {/band 3 store} if
+0 0 0 1 foureq {/band 4 store} if
+0 0 0 0 foureq {/band 6 store} if} if
+blank {/band 6 store} if
+gsave % Image Header gsave
+/rows 22 def
+/cols 32 def
+32 22 scale
+level2 {
+band 0 eq {
+/DeviceRGB
+} {/DeviceGray} ifelse
+setcolorspace currentdict /PhotoshopDuotoneColorSpace undef currentdict /PhotoshopDuotoneAltColorSpace undef } if
+/picstr1 32 string def
+/picstr2 32 string def
+/picstr3 32 string def
+/picstr4 32 string def
+/readdata {currentfile exch readhexstring pop} def
+/image2 level2 {/image load def} {{begin
+Width Height BitsPerComponent ImageMatrix
+Decode length 2 eq
+{/DataSource load image} if
+Decode length 6 eq
+{DataSource 0 get DataSource 1 get DataSource 2 get
+true 3 colorimage} if
+Decode length 8 eq
+{DataSource 0 get DataSource 1 get
+DataSource 2 get DataSource 3 get
+true 4 colorimage} if
+end} def} ifelse
+/_image2 level2 {/_image load def} {{begin
+Width Height BitsPerComponent ImageMatrix
+/DataSource load _image end} def} ifelse
+/beginimage {
+band 0 eq band 4 eq or band 5 eq or
+{image2}
+{negative {{pop 0}} {{pop 1}} ifelse
+_settransfer _image2} ifelse
+} def
+12 dict begin
+/ImageType 1 def
+/Width cols def
+/Height rows def
+/ImageMatrix [cols 0 0 rows neg 0 rows] def
+/BitsPerComponent 8 def
+band 0 eq
+{/Decode [0 1 0 1 0 1] def
+/MultipleDataSources true def
+/DataSource [
+{picstr1 readdata}
+{picstr2 readdata}
+{picstr3 readdata picstr4 readdata pop}
+] def}
+{/Decode [0 1] def
+/DataSource {
+picstr1 readdata pop
+picstr2 readdata pop
+picstr3 readdata pop
+picstr4 readdata
+} def}
+ifelse
+currentdict end
+%%BeginBinary: 5821
+beginimage
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+0008080808080808080808080808080808080808080808080808080808080800
+0000000000000000000000000000000000000000000000000000000000000000
+00B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
+0016161616161616161616161616161616161616161616161616161616161600
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D6D600
+0000000000000000000000000000000000000000000000000000000000000000
+00CBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCB00
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+
+%%EndBinary
+grestore end % Image Trailer grestore
+grestore % EPS grestore
diff --git a/Docs/Flags/armenia.gif b/Docs/Flags/armenia.gif
new file mode 100755
index 00000000000..6bd3b861015
--- /dev/null
+++ b/Docs/Flags/armenia.gif
Binary files differ
diff --git a/Docs/Flags/island.eps b/Docs/Flags/armenia.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/island.eps
+++ b/Docs/Flags/armenia.txt
diff --git a/Docs/Flags/australia.eps b/Docs/Flags/australia.eps
index f98c03e2c83..9f772787ae7 100644
--- a/Docs/Flags/australia.eps
+++ b/Docs/Flags/australia.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: australia.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-cf7b0e0808087cc6730808081084c4080808080808080808080808080808
-3f5c0600000050005300000009603a000000000000000000000000000000
-43b5b6b5b5b5a600b1b5b5b5b7b246b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-b1d2b73608087cc67308083dbcd3a5080808080808080809080808080808
-8d3e612f00005000530000355e4285000000000000000001000000000000
-bc3e82c0b5b5a600b1b5b5c17a43bfb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-096bd4cf7b0e7cc6731083d0d36108080808080808084d990c0808080808
-0162753f5c06500053095f3c7b5b00000000000000004796040000000000
-b5cd7e43b5b7a600b1b7b13e87ccb5b5b5b5b5b5b5b5c8ddb6b5b5b5b5b5
-0c0c2bb5d3b8a3c6a2bcd3ae250c0c080808080808087bba170808080808
-040424913e6478008061438f1e04040000000000000077b70f0000000000
-b6b6bfbd3f85b000bc7d43c1bdb6b6b5b5b5b5b5b5b5d5e6b9b5b5b5b5b5
-d5d5d5d5d5d5d2c6d3d5d5d5d5d5c9080808080808080d0d080808080808
-4c4c4c4c4c4a3c00414a4c4c4c4c48000000000000000505000000000000
-4c4c4c4c4c4a3c00414a4c4c4c4c52b5b5b5b5b5b5b5b6b6b5b5b5b5b5b5
-d3d3d3d4d7d6d4c6d4d6d7d4d3d3c7080808080808080808080808080808
-51515152545044004950555251514c000000000000000000000000000000
-55555555545044004950555555555bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0a0a2fb9d2b19fc69db7d2b3290a0a080808080808080808080808080808
-0202288f3a6374007c613e8e220202000000000000000000000000000000
-b5b5c0b73b8aaf00bb823ebcbeb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0b74d6ce720b7cc6730e7bcfd46b0908080808080808080808080c080808
-036b6f435703500053065c3f756201000000000000000000000004000000
-b6cd7649b8b6a600b1b7b5437ecdb5b5b5b5b5b5b5b5b5b5b5b5b6b5b5b5
-b9d2b12f08087cc673080836b7d2ab080808110808080808080eac520808
-8f3a6328000050005300002f613e870000000a00000000000006a94d0000
-b73a8abfb5b5a600b1b5b5c0823ebab5b5b5b8b5b5b5b5b5b5b6e2cab5b5
-c7720b08080877bf6f0808080e7abd080819c757080808080819ae6f0808
-3c57030000004d004f000000065b37000011c552000000000012ac6a0000
-47b8b6b5b5b5a607b1b5b5b5b7b54ab5b5baeacbb5b5b5b5b5bae3d1b5b5
-08080808080808080808080808080808081c9e50080808080f080a0a0808
-0000000000000000000000000000000000149a4a00000000070002020000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5badec9b5b5b5b5b7b5b6b5b5b5
-0808080808080808080808080808080808080808080808119a0b08080808
-000000000000000000000000000000000000000000000009960300000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b7ddb6b5b5b5b5
-0808080808080808080808080808080808080808080808080c0808080808
-000000000000000000000000000000000000000000000000040000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b6b5b5b5b5b5
-080808080808080c08080808080808080808080808080808080808080808
-000000000000000400000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080809439144090808080808080808080808080808080808080808
-0000000000013d8e3d010000000000000000000000000000000000000000
-b5b5b5b5b5b5c5dbc5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080809b0f7b1090808080808080808080808081308080808080808
-000000000001adf7af010000000000000000000000000c00000000000000
-b5b5b5b5b5b5e3f7e4b5b5b5b5b5b5b5b5b5b5b5b5b5b8b5b5b5b5b5b5b5
-08080808081c8eed8f1d08080808080808080808083ccc3a080808080808
-0000000000158aed8c15000000000000000000000035cb34000000000000
-b5b5b5b5b5bbdaf4dabbb5b5b5b5b5b5b5b5b5b5b5c3ebc3b5b5b5b5b5b5
-0808080808082c1b2c08080808080808080808080827af26080808080808
-0000000000002513250000000000000000000000001fac1e000000000000
-b5b5b5b5b5b5bfbabfb5b5b5b5b5b5b5b5b5b5b5b5bde3bdb5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000000000000000000000000000000000000000000000
+00000000000000cf7c0e08080877c67a0808080e7ccf0808080808080808
+0808080808080800003f5d06000000500053000000065e3f000000000000
+000000000000000000000043b5b7b5b5b5ab00acb5b5b5b7b543b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000b3d2b737080877c67a080837b7d2b30808
+0808080808080908080808080800008e3d622f000050005300002f623d8e
+0000000000000000010000000000000000bc3d82c0b5b5ab00acb5b5c082
+3dbcb5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000096cd5cf7c0e77c67a0e7c
+cfd56c0908080808080808419c12080808080800000164753f5d06500053
+065d3f756401000000000000003b990b00000000000000b5cd7e43b5b7ab
+00acb7b5437ecdb5b5b5b5b5b5b5b5c5deb8b5b5b5b5b50000080828b3d2
+b7a0c6a2b7d2b32808080808080808080868c91f08080808080000000021
+8e3d6279007c623d8e2100000000000000000063c81800000000000000b5
+b5bebc3d82b500b5823dbcbeb5b5b5b5b5b5b5b5b5cfeabbb5b5b5b5b500
+00d6d6d6d6d6d5d3c6d3d5d6d6d6d6d6080808080808080e0e0808080808
+080000505050504f4d4200424d4f50505050000000000000000606000000
+0000000000505050504f4d4200424d4f50505050b5b5b5b5b5b5b5b7b7b5
+b5b5b5b5b50000d6d6d6d6d6d6d3c6d3d6d6d6d6d6d60808080808080808
+080808080808080000505050505050420042505050505050000000000000
+0000000000000000000000505050505050420042505050505050b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000b0b2bb5d2b7a0c6a2b7d2b52b0b0b0808
+080808080808080808080808080000030324913d6179007c623d91240303
+0000000000000000000000000000000000b6b6bfbd3d82b500b5823dbdbf
+b6b6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000096dd5cf7b0e77c67a0e7c
+cfd56c0908080808080808080808080a08080800000165753f5c06500053
+065d3f7564010000000000000000000000030000000000b5cd7e43b5b7ab
+00acb7b5437ecdb5b5b5b5b5b5b5b5b5b5b5b5b6b5b5b50000b3d2b73608
+0877c67a080837b7d2b30808080f080808080808099861080800008f3d61
+2e000050005300002f623d8e0000000800000000000001955b00000000bc
+3d82c0b5b5ab00acb5b5c0823dbcb5b5b5b7b5b5b5b5b5b5b5ddcdb5b500
+00cf7a0e08080877c67a0808080e7bcf08080fbd5d080808080812a98708
+0800003f5b06000000500053000000065c3f000008bb5800000000000aa6
+830000000042b5b7b5b5b5ab00acb5b5b5b6b543b5b5b7e7ccb5b5b5b5b5
+b8e1d8b5b500000808080808080808080808080808080808199e64080808
+080d080b0b080800000000000000000000000000000000000000129b5f00
+0000000500030300000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5badf
+ceb5b5b5b5b6b5b6b6b5b500000808080808080808080808080808080808
+0808080808080c9a0f080808080000000000000000000000000000000000
+0000000000000000049607000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b6ddb7b5b5b5b500000808080808080808080808
+080808080808080808080808081008080808080000000000000000000000
+0000000000000000000000000000000800000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b7b5b5b5b5b500000808080808
+08080a080808080808080808080808080808080808080808080000000000
+0000000003000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808083886380a08080808080808080808080808080808080808
+080000000000000000328231020000000000000000000000000000000000
+0000000000b5b5b5b5b5b5c2d8c2b6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b50000080808080808a7f7b70808080808080808080808080810
+080808080808080000000000000000a4f7b5000000000000000000000000
+0008000000000000000000b5b5b5b5b5b5e1f7e5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b7b5b5b5b5b5b5b5000008080808081b95f39e2108080808080808
+0808080827c242080808080808000000000000001491f39b1a0000000000
+00000000000020c03c0000000000000000b5b5b5b5b5badcf6dfbcb5b5b5
+b5b5b5b5b5b5b5b5bde8c5b5b5b5b5b5b500000808080808082f25340808
+0808080808080808080825b63f0808080808080000000000000000281e2e
+0000000000000000000000001eb3390000000000000000b5b5b5b5b5b5c0
+bdc1b5b5b5b5b5b5b5b5b5b5b5b5bde5c4b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/australia.gif b/Docs/Flags/australia.gif
index 1f403f92503..6c766cbb614 100644
--- a/Docs/Flags/australia.gif
+++ b/Docs/Flags/australia.gif
Binary files differ
diff --git a/Docs/Flags/australia.pdf b/Docs/Flags/australia.pdf
new file mode 100644
index 00000000000..f7a1d0fd53d
--- /dev/null
+++ b/Docs/Flags/australia.pdf
Binary files differ
diff --git a/Docs/Flags/austria.eps b/Docs/Flags/austria.eps
index 7a0b56f3690..c6c35dc81e2 100644
--- a/Docs/Flags/austria.eps
+++ b/Docs/Flags/austria.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: austria.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d60000505050505050505050505050505050
+505050505050505050505050505050000050505050505050505050505050
+50505050505050505050505050505050500000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000d7d7d7d7d7
+d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d70000535353
+535353535353535353535353535353535353535353535353535353000054
+545454545454545454545454545454545454545454545454545454545400
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7
-575757575757575757575757575757575757575757575757575757575757
-575757575757575757575757575757575757575757575757575757575757
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4
-464646464646464646464646464646464646464646464646464646464646
-474747474747474747474747474747474747474747474747474747474747
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/austria.gif b/Docs/Flags/austria.gif
index d72b945741a..26a97856627 100644
--- a/Docs/Flags/austria.gif
+++ b/Docs/Flags/austria.gif
Binary files differ
diff --git a/Docs/Flags/austria.pdf b/Docs/Flags/austria.pdf
new file mode 100644
index 00000000000..d50b4f265cd
--- /dev/null
+++ b/Docs/Flags/austria.pdf
Binary files differ
diff --git a/Docs/Flags/belgium.eps b/Docs/Flags/belgium.eps
new file mode 100644
index 00000000000..d27fda0e1e1
--- /dev/null
+++ b/Docs/Flags/belgium.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: belgium.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000003ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6
+d6d6d6d6d600000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03d6d6d6d6d6d6d6d6d6d600000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003d6d6d6d6d6d6d6d6d6d600000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000003ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6
+d6d6d6d6d600000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03d6d6d6d6d6d6d6d6d6d600000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003d6d6d6d6d6d6d6d6d6d600000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000003ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6
+d6d6d6d6d600000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03d6d6d6d6d6d6d6d6d6d600000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003d6d6d6d6d6d6d6d6d6d600000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000003ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003d6d6d6d6d6
+d6d6d6d6d600000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000003ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03d6d6d6d6d6d6d6d6d6d600000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003d6d6d6d6d6d6d6d6d6d600000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000003ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003d6d6d6d6d6d6d6d6d6d600000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/belgium.gif b/Docs/Flags/belgium.gif
new file mode 100644
index 00000000000..2bb101dc501
--- /dev/null
+++ b/Docs/Flags/belgium.gif
Binary files differ
diff --git a/Docs/Flags/belgium.pdf b/Docs/Flags/belgium.pdf
new file mode 100644
index 00000000000..7696d4af102
--- /dev/null
+++ b/Docs/Flags/belgium.pdf
Binary files differ
diff --git a/Docs/Flags/island.gif b/Docs/Flags/belgium.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/island.gif
+++ b/Docs/Flags/belgium.txt
diff --git a/Docs/Flags/bulgaria.eps b/Docs/Flags/bulgaria.eps
index 6f4a07c616c..2eb04535d36 100644
--- a/Docs/Flags/bulgaria.eps
+++ b/Docs/Flags/bulgaria.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: bulgaria.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
-e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a70000e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2
+e2e2e2e2e2e2e2e2e2e2e2e2e2e2e20000a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a700000000000000000000000000
+000000000000000000000000000000000000000000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
+000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000000000000000000000000000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000
+000000000000000000000000000000000000000000000000008383838383
+8383838383838383838383838383838383838383838383838300003d3d3d
+3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d000000
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d
-333333333333333333333333333333333333333333333333333333333333
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/bulgaria.gif b/Docs/Flags/bulgaria.gif
index 35c0b117062..4c7377e907c 100644
--- a/Docs/Flags/bulgaria.gif
+++ b/Docs/Flags/bulgaria.gif
Binary files differ
diff --git a/Docs/Flags/bulgaria.pdf b/Docs/Flags/bulgaria.pdf
new file mode 100644
index 00000000000..24cb072598d
--- /dev/null
+++ b/Docs/Flags/bulgaria.pdf
Binary files differ
diff --git a/Docs/Flags/canada.eps b/Docs/Flags/canada.eps
index b770266de60..7773f12a699 100644
--- a/Docs/Flags/canada.eps
+++ b/Docs/Flags/canada.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: canada.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f6f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f3f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f3f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7e5ebf7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f79dbaf7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f79dbaf7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f6f5d0d6f4f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f2ed324fe9f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f2ed324fe9f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7d2c6c7d7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f73c000355f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f73c000356f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f1f7dac6c6e0f7f1f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7d7f764000081f6d9f7f7f76300000000000000
-0000000000000083f7f7f7d8f764000081f6d9f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7ede8d6d5e1c6c6e5d1dbe6f0f7dac6c6c6c6c6c6c6
-0000000000000083f7c4a951488a00009a3869a0d2f76300000000000000
-0000000000000083f7c4a952488a00009a386aa0d2f76300000000000000
-c6c6c6c6c6c6c6e0f7f3c7c6c6c7c6c6c7c6c6caf6f7dac6c6c6c6c6c6c6
-0000000000000083f7e106000003000002000014f0f76300000000000000
-0000000000000083f7e106000003000002000014f0f76300000000000000
-c6c6c6c6c6c6c6e0f7efcbc6c6c6c6c6c6c6c6cff1f7dac6c6c6c6c6c6c6
-0000000000000083f7cd1b00000000000000002bd9f76300000000000000
-0000000000000083f7cd1b00000000000000002bd9f76300000000000000
-c6c6c6c6c6c6c6e0f7f7eeddccc6c6c6c6cedff0f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7c87420000000002a7ed2f7f76300000000000000
-0000000000000083f7f7c87420000000002a7ed2f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7d7c6c7c7c6ddf7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7560003030072f7f7f7f76300000000000000
-0000000000000083f7f7f7f7560003030073f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f6f0f5e7edf4f0f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f2d6eaa8c4e8d4f6f7f7f76300000000000000
-0000000000000083f7f7f7f2d6eaa8c5e8d5f6f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7e6ecf7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7a3c0f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7a4c1f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7e6ebf7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f79fbcf7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f79fbcf7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f5f6f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7edf0f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7edf0f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-c6c6c6c6c6c6c6e0f7f7f7f7f7f7f7f7f7f7f7f7f7f7dac6c6c6c6c6c6c6
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
-0000000000000083f7f7f7f7f7f7f7f7f7f7f7f7f7f76300000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6def7f7f7f7f7f7f7f7f7f7f7f7f7f7de
+c6c6c6c6c6c6c60000000000000000007bf7f7f7f7f7f7f7f7f7f7f7f7f7
+f778000000000000000000000000000000007bf7f7f7f7f7f7f7f7f7f7f7
+f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7f7f7f7f7f7f7
+f7f7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7f7f7f7f7f7f7
+f7f7f7f7f7f7f778000000000000000000000000000000007bf7f7f7f7f7
+f7f7f7f7f7f7f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7
+f7f7f7f7f7f7f7f7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7
+f7f7f7f7f7f7f7f7f7f7f7f7f77800000000000000000000000000000000
+7bf7f7f7f7f7f7f7f7f7f7f7f7f7f779000000000000000000c6c6c6c6c6
+c6c6def7f7f7f7f7f7f7f7f7f7f7f7f7f7dec6c6c6c6c6c6c60000000000
+000000007bf7f7f7f7f7f7f5f5f7f7f7f7f7f77800000000000000000000
+0000000000007bf7f7f7f7f7f7f5f5f7f7f7f7f7f7790000000000000000
+00c6c6c6c6c6c6c6def7f7f7f7f7f7e8e8f7f7f7f7f7f7dec6c6c6c6c6c6
+c60000000000000000007bf7f7f7f7f7f7adadf7f7f7f7f7f77800000000
+0000000000000000000000007bf7f7f7f7f7f7adadf7f7f7f7f7f7790000
+00000000000000c6c6c6c6c6c6c6def7f7f7f7f7f5d3d3f5f7f7f7f7f7de
+c6c6c6c6c6c6c60000000000000000007bf7f7f7f7f5ec4242ecf5f7f7f7
+f778000000000000000000000000000000007bf7f7f7f7f5ec4242ecf5f7
+f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7f7f7d5c6c6d5
+f7f7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7f7f7f7f74a01
+014af7f7f7f7f778000000000000000000000000000000007bf7f7f7f7f7
+4a01014af7f7f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7
+f2f7dcc6c6dcf7f2f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7
+f7f7dcf76f00006ff7dcf7f7f77800000000000000000000000000000000
+7bf7f7f7dcf76f00006ff7dcf7f7f779000000000000000000c6c6c6c6c6
+c6c6def7eee9d9d5e4c6c6e4d5d9e9eef7dec6c6c6c6c6c6c60000000000
+000000007bf7caaf5e4995000095495eafcaf77800000000000000000000
+0000000000007bf7caaf5f4996000096495fafcaf7790000000000000000
+00c6c6c6c6c6c6c6def7f4c8c6c6c7c6c6c7c6c6c8f3f7dec6c6c6c6c6c6
+c60000000000000000007bf7e508000004000004000008e5f77800000000
+0000000000000000000000007bf7e508000004000004000008e5f7790000
+00000000000000c6c6c6c6c6c6c6def7f0cdc6c6c6c6c6c6c6c6cdf0f7de
+c6c6c6c6c6c6c60000000000000000007bf7d222000000000000000022d2
+f778000000000000000000000000000000007bf7d2220000000000000000
+22d2f779000000000000000000c6c6c6c6c6c6c6def7f7ecdccbc6c6c6c6
+cbdcecf7f7dec6c6c6c6c6c6c60000000000000000007bf7f6c16d1b0000
+00001b6dc0f6f778000000000000000000000000000000007bf7f6c16d1b
+000000001b6dc1f6f779000000000000000000c6c6c6c6c6c6c6def7f7f7
+f7dbc6c6c6c6dbf7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7
+f7f7f76b000000006bf7f7f7f77800000000000000000000000000000000
+7bf7f7f7f76b000000006bf7f7f7f779000000000000000000c6c6c6c6c6
+c6c6def7f7f7f7eef2e9e9f2eef6f7f7f7dec6c6c6c6c6c6c60000000000
+000000007bf7f7f7f4c8dcb0b0dcc8f4f7f7f77800000000000000000000
+0000000000007bf7f7f7f4c9dcb0b0dcc9f4f7f7f7790000000000000000
+00c6c6c6c6c6c6c6def7f7f7f7f7f7e9e9f7f7f7f7f7f7dec6c6c6c6c6c6
+c60000000000000000007bf7f7f7f7f7f7b2b2f7f7f7f7f7f77800000000
+0000000000000000000000007bf7f7f7f7f7f7b2b2f7f7f7f7f7f7790000
+00000000000000c6c6c6c6c6c6c6def7f7f7f7f7f7e9e9f7f7f7f7f7f7de
+c6c6c6c6c6c6c60000000000000000007bf7f7f7f7f7f7aeaef7f7f7f7f7
+f778000000000000000000000000000000007bf7f7f7f7f7f7aeaef7f7f7
+f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7f7f7f7f4f4f7
+f7f7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7f7f7f7f7f7ea
+e9f7f7f7f7f7f778000000000000000000000000000000007bf7f7f7f7f7
+f7eaeaf7f7f7f7f7f779000000000000000000c6c6c6c6c6c6c6def7f7f7
+f7f7f7f7f7f7f7f7f7f7f7dec6c6c6c6c6c6c60000000000000000007bf7
+f7f7f7f7f7f7f7f7f7f7f7f7f77800000000000000000000000000000000
+7bf7f7f7f7f7f7f7f7f7f7f7f7f7f779000000000000000000c6c6c6c6c6
+c6c6def7f7f7f7f7f7f7f7f7f7f7f7f7f7dec6c6c6c6c6c6c60000000000
+000000007bf7f7f7f7f7f7f7f7f7f7f7f7f7f77800000000000000000000
+0000000000007bf7f7f7f7f7f7f7f7f7f7f7f7f7f7790000000000000000
+00c6c6c6c6c6c6c6def7f7f7f7f7f7f7f7f7f7f7f7f7f7dec6c6c6c6c6c6
+c60000000000000000007bf7f7f7f7f7f7f7f7f7f7f7f7f7f77800000000
+0000000000000000000000007bf7f7f7f7f7f7f7f7f7f7f7f7f7f7790000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/canada.gif b/Docs/Flags/canada.gif
index 322d4b985b7..af672caf33d 100644
--- a/Docs/Flags/canada.gif
+++ b/Docs/Flags/canada.gif
Binary files differ
diff --git a/Docs/Flags/canada.pdf b/Docs/Flags/canada.pdf
new file mode 100644
index 00000000000..4ba0fd45ec6
--- /dev/null
+++ b/Docs/Flags/canada.pdf
Binary files differ
diff --git a/Docs/Flags/chile.eps b/Docs/Flags/chile.eps
index 8a5411a32a3..121bf0a51b3 100644
--- a/Docs/Flags/chile.eps
+++ b/Docs/Flags/chile.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: chile.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-08080808080808080811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000000000000000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808272008080811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000020190000000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5bebcb5b5b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808776e08080811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000073690000000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5d4d1b5b5b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808c7bd08080811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-00000000c5bb0000000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5eae7b5b5b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0868e3e9f7f6e9e16111f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0062e2e8f7f6e8e05b0af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5cff1f3f7f7f3f1cdb8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08083eddf7f7d9390811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-000038dcf7f7d833000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5c4f0f7f7efc3b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080808c1f7f7b8080811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-000000bff7f7b500000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5e8f7f7e5b5b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08081fe86066e8190811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-000018e85b61e711000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5bbf3cdcff3bab5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08083a2808082c360811f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-000033210000262f000af7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5c3beb5b5bfc2b5b8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0e0e0e0e0e0e0e0e0e17f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-00000000000000000009f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-b0b0b0b0b0b0b0b0b0b3f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+0000000000000008080808080808080808f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7000000000000000000000000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000b5b5b5b5b5b5b5b5b5b5f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7000008080808232408080808f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000000000001c1c00000000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5b5bcbdb5b5b5b5f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000008080808727208080808f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000000006d6d000000
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5b5d2d2b5
+b5b5b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000008080808c2
+c208080808f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000000
+00c0c000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5
+b5b5b5e8e8b5b5b5b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+000866dfe5f6f6e5e06708f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f700000062dee4f6f6e4de6200f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000b5cff0f2f7f7f2f0cfb5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000080841def7f7de410808f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7000000003bddf7f7dd3b0000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000b5b5c5f0f7f7f0c5b5b5f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000080808bcf7f7bc080808f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000000000baf7f7ba000000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5e7f7f7e7b5b5b5f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000008081beb6969eb1c0808f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000014ea6565ea1400
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5baf4d0d0f4
+bab5b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000008083b2f08
+082e3b0808f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000034
+28000028340000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5
+b5c3c0b5b5c0c3b5b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+0008080808080808080808f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7000000000000000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000b5b5b5b5b5b5b5b5b5b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000c4c4c4c4c4c4c4c4c4c4c7c7c7c7c7c7c7c7c7c7c7c7c7
+c7c7c7c7c7c7c70000000000000000000000000303030303030303030303
+030303030303030303000002020202020202020202030303030303030303
+03030303030303030303030000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/chile.gif b/Docs/Flags/chile.gif
index e7afe88df8b..dcd21381a0a 100644
--- a/Docs/Flags/chile.gif
+++ b/Docs/Flags/chile.gif
Binary files differ
diff --git a/Docs/Flags/chile.pdf b/Docs/Flags/chile.pdf
new file mode 100644
index 00000000000..6a1bfb10c0a
--- /dev/null
+++ b/Docs/Flags/chile.pdf
Binary files differ
diff --git a/Docs/Flags/china.eps b/Docs/Flags/china.eps
index 97b87f4727f..d76667bb762 100644
--- a/Docs/Flags/china.eps
+++ b/Docs/Flags/china.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: china.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c7e1c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000037602000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6cfc6c6c6c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000250000000e00000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6efc9c6c6c7e1c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000b70e00000377010000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c7e1c7c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000027602000000000000
000000000000000000000000000000000000000000000000000000000000
-c6d7f4fef7e2c7c6c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-004bccfcda7d03000d000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6cec6c6c6cac6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000240000001000
000000000000000000000000000000000000000000000000000000000000
-c6c6e2fff2c6c6c7d3c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00007dffc301000338010000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6eeca
+c6c6c7e1c7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+b41000000276020000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6e5d4e9c8c6c6d7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00008a3b9c0a00004c000000000000000000000000000000000000000000
+00c6d7f3fef7e3c7c6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000004ac8fbd88103000f000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c7c6c6c7c7d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000003000003042a00000000000000000000000000000000000000000000
+00000000000000c6c6e2fff3c6c6c7d1c7c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6000000007cffc901000233020000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6dac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000015800000000000000000000000000000000000000000000
+00000000000000000000000000c6c6e6d5eac9c6c6d9c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000008c42a20b000053000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c7c6c6c7c7cec6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000005000005032301
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6dcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000016100000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/china.gif b/Docs/Flags/china.gif
index 4baf243f158..6e0c5eb42aa 100644
--- a/Docs/Flags/china.gif
+++ b/Docs/Flags/china.gif
Binary files differ
diff --git a/Docs/Flags/china.pdf b/Docs/Flags/china.pdf
new file mode 100644
index 00000000000..9706ee48a28
--- /dev/null
+++ b/Docs/Flags/china.pdf
Binary files differ
diff --git a/Docs/Flags/costa-rica.eps b/Docs/Flags/costa-rica.eps
new file mode 100644
index 00000000000..b225246c0c7
--- /dev/null
+++ b/Docs/Flags/costa-rica.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: costa-rica.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000a6a6a6a6a6
+a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a60000a3a3a3
+a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a30000e1
+e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e100
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7
+e7e7e7e7e7e7e7e7e7e7e7e7e70000a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000e7e7e7e7e7
+e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e70000a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9
+a9a9a9a9a9a9a9a9a9a9a9a9a90000a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000e2e2e2e2e2e2e2e2e2e2e2e2e2
+e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e200000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/costa-rica.gif b/Docs/Flags/costa-rica.gif
new file mode 100644
index 00000000000..becc817fdcc
--- /dev/null
+++ b/Docs/Flags/costa-rica.gif
Binary files differ
diff --git a/Docs/Flags/costa-rica.pdf b/Docs/Flags/costa-rica.pdf
new file mode 100644
index 00000000000..881d2018d83
--- /dev/null
+++ b/Docs/Flags/costa-rica.pdf
Binary files differ
diff --git a/Docs/Flags/island.txt b/Docs/Flags/costa-rica.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/island.txt
+++ b/Docs/Flags/costa-rica.txt
diff --git a/Docs/Flags/czech-republic.eps b/Docs/Flags/czech-republic.eps
index afa50e9a82d..c179b95db17 100644
--- a/Docs/Flags/czech-republic.eps
+++ b/Docs/Flags/czech-republic.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: czech-republic.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-56e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-50e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0014a2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-00000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080808081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000014a2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-00000000000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080808080808081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000000000014a2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808080808080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-00000000000000000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5b5b5b5cbf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080808080808080808081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-0000000000000000000014a3f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5b5b5b5b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-08080808080808080808080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-00000000000000000000000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5b5b5b5b5b5b5b5b5caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080808080808080808080808081ba6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-0000000000000000000000000014a3f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-b5b5b5b5b5b5b5b5b5b5b5b5b5bae0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-080808080808080808080808081f93c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000010101010101010101010101010101
-b5b5b5b5b5b5b5b5b5b5b5b5b59f31010101010101010101010101010101
-08080808080808080808080954bcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b46d0a00000000000000000000000000000000
-080808080808080808081f93c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b59f31000000000000000000000000000000000000
-08080808080808080954bcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b46d0a00000000000000000000000000000000000000
-080808080808081f92c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+0000000000000056e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f700000013a2f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5bae0f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000008080856e2f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000000000050e1f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5caf1f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000080808081b
+a5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000000
+0013a2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5
+b5b5b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+0008080808080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7000000000000000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000b5b5b5b5b5b5caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000080808080808081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f700000000000000000013a2f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000b5b5b5b5b5b5b5bae0f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7000008080808080808080856e2f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7000000000000000000000050e1f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5b5b5b5b5b5b5caf1f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000080808080808080808081b
+a5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0013a2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5b5b5b5b5
+b5b5b5bae0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700000808080808
+0808080808080856e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000000000
+00000000000000000050e1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5
+b5b5b5b5b5b5b5b5b5b5b5caf1f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00080808080808080808080808081ba5f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000013a2f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000b5b5b5b5b5b5b5b5b5b5b5b5b5bae0f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000080808080808080808080808081784c7c7c7c7c7c7c7c7
+c7c7c7c7c7c7c70000000000000000000000000000000000030303030303
+0303030303030303030000b5b5b5b5b5b5b5b5b5b5b5b5b5a73f03030303
+0303030303030303030303000008080808080808080808080845b5c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b57b
+100000000000000000000000000000000000000808080808080808080817
+84c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5a73f00000000000000000000000000000000000000000808080808
+0808080845b5c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b57b100000000000000000000000000000000000000000
+00080808080808081784c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5a73f00000000000000000000000000000000
+0000000000000008080808080845b5c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b57b100000000000000000000000
+00000000000000000000000000080808081784c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5a73f00000000000000
+0000000000000000000000000000000000000008080845b5c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b57b100000
+00000000000000000000000000000000000000000000000000081784c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+0000000000000000000000000000000000000000000000000000000000b5
+a73f00000000000000000000000000000000000000000000000000000000
+0045b5c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+00000000007b100000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b59f31000000000000000000000000000000000000000000
-08080808080954bcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b46d0a00000000000000000000000000000000000000000000
-080808081f93c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b59f31000000000000000000000000000000000000000000000000
-08080954bcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-b5b5b46d0a00000000000000000000000000000000000000000000000000
-081f92c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-b59f31000000000000000000000000000000000000000000000000000000
-53bcc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-6e0a00000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/czech-republic.gif b/Docs/Flags/czech-republic.gif
index 10d5a3c72e9..eeaeb4b791b 100644
--- a/Docs/Flags/czech-republic.gif
+++ b/Docs/Flags/czech-republic.gif
Binary files differ
diff --git a/Docs/Flags/czech-republic.pdf b/Docs/Flags/czech-republic.pdf
new file mode 100644
index 00000000000..7fb2680269f
--- /dev/null
+++ b/Docs/Flags/czech-republic.pdf
Binary files differ
diff --git a/Docs/Flags/denmark.eps b/Docs/Flags/denmark.eps
index 2f397c4af16..c3ddf74f725 100644
--- a/Docs/Flags/denmark.eps
+++ b/Docs/Flags/denmark.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: denmark.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c7c7c7c7c7c7c7c9fffffffac7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c7c9fffffffac7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c6c7c6c6c6c7c9fffffffac7c6c6c6c6c6c6c6c6c6c6c6c6c6c7c6c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c6c7c7c7c9fffffff9c7c7c7c6c6c6c6c6c6c6c6c6c6c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c6c7c7c7c7c7c9fffffffac7c7c7c7c7c7c7c7c7c7c7c6c7c7c6c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c6c7c7c7c7c8fffffffac7c7c7c7c6c6c6c6c6c6c7c7c6c7c6c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c7c9fffffff9c7c7c7c7c6c6c6c6c6c6c7c7c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c6c9fffffffac6c7c7c7c7c6c6c6c7c7c7c7c7c7c6c7c7c8
-060606060606060efffffff0060606060606060606060606060606060606
-020202020202020affffffe9020202020202020202020202020202020202
-fefefefefefefefefffffffffefefefefefefefefefefefefefefefefefe
-fefefefefefefefefffffffffefefefefefefefefefefefefefefefefefe
-fbfbfbfbfbfbfbfbfffffffffbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-fdfdfdfdfdfdfdfdfffffffffdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfd
-f3f3f3f3f3f3f3f3fffffffef3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-f3f3f3f3f3f3f3f3fffffffef3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-c7c7c6c6c6c6c6c8fffffff9c7c6c6c6c7c6c6c6c6c6c7c6c6c6c6c6c6c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c6c6c7c7c7c7c8fffffff9c7c7c7c7c7c7c7c7c7c7c6c6c6c6c7c6c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c7c8fffffffac7c7c7c7c7c7c7c7c7c7c6c7c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c6c8fffffffac7c7c7c7c7c7c6c7c6c7c7c6c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c6c7c7c7c7c7c7c8fffffff9c7c7c7c7c7c7c7c6c7c7c7c7c7c7c6c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c6c7c7c9fffffff9c7c6c7c7c6c7c7c7c7c7c7c6c7c7c7c6c7c7
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c6c6c8fffffffac6c7c7c7c7c6c7c7c6c7c7c6c7c7c7c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
-c7c7c7c7c7c7c6c9fffffffac6c7c6c7c6c6c6c7c7c7c7c7c6c7c6c7c7c8
-0000000000000008fffffff0000000000000000000000000000000000000
-0000000000000008ffffffe9000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c7c7c7c7c7c7c7c7fffffffcc7c7c7c7c7c6c7c7c7c7c7
+c6c7c7c7c7c7c700000000000000000000fffffffc000000000000000000
+00000000000000000000000000000000000000fffffff500000000000000
+00000000000000000000000000c7c7c7c7c7c7c7c7fffffffcc7c7c7c7c7
+c7c7c7c7c7c7c7c7c7c7c7c7c700000000000000000000fffffffc000000
+00000000000000000000000000000000000000000000000000fffffff500
+00000000000000000000000000000000000000c7c6c7c6c6c6c7c7ffffff
+fcc7c6c6c6c6c6c6c6c6c6c6c6c6c6c7c7c7c700000000000000000000ff
+fffffc000000000000000000000000000000000000000000000000000000
+00fffffff50000000000000000000000000000000000000000c7c7c7c6c7
+c7c7c7fffffffcc6c7c7c6c6c6c6c6c6c6c6c6c6c7c6c7c7c70000000000
+0000000000fffffffc000000000000000000000000000000000000000000
+00000000000000fffffff500000000000000000000000000000000000000
+00c7c6c7c7c7c6c7c7fffffffcc6c7c7c7c7c7c7c7c7c7c7c7c7c7c6c7c7
+c700000000000000000000fffffffc000000000000000000000000000000
+00000000000000000000000000fffffff500000000000000000000000000
+00000000000000c7c7c6c7c7c7c7c7fffffffcc7c7c6c7c6c6c6c6c6c6c6
+c7c6c7c7c7c6c700000000000000000000fffffffc000000000000000000
+00000000000000000000000000000000000000fffffff500000000000000
+00000000000000000000000000c7c7c7c6c7c6c7c7fffffffcc6c7c7c7c6
+c6c6c6c6c7c7c6c7c7c6c7c6c700000000000000000000fffffffc000000
+00000000000000000000000000000000000000000000000000fffffff500
+00000000000000000000000000000000000000c7c7c7c7c7c7c6c7ffffff
+fcc7c6c7c6c6c7c7c6c7c7c7c7c7c7c7c6c7c700000000000000000000ff
+fffffc000000000000000000000000000000000000000000000000000000
+00fffffff50000000000000000000000000000000000000000fcfcfcfcfc
+fcfcfcfffffffffcfcfcfcfcfcfbfcfcfcfcfbfcfcfcfcfcfc0000fcfcfc
+fcfcfcfcfcfffffffffcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc0000f5
+f5f5f5f5f5f5f5fffffffff5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f500
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffff0000c7c7c7c6c7c7c6c6ffffff
+fcc6c6c6c7c7c6c6c7c7c7c7c6c6c6c7c7c7c700000000000000000000ff
+fffffc000000000000000000000000000000000000000000000000000000
+00fffffff50000000000000000000000000000000000000000c7c7c6c6c7
+c6c7c7fffffffcc6c7c7c7c7c7c7c6c7c6c6c7c7c7c7c6c7c70000000000
+0000000000fffffffc000000000000000000000000000000000000000000
+00000000000000fffffff500000000000000000000000000000000000000
+00c7c6c6c7c7c6c7c7fffffffcc7c7c7c7c7c6c7c6c7c6c7c7c7c6c7c7c7
+c700000000000000000000fffffffc000000000000000000000000000000
+00000000000000000000000000fffffff500000000000000000000000000
+00000000000000c7c6c7c7c7c7c6c7fffffffcc7c6c6c6c7c7c7c7c7c7c7
+c7c7c6c7c7c7c700000000000000000000fffffffc000000000000000000
+00000000000000000000000000000000000000fffffff500000000000000
+00000000000000000000000000c7c7c7c6c7c7c7c7fffffffcc6c6c6c7c6
+c7c6c7c6c7c7c6c7c7c7c6c7c700000000000000000000fffffffc000000
+00000000000000000000000000000000000000000000000000fffffff500
+00000000000000000000000000000000000000c7c7c7c7c7c6c7c7ffffff
+fcc7c7c7c6c7c7c7c7c6c7c6c6c7c6c7c7c6c700000000000000000000ff
+fffffc000000000000000000000000000000000000000000000000000000
+00fffffff50000000000000000000000000000000000000000c7c7c7c7c6
+c6c6c6fffffffcc6c6c7c7c6c7c7c6c7c6c7c7c7c7c7c6c6c70000000000
+0000000000fffffffc000000000000000000000000000000000000000000
+00000000000000fffffff500000000000000000000000000000000000000
+00c7c7c6c7c7c7c7c7fffffffcc6c7c6c6c7c7c7c7c7c7c6c7c6c6c7c7c7
+c700000000000000000000fffffffc000000000000000000000000000000
+00000000000000000000000000fffffff500000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/denmark.gif b/Docs/Flags/denmark.gif
index 1d8e687adcc..b2cda874fce 100644
--- a/Docs/Flags/denmark.gif
+++ b/Docs/Flags/denmark.gif
Binary files differ
diff --git a/Docs/Flags/denmark.pdf b/Docs/Flags/denmark.pdf
new file mode 100644
index 00000000000..c405a7b0f11
--- /dev/null
+++ b/Docs/Flags/denmark.pdf
Binary files differ
diff --git a/Docs/Flags/estonia.eps b/Docs/Flags/estonia.eps
index e34768c3442..a73cd8eecce 100644
--- a/Docs/Flags/estonia.eps
+++ b/Docs/Flags/estonia.eps
@@ -1,48 +1,57 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: estonia.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
+000000000000000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000505050505050505050505050505050505
+050505050505050505050505050000000000000000000000000000000000
+00000000000000000000000000000000007a7a7a7a7a7a7a7a7a7a7a7a7a
+7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a00000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-050505050505050505050505050505050505050505050505050505050505
000000000000000000000000000000000000000000000000000000000000
-757575757575757575757575757575757575757575757575757575757575
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
@@ -57,31 +66,33 @@ b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000a4a4a4a4a4
+a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a40000a4a4a4
+a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a40000a4
+a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a400
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1
-b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1
-b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/estonia.gif b/Docs/Flags/estonia.gif
index b8bbf1dbb78..ac2c62b78e9 100644
--- a/Docs/Flags/estonia.gif
+++ b/Docs/Flags/estonia.gif
Binary files differ
diff --git a/Docs/Flags/estonia.pdf b/Docs/Flags/estonia.pdf
new file mode 100644
index 00000000000..12056acb79d
--- /dev/null
+++ b/Docs/Flags/estonia.pdf
Binary files differ
diff --git a/Docs/Flags/finland.eps b/Docs/Flags/finland.eps
index c88fa4e2eaa..847a0fdd30d 100644
--- a/Docs/Flags/finland.eps
+++ b/Docs/Flags/finland.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: finland.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f2f2f2f2f2f2f2eb18181825f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2
-f5f5f5f5f5f5f5f3b5b5b5b9f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-191919191919191918181818191919191919191919191919191919191919
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-222222222222222218181819222222222222222222222222222222222222
-b8b8b8b8b8b8b8b8b5b5b5b5b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f018181825f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f5b5b5b5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7181818
+1bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5
+b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7181818
+1bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5
+b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700001b1b1b1b1b
+1b1b1b181818181b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b0000b6b6b6
+b6b6b6b6b6b5b5b5b5b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b60000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00001818181818181818181818181818181818
+181818181818181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefef
+efefefefefefefefefefefefefefefefef0000f7f7f7f7f7f7f7f7181818
+1bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5
+b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f71818181bf7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7efefefeff7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7181818
+1bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7b5
+b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f71818181bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7b5b5b5b6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/finland.gif b/Docs/Flags/finland.gif
index a43a398f8f1..08f367ce95c 100644
--- a/Docs/Flags/finland.gif
+++ b/Docs/Flags/finland.gif
Binary files differ
diff --git a/Docs/Flags/finland.pdf b/Docs/Flags/finland.pdf
new file mode 100644
index 00000000000..aa0506be383
--- /dev/null
+++ b/Docs/Flags/finland.pdf
Binary files differ
diff --git a/Docs/Flags/france.eps b/Docs/Flags/france.eps
index 6367b8b98ca..7d5b7fa0830 100644
--- a/Docs/Flags/france.eps
+++ b/Docs/Flags/france.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: france.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-08080808080808080814f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700
+0000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7
+f70000000000000000000000000808080808080808080bf7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7
+f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7
+f7f7f7f7f7f7f70000000000000000000000000808080808080808080bf7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000000000000000
+03f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5
+b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000000808080808
+080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000
+00000000000003f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5
+b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000
+000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700000000000000
+0000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700
+0000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7
+f70000000000000000000000000808080808080808080bf7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7
+f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7
+f7f7f7f7f7f7f70000000000000000000000000808080808080808080bf7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000000000000000
+03f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5
+b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000000808080808
+080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000
+00000000000003f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5
+b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000
+000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700000000000000
+0000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700
+0000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7
+f70000000000000000000000000808080808080808080bf7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7
+f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7
+f7f7f7f7f7f7f70000000000000000000000000808080808080808080bf7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000000000000000
+03f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5
+b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000000808080808
+080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000
+00000000000003f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5
+b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000
+000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700000000000000
+0000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700
+0000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7
+f70000000000000000000000000808080808080808080bf7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c6000000000000000000000003f7f7f7f7f7
+f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5b5b5b6f7f7f7
+f7f7f7f7f7f7f70000000000000000000000000808080808080808080bf7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000000000000000
+03f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5b5b5b5b5b5b5
+b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000000808080808
+080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000000000
+00000000000003f7f7f7f7f7f7f7f7f7f7000000000000000000000000b5
+b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000000000000000
+000808080808080808080bf7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c6000000000000000000000003f7f7f7f7f7f7f7f7f7f700000000000000
+0000000000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/france.gif b/Docs/Flags/france.gif
index 13fcbf29e66..f44b729895a 100644
--- a/Docs/Flags/france.gif
+++ b/Docs/Flags/france.gif
Binary files differ
diff --git a/Docs/Flags/france.pdf b/Docs/Flags/france.pdf
new file mode 100644
index 00000000000..036e96eadef
--- /dev/null
+++ b/Docs/Flags/france.pdf
Binary files differ
diff --git a/Docs/Flags/germany.eps b/Docs/Flags/germany.eps
index 568543e3680..e06e98b1883 100644
--- a/Docs/Flags/germany.eps
+++ b/Docs/Flags/germany.eps
@@ -1,22 +1,22 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: germany.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
@@ -40,48 +40,59 @@ colorimage
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-464646464646464646464646464646464646464646464646464646464646
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+000000000000000000000000004040404040404040404040404040404040
+404040404040404040404040400000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000ececececec
+ececececececececececececececececececececececececec00008e8e8e
+8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e000000
000000000000000000000000000000000000000000000000000000000000
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6000000000000000000000000000000000000000000000000000000
+00000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6000000000000000000000000000000000000000000
+00000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6000000000000000000
+00000000000000000000000000000000000000000000000000ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0000d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6000000
000000000000000000000000000000000000000000000000000000000000
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-999999999999999999999999999999999999999999999999999999999999
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/germany.gif b/Docs/Flags/germany.gif
index e25a855b3d2..aedbb037a32 100644
--- a/Docs/Flags/germany.gif
+++ b/Docs/Flags/germany.gif
Binary files differ
diff --git a/Docs/Flags/germany.pdf b/Docs/Flags/germany.pdf
new file mode 100644
index 00000000000..01df1c4cb3a
--- /dev/null
+++ b/Docs/Flags/germany.pdf
Binary files differ
diff --git a/Docs/Flags/great-britain.eps b/Docs/Flags/great-britain.eps
index 97a7ffc9b57..19464e1e3b7 100644
--- a/Docs/Flags/great-britain.eps
+++ b/Docs/Flags/great-britain.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: great-britain.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-cfd85508080808080808080811e4c6c6d70808080808080808080967decd
-2db24f000000000000000000099600009f0000000000000000000162ab20
-2ec2cab5b5b5b5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5b5b5b5cfb520
-ccc7dfa31b0808080808080811e4c6c6d7080808080808080825b4dbc6ce
-1c057a9c1300000000000000099600009f00000000000000001ea8670127
-1c057bdbbab5b5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5b5bdda670127
-edd9c6cfd85508080808080811e4c6c6d70808080808080967decdc7dde9
-e160012eb14f000000000000099600009f0000000000000162ab200373e3
-e760012ec2cab5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5cfb5210374ec
-2fc4e9ccc7dea31b0808080811e4c6c6d7080808080825b4dbc6ceedb423
-28c2b21c057a9c1300000000099600009f00000000001ea8670129c2b21c
-c0e9b21c057adabab5b5b5b5b8970000aeb5b5b5b5b5bdd9670129c2e4bc
-080b78edd9c6cfd85508080811e4c6c6d70808080967ddccc7dde8650908
-000373e160012db14f000000099600009f0000000162aa200373e1600100
-b5b6d4e760012dc1cab5b5b5b8970000aeb5b5b5b5cfb4200374eccfb5b5
-0808082fc4e9ccc7dea31b0811e4c6c6d7080825b4dac6ceedb423080808
-00000029c2b21d05799c1300099600009f00001ea8660129c2b21c000000
-b5b5b5c0e9b21d057adabab5b8970000aeb5b5bdd9660129c2e4bdb5b5b5
-080808080b78edd9c6cfd85511e4c6c6d70967ddccc7dde8650908080808
-000000000473e161012db14f099600009f0162aa200474e1600100000000
-b5b5b5b5b6d4e761012dc1cab8970000aeb5cfb4200475eccfb5b5b5b5b5
-0e0e0e0e0e0e35c9eaccc8dfaae4c6c6deb4dcc7cfedb9290e0e0e0e0e0e
-0606060606062ec7b31f0b7fa3960000a7aa6c072bc3b722060606060606
-b7b7b7b7b7b7c2eab31f0b7fde970000b0db6c072bc3e6beb7b7b7b7b7b7
-e4e4e4e4e4e4e4e4e5e5e5e5e5d9c6c6dde5e5e5e5e5e4e4e4e4e4e4e4e4
-9a9a9a9a9a9a9a9a9b9b9a9a9b5e0000709b9a9a9b9b9a9a9a9a9a9a9a9a
-9b9b9b9b9b9b9b9b9b9b9a9a9b5f0000719b9a9a9b9b9b9b9b9b9b9b9b9b
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000cfd95608080808080808080808e4c6c6e4080808080808
+0808080856d9cf00002db25000000000000000000000a00000a000000000
+00000000000050b22d00002ec2cab5b5b5b5b5b5b5b5b5b5a30000a3b5b5
+b5b5b5b5b5b5b5b5cac22e0000cbc7dea41b0808080808080808e4c6c6e4
+08080808080808081ba4dec7cb00001b057a9d130000000000000000a000
+00a00000000000000000139d7a051b00001b057bdbbab5b5b5b5b5b5b5b5
+a30000a3b5b5b5b5b5b5b5b5badb7b051b0000eed9c6cfd9560808080808
+0808e4c6c6e40808080808080856d9cfc6d9ee0000e25e002db250000000
+00000000a00000a00000000000000050b22d005ee20000e65f012ec2cab5
+b5b5b5b5b5b5a30000a3b5b5b5b5b5b5b5cac22e005fe6000031c6e9cbc7
+dea41b0808080808e4c6c6e408080808081ba4dec7cbe9c63100002ac5b0
+1b057a9d130000000000a00000a00000000000139d7a051bb0c52a0000c0
+e9b11b057adbbab5b5b5b5b5a30000a3b5b5b5b5b5badb7a051bb1eac000
+00080c7aeed9c6cfd95608080808e4c6c6e40808080856d9cfc6d9ee7a0c
+080000000476e25e002db15000000000a00000a00000000050b12d005ee2
+7604000000b5b6d4e65f012dc1cab5b5b5b5a30000a3b5b5b5b5cac12d00
+5fe6d5b6b5000008080831c6e9ccc7dea41b0808e4c6c6e408081ba4dec7
+cce9c63108080800000000002ac5b01c05799d130000a00000a00000139d
+79051cb0c52a0000000000b5b5b5c0e9b11c0579dbbab5b5a30000a3b5b5
+badb79051cb1eac0b5b5b50000080808080c7aeed9c6cfd95608e4c6c6e4
+0856d9cfc6d9ee7a0c080808080000000000000476e25f012db15000a000
+00a00050b12d005fe27604000000000000b5b5b5b5b6d4e760012dc1cab5
+a30000a3b5cac12d0160e7d5b6b5b5b5b5000008080808080831c6e9ccc7
+dea4e5c6c6e5a4dec7cce9c63108080808080800000000000000002ac5b1
+1c05799da10000a19d79051cb1c52a0000000000000000b5b5b5b5b5b5c0
+e9b21c0579dba30000a3db79051cb1eac0b5b5b5b5b5b50000e4e4e4e4e4
+e4e4e5e7e7e6e6e7dcc6c6dce7e6e6e7e7e5e4e4e4e4e4e4e40000a0a0a0
+a0a0a0a0a1a3a2a0a0a26c00006ca2a0a0a2a3a1a0a0a0a0a0a0a00000a3
+a3a3a3a3a3a3a3a4a3a1a1a36d00006da3a1a1a3a4a3a3a3a3a3a3a3a300
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-dbdbdbdbdbdbdbdfe9e8e6e6e8dbc6c6e0e8e6e6e8e9dddbdbdbdbdbdbdb
-9f9f9f9f9f9f9fa3aea79f9fab6a00007eaa9f9fa8aea19f9f9f9f9f9f9f
-abababababababacafa8a0a0ac6b00007faba0a0a9afacababababababab
-0808080808083ed2e6cac8e098e4c6c6dda3dec7cceac42f080808080808
-00000000000037d1a0120a8b93960000a59c79051db3c228000000000000
-b5b5b5b5b5b5c4eda0130a8ddb970000b0db7a051db3e9c0b5b5b5b5b5b5
-08080808108af0d6c6d2d04411e4c6c6d70855d8cfc6d9ed780b08080808
-000000000887dd4e003cb33d099600009f004fb12d0161e2730300000000
-b5b5b5b5b7d9df4e003cccc5b8970000aeb5cac12d0161e7d4b6b5b5b5b5
-0808083ed2e6cac8e091130811e4c6c6d708081aa3dec7cce9c42f080808
-00000037d09f120a8b8c0b00099600009f0000139c79051db2c228000000
-b5b5b5c4ec9f130b8dd9b8b5b8970000aeb5b5badb7a051db2e9c0b5b5b5
-08108bf0d5c6d2d04408080811e4c6c6d70808080855d8cfc6d9ed780b08
-000887dd4d003cb33e000000099600009f000000004fb12d0160e1730300
-b5b7d9df4d003cccc5b5b5b5b8970000aeb5b5b5b5cac12d0160e7d4b6b5
-3dd2e6cac8e191130808080811e4c6c6d708080808081ba3dec7cce9c42f
-37d09f120b8c8c0b00000000099600009f0000000000139c7a051cb2c229
-c4ec9f120b8dd9b8b5b5b5b5b8970000aeb5b5b5b5b5badb7a051cb2e9c0
-f0d6c6d2d04408080808080811e4c6c6d70808080808080855d8cfc6d9ee
-dd4d003db43d000000000000099600009f000000000000004fb12e0160e3
-df4d003dccc5b5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5cac22e0160e7
-cac8e191130808080808080811e4c6c6d708080808080808081ba3dec7cb
-120b8c8c0b00000000000000099600009f0000000000000000139c7a051a
-120b8ed9b8b5b5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5b5badb7b051a
-d2d24408080808080808080811e4c6c6d70808080808080808080855dacf
-3bb63e000000000000000000099600009f000000000000000000004fb32c
-3bcdc5b5b5b5b5b5b5b5b5b5b8970000aeb5b5b5b5b5b5b5b5b5b5cac32c
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000e4e4e4e4e4e4e4e5e7e7e6e6e7dcc6c6dc
+e7e6e6e7e7e5e4e4e4e4e4e4e40000a0a0a0a0a0a0a0a1a3a2a0a0a26c00
+006ca2a0a0a2a3a1a0a0a0a0a0a0a00000a3a3a3a3a3a3a3a3a4a3a1a1a3
+6d00006da3a1a1a3a4a3a3a3a3a3a3a3a3000008080808080831c6e9ccc7
+dea4e5c6c6e5a4dec7cce9c63108080808080800000000000000002ac4b1
+1c05799da10000a19d79051cb1c52a0000000000000000b5b5b5b5b5b5c0
+e9b21c0579dba30000a3db79051cb2eac0b5b5b5b5b5b50000080808080c
+7aeed9c6cfd95608e4c6c6e40856d9cfc6d9ee7a0c080808080000000000
+000476e260012db15000a00000a00050b12d0060e27604000000000000b5
+b5b5b5b6d4e760012dc1cbb5a30000a3b5cac12d0160e7d5b6b5b5b5b500
+0008080831c6e9ccc7dea41b0808e4c6c6e408081ba4dec7cce9c6310808
+0800000000002ac4b11c05799d140000a00000a00000139d79051cb1c52a
+0000000000b5b5b5c0e9b11c0579dbbab5b5a30000a3b5b5badb79051cb1
+eac0b5b5b50000080c7aeed9c6cfd95608080808e4c6c6e40808080856d9
+cfc6d9ee7a0c080000000476e25f002db15000000000a00000a000000000
+50b12d005ee17604000000b5b6d4e65f012dc1cbb5b5b5b5a30000a3b5b5
+b5b5cac12d005fe6d5b6b5000031c6e9cbc7dea41b0808080808e4c6c6e4
+08080808081ba4dec7cbe9c63100002ac4b01b057a9d140000000000a000
+00a00000000000139d7a051bb0c52a0000c0e9b11b057adbbab5b5b5b5b5
+a30000a3b5b5b5b5b5badb7a051bb1eac00000eed9c6cfd9560808080808
+0808e4c6c6e40808080808080856d9cfc6d9ee0000e25f002db250000000
+00000000a00000a00000000000000050b22d005ee10000e65f012dc2cbb5
+b5b5b5b5b5b5a30000a3b5b5b5b5b5b5b5cac22e005fe60000cbc7dea41b
+0808080808080808e4c6c6e408080808080808081ba4dec7cb00001b057a
+9d140000000000000000a00000a00000000000000000139d7a051b00001b
+057adbbab5b5b5b5b5b5b5b5a30000a3b5b5b5b5b5b5b5b5badb7b051b00
+00cfd95608080808080808080808e4c6c6e40808080808080808080856d9
+cf00002db25000000000000000000000a00000a000000000000000000000
+50b22d00002dc2cbb5b5b5b5b5b5b5b5b5b5a30000a3b5b5b5b5b5b5b5b5
+b5b5cac22e00000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/great-britain.gif b/Docs/Flags/great-britain.gif
index 0f555d078b3..ae92b536ad3 100644
--- a/Docs/Flags/great-britain.gif
+++ b/Docs/Flags/great-britain.gif
Binary files differ
diff --git a/Docs/Flags/great-britain.pdf b/Docs/Flags/great-britain.pdf
new file mode 100644
index 00000000000..f29dfd48861
--- /dev/null
+++ b/Docs/Flags/great-britain.pdf
Binary files differ
diff --git a/Docs/Flags/greece.eps b/Docs/Flags/greece.eps
index 3c022139c56..f59baa86106 100644
--- a/Docs/Flags/greece.eps
+++ b/Docs/Flags/greece.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: greece.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-1818181897f7a61818181818181818181818181818181818181818181818
-b5b5b5b5daf7dfb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefeff4f7f4efefefefefefefefefefefefefefefefefefefefefefef
-1818181897f7a61818181818181818181818181818181818181818181818
-b5b5b5b5daf7dfb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefeff4f7f4efefefefefefefefefefefefefefefefefefefefefefef
-1818181897f7a618181818bbc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7
-b5b5b5b5daf7dfb5b5b5b5e5e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9
-efefefeff4f7f4efefefeff5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5
-1818181897f7a618181818e7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5daf7dfb5b5b5b5f2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-efefefeff4f7f4efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-97979797cdf7d49797979777767676767676767676767676767676767676
-dadadadaeaf7ecdadadadad1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1
-f4f4f4f4f6f7f6f4f4f4f4f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2
-f7f7f7f7f7f7f7f7f7f7f725181818181818181818181818181818181818
-f7f7f7f7f7f7f7f7f7f7f7b9b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-f7f7f7f7f7f7f7f7f7f7f7efefefefefefefefefefefefefefefefefefef
-a6a6a6a6d4f7daa6a6a6a66a676767676767676767676767676767676767
-dfdfdfdfedf7eedfdfdfdfcdcccccccccccccccccccccccccccccccccccc
-f4f4f4f4f6f7f6f4f4f4f4f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2
-1818181897f7a618181818e7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b5b5b5daf7dfb5b5b5b5f2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-efefefeff4f7f4efefefeff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-1818181897f7a618181818c9d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-b5b5b5b5daf7dfb5b5b5b5e9edededededededededededededededededed
-efefefeff4f7f4efefefeff6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-1818181897f7a61818181818181818181818181818181818181818181818
-b5b5b5b5daf7dfb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefeff4f7f4efefefefefefefefefefefefefefefefefefefefefefef
-1818181897f7a61818181818181818181818181818181818181818181818
-b5b5b5b5daf7dfb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefeff4f7f4efefefefefefefefefefefefefefefefefefefefefefef
-e7e7e7e7f0f7f1e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7e7
-f2f2f2f2f5f7f5f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-555555555555555555555555555555555555555555555555555555555555
-c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7
-f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-878787878787878787878787878787878787878787878787878787878787
-d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6b6
-e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4
-f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000001818181893f7ac18181818181818181818181818181818
+181818181818180000b5b5b5b5d9f7e1b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefeff3f7f4efefefefefefefefefefefef
+efefefefefefefefefefef00001818181893f7ac18181818181818181818
+181818181818181818181818180000b5b5b5b5d9f7e1b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefeff3f7f4efefefefefef
+efefefefefefefefefefefefefefefefef00001818181893f7ac18181818
+b1c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c50000b5b5b5b5d9f7e1b5b5
+b5b5e2e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e80000efefefeff3f7f4
+efefefeff4f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f500001818181893
+f7ac18181818def7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5
+b5d9f7e1b5b5b5b5f0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000ef
+efefeff3f7f4efefefeff6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+0093939393caf7d5939393937a7979797979797979797979797979797979
+790000d9d9d9d9e9f7edd9d9d9d9d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2
+d2d2d20000f3f3f3f3f5f7f6f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
+f3f3f3f3f30000f7f7f7f7f7f7f7f7f7f7f72e1818181818181818181818
+181818181818180000f7f7f7f7f7f7f7f7f7f7f7bcb5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000f7f7f7f7f7f7f7f7f7f7f7f0efefefefefefef
+efefefefefefefefefefef0000acacacacd5f7deacacacac686161616161
+616161616161616161616161610000e1e1e1e1edf7f0e1e1e1e1cccacaca
+cacacacacacacacacacacacacacaca0000f4f4f4f4f6f7f6f4f4f4f4f2f2
+f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f200001818181893f7ac18181818
+def7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b5b5b5d9f7e1b5b5
+b5b5f0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000efefefeff3f7f4
+efefefeff6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700001818181893
+f7ac18181818c8dededededededededededededededededede0000b5b5b5
+b5d9f7e1b5b5b5b5e9f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f00000ef
+efefeff3f7f4efefefeff5f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f600
+001818181893f7ac18181818181818181818181818181818181818181818
+180000b5b5b5b5d9f7e1b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefeff3f7f4efefefefefefefefefefefefefefefefefef
+efefefefef00001818181893f7ac18181818181818181818181818181818
+181818181818180000b5b5b5b5d9f7e1b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefeff3f7f4efefefefefefefefefefefef
+efefefefefefefefefefef0000dedededeecf7efdededededededededede
+dedededededededededededede0000f0f0f0f0f4f7f5f0f0f0f0f0f0f0f0
+f0f0f0f0f0f0f0f0f0f0f0f0f0f0f00000f6f6f6f6f7f7f7f6f6f6f6f6f6
+f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f60000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700006161616161
+616161616161616161616161616161616161616161616161610000cacaca
+cacacacacacacacacacacacacacacacacacacacacacacacacacaca0000f2
+f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f200
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00007979797979797979797979797979797979797979797979
+797979797979790000d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2
+d2d2d2d2d2d2d2d2d20000f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
+f3f3f3f3f3f3f3f3f3f3f30000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000c5c5c5c5c5c5c5c5c5c5c5
+c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c50000e8e8e8e8e8e8e8e8e8
+e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e80000f5f5f5f5f5f5f5
+f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f500001818181818
+181818181818181818181818181818181818181818181818180000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/greece.gif b/Docs/Flags/greece.gif
index 1ede215a373..264b295b374 100644
--- a/Docs/Flags/greece.gif
+++ b/Docs/Flags/greece.gif
Binary files differ
diff --git a/Docs/Flags/greece.pdf b/Docs/Flags/greece.pdf
new file mode 100644
index 00000000000..d54d8b3e153
--- /dev/null
+++ b/Docs/Flags/greece.pdf
Binary files differ
diff --git a/Docs/Flags/hungary.eps b/Docs/Flags/hungary.eps
index e405fc3cffe..38d9cae079f 100644
--- a/Docs/Flags/hungary.eps
+++ b/Docs/Flags/hungary.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: hungary.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d60000505050505050505050505050505050
+505050505050505050505050505050000050505050505050505050505050
+50505050505050505050505050505050500000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700005353535353
+535353535353535353535353535353535353535353535353530000cbcbcb
+cbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb000053
+535353535353535353535353535353535353535353535353535353535300
000000000000000000000000000000000000000000000000000000000000
+000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7
-575757575757575757575757575757575757575757575757575757575757
-575757575757575757575757575757575757575757575757575757575757
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-464646464646464646464646464646464646464646464646464646464646
-c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-464646464646464646464646464646464646464646464646464646464646
+000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000000000000000000000000000000000000000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/hungary.gif b/Docs/Flags/hungary.gif
index eca0e109bbe..eb14887b5bb 100644
--- a/Docs/Flags/hungary.gif
+++ b/Docs/Flags/hungary.gif
Binary files differ
diff --git a/Docs/Flags/hungary.pdf b/Docs/Flags/hungary.pdf
new file mode 100644
index 00000000000..51ba552f2ba
--- /dev/null
+++ b/Docs/Flags/hungary.pdf
Binary files differ
diff --git a/Docs/Flags/iceland.eps b/Docs/Flags/iceland.eps
index c2a5529eb42..8a1bc21f4c8 100644
--- a/Docs/Flags/iceland.eps
+++ b/Docs/Flags/iceland.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: iceland.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0e0e0e0e0e0e0e15eec6c6e40e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-060606060606060ec60000cb060606060606060606060606060606060606
-b7b7b7b7b7b7b7b9c70000d6b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7
-ecececececececece6c6c6e9ecececececececececececececececececec
-c5c5c5c5c5c5c5c59f0000aec5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5
-c6c6c6c6c6c6c6c6a00000afc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808efc6c6ec0808080808080808080808
+0808080808080800000000000000000000cf0000cb000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6ec0808080808
+0808080808080808080808080800000000000000000000cf0000cb000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6
+ec08080808080808080808080808080808080800000000000000000000cf
+0000cb0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808efc6c6ec0808080808080808080808080808080808080000000000
+0000000000cf0000cb0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808efc6c6ec0808080808080808080808080808080808
+0800000000000000000000cf0000cb000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808efc6c6ec0808080808080808080808
+0808080808080800000000000000000000cf0000cb000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6ec0808080808
+0808080808080808080808080800000000000000000000cf0000cb000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6
+ec08080808080808080808080808080808080800000000000000000000cf
+0000cb0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ececececec
+ececece9c6c6e8ecececececececececececececececececec0000cbcbcb
+cbcbcbcbcbad0000adcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb0000ce
+cececececececeae0000adcececececececececececececececececece00
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-e6e6e6e6e6e6e6e6e9c6c6ebe6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6
-cecececececececeae0000becececececececececececececececececece
-d7d7d7d7d7d7d7d7af0000c0d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080feec6c6e3080808080808080808080808080808080808
-0000000000000008c60000cb000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7c70000d6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000efefefefefefefefe9c6c6e8efefefefef
+efefefefefefefefefefefefef0000cfcfcfcfcfcfcfcfad0000adcfcfcf
+cfcfcfcfcfcfcfcfcfcfcfcfcfcfcf0000cfcfcfcfcfcfcfcfae0000adcf
+cfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcf00000808080808080808efc6c6
+ec08080808080808080808080808080808080800000000000000000000cf
+0000cb0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808efc6c6ec0808080808080808080808080808080808080000000000
+0000000000cf0000cb0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808efc6c6ec0808080808080808080808080808080808
+0800000000000000000000cf0000cb000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808efc6c6ec0808080808080808080808
+0808080808080800000000000000000000cf0000cb000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6ec0808080808
+0808080808080808080808080800000000000000000000cf0000cb000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5cf0000ceb5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808efc6c6
+ec08080808080808080808080808080808080800000000000000000000cf
+0000cb0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808efc6c6ec0808080808080808080808080808080808080000000000
+0000000000cf0000cb0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808efc6c6ec0808080808080808080808080808080808
+0800000000000000000000cf0000cb000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5cf0000ceb5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/iceland.gif b/Docs/Flags/iceland.gif
index ee4d17f5d04..4fe0c0b8124 100644
--- a/Docs/Flags/iceland.gif
+++ b/Docs/Flags/iceland.gif
Binary files differ
diff --git a/Docs/Flags/iceland.pdf b/Docs/Flags/iceland.pdf
new file mode 100644
index 00000000000..3509de59ba8
--- /dev/null
+++ b/Docs/Flags/iceland.pdf
Binary files differ
diff --git a/Docs/Flags/indonesia.eps b/Docs/Flags/indonesia.eps
index e69de29bb2d..9dcef0824df 100644
--- a/Docs/Flags/indonesia.eps
+++ b/Docs/Flags/indonesia.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: indonesia.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4
+f4f4f4f4f4f4f4f4f40000f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4
+f4f4f4f4f4f4f4f4f4f4f40000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/indonesia.gif b/Docs/Flags/indonesia.gif
index 1c421df50ba..e05af4c8ff4 100644
--- a/Docs/Flags/indonesia.gif
+++ b/Docs/Flags/indonesia.gif
Binary files differ
diff --git a/Docs/Flags/indonesia.pdf b/Docs/Flags/indonesia.pdf
new file mode 100644
index 00000000000..48bd801fa15
--- /dev/null
+++ b/Docs/Flags/indonesia.pdf
Binary files differ
diff --git a/Docs/Flags/ireland.eps b/Docs/Flags/ireland.eps
index 610b2086fd7..01251367922 100644
--- a/Docs/Flags/ireland.eps
+++ b/Docs/Flags/ireland.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: ireland.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f8ffffffffffffffffffff
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7f4d6d6d6d6d6d6d6d6d6d6
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffff
+ffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6
+d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffff
+ff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6
+d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffff
+ffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6
+d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffff
+ff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6
+d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffff
+ffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6
+d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffff
+ff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6
+d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffff
+ffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6
+d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffffff0000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6d6d6d6000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7ffffffffffffffffff
+ff0000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f7d6d6d6d6d6d6d6
+d6d6d6000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/ireland.gif b/Docs/Flags/ireland.gif
index a550678761f..631be2f33b9 100644
--- a/Docs/Flags/ireland.gif
+++ b/Docs/Flags/ireland.gif
Binary files differ
diff --git a/Docs/Flags/ireland.pdf b/Docs/Flags/ireland.pdf
new file mode 100644
index 00000000000..5f84f52f049
--- /dev/null
+++ b/Docs/Flags/ireland.pdf
Binary files differ
diff --git a/Docs/Flags/italy.eps b/Docs/Flags/italy.eps
index 20c7c7d5da3..7de3ddd9c1f 100644
--- a/Docs/Flags/italy.eps
+++ b/Docs/Flags/italy.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: italy.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5b8f7f7f7f7f7f7f7f7f7e400000000000000000000
-0000000000000000000cf7f7f7f7f7f7f7f7f7e400000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700
+000000000000000000000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000
+000000000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700
+000000000000000000000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000
+000000000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700
+000000000000000000000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000
+000000000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+0000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700
+000000000000000000000000000000000000000003f7f7f7f7f7f7f7f7f7
+f700000000000000000000000000000000000000000003f7f7f7f7f7f7f7
+f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000003f7f7f7
+f7f7f7f7f7f7f700000000000000000000000000000000000000000003f7
+f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000000000000000
+000003f7f7f7f7f7f7f7f7f7f70000000000000000000000000000000000
+0000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000000000000000
+000000000000000003f7f7f7f7f7f7f7f7f7f70000000000000000000000
+0000000000000000000003f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b6f7f7f7f7f7f7f7f7f7f700000000000000
+000000000000000000000000000003f7f7f7f7f7f7f7f7f7f70000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/italy.gif b/Docs/Flags/italy.gif
index 511dba800c7..d59cf5ef55e 100644
--- a/Docs/Flags/italy.gif
+++ b/Docs/Flags/italy.gif
Binary files differ
diff --git a/Docs/Flags/italy.pdf b/Docs/Flags/italy.pdf
new file mode 100644
index 00000000000..02c7d316a05
--- /dev/null
+++ b/Docs/Flags/italy.pdf
Binary files differ
diff --git a/Docs/Flags/japan.eps b/Docs/Flags/japan.eps
index 8dee6e497ba..c8ea7aa8afe 100644
--- a/Docs/Flags/japan.eps
+++ b/Docs/Flags/japan.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: japan.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7edddd6d7dfeff7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7c17652557cccf7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7c27653557cccf7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f2d4c6c6c6c6c6c6d8f4f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7de4500000000000157e9f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7de4600000000000158e9f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f2ccc6c6c6c6c6c6c6c6d0f5f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7de1f000000000000000030eaf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7de1f000000000000000030eaf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7d4c6c6c6c6c6c6c6c6c6c6d9f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7430000000000000000000060f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7440000000000000000000060f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7ecc6c6c6c6c6c6c6c6c6c6c6c7f1f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7be000000000000000000000003d8f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7be000000000000000000000003d9f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7ddc6c6c6c6c6c6c6c6c6c6c6c6e2f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7720000000000000000000000008ff7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7720000000000000000000000008ff7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7d6c6c6c6c6c6c6c6c6c6c6c6c6dbf7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f74e0000000000000000000000006bf7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f74e0000000000000000000000006bf7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7d6c6c6c6c6c6c6c6c6c6c6c6c6dcf7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f74f0000000000000000000000006cf7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f74f0000000000000000000000006df7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7dec6c6c6c6c6c6c6c6c6c6c6c6e3f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f77600000000000000000000000093f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f77600000000000000000000000093f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7edc6c6c6c6c6c6c6c6c6c6c6c7f2f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7c6000000000000000000000005def7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7c6000000000000000000000005def7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7d6c6c6c6c6c6c6c6c6c6c6dcf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f74f000000000000000000006cf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f74f000000000000000000006df7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f4cec6c6c6c6c6c6c6c6d2f5f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7e52a00000000000000003deff7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7e52a00000000000000003deff7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f4d8c6c6c6c6c6c7dbf5f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7e7580200000000056aeff7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7e7590200000000056beff7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f0e1dadbe3f2f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7d389666890dcf7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7d389666890dcf7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7eedfd7d7dfeef7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7ca7c57577ccaf7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7ca7c57577ccaf7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f3d6c6c6c6c6c6c6d6f3f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7e45000000000000050e4f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7e45000000000000050e4f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f3cec6c6c6c6c6c6c6c6cef3f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7e427000000000000000027e4
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7e4270000000000000000
+27e4f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7d6c6c6c6c6c6c6c6
+c6c6c6d6f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7500000000000
+000000000050f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f750000000
+0000000000000050f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7eec6c6
+c6c6c6c6c6c6c6c6c6c6eef7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7ca
+000000000000000000000000caf7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7ca000000000000000000000000caf7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7dfc6c6c6c6c6c6c6c6c6c6c6c6dff7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f77c0000000000000000000000007cf7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f77c0000000000000000000000007cf7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7d7c6c6c6c6c6c6c6c6c6c6c6c6d7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f75700000000000000000000000057f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f75700000000000000000000000057f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7d7c6c6c6c6c6c6c6c6c6c6c6c6d7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f757000000000000000000000000
+57f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f75700000000000000000000
+000057f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7dfc6c6c6c6c6c6c6c6
+c6c6c6c6dff7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f77c000000000000
+0000000000007cf7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f77c00000000
+00000000000000007cf7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7eec6c6
+c6c6c6c6c6c6c6c6c6c6eef7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7c9
+000000000000000000000000caf7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7ca000000000000000000000000caf7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7d6c6c6c6c6c6c6c6c6c6c6d6f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7500000000000000000000050f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7500000000000000000000050f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f3cec6c6c6c6c6c6c6c6cef3f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7e427000000000000000027e4f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7e427000000000000000027e4f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f3d6c6c6c6c6c6c6d6f3f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7e45000000000000050e4f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7e45000000000000050
+e4f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7eedfd7d7df
+eef7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7c97c56
+567cc9f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7ca
+7c57577ccaf7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/japan.gif b/Docs/Flags/japan.gif
index 37ebca66f04..7d6a9adbd78 100644
--- a/Docs/Flags/japan.gif
+++ b/Docs/Flags/japan.gif
Binary files differ
diff --git a/Docs/Flags/japan.pdf b/Docs/Flags/japan.pdf
new file mode 100644
index 00000000000..c98ff331611
--- /dev/null
+++ b/Docs/Flags/japan.pdf
Binary files differ
diff --git a/Docs/Flags/latvia.eps b/Docs/Flags/latvia.eps
index 9c1f81f3ddc..606f7e70b3c 100644
--- a/Docs/Flags/latvia.eps
+++ b/Docs/Flags/latvia.eps
@@ -2,7 +2,7 @@
%%Creator: pnmtops
%%Title: latvia.ps
%%Pages: 1
-%%BoundingBox: 295 365 317 396
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
@@ -13,9 +13,8 @@
%%EndProlog
%%Page: 1 1
gsave
-295.44 365.64 translate
-21.12 30.72 scale
-0.5 0.5 translate 90 rotate -0.5 -0.5 translate
+290.64 385.44 translate
+30.72 21.12 scale
32 22 8
[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
@@ -26,71 +25,71 @@ colorimage
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-000000000000009494949494949494949494949494949494949494949494
-949494949494940000101010101010101010101010101010101010101010
-101010101010101010000018181818181818181818181818181818181818
-181818181818181818181800009494949494949494949494949494949494
-949494949494949494949494940000101010101010101010101010101010
-101010101010101010101010101010000018181818181818181818181818
-181818181818181818181818181818181800009494949494949494949494
-949494949494949494949494949494949494940000101010101010101010
-101010101010101010101010101010101010101010000018181818181818
-181818181818181818181818181818181818181818181800009494949494
-949494949494949494949494949494949494949494949494940000101010
-101010101010101010101010101010101010101010101010101010000018
-181818181818181818181818181818181818181818181818181818181800
-009494949494949494949494949494949494949494949494949494949494
-940000101010101010101010101010101010101010101010101010101010
-101010000018181818181818181818181818181818181818181818181818
-181818181800009494949494949494949494949494949494949494949494
-949494949494940000101010101010101010101010101010101010101010
-101010101010101010000018181818181818181818181818181818181818
-181818181818181818181800009494949494949494949494949494949494
-949494949494949494949494940000101010101010101010101010101010
-101010101010101010101010101010000018181818181818181818181818
-181818181818181818181818181818181800009494949494949494949494
-949494949494949494949494949494949494940000101010101010101010
-101010101010101010101010101010101010101010000018181818181818
-18181818181818181818181818181818181818181818180000ffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
-00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffff00009494949494949494949494
-949494949494949494949494949494949494940000101010101010101010
-101010101010101010101010101010101010101010000018181818181818
-181818181818181818181818181818181818181818181800009494949494
-949494949494949494949494949494949494949494949494940000101010
-101010101010101010101010101010101010101010101010101010000018
-181818181818181818181818181818181818181818181818181818181800
-009494949494949494949494949494949494949494949494949494949494
-940000101010101010101010101010101010101010101010101010101010
-101010000018181818181818181818181818181818181818181818181818
-181818181800009494949494949494949494949494949494949494949494
-949494949494940000101010101010101010101010101010101010101010
-101010101010101010000018181818181818181818181818181818181818
-181818181818181818181800009494949494949494949494949494949494
-949494949494949494949494940000101010101010101010101010101010
-101010101010101010101010101010000018181818181818181818181818
-181818181818181818181818181818181800009494949494949494949494
-949494949494949494949494949494949494940000101010101010101010
-101010101010101010101010101010101010101010000018181818181818
-181818181818181818181818181818181818181818181800009494949494
-949494949494949494949494949494949494949494949494940000101010
-101010101010101010101010101010101010101010101010101010000018
-181818181818181818181818181818181818181818181818181818181800
-009494949494949494949494949494949494949494949494949494949494
-940000101010101010101010101010101010101010101010101010101010
-101010000018181818181818181818181818181818181818181818181818
-181818181800000000000000000000000000000000000000000000000000
+00000000000000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a50000000000000000000000000000000000000000000000
+000000000000000000000010101010101010101010101010101010101010
+10101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000000000000000
+000000000000000000000000000000000010101010101010101010101010
+10101010101010101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000
+000000000000000000000000000000000000000000000010101010101010
+10101010101010101010101010101010101010101010100000a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000
+000000000000000000000000000000000000000000000000000000000010
+101010101010101010101010101010101010101010101010101010101000
+00a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a50000000000000000000000000000000000000000000000000000000000
+000000000010101010101010101010101010101010101010101010101010
+10101010100000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a50000000000000000000000000000000000000000000000
+000000000000000000000010101010101010101010101010101010101010
+10101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000000000000000
+000000000000000000000000000000000010101010101010101010101010
+10101010101010101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000
+000000000000000000000000000000000000000000000010101010101010
+10101010101010101010101010101010101010101010100000dbdbdbdbdb
+dbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdb0000a3a3a3
+a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a30000ab
+ababababababababababababababababababababababababababababab00
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc
+dcdcdcdcdcdcdcdcdcdcdcdcdc0000a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3
+a3a3a3a3a3a3a3a3a3a3a3a3a3a3a30000ababababababababababababab
+ababababababababababababababababab0000a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000
+000000000000000000000000000000000000000000000010101010101010
+10101010101010101010101010101010101010101010100000a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000
+000000000000000000000000000000000000000000000000000000000010
+101010101010101010101010101010101010101010101010101010101000
+00a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a50000000000000000000000000000000000000000000000000000000000
+000000000010101010101010101010101010101010101010101010101010
+10101010100000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a50000000000000000000000000000000000000000000000
+000000000000000000000010101010101010101010101010101010101010
+10101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000000000000000
+000000000000000000000000000000000010101010101010101010101010
+10101010101010101010101010101010100000a5a5a5a5a5a5a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000000000000000
+000000000000000000000000000000000000000000000010101010101010
+10101010101010101010101010101010101010101010100000a5a5a5a5a5
+a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a50000000000
+000000000000000000000000000000000000000000000000000000000010
+101010101010101010101010101010101010101010101010101010101000
+00a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5
+a50000000000000000000000000000000000000000000000000000000000
+000000000010101010101010101010101010101010101010101010101010
+101010101000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000
diff --git a/Docs/Flags/latvia.gif b/Docs/Flags/latvia.gif
index 8a898328ebe..b8ba782b703 100644
--- a/Docs/Flags/latvia.gif
+++ b/Docs/Flags/latvia.gif
Binary files differ
diff --git a/Docs/Flags/latvia.pdf b/Docs/Flags/latvia.pdf
new file mode 100644
index 00000000000..1d06690e980
--- /dev/null
+++ b/Docs/Flags/latvia.pdf
Binary files differ
diff --git a/Docs/Flags/mexico.eps b/Docs/Flags/mexico.eps
new file mode 100644
index 00000000000..c6f4f0a79de
--- /dev/null
+++ b/Docs/Flags/mexico.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: mexico.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000005ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7fffffffffffffffffffe00
+000000000000000000000000000000000000000005ffffffffffffffffff
+fe00000000000000000000000000000000000000000005ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7ffffffffff
+fffffffffe00000000000000000000000000000000000000000005ffffff
+fffffffffffffe00000000000000000000000000000000000000000005ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b7fffffffffffffffffffe00000000000000000000000000000000000000
+000005fffffffffffffffffffe0000000000000000000000000000000000
+0000000005ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b7fffffffffffffffffffe00000000000000000000000000
+000000000000000005fffffffffffffffffffe0000000000000000000000
+0000000000000000000005ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b7fffffffffffffffffffe00000000000000
+000000000000000000000000000005fffffffffffffffffffe0000000000
+0000000000000000000000000000000005ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7fffffffffffffffffffe00
+000000000000000000000000000000000000000005ffffffffffffffffff
+fe00000000000000000000000000000000000000000005fffffffee0bbe1
+ffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7fffffffed2
+95d3fffffe00000000000000000000000000000000000000000005ffffff
+fec876c7fffffe00000000000000000000000000000000000000000005ff
+ffc4ae7f8683cdffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b7ffffd790453e3daefffe00000000000000000000000000000000000000
+000005ffffbc6114010295fffe0000000000000000000000000000000000
+0000000005fffcd699827c838df6ffc6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b7fffbdca23f383c47f3fe00000000000000000000000000
+000000000000000005ffface770600000cf0fe0000000000000000000000
+0000000000000000000005f3e89eaa827eb98de6f5c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b7f6eab996493b9a53def800000000000000
+000000000000000000000000000005f1e28f8319038123d2f30000000000
+0000000000000000000000000000000005cfcf77bab38a93bdbdd5c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7dbcf97a18c5159a1cae200
+000000000000000000000000000000000000000005c3bc67796521298bab
+cd00000000000000000000000000000000000000000005fa8cbd7c4c6076
+c079fdc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7fbadcba194
+839bb6abfc00000000000000000000000000000000000000000005f978b8
+78542f63a668fb00000000000000000000000000000000000000000005ff
+e2829a795dbd8ee1ffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b7ffe5a9bf5657c8b9e7fe00000000000000000000000000000000000000
+000005ffd86ecd2d20c780d9fe0000000000000000000000000000000000
+0000000005ffffe68b989f86f5ffffc6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b7ffffe8b4aba8b5f4fffe00000000000000000000000000
+000000000000000005ffffdd7d8a8c78f0fffe0000000000000000000000
+0000000000000000000005fffffffffefeffffffffc6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b7fffffffffefefffffffe00000000000000
+000000000000000000000000000005fffffffffefefffffffe0000000000
+0000000000000000000000000000000005ffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7fffffffffffffffffffe00
+000000000000000000000000000000000000000005ffffffffffffffffff
+fe00000000000000000000000000000000000000000005ffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b7ffffffffff
+fffffffffe00000000000000000000000000000000000000000005ffffff
+fffffffffffffe00000000000000000000000000000000000000000005ff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b7fffffffffffffffffffe00000000000000000000000000000000000000
+000005fffffffffffffffffffe0000000000000000000000000000000000
+0000000005ffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b7fffffffffffffffffffe00000000000000000000000000
+000000000000000005fffffffffffffffffffe0000000000000000000000
+0000000000000000000005ffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b7fffffffffffffffffffe00000000000000
+000000000000000000000000000005fffffffffffffffffffe0000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/mexico.gif b/Docs/Flags/mexico.gif
new file mode 100644
index 00000000000..206d1236ef1
--- /dev/null
+++ b/Docs/Flags/mexico.gif
Binary files differ
diff --git a/Docs/Flags/mexico.pdf b/Docs/Flags/mexico.pdf
new file mode 100644
index 00000000000..c983198d2b5
--- /dev/null
+++ b/Docs/Flags/mexico.pdf
Binary files differ
diff --git a/Docs/Flags/kroatia.eps b/Docs/Flags/mexico.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/kroatia.eps
+++ b/Docs/Flags/mexico.txt
diff --git a/Docs/Flags/netherlands.eps b/Docs/Flags/netherlands.eps
index 6f4d9906a11..94795e98baa 100644
--- a/Docs/Flags/netherlands.eps
+++ b/Docs/Flags/netherlands.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: netherlands.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7
-575757575757575757575757575757575757575757575757575757575757
-575757575757575757575757575757575757575757575757575757575757
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c
-464646464646464646464646464646464646464646464646464646464646
-c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
+d6d6d6d6d6d6d6d6d6d6d6d6d60000505050505050505050505050505050
+505050505050505050505050505050000050505050505050505050505050
+50505050505050505050505050505050500000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700005959595959
+595959595959595959595959595959595959595959595959590000535353
+5353535353535353535353535353535353535353535353535353530000cb
+cbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb00
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/netherlands.gif b/Docs/Flags/netherlands.gif
index c09d3eb495c..2f236b58949 100644
--- a/Docs/Flags/netherlands.gif
+++ b/Docs/Flags/netherlands.gif
Binary files differ
diff --git a/Docs/Flags/netherlands.pdf b/Docs/Flags/netherlands.pdf
new file mode 100644
index 00000000000..098629aee10
--- /dev/null
+++ b/Docs/Flags/netherlands.pdf
Binary files differ
diff --git a/Docs/Flags/new-zealand.eps b/Docs/Flags/new-zealand.eps
new file mode 100644
index 00000000000..9177154f8f7
--- /dev/null
+++ b/Docs/Flags/new-zealand.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: new-zealand.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000ce770d08080874c6770808080c77ce0808080808080808
+0808080808080800003e58050000004d005000000005583e000000000000
+000000000000000000000042b4b6b5b5b5aa00abb5b5b5b6b442b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000aed2b433080874c677080833b4d2ae0808
+0808080808080808080808080800008a3d5e2b00004d005000002b5e3d8a
+0000000000000000000000000000000000bb3d81bfb5b5aa00abb5b5bf81
+3dbbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000967d3ce770d74c6770c77
+ced36709080808080808083e230808080808080000015f733e58054d0050
+05583e735f0100000000000000341c0000000000000000b5cb7d42b4b6aa
+00abb6b4427dcbb5b5b5b5b5b5b5b5bfbcb5b5b5b5b5b50000080825aed2
+b49bc69db3d2ae25080808080808080a65a49a5a0808080808000000001e
+893d5e7400765d3d8a1e000000000000000253444c4d00000000000000b5
+b5bdbb3d81b300b4813dbbbdb5b5b5b5b5b5b5b6bf7285c3b5b5b5b5b500
+00d3d3d3d3d6d5d3c6d3d5d6d3d3d3d30808080808081ccfc01308080808
+0800004d4d4d4d4f4d4200424d4f4d4d4d4d00000000000015484a0b0000
+00000000004f4f4f4f4f4d4200424d4f4f4f4f4fb5b5b5b5b5b5ba4e5fb8
+b5b5b5b5b50000d6d6d6d6d6d6d3c6d3d6d6d6d6d6d60808080808082c59
+6b1808080808080000505050505050420042505050505050000000000000
+25475a1000000000000000505050505050420042505050505050b5b5b5b5
+b5b5bfbdc2b9b5b5b5b5b50000080825aed2b49bc69db4d2ae2508080808
+08080908080808080832080808000000001e8a3d5e7400775e3d8a1e0000
+00000000010000000000002c0000000000b5b5bdbb3d81b300b4813dbbbd
+b5b5b5b5b5b5b5b5b5b5b5b5b5c1b5b5b500000967d3ce770d74c6770c77
+ced36709080808086408080808183eb14528080000015f733e58054d0050
+05583e735f010000000058000000001138714021000000b5cb7d42b4b6aa
+00abb6b4427dcbb5b5b5b5b5c6b5b5b5b5b9c49bc6beb50000aed2b43308
+0874c677080833b4d2ae08083188c8821e08080a7ec8a6190800008a3d5e
+2b00004d005000002b5e3d8a00002b534b591700000252074912000000bb
+3d81bfb5b5aa00abb5b5bf813dbbb5b5c09f58abbbb5b5b6a70776bab500
+00ce770d08080874c6770808080c77ce08080882cd5f0808080861798a08
+0800003e58050000004d005000000005583e0000004b2649000000005249
+660000000042b4b6b5b5b5aa00abb5b5b5b6b442b5b5b59a26b9b5b5b5b5
+c2a1b3b5b50000080808080808080808080808080808080808622d540808
+080810081008080000000000000000000000000000000000000000552548
+0000000008000800000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5c4
+bec2b5b5b5b5b7b5b7b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+00080808080808080808080808080808080808080808081c080808080808
+080000000000000000000000000000000000000000000000001400000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5bab5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080886
+200808080808080000000000000000000000000000000000000000000000
+005f190000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5adbcb5b5b5b5b5b500000808080808080808080808080808080808
+0808081196cdc94808080808080000000000000000000000000000000000
+00000000000a7728674100000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b8bc2978c5b5b5b5b5b500000808080808080808080808
+080808080808080808083dada00808080808080000000000000000000000
+0000000000000000000000003555670000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5c17e9fb5b5b5b5b5b500000808080808
+08080808080808080808080808080808240a250908080808080000000000
+0000000000000000000000000000000000001d021e0100000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5bdb5bdb5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/new-zealand.gif b/Docs/Flags/new-zealand.gif
new file mode 100644
index 00000000000..5d74f71ecc0
--- /dev/null
+++ b/Docs/Flags/new-zealand.gif
Binary files differ
diff --git a/Docs/Flags/new-zealand.pdf b/Docs/Flags/new-zealand.pdf
new file mode 100644
index 00000000000..040f8bdb7b0
--- /dev/null
+++ b/Docs/Flags/new-zealand.pdf
Binary files differ
diff --git a/Docs/Flags/kroatia.gif b/Docs/Flags/new-zealand.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/kroatia.gif
+++ b/Docs/Flags/new-zealand.txt
diff --git a/Docs/Flags/norway.eps b/Docs/Flags/norway.eps
new file mode 100755
index 00000000000..af62cbef81f
--- /dev/null
+++ b/Docs/Flags/norway.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: norway.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000000000cf0000cb000000000000000000
+00000000000000000000000000000000000000ecb5b5e900000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf0000cb000000
+00000000000000000000000000000000000000000000000000ecb5b5e900
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6d00808
+d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf
+0000cb000000000000000000000000000000000000000000000000000000
+00ecb5b5e90000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+0000000000cf0000cb000000000000000000000000000000000000000000
+00000000000000ecb5b5e900000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000000000cf0000cb000000000000000000000000000000
+00000000000000000000000000ecb5b5e900000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000000000cf0000cb000000000000000000
+00000000000000000000000000000000000000ecb5b5e900000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf0000cb000000
+00000000000000000000000000000000000000000000000000ecb5b5e900
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6d00808
+d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf
+0000cb000000000000000000000000000000000000000000000000000000
+00ecb5b5e90000000000000000000000000000000000000000d0d0d0d0d0
+d0d0d0b00808b0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000cbcbcb
+cbcbcbcbcbad0000adcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb0000e9
+e9e9e9e9e9e9e9e3b5b5e3e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e900
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000d0d0d0d0d0d0d0d0b00808b0d0d0d0d0d0
+d0d0d0d0d0d0d0d0d0d0d0d0d00000cfcfcfcfcfcfcfcfad0000adcfcfcf
+cfcfcfcfcfcfcfcfcfcfcfcfcfcfcf0000ecececececececece3b5b5e3ec
+ececececececececececececececececec0000c6c6c6c6c6c6c6c6d00808
+d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf
+0000cb000000000000000000000000000000000000000000000000000000
+00ecb5b5e90000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+0000000000cf0000cb000000000000000000000000000000000000000000
+00000000000000ecb5b5e900000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000000000cf0000cb000000000000000000000000000000
+00000000000000000000000000ecb5b5e900000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000000000cf0000cb000000000000000000
+00000000000000000000000000000000000000ecb5b5e900000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf0000cb000000
+00000000000000000000000000000000000000000000000000ecb5b5e900
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6d00808
+d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c600000000000000000000cf
+0000cb000000000000000000000000000000000000000000000000000000
+00ecb5b5e90000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+0000000000cf0000cb000000000000000000000000000000000000000000
+00000000000000ecb5b5e900000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6d00808d0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000000000cf0000cb000000000000000000000000000000
+00000000000000000000000000ecb5b5e900000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/norway.gif b/Docs/Flags/norway.gif
new file mode 100755
index 00000000000..e88d1029f3e
--- /dev/null
+++ b/Docs/Flags/norway.gif
Binary files differ
diff --git a/Docs/Flags/norway.pdf b/Docs/Flags/norway.pdf
new file mode 100644
index 00000000000..aaddf8c5ec4
--- /dev/null
+++ b/Docs/Flags/norway.pdf
Binary files differ
diff --git a/Docs/Flags/kroatia.txt b/Docs/Flags/norway.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/kroatia.txt
+++ b/Docs/Flags/norway.txt
diff --git a/Docs/Flags/philippines.eps b/Docs/Flags/philippines.eps
new file mode 100644
index 00000000000..9c3b242568a
--- /dev/null
+++ b/Docs/Flags/philippines.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: philippines.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000a91d080808080808080808080808080808080808080808
+080808080808080000a71600000000000000000000000000000000000000
+0000000000000000000000e2bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000f7e45a0808080808080808080808080808
+080808080808080808080808080000f6e354000000000000000000000000
+0000000000000000000000000000000000f3efcbb5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000f7fdf9a91d080808080808
+080808080808080808080808080808080808080000f6f8f5a71600000000
+0000000000000000000000000000000000000000000000eb3bbae2bbb5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000f9fdf9f7e4
+5a0808080808080808080808080808080808080808080808080000f5f8f5
+f7e3540000000000000000000000000000000000000000000000000000c8
+4fb2f7f2ccb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+00f7f8f7f7f7f7a91d080808080808080808080808080808080808080808
+080000f7f6f7f7f7f7a71600000000000000000000000000000000000000
+0000000000f7eaf7f7f7f7e2bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b50000f7f7f7f7f7f8f7e45a0808080808080808080808080808
+080808080808080000f7f7f7f7f6f5f7e354000000000000000000000000
+0000000000000000000000f7f7f7f7e8d8f7f2ccb5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000f7f7f8f7f9fbf7f8f7a91d080808080808
+080808080808080808080808080000f7f7f5f7f5f0f7f5f6a71600000000
+0000000000000000000000000000000000f7f7dcf7c785f7e1f2e2bbb5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000f7f7fcfafafdf8fcf9f7e4
+5a0808080808080808080808080808080808080000f7f6eef2f5f2f6eef3
+f7e3540000000000000000000000000000000000000000f7f26eaba44bd6
+66b9f7f2ccb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000f7f7f7feff
+fffffaf7f7f7f7a91d080808080808080808080808080808080000f7f7f6
+f4fffffcf2f7f7f7f7a616000000000000000000000000000000000000f7
+f7ea2800000290f7f7f7f7dfbbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+00f7fafafffffffffdfaf8f7fafbe45a0808080808080808080808080808
+080000f7f2f1fefffffff7f2f4f7f5f6e354000000000000000000000000
+0000000000f5a49c0100000048a4caf79d71f2ccb5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b50000f7fafafffffffffdfaf8f7fbfdf4d7c4c4c4c4c4c4c4c4
+c4c4c4c4c4c4c40000f7f2f1fefffffff7f2f4f7f5f9e255000000000000
+0000000000000000000000f4a49c0200000049a4caf68a43c75602020202
+02020202020202020202020000f7f7f7fefffffffaf7f7f7f7e8cbc6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000f7f7f6f4fffffcf2f7f7f7f7a61600
+0000000000000000000000000000000000f7f7ea2800000290f7f7f7f793
+16000000000000000000000000000000000000f7f7fcfafafdf8fcf9f7f3
+d7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000f7f6eef2f5f2f6eef3
+f7e4550000000000000000000000000000000000000000f7f26eaba44bd6
+66b9f7e4560000000000000000000000000000000000000000f7f7f8f7f9
+fbf7f8f7e8cbc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000f7f7f5
+f7f5f0f7f5f6a816000000000000000000000000000000000000000000f7
+f7dcf7c785f7e1f2a8160000000000000000000000000000000000000000
+00f7f7f7f7f7f8f7f3d7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000f7f7f7f7f6f5f7e455000000000000000000000000000000000000
+0000000000f7f7f7f7e8d8f7e45600000000000000000000000000000000
+00000000000000f7f7f7f7f7f7e8cbc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000f7f6f7f7f7f7a81600000000000000000000000000
+0000000000000000000000f7edf7f7f7f7a8160000000000000000000000
+00000000000000000000000000f8fcf9f7f3d7c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000f6f8f5f7e455000000000000000000
+0000000000000000000000000000000000d553adf7e45600000000000000
+00000000000000000000000000000000000000f8fdfae8cbc6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000f6f8f5a81600000000
+0000000000000000000000000000000000000000000000e642ada8160000
+00000000000000000000000000000000000000000000000000f7f4d7c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000f7e355
+0000000000000000000000000000000000000000000000000000000000f7
+d95600000000000000000000000000000000000000000000000000000000
+00e8cbc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000a81600000000000000000000000000000000000000000000000000
+0000000000a8160000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/philippines.gif b/Docs/Flags/philippines.gif
new file mode 100644
index 00000000000..884f2a5e8d2
--- /dev/null
+++ b/Docs/Flags/philippines.gif
Binary files differ
diff --git a/Docs/Flags/philippines.pdf b/Docs/Flags/philippines.pdf
new file mode 100644
index 00000000000..0b6639c24db
--- /dev/null
+++ b/Docs/Flags/philippines.pdf
Binary files differ
diff --git a/Docs/Flags/south-africa1.txt b/Docs/Flags/philippines.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/Docs/Flags/south-africa1.txt
+++ b/Docs/Flags/philippines.txt
diff --git a/Docs/Flags/poland.eps b/Docs/Flags/poland.eps
index 40d4363a515..06c580e1625 100644
--- a/Docs/Flags/poland.eps
+++ b/Docs/Flags/poland.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: poland.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-010101010101010101010101010101010101010101010101010101010101
-010101010101010101010101010101010101010101010101010101010101
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7
+c7c7c7c7c7c7c70000030303030303030303030303030303030303030303
+030303030303030303000003030303030303030303030303030303030303
+03030303030303030303030000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/poland.gif b/Docs/Flags/poland.gif
index 756f9398ee3..902b49f745d 100644
--- a/Docs/Flags/poland.gif
+++ b/Docs/Flags/poland.gif
Binary files differ
diff --git a/Docs/Flags/poland.pdf b/Docs/Flags/poland.pdf
new file mode 100644
index 00000000000..e2c696dda21
--- /dev/null
+++ b/Docs/Flags/poland.pdf
Binary files differ
diff --git a/Docs/Flags/portugal.eps b/Docs/Flags/portugal.eps
index 7bd24809850..01a83ecd6d1 100644
--- a/Docs/Flags/portugal.eps
+++ b/Docs/Flags/portugal.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: portugal.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-00000000000000033b6cd2cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b4bcc16033010000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-00000000000035c390a0dbe0e5cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5badfd4d58e93ba2900000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-000000000035e6bf77a5cdbed1eac9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5bae6bb5194581086da26000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000003c33fe2c4b7b8c8e0e3e0c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b4dfb8973e68614691b7b2000000000000000000000000000000
-0000000000000000342f302f000000000000000000000000000000000000
-000000003b904ebae65668e2bde5dec7c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5bcd4bf04e05064cd12b7b1240000000000000000000000000000
-0000000000000000e0cbd0cd000000000000000000000000000000000000
-0000000065dd91d658222963d7dad7d2c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5c4e4d26e501b2252737b7d530000000000000000000000000000
-0000000000000000b8bcbea8000000000000000000000000000000000000
-0000000064d0c8e363272e6ededaefcec6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5c4dbdb9a5b2027618c9aea4d0000000000000000000000000000
-0000000000000000babdc0aa000000000000000000000000000000000000
-00000000369700a6d95668d5bedce4c5c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5bad6b511a75064941e85bc1e0000000000000000000000000000
-00000000000000009bcbd088000000000000000000000000000000000000
-0000000001ba8fc8f7939df6d0cde3c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b4d7d097ce3f4fca874fae000000000000000000000000000000
-000000000000000006484503000000000000000000000000000000000000
-00000000002bdfc497a3bcd8e4e8c8c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b9e1dca73124a9d0d31e000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-00000000000029b9a3abdee3e3c8c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b9dcd9d89aa6ae1d00000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-00000000000000002859cfc7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b7bb4d20000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-0000000000000000000ac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000002c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b30000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000002c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b30000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000002c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b30000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000002c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b30000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000013462d2cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b4bac35d31010000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000002ec0989ddde0e6cac6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b9ded7d49795bc2c00000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000002ee3bd749ccfbdd0eacac6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b9e5bc5991610a80db2c
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000001c046dfc5bbbb
+c4e2e3e2c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b4debb9d3b
+65653b9ab3bc010000000000000000000000000000000000000000000000
+002b29292b00000000000000000000000000000000000000000000000034
+9843b8e45f5fe4bbe6dec8c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5bad7bd08d85959d807bfaf2f0000000000000000000000000000000000
+00000000000000d8cdcdd800000000000000000000000000000000000000
+000000000060da9ecf63282863d4d9d4d5c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5c3e3d6685822225868796d610000000000000000000000
+00000000000000000000000000b4bebeb400000000000000000000000000
+000000000000000000000061d5c9e35f26265fe3d8efd1c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5c4dcdda3551f1f559b8fea5c0000000000
+00000000000000000000000000000000000000b1bdbdb100000000000000
+0000000000000000000000000000000000349801a3d75f5fd7bce0e3c7c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5bad7b414a25959a21596b5
+2e0000000000000000000000000000000000000000000000009acdcd9a00
+000000000000000000000000000000000000000000000001bc81c3f69292
+f6cfcbe6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b4d9cc91ca
+4a4aca8141bb010000000000000000000000000000000000000000000000
+000751510700000000000000000000000000000000000000000000000000
+2de2c9a4a6bbd9e2ebc9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b9e3ddad281fafccdf2b000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000002fc0989ddde0e6c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5baded7d49795bc2b00000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000013462d2cac6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b4bac35d31010000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000002c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5b30000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000002c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5b5b5b5
+b30000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000002c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5
+b5b5b5b5b5b5b30000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+0000000000000000000002c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000b5b5b5b5b5b5b5b5b5b30000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/portugal.gif b/Docs/Flags/portugal.gif
index 91bf32addb2..add53255d60 100644
--- a/Docs/Flags/portugal.gif
+++ b/Docs/Flags/portugal.gif
Binary files differ
diff --git a/Docs/Flags/portugal.pdf b/Docs/Flags/portugal.pdf
new file mode 100644
index 00000000000..d1f66f846db
--- /dev/null
+++ b/Docs/Flags/portugal.pdf
Binary files differ
diff --git a/Docs/Flags/romania.eps b/Docs/Flags/romania.eps
index 03b53f502a1..c20a7b6871b 100644
--- a/Docs/Flags/romania.eps
+++ b/Docs/Flags/romania.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: romania.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
-08080808080808080815fffffffffffffffffffac6c6c6c6c6c6c6c6c6c6
-0000000000000000000dffffffffffffffffffe800000000000000000000
-b5b5b5b5b5b5b5b5b5ab0000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808080bffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003fffffffffffffffffffc00
+0000000000000000000000b5b5b5b5b5b5b5b5b5b3000000000000000000
+000000000000000000000000000808080808080808080bffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003ffffffffff
+fffffffffc000000000000000000000000b5b5b5b5b5b5b5b5b5b3000000
+000000000000000000000000000000000000000808080808080808080bff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03fffffffffffffffffffc000000000000000000000000b5b5b5b5b5b5b5
+b5b5b3000000000000000000000000000000000000000000000808080808
+080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003fffffffffffffffffffc000000000000000000000000b5
+b5b5b5b5b5b5b5b5b3000000000000000000000000000000000000000000
+000808080808080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003fffffffffffffffffffc00000000000000
+0000000000b5b5b5b5b5b5b5b5b5b3000000000000000000000000000000
+000000000000000808080808080808080bffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003fffffffffffffffffffc00
+0000000000000000000000b5b5b5b5b5b5b5b5b5b3000000000000000000
+000000000000000000000000000808080808080808080bffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003ffffffffff
+fffffffffc000000000000000000000000b5b5b5b5b5b5b5b5b5b3000000
+000000000000000000000000000000000000000808080808080808080bff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03fffffffffffffffffffc000000000000000000000000b5b5b5b5b5b5b5
+b5b5b3000000000000000000000000000000000000000000000808080808
+080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003fffffffffffffffffffc000000000000000000000000b5
+b5b5b5b5b5b5b5b5b3000000000000000000000000000000000000000000
+000808080808080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003fffffffffffffffffffc00000000000000
+0000000000b5b5b5b5b5b5b5b5b5b3000000000000000000000000000000
+000000000000000808080808080808080bffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003fffffffffffffffffffc00
+0000000000000000000000b5b5b5b5b5b5b5b5b5b3000000000000000000
+000000000000000000000000000808080808080808080bffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003ffffffffff
+fffffffffc000000000000000000000000b5b5b5b5b5b5b5b5b5b3000000
+000000000000000000000000000000000000000808080808080808080bff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03fffffffffffffffffffc000000000000000000000000b5b5b5b5b5b5b5
+b5b5b3000000000000000000000000000000000000000000000808080808
+080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003fffffffffffffffffffc000000000000000000000000b5
+b5b5b5b5b5b5b5b5b3000000000000000000000000000000000000000000
+000808080808080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003fffffffffffffffffffc00000000000000
+0000000000b5b5b5b5b5b5b5b5b5b3000000000000000000000000000000
+000000000000000808080808080808080bffffffffffffffffffffc6c6c6
+c6c6c6c6c6c6c6000000000000000000000003fffffffffffffffffffc00
+0000000000000000000000b5b5b5b5b5b5b5b5b5b3000000000000000000
+000000000000000000000000000808080808080808080bffffffffffffff
+ffffffc6c6c6c6c6c6c6c6c6c6000000000000000000000003ffffffffff
+fffffffffc000000000000000000000000b5b5b5b5b5b5b5b5b5b3000000
+000000000000000000000000000000000000000808080808080808080bff
+ffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000000000000000
+03fffffffffffffffffffc000000000000000000000000b5b5b5b5b5b5b5
+b5b5b3000000000000000000000000000000000000000000000808080808
+080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6c60000000000
+00000000000003fffffffffffffffffffc000000000000000000000000b5
+b5b5b5b5b5b5b5b5b3000000000000000000000000000000000000000000
+000808080808080808080bffffffffffffffffffffc6c6c6c6c6c6c6c6c6
+c6000000000000000000000003fffffffffffffffffffc00000000000000
+0000000000b5b5b5b5b5b5b5b5b5b3000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/romania.gif b/Docs/Flags/romania.gif
index 2d38df262bf..a6ffa4ad0c2 100644
--- a/Docs/Flags/romania.gif
+++ b/Docs/Flags/romania.gif
Binary files differ
diff --git a/Docs/Flags/romania.pdf b/Docs/Flags/romania.pdf
new file mode 100644
index 00000000000..45503c541bf
--- /dev/null
+++ b/Docs/Flags/romania.pdf
Binary files differ
diff --git a/Docs/Flags/russia.eps b/Docs/Flags/russia.eps
index 85c5899d891..ce1e2cb22c1 100644
--- a/Docs/Flags/russia.eps
+++ b/Docs/Flags/russia.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: russia.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3
-a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0
-e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0
-080808080808080808080808080808080808080808080808080808080808
000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-080808080808080808080808080808080808080808080808080808080808
-000000000000000000000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-909090909090909090909090909090909090909090909090909090909090
-000000000000000000000000000000000000000000000000000000000000
-333333333333333333333333333333333333333333333333333333333333
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9
+a9a9a9a9a9a9a9a9a9a9a9a9a90000a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000e2e2e2e2e2e2e2e2e2e2e2e2e2
+e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e200000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500008686868686
+868686868686868686868686868686868686868686868686860000000000
+00000000000000000000000000000000000000000000000000000000003d
+3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d00
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/russia.gif b/Docs/Flags/russia.gif
index f72e7f78da6..f76e19d7f1b 100644
--- a/Docs/Flags/russia.gif
+++ b/Docs/Flags/russia.gif
Binary files differ
diff --git a/Docs/Flags/russia.pdf b/Docs/Flags/russia.pdf
new file mode 100644
index 00000000000..84c304cba32
--- /dev/null
+++ b/Docs/Flags/russia.pdf
Binary files differ
diff --git a/Docs/Flags/singapore.eps b/Docs/Flags/singapore.eps
index bc5faf248a7..5ebedcb4f94 100644
--- a/Docs/Flags/singapore.eps
+++ b/Docs/Flags/singapore.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: singapore.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6cbc9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000001180d0000000000000000000000000000000000000000000000
-0000000001180e0000000000000000000000000000000000000000000000
-c6c6c6d7ecd6c7c6c8c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00000054bd5004000b000000000000000000000000000000000000000000
-00000054bd5004000b000000000000000000000000000000000000000000
-c6c6d8f4cdc6c6c8e9ccc6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000059e72200000aae1f0000000000000000000000000000000000000000
-000059e72200000aae1f0000000000000000000000000000000000000000
-c6c7f3dfc6c7c9c6cfc8c6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0004e07d000410002c0b0015000000000000000000000000000000000000
-0004e07d000410002d0b0015000000000000000000000000000000000000
-c6cff7d2c6dbe0c6c6c6d6e5c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-002af73e0067830000004d9b010000000000000000000000000000000000
-002bf73f0067830000004e9c010000000000000000000000000000000000
-c6cef7d3c6c9c9c6c6c6c9c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0029f740000d0d0000000d0d000000000000000000000000000000000000
-0029f740000d0d0000000d0d000000000000000000000000000000000000
-c6c7f2e0c6c6c7c9c6c6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0003dd810000060e00001500000000000000000000000000000000000000
-0003dd810000060e00001500000000000000000000000000000000000000
-c6c6d7f4cec6dcdfc6d4e6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000052e927006c7e0048a102000000000000000000000000000000000000
-000053e927006d7e0048a102000000000000000000000000000000000000
-c6c6c6d5ebd8cbc9c6c9c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000004bb859160d000d0e00000000000000000000000000000000000000
-0000004bb85a160d000d0e00000000000000000000000000000000000000
-c8c8c8c8c8cbcac8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-070707070716100707070707070707070707070707070707070707070707
-070707070716100707070707070707070707070707070707070707070707
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6cbc9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000170e0000000000000000000000000000
+00000000000000000000000000000000170e000000000000000000000000
+00000000000000000000000000c6c6c6d6ecd7c7c6c8c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000000050bd5405000a000000000000
+000000000000000000000000000000000000000050bd5405000a00000000
+00000000000000000000000000000000000000c6c6d7f4cdc6c6c8e8cdc6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000055e925000008aa
+2400000000000000000000000000000000000000000000000055e9250000
+08aa2400000000000000000000000000000000000000000000c6c7f2e0c6
+c6cac6cfc9c6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c600000003de
+81000211002c0e0013000000000000000000000000000000000000000000
+03de82000211002d0e001400000000000000000000000000000000000000
+00c6cef7d3c6dae1c6c6c6d3e7c7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000028f74200618900000042a5020000000000000000000000000000
+00000000000028f74200618900000043a503000000000000000000000000
+00000000000000c6cef7d3c6c9c9c6c6c6c9c9c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000028f742000f0f0000000e0f000000000000000000
+00000000000000000000000028f742000f0f0000000e1000000000000000
+00000000000000000000000000c6c7f2e0c6c6c7c9c6c6cac6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c600000003de810000030f00001300000000
+00000000000000000000000000000000000003de820000030f0000130000
+00000000000000000000000000000000000000c6c6d7f4cdc6dae0c6d2e8
+c7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000055e92500658400
+3ea8030000000000000000000000000000000000000000000055e9250065
+84003ea8030000000000000000000000000000000000000000c6c6c6d6ec
+d7cac9c6c9cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+50bd541510000f1200000000000000000000000000000000000000000000
+000050bd541510000f120000000000000000000000000000000000000000
+00c6c6c6c6c6cbc9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000170e0000000000000000000000000000000000000000
+00000000000000000000170e000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4
+f4f4f4f4f4f4f4f4f40000f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4
+f4f4f4f4f4f4f4f4f4f4f40000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/singapore.gif b/Docs/Flags/singapore.gif
index 7fbd3f87f62..38b06409764 100644
--- a/Docs/Flags/singapore.gif
+++ b/Docs/Flags/singapore.gif
Binary files differ
diff --git a/Docs/Flags/singapore.pdf b/Docs/Flags/singapore.pdf
new file mode 100644
index 00000000000..1d2666f851c
--- /dev/null
+++ b/Docs/Flags/singapore.pdf
Binary files differ
diff --git a/Docs/Flags/slovenia.eps b/Docs/Flags/slovenia.eps
new file mode 100755
index 00000000000..59b6482f5fa
--- /dev/null
+++ b/Docs/Flags/slovenia.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: slovenia.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7ad4d463b3b3b5340
+e5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f77d221a0f0f0f
+2814c0f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7ad8a8f97
+97978593c7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f79b43
+330d39085d18e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+753c2c0533005811bcf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7b58a95b291b576a9c6f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f79b08080c55080808e2f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7750000054f000000bcf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7b5b5b5b281b5b5b5c6f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f79b0808149a080808e2f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f77500000c97000000bcf7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7b5b5b5b8ddb5b5b5c6f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000a9a9a9763f3a74f52f6316a6a9a9a9a9a9
+a9a9a9a9a9a9a9a9a9a9a9a9a90000a7a7a74f393370f5295e0e7fa7a7a7
+a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000e2e2e2aac4c3d3f7c0ceb9b6e2
+e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2000008080836dae0e0f7cbf5aa
+2108080808080808080808080808080808080800000000000cd9dfdff7c9
+f59c000000000000000000000000000000000000000000b5b5b597eff1f1
+f7ebf6d59eb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000008080822bd
+c3e9f7d8c1a0080808080808080808080808080808080808080000000000
+05d1e8f3f7eee792000000000000000000000000000000000000000000b5
+b5b5a3e0f5f7f7f6f5bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080872c3b5c1b1bf3d080808080808080808080808080808080808
+0800000000000059e8e4e7e2dd1f00000000000000000000000000000000
+0000000000b5b5b5b5a8f5f5f5f5eb9fb5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080812c0e0c4eb8308080808080808080808080808
+080808080808080000000000000096f0e8f0510000000000000000000000
+0000000000000000000000b5b5b5b5acb8f6f5f3a0b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b50000080808080816abf0770908080808080808
+08080808080808080808080808000000000000000179dc44000000000000
+0000000000000000000000000000000000b5b5b5b5b5aaaade9cb4b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080925080808
+080808080808080808080808080808080808080000000000000000000200
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b4
+9bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500008686868686
+868686868686868686868686868686868686868686868686860000000000
+00000000000000000000000000000000000000000000000000000000003d
+3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d00
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/slovenia.gif b/Docs/Flags/slovenia.gif
new file mode 100644
index 00000000000..2cac6590840
--- /dev/null
+++ b/Docs/Flags/slovenia.gif
Binary files differ
diff --git a/Docs/Flags/slovenia.pdf b/Docs/Flags/slovenia.pdf
new file mode 100644
index 00000000000..b00ca0e6467
--- /dev/null
+++ b/Docs/Flags/slovenia.pdf
Binary files differ
diff --git a/mit-pthreads/machdep/linux-2.0/extra/bits/pthreadtypes.h b/Docs/Flags/slovenia.txt
index e69de29bb2d..e69de29bb2d 100644..100755
--- a/mit-pthreads/machdep/linux-2.0/extra/bits/pthreadtypes.h
+++ b/Docs/Flags/slovenia.txt
diff --git a/Docs/Flags/south-africa.eps b/Docs/Flags/south-africa.eps
index 702df9d4e6a..6c080095104 100644
--- a/Docs/Flags/south-africa.eps
+++ b/Docs/Flags/south-africa.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: south-africa.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-0000001fb8e6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5bde6a3140000000000000000000000000000000000000000000000
-0000001fb8a4140000000000000000000000000000000000000000000000
-000000000169e9d6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5d1df5100000000000000000000000000000000000000000000
-000000000169d85100000000000000000000000000000000000000000000
-00000000000023bde6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5bee8a3140000000000000000000000000000000000000000
-00000000000023bda3140000000000000000000000000000000000000000
-080000000000000370ebd6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b7b5b5b5b5b5b5b6d3df5100000000000000000000000000000000000000
-000000000000000370da5100000000000000000000000000000000000000
-db480000000000000028c3e6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-f5cab5b5b5b5b5b5b5c0e9a3140000000000000000000000000000000000
-00000000000000000028c3a3140000000000000000000000000000000000
-4bddac1d0000000000000477edd6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-4bdde7bdb5b5b5b5b5b5b6d5e05100000000000000000000000000000000
-000000000000000000000477dc5100000000000000000000000000000000
-000982eb74050000000000002dc8e6d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8
-000982f4d7b6b5b5b5b5b5b5c1eaa45a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
-0000000000000000000000002dc8a45a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
-00000025b8d23d00000000000005769f9f9f9f9f9f9f9f9f9f9f9f9f9f9f
-00000025b8f2c7b5b5b5b5b5b5b6d5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0
-0000000000000000000000000005769f9f9f9f9f9f9f9f9f9f9f9f9f9f9f
-000000000054e19f15000000000000000000000000000000000000000000
-000000000054e2e3bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
-0000000000000c8ae9670100000000000000000000000000000000000000
-0000000000000c8af6d3b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
-000000000000159ee1530000000000000000000000000000000000000000
-000000000000159ef6cdb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
000000000000000000000000000000000000000000000000000000000000
-000000000268e88b0c000000000000000000000000000000000000000000
-000000000268ecdeb9b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000001eb6e7cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000b5b5b5bde6a7160000000000000000000000000000
+00000000000000000000000000001eb6a716000000000000000000000000
+00000000000000000000000000000000000167e8d7c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5d1e05400000000000000
+0000000000000000000000000000000000000000000167d9540000000000
+0000000000000000000000000000000000000000000000000022bce7cac6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b5b5b5b5b5b5bee7a7
+160000000000000000000000000000000000000000000000000000000022
+bca716000000000000000000000000000000000000000000000700000000
+0000026eead7c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000b7b5b5
+b5b5b5b5b6d2e15400000000000000000000000000000000000000000000
+000000000000026edb540000000000000000000000000000000000000000
+00d9450000000000000026c1e7cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000f4c9b5b5b5b5b5b5b5bfe9a7160000000000000000000000000000
+000000000000000000000000000026c1a716000000000000000000000000
+0000000000000050e0a81a0000000000000374ecd7c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6000050e0e6bdb5b5b5b5b5b5b6d4e25400000000000000
+0000000000000000000000000000000000000000000374dd540000000000
+00000000000000000000000000000b87eb70040000000000002bc6e7d7d7
+d7d7d7d7d7d7d7d7d7d7d7d7d70000000b87f5d6b6b5b5b5b5b5b5c0eaa7
+53535353535353535353535353535300000000000000000000000000002b
+c6a7545454545454545454545454545454000000000028bdcf3900000000
+00000576a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7000000000028bdf1c6b5b5
+b5b5b5b5b6d5e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2000000000000000000
+0000000000000576a7a7a7a7a7a7a7a7a7a7a7a7a7a7a700000000000000
+59e49b130000000000000000000000000000000000000000000000000000
+000059e5e2bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000
000000000000000000000000000000000000000000000000000000000000
-00000034cac22c0000000000000b89b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3
-00000034caedc2b5b5b5b5b5b5b8dae5e5e5e5e5e5e5e5e5e5e5e5e5e5e5
-000000000000000000000000000b89b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3
-001195e760010000000000003cd4944c4c4c4c4c4c4c4c4c4c4c4c4c4c4c
-001195f6d1b5b5b5b5b5b5b5c5ed90464646464646464646464646464646
-0000000000000000000000003cd5dcc8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-5fe79812000000000000098ad64508080808080808080808080808080808
-5fe8e1bab5b5b5b5b5b5b7dad63f00000000000000000000000000000000
-00000000000000000000098aecc6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-cd360000000000000036cf93130808080808080808080808080808080808
-f1c5b5b5b5b5b5b5b5c4eb900c0000000000000000000000000000000000
-00000000000000000036d1dcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-030000000000000783d54508080808080808080808080808080808080808
-b6b5b5b5b5b5b5b7d8d63f00000000000000000000000000000000000000
-000000000000000783ebc6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-00000000000031cb94140808080808080808080808080808080808080808
-b5b5b5b5b5b5c2ea910c0000000000000000000000000000000000000000
-00000000000031ccdcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-00000000057dd44608080808080808080808080808080808080808080808
-b5b5b5b5b6d6d64000000000000000000000000000000000000000000000
-00000000057deac6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0000002ac795140808080808080808080808080808080808080808080808
-b5b5b5c0ea920c0000000000000000000000000000000000000000000000
-0000002ac7dcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000e90e86301000000000000000000000000000000000000
+0000000000000000000e90f6d2b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5000000000000000000000000000000000000000000000000000000
+000000000000000000000000000e90e86301000000000000000000000000
+0000000000000000000000000000000e90f6d2b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5000000000000000000000000000000000000000000
+00000000000000000000000000000000000059e49b130000000000000000
+000000000000000000000000000000000000000059e5e2bbb5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000000000000000000
+0000000000000000000000000000000000000000000028bdcf3900000000
+00000576a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7000000000028bdf1c6b5b5
+b5b5b5b5b6d5e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2000000000000000000
+0000000000000576a7a7a7a7a7a7a7a7a7a7a7a7a7a7a70000000b87eb70
+040000000000002bc6a95959595959595959595959595959590000000b87
+f5d6b6b5b5b5b5b5b5c0eaa7535353535353535353535353535353000000
+00000000000000000000002bc6e2cbcbcbcbcbcbcbcbcbcbcbcbcbcbcb00
+0050e0a81a0000000000000374dd5a080808080808080808080808080808
+08000050e0e6bdb5b5b5b5b5b5b6d4e25400000000000000000000000000
+0000000000000000000000000000000374ebccb5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b50000d9450000000000000026c1a91d08080808080808080808
+080808080808080000f4c9b5b5b5b5b5b5b5bfe9a7160000000000000000
+000000000000000000000000000000000000000026c1e2bbb5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5000007000000000000026edb5a080808080808
+080808080808080808080808080000b7b5b5b5b5b5b5b6d2e15400000000
+000000000000000000000000000000000000000000000000026ee9ccb5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5000000000000000022bcaa1d08
+080808080808080808080808080808080808080000b5b5b5b5b5b5bee7a8
+160000000000000000000000000000000000000000000000000000000022
+bce2bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000000000001
+67da5b080808080808080808080808080808080808080808080000b5b5b5
+b5b5d1e15500000000000000000000000000000000000000000000000000
+0000000167e7ccb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000000001eb6aa1d08080808080808080808080808080808080808080808
+080000b5b5b5bde6a8160000000000000000000000000000000000000000
+00000000000000001eb6e2bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/south-africa.gif b/Docs/Flags/south-africa.gif
index 7fd4ced4469..3ed8559eb2a 100644
--- a/Docs/Flags/south-africa.gif
+++ b/Docs/Flags/south-africa.gif
Binary files differ
diff --git a/Docs/Flags/south-africa.pdf b/Docs/Flags/south-africa.pdf
new file mode 100644
index 00000000000..6b6286a7794
--- /dev/null
+++ b/Docs/Flags/south-africa.pdf
Binary files differ
diff --git a/Docs/Flags/south-africa1.eps b/Docs/Flags/south-africa1.eps
deleted file mode 100644
index 702df9d4e6a..00000000000
--- a/Docs/Flags/south-africa1.eps
+++ /dev/null
@@ -1,87 +0,0 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Creator: pnmtops
-%%Title: noname.ps
-%%Pages: 1
-%%BoundingBox: 291 371 320 391
-%%EndComments
-/readstring {
- currentfile exch readhexstring pop
-} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
-%%EndProlog
-%%Page: 1 1
-gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
-{ rpicstr readstring }
-{ gpicstr readstring }
-{ bpicstr readstring }
-true 3
-colorimage
-0000001fb8e6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5bde6a3140000000000000000000000000000000000000000000000
-0000001fb8a4140000000000000000000000000000000000000000000000
-000000000169e9d6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5d1df5100000000000000000000000000000000000000000000
-000000000169d85100000000000000000000000000000000000000000000
-00000000000023bde6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b5b5b5b5b5b5bee8a3140000000000000000000000000000000000000000
-00000000000023bda3140000000000000000000000000000000000000000
-080000000000000370ebd6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-b7b5b5b5b5b5b5b6d3df5100000000000000000000000000000000000000
-000000000000000370da5100000000000000000000000000000000000000
-db480000000000000028c3e6cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-f5cab5b5b5b5b5b5b5c0e9a3140000000000000000000000000000000000
-00000000000000000028c3a3140000000000000000000000000000000000
-4bddac1d0000000000000477edd6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-4bdde7bdb5b5b5b5b5b5b6d5e05100000000000000000000000000000000
-000000000000000000000477dc5100000000000000000000000000000000
-000982eb74050000000000002dc8e6d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8
-000982f4d7b6b5b5b5b5b5b5c1eaa45a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
-0000000000000000000000002dc8a45a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
-00000025b8d23d00000000000005769f9f9f9f9f9f9f9f9f9f9f9f9f9f9f
-00000025b8f2c7b5b5b5b5b5b5b6d5e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0
-0000000000000000000000000005769f9f9f9f9f9f9f9f9f9f9f9f9f9f9f
-000000000054e19f15000000000000000000000000000000000000000000
-000000000054e2e3bbb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-0000000000000c8ae9670100000000000000000000000000000000000000
-0000000000000c8af6d3b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-000000000000159ee1530000000000000000000000000000000000000000
-000000000000159ef6cdb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-000000000268e88b0c000000000000000000000000000000000000000000
-000000000268ecdeb9b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-000000000000000000000000000000000000000000000000000000000000
-00000034cac22c0000000000000b89b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3
-00000034caedc2b5b5b5b5b5b5b8dae5e5e5e5e5e5e5e5e5e5e5e5e5e5e5
-000000000000000000000000000b89b3b3b3b3b3b3b3b3b3b3b3b3b3b3b3
-001195e760010000000000003cd4944c4c4c4c4c4c4c4c4c4c4c4c4c4c4c
-001195f6d1b5b5b5b5b5b5b5c5ed90464646464646464646464646464646
-0000000000000000000000003cd5dcc8c8c8c8c8c8c8c8c8c8c8c8c8c8c8
-5fe79812000000000000098ad64508080808080808080808080808080808
-5fe8e1bab5b5b5b5b5b5b7dad63f00000000000000000000000000000000
-00000000000000000000098aecc6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-cd360000000000000036cf93130808080808080808080808080808080808
-f1c5b5b5b5b5b5b5b5c4eb900c0000000000000000000000000000000000
-00000000000000000036d1dcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-030000000000000783d54508080808080808080808080808080808080808
-b6b5b5b5b5b5b5b7d8d63f00000000000000000000000000000000000000
-000000000000000783ebc6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-00000000000031cb94140808080808080808080808080808080808080808
-b5b5b5b5b5b5c2ea910c0000000000000000000000000000000000000000
-00000000000031ccdcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-00000000057dd44608080808080808080808080808080808080808080808
-b5b5b5b5b6d6d64000000000000000000000000000000000000000000000
-00000000057deac6b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0000002ac795140808080808080808080808080808080808080808080808
-b5b5b5c0ea920c0000000000000000000000000000000000000000000000
-0000002ac7dcb8b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-grestore
-showpage
-%%Trailer
diff --git a/Docs/Flags/south-africa1.gif b/Docs/Flags/south-africa1.gif
deleted file mode 100644
index 7fd4ced4469..00000000000
--- a/Docs/Flags/south-africa1.gif
+++ /dev/null
Binary files differ
diff --git a/Docs/Flags/south-korea.eps b/Docs/Flags/south-korea.eps
index a363ab514c4..8147ce78acf 100644
--- a/Docs/Flags/south-korea.eps
+++ b/Docs/Flags/south-korea.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: south-korea.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f7
-f7f7f7f7f7f7eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f7
-f7f7f7f7f7f7eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f7
-f7f7f7f7f7985ad7f7f7f7f7f7f7f7f7f7f7f7f7f7f7c255d3f7f7f7f7f7
-f7f7f7f7f7985ad7f7f7f7f7f7f7f7f7f7f7f7f7f7f7c255d3f7f7f7f7f7
-f7f7f7f7f7985ad7f7f7f7f7f7f7f7f7f7f7f7f7f7f7c255d3f7f7f7f7f7
-f7f7f7f7d6434363f7f7f7f7f7f7f7f7f7f7f7f7f7f0474476f6f7f7f7f7
-f7f7f7f7d6434363f7f7f7f7f7f7f7f7f7f7f7f7f7f0474476f6f7f7f7f7
-f7f7f7f7d6434363f7f7f7f7f7f7f7f7f7f7f7f7f7f0474476f6f7f7f7f7
-f7f7f7f7584345e4f7f7f7f7f7f6f1f1f7f7f7f7f7f7ba5a4391f7f7f7f7
-f7f7f7f7584345e4f7f7f7f7f7f4d7d9f5f7f7f7f7f7ba5a4391f7f7f7f7
-f7f7f7f7584345e4f7f7f7f7f7f4d8d9f5f7f7f7f7f7ba5a4391f7f7f7f7
-f7f7f7f7d65ab0f7f7f7f7f5decac6c6cbe0f6f7f7f7f76570dcf7f7f7f7
-f7f7f7f7d65ab0f7f7f7f7ef791300001884f3f7f7f7f76570dcf7f7f7f7
-f7f7f7f7d65ab0f7f7f7f7ef791300001885f3f7f7f7f76570dcf7f7f7f7
-f7f7f7f7f7f3f7f7f7f7f5d2c6c6c6c6c6c6d6f7f7f7f7ecf4f7f7f7f7f7
-f7f7f7f7f7f3f7f7f7f7ed3a0000000000004ef4f7f7f7ecf4f7f7f7f7f7
-f7f7f7f7f7f3f7f7f7f7ed3a0000000000004ef4f7f7f7ecf4f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7d9c6c6c6c6c6c6c6c6e3f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f76c00000000000000008ff7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f76e00000000000000008ff7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7eebbc6c6c6c6bc68548ecef7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7ee0a000000000000000026f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f41600000000095a6d3526f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7c8b1c6c6c6c53908080875f5f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7c600000000000000000001eaf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7ea140000000187b5b5b54eeaf7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7c75fc6c6c66a080808082cf4f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7c500000000000000000000e7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7ea6300000058b5b5b5b593e8f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7ed114b6b36080808080838f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7ed0900000000000000001df7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f4b7755789b5b5b5b5b5a9f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f76b080808080808080884f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f76600000000000000007ef7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7d0b5b5b5b5b5b5b5b5d5f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7eef6f7f7f7ea3508080808080844f1f7f7f7ecedf7f7f7f7f7
-f7f7f7f7f7eef6f7f7f7e92f0000000000003ef1f7f7f7ecedf7f7f7f7f7
-f7f7f7f7f7eef6f7f7f7f3c1b5b5b5b5b5b5c6f5f7f7f7ecedf7f7f7f7f7
-f7f7f7f7cd569af7f7f7f7eb70140808187bf0f7f7f7f76b60d6f7f7f7f7
-f7f7f7f7cd569af7f7f7f7ea6b0c00001177f0f7f7f7f76b60d6f7f7f7f7
-f7f7f7f7cd569af7f7f7f7f4d2b8b5b5b9d5f5f7f7f7f76b60d6f7f7f7f7
-f7f7f7f7604b52dff7f7f7f7f7f1d0d2f3f7f7f7f7f7b4794787f7f7f7f7
-f7f7f7f7604b52dff7f7f7f7f7f1cfd1f3f7f7f7f7f7b4794787f7f7f7f7
-f7f7f7f7604b52dff7f7f7f7f7f5ecedf6f7f7f7f7f7b4794787f7f7f7f7
-f7f7f7f7e0504563f7f7f7f7f7f7f7f7f7f7f7f7f7f14a4678f5f7f7f7f7
-f7f7f7f7e0504563f7f7f7f7f7f7f7f7f7f7f7f7f7f14a4678f5f7f7f7f7
-f7f7f7f7e0504563f7f7f7f7f7f7f7f7f7f7f7f7f7f14a4678f5f7f7f7f7
-f7f7f7f7f79c64ddf7f7f7f7f7f7f7f7f7f7f7f7f7f7d060d8f7f7f7f7f7
-f7f7f7f7f79c64ddf7f7f7f7f7f7f7f7f7f7f7f7f7f7d060d8f7f7f7f7f7
-f7f7f7f7f79c64ddf7f7f7f7f7f7f7f7f7f7f7f7f7f7d060d8f7f7f7f7f7
-f7f7f7f7f7f7f4f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f4f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f4f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f0f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f6f7f7f7f7f7f70000f7f7f7f7f7f7f0f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f6f7f7f7f7f7f70000f7f7f7f7f7f7f0f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f6f7f7f7f7f7f70000f7f7f7f7f79f58d5f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7d05ac3f7f7f7f7f70000f7f7f7f7f79f58d5f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7d05ac3f7f7f7f7f70000f7f7f7f7f79f58
+d5f7f7f7f7f7f7f7f7f7f7f7f7f7f7d05ac3f7f7f7f7f70000f7f7f7f7db
+43435df7f7f7f7f7f7f7f7f7f7f7f7f7f54d446ef1f7f7f7f70000f7f7f7
+f7db43435df7f7f7f7f7f7f7f7f7f7f7f7f7f54d446ef1f7f7f7f70000f7
+f7f7f7db43435df7f7f7f7f7f7f7f7f7f7f7f7f7f54d446ef1f7f7f7f700
+00f7f7f7f75a4344dff7f7f7f7f7f7f2f2f7f7f7f7f7f7c660447df7f7f7
+f70000f7f7f7f75a4344dff7f7f7f7f7f6dddcf6f7f7f7f7f7c660447df7
+f7f7f70000f7f7f7f75a4344dff7f7f7f7f7f6dddcf6f7f7f7f7f7c66044
+7df7f7f7f70000f7f7f7f7d659a7f7f7f7f7f6e0cbc6c6cbe0f6f7f7f7f7
+7261d4f7f7f7f70000f7f7f7f7d659a7f7f7f7f7f3851a00001780f2f7f7
+f7f77261d4f7f7f7f70000f7f7f7f7d659a7f7f7f7f7f3851a00001880f2
+f7f7f7f77261d4f7f7f7f70000f7f7f7f7f7f2f7f7f7f7f6d4c6c6c6c6c6
+c6d4f6f7f7f7eef0f7f7f7f7f70000f7f7f7f7f7f2f7f7f7f7f246000000
+00000044f2f7f7f7eef0f7f7f7f7f70000f7f7f7f7f7f2f7f7f7f7f24600
+000000000044f2f7f7f7eef0f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7dc
+c6c6c6c6c6c6c6c6dff7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f77a000000000000000080f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f77d000000000000000080f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f3b9c6c6c6c6c173598ecbf7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f311000000000000000017f5f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f62000000000054f683517f5f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7d2abc6c6c6c6490808086cf1f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7d000000000000000000000d8f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7ed1a0000000078b5b5b556d8f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7cf5cc6c6c67c080808081ef0f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7ce00000000000000000000d3
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7ec6500000046b5b5b5b5
+a0d4f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f113507544080808
+080825f6f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f10b00000000
+000000000bf2f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f5b8714e
+7cb5b5b5b5b5a7f2f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f76e
+08080808080808086cf7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f76a000000000000000065f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7d1b5b5b5b5b5b5b5b5cef7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f2f7f7f7f7ea3408080808080830e8f7f7f7f4ecf7f7f7f7f70000f7f7f7
+f7f7f2f7f7f7f7ea2d00000000000029e7f7f7f7f4ecf7f7f7f7f70000f7
+f7f7f7f7f2f7f7f7f7f3c1b5b5b5b5b5b5c0f3f7f7f7f4ecf7f7f7f7f700
+00f7f7f7f7d85f9df7f7f7f7e9690f08080e65e7f7f7f7f7845bd7f7f7f7
+f70000f7f7f7f7d85f9df7f7f7f7e9640800000660e6f7f7f7f7845bd7f7
+f7f7f70000f7f7f7f7d85f9df7f7f7f7f3d0b7b5b5b7cff3f7f7f7f7845b
+d7f7f7f7f70000f7f7f7f75f4650e1f7f7f7f7f7ecc3c2eaf7f7f7f7f7ca
+78486cf7f7f7f70000f7f7f7f75f4650e1f7f7f7f7f7ebc1c0eaf7f7f7f7
+f7ca78486cf7f7f7f70000f7f7f7f75f4650e1f7f7f7f7f7f4e9e8f3f7f7
+f7f7f7ca78486cf7f7f7f70000f7f7f7f7dd534961f7f7f7f7f7f7f7f7f7
+f7f7f7f7f6504671ebf7f7f7f70000f7f7f7f7dd534961f7f7f7f7f7f7f7
+f7f7f7f7f7f7f6504671ebf7f7f7f70000f7f7f7f7dd534961f7f7f7f7f7
+f7f7f7f7f7f7f7f7f6504671ebf7f7f7f70000f7f7f7f7f79659d1f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7d359bff7f7f7f7f70000f7f7f7f7f79659d1f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7d359bff7f7f7f7f70000f7f7f7f7f79659
+d1f7f7f7f7f7f7f7f7f7f7f7f7f7f7d359bff7f7f7f7f70000f7f7f7f7f7
+f6eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f70000f7f7f7
+f7f7f6eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f70000f7
+f7f7f7f7f6eff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f5f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f700000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/south-korea.gif b/Docs/Flags/south-korea.gif
index 0d8630ba963..f9a74adc732 100644
--- a/Docs/Flags/south-korea.gif
+++ b/Docs/Flags/south-korea.gif
Binary files differ
diff --git a/Docs/Flags/south-korea.pdf b/Docs/Flags/south-korea.pdf
new file mode 100644
index 00000000000..877d792caa8
--- /dev/null
+++ b/Docs/Flags/south-korea.pdf
Binary files differ
diff --git a/Docs/Flags/spain.eps b/Docs/Flags/spain.eps
index 340fe9c7671..bd318f2160a 100644
--- a/Docs/Flags/spain.eps
+++ b/Docs/Flags/spain.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: spain.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7
-040404040404040404040404040404040404040404040404040404040404
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-fdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfd
+00000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc
+fcfcfcfcfcfcfcfcfc000000000000000000000000000000000000000000
+00000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff000000000000000000
+00000000000000000000000000000000000000000000000000ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff000000000000000000000000000000000000000000000000000000
+00000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff000000000000000000000000000000000000000000
+00000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff000000000000000000
+00000000000000000000000000000000000000000000000000ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff000000000000000000000000000000000000000000000000000000
+00000000000000c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7
+c7c7c7c7c7c7c70000030303030303030303030303030303030303030303
+030303030303030303000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000000000000000000000000000000000000000000000000000000000
-fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc
-f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/spain.gif b/Docs/Flags/spain.gif
index 9d2e1be0fe7..f5ad336b00d 100644
--- a/Docs/Flags/spain.gif
+++ b/Docs/Flags/spain.gif
Binary files differ
diff --git a/Docs/Flags/spain.pdf b/Docs/Flags/spain.pdf
new file mode 100644
index 00000000000..2606d779597
--- /dev/null
+++ b/Docs/Flags/spain.pdf
Binary files differ
diff --git a/Docs/Flags/sweden.eps b/Docs/Flags/sweden.eps
index 47cd1fa3e9c..18a7c8765ba 100644
--- a/Docs/Flags/sweden.eps
+++ b/Docs/Flags/sweden.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: sweden.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0e0e0e0e0e0e0e16fffffff10e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e
-060606060606060efffffff0060606060606060606060606060606060606
-b1b1b1b1b1b1b1ab0000000ab1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1
-fefefefefefefefefffffffffefefefefefefefefefefefefefefefefefe
-fefefefefefefefefffffffffefefefefefefefefefefefefefefefefefe
-010101010101010100000000010101010101010101010101010101010101
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-f3f3f3f3f3f3f3f3fffffffef3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-f3f3f3f3f3f3f3f3fffffffef3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3
-080808080808080800000000080808080808080808080808080808080808
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-0808080808080810fffffff1080808080808080808080808080808080808
-0000000000000008fffffff0000000000000000000000000000000000000
-b5b5b5b5b5b5b5af0000000bb5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808fffffffc0808080808080808080808
+0808080808080800000000000000000000fffffffc000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808fffffffc0808080808
+0808080808080808080808080800000000000000000000fffffffc000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b500000002b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808ffffff
+fc08080808080808080808080808080808080800000000000000000000ff
+fffffc0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808fffffffc0808080808080808080808080808080808080000000000
+0000000000fffffffc0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808fffffffc0808080808080808080808080808080808
+0800000000000000000000fffffffc000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808fffffffc0808080808080808080808
+0808080808080800000000000000000000fffffffc000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808fffffffc0808080808
+0808080808080808080808080800000000000000000000fffffffc000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b500000002b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808ffffff
+fc08080808080808080808080808080808080800000000000000000000ff
+fffffc0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000fcfcfcfcfc
+fcfcfcfffffffffcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc0000fcfcfc
+fcfcfcfcfcfffffffffcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc000002
+020202020202020000000002020202020202020202020202020202020200
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff000000000000000000000000000000000000000000000000000000
+00000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff000000000000000000000000000000000000000000
+00000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff000000000000000000000000000000
+000000000000000000000000000000000000000808080808080808ffffff
+fc08080808080808080808080808080808080800000000000000000000ff
+fffffc0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808fffffffc0808080808080808080808080808080808080000000000
+0000000000fffffffc0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808fffffffc0808080808080808080808080808080808
+0800000000000000000000fffffffc000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808fffffffc0808080808080808080808
+0808080808080800000000000000000000fffffffc000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808fffffffc0808080808
+0808080808080808080808080800000000000000000000fffffffc000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b500000002b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808ffffff
+fc08080808080808080808080808080808080800000000000000000000ff
+fffffc0000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808fffffffc0808080808080808080808080808080808080000000000
+0000000000fffffffc0000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808fffffffc0808080808080808080808080808080808
+0800000000000000000000fffffffc000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b500000002b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/sweden.gif b/Docs/Flags/sweden.gif
index e16ede8e641..df7151b5aa8 100644
--- a/Docs/Flags/sweden.gif
+++ b/Docs/Flags/sweden.gif
Binary files differ
diff --git a/Docs/Flags/sweden.pdf b/Docs/Flags/sweden.pdf
new file mode 100644
index 00000000000..718d57600fd
--- /dev/null
+++ b/Docs/Flags/sweden.pdf
Binary files differ
diff --git a/Docs/Flags/switzerland.eps b/Docs/Flags/switzerland.eps
index 517919e3125..635eef9f80a 100644
--- a/Docs/Flags/switzerland.eps
+++ b/Docs/Flags/switzerland.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: switzerland.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c7c7c7c7c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000404040400000000000000000000000000
-000000000000000000000000000404040400000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c8c8c8cbf7f7f7f4c8c8c8c8c6c6c6c6c6c6c6c6c6
-00000000000000000008080817f7f7f7e708080807000000000000000000
-00000000000000000008080817f7f7f7e708080807000000000000000000
-c6c6c6c6c6c6c6c6c9f7f7f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-c6c6c6c6c6c6c6c6c9f7f7f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-c6c6c6c6c6c6c6c6c9f7f7f7f7f7f7f7f7f7f7f7f3c6c6c6c6c6c6c6c6c6
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-00000000000000000cf7f7f7f7f7f7f7f7f7f7f7e3000000000000000000
-c6c6c6c6c6c6c6c6c8f5f5f5f5f7f7f7f7f5f5f5f1c6c6c6c6c6c6c6c6c6
-00000000000000000beeeeeeeff7f7f7f6eeeeeeda000000000000000000
-00000000000000000cefefefeff7f7f7f6efefefdb000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f7f7f7f4c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000ff7f7f7e700000000000000000000000000
-00000000000000000000000010f7f7f7e700000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c9f5f5f5f2c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000000000000000000000feaeaeada00000000000000000000000000
-0000000000000000000000000febebebdb00000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c7f7f7f7f7c6c6c6c6c6c6c6c6c6c6c6c6
+c6000000000000000000000000000003f7f7f7f700000000000000000000
+000000000000000000000000000000000003f7f7f7f70000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c7f7f7f7f7c6c6c6c6c6c6
+c6c6c6c6c6c6c6000000000000000000000000000003f7f7f7f700000000
+000000000000000000000000000000000000000000000003f7f7f7f70000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c7f7f7f7f7
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000000000000000000000000003f7f7
+f7f700000000000000000000000000000000000000000000000000000003
+f7f7f7f7000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c7f7f7f7f7c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+00000003f7f7f7f700000000000000000000000000000000000000000000
+000000000003f7f7f7f7000000000000000000000000000000c6c6c6c6c6
+c6c6c6c7f7f7f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6c60000000000
+000000000003f7f7f7f7f7f7f7f7f7f7f7f7000000000000000000000000
+0000000000000003f7f7f7f7f7f7f7f7f7f7f7f700000000000000000000
+00c6c6c6c6c6c6c6c6c7f7f7f7f7f7f7f7f7f7f7f7f7c6c6c6c6c6c6c6c6
+c60000000000000000000003f7f7f7f7f7f7f7f7f7f7f7f7000000000000
+0000000000000000000000000003f7f7f7f7f7f7f7f7f7f7f7f700000000
+00000000000000c6c6c6c6c6c6c6c6c7f7f7f7f7f7f7f7f7f7f7f7f7c6c6
+c6c6c6c6c6c6c60000000000000000000003f7f7f7f7f7f7f7f7f7f7f7f7
+0000000000000000000000000000000000000003f7f7f7f7f7f7f7f7f7f7
+f7f70000000000000000000000c6c6c6c6c6c6c6c6c7f7f7f7f7f7f7f7f7
+f7f7f7f7c6c6c6c6c6c6c6c6c60000000000000000000003f7f7f7f7f7f7
+f7f7f7f7f7f70000000000000000000000000000000000000003f7f7f7f7
+f7f7f7f7f7f7f7f70000000000000000000000c6c6c6c6c6c6c6c6c6c7c7
+c7c8f7f7f7f7c7c7c7c7c6c6c6c6c6c6c6c6c60000000000000000000000
+03030306f7f7f7f703030303000000000000000000000000000000000000
+000003030306f7f7f7f7030303030000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c7f7f7f7f7c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+00000000000000000003f7f7f7f700000000000000000000000000000000
+000000000000000000000003f7f7f7f70000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c7f7f7f7f7c6c6c6c6c6c6c6c6c6c6c6c6
+c6000000000000000000000000000003f7f7f7f700000000000000000000
+000000000000000000000000000000000003f7f7f7f70000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c7f7f7f7f7c6c6c6c6c6c6
+c6c6c6c6c6c6c6000000000000000000000000000003f7f7f7f700000000
+000000000000000000000000000000000000000000000003f7f7f7f70000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c7c7c7c7
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000303
+030300000000000000000000000000000000000000000000000000000000
+03030303000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/switzerland.gif b/Docs/Flags/switzerland.gif
index 98cef7c28d6..8212d226678 100644
--- a/Docs/Flags/switzerland.gif
+++ b/Docs/Flags/switzerland.gif
Binary files differ
diff --git a/Docs/Flags/switzerland.pdf b/Docs/Flags/switzerland.pdf
new file mode 100644
index 00000000000..26935b96dfc
--- /dev/null
+++ b/Docs/Flags/switzerland.pdf
Binary files differ
diff --git a/Docs/Flags/taiwan.eps b/Docs/Flags/taiwan.eps
index a514bdf2af4..a57a8242464 100644
--- a/Docs/Flags/taiwan.eps
+++ b/Docs/Flags/taiwan.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: taiwan.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-080808080808081108080808080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000900000000000000000000000000000000000000000000
-b5b5b5b5b5b5b5b7b5b5b5b5b5b5aa000000000000000000000000000000
-0808080808490e9e11450808080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000043069a0a3f0000000000000000000000000000000000000000
-b5b5b5b5b5c7b7deb8c6b5b5b5b5aa000000000000000000000000000000
-0808080e14658bb28d59170c080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000060c6087b089530f04000000000000000000000000000000000000
-b5b5b5b7b8cfd9e4dacbb9b6b5b5aa000000000000000000000000000000
-0808080baba1f7f7f7a0a009080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00000003a89ef7f7f79d9c00000000000000000000000000000000000000
-b5b5b5b6e2dff7f7f7dfdfb5b5b5aa000000000000000000000000000000
-0808082b5becf7f7f7e06025080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000002456ecf7f7f7df5b1e000000000000000000000000000000000000
-b5b5b5bfccf4f7f7f7f1cdbdb5b5aa000000000000000000000000000000
-0808082556eaf7f7f7de5a20080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000001e50eaf7f7f7dd5418000000000000000000000000000000000000
-b5b5b5bdcaf3f7f7f7f0ccbcb5b5aa000000000000000000000000000000
-0808080bb099f7f7f799a509080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00000004ad96f7f7f795a201000000000000000000000000000000000000
-b5b5b5b6e3ddf7f7f7dde0b5b5b5aa000000000000000000000000000000
-0808080d0e6b82b2855f100b080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-0000000507667eb081590903000000000000000000000000000000000000
-b5b5b5b6b7d0d7e4d7cdb7b6b5b5aa000000000000000000000000000000
-0808080808440c970f410808080813c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-00000000003e0493073b0000000000000000000000000000000000000000
-b5b5b5b5b5c6b6dcb7c5b5b5b5b5aa000000000000000000000000000000
-0e0e0e0e0e0e0e150e0e0e0e0e0e19c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000700000000000000000000000000000000000000000000
-b0b0b0b0b0b0b0b2b0b0b0b0b0b0a6000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
-010101010101010101010101010101000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000080808080808081108080808080808c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000900000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b7b5b5b5b5b5b5b500000000
+000000000000000000000000000808080808470e9e0f470808080808c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000041069a07410000000000
+0000000000000000000000000000000000b5b5b5b5b5c6b7deb7c6b5b5b5
+b5b500000000000000000000000000000000000808080d126289b28b6013
+0d080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000060a5d85b087
+5b0b050000000000000000000000000000000000000000b5b5b5b6b8ced8
+e4d9cdb8b6b5b5b500000000000000000000000000000000000808080aac
+9df7f7f7a0aa0a080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+02a99af7f7f79ca7020000000000000000000000000000000000000000b5
+b5b5b6e2def7f7f7dfe2b6b5b5b500000000000000000000000000000000
+000808082759e8f7f7f7e85b25080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000002053e8f7f7f7e8551e000000000000000000000000000000
+0000000000b5b5b5bdcbf3f7f7f7f3ccbdb5b5b500000000000000000000
+000000000000000808082858e8f7f7f7e85a26080808c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000002052e8f7f7f7e8551f000000000000000000
+0000000000000000000000b5b5b5becbf3f7f7f7f3ccbdb5b5b500000000
+000000000000000000000000000808080aac9cf7f7f79faa09080808c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000000002a999f7f7f79ca701000000
+0000000000000000000000000000000000b5b5b5b5e2def7f7f7dfe2b5b5
+b5b500000000000000000000000000000000000808080e136487b2896113
+0d080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000060b5e83b085
+5c0c050000000000000000000000000000000000000000b5b5b5b7b8ced8
+e4d8ceb8b6b5b5b500000000000000000000000000000000000808080808
+480e9e0f480808080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000042069b074200000000000000000000000000000000000000000000b5
+b5b5b5b5c7b7deb7c7b5b5b5b5b500000000000000000000000000000000
+00080808080808081108080808080808c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000900000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b7b5b5b5b5b5b5b500000000000000000000
+00000000000000c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000002020202020202020202020202020200000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/taiwan.gif b/Docs/Flags/taiwan.gif
index 5cfc3d46425..379afea61ce 100644
--- a/Docs/Flags/taiwan.gif
+++ b/Docs/Flags/taiwan.gif
Binary files differ
diff --git a/Docs/Flags/taiwan.pdf b/Docs/Flags/taiwan.pdf
new file mode 100644
index 00000000000..013b5c16d9a
--- /dev/null
+++ b/Docs/Flags/taiwan.pdf
Binary files differ
diff --git a/Docs/Flags/turkey.eps b/Docs/Flags/turkey.eps
new file mode 100644
index 00000000000..7df5bfe70dc
--- /dev/null
+++ b/Docs/Flags/turkey.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: turkey.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c8d9e4d9c9c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000000000095f97610d0000000000000000000000000000
+00000000000000000000000000095f97610d000000000000000000000000
+00000000000000c6c6c6c6c6c6c6d1f1e4cac6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000000039da951600000000000000000000
+00000000000000000000000000000000000039da96160000000000000000
+00000000000000000000000000c6c6c6c6c6c6d0f5dec6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000000000000033ed78000000000000
+000000000000000000000000000000000000000000000033ee7800000000
+00000000000000000000000000000000000000c6c6c6c6c6c6efeec6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000002ccca02
+0000000000000000000000000000000000000000000000000000000002cc
+ca020000000000000000000000000000000000000000000000c6c6c6c6c6
+d2f7ddc6c6c6c6c6c6d6c8cbc6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+00003af77300000000000051091800000000000000000000000000000000
+000000003af7730000000000005209180000000000000000000000000000
+00c6c6c6c6c6dbf7d5c6c6c6c6c6cbe8f4d4c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000068f74c00000000001babe54600000000000000000000
+0000000000000000000069f74d00000000001babe5460000000000000000
+00000000000000c6c6c6c6c6dbf7d5c6c6c6c6c6cee7f1d9c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000068f74c000000000028a5d85f00000000
+0000000000000000000000000000000069f74d000000000028a5d8600000
+00000000000000000000000000c6c6c6c6c6d2f7ddc6c6c6c6c6c6d5c9c7
+c6c6c6c6c6c6c6c6c6c6c6c6c6000000000000003af77200000000000048
+0d0700000000000000000000000000000000000000003af7730000000000
+00490d07000000000000000000000000000000c6c6c6c6c6c6efeec6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000002ccca02
+0000000000000000000000000000000000000000000000000000000002cc
+ca020000000000000000000000000000000000000000000000c6c6c6c6c6
+c6d0f5dec6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+00000033ed78000000000000000000000000000000000000000000000000
+000000000033ee7800000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6d1f1e4cac6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c600000000000000000039da951600000000000000000000000000000000
+00000000000000000000000039da96160000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c8d9e4d9c9c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c600000000000000000000095f97610d0000000000000000
+00000000000000000000000000000000000000095f97610d000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/turkey.gif b/Docs/Flags/turkey.gif
new file mode 100644
index 00000000000..45064417a3f
--- /dev/null
+++ b/Docs/Flags/turkey.gif
Binary files differ
diff --git a/Docs/Flags/turkey.pdf b/Docs/Flags/turkey.pdf
new file mode 100644
index 00000000000..899624408a8
--- /dev/null
+++ b/Docs/Flags/turkey.pdf
Binary files differ
diff --git a/mit-pthreads/machdep/linux-2.0/socketcall.h b/Docs/Flags/turkey.txt
index e69de29bb2d..e69de29bb2d 100644
--- a/mit-pthreads/machdep/linux-2.0/socketcall.h
+++ b/Docs/Flags/turkey.txt
diff --git a/Docs/Flags/ukraine.eps b/Docs/Flags/ukraine.eps
index fe2436fa554..1cf43b4b53c 100644
--- a/Docs/Flags/ukraine.eps
+++ b/Docs/Flags/ukraine.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: ukraine.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-181818181818181818181818181818181818181818181818181818181818
-b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
-efefefefefefefefefefefefefefefefefefefefefefefefefefefefefef
-1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f
-b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7
-e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8
-fefefefefefefefefefefefefefefefefefefefefefefefefefefefefefe
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-010101010101010101010101010101010101010101010101010101010101
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+000000000000001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00001818181818181818181818181818181818
+181818181818181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefef
+efefefefefefefefefefefefefefefefef00001818181818181818181818
+181818181818181818181818181818181818180000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefef
+efefefefefefefefefefefefefefefefefefefefefefef00001818181818
+181818181818181818181818181818181818181818181818180000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef00001818181818181818181818181818181818181818181818
+181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefefefefefefefef
+efefefefefefefefefefef00001818181818181818181818181818181818
+181818181818181818181818180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefefefefefefefef
+efefefefefefefefefefefefefefefefef00001818181818181818181818
+181818181818181818181818181818181818180000b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000efefefefefefef
+efefefefefefefefefefefefefefefefefefefefefefef00001818181818
+181818181818181818181818181818181818181818181818180000b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b50000ef
+efefefefefefefefefefefefefefefefefefefefefefefefefefefefef00
+001818181818181818181818181818181818181818181818181818181818
+180000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b50000efefefefefefefefefefefefefefefefefefefefefefefefef
+efefefefef0000fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc
+fcfcfcfcfcfcfc0000fefefefefefefefefefefefefefefefefefefefefe
+fefefefefefefefefe000003030303030303030303030303030303030303
+03030303030303030303030000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff000000000000000000
+00000000000000000000000000000000000000000000000000ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff000000000000000000000000000000000000000000000000000000
+00000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffff000000000000000000000000000000000000000000
+00000000000000000000000000ffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffff000000000000000000000000000000
+00000000000000000000000000000000000000ffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffff000000000000000000
+00000000000000000000000000000000000000000000000000ffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffff000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-000000000000000000000000000000000000000000000000000000000000
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/ukraine.gif b/Docs/Flags/ukraine.gif
index b951bef5b2a..77deda40904 100644
--- a/Docs/Flags/ukraine.gif
+++ b/Docs/Flags/ukraine.gif
Binary files differ
diff --git a/Docs/Flags/ukraine.pdf b/Docs/Flags/ukraine.pdf
new file mode 100644
index 00000000000..9731eb218ba
--- /dev/null
+++ b/Docs/Flags/ukraine.pdf
Binary files differ
diff --git a/Docs/Flags/usa.eps b/Docs/Flags/usa.eps
index 31bd9996d11..08d78b8d8e6 100644
--- a/Docs/Flags/usa.eps
+++ b/Docs/Flags/usa.eps
@@ -1,87 +1,98 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
-%%Title: noname.ps
+%%Title: usa.ps
%%Pages: 1
-%%BoundingBox: 291 371 320 391
+%%BoundingBox: 290 385 321 407
%%EndComments
/readstring {
currentfile exch readhexstring pop
} bind def
-/rpicstr 30 string def
-/gpicstr 30 string def
-/bpicstr 30 string def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
%%EndProlog
%%Page: 1 1
gsave
-291.6 371.4 translate
-28.8 19.2 scale
-30 20 8
-[ 30 0 0 -20 0 20 ]
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
-182608340a122c08300e0e31082b1ec6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
-111f002d020a25002907062a00240b000000000000000000000000000000
-b9bdb5c1b6b8bfb5c0b7b7c0b5bfad000000000000000000000000000000
-1a2422331d182b243117183223291fdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc
-121d1a2c1610241c2a0f112b1c2211717171717171717171717171717171
-babdbcc1bbb9bfbdc0b9b9c0bdbeb4717171717171717171717171717171
-0a134413301e134513262813451316f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-020b3e0c29170b3f0c1f210c3f0c0ff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b8c5b8c0bbb8c6b8bdbeb8c6b8b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-28360e54101b430e4e1212500e4029c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9
-212f064e08133d06480b0a49063a17101010101010101010101010101010
-bec2b7cab7bac5b7c8b8b8c9b7c5b1101010101010101010101010101010
-080e580a3f250b5b0a30340a5b0c14d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-00065302391e035603292d02550406616161616161616161616161616161
-b5b7cbb6c4bdb6ccb6c0c1b6ccb6b0616161616161616161616161616161
-2a3d085c0b1b4c0856110f5808492cf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-233700570313460051090753004325f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-bec4b5ccb6bac8b5cab7b7cbb5c7bff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-080c5d084425096008323708600913cccccccccccccccccccccccccccccc
-000458003e1e015b002b30005a01021f1f1f1f1f1f1f1f1f1f1f1f1f1f1f
-b5b6cdb5c5bdb5cdb5c1c2b5cdb5ac1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f
-293f085e0a1a4e0858100e5a084b29d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6
-22390059021348005308065500451b525252525252525252525252525252
-bec4b5cdb6bac8b5cbb7b7ccb5c7b5525252525252525252525252525252
-080c58094222095b083034085a0a16f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-000452013b1b015500292e0055020ff7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-b5b6cbb5c5bcb5ccb5c0c1b5ccb5b9f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-23370e500d19440e4b12114c0e4224cfcfcfcfcfcfcfcfcfcfcfcfcfcfcf
-1b31064a05113e06450a0946063c132f2f2f2f2f2f2f2f2f2f2f2f2f2f2f
-bcc2b7c9b6bac5b7c7b8b8c8b7c5b22f2f2f2f2f2f2f2f2f2f2f2f2f2f2f
-4f504857484d524856494956485155d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3
-494a425142474d4250434351424c47424242424242424242424242424242
-c9c9c7cbc7c8cac7cbc7c7cbc7c9c1424242424242424242424242424242
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2
-3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
-3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e
-d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0
-323232323232323232323232323232323232323232323232323232323232
-323232323232323232323232323232323232323232323232323232323232
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5
-4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e
-4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e
-cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd
-232323232323232323232323232323232323232323232323232323232323
-232323232323232323232323232323232323232323232323232323232323
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
-d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9
-5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d
-5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d
-c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000182608330b112d082e100c32082915c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000101f002d030926002708042b00220e000000000000
+0000000000000000000000b9bdb5c1b6b8bfb5c0b7b6c1b5beb900000000
+000000000000000000000000001a2421341c162d2330151a34212617dcdc
+dcdcdcdcdcdcdcdcdcdcdcdcdc0000121d192d140e261b290d132d1a1f10
+6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f0000babdbcc1bab9bfbcc0b8bac1bc
+bdb96f6f6f6f6f6f6f6f6f6f6f6f6f6f6f0000091246122f21124712232c
+12471308f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000010a400a28190a410a
+1c260a410b00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5b8c6b8c0bcb8
+c6b8bcbfb8c6b8b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7000028370d5510
+18480d4c1411540d3b24cacacacacacacacacacacacacacaca0000213105
+4f08104105460d094e05351d1313131313131313131313131313130000be
+c2b6cab7b9c7b6c8b8b7cab6c3bd13131313131313131313131313131300
+00080d5a0a3e280a5d0a2b3a0a5b0c08d8d8d8d8d8d8d8d8d8d8d8d8d8d8
+d800000005540237210257022433025505005d5d5d5d5d5d5d5d5d5d5d5d
+5d5d5d0000b5b6ccb5c4beb6ccb5bfc3b5ccb6b55d5d5d5d5d5d5d5d5d5d
+5d5d5d5d5d0000293f085d0b18500854140c5c084325f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f700002238005703104a004e0c0456003d1df7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000bec4b5ccb6b9c9b5cab8b6ccb5c5bdf7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000080b5f0842280862082c3e08600b08cdcd
+cdcdcdcdcdcdcdcdcdcdcdcdcd0000000359003c21005c002538005a0300
+2525252525252525252525252525250000b5b6cdb5c5beb5ceb5bfc4b5cd
+b6b525252525252525252525252525252500002940085d0b17510855130c
+5c084424d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5000021390058030f4b004f
+0b0457003e1d4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a0000bec4b5ccb6b9c9
+b5cab8b6ccb5c6bd4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a0000090c560a3e
+24095909283a0a570b09f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000010450
+02381d015401213402510301f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000b5
+b6cbb5c4bdb5cbb5bec3b5cbb6b5f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+002035114b0f1842114515114a11391cd1d1d1d1d1d1d1d1d1d1d1d1d1d1
+d10000192f094507103c093f0e0944093315383838383838383838383838
+3838380000bcc2b7c7b7b9c5b7c6b9b7c7b7c3bb38383838383838383838
+3838383838000047493e523e424d3e4f413e523e4a46d1d1d1d1d1d1d1d1
+d1d1d1d1d1d1d100004143384c383d4738493b384c384440383838383838
+3838383838383838380000c6c7c4c9c4c5c8c4c8c5c4c9c4c7c638383838
+38383838383838383838380000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000d5d5d5d5d5d5d5d5d5d5d5
+d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d500004a4a4a4a4a4a4a4a4a
+4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a00004a4a4a4a4a4a4a
+4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a0000cdcdcdcdcd
+cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd0000252525
+252525252525252525252525252525252525252525252525252525000025
+252525252525252525252525252525252525252525252525252525252500
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8
+d8d8d8d8d8d8d800005d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d
+5d5d5d5d5d5d5d5d5d00005d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d
+5d5d5d5d5d5d5d5d5d5d5d0000cacacacacacacacacacacacacacacacaca
+cacacacacacacacacacacacaca0000121212121212121212121212121212
+121212121212121212121212121212000012121212121212121212121212
+12121212121212121212121212121212120000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000dcdcdcdcdc
+dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc00006f6f6f
+6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f00006f
+6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f00
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
grestore
showpage
%%Trailer
diff --git a/Docs/Flags/usa.gif b/Docs/Flags/usa.gif
index da9f4e27d6c..4d9c261808d 100644
--- a/Docs/Flags/usa.gif
+++ b/Docs/Flags/usa.gif
Binary files differ
diff --git a/Docs/Flags/usa.pdf b/Docs/Flags/usa.pdf
new file mode 100644
index 00000000000..f8bd86fdd1a
--- /dev/null
+++ b/Docs/Flags/usa.pdf
Binary files differ
diff --git a/Docs/Flags/yugoslavia.eps b/Docs/Flags/yugoslavia.eps
index e69de29bb2d..221d510451d 100644
--- a/Docs/Flags/yugoslavia.eps
+++ b/Docs/Flags/yugoslavia.eps
@@ -0,0 +1,98 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: pnmtops
+%%Title: yugoslavia.ps
+%%Pages: 1
+%%BoundingBox: 290 385 321 407
+%%EndComments
+/readstring {
+ currentfile exch readhexstring pop
+} bind def
+/rpicstr 32 string def
+/gpicstr 32 string def
+/bpicstr 32 string def
+%%EndProlog
+%%Page: 1 1
+gsave
+290.64 385.44 translate
+30.72 21.12 scale
+32 22 8
+[ 32 0 0 -22 0 22 ]
+{ rpicstr readstring }
+{ gpicstr readstring }
+{ bpicstr readstring }
+true 3
+colorimage
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808080808080808
+080808080808080808080808080000000000000000000000000000000000
+0000000000000000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808080808080808
+080808080808080808080808080808080808080000000000000000000000
+0000000000000000000000000000000000000000000000b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500000808080808
+080808080808080808080808080808080808080808080808080000000000
+0000000000000000000000000000000000000000000000000000000000b5
+b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b500
+000808080808080808080808080808080808080808080808080808080808
+080000000000000000000000000000000000000000000000000000000000
+0000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b500000808080808080808080808080808080808080808080808
+080808080808080000000000000000000000000000000000000000000000
+0000000000000000000000b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5b5
+b5b5b5b5b5b5b5b5b5b5b500005555555555555555555555555555555555
+555555555555555555555555550000505050505050505050505050505050
+5050505050505050505050505050500000cacacacacacacacacacacacaca
+cacacacacacacacacacacacacacacacaca0000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f700
+00f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000f7f7f7f7f7f7f7
+f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f70000d7d7d7d7d7
+d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d70000535353
+535353535353535353535353535353535353535353535353535353000054
+545454545454545454545454545454545454545454545454545454545400
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c60000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000c6c6c6c6c6c6c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000c6c6c6c6c6
+c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c60000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+00c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6
+c60000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000
+grestore
+showpage
+%%Trailer
diff --git a/Docs/Flags/yugoslavia.gif b/Docs/Flags/yugoslavia.gif
index 650eac242d6..e1dd52a0541 100644
--- a/Docs/Flags/yugoslavia.gif
+++ b/Docs/Flags/yugoslavia.gif
Binary files differ
diff --git a/Docs/Flags/yugoslavia.pdf b/Docs/Flags/yugoslavia.pdf
new file mode 100644
index 00000000000..1156cd257b8
--- /dev/null
+++ b/Docs/Flags/yugoslavia.pdf
Binary files differ
diff --git a/Docs/Images/mysql-logo.gif b/Docs/Images/mysql-logo.gif
index c660e1d1f4f..f8110ddcb93 100644
--- a/Docs/Images/mysql-logo.gif
+++ b/Docs/Images/mysql-logo.gif
Binary files differ
diff --git a/Docs/Makefile.am b/Docs/Makefile.am
index eea93380b35..9a77202a91b 100644
--- a/Docs/Makefile.am
+++ b/Docs/Makefile.am
@@ -21,11 +21,13 @@ info_TEXINFOS = manual.texi
targets = manual.txt mysql.info manual.html
BUILT_SOURCES = $(targets) manual_toc.html include.texi
-EXTRA_DIST = $(noinst_SCRIPTS) $(BUILT_SOURCES) mysqld_error.txt INSTALL-BINARY reservedwords.texi
+EXTRA_DIST = $(noinst_SCRIPTS) $(BUILT_SOURCES) mysqld_error.txt \
+ INSTALL-BINARY reservedwords.texi
all: $(targets) txt_files
-txt_files: ../INSTALL-SOURCE ../COPYING INSTALL-BINARY
+txt_files: ../INSTALL-SOURCE ../COPYING \
+ INSTALL-BINARY ../support-files/MacOSX/ReadMe.txt
CLEAN_FILES: $(BUILD_SOURCES)
touch $(BUILD_SOURCES)
@@ -46,72 +48,133 @@ include.texi: ../configure.in
grep "MYSQL_TCP_PORT_DEFAULT=" ../configure.in | \
sed -e 's;MYSQL_TCP_PORT_DEFAULT=;;' >> $@
+
+#
+# English Manual
+#
+
+# GNU Info
mysql.info: manual.texi include.texi
cd $(srcdir) && $(MAKEINFO) --no-split -I $(srcdir) $<
+# Plain Text
manual.txt: manual.texi include.texi
cd $(srcdir) && \
$(MAKEINFO) -I $(srcdir) --no-headers --no-split --output $@ $<
+# HTML, all in one file
manual.html: manual.texi include.texi $(srcdir)/Support/texi2html
cd $(srcdir) && @PERL@ $(srcdir)/Support/texi2html $(TEXI2HTML_FLAGS) $<
-
manual_toc.html: manual.html
-
-# Fix: add --output-comment with some interesting info?
-# Fix: @image worked with a older version of pdftex.
-# Note: @image will work if we first convert all images to pdf ...
-# is that worth it?
-# Comment: We need to run pdftex 2 times to get the cross references right.
+# PDF, Portable Document Format
manual.pdf: manual.texi
- cat manual.texi | sed -e 's|@image{[^}]*} *||g' > manual-tmp.texi
+ sed -e 's|@image{[^}]*} *||g' <$< >manual-tmp.texi
pdftex --interaction=nonstopmode manual-tmp.texi
texindex manual-tmp.??
pdftex --interaction=nonstopmode manual-tmp.texi
texindex manual-tmp.??
pdftex --interaction=nonstopmode manual-tmp.texi
- mv manual-tmp.pdf manual.pdf
+ mv manual-tmp.pdf $@
rm -f manual-tmp.*
touch $@
-# Target to produce NuSphere Manual
-nusphere.pdf: manual.texi
- cat manual.texi \
- | sed -e 's/@example/@smallexample/g' \
- -e 's/@end example/@end smallexample/g' \
- -e 's/@c ifnusphere //g' \
- -e 's|@image{[^}]*} *||g' \
- > manual-tmp.texi
+# XML, DocBook 4.0
+mysql.xml: manual.texi include.texi
+ $(MAKEINFO) --force --no-ifinfo --docbook $<
+ mv $@ mysql-tmp.xml
+ Support/docbook-fixup.pl <mysql-tmp.xml >$@
+ rm -f mysql-tmp.xml
+
+# Postscript, A4 Paper
+manual_a4.ps: manual.texi include.texi
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' \
+ $(TEXI2DVI) --batch --texinfo --quiet '@afourpaper' $<
+ $(DVIPS) -t a4 manual.dvi -o $@
+ touch $@
+
+# Postscript, US Letter Paper
+manual_letter.ps: manual.texi include.texi
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' \
+ $(TEXI2DVI) --batch $<
+ $(DVIPS) -t letter manual.dvi -o $@
+ touch $@
+
+
+#
+# German Manual
+#
+
+# GNU Info
+mysql.de.info: manual.de.texi include.texi
+ cd $(srcdir) && $(MAKEINFO) --no-split -I $(srcdir) $<
+
+# Plain Text
+manual.de.txt: manual.de.texi include.texi
+ cd $(srcdir) && \
+ $(MAKEINFO) -I $(srcdir) --no-headers --no-split --output $@ $<
+
+# HTML, all in one file
+manual.de.html: manual.de.texi include.texi $(srcdir)/Support/texi2html
+ cd $(srcdir) && @PERL@ $(srcdir)/Support/texi2html $(TEXI2HTML_FLAGS) $<
+manual_toc.de.html: manual.html
+
+# PDF, Portable Document Format
+manual.de.pdf: manual.de.texi
+ sed -e 's|@image{[^}]*} *||g' <$< >manual-tmp.texi
pdftex --interaction=nonstopmode manual-tmp.texi
texindex manual-tmp.??
pdftex --interaction=nonstopmode manual-tmp.texi
texindex manual-tmp.??
pdftex --interaction=nonstopmode manual-tmp.texi
- mv manual-tmp.pdf nusphere.pdf
+ mv manual-tmp.pdf $@
rm -f manual-tmp.*
touch $@
-# Target to produce DocBook XML
-mysql.xml: manual.texi include.texi
- $(MAKEINFO) --force --no-ifinfo --docbook manual.texi
+# XML, DocBook 4.0
+mysql.de.xml: manual.de.texi include.texi
+ $(MAKEINFO) --force --no-ifinfo --docbook $<
+ mv $@ mysql-tmp.xml
+ Support/docbook-fixup.pl <mysql-tmp.xml >$@
+ rm -f mysql-tmp.xml
-# The texi2dvi gives a lot of harmless errors. Just ignore them unless
-# you want to help with the typesetting part.
-# This is the European papersize version
-manual_a4.ps: manual.texi include.texi
+# Postscript, A4 Paper
+manual_a4.de.ps: manual.de.texi include.texi
TEXINPUTS=$(srcdir):$$TEXINPUTS \
MAKEINFO='$(MAKEINFO) -I $(srcdir)' \
$(TEXI2DVI) --batch --texinfo --quiet '@afourpaper' $<
- $(DVIPS) -t a4 manual.dvi -o $@
+ $(DVIPS) -t a4 manual.de.dvi -o $@
touch $@
-# This is the American papersize version
-manual_letter.ps: manual.texi include.texi
+# Postscript, US Letter Paper
+manual_letter.de.ps: manual.de.texi include.texi
TEXINPUTS=$(srcdir):$$TEXINPUTS \
MAKEINFO='$(MAKEINFO) -I $(srcdir)' \
$(TEXI2DVI) --batch $<
- $(DVIPS) -t letter manual.dvi -o $@
+ $(DVIPS) -t letter manual.de.dvi -o $@
+ touch $@
+
+
+#
+# Miscellaneous
+#
+
+# Target to produce NuSphere Manual
+nusphere.pdf: manual.texi
+ sed -e 's/@example/@smallexample/g' \
+ -e 's/@end example/@end smallexample/g' \
+ -e 's/@c ifnusphere //g' \
+ -e 's|@image{[^}]*} *||g' \
+ <$< >manual-tmp.texi
+ pdftex --interaction=nonstopmode manual-tmp.texi
+ texindex manual-tmp.??
+ pdftex --interaction=nonstopmode manual-tmp.texi
+ texindex manual-tmp.??
+ pdftex --interaction=nonstopmode manual-tmp.texi
+ mv manual-tmp.pdf $@
+ rm -f manual-tmp.*
touch $@
# Include images for the manual in the distribution
@@ -130,7 +193,7 @@ dist-hook:
GT = $(srcdir)/Support/generate-text-files.pl
../INSTALL-SOURCE: mysql.info $(GT)
- perl -w $(GT) mysql.info "Installing" "Compatibility" > $@
+ perl -w $(GT) mysql.info "Installing" "Tutorial" > $@
# We put the description for the binary installation here so that
# people who download source wont have to see it. It is moved up to
@@ -139,7 +202,10 @@ INSTALL-BINARY: mysql.info $(GT)
perl -w $(GT) mysql.info "Installing binary" "Installing source" > $@
../COPYING: mysql.info $(GT)
- perl -w $(GT) mysql.info "GPL license" "LGPL license" > $@
+ perl -w $(GT) mysql.info "GPL license" "Function Index" > $@
+
+../support-files/MacOSX/ReadMe.txt: mysql.info $(GT)
+ perl -w $(GT) mysql.info "Mac OS X installation" "NetWare installation" > $@
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/Docs/Support/colspec-fix.pl b/Docs/Support/colspec-fix.pl
new file mode 100755
index 00000000000..6c64edd1441
--- /dev/null
+++ b/Docs/Support/colspec-fix.pl
@@ -0,0 +1,78 @@
+#!/usr/bin/perl -w
+
+#
+# Script to rewrite colspecs from relative values to absolute values
+#
+
+# arjen 2002-03-14 append "cm" specifier to colwidth field.
+
+use strict;
+
+my $table_width = 12.75; # Specify the max width of the table in cm
+my $gutter_width = 0.55; # Specify the width of the gutters in cm
+
+my $str = join '', <>; # Push stdin (or file)
+
+$str =~ s{([\t ]*(<colspec colwidth=\".+?\" />\s*)+)}
+ {&rel2abs($1)}ges;
+
+print STDOUT $str;
+exit;
+
+#
+# Definitions for helper sub-routines
+#
+
+sub msg {
+ print STDERR shift, "\n";
+}
+
+sub rel2abs {
+ my $str = shift;
+ my $colnum = 1;
+
+ my @widths = ();
+ my $total = 0;
+ my $output = '';
+
+ my $gutters;
+ my $content_width;
+ my $total_width;
+ my @num_cache;
+
+ $str =~ /^(\s+)/;
+ my $ws = $1;
+
+ while ($str =~ m/<colspec colwidth="(\d+)\*" \/>/g) {
+ $total += $1;
+ push @widths, $1;
+ }
+
+ msg("!!! WARNING: Total Percent > 100%: $total%") if $total > 100;
+
+ if (! $total) {
+ die 'Something bad has happened - the script believes that there are no columns';
+ }
+
+ $gutters = $#widths * $gutter_width;
+ $content_width = $table_width - $gutters;
+ # Don't forget that $#... is the last offset not the count
+
+ foreach (@widths) {
+ my $temp = sprintf ("%0.2f", $_/100 * $content_width);
+ $total_width += $temp;
+
+ if ($total_width > $content_width) {
+ $temp -= $total_width - $content_width;
+ msg("!!! WARNING: Column width reduced from " .
+ ($temp + ($total_width - $content_width)) . " to $temp !!!");
+ $total_width -= $total_width - $content_width;
+ }
+
+ $output .= $ws . '<colspec colnum="'. $colnum .'" colwidth="'. $temp .'cm" />' . "\n";
+ ++$colnum;
+ push @num_cache, $temp;
+ }
+
+ return $output . "\n$ws";
+}
diff --git a/Docs/Support/docbook-fixup.pl b/Docs/Support/docbook-fixup.pl
new file mode 100755
index 00000000000..48ab085ad3e
--- /dev/null
+++ b/Docs/Support/docbook-fixup.pl
@@ -0,0 +1,200 @@
+#!/usr/bin/perl -w
+
+# Fix the output of `makeinfo --docbook` version 4.0c
+# Convert the broken docbook output to well-formed XML that conforms to the O'Reilly idiom
+# See code for detailed comments
+# Authors: Arjen Lentz and Zak Greant (original code by Jeremy Cole)
+
+use strict;
+
+my $data = '';
+my @apx = ();
+my $apx = '';
+my @nodes = ();
+my $nodes = '';
+
+msg ("-- Post-processing `makeinfo --docbook` output --");
+msg ("** Written to work with makeinfo version 4.0c **\n");
+
+msg ("Discarding DTD - not required by subsequent scripts");
+# <> is a magic filehandle - either reading lines from stdin or from file(s) specified on the command line
+<>;
+
+msg ("Create an XML PI with ISO-8859-1 character encoding");
+$data = "<?xml version='1.0' encoding='ISO-8859-1'?>";
+
+msg ("Get the rest of the data");
+$data = $data . join "", <>;
+
+msg ("Add missing <bookinfo> and <abstract> opening tags");
+# Note the absence of the g (global) pattern modified. This situation can only happen once.
+# ...as soon as we find the first instance, we can stop looking.
+$data =~ s/<book lang="en">/<book lang="en"><bookinfo><abstract>/;
+
+
+# arjen 2002-05-01
+msg ("Processing docbook-prefix special strings");
+$data =~ s/FIXUPmdashFIXUP/\&mdash\;/g;
+
+$data =~ s/FIXUPdoubledashFIXUP/--/g;
+
+$data =~ s/FIXUPstrongFIXUP/<emphasis\ role\=\"bold\">/g;
+$data =~ s/FIXUPendstrongFIXUP/<\/emphasis>/g;
+
+$data =~ s/FIXUPemphFIXUP/<emphasis>/g;
+$data =~ s/FIXUPendemphFIXUP/<\/emphasis>/g;
+
+$data =~ s/FIXUPfileFIXUP/<filename>/g;
+$data =~ s/FIXUPendfileFIXUP/<\/filename>/g;
+
+$data =~ s/FIXUPsampFIXUP/<literal>/g;
+$data =~ s/FIXUPendsampFIXUP/<\/literal>/g;
+
+
+msg ("Removing mailto: from email addresses...");
+$data =~ s/mailto://g;
+
+msg ("Removing INFORMALFIGURE...");
+$data =~ s{<informalfigure>.+?</informalfigure>}
+ {}gs;
+
+msg ("Convert ampersand to XML escape sequence...");
+$data =~ s/&(?!\w+;)/&amp;/g;
+
+# arjen 2002-05-01
+msg ("Changing (TM) to XML escape sequence...");
+$data =~ s/MySQL \(TM\)/MySQL&trade;/g;
+$data =~ s{<command>TM</command>}
+ {&trade;}g;
+
+# arjen 2002-05-01
+msg ("Changing ' -- ' to XML escape sequence...");
+$data =~ s/ -- /&mdash;/g;
+
+msg ("Changing @@ to @...");
+$data =~ s/@@/@/g;
+
+msg ("Rework references of the notation '<n>'");
+# Need to talk to Arjen about what the <n> bits are for
+$data =~ s/<(\d)>/[$1]/g;
+
+msg ("Changing '_' to '-' in references...");
+$data =~ s{((?:id|linkend)=\".+?\")}
+ {&underscore2hyphen($1)}gex;
+
+msg ("Changing ULINK to SYSTEMITEM...");
+$data =~ s{<ulink url=\"(.+?)\">\s*</ulink>}
+ {<systemitem role=\"url\">$1</systemitem>}gs;
+
+msg ("Adding PARA inside ENTRY...");
+$data =~ s{<entry>(.*?)</entry>}
+ {<entry><para>$1</para></entry>}gs;
+
+msg ("Fixing spacing problem with titles...");
+$data =~ s{(</\w+>)(\w{2,})}
+ {$1 $2}gs;
+
+msg ("Adding closing / to XREF and COLSPEC tags...");
+$data =~ s{<(xref|colspec) (.+?)>}
+ {<$1 $2 />}gs;
+
+# arjen 2002-04-26
+msg ("Removing separate target titles from LINKs and make them XREFs...");
+$data =~ s{<link (linkend=.+?)>.+?</link>}
+ {<xref $1 />}gs;
+
+# Probably need to strip these
+msg ('Adding "See " to XREFs that used to be @xref...');
+$data =~ s{([.'!)])\s*<xref }
+ {$1 See <xref }gs;
+
+msg ('Adding "see " to (XREFs) that used to be (@pxref)...');
+$data =~ s{([([,;])(\s*)<xref }
+ {$1$2see <xref }gs;
+
+msg ("Making first row in table THEAD...");
+$data =~ s{( *)<tbody>(\s*<row>.+?</row>)}
+ {$1<thead>$2\n$1</thead>\n$1<tbody>}gs;
+
+msg ("Removing EMPHASIS inside THEAD...");
+$data =~ s{<thead>(.+?)</thead>}
+ {"<thead>".&strip_tag($1, 'emphasis')."</thead>"}gsex;
+
+msg ("Removing empty PARA...");
+$data =~ s{<para>\s*</para>}
+ {}gs;
+
+msg ("Removing lf before /PARA in ENTRY...");
+$data =~ s{\n(</para></entry>)}
+ {$1}gs;
+
+msg ("Removing whitespace before /PARA if not on separate line...");
+$data =~ s{(\S+)[\t ]+</para>}
+ {$1</para>}g;
+
+msg ("Removing PARA around INDEXTERM if no text in PARA...");
+$data =~ s{<para>((?:<indexterm role=\"[^"]+\">(?:<(primary|secondary)>[^>]+</\2>)+?</indexterm>)+?)\s*</para>}
+ {$1}gs;
+
+@apx = ("Users", "MySQL Testimonials", "News", "GPL-license", "LGPL-license");
+
+foreach $apx (@apx) {
+ msg ("Removing appendix $apx...");
+ $data =~ s{<appendix id=\"$apx\">(.+?)</appendix>}
+ {}gs;
+
+ # Skip to next appendix regex if the regex did not match anything
+ next unless (defined $&);
+
+ msg ("...Building list of removed nodes...");
+
+ # Split the last bracketed regex match into an array
+ # Extract the node names from the tags and push them into an array
+ foreach (split "\n", $&) {
+ push @nodes, $1 if /<\w+ id=\"(.+?)\">/
+ }
+}
+
+# 2002-02-22 arjen@mysql.com (added fix " /" to end of regex, to make it match)
+msg ("Fixing references to removed nodes...");
+# Merge the list of node names into a set of regex alternations
+$nodes = join "|", @nodes;
+
+# Find all references to removed nodes and convert them to absolute URLs
+$data =~ s{<\w+ linkend="($nodes)" />}
+ {&xref2link($1)}ges;
+
+print STDOUT $data;
+exit;
+
+#
+# Definitions for helper sub-routines
+#
+
+sub msg {
+ print STDERR "docbook-fixup:", shift, "\n";
+}
+
+sub strip_tag($$) {
+ (my $str, my $tag) = @_;
+ $str =~ s{<$tag>(.+?)</$tag>}{$1}gs;
+ return $str;
+}
+
+sub underscore2hyphen($) {
+ my $str = shift;
+ $str =~ tr/_/-/;
+ return $str;
+}
+
+sub xref2link {
+ my $ref = shift;
+ $ref =~ tr/ /_/;
+ $ref =~ s{^((.)(.).+)$}{$2/$3/$1.html};
+ return "http://www.mysql.com/doc/" . $ref;
+}
+
+# We might need to encode the high-bit characters to ensure proper representation
+# msg ("Converting high-bit characters to entities");
+# $data =~ s/([\200-\400])/&get_entity($1)>/gs;
+# There is no get_entity function yet - no point writing it til we need it :)
diff --git a/Docs/Support/docbook-prefix.pl b/Docs/Support/docbook-prefix.pl
new file mode 100755
index 00000000000..e76d84dbfe0
--- /dev/null
+++ b/Docs/Support/docbook-prefix.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/perl -w
+
+# Preprocess the input of `makeinfo --docbook` version 4.0c
+# Authors: Arjen Lentz and Zak Greant (started by arjen 2002-05-01)
+
+use strict;
+
+my $data = '';
+
+msg ("-- Pre-processing `makeinfo --docbook` input --");
+msg ("** Written to work with makeinfo version 4.0c **\n");
+
+# <> is a magic filehandle - either reading lines from stdin or from file(s) specified on the command line
+msg ("Get the data");
+$data = join "", <>;
+
+msg ("Replacing '\@-' with FIXUPmdashFIXUP");
+$data =~ s/\@-/FIXUPmdashFIXUP/g;
+
+msg ("Replacing '--' with FIXUPdoubledashFIXUP");
+$data =~ s/--/FIXUPdoubledashFIXUP/g;
+
+msg ("Turning \@strong{} into LITERAL blocks");
+$data =~ s/\@strong\{(.*?)\}/FIXUPstrongFIXUP$1FIXUPendstrongFIXUP/gs;
+
+msg ("Turning \@emph{} into LITERAL blocks");
+$data =~ s/\@emph\{(.*?)\}/FIXUPemphFIXUP$1FIXUPendemphFIXUP/gs;
+
+msg ("Turning \@file{} into LITERAL blocks");
+$data =~ s/\@file\{(.*?)\}/FIXUPfileFIXUP$1FIXUPendfileFIXUP/gs;
+
+msg ("Turning \@samp{} into LITERAL blocks");
+$data =~ s/\@samp\{\@\{\}/FIXUPsampFIXUP\@\{FIXUPendsampFIXUP/g;
+$data =~ s/\@samp\{\@\}\}/FIXUPsampFIXUP\@\}FIXUPendsampFIXUP/g;
+$data =~ s/\@samp\{\@\{n\@\}\}/FIXUPsampFIXUP\@\{n\@\}FIXUPendsampFIXUP/g;
+$data =~ s/\@samp\{(.*?)\}/FIXUPsampFIXUP$1FIXUPendsampFIXUP/gs;
+
+
+msg ("Write the data");
+print STDOUT $data;
+exit;
+
+#
+# Definitions for helper sub-routines
+#
+
+sub msg {
+ print STDERR "docbook-prefix: ", shift, "\n";
+}
+
diff --git a/Docs/Support/docbook-split b/Docs/Support/docbook-split
new file mode 100755
index 00000000000..eafb437efe4
--- /dev/null
+++ b/Docs/Support/docbook-split
@@ -0,0 +1,70 @@
+#! /usr/bin/perl -w
+# O'Reilly's Perl script to chop mysql.xml into separate ch/apps/index files.
+# The indexes are actually not used, they're created straight from the xrefs.
+# Breaks the MySQL reference manual into chapters, appendices, and indexes.
+
+use strict;
+
+my $app_letter = "a"; # Start appendix letters at "a"
+my $chap_num = 1; # Start chapter numbers at one (there is no preface)
+my $directory = "mysql_refman_" . time;
+my $ext = ".xml";
+my $line = "";
+my $output_name = "";
+my $start_text = "";
+
+mkdir $directory unless -d $directory;
+
+while (defined $line) {
+ if ($line =~ /(<chapter.+)/i ) {
+ $start_text = $1;
+ $output_name = sprintf("ch%02d%s", $chap_num, $ext);
+ ++$chap_num;
+ &process_file("chapter");
+ }
+ elsif ($line =~ /(<appendix.+)/i ) {
+ $start_text = $1 ;
+ $output_name = "app$app_letter$ext";
+ ++$app_letter;
+ &process_file("appendix");
+ }
+ elsif ($line =~ /(<index\s+id=")(.*?)(">.*)/i ) {
+ $start_text = $1 . $2 . $3;
+ $output_name = lc($2) . $ext;
+ &process_file("index");
+ }
+ else {
+ # Skip junk in between chapters, appendices and indexes.
+ $line = <>;
+ }
+}
+
+sub process_file {
+ my $marker = shift;
+ my $path = "$directory/$output_name";
+
+ open (OUTPUT_FILE, ">$path") or die "Cannot open $path";
+
+ print STDERR "Creating $path\n";
+
+ # Print out XML PI
+ print OUTPUT_FILE "<?xml version='1.0' encoding='ISO-8859-1'?>\n";
+
+ # Print whatever happened to appear at the end of the previous chapter.
+ print OUTPUT_FILE "$start_text\n" if $start_text;
+
+ while (defined $line) {
+ $line = <>;
+
+ # Note: Anything after the terminating marker is lost, just like
+ # lines in between chapters.
+ if ($line =~ /(.*<\/\s*$marker\s*>)/i ) {
+ print OUTPUT_FILE "$1\n" if $1;
+ close OUTPUT_FILE;
+ return;
+ }
+ print OUTPUT_FILE $line;
+ }
+}
+
+exit 0;
diff --git a/Docs/Support/generate-flag-images b/Docs/Support/generate-flag-images
index 903c610d4bc..21140388012 100755
--- a/Docs/Support/generate-flag-images
+++ b/Docs/Support/generate-flag-images
@@ -1,37 +1,31 @@
#!/bin/sh
-tmp=/tmp/temp-pic.pnm
-
-all="argentina austria czech-republic germany great-britain hungary israel
-italy russia portugal sweden canada usa south-korea japan taiwan australia
-romania denmark france estonia poland singapore bulgaria south-africa
-netherlands chile ukraine greece finland switzerland croatia china
-brazil spain iceland ireland denmark"
-
-new=""
+flags=`grep @image mirrors.texi | cut -d" " -f1 | cut -d/ -f2 | tr -d "}" | sort | uniq`
set -x
-cd Flags
-
-# for c in $all; do cp empty.png $c.pdf; done; exit
+cd Flags
-for c in $new
+for c in $flags
do
- # For HTML version
- giftopnm ../Raw-Flags/$c.gif | \
- pnmscale -xsize 30 > $tmp
- pnmpaste $tmp 1 1 ../Images/flag-background.pnm > $c.pnm
- rm -f $tmp
- # For web version
+ # For PNM, to be used later
+ giftopnm ../Raw-Flags/$c.gif | pnmscale -xsize 30 > $c-tmp.pnm
+ pnmpaste $c-tmp.pnm 1 1 ../Images/flag-background.pnm > $c.pnm
+ rm -f $c-tmp.pnm
+
+ # For GIF version
ppmtogif $c.pnm > $c.gif
# or cjpeg -optimize -quality 70 -outfile $c.jpg
- # For PDF version (this coredumps. use empty file until fixed)
- # pnmtopng -verbose $c.pnm > $c.png
- cp ../Images/empty.png $c.pdf
- # For TeX version
- giftopnm ../Raw-Flags/$c.gif | \
- pnmscale -xsize 30 | \
- pnmtops -noturn > $c.eps
+
+ # For EPS version
+ pnmtops -noturn $c.pnm > $c.eps
+
+ # For PDF version
+ ps2pdf $c.eps $c.pdf
+
# For text version
echo -n "" > $c.txt
+
+ # PNM isn't really needed
+ rm -f $c.pnm
+
done
diff --git a/Docs/Support/generate-text-files.pl b/Docs/Support/generate-text-files.pl
index 570e579d926..6470baaa6e9 100755
--- a/Docs/Support/generate-text-files.pl
+++ b/Docs/Support/generate-text-files.pl
@@ -1,11 +1,11 @@
-#!/my/gnu/bin/perl -w -*- perl -*-
+#!/usr/bin/perl -w -*- perl -*-
# Generate text files from top directory from the manual.
$from = shift(@ARGV);
$fnode = shift(@ARGV);
$tnode = shift(@ARGV);
-open(IN, "$from") || die;
+open(IN, "$from") || die "Cannot open $from: $!";
$in = 0;
@@ -19,7 +19,7 @@ while (<IN>)
}
elsif (/^File: mysql.info/ || (/^/))
{
- # Just Skip node begginigs
+ # Just Skip node beginnings
}
else
{
@@ -38,3 +38,6 @@ while (<IN>)
}
close(IN);
+
+die "Could not find node \"$tnode\"" if ($in == 1);
+exit 0;
diff --git a/Docs/Support/make-docbook b/Docs/Support/make-docbook
new file mode 100755
index 00000000000..93dbc56c0f8
--- /dev/null
+++ b/Docs/Support/make-docbook
@@ -0,0 +1,29 @@
+#!/bin/sh
+# 2002-01-30 arjen@mysql.com
+# Use this to create mysql.xml (the DocBook XML format output of manual.texi)
+# Requires makeinfo 4.0c
+
+#create include.texi with version/port #
+ echo "@c This file is autogenerated by the Makefile" > include.texi
+ echo -n "@set mysql_version " >> include.texi
+# grep "AM_INIT_AUTOMAKE(mysql, " ../configure.in | \
+# sed -e 's;AM_INIT_AUTOMAKE(mysql, ;;' -e 's;);;' >> include.texi
+# 2002-04-26 arjen - the below just picks #.# instead of #.#.#-alpha
+# (code by mwagner - tnx)
+ grep "AM_INIT_AUTOMAKE(mysql, " ../configure.in | \
+ perl -p -e 's/AM_INIT_AUTOMAKE\(mysql,\s(\d+\.\d+)\..+/$1/' >> include.texi
+ echo -n "@set default_port " >> include.texi
+ grep "MYSQL_TCP_PORT_DEFAULT=" ../configure.in | \
+ sed -e 's;MYSQL_TCP_PORT_DEFAULT=;;' >> include.texi
+
+# produce DocBook XML
+ Support/docbook-prefix.pl < manual.texi |\
+ makeinfo --force --no-ifinfo --docbook -o - |\
+ Support/docbook-fixup.pl > mysql.xml
+
+ # See if the XML output is well-formed
+ xmlwf mysql.xml
+
+ # If all is well, keep processing
+ cat mysql.xml | Support/colspec-fix.pl | Support/docbook-split;
+
diff --git a/Docs/Support/test-make-manual-de b/Docs/Support/test-make-manual-de
new file mode 100755
index 00000000000..a5c03001bda
--- /dev/null
+++ b/Docs/Support/test-make-manual-de
@@ -0,0 +1,137 @@
+#!/bin/sh
+
+needed_flags=0
+needed_texi2html=0
+needed_texinfo_tex=0
+needed_include_texi=0
+
+if [ -z $BROWSER ]; then
+ BROWSER=netscape
+ echo "BROWSER not set, using $BROWSER"
+fi
+
+die ()
+{
+ echo
+ echo $1
+ cleanup
+ exit 1
+}
+
+cleanup ()
+{
+ echo "Cleaning up..."
+ if [ $needed_flags ]; then
+ bk clean Flags
+ fi
+
+ if [ $needed_texi2html ]; then
+ bk clean Support/texi2html
+ fi
+
+ if [ $needed_texinfo_tex ]; then
+ bk clean Support/texinfo.tex
+ fi
+
+ if [ $needed_include_texi ]; then
+ rm -f include.texi
+ fi
+
+ for file in \
+ manual.de.aux manual.de.cp manual.de.cps manual.de.dvi \
+ manual.de.fn manual.de.fns manual.de.ky manual.de.html \
+ manual.de.pg manual.de.toc manual.de.tp manual.de.vr \
+ mysql.de.info manual.de_toc.html ;
+ do
+ rm -f $file
+ done
+
+}
+
+
+if [ -e Flags/usa.txt ]; then
+ echo "Good, Flags are there."
+else
+ echo -n "Checking out Flags..."
+ bk edit Flags >/dev/null 2>&1
+ echo " Done."
+ needed_flags=1
+fi
+
+if [ -e Support/texi2html ]; then
+ echo "Good, texi2html is there."
+else
+ echo -n "Checking out texi2html..."
+ bk edit Support/texi2html >/dev/null 2>&1
+ echo " Done."
+ needed_texi2html=1
+fi
+
+if [ -e Support/texinfo.tex ]; then
+ echo "Good, texinfo.tex is there."
+else
+ echo -n "Checking out texinfo.tex..."
+ bk edit Support/texinfo.tex >/dev/null 2>&1
+ echo " Done."
+ needed_texinfo_tex=1
+fi
+
+if [ -e include.texi ]; then
+ echo "Good, include.texi is there."
+else
+ echo -n "Creating include.texi..."
+ bk edit ../configure.in >/dev/null 2>&1
+ echo "@c This file was generated by test-make-manual" > include.texi
+ echo -n "@set mysql_version " >> include.texi
+ grep "AM_INIT_AUTOMAKE(mysql, " ../configure.in | \
+ sed -e 's;AM_INIT_AUTOMAKE(mysql, ;;' -e 's;);;' >> include.texi
+ echo -n "@set default_port " >> include.texi
+ grep "MYSQL_TCP_PORT_DEFAULT=" ../configure.in | \
+ sed -e 's;MYSQL_TCP_PORT_DEFAULT=;;' >> include.texi
+ echo " Done."
+ needed_include_texi=1
+fi
+
+echo -n "Running makeinfo..."
+makeinfo --no-split -I . manual.de.texi
+
+if [ $? != 0 ]; then
+ die "Manual has errors - fix before you commit"
+else
+ echo " Looks good."
+fi
+
+
+echo -n "Running texi2html..."
+/usr/bin/perl ./Support/texi2html -iso -number manual.de.texi
+
+if [ $? != 0 ]; then
+ die "Manual has errors - fix before you commit"
+else
+ echo " Looks good."
+fi
+
+
+echo -n "Running texi2dvi..."
+texi2dvi --batch manual.de.texi > texi2dvi.out
+
+if [ $? != 0 ]; then
+ die "Manual has errors - fix before you commit (saved in texi2dvi.out)"
+else
+ rm texi2dvi.out
+ echo " Looks good."
+fi
+
+echo
+echo
+echo "Please examine your modifications in \`manual.de.html'."
+echo
+echo "If you would like to use a different browser, set the 'BROWSER' environment"
+echo "variable."
+echo
+
+$BROWSER file:`pwd`/manual.de_toc.html
+
+echo "-- Press Enter to Continue --"
+read junk
+cleanup
diff --git a/Docs/Support/trivial-makeinfo-4.0c.patch b/Docs/Support/trivial-makeinfo-4.0c.patch
new file mode 100644
index 00000000000..b2446c0e8bb
--- /dev/null
+++ b/Docs/Support/trivial-makeinfo-4.0c.patch
@@ -0,0 +1,11 @@
+--- alt-multi.c Sun Apr 14 10:03:19 2002
++++ multi.c Tue May 22 20:52:33 2001
+@@ -287,7 +287,7 @@
+ && *params != '\n' && *params != '@')
+ params++;
+ setup_output_environment (i,
+- (int) ((columnfrac * 100.00) + 0.49));
++ (int) (columnfrac * (fill_column - current_indent) + .5));
+ }
+ }
+
diff --git a/Docs/Support/update-reserved-words.pl b/Docs/Support/update-reserved-words.pl
new file mode 100755
index 00000000000..2920e083c9c
--- /dev/null
+++ b/Docs/Support/update-reserved-words.pl
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+
+# Based on a Emacs macro by david@mysql.com
+# Implemented in Perl by jeremy@mysql.com
+# 2001-11-20 Fixups by arjen@mysql.com, 2 keywords and 15 synonyms were missing
+# 2001-12-07 Fixup by arjen@mysql.com, add column headings for multitable.
+# 2002-05-01 Fixup by arjen@mysql.com, use 3 columns instead of 4.
+# 2002-05-03 Fixup by arjen@mysql.com, fill last row to full # of columns.
+# 2002-06-14 Fixup by arjen@mysql.com, Issue a "bk edit manual.texi".
+
+print STDERR "Scanning lex.h for symbols..\n";
+open LEX, "<../sql/lex.h";
+while($line = <LEX>) {
+ if($line =~ /\{\s*\"([A-Z_]+)\"/) {
+ $words{$1} = $1;
+ } elsif($line =~ /sql_functions/) {
+ last;
+ };
+};
+close LEX;
+
+print STDERR "Scanning sql_yacc.yy for non-reserved words...\n";
+open YACC, "<../sql/sql_yacc.yy";
+while(<YACC> !~ /^keyword:/) {};
+while(($line = <YACC>) =~ /[\s|]+([A-Z_]+)/) {
+ $keyword = $1;
+ $keyword =~ s/_SYM//;
+ delete $words{$keyword};
+};
+close YACC;
+
+
+print STDERR "Copying reserved words to an array...\n";
+foreach(keys %words) { push @words, $words{$_}; };
+
+print STDERR "Sorting array...\n";
+@words = sort @words;
+
+printf STDERR "There are %i reserved words.\n", scalar @words;
+
+@pre = ("\@item", " \@tab", " \@tab");
+
+$list = "";
+for($i=0; $word = shift(@words); $i++) {
+ $list .= sprintf "%s %s\n", $pre[$i%3], "\@code\{$word\}";
+}
+# Fill last row to full # of columns.
+for( ; $i%3; $i++) {
+ $list .= sprintf "%s\n", $pre[$i%3];
+}
+
+`bk edit manual.texi`;
+
+open OLD, "<manual.texi";
+open NEW, ">manual-tmp.texi";
+
+print STDERR "Copying beginning of manual.texi...\n";
+while(($line = <OLD>) !~ /START_OF_RESERVED_WORDS/) { print NEW $line; };
+print NEW "\@c START_OF_RESERVED_WORDS\n\n";
+printf NEW "\@c Reserved word list updated %s by %s.\n".
+ "\@c To regenerate, use Support/update-reserved-words.pl.\n\n",
+ &pretty_date, $ENV{USER};
+
+print STDERR "Inserting list of reserved words...\n";
+# Ensure the fractions add up to 100% otherwise it looks funny in print:
+print NEW "\@multitable \@columnfractions .33 .33 .34\n";
+print NEW "\@item \@strong{Word}\n \@tab \@strong{Word}\n \@tab \@strong{Word}\n";
+print NEW $list;
+print NEW "\@end multitable\n";
+print STDERR "Skipping over old list...\n";
+while(($line = <OLD>) !~ /END_OF_RESERVED_WORDS/) {};
+print NEW "\n\@c END_OF_RESERVED_WORDS\n";
+print STDERR "Copying end of manual.texi...\n";
+while($line = <OLD>) { print NEW $line; };
+
+close OLD;
+close NEW;
+
+print STDERR "Moving manual-tmp.texi to manual.texi...\n";
+unlink "manual.texi";
+rename "manual-tmp.texi", "manual.texi";
+
+print STDERR "Reserved word list updated successfully!\n";
+
+sub pretty_date {
+ @time = ($time = shift)?((localtime($time))[0..6]):((localtime)[0..6]);
+
+ ($sec, $min, $hour, $mday, $mon, $year, $wday) = @time;
+ $wday = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[$wday];
+ $mon = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)[$mon];
+ $year += 1900;
+
+ $pretty = sprintf("%s %s %2i %02i:%02i:%02i %i",
+ $wday, $mon, $mday, $hour, $min, $sec, $year);
+
+ return $pretty;
+};
+
diff --git a/Docs/Support/xwf b/Docs/Support/xwf
new file mode 100755
index 00000000000..38f89774fe8
--- /dev/null
+++ b/Docs/Support/xwf
@@ -0,0 +1,67 @@
+#!/usr/bin/perl -w
+#
+# Parse document and report first syntax (well-formedness) error found.
+#
+
+use strict;
+use XML::Parser;
+use Getopt::Std;
+
+my %opts;
+getopts('e', \%opts);
+my $ENTREFS = exists( $opts{'e'} ); # flag: check ent refs
+
+my $parser = XML::Parser->new(
+ ErrorContext => 2, # output error context
+ );
+
+# get input from files
+if( @ARGV ) {
+ foreach( @ARGV ) {
+ my $file = $_;
+ unless( -r $file ) {
+ print STDERR "ERROR: Can't open '$file'.\n";
+ return;
+ }
+ my $input = '';
+ open( F, $file );
+ while( <F> ) { $input .= $_; }
+ close F;
+
+ # parse and report errors
+ if( &parse_string( $input )) {
+ print STDERR "ERROR in $file:\n$@\n";
+ } else {
+ print STDERR "'$file' is well-formed.\n";
+ }
+ }
+ print "All files checked.\n";
+
+# get input from STDIN
+} else {
+ my $input = "";
+ while( <STDIN> ) { $input .= $_; }
+ if( &parse_string( $input )) {
+ print STDERR "ERROR in stream:\n$@\n";
+ } else {
+ print STDERR "No syntax errors found in XML stream.\n";
+ }
+}
+
+
+# parse the string and return error message
+#
+# NOTE: By default, entity refs are not expanded. XML::Parser can be
+# told not to expand entity refs, but will still try to find
+# replacement text just in case, which we don't want. Therefore, we
+# need to do a stupid regexp replacement, removing entities from input.
+#
+sub parse_string {
+ my $string = shift;
+ unless( $ENTREFS ) {
+ $string =~ s/\&[^\s;]+;//g; # remove entity references
+ }
+ eval { $parser->parse( $string ); };
+ $@ =~ s/at \/.*?$//s; # remove module line number
+ return $@;
+}
diff --git a/Docs/bk.txt b/Docs/bk.txt
index cb2521b2b05..b9274901653 100644
--- a/Docs/bk.txt
+++ b/Docs/bk.txt
@@ -1,4 +1,5 @@
Mail by sasha, should be rewritten as a HOWTO sometimes
+vva added point C) for Windows-project
-----------
I have set up a repository with BitKeeper on work. There are still some things
@@ -29,6 +30,12 @@ you will need just to set up a slave repository on your machine:
Now you have the entire source tree in the current directory. Let's compile it:
BUILD/compile-pentium-debug
+
+C) Windows project.
+ - Compile Linux-project (see points above)
+ - run VC++Files/prepare
+ - make repository accessible for Windows (using samba)
+ - open VC++Files/mysql.dsw in Microsoft Visual Stidio (5.0 or above)
After you edit a file, you need to check it in using bk citool or bk ci
filename. Note that ci is different than commit - you ci a file, but you commit
@@ -55,5 +62,4 @@ Their developers, and especially the president of the company Larry McVoy really
like MySQL and are very anxious to help us. Make sure it is obvious that you
work for MySQL, of course. And, of course, do not bug them with little things
that you can figure out on your own or with my help - they were nice to offer us
-support, but we should not abuse it.
-
+support, but we should not abuse it. \ No newline at end of file
diff --git a/Docs/manual.de.texi b/Docs/manual.de.texi
new file mode 100644
index 00000000000..902a9496bbb
--- /dev/null
+++ b/Docs/manual.de.texi
@@ -0,0 +1,107 @@
+\input texinfo @c -*-texinfo-*-
+@c
+@c *********************************************************
+@c
+@c This is a dummy placeholder file for manual.de.texi in the
+@c MySQL source trees.
+@c
+@c Note, that the manual has been moved into a separate
+@c BitKeeper source tree named "mysqldoc" - do not attempt
+@c to add NEWS entries or documentation to this file! All
+@c changes to the manual should be done in the mysqldoc tree.
+@c
+@c See http://www.mysql.com/doc/en/Installing_source_tree.html
+@c for information about how to work with BitKeeper source trees.
+@c
+@c This dummy file is being replaced with the real manual from the
+@c mysqldoc tree when building the official source distribution.
+@c
+@c Please e-mail docs@mysql.com for more information or if
+@c you are interested in doing a translation.
+@c
+@c *********************************************************
+@c
+@c %**start of header
+
+@setfilename mysql.de.info
+
+@c We want the types in the same index
+@syncodeindex tp fn
+
+@c Get version information. This file is generated by the Makefile!!
+@include include.texi
+
+@ifclear tex-debug
+@c This removes the black squares in the right margin
+@finalout
+@end ifclear
+
+@c Set background for HTML
+@set _body_tags BGCOLOR=silver TEXT=#000000 LINK=#101090 VLINK=#7030B0
+@c Set some style elements for the manual in HTML form. 'suggested'
+@c natural language colors: aqua, black, blue, fuchsia, gray, green,
+@c lime, maroon, navy, olive, purple, red, silver, teal, white, and
+@c yellow. From Steeve Buehler <ahr@YogElements.com>
+@set _extra_head <style> code {color:purple} tt {color:green} samp {color:navy} pre {color:maroon} </style>
+
+@settitle Dummy MySQL Reference Manual for version @value{mysql_version}.
+
+@c We want single-sided heading format, with chapters on new pages. To
+@c get double-sided format change 'on' below to 'odd'
+@setchapternewpage on
+
+@paragraphindent 0
+
+@c %**end of header
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* mysql: (mysql). MySQL documentation.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@titlepage
+@sp 10
+@center @titlefont{Empty placeholder for the MySQL Reference Manual}
+@sp 10
+@center Copyright @copyright{} 1995-2002 MySQL AB
+@c blank page after title page makes page 1 be a page front.
+@c also makes the back of the title page blank.
+@page
+@end titlepage
+
+@c This should be added. The HTML conversion also needs a MySQL version
+@c number somewhere.
+
+@iftex
+@c change this to double if you want formatting for double-sided
+@c printing
+@headings single
+
+@oddheading @thischapter @| @| @thispage
+@evenheading @thispage @| @| MySQL Technical Reference for Version @value{mysql_version}
+
+@end iftex
+
+@node Top, (dir), (dir), (dir)
+
+@ifinfo
+This is an empty placeholder file for the MySQL manual.
+
+The MySQL manual is now maintained in a separate BitKeeper source tree!
+Please see @url{http://www.mysql.com/doc/en/Installing_source_tree.html}
+for more info on how to work with BitKeeper.
+
+Please do not attempt to edit this file to add NEWS entries or to add
+documentation! Use the one in the @code{mysqldoc} BK tree instead.
+
+This file will be replaced with the current @code{manual.de.texi} when building
+the official source distribution.
+
+You can find a specific manual for any older version of MySQL
+in the binary or source distribution for that version.
+@end ifinfo
+
+@bye
diff --git a/Docs/manual.ja.texi b/Docs/manual.ja.texi
index aac97c61c8d..2a0b0fbf34b 100644
--- a/Docs/manual.ja.texi
+++ b/Docs/manual.ja.texi
@@ -3187,7 +3187,7 @@ encounter per year, but we are as always very flexible towards our customers!
@c @image{Flags/estonia} Estonia [Tradenet] @
@c @uref{http://mysql.tradenet.ee, WWW}
@item
-@c EMAIL: tonu@spamm.ee (Tonu Samuel)
+@c EMAIL: tonu@spam.ee (Tonu Samuel)
@image{Flags/estonia} Estonia [OKinteractive] @
@uref{http://mysql.mirror.ok.ee, WWW}
@item
@@ -23949,7 +23949,7 @@ Uptime: 10077 Threads: 1 Questions: 9 Slow queries: 0 Opens: 6 Flush tables
@item Max memory used @tab mysqld ¤Î¥³¡¼¥É¤Ë¤è¤Ã¤ÆľÀܳä¤êÅö¤Æ¤é¤ì¤ëºÇÂç¥á¥â¥ê¡¼ÎÌ (only available when @strong{MySQL} is compiled with --with-debug)
@end multitable
-If you do @code{myslqadmin shutdown} on a socket (in other words, on a
+If you do @code{mysqladmin shutdown} on a socket (in other words, on a
the computer where @code{mysqld} is running), @code{mysqladmin} will
wait until the @code{MySQL} @code{pid-file} is removed to ensure that
the @code{mysqld server} has stopped properly.
diff --git a/Docs/manual_toc.html b/Docs/manual_toc.html
new file mode 100644
index 00000000000..b9014e5efb9
--- /dev/null
+++ b/Docs/manual_toc.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<title>Place holder for manual_toc.html</title>
+</head>
+<body>
+This is just a place holder for the autogenerated manual_toc.html
+to make "make dist" happy.
+</body>
+</html>
diff --git a/Docs/mirrors.texi b/Docs/mirrors.texi
new file mode 100644
index 00000000000..651963c57c3
--- /dev/null
+++ b/Docs/mirrors.texi
@@ -0,0 +1,446 @@
+@strong{Europe:}
+
+@itemize @bullet
+
+@item
+@image{Flags/armenia} Armenia [AbideWeb Technologies] @@
+WWW (@uref{http://mysql.abideweb.com/})
+FTP (@uref{ftp://mysql.abideweb.com/mirrors/MySQL/})
+
+@item
+@image{Flags/austria} Austria [Univ. of Technology/Vienna] @@
+WWW (@uref{http://gd.tuwien.ac.at/db/mysql/})
+FTP (@uref{ftp://gd.tuwien.ac.at/db/mysql/})
+
+@item
+@image{Flags/belgium} Belgium [BELNET] @@
+WWW (@uref{http://mysql.belnet.be/})
+FTP (@uref{ftp://ftp.belnet.be/mirror/ftp.mysql.com/pub/mysql/})
+
+@item
+@image{Flags/bulgaria} Bulgaria [online.bg/Sofia] @@
+WWW (@uref{http://mysql.online.bg/})
+FTP (@uref{ftp://mysql.online.bg/})
+
+@item
+@image{Flags/czech-republic} Czech Republic [Masaryk University in Brno] @@
+WWW (@uref{http://mysql.linux.cz/})
+FTP (@uref{ftp://ftp.fi.muni.cz/pub/mysql/})
+
+@item
+@image{Flags/czech-republic} Czech Republic [www.gin.cz] @@
+WWW (@uref{http://mysql.gin.cz/})
+FTP (@uref{ftp://ftp.gin.cz/pub/MIRRORS/www.mysql.com/})
+
+@item
+@image{Flags/czech-republic} Czech Republic [www.sopik.cz] @@
+WWW (@uref{http://www.mysql.cz/})
+
+@item
+@image{Flags/denmark} Denmark [Borsen] @@
+WWW (@uref{http://mysql.borsen.dk/})
+
+@item
+@image{Flags/denmark} Denmark [Cybercity Internet] @@
+WWW (@uref{http://mysql.mirrors.cybercity.dk/})
+
+@item
+@image{Flags/denmark} Denmark [SunSITE] @@
+WWW (@uref{http://mirrors.sunsite.dk/mysql/})
+FTP (@uref{ftp://sunsite.dk/mirrors/mysql/})
+
+@item
+@image{Flags/estonia} Estonia [OK Interactive] @@
+WWW (@uref{http://mysql.mirror.ok.ee/})
+
+@item
+@image{Flags/finland} Finland [KPNQwest] @@
+WWW (@uref{http://mysql.kpnqwest.fi/})
+
+@item
+@image{Flags/finland} Finland [Mediatraffic] @@
+WWW (@uref{http://mysql.mediatraffic.fi/})
+
+@item
+@image{Flags/finland} Finland [tonnikala.net] @@
+WWW (@uref{http://mysql.tonnikala.org/})
+
+@item
+@image{Flags/france} France [free.fr] @@
+WWW (@uref{http://mysql-mirror.free.fr/})
+FTP (@uref{ftp://ftp.free.fr/pub/MySQL/})
+
+@item
+@image{Flags/france} France [mir2.ovh.net/] @@
+WWW (@uref{http://mir2.ovh.net/ftp.mysql.com/})
+FTP (@uref{ftp://mir1.ovh.net/ftp.mysql.com/})
+
+@item
+@image{Flags/france} France [Netsample] @@
+WWW (@uref{http://www.mysql.netsample.com/})
+
+@item
+@image{Flags/france} France [Universite Paris 10] @@
+WWW (@uref{http://ftp.u-paris10.fr/mysql.com})
+FTP (@uref{ftp://ftp.u-paris10.fr/mysql.com})
+
+@item
+@image{Flags/germany} Germany [GWDG] @@
+WWW (@uref{http://ftp.gwdg.de/pub/misc/mysql/})
+FTP (@uref{ftp://ftp.gwdg.de/pub/misc/mysql/})
+
+@item
+@image{Flags/germany} Germany [SunSITE Central Europe] @@
+WWW (@uref{http://sunsite.informatik.rwth-aachen.de/mysql/})
+FTP (@uref{ftp://sunsite.informatik.rwth-aachen.de/pub/mirror/www.mysql.com/})
+
+@item
+@image{Flags/germany} Germany [Tiscali] @@
+WWW (@uref{http://filepile.tiscali.de/mirror/mysql/})
+FTP (@uref{ftp://filepile.tiscali.de/mirror/mysql/})
+
+@item
+@image{Flags/germany} Germany [Wolfenbuettel] @@
+WWW (@uref{http://www.fh-wolfenbuettel.de/ftp/pub/database/mysql/})
+FTP (@uref{ftp://ftp.fh-wolfenbuettel.de/pub/database/mysql/})
+
+@item
+@image{Flags/greece} Greece [NTUA, Athens] @@
+WWW (@uref{http://www.ntua.gr/mysql/})
+FTP (@uref{ftp://ftp.ntua.gr/pub/databases/mysql/})
+
+@item
+@image{Flags/hungary} Hungary [stop.hu] @@
+WWW (@uref{http://mysql.mirror.stop.hu/})
+
+@item
+@image{Flags/hungary} Hungary [TiszaneT] @@
+WWW (@uref{http://mysql.tiszanet.hu/})
+FTP (@uref{ftp://mysql.tiszanet.hu/pub/mirrors/mysql/})
+
+@item
+@image{Flags/hungary} Hungary [Xenia] @@
+WWW (@uref{http://mysql.sote.hu/})
+FTP (@uref{ftp://xenia.sote.hu/pub/mirrors/www.mysql.com/})
+
+@item
+@image{Flags/iceland} Iceland [Tvíund] @@
+WWW (@uref{http://mysql.tviund.is/})
+
+@item
+@image{Flags/ireland} Ireland [Esat Net] @@
+WWW (@uref{http://ftp.esat.net/mirrors/download.sourceforge.net/pub/mirrors/mysql/})
+FTP (@uref{ftp://ftp.esat.net/mirrors/download.sourceforge.net/pub/mirrors/mysql/})
+
+@item
+@image{Flags/ireland} Ireland [MD NMTB Media] @@
+WWW (@uref{http://mirrors.nmtbmedia.com/mysql/})
+
+@item
+@image{Flags/israel} Israel [fresh.co.il] @@
+WWW (@uref{http://mysql.fresh.co.il/})
+
+@item
+@image{Flags/italy} Italy [feelinglinux.com] @@
+WWW (@uref{http://mysql.feelinglinux.com/})
+
+@item
+@image{Flags/italy} Italy [Teta Srl] @@
+WWW (@uref{http://www.teta.it/mysql/})
+
+@item
+@image{Flags/italy} Italy [tzone.it] @@
+WWW (@uref{http://mysql.tzone.it/})
+
+@item
+@image{Flags/latvia} Latvia [linux.lv] @@
+FTP (@uref{ftp://ftp.linux.lv/pub/software/mysql/})
+
+@item
+@image{Flags/netherlands} Netherlands [OMS-Net] @@
+WWW (@uref{http://mysql.oms-net.nl/})
+
+@item
+@image{Flags/netherlands} Netherlands [ProServe] @@
+WWW (@uref{http://mysql.proserve.nl/})
+
+@item
+@image{Flags/netherlands} Netherlands [WideXS BV] @@
+WWW (@uref{http://mysql.mirror.widexs.nl/})
+FTP (@uref{ftp://mirror.widexs.nl/pub/mysql/})
+
+@item
+@image{Flags/norway} Norway [Brainpeddlers AS] @@
+WWW (@uref{http://mysql.brainpeddlers.com/})
+
+@item
+@image{Flags/poland} Poland [ncservice.com/Gdansk] @@
+WWW (@uref{http://mysql.service.net.pl/})
+
+@item
+@image{Flags/poland} Poland [SunSITE] @@
+WWW (@uref{http://sunsite.icm.edu.pl/mysql/})
+FTP (@uref{ftp://sunsite.icm.edu.pl/pub/unix/mysql/})
+
+@item
+@image{Flags/portugal} Portugal [Instituto Supertior Técnico] @@
+WWW (@uref{http://darkstar.ist.utl.pt/mysql/})
+FTP (@uref{ftp://darkstar.ist.utl.pt/pub/mysql/})
+
+@item
+@image{Flags/portugal} Portugal [Netvisão] @@
+WWW (@uref{http://mysql.netvisao.pt/})
+FTP (@uref{ftp://mirrors2.netvisao.pt/pub/mysql/})
+
+@item
+@image{Flags/portugal} Portugal [VIZZAVI] @@
+WWW (@uref{http://ftp.vizzavi.pt/pub/mysql/})
+FTP (@uref{ftp://ftp.vizzavi.pt/pub/mysql/})
+
+@item
+@image{Flags/romania} Romania [roedu.net/Bucharest] @@
+FTP (@uref{ftp://ftp.roedu.net/pub/mirrors/ftp.mysql.com/})
+
+@item
+@image{Flags/russia} Russia [DirectNet] @@
+WWW (@uref{http://mysql.directnet.ru/})
+FTP (@uref{ftp://ftp.dn.ru/pub/MySQL/})
+
+@item
+@image{Flags/russia} Russia [Scientific Center/Chernogolovka] @@
+FTP (@uref{ftp://ftp.chg.ru/pub/databases/mysql/})
+
+@item
+@image{Flags/slovenia} Slovenia [ARNES] @@
+WWW (@uref{http://ftp.arnes.si/mysql/})
+FTP (@uref{ftp://ftp.arnes.si/packages/mysql/})
+
+@item
+@image{Flags/sweden} Sweden [Sunet] @@
+WWW (@uref{http://ftp.sunet.se/pub/unix/databases/relational/mysql/})
+FTP (@uref{ftp://ftp.sunet.se/pub/unix/databases/relational/mysql/})
+
+@item
+@image{Flags/switzerland} Switzerland [SunSITE] @@
+WWW (@uref{http://sunsite.cnlab-switch.ch/ftp/mirror/mysql/})
+FTP (@uref{ftp://sunsite.cnlab-switch.ch/mirror/mysql/})
+
+@item
+@image{Flags/turkey} Turkey [proGEN] @@
+WWW (@uref{http://mysql.progen.com.tr/})
+
+@item
+@image{Flags/turkey} Turkey [Turkish National Academic Network & Information Center] @@
+WWW (@uref{http://mysql.ulak.net.tr/})
+
+@item
+@image{Flags/great-britain} UK [PLiG/UK] @@
+WWW (@uref{http://ftp.plig.org/pub/mysql/})
+FTP (@uref{ftp://ftp.plig.org/pub/mysql/})
+
+@item
+@image{Flags/ukraine} Ukraine [ISP Alkar Teleport/Dnepropetrovsk] @@
+WWW (@uref{http://mysql.dp.ua/})
+FTP (@uref{ftp://ftp.tlk-l.net/pub/mirrors/mysql.com/})
+
+@item
+@image{Flags/ukraine} Ukraine [PACO] @@
+WWW (@uref{http://mysql.paco.net.ua/})
+FTP (@uref{ftp://mysql.paco.net.ua/})
+
+@item
+@image{Flags/yugoslavia} Yugoslavia [Open Source Network of Yugoslavia] @@
+WWW (@uref{http://mysql.boa.org.yu/})
+FTP (@uref{ftp://ftp.linux.org.yu/pub/MySQL/})
+
+@end itemize
+
+@strong{North America:}
+
+@itemize @bullet
+
+@item
+@image{Flags/canada} Canada [Tryc] @@
+WWW (@uref{http://web.tryc.on.ca/mysql/})
+
+@item
+@image{Flags/mexico} Mexico [UAM] @@
+WWW (@uref{http://mysql.azc.uam.mx/})
+FTP (@uref{ftp://mysql.azc.uam.mx/mirrors/mysql/})
+
+@item
+@image{Flags/mexico} Mexico [UNAM] @@
+WWW (@uref{http://mysql.unam.mx/})
+FTP (@uref{ftp://mysql.unam.mx/pub/mysql/})
+
+@item
+@image{Flags/usa} USA [adgrafix.com / Boston, MA] @@
+WWW (@uref{http://mysql.adgrafix.com/})
+
+@item
+@image{Flags/usa} USA [Argonne National Laboratory / Chicago, IL] @@
+FTP (@uref{ftp://mirror.mcs.anl.gov/pub/mysql/})
+
+@item
+@image{Flags/usa} USA [Hurricane Electric / San Jose, CA] @@
+WWW (@uref{http://mysql.he.net/})
+
+@item
+@image{Flags/usa} USA [netNumina / Cambridge, MA] @@
+WWW (@uref{http://mysql.mirrors.netnumina.com/})
+
+@item
+@image{Flags/usa} USA [NIXC / Vienna, VA] @@
+WWW (@uref{http://mysql.nixc.net/})
+FTP (@uref{ftp://mysql.nixc.net/pub/mysql/})
+
+@item
+@image{Flags/usa} USA [Oregon State University / Corvallis, OR] @@
+WWW (@uref{http://mysql.orst.edu/})
+FTP (@uref{ftp://ftp.orst.edu/pub/mysql/})
+
+@item
+@image{Flags/usa} USA [University of Wisconsin / Wisconsin] @@
+WWW (@uref{http://mirror.sit.wisc.edu/mysql/})
+FTP (@uref{ftp://mirror.sit.wisc.edu/mirrors/mysql/})
+
+@item
+@image{Flags/usa} USA [UUNet] @@
+WWW (@uref{http://mysql.secsup.org/})
+FTP (@uref{ftp://mysql.secsup.org/pub/software/mysql/})
+
+@end itemize
+
+@strong{South America:}
+
+@itemize @bullet
+
+@item
+@image{Flags/argentina} Argentina [bannerlandia.com] @@
+WWW (@uref{http://mysql.bannerlandia.com.ar/})
+FTP (@uref{ftp://mysql.bannerlandia.com.ar/mirrors/mysql/})
+
+@item
+@image{Flags/chile} Chile [PSINet] @@
+WWW (@uref{http://mysql.psinet.cl/})
+FTP (@uref{ftp://ftp.psinet.cl/pub/database/mysql/})
+
+@item
+@image{Flags/chile} Chile [Tecnoera] @@
+WWW (@uref{http://mysql.tecnoera.com/})
+
+@item
+@image{Flags/chile} Chile [Vision] @@
+WWW (@uref{http://mysql.vision.cl/})
+
+@item
+@image{Flags/costa-rica} Costa Rica [Ogmios Communications] @@
+WWW (@uref{http://mysql.ogmios.co.cr/})
+FTP (@uref{ftp://mysql.ogmios.co.cr/pub/mysql/})
+
+@end itemize
+
+@strong{Asia:}
+
+@itemize @bullet
+
+@item
+@image{Flags/china} China [HKLPG/Hong Kong] @@
+WWW (@uref{http://mysql.hklpg.org/})
+
+@item
+@image{Flags/china} China [linuxforum.net] @@
+FTP (@uref{http://www2.linuxforum.net/mirror/mysql/})
+
+@item
+@image{Flags/china} China [shellhung.org/Hong Kong] @@
+WWW (@uref{http://mysql.shellhung.org/})
+FTP (@uref{ftp://ftp.shellhung.org/pub/Mirror/mysql/})
+
+@item
+@image{Flags/indonesia} Indonesia [CBN] @@
+WWW (@uref{http://mysql.cbn.net.id/})
+
+@item
+@image{Flags/indonesia} Indonesia [incaf.net] @@
+WWW (@uref{http://mysql.incaf.net/})
+FTP (@uref{ftp://mysql.incaf.net/})
+
+@item
+@image{Flags/indonesia} Indonesia [M-Web] @@
+WWW (@uref{http://mysql.mweb.net.id/})
+FTP (@uref{ftp://mysql.mweb.net.id/pub/database/mysql/})
+
+@item
+@image{Flags/indonesia} Indonesia [web.id] @@
+WWW (@uref{http://mysql.itb.web.id/})
+FTP (@uref{ftp://mysql.itb.web.id/pub/MySQL/})
+
+@item
+@image{Flags/japan} Japan [Soft Agency] @@
+WWW (@uref{http://www.softagency.co.jp/MySQL/})
+
+@item
+@image{Flags/japan} Japan [u-aizu.ac.jp/Aizu] @@
+FTP (@uref{ftp://ftp.u-aizu.ac.jp/ftp/pub/dbms/mysql/mysql.com/})
+
+@item
+@image{Flags/philippines} Philippines [Ateneo de Zamboanga University] @@
+WWW (@uref{http://mysql.adzu.edu.ph/})
+
+@item
+@image{Flags/singapore} Singapore [HJC] @@
+WWW (@uref{http://mysql.hjc.edu.sg/})
+FTP (@uref{ftp://ftp.hjc.edu.sg/mysql/})
+
+@item
+@image{Flags/south-korea} South Korea [HolyNet] @@
+WWW (@uref{http://mysql.holywar.net/})
+
+@item
+@image{Flags/south-korea} South Korea [Webiiz] @@
+WWW (@uref{http://mysql.webiiz.com/})
+
+@item
+@image{Flags/taiwan} Taiwan [I-SHOU University] @@
+WWW (@uref{http://mysql.isu.edu.tw/})
+
+@item
+@image{Flags/taiwan} Taiwan [nctu.edu/HsinChu] @@
+WWW (@uref{http://mysql.nctu.edu.tw/})
+
+@item
+@image{Flags/taiwan} Taiwan [TTN] @@
+WWW (@uref{http://mysql.ttn.net/})
+
+@end itemize
+
+@strong{Australia:}
+
+@itemize @bullet
+
+@item
+@image{Flags/australia} Australia [InterActive Consulting] @@
+WWW (@uref{http://mysql.oranged.to})
+
+@item
+@image{Flags/australia} Australia [planetmirror.com] @@
+WWW (@uref{http://mysql.planetmirror.com/})
+FTP (@uref{ftp://planetmirror.com/pub/mysql/})
+
+@item
+@image{Flags/new-zealand} New Zealand [Cubalan] @@
+WWW (@uref{http://mysql.soa.co.nz/})
+
+@end itemize
+
+@strong{Africa:}
+
+@itemize @bullet
+
+@item
+@image{Flags/south-africa} South African Republic [The Internet Solution/Johannesburg] @@
+FTP (@uref{ftp://ftp.is.co.za/linux/mysql/})
+
+@end itemize
+
diff --git a/Docs/my_sys.txt b/Docs/my_sys.txt
new file mode 100644
index 00000000000..85ffc13ecb4
--- /dev/null
+++ b/Docs/my_sys.txt
@@ -0,0 +1,140 @@
+Functions i mysys: (For flags se my_sys.h)
+
+ int my_copy _A((const char *from,const char *to,myf MyFlags));
+ - Copy file
+
+ int my_delete _A((const char *name,myf MyFlags));
+ - Delete file
+
+ int my_getwd _A((string buf,uint size,myf MyFlags));
+ int my_setwd _A((const char *dir,myf MyFlags));
+ - Get and set working directory
+
+ string my_tempnam _A((const char *pfx,myf MyFlags));
+ - Make a uniq temp file name by using dir and adding something after
+ pfx to make name uniq. Name is made by adding a uniq 6 length-string
+ and TMP_EXT after pfx.
+ Returns pointer to malloced area for filename. Should be freed by
+ free().
+
+ File my_open _A((const char *FileName,int Flags,myf MyFlags));
+ File my_create _A((const char *FileName,int CreateFlags,
+ int AccsesFlags, myf MyFlags));
+ int my_close _A((File Filedes,myf MyFlags));
+ uint my_read _A((File Filedes,byte *Buffer,uint Count,myf MyFlags));
+ uint my_write _A((File Filedes,const byte *Buffer,uint Count,
+ myf MyFlags));
+ ulong my_seek _A((File fd,ulong pos,int whence,myf MyFlags));
+ ulong my_tell _A((File fd,myf MyFlags));
+ - Use instead of open,open-with-create-flag, close read and write
+ to get automatic error-messages (flag: MYF_WME) and only have
+ to test for != 0 if error (flag: MY_NABP).
+
+ int my_rename _A((const char *from,const char *to,myf MyFlags));
+ - Rename file
+
+ FILE *my_fopen _A((const char *FileName,int Flags,myf MyFlags));
+ FILE *my_fdopen _A((File Filedes,int Flags,myf MyFlags));
+ int my_fclose _A((FILE *fd,myf MyFlags));
+ uint my_fread _A((FILE *stream,byte *Buffer,uint Count,myf MyFlags));
+ uint my_fwrite _A((FILE *stream,const byte *Buffer,uint Count,
+ myf MyFlags));
+ ulong my_fseek _A((FILE *stream,ulong pos,int whence,myf MyFlags));
+ ulong my_ftell _A((FILE *stream,myf MyFlags));
+ - Same read-interface for streams as for files
+
+ gptr _mymalloc _A((uint uSize,const char *sFile,
+ uint uLine, myf MyFlag));
+ gptr _myrealloc _A((string pPtr,uint uSize,const char *sFile,
+ uint uLine, myf MyFlag));
+ void _myfree _A((gptr pPtr,const char *sFile,uint uLine));
+ int _sanity _A((const char *sFile,unsigned int uLine));
+ gptr _myget_copy_of_memory _A((const byte *from,uint length,
+ const char *sFile, uint uLine,
+ myf MyFlag));
+ - malloc(size,myflag) is mapped to this functions if not compiled
+ with -DSAFEMALLOC
+
+ void TERMINATE _A((void));
+ - Writes malloc-info on stdout if compiled with -DSAFEMALLOC.
+
+ int my_chsize _A((File fd,ulong newlength,myf MyFlags));
+ - Change size of file
+
+ void my_error _D((int nr,myf MyFlags, ...));
+ - Writes message using error number (se mysys/errors.h) on
+ stdout or curses if MYSYS_PROGRAM_USES_CURSES() is called.
+
+ void my_message _A((const char *str,myf MyFlags));
+ - Writes message-string on
+ stdout or curses if MYSYS_PROGRAM_USES_CURSES() is called.
+
+ void my_init _A((void ));
+ - Start each program (in main) with this.
+ void my_end _A((int infoflag));
+ - Gives info about program.
+ - If infoflag & MY_CHECK_ERROR prints if some files are left open
+ - If infoflag & MY_GIVE_INFO prints timing info and malloc info
+ about prog.
+
+ int my_redel _A((const char *from, const char *to, int MyFlags));
+ - Delete from before rename of to to from. Copyes state from old
+ file to new file. If MY_COPY_TIME is set sets old time.
+
+ int my_copystat _A((const char *from, const char *to, int MyFlags));
+ - Copye state from old file to new file.
+ If MY_COPY_TIME is set sets copy also time.
+
+ string my_filename _A((File fd));
+ - Give filename of open file.
+
+ int dirname _A((string to,const char *name));
+ - Copy name of directory from filename.
+
+ int test_if_hard_path _A((const char *dir_name));
+ - Test if dirname is a hard path (Starts from root)
+
+ void convert_dirname _A((string name));
+ - Convert dirname acording to system.
+ - In MSDOS changes all caracters to capitals and changes '/' to
+ '\'
+ string fn_ext _A((const char *name));
+ - Returns pointer to extension in filename
+ string fn_format _A((string to,const char *name,const char *dsk,
+ const char *form,int flag));
+ format a filename with replace of library and extension and
+ converts between different systems.
+ params to and name may be identicall
+ function dosn't change name if name != to
+ Flag may be: 1 force replace filnames library with 'dsk'
+ 2 force replace extension with 'form' */
+ 4 force Unpack filename (replace ~ with home)
+ 8 Pack filename as short as possibly for output to
+ user.
+ All open requests should allways use at least:
+ "open(fn_format(temp_buffe,name,"","",4),...)" to unpack home and
+ convert filename to system-form.
+
+ string fn_same _A((string toname,const char *name,int flag));
+ - Copys directory and extension from name to toname if neaded.
+ copy can be forced by same flags that in fn_format.
+
+ int wild_compare _A((const char *str,const char *wildstr));
+ - Compare if str matches wildstr. Wildstr can contain "*" and "?"
+ as match-characters.
+ Returns 0 if match.
+
+ void get_date _A((string to,int timeflag));
+ - Get current date in a form ready for printing.
+
+ void soundex _A((string out_pntr, string in_pntr))
+ - Makes in_pntr to a 5 chars long string. All words that sounds
+ alike have the same string.
+
+ int init_key_cache _A((ulong use_mem,ulong leave_this_much_mem));
+ - Use cacheing of keys in MISAM, PISAM, and ISAM.
+ KEY_CACHE_SIZE is a good size.
+ - Remember to lock databases for optimal cacheing
+
+ void end_key_cache _A((void));
+ - End key-cacheing.
diff --git a/Docs/mysqld_error.txt b/Docs/mysqld_error.txt
index b8f0ba72ba5..aeb3a12c263 100644
--- a/Docs/mysqld_error.txt
+++ b/Docs/mysqld_error.txt
@@ -168,7 +168,7 @@
#define ER_NO_SUCH_INDEX 1082
"Table '%-.64s' has no index like the one used in CREATE INDEX. Recreate the table",
#define ER_WRONG_FIELD_TERMINATORS 1083
-"Field separator argument is not what is expected. Check the manual","
+"Field separator argument is not what is expected. Check the manual",
#define ER_BLOBS_AND_NO_TERMINATED 1084
"You can't use fixed rowlength with BLOBs. Please use 'fields terminated by'.",
#define ER_TEXTFILE_NOT_READABLE 1085
@@ -180,7 +180,7 @@
#define ER_ALTER_INFO 1088
"Records: %ld Duplicates: %ld",
#define ER_WRONG_SUB_KEY 1089
-"Incorrect sub part key. The used key part isn't a string or the used length is longer than the key part",
+"Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the table handler doesn't support unique sub keys",
#define ER_CANT_REMOVE_ALL_FIELDS 1090
"You can't delete all columns with ALTER TABLE. Use DROP TABLE instead",
#define ER_CANT_DROP_FIELD_OR_KEY 1091
@@ -300,7 +300,7 @@
#define ER_NOT_ALLOWED_COMMAND 1148
"The used command is not allowed with this MySQL version",
#define ER_SYNTAX_ERROR 1149
-"You have an error in your SQL syntax",
+"You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use",
#define ER_DELAYED_CANT_CHANGE_LOCK 1150
"Delayed insert thread couldn't get requested lock for table %-.64s",
#define ER_TOO_MANY_DELAYED_THREADS 1151
@@ -353,3 +353,125 @@
"This version of MySQL is not compiled with RAID support",
#define ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE 1175
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
+#define ER_KEY_DOES_NOT_EXITS 1176
+"Key '%-.64s' doesn't exist in table '%-.64s'",
+#define ER_CHECK_NO_SUCH_TABLE 1177
+"Can't open table",
+#define ER_CHECK_NOT_IMPLEMENTED 1178
+"The handler for the table doesn't support %s",
+#define ER_CANT_DO_THIS_DURING_AN_TRANSACTION 1179
+"You are not allowed to execute this command in a transaction",
+#define ER_ERROR_DURING_COMMIT 1180
+"Got error %d during COMMIT",
+#define ER_ERROR_DURING_ROLLBACK 1181
+"Got error %d during ROLLBACK",
+#define ER_ERROR_DURING_FLUSH_LOGS 1182
+"Got error %d during FLUSH_LOGS",
+#define ER_ERROR_DURING_CHECKPOINT 1183
+"Got error %d during CHECKPOINT",
+#define ER_NEW_ABORTING_CONNECTION 1184
+"Aborted connection %ld to db: '%-.64s' user: '%-.32s' host: `%-.64s' (%-.64s)",
+#define ER_DUMP_NOT_IMPLEMENTED 1185
+"The handler for the table does not support binary table dump",
+#define ER_FLUSH_MASTER_BINLOG_CLOSED 1186
+"Binlog closed, cannot RESET MASTER",
+#define ER_INDEX_REBUILD 1187
+"Failed rebuilding the index of dumped table '%-.64s'",
+#define ER_MASTER 1188
+"Error from master: '%-.64s'",
+#define ER_MASTER_NET_READ 1189
+"Net error reading from master",
+#define ER_MASTER_NET_WRITE 1190
+"Net error writing to master",
+#define ER_FT_MATCHING_KEY_NOT_FOUND 1191
+"Can't find FULLTEXT index matching the column list",
+#define ER_LOCK_OR_ACTIVE_TRANSACTION 1192
+"Can't execute the given command because you have active locked tables or an active transaction",
+#define ER_UNKNOWN_SYSTEM_VARIABLE 1193
+"Unknown system variable '%-.64s'",
+#define ER_CRASHED_ON_USAGE 1194
+"Table '%-.64s' is marked as crashed and should be repaired",
+#define ER_CRASHED_ON_REPAIR 1195
+"Table '%-.64s' is marked as crashed and last (automatic?) repair failed",
+#define ER_WARNING_NOT_COMPLETE_ROLLBACK 1196
+"Warning: Some non-transactional changed tables couldn't be rolled back",
+#define ER_TRANS_CACHE_FULL 1197
+"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again',
+#define ER_SLAVE_MUST_STOP 1198
+"This operation cannot be performed with a running slave, run SLAVE STOP first",
+#define ER_SLAVE_NOT_RUNNING 1199
+"This operation requires a running slave, configure slave and do SLAVE START",
+#define ER_BAD_SLAVE 1200
+"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
+#define ER_MASTER_INFO 1201
+"Could not initialize master info structure, check permisions on master.info",
+#define ER_SLAVE_THREAD 1202
+"Could not create slave thread, check system resources",
+#define ER_TOO_MANY_USER_CONNECTIONS 1203
+"User %-.64s has already more than 'max_user_connections' active connections",
+#define ER_SET_CONSTANTS_ONLY 1204
+"You may only use constant expressions with SET",
+#define ER_LOCK_WAIT_TIMEOUT 1205
+"Lock wait timeout exceeded; Try restarting transaction",
+#define ER_LOCK_TABLE_FULL 1206
+"The total number of locks exceeds the lock table size",
+#define ER_READ_ONLY_TRANSACTION 1207
+"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
+#define ER_DROP_DB_WITH_READ_LOCK 1208
+"DROP DATABASE not allowed while thread is holding global read lock",
+#define ER_CREATE_DB_WITH_READ_LOCK 1209
+"CREATE DATABASE not allowed while thread is holding global read lock",
+#define ER_WRONG_ARGUMENTS 1210
+"Wrong arguments to %s",
+#define ER_NO_PERMISSION_TO_CREATE_USER 1211
+"%-.32s@%-.64s is not allowed to create new users",
+#define ER_UNION_TABLES_IN_DIFFERENT_DIR 1212
+"Incorrect table definition; All MERGE tables must be in the same database",
+#define ER_LOCK_DEADLOCK 1213
+"Deadlock found when trying to get lock; Try restarting transaction",
+#define ER_TABLE_CANT_HANDLE_FULLTEXT 1214
+"The used table type doesn't support FULLTEXT indexes",
+#define ER_CANNOT_ADD_FOREIGN 1215
+"Cannot add foreign key constraint",
+#define ER_NO_REFERENCED_ROW 1216
+"Cannot add a child row: a foreign key constraint fails",
+#define ER_ROW_IS_REFERENCED 1217
+"Cannot delete a parent row: a foreign key constraint fails",
+#define ER_CONNECT_TO_MASTER 1218
+"Error connecting to master: %-.128s",
+#define ER_QUERY_ON_MASTER 1219
+"Error running query on master: %-.128s",
+#define ER_ERROR_WHEN_EXECUTING_COMMAND 1220
+"Error when executing command %s: %-.128s",
+#define ER_WRONG_USAGE 1221
+"Wrong usage of %s and %s",
+#define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1222
+"The used SELECT statements have a different number of columns",
+#define ER_CANT_UPDATE_WITH_READLOCK 1223
+"Can't execute the query because you have a conflicting read lock",
+#define ER_MIXING_NOT_ALLOWED 1224
+"Mixing of transactional and non-transactional tables is disabled",
+#define ER_DUP_ARGUMENT 1225
+"Option '%s' used twice in statement",
+#define ER_USER_LIMIT_REACHED 1226
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+#define ER_SPECIFIC_ACCESS_DENIED_ERROR 1227
+"Access denied. You need the %-.128s privilege for this operation",
+#define ER_LOCAL_VARIABLE 1228
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+#define ER_GLOBAL_VARIABLE 1229
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+#define ER_NO_DEFAULT 1230
+"Variable '%-.64s' doesn't have a default value",
+#define ER_WRONG_VALUE_FOR_VAR 1231
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+#define ER_WRONG_TYPE_FOR_VAR 1232
+"Wrong argument type to variable '%-.64s'",
+#define ER_VAR_CANT_BE_READ 1233
+"Variable '%-.64s' can only be set, not read",
+#define ER_CANT_USE_OPTION_HERE 1234
+"Wrong usage/placement of '%s'",
+#define 1235
+"This version of MySQL doesn't yet support '%s'",
+#define ER_MASTER_FATAL_ERROR_READING_BINLOG 1236
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
diff --git a/Docs/section.Infolinks.texi b/Docs/section.Infolinks.texi
new file mode 100644
index 00000000000..828722e0e56
--- /dev/null
+++ b/Docs/section.Infolinks.texi
@@ -0,0 +1,880 @@
+@c FIX AGL 20011108 Extracted from manual.texi.
+@c Contains links to MySQL related info (books, articles). To web portals!
+
+
+@node MySQL-Books, General-SQL, Questions, MySQL Information Sources
+@subsection Books About MySQL
+
+For the latest book information, with user comments, please visit
+@uref{http://www.mysql.com/portal/books/html/}.
+
+While this manual is still the right place for up to date technical
+information, its primary goal is to contain everything there is to know
+about MySQL. It is sometimes nice to have a bound book to read
+in bed or while you travel. Here is a list of books about MySQL and
+related subjects (in English).
+
+By purchasing a book through these hyperlinks provided herein, you are
+contributing to the development of MySQL.
+
+@emph{MySQL}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0735709211&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab New Riders
+@item Author @tab Paul DuBois
+@item Pub Date @tab 1st Edition December 1999
+@item ISBN @tab 0735709211
+@item Pages @tab 800
+@item Price @tab $49.99 US
+@item Downloadable examples @tab
+ @uref{http://www.kitebird.com/mysql-book/} (@code{samp_db} distribution)
+@item Errata @tab
+@uref{http://www.kitebird.com/mysql-book/errata.html}
+@end multitable
+
+Foreword by Michael ``Monty'' Widenius, MySQL Moderator.
+@*
+
+In @emph{MySQL}, Paul DuBois provides you with a comprehensive guide to
+one of the most popular relational database systems. Paul has
+contributed to the online documentation for MySQL and is an
+active member of the MySQL community. The principal MySQL
+developer, Monty Widenius, and a network of his fellow developers
+reviewed the manuscript, and provided Paul with the kind of insight
+no one else could supply.
+@*
+
+Instead of merely giving you a general overview of MySQL, Paul
+teaches you how to make the most of its capabilities. Through two
+sample database applications that run throughout the book, he
+gives you solutions to problems you're sure to face. He helps you
+integrate MySQL efficiently with third-party tools, such as PHP
+and Perl, enabling you to generate dynamic Web pages through
+database queries. He teaches you to write programs that access
+MySQL databases, and also provides a comprehensive set of
+references to column types, operators, functions, SQL syntax,
+MySQL programming, C API, Perl @code{DBI}, and PHP API.
+@emph{MySQL} simply gives you the kind of information you won't find
+anywhere else.
+@*
+
+If you use MySQL, this book provides you with:
+@itemize @bullet
+@item
+An introduction to MySQL and SQL.
+@item
+Coverage of MySQL's data types and how to use them.
+@item
+Thorough treatment of how to write client programs in C.
+@item
+A guide to using the Perl @code{DBI} and PHP APIs for developing
+command-line and Web-based applications.
+@item
+Tips on administrative issues such as user accounts, backup,
+crash recovery, and security.
+@item
+Help in choosing an ISP for MySQL access.
+@item
+A comprehensive reference for MySQL's data types, operators,
+functions, and SQL statements and utilities.
+@item
+Complete reference guides for MySQL's C API, the Perl @code{DBI} API,
+and PHP's MySQL-related functions.
+@end itemize
+@*
+
+@emph{MySQL & mSQL}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=1565924347&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab O'Reilly
+@item Authors @tab Randy Jay Yarger, George Reese & Tim King
+@item Pub Date @tab 1st Edition July 1999
+@item ISBN @tab 1-56592-434-7, Order Number: 4347
+@item Pages @tab 506
+@item Price @tab $34.95
+@end multitable
+
+This book teaches you how to use MySQL and @code{mSQL}, two popular
+and robust database products that support key subsets of SQL on both Linux
+and Unix systems. Anyone who knows basic C, Java, Perl, or Python can
+write a program to interact with a database, either as a stand-alone
+application or through a Web page. This book takes you through the
+whole process, from installation and configuration to programming
+interfaces and basic administration. Includes plenty of tutorial
+material.
+@*
+
+@emph{Sams' Teach Yourself MySQL in 21 Days}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0672319144&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Sams
+@item Authors @tab Mark Maslakowski and Tony Butcher
+@item Pub Date @tab June 2000
+@item ISBN @tab 0672319144
+@item Pages @tab 650
+@item Price @tab $39.99
+@end multitable
+
+Sams' @emph{Teach Yourself MySQL in 21 Days} is for intermediate Linux users
+who want to move into databases. A large share of the audience is Web
+developers who need a database to store large amounts of information that
+can be retrieved via the Web.
+
+Sams' @emph{Teach Yourself MySQL in 21 Days} is a practical, step-by-step
+tutorial. The reader will learn to design and employ this open source
+database technology into his or her website using practical, hands-on
+examples to follow.
+@*
+
+@emph{E-Commerce Solutions with MySQL}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0761524452&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Prima Communications, Inc.
+@item Authors @tab N/A
+@item Pub Date @tab January 2000
+@item ISBN @tab 0761524452
+@item Pages @tab 500
+@item Price @tab $39.99
+@end multitable
+
+No description available.
+@*
+
+@emph{MySQL and PHP from Scratch}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0789724405&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Que
+@item Authors @tab N/A
+@item Pub Date @tab September 2000
+@item ISBN @tab 0789724405
+@item Pages @tab 550
+@item Price @tab $34.99
+@end multitable
+
+This book puts together information on installing, setting up, and
+troubleshooting Apache, MySQL, PHP3, and IMP into one complete
+volume. You also learn how each piece is part of a whole by learning,
+step-by-step, how to create a web-based e-mail system. Learn to run
+the equivalent of Active Server Pages (ASP) using PHP3, set up an
+e-commerce site using a database and the Apache web server, and create
+a data entry system (such as sales, product quality tracking, customer
+preferences, etc) that no installation in the PC.
+@*
+
+@emph{Professional MySQL Programming}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://shop.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=1861005164} (Barnes and Noble)
+@item Publisher @tab Wrox Press, Inc.
+@item Authors @tab N/A
+@item Pub Date @tab Late 2001
+@item ISBN @tab 1861005164
+@item Pages @tab 1000
+@item Price @tab $49.99
+@end multitable
+
+No description available.
+@*
+
+@emph{Professional Linux Programming}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=1861003013&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Wrox Press, Inc.
+@item Authors @tab N/A
+@item Pub Date @tab September 2000
+@item ISBN @tab 1861003013
+@item Pages @tab 1155
+@item Price @tab $47.99
+@end multitable
+
+In this follow-up to the best-selling @emph{Beginning Linux Programming},
+you will learn from the authors' real-world knowledge and experience of
+developing software for Linux; you'll be taken through the development
+of a sample 'DVD Store' application, with 'theme' chapters addressing
+different aspects of its implementation. Meanwhile, individual
+``take-a-break'' chapters cover important topics that go beyond the
+bounds of the central theme. All focus on the practical aspects of
+programming, showing how crucial it is to choose the right tools for
+the job, use them as they should be used, and get things right first
+time.
+@*
+
+@emph{PHP and MySQL Web Development}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0672317842&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Sams
+@item Authors @tab Luke Welling, Laura Thomson
+@item Pub Date @tab March 2001
+@item ISBN @tab 0672317842
+@item Pages @tab 700
+@item Price @tab $49.99
+@end multitable
+
+@emph{PHP and MySQL Web Development} introduces you to the advantages
+of implementing both MySQL and PHP. These advantages are detailed
+through the provision of both statistics and several case studies. A
+practical web application is developed throughout the book, providing
+you with the tools necessary to implement a functional online
+database. Each function is developed separately, allowing you the
+choice to incorporate only those parts that you would like to
+implement. Programming concepts of the PHP language are highlighted,
+including functions which tie MySQL support into a PHP script and
+advanced topics regarding table manipulation.
+@*
+
+@strong{Books recommended by the MySQL Developers}
+
+@emph{SQL-99 Complete, Really}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0879305681&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab CMP Books
+@item Authors @tab Peter Gulutzan, Trudy Pelzer
+@item Pub Date @tab April 1999
+@item ISBN @tab 0879305681
+@item Pages @tab 1104
+@item Price @tab $55.96
+@end multitable
+
+This book contains complete descriptions of the new standards for
+syntax, data structures, and retrieval processes of SQL databases. As
+an example-based reference manual, it includes all of the CLI
+functions, information, schema tables, and status codes, as well as a
+working SQL database provided on the companion disk.
+@*
+
+@emph{C, A reference manual}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0133262243&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Prentice Hall
+@item Authors @tab Samuel P. Harbison, Guy L. Steele
+@item Pub Date @tab September 1994
+@item ISBN @tab 0133262243
+@item Pages @tab 480
+@item Price @tab $35.99
+@end multitable
+
+A new and improved revision of the bestselling C language
+reference. This manual introduces the notion of "Clean C", writing C
+code that can be compiled as a C++ program, C programming style that
+emphasizes correctness, portability, maintainability, and
+incorporates the ISO C Amendment 1 (1994) which specifies new
+facilities for writing portable, international programs in C.
+@*
+
+@emph{C++ for Real Programmers}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0120499428&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Academic Press, Incorporated
+@item Authors @tab Jeff Alger, Jim Keogh
+@item Pub Date @tab February 1998
+@item ISBN @tab 0120499428
+@item Pages @tab 388
+@item Price @tab $39.95
+@end multitable
+
+@emph{C++ For Real Programmers} bridges the gap between C++ as described
+in beginner and intermediate-level books and C++ as it is practiced by
+experts. Numerous valuable techniques are described, organised into
+three simple themes: indirection, class hierarchies, and memory
+management. It also provides in-depth coverage of template creation,
+exception handling, pointers and optimisation techniques. The focus of
+the book is on ANSI C++ and, as such, is compiler independent.
+
+@emph{C++ For Real Programmers} is a revision of
+@emph{Secrets of the C++ Masters} and includes a new appendix comparing C++
+with Java. The book comes with a 3.5" disk for Windows with source code.
+@*
+
+@emph{Algorithms in C}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0201514257&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Addison Wesley Longman, Inc.
+@item Authors @tab Robert Sedgewick
+@item Pub Date @tab April 1990
+@item ISBN @tab 0201514257
+@item Pages @tab 648
+@item Price @tab $45.75
+@end multitable
+
+@emph{Algorithms in C} describes a variety of algorithms in a number of
+areas of interest, including: sorting, searching, string-processing, and
+geometric, graph and mathematical algorithms. The book emphasizes
+fundamental techniques, providing readers with the tools to confidently
+implement, run, and debug useful algorithms.
+@*
+
+@emph{Multithreaded Programming with Pthreads}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=0136807291&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab Prentice Hall
+@item Authors @tab Bil Lewis, Daniel J. Berg
+@item Pub Date @tab October 1997
+@item ISBN @tab 0136807291
+@item Pages @tab 432
+@item Price @tab $34.95
+@end multitable
+
+Based on the best-selling @emph{Threads Primer},
+@emph{Multithreaded Programming with Pthreads} gives you a solid
+understanding of Posix threads: what they are, how they work, when to use
+them, and how to optimise them. It retains the clarity and humor of
+@emph{Threads Primer}, but includes expanded comparisons to Win32 and OS/2
+implementations. Code examples tested on all of the major UNIX platforms
+are featured along with detailed explanations of how and why they use threads.
+@*
+
+@emph{Programming the PERL DBI: Database Programming with PERL}
+@multitable @columnfractions .3 .7
+@item Available @tab @uref{http://service.bfast.com/bfast/click?bfmid=2181&sourceid=34233559&bfpid=1565926994&bfmtype=book} (Barnes and Noble)
+@item Publisher @tab O'Reilly & Associates, Incorporated
+@item Authors @tab Alligator Descartes, Tim Bunce
+@item Pub Date @tab February 2000
+@item ISBN @tab 1565926994
+@item Pages @tab 400
+@item Price @tab $27.96
+@end multitable
+
+@emph{Programming the Perl DBI} is coauthored by Alligator Descartes, one
+of the most active members of the DBI community, and by Tim Bunce, the
+inventor of DBI. For the uninitiated, the book explains the architecture
+of DBI and shows you how to write DBI-based programs. For the experienced
+DBI dabbler, this book explains DBI's nuances and the peculiarities of each
+individual DBD.
+
+The book includes:
+@itemize @bullet
+@item
+An introduction to DBI and its design.
+@item
+How to construct queries and bind parameters.
+@item
+Working with database, driver, and statement handles.
+@item
+Debugging techniques.
+@item
+Coverage of each existing DBD.
+@item
+A complete reference to DBI.
+@end itemize
+@*
+
+
+@node General-SQL, Useful Links, MySQL-Books, MySQL Information Sources
+@subsection General SQL Information and Tutorials
+
+The MySQL book portal is split into different sections to make it easy
+to locate books for various purposes.
+@uref{http://www.mysql.com/portal/books/html/}
+
+Tutorials can be found at:
+@uref{http://www.mysql.com/portal/development/html/development-61-1.html}
+
+@node Useful Links, , General-SQL, MySQL Information Sources
+@subsection Useful MySQL-related Links
+
+The MySQL development portal is the ultimate source of MySQL related
+links. @uref{http://www.mysql.com/portal/development/html/}
+
+Apart from the following links, you can find and download a lot of
+MySQL programs, tools and APIs in the Contrib directory
+(@uref{http://www.mysql.com/Downloads/Contrib/}).
+@cindex @code{Contrib} directory
+
+@cindex URLs to MySQL information
+@cindex MySQL related information URLs
+@subheading Tutorials and Manuals
+
+@table @asis
+@item @uref{http://michael.bacarella.com/research/mysqlmyths.html} (MySQL Myths Debunked)
+MySQL used in the real world.
+
+@item @uref{http://www.4t2.com/mysql/}
+Information about the German MySQL mailing list.
+
+@item @uref{http://www2.rent-a-database.de/mysql/}
+MySQL handbook in German.
+
+@item @uref{http://www.bitmover.com:8888/home/bk/mysql/}
+Web access to the MySQL BitKeeper repository.
+
+@item @uref{http://www.analysisandsolutions.com/code/mybasic.htm}
+Beginners MySQL Tutorial on how to install and set up
+MySQL on a Windows machine.
+
+@item @uref{http://www.devshed.com/Server_Side/MySQL/}
+A lot of MySQL tutorials.
+
+@item @uref{http://mysql.hitstar.com/}
+MySQL manual in Chinese.
+
+@item @uref{http://www.linuxplanet.com/linuxplanet/tutorials/1046/1/}
+Setting Up a MySQL-based website.
+
+@item @uref{http://www.hotwired.com/webmonkey/backend/tutorials/tutorial1.html}
+MySQL-Perl tutorial.
+
+@item @uref{http://www.iserver.com/support/contrib/perl5/modules.html}
+Installing new Perl modules that require locally installed modules.
+
+@item @uref{http://www.hotwired.com/webmonkey/databases/tutorials/tutorial4.html}
+PHP/MySQL Tutorial.
+
+@item @uref{http://www.useractive.com/}
+Hands on tutorial for MySQL.
+@end table
+
+@subheading MySQL Discussion Forums
+
+@table @asis
+@item @uref{http://www.weberdev.com/}
+Examples using MySQL; (check Top 20)
+
+@item @uref{http://futurerealm.com/forum/futureforum.htm}
+FutureForum Web Discussion Software.
+@end table
+
+@subheading Porting MySQL/Using MySQL on Different Systems
+
+@table @asis
+@item @uref{http://www.entropy.ch/software/macosx/mysql/}
+Binary of MySQL for Mac OS X Client. Includes information of how to
+build and use MySQL on Mac OS X.
+
+@item @uref{http://xclave.macnn.com/MySQL/}
+The Mac OS Xclave. Running MySQL on Mac OS X.
+
+@item @uref{http://www.prnet.de/RegEx/mysql.html}
+MySQL for Mac OS X Server.
+
+@item @uref{http://www.latencyzero.com/macosx/mysql.html}
+Building MySQL for Mac OS X.
+
+@item @uref{http://www.essencesw.com/Software/mysqllib.html}
+New Client libraries for the Mac OS Classic (Macintosh).
+
+@item @uref{http://www.lilback.com/macsql/}
+Client libraries for Mac OS Classic (Macintosh).
+
+@item @uref{http://sixk.maniasys.com/index_en.html}
+MySQL for Amiga
+@end table
+
+@subheading Perl-related Links
+
+@table @asis
+@item @uref{http://dbimysql.photoflux.com/}
+Perl DBI with MySQL FAQ.
+@end table
+
+@c FIX We should get longer descriptions for things in this category!
+@subheading Commercial Applications that Support MySQL
+
+@table @asis
+@item @uref{http://www.supportwizard.com/}
+SupportWizard; Interactive helpdesk on the Web. This product includes a
+licensed copy of MySQL.
+
+@item @uref{http://www.sonork.com/}
+Sonork, Instant Messenger that is not only Internet oriented. It's
+focused on private networks and on small to medium companies. Client
+is free, server is free for up to 5 seats.
+
+@item @uref{http://www.stweb.org/}
+StWeb - Stratos Web and Application server - An easy-to-use, cross
+platform, Internet/Intranet development and deployment system for
+development of web-enabled applications. The standard version of StWeb
+has a native interface to MySQL database.
+
+@item @uref{http://www.rightnowtech.com/}
+Right Now Web; Web automation for customer service.
+
+@item @uref{http://www.icaap.org/Bazaar/}
+Bazaar; Interactive Discussion Forums with Web interface.
+
+@cindex PhoneSweep
+@item @uref{http://www.phonesweep.com/}
+PhoneSweepT is the world's first commercial Telephone Scanner. Many break-ins
+in recent years have come not through the Internet, but through unauthorised
+dial-up modems. PhoneSweep lets you find these modems by repeatedly placing
+phone calls to every phone number that your organisation
+controls. PhoneSweep has a built-in expert system that can recognise
+more than 250 different kinds of remote-access programs, including
+Carbon Copy(TM), pcANYWHERE(TM), and Windows NT RAS. All information is stored
+in the SQL database. It then generates a comprehensive report detailing
+which services were discovered on which dial-up numbers in your organisation.
+@end table
+
+@subheading SQL Clients and Report Writers
+
+@table @asis
+@item @uref{http://www.urbanresearch.com/software/utils/urbsql/} (urSQL)
+SQL Editor and Query Utility. Custom syntax highlighting, editable
+results grid, exportable result-sets, basic MySQL admin functions,
+Etc.. For Windows.
+
+@item @uref{http://www.edatanew.com/} (MySQL Data Manager)
+MySQL Data Manager * is platform independent web client
+(written in perl) for MySQL server over TCP/IP.
+
+@item @uref{http://ksql.sourceforge.net/}
+KDE MySQL client.
+
+@item @uref{http://www.ecker-software.de/}
+A Windows GUI client by David Ecker.
+
+@item @uref{http://www.icaap.org/software/kiosk/}
+Kiosk; a MySQL client for database management. Written in Perl.
+Will be a part of Bazaar.
+
+@item @uref{http://www.casestudio.com/}
+Db design tool that supports MySQL 3.23.
+
+@item @uref{http://home.skif.net/~voland/zeos/eng/}
+Zeos - A client that supports MySQL, Interbase and PostgreSQL.
+
+@item @uref{http://www.geocities.com/SiliconValley/Ridge/4280/GenericReportWriter/grwhome.html}
+A free report writer in Java
+
+@item @uref{http://www.javaframework.de/}
+MySQLExport - Export of MySQL create statements and data in a lot of
+different formats (SQL, HTML, CVS, text, ZIP, GZIP...).
+
+@item @uref{http://dlabs.4t2.com/}
+M2D, a MySQL Administration client for Windows. M2D supports
+administration of MySQL databases, creation of new databases and
+tables, editing, and more.
+
+@item @uref{http://dlabs.4t2.com/}
+Dexter, a small server written in Perl which can be used as a proxy server for
+MySQL or as a database extender.
+
+@item @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp}
+Mascon is a powerful Win32 GUI for administering MySQL databases.
+
+@item @uref{http://www.rtlabs.com/}
+MacSQL Monitor. GUI for MySQL, ODBC, and JDBC databases for the Mac OS.
+@end table
+
+@subheading Distributions that Include MySQL
+
+@c FIX add the rest (at least a couple more Linuxes)
+
+@table @asis
+@item @uref{http://www.suse.com/}
+SuSE Linux (6.1 and above)
+
+@item @uref{http://www.redhat.com/}
+RedHat Linux (7.0 and above)
+
+@item @uref{http://distro.conectiva.com.br/}
+Conectiva Linux (4.0 and above)
+@end table
+
+@subheading Web Development Tools that Support MySQL
+
+@table @asis
+@item @uref{http://www.php.net/}
+PHP: A server-side HTML-embedded scripting language.
+
+@item @uref{http://www.midgard-project.org/}
+The Midgard Application Server; a powerful Web development environment
+based on MySQL and PHP.
+
+@cindex dbServ
+@item @uref{http://www.dbServ.de/}
+dbServ is an extension to a web server to integrate database output into
+your HTML code. You may use any HTML function in your output. Only the
+client will stop you. It works as standalone server or as Java servlet.
+
+@item @uref{http://www.chilisoft.com/}
+Platform independent ASP from Chili!Soft
+
+@item @uref{http://www.voicenet.com/~zellert/tjFM/}
+A JDBC driver for MySQL.
+
+@item @uref{http://www.wernhart.priv.at/php/}
+MySQL + PHP demos.
+
+@item @uref{http://www.dbwww.com/}
+ForwardSQL: HTML interface to manipulate MySQL databases.
+
+@item @uref{http://www.daa.com.au/~james/www-sql/}
+WWW-SQL: Display database information.
+
+@item @uref{http://www.heitml.com/}
+HeiTML: A server-side extension of HTML and a 4GL language at the same time.
+
+@item @uref{http://hawkeye.net/}
+Hawkeye Internet Server Suite.
+
+@item @uref{http://www.webgroove.com/}
+WebGroove Script: HTML compiler and server-side scripting language.
+
+@item @uref{http://www.ihtml.com/}
+A server-side website scripting language.
+
+@item @uref{ftp://ftp.igc.apc.org/pub/myodbc/README}
+How to use MySQL with ColdFusion on Solaris.
+
+@item @uref{http://calistra.com/MySQL/}
+Calistra's ODBC MySQL Administrator.
+
+@item @uref{http://phpclub.net/}
+PHPclub - Tips and tricks for PHP.
+
+@item @uref{http://www.widgetchuck.com/}
+The Widgetchuck; Website Tools and Gadgets
+
+@item @uref{http://www.adcycle.com/}
+AdCycle - advertising management software.
+
+@cindex pwPage
+@item @uref{http://sourceforge.net/projects/pwpage/}
+pwPage - provides an extremely fast and simple approach to the creation
+of database forms. That is, if a database table exists and an HTML page
+has been constructed using a few simple guidelines, pwPage can be
+immediately used for table data selections, insertions, updates, deletions
+and selectable table content reviewing.
+
+@item @uref{http://www.omnis-software.com/products/studio/studio.html}
+OMNIS Studio is a rapid application development (RAD) tool.
+@end table
+
+@subheading Database Design Tools with MySQL Support
+
+@table @asis
+@item @uref{http://www.mysql.com/documentation/dezign/}
+"DeZign for databases" is a database development tool that uses an
+entity relationship diagram (ERD).
+@end table
+
+@subheading Web Servers with MySQL Tools
+
+@table @asis
+@item @uref{ftp://ftp.kcilink.com/pub/}
+mod_auth_mysql, An Apache authentication module.
+
+@item @uref{http://www.roxen.com/}
+The Roxen Challenger Web server.
+@end table
+
+@subheading Extensions for Other Programs
+
+@table @asis
+@item @uref{http://www.seawood.org/msql_bind/}
+MySQL support for BIND (The Internet Domain Name Server).
+
+@item @uref{http://www.inet-interactive.com/sendmail/}
+MySQL support for Sendmail and Procmail.
+@end table
+
+@subheading Using MySQL with Other Programs
+
+@table @asis
+@item @uref{http://www.iserver.com/support/addonhelp/database/mysql/msaccess.html}
+Using MySQL with Access.
+
+@item @uref{http://www.iserver.com/support/contrib/perl5/modules.html}
+Installing new Perl modules that require locally installed modules.
+@end table
+
+@subheading ODBC-related Links
+
+@table @asis
+@item @uref{http://www.iodbc.org/}
+Popular iODBC Driver Manager (libiodbc) now available as Open Source.
+
+@item @uref{http://users.ids.net/~bjepson/freeODBC/}
+The FreeODBC Pages.
+
+@item @uref{http://genix.net/unixODBC/}
+The unixODBC Project goals are to develop and promote unixODBC to be the
+definitive standard for ODBC on the Linux platform. This is to include GUI
+support for KDE.
+
+@item @uref{http://www.sw-soft.com/products/BtrieveODBC/}
+A MySQL-based ODBC driver for Btrieve.
+@end table
+
+@subheading @strong{API}-related Links
+
+@table @asis
+@item @uref{http://www.jppp.com/}
+Partially implemented TDataset-compatible components for MySQL.
+
+@item @uref{http://www.riverstyx.net/qpopmysql/}
+qpopmysql - A patch to allow POP3 authentication from a MySQL
+database. There's also a link to Paul Khavkine's patch for Procmail to
+allow any MTA to deliver to users in a MySQL database.
+
+@item @uref{http://www.essencesw.com/Software/mysqllib.html}
+New Client libraries for the Mac OS Classic (Macintosh).
+
+@item @uref{http://www.lilback.com/macsql/}
+Client libraries for the Macintosh.
+
+@item @uref{http://www.essencesw.com/Plugins/mysqlplug.html}
+Plugin for REALbasic (for Macintosh)
+
+@item @uref{http://www.iis.ee.ethz.ch/~neeri/macintosh/gusi-qa.html}
+A library that emulates BSD sockets and pthreads on Macintosh. This can
+be used if you want to compile the MySQL client library on Mac.
+It could probably even be sued to port MySQL to Macintosh, but we
+don't know of anyone that has tried that.
+
+@cindex SCMDB
+@item @uref{http://www.dedecker.net/jessie/scmdb/}
+SCMDB - an add-on for SCM that ports the MySQL C library to scheme
+(SCM). With this library scheme developers can make connections to a
+MySQL database and use embedded SQL in their programs.
+@end table
+
+@subheading Other MySQL-related Links
+
+@table @asis
+@item @uref{http://www.satisoft.com/} (SAT)
+The Small Application Toolkit (SAT) is a collection of utilities
+intended to simplify the development of small, multi-user, GUI based
+applications in a (Microsoft -or- X) Windows Client / Unix Server
+environment.
+
+@item @uref{http://www.wix.com/mysql-hosting/}
+Registry of Web providers who support MySQL.
+
+@item @uref{http://www.softagency.co.jp/mysql/index.en.html}
+Links about using MySQL in Japan/Asia.
+
+@item @uref{http://abattoir.cc.ndsu.nodak.edu/~nem/mysql/udf/}
+MySQL UDF Registry.
+
+@item @uref{http://www.open.com.au/products.html}
+Commercial Web defect tracking system.
+
+@item @uref{http://www.stonekeep.com/pts/}
+PTS: Project Tracking System.
+
+@item @uref{http://tomato.nvgc.vt.edu/~hroberts/mot/}
+Job and software tracking system.
+
+@item @uref{http://www.cynergi.net/exportsql/}
+ExportSQL: A script to export data from Access95+.
+
+@item @uref{http://SAL.KachinaTech.COM/H/1/MYSQL.html}
+SAL (Scientific Applications on Linux) MySQL entry.
+
+@item @uref{http://www.infotech-nj.com/itech/index.shtml}
+A consulting company which mentions MySQL in the right company.
+
+@item @uref{http://www.pmpcs.com/}
+PMP Computer Solutions. Database developers using MySQL and
+@code{mSQL}.
+
+@item @uref{http://www.dedserius.com/y2kmatrix/}
+Y2K tester.
+@end table
+
+@subheading SQL and Database Interfaces
+
+@table @asis
+@item @uref{http://java.sun.com/products/jdbc/}
+The JDBC database access API.
+
+@item @uref{http://www.gagme.com/mysql/}
+Patch for @code{mSQL} Tcl.
+
+@item @uref{http://www.amsoft.ru/easysql/}
+EasySQL: An ODBC-like driver manager.
+
+@item @uref{http://www.lightlink.com/hessling/rexxsql.html}
+A REXX interface to SQL databases.
+
+@c @item @uref{http://www.mytcl.cx/}
+@c Tcl interface based on tcl-sql with many bugfixes.
+
+@item @uref{http://www.binevolve.com/~tdarugar/tcl-sql/}
+Tcl interface for MySQL.
+
+@item @uref{http://www.contrib.andrew.cmu.edu/~shadow/sql.html}
+SQL Reference Page with a lot of interesting links.
+
+@end table
+
+@subheading Examples of MySQL Use
+
+@table @asis
+@c Added 990601
+@c EMAIL: thuss@little6.com (Todd Huss)
+@item @uref{http://www.little6.com/about/linux/}
+Little6 Inc., An online contract and job finding site that is powered by
+MySQL, PHP3, and Linux.
+
+@c Added 990521
+@c EMAIL: info@worldrecords.com (Jim Rota)
+@item @uref{http://www.worldrecords.com/}
+World Records - A search engine for information about music that uses
+MySQL and PHP.
+
+@item @uref{http://www.webtechniques.com/archives/1998/01/note/}
+A Contact Database using MySQL and PHP.
+
+@item @uref{http://modems.rosenet.net/mysql/}
+Web based interface and Community Calendar with PHP.
+
+@item @uref{http://www.odbsoft.com/cook/sources.htm}
+Perl package to generate html from a SQL table structure and for generating
+SQL statements from an html form.
+
+@item @uref{http://www.gusnet.cx/proj/telsql/}
+Basic telephone database using @code{DBI}/@code{DBD}.
+
+@item @uref{http://tecfa.unige.ch/guides/java/staf2x/ex/jdbc/coffee-break/}
+JDBC examples by Daniel K. Schneider.
+
+@item @uref{http://www.ooc.com/}
+Object Oriented Concepts Inc; CORBA applications with examples in source.
+
+@c EMAIL: paul@sword.damocles.com (Paul Bannister)
+@item @uref{http://www.stopbit.com/}
+Stopbit - A technology news site using MySQL and PHP.
+
+@item @uref{http://www.penguinservices.com/scripts/}
+Online shopping cart system.
+
+@c Added 990928 from editor@city-gallery.com
+@cindex Old Photo Album
+@item @uref{http://www.city-gallery.com/album/}
+Old Photo Album - The album is a collaborative popular history of photography
+project that generates all pages from data stored in a MySQL
+database. Pages are dynamically generated through a php3 interface to the
+database content. Users contribute images and descriptions. Contributed
+images are stored on the web server to avoid storing them in the database
+as BLOBs. All other information is stored on the shared MySQL server.
+@end table
+
+@subheading General Database Links
+
+@table @asis
+@item @uref{http://black.hole-in-the.net/guy/webdb/}
+Homepage of the webdb-l (Web Databases) mailing list.
+
+@item @uref{http://www.symbolstone.org/technology/perl/DBI/}
+Perl @code{DBI}/@code{DBD} modules homepage.
+
+@item @uref{http://www.student.uni-koeln.de/cygwin/}
+Cygwin tools. Unix on top of Windows.
+
+@cindex Tek-Tips forums
+@cindex forums, Tek-Tips
+@item @uref{http://www.tek-tips.com/}
+Tek-Tips Forums are 800+ independent peer-to-peer non-commercial support
+forums for Computer Professionals. Features include automatic e-mail
+notification of responses, a links library, and member confidentiality
+guaranteed.
+
+@item @uref{http://www.public.asu.edu/~peterjn/btree/}
+B-Trees: Balanced Tree Data Structures.
+
+@item @uref{http://www.fit.qut.edu.au/~maire/baobab/lecture/sld001.htm}
+A lecture about B-Trees.
+@end table
+
+
diff --git a/Docs/section.Testimonials.texi b/Docs/section.Testimonials.texi
new file mode 100644
index 00000000000..e757a6a92d0
--- /dev/null
+++ b/Docs/section.Testimonials.texi
@@ -0,0 +1,31 @@
+@c FIX AGL 20011108 Extracted from manual.texi.
+@c Should only be on website with new submits by webform.
+
+
+@node MySQL Testimonials, Contrib, Users, Top
+@appendix MySQL Testimonials
+
+@cindex MySQL Testimonials
+
+The section 'MySQL Users' contains a lot of different links to
+MySQL users but doesn't provide that much information about how
+they are using MySQL. @xref{Users}. This section gives you an idea
+of how other MySQL users are using MySQL to solve their problems.
+
+Please note that all new stories are added on the MySQL website,
+@uref{http://www.mysql.com/}.
+Do let us know about @emph{your} success story too!
+
+@itemize @bullet
+@item
+@strong{Peter Zaitsev of Spylog.ru} writes:
+I think you might be interested in my database size. The whole database
+is currently on 15 servers and I think it's about 60.000 of tables
+containing about 5.000.000.000 of rows. My mostly loaded server
+currently holds about 10.000 of tables with 1.000.000.000 of rows in it.
+Hugest tables have about 50.000.000 of rows, and this value will raise
+as soon as I'll move to 2.4 kernel with large files. Currently I have to
+delete much of logs for large sites to hold table sizes in 2Gb.
+
+@item
+
diff --git a/Docs/section.Users.texi b/Docs/section.Users.texi
new file mode 100644
index 00000000000..3c8d219fa16
--- /dev/null
+++ b/Docs/section.Users.texi
@@ -0,0 +1,414 @@
+@c FIX AGL 20011108 Extracted from manual.texi.
+@c Should only be on website.
+
+
+@node Users, Contrib, Problems, Top
+@appendix MySQL Users
+
+@cindex users, of MySQL
+@cindex news sites
+
+This appendix lists users of MySQL that have given us permission
+to list them in our documentation. It is by far not a complete list, but
+should give you a general idea of who uses MySQL and what it can
+be used for.
+
+@appendixsec General News Sites
+
+@itemize @bullet
+
+@item @uref{http://www.yahoo.com/} (Yahoo!)
+
+@item @uref{http://slashdot.org/} (Slashdot: A pro-Linux/tech news and comment/discussion site)
+
+@item @uref{http://www.linux.com/} (All about Linux)
+
+@item @uref{http://www.linuxtoday.com/} (Linuxtoday)
+
+@item @uref{http://www.32bitsonline.com/} (32Bits Online: because there's
+more than one way to compute)
+
+@item @uref{http://www.freshmeat.net/} (Freshmeat: News about new versions of computer-related stuff)
+
+@end itemize
+
+@cindex search engines, web
+@cindex web search engines
+@appendixsec Web Search Engines
+
+@itemize @bullet
+
+@item @uref{http://www.aaa.com.au/} (AAA Matilda Web Search)
+@item @uref{http://www.whatsnu.com/} (What's New)
+@item @uref{http://www.aladin.de/} (Aladin)
+@item @uref{http://www.columbus-finder.de/} (Columbus Finder)
+@item @uref{http://www.spider.de/} (Spider)
+@item @uref{http://www.blitzsuche.de/} (Blitzsuche)
+@item @uref{http://www.indoseek.co.id/} (Indoseek Indonesia)
+@item @uref{http://www.yaboo.dk/} (Yaboo - Yet Another BOOkmarker)
+@item @uref{http://www.ozsearch.com.au/} (OzSearch Internet Guide)
+@item @uref{http://www.splatsearch.com/} (Splat! Search)
+@item @uref{http://osdls.library.arizona.edu/} (The Open Source Digital Library System Project)
+@end itemize
+
+@appendixsec Information Search Engines Specialising in a Particular Area
+
+@itemize @bullet
+
+@item @uref{http://www.spylog.ru/} (SpyLOG ; A very popular Web counter site)
+
+@item @uref{http://www.tucows.com/} (TuCows Network; Free Software archive)
+
+@item @uref{http://www.jobvertise.com/} (Jobvertise: Post and search for jobs)
+
+@item @uref{http://www.musicdatabase.com/} (The Music Database)
+
+@item @uref{http://www.soccersearch.com/} (Football -Soccer- search page)
+
+@item @uref{http://www.headrush.net/takedown} (TAKEDOWN - wrestling)
+
+@item @uref{http://www.lyrics.net/} (The International Lyrics Network)
+
+@item @uref{http://TheMatrix.com/~matrix/band_search.phtml} (Musicians looking for other musicians; free service)
+
+@item @uref{http://www.addall.com/AddBooks/Stores.html} (AddALL books searching and price comparison)
+
+@item @uref{http://www.herbaria.harvard.edu/Data/Gray/gray.html} (Harvard's Gray Herbarium Index of Plant Names)
+
+@item @uref{http://www.game-developer.com/} (The Game Development Search Engine)
+
+@item @uref{http://www.theinnkeeper.com/} (The Innkeeper Vacation Guides)
+
+@item @uref{http://www.macgamedatabase.com/} (The Mac Game Database uses PHP and MySQL)
+@c From: Marc Antony Vose <suzerain@suzerain.com>
+
+@item @uref{http://www.csse.monash.edu.au/publications/} (Research
+Publications at Monash University in Australia)
+
+@item @uref{http://www.ipielle.emr.it/bts/}
+(Occupational Health & Safety Website database; a project for the ECC)
+@c c.presutti@ipielle.emr.it
+
+@item @uref{http://data.mch.mcgill.ca/} (Bioinformatics databases at the
+Montreal Children's Hospital using MySQL)
+@c saeed@www.debelle.mcgill.ca
+@end itemize
+
+@cindex online magazines
+@cindex magazines, online
+@appendixsec Online Magazines
+
+@itemize @bullet
+@item @uref{http://www.spoiler.com/} (Spoiler Webzine)
+An online magazine featuring music, literature, arts, and design content.
+@item @uref{http://www.linux-magazin.de/newsflash/} (Daily news about Linux in German language)
+@item @uref{http://www.betazine.com/} (Betazine - The Ultimate Online Beta Tester's Magazine)
+@item @uref{http://www.currents.net/ccinfo/aboutcc.html} (Computer Currents Magazine)
+@end itemize
+
+@cindex websites
+@appendixsec Websites that Use MySQL as a Backend
+
+@itemize @bullet
+
+@item @uref{http://liftoff.msfc.nasa.gov/} (NASA)
+@item @uref{http://kids.msfc.nasa.gov/} (NASA KIDS)
+@item @uref{http://science.nasa.gov/} (Sience@@NASA)
+
+@item @uref{http://www.handy.de/} (handy.de)
+
+@item @uref{http://lindev.jmc.tju.edu/qwor/} (Qt Widget and Object Repository)
+
+@item @uref{http://www.samba-choro.com.br/} (Brazilian samba site; in Portuguese)
+
+@item @uref{http://pgss.iss.uw.edu.pl/en_index.ISS} (Polish General Social Survey)
+
+@item @uref{http://www.expo2000.com/} Expo2000 - world-wide distribution of
+tickets for this event is implemented using MySQL and Tcl/Tk. More than
+5000 travel agencies all over the world have access to it.
+
+@item @uref{http://www.freevote.com/} FreeVote.com is a free voting
+service with millions of users.
+
+@item @uref{http://f1.tauzero.se/} (Forza Motorsport)
+
+@item @uref{http://www.dreamhost.com/} (DreamHost Web Hosting)
+
+@end itemize
+
+@cindex services
+@appendixsec Domain/Internet/Web and Related Services
+
+@itemize @bullet
+
+@item @uref{http://www.wix.com/mysql-hosting/} (Registry of Web providers that
+support MySQL)
+
+@item @uref{http://www.yi.org/} (Dynamic DNS Services)
+
+@item @uref{http://www.dynodns.net/} (Dynamic domain name service)
+
+@item @uref{http://www.ods.org/} (Open DNS Project; free dynamic DNS service)
+
+@c @item @uref{http://dynodns.net/} (Free dynamic DNS implementation)
+@c EMAIL: A Moore <amoore@mooresystems.com>
+
+@item @uref{http://www.hn.org/} (Hammernode; Public DNS Servers)
+
+@item @uref{http://www.fdns.net/} (Free 3rd level domains)
+
+@item @uref{http://worldcommunity.com/} (Online Database)
+
+@item @uref{http://www.bigbiz.com/} (BigBiz Internet Services)
+
+@item @uref{http://virt.circle.net/} (The Virt Gazette)
+
+@item @uref{http://www.california.com/} (Global InfoNet Inc)
+
+@item @uref{http://www.webhosters.com/} (WebHosters - A Guide to WWW Providers)
+
+@item @uref{http://online.dn.ru/} (Internet information server)
+
+@item @uref{http://www.worldnetla.net/} (WorldNet Communications - An Internet Services Provider)
+
+@item @uref{http://www.netizen.com.au/} (Netizen: Australian-based Web consultancy)
+
+@item @uref{http://www.trainingpages.co.uk/} (Search site for training courses in the UK)
+
+@item @uref{http://chat.nitco.com/} (Gannon Chat; GPL. Written in Perl and Javascript)
+
+@item @uref{http://www.addurls.com/} (A general links directory)
+
+@item @uref{http://www.bookmarktracker.com/} (A Web-based bookmark management service)
+
+@item @uref{http://www.cdrom.com/} (Walnut Creek CDROM)
+
+@item @uref{http://www.wwwthreads.org/} (WWWThreads; Interactive discussion Forums)
+
+@item @uref{http://pvmon.portici.enea.it/Meteo/} (In Italian; Storage data from meteo station)
+
+@item @uref{http://www.buysell.net/} (Online "Person To Person" Auction)
+
+@item @uref{http://tips.pair.com/} (Tips on Web development)
+
+@item @uref{http://www.mailfriends.com/} (Mailfriends.com is a FREE service for
+everybody who wants to find friends over the internet)
+
+@item @uref{http://www.uninova.com/cgi-bin/wctelnets?list} (Web Page Telnet BBS List)
+
+@item @uref{http://www.uninova.com/cnc.html} (UniNova Digital Postcards)
+
+@c @item @uref{http://cabinboy.powersurfr.com/} (An Internet RFC search engine)
+
+@item @uref{http://www.dslreports.com/} (DSL-provider search with reviews)
+Made with MySQL and Modperl, all pages are generated dynamically out of
+the MySQL database
+@end itemize
+
+@cindex PHP, websites
+@appendixsec Websites that Use @code{PHP} and MySQL
+
+@itemize @bullet
+@c @item @uref{http://www.wh200th.com/} (White House 200th Anniversary site)
+
+@item @uref{http://support.jgaa.com/} (Jgaa's Internet - Official Support Site)
+
+@item @uref{http://io.incluso.com/} (Ionline - online publication) MySQL,
+PHP, Java, Web programming, DB development
+
+@item @uref{http://www.baboo.com/} (BaBoo - Browse and Bookmark. Free Web-based bookmark manager and Calendar)
+
+@item @uref{http://www.courses.pjc.cc.fl.us/Schedule/}
+(Course Schedule System at Pensacola Junior College)
+
+@item @uref{http://www.fccj.org/} (Florida Community College at Jacksonville)
+
+@item @uref{http://www.32bit.com/} (32bit.com; An extensive shareware / freeware archive)
+
+@item @uref{http://www.jokes2000.com/} (Jokes 2000)
+@c Added 990604; EMAIL: ah@dybdahl.dk
+
+@item @uref{http://www.burken.nu/}
+Burken is a webhotel that provides scripts, among other things,
+for remote users, like counters, guestbooks etc.
+@c Added 990608; EMAIL: spacedmp@SpaceDump.Burken.NU (Anders Olausson)
+
+@item @uref{http://tips.pair.com/}
+Contains tips on html, javascript, 2d/3d graphics, and PHP3/MySQL.
+All pages are generated from a database.
+@c Added 990614; EMAIL: downey@image.dk (Rune Madsen)
+
+@item @uref{http://www.softwarezrus.com/}
+Ecommerce site that is selling computers.
+@end itemize
+
+@cindex consultants, list of
+@appendixsec MySQL Consultants
+
+@itemize @bullet
+
+@item @uref{http://www.ayni.com/} (Ayni AG)
+
+@item @uref{http://worldcommunity.com/} (Online Database)
+
+@item @uref{http://www2.dataguard.no/} (DataGuard; Uses MySQL and PHP)
+
+@item @uref{http://wwits.net/programs/mysql.phtml} (WWITS; uses MySQL and PHP)
+
+@item @uref{http://www.worldcommunity.com/} (WCN - The World Community Network)
+
+@item @uref{http://www.chipcastle.com/} (Chip Castle Dot Com Inc)
+@c Added 990603 EMAIL: chip@chipcastle.com (Chip Castle)
+
+@item @uref{http://www.cyber.com.au/} (Cybersource Pty. Ltd)
+
+@item @uref{http://www.spring.de/} (Spring infotainment gmbh & co. kg)
+@c added 990905 "Oliver Pischke" <opischke@spring.de>
+
+@item @uref{http://www.wamdesign.com/} (Wam Design develops websites using MySQL)
+@c Added 990905; max@wamdesign.com
+
+@item @uref{http://www.berkeleyconsultants.com/} (Berkeley Consultants Group)
+
+@item @uref{http://www.jammconsulting.com/} (JAMM Consulting Inc)
+
+@end itemize
+
+@c Commented out by Arjen 011018, section is empty!
+@c appendixsec Programming
+
+@cindex web pages, miscellaneous
+@appendixsec Uncategorised Pages
+
+@itemize @bullet
+
+@item @uref{http://www.feature-showcase.com/htmls/demo_mysql.sql} (AZC.COM's Feature Showcase)
+
+@item @uref{http://www.teach.org.uk/subjects/trainingcourse/g.html} (Course Search)
+
+@item @uref{http://www.northerbys.com/} (Northerbys Online Auctions)
+
+@item @uref{http://www.schiphol.nl/flights/home.htm} (Amsterdam Airport Schiphol)
+
+@item @uref{http://TheMatrix.com/seventhsin/query.phtml} (CD database)
+
+@item @uref{http://TheMatrix.com/~flmm/GEAR.html} (Used Audio Gear Database)
+
+@item @uref{http://www.kiss.de/musik-mueller/} (Musical note-sheets)
+
+@item @uref{http://www.bagism.com/} (Bagism; A John Lennon fan page)
+
+@item @uref{http://www.selftaught.com/} (US Folk art broker)
+
+@item @uref{http://organizer.net/} (Mail reading on the Web)
+
+@item @uref{http://www.mypage.org/} (Free home pages on www.somecoolname.mypage.org)
+
+@item @uref{http://www.schulweb.de/} (Der Server f@"ur Schulen im Web - in German)
+
+@item @uref{http://www.ald.net/} (Auldhaefen Online Services)
+
+@item @uref{http://www.cary.net/} (CaryNET Information Center)
+
+@item @uref{http://www.dataden.com/} (Dataden Computer Systems)
+
+@item @uref{http://andree.grm.se/} (Andr@'emuseet; in Swedish)
+
+@item @uref{http://www.him.net/} (HOMESITE Internet Marketing)
+
+@item @uref{http://www.jade-v.com/techinfo.html} (Jade-V Network Services)
+
+@item @uref{http://ww2010.atmos.uiuc.edu/(Gl)/abt/aknw/tech.rxml}
+Weather World 2010 Technical Credits
+
+@item @uref{http://gimp.foebud.org/registry/doc/}
+About The Gimp plugin registry
+
+@item @uref{http://www.fast-inc.com/Products/Archiver/database.html}
+Java tool; archiver technical detail (Slightly optimistic about MySQL
+ANSI-92 compliance)
+
+@item @uref{http://www.gamesdomain.com/cheats/usrcheat.phtml} (Games Domain Cheats Database)
+
+@item @uref{http://www.kcilink.com/poweredby/} (The "Powered By" Page; Kcilink)
+
+@item @uref{http://www.netcasting.net/index.whtml} (Netcasting)
+
+@item @uref{http://homepages.tig.com.au/~mjj/nbltips} (NBL: Australian National Basketball League; tipping)
+
+@item @uref{http://www.cgishop.com/} (CGI shop)
+
+@item @uref{http://www.whirlycott.com/} (Whirlycott: Website Design)
+
+@item @uref{http://www.mtp.dk/} (Museum Tusculanum Press)
+
+@item @uref{http://csdgi.historie.ku.dk/biblio/} (Centro Siciliano di Documentazione)
+
+@item @uref{http://caribou.dyn.ml.org:8000/} (Quake statistics database)
+
+@item @uref{http://www.astroforum.ch/} (Astroforum: Astrologie and related things; in German)
+
+@item @uref{http://www.opendebate.com/} (OpenDebate - Interactive Polls & Open Discussion)
+
+@item @uref{http://vermeer.organik.uni-erlangen.de/dissertationen/} (Online chemical dissertation server)
+
+@item @uref{http://www.freschinfo.com/} (FreSch! The Free Scholarship Search Service)
+
+@item @uref{http://www.nada.kth.se/~staffanu/pinball/} (Stockholm Pinball Locator)
+
+@item @uref{http://www.hek.com/} (HEK - a construction company)
+
+@item @uref{http://www.ebi.nl/} (Elsevier Business Information)
+
+@item @uref{http://vaccination.medicallink.se/} (Medical Links; using ColdFusion and MySQL)
+
+@item @uref{http://www.joblink-usa.com/} (Search for jobs & people at JobLink-USA)
+
+@item @uref{http://www.skydive.net/competfs/} (Competition Formation Skydiving)
+
+@item @uref{http://www.galaxy-net.net/} (Galaxy-NET Telecommunications; E-commerce and internal accounting)
+
+@item @uref{http://www.borsen.dk/} (Denmark's leading business daily newspaper B@o{}rsen)
+
+@item @uref{http://tmmm.simplenet.com/indb/} (The Internet NES Database)
+
+@item @uref{http://www.russia.cz/} (Travel agency in Prague in 3 languages)
+
+@item @uref{http://www.linkstation.de/} (Linkstation)
+
+@item @uref{http://www.peoplestaff.com/} (Searchable online database at Peoplestaff)
+
+@item @uref{http://www.dreamhorse.com/} (A searchable database system for horse classified ads)
+
+@item @uref{http://pootpoot.com/} (The Poot site)
+
+@item @uref{http://grateful.net/hw_html/} ("Playin' in the LAN"; a network monitoring suite)
+
+@c Update from Christopher Milton <cmilton@bwn.net> 1999-12-21
+@item @uref{http://www.usapa.army.mil/} (U.S. Army Publishing Agency)
+
+@item @uref{http://www.nekretnine.co.yu/} (Realestate handling in Yugoslavia)
+
+@item @uref{http://demo.cpsoft.com/pims/devFAQ.html} (PIMS; a Patient Information Management System)
+
+@item @uref{http://cpsoft.com/} (Pilkington Software Inc)
+
+@item @uref{http://www.no-quarter.org/} (A Vietnam Veteran's Memorial - The Wall - database)
+
+@item @uref{http://www.gamers-union.com/} (Gamer's Union specializes in auctions of used & out-of-print gaming material)
+
+@item @uref{http://www.montereyhigh.com/office/dbul.php3} (A daily bulletin at Monterey High school)
+
+@item @uref{http://www.myEastside.com/} (Community-owned site serving Lake
+Washington's Eastside residents and businesses)
+
+@item @uref{http://bowling-france.net/} (French bowling site)
+@end itemize
+
+Send any additions to this list to @email{webmaster@@mysql.com}.
+
+@page
+
+
+
+
diff --git a/Images/.cvsignore b/Images/.cvsignore
deleted file mode 100644
index 6d0d61a83d5..00000000000
--- a/Images/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-logo_nusphere_b.tif
diff --git a/Makefile.am b/Makefile.am
index 41852d89ee5..8aef19d0920 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,18 +19,24 @@
AUTOMAKE_OPTIONS = foreign
# These are built from source in the Docs directory
-EXTRA_DIST = INSTALL-SOURCE README \
- COPYING COPYING.LIB
+EXTRA_DIST = INSTALL-SOURCE README COPYING
SUBDIRS = . include @docs_dirs@ @readline_dir@ \
- @thread_dirs@ @sql_client_dirs@ \
- @sql_server_dirs@ scripts tests man \
- @bench_dirs@ support-files os2
+ @thread_dirs@ pstack @sql_client_dirs@ \
+ @sql_server_dirs@ scripts man tests \
+ BUILD @netware_dir@ os2 @libmysqld_dirs@ \
+ @bench_dirs@ support-files @fs_dirs@ @tools_dirs@
+
# Relink after clean
-CLEANFILES = linked_client_sources linked_server_sources linked_libmysql_sources linked_libmysql_r_sources linked_include_sources
+linked_sources = linked_client_sources linked_server_sources \
+ linked_libmysql_sources linked_libmysql_r_sources \
+ linked_libmysqld_sources linked_libmysqldex_sources \
+ linked_include_sources @linked_netware_sources@
+
+CLEANFILES = $(linked_sources)
# This is just so that the linking is done early.
-config.h: linked_include_sources linked_client_sources linked_server_sources linked_libmysql_sources linked_libmysql_r_sources
+config.h: $(linked_sources)
linked_include_sources:
cd include; $(MAKE) link_sources
@@ -48,6 +54,18 @@ linked_libmysql_r_sources: linked_libmysql_sources
cd libmysql_r; $(MAKE) link_sources
echo timestamp > linked_libmysql_r_sources
+linked_libmysqld_sources:
+ cd libmysqld; $(MAKE) link_sources
+ echo timestamp > linked_libmysqld_sources
+
+linked_libmysqldex_sources:
+ cd libmysqld/examples; $(MAKE) link_sources
+ echo timestamp > linked_libmysqldex_sources
+
+linked_netware_sources:
+ cd @netware_dir@; $(MAKE) link_sources
+ echo timestamp > linked_netware_sources
+
#avoid recursive make calls in sql directory
linked_server_sources:
cd sql; rm -f mini_client_errors.c;@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
@@ -58,11 +76,18 @@ init-db: all
$(top_builddir)/scripts/mysql_install_db
bin-dist: all
- $(top_builddir)/scripts/make_binary_distribution
+ $(top_builddir)/scripts/make_binary_distribution @MAKE_BINARY_DISTRIBUTION_OPTIONS@
+
+# Remove BK's "SCCS" subdirectories from source distribution
+dist-hook:
+ rm -rf `find $(distdir) -type d -name SCCS`
+tags:
+ support-files/build-tags
.PHONY: init-db bin-dist
# Test installation
test:
cd mysql-test ; ./mysql-test-run
+
diff --git a/README b/README
index b1f4ab52369..29851358765 100644
--- a/README
+++ b/README
@@ -1,8 +1,8 @@
This is a release of MySQL, a GPL (free) SQL database server (more
licence information in the PUBLIC file and in the reference manual).
-Please read the Upgrading section in the manual if emigration from
-3.20.# to 3.21.#. Otherwise it wont work!!
+Please read the "Upgrading from..." section in the manual first, if you are
+migrating from older versions of MySQL!
The latest information about MySQL can be found at:
http://www.mysql.com
@@ -24,13 +24,11 @@ For examples of SQL and benchmarking information see the bench
directory.
The manual mentioned above can be found in the Docs directory. The
-manual is available in the following formats: as text in
-Docs/manual.txt, as HTML in Docs/manual_toc.html, as GNU Info in
+manual is available in the following formats: as plain ASCII text in
+Docs/manual.txt, in HTML format in Docs/manual_toc.html, as GNU Info in
Docs/mysql.info and as PostScript in Docs/manual.ps.
-For a contributed user manual see http://www.turbolift.com/mysql.
-
-MySQL is brought to you by the MySQL team at MySQL AB
+MySQL is brought to you by the MySQL team at MySQL AB
For a list of developers and other contributors, see the Credits appendix
in the manual.
@@ -48,7 +46,7 @@ and start your editor with a form in which you can describe your
problem. Bug reports might be silently ignored by the MySQL
maintainers if there is not a good reason included in the report as to
why mysqlbug has not been used. A report that says 'MySQL does not
-work for me. Why?' is not consider a valid bug report.
+work for me. Why?' is not considered a valid bug report.
-The mysqlbug script can be found in the 'scripts' directory in the
-distribution, that is 'there-you-installed-mysql/scripts'.
+The mysqlbug script can be found in the 'scripts' directory of the
+distribution, that is '<where-you-installed-mysql>/scripts'.
diff --git a/SSL/NOTES b/SSL/NOTES
new file mode 100644
index 00000000000..413c724c583
--- /dev/null
+++ b/SSL/NOTES
@@ -0,0 +1,376 @@
+Quick notes:
+--------------------------------------------
+[tonu@x153 mysql-4.0]$ cat /etc/my.cnf
+[mysqld]
+ssl-ca=SSL/cacert.pem
+ssl-cert=SSL/server-cert.pem
+ssl-key=SSL/server-key.pem
+
+[mysql]
+ssl-ca=SSL/cacert.pem
+ssl-cert=SSL/client-cert.pem
+ssl-key=SSL/client-key.pem
+
+[mysqldump]
+ssl-ca=SSL/cacert.pem
+ssl-cert=SSL/client-cert.pem
+ssl-key=SSL/client-key.pem
+
+[tonu@x153 mysql-4.0]$
+--------------------------------------------
+To remove passwords from keyfiles:
+[tonu@x153 SSL]$ openssl rsa -inform pem < server-req.pem > server-key.pem
+read RSA key
+Enter PEM pass phrase:
+writing RSA key
+[tonu@x153 SSL]$
+--------------------------------------------
+To run server:
+
+sql/mysqld --ssl-ca=SSL/cacert.pem --ssl-cert=SSL/server-cert.pem --ssl-key=SSL/server-key.pem --skip-grant --debug='d:t:O,-' > /tmp/mysqld.trace
+--------------------------------------------
+To run client:
+
+client/mysql --ssl-ca=SSL/cacert.pem --ssl-cert=SSL/server-cert.pem --ssl-key=SSL/server-key.pem --debug='d:t:O,/tmp/client.trace' -h 127.0.0.1
+--------------------------------------------
+openssl s_client -host 127.0.0.1 -port 1111 -debug -verify 1 -cert ../SSL/client-cert.pem -key ../SSL/client-key.pem -CAfile ../SSL/cacert.pem -pause -showcerts -state
+
+--------------------------------------------
+openssl s_server -port 1111 -cert ../SSL/server-cert.pem -key ../SSL/server-key.pem
+
+
+
+
+--------------------------------------------
+
+CA stuff:
+
+[tonu@x153 bin]$ pwd
+/usr/local/ssl/bin
+[tonu@x153 bin]$
+[tonu@x153 bin]$ ./CA.sh
+[tonu@x153 bin]$ ./CA.sh -h
+usage: CA -newcert|-newreq|-newca|-sign|-verify
+[tonu@x153 bin]$
+[root@x153 bin]# ./CA.sh -newca
+CA certificate filename (or enter to create)
+
+Making CA certificate ...
+Using configuration from /usr/lib/ssl/openssl.cnf
+Generating a 1024 bit RSA private key
+.++++++
+................++++++
+writing new private key to './demoCA/private/./cakey.pem'
+Enter PEM pass phrase:
+Verifying password - Enter PEM pass phrase:
+phrase is too short, needs to be at least 4 chars
+Enter PEM pass phrase:
+Verifying password - Enter PEM pass phrase:
+-----
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+ountry Name (2 letter code) [AU]:FI
+State or Province Name (full name) [Some-State]:
+Locality Name (eg, city) []:Helsinki
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL Finland AB
+Organizational Unit Name (eg, section) []:
+Common Name (eg, YOUR name) []:Tonu Samuel
+Email Address []:tonu@mysql.com
+[root@x153 bin]#
+[root@x153 bin]# ls -la demoCA/
+total 13
+drwxr-xr-x 6 root root 232 Jun 24 18:50 ./
+drwxr-xr-x 3 root root 2136 Jun 24 18:41 ../
+-rw-r--r-- 1 root root 1241 Jun 24 18:50 cacert.pem
+drwxr-xr-x 2 root root 48 Jun 24 18:41 certs/
+drwxr-xr-x 2 root root 48 Jun 24 18:41 crl/
+-rw-r--r-- 1 root root 0 Jun 24 18:44 index.txt
+drwxr-xr-x 2 root root 48 Jun 24 18:41 newcerts/
+drwxr-xr-x 2 root root 80 Jun 24 18:44 private/
+-rw-r--r-- 1 root root 3 Jun 24 18:44 serial
+[root@x153 bin]#
+[root@x153 bin]# ls -la demoCA/private/
+total 5
+drwxr-xr-x 2 root root 80 Jun 24 18:44 ./
+drwxr-xr-x 6 root root 232 Jun 24 18:50 ../
+-rw-r--r-- 1 root root 963 Jun 24 18:50 cakey.pem
+[root@x153 bin]#
+[root@x153 bin]# ./CA.sh -newreq
+Using configuration from /usr/lib/ssl/openssl.cnf
+Generating a 1024 bit RSA private key
+..................++++++
+........................++++++
+writing new private key to 'newreq.pem'
+Enter PEM pass phrase: <- new key password, not CA
+Verifying password - Enter PEM pass phrase:
+-----
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:EE
+State or Province Name (full name) [Some-State]:
+Locality Name (eg, city) []:Tallinn
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:Noname
+Organizational Unit Name (eg, section) []:
+Common Name (eg, YOUR name) []:Mr Noname
+Email Address []:a@b.c
+
+Please enter the following 'extra' attributes
+to be sent with your certificate request
+A challenge password []:
+An optional company name []:
+Request (and private key) is in newreq.pem
+[root@x153 bin]#
+[root@x153 bin]# ls -la newreq.pem
+-rw-r--r-- 1 root root 1623 Jun 24 18:54 newreq.pem
+[root@x153 bin]#
+[root@x153 bin]# ./CA.sh -sign
+Using configuration from /usr/lib/ssl/openssl.cnf
+Enter PEM pass phrase: <- CA's one!
+Check that the request matches the signature
+Signature ok
+The Subjects Distinguished Name is as follows
+countryName :PRINTABLE:'EE'
+stateOrProvinceName :PRINTABLE:'Some-State'
+localityName :PRINTABLE:'Tallinn'
+organizationName :PRINTABLE:'Noname'
+commonName :PRINTABLE:'Mr Noname'
+emailAddress :IA5STRING:'a@b.c'
+Certificate is to be certified until Jun 24 15:50:23 2002 GMT (365 days)
+Sign the certificate? [y/n]:y
+
+
+1 out of 1 certificate requests certified, commit? [y/n]y
+Write out database with 1 new entries
+Data Base Updated
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com
+ Validity
+ Not Before: Jun 24 15:50:23 2001 GMT
+ Not After : Jun 24 15:50:23 2002 GMT
+ Subject: C=EE, ST=Some-State, L=Tallinn, O=Noname, CN=Mr Noname/Email=a@b.c
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:ab:3b:7d:5b:6c:93:f6:46:1a:2c:46:73:6f:89:
+ 8a:99:bb:e9:6b:94:0d:74:aa:aa:c4:5c:a2:61:cf:
+ 56:bb:a1:a9:5a:37:c4:4e:b2:ec:5c:18:3a:a4:8d:
+ af:3d:23:66:7c:85:7f:d1:f2:e3:fc:16:a7:4c:a2:
+ d6:45:06:92:75:d8:a2:3b:f9:aa:77:da:26:b9:87:
+ e0:df:50:54:e4:36:9f:35:87:39:8e:a6:7c:3e:a8:
+ e4:49:1a:76:c2:6f:73:0b:22:93:2a:04:67:0d:7d:
+ ae:34:5c:fe:7c:29:b8:a2:fe:1e:ef:d1:0c:4d:dd:
+ 5b:7a:67:b0:0a:22:88:a0:af
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 83:D1:0D:52:0F:DE:61:2D:A6:10:20:B8:46:0C:77:D5:D2:D0:BE:20
+ X509v3 Authority Key Identifier:
+ keyid:A5:0A:D6:72:B5:DF:E4:C2:2B:7B:07:5E:D3:4D:52:07:E1:83:6B:7F
+ DirName:/C=FI/ST=Some-State/L=Helsinki/O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@mysql.com
+ serial:00
+
+ Signature Algorithm: md5WithRSAEncryption
+ 60:85:f7:d0:54:2a:67:88:0e:37:a6:a8:8e:fd:a0:c9:a1:d7:
+ c6:fc:4c:2e:59:8d:88:6d:69:0a:b8:b2:67:5f:81:94:39:0e:
+ ab:67:fc:8b:62:de:85:f6:b3:8c:2d:1a:e3:dc:28:fc:f5:99:
+ 39:f0:3d:50:ca:88:c0:8e:f8:c2:02:5d:34:19:63:9f:c4:a2:
+ f6:a8:81:c9:8d:6d:bd:c4:42:4a:0c:49:5a:cc:24:ea:65:80:
+ dd:79:20:89:9e:ea:6b:80:7a:86:f9:bb:6d:24:3c:80:13:5b:
+ e6:16:fc:3d:8d:f6:16:ea:33:25:c6:90:20:81:a4:b0:15:2e:
+ 9c:1c
+-----BEGIN CERTIFICATE-----
+MIIDfjCCAuegAwIBAgIBATANBgkqhkiG9w0BAQQFADCBhTELMAkGA1UEBhMCRkkx
+EzARBgNVBAgTClNvbWUtU3RhdGUxETAPBgNVBAcTCEhlbHNpbmtpMRkwFwYDVQQK
+ExBNeVNRTCBGaW5sYW5kIEFCMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqG
+SIb3DQEJARYOdG9udUBteXNxbC5jb20wHhcNMDEwNjI0MTU1MDIzWhcNMDIwNjI0
+MTU1MDIzWjBvMQswCQYDVQQGEwJFRTETMBEGA1UECBMKU29tZS1TdGF0ZTEQMA4G
+A1UEBxMHVGFsbGlubjEPMA0GA1UEChMGTm9uYW1lMRIwEAYDVQQDEwlNciBOb25h
+bWUxFDASBgkqhkiG9w0BCQEWBWFAYi5jMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQCrO31bbJP2RhosRnNviYqZu+lrlA10qqrEXKJhz1a7oalaN8ROsuxcGDqk
+ja89I2Z8hX/R8uP8FqdMotZFBpJ12KI7+ap32ia5h+DfUFTkNp81hzmOpnw+qORJ
+GnbCb3MLIpMqBGcNfa40XP58Kbii/h7v0QxN3Vt6Z7AKIoigrwIDAQABo4IBETCC
+AQ0wCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQg
+Q2VydGlmaWNhdGUwHQYDVR0OBBYEFIPRDVIP3mEtphAguEYMd9XS0L4gMIGyBgNV
+HSMEgaowgaeAFKUK1nK13+TCK3sHXtNNUgfhg2t/oYGLpIGIMIGFMQswCQYDVQQG
+EwJGSTETMBEGA1UECBMKU29tZS1TdGF0ZTERMA8GA1UEBxMISGVsc2lua2kxGTAX
+BgNVBAoTEE15U1FMIEZpbmxhbmQgQUIxFDASBgNVBAMTC1RvbnUgU2FtdWVsMR0w
+GwYJKoZIhvcNAQkBFg50b251QG15c3FsLmNvbYIBADANBgkqhkiG9w0BAQQFAAOB
+gQBghffQVCpniA43pqiO/aDJodfG/EwuWY2IbWkKuLJnX4GUOQ6rZ/yLYt6F9rOM
+LRrj3Cj89Zk58D1QyojAjvjCAl00GWOfxKL2qIHJjW29xEJKDElazCTqZYDdeSCJ
+nuprgHqG+bttJDyAE1vmFvw9jfYW6jMlxpAggaSwFS6cHA==
+-----END CERTIFICATE-----
+Signed certificate is in newcert.pem
+[root@x153 bin]# ls -la demoCA/newcerts/
+total 5
+drwxr-xr-x 2 root root 72 Jun 24 18:58 ./
+drwxr-xr-x 6 root root 296 Jun 24 18:58 ../
+-rw-r--r-- 1 root root 3533 Jun 24 18:58 01.pem
+[root@x153 bin]#
+[root@x153 mysql-4.0]# ./sql/mysqld --ssl-cert=SSL/server-cert.pem --ssl-ca=SSL/cacert.pem --ssl-ke
+y=SSL/server-req.pem -L /home/tonu/mysql-4.0/sql/share/english/ -u root
+Enter PEM pass phrase:
+./sql/mysqld: ready for connections
+[tonu@x153 mysql-4.0]$ client/mysql --ssl-key=SSL/client-req.pem --ssl-ca=SSL/cacert.pem --ssl-cert
+=SSL/client-cert.pem
+Enter PEM pass phrase:
+ERROR:
+
+[tonu@x153 mysql-4.0]$
+
+
+
+
+-8<------------------------
+SSL encrypts data between MySQL server and client.
+
+You need openssl (formerly SSLeay) for MySQL SSL support. Development
+and testing was done on openssl version 0.9.3a
+
+To compile MySQL one must do:
+./configure --with-openssl=/usr
+
+or
+
+./configure --with-openssl=yes
+
+There are sample keys and certificates included with MySQL tarball in
+directory ./SSL. They are meant to be for quick start and
+testing only. Using them in production environment means same as not
+using encryption. This is because private keys are publicly
+accessible for everyone. You must use openssl distribution for new key
+and certificate generation for both client and server.
+
+----------- for manual: ---------------------
+*New API calls:*
+
+mysql_ssl_set() - Set SSL properties (key, certificate,
+certificates authority certificate). Must be called before
+mysql_real_connect();
+mysql_ssl_clear() - Clear and free resources occupied by
+mysql_ssl_set() API call.
+char *mysql_ssl_cipher(MYSQL *) - returns cipher in use. For example
+"DES-CDC3-SHA" means that you have combined triple DES symmetric
+algorithm and SHA
+hashing algorithm.
+
+
+*New command line switches:*
+--ssl Use SSL for connection (automatically set with
+other flags. This means one can use encrypted connection without strong
+cryptological authentication. Normally one must use all switches
+together including ssl-key, ssl-cert and ssl-ca and never mind about
+--ssl because this is assumed by defult if any of them (--ssl-...)
+included.
+--ssl-key X509 key in PEM format (implies --ssl)
+--ssl-cert X509 cert in PEM format (implies --ssl)
+--ssl-ca CA file in PEM format (check OpenSSL docs,
+implies --ssl)
+--ssl-capath CA directory (check OpenSSL docs, implies --ssl
+ ----------------
+ This is about using SSL in MySQL privilege system. My idea is to make
+ possible use of x509 certificates and keys instead of MySQL native
+ passwords
+Some basic theory about crypt, SSL and x509:
+x509 is standard for certificates. SSL is standard for secure
+communication. Certificates are issued by someone anyone can trust. This
+trusted party is called "Certificate Authority" or "CA". This is
+someone, we MUST trust. Everyone must have some "fingerprint" of CA (so
+called "CA certificate" or "CA cert") using which one can verify
+authenticity of other
+certificates issued by this CA. CA uses his power to give certificates
+to persons (they can be physical (like "monty") or logical (like some
+process). Person is identified by "subject" like
+"/C=EE/ST=Harjumaa/L=Tallinn/O=MySQL client bogus certificate/CN=Tonu
+Samuel/Email=<EMAIL: PROTECTED>". and signed cryptologically. This sign can be
+verified using CA-cert. So, if we trust CA, then we can trust identity
+of user.
+There can be many CA-s (usually not but who knows). Also there can be
+some users we don`t trust or have different privileges. This means we
+must have one table to hold CA-certs and other table to hold so called
+"subjects" (users). I think it`s a good idea to use existing structure
+of host/user/db/field and add some x509 relationship. Then we can
+use usual simple user/host pair or x509 subject/CA pair.
+So I think user must grant rights using old method GRANT blabla ON
+blabla TO blabla IDENTIFIED BY blabla
+or new way:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla
+IDENTIFIED BY X509 SUBJECT "/C=EE/ST=Harjumaa/L=Tallinn/O=MySQL client
+bogus certificate/CN=Tonu Samuel/Email=<EMAIL: PROTECTED>" AND ISSUER
+"/C=EE/ST=Harjumaa/L=Tallinn/O=TCX AB/CN=Tonu
+Samuel/Email=<EMAIL: PROTECTED>";
+-----------8<---------------------------
+Please note the difference in Subject and Issuer. This command requests
+user to authenticate itself with exact subject and exact certificate
+issuer. Next possibility is just have any certificate of some good CA:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla IDENTIFIED BY X509 ISSUER
+"/C=EE/ST=Harjumaa/L=Tallinn/O=TCX
+AB/CN=Tonu Samuel/Email=<EMAIL: PROTECTED>";
+-----------8<---------------------------
+or if any registered CA is good enough (usual case when only one CA is
+registered)
+but we care about exact user, then something like:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla IDENTIFIED BY X509 SUBJECT
+"/C=EE/ST=Harjumaa/L=Tallinn/O=MySQL client
+bogus certificate/CN=Tonu Samuel/Email=<EMAIL: PROTECTED>";
+-----------8<---------------------------
+And case if user must authenticate itself but we don`t care about exact
+person until he have some certificate issued by CA registered in our
+system:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla IDENTIFIED BY X509;
+-----------8<---------------------------
+Then additionally we need one exception. Let`s assume we need SSL
+encryption
+for preventing eavesdropping but we don`t care who it is at all. We need
+privilege to exclude all non-SSL users but we accept anyone using SSL.
+How
+this must be done in GRANT syntax? Maybe:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla
+IDENTIFIED BY blabla AND USING SSL
+-----------8<---------------------------
+But maybe we want to add in future possibility to check different
+algorithms and key lengths? Something like:
+-----------8<---------------------------
+GRANT blabla ON blabla TO blabla IDENTIFIED BY blabla AND USING SSL WITH
+CIPHER "DES-CBC3-SHA" OR "DES-CBC3-MD5"
+-----------8<---------------------------
+Also we need some command to include/exclude CA certificates. This must
+be some commands like INSERT/DELETE/UPDATE/REPLACE to do it.
+All examples is given for clarify my problem. I asking for help because
+I don`t know
+any similar command in other SQL-s.
+------------8<------------------------
+
+So, at moment SSL communications is ready and working. I don`t have this
+command iterface at moment yet and this can be changed a lot if someone
+can suggest good idea or reason to change them. We are ready to listen
+every opinion.
+About Kerberos: I just don`t know much about it. I have to read this
+again before I can comment. I never used it itself and forgot most of
+theory. Sorry. Anyway now the problem/need is known and I will put
+thinking about this in personal TODO.
+
+
diff --git a/SSL/cacert.pem b/SSL/cacert.pem
new file mode 100644
index 00000000000..a63dae57767
--- /dev/null
+++ b/SSL/cacert.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDcTCCAtqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCU0Ux
+EDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMSEwHwYDVQQDExhB
+YnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAvBgkqhkiG9w0BCQEWImFic3RyYWN0
+Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wHhcNMDMwOTEyMTYxNDE2WhcNMTMw
+OTA5MTYxNDE2WjCBiDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAP
+BgNVBAoTCE15U1FMIEFCMSEwHwYDVQQDExhBYnN0cmFjdCBNeVNRTCBEZXZlbG9w
+ZXIxMTAvBgkqhkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNx
+bC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKrT7zp5tp5djXp+TEQs
+5ZEds1XUglp/EQUQ1FMMb1Xe6gqJsQ62O+jsUe0nrUjXBrUCUy49k6mcnmQtZREj
+l1pWKmzx1fgcYpxTwxaY7IKB2jik5IWprhVPmSQ+AWss43oolXMZWR+csKehqm3j
++YNZc9NsR4ydE71l0VEtJEQvAgMBAAGjgegwgeUwHQYDVR0OBBYEFIiYZdnz8osD
+HWZgYSP6rXNt02iSMIG1BgNVHSMEga0wgaqAFIiYZdnz8osDHWZgYSP6rXNt02iS
+oYGOpIGLMIGIMQswCQYDVQQGEwJTRTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UE
+ChMITXlTUUwgQUIxITAfBgNVBAMTGEFic3RyYWN0IE15U1FMIERldmVsb3BlcjEx
+MC8GCSqGSIb3DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2ZWxvcGVyQG15c3FsLmNv
+bYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAGIL22MCIU/0sKDp
+pZIhoabvNVDTfuhtene+WBCrzCzGXPZjB4+b/KAJJNvOR4zi43Kk7euu+PENs9M7
+nKpInMdhvT1RcCnUHJ3jBCvDDzXab2msqn3rxhwetWWbfE0OeEn/PoQcwiZCe7x5
+h+Zz+oUbvsEe4DjtDVgG4UH9nSSS
+-----END CERTIFICATE-----
diff --git a/SSL/client-cert.pem b/SSL/client-cert.pem
new file mode 100644
index 00000000000..4c81162c911
--- /dev/null
+++ b/SSL/client-cert.pem
@@ -0,0 +1,67 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SE, L=Uppsala, O=MySQL AB, CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
+ Validity
+ Not Before: Sep 12 16:21:19 2003 GMT
+ Not After : Sep 9 16:21:19 2013 GMT
+ Subject: C=SE, L=Uppsala, O=MySQL AB, CN=MySQL Client/Email=abstract.mysql.developer@mysql.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:c4:03:0a:ee:e3:b1:12:fc:ee:b4:19:f4:e1:60:
+ 1d:e0:28:c3:96:2d:df:82:69:cd:74:7c:54:58:d0:
+ ae:b3:59:3f:0c:19:1c:99:10:a6:12:c9:cf:3a:64:
+ 05:43:8e:bf:d2:65:36:80:91:0b:65:b0:27:26:38:
+ c9:23:d8:36:a2:4a:f0:f7:c0:2f:68:38:70:01:27:
+ 29:ff:b2:c5:52:e1:6b:f1:c8:d7:c3:5c:ee:f0:37:
+ 6c:2a:9b:96:1a:05:9e:eb:33:a2:39:5a:77:66:62:
+ 27:75:1f:2f:6f:38:da:e5:9f:78:af:ca:6b:22:3f:
+ 57:2b:bc:a6:8f:47:d1:99:6f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 80:81:A9:22:EB:AB:D6:CA:7E:3F:8D:BB:D1:AC:2A:F4:87:9D:13:29
+ X509v3 Authority Key Identifier:
+ keyid:88:98:65:D9:F3:F2:8B:03:1D:66:60:61:23:FA:AD:73:6D:D3:68:92
+ DirName:/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
+ serial:00
+
+ Signature Algorithm: md5WithRSAEncryption
+ 86:17:1c:f3:9f:10:1b:75:47:03:ca:54:ea:ef:f7:15:54:8d:
+ 8f:58:c9:64:7d:de:2e:bf:ea:a6:5d:72:56:c9:81:be:bb:1c:
+ 78:a5:91:d6:f8:77:df:9d:d2:cb:94:d9:06:61:4f:05:21:22:
+ 2a:ea:9e:c3:8b:4d:fe:94:c7:98:61:cd:7e:88:19:c9:92:01:
+ 1f:10:5b:c6:16:95:99:9b:32:01:3a:89:df:fa:0a:89:ac:fa:
+ b5:40:55:7a:ca:0a:bd:5d:8b:06:d8:7e:e1:44:8c:70:c8:63:
+ c7:77:6a:37:3d:a4:ac:57:dc:00:c1:c1:f3:72:17:5b:50:95:
+ ee:b7
+-----BEGIN CERTIFICATE-----
+MIIDkTCCAvqgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCU0Ux
+EDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMSEwHwYDVQQDExhB
+YnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAvBgkqhkiG9w0BCQEWImFic3RyYWN0
+Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wHhcNMDMwOTEyMTYyMTE5WhcNMTMw
+OTA5MTYyMTE5WjB8MQswCQYDVQQGEwJTRTEQMA4GA1UEBxMHVXBwc2FsYTERMA8G
+A1UEChMITXlTUUwgQUIxFTATBgNVBAMTDE15U1FMIENsaWVudDExMC8GCSqGSIb3
+DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2ZWxvcGVyQG15c3FsLmNvbTCBnzANBgkq
+hkiG9w0BAQEFAAOBjQAwgYkCgYEAxAMK7uOxEvzutBn04WAd4CjDli3fgmnNdHxU
+WNCus1k/DBkcmRCmEsnPOmQFQ46/0mU2gJELZbAnJjjJI9g2okrw98AvaDhwAScp
+/7LFUuFr8cjXw1zu8DdsKpuWGgWe6zOiOVp3ZmIndR8vbzja5Z94r8prIj9XK7ym
+j0fRmW8CAwEAAaOCARQwggEQMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9w
+ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSAgaki66vWyn4/
+jbvRrCr0h50TKTCBtQYDVR0jBIGtMIGqgBSImGXZ8/KLAx1mYGEj+q1zbdNokqGB
+jqSBizCBiDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoT
+CE15U1FMIEFCMSEwHwYDVQQDExhBYnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAv
+BgkqhkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb22C
+AQAwDQYJKoZIhvcNAQEEBQADgYEAhhcc858QG3VHA8pU6u/3FVSNj1jJZH3eLr/q
+pl1yVsmBvrsceKWR1vh3353Sy5TZBmFPBSEiKuqew4tN/pTHmGHNfogZyZIBHxBb
+xhaVmZsyATqJ3/oKiaz6tUBVesoKvV2LBth+4USMcMhjx3dqNz2krFfcAMHB83IX
+W1CV7rc=
+-----END CERTIFICATE-----
diff --git a/SSL/client-key.pem b/SSL/client-key.pem
new file mode 100644
index 00000000000..58fa805e620
--- /dev/null
+++ b/SSL/client-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDEAwru47ES/O60GfThYB3gKMOWLd+Cac10fFRY0K6zWT8MGRyZ
+EKYSyc86ZAVDjr/SZTaAkQtlsCcmOMkj2DaiSvD3wC9oOHABJyn/ssVS4WvxyNfD
+XO7wN2wqm5YaBZ7rM6I5WndmYid1Hy9vONrln3ivymsiP1crvKaPR9GZbwIDAQAB
+AoGAcR7IaoGhKbIrGGl6d67+zuT3q24h9aOV3Mn7653TlNHGnvbHGFcRYPpyy+H5
+X7m8XnHm+F+80hzNGzPecP9Q12oPOyoZgeQn6bTK73OFkNcX7FAkNdyH4xVhf2aK
+YOzTcQfq3gRCqXtVIg4qBShTMjJLE31R8H430Or62XmJgFECQQDjP+Kz+ecQwuTB
+HADLm+GQgceIB1kLgdQoZ3deUxGvqtVImuDRViSM0F2srfJ4GfkEDhc27UI5f6ir
+ZTOw4ww7AkEA3M9wCPgWNtbOXbYjaNA0IzHcjMDxQDVvJAmb3EiZlKQp4EfrESxR
+ly/u08TyfwrK6q5WS7xE0ad8+95G1af4XQJBAI9+3ME20SB1YItMCniHYwSj3oHX
+2fN5NKWax/Zoz+c0IV+qZMHq+kNso2oRoOUTyXk1CJWndcTnBnPMALr2c9cCQQCZ
+VL7Cq6uZVx6kemcqUHH0AprZbt3YLYLI7pc5p3xmeHzPzoEQQstBhjp8+aU+zPrN
+blRkcQ8E2x5yNA7SLLrNAkAhzkA+EK8hc0f9W3ncy+py0Rn0i5Ay0N3T715vkThf
+CfOHE3L91dLlmYpL5xVqOpugY/2sHyxwctv97DgS6tHZ
+-----END RSA PRIVATE KEY-----
diff --git a/SSL/client-req.pem b/SSL/client-req.pem
new file mode 100644
index 00000000000..b3667fb5ec6
--- /dev/null
+++ b/SSL/client-req.pem
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBvDCCASUCAQAwfDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAP
+BgNVBAoTCE15U1FMIEFCMRUwEwYDVQQDEwxNeVNRTCBDbGllbnQxMTAvBgkqhkiG
+9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wgZ8wDQYJ
+KoZIhvcNAQEBBQADgY0AMIGJAoGBAMQDCu7jsRL87rQZ9OFgHeAow5Yt34JpzXR8
+VFjQrrNZPwwZHJkQphLJzzpkBUOOv9JlNoCRC2WwJyY4ySPYNqJK8PfAL2g4cAEn
+Kf+yxVLha/HI18Nc7vA3bCqblhoFnuszojlad2ZiJ3UfL2842uWfeK/KayI/Vyu8
+po9H0ZlvAgMBAAGgADANBgkqhkiG9w0BAQQFAAOBgQAnKdk68dGJXvlj/GXwBUWN
+oXWF7hq4fDmwyhmcFUqk8qZKPKFUxkcER0GLzYeUgvD2URSfaS3/YW0d7K7kXGwP
+rB5edb+suaYf6mjm/w37xw/EJI9rdSKcB/3SSu8mALds7sUHDAO+MO0WkA/9d7t0
+LOsUqcDvMkKpZuYwNILwLw==
+-----END CERTIFICATE REQUEST-----
diff --git a/SSL/run-client b/SSL/run-client
new file mode 100755
index 00000000000..f3b29eb273b
--- /dev/null
+++ b/SSL/run-client
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+cmd () {
+ echo $*
+ $*
+}
+
+client/mysql --port=4407 --socket=/tmp/test.mysql.sock --ssl-ca=SSL/cacert.pem --ssl-cert=SSL/client-cert.pem --ssl-key=SSL/client-key.pem --debug='d:t:O,/tmp/client.trace' -h 127.0.0.1 -u root
+#--execute="select version();show status"
+
diff --git a/SSL/run-server b/SSL/run-server
new file mode 100755
index 00000000000..e90a7644b83
--- /dev/null
+++ b/SSL/run-server
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+cmd () {
+ echo $*
+ $*
+}
+
+cmd sql/mysqld --port=4407 --socket=/tmp/test.mysql.sock --ssl-ca=SSL/cacert.pem --ssl-cert=SSL/server-cert.pem --ssl-key=SSL/server-key.pem --debug='d:t:O,/tmp/mysqld.trace' -uroot >& /tmp/mysqld.output
+
diff --git a/SSL/server-cert.pem b/SSL/server-cert.pem
new file mode 100644
index 00000000000..debf7026e3c
--- /dev/null
+++ b/SSL/server-cert.pem
@@ -0,0 +1,67 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=SE, L=Uppsala, O=MySQL AB, CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
+ Validity
+ Not Before: Sep 12 16:22:06 2003 GMT
+ Not After : Sep 9 16:22:06 2013 GMT
+ Subject: C=SE, L=Uppsala, O=MySQL AB, CN=MySQL Server/Email=abstract.mysql.developer@mysql.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:e9:86:7a:55:84:88:4c:be:a4:f8:92:73:30:12:
+ 49:0b:7a:85:87:39:34:39:0d:7d:0b:8d:18:c2:17:
+ 95:13:52:d2:3f:55:10:57:c8:3f:5a:f5:b2:fa:8b:
+ d0:67:49:cc:aa:82:fc:9f:ce:00:b4:73:f3:36:d2:
+ 3a:d3:c2:b0:0e:14:c3:d4:b2:21:74:a1:f0:31:81:
+ 60:87:98:73:5c:10:c1:b1:1a:4d:f1:f3:b0:98:3f:
+ f0:d7:97:9b:2b:fd:d5:21:79:b2:2f:eb:64:15:c9:
+ 9b:9d:fc:9e:2d:d4:f8:04:5b:ea:a9:75:4b:42:c3:
+ 3d:0e:4d:2a:a8:b8:ca:99:8d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 6E:E4:9B:6A:C5:EA:E4:E6:C7:EF:D7:1E:C8:63:45:60:2B:1B:D4:D4
+ X509v3 Authority Key Identifier:
+ keyid:88:98:65:D9:F3:F2:8B:03:1D:66:60:61:23:FA:AD:73:6D:D3:68:92
+ DirName:/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
+ serial:00
+
+ Signature Algorithm: md5WithRSAEncryption
+ 31:77:69:b9:bd:ab:29:f3:fc:5a:09:16:6f:5d:42:ea:ba:01:
+ 55:69:e3:75:cf:b8:d1:b7:b9:bf:da:63:85:8c:48:92:06:60:
+ 76:97:e0:00:78:4b:ad:da:ab:6a:90:6d:8b:03:a8:b1:e9:09:
+ 78:e1:29:98:56:12:60:6b:42:fe:e8:a7:c4:f8:d6:15:07:e8:
+ 2b:c2:d8:8a:e5:1b:2e:51:08:9b:56:e3:b3:7a:4c:3e:e5:be:
+ 4a:4d:f8:65:7b:a8:21:e0:ca:fe:8b:ab:d7:ec:f2:2d:f7:d0:
+ bf:d7:c5:23:1c:08:d8:aa:57:c7:f3:5f:ba:33:3f:78:d1:f4:
+ 8e:5e
+-----BEGIN CERTIFICATE-----
+MIIDkTCCAvqgAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCU0Ux
+EDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMSEwHwYDVQQDExhB
+YnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAvBgkqhkiG9w0BCQEWImFic3RyYWN0
+Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wHhcNMDMwOTEyMTYyMjA2WhcNMTMw
+OTA5MTYyMjA2WjB8MQswCQYDVQQGEwJTRTEQMA4GA1UEBxMHVXBwc2FsYTERMA8G
+A1UEChMITXlTUUwgQUIxFTATBgNVBAMTDE15U1FMIFNlcnZlcjExMC8GCSqGSIb3
+DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2ZWxvcGVyQG15c3FsLmNvbTCBnzANBgkq
+hkiG9w0BAQEFAAOBjQAwgYkCgYEA6YZ6VYSITL6k+JJzMBJJC3qFhzk0OQ19C40Y
+wheVE1LSP1UQV8g/WvWy+ovQZ0nMqoL8n84AtHPzNtI608KwDhTD1LIhdKHwMYFg
+h5hzXBDBsRpN8fOwmD/w15ebK/3VIXmyL+tkFcmbnfyeLdT4BFvqqXVLQsM9Dk0q
+qLjKmY0CAwEAAaOCARQwggEQMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9w
+ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRu5Jtqxerk5sfv
+1x7IY0VgKxvU1DCBtQYDVR0jBIGtMIGqgBSImGXZ8/KLAx1mYGEj+q1zbdNokqGB
+jqSBizCBiDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoT
+CE15U1FMIEFCMSEwHwYDVQQDExhBYnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAv
+BgkqhkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb22C
+AQAwDQYJKoZIhvcNAQEEBQADgYEAMXdpub2rKfP8WgkWb11C6roBVWnjdc+40be5
+v9pjhYxIkgZgdpfgAHhLrdqrapBtiwOosekJeOEpmFYSYGtC/uinxPjWFQfoK8LY
+iuUbLlEIm1bjs3pMPuW+Sk34ZXuoIeDK/our1+zyLffQv9fFIxwI2KpXx/NfujM/
+eNH0jl4=
+-----END CERTIFICATE-----
diff --git a/SSL/server-key.pem b/SSL/server-key.pem
new file mode 100644
index 00000000000..4292dc79929
--- /dev/null
+++ b/SSL/server-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDphnpVhIhMvqT4knMwEkkLeoWHOTQ5DX0LjRjCF5UTUtI/VRBX
+yD9a9bL6i9BnScyqgvyfzgC0c/M20jrTwrAOFMPUsiF0ofAxgWCHmHNcEMGxGk3x
+87CYP/DXl5sr/dUhebIv62QVyZud/J4t1PgEW+qpdUtCwz0OTSqouMqZjQIDAQAB
+AoGBALTq11nrjIEQbdSZ+R1z/R0kddB2U+wjdA3/6P9tr7PBxVsFdtzbKaI5mcib
+iwCKX0J2qmrP+SHUdsexBZxLR4KV/Z55v9Pym99Dy+DxDA95zURyCMKRBIzlU5uN
+F7USEQoltLUCsmZwNWdit0gfxSWdddkHNuI0uxTzHwuDcUlNAkEA/76zVremngNL
+DlekM9NPn/8E/TXBHN1b1jdUKd7WymSJykdcm3viU98dFNZFWF8B0jiTcuBKXgpR
+vTShNab/swJBAOnCGp554BLhioTyyk8qjRLt3xEsjsDljJULHVLYWcUqIkMf97GL
+VLBhl6ZEI9i0WduqvgZ+Bacd0uHqIHz1Yb8CQQDm1CjqTDiGxlIoT9JVNJTZxEOs
+h6gVdXY+kxHT+N3FL5luiZp8fAR7zxVgiUVtzdLG+2madfapiobcT3RyCJkhAkBI
+64AaR7KasTjg2Ew7/e4cJZAcb2XozrLYG6t+GHeIhehCQEqoW+qDSy5fc4orI7eU
+SuMUa2OgCjGqv7p6wKFJAkEAznmum/MbVOBpC4FsdnIGkxyFKIbh2OLY2aUb2KkK
+Ouf4S8Y5Ldgszi0fnDPRaxWJzewwZKvcff2zj+mYZeAXbA==
+-----END RSA PRIVATE KEY-----
diff --git a/SSL/server-req.pem b/SSL/server-req.pem
new file mode 100644
index 00000000000..7c3db0660ad
--- /dev/null
+++ b/SSL/server-req.pem
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBvDCCASUCAQAwfDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAP
+BgNVBAoTCE15U1FMIEFCMRUwEwYDVQQDEwxNeVNRTCBTZXJ2ZXIxMTAvBgkqhkiG
+9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wgZ8wDQYJ
+KoZIhvcNAQEBBQADgY0AMIGJAoGBAOmGelWEiEy+pPiSczASSQt6hYc5NDkNfQuN
+GMIXlRNS0j9VEFfIP1r1svqL0GdJzKqC/J/OALRz8zbSOtPCsA4Uw9SyIXSh8DGB
+YIeYc1wQwbEaTfHzsJg/8NeXmyv91SF5si/rZBXJm538ni3U+ARb6ql1S0LDPQ5N
+Kqi4ypmNAgMBAAGgADANBgkqhkiG9w0BAQQFAAOBgQCagJxGHBC+G5aSh3OguFn6
+z+qAC7u3B181kPBgNv20zMgLeq7YiAh3iNx4XO2+QXRGzMznFKx1tFr/mavCpgLs
+p3+dCvQt5FHEFFK1D1pDeXy4146X07hOTtC9jc/jSWeVnH4ujuX5gMtZqisOyYWV
+/gpw6dBtkTYlhS+y86kM/Q==
+-----END CERTIFICATE REQUEST-----
diff --git a/VC++Files/InstallShield/3.23.XX-com/Component Definitions/.fgl b/VC++Files/InstallShield/3.23.XX-com/Component Definitions/.fgl
deleted file mode 100644
index 81e474f9be8..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/Component Definitions/.fgl
+++ /dev/null
@@ -1,37 +0,0 @@
-[General]
-Type=FILELIST
-Version=1.00.000
-
-[topdir]
-subdir0=<WINDIR>
-subdir1=<PROGRAMFILES>
-subdir2=<TARGETDIR>
-subdir3=USERDEFINED
-
-[<WINDIR>]
-DISPLAYTEXT=Windows Operating System
-TYPE=TEXTSUBFIXED
-subdir0=<WINDIR>\<WINSYSDIR>
-
-[<WINDIR>\<WINSYSDIR>]
-DISPLAYTEXT=Windows System Folder
-TYPE=TEXTSUBFIXED
-
-[<PROGRAMFILES>]
-DISPLAYTEXT=Program Files Folder
-TYPE=TEXTSUBFIXED
-subdir0=<PROGRAMFILES>\<COMMONFILES>
-
-[<PROGRAMFILES>\<COMMONFILES>]
-DISPLAYTEXT=Common Files Folder
-TYPE=TEXTSUBFIXED
-
-[<TARGETDIR>]
-DISPLAYTEXT=General Application Destination
-TYPE=TEXTSUBFIXED
-
-[USERDEFINED]
-DISPLAYTEXT=Script-defined Folders
-TYPE=USERSTART
-
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/Component Definitions/Default.cdf b/VC++Files/InstallShield/3.23.XX-com/Component Definitions/Default.cdf
deleted file mode 100644
index f44131f754e..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/Component Definitions/Default.cdf
+++ /dev/null
@@ -1,192 +0,0 @@
-[Development]
-required0=Servers
-SELECTED=Yes
-FILENEED=STANDARD
-required1=Grant Tables
-HTTPLOCATION=
-STATUS=Examples, Libraries, Includes and Script files
-UNINSTALLABLE=Yes
-TARGET=<TARGETDIR>
-FTPLOCATION=
-VISIBLE=Yes
-DESCRIPTION=Examples, Libraries, Includes and Script files
-DISPLAYTEXT=Examples, Libraries, Includes and Script files
-IMAGE=
-DEFSELECTION=Yes
-filegroup0=Development
-COMMENT=
-INCLUDEINBUILD=Yes
-INSTALLATION=ALWAYSOVERWRITE
-COMPRESSIFSEPARATE=No
-MISC=
-ENCRYPT=No
-DISK=ANYDISK
-TARGETDIRCDROM=
-PASSWORD=
-TARGETHIDDEN=General Application Destination
-
-[Grant Tables]
-required0=Servers
-SELECTED=Yes
-FILENEED=CRITICAL
-HTTPLOCATION=
-STATUS=The Grant Tables and Core Files
-UNINSTALLABLE=Yes
-TARGET=<TARGETDIR>
-FTPLOCATION=
-VISIBLE=Yes
-DESCRIPTION=The Grant Tables and Core Files
-DISPLAYTEXT=The Grant Tables and Core Files
-IMAGE=
-DEFSELECTION=Yes
-filegroup0=Grant Tables
-requiredby0=Development
-COMMENT=
-INCLUDEINBUILD=Yes
-requiredby1=Clients and Tools
-INSTALLATION=NEVEROVERWRITE
-requiredby2=Documentation
-COMPRESSIFSEPARATE=No
-MISC=
-ENCRYPT=No
-DISK=ANYDISK
-TARGETDIRCDROM=
-PASSWORD=
-TARGETHIDDEN=General Application Destination
-
-[Components]
-component0=Development
-component1=Grant Tables
-component2=Clients and Tools
-component3=Servers
-component4=Documentation
-
-[TopComponents]
-component0=Servers
-component1=Clients and Tools
-component2=Documentation
-component3=Development
-component4=Grant Tables
-
-[SetupType]
-setuptype0=Compact
-setuptype1=Typical
-setuptype2=Custom
-
-[Servers]
-SELECTED=Yes
-FILENEED=CRITICAL
-HTTPLOCATION=
-STATUS=The MySQL Servers
-UNINSTALLABLE=Yes
-TARGET=<TARGETDIR>
-FTPLOCATION=
-VISIBLE=Yes
-DESCRIPTION=The MySQL Servers
-DISPLAYTEXT=The MySQL Servers
-IMAGE=
-DEFSELECTION=Yes
-filegroup0=Servers
-requiredby0=Development
-COMMENT=
-INCLUDEINBUILD=Yes
-requiredby1=Grant Tables
-INSTALLATION=ALWAYSOVERWRITE
-requiredby2=Clients and Tools
-requiredby3=Documentation
-COMPRESSIFSEPARATE=No
-MISC=
-ENCRYPT=No
-DISK=ANYDISK
-TARGETDIRCDROM=
-PASSWORD=
-TARGETHIDDEN=General Application Destination
-
-[Clients and Tools]
-required0=Servers
-SELECTED=Yes
-FILENEED=HIGHLYRECOMMENDED
-required1=Grant Tables
-HTTPLOCATION=
-STATUS=The MySQL clients and Maintenance Tools
-UNINSTALLABLE=Yes
-TARGET=<TARGETDIR>
-FTPLOCATION=
-VISIBLE=Yes
-DESCRIPTION=The MySQL clients and Maintenance Tools
-DISPLAYTEXT=The MySQL clients and Maintenance Tools
-IMAGE=
-DEFSELECTION=Yes
-filegroup0=Clients and Tools
-COMMENT=
-INCLUDEINBUILD=Yes
-INSTALLATION=NEWERDATE
-COMPRESSIFSEPARATE=No
-MISC=
-ENCRYPT=No
-DISK=ANYDISK
-TARGETDIRCDROM=
-PASSWORD=
-TARGETHIDDEN=General Application Destination
-
-[SetupTypeItem-Compact]
-Comment=
-item0=Grant Tables
-item1=Clients and Tools
-item2=Servers
-item3=Documentation
-Descrip=
-DisplayText=
-
-[SetupTypeItem-Custom]
-Comment=
-item0=Development
-item1=Grant Tables
-item2=Clients and Tools
-item3=Servers
-Descrip=
-item4=Documentation
-DisplayText=
-
-[Info]
-Type=CompDef
-Version=1.00.000
-Name=
-
-[SetupTypeItem-Typical]
-Comment=
-item0=Development
-item1=Grant Tables
-item2=Clients and Tools
-item3=Servers
-Descrip=
-item4=Documentation
-DisplayText=
-
-[Documentation]
-required0=Servers
-SELECTED=Yes
-FILENEED=HIGHLYRECOMMENDED
-required1=Grant Tables
-HTTPLOCATION=
-STATUS=The MySQL Documentation with different formats
-UNINSTALLABLE=Yes
-TARGET=<TARGETDIR>
-FTPLOCATION=
-VISIBLE=Yes
-DESCRIPTION=The MySQL Documentation with different formats
-DISPLAYTEXT=The MySQL Documentation with different formats
-IMAGE=
-DEFSELECTION=Yes
-filegroup0=Documentation
-COMMENT=
-INCLUDEINBUILD=Yes
-INSTALLATION=ALWAYSOVERWRITE
-COMPRESSIFSEPARATE=No
-MISC=
-ENCRYPT=No
-DISK=ANYDISK
-TARGETDIRCDROM=
-PASSWORD=
-TARGETHIDDEN=General Application Destination
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/File Groups/Clients and Tools.fgl b/VC++Files/InstallShield/3.23.XX-com/File Groups/Clients and Tools.fgl
deleted file mode 100644
index 7f30ff9f64b..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/File Groups/Clients and Tools.fgl
+++ /dev/null
@@ -1,35 +0,0 @@
-[bin]
-file15=C:\mysql\bin\pack_isam.exe
-file16=C:\mysql\bin\perror.exe
-file0=C:\mysql\bin\isamchk.exe
-file17=C:\mysql\bin\replace.exe
-file1=C:\mysql\bin\myisamchk.exe
-file18=C:\mysql\bin\winmysqladmin.cnt
-file2=C:\mysql\bin\myisamlog.exe
-file19=C:\mysql\bin\winmysqladmin.exe
-file3=C:\mysql\bin\myisampack.exe
-file4=C:\mysql\bin\mysql.exe
-file5=C:\mysql\bin\mysqladmin.exe
-file6=C:\mysql\bin\mysqlbinlog.exe
-file7=C:\mysql\bin\mysqlc.exe
-file8=C:\mysql\bin\mysqlcheck.exe
-file9=C:\mysql\bin\mysqldump.exe
-file20=C:\mysql\bin\WINMYSQLADMIN.HLP
-file21=C:\mysql\bin\cygwinb19.dll
-file10=C:\mysql\bin\mysqlimport.exe
-fulldirectory=
-file22=C:\mysql\bin\libmySQL.dll
-file11=C:\mysql\bin\MySqlManager.exe
-file23=C:\mysql\bin\my_print_defaults.exe
-file12=C:\mysql\bin\mysqlshow.exe
-file24=C:\mysql\bin\comp-err.exe
-file13=C:\mysql\bin\mysqlshutdown.exe
-file14=C:\mysql\bin\mysqlwatch.exe
-
-[TopDir]
-SubDir0=bin
-
-[General]
-Type=FILELIST
-Version=1.00.000
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/File Groups/Default.fdf b/VC++Files/InstallShield/3.23.XX-com/File Groups/Default.fdf
deleted file mode 100644
index 282fae9d19b..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/File Groups/Default.fdf
+++ /dev/null
@@ -1,82 +0,0 @@
-[FileGroups]
-group0=Development
-group1=Grant Tables
-group2=Clients and Tools
-group3=Servers
-group4=Documentation
-
-[Development]
-SELFREGISTERING=No
-HTTPLOCATION=
-LANGUAGE=
-OPERATINGSYSTEM=
-FTPLOCATION=
-FILETYPE=No
-INFOTYPE=Standard
-COMMENT=
-COMPRESS=Yes
-COMPRESSDLL=
-POTENTIALLY=No
-MISC=
-
-[Grant Tables]
-SELFREGISTERING=No
-HTTPLOCATION=
-LANGUAGE=
-OPERATINGSYSTEM=
-FTPLOCATION=
-FILETYPE=No
-INFOTYPE=Standard
-COMMENT=
-COMPRESS=Yes
-COMPRESSDLL=
-POTENTIALLY=No
-MISC=
-
-[Servers]
-SELFREGISTERING=No
-HTTPLOCATION=
-LANGUAGE=
-OPERATINGSYSTEM=
-FTPLOCATION=
-FILETYPE=No
-INFOTYPE=Standard
-COMMENT=
-COMPRESS=Yes
-COMPRESSDLL=
-POTENTIALLY=No
-MISC=
-
-[Clients and Tools]
-SELFREGISTERING=No
-HTTPLOCATION=
-LANGUAGE=
-OPERATINGSYSTEM=0000000000000000
-FTPLOCATION=
-FILETYPE=No
-INFOTYPE=Standard
-COMMENT=
-COMPRESS=Yes
-COMPRESSDLL=
-POTENTIALLY=No
-MISC=
-
-[Info]
-Type=FileGrp
-Version=1.00.000
-Name=
-
-[Documentation]
-SELFREGISTERING=No
-HTTPLOCATION=
-LANGUAGE=
-OPERATINGSYSTEM=
-FTPLOCATION=
-FILETYPE=No
-INFOTYPE=Standard
-COMMENT=
-COMPRESS=Yes
-COMPRESSDLL=
-POTENTIALLY=No
-MISC=
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/File Groups/Default.fgl b/VC++Files/InstallShield/3.23.XX-com/File Groups/Default.fgl
deleted file mode 100644
index 94344a6ff69..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/File Groups/Default.fgl
+++ /dev/null
@@ -1,4 +0,0 @@
-[General]
-Type=FILELIST
-Version=1.00.000
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/File Groups/Development.fgl b/VC++Files/InstallShield/3.23.XX-com/File Groups/Development.fgl
deleted file mode 100644
index a1cf53f880a..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/File Groups/Development.fgl
+++ /dev/null
@@ -1,190 +0,0 @@
-[bench\Data\Wisconsin]
-file0=C:\mysql\bench\Data\Wisconsin\onek.data
-file1=C:\mysql\bench\Data\Wisconsin\tenk.data
-fulldirectory=
-
-[lib\debug]
-file0=C:\mysql\lib\debug\libmySQL.dll
-file1=C:\mysql\lib\debug\libmySQL.lib
-file2=C:\mysql\lib\debug\mysqlclient.lib
-file3=C:\mysql\lib\debug\zlib.lib
-fulldirectory=
-
-[bench\output]
-fulldirectory=
-
-[examples\libmysqltest]
-file0=C:\mysql\examples\libmysqltest\myTest.c
-file1=C:\mysql\examples\libmysqltest\myTest.dsp
-file2=C:\mysql\examples\libmysqltest\myTest.dsw
-file3=C:\mysql\examples\libmysqltest\myTest.exe
-file4=C:\mysql\examples\libmysqltest\myTest.mak
-file5=C:\mysql\examples\libmysqltest\myTest.ncb
-file6=C:\mysql\examples\libmysqltest\myTest.opt
-file7=C:\mysql\examples\libmysqltest\readme
-fulldirectory=
-
-[include]
-file0=C:\mysql\include\raid.h
-file1=C:\mysql\include\errmsg.h
-file2=C:\mysql\include\Libmysql.def
-file3=C:\mysql\include\m_ctype.h
-file4=C:\mysql\include\m_string.h
-file5=C:\mysql\include\my_list.h
-file6=C:\mysql\include\my_pthread.h
-file7=C:\mysql\include\my_sys.h
-file8=C:\mysql\include\mysql.h
-file9=C:\mysql\include\mysql_com.h
-file10=C:\mysql\include\mysql_version.h
-fulldirectory=
-file11=C:\mysql\include\mysqld_error.h
-file12=C:\mysql\include\dbug.h
-file13=C:\mysql\include\my_global.h
-file14=C:\mysql\include\config-win.h
-
-[examples]
-SubDir0=examples\libmysqltest
-SubDir1=examples\tests
-fulldirectory=
-
-[lib\opt]
-file0=C:\mysql\lib\opt\libmySQL.dll
-file1=C:\mysql\lib\opt\libmySQL.lib
-file2=C:\mysql\lib\opt\mysqlclient.lib
-file3=C:\mysql\lib\opt\zlib.lib
-fulldirectory=
-
-[bench\Data]
-SubDir0=bench\Data\ATIS
-SubDir1=bench\Data\Wisconsin
-fulldirectory=
-
-[bench\limits]
-file15=C:\mysql\bench\limits\pg.comment
-file16=C:\mysql\bench\limits\solid.cfg
-file0=C:\mysql\bench\limits\access.cfg
-file17=C:\mysql\bench\limits\solid-nt4.cfg
-file1=C:\mysql\bench\limits\access.comment
-file18=C:\mysql\bench\limits\sybase.cfg
-file2=C:\mysql\bench\limits\Adabas.cfg
-file3=C:\mysql\bench\limits\Adabas.comment
-file4=C:\mysql\bench\limits\Db2.cfg
-file5=C:\mysql\bench\limits\empress.cfg
-file6=C:\mysql\bench\limits\empress.comment
-file7=C:\mysql\bench\limits\Informix.cfg
-file8=C:\mysql\bench\limits\Informix.comment
-file9=C:\mysql\bench\limits\msql.cfg
-file10=C:\mysql\bench\limits\ms-sql.cfg
-fulldirectory=
-file11=C:\mysql\bench\limits\Ms-sql65.cfg
-file12=C:\mysql\bench\limits\mysql.cfg
-file13=C:\mysql\bench\limits\oracle.cfg
-file14=C:\mysql\bench\limits\pg.cfg
-
-[TopDir]
-SubDir0=bench
-SubDir1=examples
-SubDir2=include
-SubDir3=lib
-SubDir4=scripts
-
-[bench]
-file15=C:\mysql\bench\test-create
-file16=C:\mysql\bench\test-insert
-file0=C:\mysql\bench\uname.bat
-file17=C:\mysql\bench\test-select
-file1=C:\mysql\bench\compare-results
-file18=C:\mysql\bench\test-wisconsin
-file2=C:\mysql\bench\copy-db
-file19=C:\mysql\bench\bench-init.pl
-file3=C:\mysql\bench\crash-me
-file4=C:\mysql\bench\example.bat
-file5=C:\mysql\bench\print-limit-table
-file6=C:\mysql\bench\pwd.bat
-file7=C:\mysql\bench\Readme
-SubDir0=bench\Data
-file8=C:\mysql\bench\run.bat
-SubDir1=bench\limits
-file9=C:\mysql\bench\run-all-tests
-SubDir2=bench\output
-file10=C:\mysql\bench\server-cfg
-fulldirectory=
-file11=C:\mysql\bench\test-alter-table
-file12=C:\mysql\bench\test-ATIS
-file13=C:\mysql\bench\test-big-tables
-file14=C:\mysql\bench\test-connect
-
-[examples\tests]
-file15=C:\mysql\examples\tests\lock_test.res
-file16=C:\mysql\examples\tests\mail_to_db.pl
-file0=C:\mysql\examples\tests\unique_users.tst
-file17=C:\mysql\examples\tests\table_types.pl
-file1=C:\mysql\examples\tests\auto_increment.tst
-file18=C:\mysql\examples\tests\test_delayed_insert.pl
-file2=C:\mysql\examples\tests\big_record.pl
-file19=C:\mysql\examples\tests\udf_test
-file3=C:\mysql\examples\tests\big_record.res
-file4=C:\mysql\examples\tests\czech-sorting
-file5=C:\mysql\examples\tests\deadlock-script.pl
-file6=C:\mysql\examples\tests\export.pl
-file7=C:\mysql\examples\tests\fork_test.pl
-file8=C:\mysql\examples\tests\fork2_test.pl
-file9=C:\mysql\examples\tests\fork3_test.pl
-file20=C:\mysql\examples\tests\udf_test.res
-file21=C:\mysql\examples\tests\auto_increment.res
-file10=C:\mysql\examples\tests\function.res
-fulldirectory=
-file11=C:\mysql\examples\tests\function.tst
-file12=C:\mysql\examples\tests\grant.pl
-file13=C:\mysql\examples\tests\grant.res
-file14=C:\mysql\examples\tests\lock_test.pl
-
-[bench\Data\ATIS]
-file26=C:\mysql\bench\Data\ATIS\stop1.txt
-file15=C:\mysql\bench\Data\ATIS\flight_class.txt
-file27=C:\mysql\bench\Data\ATIS\time_interval.txt
-file16=C:\mysql\bench\Data\ATIS\flight_day.txt
-file0=C:\mysql\bench\Data\ATIS\transport.txt
-file28=C:\mysql\bench\Data\ATIS\time_zone.txt
-file17=C:\mysql\bench\Data\ATIS\flight_fare.txt
-file1=C:\mysql\bench\Data\ATIS\airline.txt
-file29=C:\mysql\bench\Data\ATIS\aircraft.txt
-file18=C:\mysql\bench\Data\ATIS\food_service.txt
-file2=C:\mysql\bench\Data\ATIS\airport.txt
-file19=C:\mysql\bench\Data\ATIS\ground_service.txt
-file3=C:\mysql\bench\Data\ATIS\airport_service.txt
-file4=C:\mysql\bench\Data\ATIS\city.txt
-file5=C:\mysql\bench\Data\ATIS\class_of_service.txt
-file6=C:\mysql\bench\Data\ATIS\code_description.txt
-file7=C:\mysql\bench\Data\ATIS\compound_class.txt
-file8=C:\mysql\bench\Data\ATIS\connect_leg.txt
-file9=C:\mysql\bench\Data\ATIS\date_day.txt
-file20=C:\mysql\bench\Data\ATIS\month_name.txt
-file21=C:\mysql\bench\Data\ATIS\restrict_carrier.txt
-file10=C:\mysql\bench\Data\ATIS\day_name.txt
-fulldirectory=
-file22=C:\mysql\bench\Data\ATIS\restrict_class.txt
-file11=C:\mysql\bench\Data\ATIS\dual_carrier.txt
-file23=C:\mysql\bench\Data\ATIS\restriction.txt
-file12=C:\mysql\bench\Data\ATIS\fare.txt
-file24=C:\mysql\bench\Data\ATIS\state.txt
-file13=C:\mysql\bench\Data\ATIS\fconnection.txt
-file25=C:\mysql\bench\Data\ATIS\stop.txt
-file14=C:\mysql\bench\Data\ATIS\flight.txt
-
-[General]
-Type=FILELIST
-Version=1.00.000
-
-[scripts]
-file0=C:\mysql\scripts\mysql_find_rows.pl
-file1=C:\mysql\scripts\mysql_setpermission.pl
-file2=C:\mysql\scripts\mysqlhotcopy.pl
-file3=C:\mysql\scripts\Readme
-fulldirectory=
-
-[lib]
-SubDir0=lib\debug
-SubDir1=lib\opt
-fulldirectory=
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/File Groups/Documentation.fgl b/VC++Files/InstallShield/3.23.XX-com/File Groups/Documentation.fgl
deleted file mode 100644
index d36acb64538..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/File Groups/Documentation.fgl
+++ /dev/null
@@ -1,98 +0,0 @@
-[Docs\Flags]
-file59=C:\mysql\Docs\Flags\romania.gif
-file48=C:\mysql\Docs\Flags\kroatia.eps
-file37=C:\mysql\Docs\Flags\iceland.gif
-file26=C:\mysql\Docs\Flags\france.eps
-file15=C:\mysql\Docs\Flags\china.gif
-file49=C:\mysql\Docs\Flags\kroatia.gif
-file38=C:\mysql\Docs\Flags\ireland.eps
-file27=C:\mysql\Docs\Flags\france.gif
-file16=C:\mysql\Docs\Flags\croatia.eps
-file0=C:\mysql\Docs\Flags\usa.gif
-file39=C:\mysql\Docs\Flags\ireland.gif
-file28=C:\mysql\Docs\Flags\germany.eps
-file17=C:\mysql\Docs\Flags\croatia.gif
-file1=C:\mysql\Docs\Flags\argentina.gif
-file29=C:\mysql\Docs\Flags\germany.gif
-file18=C:\mysql\Docs\Flags\czech-republic.eps
-file2=C:\mysql\Docs\Flags\australia.eps
-file19=C:\mysql\Docs\Flags\czech-republic.gif
-file3=C:\mysql\Docs\Flags\australia.gif
-file80=C:\mysql\Docs\Flags\usa.eps
-file4=C:\mysql\Docs\Flags\austria.eps
-file81=C:\mysql\Docs\Flags\argentina.eps
-file70=C:\mysql\Docs\Flags\spain.eps
-file5=C:\mysql\Docs\Flags\austria.gif
-file71=C:\mysql\Docs\Flags\spain.gif
-file60=C:\mysql\Docs\Flags\russia.eps
-file6=C:\mysql\Docs\Flags\brazil.eps
-file72=C:\mysql\Docs\Flags\sweden.eps
-file61=C:\mysql\Docs\Flags\russia.gif
-file50=C:\mysql\Docs\Flags\latvia.eps
-file7=C:\mysql\Docs\Flags\brazil.gif
-file73=C:\mysql\Docs\Flags\sweden.gif
-file62=C:\mysql\Docs\Flags\singapore.eps
-file51=C:\mysql\Docs\Flags\latvia.gif
-file40=C:\mysql\Docs\Flags\island.eps
-file8=C:\mysql\Docs\Flags\bulgaria.eps
-file74=C:\mysql\Docs\Flags\switzerland.eps
-file63=C:\mysql\Docs\Flags\singapore.gif
-file52=C:\mysql\Docs\Flags\netherlands.eps
-file41=C:\mysql\Docs\Flags\island.gif
-file30=C:\mysql\Docs\Flags\great-britain.eps
-file9=C:\mysql\Docs\Flags\bulgaria.gif
-file75=C:\mysql\Docs\Flags\switzerland.gif
-file64=C:\mysql\Docs\Flags\south-africa.eps
-file53=C:\mysql\Docs\Flags\netherlands.gif
-file42=C:\mysql\Docs\Flags\israel.eps
-file31=C:\mysql\Docs\Flags\great-britain.gif
-file20=C:\mysql\Docs\Flags\denmark.eps
-file76=C:\mysql\Docs\Flags\taiwan.eps
-file65=C:\mysql\Docs\Flags\south-africa.gif
-file54=C:\mysql\Docs\Flags\poland.eps
-file43=C:\mysql\Docs\Flags\israel.gif
-file32=C:\mysql\Docs\Flags\greece.eps
-file21=C:\mysql\Docs\Flags\denmark.gif
-file10=C:\mysql\Docs\Flags\canada.eps
-fulldirectory=
-file77=C:\mysql\Docs\Flags\taiwan.gif
-file66=C:\mysql\Docs\Flags\south-africa1.eps
-file55=C:\mysql\Docs\Flags\poland.gif
-file44=C:\mysql\Docs\Flags\italy.eps
-file33=C:\mysql\Docs\Flags\greece.gif
-file22=C:\mysql\Docs\Flags\estonia.eps
-file11=C:\mysql\Docs\Flags\canada.gif
-file78=C:\mysql\Docs\Flags\ukraine.eps
-file67=C:\mysql\Docs\Flags\south-africa1.gif
-file56=C:\mysql\Docs\Flags\portugal.eps
-file45=C:\mysql\Docs\Flags\italy.gif
-file34=C:\mysql\Docs\Flags\hungary.eps
-file23=C:\mysql\Docs\Flags\estonia.gif
-file12=C:\mysql\Docs\Flags\chile.eps
-file79=C:\mysql\Docs\Flags\ukraine.gif
-file68=C:\mysql\Docs\Flags\south-korea.eps
-file57=C:\mysql\Docs\Flags\portugal.gif
-file46=C:\mysql\Docs\Flags\japan.eps
-file35=C:\mysql\Docs\Flags\hungary.gif
-file24=C:\mysql\Docs\Flags\finland.eps
-file13=C:\mysql\Docs\Flags\chile.gif
-file69=C:\mysql\Docs\Flags\south-korea.gif
-file58=C:\mysql\Docs\Flags\romania.eps
-file47=C:\mysql\Docs\Flags\japan.gif
-file36=C:\mysql\Docs\Flags\iceland.eps
-file25=C:\mysql\Docs\Flags\finland.gif
-file14=C:\mysql\Docs\Flags\china.eps
-
-[Docs]
-file0=C:\mysql\Docs\manual_toc.html
-file1=C:\mysql\Docs\manual.html
-SubDir0=Docs\Flags
-fulldirectory=
-
-[TopDir]
-SubDir0=Docs
-
-[General]
-Type=FILELIST
-Version=1.00.000
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/File Groups/Servers.fgl b/VC++Files/InstallShield/3.23.XX-com/File Groups/Servers.fgl
deleted file mode 100644
index 6f91a474d80..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/File Groups/Servers.fgl
+++ /dev/null
@@ -1,183 +0,0 @@
-[share\polish]
-file0=C:\mysql\share\polish\errmsg.sys
-file1=C:\mysql\share\polish\errmsg.txt
-fulldirectory=
-
-[share\dutch]
-file0=C:\mysql\share\dutch\errmsg.sys
-file1=C:\mysql\share\dutch\errmsg.txt
-fulldirectory=
-
-[share\spanish]
-file0=C:\mysql\share\spanish\errmsg.sys
-file1=C:\mysql\share\spanish\errmsg.txt
-fulldirectory=
-
-[share\english]
-file0=C:\mysql\share\english\errmsg.sys
-file1=C:\mysql\share\english\errmsg.txt
-fulldirectory=
-
-[bin]
-file0=C:\mysql\bin\mysqld-opt.exe
-file1=C:\mysql\bin\mysqld-max.exe
-file2=C:\mysql\bin\mysqld-max-nt.exe
-file3=C:\mysql\bin\mysqld-nt.exe
-file4=C:\mysql\bin\mysqld.exe
-fulldirectory=
-
-[share\korean]
-file0=C:\mysql\share\korean\errmsg.sys
-file1=C:\mysql\share\korean\errmsg.txt
-fulldirectory=
-
-[share\charsets]
-file15=C:\mysql\share\charsets\latin1.conf
-file16=C:\mysql\share\charsets\latin2.conf
-file0=C:\mysql\share\charsets\win1251ukr.conf
-file17=C:\mysql\share\charsets\latin5.conf
-file1=C:\mysql\share\charsets\cp1257.conf
-file18=C:\mysql\share\charsets\Readme
-file2=C:\mysql\share\charsets\croat.conf
-file19=C:\mysql\share\charsets\swe7.conf
-file3=C:\mysql\share\charsets\danish.conf
-file4=C:\mysql\share\charsets\dec8.conf
-file5=C:\mysql\share\charsets\dos.conf
-file6=C:\mysql\share\charsets\estonia.conf
-file7=C:\mysql\share\charsets\german1.conf
-file8=C:\mysql\share\charsets\greek.conf
-file9=C:\mysql\share\charsets\hebrew.conf
-file20=C:\mysql\share\charsets\usa7.conf
-file21=C:\mysql\share\charsets\win1250.conf
-file10=C:\mysql\share\charsets\hp8.conf
-fulldirectory=
-file22=C:\mysql\share\charsets\win1251.conf
-file11=C:\mysql\share\charsets\hungarian.conf
-file23=C:\mysql\share\charsets\cp1251.conf
-file12=C:\mysql\share\charsets\Index
-file13=C:\mysql\share\charsets\koi8_ru.conf
-file14=C:\mysql\share\charsets\koi8_ukr.conf
-
-[share\ukrainian]
-file0=C:\mysql\share\ukrainian\errmsg.sys
-file1=C:\mysql\share\ukrainian\errmsg.txt
-fulldirectory=
-
-[share\hungarian]
-file0=C:\mysql\share\hungarian\errmsg.sys
-file1=C:\mysql\share\hungarian\errmsg.txt
-fulldirectory=
-
-[share\german]
-file0=C:\mysql\share\german\errmsg.sys
-file1=C:\mysql\share\german\errmsg.txt
-fulldirectory=
-
-[share\portuguese]
-file0=C:\mysql\share\portuguese\errmsg.sys
-file1=C:\mysql\share\portuguese\errmsg.txt
-fulldirectory=
-
-[share\estonian]
-file0=C:\mysql\share\estonian\errmsg.sys
-file1=C:\mysql\share\estonian\errmsg.txt
-fulldirectory=
-
-[share\romanian]
-file0=C:\mysql\share\romanian\errmsg.sys
-file1=C:\mysql\share\romanian\errmsg.txt
-fulldirectory=
-
-[share\french]
-file0=C:\mysql\share\french\errmsg.sys
-file1=C:\mysql\share\french\errmsg.txt
-fulldirectory=
-
-[share\swedish]
-file0=C:\mysql\share\swedish\errmsg.sys
-file1=C:\mysql\share\swedish\errmsg.txt
-fulldirectory=
-
-[share\slovak]
-file0=C:\mysql\share\slovak\errmsg.sys
-file1=C:\mysql\share\slovak\errmsg.txt
-fulldirectory=
-
-[share\greek]
-file0=C:\mysql\share\greek\errmsg.sys
-file1=C:\mysql\share\greek\errmsg.txt
-fulldirectory=
-
-[TopDir]
-file0=C:\mysql\my-small.cnf
-file1=C:\mysql\my-large.cnf
-file2=C:\mysql\my-medium.cnf
-file3=C:\mysql\my-huge.cnf
-SubDir0=bin
-SubDir1=share
-
-[share]
-SubDir8=share\hungarian
-SubDir9=share\charsets
-SubDir20=share\spanish
-SubDir21=share\swedish
-SubDir10=share\italian
-SubDir22=share\ukrainian
-SubDir11=share\japanese
-SubDir12=share\korean
-SubDir13=share\norwegian
-SubDir14=share\norwegian-ny
-SubDir15=share\polish
-SubDir16=share\portuguese
-SubDir0=share\czech
-SubDir17=share\romanian
-SubDir1=share\danish
-SubDir18=share\russian
-SubDir2=share\dutch
-SubDir19=share\slovak
-SubDir3=share\english
-fulldirectory=
-SubDir4=share\estonian
-SubDir5=share\french
-SubDir6=share\german
-SubDir7=share\greek
-
-[share\norwegian-ny]
-file0=C:\mysql\share\norwegian-ny\errmsg.sys
-file1=C:\mysql\share\norwegian-ny\errmsg.txt
-fulldirectory=
-
-[share\danish]
-file0=C:\mysql\share\danish\errmsg.sys
-file1=C:\mysql\share\danish\errmsg.txt
-fulldirectory=
-
-[share\czech]
-file0=C:\mysql\share\czech\errmsg.sys
-file1=C:\mysql\share\czech\errmsg.txt
-fulldirectory=
-
-[General]
-Type=FILELIST
-Version=1.00.000
-
-[share\russian]
-file0=C:\mysql\share\russian\errmsg.sys
-file1=C:\mysql\share\russian\errmsg.txt
-fulldirectory=
-
-[share\norwegian]
-file0=C:\mysql\share\norwegian\errmsg.sys
-file1=C:\mysql\share\norwegian\errmsg.txt
-fulldirectory=
-
-[share\japanese]
-file0=C:\mysql\share\japanese\errmsg.sys
-file1=C:\mysql\share\japanese\errmsg.txt
-fulldirectory=
-
-[share\italian]
-file0=C:\mysql\share\italian\errmsg.sys
-file1=C:\mysql\share\italian\errmsg.txt
-fulldirectory=
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/MySQL 3.23.com.ipr b/VC++Files/InstallShield/3.23.XX-com/MySQL 3.23.com.ipr
deleted file mode 100644
index 811d69717d8..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/MySQL 3.23.com.ipr
+++ /dev/null
@@ -1,51 +0,0 @@
-[Language]
-LanguageSupport0=0009
-
-[OperatingSystem]
-OSSupport=0000000000010010
-
-[Data]
-CurrentMedia=
-set_mifserial=
-ProductName=MySQL Servers and Clients
-CurrentComponentDef=Default.cdf
-set_dlldebug=No
-AppExe=
-DevEnvironment=Microsoft Visual C++ 6
-set_mif=No
-set_testmode=No
-Instructions=Instructions.txt
-EmailAddresss=
-SummaryText=
-Department=
-Type=Database Application
-Author=
-HomeURL=
-InstallRoot=C:\MySQL-Install\3.23.XXcom
-set_level=Level 3
-InstallationGUID=40744a4d-efed-4cff-84a9-9e6389550f5c
-Version=1.00.000
-set_miffile=Status.mif
-set_args=
-set_maxerr=50
-Notes=Notes.txt
-CurrentFileGroupDef=Default.fdf
-set_dllcmdline=
-set_warnaserr=No
-Copyright=
-set_preproc=
-Category=
-CurrentPlatform=
-set_compileb4build=No
-set_crc=Yes
-set_maxwarn=50
-Description=Description.txt
-CompanyName=MySQL
-CurrentLanguage=English
-
-[MediaInfo]
-
-[General]
-Type=INSTALLMAIN
-Version=1.10.000
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.rul b/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.rul
deleted file mode 100644
index 0db8417a62c..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.rul
+++ /dev/null
@@ -1,641 +0,0 @@
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// IIIIIII SSSSSS
-// II SS InstallShield (R)
-// II SSSSSS (c) 1996-1997, InstallShield Software Corporation
-// II SS (c) 1990-1996, InstallShield Corporation
-// IIIIIII SSSSSS All Rights Reserved.
-//
-//
-// This code is generated as a starting setup template. You should
-// modify it to provide all necessary steps for your setup.
-//
-//
-// File Name: Setup.rul
-//
-// Description: InstallShield script
-//
-// Comments: This template script performs a basic setup on a
-// Windows 95 or Windows NT 4.0 platform. With minor
-// modifications, this template can be adapted to create
-// new, customized setups.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-
- // Include header file
-#include "sdlang.h"
-#include "sddialog.h"
-
-////////////////////// string defines ////////////////////////////
-
-#define UNINST_LOGFILE_NAME "Uninst.isu"
-
-//////////////////// installation declarations ///////////////////
-
- // ----- DLL prototypes -----
-
-
- // your DLL prototypes
-
-
- // ---- script prototypes -----
-
- // generated
- prototype ShowDialogs();
- prototype MoveFileData();
- prototype HandleMoveDataError( NUMBER );
- prototype ProcessBeforeDataMove();
- prototype ProcessAfterDataMove();
- prototype SetupRegistry();
- prototype SetupFolders();
- prototype CleanUpInstall();
- prototype SetupInstall();
- prototype SetupScreen();
- prototype CheckRequirements();
- prototype DialogShowSdWelcome();
- prototype DialogShowSdShowInfoList();
- prototype DialogShowSdAskDestPath();
- prototype DialogShowSdSetupType();
- prototype DialogShowSdComponentDialog2();
- prototype DialogShowSdFinishReboot();
-
- // your prototypes
-
-
- // ----- global variables ------
-
- // generated
- BOOL bWinNT, bIsShellExplorer, bInstallAborted, bIs32BitSetup;
- STRING svDir;
- STRING svName, svCompany, svSerial;
- STRING szAppPath;
- STRING svSetupType;
-
-
- // your global variables
-
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// MAIN PROGRAM
-//
-// The setup begins here by hiding the visible setup
-// window. This is done to allow all the titles, images, etc. to
-// be established before showing the main window. The following
-// logic then performs the setup in a series of steps.
-//
-///////////////////////////////////////////////////////////////////////////////
-program
- Disable( BACKGROUND );
-
- CheckRequirements();
-
- SetupInstall();
-
- SetupScreen();
-
- if (ShowDialogs()<0) goto end_install;
-
- if (ProcessBeforeDataMove()<0) goto end_install;
-
- if (MoveFileData()<0) goto end_install;
-
- if (ProcessAfterDataMove()<0) goto end_install;
-
- if (SetupRegistry()<0) goto end_install;
-
- if (SetupFolders()<0) goto end_install;
-
-
- end_install:
-
- CleanUpInstall();
-
- // If an unrecoverable error occurred, clean up the partial installation.
- // Otherwise, exit normally.
-
- if (bInstallAborted) then
- abort;
- endif;
-
-endprogram
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: ShowDialogs //
-// //
-// Purpose: This function manages the display and navigation //
-// the standard dialogs that exist in a setup. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function ShowDialogs()
- NUMBER nResult;
- begin
-
- Dlg_Start:
- // beginning of dialogs label
-
- Dlg_SdWelcome:
- nResult = DialogShowSdWelcome();
- if (nResult = BACK) goto Dlg_Start;
-
- Dlg_SdShowInfoList:
- nResult = DialogShowSdShowInfoList();
- if (nResult = BACK) goto Dlg_SdWelcome;
-
- Dlg_SdAskDestPath:
- nResult = DialogShowSdAskDestPath();
- if (nResult = BACK) goto Dlg_SdShowInfoList;
-
- Dlg_SdSetupType:
- nResult = DialogShowSdSetupType();
- if (nResult = BACK) goto Dlg_SdAskDestPath;
-
- Dlg_SdComponentDialog2:
- if ((nResult = BACK) && (svSetupType != "Custom") && (svSetupType != "")) then
- goto Dlg_SdSetupType;
- endif;
- nResult = DialogShowSdComponentDialog2();
- if (nResult = BACK) goto Dlg_SdSetupType;
-
- return 0;
-
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: ProcessBeforeDataMove //
-// //
-// Purpose: This function performs any necessary operations prior to the //
-// actual data move operation. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function ProcessBeforeDataMove()
- STRING svLogFile;
- NUMBER nResult;
- begin
-
- InstallationInfo( @COMPANY_NAME, @PRODUCT_NAME, @PRODUCT_VERSION, @PRODUCT_KEY );
-
- svLogFile = UNINST_LOGFILE_NAME;
-
- nResult = DeinstallStart( svDir, svLogFile, @UNINST_KEY, 0 );
- if (nResult < 0) then
- MessageBox( @ERROR_UNINSTSETUP, WARNING );
- endif;
-
- szAppPath = TARGETDIR; // TODO : if your application .exe is in a subdir of TARGETDIR then add subdir
-
- if ((bIs32BitSetup) && (bIsShellExplorer)) then
- RegDBSetItem( REGDB_APPPATH, szAppPath );
- RegDBSetItem( REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY );
- RegDBSetItem( REGDB_UNINSTALL_NAME, @UNINST_DISPLAY_NAME );
- endif;
-
- // TODO : update any items you want to process before moving the data
- //
-
- return 0;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: MoveFileData //
-// //
-// Purpose: This function handles the data movement for //
-// the setup. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function MoveFileData()
- NUMBER nResult, nDisk;
- begin
-
- nDisk = 1;
- SetStatusWindow( 0, "" );
- Disable( DIALOGCACHE );
- Enable( STATUS );
- StatusUpdate( ON, 100 );
- nResult = ComponentMoveData( MEDIA, nDisk, 0 );
-
- HandleMoveDataError( nResult );
-
- Disable( STATUS );
-
- return nResult;
-
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: HandleMoveDataError //
-// //
-// Purpose: This function handles the error (if any) during the move data //
-// operation. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function HandleMoveDataError( nResult )
- STRING szErrMsg, svComponent , svFileGroup , svFile;
- begin
-
- svComponent = "";
- svFileGroup = "";
- svFile = "";
-
- switch (nResult)
- case 0:
- return 0;
- default:
- ComponentError ( MEDIA , svComponent , svFileGroup , svFile , nResult );
- szErrMsg = @ERROR_MOVEDATA + "\n\n" +
- @ERROR_COMPONENT + " " + svComponent + "\n" +
- @ERROR_FILEGROUP + " " + svFileGroup + "\n" +
- @ERROR_FILE + " " + svFile;
- SprintfBox( SEVERE, @TITLE_CAPTIONBAR, szErrMsg, nResult );
- bInstallAborted = TRUE;
- return nResult;
- endswitch;
-
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: ProcessAfterDataMove //
-// //
-// Purpose: This function performs any necessary operations needed after //
-// all data has been moved. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function ProcessAfterDataMove()
- begin
-
- // TODO : update self-registered files and other processes that
- // should be performed after the data has been moved.
-
-
- return 0;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: SetupRegistry //
-// //
-// Purpose: This function makes the registry entries for this setup. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function SetupRegistry()
- NUMBER nResult;
-
- begin
-
- // TODO : Add all your registry entry keys here
- //
- //
- // RegDBCreateKeyEx, RegDBSetKeyValueEx....
- //
-
- nResult = CreateRegistrySet( "" );
-
- return nResult;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// Function: SetupFolders
-//
-// Purpose: This function creates all the folders and shortcuts for the
-// setup. This includes program groups and items for Windows 3.1.
-//
-///////////////////////////////////////////////////////////////////////////////
-function SetupFolders()
- NUMBER nResult;
-
- begin
-
-
- // TODO : Add all your folder (program group) along with shortcuts (program items)
- //
- //
- // CreateProgramFolder, AddFolderIcon....
- //
-
- nResult = CreateShellObjects( "" );
-
- return nResult;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: CleanUpInstall //
-// //
-// Purpose: This cleans up the setup. Anything that should //
-// be released or deleted at the end of the setup should //
-// be done here. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function CleanUpInstall()
- begin
-
-
- if (bInstallAborted) then
- return 0;
- endif;
-
- DialogShowSdFinishReboot();
-
- if (BATCH_INSTALL) then // ensure locked files are properly written
- CommitSharedFiles(0);
- endif;
-
- return 0;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: SetupInstall //
-// //
-// Purpose: This will setup the installation. Any general initialization //
-// needed for the installation should be performed here. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function SetupInstall()
- begin
-
- Enable( CORECOMPONENTHANDLING );
-
- bInstallAborted = FALSE;
-
- if (bIs32BitSetup) then
- svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME ^ @PRODUCT_NAME;
- else
- svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME16 ^ @PRODUCT_NAME16; // use shorten names
- endif;
-
- TARGETDIR = svDir;
-
- SdProductName( @PRODUCT_NAME );
-
- Enable( DIALOGCACHE );
-
- return 0;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: SetupScreen //
-// //
-// Purpose: This function establishes the screen look. This includes //
-// colors, fonts, and text to be displayed. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function SetupScreen()
- begin
-
- Enable( FULLWINDOWMODE );
- Enable( INDVFILESTATUS );
- SetTitle( @TITLE_MAIN, 24, WHITE );
-
- SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text.
-
- Enable( BACKGROUND );
-
- Delay( 1 );
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: CheckRequirements //
-// //
-// Purpose: This function checks all minimum requirements for the //
-// application being installed. If any fail, then the user //
-// is informed and the setup is terminated. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function CheckRequirements()
- NUMBER nvDx, nvDy, nvResult;
- STRING svResult;
-
- begin
-
- bWinNT = FALSE;
- bIsShellExplorer = FALSE;
-
- // Check screen resolution.
- GetExtents( nvDx, nvDy );
-
- if (nvDy < 480) then
- MessageBox( @ERROR_VGARESOLUTION, WARNING );
- abort;
- endif;
-
- // set 'setup' operation mode
- bIs32BitSetup = TRUE;
- GetSystemInfo( ISTYPE, nvResult, svResult );
- if (nvResult = 16) then
- bIs32BitSetup = FALSE; // running 16-bit setup
- return 0; // no additional information required
- endif;
-
- // --- 32-bit testing after this point ---
-
- // Determine the target system's operating system.
- GetSystemInfo( OS, nvResult, svResult );
-
- if (nvResult = IS_WINDOWSNT) then
- // Running Windows NT.
- bWinNT = TRUE;
-
- // Check to see if the shell being used is EXPLORER shell.
- if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then
- if (nvResult >= 4) then
- bIsShellExplorer = TRUE;
- endif;
- endif;
-
- elseif (nvResult = IS_WINDOWS95 ) then
- bIsShellExplorer = TRUE;
-
- endif;
-
-end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdWelcome //
-// //
-// Purpose: This function handles the standard welcome dialog. //
-// //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdWelcome()
- NUMBER nResult;
- STRING szTitle, szMsg;
- begin
-
- szTitle = "";
- szMsg = "";
- nResult = SdWelcome( szTitle, szMsg );
-
- return nResult;
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdShowInfoList //
-// //
-// Purpose: This function displays the general information list dialog. //
-// //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdShowInfoList()
- NUMBER nResult;
- LIST list;
- STRING szTitle, szMsg, szFile;
- begin
-
- szFile = SUPPORTDIR ^ "infolist.txt";
-
- list = ListCreate( STRINGLIST );
- ListReadFromFile( list, szFile );
- szTitle = "";
- szMsg = " ";
- nResult = SdShowInfoList( szTitle, szMsg, list );
-
- ListDestroy( list );
-
- return nResult;
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdAskDestPath //
-// //
-// Purpose: This function asks the user for the destination directory. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdAskDestPath()
- NUMBER nResult;
- STRING szTitle, szMsg;
- begin
-
- szTitle = "";
- szMsg = "";
- nResult = SdAskDestPath( szTitle, szMsg, svDir, 0 );
-
- TARGETDIR = svDir;
-
- return nResult;
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdSetupType //
-// //
-// Purpose: This function displays the standard setup type dialog. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdSetupType()
- NUMBER nResult, nType;
- STRING szTitle, szMsg;
- begin
-
- switch (svSetupType)
- case "Typical":
- nType = TYPICAL;
- case "Custom":
- nType = CUSTOM;
- case "Compact":
- nType = COMPACT;
- case "":
- svSetupType = "Typical";
- nType = TYPICAL;
- endswitch;
-
- szTitle = "";
- szMsg = "";
- nResult = SetupType( szTitle, szMsg, "", nType, 0 );
-
- switch (nResult)
- case COMPACT:
- svSetupType = "Compact";
- case TYPICAL:
- svSetupType = "Typical";
- case CUSTOM:
- svSetupType = "Custom";
- endswitch;
-
- return nResult;
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdComponentDialog2 //
-// //
-// Purpose: This function displays the custom component dialog. //
-// //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdComponentDialog2()
- NUMBER nResult;
- STRING szTitle, szMsg;
- begin
-
- if ((svSetupType != "Custom") && (svSetupType != "")) then
- return 0;
- endif;
-
- szTitle = "";
- szMsg = "";
- nResult = SdComponentDialog2( szTitle, szMsg, svDir, "" );
-
- return nResult;
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdFinishReboot //
-// //
-// Purpose: This function will show the last dialog of the product. //
-// It will allow the user to reboot and/or show some readme text. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdFinishReboot()
- NUMBER nResult, nDefOptions;
- STRING szTitle, szMsg1, szMsg2, szOption1, szOption2;
- NUMBER bOpt1, bOpt2;
- begin
-/*
- if (!BATCH_INSTALL) then
- bOpt1 = FALSE;
- bOpt2 = FALSE;
- szMsg1 = "";
- szMsg2 = "";
- szOption1 = "";
- szOption2 = "";
- nResult = SdFinish( szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2 );
- return 0;
- endif;
-
- nDefOptions = SYS_BOOTMACHINE;
- szTitle = "";
- szMsg1 = "";
- szMsg2 = "";
- nResult = SdFinishReboot( szTitle, szMsg1, nDefOptions, szMsg2, 0 );
-*/
- return nResult;
- end;
-
- // --- include script file section ---
-
-#include "sddialog.rul"
-
-
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt b/VC++Files/InstallShield/3.23.XX-com/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt
deleted file mode 100644
index b0a0a1eeb92..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-This is a release of MySQL @VERSION@ for Win32.
-
-NOTE: If you install MySQL in a folder other than
-C:\MYSQL or you intend to start MySQL on NT/Win2000
-as a service, you must create a file named C:\MY.CNF
-or \Windows\my.ini or \winnt\my.ini with the following
-information::
-
-[mysqld]
-basedir=E:/installation-path/
-datadir=E:/data-path/
-
-After your have installed MySQL, the installation
-directory which contains the files named 'my-size.cnf'.
-You can use this as a starting point for your own
-C:\my.cnf file.
-
-If you have any problems, you can mail them to
-win32@lists.mysql.com after you have consulted the
-MySQL manual and the MySQL mailing list archive
-(http://www.mysql.com/documentation/index.html)
-
-On behalf of the MySQL AB gang,
-Michael Widenius
diff --git a/VC++Files/InstallShield/3.23.XX-com/String Tables/0009-English/value.shl b/VC++Files/InstallShield/3.23.XX-com/String Tables/0009-English/value.shl
deleted file mode 100644
index f0a78602cc0..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/String Tables/0009-English/value.shl
+++ /dev/null
@@ -1,23 +0,0 @@
-[Data]
-TITLE_MAIN=MySQL Commercial Servers and Clients @VERSION@
-ERROR_COMPONENT=Component:
-COMPANY_NAME=MySQL AB
-COMPANY_NAME16=Company
-ERROR_FILEGROUP=File Group:
-ERROR_MOVEDATA=An error occurred during the move data process: %d
-PRODUCT_VERSION=@VERSION@
-UNINST_KEY=MySQL Commercial Servers and Clients @VERSION@
-TITLE_CAPTIONBAR=MySQL Commercial Servers and Clients @VERSION@ Setup
-PRODUCT_NAME16=Product
-ERROR_FILE=File:
-ERROR_VGARESOLUTION=This program requires VGA or better resolution.
-PRODUCT_KEY=yourapp.Exe
-UNINST_DISPLAY_NAME=MySQL Commercial Servers and Clients @VERSION@
-ERROR_UNINSTSETUP=unInstaller setup failed to initialize. You may not be able to uninstall this product.
-PRODUCT_NAME=MySQL Commercial Servers and Clients @VERSION@
-
-[General]
-Language=0009
-Type=STRINGTABLESPECIFIC
-Version=1.00.000
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/String Tables/Default.shl b/VC++Files/InstallShield/3.23.XX-com/String Tables/Default.shl
deleted file mode 100644
index f197667992e..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/String Tables/Default.shl
+++ /dev/null
@@ -1,74 +0,0 @@
-[TITLE_MAIN]
-Comment=
-
-[ERROR_COMPONENT]
-Comment=
-
-[COMPANY_NAME]
-Comment=
-
-[COMPANY_NAME16]
-Comment=
-
-[ERROR_FILEGROUP]
-Comment=
-
-[ERROR_MOVEDATA]
-Comment=
-
-[PRODUCT_VERSION]
-Comment=
-
-[UNINST_KEY]
-Comment=
-
-[Language]
-Lang0=0009
-CurrentLang=0
-
-[TITLE_CAPTIONBAR]
-Comment=
-
-[PRODUCT_NAME16]
-Comment=
-
-[Data]
-Entry0=ERROR_VGARESOLUTION
-Entry1=TITLE_MAIN
-Entry2=TITLE_CAPTIONBAR
-Entry3=UNINST_KEY
-Entry4=UNINST_DISPLAY_NAME
-Entry5=COMPANY_NAME
-Entry6=PRODUCT_NAME
-Entry7=PRODUCT_VERSION
-Entry8=PRODUCT_KEY
-Entry10=ERROR_UNINSTSETUP
-Entry9=ERROR_MOVEDATA
-Entry11=COMPANY_NAME16
-Entry12=PRODUCT_NAME16
-Entry13=ERROR_COMPONENT
-Entry14=ERROR_FILEGROUP
-Entry15=ERROR_FILE
-
-[ERROR_FILE]
-Comment=
-
-[ERROR_VGARESOLUTION]
-Comment=
-
-[PRODUCT_KEY]
-Comment=
-
-[UNINST_DISPLAY_NAME]
-Comment=
-
-[General]
-Type=STRINGTABLE
-Version=1.00.000
-
-[ERROR_UNINSTSETUP]
-Comment=
-
-[PRODUCT_NAME]
-Comment=
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/Text Substitutions/Build.tsb b/VC++Files/InstallShield/3.23.XX-com/Text Substitutions/Build.tsb
deleted file mode 100644
index 0478df14bff..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/Text Substitutions/Build.tsb
+++ /dev/null
@@ -1,56 +0,0 @@
-[<HKCR>]
-KeyType=4
-Value=
-
-[<HKUS>]
-KeyType=4
-Value=
-
-[<PROGRAMFILES>]
-KeyType=4
-Value=
-
-[<WINSYSDIR>]
-KeyType=4
-Value=
-
-[<COMMONFILES>]
-KeyType=4
-Value=
-
-[<WINDIR>]
-KeyType=4
-Value=
-
-[Data]
-Key0=<PROGRAMFILES>
-Key1=<COMMONFILES>
-Key2=<WINDIR>
-Key3=<WINSYSDIR>
-Key4=<HKLM>
-Key5=<HKCU>
-Key6=<HKCC>
-Key7=<HKDD>
-Key8=<HKUS>
-Key9=<HKCR>
-
-[General]
-Type=TEXTSUB
-Version=1.00.000
-
-[<HKCU>]
-KeyType=4
-Value=
-
-[<HKLM>]
-KeyType=4
-Value=
-
-[<HKDD>]
-KeyType=4
-Value=
-
-[<HKCC>]
-KeyType=4
-Value=
-
diff --git a/VC++Files/InstallShield/3.23.XX-com/Text Substitutions/Setup.tsb b/VC++Files/InstallShield/3.23.XX-com/Text Substitutions/Setup.tsb
deleted file mode 100644
index 258173c7a48..00000000000
--- a/VC++Files/InstallShield/3.23.XX-com/Text Substitutions/Setup.tsb
+++ /dev/null
@@ -1,76 +0,0 @@
-[<HKCR>]
-KeyType=4
-Value=
-
-[<HKUS>]
-KeyType=4
-Value=
-
-[<SRCDIR>]
-KeyType=4
-Value=
-
-[<PROGRAMFILES>]
-KeyType=4
-Value=
-
-[<TARGETDIR>]
-KeyType=4
-Value=
-
-[<WINSYSDIR>]
-KeyType=4
-Value=
-
-[<COMMONFILES>]
-KeyType=4
-Value=
-
-[<WINDIR>]
-KeyType=4
-Value=
-
-[Data]
-Key0=<PROGRAMFILES>
-Key1=<COMMONFILES>
-Key2=<WINDIR>
-Key3=<WINSYSDIR>
-Key4=<TARGETDIR>
-Key10=<HKDD>
-Key5=<SUPPORTDIR>
-Key11=<HKUS>
-Key6=<SRCDIR>
-Key12=<HKCR>
-Key7=<HKLM>
-Key13=<SHELL_OBJECT_FOLDER>
-Key8=<HKCU>
-Key9=<HKCC>
-
-[<SHELL_OBJECT_FOLDER>]
-KeyType=4
-Value=
-
-[<SUPPORTDIR>]
-KeyType=4
-Value=
-
-[General]
-Type=TEXTSUB
-Version=1.00.000
-
-[<HKCU>]
-KeyType=4
-Value=
-
-[<HKLM>]
-KeyType=4
-Value=
-
-[<HKDD>]
-KeyType=4
-Value=
-
-[<HKCC>]
-KeyType=4
-Value=
-
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/.fgl b/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/.fgl
deleted file mode 100644
index 81e474f9be8..00000000000
--- a/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/.fgl
+++ /dev/null
@@ -1,37 +0,0 @@
-[General]
-Type=FILELIST
-Version=1.00.000
-
-[topdir]
-subdir0=<WINDIR>
-subdir1=<PROGRAMFILES>
-subdir2=<TARGETDIR>
-subdir3=USERDEFINED
-
-[<WINDIR>]
-DISPLAYTEXT=Windows Operating System
-TYPE=TEXTSUBFIXED
-subdir0=<WINDIR>\<WINSYSDIR>
-
-[<WINDIR>\<WINSYSDIR>]
-DISPLAYTEXT=Windows System Folder
-TYPE=TEXTSUBFIXED
-
-[<PROGRAMFILES>]
-DISPLAYTEXT=Program Files Folder
-TYPE=TEXTSUBFIXED
-subdir0=<PROGRAMFILES>\<COMMONFILES>
-
-[<PROGRAMFILES>\<COMMONFILES>]
-DISPLAYTEXT=Common Files Folder
-TYPE=TEXTSUBFIXED
-
-[<TARGETDIR>]
-DISPLAYTEXT=General Application Destination
-TYPE=TEXTSUBFIXED
-
-[USERDEFINED]
-DISPLAYTEXT=Script-defined Folders
-TYPE=USERSTART
-
-
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Clients and Tools.fgl b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Clients and Tools.fgl
deleted file mode 100644
index 7f30ff9f64b..00000000000
--- a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Clients and Tools.fgl
+++ /dev/null
@@ -1,35 +0,0 @@
-[bin]
-file15=C:\mysql\bin\pack_isam.exe
-file16=C:\mysql\bin\perror.exe
-file0=C:\mysql\bin\isamchk.exe
-file17=C:\mysql\bin\replace.exe
-file1=C:\mysql\bin\myisamchk.exe
-file18=C:\mysql\bin\winmysqladmin.cnt
-file2=C:\mysql\bin\myisamlog.exe
-file19=C:\mysql\bin\winmysqladmin.exe
-file3=C:\mysql\bin\myisampack.exe
-file4=C:\mysql\bin\mysql.exe
-file5=C:\mysql\bin\mysqladmin.exe
-file6=C:\mysql\bin\mysqlbinlog.exe
-file7=C:\mysql\bin\mysqlc.exe
-file8=C:\mysql\bin\mysqlcheck.exe
-file9=C:\mysql\bin\mysqldump.exe
-file20=C:\mysql\bin\WINMYSQLADMIN.HLP
-file21=C:\mysql\bin\cygwinb19.dll
-file10=C:\mysql\bin\mysqlimport.exe
-fulldirectory=
-file22=C:\mysql\bin\libmySQL.dll
-file11=C:\mysql\bin\MySqlManager.exe
-file23=C:\mysql\bin\my_print_defaults.exe
-file12=C:\mysql\bin\mysqlshow.exe
-file24=C:\mysql\bin\comp-err.exe
-file13=C:\mysql\bin\mysqlshutdown.exe
-file14=C:\mysql\bin\mysqlwatch.exe
-
-[TopDir]
-SubDir0=bin
-
-[General]
-Type=FILELIST
-Version=1.00.000
-
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fgl b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fgl
deleted file mode 100644
index 94344a6ff69..00000000000
--- a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fgl
+++ /dev/null
@@ -1,4 +0,0 @@
-[General]
-Type=FILELIST
-Version=1.00.000
-
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Development.fgl b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Development.fgl
deleted file mode 100644
index e7b8cc7cd0f..00000000000
--- a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Development.fgl
+++ /dev/null
@@ -1,191 +0,0 @@
-[bench\Data\Wisconsin]
-file0=C:\mysql\bench\Data\Wisconsin\onek.data
-file1=C:\mysql\bench\Data\Wisconsin\tenk.data
-fulldirectory=
-
-[lib\debug]
-file0=C:\mysql\lib\debug\libmySQL.dll
-file1=C:\mysql\lib\debug\libmySQL.lib
-file2=C:\mysql\lib\debug\mysqlclient.lib
-file3=C:\mysql\lib\debug\zlib.lib
-fulldirectory=
-
-[bench\output]
-fulldirectory=
-
-[examples\libmysqltest]
-file0=C:\mysql\examples\libmysqltest\myTest.c
-file1=C:\mysql\examples\libmysqltest\myTest.dsp
-file2=C:\mysql\examples\libmysqltest\myTest.dsw
-file3=C:\mysql\examples\libmysqltest\myTest.exe
-file4=C:\mysql\examples\libmysqltest\myTest.mak
-file5=C:\mysql\examples\libmysqltest\myTest.ncb
-file6=C:\mysql\examples\libmysqltest\myTest.opt
-file7=C:\mysql\examples\libmysqltest\readme
-fulldirectory=
-
-[include]
-file0=C:\mysql\include\raid.h
-file1=C:\mysql\include\errmsg.h
-file2=C:\mysql\include\Libmysql.def
-file3=C:\mysql\include\m_ctype.h
-file4=C:\mysql\include\m_string.h
-file5=C:\mysql\include\my_list.h
-file6=C:\mysql\include\my_pthread.h
-file7=C:\mysql\include\my_sys.h
-file8=C:\mysql\include\mysql.h
-file9=C:\mysql\include\mysql_com.h
-file10=C:\mysql\include\mysql_version.h
-fulldirectory=
-file11=C:\mysql\include\mysqld_error.h
-file12=C:\mysql\include\dbug.h
-file13=C:\mysql\include\my_global.h
-file14=C:\mysql\include\config-win.h
-
-[examples]
-SubDir0=examples\libmysqltest
-SubDir1=examples\tests
-fulldirectory=
-
-[lib\opt]
-file0=C:\mysql\lib\opt\libmySQL.dll
-file1=C:\mysql\lib\opt\libmySQL.lib
-file2=C:\mysql\lib\opt\mysqlclient.lib
-file3=C:\mysql\lib\opt\zlib.lib
-fulldirectory=
-
-[bench\Data]
-SubDir0=bench\Data\ATIS
-SubDir1=bench\Data\Wisconsin
-fulldirectory=
-
-[bench\limits]
-file15=C:\mysql\bench\limits\pg.comment
-file16=C:\mysql\bench\limits\solid.cfg
-file0=C:\mysql\bench\limits\access.cfg
-file17=C:\mysql\bench\limits\solid-nt4.cfg
-file1=C:\mysql\bench\limits\access.comment
-file18=C:\mysql\bench\limits\sybase.cfg
-file2=C:\mysql\bench\limits\Adabas.cfg
-file3=C:\mysql\bench\limits\Adabas.comment
-file4=C:\mysql\bench\limits\Db2.cfg
-file5=C:\mysql\bench\limits\empress.cfg
-file6=C:\mysql\bench\limits\empress.comment
-file7=C:\mysql\bench\limits\Informix.cfg
-file8=C:\mysql\bench\limits\Informix.comment
-file9=C:\mysql\bench\limits\msql.cfg
-file10=C:\mysql\bench\limits\ms-sql.cfg
-fulldirectory=
-file11=C:\mysql\bench\limits\Ms-sql65.cfg
-file12=C:\mysql\bench\limits\mysql.cfg
-file13=C:\mysql\bench\limits\oracle.cfg
-file14=C:\mysql\bench\limits\pg.cfg
-
-[TopDir]
-SubDir0=bench
-SubDir1=examples
-SubDir2=include
-SubDir3=lib
-SubDir4=scripts
-
-[bench]
-file15=C:\mysql\bench\test-create
-file16=C:\mysql\bench\test-insert
-file0=C:\mysql\bench\uname.bat
-file17=C:\mysql\bench\test-select
-file1=C:\mysql\bench\compare-results
-file18=C:\mysql\bench\test-wisconsin
-file2=C:\mysql\bench\copy-db
-file19=C:\mysql\bench\bench-init.pl
-file3=C:\mysql\bench\crash-me
-file4=C:\mysql\bench\example.bat
-file5=C:\mysql\bench\print-limit-table
-file6=C:\mysql\bench\pwd.bat
-file7=C:\mysql\bench\Readme
-SubDir0=bench\Data
-file8=C:\mysql\bench\run.bat
-SubDir1=bench\limits
-file9=C:\mysql\bench\run-all-tests
-SubDir2=bench\output
-file10=C:\mysql\bench\server-cfg
-fulldirectory=
-file11=C:\mysql\bench\test-alter-table
-file12=C:\mysql\bench\test-ATIS
-file13=C:\mysql\bench\test-big-tables
-file14=C:\mysql\bench\test-connect
-
-[examples\tests]
-file15=C:\mysql\examples\tests\lock_test.res
-file16=C:\mysql\examples\tests\mail_to_db.pl
-file0=C:\mysql\examples\tests\unique_users.tst
-file17=C:\mysql\examples\tests\table_types.pl
-file1=C:\mysql\examples\tests\auto_increment.tst
-file18=C:\mysql\examples\tests\test_delayed_insert.pl
-file2=C:\mysql\examples\tests\big_record.pl
-file19=C:\mysql\examples\tests\udf_test
-file3=C:\mysql\examples\tests\big_record.res
-file4=C:\mysql\examples\tests\czech-sorting
-file5=C:\mysql\examples\tests\deadlock-script.pl
-file6=C:\mysql\examples\tests\export.pl
-file7=C:\mysql\examples\tests\fork_test.pl
-file8=C:\mysql\examples\tests\fork2_test.pl
-file9=C:\mysql\examples\tests\fork3_test.pl
-file20=C:\mysql\examples\tests\udf_test.res
-file21=C:\mysql\examples\tests\auto_increment.res
-file10=C:\mysql\examples\tests\function.res
-fulldirectory=
-file11=C:\mysql\examples\tests\function.tst
-file12=C:\mysql\examples\tests\grant.pl
-file13=C:\mysql\examples\tests\grant.res
-file14=C:\mysql\examples\tests\lock_test.pl
-
-[bench\Data\ATIS]
-file26=C:\mysql\bench\Data\ATIS\stop1.txt
-file15=C:\mysql\bench\Data\ATIS\flight_class.txt
-file27=C:\mysql\bench\Data\ATIS\time_interval.txt
-file16=C:\mysql\bench\Data\ATIS\flight_day.txt
-file0=C:\mysql\bench\Data\ATIS\transport.txt
-file28=C:\mysql\bench\Data\ATIS\time_zone.txt
-file17=C:\mysql\bench\Data\ATIS\flight_fare.txt
-file1=C:\mysql\bench\Data\ATIS\airline.txt
-file29=C:\mysql\bench\Data\ATIS\aircraft.txt
-file18=C:\mysql\bench\Data\ATIS\food_service.txt
-file2=C:\mysql\bench\Data\ATIS\airport.txt
-file19=C:\mysql\bench\Data\ATIS\ground_service.txt
-file3=C:\mysql\bench\Data\ATIS\airport_service.txt
-file4=C:\mysql\bench\Data\ATIS\city.txt
-file5=C:\mysql\bench\Data\ATIS\class_of_service.txt
-file6=C:\mysql\bench\Data\ATIS\code_description.txt
-file7=C:\mysql\bench\Data\ATIS\compound_class.txt
-file8=C:\mysql\bench\Data\ATIS\connect_leg.txt
-file9=C:\mysql\bench\Data\ATIS\date_day.txt
-file20=C:\mysql\bench\Data\ATIS\month_name.txt
-file21=C:\mysql\bench\Data\ATIS\restrict_carrier.txt
-file10=C:\mysql\bench\Data\ATIS\day_name.txt
-fulldirectory=
-file22=C:\mysql\bench\Data\ATIS\restrict_class.txt
-file11=C:\mysql\bench\Data\ATIS\dual_carrier.txt
-file23=C:\mysql\bench\Data\ATIS\restriction.txt
-file12=C:\mysql\bench\Data\ATIS\fare.txt
-file24=C:\mysql\bench\Data\ATIS\state.txt
-file13=C:\mysql\bench\Data\ATIS\fconnection.txt
-file25=C:\mysql\bench\Data\ATIS\stop.txt
-file14=C:\mysql\bench\Data\ATIS\flight.txt
-
-[General]
-Type=FILELIST
-Version=1.00.000
-
-[scripts]
-file0=C:\mysql\scripts\mysql_find_rows.pl
-file1=C:\mysql\scripts\mysql_setpermission.pl
-file2=C:\mysql\scripts\mysqlhotcopy.pl
-file3=C:\mysql\scripts\Readme
-fulldirectory=
-
-[lib]
-file0=C:\mysql\lib\Readme
-SubDir0=lib\debug
-SubDir1=lib\opt
-fulldirectory=
-
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Servers.fgl b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Servers.fgl
deleted file mode 100644
index b23e2f90595..00000000000
--- a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Servers.fgl
+++ /dev/null
@@ -1,184 +0,0 @@
-[share\polish]
-file0=C:\mysql\share\polish\errmsg.sys
-file1=C:\mysql\share\polish\errmsg.txt
-fulldirectory=
-
-[share\dutch]
-file0=C:\mysql\share\dutch\errmsg.sys
-file1=C:\mysql\share\dutch\errmsg.txt
-fulldirectory=
-
-[share\spanish]
-file0=C:\mysql\share\spanish\errmsg.sys
-file1=C:\mysql\share\spanish\errmsg.txt
-fulldirectory=
-
-[share\english]
-file0=C:\mysql\share\english\errmsg.sys
-file1=C:\mysql\share\english\errmsg.txt
-fulldirectory=
-
-[bin]
-file0=C:\mysql\bin\mysqld-opt.exe
-file1=C:\mysql\bin\mysqld-max.exe
-file2=C:\mysql\bin\mysqld-max-nt.exe
-file3=C:\mysql\bin\mysqld-nt.exe
-file4=C:\mysql\bin\mysqld.exe
-fulldirectory=
-
-[share\korean]
-file0=C:\mysql\share\korean\errmsg.sys
-file1=C:\mysql\share\korean\errmsg.txt
-fulldirectory=
-
-[share\charsets]
-file15=C:\mysql\share\charsets\latin1.conf
-file16=C:\mysql\share\charsets\latin2.conf
-file0=C:\mysql\share\charsets\win1251ukr.conf
-file17=C:\mysql\share\charsets\latin5.conf
-file1=C:\mysql\share\charsets\cp1257.conf
-file18=C:\mysql\share\charsets\Readme
-file2=C:\mysql\share\charsets\croat.conf
-file19=C:\mysql\share\charsets\swe7.conf
-file3=C:\mysql\share\charsets\danish.conf
-file4=C:\mysql\share\charsets\dec8.conf
-file5=C:\mysql\share\charsets\dos.conf
-file6=C:\mysql\share\charsets\estonia.conf
-file7=C:\mysql\share\charsets\german1.conf
-file8=C:\mysql\share\charsets\greek.conf
-file9=C:\mysql\share\charsets\hebrew.conf
-file20=C:\mysql\share\charsets\usa7.conf
-file21=C:\mysql\share\charsets\win1250.conf
-file10=C:\mysql\share\charsets\hp8.conf
-fulldirectory=
-file22=C:\mysql\share\charsets\win1251.conf
-file11=C:\mysql\share\charsets\hungarian.conf
-file23=C:\mysql\share\charsets\cp1251.conf
-file12=C:\mysql\share\charsets\Index
-file13=C:\mysql\share\charsets\koi8_ru.conf
-file14=C:\mysql\share\charsets\koi8_ukr.conf
-
-[share\ukrainian]
-file0=C:\mysql\share\ukrainian\errmsg.sys
-file1=C:\mysql\share\ukrainian\errmsg.txt
-fulldirectory=
-
-[share\hungarian]
-file0=C:\mysql\share\hungarian\errmsg.sys
-file1=C:\mysql\share\hungarian\errmsg.txt
-fulldirectory=
-
-[share\german]
-file0=C:\mysql\share\german\errmsg.sys
-file1=C:\mysql\share\german\errmsg.txt
-fulldirectory=
-
-[share\portuguese]
-file0=C:\mysql\share\portuguese\errmsg.sys
-file1=C:\mysql\share\portuguese\errmsg.txt
-fulldirectory=
-
-[share\estonian]
-file0=C:\mysql\share\estonian\errmsg.sys
-file1=C:\mysql\share\estonian\errmsg.txt
-fulldirectory=
-
-[share\romanian]
-file0=C:\mysql\share\romanian\errmsg.sys
-file1=C:\mysql\share\romanian\errmsg.txt
-fulldirectory=
-
-[share\french]
-file0=C:\mysql\share\french\errmsg.sys
-file1=C:\mysql\share\french\errmsg.txt
-fulldirectory=
-
-[share\swedish]
-file0=C:\mysql\share\swedish\errmsg.sys
-file1=C:\mysql\share\swedish\errmsg.txt
-fulldirectory=
-
-[share\slovak]
-file0=C:\mysql\share\slovak\errmsg.sys
-file1=C:\mysql\share\slovak\errmsg.txt
-fulldirectory=
-
-[share\greek]
-file0=C:\mysql\share\greek\errmsg.sys
-file1=C:\mysql\share\greek\errmsg.txt
-fulldirectory=
-
-[TopDir]
-file0=C:\mysql\mysqlbug.txt
-file1=C:\mysql\my-small.cnf
-file2=C:\mysql\my-large.cnf
-file3=C:\mysql\my-medium.cnf
-file4=C:\mysql\my-huge.cnf
-SubDir0=bin
-SubDir1=share
-
-[share]
-SubDir8=share\hungarian
-SubDir9=share\charsets
-SubDir20=share\spanish
-SubDir21=share\swedish
-SubDir10=share\italian
-SubDir22=share\ukrainian
-SubDir11=share\japanese
-SubDir12=share\korean
-SubDir13=share\norwegian
-SubDir14=share\norwegian-ny
-SubDir15=share\polish
-SubDir16=share\portuguese
-SubDir0=share\czech
-SubDir17=share\romanian
-SubDir1=share\danish
-SubDir18=share\russian
-SubDir2=share\dutch
-SubDir19=share\slovak
-SubDir3=share\english
-fulldirectory=
-SubDir4=share\estonian
-SubDir5=share\french
-SubDir6=share\german
-SubDir7=share\greek
-
-[share\norwegian-ny]
-file0=C:\mysql\share\norwegian-ny\errmsg.sys
-file1=C:\mysql\share\norwegian-ny\errmsg.txt
-fulldirectory=
-
-[share\danish]
-file0=C:\mysql\share\danish\errmsg.sys
-file1=C:\mysql\share\danish\errmsg.txt
-fulldirectory=
-
-[share\czech]
-file0=C:\mysql\share\czech\errmsg.sys
-file1=C:\mysql\share\czech\errmsg.txt
-fulldirectory=
-
-[General]
-Type=FILELIST
-Version=1.00.000
-
-[share\russian]
-file0=C:\mysql\share\russian\errmsg.sys
-file1=C:\mysql\share\russian\errmsg.txt
-fulldirectory=
-
-[share\norwegian]
-file0=C:\mysql\share\norwegian\errmsg.sys
-file1=C:\mysql\share\norwegian\errmsg.txt
-fulldirectory=
-
-[share\japanese]
-file0=C:\mysql\share\japanese\errmsg.sys
-file1=C:\mysql\share\japanese\errmsg.txt
-fulldirectory=
-
-[share\italian]
-file0=C:\mysql\share\italian\errmsg.sys
-file1=C:\mysql\share\italian\errmsg.txt
-fulldirectory=
-
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/MySQL 3.23.XX-GPL.ipr b/VC++Files/InstallShield/3.23.XX-gpl/MySQL 3.23.XX-GPL.ipr
deleted file mode 100644
index de15790e744..00000000000
--- a/VC++Files/InstallShield/3.23.XX-gpl/MySQL 3.23.XX-GPL.ipr
+++ /dev/null
@@ -1,51 +0,0 @@
-[Language]
-LanguageSupport0=0009
-
-[OperatingSystem]
-OSSupport=0000000000010010
-
-[Data]
-CurrentMedia=
-CurrentComponentDef=Default.cdf
-ProductName=MySQL Servers and Clients
-set_mifserial=
-DevEnvironment=Microsoft Visual C++ 6
-AppExe=
-set_dlldebug=No
-EmailAddresss=
-Instructions=Instructions.txt
-set_testmode=No
-set_mif=No
-SummaryText=
-Department=
-HomeURL=
-Author=
-Type=Database Application
-InstallRoot=C:\MySQL-Install\3.23.XX-gpl
-Version=1.00.000
-InstallationGUID=40744a4d-efed-4cff-84a9-9e6389550f5c
-set_level=Level 3
-CurrentFileGroupDef=Default.fdf
-Notes=Notes.txt
-set_maxerr=50
-set_args=
-set_miffile=Status.mif
-set_dllcmdline=
-Copyright=
-set_warnaserr=No
-CurrentPlatform=
-Category=
-set_preproc=
-CurrentLanguage=English
-CompanyName=MySQL
-Description=Description.txt
-set_maxwarn=50
-set_crc=Yes
-set_compileb4build=No
-
-[MediaInfo]
-
-[General]
-Type=INSTALLMAIN
-Version=1.10.000
-
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.rul b/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.rul
deleted file mode 100644
index 0db8417a62c..00000000000
--- a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.rul
+++ /dev/null
@@ -1,641 +0,0 @@
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// IIIIIII SSSSSS
-// II SS InstallShield (R)
-// II SSSSSS (c) 1996-1997, InstallShield Software Corporation
-// II SS (c) 1990-1996, InstallShield Corporation
-// IIIIIII SSSSSS All Rights Reserved.
-//
-//
-// This code is generated as a starting setup template. You should
-// modify it to provide all necessary steps for your setup.
-//
-//
-// File Name: Setup.rul
-//
-// Description: InstallShield script
-//
-// Comments: This template script performs a basic setup on a
-// Windows 95 or Windows NT 4.0 platform. With minor
-// modifications, this template can be adapted to create
-// new, customized setups.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-
- // Include header file
-#include "sdlang.h"
-#include "sddialog.h"
-
-////////////////////// string defines ////////////////////////////
-
-#define UNINST_LOGFILE_NAME "Uninst.isu"
-
-//////////////////// installation declarations ///////////////////
-
- // ----- DLL prototypes -----
-
-
- // your DLL prototypes
-
-
- // ---- script prototypes -----
-
- // generated
- prototype ShowDialogs();
- prototype MoveFileData();
- prototype HandleMoveDataError( NUMBER );
- prototype ProcessBeforeDataMove();
- prototype ProcessAfterDataMove();
- prototype SetupRegistry();
- prototype SetupFolders();
- prototype CleanUpInstall();
- prototype SetupInstall();
- prototype SetupScreen();
- prototype CheckRequirements();
- prototype DialogShowSdWelcome();
- prototype DialogShowSdShowInfoList();
- prototype DialogShowSdAskDestPath();
- prototype DialogShowSdSetupType();
- prototype DialogShowSdComponentDialog2();
- prototype DialogShowSdFinishReboot();
-
- // your prototypes
-
-
- // ----- global variables ------
-
- // generated
- BOOL bWinNT, bIsShellExplorer, bInstallAborted, bIs32BitSetup;
- STRING svDir;
- STRING svName, svCompany, svSerial;
- STRING szAppPath;
- STRING svSetupType;
-
-
- // your global variables
-
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// MAIN PROGRAM
-//
-// The setup begins here by hiding the visible setup
-// window. This is done to allow all the titles, images, etc. to
-// be established before showing the main window. The following
-// logic then performs the setup in a series of steps.
-//
-///////////////////////////////////////////////////////////////////////////////
-program
- Disable( BACKGROUND );
-
- CheckRequirements();
-
- SetupInstall();
-
- SetupScreen();
-
- if (ShowDialogs()<0) goto end_install;
-
- if (ProcessBeforeDataMove()<0) goto end_install;
-
- if (MoveFileData()<0) goto end_install;
-
- if (ProcessAfterDataMove()<0) goto end_install;
-
- if (SetupRegistry()<0) goto end_install;
-
- if (SetupFolders()<0) goto end_install;
-
-
- end_install:
-
- CleanUpInstall();
-
- // If an unrecoverable error occurred, clean up the partial installation.
- // Otherwise, exit normally.
-
- if (bInstallAborted) then
- abort;
- endif;
-
-endprogram
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: ShowDialogs //
-// //
-// Purpose: This function manages the display and navigation //
-// the standard dialogs that exist in a setup. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function ShowDialogs()
- NUMBER nResult;
- begin
-
- Dlg_Start:
- // beginning of dialogs label
-
- Dlg_SdWelcome:
- nResult = DialogShowSdWelcome();
- if (nResult = BACK) goto Dlg_Start;
-
- Dlg_SdShowInfoList:
- nResult = DialogShowSdShowInfoList();
- if (nResult = BACK) goto Dlg_SdWelcome;
-
- Dlg_SdAskDestPath:
- nResult = DialogShowSdAskDestPath();
- if (nResult = BACK) goto Dlg_SdShowInfoList;
-
- Dlg_SdSetupType:
- nResult = DialogShowSdSetupType();
- if (nResult = BACK) goto Dlg_SdAskDestPath;
-
- Dlg_SdComponentDialog2:
- if ((nResult = BACK) && (svSetupType != "Custom") && (svSetupType != "")) then
- goto Dlg_SdSetupType;
- endif;
- nResult = DialogShowSdComponentDialog2();
- if (nResult = BACK) goto Dlg_SdSetupType;
-
- return 0;
-
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: ProcessBeforeDataMove //
-// //
-// Purpose: This function performs any necessary operations prior to the //
-// actual data move operation. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function ProcessBeforeDataMove()
- STRING svLogFile;
- NUMBER nResult;
- begin
-
- InstallationInfo( @COMPANY_NAME, @PRODUCT_NAME, @PRODUCT_VERSION, @PRODUCT_KEY );
-
- svLogFile = UNINST_LOGFILE_NAME;
-
- nResult = DeinstallStart( svDir, svLogFile, @UNINST_KEY, 0 );
- if (nResult < 0) then
- MessageBox( @ERROR_UNINSTSETUP, WARNING );
- endif;
-
- szAppPath = TARGETDIR; // TODO : if your application .exe is in a subdir of TARGETDIR then add subdir
-
- if ((bIs32BitSetup) && (bIsShellExplorer)) then
- RegDBSetItem( REGDB_APPPATH, szAppPath );
- RegDBSetItem( REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY );
- RegDBSetItem( REGDB_UNINSTALL_NAME, @UNINST_DISPLAY_NAME );
- endif;
-
- // TODO : update any items you want to process before moving the data
- //
-
- return 0;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: MoveFileData //
-// //
-// Purpose: This function handles the data movement for //
-// the setup. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function MoveFileData()
- NUMBER nResult, nDisk;
- begin
-
- nDisk = 1;
- SetStatusWindow( 0, "" );
- Disable( DIALOGCACHE );
- Enable( STATUS );
- StatusUpdate( ON, 100 );
- nResult = ComponentMoveData( MEDIA, nDisk, 0 );
-
- HandleMoveDataError( nResult );
-
- Disable( STATUS );
-
- return nResult;
-
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: HandleMoveDataError //
-// //
-// Purpose: This function handles the error (if any) during the move data //
-// operation. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function HandleMoveDataError( nResult )
- STRING szErrMsg, svComponent , svFileGroup , svFile;
- begin
-
- svComponent = "";
- svFileGroup = "";
- svFile = "";
-
- switch (nResult)
- case 0:
- return 0;
- default:
- ComponentError ( MEDIA , svComponent , svFileGroup , svFile , nResult );
- szErrMsg = @ERROR_MOVEDATA + "\n\n" +
- @ERROR_COMPONENT + " " + svComponent + "\n" +
- @ERROR_FILEGROUP + " " + svFileGroup + "\n" +
- @ERROR_FILE + " " + svFile;
- SprintfBox( SEVERE, @TITLE_CAPTIONBAR, szErrMsg, nResult );
- bInstallAborted = TRUE;
- return nResult;
- endswitch;
-
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: ProcessAfterDataMove //
-// //
-// Purpose: This function performs any necessary operations needed after //
-// all data has been moved. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function ProcessAfterDataMove()
- begin
-
- // TODO : update self-registered files and other processes that
- // should be performed after the data has been moved.
-
-
- return 0;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: SetupRegistry //
-// //
-// Purpose: This function makes the registry entries for this setup. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function SetupRegistry()
- NUMBER nResult;
-
- begin
-
- // TODO : Add all your registry entry keys here
- //
- //
- // RegDBCreateKeyEx, RegDBSetKeyValueEx....
- //
-
- nResult = CreateRegistrySet( "" );
-
- return nResult;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// Function: SetupFolders
-//
-// Purpose: This function creates all the folders and shortcuts for the
-// setup. This includes program groups and items for Windows 3.1.
-//
-///////////////////////////////////////////////////////////////////////////////
-function SetupFolders()
- NUMBER nResult;
-
- begin
-
-
- // TODO : Add all your folder (program group) along with shortcuts (program items)
- //
- //
- // CreateProgramFolder, AddFolderIcon....
- //
-
- nResult = CreateShellObjects( "" );
-
- return nResult;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: CleanUpInstall //
-// //
-// Purpose: This cleans up the setup. Anything that should //
-// be released or deleted at the end of the setup should //
-// be done here. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function CleanUpInstall()
- begin
-
-
- if (bInstallAborted) then
- return 0;
- endif;
-
- DialogShowSdFinishReboot();
-
- if (BATCH_INSTALL) then // ensure locked files are properly written
- CommitSharedFiles(0);
- endif;
-
- return 0;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: SetupInstall //
-// //
-// Purpose: This will setup the installation. Any general initialization //
-// needed for the installation should be performed here. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function SetupInstall()
- begin
-
- Enable( CORECOMPONENTHANDLING );
-
- bInstallAborted = FALSE;
-
- if (bIs32BitSetup) then
- svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME ^ @PRODUCT_NAME;
- else
- svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME16 ^ @PRODUCT_NAME16; // use shorten names
- endif;
-
- TARGETDIR = svDir;
-
- SdProductName( @PRODUCT_NAME );
-
- Enable( DIALOGCACHE );
-
- return 0;
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: SetupScreen //
-// //
-// Purpose: This function establishes the screen look. This includes //
-// colors, fonts, and text to be displayed. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function SetupScreen()
- begin
-
- Enable( FULLWINDOWMODE );
- Enable( INDVFILESTATUS );
- SetTitle( @TITLE_MAIN, 24, WHITE );
-
- SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text.
-
- Enable( BACKGROUND );
-
- Delay( 1 );
- end;
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: CheckRequirements //
-// //
-// Purpose: This function checks all minimum requirements for the //
-// application being installed. If any fail, then the user //
-// is informed and the setup is terminated. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function CheckRequirements()
- NUMBER nvDx, nvDy, nvResult;
- STRING svResult;
-
- begin
-
- bWinNT = FALSE;
- bIsShellExplorer = FALSE;
-
- // Check screen resolution.
- GetExtents( nvDx, nvDy );
-
- if (nvDy < 480) then
- MessageBox( @ERROR_VGARESOLUTION, WARNING );
- abort;
- endif;
-
- // set 'setup' operation mode
- bIs32BitSetup = TRUE;
- GetSystemInfo( ISTYPE, nvResult, svResult );
- if (nvResult = 16) then
- bIs32BitSetup = FALSE; // running 16-bit setup
- return 0; // no additional information required
- endif;
-
- // --- 32-bit testing after this point ---
-
- // Determine the target system's operating system.
- GetSystemInfo( OS, nvResult, svResult );
-
- if (nvResult = IS_WINDOWSNT) then
- // Running Windows NT.
- bWinNT = TRUE;
-
- // Check to see if the shell being used is EXPLORER shell.
- if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then
- if (nvResult >= 4) then
- bIsShellExplorer = TRUE;
- endif;
- endif;
-
- elseif (nvResult = IS_WINDOWS95 ) then
- bIsShellExplorer = TRUE;
-
- endif;
-
-end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdWelcome //
-// //
-// Purpose: This function handles the standard welcome dialog. //
-// //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdWelcome()
- NUMBER nResult;
- STRING szTitle, szMsg;
- begin
-
- szTitle = "";
- szMsg = "";
- nResult = SdWelcome( szTitle, szMsg );
-
- return nResult;
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdShowInfoList //
-// //
-// Purpose: This function displays the general information list dialog. //
-// //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdShowInfoList()
- NUMBER nResult;
- LIST list;
- STRING szTitle, szMsg, szFile;
- begin
-
- szFile = SUPPORTDIR ^ "infolist.txt";
-
- list = ListCreate( STRINGLIST );
- ListReadFromFile( list, szFile );
- szTitle = "";
- szMsg = " ";
- nResult = SdShowInfoList( szTitle, szMsg, list );
-
- ListDestroy( list );
-
- return nResult;
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdAskDestPath //
-// //
-// Purpose: This function asks the user for the destination directory. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdAskDestPath()
- NUMBER nResult;
- STRING szTitle, szMsg;
- begin
-
- szTitle = "";
- szMsg = "";
- nResult = SdAskDestPath( szTitle, szMsg, svDir, 0 );
-
- TARGETDIR = svDir;
-
- return nResult;
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdSetupType //
-// //
-// Purpose: This function displays the standard setup type dialog. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdSetupType()
- NUMBER nResult, nType;
- STRING szTitle, szMsg;
- begin
-
- switch (svSetupType)
- case "Typical":
- nType = TYPICAL;
- case "Custom":
- nType = CUSTOM;
- case "Compact":
- nType = COMPACT;
- case "":
- svSetupType = "Typical";
- nType = TYPICAL;
- endswitch;
-
- szTitle = "";
- szMsg = "";
- nResult = SetupType( szTitle, szMsg, "", nType, 0 );
-
- switch (nResult)
- case COMPACT:
- svSetupType = "Compact";
- case TYPICAL:
- svSetupType = "Typical";
- case CUSTOM:
- svSetupType = "Custom";
- endswitch;
-
- return nResult;
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdComponentDialog2 //
-// //
-// Purpose: This function displays the custom component dialog. //
-// //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdComponentDialog2()
- NUMBER nResult;
- STRING szTitle, szMsg;
- begin
-
- if ((svSetupType != "Custom") && (svSetupType != "")) then
- return 0;
- endif;
-
- szTitle = "";
- szMsg = "";
- nResult = SdComponentDialog2( szTitle, szMsg, svDir, "" );
-
- return nResult;
- end;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// //
-// Function: DialogShowSdFinishReboot //
-// //
-// Purpose: This function will show the last dialog of the product. //
-// It will allow the user to reboot and/or show some readme text. //
-// //
-///////////////////////////////////////////////////////////////////////////////
-function DialogShowSdFinishReboot()
- NUMBER nResult, nDefOptions;
- STRING szTitle, szMsg1, szMsg2, szOption1, szOption2;
- NUMBER bOpt1, bOpt2;
- begin
-/*
- if (!BATCH_INSTALL) then
- bOpt1 = FALSE;
- bOpt2 = FALSE;
- szMsg1 = "";
- szMsg2 = "";
- szOption1 = "";
- szOption2 = "";
- nResult = SdFinish( szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2 );
- return 0;
- endif;
-
- nDefOptions = SYS_BOOTMACHINE;
- szTitle = "";
- szMsg1 = "";
- szMsg2 = "";
- nResult = SdFinishReboot( szTitle, szMsg1, nDefOptions, szMsg2, 0 );
-*/
- return nResult;
- end;
-
- // --- include script file section ---
-
-#include "sddialog.rul"
-
-
-
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt b/VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt
deleted file mode 100644
index b0a0a1eeb92..00000000000
--- a/VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-This is a release of MySQL @VERSION@ for Win32.
-
-NOTE: If you install MySQL in a folder other than
-C:\MYSQL or you intend to start MySQL on NT/Win2000
-as a service, you must create a file named C:\MY.CNF
-or \Windows\my.ini or \winnt\my.ini with the following
-information::
-
-[mysqld]
-basedir=E:/installation-path/
-datadir=E:/data-path/
-
-After your have installed MySQL, the installation
-directory which contains the files named 'my-size.cnf'.
-You can use this as a starting point for your own
-C:\my.cnf file.
-
-If you have any problems, you can mail them to
-win32@lists.mysql.com after you have consulted the
-MySQL manual and the MySQL mailing list archive
-(http://www.mysql.com/documentation/index.html)
-
-On behalf of the MySQL AB gang,
-Michael Widenius
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/String Tables/0009-English/value.shl b/VC++Files/InstallShield/3.23.XX-gpl/String Tables/0009-English/value.shl
deleted file mode 100644
index abbf6bce813..00000000000
--- a/VC++Files/InstallShield/3.23.XX-gpl/String Tables/0009-English/value.shl
+++ /dev/null
@@ -1,23 +0,0 @@
-[Data]
-TITLE_MAIN=MySQL Servers and Clients @VERSION@
-COMPANY_NAME=MySQL AB
-ERROR_COMPONENT=Component:
-COMPANY_NAME16=Company
-PRODUCT_VERSION=@VERSION@
-ERROR_MOVEDATA=An error occurred during the move data process: %d
-ERROR_FILEGROUP=File Group:
-UNINST_KEY=MySQL Servers and Clients @VERSION@
-TITLE_CAPTIONBAR=MySQL Servers and Clients @VERSION@ Setup
-PRODUCT_NAME16=Product
-ERROR_VGARESOLUTION=This program requires VGA or better resolution.
-ERROR_FILE=File:
-UNINST_DISPLAY_NAME=MySQL Servers and Clients @VERSION@
-PRODUCT_KEY=yourapp.Exe
-PRODUCT_NAME=MySQL Servers and Clients @VERSION@
-ERROR_UNINSTSETUP=unInstaller setup failed to initialize. You may not be able to uninstall this product.
-
-[General]
-Language=0009
-Type=STRINGTABLESPECIFIC
-Version=1.00.000
-
diff --git a/VC++Files/InstallShield/4.0.XX-classic/4.0.XX-classic.ipr b/VC++Files/InstallShield/4.0.XX-classic/4.0.XX-classic.ipr
new file mode 100755
index 00000000000..ef8404545fb
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-classic/4.0.XX-classic.ipr
@@ -0,0 +1,51 @@
+[Language]
+LanguageSupport0=0009
+
+[OperatingSystem]
+OSSupport=0000000000010010
+
+[Data]
+CurrentMedia=
+CurrentComponentDef=Default.cdf
+ProductName=MySQL Servers and Clients
+set_mifserial=
+DevEnvironment=Microsoft Visual C++ 6
+AppExe=
+set_dlldebug=No
+EmailAddresss=
+Instructions=Instructions.txt
+set_testmode=No
+set_mif=No
+SummaryText=
+Department=
+HomeURL=
+Author=
+Type=Database Application
+InstallRoot=D:\MySQL-Install\4.0.xcom-clas
+Version=1.00.000
+InstallationGUID=40744a4d-efed-4cff-84a9-9e6389550f5c
+set_level=Level 3
+CurrentFileGroupDef=Default.fdf
+Notes=Notes.txt
+set_maxerr=50
+set_args=
+set_miffile=Status.mif
+set_dllcmdline=
+Copyright=
+set_warnaserr=No
+CurrentPlatform=
+Category=
+set_preproc=
+CurrentLanguage=English
+CompanyName=MySQL
+Description=Description.txt
+set_maxwarn=50
+set_crc=Yes
+set_compileb4build=No
+
+[MediaInfo]
+
+[General]
+Type=INSTALLMAIN
+Version=1.10.000
+
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.cdf b/VC++Files/InstallShield/4.0.XX-classic/Component Definitions/Default.cdf
index 48d37800cd1..48d37800cd1 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.cdf
+++ b/VC++Files/InstallShield/4.0.XX-classic/Component Definitions/Default.cdf
diff --git a/VC++Files/InstallShield/3.23.XX-com/Component Definitions/Default.fgl b/VC++Files/InstallShield/4.0.XX-classic/Component Definitions/Default.fgl
index 4e20dcea4ab..4e20dcea4ab 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-com/Component Definitions/Default.fgl
+++ b/VC++Files/InstallShield/4.0.XX-classic/Component Definitions/Default.fgl
diff --git a/VC++Files/InstallShield/4.0.XX-classic/File Groups/Clients and Tools.fgl b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Clients and Tools.fgl
new file mode 100755
index 00000000000..7bba3d7474a
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Clients and Tools.fgl
@@ -0,0 +1,31 @@
+[bin]
+file15=C:\mysql\bin\replace.exe
+file16=C:\mysql\bin\winmysqladmin.cnt
+file0=C:\mysql\bin\isamchk.exe
+file17=C:\mysql\bin\WINMYSQLADMIN.HLP
+file1=C:\mysql\bin\myisamchk.exe
+file18=C:\mysql\bin\comp-err.exe
+file2=C:\mysql\bin\myisamlog.exe
+file19=C:\mysql\bin\my_print_defaults.exe
+file3=C:\mysql\bin\myisampack.exe
+file4=C:\mysql\bin\mysql.exe
+file5=C:\mysql\bin\mysqladmin.exe
+file6=C:\mysql\bin\mysqlbinlog.exe
+file7=C:\mysql\bin\mysqlc.exe
+file8=C:\mysql\bin\mysqlcheck.exe
+file9=C:\mysql\bin\mysqldump.exe
+file20=C:\mysql\bin\winmysqladmin.exe
+file10=C:\mysql\bin\mysqlimport.exe
+fulldirectory=
+file11=C:\mysql\bin\mysqlshow.exe
+file12=C:\mysql\bin\mysqlwatch.exe
+file13=C:\mysql\bin\pack_isam.exe
+file14=C:\mysql\bin\perror.exe
+
+[TopDir]
+SubDir0=bin
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fdf b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Default.fdf
index 8096a4b74bf..8096a4b74bf 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fdf
+++ b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Default.fdf
diff --git a/VC++Files/InstallShield/4.0.XX-classic/File Groups/Development.fgl b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Development.fgl
new file mode 100755
index 00000000000..6f9df51965b
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Development.fgl
@@ -0,0 +1,239 @@
+[bench\Data\Wisconsin]
+file0=C:\mysql\bench\Data\Wisconsin\onek.data
+file1=C:\mysql\bench\Data\Wisconsin\tenk.data
+fulldirectory=
+
+[lib\debug]
+file0=C:\mysql\lib\debug\libmySQL.dll
+file1=C:\mysql\lib\debug\libmySQL.lib
+file2=C:\mysql\lib\debug\mysqlclient.lib
+file3=C:\mysql\lib\debug\zlib.lib
+file4=C:\mysql\lib\debug\mysys.lib
+file5=C:\mysql\lib\debug\regex.lib
+file6=C:\mysql\lib\debug\strings.lib
+fulldirectory=
+
+[bench\output]
+fulldirectory=
+
+[examples\libmysqltest]
+file0=C:\mysql\examples\libmysqltest\myTest.c
+file1=C:\mysql\examples\libmysqltest\myTest.dsp
+file2=C:\mysql\examples\libmysqltest\myTest.dsw
+file3=C:\mysql\examples\libmysqltest\myTest.exe
+file4=C:\mysql\examples\libmysqltest\myTest.mak
+file5=C:\mysql\examples\libmysqltest\myTest.ncb
+file6=C:\mysql\examples\libmysqltest\myTest.opt
+file7=C:\mysql\examples\libmysqltest\readme
+fulldirectory=
+
+[include]
+file15=C:\mysql\include\libmysqld.def
+file16=C:\mysql\include\my_alloc.h
+file0=C:\mysql\include\raid.h
+file17=C:\mysql\include\my_getopt.h
+file1=C:\mysql\include\errmsg.h
+file2=C:\mysql\include\Libmysql.def
+file3=C:\mysql\include\m_ctype.h
+file4=C:\mysql\include\m_string.h
+file5=C:\mysql\include\my_list.h
+file6=C:\mysql\include\my_pthread.h
+file7=C:\mysql\include\my_sys.h
+file8=C:\mysql\include\mysql.h
+file9=C:\mysql\include\mysql_com.h
+file10=C:\mysql\include\mysql_version.h
+fulldirectory=
+file11=C:\mysql\include\mysqld_error.h
+file12=C:\mysql\include\dbug.h
+file13=C:\mysql\include\config-win.h
+file14=C:\mysql\include\my_global.h
+
+[examples]
+SubDir0=examples\libmysqltest
+SubDir1=examples\tests
+fulldirectory=
+
+[lib\opt]
+file0=C:\mysql\lib\opt\libmySQL.dll
+file1=C:\mysql\lib\opt\libmySQL.lib
+file2=C:\mysql\lib\opt\mysqlclient.lib
+file3=C:\mysql\lib\opt\zlib.lib
+file4=C:\mysql\lib\opt\mysys.lib
+file5=C:\mysql\lib\opt\regex.lib
+file6=C:\mysql\lib\opt\strings.lib
+fulldirectory=
+
+[bench\Data]
+SubDir0=bench\Data\ATIS
+SubDir1=bench\Data\Wisconsin
+fulldirectory=
+
+[bench\limits]
+file15=C:\mysql\bench\limits\pg.comment
+file16=C:\mysql\bench\limits\solid.cfg
+file0=C:\mysql\bench\limits\access.cfg
+file17=C:\mysql\bench\limits\solid-nt4.cfg
+file1=C:\mysql\bench\limits\access.comment
+file18=C:\mysql\bench\limits\sybase.cfg
+file2=C:\mysql\bench\limits\Adabas.cfg
+file3=C:\mysql\bench\limits\Adabas.comment
+file4=C:\mysql\bench\limits\Db2.cfg
+file5=C:\mysql\bench\limits\empress.cfg
+file6=C:\mysql\bench\limits\empress.comment
+file7=C:\mysql\bench\limits\Informix.cfg
+file8=C:\mysql\bench\limits\Informix.comment
+file9=C:\mysql\bench\limits\msql.cfg
+file10=C:\mysql\bench\limits\ms-sql.cfg
+fulldirectory=
+file11=C:\mysql\bench\limits\Ms-sql65.cfg
+file12=C:\mysql\bench\limits\mysql.cfg
+file13=C:\mysql\bench\limits\oracle.cfg
+file14=C:\mysql\bench\limits\pg.cfg
+
+[TopDir]
+SubDir0=bench
+SubDir1=examples
+SubDir2=include
+SubDir3=lib
+SubDir4=scripts
+
+[bench]
+file15=C:\mysql\bench\test-create
+file16=C:\mysql\bench\test-insert
+file0=C:\mysql\bench\uname.bat
+file17=C:\mysql\bench\test-select
+file1=C:\mysql\bench\compare-results
+file18=C:\mysql\bench\test-wisconsin
+file2=C:\mysql\bench\copy-db
+file19=C:\mysql\bench\bench-init.pl
+file3=C:\mysql\bench\crash-me
+file4=C:\mysql\bench\example.bat
+file5=C:\mysql\bench\print-limit-table
+file6=C:\mysql\bench\pwd.bat
+file7=C:\mysql\bench\Readme
+SubDir0=bench\Data
+file8=C:\mysql\bench\run.bat
+SubDir1=bench\limits
+file9=C:\mysql\bench\run-all-tests
+SubDir2=bench\output
+file10=C:\mysql\bench\server-cfg
+fulldirectory=
+file11=C:\mysql\bench\test-alter-table
+file12=C:\mysql\bench\test-ATIS
+file13=C:\mysql\bench\test-big-tables
+file14=C:\mysql\bench\test-connect
+
+[examples\tests]
+file15=C:\mysql\examples\tests\lock_test.res
+file16=C:\mysql\examples\tests\mail_to_db.pl
+file0=C:\mysql\examples\tests\unique_users.tst
+file17=C:\mysql\examples\tests\table_types.pl
+file1=C:\mysql\examples\tests\auto_increment.tst
+file18=C:\mysql\examples\tests\test_delayed_insert.pl
+file2=C:\mysql\examples\tests\big_record.pl
+file19=C:\mysql\examples\tests\udf_test
+file3=C:\mysql\examples\tests\big_record.res
+file4=C:\mysql\examples\tests\czech-sorting
+file5=C:\mysql\examples\tests\deadlock-script.pl
+file6=C:\mysql\examples\tests\export.pl
+file7=C:\mysql\examples\tests\fork_test.pl
+file8=C:\mysql\examples\tests\fork2_test.pl
+file9=C:\mysql\examples\tests\fork3_test.pl
+file20=C:\mysql\examples\tests\udf_test.res
+file21=C:\mysql\examples\tests\auto_increment.res
+file10=C:\mysql\examples\tests\function.res
+fulldirectory=
+file11=C:\mysql\examples\tests\function.tst
+file12=C:\mysql\examples\tests\grant.pl
+file13=C:\mysql\examples\tests\grant.res
+file14=C:\mysql\examples\tests\lock_test.pl
+
+[bench\Data\ATIS]
+file26=C:\mysql\bench\Data\ATIS\stop1.txt
+file15=C:\mysql\bench\Data\ATIS\flight_class.txt
+file27=C:\mysql\bench\Data\ATIS\time_interval.txt
+file16=C:\mysql\bench\Data\ATIS\flight_day.txt
+file0=C:\mysql\bench\Data\ATIS\transport.txt
+file28=C:\mysql\bench\Data\ATIS\time_zone.txt
+file17=C:\mysql\bench\Data\ATIS\flight_fare.txt
+file1=C:\mysql\bench\Data\ATIS\airline.txt
+file29=C:\mysql\bench\Data\ATIS\aircraft.txt
+file18=C:\mysql\bench\Data\ATIS\food_service.txt
+file2=C:\mysql\bench\Data\ATIS\airport.txt
+file19=C:\mysql\bench\Data\ATIS\ground_service.txt
+file3=C:\mysql\bench\Data\ATIS\airport_service.txt
+file4=C:\mysql\bench\Data\ATIS\city.txt
+file5=C:\mysql\bench\Data\ATIS\class_of_service.txt
+file6=C:\mysql\bench\Data\ATIS\code_description.txt
+file7=C:\mysql\bench\Data\ATIS\compound_class.txt
+file8=C:\mysql\bench\Data\ATIS\connect_leg.txt
+file9=C:\mysql\bench\Data\ATIS\date_day.txt
+file20=C:\mysql\bench\Data\ATIS\month_name.txt
+file21=C:\mysql\bench\Data\ATIS\restrict_carrier.txt
+file10=C:\mysql\bench\Data\ATIS\day_name.txt
+fulldirectory=
+file22=C:\mysql\bench\Data\ATIS\restrict_class.txt
+file11=C:\mysql\bench\Data\ATIS\dual_carrier.txt
+file23=C:\mysql\bench\Data\ATIS\restriction.txt
+file12=C:\mysql\bench\Data\ATIS\fare.txt
+file24=C:\mysql\bench\Data\ATIS\state.txt
+file13=C:\mysql\bench\Data\ATIS\fconnection.txt
+file25=C:\mysql\bench\Data\ATIS\stop.txt
+file14=C:\mysql\bench\Data\ATIS\flight.txt
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
+[scripts]
+file37=C:\mysql\scripts\mysqld_safe-watch.sh
+file26=C:\mysql\scripts\mysql_zap
+file15=C:\mysql\scripts\mysql_fix_privilege_tables
+file38=C:\mysql\scripts\mysqldumpslow
+file27=C:\mysql\scripts\mysql_zap.sh
+file16=C:\mysql\scripts\mysql_fix_privilege_tables.sh
+file0=C:\mysql\scripts\Readme
+file39=C:\mysql\scripts\mysqldumpslow.sh
+file28=C:\mysql\scripts\mysqlaccess
+file17=C:\mysql\scripts\mysql_install_db
+file1=C:\mysql\scripts\make_binary_distribution.sh
+file29=C:\mysql\scripts\mysqlaccess.conf
+file18=C:\mysql\scripts\mysql_install_db.sh
+file2=C:\mysql\scripts\msql2mysql
+file19=C:\mysql\scripts\mysql_secure_installation
+file3=C:\mysql\scripts\msql2mysql.sh
+file4=C:\mysql\scripts\mysql_config
+file5=C:\mysql\scripts\mysql_config.sh
+file6=C:\mysql\scripts\mysql_convert_table_format
+file7=C:\mysql\scripts\mysql_convert_table_format.sh
+file40=C:\mysql\scripts\mysqlhotcopy
+file8=C:\mysql\scripts\mysql_explain_log
+file41=C:\mysql\scripts\mysqlhotcopy.pl
+file30=C:\mysql\scripts\mysqlaccess.sh
+file9=C:\mysql\scripts\mysql_explain_log.sh
+file42=C:\mysql\scripts\mysqlhotcopy.sh
+file31=C:\mysql\scripts\mysqlbug
+file20=C:\mysql\scripts\mysql_secure_installation.sh
+file43=C:\mysql\scripts\make_binary_distribution
+file32=C:\mysql\scripts\mysqlbug.sh
+file21=C:\mysql\scripts\mysql_setpermission
+file10=C:\mysql\scripts\mysql_find_rows
+fulldirectory=
+file33=C:\mysql\scripts\mysqld_multi
+file22=C:\mysql\scripts\mysql_setpermission.pl
+file11=C:\mysql\scripts\mysql_find_rows.pl
+file34=C:\mysql\scripts\mysqld_multi.sh
+file23=C:\mysql\scripts\mysql_setpermission.sh
+file12=C:\mysql\scripts\mysql_find_rows.sh
+file35=C:\mysql\scripts\mysqld_safe
+file24=C:\mysql\scripts\mysql_tableinfo
+file13=C:\mysql\scripts\mysql_fix_extensions
+file36=C:\mysql\scripts\mysqld_safe.sh
+file25=C:\mysql\scripts\mysql_tableinfo.sh
+file14=C:\mysql\scripts\mysql_fix_extensions.sh
+
+[lib]
+SubDir0=lib\debug
+SubDir1=lib\opt
+fulldirectory=
+
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Documentation.fgl b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Documentation.fgl
index 80fe777cf0f..80fe777cf0f 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Documentation.fgl
+++ b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Documentation.fgl
diff --git a/VC++Files/InstallShield/3.23.XX-com/File Groups/Grant Tables.fgl b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Grant Tables.fgl
index 178065a7003..178065a7003 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-com/File Groups/Grant Tables.fgl
+++ b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Grant Tables.fgl
diff --git a/VC++Files/InstallShield/4.0.XX-classic/File Groups/Servers.fgl b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Servers.fgl
new file mode 100755
index 00000000000..3f875b574f6
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-classic/File Groups/Servers.fgl
@@ -0,0 +1,226 @@
+[Embedded\Static\release]
+file0=C:\mysql\embedded\Static\release\test_stc.dsp
+file1=C:\mysql\embedded\Static\release\ReadMe.txt
+file2=C:\mysql\embedded\Static\release\StdAfx.cpp
+file3=C:\mysql\embedded\Static\release\StdAfx.h
+file4=C:\mysql\embedded\Static\release\test_stc.cpp
+file5=C:\mysql\embedded\Static\release\mysqlserver.lib
+fulldirectory=
+
+[share\polish]
+file0=C:\mysql\share\polish\errmsg.sys
+file1=C:\mysql\share\polish\errmsg.txt
+fulldirectory=
+
+[share\dutch]
+file0=C:\mysql\share\dutch\errmsg.sys
+file1=C:\mysql\share\dutch\errmsg.txt
+fulldirectory=
+
+[share\spanish]
+file0=C:\mysql\share\spanish\errmsg.sys
+file1=C:\mysql\share\spanish\errmsg.txt
+fulldirectory=
+
+[share\english]
+file0=C:\mysql\share\english\errmsg.sys
+file1=C:\mysql\share\english\errmsg.txt
+fulldirectory=
+
+[bin]
+file0=C:\mysql\bin\mysqld-opt.exe
+file1=C:\mysql\bin\mysqld-nt.exe
+file2=C:\mysql\bin\mysqld.exe
+file3=C:\mysql\bin\cygwinb19.dll
+file4=C:\mysql\bin\libmySQL.dll
+fulldirectory=
+
+[share\korean]
+file0=C:\mysql\share\korean\errmsg.sys
+file1=C:\mysql\share\korean\errmsg.txt
+fulldirectory=
+
+[share\charsets]
+file15=C:\mysql\share\charsets\latin1.conf
+file16=C:\mysql\share\charsets\latin2.conf
+file0=C:\mysql\share\charsets\win1251ukr.conf
+file17=C:\mysql\share\charsets\latin5.conf
+file1=C:\mysql\share\charsets\cp1257.conf
+file18=C:\mysql\share\charsets\Readme
+file2=C:\mysql\share\charsets\croat.conf
+file19=C:\mysql\share\charsets\swe7.conf
+file3=C:\mysql\share\charsets\danish.conf
+file4=C:\mysql\share\charsets\dec8.conf
+file5=C:\mysql\share\charsets\dos.conf
+file6=C:\mysql\share\charsets\estonia.conf
+file7=C:\mysql\share\charsets\german1.conf
+file8=C:\mysql\share\charsets\greek.conf
+file9=C:\mysql\share\charsets\hebrew.conf
+file20=C:\mysql\share\charsets\usa7.conf
+file21=C:\mysql\share\charsets\win1250.conf
+file10=C:\mysql\share\charsets\hp8.conf
+fulldirectory=
+file22=C:\mysql\share\charsets\win1251.conf
+file11=C:\mysql\share\charsets\hungarian.conf
+file23=C:\mysql\share\charsets\cp1251.conf
+file12=C:\mysql\share\charsets\Index
+file13=C:\mysql\share\charsets\koi8_ru.conf
+file14=C:\mysql\share\charsets\koi8_ukr.conf
+
+[Embedded\DLL\debug]
+file0=C:\mysql\embedded\DLL\debug\libmysqld.dll
+file1=C:\mysql\embedded\DLL\debug\libmysqld.exp
+file2=C:\mysql\embedded\DLL\debug\libmysqld.lib
+fulldirectory=
+
+[Embedded]
+file0=C:\mysql\embedded\embedded.dsw
+SubDir0=Embedded\DLL
+SubDir1=Embedded\Static
+fulldirectory=
+
+[share\ukrainian]
+file0=C:\mysql\share\ukrainian\errmsg.sys
+file1=C:\mysql\share\ukrainian\errmsg.txt
+fulldirectory=
+
+[share\hungarian]
+file0=C:\mysql\share\hungarian\errmsg.sys
+file1=C:\mysql\share\hungarian\errmsg.txt
+fulldirectory=
+
+[share\german]
+file0=C:\mysql\share\german\errmsg.sys
+file1=C:\mysql\share\german\errmsg.txt
+fulldirectory=
+
+[share\portuguese]
+file0=C:\mysql\share\portuguese\errmsg.sys
+file1=C:\mysql\share\portuguese\errmsg.txt
+fulldirectory=
+
+[share\estonian]
+file0=C:\mysql\share\estonian\errmsg.sys
+file1=C:\mysql\share\estonian\errmsg.txt
+fulldirectory=
+
+[share\romanian]
+file0=C:\mysql\share\romanian\errmsg.sys
+file1=C:\mysql\share\romanian\errmsg.txt
+fulldirectory=
+
+[share\french]
+file0=C:\mysql\share\french\errmsg.sys
+file1=C:\mysql\share\french\errmsg.txt
+fulldirectory=
+
+[share\swedish]
+file0=C:\mysql\share\swedish\errmsg.sys
+file1=C:\mysql\share\swedish\errmsg.txt
+fulldirectory=
+
+[share\slovak]
+file0=C:\mysql\share\slovak\errmsg.sys
+file1=C:\mysql\share\slovak\errmsg.txt
+fulldirectory=
+
+[share\greek]
+file0=C:\mysql\share\greek\errmsg.sys
+file1=C:\mysql\share\greek\errmsg.txt
+fulldirectory=
+
+[TopDir]
+file0=C:\mysql\my-huge.cnf
+file1=C:\mysql\my-large.cnf
+file2=C:\mysql\my-medium.cnf
+file3=C:\mysql\my-small.cnf
+file4=C:\mysql\MySQLEULA.txt
+SubDir0=bin
+SubDir1=share
+SubDir2=Embedded
+
+[share]
+SubDir8=share\hungarian
+SubDir9=share\charsets
+SubDir20=share\spanish
+SubDir21=share\swedish
+SubDir10=share\italian
+SubDir22=share\ukrainian
+SubDir11=share\japanese
+SubDir12=share\korean
+SubDir13=share\norwegian
+SubDir14=share\norwegian-ny
+SubDir15=share\polish
+SubDir16=share\portuguese
+SubDir0=share\czech
+SubDir17=share\romanian
+SubDir1=share\danish
+SubDir18=share\russian
+SubDir2=share\dutch
+SubDir19=share\slovak
+SubDir3=share\english
+fulldirectory=
+SubDir4=share\estonian
+SubDir5=share\french
+SubDir6=share\german
+SubDir7=share\greek
+
+[share\norwegian-ny]
+file0=C:\mysql\share\norwegian-ny\errmsg.sys
+file1=C:\mysql\share\norwegian-ny\errmsg.txt
+fulldirectory=
+
+[Embedded\DLL]
+file0=C:\mysql\embedded\DLL\test_dll.dsp
+file1=C:\mysql\embedded\DLL\StdAfx.h
+file2=C:\mysql\embedded\DLL\test_dll.cpp
+file3=C:\mysql\embedded\DLL\StdAfx.cpp
+SubDir0=Embedded\DLL\debug
+SubDir1=Embedded\DLL\release
+fulldirectory=
+
+[Embedded\Static]
+SubDir0=Embedded\Static\release
+fulldirectory=
+
+[Embedded\DLL\release]
+file0=C:\mysql\embedded\DLL\release\libmysqld.dll
+file1=C:\mysql\embedded\DLL\release\libmysqld.exp
+file2=C:\mysql\embedded\DLL\release\libmysqld.lib
+file3=C:\mysql\embedded\DLL\release\mysql-server.exe
+fulldirectory=
+
+[share\danish]
+file0=C:\mysql\share\danish\errmsg.sys
+file1=C:\mysql\share\danish\errmsg.txt
+fulldirectory=
+
+[share\czech]
+file0=C:\mysql\share\czech\errmsg.sys
+file1=C:\mysql\share\czech\errmsg.txt
+fulldirectory=
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
+[share\russian]
+file0=C:\mysql\share\russian\errmsg.sys
+file1=C:\mysql\share\russian\errmsg.txt
+fulldirectory=
+
+[share\norwegian]
+file0=C:\mysql\share\norwegian\errmsg.sys
+file1=C:\mysql\share\norwegian\errmsg.txt
+fulldirectory=
+
+[share\japanese]
+file0=C:\mysql\share\japanese\errmsg.sys
+file1=C:\mysql\share\japanese\errmsg.txt
+fulldirectory=
+
+[share\italian]
+file0=C:\mysql\share\italian\errmsg.sys
+file1=C:\mysql\share\italian\errmsg.txt
+fulldirectory=
+
diff --git a/VC++Files/InstallShield/3.23.XX-com/Registry Entries/Default.rge b/VC++Files/InstallShield/4.0.XX-classic/Registry Entries/Default.rge
index 537dfd82e48..537dfd82e48 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-com/Registry Entries/Default.rge
+++ b/VC++Files/InstallShield/4.0.XX-classic/Registry Entries/Default.rge
diff --git a/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.dbg b/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.dbg
index 0c6d4e6b708..0c6d4e6b708 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.dbg
+++ b/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.dbg
Binary files differ
diff --git a/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.ino b/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.ino
index 204d8ea0f36..204d8ea0f36 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.ino
+++ b/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.ino
Binary files differ
diff --git a/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.ins b/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.ins
index 759009b5c84..759009b5c84 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.ins
+++ b/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.ins
Binary files differ
diff --git a/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.obs b/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.obs
index 5fcfcb62c4e..5fcfcb62c4e 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-com/Script Files/Setup.obs
+++ b/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.obs
Binary files differ
diff --git a/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.rul b/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.rul
new file mode 100755
index 00000000000..df143b493c4
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-classic/Script Files/Setup.rul
@@ -0,0 +1,640 @@
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// IIIIIII SSSSSS
+// II SS InstallShield (R)
+// II SSSSSS (c) 1996-1997, InstallShield Software Corporation
+// II SS (c) 1990-1996, InstallShield Corporation
+// IIIIIII SSSSSS All Rights Reserved.
+//
+//
+// This code is generated as a starting setup template. You should
+// modify it to provide all necessary steps for your setup.
+//
+//
+// File Name: Setup.rul
+//
+// Description: InstallShield script
+//
+// Comments: This template script performs a basic setup on a
+// Windows 95 or Windows NT 4.0 platform. With minor
+// modifications, this template can be adapted to create
+// new, customized setups.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+ // Include header file
+#include "sdlang.h"
+#include "sddialog.h"
+
+////////////////////// string defines ////////////////////////////
+
+#define UNINST_LOGFILE_NAME "Uninst.isu"
+
+//////////////////// installation declarations ///////////////////
+
+ // ----- DLL prototypes -----
+
+
+ // your DLL prototypes
+
+
+ // ---- script prototypes -----
+
+ // generated
+ prototype ShowDialogs();
+ prototype MoveFileData();
+ prototype HandleMoveDataError( NUMBER );
+ prototype ProcessBeforeDataMove();
+ prototype ProcessAfterDataMove();
+ prototype SetupRegistry();
+ prototype SetupFolders();
+ prototype CleanUpInstall();
+ prototype SetupInstall();
+ prototype SetupScreen();
+ prototype CheckRequirements();
+ prototype DialogShowSdWelcome();
+ prototype DialogShowSdShowInfoList();
+ prototype DialogShowSdAskDestPath();
+ prototype DialogShowSdSetupType();
+ prototype DialogShowSdComponentDialog2();
+ prototype DialogShowSdFinishReboot();
+
+ // your prototypes
+
+
+ // ----- global variables ------
+
+ // generated
+ BOOL bWinNT, bIsShellExplorer, bInstallAborted, bIs32BitSetup;
+ STRING svDir;
+ STRING svName, svCompany, svSerial;
+ STRING szAppPath;
+ STRING svSetupType;
+
+
+ // your global variables
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// MAIN PROGRAM
+//
+// The setup begins here by hiding the visible setup
+// window. This is done to allow all the titles, images, etc. to
+// be established before showing the main window. The following
+// logic then performs the setup in a series of steps.
+//
+///////////////////////////////////////////////////////////////////////////////
+program
+ Disable( BACKGROUND );
+
+ CheckRequirements();
+
+ SetupInstall();
+
+ SetupScreen();
+
+ if (ShowDialogs()<0) goto end_install;
+
+ if (ProcessBeforeDataMove()<0) goto end_install;
+
+ if (MoveFileData()<0) goto end_install;
+
+ if (ProcessAfterDataMove()<0) goto end_install;
+
+ if (SetupRegistry()<0) goto end_install;
+
+ if (SetupFolders()<0) goto end_install;
+
+
+ end_install:
+
+ CleanUpInstall();
+
+ // If an unrecoverable error occurred, clean up the partial installation.
+ // Otherwise, exit normally.
+
+ if (bInstallAborted) then
+ abort;
+ endif;
+
+endprogram
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ShowDialogs //
+// //
+// Purpose: This function manages the display and navigation //
+// the standard dialogs that exist in a setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ShowDialogs()
+ NUMBER nResult;
+ begin
+
+ Dlg_Start:
+ // beginning of dialogs label
+
+ Dlg_SdWelcome:
+ nResult = DialogShowSdWelcome();
+ if (nResult = BACK) goto Dlg_Start;
+
+ Dlg_SdShowInfoList:
+ nResult = DialogShowSdShowInfoList();
+ if (nResult = BACK) goto Dlg_SdWelcome;
+
+ Dlg_SdAskDestPath:
+ nResult = DialogShowSdAskDestPath();
+ if (nResult = BACK) goto Dlg_SdShowInfoList;
+
+ Dlg_SdSetupType:
+ nResult = DialogShowSdSetupType();
+ if (nResult = BACK) goto Dlg_SdAskDestPath;
+
+ Dlg_SdComponentDialog2:
+ if ((nResult = BACK) && (svSetupType != "Custom") && (svSetupType != "")) then
+ goto Dlg_SdSetupType;
+ endif;
+ nResult = DialogShowSdComponentDialog2();
+ if (nResult = BACK) goto Dlg_SdSetupType;
+
+ return 0;
+
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ProcessBeforeDataMove //
+// //
+// Purpose: This function performs any necessary operations prior to the //
+// actual data move operation. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ProcessBeforeDataMove()
+ STRING svLogFile;
+ NUMBER nResult;
+ begin
+
+ InstallationInfo( @COMPANY_NAME, @PRODUCT_NAME, @PRODUCT_VERSION, @PRODUCT_KEY );
+
+ svLogFile = UNINST_LOGFILE_NAME;
+
+ nResult = DeinstallStart( svDir, svLogFile, @UNINST_KEY, 0 );
+ if (nResult < 0) then
+ MessageBox( @ERROR_UNINSTSETUP, WARNING );
+ endif;
+
+ szAppPath = TARGETDIR; // TODO : if your application .exe is in a subdir of TARGETDIR then add subdir
+
+ if ((bIs32BitSetup) && (bIsShellExplorer)) then
+ RegDBSetItem( REGDB_APPPATH, szAppPath );
+ RegDBSetItem( REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY );
+ RegDBSetItem( REGDB_UNINSTALL_NAME, @UNINST_DISPLAY_NAME );
+ endif;
+
+ // TODO : update any items you want to process before moving the data
+ //
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: MoveFileData //
+// //
+// Purpose: This function handles the data movement for //
+// the setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function MoveFileData()
+ NUMBER nResult, nDisk;
+ begin
+
+ nDisk = 1;
+ SetStatusWindow( 0, "" );
+ Disable( DIALOGCACHE );
+ Enable( STATUS );
+ StatusUpdate( ON, 100 );
+ nResult = ComponentMoveData( MEDIA, nDisk, 0 );
+
+ HandleMoveDataError( nResult );
+
+ Disable( STATUS );
+
+ return nResult;
+
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: HandleMoveDataError //
+// //
+// Purpose: This function handles the error (if any) during the move data //
+// operation. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function HandleMoveDataError( nResult )
+ STRING szErrMsg, svComponent , svFileGroup , svFile;
+ begin
+
+ svComponent = "";
+ svFileGroup = "";
+ svFile = "";
+
+ switch (nResult)
+ case 0:
+ return 0;
+ default:
+ ComponentError ( MEDIA , svComponent , svFileGroup , svFile , nResult );
+ szErrMsg = @ERROR_MOVEDATA + "\n\n" +
+ @ERROR_COMPONENT + " " + svComponent + "\n" +
+ @ERROR_FILEGROUP + " " + svFileGroup + "\n" +
+ @ERROR_FILE + " " + svFile;
+ SprintfBox( SEVERE, @TITLE_CAPTIONBAR, szErrMsg, nResult );
+ bInstallAborted = TRUE;
+ return nResult;
+ endswitch;
+
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ProcessAfterDataMove //
+// //
+// Purpose: This function performs any necessary operations needed after //
+// all data has been moved. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ProcessAfterDataMove()
+ begin
+
+ // TODO : update self-registered files and other processes that
+ // should be performed after the data has been moved.
+
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupRegistry //
+// //
+// Purpose: This function makes the registry entries for this setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupRegistry()
+ NUMBER nResult;
+
+ begin
+
+ // TODO : Add all your registry entry keys here
+ //
+ //
+ // RegDBCreateKeyEx, RegDBSetKeyValueEx....
+ //
+
+ nResult = CreateRegistrySet( "" );
+
+ return nResult;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Function: SetupFolders
+//
+// Purpose: This function creates all the folders and shortcuts for the
+// setup. This includes program groups and items for Windows 3.1.
+//
+///////////////////////////////////////////////////////////////////////////////
+function SetupFolders()
+ NUMBER nResult;
+
+ begin
+
+
+ // TODO : Add all your folder (program group) along with shortcuts (program items)
+ //
+ //
+ // CreateProgramFolder, AddFolderIcon....
+ //
+
+ nResult = CreateShellObjects( "" );
+
+ return nResult;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: CleanUpInstall //
+// //
+// Purpose: This cleans up the setup. Anything that should //
+// be released or deleted at the end of the setup should //
+// be done here. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function CleanUpInstall()
+ begin
+
+
+ if (bInstallAborted) then
+ return 0;
+ endif;
+
+ DialogShowSdFinishReboot();
+
+ if (BATCH_INSTALL) then // ensure locked files are properly written
+ CommitSharedFiles(0);
+ endif;
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupInstall //
+// //
+// Purpose: This will setup the installation. Any general initialization //
+// needed for the installation should be performed here. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupInstall()
+ begin
+
+ Enable( CORECOMPONENTHANDLING );
+
+ bInstallAborted = FALSE;
+
+ if (bIs32BitSetup) then
+ svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME ^ @PRODUCT_NAME;
+ else
+ svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME16 ^ @PRODUCT_NAME16; // use shorten names
+ endif;
+
+ TARGETDIR = svDir;
+
+ SdProductName( @PRODUCT_NAME );
+
+ Enable( DIALOGCACHE );
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupScreen //
+// //
+// Purpose: This function establishes the screen look. This includes //
+// colors, fonts, and text to be displayed. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupScreen()
+ begin
+
+ Enable( FULLWINDOWMODE );
+ Enable( INDVFILESTATUS );
+ SetTitle( @TITLE_MAIN, 24, WHITE );
+
+ SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text.
+
+ Enable( BACKGROUND );
+
+ Delay( 1 );
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: CheckRequirements //
+// //
+// Purpose: This function checks all minimum requirements for the //
+// application being installed. If any fail, then the user //
+// is informed and the setup is terminated. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function CheckRequirements()
+ NUMBER nvDx, nvDy, nvResult;
+ STRING svResult;
+
+ begin
+
+ bWinNT = FALSE;
+ bIsShellExplorer = FALSE;
+
+ // Check screen resolution.
+ GetExtents( nvDx, nvDy );
+
+ if (nvDy < 480) then
+ MessageBox( @ERROR_VGARESOLUTION, WARNING );
+ abort;
+ endif;
+
+ // set 'setup' operation mode
+ bIs32BitSetup = TRUE;
+ GetSystemInfo( ISTYPE, nvResult, svResult );
+ if (nvResult = 16) then
+ bIs32BitSetup = FALSE; // running 16-bit setup
+ return 0; // no additional information required
+ endif;
+
+ // --- 32-bit testing after this point ---
+
+ // Determine the target system's operating system.
+ GetSystemInfo( OS, nvResult, svResult );
+
+ if (nvResult = IS_WINDOWSNT) then
+ // Running Windows NT.
+ bWinNT = TRUE;
+
+ // Check to see if the shell being used is EXPLORER shell.
+ if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then
+ if (nvResult >= 4) then
+ bIsShellExplorer = TRUE;
+ endif;
+ endif;
+
+ elseif (nvResult = IS_WINDOWS95 ) then
+ bIsShellExplorer = TRUE;
+
+ endif;
+
+end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdWelcome //
+// //
+// Purpose: This function handles the standard welcome dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdWelcome()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdWelcome( szTitle, szMsg );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdShowInfoList //
+// //
+// Purpose: This function displays the general information list dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdShowInfoList()
+ NUMBER nResult;
+ LIST list;
+ STRING szTitle, szMsg, szFile;
+ begin
+
+ szFile = SUPPORTDIR ^ "infolist.txt";
+
+ list = ListCreate( STRINGLIST );
+ ListReadFromFile( list, szFile );
+ szTitle = "";
+ szMsg = " ";
+ nResult = SdShowInfoList( szTitle, szMsg, list );
+
+ ListDestroy( list );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdAskDestPath //
+// //
+// Purpose: This function asks the user for the destination directory. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdAskDestPath()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdAskDestPath( szTitle, szMsg, svDir, 0 );
+
+ TARGETDIR = svDir;
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdSetupType //
+// //
+// Purpose: This function displays the standard setup type dialog. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdSetupType()
+ NUMBER nResult, nType;
+ STRING szTitle, szMsg;
+ begin
+
+ switch (svSetupType)
+ case "Typical":
+ nType = TYPICAL;
+ case "Custom":
+ nType = CUSTOM;
+ case "Compact":
+ nType = COMPACT;
+ case "":
+ svSetupType = "Typical";
+ nType = TYPICAL;
+ endswitch;
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SetupType( szTitle, szMsg, "", nType, 0 );
+
+ switch (nResult)
+ case COMPACT:
+ svSetupType = "Compact";
+ case TYPICAL:
+ svSetupType = "Typical";
+ case CUSTOM:
+ svSetupType = "Custom";
+ endswitch;
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdComponentDialog2 //
+// //
+// Purpose: This function displays the custom component dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdComponentDialog2()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ if ((svSetupType != "Custom") && (svSetupType != "")) then
+ return 0;
+ endif;
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdComponentDialog2( szTitle, szMsg, svDir, "" );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdFinishReboot //
+// //
+// Purpose: This function will show the last dialog of the product. //
+// It will allow the user to reboot and/or show some readme text. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdFinishReboot()
+ NUMBER nResult, nDefOptions;
+ STRING szTitle, szMsg1, szMsg2, szOption1, szOption2;
+ NUMBER bOpt1, bOpt2;
+ begin
+
+ if (!BATCH_INSTALL) then
+ bOpt1 = FALSE;
+ bOpt2 = FALSE;
+ szMsg1 = "";
+ szMsg2 = "";
+ szOption1 = "";
+ szOption2 = "";
+ nResult = SdFinish( szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2 );
+ return 0;
+ endif;
+
+ nDefOptions = SYS_BOOTMACHINE;
+ szTitle = "";
+ szMsg1 = "";
+ szMsg2 = "";
+ nResult = SdFinishReboot( szTitle, szMsg1, nDefOptions, szMsg2, 0 );
+
+ return nResult;
+ end;
+
+ // --- include script file section ---
+
+#include "sddialog.rul"
+
+
diff --git a/VC++Files/InstallShield/4.0.XX-classic/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt b/VC++Files/InstallShield/4.0.XX-classic/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt
new file mode 100755
index 00000000000..e5a6f6ac433
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-classic/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt
@@ -0,0 +1,25 @@
+This is a release of MySQL Classic @VERSION@ for Win32.
+
+NOTE: If you install MySQL in a folder other than
+C:\MYSQL or you intend to start MySQL on NT/Win2000
+as a service, you must create a file named C:\MY.CNF
+or \Windows\my.ini or \winnt\my.ini with the following
+information::
+
+[mysqld]
+basedir=E:/installation-path/
+datadir=E:/data-path/
+
+After your have installed MySQL, the installation
+directory will contain 4 files named 'my-small.cnf,
+my-medium.cnf, my-large.cnf, my-huge.cnf'.
+You can use this as a starting point for your own
+C:\my.cnf file.
+
+If you have any problems, you can mail them to
+win32@lists.mysql.com after you have consulted the
+MySQL manual and the MySQL mailing list archive
+(http://www.mysql.com/documentation/index.html)
+
+On behalf of the MySQL AB gang,
+Michael Widenius
diff --git a/VC++Files/InstallShield/3.23.XX-com/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP b/VC++Files/InstallShield/4.0.XX-classic/Setup Files/Uncompressed Files/Language Independent/OS Independent/setup.bmp
index 3229d50c9bf..3229d50c9bf 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-com/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP
+++ b/VC++Files/InstallShield/4.0.XX-classic/Setup Files/Uncompressed Files/Language Independent/OS Independent/setup.bmp
Binary files differ
diff --git a/VC++Files/InstallShield/3.23.XX-com/Shell Objects/Default.shl b/VC++Files/InstallShield/4.0.XX-classic/Shell Objects/Default.shl
index 187cb651307..187cb651307 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-com/Shell Objects/Default.shl
+++ b/VC++Files/InstallShield/4.0.XX-classic/Shell Objects/Default.shl
diff --git a/VC++Files/InstallShield/4.0.XX-classic/String Tables/0009-English/value.shl b/VC++Files/InstallShield/4.0.XX-classic/String Tables/0009-English/value.shl
new file mode 100755
index 00000000000..868c801c68c
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-classic/String Tables/0009-English/value.shl
@@ -0,0 +1,23 @@
+[Data]
+TITLE_MAIN=MySQL Classic Servers and Clients @VERSION@
+COMPANY_NAME=MySQL AB
+ERROR_COMPONENT=Component:
+COMPANY_NAME16=Company
+PRODUCT_VERSION=MySQL Classic Servers and Clients @VERSION@
+ERROR_MOVEDATA=An error occurred during the move data process: %d
+ERROR_FILEGROUP=File Group:
+UNINST_KEY=MySQL Classic Servers and Clients @VERSION@
+TITLE_CAPTIONBAR=MySQL Classic Servers and Clients @VERSION@
+PRODUCT_NAME16=Product
+ERROR_VGARESOLUTION=This program requires VGA or better resolution.
+ERROR_FILE=File:
+UNINST_DISPLAY_NAME=MySQL Classic Servers and Clients @VERSION@
+PRODUCT_KEY=yourapp.Exe
+PRODUCT_NAME=MySQL Classic Servers and Clients @VERSION@
+ERROR_UNINSTSETUP=unInstaller setup failed to initialize. You may not be able to uninstall this product.
+
+[General]
+Language=0009
+Type=STRINGTABLESPECIFIC
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/String Tables/Default.shl b/VC++Files/InstallShield/4.0.XX-classic/String Tables/Default.shl
index d4dc4925ab1..d4dc4925ab1 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/String Tables/Default.shl
+++ b/VC++Files/InstallShield/4.0.XX-classic/String Tables/Default.shl
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Build.tsb b/VC++Files/InstallShield/4.0.XX-classic/Text Substitutions/Build.tsb
index 3949bd4c066..3949bd4c066 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Build.tsb
+++ b/VC++Files/InstallShield/4.0.XX-classic/Text Substitutions/Build.tsb
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Setup.tsb b/VC++Files/InstallShield/4.0.XX-classic/Text Substitutions/Setup.tsb
index b0c5a509f0b..b0c5a509f0b 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Setup.tsb
+++ b/VC++Files/InstallShield/4.0.XX-classic/Text Substitutions/Setup.tsb
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/4.0.XX-gpl.ipr b/VC++Files/InstallShield/4.0.XX-gpl/4.0.XX-gpl.ipr
new file mode 100755
index 00000000000..c415a03a315
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/4.0.XX-gpl.ipr
@@ -0,0 +1,51 @@
+[Language]
+LanguageSupport0=0009
+
+[OperatingSystem]
+OSSupport=0000000000010010
+
+[Data]
+CurrentMedia=
+CurrentComponentDef=Default.cdf
+ProductName=MySQL Servers and Clients
+set_mifserial=
+DevEnvironment=Microsoft Visual C++ 6
+AppExe=
+set_dlldebug=No
+EmailAddresss=
+Instructions=Instructions.txt
+set_testmode=No
+set_mif=No
+SummaryText=
+Department=
+HomeURL=
+Author=
+Type=Database Application
+InstallRoot=D:\MySQL-Install\mysql-4\MySQL Servers and Clients
+Version=1.00.000
+InstallationGUID=40744a4d-efed-4cff-84a9-9e6389550f5c
+set_level=Level 3
+CurrentFileGroupDef=Default.fdf
+Notes=Notes.txt
+set_maxerr=50
+set_args=
+set_miffile=Status.mif
+set_dllcmdline=
+Copyright=
+set_warnaserr=No
+CurrentPlatform=
+Category=
+set_preproc=
+CurrentLanguage=English
+CompanyName=MySQL
+Description=Description.txt
+set_maxwarn=50
+set_crc=Yes
+set_compileb4build=No
+
+[MediaInfo]
+
+[General]
+Type=INSTALLMAIN
+Version=1.10.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/Component Definitions/Default.cdf b/VC++Files/InstallShield/4.0.XX-gpl/Component Definitions/Default.cdf
new file mode 100755
index 00000000000..48d37800cd1
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Component Definitions/Default.cdf
@@ -0,0 +1,192 @@
+[Development]
+required0=Servers
+SELECTED=Yes
+FILENEED=STANDARD
+required1=Grant Tables
+HTTPLOCATION=
+STATUS=Examples, Libraries, Includes and Script files
+UNINSTALLABLE=Yes
+TARGET=<TARGETDIR>
+FTPLOCATION=
+VISIBLE=Yes
+DESCRIPTION=Examples, Libraries, Includes and Script files
+DISPLAYTEXT=Examples, Libraries, Includes and Script files
+IMAGE=
+DEFSELECTION=Yes
+filegroup0=Development
+COMMENT=
+INCLUDEINBUILD=Yes
+INSTALLATION=ALWAYSOVERWRITE
+COMPRESSIFSEPARATE=No
+MISC=
+ENCRYPT=No
+DISK=ANYDISK
+TARGETDIRCDROM=
+PASSWORD=
+TARGETHIDDEN=General Application Destination
+
+[Grant Tables]
+required0=Servers
+SELECTED=Yes
+FILENEED=CRITICAL
+HTTPLOCATION=
+STATUS=The Grant Tables and Core Files
+UNINSTALLABLE=Yes
+TARGET=<TARGETDIR>
+FTPLOCATION=
+VISIBLE=Yes
+DESCRIPTION=The Grant Tables and Core Files
+DISPLAYTEXT=The Grant Tables and Core Files
+IMAGE=
+DEFSELECTION=Yes
+filegroup0=Grant Tables
+requiredby0=Development
+COMMENT=
+INCLUDEINBUILD=Yes
+requiredby1=Clients and Tools
+INSTALLATION=NEVEROVERWRITE
+requiredby2=Documentation
+COMPRESSIFSEPARATE=No
+MISC=
+ENCRYPT=No
+DISK=ANYDISK
+TARGETDIRCDROM=
+PASSWORD=
+TARGETHIDDEN=General Application Destination
+
+[Components]
+component0=Development
+component1=Grant Tables
+component2=Servers
+component3=Clients and Tools
+component4=Documentation
+
+[TopComponents]
+component0=Servers
+component1=Clients and Tools
+component2=Documentation
+component3=Development
+component4=Grant Tables
+
+[SetupType]
+setuptype0=Compact
+setuptype1=Typical
+setuptype2=Custom
+
+[Clients and Tools]
+required0=Servers
+SELECTED=Yes
+FILENEED=HIGHLYRECOMMENDED
+required1=Grant Tables
+HTTPLOCATION=
+STATUS=The MySQL clients and Maintenance Tools
+UNINSTALLABLE=Yes
+TARGET=<TARGETDIR>
+FTPLOCATION=
+VISIBLE=Yes
+DESCRIPTION=The MySQL clients and Maintenance Tools
+DISPLAYTEXT=The MySQL clients and Maintenance Tools
+IMAGE=
+DEFSELECTION=Yes
+filegroup0=Clients and Tools
+COMMENT=
+INCLUDEINBUILD=Yes
+INSTALLATION=NEWERDATE
+COMPRESSIFSEPARATE=No
+MISC=
+ENCRYPT=No
+DISK=ANYDISK
+TARGETDIRCDROM=
+PASSWORD=
+TARGETHIDDEN=General Application Destination
+
+[Servers]
+SELECTED=Yes
+FILENEED=CRITICAL
+HTTPLOCATION=
+STATUS=The MySQL Servers
+UNINSTALLABLE=Yes
+TARGET=<TARGETDIR>
+FTPLOCATION=
+VISIBLE=Yes
+DESCRIPTION=The MySQL Servers
+DISPLAYTEXT=The MySQL Servers
+IMAGE=
+DEFSELECTION=Yes
+filegroup0=Servers
+requiredby0=Development
+COMMENT=
+INCLUDEINBUILD=Yes
+requiredby1=Grant Tables
+INSTALLATION=ALWAYSOVERWRITE
+requiredby2=Clients and Tools
+requiredby3=Documentation
+COMPRESSIFSEPARATE=No
+MISC=
+ENCRYPT=No
+DISK=ANYDISK
+TARGETDIRCDROM=
+PASSWORD=
+TARGETHIDDEN=General Application Destination
+
+[SetupTypeItem-Compact]
+Comment=
+item0=Grant Tables
+item1=Servers
+item2=Clients and Tools
+item3=Documentation
+Descrip=
+DisplayText=
+
+[SetupTypeItem-Custom]
+Comment=
+item0=Development
+item1=Grant Tables
+item2=Servers
+item3=Clients and Tools
+Descrip=
+item4=Documentation
+DisplayText=
+
+[Info]
+Type=CompDef
+Version=1.00.000
+Name=
+
+[SetupTypeItem-Typical]
+Comment=
+item0=Development
+item1=Grant Tables
+item2=Servers
+item3=Clients and Tools
+Descrip=
+item4=Documentation
+DisplayText=
+
+[Documentation]
+required0=Servers
+SELECTED=Yes
+FILENEED=HIGHLYRECOMMENDED
+required1=Grant Tables
+HTTPLOCATION=
+STATUS=The MySQL Documentation with different formats
+UNINSTALLABLE=Yes
+TARGET=<TARGETDIR>
+FTPLOCATION=
+VISIBLE=Yes
+DESCRIPTION=The MySQL Documentation with different formats
+DISPLAYTEXT=The MySQL Documentation with different formats
+IMAGE=
+DEFSELECTION=Yes
+filegroup0=Documentation
+COMMENT=
+INCLUDEINBUILD=Yes
+INSTALLATION=ALWAYSOVERWRITE
+COMPRESSIFSEPARATE=No
+MISC=
+ENCRYPT=No
+DISK=ANYDISK
+TARGETDIRCDROM=
+PASSWORD=
+TARGETHIDDEN=General Application Destination
+
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.fgl b/VC++Files/InstallShield/4.0.XX-gpl/Component Definitions/Default.fgl
index 4e20dcea4ab..4e20dcea4ab 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.fgl
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Component Definitions/Default.fgl
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Clients and Tools.fgl b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Clients and Tools.fgl
new file mode 100755
index 00000000000..7bba3d7474a
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Clients and Tools.fgl
@@ -0,0 +1,31 @@
+[bin]
+file15=C:\mysql\bin\replace.exe
+file16=C:\mysql\bin\winmysqladmin.cnt
+file0=C:\mysql\bin\isamchk.exe
+file17=C:\mysql\bin\WINMYSQLADMIN.HLP
+file1=C:\mysql\bin\myisamchk.exe
+file18=C:\mysql\bin\comp-err.exe
+file2=C:\mysql\bin\myisamlog.exe
+file19=C:\mysql\bin\my_print_defaults.exe
+file3=C:\mysql\bin\myisampack.exe
+file4=C:\mysql\bin\mysql.exe
+file5=C:\mysql\bin\mysqladmin.exe
+file6=C:\mysql\bin\mysqlbinlog.exe
+file7=C:\mysql\bin\mysqlc.exe
+file8=C:\mysql\bin\mysqlcheck.exe
+file9=C:\mysql\bin\mysqldump.exe
+file20=C:\mysql\bin\winmysqladmin.exe
+file10=C:\mysql\bin\mysqlimport.exe
+fulldirectory=
+file11=C:\mysql\bin\mysqlshow.exe
+file12=C:\mysql\bin\mysqlwatch.exe
+file13=C:\mysql\bin\pack_isam.exe
+file14=C:\mysql\bin\perror.exe
+
+[TopDir]
+SubDir0=bin
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Default.fdf b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Default.fdf
new file mode 100755
index 00000000000..8096a4b74bf
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Default.fdf
@@ -0,0 +1,82 @@
+[FileGroups]
+group0=Development
+group1=Grant Tables
+group2=Servers
+group3=Clients and Tools
+group4=Documentation
+
+[Development]
+SELFREGISTERING=No
+HTTPLOCATION=
+LANGUAGE=
+OPERATINGSYSTEM=
+FTPLOCATION=
+FILETYPE=No
+INFOTYPE=Standard
+COMMENT=
+COMPRESS=Yes
+COMPRESSDLL=
+POTENTIALLY=No
+MISC=
+
+[Grant Tables]
+SELFREGISTERING=No
+HTTPLOCATION=
+LANGUAGE=
+OPERATINGSYSTEM=
+FTPLOCATION=
+FILETYPE=No
+INFOTYPE=Standard
+COMMENT=
+COMPRESS=Yes
+COMPRESSDLL=
+POTENTIALLY=No
+MISC=
+
+[Clients and Tools]
+SELFREGISTERING=No
+HTTPLOCATION=
+LANGUAGE=
+OPERATINGSYSTEM=0000000000000000
+FTPLOCATION=
+FILETYPE=No
+INFOTYPE=Standard
+COMMENT=
+COMPRESS=Yes
+COMPRESSDLL=
+POTENTIALLY=No
+MISC=
+
+[Servers]
+SELFREGISTERING=No
+HTTPLOCATION=
+LANGUAGE=
+OPERATINGSYSTEM=
+FTPLOCATION=
+FILETYPE=No
+INFOTYPE=Standard
+COMMENT=
+COMPRESS=Yes
+COMPRESSDLL=
+POTENTIALLY=No
+MISC=
+
+[Info]
+Type=FileGrp
+Version=1.00.000
+Name=
+
+[Documentation]
+SELFREGISTERING=No
+HTTPLOCATION=
+LANGUAGE=
+OPERATINGSYSTEM=
+FTPLOCATION=
+FILETYPE=No
+INFOTYPE=Standard
+COMMENT=
+COMPRESS=Yes
+COMPRESSDLL=
+POTENTIALLY=No
+MISC=
+
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Development.fgl b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Development.fgl
new file mode 100755
index 00000000000..401509e9b7a
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Development.fgl
@@ -0,0 +1,241 @@
+[bench\Data\Wisconsin]
+file0=C:\mysql\bench\Data\Wisconsin\onek.data
+file1=C:\mysql\bench\Data\Wisconsin\tenk.data
+fulldirectory=
+
+[lib\debug]
+file0=C:\mysql\lib\debug\libmySQL.dll
+file1=C:\mysql\lib\debug\libmySQL.lib
+file2=C:\mysql\lib\debug\mysqlclient.lib
+file3=C:\mysql\lib\debug\zlib.lib
+file4=C:\mysql\lib\debug\regex.lib
+file5=C:\mysql\lib\debug\mysys.lib
+file6=C:\mysql\lib\debug\strings.lib
+fulldirectory=
+
+[bench\output]
+fulldirectory=
+
+[examples\libmysqltest]
+file0=C:\mysql\examples\libmysqltest\myTest.c
+file1=C:\mysql\examples\libmysqltest\myTest.dsp
+file2=C:\mysql\examples\libmysqltest\myTest.dsw
+file3=C:\mysql\examples\libmysqltest\myTest.exe
+file4=C:\mysql\examples\libmysqltest\myTest.mak
+file5=C:\mysql\examples\libmysqltest\myTest.ncb
+file6=C:\mysql\examples\libmysqltest\myTest.opt
+file7=C:\mysql\examples\libmysqltest\readme
+fulldirectory=
+
+[include]
+file15=C:\mysql\include\libmysqld.def
+file16=C:\mysql\include\my_alloc.h
+file0=C:\mysql\include\raid.h
+file17=C:\mysql\include\my_getopt.h
+file1=C:\mysql\include\errmsg.h
+file2=C:\mysql\include\Libmysql.def
+file3=C:\mysql\include\m_ctype.h
+file4=C:\mysql\include\m_string.h
+file5=C:\mysql\include\my_list.h
+file6=C:\mysql\include\my_pthread.h
+file7=C:\mysql\include\my_sys.h
+file8=C:\mysql\include\mysql.h
+file9=C:\mysql\include\mysql_com.h
+file10=C:\mysql\include\mysql_version.h
+fulldirectory=
+file11=C:\mysql\include\mysqld_error.h
+file12=C:\mysql\include\dbug.h
+file13=C:\mysql\include\config-win.h
+file14=C:\mysql\include\my_global.h
+
+[examples]
+SubDir0=examples\libmysqltest
+SubDir1=examples\tests
+fulldirectory=
+
+[lib\opt]
+file0=C:\mysql\lib\opt\libmySQL.dll
+file1=C:\mysql\lib\opt\libmySQL.lib
+file2=C:\mysql\lib\opt\mysqlclient.lib
+file3=C:\mysql\lib\opt\zlib.lib
+file4=C:\mysql\lib\opt\strings.lib
+file5=C:\mysql\lib\opt\mysys-max.lib
+file6=C:\mysql\lib\opt\regex.lib
+file7=C:\mysql\lib\opt\mysys.lib
+fulldirectory=
+
+[bench\Data]
+SubDir0=bench\Data\ATIS
+SubDir1=bench\Data\Wisconsin
+fulldirectory=
+
+[bench\limits]
+file15=C:\mysql\bench\limits\pg.comment
+file16=C:\mysql\bench\limits\solid.cfg
+file0=C:\mysql\bench\limits\access.cfg
+file17=C:\mysql\bench\limits\solid-nt4.cfg
+file1=C:\mysql\bench\limits\access.comment
+file18=C:\mysql\bench\limits\sybase.cfg
+file2=C:\mysql\bench\limits\Adabas.cfg
+file3=C:\mysql\bench\limits\Adabas.comment
+file4=C:\mysql\bench\limits\Db2.cfg
+file5=C:\mysql\bench\limits\empress.cfg
+file6=C:\mysql\bench\limits\empress.comment
+file7=C:\mysql\bench\limits\Informix.cfg
+file8=C:\mysql\bench\limits\Informix.comment
+file9=C:\mysql\bench\limits\msql.cfg
+file10=C:\mysql\bench\limits\ms-sql.cfg
+fulldirectory=
+file11=C:\mysql\bench\limits\Ms-sql65.cfg
+file12=C:\mysql\bench\limits\mysql.cfg
+file13=C:\mysql\bench\limits\oracle.cfg
+file14=C:\mysql\bench\limits\pg.cfg
+
+[TopDir]
+SubDir0=bench
+SubDir1=examples
+SubDir2=include
+SubDir3=lib
+SubDir4=scripts
+
+[bench]
+file15=C:\mysql\bench\test-create
+file16=C:\mysql\bench\test-insert
+file0=C:\mysql\bench\uname.bat
+file17=C:\mysql\bench\test-select
+file1=C:\mysql\bench\compare-results
+file18=C:\mysql\bench\test-wisconsin
+file2=C:\mysql\bench\copy-db
+file19=C:\mysql\bench\bench-init.pl
+file3=C:\mysql\bench\crash-me
+file4=C:\mysql\bench\example.bat
+file5=C:\mysql\bench\print-limit-table
+file6=C:\mysql\bench\pwd.bat
+file7=C:\mysql\bench\Readme
+SubDir0=bench\Data
+file8=C:\mysql\bench\run.bat
+SubDir1=bench\limits
+file9=C:\mysql\bench\run-all-tests
+SubDir2=bench\output
+file10=C:\mysql\bench\server-cfg
+fulldirectory=
+file11=C:\mysql\bench\test-alter-table
+file12=C:\mysql\bench\test-ATIS
+file13=C:\mysql\bench\test-big-tables
+file14=C:\mysql\bench\test-connect
+
+[examples\tests]
+file15=C:\mysql\examples\tests\lock_test.res
+file16=C:\mysql\examples\tests\mail_to_db.pl
+file0=C:\mysql\examples\tests\unique_users.tst
+file17=C:\mysql\examples\tests\table_types.pl
+file1=C:\mysql\examples\tests\auto_increment.tst
+file18=C:\mysql\examples\tests\test_delayed_insert.pl
+file2=C:\mysql\examples\tests\big_record.pl
+file19=C:\mysql\examples\tests\udf_test
+file3=C:\mysql\examples\tests\big_record.res
+file4=C:\mysql\examples\tests\czech-sorting
+file5=C:\mysql\examples\tests\deadlock-script.pl
+file6=C:\mysql\examples\tests\export.pl
+file7=C:\mysql\examples\tests\fork_test.pl
+file8=C:\mysql\examples\tests\fork2_test.pl
+file9=C:\mysql\examples\tests\fork3_test.pl
+file20=C:\mysql\examples\tests\udf_test.res
+file21=C:\mysql\examples\tests\auto_increment.res
+file10=C:\mysql\examples\tests\function.res
+fulldirectory=
+file11=C:\mysql\examples\tests\function.tst
+file12=C:\mysql\examples\tests\grant.pl
+file13=C:\mysql\examples\tests\grant.res
+file14=C:\mysql\examples\tests\lock_test.pl
+
+[bench\Data\ATIS]
+file26=C:\mysql\bench\Data\ATIS\stop1.txt
+file15=C:\mysql\bench\Data\ATIS\flight_class.txt
+file27=C:\mysql\bench\Data\ATIS\time_interval.txt
+file16=C:\mysql\bench\Data\ATIS\flight_day.txt
+file0=C:\mysql\bench\Data\ATIS\transport.txt
+file28=C:\mysql\bench\Data\ATIS\time_zone.txt
+file17=C:\mysql\bench\Data\ATIS\flight_fare.txt
+file1=C:\mysql\bench\Data\ATIS\airline.txt
+file29=C:\mysql\bench\Data\ATIS\aircraft.txt
+file18=C:\mysql\bench\Data\ATIS\food_service.txt
+file2=C:\mysql\bench\Data\ATIS\airport.txt
+file19=C:\mysql\bench\Data\ATIS\ground_service.txt
+file3=C:\mysql\bench\Data\ATIS\airport_service.txt
+file4=C:\mysql\bench\Data\ATIS\city.txt
+file5=C:\mysql\bench\Data\ATIS\class_of_service.txt
+file6=C:\mysql\bench\Data\ATIS\code_description.txt
+file7=C:\mysql\bench\Data\ATIS\compound_class.txt
+file8=C:\mysql\bench\Data\ATIS\connect_leg.txt
+file9=C:\mysql\bench\Data\ATIS\date_day.txt
+file20=C:\mysql\bench\Data\ATIS\month_name.txt
+file21=C:\mysql\bench\Data\ATIS\restrict_carrier.txt
+file10=C:\mysql\bench\Data\ATIS\day_name.txt
+fulldirectory=
+file22=C:\mysql\bench\Data\ATIS\restrict_class.txt
+file11=C:\mysql\bench\Data\ATIS\dual_carrier.txt
+file23=C:\mysql\bench\Data\ATIS\restriction.txt
+file12=C:\mysql\bench\Data\ATIS\fare.txt
+file24=C:\mysql\bench\Data\ATIS\state.txt
+file13=C:\mysql\bench\Data\ATIS\fconnection.txt
+file25=C:\mysql\bench\Data\ATIS\stop.txt
+file14=C:\mysql\bench\Data\ATIS\flight.txt
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
+[scripts]
+file37=C:\mysql\scripts\mysqld_safe-watch.sh
+file26=C:\mysql\scripts\mysql_zap
+file15=C:\mysql\scripts\mysql_fix_privilege_tables
+file38=C:\mysql\scripts\mysqldumpslow
+file27=C:\mysql\scripts\mysql_zap.sh
+file16=C:\mysql\scripts\mysql_fix_privilege_tables.sh
+file0=C:\mysql\scripts\Readme
+file39=C:\mysql\scripts\mysqldumpslow.sh
+file28=C:\mysql\scripts\mysqlaccess
+file17=C:\mysql\scripts\mysql_install_db
+file1=C:\mysql\scripts\make_binary_distribution.sh
+file29=C:\mysql\scripts\mysqlaccess.conf
+file18=C:\mysql\scripts\mysql_install_db.sh
+file2=C:\mysql\scripts\msql2mysql
+file19=C:\mysql\scripts\mysql_secure_installation
+file3=C:\mysql\scripts\msql2mysql.sh
+file4=C:\mysql\scripts\mysql_config
+file5=C:\mysql\scripts\mysql_config.sh
+file6=C:\mysql\scripts\mysql_convert_table_format
+file7=C:\mysql\scripts\mysql_convert_table_format.sh
+file40=C:\mysql\scripts\mysqlhotcopy
+file8=C:\mysql\scripts\mysql_explain_log
+file41=C:\mysql\scripts\mysqlhotcopy.pl
+file30=C:\mysql\scripts\mysqlaccess.sh
+file9=C:\mysql\scripts\mysql_explain_log.sh
+file42=C:\mysql\scripts\mysqlhotcopy.sh
+file31=C:\mysql\scripts\mysqlbug
+file20=C:\mysql\scripts\mysql_secure_installation.sh
+file43=C:\mysql\scripts\make_binary_distribution
+file32=C:\mysql\scripts\mysqlbug.sh
+file21=C:\mysql\scripts\mysql_setpermission
+file10=C:\mysql\scripts\mysql_find_rows
+fulldirectory=
+file33=C:\mysql\scripts\mysqld_multi
+file22=C:\mysql\scripts\mysql_setpermission.pl
+file11=C:\mysql\scripts\mysql_find_rows.pl
+file34=C:\mysql\scripts\mysqld_multi.sh
+file23=C:\mysql\scripts\mysql_setpermission.sh
+file12=C:\mysql\scripts\mysql_find_rows.sh
+file35=C:\mysql\scripts\mysqld_safe
+file24=C:\mysql\scripts\mysql_tableinfo
+file13=C:\mysql\scripts\mysql_fix_extensions
+file36=C:\mysql\scripts\mysqld_safe.sh
+file25=C:\mysql\scripts\mysql_tableinfo.sh
+file14=C:\mysql\scripts\mysql_fix_extensions.sh
+
+[lib]
+file0=C:\mysql\lib\Readme
+SubDir0=lib\debug
+SubDir1=lib\opt
+fulldirectory=
+
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Documentation.fgl b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Documentation.fgl
new file mode 100755
index 00000000000..107ebd1afb7
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Documentation.fgl
@@ -0,0 +1,101 @@
+[Docs\Flags]
+file59=C:\mysql\Docs\Flags\romania.gif
+file48=C:\mysql\Docs\Flags\kroatia.eps
+file37=C:\mysql\Docs\Flags\iceland.gif
+file26=C:\mysql\Docs\Flags\france.eps
+file15=C:\mysql\Docs\Flags\china.gif
+file49=C:\mysql\Docs\Flags\kroatia.gif
+file38=C:\mysql\Docs\Flags\ireland.eps
+file27=C:\mysql\Docs\Flags\france.gif
+file16=C:\mysql\Docs\Flags\croatia.eps
+file0=C:\mysql\Docs\Flags\usa.gif
+file39=C:\mysql\Docs\Flags\ireland.gif
+file28=C:\mysql\Docs\Flags\germany.eps
+file17=C:\mysql\Docs\Flags\croatia.gif
+file1=C:\mysql\Docs\Flags\argentina.gif
+file29=C:\mysql\Docs\Flags\germany.gif
+file18=C:\mysql\Docs\Flags\czech-republic.eps
+file2=C:\mysql\Docs\Flags\australia.eps
+file19=C:\mysql\Docs\Flags\czech-republic.gif
+file3=C:\mysql\Docs\Flags\australia.gif
+file80=C:\mysql\Docs\Flags\usa.eps
+file4=C:\mysql\Docs\Flags\austria.eps
+file81=C:\mysql\Docs\Flags\argentina.eps
+file70=C:\mysql\Docs\Flags\spain.eps
+file5=C:\mysql\Docs\Flags\austria.gif
+file71=C:\mysql\Docs\Flags\spain.gif
+file60=C:\mysql\Docs\Flags\russia.eps
+file6=C:\mysql\Docs\Flags\brazil.eps
+file72=C:\mysql\Docs\Flags\sweden.eps
+file61=C:\mysql\Docs\Flags\russia.gif
+file50=C:\mysql\Docs\Flags\latvia.eps
+file7=C:\mysql\Docs\Flags\brazil.gif
+file73=C:\mysql\Docs\Flags\sweden.gif
+file62=C:\mysql\Docs\Flags\singapore.eps
+file51=C:\mysql\Docs\Flags\latvia.gif
+file40=C:\mysql\Docs\Flags\island.eps
+file8=C:\mysql\Docs\Flags\bulgaria.eps
+file74=C:\mysql\Docs\Flags\switzerland.eps
+file63=C:\mysql\Docs\Flags\singapore.gif
+file52=C:\mysql\Docs\Flags\netherlands.eps
+file41=C:\mysql\Docs\Flags\island.gif
+file30=C:\mysql\Docs\Flags\great-britain.eps
+file9=C:\mysql\Docs\Flags\bulgaria.gif
+file75=C:\mysql\Docs\Flags\switzerland.gif
+file64=C:\mysql\Docs\Flags\south-africa.eps
+file53=C:\mysql\Docs\Flags\netherlands.gif
+file42=C:\mysql\Docs\Flags\israel.eps
+file31=C:\mysql\Docs\Flags\great-britain.gif
+file20=C:\mysql\Docs\Flags\denmark.eps
+file76=C:\mysql\Docs\Flags\taiwan.eps
+file65=C:\mysql\Docs\Flags\south-africa.gif
+file54=C:\mysql\Docs\Flags\poland.eps
+file43=C:\mysql\Docs\Flags\israel.gif
+file32=C:\mysql\Docs\Flags\greece.eps
+file21=C:\mysql\Docs\Flags\denmark.gif
+file10=C:\mysql\Docs\Flags\canada.eps
+fulldirectory=
+file77=C:\mysql\Docs\Flags\taiwan.gif
+file66=C:\mysql\Docs\Flags\south-africa1.eps
+file55=C:\mysql\Docs\Flags\poland.gif
+file44=C:\mysql\Docs\Flags\italy.eps
+file33=C:\mysql\Docs\Flags\greece.gif
+file22=C:\mysql\Docs\Flags\estonia.eps
+file11=C:\mysql\Docs\Flags\canada.gif
+file78=C:\mysql\Docs\Flags\ukraine.eps
+file67=C:\mysql\Docs\Flags\south-africa1.gif
+file56=C:\mysql\Docs\Flags\portugal.eps
+file45=C:\mysql\Docs\Flags\italy.gif
+file34=C:\mysql\Docs\Flags\hungary.eps
+file23=C:\mysql\Docs\Flags\estonia.gif
+file12=C:\mysql\Docs\Flags\chile.eps
+file79=C:\mysql\Docs\Flags\ukraine.gif
+file68=C:\mysql\Docs\Flags\south-korea.eps
+file57=C:\mysql\Docs\Flags\portugal.gif
+file46=C:\mysql\Docs\Flags\japan.eps
+file35=C:\mysql\Docs\Flags\hungary.gif
+file24=C:\mysql\Docs\Flags\finland.eps
+file13=C:\mysql\Docs\Flags\chile.gif
+file69=C:\mysql\Docs\Flags\south-korea.gif
+file58=C:\mysql\Docs\Flags\romania.eps
+file47=C:\mysql\Docs\Flags\japan.gif
+file36=C:\mysql\Docs\Flags\iceland.eps
+file25=C:\mysql\Docs\Flags\finland.gif
+file14=C:\mysql\Docs\Flags\china.eps
+
+[Docs]
+file0=C:\mysql\Docs\manual_toc.html
+file1=C:\mysql\Docs\Copying
+file2=C:\mysql\Docs\Copying.lib
+file3=C:\mysql\Docs\manual.html
+file4=C:\mysql\Docs\manual.txt
+SubDir0=Docs\Flags
+fulldirectory=
+
+[TopDir]
+SubDir0=Docs
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Grant Tables.fgl b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Grant Tables.fgl
index 178065a7003..178065a7003 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Grant Tables.fgl
+++ b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Grant Tables.fgl
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Servers.fgl b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Servers.fgl
new file mode 100755
index 00000000000..64883f7f369
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/File Groups/Servers.fgl
@@ -0,0 +1,229 @@
+[Embedded\Static\release]
+file0=C:\mysql\embedded\Static\release\test_stc.dsp
+file1=C:\mysql\embedded\Static\release\ReadMe.txt
+file2=C:\mysql\embedded\Static\release\StdAfx.cpp
+file3=C:\mysql\embedded\Static\release\StdAfx.h
+file4=C:\mysql\embedded\Static\release\test_stc.cpp
+file5=C:\mysql\embedded\Static\release\mysqlserver.lib
+fulldirectory=
+
+[share\polish]
+file0=C:\mysql\share\polish\errmsg.sys
+file1=C:\mysql\share\polish\errmsg.txt
+fulldirectory=
+
+[share\dutch]
+file0=C:\mysql\share\dutch\errmsg.sys
+file1=C:\mysql\share\dutch\errmsg.txt
+fulldirectory=
+
+[share\spanish]
+file0=C:\mysql\share\spanish\errmsg.sys
+file1=C:\mysql\share\spanish\errmsg.txt
+fulldirectory=
+
+[share\english]
+file0=C:\mysql\share\english\errmsg.sys
+file1=C:\mysql\share\english\errmsg.txt
+fulldirectory=
+
+[bin]
+file0=C:\mysql\bin\mysqld-opt.exe
+file1=C:\mysql\bin\mysqld-max.exe
+file2=C:\mysql\bin\mysqld-max-nt.exe
+file3=C:\mysql\bin\mysqld-nt.exe
+file4=C:\mysql\bin\mysqld.exe
+file5=C:\mysql\bin\cygwinb19.dll
+file6=C:\mysql\bin\libmySQL.dll
+fulldirectory=
+
+[share\korean]
+file0=C:\mysql\share\korean\errmsg.sys
+file1=C:\mysql\share\korean\errmsg.txt
+fulldirectory=
+
+[share\charsets]
+file15=C:\mysql\share\charsets\latin1.conf
+file16=C:\mysql\share\charsets\latin2.conf
+file0=C:\mysql\share\charsets\win1251ukr.conf
+file17=C:\mysql\share\charsets\latin5.conf
+file1=C:\mysql\share\charsets\cp1257.conf
+file18=C:\mysql\share\charsets\Readme
+file2=C:\mysql\share\charsets\croat.conf
+file19=C:\mysql\share\charsets\swe7.conf
+file3=C:\mysql\share\charsets\danish.conf
+file4=C:\mysql\share\charsets\dec8.conf
+file5=C:\mysql\share\charsets\dos.conf
+file6=C:\mysql\share\charsets\estonia.conf
+file7=C:\mysql\share\charsets\german1.conf
+file8=C:\mysql\share\charsets\greek.conf
+file9=C:\mysql\share\charsets\hebrew.conf
+file20=C:\mysql\share\charsets\usa7.conf
+file21=C:\mysql\share\charsets\win1250.conf
+file10=C:\mysql\share\charsets\hp8.conf
+fulldirectory=
+file22=C:\mysql\share\charsets\win1251.conf
+file11=C:\mysql\share\charsets\hungarian.conf
+file23=C:\mysql\share\charsets\cp1251.conf
+file12=C:\mysql\share\charsets\Index
+file13=C:\mysql\share\charsets\koi8_ru.conf
+file14=C:\mysql\share\charsets\koi8_ukr.conf
+
+[Embedded\DLL\debug]
+file0=C:\mysql\embedded\DLL\debug\libmysqld.dll
+file1=C:\mysql\embedded\DLL\debug\libmysqld.exp
+file2=C:\mysql\embedded\DLL\debug\libmysqld.lib
+fulldirectory=
+
+[Embedded]
+file0=C:\mysql\embedded\embedded.dsw
+SubDir0=Embedded\DLL
+SubDir1=Embedded\Static
+fulldirectory=
+
+[share\ukrainian]
+file0=C:\mysql\share\ukrainian\errmsg.sys
+file1=C:\mysql\share\ukrainian\errmsg.txt
+fulldirectory=
+
+[share\hungarian]
+file0=C:\mysql\share\hungarian\errmsg.sys
+file1=C:\mysql\share\hungarian\errmsg.txt
+fulldirectory=
+
+[share\german]
+file0=C:\mysql\share\german\errmsg.sys
+file1=C:\mysql\share\german\errmsg.txt
+fulldirectory=
+
+[share\portuguese]
+file0=C:\mysql\share\portuguese\errmsg.sys
+file1=C:\mysql\share\portuguese\errmsg.txt
+fulldirectory=
+
+[share\estonian]
+file0=C:\mysql\share\estonian\errmsg.sys
+file1=C:\mysql\share\estonian\errmsg.txt
+fulldirectory=
+
+[share\romanian]
+file0=C:\mysql\share\romanian\errmsg.sys
+file1=C:\mysql\share\romanian\errmsg.txt
+fulldirectory=
+
+[share\french]
+file0=C:\mysql\share\french\errmsg.sys
+file1=C:\mysql\share\french\errmsg.txt
+fulldirectory=
+
+[share\swedish]
+file0=C:\mysql\share\swedish\errmsg.sys
+file1=C:\mysql\share\swedish\errmsg.txt
+fulldirectory=
+
+[share\slovak]
+file0=C:\mysql\share\slovak\errmsg.sys
+file1=C:\mysql\share\slovak\errmsg.txt
+fulldirectory=
+
+[share\greek]
+file0=C:\mysql\share\greek\errmsg.sys
+file1=C:\mysql\share\greek\errmsg.txt
+fulldirectory=
+
+[TopDir]
+file0=C:\mysql\Readme
+file1=C:\mysql\mysqlbug.txt
+file2=C:\mysql\my-huge.cnf
+file3=C:\mysql\my-large.cnf
+file4=C:\mysql\my-medium.cnf
+file5=C:\mysql\my-small.cnf
+SubDir0=bin
+SubDir1=share
+SubDir2=Embedded
+
+[share]
+SubDir8=share\hungarian
+SubDir9=share\charsets
+SubDir20=share\spanish
+SubDir21=share\swedish
+SubDir10=share\italian
+SubDir22=share\ukrainian
+SubDir11=share\japanese
+SubDir12=share\korean
+SubDir13=share\norwegian
+SubDir14=share\norwegian-ny
+SubDir15=share\polish
+SubDir16=share\portuguese
+SubDir0=share\czech
+SubDir17=share\romanian
+SubDir1=share\danish
+SubDir18=share\russian
+SubDir2=share\dutch
+SubDir19=share\slovak
+SubDir3=share\english
+fulldirectory=
+SubDir4=share\estonian
+SubDir5=share\french
+SubDir6=share\german
+SubDir7=share\greek
+
+[share\norwegian-ny]
+file0=C:\mysql\share\norwegian-ny\errmsg.sys
+file1=C:\mysql\share\norwegian-ny\errmsg.txt
+fulldirectory=
+
+[Embedded\DLL]
+file0=C:\mysql\embedded\DLL\test_dll.dsp
+file1=C:\mysql\embedded\DLL\StdAfx.h
+file2=C:\mysql\embedded\DLL\test_dll.cpp
+file3=C:\mysql\embedded\DLL\StdAfx.cpp
+SubDir0=Embedded\DLL\debug
+SubDir1=Embedded\DLL\release
+fulldirectory=
+
+[Embedded\Static]
+SubDir0=Embedded\Static\release
+fulldirectory=
+
+[Embedded\DLL\release]
+file0=C:\mysql\embedded\DLL\release\libmysqld.dll
+file1=C:\mysql\embedded\DLL\release\libmysqld.exp
+file2=C:\mysql\embedded\DLL\release\libmysqld.lib
+file3=C:\mysql\embedded\DLL\release\mysql-server.exe
+fulldirectory=
+
+[share\danish]
+file0=C:\mysql\share\danish\errmsg.sys
+file1=C:\mysql\share\danish\errmsg.txt
+fulldirectory=
+
+[share\czech]
+file0=C:\mysql\share\czech\errmsg.sys
+file1=C:\mysql\share\czech\errmsg.txt
+fulldirectory=
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
+[share\russian]
+file0=C:\mysql\share\russian\errmsg.sys
+file1=C:\mysql\share\russian\errmsg.txt
+fulldirectory=
+
+[share\norwegian]
+file0=C:\mysql\share\norwegian\errmsg.sys
+file1=C:\mysql\share\norwegian\errmsg.txt
+fulldirectory=
+
+[share\japanese]
+file0=C:\mysql\share\japanese\errmsg.sys
+file1=C:\mysql\share\japanese\errmsg.txt
+fulldirectory=
+
+[share\italian]
+file0=C:\mysql\share\italian\errmsg.sys
+file1=C:\mysql\share\italian\errmsg.txt
+fulldirectory=
+
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Registry Entries/Default.rge b/VC++Files/InstallShield/4.0.XX-gpl/Registry Entries/Default.rge
index 537dfd82e48..537dfd82e48 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Registry Entries/Default.rge
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Registry Entries/Default.rge
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.dbg b/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.dbg
index 0c6d4e6b708..0c6d4e6b708 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.dbg
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.dbg
Binary files differ
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ino b/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.ino
index 204d8ea0f36..204d8ea0f36 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ino
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.ino
Binary files differ
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ins b/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.ins
index 759009b5c84..759009b5c84 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ins
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.ins
Binary files differ
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.obs b/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.obs
index 5fcfcb62c4e..5fcfcb62c4e 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.obs
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.obs
Binary files differ
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.rul b/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.rul
new file mode 100755
index 00000000000..df143b493c4
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Script Files/Setup.rul
@@ -0,0 +1,640 @@
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// IIIIIII SSSSSS
+// II SS InstallShield (R)
+// II SSSSSS (c) 1996-1997, InstallShield Software Corporation
+// II SS (c) 1990-1996, InstallShield Corporation
+// IIIIIII SSSSSS All Rights Reserved.
+//
+//
+// This code is generated as a starting setup template. You should
+// modify it to provide all necessary steps for your setup.
+//
+//
+// File Name: Setup.rul
+//
+// Description: InstallShield script
+//
+// Comments: This template script performs a basic setup on a
+// Windows 95 or Windows NT 4.0 platform. With minor
+// modifications, this template can be adapted to create
+// new, customized setups.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+ // Include header file
+#include "sdlang.h"
+#include "sddialog.h"
+
+////////////////////// string defines ////////////////////////////
+
+#define UNINST_LOGFILE_NAME "Uninst.isu"
+
+//////////////////// installation declarations ///////////////////
+
+ // ----- DLL prototypes -----
+
+
+ // your DLL prototypes
+
+
+ // ---- script prototypes -----
+
+ // generated
+ prototype ShowDialogs();
+ prototype MoveFileData();
+ prototype HandleMoveDataError( NUMBER );
+ prototype ProcessBeforeDataMove();
+ prototype ProcessAfterDataMove();
+ prototype SetupRegistry();
+ prototype SetupFolders();
+ prototype CleanUpInstall();
+ prototype SetupInstall();
+ prototype SetupScreen();
+ prototype CheckRequirements();
+ prototype DialogShowSdWelcome();
+ prototype DialogShowSdShowInfoList();
+ prototype DialogShowSdAskDestPath();
+ prototype DialogShowSdSetupType();
+ prototype DialogShowSdComponentDialog2();
+ prototype DialogShowSdFinishReboot();
+
+ // your prototypes
+
+
+ // ----- global variables ------
+
+ // generated
+ BOOL bWinNT, bIsShellExplorer, bInstallAborted, bIs32BitSetup;
+ STRING svDir;
+ STRING svName, svCompany, svSerial;
+ STRING szAppPath;
+ STRING svSetupType;
+
+
+ // your global variables
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// MAIN PROGRAM
+//
+// The setup begins here by hiding the visible setup
+// window. This is done to allow all the titles, images, etc. to
+// be established before showing the main window. The following
+// logic then performs the setup in a series of steps.
+//
+///////////////////////////////////////////////////////////////////////////////
+program
+ Disable( BACKGROUND );
+
+ CheckRequirements();
+
+ SetupInstall();
+
+ SetupScreen();
+
+ if (ShowDialogs()<0) goto end_install;
+
+ if (ProcessBeforeDataMove()<0) goto end_install;
+
+ if (MoveFileData()<0) goto end_install;
+
+ if (ProcessAfterDataMove()<0) goto end_install;
+
+ if (SetupRegistry()<0) goto end_install;
+
+ if (SetupFolders()<0) goto end_install;
+
+
+ end_install:
+
+ CleanUpInstall();
+
+ // If an unrecoverable error occurred, clean up the partial installation.
+ // Otherwise, exit normally.
+
+ if (bInstallAborted) then
+ abort;
+ endif;
+
+endprogram
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ShowDialogs //
+// //
+// Purpose: This function manages the display and navigation //
+// the standard dialogs that exist in a setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ShowDialogs()
+ NUMBER nResult;
+ begin
+
+ Dlg_Start:
+ // beginning of dialogs label
+
+ Dlg_SdWelcome:
+ nResult = DialogShowSdWelcome();
+ if (nResult = BACK) goto Dlg_Start;
+
+ Dlg_SdShowInfoList:
+ nResult = DialogShowSdShowInfoList();
+ if (nResult = BACK) goto Dlg_SdWelcome;
+
+ Dlg_SdAskDestPath:
+ nResult = DialogShowSdAskDestPath();
+ if (nResult = BACK) goto Dlg_SdShowInfoList;
+
+ Dlg_SdSetupType:
+ nResult = DialogShowSdSetupType();
+ if (nResult = BACK) goto Dlg_SdAskDestPath;
+
+ Dlg_SdComponentDialog2:
+ if ((nResult = BACK) && (svSetupType != "Custom") && (svSetupType != "")) then
+ goto Dlg_SdSetupType;
+ endif;
+ nResult = DialogShowSdComponentDialog2();
+ if (nResult = BACK) goto Dlg_SdSetupType;
+
+ return 0;
+
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ProcessBeforeDataMove //
+// //
+// Purpose: This function performs any necessary operations prior to the //
+// actual data move operation. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ProcessBeforeDataMove()
+ STRING svLogFile;
+ NUMBER nResult;
+ begin
+
+ InstallationInfo( @COMPANY_NAME, @PRODUCT_NAME, @PRODUCT_VERSION, @PRODUCT_KEY );
+
+ svLogFile = UNINST_LOGFILE_NAME;
+
+ nResult = DeinstallStart( svDir, svLogFile, @UNINST_KEY, 0 );
+ if (nResult < 0) then
+ MessageBox( @ERROR_UNINSTSETUP, WARNING );
+ endif;
+
+ szAppPath = TARGETDIR; // TODO : if your application .exe is in a subdir of TARGETDIR then add subdir
+
+ if ((bIs32BitSetup) && (bIsShellExplorer)) then
+ RegDBSetItem( REGDB_APPPATH, szAppPath );
+ RegDBSetItem( REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY );
+ RegDBSetItem( REGDB_UNINSTALL_NAME, @UNINST_DISPLAY_NAME );
+ endif;
+
+ // TODO : update any items you want to process before moving the data
+ //
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: MoveFileData //
+// //
+// Purpose: This function handles the data movement for //
+// the setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function MoveFileData()
+ NUMBER nResult, nDisk;
+ begin
+
+ nDisk = 1;
+ SetStatusWindow( 0, "" );
+ Disable( DIALOGCACHE );
+ Enable( STATUS );
+ StatusUpdate( ON, 100 );
+ nResult = ComponentMoveData( MEDIA, nDisk, 0 );
+
+ HandleMoveDataError( nResult );
+
+ Disable( STATUS );
+
+ return nResult;
+
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: HandleMoveDataError //
+// //
+// Purpose: This function handles the error (if any) during the move data //
+// operation. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function HandleMoveDataError( nResult )
+ STRING szErrMsg, svComponent , svFileGroup , svFile;
+ begin
+
+ svComponent = "";
+ svFileGroup = "";
+ svFile = "";
+
+ switch (nResult)
+ case 0:
+ return 0;
+ default:
+ ComponentError ( MEDIA , svComponent , svFileGroup , svFile , nResult );
+ szErrMsg = @ERROR_MOVEDATA + "\n\n" +
+ @ERROR_COMPONENT + " " + svComponent + "\n" +
+ @ERROR_FILEGROUP + " " + svFileGroup + "\n" +
+ @ERROR_FILE + " " + svFile;
+ SprintfBox( SEVERE, @TITLE_CAPTIONBAR, szErrMsg, nResult );
+ bInstallAborted = TRUE;
+ return nResult;
+ endswitch;
+
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ProcessAfterDataMove //
+// //
+// Purpose: This function performs any necessary operations needed after //
+// all data has been moved. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ProcessAfterDataMove()
+ begin
+
+ // TODO : update self-registered files and other processes that
+ // should be performed after the data has been moved.
+
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupRegistry //
+// //
+// Purpose: This function makes the registry entries for this setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupRegistry()
+ NUMBER nResult;
+
+ begin
+
+ // TODO : Add all your registry entry keys here
+ //
+ //
+ // RegDBCreateKeyEx, RegDBSetKeyValueEx....
+ //
+
+ nResult = CreateRegistrySet( "" );
+
+ return nResult;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Function: SetupFolders
+//
+// Purpose: This function creates all the folders and shortcuts for the
+// setup. This includes program groups and items for Windows 3.1.
+//
+///////////////////////////////////////////////////////////////////////////////
+function SetupFolders()
+ NUMBER nResult;
+
+ begin
+
+
+ // TODO : Add all your folder (program group) along with shortcuts (program items)
+ //
+ //
+ // CreateProgramFolder, AddFolderIcon....
+ //
+
+ nResult = CreateShellObjects( "" );
+
+ return nResult;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: CleanUpInstall //
+// //
+// Purpose: This cleans up the setup. Anything that should //
+// be released or deleted at the end of the setup should //
+// be done here. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function CleanUpInstall()
+ begin
+
+
+ if (bInstallAborted) then
+ return 0;
+ endif;
+
+ DialogShowSdFinishReboot();
+
+ if (BATCH_INSTALL) then // ensure locked files are properly written
+ CommitSharedFiles(0);
+ endif;
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupInstall //
+// //
+// Purpose: This will setup the installation. Any general initialization //
+// needed for the installation should be performed here. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupInstall()
+ begin
+
+ Enable( CORECOMPONENTHANDLING );
+
+ bInstallAborted = FALSE;
+
+ if (bIs32BitSetup) then
+ svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME ^ @PRODUCT_NAME;
+ else
+ svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME16 ^ @PRODUCT_NAME16; // use shorten names
+ endif;
+
+ TARGETDIR = svDir;
+
+ SdProductName( @PRODUCT_NAME );
+
+ Enable( DIALOGCACHE );
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupScreen //
+// //
+// Purpose: This function establishes the screen look. This includes //
+// colors, fonts, and text to be displayed. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupScreen()
+ begin
+
+ Enable( FULLWINDOWMODE );
+ Enable( INDVFILESTATUS );
+ SetTitle( @TITLE_MAIN, 24, WHITE );
+
+ SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text.
+
+ Enable( BACKGROUND );
+
+ Delay( 1 );
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: CheckRequirements //
+// //
+// Purpose: This function checks all minimum requirements for the //
+// application being installed. If any fail, then the user //
+// is informed and the setup is terminated. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function CheckRequirements()
+ NUMBER nvDx, nvDy, nvResult;
+ STRING svResult;
+
+ begin
+
+ bWinNT = FALSE;
+ bIsShellExplorer = FALSE;
+
+ // Check screen resolution.
+ GetExtents( nvDx, nvDy );
+
+ if (nvDy < 480) then
+ MessageBox( @ERROR_VGARESOLUTION, WARNING );
+ abort;
+ endif;
+
+ // set 'setup' operation mode
+ bIs32BitSetup = TRUE;
+ GetSystemInfo( ISTYPE, nvResult, svResult );
+ if (nvResult = 16) then
+ bIs32BitSetup = FALSE; // running 16-bit setup
+ return 0; // no additional information required
+ endif;
+
+ // --- 32-bit testing after this point ---
+
+ // Determine the target system's operating system.
+ GetSystemInfo( OS, nvResult, svResult );
+
+ if (nvResult = IS_WINDOWSNT) then
+ // Running Windows NT.
+ bWinNT = TRUE;
+
+ // Check to see if the shell being used is EXPLORER shell.
+ if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then
+ if (nvResult >= 4) then
+ bIsShellExplorer = TRUE;
+ endif;
+ endif;
+
+ elseif (nvResult = IS_WINDOWS95 ) then
+ bIsShellExplorer = TRUE;
+
+ endif;
+
+end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdWelcome //
+// //
+// Purpose: This function handles the standard welcome dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdWelcome()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdWelcome( szTitle, szMsg );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdShowInfoList //
+// //
+// Purpose: This function displays the general information list dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdShowInfoList()
+ NUMBER nResult;
+ LIST list;
+ STRING szTitle, szMsg, szFile;
+ begin
+
+ szFile = SUPPORTDIR ^ "infolist.txt";
+
+ list = ListCreate( STRINGLIST );
+ ListReadFromFile( list, szFile );
+ szTitle = "";
+ szMsg = " ";
+ nResult = SdShowInfoList( szTitle, szMsg, list );
+
+ ListDestroy( list );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdAskDestPath //
+// //
+// Purpose: This function asks the user for the destination directory. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdAskDestPath()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdAskDestPath( szTitle, szMsg, svDir, 0 );
+
+ TARGETDIR = svDir;
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdSetupType //
+// //
+// Purpose: This function displays the standard setup type dialog. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdSetupType()
+ NUMBER nResult, nType;
+ STRING szTitle, szMsg;
+ begin
+
+ switch (svSetupType)
+ case "Typical":
+ nType = TYPICAL;
+ case "Custom":
+ nType = CUSTOM;
+ case "Compact":
+ nType = COMPACT;
+ case "":
+ svSetupType = "Typical";
+ nType = TYPICAL;
+ endswitch;
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SetupType( szTitle, szMsg, "", nType, 0 );
+
+ switch (nResult)
+ case COMPACT:
+ svSetupType = "Compact";
+ case TYPICAL:
+ svSetupType = "Typical";
+ case CUSTOM:
+ svSetupType = "Custom";
+ endswitch;
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdComponentDialog2 //
+// //
+// Purpose: This function displays the custom component dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdComponentDialog2()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ if ((svSetupType != "Custom") && (svSetupType != "")) then
+ return 0;
+ endif;
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdComponentDialog2( szTitle, szMsg, svDir, "" );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdFinishReboot //
+// //
+// Purpose: This function will show the last dialog of the product. //
+// It will allow the user to reboot and/or show some readme text. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdFinishReboot()
+ NUMBER nResult, nDefOptions;
+ STRING szTitle, szMsg1, szMsg2, szOption1, szOption2;
+ NUMBER bOpt1, bOpt2;
+ begin
+
+ if (!BATCH_INSTALL) then
+ bOpt1 = FALSE;
+ bOpt2 = FALSE;
+ szMsg1 = "";
+ szMsg2 = "";
+ szOption1 = "";
+ szOption2 = "";
+ nResult = SdFinish( szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2 );
+ return 0;
+ endif;
+
+ nDefOptions = SYS_BOOTMACHINE;
+ szTitle = "";
+ szMsg1 = "";
+ szMsg2 = "";
+ nResult = SdFinishReboot( szTitle, szMsg1, nDefOptions, szMsg2, 0 );
+
+ return nResult;
+ end;
+
+ // --- include script file section ---
+
+#include "sddialog.rul"
+
+
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt b/VC++Files/InstallShield/4.0.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt
new file mode 100755
index 00000000000..acdf4f48618
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt
@@ -0,0 +1,25 @@
+This is a release of MySQL @VERSION@ for Win32.
+
+NOTE: If you install MySQL in a folder other than
+C:\MYSQL or you intend to start MySQL on NT/Win2000
+as a service, you must create a file named C:\MY.CNF
+or \Windows\my.ini or \winnt\my.ini with the following
+information::
+
+[mysqld]
+basedir=E:/installation-path/
+datadir=E:/data-path/
+
+After your have installed MySQL, the installation
+directory will contain 4 files named 'my-small.cnf,
+my-medium.cnf, my-large.cnf, my-huge.cnf'.
+You can use this as a starting point for your own
+C:\my.cnf file.
+
+If you have any problems, you can mail them to
+win32@lists.mysql.com after you have consulted the
+MySQL manual and the MySQL mailing list archive
+(http://www.mysql.com/documentation/index.html)
+
+On behalf of the MySQL AB gang,
+Michael Widenius
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP b/VC++Files/InstallShield/4.0.XX-gpl/Setup Files/Uncompressed Files/Language Independent/OS Independent/setup.bmp
index 3229d50c9bf..3229d50c9bf 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Setup Files/Uncompressed Files/Language Independent/OS Independent/setup.bmp
Binary files differ
diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Shell Objects/Default.shl b/VC++Files/InstallShield/4.0.XX-gpl/Shell Objects/Default.shl
index 187cb651307..187cb651307 100644..100755
--- a/VC++Files/InstallShield/3.23.XX-gpl/Shell Objects/Default.shl
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Shell Objects/Default.shl
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/String Tables/0009-English/value.shl b/VC++Files/InstallShield/4.0.XX-gpl/String Tables/0009-English/value.shl
new file mode 100755
index 00000000000..35e7c278cc9
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/String Tables/0009-English/value.shl
@@ -0,0 +1,23 @@
+[Data]
+TITLE_MAIN=MySQL Servers and Clients @VERSION@
+COMPANY_NAME=MySQL AB
+ERROR_COMPONENT=Component:
+COMPANY_NAME16=Company
+PRODUCT_VERSION=MySQL Servers and Clients @VERSION@
+ERROR_MOVEDATA=An error occurred during the move data process: %d
+ERROR_FILEGROUP=File Group:
+UNINST_KEY=MySQL Servers and Clients @VERSION@
+TITLE_CAPTIONBAR=MySQL Servers and Clients @VERSION@
+PRODUCT_NAME16=Product
+ERROR_VGARESOLUTION=This program requires VGA or better resolution.
+ERROR_FILE=File:
+UNINST_DISPLAY_NAME=MySQL Servers and Clients @VERSION@
+PRODUCT_KEY=yourapp.Exe
+PRODUCT_NAME=MySQL Servers and Clients @VERSION@
+ERROR_UNINSTSETUP=unInstaller setup failed to initialize. You may not be able to uninstall this product.
+
+[General]
+Language=0009
+Type=STRINGTABLESPECIFIC
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/String Tables/Default.shl b/VC++Files/InstallShield/4.0.XX-gpl/String Tables/Default.shl
new file mode 100755
index 00000000000..d4dc4925ab1
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/String Tables/Default.shl
@@ -0,0 +1,74 @@
+[TITLE_MAIN]
+Comment=
+
+[COMPANY_NAME]
+Comment=
+
+[ERROR_COMPONENT]
+Comment=
+
+[COMPANY_NAME16]
+Comment=
+
+[PRODUCT_VERSION]
+Comment=
+
+[ERROR_MOVEDATA]
+Comment=
+
+[ERROR_FILEGROUP]
+Comment=
+
+[Language]
+Lang0=0009
+CurrentLang=0
+
+[UNINST_KEY]
+Comment=
+
+[TITLE_CAPTIONBAR]
+Comment=
+
+[Data]
+Entry0=ERROR_VGARESOLUTION
+Entry1=TITLE_MAIN
+Entry2=TITLE_CAPTIONBAR
+Entry3=UNINST_KEY
+Entry4=UNINST_DISPLAY_NAME
+Entry5=COMPANY_NAME
+Entry6=PRODUCT_NAME
+Entry7=PRODUCT_VERSION
+Entry8=PRODUCT_KEY
+Entry9=ERROR_MOVEDATA
+Entry10=ERROR_UNINSTSETUP
+Entry11=COMPANY_NAME16
+Entry12=PRODUCT_NAME16
+Entry13=ERROR_COMPONENT
+Entry14=ERROR_FILEGROUP
+Entry15=ERROR_FILE
+
+[PRODUCT_NAME16]
+Comment=
+
+[ERROR_VGARESOLUTION]
+Comment=
+
+[ERROR_FILE]
+Comment=
+
+[General]
+Type=STRINGTABLE
+Version=1.00.000
+
+[UNINST_DISPLAY_NAME]
+Comment=
+
+[PRODUCT_KEY]
+Comment=
+
+[PRODUCT_NAME]
+Comment=
+
+[ERROR_UNINSTSETUP]
+Comment=
+
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/Text Substitutions/Build.tsb b/VC++Files/InstallShield/4.0.XX-gpl/Text Substitutions/Build.tsb
new file mode 100755
index 00000000000..3949bd4c066
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Text Substitutions/Build.tsb
@@ -0,0 +1,56 @@
+[<HKUS>]
+Value=
+KeyType=4
+
+[<HKCR>]
+Value=
+KeyType=4
+
+[<PROGRAMFILES>]
+Value=
+KeyType=4
+
+[<WINSYSDIR>]
+Value=
+KeyType=4
+
+[<COMMONFILES>]
+Value=
+KeyType=4
+
+[<WINDIR>]
+Value=
+KeyType=4
+
+[Data]
+Key0=<PROGRAMFILES>
+Key1=<COMMONFILES>
+Key2=<WINDIR>
+Key3=<WINSYSDIR>
+Key4=<HKLM>
+Key5=<HKCU>
+Key6=<HKCC>
+Key7=<HKDD>
+Key8=<HKUS>
+Key9=<HKCR>
+
+[General]
+Type=TEXTSUB
+Version=1.00.000
+
+[<HKLM>]
+Value=
+KeyType=4
+
+[<HKCU>]
+Value=
+KeyType=4
+
+[<HKCC>]
+Value=
+KeyType=4
+
+[<HKDD>]
+Value=
+KeyType=4
+
diff --git a/VC++Files/InstallShield/4.0.XX-gpl/Text Substitutions/Setup.tsb b/VC++Files/InstallShield/4.0.XX-gpl/Text Substitutions/Setup.tsb
new file mode 100755
index 00000000000..b0c5a509f0b
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-gpl/Text Substitutions/Setup.tsb
@@ -0,0 +1,76 @@
+[<SRCDIR>]
+Value=
+KeyType=4
+
+[<HKUS>]
+Value=
+KeyType=4
+
+[<HKCR>]
+Value=
+KeyType=4
+
+[<PROGRAMFILES>]
+Value=
+KeyType=4
+
+[<TARGETDIR>]
+Value=
+KeyType=4
+
+[<WINSYSDIR>]
+Value=
+KeyType=4
+
+[<COMMONFILES>]
+Value=
+KeyType=4
+
+[<WINDIR>]
+Value=
+KeyType=4
+
+[Data]
+Key0=<PROGRAMFILES>
+Key1=<COMMONFILES>
+Key2=<WINDIR>
+Key3=<WINSYSDIR>
+Key4=<TARGETDIR>
+Key5=<SUPPORTDIR>
+Key10=<HKDD>
+Key6=<SRCDIR>
+Key11=<HKUS>
+Key7=<HKLM>
+Key12=<HKCR>
+Key8=<HKCU>
+Key13=<SHELL_OBJECT_FOLDER>
+Key9=<HKCC>
+
+[<SUPPORTDIR>]
+Value=
+KeyType=4
+
+[<SHELL_OBJECT_FOLDER>]
+Value=
+KeyType=4
+
+[General]
+Type=TEXTSUB
+Version=1.00.000
+
+[<HKLM>]
+Value=
+KeyType=4
+
+[<HKCU>]
+Value=
+KeyType=4
+
+[<HKCC>]
+Value=
+KeyType=4
+
+[<HKDD>]
+Value=
+KeyType=4
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/4.0.XX-pro.ipr b/VC++Files/InstallShield/4.0.XX-pro/4.0.XX-pro.ipr
new file mode 100755
index 00000000000..bfa7a082873
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/4.0.XX-pro.ipr
@@ -0,0 +1,52 @@
+[Language]
+LanguageSupport0=0009
+
+[OperatingSystem]
+OSSupport=0000000000010010
+
+[Data]
+CurrentMedia=New Media
+CurrentComponentDef=Default.cdf
+ProductName=MySQL Servers and Clients
+set_mifserial=
+DevEnvironment=Microsoft Visual C++ 6
+AppExe=
+set_dlldebug=No
+EmailAddresss=
+Instructions=Instructions.txt
+set_testmode=No
+set_mif=No
+SummaryText=
+Department=
+HomeURL=
+Author=
+Type=Database Application
+InstallRoot=D:\MySQL-Install\4.0.xpro
+Version=1.00.000
+InstallationGUID=40744a4d-efed-4cff-84a9-9e6389550f5c
+set_level=Level 3
+CurrentFileGroupDef=Default.fdf
+Notes=Notes.txt
+set_maxerr=50
+set_args=
+set_miffile=Status.mif
+set_dllcmdline=
+Copyright=
+set_warnaserr=No
+CurrentPlatform=
+Category=
+set_preproc=
+CurrentLanguage=English
+CompanyName=MySQL
+Description=Description.txt
+set_maxwarn=50
+set_crc=Yes
+set_compileb4build=No
+
+[MediaInfo]
+mediadata0=New Media/
+
+[General]
+Type=INSTALLMAIN
+Version=1.10.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Component Definitions/Default.cdf b/VC++Files/InstallShield/4.0.XX-pro/Component Definitions/Default.cdf
new file mode 100755
index 00000000000..48d37800cd1
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Component Definitions/Default.cdf
@@ -0,0 +1,192 @@
+[Development]
+required0=Servers
+SELECTED=Yes
+FILENEED=STANDARD
+required1=Grant Tables
+HTTPLOCATION=
+STATUS=Examples, Libraries, Includes and Script files
+UNINSTALLABLE=Yes
+TARGET=<TARGETDIR>
+FTPLOCATION=
+VISIBLE=Yes
+DESCRIPTION=Examples, Libraries, Includes and Script files
+DISPLAYTEXT=Examples, Libraries, Includes and Script files
+IMAGE=
+DEFSELECTION=Yes
+filegroup0=Development
+COMMENT=
+INCLUDEINBUILD=Yes
+INSTALLATION=ALWAYSOVERWRITE
+COMPRESSIFSEPARATE=No
+MISC=
+ENCRYPT=No
+DISK=ANYDISK
+TARGETDIRCDROM=
+PASSWORD=
+TARGETHIDDEN=General Application Destination
+
+[Grant Tables]
+required0=Servers
+SELECTED=Yes
+FILENEED=CRITICAL
+HTTPLOCATION=
+STATUS=The Grant Tables and Core Files
+UNINSTALLABLE=Yes
+TARGET=<TARGETDIR>
+FTPLOCATION=
+VISIBLE=Yes
+DESCRIPTION=The Grant Tables and Core Files
+DISPLAYTEXT=The Grant Tables and Core Files
+IMAGE=
+DEFSELECTION=Yes
+filegroup0=Grant Tables
+requiredby0=Development
+COMMENT=
+INCLUDEINBUILD=Yes
+requiredby1=Clients and Tools
+INSTALLATION=NEVEROVERWRITE
+requiredby2=Documentation
+COMPRESSIFSEPARATE=No
+MISC=
+ENCRYPT=No
+DISK=ANYDISK
+TARGETDIRCDROM=
+PASSWORD=
+TARGETHIDDEN=General Application Destination
+
+[Components]
+component0=Development
+component1=Grant Tables
+component2=Servers
+component3=Clients and Tools
+component4=Documentation
+
+[TopComponents]
+component0=Servers
+component1=Clients and Tools
+component2=Documentation
+component3=Development
+component4=Grant Tables
+
+[SetupType]
+setuptype0=Compact
+setuptype1=Typical
+setuptype2=Custom
+
+[Clients and Tools]
+required0=Servers
+SELECTED=Yes
+FILENEED=HIGHLYRECOMMENDED
+required1=Grant Tables
+HTTPLOCATION=
+STATUS=The MySQL clients and Maintenance Tools
+UNINSTALLABLE=Yes
+TARGET=<TARGETDIR>
+FTPLOCATION=
+VISIBLE=Yes
+DESCRIPTION=The MySQL clients and Maintenance Tools
+DISPLAYTEXT=The MySQL clients and Maintenance Tools
+IMAGE=
+DEFSELECTION=Yes
+filegroup0=Clients and Tools
+COMMENT=
+INCLUDEINBUILD=Yes
+INSTALLATION=NEWERDATE
+COMPRESSIFSEPARATE=No
+MISC=
+ENCRYPT=No
+DISK=ANYDISK
+TARGETDIRCDROM=
+PASSWORD=
+TARGETHIDDEN=General Application Destination
+
+[Servers]
+SELECTED=Yes
+FILENEED=CRITICAL
+HTTPLOCATION=
+STATUS=The MySQL Servers
+UNINSTALLABLE=Yes
+TARGET=<TARGETDIR>
+FTPLOCATION=
+VISIBLE=Yes
+DESCRIPTION=The MySQL Servers
+DISPLAYTEXT=The MySQL Servers
+IMAGE=
+DEFSELECTION=Yes
+filegroup0=Servers
+requiredby0=Development
+COMMENT=
+INCLUDEINBUILD=Yes
+requiredby1=Grant Tables
+INSTALLATION=ALWAYSOVERWRITE
+requiredby2=Clients and Tools
+requiredby3=Documentation
+COMPRESSIFSEPARATE=No
+MISC=
+ENCRYPT=No
+DISK=ANYDISK
+TARGETDIRCDROM=
+PASSWORD=
+TARGETHIDDEN=General Application Destination
+
+[SetupTypeItem-Compact]
+Comment=
+item0=Grant Tables
+item1=Servers
+item2=Clients and Tools
+item3=Documentation
+Descrip=
+DisplayText=
+
+[SetupTypeItem-Custom]
+Comment=
+item0=Development
+item1=Grant Tables
+item2=Servers
+item3=Clients and Tools
+Descrip=
+item4=Documentation
+DisplayText=
+
+[Info]
+Type=CompDef
+Version=1.00.000
+Name=
+
+[SetupTypeItem-Typical]
+Comment=
+item0=Development
+item1=Grant Tables
+item2=Servers
+item3=Clients and Tools
+Descrip=
+item4=Documentation
+DisplayText=
+
+[Documentation]
+required0=Servers
+SELECTED=Yes
+FILENEED=HIGHLYRECOMMENDED
+required1=Grant Tables
+HTTPLOCATION=
+STATUS=The MySQL Documentation with different formats
+UNINSTALLABLE=Yes
+TARGET=<TARGETDIR>
+FTPLOCATION=
+VISIBLE=Yes
+DESCRIPTION=The MySQL Documentation with different formats
+DISPLAYTEXT=The MySQL Documentation with different formats
+IMAGE=
+DEFSELECTION=Yes
+filegroup0=Documentation
+COMMENT=
+INCLUDEINBUILD=Yes
+INSTALLATION=ALWAYSOVERWRITE
+COMPRESSIFSEPARATE=No
+MISC=
+ENCRYPT=No
+DISK=ANYDISK
+TARGETDIRCDROM=
+PASSWORD=
+TARGETHIDDEN=General Application Destination
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Component Definitions/Default.fgl b/VC++Files/InstallShield/4.0.XX-pro/Component Definitions/Default.fgl
new file mode 100755
index 00000000000..4e20dcea4ab
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Component Definitions/Default.fgl
@@ -0,0 +1,42 @@
+[<PROGRAMFILES>\<COMMONFILES>]
+DISPLAYTEXT=Common Files Folder
+TYPE=TEXTSUBFIXED
+fulldirectory=
+
+[<WINDIR>\<WINSYSDIR>]
+DISPLAYTEXT=Windows System Folder
+TYPE=TEXTSUBFIXED
+fulldirectory=
+
+[USERDEFINED]
+DISPLAYTEXT=Script-defined Folders
+TYPE=USERSTART
+fulldirectory=
+
+[<PROGRAMFILES>]
+DISPLAYTEXT=Program Files Folder
+SubDir0=<PROGRAMFILES>\<COMMONFILES>
+TYPE=TEXTSUBFIXED
+fulldirectory=
+
+[<TARGETDIR>]
+DISPLAYTEXT=General Application Destination
+TYPE=TEXTSUBFIXED
+fulldirectory=
+
+[<WINDIR>]
+DISPLAYTEXT=Windows Operating System
+SubDir0=<WINDIR>\<WINSYSDIR>
+TYPE=TEXTSUBFIXED
+fulldirectory=
+
+[TopDir]
+SubDir0=<WINDIR>
+SubDir1=<PROGRAMFILES>
+SubDir2=<TARGETDIR>
+SubDir3=USERDEFINED
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/File Groups/Clients and Tools.fgl b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Clients and Tools.fgl
new file mode 100755
index 00000000000..7bba3d7474a
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Clients and Tools.fgl
@@ -0,0 +1,31 @@
+[bin]
+file15=C:\mysql\bin\replace.exe
+file16=C:\mysql\bin\winmysqladmin.cnt
+file0=C:\mysql\bin\isamchk.exe
+file17=C:\mysql\bin\WINMYSQLADMIN.HLP
+file1=C:\mysql\bin\myisamchk.exe
+file18=C:\mysql\bin\comp-err.exe
+file2=C:\mysql\bin\myisamlog.exe
+file19=C:\mysql\bin\my_print_defaults.exe
+file3=C:\mysql\bin\myisampack.exe
+file4=C:\mysql\bin\mysql.exe
+file5=C:\mysql\bin\mysqladmin.exe
+file6=C:\mysql\bin\mysqlbinlog.exe
+file7=C:\mysql\bin\mysqlc.exe
+file8=C:\mysql\bin\mysqlcheck.exe
+file9=C:\mysql\bin\mysqldump.exe
+file20=C:\mysql\bin\winmysqladmin.exe
+file10=C:\mysql\bin\mysqlimport.exe
+fulldirectory=
+file11=C:\mysql\bin\mysqlshow.exe
+file12=C:\mysql\bin\mysqlwatch.exe
+file13=C:\mysql\bin\pack_isam.exe
+file14=C:\mysql\bin\perror.exe
+
+[TopDir]
+SubDir0=bin
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/File Groups/Default.fdf b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Default.fdf
new file mode 100755
index 00000000000..8096a4b74bf
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Default.fdf
@@ -0,0 +1,82 @@
+[FileGroups]
+group0=Development
+group1=Grant Tables
+group2=Servers
+group3=Clients and Tools
+group4=Documentation
+
+[Development]
+SELFREGISTERING=No
+HTTPLOCATION=
+LANGUAGE=
+OPERATINGSYSTEM=
+FTPLOCATION=
+FILETYPE=No
+INFOTYPE=Standard
+COMMENT=
+COMPRESS=Yes
+COMPRESSDLL=
+POTENTIALLY=No
+MISC=
+
+[Grant Tables]
+SELFREGISTERING=No
+HTTPLOCATION=
+LANGUAGE=
+OPERATINGSYSTEM=
+FTPLOCATION=
+FILETYPE=No
+INFOTYPE=Standard
+COMMENT=
+COMPRESS=Yes
+COMPRESSDLL=
+POTENTIALLY=No
+MISC=
+
+[Clients and Tools]
+SELFREGISTERING=No
+HTTPLOCATION=
+LANGUAGE=
+OPERATINGSYSTEM=0000000000000000
+FTPLOCATION=
+FILETYPE=No
+INFOTYPE=Standard
+COMMENT=
+COMPRESS=Yes
+COMPRESSDLL=
+POTENTIALLY=No
+MISC=
+
+[Servers]
+SELFREGISTERING=No
+HTTPLOCATION=
+LANGUAGE=
+OPERATINGSYSTEM=
+FTPLOCATION=
+FILETYPE=No
+INFOTYPE=Standard
+COMMENT=
+COMPRESS=Yes
+COMPRESSDLL=
+POTENTIALLY=No
+MISC=
+
+[Info]
+Type=FileGrp
+Version=1.00.000
+Name=
+
+[Documentation]
+SELFREGISTERING=No
+HTTPLOCATION=
+LANGUAGE=
+OPERATINGSYSTEM=
+FTPLOCATION=
+FILETYPE=No
+INFOTYPE=Standard
+COMMENT=
+COMPRESS=Yes
+COMPRESSDLL=
+POTENTIALLY=No
+MISC=
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/File Groups/Development.fgl b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Development.fgl
new file mode 100755
index 00000000000..df4c058f8ce
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Development.fgl
@@ -0,0 +1,239 @@
+[bench\Data\Wisconsin]
+file0=C:\mysql\bench\Data\Wisconsin\onek.data
+file1=C:\mysql\bench\Data\Wisconsin\tenk.data
+fulldirectory=
+
+[lib\debug]
+file0=C:\mysql\lib\debug\libmySQL.dll
+file1=C:\mysql\lib\debug\libmySQL.lib
+file2=C:\mysql\lib\debug\mysqlclient.lib
+file3=C:\mysql\lib\debug\zlib.lib
+file4=C:\mysql\lib\debug\mysys.lib
+file5=C:\mysql\lib\debug\regex.lib
+file6=C:\mysql\lib\debug\strings.lib
+fulldirectory=
+
+[bench\output]
+fulldirectory=
+
+[examples\libmysqltest]
+file0=C:\mysql\examples\libmysqltest\myTest.c
+file1=C:\mysql\examples\libmysqltest\myTest.dsp
+file2=C:\mysql\examples\libmysqltest\myTest.dsw
+file3=C:\mysql\examples\libmysqltest\myTest.exe
+file4=C:\mysql\examples\libmysqltest\myTest.mak
+file5=C:\mysql\examples\libmysqltest\myTest.ncb
+file6=C:\mysql\examples\libmysqltest\myTest.opt
+file7=C:\mysql\examples\libmysqltest\readme
+fulldirectory=
+
+[include]
+file15=C:\mysql\include\libmysqld.def
+file16=C:\mysql\include\my_alloc.h
+file0=C:\mysql\include\raid.h
+file17=C:\mysql\include\my_getopt.h
+file1=C:\mysql\include\errmsg.h
+file2=C:\mysql\include\Libmysql.def
+file3=C:\mysql\include\m_ctype.h
+file4=C:\mysql\include\m_string.h
+file5=C:\mysql\include\my_list.h
+file6=C:\mysql\include\my_pthread.h
+file7=C:\mysql\include\my_sys.h
+file8=C:\mysql\include\mysql.h
+file9=C:\mysql\include\mysql_com.h
+file10=C:\mysql\include\mysql_version.h
+fulldirectory=
+file11=C:\mysql\include\mysqld_error.h
+file12=C:\mysql\include\dbug.h
+file13=C:\mysql\include\config-win.h
+file14=C:\mysql\include\my_global.h
+
+[examples]
+SubDir0=examples\libmysqltest
+SubDir1=examples\tests
+fulldirectory=
+
+[lib\opt]
+file0=C:\mysql\lib\opt\libmySQL.dll
+file1=C:\mysql\lib\opt\libmySQL.lib
+file2=C:\mysql\lib\opt\mysqlclient.lib
+file3=C:\mysql\lib\opt\zlib.lib
+file4=C:\mysql\lib\opt\strings.lib
+file5=C:\mysql\lib\opt\regex.lib
+file6=C:\mysql\lib\opt\mysys.lib
+fulldirectory=
+
+[bench\Data]
+SubDir0=bench\Data\ATIS
+SubDir1=bench\Data\Wisconsin
+fulldirectory=
+
+[bench\limits]
+file15=C:\mysql\bench\limits\pg.comment
+file16=C:\mysql\bench\limits\solid.cfg
+file0=C:\mysql\bench\limits\access.cfg
+file17=C:\mysql\bench\limits\solid-nt4.cfg
+file1=C:\mysql\bench\limits\access.comment
+file18=C:\mysql\bench\limits\sybase.cfg
+file2=C:\mysql\bench\limits\Adabas.cfg
+file3=C:\mysql\bench\limits\Adabas.comment
+file4=C:\mysql\bench\limits\Db2.cfg
+file5=C:\mysql\bench\limits\empress.cfg
+file6=C:\mysql\bench\limits\empress.comment
+file7=C:\mysql\bench\limits\Informix.cfg
+file8=C:\mysql\bench\limits\Informix.comment
+file9=C:\mysql\bench\limits\msql.cfg
+file10=C:\mysql\bench\limits\ms-sql.cfg
+fulldirectory=
+file11=C:\mysql\bench\limits\Ms-sql65.cfg
+file12=C:\mysql\bench\limits\mysql.cfg
+file13=C:\mysql\bench\limits\oracle.cfg
+file14=C:\mysql\bench\limits\pg.cfg
+
+[TopDir]
+SubDir0=bench
+SubDir1=examples
+SubDir2=include
+SubDir3=lib
+SubDir4=scripts
+
+[bench]
+file15=C:\mysql\bench\test-create
+file16=C:\mysql\bench\test-insert
+file0=C:\mysql\bench\uname.bat
+file17=C:\mysql\bench\test-select
+file1=C:\mysql\bench\compare-results
+file18=C:\mysql\bench\test-wisconsin
+file2=C:\mysql\bench\copy-db
+file19=C:\mysql\bench\bench-init.pl
+file3=C:\mysql\bench\crash-me
+file4=C:\mysql\bench\example.bat
+file5=C:\mysql\bench\print-limit-table
+file6=C:\mysql\bench\pwd.bat
+file7=C:\mysql\bench\Readme
+SubDir0=bench\Data
+file8=C:\mysql\bench\run.bat
+SubDir1=bench\limits
+file9=C:\mysql\bench\run-all-tests
+SubDir2=bench\output
+file10=C:\mysql\bench\server-cfg
+fulldirectory=
+file11=C:\mysql\bench\test-alter-table
+file12=C:\mysql\bench\test-ATIS
+file13=C:\mysql\bench\test-big-tables
+file14=C:\mysql\bench\test-connect
+
+[examples\tests]
+file15=C:\mysql\examples\tests\lock_test.res
+file16=C:\mysql\examples\tests\mail_to_db.pl
+file0=C:\mysql\examples\tests\unique_users.tst
+file17=C:\mysql\examples\tests\table_types.pl
+file1=C:\mysql\examples\tests\auto_increment.tst
+file18=C:\mysql\examples\tests\test_delayed_insert.pl
+file2=C:\mysql\examples\tests\big_record.pl
+file19=C:\mysql\examples\tests\udf_test
+file3=C:\mysql\examples\tests\big_record.res
+file4=C:\mysql\examples\tests\czech-sorting
+file5=C:\mysql\examples\tests\deadlock-script.pl
+file6=C:\mysql\examples\tests\export.pl
+file7=C:\mysql\examples\tests\fork_test.pl
+file8=C:\mysql\examples\tests\fork2_test.pl
+file9=C:\mysql\examples\tests\fork3_test.pl
+file20=C:\mysql\examples\tests\udf_test.res
+file21=C:\mysql\examples\tests\auto_increment.res
+file10=C:\mysql\examples\tests\function.res
+fulldirectory=
+file11=C:\mysql\examples\tests\function.tst
+file12=C:\mysql\examples\tests\grant.pl
+file13=C:\mysql\examples\tests\grant.res
+file14=C:\mysql\examples\tests\lock_test.pl
+
+[bench\Data\ATIS]
+file26=C:\mysql\bench\Data\ATIS\stop1.txt
+file15=C:\mysql\bench\Data\ATIS\flight_class.txt
+file27=C:\mysql\bench\Data\ATIS\time_interval.txt
+file16=C:\mysql\bench\Data\ATIS\flight_day.txt
+file0=C:\mysql\bench\Data\ATIS\transport.txt
+file28=C:\mysql\bench\Data\ATIS\time_zone.txt
+file17=C:\mysql\bench\Data\ATIS\flight_fare.txt
+file1=C:\mysql\bench\Data\ATIS\airline.txt
+file29=C:\mysql\bench\Data\ATIS\aircraft.txt
+file18=C:\mysql\bench\Data\ATIS\food_service.txt
+file2=C:\mysql\bench\Data\ATIS\airport.txt
+file19=C:\mysql\bench\Data\ATIS\ground_service.txt
+file3=C:\mysql\bench\Data\ATIS\airport_service.txt
+file4=C:\mysql\bench\Data\ATIS\city.txt
+file5=C:\mysql\bench\Data\ATIS\class_of_service.txt
+file6=C:\mysql\bench\Data\ATIS\code_description.txt
+file7=C:\mysql\bench\Data\ATIS\compound_class.txt
+file8=C:\mysql\bench\Data\ATIS\connect_leg.txt
+file9=C:\mysql\bench\Data\ATIS\date_day.txt
+file20=C:\mysql\bench\Data\ATIS\month_name.txt
+file21=C:\mysql\bench\Data\ATIS\restrict_carrier.txt
+file10=C:\mysql\bench\Data\ATIS\day_name.txt
+fulldirectory=
+file22=C:\mysql\bench\Data\ATIS\restrict_class.txt
+file11=C:\mysql\bench\Data\ATIS\dual_carrier.txt
+file23=C:\mysql\bench\Data\ATIS\restriction.txt
+file12=C:\mysql\bench\Data\ATIS\fare.txt
+file24=C:\mysql\bench\Data\ATIS\state.txt
+file13=C:\mysql\bench\Data\ATIS\fconnection.txt
+file25=C:\mysql\bench\Data\ATIS\stop.txt
+file14=C:\mysql\bench\Data\ATIS\flight.txt
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
+[scripts]
+file37=C:\mysql\scripts\mysqld_safe-watch.sh
+file26=C:\mysql\scripts\mysql_zap
+file15=C:\mysql\scripts\mysql_fix_privilege_tables
+file38=C:\mysql\scripts\mysqldumpslow
+file27=C:\mysql\scripts\mysql_zap.sh
+file16=C:\mysql\scripts\mysql_fix_privilege_tables.sh
+file0=C:\mysql\scripts\Readme
+file39=C:\mysql\scripts\mysqldumpslow.sh
+file28=C:\mysql\scripts\mysqlaccess
+file17=C:\mysql\scripts\mysql_install_db
+file1=C:\mysql\scripts\make_binary_distribution.sh
+file29=C:\mysql\scripts\mysqlaccess.conf
+file18=C:\mysql\scripts\mysql_install_db.sh
+file2=C:\mysql\scripts\msql2mysql
+file19=C:\mysql\scripts\mysql_secure_installation
+file3=C:\mysql\scripts\msql2mysql.sh
+file4=C:\mysql\scripts\mysql_config
+file5=C:\mysql\scripts\mysql_config.sh
+file6=C:\mysql\scripts\mysql_convert_table_format
+file7=C:\mysql\scripts\mysql_convert_table_format.sh
+file40=C:\mysql\scripts\mysqlhotcopy
+file8=C:\mysql\scripts\mysql_explain_log
+file41=C:\mysql\scripts\mysqlhotcopy.pl
+file30=C:\mysql\scripts\mysqlaccess.sh
+file9=C:\mysql\scripts\mysql_explain_log.sh
+file42=C:\mysql\scripts\mysqlhotcopy.sh
+file31=C:\mysql\scripts\mysqlbug
+file20=C:\mysql\scripts\mysql_secure_installation.sh
+file43=C:\mysql\scripts\make_binary_distribution
+file32=C:\mysql\scripts\mysqlbug.sh
+file21=C:\mysql\scripts\mysql_setpermission
+file10=C:\mysql\scripts\mysql_find_rows
+fulldirectory=
+file33=C:\mysql\scripts\mysqld_multi
+file22=C:\mysql\scripts\mysql_setpermission.pl
+file11=C:\mysql\scripts\mysql_find_rows.pl
+file34=C:\mysql\scripts\mysqld_multi.sh
+file23=C:\mysql\scripts\mysql_setpermission.sh
+file12=C:\mysql\scripts\mysql_find_rows.sh
+file35=C:\mysql\scripts\mysqld_safe
+file24=C:\mysql\scripts\mysql_tableinfo
+file13=C:\mysql\scripts\mysql_fix_extensions
+file36=C:\mysql\scripts\mysqld_safe.sh
+file25=C:\mysql\scripts\mysql_tableinfo.sh
+file14=C:\mysql\scripts\mysql_fix_extensions.sh
+
+[lib]
+SubDir0=lib\debug
+SubDir1=lib\opt
+fulldirectory=
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/File Groups/Documentation.fgl b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Documentation.fgl
new file mode 100755
index 00000000000..80fe777cf0f
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Documentation.fgl
@@ -0,0 +1,99 @@
+[Docs\Flags]
+file59=C:\mysql\Docs\Flags\romania.gif
+file48=C:\mysql\Docs\Flags\kroatia.eps
+file37=C:\mysql\Docs\Flags\iceland.gif
+file26=C:\mysql\Docs\Flags\france.eps
+file15=C:\mysql\Docs\Flags\china.gif
+file49=C:\mysql\Docs\Flags\kroatia.gif
+file38=C:\mysql\Docs\Flags\ireland.eps
+file27=C:\mysql\Docs\Flags\france.gif
+file16=C:\mysql\Docs\Flags\croatia.eps
+file0=C:\mysql\Docs\Flags\usa.gif
+file39=C:\mysql\Docs\Flags\ireland.gif
+file28=C:\mysql\Docs\Flags\germany.eps
+file17=C:\mysql\Docs\Flags\croatia.gif
+file1=C:\mysql\Docs\Flags\argentina.gif
+file29=C:\mysql\Docs\Flags\germany.gif
+file18=C:\mysql\Docs\Flags\czech-republic.eps
+file2=C:\mysql\Docs\Flags\australia.eps
+file19=C:\mysql\Docs\Flags\czech-republic.gif
+file3=C:\mysql\Docs\Flags\australia.gif
+file80=C:\mysql\Docs\Flags\usa.eps
+file4=C:\mysql\Docs\Flags\austria.eps
+file81=C:\mysql\Docs\Flags\argentina.eps
+file70=C:\mysql\Docs\Flags\spain.eps
+file5=C:\mysql\Docs\Flags\austria.gif
+file71=C:\mysql\Docs\Flags\spain.gif
+file60=C:\mysql\Docs\Flags\russia.eps
+file6=C:\mysql\Docs\Flags\brazil.eps
+file72=C:\mysql\Docs\Flags\sweden.eps
+file61=C:\mysql\Docs\Flags\russia.gif
+file50=C:\mysql\Docs\Flags\latvia.eps
+file7=C:\mysql\Docs\Flags\brazil.gif
+file73=C:\mysql\Docs\Flags\sweden.gif
+file62=C:\mysql\Docs\Flags\singapore.eps
+file51=C:\mysql\Docs\Flags\latvia.gif
+file40=C:\mysql\Docs\Flags\island.eps
+file8=C:\mysql\Docs\Flags\bulgaria.eps
+file74=C:\mysql\Docs\Flags\switzerland.eps
+file63=C:\mysql\Docs\Flags\singapore.gif
+file52=C:\mysql\Docs\Flags\netherlands.eps
+file41=C:\mysql\Docs\Flags\island.gif
+file30=C:\mysql\Docs\Flags\great-britain.eps
+file9=C:\mysql\Docs\Flags\bulgaria.gif
+file75=C:\mysql\Docs\Flags\switzerland.gif
+file64=C:\mysql\Docs\Flags\south-africa.eps
+file53=C:\mysql\Docs\Flags\netherlands.gif
+file42=C:\mysql\Docs\Flags\israel.eps
+file31=C:\mysql\Docs\Flags\great-britain.gif
+file20=C:\mysql\Docs\Flags\denmark.eps
+file76=C:\mysql\Docs\Flags\taiwan.eps
+file65=C:\mysql\Docs\Flags\south-africa.gif
+file54=C:\mysql\Docs\Flags\poland.eps
+file43=C:\mysql\Docs\Flags\israel.gif
+file32=C:\mysql\Docs\Flags\greece.eps
+file21=C:\mysql\Docs\Flags\denmark.gif
+file10=C:\mysql\Docs\Flags\canada.eps
+fulldirectory=
+file77=C:\mysql\Docs\Flags\taiwan.gif
+file66=C:\mysql\Docs\Flags\south-africa1.eps
+file55=C:\mysql\Docs\Flags\poland.gif
+file44=C:\mysql\Docs\Flags\italy.eps
+file33=C:\mysql\Docs\Flags\greece.gif
+file22=C:\mysql\Docs\Flags\estonia.eps
+file11=C:\mysql\Docs\Flags\canada.gif
+file78=C:\mysql\Docs\Flags\ukraine.eps
+file67=C:\mysql\Docs\Flags\south-africa1.gif
+file56=C:\mysql\Docs\Flags\portugal.eps
+file45=C:\mysql\Docs\Flags\italy.gif
+file34=C:\mysql\Docs\Flags\hungary.eps
+file23=C:\mysql\Docs\Flags\estonia.gif
+file12=C:\mysql\Docs\Flags\chile.eps
+file79=C:\mysql\Docs\Flags\ukraine.gif
+file68=C:\mysql\Docs\Flags\south-korea.eps
+file57=C:\mysql\Docs\Flags\portugal.gif
+file46=C:\mysql\Docs\Flags\japan.eps
+file35=C:\mysql\Docs\Flags\hungary.gif
+file24=C:\mysql\Docs\Flags\finland.eps
+file13=C:\mysql\Docs\Flags\chile.gif
+file69=C:\mysql\Docs\Flags\south-korea.gif
+file58=C:\mysql\Docs\Flags\romania.eps
+file47=C:\mysql\Docs\Flags\japan.gif
+file36=C:\mysql\Docs\Flags\iceland.eps
+file25=C:\mysql\Docs\Flags\finland.gif
+file14=C:\mysql\Docs\Flags\china.eps
+
+[Docs]
+file0=C:\mysql\Docs\manual_toc.html
+file1=C:\mysql\Docs\manual.html
+file2=C:\mysql\Docs\manual.txt
+SubDir0=Docs\Flags
+fulldirectory=
+
+[TopDir]
+SubDir0=Docs
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/File Groups/Grant Tables.fgl b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Grant Tables.fgl
new file mode 100755
index 00000000000..178065a7003
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Grant Tables.fgl
@@ -0,0 +1,36 @@
+[data\test]
+fulldirectory=
+
+[data\mysql]
+file15=C:\mysql\data\mysql\func.frm
+file16=C:\mysql\data\mysql\func.MYD
+file0=C:\mysql\data\mysql\columns_priv.frm
+file17=C:\mysql\data\mysql\func.MYI
+file1=C:\mysql\data\mysql\columns_priv.MYD
+file2=C:\mysql\data\mysql\columns_priv.MYI
+file3=C:\mysql\data\mysql\db.frm
+file4=C:\mysql\data\mysql\db.MYD
+file5=C:\mysql\data\mysql\db.MYI
+file6=C:\mysql\data\mysql\host.frm
+file7=C:\mysql\data\mysql\host.MYD
+file8=C:\mysql\data\mysql\host.MYI
+file9=C:\mysql\data\mysql\tables_priv.frm
+file10=C:\mysql\data\mysql\tables_priv.MYD
+fulldirectory=
+file11=C:\mysql\data\mysql\tables_priv.MYI
+file12=C:\mysql\data\mysql\user.frm
+file13=C:\mysql\data\mysql\user.MYD
+file14=C:\mysql\data\mysql\user.MYI
+
+[TopDir]
+SubDir0=data
+
+[data]
+SubDir0=data\mysql
+SubDir1=data\test
+fulldirectory=
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/File Groups/Servers.fgl b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Servers.fgl
new file mode 100755
index 00000000000..3f875b574f6
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/File Groups/Servers.fgl
@@ -0,0 +1,226 @@
+[Embedded\Static\release]
+file0=C:\mysql\embedded\Static\release\test_stc.dsp
+file1=C:\mysql\embedded\Static\release\ReadMe.txt
+file2=C:\mysql\embedded\Static\release\StdAfx.cpp
+file3=C:\mysql\embedded\Static\release\StdAfx.h
+file4=C:\mysql\embedded\Static\release\test_stc.cpp
+file5=C:\mysql\embedded\Static\release\mysqlserver.lib
+fulldirectory=
+
+[share\polish]
+file0=C:\mysql\share\polish\errmsg.sys
+file1=C:\mysql\share\polish\errmsg.txt
+fulldirectory=
+
+[share\dutch]
+file0=C:\mysql\share\dutch\errmsg.sys
+file1=C:\mysql\share\dutch\errmsg.txt
+fulldirectory=
+
+[share\spanish]
+file0=C:\mysql\share\spanish\errmsg.sys
+file1=C:\mysql\share\spanish\errmsg.txt
+fulldirectory=
+
+[share\english]
+file0=C:\mysql\share\english\errmsg.sys
+file1=C:\mysql\share\english\errmsg.txt
+fulldirectory=
+
+[bin]
+file0=C:\mysql\bin\mysqld-opt.exe
+file1=C:\mysql\bin\mysqld-nt.exe
+file2=C:\mysql\bin\mysqld.exe
+file3=C:\mysql\bin\cygwinb19.dll
+file4=C:\mysql\bin\libmySQL.dll
+fulldirectory=
+
+[share\korean]
+file0=C:\mysql\share\korean\errmsg.sys
+file1=C:\mysql\share\korean\errmsg.txt
+fulldirectory=
+
+[share\charsets]
+file15=C:\mysql\share\charsets\latin1.conf
+file16=C:\mysql\share\charsets\latin2.conf
+file0=C:\mysql\share\charsets\win1251ukr.conf
+file17=C:\mysql\share\charsets\latin5.conf
+file1=C:\mysql\share\charsets\cp1257.conf
+file18=C:\mysql\share\charsets\Readme
+file2=C:\mysql\share\charsets\croat.conf
+file19=C:\mysql\share\charsets\swe7.conf
+file3=C:\mysql\share\charsets\danish.conf
+file4=C:\mysql\share\charsets\dec8.conf
+file5=C:\mysql\share\charsets\dos.conf
+file6=C:\mysql\share\charsets\estonia.conf
+file7=C:\mysql\share\charsets\german1.conf
+file8=C:\mysql\share\charsets\greek.conf
+file9=C:\mysql\share\charsets\hebrew.conf
+file20=C:\mysql\share\charsets\usa7.conf
+file21=C:\mysql\share\charsets\win1250.conf
+file10=C:\mysql\share\charsets\hp8.conf
+fulldirectory=
+file22=C:\mysql\share\charsets\win1251.conf
+file11=C:\mysql\share\charsets\hungarian.conf
+file23=C:\mysql\share\charsets\cp1251.conf
+file12=C:\mysql\share\charsets\Index
+file13=C:\mysql\share\charsets\koi8_ru.conf
+file14=C:\mysql\share\charsets\koi8_ukr.conf
+
+[Embedded\DLL\debug]
+file0=C:\mysql\embedded\DLL\debug\libmysqld.dll
+file1=C:\mysql\embedded\DLL\debug\libmysqld.exp
+file2=C:\mysql\embedded\DLL\debug\libmysqld.lib
+fulldirectory=
+
+[Embedded]
+file0=C:\mysql\embedded\embedded.dsw
+SubDir0=Embedded\DLL
+SubDir1=Embedded\Static
+fulldirectory=
+
+[share\ukrainian]
+file0=C:\mysql\share\ukrainian\errmsg.sys
+file1=C:\mysql\share\ukrainian\errmsg.txt
+fulldirectory=
+
+[share\hungarian]
+file0=C:\mysql\share\hungarian\errmsg.sys
+file1=C:\mysql\share\hungarian\errmsg.txt
+fulldirectory=
+
+[share\german]
+file0=C:\mysql\share\german\errmsg.sys
+file1=C:\mysql\share\german\errmsg.txt
+fulldirectory=
+
+[share\portuguese]
+file0=C:\mysql\share\portuguese\errmsg.sys
+file1=C:\mysql\share\portuguese\errmsg.txt
+fulldirectory=
+
+[share\estonian]
+file0=C:\mysql\share\estonian\errmsg.sys
+file1=C:\mysql\share\estonian\errmsg.txt
+fulldirectory=
+
+[share\romanian]
+file0=C:\mysql\share\romanian\errmsg.sys
+file1=C:\mysql\share\romanian\errmsg.txt
+fulldirectory=
+
+[share\french]
+file0=C:\mysql\share\french\errmsg.sys
+file1=C:\mysql\share\french\errmsg.txt
+fulldirectory=
+
+[share\swedish]
+file0=C:\mysql\share\swedish\errmsg.sys
+file1=C:\mysql\share\swedish\errmsg.txt
+fulldirectory=
+
+[share\slovak]
+file0=C:\mysql\share\slovak\errmsg.sys
+file1=C:\mysql\share\slovak\errmsg.txt
+fulldirectory=
+
+[share\greek]
+file0=C:\mysql\share\greek\errmsg.sys
+file1=C:\mysql\share\greek\errmsg.txt
+fulldirectory=
+
+[TopDir]
+file0=C:\mysql\my-huge.cnf
+file1=C:\mysql\my-large.cnf
+file2=C:\mysql\my-medium.cnf
+file3=C:\mysql\my-small.cnf
+file4=C:\mysql\MySQLEULA.txt
+SubDir0=bin
+SubDir1=share
+SubDir2=Embedded
+
+[share]
+SubDir8=share\hungarian
+SubDir9=share\charsets
+SubDir20=share\spanish
+SubDir21=share\swedish
+SubDir10=share\italian
+SubDir22=share\ukrainian
+SubDir11=share\japanese
+SubDir12=share\korean
+SubDir13=share\norwegian
+SubDir14=share\norwegian-ny
+SubDir15=share\polish
+SubDir16=share\portuguese
+SubDir0=share\czech
+SubDir17=share\romanian
+SubDir1=share\danish
+SubDir18=share\russian
+SubDir2=share\dutch
+SubDir19=share\slovak
+SubDir3=share\english
+fulldirectory=
+SubDir4=share\estonian
+SubDir5=share\french
+SubDir6=share\german
+SubDir7=share\greek
+
+[share\norwegian-ny]
+file0=C:\mysql\share\norwegian-ny\errmsg.sys
+file1=C:\mysql\share\norwegian-ny\errmsg.txt
+fulldirectory=
+
+[Embedded\DLL]
+file0=C:\mysql\embedded\DLL\test_dll.dsp
+file1=C:\mysql\embedded\DLL\StdAfx.h
+file2=C:\mysql\embedded\DLL\test_dll.cpp
+file3=C:\mysql\embedded\DLL\StdAfx.cpp
+SubDir0=Embedded\DLL\debug
+SubDir1=Embedded\DLL\release
+fulldirectory=
+
+[Embedded\Static]
+SubDir0=Embedded\Static\release
+fulldirectory=
+
+[Embedded\DLL\release]
+file0=C:\mysql\embedded\DLL\release\libmysqld.dll
+file1=C:\mysql\embedded\DLL\release\libmysqld.exp
+file2=C:\mysql\embedded\DLL\release\libmysqld.lib
+file3=C:\mysql\embedded\DLL\release\mysql-server.exe
+fulldirectory=
+
+[share\danish]
+file0=C:\mysql\share\danish\errmsg.sys
+file1=C:\mysql\share\danish\errmsg.txt
+fulldirectory=
+
+[share\czech]
+file0=C:\mysql\share\czech\errmsg.sys
+file1=C:\mysql\share\czech\errmsg.txt
+fulldirectory=
+
+[General]
+Type=FILELIST
+Version=1.00.000
+
+[share\russian]
+file0=C:\mysql\share\russian\errmsg.sys
+file1=C:\mysql\share\russian\errmsg.txt
+fulldirectory=
+
+[share\norwegian]
+file0=C:\mysql\share\norwegian\errmsg.sys
+file1=C:\mysql\share\norwegian\errmsg.txt
+fulldirectory=
+
+[share\japanese]
+file0=C:\mysql\share\japanese\errmsg.sys
+file1=C:\mysql\share\japanese\errmsg.txt
+fulldirectory=
+
+[share\italian]
+file0=C:\mysql\share\italian\errmsg.sys
+file1=C:\mysql\share\italian\errmsg.txt
+fulldirectory=
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Registry Entries/Default.rge b/VC++Files/InstallShield/4.0.XX-pro/Registry Entries/Default.rge
new file mode 100755
index 00000000000..537dfd82e48
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Registry Entries/Default.rge
@@ -0,0 +1,4 @@
+[General]
+Type=REGISTRYDATA
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.dbg b/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.dbg
new file mode 100755
index 00000000000..0c6d4e6b708
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.dbg
Binary files differ
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.ino b/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.ino
new file mode 100755
index 00000000000..204d8ea0f36
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.ino
Binary files differ
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.ins b/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.ins
new file mode 100755
index 00000000000..759009b5c84
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.ins
Binary files differ
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.obs b/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.obs
new file mode 100755
index 00000000000..5fcfcb62c4e
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.obs
Binary files differ
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.rul b/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.rul
new file mode 100755
index 00000000000..df143b493c4
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Script Files/Setup.rul
@@ -0,0 +1,640 @@
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// IIIIIII SSSSSS
+// II SS InstallShield (R)
+// II SSSSSS (c) 1996-1997, InstallShield Software Corporation
+// II SS (c) 1990-1996, InstallShield Corporation
+// IIIIIII SSSSSS All Rights Reserved.
+//
+//
+// This code is generated as a starting setup template. You should
+// modify it to provide all necessary steps for your setup.
+//
+//
+// File Name: Setup.rul
+//
+// Description: InstallShield script
+//
+// Comments: This template script performs a basic setup on a
+// Windows 95 or Windows NT 4.0 platform. With minor
+// modifications, this template can be adapted to create
+// new, customized setups.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+ // Include header file
+#include "sdlang.h"
+#include "sddialog.h"
+
+////////////////////// string defines ////////////////////////////
+
+#define UNINST_LOGFILE_NAME "Uninst.isu"
+
+//////////////////// installation declarations ///////////////////
+
+ // ----- DLL prototypes -----
+
+
+ // your DLL prototypes
+
+
+ // ---- script prototypes -----
+
+ // generated
+ prototype ShowDialogs();
+ prototype MoveFileData();
+ prototype HandleMoveDataError( NUMBER );
+ prototype ProcessBeforeDataMove();
+ prototype ProcessAfterDataMove();
+ prototype SetupRegistry();
+ prototype SetupFolders();
+ prototype CleanUpInstall();
+ prototype SetupInstall();
+ prototype SetupScreen();
+ prototype CheckRequirements();
+ prototype DialogShowSdWelcome();
+ prototype DialogShowSdShowInfoList();
+ prototype DialogShowSdAskDestPath();
+ prototype DialogShowSdSetupType();
+ prototype DialogShowSdComponentDialog2();
+ prototype DialogShowSdFinishReboot();
+
+ // your prototypes
+
+
+ // ----- global variables ------
+
+ // generated
+ BOOL bWinNT, bIsShellExplorer, bInstallAborted, bIs32BitSetup;
+ STRING svDir;
+ STRING svName, svCompany, svSerial;
+ STRING szAppPath;
+ STRING svSetupType;
+
+
+ // your global variables
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// MAIN PROGRAM
+//
+// The setup begins here by hiding the visible setup
+// window. This is done to allow all the titles, images, etc. to
+// be established before showing the main window. The following
+// logic then performs the setup in a series of steps.
+//
+///////////////////////////////////////////////////////////////////////////////
+program
+ Disable( BACKGROUND );
+
+ CheckRequirements();
+
+ SetupInstall();
+
+ SetupScreen();
+
+ if (ShowDialogs()<0) goto end_install;
+
+ if (ProcessBeforeDataMove()<0) goto end_install;
+
+ if (MoveFileData()<0) goto end_install;
+
+ if (ProcessAfterDataMove()<0) goto end_install;
+
+ if (SetupRegistry()<0) goto end_install;
+
+ if (SetupFolders()<0) goto end_install;
+
+
+ end_install:
+
+ CleanUpInstall();
+
+ // If an unrecoverable error occurred, clean up the partial installation.
+ // Otherwise, exit normally.
+
+ if (bInstallAborted) then
+ abort;
+ endif;
+
+endprogram
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ShowDialogs //
+// //
+// Purpose: This function manages the display and navigation //
+// the standard dialogs that exist in a setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ShowDialogs()
+ NUMBER nResult;
+ begin
+
+ Dlg_Start:
+ // beginning of dialogs label
+
+ Dlg_SdWelcome:
+ nResult = DialogShowSdWelcome();
+ if (nResult = BACK) goto Dlg_Start;
+
+ Dlg_SdShowInfoList:
+ nResult = DialogShowSdShowInfoList();
+ if (nResult = BACK) goto Dlg_SdWelcome;
+
+ Dlg_SdAskDestPath:
+ nResult = DialogShowSdAskDestPath();
+ if (nResult = BACK) goto Dlg_SdShowInfoList;
+
+ Dlg_SdSetupType:
+ nResult = DialogShowSdSetupType();
+ if (nResult = BACK) goto Dlg_SdAskDestPath;
+
+ Dlg_SdComponentDialog2:
+ if ((nResult = BACK) && (svSetupType != "Custom") && (svSetupType != "")) then
+ goto Dlg_SdSetupType;
+ endif;
+ nResult = DialogShowSdComponentDialog2();
+ if (nResult = BACK) goto Dlg_SdSetupType;
+
+ return 0;
+
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ProcessBeforeDataMove //
+// //
+// Purpose: This function performs any necessary operations prior to the //
+// actual data move operation. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ProcessBeforeDataMove()
+ STRING svLogFile;
+ NUMBER nResult;
+ begin
+
+ InstallationInfo( @COMPANY_NAME, @PRODUCT_NAME, @PRODUCT_VERSION, @PRODUCT_KEY );
+
+ svLogFile = UNINST_LOGFILE_NAME;
+
+ nResult = DeinstallStart( svDir, svLogFile, @UNINST_KEY, 0 );
+ if (nResult < 0) then
+ MessageBox( @ERROR_UNINSTSETUP, WARNING );
+ endif;
+
+ szAppPath = TARGETDIR; // TODO : if your application .exe is in a subdir of TARGETDIR then add subdir
+
+ if ((bIs32BitSetup) && (bIsShellExplorer)) then
+ RegDBSetItem( REGDB_APPPATH, szAppPath );
+ RegDBSetItem( REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY );
+ RegDBSetItem( REGDB_UNINSTALL_NAME, @UNINST_DISPLAY_NAME );
+ endif;
+
+ // TODO : update any items you want to process before moving the data
+ //
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: MoveFileData //
+// //
+// Purpose: This function handles the data movement for //
+// the setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function MoveFileData()
+ NUMBER nResult, nDisk;
+ begin
+
+ nDisk = 1;
+ SetStatusWindow( 0, "" );
+ Disable( DIALOGCACHE );
+ Enable( STATUS );
+ StatusUpdate( ON, 100 );
+ nResult = ComponentMoveData( MEDIA, nDisk, 0 );
+
+ HandleMoveDataError( nResult );
+
+ Disable( STATUS );
+
+ return nResult;
+
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: HandleMoveDataError //
+// //
+// Purpose: This function handles the error (if any) during the move data //
+// operation. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function HandleMoveDataError( nResult )
+ STRING szErrMsg, svComponent , svFileGroup , svFile;
+ begin
+
+ svComponent = "";
+ svFileGroup = "";
+ svFile = "";
+
+ switch (nResult)
+ case 0:
+ return 0;
+ default:
+ ComponentError ( MEDIA , svComponent , svFileGroup , svFile , nResult );
+ szErrMsg = @ERROR_MOVEDATA + "\n\n" +
+ @ERROR_COMPONENT + " " + svComponent + "\n" +
+ @ERROR_FILEGROUP + " " + svFileGroup + "\n" +
+ @ERROR_FILE + " " + svFile;
+ SprintfBox( SEVERE, @TITLE_CAPTIONBAR, szErrMsg, nResult );
+ bInstallAborted = TRUE;
+ return nResult;
+ endswitch;
+
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ProcessAfterDataMove //
+// //
+// Purpose: This function performs any necessary operations needed after //
+// all data has been moved. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ProcessAfterDataMove()
+ begin
+
+ // TODO : update self-registered files and other processes that
+ // should be performed after the data has been moved.
+
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupRegistry //
+// //
+// Purpose: This function makes the registry entries for this setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupRegistry()
+ NUMBER nResult;
+
+ begin
+
+ // TODO : Add all your registry entry keys here
+ //
+ //
+ // RegDBCreateKeyEx, RegDBSetKeyValueEx....
+ //
+
+ nResult = CreateRegistrySet( "" );
+
+ return nResult;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Function: SetupFolders
+//
+// Purpose: This function creates all the folders and shortcuts for the
+// setup. This includes program groups and items for Windows 3.1.
+//
+///////////////////////////////////////////////////////////////////////////////
+function SetupFolders()
+ NUMBER nResult;
+
+ begin
+
+
+ // TODO : Add all your folder (program group) along with shortcuts (program items)
+ //
+ //
+ // CreateProgramFolder, AddFolderIcon....
+ //
+
+ nResult = CreateShellObjects( "" );
+
+ return nResult;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: CleanUpInstall //
+// //
+// Purpose: This cleans up the setup. Anything that should //
+// be released or deleted at the end of the setup should //
+// be done here. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function CleanUpInstall()
+ begin
+
+
+ if (bInstallAborted) then
+ return 0;
+ endif;
+
+ DialogShowSdFinishReboot();
+
+ if (BATCH_INSTALL) then // ensure locked files are properly written
+ CommitSharedFiles(0);
+ endif;
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupInstall //
+// //
+// Purpose: This will setup the installation. Any general initialization //
+// needed for the installation should be performed here. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupInstall()
+ begin
+
+ Enable( CORECOMPONENTHANDLING );
+
+ bInstallAborted = FALSE;
+
+ if (bIs32BitSetup) then
+ svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME ^ @PRODUCT_NAME;
+ else
+ svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME16 ^ @PRODUCT_NAME16; // use shorten names
+ endif;
+
+ TARGETDIR = svDir;
+
+ SdProductName( @PRODUCT_NAME );
+
+ Enable( DIALOGCACHE );
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupScreen //
+// //
+// Purpose: This function establishes the screen look. This includes //
+// colors, fonts, and text to be displayed. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupScreen()
+ begin
+
+ Enable( FULLWINDOWMODE );
+ Enable( INDVFILESTATUS );
+ SetTitle( @TITLE_MAIN, 24, WHITE );
+
+ SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text.
+
+ Enable( BACKGROUND );
+
+ Delay( 1 );
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: CheckRequirements //
+// //
+// Purpose: This function checks all minimum requirements for the //
+// application being installed. If any fail, then the user //
+// is informed and the setup is terminated. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function CheckRequirements()
+ NUMBER nvDx, nvDy, nvResult;
+ STRING svResult;
+
+ begin
+
+ bWinNT = FALSE;
+ bIsShellExplorer = FALSE;
+
+ // Check screen resolution.
+ GetExtents( nvDx, nvDy );
+
+ if (nvDy < 480) then
+ MessageBox( @ERROR_VGARESOLUTION, WARNING );
+ abort;
+ endif;
+
+ // set 'setup' operation mode
+ bIs32BitSetup = TRUE;
+ GetSystemInfo( ISTYPE, nvResult, svResult );
+ if (nvResult = 16) then
+ bIs32BitSetup = FALSE; // running 16-bit setup
+ return 0; // no additional information required
+ endif;
+
+ // --- 32-bit testing after this point ---
+
+ // Determine the target system's operating system.
+ GetSystemInfo( OS, nvResult, svResult );
+
+ if (nvResult = IS_WINDOWSNT) then
+ // Running Windows NT.
+ bWinNT = TRUE;
+
+ // Check to see if the shell being used is EXPLORER shell.
+ if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then
+ if (nvResult >= 4) then
+ bIsShellExplorer = TRUE;
+ endif;
+ endif;
+
+ elseif (nvResult = IS_WINDOWS95 ) then
+ bIsShellExplorer = TRUE;
+
+ endif;
+
+end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdWelcome //
+// //
+// Purpose: This function handles the standard welcome dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdWelcome()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdWelcome( szTitle, szMsg );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdShowInfoList //
+// //
+// Purpose: This function displays the general information list dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdShowInfoList()
+ NUMBER nResult;
+ LIST list;
+ STRING szTitle, szMsg, szFile;
+ begin
+
+ szFile = SUPPORTDIR ^ "infolist.txt";
+
+ list = ListCreate( STRINGLIST );
+ ListReadFromFile( list, szFile );
+ szTitle = "";
+ szMsg = " ";
+ nResult = SdShowInfoList( szTitle, szMsg, list );
+
+ ListDestroy( list );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdAskDestPath //
+// //
+// Purpose: This function asks the user for the destination directory. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdAskDestPath()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdAskDestPath( szTitle, szMsg, svDir, 0 );
+
+ TARGETDIR = svDir;
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdSetupType //
+// //
+// Purpose: This function displays the standard setup type dialog. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdSetupType()
+ NUMBER nResult, nType;
+ STRING szTitle, szMsg;
+ begin
+
+ switch (svSetupType)
+ case "Typical":
+ nType = TYPICAL;
+ case "Custom":
+ nType = CUSTOM;
+ case "Compact":
+ nType = COMPACT;
+ case "":
+ svSetupType = "Typical";
+ nType = TYPICAL;
+ endswitch;
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SetupType( szTitle, szMsg, "", nType, 0 );
+
+ switch (nResult)
+ case COMPACT:
+ svSetupType = "Compact";
+ case TYPICAL:
+ svSetupType = "Typical";
+ case CUSTOM:
+ svSetupType = "Custom";
+ endswitch;
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdComponentDialog2 //
+// //
+// Purpose: This function displays the custom component dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdComponentDialog2()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ if ((svSetupType != "Custom") && (svSetupType != "")) then
+ return 0;
+ endif;
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdComponentDialog2( szTitle, szMsg, svDir, "" );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdFinishReboot //
+// //
+// Purpose: This function will show the last dialog of the product. //
+// It will allow the user to reboot and/or show some readme text. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdFinishReboot()
+ NUMBER nResult, nDefOptions;
+ STRING szTitle, szMsg1, szMsg2, szOption1, szOption2;
+ NUMBER bOpt1, bOpt2;
+ begin
+
+ if (!BATCH_INSTALL) then
+ bOpt1 = FALSE;
+ bOpt2 = FALSE;
+ szMsg1 = "";
+ szMsg2 = "";
+ szOption1 = "";
+ szOption2 = "";
+ nResult = SdFinish( szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2 );
+ return 0;
+ endif;
+
+ nDefOptions = SYS_BOOTMACHINE;
+ szTitle = "";
+ szMsg1 = "";
+ szMsg2 = "";
+ nResult = SdFinishReboot( szTitle, szMsg1, nDefOptions, szMsg2, 0 );
+
+ return nResult;
+ end;
+
+ // --- include script file section ---
+
+#include "sddialog.rul"
+
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt b/VC++Files/InstallShield/4.0.XX-pro/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt
new file mode 100755
index 00000000000..52ccf8e11a9
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt
@@ -0,0 +1,25 @@
+This is a release of MySQL Pro @VERSION@ for Win32.
+
+NOTE: If you install MySQL in a folder other than
+C:\MYSQL or you intend to start MySQL on NT/Win2000
+as a service, you must create a file named C:\MY.CNF
+or \Windows\my.ini or \winnt\my.ini with the following
+information::
+
+[mysqld]
+basedir=E:/installation-path/
+datadir=E:/data-path/
+
+After your have installed MySQL, the installation
+directory will contain 4 files named 'my-small.cnf,
+my-medium.cnf, my-large.cnf, my-huge.cnf'.
+You can use this as a starting point for your own
+C:\my.cnf file.
+
+If you have any problems, you can mail them to
+win32@lists.mysql.com after you have consulted the
+MySQL manual and the MySQL mailing list archive
+(http://www.mysql.com/documentation/index.html)
+
+On behalf of the MySQL AB gang,
+Michael Widenius
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Setup Files/Uncompressed Files/Language Independent/OS Independent/setup.bmp b/VC++Files/InstallShield/4.0.XX-pro/Setup Files/Uncompressed Files/Language Independent/OS Independent/setup.bmp
new file mode 100755
index 00000000000..3229d50c9bf
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Setup Files/Uncompressed Files/Language Independent/OS Independent/setup.bmp
Binary files differ
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Shell Objects/Default.shl b/VC++Files/InstallShield/4.0.XX-pro/Shell Objects/Default.shl
new file mode 100755
index 00000000000..187cb651307
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Shell Objects/Default.shl
@@ -0,0 +1,12 @@
+[Data]
+Folder3=<FOLDER_STARTUP>
+Group0=Main
+Group1=Startup
+Folder0=<FOLDER_DESKTOP>
+Folder1=<FOLDER_STARTMENU>
+Folder2=<FOLDER_PROGRAMS>
+
+[Info]
+Type=ShellObject
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/String Tables/0009-English/value.shl b/VC++Files/InstallShield/4.0.XX-pro/String Tables/0009-English/value.shl
new file mode 100755
index 00000000000..525f3be0b3e
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/String Tables/0009-English/value.shl
@@ -0,0 +1,23 @@
+[Data]
+TITLE_MAIN=MySQL Pro Servers and Clients @VERSION@
+COMPANY_NAME=MySQL AB
+ERROR_COMPONENT=Component:
+COMPANY_NAME16=Company
+PRODUCT_VERSION=MySQL Pro Servers and Clients @VERSION@
+ERROR_MOVEDATA=An error occurred during the move data process: %d
+ERROR_FILEGROUP=File Group:
+UNINST_KEY=MySQL Pro Servers and Clients @VERSION@
+TITLE_CAPTIONBAR=MySQL Pro Servers and Clients @VERSION@
+PRODUCT_NAME16=Product
+ERROR_VGARESOLUTION=This program requires VGA or better resolution.
+ERROR_FILE=File:
+UNINST_DISPLAY_NAME=MySQL Pro Servers and Clients @VERSION@
+PRODUCT_KEY=yourapp.Exe
+PRODUCT_NAME=MySQL Pro Servers and Clients @VERSION@
+ERROR_UNINSTSETUP=unInstaller setup failed to initialize. You may not be able to uninstall this product.
+
+[General]
+Language=0009
+Type=STRINGTABLESPECIFIC
+Version=1.00.000
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/String Tables/Default.shl b/VC++Files/InstallShield/4.0.XX-pro/String Tables/Default.shl
new file mode 100755
index 00000000000..d4dc4925ab1
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/String Tables/Default.shl
@@ -0,0 +1,74 @@
+[TITLE_MAIN]
+Comment=
+
+[COMPANY_NAME]
+Comment=
+
+[ERROR_COMPONENT]
+Comment=
+
+[COMPANY_NAME16]
+Comment=
+
+[PRODUCT_VERSION]
+Comment=
+
+[ERROR_MOVEDATA]
+Comment=
+
+[ERROR_FILEGROUP]
+Comment=
+
+[Language]
+Lang0=0009
+CurrentLang=0
+
+[UNINST_KEY]
+Comment=
+
+[TITLE_CAPTIONBAR]
+Comment=
+
+[Data]
+Entry0=ERROR_VGARESOLUTION
+Entry1=TITLE_MAIN
+Entry2=TITLE_CAPTIONBAR
+Entry3=UNINST_KEY
+Entry4=UNINST_DISPLAY_NAME
+Entry5=COMPANY_NAME
+Entry6=PRODUCT_NAME
+Entry7=PRODUCT_VERSION
+Entry8=PRODUCT_KEY
+Entry9=ERROR_MOVEDATA
+Entry10=ERROR_UNINSTSETUP
+Entry11=COMPANY_NAME16
+Entry12=PRODUCT_NAME16
+Entry13=ERROR_COMPONENT
+Entry14=ERROR_FILEGROUP
+Entry15=ERROR_FILE
+
+[PRODUCT_NAME16]
+Comment=
+
+[ERROR_VGARESOLUTION]
+Comment=
+
+[ERROR_FILE]
+Comment=
+
+[General]
+Type=STRINGTABLE
+Version=1.00.000
+
+[UNINST_DISPLAY_NAME]
+Comment=
+
+[PRODUCT_KEY]
+Comment=
+
+[PRODUCT_NAME]
+Comment=
+
+[ERROR_UNINSTSETUP]
+Comment=
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Text Substitutions/Build.tsb b/VC++Files/InstallShield/4.0.XX-pro/Text Substitutions/Build.tsb
new file mode 100755
index 00000000000..3949bd4c066
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Text Substitutions/Build.tsb
@@ -0,0 +1,56 @@
+[<HKUS>]
+Value=
+KeyType=4
+
+[<HKCR>]
+Value=
+KeyType=4
+
+[<PROGRAMFILES>]
+Value=
+KeyType=4
+
+[<WINSYSDIR>]
+Value=
+KeyType=4
+
+[<COMMONFILES>]
+Value=
+KeyType=4
+
+[<WINDIR>]
+Value=
+KeyType=4
+
+[Data]
+Key0=<PROGRAMFILES>
+Key1=<COMMONFILES>
+Key2=<WINDIR>
+Key3=<WINSYSDIR>
+Key4=<HKLM>
+Key5=<HKCU>
+Key6=<HKCC>
+Key7=<HKDD>
+Key8=<HKUS>
+Key9=<HKCR>
+
+[General]
+Type=TEXTSUB
+Version=1.00.000
+
+[<HKLM>]
+Value=
+KeyType=4
+
+[<HKCU>]
+Value=
+KeyType=4
+
+[<HKCC>]
+Value=
+KeyType=4
+
+[<HKDD>]
+Value=
+KeyType=4
+
diff --git a/VC++Files/InstallShield/4.0.XX-pro/Text Substitutions/Setup.tsb b/VC++Files/InstallShield/4.0.XX-pro/Text Substitutions/Setup.tsb
new file mode 100755
index 00000000000..b0c5a509f0b
--- /dev/null
+++ b/VC++Files/InstallShield/4.0.XX-pro/Text Substitutions/Setup.tsb
@@ -0,0 +1,76 @@
+[<SRCDIR>]
+Value=
+KeyType=4
+
+[<HKUS>]
+Value=
+KeyType=4
+
+[<HKCR>]
+Value=
+KeyType=4
+
+[<PROGRAMFILES>]
+Value=
+KeyType=4
+
+[<TARGETDIR>]
+Value=
+KeyType=4
+
+[<WINSYSDIR>]
+Value=
+KeyType=4
+
+[<COMMONFILES>]
+Value=
+KeyType=4
+
+[<WINDIR>]
+Value=
+KeyType=4
+
+[Data]
+Key0=<PROGRAMFILES>
+Key1=<COMMONFILES>
+Key2=<WINDIR>
+Key3=<WINSYSDIR>
+Key4=<TARGETDIR>
+Key5=<SUPPORTDIR>
+Key10=<HKDD>
+Key6=<SRCDIR>
+Key11=<HKUS>
+Key7=<HKLM>
+Key12=<HKCR>
+Key8=<HKCU>
+Key13=<SHELL_OBJECT_FOLDER>
+Key9=<HKCC>
+
+[<SUPPORTDIR>]
+Value=
+KeyType=4
+
+[<SHELL_OBJECT_FOLDER>]
+Value=
+KeyType=4
+
+[General]
+Type=TEXTSUB
+Version=1.00.000
+
+[<HKLM>]
+Value=
+KeyType=4
+
+[<HKCU>]
+Value=
+KeyType=4
+
+[<HKCC>]
+Value=
+KeyType=4
+
+[<HKDD>]
+Value=
+KeyType=4
+
diff --git a/VC++Files/InstallShield/Script Files/Setup.dbg b/VC++Files/InstallShield/Script Files/Setup.dbg
new file mode 100644
index 00000000000..0c6d4e6b708
--- /dev/null
+++ b/VC++Files/InstallShield/Script Files/Setup.dbg
Binary files differ
diff --git a/VC++Files/InstallShield/Script Files/Setup.ino b/VC++Files/InstallShield/Script Files/Setup.ino
new file mode 100644
index 00000000000..204d8ea0f36
--- /dev/null
+++ b/VC++Files/InstallShield/Script Files/Setup.ino
Binary files differ
diff --git a/VC++Files/InstallShield/Script Files/Setup.ins b/VC++Files/InstallShield/Script Files/Setup.ins
new file mode 100644
index 00000000000..759009b5c84
--- /dev/null
+++ b/VC++Files/InstallShield/Script Files/Setup.ins
Binary files differ
diff --git a/VC++Files/InstallShield/Script Files/Setup.obs b/VC++Files/InstallShield/Script Files/Setup.obs
new file mode 100644
index 00000000000..5fcfcb62c4e
--- /dev/null
+++ b/VC++Files/InstallShield/Script Files/Setup.obs
Binary files differ
diff --git a/VC++Files/InstallShield/Script Files/Setup.rul b/VC++Files/InstallShield/Script Files/Setup.rul
new file mode 100644
index 00000000000..df143b493c4
--- /dev/null
+++ b/VC++Files/InstallShield/Script Files/Setup.rul
@@ -0,0 +1,640 @@
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// IIIIIII SSSSSS
+// II SS InstallShield (R)
+// II SSSSSS (c) 1996-1997, InstallShield Software Corporation
+// II SS (c) 1990-1996, InstallShield Corporation
+// IIIIIII SSSSSS All Rights Reserved.
+//
+//
+// This code is generated as a starting setup template. You should
+// modify it to provide all necessary steps for your setup.
+//
+//
+// File Name: Setup.rul
+//
+// Description: InstallShield script
+//
+// Comments: This template script performs a basic setup on a
+// Windows 95 or Windows NT 4.0 platform. With minor
+// modifications, this template can be adapted to create
+// new, customized setups.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+ // Include header file
+#include "sdlang.h"
+#include "sddialog.h"
+
+////////////////////// string defines ////////////////////////////
+
+#define UNINST_LOGFILE_NAME "Uninst.isu"
+
+//////////////////// installation declarations ///////////////////
+
+ // ----- DLL prototypes -----
+
+
+ // your DLL prototypes
+
+
+ // ---- script prototypes -----
+
+ // generated
+ prototype ShowDialogs();
+ prototype MoveFileData();
+ prototype HandleMoveDataError( NUMBER );
+ prototype ProcessBeforeDataMove();
+ prototype ProcessAfterDataMove();
+ prototype SetupRegistry();
+ prototype SetupFolders();
+ prototype CleanUpInstall();
+ prototype SetupInstall();
+ prototype SetupScreen();
+ prototype CheckRequirements();
+ prototype DialogShowSdWelcome();
+ prototype DialogShowSdShowInfoList();
+ prototype DialogShowSdAskDestPath();
+ prototype DialogShowSdSetupType();
+ prototype DialogShowSdComponentDialog2();
+ prototype DialogShowSdFinishReboot();
+
+ // your prototypes
+
+
+ // ----- global variables ------
+
+ // generated
+ BOOL bWinNT, bIsShellExplorer, bInstallAborted, bIs32BitSetup;
+ STRING svDir;
+ STRING svName, svCompany, svSerial;
+ STRING szAppPath;
+ STRING svSetupType;
+
+
+ // your global variables
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// MAIN PROGRAM
+//
+// The setup begins here by hiding the visible setup
+// window. This is done to allow all the titles, images, etc. to
+// be established before showing the main window. The following
+// logic then performs the setup in a series of steps.
+//
+///////////////////////////////////////////////////////////////////////////////
+program
+ Disable( BACKGROUND );
+
+ CheckRequirements();
+
+ SetupInstall();
+
+ SetupScreen();
+
+ if (ShowDialogs()<0) goto end_install;
+
+ if (ProcessBeforeDataMove()<0) goto end_install;
+
+ if (MoveFileData()<0) goto end_install;
+
+ if (ProcessAfterDataMove()<0) goto end_install;
+
+ if (SetupRegistry()<0) goto end_install;
+
+ if (SetupFolders()<0) goto end_install;
+
+
+ end_install:
+
+ CleanUpInstall();
+
+ // If an unrecoverable error occurred, clean up the partial installation.
+ // Otherwise, exit normally.
+
+ if (bInstallAborted) then
+ abort;
+ endif;
+
+endprogram
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ShowDialogs //
+// //
+// Purpose: This function manages the display and navigation //
+// the standard dialogs that exist in a setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ShowDialogs()
+ NUMBER nResult;
+ begin
+
+ Dlg_Start:
+ // beginning of dialogs label
+
+ Dlg_SdWelcome:
+ nResult = DialogShowSdWelcome();
+ if (nResult = BACK) goto Dlg_Start;
+
+ Dlg_SdShowInfoList:
+ nResult = DialogShowSdShowInfoList();
+ if (nResult = BACK) goto Dlg_SdWelcome;
+
+ Dlg_SdAskDestPath:
+ nResult = DialogShowSdAskDestPath();
+ if (nResult = BACK) goto Dlg_SdShowInfoList;
+
+ Dlg_SdSetupType:
+ nResult = DialogShowSdSetupType();
+ if (nResult = BACK) goto Dlg_SdAskDestPath;
+
+ Dlg_SdComponentDialog2:
+ if ((nResult = BACK) && (svSetupType != "Custom") && (svSetupType != "")) then
+ goto Dlg_SdSetupType;
+ endif;
+ nResult = DialogShowSdComponentDialog2();
+ if (nResult = BACK) goto Dlg_SdSetupType;
+
+ return 0;
+
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ProcessBeforeDataMove //
+// //
+// Purpose: This function performs any necessary operations prior to the //
+// actual data move operation. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ProcessBeforeDataMove()
+ STRING svLogFile;
+ NUMBER nResult;
+ begin
+
+ InstallationInfo( @COMPANY_NAME, @PRODUCT_NAME, @PRODUCT_VERSION, @PRODUCT_KEY );
+
+ svLogFile = UNINST_LOGFILE_NAME;
+
+ nResult = DeinstallStart( svDir, svLogFile, @UNINST_KEY, 0 );
+ if (nResult < 0) then
+ MessageBox( @ERROR_UNINSTSETUP, WARNING );
+ endif;
+
+ szAppPath = TARGETDIR; // TODO : if your application .exe is in a subdir of TARGETDIR then add subdir
+
+ if ((bIs32BitSetup) && (bIsShellExplorer)) then
+ RegDBSetItem( REGDB_APPPATH, szAppPath );
+ RegDBSetItem( REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY );
+ RegDBSetItem( REGDB_UNINSTALL_NAME, @UNINST_DISPLAY_NAME );
+ endif;
+
+ // TODO : update any items you want to process before moving the data
+ //
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: MoveFileData //
+// //
+// Purpose: This function handles the data movement for //
+// the setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function MoveFileData()
+ NUMBER nResult, nDisk;
+ begin
+
+ nDisk = 1;
+ SetStatusWindow( 0, "" );
+ Disable( DIALOGCACHE );
+ Enable( STATUS );
+ StatusUpdate( ON, 100 );
+ nResult = ComponentMoveData( MEDIA, nDisk, 0 );
+
+ HandleMoveDataError( nResult );
+
+ Disable( STATUS );
+
+ return nResult;
+
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: HandleMoveDataError //
+// //
+// Purpose: This function handles the error (if any) during the move data //
+// operation. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function HandleMoveDataError( nResult )
+ STRING szErrMsg, svComponent , svFileGroup , svFile;
+ begin
+
+ svComponent = "";
+ svFileGroup = "";
+ svFile = "";
+
+ switch (nResult)
+ case 0:
+ return 0;
+ default:
+ ComponentError ( MEDIA , svComponent , svFileGroup , svFile , nResult );
+ szErrMsg = @ERROR_MOVEDATA + "\n\n" +
+ @ERROR_COMPONENT + " " + svComponent + "\n" +
+ @ERROR_FILEGROUP + " " + svFileGroup + "\n" +
+ @ERROR_FILE + " " + svFile;
+ SprintfBox( SEVERE, @TITLE_CAPTIONBAR, szErrMsg, nResult );
+ bInstallAborted = TRUE;
+ return nResult;
+ endswitch;
+
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: ProcessAfterDataMove //
+// //
+// Purpose: This function performs any necessary operations needed after //
+// all data has been moved. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function ProcessAfterDataMove()
+ begin
+
+ // TODO : update self-registered files and other processes that
+ // should be performed after the data has been moved.
+
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupRegistry //
+// //
+// Purpose: This function makes the registry entries for this setup. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupRegistry()
+ NUMBER nResult;
+
+ begin
+
+ // TODO : Add all your registry entry keys here
+ //
+ //
+ // RegDBCreateKeyEx, RegDBSetKeyValueEx....
+ //
+
+ nResult = CreateRegistrySet( "" );
+
+ return nResult;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Function: SetupFolders
+//
+// Purpose: This function creates all the folders and shortcuts for the
+// setup. This includes program groups and items for Windows 3.1.
+//
+///////////////////////////////////////////////////////////////////////////////
+function SetupFolders()
+ NUMBER nResult;
+
+ begin
+
+
+ // TODO : Add all your folder (program group) along with shortcuts (program items)
+ //
+ //
+ // CreateProgramFolder, AddFolderIcon....
+ //
+
+ nResult = CreateShellObjects( "" );
+
+ return nResult;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: CleanUpInstall //
+// //
+// Purpose: This cleans up the setup. Anything that should //
+// be released or deleted at the end of the setup should //
+// be done here. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function CleanUpInstall()
+ begin
+
+
+ if (bInstallAborted) then
+ return 0;
+ endif;
+
+ DialogShowSdFinishReboot();
+
+ if (BATCH_INSTALL) then // ensure locked files are properly written
+ CommitSharedFiles(0);
+ endif;
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupInstall //
+// //
+// Purpose: This will setup the installation. Any general initialization //
+// needed for the installation should be performed here. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupInstall()
+ begin
+
+ Enable( CORECOMPONENTHANDLING );
+
+ bInstallAborted = FALSE;
+
+ if (bIs32BitSetup) then
+ svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME ^ @PRODUCT_NAME;
+ else
+ svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME16 ^ @PRODUCT_NAME16; // use shorten names
+ endif;
+
+ TARGETDIR = svDir;
+
+ SdProductName( @PRODUCT_NAME );
+
+ Enable( DIALOGCACHE );
+
+ return 0;
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: SetupScreen //
+// //
+// Purpose: This function establishes the screen look. This includes //
+// colors, fonts, and text to be displayed. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function SetupScreen()
+ begin
+
+ Enable( FULLWINDOWMODE );
+ Enable( INDVFILESTATUS );
+ SetTitle( @TITLE_MAIN, 24, WHITE );
+
+ SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text.
+
+ Enable( BACKGROUND );
+
+ Delay( 1 );
+ end;
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: CheckRequirements //
+// //
+// Purpose: This function checks all minimum requirements for the //
+// application being installed. If any fail, then the user //
+// is informed and the setup is terminated. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function CheckRequirements()
+ NUMBER nvDx, nvDy, nvResult;
+ STRING svResult;
+
+ begin
+
+ bWinNT = FALSE;
+ bIsShellExplorer = FALSE;
+
+ // Check screen resolution.
+ GetExtents( nvDx, nvDy );
+
+ if (nvDy < 480) then
+ MessageBox( @ERROR_VGARESOLUTION, WARNING );
+ abort;
+ endif;
+
+ // set 'setup' operation mode
+ bIs32BitSetup = TRUE;
+ GetSystemInfo( ISTYPE, nvResult, svResult );
+ if (nvResult = 16) then
+ bIs32BitSetup = FALSE; // running 16-bit setup
+ return 0; // no additional information required
+ endif;
+
+ // --- 32-bit testing after this point ---
+
+ // Determine the target system's operating system.
+ GetSystemInfo( OS, nvResult, svResult );
+
+ if (nvResult = IS_WINDOWSNT) then
+ // Running Windows NT.
+ bWinNT = TRUE;
+
+ // Check to see if the shell being used is EXPLORER shell.
+ if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then
+ if (nvResult >= 4) then
+ bIsShellExplorer = TRUE;
+ endif;
+ endif;
+
+ elseif (nvResult = IS_WINDOWS95 ) then
+ bIsShellExplorer = TRUE;
+
+ endif;
+
+end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdWelcome //
+// //
+// Purpose: This function handles the standard welcome dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdWelcome()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdWelcome( szTitle, szMsg );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdShowInfoList //
+// //
+// Purpose: This function displays the general information list dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdShowInfoList()
+ NUMBER nResult;
+ LIST list;
+ STRING szTitle, szMsg, szFile;
+ begin
+
+ szFile = SUPPORTDIR ^ "infolist.txt";
+
+ list = ListCreate( STRINGLIST );
+ ListReadFromFile( list, szFile );
+ szTitle = "";
+ szMsg = " ";
+ nResult = SdShowInfoList( szTitle, szMsg, list );
+
+ ListDestroy( list );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdAskDestPath //
+// //
+// Purpose: This function asks the user for the destination directory. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdAskDestPath()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdAskDestPath( szTitle, szMsg, svDir, 0 );
+
+ TARGETDIR = svDir;
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdSetupType //
+// //
+// Purpose: This function displays the standard setup type dialog. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdSetupType()
+ NUMBER nResult, nType;
+ STRING szTitle, szMsg;
+ begin
+
+ switch (svSetupType)
+ case "Typical":
+ nType = TYPICAL;
+ case "Custom":
+ nType = CUSTOM;
+ case "Compact":
+ nType = COMPACT;
+ case "":
+ svSetupType = "Typical";
+ nType = TYPICAL;
+ endswitch;
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SetupType( szTitle, szMsg, "", nType, 0 );
+
+ switch (nResult)
+ case COMPACT:
+ svSetupType = "Compact";
+ case TYPICAL:
+ svSetupType = "Typical";
+ case CUSTOM:
+ svSetupType = "Custom";
+ endswitch;
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdComponentDialog2 //
+// //
+// Purpose: This function displays the custom component dialog. //
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdComponentDialog2()
+ NUMBER nResult;
+ STRING szTitle, szMsg;
+ begin
+
+ if ((svSetupType != "Custom") && (svSetupType != "")) then
+ return 0;
+ endif;
+
+ szTitle = "";
+ szMsg = "";
+ nResult = SdComponentDialog2( szTitle, szMsg, svDir, "" );
+
+ return nResult;
+ end;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Function: DialogShowSdFinishReboot //
+// //
+// Purpose: This function will show the last dialog of the product. //
+// It will allow the user to reboot and/or show some readme text. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+function DialogShowSdFinishReboot()
+ NUMBER nResult, nDefOptions;
+ STRING szTitle, szMsg1, szMsg2, szOption1, szOption2;
+ NUMBER bOpt1, bOpt2;
+ begin
+
+ if (!BATCH_INSTALL) then
+ bOpt1 = FALSE;
+ bOpt2 = FALSE;
+ szMsg1 = "";
+ szMsg2 = "";
+ szOption1 = "";
+ szOption2 = "";
+ nResult = SdFinish( szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2 );
+ return 0;
+ endif;
+
+ nDefOptions = SYS_BOOTMACHINE;
+ szTitle = "";
+ szMsg1 = "";
+ szMsg2 = "";
+ nResult = SdFinishReboot( szTitle, szMsg1, nDefOptions, szMsg2, 0 );
+
+ return nResult;
+ end;
+
+ // --- include script file section ---
+
+#include "sddialog.rul"
+
+
diff --git a/VC++Files/bdb/bdb.dsp b/VC++Files/bdb/bdb.dsp
index 1e9d00af863..40dfd3900f8 100644
--- a/VC++Files/bdb/bdb.dsp
+++ b/VC++Files/bdb/bdb.dsp
@@ -1,682 +1,682 @@
-# Microsoft Developer Studio Project File - Name="bdb" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
+# Microsoft Developer Studio Project File - Name="bdb" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
CFG=bdb - Win32 Max
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "bdb.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "bdb.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
!MESSAGE NMAKE /f "bdb.mak" CFG="bdb - Win32 Max"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "bdb - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE "bdb - Win32 Max" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "bdb - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../bdb/build_win32" /I "../bdb/include" /D "__WIN32__" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
-# SUBTRACT CPP /Fr
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\lib_debug\bdb.lib"
-
-!ELSEIF "$(CFG)" == "bdb - Win32 Max"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "bdb___Win32_Max"
-# PROP BASE Intermediate_Dir "bdb___Win32_Max"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "bdb___Win32_Max"
-# PROP Intermediate_Dir "bdb___Win32_Max"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../bdb/build_win32" /I "../bdb/include" /D "__WIN32__" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
-# SUBTRACT BASE CPP /Fr
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../bdb/build_win32" /I "../bdb/include" /I "../zlib../sql" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /Fo"mysys___Win32_Max/" /Fd"mysys___Win32_Max/" /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo /out:"..\lib_debug\bdb.lib"
-# ADD LIB32 /nologo /out:"..\lib_release\bdb.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "bdb - Win32 Debug"
-# Name "bdb - Win32 Max"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\btree\bt_compare.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_conv.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_curadj.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_cursor.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_delete.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_method.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_open.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_put.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_rec.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_reclaim.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_recno.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_rsearch.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_search.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_split.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_stat.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_upgrade.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\bt_verify.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\btree\btree_auto.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\crdel_auto.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\crdel_rec.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\cxx\cxx_app.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\cxx\cxx_except.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\cxx\cxx_lock.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\cxx\cxx_log.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\cxx\cxx_mpool.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\cxx\cxx_table.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\cxx\cxx_txn.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_am.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_auto.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\common\db_byteorder.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_cam.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_conv.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_dispatch.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_dup.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\common\db_err.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\common\db_getlong.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_iface.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_join.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\common\db_log2.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_meta.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_method.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_overflow.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_pr.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_rec.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_reclaim.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_ret.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\env\db_salloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\env\db_shash.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_upg.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_upg_opd.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_vrfy.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\db\db_vrfyutil.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\dbm\dbm.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\env\env_method.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\env\env_open.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\env\env_recover.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\env\env_region.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_auto.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_conv.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_dup.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_func.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_meta.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_method.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_page.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_rec.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_reclaim.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_stat.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_upgrade.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hash\hash_verify.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\hsearch\hsearch.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\lock\lock.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\lock\lock_conflict.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\lock\lock_deadlock.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\lock\lock_method.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\lock\lock_region.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\lock\lock_stat.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\lock\lock_util.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\log\log.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\log\log_archive.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\log\log_auto.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\log\log_compare.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\log\log_findckp.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\log\log_get.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\log\log_method.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\log\log_put.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\log\log_rec.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\log\log_register.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_alloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_bh.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_fget.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_fopen.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_fput.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_fset.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_method.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_region.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_register.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_stat.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_sync.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mp\mp_trickle.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mutex\mut_tas.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\mutex\mutex.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_abs.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_alloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_dir.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_errno.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_fid.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_finit.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_fsync.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_handle.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_map.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_method.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_oflags.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_open.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_region.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_rename.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_root.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_rpath.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_rw.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_seek.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_sleep.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_spin.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_stat.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_tmpdir.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os_win32\os_type.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\os\os_unlink.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\qam\qam.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\qam\qam_auto.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\qam\qam_conv.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\qam\qam_files.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\qam\qam_method.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\qam\qam_open.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\qam\qam_rec.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\qam\qam_stat.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\qam\qam_upgrade.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\qam\qam_verify.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\clib\strcasecmp.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\txn\txn.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\txn\txn_auto.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\txn\txn_rec.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\txn\txn_region.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\common\util_log.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\common\util_sig.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\xa\xa.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\xa\xa_db.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\xa\xa_map.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# End Target
-# End Project
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "bdb - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "bdb - Win32 Max" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "bdb - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../bdb/build_win32" /I "../bdb/include" /D "__WIN32__" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /Fr
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\bdb.lib"
+
+!ELSEIF "$(CFG)" == "bdb - Win32 Max"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "bdb___Win32_Max"
+# PROP BASE Intermediate_Dir "bdb___Win32_Max"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "max"
+# PROP Intermediate_Dir "max"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../bdb/build_win32" /I "../bdb/include" /D "__WIN32__" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT BASE CPP /Fr
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../bdb/build_win32" /I "../bdb/include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /Fo"mysys___Win32_Max/" /Fd"mysys___Win32_Max/" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_debug\bdb.lib"
+# ADD LIB32 /nologo /out:"..\lib_release\bdb.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "bdb - Win32 Debug"
+# Name "bdb - Win32 Max"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\btree\bt_compare.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_conv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_curadj.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_cursor.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_put.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_reclaim.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_recno.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_rsearch.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_search.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_split.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_upgrade.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\bt_verify.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree\btree_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\crdel_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\crdel_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_app.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_except.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_lock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_log.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_mpool.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cxx\cxx_txn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_am.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\db_byteorder.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_cam.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_conv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_dispatch.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_dup.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\db_err.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\db_getlong.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_iface.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_join.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\db_log2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_meta.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_overflow.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_pr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_reclaim.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_ret.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\db_salloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\db_shash.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_upg.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_upg_opd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_vrfy.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\db\db_vrfyutil.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dbm\dbm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\env_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\env_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\env_recover.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\env\env_region.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_conv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_dup.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_func.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_meta.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_page.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_reclaim.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_upgrade.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hash\hash_verify.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hsearch\hsearch.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_conflict.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_deadlock.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_region.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lock\lock_util.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_archive.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_compare.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_findckp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_get.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_put.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log\log_register.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_alloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_bh.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_fget.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_fopen.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_fput.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_fset.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_region.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_register.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_sync.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp\mp_trickle.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mutex\mut_tas.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mutex\mutex.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_abs.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_alloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_dir.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_errno.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_fid.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_finit.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_fsync.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_handle.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_map.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_oflags.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_region.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_rename.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_root.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_rpath.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_rw.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_seek.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_sleep.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_spin.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_tmpdir.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os_win32\os_type.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\os_unlink.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_conv.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_files.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_method.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_stat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_upgrade.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qam\qam_verify.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\clib\strcasecmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\txn\txn.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\txn\txn_auto.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\txn\txn_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\txn\txn_region.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\util_log.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\common\util_sig.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\xa\xa.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\xa\xa_db.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\xa\xa_map.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/bdb/build_win32/Berkeley_DB.dsw b/VC++Files/bdb/build_win32/Berkeley_DB.dsw
index 482ac7537f0..899e31ad58d 100644
--- a/VC++Files/bdb/build_win32/Berkeley_DB.dsw
+++ b/VC++Files/bdb/build_win32/Berkeley_DB.dsw
@@ -566,4 +566,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/bdb/build_win32/db_archive.dsp b/VC++Files/bdb/build_win32/db_archive.dsp
index 4b8509950ef..b115caba486 100644
--- a/VC++Files/bdb/build_win32/db_archive.dsp
+++ b/VC++Files/bdb/build_win32/db_archive.dsp
@@ -7,16 +7,16 @@
CFG=db_archive - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_archive.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_archive.mak" CFG="db_archive - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_archive - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "db_archive - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=db_archive - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "db_archive - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_buildall.dsp b/VC++Files/bdb/build_win32/db_buildall.dsp
index 58990dbb867..1f54083d00f 100644
--- a/VC++Files/bdb/build_win32/db_buildall.dsp
+++ b/VC++Files/bdb/build_win32/db_buildall.dsp
@@ -7,23 +7,23 @@
CFG=db_buildall - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_buildall.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_buildall.mak" CFG="db_buildall - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_buildall - Win32 Release" (based on "Win32 (x86) External Target")
!MESSAGE "db_buildall - Win32 Debug" (based on "Win32 (x86) External Target")
!MESSAGE "db_buildall - Win32 Release Static" (based on\
"Win32 (x86) External Target")
!MESSAGE "db_buildall - Win32 Debug Static" (based on\
"Win32 (x86) External Target")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -105,7 +105,7 @@ CFG=db_buildall - Win32 Debug
# PROP Bsc_Name "db_buildall.bsc"
# PROP Target_Dir ""
-!ENDIF
+!ENDIF
# Begin Target
@@ -122,7 +122,7 @@ CFG=db_buildall - Win32 Debug
!ELSEIF "$(CFG)" == "db_buildall - Win32 Debug Static"
-!ENDIF
+!ENDIF
# End Target
# End Project
diff --git a/VC++Files/bdb/build_win32/db_checkpoint.dsp b/VC++Files/bdb/build_win32/db_checkpoint.dsp
index ac464a07ab8..71ee57e1693 100644
--- a/VC++Files/bdb/build_win32/db_checkpoint.dsp
+++ b/VC++Files/bdb/build_win32/db_checkpoint.dsp
@@ -7,16 +7,16 @@
CFG=db_checkpoint - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_checkpoint.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_checkpoint.mak" CFG="db_checkpoint - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_checkpoint - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "db_checkpoint - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=db_checkpoint - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "db_checkpoint - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_deadlock.dsp b/VC++Files/bdb/build_win32/db_deadlock.dsp
index 429896ded04..d9112bace47 100644
--- a/VC++Files/bdb/build_win32/db_deadlock.dsp
+++ b/VC++Files/bdb/build_win32/db_deadlock.dsp
@@ -7,16 +7,16 @@
CFG=db_deadlock - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_deadlock.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_deadlock.mak" CFG="db_deadlock - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_deadlock - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "db_deadlock - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=db_deadlock - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "db_deadlock - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_dll.dsp b/VC++Files/bdb/build_win32/db_dll.dsp
index d394e0313fd..3ec370c1d72 100644
--- a/VC++Files/bdb/build_win32/db_dll.dsp
+++ b/VC++Files/bdb/build_win32/db_dll.dsp
@@ -7,23 +7,23 @@
CFG=db_dll - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_dll.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_dll.mak" CFG="db_dll - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "db_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "db_dll - Win32 Release Static" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "db_dll - Win32 Debug Static" (based on\
"Win32 (x86) Dynamic-Link Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -141,7 +141,7 @@ LINK32=link.exe
# ADD BASE LINK32 /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb32d.dll" /fixed:no
# ADD LINK32 /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb32d.dll" /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_dump.dsp b/VC++Files/bdb/build_win32/db_dump.dsp
index f4808b5138d..dbc183166a4 100644
--- a/VC++Files/bdb/build_win32/db_dump.dsp
+++ b/VC++Files/bdb/build_win32/db_dump.dsp
@@ -7,16 +7,16 @@
CFG=db_dump - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_dump.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_dump.mak" CFG="db_dump - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_dump - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "db_dump - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=db_dump - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "db_dump - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_java.dsp b/VC++Files/bdb/build_win32/db_java.dsp
index 0a0d9dc0fcb..5866d355259 100644
--- a/VC++Files/bdb/build_win32/db_java.dsp
+++ b/VC++Files/bdb/build_win32/db_java.dsp
@@ -7,20 +7,20 @@
CFG=db_java - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_java.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_java.mak" CFG="db_java - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_java - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "db_java - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -60,20 +60,20 @@ InputPath=.\Release\libdb_java32.dll
SOURCE=$(InputPath)
"force_compilation.txt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- cd $(ProjDir)\..\java\src\com\sleepycat\db
- mkdir ..\..\..\..\classes
- echo compiling Berkeley DB classes
+ cd $(ProjDir)\..\java\src\com\sleepycat\db
+ mkdir ..\..\..\..\classes
+ echo compiling Berkeley DB classes
javac -d ../../../../classes -classpath "$(CLASSPATH);../../../../classes"\
- *.java
- echo compiling examples
- cd ..\examples
+ *.java
+ echo compiling examples
+ cd ..\examples
javac -d ../../../../classes -classpath "$(CLASSPATH);../../../../classes"\
- *.java
- echo creating jar file
+ *.java
+ echo creating jar file
cd ..\..\..\..\classes
- jar cf db.jar com\sleepycat\db\*.class
- echo Java build finished
-
+ jar cf db.jar com\sleepycat\db\*.class
+ echo Java build finished
+
# End Custom Build
!ELSEIF "$(CFG)" == "db_java - Win32 Debug"
@@ -108,23 +108,23 @@ InputPath=.\Debug\libdb_java32d.dll
SOURCE=$(InputPath)
"force_compilation.txt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- cd $(ProjDir)\..\java\src\com\sleepycat\db
- mkdir ..\..\..\..\classes
- echo compiling Berkeley DB classes
+ cd $(ProjDir)\..\java\src\com\sleepycat\db
+ mkdir ..\..\..\..\classes
+ echo compiling Berkeley DB classes
javac -g -d ../../../../classes -classpath "$(CLASSPATH);../../../../classes"\
- *.java
- echo compiling examples
+ *.java
+ echo compiling examples
javac -g -d ../../../../classes -classpath "$(CLASSPATH);../../../../classes"\
- *.java
- cd ..\examples
- echo creating jar file
+ *.java
+ cd ..\examples
+ echo creating jar file
cd ..\..\..\..\classes
- jar cf db.jar com\sleepycat\db\*.class
- echo Java build finished
-
+ jar cf db.jar com\sleepycat\db\*.class
+ echo Java build finished
+
# End Custom Build
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_load.dsp b/VC++Files/bdb/build_win32/db_load.dsp
index adec8475a88..ddd516e67fd 100644
--- a/VC++Files/bdb/build_win32/db_load.dsp
+++ b/VC++Files/bdb/build_win32/db_load.dsp
@@ -7,16 +7,16 @@
CFG=db_load - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_load.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_load.mak" CFG="db_load - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_load - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "db_load - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=db_load - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "db_load - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_printlog.dsp b/VC++Files/bdb/build_win32/db_printlog.dsp
index 8b3fbd9fe31..4e19ff7344a 100644
--- a/VC++Files/bdb/build_win32/db_printlog.dsp
+++ b/VC++Files/bdb/build_win32/db_printlog.dsp
@@ -7,16 +7,16 @@
CFG=db_printlog - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_printlog.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_printlog.mak" CFG="db_printlog - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_printlog - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "db_printlog - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=db_printlog - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "db_printlog - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_recover.dsp b/VC++Files/bdb/build_win32/db_recover.dsp
index bf07631f9b9..6419c3faf64 100644
--- a/VC++Files/bdb/build_win32/db_recover.dsp
+++ b/VC++Files/bdb/build_win32/db_recover.dsp
@@ -7,16 +7,16 @@
CFG=db_recover - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_recover.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_recover.mak" CFG="db_recover - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_recover - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "db_recover - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=db_recover - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "db_recover - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_stat.dsp b/VC++Files/bdb/build_win32/db_stat.dsp
index 3e906897e68..8cf59197d42 100644
--- a/VC++Files/bdb/build_win32/db_stat.dsp
+++ b/VC++Files/bdb/build_win32/db_stat.dsp
@@ -7,16 +7,16 @@
CFG=db_stat - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_stat.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_stat.mak" CFG="db_stat - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_stat - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "db_stat - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=db_stat - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "db_stat - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_static.dsp b/VC++Files/bdb/build_win32/db_static.dsp
index 0c355241537..5a95bf7b1c6 100644
--- a/VC++Files/bdb/build_win32/db_static.dsp
+++ b/VC++Files/bdb/build_win32/db_static.dsp
@@ -7,23 +7,23 @@
CFG=db_static - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_static.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_static.mak" CFG="db_static - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_static - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "db_static - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "db_static - Win32 Release Static" (based on\
"Win32 (x86) Static Library")
!MESSAGE "db_static - Win32 Debug Static" (based on\
"Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -114,7 +114,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo /out:"Debug/libdb32sd.lib"
# ADD LIB32 /nologo /out:"Debug_static/libdb32sd.lib"
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_static1.dsp b/VC++Files/bdb/build_win32/db_static1.dsp
new file mode 100644
index 00000000000..15498e58ca5
--- /dev/null
+++ b/VC++Files/bdb/build_win32/db_static1.dsp
@@ -0,0 +1,85 @@
+# Microsoft Developer Studio Project File - Name="db_static1" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=db_static1 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "db_static1.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "db_static1.mak" CFG="db_static1 - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "db_static1 - Win32 Release" (based on "Win32 (x86) External Target")
+!MESSAGE "db_static1 - Win32 Debug" (based on "Win32 (x86) External Target")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "db_static1 - Win32 Release"
+
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Cmd_Line "NMAKE /f db_static.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "db_static.exe"
+# PROP BASE Bsc_Name "db_static.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Cmd_Line "NMAKE /f db_static.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "db_static1.exe"
+# PROP Bsc_Name "db_static1.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF "$(CFG)" == "db_static1 - Win32 Debug"
+
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Cmd_Line "NMAKE /f db_static.mak"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "db_static.exe"
+# PROP BASE Bsc_Name "db_static.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Cmd_Line "NMAKE /f db_static.mak"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "db_static1.exe"
+# PROP Bsc_Name "db_static1.bsc"
+# PROP Target_Dir ""
+
+!ENDIF
+
+# Begin Target
+
+# Name "db_static1 - Win32 Release"
+# Name "db_static1 - Win32 Debug"
+
+!IF "$(CFG)" == "db_static1 - Win32 Release"
+
+!ELSEIF "$(CFG)" == "db_static1 - Win32 Debug"
+
+!ENDIF
+
+# Begin Source File
+
+SOURCE=.\db_static.dsp
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/bdb/build_win32/db_tcl.dsp b/VC++Files/bdb/build_win32/db_tcl.dsp
index 5a0712c3f82..ae2e1a38e9b 100644
--- a/VC++Files/bdb/build_win32/db_tcl.dsp
+++ b/VC++Files/bdb/build_win32/db_tcl.dsp
@@ -7,19 +7,19 @@
CFG=db_tcl - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_tcl.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_tcl.mak" CFG="db_tcl - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_tcl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "db_tcl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -81,7 +81,7 @@ LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 Debug/libdb32d.lib tcl83d.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb_tcl32d.dll" /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_test.dsp b/VC++Files/bdb/build_win32/db_test.dsp
index e1bb9056824..406a1369696 100644
--- a/VC++Files/bdb/build_win32/db_test.dsp
+++ b/VC++Files/bdb/build_win32/db_test.dsp
@@ -7,19 +7,19 @@
CFG=db_test - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_test.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_test.mak" CFG="db_test - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_test - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "db_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -85,7 +85,7 @@ PostBuild_Desc=Copy built executable files.
PostBuild_Cmds=copy Debug\*.exe .
# End Special Build Tool
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_upgrade.dsp b/VC++Files/bdb/build_win32/db_upgrade.dsp
index 4bb821f57e2..c2f3a748a61 100644
--- a/VC++Files/bdb/build_win32/db_upgrade.dsp
+++ b/VC++Files/bdb/build_win32/db_upgrade.dsp
@@ -7,16 +7,16 @@
CFG=db_upgrade - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_upgrade.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_upgrade.mak" CFG="db_upgrade - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_upgrade - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "db_upgrade - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=db_upgrade - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "db_upgrade - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/db_verify.dsp b/VC++Files/bdb/build_win32/db_verify.dsp
index a8112364a83..b76bd203b44 100644
--- a/VC++Files/bdb/build_win32/db_verify.dsp
+++ b/VC++Files/bdb/build_win32/db_verify.dsp
@@ -7,16 +7,16 @@
CFG=db_verify - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_verify.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "db_verify.mak" CFG="db_verify - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "db_verify - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "db_verify - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=db_verify - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "db_verify - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/ex_access.dsp b/VC++Files/bdb/build_win32/ex_access.dsp
index 8c802b1d774..5c1615c915a 100644
--- a/VC++Files/bdb/build_win32/ex_access.dsp
+++ b/VC++Files/bdb/build_win32/ex_access.dsp
@@ -7,16 +7,16 @@
CFG=ex_access - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_access.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_access.mak" CFG="ex_access - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "ex_access - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "ex_access - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=ex_access - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "ex_access - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/ex_btrec.dsp b/VC++Files/bdb/build_win32/ex_btrec.dsp
index 08bc90752f5..e687324d813 100644
--- a/VC++Files/bdb/build_win32/ex_btrec.dsp
+++ b/VC++Files/bdb/build_win32/ex_btrec.dsp
@@ -7,16 +7,16 @@
CFG=ex_btrec - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_btrec.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_btrec.mak" CFG="ex_btrec - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "ex_btrec - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "ex_btrec - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=ex_btrec - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "ex_btrec - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/ex_env.dsp b/VC++Files/bdb/build_win32/ex_env.dsp
index a46e66dac27..ade4c87d965 100644
--- a/VC++Files/bdb/build_win32/ex_env.dsp
+++ b/VC++Files/bdb/build_win32/ex_env.dsp
@@ -7,16 +7,16 @@
CFG=ex_env - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_env.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_env.mak" CFG="ex_env - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "ex_env - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "ex_env - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=ex_env - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "ex_env - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/ex_lock.dsp b/VC++Files/bdb/build_win32/ex_lock.dsp
index 0fa57a960f8..ce5ecc22b56 100644
--- a/VC++Files/bdb/build_win32/ex_lock.dsp
+++ b/VC++Files/bdb/build_win32/ex_lock.dsp
@@ -7,16 +7,16 @@
CFG=ex_lock - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_lock.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_lock.mak" CFG="ex_lock - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "ex_lock - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "ex_lock - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=ex_lock - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "ex_lock - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/ex_mpool.dsp b/VC++Files/bdb/build_win32/ex_mpool.dsp
index 3e2ee7205ce..f6ae1df52dc 100644
--- a/VC++Files/bdb/build_win32/ex_mpool.dsp
+++ b/VC++Files/bdb/build_win32/ex_mpool.dsp
@@ -7,16 +7,16 @@
CFG=ex_mpool - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_mpool.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_mpool.mak" CFG="ex_mpool - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "ex_mpool - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "ex_mpool - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=ex_mpool - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "ex_mpool - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/ex_tpcb.dsp b/VC++Files/bdb/build_win32/ex_tpcb.dsp
index fbaa67de7ac..43f7a560915 100644
--- a/VC++Files/bdb/build_win32/ex_tpcb.dsp
+++ b/VC++Files/bdb/build_win32/ex_tpcb.dsp
@@ -7,16 +7,16 @@
CFG=ex_tpcb - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_tpcb.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "ex_tpcb.mak" CFG="ex_tpcb - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "ex_tpcb - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "ex_tpcb - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=ex_tpcb - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "ex_tpcb - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/excxx_access.dsp b/VC++Files/bdb/build_win32/excxx_access.dsp
index d93894dc5b7..f817b791627 100644
--- a/VC++Files/bdb/build_win32/excxx_access.dsp
+++ b/VC++Files/bdb/build_win32/excxx_access.dsp
@@ -7,16 +7,16 @@
CFG=excxx_access - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_access.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_access.mak" CFG="excxx_access - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "excxx_access - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "excxx_access - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=excxx_access - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "excxx_access - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/excxx_btrec.dsp b/VC++Files/bdb/build_win32/excxx_btrec.dsp
index 403e438a6e1..a06904f2160 100644
--- a/VC++Files/bdb/build_win32/excxx_btrec.dsp
+++ b/VC++Files/bdb/build_win32/excxx_btrec.dsp
@@ -7,16 +7,16 @@
CFG=excxx_btrec - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_btrec.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_btrec.mak" CFG="excxx_btrec - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "excxx_btrec - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "excxx_btrec - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=excxx_btrec - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "excxx_btrec - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/excxx_env.dsp b/VC++Files/bdb/build_win32/excxx_env.dsp
index 792358ee3ac..5f1b1c0a2e4 100644
--- a/VC++Files/bdb/build_win32/excxx_env.dsp
+++ b/VC++Files/bdb/build_win32/excxx_env.dsp
@@ -7,16 +7,16 @@
CFG=excxx_env - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_env.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_env.mak" CFG="excxx_env - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "excxx_env - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "excxx_env - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=excxx_env - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "excxx_env - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/excxx_lock.dsp b/VC++Files/bdb/build_win32/excxx_lock.dsp
index d35605cb412..5fe931537a9 100644
--- a/VC++Files/bdb/build_win32/excxx_lock.dsp
+++ b/VC++Files/bdb/build_win32/excxx_lock.dsp
@@ -7,16 +7,16 @@
CFG=excxx_lock - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_lock.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_lock.mak" CFG="excxx_lock - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "excxx_lock - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "excxx_lock - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=excxx_lock - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "excxx_lock - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/excxx_mpool.dsp b/VC++Files/bdb/build_win32/excxx_mpool.dsp
index 2159e75bb9a..213202b1726 100644
--- a/VC++Files/bdb/build_win32/excxx_mpool.dsp
+++ b/VC++Files/bdb/build_win32/excxx_mpool.dsp
@@ -7,16 +7,16 @@
CFG=excxx_mpool - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_mpool.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_mpool.mak" CFG="excxx_mpool - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "excxx_mpool - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "excxx_mpool - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=excxx_mpool - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "excxx_mpool - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/excxx_tpcb.dsp b/VC++Files/bdb/build_win32/excxx_tpcb.dsp
index 9033daa6cfe..ef89fc0de87 100644
--- a/VC++Files/bdb/build_win32/excxx_tpcb.dsp
+++ b/VC++Files/bdb/build_win32/excxx_tpcb.dsp
@@ -7,16 +7,16 @@
CFG=excxx_tpcb - Win32 Debug Static
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_tpcb.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "excxx_tpcb.mak" CFG="excxx_tpcb - Win32 Debug Static"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "excxx_tpcb - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "excxx_tpcb - Win32 Debug" (based on\
@@ -25,7 +25,7 @@ CFG=excxx_tpcb - Win32 Debug Static
"Win32 (x86) Console Application")
!MESSAGE "excxx_tpcb - Win32 Debug Static" (based on\
"Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -131,7 +131,7 @@ LINK32=link.exe
# ADD BASE LINK32 Debug_static/libdb32d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
# ADD LINK32 Debug_static/libdb32sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /fixed:no
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/bdb/build_win32/libdb.def b/VC++Files/bdb/build_win32/libdb.def
new file mode 100644
index 00000000000..a3b4cb3b26b
--- /dev/null
+++ b/VC++Files/bdb/build_win32/libdb.def
@@ -0,0 +1,151 @@
+; $Id: libdb.def,v 11.21 2001/01/04 15:07:33 dda Exp $
+
+DESCRIPTION 'Berkeley DB 3.2 Library'
+EXPORTS
+ lock_get @1
+ lock_id @2
+ lock_put @3
+ lock_vec @4
+ log_compare @5
+ log_file @6
+ log_flush @7
+ log_get @8
+ log_put @9
+ log_register @10
+ log_unregister @11
+ memp_fclose @12
+ memp_fget @13
+ memp_fopen @14
+ memp_fput @15
+ memp_fset @16
+ memp_fsync @17
+ memp_register @18
+ memp_sync @19
+ txn_abort @20
+ txn_begin @21
+ txn_checkpoint @22
+ txn_commit @23
+ txn_prepare @24
+ db_version @25
+ memp_stat @26
+ log_archive @27
+ lock_detect @28
+ txn_id @29
+ txn_stat @30
+ memp_trickle @31
+ log_stat @32
+ lock_stat @33
+ db_create @34
+ db_env_create @35
+ db_strerror @36
+ db_xa_switch @37
+ db_env_set_func_close @38
+ db_env_set_func_dirfree @39
+ db_env_set_func_dirlist @40
+ db_env_set_func_exists @41
+ db_env_set_func_free @42
+ db_env_set_func_fsync @43
+ db_env_set_func_ioinfo @44
+ db_env_set_func_malloc @45
+ db_env_set_func_map @46
+ db_env_set_func_open @47
+ db_env_set_func_read @48
+ db_env_set_func_realloc @49
+ db_env_set_func_rename @50
+ db_env_set_func_sleep @51
+ db_env_set_func_unlink @52
+ db_env_set_func_unmap @53
+ db_env_set_func_write @54
+ db_env_set_func_yield @55
+; FREE @56
+ db_env_set_pageyield @57
+ db_env_set_panicstate @58
+ db_env_set_region_init @59
+ db_env_set_tas_spins @60
+; these are only for testing
+ __db_loadme @201
+ __ham_func2 @202
+ __ham_func3 @203
+ __ham_func4 @204
+ __ham_func5 @205
+ __db_hcreate @206
+ __db_hsearch @207
+ __db_hdestroy @208
+ __db_dbm_init @209
+ __db_dbm_delete @210
+ __db_dbm_fetch @211
+ __db_dbm_store @212
+ __db_dbm_firstkey @213
+ __db_dbm_nextkey @214
+ __db_dbm_close @215
+ __db_ndbm_open @216
+ __db_ndbm_store @217
+ __db_ndbm_rdonly @218
+ __db_ndbm_pagfno @219
+ __db_ndbm_nextkey @220
+ __db_ndbm_firstkey @221
+ __db_ndbm_fetch @222
+ __db_ndbm_error @223
+ __db_ndbm_dirfno @224
+ __db_ndbm_delete @225
+ __db_ndbm_close @226
+ __db_ndbm_clearerr @227
+ __lock_dump_region @228
+ __memp_dump_region @229
+ __os_closehandle @230
+ __os_openhandle @231
+ __os_strdup @232
+ __db_r_attach @233
+ __db_r_detach @234
+ __db_tas_mutex_init @235
+ __db_tas_mutex_lock @236
+ __db_tas_mutex_unlock @237
+ __os_read @238
+ __os_write @239
+ __os_open @240
+ __os_ioinfo @241
+ __os_free @242
+ __os_malloc @243
+ __os_freestr @244
+ __os_calloc @245
+ __ham_test @246
+; these are needed for linking tools
+ __db_dump @401
+ __db_rpath @402
+ __db_dispatch @403
+ __db_err @404
+ __db_init_print @405
+ __txn_init_print @406
+ __log_init_print @407
+ __ham_init_print @408
+ __bam_init_print @409
+ __db_jump @410
+ __ham_pgin @411
+ __ham_pgout @412
+ __bam_pgin @413
+ __bam_pgout @414
+ __db_omode @415
+ __db_prdbt @416
+ __os_sleep @417
+ __db_e_stat @420
+ __db_getlong @421
+ __os_get_errno @422
+ __os_set_errno @423
+ __ham_get_meta @424
+ __ham_release_meta @425
+ __qam_init_print @426
+ __crdel_init_print @427
+ __qam_pgin_out @428
+ __db_pgin @429
+ __db_pgout @430
+ __db_getulong @431
+ __db_util_sigresend @432
+ __db_util_siginit @433
+ __db_util_interrupted @434
+ __db_util_logset @435
+ __db_prheader @436
+ __db_prfooter @437
+ __db_verify_callback @438
+ __db_verify_internal @439
+ __os_yield @440
+ __db_global_values @441
diff --git a/VC++Files/bdb/build_win32/libdb_tcl.def b/VC++Files/bdb/build_win32/libdb_tcl.def
new file mode 100644
index 00000000000..a18459beaba
--- /dev/null
+++ b/VC++Files/bdb/build_win32/libdb_tcl.def
@@ -0,0 +1,35 @@
+; $Id: libdb_tcl.def,v 11.2 1999/11/21 23:10:00 bostic Exp $
+
+DESCRIPTION 'Berkeley DB TCL interface Library'
+EXPORTS
+ Db_tcl_Init
+ bdb_DbmCommand
+ bdb_HCommand
+ bdb_NdbmOpen
+ bdb_RandCommand
+ db_Cmd
+ dbc_Cmd
+ env_Cmd
+ ndbm_Cmd
+ tcl_EnvRemove
+ tcl_LockDetect
+ tcl_LockGet
+ tcl_LockStat
+ tcl_LockVec
+ tcl_LogArchive
+ tcl_LogCompare
+ tcl_LogFile
+ tcl_LogFlush
+ tcl_LogGet
+ tcl_LogPut
+ tcl_LogRegister
+ tcl_LogStat
+ tcl_LogUnregister
+ tcl_Mp
+ tcl_MpStat
+ tcl_MpSync
+ tcl_MpTrickle
+ tcl_Txn
+ tcl_TxnCheckpoint
+ tcl_TxnStat
+ txn_Cmd
diff --git a/VC++Files/client/mysql.dsp b/VC++Files/client/mysql.dsp
index 4c9819bacde..9910718778e 100644
--- a/VC++Files/client/mysql.dsp
+++ b/VC++Files/client/mysql.dsp
@@ -7,25 +7,25 @@
CFG=mysql - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysql.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysql.mak" CFG="mysql - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysql - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "mysql - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "mysql - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_release/mysql.exe" /libpath:"..\lib_release\\"
# SUBTRACT LINK32 /incremental:yes
@@ -68,17 +68,18 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysql.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
-!ENDIF
+!ENDIF
# Begin Target
@@ -86,6 +87,10 @@ LINK32=link.exe
# Name "mysql - Win32 Debug"
# Begin Source File
+SOURCE=..\mysys\my_gethostbyname.c
+# End Source File
+# Begin Source File
+
SOURCE=.\mysql.cpp
!IF "$(CFG)" == "mysql - Win32 Release"
@@ -94,7 +99,7 @@ SOURCE=.\mysql.cpp
!ELSEIF "$(CFG)" == "mysql - Win32 Debug"
-!ENDIF
+!ENDIF
# End Source File
# End Target
diff --git a/VC++Files/client/mysqladmin.dsp b/VC++Files/client/mysqladmin.dsp
index 278bcdae8b0..2c762cd8a24 100644
--- a/VC++Files/client/mysqladmin.dsp
+++ b/VC++Files/client/mysqladmin.dsp
@@ -7,25 +7,25 @@
CFG=mysqladmin - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqladmin.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqladmin.mak" CFG="mysqladmin - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqladmin - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqladmin - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "mysqladmin - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqladmin.exe" /libpath:"..\lib_release\\"
@@ -67,17 +67,18 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqladmin.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/client/mysqlcheck.dsp b/VC++Files/client/mysqlcheck.dsp
index b334c0a8f1c..30e7a365f04 100644
--- a/VC++Files/client/mysqlcheck.dsp
+++ b/VC++Files/client/mysqlcheck.dsp
@@ -7,18 +7,18 @@
CFG=mysqlcheck - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlcheck.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlcheck.mak" CFG="mysqlcheck - Win32 Release"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqlcheck - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
diff --git a/VC++Files/client/mysqlclient.dsp b/VC++Files/client/mysqlclient.dsp
index d4de119e51c..28693f32e95 100644
--- a/VC++Files/client/mysqlclient.dsp
+++ b/VC++Files/client/mysqlclient.dsp
@@ -7,25 +7,25 @@
CFG=mysqlclient - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlclient.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlclient.mak" CFG="mysqlclient - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqlclient - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "mysqlclient - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "mysqlclient - Win32 Release"
@@ -41,14 +41,14 @@ RSC=rc.exe
# PROP Intermediate_Dir "release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../zlib" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_TLS" /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_TLS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LIB32=link.exe -lib
+LIB32=xilink6.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_release\mysqlclient.lib"
@@ -65,17 +65,18 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Zi /Od /I "../include" /I "../zlib" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /D "USE_TLS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /D "USE_TLS" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LIB32=link.exe -lib
+LIB32=xilink6.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_debug\mysqlclient.lib"
-!ENDIF
+!ENDIF
# Begin Target
@@ -131,6 +132,10 @@ SOURCE="..\strings\ctype-gbk.c"
# End Source File
# Begin Source File
+SOURCE="..\strings\ctype-latin1_de.c"
+# End Source File
+# Begin Source File
+
SOURCE="..\strings\ctype-sjis.c"
# End Source File
# Begin Source File
@@ -167,18 +172,6 @@ SOURCE=..\libmysql\get_password.c
# End Source File
# Begin Source File
-SOURCE=..\mysys\getopt.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\getopt1.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\getvar.c
-# End Source File
-# Begin Source File
-
SOURCE=..\strings\int2str.c
# End Source File
# Begin Source File
@@ -227,6 +220,19 @@ SOURCE=..\mysys\mf_iocache.c
# End Source File
# Begin Source File
+SOURCE=..\mysys\mf_iocache2.c
+
+!IF "$(CFG)" == "mysqlclient - Win32 Release"
+
+!ELSEIF "$(CFG)" == "mysqlclient - Win32 Debug"
+
+# ADD CPP /Od
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
SOURCE=..\mysys\mf_loadpath.c
# End Source File
# Begin Source File
@@ -260,6 +266,7 @@ SOURCE=..\mysys\my_alloc.c
# Begin Source File
SOURCE=..\mysys\my_compress.c
+# ADD CPP /I "../zlib"
# End Source File
# Begin Source File
@@ -291,6 +298,10 @@ SOURCE=..\mysys\my_gethostbyname.c
# End Source File
# Begin Source File
+SOURCE=..\mysys\my_getopt.c
+# End Source File
+# Begin Source File
+
SOURCE=..\mysys\my_getwd.c
# End Source File
# Begin Source File
@@ -339,6 +350,10 @@ SOURCE=..\mysys\my_realloc.c
# End Source File
# Begin Source File
+SOURCE=..\mysys\my_rename.c
+# End Source File
+# Begin Source File
+
SOURCE=..\mysys\my_seek.c
# End Source File
# Begin Source File
@@ -347,6 +362,14 @@ SOURCE=..\mysys\my_static.c
# End Source File
# Begin Source File
+SOURCE=..\mysys\my_symlink.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_symlink2.c
+# End Source File
+# Begin Source File
+
SOURCE=..\mysys\my_tempnam.c
# End Source File
# Begin Source File
@@ -355,6 +378,10 @@ SOURCE=..\mysys\my_thr_init.c
# End Source File
# Begin Source File
+SOURCE=..\mysys\my_vsnprintf.c
+# End Source File
+# Begin Source File
+
SOURCE=..\mysys\my_wincond.c
# End Source File
# Begin Source File
@@ -371,7 +398,7 @@ SOURCE=.\mysys_priv.h
# End Source File
# Begin Source File
-SOURCE=..\libmysql\net.c
+SOURCE=..\sql\net_serv.cpp
# End Source File
# Begin Source File
@@ -463,7 +490,19 @@ SOURCE=..\mysys\typelib.c
# End Source File
# Begin Source File
-SOURCE=..\sql\violite.c
+SOURCE=..\vio\vio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viosocket.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viossl.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viosslfactories.c
# End Source File
# End Target
# End Project
diff --git a/VC++Files/client/mysqlclient.dsw b/VC++Files/client/mysqlclient.dsw
index 9c08bbf0407..0f35d0c2253 100644
--- a/VC++Files/client/mysqlclient.dsw
+++ b/VC++Files/client/mysqlclient.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/client/mysqldump.dsp b/VC++Files/client/mysqldump.dsp
index 448ba126153..d36664e09ce 100644
--- a/VC++Files/client/mysqldump.dsp
+++ b/VC++Files/client/mysqldump.dsp
@@ -7,25 +7,25 @@
CFG=mysqldump - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqldump.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqldump.mak" CFG="mysqldump - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqldump - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqldump - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "mysqldump - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqldump.exe" /libpath:"..\lib_release\\"
@@ -67,17 +67,18 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_debug/mysqldump.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqldump.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
-!ENDIF
+!ENDIF
# Begin Target
@@ -94,7 +95,7 @@ SOURCE=.\mysqldump.c
# ADD CPP /W3
# SUBTRACT CPP /YX
-!ENDIF
+!ENDIF
# End Source File
# End Target
diff --git a/VC++Files/client/mysqlimport.dsp b/VC++Files/client/mysqlimport.dsp
index 5de3b68dd4e..a8b239d226f 100644
--- a/VC++Files/client/mysqlimport.dsp
+++ b/VC++Files/client/mysqlimport.dsp
@@ -7,25 +7,25 @@
CFG=mysqlimport - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlimport.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlimport.mak" CFG="mysqlimport - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqlimport - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqlimport - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "mysqlimport - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlimport.exe" /libpath:"..\lib_release\\"
# SUBTRACT LINK32 /incremental:yes
@@ -68,17 +68,18 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlimport.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/client/mysqlshow.dsp b/VC++Files/client/mysqlshow.dsp
index 329f128d1b6..26705465fec 100644
--- a/VC++Files/client/mysqlshow.dsp
+++ b/VC++Files/client/mysqlshow.dsp
@@ -7,25 +7,25 @@
CFG=mysqlshow - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlshow.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlshow.mak" CFG="mysqlshow - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqlshow - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqlshow - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "mysqlshow - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlshow.exe" /libpath:"..\lib_release\\"
@@ -67,17 +67,18 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_debug/mysqlshow.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlshow.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/comp_err/comp_err.dsp b/VC++Files/comp_err/comp_err.dsp
index 784266f4016..deaf0627262 100644
--- a/VC++Files/comp_err/comp_err.dsp
+++ b/VC++Files/comp_err/comp_err.dsp
@@ -7,24 +7,24 @@
CFG=comp_err - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "comp_err.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "comp_err.mak" CFG="comp_err - Win32 Release"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "comp_err - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
@@ -33,8 +33,8 @@ RSC=rc.exe
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -44,7 +44,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\lib_release\mysys.lib wsock32.lib ..\lib_release\strings.lib ..\lib_release\dbug.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"LIBC.lib" /out:"Release/comp-err.exe"
# Begin Target
diff --git a/VC++Files/contrib/asm386/zlibvc.dsp b/VC++Files/contrib/asm386/zlibvc.dsp
index a70d4d4a6b0..63d8fee6511 100644
--- a/VC++Files/contrib/asm386/zlibvc.dsp
+++ b/VC++Files/contrib/asm386/zlibvc.dsp
@@ -8,16 +8,16 @@
CFG=zlibvc - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "zlibvc.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "zlibvc.mak" CFG="zlibvc - Win32 Release"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\
@@ -26,7 +26,7 @@ CFG=zlibvc - Win32 Release
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\
"Win32 (x86) Dynamic-Link Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -191,7 +191,7 @@ LINK32=link.exe
# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll"
# SUBTRACT LINK32 /pdb:none
-!ENDIF
+!ENDIF
# Begin Target
@@ -216,13 +216,13 @@ SOURCE=.\adler32.c
DEP_CPP_ADLER=\
".\zconf.h"\
".\zlib.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -238,13 +238,13 @@ SOURCE=.\compress.c
DEP_CPP_COMPR=\
".\zconf.h"\
".\zlib.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -260,13 +260,13 @@ SOURCE=.\crc32.c
DEP_CPP_CRC32=\
".\zconf.h"\
".\zlib.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -284,13 +284,13 @@ DEP_CPP_DEFLA=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -307,7 +307,7 @@ SOURCE=.\gvmat32c.c
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -324,13 +324,13 @@ DEP_CPP_GZIO_=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -351,13 +351,13 @@ DEP_CPP_INFBL=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -379,13 +379,13 @@ DEP_CPP_INFCO=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -407,13 +407,13 @@ DEP_CPP_INFFA=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -431,13 +431,13 @@ DEP_CPP_INFLA=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -455,13 +455,13 @@ DEP_CPP_INFTR=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -482,13 +482,13 @@ DEP_CPP_INFUT=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -506,13 +506,13 @@ DEP_CPP_TREES=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -528,13 +528,13 @@ SOURCE=.\uncompr.c
DEP_CPP_UNCOM=\
".\zconf.h"\
".\zlib.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -551,7 +551,7 @@ SOURCE=.\unzip.c
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -568,7 +568,7 @@ SOURCE=.\zip.c
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -593,13 +593,13 @@ DEP_CPP_ZUTIL=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# End Group
diff --git a/VC++Files/contrib/asm386/zlibvc.dsw b/VC++Files/contrib/asm386/zlibvc.dsw
index 493cd870365..041a77a06a2 100644
--- a/VC++Files/contrib/asm386/zlibvc.dsw
+++ b/VC++Files/contrib/asm386/zlibvc.dsw
@@ -38,4 +38,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/contrib/minizip/zlibvc.dsp b/VC++Files/contrib/minizip/zlibvc.dsp
index a70d4d4a6b0..63d8fee6511 100644
--- a/VC++Files/contrib/minizip/zlibvc.dsp
+++ b/VC++Files/contrib/minizip/zlibvc.dsp
@@ -8,16 +8,16 @@
CFG=zlibvc - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "zlibvc.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "zlibvc.mak" CFG="zlibvc - Win32 Release"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\
@@ -26,7 +26,7 @@ CFG=zlibvc - Win32 Release
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\
"Win32 (x86) Dynamic-Link Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -191,7 +191,7 @@ LINK32=link.exe
# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll"
# SUBTRACT LINK32 /pdb:none
-!ENDIF
+!ENDIF
# Begin Target
@@ -216,13 +216,13 @@ SOURCE=.\adler32.c
DEP_CPP_ADLER=\
".\zconf.h"\
".\zlib.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -238,13 +238,13 @@ SOURCE=.\compress.c
DEP_CPP_COMPR=\
".\zconf.h"\
".\zlib.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -260,13 +260,13 @@ SOURCE=.\crc32.c
DEP_CPP_CRC32=\
".\zconf.h"\
".\zlib.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -284,13 +284,13 @@ DEP_CPP_DEFLA=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -307,7 +307,7 @@ SOURCE=.\gvmat32c.c
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -324,13 +324,13 @@ DEP_CPP_GZIO_=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -351,13 +351,13 @@ DEP_CPP_INFBL=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -379,13 +379,13 @@ DEP_CPP_INFCO=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -407,13 +407,13 @@ DEP_CPP_INFFA=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -431,13 +431,13 @@ DEP_CPP_INFLA=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -455,13 +455,13 @@ DEP_CPP_INFTR=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -482,13 +482,13 @@ DEP_CPP_INFUT=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -506,13 +506,13 @@ DEP_CPP_TREES=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -528,13 +528,13 @@ SOURCE=.\uncompr.c
DEP_CPP_UNCOM=\
".\zconf.h"\
".\zlib.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -551,7 +551,7 @@ SOURCE=.\unzip.c
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -568,7 +568,7 @@ SOURCE=.\zip.c
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -593,13 +593,13 @@ DEP_CPP_ZUTIL=\
".\zconf.h"\
".\zlib.h"\
".\zutil.h"\
-
+
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
-!ENDIF
+!ENDIF
# End Source File
# End Group
diff --git a/VC++Files/contrib/minizip/zlibvc.dsw b/VC++Files/contrib/minizip/zlibvc.dsw
index 493cd870365..041a77a06a2 100644
--- a/VC++Files/contrib/minizip/zlibvc.dsw
+++ b/VC++Files/contrib/minizip/zlibvc.dsw
@@ -38,4 +38,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/dbug/dbug.dsp b/VC++Files/dbug/dbug.dsp
index 11721da98d6..5db7b05175b 100644
--- a/VC++Files/dbug/dbug.dsp
+++ b/VC++Files/dbug/dbug.dsp
@@ -7,19 +7,19 @@
CFG=dbug - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "dbug.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "dbug.mak" CFG="dbug - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "dbug - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "dbug - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -76,7 +76,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_debug\dbug.lib"
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/dbug/dbug.dsw b/VC++Files/dbug/dbug.dsw
index a0cd4da7891..b1e978b2c8f 100644
--- a/VC++Files/dbug/dbug.dsw
+++ b/VC++Files/dbug/dbug.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/heap/heap.dsp b/VC++Files/heap/heap.dsp
index c21c3139519..1edeec80e9b 100644
--- a/VC++Files/heap/heap.dsp
+++ b/VC++Files/heap/heap.dsp
@@ -7,19 +7,19 @@
CFG=heap - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "heap.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "heap.mak" CFG="heap - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "heap - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "heap - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -76,7 +76,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_debug\heap.lib"
-!ENDIF
+!ENDIF
# Begin Target
@@ -128,7 +128,7 @@ SOURCE=.\hp_hash.c
# SUBTRACT CPP /YX
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
diff --git a/VC++Files/innobase/innobase.dsp b/VC++Files/innobase/innobase.dsp
index b458c62a7cd..83419fc53cc 100644
--- a/VC++Files/innobase/innobase.dsp
+++ b/VC++Files/innobase/innobase.dsp
@@ -4,107 +4,136 @@
# TARGTYPE "Win32 (x86) Static Library" 0x0104
-CFG=innobase - Win32 Max
+CFG=INNOBASE - WIN32 RELEASE
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "innobase.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "innobase.mak" CFG="innobase - Win32 Max"
-!MESSAGE
+!MESSAGE
+!MESSAGE NMAKE /f "innobase.mak" CFG="INNOBASE - WIN32 RELEASE"
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "innobase - Win32 Max" (based on "Win32 (x86) Static Library")
-!MESSAGE "innobase - Win32 Max nt" (based on "Win32 (x86) Static Library")
+!MESSAGE
!MESSAGE "innobase - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE "innobase - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "innobase - Win32 nt" (based on "Win32 (x86) Static Library")
+!MESSAGE "innobase - Win32 Max nt" (based on "Win32 (x86) Static Library")
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
-!IF "$(CFG)" == "innobase - Win32 Max"
+!IF "$(CFG)" == "innobase - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "innobase___Win32_Max"
-# PROP BASE Intermediate_Dir "innobase___Win32_Max"
+# PROP BASE Output_Dir "innobase___Win32_Debug"
+# PROP BASE Intermediate_Dir "innobase___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "innobase___Win32_Max"
-# PROP Intermediate_Dir "innobase___Win32_Max"
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /I "../zlib../sql" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /GX /Z7 /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x416 /d "NDEBUG"
# ADD RSC /l 0x416 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LIB32=link.exe -lib
+LIB32=xilink6.exe -lib
# ADD BASE LIB32 /nologo /out:"..\lib_release\innobase-nt.lib"
+# ADD LIB32 /nologo /out:"..\lib_debug\innodb.lib"
+
+!ELSEIF "$(CFG)" == "innobase - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "innobase___Win32_Release0"
+# PROP BASE Intermediate_Dir "innobase___Win32_Release0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=xilink6.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_release\innodb.lib"
# ADD LIB32 /nologo /out:"..\lib_release\innodb.lib"
-!ELSEIF "$(CFG)" == "innobase - Win32 Max nt"
+!ELSEIF "$(CFG)" == "innobase - Win32 nt"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "innobase___Win32_Max_nt"
-# PROP BASE Intermediate_Dir "innobase___Win32_Max_nt"
+# PROP BASE Output_Dir "innobase___Win32_nt"
+# PROP BASE Intermediate_Dir "innobase___Win32_nt"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "innobase___Win32_Max_nt"
-# PROP Intermediate_Dir "innobase___Win32_Max_nt"
+# PROP Output_Dir "nt"
+# PROP Intermediate_Dir "nt"
# PROP Target_Dir ""
-# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /I "../zlib" /I "../sql" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x416 /d "NDEBUG"
# ADD RSC /l 0x416 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo /out:"..\lib_release\innobase-nt.lib"
-# ADD LIB32 /nologo /out:"..\lib_release\innodb-nt.lib"
+LIB32=xilink6.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_release\innodb.lib"
+# ADD LIB32 /nologo /out:"..\lib_release\innodb.lib"
-!ELSEIF "$(CFG)" == "innobase - Win32 Debug"
+!ELSEIF "$(CFG)" == "innobase - Win32 Max nt"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "innobase___Win32_Debug"
-# PROP BASE Intermediate_Dir "innobase___Win32_Debug"
+# PROP BASE Output_Dir "innobase___Win32_Max_nt"
+# PROP BASE Intermediate_Dir "innobase___Win32_Max_nt"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "innobase___Win32_Debug"
-# PROP Intermediate_Dir "innobase___Win32_Debug"
+# PROP Output_Dir "max_nt"
+# PROP Intermediate_Dir "max_nt"
# PROP Target_Dir ""
-# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /GX /Z7 /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "__NT__" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "../innobase/include" /I "../include" /D "NDEBUG" /D "_LIB" /D "_WIN32" /D "WIN32" /D "_MBCS" /D "MYSQL_SERVER" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x416 /d "NDEBUG"
# ADD RSC /l 0x416 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo /out:"..\lib_release\innobase-nt.lib"
-# ADD LIB32 /nologo /out:"..\lib_debug\innodb.lib"
+LIB32=xilink6.exe -lib
+# ADD BASE LIB32 /nologo /out:"..\lib_release\innodb.lib"
+# ADD LIB32 /nologo /out:"..\lib_release\innodb.lib"
-!ENDIF
+!ENDIF
# Begin Target
-# Name "innobase - Win32 Max"
-# Name "innobase - Win32 Max nt"
# Name "innobase - Win32 Debug"
+# Name "innobase - Win32 Release"
+# Name "innobase - Win32 nt"
+# Name "innobase - Win32 Max nt"
# Begin Source File
SOURCE=.\btr\btr0btr.c
diff --git a/VC++Files/isam/isam.dsp b/VC++Files/isam/isam.dsp
index 32832919654..12047145f6d 100644
--- a/VC++Files/isam/isam.dsp
+++ b/VC++Files/isam/isam.dsp
@@ -7,19 +7,19 @@
CFG=isam - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "isam.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "isam.mak" CFG="isam - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "isam - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "isam - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -76,7 +76,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_Debug\isam.lib"
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/isam/isam.dsw b/VC++Files/isam/isam.dsw
index 6874c8cf4c3..c18224a6d73 100644
--- a/VC++Files/isam/isam.dsw
+++ b/VC++Files/isam/isam.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/isamchk/isamchk.dsp b/VC++Files/isamchk/isamchk.dsp
index e02125a44fd..0e8e2b04bd7 100644
--- a/VC++Files/isamchk/isamchk.dsp
+++ b/VC++Files/isamchk/isamchk.dsp
@@ -7,25 +7,25 @@
CFG=isamchk - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "isamchk.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "isamchk.mak" CFG="isamchk - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "isamchk - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "isamchk - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "isamchk - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /machine:I386 /out:"../client_release/isamchk.exe"
# SUBTRACT LINK32 /pdb:none
@@ -68,18 +68,19 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../isam" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../isam" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /Fr /YX
# ADD BASE RSC /l 0x41d /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/isamchk.exe" /pdbtype:sept
# SUBTRACT LINK32 /verbose /pdb:none
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/libmysql/libmySQL.dsp b/VC++Files/libmysql/libmySQL.dsp
deleted file mode 100644
index 24c44a43652..00000000000
--- a/VC++Files/libmysql/libmySQL.dsp
+++ /dev/null
@@ -1,440 +0,0 @@
-# Microsoft Developer Studio Project File - Name="libmySQL" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=libmySQL - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "libmySQL.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "libmySQL.mak" CFG="libmySQL - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "libmySQL - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "libmySQL - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "libmySQL - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "release"
-# PROP Intermediate_Dir "release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "." /I "..\include" /I "../zlib" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_TLS" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
-# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"libmysql.def" /out:"../lib_release/libmySQL.dll" /libpath:"." /libpath:"..\lib_release"
-# SUBTRACT LINK32 /pdb:none
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Desc=Move DLL export lib
-PostBuild_Cmds=copy release\libmysql.lib ..\lib_release
-# End Special Build Tool
-
-!ELSEIF "$(CFG)" == "libmySQL - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "debug"
-# PROP Intermediate_Dir "debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "." /I "..\include" /I "..\zlib" /D "_DEBUG" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /FD /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 zlib.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /def:"libmysql.def" /out:"../lib_debug/libmySQL.dll" /pdbtype:sept /libpath:"." /libpath:"..\lib_debug"
-# SUBTRACT LINK32 /pdb:none
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Desc=Move DLL export lib
-PostBuild_Cmds=copy ..\lib_debug\libmysql.dll C:\winnt\system32\ copy debug\libmysql.lib ..\lib_debug\
-# End Special Build Tool
-
-!ENDIF
-
-# Begin Target
-
-# Name "libmySQL - Win32 Release"
-# Name "libmySQL - Win32 Debug"
-# Begin Source File
-
-SOURCE=..\mysys\array.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\bchange.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\bmove.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\bmove_upp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\charset.c
-# End Source File
-# Begin Source File
-
-SOURCE="..\strings\ctype-big5.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\strings\ctype-czech.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\strings\ctype-euc_kr.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\strings\ctype-gb2312.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\strings\ctype-gbk.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\strings\ctype-sjis.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\strings\ctype-tis620.c"
-# End Source File
-# Begin Source File
-
-SOURCE="..\strings\ctype-ujis.c"
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\ctype.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\dbug\dbug.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\default.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\dll.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\errmsg.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\errors.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\get_password.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\int2str.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\is_prefix.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\libmysql.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\Libmysql.def
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\list.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\llstr.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\longlong2str.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\mf_casecnv.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\mf_dirname.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\mf_fn_ext.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\mf_format.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\mf_loadpath.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\mf_pack.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\mf_unixpath.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\mf_wcomp.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\mulalloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_alloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_compress.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_create.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_delete.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_div.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_error.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_fopen.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_fstream.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_gethostbyname.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_getwd.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_init.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_lib.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_malloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_messnc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_net.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_once.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_open.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_pthread.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_read.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_realloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_static.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_tempnam.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_thr_init.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_wincond.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_winthread.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\my_write.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\client\mysys_priv.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\net.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\password.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\safemalloc.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\client\select_test.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\client\sql_string.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\client\sql_string.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\str2int.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\strcend.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\strcont.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\strend.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\strfill.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\string.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\strinstr.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\strmake.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\strmov.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\strnlen.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\strnmov.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\strings\strxmov.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\thr_mutex.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\mysys\typelib.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\sql\violite.c
-# End Source File
-# End Target
-# End Project
diff --git a/VC++Files/libmysql/libmysql.dsp b/VC++Files/libmysql/libmysql.dsp
new file mode 100644
index 00000000000..923cac29c37
--- /dev/null
+++ b/VC++Files/libmysql/libmysql.dsp
@@ -0,0 +1,489 @@
+# Microsoft Developer Studio Project File - Name="libmysql" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=libmysql - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "libmysql.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "libmysql.mak" CFG="libmysql - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "libmysql - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "libmysql - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=xicl6.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "libmysql - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "." /I "..\include" /I "../zlib" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_TLS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"libmysql.def" /out:"..\lib_release\libmysql.dll" /libpath:"." /libpath:"..\lib_release"
+# SUBTRACT LINK32 /pdb:none
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Desc=Move DLL export lib
+PostBuild_Cmds=xcopy release\libmysql.lib ..\lib_release /y
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "libmysql - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "." /I "..\include" /I "../zlib" /D "_DEBUG" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 zlib.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /def:"libmysql.def" /out:"..\lib_debug\libmysql.dll" /pdbtype:sept /libpath:"." /libpath:"..\lib_debug"
+# SUBTRACT LINK32 /pdb:none
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Desc=Move DLL export lib
+PostBuild_Cmds=xcopy ..\lib_debug\libmysql.dll C:\winnt\system32\ /y xcopy debug\libmysql.lib ..\lib_debug\ /y
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "libmysql - Win32 Release"
+# Name "libmysql - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\mysys\array.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\bchange.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\bmove.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\bmove_upp.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\charset.c
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-big5.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-czech.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-euc_kr.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-gb2312.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-gbk.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-latin1_de.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-sjis.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-tis620.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\strings\ctype-ujis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\ctype.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\dbug\dbug.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\default.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dll.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\errmsg.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\errors.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\get_password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\int2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\is_prefix.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libmysql.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\Libmysql.def
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\list.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\llstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\longlong2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_casecnv.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_dirname.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_fn_ext.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_format.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_loadpath.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_pack.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_path.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_unixpath.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mf_wcomp.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\mulalloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_alloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_create.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_delete.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_div.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_error.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_fopen.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_fstream.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_gethostbyname.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_getopt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_getwd.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_init.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_lib.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_malloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_messnc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_net.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_once.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_open.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_pthread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_read.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_realloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_rename.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_static.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_symlink.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_symlink2.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_tempnam.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_thr_init.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_vsnprintf.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_wincond.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_winthread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\my_write.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\client\mysys_priv.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\net_serv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\safemalloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\client\select_test.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\sha1.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\client\sql_string.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\client\sql_string.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\str2int.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strcend.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strcont.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strend.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strfill.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\string.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strinstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strmake.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strnlen.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strnmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strtoll.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\strings\strxmov.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\thr_mutex.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\mysys\typelib.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\vio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viosocket.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viossl.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\vio\viosslfactories.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/libmysql/libmysql.dsw b/VC++Files/libmysql/libmysql.dsw
index fe121fa65cc..36d5b9b330b 100644
--- a/VC++Files/libmysql/libmysql.dsw
+++ b/VC++Files/libmysql/libmysql.dsw
@@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 5.00
###############################################################################
-Project: "libmySQL"=".\libmySQL.dsp" - Package Owner=<4>
+Project: "libmysql"=".\libmysql.dsp" - Package Owner=<4>
Package=<5>
{{{
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/libmysqld/examples/test_libmysqld.dsp b/VC++Files/libmysqld/examples/test_libmysqld.dsp
new file mode 100644
index 00000000000..d5fd0a0982d
--- /dev/null
+++ b/VC++Files/libmysqld/examples/test_libmysqld.dsp
@@ -0,0 +1,66 @@
+# Microsoft Developer Studio Project File - Name="test_libmysqld" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=test_libmysqld - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "test_libmysqld.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "test_libmysqld.mak" CFG="test_libmysqld - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "test_libmysqld - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /I "../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "DBUG_OFF" /FR /YX /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"LIBCMTD" /out:"Release/mysql-server.exe"
+# Begin Target
+
+# Name "test_libmysqld - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\client\mysql.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\lib_release\libmysqld.lib
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/libmysqld/libmysqld.def b/VC++Files/libmysqld/libmysqld.def
new file mode 100644
index 00000000000..c6615ee971c
--- /dev/null
+++ b/VC++Files/libmysqld/libmysqld.def
@@ -0,0 +1,65 @@
+LIBRARY LIBMYSQLD
+DESCRIPTION 'MySQL 4.0 Embedded Server Library'
+VERSION 4.0
+EXPORTS
+ mysql_server_end
+ mysql_server_init
+ mysql_use_result
+ mysql_thread_safe
+ mysql_thread_id
+ mysql_store_result
+ mysql_stat
+ mysql_shutdown
+ mysql_select_db
+ mysql_row_tell
+ mysql_row_seek
+ mysql_real_query
+ mysql_real_connect
+ mysql_query
+ mysql_ping
+ mysql_options
+ mysql_num_rows
+ mysql_num_fields
+ mysql_list_tables
+ mysql_list_processes
+ mysql_list_fields
+ mysql_list_dbs
+ mysql_kill
+ mysql_insert_id
+ mysql_init
+ mysql_info
+ mysql_get_server_info
+ mysql_get_proto_info
+ mysql_get_host_info
+ mysql_get_client_info
+ mysql_free_result
+ mysql_field_tell
+ mysql_field_count
+ mysql_field_seek
+ mysql_fetch_row
+ mysql_fetch_lengths
+ mysql_fetch_fields
+ mysql_fetch_field_direct
+ mysql_fetch_field
+ mysql_escape_string
+ mysql_real_escape_string
+ mysql_error
+ mysql_errno
+ mysql_eof
+ mysql_dump_debug_info
+ mysql_drop_db
+ mysql_debug
+ mysql_data_seek
+ mysql_create_db
+ mysql_character_set_name
+ mysql_change_user
+ mysql_connect
+ mysql_close
+ mysql_affected_rows
+ mysql_thread_init
+ mysql_thread_end
+ mysql_send_query
+ mysql_read_query_result
+ mysql_refresh
+ mysql_odbc_escape_string
+ myodbc_remove_escape
diff --git a/VC++Files/libmysqld/libmysqld.dsp b/VC++Files/libmysqld/libmysqld.dsp
new file mode 100644
index 00000000000..d2614ae4858
--- /dev/null
+++ b/VC++Files/libmysqld/libmysqld.dsp
@@ -0,0 +1,409 @@
+# Microsoft Developer Studio Project File - Name="libmysqld" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=libmysqld - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "libmysqld.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "libmysqld.mak" CFG="libmysqld - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "libmysqld - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "libmysqld - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=xicl6.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "libmysqld - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBMYSQLD_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /D "__WIN__" /FR /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib ..\lib_release\zlib.lib /nologo /dll /machine:I386 /out:"../lib_release/libmysqld.dll" /implib:"../lib_release/libmysqld.lib"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "libmysqld - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "libmysqld___Win32_Debug"
+# PROP BASE Intermediate_Dir "libmysqld___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBMYSQLD_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MT /W3 /Z7 /Od /I "../include" /I "../sql" /I "../regex" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /D "__WIN__" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x416 /d "_DEBUG"
+# ADD RSC /l 0x416 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_debug\dbug.lib ..\lib_debug\mysys.lib ..\lib_debug\strings.lib ..\lib_debug\regex.lib ..\lib_debug\heap.lib ..\lib_debug\innodb.lib /nologo /dll /incremental:no /debug /machine:I386 /nodefaultlib:"LIBCMTD" /out:"../lib_debug/libmysqld.dll" /implib:"../lib_debug/libmysqld.lib" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "libmysqld - Win32 Release"
+# Name "libmysqld - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\sql\convert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\derror.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\errmsg.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\field.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\field_conv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\filesort.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\get_password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_berkeley.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_heap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_innodb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_isammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_myisam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_myisammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\hash_filo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\hostname.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\init.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_buff.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_cmpfunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_create.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_func.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_strfunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_sum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_timefunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_uniq.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\key.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\lib_sql.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\libmysqld.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libmysqld.def
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\lock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\log.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\log_event.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\mf_iocache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\mini_client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\net_pkg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\net_serv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_ft.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_range.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_sum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\procedure.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\records.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\repl_failsafe.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\set_var.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\slave.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_acl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_analyse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_base.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_cache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_class.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_crypt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_db.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_delete.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_do.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_insert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_lex.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_list.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_load.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_manager.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_map.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_parse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_rename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_repl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_select.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_show.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_string.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_test.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_udf.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_union.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_yacc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\thr_malloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\time.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\uniques.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\unireg.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/libmysqltest/myTest-package.dsp b/VC++Files/libmysqltest/myTest-package.dsp
new file mode 100644
index 00000000000..a5c73d447b3
--- /dev/null
+++ b/VC++Files/libmysqltest/myTest-package.dsp
@@ -0,0 +1,92 @@
+# Microsoft Developer Studio Project File - Name="myTest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=myTest - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "myTest.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "myTest.mak" CFG="myTest - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "myTest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "myTest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=xicl6.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "myTest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /W3 /O2 /I "..\..\include" /D "NDEBUG" /D "DBUG_UFF" /D "_CONSOLE" /D "_MBCS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ..\..\lib\opt\libmysql.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\lib_release"
+
+!ELSEIF "$(CFG)" == "myTest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "..\..\include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ..\..\lib\debug\libmysql.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"..\lib_debug"
+
+!ENDIF
+
+# Begin Target
+
+# Name "myTest - Win32 Release"
+# Name "myTest - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\Mytest.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/libmysqltest/myTest.dsp b/VC++Files/libmysqltest/myTest.dsp
index 74f7b8ae48e..1d3a790edd5 100644
--- a/VC++Files/libmysqltest/myTest.dsp
+++ b/VC++Files/libmysqltest/myTest.dsp
@@ -7,25 +7,25 @@
CFG=myTest - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myTest.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myTest.mak" CFG="myTest - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "myTest - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "myTest - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "myTest - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 libmysql.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\lib_release"
@@ -67,17 +67,18 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "..\include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "..\include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
+# SUBTRACT CPP /Fr /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 libmysql.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"..\lib_debug"
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/libmysqltest/mytest.c b/VC++Files/libmysqltest/mytest.c
index 8b4029f5e1e..ceecbb19902 100644
--- a/VC++Files/libmysqltest/mytest.c
+++ b/VC++Files/libmysqltest/mytest.c
@@ -1,169 +1,170 @@
-/*C4*/
-/****************************************************************/
-/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */
-/* Date: 02/18/1998 */
-/* mytest.c : do some testing of the libmySQL.DLL.... */
-/* */
-/* History: */
-/* 02/18/1998 jw3 also sprach zarathustra.... */
-/****************************************************************/
-
-
-#include <windows.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <mysql.h>
-
-#define DEFALT_SQL_STMT "SELECT * FROM db"
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-
-
-/********************************************************
-**
-** main :-
-**
-********************************************************/
-
-int
-main( int argc, char * argv[] )
-{
-
- char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], * pszT, szDB[ 50 ] ;
- int i, j, k, l, x ;
- MYSQL * myData ;
- MYSQL_RES * res ;
- MYSQL_FIELD * fd ;
- MYSQL_ROW row ;
-
- //....just curious....
- printf( "sizeof( MYSQL ) == %d\n", sizeof( MYSQL ) ) ;
- if ( argc == 2 )
- {
- strcpy( szDB, argv[ 1 ] ) ;
- strcpy( szSQL, DEFALT_SQL_STMT ) ;
- if (!strcmp(szDB,"--debug"))
- {
- strcpy( szDB, "mysql" ) ;
- printf("Some mysql struct information (size and offset):\n");
- printf("net:\t%3d %3d\n",sizeof(myData->net),offsetof(MYSQL,net));
- printf("host:\t%3d %3d\n",sizeof(myData->host),offsetof(MYSQL,host));
- printf("port:\t%3d %3d\n",sizeof(myData->port),offsetof(MYSQL,port));
- printf("protocol_version:\t%3d %3d\n",sizeof(myData->protocol_version),
- offsetof(MYSQL,protocol_version));
- printf("thread_id:\t%3d %3d\n",sizeof(myData->thread_id),
- offsetof(MYSQL,thread_id));
- printf("affected_rows:\t%3d %3d\n",sizeof(myData->affected_rows),
- offsetof(MYSQL,affected_rows));
- printf("packet_length:\t%3d %3d\n",sizeof(myData->packet_length),
- offsetof(MYSQL,packet_length));
- printf("status:\t%3d %3d\n",sizeof(myData->status),
- offsetof(MYSQL,status));
- printf("fields:\t%3d %3d\n",sizeof(myData->fields),
- offsetof(MYSQL,fields));
- printf("field_alloc:\t%3d %3d\n",sizeof(myData->field_alloc),
- offsetof(MYSQL,field_alloc));
- printf("free_me:\t%3d %3d\n",sizeof(myData->free_me),
- offsetof(MYSQL,free_me));
- printf("options:\t%3d %3d\n",sizeof(myData->options),
- offsetof(MYSQL,options));
- puts("");
- }
- }
- else if ( argc > 2 ) {
- strcpy( szDB, argv[ 1 ] ) ;
- strcpy( szSQL, argv[ 2 ] ) ;
- }
- else {
- strcpy( szDB, "mysql" ) ;
- strcpy( szSQL, DEFALT_SQL_STMT ) ;
- }
- //....
-
- if ( (myData = mysql_init((MYSQL*) 0)) &&
- mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT,
- NULL, 0 ) )
- {
- if ( mysql_select_db( myData, szDB ) < 0 ) {
- printf( "Can't select the %s database !\n", szDB ) ;
- mysql_close( myData ) ;
- return 2 ;
- }
- }
- else {
- printf( "Can't connect to the mysql server on port %d !\n",
- MYSQL_PORT ) ;
- mysql_close( myData ) ;
- return 1 ;
- }
- //....
- if ( ! mysql_query( myData, szSQL ) ) {
- res = mysql_store_result( myData ) ;
- i = (int) mysql_num_rows( res ) ; l = 1 ;
- printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ;
- //....we can get the field-specific characteristics here....
- for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- strcpy( aszFlds[ x ], fd->name ) ;
- //....
- while ( row = mysql_fetch_row( res ) ) {
- j = mysql_num_fields( res ) ;
- printf( "Record #%ld:-\n", l++ ) ;
- for ( k = 0 ; k < j ; k++ )
- printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- puts( "==============================\n" ) ;
- }
- mysql_free_result( res ) ;
- }
- else printf( "Couldn't execute %s on the server !\n", szSQL ) ;
- //....
- puts( "==== Diagnostic info ====" ) ;
- pszT = mysql_get_client_info() ;
- printf( "Client info: %s\n", pszT ) ;
- //....
- pszT = mysql_get_host_info( myData ) ;
- printf( "Host info: %s\n", pszT ) ;
- //....
- pszT = mysql_get_server_info( myData ) ;
- printf( "Server info: %s\n", pszT ) ;
- //....
- res = mysql_list_processes( myData ) ; l = 1 ;
- if (res)
- {
- for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- strcpy( aszFlds[ x ], fd->name ) ;
- while ( row = mysql_fetch_row( res ) ) {
- j = mysql_num_fields( res ) ;
- printf( "Process #%ld:-\n", l++ ) ;
- for ( k = 0 ; k < j ; k++ )
- printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- puts( "==============================\n" ) ;
- }
- }
- else
- {
- printf("Got error %s when retreiving processlist\n",mysql_error(myData));
- }
- //....
- res = mysql_list_tables( myData, "%" ) ; l = 1 ;
- for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- strcpy( aszFlds[ x ], fd->name ) ;
- while ( row = mysql_fetch_row( res ) ) {
- j = mysql_num_fields( res ) ;
- printf( "Table #%ld:-\n", l++ ) ;
- for ( k = 0 ; k < j ; k++ )
- printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- puts( "==============================\n" ) ;
- }
- //....
- pszT = mysql_stat( myData ) ;
- puts( pszT ) ;
- //....
- mysql_close( myData ) ;
- return 0 ;
-
-}
+/*C4*/
+/****************************************************************/
+/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */
+/* Date: 02/18/1998 */
+/* mytest.c : do some testing of the libmySQL.DLL.... */
+/* */
+/* History: */
+/* 02/18/1998 jw3 also sprach zarathustra.... */
+/****************************************************************/
+
+
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <mysql.h>
+
+#define DEFALT_SQL_STMT "SELECT * FROM db"
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+
+/********************************************************
+**
+** main :-
+**
+********************************************************/
+
+int
+main( int argc, char * argv[] )
+{
+
+ char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], szDB[ 50 ] ;
+ const char *pszT;
+ int i, j, k, l, x ;
+ MYSQL * myData ;
+ MYSQL_RES * res ;
+ MYSQL_FIELD * fd ;
+ MYSQL_ROW row ;
+
+ //....just curious....
+ printf( "sizeof( MYSQL ) == %d\n", sizeof( MYSQL ) ) ;
+ if ( argc == 2 )
+ {
+ strcpy( szDB, argv[ 1 ] ) ;
+ strcpy( szSQL, DEFALT_SQL_STMT ) ;
+ if (!strcmp(szDB,"--debug"))
+ {
+ strcpy( szDB, "mysql" ) ;
+ printf("Some mysql struct information (size and offset):\n");
+ printf("net:\t%3d %3d\n",sizeof(myData->net),offsetof(MYSQL,net));
+ printf("host:\t%3d %3d\n",sizeof(myData->host),offsetof(MYSQL,host));
+ printf("port:\t%3d %3d\n",sizeof(myData->port),offsetof(MYSQL,port));
+ printf("protocol_version:\t%3d %3d\n",sizeof(myData->protocol_version),
+ offsetof(MYSQL,protocol_version));
+ printf("thread_id:\t%3d %3d\n",sizeof(myData->thread_id),
+ offsetof(MYSQL,thread_id));
+ printf("affected_rows:\t%3d %3d\n",sizeof(myData->affected_rows),
+ offsetof(MYSQL,affected_rows));
+ printf("packet_length:\t%3d %3d\n",sizeof(myData->packet_length),
+ offsetof(MYSQL,packet_length));
+ printf("status:\t%3d %3d\n",sizeof(myData->status),
+ offsetof(MYSQL,status));
+ printf("fields:\t%3d %3d\n",sizeof(myData->fields),
+ offsetof(MYSQL,fields));
+ printf("field_alloc:\t%3d %3d\n",sizeof(myData->field_alloc),
+ offsetof(MYSQL,field_alloc));
+ printf("free_me:\t%3d %3d\n",sizeof(myData->free_me),
+ offsetof(MYSQL,free_me));
+ printf("options:\t%3d %3d\n",sizeof(myData->options),
+ offsetof(MYSQL,options));
+ puts("");
+ }
+ }
+ else if ( argc > 2 ) {
+ strcpy( szDB, argv[ 1 ] ) ;
+ strcpy( szSQL, argv[ 2 ] ) ;
+ }
+ else {
+ strcpy( szDB, "mysql" ) ;
+ strcpy( szSQL, DEFALT_SQL_STMT ) ;
+ }
+ //....
+
+ if ( (myData = mysql_init((MYSQL*) 0)) &&
+ mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT,
+ NULL, 0 ) )
+ {
+ if ( mysql_select_db( myData, szDB ) < 0 ) {
+ printf( "Can't select the %s database !\n", szDB ) ;
+ mysql_close( myData ) ;
+ return 2 ;
+ }
+ }
+ else {
+ printf( "Can't connect to the mysql server on port %d !\n",
+ MYSQL_PORT ) ;
+ mysql_close( myData ) ;
+ return 1 ;
+ }
+ //....
+ if ( ! mysql_query( myData, szSQL ) ) {
+ res = mysql_store_result( myData ) ;
+ i = (int) mysql_num_rows( res ) ; l = 1 ;
+ printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ;
+ //....we can get the field-specific characteristics here....
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ //....
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Record #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ mysql_free_result( res ) ;
+ }
+ else printf( "Couldn't execute %s on the server !\n", szSQL ) ;
+ //....
+ puts( "==== Diagnostic info ====" ) ;
+ pszT = mysql_get_client_info() ;
+ printf( "Client info: %s\n", pszT ) ;
+ //....
+ pszT = mysql_get_host_info( myData ) ;
+ printf( "Host info: %s\n", pszT ) ;
+ //....
+ pszT = mysql_get_server_info( myData ) ;
+ printf( "Server info: %s\n", pszT ) ;
+ //....
+ res = mysql_list_processes( myData ) ; l = 1 ;
+ if (res)
+ {
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Process #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ }
+ else
+ {
+ printf("Got error %s when retreiving processlist\n",mysql_error(myData));
+ }
+ //....
+ res = mysql_list_tables( myData, "%" ) ; l = 1 ;
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Table #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ //....
+ pszT = mysql_stat( myData ) ;
+ puts( pszT ) ;
+ //....
+ mysql_close( myData ) ;
+ return 0 ;
+
+}
diff --git a/VC++Files/libmysqltest/mytest.dsw b/VC++Files/libmysqltest/mytest.dsw
index 621899eb4d0..1aa804386bc 100644
--- a/VC++Files/libmysqltest/mytest.dsw
+++ b/VC++Files/libmysqltest/mytest.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/merge/merge.dsp b/VC++Files/merge/merge.dsp
index 7a7945b806a..8a8173fd606 100644
--- a/VC++Files/merge/merge.dsp
+++ b/VC++Files/merge/merge.dsp
@@ -7,19 +7,19 @@
CFG=merge - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "merge.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "merge.mak" CFG="merge - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "merge - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "merge - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -41,7 +41,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../zlib" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
@@ -65,7 +65,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /I "../zlib" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
@@ -76,7 +76,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_debug\merge.lib"
-!ENDIF
+!ENDIF
# Begin Target
@@ -84,55 +84,51 @@ LIB32=link.exe -lib
# Name "merge - Win32 Debug"
# Begin Source File
-SOURCE=.\_locking.c
+SOURCE=.\mrg_close.c
# End Source File
# Begin Source File
-SOURCE=.\close.c
+SOURCE=.\mrg_create.c
# End Source File
# Begin Source File
-SOURCE=.\create.c
+SOURCE=.\mrg_delete.c
# End Source File
# Begin Source File
-SOURCE=.\delete.c
+SOURCE=.\mrg_extra.c
# End Source File
# Begin Source File
-SOURCE=.\extra.c
+SOURCE=.\mrg_info.c
# End Source File
# Begin Source File
-SOURCE=.\info.c
+SOURCE=.\mrg_locking.c
# End Source File
# Begin Source File
-SOURCE=.\mrgdef.h
+SOURCE=.\mrg_open.c
# End Source File
# Begin Source File
-SOURCE=.\open.c
+SOURCE=.\mrg_panic.c
# End Source File
# Begin Source File
-SOURCE=.\panic.c
+SOURCE=.\mrg_rrnd.c
# End Source File
# Begin Source File
-SOURCE=.\rrnd.c
+SOURCE=.\mrg_rsame.c
# End Source File
# Begin Source File
-SOURCE=.\rsame.c
+SOURCE=.\mrg_static.c
# End Source File
# Begin Source File
-SOURCE=.\static.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\update.c
+SOURCE=.\mrg_update.c
# End Source File
# End Target
# End Project
diff --git a/VC++Files/merge/merge.dsw b/VC++Files/merge/merge.dsw
index a2d5ccb2ff2..26d3bb5200c 100644
--- a/VC++Files/merge/merge.dsw
+++ b/VC++Files/merge/merge.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/my_print_defaults/my_print_defaults.dsp b/VC++Files/my_print_defaults/my_print_defaults.dsp
index c7727b49851..25f5332eb0f 100644
--- a/VC++Files/my_print_defaults/my_print_defaults.dsp
+++ b/VC++Files/my_print_defaults/my_print_defaults.dsp
@@ -7,25 +7,25 @@
CFG=my_print_defaults - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "my_print_defaults.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "my_print_defaults.mak" CFG="my_print_defaults - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "my_print_defaults - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "my_print_defaults - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "my_print_defaults - Win32 Release"
@@ -37,8 +37,8 @@ RSC=rc.exe
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -47,9 +47,9 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "my_print_defaults - Win32 Debug"
@@ -64,18 +64,18 @@ LINK32=link.exe
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MT /W3 /Gm /GX /ZI /Od /I "../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MT /W3 /GX /Z7 /Od /I "../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x416 /d "_DEBUG"
# ADD RSC /l 0x416 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"LIBCMTD.lib" /pdbtype:sept
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"LIBCMTD.lib" /pdbtype:sept
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/myisam/myisam.dsp b/VC++Files/myisam/myisam.dsp
index b5de44062dd..51d4fb73713 100644
--- a/VC++Files/myisam/myisam.dsp
+++ b/VC++Files/myisam/myisam.dsp
@@ -7,19 +7,19 @@
CFG=myisam - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myisam.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myisam.mak" CFG="myisam - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "myisam - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "myisam - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -74,7 +74,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_Debug\myisam.lib"
-!ENDIF
+!ENDIF
# Begin Target
@@ -85,15 +85,15 @@ LIB32=link.exe -lib
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
-SOURCE=.\ft_eval.c
+SOURCE=.\ft_boolean_search.c
# End Source File
# Begin Source File
-SOURCE=.\ft_parser.c
+SOURCE=.\ft_nlq_search.c
# End Source File
# Begin Source File
-SOURCE=.\ft_search.c
+SOURCE=.\ft_parser.c
# End Source File
# Begin Source File
@@ -101,6 +101,10 @@ SOURCE=.\ft_static.c
# End Source File
# Begin Source File
+SOURCE=.\ft_stem.c
+# End Source File
+# Begin Source File
+
SOURCE=.\ft_stopwords.c
# End Source File
# Begin Source File
diff --git a/VC++Files/myisamchk/myisamchk.dsp b/VC++Files/myisamchk/myisamchk.dsp
index 7f0459d21d0..0c8e7c00f1a 100644
--- a/VC++Files/myisamchk/myisamchk.dsp
+++ b/VC++Files/myisamchk/myisamchk.dsp
@@ -7,19 +7,19 @@
CFG=myisamchk - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myisamchk.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myisamchk.mak" CFG="myisamchk - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "myisamchk - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "myisamchk - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -78,7 +78,7 @@ LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/myisamchk.exe" /pdbtype:sept
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/myisamlog/myisamlog.dsp b/VC++Files/myisamlog/myisamlog.dsp
index efc43914759..6df65add63c 100644
--- a/VC++Files/myisamlog/myisamlog.dsp
+++ b/VC++Files/myisamlog/myisamlog.dsp
@@ -7,25 +7,25 @@
CFG=myisamlog - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myisamlog.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myisamlog.mak" CFG="myisamlog - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "myisamlog - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "myisamlog - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "myisamlog - Win32 Release"
@@ -37,8 +37,8 @@ RSC=rc.exe
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
@@ -48,7 +48,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib setargv.obj /nologo /subsystem:console /pdb:"release/myisamchk.pdb" /machine:I386 /out:"../client_release/myisamlog.exe"
# SUBTRACT LINK32 /pdb:none
@@ -74,12 +74,12 @@ LINK32=link.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /pdb:"debug/myisamchk.pdb" /debug /machine:I386 /out:"../client_debug/myisamlog.exe" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/myisammrg/myisammrg.dsp b/VC++Files/myisammrg/myisammrg.dsp
index 46dec803697..9363bd63e62 100644
--- a/VC++Files/myisammrg/myisammrg.dsp
+++ b/VC++Files/myisammrg/myisammrg.dsp
@@ -7,19 +7,19 @@
CFG=myisammrg - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myisammrg.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myisammrg.mak" CFG="myisammrg - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "myisammrg - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "myisammrg - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -75,7 +75,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_Debug\myisammrg.lib"
-!ENDIF
+!ENDIF
# Begin Target
@@ -122,6 +122,10 @@ SOURCE=.\myrg_queue.c
# End Source File
# Begin Source File
+SOURCE=.\myrg_range.c
+# End Source File
+# Begin Source File
+
SOURCE=.\myrg_rfirst.c
# End Source File
# Begin Source File
@@ -156,6 +160,10 @@ SOURCE=.\myrg_static.c
SOURCE=.\myrg_update.c
# End Source File
+# Begin Source File
+
+SOURCE=.\myrg_write.c
+# End Source File
# End Group
# Begin Group "Header Files"
diff --git a/VC++Files/myisampack/myisampack.dsp b/VC++Files/myisampack/myisampack.dsp
index f576a93faf2..cdfc44331ea 100644
--- a/VC++Files/myisampack/myisampack.dsp
+++ b/VC++Files/myisampack/myisampack.dsp
@@ -7,19 +7,19 @@
CFG=myisampack - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myisampack.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myisampack.mak" CFG="myisampack - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "myisampack - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "myisampack - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -77,7 +77,7 @@ LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/mysql.dsp b/VC++Files/mysql.dsp
index 41f2538a7e5..4f97866cc31 100644
--- a/VC++Files/mysql.dsp
+++ b/VC++Files/mysql.dsp
@@ -7,19 +7,19 @@
CFG=mysql - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysql.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysql.mak" CFG="mysql - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysql - Win32 Release" (based on "Win32 (x86) External Target")
!MESSAGE "mysql - Win32 Debug" (based on "Win32 (x86) External Target")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
@@ -63,7 +63,7 @@ CFG=mysql - Win32 Debug
# PROP Bsc_Name "mysql.bsc"
# PROP Target_Dir ""
-!ENDIF
+!ENDIF
# Begin Target
@@ -74,7 +74,7 @@ CFG=mysql - Win32 Debug
!ELSEIF "$(CFG)" == "mysql - Win32 Debug"
-!ENDIF
+!ENDIF
# End Target
# End Project
diff --git a/VC++Files/mysql.dsw b/VC++Files/mysql.dsw
index 57e51ee063c..eef82588fa8 100644
--- a/VC++Files/mysql.dsw
+++ b/VC++Files/mysql.dsw
@@ -114,7 +114,7 @@ Package=<4>
###############################################################################
-Project: "libmySQL"=".\libmysql\libmySQL.dsp" - Package Owner=<4>
+Project: "libmysql"=".\libmysql\libmysql.dsp" - Package Owner=<4>
Package=<5>
{{{
@@ -129,6 +129,48 @@ Package=<4>
###############################################################################
+Project: "libmysqld"=".\libmysqld\libmysqld.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name bdb
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name heap
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name innobase
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name regex
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisammrg
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+}}}
+
+###############################################################################
+
Project: "merge"=".\merge\merge.dsp" - Package Owner=<4>
Package=<5>
@@ -150,7 +192,7 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
- Project_Dep_Name libmySQL
+ Project_Dep_Name libmysql
End Project Dependency
}}}
@@ -165,7 +207,13 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
- Project_Dep_Name mysqlclient
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name dbug
End Project Dependency
}}}
@@ -311,14 +359,11 @@ Package=<4>
Begin Project Dependency
Project_Dep_Name mysqlclient
End Project Dependency
- Begin Project Dependency
- Project_Dep_Name mysys
- End Project Dependency
}}}
###############################################################################
-Project: "mysqlcheck"=".\CLIENT\mysqlcheck.dsp" - Package Owner=<4>
+Project: "mysqlcheck"=".\mysqlcheck\mysqlcheck.dsp" - Package Owner=<4>
Package=<5>
{{{
@@ -329,9 +374,6 @@ Package=<4>
Begin Project Dependency
Project_Dep_Name mysqlclient
End Project Dependency
- Begin Project Dependency
- Project_Dep_Name zlib
- End Project Dependency
}}}
###############################################################################
@@ -417,15 +459,30 @@ Package=<4>
Project_Dep_Name myisammrg
End Project Dependency
Begin Project Dependency
- Project_Dep_Name innobase
+ Project_Dep_Name bdb
End Project Dependency
Begin Project Dependency
- Project_Dep_Name bdb
+ Project_Dep_Name vio
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name innobase
End Project Dependency
}}}
###############################################################################
+Project: "mysqldemb"=".\mysqldemb\mysqldemb.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
Project: "mysqldump"=".\client\mysqldump.dsp" - Package Owner=<4>
Package=<5>
@@ -456,6 +513,51 @@ Package=<4>
###############################################################################
+Project: "mysqlserver"=".\mysqlserver\mysqlserver.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name dbug
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name heap
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name innobase
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name merge
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisam
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name myisammrg
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysqldemb
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name regex
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+}}}
+
+###############################################################################
+
Project: "mysqlshow"=".\client\mysqlshow.dsp" - Package Owner=<4>
Package=<5>
@@ -597,6 +699,48 @@ Package=<4>
###############################################################################
+Project: "test1"=".\test1\test1.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name libmysql
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "test_libmysqld"=".\libmysqld\examples\test_libmysqld.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name strings
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name libmysqld
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name vio
+ End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+}}}
+
+###############################################################################
+
Project: "thr_test"=".\thr_test\thr_test.dsp" - Package Owner=<4>
Package=<5>
@@ -618,6 +762,18 @@ Package=<4>
###############################################################################
+Project: "vio"=".\vio\vio.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
Project: "zlib"=".\zlib\zlib.dsp" - Package Owner=<4>
Package=<5>
@@ -641,4 +797,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/mysqlbinlog/mysqlbinlog.dsp b/VC++Files/mysqlbinlog/mysqlbinlog.dsp
index e545c19a2d7..b26b911af77 100644
--- a/VC++Files/mysqlbinlog/mysqlbinlog.dsp
+++ b/VC++Files/mysqlbinlog/mysqlbinlog.dsp
@@ -7,25 +7,25 @@
CFG=mysqlbinlog - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlbinlog.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlbinlog.mak" CFG="mysqlbinlog - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqlbinlog - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqlbinlog - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "mysqlbinlog - Win32 Release"
@@ -37,18 +37,18 @@ RSC=rc.exe
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
+# PROP Output_Dir "eelease"
+# PROP Intermediate_Dir "eelease"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../sql" /I "../regex" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /I "../sql" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlbinlog.exe" /libpath:"..\lib_release\\"
# SUBTRACT LINK32 /pdb:none /debug
@@ -67,17 +67,17 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../sql" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../" /I "../sql" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlbinlog.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
-!ENDIF
+!ENDIF
# Begin Target
@@ -90,10 +90,6 @@ LINK32=link.exe
SOURCE=..\client\mysqlbinlog.cpp
# End Source File
-# Begin Source File
-
-SOURCE=..\sql\net_serv.cpp
-# End Source File
# End Group
# Begin Group "Header Files"
diff --git a/VC++Files/mysqlcheck/mysqlcheck.dsp b/VC++Files/mysqlcheck/mysqlcheck.dsp
new file mode 100644
index 00000000000..f8487119da3
--- /dev/null
+++ b/VC++Files/mysqlcheck/mysqlcheck.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="mysqlcheck" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=mysqlcheck - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlcheck.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlcheck.mak" CFG="mysqlcheck - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqlcheck - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "mysqlcheck - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=xicl6.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqlcheck - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlcheck.exe" /libpath:"..\lib_release\\"
+
+!ELSEIF "$(CFG)" == "mysqlcheck - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "MYSQL_SERVER" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlcheck.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqlcheck - Win32 Release"
+# Name "mysqlcheck - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\client\mysqlcheck.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/mysqldemb/mysqldemb.dsp b/VC++Files/mysqldemb/mysqldemb.dsp
new file mode 100644
index 00000000000..3d27f5cfc7f
--- /dev/null
+++ b/VC++Files/mysqldemb/mysqldemb.dsp
@@ -0,0 +1,386 @@
+# Microsoft Developer Studio Project File - Name="mysqldemb" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=mysqldemb - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqldemb.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqldemb.mak" CFG="mysqldemb - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqldemb - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "mysqldemb - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=xicl6.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqldemb - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /D "__WIN__" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=xilink6.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "mysqldemb - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Z7 /Od /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /D "__WIN__" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x416 /d "_DEBUG"
+# ADD RSC /l 0x416 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=xilink6.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqldemb - Win32 Release"
+# Name "mysqldemb - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\sql\convert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\derror.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\errmsg.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\field.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\field_conv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\filesort.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\get_password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_heap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_innodb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_isammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_myisam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\ha_myisammrg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\hash_filo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\hostname.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\init.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_buff.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_cmpfunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_create.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_func.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_strfunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_sum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_timefunc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\item_uniq.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\key.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysqld\lib_sql.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysqld\libmysqld.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\lock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\log.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\log_event.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\mf_iocache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\mini_client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\net_pkg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\net_serv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_ft.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_range.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\opt_sum.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\libmysql\password.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\procedure.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\records.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\repl_failsafe.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\slave.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_acl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_analyse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_base.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_cache.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_class.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_crypt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_db.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_delete.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_do.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_insert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_lex.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_list.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_manager.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_map.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_parse.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_rename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_repl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_select.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_show.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_string.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_test.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_udf.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_union.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\sql_yacc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\table.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\thr_malloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\time.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\uniques.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\sql\unireg.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/mysqlmanager/CHILDFRM.CPP b/VC++Files/mysqlmanager/CHILDFRM.CPP
new file mode 100644
index 00000000000..08027e068ac
--- /dev/null
+++ b/VC++Files/mysqlmanager/CHILDFRM.CPP
@@ -0,0 +1,65 @@
+// ChildFrm.cpp : implementation of the CChildFrame class
+//
+
+#include "stdafx.h"
+#include "MySqlManager.h"
+
+#include "ChildFrm.h"
+
+#ifdef _DEBUG
+ #define new DEBUG_NEW
+ #undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CChildFrame
+
+IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)
+
+BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
+//{{AFX_MSG_MAP(CChildFrame)
+// NOTE - the ClassWizard will add and remove mapping macros here.
+// DO NOT EDIT what you see in these blocks of generated code !
+//}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CChildFrame construction/destruction
+
+CChildFrame::CChildFrame()
+{
+ // TODO: add member initialization code here
+
+}
+
+CChildFrame::~CChildFrame()
+{
+}
+
+BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+ // TODO: Modify the Window class or styles here by modifying
+ // the CREATESTRUCT cs
+
+ return CMDIChildWnd::PreCreateWindow(cs);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CChildFrame diagnostics
+
+#ifdef _DEBUG
+void CChildFrame::AssertValid() const
+{
+ CMDIChildWnd::AssertValid();
+}
+
+void CChildFrame::Dump(CDumpContext& dc) const
+{
+ CMDIChildWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CChildFrame message handlers
diff --git a/VC++Files/mysqlmanager/CHILDFRM.H b/VC++Files/mysqlmanager/CHILDFRM.H
new file mode 100644
index 00000000000..3075be58a67
--- /dev/null
+++ b/VC++Files/mysqlmanager/CHILDFRM.H
@@ -0,0 +1,52 @@
+// ChildFrm.h : interface of the CChildFrame class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_CHILDFRM_H__826CB2F0_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
+#define AFX_CHILDFRM_H__826CB2F0_8B6D_11D1_AEC1_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+class CChildFrame : public CMDIChildWnd
+{
+ DECLARE_DYNCREATE(CChildFrame)
+public:
+ CChildFrame();
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CChildFrame)
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CChildFrame();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CChildFrame)
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code!
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_CHILDFRM_H__826CB2F0_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlmanager/MAINFRM.CPP b/VC++Files/mysqlmanager/MAINFRM.CPP
new file mode 100644
index 00000000000..499704ed2a0
--- /dev/null
+++ b/VC++Files/mysqlmanager/MAINFRM.CPP
@@ -0,0 +1,137 @@
+// MainFrm.cpp : implementation of the CMainFrame class
+//
+
+#include "stdafx.h"
+#include "MySqlManager.h"
+#include "MainFrm.h"
+
+CMainFrame* CMainFrame::g_pMainFrame = NULL;
+
+#ifdef _DEBUG
+ #define new DEBUG_NEW
+ #undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame
+
+IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
+
+BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
+//{{AFX_MSG_MAP(CMainFrame)
+// NOTE - the ClassWizard will add and remove mapping macros here.
+// DO NOT EDIT what you see in these blocks of generated code !
+ ON_WM_CREATE()
+//}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+static UINT indicators[] =
+{
+ ID_SEPARATOR, // status line indicator
+ ID_INDICATOR_CAPS,
+ ID_INDICATOR_NUM,
+ ID_INDICATOR_SCRL,
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame construction/destruction
+
+CMainFrame::CMainFrame()
+{
+ // TODO: add member initialization code here
+
+}
+
+CMainFrame::~CMainFrame()
+{
+}
+
+int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ if (!m_wndToolBar.Create(this) ||
+ !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
+ {
+ TRACE0("Failed to create toolbar\n");
+ return -1; // fail to create
+ }
+
+ if (!m_wndStatusBar.Create(this) ||
+ !m_wndStatusBar.SetIndicators(indicators,
+ sizeof(indicators)/sizeof(UINT)))
+ {
+ TRACE0("Failed to create status bar\n");
+ return -1; // fail to create
+ }
+
+ // TODO: Remove this if you don't want tool tips or a resizeable toolbar
+ m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
+ CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+
+ // TODO: Delete these three lines if you don't want the toolbar to
+ // be dockable
+ m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
+ EnableDocking(CBRS_ALIGN_ANY);
+ DockControlBar(&m_wndToolBar);
+
+ return 0;
+}
+
+BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+ // TODO: Modify the Window class or styles here by modifying
+ // the CREATESTRUCT cs
+
+ return CMDIFrameWnd::PreCreateWindow(cs);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame diagnostics
+
+#ifdef _DEBUG
+void CMainFrame::AssertValid() const
+{
+ CMDIFrameWnd::AssertValid();
+}
+
+void CMainFrame::Dump(CDumpContext& dc) const
+{
+ CMDIFrameWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame message handlers
+
+int CMainFrame::StatusMsg ( LPCSTR fmt, ... )
+
+{
+
+ char buf [2048];
+ va_list args;
+ va_start(args, fmt);
+ int ret = vsprintf(buf, fmt, args);
+
+ if ( this != NULL )
+ {
+ static char g_StatusMsg_Buffer_TT [ 2048 ];
+ memcpy ( g_StatusMsg_Buffer_TT, buf, sizeof(g_StatusMsg_Buffer_TT) );
+ m_wndStatusBar.SetPaneText ( 0, buf );
+ m_wndStatusBar.UpdateWindow ();
+ }
+
+ va_end(args);
+ return ( ret );
+
+}
+
+
+BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
+{
+ g_pMainFrame = this;
+ return CMDIFrameWnd::OnCreateClient(lpcs, pContext);
+}
diff --git a/VC++Files/mysqlmanager/MAINFRM.H b/VC++Files/mysqlmanager/MAINFRM.H
new file mode 100644
index 00000000000..06c51965bb1
--- /dev/null
+++ b/VC++Files/mysqlmanager/MAINFRM.H
@@ -0,0 +1,69 @@
+// MainFrm.h : interface of the CMainFrame class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_MAINFRM_H__826CB2EE_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
+#define AFX_MAINFRM_H__826CB2EE_8B6D_11D1_AEC1_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+class CMainFrame : public CMDIFrameWnd
+{
+ DECLARE_DYNAMIC(CMainFrame)
+public:
+ CMainFrame();
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CMainFrame)
+ public:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ protected:
+ virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CMainFrame();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+ int StatusMsg ( LPCSTR fmt, ... );
+
+protected: // control bar embedded members
+ CStatusBar m_wndStatusBar;
+ CToolBar m_wndToolBar;
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CMainFrame)
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code!
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+public:
+
+static CMainFrame* g_pMainFrame;
+
+};
+
+#define MainFrame ( CMainFrame::g_pMainFrame ? CMainFrame::g_pMainFrame : (CMainFrame*) AfxGetMainWnd() -> GetTopLevelFrame() )
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_MAINFRM_H__826CB2EE_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlmanager/MySqlManager.dsp b/VC++Files/mysqlmanager/MySqlManager.dsp
index 56e1b4a5bf2..1397c4878af 100644
--- a/VC++Files/mysqlmanager/MySqlManager.dsp
+++ b/VC++Files/mysqlmanager/MySqlManager.dsp
@@ -7,25 +7,25 @@
CFG=MySqlManager - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "MySqlManager.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "MySqlManager.mak" CFG="MySqlManager - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "MySqlManager - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "MySqlManager - Win32 Debug" (based on "Win32 (x86) Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
MTL=midl.exe
RSC=rc.exe
@@ -52,7 +52,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 /nologo /subsystem:windows /machine:I386 /out:"../client_release/MySqlManager.exe"
# SUBTRACT LINK32 /nodefaultlib
@@ -71,7 +71,8 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /GX /Zi /Od /I "../include" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /GR /GX /Z7 /Od /I "../include" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /Fr /YX /Yc /Yu
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /o "NUL" /win32
# SUBTRACT MTL /mktyplib203
@@ -80,12 +81,12 @@ LINK32=link.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /subsystem:windows /incremental:no /debug /machine:I386 /out:"../client_debug/MySqlManager.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
# SUBTRACT LINK32 /pdb:none
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/mysqlmanager/MySqlManager.mak b/VC++Files/mysqlmanager/MySqlManager.mak
new file mode 100644
index 00000000000..b372daa52f2
--- /dev/null
+++ b/VC++Files/mysqlmanager/MySqlManager.mak
@@ -0,0 +1,327 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on MySqlManager.dsp
+!IF "$(CFG)" == ""
+CFG=MySqlManager - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to MySqlManager - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "MySqlManager - Win32 Release" && "$(CFG)" != "MySqlManager - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "MySqlManager.mak" CFG="MySqlManager - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "MySqlManager - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "MySqlManager - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "MySqlManager - Win32 Release"
+
+OUTDIR=.\release
+INTDIR=.\release
+# Begin Custom Macros
+OutDir=.\release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "..\client_release\MySqlManager.exe" "$(OUTDIR)\MySqlManager.pch"
+
+!ELSE
+
+ALL : "mysqlclient - Win32 Release" "..\client_release\MySqlManager.exe" "$(OUTDIR)\MySqlManager.pch"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"mysqlclient - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\ChildFrm.obj"
+ -@erase "$(INTDIR)\MainFrm.obj"
+ -@erase "$(INTDIR)\MySqlManager.obj"
+ -@erase "$(INTDIR)\MySqlManager.pch"
+ -@erase "$(INTDIR)\MySqlManager.res"
+ -@erase "$(INTDIR)\MySqlManagerDoc.obj"
+ -@erase "$(INTDIR)\MySqlManagerView.obj"
+ -@erase "$(INTDIR)\RegisterServer.obj"
+ -@erase "$(INTDIR)\StdAfx.obj"
+ -@erase "$(INTDIR)\ToolSql.obj"
+ -@erase "$(INTDIR)\ToolSqlQuery.obj"
+ -@erase "$(INTDIR)\ToolSqlResults.obj"
+ -@erase "$(INTDIR)\ToolSqlStatus.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "..\client_release\MySqlManager.exe"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /G6 /MT /W3 /GX /O1 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\MySqlManager.res" /d "NDEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\MySqlManager.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=/nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\MySqlManager.pdb" /machine:I386 /out:"../client_release/MySqlManager.exe"
+LINK32_OBJS= \
+ "$(INTDIR)\ChildFrm.obj" \
+ "$(INTDIR)\MainFrm.obj" \
+ "$(INTDIR)\MySqlManager.obj" \
+ "$(INTDIR)\MySqlManagerDoc.obj" \
+ "$(INTDIR)\MySqlManagerView.obj" \
+ "$(INTDIR)\RegisterServer.obj" \
+ "$(INTDIR)\StdAfx.obj" \
+ "$(INTDIR)\ToolSql.obj" \
+ "$(INTDIR)\ToolSqlQuery.obj" \
+ "$(INTDIR)\ToolSqlResults.obj" \
+ "$(INTDIR)\ToolSqlStatus.obj" \
+ "$(INTDIR)\MySqlManager.res" \
+ "..\lib_release\mysqlclient.lib"
+
+"..\client_release\MySqlManager.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "MySqlManager - Win32 Debug"
+
+OUTDIR=.\debug
+INTDIR=.\debug
+# Begin Custom Macros
+OutDir=.\debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "..\client_debug\MySqlManager.exe" "$(OUTDIR)\MySqlManager.pch"
+
+!ELSE
+
+ALL : "mysqlclient - Win32 Debug" "..\client_debug\MySqlManager.exe" "$(OUTDIR)\MySqlManager.pch"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"mysqlclient - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\ChildFrm.obj"
+ -@erase "$(INTDIR)\MainFrm.obj"
+ -@erase "$(INTDIR)\MySqlManager.obj"
+ -@erase "$(INTDIR)\MySqlManager.pch"
+ -@erase "$(INTDIR)\MySqlManager.res"
+ -@erase "$(INTDIR)\MySqlManagerDoc.obj"
+ -@erase "$(INTDIR)\MySqlManagerView.obj"
+ -@erase "$(INTDIR)\RegisterServer.obj"
+ -@erase "$(INTDIR)\StdAfx.obj"
+ -@erase "$(INTDIR)\ToolSql.obj"
+ -@erase "$(INTDIR)\ToolSqlQuery.obj"
+ -@erase "$(INTDIR)\ToolSqlResults.obj"
+ -@erase "$(INTDIR)\ToolSqlStatus.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(OUTDIR)\MySqlManager.pdb"
+ -@erase "..\client_debug\MySqlManager.exe"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /G6 /MTd /W3 /Gm /GX /ZI /Od /I "../include" /D "_DEBUG" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+MTL_PROJ=/nologo /D "_DEBUG" /o "NUL" /win32
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\MySqlManager.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\MySqlManager.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\MySqlManager.pdb" /debug /machine:I386 /out:"../client_debug/MySqlManager.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+LINK32_OBJS= \
+ "$(INTDIR)\ChildFrm.obj" \
+ "$(INTDIR)\MainFrm.obj" \
+ "$(INTDIR)\MySqlManager.obj" \
+ "$(INTDIR)\MySqlManagerDoc.obj" \
+ "$(INTDIR)\MySqlManagerView.obj" \
+ "$(INTDIR)\RegisterServer.obj" \
+ "$(INTDIR)\StdAfx.obj" \
+ "$(INTDIR)\ToolSql.obj" \
+ "$(INTDIR)\ToolSqlQuery.obj" \
+ "$(INTDIR)\ToolSqlResults.obj" \
+ "$(INTDIR)\ToolSqlStatus.obj" \
+ "$(INTDIR)\MySqlManager.res" \
+ "..\lib_debug\mysqlclient.lib"
+
+"..\client_debug\MySqlManager.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("MySqlManager.dep")
+!INCLUDE "MySqlManager.dep"
+!ELSE
+!MESSAGE Warning: cannot find "MySqlManager.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "MySqlManager - Win32 Release" || "$(CFG)" == "MySqlManager - Win32 Debug"
+SOURCE=.\ChildFrm.cpp
+
+"$(INTDIR)\ChildFrm.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\MainFrm.cpp
+
+"$(INTDIR)\MainFrm.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\MySqlManager.cpp
+
+"$(INTDIR)\MySqlManager.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\MySqlManager.rc
+
+"$(INTDIR)\MySqlManager.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+
+SOURCE=.\MySqlManagerDoc.cpp
+
+"$(INTDIR)\MySqlManagerDoc.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\MySqlManagerView.cpp
+
+"$(INTDIR)\MySqlManagerView.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\RegisterServer.cpp
+
+"$(INTDIR)\RegisterServer.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\StdAfx.cpp
+
+!IF "$(CFG)" == "MySqlManager - Win32 Release"
+
+CPP_SWITCHES=/nologo /G6 /MT /W3 /GX /O1 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /Fp"$(INTDIR)\MySqlManager.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+"$(INTDIR)\StdAfx.obj" "$(INTDIR)\MySqlManager.pch" : $(SOURCE) "$(INTDIR)"
+ $(CPP) @<<
+ $(CPP_SWITCHES) $(SOURCE)
+<<
+
+
+!ELSEIF "$(CFG)" == "MySqlManager - Win32 Debug"
+
+CPP_SWITCHES=/nologo /G6 /MTd /W3 /Gm /GX /ZI /Od /I "../include" /D "_DEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\MySqlManager.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+"$(INTDIR)\StdAfx.obj" "$(INTDIR)\MySqlManager.pch" : $(SOURCE) "$(INTDIR)"
+ $(CPP) @<<
+ $(CPP_SWITCHES) $(SOURCE)
+<<
+
+
+!ENDIF
+
+SOURCE=.\ToolSql.cpp
+
+"$(INTDIR)\ToolSql.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\ToolSqlQuery.cpp
+
+"$(INTDIR)\ToolSqlQuery.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\ToolSqlResults.cpp
+
+"$(INTDIR)\ToolSqlResults.obj" : $(SOURCE) "$(INTDIR)"
+
+
+SOURCE=.\ToolSqlStatus.cpp
+
+"$(INTDIR)\ToolSqlStatus.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!IF "$(CFG)" == "MySqlManager - Win32 Release"
+
+"mysqlclient - Win32 Release" :
+ cd "\MYSQL-3.23\client"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mysqlclient.mak" CFG="mysqlclient - Win32 Release"
+ cd "..\mysqlmanager"
+
+"mysqlclient - Win32 ReleaseCLEAN" :
+ cd "\MYSQL-3.23\client"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mysqlclient.mak" CFG="mysqlclient - Win32 Release" RECURSE=1 CLEAN
+ cd "..\mysqlmanager"
+
+!ELSEIF "$(CFG)" == "MySqlManager - Win32 Debug"
+
+"mysqlclient - Win32 Debug" :
+ cd "\MYSQL-3.23\client"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mysqlclient.mak" CFG="mysqlclient - Win32 Debug"
+ cd "..\mysqlmanager"
+
+"mysqlclient - Win32 DebugCLEAN" :
+ cd "\MYSQL-3.23\client"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mysqlclient.mak" CFG="mysqlclient - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\mysqlmanager"
+
+!ENDIF
+
+
+!ENDIF
+
diff --git a/VC++Files/mysqlmanager/README.TXT b/VC++Files/mysqlmanager/README.TXT
new file mode 100644
index 00000000000..cdd54c2cba8
--- /dev/null
+++ b/VC++Files/mysqlmanager/README.TXT
@@ -0,0 +1,102 @@
+========================================================================
+ MICROSOFT FOUNDATION CLASS LIBRARY : MySqlManager
+========================================================================
+
+
+AppWizard has created this MySqlManager application for you. This application
+not only demonstrates the basics of using the Microsoft Foundation classes
+but is also a starting point for writing your application.
+
+This file contains a summary of what you will find in each of the files that
+make up your MySqlManager application.
+
+MySqlManager.h
+ This is the main header file for the application. It includes other
+ project specific headers (including Resource.h) and declares the
+ CMySqlManagerApp application class.
+
+MySqlManager.cpp
+ This is the main application source file that contains the application
+ class CMySqlManagerApp.
+
+MySqlManager.rc
+ This is a listing of all of the Microsoft Windows resources that the
+ program uses. It includes the icons, bitmaps, and cursors that are stored
+ in the RES subdirectory. This file can be directly edited in Microsoft
+ Developer Studio.
+
+res\MySqlManager.ico
+ This is an icon file, which is used as the application's icon. This
+ icon is included by the main resource file MySqlManager.rc.
+
+res\MySqlManager.rc2
+ This file contains resources that are not edited by Microsoft
+ Developer Studio. You should place all resources not
+ editable by the resource editor in this file.
+
+MySqlManager.clw
+ This file contains information used by ClassWizard to edit existing
+ classes or add new classes. ClassWizard also uses this file to store
+ information needed to create and edit message maps and dialog data
+ maps and to create prototype member functions.
+
+/////////////////////////////////////////////////////////////////////////////
+
+For the main frame window:
+
+MainFrm.h, MainFrm.cpp
+ These files contain the frame class CMainFrame, which is derived from
+ CMDIFrameWnd and controls all MDI frame features.
+
+res\Toolbar.bmp
+ This bitmap file is used to create tiled images for the toolbar.
+ The initial toolbar and status bar are constructed in the
+ CMainFrame class. Edit this toolbar bitmap along with the
+ array in MainFrm.cpp to add more toolbar buttons.
+
+/////////////////////////////////////////////////////////////////////////////
+
+AppWizard creates one document type and one view:
+
+MySqlManagerDoc.h, MySqlManagerDoc.cpp - the document
+ These files contain your CMySqlManagerDoc class. Edit these files to
+ add your special document data and to implement file saving and loading
+ (via CMySqlManagerDoc::Serialize).
+
+MySqlManagerView.h, MySqlManagerView.cpp - the view of the document
+ These files contain your CMySqlManagerView class.
+ CMySqlManagerView objects are used to view CMySqlManagerDoc objects.
+
+res\MySqlManagerDoc.ico
+ This is an icon file, which is used as the icon for MDI child windows
+ for the CMySqlManagerDoc class. This icon is included by the main
+ resource file MySqlManager.rc.
+
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+ These files are used to build a precompiled header (PCH) file
+ named MySqlManager.pch and a precompiled types file named StdAfx.obj.
+
+Resource.h
+ This is the standard header file, which defines new resource IDs.
+ Microsoft Developer Studio reads and updates this file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" to indicate parts of the source code you
+should add to or customize.
+
+If your application uses MFC in a shared DLL, and your application is
+in a language other than the operating system's current language, you
+will need to copy the corresponding localized resources MFC40XXX.DLL
+from the Microsoft Visual C++ CD-ROM onto the system or system32 directory,
+and rename it to be MFCLOC.DLL. ("XXX" stands for the language abbreviation.
+For example, MFC40DEU.DLL contains resources translated to German.) If you
+don't do this, some of the UI elements of your application will remain in the
+language of the operating system.
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/VC++Files/mysqlmanager/RES/BITMAP1.BMP b/VC++Files/mysqlmanager/RES/BITMAP1.BMP
new file mode 100644
index 00000000000..3751f1a6923
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/BITMAP1.BMP
Binary files differ
diff --git a/VC++Files/mysqlmanager/RES/BITMAP3.BMP b/VC++Files/mysqlmanager/RES/BITMAP3.BMP
new file mode 100644
index 00000000000..3751f1a6923
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/BITMAP3.BMP
Binary files differ
diff --git a/VC++Files/mysqlmanager/RES/BMP00001.BMP b/VC++Files/mysqlmanager/RES/BMP00001.BMP
new file mode 100644
index 00000000000..e98e93d7850
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/BMP00001.BMP
Binary files differ
diff --git a/VC++Files/mysqlmanager/RES/BMP00002.BMP b/VC++Files/mysqlmanager/RES/BMP00002.BMP
new file mode 100644
index 00000000000..2f2c195a683
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/BMP00002.BMP
Binary files differ
diff --git a/VC++Files/mysqlmanager/RES/DATABASE.BMP b/VC++Files/mysqlmanager/RES/DATABASE.BMP
new file mode 100644
index 00000000000..2fc41313541
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/DATABASE.BMP
Binary files differ
diff --git a/VC++Files/mysqlmanager/RES/FONTD.BMP b/VC++Files/mysqlmanager/RES/FONTD.BMP
new file mode 100644
index 00000000000..c77b4f4fdd0
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/FONTD.BMP
Binary files differ
diff --git a/VC++Files/mysqlmanager/RES/FONTU.BMP b/VC++Files/mysqlmanager/RES/FONTU.BMP
new file mode 100644
index 00000000000..c77b4f4fdd0
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/FONTU.BMP
Binary files differ
diff --git a/VC++Files/mysqlmanager/RES/QUERY_EX.BMP b/VC++Files/mysqlmanager/RES/QUERY_EX.BMP
new file mode 100644
index 00000000000..cc77222decc
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/QUERY_EX.BMP
Binary files differ
diff --git a/VC++Files/mysqlmanager/RES/TOOLBAR.BMP b/VC++Files/mysqlmanager/RES/TOOLBAR.BMP
new file mode 100644
index 00000000000..d501723c1ce
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/TOOLBAR.BMP
Binary files differ
diff --git a/VC++Files/mysqlmanager/RES/mysqlmanager.ico b/VC++Files/mysqlmanager/RES/mysqlmanager.ico
new file mode 100644
index 00000000000..7eef0bcbe65
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/mysqlmanager.ico
Binary files differ
diff --git a/VC++Files/mysqlmanager/RES/mysqlmanager.rc2 b/VC++Files/mysqlmanager/RES/mysqlmanager.rc2
new file mode 100644
index 00000000000..67d4f3f4a85
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/mysqlmanager.rc2
@@ -0,0 +1,13 @@
+//
+// MYSQLMANAGER.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+ #error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/VC++Files/mysqlmanager/RES/mysqlmanagerdoc.ico b/VC++Files/mysqlmanager/RES/mysqlmanagerdoc.ico
new file mode 100644
index 00000000000..2a1f1ae6ef1
--- /dev/null
+++ b/VC++Files/mysqlmanager/RES/mysqlmanagerdoc.ico
Binary files differ
diff --git a/VC++Files/mysqlmanager/RESOURCE.H b/VC++Files/mysqlmanager/RESOURCE.H
new file mode 100644
index 00000000000..def26ce6808
--- /dev/null
+++ b/VC++Files/mysqlmanager/RESOURCE.H
@@ -0,0 +1,55 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by MySqlManager.rc
+//
+#define IDC_START_PB 3
+#define IDC_STOP_PB 4
+#define ID_SERVERS_PB 7
+#define IDD_ABOUTBOX 100
+#define IDM_QUERY_EXEC 101
+#define IDM_QUERY_DATABASES 102
+#define IDM_REFRESH 103
+#define IDD_REGISTER_SERVER 114
+#define IDR_MAINFRAME 128
+#define IDR_MYSQLMTYPE 129
+#define IDD_TOOL_SQL 132
+#define IDB_BITMAP1 133
+#define IDD_TOOL_SQL_QUERY 134
+#define IDD_TOOL_SQL_RESULTS 135
+#define IDD_TOOL_SQL_STATUS 136
+#define IDC_TAB1 1000
+#define IDC_EDIT 1001
+#define IDC_QUERY_PB 1002
+#define IDC_FONT_PB 1003
+#define IDS_QUERY_EXEC 1003
+#define ID_SERVER_CB 1003
+#define ID_USER 1004
+#define IDC_SERVER_CB 1004
+#define IDC_DATABASES_PB 1005
+#define ID_PASSWORD 1005
+#define ID_HOST_CB 1006
+#define IDC_TIMER_SECS 1006
+#define ID_PORT_CB 1007
+#define IDC_CLEAR 1007
+#define ID_GROUPS_PB 1012
+#define ID_REMOVE_PB 1017
+#define ID_DISPLAY_SERVER_STATUS_CK 1057
+#define ID_USE_STANDARD_CK 1058
+#define ID_USE_TRUSTED_CK 1059
+#define IDM_SQL_TOOL_QUERY 32771
+#define IDM_TOOLS_REGISTER_SERVER 32772
+#define IDM_TOOLS_SERVER_PROPERTIES 32773
+#define IDS_QUERY_DATABASES 57346
+#define IDS_REFRESH 57347
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_3D_CONTROLS 1
+#define _APS_NEXT_RESOURCE_VALUE 136
+#define _APS_NEXT_COMMAND_VALUE 32775
+#define _APS_NEXT_CONTROL_VALUE 1008
+#define _APS_NEXT_SYMED_VALUE 104
+#endif
+#endif
diff --git a/VC++Files/mysqlmanager/STDAFX.CPP b/VC++Files/mysqlmanager/STDAFX.CPP
new file mode 100644
index 00000000000..3e0251dff43
--- /dev/null
+++ b/VC++Files/mysqlmanager/STDAFX.CPP
@@ -0,0 +1,5 @@
+// stdafx.cpp : source file that includes just the standard includes
+// MySqlManager.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
diff --git a/VC++Files/mysqlmanager/STDAFX.H b/VC++Files/mysqlmanager/STDAFX.H
new file mode 100644
index 00000000000..8cd7dfd04f3
--- /dev/null
+++ b/VC++Files/mysqlmanager/STDAFX.H
@@ -0,0 +1,28 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__826CB2EC_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
+#define AFX_STDAFX_H__826CB2EC_8B6D_11D1_AEC1_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxdisp.h> // MFC OLE automation classes
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxsock.h>
+#include "mysql.h"
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__826CB2EC_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlmanager/TOOLSQL.CPP b/VC++Files/mysqlmanager/TOOLSQL.CPP
new file mode 100644
index 00000000000..1773a3a6dc7
--- /dev/null
+++ b/VC++Files/mysqlmanager/TOOLSQL.CPP
@@ -0,0 +1,687 @@
+// ToolSql.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "MySqlManager.h"
+#include "ToolSql.h"
+
+#define WINDOW_COORDS 0
+#define CLIENT_COORDS 1
+
+#define MY_TIMER_ID 0x1234
+
+#ifdef _DEBUG
+ #define new DEBUG_NEW
+ #undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+CToolSql::CToolSql(CWnd* pParent,CResource* pServer,CResource* pResource)
+: CDialog(CToolSql::IDD, pParent)
+, m_pQuery(0)
+, m_pResults(0)
+, m_pStatus(0)
+, m_pServer(pServer)
+, m_pResource(pResource)
+, m_ui_timer(0)
+{
+ //{{AFX_DATA_INIT(CToolSql)
+ m_nIntervalTimerSeconds = 10;
+ m_bClear = FALSE;
+ //}}AFX_DATA_INIT
+ memset ( & m_lf, 0,sizeof(m_lf) );
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+CToolSql::~CToolSql()
+{
+
+ if (m_ui_timer)
+ {
+ KillTimer(MY_TIMER_ID);
+ }
+
+ if (m_pdb)
+ {
+ mysql_close(m_pdb);
+ }
+ if (m_pQuery)
+ {
+ m_pQuery->DestroyWindow();
+ delete m_pQuery;
+ }
+ if (m_pResults)
+ {
+ m_pResults->DestroyWindow();
+ delete m_pResults;
+ }
+ if (m_pStatus)
+ {
+ m_pStatus->DestroyWindow();
+ delete m_pStatus;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CToolSql)
+ DDX_Control(pDX, IDC_STOP_PB, m_ctl_Stop);
+ DDX_Control(pDX, IDC_START_PB, m_ctl_Start);
+ DDX_Control(pDX, IDC_SERVER_CB, m_ctl_Server);
+ DDX_Control(pDX, IDC_TAB1, m_tabs);
+ DDX_Text(pDX, IDC_TIMER_SECS, m_nIntervalTimerSeconds);
+ DDV_MinMaxInt(pDX, m_nIntervalTimerSeconds, 1, 120);
+ DDX_Check(pDX, IDC_CLEAR, m_bClear);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CToolSql, CDialog)
+//{{AFX_MSG_MAP(CToolSql)
+ ON_BN_CLICKED(IDC_QUERY_PB, OnQueryPb)
+ ON_BN_CLICKED(IDC_DATABASES_PB, OnQueryDatabases)
+ ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnSelchangeTab1)
+ ON_BN_CLICKED(IDC_FONT_PB, OnFontPb)
+ ON_WM_SIZE()
+ ON_BN_CLICKED(IDC_START_PB, OnStartPb)
+ ON_BN_CLICKED(IDC_STOP_PB, OnStopPb)
+ ON_WM_TIMER()
+ ON_WM_DESTROY()
+ ON_BN_CLICKED(IDC_CLEAR, OnClear)
+ ON_COMMAND(IDM_QUERY_EXEC, OnQueryPb)
+ ON_COMMAND(IDM_QUERY_DATABASES, OnQueryDatabases)
+ ON_EN_CHANGE(IDC_TIMER_SECS, OnChangeTimerSecs)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+
+BOOL CToolSql::OnInitDialog()
+{
+
+ CDialog::OnInitDialog();
+
+ m_ctl_Start . EnableWindow(TRUE);
+ m_ctl_Stop . EnableWindow(FALSE);
+
+ CString strTitle;
+
+ strTitle.Format ("mySql Query to %s on %s",m_pServer->GetDisplayName(),m_pServer->GetHostName());
+
+ m_ctl_Server.AddString ( m_pServer->GetDisplayName() );
+ m_ctl_Server.SetCurSel (0);
+
+ SetWindowText(strTitle);
+
+ CWaitCursor x;
+
+ m_btn_QueryExec.AutoLoad ( IDC_QUERY_PB, this );
+ m_btn_QueryDatabases.AutoLoad ( IDC_DATABASES_PB, this );
+ m_btn_Font.AutoLoad ( IDC_FONT_PB, this );
+
+ m_tabs.GetWindowRect ( m_rectTab[WINDOW_COORDS] );
+ GetWindowRect ( m_rectDlg[WINDOW_COORDS] );
+
+ m_tabs.GetClientRect ( m_rectTab[CLIENT_COORDS] );
+ GetClientRect ( m_rectDlg[CLIENT_COORDS] );
+
+ CMenu* pSysMenu = GetSystemMenu(FALSE);
+ if (pSysMenu != NULL)
+ {
+ CString strText;
+ strText.LoadString(IDS_QUERY_EXEC);
+ if (!strText.IsEmpty())
+ {
+ pSysMenu->AppendMenu(MF_SEPARATOR);
+ pSysMenu->AppendMenu(MF_STRING, IDM_QUERY_EXEC, strText);
+ }
+ strText.LoadString(IDS_QUERY_DATABASES);
+ if (!strText.IsEmpty())
+ {
+ pSysMenu->AppendMenu(MF_STRING, IDM_QUERY_DATABASES, strText);
+ }
+ }
+
+
+ m_pdb = new MYSQL;
+
+ CString strQuery ( "Query" );
+ CString strResults ( "Results" );
+ CString strStatus ( "Status" );
+
+ TC_ITEM tc1 = { TCIF_TEXT, 0,0, (LPSTR)(LPCTSTR)strQuery, strQuery.GetLength(), 0,0};
+ TC_ITEM tc2 = { TCIF_TEXT, 0,0, (LPSTR)(LPCTSTR)strResults, strResults.GetLength(), 0,0};
+ TC_ITEM tc3 = { TCIF_TEXT, 0,0, (LPSTR)(LPCTSTR)strStatus, strStatus.GetLength(), 0,0};
+
+ m_tabs.InsertItem ( 0,&tc1 );
+ m_tabs.InsertItem ( 1,&tc2 );
+ m_tabs.InsertItem ( 2,&tc3 );
+
+ m_pQuery = new CToolSqlQuery ( NULL );
+ m_pResults = new CToolSqlResults ( NULL );
+ m_pStatus = new CToolSqlStatus ( NULL );
+
+ try
+ {
+
+// OpenDatabase();
+//
+// m_pSelection->SetDatabase ( & m_db );
+// m_pScript->SetDatabase ( & m_db );
+// m_pLog->SetDatabase ( & m_db );
+
+ m_pQuery -> Create ( (LPCTSTR)IDD_TOOL_SQL_QUERY, &m_tabs );
+ m_pResults -> Create ( (LPCTSTR)IDD_TOOL_SQL_RESULTS, &m_tabs );
+ m_pStatus -> Create ( (LPCTSTR)IDD_TOOL_SQL_STATUS, &m_tabs );
+
+ ActivateTab ( 0 );
+
+ m_pQuery -> SetWindowPos(NULL,20,24,0,0,SWP_NOZORDER|SWP_NOSIZE);
+ m_pResults -> SetWindowPos(NULL,20,24,0,0,SWP_NOZORDER|SWP_NOSIZE);
+ m_pStatus -> SetWindowPos(NULL,20,24,0,0,SWP_NOZORDER|SWP_NOSIZE);
+
+ DoOnSize( SIZE_RESTORED, m_rectDlg[CLIENT_COORDS].Width(), m_rectDlg[CLIENT_COORDS].Height() );
+
+ }
+ catch (...)
+ {
+ }
+
+ mysql_init(m_pdb);
+ if (!mysql_real_connect(m_pdb,m_pServer->GetHostName(), m_pServer->GetUserName(),m_pServer->GetPassword(),0,m_pServer->GetPortNumber(), NullS,0))
+ {
+// my_printf_error(0,"connect to server at '%s' failed; error: '%s'",
+// MYF(ME_BELL), pResource->GetHostName(), mysql_error(&mysql));
+ CString strText;
+ strText.Format ( "connect to server at '%s' failed; error: '%s'", m_pServer->GetHostName(), mysql_error(m_pdb));
+ AfxMessageBox(strText);
+ EndDialog(IDCANCEL);
+ return FALSE;
+ }
+
+ if ( m_pResource && m_pResource->GetType() == CResource::eDatabase )
+ {
+ CString strDB = m_pResource->GetDisplayName();
+ strDB.TrimRight();
+ if (mysql_select_db(m_pdb,strDB))
+ {
+ }
+ }
+
+ return FALSE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::ActivateTab ( int tab )
+
+{
+ switch (tab)
+ {
+ case 0: ;
+ m_pResults-> ShowWindow(SW_HIDE);
+ m_pStatus-> ShowWindow(SW_HIDE);
+ m_pQuery-> ShowWindow(SW_SHOW);
+ m_pQuery->m_ctl_edit.SetFocus();
+ break;
+ case 1: ;
+ m_pQuery-> ShowWindow(SW_HIDE);
+ m_pStatus-> ShowWindow(SW_HIDE);
+ m_pResults-> ShowWindow(SW_SHOW);
+ m_pResults->m_ctl_edit.SetFocus();
+ break;
+ case 2: ;
+ m_pResults-> ShowWindow(SW_HIDE);
+ m_pQuery-> ShowWindow(SW_HIDE);
+ m_pStatus-> ShowWindow(SW_SHOW);
+ m_pStatus->m_ctl_edit.SetFocus();
+ break;
+ default:
+ break;
+ }
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CalculateFontSize ( CEdit& ed, CSize& sizeRet )
+
+{
+
+ CDC* pdc = ed.GetDC();
+
+ int nAveWidth , nAveHeight;
+ int i ;
+
+ CSize size ;
+
+ static BOOL bFirstTime = TRUE;
+ static char rgchAlphabet [54] ;
+
+ if ( bFirstTime )
+ {
+ bFirstTime = false;
+ for ( i = 0 ; i <= 25 ; i++)
+ {
+ rgchAlphabet[i] = (char)(i+(int)'a') ;
+ rgchAlphabet[i+26] = (char)(i+(int)'A') ;
+ }
+ rgchAlphabet[52] = 0x20;
+ rgchAlphabet[53] = 0x20;
+ }
+
+ CFont* pf = ed.GetFont();
+ LOGFONT lf;
+ pf->GetLogFont(&lf);
+ pdc->SelectObject (pf);
+ GetTextExtentPoint32 ( pdc->m_hDC, (LPSTR) rgchAlphabet, 54, & size ) ;
+
+ nAveWidth = size.cx / 54 ;
+
+ if ( size.cx % 54 )
+ {
+ nAveWidth++;
+ }
+
+ nAveHeight = size.cy; //6 * size.cy / 4;
+
+ sizeRet.cx = nAveWidth;
+ sizeRet.cy = nAveHeight; // tm.tmHeight;
+
+ ed.ReleaseDC(pdc);
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+int ProcessYieldMessage ()
+{
+
+ CWinApp* pApp = AfxGetApp();
+
+ if ( pApp )
+ {
+ MSG msgx;
+ while (::PeekMessage(&msgx, NULL, NULL, NULL, PM_NOREMOVE))
+ try
+ {
+ if (!pApp->PumpMessage())
+ {
+// ExitProcess(1);
+ }
+ }
+ catch (...)
+ {
+ }
+ }
+
+ return 0;
+
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+void print_table_data(MYSQL_RES *result,CString& str,CEdit& ed,LOGFONT& lf)
+{
+ MYSQL_ROW cur;
+ uint length;
+ MYSQL_FIELD* field;
+ bool* num_flag;
+ my_ulonglong nRows = mysql_num_rows(result);
+ uint nFields = mysql_num_fields(result);
+ int* rgi = new int [nFields];
+ memset ( rgi, 0, nFields*sizeof(int) );
+ num_flag=(bool*) my_alloca(sizeof(bool)*nFields);
+
+ ed.SetLimitText(65535*16);
+
+ CSize sizeFont;
+ CalculateFontSize ( ed, sizeFont );
+ uint index = 0;
+ rgi[index++]=0;
+ CString separator("");
+
+ mysql_field_seek(result,0);
+
+ for (uint off=0; (field = mysql_fetch_field(result)) ; off++)
+ {
+ uint length= (uint) strlen(field->name);
+ length=max(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length+1;
+ int n=length+2;
+ for (uint i=lstrlen(field->name); i-- > 0 ; ) separator+="-";
+ if ( index!= nFields )
+ {
+ int o = rgi[index-1];
+ rgi[index++]=o+((n+1)*sizeFont.cx)/2;
+ }
+ separator+='\t';
+ str += field->name;
+ str += "\t";
+ num_flag[off]= IS_NUM(field->type);
+ }
+ separator += "\r\n";
+ str += "\r\n";
+ str += separator;
+ ed.SetSel(-1,-1);
+ ed.ReplaceSel(str);
+
+ if ( 1 || nRows > 100 )
+ {
+ while ((cur = mysql_fetch_row(result)))
+ {
+ ProcessYieldMessage ();
+ mysql_field_seek(result,0);
+ str.Empty();
+ ed.SetSel(-1,-1);
+ for (uint off=0 ; off < mysql_num_fields(result); off++)
+ {
+ field = mysql_fetch_field(result);
+ length=field->max_length;
+ CString strText;
+ strText.Format ("%s", cur[off] ? (char*) cur[off] : "NULL");
+ str += strText;
+ str += "\t";
+ }
+ str += "\r\n";
+ ed.SetSel(-1,-1);
+ ed.ReplaceSel(str);
+ }
+ }
+ else
+ {
+ while ((cur = mysql_fetch_row(result)))
+ {
+ mysql_field_seek(result,0);
+ for (uint off=0 ; off < mysql_num_fields(result); off++)
+ {
+ field = mysql_fetch_field(result);
+ length=field->max_length;
+ CString strText;
+ strText.Format ("%s", cur[off] ? (char*) cur[off] : "NULL");
+ str += strText;
+ str += "\t";
+ }
+ str += "\r\n";
+ }
+ }
+ my_afree((gptr) num_flag);
+ str += "\r\n";
+ ed.SetTabStops(nFields,rgi);
+ delete [] rgi;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::OnQueryPb()
+{
+
+ CWaitCursor x;
+// mysql_select_db(m_pdb,"mysql");
+
+ if ( m_pResource && m_pResource->GetType() == CResource::eDatabase )
+ {
+ CString strDB = m_pResource->GetDisplayName();
+ strDB.TrimRight();
+ if (mysql_select_db(m_pdb,strDB))
+ {
+ }
+ }
+
+ m_pQuery->UpdateData();
+ m_pResults->m_edit.Empty();
+ CString str = m_pQuery->m_edit;
+ if ( mysql_real_query(m_pdb,str,str.GetLength())==0 )
+ {
+ MYSQL_RES *result;
+ if ((result=mysql_store_result(m_pdb)))
+ {
+ my_ulonglong nRows = mysql_num_rows(result);
+ m_pResults->UpdateData(FALSE);
+ m_tabs.SetCurSel(1);
+ ActivateTab ( 1 );
+ print_table_data(result,m_pResults->m_edit,m_pResults->m_ctl_edit,m_lf);
+// m_pResults->UpdateData(FALSE);
+ m_pResults->m_ctl_edit.SetSel(-1,-1);
+ CString strText;
+ strText.Format ( "\r\n(%d row(s) affected)\r\n", nRows );
+ m_pResults->m_ctl_edit.ReplaceSel(strText);
+ mysql_free_result(result);
+ }
+ else
+ {
+ m_pResults->m_edit = mysql_error(m_pdb);
+ m_pResults->UpdateData(FALSE);
+ }
+ }
+ else
+ {
+ m_pResults->m_edit = mysql_error(m_pdb);
+ m_pResults->UpdateData(FALSE);
+ }
+
+ m_tabs.SetCurSel(1);
+ ActivateTab ( 1 );
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::OnQueryDatabases()
+{
+ CWaitCursor x;
+ MYSQL_RES *result;
+ m_pResults->m_edit.Empty();
+ if ((result=mysql_list_dbs(m_pdb,0)))
+ {
+ my_ulonglong nRows = mysql_num_rows(result);
+ print_table_data(result,m_pResults->m_edit,m_pResults->m_ctl_edit,m_lf);
+ //m_pResults->UpdateData(FALSE);
+ mysql_free_result(result);
+ }
+ else
+ {
+ m_pResults->m_edit = mysql_error(m_pdb);
+ m_pResults->UpdateData(FALSE);
+ }
+
+ m_tabs.SetCurSel(1);
+ ActivateTab ( 1 );
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ ActivateTab ( m_tabs.GetCurSel() );
+ *pResult = 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::OnFontPb()
+{
+
+ CFontDialog FontDlg ( & m_lf );
+
+ if ( FontDlg.DoModal ( ) == IDOK )
+ {
+ if (m_font.GetSafeHandle())
+ m_font.DeleteObject();
+ m_lf = *FontDlg.m_cf.lpLogFont;
+ m_font.CreateFontIndirect(FontDlg.m_cf.lpLogFont);
+ m_pQuery->SetFont(&m_font);
+ m_pResults->SetFont(&m_font);
+ m_pStatus->SetFont(&m_font);
+ }
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::DoOnSize(UINT nType, int cx, int cy)
+{
+
+ int nx = cx - ( m_rectDlg[CLIENT_COORDS].Width ( ) - m_rectTab[CLIENT_COORDS].Width ( ) );
+ int ny = cy - ( m_rectDlg[CLIENT_COORDS].Height ( ) - m_rectTab[CLIENT_COORDS].Height ( ) );
+
+ if (IsWindow(m_tabs.GetSafeHwnd()))
+ {
+ m_tabs.SetWindowPos ( NULL
+ , 0
+ , 0
+ , nx
+ , ny
+ , SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW );
+
+ if (m_pResults&&IsWindow(m_pResults->GetSafeHwnd()))
+ m_pResults -> SetWindowPos(NULL,20,24,nx-40,ny-48,SWP_NOZORDER | SWP_NOMOVE );
+ if (m_pQuery&&IsWindow(m_pQuery->GetSafeHwnd()))
+ m_pQuery -> SetWindowPos(NULL,20,24,nx-40,ny-48,SWP_NOZORDER | SWP_NOMOVE );
+ if (m_pStatus&&IsWindow(m_pStatus->GetSafeHwnd()))
+ m_pStatus -> SetWindowPos(NULL,20,24,nx-40,ny-48,SWP_NOZORDER | SWP_NOMOVE );
+// switch ( m_tabs.GetCurSel() )
+// {
+// case 0:
+// {
+// if (m_pResults&&IsWindow(m_pResults->GetSafeHwnd()))
+// m_pResults -> SetWindowPos(NULL,20,24,nx-40,ny-48,SWP_NOZORDER | SWP_NOMOVE | SWP_HIDEWINDOW );
+// if (m_pQuery&&IsWindow(m_pQuery->GetSafeHwnd()))
+// m_pQuery -> SetWindowPos(NULL,20,24,nx-40,ny-48,SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW );
+// break;
+// }
+// case 1:
+// {
+// if (m_pQuery&&IsWindow(m_pQuery->GetSafeHwnd()))
+// m_pQuery -> SetWindowPos(NULL,20,24,nx-40,ny-48,SWP_NOZORDER | SWP_NOMOVE | SWP_HIDEWINDOW );
+// if (m_pResults&&IsWindow(m_pResults->GetSafeHwnd()))
+// m_pResults -> SetWindowPos(NULL,20,24,nx-40,ny-48,SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW );
+// break;
+// }
+// }
+ }
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::OnSize(UINT nType, int cx, int cy)
+{
+
+ CDialog::OnSize(nType, cx, cy);
+
+ DoOnSize ( nType, cx, cy );
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::OnOK()
+{
+ CDialog::OnOK();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::OnCancel()
+{
+ CDialog::OnCancel();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+BOOL CToolSql::PreTranslateMessage(MSG* pMsg)
+{
+ return CDialog::PreTranslateMessage(pMsg);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::DoProcessListQuery()
+{
+
+ MYSQL_RES *result;
+ if (result=mysql_list_processes(m_pdb))
+ {
+ if (m_bClear)
+ {
+ m_pStatus->m_edit.Empty();
+ m_pStatus->UpdateData(FALSE);
+ }
+ print_table_data(result,m_pStatus->m_edit,m_pStatus->m_ctl_edit,m_lf);
+ mysql_free_result(result);
+ }
+ else
+ {
+// my_printf_error(0,"process list failed; error: '%s'",MYF(ME_BELL),mysql_error(mysql));
+ }
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::OnStartPb()
+{
+ UpdateData();
+ if (m_ui_timer) return;
+ if (m_nIntervalTimerSeconds<1) return;
+ ActivateTab ( 2 );
+ m_ui_timer = SetTimer( MY_TIMER_ID, m_nIntervalTimerSeconds*1000, NULL );
+ m_ctl_Start . EnableWindow(FALSE);
+ m_ctl_Stop . EnableWindow(TRUE);
+ DoProcessListQuery();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::OnStopPb()
+{
+ UpdateData();
+ if (m_ui_timer)
+ {
+ KillTimer(MY_TIMER_ID);
+ m_ui_timer = 0;
+ }
+ m_ctl_Start . EnableWindow(TRUE);
+ m_ctl_Stop . EnableWindow(FALSE);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSql::OnTimer(UINT nIDEvent)
+{
+ DoProcessListQuery();
+ CDialog::OnTimer(nIDEvent);
+}
+
+void CToolSql::OnDestroy()
+{
+ if (m_ui_timer)
+ {
+ KillTimer(MY_TIMER_ID);
+ m_ui_timer = 0;
+ }
+ CDialog::OnDestroy();
+}
+
+void CToolSql::OnClear()
+{
+ UpdateData();
+}
+
+void CToolSql::OnChangeTimerSecs()
+{
+ UpdateData();
+}
diff --git a/VC++Files/mysqlmanager/TOOLSQL.H b/VC++Files/mysqlmanager/TOOLSQL.H
new file mode 100644
index 00000000000..7d608f46cd2
--- /dev/null
+++ b/VC++Files/mysqlmanager/TOOLSQL.H
@@ -0,0 +1,102 @@
+#if !defined(AFX_ToolSql_H__826CB2FC_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
+#define AFX_ToolSql_H__826CB2FC_8B6D_11D1_AEC1_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#include "ToolSqlQuery.h"
+#include "ToolSqlResults.h"
+#include "ToolSqlStatus.h"
+#include "cresource.h"
+#include <my_global.h>
+#include "my_sys.h"
+#include "mysql.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CToolSql dialog
+
+class CToolSql : public CDialog
+{
+// Construction
+public:
+ CToolSql(CWnd* pParent = NULL,CResource* pServer=NULL,CResource* pResource=NULL);
+ ~CToolSql();
+
+// Dialog Data
+ //{{AFX_DATA(CToolSql)
+ enum { IDD = IDD_TOOL_SQL };
+ CButton m_ctl_Stop;
+ CButton m_ctl_Start;
+ CComboBox m_ctl_Server;
+ CTabCtrl m_tabs;
+ int m_nIntervalTimerSeconds;
+ BOOL m_bClear;
+ //}}AFX_DATA
+
+ CBitmapButton m_btn_QueryExec;
+ CBitmapButton m_btn_Font;
+ CBitmapButton m_btn_QueryDatabases;
+
+#ifdef _WIN64
+ __int64 m_ui_timer;
+#else
+ UINT m_ui_timer;
+#endif
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CToolSql)
+ public:
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+
+ void ActivateTab ( int tab );
+ void DoProcessListQuery();
+
+ CToolSqlQuery* m_pQuery;
+ CToolSqlResults* m_pResults;
+ CToolSqlStatus* m_pStatus;
+
+ CResource* m_pServer;
+ CResource* m_pResource;
+ MYSQL* m_pdb;
+ CFont m_font;
+ LOGFONT m_lf;
+ CRect m_rectTab[2];
+ CRect m_rectDlg[2];
+
+protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(CToolSql)
+ virtual BOOL OnInitDialog();
+ afx_msg void OnQueryPb();
+ afx_msg void OnQueryDatabases();
+ afx_msg void OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnFontPb();
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ virtual void OnOK();
+ virtual void OnCancel();
+ afx_msg void OnStartPb();
+ afx_msg void OnStopPb();
+ afx_msg void OnTimer(UINT nIDEvent);
+ afx_msg void OnDestroy();
+ afx_msg void OnClear();
+ afx_msg void OnChangeTimerSecs();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+ void DoOnSize(UINT nType, int cx, int cy) ;
+
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_ToolSql_H__826CB2FC_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlmanager/cresource.h b/VC++Files/mysqlmanager/cresource.h
new file mode 100644
index 00000000000..37c1839d758
--- /dev/null
+++ b/VC++Files/mysqlmanager/cresource.h
@@ -0,0 +1,134 @@
+#ifndef _CRESOURCE_H
+#define _CRESOURCE_H
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define MYSQL_PORT_AS_STRING "3306" /* Can't use # in preprocessor because of bugs in VC++ 5.0 */
+
+class CResource
+{
+public:
+ enum eRESOURCETYPE
+ {
+ eNone
+ , eServer
+ , eDatabase
+ , eTable
+ , eField
+ , eProcesslist
+ , eProcesslistItem
+ };
+ virtual LPCTSTR GetDisplayName() { return ""; }
+ virtual LPCTSTR GetHostName() { return LOCAL_HOST; }
+ virtual LPCTSTR GetUserName() { return "root"; }
+ virtual LPCTSTR GetPassword() { return ""; }
+ virtual LPCTSTR GetPortName() { return MYSQL_PORT_AS_STRING; }
+ virtual int GetPortNumber() { return MYSQL_PORT; }
+ virtual eRESOURCETYPE GetType() { return eNone; }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CResourceServer : public CResource
+{
+public:
+ CResourceServer(LPCTSTR pszName = "",LPCTSTR pszHost = LOCAL_HOST ,LPCTSTR pszUser = "root", LPCTSTR pszPassword = "", LPCTSTR pszPort = MYSQL_PORT_AS_STRING)
+ : m_strName(pszName)
+ , m_strHost(pszHost)
+ , m_strUser(pszUser)
+ , m_strPassword(pszPassword)
+ , m_strPort(pszPort)
+ {
+ }
+ virtual LPCTSTR GetDisplayName() { return m_strName; }
+ virtual LPCTSTR GetHostName() { return m_strHost; }
+ virtual LPCTSTR GetUserName() { return m_strUser; }
+ virtual LPCTSTR GetPassword() { return m_strPassword; }
+ virtual eRESOURCETYPE GetType() { return eServer; }
+ virtual LPCTSTR GetPortName() { return m_strPort; }
+ virtual int GetPortNumber() { return atoi(m_strPort); }
+ CString m_strName;
+ CString m_strHost;
+ CString m_strUser;
+ CString m_strPassword;
+ CString m_strPort;
+ CStringArray m_rgFields;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CResourceDatabase : public CResource
+{
+public:
+ CResourceDatabase(LPCTSTR pszName = "")
+ : m_strName(pszName)
+ {
+ }
+ virtual LPCTSTR GetDisplayName() { return m_strName; }
+ virtual eRESOURCETYPE GetType() { return eDatabase; }
+ CString m_strName;
+ CStringArray m_rgFields;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CResourceTable : public CResource
+{
+public:
+ CResourceTable(LPCTSTR pszName = "")
+ : m_strName(pszName)
+ {
+ }
+ virtual LPCTSTR GetDisplayName() { return m_strName; }
+ virtual eRESOURCETYPE GetType() { return eTable; }
+ CString m_strName;
+ CStringArray m_rgFields;
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CResourceField : public CResource
+{
+public:
+ CResourceField(LPCTSTR pszName = "")
+ : m_strName(pszName)
+ {
+ }
+ virtual LPCTSTR GetDisplayName() { return m_strName; }
+ virtual eRESOURCETYPE GetType() { return eField; }
+ CString m_strName;
+ CStringArray m_rgFields;
+};
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CResourceProcesslist : public CResource
+{
+public:
+ CResourceProcesslist(LPCTSTR pszName = "Processlist")
+ : m_strName(pszName)
+ {
+ }
+ virtual LPCTSTR GetDisplayName() { return m_strName; }
+ virtual eRESOURCETYPE GetType() { return eProcesslist; }
+ CString m_strName;
+ CStringArray m_rgFields;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CResourceProcesslistItem : public CResourceProcesslist
+{
+public:
+ CResourceProcesslistItem(LPCTSTR pszName = "ProcesslistItem")
+ : CResourceProcesslist(pszName)
+ {
+ }
+ virtual eRESOURCETYPE GetType() { return eProcesslistItem; }
+};
+
+
+#endif
diff --git a/VC++Files/mysqlmanager/mysqlmanager.cpp b/VC++Files/mysqlmanager/mysqlmanager.cpp
new file mode 100644
index 00000000000..09a19181e22
--- /dev/null
+++ b/VC++Files/mysqlmanager/mysqlmanager.cpp
@@ -0,0 +1,168 @@
+// MySqlManager.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "MySqlManager.h"
+
+#include "MainFrm.h"
+#include "ChildFrm.h"
+#include "MySqlManagerDoc.h"
+#include "MySqlManagerView.h"
+
+#ifdef _DEBUG
+ #define new DEBUG_NEW
+ #undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CMySqlManagerApp
+
+BEGIN_MESSAGE_MAP(CMySqlManagerApp, CWinApp)
+//{{AFX_MSG_MAP(CMySqlManagerApp)
+ ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
+// NOTE - the ClassWizard will add and remove mapping macros here.
+// DO NOT EDIT what you see in these blocks of generated code!
+//}}AFX_MSG_MAP
+// Standard file based document commands
+ ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
+ ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
+// Standard print setup command
+ ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CMySqlManagerApp construction
+
+CMySqlManagerApp::CMySqlManagerApp()
+{
+ // TODO: add construction code here,
+ // Place all significant initialization in InitInstance
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// The one and only CMySqlManagerApp object
+
+CMySqlManagerApp theApp;
+
+/////////////////////////////////////////////////////////////////////////////
+// CMySqlManagerApp initialization
+
+BOOL CMySqlManagerApp::InitInstance()
+{
+
+ WSADATA WsaData;
+
+ if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
+ {
+ AfxMessageBox("WSAStartup Failed\n");
+ return FALSE;
+ }
+
+ AfxEnableControlContainer();
+
+ // Standard initialization
+ // If you are not using these features and wish to reduce the size
+ // of your final executable, you should remove from the following
+ // the specific initialization routines you do not need.
+
+#ifdef _AFXDLL
+ Enable3dControls(); // Call this when using MFC in a shared DLL
+#else
+ Enable3dControlsStatic(); // Call this when linking to MFC statically
+#endif
+
+ // Change the registry key under which our settings are stored.
+ // You should modify this string to be something appropriate
+ // such as the name of your company or organization.
+ SetRegistryKey(_T("Local AppWizard-Generated Applications"));
+
+ LoadStdProfileSettings(); // Load standard INI file options (including MRU)
+
+ // Register the application's document templates. Document templates
+ // serve as the connection between documents, frame windows and views.
+
+ CMultiDocTemplate* pDocTemplate;
+ pDocTemplate = new CMultiDocTemplate(
+ IDR_MYSQLMTYPE,
+ RUNTIME_CLASS(CMySqlManagerDoc),
+ RUNTIME_CLASS(CChildFrame), // custom MDI child frame
+ RUNTIME_CLASS(CMySqlManagerView));
+ AddDocTemplate(pDocTemplate);
+
+ // create main MDI Frame window
+ CMainFrame* pMainFrame = new CMainFrame;
+ if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
+ return FALSE;
+ m_pMainWnd = pMainFrame;
+
+ // Parse command line for standard shell commands, DDE, file open
+ CCommandLineInfo cmdInfo;
+ ParseCommandLine(cmdInfo);
+
+ // Dispatch commands specified on the command line
+ if (!ProcessShellCommand(cmdInfo))
+ return FALSE;
+
+ // The main window has been initialized, so show and update it.
+ pMainFrame->ShowWindow(m_nCmdShow);
+ pMainFrame->UpdateWindow();
+
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+ CAboutDlg();
+
+// Dialog Data
+ //{{AFX_DATA(CAboutDlg)
+ enum {IDD = IDD_ABOUTBOX};
+ //}}AFX_DATA
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CAboutDlg)
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ //{{AFX_MSG(CAboutDlg)
+ // No message handlers
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+ //{{AFX_DATA_INIT(CAboutDlg)
+ //}}AFX_DATA_INIT
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CAboutDlg)
+ //}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+//{{AFX_MSG_MAP(CAboutDlg)
+// No message handlers
+//}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+// App command to run the dialog
+void CMySqlManagerApp::OnAppAbout()
+{
+ CAboutDlg aboutDlg;
+ aboutDlg.DoModal();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CMySqlManagerApp commands
diff --git a/VC++Files/mysqlmanager/mysqlmanager.dsw b/VC++Files/mysqlmanager/mysqlmanager.dsw
index 02ec9a86dc5..013873b113b 100644
--- a/VC++Files/mysqlmanager/mysqlmanager.dsw
+++ b/VC++Files/mysqlmanager/mysqlmanager.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/mysqlmanager/mysqlmanager.h b/VC++Files/mysqlmanager/mysqlmanager.h
new file mode 100644
index 00000000000..accb63a908f
--- /dev/null
+++ b/VC++Files/mysqlmanager/mysqlmanager.h
@@ -0,0 +1,50 @@
+// MySqlManager.h : main header file for the MYSQLMANAGER application
+//
+
+#if !defined(AFX_MYSQLMANAGER_H__826CB2EA_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
+#define AFX_MYSQLMANAGER_H__826CB2EA_8B6D_11D1_AEC1_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+/////////////////////////////////////////////////////////////////////////////
+// CMySqlManagerApp:
+// See MySqlManager.cpp for the implementation of this class
+//
+
+class CMySqlManagerApp : public CWinApp
+{
+public:
+ CMySqlManagerApp();
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CMySqlManagerApp)
+ public:
+ virtual BOOL InitInstance();
+ //}}AFX_VIRTUAL
+
+// Implementation
+
+ //{{AFX_MSG(CMySqlManagerApp)
+ afx_msg void OnAppAbout();
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code !
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_MYSQLMANAGER_H__826CB2EA_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlmanager/mysqlmanager.rc b/VC++Files/mysqlmanager/mysqlmanager.rc
new file mode 100644
index 00000000000..1dd9caeb686
--- /dev/null
+++ b/VC++Files/mysqlmanager/mysqlmanager.rc
@@ -0,0 +1,572 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "#ifdef _WIN32\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#endif\r\n"
+ "#include ""res\\MySqlManager.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#include ""afxprint.rc"" // printing/print preview resources\r\n"
+ "#endif\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON DISCARDABLE "res\\MySqlManager.ico"
+IDR_MYSQLMTYPE ICON DISCARDABLE "res\\MySqlManagerDoc.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDR_MAINFRAME BITMAP MOVEABLE PURE "res\\Toolbar.bmp"
+IDB_BITMAP1 BITMAP DISCARDABLE "res\\bitmap3.bmp"
+IDB_QUERY_EXECU BITMAP FIXED IMPURE "res\\query_ex.bmp"
+IDB_QUERY_EXECD BITMAP FIXED IMPURE "res\\bmp00001.bmp"
+IDB_FONTU BITMAP FIXED IMPURE "res\\fontu.bmp"
+IDB_FONTD BITMAP FIXED IMPURE "res\\fontd.bmp"
+IDB_DATABASESU BITMAP FIXED IMPURE "res\\database.bmp"
+IDB_DATABASESD BITMAP FIXED IMPURE "res\\bmp00002.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Toolbar
+//
+
+IDR_MAINFRAME TOOLBAR DISCARDABLE 16, 15
+BEGIN
+ BUTTON ID_FILE_NEW
+ BUTTON ID_FILE_OPEN
+ BUTTON ID_FILE_SAVE
+ SEPARATOR
+ BUTTON ID_EDIT_CUT
+ BUTTON ID_EDIT_COPY
+ BUTTON ID_EDIT_PASTE
+ SEPARATOR
+ BUTTON ID_FILE_PRINT
+ BUTTON ID_APP_ABOUT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MAINFRAME MENU PRELOAD DISCARDABLE
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&New\tCtrl+N", ID_FILE_NEW
+ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
+ MENUITEM SEPARATOR
+ MENUITEM "P&rint Setup...", ID_FILE_PRINT_SETUP
+ MENUITEM SEPARATOR
+ MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", ID_APP_EXIT
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
+ MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&About MySqlManager...", ID_APP_ABOUT
+ END
+END
+
+IDR_MYSQLMTYPE MENU PRELOAD DISCARDABLE
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&New\tCtrl+N", ID_FILE_NEW
+ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
+ MENUITEM "&Close", ID_FILE_CLOSE
+ MENUITEM "&Save\tCtrl+S", ID_FILE_SAVE
+ MENUITEM "Save &As...", ID_FILE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "&Print...\tCtrl+P", ID_FILE_PRINT
+ MENUITEM "Print Pre&view", ID_FILE_PRINT_PREVIEW
+ MENUITEM "P&rint Setup...", ID_FILE_PRINT_SETUP
+ MENUITEM SEPARATOR
+ MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", ID_APP_EXIT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "&Undo\tCtrl+Z", ID_EDIT_UNDO
+ MENUITEM SEPARATOR
+ MENUITEM "Cu&t\tCtrl+X", ID_EDIT_CUT
+ MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY
+ MENUITEM "&Paste\tCtrl+V", ID_EDIT_PASTE
+ END
+ POPUP "&Tools"
+ BEGIN
+ MENUITEM "SQL &Query", IDM_SQL_TOOL_QUERY
+ MENUITEM "Register Server", IDM_TOOLS_REGISTER_SERVER
+ MENUITEM "Server Properties", IDM_TOOLS_SERVER_PROPERTIES
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
+ MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR
+ END
+ POPUP "&Window"
+ BEGIN
+ MENUITEM "&New Window", ID_WINDOW_NEW
+ MENUITEM "&Cascade", ID_WINDOW_CASCADE
+ MENUITEM "&Tile", ID_WINDOW_TILE_HORZ
+ MENUITEM "&Arrange Icons", ID_WINDOW_ARRANGE
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&About MySqlManager...", ID_APP_ABOUT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
+BEGIN
+ "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ "D", IDM_QUERY_DATABASES, VIRTKEY, ALT, NOINVERT
+ "E", IDM_QUERY_EXEC, VIRTKEY, CONTROL, NOINVERT
+ "N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
+ "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
+ "P", ID_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT
+ "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
+ "V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
+ VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT, NOINVERT
+ VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT, NOINVERT
+ VK_F6, ID_NEXT_PANE, VIRTKEY, NOINVERT
+ VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT, NOINVERT
+ VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT
+ "X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
+ "X", IDM_QUERY_EXEC, VIRTKEY, ALT, NOINVERT
+ "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 234, 72
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About MySqlManager"
+FONT 8, "MS Sans Serif"
+BEGIN
+ ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
+ LTEXT "MySqlManager Version 1.0.2",IDC_STATIC,37,10,119,8,
+ SS_NOPREFIX
+ LTEXT "By James Pereira (jpereira@iafrica.com)",IDC_STATIC,37,
+ 49,146,9
+ DEFPUSHBUTTON "OK",IDOK,195,7,32,14,WS_GROUP
+ LTEXT "This file is public domain and comes with NO WARRANTY of any kind",
+ IDC_STATIC,38,25,136,18,SS_SUNKEN
+END
+
+IDD_TOOL_SQL DIALOGEX 0, 0, 452, 246
+STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_CLIENTEDGE
+CAPTION "mySQL Query Tool"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ PUSHBUTTON "OK",IDOK,369,10,12,14,NOT WS_VISIBLE
+ DEFPUSHBUTTON "Close",IDCANCEL,391,10,50,14
+ CONTROL "Tab1",IDC_TAB1,"SysTabControl32",0x0,11,26,434,213
+ CONTROL "IDB_QUERY_EXEC",IDC_QUERY_PB,"Button",BS_OWNERDRAW |
+ WS_TABSTOP,106,10,12,14
+ CONTROL "IDB_FONT",IDC_FONT_PB,"Button",BS_OWNERDRAW |
+ WS_TABSTOP,123,10,12,14
+ COMBOBOX IDC_SERVER_CB,12,9,85,128,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ CONTROL "IDB_DATABASES",IDC_DATABASES_PB,"Button",BS_OWNERDRAW |
+ WS_TABSTOP,142,10,12,14
+ DEFPUSHBUTTON "&Start",IDC_START_PB,315,10,23,14
+ DEFPUSHBUTTON "S&top",IDC_STOP_PB,343,10,23,14
+ EDITTEXT IDC_TIMER_SECS,287,10,22,14,ES_AUTOHSCROLL
+ LTEXT "Interval (s)",IDC_STATIC,249,11,34,8
+ CONTROL "Clear",IDC_CLEAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 215,11,29,10
+END
+
+IDD_TOOL_SQL_QUERY DIALOG DISCARDABLE 0, 0, 452, 247
+STYLE WS_CHILD | WS_BORDER
+FONT 8, "MS Sans Serif"
+BEGIN
+ EDITTEXT IDC_EDIT,11,11,434,229,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+END
+
+IDD_TOOL_SQL_RESULTS DIALOG DISCARDABLE 0, 0, 452, 247
+STYLE WS_CHILD | WS_BORDER
+FONT 8, "MS Sans Serif"
+BEGIN
+ EDITTEXT IDC_EDIT,11,11,434,229,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | WS_VSCROLL
+END
+
+IDD_REGISTER_SERVER DIALOG FIXED IMPURE 0, 0, 281, 199
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Register Server"
+FONT 8, "MS Sans Serif"
+BEGIN
+ GROUPBOX "",-1,5,0,270,195
+ LTEXT "&Server:",-1,12,14,25,8
+ COMBOBOX ID_SERVER_CB,46,12,159,60,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Host",-1,12,33,25,8
+ COMBOBOX ID_HOST_CB,46,31,159,60,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Port",-1,12,53,25,8
+ COMBOBOX ID_PORT_CB,46,50,159,60,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Login Information",-1,12,82,194,76
+ CONTROL "Use S&tandard Security",ID_USE_STANDARD_CK,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,19,107,94,11
+ CONTROL "Use Tr&usted Connection",ID_USE_TRUSTED_CK,"Button",
+ BS_AUTORADIOBUTTON,19,94,99,11
+ LTEXT "&Login ID:",1060,37,124,35,8
+ EDITTEXT ID_USER,77,122,120,12,ES_AUTOHSCROLL | WS_GROUP
+ LTEXT "&Password:",1061,37,140,35,8
+ EDITTEXT ID_PASSWORD,77,138,120,12,ES_PASSWORD | ES_AUTOHSCROLL
+ LTEXT "S&erver Group:",-1,12,164,24,25
+ CONTROL "&Display Server Status in Server Manager",
+ ID_DISPLAY_SERVER_STATUS_CK,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,44,168,152,10
+ DEFPUSHBUTTON "&Register",IDOK,214,11,53,14
+ PUSHBUTTON "Re&move",ID_REMOVE_PB,214,27,53,14
+ PUSHBUTTON "&Close",IDCANCEL,214,43,53,14
+ PUSHBUTTON "&Help",ID_HELP,214,59,53,14
+ PUSHBUTTON "Ser&vers...",ID_SERVERS_PB,214,92,53,14
+ PUSHBUTTON "&Groups...",ID_GROUPS_PB,214,108,53,14
+END
+
+IDD_TOOL_SQL_STATUS DIALOG DISCARDABLE 0, 0, 452, 247
+STYLE WS_CHILD | WS_BORDER
+FONT 8, "MS Sans Serif"
+BEGIN
+ EDITTEXT IDC_EDIT,11,11,434,229,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | WS_VSCROLL
+END
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,2
+ PRODUCTVERSION 1,0,0,2
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "\0"
+ VALUE "FileDescription", "MySqlManager MFC Application\0"
+ VALUE "FileVersion", "1, 0, 0, 2\0"
+ VALUE "InternalName", "MySqlManager\0"
+ VALUE "LegalCopyright", "Copyright (C) 1998\0"
+ VALUE "OriginalFilename", "MySqlManager.EXE\0"
+ VALUE "ProductName", "MySqlManager Application\0"
+ VALUE "ProductVersion", "1, 0, 0, 2\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_ABOUTBOX, DIALOG
+ BEGIN
+ LEFTMARGIN, 6
+ RIGHTMARGIN, 227
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 65
+ END
+
+ IDD_TOOL_SQL, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 445
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 239
+ END
+
+ IDD_TOOL_SQL_QUERY, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 445
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 240
+ END
+
+ IDD_TOOL_SQL_RESULTS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 445
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 240
+ END
+
+ IDD_TOOL_SQL_STATUS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 445
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 240
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE PRELOAD DISCARDABLE
+BEGIN
+ IDR_MAINFRAME "MySqlManager"
+ IDR_MYSQLMTYPE "\nMySqlM\nMySqlM\n\n\nMySqlManager.Document\nMySqlM Document"
+END
+
+STRINGTABLE PRELOAD DISCARDABLE
+BEGIN
+ AFX_IDS_APP_TITLE "MySqlManager"
+ AFX_IDS_IDLEMESSAGE "Ready"
+ IDS_QUERY_DATABASES "Query Database(s)"
+ IDS_REFRESH "Refresh"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_INDICATOR_EXT "EXT"
+ ID_INDICATOR_CAPS "CAP"
+ ID_INDICATOR_NUM "NUM"
+ ID_INDICATOR_SCRL "SCRL"
+ ID_INDICATOR_OVR "OVR"
+ ID_INDICATOR_REC "REC"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_FILE_NEW "Create a new document\nNew"
+ ID_FILE_OPEN "Open an existing document\nOpen"
+ ID_FILE_CLOSE "Close the active document\nClose"
+ ID_FILE_SAVE "Save the active document\nSave"
+ ID_FILE_SAVE_AS "Save the active document with a new name\nSave As"
+ ID_FILE_PAGE_SETUP "Change the printing options\nPage Setup"
+ ID_FILE_PRINT_SETUP "Change the printer and printing options\nPrint Setup"
+ ID_FILE_PRINT "Print the active document\nPrint"
+ ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
+ ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_FILE_MRU_FILE1 "Open this document"
+ ID_FILE_MRU_FILE2 "Open this document"
+ ID_FILE_MRU_FILE3 "Open this document"
+ ID_FILE_MRU_FILE4 "Open this document"
+ ID_FILE_MRU_FILE5 "Open this document"
+ ID_FILE_MRU_FILE6 "Open this document"
+ ID_FILE_MRU_FILE7 "Open this document"
+ ID_FILE_MRU_FILE8 "Open this document"
+ ID_FILE_MRU_FILE9 "Open this document"
+ ID_FILE_MRU_FILE10 "Open this document"
+ ID_FILE_MRU_FILE11 "Open this document"
+ ID_FILE_MRU_FILE12 "Open this document"
+ ID_FILE_MRU_FILE13 "Open this document"
+ ID_FILE_MRU_FILE14 "Open this document"
+ ID_FILE_MRU_FILE15 "Open this document"
+ ID_FILE_MRU_FILE16 "Open this document"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
+ ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_WINDOW_NEW "Open another window for the active document\nNew Window"
+ ID_WINDOW_ARRANGE "Arrange icons at the bottom of the window\nArrange Icons"
+ ID_WINDOW_CASCADE "Arrange windows so they overlap\nCascade Windows"
+ ID_WINDOW_TILE_HORZ "Arrange windows as non-overlapping tiles\nTile Windows"
+ ID_WINDOW_TILE_VERT "Arrange windows as non-overlapping tiles\nTile Windows"
+ ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_EDIT_CLEAR "Erase the selection\nErase"
+ ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
+ ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy"
+ ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut"
+ ID_EDIT_FIND "Find the specified text\nFind"
+ ID_EDIT_PASTE "Insert Clipboard contents\nPaste"
+ ID_EDIT_REPEAT "Repeat the last action\nRepeat"
+ ID_EDIT_REPLACE "Replace specific text with different text\nReplace"
+ ID_EDIT_SELECT_ALL "Select the entire document\nSelect All"
+ ID_EDIT_UNDO "Undo the last action\nUndo"
+ ID_EDIT_REDO "Redo the previously undone action\nRedo"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"
+ ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ AFX_IDS_SCSIZE "Change the window size"
+ AFX_IDS_SCMOVE "Change the window position"
+ AFX_IDS_SCMINIMIZE "Reduce the window to an icon"
+ AFX_IDS_SCMAXIMIZE "Enlarge the window to full size"
+ AFX_IDS_SCNEXTWINDOW "Switch to the next document window"
+ AFX_IDS_SCPREVWINDOW "Switch to the previous document window"
+ AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ AFX_IDS_SCRESTORE "Restore the window to normal size"
+ AFX_IDS_SCTASKLIST "Activate Task List"
+ AFX_IDS_MDICHILD "Activate this window"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ AFX_IDS_PREVIEW_CLOSE "Close print preview mode\nCancel Preview"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDC_QUERY_PB "Execute Query"
+ IDS_QUERY_EXEC "Execute Query"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif
+#include "res\MySqlManager.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#include "afxprint.rc" // printing/print preview resources
+#endif
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
diff --git a/VC++Files/mysqlmanager/mysqlmanagerdoc.cpp b/VC++Files/mysqlmanager/mysqlmanagerdoc.cpp
new file mode 100644
index 00000000000..c89ce693a60
--- /dev/null
+++ b/VC++Files/mysqlmanager/mysqlmanagerdoc.cpp
@@ -0,0 +1,84 @@
+// MySqlManagerDoc.cpp : implementation of the CMySqlManagerDoc class
+//
+
+#include "stdafx.h"
+#include "MySqlManager.h"
+
+#include "MySqlManagerDoc.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CMySqlManagerDoc
+
+IMPLEMENT_DYNCREATE(CMySqlManagerDoc, CDocument)
+
+BEGIN_MESSAGE_MAP(CMySqlManagerDoc, CDocument)
+ //{{AFX_MSG_MAP(CMySqlManagerDoc)
+ // NOTE - the ClassWizard will add and remove mapping macros here.
+ // DO NOT EDIT what you see in these blocks of generated code!
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CMySqlManagerDoc construction/destruction
+
+CMySqlManagerDoc::CMySqlManagerDoc()
+{
+ // TODO: add one-time construction code here
+
+}
+
+CMySqlManagerDoc::~CMySqlManagerDoc()
+{
+}
+
+BOOL CMySqlManagerDoc::OnNewDocument()
+{
+ if (!CDocument::OnNewDocument())
+ return FALSE;
+
+ // TODO: add reinitialization code here
+ // (SDI documents will reuse this document)
+
+ return TRUE;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CMySqlManagerDoc serialization
+
+void CMySqlManagerDoc::Serialize(CArchive& ar)
+{
+ if (ar.IsStoring())
+ {
+ // TODO: add storing code here
+ }
+ else
+ {
+ // TODO: add loading code here
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CMySqlManagerDoc diagnostics
+
+#ifdef _DEBUG
+void CMySqlManagerDoc::AssertValid() const
+{
+ CDocument::AssertValid();
+}
+
+void CMySqlManagerDoc::Dump(CDumpContext& dc) const
+{
+ CDocument::Dump(dc);
+}
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CMySqlManagerDoc commands
diff --git a/VC++Files/mysqlmanager/mysqlmanagerdoc.h b/VC++Files/mysqlmanager/mysqlmanagerdoc.h
new file mode 100644
index 00000000000..f4a4d35cfd5
--- /dev/null
+++ b/VC++Files/mysqlmanager/mysqlmanagerdoc.h
@@ -0,0 +1,57 @@
+// MySqlManagerDoc.h : interface of the CMySqlManagerDoc class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_MYSQLMANAGERDOC_H__826CB2F2_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
+#define AFX_MYSQLMANAGERDOC_H__826CB2F2_8B6D_11D1_AEC1_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+
+class CMySqlManagerDoc : public CDocument
+{
+protected: // create from serialization only
+ CMySqlManagerDoc();
+ DECLARE_DYNCREATE(CMySqlManagerDoc)
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CMySqlManagerDoc)
+ public:
+ virtual BOOL OnNewDocument();
+ virtual void Serialize(CArchive& ar);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CMySqlManagerDoc();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CMySqlManagerDoc)
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code !
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_MYSQLMANAGERDOC_H__826CB2F2_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlmanager/mysqlmanagerview.cpp b/VC++Files/mysqlmanager/mysqlmanagerview.cpp
new file mode 100644
index 00000000000..1d4756e7d7a
--- /dev/null
+++ b/VC++Files/mysqlmanager/mysqlmanagerview.cpp
@@ -0,0 +1,849 @@
+// MySqlManagerView.cpp : implementation of the CMySqlManagerView class
+//
+
+#include "stdafx.h"
+#include "MySqlManager.h"
+#include "MySqlManagerDoc.h"
+#include "MySqlManagerView.h"
+#include "mainfrm.h"
+#include "ToolSql.h"
+#include "RegisterServer.h"
+
+class XStatus
+{
+public:
+ XStatus ( LPCSTR fmt, ... )
+ {
+ char buf [2048];
+ va_list args;
+ va_start(args, fmt);
+ int ret = vsprintf(buf, fmt, args);
+ MainFrame->StatusMsg ( "%s", buf );
+ va_end(args);
+ }
+ ~XStatus()
+ {
+ MainFrame->StatusMsg ( " ");
+ }
+private:
+ XStatus();
+};
+
+#ifdef _DEBUG
+ #define new DEBUG_NEW
+ #undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_DYNCREATE(CMySqlManagerView, CTreeView)
+
+BEGIN_MESSAGE_MAP(CMySqlManagerView, CTreeView)
+//{{AFX_MSG_MAP(CMySqlManagerView)
+ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
+ON_COMMAND(IDM_SQL_TOOL_QUERY, OnSqlToolQuery)
+ON_COMMAND(IDM_REFRESH, OnRefresh)
+ON_COMMAND(IDM_TOOLS_SERVER_PROPERTIES,OnServerProperties)
+ON_COMMAND(IDM_TOOLS_REGISTER_SERVER, OnRegisterServer)
+ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
+//}}AFX_MSG_MAP
+// Standard printing commands
+ON_COMMAND(ID_FILE_PRINT, CTreeView::OnFilePrint)
+ON_COMMAND(ID_FILE_PRINT_DIRECT, CTreeView::OnFilePrint)
+ON_COMMAND(ID_FILE_PRINT_PREVIEW, CTreeView::OnFilePrintPreview)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+
+CMySqlManagerView::CMySqlManagerView()
+: m_pTree(0)
+, m_pImages(0)
+, m_pbmBmp(0)
+, m_pTool(0)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+CMySqlManagerView::~CMySqlManagerView()
+{
+ if ( m_pbmBmp ) delete m_pbmBmp;
+ if ( m_pImages ) delete m_pImages;
+ if ( m_pTool )
+ {
+ m_pTool->DestroyWindow();
+ delete m_pTool;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+BOOL CMySqlManagerView::PreCreateWindow(CREATESTRUCT& cs)
+{
+ return CTreeView::PreCreateWindow(cs);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::OnDraw(CDC* pDC)
+{
+ CMySqlManagerDoc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+BOOL CMySqlManagerView::OnPreparePrinting(CPrintInfo* pInfo)
+{
+ return DoPreparePrinting(pInfo);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef _DEBUG
+void CMySqlManagerView::AssertValid() const
+{
+ CTreeView::AssertValid();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::Dump(CDumpContext& dc) const
+{
+ CTreeView::Dump(dc);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+CMySqlManagerDoc* CMySqlManagerView::GetDocument() // non-debug version is inline
+{
+ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMySqlManagerDoc)));
+ return (CMySqlManagerDoc*)m_pDocument;
+}
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::OnInitialUpdate()
+{
+
+ CTreeView::OnInitialUpdate();
+
+ m_pTree = & GetTreeCtrl();
+ m_pImages = new CImageList;
+ m_pImages->Create( 16, 16, FALSE, 0, 10 );
+ m_pbmBmp = new CBitmap;
+ m_pbmBmp->LoadBitmap( IDB_BITMAP1 );
+ m_pImages->Add( m_pbmBmp, (COLORREF)0 );
+ m_pTree->SetImageList( m_pImages, TVSIL_NORMAL );
+
+ HTREEITEM h = AddResource ( TVI_ROOT, new CResourceServer ( "MySQL", "localhost", "root", "" ) );
+// AddResource ( h, new CResourceProcesslist () );
+ h = AddResource ( TVI_ROOT, new CResourceServer ( "Test", "localhost", "test", "" ) );
+// AddResource ( h, new CResourceProcesslist () );
+
+ m_pTree->ModifyStyle(0, TVS_HASLINES|TVS_HASBUTTONS);
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+HTREEITEM CMySqlManagerView::AddResource ( HTREEITEM hParent, CResource* pRes, HTREEITEM hLastItem )
+{
+
+ TV_INSERTSTRUCT ItemStruct;
+ memset( &ItemStruct, 0, sizeof(ItemStruct) );
+ ItemStruct.hParent = hParent;
+ ItemStruct.hInsertAfter = hLastItem;
+ ItemStruct.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_IMAGE;
+ ItemStruct.item.hItem = 0;
+ ItemStruct.item.state = 0;
+ ItemStruct.item.stateMask = 0;
+ ItemStruct.item.pszText = (LPSTR) pRes->GetDisplayName();
+ ItemStruct.item.cchTextMax = (int) strlen( ItemStruct.item.pszText );
+ ItemStruct.item.iImage = 2;
+ ItemStruct.item.iSelectedImage = 3;
+ ItemStruct.item.cChildren = 0;
+ ItemStruct.item.lParam = (long) pRes;
+ hLastItem = m_pTree->InsertItem( &ItemStruct );
+ return hLastItem;
+}
+
+//int InsertNetResources( LPNETRESOURCE lpNetResource, CTreeCtrl *pTreeCtrl, HTREEITEM hParent, int *pnCount )
+//{
+//
+// DWORD Erc;
+// NETRESOURCE *pNetRes;
+// HANDLE hEnum;
+//
+// if( !pTreeCtrl ) return -1;
+// if( pnCount ) *pnCount = 0;
+// Erc = WNetOpenEnum(
+// RESOURCE_GLOBALNET,//DWORD dwScope, // scope of enumeration
+// RESOURCETYPE_ANY,//DWORD dwType, // resource types to list
+// 0,//DWORD dwUsage, // resource usage to list
+// lpNetResource,//LPNETRESOURCE lpNetResource, // pointer to resource structure
+// &hEnum//LPHANDLE lphEnum // pointer to enumeration handle buffer
+// );
+// if( Erc )
+// {
+// ShowError( Erc );
+// return Erc;
+// }
+//
+//
+// DWORD dwBufferSize = 1024;
+// pNetRes = (NETRESOURCE *)malloc( dwBufferSize );
+//
+// while( TRUE )
+// {
+// DWORD dwCount = 0xFFFFFFFF;
+// Erc = WNetEnumResource(
+// hEnum,//HANDLE hEnum, // handle to enumeration
+// &dwCount,//LPDWORD lpcCount, // pointer to entries to list
+// pNetRes,//LPVOID lpBuffer, // pointer to buffer for results
+// &dwBufferSize//LPDWORD lpBufferSize // pointer to buffer size variable
+// );
+// if( Erc == ERROR_NO_MORE_ITEMS ) return 0;
+// if( Erc )
+// {
+// free( pNetRes );
+// pNetRes = (NETRESOURCE *)malloc( dwBufferSize );
+// Erc = WNetEnumResource(
+// hEnum,//HANDLE hEnum, // handle to enumeration
+// &dwCount,//LPDWORD lpcCount, // pointer to entries to list
+// pNetRes,//LPVOID lpBuffer, // pointer to buffer for results
+// &dwBufferSize//LPDWORD lpBufferSize // pointer to buffer size variable
+// );
+// }
+// if( Erc ){ ShowError( Erc ); return Erc; }
+//
+// TV_INSERTSTRUCT ItemStruct;
+// HTREEITEM hLastItem = TVI_FIRST;
+// DWORD i;
+//
+// if( pnCount ) *pnCount += dwCount;
+// for( i=0; i<dwCount; i++ )
+// {
+// memset( &ItemStruct, 0, sizeof(ItemStruct) );
+// ItemStruct.hParent = hParent;
+// ItemStruct.hInsertAfter = hLastItem;
+// ItemStruct.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_IMAGE;
+// ItemStruct.item.hItem = 0;
+// ItemStruct.item.state = 0;
+// ItemStruct.item.stateMask = 0;
+// ItemStruct.item.pszText = pNetRes[i].lpRemoteName;
+// ItemStruct.item.cchTextMax = strlen( ItemStruct.item.pszText );
+// ItemStruct.item.iImage = 2;
+// ItemStruct.item.iSelectedImage = 3;
+// ItemStruct.item.cChildren = 0;
+// ItemStruct.item.lParam = (long) (new CNetResource( &pNetRes[i] ));
+//
+// hLastItem = pTreeCtrl->InsertItem( &ItemStruct );
+// }
+// }//end while()
+//
+// WNetCloseEnum( hEnum );
+// free( pNetRes );
+// return Erc;
+//}
+
+/////////////////////////////////////////////////////////////////////////////
+
+static void print_top(MYSQL_RES *result)
+{
+ uint length;
+ MYSQL_FIELD *field;
+ mysql_field_seek(result,0);
+ while ((field = mysql_fetch_field(result)))
+ {
+ if ((length= (uint) strlen(field->name)) > field->max_length)
+ field->max_length=length;
+ else
+ length=field->max_length;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+static void print_header(MYSQL_RES *result,CStringArray& rg)
+{
+ MYSQL_FIELD *field;
+ print_top(result);
+ mysql_field_seek(result,0);
+ while ((field = mysql_fetch_field(result)))
+ {
+// printf(" %-*s|",field->max_length+1,field->name);
+ rg.Add(field->name);
+ }
+ print_top(result);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+static void print_row(MYSQL_RES *result,MYSQL_ROW row,CStringArray& rg)
+{
+ uint i,length;
+ MYSQL_FIELD *field;
+ mysql_field_seek(result,0);
+ for (i=0 ; i < mysql_num_fields(result); i++)
+ {
+ field = mysql_fetch_field(result);
+ length=field->max_length;
+ rg.Add(row[i] ? (char*) row[i] : "");
+// printf(" %-*s|",length+1,row[i] ? (char*) row[i] : "");
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::ProcessResultSet ( HTREEITEM hItem, LPVOID r, CResource* pResource )
+{
+
+ MYSQL_RES* result = (MYSQL_RES *) r;
+ MYSQL_ROW row;
+
+ switch (pResource->GetType())
+ {
+ case CResource::eProcesslist:
+ {
+ CResourceProcesslist* p = (CResourceProcesslist*) pResource;
+ CResourceProcesslistItem* pi = new CResourceProcesslistItem ();
+ CString strText;
+ print_header(result,p->m_rgFields);
+ for (int i = 0; i<p->m_rgFields.GetSize(); i++ )
+ {
+ strText += p->m_rgFields[i];
+ strText += " ";
+ }
+ pi->m_strName = strText;
+ AddResource ( hItem, pi );
+ for (int index=0;(row=mysql_fetch_row(result));index++)
+ {
+ pi = new CResourceProcesslistItem ();
+ print_row(result,row,pi->m_rgFields);
+ strText.Empty();
+ for (int i = 0; i<pi->m_rgFields.GetSize(); i++ )
+ {
+ strText += pi->m_rgFields[i];
+ strText += " ";
+ }
+ pi->m_strName = strText;
+ AddResource ( hItem, pi );
+ }
+ print_top(result);
+ break;
+ }
+ case CResource::eServer:
+ {
+ CResourceServer* p = (CResourceServer*) pResource;
+ CResourceDatabase* pi = new CResourceDatabase ();
+ CString strText;
+ /* print_header(result,p->m_rgFields); */
+ for (int i = 0; i<p->m_rgFields.GetSize(); i++ )
+ {
+ strText += p->m_rgFields[i];
+ strText += " ";
+ }
+ pi->m_strName = strText;
+ /* AddResource ( hItem, pi ); */
+ for (int index=0;(row=mysql_fetch_row(result));index++)
+ {
+ pi = new CResourceDatabase ();
+ print_row(result,row,pi->m_rgFields);
+ strText.Empty();
+ for (int i = 0; i<pi->m_rgFields.GetSize(); i++ )
+ {
+ strText += pi->m_rgFields[i];
+ strText += " ";
+ }
+ pi->m_strName = strText;
+ AddResource ( hItem, pi );
+ }
+ print_top(result);
+ break;
+ }
+ case CResource::eDatabase:
+ {
+ CResourceDatabase* p = (CResourceDatabase*) pResource;
+ CResourceTable* pi = new CResourceTable ();
+ CString strText;
+ /* print_header(result,p->m_rgFields); */
+ for (int i = 0; i<p->m_rgFields.GetSize(); i++ )
+ {
+ strText += p->m_rgFields[i];
+ strText += " ";
+ }
+ pi->m_strName = strText;
+ /* AddResource ( hItem, pi ); */
+ for (int index=0;(row=mysql_fetch_row(result));index++)
+ {
+ pi = new CResourceTable ();
+ print_row(result,row,pi->m_rgFields);
+ strText.Empty();
+ for (int i = 0; i<pi->m_rgFields.GetSize(); i++ )
+ {
+ strText += pi->m_rgFields[i];
+ strText += " ";
+ }
+ pi->m_strName = strText;
+ AddResource ( hItem, pi );
+ }
+ print_top(result);
+ break;
+ }
+ case CResource::eTable:
+ {
+ CResourceTable* p = (CResourceTable*) pResource;
+ CResourceField* pi = new CResourceField ();
+ CString strText;
+ /* print_header(result,p->m_rgFields); */
+ for (int i = 0; i<p->m_rgFields.GetSize(); i++ )
+ {
+ strText += p->m_rgFields[i];
+ strText += " ";
+ }
+ pi->m_strName = strText;
+ /* AddResource ( hItem, pi ); */
+ for (int index=0;(row=mysql_fetch_row(result));index++)
+ {
+ pi = new CResourceField ();
+ print_row(result,row,pi->m_rgFields);
+ strText.Empty();
+ for (int i = 0; i<pi->m_rgFields.GetSize(); i++ )
+ {
+ strText += pi->m_rgFields[i];
+ strText += " ";
+ }
+ pi->m_strName = strText;
+ AddResource ( hItem, pi );
+ }
+ print_top(result);
+ break;
+ }
+ }
+
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+CResource* CMySqlManagerView::GetSelectedResource(HTREEITEM* phItemRet)
+{
+ CResource* pResource = NULL;
+ HTREEITEM hItem = m_pTree->GetSelectedItem();
+ if ( hItem )
+ {
+ TV_ITEM item;
+ memset( &item, 0, sizeof(TV_ITEM) );
+ item.hItem = hItem;
+ item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM ;
+ m_pTree->GetItem( &item );
+ if ( item.lParam )
+ {
+ pResource = (CResource*) item.lParam;
+ }
+ }
+ if (phItemRet)
+ {
+ *phItemRet = hItem;
+ }
+ return pResource;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+CResourceServer* CMySqlManagerView::GetServerResource(HTREEITEM hItem)
+{
+
+ TV_ITEM item;
+
+ memset( &item, 0, sizeof(TV_ITEM) );
+ item.hItem = hItem;
+ item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM ;
+ m_pTree->GetItem( &item );
+ if ( !item.lParam ) return NULL;
+
+ CResource* pResource = (CResource*) item.lParam;
+
+ switch (pResource->GetType())
+ {
+ case CResource::eServer:
+ {
+ return (CResourceServer*) pResource;
+ }
+ case CResource::eDatabase:
+ {
+ HTREEITEM hParent = m_pTree->GetParentItem(hItem);
+ memset( &item, 0, sizeof(TV_ITEM) );
+ item.hItem = hParent;
+ item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM ;
+ m_pTree->GetItem( &item );
+ if ( !item.lParam ) return NULL;
+ return (CResourceServer*) item.lParam;
+ }
+ case CResource::eTable:
+ {
+ HTREEITEM hParent = m_pTree->GetParentItem(m_pTree->GetParentItem(hItem));
+ memset( &item, 0, sizeof(TV_ITEM) );
+ item.hItem = hParent;
+ item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM ;
+ m_pTree->GetItem( &item );
+ if ( !item.lParam ) return NULL;
+ return (CResourceServer*) item.lParam;
+ }
+ }
+
+ return NULL;
+
+}
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ HTREEITEM hItem;
+ hItem = m_pTree->GetSelectedItem();
+ *pResult = 0;
+ if ( !hItem ) return;
+
+ TV_ITEM item;
+ memset( &item, 0, sizeof(TV_ITEM) );
+ item.hItem = hItem;
+ item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM ;
+ m_pTree->GetItem( &item );
+
+ if ( ! item.lParam ) return;
+
+ if ( item.cChildren ) return; //if has got children expand only
+
+ CWaitCursor x;
+
+ CResource* pResource = (CResource*) item.lParam;
+
+ MYSQL mysql;
+ MYSQL_RES *result;
+
+ switch (pResource->GetType())
+ {
+ case CResource::eProcesslist:
+ {
+ XStatus x ( "Connecting to server %s on host %s..."
+ , (LPCTSTR) pResource->GetDisplayName()
+ , (LPCTSTR) pResource->GetHostName()
+ );
+ mysql_init(&mysql);
+ if (!mysql_real_connect(&mysql,pResource->GetHostName(), pResource->GetUserName(),pResource->GetPassword(),0,pResource->GetPortNumber(), NullS,0))
+ {
+ PostMessage(WM_COMMAND,IDM_TOOLS_SERVER_PROPERTIES);
+ return;
+ }
+ if (!(result=mysql_list_processes(&mysql)))
+ {
+ return;
+ }
+ ProcessResultSet ( hItem, result, pResource );
+ mysql_free_result(result);
+ mysql_close(&mysql);
+ break;
+ }
+ case CResource::eServer:
+ {
+ MainFrame->StatusMsg ( "Connecting to server %s on host %s..."
+ , (LPCTSTR) pResource->GetDisplayName()
+ , (LPCTSTR) pResource->GetHostName()
+ );
+ mysql_init(&mysql);
+ if (!mysql_real_connect(&mysql,pResource->GetHostName(), pResource->GetUserName(),pResource->GetPassword(),0,pResource->GetPortNumber(), NullS,0))
+ {
+ PostMessage(WM_COMMAND,IDM_TOOLS_SERVER_PROPERTIES);
+ MainFrame->StatusMsg ( "Error: Connecting to server %s... (%s)"
+ , (LPCTSTR) pResource->GetDisplayName()
+ , mysql_error(&mysql)
+ );
+ return;
+ }
+ if (!(result=mysql_list_dbs(&mysql,0)))
+ {
+ }
+ ProcessResultSet ( hItem, result, pResource );
+ mysql_free_result(result);
+ mysql_close(&mysql);
+ MainFrame->StatusMsg ( " " );
+ break;
+ }
+ case CResource::eDatabase:
+ {
+ CResourceServer* pServer = GetServerResource(hItem);
+ if (!pServer) return;
+ MainFrame->StatusMsg ( "Connecting to server %s on host %s..."
+ , (LPCTSTR) pServer->GetDisplayName()
+ , (LPCTSTR) pServer->GetHostName()
+ );
+ mysql_init(&mysql);
+ if (!mysql_real_connect(&mysql,pServer->GetHostName(), pServer->GetUserName(),pServer->GetPassword(),0,pServer->GetPortNumber(), NullS,0))
+ {
+ PostMessage(WM_COMMAND,IDM_TOOLS_SERVER_PROPERTIES);
+ MainFrame->StatusMsg ( "Error: Connecting to server %s... (%s)"
+ , (LPCTSTR) pServer->GetDisplayName()
+ , mysql_error(&mysql)
+ );
+ return;
+ }
+ CResourceDatabase* pRes = (CResourceDatabase*) pResource;
+ CString strDB = pResource->GetDisplayName();
+ strDB.TrimRight();
+ if (mysql_select_db(&mysql,strDB))
+ {
+ MainFrame->StatusMsg ( "Error: Selecting database %s... (%s)"
+ , (LPCTSTR) strDB
+ , mysql_error(&mysql)
+ );
+ return;
+ }
+ if (!(result=mysql_list_tables(&mysql,0)))
+ {
+ }
+ ProcessResultSet ( hItem, result, pRes );
+ mysql_free_result(result);
+ mysql_close(&mysql);
+ MainFrame->StatusMsg ( " " );
+ break;
+ }
+ case CResource::eTable:
+ {
+ CResourceServer* pServer = GetServerResource(hItem);
+ if (!pServer) return;
+ MainFrame->StatusMsg ( "Connecting to server %s on host %s..."
+ , (LPCTSTR) pServer->GetDisplayName()
+ , (LPCTSTR) pServer->GetHostName()
+ );
+ mysql_init(&mysql);
+ if (!mysql_real_connect(&mysql,pServer->GetHostName(), pServer->GetUserName(),pServer->GetPassword(),0,pServer->GetPortNumber(), NullS,0))
+ {
+ PostMessage(WM_COMMAND,IDM_TOOLS_SERVER_PROPERTIES);
+ MainFrame->StatusMsg ( "Error: Connecting to server %s... (%s)"
+ , (LPCTSTR) pServer->GetDisplayName()
+ , mysql_error(&mysql)
+ );
+ return;
+ }
+ HTREEITEM hParent = m_pTree->GetParentItem(hItem);
+ memset( &item, 0, sizeof(TV_ITEM) );
+ item.hItem = hParent;
+ item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM ;
+ m_pTree->GetItem( &item );
+ if ( item.lParam )
+ {
+ CResourceDatabase* pResDatabase = (CResourceDatabase*) item.lParam;
+ CResourceTable* pRes = (CResourceTable*) pResource;
+ CString strDB = pResDatabase->GetDisplayName();
+ CString strTable = pResource->GetDisplayName();
+ strDB.TrimRight();
+ strTable.TrimRight();
+ if (mysql_select_db(&mysql,strDB))
+ {
+ return;
+ }
+ CString str; str.Format("show fields from %s",(LPCTSTR)strTable);
+ if ( mysql_query(&mysql,str)==0 )
+ {
+ MYSQL_RES *result;
+ if ((result=mysql_store_result(&mysql)))
+ {
+ ProcessResultSet ( hItem, result, pRes );
+ mysql_free_result(result);
+ }
+ }
+ }
+ mysql_close(&mysql);
+ break;
+ }
+ }
+
+// InsertNetResources( (LPNETRESOURCE)pTvItem->lParam,
+// &m_TreeCtrl,
+// hItem,
+// &pTvItem->cChildren );
+// pTvItem->mask = TVIF_CHILDREN;
+// m_TreeCtrl.SetItem( pTvItem );
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::OnRefresh()
+{
+ HTREEITEM hItem = NULL;
+ CResource* pResource = GetSelectedResource(&hItem);
+ if (pResource&&hItem)
+ {
+ switch (pResource->GetType())
+ {
+ case CResource::eTable:
+ {
+
+ TV_ITEM item;
+ MYSQL mysql;
+// MYSQL_RES *result;
+
+ HTREEITEM hParent = m_pTree->GetParentItem(hItem);
+
+ HTREEITEM hChild = m_pTree->GetChildItem(hItem);
+ while (hChild)
+ {
+ HTREEITEM h = m_pTree->GetNextSiblingItem(hChild);
+ BOOL b = m_pTree->DeleteItem(hChild);
+ hChild = h;
+ }
+ mysql_init(&mysql);
+ if (!mysql_real_connect(&mysql,pResource->GetHostName(), pResource->GetUserName(),pResource->GetPassword(),0,pResource->GetPortNumber(), NullS,0))
+ {
+ return;
+ }
+ memset( &item, 0, sizeof(TV_ITEM) );
+ item.hItem = hParent;
+ item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM ;
+ m_pTree->GetItem( &item );
+ if ( item.lParam )
+ {
+ CResourceDatabase* pResDatabase = (CResourceDatabase*) item.lParam;
+ CResourceTable* pRes = (CResourceTable*) pResource;
+ CString strDB = pResDatabase->GetDisplayName();
+ CString strTable = pResource->GetDisplayName();
+ strDB.TrimRight();
+ strTable.TrimRight();
+ if (mysql_select_db(&mysql,strDB))
+ {
+ return;
+ }
+ CString str; str.Format("show fields from %s",(LPCTSTR)strTable);
+ if ( mysql_query(&mysql,str)==0 )
+ {
+ MYSQL_RES *result;
+ if ((result=mysql_store_result(&mysql)))
+ {
+ ProcessResultSet ( hItem, result, pRes );
+ mysql_free_result(result);
+ }
+ }
+ }
+ mysql_close(&mysql);
+ break;
+ }
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::OnRegisterServer()
+{
+ CRegisterServer dlg;
+ if (dlg.DoModal()!=IDOK) return;
+ AddResource (
+ TVI_ROOT,
+ new CResourceServer ( dlg.m_strServer, dlg.m_strHost, dlg.m_strUser, dlg.m_strPassword, dlg.m_strPort )
+ );
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::OnServerProperties()
+{
+ HTREEITEM hItem;
+ CResource* pRes = GetSelectedResource(&hItem);
+ if (!pRes) return;
+ if (pRes->GetType()!=CResource::eServer) return;
+ CResourceServer* pResource = (CResourceServer*)pRes;
+ CRegisterServer dlg;
+ dlg.m_strHost = pResource->GetHostName();
+ dlg.m_strUser = pResource->GetUserName();
+ dlg.m_strPassword = pResource->GetPassword();
+ dlg.m_strPort = pResource->GetPortName();
+ if (dlg.DoModal()!=IDOK) return;
+ pResource->m_strHost = dlg.m_strHost ;
+ pResource->m_strUser = dlg.m_strUser ;
+ pResource->m_strPassword = dlg.m_strPassword;
+ pResource->m_strPort = dlg.m_strPort ;
+ TV_ITEM item;
+ memset( &item, 0, sizeof(TV_ITEM) );
+ item.hItem = hItem;
+ item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM ;
+ m_pTree->GetItem( &item );
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CMySqlManagerView::OnSqlToolQuery()
+{
+
+ HTREEITEM hItem;
+
+ CResource* pResource = GetSelectedResource(&hItem);
+
+ if (!pResource) return;
+
+ CResourceServer* pServer = GetServerResource(hItem);
+ if (!pServer) return; /* Avoid bug when selecting field */
+
+ m_pTool = new CToolSql ( AfxGetMainWnd(), pServer, pResource );
+
+ if ( ! m_pTool->Create(IDD_TOOL_SQL,this) )
+ {
+ delete m_pTool;
+ m_pTool = 0;
+ PostMessage(WM_COMMAND,IDM_TOOLS_SERVER_PROPERTIES);
+ }
+ else
+ {
+ m_pTool->ShowWindow(SW_SHOW);
+ }
+
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+BOOL CMySqlManagerView::PreTranslateMessage(MSG* pMsg)
+{
+ if (m_pTool && m_pTool->PreTranslateMessage(pMsg))
+ return TRUE;
+ return CTreeView::PreTranslateMessage(pMsg);
+}
+
+void CMySqlManagerView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
+{
+
+ POINT pt;
+
+ GetCursorPos ( & pt );
+
+ CMenu menu;
+
+ menu.CreatePopupMenu ();
+
+ menu.AppendMenu ( MF_ENABLED , IDM_SQL_TOOL_QUERY, "SQL Query" );
+ menu.AppendMenu ( MF_ENABLED , IDM_REFRESH, "Refresh active item(s)" );
+ menu.AppendMenu ( MF_ENABLED , IDM_TOOLS_REGISTER_SERVER, "Register server" );
+ menu.AppendMenu ( MF_ENABLED , IDM_TOOLS_SERVER_PROPERTIES, "Properties" );
+
+ menu.TrackPopupMenu ( TPM_LEFTALIGN | TPM_RIGHTBUTTON , pt.x, pt.y, CWnd::GetParent(), NULL );
+
+ *pResult = 0;
+
+}
diff --git a/VC++Files/mysqlmanager/mysqlmanagerview.h b/VC++Files/mysqlmanager/mysqlmanagerview.h
new file mode 100644
index 00000000000..97f5a2596d1
--- /dev/null
+++ b/VC++Files/mysqlmanager/mysqlmanagerview.h
@@ -0,0 +1,89 @@
+// MySqlManagerView.h : interface of the CMySqlManagerView class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_MYSQLMANAGERVIEW_H__826CB2F4_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
+#define AFX_MYSQLMANAGERVIEW_H__826CB2F4_8B6D_11D1_AEC1_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#include <afxcview.h>
+#include "cresource.h"
+
+class CToolSql;
+
+class CMySqlManagerView : public CTreeView
+{
+protected: // create from serialization only
+ CMySqlManagerView();
+ DECLARE_DYNCREATE(CMySqlManagerView)
+
+// Attributes
+public:
+ CMySqlManagerDoc* GetDocument();
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CMySqlManagerView)
+ public:
+ virtual void OnDraw(CDC* pDC); // overridden to draw this view
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual void OnInitialUpdate();
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ protected:
+ virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
+ virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
+ //}}AFX_VIRTUAL
+
+// Implementation
+
+ CResource* GetSelectedResource(HTREEITEM* phItemRet=NULL);
+ CResourceServer* GetServerResource(HTREEITEM hItem);
+
+ HTREEITEM AddResource ( HTREEITEM hParent, CResource* pRes, HTREEITEM hLastItem = TVI_FIRST ) ;
+ void ProcessResultSet ( HTREEITEM hItem, LPVOID result, CResource* pResource );
+
+public:
+ virtual ~CMySqlManagerView();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+
+ CTreeCtrl* m_pTree;
+ CImageList* m_pImages;
+ CBitmap* m_pbmBmp;
+ CToolSql* m_pTool;
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CMySqlManagerView)
+ afx_msg void OnDblclk(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnSqlToolQuery();
+ afx_msg void OnRefresh();
+ afx_msg void OnRegisterServer();
+ afx_msg void OnServerProperties();
+ afx_msg void OnRclick(NMHDR* pNMHDR, LRESULT* pResult);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+#ifndef _DEBUG // debug version in MySqlManagerView.cpp
+inline CMySqlManagerDoc* CMySqlManagerView::GetDocument()
+ { return (CMySqlManagerDoc*)m_pDocument; }
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_MYSQLMANAGERVIEW_H__826CB2F4_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlmanager/registerserver.cpp b/VC++Files/mysqlmanager/registerserver.cpp
new file mode 100644
index 00000000000..a0e9dcca3df
--- /dev/null
+++ b/VC++Files/mysqlmanager/registerserver.cpp
@@ -0,0 +1,51 @@
+// RegisterServer.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mysqlmanager.h"
+#include "RegisterServer.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CRegisterServer dialog
+
+
+CRegisterServer::CRegisterServer(CWnd* pParent /*=NULL*/)
+ : CDialog(CRegisterServer::IDD, pParent)
+ , m_strServer("servername")
+ , m_strHost("localhost")
+ , m_strUser("root")
+ , m_strPassword("")
+{
+ //{{AFX_DATA_INIT(CRegisterServer)
+ m_strPort = _T("3306");
+ //}}AFX_DATA_INIT
+}
+
+
+void CRegisterServer::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CRegisterServer)
+ DDX_CBString(pDX, ID_SERVER_CB, m_strServer);
+ DDX_CBString(pDX, ID_HOST_CB, m_strHost);
+ DDX_Text(pDX, ID_USER, m_strUser);
+ DDX_Text(pDX, ID_PASSWORD, m_strPassword);
+ DDX_CBString(pDX, ID_PORT_CB, m_strPort);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CRegisterServer, CDialog)
+ //{{AFX_MSG_MAP(CRegisterServer)
+ // NOTE: the ClassWizard will add message map macros here
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CRegisterServer message handlers
diff --git a/VC++Files/mysqlmanager/registerserver.h b/VC++Files/mysqlmanager/registerserver.h
new file mode 100644
index 00000000000..f4ac2356b2c
--- /dev/null
+++ b/VC++Files/mysqlmanager/registerserver.h
@@ -0,0 +1,50 @@
+#if !defined(AFX_REGISTERSERVER_H__826CB2FF_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
+#define AFX_REGISTERSERVER_H__826CB2FF_8B6D_11D1_AEC1_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+// RegisterServer.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CRegisterServer dialog
+
+class CRegisterServer : public CDialog
+{
+// Construction
+public:
+ CRegisterServer(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(CRegisterServer)
+ enum { IDD = IDD_REGISTER_SERVER };
+ CString m_strServer;
+ CString m_strHost;
+ CString m_strUser;
+ CString m_strPassword;
+ CString m_strPort;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CRegisterServer)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(CRegisterServer)
+ // NOTE: the ClassWizard will add member functions here
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_REGISTERSERVER_H__826CB2FF_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlmanager/toolsqlquery.cpp b/VC++Files/mysqlmanager/toolsqlquery.cpp
new file mode 100644
index 00000000000..1f246f47786
--- /dev/null
+++ b/VC++Files/mysqlmanager/toolsqlquery.cpp
@@ -0,0 +1,110 @@
+// ToolSqlQuery.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "MySqlManager.h"
+#include "ToolSqlQuery.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+CToolSqlQuery::CToolSqlQuery(CWnd* pParent /*=NULL*/)
+ : CDialog(CToolSqlQuery::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CToolSqlQuery)
+ m_edit = _T("");
+ //}}AFX_DATA_INIT
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlQuery::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CToolSqlQuery)
+ DDX_Control(pDX, IDC_EDIT, m_ctl_edit);
+ DDX_Text(pDX, IDC_EDIT, m_edit);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CToolSqlQuery, CDialog)
+ //{{AFX_MSG_MAP(CToolSqlQuery)
+ ON_WM_SIZE()
+ ON_WM_CLOSE()
+ ON_COMMAND(IDM_QUERY_EXEC, OnQueryPb)
+ ON_COMMAND(IDM_QUERY_DATABASES, OnQueryDatabases)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlQuery::SetFont(CFont* pFont, BOOL bRedraw)
+{
+ m_ctl_edit.SetFont(pFont,bRedraw);
+ m_ctl_edit.Invalidate();
+ m_ctl_edit.UpdateWindow();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlQuery::OnSize(UINT nType, int cx, int cy)
+{
+ CDialog::OnSize(nType, cx, cy);
+ if (IsWindow(m_ctl_edit.GetSafeHwnd()))
+ m_ctl_edit.SetWindowPos(NULL,20,24,cx-40,cy-48,SWP_NOZORDER | SWP_NOMOVE);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlQuery::OnCancel()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlQuery::OnClose()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlQuery::OnQueryPb()
+{
+ GetParent()->GetParent()->PostMessage(WM_COMMAND,IDM_QUERY_EXEC);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlQuery::OnQueryDatabases()
+{
+ GetParent()->GetParent()->PostMessage(WM_COMMAND,IDM_QUERY_DATABASES);
+}
+/////////////////////////////////////////////////////////////////////////////
+
+BOOL CToolSqlQuery::PreTranslateMessage(MSG* pMsg)
+{
+ if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
+ {
+ if (::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
+ return TRUE;
+ }
+ return CDialog::PreTranslateMessage(pMsg);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+BOOL CToolSqlQuery::OnInitDialog()
+{
+
+ CDialog::OnInitDialog();
+ m_hAccel = ::LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE ( IDR_MAINFRAME ));
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
diff --git a/VC++Files/mysqlmanager/toolsqlquery.h b/VC++Files/mysqlmanager/toolsqlquery.h
new file mode 100644
index 00000000000..c5d318c161b
--- /dev/null
+++ b/VC++Files/mysqlmanager/toolsqlquery.h
@@ -0,0 +1,60 @@
+#if !defined(AFX_TOOLSQLQUERY_H__826CB2FD_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
+#define AFX_TOOLSQLQUERY_H__826CB2FD_8B6D_11D1_AEC1_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+// ToolSqlQuery.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CToolSqlQuery dialog
+
+class CToolSqlQuery : public CDialog
+{
+// Construction
+public:
+ CToolSqlQuery(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(CToolSqlQuery)
+ enum { IDD = IDD_TOOL_SQL_QUERY };
+ CEdit m_ctl_edit;
+ CString m_edit;
+ //}}AFX_DATA
+
+ HACCEL m_hAccel;
+
+ void SetFont(CFont* pFont, BOOL bRedraw = TRUE);
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CToolSqlQuery)
+ public:
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+
+protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(CToolSqlQuery)
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnCancel();
+ afx_msg void OnClose();
+ virtual BOOL OnInitDialog();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+ afx_msg void OnQueryPb();
+ afx_msg void OnQueryDatabases();
+
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_TOOLSQLQUERY_H__826CB2FD_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlmanager/toolsqlresults.cpp b/VC++Files/mysqlmanager/toolsqlresults.cpp
new file mode 100644
index 00000000000..b6cfcded18b
--- /dev/null
+++ b/VC++Files/mysqlmanager/toolsqlresults.cpp
@@ -0,0 +1,73 @@
+// ToolSqlResults.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "MySqlManager.h"
+#include "ToolSqlResults.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+CToolSqlResults::CToolSqlResults(CWnd* pParent /*=NULL*/)
+ : CDialog(CToolSqlResults::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CToolSqlResults)
+ m_edit = _T("");
+ //}}AFX_DATA_INIT
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlResults::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CToolSqlResults)
+ DDX_Control(pDX, IDC_EDIT, m_ctl_edit);
+ DDX_Text(pDX, IDC_EDIT, m_edit);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CToolSqlResults, CDialog)
+ //{{AFX_MSG_MAP(CToolSqlResults)
+ ON_WM_SIZE()
+ ON_WM_CLOSE()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlResults::SetFont(CFont* pFont, BOOL bRedraw)
+{
+ m_ctl_edit.SetFont(pFont,bRedraw);
+ m_ctl_edit.Invalidate();
+ m_ctl_edit.UpdateWindow();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlResults::OnSize(UINT nType, int cx, int cy)
+{
+ CDialog::OnSize(nType, cx, cy);
+ if (IsWindow(m_ctl_edit.GetSafeHwnd()))
+ m_ctl_edit.SetWindowPos(NULL,20,24,cx-40,cy-48,SWP_NOZORDER | SWP_NOMOVE);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlResults::OnCancel()
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CToolSqlResults::OnClose()
+{
+}
diff --git a/VC++Files/mysqlmanager/toolsqlresults.h b/VC++Files/mysqlmanager/toolsqlresults.h
new file mode 100644
index 00000000000..c4de651cb81
--- /dev/null
+++ b/VC++Files/mysqlmanager/toolsqlresults.h
@@ -0,0 +1,53 @@
+#if !defined(AFX_TOOLSQLRESULTS_H__826CB2FE_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
+#define AFX_TOOLSQLRESULTS_H__826CB2FE_8B6D_11D1_AEC1_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+// ToolSqlResults.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CToolSqlResults dialog
+
+class CToolSqlResults : public CDialog
+{
+// Construction
+public:
+ CToolSqlResults(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(CToolSqlResults)
+ enum { IDD = IDD_TOOL_SQL_RESULTS };
+ CEdit m_ctl_edit;
+ CString m_edit;
+ //}}AFX_DATA
+
+ void SetFont(CFont* pFont, BOOL bRedraw = TRUE);
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CToolSqlResults)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+
+protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(CToolSqlResults)
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnCancel();
+ afx_msg void OnClose();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_TOOLSQLRESULTS_H__826CB2FE_8B6D_11D1_AEC1_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlmanager/toolsqlstatus.cpp b/VC++Files/mysqlmanager/toolsqlstatus.cpp
new file mode 100644
index 00000000000..81605480783
--- /dev/null
+++ b/VC++Files/mysqlmanager/toolsqlstatus.cpp
@@ -0,0 +1,50 @@
+// ToolSqlStatus.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "mysqlmanager.h"
+#include "ToolSqlStatus.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CToolSqlStatus dialog
+
+
+CToolSqlStatus::CToolSqlStatus(CWnd* pParent /*=NULL*/)
+ : CDialog(CToolSqlStatus::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CToolSqlStatus)
+ m_edit = _T("");
+ //}}AFX_DATA_INIT
+}
+
+
+void CToolSqlStatus::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CToolSqlStatus)
+ DDX_Control(pDX, IDC_EDIT, m_ctl_edit);
+ DDX_Text(pDX, IDC_EDIT, m_edit);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CToolSqlStatus, CDialog)
+ //{{AFX_MSG_MAP(CToolSqlStatus)
+ ON_WM_DESTROY()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CToolSqlStatus message handlers
+
+void CToolSqlStatus::OnDestroy()
+{
+ CDialog::OnDestroy();
+
+}
diff --git a/VC++Files/mysqlmanager/toolsqlstatus.h b/VC++Files/mysqlmanager/toolsqlstatus.h
new file mode 100644
index 00000000000..5e4883b0b30
--- /dev/null
+++ b/VC++Files/mysqlmanager/toolsqlstatus.h
@@ -0,0 +1,47 @@
+#if !defined(AFX_TOOLSQLSTATUS_H__40C861B4_9E5A_11D1_AED0_00600806E071__INCLUDED_)
+#define AFX_TOOLSQLSTATUS_H__40C861B4_9E5A_11D1_AED0_00600806E071__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+// ToolSqlStatus.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CToolSqlStatus dialog
+
+class CToolSqlStatus : public CDialog
+{
+// Construction
+public:
+ CToolSqlStatus(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(CToolSqlStatus)
+ enum { IDD = IDD_TOOL_SQL_STATUS };
+ CEdit m_ctl_edit;
+ CString m_edit;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CToolSqlStatus)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(CToolSqlStatus)
+ afx_msg void OnDestroy();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_TOOLSQLSTATUS_H__40C861B4_9E5A_11D1_AED0_00600806E071__INCLUDED_)
diff --git a/VC++Files/mysqlserver/mysqlserver.dsp b/VC++Files/mysqlserver/mysqlserver.dsp
new file mode 100644
index 00000000000..d8df71ebbb2
--- /dev/null
+++ b/VC++Files/mysqlserver/mysqlserver.dsp
@@ -0,0 +1,84 @@
+# Microsoft Developer Studio Project File - Name="mysqlserver" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=mysqlserver - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlserver.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mysqlserver.mak" CFG="mysqlserver - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mysqlserver - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "mysqlserver - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=xicl6.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mysqlserver - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /O2 /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "DBUG_OFF" /D "USE_TLS" /YX /FD /c
+# ADD BASE RSC /l 0x416 /d "NDEBUG"
+# ADD RSC /l 0x416 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=xilink6.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "mysqlserver - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Z7 /Od /I "../include" /I "../regex" /I "../sql" /I "../bdb/build_win32" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /D "EMBEDDED_LIBRARY" /D "HAVE_INNOBASE_DB" /D "USE_TLS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x416 /d "_DEBUG"
+# ADD RSC /l 0x416 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=xilink6.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "mysqlserver - Win32 Release"
+# Name "mysqlserver - Win32 Debug"
+# End Target
+# End Project
diff --git a/VC++Files/mysqlshutdown/myshutdown.dsp b/VC++Files/mysqlshutdown/myshutdown.dsp
index 390921f599c..0119df3cd59 100644
--- a/VC++Files/mysqlshutdown/myshutdown.dsp
+++ b/VC++Files/mysqlshutdown/myshutdown.dsp
@@ -7,19 +7,19 @@
CFG=myshutdown - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myshutdown.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "myshutdown.mak" CFG="myshutdown - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "myshutdown - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "myshutdown - Win32 Debug" (based on "Win32 (x86) Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -79,7 +79,7 @@ LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/mysqlshutdown/mysqlshutdown.dsp b/VC++Files/mysqlshutdown/mysqlshutdown.dsp
index 1489a5547ed..d4dd389e99d 100644
--- a/VC++Files/mysqlshutdown/mysqlshutdown.dsp
+++ b/VC++Files/mysqlshutdown/mysqlshutdown.dsp
@@ -7,25 +7,25 @@
CFG=mysqlshutdown - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlshutdown.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlshutdown.mak" CFG="mysqlshutdown - Win32 Release"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqlshutdown - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "mysqlshutdown - Win32 Debug" (based on "Win32 (x86) Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
MTL=midl.exe
RSC=rc.exe
@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /W3 /GX- /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
+# ADD CPP /nologo /G6 /W3 /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@@ -52,7 +52,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"../client_release/mysqlshutdown.exe"
@@ -72,7 +72,7 @@ LINK32=link.exe
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G6 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /G6 /W3 /GX- /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
+# ADD CPP /nologo /G6 /W3 /Z7 /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@@ -81,11 +81,11 @@ LINK32=link.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"../client_release/mysqlshutdown.exe"
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"../client_debug/mysqlshutdown.exe"
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/mysqlwatch/mysqlwatch.dsp b/VC++Files/mysqlwatch/mysqlwatch.dsp
index 004f444e09b..5c209f55e51 100644
--- a/VC++Files/mysqlwatch/mysqlwatch.dsp
+++ b/VC++Files/mysqlwatch/mysqlwatch.dsp
@@ -7,18 +7,18 @@
CFG=mysqlwatch - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlwatch.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqlwatch.mak" CFG="mysqlwatch - Win32 Release"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqlwatch - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
diff --git a/VC++Files/mysys/mysys.dsp b/VC++Files/mysys/mysys.dsp
index e7d8f4172a6..b410d0a7465 100644
--- a/VC++Files/mysys/mysys.dsp
+++ b/VC++Files/mysys/mysys.dsp
@@ -7,26 +7,26 @@
CFG=mysys - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysys.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysys.mak" CFG="mysys - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysys - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "mysys - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "mysys - Win32 Max" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "mysys - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LIB32=link.exe -lib
+LIB32=xilink6.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_release\mysys.lib"
@@ -66,13 +66,14 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Zi /Od /I "../include" /I "../zlib" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /D "USE_SYMDIR" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../zlib" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /D "USE_SYMDIR" /FD /c
+# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LIB32=link.exe -lib
+LIB32=xilink6.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_debug\mysys.lib"
@@ -85,23 +86,23 @@ LIB32=link.exe -lib
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "mysys___Win32_Max"
-# PROP Intermediate_Dir "mysys___Win32_Max"
+# PROP Output_Dir "max"
+# PROP Intermediate_Dir "max"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../zlib" /I "../sql" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_SYMDIR" /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../zlib" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /D "USE_SYMDIR" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LIB32=link.exe -lib
+LIB32=xilink6.exe -lib
# ADD BASE LIB32 /nologo /out:"..\lib_release\mysys.lib"
# ADD LIB32 /nologo /out:"..\lib_release\mysys-max.lib"
-!ENDIF
+!ENDIF
# Begin Target
@@ -120,7 +121,7 @@ SOURCE=.\array.c
!ELSEIF "$(CFG)" == "mysys - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -141,23 +142,15 @@ SOURCE=.\errors.c
# End Source File
# Begin Source File
-SOURCE=.\getopt.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\getopt1.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\getvar.c
+SOURCE=.\hash.c
# End Source File
# Begin Source File
-SOURCE=.\hash.c
+SOURCE=.\list.c
# End Source File
# Begin Source File
-SOURCE=.\list.c
+SOURCE=.\md5.c
# End Source File
# Begin Source File
@@ -209,10 +202,6 @@ SOURCE=.\mf_pack.c
# End Source File
# Begin Source File
-SOURCE=.\mf_pack2.c
-# End Source File
-# Begin Source File
-
SOURCE=.\mf_path.c
# End Source File
# Begin Source File
@@ -261,6 +250,10 @@ SOURCE=.\mulalloc.c
# End Source File
# Begin Source File
+SOURCE=.\my_aes.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_alarm.c
# End Source File
# Begin Source File
@@ -273,6 +266,10 @@ SOURCE=.\my_append.c
# End Source File
# Begin Source File
+SOURCE=.\my_bit.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_bitmap.c
# End Source File
# Begin Source File
@@ -321,6 +318,10 @@ SOURCE=.\my_gethostbyname.c
# End Source File
# Begin Source File
+SOURCE=.\my_getopt.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_getwd.c
# End Source File
# Begin Source File
@@ -405,6 +406,10 @@ SOURCE=.\my_seek.c
# End Source File
# Begin Source File
+SOURCE=.\my_sleep.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_static.c
# End Source File
# Begin Source File
@@ -413,6 +418,18 @@ SOURCE=.\my_static.h
# End Source File
# Begin Source File
+SOURCE=.\my_symlink.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_symlink2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\my_sync.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_tempnam.c
# End Source File
# Begin Source File
@@ -429,6 +446,10 @@ SOURCE=.\my_wincond.c
# End Source File
# Begin Source File
+SOURCE=.\my_winsem.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_winthread.c
# End Source File
# Begin Source File
@@ -453,7 +474,7 @@ SOURCE=.\raid.cpp
# End Source File
# Begin Source File
-SOURCE=.\raid2.c
+SOURCE=.\rijndael.c
# End Source File
# Begin Source File
@@ -461,6 +482,10 @@ SOURCE=.\safemalloc.c
# End Source File
# Begin Source File
+SOURCE=.\sha1.c
+# End Source File
+# Begin Source File
+
SOURCE=.\string.c
# End Source File
# Begin Source File
@@ -479,7 +504,7 @@ SOURCE=.\thr_lock.c
!ELSEIF "$(CFG)" == "mysys - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
diff --git a/VC++Files/mysys/mysys.dsw b/VC++Files/mysys/mysys.dsw
index d5064051fc9..445079aed69 100644
--- a/VC++Files/mysys/mysys.dsw
+++ b/VC++Files/mysys/mysys.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/pack_isam/pack_isam.dsp b/VC++Files/pack_isam/pack_isam.dsp
index ee949e376d3..cdcba702e15 100644
--- a/VC++Files/pack_isam/pack_isam.dsp
+++ b/VC++Files/pack_isam/pack_isam.dsp
@@ -7,25 +7,25 @@
CFG=pack_isam - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "pack_isam.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "pack_isam.mak" CFG="pack_isam - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "pack_isam - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "pack_isam - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "pack_isam - Win32 Release"
@@ -48,7 +48,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /machine:I386 /out:"../client_release/pack_isam.exe"
@@ -66,17 +66,18 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /I "../isam" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../isam" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /debug /machine:I386 /out:"../client_debug/pack_isam.exe" /pdbtype:sept
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/perror/perror.dsp b/VC++Files/perror/perror.dsp
index 2b720ace3e7..99bd8f67ae2 100644
--- a/VC++Files/perror/perror.dsp
+++ b/VC++Files/perror/perror.dsp
@@ -7,25 +7,25 @@
CFG=perror - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "perror.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "perror.mak" CFG="perror - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "perror - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "perror - Win32 Debug" (based on "Win32 (x86) Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
MTL=midl.exe
RSC=rc.exe
@@ -38,12 +38,13 @@ RSC=rc.exe
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -51,7 +52,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/perror.exe"
# SUBTRACT LINK32 /pdb:none
@@ -70,7 +71,8 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
+# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -78,12 +80,12 @@ LINK32=link.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /incremental:no /debug /machine:I386 /pdbtype:sept
# SUBTRACT LINK32 /pdb:none
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/prepare b/VC++Files/prepare
new file mode 100755
index 00000000000..e0dff9e04c0
--- /dev/null
+++ b/VC++Files/prepare
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+if [ -f prepare_done ]
+then
+ exit
+fi
+
+cd ..
+SRCDIR=`pwd`
+
+(
+find $SRCDIR -name *.dsw -and -not -path \*SCCS\* -print
+find $SRCDIR -name *.dsp -and -not -path \*SCCS\* -print
+)|(
+while read v
+do
+ sed 's/$'"/`echo -e \\\r`/" $v > $v.tmp
+ rm $v
+ mv $v.tmp $v
+done
+)
+
+ln -s $SRCDIR/include $SRCDIR/VC++Files/include
+
+link_dir_files()
+{
+ for arg do
+
+ cd $SRCDIR/$arg/
+ (
+ ls -A1|grep \\.[ch]$
+ ls -A1|grep \\.ih$
+ ls -A1|grep \\.asm$
+ )|(
+ while read v
+ do
+ ln -s $SRCDIR/$arg/$v $SRCDIR/VC++Files/$arg/$v
+ done
+ )
+
+ cd $SRCDIR/$arg/
+ (ls -A1|grep \\.cc$|sed 's/.cc$//g')|(
+ while read v
+ do
+ ln -s $SRCDIR/$arg/$v.cc $SRCDIR/VC++Files/$arg/$v.cpp
+ done
+ )
+
+ done
+}
+
+link_dir_dirs()
+{
+ for arg do
+
+ cd $SRCDIR/$arg/
+ (
+ ls -l |grep "^d"|awk '{print($9)}' -
+ )|(
+ while read v
+ do
+ ln -s $SRCDIR/$arg/$v $SRCDIR/VC++Files/$arg/
+ done
+ )
+
+ done
+}
+
+link_dir_files 'heap'
+link_dir_files 'isam'
+link_dir_files 'merge'
+link_dir_files 'mysys'
+link_dir_files 'zlib'
+link_dir_files 'regex'
+link_dir_files 'strings'
+link_dir_files 'dbug'
+link_dir_files 'vio'
+link_dir_files 'client'
+link_dir_files 'libmysql'
+link_dir_files 'extra'
+link_dir_files 'myisam'
+link_dir_files 'myisammrg'
+link_dir_files 'innobase'
+link_dir_files 'bdb'
+link_dir_files 'sql'
+link_dir_files 'bdb/build_win32'
+link_dir_files 'libmysqld'
+
+link_dir_dirs 'bdb'
+link_dir_dirs 'innobase'
+
+ln -s $SRCDIR/myisam/myisampack.c $SRCDIR/VC++Files/myisampack/
+ln -s $SRCDIR/client/mysqlbinlog.cc $SRCDIR/VC++Files/mysqlbinlog/mysqlbinlog.cpp
+ln -s $SRCDIR/isam/pack_isam.c $SRCDIR/VC++Files/pack_isam/pack_isam.c
+
+echo '/* added for win : */' >> $SRCDIR/config.h
+echo '#undef HAVE_SCHED_H' >> $SRCDIR/config.h
+echo '#USE_QUERY_CACHE_INTEGRITY_CHECK 1' >> $SRCDIR/config.h
+
+echo '/* added for win : */' >> $SRCDIR/innobase/ib_config.h
+echo '#undef HAVE_SCHED_H' >> $SRCDIR/innobase/ib_config.h
+
+cd $SRCDIR/VC++Files
+echo '1' > prepare_done \ No newline at end of file
diff --git a/VC++Files/regex/regex.dsp b/VC++Files/regex/regex.dsp
index 5ee617c58b7..59b55ffe46f 100644
--- a/VC++Files/regex/regex.dsp
+++ b/VC++Files/regex/regex.dsp
@@ -7,19 +7,19 @@
CFG=regex - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "regex.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "regex.mak" CFG="regex - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "regex - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "regex - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -76,7 +76,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_debug\regex.lib"
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/regex/regex.dsw b/VC++Files/regex/regex.dsw
index 102e07af409..1abe4485cd4 100644
--- a/VC++Files/regex/regex.dsw
+++ b/VC++Files/regex/regex.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/replace/replace.dsp b/VC++Files/replace/replace.dsp
index 54584151418..2fe763ff388 100644
--- a/VC++Files/replace/replace.dsp
+++ b/VC++Files/replace/replace.dsp
@@ -7,25 +7,25 @@
CFG=replace - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "replace.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "replace.mak" CFG="replace - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "replace - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "replace - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "replace - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /machine:I386 /out:"../client_release/replace.exe"
@@ -67,18 +67,19 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40b /d "_DEBUG"
# ADD RSC /l 0x40b /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib wsock32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib setargv.obj /nologo /subsystem:console /incremental:no /machine:I386 /out:"../client_debug/replace.exe" /pdbtype:sept
# SUBTRACT LINK32 /debug
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/sql/mysqld.dsp b/VC++Files/sql/mysqld.dsp
index a63d84c6251..0da3d936df9 100644
--- a/VC++Files/sql/mysqld.dsp
+++ b/VC++Files/sql/mysqld.dsp
@@ -7,28 +7,28 @@
CFG=mysqld - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqld.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqld.mak" CFG="mysqld - Win32 Release"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqld - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqld - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqld - Win32 nt" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqld - Win32 Max nt" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqld - Win32 Max" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "mysqld - Win32 Release"
@@ -45,16 +45,16 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../zlib" /D "NDEBUG" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "SIGNAL_WITH_VIO_CLOSE" /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../zlib" /D "NDEBUG" /D "DBUG_OFF" /D "HAVE_INNOBASE_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_DLOPEN" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x410 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../client_release/mysqld-opt.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../client_release/mysqld-opt.exe"
# SUBTRACT LINK32 /debug
!ELSEIF "$(CFG)" == "mysqld - Win32 Debug"
@@ -71,15 +71,16 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /O2 /I "../include" /I "../regex" /I "../bdb/build_win32" /I "../zlib" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "USE_SYMDIR" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /FR /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../regex" /I "../bdb/build_win32" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_DLOPEN" /FD /c
+# SUBTRACT CPP /Fr /YX
# ADD BASE RSC /l 0x410 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_debug\dbug.lib ..\lib_debug\isam.lib ..\lib_debug\merge.lib ..\lib_debug\mysys.lib ..\lib_debug\strings.lib ..\lib_debug\regex.lib ..\lib_debug\heap.lib ..\lib_debug\bdb.lib ..\lib_debug\innodb.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqld.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_debug\dbug.lib ..\lib_debug\vio.lib ..\lib_debug\isam.lib ..\lib_debug\merge.lib ..\lib_debug\mysys.lib ..\lib_debug\strings.lib ..\lib_debug\regex.lib ..\lib_debug\heap.lib ..\lib_debug\bdb.lib ..\lib_debug\innodb.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqld.exe" /pdbtype:sept
!ELSEIF "$(CFG)" == "mysqld - Win32 nt"
@@ -91,22 +92,22 @@ LINK32=link.exe
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "NT"
-# PROP Intermediate_Dir "NT"
+# PROP Output_Dir "nt"
+# PROP Intermediate_Dir "nt"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G5 /MT /W3 /O2 /I "../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__WIN32__" /D "DBUG_OFF" /FD /c
# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../zlib" /I "../sql" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "HAVE_INNOBASE_DB" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_DLOPEN" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x410 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\dbug.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib /nologo /subsystem:console /debug /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-nt.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innodb.lib ..\lib_release\zlib.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-nt.exe"
# SUBTRACT LINK32 /pdb:none /debug
!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt"
@@ -119,23 +120,23 @@ LINK32=link.exe
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "mysqld___Win32_Max_nt"
-# PROP Intermediate_Dir "mysqld___Win32_Max_nt"
+# PROP Output_Dir "max_nt"
+# PROP Intermediate_Dir "max_nt"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /FD /c
# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../regex" /I "../bdb/build_win32" /I "../include" /I "../zlib" /I "../sql" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../bdb/build_win32" /D "NDEBUG" /D "__NT__" /D "DBUG_OFF" /D "USE_SYMDIR" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_DLOPEN" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-nt.exe"
# SUBTRACT BASE LINK32 /pdb:none /debug
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys-max.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib ..\lib_release\innodb-nt.lib ..\lib_release\bdb.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-max-nt.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys-max.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib /nologo /subsystem:console /map /machine:I386 /out:"../client_release/mysqld-max-nt.exe"
# SUBTRACT LINK32 /pdb:none /debug
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
@@ -148,25 +149,25 @@ LINK32=link.exe
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "mysqld___Win32_Max"
-# PROP Intermediate_Dir "mysqld___Win32_Max"
+# PROP Output_Dir "max"
+# PROP Intermediate_Dir "max"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /D "NDEBUG" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /FD /c
# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../bdb/build_win32" /I "../zlib../sql" /D "NDEBUG" /D "DBUG_OFF" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "USE_SYMDIR" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "SIGNAL_WITH_VIO_CLOSE" /D "HAVE_DLOPEN" /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../regex" /I "../bdb/build_win32" /D "NDEBUG" /D "DBUG_OFF" /D "USE_SYMDIR" /D "HAVE_INNOBASE_DB" /D "HAVE_BERKELEY_DB" /D "MYSQL_SERVER" /D "_WINDOWS" /D "_CONSOLE" /D "_MBCS" /D "HAVE_DLOPEN" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /out:"../client_release/mysqld-opt.exe"
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys-max.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib ..\lib_release\zlib.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../client_release/mysqld-max.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\vio.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys-max.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib ..\lib_release\zlib.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../client_release/mysqld-max.exe"
# SUBTRACT LINK32 /debug
-!ENDIF
+!ENDIF
# Begin Target
@@ -192,7 +193,7 @@ SOURCE=.\convert.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -212,7 +213,7 @@ SOURCE=.\derror.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -236,7 +237,7 @@ SOURCE=.\field.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -256,7 +257,7 @@ SOURCE=.\field_conv.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -276,7 +277,7 @@ SOURCE=.\filesort.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -289,7 +290,7 @@ SOURCE=.\ha_heap.cpp
# End Source File
# Begin Source File
-SOURCE=.\ha_innobase.cpp
+SOURCE=.\ha_innodb.cpp
# End Source File
# Begin Source File
@@ -324,7 +325,7 @@ SOURCE=.\handler.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -343,7 +344,7 @@ SOURCE=.\hash_filo.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -366,7 +367,7 @@ SOURCE=.\hostname.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -386,7 +387,7 @@ SOURCE=.\init.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -406,7 +407,7 @@ SOURCE=.\item.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -426,7 +427,7 @@ SOURCE=.\item_buff.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -446,7 +447,7 @@ SOURCE=.\item_cmpfunc.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -470,7 +471,7 @@ SOURCE=.\item_func.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -490,7 +491,7 @@ SOURCE=.\item_strfunc.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -510,7 +511,7 @@ SOURCE=.\item_sum.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -529,7 +530,7 @@ SOURCE=.\item_timefunc.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -549,7 +550,7 @@ SOURCE=.\item_uniq.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -569,7 +570,7 @@ SOURCE=.\key.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -589,7 +590,7 @@ SOURCE=.\lock.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -609,7 +610,7 @@ SOURCE=.\log.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -618,10 +619,6 @@ SOURCE=.\log_event.cpp
# End Source File
# Begin Source File
-SOURCE=.\md5.c
-# End Source File
-# Begin Source File
-
SOURCE=.\mf_iocache.cpp
!IF "$(CFG)" == "mysqld - Win32 Release"
@@ -636,7 +633,7 @@ SOURCE=.\mf_iocache.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -660,7 +657,7 @@ SOURCE=.\mysqld.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -680,7 +677,7 @@ SOURCE=.\net_pkg.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -703,7 +700,7 @@ SOURCE=.\nt_servc.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -730,7 +727,7 @@ SOURCE=.\opt_range.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -757,7 +754,7 @@ SOURCE=.\password.c
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -777,7 +774,7 @@ SOURCE=.\procedure.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -797,8 +794,16 @@ SOURCE=.\records.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
+
+# End Source File
+# Begin Source File
+SOURCE=.\repl_failsafe.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\set_var.cpp
# End Source File
# Begin Source File
@@ -821,7 +826,7 @@ SOURCE=.\sql_acl.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -845,7 +850,7 @@ SOURCE=.\sql_base.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -869,7 +874,7 @@ SOURCE=.\sql_class.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -897,7 +902,7 @@ SOURCE=.\sql_db.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -917,7 +922,7 @@ SOURCE=.\sql_delete.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -926,6 +931,10 @@ SOURCE=.\sql_do.cpp
# End Source File
# Begin Source File
+SOURCE=.\sql_handler.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\sql_insert.cpp
!IF "$(CFG)" == "mysqld - Win32 Release"
@@ -941,7 +950,7 @@ SOURCE=.\sql_insert.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -961,7 +970,7 @@ SOURCE=.\sql_lex.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -981,7 +990,7 @@ SOURCE=.\sql_list.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1001,7 +1010,7 @@ SOURCE=.\sql_load.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1025,7 +1034,7 @@ SOURCE=.\sql_map.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1045,7 +1054,7 @@ SOURCE=.\sql_parse.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1073,7 +1082,7 @@ SOURCE=.\sql_select.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1093,7 +1102,7 @@ SOURCE=.\sql_show.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1113,7 +1122,7 @@ SOURCE=.\sql_string.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1133,7 +1142,7 @@ SOURCE=.\sql_table.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1153,7 +1162,7 @@ SOURCE=.\sql_test.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1162,6 +1171,10 @@ SOURCE=.\sql_udf.cpp
# End Source File
# Begin Source File
+SOURCE=.\sql_union.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\sql_update.cpp
!IF "$(CFG)" == "mysqld - Win32 Release"
@@ -1177,7 +1190,7 @@ SOURCE=.\sql_update.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1197,7 +1210,7 @@ SOURCE=.\sql_yacc.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1221,7 +1234,7 @@ SOURCE=.\thr_malloc.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -1241,8 +1254,12 @@ SOURCE=.\time.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
+!ENDIF
+
+# End Source File
+# Begin Source File
+SOURCE=.\uniques.cpp
# End Source File
# Begin Source File
@@ -1261,12 +1278,8 @@ SOURCE=.\unireg.cpp
!ELSEIF "$(CFG)" == "mysqld - Win32 Max"
-!ENDIF
-
-# End Source File
-# Begin Source File
+!ENDIF
-SOURCE=.\violite.c
# End Source File
# End Target
# End Project
diff --git a/VC++Files/sql/mysqld.dsw b/VC++Files/sql/mysqld.dsw
index ed820ed7a90..67948565f66 100644
--- a/VC++Files/sql/mysqld.dsw
+++ b/VC++Files/sql/mysqld.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/sql/mysqldmax.dsp b/VC++Files/sql/mysqldmax.dsp
index 4d24d033c51..24ea83159d9 100644
--- a/VC++Files/sql/mysqldmax.dsp
+++ b/VC++Files/sql/mysqldmax.dsp
@@ -7,20 +7,20 @@
CFG=mysqldmax - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqldmax.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "mysqldmax.mak" CFG="mysqldmax - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "mysqldmax - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqldmax - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "mysqldmax - Win32 nt" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -103,7 +103,7 @@ LINK32=link.exe
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\isam.lib ..\lib_release\merge.lib ..\lib_release\myisam.lib ..\lib_release\myisammrg.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap.lib ..\lib_release\zlib.lib ..\lib_release\innobase-nt.lib ..\lib_release\libdb32s.lib /nologo /subsystem:console /pdb:"NT/mysqld-nt.pdb" /map:"NT/mysqld-nt.map" /machine:I386 /nodefaultlib:"LIBC" /out:"../client_release/mysqld-max-nt.exe"
# SUBTRACT LINK32 /pdb:none
-!ENDIF
+!ENDIF
# Begin Target
@@ -123,7 +123,7 @@ SOURCE=.\convert.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -139,7 +139,7 @@ SOURCE=.\derror.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -155,7 +155,7 @@ SOURCE=.\field.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -171,7 +171,7 @@ SOURCE=.\field_conv.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -187,7 +187,7 @@ SOURCE=.\filesort.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -231,7 +231,7 @@ SOURCE=.\handler.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -246,7 +246,7 @@ SOURCE=.\hash_filo.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -265,7 +265,7 @@ SOURCE=.\hostname.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -281,7 +281,7 @@ SOURCE=.\init.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -297,7 +297,7 @@ SOURCE=.\item.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -313,7 +313,7 @@ SOURCE=.\item_buff.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -329,7 +329,7 @@ SOURCE=.\item_cmpfunc.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -349,7 +349,7 @@ SOURCE=.\item_func.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -365,7 +365,7 @@ SOURCE=.\item_strfunc.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -381,7 +381,7 @@ SOURCE=.\item_sum.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -396,7 +396,7 @@ SOURCE=.\item_timefunc.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -412,7 +412,7 @@ SOURCE=.\item_uniq.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -428,7 +428,7 @@ SOURCE=.\key.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -444,7 +444,7 @@ SOURCE=.\lock.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -460,7 +460,7 @@ SOURCE=.\log.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -483,7 +483,7 @@ SOURCE=.\mf_iocache.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -507,7 +507,7 @@ SOURCE=.\mysqld.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -523,7 +523,7 @@ SOURCE=.\net_pkg.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -542,7 +542,7 @@ SOURCE=.\nt_servc.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -565,7 +565,7 @@ SOURCE=.\opt_range.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -588,7 +588,7 @@ SOURCE=.\password.c
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -604,7 +604,7 @@ SOURCE=.\procedure.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -620,7 +620,7 @@ SOURCE=.\records.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -640,7 +640,7 @@ SOURCE=.\sql_acl.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -660,7 +660,7 @@ SOURCE=.\sql_base.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -680,7 +680,7 @@ SOURCE=.\sql_class.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -704,7 +704,7 @@ SOURCE=.\sql_db.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -720,7 +720,7 @@ SOURCE=.\sql_delete.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -736,7 +736,7 @@ SOURCE=.\sql_insert.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -752,7 +752,7 @@ SOURCE=.\sql_lex.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -768,7 +768,7 @@ SOURCE=.\sql_list.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -784,7 +784,7 @@ SOURCE=.\sql_load.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -804,7 +804,7 @@ SOURCE=.\sql_map.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -820,7 +820,7 @@ SOURCE=.\sql_parse.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -844,7 +844,7 @@ SOURCE=.\sql_select.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -860,7 +860,7 @@ SOURCE=.\sql_show.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -876,7 +876,7 @@ SOURCE=.\sql_string.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -892,7 +892,7 @@ SOURCE=.\sql_table.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -908,7 +908,7 @@ SOURCE=.\sql_test.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -924,7 +924,7 @@ SOURCE=.\sql_update.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -940,7 +940,7 @@ SOURCE=.\sql_yacc.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -960,7 +960,7 @@ SOURCE=.\thr_malloc.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -976,7 +976,7 @@ SOURCE=.\time.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -992,7 +992,7 @@ SOURCE=.\unireg.cpp
!ELSEIF "$(CFG)" == "mysqldmax - Win32 nt"
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
diff --git a/VC++Files/sql/old/mysqld.dsw b/VC++Files/sql/old/mysqld.dsw
new file mode 100644
index 00000000000..67948565f66
--- /dev/null
+++ b/VC++Files/sql/old/mysqld.dsw
@@ -0,0 +1,28 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "mysqld"=".\mysqld.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
diff --git a/VC++Files/strings/MASM6x/strings.dsp b/VC++Files/strings/MASM6x/strings.dsp
index 0c1a3bdc0c2..1f54910bf58 100644
--- a/VC++Files/strings/MASM6x/strings.dsp
+++ b/VC++Files/strings/MASM6x/strings.dsp
@@ -7,19 +7,19 @@
CFG=strings - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "strings.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "strings.mak" CFG="strings - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "strings - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "strings - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -76,7 +76,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_debug\strings.lib"
-!ENDIF
+!ENDIF
# Begin Target
@@ -186,7 +186,7 @@ InputName=Strings
# End Custom Build
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
@@ -233,7 +233,7 @@ InputName=Strxmov
# End Custom Build
-!ENDIF
+!ENDIF
# End Source File
# Begin Source File
diff --git a/VC++Files/strings/MASM6x/strings.dsw b/VC++Files/strings/MASM6x/strings.dsw
index e3777b8e7d5..63fc3706c19 100644
--- a/VC++Files/strings/MASM6x/strings.dsw
+++ b/VC++Files/strings/MASM6x/strings.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/strings/backup/strings.dsp b/VC++Files/strings/backup/strings.dsp
new file mode 100644
index 00000000000..a6be39b40ab
--- /dev/null
+++ b/VC++Files/strings/backup/strings.dsp
@@ -0,0 +1,244 @@
+# Microsoft Developer Studio Project File - Name="strings" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=strings - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "strings.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "strings.mak" CFG="strings - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "strings - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "strings - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\strings.lib"
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\strings.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "strings - Win32 Release"
+# Name "strings - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\atof.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bchange.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bcmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bfill.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bmove512.c
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-big5.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-czech.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-euc_kr.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-gb2312.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-gbk.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-sjis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-tis620.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-ujis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=.\ctype.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\int2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\llstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\longlong2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_strinstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\str2int.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\Strings.asm
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# Begin Custom Build
+OutDir=.\release
+InputPath=.\Strings.asm
+InputName=Strings
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ C:\masm\masm -Mx -t -DDOS386 -DM_I386 $(InputPath),$(OutDir)\$(InputName).obj,,,
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# Begin Custom Build
+OutDir=.\debug
+InputPath=.\Strings.asm
+InputName=Strings
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ C:\masm\masm -Mx -t -DDOS386 -DM_I386 $(InputPath),$(Outdir)\$(InputName).obj,,,
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtol.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoll.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoul.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoull.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\Strxmov.asm
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# Begin Custom Build
+OutDir=.\release
+InputPath=.\Strxmov.asm
+InputName=Strxmov
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ C:\masm\masm -Mx -t -DDOS386 -DM_I386 $(InputPath),$(OutDir)\$(InputName).obj,,,
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# Begin Custom Build
+OutDir=.\debug
+InputPath=.\Strxmov.asm
+InputName=Strxmov
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ C:\masm\masm -Mx -t -DDOS386 -DM_I386 $(InputPath),$(Outdir)\$(InputName).obj,,,
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\strxnmov.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/strings/backup/strings.dsw b/VC++Files/strings/backup/strings.dsw
new file mode 100644
index 00000000000..63fc3706c19
--- /dev/null
+++ b/VC++Files/strings/backup/strings.dsw
@@ -0,0 +1,28 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "strings"=".\strings.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
diff --git a/VC++Files/strings/noMASM/strings.dsp b/VC++Files/strings/noMASM/strings.dsp
index ec66cf7efd8..6e2dbb3c013 100644
--- a/VC++Files/strings/noMASM/strings.dsp
+++ b/VC++Files/strings/noMASM/strings.dsp
@@ -7,19 +7,19 @@
CFG=strings - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "strings.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "strings.mak" CFG="strings - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "strings - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "strings - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -76,7 +76,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_debug\strings.lib"
-!ENDIF
+!ENDIF
# Begin Target
@@ -132,6 +132,10 @@ SOURCE=".\ctype-gbk.c"
# End Source File
# Begin Source File
+SOURCE=".\ctype-latin1_de.c"
+# End Source File
+# Begin Source File
+
SOURCE=".\ctype-sjis.c"
# End Source File
# Begin Source File
diff --git a/VC++Files/strings/noMASM/strings.dsw b/VC++Files/strings/noMASM/strings.dsw
index e3777b8e7d5..63fc3706c19 100644
--- a/VC++Files/strings/noMASM/strings.dsw
+++ b/VC++Files/strings/noMASM/strings.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/strings/strings.dsp b/VC++Files/strings/strings.dsp
new file mode 100644
index 00000000000..28cc1f39c0c
--- /dev/null
+++ b/VC++Files/strings/strings.dsp
@@ -0,0 +1,248 @@
+# Microsoft Developer Studio Project File - Name="strings" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=strings - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "strings.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "strings.mak" CFG="strings - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "strings - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "strings - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\strings.lib"
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "debug"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /Gf /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\strings.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "strings - Win32 Release"
+# Name "strings - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\atof.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bchange.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bcmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bfill.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bmove512.c
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-big5.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-czech.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-euc_kr.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-gb2312.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-gbk.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-latin1_de.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-sjis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-tis620.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\ctype-ujis.c"
+# End Source File
+# Begin Source File
+
+SOURCE=.\ctype.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\int2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\llstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\longlong2str.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_strinstr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\str2int.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\Strings.asm
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# Begin Custom Build
+OutDir=.\release
+InputPath=.\Strings.asm
+InputName=Strings
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /Cx /nologo /DDOS386 /DM_I386 /Zm /coff /c /Fo $(Outdir)\$(InputName).obj $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# Begin Custom Build
+OutDir=.\debug
+InputPath=.\Strings.asm
+InputName=Strings
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /Cx /nologo /DDOS386 /DM_I386 /Zm /coff /c /Fo $(Outdir)\$(InputName).obj $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtol.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoll.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoul.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\strtoull.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\Strxmov.asm
+
+!IF "$(CFG)" == "strings - Win32 Release"
+
+# Begin Custom Build
+OutDir=.\release
+InputPath=.\Strxmov.asm
+InputName=Strxmov
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /Cx /nologo /DDOS386 /DM_I386 /Zm /coff /c /Fo $(Outdir)\$(InputName).obj $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "strings - Win32 Debug"
+
+# Begin Custom Build
+OutDir=.\debug
+InputPath=.\Strxmov.asm
+InputName=Strxmov
+
+"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /Cx /nologo /DDOS386 /DM_I386 /Zm /coff /c /Fo $(Outdir)\$(InputName).obj $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\strxnmov.c
+# End Source File
+# End Target
+# End Project
diff --git a/VC++Files/strings/strings.dsw b/VC++Files/strings/strings.dsw
index e3777b8e7d5..63fc3706c19 100644
--- a/VC++Files/strings/strings.dsw
+++ b/VC++Files/strings/strings.dsw
@@ -26,4 +26,3 @@ Package=<3>
}}}
###############################################################################
-
diff --git a/VC++Files/test1/mysql_thr.c b/VC++Files/test1/mysql_thr.c
new file mode 100644
index 00000000000..fac5c37a9af
--- /dev/null
+++ b/VC++Files/test1/mysql_thr.c
@@ -0,0 +1,255 @@
+/* Testing of connecting to MySQL from X threads */
+
+#include <windows.h>
+#include <process.h>
+#include <stdio.h>
+#include <mysql.h>
+#include <errno.h>
+
+#define TEST_COUNT 20
+
+/*****************************************************************************
+** The following is to emulate the posix thread interface
+*****************************************************************************/
+
+typedef HANDLE pthread_t;
+typedef struct thread_attr {
+ DWORD dwStackSize ;
+ DWORD dwCreatingFlag ;
+ int priority ;
+} pthread_attr_t ;
+
+typedef struct { int dummy; } pthread_condattr_t;
+typedef unsigned int uint;
+
+typedef struct {
+ uint waiting;
+ HANDLE semaphore;
+} pthread_cond_t;
+
+typedef CRITICAL_SECTION pthread_mutex_t;
+
+#define pthread_mutex_init(A,B) InitializeCriticalSection(A)
+#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
+#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
+#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
+#define pthread_handler_decl(A,B) unsigned __cdecl A(void *B)
+typedef unsigned (__cdecl *pthread_handler)(void *);
+#define pthread_self() GetCurrentThread()
+
+static unsigned int thread_count;
+static pthread_cond_t COND_thread_count;
+static pthread_mutex_t LOCK_thread_count;
+
+pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
+ THR_LOCK_lock,THR_LOCK_isam;
+
+/*
+** We have tried to use '_beginthreadex' instead of '_beginthread' here
+** but in this case the program leaks about 512 characters for each
+** created thread !
+*/
+
+int pthread_create(pthread_t *thread_id, pthread_attr_t *attr,
+ pthread_handler func, void *param)
+{
+ HANDLE hThread;
+
+ hThread=(HANDLE)_beginthread(func,
+ attr->dwStackSize ? attr->dwStackSize :
+ 65535,param);
+ if ((long) hThread == -1L)
+ {
+ return(errno ? errno : -1);
+ }
+ *thread_id=hThread;
+ return(0);
+}
+
+void pthread_exit(unsigned A)
+{
+ _endthread();
+}
+
+/*
+** The following simple implementation of conds works as long as
+** only one thread uses pthread_cond_wait at a time.
+** This is coded very carefully to work with thr_lock.
+*/
+
+/*****************************************************************************
+** The following is a simple implementation of posix conditions
+*****************************************************************************/
+
+int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+ cond->waiting=0;
+ cond->semaphore=CreateSemaphore(NULL,0,0x7FFFFFFF,(char*) 0);
+ if (!cond->semaphore)
+ return ENOMEM;
+ return 0;
+}
+
+int pthread_cond_destroy(pthread_cond_t *cond)
+{
+ return CloseHandle(cond->semaphore) ? 0 : EINVAL;
+}
+
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ InterlockedIncrement(&cond->waiting);
+ LeaveCriticalSection(mutex);
+ WaitForSingleObject(cond->semaphore,INFINITE);
+ InterlockedDecrement(&cond->waiting);
+ EnterCriticalSection(mutex);
+ return 0 ;
+}
+
+int pthread_cond_signal(pthread_cond_t *cond)
+{
+ long prev_count;
+ if (cond->waiting)
+ ReleaseSemaphore(cond->semaphore,1,&prev_count);
+ return 0;
+}
+
+int pthread_attr_init(pthread_attr_t *connect_att)
+{
+ connect_att->dwStackSize = 0;
+ connect_att->dwCreatingFlag = 0;
+ connect_att->priority = 0;
+ return 0;
+}
+
+int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack)
+{
+ connect_att->dwStackSize=stack;
+ return 0;
+}
+
+int pthread_attr_setprio(pthread_attr_t *connect_att,int priority)
+{
+ connect_att->priority=priority;
+ return 0;
+}
+
+int pthread_attr_destroy(pthread_attr_t *connect_att)
+{
+ return 0;
+}
+
+/* from my_pthread.c */
+
+#ifndef REMOVE_BUG
+
+__declspec(thread) int THR_KEY_my_errno;
+
+int _my_errno(void)
+{
+ return THR_KEY_my_errno;
+}
+#endif
+
+
+/*****************************************************************************
+** The test program
+*****************************************************************************/
+
+pthread_handler_decl(test_thread,arg)
+{
+ MYSQL mysql;
+ MYSQL_RES *res;
+
+ mysql_init(&mysql);
+ if (!mysql_real_connect(&mysql,NULL,0,0,NULL,0,NULL,0))
+ {
+ fprintf(stderr,"Couldn't connect to engine!\n%s\n\n",mysql_error(&mysql));
+ perror("");
+ goto end;
+ }
+ if (mysql_query(&mysql,"select 1") < 0)
+ {
+ fprintf(stderr,"Query failed (%s)\n",mysql_error(&mysql));
+ goto end;
+ }
+ if (!(res=mysql_store_result(&mysql)))
+ {
+ fprintf(stderr,"Couldn't get result from query failed\n",
+ mysql_error(&mysql));
+ goto end;
+ }
+ mysql_free_result(res);
+
+end:
+
+ Sleep(1000); /* Win32 sleep */
+ mysql_close(&mysql);
+
+ pthread_mutex_lock(&LOCK_thread_count);
+ thread_count--;
+ pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
+ pthread_mutex_unlock(&LOCK_thread_count);
+ pthread_exit(0);
+ return 0;
+}
+
+int main(int argc,char **argv)
+{
+ pthread_t tid;
+ pthread_attr_t thr_attr;
+ int i,error;
+
+ if ((error=pthread_cond_init(&COND_thread_count,NULL)))
+ {
+ fprintf(stderr,"Got error: %d from pthread_cond_init (errno: %d)",
+ error,errno);
+ exit(1);
+ }
+ pthread_mutex_init(&LOCK_thread_count,NULL);
+ if ((error=pthread_attr_init(&thr_attr)))
+ {
+ fprintf(stderr,"Got error: %d from pthread_attr_init (errno: %d)",
+ error,errno);
+ exit(1);
+ }
+ if ((error=pthread_attr_setstacksize(&thr_attr,65536L)))
+ {
+ fprintf(stderr,"Got error: %d from pthread_attr_setstacksize (errno: %d)",
+ error,errno);
+ exit(1);
+ }
+
+ printf("Init ok. Creating %d threads\n",TEST_COUNT);
+
+ for (i=1 ; i <= TEST_COUNT ; i++)
+ {
+ int *param= &i;
+ if ((error=pthread_mutex_lock(&LOCK_thread_count)))
+ {
+ fprintf(stderr,"\nGot error: %d from pthread_mutex_lock (errno: %d)",
+ error,errno);
+ exit(1);
+ }
+ if ((error=pthread_create(&tid,&thr_attr,test_thread,(void*) param)))
+ {
+ fprintf(stderr,"\nGot error: %d from pthread_create (errno: %d)\n",
+ error,errno);
+ pthread_mutex_unlock(&LOCK_thread_count);
+ exit(1);
+ }
+ thread_count++;
+ pthread_mutex_unlock(&LOCK_thread_count);
+ }
+
+ if ((error=pthread_mutex_lock(&LOCK_thread_count)))
+ fprintf(stderr,"\nGot error: %d from pthread_mutex_lock\n",error);
+ while (thread_count)
+ {
+ if ((error=pthread_cond_wait(&COND_thread_count,&LOCK_thread_count)))
+ fprintf(stderr,"\nGot error: %d from pthread_cond_wait\n",error);
+ }
+ pthread_mutex_unlock(&LOCK_thread_count);
+ pthread_attr_destroy(&thr_attr);
+ printf("\nend\n");
+ return 0;
+}
diff --git a/VC++Files/test1/test1.dsp b/VC++Files/test1/test1.dsp
index 50a165e3e4d..df4b31d684e 100644
--- a/VC++Files/test1/test1.dsp
+++ b/VC++Files/test1/test1.dsp
@@ -7,25 +7,25 @@
CFG=test1 - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "test1.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "test1.mak" CFG="test1 - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "test1 - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "test1 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "test1 - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
@@ -67,19 +67,19 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /ZI /Od /I "../include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 libmysql.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\lib_debug"
# SUBTRACT LINK32 /incremental:no
-!ENDIF
+!ENDIF
# Begin Target
@@ -95,7 +95,7 @@ SOURCE=.\mysql_thr.c
!ELSEIF "$(CFG)" == "test1 - Win32 Debug"
-!ENDIF
+!ENDIF
# End Source File
# End Target
diff --git a/VC++Files/thr_insert_test/thr_insert_test.dsp b/VC++Files/thr_insert_test/thr_insert_test.dsp
index 770125ab65b..11028b926d1 100644
--- a/VC++Files/thr_insert_test/thr_insert_test.dsp
+++ b/VC++Files/thr_insert_test/thr_insert_test.dsp
@@ -7,19 +7,19 @@
CFG=thr_insert_test - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "thr_insert_test.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "thr_insert_test.mak" CFG="thr_insert_test - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "thr_insert_test - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "thr_insert_test - Win32 Debug" (based on "Win32 (x86) Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -83,7 +83,7 @@ LINK32=link.exe
# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:"debug/mysqldump.pdb" /debug /machine:I386 /out:"../client_debug/thr_insert_test.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
# SUBTRACT LINK32 /pdb:none
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/VC++Files/thr_test/thr_test.dsp b/VC++Files/thr_test/thr_test.dsp
index 495d7280808..0c80de42521 100644
--- a/VC++Files/thr_test/thr_test.dsp
+++ b/VC++Files/thr_test/thr_test.dsp
@@ -7,25 +7,25 @@
CFG=thr_test - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "thr_test.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "thr_test.mak" CFG="thr_test - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "thr_test - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "thr_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "thr_test - Win32 Release"
@@ -49,7 +49,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# SUBTRACT LINK32 /nodefaultlib
@@ -68,17 +68,18 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Gm /Zi /Od /I "../include" /D "__WIN32__" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /D "__WIN32__" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c
+# SUBTRACT CPP /Fr /YX
# ADD BASE RSC /l 0x40b /d "_DEBUG"
# ADD RSC /l 0x40b /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LINK32=link.exe
+LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept
-!ENDIF
+!ENDIF
# Begin Target
@@ -96,7 +97,7 @@ SOURCE=.\thr_test.c
# ADD CPP /FAcs
-!ENDIF
+!ENDIF
# End Source File
# End Target
diff --git a/VC++Files/vio/vio.dsp b/VC++Files/vio/vio.dsp
new file mode 100644
index 00000000000..c250e693995
--- /dev/null
+++ b/VC++Files/vio/vio.dsp
@@ -0,0 +1,108 @@
+# Microsoft Developer Studio Project File - Name="vio" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=vio - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "vio.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "vio.mak" CFG="vio - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "vio - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "vio - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=xicl6.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "vio - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "release"
+# PROP Intermediate_Dir "release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_WINDOWS" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=xilink6.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_release\vio.lib"
+
+!ELSEIF "$(CFG)" == "vio - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_WINDOWS" /D "USE_SYMDIR" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=xilink6.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\lib_debug\vio.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "vio - Win32 Release"
+# Name "vio - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\vio.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\viosocket.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\viossl.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\viosslfactories.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/winmysqladmin/db.cpp b/VC++Files/winmysqladmin/db.cpp
new file mode 100644
index 00000000000..6e796856a7e
--- /dev/null
+++ b/VC++Files/winmysqladmin/db.cpp
@@ -0,0 +1,80 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+
+#include "db.h"
+#include "main.h"
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+Tdbfrm *dbfrm;
+//---------------------------------------------------------------------------
+__fastcall Tdbfrm::Tdbfrm(TComponent* Owner)
+ : TForm(Owner)
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall Tdbfrm::SpeedButton2Click(TObject *Sender)
+{
+ Close();
+}
+//---------------------------------------------------------------------------
+void __fastcall Tdbfrm::SpeedButton1Click(TObject *Sender)
+{
+ if (VerDBName())
+ {
+ if (!Form1->CreatingDB())
+ {
+ Form1->OutRefresh();
+ Edit1->Text = "";
+ Application->MessageBox("The database was created", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ }
+ }
+
+
+
+
+
+}
+//---------------------------------------------------------------------------
+bool __fastcall Tdbfrm::VerDBName()
+{
+ String temp = Edit1->Text;
+ if (Edit1->Text.IsEmpty())
+ {
+ Application->MessageBox("The name of the Database is Empty", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+
+ if (temp.Length() > 64)
+ {
+ Application->MessageBox("The name of the Database can't have more than 64 characters ", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+
+ for (int j = 1; j <= temp.Length(); j++)
+ {
+ if (temp[j] == ' ')
+ {
+ Application->MessageBox("The name of the Database can't have blank spaces ", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+ else if (temp[j] == '/')
+ {
+ Application->MessageBox("The name of the Database can't have frontslash (/)", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+ else if (temp[j] == '\\')
+ {
+ Application->MessageBox("The name of the Database can't have backslash (\\)", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+ else if (temp[j] == '.')
+ {
+ Application->MessageBox("The name of the Database can't have periods", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ return false;
+ }
+ }
+ return true;
+}
+//---------------------------------------------------------------------------
diff --git a/VC++Files/winmysqladmin/db.h b/VC++Files/winmysqladmin/db.h
new file mode 100644
index 00000000000..f7ab87351ea
--- /dev/null
+++ b/VC++Files/winmysqladmin/db.h
@@ -0,0 +1,32 @@
+//---------------------------------------------------------------------------
+#ifndef dbH
+#define dbH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <ExtCtrls.hpp>
+#include <Graphics.hpp>
+#include <Buttons.hpp>
+//---------------------------------------------------------------------------
+class Tdbfrm : public TForm
+{
+__published: // IDE-managed Components
+ TImage *Image1;
+ TLabel *Label1;
+ TLabel *Label2;
+ TEdit *Edit1;
+ TSpeedButton *SpeedButton1;
+ TSpeedButton *SpeedButton2;
+ void __fastcall SpeedButton2Click(TObject *Sender);
+ void __fastcall SpeedButton1Click(TObject *Sender);
+private: // User declarations
+ bool __fastcall VerDBName();
+public: // User declarations
+ __fastcall Tdbfrm(TComponent* Owner);
+};
+//---------------------------------------------------------------------------
+extern PACKAGE Tdbfrm *dbfrm;
+//---------------------------------------------------------------------------
+#endif
diff --git a/VC++Files/winmysqladmin/images/Goahead.ico b/VC++Files/winmysqladmin/images/Goahead.ico
new file mode 100644
index 00000000000..8241c90e2a2
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Goahead.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/HELP.ICO b/VC++Files/winmysqladmin/images/HELP.ICO
new file mode 100644
index 00000000000..d0cd6d68cce
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/HELP.ICO
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/INFO.ICO b/VC++Files/winmysqladmin/images/INFO.ICO
new file mode 100644
index 00000000000..e3afa8cf52c
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/INFO.ICO
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Info.bmp b/VC++Files/winmysqladmin/images/Info.bmp
new file mode 100644
index 00000000000..58f729fb1fd
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Info.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/MYINI.ICO b/VC++Files/winmysqladmin/images/MYINI.ICO
new file mode 100644
index 00000000000..428ed8e92b0
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/MYINI.ICO
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Myini.bmp b/VC++Files/winmysqladmin/images/Myini.bmp
new file mode 100644
index 00000000000..e743a1b9b32
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Myini.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Noentry.ico b/VC++Files/winmysqladmin/images/Noentry.ico
new file mode 100644
index 00000000000..27f2211f56c
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Noentry.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/SETUP.BMP b/VC++Files/winmysqladmin/images/SETUP.BMP
new file mode 100644
index 00000000000..c5794e5ac00
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/SETUP.BMP
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Setup 16.bmp b/VC++Files/winmysqladmin/images/Setup 16.bmp
new file mode 100644
index 00000000000..e17b06155fb
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Setup 16.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Table.ico b/VC++Files/winmysqladmin/images/Table.ico
new file mode 100644
index 00000000000..4469a915b7f
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Table.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/Working.ico b/VC++Files/winmysqladmin/images/Working.ico
new file mode 100644
index 00000000000..72faedbbfc5
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/Working.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/database.ico b/VC++Files/winmysqladmin/images/database.ico
new file mode 100644
index 00000000000..9689aa88361
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/database.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/find.ico b/VC++Files/winmysqladmin/images/find.ico
new file mode 100644
index 00000000000..2e0f96c52f9
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/find.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/green.ico b/VC++Files/winmysqladmin/images/green.ico
new file mode 100644
index 00000000000..ef53cd87994
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/green.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/help.bmp b/VC++Files/winmysqladmin/images/help.bmp
new file mode 100644
index 00000000000..76c6a90d2d8
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/help.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/initsetup.cpp b/VC++Files/winmysqladmin/images/initsetup.cpp
new file mode 100644
index 00000000000..d0dd15b059c
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/initsetup.cpp
@@ -0,0 +1,42 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+
+#include "initsetup.h"
+#include "main.h"
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+TForm2 *Form2;
+//---------------------------------------------------------------------------
+__fastcall TForm2::TForm2(TComponent* Owner)
+ : TForm(Owner)
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::BitBtn1Click(TObject *Sender)
+{
+if ((Edit1->Text).IsEmpty() || (Edit2->Text).IsEmpty())
+ Application->MessageBox("Fill the User name and Password text boxs ", "Winmysqladmin 1.0", MB_OK |MB_ICONINFORMATION);
+ else
+ {
+ if(Form1->ForceConnection())
+ if(Form1->ForceMySQLInit())
+ {
+ Form1->CreateMyIniFile();
+ Form1->CreatingShortCut();
+ }
+ Close();
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::BitBtn2Click(TObject *Sender)
+{
+ Close();
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::SpeedButton1Click(TObject *Sender)
+{
+ Application->HelpCommand(HELP_FINDER,0);
+}
+//---------------------------------------------------------------------------
diff --git a/VC++Files/winmysqladmin/images/killdb.ico b/VC++Files/winmysqladmin/images/killdb.ico
new file mode 100644
index 00000000000..9689aa88361
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/killdb.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/logo.ico b/VC++Files/winmysqladmin/images/logo.ico
new file mode 100644
index 00000000000..9409cad72b6
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/logo.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/multitrg.ico b/VC++Files/winmysqladmin/images/multitrg.ico
new file mode 100644
index 00000000000..76ffbe29c77
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/multitrg.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/mysql-07.bmp b/VC++Files/winmysqladmin/images/mysql-07.bmp
new file mode 100644
index 00000000000..dcae23b8813
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/mysql-07.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/mysql-17.bmp b/VC++Files/winmysqladmin/images/mysql-17.bmp
new file mode 100644
index 00000000000..0291c804006
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/mysql-17.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/mysql.BMP b/VC++Files/winmysqladmin/images/mysql.BMP
new file mode 100644
index 00000000000..ed5c7f9051f
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/mysql.BMP
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/red.ico b/VC++Files/winmysqladmin/images/red.ico
new file mode 100644
index 00000000000..b28288d576e
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/red.ico
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/red22.BMP b/VC++Files/winmysqladmin/images/red22.BMP
new file mode 100644
index 00000000000..a35052afa01
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/red22.BMP
Binary files differ
diff --git a/VC++Files/winmysqladmin/images/see.bmp b/VC++Files/winmysqladmin/images/see.bmp
new file mode 100644
index 00000000000..72fb2c50ec6
--- /dev/null
+++ b/VC++Files/winmysqladmin/images/see.bmp
Binary files differ
diff --git a/VC++Files/winmysqladmin/initsetup.cpp b/VC++Files/winmysqladmin/initsetup.cpp
new file mode 100644
index 00000000000..0a25b8cb79c
--- /dev/null
+++ b/VC++Files/winmysqladmin/initsetup.cpp
@@ -0,0 +1,40 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+
+#include "initsetup.h"
+#include "main.h"
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+TForm2 *Form2;
+//---------------------------------------------------------------------------
+__fastcall TForm2::TForm2(TComponent* Owner)
+ : TForm(Owner)
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::BitBtn1Click(TObject *Sender)
+{
+ if ((Edit1->Text).IsEmpty() || (Edit2->Text).IsEmpty())
+ Application->MessageBox("Fill the User name and Password text boxs ", "Winmysqladmin 1.0", MB_OK |MB_ICONINFORMATION);
+ else
+ {
+ Form1->GetServerFile();
+ Form1->CreateMyIniFile();
+ Form1->CreatingShortCut();
+
+ Close();
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::BitBtn2Click(TObject *Sender)
+{
+ Close();
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm2::SpeedButton1Click(TObject *Sender)
+{
+ Application->HelpCommand(HELP_FINDER,0);
+}
+//---------------------------------------------------------------------------
diff --git a/VC++Files/winmysqladmin/initsetup.h b/VC++Files/winmysqladmin/initsetup.h
new file mode 100644
index 00000000000..28f575198e3
--- /dev/null
+++ b/VC++Files/winmysqladmin/initsetup.h
@@ -0,0 +1,38 @@
+//---------------------------------------------------------------------------
+#ifndef initsetupH
+#define initsetupH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <Buttons.hpp>
+#include <ExtCtrls.hpp>
+#include <Graphics.hpp>
+//---------------------------------------------------------------------------
+class TForm2 : public TForm
+{
+__published: // IDE-managed Components
+ TImage *Image1;
+ TLabel *Label1;
+ TLabel *Label4;
+ TPanel *Panel1;
+ TLabel *Label5;
+ TLabel *Label6;
+ TLabel *Label2;
+ TEdit *Edit1;
+ TEdit *Edit2;
+ TBitBtn *BitBtn1;
+ TSpeedButton *SpeedButton1;
+ TBitBtn *BitBtn2;
+ void __fastcall BitBtn1Click(TObject *Sender);
+ void __fastcall BitBtn2Click(TObject *Sender);
+ void __fastcall SpeedButton1Click(TObject *Sender);
+private: // User declarations
+public: // User declarations
+ __fastcall TForm2(TComponent* Owner);
+};
+//---------------------------------------------------------------------------
+extern PACKAGE TForm2 *Form2;
+//---------------------------------------------------------------------------
+#endif
diff --git a/VC++Files/winmysqladmin/main.cpp b/VC++Files/winmysqladmin/main.cpp
new file mode 100644
index 00000000000..6ca29659255
--- /dev/null
+++ b/VC++Files/winmysqladmin/main.cpp
@@ -0,0 +1,2529 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+
+#include "main.h"
+#include "initsetup.h"
+#include "db.h"
+
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+#include <shellapi.h>
+#include <registry.hpp>
+#include <winsvc.h>
+#include <winsock.h>
+#include <shlobj.h>
+#include <IniFiles.hpp>
+#include <dir.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <deque.h>
+#include <vector.h>
+#include <fstream.h>
+#include <iostream.h>
+#include <iterator.h>
+#include <sstream.h>
+#include "mysql.h"
+#include <Printers.hpp>
+
+TForm1 *Form1;
+bool i_start, NT;
+bool IsForce = false;
+bool IsVariables = false;
+bool IsProcess = false ;
+bool IsDatabases = false;
+bool new_line = 0;
+bool ya = true;
+bool yy = true;
+bool rinit = false;
+AnsiString vpath;
+AnsiString vip;
+MYSQL_RES *res_1;
+static unsigned long q = 0;
+bool preport = false;
+bool treport = false;
+bool ereport = false;
+AnsiString mainroot;
+bool IsMySQLNode = false;
+MYSQL *MySQL;
+//---------------------------------------------------------------------------
+__fastcall TForm1::TForm1(TComponent* Owner)
+ : TForm(Owner)
+{
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::FormCreate(TObject *Sender)
+{
+ i_start = true;
+ IsConnect = false;
+ if (ParamCount() > 0){
+ if (ParamStr(1) == "-h" || ParamStr(1) == "h" ) {
+ ShowHelp(); Application->Terminate(); }
+ else if (ParamStr(1) == "-w" || ParamStr(1) == "w") {
+ i_start = false; ContinueLoad(); }
+ }
+ else {
+ ContinueLoad(); Hide(); GetServerOptions(); }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::DrawItem(TMessage& Msg)
+{
+ IconDrawItem((LPDRAWITEMSTRUCT)Msg.LParam);
+ TForm::Dispatch(&Msg);
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::MyNotify(TMessage& Msg)
+{
+ POINT MousePos;
+
+ switch(Msg.LParam) {
+ case WM_RBUTTONUP:
+ if (GetCursorPos(&MousePos)){
+ PopupMenu1->PopupComponent = Form1; SetForegroundWindow(Handle);
+ PopupMenu1->Popup(MousePos.x, MousePos.y);}
+ else Show();
+ break;
+ case WM_LBUTTONUP:
+ if (GetCursorPos(&MousePos)){
+ PopupMenu1->PopupComponent = Form1; SetForegroundWindow(Handle);
+ PopupMenu1->Popup(MousePos.x, MousePos.y); }
+
+ ToggleState();
+ break;
+ default:
+ break; }
+
+ TForm::Dispatch(&Msg);
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TrayMessage(DWORD dwMessage)
+{
+ NOTIFYICONDATA tnd;
+ PSTR pszTip;
+
+ pszTip = TipText();
+
+ tnd.cbSize = sizeof(NOTIFYICONDATA);
+ tnd.hWnd = Handle;
+ tnd.uID = IDC_MYICON;
+ tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
+ tnd.uCallbackMessage = MYWM_NOTIFY;
+
+ if (dwMessage == NIM_MODIFY){
+ tnd.hIcon = IconHandle();
+ if (pszTip)lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip));
+ else tnd.szTip[0] = '\0'; }
+ else { tnd.hIcon = NULL; tnd.szTip[0] = '\0'; }
+
+ return (Shell_NotifyIcon(dwMessage, &tnd));
+}
+//---------------------------------------------------------------------------
+HANDLE __fastcall TForm1::IconHandle(void)
+{
+
+ if (!NT){
+ if (MySQLSignal()){Image3->Visible = false; Image2->Visible = true;
+ return (Image2->Picture->Icon->Handle); }
+ else {Image2->Visible = false; Image3->Visible = true;
+ return (Image3->Picture->Icon->Handle); }
+ }
+ else {
+ if (TheServiceStatus()){Image3->Visible = false; Image2->Visible = true;
+ return (Image2->Picture->Icon->Handle); }
+
+ else if (MySQLSignal()){Image3->Visible = false; Image2->Visible = true;
+ return (Image2->Picture->Icon->Handle); }
+ else {Image2->Visible = false; Image3->Visible = true;
+ return (Image3->Picture->Icon->Handle); }
+ }
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::ToggleState(void)
+{
+
+ TrayMessage(NIM_MODIFY);
+ if (!NT){
+ if (MySQLSignal()){SSW9->Caption = "ShutDown the Server";
+ Image3->Visible = false; Image2->Visible = true; }
+ else {SSW9->Caption = "Start the Server";
+ Image2->Visible = false; Image3->Visible = true; }
+ }
+ else {
+ if (TheServiceStart()) {
+ Standa->Enabled = false;
+ if (TheServiceStatus()) {RService->Enabled = false;
+ StopS->Enabled = true;
+ StopS->Caption = "Stop the Service";
+ Image3->Visible = false;
+ Image2->Visible = true; }
+ else {RService->Enabled = true;
+ StopS->Enabled = true;
+ RService->Caption = "Remove the Service";
+ StopS->Caption = "Start the Service";
+ Image2->Visible = false;
+ Image3->Visible = true; }
+ }
+ else {
+ Standa->Enabled = true;
+ StopS->Enabled = false;
+ if (MySQLSignal()) {
+ RService->Enabled = false;
+ Standa->Caption = "ShutDown the Server Standalone";
+ Image3->Visible = false;
+ Image2->Visible = true; }
+
+ else {
+ RService->Enabled = true;
+ RService->Caption = "Install the Service";
+ Standa->Caption = "Start the Server Standalone";
+ Image2->Visible = false;
+ Image3->Visible = true; }
+
+ }
+
+
+ }
+
+}
+//---------------------------------------------------------------------------
+PSTR __fastcall TForm1::TipText(void)
+{
+ char* status = StatusLine->SimpleText.c_str();
+ return status;
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::WMQueryEndSession(TWMQueryEndSession &msg)
+{
+
+
+ if (!NT) {
+
+ if (MySQLSignal()){
+ StatusLine->SimpleText = "Shutdown in progress.....";
+ Show(); Shutd(); msg.Result = 1; }
+ else {
+ StatusLine->SimpleText = "The Server already is down......";
+ Show(); msg.Result = 1; Close(); }
+ }
+ else {
+
+ Show();
+ if (!TheServiceStart()) { if (MySQLSignal()) Shutd(); }
+ msg.Result = 1;
+ }
+
+}
+
+//---------------------------------------------------------------------------
+LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi)
+{
+ HICON hIcon;
+
+ hIcon = (HICON)LoadImage(g_hinst, MAKEINTRESOURCE(lpdi->CtlID), IMAGE_ICON,
+ 16, 16, 0);
+ if (!hIcon)
+ return(false);
+
+ DrawIconEx(lpdi->hDC, lpdi->rcItem.left, lpdi->rcItem.top, hIcon,
+ 16, 16, 0, NULL, DI_NORMAL);
+
+ return(true);
+}
+//---------------------------------------------------------------------------
+AnsiString __fastcall TForm1::TheComputer()
+{
+ AnsiString theword;
+ DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
+ char szBuf[MAX_COMPUTERNAME_LENGTH + 1];
+ szBuf[0] = '\0';
+
+ GetComputerName(szBuf, &dwSize);
+ theword = (AnsiString) szBuf;
+ delete [] szBuf;
+ return theword;
+
+}
+//---------------------------------------------------------------------------
+AnsiString __fastcall TForm1::TheOS()
+{
+ AnsiString theword;
+ OSVERSIONINFO info;
+ info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&info);
+
+ switch (info.dwPlatformId)
+ {
+ case VER_PLATFORM_WIN32s:
+ NT = false;
+ theword = "Win32s detected";
+ break;
+ case VER_PLATFORM_WIN32_WINDOWS:
+ NT = false;
+ theword = "Win 95 or Win 98 detected";
+ break;
+ case VER_PLATFORM_WIN32_NT:
+ NT = true;
+ theword = "Windows NT detected";
+ break;
+ }
+ return theword;
+}
+///---------------------------------------------------------------------------
+AnsiString __fastcall TForm1::TheUser()
+{
+ AnsiString theword;
+ DWORD dwSize = 0;
+
+ GetUserName(NULL, &dwSize);
+
+ char *szBuf = new char[dwSize];
+ szBuf[0] = '\0';
+
+ GetUserName(szBuf, &dwSize);
+ theword = (AnsiString) szBuf;
+ delete [] szBuf;
+ return theword;
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::TakeIP(void)
+{
+ WORD wVersionRequested;
+ WSADATA WSAData;
+ wVersionRequested = MAKEWORD(1,1);
+ WSAStartup(wVersionRequested,&WSAData);
+
+ hostent *P;
+ char s[128];
+ in_addr in;
+ char *P2;
+ gethostname(s, 128);
+ P = gethostbyname(s);
+
+ Memo2->Lines->Clear();
+ Memo2->Lines->Add((AnsiString)P->h_name);
+ mainroot = P->h_name;
+ in.S_un.S_un_b.s_b1 = P->h_addr_list[0][0];
+ in.S_un.S_un_b.s_b2 = P->h_addr_list[0][1];
+ in.S_un.S_un_b.s_b3 = P->h_addr_list[0][2];
+ in.S_un.S_un_b.s_b4 = P->h_addr_list[0][3];
+ P2 = inet_ntoa(in);
+ vip = P2;
+ mainroot += " ( " + (AnsiString)P2 + " )";
+ Memo2->Lines->Add(P2);
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetmemStatus(void)
+{
+ MEMORYSTATUS ms;
+ ms.dwLength = sizeof(MEMORYSTATUS);
+ GlobalMemoryStatus(&ms);
+
+ Edit2->Text = AnsiString((double)ms.dwTotalPhys / 1024000.0) + " MB RAM";
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TForm1::ShowHelp(void)
+{
+ Application->MessageBox("Usage: WinMySQLadmin.EXE [OPTIONS]\n\n-w Run the tool without start the Server.\n-h Shows this message and exit ", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::ContinueLoad(void)
+{
+ OS->Text = TheOS();
+ Localhost->Text = TheComputer();
+ Localuser->Text = TheUser();
+ GetmemStatus();
+ ClearBox();
+ TakeIP();
+ MyODBC();
+
+
+ IsMyIniUp();
+
+ if (!NT) { WinNT->Enabled = false; NtVer->Enabled = false; Win9->Enabled = true; }
+ else { WinNT->Enabled = true; Win9->Enabled = false; }
+
+ if (i_start)
+ {
+ // NT never is started from the prompt
+ if ((!NT) && (!MySQLSignal())) mysqldstart();
+ {
+ TrayMessage(NIM_MODIFY);
+ SeekErrFile();
+ }
+ }
+ Hide();
+
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TForm1::MyODBC(void)
+{
+
+ TRegistry *Registry = new TRegistry();
+ Memo3->Lines->Clear();
+
+ try
+ {
+ Registry->RootKey = HKEY_LOCAL_MACHINE;
+ // the basic data of myodbc
+ if (Registry->OpenKey("Software\\ODBC\\ODBCINST.INI\\MySQL", false))
+ {
+ Memo3->Lines->Add("Driver Version\t" + Registry->ReadString("DriverODBCVer"));
+ Memo3->Lines->Add("Driver\t\t" + Registry->ReadString("Driver"));
+ Memo3->Lines->Add("API Level\t\t" + Registry->ReadString("APILevel"));
+ Memo3->Lines->Add("Setup\t\t" + Registry->ReadString("Setup"));
+ Memo3->Lines->Add("SQL Level\t" + Registry->ReadString("SQLLevel"));
+ }
+ else
+ Memo3->Lines->Add("Not Found");
+
+ }
+ catch (...)
+ {
+ delete Registry;
+ }
+ Memo3->Enabled = false;
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::IsMyIniUp(void)
+{
+ // we see if the my.ini is Up
+ AnsiString asFileName = FileSearch("my.ini", TheWinDir());
+ if (asFileName.IsEmpty())
+ {
+ IsForce = true;
+ i_start = false;
+ QuickSearch();
+ }
+ else
+ {
+ Memo1->Enabled = true;
+ Memo1->Lines->Clear();
+ FillMyIni();
+ GetBaseDir();
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::QuickSearch(void)
+{
+ AnsiString asFileName = FileSearch("mysql.exe", "c:/mysql/bin");
+ if (!asFileName.IsEmpty())
+ BaseDir->Text = "c:/mysql";
+}
+//---------------------------------------------------------------------------
+AnsiString __fastcall TForm1::TheWinDir()
+{
+ AnsiString WinDir;
+ UINT BufferSize = GetWindowsDirectory(NULL,0);
+ WinDir.SetLength(BufferSize+1);
+ GetWindowsDirectory(WinDir.c_str(),BufferSize);
+ char* dirw = WinDir.c_str();
+ return dirw ;
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::FillMyIni(void)
+{
+ Memo1->Lines->LoadFromFile(TheWinDir() + "\\my.ini");
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetBaseDir(void)
+{
+
+ char drive[_MAX_DRIVE];
+ char dir[_MAX_DIR];
+ char file[_MAX_FNAME];
+ char ext[_MAX_EXT];
+
+
+ TIniFile *pIniFile = new
+ TIniFile(TheWinDir() + "\\my.ini");
+
+ BaseDir->Text = pIniFile->ReadString("mysqld","basedir","") ;
+ AnsiString lx = pIniFile->ReadString("WinMySQLadmin","Server","") ;
+ _splitpath((lx).c_str(),drive,dir,file,ext);
+ AnsiString lw = (AnsiString) file + ext;
+
+ if ( lw == "mysqld-shareware.exe") {ShareVer->Checked = true;}
+ if ( lw == "mysqld.exe") {MysqldVer->Checked = true;}
+ if ( lw == "mysqld-opt.exe") {OptVer->Checked = true;}
+ if ( lw == "mysqld-nt.exe") {NtVer->Checked = true;}
+
+ delete pIniFile;
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::Showme1Click(TObject *Sender)
+{
+ if(Showme1->Caption == "Show me") { TrayMessage(NIM_DELETE);
+ Showme1->Caption = "Hide me"; Show(); }
+ else { TrayMessage(NIM_ADD); TrayMessage(NIM_MODIFY);
+ Showme1->Caption = "Show me"; Hide(); }
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::MySQLSignal()
+{
+ HANDLE hEventShutdown;
+ hEventShutdown=OpenEvent(EVENT_MODIFY_STATE, 0, "MySqlShutdown");
+
+ if(hEventShutdown)
+ {
+ CloseHandle(hEventShutdown);
+ return true;
+ }
+ else
+ {
+ CloseHandle(hEventShutdown);
+ return false;
+ }
+
+}
+
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::mysqldstart()
+{
+ memset(&pi, 0, sizeof(pi));
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ si.dwFlags |= STARTF_USESHOWWINDOW;
+ si.wShowWindow |= SW_SHOWNORMAL;
+
+
+ TIniFile *pIniFile = new
+ TIniFile(TheWinDir() + "\\my.ini");
+
+ if (NT)
+ vpath = pIniFile->ReadString("WinMySQLadmin","Server","") + " --standalone\0" ;
+ else
+ vpath = pIniFile->ReadString("WinMySQLadmin","Server","") + "\0" ;
+
+ if ( ! CreateProcess(0,vpath.c_str(), 0, 0, 0, 0, 0, 0, &si,&pi))
+ {
+ TrayMessage(NIM_MODIFY);
+ return false;
+ }
+ else
+ {
+ TrayMessage(NIM_MODIFY);
+ return true;
+
+ }
+
+}
+
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::SeekErrFile()
+{
+ Memo4->Enabled = true;
+ Memo4->Lines->Clear();
+ AnsiString asFileName = FileSearch("mysql.err", BaseDir->Text + "/data");
+ if (!asFileName.IsEmpty())
+ {
+ FName = BaseDir->Text + "/data/mysql.err";
+ ifstream in((FName).c_str());
+ in.seekg(0, ios::end);
+ string s, line;
+ deque<string> v;
+ deque<string> lines;
+ streampos sp = in.tellg();
+ if (sp <= 1000)
+ in.seekg(0, ios::beg);
+ else
+ {
+ in.seekg(0, ios::beg);
+ in.seekg((sp - 1000));
+ }
+
+ do {
+ lines.push_back(line);
+ }while (getline(in, line));
+
+
+ if( lines.size() <= 15)
+ {
+ deque<string>::reverse_iterator r;
+ for(r = lines.rbegin(); r != lines.rend() ; r++)
+ {
+ if (ereport)
+ Memo5->Lines->Add((*r).c_str());
+ Memo4->Lines->Add((*r).c_str());
+
+ }
+ }
+ else
+ {
+ int k = 0;
+ deque<string>::reverse_iterator r;
+ for(r = lines.rbegin(); r != lines.rend(); r++)
+ {
+ if (ereport)
+ Memo5->Lines->Add((*r).c_str());
+ Memo4->Lines->Add((*r).c_str());
+ if (++k >= 15) { break;}
+ }
+ }
+ in.close();
+ return true;
+ }
+ else
+ return false;
+
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TForm1::Timer1Timer(TObject *Sender)
+{
+ Showme1->Caption = "Show me";
+ TrayMessage(NIM_ADD);
+ TrayMessage(NIM_MODIFY);
+ Hide();
+ if (IsForce) {Form2->Show();}
+ Timer1->Enabled = false;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetServerFile()
+{
+
+ AnsiString FileName;
+
+ if(!NT) {
+ FileName = FileSearch("mysqld-opt.exe", ExtractFilePath(Application->ExeName));
+ if (FileName.IsEmpty()) FileName = FileSearch("mysqld.exe", ExtractFilePath(Application->ExeName));
+ if (FileName.IsEmpty()) FileName = FileSearch("mysqld-shareware.exe", ExtractFilePath(Application->ExeName));
+
+ if (!FileName.IsEmpty()){
+ if ( FileName == "mysqld-opt.exe") {OptVer->Checked = true;}
+ if ( FileName == "mysqld.exe") {MysqldVer->Checked= true;}
+ if ( FileName == "mysqld-shareware.exe") {ShareVer->Checked= true;} }
+
+ }
+ else {
+
+ FileName = FileSearch("mysqld-nt.exe", ExtractFilePath(Application->ExeName));
+ if (FileName.IsEmpty()) FileName = FileSearch("mysqld.exe", ExtractFilePath(Application->ExeName));
+ if (FileName.IsEmpty()) FileName = FileSearch("mysqld-shareware.exe", ExtractFilePath(Application->ExeName));
+
+ if (!FileName.IsEmpty()) {
+ if ( FileName == "mysqld-nt.exe") {NtVer->Checked = true;}
+ if ( FileName == "mysqld.exe") {MysqldVer->Checked= true;}
+ if ( FileName == "mysqld-shareware.exe") {ShareVer->Checked= true;} }
+
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::CreateMyIniFile(void)
+{
+ char szFileName[6];
+ int iFileHandle;
+ AnsiString jk;
+
+ Memo1->Enabled = true;
+ Memo1->Lines->Clear();
+ strcpy(szFileName,"\\my.ini");
+ iFileHandle = FileCreate(TheWinDir() + szFileName );
+
+ jk = "#This File was made using the WinMySQLadmin 1.0 Tool\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#" + Now() + "\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#Uncomment or Add only the keys that you know how works.\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#Read the MySQL Manual for instructions\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+
+ jk = "[mysqld]\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "basedir=" + TheDir() + "\n";
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#bind-address=" + vip + "\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#datadir=" + TheDir() + "/data\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#language=" + TheDir() + "/share/your language directory\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#delay-key-write-for-all-tables\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#log-long-format\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#slow query log=#\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#tmpdir=#\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#ansi\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#new\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#port=3306\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#safe\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#skip-name-resolve\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#skip-networking\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#skip-new\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#skip-host-cache\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable = key_buffer=16M\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable = max_allowed_packet=1M\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable = thread_stack=128K\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable = flush_time=1800\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "[mysqldump]\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#quick\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable = max_allowed_packet=16M\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "[mysql]\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#no-auto-rehash\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "[isamchk]\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "#set-variable= key=16M\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "[WinMySQLadmin]\n\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+
+ if (ShareVer->Checked) { jk = "Server=" + TheDir() + "/bin/mysqld-shareware.exe\n\n";}
+ if (MysqldVer->Checked) {jk = "Server=" + TheDir() + "/bin/mysqld.exe\n\n";}
+ if (OptVer->Checked) {jk = "Server=" + TheDir() + "/bin/mysqld-opt.exe\n\n";}
+ if (NtVer->Checked) {jk = "Server=" + TheDir() + "/bin/mysqld-nt.exe\n\n";}
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "user=" + Form2->Edit1->Text + "\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ jk = "password=" + Form2->Edit2->Text + "\n" ;
+ FileWrite(iFileHandle, (jk).c_str(), (jk).Length());
+
+ FileClose(iFileHandle);
+ FillMyIni();
+
+}
+
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::CreatingShortCut()
+{
+ // Where is The Start Menu in this Machine ?
+ LPITEMIDLIST pidl;
+ LPMALLOC pShellMalloc;
+ char szDir[MAX_PATH + 16];
+ AnsiString file;
+ AnsiString jk = "\\WinMySQLadmin.lnk" ;
+
+ if(SUCCEEDED(SHGetMalloc(&pShellMalloc)))
+ {
+ if(SUCCEEDED(SHGetSpecialFolderLocation(NULL,
+ CSIDL_STARTUP, &pidl)))
+ {
+ if(!SHGetPathFromIDList(pidl, szDir))
+ {
+ pShellMalloc->Release();
+ pShellMalloc->Free(pidl);
+ return false;
+ }
+
+ pShellMalloc->Free(pidl);
+ }
+
+ pShellMalloc->Release();
+ StrCat(szDir, jk.c_str());
+ }
+
+ // the create
+
+ IShellLink* pLink;
+ IPersistFile* pPersistFile;
+
+ if(SUCCEEDED(CoInitialize(NULL)))
+ {
+ if(SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IShellLink, (void **) &pLink)))
+ {
+
+ pLink->SetPath((ExtractFilePath(Application->ExeName) + "WinMySQLadmin.exe").c_str());
+ pLink->SetDescription("WinMySQLadmin Tool");
+ pLink->SetShowCmd(SW_SHOW);
+
+ if(SUCCEEDED(pLink->QueryInterface(IID_IPersistFile,
+ (void **)&pPersistFile)))
+ {
+
+ WideString strShortCutLocation(szDir);
+ pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE);
+ pPersistFile->Release();
+ }
+ pLink->Release();
+ }
+
+ CoUninitialize();
+ }
+
+
+ return true;
+}
+
+//---------------------------------------------------------------------------
+AnsiString __fastcall TForm1::TheDir()
+{
+ AnsiString buffer;
+ char s[_MAX_PATH + 1];
+
+ StrCopy(s, ( BaseDir->Text).c_str()) ;
+
+ for (int i = 0; s[i] != NULL; i++)
+ if (s[i] != '\\')
+ buffer += s[i];
+ else
+ buffer += "/";
+
+ return buffer;
+
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
+{
+ Application->HelpCommand(HELP_FINDER,0);
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Timer2Timer(TObject *Sender)
+{
+ ToggleState();
+
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServiceStart()
+{
+ bool thatok;
+ char *SERVICE_NAME = "MySql";
+ SC_HANDLE myService, scm;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS | GENERIC_WRITE);
+ if (scm)
+ {
+ myService = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (myService)
+ thatok = true;
+ else
+ thatok = false;
+ }
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ return thatok;
+}
+
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServicePause()
+{
+
+ bool thatok;
+ char *SERVICE_NAME = "MySql";
+ SC_HANDLE myService, scm;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+
+ if (scm)
+ {
+ myService = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (myService)
+ {
+ // stop the service
+ if (IsConnect)
+ {
+ mysql_kill(MySQL,mysql_thread_id(MySQL));
+ StatusLine->SimpleText = "";
+ q = 0;
+ }
+
+
+ SERVICE_STATUS ss;
+ thatok = ControlService(myService,
+ SERVICE_CONTROL_STOP,
+ &ss);
+
+ }
+ else
+ thatok = false;
+ }
+ else
+ thatok = false;
+
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ return thatok;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServiceResume()
+{
+
+ bool thatok;
+ char *SERVICE_NAME = "MySql";
+ SC_HANDLE myService, scm;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+
+ if (scm)
+ {
+ myService = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (myService)
+ {
+ // start the service
+
+ thatok = StartService(myService, 0, NULL);
+ }
+ else
+ thatok = false;
+ }
+ else
+ thatok = false;
+
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ return thatok;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServiceStatus()
+{
+ bool thatok;
+ bool k;
+ char *SERVICE_NAME = "MySql";
+ SC_HANDLE myService, scm;
+ SERVICE_STATUS ss;
+ DWORD dwState = 0xFFFFFFFF;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+
+ if (scm)
+ {
+ myService = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (myService)
+ {
+ memset(&ss, 0, sizeof(ss));
+ k = QueryServiceStatus(myService,&ss);
+ if (k)
+ {
+ dwState = ss.dwCurrentState;
+ if (dwState == SERVICE_RUNNING)
+ thatok = true;
+ }
+ else
+ thatok = false;
+ }
+ else
+ thatok = false;
+ }
+ else
+ thatok = false;
+
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ return thatok;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServiceCreate()
+
+{
+ bool thatok;
+ char *SERVICE_NAME = "MySql";
+ char *szFullPath = vpath.c_str();
+ SC_HANDLE myService, scm;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+
+ if (scm)
+ { myService = CreateService(
+ scm,
+ SERVICE_NAME,
+ SERVICE_NAME,
+ SERVICE_ALL_ACCESS,
+ SERVICE_WIN32_OWN_PROCESS,
+ SERVICE_AUTO_START ,
+ SERVICE_ERROR_NORMAL,
+ szFullPath,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+
+ if (myService)
+ thatok = true;
+ else
+ thatok = false;
+
+ }
+
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ return thatok;
+
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Swin9Click(TObject *Sender)
+{
+ if(Application->MessageBox("Shutdown this tool", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ Close();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SSW9Click(TObject *Sender)
+{
+ if (MySQLSignal())
+ {
+ if(Application->MessageBox("Shutdown the MySQL Server ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+
+ if (Shutd())
+ {
+ IsConnect = false;
+ IsVariables = false;
+ IsProcess = false;
+ IsDatabases = false;
+ ya = false;
+ ClearBox();
+ Sleep(500);
+ TrayMessage(NIM_MODIFY);
+
+ }
+ else
+ Application->MessageBox("Fails to Shutdown the Server", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+ else
+ {
+ if(Application->MessageBox("Start the MySQL Server ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (mysqldstart())
+ {
+ TrayMessage(NIM_MODIFY);
+ ya = true;
+ }
+ else
+ Application->MessageBox("Fails to Start the Server", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+
+ }
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::ShutDownBoth1Click(TObject *Sender)
+{
+ if (MySQLSignal())
+ {
+ if(Application->MessageBox("Shutdown the MySQL Server and this tool ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+
+ if (Shutd())
+ Close();
+ else
+ {
+ Application->MessageBox("Fails to Shutdown the Server", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+
+ }
+ }
+ }
+ else
+ if(Application->MessageBox("Shutdown this tool ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ Close();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::ShutDownthisTool1Click(TObject *Sender)
+{
+ if(Application->MessageBox("Shutdown this tool ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ Close();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::StopSClick(TObject *Sender)
+{
+ AnsiString theWarning;
+ theWarning = "Are you sure to stop the Service ?\n\nAll the connections will be loss !" ;
+ if (TheServiceStatus())
+ {
+ if(Application->MessageBox(theWarning.c_str(), "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (TheServicePause())
+ {
+ TrayMessage(NIM_MODIFY);
+ IsConnect = false;
+ IsVariables = false;
+ IsProcess = false;
+ IsDatabases = false;
+ ya = false;
+ ClearBox();
+
+ }
+ else
+ Application->MessageBox("Fails to stop the Service", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+
+ }
+ }
+ else
+ {
+ if(Application->MessageBox("Start the Service Manager for the MySQL Server ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (TheServiceResume())
+ {
+ ya = true;
+ TrayMessage(NIM_MODIFY);
+ }
+ else
+ Application->MessageBox("Fails to start the Service", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::RServiceClick(TObject *Sender)
+{
+ if (TheServiceStart())
+ {
+ if(Application->MessageBox("Remove the MySQL Server service ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (!TheServiceRemove())
+ Application->MessageBox("Fails to Remove The MySQL Server Service", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+ else
+ {
+ if(Application->MessageBox("Install the MySQL Server service ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (!TheServerPath())
+ Application->MessageBox("Please create first the my.ini setup", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ else
+ {
+ if (!TheServiceCreate())
+ Application->MessageBox("Fails to Install The MySQL Server Service", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+
+ }
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::StandaClick(TObject *Sender)
+{
+ if (MySQLSignal())
+ {
+ if(Application->MessageBox("Shutdown the MySQL Server ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (Shutd())
+ {
+ IsConnect = false;
+ IsVariables = false;
+ IsProcess = false;
+ IsDatabases = false;
+ ya = false;
+ ClearBox();
+ Sleep(500);
+ TrayMessage(NIM_MODIFY);
+
+ }
+ else
+ Application->MessageBox("Fails to Shutdown the Server", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+ else
+ {
+ if(Application->MessageBox("Start the MySQL Server ", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (mysqldstart())
+ {
+ StatusLine->SimpleText = "";
+ TrayMessage(NIM_MODIFY);
+
+ }
+ else
+ Application->MessageBox("Fails to Start the Server", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::Shutd()
+{
+ // from Irena
+ HANDLE hEventShutdown;
+ hEventShutdown=OpenEvent(EVENT_MODIFY_STATE, 0, "MySqlShutdown");
+
+ if (IsConnect)
+ {
+ mysql_kill(MySQL,mysql_thread_id(MySQL));
+ mysql_shutdown(MySQL);
+ StatusLine->SimpleText = "";
+
+ }
+
+ q = 0;
+
+
+ if(hEventShutdown)
+ {
+ SetEvent(hEventShutdown);
+ CloseHandle(hEventShutdown);
+ TrayMessage(NIM_MODIFY);
+ IsConnect = false;
+ return true;
+ }
+ else
+ {
+ TrayMessage(NIM_MODIFY);
+ return false;
+ }
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::ClearBox(void)
+{
+
+ st22->Text = "";
+ st23->Text = "";
+ st24->Text = "";
+ st25->Text = "";
+ st26->Text = "";
+ st27->Text = "";
+ st28->Text = "";
+ st29->Text = "";
+ Edit3->Text = "";
+ Edit4->Text = "";
+ Edit5->Text = "";
+ Edit6->Text = "";
+
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServiceRemove()
+{
+ bool thatok;
+ char *SERVICE_NAME = "MySql";
+ SC_HANDLE myService, scm;
+ scm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+ if (scm)
+ {
+ myService = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (myService)
+ {
+ if(DeleteService(myService))
+ {
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ thatok = true;
+ }
+ else
+ {
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ thatok = false;
+ }
+
+ }
+ else
+ {
+ CloseServiceHandle(myService);
+ CloseServiceHandle(scm);
+ thatok = false;
+ }
+ }
+ else
+ {
+ thatok = false;
+ CloseServiceHandle(scm);
+ }
+
+ return thatok;
+
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::TheServerPath()
+{
+
+ TIniFile *pIniFile = new
+ TIniFile(TheWinDir() + "\\my.ini");
+
+ vpath = pIniFile->ReadString("WinMySQLadmin","Server","") ;
+ delete pIniFile;
+ if (vpath.IsEmpty())
+ return false;
+ else
+ return true;
+
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button5Click(TObject *Sender)
+{
+ if (!SeekErrFile())
+ Application->MessageBox("Fails to find mysql.err", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::IsMySQLInit(void)
+{
+ AnsiString theCommand;
+ char *host = NULL,*password=0,*user=0 ;
+ TIniFile *pIniFile = new
+ TIniFile(TheWinDir() + "\\my.ini");
+
+ AnsiString MyUser = pIniFile->ReadString("WinMySQLadmin","user","") ;
+ AnsiString MyPass = pIniFile->ReadString("WinMySQLadmin","password","") ;
+
+ delete pIniFile;
+
+
+ if (!MyUser.IsEmpty() && MyUser.Length() && !MyPass.IsEmpty() && MyPass.Length())
+ {
+ if (!IsConnect)
+ {
+
+ MySQL = mysql_init(MySQL);
+ if (mysql_real_connect(MySQL, "localhost",(MyUser).c_str(), (MyPass).c_str() , 0, 0, NULL, 0))
+ IsConnect = true;
+ else
+ {
+ if(mysql_real_connect(MySQL,host,user,password , 0, 0, NULL, 0))
+ {
+ IsConnect = true;
+ theCommand = "GRANT ALL PRIVILEGES ON *.* TO ";
+ theCommand += "'" + MyUser + "' @localhost IDENTIFIED BY ";
+ theCommand += "'" + MyPass + "' with GRANT OPTION";
+ char* los = theCommand.c_str();
+ if(!mysql_query(MySQL, los ))
+ StatusLine->SimpleText = " ";
+ }
+
+ }
+
+ }
+
+ }
+ else
+ {
+ if (!IsConnect)
+ {
+ MySQL = mysql_init(MySQL);
+ if(mysql_real_connect(MySQL,host,user,password , 0, 0, NULL, 0))
+ IsConnect = true;
+ }
+ }
+}
+
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Timer3Timer(TObject *Sender)
+{
+ if ((NT) && TheServiceStatus()) {IsMySQLInit(); }
+
+ if ((NT) && !TheServiceStatus() && MySQLSignal()) {IsMySQLInit(); }
+
+ if (!(NT) && MySQLSignal()) {IsMySQLInit(); }
+
+ if (IsConnect)
+ {
+ GetServerStatus();
+ if (!IsMySQLNode)
+ GetMainRoot();
+ Extended->Enabled = true;
+ if (!IsProcess && !GetProcess())
+ StatusLine->SimpleText = "";
+ if (!IsVariables && !GetVariables())
+ StatusLine->SimpleText = "";
+ Timer3->Interval = 10000;
+ }
+ else
+ Extended->Enabled = false;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetServerStatus(void)
+{
+
+ GetExtendedStatus();
+ Edit3->Text = mysql_get_server_info(MySQL);
+ Edit4->Text = mysql_get_host_info(MySQL);
+ Edit5->Text = mysql_get_client_info();
+ Edit6->Text = mysql_get_proto_info(MySQL);
+
+
+}
+
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::GetProcess()
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ int k = 0;
+ int therow = 1;
+ new_line=1;
+
+ StringGrid2->RowCount= 2;
+
+ if (!(res=mysql_list_processes(MySQL)))
+ {
+ return false;
+ }
+
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+ StringGrid2->Cells[0][0] = "PID";
+ StringGrid2->Cells[1][0] = "User";
+ StringGrid2->Cells[2][0] = "Host";
+ StringGrid2->Cells[3][0] = "DB";
+ StringGrid2->Cells[4][0] = "Command";
+ StringGrid2->Cells[5][0] = "Time";
+ StringGrid2->Cells[6][0] = "State";
+ StringGrid2->Cells[7][0] = "Info";
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+
+ if (k <= 6 )
+ {
+ StringGrid2->Cells[k][therow] = row[i];
+ k++;
+ }
+ else
+ {
+
+ StringGrid2->Cells[(k)][therow] = row[i];
+ k = 0;
+ therow++ ;
+ StringGrid2->RowCount++;
+
+ }
+
+ }
+
+ }
+
+ StringGrid2->RowCount--;
+ mysql_free_result(res);
+ StringGrid5->RowCount--;
+ IsProcess = true;
+ return true;
+
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::GetVariables()
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ int k = 1;
+ new_line=1;
+ bool left = true;
+ AnsiString report;
+ StringGrid1->RowCount = 2;
+ if (mysql_query(MySQL,"show variables") ||
+ !(res=mysql_store_result(MySQL)))
+ {
+ return false;
+ }
+
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+
+ StringGrid1->Cells[0][0] = "Variable Name";
+ StringGrid1->Cells[1][0] = "Value";
+
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+
+ if (left)
+ {
+ if (treport)
+ report = GetString(row[i]);
+ StringGrid1->Cells[0][k++] = row[i];
+ left = false;
+ }
+ else
+ {
+ if (treport)
+ Memo5->Lines->Add(report + row[i]);
+ StringGrid1->RowCount++;
+ StringGrid1->Cells[1][--k] = row[i];
+ k++;
+ left = true;
+ }
+
+ }
+
+ }
+
+ StringGrid1->RowCount--;
+ mysql_free_result(res);
+ IsVariables = true;
+ return true;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::nice_time(AnsiString buff)
+{
+
+ unsigned long sec;
+ unsigned long tmp;
+ AnsiString mytime;
+
+ sec = StrToInt(buff);
+
+ if (sec >= 3600L*24)
+ {
+ tmp=sec/(3600L*24);
+ sec-=3600L*24*tmp;
+
+ mytime = IntToStr(tmp);
+ if (tmp > 1)
+ mytime+= " days ";
+ else
+ mytime+= " day ";
+
+ }
+
+ if (sec >= 3600L)
+ {
+ tmp=sec/3600L;
+ sec-=3600L*tmp;
+ mytime += IntToStr(tmp);
+ if (tmp > 1)
+ mytime+= " hours ";
+ else
+ mytime+= " hour ";
+ }
+ if (sec >= 60)
+ {
+ tmp=sec/60;
+ sec-=60*tmp;
+ mytime += IntToStr(tmp);
+ mytime+= " min ";
+
+ }
+ mytime += IntToStr(sec);
+ mytime+= " sec ";
+ st29->Text = mytime ;
+ return true;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::Button11Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (GetVariables())
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button10Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (GetProcess())
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button6Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_HOSTS))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button7Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_LOG))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button8Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_TABLES))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button2Click(TObject *Sender)
+{
+ Memo1->Enabled = true;
+ Memo1->Lines->Clear();
+ AnsiString asFileName = FileSearch("my.ini", TheWinDir());
+ if (asFileName.IsEmpty())
+ Application->MessageBox("Don't found my.ini file on the Win Directory", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ else
+ FillMyIni();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button3Click(TObject *Sender)
+{
+ TIniFile *pIniFile = new
+ TIniFile(TheWinDir() + "\\my.ini");
+
+ if (!Memo1->GetTextLen())
+ Application->MessageBox("The Memo Box is Empty", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ else
+ {
+ if(Application->MessageBox("Are you sure to write the modifications into My.ini file.", "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ Memo1->Lines->SaveToFile(TheWinDir() + "\\my.ini");
+
+ Memo1->Lines->Clear();
+ Memo1->Enabled = true;
+ Memo1->Lines->Clear();
+ if (NtVer->Checked)
+ pIniFile->WriteString("WinMySQLadmin","Server",TheDir() + "/bin/mysqld-nt.exe");
+ if (MysqldVer->Checked == true)
+ pIniFile->WriteString("WinMySQLadmin","Server", TheDir() + "/bin/mysqld.exe");
+ if (ShareVer->Checked)
+ pIniFile->WriteString("WinMySQLadmin","Server",TheDir() + "/bin/mysqld-shareware.exe");
+ if (OptVer->Checked)
+ pIniFile->WriteString("WinMySQLadmin","Server", TheDir() + "/bin/mysqld-opt.exe");
+ FillMyIni();
+ Application->MessageBox("My.ini was modificated", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ }
+
+ }
+ delete pIniFile;
+ Memo1->Lines->Clear();
+ FillMyIni();
+
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button1Click(TObject *Sender)
+{
+ if(CreatingShortCut())
+ Application->MessageBox("The ShortCut on Start Menu was created", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+ else
+ Application->MessageBox("Fails the Operation of Create the ShortCut", "WinMySQLadmin 1.0", MB_OK |MB_ICONINFORMATION);
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
+{
+ BROWSEINFO info;
+ char szDir[MAX_PATH];
+ char szDisplayName[MAX_PATH];
+ LPITEMIDLIST pidl;
+ LPMALLOC pShellMalloc;
+
+
+ if(SHGetMalloc(&pShellMalloc) == NO_ERROR)
+ {
+
+ memset(&info, 0x00,sizeof(info));
+ info.hwndOwner = Handle;
+ info.pidlRoot = 0;
+ info.pszDisplayName = szDisplayName;
+ info.lpszTitle = "Search MySQL Base Directory";
+ info.ulFlags = BIF_RETURNONLYFSDIRS;
+ info.lpfn = 0;
+
+ pidl = SHBrowseForFolder(&info);
+
+ if(pidl)
+ {
+
+ if(SHGetPathFromIDList(pidl, szDir)) {BaseDir->Text = szDir; }
+
+ pShellMalloc->Free(pidl);
+ }
+ pShellMalloc->Release();
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Button4Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ Memo3->Lines->Add(mysql_stat(MySQL));
+ }
+}
+//---------------------------------------------------------------------------
+
+
+void __fastcall TForm1::SpeedButton3Click(TObject *Sender)
+{
+ if(Showme1->Caption == "Show me") { TrayMessage(NIM_DELETE);
+ Showme1->Caption = "Hide me"; Show(); }
+ else { TrayMessage(NIM_ADD); TrayMessage(NIM_MODIFY);
+ Showme1->Caption = "Show me"; Hide(); }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::ExtendedClick(TObject *Sender)
+{
+if (ya)
+ {
+ Extended->Caption = "Start Extended Server Status";
+ ya = false;
+ ClearBox();
+ }
+else
+ {
+ Extended->Caption = "Stop Extended Server Status";
+ ya = true;
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetServerOptions(void)
+{
+AnsiString FileName;
+FileName = FileSearch("mysqld-opt.exe", ExtractFilePath(Application->ExeName));
+if (FileName.IsEmpty()) {OptVer->Enabled = false; }
+
+FileName = FileSearch("mysqld-shareware.exe", ExtractFilePath(Application->ExeName));
+if (FileName.IsEmpty()) {ShareVer->Enabled = false; }
+
+FileName = FileSearch("mysqld.exe", ExtractFilePath(Application->ExeName));
+if (FileName.IsEmpty()) {MysqldVer->Enabled = false; }
+
+FileName = FileSearch("mysqld-nt.exe", ExtractFilePath(Application->ExeName));
+if (FileName.IsEmpty()) {NtVer->Enabled = false; }
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::GetReportServer(void)
+{
+
+ AnsiString strspace;
+ Memo5->Lines->Clear();
+ Memo5->Lines->Add("This Report was made using the WinMySQLadmin 1.0 Tool");
+ Memo5->Lines->Add("");
+ Memo5->Lines->Add(Now());
+ Memo5->Lines->Add("");
+
+ preport = true;
+ Memo5->Lines->Add("");
+ Memo5->Lines->Add("Server Status Values");
+ Memo5->Lines->Add("");
+ Memo5->Lines->Add(GetString("Server Info") + mysql_get_server_info(MySQL));
+ Memo5->Lines->Add(GetString("Host Info") + mysql_get_host_info(MySQL));
+ Memo5->Lines->Add(GetString("Client Info") + mysql_get_client_info());
+ Memo5->Lines->Add(GetString("Proto Info") + mysql_get_proto_info(MySQL));
+ GetExtendedStatus();
+ preport = false;
+ treport = true;
+ Memo5->Lines->Add("");
+ Memo5->Lines->Add("Variables Values");
+ Memo5->Lines->Add("");
+ GetVariables();
+ treport = false;
+ ereport = true;
+ Memo5->Lines->Add("");
+ Memo5->Lines->Add("Last Lines from Err File");
+ Memo5->Lines->Add("");
+ SeekErrFile();
+ ereport = false;
+
+}
+
+void __fastcall TForm1::SpeedButton4Click(TObject *Sender)
+{
+ if(IsConnect)
+ GetReportServer();
+ else
+ Application->MessageBox("The Server must be connected", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton5Click(TObject *Sender)
+{
+ AnsiString PathName;
+ SaveFileDialog->FileName = PathName;
+ if (SaveFileDialog->Execute() ){
+ PathName= SaveFileDialog->FileName;
+ Caption = ExtractFileName(PathName);
+ Memo5->Lines->SaveToFile(PathName);
+ Memo5->Modified = false;
+ }
+}
+//---------------------------------------------------------------------------
+String __fastcall TForm1::GetString(String k)
+{
+ int i = 35 - k.Length();
+ for (int y = 1 ; y <= i ;y++ )
+ k+= " ";
+ return k ;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::SpeedButton6Click(TObject *Sender)
+{
+ PrinterSetupDialog1->Execute();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton7Click(TObject *Sender)
+{
+ AnsiString PathName;
+ if (PrintDialog1->Execute()){
+ try {
+ Memo5->Print(PathName);
+ }
+ catch(...){
+ Printer()->EndDoc();
+ throw;
+ }
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton8Click(TObject *Sender)
+{
+ Memo5->CutToClipboard();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton9Click(TObject *Sender)
+{
+ Memo5->CopyToClipboard();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton10Click(TObject *Sender)
+{
+
+ Memo5->PasteFromClipboard();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton11Click(TObject *Sender)
+{
+ Memo5->ClearSelection();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::SpeedButton12Click(TObject *Sender)
+{
+ Memo5->SelectAll();
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::GetMainRoot()
+{
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ AnsiString command;
+
+ CleanGrid();
+ CleanGridI();
+ TakeIP();
+
+ MySQLNode = DBView->Items->Add(NULL, mainroot.UpperCase());
+ MySQLNode->ImageIndex = 0;
+
+ if (!(res=mysql_list_dbs(MySQL,"%"))) { return false; }
+ while ((row=mysql_fetch_row(res)) != 0) {
+ mysql_field_seek(res,0);
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+ MySQLDbs = DBView->Items->AddChild(MySQLNode, row[i]);
+ MySQLDbs->ImageIndex = 1;
+ MySQLDbs->SelectedIndex = 1;
+
+
+ }
+
+ }
+
+ mysql_free_result(res);
+ MySQLNode->Expanded = true;
+
+
+
+
+ IsMySQLNode = true;
+ return true;
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::DeleteDatabaseSClick(TObject *Sender)
+{
+ AnsiString alert;
+ if (IsConnect)
+ {
+ if(DBView->Selected == MySQLNode )
+ Application->MessageBox("Invalid database row selected.", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ else if ( DBView->Selected == NULL )
+ Application->MessageBox("Invalid database row selected.", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ else
+ {
+ if (DBView->Selected->Text.UpperCase() == "MYSQL")
+ Application->MessageBox("You cann't use this tool to drop the MySQL Database.", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ else {
+ alert = "Are you sure to drop the < ";
+ alert+= DBView->Selected->Text.c_str();
+ alert+= " > database.";
+ if(Application->MessageBox(alert.c_str(), "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ char* lese = DBView->Selected->Text.c_str();
+ if (!mysql_drop_db(MySQL, lese ))
+ {
+ DBView->Items->Clear();
+ GetMainRoot();
+ }
+ else
+ Application->MessageBox("Fails to drop the Database.", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ }
+ }
+ }
+ }
+ else
+ Application->MessageBox("The Server must be connected", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+}
+//---------------------------------------------------------------------------
+ bool __fastcall TForm1::IsDatabase(String Name)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ AnsiString command;
+
+
+ CleanTree();
+ command = "use ";
+ command+= Name.c_str();
+ char* das = command.c_str();
+ char* lis = Name.c_str();
+ if (mysql_query(MySQL, das ) ||
+ !(res=mysql_list_tables(MySQL,"%")))
+ return false;
+
+ MySQLNodeT = TableView->Items->Add(NULL, lis);
+ MySQLNodeT->ImageIndex = 1;
+ MySQLNodeT->SelectedIndex = 1;
+ while ((row=mysql_fetch_row(res)) != 0) {
+ mysql_field_seek(res,0);
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+
+ MySQLTbs = TableView->Items->AddChild(MySQLNodeT, row[i]);
+ MySQLTbs->ImageIndex = 2;
+ MySQLTbs->SelectedIndex = 2;
+ }
+ MySQLNodeT->Expanded = true;
+ }
+ mysql_free_result(res);
+ return true;
+}
+//---------------------------------------------------------------------------
+
+
+void __fastcall TForm1::DBViewClick(TObject *Sender)
+{
+
+ if (IsConnect)
+ {
+ if (DBView->Selected != MySQLNode && DBView->Selected != NULL )
+ {
+ IsDatabase(DBView->Selected->Text);
+
+ }
+ else
+ {
+ CleanTree();
+ }
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::TableViewClick(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (DBView->Selected != MySQLNodeT )
+ {
+ IsTable(TableView->Selected->Text);
+ IsIndex(TableView->Selected->Text);
+
+ }
+ else
+ {
+ CleanGrid();
+ CleanGridI();
+
+ }
+ }
+}
+//---------------------------------------------------------------------------
+ bool __fastcall TForm1::IsTable(String Name)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ int k = 0;
+ int therow = 1;
+ new_line=1;
+ AnsiString command;
+ AnsiString commandt;
+
+ CleanGrid();
+ CleanGridI();
+ command = "use ";
+ command+= DBView->Selected->Text.c_str();
+ char* las = command.c_str();
+
+ commandt = "desc ";
+ commandt+= Name.c_str();
+ char* les = commandt.c_str();
+
+ if (mysql_query(MySQL, las ))
+ return false;
+
+ if (mysql_query(MySQL, les ) ||
+ !(res=mysql_store_result(MySQL)))
+ return false ;
+
+ StringGrid4->Cells[0][0] = "Field";
+ StringGrid4->Cells[1][0] = "Type";
+ StringGrid4->Cells[2][0] = "Null";
+ StringGrid4->Cells[3][0] = "Key";
+ StringGrid4->Cells[4][0] = "Default";
+ StringGrid4->Cells[5][0] = "Extra";
+ StringGrid4->Cells[6][0] = "Previleges";
+
+
+ int thecounter;
+ String u = GetNumberServer();
+ if ( u == "3.22")
+ {
+ StringGrid3->ColCount = 7;
+ thecounter = 4;
+ }
+ else
+ thecounter = 5;
+
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+ if (k <= thecounter )
+ {
+ StringGrid4->Cells[k][therow] = row[i];
+ k++;
+ }
+ else
+ {
+ StringGrid4->Cells[(k)][therow] = row[i];
+ k = 0;
+ therow++ ;
+ StringGrid4->RowCount++;
+ }
+ }
+
+ }
+ StringGrid4->RowCount--;
+ mysql_free_result(res);
+ return true;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::TableViewChange(TObject *Sender, TTreeNode *Node)
+{
+if (IsConnect)
+ {
+ if (DBView->Selected != MySQLNodeT )
+ {
+ IsTable(TableView->Selected->Text);
+ IsIndex(TableView->Selected->Text);
+
+ }
+ else
+ {
+ CleanGrid();
+ CleanGridI();
+
+ }
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::DBViewChange(TObject *Sender, TTreeNode *Node)
+{
+ if (IsConnect)
+ {
+ if (DBView->Selected != MySQLNode )
+ {
+ IsDatabase(DBView->Selected->Text);
+
+ }
+ else
+ {
+ CleanTree();
+ }
+ }
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::RefreshSClick(TObject *Sender)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ AnsiString command;
+
+ if (IsConnect)
+ {
+ IsMySQLNode = false;
+ CleanTree();
+ DBView->Items->Clear();
+
+ TakeIP();
+
+ MySQLNode = DBView->Items->Add(NULL, mainroot.UpperCase());
+ MySQLNode->ImageIndex = 0;
+
+ if (!(res=mysql_list_dbs(MySQL,"%"))) { /*do nothing;*/ }
+ while ((row=mysql_fetch_row(res)) != 0) {
+ mysql_field_seek(res,0);
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+ MySQLDbs = DBView->Items->AddChild(MySQLNode, row[i]);
+ MySQLDbs->ImageIndex = 1;
+ MySQLDbs->SelectedIndex = 1;
+
+ }
+
+ }
+
+ mysql_free_result(res);
+
+ IsMySQLNode = true;
+
+ MySQLNode->Expanded = true;
+
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::CreateDatabaseSClick(TObject *Sender)
+{
+
+ if (IsConnect)
+ {
+ dbfrm->Show();
+
+ }
+ else
+ ShowMessage("Precisa estar conectado");
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::CleanTree(void)
+{
+ StringGrid4->RowCount= 2;
+ StringGrid4->Cells[0][1] = "";
+ StringGrid4->Cells[1][1] = "";
+ StringGrid4->Cells[2][1] = "";
+ StringGrid4->Cells[3][1] = "";
+ StringGrid4->Cells[4][1] = "";
+ StringGrid4->Cells[5][1] = "";
+ TableView->Items->Clear();
+
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::CleanGrid(void)
+{
+ StringGrid4->RowCount= 2;
+ StringGrid4->Cells[0][1] = "";
+ StringGrid4->Cells[1][1] = "";
+ StringGrid4->Cells[2][1] = "";
+ StringGrid4->Cells[3][1] = "";
+ StringGrid4->Cells[4][1] = "";
+ StringGrid4->Cells[5][1] = "";
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::CreatingDB()
+{
+
+ if (mysql_create_db(MySQL, dbfrm->Edit1->Text.c_str()))
+ return true;
+ else
+ return false;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::OutRefresh(void)
+{
+ RefreshSClick(dbfrm->SpeedButton1);
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::FlushHosts1Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_HOSTS))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::FlushLogs1Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_LOG))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::FlushTables1Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_TABLES))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+ bool __fastcall TForm1::IsIndex(String Name)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ int k = 0;
+ int therow = 1;
+ new_line=1;
+ AnsiString command;
+ AnsiString commandt;
+ i = 0;
+ CleanGridI();
+ command = "use ";
+ command+= DBView->Selected->Text.c_str();
+ char* las = command.c_str();
+
+ commandt = "show index from ";
+ commandt+= Name.c_str();
+ char* les = commandt.c_str();
+
+ if (mysql_query(MySQL, las ))
+ return false;
+
+ if (mysql_query(MySQL, les ) ||
+ !(res=mysql_store_result(MySQL)))
+ return false ;
+
+ StringGrid3->RowCount= 2;
+ StringGrid3->Cells[0][0] = "Table";
+ StringGrid3->Cells[1][0] = "Non_unique";
+ StringGrid3->Cells[2][0] = "Key_name";
+ StringGrid3->Cells[3][0] = "Seq_in_index";
+ StringGrid3->Cells[4][0] = "Col_name";
+ StringGrid3->Cells[5][0] = "Collation";
+ StringGrid3->Cells[6][0] = "Card.";
+ StringGrid3->Cells[7][0] = "Sub_part";
+ StringGrid3->Cells[8][0] = "Packed";
+ StringGrid3->Cells[9][0] = "Comment";
+
+ int thecounter;
+ String u = GetNumberServer();
+
+ if ( u == "3.22")
+ {
+ StringGrid3->ColCount = 8;
+ thecounter = 6;
+ }
+ else
+ thecounter = 8;
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+ if (k <= thecounter )
+ {
+ StringGrid3->Cells[k][therow] = row[i];
+ k++;
+ }
+ else
+ {
+ StringGrid3->Cells[(k)][therow] = row[i];
+ k = 0;
+ therow++ ;
+ StringGrid3->RowCount++;
+ }
+ }
+
+ }
+ if (i)
+ StringGrid3->RowCount--;
+ mysql_free_result(res);
+ return true;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::CleanGridI(void)
+{
+ StringGrid3->RowCount= 2;
+ StringGrid3->Cells[0][1] = "";
+ StringGrid3->Cells[1][1] = "";
+ StringGrid3->Cells[2][1] = "";
+ StringGrid3->Cells[3][1] = "";
+ StringGrid3->Cells[4][1] = "";
+ StringGrid3->Cells[5][1] = "";
+ StringGrid3->Cells[6][1] = "";
+ StringGrid3->Cells[7][1] = "";
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::CreatingTable(String TheTable)
+{
+
+ if (!mysql_query(MySQL, TheTable.c_str()))
+ return true;
+ else
+ return false;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::GetExtendedStatus()
+{
+ if (!ya && !preport)
+ return true;
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ unsigned int i;
+ int k = 1;
+ new_line=1;
+ bool left = true;
+ bool open_tables = false;
+ bool open_files = false;
+ bool uptime = false;
+ bool running_threads = false;
+ bool open_streams = false;
+ bool slow_queries = false;
+ bool opened_tables = false;
+ bool questions = false;
+
+ AnsiString report;
+ if (yy)
+ StringGrid5->RowCount = 2;
+
+ if (mysql_query(MySQL,"show status") ||
+ !(res=mysql_store_result(MySQL)))
+ {
+ return false;
+ }
+
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+
+ StringGrid5->Cells[0][0] = "Variable Name";
+ StringGrid5->Cells[1][0] = "Value";
+
+
+ for (i=0 ; i < mysql_num_fields(res); i++)
+ {
+
+ if (left)
+ {
+ if (preport)
+ report = GetString(row[i]);
+ if ( (String) row[i] == "Open_tables")
+ open_tables = true;
+ else
+ open_tables = false;
+ if ( (String) row[i] == "Open_files")
+ open_files = true;
+ else
+ open_files = false;
+ if ((String) row[i] == "Uptime")
+ uptime = true;
+ else
+ uptime = false;
+
+ if ( (String) row[i] == "Opened_tables")
+ opened_tables = true;
+ else
+ opened_tables = false;
+
+ if ( (String) row[i] == "Threads_running" || (String) row[i] == "Running_threads")
+ running_threads = true;
+ else
+ running_threads = false;
+
+ if ( (String) row[i] == "Open_streams")
+ open_streams = true;
+ else
+ open_streams = false;
+
+ if ( (String) row[i] == "Slow_queries")
+ slow_queries = true;
+ else
+ slow_queries = false;
+
+ if ( (String) row[i] == "Questions")
+ questions = true;
+ else
+ questions = false;
+
+ if (yy)
+ StringGrid5->Cells[0][k++] = row[i];
+
+ left = false;
+ }
+ else
+ {
+ if (preport)
+ Memo5->Lines->Add(report + row[i]);
+ if (open_tables)
+ st22->Text = row[i];
+ if (open_files)
+ st23->Text = row[i];
+ if (uptime)
+ nice_time(row[i]);
+ if (running_threads)
+ st27->Text = row[i];
+ if (open_streams)
+ st24->Text = row[i];
+ if (slow_queries)
+ st28->Text = row[i];
+ if (opened_tables)
+ st25->Text = row[i];
+ if (questions){
+ q++;
+ st26->Text = StrToInt64(row[i]) - q; }
+
+ if (yy){
+ StringGrid5->RowCount++;
+ StringGrid5->Cells[1][--k] = row[i];
+ k++; }
+
+ left = true;
+ }
+
+ }
+
+ }
+
+
+ if (rinit)
+ StringGrid5->RowCount--;
+ mysql_free_result(res);
+ yy = false;
+ return true;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::SpeedButton13Click(TObject *Sender)
+{
+ yy = true;
+ // rinit = true;
+}
+//---------------------------------------------------------------------------
+String __fastcall TForm1::GetNumberServer()
+{
+ String TheVersion;
+
+ TheVersion = mysql_get_server_info(MySQL) ;
+ TheVersion.SetLength(4);
+ return TheVersion;
+
+
+}
+
+//---------------------------------------------------------------------------
+void __fastcall TForm1::KillProcess1Click(TObject *Sender)
+{
+
+ if (IsConnect)
+ KillPID();
+ else
+ Application->MessageBox("The Server must be connected", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::KillPID()
+{
+ String s = "Are you sure to kill the process PID no. ";
+ s+= StringGrid2->Cells[0][StringGrid2->Row];
+ s+= " of the USER ";
+ s+= StringGrid2->Cells[1][StringGrid2->Row];
+ unsigned long xx = mysql_thread_id(MySQL);
+ unsigned long yy = StrToInt(StringGrid2->Cells[0][StringGrid2->Row]);
+ if ( xx != yy)
+ {
+ if(Application->MessageBox(s.c_str(), "WinMySQLadmin 1.0", MB_YESNOCANCEL | MB_ICONQUESTION ) == IDYES)
+ {
+ if (!mysql_kill(MySQL,yy))
+ {
+ GetProcess();
+ return true;
+ }
+ }
+ }
+ else
+ {
+ Application->MessageBox("From here you can't kill the PID of this tool", "WinMySQLadmin 1.0", MB_OK | MB_ICONEXCLAMATION);
+ return true;
+ }
+ return true;
+}
+void __fastcall TForm1::FlushThreads1Click(TObject *Sender)
+{
+ if (IsConnect)
+ {
+ if (mysql_refresh(MySQL,REFRESH_THREADS))
+ StatusLine->SimpleText = "";
+ }
+}
+//---------------------------------------------------------------------------
+
diff --git a/VC++Files/winmysqladmin/main.h b/VC++Files/winmysqladmin/main.h
new file mode 100644
index 00000000000..dcb8ad60d7b
--- /dev/null
+++ b/VC++Files/winmysqladmin/main.h
@@ -0,0 +1,314 @@
+//---------------------------------------------------------------------------
+#ifndef mainH
+#define mainH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <Buttons.hpp>
+#include <ComCtrls.hpp>
+#include <ExtCtrls.hpp>
+#include <Graphics.hpp>
+#include <Grids.hpp>
+#include <ImgList.hpp>
+#include <Menus.hpp>
+#include <Dialogs.hpp>
+#include <string.h>
+
+#define MYWM_NOTIFY (WM_APP+100)
+#define IDC_MYICON 1006
+extern HINSTANCE g_hinst;
+LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi);
+//---------------------------------------------------------------------------
+class TForm1 : public TForm
+{
+__published: // IDE-managed Components
+ TStatusBar *StatusLine;
+ TPanel *Panel1;
+ TImage *Image1;
+ TLabel *Label1;
+ TLabel *Label2;
+ TLabel *Label3;
+ TLabel *Label8;
+ TImage *Image3;
+ TImage *Image2;
+ TPageControl *PageControl1;
+ TTabSheet *TabSheet1;
+ TSpeedButton *SpeedButton1;
+ TGroupBox *GroupBox1;
+ TLabel *Label4;
+ TLabel *Label5;
+ TLabel *Label6;
+ TLabel *Label14;
+ TLabel *Label17;
+ TEdit *Localhost;
+ TEdit *Localuser;
+ TEdit *OS;
+ TMemo *Memo2;
+ TEdit *Edit2;
+ TGroupBox *GroupBox2;
+ TMemo *Memo3;
+ TGroupBox *GroupBox3;
+ TLabel *Label13;
+ TLabel *Label15;
+ TLabel *Label16;
+ TLabel *Label7;
+ TLabel *Label47;
+ TLabel *Label44;
+ TLabel *Label42;
+ TLabel *Label45;
+ TEdit *Edit3;
+ TEdit *Edit4;
+ TEdit *Edit5;
+ TEdit *Edit6;
+ TEdit *st29;
+ TEdit *st27;
+ TEdit *st25;
+ TEdit *st28;
+ TTabSheet *TabSheet2;
+ TTabSheet *TabSheet3;
+ TLabel *Label18;
+ TSpeedButton *SpeedButton2;
+ TEdit *BaseDir;
+ TMemo *Memo1;
+ TRadioGroup *RadioGroup1;
+ TRadioButton *ShareVer;
+ TRadioButton *MysqldVer;
+ TRadioButton *OptVer;
+ TRadioButton *NtVer;
+ TButton *Button2;
+ TButton *Button3;
+ TButton *Button1;
+ TTabSheet *TabSheet4;
+ TMemo *Memo4;
+ TButton *Button5;
+ TTabSheet *TabSheet5;
+ TStringGrid *StringGrid1;
+ TButton *Button11;
+ TTabSheet *TabSheet6;
+ TStringGrid *StringGrid2;
+ TButton *Button10;
+ TPopupMenu *PopupMenu1;
+ TMenuItem *Showme1;
+ TMenuItem *N1;
+ TMenuItem *Win9;
+ TMenuItem *Swin9;
+ TMenuItem *N3;
+ TMenuItem *SSW9;
+ TMenuItem *N4;
+ TMenuItem *ShutDownBoth1;
+ TMenuItem *N2;
+ TMenuItem *WinNT;
+ TMenuItem *ShutDownthisTool1;
+ TMenuItem *N5;
+ TMenuItem *StopS;
+ TMenuItem *N6;
+ TMenuItem *RService;
+ TMenuItem *N7;
+ TMenuItem *Standa;
+ TImageList *ImageList1;
+ TTimer *Timer1;
+ TTimer *Timer2;
+ TTimer *Timer3;
+ TSpeedButton *SpeedButton3;
+ TSpeedButton *Extended;
+ TLabel *Label9;
+ TEdit *st26;
+ TLabel *Label43;
+ TEdit *st24;
+ TLabel *Label41;
+ TEdit *st23;
+ TLabel *Label40;
+ TEdit *st22;
+ TLabel *Label39;
+ TTabSheet *TabSheet8;
+ TSaveDialog *SaveFileDialog;
+ TPrinterSetupDialog *PrinterSetupDialog1;
+ TPrintDialog *PrintDialog1;
+ TRichEdit *Memo5;
+ TGroupBox *GroupBox5;
+ TSpeedButton *SpeedButton4;
+ TSpeedButton *SpeedButton5;
+ TSpeedButton *SpeedButton7;
+ TSpeedButton *SpeedButton6;
+ TGroupBox *GroupBox6;
+ TSpeedButton *SpeedButton8;
+ TSpeedButton *SpeedButton9;
+ TSpeedButton *SpeedButton10;
+ TSpeedButton *SpeedButton11;
+ TSpeedButton *SpeedButton12;
+ TTabSheet *TabSheet9;
+ TImageList *ImageList2;
+ TPopupMenu *PopupMenu2;
+ TMenuItem *CreateDatabaseS;
+ TMenuItem *DeleteDatabaseS;
+ TMenuItem *RefreshS;
+ TMenuItem *N8;
+ TMenuItem *N9;
+ TMenuItem *N10;
+ TGroupBox *GroupBox7;
+ TTreeView *DBView;
+ TGroupBox *GroupBox8;
+ TTreeView *TableView;
+ TGroupBox *GroupBox9;
+ TStringGrid *StringGrid4;
+ TMenuItem *FlushHosts1;
+ TMenuItem *N11;
+ TMenuItem *FlushLogs1;
+ TMenuItem *N12;
+ TMenuItem *FlushTables1;
+ TGroupBox *GroupBox10;
+ TStringGrid *StringGrid3;
+ TImage *Image5;
+ TStringGrid *StringGrid5;
+ TSpeedButton *SpeedButton13;
+ TPopupMenu *PopupMenu4;
+ TMenuItem *KillProcess1;
+ TMenuItem *N13;
+ TMenuItem *FlushThreads1;
+ void __fastcall FormCreate(TObject *Sender);
+ void __fastcall Showme1Click(TObject *Sender);
+ void __fastcall Timer1Timer(TObject *Sender);
+ void __fastcall SpeedButton1Click(TObject *Sender);
+ void __fastcall Timer2Timer(TObject *Sender);
+ void __fastcall Swin9Click(TObject *Sender);
+ void __fastcall SSW9Click(TObject *Sender);
+ void __fastcall ShutDownBoth1Click(TObject *Sender);
+ void __fastcall ShutDownthisTool1Click(TObject *Sender);
+ void __fastcall StopSClick(TObject *Sender);
+ void __fastcall RServiceClick(TObject *Sender);
+ void __fastcall StandaClick(TObject *Sender);
+ void __fastcall Button5Click(TObject *Sender);
+ void __fastcall Timer3Timer(TObject *Sender);
+ void __fastcall Button11Click(TObject *Sender);
+ void __fastcall Button10Click(TObject *Sender);
+ void __fastcall Button6Click(TObject *Sender);
+ void __fastcall Button7Click(TObject *Sender);
+ void __fastcall Button8Click(TObject *Sender);
+
+ void __fastcall Button2Click(TObject *Sender);
+ void __fastcall Button3Click(TObject *Sender);
+ void __fastcall Button1Click(TObject *Sender);
+ void __fastcall SpeedButton2Click(TObject *Sender);
+ void __fastcall Button4Click(TObject *Sender);
+ void __fastcall SpeedButton3Click(TObject *Sender);
+ void __fastcall ExtendedClick(TObject *Sender);
+ void __fastcall SpeedButton4Click(TObject *Sender);
+ void __fastcall SpeedButton5Click(TObject *Sender);
+ void __fastcall SpeedButton6Click(TObject *Sender);
+ void __fastcall SpeedButton7Click(TObject *Sender);
+ void __fastcall SpeedButton8Click(TObject *Sender);
+ void __fastcall SpeedButton9Click(TObject *Sender);
+ void __fastcall SpeedButton10Click(TObject *Sender);
+ void __fastcall SpeedButton11Click(TObject *Sender);
+ void __fastcall SpeedButton12Click(TObject *Sender);
+ void __fastcall DeleteDatabaseSClick(TObject *Sender);
+ void __fastcall DBViewClick(TObject *Sender);
+ void __fastcall TableViewClick(TObject *Sender);
+ void __fastcall TableViewChange(TObject *Sender, TTreeNode *Node);
+ void __fastcall DBViewChange(TObject *Sender, TTreeNode *Node);
+
+ void __fastcall RefreshSClick(TObject *Sender);
+ void __fastcall CreateDatabaseSClick(TObject *Sender);
+ void __fastcall FlushHosts1Click(TObject *Sender);
+ void __fastcall FlushLogs1Click(TObject *Sender);
+ void __fastcall FlushTables1Click(TObject *Sender);
+ void __fastcall SpeedButton13Click(TObject *Sender);
+ void __fastcall KillProcess1Click(TObject *Sender);
+ void __fastcall FlushThreads1Click(TObject *Sender);
+
+
+
+
+
+
+
+private: // User declarations
+ void __fastcall DrawItem(TMessage& Msg);
+ void __fastcall MyNotify(TMessage& Msg);
+ bool __fastcall TrayMessage(DWORD dwMessage);
+ HANDLE __fastcall IconHandle(void);
+ void __fastcall ToggleState(void);
+ PSTR __fastcall TipText(void);
+ void __fastcall WMQueryEndSession(TWMQueryEndSession &msg);
+ AnsiString __fastcall TheComputer();
+ AnsiString __fastcall TheUser();
+ AnsiString __fastcall TheOS();
+ void __fastcall TakeIP(void);
+ void __fastcall GetmemStatus(void);
+ void __fastcall ShowHelp(void);
+ void __fastcall ContinueLoad(void);
+ void __fastcall MyODBC(void);
+ void __fastcall IsMyIniUp(void);
+ void __fastcall QuickSearch(void);
+ AnsiString __fastcall TheWinDir();
+ void __fastcall FillMyIni(void);
+ void __fastcall GetBaseDir(void);
+ bool __fastcall MySQLSignal();
+ bool __fastcall mysqldstart();
+ bool __fastcall SeekErrFile();
+ AnsiString __fastcall TheDir();
+ bool __fastcall TheServiceStart();
+ bool __fastcall TheServicePause();
+ bool __fastcall TheServiceResume();
+ bool __fastcall TheServiceStatus();
+ bool __fastcall TheServiceCreate();
+ bool __fastcall TheServiceRemove();
+ bool __fastcall Shutd();
+ void __fastcall ClearBox(void);
+ bool __fastcall TheServerPath();
+ void __fastcall GetServerOptions(void);
+ void __fastcall GetReportServer(void);
+
+
+ TFileStream *MyFile;
+ String FName;
+
+ void __fastcall IsMySQLInit(void);
+ void __fastcall GetServerStatus(void);
+ bool __fastcall GetExtendedStatus();
+ bool __fastcall GetProcess();
+ bool __fastcall GetVariables();
+ bool __fastcall nice_time(AnsiString buff);
+ String __fastcall GetString(String k);
+ String __fastcall GetNumberServer();
+ // pointers for database screen
+ TTreeNode *MySQLNode, *MySQLDbs, *MySQLNodeT, *MySQLTbs;
+
+ bool __fastcall GetMainRoot();
+ bool __fastcall IsDatabase(String Name);
+ bool __fastcall IsTable(String Name);
+ void __fastcall CleanTree(void);
+ void __fastcall CleanGrid(void);
+ bool __fastcall IsIndex(String Name);
+ void __fastcall CleanGridI(void);
+ bool __fastcall KillPID();
+
+
+
+public: // User declarations
+ __fastcall TForm1(TComponent* Owner);
+ void __fastcall GetServerFile(void);
+ void __fastcall CreateMyIniFile(void);
+ bool __fastcall CreatingShortCut();
+ bool __fastcall CreatingDB();
+ void __fastcall OutRefresh(void);
+ bool __fastcall CreatingTable(String TheTable);
+
+ bool IsConnect ;
+
+
+
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ BEGIN_MESSAGE_MAP
+ MESSAGE_HANDLER(WM_DRAWITEM,TMessage,DrawItem)
+ MESSAGE_HANDLER(MYWM_NOTIFY,TMessage,MyNotify)
+ MESSAGE_HANDLER(WM_QUERYENDSESSION,TWMQueryEndSession,WMQueryEndSession)
+ END_MESSAGE_MAP(TForm)
+};
+//---------------------------------------------------------------------------
+extern PACKAGE TForm1 *Form1;
+//---------------------------------------------------------------------------
+#endif
diff --git a/VC++Files/winmysqladmin/mysql.h b/VC++Files/winmysqladmin/mysql.h
new file mode 100644
index 00000000000..e83babb8fa8
--- /dev/null
+++ b/VC++Files/winmysqladmin/mysql.h
@@ -0,0 +1,293 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA */
+
+/* defines for the libmysql library */
+
+#ifndef _mysql_h
+#define _mysql_h
+
+#ifndef MYSQL_SERVER
+#ifdef __cplusplus
+extern "C" {
+#endif
+#endif
+
+#ifndef _global_h /* If not standard header */
+#include <sys/types.h>
+typedef char my_bool;
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__WIN__)
+#define __WIN__
+#endif
+#if !defined(__WIN__)
+#define STDCALL
+#else
+#define STDCALL __stdcall
+#endif
+typedef char * gptr;
+
+#ifndef ST_USED_MEM_DEFINED
+#define ST_USED_MEM_DEFINED
+typedef struct st_used_mem { /* struct for once_alloc */
+ struct st_used_mem *next; /* Next block in use */
+ unsigned int left; /* memory left in block */
+ unsigned int size; /* size of block */
+} USED_MEM;
+typedef struct st_mem_root {
+ USED_MEM *free;
+ USED_MEM *used;
+ unsigned int min_malloc;
+ unsigned int block_size;
+ void (*error_handler)(void);
+} MEM_ROOT;
+#endif
+
+#ifndef my_socket_defined
+#ifdef __WIN__
+#define my_socket SOCKET
+#else
+typedef int my_socket;
+#endif
+#endif
+#endif
+#include "mysql_com.h"
+#include "mysql_version.h"
+
+extern unsigned int mysql_port;
+extern char *mysql_unix_port;
+
+#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG)
+#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG)
+#define IS_BLOB(n) ((n) & BLOB_FLAG)
+#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR)
+
+typedef struct st_mysql_field {
+ char *name; /* Name of column */
+ char *table; /* Table of column if column was a field */
+ char *def; /* Default value (set by mysql_list_fields) */
+ enum enum_field_types type; /* Type of field. Se mysql_com.h for types */
+ unsigned int length; /* Width of column */
+ unsigned int max_length; /* Max width of selected set */
+ unsigned int flags; /* Div flags */
+ unsigned int decimals; /* Number of decimals in field */
+} MYSQL_FIELD;
+
+typedef char **MYSQL_ROW; /* return data as array of strings */
+typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */
+
+#if defined(NO_CLIENT_LONG_LONG)
+typedef unsigned long my_ulonglong;
+#elif defined (__WIN__)
+typedef unsigned __int64 my_ulonglong;
+#else
+typedef unsigned long long my_ulonglong;
+#endif
+
+#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0)
+
+typedef struct st_mysql_rows {
+ struct st_mysql_rows *next; /* list of rows */
+ MYSQL_ROW data;
+} MYSQL_ROWS;
+
+typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */
+
+typedef struct st_mysql_data {
+ my_ulonglong rows;
+ unsigned int fields;
+ MYSQL_ROWS *data;
+ MEM_ROOT alloc;
+} MYSQL_DATA;
+
+struct st_mysql_options {
+ unsigned int connect_timeout,client_flag;
+ my_bool compress,named_pipe;
+ unsigned int port;
+ char *host,*init_command,*user,*password,*unix_socket,*db;
+ char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
+ my_bool use_ssl; /* if to use SSL or not */
+ char *ssl_key; /* PEM key file */
+ char *ssl_cert; /* PEM cert file */
+ char *ssl_ca; /* PEM CA file */
+ char *ssl_capath; /* PEM directory of CA-s? */
+};
+
+enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS,
+ MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND,
+ MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
+ MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME};
+
+enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,
+ MYSQL_STATUS_USE_RESULT};
+
+typedef struct st_mysql {
+ NET net; /* Communication parameters */
+ gptr connector_fd; /* ConnectorFd for SSL */
+ char *host,*user,*passwd,*unix_socket,*server_version,*host_info,
+ *info,*db;
+ unsigned int port,client_flag,server_capabilities;
+ unsigned int protocol_version;
+ unsigned int field_count;
+ unsigned int server_status;
+ unsigned long thread_id; /* Id for connection in server */
+ my_ulonglong affected_rows;
+ my_ulonglong insert_id; /* id if insert on table with NEXTNR */
+ my_ulonglong extra_info; /* Used by mysqlshow */
+ unsigned long packet_length;
+ enum mysql_status status;
+ MYSQL_FIELD *fields;
+ MEM_ROOT field_alloc;
+ my_bool free_me; /* If free in mysql_close */
+ my_bool reconnect; /* set to 1 if automatic reconnect */
+ struct st_mysql_options options;
+ char scramble_buff[9];
+ struct charset_info_st *charset;
+ unsigned int server_language;
+} MYSQL;
+
+
+typedef struct st_mysql_res {
+ my_ulonglong row_count;
+ unsigned int field_count, current_field;
+ MYSQL_FIELD *fields;
+ MYSQL_DATA *data;
+ MYSQL_ROWS *data_cursor;
+ MEM_ROOT field_alloc;
+ MYSQL_ROW row; /* If unbuffered read */
+ MYSQL_ROW current_row; /* buffer to current row */
+ unsigned long *lengths; /* column lengths of current row */
+ MYSQL *handle; /* for unbuffered reads */
+ my_bool eof; /* Used my mysql_fetch_row */
+} MYSQL_RES;
+
+/* Functions to get information from the MYSQL and MYSQL_RES structures */
+/* Should definitely be used if one uses shared libraries */
+
+my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res);
+unsigned int STDCALL mysql_num_fields(MYSQL_RES *res);
+my_bool STDCALL mysql_eof(MYSQL_RES *res);
+MYSQL_FIELD *STDCALL mysql_fetch_field_direct(MYSQL_RES *res,
+ unsigned int fieldnr);
+MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res);
+MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res);
+unsigned int STDCALL mysql_field_tell(MYSQL_RES *res);
+
+unsigned int STDCALL mysql_field_count(MYSQL *mysql);
+my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
+my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
+unsigned int STDCALL mysql_errno(MYSQL *mysql);
+char * STDCALL mysql_error(MYSQL *mysql);
+char * STDCALL mysql_info(MYSQL *mysql);
+unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
+const char * STDCALL mysql_character_set_name(MYSQL *mysql);
+
+MYSQL * STDCALL mysql_init(MYSQL *mysql);
+#ifdef HAVE_OPENSSL
+int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
+ const char *cert, const char *ca,
+ const char *capath);
+char * STDCALL mysql_ssl_cipher(MYSQL *mysql);
+int STDCALL mysql_ssl_clear(MYSQL *mysql);
+#endif /* HAVE_OPENSSL */
+MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host,
+ const char *user, const char *passwd);
+my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
+ const char *passwd, const char *db);
+#if MYSQL_VERSION_ID >= 32200
+MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
+ const char *user,
+ const char *passwd,
+ const char *db,
+ unsigned int port,
+ const char *unix_socket,
+ unsigned int clientflag);
+#else
+MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
+ const char *user,
+ const char *passwd,
+ unsigned int port,
+ const char *unix_socket,
+ unsigned int clientflag);
+#endif
+void STDCALL mysql_close(MYSQL *sock);
+int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
+int STDCALL mysql_query(MYSQL *mysql, const char *q);
+int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
+ unsigned int length);
+int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
+int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
+int STDCALL mysql_shutdown(MYSQL *mysql);
+int STDCALL mysql_dump_debug_info(MYSQL *mysql);
+int STDCALL mysql_refresh(MYSQL *mysql,
+ unsigned int refresh_options);
+int STDCALL mysql_kill(MYSQL *mysql,unsigned long pid);
+int STDCALL mysql_ping(MYSQL *mysql);
+char * STDCALL mysql_stat(MYSQL *mysql);
+char * STDCALL mysql_get_server_info(MYSQL *mysql);
+char * STDCALL mysql_get_client_info(void);
+char * STDCALL mysql_get_host_info(MYSQL *mysql);
+unsigned int STDCALL mysql_get_proto_info(MYSQL *mysql);
+MYSQL_RES * STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild);
+MYSQL_RES * STDCALL mysql_list_tables(MYSQL *mysql,const char *wild);
+MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table,
+ const char *wild);
+MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql);
+MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
+MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql);
+int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
+ const char *arg);
+void STDCALL mysql_free_result(MYSQL_RES *result);
+void STDCALL mysql_data_seek(MYSQL_RES *result,
+ my_ulonglong offset);
+MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET);
+MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result,
+ MYSQL_FIELD_OFFSET offset);
+MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
+unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result);
+MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result);
+unsigned long STDCALL mysql_escape_string(char *to,const char *from,
+ unsigned long from_length);
+unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
+ char *to,const char *from,
+ unsigned long length);
+void STDCALL mysql_debug(const char *debug);
+char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
+ char *to,
+ unsigned long to_length,
+ const char *from,
+ unsigned long from_length,
+ void *param,
+ char *
+ (*extend_buffer)
+ (void *, char *to,
+ unsigned long *length));
+void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
+unsigned int STDCALL mysql_thread_safe(void);
+
+
+#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
+
+/* new api functions */
+
+#define HAVE_MYSQL_REAL_CONNECT
+
+#ifndef MYSQL_SERVER
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif
diff --git a/VC++Files/winmysqladmin/mysql_com.h b/VC++Files/winmysqladmin/mysql_com.h
new file mode 100644
index 00000000000..2a1471f735d
--- /dev/null
+++ b/VC++Files/winmysqladmin/mysql_com.h
@@ -0,0 +1,242 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA */
+
+/*
+** Common definition between mysql server & client
+*/
+
+#ifndef _mysql_com_h
+#define _mysql_com_h
+
+
+#define NAME_LEN 64 /* Field/table name length */
+#define HOSTNAME_LENGTH 60
+#define USERNAME_LENGTH 16
+
+#define LOCAL_HOST "localhost"
+#define LOCAL_HOST_NAMEDPIPE "."
+
+#if defined(__EMX__) || defined(__OS2__)
+#undef MYSQL_UNIX_ADDR
+#define MYSQL_OS2_ADDR "\\socket\\MySQL"
+#define MYSQL_UNIX_ADDR MYSQL_OS2_ADDR
+#endif
+#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
+#define MYSQL_NAMEDPIPE "MySQL"
+#define MYSQL_SERVICENAME "MySql"
+#endif /* __WIN__ */
+
+enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
+ COM_FIELD_LIST,COM_CREATE_DB,COM_DROP_DB,COM_REFRESH,
+ COM_SHUTDOWN,COM_STATISTICS,
+ COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL,
+ COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT,
+ COM_CHANGE_USER, COM_BINLOG_DUMP,
+ COM_TABLE_DUMP};
+
+#define NOT_NULL_FLAG 1 /* Field can't be NULL */
+#define PRI_KEY_FLAG 2 /* Field is part of a primary key */
+#define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */
+#define MULTIPLE_KEY_FLAG 8 /* Field is part of a key */
+#define BLOB_FLAG 16 /* Field is a blob */
+#define UNSIGNED_FLAG 32 /* Field is unsigned */
+#define ZEROFILL_FLAG 64 /* Field is zerofill */
+#define BINARY_FLAG 128
+/* The following are only sent to new clients */
+#define ENUM_FLAG 256 /* field is an enum */
+#define AUTO_INCREMENT_FLAG 512 /* field is a autoincrement field */
+#define TIMESTAMP_FLAG 1024 /* Field is a timestamp */
+#define SET_FLAG 2048 /* field is a set */
+#define PART_KEY_FLAG 16384 /* Intern; Part of some key */
+#define GROUP_FLAG 32768 /* Intern: Group field */
+#define UNIQUE_FLAG 65536 /* Intern: Used by sql_yacc */
+
+#define REFRESH_GRANT 1 /* Refresh grant tables */
+#define REFRESH_LOG 2 /* Start on new log file */
+#define REFRESH_TABLES 4 /* close all tables */
+#define REFRESH_HOSTS 8 /* Flush host cache */
+#define REFRESH_STATUS 16 /* Flush status variables */
+#define REFRESH_THREADS 32 /* Flush status variables */
+#define REFRESH_SLAVE 64 /* Reset master info and restart slave
+ thread */
+#define REFRESH_MASTER 128 /* Remove all bin logs in the index
+ and truncate the index */
+
+/* The following can't be set with mysql_refresh() */
+#define REFRESH_READ_LOCK 16384 /* Lock tables for read */
+#define REFRESH_FAST 32768 /* Intern flag */
+
+#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
+#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
+#define CLIENT_LONG_FLAG 4 /* Get all column flags */
+#define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */
+#define CLIENT_NO_SCHEMA 16 /* Don't allow database.table.column */
+#define CLIENT_COMPRESS 32 /* Can use compression protocol */
+#define CLIENT_ODBC 64 /* Odbc client */
+#define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */
+#define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */
+#define CLIENT_CHANGE_USER 512 /* Support the mysql_change_user() */
+#define CLIENT_INTERACTIVE 1024 /* This is an interactive client */
+#define CLIENT_SSL 2048 /* Switch to SSL after handshake */
+#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */
+#define CLIENT_TRANSACTIONS 8196 /* Client knows about transactions */
+
+#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
+#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */
+
+#define MYSQL_ERRMSG_SIZE 200
+#define NET_READ_TIMEOUT 30 /* Timeout on read */
+#define NET_WRITE_TIMEOUT 60 /* Timeout on write */
+#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */
+
+#ifndef Vio_defined
+#define Vio_defined
+#ifdef HAVE_VIO
+class Vio; /* Fill Vio class in C++ */
+#else
+struct st_vio; /* Only C */
+typedef struct st_vio Vio;
+#endif
+#endif
+
+typedef struct st_net {
+ Vio* vio;
+ my_socket fd; /* For Perl DBI/dbd */
+ int fcntl;
+ unsigned char *buff,*buff_end,*write_pos,*read_pos;
+ char last_error[MYSQL_ERRMSG_SIZE];
+ unsigned int last_errno,max_packet,timeout,pkt_nr;
+ unsigned char error;
+ my_bool return_errno,compress;
+ my_bool no_send_ok; /* needed if we are doing several
+ queries in one command ( as in LOAD TABLE ... FROM MASTER ),
+ and do not want to confuse the client with OK at the wrong time
+ */
+ unsigned long remain_in_buf,length, buf_length, where_b;
+ unsigned int *return_status;
+ unsigned char reading_or_writing;
+ char save_char;
+} NET;
+
+#define packet_error ((unsigned int) -1)
+
+enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY,
+ FIELD_TYPE_SHORT, FIELD_TYPE_LONG,
+ FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE,
+ FIELD_TYPE_NULL, FIELD_TYPE_TIMESTAMP,
+ FIELD_TYPE_LONGLONG,FIELD_TYPE_INT24,
+ FIELD_TYPE_DATE, FIELD_TYPE_TIME,
+ FIELD_TYPE_DATETIME, FIELD_TYPE_YEAR,
+ FIELD_TYPE_NEWDATE,
+ FIELD_TYPE_ENUM=247,
+ FIELD_TYPE_SET=248,
+ FIELD_TYPE_TINY_BLOB=249,
+ FIELD_TYPE_MEDIUM_BLOB=250,
+ FIELD_TYPE_LONG_BLOB=251,
+ FIELD_TYPE_BLOB=252,
+ FIELD_TYPE_VAR_STRING=253,
+ FIELD_TYPE_STRING=254
+};
+
+#define FIELD_TYPE_CHAR FIELD_TYPE_TINY /* For compability */
+#define FIELD_TYPE_INTERVAL FIELD_TYPE_ENUM /* For compability */
+
+extern unsigned long max_allowed_packet;
+extern unsigned long net_buffer_length;
+
+#define net_new_transaction(net) ((net)->pkt_nr=0)
+
+int my_net_init(NET *net, Vio* vio);
+void net_end(NET *net);
+void net_clear(NET *net);
+int net_flush(NET *net);
+int my_net_write(NET *net,const char *packet,unsigned long len);
+int net_write_command(NET *net,unsigned char command,const char *packet,
+ unsigned long len);
+int net_real_write(NET *net,const char *packet,unsigned long len);
+unsigned int my_net_read(NET *net);
+
+struct rand_struct {
+ unsigned long seed1,seed2,max_value;
+ double max_value_dbl;
+};
+
+ /* The following is for user defined functions */
+
+enum Item_result {STRING_RESULT,REAL_RESULT,INT_RESULT};
+
+typedef struct st_udf_args
+{
+ unsigned int arg_count; /* Number of arguments */
+ enum Item_result *arg_type; /* Pointer to item_results */
+ char **args; /* Pointer to argument */
+ unsigned long *lengths; /* Length of string arguments */
+ char *maybe_null; /* Set to 1 for all maybe_null args */
+} UDF_ARGS;
+
+ /* This holds information about the result */
+
+typedef struct st_udf_init
+{
+ my_bool maybe_null; /* 1 if function can return NULL */
+ unsigned int decimals; /* for real functions */
+ unsigned int max_length; /* For string functions */
+ char *ptr; /* free pointer for function data */
+ my_bool const_item; /* 0 if result is independent of arguments */
+} UDF_INIT;
+
+ /* Constants when using compression */
+#define NET_HEADER_SIZE 4 /* standard header size */
+#define COMP_HEADER_SIZE 3 /* compression header extra size */
+
+ /* Prototypes to password functions */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void randominit(struct rand_struct *,unsigned long seed1,
+ unsigned long seed2);
+double rnd(struct rand_struct *);
+void make_scrambled_password(char *to,const char *password);
+void get_salt_from_password(unsigned long *res,const char *password);
+void make_password_from_salt(char *to, unsigned long *hash_res);
+char *scramble(char *to,const char *message,const char *password,
+ my_bool old_ver);
+my_bool check_scramble(const char *, const char *message,
+ unsigned long *salt,my_bool old_ver);
+char *get_tty_password(char *opt_message);
+void hash_password(unsigned long *result, const char *password);
+#ifdef __cplusplus
+}
+#endif
+
+/* Some other useful functions */
+
+void my_init(void);
+void load_defaults(const char *conf_file, const char **groups,
+ int *argc, char ***argv);
+
+#define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */
+
+#ifdef __WIN__
+#define socket_errno WSAGetLastError()
+#else
+#define socket_errno errno
+#endif
+
+#endif
diff --git a/VC++Files/winmysqladmin/mysql_version.h b/VC++Files/winmysqladmin/mysql_version.h
new file mode 100644
index 00000000000..1f868704fe8
--- /dev/null
+++ b/VC++Files/winmysqladmin/mysql_version.h
@@ -0,0 +1,20 @@
+/* Copyright Abandoned 1996,1999 TCX DataKonsult AB & Monty Program KB & Detron HB
+ This file is public domain and comes with NO WARRANTY of any kind */
+
+/* Version numbers for protocol & mysqld */
+
+#ifdef _CUSTOMCONFIG_
+ #include <custom_conf.h>
+#else
+#define PROTOCOL_VERSION 10
+#define MYSQL_SERVER_VERSION "3.23.22-beta"
+#define FRM_VER 6
+#define MYSQL_VERSION_ID 32322
+#define MYSQL_PORT 3306
+#define MYSQL_UNIX_ADDR "/tmp/mysql.sock"
+
+/* mysqld compile time options */
+#ifndef MYSQL_CHARSET
+#define MYSQL_CHARSET "latin1"
+#endif
+#endif
diff --git a/VC++Files/winmysqladmin/winmysqladmin.cpp b/VC++Files/winmysqladmin/winmysqladmin.cpp
new file mode 100644
index 00000000000..591b7518fa3
--- /dev/null
+++ b/VC++Files/winmysqladmin/winmysqladmin.cpp
@@ -0,0 +1,38 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+HINSTANCE g_hinst;
+USERES("winmysqladmin.res");
+USEFORM("main.cpp", Form1);
+USEFORM("initsetup.cpp", Form2);
+USEFORM("db.cpp", dbfrm);
+USELIB("lib\mysqlclient.lib");
+USELIB("lib\myisammrg.lib");
+USELIB("lib\heap.lib");
+USELIB("lib\isam.lib");
+USELIB("lib\merge.lib");
+USELIB("lib\myisam.lib");
+USELIB("lib\mysys.lib");
+USELIB("lib\regex.lib");
+USELIB("lib\strings.lib");
+USELIB("lib\zlib.lib");
+//---------------------------------------------------------------------------
+WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
+{
+ try
+ {
+ Application->Initialize();
+ Application->HelpFile = "C:\\mysql\\bin\\WINMYSQLADMIN.HLP";
+ Application->Title = "WinMySQLadmin 1.0";
+ Application->CreateForm(__classid(TForm1), &Form1);
+ Application->CreateForm(__classid(TForm2), &Form2);
+ Application->CreateForm(__classid(Tdbfrm), &dbfrm);
+ Application->Run();
+ }
+ catch (Exception &exception)
+ {
+ Application->ShowException(&exception);
+ }
+ return 0;
+}
+//---------------------------------------------------------------------------
diff --git a/VC++Files/zlib/contrib/asm386/zlibvc.dsp b/VC++Files/zlib/contrib/asm386/zlibvc.dsp
new file mode 100644
index 00000000000..a70d4d4a6b0
--- /dev/null
+++ b/VC++Files/zlib/contrib/asm386/zlibvc.dsp
@@ -0,0 +1,651 @@
+# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602
+
+CFG=zlibvc - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zlibvc.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zlibvc.mak" CFG="zlibvc - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\
+ "Win32 (ALPHA) Dynamic-Link Library")
+!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\
+ "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\
+ "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir ".\Release"
+# PROP BASE Intermediate_Dir ".\Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\Release"
+# PROP Intermediate_Dir ".\Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c
+# SUBTRACT CPP /YX
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir ".\Debug"
+# PROP BASE Intermediate_Dir ".\Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\Debug"
+# PROP Intermediate_Dir ".\Debug"
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c
+# SUBTRACT CPP /YX
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x40c /d "_DEBUG"
+# ADD RSC /l 0x40c /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlibvc__"
+# PROP BASE Intermediate_Dir "zlibvc__"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zlibvc__"
+# PROP Intermediate_Dir "zlibvc__"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+CPP=cl.exe
+# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c
+# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c
+# SUBTRACT CPP /YX
+RSC=rc.exe
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll"
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlibvc_0"
+# PROP BASE Intermediate_Dir "zlibvc_0"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zlibvc_0"
+# PROP Intermediate_Dir "zlibvc_0"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c
+# SUBTRACT CPP /YX
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlibvc_1"
+# PROP BASE Intermediate_Dir "zlibvc_1"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zlibvc_1"
+# PROP Intermediate_Dir "zlibvc_1"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c
+# SUBTRACT CPP /YX
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll"
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "zlibvc - Win32 Release"
+# Name "zlibvc - Win32 Debug"
+# Name "zlibvc - Win32 ReleaseAxp"
+# Name "zlibvc - Win32 ReleaseWithoutAsm"
+# Name "zlibvc - Win32 ReleaseWithoutCrtdll"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
+# Begin Source File
+
+SOURCE=.\adler32.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_ADLER=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\compress.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_COMPR=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\crc32.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_CRC32=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\deflate.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_DEFLA=\
+ ".\deflate.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\gvmat32c.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\gzio.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_GZIO_=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\infblock.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFBL=\
+ ".\infblock.h"\
+ ".\infcodes.h"\
+ ".\inftrees.h"\
+ ".\infutil.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\infcodes.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFCO=\
+ ".\infblock.h"\
+ ".\infcodes.h"\
+ ".\inffast.h"\
+ ".\inftrees.h"\
+ ".\infutil.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\inffast.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFFA=\
+ ".\infblock.h"\
+ ".\infcodes.h"\
+ ".\inffast.h"\
+ ".\inftrees.h"\
+ ".\infutil.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\inflate.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFLA=\
+ ".\infblock.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\inftrees.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFTR=\
+ ".\inftrees.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\infutil.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_INFUT=\
+ ".\infblock.h"\
+ ".\infcodes.h"\
+ ".\inftrees.h"\
+ ".\infutil.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\trees.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_TREES=\
+ ".\deflate.h"\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\uncompr.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_UNCOM=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\unzip.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\zip.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\zlib.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\zlibvc.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\zutil.c
+
+!IF "$(CFG)" == "zlibvc - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp"
+
+DEP_CPP_ZUTIL=\
+ ".\zconf.h"\
+ ".\zlib.h"\
+ ".\zutil.h"\
+
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm"
+
+!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll"
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
+# Begin Source File
+
+SOURCE=.\deflate.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\infblock.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\infcodes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\inffast.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\inftrees.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\infutil.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\zconf.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\zlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\zutil.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/zlib/contrib/asm386/zlibvc.dsw b/VC++Files/zlib/contrib/asm386/zlibvc.dsw
new file mode 100644
index 00000000000..493cd870365
--- /dev/null
+++ b/VC++Files/zlib/contrib/asm386/zlibvc.dsw
@@ -0,0 +1,41 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/VC++Files/zlib/zlib.dsp b/VC++Files/zlib/zlib.dsp
index b46afad005c..40aaadaa4e1 100644
--- a/VC++Files/zlib/zlib.dsp
+++ b/VC++Files/zlib/zlib.dsp
@@ -7,25 +7,25 @@
CFG=zlib - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "zlib.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 Debug"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "zlib - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "zlib - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
-CPP=cl.exe
+CPP=xicl6.exe
RSC=rc.exe
!IF "$(CFG)" == "zlib - Win32 Release"
@@ -48,7 +48,7 @@ RSC=rc.exe
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LIB32=link.exe -lib
+LIB32=xilink6.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_release\zlib.lib"
@@ -65,17 +65,17 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /G6 /MTd /W3 /Zi /Od /D "_DEBUG" /D "__WIN32__" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /D "_DEBUG" /D "__WIN32__" /D "_WINDOWS" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
-LIB32=link.exe -lib
+LIB32=xilink6.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\lib_debug\zlib.lib"
-!ENDIF
+!ENDIF
# Begin Target
diff --git a/acconfig.h b/acconfig.h
index 3cea5bf4b73..825842d256a 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -91,6 +91,9 @@
/* Using Innobase DB */
#undef HAVE_INNOBASE_DB
+/* Using old ISAM tables */
+#undef HAVE_ISAM
+
/* Define if we have GNU readline */
#undef HAVE_LIBREADLINE
@@ -121,6 +124,9 @@
/* sigwait with one argument */
#undef HAVE_NONPOSIX_SIGWAIT
+/* ORBIT */
+#undef HAVE_ORBIT
+
/* pthread_attr_setscope */
#undef HAVE_PTHREAD_ATTR_SETSCOPE
@@ -142,6 +148,9 @@
/* crypt */
#undef HAVE_CRYPT
+/* If we want to have query cache */
+#undef HAVE_QUERY_CACHE
+
/* Solaris define gethostbyaddr_r with 7 arguments. glibc2 defines
this with 8 arguments */
#undef HAVE_SOLARIS_STYLE_GETHOST
@@ -164,15 +173,24 @@
/* Define if the system files define ulong */
#undef HAVE_ULONG
+/* Define if the system files define in_addr_t */
+#undef HAVE_IN_ADDR_T
+
/* UNIXWARE7 threads are not posix */
#undef HAVE_UNIXWARE7_THREADS
/* new UNIXWARE7 threads that are not yet posix */
#undef HAVE_UNIXWARE7_POSIX
+/* OpenSSL */
+#undef HAVE_OPENSSL
+
/* READLINE: */
#undef HAVE_USG_SIGHOLD
+/* Virtual IO */
+#undef HAVE_VIO
+
/* Handling of large files on Solaris 2.6 */
#undef _LARGEFILE_SOURCE
@@ -219,7 +237,7 @@
#undef SPRINTF_RETURNS_INT
#undef SPRINTF_RETURNS_GARBAGE
-/* Needed to get large file supportat HPUX 10.20 */
+/* Needed to get large file support on HPUX 10.20 */
#undef __STDC_EXT__
#undef STACK_DIRECTION
@@ -248,6 +266,9 @@
#undef USE_MB
#undef USE_MB_IDENT
+/* the pstack backtrace library */
+#undef USE_PSTACK
+
/* Use MySQL RAID */
#undef USE_RAID
diff --git a/acinclude.m4 b/acinclude.m4
index 69cd1a82108..8a92048f9ab 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -38,7 +38,7 @@ AC_LANG_SAVE
AC_LANG_CPLUSPLUS
if test "$ac_cv_prog_gxx" = "yes"
then
- CXXFLAGS="$CXXFLAGS -Werror"
+ CXXFLAGS=`echo $CXXFLAGS -Werror | sed 's/-fbranch-probabilities//'`
fi
mysql_cv_btype_last_arg_accept=none
[AC_TRY_COMPILE([#if defined(inline)
@@ -50,7 +50,7 @@ mysql_cv_btype_last_arg_accept=none
],
[int a = accept(1, (struct sockaddr *) 0, (socklen_t *) 0); return (a != 0);],
mysql_cv_btype_last_arg_accept=socklen_t)]
-if test $mysql_cv_btype_last_arg_accept = none; then
+if test "$mysql_cv_btype_last_arg_accept" = "none"; then
[AC_TRY_COMPILE([#if defined(inline)
#undef inline
#endif
@@ -61,7 +61,7 @@ if test $mysql_cv_btype_last_arg_accept = none; then
[int a = accept(1, (struct sockaddr *) 0, (size_t *) 0); return (a != 0);],
mysql_cv_btype_last_arg_accept=size_t)]
fi
-if test $mysql_cv_btype_last_arg_accept = none; then
+if test "$mysql_cv_btype_last_arg_accept" = "none"; then
mysql_cv_btype_last_arg_accept=int
fi)
AC_LANG_RESTORE
@@ -126,12 +126,19 @@ AC_DEFUN(MYSQL_CHECK_ZLIB_WITH_COMPRESS, [
save_LIBS="$LIBS"
LIBS="-l$1 $LIBS"
AC_CACHE_CHECK([if libz with compress], mysql_cv_compress,
-[AC_TRY_LINK([#include <zlib.h>
+[AC_TRY_RUN([#include <zlib.h>
#ifdef __cplusplus
extern "C"
#endif
-],
-[ return compress(0, (unsigned long*) 0, "", 0);
+int main(int argv, char **argc)
+{
+ return 0;
+}
+
+int link_test()
+{
+ return compress(0, (unsigned long*) 0, "", 0);
+}
], mysql_cv_compress=yes, mysql_cv_compress=no)])
if test "$mysql_cv_compress" = "yes"
then
@@ -197,6 +204,28 @@ fi
])
+AC_DEFUN(MYSQL_CHECK_IN_ADDR_T,
+[AC_MSG_CHECKING(for type in_addr_t)
+AC_CACHE_VAL(ac_cv_in_addr_t,
+[AC_TRY_RUN([#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int main(int argc, char **argv)
+{
+ in_addr_t foo;
+ exit(0);
+}], ac_cv_in_addr_t=yes, ac_cv_in_addr_t=no, ac_cv_in_addr_t=no)])
+AC_MSG_RESULT($ac_cv_in_addr_t)
+if test "$ac_cv_in_addr_t" = "yes"
+then
+ AC_DEFINE(HAVE_IN_ADDR_T)
+fi
+])
+
+
AC_DEFUN(MYSQL_PTHREAD_YIELD,
[AC_CACHE_CHECK([if pthread_yield takes zero arguments], ac_cv_pthread_yield_zero_arg,
[AC_TRY_LINK([#define _GNU_SOURCE
@@ -346,11 +375,11 @@ AC_CACHE_VAL(mysql_cv_termcap_lib,
[AC_CHECK_LIB(termcap, tgetent, mysql_cv_termcap_lib=libtermcap,
mysql_cv_termcap_lib=NOT_FOUND)])])])
AC_MSG_CHECKING(for termcap functions library)
-if test $mysql_cv_termcap_lib = NOT_FOUND; then
+if test "$mysql_cv_termcap_lib" = "NOT_FOUND"; then
AC_MSG_ERROR([No curses/termcap library found])
-elif test $mysql_cv_termcap_lib = libtermcap; then
+elif test "$mysql_cv_termcap_lib" = "libtermcap"; then
TERMCAP_LIB=-ltermcap
-elif test $mysql_cv_termcap_lib = libncurses; then
+elif test "$mysql_cv_termcap_lib" = "libncurses"; then
TERMCAP_LIB=-lncurses
else
TERMCAP_LIB=-lcurses
@@ -406,7 +435,7 @@ AC_CACHE_VAL(mysql_cv_can_redecl_getpw,
extern struct passwd *getpwent();], [struct passwd *z; z = getpwent();],
mysql_cv_can_redecl_getpw=yes,mysql_cv_can_redecl_getpw=no)])
AC_MSG_RESULT($mysql_cv_can_redecl_getpw)
-if test $mysql_cv_can_redecl_getpw = no; then
+if test "$mysql_cv_can_redecl_getpw" = "no"; then
AC_DEFINE(HAVE_GETPW_DECLS)
fi
])
@@ -418,7 +447,7 @@ AC_CACHE_VAL(mysql_cv_tiocgwinsz_in_ioctl,
#include <sys/ioctl.h>], [int x = TIOCGWINSZ;],
mysql_cv_tiocgwinsz_in_ioctl=yes,mysql_cv_tiocgwinsz_in_ioctl=no)])
AC_MSG_RESULT($mysql_cv_tiocgwinsz_in_ioctl)
-if test $mysql_cv_tiocgwinsz_in_ioctl = yes; then
+if test "$mysql_cv_tiocgwinsz_in_ioctl" = "yes"; then
AC_DEFINE(GWINSZ_IN_SYS_IOCTL)
fi
])
@@ -430,7 +459,7 @@ AC_CACHE_VAL(mysql_cv_fionread_in_ioctl,
#include <sys/ioctl.h>], [int x = FIONREAD;],
mysql_cv_fionread_in_ioctl=yes,mysql_cv_fionread_in_ioctl=no)])
AC_MSG_RESULT($mysql_cv_fionread_in_ioctl)
-if test $mysql_cv_fionread_in_ioctl = yes; then
+if test "$mysql_cv_fionread_in_ioctl" = "yes"; then
AC_DEFINE(FIONREAD_IN_SYS_IOCTL)
fi
])
@@ -442,7 +471,7 @@ AC_CACHE_VAL(mysql_cv_tiocstat_in_ioctl,
#include <sys/ioctl.h>], [int x = TIOCSTAT;],
mysql_cv_tiocstat_in_ioctl=yes,mysql_cv_tiocstat_in_ioctl=no)])
AC_MSG_RESULT($mysql_cv_tiocstat_in_ioctl)
-if test $mysql_cv_tiocstat_in_ioctl = yes; then
+if test "$mysql_cv_tiocstat_in_ioctl" = "yes"; then
AC_DEFINE(TIOCSTAT_IN_SYS_IOCTL)
fi
])
@@ -475,7 +504,7 @@ AC_CACHE_VAL(mysql_cv_dirent_has_dino,
struct dirent d; int z; z = d.d_ino;
], mysql_cv_dirent_has_dino=yes, mysql_cv_dirent_has_dino=no)])
AC_MSG_RESULT($mysql_cv_dirent_has_dino)
-if test $mysql_cv_dirent_has_dino = yes; then
+if test "$mysql_cv_dirent_has_dino" = "yes"; then
AC_DEFINE(STRUCT_DIRENT_HAS_D_INO)
fi
])
@@ -494,7 +523,7 @@ extern "C"
void (*signal ()) ();],
[int i;], mysql_cv_void_sighandler=yes, mysql_cv_void_sighandler=no)])dnl
AC_MSG_RESULT($mysql_cv_void_sighandler)
-if test $mysql_cv_void_sighandler = yes; then
+if test "$mysql_cv_void_sighandler" = "yes"; then
AC_DEFINE(VOID_SIGHANDLER)
fi
])
@@ -553,7 +582,7 @@ then
AC_CACHE_CHECK([for working alloca.h], ac_cv_header_alloca_h,
[AC_TRY_LINK([#include <alloca.h>], [char *p = alloca(2 * sizeof(int));],
ac_cv_header_alloca_h=yes, ac_cv_header_alloca_h=no)])
- if test $ac_cv_header_alloca_h = yes
+ if test "$ac_cv_header_alloca_h" = "yes"
then
AC_DEFINE(HAVE_ALLOCA)
fi
@@ -577,11 +606,11 @@ then
#endif
], [char *p = (char *) alloca(1);],
ac_cv_func_alloca_works=yes, ac_cv_func_alloca_works=no)])
- if test $ac_cv_func_alloca_works = yes; then
+ if test "$ac_cv_func_alloca_works" = "yes"; then
AC_DEFINE(HAVE_ALLOCA)
fi
- if test $ac_cv_func_alloca_works = no; then
+ if test "$ac_cv_func_alloca_works" = "no"; then
# The SVR3 libPW and SVR4 libucb both contain incompatible functions
# that cause trouble. Some versions do not even contain alloca or
# contain a buggy version. If you still want to use their alloca,
@@ -597,7 +626,7 @@ then
wenotbecray
#endif
], ac_cv_os_cray=yes, ac_cv_os_cray=no)])
- if test $ac_cv_os_cray = yes; then
+ if test "$ac_cv_os_cray" = "yes"; then
for ac_func in _getb67 GETB67 getb67; do
AC_CHECK_FUNC($ac_func, [AC_DEFINE_UNQUOTED(CRAY_STACKSEG_END, $ac_func)
break])
@@ -635,6 +664,258 @@ fi
AC_MSG_RESULT($ac_cv_conv_longlong_to_float)
])
+AC_DEFUN(MYSQL_CHECK_CPU,
+[AC_CACHE_CHECK([if compiler supports optimizations for current cpu],
+mysql_cv_cpu,[
+
+ac_save_CFLAGS="$CFLAGS"
+if test -r /proc/cpuinfo ; then
+ cpuinfo="cat /proc/cpuinfo"
+ cpu_family=`$cpuinfo | grep 'cpu family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
+ cpu_vendor=`$cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
+fi
+if test "$cpu_vendor" = "AuthenticAMD"; then
+ if test $cpu_family -ge 6; then
+ cpu_set="athlon pentiumpro k5 pentium i486 i386";
+ elif test $cpu_family -eq 5; then
+ cpu_set="k5 pentium i486 i386";
+ elif test $cpu_family -eq 4; then
+ cpu_set="i486 i386"
+ else
+ cpu_set="i386"
+ fi
+elif test "$cpu_vendor" = "GenuineIntel"; then
+ if test $cpu_family -ge 6; then
+ cpu_set="pentiumpro pentium i486 i386";
+ elif test $cpu_family -eq 5; then
+ cpu_set="pentium i486 i386";
+ elif test $cpu_family -eq 4; then
+ cpu_set="i486 i386"
+ else
+ cpu_set="i386"
+ fi
+fi
+
+for ac_arg in $cpu_set;
+do
+ CFLAGS="$ac_save_CFLAGS -mcpu=$ac_arg -march=$ac_arg -DCPU=$ac_arg"
+ AC_TRY_COMPILE([],[int i],mysql_cv_cpu=$ac_arg; break;, mysql_cv_cpu="unknown")
+done
+
+if test "$mysql_cv_cpu" = "unknown"
+then
+ CFLAGS="$ac_save_CFLAGS"
+ AC_MSG_RESULT(none)
+else
+ AC_MSG_RESULT($mysql_cv_cpu)
+fi
+]]))
+
+AC_DEFUN(MYSQL_CHECK_VIO, [
+ AC_ARG_WITH([vio],
+ [ --with-vio Include the Virtual IO support],
+ [vio="$withval"],
+ [vio=no])
+
+ if test "$vio" = "yes"
+ then
+ vio_dir="vio"
+ vio_libs="../vio/libvio.la"
+ AC_DEFINE(HAVE_VIO)
+ else
+ vio_dir=""
+ vio_libs=""
+ fi
+ AC_SUBST([vio_dir])
+ AC_SUBST([vio_libs])
+])
+
+AC_DEFUN(MYSQL_FIND_OPENSSL, [
+ incs="$1"
+ libs="$2"
+ case "$incs---$libs" in
+ ---)
+ for d in /usr/ssl/include /usr/local/ssl/include /usr/include \
+/usr/include/ssl /opt/ssl/include /opt/openssl/include \
+/usr/local/ssl/include /usr/local/include ; do
+ if test -f $d/openssl/ssl.h ; then
+ OPENSSL_INCLUDE=-I$d
+ fi
+ done
+
+ for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \
+/usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do
+ if test -f $d/libssl.a || test -f $d/libssl.so || test -f $d/libssl.dylib ; then
+ OPENSSL_LIB=$d
+ fi
+ done
+ ;;
+ ---* | *---)
+ AC_MSG_ERROR([if either 'includes' or 'libs' is specified, both must be specified])
+ ;;
+ * )
+ if test -f $incs/openssl/ssl.h ; then
+ OPENSSL_INCLUDE=-I$incs
+ fi
+ if test -f $libs/libssl.a || test -f $libs/libssl.so || test -f $libs/libssl.dylib ; then
+ OPENSSL_LIB=$libs
+ fi
+ ;;
+ esac
+
+ # On RedHat 9 we need kerberos to compile openssl
+ for d in /usr/kerberos/include
+ do
+ if test -f $d/krb5.h ; then
+ OPENSSL_KERBEROS_INCLUDE="$d"
+ fi
+ done
+
+
+ if test -z "$OPENSSL_LIB" -o -z "$OPENSSL_INCLUDE" ; then
+ echo "Could not find an installation of OpenSSL"
+ if test -n "$OPENSSL_LIB" ; then
+ if test "$IS_LINUX" = "true"; then
+ echo "Looks like you've forgotten to install OpenSSL development RPM"
+ fi
+ fi
+ exit 1
+ fi
+
+])
+
+AC_DEFUN(MYSQL_CHECK_OPENSSL, [
+AC_MSG_CHECKING(for OpenSSL)
+ AC_ARG_WITH([openssl],
+ [ --with-openssl Include the OpenSSL support],
+ [openssl="$withval"],
+ [openssl=no])
+
+ AC_ARG_WITH([openssl-includes],
+ [
+ --with-openssl-includes=DIR
+ Find OpenSSL headers in DIR],
+ [openssl_includes="$withval"],
+ [openssl_includes=""])
+
+ AC_ARG_WITH([openssl-libs],
+ [
+ --with-openssl-libs=DIR
+ Find OpenSSL libraries in DIR],
+ [openssl_libs="$withval"],
+ [openssl_libs=""])
+
+ if test "$openssl" = "yes"
+ then
+ MYSQL_FIND_OPENSSL([$openssl_includes], [$openssl_libs])
+ #force VIO use
+ vio_dir="vio"
+ vio_libs="../vio/libvio.la"
+ AC_DEFINE(HAVE_VIO)
+ AC_MSG_RESULT(yes)
+ openssl_libs="-L$OPENSSL_LIB -lssl -lcrypto"
+ # Don't set openssl_includes to /usr/include as this gives us a lot of
+ # compiler warnings when using gcc 3.x
+ openssl_includes=""
+ if test "$OPENSSL_INCLUDE" != "-I/usr/include"
+ then
+ openssl_includes="$OPENSSL_INCLUDE"
+ fi
+ if test "$OPENSSL_KERBEROS_INCLUDE"
+ then
+ openssl_includes="$openssl_includes -I$OPENSSL_KERBEROS_INCLUDE"
+ fi
+ AC_DEFINE(HAVE_OPENSSL)
+
+ # openssl-devel-0.9.6 requires dlopen() and we can't link staticly
+ # on many platforms (We should actually test this here, but it's quite
+ # hard) to do as we are doing libtool for linking.
+ using_static=""
+ case "$CLIENT_EXTRA_LDFLAGS $MYSQLD_EXTRA_LDFLAGS" in
+ *-all-static*) using_static="yes" ;;
+ esac
+ if test "$using_static" = "yes"
+ then
+ echo "You can't use the --all-static link option when using openssl."
+ exit 1
+ fi
+ NON_THREADED_CLIENT_LIBS="$NON_THREADED_CLIENT_LIBS $openssl_libs"
+ else
+ AC_MSG_RESULT(no)
+ fi
+ AC_SUBST(openssl_libs)
+ AC_SUBST(openssl_includes)
+])
+
+
+AC_DEFUN(MYSQL_CHECK_MYSQLFS, [
+ AC_ARG_WITH([mysqlfs],
+ [
+ --with-mysqlfs Include the corba-based MySQL file system],
+ [mysqlfs="$withval"],
+ [mysqlfs=no])
+
+dnl Call MYSQL_CHECK_ORBIT even if mysqlfs == no, so that @orbit_*@
+dnl get substituted.
+ MYSQL_CHECK_ORBIT
+
+ AC_MSG_CHECKING(if we should build MySQLFS)
+ fs_dirs=""
+ if test "$mysqlfs" = "yes"
+ then
+ if test -n "$orbit_exec_prefix"
+ then
+ fs_dirs=fs
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT(disabled because ORBIT, the CORBA ORB, was not found)
+ fi
+ else
+ AC_MSG_RESULT([no])
+ fi
+ AC_SUBST([fs_dirs])
+])
+
+AC_DEFUN(MYSQL_CHECK_ORBIT, [
+AC_MSG_CHECKING(for ORBit)
+orbit_config_path=`which orbit-config`
+if test -n "$orbit_config_path" -a $? = 0
+then
+ orbit_exec_prefix=`orbit-config --exec-prefix`
+ orbit_includes=`orbit-config --cflags server`
+ orbit_libs=`orbit-config --libs server`
+ orbit_idl="$orbit_exec_prefix/bin/orbit-idl"
+ AC_MSG_RESULT(found!)
+ AC_DEFINE(HAVE_ORBIT)
+else
+ orbit_exec_prefix=
+ orbit_includes=
+ orbit_libs=
+ orbit_idl=
+ AC_MSG_RESULT(not found)
+fi
+AC_SUBST(orbit_includes)
+AC_SUBST(orbit_libs)
+AC_SUBST(orbit_idl)
+])
+
+AC_DEFUN([MYSQL_CHECK_ISAM], [
+ AC_ARG_WITH([isam], [
+ --without-isam Disable the ISAM table type],
+ [with_isam="$withval"],
+ [with_isam=yes])
+
+ isam_libs=
+ if test X"$with_isam" = X"yes"
+ then
+ AC_DEFINE(HAVE_ISAM)
+ isam_libs="\$(top_builddir)/isam/libnisam.a\
+ \$(top_builddir)/merge/libmerge.a"
+ fi
+ AC_SUBST(isam_libs)
+])
+
+
dnl ---------------------------------------------------------------------------
dnl Macro: MYSQL_CHECK_BDB
dnl Sets HAVE_BERKELEY_DB if inst library is found
@@ -907,9 +1188,9 @@ dnl ---------------------------------------------------------------------------
AC_DEFUN([MYSQL_CHECK_INNODB], [
AC_ARG_WITH([innodb],
[
- --with-innodb Use Innodb],
+ --without-innodb Do not include the InnoDB table handler],
[innodb="$withval"],
- [innodb=no])
+ [innodb=yes])
AC_MSG_CHECKING([for Innodb])
@@ -979,53 +1260,6 @@ dnl ---------------------------------------------------------------------------
dnl END OF MYSQL_CHECK_INNODB SECTION
dnl ---------------------------------------------------------------------------
-dnl ---------------------------------------------------------------------------
-dnl Macro: MYSQL_CHECK_GEMINI
-dnl Sets HAVE_GEMINI_DB if --with-gemini is used
-dnl ---------------------------------------------------------------------------
-
-AC_DEFUN([MYSQL_CHECK_GEMINI], [
- AC_ARG_WITH([gemini],
- [
- --with-gemini[=DIR] Use Gemini DB located in DIR],
- [gemini="$withval"],
- [gemini=no])
-
- AC_MSG_CHECKING([for Gemini DB])
-
-dnl SORT OUT THE SUPPLIED ARGUMENTS TO DETERMINE WHAT TO DO
-dnl echo "DBG_GEM1: gemini='$gemini'"
- have_gemini_db=no
- gemini_includes=
- gemini_libs=
- case "$gemini" in
- no)
- AC_MSG_RESULT([Not using Gemini DB])
- ;;
- yes | default | *)
- have_gemini_db="yes"
- gemini_includes="-I../gemini/incl -I../gemini"
- gemini_libs="\
- ../gemini/api/libapi.a\
- ../gemini/db/libdb.a\
- ../gemini/dbut/libdbut.a"
- AC_MSG_RESULT([Using Gemini DB])
- ;;
- esac
-
- AC_SUBST(gemini_includes)
- AC_SUBST(gemini_libs)
-])
-
-dnl ---------------------------------------------------------------------------
-dnl END OF MYSQL_CHECK_GEMINI SECTION
-dnl ---------------------------------------------------------------------------
-
-dnl ---------------------------------------------------------------------------
-dnl Got this from the GNU tar 1.13.11 distribution
-dnl by Paul Eggert <eggert@twinsun.com>
-dnl ---------------------------------------------------------------------------
-
dnl By default, many hosts won't let programs access large files;
dnl one must use special compiler options to get large-file access to work.
dnl For more details about this brain damage please see:
@@ -1050,7 +1284,9 @@ changequote(, )dnl
hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
changequote([, ])dnl
if test "$GCC" = yes; then
- ac_cv_sys_largefile_CFLAGS=-D__STDC_EXT__
+ case `$CC --version 2>/dev/null` in
+ 2.95.*) ac_cv_sys_largefile_CFLAGS=-D__STDC_EXT__ ;;
+ esac
fi
;;
# IRIX 6.2 and later require cc -n32.
@@ -1088,7 +1324,6 @@ AC_DEFUN(AC_SYS_LARGEFILE_MACRO_VALUE,
[AC_CACHE_CHECK([for $1], $2,
[$2=no
changequote(, )dnl
- $4
for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
case "$ac_flag" in
-D$1)
@@ -1097,6 +1332,7 @@ changequote(, )dnl
$2=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;;
esac
done
+ $4
changequote([, ])dnl
])
if test "[$]$2" != no; then
@@ -1127,6 +1363,7 @@ AC_DEFUN(MYSQL_SYS_LARGEFILE,
done
AC_SYS_LARGEFILE_SPACE_APPEND(LDFLAGS, "$ac_cv_sys_largefile_LDFLAGS")
AC_SYS_LARGEFILE_SPACE_APPEND(LIBS, "$ac_cv_sys_largefile_LIBS")
+
AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS,
ac_cv_sys_file_offset_bits,
[Number of bits in a file offset, on hosts where this is settable.],
@@ -1134,6 +1371,14 @@ AC_DEFUN(MYSQL_SYS_LARGEFILE,
# HP-UX 10.20 and later
hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
ac_cv_sys_file_offset_bits=64 ;;
+ # We can't declare _FILE_OFFSET_BITS here as this will cause
+ # compile errors as AC_PROG_CC adds include files in confdefs.h
+ # We solve this (until autoconf is fixed) by instead declaring it
+ # as define instead
+ solaris2.[8,9])
+ CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64"
+ CXXFLAGS="$CXXFLAGS -D_FILE_OFFSET_BITS=64"
+ ac_cv_sys_file_offset_bits=no ;;
esac])
AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE,
ac_cv_sys_largefile_source,
@@ -1154,8 +1399,9 @@ AC_DEFUN(MYSQL_SYS_LARGEFILE,
fi
])
+
# Local version of _AC_PROG_CXX_EXIT_DECLARATION that does not
-# include #stdlib.h as this breaks things on Solaris
+# include #stdlib.h as default as this breaks things on Solaris
# (Conflicts with pthreads and big file handling)
m4_define([_AC_PROG_CXX_EXIT_DECLARATION],
@@ -1184,3 +1430,6 @@ if test -n "$ac_declaration"; then
echo '#endif' >>confdefs.h
fi
])# _AC_PROG_CXX_EXIT_DECLARATION
+
+dnl ---------------------------------------------------------------------------
+
diff --git a/bdb/dist/s_symlink b/bdb/dist/s_symlink
index 70efa445521..8c0e12dedd0 100755
--- a/bdb/dist/s_symlink
+++ b/bdb/dist/s_symlink
@@ -28,46 +28,46 @@ build db_stat/tags ../dist/tags
build db_upgrade/tags ../dist/tags
build db_verify/tags ../dist/tags
build dbm/tags ../dist/tags
-build docs_src/api_cxx/Makefile ../api_c/Makefile
-build docs_src/api_cxx/m4.seealso ../api_c/m4.seealso
-build docs_src/api_cxx/spell.ok ../api_c/spell.ok
-build docs_src/api_java/Makefile ../api_c/Makefile
-build docs_src/api_java/java_index.so ../api_cxx/cxx_index.so
-build docs_src/api_java/m4.seealso ../api_c/m4.seealso
-build docs_src/api_java/spell.ok ../api_c/spell.ok
-build docs_src/api_tcl/spell.ok ../api_c/spell.ok
-build docs_src/ref/am/spell.ok ../spell.ok
-build docs_src/ref/am_conf/spell.ok ../spell.ok
-build docs_src/ref/arch/spell.ok ../spell.ok
-build docs_src/ref/build_unix/spell.ok ../spell.ok
-build docs_src/ref/build_vxworks/spell.ok ../spell.ok
-build docs_src/ref/build_win/spell.ok ../spell.ok
-build docs_src/ref/cam/spell.ok ../spell.ok
-build docs_src/ref/debug/spell.ok ../spell.ok
-build docs_src/ref/distrib/spell.ok ../spell.ok
-build docs_src/ref/dumpload/spell.ok ../spell.ok
-build docs_src/ref/env/spell.ok ../spell.ok
-build docs_src/ref/install/spell.ok ../spell.ok
-build docs_src/ref/intro/spell.ok ../spell.ok
-build docs_src/ref/java/spell.ok ../spell.ok
-build docs_src/ref/lock/spell.ok ../spell.ok
-build docs_src/ref/log/spell.ok ../spell.ok
-build docs_src/ref/mp/spell.ok ../spell.ok
-build docs_src/ref/perl/spell.ok ../spell.ok
-build docs_src/ref/program/spell.ok ../spell.ok
-build docs_src/ref/refs/spell.ok ../spell.ok
-build docs_src/ref/rpc/spell.ok ../spell.ok
-build docs_src/ref/sendmail/spell.ok ../spell.ok
-build docs_src/ref/simple_tut/spell.ok ../spell.ok
-build docs_src/ref/tcl/spell.ok ../spell.ok
-build docs_src/ref/test/spell.ok ../spell.ok
-build docs_src/ref/transapp/spell.ok ../spell.ok
-build docs_src/ref/txn/spell.ok ../spell.ok
-build docs_src/ref/upgrade.2.0/spell.ok ../spell.ok
-build docs_src/ref/upgrade.3.0/spell.ok ../spell.ok
-build docs_src/ref/upgrade.3.1/spell.ok ../spell.ok
-build docs_src/ref/upgrade.3.2/spell.ok ../spell.ok
-build docs_src/ref/xa/spell.ok ../spell.ok
+# build docs_src/api_cxx/Makefile ../api_c/Makefile
+# build docs_src/api_cxx/m4.seealso ../api_c/m4.seealso
+# build docs_src/api_cxx/spell.ok ../api_c/spell.ok
+# build docs_src/api_java/Makefile ../api_c/Makefile
+# build docs_src/api_java/java_index.so ../api_cxx/cxx_index.so
+# build docs_src/api_java/m4.seealso ../api_c/m4.seealso
+# build docs_src/api_java/spell.ok ../api_c/spell.ok
+# build docs_src/api_tcl/spell.ok ../api_c/spell.ok
+# build docs_src/ref/am/spell.ok ../spell.ok
+# build docs_src/ref/am_conf/spell.ok ../spell.ok
+# build docs_src/ref/arch/spell.ok ../spell.ok
+# build docs_src/ref/build_unix/spell.ok ../spell.ok
+# build docs_src/ref/build_vxworks/spell.ok ../spell.ok
+# build docs_src/ref/build_win/spell.ok ../spell.ok
+# build docs_src/ref/cam/spell.ok ../spell.ok
+# build docs_src/ref/debug/spell.ok ../spell.ok
+# build docs_src/ref/distrib/spell.ok ../spell.ok
+# build docs_src/ref/dumpload/spell.ok ../spell.ok
+# build docs_src/ref/env/spell.ok ../spell.ok
+# build docs_src/ref/install/spell.ok ../spell.ok
+# build docs_src/ref/intro/spell.ok ../spell.ok
+# build docs_src/ref/java/spell.ok ../spell.ok
+# build docs_src/ref/lock/spell.ok ../spell.ok
+# build docs_src/ref/log/spell.ok ../spell.ok
+# build docs_src/ref/mp/spell.ok ../spell.ok
+# build docs_src/ref/perl/spell.ok ../spell.ok
+# build docs_src/ref/program/spell.ok ../spell.ok
+# build docs_src/ref/refs/spell.ok ../spell.ok
+# build docs_src/ref/rpc/spell.ok ../spell.ok
+# build docs_src/ref/sendmail/spell.ok ../spell.ok
+# build docs_src/ref/simple_tut/spell.ok ../spell.ok
+# build docs_src/ref/tcl/spell.ok ../spell.ok
+# build docs_src/ref/test/spell.ok ../spell.ok
+# build docs_src/ref/transapp/spell.ok ../spell.ok
+# build docs_src/ref/txn/spell.ok ../spell.ok
+# build docs_src/ref/upgrade.2.0/spell.ok ../spell.ok
+# build docs_src/ref/upgrade.3.0/spell.ok ../spell.ok
+# build docs_src/ref/upgrade.3.1/spell.ok ../spell.ok
+# build docs_src/ref/upgrade.3.2/spell.ok ../spell.ok
+# build docs_src/ref/xa/spell.ok ../spell.ok
build env/tags ../dist/tags
build examples_c/tags ../dist/tags
build examples_cxx/tags ../dist/tags
diff --git a/bdb/include/btree_ext.h b/bdb/include/btree_ext.h
deleted file mode 100644
index 8a9866e0b5a..00000000000
--- a/bdb/include/btree_ext.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _btree_ext_h_
-#define _btree_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __bam_cmp __P((DB *, const DBT *, PAGE *,
- u_int32_t, int (*)(DB *, const DBT *, const DBT *), int *));
-int __bam_defcmp __P((DB *, const DBT *, const DBT *));
-size_t __bam_defpfx __P((DB *, const DBT *, const DBT *));
-int __bam_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *));
-int __bam_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *));
-int __bam_mswap __P((PAGE *));
-void __bam_cprint __P((DBC *));
-int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int));
-int __ram_ca_delete __P((DB *, db_pgno_t));
-int __bam_ca_di __P((DBC *, db_pgno_t, u_int32_t, int));
-int __bam_ca_dup __P((DBC *,
- u_int32_t, db_pgno_t, u_int32_t, db_pgno_t, u_int32_t));
-int __bam_ca_undodup __P((DB *,
- u_int32_t, db_pgno_t, u_int32_t, u_int32_t));
-int __bam_ca_rsplit __P((DBC *, db_pgno_t, db_pgno_t));
-int __bam_ca_split __P((DBC *,
- db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, int));
-void __bam_ca_undosplit __P((DB *,
- db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t));
-int __bam_c_init __P((DBC *, DBTYPE));
-int __bam_c_refresh __P((DBC *));
-int __bam_c_count __P((DBC *, db_recno_t *));
-int __bam_c_dup __P((DBC *, DBC *));
-int __bam_c_rget __P((DBC *, DBT *, u_int32_t));
-int __bam_delete __P((DB *, DB_TXN *, DBT *, u_int32_t));
-int __bam_ditem __P((DBC *, PAGE *, u_int32_t));
-int __bam_adjindx __P((DBC *, PAGE *, u_int32_t, u_int32_t, int));
-int __bam_dpages __P((DBC *, EPG *));
-int __bam_db_create __P((DB *));
-int __bam_db_close __P((DB *));
-int __bam_set_flags __P((DB *, u_int32_t *flagsp));
-int __ram_set_flags __P((DB *, u_int32_t *flagsp));
-int __bam_open __P((DB *, const char *, db_pgno_t, u_int32_t));
-int __bam_metachk __P((DB *, const char *, BTMETA *));
-int __bam_read_root __P((DB *, const char *, db_pgno_t, u_int32_t));
-int __bam_iitem __P((DBC *, DBT *, DBT *, u_int32_t, u_int32_t));
-u_int32_t __bam_partsize __P((u_int32_t, DBT *, PAGE *, u_int32_t));
-int __bam_build __P((DBC *, u_int32_t,
- DBT *, PAGE *, u_int32_t, u_int32_t));
-int __bam_ritem __P((DBC *, PAGE *, u_int32_t, DBT *));
-int __bam_pg_alloc_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_pg_free_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_split_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_rsplit_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_adj_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_cadjust_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_cdel_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_repl_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_root_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_curadj_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_rcuradj_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __bam_reclaim __P((DB *, DB_TXN *));
-int __ram_open __P((DB *, const char *, db_pgno_t, u_int32_t));
-int __ram_c_del __P((DBC *));
-int __ram_c_get
- __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
-int __ram_c_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
-int __ram_ca __P((DBC *, ca_recno_arg));
-int __ram_getno __P((DBC *, const DBT *, db_recno_t *, int));
-int __ram_writeback __P((DB *));
-int __bam_rsearch __P((DBC *, db_recno_t *, u_int32_t, int, int *));
-int __bam_adjust __P((DBC *, int32_t));
-int __bam_nrecs __P((DBC *, db_recno_t *));
-db_recno_t __bam_total __P((PAGE *));
-int __bam_search __P((DBC *,
- const DBT *, u_int32_t, int, db_recno_t *, int *));
-int __bam_stkrel __P((DBC *, u_int32_t));
-int __bam_stkgrow __P((DB_ENV *, BTREE_CURSOR *));
-int __bam_split __P((DBC *, void *));
-int __bam_copy __P((DB *, PAGE *, PAGE *, u_int32_t, u_int32_t));
-int __bam_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
-int __bam_traverse __P((DBC *, db_lockmode_t,
- db_pgno_t, int (*)(DB *, PAGE *, void *, int *), void *));
-int __bam_stat_callback __P((DB *, PAGE *, void *, int *));
-int __bam_key_range __P((DB *,
- DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t));
-int __bam_30_btreemeta __P((DB *, char *, u_int8_t *));
-int __bam_31_btreemeta
- __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
-int __bam_31_lbtree
- __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
-int __bam_vrfy_meta __P((DB *, VRFY_DBINFO *, BTMETA *,
- db_pgno_t, u_int32_t));
-int __ram_vrfy_leaf __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
- u_int32_t));
-int __bam_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
- u_int32_t));
-int __bam_vrfy_itemorder __P((DB *, VRFY_DBINFO *, PAGE *,
- db_pgno_t, u_int32_t, int, int, u_int32_t));
-int __bam_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t,
- u_int32_t));
-int __bam_vrfy_subtree __P((DB *, VRFY_DBINFO *, db_pgno_t, void *,
- void *, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *));
-int __bam_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t,
- PAGE *, void *, int (*)(void *, const void *), DBT *,
- u_int32_t));
-int __bam_salvage_walkdupint __P((DB *, VRFY_DBINFO *, PAGE *,
- DBT *, void *, int (*)(void *, const void *), u_int32_t));
-int __bam_meta2pgset __P((DB *, VRFY_DBINFO *, BTMETA *,
- u_int32_t, DB *));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _btree_ext_h_ */
diff --git a/bdb/include/clib_ext.h b/bdb/include/clib_ext.h
deleted file mode 100644
index efd0796afe3..00000000000
--- a/bdb/include/clib_ext.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _clib_ext_h_
-#define _clib_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-#ifndef HAVE_GETCWD
-char *getcwd __P((char *, size_t));
-#endif
-#ifndef HAVE_GETOPT
-int getopt __P((int, char * const *, const char *));
-#endif
-#ifndef HAVE_MEMCMP
-int memcmp __P((const void *, const void *, size_t));
-#endif
-#ifndef HAVE_MEMCPY
-void *memcpy __P((void *, const void *, size_t));
-#endif
-#ifndef HAVE_MEMMOVE
-void *memmove __P((void *, const void *, size_t));
-#endif
-#ifndef HAVE_RAISE
-int raise __P((int));
-#endif
-#ifndef HAVE_SNPRINTF
-int snprintf __P((char *, size_t, const char *, ...));
-#endif
-int strcasecmp __P((const char *, const char *));
-#ifndef HAVE_STRERROR
-char *strerror __P((int));
-#endif
-#ifndef HAVE_VSNPRINTF
-int vsnprintf();
-#endif
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _clib_ext_h_ */
diff --git a/bdb/include/common_ext.h b/bdb/include/common_ext.h
deleted file mode 100644
index a36d62cac4a..00000000000
--- a/bdb/include/common_ext.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _common_ext_h_
-#define _common_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __db_byteorder __P((DB_ENV *, int));
-int __db_fchk __P((DB_ENV *, const char *, u_int32_t, u_int32_t));
-int __db_fcchk
- __P((DB_ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
-int __db_ferr __P((const DB_ENV *, const char *, int));
-int __db_pgerr __P((DB *, db_pgno_t));
-int __db_pgfmt __P((DB *, db_pgno_t));
-int __db_eopnotsup __P((const DB_ENV *));
-#ifdef DIAGNOSTIC
-void __db_assert __P((const char *, const char *, int));
-#endif
-int __db_panic_msg __P((DB_ENV *));
-int __db_panic __P((DB_ENV *, int));
-void __db_err __P((const DB_ENV *, const char *, ...));
-void __db_real_err
- __P((const DB_ENV *, int, int, int, const char *, va_list));
-void __db_logmsg __P((const DB_ENV *,
- DB_TXN *, const char *, u_int32_t, const char *, ...));
-void __db_real_log __P((const DB_ENV *,
- DB_TXN *, const char *, u_int32_t, const char *, va_list ap));
-int __db_unknown_flag __P((DB_ENV *, char *, u_int32_t));
-int __db_unknown_type __P((DB_ENV *, char *, u_int32_t));
-#ifdef DIAGNOSTIC
-int __db_missing_txn_err __P((DB_ENV *));
-#endif
-int __db_getlong
- __P((DB *, const char *, char *, long, long, long *));
-int __db_getulong
- __P((DB *, const char *, char *, u_long, u_long, u_long *));
-u_int32_t __db_log2 __P((u_int32_t));
-int __db_util_logset __P((const char *, char *));
-void __db_util_siginit __P((void));
-int __db_util_interrupted __P((void));
-void __db_util_sigresend __P((void));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _common_ext_h_ */
diff --git a/bdb/include/env_ext.h b/bdb/include/env_ext.h
deleted file mode 100644
index 0e7313fde9d..00000000000
--- a/bdb/include/env_ext.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _env_ext_h_
-#define _env_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-void __db_shalloc_init __P((void *, size_t));
-int __db_shalloc_size __P((size_t, size_t));
-int __db_shalloc __P((void *, size_t, size_t, void *));
-void __db_shalloc_free __P((void *, void *));
-size_t __db_shalloc_count __P((void *));
-size_t __db_shsizeof __P((void *));
-void __db_shalloc_dump __P((void *, FILE *));
-int __db_tablesize __P((u_int32_t));
-void __db_hashinit __P((void *, u_int32_t));
-int __dbenv_init __P((DB_ENV *));
-int __db_mi_env __P((DB_ENV *, const char *));
-int __db_mi_open __P((DB_ENV *, const char *, int));
-int __db_env_config __P((DB_ENV *, int));
-int __dbenv_open __P((DB_ENV *, const char *, u_int32_t, int));
-int __dbenv_remove __P((DB_ENV *, const char *, u_int32_t));
-int __dbenv_close __P((DB_ENV *, u_int32_t));
-int __db_appname __P((DB_ENV *, APPNAME,
- const char *, const char *, u_int32_t, DB_FH *, char **));
-int __db_apprec __P((DB_ENV *, u_int32_t));
-int __db_e_attach __P((DB_ENV *, u_int32_t *));
-int __db_e_detach __P((DB_ENV *, int));
-int __db_e_remove __P((DB_ENV *, int));
-int __db_e_stat __P((DB_ENV *, REGENV *, REGION *, int *));
-int __db_r_attach __P((DB_ENV *, REGINFO *, size_t));
-int __db_r_detach __P((DB_ENV *, REGINFO *, int));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _env_ext_h_ */
diff --git a/bdb/include/hash_ext.h b/bdb/include/hash_ext.h
deleted file mode 100644
index babb77a7902..00000000000
--- a/bdb/include/hash_ext.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _hash_ext_h_
-#define _hash_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __ham_metachk __P((DB *, const char *, HMETA *));
-int __ham_open __P((DB *, const char *, db_pgno_t, u_int32_t));
-int __ham_c_init __P((DBC *));
-int __ham_c_count __P((DBC *, db_recno_t *));
-int __ham_c_dup __P((DBC *, DBC *));
-u_int32_t __ham_call_hash __P((DBC *, u_int8_t *, int32_t));
-int __ham_init_dbt __P((DB_ENV *,
- DBT *, u_int32_t, void **, u_int32_t *));
-int __ham_c_update
- __P((DBC *, u_int32_t, int, int));
-int __ham_get_clist __P((DB *,
- db_pgno_t, u_int32_t, DBC ***));
-int __ham_c_chgpg
- __P((DBC *, db_pgno_t, u_int32_t, db_pgno_t, u_int32_t));
-int __ham_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *));
-int __ham_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *));
-int __ham_mswap __P((void *));
-int __ham_add_dup __P((DBC *, DBT *, u_int32_t, db_pgno_t *));
-int __ham_dup_convert __P((DBC *));
-int __ham_make_dup __P((DB_ENV *,
- const DBT *, DBT *d, void **, u_int32_t *));
-void __ham_move_offpage __P((DBC *, PAGE *, u_int32_t, db_pgno_t));
-void __ham_dsearch __P((DBC *, DBT *, u_int32_t *, int *));
-int __ham_cprint __P((DB *));
-u_int32_t __ham_func2 __P((DB *, const void *, u_int32_t));
-u_int32_t __ham_func3 __P((DB *, const void *, u_int32_t));
-u_int32_t __ham_func4 __P((DB *, const void *, u_int32_t));
-u_int32_t __ham_func5 __P((DB *, const void *, u_int32_t));
-int __ham_get_meta __P((DBC *));
-int __ham_release_meta __P((DBC *));
-int __ham_dirty_meta __P((DBC *));
-int __ham_db_create __P((DB *));
-int __ham_db_close __P((DB *));
-int __ham_item __P((DBC *, db_lockmode_t, db_pgno_t *));
-int __ham_item_reset __P((DBC *));
-void __ham_item_init __P((DBC *));
-int __ham_item_last __P((DBC *, db_lockmode_t, db_pgno_t *));
-int __ham_item_first __P((DBC *, db_lockmode_t, db_pgno_t *));
-int __ham_item_prev __P((DBC *, db_lockmode_t, db_pgno_t *));
-int __ham_item_next __P((DBC *, db_lockmode_t, db_pgno_t *));
-void __ham_putitem __P((PAGE *p, const DBT *, int));
-void __ham_reputpair
- __P((PAGE *p, u_int32_t, u_int32_t, const DBT *, const DBT *));
-int __ham_del_pair __P((DBC *, int));
-int __ham_replpair __P((DBC *, DBT *, u_int32_t));
-void __ham_onpage_replace __P((PAGE *, size_t, u_int32_t, int32_t,
- int32_t, DBT *));
-int __ham_split_page __P((DBC *, u_int32_t, u_int32_t));
-int __ham_add_el __P((DBC *, const DBT *, const DBT *, int));
-void __ham_copy_item __P((size_t, PAGE *, u_int32_t, PAGE *));
-int __ham_add_ovflpage __P((DBC *, PAGE *, int, PAGE **));
-int __ham_get_cpage __P((DBC *, db_lockmode_t));
-int __ham_next_cpage __P((DBC *, db_pgno_t, int));
-int __ham_lock_bucket __P((DBC *, db_lockmode_t));
-void __ham_dpair __P((DB *, PAGE *, u_int32_t));
-int __ham_insdel_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_newpage_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_replace_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_splitdata_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_copypage_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_metagroup_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_groupalloc_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_curadj_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_chgpg_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __ham_reclaim __P((DB *, DB_TXN *txn));
-int __ham_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
- int __ham_traverse __P((DB *, DBC *, db_lockmode_t,
- int (*)(DB *, PAGE *, void *, int *), void *));
-int __ham_30_hashmeta __P((DB *, char *, u_int8_t *));
-int __ham_30_sizefix __P((DB *, DB_FH *, char *, u_int8_t *));
-int __ham_31_hashmeta
- __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
-int __ham_31_hash
- __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
-int __ham_vrfy_meta __P((DB *, VRFY_DBINFO *, HMETA *,
- db_pgno_t, u_int32_t));
-int __ham_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
- u_int32_t));
-int __ham_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t,
- u_int32_t));
-int __ham_vrfy_hashing __P((DB *,
- u_int32_t, HMETA *, u_int32_t, db_pgno_t, u_int32_t,
- u_int32_t (*) __P((DB *, const void *, u_int32_t))));
-int __ham_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *,
- void *, int (*)(void *, const void *), u_int32_t));
-int __ham_meta2pgset __P((DB *, VRFY_DBINFO *, HMETA *, u_int32_t,
- DB *));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _hash_ext_h_ */
diff --git a/bdb/include/lock_ext.h b/bdb/include/lock_ext.h
deleted file mode 100644
index 7ed9b1c695b..00000000000
--- a/bdb/include/lock_ext.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _lock_ext_h_
-#define _lock_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __lock_downgrade __P((DB_ENV *,
- DB_LOCK *, db_lockmode_t, u_int32_t));
-int __lock_addfamilylocker __P((DB_ENV *, u_int32_t, u_int32_t));
-int __lock_freefamilylocker __P((DB_LOCKTAB *, u_int32_t));
-void __lock_freelocker __P((DB_LOCKTAB *,
- DB_LOCKREGION *, DB_LOCKER *, u_int32_t));
-int __lock_getlocker __P((DB_LOCKTAB *,
- u_int32_t, u_int32_t, int, DB_LOCKER **));
-int __lock_getobj __P((DB_LOCKTAB *,
- const DBT *, u_int32_t, int, DB_LOCKOBJ **));
-int __lock_promote __P((DB_LOCKTAB *, DB_LOCKOBJ *, int));
-void __lock_printlock __P((DB_LOCKTAB *, struct __db_lock *, int));
-int __lock_set_lk_conflicts __P((DB_ENV *, u_int8_t *, int));
-int __lock_set_lk_detect __P((DB_ENV *, u_int32_t));
-int __lock_set_lk_max __P((DB_ENV *, u_int32_t));
-int __lock_set_lk_max_locks __P((DB_ENV *, u_int32_t));
-int __lock_set_lk_max_lockers __P((DB_ENV *, u_int32_t));
-int __lock_set_lk_max_objects __P((DB_ENV *, u_int32_t));
-void __lock_dbenv_create __P((DB_ENV *));
-void __lock_dbenv_close __P((DB_ENV *));
-int __lock_open __P((DB_ENV *));
-int __lock_close __P((DB_ENV *));
-void __lock_region_destroy __P((DB_ENV *, REGINFO *));
-void __lock_dump_region __P((DB_ENV *, char *, FILE *));
-int __lock_cmp __P((const DBT *, DB_LOCKOBJ *));
-int __lock_locker_cmp __P((u_int32_t, DB_LOCKER *));
-u_int32_t __lock_ohash __P((const DBT *));
-u_int32_t __lock_lhash __P((DB_LOCKOBJ *));
-u_int32_t __lock_locker_hash __P((u_int32_t));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _lock_ext_h_ */
diff --git a/bdb/include/log_ext.h b/bdb/include/log_ext.h
deleted file mode 100644
index 985c5d7745b..00000000000
--- a/bdb/include/log_ext.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _log_ext_h_
-#define _log_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __log_open __P((DB_ENV *));
-int __log_find __P((DB_LOG *, int, int *, logfile_validity *));
-int __log_valid __P((DB_LOG *, u_int32_t, int, logfile_validity *));
-int __log_close __P((DB_ENV *));
-int __log_lastckp __P((DB_ENV *, DB_LSN *));
-int __log_findckp __P((DB_ENV *, DB_LSN *));
-int __log_get __P((DB_LOG *, DB_LSN *, DBT *, u_int32_t, int));
-void __log_dbenv_create __P((DB_ENV *));
-int __log_put __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t));
-int __log_name __P((DB_LOG *,
- u_int32_t, char **, DB_FH *, u_int32_t));
-int __log_register_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __log_reopen_file __P((DB_ENV *,
- char *, int32_t, u_int8_t *, db_pgno_t));
-int __log_add_logid __P((DB_ENV *, DB_LOG *, DB *, int32_t));
-int __db_fileid_to_db __P((DB_ENV *, DB **, int32_t, int));
-void __log_close_files __P((DB_ENV *));
-void __log_rem_logid __P((DB_LOG *, DB *, int32_t));
-int __log_lid_to_fname __P((DB_LOG *, int32_t, FNAME **));
-int __log_filelist_update
- __P((DB_ENV *, DB *, int32_t, const char *, int *));
-int __log_file_lock __P((DB *));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _log_ext_h_ */
diff --git a/bdb/include/mp_ext.h b/bdb/include/mp_ext.h
deleted file mode 100644
index 9f2b8c61f45..00000000000
--- a/bdb/include/mp_ext.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _mp_ext_h_
-#define _mp_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __memp_alloc __P((DB_MPOOL *,
- REGINFO *, MPOOLFILE *, size_t, roff_t *, void *));
-int __memp_bhwrite
- __P((DB_MPOOL *, MPOOLFILE *, BH *, int *, int *));
-int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
-int __memp_pgwrite
- __P((DB_MPOOL *, DB_MPOOLFILE *, BH *, int *, int *));
-int __memp_pg __P((DB_MPOOLFILE *, BH *, int));
-void __memp_bhfree __P((DB_MPOOL *, BH *, int));
-void __memp_set_unlink __P((DB_MPOOLFILE *));
-void __memp_clear_unlink __P((DB_MPOOLFILE *));
-int __memp_fopen __P((DB_MPOOL *, MPOOLFILE *, const char *,
- u_int32_t, int, size_t, int, DB_MPOOL_FINFO *, DB_MPOOLFILE **));
-void __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *));
-int __memp_fremove __P((DB_MPOOLFILE *));
-char * __memp_fn __P((DB_MPOOLFILE *));
-char * __memp_fns __P((DB_MPOOL *, MPOOLFILE *));
-void __memp_dbenv_create __P((DB_ENV *));
-int __memp_open __P((DB_ENV *));
-int __memp_close __P((DB_ENV *));
-void __mpool_region_destroy __P((DB_ENV *, REGINFO *));
-void __memp_dump_region __P((DB_ENV *, char *, FILE *));
-int __mp_xxx_fh __P((DB_MPOOLFILE *, DB_FH **));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _mp_ext_h_ */
diff --git a/bdb/include/os_ext.h b/bdb/include/os_ext.h
deleted file mode 100644
index ae9e3d304f2..00000000000
--- a/bdb/include/os_ext.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _os_ext_h_
-#define _os_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __os_abspath __P((const char *));
-int __os_strdup __P((DB_ENV *, const char *, void *));
-int __os_calloc __P((DB_ENV *, size_t, size_t, void *));
-int __os_malloc __P((DB_ENV *, size_t, void *(*)(size_t), void *));
-int __os_realloc __P((DB_ENV *,
- size_t, void *(*)(void *, size_t), void *));
-void __os_free __P((void *, size_t));
-void __os_freestr __P((void *));
-void *__ua_memcpy __P((void *, const void *, size_t));
-int __os_dirlist __P((DB_ENV *, const char *, char ***, int *));
-void __os_dirfree __P((char **, int));
-int __os_get_errno __P((void));
-void __os_set_errno __P((int));
-int __os_fileid __P((DB_ENV *, const char *, int, u_int8_t *));
-int __os_finit __P((DB_ENV *, DB_FH *, size_t, int));
-int __os_fpinit __P((DB_ENV *, DB_FH *, db_pgno_t, int, int));
-int __os_fsync __P((DB_ENV *, DB_FH *));
-int __os_openhandle __P((DB_ENV *, const char *, int, int, DB_FH *));
-int __os_closehandle __P((DB_FH *));
-int __os_r_sysattach __P((DB_ENV *, REGINFO *, REGION *));
-int __os_r_sysdetach __P((DB_ENV *, REGINFO *, int));
-int __os_mapfile __P((DB_ENV *,
- char *, DB_FH *, size_t, int, void **));
-int __os_unmapfile __P((DB_ENV *, void *, size_t));
-u_int32_t __db_oflags __P((int));
-int __db_omode __P((const char *));
-int __os_open __P((DB_ENV *, const char *, u_int32_t, int, DB_FH *));
-int __os_shmname __P((DB_ENV *, const char *, char **));
-int __os_r_attach __P((DB_ENV *, REGINFO *, REGION *));
-int __os_r_detach __P((DB_ENV *, REGINFO *, int));
-int __os_rename __P((DB_ENV *, const char *, const char *));
-int __os_isroot __P((void));
-char *__db_rpath __P((const char *));
-int __os_io __P((DB_ENV *, DB_IO *, int, size_t *));
-int __os_read __P((DB_ENV *, DB_FH *, void *, size_t, size_t *));
-int __os_write __P((DB_ENV *, DB_FH *, void *, size_t, size_t *));
-int __os_seek __P((DB_ENV *,
- DB_FH *, size_t, db_pgno_t, u_int32_t, int, DB_OS_SEEK));
-int __os_sleep __P((DB_ENV *, u_long, u_long));
-int __os_spin __P((void));
-void __os_yield __P((DB_ENV*, u_long));
-int __os_exists __P((const char *, int *));
-int __os_ioinfo __P((DB_ENV *, const char *,
- DB_FH *, u_int32_t *, u_int32_t *, u_int32_t *));
-int __os_tmpdir __P((DB_ENV *, u_int32_t));
-int __os_unlink __P((DB_ENV *, const char *));
-int __os_region_unlink __P((DB_ENV *, const char *));
-#if defined(DB_WIN32)
-int __os_win32_errno __P((void));
-#endif
-int __os_fpinit __P((DB_ENV *, DB_FH *, db_pgno_t, int, int));
-int __os_is_winnt __P((void));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _os_ext_h_ */
diff --git a/bdb/include/qam_ext.h b/bdb/include/qam_ext.h
deleted file mode 100644
index f6e95110c0e..00000000000
--- a/bdb/include/qam_ext.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _qam_ext_h_
-#define _qam_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __qam_position
- __P((DBC *, db_recno_t *, qam_position_mode, int *));
-int __qam_pitem
- __P((DBC *, QPAGE *, u_int32_t, db_recno_t, DBT *));
-int __qam_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
-int __qam_delete __P((DB *, DB_TXN *, DBT *, u_int32_t));
-int __qam_c_dup __P((DBC *, DBC *));
-int __qam_c_init __P((DBC *));
-int __qam_mswap __P((PAGE *));
-int __qam_pgin_out __P((DB_ENV *, db_pgno_t, void *, DBT *));
-int __qam_fprobe __P((DB *, db_pgno_t, void *, qam_probe_mode, int));
-int __qam_fclose __P((DB *, db_pgno_t));
-int __qam_fremove __P((DB *, db_pgno_t));
-int __qam_sync __P((DB *, u_int32_t));
-int __qam_gen_filelist __P(( DB *, QUEUE_FILELIST **));
-int __qam_db_create __P((DB *));
-int __qam_db_close __P((DB *));
-int __db_prqueue __P((DB *, u_int32_t));
-int __qam_remove __P((DB *, const char *,
- const char *, DB_LSN *, int (**)(DB *, void*), void **));
-int __qam_rename __P((DB *,
- const char *, const char *, const char *));
-int __qam_open __P((DB *, const char *, db_pgno_t, int, u_int32_t));
-int __qam_metachk __P((DB *, const char *, QMETA *));
-int __qam_inc_recover __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_incfirst_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_mvptr_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_del_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_delext_recover __P((DB_ENV *,
- DBT *, DB_LSN *, db_recops, void *));
-int __qam_add_recover __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_delete_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_rename_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __qam_stat __P((DB *, void *, void *(*)(size_t), u_int32_t));
-int __qam_31_qammeta __P((DB *, char *, u_int8_t *));
-int __qam_32_qammeta __P((DB *, char *, u_int8_t *));
-int __qam_vrfy_meta __P((DB *, VRFY_DBINFO *, QMETA *,
- db_pgno_t, u_int32_t));
-int __qam_vrfy_data __P((DB *, VRFY_DBINFO *, QPAGE *,
- db_pgno_t, u_int32_t));
-int __qam_vrfy_structure __P((DB *, VRFY_DBINFO *, u_int32_t));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _qam_ext_h_ */
diff --git a/bdb/include/tcl_ext.h b/bdb/include/tcl_ext.h
deleted file mode 100644
index 9baf7e4fdcf..00000000000
--- a/bdb/include/tcl_ext.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _tcl_ext_h_
-#define _tcl_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int bdb_HCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-#if DB_DBM_HSEARCH != 0
-int bdb_NdbmOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBM **));
-#endif
-#if DB_DBM_HSEARCH != 0
-int bdb_DbmCommand
- __P((Tcl_Interp *, int, Tcl_Obj * CONST*, int, DBM *));
-#endif
-int ndbm_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-int bdb_RandCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
-int tcl_Mutex __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *,
- DBTCL_INFO *));
-int db_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-int dbc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-int env_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-int tcl_EnvRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*,
- DB_ENV *, DBTCL_INFO *));
-int tcl_EnvVerbose __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *,
- Tcl_Obj *));
-int tcl_EnvTest __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-DBTCL_INFO *_NewInfo __P((Tcl_Interp *,
- void *, char *, enum INFOTYPE));
-void *_NameToPtr __P((CONST char *));
-char *_PtrToName __P((CONST void *));
-DBTCL_INFO *_PtrToInfo __P((CONST void *));
-DBTCL_INFO *_NameToInfo __P((CONST char *));
-void _SetInfoData __P((DBTCL_INFO *, void *));
-void _DeleteInfo __P((DBTCL_INFO *));
-int _SetListElem __P((Tcl_Interp *,
- Tcl_Obj *, void *, int, void *, int));
-int _SetListElemInt __P((Tcl_Interp *, Tcl_Obj *, void *, int));
-int _SetListRecnoElem __P((Tcl_Interp *, Tcl_Obj *,
- db_recno_t, u_char *, int));
-int _GetGlobPrefix __P((char *, char **));
-int _ReturnSetup __P((Tcl_Interp *, int, char *));
-int _ErrorSetup __P((Tcl_Interp *, int, char *));
-void _ErrorFunc __P((CONST char *, char *));
-int _GetLsn __P((Tcl_Interp *, Tcl_Obj *, DB_LSN *));
-void _debug_check __P((void));
-int tcl_LockDetect __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LockGet __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LockStat __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LockVec __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogArchive __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogCompare __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*));
-int tcl_LogFile __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogFlush __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogGet __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogPut __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogRegister __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogStat __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_LogUnregister __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-void _MpInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
-int tcl_MpSync __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-int tcl_MpTrickle __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_Mp __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
-int tcl_MpStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
-void _TxnInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
-int tcl_TxnCheckpoint __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int tcl_Txn __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
-int tcl_TxnStat __P((Tcl_Interp *, int,
- Tcl_Obj * CONST*, DB_ENV *));
-int txn_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _tcl_ext_h_ */
diff --git a/bdb/include/txn_ext.h b/bdb/include/txn_ext.h
deleted file mode 100644
index ee6922d701c..00000000000
--- a/bdb/include/txn_ext.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _txn_ext_h_
-#define _txn_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __txn_xa_begin __P((DB_ENV *, DB_TXN *));
-int __txn_end __P((DB_TXN *, int));
-int __txn_activekids __P((DB_ENV *, u_int32_t, DB_TXN *));
-int __txn_regop_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __txn_xa_regop_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __txn_ckp_recover
-__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-int __txn_child_recover
- __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
-void __txn_dbenv_create __P((DB_ENV *));
-int __txn_open __P((DB_ENV *));
-int __txn_close __P((DB_ENV *));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _txn_ext_h_ */
diff --git a/bdb/include/xa_ext.h b/bdb/include/xa_ext.h
deleted file mode 100644
index cc16ba18337..00000000000
--- a/bdb/include/xa_ext.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef _xa_ext_h_
-#define _xa_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __db_xa_create __P((DB *));
-int __db_rmid_to_env __P((int rmid, DB_ENV **envp));
-int __db_xid_to_txn __P((DB_ENV *, XID *, size_t *));
-int __db_map_rmid __P((int, DB_ENV *));
-int __db_unmap_rmid __P((int));
-int __db_map_xid __P((DB_ENV *, XID *, size_t));
-void __db_unmap_xid __P((DB_ENV *, XID *, size_t));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _xa_ext_h_ */
diff --git a/bdb/os/os_handle.c b/bdb/os/os_handle.c
index b127c5ff506..d85b13a6602 100644
--- a/bdb/os/os_handle.c
+++ b/bdb/os/os_handle.c
@@ -121,7 +121,7 @@ __os_openhandle(dbenv, name, flags, mode, fhp)
} else {
#if defined(HAVE_FCNTL_F_SETFD)
/* Deny file descriptor access to any child process. */
- if (fcntl(fhp->fd, F_SETFD, 1) == -1) {
+ if (fcntl(fhp->fd, F_SETFD, FD_CLOEXEC) == -1) {
ret = __os_get_errno();
__db_err(dbenv, "fcntl(F_SETFD): %s",
strerror(ret));
diff --git a/build-tags b/build-tags
deleted file mode 100755
index 90b957eb3bc..00000000000
--- a/build-tags
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /bin/sh
-
-if [ ! -f configure.in ] ; then
- echo "$0 must be run from MySQL source root"
- exit 1
-fi
-
-rm -f TAGS
-find -not -path \*SCCS\* -and \
- \( -name \*.cc -or -name \*.h -or -name \*.yy -or -name \*.c \) \
- -print -exec etags -o TAGS --append {} \;
diff --git a/client/Makefile.am b/client/Makefile.am
index 1710e573d20..9c994814714 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -18,11 +18,11 @@
INCLUDES = -I$(srcdir)/../include \
-I../include -I$(srcdir)/.. -I$(top_srcdir) \
- -I..
+ -I.. $(openssl_includes)
LIBS = @CLIENT_LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la
bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \
- mysqldump mysqlimport mysqltest mysqlbinlog
+ mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen
noinst_PROGRAMS = insert_test select_test thread_test
noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \
client_priv.h
@@ -41,6 +41,8 @@ mysqltest_SOURCES= mysqltest.c
mysqltest_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqlbinlog_SOURCES = mysqlbinlog.cc
mysqlbinlog_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
+mysqlmanagerc_SOURCES = mysqlmanagerc.c
+mysqlmanagerc_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
sql_src=log_event.h log_event.cc
# Fix for mit-threads
diff --git a/client/client_priv.h b/client/client_priv.h
index 147670005f2..5029f219494 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -1,34 +1,41 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Common defines for all clients */
-#include <global.h>
-#include <my_sys.h>
+#include <my_global.h>
+#include <my_sys.h>
#include <m_string.h>
#include <mysql.h>
+#include <mysql_embed.h>
#include <errmsg.h>
-#include <getopt.h>
+#include <my_getopt.h>
/* We have to define 'enum options' identical in all files to keep OS2 happy */
-enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
+enum options_client { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE,
OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS,
OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE,
OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES,
- OPT_MASTER_DATA, OPT_AUTOCOMMIT, OPT_LOCAL_INFILE,
- OPT_DELETE_MASTER_LOGS};
+ OPT_MASTER_DATA, OPT_AUTOCOMMIT, OPT_AUTO_REHASH,
+ OPT_LINE_NUMBERS, OPT_COLUMN_NAMES, OPT_CONNECT_TIMEOUT,
+ OPT_MAX_ALLOWED_PACKET, OPT_NET_BUFFER_LENGTH,
+ OPT_SELECT_LIMIT, OPT_MAX_JOIN_SIZE, OPT_SSL_SSL,
+ OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
+ OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE,
+ OPT_DELETE_MASTER_LOGS,
+ OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION, OPT_FRM };
diff --git a/client/completion_hash.cc b/client/completion_hash.cc
index 006427f0295..ff5d0b28e41 100644
--- a/client/completion_hash.cc
+++ b/client/completion_hash.cc
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Quick & light hash implementation for tab completion purposes
*
@@ -22,7 +21,7 @@
* Small portability changes by Monty. Changed also to use my_malloc/my_free
*/
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#undef SAFEMALLOC // Speed things up
#include <my_sys.h>
@@ -47,10 +46,12 @@ int completion_hash_init(HashTable *ht, uint nSize)
ht->arBuckets = (Bucket **) my_malloc(nSize* sizeof(Bucket *),
MYF(MY_ZEROFILL | MY_WME));
- if (!ht->arBuckets) {
+ if (!ht->arBuckets)
+ {
ht->initialized = 0;
return FAILURE;
}
+ init_alloc_root(&ht->mem_root, 8192, 0);
ht->pHashFunction = hashpjw;
ht->nTableSize = nSize;
ht->initialized = 1;
@@ -78,8 +79,7 @@ int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength,
if (!memcmp(p->arKey, arKey, nKeyLength)) {
entry *n;
- n = (entry *) my_malloc(sizeof(entry),
- MYF(MY_WME));
+ n = (entry *) alloc_root(&ht->mem_root,sizeof(entry));
n->pNext = p->pData;
n->str = str;
p->pData = n;
@@ -91,20 +91,16 @@ int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength,
p = p->pNext;
}
- p = (Bucket *) my_malloc(sizeof(Bucket),MYF(MY_WME));
-
- if (!p) {
+ if (!(p = (Bucket *) alloc_root(&ht->mem_root, sizeof(Bucket))))
return FAILURE;
- }
+
p->arKey = arKey;
p->nKeyLength = nKeyLength;
p->h = h;
- p->pData = (entry*) my_malloc(sizeof(entry),MYF(MY_WME));
- if (!p->pData) {
- my_free((gptr) p,MYF(0));
+ if (!(p->pData = (entry*) alloc_root(&ht->mem_root, sizeof(entry))))
return FAILURE;
- }
+
p->pData->str = str;
p->pData->pNext = 0;
p->count = 1;
@@ -209,24 +205,7 @@ Bucket *find_longest_match(HashTable *ht, char *str, uint length,
void completion_hash_clean(HashTable *ht)
{
- uint i;
- entry *e, *t;
- Bucket *b, *tmp;
-
- for (i=0; i<ht->nTableSize; i++) {
- b = ht->arBuckets[i];
- while (b) {
- e = b->pData;
- while (e) {
- t = e;
- e = e->pNext;
- my_free((gptr) t,MYF(0));
- }
- tmp = b;
- b = b->pNext;
- my_free((gptr) tmp,MYF(0));
- }
- }
+ free_root(&ht->mem_root,MYF(0));
bzero((char*) ht->arBuckets,ht->nTableSize*sizeof(Bucket *));
}
@@ -241,9 +220,7 @@ void completion_hash_free(HashTable *ht)
void add_word(HashTable *ht,char *str)
{
int i;
- int length= (int) strlen(str);
-
- for (i=1; i<=length; i++) {
+ char *pos=str;
+ for (i=1; *pos; i++, pos++)
completion_hash_update(ht, str, i, str);
- }
}
diff --git a/client/completion_hash.h b/client/completion_hash.h
index 583a42bbbe5..c0853fddfe7 100644
--- a/client/completion_hash.h
+++ b/client/completion_hash.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
-
+
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
-
+
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -22,26 +22,29 @@
#define FAILURE 1
#include <sys/types.h>
+#include <my_sys.h>
typedef struct _entry {
char *str;
struct _entry *pNext;
} entry;
-typedef struct bucket {
- uint h; /* Used for numeric indexing */
- char *arKey;
- uint nKeyLength;
- uint count;
- entry *pData;
- struct bucket *pNext;
+typedef struct bucket
+{
+ uint h; /* Used for numeric indexing */
+ char *arKey;
+ uint nKeyLength;
+ uint count;
+ entry *pData;
+ struct bucket *pNext;
} Bucket;
typedef struct hashtable {
- uint nTableSize;
- uint initialized;
- uint(*pHashFunction) (char *arKey, uint nKeyLength);
- Bucket **arBuckets;
+ uint nTableSize;
+ uint initialized;
+ MEM_ROOT mem_root;
+ uint(*pHashFunction) (char *arKey, uint nKeyLength);
+ Bucket **arBuckets;
} HashTable;
extern int completion_hash_init(HashTable *ht, uint nSize);
@@ -54,4 +57,4 @@ extern void completion_hash_clean(HashTable *ht);
extern int completion_hash_exists(HashTable *ht, char *arKey, uint nKeyLength);
extern void completion_hash_free(HashTable *ht);
-#endif /* _HASH_ */
+#endif /* _HASH_ */
diff --git a/client/connect_test.c b/client/connect_test.c
index 661d448fdb0..fd81ad635ad 100644
--- a/client/connect_test.c
+++ b/client/connect_test.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <stdlib.h>
diff --git a/client/errmsg.c b/client/errmsg.c
deleted file mode 100644
index 67cfe874f77..00000000000
--- a/client/errmsg.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* Error messages for MySQL clients */
-/* error messages for the demon is in share/language/errmsg.sys */
-
-#include <global.h>
-#include <my_sys.h>
-#include "errmsg.h"
-
-#ifdef GERMAN
-const char *client_errors[]=
-{
- "Unbekannter MySQL Fehler",
- "Kann UNIX-Socket nicht anlegen (%d)",
- "Keine Verbindung zu lokalem MySQL Server, socket: '%-.64s' (%d)",
- "Keine Verbindung zu MySQL Server auf %-.64s (%d)",
- "Kann TCP/IP-Socket nicht anlegen (%d)",
- "Unbekannter MySQL Server Host (%-.64s) (%d)",
- "MySQL Server nicht vorhanden",
- "Protokolle ungleich. Server Version = % d Client Version = %d",
- "MySQL client got out of memory",
- "Wrong host info",
- "Localhost via UNIX socket",
- "%-.64s via TCP/IP",
- "Error in server handshake",
- "Lost connection to MySQL server during query",
- "Commands out of sync; You can't run this command now",
- "Verbindung ueber Named Pipe; Host: %-.64s",
- "Kann nicht auf Named Pipe warten. Host: %-.64s pipe: %-.32s (%lu)",
- "Kann Named Pipe nicht oeffnen. Host: %-.64s pipe: %-.32s (%lu)",
- "Kann den Status der Named Pipe nicht setzen. Host: %-.64s pipe: %-.32s (%lu)",
- "Can't initialize character set %-.64s (path: %-.64s)",
- "Got packet bigger than 'max_allowed_packet'"
-};
-
-/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
-
-#elif defined PORTUGUESE
-const char *client_errors[]=
-{
- "Erro desconhecido do MySQL",
- "Não pode criar 'UNIX socket' (%d)",
- "Não pode se conectar ao servidor MySQL local através do 'socket' '%-.64s' (%d)",
- "Não pode se conectar ao servidor MySQL em '%-.64s' (%d)",
- "Não pode criar 'socket TCP/IP' (%d)",
- "'Host' servidor MySQL '%-.64s' (%d) desconhecido",
- "Servidor MySQL desapareceu",
- "Incompatibilidade de protocolos. Versão do Servidor: %d - Versão do Cliente: %d",
- "Cliente do MySQL com falta de memória",
- "Informação inválida de 'host'",
- "Localhost via 'UNIX socket'",
- "%-.64s via 'TCP/IP'",
- "Erro na negociação de acesso ao servidor",
- "Conexão perdida com servidor MySQL durante 'query'",
- "Comandos fora de sincronismo. Você não pode executar este comando agora",
- "%-.64s via 'named pipe'",
- "Não pode esperar pelo 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
- "Não pode abrir 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
- "Não pode estabelecer o estado do 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
- "Não pode inicializar conjunto de caracteres %-.64s (caminho %-.64s)",
- "Obteve pacote maior do que 'max_allowed_packet'"
-};
-
-#else /* ENGLISH */
-const char *client_errors[]=
-{
- "Unknown MySQL error",
- "Can't create UNIX socket (%d)",
- "Can't connect to local MySQL server through socket '%-.64s' (%d)",
- "Can't connect to MySQL server on '%-.64s' (%d)",
- "Can't create TCP/IP socket (%d)",
- "Unknown MySQL Server Host '%-.64s' (%d)",
- "MySQL server has gone away",
- "Protocol mismatch. Server Version = %d Client Version = %d",
- "MySQL client run out of memory",
- "Wrong host info",
- "Localhost via UNIX socket",
- "%-.64s via TCP/IP",
- "Error in server handshake",
- "Lost connection to MySQL server during query",
- "Commands out of sync; You can't run this command now",
- "%-.64s via named pipe",
- "Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)",
- "Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
- "Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
- "Can't initialize character set %-.64s (path: %-.64s)",
- "Got packet bigger than 'max_allowed_packet'"
-};
-#endif
-
-
-void init_client_errs(void)
-{
- my_errmsg[CLIENT_ERRMAP] = &client_errors[0];
-}
diff --git a/client/get_password.c b/client/get_password.c
index 25069a14b75..5d78656ab0a 100644
--- a/client/get_password.c
+++ b/client/get_password.c
@@ -1,25 +1,24 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
** Ask for a password from tty
** This is an own file to avoid conflicts with curses
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "mysql.h"
#include <m_string.h>
@@ -72,7 +71,7 @@ char *get_tty_password(char *opt_message)
char *pos=to,*end=to+sizeof(to)-1;
int i=0;
DBUG_ENTER("get_tty_password");
- fprintf(stdout,opt_message ? opt_message : "Enter password: ");
+ _cputs(opt_message ? opt_message : "Enter password: ");
for (;;)
{
char tmp;
@@ -125,8 +124,8 @@ static void get_password(char *to,uint length,int fd,bool echo)
{
if (echo)
{
- fputs("\b \b",stdout);
- fflush(stdout);
+ fputs("\b \b",stderr);
+ fflush(stderr);
}
pos--;
continue;
@@ -138,8 +137,8 @@ static void get_password(char *to,uint length,int fd,bool echo)
continue;
if (echo)
{
- fputc('*',stdout);
- fflush(stdout);
+ fputc('*',stderr);
+ fflush(stderr);
}
*(pos++) = tmp;
}
@@ -172,10 +171,10 @@ char *get_tty_password(char *opt_message)
memset(passbuff, 0, _PASSWORD_LEN);
#endif
#else
- if (isatty(fileno(stdout)))
+ if (isatty(fileno(stderr)))
{
- fputs(opt_message ? opt_message : "Enter password: ",stdout);
- fflush(stdout);
+ fputs(opt_message ? opt_message : "Enter password: ",stderr);
+ fflush(stderr);
}
#if defined(HAVE_TERMIOS_H)
tcgetattr(fileno(stdin), &org);
@@ -184,7 +183,7 @@ char *get_tty_password(char *opt_message)
tmp.c_cc[VMIN] = 1;
tmp.c_cc[VTIME] = 0;
tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
- get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stdout)));
+ get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stderr)));
tcsetattr(fileno(stdin), TCSADRAIN, &org);
#elif defined(HAVE_TERMIO_H)
ioctl(fileno(stdin), (int) TCGETA, &org);
@@ -193,7 +192,7 @@ char *get_tty_password(char *opt_message)
tmp.c_cc[VMIN] = 1;
tmp.c_cc[VTIME]= 0;
ioctl(fileno(stdin),(int) TCSETA, &tmp);
- get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
+ get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr)));
ioctl(fileno(stdin),(int) TCSETA, &org);
#else
gtty(fileno(stdin), &org);
@@ -201,11 +200,11 @@ char *get_tty_password(char *opt_message)
tmp.sg_flags &= ~ECHO;
tmp.sg_flags |= RAW;
stty(fileno(stdin), &tmp);
- get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
+ get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr)));
stty(fileno(stdin), &org);
#endif
- if (isatty(fileno(stdout)))
- fputc('\n',stdout);
+ if (isatty(fileno(stderr)))
+ fputc('\n',stderr);
#endif /* HAVE_GETPASS */
DBUG_RETURN(my_strdup(buff,MYF(MY_FAE)));
diff --git a/client/insert_test.c b/client/insert_test.c
index 640935d63b2..42691df6875 100644
--- a/client/insert_test.c
+++ b/client/insert_test.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <stdlib.h>
@@ -34,19 +33,13 @@ int main(int argc, char **argv)
exit(1);
}
- if (!(sock = mysql_connect(&mysql,NULL,0,0)))
+ if (!(sock = mysql_real_connect(&mysql,NULL,NULL,NULL,argv[1],0,NULL,0)))
{
fprintf(stderr,"Couldn't connect to engine!\n%s\n",mysql_error(&mysql));
perror("");
exit(1);
}
- if (mysql_select_db(sock,argv[1]))
- {
- fprintf(stderr,"Couldn't select database %s!\n%s\n",argv[1],
- mysql_error(sock));
- }
-
num = atoi(argv[2]);
count = 0;
while (count < num)
diff --git a/client/list_test.c b/client/list_test.c
index 718cc45e012..06bf16d2751 100644
--- a/client/list_test.c
+++ b/client/list_test.c
@@ -1,34 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef __WIN__
#include <windows.h>
diff --git a/client/my_readline.h b/client/my_readline.h
index 547587bc19d..2e716eec4cf 100644
--- a/client/my_readline.h
+++ b/client/my_readline.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* readline for batch mode */
diff --git a/client/mysql.cc b/client/mysql.cc
index 32547a4d138..15770d2eb52 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000-2003 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,21 +20,27 @@
* Written by:
* Michael 'Monty' Widenius
* Andi Gutmans <andi@zend.com>
- * Zeev Suraski <zeev@zend.com>
- * Jani Tolonen <jani@mysql.com>
+ * Zeev Suraski <zeev@zend.com>
+ * Jani Tolonen <jani@mysql.com>
+ * Matt Wagner <matt@mysql.com>
+ * Jeremy Cole <jcole@mysql.com>
+ * Tonu Samuel <tonu@mysql.com>
+ * Harrison Fisk <hcfisk@buffalo.edu>
*
**/
#include "client_priv.h"
#include <m_ctype.h>
+#include <stdarg.h>
#include <my_dir.h>
#ifndef __GNU_LIBRARY__
#define __GNU_LIBRARY__ // Skip warnings in getopt.h
#endif
#include "my_readline.h"
#include <signal.h>
+#include <violite.h>
-const char *VER="11.18";
+const char *VER= "12.22";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
@@ -71,10 +77,9 @@ extern "C" {
#endif
#undef bcmp // Fix problem with new readline
-#undef bzero
#if defined( __WIN__) || defined(OS2)
#include <conio.h>
-#else
+#elif !defined(__NETWARE__)
#include <readline/readline.h>
#define HAVE_READLINE
#endif
@@ -86,14 +91,20 @@ extern "C" {
#define vidattr(A) {} // Can't get this to work
#endif
-#ifdef __WIN__
+#ifdef FN_NO_CASE_SENCE
#define cmp_database(A,B) my_strcasecmp((A),(B))
#else
#define cmp_database(A,B) strcmp((A),(B))
#endif
+#if !defined( __WIN__) && !defined( OS2) && !defined(__NETWARE__) && (!defined(HAVE_mit_thread) || !defined(THREAD))
+#define USE_POPEN
+#endif
+
#include "completion_hash.h"
+#define PROMPT_CHAR '\\'
+
typedef struct st_status
{
int exit_status;
@@ -105,30 +116,45 @@ typedef struct st_status
static HashTable ht;
+static char **defaults_argv;
enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
typedef enum enum_info_type INFO_TYPE;
static MYSQL mysql; /* The connection */
-static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
- connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
- no_rehash=0,skip_updates=0,safe_updates=0,one_database=0,
- opt_compress=0, using_opt_local_infile=0,
- vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0,
- opt_nopager=1, opt_outfile=0, no_named_cmds=1;
+static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
+ connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
+ rehash=1,skip_updates=0,safe_updates=0,one_database=0,
+ opt_compress=0, using_opt_local_infile=0,
+ vertical=0, line_numbers=1, column_names=1,opt_html=0,
+ opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
+ tty_password= 0, opt_nobeep=0;
static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
static my_string opt_mysql_unix_port=0;
static int connect_flag=CLIENT_INTERACTIVE;
static char *current_host,*current_db,*current_user=0,*opt_password=0,
- *default_charset;
+ *current_prompt=0, *default_charset;
static char *histfile;
static String glob_buffer,old_buffer;
+static String processed_prompt;
+static char *full_username=0,*part_username=0,*default_prompt=0;
static int wait_time = 5;
static STATUS status;
static ulong select_limit,max_join_size,opt_connect_timeout=0;
+static char mysql_charsets_dir[FN_REFLEN+1];
+static const char *xmlmeta[] = {
+ "&", "&amp;",
+ "<", "&lt;",
+ 0, 0
+};
+static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
+static const char *month_names[]={"Jan","Feb","Mar","Apr","May","Jun","Jul",
+ "Aug","Sep","Oct","Nov","Dec"};
static char default_pager[FN_REFLEN];
-char pager[FN_REFLEN], outfile[FN_REFLEN];
-FILE *PAGER, *OUTFILE;
+static char pager[FN_REFLEN], outfile[FN_REFLEN];
+static FILE *PAGER, *OUTFILE;
+static MEM_ROOT hash_mem_root;
+static uint prompt_counter;
#include "sslopt-vars.h"
@@ -149,11 +175,12 @@ static int com_quit(String *str,char*),
com_connect(String *str,char*), com_status(String *str,char*),
com_use(String *str,char*), com_source(String *str, char*),
com_rehash(String *str, char*), com_tee(String *str, char*),
- com_notee(String *str, char*);
+ com_notee(String *str, char*),
+ com_prompt(String *str, char*);
-#ifndef __WIN__
+#ifdef USE_POPEN
static int com_nopager(String *str, char*), com_pager(String *str, char*),
- com_edit(String *str,char*);
+ com_edit(String *str,char*), com_shell(String *str, char *);
#endif
static int read_lines(bool execute_commands);
@@ -161,10 +188,14 @@ static int sql_connect(char *host,char *database,char *user,char *password,
uint silent);
static int put_info(const char *str,INFO_TYPE info,uint error=0);
static void safe_put_field(const char *pos,ulong length);
+static void xmlencode_print(const char *src, uint length);
static void init_pager();
static void end_pager();
-static void init_tee();
+static void init_tee(const char *);
static void end_tee();
+static const char* construct_prompt();
+static void init_username();
+static void add_int_to_prompt(int toadd);
/* A structure which contains information on the commands this program
can understand. */
@@ -183,27 +214,31 @@ static COMMANDS commands[] = {
{ "clear", 'c', com_clear, 0, "Clear command."},
{ "connect",'r', com_connect,1,
"Reconnect to the server. Optional arguments are db and host." },
-#ifndef __WIN__
+#ifdef USE_POPEN
{ "edit", 'e', com_edit, 0, "Edit command with $EDITOR."},
#endif
{ "ego", 'G', com_ego, 0,
"Send command to mysql server, display result vertically."},
{ "exit", 'q', com_quit, 0, "Exit mysql. Same as quit."},
{ "go", 'g', com_go, 0, "Send command to mysql server." },
-#ifndef __WIN__
+#ifdef USE_POPEN
{ "nopager",'n', com_nopager,0, "Disable pager, print to stdout." },
#endif
{ "notee", 't', com_notee, 0, "Don't write into outfile." },
-#ifndef __WIN__
+#ifdef USE_POPEN
{ "pager", 'P', com_pager, 1,
"Set PAGER [to_pager]. Print the query results via PAGER." },
#endif
{ "print", 'p', com_print, 0, "Print current command." },
+ { "prompt", 'R', com_prompt, 1, "Change your mysql prompt."},
{ "quit", 'q', com_quit, 0, "Quit mysql." },
{ "rehash", '#', com_rehash, 0, "Rebuild completion hash." },
{ "source", '.', com_source, 1,
"Execute a SQL script file. Takes a file name as an argument."},
{ "status", 's', com_status, 0, "Get status information from the server."},
+#ifdef USE_POPEN
+ { "system", '!', com_shell, 1, "Execute a system shell command."},
+#endif
{ "tee", 'T', com_tee, 1,
"Set outfile [to_outfile]. Append everything into given outfile." },
{ "use", 'u', com_use, 1,
@@ -232,6 +267,8 @@ static COMMANDS commands[] = {
};
static const char *load_default_groups[]= { "mysql","client",0 };
+static const char *server_default_groups[]=
+{ "server", "embedded", "mysql_SERVER", 0 };
#ifdef HAVE_READLINE
extern "C" void add_history(char *command); /* From readline directory */
@@ -245,6 +282,7 @@ static bool add_line(String &buffer,char *line,char *in_string);
static void remove_cntrl(String &buffer);
static void print_table_data(MYSQL_RES *result);
static void print_table_data_html(MYSQL_RES *result);
+static void print_table_data_xml(MYSQL_RES *result);
static void print_tab_data(MYSQL_RES *result);
static void print_table_data_vertically(MYSQL_RES *result);
static ulong start_timer(void);
@@ -262,8 +300,14 @@ int main(int argc,char *argv[])
DBUG_ENTER("main");
DBUG_PROCESS(argv[0]);
- strmov(outfile, "\0"); // no (default) outfile, unless given at least once
- strmov(pager, "stdout"); // the default, if --pager wasn't given
+ default_prompt = my_strdup(getenv("MYSQL_PS1") ?
+ getenv("MYSQL_PS1") :
+ "mysql> ",MYF(MY_WME));
+ current_prompt = my_strdup(default_prompt,MYF(MY_WME));
+ prompt_counter=0;
+
+ outfile[0]=0; // no (default) outfile
+ strmov(pager, "stdout"); // the default, if --pager wasn't given
{
char *tmp=getenv("PAGER");
if (tmp)
@@ -278,17 +322,24 @@ int main(int argc,char *argv[])
status.add_to_history=1;
status.exit_status=1;
load_defaults("my",load_default_groups,&argc,&argv);
- if (get_options(argc,(char **) argv))
+ defaults_argv=argv;
+ if (get_options(argc, (char **) argv))
{
+ free_defaults(defaults_argv);
my_end(0);
exit(1);
}
- free_defaults(argv);
if (status.batch && !status.line_buff &&
!(status.line_buff=batch_readline_init(max_allowed_packet+512,stdin)))
+ {
+ free_defaults(defaults_argv);
exit(1);
+ }
glob_buffer.realloc(512);
- completion_hash_init(&ht,50);
+ mysql_server_init(0, NULL, (char**) server_default_groups);
+ completion_hash_init(&ht, 128);
+ init_alloc_root(&hash_mem_root, 16384, 0);
+ bzero((char*) &mysql, sizeof(mysql));
if (sql_connect(current_host,current_db,current_user,opt_password,
opt_silent))
{
@@ -301,21 +352,21 @@ int main(int argc,char *argv[])
signal(SIGINT, mysql_end); // Catch SIGINT to clean up
/*
- ** Run in interactive mode like the ingres/postgres monitor
+ Run in interactive mode like the ingres/postgres monitor
*/
put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.",
INFO_INFO);
sprintf((char*) glob_buffer.ptr(),
- "Your MySQL connection id is %ld to server version: %s\n",
+ "Your MySQL connection id is %lu to server version: %s\n",
mysql_thread_id(&mysql),mysql_get_server_info(&mysql));
put_info((char*) glob_buffer.ptr(),INFO_INFO);
#ifdef HAVE_READLINE
initialize_readline(my_progname);
- if (!status.batch && !quick && !opt_html)
+ if (!status.batch && !quick && !opt_html && !opt_xml)
{
- /*read-history from file, default ~/.mysql_history*/
+ /* read-history from file, default ~/.mysql_history*/
if (getenv("MYSQL_HISTFILE"))
histfile=my_strdup(getenv("MYSQL_HISTFILE"),MYF(MY_WME));
else if (getenv("HOME"))
@@ -348,10 +399,9 @@ int main(int argc,char *argv[])
sig_handler mysql_end(int sig)
{
- if (connected)
- mysql_close(&mysql);
+ mysql_close(&mysql);
#ifdef HAVE_READLINE
- if (!status.batch && !quick && ! opt_html)
+ if (!status.batch && !quick && !opt_html && !opt_xml)
{
/* write-history */
if (verbose)
@@ -360,88 +410,181 @@ sig_handler mysql_end(int sig)
}
batch_readline_end(status.line_buff);
completion_hash_free(&ht);
+ free_root(&hash_mem_root,MYF(0));
+
#endif
if (sig >= 0)
put_info(sig ? "Aborted" : "Bye", INFO_RESULT);
glob_buffer.free();
old_buffer.free();
+ processed_prompt.free();
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
+ mysql_server_end();
+ free_defaults(defaults_argv);
my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(status.exit_status);
}
-static struct option long_options[] =
+
+static struct my_option my_long_options[] =
{
- {"i-am-a-dummy", optional_argument, 0, 'U'},
- {"batch", no_argument, 0, 'B'},
- {"character-sets-dir",required_argument, 0, OPT_CHARSETS_DIR},
- {"compress", no_argument, 0, 'C'},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"auto-rehash", OPT_AUTO_REHASH,
+ "Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash.",
+ (gptr*) &rehash, (gptr*) &rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"no-auto-rehash", 'A',
+ "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"batch", 'B',
+ "Print results with a tab as separator, each row on new line. Doesn't use history file.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are.", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default-character-set", OPT_DEFAULT_CHARSET,
+ "Set the default character set.", (gptr*) &default_charset,
+ (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol.",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", optional_argument, 0, '#'},
+ {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option,
+ (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"database", 'D', "Database to use.", (gptr*) &current_db,
+ (gptr*) &current_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"execute", 'e', "Execute command and quit. (Output like with --batch).", 0,
+ 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"vertical", 'E', "Print the output of a query (rows) vertically.",
+ (gptr*) &vertical, (gptr*) &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"force", 'f', "Continue even if we get an sql error.",
+ (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"no-named-commands", 'g',
+ "Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option deprecated; use --disable-named-commands instead.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"named-commands", 'G',
+ "Enable named commands. Named commands mean this program's internal commands; see mysql> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter. Disable with --disable-named-commands. This option is disabled by default.",
+ (gptr*) &named_cmds, (gptr*) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"ignore-spaces", 'i', "Ignore space after function names.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.",
+ (gptr*) &opt_local_infile,
+ (gptr*) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"no-beep", 'b', "Turn off beep on error.", (gptr*) &opt_nobeep,
+ (gptr*) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &current_host,
+ (gptr*) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"html", 'H', "Produce HTML output.", (gptr*) &opt_html, (gptr*) &opt_html,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"xml", 'X', "Produce XML output", (gptr*) &opt_xml, (gptr*) &opt_xml, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
+ (gptr*) &line_numbers, (gptr*) &line_numbers, 0, GET_BOOL,
+ NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef USE_POPEN
+ {"no-pager", OPT_NOPAGER,
+ "Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"database", required_argument, 0, 'D'},
- {"debug-info", no_argument, 0, 'T'},
- {"default-character-set", required_argument,0, OPT_DEFAULT_CHARSET},
- {"enable-named-commands", no_argument, 0, 'G'},
- {"execute", required_argument, 0, 'e'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"html", no_argument, 0, 'H'},
- {"host", required_argument, 0, 'h'},
- {"ignore-spaces", no_argument, 0, 'i'},
- {"local-infile", optional_argument, 0, OPT_LOCAL_INFILE},
- {"no-auto-rehash",no_argument, 0, 'A'},
- {"no-named-commands", no_argument, 0, 'g'},
-#ifndef __WIN__
- {"no-pager", no_argument, 0, OPT_NOPAGER},
- {"nopager", no_argument, 0, OPT_NOPAGER}, /* we are kind */
- {"pager", optional_argument, 0, OPT_PAGER},
+ {"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"unbuffered", 'n', "Flush buffer after each query.", (gptr*) &unbuffered,
+ (gptr*) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"column-names", OPT_COLUMN_NAMES, "Write column names in results.",
+ (gptr*) &column_names, (gptr*) &column_names, 0, GET_BOOL,
+ NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"skip-column-names", 'N',
+ "Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"one-database", 'o',
+ "Only update the default database. This is useful for skipping updates to other database in the update log.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef USE_POPEN
+ {"pager", OPT_PAGER,
+ "Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"no-tee", no_argument, 0, OPT_NOTEE},
- {"notee", no_argument, 0, OPT_NOTEE}, /* we are kind */
- {"tee", required_argument, 0, OPT_TEE},
- {"one-database", no_argument, 0, 'o'},
- {"password", optional_argument, 0, 'p'},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"port", required_argument, 0, 'P'},
- {"quick", no_argument, 0, 'q'},
- {"set-variable", required_argument, 0, 'O'},
- {"raw", no_argument, 0, 'r'},
- {"safe-updates", optional_argument, 0, 'U'},
- {"silent", no_argument, 0, 's'},
- {"skip-column-names",no_argument, 0, 'N'},
- {"skip-line-numbers",no_argument, 0, 'L'},
- {"socket", required_argument, 0, 'S'},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
+ {"prompt", OPT_PROMPT, "Set the mysql prompt to this value.",
+ (gptr*) &current_prompt, (gptr*) &current_prompt, 0, GET_STR_ALLOC,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"quick", 'q',
+ "Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file. ",
+ (gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"raw", 'r', "Write fields without conversion. Used with --batch",
+ (gptr*) &opt_raw_data, (gptr*) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"silent", 's', "Be more silent.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR_ALLOC,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include "sslopt-longopts.h"
- {"table", no_argument, 0, 't'},
+ {"table", 't', "Output in table format.", (gptr*) &output_tables,
+ (gptr*) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug-info", 'T', "Print some debug info at exit.", (gptr*) &info_flag,
+ (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"tee", OPT_TEE,
+ "Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.", (gptr*) &current_user,
+ (gptr*) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"unbuffered", no_argument, 0, 'n'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"vertical", no_argument, 0, 'E'},
- {"wait", optional_argument, 0, 'w'},
- {0, 0, 0, 0}
-};
-
-
-CHANGEABLE_VAR changeable_vars[] = {
- { "connect_timeout", (long*) &opt_connect_timeout, 0, 0, 3600*12, 0, 1},
- { "max_allowed_packet", (long*) &max_allowed_packet,16*1024L*1024L,4096,
- 24*1024L*1024L, MALLOC_OVERHEAD,1024},
- { "net_buffer_length",(long*) &net_buffer_length,16384,1024,16*1024*1024L,
- MALLOC_OVERHEAD,1024},
- { "select_limit", (long*) &select_limit, 1000L, 1, ~0L, 0, 1},
- { "max_join_size", (long*) &max_join_size, 1000000L, 1, ~0L, 0, 1},
- { 0, 0, 0, 0, 0, 0, 0}
+ {"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.",
+ (gptr*) &safe_updates, (gptr*) &safe_updates, 0, GET_BOOL, OPT_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.",
+ (gptr*) &safe_updates, (gptr*) &safe_updates, 0, GET_BOOL, OPT_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"verbose", 'v', "Write more. (-v -v -v gives the table output format)", 0,
+ 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout,
+ (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
+ 0, 1},
+ {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
+ (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, GET_ULONG,
+ REQUIRED_ARG, 16 *1024L*1024L, 4096, (longlong) 2*1024L*1024L*1024L,
+ MALLOC_OVERHEAD, 1024, 0},
+ {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
+ (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0},
+ {"select_limit", OPT_SELECT_LIMIT, "", (gptr*) &select_limit,
+ (gptr*) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0},
+ {"max_join_size", OPT_MAX_JOIN_SIZE, "", (gptr*) &max_join_size,
+ (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1,
+ 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -451,298 +594,172 @@ static void usage(int version)
my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
if (version)
return;
- puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB");
- puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
- printf("Usage: %s [OPTIONS] [database]\n", my_progname);
- printf("\n\
- -?, --help Display this help and exit.\n\
- -A, --no-auto-rehash No automatic rehashing. One has to use 'rehash' to\n\
- get table and field completion. This gives a quicker\n\
- start of mysql and disables rehashing on reconnect.\n\
- -B, --batch Print results with a tab as separator, each row on\n\
- a new line. Doesn't use history file.\n\
- --character-sets-dir=...\n\
- Directory where character sets are located.\n\
- -C, --compress Use compression in server/client protocol.\n");
-#ifndef DBUG_OFF
- printf("\
- -#, --debug[=...] Debug log. Default is '%s'.\n",default_dbug_option);
-#endif
- printf("\
- -D, --database=.. Database to use.\n\
- --default-character-set=...\n\
- Set the default character set.\n\
- -e, --execute=... Execute command and quit. (Output like with --batch)\n\
- -E, --vertical Print the output of a query (rows) vertically.\n\
- -f, --force Continue even if we get an sql error.\n\
- -g, --no-named-commands\n\
- Named commands are disabled. Use \\* form only, or\n\
- use named commands only in the beginning of a line\n\
- ending with a semicolon (;) Since version 10.9 the\n\
- client now starts with this option ENABLED by\n\
- default! Disable with '-G'. Long format commands\n\
- still work from the first line.\n\
- -G, --enable-named-commands\n\
- Named commands are enabled. Opposite to -g.\n\
- -i, --ignore-spaces Ignore spaces after function names.\n\
- -h, --host=... Connect to host.\n\
- -H, --html Produce HTML output.\n\
- --local-infile=[1|0] Enable/disable LOAD DATA LOCAL INFILE\n\
- -L, --skip-line-numbers\n\
- Don't write line number for errors.\n");
-#ifndef __WIN__
printf("\
- --no-pager Disable pager and print to stdout. See interactive\n\
- help (\\h) also.\n");
-#endif
- printf("\
- --no-tee Disable outfile. See interactive help (\\h) also.\n\
- -n, --unbuffered Flush buffer after each query.\n\
- -N, --skip-column-names\n\
- Don't write column names in results.\n\
- -O, --set-variable var=option\n\
- Give a variable an value. --help lists variables.\n\
- -o, --one-database Only update the default database. This is useful\n\
- for skipping updates to other database in the update\n\
- log.\n");
-#ifndef __WIN__
- printf("\
- --pager[=...] Pager to use to display results. If you don't supply\n\
- an option the default pager is taken from your ENV\n\
- variable PAGER (%s).\n\
- Valid pagers are less, more, cat [> filename], etc.\n\
- See interactive help (\\h) also. This option does\n\
- not work in batch mode.\n", getenv("PAGER") ? getenv("PAGER") : "");
-#endif
- printf("\
- -p[password], --password[=...]\n\
- Password to use when connecting to server\n\
- If password is not given it's asked from the tty.\n");
-#ifdef __WIN__
- puts(" -W, --pipe Use named pipes to connect to server");
-#endif
- printf("\n\
- -P, --port=... Port number to use for connection.\n\
- -q, --quick Don't cache result, print it row by row. This may\n\
- slow down the server if the output is suspended.\n\
- Doesn't use history file.\n\
- -r, --raw Write fields without conversion. Used with --batch\n\
- -s, --silent Be more silent.\n\
- -S --socket=... Socket file to use for connection.\n");
-#include "sslopt-usage.h"
- printf("\
- -t, --table Output in table format.\n\
- -T, --debug-info Print some debug info at exit.\n\
- --tee=... Append everything into outfile. See interactive help\n\
- (\\h) also. Does not work in batch mode.\n");
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# User for login if not current user.\n");
-#endif
- printf("\
- -U, --safe-updates[=#], --i-am-a-dummy[=#]\n\
- Only allow UPDATE and DELETE that uses keys.\n\
- -v, --verbose Write more. (-v -v -v gives the table output format)\n\
- -V, --version Output version information and exit.\n\
- -w, --wait Wait and retry if connection is down.\n");
- print_defaults("my",load_default_groups);
-
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (uint i=0 ; changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- changeable_vars[i].name,
- (ulong) *changeable_vars[i].varptr);
+Copyright (C) 2002 MySQL AB\n\
+This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
+and you are welcome to modify and redistribute it under the GPL license\n");
+ printf("Usage: %s [OPTIONS] [database]\n", my_progname);
+ my_print_help(my_long_options);
+ print_defaults("my", load_default_groups);
+ my_print_variables(my_long_options);
}
-
-static int get_options(int argc, char **argv)
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
{
- int c,option_index=0;
- bool tty_password=0;
-
- set_all_changeable_vars(changeable_vars);
- while ((c=getopt_long(argc,argv,
- (char*) "?ABCD:LfgGHinNoqrstTU::vVw::WEe:h:O:P:S:u:#::p::",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case OPT_DEFAULT_CHARSET:
- default_charset= optarg;
- break;
- case OPT_CHARSETS_DIR:
- charsets_dir= optarg;
- break;
- case OPT_TEE:
- if (!opt_outfile && strlen(optarg))
- {
- strmov(outfile, optarg);
- opt_outfile=1;
- init_tee();
- }
- break;
- case OPT_NOTEE:
+ switch(optid) {
+ case OPT_CHARSETS_DIR:
+ strmov(mysql_charsets_dir, argument);
+ charsets_dir = mysql_charsets_dir;
+ break;
+ case OPT_LOCAL_INFILE:
+ using_opt_local_infile=1;
+ break;
+ case OPT_TEE:
+ if (argument == disabled_my_option)
+ {
if (opt_outfile)
end_tee();
- opt_outfile=0;
- break;
- case OPT_PAGER:
- opt_nopager=0;
- if (optarg)
- strmov(pager, optarg);
+ }
+ else
+ init_tee(argument);
+ break;
+ case OPT_NOTEE:
+ printf("WARNING: option deprecated; use --disable-tee instead.\n");
+ if (opt_outfile)
+ end_tee();
+ break;
+ case OPT_PAGER:
+ if (argument == disabled_my_option)
+ opt_nopager= 1;
+ else
+ {
+ opt_nopager= 0;
+ if (argument)
+ strmov(pager, argument);
else
- {
- char *pagpoint = getenv("PAGER");
- if (!((char*) (pagpoint)))
- {
- strmov(pager, "stdout");
- opt_nopager=1;
- }
- else
- strmov(pager, pagpoint);
- }
+ strmov(pager, default_pager);
strmov(default_pager, pager);
- break;
- case OPT_NOPAGER:
- opt_nopager=1;
- break;
- case 'D':
- my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
- current_db=my_strdup(optarg,MYF(MY_WME));
- break;
- case 'e':
- status.batch=1;
- status.add_to_history=0;
- batch_readline_end(status.line_buff); // If multiple -e
- if (!(status.line_buff=batch_readline_command(optarg)))
- return 1;
- ignore_errors=0;
- break;
- case 'f':
- ignore_errors=1;
- break;
- case 'h':
- my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
- current_host=my_strdup(optarg,MYF(MY_WME));
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
- current_user= my_strdup(optarg,MYF(MY_WME));
- break;
-#endif
- case 'U':
- if (!optarg)
- safe_updates=1;
- else
- safe_updates=atoi(optarg) != 0;
- break;
- case 'o':
- one_database=skip_updates=1;
- break;
- case 'O':
- if (set_changeable_var(optarg, changeable_vars))
- {
- usage(0);
- return(1);
- }
- break;
- case 'p':
- if (optarg)
- {
- char *start=optarg;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- opt_password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; // Destroy argument
- if (*start)
- start[1]=0;
- }
- else
- tty_password=1;
- break;
- case 't':
- output_tables=1;
- break;
- case 'r':
- opt_raw_data=1;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : default_dbug_option);
- info_flag=1;
- break;
- case 'q': quick=1; break;
- case 's': opt_silent++; break;
- case 'T': info_flag=1; break;
- case 'n': unbuffered=1; break;
- case 'v': verbose++; break;
- case 'E': vertical=1; break;
- case 'w':
- wait_flag=1;
- if(optarg) wait_time = atoi(optarg) ;
- break;
- case 'A': no_rehash=1; break;
- case 'G': no_named_cmds=0; break;
- case 'g': no_named_cmds=1; break;
- case 'H': opt_html=1; break;
- case 'i': connect_flag|= CLIENT_IGNORE_SPACE; break;
- case 'B':
- if (!status.batch)
- {
- status.batch=1;
- status.add_to_history=0;
- opt_silent++; // more silent
- }
- break;
- case 'C':
- opt_compress=1;
- break;
- case OPT_LOCAL_INFILE:
- using_opt_local_infile=1;
- opt_local_infile= test(!optarg || atoi(optarg)>0);
- break;
- case 'L':
- skip_line_numbers=1;
- break;
- case 'N':
- skip_column_names=1;
- break;
- case 'P':
- opt_mysql_port= (unsigned int) atoi(optarg);
- break;
- case 'S':
- my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
- opt_mysql_unix_port= my_strdup(optarg,MYF(0));
- break;
- case 'W':
+ }
+ break;
+ case OPT_NOPAGER:
+ printf("WARNING: option deprecated; use --disable-pager instead.\n");
+ opt_nopager= 1;
+ break;
+ case 'A':
+ rehash= 0;
+ break;
+ case 'N':
+ column_names= 0;
+ break;
+ case 'e':
+ status.batch= 1;
+ status.add_to_history= 0;
+ batch_readline_end(status.line_buff); // If multiple -e
+ if (!(status.line_buff= batch_readline_command(argument)))
+ return 1;
+ ignore_errors= 0;
+ break;
+ case 'o':
+ if (argument == disabled_my_option)
+ one_database= 0;
+ else
+ one_database= skip_updates= 1;
+ break;
+ case 'p':
+ if (argument == disabled_my_option)
+ argument= (char*) ""; // Don't require password
+ if (argument)
+ {
+ char *start= argument;
+ my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ opt_password= my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; // Destroy argument
+ if (*start)
+ start[1]=0 ;
+ }
+ else
+ tty_password= 1;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : default_dbug_option);
+ info_flag= 1;
+ break;
+ case 's':
+ if (argument == disabled_my_option)
+ opt_silent= 0;
+ else
+ opt_silent++;
+ break;
+ case 'v':
+ if (argument == disabled_my_option)
+ verbose= 0;
+ else
+ verbose++;
+ break;
+ case 'B':
+ if (!status.batch)
+ {
+ status.batch= 1;
+ status.add_to_history= 0;
+ opt_silent++; // more silent
+ }
+ break;
+ case 'W':
#ifdef __WIN__
- opt_mysql_unix_port=my_strdup(MYSQL_NAMEDPIPE,MYF(0));
+ my_free(opt_mysql_unix_port, MYF(MY_ALLOW_ZERO_PTR));
+ opt_mysql_unix_port= my_strdup(MYSQL_NAMEDPIPE, MYF(0));
#endif
- break;
- case 'V': usage(1); exit(0);
- case 'I':
- case '?':
- usage(0);
- exit(0);
-#include "sslopt-case.h"
- default:
- tee_fprintf(stderr,"illegal option: -%c\n",opterr);
- usage(0);
- exit(1);
- }
+ break;
+#include <sslopt-case.h>
+ case 'V':
+ usage(1);
+ exit(0);
+ case 'I':
+ case '?':
+ usage(0);
+ exit(0);
}
+ return 0;
+}
+
+
+static int get_options(int argc, char **argv)
+{
+ char *tmp, *pagpoint;
+ int ho_error;
+
+ tmp= (char *) getenv("MYSQL_HOST");
+ if (tmp)
+ current_host= my_strdup(tmp, MYF(MY_WME));
+
+ pagpoint= getenv("PAGER");
+ if (!((char*) (pagpoint)))
+ {
+ strmov(pager, "stdout");
+ opt_nopager= 1;
+ }
+ else
+ strmov(pager, pagpoint);
+ strmov(default_pager, pager);
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (status.batch) /* disable pager and outfile in this case */
{
strmov(default_pager, "stdout");
strmov(pager, "stdout");
- opt_nopager=1;
- opt_outfile=0;
+ opt_nopager= 1;
+ opt_outfile= 0;
+ connect_flag= 0; /* Not in interactive mode */
}
if (default_charset)
{
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
exit(1);
}
- argc-=optind;
- argv+=optind;
if (argc > 1)
{
usage(0);
@@ -750,23 +767,18 @@ static int get_options(int argc, char **argv)
}
if (argc == 1)
{
- my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
- current_db= my_strdup(*argv,MYF(MY_WME));
- }
- if (!current_host)
- { /* If we don't have a hostname have a look at MYSQL_HOST */
- char *tmp=(char *) getenv("MYSQL_HOST");
- if (tmp)
- current_host = my_strdup(tmp,MYF(MY_WME));
+ skip_updates= 0;
+ my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
+ current_db= my_strdup(*argv, MYF(MY_WME));
}
if (tty_password)
- opt_password=get_tty_password(NullS);
+ opt_password= get_tty_password(NullS);
return(0);
}
static int read_lines(bool execute_commands)
{
-#if defined( __WIN__) || defined(OS2)
+#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
char linebuffer[254];
#endif
char *line;
@@ -786,30 +798,35 @@ static int read_lines(bool execute_commands)
}
else
{
-#if defined( __WIN__) || defined(OS2)
+ char *prompt= (char*) (glob_buffer.is_empty() ? construct_prompt() :
+ !in_string ? " -> " :
+ in_string == '\'' ?
+ " '> " : (in_string == '`' ?
+ " `> " :
+ " \"> "));
if (opt_outfile && glob_buffer.is_empty())
fflush(OUTFILE);
- tee_fputs(glob_buffer.is_empty() ? "mysql> " :
- !in_string ? " -> " :
- in_string == '\'' ?
- " '> " : " \"> ",stdout);
- linebuffer[0]=(char) sizeof(linebuffer);
- line=_cgets(linebuffer);
-#else
- if (opt_outfile)
+
+#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
+ tee_fputs(prompt, stdout);
+#ifdef __NETWARE__
+ line=fgets(linebuffer, sizeof(linebuffer)-1, stdin);
+ /* Remove the '\n' */
{
- if (glob_buffer.is_empty())
- fflush(OUTFILE);
- fputs(glob_buffer.is_empty() ? "mysql> " :
- !in_string ? " -> " :
- in_string == '\'' ?
- " '> " : " \"> ", OUTFILE);
+ char *p = strrchr(line, '\n');
+ if (p != NULL)
+ *p = '\0';
}
- line=readline((char*) (glob_buffer.is_empty() ? "mysql> " :
- !in_string ? " -> " :
- in_string == '\'' ?
- " '> " : " \"> "));
-#endif
+#else
+ linebuffer[0]= (char) sizeof(linebuffer);
+ line= _cgets(linebuffer);
+#endif /* __NETWARE__ */
+#else
+ if (opt_outfile)
+ fputs(prompt, OUTFILE);
+ line= readline(prompt);
+#endif /* defined( __WIN__) || defined(OS2) || defined(__NETWARE__) */
+
if (opt_outfile)
fprintf(OUTFILE, "%s\n", line);
}
@@ -823,9 +840,11 @@ static int read_lines(bool execute_commands)
line[0] == 0))
continue; // Skip comment lines
- /* Check if line is a mysql command line */
- /* (We want to allow help, print and clear anywhere at line start */
- if (execute_commands && (!no_named_cmds || glob_buffer.is_empty())
+ /*
+ Check if line is a mysql command line
+ (We want to allow help, print and clear anywhere at line start
+ */
+ if (execute_commands && (named_cmds || glob_buffer.is_empty())
&& !in_string && (com=find_command(line,0)))
{
if ((*com->func)(&glob_buffer,line) > 0)
@@ -903,6 +922,7 @@ static bool add_line(String &buffer,char *line,char *in_string)
uchar inchar;
char buff[80],*pos,*out;
COMMANDS *com;
+ my_bool in_comment= 0;
if (!line[0] && buffer.is_empty())
return 0;
@@ -962,7 +982,7 @@ static bool add_line(String &buffer,char *line,char *in_string)
continue;
}
}
- else if (inchar == ';' && !*in_string)
+ else if (inchar == ';' && !*in_string && !in_comment)
{ // ';' is end of command
if (out != line)
buffer.append(line,(uint) (out-line)); // Add this line
@@ -990,9 +1010,16 @@ static bool add_line(String &buffer,char *line,char *in_string)
{ // Add found char to buffer
if (inchar == *in_string)
*in_string=0;
- else if (!*in_string && (inchar == '\'' || inchar == '"'))
+ else if (!*in_string && (inchar == '\'' || inchar == '"' || inchar == '`'))
*in_string=(char) inchar;
*out++ = (char) inchar;
+ if (inchar == '*' && !*in_string)
+ {
+ if (pos != line && pos[-1] == '/')
+ in_comment= 1;
+ else if (in_comment && pos[1] == '/')
+ in_comment= 0;
+ }
}
}
if (out != line || !buffer.is_empty())
@@ -1007,20 +1034,20 @@ static bool add_line(String &buffer,char *line,char *in_string)
return 0;
}
-/* **************************************************************** */
-/* */
-/* Interface to Readline Completion */
-/* */
-/* **************************************************************** */
+/*****************************************************************
+ Interface to Readline Completion
+******************************************************************/
#ifdef HAVE_READLINE
static char *new_command_generator(char *text, int);
static char **new_mysql_completion (char *text, int start, int end);
-/* Tell the GNU Readline library how to complete. We want to try to complete
- on command names if this is the first word in the line, or on filenames
- if not. */
+/*
+ Tell the GNU Readline library how to complete. We want to try to complete
+ on command names if this is the first word in the line, or on filenames
+ if not.
+*/
char **no_completion (char *text __attribute__ ((unused)),
char *word __attribute__ ((unused)))
@@ -1039,11 +1066,12 @@ static void initialize_readline (char *name)
rl_completion_entry_function=(Function *) no_completion;
}
-/* Attempt to complete on the contents of TEXT. START and END show the
- region of TEXT that contains the word to complete. We can use the
- entire line in case we want to do some simple parsing. Return the
- array of matches, or NULL if there aren't any. */
-
+/*
+ Attempt to complete on the contents of TEXT. START and END show the
+ region of TEXT that contains the word to complete. We can use the
+ entire line in case we want to do some simple parsing. Return the
+ array of matches, or NULL if there aren't any.
+*/
static char **new_mysql_completion (char *text,
int start __attribute__((unused)),
@@ -1063,67 +1091,72 @@ static char *new_command_generator(char *text,int state)
static entry *e;
static uint i;
- if (!state) {
+ if (!state)
textlen=(uint) strlen(text);
- }
- if (textlen>0) { /* lookup in the hash */
- if (!state) {
+ if (textlen>0)
+ { /* lookup in the hash */
+ if (!state)
+ {
uint len;
b = find_all_matches(&ht,text,(uint) strlen(text),&len);
- if (!b) {
+ if (!b)
return NullS;
- }
e = b->pData;
}
- while (e) {
+ if (e)
+ {
ptr= strdup(e->str);
e = e->pNext;
return ptr;
}
- } else { /* traverse the entire hash, ugly but works */
+ }
+ else
+ { /* traverse the entire hash, ugly but works */
- if (!state) {
- i=0;
+ if (!state)
+ {
/* find the first used bucket */
- while (i<ht.nTableSize) {
- if (ht.arBuckets[i]) {
+ for (i=0 ; i < ht.nTableSize ; i++)
+ {
+ if (ht.arBuckets[i])
+ {
b = ht.arBuckets[i];
e = b->pData;
break;
}
- i++;
}
}
ptr= NullS;
- while (e && !ptr) { /* find valid entry in bucket */
- if ((uint) strlen(e->str)==b->nKeyLength) {
+ while (e && !ptr)
+ { /* find valid entry in bucket */
+ if ((uint) strlen(e->str) == b->nKeyLength)
ptr = strdup(e->str);
- }
/* find the next used entry */
e = e->pNext;
- if (!e) { /* find the next used bucket */
+ if (!e)
+ { /* find the next used bucket */
b = b->pNext;
- if (!b) {
- i++;
- while (i<ht.nTableSize) {
- if (ht.arBuckets[i]) {
+ if (!b)
+ {
+ for (i++ ; i<ht.nTableSize; i++)
+ {
+ if (ht.arBuckets[i])
+ {
b = ht.arBuckets[i];
e = b->pData;
break;
}
- i++;
}
- } else {
- e = b->pData;
}
+ else
+ e = b->pData;
}
}
- if (ptr) {
+ if (ptr)
return ptr;
- }
}
return NullS;
}
@@ -1131,10 +1164,11 @@ static char *new_command_generator(char *text,int state)
/* Build up the completion hash */
-static void build_completion_hash(bool skip_rehash,bool write_info)
+static void build_completion_hash(bool rehash, bool write_info)
{
COMMANDS *cmd=commands;
- static MYSQL_RES *databases=0,*tables=0,*fields;
+ MYSQL_RES *databases=0,*tables=0;
+ MYSQL_RES *fields;
static char ***field_names= 0;
MYSQL_ROW database_row,table_row;
MYSQL_FIELD *sql_field;
@@ -1145,35 +1179,42 @@ static void build_completion_hash(bool skip_rehash,bool write_info)
if (status.batch || quick || !current_db)
DBUG_VOID_RETURN; // We don't need completion in batches
- completion_hash_clean(&ht);
if (tables)
{
mysql_free_result(tables);
tables=0;
}
- if (databases) {
- mysql_free_result(databases);
- databases=0;
- }
/* hash SQL commands */
while (cmd->name) {
add_word(&ht,(char*) cmd->name);
cmd++;
}
- if (skip_rehash)
+ if (!rehash)
DBUG_VOID_RETURN;
+ /* Free old used memory */
+ if (field_names)
+ field_names=0;
+ completion_hash_clean(&ht);
+ free_root(&hash_mem_root,MYF(0));
+
/* hash MySQL functions (to be implemented) */
/* hash all database names */
- if (mysql_query(&mysql,"show databases")==0) {
+ if (mysql_query(&mysql,"show databases") == 0)
+ {
if (!(databases = mysql_store_result(&mysql)))
put_info(mysql_error(&mysql),INFO_INFO);
else
{
while ((database_row=mysql_fetch_row(databases)))
- add_word(&ht,(char*) database_row[0]);
+ {
+ char *str=strdup_root(&hash_mem_root, (char*) database_row[0]);
+ if (str)
+ add_word(&ht,(char*) str);
+ }
+ mysql_free_result(databases);
}
}
/* hash all table names */
@@ -1191,22 +1232,13 @@ You can turn off this feature to get a quicker startup with -A\n\n");
}
while ((table_row=mysql_fetch_row(tables)))
{
- if (!completion_hash_exists(&ht,(char*) table_row[0],
- (uint) strlen((const char*) table_row[0])))
- add_word(&ht,table_row[0]);
+ char *str=strdup_root(&hash_mem_root, (char*) table_row[0]);
+ if (str &&
+ !completion_hash_exists(&ht,(char*) str, (uint) strlen(str)))
+ add_word(&ht,str);
}
}
}
- if (field_names) {
- for (i=0; field_names[i]; i++) {
- for (j=0; field_names[i][j]; j++) {
- my_free(field_names[i][j],MYF(0));
- }
- my_free((gptr) field_names[i],MYF(0));
- }
- my_free((gptr) field_names,MYF(0));
- }
- field_names=0;
/* hash all field names, both with the table prefix and without it */
if (!tables) /* no tables */
@@ -1214,36 +1246,37 @@ You can turn off this feature to get a quicker startup with -A\n\n");
DBUG_VOID_RETURN;
}
mysql_data_seek(tables,0);
- field_names = (char ***) my_malloc(sizeof(char **) *
- (uint) (mysql_num_rows(tables)+1),
- MYF(MY_WME));
- if (!field_names)
+ if (!(field_names= (char ***) alloc_root(&hash_mem_root,sizeof(char **) *
+ (uint) (mysql_num_rows(tables)+1))))
+ {
+ mysql_free_result(tables);
DBUG_VOID_RETURN;
+ }
i=0;
while ((table_row=mysql_fetch_row(tables)))
{
if ((fields=mysql_list_fields(&mysql,(const char*) table_row[0],NullS)))
{
num_fields=mysql_num_fields(fields);
- field_names[i] = (char **) my_malloc(sizeof(char *)*(num_fields*2+1),
- MYF(0));
- if (!field_names[i])
- {
- continue;
- }
+ if (!(field_names[i] = (char **) alloc_root(&hash_mem_root,
+ sizeof(char *) *
+ (num_fields*2+1))))
+ break;
field_names[i][num_fields*2]='\0';
j=0;
while ((sql_field=mysql_fetch_field(fields)))
{
sprintf(buf,"%s.%s",table_row[0],sql_field->name);
- field_names[i][j] = my_strdup(buf,MYF(0));
+ field_names[i][j] = strdup_root(&hash_mem_root,buf);
add_word(&ht,field_names[i][j]);
- field_names[i][num_fields+j] = my_strdup(sql_field->name,MYF(0));
+ field_names[i][num_fields+j] = strdup_root(&hash_mem_root,
+ sql_field->name);
if (!completion_hash_exists(&ht,field_names[i][num_fields+j],
(uint) strlen(field_names[i][num_fields+j])))
add_word(&ht,field_names[i][num_fields+j]);
j++;
}
+ mysql_free_result(fields);
}
else
{
@@ -1253,20 +1286,18 @@ You can turn off this feature to get a quicker startup with -A\n\n");
}
i++;
}
+ mysql_free_result(tables);
field_names[i]=0; // End pointer
DBUG_VOID_RETURN;
}
-
/* for gnu readline */
#ifndef HAVE_INDEX
-#ifdef __cplusplus
extern "C" {
-#endif
-extern char *index(const char *,pchar c),*rindex(const char *,pchar);
+extern char *index(const char *,int c),*rindex(const char *,int);
-char *index(const char *s,pchar c)
+char *index(const char *s,int c)
{
for (;;)
{
@@ -1275,7 +1306,7 @@ char *index(const char *s,pchar c)
}
}
-char *rindex(const char *s,pchar c)
+char *rindex(const char *s,int c)
{
reg3 char *t;
@@ -1283,19 +1314,19 @@ char *rindex(const char *s,pchar c)
do if (*s == (char) c) t = (char*) s; while (*s++);
return (char*) t;
}
-#ifdef __cplusplus
}
#endif
-#endif
#endif /* HAVE_READLINE */
+
static int reconnect(void)
{
if (!status.batch)
{
put_info("No connection. Trying to reconnect...",INFO_INFO);
(void) com_connect((String *) 0, 0);
- if(!no_rehash) com_rehash(NULL, NULL);
+ if (rehash)
+ com_rehash(NULL, NULL);
}
if (!connected)
return put_info("Can't connect to the server\n",INFO_ERROR);
@@ -1313,9 +1344,13 @@ com_help (String *buffer __attribute__((unused)),
{
reg1 int i;
- put_info("\nMySQL commands:",INFO_INFO);
- if (no_named_cmds)
- put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO);
+ put_info("\nFor the complete MySQL Manual online visit:\n http://www.mysql.com/documentation\n", INFO_INFO);
+ put_info("For info on technical support from MySQL developers visit:\n http://www.mysql.com/support\n", INFO_INFO);
+ put_info("For info on MySQL books, utilities, consultants, etc. visit:\n http://www.mysql.com/portal\n", INFO_INFO);
+ put_info("List of all MySQL commands:", INFO_INFO);
+ if (!named_cmds)
+ put_info(" (Commands must appear first on line and end with ';')\n",
+ INFO_INFO);
for (i = 0; commands[i].name; i++)
{
if (commands[i].func)
@@ -1324,7 +1359,7 @@ com_help (String *buffer __attribute__((unused)),
}
if (connected)
tee_fprintf(stdout,
- "\nConnection id: %ld (Can be used with mysqladmin kill)\n\n",
+ "\nConnection id: %lu (Can be used with mysqladmin kill)\n\n",
mysql_thread_id(&mysql));
else
tee_fprintf(stdout, "Not connected! Reconnect with 'connect'!\n\n");
@@ -1342,10 +1377,10 @@ com_clear(String *buffer,char *line __attribute__((unused)))
/*
-** Execute command
-** Returns: 0 if ok
-** -1 if not fatal error
-** 1 if fatal error
+ Execute command
+ Returns: 0 if ok
+ -1 if not fatal error
+ 1 if fatal error
*/
@@ -1363,7 +1398,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
old_buffer.copy();
}
- /* Remove garbage for nicer messages */
+ /* Remove garbage for nicer messages */
LINT_INIT(buff[0]);
remove_cntrl(*buffer);
@@ -1443,6 +1478,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
init_pager();
if (opt_html)
print_table_data_html(result);
+ else if (opt_xml)
+ print_table_data_xml(result);
else if (vertical)
print_table_data_vertically(result);
else if (opt_silent && verbose <= 2 && !output_tables)
@@ -1479,7 +1516,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
static void init_pager()
{
-#if !defined( __WIN__) && !defined( OS2)
+#ifdef USE_POPEN
if (!opt_nopager)
{
if (!(PAGER= popen(pager, "w")))
@@ -1495,25 +1532,36 @@ static void init_pager()
static void end_pager()
{
-#if !defined( __WIN__) && !defined( OS2)
+#ifdef USE_POPEN
if (!opt_nopager)
pclose(PAGER);
#endif
}
-static void init_tee()
+
+static void init_tee(const char *file_name)
{
- if (!(OUTFILE= my_fopen(outfile, O_APPEND | O_WRONLY, MYF(MY_WME))))
+ FILE* new_outfile;
+ if (opt_outfile)
+ end_tee();
+ if (!(new_outfile= my_fopen(file_name, O_APPEND | O_WRONLY, MYF(MY_WME))))
{
- opt_outfile=0;
- init_pager();
+ tee_fprintf(stdout, "Error logging to file '%s'\n", file_name);
return;
}
+ OUTFILE = new_outfile;
+ strmake(outfile, file_name, FN_REFLEN-1);
+ tee_fprintf(stdout, "Logging to file '%s'\n", file_name);
+ opt_outfile= 1;
+ return;
}
+
static void end_tee()
{
my_fclose(OUTFILE, MYF(0));
+ OUTFILE= 0;
+ opt_outfile= 0;
return;
}
@@ -1534,11 +1582,12 @@ print_field_types(MYSQL_RES *result)
MYSQL_FIELD *field;
while ((field = mysql_fetch_field(result)))
{
- tee_fprintf(PAGER,"%s '%s' %d %d %d %d %d\n",
+ tee_fprintf(PAGER,"Name: '%s'\nTable: '%s'\nType: %d\nLength: %d\nMax length: %d\nIs_null: %d\nFlags: %d\nDecimals: %d\n\n",
field->name,
field->table ? "" : field->table,
(int) field->type,
- field->length, field->max_length,
+ field->length, field->max_length,
+ !IS_NOT_NULL(field->flags),
field->flags, field->decimals);
}
tee_puts("", PAGER);
@@ -1562,7 +1611,7 @@ print_table_data(MYSQL_RES *result)
separator.copy("+",1);
while ((field = mysql_fetch_field(result)))
{
- uint length=skip_column_names ? 0 : (uint) strlen(field->name);
+ uint length= column_names ? (uint) strlen(field->name) : 0;
if (quick)
length=max(length,field->length);
else
@@ -1574,7 +1623,7 @@ print_table_data(MYSQL_RES *result)
separator.append('+');
}
tee_puts(separator.c_ptr(), PAGER);
- if (!skip_column_names)
+ if (column_names)
{
mysql_field_seek(result,0);
(void) tee_fputs("|", PAGER);
@@ -1588,18 +1637,19 @@ print_table_data(MYSQL_RES *result)
tee_puts(separator.c_ptr(), PAGER);
}
- while ((cur = mysql_fetch_row(result)))
+ while ((cur= mysql_fetch_row(result)))
{
(void) tee_fputs("|", PAGER);
- mysql_field_seek(result,0);
- for (uint off=0 ; off < mysql_num_fields(result); off++)
+ mysql_field_seek(result, 0);
+ for (uint off= 0; off < mysql_num_fields(result); off++)
{
- const char *str=cur[off] ? cur[off] : "NULL";
- field = mysql_fetch_field(result);
- uint length=field->max_length;
+ const char *str= cur[off] ? cur[off] : "NULL";
+ field= mysql_fetch_field(result);
+ uint length= field->max_length;
if (length > MAX_COLUMN_LENGTH)
{
- tee_fputs(str,PAGER); tee_fputs(" |",PAGER);
+ tee_fputs(str, PAGER);
+ tee_fputs(" |", PAGER);
}
else
tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|",
@@ -1611,15 +1661,16 @@ print_table_data(MYSQL_RES *result)
my_afree((gptr) num_flag);
}
+
static void
print_table_data_html(MYSQL_RES *result)
{
- MYSQL_ROW cur;
- MYSQL_FIELD *field;
+ MYSQL_ROW cur;
+ MYSQL_FIELD *field;
mysql_field_seek(result,0);
(void) tee_fputs("<TABLE BORDER=1><TR>", PAGER);
- if (!skip_column_names)
+ if (column_names)
{
while((field = mysql_fetch_field(result)))
{
@@ -1645,6 +1696,38 @@ print_table_data_html(MYSQL_RES *result)
}
+static void
+print_table_data_xml(MYSQL_RES *result)
+{
+ MYSQL_ROW cur;
+ MYSQL_FIELD *fields;
+
+ mysql_field_seek(result,0);
+
+ tee_fputs("<?xml version=\"1.0\"?>\n\n<resultset statement=\"", PAGER);
+ xmlencode_print(glob_buffer.ptr(), strlen(glob_buffer.ptr()));
+ tee_fputs("\">", PAGER);
+
+ fields = mysql_fetch_fields(result);
+ while ((cur = mysql_fetch_row(result)))
+ {
+ (void) tee_fputs("\n <row>\n", PAGER);
+ for (uint i=0; i < mysql_num_fields(result); i++)
+ {
+ ulong *lengths=mysql_fetch_lengths(result);
+ tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ xmlencode_print(cur[i], lengths[i]);
+ tee_fprintf(PAGER, "</%s>\n", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ }
+ (void) tee_fputs(" </row>\n", PAGER);
+ }
+ (void) tee_fputs("</resultset>\n", PAGER);
+}
+
static void
print_table_data_vertically(MYSQL_RES *result)
@@ -1677,6 +1760,36 @@ print_table_data_vertically(MYSQL_RES *result)
}
+static const char
+*array_value(const char **array, char key)
+{
+ int x;
+ for (x= 0; array[x]; x+= 2)
+ if (*array[x] == key)
+ return array[x + 1];
+ return 0;
+}
+
+
+static void
+xmlencode_print(const char *src, uint length)
+{
+ if (!src)
+ tee_fputs("NULL", PAGER);
+ else
+ {
+ for (const char *p = src; *p && length; *p++, length--)
+ {
+ const char *t;
+ if ((t = array_value(xmlmeta, *p)))
+ tee_fputs(t, PAGER);
+ else
+ tee_putc(*p, PAGER);
+ }
+ }
+}
+
+
static void
safe_put_field(const char *pos,ulong length)
{
@@ -1706,7 +1819,7 @@ safe_put_field(const char *pos,ulong length)
tee_fputs("\\n", PAGER); // This too
else if (*pos == '\\')
tee_fputs("\\\\", PAGER);
- else
+ else
tee_putc(*pos, PAGER);
}
}
@@ -1720,7 +1833,7 @@ print_tab_data(MYSQL_RES *result)
MYSQL_FIELD *field;
ulong *lengths;
- if (opt_silent < 2 && !skip_column_names)
+ if (opt_silent < 2 && column_names)
{
int first=0;
while ((field = mysql_fetch_field(result)))
@@ -1738,7 +1851,7 @@ print_tab_data(MYSQL_RES *result)
for (uint off=1 ; off < mysql_num_fields(result); off++)
{
(void) tee_fputs("\t", PAGER);
- safe_put_field(cur[off],lengths[off]);
+ safe_put_field(cur[off], lengths[off]);
}
(void) tee_fputs("\n", PAGER);
}
@@ -1757,57 +1870,51 @@ com_tee(String *buffer, char *line __attribute__((unused)))
{
if (!strlen(outfile))
{
- printf("No previous outfile available, you must give the filename!\n");
- opt_outfile=0;
+ printf("No previous outfile available, you must give a filename!\n");
return 0;
}
- }
- else
- {
- while (isspace(*param))
- param++;
- end= strend(param);
- while (end > file_name && (isspace(end[-1]) || iscntrl(end[-1])))
- end--;
- end[0]= 0;
- if ((*(end - 1) == '"' && *param == '"') ||
- (*(end - 1) == '\'' && *param == '\''))
+ else if (opt_outfile)
{
- *--end= 0;
- param++;
+ tee_fprintf(stdout, "Currently logging to file '%s'\n", outfile);
+ return 0;
}
- strmake(file_name, param, sizeof(file_name) - 1);
- strmov(outfile, file_name);
+ else
+ param = outfile; //resume using the old outfile
}
- if (!strlen(outfile))
+
+ /* eliminate the spaces before the parameters */
+ while (isspace(*param))
+ param++;
+ end= strmake(file_name, param, sizeof(file_name) - 1);
+ /* remove end space from command line */
+ while (end > file_name && (isspace(end[-1]) || iscntrl(end[-1])))
+ end--;
+ end[0]= 0;
+ if (end == file_name)
{
printf("No outfile specified!\n");
return 0;
}
- if (opt_outfile)
- end_tee();
- init_tee();
- opt_outfile= 1;
- tee_fprintf(stdout, "Logging to file '%s'\n", outfile);
+ init_tee(file_name);
return 0;
}
+
static int
com_notee(String *buffer __attribute__((unused)),
char *line __attribute__((unused)))
{
if (opt_outfile)
end_tee();
- opt_outfile=0;
tee_fprintf(stdout, "Outfile disabled.\n");
return 0;
}
/*
-** Sorry, this command is not available in Windows.
+ Sorry, this command is not available in Windows.
*/
-#ifndef __WIN__
+#ifdef USE_POPEN
static int
com_pager(String *buffer, char *line __attribute__((unused)))
{
@@ -1818,9 +1925,9 @@ com_pager(String *buffer, char *line __attribute__((unused)))
/* Skip space from file name */
while (isspace(*line))
line++;
- if (!(param = strchr(line, ' '))) // if pager was not given, use the default
+ if (!(param= strchr(line, ' '))) // if pager was not given, use the default
{
- if (!strlen(default_pager))
+ if (!default_pager[0])
{
tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
opt_nopager=1;
@@ -1860,10 +1967,10 @@ com_nopager(String *buffer __attribute__((unused)),
/*
-** Sorry, you can't send the result to an editor in Win32
+ Sorry, you can't send the result to an editor in Win32
*/
-#ifndef __WIN__
+#ifdef USE_POPEN
static int
com_edit(String *buffer,char *line __attribute__((unused)))
{
@@ -1911,6 +2018,10 @@ static int
com_quit(String *buffer __attribute__((unused)),
char *line __attribute__((unused)))
{
+#ifdef __NETWARE__
+ // let the screen auto close on a normal shutdown
+ setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
+#endif
status.exit_status=0;
return 1;
}
@@ -1920,11 +2031,36 @@ com_rehash(String *buffer __attribute__((unused)),
char *line __attribute__((unused)))
{
#ifdef HAVE_READLINE
- build_completion_hash(0,0);
+ build_completion_hash(1, 0);
#endif
return 0;
}
+
+#ifdef USE_POPEN
+static int
+com_shell(String *buffer, char *line __attribute__((unused)))
+{
+ char *shell_cmd;
+ if (!(shell_cmd = strchr(line, ' ')))
+ {
+ put_info("Usage: \\! shell-command", INFO_ERROR);
+ return -1;
+ }
+ /*
+ The output of the shell command does not
+ get directed to the pager or the outfile
+ */
+ if (system(shell_cmd) == -1)
+ {
+ put_info(strerror(errno), INFO_ERROR, errno);
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+
static int
com_print(String *buffer,char *line __attribute__((unused)))
{
@@ -1941,7 +2077,7 @@ static int
com_connect(String *buffer, char *line)
{
char *tmp,buff[256];
- bool save_rehash=no_rehash;
+ bool save_rehash= rehash;
int error;
if (buffer)
@@ -1963,17 +2099,17 @@ com_connect(String *buffer, char *line)
}
}
else
- no_rehash=1; // Quick re-connect
+ rehash= 0; // Quick re-connect
buffer->length(0); // command used
}
else
- no_rehash=1;
+ rehash= 0;
error=sql_connect(current_host,current_db,current_user,opt_password,0);
- no_rehash=save_rehash;
+ rehash= save_rehash;
if (connected)
{
- sprintf(buff,"Connection id: %ld",mysql_thread_id(&mysql));
+ sprintf(buff,"Connection id: %lu",mysql_thread_id(&mysql));
put_info(buff,INFO_INFO);
sprintf(buff,"Current database: %s\n",
current_db ? current_db : "*** NONE ***");
@@ -2055,7 +2191,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
if (!current_db || cmp_database(current_db,tmp))
{
if (one_database)
- skip_updates=1;
+ skip_updates= 1;
else
{
/*
@@ -2077,12 +2213,12 @@ com_use(String *buffer __attribute__((unused)), char *line)
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
current_db=my_strdup(tmp,MYF(MY_WME));
#ifdef HAVE_READLINE
- build_completion_hash(no_rehash,1);
+ build_completion_hash(rehash, 1);
#endif
}
}
else
- skip_updates=0;
+ skip_updates= 0;
put_info("Database changed",INFO_INFO);
return 0;
}
@@ -2093,9 +2229,9 @@ sql_real_connect(char *host,char *database,char *user,char *password,
uint silent)
{
if (connected)
- { /* if old is open, close it first */
- mysql_close(&mysql);
+ {
connected= 0;
+ mysql_close(&mysql);
}
mysql_init(&mysql);
if (opt_connect_timeout)
@@ -2111,7 +2247,7 @@ sql_real_connect(char *host,char *database,char *user,char *password,
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
- opt_ssl_capath);
+ opt_ssl_capath, opt_ssl_cipher);
#endif
if (safe_updates)
{
@@ -2121,8 +2257,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
select_limit,max_join_size);
mysql_options(&mysql, MYSQL_INIT_COMMAND, init_command);
}
- if (!mysql_real_connect(&mysql,host,user,password,
- database,opt_mysql_port,opt_mysql_unix_port,
+ if (!mysql_real_connect(&mysql, host, user, password,
+ database, opt_mysql_port, opt_mysql_unix_port,
connect_flag))
{
if (!silent ||
@@ -2138,7 +2274,7 @@ sql_real_connect(char *host,char *database,char *user,char *password,
connected=1;
mysql.reconnect=info_flag ? 1 : 0; // We want to know if this happens
#ifdef HAVE_READLINE
- build_completion_hash(no_rehash,1);
+ build_completion_hash(rehash, 1);
#endif
return 0;
}
@@ -2183,22 +2319,30 @@ static int
com_status(String *buffer __attribute__((unused)),
char *line __attribute__((unused)))
{
- char *status;
+ const char *status;
tee_puts("--------------", stdout);
usage(1); /* Print version */
if (connected)
{
MYSQL_RES *result;
LINT_INIT(result);
- tee_fprintf(stdout, "\nConnection id:\t\t%ld\n",mysql_thread_id(&mysql));
+ tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql));
if (!mysql_query(&mysql,"select DATABASE(),USER()") &&
(result=mysql_use_result(&mysql)))
{
MYSQL_ROW cur=mysql_fetch_row(result);
- tee_fprintf(stdout, "Current database:\t%s\n",cur[0]);
+ tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : "");
tee_fprintf(stdout, "Current user:\t\t%s\n",cur[1]);
(void) mysql_fetch_row(result); // Read eof
}
+#ifdef HAVE_OPENSSL
+ if (mysql.net.vio && mysql.net.vio->ssl_arg &&
+ SSL_get_cipher((SSL*) mysql.net.vio->ssl_arg))
+ tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n",
+ SSL_get_cipher((SSL*) mysql.net.vio->ssl_arg));
+ else
+#endif /* HAVE_OPENSSL */
+ tee_puts("SSL:\t\t\tNot in use", stdout);
}
else
{
@@ -2213,7 +2357,7 @@ com_status(String *buffer __attribute__((unused)),
tee_fprintf(stdout, "\nAll updates ignored to this database\n");
vidattr(A_NORMAL);
}
-#ifndef __WIN__
+#ifdef USE_POPEN
tee_fprintf(stdout, "Current pager:\t\t%s\n", pager);
tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : "");
#endif
@@ -2232,11 +2376,11 @@ com_status(String *buffer __attribute__((unused)),
if ((status=mysql_stat(&mysql)) && !mysql_error(&mysql)[0])
{
- char *pos,buff[40];
ulong sec;
- pos=strchr(status,' ');
- *pos++=0;
- tee_fprintf(stdout, "%s\t\t\t", status); /* print label */
+ char buff[40];
+ const char *pos= strchr(status,' ');
+ /* print label */
+ tee_fprintf(stdout, "%.*s\t\t\t", (int) (pos-status), status);
if ((status=str2int(pos,10,0,LONG_MAX,(long*) &sec)))
{
nice_time((double) sec,buff,0);
@@ -2269,31 +2413,32 @@ select_limit, max_join_size);
static int
put_info(const char *str,INFO_TYPE info_type,uint error)
{
+ FILE *file= (info_type == INFO_ERROR ? stderr : stdout);
static int inited=0;
-
+
if (status.batch)
{
if (info_type == INFO_ERROR)
{
- (void) fflush(stdout);
- fprintf(stderr,"ERROR");
+ (void) fflush(file);
+ fprintf(file,"ERROR");
if (error)
- (void) fprintf(stderr," %d",error);
- if (status.query_start_line && ! skip_line_numbers)
+ (void) fprintf(file," %d",error);
+ if (status.query_start_line && line_numbers)
{
- (void) fprintf(stderr," at line %lu",status.query_start_line);
+ (void) fprintf(file," at line %lu",status.query_start_line);
if (status.file_name)
- (void) fprintf(stderr," in file: '%s'", status.file_name);
+ (void) fprintf(file," in file: '%s'", status.file_name);
}
- (void) fprintf(stderr,": %s\n",str);
- (void) fflush(stderr);
+ (void) fprintf(file,": %s\n",str);
+ (void) fflush(file);
if (!ignore_errors)
return 1;
}
else if (info_type == INFO_RESULT && verbose > 1)
- tee_puts(str, stdout);
+ tee_puts(str, file);
if (unbuffered)
- fflush(stdout);
+ fflush(file);
return info_type == INFO_ERROR ? -1 : 0;
}
if (!opt_silent || info_type == INFO_ERROR)
@@ -2307,20 +2452,21 @@ put_info(const char *str,INFO_TYPE info_type,uint error)
}
if (info_type == INFO_ERROR)
{
- putchar('\007'); /* This should make a bell */
+ if (!opt_nobeep)
+ putchar('\007'); /* This should make a bell */
vidattr(A_STANDOUT);
if (error)
- (void) tee_fprintf(stderr, "ERROR %d: ", error);
+ (void) tee_fprintf(file, "ERROR %d: ", error);
else
- tee_puts("ERROR: ", stdout);
+ tee_puts("ERROR: ", file);
}
else
vidattr(A_BOLD);
- (void) tee_puts(str, stdout);
+ (void) tee_puts(str, file);
vidattr(A_NORMAL);
}
if (unbuffered)
- fflush(stdout);
+ fflush(file);
return info_type == INFO_ERROR ? -1 : 0;
}
@@ -2385,17 +2531,19 @@ void tee_putc(int c, FILE *file)
putc(c, OUTFILE);
}
-#if defined( __WIN__) || defined( OS2)
+#if defined( __WIN__) || defined( OS2) || defined(__NETWARE__)
#include <time.h>
#else
#include <sys/times.h>
+#ifdef _SC_CLK_TCK // For mit-pthreads
#undef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
#endif
+#endif
static ulong start_timer(void)
{
-#if defined( __WIN__) || defined( OS2)
+#if defined( __WIN__) || defined( OS2) || defined(__NETWARE__)
return clock();
#else
struct tms tms_tmp;
@@ -2450,6 +2598,190 @@ static void mysql_end_timer(ulong start_time,char *buff)
strmov(strend(buff),")");
}
+static const char* construct_prompt()
+{
+ processed_prompt.free(); // Erase the old prompt
+ time_t lclock = time(NULL); // Get the date struct
+ struct tm *t = localtime(&lclock);
+
+ /* parse thru the settings for the prompt */
+ for (char *c = current_prompt; *c ; *c++)
+ {
+ if (*c != PROMPT_CHAR)
+ processed_prompt.append(*c);
+ else
+ {
+ switch (*++c) {
+ case '\0':
+ c--; // stop it from going beyond if ends with %
+ break;
+ case 'c':
+ add_int_to_prompt(++prompt_counter);
+ break;
+ case 'v':
+ if (connected)
+ processed_prompt.append(mysql_get_server_info(&mysql));
+ else
+ processed_prompt.append("not_connected");
+ break;
+ case 'd':
+ processed_prompt.append(current_db ? current_db : "(none)");
+ break;
+ case 'h':
+ {
+ const char *prompt;
+ prompt= connected ? mysql_get_host_info(&mysql) : "not_connected";
+ if (strstr(prompt, "Localhost"))
+ processed_prompt.append("localhost");
+ else
+ {
+ const char *end=strcend(prompt,' ');
+ processed_prompt.append(prompt, (uint) (end-prompt));
+ }
+ break;
+ }
+ case 'p':
+ if (!connected)
+ {
+ processed_prompt.append("not_connected");
+ break;
+ }
+ if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || !
+ mysql.unix_socket)
+ add_int_to_prompt(mysql.port);
+ else
+ {
+ char *pos=strrchr(mysql.unix_socket,'/');
+ processed_prompt.append(pos ? pos+1 : mysql.unix_socket);
+ }
+ break;
+ case 'U':
+ if (!full_username)
+ init_username();
+ processed_prompt.append(full_username);
+ break;
+ case 'u':
+ if (!full_username)
+ init_username();
+ processed_prompt.append(part_username);
+ break;
+ case PROMPT_CHAR:
+ processed_prompt.append(PROMPT_CHAR);
+ break;
+ case 'n':
+ processed_prompt.append('\n');
+ break;
+ case ' ':
+ case '_':
+ processed_prompt.append(' ');
+ break;
+ case 'R':
+ add_int_to_prompt(t->tm_hour);
+ break;
+ case 'r':
+ int getHour;
+ getHour = t->tm_hour % 12;
+ if (getHour == 0)
+ getHour=12;
+ add_int_to_prompt(getHour);
+ break;
+ case 'm':
+ if (t->tm_min < 10)
+ processed_prompt.append('0');
+ add_int_to_prompt(t->tm_min);
+ break;
+ case 'y':
+ int getYear;
+ getYear = t->tm_year % 100;
+ if (getYear < 10)
+ processed_prompt.append('0');
+ add_int_to_prompt(getYear);
+ break;
+ case 'Y':
+ add_int_to_prompt(t->tm_year+1900);
+ break;
+ case 'D':
+ char* dateTime;
+ time_t lclock;
+ lclock = time(NULL);
+ dateTime = ctime(&lclock);
+ processed_prompt.append(strtok(dateTime,"\n"));
+ break;
+ case 's':
+ add_int_to_prompt(t->tm_sec);
+ break;
+ case 'w':
+ processed_prompt.append(day_names[t->tm_wday]);
+ break;
+ case 'P':
+ processed_prompt.append(t->tm_hour < 12 ? "am" : "pm");
+ break;
+ case 'o':
+ add_int_to_prompt(t->tm_mon+1);
+ break;
+ case 'O':
+ processed_prompt.append(month_names[t->tm_mon]);
+ break;
+ case '\'':
+ processed_prompt.append("'");
+ break;
+ case '"':
+ processed_prompt.append('"');
+ break;
+ case 'S':
+ processed_prompt.append(';');
+ break;
+ case 't':
+ processed_prompt.append('\t');
+ break;
+ default:
+ processed_prompt.append(c);
+ }
+ }
+ }
+ processed_prompt.append('\0');
+ return processed_prompt.ptr();
+}
+
+
+static void add_int_to_prompt(int toadd)
+{
+ char buffer[16];
+ int10_to_str(toadd,buffer,10);
+ processed_prompt.append(buffer);
+}
+
+static void init_username()
+{
+ my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
+
+ MYSQL_RES *result;
+ LINT_INIT(result);
+ if (!mysql_query(&mysql,"select USER()") &&
+ (result=mysql_use_result(&mysql)))
+ {
+ MYSQL_ROW cur=mysql_fetch_row(result);
+ full_username=my_strdup(cur[0],MYF(MY_WME));
+ part_username=my_strdup(strtok(cur[0],"@"),MYF(MY_WME));
+ (void) mysql_fetch_row(result); // Read eof
+ }
+}
+
+static int com_prompt(String *buffer, char *line)
+{
+ char *ptr=strchr(line, ' ');
+ prompt_counter = 0;
+ my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
+ current_prompt=my_strdup(ptr ? ptr+1 : default_prompt,MYF(MY_WME));
+ if (!ptr)
+ tee_fprintf(stdout, "Returning to default PROMPT of %s\n", default_prompt);
+ else
+ tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
+ return 0;
+}
+
+#ifndef EMBEDDED_LIBRARY
/* Keep sql_string library happy */
gptr sql_alloc(unsigned int Size)
@@ -2461,3 +2793,4 @@ void sql_element_free(void *ptr)
{
my_free((gptr) ptr,MYF(0));
}
+#endif /* EMBEDDED_LIBRARY */
diff --git a/client/mysqladmin.c b/client/mysqladmin.c
index b62be3e45d3..95bc17e880b 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.c
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -22,35 +22,41 @@
#ifdef THREAD
#include <my_pthread.h> /* because of signal() */
#endif
+#include <sys/stat.h>
-#define ADMIN_VERSION "8.23"
+#define ADMIN_VERSION "8.40"
#define MAX_MYSQL_VAR 256
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3
+char *host= NULL, *user= 0, *opt_password= 0;
char truncated_var_names[MAX_MYSQL_VAR][MAX_TRUNC_LENGTH];
char ex_var_names[MAX_MYSQL_VAR][FN_REFLEN];
ulonglong last_values[MAX_MYSQL_VAR];
static int interval=0;
static my_bool option_force=0,interrupted=0,new_line=0,
- opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0;
-static uint tcp_port = 0, option_wait = 0, option_silent=0;
+ opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0,
+ tty_password=0;
+static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations,
+ opt_count_iterations= 0;
static ulong opt_connect_timeout, opt_shutdown_timeout;
static my_string unix_port=0;
-/* When using extended-status relatively, ex_val_max_len is the estimated
- maximum length for any relative value printed by extended-status. The
- idea is to try to keep the length of output as short as possible. */
+/*
+ When using extended-status relatively, ex_val_max_len is the estimated
+ maximum length for any relative value printed by extended-status. The
+ idea is to try to keep the length of output as short as possible.
+*/
+
static uint ex_val_max_len[MAX_MYSQL_VAR];
static my_bool ex_status_printed = 0; /* First output is not relative. */
static uint ex_var_count, max_var_length, max_val_length;
-#include "sslopt-vars.h"
+#include <sslopt-vars.h>
static void print_version(void);
static void usage(void);
-static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user,
- const char *password,uint wait);
+static my_bool sql_connect(MYSQL *mysql, uint wait);
static int execute_commands(MYSQL *mysql,int argc, char **argv);
static int drop_db(MYSQL *mysql,const char *db);
static sig_handler endprog(int signal_number);
@@ -64,7 +70,8 @@ static void print_relative_header();
static void print_relative_line();
static void truncate_names();
static my_bool get_pidfile(MYSQL *mysql, char *pidfile);
-static void wait_pidfile(char *pidfile);
+static my_bool wait_pidfile(char *pidfile, time_t last_modified,
+ struct stat *pidfile_status);
static void store_values(MYSQL_RES *result);
/*
@@ -97,158 +104,168 @@ static const char *command_names[]= {
static TYPELIB command_typelib=
{ array_elements(command_names)-1,"commands", command_names};
-static struct option long_options[] = {
- {"compress", no_argument, 0, 'C'},
- {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR},
- {"debug", optional_argument, 0, '#'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"password", optional_argument, 0, 'p'},
+static struct my_option my_long_options[] =
+{
+ {"count", 'c',
+ "Number of iterations to make. This works with -i (--sleep) only",
+ (gptr*) &nr_iterations, (gptr*) &nr_iterations, 0, GET_UINT,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"force", 'f',
+ "Don't ask for confirmation on drop database; with multiple commands, continue even if an error occurs.",
+ (gptr*) &option_force, (gptr*) &option_force, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are.", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host", (gptr*) &host, (gptr*) &host, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"port", required_argument, 0, 'P'},
- {"relative", no_argument, 0, 'r'},
- {"set-variable", required_argument, 0, 'O'},
- {"silent", no_argument, 0, 's'},
- {"socket", required_argument, 0, 'S'},
- {"sleep", required_argument, 0, 'i'},
-#include "sslopt-longopts.h"
+ {"port", 'P', "Port number to use for connection.", (gptr*) &tcp_port,
+ (gptr*) &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"relative", 'r',
+ "Show difference between current and previous values when used with -i. Currently works only with extended-status.",
+ (gptr*) &opt_relative, (gptr*) &opt_relative, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Silently exit if one can't connect to server",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &unix_port, (gptr*) &unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"sleep", 'i', "Execute commands again and again with a sleep between.",
+ (gptr*) &interval, (gptr*) &interval, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+#include <sslopt-longopts.h>
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.", (gptr*) &user,
+ (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"vertical", no_argument, 0, 'E'},
- {"wait", optional_argument, 0, 'w'},
- {0, 0, 0, 0}
+ {"verbose", 'v', "Write more information.", (gptr*) &opt_verbose,
+ (gptr*) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"vertical", 'E',
+ "Print output vertically. Is similar to --relative, but prints output vertically.",
+ (gptr*) &opt_vertical, (gptr*) &opt_vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"wait", 'w', "Wait and retry if connection is down", 0, 0, 0, GET_UINT,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout,
+ (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 3600*12, 0,
+ 3600*12, 0, 1, 0},
+ {"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", (gptr*) &opt_shutdown_timeout,
+ (gptr*) &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG,
+ SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-static CHANGEABLE_VAR changeable_vars[] = {
- { "connect_timeout", (long*) &opt_connect_timeout, 0, 0, 3600*12, 0, 1},
- { "shutdown_timeout", (long*) &opt_shutdown_timeout, SHUTDOWN_DEF_TIMEOUT, 0,
- 3600*12, 0, 1},
- { 0, 0, 0, 0, 0, 0, 0}
-};
static const char *load_default_groups[]= { "mysqladmin","client",0 };
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ int error = 0;
+
+ switch(optid) {
+ case 'c':
+ opt_count_iterations= 1;
+ break;
+ case 'p':
+ if (argument)
+ {
+ char *start=argument;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(argument,MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
+ }
+ else
+ tty_password=1;
+ break;
+ case 's':
+ option_silent++;
+ break;
+ case 'W':
+#ifdef __WIN__
+ unix_port=MYSQL_NAMEDPIPE;
+#endif
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o,/tmp/mysqladmin.trace");
+ break;
+#include <sslopt-case.h>
+ case 'V':
+ print_version();
+ exit(0);
+ break;
+ case 'w':
+ if (argument)
+ {
+ if ((option_wait=atoi(argument)) <= 0)
+ option_wait=1;
+ }
+ else
+ option_wait= ~0;
+ break;
+ case '?':
+ case 'I': /* Info */
+ error++;
+ break;
+ case OPT_CHARSETS_DIR:
+#if MYSQL_VERSION_ID > 32300
+ charsets_dir = argument;
+#endif
+ break;
+ }
+ if (error)
+ {
+ usage();
+ exit(1);
+ }
+ return 0;
+}
+
+
int main(int argc,char *argv[])
{
- int c, error = 0,option_index=0;
+ int error, ho_error;
MYSQL mysql;
- char *host = NULL,*opt_password=0,*user=0,**commands;
- my_bool tty_password=0;
+ char **commands, **save_argv;
+
MY_INIT(argv[0]);
mysql_init(&mysql);
load_defaults("my",load_default_groups,&argc,&argv);
- set_all_changeable_vars( changeable_vars );
-
- while ((c=getopt_long(argc,argv,
- (char*) "h:i:p::u:#::P:sS:Ct:fq?vVw::WrEO:",
- long_options, &option_index)) != EOF)
+ save_argv = argv; /* Save for free_defaults */
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
{
- switch(c) {
- case 'C':
- opt_compress=1;
- break;
- case 'h':
- host = optarg;
- break;
- case 'q': /* Allow old 'q' option */
- case 'f':
- option_force++;
- break;
- case 'p':
- if (optarg)
- {
- char *start=optarg;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- opt_password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1]=0; /* Cut length of argument */
- }
- else
- tty_password=1;
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- user= my_strdup(optarg,MYF(0));
- break;
-#endif
- case 'i':
- interval=atoi(optarg);
- break;
- case 'P':
- tcp_port= (unsigned int) atoi(optarg);
- break;
- case 'r':
- opt_relative = 1;
- break;
- case 'E':
- opt_vertical = 1;
- break;
- case 'O':
- if (set_changeable_var(optarg, changeable_vars))
- {
- usage();
- return(1);
- }
- break;
- case 's':
- option_silent++;
- break;
- case 'S':
- unix_port= optarg;
- break;
- case 'W':
-#ifdef __WIN__
- unix_port=MYSQL_NAMEDPIPE;
-#endif
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/mysqladmin.trace");
- break;
- case 'V':
- print_version();
- exit(0);
- break;
- case 'v':
- opt_verbose=1;
- break;
- case 'w':
- if (optarg)
- {
- if ((option_wait=atoi(optarg)) <= 0)
- option_wait=1;
- }
- else
- option_wait= ~0;
- break;
-#include "sslopt-case.h"
- default:
- fprintf(stderr,"Illegal option character '%c'\n",opterr);
- /* Fall throught */
- case '?':
- case 'I': /* Info */
- error++;
- break;
- case OPT_CHARSETS_DIR:
-#if MYSQL_VERSION_ID > 32300
- charsets_dir = optarg;
-#endif
- break;
- }
+ free_defaults(save_argv);
+ exit(ho_error);
}
- argc -= optind;
- commands = argv + optind;
- if (error || argc == 0)
+
+ if (argc == 0)
{
usage();
exit(1);
}
+ commands = argv;
if (tty_password)
opt_password = get_tty_password(NullS);
@@ -265,14 +282,14 @@ int main(int argc,char *argv[])
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
- opt_ssl_capath);
-#endif /* HAVE_OPENSSL */
- if (sql_connect(&mysql,host,user,opt_password,option_wait))
+ opt_ssl_capath, opt_ssl_cipher);
+#endif
+ if (sql_connect(&mysql, option_wait))
error = 1;
else
{
error = 0;
- while (!interrupted)
+ while (!interrupted && (!opt_count_iterations || nr_iterations))
{
new_line = 0;
if ((error=execute_commands(&mysql,argc,commands)))
@@ -284,7 +301,7 @@ int main(int argc,char *argv[])
if (option_wait && !interrupted)
{
mysql_close(&mysql);
- if (!sql_connect(&mysql,host,user,opt_password,option_wait))
+ if (!sql_connect(&mysql, option_wait))
{
sleep(1); /* Don't retry too rapidly */
continue; /* Retry */
@@ -299,6 +316,8 @@ int main(int argc,char *argv[])
sleep(interval);
if (new_line)
puts("");
+ if (opt_count_iterations)
+ nr_iterations--;
}
else
break;
@@ -307,7 +326,7 @@ int main(int argc,char *argv[])
}
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
my_free(user,MYF(MY_ALLOW_ZERO_PTR));
- free_defaults(argv);
+ free_defaults(save_argv);
my_end(0);
exit(error ? 1 : 0);
return 0;
@@ -320,15 +339,14 @@ static sig_handler endprog(int signal_number __attribute__((unused)))
}
-static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user,
- const char *password,uint wait)
+static my_bool sql_connect(MYSQL *mysql, uint wait)
{
my_bool info=0;
for (;;)
{
- if (mysql_real_connect(mysql,host,user,password,NullS,tcp_port,unix_port,
- 0))
+ if (mysql_real_connect(mysql,host,user,opt_password,NullS,tcp_port,
+ unix_port, 0))
{
if (info)
{
@@ -337,13 +355,13 @@ static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user,
}
return 0;
}
-
+
if (!wait)
{
if (!option_silent)
{
if (!host)
- host=LOCAL_HOST;
+ host= (char*) LOCAL_HOST;
my_printf_error(0,"connect to server at '%s' failed\nerror: '%s'",
MYF(ME_BELL), host, mysql_error(mysql));
if (mysql_errno(mysql) == CR_CONNECTION_ERROR)
@@ -400,7 +418,7 @@ static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user,
static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
- char *status;
+ const char *status;
for (; argc > 0 ; argv++,argc--)
{
@@ -438,11 +456,18 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
case ADMIN_SHUTDOWN:
{
char pidfile[FN_REFLEN];
- my_bool got_pidfile=0;
- /* Only wait for pidfile on local connections */
- /* If pidfile doesn't exist, continue without pid file checking */
- if (mysql->unix_socket)
- got_pidfile= !get_pidfile(mysql, pidfile);
+ my_bool got_pidfile= 0;
+ time_t last_modified= 0;
+ struct stat pidfile_status;
+
+ /*
+ Only wait for pidfile on local connections
+ If pidfile doesn't exist, continue without pid file checking
+ */
+ if (mysql->unix_socket && (got_pidfile= !get_pidfile(mysql, pidfile)) &&
+ !stat(pidfile, &pidfile_status))
+ last_modified= pidfile_status.st_mtime;
+
if (mysql_shutdown(mysql))
{
my_printf_error(0,"shutdown failed; error: '%s'",MYF(ME_BELL),
@@ -454,7 +479,10 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
if (opt_verbose)
printf("Shutdown signal sent to server; Waiting for pid file to disappear\n");
- wait_pidfile(pidfile); /* Wait until pid file is gone */
+
+ /* Wait until pid file is gone */
+ if (wait_pidfile(pidfile, last_modified, &pidfile_status))
+ return -1;
}
break;
}
@@ -583,7 +611,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
MYSQL_ROW row;
new_line=1;
- if (mysql_query(mysql,"show variables") ||
+ if (mysql_query(mysql,"show /*!40003 GLOBAL */ variables") ||
!(res=mysql_store_result(mysql)))
{
my_printf_error(0,"unable to show variables; error: '%s'",MYF(ME_BELL),
@@ -649,7 +677,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
else
print_top(res);
-
+
ex_status_printed = 1; /* From now on the output will be relative */
mysql_free_result(res);
break;
@@ -745,7 +773,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
else
puts("Slave stopped");
break;
-
+
case ADMIN_PING:
mysql->reconnect=0; /* We want to know of reconnects */
if (!mysql_ping(mysql))
@@ -788,52 +816,14 @@ static void print_version(void)
static void usage(void)
{
- uint i;
print_version();
puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB");
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Administration program for the mysqld daemon.");
printf("Usage: %s [OPTIONS] command command....\n", my_progname);
- printf("\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename`\n\
- -f, --force Don't ask for confirmation on drop database; with\n\
- multiple commands, continue even if an error occurs\n\
- -?, --help Display this help and exit\n\
- --character-sets-dir=...\n\
- Set the character set directory\n\
- -C, --compress Use compression in server/client protocol\n\
- -h, --host=# Connect to host\n\
- -p, --password[=...] Password to use when connecting to server\n\
- If password is not given it's asked from the tty\n");
-#ifdef __WIN__
- puts("-W, --pipe Use named pipes to connect to server");
-#endif
- printf("\
- -P --port=... Port number to use for connection\n\
- -i, --sleep=sec Execute commands again and again with a sleep between\n\
- -r, --relative Show difference between current and previous values\n\
- when used with -i. Currently works only with\n\
- extended-status\n\
- -E, --vertical Print output vertically. Is similar to --relative,\n\
- but prints output vertically.\n\
- -s, --silent Silently exit if one can't connect to server\n\
- -S, --socket=... Socket file to use for connection\n");
-#include "sslopt-usage.h"
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# User for login if not current user\n");
-#endif
- printf("\
- -v, --verbose Write more information\n\
- -V, --version Output version information and exit\n\
- -w, --wait[=retries] Wait and retry if connection is down\n");
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
print_defaults("my",load_default_groups);
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (i=0 ; changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- changeable_vars[i].name,
- (ulong) *changeable_vars[i].varptr);
-
puts("\nWhere command is a one or more of: (Commands may be shortened)\n\
create databasename Create a new database\n\
drop databasename Delete a database and all its tables\n\
@@ -928,7 +918,7 @@ static void print_header(MYSQL_RES *result)
putchar('|');
while ((field = mysql_fetch_field(result)))
{
- printf(" %-*s|",field->max_length+1,field->name);
+ printf(" %-*s|",(int) field->max_length+1,field->name);
}
putchar('\n');
print_top(result);
@@ -983,11 +973,11 @@ static void print_relative_row(MYSQL_RES *result, MYSQL_ROW cur, uint row)
mysql_field_seek(result, 0);
field = mysql_fetch_field(result);
- printf("| %-*s|", field->max_length + 1, cur[0]);
+ printf("| %-*s|", (int) field->max_length + 1, cur[0]);
field = mysql_fetch_field(result);
tmp = cur[1] ? strtoull(cur[1], NULL, 10) : (ulonglong) 0;
- printf(" %-*s|\n", field->max_length + 1,
+ printf(" %-*s|\n", (int) field->max_length + 1,
llstr((tmp - last_values[row]), buff));
last_values[row] = tmp;
}
@@ -1000,11 +990,11 @@ static void print_relative_row_vert(MYSQL_RES *result __attribute__((unused)),
uint length;
ulonglong tmp;
char buff[22];
-
+
if (!row)
putchar('|');
- tmp = cur[1] ? strtoull(cur[1], NULL, 0) : (ulonglong) 0;
+ tmp = cur[1] ? strtoull(cur[1], NULL, 10) : (ulonglong) 0;
printf(" %-*s|", ex_val_max_len[row] + 1,
llstr((tmp - last_values[row]), buff));
@@ -1079,7 +1069,7 @@ static void truncate_names()
*ptr++='+';
*ptr=0;
puts(top_line);
-
+
for (i = 0 ; i < ex_var_count; i++)
{
uint sfx=1,j;
@@ -1121,25 +1111,51 @@ static my_bool get_pidfile(MYSQL *mysql, char *pidfile)
return 1; /* Error */
}
+/*
+ Return 1 if pid file didn't disappear or change
+*/
-static void wait_pidfile(char *pidfile)
+static my_bool wait_pidfile(char *pidfile, time_t last_modified,
+ struct stat *pidfile_status)
{
char buff[FN_REFLEN];
- int fd;
- uint count=0;
+ int error= 1;
+ uint count= 0;
+ DBUG_ENTER("wait_pidfile");
- system_filename(buff,pidfile);
- while ((fd = my_open(buff, O_RDONLY, MYF(0))) >= 0 &&
- count++ < opt_shutdown_timeout && !interrupted)
+ system_filename(buff, pidfile);
+ do
{
- my_close(fd,MYF(0));
+ int fd;
+ if ((fd= my_open(buff, O_RDONLY, MYF(0))) < 0)
+ {
+ error= 0;
+ break;
+ }
+ (void) my_close(fd,MYF(0));
+ if (last_modified && !stat(pidfile, pidfile_status))
+ {
+ if (last_modified != pidfile_status->st_mtime)
+ {
+ /* File changed; Let's assume that mysqld did restart */
+ if (opt_verbose)
+ printf("pid file '%s' changed while waiting for it to disappear!\nmysqld did probably restart\n",
+ buff);
+ error= 0;
+ break;
+ }
+ }
+ if (count++ == opt_shutdown_timeout)
+ break;
sleep(1);
- }
- if (fd >= 0)
+ } while (!interrupted);
+
+ if (error)
{
- my_close(fd,MYF(0));
+ DBUG_PRINT("warning",("Pid file didn't disappear"));
fprintf(stderr,
"Warning; Aborted waiting on pid file: '%s' after %d seconds\n",
buff, count-1);
}
+ DBUG_RETURN(error);
}
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index e0cee438f1b..34b7ae11f74 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -1,36 +1,31 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2001 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
#define MYSQL_CLIENT
#undef MYSQL_SERVER
#include "client_priv.h"
#include <time.h>
+#include <assert.h>
#include "log_event.h"
-#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
+#define BIN_LOG_HEADER_SIZE 4
+#define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4)
-#ifndef OS2
-extern "C"
-{
- int simple_command(MYSQL *mysql,enum enum_server_command command,
- const char *arg, uint length, my_bool skipp_check);
- uint net_safe_read(MYSQL* mysql);
-}
-#endif
+
+#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
char server_version[SERVER_VERSION_LENGTH];
ulong server_id = 0;
@@ -45,48 +40,222 @@ static FILE *result_file;
#ifndef DBUG_OFF
static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace";
#endif
+static const char *load_default_groups[]= { "mysqlbinlog","client",0 };
-static struct option long_options[] =
-{
-#ifndef DBUG_OFF
- {"debug", optional_argument, 0, '#'},
-#endif
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"offset", required_argument, 0, 'o'},
- {"password", optional_argument, 0, 'p'},
- {"port", required_argument, 0, 'P'},
- {"position", required_argument, 0, 'j'},
- {"result-file", required_argument, 0, 'r'},
- {"short-form", no_argument, 0, 's'},
- {"table", required_argument, 0, 't'},
- {"user", required_argument, 0, 'u'},
- {"version", no_argument, 0, 'V'},
-};
-
-void sql_print_error(const char *format,...);
+void sql_print_error(const char *format, ...);
-static bool short_form = 0;
+static bool one_database = 0;
+static const char* database= 0;
+static my_bool force_opt= 0, short_form= 0, remote_opt= 0;
static ulonglong offset = 0;
-static const char* host = "localhost";
+static const char* host = 0;
static int port = MYSQL_PORT;
-static const char* user = "test";
+static const char* sock= 0;
+static const char* user = 0;
static char* pass = 0;
static ulonglong position = 0;
-static bool use_remote = 0;
static short binlog_flags = 0;
static MYSQL* mysql = NULL;
-static const char* table = 0;
+
+static const char* dirname_for_local_load= 0;
static void dump_local_log_entries(const char* logname);
static void dump_remote_log_entries(const char* logname);
static void dump_log_entries(const char* logname);
static void dump_remote_file(NET* net, const char* fname);
-static void dump_remote_table(NET* net, const char* db, const char* table);
static void die(const char* fmt, ...);
-static void cleanup();
static MYSQL* safe_connect();
+class Load_log_processor
+{
+ char target_dir_name[MY_NFILE];
+ int target_dir_name_len;
+ DYNAMIC_ARRAY file_names;
+
+ const char *create_file(Create_file_log_event *ce);
+ void append_to_file(const char* fname, int flags,
+ gptr data, uint size)
+ {
+ File file;
+ if (((file= my_open(fname,flags,MYF(MY_WME))) < 0) ||
+ my_write(file,(byte*) data,size,MYF(MY_WME|MY_NABP)) ||
+ my_close(file,MYF(MY_WME)))
+ exit(1);
+ }
+
+public:
+ Load_log_processor()
+ {
+ init_dynamic_array(&file_names,sizeof(Create_file_log_event*),
+ 100,100 CALLER_INFO);
+ }
+
+ ~Load_log_processor()
+ {
+ destroy();
+ delete_dynamic(&file_names);
+ }
+
+ void init_by_dir_name(const char *dir)
+ {
+ target_dir_name_len= (convert_dirname(target_dir_name, dir, NullS) -
+ target_dir_name);
+ }
+ void init_by_cur_dir()
+ {
+ if (my_getwd(target_dir_name,sizeof(target_dir_name),MYF(MY_WME)))
+ exit(1);
+ target_dir_name_len= strlen(target_dir_name);
+ }
+ void destroy()
+ {
+ Create_file_log_event **ptr= (Create_file_log_event**)file_names.buffer;
+ Create_file_log_event **end= ptr + file_names.elements;
+ for (; ptr<end; ptr++)
+ {
+ if (*ptr)
+ {
+ my_free((char*)(*ptr)->fname,MYF(MY_WME));
+ delete *ptr;
+ *ptr= 0;
+ }
+ }
+ }
+ Create_file_log_event *grab_event(uint file_id)
+ {
+ if (file_id >= file_names.elements)
+ return 0;
+ Create_file_log_event **ptr=
+ (Create_file_log_event**)file_names.buffer + file_id;
+ Create_file_log_event *res= *ptr;
+ *ptr= 0;
+ return res;
+ }
+ void process(Create_file_log_event *ce)
+ {
+ const char *fname= create_file(ce);
+ append_to_file(fname,O_CREAT|O_EXCL|O_BINARY|O_WRONLY,ce->block,
+ ce->block_len);
+ }
+ void process(Append_block_log_event *ae)
+ {
+ Create_file_log_event* ce= (ae->file_id < file_names.elements) ?
+ *((Create_file_log_event**)file_names.buffer + ae->file_id) : 0;
+
+ if (ce)
+ append_to_file(ce->fname,O_APPEND|O_BINARY|O_WRONLY, ae->block,
+ ae->block_len);
+ else
+ {
+ /*
+ There is no Create_file event (a bad binlog or a big
+ --position). Assuming it's a big --position, we just do nothing and
+ print a warning.
+ */
+ fprintf(stderr,"Warning: ignoring Append_block as there is no \
+Create_file event for file_id: %u\n",ae->file_id);
+ }
+ }
+};
+
+
+const char *Load_log_processor::create_file(Create_file_log_event *ce)
+{
+ const char *bname= ce->fname+dirname_length(ce->fname);
+ uint blen= ce->fname_len - (bname-ce->fname);
+ uint full_len= target_dir_name_len + blen + 9 + 9 + 1;
+ uint version= 0;
+ char *tmp, *ptr;
+
+ if (!(tmp= my_malloc(full_len,MYF(MY_WME))) ||
+ set_dynamic(&file_names,(gptr)&ce,ce->file_id))
+ {
+ die("Could not construct local filename %s%s",target_dir_name,bname);
+ return 0;
+ }
+
+ memcpy(tmp, target_dir_name, target_dir_name_len);
+ ptr= tmp+ target_dir_name_len;
+ memcpy(ptr,bname,blen);
+ ptr+= blen;
+ ptr+= my_sprintf(ptr,(ptr,"-%x",ce->file_id));
+
+ /*
+ Note that this code has a possible race condition if there was was
+ many simultaneous clients running which tried to create files at the same
+ time. Fortunately this should never be the case.
+
+ A better way to do this would be to use 'create_tmp_file() and avoid this
+ race condition altogether on the expense of getting more cryptic file
+ names.
+ */
+ for (;;)
+ {
+ sprintf(ptr,"-%x",version);
+ if (access(tmp,F_OK))
+ break;
+ /* If we have to try more than 1000 times, something is seriously wrong */
+ if (version++ > 1000)
+ {
+ die("Could not construct local filename %s%s",target_dir_name,bname);
+ return 0;
+ }
+ }
+ ce->set_fname_outside_temp_buf(tmp,strlen(tmp));
+ return tmp;
+}
+
+
+Load_log_processor load_processor;
+
+static struct my_option my_long_options[] =
+{
+#ifndef DBUG_OFF
+ {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option,
+ (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"database", 'd', "List entries for just this database (local log only).",
+ (gptr*) &database, (gptr*) &database, 0, GET_STR_ALLOC, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"force-read", 'f', "Force reading unknown binlog events.",
+ (gptr*) &force_opt, (gptr*) &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Get the binlog from server.", (gptr*) &host, (gptr*) &host,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"offset", 'o', "Skip the first N entries.", (gptr*) &offset, (gptr*) &offset,
+ 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p', "Password to connect to remote server.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Use port to connect to the remote server.",
+ (gptr*) &port, (gptr*) &port, 0, GET_INT, REQUIRED_ARG, MYSQL_PORT, 0, 0,
+ 0, 0, 0},
+ {"position", 'j', "Start reading the binlog at position N.",
+ (gptr*) &position, (gptr*) &position, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"result-file", 'r', "Direct output to a given file.", 0, 0, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"read-from-remote-server", 'R', "Read binary logs from a MySQL server",
+ (gptr*) &remote_opt, (gptr*) &remote_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"short-form", 's', "Just show the queries, no extra info.",
+ (gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &sock, (gptr*) &sock, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"user", 'u', "Connect to the remote server as username.",
+ (gptr*) &user, (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"local-load", 'l', "Prepare files for local load in directory.",
+ (gptr*) &dirname_for_local_load, (gptr*) &dirname_for_local_load, 0,
+ GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
void sql_print_error(const char *format,...)
{
@@ -117,38 +286,23 @@ static void die(const char* fmt, ...)
static void print_version()
{
- printf("%s Ver 1.6 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE);
+ printf("%s Ver 2.4 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
}
static void usage()
{
print_version();
- puts("By Sasha, for your professional use\n\
-This software comes with NO WARRANTY: see the file PUBLIC for details\n");
+ puts("By Monty and Sasha, for your professional use\n\
+This software comes with NO WARRANTY: This is free software,\n\
+and you are welcome to modify and redistribute it under the GPL license\n");
printf("\
-Dumps a MySQL binary log in a format usable for viewing or for pipeing to\n\
+Dumps a MySQL binary log in a format usable for viewing or for piping to\n\
the mysql command line client\n\n");
- printf("Usage: %s [options] log-files\n",my_progname);
- puts("Options:");
-#ifndef DBUG_OFF
- printf("-#, --debug[=...] Output debug log. (%s)\n",
- default_dbug_option);
-#endif
- printf("\
--?, --help Display this help and exit\n\
--s, --short-form Just show the queries, no extra info\n\
--o, --offset=N Skip the first N entries\n\
--h, --host=server Get the binlog from server\n\
--P, --port=port Use port to connect to the remote server\n\
--u, --user=username Connect to the remote server as username\n\
--p, --password=password Password to connect to remote server\n\
--r, --result-file=file Direct output to a given file\n\
--j, --position=N Start reading the binlog at position N\n\
--t, --table=name Get raw table dump using COM_TABLE_DUMB\n\
--V, --version Print version and exit.\n\
-");
+ printf("Usage: %s [options] log-files\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
}
static void dump_remote_file(NET* net, const char* fname)
@@ -181,100 +335,74 @@ static void dump_remote_file(NET* net, const char* fname)
fflush(result_file);
}
-static int parse_args(int *argc, char*** argv)
-{
- int c, opt_index = 0;
- bool tty_password= 0;
- result_file = stdout;
- while((c = getopt_long(*argc, *argv, "so:#::h:j:u:p::P:r:t:?V", long_options,
- &opt_index)) != EOF)
- {
- switch(c)
- {
+extern "C" my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ bool tty_password=0;
+ switch (optid) {
#ifndef DBUG_OFF
- case '#':
- DBUG_PUSH(optarg ? optarg : default_dbug_option);
- break;
+ case '#':
+ DBUG_PUSH(argument ? argument : default_dbug_option);
+ break;
#endif
- case 's':
- short_form = 1;
- break;
-
- case 'o':
- offset = strtoull(optarg,(char**) 0, 10);
- break;
-
- case 'j':
- position = strtoull(optarg,(char**) 0, 10);
- break;
-
- case 'h':
- use_remote = 1;
- host = my_strdup(optarg, MYF(0));
- break;
-
- case 'P':
- use_remote = 1;
- port = atoi(optarg);
- break;
-
- case 'p':
- use_remote = 1;
- if (optarg)
- {
- char *start=optarg;
- my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
- pass= my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1]=0; /* Cut length of argument */
- }
- else
- tty_password=1;
- break;
-
- case 'r':
- if (!(result_file = my_fopen(optarg, O_WRONLY | O_BINARY, MYF(MY_WME))))
- exit(1);
- break;
-
- case 'u':
- use_remote = 1;
- user = my_strdup(optarg, MYF(0));
- break;
-
- case 't':
- table = my_strdup(optarg, MYF(0));
- break;
-
- case 'V':
- print_version();
- exit(0);
-
- case '?':
- default:
- usage();
- exit(0);
-
+ case 'd':
+ one_database = 1;
+ break;
+ case 'p':
+ if (argument)
+ {
+ my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
+ char *start=argument;
+ pass= my_strdup(argument,MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
}
+ else
+ tty_password=1;
+ break;
+ case 'r':
+ if (!(result_file = my_fopen(argument, O_WRONLY | O_BINARY, MYF(MY_WME))))
+ exit(1);
+ break;
+ case 'R':
+ remote_opt= 1;
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
}
-
- (*argc)-=optind;
- (*argv)+=optind;
if (tty_password)
pass= get_tty_password(NullS);
return 0;
}
+
+static int parse_args(int *argc, char*** argv)
+{
+ int ho_error;
+
+ result_file = stdout;
+ load_defaults("my",load_default_groups,argc,argv);
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ return 0;
+}
+
static MYSQL* safe_connect()
{
MYSQL *local_mysql = mysql_init(NULL);
if(!local_mysql)
die("Failed on mysql_init");
- if(!mysql_real_connect(local_mysql, host, user, pass, 0, port, 0, 0))
+ if (!mysql_real_connect(local_mysql, host, user, pass, 0, port, sock, 0))
die("failed on connect: %s", mysql_error(local_mysql));
return local_mysql;
@@ -282,39 +410,57 @@ static MYSQL* safe_connect()
static void dump_log_entries(const char* logname)
{
- if(use_remote)
+ if (remote_opt)
dump_remote_log_entries(logname);
else
dump_local_log_entries(logname);
}
-static void dump_remote_table(NET* net, const char* db, const char* table)
+static int check_master_version(MYSQL* mysql)
{
- char buf[1024];
- char * p = buf;
- uint table_len = (uint) strlen(table);
- uint db_len = (uint) strlen(db);
- if(table_len + db_len > sizeof(buf) - 2)
- die("Buffer overrun");
-
- *p++ = db_len;
- memcpy(p, db, db_len);
- p += db_len;
- *p++ = table_len;
- memcpy(p, table, table_len);
-
- if(simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1))
- die("Error sending the table dump command");
+ MYSQL_RES* res = 0;
+ MYSQL_ROW row;
+ const char* version;
+ int old_format = 0;
- for(;;)
+ if (mysql_query(mysql, "SELECT VERSION()") ||
+ !(res = mysql_store_result(mysql)))
+ {
+ mysql_close(mysql);
+ die("Error checking master version: %s",
+ mysql_error(mysql));
+ }
+ if (!(row = mysql_fetch_row(res)))
+ {
+ mysql_free_result(res);
+ mysql_close(mysql);
+ die("Master returned no rows for SELECT VERSION()");
+ return 1;
+ }
+ if (!(version = row[0]))
{
- uint packet_len = my_net_read(net);
- if(packet_len == 0) break; // end of file
- if(packet_len == packet_error)
- die("Error reading packet in table dump");
- my_fwrite(result_file, (byte*)net->read_pos, packet_len, MYF(MY_WME));
- fflush(result_file);
+ mysql_free_result(res);
+ mysql_close(mysql);
+ die("Master reported NULL for the version");
+ }
+
+ switch (*version) {
+ case '3':
+ old_format = 1;
+ break;
+ case '4':
+ case '5':
+ old_format = 0;
+ break;
+ default:
+ sql_print_error("Master reported unrecognized MySQL version '%s'",
+ version);
+ mysql_free_result(res);
+ mysql_close(mysql);
+ return 1;
}
+ mysql_free_result(res);
+ return old_format;
}
@@ -324,37 +470,41 @@ static void dump_remote_log_entries(const char* logname)
char last_db[FN_REFLEN+1] = "";
uint len;
NET* net = &mysql->net;
- if(!position) position = 4; // protect the innocent from spam
- if (position < 4)
+ int old_format;
+ old_format = check_master_version(mysql);
+
+ if (!position)
+ position = BIN_LOG_HEADER_SIZE; // protect the innocent from spam
+ if (position < BIN_LOG_HEADER_SIZE)
{
- position = 4;
+ position = BIN_LOG_HEADER_SIZE;
// warn the guity
- sql_print_error("Warning: The position in the binary log can't be less than 4.\nStarting from position 4\n");
+ sql_print_error("Warning: The position in the binary log can't be less than %d.\nStarting from position %d\n", BIN_LOG_HEADER_SIZE, BIN_LOG_HEADER_SIZE);
}
int4store(buf, position);
- int2store(buf + 4, binlog_flags);
+ int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags);
len = (uint) strlen(logname);
int4store(buf + 6, 0);
memcpy(buf + 10, logname,len);
- if(simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1))
+ if (simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1))
die("Error sending the log dump command");
-
- for(;;)
+
+ for (;;)
{
+ const char *error;
len = net_safe_read(mysql);
if (len == packet_error)
die("Error reading packet from server: %s", mysql_error(mysql));
- if(len == 1 && net->read_pos[0] == 254)
+ if (len < 8 && net->read_pos[0] == 254)
break; // end of data
DBUG_PRINT("info",( "len= %u, net->read_pos[5] = %d\n",
len, net->read_pos[5]));
- Log_event * ev = Log_event::read_log_event(
- (const char*) net->read_pos + 1 ,
- len - 1);
- if(ev)
+ Log_event *ev = Log_event::read_log_event((const char*) net->read_pos + 1 ,
+ len - 1, &error, old_format);
+ if (ev)
{
ev->print(result_file, short_form, last_db);
- if(ev->get_type_code() == LOAD_EVENT)
+ if (ev->get_type_code() == LOAD_EVENT)
dump_remote_file(net, ((Load_log_event*)ev)->fname);
delete ev;
}
@@ -363,12 +513,43 @@ static void dump_remote_log_entries(const char* logname)
}
}
+
+static int check_header(IO_CACHE* file)
+{
+ byte header[BIN_LOG_HEADER_SIZE];
+ byte buf[PROBE_HEADER_LEN];
+ int old_format=0;
+
+ my_off_t pos = my_b_tell(file);
+ my_b_seek(file, (my_off_t)0);
+ if (my_b_read(file, header, sizeof(header)))
+ die("Failed reading header; Probably an empty file");
+ if (memcmp(header, BINLOG_MAGIC, sizeof(header)))
+ die("File is not a binary log file");
+ if (!my_b_read(file, buf, sizeof(buf)))
+ {
+ if (buf[4] == START_EVENT)
+ {
+ uint event_len;
+ event_len = uint4korr(buf + EVENT_LEN_OFFSET);
+ old_format = (event_len < (LOG_EVENT_HEADER_LEN + START_HEADER_LEN));
+ }
+ }
+ my_b_seek(file, pos);
+ return old_format;
+}
+
+
static void dump_local_log_entries(const char* logname)
{
File fd = -1;
IO_CACHE cache,*file= &cache;
ulonglong rec_count = 0;
- char last_db[FN_REFLEN+1] = "";
+ char last_db[FN_REFLEN+1];
+ byte tmp_buff[BIN_LOG_HEADER_SIZE];
+ bool old_format = 0;
+
+ last_db[0]=0;
if (logname && logname[0] != '-')
{
@@ -377,12 +558,14 @@ static void dump_local_log_entries(const char* logname)
if (init_io_cache(file, fd, 0, READ_CACHE, (my_off_t) position, 0,
MYF(MY_WME | MY_NABP)))
exit(1);
+ old_format = check_header(file);
}
else
{
if (init_io_cache(file, fileno(result_file), 0, READ_CACHE, (my_off_t) 0,
0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
exit(1);
+ old_format = check_header(file);
if (position)
{
/* skip 'position' characters from stdout */
@@ -391,7 +574,7 @@ static void dump_local_log_entries(const char* logname)
for (length= (my_off_t) position ; length > 0 ; length-=tmp)
{
tmp=min(length,sizeof(buff));
- if (my_b_read(file,buff, (uint) tmp))
+ if (my_b_read(file, buff, (uint) tmp))
exit(1);
}
}
@@ -400,20 +583,13 @@ static void dump_local_log_entries(const char* logname)
}
if (!position)
- {
- char magic[4];
- if (my_b_read(file, (byte*) magic, sizeof(magic)))
- die("I/O error reading binlog magic number");
- if(memcmp(magic, BINLOG_MAGIC, 4))
- die("Bad magic number; The file is probably not a MySQL binary log");
- }
-
+ my_b_read(file, tmp_buff, BIN_LOG_HEADER_SIZE); // Skip header
for (;;)
{
char llbuff[21];
my_off_t old_off = my_b_tell(file);
- Log_event* ev = Log_event::read_log_event(file);
+ Log_event* ev = Log_event::read_log_event(file, old_format);
if (!ev)
{
if (file->error)
@@ -427,57 +603,204 @@ Could not read entry at offset %s : Error in log format or read error",
{
if (!short_form)
fprintf(result_file, "# at %s\n",llstr(old_off,llbuff));
-
- ev->print(result_file, short_form, last_db);
+
+ switch (ev->get_type_code()) {
+ case QUERY_EVENT:
+ if (one_database)
+ {
+ const char * log_dbname = ((Query_log_event*)ev)->db;
+ if ((log_dbname != NULL) && (strcmp(log_dbname, database)))
+ {
+ rec_count++;
+ delete ev;
+ continue; // next
+ }
+ }
+ ev->print(result_file, short_form, last_db);
+ break;
+ case CREATE_FILE_EVENT:
+ {
+ Create_file_log_event* ce= (Create_file_log_event*)ev;
+ if (one_database)
+ {
+ /*
+ We test if this event has to be ignored. If yes, we don't save this
+ event; this will have the good side-effect of ignoring all related
+ Append_block and Exec_load.
+ Note that Load event from 3.23 is not tested.
+ */
+ const char * log_dbname = ce->db;
+ if ((log_dbname != NULL) && (strcmp(log_dbname, database)))
+ {
+ rec_count++;
+ delete ev;
+ continue; // next
+ }
+ }
+ /*
+ We print the event, but with a leading '#': this is just to inform
+ the user of the original command; the command we want to execute
+ will be a derivation of this original command (we will change the
+ filename and use LOCAL), prepared in the 'case EXEC_LOAD_EVENT'
+ below.
+ */
+ ce->print(result_file, short_form, last_db, true);
+ load_processor.process(ce);
+ ev= 0;
+ break;
+ }
+ case APPEND_BLOCK_EVENT:
+ ev->print(result_file, short_form, last_db);
+ load_processor.process((Append_block_log_event*)ev);
+ break;
+ case EXEC_LOAD_EVENT:
+ {
+ ev->print(result_file, short_form, last_db);
+ Execute_load_log_event *exv= (Execute_load_log_event*)ev;
+ Create_file_log_event *ce= load_processor.grab_event(exv->file_id);
+ /*
+ if ce is 0, it probably means that we have not seen the Create_file
+ event (a bad binlog, or most probably --position is after the
+ Create_file event). Print a warning comment.
+ */
+ if (ce)
+ {
+ ce->print(result_file, short_form, last_db,true);
+ my_free((char*)ce->fname,MYF(MY_WME));
+ delete ce;
+ }
+ else
+ fprintf(stderr,"Warning: ignoring Exec_load as there is no \
+Create_file event for file_id: %u\n",exv->file_id);
+ break;
+ }
+ default:
+ ev->print(result_file, short_form, last_db);
+ }
}
rec_count++;
- delete ev;
+ if (ev)
+ delete ev;
}
- if(fd >= 0)
- my_close(fd, MYF(MY_WME));
+ if (fd >= 0)
+ my_close(fd, MYF(MY_WME));
end_io_cache(file);
}
+#if MYSQL_VERSION_ID < 40101
+
+typedef struct st_my_tmpdir
+{
+ char **list;
+ uint cur, max;
+} MY_TMPDIR;
+
+#if defined( __WIN__) || defined(OS2)
+#define DELIM ';'
+#else
+#define DELIM ':'
+#endif
+
+my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist)
+{
+ char *end, *copy;
+ char buff[FN_REFLEN];
+ DYNAMIC_ARRAY t_arr;
+ if (my_init_dynamic_array(&t_arr, sizeof(char*), 1, 5))
+ return TRUE;
+ if (!pathlist || !pathlist[0])
+ {
+ /* Get default temporary directory */
+ pathlist=getenv("TMPDIR"); /* Use this if possible */
+#if defined( __WIN__) || defined(OS2)
+ if (!pathlist)
+ pathlist=getenv("TEMP");
+ if (!pathlist)
+ pathlist=getenv("TMP");
+#endif
+ if (!pathlist || !pathlist[0])
+ pathlist=(char*) P_tmpdir;
+ }
+ do
+ {
+ end=strcend(pathlist, DELIM);
+ convert_dirname(buff, pathlist, end);
+ if (!(copy=my_strdup(buff, MYF(MY_WME))))
+ return TRUE;
+ if (insert_dynamic(&t_arr, (gptr)&copy))
+ return TRUE;
+ pathlist=end+1;
+ }
+ while (*end);
+ freeze_size(&t_arr);
+ tmpdir->list=(char **)t_arr.buffer;
+ tmpdir->max=t_arr.elements-1;
+ tmpdir->cur=0;
+ return FALSE;
+}
+
+char *my_tmpdir(MY_TMPDIR *tmpdir)
+{
+ char *dir;
+ dir=tmpdir->list[tmpdir->cur];
+ tmpdir->cur= (tmpdir->cur == tmpdir->max) ? 0 : tmpdir->cur+1;
+ return dir;
+}
+
+void free_tmpdir(MY_TMPDIR *tmpdir)
+{
+ uint i;
+ for (i=0; i<=tmpdir->max; i++)
+ my_free(tmpdir->list[i], MYF(0));
+ my_free((gptr)tmpdir->list, MYF(0));
+}
+
+#endif
int main(int argc, char** argv)
{
+ static char **defaults_argv;
MY_INIT(argv[0]);
+
parse_args(&argc, (char***)&argv);
+ defaults_argv=argv;
- if(!argc && !table)
+ if (!argc)
{
usage();
+ free_defaults(defaults_argv);
return -1;
}
- if(use_remote)
- {
+ if (remote_opt)
mysql = safe_connect();
- }
- if (table)
+ MY_TMPDIR tmpdir;
+ tmpdir.list= 0;
+ if (!dirname_for_local_load)
{
- if(!use_remote)
- die("You must specify connection parameter to get table dump");
- char* db = (char*)table;
- char* tbl = (char*) strchr(table, '.');
- if(!tbl)
- die("You must use database.table syntax to specify the table");
- *tbl++ = 0;
- dump_remote_table(&mysql->net, db, tbl);
+ if (init_tmpdir(&tmpdir, 0))
+ exit(1);
+ dirname_for_local_load= my_tmpdir(&tmpdir);
}
+
+ if (dirname_for_local_load)
+ load_processor.init_by_dir_name(dirname_for_local_load);
else
- {
- while(--argc >= 0)
- {
- dump_log_entries(*(argv++));
- }
- }
+ load_processor.init_by_cur_dir();
+
+ while (--argc >= 0)
+ dump_log_entries(*(argv++));
+
+ if (tmpdir.list)
+ free_tmpdir(&tmpdir);
if (result_file != stdout)
my_fclose(result_file, MYF(0));
- if (use_remote)
+ if (remote_opt)
mysql_close(mysql);
cleanup();
+ free_defaults(defaults_argv);
+ my_end(0);
return 0;
}
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index f06e06c8a83..3261ec1577d 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,13 +16,13 @@
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */
-#define CHECK_VERSION "1.02"
+#define CHECK_VERSION "2.4.3"
#include "client_priv.h"
#include <m_ctype.h>
-#include "mysql_version.h"
-#include "mysqld_error.h"
-#include "sslopt-vars.h"
+#include <mysql_version.h>
+#include <mysqld_error.h>
+#include <sslopt-vars.h>
/* Exit codes */
@@ -33,7 +33,8 @@ static MYSQL mysql_connection, *sock = 0;
static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
opt_compress = 0, opt_databases = 0, opt_fast = 0,
opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
- opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0;
+ opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0,
+ tty_password = 0, opt_frm = 0;
static uint verbose = 0, opt_mysql_port=0;
static my_string opt_mysql_unix_port = 0;
static char *opt_password = 0, *current_user = 0, *default_charset = 0,
@@ -43,43 +44,99 @@ DYNAMIC_ARRAY tables4repair;
enum operations {DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE};
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"all-databases", no_argument, 0, 'A'},
- {"all-in-1", no_argument, 0, '1'},
- {"auto-repair", no_argument, 0, OPT_AUTO_REPAIR},
- {"analyze", no_argument, 0, 'a'},
- {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR},
- {"check", no_argument, 0, 'c'},
- {"check-only-changed", no_argument, 0, 'C'},
- {"compress", no_argument, 0, OPT_COMPRESS},
- {"databases", no_argument, 0, 'B'},
- {"debug", optional_argument, 0, '#'},
- {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
- {"fast", no_argument, 0, 'F'},
- {"force", no_argument, 0, 'f'},
- {"extended", no_argument, 0, 'e'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"medium-check", no_argument, 0, 'm'},
- {"optimize", no_argument, 0, 'o'},
- {"password", optional_argument, 0, 'p'},
+ {"all-databases", 'A',
+ "Check all the databases. This will be same as --databases with all databases selected.",
+ (gptr*) &opt_alldbs, (gptr*) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"analyze", 'a', "Analyze given tables.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"all-in-1", '1',
+ "Instead of issuing one query for each table, use one query per database, naming all tables in the database in a comma-separated list.",
+ (gptr*) &opt_all_in_1, (gptr*) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"auto-repair", OPT_AUTO_REPAIR,
+ "If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.",
+ (gptr*) &opt_auto_repair, (gptr*) &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"check", 'c', "Check table for errors", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"check-only-changed", 'C',
+ "Check only tables that have changed since last check or haven't been closed properly.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"compress", OPT_COMPRESS, "Use compression in server/client protocol.",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"databases", 'B',
+ "To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames.",
+ (gptr*) &opt_databases, (gptr*) &opt_databases, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"default-character-set", OPT_DEFAULT_CHARSET,
+ "Set the default character set", (gptr*) &default_charset,
+ (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"fast",'F', "Check only tables that haven't been closed properly",
+ (gptr*) &opt_fast, (gptr*) &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"force", 'f', "Continue even if we get an sql-error.",
+ (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"extended", 'e',
+ "If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will force using old slow repair with keycache method, instead of much faster repair by sorting.",
+ (gptr*) &opt_extended, (gptr*) &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host",'h', "Connect to host.", (gptr*) &current_host,
+ (gptr*) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"medium-check", 'm',
+ "Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's solicited on the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"port", required_argument, 0, 'P'},
- {"quick", no_argument, 0, 'q'},
- {"repair", no_argument, 0, 'r'},
- {"silent", no_argument, 0, 's'},
- {"socket", required_argument, 0, 'S'},
-#include "sslopt-longopts.h"
- {"tables", no_argument, 0, OPT_TABLES},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
+ {"quick", 'q',
+ "If you are using this option with CHECK TABLE, it prevents the check from scanning the rows to check for wrong links. This is the fastest check. If you are using this option with REPAIR TABLE, it will try to repair only the index tree. This is the fastest repair method for a table.",
+ (gptr*) &opt_quick, (gptr*) &opt_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"repair", 'r',
+ "Can fix almost anything except unique keys that aren't unique.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Print only error messages.", (gptr*) &opt_silent,
+ (gptr*) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#include <sslopt-longopts.h>
+ {"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.", (gptr*) &current_user,
+ (gptr*) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"use-frm", OPT_FRM,
+ "When used with REPAIR, get table structure from .frm file, so the table can be repaired even if .MYI header is corrupted.",
+ (gptr*) &opt_frm, (gptr*) &opt_frm, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"verbose", 'v', "Print info about the various stages.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static const char *load_default_groups[] = { "mysqlcheck", "client", 0 };
@@ -99,6 +156,7 @@ static void dbDisconnect(char *host);
static void DBerror(MYSQL *mysql, const char *when);
static void safe_exit(int error);
static void print_result();
+static char *fix_table_name(char *dest, char *src);
int what_to_do = 0;
static void print_version(void)
@@ -116,7 +174,7 @@ static void usage(void)
puts("and you are welcome to modify and redistribute it under the GPL license.\n");
puts("This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)");
puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be");
- puts("used same time. It works on MyISAM and in some cases on BDB tables.");
+ puts("used at the same time. It works on MyISAM and in some cases on BDB tables.");
puts("Please consult the MySQL manual for latest information about the");
puts("above. The options -c,-r,-a and -o are exclusive to each other, which");
puts("means that the last option will be used, if several was specified.\n");
@@ -130,78 +188,78 @@ static void usage(void)
printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
my_progname);
printf("OR %s [OPTIONS] --all-databases\n", my_progname);
- printf("\
- -A, --all-databases Check all the databases. This will be same as\n\
- --databases with all databases selected\n\
- -1, --all-in-1 Instead of making one query for each table, execute\n\
- all queries in 1 query separately for each database.\n\
- Table names will be in a comma separeted list.\n\
- -a, --analyze Analyze given tables.\n\
- --auto-repair If a checked table is corrupted, automatically fix\n\
- it. Repairing will be done after all tables have\n\
- been checked, if corrupted ones were found.\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename'\n\
- --character-sets-dir=...\n\
- Directory where character sets are\n\
- -c, --check Check table for errors\n\
- -C, --check-only-changed\n\
- Check only tables that have changed since last check\n\
- or haven't been closed properly.\n\
- --compress Use compression in server/client protocol.\n\
- -?, --help Display this help message and exit.\n\
- -B, --databases To check several databases. Note the difference in\n\
- usage; In this case no tables are given. All name\n\
- arguments are regarded as databasenames.\n\
- --default-character-set=...\n\
- Set the default character set\n\
- -F, --fast Check only tables that hasn't been closed properly\n\
- -f, --force Continue even if we get an sql-error.\n\
- -e, --extended If you are using this option with CHECK TABLE,\n\
- it will ensure that the table is 100 percent\n\
- consistent, but will take a long time.\n\n");
-printf("\
- If you are using this option with REPAIR TABLE,\n\
- it will run an extended repair on the table, which\n\
- may not only take a long time to execute, but\n\
- may produce a lot of garbage rows also!\n\
- -h, --host=... Connect to host.\n\
- -m, --medium-check Faster than extended-check, but only finds 99.99 percent\n\
- of all errors. Should be good enough for most cases.\n\
- -o, --optimize Optimize table\n\
- -p, --password[=...] Password to use when connecting to server.\n\
- If password is not given it's solicited on the tty.\n");
-#ifdef __WIN__
- puts("-W, --pipe Use named pipes to connect to server");
-#endif
- printf("\
- -P, --port=... Port number to use for connection.\n\
- -q, --quick If you are using this option with CHECK TABLE, it\n\
- prevents the check from scanning the rows to check\n\
- for wrong links. This is the fastest check.\n\n\
- If you are using this option with REPAIR TABLE, it\n\
- will try to repair only the index tree. This is\n\
- the fastest repair method for a table.\n\
- -r, --repair Can fix almost anything except unique keys that aren't\n\
- unique.\n\
- -s, --silent Print only error messages.\n\
- -S, --socket=... Socket file to use for connection.\n\
- --tables Overrides option --databases (-B).\n");
-#include "sslopt-usage.h"
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# User for login if not current user.\n");
-#endif
- printf("\
- -v, --verbose Print info about the various stages.\n\
- -V, --version Output version information and exit.\n");
print_defaults("my", load_default_groups);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
} /* usage */
-
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case 'a':
+ what_to_do = DO_ANALYZE;
+ break;
+ case 'c':
+ what_to_do = DO_CHECK;
+ break;
+ case 'C':
+ what_to_do = DO_CHECK;
+ opt_check_only_changed = 1;
+ break;
+ case 'I': /* Fall through */
+ case '?':
+ usage();
+ exit(0);
+ case 'm':
+ what_to_do = DO_CHECK;
+ opt_medium_check = 1;
+ break;
+ case 'o':
+ what_to_do = DO_OPTIMIZE;
+ break;
+ case 'p':
+ if (argument)
+ {
+ char *start = argument;
+ my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ opt_password = my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1] = 0; /* Cut length of argument */
+ }
+ else
+ tty_password = 1;
+ break;
+ case 'r':
+ what_to_do = DO_REPAIR;
+ break;
+ case 'W':
+#ifdef __WIN__
+ opt_mysql_unix_port = MYSQL_NAMEDPIPE;
+#endif
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+#include <sslopt-case.h>
+ case OPT_TABLES:
+ opt_databases = 0;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'V': print_version(); exit(0);
+ }
+ return 0;
+}
+
+
static int get_options(int *argc, char ***argv)
{
- int c, option_index;
- my_bool tty_password = 0;
+ int ho_error;
if (*argc == 1)
{
@@ -210,119 +268,10 @@ static int get_options(int *argc, char ***argv)
}
load_defaults("my", load_default_groups, argc, argv);
- while ((c = getopt_long(*argc, *argv, "#::p::h:u:P:S:BaAcCdeFfmqorsvVw:?I1",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'a':
- what_to_do = DO_ANALYZE;
- break;
- case '1':
- opt_all_in_1 = 1;
- break;
- case 'A':
- opt_alldbs = 1;
- break;
- case OPT_AUTO_REPAIR:
- opt_auto_repair = 1;
- break;
- case OPT_DEFAULT_CHARSET:
- default_charset = optarg;
- break;
- case OPT_CHARSETS_DIR:
- charsets_dir = optarg;
- break;
- case 'c':
- what_to_do = DO_CHECK;
- break;
- case 'C':
- what_to_do = DO_CHECK;
- opt_check_only_changed = 1;
- break;
- case 'e':
- opt_extended = 1;
- break;
- case OPT_COMPRESS:
- opt_compress = 1;
- break;
- case 'B':
- opt_databases = 1;
- break;
- case 'F':
- opt_fast = 1;
- break;
- case 'f':
- ignore_errors = 1;
- break;
- case 'I': /* Fall through */
- case '?':
- usage();
- exit(0);
- case 'h':
- my_free(current_host, MYF(MY_ALLOW_ZERO_PTR));
- current_host = my_strdup(optarg, MYF(MY_WME));
- break;
- case 'm':
- what_to_do = DO_CHECK;
- opt_medium_check = 1;
- break;
- case 'o':
- what_to_do = DO_OPTIMIZE;
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- current_user = optarg;
- break;
-#endif
- case 'p':
- if (optarg)
- {
- char *start = optarg;
- my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
- opt_password = my_strdup(optarg, MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1] = 0; /* Cut length of argument */
- }
- else
- tty_password = 1;
- break;
- case 'P':
- opt_mysql_port = (unsigned int) atoi(optarg);
- break;
- case 'q':
- opt_quick = 1;
- break;
- case 'r':
- what_to_do = DO_REPAIR;
- break;
- case 'S':
- opt_mysql_unix_port = optarg;
- break;
- case 's':
- opt_silent = 1;
- break;
- case 'W':
-#ifdef __WIN__
- opt_mysql_unix_port = MYSQL_NAMEDPIPE;
-#endif
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case OPT_TABLES:
- opt_databases = 0;
- break;
- case 'v':
- verbose++;
- break;
- case 'V': print_version(); exit(0);
- default:
- fprintf(stderr, "%s: Illegal option character '%c'\n", my_progname,
- opterr);
-#include "sslopt-case.h"
- }
- }
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (!what_to_do)
{
int pnlen = strlen(my_progname);
@@ -343,8 +292,6 @@ static int get_options(int *argc, char ***argv)
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
exit(1);
}
- (*argc) -= optind;
- (*argv) += optind;
if (*argc > 0 && opt_alldbs)
{
printf("You should give only options, no arguments at all, with option\n");
@@ -416,7 +363,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
for (i = 0; i < tables; i++)
tot_length += strlen(*(table_names + i)) + 4;
-
+
if (!(table_names_comma_sep = (char *)
my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
return 1;
@@ -424,7 +371,8 @@ static int process_selected_tables(char *db, char **table_names, int tables)
for (end = table_names_comma_sep + 1; tables > 0;
tables--, table_names++)
{
- end = strxmov(end, " `", *table_names, "`,", NullS);
+ end= fix_table_name(end, *table_names);
+ *end++= ',';
}
*--end = 0;
handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1);
@@ -437,6 +385,22 @@ static int process_selected_tables(char *db, char **table_names, int tables)
} /* process_selected_tables */
+static char *fix_table_name(char *dest, char *src)
+{
+ char *db_sep;
+
+ *dest++= '`';
+ if ((db_sep= strchr(src, '.')))
+ {
+ dest= strmake(dest, src, (uint) (db_sep - src));
+ dest= strmov(dest, "`.`");
+ src= db_sep + 1;
+ }
+ dest= strxmov(dest, src, "`", NullS);
+ return dest;
+}
+
+
static int process_all_tables_in_db(char *database)
{
MYSQL_RES *res;
@@ -448,7 +412,7 @@ static int process_all_tables_in_db(char *database)
if (!(mysql_query(sock, "SHOW TABLES") ||
(res = mysql_store_result(sock))))
return 1;
-
+
if (opt_all_in_1)
{
/*
@@ -463,7 +427,7 @@ static int process_all_tables_in_db(char *database)
while ((row = mysql_fetch_row(res)))
tot_length += strlen(row[0]) + 4;
mysql_data_seek(res, 0);
-
+
if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+4, MYF(MY_WME))))
{
mysql_free_result(res);
@@ -471,7 +435,8 @@ static int process_all_tables_in_db(char *database)
}
for (end = tables + 1; (row = mysql_fetch_row(res)) ;)
{
- end = strxmov(end, " `", row[0], "`,", NullS);
+ end= fix_table_name(end, row[0]);
+ *end++= ',';
}
*--end = 0;
if (tot_length)
@@ -502,6 +467,7 @@ static int use_db(char *database)
static int handle_request_for_tables(char *tables, uint length)
{
char *query, *end, options[100], message[100];
+ uint query_length= 0;
const char *op = 0;
options[0] = 0;
@@ -519,6 +485,7 @@ static int handle_request_for_tables(char *tables, uint length)
op = "REPAIR";
if (opt_quick) end = strmov(end, " QUICK");
if (opt_extended) end = strmov(end, " EXTENDED");
+ if (opt_frm) end = strmov(end, " USE_FRM");
break;
case DO_ANALYZE:
op = "ANALYZE";
@@ -531,11 +498,21 @@ static int handle_request_for_tables(char *tables, uint length)
if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))
return 1;
if (opt_all_in_1)
+ {
/* No backticks here as we added them before */
- sprintf(query, "%s TABLE %s %s", op, tables, options);
+ query_length= my_sprintf(query,
+ (query, "%s TABLE %s %s", op, tables, options));
+ }
else
- sprintf(query, "%s TABLE `%s` %s", op, tables, options);
- if (mysql_query(sock, query))
+ {
+ char *ptr;
+
+ ptr= strmov(strmov(query, op), " TABLE ");
+ ptr= fix_table_name(ptr, tables);
+ ptr= strxmov(ptr, " ", options, NullS);
+ query_length= (uint) (ptr - query);
+ }
+ if (mysql_real_query(sock, query, query_length))
{
sprintf(message, "when executing '%s TABLE ... %s'", op, options);
DBerror(sock, message);
@@ -564,12 +541,9 @@ static void print_result()
if (status)
{
- if (found_error)
- {
- if (what_to_do != DO_REPAIR && opt_auto_repair &&
- (!opt_fast || strcmp(row[3],"OK")))
- insert_dynamic(&tables4repair, row[0]);
- }
+ if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
+ (!opt_fast || strcmp(row[3],"OK")))
+ insert_dynamic(&tables4repair, prev);
found_error=0;
if (opt_silent)
continue;
@@ -586,6 +560,9 @@ static void print_result()
strmov(prev, row[0]);
putchar('\n');
}
+ if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
+ (!opt_fast || strcmp(row[3],"OK")))
+ insert_dynamic(&tables4repair, prev);
mysql_free_result(res);
}
@@ -603,7 +580,7 @@ static int dbConnect(char *host, char *user, char *passwd)
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
- opt_ssl_capath);
+ opt_ssl_capath, opt_ssl_cipher);
#endif
if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
@@ -659,7 +636,7 @@ int main(int argc, char **argv)
if (dbConnect(current_host, current_user, opt_password))
exit(EX_MYSQLERR);
- if (opt_auto_repair &&
+ if (opt_auto_repair &&
my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64))
{
first_error = 1;
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 93b75a70320..34f9b7998d7 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -33,9 +33,10 @@
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up
** and adapted to mysqldump 05/11/01 by Jani Tolonen
+** Added --single-transaction option 06/06/2002 by Peter Zaitsev
*/
-#define DUMP_VERSION "8.23"
+#define DUMP_VERSION "9.10"
#include <my_global.h>
#include <my_sys.h>
@@ -46,7 +47,6 @@
#include "mysql.h"
#include "mysql_version.h"
#include "mysqld_error.h"
-#include <getopt.h>
/* Exit codes */
@@ -64,6 +64,9 @@
#define SHOW_EXTRA 5
#define QUOTE_CHAR '`'
+/* Size of buffer for dump's select query */
+#define QUERY_LENGTH 1536
+
static char *add_load_option(char *ptr, const char *object,
const char *statement);
@@ -74,7 +77,8 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0,
opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0,
opt_alldbs=0,opt_create_db=0,opt_first_slave=0,
opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0,
- opt_delete_master_logs=0;
+ opt_delete_master_logs=0, tty_password=0,
+ opt_single_transaction=0, opt_comments= 0;
static MYSQL mysql_connection,*sock=0;
static char insert_pat[12 * 1024],*opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0,
@@ -85,76 +89,170 @@ static my_string opt_mysql_unix_port=0;
static int first_error=0;
extern ulong net_buffer_length;
static DYNAMIC_STRING extended_row;
-#include "sslopt-vars.h"
+#include <sslopt-vars.h>
FILE *md_result_file;
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"all-databases", no_argument, 0, 'A'},
- {"all", no_argument, 0, 'a'},
- {"add-drop-table", no_argument, 0, OPT_DROP},
- {"add-locks", no_argument, 0, OPT_LOCKS},
- {"allow-keywords", no_argument, 0, OPT_KEYWORDS},
- {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
- {"complete-insert", no_argument, 0, 'c'},
- {"compress", no_argument, 0, 'C'},
- {"databases", no_argument, 0, 'B'},
- {"debug", optional_argument, 0, '#'},
- {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
- {"delayed-insert", no_argument, 0, OPT_DELAYED},
- {"delete-master-logs", no_argument, 0, OPT_DELETE_MASTER_LOGS},
- {"disable-keys", no_argument, 0, 'K'},
- {"extended-insert", no_argument, 0, 'e'},
- {"fields-terminated-by", required_argument, 0, (int) OPT_FTB},
- {"fields-enclosed-by", required_argument, 0, (int) OPT_ENC},
- {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC},
- {"fields-escaped-by", required_argument, 0, (int) OPT_ESC},
- {"first-slave", no_argument, 0, 'x'},
- {"flush-logs", no_argument, 0, 'F'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"lines-terminated-by", required_argument, 0, (int) OPT_LTB},
- {"lock-tables", no_argument, 0, 'l'},
- {"master-data", no_argument, 0, OPT_MASTER_DATA},
- {"no-autocommit", no_argument, 0, OPT_AUTOCOMMIT},
- {"no-create-db", no_argument, 0, 'n'},
- {"no-create-info", no_argument, 0, 't'},
- {"no-data", no_argument, 0, 'd'},
- {"opt", no_argument, 0, OPT_OPTIMIZE},
- {"password", optional_argument, 0, 'p'},
+ {"all-databases", 'A',
+ "Dump all the databases. This will be same as --databases with all databases selected.",
+ (gptr*) &opt_alldbs, (gptr*) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"all", 'a', "Include all MySQL specific create options.",
+ (gptr*) &create_options, (gptr*) &create_options, 0, GET_BOOL, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
+ (gptr*) &opt_drop, (gptr*) &opt_drop, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"add-locks", OPT_LOCKS, "Add locks around insert statements.",
+ (gptr*) &opt_lock, (gptr*) &opt_lock, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"allow-keywords", OPT_KEYWORDS,
+ "Allow creation of column names that are keywords.", (gptr*) &opt_keywords,
+ (gptr*) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"complete-insert", 'c', "Use complete insert statements.", (gptr*) &cFlag,
+ (gptr*) &cFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol.",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"databases", 'B',
+ "To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output.",
+ (gptr*) &opt_databases, (gptr*) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"default-character-set", OPT_DEFAULT_CHARSET,
+ "Set the default character set.", (gptr*) &default_charset,
+ (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED.",
+ (gptr*) &opt_delayed, (gptr*) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"delete-master-logs", OPT_DELETE_MASTER_LOGS,
+ "Delete logs on master after backup. This will automagically enable --first-slave.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"disable-keys", 'K',
+ "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys,
+ (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"extended-insert", 'e',
+ "Allows utilization of the new, much faster INSERT syntax.",
+ (gptr*) &extended_insert, (gptr*) &extended_insert, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"fields-terminated-by", OPT_FTB,
+ "Fields in the textfile are terminated by ...", (gptr*) &fields_terminated,
+ (gptr*) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"fields-enclosed-by", OPT_ENC,
+ "Fields in the importfile are enclosed by ...", (gptr*) &enclosed,
+ (gptr*) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
+ {"fields-optionally-enclosed-by", OPT_O_ENC,
+ "Fields in the i.file are opt. enclosed by ...", (gptr*) &opt_enclosed,
+ (gptr*) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
+ {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
+ (gptr*) &escaped, (gptr*) &escaped, 0, GET_STR, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"first-slave", 'x', "Locks all tables across all databases.",
+ (gptr*) &opt_first_slave, (gptr*) &opt_first_slave, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"flush-logs", 'F', "Flush logs file in server before starting dump. "
+ "Note that if you dump many databases at once (using the option "
+ "--databases= or --all-databases), the logs will be flushed for "
+ "each database dumped.",
+ (gptr*) &flush_logs, (gptr*) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"force", 'f', "Continue even if we get an sql-error.",
+ (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &current_host,
+ (gptr*) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
+ (gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"lock-tables", 'l', "Lock all tables for read.", (gptr*) &lock_tables,
+ (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"master-data", OPT_MASTER_DATA,
+ "This will cause the master position and filename to be appended to your output. This will automagically enable --first-slave.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"no-autocommit", OPT_AUTOCOMMIT,
+ "Wrap tables with autocommit/commit statements.",
+ (gptr*) &opt_autocommit, (gptr*) &opt_autocommit, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"single-transaction", OPT_TRANSACTION,
+ "Dump all tables in single transaction to get consistent snapshot. Mutually exclusive with --lock-tables.",
+ (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"no-create-db", 'n',
+ "'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}",
+ (gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"no-create-info", 't', "Don't write table creation info.",
+ (gptr*) &tFlag, (gptr*) &tFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"no-data", 'd', "No row information.", (gptr*) &dFlag, (gptr*) &dFlag, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"opt", OPT_OPTIMIZE,
+ "Same as --add-drop-table --add-locks --all --quick --extended-insert --lock-tables --disable-keys",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's solicited on the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"port", required_argument, 0, 'P'},
- {"quick", no_argument, 0, 'q'},
- {"quote-names", no_argument, 0, 'Q'},
- {"result-file", required_argument, 0, 'r'},
- {"set-variable", required_argument, 0, 'O'},
- {"socket", required_argument, 0, 'S'},
-#include "sslopt-longopts.h"
- {"tab", required_argument, 0, 'T'},
- {"tables", no_argument, 0, OPT_TABLES},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
+ {"quick", 'q', "Don't buffer query, dump directly to stdout.",
+ (gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"quote-names",'Q', "Quote table and column names with a `",
+ (gptr*) &opt_quoted, (gptr*) &opt_quoted, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"result-file", 'r',
+ "Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#include <sslopt-longopts.h>
+ {"tab",'T',
+ "Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.",
+ (gptr*) &path, (gptr*) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"tables", OPT_TABLES, "Overrides option --databases (-B).",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.",
+ (gptr*) &current_user, (gptr*) &current_user, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
#endif
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"where", required_argument, 0, 'w'},
- {"xml", no_argument, 0, 'X'},
- {0, 0, 0, 0}
+ {"verbose", 'v', "Print info about the various stages.",
+ (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version",'V', "Output version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"where", 'w', "Dump only selected records; QUOTES mandatory!",
+ (gptr*) &where, (gptr*) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
+ (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0,
+ GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096,
+ (longlong) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
+ {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
+ (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0,
+ GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L,
+ MALLOC_OVERHEAD-1024, 1024, 0},
+ {"comments", 'i', "Write additional information.",
+ (gptr*) &opt_comments, (gptr*) &opt_comments, 0, GET_BOOL, NO_ARG,
+ 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static const char *load_default_groups[]= { "mysqldump","client",0 };
-CHANGEABLE_VAR md_changeable_vars[] = {
- { "max_allowed_packet", (long*) &max_allowed_packet,24*1024*1024,4096,
- 16*1024L*1024L,MALLOC_OVERHEAD,1024},
- { "net_buffer_length", (long*) &net_buffer_length,1024*1024L-1025,4096,
- 16*1024L*1024L,MALLOC_OVERHEAD+1024,1024},
- { 0, 0, 0, 0, 0, 0, 0}
-};
-
static void safe_exit(int error);
static void write_header(FILE *sql_file, char *db_name);
static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
@@ -167,6 +265,8 @@ static int dump_databases(char **);
static int dump_all_databases();
static char *quote_name(const char *name, char *buff, my_bool force);
static void print_quoted_xml(FILE *output, char *fname, char *str, uint len);
+static const char *check_if_ignore_table(const char *table_name);
+
static void print_version(void)
{
@@ -175,128 +275,47 @@ static void print_version(void)
} /* print_version */
+static void short_usage_sub(void)
+{
+ printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
+ printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
+ my_progname);
+ printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
+}
+
static void usage(void)
{
- uint i;
print_version();
puts("By Igor Romanenko, Monty, Jani & Sinisa");
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Dumping definition and data mysql database or table");
- printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
- printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
- my_progname);
- printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
- printf("\n\
- -A, --all-databases Dump all the databases. This will be same as\n\
- --databases with all databases selected.\n\
- -a, --all Include all MySQL specific create options.\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename`.\n\
- --character-sets-dir=...\n\
- Directory where character sets are\n\
- -?, --help Display this help message and exit.\n\
- -B, --databases To dump several databases. Note the difference in\n\
- usage; In this case no tables are given. All name\n\
- arguments are regarded as databasenames.\n\
- 'USE db_name;' will be included in the output\n\
- -c, --complete-insert Use complete insert statements.\n\
- -C, --compress Use compression in server/client protocol.\n\
- --default-character-set=...\n\
- Set the default character set\n\
- -e, --extended-insert Allows utilization of the new, much faster\n\
- INSERT syntax.\n\
- --add-drop-table Add a 'drop table' before each create.\n\
- --add-locks Add locks around insert statements.\n\
- --allow-keywords Allow creation of column names that are keywords.\n\
- --delayed-insert Insert rows with INSERT DELAYED.\n\
- --delete-master-logs Issue RESET MASTER on the master just after taking\n\
- the dump, and before unlocking tables.\n\
- This will automatically enable --first-slave.\n\
- --master-data This will cause the master position and filename to \n\
- be appended to your output, before unlocking tables.\n\
- This will automatically enable --first-slave.\n\
- -F, --flush-logs Flush logs file in server before starting dump.\n\
- -f, --force Continue even if we get an sql-error.\n\
- -h, --host=... Connect to host.\n");
-puts("\
- -l, --lock-tables Lock all tables for read.\n\
- --no-autocommit Wrap tables with autocommit/commit statements.\n\
- -K, --disable-keys '/*!40000 ALTER TABLE tb_name DISABLE KEYS */;\n\
- and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */;\n\
- will be put in the output.\n\
- -n, --no-create-db 'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'\n\
- will not be put in the output. The above line will\n\
- be added otherwise, if --databases or\n\
- --all-databases option was given.\n\
- -t, --no-create-info Don't write table creation info.\n\
- -d, --no-data No row information.\n\
- -O, --set-variable var=option\n\
- give a variable a value. --help lists variables\n\
- --opt Same as --add-drop-table --add-locks --all --quick\n\
- --extended-insert --lock-tables --disable-keys\n\
- -p, --password[=...] Password to use when connecting to server.\n\
- If password is not given it's solicited on the tty.\n");
-#ifdef __WIN__
- puts("-W, --pipe Use named pipes to connect to server");
-#endif
- printf("\
- -P, --port=... Port number to use for connection.\n\
- -q, --quick Don't buffer query, dump directly to stdout.\n\
- -Q, --quote-names Quote table and column names with `\n\
- -r, --result-file=... Direct output to a given file. This option should be\n\
- used in MSDOS, because it prevents new line '\\n'\n\
- from being converted to '\\n\\r' (newline + carriage\n\
- return).\n\
- -S, --socket=... Socket file to use for connection.\n\
- --tables Overrides option --databases (-B).\n");
-#include "sslopt-usage.h"
- printf("\
- -T, --tab=... Creates tab separated textfile for each table to\n\
- given path. (creates .sql and .txt files).\n\
- NOTE: This only works if mysqldump is run on\n\
- the same machine as the mysqld daemon.\n");
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# User for login if not current user.\n");
-#endif
- printf("\
- -v, --verbose Print info about the various stages.\n\
- -V, --version Output version information and exit.\n\
- -w, --where= dump only selected records; QUOTES mandatory!\n\
- -X, --xml dump a database as well formed XML\n\
- -x, --first-slave Locks all tables across all databases.\n\
- EXAMPLES: \"--where=user=\'jimf\'\" \"-wuserid>1\" \"-wuserid<1\"\n\
- Use -T (--tab=...) with --fields-...\n\
- --fields-terminated-by=...\n\
- Fields in the textfile are terminated by ...\n\
- --fields-enclosed-by=...\n\
- Fields in the importfile are enclosed by ...\n\
- --fields-optionally-enclosed-by=...\n\
- Fields in the i.file are opt. enclosed by ...\n\
- --fields-escaped-by=...\n\
- Fields in the i.file are escaped by ...\n\
- --lines-terminated-by=...\n\
- Lines in the i.file are terminated by ...\n\
-");
+ short_usage_sub();
print_defaults("my",load_default_groups);
-
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (i=0 ; md_changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- md_changeable_vars[i].name,
- (ulong) *md_changeable_vars[i].varptr);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
} /* usage */
+static void short_usage(void)
+{
+ short_usage_sub();
+ printf("For more options, use %s --help\n", my_progname);
+}
+
+
static void write_header(FILE *sql_file, char *db_name)
{
if (opt_xml)
+ {
fprintf(sql_file,"<?xml version=\"1.0\"?>\n");
- else
+ fprintf(sql_file,"<mysqldump>\n");
+ }
+ else if (opt_comments)
{
fprintf(sql_file, "-- MySQL dump %s\n--\n", DUMP_VERSION);
fprintf(sql_file, "-- Host: %s Database: %s\n",
current_host ? current_host : "localhost", db_name ? db_name : "");
- fputs("---------------------------------------------------------\n",
+ fputs("-- ------------------------------------------------------\n",
sql_file);
fprintf(sql_file, "-- Server version\t%s\n",
mysql_get_server_info(&mysql_connection));
@@ -304,186 +323,104 @@ static void write_header(FILE *sql_file, char *db_name)
return;
} /* write_header */
-
-static int get_options(int *argc,char ***argv)
+static void write_footer(FILE *sql_file)
{
- int c,option_index;
- my_bool tty_password=0;
+ if (opt_xml)
+ fprintf(sql_file,"</mysqldump>");
+ fputs("\n", sql_file);
+} /* write_footer */
- md_result_file=stdout;
- load_defaults("my",load_default_groups,argc,argv);
- set_all_changeable_vars(md_changeable_vars);
- while ((c=getopt_long(*argc,*argv,
- "#::p::h:u:O:P:r:S:T:EBaAcCdefFKlnqQtvVw:?IxX",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case OPT_MASTER_DATA:
- opt_master_data=1;
- opt_first_slave=1;
- break;
- case OPT_DELETE_MASTER_LOGS:
- opt_delete_master_logs=1;
- opt_first_slave=1;
- break;
- case OPT_AUTOCOMMIT:
- opt_autocommit=1;
- break;
- case 'a':
- create_options=1;
- break;
- case 'e':
- extended_insert=1;
- break;
- case 'A':
- opt_alldbs=1;
- break;
- case OPT_DEFAULT_CHARSET:
- default_charset= optarg;
- break;
- case OPT_CHARSETS_DIR:
- charsets_dir= optarg;
- break;
- case 'f':
- ignore_errors=1;
- break;
- case 'F':
- flush_logs=1;
- break;
- case 'h':
- my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
- current_host=my_strdup(optarg,MYF(MY_WME));
- break;
- case 'K':
- opt_disable_keys=1;
- break;
- case 'n':
- opt_create_db = 1;
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- current_user=optarg;
- break;
-#endif
- case 'O':
- if (set_changeable_var(optarg, md_changeable_vars))
- {
- usage();
- return(1);
- }
- break;
- case 'p':
- if (optarg)
- {
- char *start=optarg;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- opt_password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1]=0; /* Cut length of argument */
- }
- else
- tty_password=1;
- break;
- case 'P':
- opt_mysql_port= (unsigned int) atoi(optarg);
- break;
- case 'r':
- if (!(md_result_file = my_fopen(optarg, O_WRONLY | O_BINARY,
- MYF(MY_WME))))
- exit(1);
- break;
- case 'S':
- opt_mysql_unix_port= optarg;
- break;
- case 'W':
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case OPT_MASTER_DATA:
+ opt_master_data=1;
+ opt_first_slave=1;
+ break;
+ case OPT_DELETE_MASTER_LOGS:
+ opt_delete_master_logs=1;
+ opt_first_slave=1;
+ break;
+ case 'p':
+ if (argument)
+ {
+ char *start=argument;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(argument,MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
+ }
+ else
+ tty_password=1;
+ break;
+ case 'r':
+ if (!(md_result_file = my_fopen(argument, O_WRONLY | FILE_BINARY,
+ MYF(MY_WME))))
+ exit(1);
+ break;
+ case 'W':
#ifdef __WIN__
- opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+ opt_mysql_unix_port=MYSQL_NAMEDPIPE;
#endif
- break;
- case 'T':
- path= optarg;
- opt_disable_keys=0;
- break;
- case 'B':
- opt_databases = 1;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case 'c': cFlag=1; break;
- case 'C':
- opt_compress=1;
- break;
- case 'd': dFlag=1; break;
- case 'l': lock_tables=1; break;
- case 'q': quick=1; break;
- case 'Q': opt_quoted=1; break;
- case 't': tFlag=1; break;
- case 'v': verbose=1; break;
- case 'V': print_version(); exit(0);
- case 'w':
- where=optarg;
- break;
- case 'X':
- opt_xml = 1;
- opt_disable_keys=0;
- break;
- case 'x':
- opt_first_slave=1;
- break;
- default:
- fprintf(stderr,"%s: Illegal option character '%c'\n",my_progname,opterr);
- /* Fall throught */
- case 'I':
- case '?':
- usage();
- exit(0);
- case (int) OPT_FTB:
- fields_terminated= optarg;
- break;
- case (int) OPT_LTB:
- lines_terminated= optarg;
- break;
- case (int) OPT_ENC:
- enclosed= optarg;
- break;
- case (int) OPT_O_ENC:
- opt_enclosed= optarg;
- break;
- case (int) OPT_ESC:
- escaped= optarg;
- break;
- case (int) OPT_DROP:
- opt_drop=1;
- break;
- case (int) OPT_KEYWORDS:
- opt_keywords=1;
- break;
- case (int) OPT_LOCKS:
- opt_lock=1;
- break;
- case (int) OPT_OPTIMIZE:
- extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options=
- opt_disable_keys=1;
- break;
- case (int) OPT_DELAYED:
- opt_delayed=1;
- break;
- case (int) OPT_TABLES:
- opt_databases=0;
- break;
-#include "sslopt-case.h"
- }
+ break;
+ case 'T':
+ opt_disable_keys=0;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+#include <sslopt-case.h>
+ case 'V': print_version(); exit(0);
+ case 'X':
+ opt_xml = 1;
+ opt_disable_keys=0;
+ break;
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ case (int) OPT_OPTIMIZE:
+ extended_insert=opt_drop=opt_lock=quick=create_options=opt_disable_keys=
+ lock_tables=1;
+ if (opt_single_transaction) lock_tables=0;
+ break;
+ case (int) OPT_TABLES:
+ opt_databases=0;
+ break;
}
+ return 0;
+}
+
+
+static int get_options(int *argc, char ***argv)
+{
+ int ho_error;
+
+ md_result_file= stdout;
+ load_defaults("my",load_default_groups,argc,argv);
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (opt_delayed)
opt_lock=0; /* Can't have lock with delayed */
if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
fields_terminated))
{
- fprintf(stderr, "%s: You must use option --tab with --fields-...\n", my_progname);
+ fprintf(stderr,
+ "%s: You must use option --tab with --fields-...\n", my_progname);
return(1);
}
+
+ if (opt_single_transaction && lock_tables)
+ {
+ fprintf(stderr, "%s: You can't use --lock-tables and --single-transaction at the same time.\n", my_progname);
+ return(1);
+ }
if (enclosed && opt_enclosed)
{
@@ -507,11 +444,9 @@ static int get_options(int *argc,char ***argv)
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
exit(1);
}
- (*argc)-=optind;
- (*argv)+=optind;
if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
{
- usage();
+ short_usage();
return 1;
}
if (tty_password)
@@ -634,6 +569,23 @@ static char *quote_name(const char *name, char *buff, my_bool force)
} /* quote_name */
+
+static char *quote_for_like(const char *name, char *buff)
+{
+ char *to= buff;
+ *to++= '\'';
+ while (*name)
+ {
+ if (*name == '\'' || *name == '_' || *name == '\\' || *name == '%')
+ *to++= '\\';
+ *to++= *name++;
+ }
+ to[0]= '\'';
+ to[1]= 0;
+ return buff;
+}
+
+
/*
getStructure -- retrievs database structure, prints out corresponding
CREATE statement and fills out insert_pat.
@@ -660,7 +612,8 @@ static uint getTableStructure(char *table, char* db)
if (verbose)
fprintf(stderr, "-- Retrieving table structure for table %s...\n", table);
- sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", opt_quoted);
+ sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
+ (opt_quoted || opt_keywords));
result_table= quote_name(table, table_buff, 1);
opt_quoted_table= quote_name(table, table_buff2, 0);
if (!mysql_query(sock,insert_pat))
@@ -683,8 +636,7 @@ static uint getTableStructure(char *table, char* db)
if (path)
{
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
- strmov(tmp_path,path);
- convert_dirname(tmp_path);
+ convert_dirname(tmp_path,path,NullS);
sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
O_WRONLY, MYF(MY_WME));
if (!sql_file) /* If file couldn't be opened */
@@ -694,7 +646,7 @@ static uint getTableStructure(char *table, char* db)
}
write_header(sql_file, db);
}
- if (!opt_xml)
+ if (!opt_xml && opt_comments)
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
result_table);
if (opt_drop)
@@ -762,8 +714,7 @@ static uint getTableStructure(char *table, char* db)
if (path)
{
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
- strmov(tmp_path,path);
- convert_dirname(tmp_path);
+ convert_dirname(tmp_path,path,NullS);
sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
O_WRONLY, MYF(MY_WME));
if (!sql_file) /* If file couldn't be opened */
@@ -773,7 +724,7 @@ static uint getTableStructure(char *table, char* db)
}
write_header(sql_file, db);
}
- if (!opt_xml)
+ if (!opt_xml && opt_comments)
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
result_table);
if (opt_drop)
@@ -891,7 +842,9 @@ static uint getTableStructure(char *table, char* db)
/* Get MySQL specific create options */
if (create_options)
{
- sprintf(buff,"show table status like %s",result_table);
+ char show_name_buff[FN_REFLEN];
+ sprintf(buff,"show table status like %s",
+ quote_for_like(table, show_name_buff));
if (mysql_query(sock, buff))
{
if (mysql_errno(sock) != ER_PARSE_ERROR)
@@ -922,9 +875,6 @@ static uint getTableStructure(char *table, char* db)
fputs(";\n", sql_file);
}
}
- if (opt_disable_keys)
- fprintf(sql_file, "\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
- result_table);
if (cFlag)
{
strpos=strmov(strpos,") VALUES ");
@@ -993,28 +943,40 @@ static char *field_escape(char *to,const char *from,uint length)
*/
static void dumpTable(uint numFields, char *table)
{
- char query[1024], *end, buff[256],table_buff[NAME_LEN+3], *result_table;
- char table_buff2[NAME_LEN*2+3], *opt_quoted_table;
+ char query[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3];
+ char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
MYSQL_RES *res;
- MYSQL_FIELD *field;
- MYSQL_ROW row;
+ MYSQL_FIELD *field;
+ MYSQL_ROW row;
ulong rownr, row_break, total_length, init_length;
+ const char *table_type;
- if (verbose)
- fprintf(stderr, "-- Sending SELECT query...\n");
result_table= quote_name(table,table_buff, 1);
opt_quoted_table= quote_name(table, table_buff2, 0);
+
+ /* Check table type */
+ if ((table_type= check_if_ignore_table(table)))
+ {
+ if (verbose)
+ fprintf(stderr,
+ "-- Skipping data for table '%s' because it's of type %s\n",
+ table, table_type);
+ return;
+ }
+
+ if (verbose)
+ fprintf(stderr, "-- Sending SELECT query...\n");
if (path)
{
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
- strmov(tmp_path,path);
- convert_dirname(tmp_path);
+ convert_dirname(tmp_path,path,NullS);
my_load_path(tmp_path, tmp_path, NULL);
fn_format(filename, table, tmp_path, ".txt", 4);
my_delete(filename, MYF(0)); /* 'INTO OUTFILE' doesn't work, if
filename wasn't deleted */
to_unix_path(filename);
- sprintf(query, "SELECT * INTO OUTFILE '%s'", filename);
+ sprintf(query, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '%s'",
+ filename);
end= strend(query);
if (replace)
end= strmov(end, " REPLACE");
@@ -1042,18 +1004,19 @@ static void dumpTable(uint numFields, char *table)
}
else
{
- if (!opt_xml)
+ if (!opt_xml && opt_comments)
fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n",
result_table);
- sprintf(query, "SELECT * FROM %s", result_table);
+ sprintf(query, "SELECT /*!40001 SQL_NO_CACHE */ * FROM %s",
+ result_table);
if (where)
{
- if (!opt_xml)
+ if (!opt_xml && opt_comments)
fprintf(md_result_file,"-- WHERE: %s\n",where);
strxmov(strend(query), " WHERE ",where,NullS);
}
if (!opt_xml)
- fputs("\n\n", md_result_file);
+ fputs("\n", md_result_file);
if (mysql_query(sock, query))
{
DBerror(sock, "when retrieving data from server");
@@ -1078,6 +1041,9 @@ static void dumpTable(uint numFields, char *table)
return;
}
+ if (opt_disable_keys)
+ fprintf(md_result_file, "\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
+ opt_quoted_table);
if (opt_lock)
fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
@@ -1086,7 +1052,7 @@ static void dumpTable(uint numFields, char *table)
rownr=0;
init_length=(uint) strlen(insert_pat)+4;
if (opt_xml)
- fprintf(md_result_file, "\t<%s>\n", table);
+ fprintf(md_result_file, "\t<table name=\"%s\">\n", table);
if (opt_autocommit)
fprintf(md_result_file, "set autocommit=0;\n");
@@ -1141,10 +1107,22 @@ static void dumpTable(uint numFields, char *table)
}
else
{
- /* change any strings ("inf","nan",..) into NULL */
+ /* change any strings ("inf", "-inf", "nan") into NULL */
char *ptr = row[i];
- dynstr_append(&extended_row,
- (!isalpha(*ptr)) ? ptr : "NULL");
+ if (isalpha(*ptr) || (*ptr == '-' && isalpha(ptr[1])))
+ dynstr_append(&extended_row, "NULL");
+ else
+ {
+ if (field->type == FIELD_TYPE_DECIMAL)
+ {
+ /* add " signs around */
+ dynstr_append(&extended_row, "\"");
+ dynstr_append(&extended_row, ptr);
+ dynstr_append(&extended_row, "\"");
+ }
+ else
+ dynstr_append(&extended_row, ptr);
+ }
}
}
else
@@ -1172,20 +1150,32 @@ static void dumpTable(uint numFields, char *table)
}
else
{
- /* change any strings ("inf","nan",..) into NULL */
+ /* change any strings ("inf", "-inf", "nan") into NULL */
char *ptr = row[i];
if (opt_xml)
- fprintf(md_result_file, "\t\t<%s>%s</%s>\n",
- field->name,!isalpha(*ptr) ?ptr: "NULL",field->name);
+ fprintf(md_result_file, "\t\t<field name=\"%s\">%s</field>\n",
+ field->name,!isalpha(*ptr) ?ptr: "NULL");
+ else if (isalpha(*ptr) || (*ptr == '-' && isalpha(ptr[1])))
+ fputs("NULL", md_result_file);
else
- fputs((!isalpha(*ptr)) ? ptr : "NULL", md_result_file);
+ {
+ if (field->type == FIELD_TYPE_DECIMAL)
+ {
+ /* add " signs around */
+ fputs("\"", md_result_file);
+ fputs(ptr, md_result_file);
+ fputs("\"", md_result_file);
+ }
+ else
+ fputs(ptr, md_result_file);
+ }
}
}
else
{
if (opt_xml)
- fprintf(md_result_file, "\t\t<%s>%s</%s>\n",
- field->name, "NULL", field->name);
+ fprintf(md_result_file, "\t\t<field name=\"%s\">%s</field>\n",
+ field->name, "NULL");
else
fputs("NULL", md_result_file);
}
@@ -1224,9 +1214,9 @@ static void dumpTable(uint numFields, char *table)
fputs(");\n", md_result_file);
}
- /*XML - close table tag and supress regular output*/
+ /* XML - close table tag and supress regular output */
if (opt_xml)
- fprintf(md_result_file, "\t</%s>\n", table);
+ fprintf(md_result_file, "\t</table>\n");
else if (extended_insert && row_break)
fputs(";\n", md_result_file); /* If not empty table */
fflush(md_result_file);
@@ -1242,11 +1232,11 @@ static void dumpTable(uint numFields, char *table)
safe_exit(EX_CONSCHECK);
return;
}
- if (opt_disable_keys)
- fprintf(md_result_file, "\n/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
- result_table);
if (opt_lock)
fputs("UNLOCK TABLES;\n", md_result_file);
+ if (opt_disable_keys)
+ fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
+ opt_quoted_table);
if (opt_autocommit)
fprintf(md_result_file, "commit;\n");
mysql_free_result(res);
@@ -1258,7 +1248,7 @@ static void print_quoted_xml(FILE *output, char *fname, char *str, uint len)
{
const char *end;
- fprintf(output, "\t\t<%s>", fname);
+ fprintf(output, "\t\t<field name=\"%s\">", fname);
for (end = str + len; str != end; str++)
{
if (*str == '<')
@@ -1272,7 +1262,7 @@ static void print_quoted_xml(FILE *output, char *fname, char *str, uint len)
else
fputc(*str, output);
}
- fprintf(output, "</%s>\n", fname);
+ fprintf(output, "</field>\n");
}
static char *getTableName(int reset)
@@ -1327,13 +1317,8 @@ static int dump_databases(char **db_names)
int result=0;
for ( ; *db_names ; db_names++)
{
- /*XML edit - add database element*/
- if (opt_xml)
- fprintf(md_result_file, "<%s>\n", *db_names);
if (dump_all_tables_in_db(*db_names))
result=1;
- if (opt_xml)
- fprintf(md_result_file, "</%s>\n", *db_names);
}
return result;
} /* dump_databases */
@@ -1346,14 +1331,18 @@ static int init_dumping(char *database)
DBerror(sock, "when selecting the database");
return 1; /* If --force */
}
- if (!path)
+ if (!path && !opt_xml)
{
if (opt_databases || opt_alldbs)
{
- fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", database);
+ /* length of table name * 2 (if name contain quotas), 2 quotas and 0 */
+ char quoted_database_buf[64*2+3];
+ char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
+ if (opt_comments)
+ fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", database);
if (!opt_create_db)
fprintf(md_result_file,"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
- database);
+ qdatabase);
fprintf(md_result_file,"\nUSE %s;\n", database);
}
}
@@ -1372,6 +1361,8 @@ static int dump_all_tables_in_db(char *database)
if (init_dumping(database))
return 1;
+ if (opt_xml)
+ fprintf(md_result_file, "<database name=\"%s\">\n", database);
if (lock_tables)
{
DYNAMIC_STRING query;
@@ -1398,8 +1389,10 @@ static int dump_all_tables_in_db(char *database)
if (!dFlag && numrows > 0)
dumpTable(numrows,table);
}
+ if (opt_xml)
+ fprintf(md_result_file, "</database>\n");
if (lock_tables)
- mysql_query(sock,"UNLOCK_TABLES");
+ mysql_query(sock,"UNLOCK TABLES");
return 0;
} /* dump_all_tables_in_db */
@@ -1434,14 +1427,18 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
DBerror(sock, "when doing refresh");
/* We shall countinue here, if --force was given */
}
+ if (opt_xml)
+ fprintf(md_result_file, "<database name=\"%s\">\n", db);
for (; tables > 0 ; tables-- , table_names++)
{
numrows = getTableStructure(*table_names, db);
if (!dFlag && numrows > 0)
dumpTable(numrows, *table_names);
}
+ if (opt_xml)
+ fprintf(md_result_file, "</database>\n");
if (lock_tables)
- mysql_query(sock,"UNLOCK_TABLES");
+ mysql_query(sock,"UNLOCK TABLES");
return 0;
} /* dump_selected_tables */
@@ -1474,15 +1471,67 @@ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
} /* print_value */
+/*
+ Check if we the table is one of the table types that should be ignored:
+ MRG_ISAM, MRG_MYISAM
+
+ SYNOPSIS
+ check_if_ignore_table()
+ table_name Table name to check
+
+ GLOBAL VARIABLES
+ sock MySQL socket
+ verbose Write warning messages
+
+ RETURN
+ 0 Table should be backuped
+ # Type of table (that should be skipped)
+*/
+
+static const char *check_if_ignore_table(const char *table_name)
+{
+ char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ const char *result= 0;
+
+ sprintf(buff,"show table status like %s",
+ quote_for_like(table_name, show_name_buff));
+ if (mysql_query(sock, buff))
+ {
+ if (mysql_errno(sock) != ER_PARSE_ERROR)
+ { /* If old MySQL version */
+ if (verbose)
+ fprintf(stderr,
+ "-- Warning: Couldn't get status information for table %s (%s)\n",
+ table_name,mysql_error(sock));
+ return 0; /* assume table is ok */
+ }
+ }
+ if (!(res= mysql_store_result(sock)) ||
+ !(row= mysql_fetch_row(res)))
+ {
+ fprintf(stderr,
+ "Error: Couldn't read status information for table %s (%s)\n",
+ table_name, mysql_error(sock));
+ if (res)
+ mysql_free_result(res);
+ return 0; /* assume table is ok */
+ }
+ if (strcmp(row[1], (result= "MRG_MyISAM")) &&
+ strcmp(row[1], (result= "MRG_ISAM")))
+ result= 0;
+ mysql_free_result(res);
+ return result;
+}
+
+
int main(int argc, char **argv)
{
MYSQL_ROW row;
MYSQL_RES *master;
MY_INIT(argv[0]);
- /*
- ** Check out the args
- */
if (get_options(&argc, &argv))
{
my_end(0);
@@ -1504,14 +1553,29 @@ int main(int argc, char **argv)
return(first_error);
}
}
+ else if (opt_single_transaction)
+ {
+ /* There is no sense to start transaction if all tables are locked */
+ if (mysql_query(sock, "BEGIN"))
+ {
+ my_printf_error(0, "Error: Couldn't execute 'BEGIN': %s",
+ MYF(0), mysql_error(sock));
+ my_end(0);
+ return(first_error);
+ }
+ }
if (opt_alldbs)
dump_all_databases();
- /* Only one database and selected table(s) */
else if (argc > 1 && !opt_databases)
+ {
+ /* Only one database and selected table(s) */
dump_selected_tables(*argv, (argv + 1), (argc - 1));
- /* One or more databases, all tables */
+ }
else
+ {
+ /* One or more databases, all tables */
dump_databases(argv);
+ }
if (opt_first_slave)
{
@@ -1524,32 +1588,43 @@ int main(int argc, char **argv)
{
if (mysql_query(sock, "SHOW MASTER STATUS") ||
!(master = mysql_store_result(sock)))
- {
my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s",
MYF(0), mysql_error(sock));
- }
else
{
row = mysql_fetch_row(master);
- if(row && row[0] && row[1]) {
- fprintf(md_result_file,
- "\n--\n-- Position to start replication from\n--\n\n");
+ if (row && row[0] && row[1])
+ {
+ if (opt_comments)
+ fprintf(md_result_file,
+ "\n--\n-- Position to start replication from\n--\n\n");
fprintf(md_result_file,
- "CHANGE MASTER TO MASTER_LOG_FILE='%s' ;\n", row[0]);
- fprintf(md_result_file, "CHANGE MASTER TO MASTER_LOG_POS=%s ;\n",
- row[1]);
+ "CHANGE MASTER TO MASTER_LOG_FILE='%s', \
+MASTER_LOG_POS=%s ;\n",row[0],row[1]);
}
mysql_free_result(master);
}
}
if (mysql_query(sock, "UNLOCK TABLES"))
- {
my_printf_error(0, "Error: Couldn't execute 'UNLOCK TABLES': %s",
MYF(0), mysql_error(sock));
- }
+ }
+ else if (opt_single_transaction) /* Just to make it beautiful enough */
+ {
+ /*
+ In case we were locking all tables, we did not start transaction
+ so there is no need to commit it.
+ */
+
+ /* This should just free locks as we did not change anything */
+ if (mysql_query(sock, "COMMIT"))
+ {
+ my_printf_error(0, "Error: Couldn't execute 'COMMIT': %s",
+ MYF(0), mysql_error(sock));
+ }
}
dbDisconnect(current_host);
- fputs("\n", md_result_file);
+ write_footer(md_result_file);
if (md_result_file != stdout)
my_fclose(md_result_file, MYF(0));
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index d1140c74358..c72e32dd2a7 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -25,7 +25,7 @@
** * *
** *************************
*/
-#define IMPORT_VERSION "2.8"
+#define IMPORT_VERSION "3.4"
#include "client_priv.h"
#include "mysql_version.h"
@@ -37,53 +37,98 @@ static char *add_load_option(char *ptr,const char *object,
const char *statement);
static my_bool verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0,
- replace=0,silent=0,ignore=0,opt_compress=0,opt_local_file=0;
-
+ replace=0,silent=0,ignore=0,opt_compress=0,opt_local_file=0,
+ opt_low_priority= 0, tty_password= 0;
static MYSQL mysql_connection;
static char *opt_password=0, *current_user=0,
*current_host=0, *current_db=0, *fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0,
- *escaped=0, opt_low_priority=0, *opt_columns=0,
- *default_charset;
+ *escaped=0, *opt_columns=0, *default_charset;
static uint opt_mysql_port=0;
static my_string opt_mysql_unix_port=0;
-#include "sslopt-vars.h"
+static longlong opt_ignore_lines= -1;
+#include <sslopt-vars.h>
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR},
- {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
- {"columns", required_argument, 0, 'c'},
- {"compress", no_argument, 0, 'C'},
- {"debug", optional_argument, 0, '#'},
- {"delete", no_argument, 0, 'd'},
- {"fields-terminated-by", required_argument, 0, (int) OPT_FTB},
- {"fields-enclosed-by", required_argument, 0, (int) OPT_ENC},
- {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC},
- {"fields-escaped-by", required_argument, 0, (int) OPT_ESC},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"ignore", no_argument, 0, 'i'},
- {"lines-terminated-by", required_argument, 0, (int) OPT_LTB},
- {"local", no_argument, 0, 'L'},
- {"lock-tables", no_argument, 0, 'l'},
- {"low-priority", no_argument, 0, (int) OPT_LOW_PRIORITY},
- {"password", optional_argument, 0, 'p'},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default-character-set", OPT_DEFAULT_CHARSET,
+ "Set the default character set.", (gptr*) &default_charset,
+ (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"columns", 'c',
+ "Use only these columns to import the data to. Give the column names in a comma separated list. This is same as giving columns to LOAD DATA INFILE.",
+ (gptr*) &opt_columns, (gptr*) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol.",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'", 0, 0, 0,
+ GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"delete", 'd', "First delete all rows from table.", (gptr*) &opt_delete,
+ (gptr*) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"fields-terminated-by", OPT_FTB,
+ "Fields in the textfile are terminated by ...", (gptr*) &fields_terminated,
+ (gptr*) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"fields-enclosed-by", OPT_ENC,
+ "Fields in the importfile are enclosed by ...", (gptr*) &enclosed,
+ (gptr*) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"fields-optionally-enclosed-by", OPT_O_ENC,
+ "Fields in the i.file are opt. enclosed by ...", (gptr*) &opt_enclosed,
+ (gptr*) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
+ (gptr*) &escaped, (gptr*) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"force", 'f', "Continue even if we get an sql-error.",
+ (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &current_host,
+ (gptr*) &current_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"ignore", 'i', "If duplicate unique key was found, keep old row.",
+ (gptr*) &ignore, (gptr*) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
+ (gptr*) &opt_ignore_lines, (gptr*) &opt_ignore_lines, 0, GET_LL,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
+ (gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"local", 'L', "Read all files through the client", (gptr*) &opt_local_file,
+ (gptr*) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"lock-tables", 'l', "Lock all tables for write.", (gptr*) &lock_tables,
+ (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"low-priority", OPT_LOW_PRIORITY,
+ "Use LOW_PRIORITY when updating the table", (gptr*) &opt_low_priority,
+ (gptr*) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"port", required_argument, 0, 'P'},
- {"replace", no_argument, 0, 'r'},
- {"silent", no_argument, 0, 's'},
- {"socket", required_argument, 0, 'S'},
-#include "sslopt-longopts.h"
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
+ {"replace", 'r', "If duplicate unique key was found, replace old row.",
+ (gptr*) &replace, (gptr*) &replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Be more silent.", (gptr*) &silent, (gptr*) &silent, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#include <sslopt-longopts.h>
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.", (gptr*) &current_user,
+ (gptr*) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"verbose", 'v', "Print info about the various stages.", (gptr*) &verbose,
+ (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -110,155 +155,57 @@ read the text file directly. In other cases the client will open the text\n\
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
printf("\nUsage: %s [OPTIONS] database textfile...",my_progname);
- printf("\n\
- -#, --debug[=...] Output debug log. Often this is 'd:t:o,filename`\n\
- -?, --help Displays this help and exits.\n\
- --default-character-set=...\n\
- Set the default character set.\n\
- --character-sets-dir=...\n\
- Directory where character sets are\n\
- -c, --columns=... Use only these columns to import the data to.\n\
- Give the column names in a comma separated list.\n\
- This is same as giving columns to LOAD DATA INFILE.\n\
- -C, --compress Use compression in server/client protocol\n\
- -d, --delete First delete all rows from table.\n\
- -f, --force Continue even if we get an sql-error.\n\
- -h, --host=... Connect to host.\n\
- -i, --ignore If duplicate unique key was found, keep old row.\n\
- -l, --lock-tables Lock all tables for write.\n\
- -L, --local Read all files through the client\n\
- --low-priority Use LOW_PRIORITY when updating the table\n\
- -p, --password[=...] Password to use when connecting to server.\n\
- If password is not given it's asked from the tty.\n");
-#ifdef __WIN__
- puts("-W, --pipe Use named pipes to connect to server");
-#endif
- printf("\
- -P, --port=... Port number to use for connection.\n\
- -r, --replace If duplicate unique key was found, replace old row.\n\
- -s, --silent Be more silent.\n\
- -S, --socket=... Socket file to use for connection.\n");
-#include "sslopt-usage.h"
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# User for login if not current user.\n");
-#endif
- printf("\
- -v, --verbose Print info about the various stages.\n\
- -V, --version Output version information and exit.\n\
- --fields-terminated-by=...\n\
- Fields in the textfile are terminated by ...\n\
- --fields-enclosed-by=...\n\
- Fields in the importfile are enclosed by ...\n\
- --fields-optionally-enclosed-by=...\n\
- Fields in the i.file are opt. enclosed by ...\n\
- --fields-escaped-by=...\n\
- Fields in the i.file are escaped by ...\n\
- --lines-terminated-by=...\n\
- Lines in the i.file are terminated by ...\n\
-");
print_defaults("my",load_default_groups);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
}
-static int get_options(int *argc, char ***argv)
-{
- int c, option_index;
- my_bool tty_password=0;
- while ((c=getopt_long(*argc,*argv,
- (char*) "#::p::c:h:u:P:S:CdfilLrsvV?IW",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'c':
- opt_columns= optarg;
- break;
- case 'C':
- opt_compress=1;
- break;
- case OPT_DEFAULT_CHARSET:
- default_charset= optarg;
- break;
- case OPT_CHARSETS_DIR:
- charsets_dir= optarg;
- break;
- case 'd':
- opt_delete= 1;
- break;
- case 'f':
- ignore_errors= 1;
- break;
- case 'h':
- current_host= optarg;
- break;
- case 'i':
- ignore= 1;
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- current_user= optarg;
- break;
-#endif
- case 'p':
- if (optarg)
- {
- char *start=optarg;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- opt_password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1]=0; /* Cut length of argument */
- }
- else
- tty_password= 1;
- break;
- case 'P':
- opt_mysql_port= (unsigned int) atoi(optarg);
- break;
- case 'r':
- replace= 1;
- break;
- case 's':
- silent= 1;
- break;
- case 'S':
- opt_mysql_unix_port= optarg;
- break;
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case 'p':
+ if (argument)
+ {
+ char *start=argument;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(argument,MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
+ }
+ else
+ tty_password= 1;
+ break;
#ifdef __WIN__
- case 'W':
- opt_mysql_unix_port=MYSQL_NAMEDPIPE;
- opt_local_file=1;
- break;
+ case 'W':
+ opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+ opt_local_file=1;
+ break;
#endif
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case 'l': lock_tables= 1; break;
- case 'L': opt_local_file=1; break;
- case 'v': verbose= 1; break;
- case 'V': print_version(); exit(0);
- case 'I':
- case '?':
- usage();
- exit(0);
- case (int) OPT_FTB:
- fields_terminated= optarg;
- break;
- case (int) OPT_LTB:
- lines_terminated= optarg;
- break;
- case (int) OPT_ENC:
- enclosed= optarg;
- break;
- case (int) OPT_O_ENC:
- opt_enclosed= optarg;
- break;
- case (int) OPT_ESC:
- escaped= optarg;
- break;
-#include "sslopt-case.h"
- }
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+#include <sslopt-case.h>
+ case 'V': print_version(); exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
}
+ return 0;
+}
+
+
+static int get_options(int *argc, char ***argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (enclosed && opt_enclosed)
{
fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
@@ -274,8 +221,6 @@ static int get_options(int *argc, char ***argv)
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
exit(1);
}
- (*argc)-=optind;
- (*argv)+=optind;
if (*argc < 2)
{
usage();
@@ -293,7 +238,7 @@ static int get_options(int *argc, char ***argv)
static int write_to_table(char *filename, MYSQL *sock)
{
char tablename[FN_REFLEN], hard_path[FN_REFLEN],
- sql_statement[FN_REFLEN*2+256], *end;
+ sql_statement[FN_REFLEN*16+256], *end;
my_bool local_file;
DBUG_ENTER("write_to_table");
DBUG_PRINT("enter",("filename: %s",filename));
@@ -345,6 +290,9 @@ static int write_to_table(char *filename, MYSQL *sock)
" OPTIONALLY ENCLOSED BY");
end= add_load_option(end, escaped, " ESCAPED BY");
end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
+ if (opt_ignore_lines >= 0)
+ end= strmov(longlong10_to_str(opt_ignore_lines,
+ strmov(end, " IGNORE "),10), " LINES");
if (opt_columns)
end= strmov(strmov(strmov(end, " ("), opt_columns), ")");
*end= '\0';
@@ -522,9 +470,15 @@ int main(int argc, char **argv)
/* argv is changed in the program */
argv_to_free= argv;
if (get_options(&argc, &argv))
+ {
+ free_defaults(argv_to_free);
return(1);
+ }
if (!(sock= db_connect(current_host,current_db,current_user,opt_password)))
+ {
+ free_defaults(argv_to_free);
return(1); /* purecov: deadcode */
+ }
if (lock_tables)
lock_table(sock, argc, argv);
for (; *argv != NULL; argv++)
diff --git a/client/mysqlmanager-pwgen.c b/client/mysqlmanager-pwgen.c
new file mode 100644
index 00000000000..57d91b52f49
--- /dev/null
+++ b/client/mysqlmanager-pwgen.c
@@ -0,0 +1,161 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#define MANAGER_PWGEN_VERSION "1.4"
+
+#include <my_global.h>
+#include <m_ctype.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <mysql_version.h>
+#include <errno.h>
+#include <my_getopt.h>
+#include <md5.h>
+
+const char* outfile=0,*user="root";
+
+static struct my_option my_long_options[] =
+{
+ {"output-file", 'o', "Write the output to the file with the given name",
+ (gptr*) &outfile, (gptr*) &outfile, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"user", 'u', "Put given user in the password file", (gptr*) &user,
+ (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this message and exit", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Display version info", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+static void die(const char* fmt, ...)
+{
+ va_list args;
+ DBUG_ENTER("die");
+ va_start(args, fmt);
+ if (fmt)
+ {
+ fprintf(stderr, "%s: ", my_progname);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ }
+ va_end(args);
+ exit(1);
+}
+
+static void print_version(void)
+{
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,
+ MANAGER_PWGEN_VERSION,
+ MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+
+void usage()
+{
+ print_version();
+ printf("MySQL AB, by Sasha\n");
+ printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
+ printf("Generates a password file to be used by mysqltest.\n\n");
+ printf("Usage: %s [OPTIONS]\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch (optid) {
+ case '?':
+ usage();
+ exit(0);
+ case 'V':
+ print_version();
+ exit(0);
+ }
+ return 0;
+}
+
+
+int parse_args(int argc, char** argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ return 0;
+}
+
+void get_pass(char* pw, int len)
+{
+ FILE* fp;
+ char* pw_end=pw+len;
+ /*
+ /dev/random is more secure than rand() because the seed is easy to
+ predict, so we resort to rand() only if /dev/random is not available
+ */
+ if ((fp=fopen("/dev/random","r")))
+ {
+ fread(pw,len,1,fp);
+ fclose(fp);
+ while (pw<pw_end)
+ {
+ char tmp= 'a'+((uint)*pw % 26);
+ *pw++= tmp;
+ }
+ }
+ else
+ {
+ srand(time(NULL));
+ while (pw<pw_end)
+ {
+ char tmp= 'a'+((uint)*pw % 26);
+ *pw++= tmp;
+ }
+ }
+ *pw_end=0;
+}
+
+
+int main(int argc, char** argv)
+{
+ FILE* fp;
+ my_MD5_CTX context;
+ uchar digest[16];
+ char pw[17];
+ uint i;
+
+ MY_INIT(argv[0]);
+ parse_args(argc,argv);
+ if (!outfile)
+ die("Missing --output-file");
+
+ if (!(fp=fopen(outfile,"w")))
+ die("Could not open '%s'(errno=%d)",outfile,errno);
+ get_pass(pw,sizeof(pw)-1);
+ my_MD5Init(&context);
+ my_MD5Update(&context,(uchar*) pw,sizeof(pw)-1);
+ my_MD5Final(digest,&context);
+ fprintf(fp,"%s:",user);
+ for (i=0;i<sizeof(digest);i++)
+ fprintf(fp,"%02x",digest[i]);
+ fprintf(fp,"\n");
+ fclose(fp);
+ printf("%s\n",pw);
+ return 0;
+}
diff --git a/client/mysqlmanagerc.c b/client/mysqlmanagerc.c
new file mode 100644
index 00000000000..0001a0266e6
--- /dev/null
+++ b/client/mysqlmanagerc.c
@@ -0,0 +1,174 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#define MANAGER_CLIENT_VERSION "1.4"
+
+#include <my_global.h>
+#include <mysql.h>
+#include <mysql_version.h>
+#include <mysqld_error.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <my_getopt.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifndef MYSQL_MANAGER_PORT
+#define MYSQL_MANAGER_PORT 9305
+#endif
+
+static void die(const char* fmt, ...);
+
+const char* user="root",*host="localhost";
+char* pass=0;
+my_bool quiet=0;
+uint port=MYSQL_MANAGER_PORT;
+static const char *load_default_groups[]= { "mysqlmanagerc",0 };
+char** default_argv;
+MYSQL_MANAGER *manager;
+FILE* fp, *fp_out;
+
+static struct my_option my_long_options[] =
+{
+ {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "User for login.", (gptr*) &user, (gptr*) &user, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p', "Password to use when connecting to server.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &port,
+ (gptr*) &port, 0, GET_UINT, REQUIRED_ARG, MYSQL_MANAGER_PORT, 0, 0, 0, 0,
+ 0},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"quiet", 'q', "Suppress all normal output.", (gptr*) &quiet, (gptr*) &quiet,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+static void die(const char* fmt, ...)
+{
+ va_list args;
+ DBUG_ENTER("die");
+ va_start(args, fmt);
+ if (fmt)
+ {
+ fprintf(stderr, "%s: ", my_progname);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ }
+ va_end(args);
+ exit(1);
+}
+
+static void print_version(void)
+{
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,
+ MANAGER_CLIENT_VERSION,
+ MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+
+void usage()
+{
+ print_version();
+ printf("MySQL AB, by Sasha\n");
+ printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
+ printf("Command-line client for MySQL manager daemon.\n\n");
+ printf("Usage: %s [OPTIONS] < command_file\n", my_progname);
+ my_print_help(my_long_options);
+ printf(" --no-defaults Don't read default options from any options file.\n");
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ my_bool tty_password=0;
+
+ switch (optid) {
+ case 'p':
+ if (argument)
+ {
+ my_free(pass, MYF(MY_ALLOW_ZERO_PTR));
+ pass= my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ }
+ else
+ tty_password=1;
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ int ho_error;
+
+ load_defaults("my",load_default_groups,&argc,&argv);
+ default_argv= argv;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ return 0;
+}
+
+
+int main(int argc, char** argv)
+{
+ MY_INIT(argv[0]);
+ fp=stdin;
+ fp_out=stdout;
+ parse_args(argc,argv);
+ if (!(manager=mysql_manager_init(0)))
+ die("Failed in mysql_manager_init()");
+ if (!mysql_manager_connect(manager,host,user,pass,port))
+ die("Could not connect to MySQL manager: %s (%d)",manager->last_error,
+ manager->last_errno);
+ for (;!feof(fp);)
+ {
+ char buf[4096];
+ if (!fgets(buf,sizeof(buf),fp))
+ break;
+ if (!quiet)
+ fprintf(fp_out,"<<%s",buf);
+ if (mysql_manager_command(manager,buf,strlen(buf)))
+ die("Error in command: %s (%d)",manager->last_error,manager->last_errno);
+ while (!manager->eof)
+ {
+ if (mysql_manager_fetch_line(manager,buf,sizeof(buf)))
+ die("Error fetching result line: %s (%d)", manager->last_error,
+ manager->last_errno);
+ if (!quiet)
+ fprintf(fp_out,">>%s\n",buf);
+ }
+ }
+ mysql_manager_close(manager);
+ return 0;
+}
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 199318abc2f..ccae43e4e27 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -1,35 +1,34 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Show databases, tables or columns */
-#define SHOW_VERSION "8.3"
+#define SHOW_VERSION "9.4"
-#include <global.h>
+#include "client_priv.h"
#include <my_sys.h>
#include <m_string.h>
-#include "mysql.h"
-#include "mysql_version.h"
-#include "mysqld_error.h"
+#include <mysql.h>
+#include <mysqld_error.h>
#include <signal.h>
#include <stdarg.h>
-#include <getopt.h>
+#include <sslopt-vars.h>
static my_string host=0,opt_password=0,user=0;
-static my_bool opt_show_keys=0,opt_compress=0,opt_status=0;
+static my_bool opt_show_keys=0,opt_compress=0,opt_status=0, tty_password=0;
static uint opt_verbose=0;
static void get_options(int *argc,char ***argv);
@@ -48,11 +47,11 @@ static void print_res_row(MYSQL_RES *result,MYSQL_ROW cur);
static const char *load_default_groups[]= { "mysqlshow","client",0 };
static my_string opt_mysql_unix_port=0;
-#include "sslopt-vars.h"
int main(int argc, char **argv)
{
int error;
+ my_bool first_argument_uses_wildcards=0;
char *wild;
MYSQL mysql;
MY_INIT(argv[0]);
@@ -60,21 +59,37 @@ int main(int argc, char **argv)
get_options(&argc,&argv);
wild=0;
- if (argc && strcont(argv[argc-1],"*?%_"))
+ if (argc)
{
- char *pos;
-
- wild=argv[--argc];
- for (pos=wild ; *pos ; pos++)
- { /* Unix wildcards to sql */
- if (*pos == '*')
- *pos='%';
- else if (*pos == '?')
- *pos='_';
- }
+ char *pos= argv[argc-1], *to;
+ for (to= pos ; *pos ; pos++, to++)
+ {
+ switch (*pos)
+ {
+ case '*':
+ *pos= '%';
+ first_argument_uses_wildcards= 1;
+ break;
+ case '?':
+ *pos= '_';
+ first_argument_uses_wildcards= 1;
+ break;
+ case '%':
+ case '_':
+ first_argument_uses_wildcards= 1;
+ break;
+ case '\\':
+ pos++;
+ default: break;
+ }
+ *to= *pos;
+ }
+ *to= *pos; /* just to copy a '\0' if '\\' was used */
}
+ if (first_argument_uses_wildcards)
+ wild= argv[--argc];
else if (argc == 3) /* We only want one field */
- wild=argv[--argc];
+ wild= argv[--argc];
if (argc > 2)
{
@@ -87,10 +102,10 @@ int main(int argc, char **argv)
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
- opt_ssl_capath);
+ opt_ssl_capath, opt_ssl_cipher);
#endif
if (!(mysql_real_connect(&mysql,host,user,opt_password,
- argv[0],opt_mysql_port,opt_mysql_unix_port,
+ (first_argument_uses_wildcards) ? "" : argv[0],opt_mysql_port,opt_mysql_unix_port,
0)))
{
fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql));
@@ -121,32 +136,52 @@ int main(int argc, char **argv)
return 0; /* No compiler warnings */
}
-
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"character-sets-dir", required_argument, 0, 'c'},
- {"compress", no_argument, 0, 'C'},
- {"debug", optional_argument, 0, '#'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"status", no_argument, 0, 'i'},
- {"keys", no_argument, 0, 'k'},
- {"password", optional_argument, 0, 'p'},
- {"port", required_argument, 0, 'P'},
+ {"character-sets-dir", 'c', "Directory where character sets are",
+ (gptr*) &charsets_dir, (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"status", 'i', "Shows a lot of extra information about each table.",
+ (gptr*) &opt_status, (gptr*) &opt_status, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"keys", 'k', "Show keys for table", (gptr*) &opt_show_keys,
+ (gptr*) &opt_show_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
#ifdef __WIN__
- {"pipe", no_argument, 0, 'W'},
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"socket", required_argument, 0, 'S'},
-#include "sslopt-longopts.h"
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#include <sslopt-longopts.h>
#ifndef DONT_ALLOW_USER_CHANGE
- {"user", required_argument, 0, 'u'},
+ {"user", 'u', "User for login if not current user.", (gptr*) &user,
+ (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"verbose", 'v',
+ "More verbose output; You can use this multiple times to get even more verbose output.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-
-
+
+
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,SHOW_VERSION,
@@ -160,33 +195,6 @@ static void usage(void)
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Shows the structure of a mysql database (databases,tables and columns)\n");
printf("Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname);
- printf("\n\
- -#, --debug=... output debug log. Often this is 'd:t:o,filename`\n\
- -?, --help display this help and exit\n\
- -c, --character-sets-dir=...\n\
- Directory where character sets are\n\
- -C, --compress Use compression in server/client protocol\n\
- -h, --host=... connect to host\n\
- -i, --status Shows a lot of extra information about each table\n\
- -k, --keys show keys for table\n\
- -p, --password[=...] password to use when connecting to server\n\
- If password is not given it's asked from the tty.\n");
-#ifdef __WIN__
- puts("-W, --pipe Use named pipes to connect to server");
-#endif
- printf("\
- -P --port=... Port number to use for connection\n\
- -S --socket=... Socket file to use for connection\n");
-#include "sslopt-usage.h"
-#ifndef DONT_ALLOW_USER_CHANGE
- printf("\
- -u, --user=# user for login if not current user\n");
-#endif
- printf("\
- -v, --verbose more verbose output; You can use this multiple times\n\
- to get even more verbose output.\n\
- -V, --version output version information and exit\n");
-
puts("\n\
If last argument contains a shell or SQL wildcard (*,?,% or _) then only\n\
what\'s matched by the wildcard is shown.\n\
@@ -195,85 +203,61 @@ If no table is given then all matching tables in database are shown\n\
If no column is given then all matching columns and columntypes in table\n\
are shown");
print_defaults("my",load_default_groups);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case 'v':
+ opt_verbose++;
+ break;
+ case 'p':
+ if (argument)
+ {
+ char *start=argument;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(argument,MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
+ }
+ else
+ tty_password=1;
+ break;
+ case 'W':
+#ifdef __WIN__
+ opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+#endif
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+#include <sslopt-case.h>
+ case 'V':
+ print_version();
+ exit(0);
+ break;
+ case '?':
+ case 'I': /* Info */
+ usage();
+ exit(0);
+ }
+ return 0;
}
static void
get_options(int *argc,char ***argv)
{
- int c,option_index;
- my_bool tty_password=0;
+ int ho_error;
- while ((c=getopt_long(*argc,*argv,"c:h:p::u:#::P:S:Ck?vVWi",long_options,
- &option_index)) != EOF)
- {
- switch(c) {
- case 'C':
- opt_compress=1;
- break;
- case 'c':
- charsets_dir= optarg;
- break;
- case 'v':
- opt_verbose++;
- break;
- case 'h':
- host = optarg;
- break;
- case 'i':
- opt_status=1;
- break;
- case 'k':
- opt_show_keys=1;
- break;
- case 'p':
- if (optarg)
- {
- char *start=optarg;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- opt_password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- if (*start)
- start[1]=0; /* Cut length of argument */
- }
- else
- tty_password=1;
- break;
-#ifndef DONT_ALLOW_USER_CHANGE
- case 'u':
- user=optarg;
- break;
-#endif
- case 'P':
- opt_mysql_port= (unsigned int) atoi(optarg);
- break;
- case 'S':
- opt_mysql_unix_port= optarg;
- break;
- case 'W':
-#ifdef __WIN__
- opt_mysql_unix_port=MYSQL_NAMEDPIPE;
-#endif
- break;
-#include "sslopt-case.h"
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case 'V':
- print_version();
- exit(0);
- break;
- default:
- fprintf(stderr,"Illegal option character '%c'\n",opterr);
- /* Fall throught */
- case '?':
- case 'I': /* Info */
- usage();
- exit(0);
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (tty_password)
opt_password=get_tty_password(NullS);
return;
@@ -713,7 +697,7 @@ static void print_res_header(MYSQL_RES *result)
putchar('|');
while ((field = mysql_fetch_field(result)))
{
- printf(" %-*s|",field->max_length+1,field->name);
+ printf(" %-*s|",(int) field->max_length+1,field->name);
}
putchar('\n');
print_res_top(result);
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 18fafff275e..13f575eaf0a 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,20 +15,19 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* mysqltest test tool
- * See man page for more information.
+ * See the manual for more information
+ * TODO: document better how mysqltest works
*
* Written by:
* Sasha Pachev <sasha@mysql.com>
* Matt Wagner <matt@mysql.com>
* Monty
+ * Jani
**/
/**********************************************************************
TODO:
-- Print also the queries that returns a result to the log file; This makes
- it much easier to find out what's wrong.
-
- Do comparison line by line, instead of doing a full comparison of
the text file. This will save space as we don't need to keep many
results in memory. It will also make it possible to do simple
@@ -43,34 +42,27 @@
**********************************************************************/
-#define MTEST_VERSION "1.11"
+#define MTEST_VERSION "1.30"
-#include <global.h>
+#include <my_global.h>
+#include <mysql_embed.h>
#include <my_sys.h>
#include <m_string.h>
#include <mysql.h>
#include <mysql_version.h>
+#include <mysqld_error.h>
#include <m_ctype.h>
-#ifdef OS2
-#include <config-os2.h>
-#else
- #include <my_config.h>
-#endif
#include <my_dir.h>
#include <hash.h>
-#include <mysqld_error.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
+#include <my_getopt.h>
#include <stdarg.h>
#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
#include <violite.h>
-#define MAX_QUERY 65536
+#define MAX_QUERY 65536
+#define MAX_COLUMNS 256
#define PAD_SIZE 128
-#define MAX_CONS 1024
+#define MAX_CONS 128
#define MAX_INCLUDE_DEPTH 16
#define LAZY_GUESS_BUF_SIZE 8192
#define INIT_Q_LINES 1024
@@ -79,17 +71,45 @@
#define MAX_EXPECTED_ERRORS 10
#define QUERY_SEND 1
#define QUERY_REAP 2
-#define CON_RETRY_SLEEP 1 /* how long to sleep before trying to connect again*/
-#define MAX_CON_TRIES 2 /* sometimes in a test the client starts before
- * the server - to solve the problem, we try again
- * after some sleep if connection fails the first
- * time */
+#ifndef MYSQL_MANAGER_PORT
+#define MYSQL_MANAGER_PORT 23546
+#endif
+#define MAX_SERVER_ARGS 20
+
+/* Defines to make this look like MySQL 4.1 */
+#define charset_info default_charset_info
+#define my_isvar(A,B) isvar(B)
+#define my_hash_insert(A,B) hash_insert((A), (B))
+
+/*
+ Sometimes in a test the client starts before
+ the server - to solve the problem, we try again
+ after some sleep if connection fails the first
+ time
+*/
+#define CON_RETRY_SLEEP 2
+#define MAX_CON_TRIES 5
+
+#define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */
-static int record = 0, verbose = 0, silent = 0, opt_sleep=0;
+
+enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
+ OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC,
+ OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
+ OPT_SSL_CIPHER};
+
+static int record = 0, opt_sleep=0;
static char *db = 0, *pass=0;
-const char* user = 0, *host = 0, *unix_sock = 0;
-static int port = 0, opt_big_test=0;
+const char* user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./";
+static int port = 0;
+static my_bool opt_big_test= 0, opt_compress= 0, silent= 0, verbose = 0,
+ tty_password= 0;
static uint start_lineno, *lineno;
+const char* manager_user="root",*manager_host=0;
+char *manager_pass=0;
+int manager_port=MYSQL_MANAGER_PORT;
+int manager_wait_timeout=3;
+MYSQL_MANAGER* manager=0;
static char **default_argv;
static const char *load_default_groups[]= { "mysqltest","client",0 };
@@ -99,18 +119,28 @@ static FILE** cur_file;
static FILE** file_stack_end;
static uint lineno_stack[MAX_INCLUDE_DEPTH];
static char TMPDIR[FN_REFLEN];
-static int *block_ok_stack_end;
static int *cur_block, *block_stack_end;
static int block_stack[BLOCK_STACK_DEPTH];
-
static int block_ok_stack[BLOCK_STACK_DEPTH];
-static uint global_expected_errno[MAX_EXPECTED_ERRORS];
+static uint global_expected_errno[MAX_EXPECTED_ERRORS], global_expected_errors;
+
+static int embedded_server_arg_count=0;
+static char *embedded_server_args[MAX_SERVER_ARGS];
+
+static const char *embedded_server_groups[] = {
+ "server",
+ "embedded",
+ "mysqltest_SERVER",
+ NullS
+};
DYNAMIC_ARRAY q_lines;
-typedef struct
+#include "sslopt-vars.h"
+
+typedef struct
{
char file[FN_REFLEN];
ulong pos;
@@ -127,27 +157,32 @@ typedef struct
int read_lines,current_line;
} PARSER;
+MYSQL_RES *last_result=0;
+
PARSER parser;
MASTER_POS master_pos;
-int* block_ok; /* set to 0 if the current block should not be executed */
+int *block_ok; /* set to 0 if the current block should not be executed */
int false_block_depth = 0;
-const char* result_file = 0; /* if set, all results are concated and
- compared against this file*/
+/* if set, all results are concated and compared against this file */
+const char *result_file = 0;
typedef struct
{
- char* name;
+ char *name;
int name_len;
- char* str_val;
+ char *str_val;
int str_val_len;
int int_val;
int alloced_len;
int int_dirty; /* do not update string if int is updated until first read */
+ int alloced;
} VAR;
VAR var_reg[10];
/*Perl/shell-like variable registers */
HASH var_hash;
+my_bool disable_query_log=0, disable_result_log=0, disable_warnings=0;
+my_bool disable_info= 1; /* By default off */
struct connection cons[MAX_CONS];
struct connection* cur_con, *next_con, *cons_end;
@@ -155,22 +190,32 @@ struct connection* cur_con, *next_con, *cons_end;
/* Add new commands before Q_UNKNOWN !*/
enum enum_commands {
-Q_CONNECTION=1, Q_QUERY,
-Q_CONNECT, Q_SLEEP,
-Q_INC, Q_DEC,
-Q_SOURCE, Q_DISCONNECT,
-Q_LET, Q_ECHO,
-Q_WHILE, Q_END_BLOCK,
-Q_SYSTEM, Q_RESULT,
-Q_REQUIRE, Q_SAVE_MASTER_POS,
-Q_SYNC_WITH_MASTER, Q_ERROR,
-Q_SEND, Q_REAP,
-Q_DIRTY_CLOSE, Q_REPLACE,
-Q_PING, Q_EVAL,
-Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
+Q_CONNECTION=1, Q_QUERY,
+Q_CONNECT, Q_SLEEP, Q_REAL_SLEEP,
+Q_INC, Q_DEC,
+Q_SOURCE, Q_DISCONNECT,
+Q_LET, Q_ECHO,
+Q_WHILE, Q_END_BLOCK,
+Q_SYSTEM, Q_RESULT,
+Q_REQUIRE, Q_SAVE_MASTER_POS,
+Q_SYNC_WITH_MASTER,
+Q_SYNC_SLAVE_WITH_MASTER,
+Q_ERROR,
+Q_SEND, Q_REAP,
+Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
+Q_PING, Q_EVAL,
+Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
-Q_UNKNOWN, /* Unknown command. */
-Q_COMMENT, /* Comments, ignored. */
+Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
+Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
+Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER,
+Q_WAIT_FOR_SLAVE_TO_STOP,
+Q_REQUIRE_VERSION,
+Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS,
+Q_ENABLE_INFO, Q_DISABLE_INFO,
+Q_EXEC,
+Q_UNKNOWN, /* Unknown command. */
+Q_COMMENT, /* Comments, ignored. */
Q_COMMENT_WITH_COMMAND
};
@@ -181,25 +226,65 @@ struct st_query
int first_word_len;
my_bool abort_on_error, require_file;
uint expected_errno[MAX_EXPECTED_ERRORS];
+ uint expected_errors;
char record_file[FN_REFLEN];
enum enum_commands type;
};
-const char *command_names[] = {
- "connection", "query",
- "connect", "sleep",
- "inc", "dec",
- "source", "disconnect",
- "let", "echo",
- "while", "end",
- "system", "result",
- "require", "save_master_pos",
- "sync_with_master", "error",
- "send", "reap",
- "dirty_close", "replace_result",
- "ping", "eval",
- "rpl_probe", "enable_rpl_parse",
- "disable_rpl_parse", "eval_result",
+const char *command_names[]=
+{
+ "connection",
+ "query",
+ "connect",
+ /* the difference between sleep and real_sleep is that sleep will use
+ the delay from command line (--sleep) if there is one.
+ real_sleep always uses delay from it's argument.
+ the logic is that sometimes delays are cpu-dependent (and --sleep
+ can be used to set this delay. real_sleep is used for cpu-independent
+ delays
+ */
+ "sleep",
+ "real_sleep",
+ "inc",
+ "dec",
+ "source",
+ "disconnect",
+ "let",
+ "echo",
+ "while",
+ "end",
+ "system",
+ "result",
+ "require",
+ "save_master_pos",
+ "sync_with_master",
+ "sync_slave_with_master",
+ "error",
+ "send",
+ "reap",
+ "dirty_close",
+ "replace_result",
+ "replace_column",
+ "ping",
+ "eval",
+ "rpl_probe",
+ "enable_rpl_parse",
+ "disable_rpl_parse",
+ "eval_result",
+ "enable_query_log",
+ "disable_query_log",
+ "enable_result_log",
+ "disable_result_log",
+ "server_start",
+ "server_stop",
+ "require_manager",
+ "wait_for_slave_to_stop",
+ "require_version",
+ "enable_warnings",
+ "disable_warnings",
+ "enable_info",
+ "disable_info",
+ "exec",
0
};
@@ -207,56 +292,68 @@ TYPELIB command_typelib= {array_elements(command_names),"",
command_names};
DYNAMIC_STRING ds_res;
-static void die(const char* fmt, ...);
+static void die(const char *fmt, ...);
static void init_var_hash();
static byte* get_var_key(const byte* rec, uint* len,
my_bool __attribute__((unused)) t);
-static VAR* var_init(VAR* v, const char* name, int name_len, const char* val,
+static VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
int val_len);
static void var_free(void* v);
-int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname);
-void reject_dump(const char* record_file, char* buf, int size);
+int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname);
+void reject_dump(const char *record_file, char *buf, int size);
int close_connection(struct st_query* q);
-VAR* var_get(const char* var_name, const char** var_name_end, int raw);
-int eval_expr(VAR* v, const char* p, const char** p_end);
+VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw,
+ my_bool ignore_not_existing);
+int eval_expr(VAR* v, const char *p, const char** p_end);
+static int read_server_arguments(const char *name);
-/* Definitions for replace */
+/* Definitions for replace result */
typedef struct st_pointer_array { /* when using array-strings */
TYPELIB typelib; /* Pointer to strings */
byte *str; /* Strings is here */
int7 *flag; /* Flag about each var. */
- uint array_allocs,max_count,length,max_length;
+ uint array_allocs,max_count,length,max_length;
} POINTER_ARRAY;
struct st_replace;
struct st_replace *init_replace(my_string *from, my_string *to, uint count,
my_string word_end_chars);
uint replace_strings(struct st_replace *rep, my_string *start,
- uint *max_length, my_string from);
+ uint *max_length, const char *from);
+void free_replace();
static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name);
void free_pointer_array(POINTER_ARRAY *pa);
static int initialize_replace_buffer(void);
static void free_replace_buffer(void);
-static void do_eval(DYNAMIC_STRING* query_eval, const char* query);
-void str_to_file(const char* fname, char* str, int size);
+static void do_eval(DYNAMIC_STRING* query_eval, const char *query);
+void str_to_file(const char *fname, char *str, int size);
+int do_server_op(struct st_query* q,const char *op);
struct st_replace *glob_replace;
static char *out_buff;
static uint out_length;
static int eval_result = 0;
+/* For column replace */
+char *replace_column[MAX_COLUMNS];
+uint max_replace_column= 0;
+
+static void get_replace_column(struct st_query *q);
+static void free_replace_column();
+
/* Disable functions that only exist in MySQL 4.0 */
-#if MYSQL_VERSION_ID < 40000
-static void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
-static void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
-static int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
-static int mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
+#if MYSQL_VERSION_ID < 40000 || defined(EMBEDDED_LIBRARY)
+void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
+void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
+int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
+int mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
#endif
-
+static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
+ int len);
static void do_eval(DYNAMIC_STRING* query_eval, const char* query)
{
@@ -264,43 +361,45 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char* query)
register char c;
register int escaped = 0;
VAR* v;
-
- for(p = query; (c = *p); ++p)
- {
- switch(c)
- {
- case '$':
- if(escaped)
- {
- escaped = 0;
- dynstr_append_mem(query_eval, p, 1);
- }
- else
- {
- if(!(v = var_get(p, &p, 0)))
- die("Bad variable in eval");
- dynstr_append_mem(query_eval, v->str_val, v->str_val_len);
- }
- break;
- case '\\':
- if(escaped)
- {
- escaped = 0;
- dynstr_append_mem(query_eval, p, 1);
- }
- else
- escaped = 1;
- break;
- default:
- dynstr_append_mem(query_eval, p, 1);
- break;
- }
+
+ for (p= query; (c = *p); ++p)
+ {
+ switch(c) {
+ case '$':
+ if (escaped)
+ {
+ escaped = 0;
+ dynstr_append_mem(query_eval, p, 1);
+ }
+ else
+ {
+ if (!(v = var_get(p, &p, 0, 0)))
+ die("Bad variable in eval");
+ dynstr_append_mem(query_eval, v->str_val, v->str_val_len);
+ }
+ break;
+ case '\\':
+ if (escaped)
+ {
+ escaped = 0;
+ dynstr_append_mem(query_eval, p, 1);
+ }
+ else
+ escaped = 1;
+ break;
+ default:
+ dynstr_append_mem(query_eval, p, 1);
+ break;
}
+ }
}
+
static void close_cons()
{
DBUG_ENTER("close_cons");
+ if (last_result)
+ mysql_free_result(last_result);
for (--next_con; next_con >= cons; --next_con)
{
mysql_close(&next_con->mysql);
@@ -309,38 +408,51 @@ static void close_cons()
DBUG_VOID_RETURN;
}
+
static void close_files()
{
- do
+ DBUG_ENTER("close_files");
+ for (; cur_file != file_stack ; cur_file--)
{
if (*cur_file != stdin && *cur_file)
my_fclose(*cur_file,MYF(0));
- } while (cur_file-- != file_stack);
+ }
+ DBUG_VOID_RETURN;
}
+
static void free_used_memory()
{
uint i;
DBUG_ENTER("free_used_memory");
+#ifndef EMBEDDED_LIBRARY
+ if (manager)
+ mysql_manager_close(manager);
+#endif
close_cons();
close_files();
hash_free(&var_hash);
-
+
for (i=0 ; i < q_lines.elements ; i++)
{
struct st_query **q= dynamic_element(&q_lines, i, struct st_query**);
my_free((gptr) (*q)->query_buf,MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr) (*q),MYF(0));
}
- for(i=0; i < 10; i++)
- {
- if(var_reg[i].alloced_len)
- my_free(var_reg[i].str_val, MYF(MY_WME));
- }
+ for (i=0; i < 10; i++)
+ {
+ if (var_reg[i].alloced_len)
+ my_free(var_reg[i].str_val, MYF(MY_WME));
+ }
+ while (embedded_server_arg_count > 1)
+ my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
delete_dynamic(&q_lines);
dynstr_free(&ds_res);
+ free_replace();
+ free_replace_column();
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
free_defaults(default_argv);
+ mysql_server_end();
my_end(MY_CHECK_ERROR);
DBUG_VOID_RETURN;
}
@@ -362,6 +474,8 @@ static void die(const char* fmt, ...)
exit(1);
}
+/* Note that we will get some memory leaks when calling this! */
+
static void abort_not_supported_test()
{
DBUG_ENTER("abort_not_supported_test");
@@ -395,15 +509,6 @@ void init_parser()
memset(&var_reg,0, sizeof(var_reg));
}
-int hex_val(int c)
-{
- if (isdigit(c))
- return c - '0';
- else if ((c = tolower(c)) >= 'a' && c <= 'f')
- return c - 'a' + 10;
- else
- return -1;
-}
int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname)
{
@@ -416,13 +521,26 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname)
DYNAMIC_STRING res_ds;
DBUG_ENTER("dyn_string_cmp");
- if (!my_stat(fname, &stat_info, MYF(MY_WME)))
+ if (!test_if_hard_path(fname))
+ {
+ strxmov(eval_file, opt_basedir, fname, NullS);
+ fn_format(eval_file, eval_file,"","",4);
+ }
+ else
+ fn_format(eval_file, fname,"","",4);
+
+ if (!my_stat(eval_file, &stat_info, MYF(MY_WME)))
die(NullS);
- if (!eval_result && stat_info.st_size != ds->length)
+ if (!eval_result && (uint) stat_info.st_size != ds->length)
+ {
+ DBUG_PRINT("info",("Size differs: result size: %u file size: %u",
+ ds->length, stat_info.st_size));
DBUG_RETURN(2);
+ }
if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME))))
die(NullS);
- if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0)
+
+ if ((fd = my_open(eval_file, O_RDONLY, MYF(MY_WME))) < 0)
die(NullS);
if (my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP)))
die(NullS);
@@ -432,7 +550,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname)
{
do_eval(&res_ds, tmp);
res_ptr = res_ds.str;
- if((res_len = res_ds.length) != ds->length)
+ if ((res_len = res_ds.length) != ds->length)
{
res = 2;
goto err;
@@ -443,18 +561,18 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname)
res_ptr = tmp;
res_len = stat_info.st_size;
}
-
+
res = (memcmp(res_ptr, ds->str, res_len)) ? 1 : 0;
-
-err:
- if(res && eval_result)
- str_to_file(fn_format(eval_file, fname, "", ".eval",2), res_ptr,
- res_len);
-
+
+err:
+ if (res && eval_result)
+ str_to_file(fn_format(eval_file, fname, "", ".eval",2), res_ptr,
+ res_len);
+
my_free((gptr) tmp, MYF(0));
my_close(fd, MYF(MY_WME));
dynstr_free(&res_ds);
-
+
DBUG_RETURN(res);
}
@@ -466,8 +584,7 @@ static int check_result(DYNAMIC_STRING* ds, const char* fname,
if (res && require_option)
abort_not_supported_test();
- switch (res)
- {
+ switch (res) {
case 0:
break; /* ok */
case 2:
@@ -486,64 +603,67 @@ static int check_result(DYNAMIC_STRING* ds, const char* fname,
return error;
}
-VAR* var_get(const char* var_name, const char** var_name_end, int raw)
+VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw,
+ my_bool ignore_not_existing)
{
int digit;
VAR* v;
- if (*var_name++ != '$')
- {
- --var_name;
+ DBUG_ENTER("var_get");
+ DBUG_PRINT("enter",("var_name: %s",var_name));
+
+ if (*var_name != '$')
goto err;
- }
- digit = *var_name - '0';
+ digit = *++var_name - '0';
if (!(digit < 10 && digit >= 0))
{
const char* save_var_name = var_name, *end;
end = (var_name_end) ? *var_name_end : 0;
- while (isvar(*var_name))
- {
- if(end && var_name == end)
- break;
+ while (my_isvar(charset_info,*var_name) && var_name != end)
++var_name;
- }
- if(var_name == save_var_name)
+ if (var_name == save_var_name)
+ {
+ if (ignore_not_existing)
+ DBUG_RETURN(0);
die("Empty variable");
-
- if(!(v = (VAR*)hash_search(&var_hash, save_var_name,
+ }
+
+ if (!(v = (VAR*) hash_search(&var_hash, save_var_name,
var_name - save_var_name)))
- {
- if (end)
- *(char*)end = 0;
- die("Variable '%s' used uninitialized", save_var_name);
- }
- --var_name;
+ {
+ if (ignore_not_existing)
+ DBUG_RETURN(0);
+ if (end)
+ *(char*) end = 0;
+ die("Variable '%s' used uninitialized", save_var_name);
+ }
+ --var_name; /* Point at last character */
}
- else
- v = var_reg + digit;
-
+ else
+ v = var_reg + digit;
+
if (!raw && v->int_dirty)
{
sprintf(v->str_val, "%d", v->int_val);
v->int_dirty = 0;
v->str_val_len = strlen(v->str_val);
}
- if(var_name_end)
+ if (var_name_end)
*var_name_end = var_name ;
- return v;
+ DBUG_RETURN(v);
err:
if (var_name_end)
*var_name_end = 0;
die("Unsupported variable name: %s", var_name);
- return 0;
+ DBUG_RETURN(0);
}
static VAR* var_obtain(char* name, int len)
{
VAR* v;
- if((v = (VAR*)hash_search(&var_hash, name, len)))
+ if ((v = (VAR*)hash_search(&var_hash, name, len)))
return v;
v = var_init(0, name, len, "", 0);
- hash_insert(&var_hash, (byte*)v);
+ my_hash_insert(&var_hash, (byte*)v);
return v;
}
@@ -563,17 +683,25 @@ int var_set(char* var_name, char* var_name_end, char* var_val,
{
v = var_obtain(var_name, var_name_end - var_name);
}
- else
+ else
v = var_reg + digit;
-
+
return eval_expr(v, var_val, (const char**)&var_val_end);
}
int open_file(const char* name)
{
+ char buff[FN_REFLEN];
+ if (!test_if_hard_path(name))
+ {
+ strxmov(buff, opt_basedir, name, NullS);
+ name=buff;
+ }
+ fn_format(buff,name,"","",4);
+
if (*cur_file && cur_file == file_stack_end)
die("Source directives are nesting too deep");
- if (!(*(cur_file+1) = my_fopen(name, O_RDONLY | O_BINARY, MYF(MY_WME))))
+ if (!(*(cur_file+1) = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME))))
die(NullS);
cur_file++;
*++lineno=1;
@@ -581,19 +709,198 @@ int open_file(const char* name)
return 0;
}
+
+/* ugly long name, but we are following the convention */
+int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused)))
+{
+ MYSQL* mysql = &cur_con->mysql;
+ for (;;)
+ {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int done;
+ LINT_INIT(res);
+
+ if (mysql_query(mysql,"show status like 'Slave_running'") ||
+ !(res=mysql_store_result(mysql)))
+ die("Query failed while probing slave for stop: %s",
+ mysql_error(mysql));
+ if (!(row=mysql_fetch_row(res)) || !row[1])
+ {
+ mysql_free_result(res);
+ die("Strange result from query while probing slave for stop");
+ }
+ done = !strcmp(row[1],"OFF");
+ mysql_free_result(res);
+ if (done)
+ break;
+ my_sleep(SLAVE_POLL_INTERVAL);
+ }
+ return 0;
+}
+
+int do_require_manager(struct st_query* a __attribute__((unused)))
+{
+ if (!manager)
+ abort_not_supported_test();
+ return 0;
+}
+
+#ifndef EMBEDDED_LIBRARY
+int do_server_start(struct st_query* q)
+{
+ return do_server_op(q,"start");
+}
+
+int do_server_stop(struct st_query* q)
+{
+ return do_server_op(q,"stop");
+}
+
+int do_server_op(struct st_query* q,const char* op)
+{
+ char* p=q->first_argument;
+ char com_buf[256],*com_p;
+ if (!manager)
+ {
+ die("Manager is not initialized, manager commands are not possible");
+ }
+ com_p=strmov(com_buf,op);
+ com_p=strmov(com_p,"_exec ");
+ if (!*p)
+ die("Missing server name in server_%s\n",op);
+ while (*p && !my_isspace(charset_info,*p))
+ *com_p++= *p++;
+ *com_p++=' ';
+ com_p=int10_to_str(manager_wait_timeout,com_p,10);
+ *com_p++ = '\n';
+ *com_p=0;
+ if (mysql_manager_command(manager,com_buf,(int)(com_p-com_buf)))
+ die("Error in command: %s(%d)",manager->last_error,manager->last_errno);
+ while (!manager->eof)
+ {
+ if (mysql_manager_fetch_line(manager,com_buf,sizeof(com_buf)))
+ die("Error fetching result line: %s(%d)", manager->last_error,
+ manager->last_errno);
+ }
+
+ return 0;
+}
+#endif
+
+int do_require_version(struct st_query* q)
+{
+ MYSQL* mysql = &cur_con->mysql;
+ MYSQL_RES* res;
+ MYSQL_ROW row;
+ char* p=q->first_argument, *ver_arg;
+ uint ver_arg_len,ver_len;
+ LINT_INIT(res);
+
+ if (!*p)
+ die("Missing version argument in require_version\n");
+ ver_arg = p;
+ while (*p && !my_isspace(charset_info,*p))
+ p++;
+ *p = 0;
+ ver_arg_len = p - ver_arg;
+
+ if (mysql_query(mysql, "select version()") ||
+ !(res=mysql_store_result(mysql)))
+ die("Query failed while check server version: %s",
+ mysql_error(mysql));
+ if (!(row=mysql_fetch_row(res)) || !row[0])
+ {
+ mysql_free_result(res);
+ die("Strange result from query while checking version");
+ }
+ ver_len = strlen(row[0]);
+ if (ver_len < ver_arg_len || memcmp(row[0],ver_arg,ver_arg_len))
+ {
+ mysql_free_result(res);
+ abort_not_supported_test();
+ }
+ mysql_free_result(res);
+ return 0;
+}
+
int do_source(struct st_query* q)
{
char* p=q->first_argument, *name;
if (!*p)
die("Missing file name in source\n");
name = p;
- while (*p && !isspace(*p))
+ while (*p && !my_isspace(charset_info,*p))
p++;
*p = 0;
return open_file(name);
}
+/*
+ Execute given command.
+
+ SYNOPSIS
+ do_exec()
+ q called command
+
+ DESCRIPTION
+ If one uses --exec command [args] command in .test file
+ we will execute the command and record its output.
+
+ RETURN VALUES
+ 0 ok
+ 1 error
+*/
+
+int do_exec(struct st_query* q)
+{
+ int error= 0;
+ DYNAMIC_STRING *ds;
+ DYNAMIC_STRING ds_tmp;
+ char buf[1024];
+ FILE *res_file;
+ char *cmd= q->first_argument;
+
+ while (*cmd && my_isspace(charset_info, *cmd))
+ cmd++;
+ if (!*cmd)
+ die("Missing argument in exec\n");
+
+ if (q->record_file[0])
+ {
+ init_dynamic_string(&ds_tmp, "", 16384, 65536);
+ ds= &ds_tmp;
+ }
+ else
+ ds= &ds_res;
+
+ if (!(res_file= popen(cmd, "r")) && q->abort_on_error)
+ die("popen() failed\n");
+ while (fgets(buf, sizeof(buf), res_file))
+ replace_dynstr_append_mem(ds, buf, strlen(buf));
+ pclose(res_file);
+
+ if (glob_replace)
+ free_replace();
+
+ if (record)
+ {
+ if (!q->record_file[0] && !result_file)
+ die("At line %u: Missing result file", start_lineno);
+ if (!result_file)
+ str_to_file(q->record_file, ds->str, ds->length);
+ }
+ else if (q->record_file[0])
+ {
+ error= check_result(ds, q->record_file, q->require_file);
+ }
+ if (ds == &ds_tmp)
+ dynstr_free(&ds_tmp);
+
+ return error;
+}
+
int var_query_set(VAR* v, const char* p, const char** p_end)
{
char* end = (char*)((p_end && *p_end) ? *p_end : p + strlen(p));
@@ -601,7 +908,7 @@ int var_query_set(VAR* v, const char* p, const char** p_end)
MYSQL_ROW row;
MYSQL* mysql = &cur_con->mysql;
LINT_INIT(res);
-
+
while (end > p && *end != '`')
--end;
if (p == end)
@@ -616,7 +923,28 @@ int var_query_set(VAR* v, const char* p, const char** p_end)
}
if ((row = mysql_fetch_row(res)) && row[0])
- eval_expr(v, row[0], 0);
+ {
+ /*
+ Concatenate all row results with tab in between to allow us to work
+ with results from many columns (for example from SHOW VARIABLES)
+ */
+ DYNAMIC_STRING result;
+ uint i;
+ ulong *lengths;
+ char *end;
+
+ init_dynamic_string(&result, "", 16384, 65536);
+ lengths= mysql_fetch_lengths(res);
+ for (i=0; i < mysql_num_fields(res); i++)
+ {
+ if (row[0])
+ dynstr_append_mem(&result, row[i], lengths[i]);
+ dynstr_append_mem(&result, "\t", 1);
+ }
+ end= result.str + result.length-1;
+ eval_expr(v, result.str, (const char**) &end);
+ dynstr_free(&result);
+ }
else
eval_expr(v, "", 0);
@@ -624,18 +952,30 @@ int var_query_set(VAR* v, const char* p, const char** p_end)
return 0;
}
+void var_copy(VAR* dest, VAR* src)
+{
+ dest->int_val=src->int_val;
+ dest->int_dirty=src->int_dirty;
+ if (dest->alloced_len < src->alloced_len &&
+ !(dest->str_val=my_realloc(dest->str_val,src->alloced_len+1,
+ MYF(MY_WME))))
+ die("Out of memory");
+ dest->str_val_len=src->str_val_len;
+ memcpy(dest->str_val,src->str_val,src->str_val_len+1);
+}
+
int eval_expr(VAR* v, const char* p, const char** p_end)
{
VAR* vp;
if (*p == '$')
+ {
+ if ((vp = var_get(p,p_end,0,0)))
{
- if ((vp = var_get(p,p_end,0)))
- {
- memcpy(v, vp, sizeof(*v));
- return 0;
- }
+ var_copy(v, vp);
+ return 0;
}
- else if(*p == '`')
+ }
+ else if (*p == '`')
{
return var_query_set(v, p, p_end);
}
@@ -645,12 +985,12 @@ int eval_expr(VAR* v, const char* p, const char** p_end)
(int) (*p_end - p) : (int) strlen(p);
if (new_val_len + 1 >= v->alloced_len)
{
- v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
+ v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
MIN_VAR_ALLOC : new_val_len + 1;
if (!(v->str_val =
- v->str_val ? my_realloc(v->str_val, v->alloced_len,
+ v->str_val ? my_realloc(v->str_val, v->alloced_len+1,
MYF(MY_WME)) :
- my_malloc(v->alloced_len, MYF(MY_WME))))
+ my_malloc(v->alloced_len+1, MYF(MY_WME))))
die("Out of memory");
}
v->str_val_len = new_val_len;
@@ -661,8 +1001,6 @@ int eval_expr(VAR* v, const char* p, const char** p_end)
return 0;
}
- if (p_end)
- *p_end = 0;
die("Invalid expr: %s", p);
return 1;
}
@@ -671,7 +1009,7 @@ int do_inc(struct st_query* q)
{
char* p=q->first_argument;
VAR* v;
- v = var_get(p, 0, 1);
+ v = var_get(p, 0, 1, 0);
v->int_val++;
v->int_dirty = 1;
return 0;
@@ -681,7 +1019,7 @@ int do_dec(struct st_query* q)
{
char* p=q->first_argument;
VAR* v;
- v = var_get(p, 0, 1);
+ v = var_get(p, 0, 1, 0);
v->int_val--;
v->int_dirty = 1;
return 0;
@@ -694,16 +1032,17 @@ int do_system(struct st_query* q)
var_init(&v, 0, 0, 0, 0);
eval_expr(&v, p, 0); /* NULL terminated */
if (v.str_val_len)
- {
- char expr_buf[512];
- if ((uint)v.str_val_len > sizeof(expr_buf) - 1)
- v.str_val_len = sizeof(expr_buf) - 1;
- memcpy(expr_buf, v.str_val, v.str_val_len);
- expr_buf[v.str_val_len] = 0;
- DBUG_PRINT("info", ("running system command '%s'", expr_buf));
- if (system(expr_buf) && q->abort_on_error)
- die("system command '%s' failed", expr_buf);
- }
+ {
+ char expr_buf[512];
+ if ((uint)v.str_val_len > sizeof(expr_buf) - 1)
+ v.str_val_len = sizeof(expr_buf) - 1;
+ memcpy(expr_buf, v.str_val, v.str_val_len);
+ expr_buf[v.str_val_len] = 0;
+ DBUG_PRINT("info", ("running system command '%s'", expr_buf));
+ if (system(expr_buf) && q->abort_on_error)
+ die("system command '%s' failed", expr_buf);
+ }
+ var_free(&v);
return 0;
}
@@ -719,70 +1058,84 @@ int do_echo(struct st_query* q)
write(1, v.str_val, v.str_val_len);
}
write(1, "\n", 1);
+ var_free(&v);
return 0;
}
-int do_sync_with_master(struct st_query* q)
+
+int do_sync_with_master2(const char* p)
{
MYSQL_RES* res;
MYSQL_ROW row;
MYSQL* mysql = &cur_con->mysql;
char query_buf[FN_REFLEN+128];
int offset = 0;
- char* p = q->first_argument;
int rpl_parse;
+ if (!master_pos.file[0])
+ {
+ die("Line %u: Calling 'sync_with_master' without calling 'save_master_pos'", start_lineno);
+ }
rpl_parse = mysql_rpl_parse_enabled(mysql);
mysql_disable_rpl_parse(mysql);
-
- if(*p)
+
+ if (*p)
offset = atoi(p);
-
+
sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file,
master_pos.pos + offset);
- if(mysql_query(mysql, query_buf))
- die("At line %u: failed in %s: %d: %s", start_lineno, query_buf,
+ if (mysql_query(mysql, query_buf))
+ die("line %u: failed in %s: %d: %s", start_lineno, query_buf,
mysql_errno(mysql), mysql_error(mysql));
- if(!(res = mysql_store_result(mysql)))
- die("line %u: mysql_store_result() retuned NULL", start_lineno);
- if(!(row = mysql_fetch_row(res)))
+ if (!(last_result = res = mysql_store_result(mysql)))
+ die("line %u: mysql_store_result() returned NULL for '%s'", start_lineno,
+ query_buf);
+ if (!(row = mysql_fetch_row(res)))
die("line %u: empty result in %s", start_lineno, query_buf);
- if(!row[0])
- die("Error on slave while syncing with master");
+ if (!row[0])
+ die("line %u: could not sync with master ('%s' returned NULL)",
+ start_lineno, query_buf);
mysql_free_result(res);
-
- if(rpl_parse)
+ last_result=0;
+ if (rpl_parse)
mysql_enable_rpl_parse(mysql);
-
+
return 0;
}
+int do_sync_with_master(struct st_query* q)
+{
+ return do_sync_with_master2(q->first_argument);
+}
+
int do_save_master_pos()
{
MYSQL_RES* res;
MYSQL_ROW row;
MYSQL* mysql = &cur_con->mysql;
+ const char *query;
int rpl_parse;
rpl_parse = mysql_rpl_parse_enabled(mysql);
mysql_disable_rpl_parse(mysql);
-
- if(mysql_query(mysql, "show master status"))
+
+ if (mysql_query(mysql, query= "show master status"))
die("At line %u: failed in show master status: %d: %s", start_lineno,
mysql_errno(mysql), mysql_error(mysql));
- if(!(res = mysql_store_result(mysql)))
- die("line %u: mysql_store_result() retuned NULL", start_lineno);
- if(!(row = mysql_fetch_row(res)))
+ if (!(last_result =res = mysql_store_result(mysql)))
+ die("line %u: mysql_store_result() retuned NULL for '%s'", start_lineno,
+ query);
+ if (!(row = mysql_fetch_row(res)))
die("line %u: empty result in show master status", start_lineno);
- strncpy(master_pos.file, row[0], sizeof(master_pos.file));
- master_pos.pos = strtoul(row[1], (char**) 0, 10);
- mysql_free_result(res);
-
- if(rpl_parse)
+ strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
+ master_pos.pos = strtoul(row[1], (char**) 0, 10);
+ mysql_free_result(res); last_result=0;
+
+ if (rpl_parse)
mysql_enable_rpl_parse(mysql);
-
+
return 0;
}
@@ -794,86 +1147,49 @@ int do_let(struct st_query* q)
if (!*p)
die("Missing variable name in let\n");
var_name = p;
- while(*p && (*p != '=' || isspace(*p)))
+ while (*p && (*p != '=' || my_isspace(charset_info,*p)))
p++;
var_name_end = p;
if (*p == '=') p++;
- while(*p && isspace(*p))
+ while (*p && my_isspace(charset_info,*p))
p++;
var_val_start = p;
return var_set(var_name, var_name_end, var_val_start, q->end);
}
-int do_rpl_probe(struct st_query* __attribute__((unused)) q)
+int do_rpl_probe(struct st_query* q __attribute__((unused)))
{
- if(mysql_rpl_probe(&cur_con->mysql))
- die("Failed in mysql_rpl_probe(): %s", mysql_error(&cur_con->mysql));
- return 0;
+ DBUG_ENTER("do_rpl_probe");
+ if (mysql_rpl_probe(&cur_con->mysql))
+ die("Failed in mysql_rpl_probe(): '%s'", mysql_error(&cur_con->mysql));
+ DBUG_RETURN(0);
}
-int do_enable_rpl_parse(struct st_query* __attribute__((unused)) q)
+int do_enable_rpl_parse(struct st_query* q __attribute__((unused)))
{
mysql_enable_rpl_parse(&cur_con->mysql);
return 0;
}
-int do_disable_rpl_parse(struct st_query* __attribute__((unused)) q)
+int do_disable_rpl_parse(struct st_query* q __attribute__((unused)))
{
mysql_disable_rpl_parse(&cur_con->mysql);
return 0;
}
-int do_sleep(struct st_query* q)
+int do_sleep(struct st_query* q, my_bool real_sleep)
{
- char* p=q->first_argument;
- struct timeval t;
- int dec_mul = 1000000;
- while(*p && isspace(*p)) p++;
+ char *p=q->first_argument;
+ while (*p && my_isspace(charset_info,*p))
+ p++;
if (!*p)
die("Missing argument in sleep\n");
- t.tv_usec = 0;
-
-#ifdef OS2
-
- if (opt_sleep)
- DosSleep( opt_sleep * 1000);
+ if (opt_sleep && !real_sleep)
+ my_sleep(opt_sleep * 1000000L);
else
- DosSleep( atof( p) * 1000);
-
+ my_sleep((ulong) (atof(p) * 1000000L));
return 0;
-
-#else
- if (opt_sleep)
- t.tv_sec = opt_sleep;
- else
- {
- t.tv_sec = atoi(p);
- while(*p && *p != '.' && !isspace(*p))
- p++;
- if (*p == '.')
- {
- int c;
- char *p_end;
- p++;
- p_end = p + 6;
-
- for(;p <= p_end; ++p)
- {
- c = (int) (*p - '0');
- if (c < 10 && (int) c >= 0)
- {
- t.tv_usec = t.tv_usec * 10 + c;
- dec_mul /= 10;
- }
- else
- break;
- }
- }
- }
- t.tv_usec *= dec_mul;
- return select(0,0,0,0, &t);
-#endif
}
static void get_file_name(char *filename, struct st_query* q)
@@ -881,16 +1197,17 @@ static void get_file_name(char *filename, struct st_query* q)
char* p=q->first_argument;
strnmov(filename, p, FN_REFLEN);
/* Remove end space */
- while (p > filename && isspace(p[-1]))
+ while (p > filename && my_isspace(charset_info,p[-1]))
p--;
p[0]=0;
}
-static void get_ints(uint *to,struct st_query* q)
+static uint get_ints(uint *to,struct st_query* q)
{
char* p=q->first_argument;
long val;
+ uint count=0;
DBUG_ENTER("get_ints");
if (!*p)
@@ -898,25 +1215,28 @@ static void get_ints(uint *to,struct st_query* q)
for (; (p=str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val)) ; p++)
{
+ count++;
*to++= (uint) val;
if (*p != ',')
break;
}
*to++=0; /* End of data */
- DBUG_VOID_RETURN;
+ DBUG_RETURN(count);
}
/*
Get a string; Return ptr to end of string
Strings may be surrounded by " or '
+
+ If string is a '$variable', return the value of the variable.
*/
-static void get_string(char **to_ptr, char **from_ptr,
- struct st_query* q)
+static char *get_string(char **to_ptr, char **from_ptr,
+ struct st_query* q)
{
reg1 char c,sep;
- char *to= *to_ptr, *from= *from_ptr;
+ char *to= *to_ptr, *from= *from_ptr, *start=to;
DBUG_ENTER("get_string");
/* Find separator */
@@ -963,12 +1283,25 @@ static void get_string(char **to_ptr, char **from_ptr,
if (*from != ' ' && *from)
die("Wrong string argument in %s\n", q->query);
- while (isspace(*from)) /* Point to next string */
+ while (my_isspace(charset_info,*from)) /* Point to next string */
from++;
- *to++ =0; /* End of string marker */
- *to_ptr= to;
+ *to =0; /* End of string marker */
+ *to_ptr= to+1; /* Store pointer to end */
*from_ptr= from;
+
+ /* Check if this was a variable */
+ if (*start == '$')
+ {
+ const char *end= to;
+ VAR *var=var_get(start, &end, 0, 1);
+ if (var && to == (char*) end+1)
+ {
+ DBUG_PRINT("info",("var: '%s' -> '%s'", start, var->str_val));
+ DBUG_RETURN(var->str_val); /* return found variable value */
+ }
+ }
+ DBUG_RETURN(start);
}
@@ -976,6 +1309,8 @@ static void get_string(char **to_ptr, char **from_ptr,
Get arguments for replace. The syntax is:
replace from to [from to ...]
Where each argument may be quoted with ' or "
+ A argument may also be a variable, in which case the value of the
+ variable is replaced.
*/
static void get_replace(struct st_query *q)
@@ -987,6 +1322,8 @@ static void get_replace(struct st_query *q)
POINTER_ARRAY to_array,from_array;
DBUG_ENTER("get_replace");
+ free_replace();
+
bzero((char*) &to_array,sizeof(to_array));
bzero((char*) &from_array,sizeof(from_array));
if (!*from)
@@ -995,17 +1332,16 @@ static void get_replace(struct st_query *q)
while (*from)
{
char *to=buff;
- get_string(&buff, &from, q);
+ to=get_string(&buff, &from, q);
if (!*from)
die("Wrong number of arguments to replace in %s\n", q->query);
insert_pointer_name(&from_array,to);
- to=buff;
- get_string(&buff, &from, q);
+ to=get_string(&buff, &from, q);
insert_pointer_name(&to_array,to);
}
for (i=1,pos=word_end_chars ; i < 256 ; i++)
- if (isspace(i))
- *pos++=i;
+ if (my_isspace(charset_info,i))
+ *pos++= i;
*pos=0; /* End pointer */
if (!(glob_replace=init_replace((char**) from_array.typelib.type_names,
(char**) to_array.typelib.type_names,
@@ -1016,21 +1352,24 @@ static void get_replace(struct st_query *q)
free_pointer_array(&from_array);
free_pointer_array(&to_array);
my_free(start, MYF(0));
+ DBUG_VOID_RETURN;
}
void free_replace()
{
DBUG_ENTER("free_replace");
- my_free((char*) glob_replace,MYF(0));
- glob_replace=0;
- free_replace_buffer();
+ if (glob_replace)
+ {
+ my_free((char*) glob_replace,MYF(0));
+ glob_replace=0;
+ free_replace_buffer();
+ }
DBUG_VOID_RETURN;
}
-
-int select_connection(struct st_query* q)
+int select_connection(char *p)
{
- char* p=q->first_argument, *name;
+ char* name;
struct connection *con;
DBUG_ENTER("select_connection");
DBUG_PRINT("enter",("name: '%s'",p));
@@ -1038,7 +1377,7 @@ int select_connection(struct st_query* q)
if (!*p)
die("Missing connection name in connect\n");
name = p;
- while(*p && !isspace(*p))
+ while (*p && !my_isspace(charset_info,*p))
p++;
*p = 0;
@@ -1064,23 +1403,24 @@ int close_connection(struct st_query* q)
if (!*p)
die("Missing connection name in connect\n");
name = p;
- while(*p && !isspace(*p))
+ while (*p && !my_isspace(charset_info,*p))
p++;
*p = 0;
- for(con = cons; con < next_con; con++)
+ for (con = cons; con < next_con; con++)
{
if (!strcmp(con->name, name))
{
- if(q->type == Q_DIRTY_CLOSE)
+#ifndef EMBEDDED_LIBRARY
+ if (q->type == Q_DIRTY_CLOSE)
+ {
+ if (con->mysql.net.vio)
{
- if(con->mysql.net.vio)
- {
- vio_delete(con->mysql.net.vio);
- con->mysql.net.vio = 0;
- }
+ vio_delete(con->mysql.net.vio);
+ con->mysql.net.vio = 0;
}
-
+ }
+#endif
mysql_close(&con->mysql);
DBUG_RETURN(0);
}
@@ -1090,7 +1430,8 @@ int close_connection(struct st_query* q)
}
-/* this one now is a hack - we may want to improve in in the
+/*
+ This one now is a hack - we may want to improve in in the
future to handle quotes. For now we assume that anything that is not
a comma, a space or ) belongs to the argument. space is a chopper, comma or
) are delimiters/terminators
@@ -1099,11 +1440,13 @@ int close_connection(struct st_query* q)
char* safe_get_param(char* str, char** arg, const char* msg)
{
DBUG_ENTER("safe_get_param");
- while (*str && isspace(*str)) str++;
+ while (*str && my_isspace(charset_info,*str))
+ str++;
*arg = str;
for (; *str && *str != ',' && *str != ')' ; str++)
{
- if (isspace(*str)) *str = 0;
+ if (my_isspace(charset_info,*str))
+ *str = 0;
}
if (!*str)
die(msg);
@@ -1112,6 +1455,37 @@ char* safe_get_param(char* str, char** arg, const char* msg)
DBUG_RETURN(str);
}
+#ifndef EMBEDDED_LIBRARY
+void init_manager()
+{
+ if (!(manager=mysql_manager_init(0)))
+ die("Failed in mysql_manager_init()");
+ if (!mysql_manager_connect(manager,manager_host,manager_user,
+ manager_pass,manager_port))
+ die("Could not connect to MySQL manager: %s(%d)",manager->last_error,
+ manager->last_errno);
+
+}
+#endif
+
+int safe_connect(MYSQL* con, const char* host, const char* user,
+ const char* pass,
+ const char* db, int port, const char* sock)
+{
+ int con_error = 1;
+ int i;
+ for (i = 0; i < MAX_CON_TRIES; ++i)
+ {
+ if (mysql_real_connect(con, host,user, pass, db, port, sock, 0))
+ {
+ con_error = 0;
+ break;
+ }
+ sleep(CON_RETRY_SLEEP);
+ }
+ return con_error;
+}
+
int do_connect(struct st_query* q)
{
@@ -1120,8 +1494,8 @@ int do_connect(struct st_query* q)
char* p=q->first_argument;
char buff[FN_REFLEN];
int con_port;
- int i, con_error;
-
+ int free_con_sock = 0;
+
DBUG_ENTER("do_connect");
DBUG_PRINT("enter",("connect: %s",p));
@@ -1140,43 +1514,65 @@ int do_connect(struct st_query* q)
}
else
{
+ VAR* var_port, *var_sock;
p = safe_get_param(p, &con_port_str, "missing connection port");
- con_port=atoi(con_port_str);
+ if (*con_port_str == '$')
+ {
+ if (!(var_port = var_get(con_port_str, 0, 0, 0)))
+ die("Unknown variable '%s'", con_port_str+1);
+ con_port = var_port->int_val;
+ }
+ else
+ con_port=atoi(con_port_str);
p = safe_get_param(p, &con_sock, "missing connection socket");
+ if (*con_sock == '$')
+ {
+ if (!(var_sock = var_get(con_sock, 0, 0, 0)))
+ die("Unknown variable '%s'", con_sock+1);
+ if (!(con_sock = (char*)my_malloc(var_sock->str_val_len+1, MYF(0))))
+ die("Out of memory");
+ free_con_sock = 1;
+ memcpy(con_sock, var_sock->str_val, var_sock->str_val_len);
+ con_sock[var_sock->str_val_len] = 0;
+ }
}
+
if (next_con == cons_end)
die("Connection limit exhausted - increase MAX_CONS in mysqltest.c");
if (!mysql_init(&next_con->mysql))
die("Failed on mysql_init()");
- if (con_sock)
+ if (opt_compress)
+ mysql_options(&next_con->mysql,MYSQL_OPT_COMPRESS,NullS);
+ mysql_options(&next_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
+
+#ifdef HAVE_OPENSSL
+ if (opt_use_ssl)
+ mysql_ssl_set(&next_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+ opt_ssl_capath, opt_ssl_cipher);
+#endif
+ if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR)
con_sock=fn_format(buff, con_sock, TMPDIR, "",0);
if (!con_db[0])
con_db=db;
- con_error = 1;
- for (i = 0; i < MAX_CON_TRIES; ++i)
- {
- if(mysql_real_connect(&next_con->mysql, con_host,
- con_user, con_pass,
- con_db, con_port, con_sock, 0))
- {
- con_error = 0;
- break;
- }
- sleep(CON_RETRY_SLEEP);
- }
-
- if(con_error)
+ /* Special database to allow one to connect without a database name */
+ if (con_db && !strcmp(con_db,"*NO-ONE*"))
+ con_db=0;
+ if ((safe_connect(&next_con->mysql, con_host,
+ con_user, con_pass,
+ con_db, con_port, con_sock ? con_sock: 0)))
die("Could not open connection '%s': %s", con_name,
mysql_error(&next_con->mysql));
if (!(next_con->name = my_strdup(con_name, MYF(MY_WME))))
die(NullS);
cur_con = next_con++;
-
+ if (free_con_sock)
+ my_free(con_sock, MYF(MY_WME));
DBUG_RETURN(0);
}
+
int do_done(struct st_query* q)
{
q->type = Q_END_BLOCK;
@@ -1187,10 +1583,10 @@ int do_done(struct st_query* q)
parser.current_line = *--cur_block;
}
else
- {
- ++parser.current_line;
- --cur_block;
- }
+ {
+ ++parser.current_line;
+ --cur_block;
+ }
return 0;
}
@@ -1199,89 +1595,37 @@ int do_while(struct st_query* q)
char* p=q->first_argument;
const char* expr_start, *expr_end;
VAR v;
- var_init(&v,0,0,0,0);
if (cur_block == block_stack_end)
- die("Nesting too deeply");
+ die("Nesting too deeply");
if (!*block_ok)
- {
- ++false_block_depth;
- *++block_ok = 0;
- *cur_block++ = parser.current_line++;
- return 0;
- }
-
+ {
+ ++false_block_depth;
+ *++block_ok = 0;
+ *cur_block++ = parser.current_line++;
+ return 0;
+ }
+
expr_start = strchr(p, '(');
if (!expr_start)
die("missing '(' in while");
expr_end = strrchr(expr_start, ')');
if (!expr_end)
die("missing ')' in while");
+ var_init(&v,0,0,0,0);
eval_expr(&v, ++expr_start, &expr_end);
*cur_block++ = parser.current_line++;
if (!v.int_val)
- {
- *++block_ok = 0;
- false_block_depth++;
- }
+ {
+ *++block_ok = 0;
+ false_block_depth++;
+ }
else
*++block_ok = 1;
+ var_free(&v);
return 0;
}
-int safe_copy_unescape(char* dest, char* src, int size)
-{
- register char* p_dest = dest, *p_src = src;
- register int c, val;
- enum { ST_NORMAL, ST_ESCAPED, ST_HEX2} state = ST_NORMAL ;
-
- size--; /* just to make life easier */
-
- for(; p_dest - size < dest && p_src - size < src
- && (c = *p_src) != '\n' && c; ++p_src )
- {
- switch(state)
- {
- case ST_NORMAL:
- if (c == '\\')
- {
- state = ST_ESCAPED;
- }
- else
- *p_dest++ = c;
- break;
- case ST_ESCAPED:
- if ((val = hex_val(c)) > 0)
- {
- *p_dest = val;
- state = ST_HEX2;
- }
- else
- {
- state = ST_NORMAL;
- *p_dest++ = c;
- }
- break;
- case ST_HEX2:
- if ((val = hex_val(c)) > 0)
- {
- *p_dest = (*p_dest << 4) + val;
- p_dest++;
- }
- else
- *p_dest++ = c;
-
- state = ST_NORMAL;
- break;
-
- }
- }
-
- *p_dest = 0;
- return (p_dest - dest);
-}
-
-
int read_line(char* buf, int size)
{
int c;
@@ -1300,15 +1644,11 @@ int read_line(char* buf, int size)
{
if ((*cur_file) != stdin)
my_fclose(*cur_file,MYF(0));
-
+ cur_file--;
+ lineno--;
if (cur_file == file_stack)
return 1;
- else
- {
- cur_file--;
- lineno--;
- continue;
- }
+ continue;
}
switch(state) {
@@ -1342,7 +1682,7 @@ int read_line(char* buf, int size)
{
state = R_COMMENT;
}
- else if (isspace(c))
+ else if (my_isspace(charset_info,c))
{
if (c == '\n')
start_lineno= ++*lineno; /* Query hasn't started yet */
@@ -1439,8 +1779,11 @@ int read_query(struct st_query** q_ptr)
q->first_word_len = 0;
memcpy((gptr) q->expected_errno, (gptr) global_expected_errno,
sizeof(global_expected_errno));
+ q->expected_errors=global_expected_errors;
q->abort_on_error = global_expected_errno[0] == 0;
bzero((gptr) global_expected_errno,sizeof(global_expected_errno));
+ global_expected_errors=0;
+
q->type = Q_UNKNOWN;
q->query_buf=q->query=0;
if (read_line(read_query_buf, sizeof(read_query_buf)))
@@ -1465,32 +1808,36 @@ int read_query(struct st_query** q_ptr)
{
expected_errno = 0;
p++;
- for (;isdigit(*p);p++)
+ for (;my_isdigit(charset_info,*p);p++)
expected_errno = expected_errno * 10 + *p - '0';
q->expected_errno[0] = expected_errno;
q->expected_errno[1] = 0;
+ q->expected_errors=1;
}
}
- while(*p && isspace(*p)) p++ ;
+ while (*p && my_isspace(charset_info,*p))
+ p++ ;
if (*p == '@')
{
p++;
p1 = q->record_file;
- while (!isspace(*p) &&
+ while (!my_isspace(charset_info,*p) &&
p1 < q->record_file + sizeof(q->record_file) - 1)
*p1++ = *p++;
*p1 = 0;
}
}
- while (*p && isspace(*p)) p++;
+ while (*p && my_isspace(charset_info,*p))
+ p++;
if (!(q->query_buf=q->query=my_strdup(p,MYF(MY_WME))))
die(NullS);
/* Calculate first word and first argument */
- for (p=q->query; *p && !isspace(*p) ; p++) ;
+ for (p=q->query; *p && !my_isspace(charset_info,*p) ; p++) ;
q->first_word_len = (uint) (p - q->query);
- while (*p && isspace(*p)) p++;
+ while (*p && my_isspace(charset_info,*p))
+ p++;
q->first_argument=p;
q->end = strend(q->query);
parser.read_lines++;
@@ -1498,30 +1845,77 @@ int read_query(struct st_query** q_ptr)
}
-struct option long_options[] =
-{
- {"debug", optional_argument, 0, '#'},
- {"database", required_argument, 0, 'D'},
- {"big-test", no_argument, 0, 'B'},
- {"help", no_argument, 0, '?'},
- {"host", required_argument, 0, 'h'},
- {"password", optional_argument, 0, 'p'},
- {"port", required_argument, 0, 'P'},
- {"quiet", no_argument, 0, 'q'},
- {"record", no_argument, 0, 'r'},
- {"result-file", required_argument, 0, 'R'},
- {"silent", no_argument, 0, 'q'},
- {"sleep", required_argument, 0, 'T'},
- {"socket", required_argument, 0, 'S'},
- {"test-file", required_argument, 0, 'x'},
- {"tmpdir", required_argument, 0, 't'},
- {"user", required_argument, 0, 'u'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+static struct my_option my_long_options[] =
+{
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"database", 'D', "Database to use.", (gptr*) &db, (gptr*) &db, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"basedir", 'b', "Basedir for tests.", (gptr*) &opt_basedir,
+ (gptr*) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"big-test", 'B', "Define BIG_TEST to 1.", (gptr*) &opt_big_test,
+ (gptr*) &opt_big_test, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"compress", 'C', "Use the compressed server/client protocol.",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"manager-user", OPT_MANAGER_USER, "Undocumented: Used for debugging.",
+ (gptr*) &manager_user, (gptr*) &manager_user, 0, GET_STR, REQUIRED_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"manager-host", OPT_MANAGER_HOST, "Undocumented: Used for debugging.",
+ (gptr*) &manager_host, (gptr*) &manager_host, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"manager-password", OPT_MANAGER_PASSWD, "Undocumented: Used for debugging.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"manager-port", OPT_MANAGER_PORT, "Undocumented: Used for debugging.",
+ (gptr*) &manager_port, (gptr*) &manager_port, 0, GET_INT, REQUIRED_ARG,
+ MYSQL_MANAGER_PORT, 0, 0, 0, 0, 0},
+ {"manager-wait-timeout", OPT_MANAGER_WAIT_TIMEOUT,
+ "Undocumented: Used for debugging.", (gptr*) &manager_wait_timeout,
+ (gptr*) &manager_wait_timeout, 0, GET_INT, REQUIRED_ARG, 3, 0, 0, 0, 0, 0},
+ {"password", 'p', "Password to use when connecting to server.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &port,
+ (gptr*) &port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"quiet", 's', "Suppress all normal output.", (gptr*) &silent,
+ (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"record", 'r', "Record output of test_file into result file.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"result-file", 'R', "Read/Store result from/in this file.",
+ (gptr*) &result_file, (gptr*) &result_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"server-arg", 'A', "Send enbedded server this as a paramenter.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"server-file", 'F', "Read embedded server arguments from file.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Suppress all normal output. Synonym for --quiet.",
+ (gptr*) &silent, (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
+ "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"sleep", 'T', "Sleep always this many seconds on sleep commands.",
+ (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &unix_sock, (gptr*) &unix_sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+#include "sslopt-longopts.h"
+ {"test-file", 'x', "Read test from/in this file (default stdin).",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"tmpdir", 't', "Temporary directory where sockets are put.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "User for login.", (gptr*) &user, (gptr*) &user, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Write more.", (gptr*) &verbose, (gptr*) &verbose, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION,
@@ -1531,115 +1925,103 @@ static void print_version(void)
void usage()
{
print_version();
- printf("MySQL AB, by Sasha, Matt & Monty\n");
+ printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
printf("Runs a test against the mysql server and compares output with a results file.\n\n");
printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname);
- printf("\n\
- -?, --help Display this help and exit.\n");
+ my_print_help(my_long_options);
+ printf(" --no-defaults Don't read default options from any options file.\n");
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case '#':
#ifndef DBUG_OFF
- puts("\
- -#, --debug=[...] Output debug log. Often this is 'd:t:o,filename`");
+ DBUG_PUSH(argument ? argument : "d:t:S:i:O,/tmp/mysqltest.trace");
+#endif
+ break;
+ case 'r':
+ record = 1;
+ break;
+ case (int)OPT_MANAGER_PASSWD:
+ my_free(manager_pass,MYF(MY_ALLOW_ZERO_PTR));
+ manager_pass=my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ break;
+ case 'x':
+ {
+ char buff[FN_REFLEN];
+ if (!test_if_hard_path(argument))
+ {
+ strxmov(buff, opt_basedir, argument, NullS);
+ argument= buff;
+ }
+ fn_format(buff, argument, "", "", 4);
+ if (!(*++cur_file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME))))
+ die("Could not open %s: errno = %d", argument, errno);
+ break;
+ }
+ case 'p':
+ if (argument)
+ {
+ my_free(pass, MYF(MY_ALLOW_ZERO_PTR));
+ pass= my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ }
+ else
+ tty_password= 1;
+ break;
+#include <sslopt-case.h>
+ case 't':
+ strnmov(TMPDIR, argument, sizeof(TMPDIR));
+ break;
+ case 'A':
+ if (!embedded_server_arg_count)
+ {
+ embedded_server_arg_count=1;
+ embedded_server_args[0]= (char*) "";
+ }
+ embedded_server_args[embedded_server_arg_count++]=
+ my_strdup(argument, MYF(MY_FAE));
+ if (embedded_server_arg_count == MAX_SERVER_ARGS ||
+ !embedded_server_args[embedded_server_arg_count-1])
+ {
+ die("Can't use server argument");
+ }
+ break;
+ case 'F':
+ if (read_server_arguments(argument))
+ die(NullS);
+ break;
+ case OPT_SKIP_SAFEMALLOC:
+#ifdef SAFEMALLOC
+ sf_malloc_quick=1;
#endif
- printf("\
- -h, --host=... Connect to host.\n\
- -u, --user=... User for login.\n\
- -p[password], --password[=...]\n\
- Password to use when connecting to server.\n\
- -B, --big-test Define BIG_TEST to 1\n\
- -D, --database=... Database to use.\n\
- -P, --port=... Port number to use for connection.\n\
- -S, --socket=... Socket file to use for connection.\n\
- -t, --tmpdir=... Temporary directory where sockets are put\n\
- -T, --sleep=# Sleep always this many seconds on sleep commands\n\
- -r, --record Record output of test_file into result file.\n\
- -R, --result-file=... Read/Store result from/in this file.\n\
- -x, --test-file=... Read test from/in this file (default stdin).\n\
- -v, --verbose Write more.\n\
- -q, --quiet, --silent Suppress all normal output.\n\
- -V, --version Output version information and exit.\n\
- --no-defaults Don't read default options from any options file.\n\n");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(1);
+ }
+ return 0;
}
+
int parse_args(int argc, char **argv)
{
- int c, option_index = 0;
- my_bool tty_password=0;
-
load_defaults("my",load_default_groups,&argc,&argv);
default_argv= argv;
- while((c = getopt_long(argc, argv, "h:p::u:BP:D:S:R:x:t:T:#:?rvVq",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:O,/tmp/mysqltest.trace");
- break;
- case 'v':
- verbose = 1;
- break;
- case 'r':
- record = 1;
- break;
- case 'u':
- user = optarg;
- break;
- case 'R':
- result_file = optarg;
- break;
- case 'x':
- if (!(*cur_file = my_fopen(optarg, O_RDONLY | O_BINARY, MYF(MY_WME))))
- die("Could not open %s: errno = %d", optarg, errno);
- break;
- case 'p':
- if (optarg)
- {
- my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
- pass=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- }
- else
- tty_password=1;
- break;
- case 'B':
- opt_big_test=1;
- break;
- case 'P':
- port = atoi(optarg);
- break;
- case 'S':
- unix_sock = optarg;
- break;
- case 'D':
- db = optarg;
- break;
- case 'h':
- host = optarg;
- break;
- case 'q':
- silent = 1;
- break;
- case 't':
- strnmov(TMPDIR,optarg,sizeof(TMPDIR));
- break;
- case 'T':
- opt_sleep=atoi(optarg);
- break;
- case 'V':
- print_version();
- exit(0);
- case '?':
- usage();
- exit(1); /* Unknown option */
- default:
- usage();
- exit(1);
- }
- }
+ if ((handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(1);
- argc-=optind;
- argv+=optind;
if (argc > 1)
{
usage();
@@ -1656,7 +2038,7 @@ int parse_args(int argc, char **argv)
char* safe_str_append(char* buf, const char* str, int size)
{
int i,c ;
- for(i = 0; (c = *str++) && i < size - 1; i++)
+ for (i = 0; (c = *str++) && i < size - 1; i++)
*buf++ = c;
*buf = 0;
return buf;
@@ -1665,9 +2047,17 @@ char* safe_str_append(char* buf, const char* str, int size)
void str_to_file(const char* fname, char* str, int size)
{
int fd;
- if ((fd = my_open(fname, O_WRONLY | O_CREAT | O_TRUNC,
+ char buff[FN_REFLEN];
+ if (!test_if_hard_path(fname))
+ {
+ strxmov(buff, opt_basedir, fname, NullS);
+ fname=buff;
+ }
+ fn_format(buff,fname,"","",4);
+
+ if ((fd = my_open(buff, O_WRONLY | O_CREAT | O_TRUNC,
MYF(MY_WME | MY_FFNF))) < 0)
- die("Could not open %s: errno = %d", fname, errno);
+ die("Could not open %s: errno = %d", buff, errno);
if (my_write(fd, (byte*)str, size, MYF(MY_WME|MY_FNABP)))
die("write failed");
my_close(fd, MYF(0));
@@ -1679,8 +2069,64 @@ void reject_dump(const char* record_file, char* buf, int size)
str_to_file(fn_format(reject_file, record_file,"",".reject",2), buf, size);
}
+
+/* Append the string to ds, with optional replace */
+
+static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
+ int len)
+{
+ if (glob_replace)
+ {
+ len=(int) replace_strings(glob_replace, &out_buff, &out_length, val);
+ if (len == -1)
+ die("Out of memory in replace\n");
+ val=out_buff;
+ }
+ dynstr_append_mem(ds, val, len);
+}
+
+
+/*
+ Append all results to the dynamic string separated with '\t'
+ Values may be converted with 'replace_column'
+*/
+
+static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
+{
+ MYSQL_ROW row;
+ uint num_fields= mysql_num_fields(res);
+ unsigned long *lengths;
+ while ((row = mysql_fetch_row(res)))
+ {
+ uint i;
+ lengths = mysql_fetch_lengths(res);
+ for (i = 0; i < num_fields; i++)
+ {
+ const char *val= row[i];
+ ulonglong len= lengths[i];
+
+ if (i < max_replace_column && replace_column[i])
+ {
+ val= replace_column[i];
+ len= strlen(val);
+ }
+ if (!val)
+ {
+ val= "NULL";
+ len= 4;
+ }
+ if (i)
+ dynstr_append_mem(ds, "\t", 1);
+ replace_dynstr_append_mem(ds, val, len);
+ }
+ dynstr_append_mem(ds, "\n", 1);
+ }
+ free_replace_column();
+}
+
+
/*
-* flags control the phased/stages of query execution to be performed
+* flags control the phased/stages of query execution to be performed
* if QUERY_SEND bit is on, the query will be sent. If QUERY_REAP is on
* the result will be read - for regular query, both bits must be on
*/
@@ -1688,81 +2134,103 @@ void reject_dump(const char* record_file, char* buf, int size)
int run_query(MYSQL* mysql, struct st_query* q, int flags)
{
MYSQL_RES* res = 0;
- MYSQL_FIELD* fields;
- MYSQL_ROW row;
- int num_fields,i, error = 0;
- unsigned long* lengths;
- char* val;
- int len;
+ int i, error = 0;
DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_tmp;
DYNAMIC_STRING eval_query;
char* query;
int query_len;
DBUG_ENTER("run_query");
-
- if(q->type != Q_EVAL)
- {
- query = q->query;
- query_len = strlen(query);
- }
- else
- {
- init_dynamic_string(&eval_query, "", 16384, 65536);
- do_eval(&eval_query, q->query);
- query = eval_query.str;
- query_len = eval_query.length;
- }
- if ( q->record_file[0])
+ if (q->type != Q_EVAL)
+ {
+ query = q->query;
+ query_len = strlen(query);
+ }
+ else
+ {
+ init_dynamic_string(&eval_query, "", 16384, 65536);
+ do_eval(&eval_query, q->query);
+ query = eval_query.str;
+ query_len = eval_query.length;
+ }
+ DBUG_PRINT("enter", ("query: '%-.60s'", query));
+
+ if (q->record_file[0])
{
init_dynamic_string(&ds_tmp, "", 16384, 65536);
ds = &ds_tmp;
}
else
ds= &ds_res;
-
+
if ((flags & QUERY_SEND) && mysql_send_query(mysql, query, query_len))
- die("At line %u: unable to send query '%s'", start_lineno, query);
- if(!(flags & QUERY_REAP))
- return 0;
-
+ die("At line %u: unable to send query '%s'(mysql_errno=%d,errno=%d)",
+ start_lineno, query,
+ mysql_errno(mysql), errno);
+ if ((flags & QUERY_SEND) && !disable_query_log)
+ {
+ replace_dynstr_append_mem(ds,query, query_len);
+ dynstr_append_mem(ds,";\n",2);
+ }
+ if (!(flags & QUERY_REAP))
+ DBUG_RETURN(0);
+
if (mysql_read_query_result(mysql) ||
- (!(res = mysql_store_result(mysql)) && mysql_field_count(mysql)))
+ (!(last_result = res = mysql_store_result(mysql)) &&
+ mysql_field_count(mysql)))
{
if (q->require_file)
+ {
abort_not_supported_test();
+ }
if (q->abort_on_error)
die("At line %u: query '%s' failed: %d: %s", start_lineno, query,
mysql_errno(mysql), mysql_error(mysql));
else
{
- for (i=0 ; q->expected_errno[i] ; i++)
+ for (i=0 ; (uint) i < q->expected_errors ; i++)
{
if ((q->expected_errno[i] == mysql_errno(mysql)))
+ {
+ if (i == 0 && q->expected_errors == 1)
+ {
+ /* Only log error if there is one possible error */
+ replace_dynstr_append_mem(ds,mysql_error(mysql),
+ strlen(mysql_error(mysql)));
+ dynstr_append_mem(ds,"\n",1);
+ }
+ /* Don't log error if we may not get an error */
+ else if (q->expected_errno[0] != 0)
+ dynstr_append(ds,"Got one of the listed errors\n");
goto end; /* Ok */
+ }
}
+ DBUG_PRINT("info",("i: %d expected_errors: %d", i, q->expected_errors));
+ replace_dynstr_append_mem(ds, mysql_error(mysql),
+ strlen(mysql_error(mysql)));
+ dynstr_append_mem(ds,"\n",1);
if (i)
{
verbose_msg("query '%s' failed with wrong errno %d instead of %d...",
q->query, mysql_errno(mysql), q->expected_errno[0]);
- error=1;
+ error= 1;
goto end;
}
verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql),
mysql_error(mysql));
- /*
- if we do not abort on error, failure to run the query does
- not fail the whole test case
+ /*
+ if we do not abort on error, failure to run the query does
+ not fail the whole test case
*/
goto end;
}
/*{
verbose_msg("failed in mysql_store_result for query '%s' (%d)", query,
- mysql_errno(mysql));
+ mysql_errno(mysql));
error = 1;
goto end;
- }*/
+ }*/
}
if (q->expected_errno[0])
@@ -1773,48 +2241,30 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
goto end;
}
- if (!res) goto end;
-
- fields = mysql_fetch_fields(res);
- num_fields = mysql_num_fields(res);
- for( i = 0; i < num_fields; i++)
- {
- if (i)
- dynstr_append_mem(ds, "\t", 1);
- dynstr_append(ds, fields[i].name);
- }
-
- dynstr_append_mem(ds, "\n", 1);
-
-
- while((row = mysql_fetch_row(res)))
+ if (!disable_result_log)
{
- lengths = mysql_fetch_lengths(res);
- for(i = 0; i < num_fields; i++)
+ if (res)
{
- val = (char*)row[i];
- len = lengths[i];
-
- if (!val)
+ int num_fields= mysql_num_fields(res);
+ MYSQL_FIELD *fields= mysql_fetch_fields(res);
+ for (i = 0; i < num_fields; i++)
{
- val = (char*)"NULL";
- len = 4;
+ if (i)
+ dynstr_append_mem(ds, "\t", 1);
+ dynstr_append(ds, fields[i].name);
}
-
- if (i)
- dynstr_append_mem(ds, "\t", 1);
- if (glob_replace)
- {
- len=(int) replace_strings(glob_replace, &out_buff, &out_length, val);
- if (len == -1)
- die("Out of memory in replace\n");
- val=out_buff;
- }
- dynstr_append_mem(ds, val, len);
+ dynstr_append_mem(ds, "\n", 1);
+ append_result(ds, res);
}
- dynstr_append_mem(ds, "\n", 1);
+ if (!disable_info && mysql_info(mysql))
+ {
+ dynstr_append(ds, "info: ");
+ dynstr_append(ds, mysql_info(mysql));
+ dynstr_append_mem(ds, "\n", 1);
+ }
}
+
if (glob_replace)
free_replace();
@@ -1831,10 +2281,12 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
}
end:
- if (res) mysql_free_result(res);
+ if (res)
+ mysql_free_result(res);
+ last_result=0;
if (ds == &ds_tmp)
dynstr_free(&ds_tmp);
- if(q->type == Q_EVAL)
+ if (q->type == Q_EVAL)
dynstr_free(&eval_query);
DBUG_RETURN(error);
}
@@ -1860,7 +2312,7 @@ void get_query_type(struct st_query* q)
q->type=(enum enum_commands) type; /* Found command */
}
-static byte* get_var_key(const byte* var, uint* len,
+static byte *get_var_key(const byte* var, uint* len,
my_bool __attribute__((unused)) t)
{
register char* key;
@@ -1869,28 +2321,32 @@ static byte* get_var_key(const byte* var, uint* len,
return (byte*)key;
}
-static VAR* var_init(VAR* v, const char* name, int name_len, const char* val,
+static VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
int val_len)
{
int val_alloc_len;
- VAR* tmp_var;
- if(!name_len && name)
+ VAR *tmp_var;
+ if (!name_len && name)
name_len = strlen(name);
- if(!val_len && val)
+ if (!val_len && val)
val_len = strlen(val) ;
val_alloc_len = val_len + 16; /* room to grow */
- if(!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
- + name_len, MYF(MY_WME))))
+ if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
+ + name_len, MYF(MY_WME))))
die("Out of memory");
-
- tmp_var->name = (name) ? (char*)tmp_var + sizeof(*tmp_var) : 0;
- if(!(tmp_var->str_val = my_malloc(val_alloc_len, MYF(MY_WME))))
+ tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0;
+ tmp_var->alloced = (v == 0);
+
+ if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME))))
die("Out of memory");
-
+
memcpy(tmp_var->name, name, name_len);
- if(val)
- memcpy(tmp_var->str_val, val, val_len + 1);
+ if (val)
+ {
+ memcpy(tmp_var->str_val, val, val_len);
+ tmp_var->str_val[val_len]=0;
+ }
tmp_var->name_len = name_len;
tmp_var->str_val_len = val_len;
tmp_var->alloced_len = val_alloc_len;
@@ -1899,42 +2355,56 @@ static VAR* var_init(VAR* v, const char* name, int name_len, const char* val,
return tmp_var;
}
-static void var_free(void* v)
+static void var_free(void *v)
{
my_free(((VAR*) v)->str_val, MYF(MY_WME));
- my_free((char*) v, MYF(MY_WME));
+ if (((VAR*)v)->alloced)
+ my_free((char*) v, MYF(MY_WME));
}
-static void var_from_env(const char* name, const char* def_val)
+static void var_from_env(const char *name, const char *def_val)
{
- const char* tmp;
- VAR* v;
- if(!(tmp = getenv(name)))
+ const char *tmp;
+ VAR *v;
+ if (!(tmp = getenv(name)))
tmp = def_val;
-
- v = var_init(0, name, 0, tmp, 0);
- hash_insert(&var_hash, (byte*)v);
+
+ v = var_init(0, name, 0, tmp, 0);
+ my_hash_insert(&var_hash, (byte*)v);
}
-static void init_var_hash()
+static void init_var_hash(MYSQL *mysql)
{
- if (hash_init(&var_hash, 1024, 0, 0, get_var_key, var_free, MYF(0)))
+ VAR *v;
+ DBUG_ENTER("init_var_hash");
+ if (hash_init(&var_hash,
+ 1024, 0, 0, get_var_key, var_free, MYF(0)))
die("Variable hash initialization failed");
var_from_env("MASTER_MYPORT", "9306");
var_from_env("SLAVE_MYPORT", "9307");
var_from_env("MYSQL_TEST_DIR", "/tmp");
var_from_env("BIG_TEST", opt_big_test ? "1" : "0");
+ v= var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "62",0);
+ my_hash_insert(&var_hash, (byte*) v);
+ v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0);
+ my_hash_insert(&var_hash, (byte*) v);
+
+ DBUG_VOID_RETURN;
}
-int main(int argc, char** argv)
+
+int main(int argc, char **argv)
{
int error = 0;
- struct st_query* q;
+ struct st_query *q;
my_bool require_file=0, q_send_flag=0;
char save_file[FN_REFLEN];
MY_INIT(argv[0]);
+ {
+ DBUG_ENTER("main");
+ DBUG_PROCESS(argv[0]);
save_file[0]=0;
TMPDIR[0]=0;
@@ -1942,7 +2412,7 @@ int main(int argc, char** argv)
cons_end = cons + MAX_CONS;
next_con = cons + 1;
cur_con = cons;
-
+
memset(file_stack, 0, sizeof(file_stack));
memset(&master_pos, 0, sizeof(master_pos));
file_stack_end = file_stack + MAX_INCLUDE_DEPTH;
@@ -1953,28 +2423,41 @@ int main(int argc, char** argv)
memset(block_stack, 0, sizeof(block_stack));
block_stack_end = block_stack + BLOCK_STACK_DEPTH;
memset(block_ok_stack, 0, sizeof(block_stack));
- block_ok_stack_end = block_ok_stack + BLOCK_STACK_DEPTH;
cur_block = block_stack;
block_ok = block_ok_stack;
*block_ok = 1;
init_dynamic_string(&ds_res, "", 0, 65536);
parse_args(argc, argv);
- init_var_hash();
- if (!*cur_file)
- *cur_file = stdin;
+ if (mysql_server_init(embedded_server_arg_count,
+ embedded_server_args,
+ (char**) embedded_server_groups))
+ die("Can't initialize MySQL server");
+ if (cur_file == file_stack)
+ *++cur_file = stdin;
*lineno=1;
-
+#ifndef EMBEDDED_LIBRARY
+ if (manager_host)
+ init_manager();
+#endif
if (!( mysql_init(&cur_con->mysql)))
die("Failed in mysql_init()");
- cur_con->name = my_strdup("default", MYF(MY_WME));
- if (!cur_con->name)
+ if (opt_compress)
+ mysql_options(&cur_con->mysql,MYSQL_OPT_COMPRESS,NullS);
+ mysql_options(&cur_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
+#ifdef HAVE_OPENSSL
+ if (opt_use_ssl)
+ mysql_ssl_set(&cur_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+ opt_ssl_capath, opt_ssl_cipher);
+#endif
+
+ if (!(cur_con->name = my_strdup("default", MYF(MY_WME))))
die("Out of memory");
- if (!mysql_real_connect(&cur_con->mysql, host,
- user, pass, db, port, unix_sock,
- 0))
+ if (safe_connect(&cur_con->mysql, host, user, pass, db, port, unix_sock))
die("Failed in mysql_real_connect(): %s", mysql_error(&cur_con->mysql));
+ init_var_hash(&cur_con->mysql);
+
while (!read_query(&q))
{
int current_line_inc = 1, processed = 0;
@@ -1985,31 +2468,49 @@ int main(int argc, char** argv)
processed = 1;
switch (q->type) {
case Q_CONNECT: do_connect(q); break;
- case Q_CONNECTION: select_connection(q); break;
+ case Q_CONNECTION: select_connection(q->first_argument); break;
case Q_DISCONNECT:
- case Q_DIRTY_CLOSE:
+ case Q_DIRTY_CLOSE:
close_connection(q); break;
case Q_RPL_PROBE: do_rpl_probe(q); break;
- case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break;
- case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
+ case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break;
+ case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
+ case Q_ENABLE_QUERY_LOG: disable_query_log=0; break;
+ case Q_DISABLE_QUERY_LOG: disable_query_log=1; break;
+ case Q_ENABLE_RESULT_LOG: disable_result_log=0; break;
+ case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
+ case Q_ENABLE_WARNINGS: disable_warnings=0; break;
+ case Q_DISABLE_WARNINGS: disable_warnings=1; break;
+ case Q_ENABLE_INFO: disable_info=0; break;
+ case Q_DISABLE_INFO: disable_info=1; break;
case Q_SOURCE: do_source(q); break;
- case Q_SLEEP: do_sleep(q); break;
+ case Q_SLEEP: do_sleep(q, 0); break;
+ case Q_REAL_SLEEP: do_sleep(q, 1); break;
+ case Q_REQUIRE_VERSION: do_require_version(q); break;
+ case Q_WAIT_FOR_SLAVE_TO_STOP: do_wait_for_slave_to_stop(q); break;
+ case Q_REQUIRE_MANAGER: do_require_manager(q); break;
+#ifndef EMBEDDED_LIBRARY
+ case Q_SERVER_START: do_server_start(q); break;
+ case Q_SERVER_STOP: do_server_stop(q); break;
+#endif
case Q_INC: do_inc(q); break;
case Q_DEC: do_dec(q); break;
case Q_ECHO: do_echo(q); break;
case Q_SYSTEM: do_system(q); break;
case Q_LET: do_let(q); break;
- case Q_EVAL_RESULT: eval_result = 1; break;
+ case Q_EVAL_RESULT: eval_result = 1; break;
case Q_EVAL:
- if (q->query == q->query_buf)
- q->query += q->first_word_len;
- /* fall through */
+ if (q->query == q->query_buf)
+ q->query= q->first_argument;
+ /* fall through */
case Q_QUERY:
- case Q_REAP:
+ case Q_REAP:
{
- int flags = QUERY_REAP; /* we read the result always regardless
- * of the mode for both full query and
- * read-result only ( reap) */
+ /*
+ We read the result always regardless of the mode for both full
+ query and read-result only (reap)
+ */
+ int flags = QUERY_REAP;
if (q->type != Q_REAP) /* for a full query, enable the send stage */
flags |= QUERY_SEND;
if (q_send_flag)
@@ -2036,19 +2537,20 @@ int main(int argc, char** argv)
/* fix up query pointer if this is * first iteration for this line */
if (q->query == q->query_buf)
q->query += q->first_word_len;
- error |= run_query(&cur_con->mysql, q, QUERY_SEND);
- /* run query can execute a query partially, depending on the flags
- * QUERY_SEND flag without QUERY_REAP tells it to just send the
- * query and read the result some time later when reap instruction
- * is given on this connection
+ /*
+ run_query() can execute a query partially, depending on the flags
+ QUERY_SEND flag without QUERY_REAP tells it to just send the
+ query and read the result some time later when reap instruction
+ is given on this connection.
*/
+ error |= run_query(&cur_con->mysql, q, QUERY_SEND);
break;
case Q_RESULT:
get_file_name(save_file,q);
require_file=0;
break;
case Q_ERROR:
- get_ints(global_expected_errno,q);
+ global_expected_errors=get_ints(global_expected_errno,q);
break;
case Q_REQUIRE:
get_file_name(save_file,q);
@@ -2057,13 +2559,33 @@ int main(int argc, char** argv)
case Q_REPLACE:
get_replace(q);
break;
- case Q_SAVE_MASTER_POS: do_save_master_pos(); break;
- case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break;
+ case Q_REPLACE_COLUMN:
+ get_replace_column(q);
+ break;
+ case Q_SAVE_MASTER_POS: do_save_master_pos(); break;
+ case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break;
+ case Q_SYNC_SLAVE_WITH_MASTER:
+ {
+ do_save_master_pos();
+ if (*q->first_argument)
+ select_connection(q->first_argument);
+ else
+ {
+ char buf[] = "slave";
+ select_connection(buf);
+ }
+ do_sync_with_master2("");
+ break;
+ }
case Q_COMMENT: /* Ignore row */
- case Q_COMMENT_WITH_COMMAND:
+ case Q_COMMENT_WITH_COMMAND:
+ break;
case Q_PING:
(void) mysql_ping(&cur_con->mysql);
break;
+ case Q_EXEC:
+ (void) do_exec(q);
+ break;
default: processed = 0; break;
}
}
@@ -2071,8 +2593,7 @@ int main(int argc, char** argv)
if (!processed)
{
current_line_inc = 0;
- switch(q->type)
- {
+ switch (q->type) {
case Q_WHILE: do_while(q); break;
case Q_END_BLOCK: do_done(q); break;
default: current_line_inc = 1; break;
@@ -2091,8 +2612,9 @@ int main(int argc, char** argv)
}
dynstr_free(&ds_res);
- if (!silent) {
- if(error)
+ if (!silent)
+ {
+ if (error)
printf("not ok\n");
else
printf("ok\n");
@@ -2101,8 +2623,54 @@ int main(int argc, char** argv)
free_used_memory();
exit(error ? 1 : 0);
return error ? 1 : 0; /* Keep compiler happy */
+ }
}
+/*
+ Read arguments for embedded server and put them into
+ embedded_server_args_count and embedded_server_args[]
+*/
+
+
+static int read_server_arguments(const char *name)
+{
+ char argument[1024],buff[FN_REFLEN], *str=0;
+ FILE *file;
+
+ if (!test_if_hard_path(name))
+ {
+ strxmov(buff, opt_basedir, name, NullS);
+ name=buff;
+ }
+ fn_format(buff,name,"","",4);
+
+ if (!embedded_server_arg_count)
+ {
+ embedded_server_arg_count=1;
+ embedded_server_args[0]= (char*) ""; /* Progname */
+ }
+ if (!(file=my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME))))
+ return 1;
+ while (embedded_server_arg_count < MAX_SERVER_ARGS &&
+ (str=fgets(argument,sizeof(argument), file)))
+ {
+ *(strend(str)-1)=0; /* Remove end newline */
+ if (!(embedded_server_args[embedded_server_arg_count]=
+ (char*) my_strdup(str,MYF(MY_WME))))
+ {
+ my_fclose(file,MYF(0));
+ return 1;
+ }
+ embedded_server_arg_count++;
+ }
+ my_fclose(file,MYF(0));
+ if (str)
+ {
+ fprintf(stderr,"Too many arguments in option file: %s\n",name);
+ return 1;
+ }
+ return 0;
+}
/****************************************************************************
* Handle replacement of strings
@@ -2117,7 +2685,7 @@ int main(int argc, char** argv)
#define LAST_CHAR_CODE 259
typedef struct st_replace {
- bool found;
+ bool found;
struct st_replace *next[256];
} REPLACE;
@@ -2223,12 +2791,12 @@ void free_pointer_array(POINTER_ARRAY *pa)
#define SET_MALLOC_HUNC 64
typedef struct st_rep_set {
- uint *bits; /* Pointer to used sets */
- short next[LAST_CHAR_CODE]; /* Pointer to next sets */
+ uint *bits; /* Pointer to used sets */
+ short next[LAST_CHAR_CODE]; /* Pointer to next sets */
uint found_len; /* Best match to date */
int found_offset;
- uint table_offset;
- uint size_of_bits; /* For convinience */
+ uint table_offset;
+ uint size_of_bits; /* For convinience */
} REP_SET;
typedef struct st_rep_sets {
@@ -2759,8 +3327,8 @@ static uint replace_len(my_string str)
/* Replace strings; Return length of result string */
-uint replace_strings(REPLACE *rep, my_string *start,uint *max_length,
- my_string from)
+uint replace_strings(REPLACE *rep, my_string *start,uint *max_length,
+ const char *from)
{
reg1 REPLACE *rep_pos;
reg2 REPLACE_STRING *rep_str;
@@ -2768,7 +3336,7 @@ uint replace_strings(REPLACE *rep, my_string *start,uint *max_length,
end=(to= *start) + *max_length-1;
rep_pos=rep+1;
- for(;;)
+ for (;;)
{
while (!rep_pos->found)
{
@@ -2816,3 +3384,60 @@ static void free_replace_buffer(void)
{
my_free(out_buff,MYF(MY_WME));
}
+
+
+/****************************************************************************
+ Replace results for a column
+*****************************************************************************/
+
+static void free_replace_column()
+{
+ uint i;
+ for (i=0 ; i < max_replace_column ; i++)
+ {
+ if (replace_column[i])
+ {
+ my_free(replace_column[i], 0);
+ replace_column[i]= 0;
+ }
+ }
+ max_replace_column= 0;
+}
+
+/*
+ Get arguments for replace_columns. The syntax is:
+ replace-column column_number to_string [column_number to_string ...]
+ Where each argument may be quoted with ' or "
+ A argument may also be a variable, in which case the value of the
+ variable is replaced.
+*/
+
+static void get_replace_column(struct st_query *q)
+{
+ char *from=q->first_argument;
+ char *buff,*start;
+ DBUG_ENTER("get_replace_columns");
+
+ free_replace_column();
+ if (!*from)
+ die("Missing argument in %s\n", q->query);
+
+ /* Allocate a buffer for results */
+ start=buff=my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
+ while (*from)
+ {
+ char *to;
+ uint column_number;
+
+ to= get_string(&buff, &from, q);
+ if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS)
+ die("Wrong column number to replace_columns in %s\n", q->query);
+ if (!*from)
+ die("Wrong number of arguments to replace in %s\n", q->query);
+ to= get_string(&buff, &from, q);
+ my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR);
+ replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE));
+ set_if_bigger(max_replace_column, column_number);
+ }
+ my_free(start, MYF(0));
+}
diff --git a/client/password.c b/client/password.c
deleted file mode 100644
index 0fd5861873a..00000000000
--- a/client/password.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* password checking routines */
-/*****************************************************************************
- The main idea is that no password are sent between client & server on
- connection and that no password are saved in mysql in a decodable form.
-
- On connection a random string is generated and sent to the client.
- The client generates a new string with a random generator inited with
- the hash values from the password and the sent string.
- This 'check' string is sent to the server where it is compared with
- a string generated from the stored hash_value of the password and the
- random string.
-
- The password is saved (in user.password) by using the PASSWORD() function in
- mysql.
-
- Example:
- update user set password=PASSWORD("hello") where user="test"
- This saves a hashed number as a string in the password field.
-*****************************************************************************/
-
-#include <global.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include "mysql.h"
-
-
-void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2)
-{ /* For mysql 3.21.# */
-#ifdef HAVE_purify
- bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
-#endif
- rand_st->max_value= 0x3FFFFFFFL;
- rand_st->max_value_dbl=(double) rand_st->max_value;
- rand_st->seed1=seed1%rand_st->max_value ;
- rand_st->seed2=seed2%rand_st->max_value;
-}
-
-static void old_randominit(struct rand_struct *rand_st,ulong seed1)
-{ /* For mysql 3.20.# */
- rand_st->max_value= 0x01FFFFFFL;
- rand_st->max_value_dbl=(double) rand_st->max_value;
- seed1%=rand_st->max_value;
- rand_st->seed1=seed1 ; rand_st->seed2=seed1/2;
-}
-
-double rnd(struct rand_struct *rand_st)
-{
- rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
- rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
- return (((double) rand_st->seed1)/rand_st->max_value_dbl);
-}
-
-void hash_password(ulong *result, const char *password)
-{
- register ulong nr=1345345333L, add=7, nr2=0x12345671L;
- ulong tmp;
- for (; *password ; password++)
- {
- if (*password == ' ' || *password == '\t')
- continue; /* skipp space in password */
- tmp= (ulong) (uchar) *password;
- nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
- nr2+=(nr2 << 8) ^ nr;
- add+=tmp;
- }
- result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
- result[1]=nr2 & (((ulong) 1L << 31) -1L);
- return;
-}
-
-void make_scrambled_password(char *to,const char *password)
-{
- ulong hash_res[2];
- hash_password(hash_res,password);
- sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
-}
-
-static inline uint char_val(char X)
-{
- return (uint) (X >= '0' && X <= '9' ? X-'0' :
- X >= 'A' && X <= 'Z' ? X-'A'+10 :
- X-'a'+10);
-}
-
-/*
-** This code assumes that len(password) is divideable with 8 and that
-** res is big enough (2 in mysql)
-*/
-
-void get_salt_from_password(ulong *res,const char *password)
-{
- res[0]=res[1]=0;
- if (password)
- {
- while (*password)
- {
- ulong val=0;
- uint i;
- for (i=0 ; i < 8 ; i++)
- val=(val << 4)+char_val(*password++);
- *res++=val;
- }
- }
- return;
-}
-
-void make_password_from_salt(char *to, ulong *hash_res)
-{
- sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
-}
-
-
-/*
- * Genererate a new message based on message and password
- * The same thing is done in client and server and the results are checked.
- */
-
-char *scramble(char *to,const char *message,const char *password,
- my_bool old_ver)
-{
- struct rand_struct rand_st;
- ulong hash_pass[2],hash_message[2];
- if (password && password[0])
- {
- char *to_start=to;
- hash_password(hash_pass,password);
- hash_password(hash_message,message);
- if (old_ver)
- old_randominit(&rand_st,hash_pass[0] ^ hash_message[0]);
- else
- randominit(&rand_st,hash_pass[0] ^ hash_message[0],
- hash_pass[1] ^ hash_message[1]);
- while (*message++)
- *to++= (char) (floor(rnd(&rand_st)*31)+64);
- if (!old_ver)
- { /* Make it harder to break */
- char extra=(char) (floor(rnd(&rand_st)*31));
- while (to_start != to)
- *(to_start++)^=extra;
- }
- }
- *to=0;
- return to;
-}
-
-
-my_bool check_scramble(const char *scrambled, const char *message,
- ulong *hash_pass, my_bool old_ver)
-{
- struct rand_struct rand_st;
- ulong hash_message[2];
- char buff[16],*to,extra; /* Big enough for check */
- const char *pos;
-
- hash_password(hash_message,message);
- if (old_ver)
- old_randominit(&rand_st,hash_pass[0] ^ hash_message[0]);
- else
- randominit(&rand_st,hash_pass[0] ^ hash_message[0],
- hash_pass[1] ^ hash_message[1]);
- to=buff;
- for (pos=scrambled ; *pos ; pos++)
- *to++=(char) (floor(rnd(&rand_st)*31)+64);
- if (old_ver)
- extra=0;
- else
- extra=(char) (floor(rnd(&rand_st)*31));
- to=buff;
- while (*scrambled)
- {
- if (*scrambled++ != (char) (*to++ ^ extra))
- return 1; /* Wrong password */
- }
- return 0;
-}
diff --git a/client/readline.cc b/client/readline.cc
index f0312b089e5..f5fbfd8cd0c 100644
--- a/client/readline.cc
+++ b/client/readline.cc
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* readline for batch mode */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include "my_readline.h"
@@ -120,20 +119,11 @@ static bool init_line_buffer_from_string(LINE_BUFFER *buffer,my_string str)
}
-static void free_line_buffer(LINE_BUFFER *buffer)
-{
- if (buffer->buffer)
- {
- my_free((gptr) buffer->buffer,MYF(0));
- buffer->buffer=0;
- }
-}
-
-
-/* Fill the buffer retaining the last n bytes at the beginning of the
- newly filled buffer (for backward context). Returns the number of new
- bytes read from disk. */
-
+/*
+ Fill the buffer retaining the last n bytes at the beginning of the
+ newly filled buffer (for backward context). Returns the number of new
+ bytes read from disk.
+*/
static uint fill_buffer(LINE_BUFFER *buffer)
{
diff --git a/client/select_test.c b/client/select_test.c
index 049f2b908be..ee2a9192865 100644
--- a/client/select_test.c
+++ b/client/select_test.c
@@ -1,20 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
diff --git a/client/showdb_test.c b/client/showdb_test.c
index f4c25999fe5..df2b3037c00 100644
--- a/client/showdb_test.c
+++ b/client/showdb_test.c
@@ -1,34 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
#ifdef __WIN__
#include <windows.h>
#endif
diff --git a/client/sql_string.cc b/client/sql_string.cc
index 4b9ebef21f1..3c5e481eaad 100644
--- a/client/sql_string.cc
+++ b/client/sql_string.cc
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program file is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is originally from the mysql distribution. Coded by monty */
@@ -21,7 +20,7 @@
#pragma implementation // gcc: Class implementation
#endif
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
diff --git a/client/sql_string.h b/client/sql_string.h
index 74dbc4cc6bd..cffe78936a0 100644
--- a/client/sql_string.h
+++ b/client/sql_string.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is originally from the mysql distribution. Coded by monty */
diff --git a/client/ssl_test.c b/client/ssl_test.c
index d1ec1776696..279c1e95fdc 100644
--- a/client/ssl_test.c
+++ b/client/ssl_test.c
@@ -1,34 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
#ifdef __WIN__
#include <windows.h>
#endif
diff --git a/client/thimble.cc b/client/thimble.cc
index 6d1e8a85559..94b75d8fb35 100644
--- a/client/thimble.cc
+++ b/client/thimble.cc
@@ -1,8 +1,24 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include "my_global.h"
+#include "my_my_global.h"
static void spawn_stern_thread(pthread_t *t);
static int act_goofy(void);
@@ -89,5 +105,3 @@ static void *be_stern(void *v __attribute__((unused)))
fputs("You are NOTHING!\n", stderr);
return NULL;
}
-
-
diff --git a/client/thread_test.c b/client/thread_test.c
index dbe2acee8db..2900ab712e2 100644
--- a/client/thread_test.c
+++ b/client/thread_test.c
@@ -1,25 +1,24 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include <global.h>
+#include <my_global.h>
#ifndef THREAD
-int main(void)
+int main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
{
printf("This test must be compiled with multithread support to work\n");
exit(1);
@@ -29,9 +28,9 @@ int main(void)
#include <my_sys.h>
#include <my_pthread.h>
#include "mysql.h"
-#include <getopt.h>
+#include <my_getopt.h>
-static my_bool version,verbose;
+static my_bool version, verbose, tty_password= 0;
static uint thread_count,number_of_tests=1000,number_of_threads=2;
static pthread_cond_t COND_thread_count;
static pthread_mutex_t LOCK_thread_count;
@@ -85,23 +84,39 @@ end:
}
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"help", no_argument, 0, '?'},
- {"database", required_argument, 0, 'D'},
- {"host", required_argument, 0, 'h'},
- {"password", optional_argument, 0, 'p'},
- {"user", required_argument, 0, 'u'},
- {"version", no_argument, 0, 'V'},
- {"verbose", no_argument, 0, 'v'},
- {"query", required_argument, 0, 'Q'},
- {"port", required_argument, 0, 'P'},
- {"socket", required_argument, 0, 'S'},
- {"test-count",required_argument, 0, 'c'},
- {"thread-count",required_argument, 0, 't'},
- {0, 0, 0, 0}
+ {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"database", 'D', "Database to use", (gptr*) &database, (gptr*) &database,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host", (gptr*) &host, (gptr*) &host, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "User for login if not current user", (gptr*) &user,
+ (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Write some progress indicators", (gptr*) &verbose,
+ (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"query", 'Q', "Query to execute in each threads", (gptr*) &query,
+ (gptr*) &query, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection", (gptr*) &tcp_port,
+ (gptr*) &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection", (gptr*) &unix_socket,
+ (gptr*) &unix_socket, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"test-count", 'c', "Run test count times (default %d)",
+ (gptr*) &number_of_tests, (gptr*) &number_of_tests, 0, GET_UINT,
+ REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
+ {"thread-count", 't', "Number of threads to start",
+ (gptr*) &number_of_threads, (gptr*) &number_of_threads, 0, GET_UINT,
+ REQUIRED_ARG, 2, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static const char *load_default_groups[]= { "client",0 };
static void usage()
@@ -111,103 +126,55 @@ static void usage()
return;
puts("This software comes with ABSOLUTELY NO WARRANTY.\n");
printf("Usage: %s [OPTIONS] [database]\n", my_progname);
- printf("\n\
- -?, --help Display this help and exit\n\
- -c #, --test-count=# Run test count times (default %d)\n",number_of_tests);
- printf("\
- -D, --database=.. Database to use\n\
- -h, --host=... Connect to host\n\
- -p[password], --password[=...]\n\
- Password to use when connecting to server\n\
- If password is not given it's asked from the tty.\n");
- printf("\n\
- -P --port=... Port number to use for connection\n\
- -Q, --query=... Query to execute in each threads\n\
- -S --socket=... Socket file to use for connection\n");
- printf("\
- -t --thread-count=# Number of threads to start (default: %d) \n\
- -u, --user=# User for login if not current user\n\
- -v, --verbose Write some progress indicators\n\
- -V, --version Output version information and exit\n",
- number_of_threads);
+ my_print_help(my_long_options);
print_defaults("my",load_default_groups);
-
+ my_print_variables(my_long_options);
printf("\nExample usage:\n\n\
%s -Q 'select * from mysql.user' -c %d -t %d\n",
my_progname, number_of_tests, number_of_threads);
}
-static void get_options(int argc, char **argv)
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
{
- int c,option_index=0,error=0;
- bool tty_password=0;
- load_defaults("my",load_default_groups,&argc,&argv);
-
- while ((c=getopt_long(argc,argv, "c:D:h:p::VQ:P:S:t:?I",
- long_options, &option_index)) != EOF)
- {
- switch (c) {
- case 'c':
- number_of_tests=atoi(optarg);
- break;
- case 'D':
- my_free(database,MYF(MY_ALLOW_ZERO_PTR));
- database=my_strdup(optarg,MYF(MY_WME));
- break;
- case 'h':
- host = optarg;
- break;
- case 'Q': /* Allow old 'q' option */
- query= optarg;
- break;
- case 'p':
- if (optarg)
- {
- my_free(password,MYF(MY_ALLOW_ZERO_PTR));
- password=my_strdup(optarg,MYF(MY_FAE));
- while (*optarg) *optarg++= 'x'; /* Destroy argument */
- }
- else
- tty_password=1;
- break;
- case 'u':
- my_free(user,MYF(MY_ALLOW_ZERO_PTR));
- user= my_strdup(optarg,MYF(0));
- break;
- case 'P':
- tcp_port= (unsigned int) atoi(optarg);
- break;
- case 'S':
- my_free(unix_socket,MYF(MY_ALLOW_ZERO_PTR));
- unix_socket= my_strdup(optarg,MYF(0));
- break;
- case 't':
- number_of_threads=atoi(optarg);
- break;
- case 'v':
- verbose=1;
- break;
- case 'V':
- version=1;
- usage();
- exit(0);
- break;
- default:
- fprintf(stderr,"Illegal option character '%c'\n",opterr);
- /* Fall through */
- case '?':
- case 'I': /* Info */
- error++;
- break;
+ switch (optid) {
+ case 'p':
+ if (argument)
+ {
+ my_free(password, MYF(MY_ALLOW_ZERO_PTR));
+ password= my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
}
- }
- if (error || argc != optind)
- {
+ else
+ tty_password= 1;
+ break;
+ case 'V':
+ version= 1;
+ usage();
+ exit(0);
+ break;
+ case '?':
+ case 'I': /* Info */
usage();
exit(1);
+ break;
}
+ return 0;
+}
+
+
+static void get_options(int argc, char **argv)
+{
+ int ho_error;
+
+ load_defaults("my",load_default_groups,&argc,&argv);
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
free_defaults(argv);
if (tty_password)
password=get_tty_password(NullS);
diff --git a/client/violite.c b/client/violite.c
deleted file mode 100644
index 224ba051d82..00000000000
--- a/client/violite.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-#include <global.h>
-
-#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
-
-#include <errno.h>
-#include <assert.h>
-#include <violite.h>
-#include <my_sys.h>
-#include <my_net.h>
-#include <m_string.h>
-
-#if defined(__EMX__)
-#include <sys/ioctl.h>
-#define ioctlsocket(A,B,C) ioctl((A),(B),(void *)(C),sizeof(*(C)))
-#undef HAVE_FCNTL
-#endif /* defined(__EMX__) */
-
-#if defined(MSDOS) || defined(__WIN__)
-#ifdef __WIN__
-#undef errno
-#undef EINTR
-#undef EAGAIN
-#define errno WSAGetLastError()
-#define EINTR WSAEINTR
-#define EAGAIN WSAEINPROGRESS
-#endif /* __WIN__ */
-#define O_NONBLOCK 1 /* For emulation of fcntl() */
-#endif
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK EAGAIN
-#endif
-
-#ifndef __WIN__
-#define HANDLE void *
-#endif
-
-struct st_vio
-{
- my_socket sd; /* my_socket - real or imaginary */
- HANDLE hPipe;
- my_bool localhost; /* Are we from localhost? */
- int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
- my_bool fcntl_set; /* Have we done any fcntl yet?*/
- struct sockaddr_in local; /* Local internet address */
- struct sockaddr_in remote; /* Remote internet address */
- enum enum_vio_type type; /* Type of connection */
- char desc[30]; /* String description */
-};
-
-typedef void *vio_ptr;
-typedef char *vio_cstring;
-
-/*
- * Helper to fill most of the Vio* with defaults.
- */
-
-static void vio_reset(Vio* vio, enum enum_vio_type type,
- my_socket sd, HANDLE hPipe,
- my_bool localhost)
-{
- bzero((char*) vio, sizeof(*vio));
- vio->type = type;
- vio->sd = sd;
- vio->hPipe = hPipe;
- vio->localhost= localhost;
-}
-
-Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
-{
- Vio *vio;
- DBUG_ENTER("vio_new");
- DBUG_PRINT("enter", ("sd=%d", sd));
- if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
- {
- vio_reset(vio, type, sd, 0, localhost);
- sprintf(vio->desc, "socket (%d)", vio->sd);
- }
- DBUG_RETURN(vio);
-}
-
-
-#ifdef __WIN__
-
-Vio *vio_new_win32pipe(HANDLE hPipe)
-{
- Vio *vio;
- DBUG_ENTER("vio_new_handle");
- if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
- {
- vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
- strmov(vio->desc, "named pipe");
- }
- DBUG_RETURN(vio);
-}
-
-#endif
-
-void vio_delete(Vio * vio)
-{
- /* It must be safe to delete null pointers. */
- /* This matches the semantics of C++'s delete operator. */
- if (vio)
- {
- vio_close(vio);
- my_free((gptr) vio,MYF(0));
- }
-}
-
-int vio_errno(Vio *vio)
-{
- return errno; /* On Win32 this mapped to WSAGetLastError() */
-}
-
-
-int vio_read(Vio * vio, gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_read");
- DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
- assert(vio->sd >= 0);
-#ifdef __WIN__
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
- if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
- DBUG_RETURN(-1);
- DBUG_RETURN(length);
- }
- r = recv(vio->sd, buf, size,0);
-#else
- errno=0; /* For linux */
- r = read(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("error", ("Got error %d during read",errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_write(Vio * vio, const gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_write");
- DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
- assert(vio->sd >= 0);
-#ifdef __WIN__
- if ( vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
- if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
- DBUG_RETURN(-1);
- DBUG_RETURN(length);
- }
- r = send(vio->sd, buf, size,0);
-#else
- r = write(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("error", ("Got error on write: %d",errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_blocking(Vio * vio, my_bool set_blocking_mode)
-{
- int r=0;
- DBUG_ENTER("vio_blocking");
- DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
-
-#if !defined(___WIN__) && !defined(__EMX__)
-#if !defined(NO_FCNTL_NONBLOCK)
-
- if (vio->sd >= 0)
- {
- int old_fcntl=vio->fcntl_mode;
- if (!vio->fcntl_set)
- {
- vio->fcntl_set = TRUE;
- old_fcntl=vio->fcntl_mode = fcntl(vio->sd, F_GETFL);
- }
- if (set_blocking_mode)
- vio->fcntl_mode &= ~O_NONBLOCK; /*clear bit */
- else
- vio->fcntl_mode |= O_NONBLOCK; /*set bit */
- if (old_fcntl != vio->fcntl_mode)
- r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
- }
-#endif /* !defined(NO_FCNTL_NONBLOCK) */
-#else /* !defined(__WIN__) && !defined(__EMX__) */
-#ifndef __EMX__
- if (vio->type != VIO_TYPE_NAMEDPIPE)
-#endif
- {
- ulong arg;
- int old_fcntl=vio->fcntl_mode;
- if (!vio->fcntl_set)
- {
- vio->fcntl_set = TRUE;
- old_fnctl=vio->fcntl_mode=0;
- }
- if (set_blocking_mode)
- {
- arg = 0;
- vio->fcntl_mode &= ~O_NONBLOCK; /*clear bit */
- }
- else
- {
- arg = 1;
- vio->fcntl_mode |= O_NONBLOCK; /*set bit */
- }
- if (old_fcntl != vio->fcntl_mode)
- r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
- }
-#endif /* !defined(__WIN__) && !defined(__EMX__) */
- DBUG_RETURN(r);
-}
-
-my_bool
-vio_is_blocking(Vio * vio)
-{
- my_bool r;
- DBUG_ENTER("vio_is_blocking");
- r = !(vio->fcntl_mode & O_NONBLOCK);
- DBUG_PRINT("exit", ("%d", (int) r));
- DBUG_RETURN(r);
-}
-
-
-int vio_fastsend(Vio * vio, my_bool onoff)
-{
- int r=0;
- DBUG_ENTER("vio_fastsend");
- DBUG_PRINT("enter", ("onoff:%d", (int) onoff));
- assert(vio->sd >= 0);
-
-#ifdef IPTOS_THROUGHPUT
- {
-#ifndef __EMX__
- int tos = IPTOS_THROUGHPUT;
- if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
-#endif /* !__EMX__ */
- {
- int nodelay = 1;
- if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
- sizeof(nodelay))) {
- DBUG_PRINT("warning",
- ("Couldn't set socket option for fast send"));
- r= -1;
- }
- }
- }
-#endif /* IPTOS_THROUGHPUT */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-int vio_keepalive(Vio* vio, my_bool set_keep_alive)
-{
- int r=0;
- uint opt = 0;
- DBUG_ENTER("vio_keepalive");
- DBUG_PRINT("enter", ("sd=%d, set_keep_alive=%d", vio->sd, (int)
- set_keep_alive));
- if (vio->type != VIO_TYPE_NAMEDPIPE)
- {
- assert(vio->sd >= 0);
- if (set_keep_alive)
- opt = 1;
- r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
- sizeof(opt));
- }
- DBUG_RETURN(r);
-}
-
-
-my_bool
-vio_should_retry(Vio * vio)
-{
- int en = errno;
- return en == EAGAIN || en == EINTR || en == EWOULDBLOCK;
-}
-
-
-int vio_close(Vio * vio)
-{
- int r;
- DBUG_ENTER("vio_close");
- assert(vio->sd >= 0); /* Vill also work on PIPE:s */
-#ifdef __WIN__
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
-#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIO(vio->hPipe);
- DisconnectNamedPipe(vio->hPipe);
-#endif
- r=CloseHandle(vio->hPipe);
- }
- else
-#endif /* __WIN__ */
- {
- r=0;
- if (shutdown(vio->sd,2))
- r= -1;
- if (closesocket(vio->sd))
- r= -1;
- }
- if (r)
- {
- DBUG_PRINT("error", ("close() failed, error: %d",errno));
- /* FIXME: error handling (not critical for MySQL) */
- }
- vio_reset(vio,VIO_CLOSED,-1,0,TRUE); /* For debugging */
- DBUG_RETURN(r);
-}
-
-
-const char *vio_description(Vio * vio)
-{
- return vio->desc;
-}
-
-enum enum_vio_type vio_type(Vio* vio)
-{
- return vio->type;
-}
-
-my_socket vio_fd(Vio* vio)
-{
- return vio->sd;
-}
-
-
-my_bool vio_peer_addr(Vio * vio, char *buf)
-{
- DBUG_ENTER("vio_peer_addr");
- DBUG_PRINT("enter", ("sd=%d", vio->sd));
- if (vio->localhost)
- {
- strmov(buf,"127.0.0.1");
- }
- else
- {
- size_socket addrLen = sizeof(struct sockaddr);
- if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
- &addrLen) != 0)
- {
- DBUG_PRINT("exit", ("getpeername, error: %d", errno));
- DBUG_RETURN(1);
- }
- my_inet_ntoa(vio->remote.sin_addr,buf);
- }
- DBUG_PRINT("exit", ("addr=%s", buf));
- DBUG_RETURN(0);
-}
-
-
-void vio_in_addr(Vio *vio, struct in_addr *in)
-{
- DBUG_ENTER("vio_in_addr");
- if (vio->localhost)
- bzero((char*) in, sizeof(*in)); /* This should never be executed */
- else
- *in=vio->remote.sin_addr;
- DBUG_VOID_RETURN;
-}
-
-#endif /* HAVE_VIO */
diff --git a/config.guess b/config.guess
index 27ccc69772b..ef65f9b4ea9 100755
--- a/config.guess
+++ b/config.guess
@@ -1,9 +1,9 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-timestamp='2001-08-21'
+timestamp='2003-07-02'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -24,8 +24,9 @@ timestamp='2001-08-21'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
-# Written by Per Bothner <bothner@cygnus.com>.
-# Please send patches to <config-patches@gnu.org>.
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
@@ -87,30 +88,42 @@ if test $# != 0; then
exit 1
fi
+trap 'exit 1' 1 2 15
-dummy=dummy-$$
-trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
-# CC_FOR_BUILD -- compiler used by this script.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
-set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int dummy(){}" > $dummy.c ;
- for c in cc gcc c89 ; do
- ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
- if test $? = 0 ; then
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
- rm -f $dummy.c $dummy.o $dummy.rel ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac'
+esac ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
@@ -136,29 +149,30 @@ esac
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
- # Netbsd (nbsd) targets should (where applicable) match one or
+ # NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
- # Determine the machine/vendor (is the vendor relevant).
- case "${UNAME_MACHINE}" in
- amiga) machine=m68k-unknown ;;
- arm32) machine=arm-unknown ;;
- atari*) machine=m68k-atari ;;
- sun3*) machine=m68k-sun ;;
- mac68k) machine=m68k-apple ;;
- macppc) machine=powerpc-apple ;;
- hp3[0-9][05]) machine=m68k-hp ;;
- ibmrt|romp-ibm) machine=romp-ibm ;;
- *) machine=${UNAME_MACHINE}-unknown ;;
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
- case "${UNAME_MACHINE}" in
- i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
@@ -175,75 +189,112 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# The OS release
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvmeppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mipseb-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
fi
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- cat <<EOF >$dummy.s
- .data
-\$Lformat:
- .byte 37,100,45,37,120,10,0 # "%d-%x\n"
-
- .text
- .globl main
- .align 4
- .ent main
-main:
- .frame \$30,16,\$26,0
- ldgp \$29,0(\$27)
- .prologue 1
- .long 0x47e03d80 # implver \$0
- lda \$2,-1
- .long 0x47e20c21 # amask \$2,\$1
- lda \$16,\$Lformat
- mov \$0,\$17
- not \$1,\$18
- jsr \$26,printf
- ldgp \$29,0(\$26)
- mov 0,\$16
- jsr \$26,exit
- .end main
-EOF
- eval $set_cc_for_build
- $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
- if test "$?" = 0 ; then
- case `./$dummy` in
- 0-0)
- UNAME_MACHINE="alpha"
- ;;
- 1-0)
- UNAME_MACHINE="alphaev5"
- ;;
- 1-1)
- UNAME_MACHINE="alphaev56"
- ;;
- 1-101)
- UNAME_MACHINE="alphapca56"
- ;;
- 2-303)
- UNAME_MACHINE="alphaev6"
- ;;
- 2-307)
- UNAME_MACHINE="alphaev67"
- ;;
- 2-1307)
- UNAME_MACHINE="alphaev68"
- ;;
- esac
- fi
- rm -f $dummy.s $dummy
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit 0 ;;
+ Alpha*:OpenVMS:*:*)
+ echo alpha-hp-vms
+ exit 0 ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@@ -256,29 +307,11 @@ EOF
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit 0;;
- amiga:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit 0 ;;
- arc64:OpenBSD:*:*)
- echo mips64el-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- arc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- hkmips:OpenBSD:*:*)
- echo mips-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- pmax:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sgi:OpenBSD:*:*)
- echo mips-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- wgrisc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
exit 0 ;;
*:OS/390:*:*)
echo i370-ibm-openedition
@@ -300,6 +333,13 @@ EOF
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit 0 ;;
+ DRS?6000:UNIX_SV:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7 && exit 0 ;;
+ esac ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
@@ -328,7 +368,7 @@ EOF
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
@@ -342,12 +382,6 @@ EOF
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
- sparc*:NetBSD:*)
- echo `uname -p`-unknown-netbsd${UNAME_RELEASE}
- exit 0 ;;
- atari*:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
@@ -374,18 +408,6 @@ EOF
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
- sun3*:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme88k:OpenBSD:*:*)
- echo m88k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
@@ -402,6 +424,7 @@ EOF
echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
@@ -423,16 +446,20 @@ EOF
exit (-1);
}
EOF
- eval $set_cc_for_build
- $CC_FOR_BUILD $dummy.c -o $dummy \
- && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
- && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
+ $CC_FOR_BUILD -o $dummy $dummy.c \
+ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && exit 0
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
exit 0 ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
@@ -493,6 +520,7 @@ EOF
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <sys/systemcfg.h>
@@ -504,9 +532,7 @@ EOF
exit(0);
}
EOF
- eval $set_cc_for_build
- $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
@@ -515,7 +541,7 @@ EOF
fi
exit 0 ;;
*:AIX:*:[45])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
@@ -555,10 +581,8 @@ EOF
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
- case "${HPUX_REV}" in
- 11.[0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
@@ -567,12 +591,13 @@ EOF
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
- fi ;;
- esac
- if [ "${HP_ARCH}" = "" ]; then
- sed 's/^ //' << EOF >$dummy.c
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
@@ -605,12 +630,21 @@ EOF
exit (0);
}
EOF
- eval $set_cc_for_build
- (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
- if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
- rm -f $dummy.c $dummy
- fi ;;
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ # avoid double evaluation of $set_cc_for_build
+ test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
ia64:HP-UX:*:*)
@@ -618,6 +652,7 @@ EOF
echo ia64-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
+ eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <unistd.h>
int
@@ -643,9 +678,7 @@ EOF
exit (0);
}
EOF
- eval $set_cc_for_build
- $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
@@ -673,9 +706,6 @@ EOF
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
- hppa*:OpenBSD:*:*)
- echo hppa-unknown-openbsd
- exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
@@ -694,9 +724,6 @@ EOF
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
- CRAY*X-MP:*:*:*)
- echo xmp-cray-unicos
- exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
@@ -709,27 +736,21 @@ EOF
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
- CRAY*T3D:*:*:*)
- echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
- CRAY-2:*:*:*)
- echo cray2-cray-unicos
- exit 0 ;;
+ *:UNICOS/mp:*:*)
+ echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
- hp300:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
@@ -739,11 +760,22 @@ EOF
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
- *:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- *:OpenBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ *:FreeBSD:*:*|*:GNU/FreeBSD:*:*)
+ # Determine whether the default compiler uses glibc.
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #if __GLIBC__ >= 2
+ LIBC=gnu
+ #else
+ LIBC=
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ # GNU/FreeBSD systems have a "k" prefix to indicate we are using
+ # FreeBSD's kernel, but not the complete OS.
+ case ${LIBC} in gnu) kernel_only='k' ;; esac
+ echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
exit 0 ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
@@ -754,11 +786,17 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit 0 ;;
+ x86:Interix*:[34]*)
+ echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+ exit 0 ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit 0 ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
- echo i386-pc-interix
+ echo i586-pc-interix
exit 0 ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
@@ -778,6 +816,9 @@ EOF
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-${VENDOR}-linux
exit 0 ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux
+ exit 0 ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-${VENDOR}-linux
exit 0 ;;
@@ -785,19 +826,48 @@ EOF
echo ${UNAME_MACHINE}-${VENDOR}-linux
exit 0 ;;
mips:Linux:*:*)
- case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
- big) echo mips-${VENDOR}-linux && exit 0 ;;
- little) echo mipsel-${VENDOR}-linux && exit 0 ;;
- esac
- case `sed -n '/^system type/s/^.*: \([^ ]*\).*/\1/p' < /proc/cpuinfo` in
- SGI|sgi) echo mips-${VENDOR}-linux-gnu && exit 0 ;;
- esac
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && echo "${CPU}-${VENDOR}-linux" && exit 0
+ ;;
+ mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips64
+ #undef mips64el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mips64el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips64
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && echo "${CPU}-${VENDOR}-linux" && exit 0
;;
- ppc:Linux:*:*|ppc64:Linux:*:*)
+ ppc:Linux:*:*)
echo powerpc-${VENDOR}-linux
exit 0 ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
+ echo powerpc64-${VENDOR}-linux
exit 0 ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -810,7 +880,7 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ if test "$?" = 0 ; then LIBC="-libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-${VENDOR}-linux${LIBC}
exit 0 ;;
parisc:Linux:*:* | hppa:Linux:*:*)
@@ -827,6 +897,9 @@ EOF
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit 0 ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-${VENDOR}-linux
+ exit 0 ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-${VENDOR}-linux
exit 0 ;;
@@ -840,7 +913,8 @@ EOF
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
- ld_supported_targets=`cd /; ld --help 2>&1 \
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
@@ -852,7 +926,7 @@ EOF
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-${VENDOR}-linuxaout"
- exit 0 ;;
+ exit 0 ;;
coff-i386)
echo "${UNAME_MACHINE}-${VENDOR}-linuxcoff"
exit 0 ;;
@@ -863,33 +937,29 @@ EOF
exit 0 ;;
esac
# Determine whether the default compiler is a.out or elf
- cat >$dummy.c <<EOF
-#include <features.h>
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __ELF__
-# ifdef __GLIBC__
-# if __GLIBC__ >= 2
- printf ("%s-${VENDOR}-linux\n", argv[1]);
-# else
- printf ("%s-${VENDOR}-linuxlibc1\n", argv[1]);
-# endif
-# else
- printf ("%s-${VENDOR}-linuxlibc1\n", argv[1]);
-# endif
-#else
- printf ("%s-${VENDOR}-linuxaout\n", argv[1]);
-#endif
- return 0;
-}
-EOF
eval $set_cc_for_build
- $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #ifdef __INTEL_COMPILER
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ test x"${LIBC}" != x && echo "${UNAME_MACHINE}-${VENDOR}-linux-${LIBC}" | sed 's/linux-gnu/linux/' && exit 0
test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
;;
i*86:DYNIX/ptx:4*:*)
@@ -906,6 +976,23 @@ EOF
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
@@ -927,22 +1014,19 @@ EOF
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
- (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
- (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
- (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit 0 ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -966,9 +1050,15 @@ EOF
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit 0 ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit 0 ;;
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
@@ -985,9 +1075,6 @@ EOF
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
@@ -1059,6 +1146,9 @@ EOF
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit 0 ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
@@ -1066,18 +1156,24 @@ EOF
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Darwin:*:*)
- echo `uname -p`-apple-darwin${UNAME_RELEASE}
+ case `uname -p` in
+ *86) UNAME_PROCESSOR=i686 ;;
+ powerpc) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit 0 ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
- if test "${UNAME_MACHINE}" = "x86pc"; then
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
exit 0 ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit 0 ;;
- NSR-[KW]:NONSTOP_KERNEL:*:*)
+ NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;;
*:NonStop-UX:*:*)
@@ -1100,11 +1196,6 @@ EOF
fi
echo ${UNAME_MACHINE}-unknown-plan9
exit 0 ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit 0 ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
exit 0 ;;
@@ -1123,14 +1214,15 @@ EOF
*:ITS:*:*)
echo pdp10-unknown-its
exit 0 ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
@@ -1245,9 +1337,7 @@ main ()
}
EOF
-eval $set_cc_for_build
-$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
-rm -f $dummy.c $dummy
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
# Apollos put the system type in the environment.
diff --git a/config.sub b/config.sub
index 83f4b0151e0..9952c14c714 100755
--- a/config.sub
+++ b/config.sub
@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-timestamp='2001-08-13'
+timestamp='2003-07-04'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -29,7 +29,8 @@ timestamp='2001-08-13'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
-# Please send patches to <config-patches@gnu.org>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@@ -117,7 +118,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+ nto-qnx* | linux-gnu* | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -226,31 +227,44 @@ case $basic_machine in
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
- | d10v | d30v | dsp16xx \
- | fr30 \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
+ | ip2k \
| m32r | m68000 | m68k | m88k | mcore \
- | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
- | mips64vr4100 | mips64vr4100el | mips64vr4300 \
- | mips64vr4300el | mips64vr5000 | mips64vr5000el \
- | mipsbe | mipsel | mipsle | mipstx39 | mipstx39el \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
| mn10200 | mn10300 \
+ | msp430 \
| ns16k | ns32k \
- | openrisc \
+ | openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
- | s390 | s390x \
- | sh | sh[34] | sh[34]eb | shbe | shle \
- | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
+ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
- | tahoe | thumb | tic80 | tron \
- | v850 \
+ | tahoe | thumb | tic4x | tic80 | tron \
+ | v850 | v850e \
| we32k \
- | x86 | xscale \
+ | x86 | xscale | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
@@ -277,38 +291,55 @@ case $basic_machine in
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alphapca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armv*-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* \
| bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c54x-* \
- | clipper-* | cray2-* | cydra-* \
- | d10v-* | d30v-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
| elxsi-* \
- | f30[01]-* | f700-* | fr30-* | fx80-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* \
| m32r-* \
- | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
- | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
- | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipsel-* \
- | mipsle-* | mipstx39-* | mipstx39el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | msp430-* \
+ | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
- | s390-* | s390x-* \
- | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
- | sparc-* | sparc64-* | sparc86x-* | sparclite-* \
- | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \
- | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
- | v850-* | vax-* \
+ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
+ | v850-* | v850e-* | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+ | xtensa-* \
| ymp-* \
| z8k-*)
;;
@@ -342,6 +373,9 @@ case $basic_machine in
basic_machine=a29k-none
os=-bsd
;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@@ -373,6 +407,10 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -393,16 +431,8 @@ case $basic_machine in
basic_machine=c38-convex
os=-bsd
;;
- cray | ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- cray2)
- basic_machine=cray2-cray
- os=-unicos
- ;;
- [cjt]90)
- basic_machine=${basic_machine}-cray
+ cray | j90)
+ basic_machine=j90-cray
os=-unicos
;;
crds | unos)
@@ -417,6 +447,14 @@ case $basic_machine in
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
@@ -597,12 +635,6 @@ case $basic_machine in
basic_machine=m68k-atari
os=-mint
;;
- mipsel*-linux*)
- basic_machine=mipsel-unknown
- ;;
- mips*-linux*)
- basic_machine=mips-unknown
- ;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
@@ -617,6 +649,10 @@ case $basic_machine in
basic_machine=m68k-rom68k
os=-coff
;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -689,6 +725,10 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
+ nv1)
+ basic_machine=nv1-cray
+ os=-unicosmp
+ ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -696,6 +736,10 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
+ or32 | or32-*)
+ basic_machine=or32-unknown
+ os=-coff
+ ;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
@@ -718,51 +762,55 @@ case $basic_machine in
pbb)
basic_machine=m68k-tti
;;
- pc532 | pc532-*)
+ pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
- pentium | p5 | k5 | k6 | nexgen)
+ pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
- pentiumpro | p6 | 6x86 | athlon)
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
- pentiumii | pentium2)
+ pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-*)
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
- pentiumii-* | pentium2-*)
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
- ;;
- ppc64) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
- ;;
+ ;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
- ;;
+ ;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
- ;;
+ ;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
@@ -783,10 +831,26 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
sequent)
basic_machine=i386-sequent
;;
@@ -794,7 +858,10 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
- sparclite-wrs)
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@@ -861,19 +928,35 @@ case $basic_machine in
os=-dynix
;;
t3e)
- basic_machine=t3e-cray
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
tower | tower-32)
basic_machine=m68k-ncr
;;
@@ -898,8 +981,8 @@ case $basic_machine in
os=-vms
;;
vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
+ basic_machine=f301-fujitsu
+ ;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -920,17 +1003,13 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
- windows32)
- basic_machine=i386-pc
- os=-windows32-msvcrt
+ xps | xps100)
+ basic_machine=xps100-honeywell
;;
- xmp)
- basic_machine=xmp-cray
+ ymp)
+ basic_machine=ymp-cray
os=-unicos
;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
@@ -951,16 +1030,6 @@ case $basic_machine in
op60c)
basic_machine=hppa1.1-oki
;;
- mips)
- case $os in
- linux*)
- basic_machine=mips-unknown
- ;;
- *)
- basic_machine=mips-mips
- ;;
- esac
- ;;
romp)
basic_machine=romp-ibm
;;
@@ -980,13 +1049,16 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh3 | sh4 | sh3eb | sh4eb)
+ sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
- cydra)
+ cydra)
basic_machine=cydra-cydrome
;;
orion)
@@ -1001,10 +1073,6 @@ case $basic_machine in
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
- c4x*)
- basic_machine=c4x-none
- os=-coff
- ;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
@@ -1060,17 +1128,19 @@ case $os in
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux* | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos*)
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1082,8 +1152,10 @@ case $os in
;;
esac
;;
+ -nto-qnx*)
+ ;;
-nto*)
- os=-nto-qnx
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
@@ -1119,14 +1191,20 @@ case $os in
-acis*)
os=-aos
;;
+ -atheos*)
+ os=-atheos
+ ;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
-ns2 )
- os=-nextstep2
+ os=-nextstep2
;;
-nsk*)
os=-nsk
@@ -1165,8 +1243,14 @@ case $os in
-xenix)
os=-xenix
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
;;
-none)
;;
@@ -1199,10 +1283,14 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
- pdp11-*)
+ pdp11-*)
os=-none
;;
*-dec | vax-*)
@@ -1229,6 +1317,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
+ or32-*)
+ os=-coff
+ ;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
@@ -1292,19 +1383,19 @@ case $basic_machine in
*-next)
os=-nextstep3
;;
- *-gould)
+ *-gould)
os=-sysv
;;
- *-highlevel)
+ *-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
- *-sgi)
+ *-sgi)
os=-irix
;;
- *-siemens)
+ *-siemens)
os=-sysv4
;;
*-masscomp)
@@ -1376,7 +1467,7 @@ case $basic_machine in
-ptx*)
vendor=sequent
;;
- -vxsim* | -vxworks*)
+ -vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
diff --git a/configure.in b/configure.in
index 8ed84e8058a..86a3daf84da 100644
--- a/configure.in
+++ b/configure.in
@@ -4,17 +4,17 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
-AM_INIT_AUTOMAKE(mysql, 3.23.59)
+AM_INIT_AUTOMAKE(mysql, 4.0.18)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
DOT_FRM_VERSION=6
# See the libtool docs for information on how to do shared lib versions.
-SHARED_LIB_VERSION=10:0:0
+SHARED_LIB_VERSION=12:0:0
# Set all version vars based on $VERSION. How do we do this more elegant ?
# Remember that regexps needs to quote [ and ] since this is run through m4
-MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|-.*$||"`
+MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[[a-z]]*-.*$||"`
MYSQL_BASE_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|\.[[^.]]*$||"`
F_PART=`echo $MYSQL_BASE_VERSION | sed -e "s|\.||g"| sed -e "s|[a-zA-Z]\+||"|sed -e "s|^\(..\)$|\\10|"`
L_PART=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|^[[0-9]]\.[[0-9]]*\.||" | sed -e "s|^\(.\)$|0\\1|" | sed -e "s|[[a-z]]||"`
@@ -37,9 +37,18 @@ rm -f $AVAILABLE_LANGUAGES_ERRORS_RULES
for i in $AVAILABLE_LANGUAGES
do
AVAILABLE_LANGUAGES_ERRORS="$AVAILABLE_LANGUAGES_ERRORS $i/errmsg.sys"
+ case $host_os in
+ netware* | modesto*)
+ echo "$i/errmsg.sys: $i/errmsg.txt
+ \$(top_builddir)/extra/comp_err.linux \$^ $i/errmsg.sys" \
+ >> $AVAILABLE_LANGUAGES_ERRORS_RULES
+ ;;
+ *)
echo "$i/errmsg.sys: $i/errmsg.txt
\$(top_builddir)/extra/comp_err \$^ $i/errmsg.sys" \
>> $AVAILABLE_LANGUAGES_ERRORS_RULES
+ ;;
+ esac
done
#####
@@ -72,12 +81,14 @@ case $MACHINE_TYPE in
esac
# Save some variables and the command line options for mysqlbug
+SAVE_ASFLAGS="$ASFLAGS"
SAVE_CFLAGS="$CFLAGS"
SAVE_CXXFLAGS="$CXXFLAGS"
SAVE_LDFLAGS="$LDFLAGS"
SAVE_CXXLDFLAGS="$CXXLDFLAGS"
CONF_COMMAND="$0 $ac_configure_args"
AC_SUBST(CONF_COMMAND)
+AC_SUBST(SAVE_ASFLAGS)
AC_SUBST(SAVE_CFLAGS)
AC_SUBST(SAVE_CXXFLAGS)
AC_SUBST(SAVE_LDFLAGS)
@@ -127,18 +138,38 @@ AC_PROG_CXX
AC_PROG_CPP
# Print version of CC and CXX compiler (if they support --version)
-CC_VERSION=`$CC --version`
+case $SYSTEM_TYPE in
+ *netware*)
+CC_VERSION=`$CC -version | grep -i version`
+ ;;
+ *)
+CC_VERSION=`$CC --version | sed 1q`
+ ;;
+esac
if test $? -eq "0"
then
AC_MSG_CHECKING("C Compiler version");
AC_MSG_RESULT("$CC $CC_VERSION")
+else
+CC_VERSION=""
fi
-CXX_VERSION=`$CXX --version`
+case $SYSTEM_TYPE in
+ *netware*)
+CXX_VERSION=`$CXX -version | grep -i version`
+ ;;
+ *)
+CXX_VERSION=`$CXX --version | sed 1q`
+ ;;
+esac
if test $? -eq "0"
then
AC_MSG_CHECKING("C++ compiler version");
AC_MSG_RESULT("$CXX $CXX_VERSION")
+else
+CXX_VERSION=""
fi
+AC_SUBST(CXX_VERSION)
+AC_SUBST(CC_VERSION)
# Fix for sgi gcc / sgiCC which tries to emulate gcc
if test "$CC" = "sgicc"
@@ -177,6 +208,11 @@ AC_CHECK_PROG(DVIS, tex, manual.dvi)
AC_MSG_CHECKING("return type of sprintf")
#check the return type of sprintf
+case $SYSTEM_TYPE in
+ *netware*)
+ AC_DEFINE(SPRINTF_RETURNS_INT) AC_MSG_RESULT("int")
+ ;;
+ *)
AC_TRY_RUN([
int main()
{
@@ -196,11 +232,13 @@ AC_DEFINE(SPRINTF_RETURNS_INT) AC_MSG_RESULT("int"),
char buf[6];
if((char*)sprintf(buf,s) == buf + strlen(s))
return 0;
- return -1;
+ return -1;
}
], AC_DEFINE(SPRINTF_RETURNS_PTR) AC_MSG_RESULT("ptr"),
AC_DEFINE(SPRINTF_RETURNS_GARBAGE) AC_MSG_RESULT("garbage")))
-
+ ;;
+esac
+
# option, cache_name, variable,
# code to execute if yes, code to exectute if fail
@@ -323,7 +361,7 @@ then
# we will gets some problems when linking static programs.
# The following code is used to fix this problem.
- if test "$CXX" = "gcc"
+ if test "$CXX" = "gcc" -o "$CXX" = "ccache gcc"
then
if $CXX -v 2>&1 | grep 'version 3' > /dev/null 2>&1
then
@@ -352,10 +390,12 @@ dnl Find paths to some shell programs
AC_PATH_PROG(LN, ln, ln)
# This must be able to take a -f flag like normal unix ln.
AC_PATH_PROG(LN_CP_F, ln, ln)
+if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then
# If ln -f does not exists use -s (AFS systems)
if test -n "$LN_CP_F"; then
LN_CP_F="$LN_CP_F -s"
fi
+fi
AC_PATH_PROG(MV, mv, mv)
AC_PATH_PROG(RM, rm, rm)
@@ -420,6 +460,9 @@ else
*cygwin*)
FIND_PROC="$PS -e | grep mysqld | grep \" \$\$PID \" > /dev/null"
;;
+ *netware* | *modesto*)
+ FIND_PROC=
+ ;;
*)
AC_MSG_ERROR([Could not find the right ps switches. Which OS is this ?. See the Installation chapter in the Reference Manual.])
esac
@@ -602,8 +645,9 @@ AC_ARG_ENABLE(assembler,
AC_MSG_CHECKING(if we should use assembler functions)
# For now we only support assembler on i386 and sparc systems
AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386")
-AM_CONDITIONAL(ASSEMBLER_sparc, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparc")
-AM_CONDITIONAL(ASSEMBLER, test "$ASSEMBLER_x86_TRUE" = "" -o "$ASSEMBLER_sparc_TRUE" = "")
+AM_CONDITIONAL(ASSEMBLER_sparc32, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparc")
+AM_CONDITIONAL(ASSEMBLER_sparc64, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparcv9")
+AM_CONDITIONAL(ASSEMBLER, test "$ASSEMBLER_x86_TRUE" = "" -o "$ASSEMBLER_sparc32_TRUE" = "")
if test "$ASSEMBLER_TRUE" = ""
then
@@ -657,7 +701,7 @@ AC_ARG_WITH(mysqld-user,
AC_SUBST(MYSQLD_USER)
# If we should allow LOAD DATA LOCAL
-AC_MSG_CHECKING(if we should should enable LOAD DATA LOCAL by default)
+AC_MSG_CHECKING(If we should should enable LOAD DATA LOCAL by default)
AC_ARG_ENABLE(local-infile,
[ --enable-local-infile Enable LOAD DATA LOCAL INFILE (default: disabled)],
[ ENABLED_LOCAL_INFILE=$enableval ],
@@ -671,7 +715,6 @@ else
AC_MSG_RESULT([no])
fi
-# Use Paul Eggerts macros from GNU tar to check for large file support.
MYSQL_SYS_LARGEFILE
# Types that must be checked AFTER large file support is checked
@@ -690,7 +733,7 @@ AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \
strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
- sys/ioctl.h)
+ sys/ioctl.h malloc.h sys/malloc.h linux/config.h)
#--------------------------------------------------------------------
# Check for system libraries. Adds the library to $LIBS
@@ -714,7 +757,7 @@ AC_CHECK_LIB(crypt, crypt)
AC_CHECK_FUNC(crypt, AC_DEFINE(HAVE_CRYPT))
# For sem_xxx functions on Solaris 2.6
-AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4))
+AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4, sem_init))
# For compress in zlib
MYSQL_CHECK_ZLIB_WITH_COMPRESS($with_named_zlib)
@@ -793,7 +836,46 @@ int main()
if test -z "$atom_ops"; then atom_ops="no"; fi
AC_MSG_RESULT($atom_ops)
+
+ AC_ARG_WITH(pstack,
+ [ --with-pstack Use the pstack backtrace library],
+ [ USE_PSTACK=$withval ],
+ [ USE_PSTACK=no ])
+ pstack_libs=
+ pstack_dirs=
+ if test "$USE_PSTACK" = yes -a "$IS_LINUX" = "true" -a "$BASE_MACHINE_TYPE" = "i386" -a "$with_mit_threads" = "no"
+ then
+ have_libiberty= have_libbfd=
+ my_save_LIBS="$LIBS"
+dnl I have no idea if this is a good test - can not find docs for libiberty
+ AC_CHECK_LIB([iberty], [fdmatch],
+ [have_libiberty=yes
+ AC_CHECK_LIB([bfd], [bfd_openr], [have_libbfd=yes], , [-liberty])])
+ LIBS="$my_save_LIBS"
+
+ if test x"$have_libiberty" = xyes -a x"$have_libbfd" = xyes
+ then
+ pstack_dirs='$(top_srcdir)'/pstack
+ pstack_libs="../pstack/libpstack.a -lbfd -liberty"
+ # We must link staticly when using pstack
+ with_mysqld_ldflags="-all-static"
+ AC_SUBST([pstack_dirs])
+ AC_SUBST([pstack_libs])
+ AC_DEFINE([USE_PSTACK])
+dnl This check isn't needed, but might be nice to give some feedback....
+dnl AC_CHECK_HEADER(libiberty.h,
+dnl have_libiberty_h=yes,
+dnl have_libiberty_h=no)
+ else
+ USE_PSTACK="no"
+ fi
+ else
+ USE_PSTACK="no"
+ fi
fi
+AM_CONDITIONAL(COMPILE_PSTACK, test "$USE_PSTACK" = "yes")
+AC_MSG_CHECKING([if we should use pstack])
+AC_MSG_RESULT([$USE_PSTACK])
# Check for gtty if termio.h doesn't exists
if test "$ac_cv_header_termio_h" = "no" -a "$ac_cv_header_termios_h" = "no"
@@ -805,6 +887,11 @@ fi
NON_THREADED_CLIENT_LIBS="$LIBS"
AC_MSG_CHECKING([for int8])
+case $SYSTEM_TYPE in
+ *netware)
+ AC_MSG_RESULT([no])
+ ;;
+ *)
AC_TRY_RUN([
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@@ -825,12 +912,15 @@ int main()
}
], AC_DEFINE(HAVE_INT_8_16_32) AC_MSG_RESULT([yes]), AC_MSG_RESULT([no])
)
+ ;;
+esac
#
# Some system specific hacks
#
MAX_C_OPTIMIZE="-O3"
+MAX_CXX_OPTIMIZE="-O3"
case $SYSTEM_TYPE in
*solaris2.7*)
@@ -876,8 +966,8 @@ case $SYSTEM_TYPE in
;;
*hpux10.20*)
echo "Enabling workarounds for hpux 10.20"
- CFLAGS="$CFLAGS -DHAVE_BROKEN_SNPRINTF -DSIGNALS_DONT_BREAK_READ -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHPUX -DSIGNAL_WITH_VIO_CLOSE -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT -DHAVE_POSIX1003_4a_MUTEX"
- CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_SNPRINTF -D_INCLUDE_LONGLONG -DSIGNALS_DONT_BREAK_READ -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHPUX -DSIGNAL_WITH_VIO_CLOSE -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT -DHAVE_POSIX1003_4a_MUTEX"
+ CFLAGS="$CFLAGS -DHAVE_BROKEN_SNPRINTF -DSIGNALS_DONT_BREAK_READ -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHPUX10 -DSIGNAL_WITH_VIO_CLOSE -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT -DHAVE_POSIX1003_4a_MUTEX"
+ CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_SNPRINTF -D_INCLUDE_LONGLONG -DSIGNALS_DONT_BREAK_READ -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHPUX10 -DSIGNAL_WITH_VIO_CLOSE -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT -DHAVE_POSIX1003_4a_MUTEX"
if test "$with_named_thread" = "no"
then
echo "Using --with-named-thread=-lpthread"
@@ -886,8 +976,8 @@ case $SYSTEM_TYPE in
;;
*hpux11.*)
echo "Enabling workarounds for hpux 11"
- CFLAGS="$CFLAGS -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -DHAVE_BROKEN_GETPASS -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
- CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -D_INCLUDE_LONGLONG -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
+ CFLAGS="$CFLAGS -DHPUX11 -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -DHAVE_BROKEN_GETPASS -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
+ CXXFLAGS="$CXXFLAGS -DHPUX11 -DHAVE_BROKEN_PREAD -DDONT_USE_FINITE -D_INCLUDE_LONGLONG -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
if test "$with_named_thread" = "no"
then
echo "Using --with-named-thread=-lpthread"
@@ -896,8 +986,10 @@ case $SYSTEM_TYPE in
# Fixes for HPUX 11.0 compiler
if test "$ac_cv_prog_gcc" = "no"
then
- CFLAGS="$CFLAGS +DD64 -DHAVE_BROKEN_INLINE"
- CXXFLAGS="$CXXFLAGS +DD64 +O2"
+ CFLAGS="$CFLAGS -DHAVE_BROKEN_INLINE"
+ CXXFLAGS="$CXXFLAGS +O2"
+ MAX_C_OPTIMIZE=""
+ MAX_CXX_OPTIMIZE=""
fi
;;
*rhapsody*)
@@ -915,8 +1007,9 @@ case $SYSTEM_TYPE in
*darwin5*)
if test "$ac_cv_prog_gcc" = "yes"
then
- CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH -DFN_NO_CASE_SENCE"
- CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DFN_NO_CASE_SENCE"
+ FLAGS="-traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH -DFN_NO_CASE_SENCE"
+ CFLAGS="$CFLAGS $FLAGS"
+ CXXFLAGS="$CXXFLAGS $FLAGS"
MAX_C_OPTIMIZE="-O"
with_named_curses=""
fi
@@ -924,15 +1017,24 @@ case $SYSTEM_TYPE in
*darwin6*)
if test "$ac_cv_prog_gcc" = "yes"
then
- CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH -DFN_NO_CASE_SENCE"
- CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DFN_NO_CASE_SENCE"
+ FLAGS="-DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH -DFN_NO_CASE_SENCE"
+ CFLAGS="$CFLAGS $FLAGS"
+ CXXFLAGS="$CXXFLAGS $FLAGS"
MAX_C_OPTIMIZE="-O"
fi
;;
*freebsd*)
echo "Adding fix for interrupted reads"
- CFLAGS="$CFLAGS -DHAVE_BROKEN_REALPATH"
- CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000 -DHAVE_BROKEN_REALPATH"
+ OSVERSION=`sysctl -a | grep osreldate | awk '{ print $2 }'`
+ if test "$OSVERSION" -gt "480100" && \
+ test "$OSVERSION" -lt "500000" || \
+ test "$OSVERSION" -gt "500109"
+ then
+ CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000"
+ else
+ CFLAGS="$CFLAGS -DHAVE_BROKEN_REALPATH"
+ CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000 -DHAVE_BROKEN_REALPATH"
+ fi
;;
*netbsd*)
echo "Adding flag -Dunix"
@@ -951,7 +1053,7 @@ case $SYSTEM_TYPE in
echo "Using --with-named-thread=-lpthread"
with_named_thread="-lpthread"
fi
- CXXFLAGS="-D_BOOL"
+ CXXFLAGS="$CXXFLAGS -D_BOOL"
;;
*aix4.3*)
echo "Adding defines for AIX"
@@ -971,6 +1073,110 @@ dnl Is this the right match for DEC OSF on alpha?
CFLAGS="$CFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
CXXFLAGS="$CXXFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
;;
+ *netware*)
+ # No need for curses library so set it to null
+ with_named_curses=""
+
+ # No thread library - in LibC
+ with_named_thread=""
+
+ #
+ # Edit Makefile.in files.
+ #
+ echo -n "configuring Makefile.in files for NetWare... "
+ for file in sql/Makefile.in libmysql/Makefile.in libmysql_r/Makefile.in sql/share/Makefile.in strings/Makefile.in client/Makefile.in
+ do
+ # echo "#### $file ####"
+ filedir="`dirname $file`"
+ filebase="`basename $file`"
+ filesed=$filedir/$filebase.sed
+ #
+ # Backup and always use original file
+ #
+ if test -f $file.bk
+ then
+ cp -fp $file.bk $file
+ else
+ cp -fp $file $file.bk
+ fi
+ case $file in
+ sql/Makefile.in)
+ # Use gen_lex_hash.linux instead of gen_lex_hash
+ # Add library dependencies to mysqld_DEPENDENCIES
+ lib_DEPENDENCIES="\$(bdb_libs_with_path) \$(innodb_libs) \$(pstack_libs) \$(innodb_system_libs) \$(openssl_libs)"
+ cat > $filesed << EOF
+s,\(^.*\$(MAKE) gen_lex_hash\),#\1,
+s,\(\./gen_lex_hash\),\1.linux,
+s%\(mysqld_DEPENDENCIES = \) %\1$lib_DEPENDENCIES %
+EOF
+ ;;
+ sql/share/Makefile.in)
+ cat > $filesed << EOF
+s,\(extra/comp_err\),\1.linux,
+EOF
+ ;;
+ libmysql/Makefile.in)
+ cat > $filesed << EOF
+s,\(\./conf_to_src\)\( \$(top_srcdir)\),\1.linux\2,
+s,\(: conf_to_src\),\1.linux,
+EOF
+ ;;
+ libmysql_r/Makefile.in)
+ cat > $filesed << EOF
+s,\(\./conf_to_src\)\( \$(top_srcdir)\),\1.linux\2,
+s,\(: conf_to_src\),\1.linux,
+EOF
+ ;;
+ strings/Makefile.in)
+ cat > $filesed << EOF
+s,\(\./conf_to_src\)\( \$(top_srcdir)\),\1.linux\2,
+s,\(: conf_to_src\),\1.linux,
+EOF
+ ;;
+ client/Makefile.in)
+ #
+ cat > $filesed << EOF
+s,libmysqlclient.la,.libs/libmysqlclient.a,
+EOF
+ ;;
+ esac
+ if `sed -f $filesed $file > $file.nw`;\
+ then
+ mv -f $file.nw $file
+ rm -f $filesed
+ else
+ exit 1
+ fi
+ # wait for file system changes to complete
+ sleep 1
+ done
+ echo "done"
+
+ #
+ # Make sure the following files are writable.
+ #
+ # When the files are retrieved from some source code control systems they are read-only.
+ #
+ echo -n "making sure specific build files are writable... "
+ for file in \
+ Docs/include.texi \
+ Docs/mysql.info \
+ Docs/manual.txt \
+ Docs/manual_toc.html \
+ Docs/manual.html \
+ Docs/INSTALL-BINARY \
+ INSTALL-SOURCE \
+ COPYING \
+ COPYING.LIB \
+ MIRRORS
+ do
+ if test -e $file; then
+ chmod +w $file
+ fi
+ done
+ echo "done"
+
+ ;;
esac
@@ -1010,7 +1216,8 @@ Reference Manual for more information.])
if test -f /usr/shlib/libpthread.so -a -f /usr/lib/libmach.a -a -f /usr/ccs/lib/cmplrs/cc/libexc.a
then
with_named_thread="-lpthread -lmach -lexc"
- #with_named_thread="-lpthread -lmach -lexc -lc"
+ CFLAGS="$CFLAGS -D_REENTRANT"
+ CXXFLAGS="$CXXFLAGS -D_REENTRANT"
AC_DEFINE(HAVE_DEC_THREADS)
AC_MSG_RESULT("yes")
else
@@ -1075,12 +1282,12 @@ then
AC_MSG_ERROR([On SCO UNIX MySQL must be compiled with gcc. See the Installation chapter in the Reference Manual.]);
fi
AC_MSG_RESULT("yes")
- # Hack for SCO UnixWare 7.1
+ # Hack for SCO UnixWare 7.1.x
#
elif test "$with_named_thread" = "no"
then
AC_MSG_RESULT("no")
- AC_MSG_CHECKING("SCO UnixWare 7.1 native threads")
+ AC_MSG_CHECKING("SCO UnixWare 7.1.x native threads")
if expr "$SYSTEM_TYPE" : ".*sco.*" > /dev/null
then
if test -f /usr/lib/libthread.so -o -f /usr/lib/libthreadT.so
@@ -1103,11 +1310,11 @@ then
AC_MSG_CHECKING("for gcc")
if expr "$CC" : ".*gcc.*"
then
- CC="$CC -pthread -DUNIXWARE_7";
- CXX="$CXX -pthread -DUNIXWARE_7";
+ CC="$CC -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
+ CXX="$CXX -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
else
- CC="$CC -Kthread -DUNIXWARE_7";
- CXX="$CXX -Kthread -DUNIXWARE_7";
+ CC="$CC -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
+ CXX="$CXX -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
fi
else
{ echo "configure: error: Can't find thread libs on SCO UnixWare7. See the Installation chapter in the Reference Manual." 1>&2; exit 1; };
@@ -1132,7 +1339,12 @@ then
if test -f /usr/lib/libthread.so -o -f /usr/lib/libthreadT.so
then
MYSQL_REMOVE_SOCKET_FROM_LIBS_HACK
- with_named_thread="-Kthread -lsocket -lnsl"
+ if expr "$CC" : ".*gcc.*"
+ then
+ with_named_thread="-pthread -lsocket -lnsl"
+ else
+ with_named_thread="-Kthread -lsocket -lnsl"
+ fi
if expr "$SYSTEM_TYPE" : ".*unixware7.0.0" > /dev/null
then
AC_DEFINE(HAVE_UNIXWARE7_THREADS)
@@ -1143,10 +1355,11 @@ then
AC_MSG_CHECKING("for gcc")
if expr "$CC" : ".*gcc.*"
then
- { echo "configure: error: On SCO UnixWare7 MySQL must be compiled with cc. See the Installation chapter in the Reference Manual." 1>&2; exit 1; };
+ CC="$CC -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
+ CXX="$CXX -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
else
- CC="$CC -Kthread -DUNIXWARE_7";
- CXX="$CXX -Kthread -DUNIXWARE_7";
+ CC="$CC -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
+ CXX="$CXX -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
fi
AC_MSG_RESULT("yes")
else
@@ -1167,7 +1380,12 @@ then
if test -f /usr/lib/libthread.so -o -f /usr/lib/libthreadT.so
then
MYSQL_REMOVE_SOCKET_FROM_LIBS_HACK
- with_named_thread="-Kthread -lsocket -lnsl"
+ if expr "$CC" : ".*gcc.*"
+ then
+ with_named_thread="-pthread -lsocket -lnsl"
+ else
+ with_named_thread="-Kthread -lsocket -lnsl"
+ fi
if expr "$SYSTEM_TYPE" : ".*unixware7.0.0" > /dev/null
then
AC_DEFINE(HAVE_UNIXWARE7_THREADS)
@@ -1178,7 +1396,8 @@ then
AC_MSG_CHECKING("for gcc")
if expr "$CC" : ".*gcc.*"
then
- { echo "configure: error: On OpenUNIX8 and UnixWare7 MySQL must be compiled with cc. See the Installation chapter in the Reference Manual." 1>&2; exit 1; };
+ CC="$CC -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
+ CXX="$CXX -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
else
CC="$CC -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
CXX="$CXX -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK";
@@ -1233,11 +1452,14 @@ then
fi
fi
+TOOLS_LIBS="$NON_THREADED_CLIENT_LIBS"
+
# Should we use named pthread library ?
AC_MSG_CHECKING("named thread libs:")
if test "$with_named_thread" != "no"
then
LIBS="$with_named_thread $LIBS $with_named_thread"
+ TOOLS_LIBS="$with_named_thread $TOOLS_LIBS $with_named_thread"
with_posix_threads="yes"
with_mit_threads="no"
AC_MSG_RESULT("$with_named_thread")
@@ -1256,7 +1478,9 @@ else
then
AC_MSG_CHECKING("for pthread_create in -lpthread");
ac_save_LIBS="$LIBS"
+ ac_save_TOOLS_LIBS="$TOOLS_LIBS"
LIBS="$LIBS -lpthread"
+ TOOLS_LIBS="$TOOLS_LIBS -lpthread"
AC_TRY_LINK(
[#include <pthread.h>],
[ (void) pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0); ],
@@ -1265,6 +1489,7 @@ else
if test "$with_posix_threads" = "no"
then
LIBS=" $ac_save_LIBS -lpthreads"
+ TOOLS_LIBS=" $ac_save_TOOLS_LIBS -lpthreads"
AC_MSG_CHECKING("for pthread_create in -lpthreads");
AC_TRY_LINK(
[#include <pthread.h>],
@@ -1275,6 +1500,7 @@ else
then
# This is for FreeBSD
LIBS="$ac_save_LIBS -pthread"
+ TOOLS_LIBS="$ac_save_TOOLS_LIBS -pthread"
AC_MSG_CHECKING("for pthread_create in -pthread");
AC_TRY_LINK(
[#include <pthread.h>],
@@ -1285,6 +1511,7 @@ else
then
with_mit_threads="yes"
LIBS="$ac_save_LIBS"
+ TOOLS_LIBS="$ac_save_TOOLS_LIBS"
fi
fi
fi
@@ -1301,11 +1528,11 @@ AC_CHECK_LIB(pthread,strtok_r)
LIBS="$my_save_LIBS"
if test "$ac_cv_lib_pthread_strtok_r" = "no"
then
- my_save_LIBS="$LIBS"
AC_CHECK_LIB(c_r,strtok_r)
case "$with_osf32_threads---$target_os" in
# Don't keep -lc_r in LIBS; -pthread handles it magically
- yes---* | *---freebsd* ) LIBS="$my_save_LIBS" ;;
+ yes---* | *---freebsd* | *---hpux*) LIBS="$my_save_LIBS" ;;
+
esac
AC_CHECK_FUNCS(strtok_r pthread_init)
else
@@ -1325,7 +1552,12 @@ LIBS="$my_save_LIBS"
AC_SUBST(LIBDL)
# System characteristics
+case $SYSTEM_TYPE in
+ *netware* | *modesto*) ;;
+ *)
AC_SYS_RESTARTABLE_SYSCALLS
+ ;;
+esac
# Build optimized or debug version ?
# First check for gcc and g++
@@ -1343,13 +1575,20 @@ if test "$ac_cv_prog_cxx_g" = "yes"
then
DEBUG_CXXFLAGS="-g"
DEBUG_OPTIMIZE_CXX="-O"
- OPTIMIZE_CXXFLAGS="-O3"
+ OPTIMIZE_CXXFLAGS="$MAX_CXX_OPTIMIZE"
else
DEBUG_CXXFLAGS="-g"
DEBUG_OPTIMIZE_CXX=""
OPTIMIZE_CXXFLAGS="-O"
fi
+if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then
+ DEBUG_CFLAGS="$DEBUG_CFLAGS -DDEBUG -sym internal,codeview4"
+ DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -DDEBUG -sym internal,codeview4"
+ OPTIMIZE_CFLAGS="$OPTIMIZE_CFLAGS -DNDEBUG"
+ OPTIMIZE_CXXFLAGS="$OPTIMIZE_CXXFLAGS -DNDEBUG"
+fi
+
AC_ARG_WITH(debug,
[ --without-debug Build a production version without debugging code],
[with_debug=$withval],
@@ -1449,6 +1688,7 @@ install the static libraries and try again. If this isn't the problem,
examine config.log for possible errors. If you want to report this, use
'scripts/mysqlbug' and include at least the last 20 rows from config.log!])
fi
+AC_CHECK_SIZEOF(char*, 4)
AC_CHECK_SIZEOF(int, 4)
if test "$ac_cv_sizeof_int" -eq 0
then
@@ -1491,11 +1731,14 @@ MYSQL_CHECK_ULONG
MYSQL_CHECK_UCHAR
# Do the system files define uint
MYSQL_CHECK_UINT
-#Check for fp_except in ieeefp.h
+# Check for fp_except in ieeefp.h
MYSQL_CHECK_FP_EXCEPT
+# Check for IN_ADDR_T
+MYSQL_CHECK_IN_ADDR_T
# Do the c++ compiler have a bool type
MYSQL_CXX_BOOL
# Check some common bugs with gcc 2.8.# on sparc
+if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then
MYSQL_CHECK_LONGLONG_TO_FLOAT
if test "$ac_cv_conv_longlong_to_float" != "yes"
then
@@ -1503,6 +1746,7 @@ then
If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try
again]);
fi
+fi
MYSQL_PTHREAD_YIELD
######################################################################
@@ -1516,7 +1760,7 @@ AC_SUBST(MAKE_SHELL)
AC_CHECK_HEADERS(varargs.h stdarg.h dirent.h locale.h ndir.h sys/dir.h \
sys/file.h sys/ndir.h sys/ptem.h sys/pte.h sys/select.h sys/stream.h \
sys/mman.h curses.h termcap.h termio.h termbits.h asm/termbits.h grp.h \
-paths.h)
+paths.h semaphore.h)
# Already-done: strcasecmp
AC_CHECK_FUNCS(lstat putenv select setenv setlocale strcoll tcgetattr)
@@ -1541,6 +1785,17 @@ AC_SUBST(TERMCAP_LIB)
#########################################################################
dnl Checks for library functions.
+
+#
+# The following code disables intrinsic function support while we test for
+# library functions. This is to avoid configure problems with Intel ecc
+# compiler
+
+ORG_CFLAGS="$CFLAGS"
+if test "$GCC" != "yes"; then
+ AC_SYS_COMPILER_FLAG(-nolib_inline,nolib_inline,CFLAGS,[],[])
+fi
+
AC_FUNC_MMAP
AC_TYPE_SIGNAL
MYSQL_TYPE_QSORT
@@ -1551,7 +1806,7 @@ AC_CHECK_FUNCS(alarm bmove \
cuserid fcntl fconvert poll \
getrusage getpwuid getcwd getrlimit getwd index stpcpy locking longjmp \
perror pread realpath readlink rename \
- socket strnlen madvise mkstemp \
+ socket strnlen madvise mallinfo mkstemp \
strtol strtoul strtoll strtoull snprintf tempnam thr_setconcurrency \
gethostbyaddr_r gethostbyname_r getpwnam \
bfill bzero bcmp strstr strpbrk strerror \
@@ -1560,8 +1815,11 @@ AC_CHECK_FUNCS(alarm bmove \
sigset sigthreadmask pthread_sigmask pthread_setprio pthread_setprio_np \
pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \
pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \
+ pthread_attr_getstacksize pthread_key_delete \
pthread_condattr_create rwlock_init pthread_rwlock_rdlock \
- fchmod getpass getpassphrase initgroups mlockall)
+ fsync fdatasync fchmod getpass getpassphrase initgroups mlockall)
+
+CFLAGS="$ORG_CFLAGS"
# Sanity check: We chould not have any fseeko symbol unless
# large_file_support=yes
@@ -1586,9 +1844,11 @@ AC_LANG_CPLUSPLUS
# Do not treat warnings as errors if we are linking against other libc
# this is to work around gcc not being permissive on non-system includes
# with respect to ANSI C++
-if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no"
+# We also remove the -fbranch-probabilities option as this will give warnings
+# about not profiled code, which confuses configure
+if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no"
then
- CXXFLAGS="$CXXFLAGS -Werror"
+ CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed 's/-fbranch-probabilities//'`
fi
AC_TRY_COMPILE(
@@ -1622,7 +1882,7 @@ AC_LANG_SAVE
AC_LANG_CPLUSPLUS
if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no"
then
- CXXFLAGS="$CXXFLAGS -Werror"
+ CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed 's/-fbranch-probabilities//'`
fi
AC_TRY_COMPILE(
[#undef inline
@@ -1654,7 +1914,7 @@ AC_LANG_SAVE
AC_LANG_CPLUSPLUS
if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no"
then
- CXXFLAGS="$CXXFLAGS -Werror"
+ CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed 's/-fbranch-probabilities//'`
fi
AC_TRY_COMPILE(
[#undef inline
@@ -1818,6 +2078,59 @@ AC_ARG_WITH(server,
[with_server=yes]
)
+AC_ARG_WITH(embedded-server,
+ [ --with-embedded-server Build the embedded server (libmysqld).],
+ [with_embedded_server=$withval],
+ [with_embedded_server=no]
+)
+
+AC_ARG_WITH(query_cache,
+ [ --without-query-cache Do not build query cache.],
+ [with_query_cache=$withval],
+ [with_query_cache=yes]
+)
+
+if test "$with_query_cache" = "yes"
+then
+ AC_DEFINE(HAVE_QUERY_CACHE)
+fi
+
+AC_ARG_WITH(extra-tools,
+ [ --without-extra-tools Skip building utilites in the tools directory.],
+ [with_tools=$withval],
+ [with_tools=yes]
+)
+
+tools_dirs=""
+if test "$with_tools" = "yes"
+then
+ if test "$THREAD_SAFE_CLIENT" = "no"
+ then
+ echo "Warning: extra-tools disabled because --enable-thread-safe-client wasn't used"
+ else
+ tools_dirs="tools"
+ fi
+fi
+AC_SUBST(tools_dirs)
+
+#MYSQL_CHECK_CPU
+MYSQL_CHECK_MYSQLFS
+MYSQL_CHECK_VIO
+MYSQL_CHECK_OPENSSL
+
+libmysqld_dirs=
+if test "$with_embedded_server" = "yes"
+then
+ libmysqld_dirs=libmysqld
+ # We can't build embedded library without building the server, because
+ # we depend on libmysys, libmystrings, libmyisam, etc.
+ with_server=yes
+fi
+# XXX: We need to add @libmysqld_extra_libs@ (or whatever) so that
+# mysql_config --libmysqld-libs will print out something like
+# -L/path/to/lib/mysql -lmysqld -lmyisam -lmysys -lmystrings -ldbug ...
+AC_SUBST([libmysqld_dirs])
+
# Shall we build the docs?
AC_ARG_WITH(docs,
[ --without-docs Skip building of the documentation.],
@@ -1855,6 +2168,11 @@ AC_ARG_WITH(readline,
[ with_readline=$withval ],
[ with_readline=yes ]
)
+if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then
+ # For NetWare, do not need readline
+ readline_dir=""
+ readline_link=""
+else
if test "$with_readline" = "yes"
then
readline_dir="readline"
@@ -1865,6 +2183,7 @@ else
readline_dir=""
readline_link="-lreadline"
fi
+fi
AC_SUBST(readline_dir)
AC_SUBST(readline_link)
@@ -1874,17 +2193,20 @@ dnl If the character set uses strcoll or other special handling,
dnl you must also create strings/ctype-$charset_name.c
AC_DIVERT_PUSH(0)
-CHARSETS_AVAILABLE="big5 cp1251 cp1257 croat czech danish dec8 dos estonia euc_kr gb2312 gbk german1 greek hebrew hp8 hungarian koi8_ru koi8_ukr latin1 latin2 latin5 swe7 usa7 win1250 win1251 win1251ukr ujis sjis tis620"
+CHARSETS_AVAILABLE="big5 cp1251 cp1257
+ croat czech danish dec8 dos estonia euc_kr gb2312 gbk
+ german1 greek hebrew hp8 hungarian koi8_ru koi8_ukr
+ latin1 latin1_de latin2 latin5 sjis swe7 tis620 ujis
+ usa7 win1250 win1251ukr"
+CHARSETS_DEPRECATED="win1251"
DEFAULT_CHARSET=latin1
AC_DIVERT_POP
-dnl win1251 is deprecated - it's available, but not listed here in the help
+dnl fix this later..
+dnl [ --with-charset=CHARSET Use CHARSET by default (one of: $CHARSETS_AVAILABLE; Default is $DEFAULT_CHARSET)],
+
AC_ARG_WITH(charset,
- [ --with-charset=CHARSET Use CHARSET by default (one of: big5 cp1251 cp1257
- croat czech danish dec8 dos estonia euc_kr gb2312 gbk
- german1 greek hebrew hp8 hungarian koi8_ru koi8_ukr
- latin1 latin2 latin5 swe7 usa7 win1250 win1251ukr
- ujis sjis tis620; Default is latin1)],
+ [ --with-charset=CHARSET Use CHARSET by default (Default is latin1)],
[default_charset="$withval"],
[default_charset="$DEFAULT_CHARSET"])
@@ -1897,7 +2219,9 @@ AC_ARG_WITH(extra-charsets,
AC_MSG_CHECKING("character sets")
-if test "$extra_charsets" = none; then
+if test "$extra_charsets" = no; then
+ CHARSETS=""
+elif test "$extra_charsets" = none; then
CHARSETS=""
elif test "$extra_charsets" = complex; then
CHARSETS=`/bin/ls -1 $srcdir/strings/ctype-*.c | \
@@ -1905,7 +2229,7 @@ elif test "$extra_charsets" = complex; then
CHARSETS=`echo $CHARSETS` # get rid of line breaks
else
if test "$extra_charsets" = all; then
- CHARSETS="$CHARSETS_AVAILABLE"
+ CHARSETS="$CHARSETS_AVAILABLE $CHARSETS_DEPRECATED"
else
CHARSETS=`echo $extra_charsets | sed -e 's/,/ /g'`
fi
@@ -1926,13 +2250,13 @@ CHARSETS=$TMP_CHARSETS
for cs in $CHARSETS
do
charset_okay=0
- for charset in $CHARSETS_AVAILABLE
+ for charset in $CHARSETS_AVAILABLE $CHARSETS_DEPRECATED
do
if test $cs = $charset; then charset_okay=1; fi
done
if test $charset_okay = 0;
then
- AC_MSG_ERROR([Charset $cs not available. (Available $CHARSETS_AVAILABLE).
+ AC_MSG_ERROR([Charset '$cs' not available. (Available $CHARSETS_AVAILABLE).
See the Installation chapter in the Reference Manual.]);
fi
done
@@ -2037,7 +2361,7 @@ extern int mbcharlen_${c}(uint);"
mbcharlen_${c}"
else
CHARSET_COMP_CS_INIT="$CHARSET_COMP_CS_INIT
- 0, /* mbmaxlen */
+ 1, /* mbmaxlen */
NULL, /* ismbchar */
NULL, /* ismbhead */
NULL /* mbcharlen */"
@@ -2106,9 +2430,9 @@ EOF
AC_MSG_RESULT([default: $default_charset; compiled in: $CHARSETS])
+MYSQL_CHECK_ISAM
MYSQL_CHECK_BDB
MYSQL_CHECK_INNODB
-MYSQL_CHECK_GEMINI
# If we have threads generate some library functions and test programs
sql_server_dirs=
@@ -2133,24 +2457,41 @@ AC_SUBST(CLIENT_LIBS)
AC_SUBST(sql_client_dirs)
AC_SUBST(linked_client_targets)
-if test "$with_server" = "yes" -o "$THREAD_SAFE_CLIENT" != "no"
-then
- AC_DEFINE(THREAD)
+# If configuring for NetWare, set up to link sources from and build the netware directory
+netware_dir=
+linked_netware_sources=
+if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then
+ netware_dir="netware"
+ linked_netware_sources="linked_netware_sources"
fi
+AC_SUBST(netware_dir)
+AC_SUBST(linked_netware_sources)
-if test "$with_server" = "yes"
+if test "$with_server" = "yes" -o "$THREAD_SAFE_CLIENT" != "no"
then
+ AC_DEFINE(THREAD)
# Avoid _PROGRAMS names
- THREAD_LPROGRAMS="test_thr_alarm test_thr_lock"
+ THREAD_LPROGRAMS="test_thr_alarm\$(EXEEXT) test_thr_lock\$(EXEEXT)"
AC_SUBST(THREAD_LPROGRAMS)
THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o"
AC_SUBST(THREAD_LOBJECTS)
- sql_server_dirs="strings dbug mysys extra regex isam merge myisam myisammrg heap sql"
- server_scripts="safe_mysqld mysql_install_db"
+ server_scripts="mysqld_safe mysql_install_db"
+ sql_server_dirs="strings dbug mysys extra regex"
+
+
+ #
+ # Configuration for optional table handlers
+ #
+
+ if test X"$have_isam" != Xno
+ then
+ sql_server_dirs="$sql_server_dirs isam merge"
+ fi
+
if test X"$have_berkeley_db" != Xno; then
if test X"$have_berkeley_db" != Xyes; then
# we must build berkeley db from source
- sql_server_dirs="$have_berkeley_db $sql_server_dirs"
+ sql_server_dirs="$sql_server_dirs $have_berkeley_db"
echo "CONFIGURING FOR BERKELEY DB"
bdb_conf_flags=
@@ -2217,7 +2558,8 @@ EOF
if test X"$have_innodb" = Xyes
then
- sql_server_dirs="innobase $sql_server_dirs"
+ innodb_conf_flags=""
+ sql_server_dirs="$sql_server_dirs innobase"
echo "CONFIGURING FOR INNODB"
if test ! -d "innobase"; then
# This should only happen when doing a VPATH build
@@ -2229,26 +2571,20 @@ EOF
/* ) rel_srcdir="$srcdir" ;;
* ) rel_srcdir="../$srcdir" ;;
esac
- (cd innobase && sh $rel_srcdir/innobase/configure) \
+ if test "x$enable_dependency_tracking" == xno
+ then
+ innodb_conf_flags=--disable-dependency-tracking
+ fi
+ (cd innobase && sh $rel_srcdir/innobase/configure --host=$host $innodb_conf_flags) \
|| AC_MSG_ERROR([could not configure INNODB])
echo "END OF INNODB CONFIGURATION"
fi
+ #
+ # END of configuration for optional table handlers
+ #
+ sql_server_dirs="$sql_server_dirs myisam myisammrg heap vio sql"
- if test "X$have_gemini_db" = "Xyes"; then
- sql_server_dirs="gemini $sql_server_dirs"
- echo "CONFIGURING FOR GEMINI DB"
- (cd gemini && sh ./configure) \
- || AC_MSG_ERROR([could not configure Gemini DB])
-
- echo "END OF GEMINI DB CONFIGURATION"
-
- AC_DEFINE(HAVE_GEMINI_DB)
- fi
-fi
-
-if test "$with_server" = "yes" -o "$THREAD_SAFE_CLIENT" != "no"
-then
if test "$with_posix_threads" = "no" -o "$with_mit_threads" = "yes"
then
# MIT user level threads
@@ -2266,7 +2602,7 @@ then
echo ""
echo "Configuring MIT Pthreads"
# We will never install so installation paths are not needed.
- (cd mit-pthreads; sh ./configure)
+ (cd mit-pthreads && sh ./configure) || exit 1
echo "End of MIT Pthreads configuration"
echo ""
LIBS="$MT_LD_ADD $LIBS"
@@ -2293,20 +2629,35 @@ AC_SUBST(server_scripts)
# Some usefull subst
AC_SUBST(CC)
AC_SUBST(GXX)
+#Remove TOOLS_LIBS, because this is included in LIBRARIES
+#AC_SUBST(TOOLS_LIBS)
+
+# Set configuration options for make_binary_distribution
+case $SYSTEM_TYPE in
+ *netware*)
+ MAKE_BINARY_DISTRIBUTION_OPTIONS=--no-strip
+ ;;
+ *)
+ MAKE_BINARY_DISTRIBUTION_OPTIONS=
+ ;;
+esac
+AC_SUBST(MAKE_BINARY_DISTRIBUTION_OPTIONS)
# Output results
-AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile \
- strings/Makefile regex/Makefile heap/Makefile \
- bdb/Makefile \
- myisam/Makefile myisammrg/Makefile \
- man/Makefile os2/Makefile os2/include/Makefile os2/include/sys/Makefile \
- readline/Makefile libmysql_r/Makefile libmysql/Makefile client/Makefile \
- sql/Makefile sql/share/Makefile \
- merge/Makefile dbug/Makefile scripts/Makefile \
- include/Makefile sql-bench/Makefile \
- tests/Makefile Docs/Makefile support-files/Makefile \
- mysql-test/Makefile \
- include/mysql_version.h
+AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl
+ strings/Makefile regex/Makefile heap/Makefile dnl
+ bdb/Makefile dnl
+ myisam/Makefile myisammrg/Makefile dnl
+ os2/Makefile os2/include/Makefile os2/include/sys/Makefile dnl
+ man/Makefile BUILD/Makefile readline/Makefile vio/Makefile dnl
+ libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile dnl
+ libmysql/Makefile client/Makefile dnl
+ pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile dnl
+ merge/Makefile dbug/Makefile scripts/Makefile dnl
+ include/Makefile sql-bench/Makefile tools/Makefile dnl
+ tests/Makefile Docs/Makefile support-files/Makefile dnl
+ support-files/MacOSX/Makefile mysql-test/Makefile dnl
+ include/mysql_version.h dnl
, , [
test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
])
diff --git a/dbug/dbug.c b/dbug/dbug.c
index cfe4ca161c6..c6df6b105c5 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -21,7 +21,8 @@
* all copies and derivative works. Thank you. *
* *
* The author makes no warranty of any kind with respect to this *
- * product and explicitly disclaims any implied warranties of mer- *
+ * product and explicitly disclaims any implied warranties of mer- *ct_lex.table_list.first=0;
+ thd->lex.selec
* chantability or fitness for any particular purpose. *
* *
******************************************************************************
@@ -58,7 +59,7 @@
* seismo!bpa!sjuvax!bbanerje
*
* Michael Widenius:
- * DBUG_DUMP - To dump a pice of memory.
+ * DBUG_DUMP - To dump a block of memory.
* PUSH_FLAG "O" - To be used insted of "o" if we don't
* want flushing (for slow systems)
* PUSH_FLAG "A" - as 'O', but we will append to the out file instead
@@ -69,7 +70,7 @@
#ifdef DBUG_OFF
#undef DBUG_OFF
#endif
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#include <errno.h>
#if defined(MSDOS) || defined(__WIN__)
@@ -500,7 +501,7 @@ void _db_push_ (const char *control)
if (! _db_fp_)
_db_fp_= stderr; /* Output stream, default stderr */
- if (control && *control == '-')
+ if (*control == '-')
{
if (*++control == '#')
control++;
@@ -705,9 +706,16 @@ char ***_sframep_ __attribute__((unused)))
if (!_no_db_)
{
int save_errno=errno;
+ /*
+ Sasha: the test below is so we could call functions with DBUG_ENTER
+ before my_thread_init(). I needed this because I suspected corruption
+ of a block allocated by my_thread_init() itself, so I wanted to use
+ my_malloc()/my_free() in my_thread_init()/my_thread_end()
+ */
+ if (!(state=code_state()))
+ return;
if (!init_done)
_db_push_ (_DBUG_START_CONDITION_);
- state=code_state();
*_sfunc_ = state->func;
*_sfile_ = state->file;
@@ -787,10 +795,10 @@ uint *_slevel_)
if (!_no_db_)
{
int save_errno=errno;
+ if (!(state=code_state()))
+ return;
if (!init_done)
_db_push_ ("");
- if (!(state=code_state()))
- return; /* Only happens at end of program */
if (stack->flags & (TRACE_ON | DEBUG_ON | PROFILE_ON))
{
if (!state->locked)
@@ -855,6 +863,9 @@ uint _line_,
const char *keyword)
{
CODE_STATE *state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!state)
+ return;
state->u_line = _line_;
state->u_keyword = (char*) keyword;
}
@@ -890,7 +901,9 @@ void _db_doprnt_ (const char *format,...)
{
va_list args;
CODE_STATE *state;
- state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!(state=code_state()))
+ return;
va_start(args,format);
@@ -906,7 +919,6 @@ void _db_doprnt_ (const char *format,...)
}
(void) fprintf (_db_fp_, "%s: ", state->u_keyword);
(void) vfprintf (_db_fp_, format, args);
- va_end(args);
(void) fputc('\n',_db_fp_);
dbug_flush(state);
errno=save_errno;
@@ -942,7 +954,9 @@ uint length)
int pos;
char dbuff[90];
CODE_STATE *state;
- state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!(state=code_state()))
+ return;
if (_db_keyword_ ((char*) keyword))
{
@@ -1224,7 +1238,9 @@ const char *keyword)
if (!init_done)
_db_push_ ("");
- state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!(state=code_state()))
+ return FALSE;
result = FALSE;
if (DEBUGGING &&
state->level <= stack -> maxdepth &&
@@ -1928,7 +1944,7 @@ static void dbug_flush(CODE_STATE *state)
{
if (!(freopen(stack->name,"a",_db_fp_)))
{
- (void) fprintf(stderr, ERR_OPEN, _db_process_);
+ (void) fprintf(stderr, ERR_OPEN, _db_process_, stack->name);
fflush(stderr);
_db_fp_ = stdout;
stack -> out_file = _db_fp_;
diff --git a/dbug/dbug_add_tags.pl b/dbug/dbug_add_tags.pl
new file mode 100755
index 00000000000..141a2ed85f1
--- /dev/null
+++ b/dbug/dbug_add_tags.pl
@@ -0,0 +1,73 @@
+#!/usr/bin/perl
+
+die "No files specified\n" unless $ARGV[0];
+
+$ctags="exctags -x -f - --c-types=f -u";
+
+sub get_tag {
+ local $.; local $_=<TAGS>;
+ ($symbol, $line)= /^(.*\S)\s+function\s+(\d+)/;
+ $symbol=$1 if /\s(\S+)\s*\(/;
+ $line=1e50 unless $line;
+}
+
+while($src=shift)
+{
+ warn "==> $src\n";
+
+ $dst=$src.$$;
+ open(TAGS, "$ctags $src|") || die "Cannot exec('$ctags $src'): $!";
+ open(SRC, "<$src") || die "Cannot open $src: $!";
+ open(DST, ">$dst") || die "Cannot create $dst: $!";
+ select DST;
+
+ &get_tag;
+ $in_func=0;
+ while(<SRC>)
+ {
+ my $orig=$_;
+ if ($in_func)
+ {
+ if (/\breturn\b/ && !/\/\*.*\breturn\b.*\*\// && !/;/ )
+ {
+ $_.=<SRC> until /;/;
+ }
+ s/(?<=\s)return\s*;/DBUG_VOID_RETURN;/;
+ s/(?<=\s)return\s*(.+)\s*;/DBUG_RETURN(\1);/s;
+ $ret_line=$. if /DBUG_(VOID_)?RETURN/; #{{
+ print "$tab DBUG_VOID_RETURN;\n" if /^$tab}/ && $ret_line < $.-1;
+ $in_func=0 if /^$tab}/;
+ warn "$src:".($.-1)."\t$orig" if /\breturn\b/;
+ }
+ print;
+ next if $. < $line;
+ die "Something wrong: \$.=$., \$line=$line, \$symbol=$symbol\n" if $. > $line;
+ &get_tag && next if /^\s*inline /;
+ print $_=<SRC> until /{/; $tab=$`;
+ &get_tag && next if /}/; # skip one-liners
+ $semicolon=1;
+ while(<SRC>)
+ {
+ $skip=!$semicolon;
+ $semicolon= /;\s*$/;
+ print && next if $skip ||
+ (/^\s+\w+((::\w+)?|<\w+>)\s+\**\w+/ && !/^\s*return/);
+ last if /DBUG_ENTER/;
+ print "$tab DBUG_ENTER(\"$symbol\");\n";
+ print "\n" unless $_ eq "\n";
+ last;
+ }
+ $in_func=1;
+ &get_tag;
+ redo;
+ }
+ close SRC;
+ close DST;
+ close TAGS;
+ unlink("$src.orig");
+ rename($src, "$src.orig") || die "Cannot rename $src to $src.orig: $!";
+ rename($dst, $src) || die "Cannot rename $dst to $src: $!";
+}
+
+warn "All done!\n";
+
diff --git a/dbug/dbug_analyze.c b/dbug/dbug_analyze.c
index bcee5230527..de228c64aa5 100644
--- a/dbug/dbug_analyze.c
+++ b/dbug/dbug_analyze.c
@@ -49,7 +49,7 @@
* if invoked with -v flag.
*/
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
static char *my_name;
diff --git a/dbug/example1.c b/dbug/example1.c
index 932e269cc4c..e468f065796 100644
--- a/dbug/example1.c
+++ b/dbug/example1.c
@@ -1,5 +1,5 @@
-#include <global.h>
+#include <my_global.h>
main (argc, argv)
int argc;
diff --git a/dbug/example2.c b/dbug/example2.c
index 482691a8a74..5e5f14f0e7e 100644
--- a/dbug/example2.c
+++ b/dbug/example2.c
@@ -1,5 +1,5 @@
-#include <global.h>
+#include <my_global.h>
int debug = 0;
diff --git a/dbug/example3.c b/dbug/example3.c
index b504edf2e61..f177c07425d 100644
--- a/dbug/example3.c
+++ b/dbug/example3.c
@@ -1,5 +1,5 @@
-#include <global.h>
+#include <my_global.h>
main (argc, argv)
int argc;
diff --git a/dbug/factorial.c b/dbug/factorial.c
index 0dda5c7459e..56197aef29e 100644
--- a/dbug/factorial.c
+++ b/dbug/factorial.c
@@ -2,7 +2,7 @@
#undef DBUG_OFF
#endif
-#include <global.h>
+#include <my_global.h>
int factorial (
register int value)
diff --git a/dbug/main.c b/dbug/main.c
index 863b4d319c2..da56c00feb3 100644
--- a/dbug/main.c
+++ b/dbug/main.c
@@ -2,7 +2,7 @@
#undef DBUG_OFF
#endif
-#include <global.h> /* This includes dbug.h */
+#include <my_global.h> /* This includes dbug.h */
int main (argc, argv)
int argc;
diff --git a/dbug/sanity.c b/dbug/sanity.c
index d287a468028..df43fc14ba9 100644
--- a/dbug/sanity.c
+++ b/dbug/sanity.c
@@ -1,6 +1,6 @@
/* Declarate _sanity() if not declared in main program */
-#include <global.h>
+#include <my_global.h>
extern int _sanity(const char *file,uint line);
diff --git a/div/deadlock_test.c b/div/deadlock_test.c
index be6d940cf1b..65a0df5c215 100644
--- a/div/deadlock_test.c
+++ b/div/deadlock_test.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -126,7 +126,7 @@ static void permute_aux(int *order, int num_queries, int* fixed)
}
/*printf("num_free = %d\n", num_free); */
-
+
if(num_free <= 1)
{
count++;
@@ -156,7 +156,7 @@ static void run_query_batch(int* order, int num_queries)
dump_result(q->mysql, q->query);
}
printf("\n");
-
+
}
static void safe_net_read(NET* net, char* query)
@@ -167,8 +167,8 @@ static void safe_net_read(NET* net, char* query)
die("Error running query '%s'", query);
if(net->read_pos[0] == 255)
die("Error running query '%s'", query);
-}
-
+}
+
static void safe_query(MYSQL* mysql, char* query, int read_ok)
{
@@ -230,7 +230,7 @@ int main()
permute(order, num_queries);
printf("count = %d\n", count);
-
+
mysql_close(&lock);
mysql_close(&sel);
mysql_close(&del_ins);
diff --git a/extra/Makefile.am b/extra/Makefile.am
index 6292faf4ad4..8e4491969b5 100644
--- a/extra/Makefile.am
+++ b/extra/Makefile.am
@@ -18,7 +18,7 @@ INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include -I..
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
../dbug/libdbug.a ../strings/libmystrings.a
bin_PROGRAMS = replace comp_err perror resolveip my_print_defaults \
-resolve_stack_dump
+ resolve_stack_dump mysql_install mysql_waitpid
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/extra/comp_err.c b/extra/comp_err.c
index f7b68ff0891..bd7e6231908 100644
--- a/extra/comp_err.c
+++ b/extra/comp_err.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Saves all errmesg in a header file, updated by me, in a compact file */
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
@@ -61,7 +60,7 @@ int main(int argc,char *argv[])
return(1);
}
- VOID(count_rows(from,'"','}')); /* Calculate start-info */
+ VOID(count_rows(from,'"','{')); /* Calculate start-info */
if (remember_rows(from,'}') < 0) /* Remember rows */
{
fprintf(stderr,"Can't find textrows in '%s'\n",*argv);
@@ -110,7 +109,7 @@ int main(int argc,char *argv[])
if (to)
fclose(to);
if (error)
- fprintf(stderr,"Can't uppdate messagefile %s, errno: %d\n",*argv,errno);
+ fprintf(stderr,"Can't update messagefile %s, errno: %d\n",*argv,errno);
exit(error);
return(0);
diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c
index 316d91ef7b3..07d6c0ca555 100644
--- a/extra/my_print_defaults.c
+++ b/extra/my_print_defaults.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
** print_default.c:
@@ -22,73 +21,88 @@
** Written by Monty
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
-#include <getopt.h>
+#include <my_getopt.h>
const char *config_file="my"; /* Default config file */
+uint verbose= 0, opt_defaults_file_used= 0;
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"config-file", required_argument, 0, 'c'},
- {"defaults-file", required_argument, 0, 'c'},
- {"defaults-extra-file", required_argument, 0, 'e'},
- {"extra-file", required_argument, 0, 'e'},
- {"no-defaults", no_argument, 0, 'n'},
- {"help", no_argument, 0, '?'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"config-file", 'c', "The config file to be used",
+ (gptr*) &config_file, (gptr*) &config_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"defaults-file", 'c', "Synonym for --config-file",
+ (gptr*) &config_file, (gptr*) &config_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"defaults-extra-file", 'e',
+ "Read this file after the global /etc config file and before the config file in the users home directory.",
+ (gptr*) &defaults_extra_file, (gptr*) &defaults_extra_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"extra-file", 'e',
+ "Synonym for --defaults-extra-file",
+ (gptr*) &defaults_extra_file, (gptr*) &defaults_extra_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"no-defaults", 'n', "Return an empty string (useful for scripts)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help message and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Increase the output level",
+ 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static void usage(my_bool version)
{
- printf("%s Ver 1.3 for %s at %s\n",my_progname,SYSTEM_TYPE,
+ printf("%s Ver 1.6 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE);
if (version)
return;
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Prints all arguments that is give to some program using the default files");
- printf("Usage: %s [OPTIONS] groups\n",my_progname);
- printf("\n\
- -c, --config-file=#, --defaults-file=#\n\
- The config file to use (default '%s')\n\
- -e, --extra-file=#, --defaults-extra-file=#\n\
- Read this file after the global /etc config file and\n\
- before the config file in the users home directory.\n\
- -n, --no-defaults Return an empty string (useful for scripts)\n\
- -?, --help Display this help message and exit.\n\
- -V, --version Output version information and exit.\n",
- config_file);
- printf("\nExample usage: %s --config-file=my client mysql\n",my_progname);
+ printf("Usage: %s [OPTIONS] groups\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+ printf("\nExample usage:\n%s --config-file=my client mysql\n", my_progname);
}
-static int get_options(int *argc,char ***argv)
-{
- int c,option_index;
- while ((c=getopt_long(*argc,*argv,"nc:e:V?I",
- long_options, &option_index)) != EOF)
- {
- switch (c) {
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch (optid) {
case 'c':
- config_file=optarg;
- break;
- case 'e':
- defaults_extra_file=optarg; /* Used by the load_defaults */
+ opt_defaults_file_used= 1;
break;
case 'n':
- exit(0);
+ exit(0);
case 'I':
case '?':
- usage(0);
- exit(0);
+ usage(0);
+ exit(0);
+ case 'v':
+ verbose++;
+ break;
case 'V':
- usage(1);
- exit(0);
- }
+ usage(1);
+ exit(0);
}
- (*argc)-=optind;
- (*argv)+=optind;
+ return 0;
+}
+
+
+static int get_options(int *argc,char ***argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (*argc < 1)
{
usage(0);
@@ -99,7 +113,7 @@ static int get_options(int *argc,char ***argv)
int main(int argc, char **argv)
{
- int count;
+ int count, error;
char **load_default_groups, *tmp_arguments[2],
**argument, **arguments;
MY_INIT(argv[0]);
@@ -121,13 +135,26 @@ int main(int argc, char **argv)
arguments=tmp_arguments;
arguments[0]=my_progname;
arguments[1]=0;
- load_defaults(config_file, (const char **) load_default_groups,
- &count, &arguments);
+ if ((error= load_defaults(config_file, (const char **) load_default_groups,
+ &count, &arguments)))
+ {
+ if (verbose && opt_defaults_file_used)
+ {
+ if (error == 1)
+ fprintf(stderr, "WARNING: Defaults file '%s' not found!\n",
+ config_file);
+ /* This error is not available now. For the future */
+ if (error == 2)
+ fprintf(stderr, "WARNING: Defaults file '%s' is not a regular file!\n",
+ config_file);
+ }
+ error= 2;
+ }
for (argument= arguments+1 ; *argument ; argument++)
puts(*argument);
my_free((char*) load_default_groups,MYF(0));
free_defaults(arguments);
- exit(0);
+ exit(error);
}
diff --git a/extra/mysql_install.c b/extra/mysql_install.c
index dfd71895647..e2783f906b9 100644
--- a/extra/mysql_install.c
+++ b/extra/mysql_install.c
@@ -18,24 +18,212 @@
/* Install or upgrade MySQL server. By Sasha Pachev <sasha@mysql.com>
*/
-#define INSTALL_VERSION "1.0"
+#define INSTALL_VERSION "1.2"
#define DONT_USE_RAID
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
#include <mysql_version.h>
#include <errno.h>
-#include <getopt.h>
+#include <my_getopt.h>
-struct option long_options[] =
+#define ANSWERS_CHUNCK 32
+
+int have_gui=0;
+
+static struct my_option my_long_options[] =
{
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'V'},
- {0, 0,0,0}
+ {"help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+/* For now, not much exciting here, but we'll add more once
+ we add GUI support
+ */
+typedef struct
+{
+ FILE* out;
+ FILE* in;
+ const char* question;
+ int default_ind;
+ DYNAMIC_ARRAY answers;
+} QUESTION_WIDGET;
+
+static void usage();
+static void die(const char* fmt, ...);
+static void print_version(void);
+static char get_answer_char(int ans_ind);
+static int ask_user(const char* question,int default_ind, ...);
+static void add_answer(QUESTION_WIDGET* w, const char* ans);
+static void display_question(QUESTION_WIDGET* w);
+static int init_question_widget(QUESTION_WIDGET* w, const char* question,
+ int default_ind);
+static void end_question_widget(QUESTION_WIDGET* w);
+static int get_answer(QUESTION_WIDGET* w);
+static char answer_from_char(char c);
+static void invalid_answer(QUESTION_WIDGET* w);
+
+enum {IMODE_STANDARD=0,IMODE_CUSTOM,IMODE_UPGRAGE} install_mode
+ = IMODE_STANDARD;
+
+static char get_answer_char(int ans_ind)
+{
+ return 'a' + ans_ind;
+}
+
+static void invalid_answer(QUESTION_WIDGET* w)
+{
+ if (!have_gui)
+ {
+ fprintf(w->out, "ERROR: invalid answer, try again...\a\n");
+ }
+}
+
+static char answer_from_char(char c)
+{
+ return c - 'a';
+}
+
+static void die(const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ fprintf(stderr, "%s: ", my_progname);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ va_end(args);
+ exit(1);
+}
+
+static void display_question(QUESTION_WIDGET* w)
+{
+ if (!have_gui)
+ {
+ uint i,num_answers=w->answers.elements;
+ DYNAMIC_ARRAY* answers = &w->answers;
+ fprintf(w->out,"\n%s\n\n",w->question);
+
+ for (i=0; i<num_answers; i++)
+ {
+ char* ans;
+ get_dynamic(answers,(gptr)&ans,i);
+ fprintf(w->out,"%c - %s\n",get_answer_char(i),ans);
+ }
+ fprintf(w->out,"q - Abort Install/Upgrade\n\n");
+ }
+}
+
+static void add_answer(QUESTION_WIDGET* w, const char* ans)
+{
+ insert_dynamic(&w->answers,(gptr)&ans);
+}
+
+static int init_question_widget(QUESTION_WIDGET* w, const char* question,
+ int default_ind)
+{
+ if (have_gui)
+ {
+ w->in = w->out = 0;
+ }
+ else
+ {
+ w->out = stdout;
+ w->in = stdin;
+ }
+ w->question = question;
+ w->default_ind = default_ind;
+ if (my_init_dynamic_array(&w->answers,sizeof(char*),
+ ANSWERS_CHUNCK,ANSWERS_CHUNCK))
+ die("Out of memory");
+ return 0;
+}
+
+static void end_question_widget(QUESTION_WIDGET* w)
+{
+ delete_dynamic(&w->answers);
+}
+
+static int get_answer(QUESTION_WIDGET* w)
+{
+ if (!have_gui)
+ {
+ char buf[32];
+ int ind;
+ char c;
+ if (!fgets(buf,sizeof(buf),w->in))
+ die("Failed fgets on input stream");
+ switch ((c=tolower(*buf)))
+ {
+ case '\n':
+ return w->default_ind;
+ case 'q':
+ die("Install/Upgrade aborted");
+ default:
+ ind = answer_from_char(c);
+ if (ind >= 0 && ind < (int)w->answers.elements)
+ return ind;
+ }
+ }
+ return -1;
+}
+
+static int ask_user(const char* question,int default_ind, ...)
+{
+ va_list args;
+ char* opt;
+ QUESTION_WIDGET w;
+ int ans;
+
+ va_start(args,default_ind);
+ init_question_widget(&w,question,default_ind);
+ for (;(opt=va_arg(args,char*));)
+ {
+ add_answer(&w,opt);
+ }
+ for (;;)
+ {
+ display_question(&w);
+ if ((ans = get_answer(&w)) >= 0)
+ break;
+ invalid_answer(&w);
+ }
+ end_question_widget(&w);
+ va_end(args);
+ return ans;
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch(optid) {
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+
+static int parse_args(int argc, char **argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ return 0;
+}
+
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,INSTALL_VERSION,
@@ -49,12 +237,20 @@ static void usage()
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
printf("Install or upgrade MySQL server.\n\n");
printf("Usage: %s [OPTIONS] \n", my_progname);
- printf("\n\
- -?, --help Display this help and exit.\n\
- -h, --host=... Connect to host.\n\
- -V, --version Output version information and exit.\n");
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
}
+int main(int argc, char** argv)
+{
+ MY_INIT(argv[0]);
+ parse_args(argc,argv);
+ install_mode = ask_user("Please select install/upgrade mode",
+ install_mode, "Standard Install",
+ "Custom Install", "Upgrade",0);
+ printf("mode=%d\n", install_mode);
+ return 0;
+}
diff --git a/extra/mysql_waitpid.c b/extra/mysql_waitpid.c
new file mode 100644
index 00000000000..bff1752ec21
--- /dev/null
+++ b/extra/mysql_waitpid.c
@@ -0,0 +1,117 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Wait until a program dies */
+
+#ifndef __NETWARE__
+
+#include <my_global.h>
+#include <m_string.h>
+#include <my_getopt.h>
+#include <signal.h>
+#include <errno.h>
+
+static const char *VER= "1.1";
+static char *progname;
+static my_bool verbose;
+
+void usage(void);
+
+static struct my_option my_long_options[] =
+{
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"help", 'I', "Synonym for -?.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"verbose", 'v',
+ "Be more verbose. Give a warning, if kill can't handle signal 0.",
+ (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Print version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch(optid) {
+ case 'V':
+ printf("%s version %s by Jani Tolonen\n", progname, VER);
+ exit(-1);
+ case 'I':
+ case '?':
+ usage();
+ }
+ return 0;
+}
+
+
+int main(int argc, char *argv[])
+{
+ int pid= 0, t= 0, sig= 0;
+
+ progname= argv[0];
+
+ if (handle_options(&argc, &argv, my_long_options, get_one_option))
+ exit(-1);
+ if (!argv[0] || !argv[1] || (pid= atoi(argv[0])) <= 0 ||
+ (t= atoi(argv[1])) <= 0)
+ usage();
+ for (; t > 0; t--)
+ {
+ if (kill((pid_t) pid, sig))
+ {
+ if (errno == EINVAL)
+ {
+ if (verbose)
+ printf("WARNING: kill couldn't handle signal 0, using signal 1.\n");
+ sig= 1;
+ t++;
+ continue;
+ }
+ return 0;
+ }
+ sleep(1);
+ }
+ return 1;
+}
+
+void usage(void)
+{
+ printf("%s version %s by Jani Tolonen\n\n", progname, VER);
+ printf("usage: %s [options] #pid #time\n\n", progname);
+ printf("Description: Waits for a program, which program id is #pid, to\n");
+ printf("terminate within #time seconds. If the program terminates within\n");
+ printf("this time, or if the #pid no longer exists, value 0 is returned.\n");
+ printf("Otherwise 1 is returned. Both #pid and #time must be positive\n");
+ printf("integer arguments.\n\n");
+ printf("Options:\n");
+ my_print_help(my_long_options);
+ exit(-1);
+}
+
+#else
+
+#include <stdio.h>
+
+main()
+{
+ fprintf(stderr,"This tool has not been ported to NetWare\n");
+ return 0;
+}
+
+#endif /* __NETWARE__ */
diff --git a/extra/perror.c b/extra/perror.c
index 6cb86eedf27..ca6bbfb54f9 100644
--- a/extra/perror.c
+++ b/extra/perror.c
@@ -1,48 +1,57 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Return error-text for system error messages and nisam messages */
-#define PERROR_VERSION "2.7"
+#define PERROR_VERSION "2.9"
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <errno.h>
-#include <getopt.h>
+#include <my_getopt.h>
+static my_bool verbose, print_all_codes;
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"help", no_argument, 0, '?'},
- {"info", no_argument, 0, 'I'},
- {"all", no_argument, 0, 'a'},
- {"silent", no_argument, 0, 's'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"info", 'I', "Synonym for --help", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SYS_ERRLIST
+ {"all", 'a', "Print all the error messages and the number.",
+ (gptr*) &print_all_codes, (gptr*) &print_all_codes, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
+ {"silent", 's', "Only print the error message", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Print error code and message (default).", (gptr*) &verbose,
+ (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"version", 'V', "Displays version information and exits.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
typedef struct ha_errors {
int errcode;
const char *msg;
} HA_ERRORS;
-static int verbose=1,print_all_codes=0;
static HA_ERRORS ha_errlist[]=
{
@@ -50,8 +59,10 @@ static HA_ERRORS ha_errlist[]=
{ 121,"Duplicate key on write or update" },
{ 123,"Someone has changed the row since it was read; Update with is recoverable" },
{ 124,"Wrong index given to function" },
- { 126,"Index file is crashed / Wrong file format" },
+ { 126,"Index file is crashed" },
{ 127,"Record-file is crashed" },
+ { 128,"Out of memory" },
+ { 130,"Incorrect file format" },
{ 131,"Command not supported by database" },
{ 132,"Old database file" },
{ 133,"No record read before update" },
@@ -64,13 +75,16 @@ static HA_ERRORS ha_errlist[]=
{ 140,"Wrong create options"},
{ 141,"Duplicate unique key or constraint on write or update"},
{ 142,"Unknown character set used"},
- { 143,"Conflicting table definition between MERGE and mapped table"},
+ { 143,"Conflicting table definitions in sub-tables of MERGE table"},
{ 144,"Table is crashed and last repair failed"},
{ 145,"Table was marked as crashed and should be repaired"},
{ 146,"Lock timed out; Retry transaction"},
{ 147,"Lock table is full; Restart program with a larger locktable"},
{ 148,"Updates are not allowed under a read only transactions"},
{ 149,"Lock deadlock; Retry transaction"},
+ { 150,"Foreign key constraint is incorrectly formed"},
+ { 151,"Cannot add a child row"},
+ { 152,"Cannot delete a parent row"},
{ -30999, "DB_INCOMPLETE: Sync didn't finish"},
{ -30998, "DB_KEYEMPTY: Key/data deleted or never created"},
{ -30997, "DB_KEYEXIST: The key/data pair already exists"},
@@ -97,60 +111,43 @@ static void usage(void)
{
print_version();
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
- printf("Print a description for a system error code or a error code from\na MyISAM/ISAM/BDB table handler.\n");
+ printf("Print a description for a system error code or an error code from\na MyISAM/ISAM/BDB table handler.\n");
printf("If you want to get the error for a negative error code, you should use\n-- before the first error code to tell perror that there was no more options.\n\n");
printf("Usage: %s [OPTIONS] [ERRORCODE [ERRORCODE...]]\n",my_progname);
- printf("\n\
- -?, --help Displays this help and exits.\n\
- -I, --info Synonym for the above.");
-#ifdef HAVE_SYS_ERRLIST
- printf("\n\
- -a, --all Print all the error messages and the number.");
-#endif
- printf("\n\
- -s, --silent Only print the error message\n\
- -v, --verbose Print error code and message (default).\n\
- -V, --version Displays version information and exits.\n");
-}
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch (optid) {
+ case 's':
+ verbose=0;
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ break;
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ break;
+ }
+ return 0;
+}
static int get_options(int *argc,char ***argv)
{
- int c,option_index;
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
- while ((c=getopt_long(*argc,*argv,"asvVI?",long_options,
- &option_index)) != EOF)
- {
- switch (c) {
-#ifdef HAVE_SYS_ERRLIST
- case 'a':
- print_all_codes=1;
- break;
-#endif
- case 'v':
- verbose=1;
- break;
- case 's':
- verbose=0;
- break;
- case 'V':
- print_version();
- exit(0);
- break;
- case 'I':
- case '?':
- usage();
- exit(0);
- break;
- default:
- fprintf(stderr,"%s: Illegal option character '%c'\n",
- my_progname,opterr);
- return(1);
- break;
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
if (!*argc && !print_all_codes)
{
usage();
@@ -231,4 +228,3 @@ int main(int argc,char *argv[])
exit(error);
return error;
}
-
diff --git a/extra/replace.c b/extra/replace.c
index ef3abda5cc5..41312f5e3d4 100644
--- a/extra/replace.c
+++ b/extra/replace.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Replace strings in textfile
This program replace strings in a file or on stdin/stdout.
@@ -38,7 +37,7 @@
*/
#define DONT_USE_RAID
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
diff --git a/extra/resolve_stack_dump.c b/extra/resolve_stack_dump.c
index a08845b8de3..c54f17a186e 100644
--- a/extra/resolve_stack_dump.c
+++ b/extra/resolve_stack_dump.c
@@ -1,37 +1,36 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Resolve numeric stack dump produced by mysqld 3.23.30 and later
versions into symbolic names. By Sasha Pachev <sasha@mysql.com>
*/
#define DONT_USE_RAID
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
#include <mysql_version.h>
#include <errno.h>
-#include <getopt.h>
+#include <my_getopt.h>
#define INIT_SYM_TABLE 4096
#define INC_SYM_TABLE 4096
#define MAX_SYM_SIZE 128
-#define DUMP_VERSION "1.2"
+#define DUMP_VERSION "1.4"
#define HEX_INVALID (uchar)255
typedef ulong my_long_addr_t ; /* at some point, we need to fix configure
@@ -49,15 +48,21 @@ static char* dump_fname = 0, *sym_fname = 0;
static DYNAMIC_ARRAY sym_table; /* how do you like this , static DYNAMIC ? */
static FILE* fp_dump, *fp_sym = 0, *fp_out;
-struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'V'},
- {"symbols-file", required_argument, 0, 's'},
- {"numeric-dump-file", required_argument, 0, 'n'},
- {0, 0,0,0}
+ {"help", 'h', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"symbols-file", 's', "Use specified symbols file.", (gptr*) &sym_fname,
+ (gptr*) &sym_fname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"numeric-dump-file", 'n', "Read the dump from specified file.",
+ (gptr*) &dump_fname, (gptr*) &dump_fname, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static void verify_sort();
static void print_version(void)
@@ -72,12 +77,10 @@ static void usage()
printf("MySQL AB, by Sasha Pachev\n");
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
printf("Resolve numeric stack strace dump into symbols.\n\n");
- printf("Usage: %s [OPTIONS] symbols-file [numeric-dump-file]\n", my_progname);
- printf("\n\
- -?, --help Display this help and exit.\n\
- -s, --symbols-file=... Use specified symbols file.\n\
- -n, --numeric-dump-file=... Read the dump from specified file.\n\
- -V, --version Output version information and exit.\n");
+ printf("Usage: %s [OPTIONS] symbols-file [numeric-dump-file]\n",
+ my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
printf("\n\
The symbols-file should include the output from: 'nm --numeric-sort mysqld'.\n\
The numeric-dump-file should contain a numeric stack trace from mysqld.\n\
@@ -98,40 +101,33 @@ static void die(const char* fmt, ...)
}
-static int parse_args(int argc, char **argv)
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
{
- int c, option_index = 0;
+ switch(optid) {
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
- while((c = getopt_long(argc, argv, "?Vn:s:",
- long_options, &option_index)) != EOF)
- {
- switch(c)
- {
- case 'n':
- dump_fname = optarg;
- break;
- case 's':
- sym_fname = optarg;
- break;
- case 'V':
- print_version();
- exit(0);
- case '?':
- usage();
- exit(0);
- default:
- usage();
- exit(1);
- }
- }
- argc-=optind;
- argv+=optind;
+static int parse_args(int argc, char **argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
/*
The following code is to make the command compatible with the old
version that required one to use the -n and -s options
- */
+ */
if (argc == 2)
{
@@ -163,26 +159,26 @@ static void open_files()
{
fp_out = stdout;
fp_dump = stdin;
-
- if(dump_fname && !(fp_dump = my_fopen(dump_fname, O_RDONLY, MYF(MY_WME))))
+
+ if (dump_fname && !(fp_dump = my_fopen(dump_fname, O_RDONLY, MYF(MY_WME))))
die("Could not open %s", dump_fname);
/* if name not given, assume stdin*/
- if(!sym_fname)
+ if (!sym_fname)
die("Please run nm --numeric-sort on mysqld binary that produced stack \
trace dump and specify the path to it with -s or --symbols-file");
- if(!(fp_sym = my_fopen(sym_fname, O_RDONLY, MYF(MY_WME))))
+ if (!(fp_sym = my_fopen(sym_fname, O_RDONLY, MYF(MY_WME))))
die("Could not open %s", sym_fname);
-
+
}
static uchar hex_val(char c)
{
uchar l;
- if(isdigit(c))
+ if (isdigit(c))
return c - '0';
l = tolower(c);
- if(l < 'a' || l > 'f')
+ if (l < 'a' || l > 'f')
return HEX_INVALID;
return (uchar)10 + ((uchar)c - (uchar)'a');
}
@@ -192,10 +188,10 @@ static my_long_addr_t read_addr(char** buf)
uchar c;
char* p = *buf;
my_long_addr_t addr = 0;
-
+
while((c = hex_val(*p++)) != HEX_INVALID)
addr = (addr << 4) + c;
-
+
*buf = p;
return addr;
}
@@ -205,25 +201,18 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
char* p, *p_end;
se->addr = (uchar*)read_addr(&buf);
- if(!se->addr)
+ if (!se->addr)
return -1;
- while(isspace(*buf++))
- /* empty */;
-
- while(isspace(*buf++))
- /* empty - skip more space */;
+ while (isspace(*buf++)) ;
+
+ while (isspace(*buf++)) ; /* skip more space */
--buf;
/* now we are on the symbol */
- for(p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1;
- *buf != '\n' && *buf; ++buf,++p )
- {
- if(p < p_end)
- *p = *buf;
- else
- break;
- }
+ for (p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1;
+ *buf != '\n' && *buf && p < p_end; ++buf,++p)
+ *p = *buf;
*p = 0;
- if(!strcmp(se->symbol, "gcc2_compiled."))
+ if (!strcmp(se->symbol, "gcc2_compiled."))
return -1;
return 0;
}
@@ -231,18 +220,18 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
static void init_sym_table()
{
char buf[512];
- if(my_init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE,
- INC_SYM_TABLE))
+ if (my_init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE,
+ INC_SYM_TABLE))
die("Failed in my_init_dynamic_array() -- looks like out of memory problem");
- while(fgets(buf, sizeof(buf), fp_sym))
- {
- SYM_ENTRY se;
- if(init_sym_entry(&se, buf))
- continue;
- if(insert_dynamic(&sym_table, (gptr)&se))
- die("insert_dynamic() failed - looks like we are out of memory");
- }
+ while (fgets(buf, sizeof(buf), fp_sym))
+ {
+ SYM_ENTRY se;
+ if (init_sym_entry(&se, buf))
+ continue;
+ if (insert_dynamic(&sym_table, (gptr)&se))
+ die("insert_dynamic() failed - looks like we are out of memory");
+ }
verify_sort();
}
@@ -256,67 +245,69 @@ static void verify_sort()
{
uint i;
uchar* last = 0;
-
- for(i = 0; i < sym_table.elements; i++)
- {
- SYM_ENTRY se;
- get_dynamic(&sym_table, (gptr)&se, i);
- if(se.addr < last)
- die("sym table does not appear to be sorted, did you forget \
+
+ for (i = 0; i < sym_table.elements; i++)
+ {
+ SYM_ENTRY se;
+ get_dynamic(&sym_table, (gptr)&se, i);
+ if (se.addr < last)
+ die("sym table does not appear to be sorted, did you forget \
--numeric-sort arg to nm? trouble addr = %p, last = %p", se.addr, last);
- last = se.addr;
- }
+ last = se.addr;
+ }
}
+
static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se)
{
uint i;
get_dynamic(&sym_table, (gptr)se, 0);
- if(addr < se->addr)
+ if (addr < se->addr)
return 0;
-
- for(i = 1; i < sym_table.elements; i++)
+
+ for (i = 1; i < sym_table.elements; i++)
+ {
+ get_dynamic(&sym_table, (gptr)se, i);
+ if (addr < se->addr)
{
- get_dynamic(&sym_table, (gptr)se, i);
- if(addr < se->addr)
- {
- get_dynamic(&sym_table, (gptr)se, i - 1);
- return se;
- }
+ get_dynamic(&sym_table, (gptr)se, i - 1);
+ return se;
}
+ }
return se;
}
+
static void do_resolve()
{
char buf[1024], *p;
- while(fgets(buf, sizeof(buf), fp_dump))
+ while (fgets(buf, sizeof(buf), fp_dump))
+ {
+ p = buf;
+ while(isspace(*p))
+ ++p;
+
+ if (*p++ == '0' && *p++ == 'x')
{
- p = buf;
- while(isspace(*p))
- ++p;
- /* skip space */;
-
- if(*p++ == '0' && *p++ == 'x')
- {
- SYM_ENTRY se ;
- uchar* addr = (uchar*)read_addr(&p);
- if(resolve_addr(addr, &se))
- fprintf(fp_out, "%p %s + %d\n", addr, se.symbol,
- (int) (addr - se.addr));
- else
- fprintf(fp_out, "%p (?)\n", addr);
-
- }
+ SYM_ENTRY se ;
+ uchar* addr = (uchar*)read_addr(&p);
+ if (resolve_addr(addr, &se))
+ fprintf(fp_out, "%p %s + %d\n", addr, se.symbol,
+ (int) (addr - se.addr));
else
- {
- fputs(buf, fp_out);
- continue;
- }
+ fprintf(fp_out, "%p (?)\n", addr);
+
}
+ else
+ {
+ fputs(buf, fp_out);
+ continue;
+ }
+ }
}
+
int main(int argc, char** argv)
{
MY_INIT(argv[0]);
@@ -327,4 +318,3 @@ int main(int argc, char** argv)
clean_up();
return 0;
}
-
diff --git a/extra/resolveip.c b/extra/resolveip.c
index 004f312dc7c..d3caa9e1d45 100644
--- a/extra/resolveip.c
+++ b/extra/resolveip.c
@@ -16,7 +16,7 @@
/* Resolves IP's to hostname and hostnames to IP's */
-#define RESOLVE_VERSION "2.0"
+#define RESOLVE_VERSION "2.3"
#include <my_global.h>
#include <m_ctype.h>
@@ -30,26 +30,25 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <my_net.h>
-#include <getopt.h>
+#include <my_getopt.h>
#if !defined(_AIX) && !defined(HAVE_UNIXWARE7_THREADS) && !defined(HAVE_UNIXWARE7_POSIX) && !defined(h_errno)
extern int h_errno;
#endif
-#ifndef HAVE_IN_ADDR_T
-#define in_addr_t ulong
-#endif
-
+static my_bool silent;
-static int silent=0;
-
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"help", no_argument, 0, '?'},
- {"info", no_argument, 0, 'I'},
- {"silent", no_argument, 0, 's'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"help", '?', "Displays this help and exits.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"info", 'I', "Synonym for --help",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Be more silent.", (gptr*) &silent, (gptr*) &silent,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Displays version information and exits.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -66,41 +65,34 @@ static void usage(void)
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Get hostname based on IP-address or IP-address based on hostname.\n");
printf("Usage: %s [OPTIONS] hostname or IP-address\n",my_progname);
- printf("\n\
- -?, --help Displays this help and exits.\n\
- -I, --info Synonym for the above.\n\
- -s, --silent Be more silent.\n\
- -V, --version Displays version information and exits.\n");
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch (optid) {
+ case 'V': print_version(); exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
}
/*static my_string load_default_groups[]= { "resolveip","client",0 }; */
static int get_options(int *argc,char ***argv)
{
- int c,option_index;
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
- /* load_defaults("my",load_default_groups,argc,argv); */
- while ((c=getopt_long(*argc,*argv,"?IsV",
- long_options, &option_index)) != EOF)
- {
- switch (c) {
- case 's':
- silent=1;
- break;
- case 'V': print_version(); exit(0);
- case 'I':
- case '?':
- usage();
- exit(0);
- default:
- fprintf(stderr,"%s: Illegal option character '%c'\n",
- my_progname,opterr);
- return(1);
- break;
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
if (*argc == 0)
{
usage();
@@ -152,8 +144,11 @@ int main(int argc, char **argv)
else
{
printf ("Host name of %s is %s", ip,hpaddr->h_name);
+#ifndef __NETWARE__
+ /* this information is not available on NetWare */
for (q = hpaddr->h_aliases; *q != 0; q++)
(void) printf(", %s", *q);
+#endif /* __NETWARE__ */
puts("");
}
}
diff --git a/fs/CorbaFS.idl b/fs/CorbaFS.idl
new file mode 100644
index 00000000000..8fe089bd13c
--- /dev/null
+++ b/fs/CorbaFS.idl
@@ -0,0 +1,38 @@
+// -----------------------------------------------------------------------------
+// CorbaDS Module - Implement Kernel functionality in korbit
+// -----------------------------------------------------------------------------
+//
+// Main source of information:
+// http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html
+//
+module CorbaFS {
+
+ struct dirent
+ {
+ long inode; // inode number
+ string name; // file name (null-terminated)
+ };
+
+ typedef sequence<dirent> DirEntSeq;
+ typedef sequence<octet> Buffer;
+
+ interface Inode {
+ void getStatus(out unsigned short mode, out unsigned long uid, out unsigned long gid,
+ out unsigned long size, out unsigned long inodeNum, out unsigned short numLinks,
+ out long atime, out long mtime, out long ctime);
+ void readpage(out Buffer buffer, in long size, in long offset);
+ void release();
+ };
+
+ interface FileSystem {
+ Inode getInode(in string path);
+
+ // DirectoryInode getStatus implementation must have S_IFDIR in the S_IFMT
+ // field of the mode value.
+ DirEntSeq readdir(in string path);
+
+ // SymlinkInode getStatus implementation must have S_IFLNK in the S_IFMT
+ // field of the mode value.
+ string readlink(in string filename);
+ };
+};
diff --git a/fs/Makefile.am b/fs/Makefile.am
new file mode 100644
index 00000000000..33d1acd913d
--- /dev/null
+++ b/fs/Makefile.am
@@ -0,0 +1,93 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#called from the top level Makefile
+
+CFLAGS = $(ORBIT_CFLAGS) -g
+LFLAGS = $(ORBIT_LIBS)
+orbit_idl = @orbit_idl@
+orbit_includes = @orbit_includes@
+orbit_libs = @orbit_libs@
+
+DISTCLEANFILES = CorbaFS-common.* CorbaFS-stubs.* CorbaFS-skels.* CorbaFS.h
+
+MYSQLDATAdir = $(localstatedir)
+MYSQLSHAREdir = $(pkgdatadir)
+MYSQLBASEdir= $(prefix)
+INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include \
+ -I$(srcdir)/../regex \
+ -I$(srcdir) -I../include -I.. -I. \
+ -I$(srcdir) -I../include -I.. -I. \
+ $(orbit_includes)
+WRAPLIBS= @WRAPLIBS@
+libexec_PROGRAMS = mysqlcorbafsd
+noinst_PROGRAMS =mysqlfs_test
+LDADD = ../libmysql/libmysqlclient.la $(orbit_libs)
+mysqlcorbafsd_LDADD = $(LDADD) $(CXXLDFLAGS)
+noinst_HEADERS =
+mysqlfs_test_SOURCES = mysqlcorbafs_test.c CorbaFS-common.c CorbaFS-stubs.c libmysqlfs.c
+mysqlcorbafsd_SOURCES = mysqlcorbafs.c CorbaFS-skels.c database.c CorbaFS-common.c libmysqlfs.c
+
+DEFS = -DMYSQL_SERVER \
+ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
+ -DDATADIR="\"$(MYSQLDATAdir)\"" \
+ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
+ @DEFS@
+# Don't put lex_hash.h in BUILT_SOURCES as this will give infinite recursion
+BUILT_SOURCES = CorbaFS-common.c CorbaFS-stubs.c CorbaFS-skels.c CorbaFS.h
+EXTRA_DIST = $(BUILT_SOURCES)
+#YFLAGS = -d
+
+OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
+ __math.h time.h __time.h unistd.h __unistd.h types.h \
+ xtypes.h ac-types.h posix.h string.h __string.h \
+ errno.h socket.h inet.h dirent.h netdb.h \
+ cleanup.h cond.h debug_out.h fd.h kernel.h mutex.h \
+ prio_queue.h pthread_attr.h pthread_once.h queue.h\
+ sleep.h specific.h version.h pwd.h timers.h uio.h \
+ cdefs.h machdep.h signal.h __signal.h util.h lex.h \
+ wait.h
+
+link_sources:
+ rm -f mini_client_errors.c
+ @LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
+
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
+
+idltargets : CorbaFS.idl
+ $(ORBIT_IDL) CorbaFS.idl
+ $(orbit_idl) CorbaFS.idl
+
+# individual rules
+
+CorbaFS-stubs.c : CorbaFS.idl
+ $(orbit_idl) CorbaFS.idl
+
+CorbaFS-common.c : CorbaFS.idl
+ $(orbit_idl) CorbaFS.idl
+
+CorbaFS-skels.c : CorbaFS.idl
+ $(orbit_idl) CorbaFS.idl
+
+#CorbaFS-client.c : CorbaFS.h
+
+#CorbaFS-server.c : CorbaFS.h
+
+CorbaFS.h : CorbaFS.idl
+ $(orbit_idl) CorbaFS.idl
+
diff --git a/fs/README b/fs/README
new file mode 100644
index 00000000000..5d86da3a7e4
--- /dev/null
+++ b/fs/README
@@ -0,0 +1,58 @@
+MySQL Filesystem
+Tõnu Samuel - tonu@mysql.com
+Some additional information is available on http://no.spam.ee/~tonu/mysqlfs.html
+
+WARNING: Experimental code and known to crash computer.
+
+Instructions, how to get this stuff working:
+1. Make sure you have ORBit, includeing development libraries installed. They should be version 0.5.3 or later.
+- I am lazy man and use default ones included with my RedHat:
+ [root@localhost /root]# rpm -qa | grep ORBit
+ ORBit-0.5.3-2
+ ORBit-devel-0.5.3-2
+ [root@localhost /root]#
+
+2. Prepare kernel to include korbit:
+- Get Linux 2.4.1 kernel source. (very possibly this patch works on 2.4.0 without modifications too)
+- unpack it
+- apply patch named "korbit-kernel-2.4.1-patch" on it.
+- make menuconfig
+- In section "Networking options":
+ ...
+ [*] Kernel ORB (EXPERIMENTAL)
+ ...
+ <M> CORBA User-space FileSystem (EXPERIMENTAL)
+ ...
+- make dep ; make bzlilo ; make modules ; make modules_install
+- reboot
+- Execute: insmod /lib/modules/$(uname -r)/kernel/net/korbit/modules/CorbaFS/client/corba-corbafs-client.o
+ You should see "gethostname() = localhost". Look at known bug 3 in the end of this doc.
+
+3. Make sure MySQL server is working on your system
+- On my RedHat 7.0 I execute "/etc/init.d/mysqld start"
+
+4. Prepare MySQL FS daemon
+- Get MySQL 4.0 from repository OR get MySQL FS source from http://no.spam.ee/~tonu/mysqlfs.html
+- unpack it. In MySQL 4.0 source this is located in directory named "fs". cd into it.
+- make
+- Execute command "./RunServer"
+
+5. mount MySQL server to disk tree
+- Execute command "mkdir /mnt/mysql"
+- Execute command "mount -t corbafs -o `cat /tmp/mysqlcorbafs.ior` none /mnt/mysql/"
+- Check you SQL server content by executing "ls -la /mnt/mysql/"
+
+Known bugs:
+
+1. User bugs. fix user ;)
+
+2. MySQL FS daemon will crash or will be stopped when cobrafs is mounted, then there is no way
+to unmount disks anymore. This is korbit business to handle such cases and I had no time to dig
+into korbit code.
+
+3. host name returned by gethostname() should be "localhost" or korbit will crash. Also "localhost"
+must be first string after 127.0.0.1 in /etc/hosts
+
+
+
+
diff --git a/fs/RunServer.sh b/fs/RunServer.sh
new file mode 100755
index 00000000000..22d152bb20b
--- /dev/null
+++ b/fs/RunServer.sh
@@ -0,0 +1,2 @@
+.libs/mysqlcorbafsd -ORBIIOPUSock=0 -ORBIIOPIPv4=1 --debug='d:t:o,~/mysqlfsd.trace' $*
+#.libs/mysqlcorbafsd -ORBIIOPUSock=0 -ORBIIOPIPv4=1 $*
diff --git a/fs/database.c b/fs/database.c
new file mode 100644
index 00000000000..462e61760e9
--- /dev/null
+++ b/fs/database.c
@@ -0,0 +1,628 @@
+/* Copyright (C) 2000 db AB & db Finland AB & TCX DataKonsult AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Database functions
+ *
+ * Using these functions we emulate filesystem behaviour on top of SQL
+ * database.
+ * Written by Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
+ *
+ * FIXME:
+ * - Direct handling of database handlers without SQL parsing overhead
+ * - connection pool
+ * - configurable function name/file name mappings
+ */
+
+
+#include "libmysqlfs.h"
+#include "mysqlcorbafs.h"
+#include <unistd.h>
+#include <string.h>
+#include <my_sys.h>
+
+DYNAMIC_ARRAY field_array;
+
+/*
+ * ** dbConnect -- connects to the host and selects DB.
+ * ** Also checks whether the tablename is a valid table name.
+ * */
+int db_connect(char *host, char *user,char *passwd)
+{
+ DBUG_ENTER("db_connect");
+ DBUG_PRINT("enter",("host: '%s', user: '%s', passwd: '%s'", host, user, passwd));
+
+ if (verbose)
+ {
+ fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
+ }
+ mysql_init(&connection);
+ if (opt_compress)
+ mysql_options(&connection,MYSQL_OPT_COMPRESS,NullS);
+#ifdef HAVE_OPENSSL
+ if (opt_use_ssl)
+ mysql_ssl_set(&connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+ opt_ssl_capath);
+#endif
+ if (!(sock= mysql_real_connect(&connection,host,user,passwd,
+ NULL,opt_mysql_port,opt_mysql_unix_port,0)))
+ {
+ DBerror(&connection, "when trying to connect");
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+} /* dbConnect */
+
+
+/*
+ * ** dbDisconnect -- disconnects from the host.
+ * */
+void db_disconnect(char *host)
+{
+ DBUG_ENTER("db_disconnect");
+ DBUG_PRINT("enter",("host: '%s'", host));
+ if (verbose)
+ fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
+ mysql_close(sock);
+ DBUG_VOID_RETURN;
+} /* dbDisconnect */
+
+#define OUTPUT(x) strcpy(buffptr,x); buffptr+=strlen(x);
+#define OUTPUT_TOP(x) strcpy(topptr,x); topptr+=strlen(x);
+#define OUTPUT_MIDDLE(x) strcpy(midptr,x); midptr+=strlen(x);
+#define OUTPUT_BOTTOM(x) strcpy(botptr,x); botptr+=strlen(x);
+#define OUTPUT_HEADER(x) strcpy(hdrptr,x); hdrptr+=strlen(x);
+
+void db_show_result(MYSQL* sock, char *b, struct format *f)
+{
+ MYSQL_ROW row;
+ MYSQL_RES *result;
+ MYSQL_FIELD *field;
+ char *buffptr;
+ char topseparator[BUFLEN]="";
+ char middleseparator[BUFLEN]="";
+ char bottomseparator[BUFLEN]="";
+ char header[BUFLEN]="";
+ char *topptr=topseparator;
+ char *midptr=middleseparator;
+ char *botptr=bottomseparator;
+ char *hdrptr=header;
+ uint i,count, length;
+
+ DBUG_ENTER("db_show_result");
+ DBUG_PRINT("enter",("b: '%s', f '%x'", b, f));
+
+ result=mysql_store_result(sock);
+
+ buffptr=b;
+ OUTPUT(f->tablestart)
+
+ OUTPUT_TOP(f->leftuppercorner);
+ OUTPUT_MIDDLE(f->leftcross);
+ OUTPUT_BOTTOM(f->leftdowncorner);
+ OUTPUT_HEADER(f->headerrowstart);
+
+
+ count=mysql_num_fields(result);
+/* while ((field = mysql_fetch_field(result))) */
+ for(i=0 ; i < count ; ++i)
+ {
+ field = mysql_fetch_field(result);
+ length=(uint) strlen(field->name);
+ OUTPUT_HEADER(f->headercellstart);
+
+ length=max(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; /* Room for "NULL" */
+ field->max_length=length;
+
+ memset(topptr,'=',field->max_length);
+ memset(midptr,'-',field->max_length);
+ memset(botptr,'=',field->max_length);
+
+ sprintf(hdrptr,"%-*s",field->max_length,field->name);
+ /* num_flag[off]= IS_NUM(field->type); */
+
+ topptr+=field->max_length;
+ midptr+=field->max_length;
+ botptr+=field->max_length;
+ hdrptr+=field->max_length;
+
+ if(i<count-1) {
+ OUTPUT_TOP(f->topcross);
+ OUTPUT_MIDDLE(f->middlecross);
+ OUTPUT_BOTTOM(f->bottomcross);
+ OUTPUT_HEADER(f->headercellseparator);
+ }
+ }
+ OUTPUT_TOP(f->rightuppercorner);
+ OUTPUT_MIDDLE(f->rightcross);
+ OUTPUT_BOTTOM(f->rightdowncorner);
+
+ OUTPUT_HEADER(f->headercellend);
+ OUTPUT_HEADER(f->headerrowend);
+
+ OUTPUT(topseparator);
+ OUTPUT(header);
+ OUTPUT(middleseparator);
+ while(row=mysql_fetch_row(result)) {
+ mysql_field_seek(result,0);
+
+ OUTPUT(f->contentrowstart);
+ for(i=0 ; i < mysql_field_count(sock); ++i) {
+ field = mysql_fetch_field(result);
+ OUTPUT(f->contentcellstart);
+ sprintf(buffptr,"%-*s",field->max_length,row[i]);
+ buffptr+=field->max_length;
+
+ if(i==mysql_field_count(sock))
+ {
+ OUTPUT(f->contentcellend);
+ } else {
+ OUTPUT(f->contentcellseparator);
+ }
+ }
+ OUTPUT(f->contentrowend);
+ }
+ OUTPUT(bottomseparator);
+ OUTPUT(f->tableend);
+
+ mysql_free_result(result);
+ DBUG_VOID_RETURN;
+}
+
+
+int db_function(char *b,const char *server, const char *database,const char *table,const char *field, const char *value, const char* path, struct func_st *function)
+{
+ char buff[BUFLEN];
+ int i;
+ DBUG_ENTER("db_function");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s', field: '%s', path: '%s'", b, database, table, field,path));
+
+ if(*database) {
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to'%s'\n",database);
+ DBUG_RETURN(-1);
+ }
+ }
+
+ sprintf(buff,"%s",function->function);
+ search_and_replace("$database",database,buff);
+ search_and_replace("$table",table,buff);
+ search_and_replace("$field",field,buff);
+ search_and_replace("$value",value,buff);
+ DBUG_PRINT("info",("path: '%s'",path));
+ DBUG_PRINT("info",("sum: '%d'",(database[0] ? strlen(database)+1 : 0) +(table[0] ? strlen(table)+1 : 0) +(field[0] ? strlen(field)+1 : 0) +(value[0] ? strlen(value)+1 : 0) +1));
+ search_and_replace("$*",path+
+ (server[0] ? strlen(server)+1 : 0) +
+ (database[0] ? strlen(database)+1 : 0) +
+ (table[0] ? strlen(table)+1 : 0) +
+ (field[0] ? strlen(field)+1 : 0) +
+ (value[0] ? strlen(value)+1 : 0) +
+ function->length +
+ 1,buff);
+ DBUG_PRINT("info",("Executing constructed function query: '%s'", buff));
+ if (mysql_query(sock, buff))
+ {
+ printf("error when executing '%s'\n",buff);
+ sprintf(b,"ERROR %d: %s",mysql_error(sock),mysql_error(sock));
+ DBUG_VOID_RETURN;
+ }
+
+ db_show_result(sock, b, &Human);
+ DBUG_PRINT("info",("Returning: %s", b));
+ DBUG_RETURN(1);
+}
+
+int db_show_field(char *b,const char *database,const char *table, const char *field,const char *value, const char *param)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char buff[BUFLEN];
+ int i=0;
+ my_string *ptr;
+ DBUG_ENTER("db_show_field");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s', field: '%s' value: '%s'", b, database, table, field, value));
+
+ /* We cant output fields when one of these variables is missing */
+ if (!(database[0] && table[0] && field[0]))
+ DBUG_RETURN(-1);
+
+ my_init_dynamic_array(&field_array, sizeof(buff), 4096, 1024);
+
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to'%s'\n",database);
+ delete_dynamic(&field_array);
+ DBUG_RETURN(-1);
+ }
+
+ if(param) {
+ sprintf(buff,"%s",param);
+ } else {
+ sprintf(buff,"select %s from %s where %s='%s' LIMIT 1",field,table,field,value);
+ }
+ if (mysql_query(sock, buff))
+ {
+ printf("error when executing '%s'\n",buff);
+ delete_dynamic(&field_array);
+ DBUG_RETURN(-1);
+ }
+
+
+ db_show_result(sock,b,&Human);
+/* if(result=mysql_use_result(sock)) {
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i][BUFLEN],row[0]);
+ DBUG_PRINT("info",("field %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
+// ptr = (*dynamic_element(&field_array,i,row[0]));
+ i++;
+ }
+ }
+// fix_filenames((char *)b);
+ mysql_free_result(result);
+ */
+ delete_dynamic(&field_array);
+ DBUG_RETURN(i);
+
+}
+int db_show_fields(char *b,const char *database,const char *table)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ MYSQL_FIELD *field;
+ char buff[BUFLEN];
+ int i=0;
+
+ DBUG_ENTER("show_fields");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s'", b, database, table));
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to'%s'\n",database);
+ DBUG_RETURN(-1);
+ }
+ if(result=mysql_list_fields(sock,buff,NULL)) {
+
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i*BUFLEN],row[0]);
+ DBUG_PRINT("info",("field %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
+ i++;
+ }
+ }
+ mysql_free_result(result);
+ DBUG_RETURN(i);
+}
+
+int db_show_primary_keys(char *b,const char *database, const char *table)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char buff[BUFLEN];
+ char buff2[BUFLEN];
+ unsigned int i;
+
+ DBUG_ENTER("db_show_primary_keys");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s'", b, database, table));
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to '%s'\n",database);
+ DBUG_RETURN(-1);
+ }
+ sprintf(buff,"show keys from %s",table);
+ if (mysql_query(sock, buff))
+ {
+ printf("error when executing '%s'\n",buff);
+ DBUG_RETURN(0);
+ }
+ buff2[0]='\0';
+ if(result=mysql_use_result(sock)) {
+ while(row=mysql_fetch_row(result)) {
+ if(!strcasecmp(row[2],"PRIMARY")) {
+ strcat(buff2,row[4]);
+ strcat(buff2,",\"_\",");
+ }
+ }
+ buff2[strlen(buff2)-5]='\0';
+ if(!buff2[0])
+ DBUG_RETURN(-1); /* No PRIMARY keys in table */
+ DBUG_PRINT("info",("Keys: %s<- \n", buff2));
+ } else
+ DBUG_RETURN(-1); /* No keys in table */
+
+ sprintf(buff,"SELECT CONCAT(%s) AS X FROM %s LIMIT 256",buff2,table);
+ if (mysql_query(sock, buff))
+ {
+ printf("error when executing '%s'\n",buff);
+ DBUG_RETURN(0);
+ }
+ i=0;
+ if(result=mysql_use_result(sock)) {
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i*BUFLEN],row[0]);
+ fix_filenames(&b[i*BUFLEN]);
+ DBUG_PRINT("info",("primarykey %s at %x, %i", &b[i*BUFLEN],&b[i*BUFLEN],i));
+ if(i++ >= MAXDIRS)
+ break;
+ }
+ }
+ mysql_free_result(result);
+ DBUG_RETURN(i);
+}
+
+
+int db_show_keys(char *b,const char *database, const char *table)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char buff[BUFLEN];
+ int i=0;
+
+ DBUG_ENTER("show_keys");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s', table: '%s'", b, database, table));
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to'%s'\n",database);
+ DBUG_RETURN(-1);
+ }
+ sprintf(buff,"show keys from %s",table);
+ if (mysql_query(sock, buff))
+ {
+ printf("error when executing '%s'\n",buff);
+ DBUG_RETURN(0);
+ }
+ if(result=mysql_use_result(sock)) {
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i*BUFLEN],row[0]);
+ DBUG_PRINT("info",("Key %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
+ i++;
+ }
+ }
+ mysql_free_result(result);
+ DBUG_RETURN(i);
+}
+
+
+int db_show_tables(char *b,const char *database)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char buff[BUFLEN];
+ int i=0;
+
+ DBUG_ENTER("db_show_tables");
+ DBUG_PRINT("enter",("buffer: '%s', database: '%s'", b, database));
+ if (mysql_select_db(sock,database))
+ {
+ printf("error when changing database to '%s'\n",database);
+ DBUG_RETURN(-1);
+ }
+
+ if(result=mysql_list_tables(sock,NULL)) {
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i*BUFLEN],row[0]);
+ DBUG_PRINT("info",("table %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
+ i++;
+ }
+ }
+ mysql_free_result(result);
+ DBUG_RETURN(i);
+}
+
+/*
+ * Finds all servers we are connected to
+ * and stores them in array supplied.
+ * returns count of servers
+ */
+int
+db_show_servers(char *b,int size)
+{
+ char* bufptr;
+ char* buff[BUFLEN*2];
+ DBUG_ENTER("db_show_servers");
+ DBUG_PRINT("enter",("buffer: '%s', size: '%d'", b, size));
+ bufptr=mysql_get_host_info(sock);
+ /* FIXME: Actually we need to escape prohibited symbols in filenames */
+ fix_filenames(bufptr);
+ strcpy(b,bufptr);
+ DBUG_RETURN(1);
+}
+
+/*
+ * Finds all databases in server
+ * and stores them in array supplied.
+ * returns count of databases
+ */
+int
+db_show_databases(char *b,int size)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char buff[BUFLEN];
+ int i=0;
+
+ DBUG_ENTER("db_show_databases");
+ DBUG_PRINT("enter",("buffer: '%s', size: '%d'", b, size));
+ result=mysql_list_dbs(sock,NULL);
+ while(row=mysql_fetch_row(result))
+ {
+ strcpy(&b[i*BUFLEN],row[0]);
+ DBUG_PRINT("info",("database %s at %x", &b[i*BUFLEN],&b[i*BUFLEN]));
+ i++;
+ }
+ mysql_free_result(result);
+ DBUG_RETURN(i);
+}
+
+void db_load_formats()
+{
+
+ /* In future we should read these variables
+ * from configuration file/database here */
+
+ /* HTML output */
+ HTML.tablestart="<table>\n";
+
+ HTML.headerrowstart="<tr>";
+ HTML.headercellstart="<th>";
+ HTML.headercellseparator="</th><th>";
+ HTML.headercellend="</th>";
+ HTML.headerrowend="</tr>\n";
+ HTML.headerformat=0;
+
+ HTML.leftuppercorner="";
+ HTML.rightuppercorner="";
+ HTML.leftdowncorner="";
+ HTML.rightdowncorner="";
+ HTML.topcross="";
+ HTML.middlecross="";
+ HTML.bottomcross="";
+ HTML.leftcross="";
+ HTML.rightcross="";
+ HTML.bottomcross="";
+
+ HTML.contentrowstart="<tr>";
+ HTML.contentcellstart="<td>";
+ HTML.contentcellseparator="</td><td>";
+ HTML.contentcellend="</td>";
+ HTML.contentrowend="</tr>\n";
+ HTML.headerformat=0;
+
+ HTML.footerrowstart="";
+ HTML.footercellstart="";
+ HTML.footercellseparator="";
+ HTML.footercellend="";
+ HTML.footerrowend="\n";
+ HTML.footerformat=0;
+
+ HTML.tableend="</table>\n";
+
+/* Nice to look mysql client like output */
+
+ Human.tablestart="\n";
+
+ Human.headerrowstart="| ";
+ Human.headercellstart="";
+ Human.headercellseparator=" | ";
+ Human.headercellend=" |";
+ Human.headerrowend="\n";
+ Human.headerformat=1;
+
+ Human.leftuppercorner="/=";
+ Human.rightuppercorner="=\\\n";
+ Human.leftdowncorner="\\=";
+ Human.rightdowncorner="=/\n";
+ Human.leftcross="+-";
+ Human.rightcross="-+\n";
+ Human.topcross="=T=";
+ Human.middlecross="-+-";
+ Human.bottomcross="=`=";
+
+ Human.contentrowstart="| ";
+ Human.contentcellstart="";
+ Human.contentcellseparator=" | ";
+ Human.contentcellend=" |";
+ Human.contentrowend="\n";
+ Human.contentformat=1;
+
+ Human.footerrowstart="";
+ Human.footercellstart="";
+ Human.footercellseparator="";
+ Human.footercellend="";
+ Human.footerrowend="\n";
+ Human.footerformat=1;
+
+ Human.tableend="\n";
+
+/* Comma-separated format. For machine reading */
+
+ /* XML */
+
+/*
+ tee_fprintf(PAGER,"<?xml version=\"1.0\"?>\n\n<resultset statement=\"%s\">", statement);
+ (void) tee_fputs("\n <row>\n", PAGER);
+ data=(char*) my_malloc(lengths[i]*5+1, MYF(MY_WME));
+ tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ xmlencode(data, cur[i]);
+ tee_fprintf(PAGER, "</%s>\n", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ </row>\n" </resultset>\n*/
+}
+
+gptr db_load_functions()
+{
+ char *functions[]={
+ "database",".tables","SHOW TABLES","0",
+ "table",".status","SHOW TABLE STATUS FROM $table","0",
+ "table",".count","SELECT COUNT(*) FROM $table","0",
+ "table",".table","SELECT * FROM $table","0",
+ "table",".check","CHECK TABLE $table","0",
+ "table",".repair","REPAIR TABLE $table","0",
+ "key",".min","SELECT MIN($key) FROM $table","0",
+ "key",".max","SELECT MAX($key) FROM $table","0",
+ "key",".avg","SELECT AVG($key) FROM $table","0",
+ "server",".uptime","SHOW STATUS like 'Uptime'","0",
+ "server",".version","SELECT VERSION()","0",
+ "server",".execute","$*","1",
+ "root",".connect","CONNECT $*","0",
+ NULL,NULL,NULL,NULL
+ };
+ char buff[BUFLEN];
+ int i=0;
+ struct func_st func;
+ DBUG_ENTER("db_load_functions");
+ my_init_dynamic_array(&functions_array, sizeof(struct func_st), 4096, 1024);
+ while(functions[i]) {
+ strcpy(func.type_s, functions[i]); /* Type in string: "table"` */
+ strcpy(func.filename, functions[i+1]); /* Name like it appears on FS: "count" */
+ strcpy(func.function, functions[i+2]); /* Query: "SELECT COUNT(*) FROM `%table`" */
+ func.continuous= atoi(functions[i+3]); /* Query: "If command can be continued" */
+
+ if(!strcasecmp(func.type_s,"server"))
+ func.type=SERVER_FUNCTION;
+ else if(!strcasecmp(func.type_s,"table"))
+ func.type=TABLE_FUNCTION;
+ else if(!strcasecmp(func.type_s,"key"))
+ func.type=KEY_FUNCTION;
+ else if(!strcasecmp(func.type_s,"database"))
+ func.type=DATABASE_FUNCTION;
+ else if(!strcasecmp(func.type_s,"field"))
+ func.type=FIELD_FUNCTION;
+ else if(!strcasecmp(func.type_s,"root"))
+ func.type=ROOT_FUNCTION;
+ else func.type=NONE_FUNCTION;
+
+ func.length=strlen(func.filename); /* Filename length */
+ DBUG_PRINT("info",("func.type_s: %s",func.type_s));
+ DBUG_PRINT("info",("func.filename: %s",func.filename));
+ DBUG_PRINT("info",("func.function: %s",func.function));
+ DBUG_PRINT("info",("func.type: %d",func.type));
+ DBUG_PRINT("info",("func.continuous: %d",func.continuous));
+ DBUG_PRINT("info",("i: %d",i));
+ insert_dynamic(&functions_array,(gptr)&func);
+ i+=4;
+ }
+ DBUG_RETURN((gptr)&functions_array);
+}
diff --git a/fs/dump.sql b/fs/dump.sql
new file mode 100644
index 00000000000..c61669cecb5
--- /dev/null
+++ b/fs/dump.sql
@@ -0,0 +1,28 @@
+# MySQL dump 8.12
+#
+# Host: localhost Database: mysqlfs
+#--------------------------------------------------------
+# Server version 3.23.33
+
+#
+# Table structure for table 'functions'
+#
+
+CREATE TABLE functions (
+ type enum('server','database','table','field','key') NOT NULL default 'server',
+ name char(20) NOT NULL default '',
+ sql char(128) NOT NULL default '',
+ PRIMARY KEY (type,name)
+) TYPE=MyISAM;
+
+#
+# Dumping data for table 'functions'
+#
+
+INSERT INTO functions VALUES ('server','uptime','SHOW STATUS like \'Uptime\'');
+INSERT INTO functions VALUES ('server','version','SELECT VERSION()');
+INSERT INTO functions VALUES ('table','count','SELECT COUNT(*) FROM `%table`');
+INSERT INTO functions VALUES ('key','min','SELECT MIN(%key) FROM `%table`');
+INSERT INTO functions VALUES ('key','max','SELECT MAX(%key) FROM `%table`');
+INSERT INTO functions VALUES ('key','avg','SELECT AVG(%key) FROM `%table`');
+
diff --git a/fs/korbit-kernel-2.4.1-patch b/fs/korbit-kernel-2.4.1-patch
new file mode 100644
index 00000000000..d97b1dac344
--- /dev/null
+++ b/fs/korbit-kernel-2.4.1-patch
@@ -0,0 +1,35661 @@
+diff -urN linux-2.4.1/.cvsignore linux-2.4.1-korbit/.cvsignore
+--- linux-2.4.1/.cvsignore Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/.cvsignore Thu Feb 1 11:46:48 2001
+@@ -0,0 +1 @@
++makekorbit.sh
+diff -urN linux-2.4.1/KORBit.Announce linux-2.4.1-korbit/KORBit.Announce
+--- linux-2.4.1/KORBit.Announce Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/KORBit.Announce Thu Feb 1 11:46:48 2001
+@@ -0,0 +1,62 @@
++From sabre@nondot.org Fri Dec 8 15:15:43 2000
++Date: Fri, 8 Dec 2000 17:10:47 -0600 (CST)
++From: Chris Lattner <sabre@nondot.org>
++To: linux-kernel@vger.kernel.org, orbit-list@gnome.org
++Cc: korbit-cvs@lists.sourceforge.net
++Subject: ANNOUNCE: Linux Kernel ORB: kORBit
++
++
++This email is here to announce the availability of a port of ORBit (the
++GNOME ORB) to the Linux kernel. This ORB, named kORBit, is available from
++our sourceforge web site (http://korbit.sourceforge.net/). A kernel ORB
++allows you to write kernel extensions in CORBA and have the kernel call
++into them, or to call into the kernel through CORBA. This opens the door
++to a wide range of experiments/hacks:
++
++* We can now write device drivers in perl, and let them run on the iMAC
++ across the hall from you. :)
++* Through the use of a LD_PRELOAD'd syscall wrapper library, you can
++ forward system calls through CORBA to an arbitrary local/remote machine.
++* CORBA servers are implemented as Linux kernel modules, so they may be
++ dynamically loaded or unloaded from a running system at any time. CORBA
++ servers expose their IOR's through a /proc/corba filesystem.
++* Filesystems may be implemented as remote CORBA objects and mounted on
++ the local machine, by using 'mount -t corbafs -o IOR:... none /mnt/corba'
++
++This are just some of the features available _RIGHT_NOW_ that are
++supported by kORBit. I'm sure that YOU can think of many more.
++
++Implementation:
++We implemented this port by providing a user->kernel mapping layer that
++consists of providing standard system header files for the "user" code to
++#include. In these header files, we do the mapping required. For
++example, we implement a <stdio.h> that #defines printf to printk (as a
++trivial example). Only user level code sees or uses these wrappers... all
++of our modifications to the Linux kernel are contained within the
++linux/net/korbit subdirectory.
++
++This is currently implemented with a 2.4.0test10 kernel, although forward
++porting should be very easy. This project was implemented as a cs423
++semester project by Chris Lattner, Fredrik Vraalsen, Andy Reitz, and Keith
++Wessel at the University of Illinois @ Urbana Champaign.
++
++Unresolved issues:
++* Our poll model is not optimial. Currently we actually do a real poll on
++ a (struct socket *) set. This causes relatively high latencies (on the
++ order 1 second, worst case) for CORBA requests. Our waitqueues are not
++ working quite as well as they should. :)
++* Security is completely unimplemented. Someone could use corba
++ interfaces to read any file on your system, for example (if the
++ CORBA-FileServer module is installed). Thus, this is really more for
++ prototyping and development than actual real world use. :)
++
++If you have any questions or comments, please feel free to contact us at:
++
++Chris Lattner, Fredrik Vraalsen, Andy Reitz, Keith Wessel
++<korbit-cvs@lists.sourceforge.net>
++
++btw, yes we are quite crazy, but what good is it to be normal and
++conformist afterall? :)
++
++
++
+diff -urN linux-2.4.1/Makefile linux-2.4.1-korbit/Makefile
+--- linux-2.4.1/Makefile Tue Jan 30 09:19:26 2001
++++ linux-2.4.1-korbit/Makefile Thu Feb 1 15:48:45 2001
+@@ -70,7 +70,7 @@
+ # images. Uncomment if you want to place them anywhere other than root.
+ #
+
+-#export INSTALL_PATH=/boot
++export INSTALL_PATH=/boot
+
+ #
+ # INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
+diff -urN linux-2.4.1/README.korbit linux-2.4.1-korbit/README.korbit
+--- linux-2.4.1/README.korbit Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/README.korbit Thu Feb 1 11:46:48 2001
+@@ -0,0 +1,83 @@
++ ====================
++ KORBit: A CORBA ORB
++ For The Linux Kernel
++ ====================
++
++ Submitted as a final project in CS423 by
++ Chris Lattner <lattner@uiuc.edu>,
++ Andy Reitz <areitz@uiuc.edu>,
++ Fredrik Vraalsen <vraalsen@uiuc.edu>, and
++ Keith Wessel <kwessel@uiuc.edu>
++
++ December 8, 2000
++
++
++About:
++======
++KORBit is a port of the CORBA Object Request Broker ORBit to the Linux
++kernel. For more information, see http://korbit.sourceforge.net/
++
++In order to use this code, you need to have ORBit-0.5.3 or later
++installed (including the development environment). The KORBit server
++modules make use of the ORBit IDL Compiler during the build process.
++
++Building The Code:
++==================
++In order to compile and run KORBit you need a recent 2.4.0-test
++version of the Linux kernel (KORBit is developed on 2.4.0-test10).
++
++To obtain a copy of the KORBit source code, see the webpage above.
++Once you have untar'ed the source code, copy the contents of the linux
++subdirectory of KORBit into the Linux root source directory
++(e.g. /usr/src/linux).
++
++Run your favourite configuration option for Linux (e.g. 'make
++menuconfig'). To enable KORBit support in the kernel, go into the
++'Networking options' section of the configuration and enable 'Kernel
++ORB'. Then add the various CORBA services that you wish to run in the
++kernel.
++
++NOTE: The Kernel ORB *must* be compiled statically into the kernel
++(answer 'Y') and CORBA services *must* be compiled as modules (answer
++'M') at the moment.
++
++Then compile and install the Linux kernel in the standard way, e.g.:
++
++make dep ; make clean ; make bzImage ; make modules ; make modules_install
++
++Copy System.map and arch/<i386|whatever>/boot/bzImage to the proper
++places (/boot), edit your lilo.conf, run lilo and reboot.
++
++You should now be able to use CORBA in your Linux kernel! Remember,
++this is *pre-alpha* software! Use on your own risk! Don't come to us
++crying if your machine blows up...
++
++Using Our Example KORBit Objects:
++=================================
++The "CORBA Echo Server" is effectively our "hello world" object. Once
++loaded into the kernel, module will instantiate an object that
++implements the "echoString()" interface. This method allows the client
++to send a string, which will be printed on the system console. Then,
++it will return a random number, which the client will print. Thus,
++after running this test, you will verify that two-way communication is
++working between KORBit and your ORB of choice.
++
++To insert this module into your newly-compiled kernel, type
++
++insmod /lib/modules/2.4.0-test10/kernel/net/korbit/modules/Echo/server/corba-echo-server.o
++
++Next verify that this module is actually loaded, by invoking
++"lsmod". You should see something like this:
++
++ Module Size Used by
++ corba-echo-server 3344 0 (unused)
++
++Now, you can grab the IOR to this object by typing "cat
++/proc/corba/echo-server". Now, you need to build the echo client,
++which will use this IOR in order to connect to the echo server. This
++can be accomplished by simply changing to the
++"/usr/src/linux/net/korbit/modules/Echo/client" directory, and then
++typing "make". Once finished, simply type "./echo-client `cat
++/proc/corba/echo-server`", and then cross your fingers!
++
++
+diff -urN linux-2.4.1/Rules.make linux-2.4.1-korbit/Rules.make
+--- linux-2.4.1/Rules.make Sat Dec 30 00:07:19 2000
++++ linux-2.4.1-korbit/Rules.make Thu Feb 1 15:46:07 2001
+@@ -222,9 +222,9 @@
+
+ $(MODINCL)/%.ver: %.c
+ @if [ ! -r $(MODINCL)/$*.stamp -o $(MODINCL)/$*.stamp -ot $< ]; then \
+- echo '$(CC) $(CFLAGS) -E -D__GENKSYMS__ $<'; \
++ echo '$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $<'; \
+ echo '| $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp'; \
+- $(CC) $(CFLAGS) -E -D__GENKSYMS__ $< \
++ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $< \
+ | $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp; \
+ if [ -r $@ ] && cmp -s $@ $@.tmp; then echo $@ is unchanged; rm -f $@.tmp; \
+ else echo mv $@.tmp $@; mv -f $@.tmp $@; fi; \
+diff -urN linux-2.4.1/korbit.patch linux-2.4.1-korbit/korbit.patch
+--- linux-2.4.1/korbit.patch Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/korbit.patch Thu Feb 1 11:46:48 2001
+@@ -0,0 +1,43 @@
++--- linux/Rules.make.orig Wed Jan 31 22:50:40 2001
+++++ linux/Rules.make Thu Feb 1 01:39:46 2001
++@@ -222,9 +222,9 @@
++
++ $(MODINCL)/%.ver: %.c
++ @if [ ! -r $(MODINCL)/$*.stamp -o $(MODINCL)/$*.stamp -ot $< ]; then \
++- echo '$(CC) $(CFLAGS) -E -D__GENKSYMS__ $<'; \
+++ echo '$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $<'; \
++ echo '| $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp'; \
++- $(CC) $(CFLAGS) -E -D__GENKSYMS__ $< \
+++ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $< \
++ | $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp; \
++ if [ -r $@ ] && cmp -s $@ $@.tmp; then echo $@ is unchanged; rm -f $@.tmp; \
++ else echo mv $@.tmp $@; mv -f $@.tmp $@; fi; \
++--- linux/net/Config.in.orig Wed Jan 31 22:39:32 2001
+++++ linux/net/Config.in Thu Feb 1 01:40:02 2001
++@@ -30,6 +30,7 @@
++ fi
++ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
++ source net/khttpd/Config.in
+++ source net/korbit/Config.in
++ fi
++ fi
++ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
++--- linux/net/Makefile.orig Thu Feb 1 01:41:42 2001
+++++ linux/net/Makefile Thu Feb 1 01:41:35 2001
++@@ -7,7 +7,7 @@
++
++ O_TARGET := network.o
++
++-mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm netlink sched
+++mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm netlink sched korbit
++ export-objs := netsyms.o
++
++ subdir-y := core ethernet
++@@ -27,6 +27,7 @@
++ endif
++
++ subdir-$(CONFIG_KHTTPD) += khttpd
+++subdir-$(CONFIG_KORBIT) += korbit
++ subdir-$(CONFIG_NETLINK) += netlink
++ subdir-$(CONFIG_PACKET) += packet
++ subdir-$(CONFIG_NET_SCHED) += sched
+diff -urN linux-2.4.1/makekorbit.sh linux-2.4.1-korbit/makekorbit.sh
+--- linux-2.4.1/makekorbit.sh Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/makekorbit.sh Thu Feb 1 11:46:48 2001
+@@ -0,0 +1,4 @@
++#!/bin/sh
++
++make CFLAGS="-D__KERNEL__ -I`pwd`/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -march=k6 -DHAVE_CONFIG_H -DHAVE_UNISTD_H -I. -I.. -I../include -nostdinc" -C net/korbit TOPDIR=`pwd`
++
+diff -urN linux-2.4.1/net/CVS/Entries linux-2.4.1-korbit/net/CVS/Entries
+--- linux-2.4.1/net/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/CVS/Entries Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++D
+diff -urN linux-2.4.1/net/CVS/Entries.Log linux-2.4.1-korbit/net/CVS/Entries.Log
+--- linux-2.4.1/net/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/CVS/Entries.Log Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++A D/korbit////
+diff -urN linux-2.4.1/net/CVS/Repository linux-2.4.1-korbit/net/CVS/Repository
+--- linux-2.4.1/net/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/CVS/Repository Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net
+diff -urN linux-2.4.1/net/CVS/Root linux-2.4.1-korbit/net/CVS/Root
+--- linux-2.4.1/net/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/CVS/Root Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/Config.in linux-2.4.1-korbit/net/Config.in
+--- linux-2.4.1/net/Config.in Tue Oct 10 19:33:52 2000
++++ linux-2.4.1-korbit/net/Config.in Thu Feb 1 15:46:07 2001
+@@ -30,6 +30,7 @@
+ fi
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ source net/khttpd/Config.in
++ source net/korbit/Config.in
+ fi
+ fi
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+diff -urN linux-2.4.1/net/Makefile linux-2.4.1-korbit/net/Makefile
+--- linux-2.4.1/net/Makefile Sat Dec 30 00:07:24 2000
++++ linux-2.4.1-korbit/net/Makefile Thu Feb 1 15:46:07 2001
+@@ -7,7 +7,7 @@
+
+ O_TARGET := network.o
+
+-mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm netlink sched
++mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm netlink sched korbit
+ export-objs := netsyms.o
+
+ subdir-y := core ethernet
+@@ -27,6 +27,7 @@
+ endif
+
+ subdir-$(CONFIG_KHTTPD) += khttpd
++subdir-$(CONFIG_KORBIT) += korbit
+ subdir-$(CONFIG_NETLINK) += netlink
+ subdir-$(CONFIG_PACKET) += packet
+ subdir-$(CONFIG_NET_SCHED) += sched
+diff -urN linux-2.4.1/net/korbit/CVS/Entries linux-2.4.1-korbit/net/korbit/CVS/Entries
+--- linux-2.4.1/net/korbit/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/CVS/Entries Thu Feb 1 11:46:49 2001
+@@ -0,0 +1,6 @@
++/Config.in/1.3/Thu Feb 1 09:46:49 2001//
++/Makefile/1.7/Thu Feb 1 09:46:49 2001//
++/config.h/1.2/Thu Feb 1 09:46:49 2001//
++/exported_symbols.c/1.8/Thu Feb 1 09:46:49 2001//
++/korbit.h/1.2/Thu Feb 1 09:46:49 2001//
++D
+diff -urN linux-2.4.1/net/korbit/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/CVS/Entries.Log Thu Feb 1 11:47:15 2001
+@@ -0,0 +1,7 @@
++A D/IIOP////
++A D/ORBitutil////
++A D/include////
++A D/kglib////
++A D/modules////
++A D/orb////
++A D/sup////
+diff -urN linux-2.4.1/net/korbit/CVS/Repository linux-2.4.1-korbit/net/korbit/CVS/Repository
+--- linux-2.4.1/net/korbit/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/CVS/Repository Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit
+diff -urN linux-2.4.1/net/korbit/CVS/Root linux-2.4.1-korbit/net/korbit/CVS/Root
+--- linux-2.4.1/net/korbit/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/CVS/Root Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/Config.in linux-2.4.1-korbit/net/korbit/Config.in
+--- linux-2.4.1/net/korbit/Config.in Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/Config.in Thu Feb 1 11:46:49 2001
+@@ -0,0 +1,8 @@
++#
++# KORBit
++#
++
++#tristate ' Kernel ORB (EXPERIMENTAL)' CONFIG_KORBIT
++bool ' Kernel ORB (EXPERIMENTAL)' CONFIG_KORBIT
++
++source net/korbit/modules/Config.in
+diff -urN linux-2.4.1/net/korbit/IIOP/CVS/Entries linux-2.4.1-korbit/net/korbit/IIOP/CVS/Entries
+--- linux-2.4.1/net/korbit/IIOP/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/CVS/Entries Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,15 @@
++/IIOP-config.h/1.1.1.1/Thu Feb 1 09:46:50 2001//
++/IIOP-design.txt/1.1.1.1/Thu Feb 1 09:46:50 2001//
++/IIOP-private.h/1.2/Thu Feb 1 09:46:50 2001//
++/IIOP-types.h/1.1.1.1/Thu Feb 1 09:46:50 2001//
++/IIOP.h/1.1.1.1/Thu Feb 1 09:46:50 2001//
++/Makefile/1.4/Thu Feb 1 09:46:51 2001//
++/connection.c/1.19/Thu Feb 1 09:46:51 2001//
++/encoders.c/1.1.1.1/Thu Feb 1 09:46:51 2001//
++/giop-msg-buffer.c/1.12/Thu Feb 1 09:46:51 2001//
++/giop-msg-buffer.h/1.1.1.1/Thu Feb 1 09:46:51 2001//
++/iiop-encoders.h/1.1.1.1/Thu Feb 1 09:46:51 2001//
++/iiop-endian.c/1.1.1.1/Thu Feb 1 09:46:51 2001//
++/iiop-endian.h/1.1.1.1/Thu Feb 1 09:46:51 2001//
++/iiop-endianP.h/1.1.1.1/Thu Feb 1 09:46:51 2001//
++D
+diff -urN linux-2.4.1/net/korbit/IIOP/CVS/Repository linux-2.4.1-korbit/net/korbit/IIOP/CVS/Repository
+--- linux-2.4.1/net/korbit/IIOP/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/CVS/Repository Thu Feb 1 11:46:50 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/IIOP
+diff -urN linux-2.4.1/net/korbit/IIOP/CVS/Root linux-2.4.1-korbit/net/korbit/IIOP/CVS/Root
+--- linux-2.4.1/net/korbit/IIOP/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/CVS/Root Thu Feb 1 11:46:49 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/IIOP/IIOP-config.h linux-2.4.1-korbit/net/korbit/IIOP/IIOP-config.h
+--- linux-2.4.1/net/korbit/IIOP/IIOP-config.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/IIOP-config.h Thu Feb 1 11:46:50 2001
+@@ -0,0 +1,5 @@
++/* The size of the chunks that are used for indirect pieces of messages.
++ Too low, and you'll have a lot of malloc overhead. Too high, and you'll
++ get wasted mem.
++*/
++#define GIOP_INDIRECT_CHUNK_SIZE 1024
+diff -urN linux-2.4.1/net/korbit/IIOP/IIOP-design.txt linux-2.4.1-korbit/net/korbit/IIOP/IIOP-design.txt
+--- linux-2.4.1/net/korbit/IIOP/IIOP-design.txt Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/IIOP-design.txt Thu Feb 1 11:46:50 2001
+@@ -0,0 +1,14 @@
++
++void Hello_hello(CORBA_Object anobj, const char *arg1, CORBA_Environment *ev)
++
++If we're doing a local call (i.e. shared library object activation),
++just do it.
++
++If we're doing a remote call, we need to setup generic header
++(utilfunc), setup request header (utilfunc), encode arguments (stubs),
++send the message headers & body (utilfunc) and wait for a reply (XXX
++define more clearly). When we get the reply, we need to read the
++reply(utilfunc), decode the return value & out/inout arguments(stubs)
++& fill them in (or decode the exception that resulted (utilfunc)), and
++return.
++
+diff -urN linux-2.4.1/net/korbit/IIOP/IIOP-private.h linux-2.4.1-korbit/net/korbit/IIOP/IIOP-private.h
+--- linux-2.4.1/net/korbit/IIOP/IIOP-private.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/IIOP-private.h Thu Feb 1 11:46:50 2001
+@@ -0,0 +1,46 @@
++#ifndef IIOP_PRIVATE_H
++#define IIOP_PRIVATE_H 1
++
++
++#include "config.h"
++
++#if defined(HAVE_POLL) && defined(I_WANT_POLL)
++#define USE_POLL
++#else
++#undef USE_POLL
++#endif
++
++#ifdef HAVE_SYS_POLL_H
++#include <sys/poll.h>
++#endif
++
++#include <sys/time.h>
++#include <sys/types.h>
++#include <unistd.h>
++
++#include <glib.h>
++
++typedef struct {
++ GList *list;
++ gboolean connection_list_changed;
++#ifndef __KORBIT__
++ GPtrArray *fd_to_connection_mapping;
++#else /* __KORBIT__ */
++ GHashTable *fd_to_connection_mapping;
++#endif /* __KORBIT__ */
++# ifdef USE_POLL
++ GArray *pollset;
++# else
++ fd_set selectset_rd, selectset_ex;
++# endif
++ int max_fd;
++} GIOPConnectionList;
++
++extern GIOPConnectionList giop_connection_list;
++
++/* If you get a buffer that you didn't want, add it to the list! */
++void giop_received_list_push(GIOPRecvBuffer *recv_buffer);
++GIOPRecvBuffer *giop_received_list_pop(void);
++
++
++#endif
+diff -urN linux-2.4.1/net/korbit/IIOP/IIOP-types.h linux-2.4.1-korbit/net/korbit/IIOP/IIOP-types.h
+--- linux-2.4.1/net/korbit/IIOP/IIOP-types.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/IIOP-types.h Thu Feb 1 11:46:50 2001
+@@ -0,0 +1,76 @@
++#ifndef IIOP_TYPES_H
++#define IIOP_TYPES_H 1
++
++/* XXX todo sync this up with basic_types.h if needed */
++#include <unistd.h>
++#include <netinet/in.h>
++#include <sys/un.h>
++
++#include <ORBitutil/basic_types.h>
++
++typedef enum {
++ GIOP_CONNECTION_SERVER, /* Not a real connection to any place - just
++ listening */
++ GIOP_CONNECTION_CLIENT
++} GIOPConnectionClass;
++
++typedef struct _GIOPConnection GIOPConnection;
++struct _GIOPConnection {
++ enum { GIOP_CONNECTION_NONE, GIOP_CONNECTION_IIOP } connection_type;
++ void (*destroy_func)(GIOPConnection *connection);
++
++ gint refcount;
++ GIOPConnectionClass connection_class;
++
++ int fd;
++
++ /* You can access these if you wish. */
++ gpointer orb_data;
++ gpointer user_data;
++ /* end accessable stuff */
++
++ guchar is_valid, was_initiated, is_auth;
++
++ gpointer incoming_msg; /* GIOPRecvBuffer */
++};
++
++#define GIOP_CONNECTION(x) ((GIOPConnection *)(x))
++#define GIOP_CONNECTION_GET_FD(x) (GIOP_CONNECTION((x))->fd)
++
++typedef enum { IIOP_IPV4, IIOP_IPV6, IIOP_USOCK } IIOPConnectionType;
++
++typedef struct {
++ GIOPConnection giop_connection;
++
++ gboolean is_serversock;
++ IIOPConnectionType icnxtype;
++ union {
++ struct {
++ char *hostname;
++ struct sockaddr_in location;
++ } ipv4;
++ struct sockaddr_un usock;
++ /* Yes this is a config.h define, and no it doesn't matter,
++ because this structure should only be used internally anyways */
++#ifdef HAVE_IPV6
++ struct {
++ char *hostname;
++ struct sockaddr_in6 location;
++ } ipv6;
++#endif
++ } u;
++} IIOPConnection;
++
++#define IIOP_CONNECTION(x) ((IIOPConnection *)(x))
++
++#if defined(DEBUG_sopwith_connection_refcounting)
++#define giop_connection_ref(x) G_STMT_START{ (GIOP_CONNECTION(x)->refcount++); g_print("! reffing fd %d in " __PRETTY_FUNCTION__ ":%d to %d\n", GIOP_CONNECTION_GET_FD(x), __LINE__, GIOP_CONNECTION(x)->refcount); }G_STMT_END
++
++#define giop_connection_unref(x) G_STMT_START{ GIOP_CONNECTION(x)->refcount--; g_print("! dereffing fd %d in " __PRETTY_FUNCTION__ ":%d to %d\n", GIOP_CONNECTION_GET_FD(x), __LINE__, GIOP_CONNECTION(x)->refcount); if(GIOP_CONNECTION(x)->refcount <= 0) giop_connection_free(x); }G_STMT_END
++#else
++#define giop_connection_ref(x) G_STMT_START{ (GIOP_CONNECTION(x)->refcount++); }G_STMT_END
++
++#define giop_connection_unref(x) G_STMT_START{ GIOP_CONNECTION(x)->refcount--; if(GIOP_CONNECTION(x)->refcount <= 0) giop_connection_free(x); }G_STMT_END
++#endif
++
++#endif /* IIOP_TYPES_H */
+diff -urN linux-2.4.1/net/korbit/IIOP/IIOP.h linux-2.4.1-korbit/net/korbit/IIOP/IIOP.h
+--- linux-2.4.1/net/korbit/IIOP/IIOP.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/IIOP.h Thu Feb 1 16:19:47 2001
+@@ -0,0 +1,52 @@
++#ifndef IIOP_H
++#define IIOP_H 1
++
++#include <unistd.h>
++#include <ORBitutil/util.h>
++#include "IIOP-config.h"
++#include "IIOP-types.h"
++#include "giop-msg-buffer.h"
++#include "iiop-encoders.h"
++#include "iiop-endian.h"
++
++/* We don't speak GIOP 1.0, sosumi */
++#define GIOP_1_1
++
++
++void giop_init(const char *argv0);
++
++/* You use this to get a pointer to a new (or existing) connection
++ that has the specified host/port characteristics */
++IIOPConnection *iiop_connection_get(const char *host, gushort port,
++ gboolean existing_only);
++/* Similar, but for UNIX sockets */
++IIOPConnection *iiop_connection_unix_get(const char *sockpath,
++ gboolean existing_only);
++
++/* gives us a local socket that other people can connect to... */
++IIOPConnection *iiop_connection_server(void);
++IIOPConnection *iiop_connection_server_ipv6(void);
++IIOPConnection *iiop_connection_server_unix(const char *sockpath);
++
++void giop_main_quit(void);
++void giop_main(void); /* main loop for the program if none other is given,
++ and also used while waiting for a reply */
++void giop_main_iterate(gboolean blocking);
++void giop_main_handle_connection(GIOPConnection *connection);
++void giop_main_handle_connection_exception(GIOPConnection *connection);
++GIOPRecvBuffer *giop_main_next_message(gboolean blocking);
++GIOPRecvBuffer *giop_main_next_message_2(gboolean blocking,
++ GIOPConnection *monitor);
++GIOPConnection *giop_check_connections(gboolean block_for_reply);
++
++/* This assumes that the appropriate GIOP_CLOSECONNECTION message
++ has been sent to the peer */
++void giop_connection_free(GIOPConnection *connection);
++
++/* Called when a connection is created */
++extern void (*IIOPAddConnectionHandler)(GIOPConnection *newcnx);
++/* Called when a connection is about to be destroyed */
++extern void (*IIOPRemoveConnectionHandler)(GIOPConnection *oldcnx);
++extern void (*IIOPIncomingMessageHandler)(GIOPRecvBuffer *recv_buffer);
++
++#endif /* IIOP_H */
+diff -urN linux-2.4.1/net/korbit/IIOP/Makefile linux-2.4.1-korbit/net/korbit/IIOP/Makefile
+--- linux-2.4.1/net/korbit/IIOP/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/Makefile Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,18 @@
++#
++# Makefile for KORBit/IIOP
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .o file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := IIOPlib.o
++
++#obj-m := $(O_TARGET)
++obj-y := connection.o encoders.o giop-msg-buffer.o iiop-endian.o
++
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -I. -I.. -I../include -I../kglib -I../ORBitutil -nostdinc
++
++include $(TOPDIR)/Rules.make
+diff -urN linux-2.4.1/net/korbit/IIOP/connection.c linux-2.4.1-korbit/net/korbit/IIOP/connection.c
+--- linux-2.4.1/net/korbit/IIOP/connection.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/connection.c Thu Feb 1 19:26:07 2001
+@@ -0,0 +1,1565 @@
++#include "config.h"
++
++#if defined(HAVE_POLL) && defined(I_WANT_POLL)
++#define USE_POLL
++#else
++#undef USE_POLL
++#endif
++
++#ifndef _XOPEN_SOURCE_EXTENDED
++# define _XOPEN_SOURCE_EXTENDED 1
++# define WE_DEFINED_XOPEN_SOURCE_EXTENDED 1
++#endif
++#include "iiop-endianP.h"
++#ifdef WE_DEFINED_XOPEN_SOURCE_EXTENDED
++# undef _XOPEN_SOURCE_EXTENDED
++#endif
++#include "IIOP.h"
++#include "IIOP-private.h"
++#include "giop-msg-buffer.h"
++#include <stdlib.h>
++#include <unistd.h>
++#ifdef ORBIT_DEBUG
++#include <errno.h>
++#endif
++#include <sys/types.h>
++#include <fcntl.h>
++#include <sys/socket.h>
++#include <sys/un.h>
++#ifndef _XOPEN_SOURCE_EXTENDED
++# define _XOPEN_SOURCE_EXTENDED 1
++#endif
++#include <arpa/inet.h>
++#include <netdb.h>
++#ifdef WE_DEFINED_XOPEN_SOURCE_EXTENDED
++# undef _XOPEN_SOURCE_EXTENDED
++#endif
++#include <ctype.h>
++#include <string.h>
++#include <sys/time.h>
++#include <sys/ioctl.h>
++#include <signal.h>
++#include <syslog.h>
++#include <stdio.h>
++
++/*
++#ifdef O_NONBLOCK
++#undef O_NONBLOCK
++#endif
++#define O_NONBLOCK 0
++*/
++
++#if defined(HAVE_TCPD_H) && defined(HAVE_HOSTS_ACCESS)
++#include <tcpd.h>
++#endif
++
++#if 0
++#include <malloc.h>
++
++static struct mallinfo mi1, mi2;
++
++#define AM() mi1 = mallinfo();
++#define PM(x) mi2 = mallinfo(); printf(x ": used %d, now %d\n", \
++mi2.uordblks - mi1.uordblks, mi2.uordblks);
++#endif
++
++#ifdef HAVE_POLL
++#include <sys/poll.h>
++#endif
++
++#ifndef SUN_LEN
++/* This system is not POSIX.1g. */
++#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
++ + strlen ((ptr)->sun_path))
++#endif
++
++void (*IIOPAddConnectionHandler)(GIOPConnection *newcnx) = NULL;
++void (*IIOPRemoveConnectionHandler)(GIOPConnection *oldcnx) = NULL;
++void (*IIOPIncomingMessageHandler)(GIOPRecvBuffer *recv_buffer) = NULL;
++
++static void giop_connection_add_to_list (GIOPConnection *cnx);
++static void giop_connection_remove_from_list (GIOPConnection *cnx);
++
++static void iiop_init (void);
++static void iiop_connection_server_accept (GIOPConnection *connection);
++static void iiop_connection_destroy (IIOPConnection *connection);
++static IIOPConnection *iiop_connection_new (const char *host, gushort port);
++static IIOPConnection *iiop_connection_unix_new (const char *sockpath);
++static void iiop_unlink_unix_sockets (void);
++
++DEFINE_LOCK(giop_connection_list);
++GIOPConnectionList giop_connection_list;
++static GSList *iiop_unix_socket_list = NULL;
++
++#if defined(HAVE_HOSTS_ACCESS) && defined (HAVE_TCPD_H)
++static const char *argv0_val = NULL;
++#endif
++
++struct fd_hash_elem
++{
++ guint fd;
++ GIOPConnection *cnx;
++};
++
++static guint fd_hash_func(gconstpointer key)
++{
++ const guint *key_ptr = (guint *)key;
++ guint result = *key_ptr >> 2;
++ return result;
++}
++
++static gint fd_compare_func(gconstpointer a, gconstpointer b)
++{
++ const guint *a_ptr = (guint *)a;
++ const guint *b_ptr = (guint *)b;
++ return *a_ptr == *b_ptr;
++}
++
++static gboolean fd_hash_clear(gpointer key, gpointer value, gpointer user_data)
++{
++ struct fd_hash_elem *el = (struct fd_hash_elem *)value;
++ g_free(el);
++ return TRUE;
++}
++
++/*
++ * giop_init
++ *
++ * Inputs: None
++ * Outputs: None
++ *
++ * Side effects: Initializes giop_connection_list
++ * Global data structures used: giop_connection_list
++ *
++ * Description: Initializes giop_connection_list. Calls
++ * giop_message_buffer_init() to initialize the
++ * message_buffer subsystem. Calls iiop_init()
++ * to perform IIOP-specific initialization.
++ */
++
++void giop_init(const char *argv0)
++{
++#ifndef __KERNEL__
++ struct sigaction mypipe;
++#endif
++ g_assert(sizeof(GIOPMessageHeader) == 12);
++
++#if defined(HAVE_HOSTS_ACCESS) && defined (HAVE_TCPD_H)
++ argv0_val = g_strdup(g_basename(argv0)); /* For TCP wrappers */
++#endif
++
++#ifndef __KERNEL__
++ memset(&mypipe, '\0', sizeof(mypipe));
++ mypipe.sa_handler = SIG_IGN;
++
++ sigaction(SIGPIPE, &mypipe, NULL);
++#endif
++
++ giop_message_buffer_init();
++
++ INIT_LOCK(giop_connection_list);
++
++ giop_connection_list.list = NULL;
++ giop_connection_list.connection_list_changed = FALSE;
++
++#ifdef USE_POLL
++ giop_connection_list.pollset = g_array_new(FALSE, FALSE,
++ sizeof(struct pollfd));
++#else
++ FD_ZERO(&giop_connection_list.selectset_rd);
++ FD_ZERO(&giop_connection_list.selectset_ex);
++#endif
++
++#ifndef __KORBIT__
++ giop_connection_list.fd_to_connection_mapping = g_ptr_array_new();
++#else
++ giop_connection_list.fd_to_connection_mapping =
++ g_hash_table_new(&fd_hash_func,
++ &fd_compare_func);
++#endif
++
++ /*
++ * This also needs to do any transport-specific initialization
++ * as appropriate
++ */
++ iiop_init();
++}
++
++/*** giop_connection_init
++ *
++ * Inputs: 'giop_connection' - memory region allocated for use as a
++ * GIOPConnection.
++ * 'cnxclass' - the class of connection that will be stored
++ * here (SERVER, CLIENT)
++ *
++ * Outputs: None
++ *
++ * Side effects: Initializes 'giop_connection'.
++ *
++ * Description: Basic setup of a GIOPConnection.
++ * Sets is_valid to FALSE because it is the responsibility of
++ * the transport-specific initialization routine to make
++ * a connection valid.
++ */
++
++static void giop_connection_init(GIOPConnection *giop_connection,
++ GIOPConnectionClass cnxclass)
++{
++ giop_connection->connection_type = GIOP_CONNECTION_NONE;
++ giop_connection->refcount = 0;
++ giop_connection->connection_class = cnxclass;
++ giop_connection->is_valid = FALSE;
++ giop_connection->is_auth = FALSE;
++ giop_connection->was_initiated = FALSE;
++}
++
++/*
++ * giop_connection_free
++ * Inputs: 'connection'
++ * Outputs: None
++ * Side effects: Makes the 'connection' invalid as a GIOPConnection
++ * and as a gpointer.
++ *
++ * Description: Calls giop_connection_remove_from_list() to
++ * stop the connection from being used for incoming.
++ *
++ * If a transport-specific finalization function has
++ * been provided, call it.
++ *
++ * Free the memory block at '*connection'.
++ *
++ */
++void giop_connection_free(GIOPConnection *connection)
++{
++ g_return_if_fail(connection != NULL);
++ giop_connection_remove_from_list(connection);
++
++ if(connection->is_valid && connection->destroy_func)
++ connection->destroy_func(connection);
++
++ connection->is_valid = FALSE;
++
++ if(connection->incoming_msg) {
++ GIOPRecvBuffer *buf;
++
++ buf = connection->incoming_msg;
++ connection->incoming_msg = NULL;
++ giop_recv_buffer_unuse(buf);
++ }
++
++ g_free(connection);
++}
++
++/*
++ * giop_connection_list_recreate
++ *
++ * Inputs: None
++ * Outputs: None
++ *
++ * Side effects: giop_connection_list changes.
++ *
++ * Global data structures used: giop_connection_list
++ *
++ * Description:
++ * When new connections are added to giop_connection_list.list,
++ * the data structures passed to poll() or select() (OS-dependant)
++ * must be recreated to match this list.
++ *
++ * [We do this at add-connection/remove-connection time
++ * instead of every time a poll/select is done in order to
++ * speed things up a little]
++ *
++ * This function reinitializes the OS-specific file
++ * descriptor data structure and then adds all the file
++ * descriptors in the list to it.
++ *
++ * It also regenerates the array that maps file descriptors
++ * into GIOPConnection*'s
++ *
++ */
++static void
++giop_connection_list_recreate(void)
++{
++ int curfd;
++ GList *item;
++ GIOPConnection *cnx;
++#ifdef USE_POLL
++ struct pollfd new_poll;
++
++ new_poll.revents = 0;
++#endif
++
++ giop_connection_list.max_fd = 0;
++ for(item = giop_connection_list.list; item; item = g_list_next(item))
++ {
++ cnx = item->data;
++ curfd = GIOP_CONNECTION_GET_FD(cnx);
++
++ if(curfd > giop_connection_list.max_fd)
++ giop_connection_list.max_fd = curfd;
++ }
++
++#ifndef __KORBIT__
++ g_ptr_array_set_size(giop_connection_list.fd_to_connection_mapping,
++ giop_connection_list.max_fd + 1);
++#else
++ g_hash_table_foreach_remove(giop_connection_list.fd_to_connection_mapping,
++ fd_hash_clear,
++ NULL);
++#endif
++
++#ifdef USE_POLL
++ g_array_set_size(giop_connection_list.pollset, 0);
++#else
++ FD_ZERO(&giop_connection_list.selectset_rd);
++ FD_ZERO(&giop_connection_list.selectset_ex);
++#endif
++
++ for(item = giop_connection_list.list; item; item = g_list_next(item))
++ {
++ struct fd_hash_elem *el;
++
++ cnx = item->data;
++ curfd = GIOP_CONNECTION_GET_FD(cnx);
++
++#ifndef __KORBIT__
++ giop_connection_list.fd_to_connection_mapping->pdata[curfd] = cnx;
++#else
++ el = g_new(struct fd_hash_elem, 1);
++ el->fd = curfd;
++ el->cnx = cnx;
++ g_hash_table_insert(giop_connection_list.fd_to_connection_mapping,
++ &(el->fd),
++ el);
++#endif
++
++# ifdef USE_POLL
++ new_poll.fd = curfd;
++ new_poll.events = POLLIN|POLLPRI;
++ g_array_append_val(giop_connection_list.pollset,
++ new_poll);
++# else
++ FD_SET(curfd, &giop_connection_list.selectset_rd);
++ FD_SET(curfd, &giop_connection_list.selectset_ex);
++# endif
++ }
++}
++
++/*
++ * giop_connection_add_to_list
++ *
++ * Inputs: 'cnx' - a GIOPConnection that the user wishes added to the list
++ * Outputs: None
++ *
++ * Side effects: Modifies giop_connection_list
++ * Global data structures used: giop_connection_list
++ * Bugs: Does not check for duplicate additions.
++ *
++ * Description:
++ * Adds a connection to the list of active connections.
++ */
++static void
++giop_connection_add_to_list(GIOPConnection *cnx)
++{
++ g_return_if_fail(cnx->is_valid == FALSE);
++
++ cnx->is_valid = TRUE;
++
++ GET_LOCK(giop_connection_list);
++ giop_connection_list.list = g_list_prepend(giop_connection_list.list, cnx);
++
++ giop_connection_list_recreate();
++
++ RELEASE_LOCK(giop_connection_list);
++
++ if(IIOPAddConnectionHandler)
++ IIOPAddConnectionHandler(cnx);
++
++ giop_connection_ref(cnx);
++}
++
++/*
++ * giop_connection_remove_from_list
++ *
++ * Inputs: 'cnx' - a GIOPConnection that the user wishes
++ * Outputs: None
++ *
++ * Side effects: Modifies giop_connection_list
++ * Global data structures used: giop_connection_list
++ *
++ * Description:
++ * Removes a connection from the list of active connections.
++ * Calls the library user's "I removed connection" handler if it
++ * exists.
++ *
++ * Bugs: Does not check for duplicate removals. This may not be "bad" though.
++ */
++void
++giop_connection_remove_from_list(GIOPConnection *cnx)
++{
++ GList *link;
++
++ GET_LOCK(giop_connection_list);
++
++ link = g_list_find(giop_connection_list.list, cnx);
++
++ if(!link)
++ goto out;
++
++ if(IIOPRemoveConnectionHandler && cnx->is_valid)
++ IIOPRemoveConnectionHandler(cnx);
++
++ giop_connection_list.list = g_list_remove_link(giop_connection_list.list,
++ link);
++ g_list_free_1(link);
++
++ giop_connection_unref(cnx);
++
++ giop_connection_list_recreate();
++ out:
++ RELEASE_LOCK(giop_connection_list);
++}
++
++/************************************************
++ * Routines specific to the IIOP/IPv4 transport *
++ ************************************************/
++
++/*
++ * iiop_init
++ *
++ * Inputs: None
++ * Outputs: None
++ *
++ * Side effects: Initializes iiop_unix_socket_list
++ * Global data structures used: iiop_unix_socket_list
++ *
++ * Description: Initializes iiop_unix_socket_list.
++ * Registers Unix domain sockets for
++ * removal at server termination.
++ */
++static void
++iiop_init(void)
++{
++#ifndef __KERNEL__
++ g_atexit(iiop_unlink_unix_sockets);
++#endif
++}
++
++/*
++ * iiop_connection_init
++ *
++ * Inputs: 'connection' - a memory region that needs to be initialized as
++ * an 'IIOPConnection'.
++ *
++ * Side effects: initializes 'connection'
++ *
++ * Description: Performs the IIOP-specific initialization of an
++ * IIOPConnection. giop_connection_init is called.
++ *
++ */
++void
++iiop_connection_init(IIOPConnection *connection,
++ GIOPConnectionClass cnxclass,
++ IIOPConnectionType iioptype)
++{
++ giop_connection_init(GIOP_CONNECTION(connection), cnxclass);
++
++ GIOP_CONNECTION(connection)->connection_type =
++ GIOP_CONNECTION_IIOP;
++
++ GIOP_CONNECTION(connection)->destroy_func =
++ (void (*)(GIOPConnection *))iiop_connection_destroy;
++
++ connection->icnxtype = iioptype;
++}
++
++/*
++ * iiop_connection_from_fd
++ *
++ * Inputs: 'fd' - a file descriptor that attention should be paid to
++ * Outputs: 'fd_cnx' - the created connection
++ *
++ * Description: This is intended to be used on a file descriptor
++ * that has been accept()'d. It creates the connection
++ * and fills in the connection information, then adds
++ * it to the active list.
++ */
++IIOPConnection *
++iiop_connection_from_fd(int fd, IIOPConnection *parent)
++{
++ IIOPConnection *fd_cnx;
++ struct hostent *hent;
++ socklen_t n;
++
++ g_assert(fd >= 0);
++
++ fd_cnx = g_new0(IIOPConnection, 1);
++
++ iiop_connection_init(fd_cnx, GIOP_CONNECTION_CLIENT, parent->icnxtype);
++
++ GIOP_CONNECTION(fd_cnx)->fd = fd;
++
++ switch(parent->icnxtype) {
++ case IIOP_IPV4:
++ n = sizeof(struct sockaddr_in);
++ if(getpeername(GIOP_CONNECTION_GET_FD(fd_cnx), (struct sockaddr *)&fd_cnx->u.ipv4.location, &n))
++ {
++ fd_cnx->u.ipv4.hostname = g_strdup("");
++ }
++ else
++ {
++ hent = gethostbyaddr((const char *)&fd_cnx->u.ipv4.location.sin_addr.s_addr, 4, AF_INET);
++ if(hent)
++ {
++ fd_cnx->u.ipv4.hostname = g_strdup(hent->h_name);
++ }
++ else
++ {
++ fd_cnx->u.ipv4.hostname = inet_ntoa(*((struct in_addr *)&fd_cnx->u.ipv4.location.sin_addr));
++ }
++ }
++ break;
++
++ case IIOP_USOCK:
++ n = sizeof(struct sockaddr_un);
++ fd_cnx->u.usock.sun_family = AF_UNIX;
++ getpeername(GIOP_CONNECTION_GET_FD(fd_cnx),
++ (struct sockaddr *)&fd_cnx->u.usock, &n);
++ break;
++
++#ifdef HAVE_IPV6
++ case IIOP_IPV6:
++ n = sizeof(struct sockaddr_in6);
++ getpeername(GIOP_CONNECTION_GET_FD(fd_cnx),
++ (struct sockaddr *)&fd_cnx->u.ipv6.location, &n);
++ hent = gethostbyaddr((const char *)&fd_cnx->u.ipv6.location.sin6_addr,
++ sizeof(fd_cnx->u.ipv6.location.sin6_addr), AF_INET6);
++ fd_cnx->u.ipv6.hostname = g_strdup(hent->h_name);
++ break;
++#endif
++
++ default:
++ g_error("Unsupported connection type %d", parent->icnxtype);
++ }
++
++ fcntl(GIOP_CONNECTION_GET_FD(fd_cnx), F_SETFD,
++ fcntl(GIOP_CONNECTION_GET_FD(fd_cnx), F_GETFD, 0)
++ | FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(fd_cnx), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(fd_cnx), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "iiop_connection_from_fd connect [%d]\n",
++ GIOP_CONNECTION_GET_FD(fd_cnx));
++
++ giop_connection_add_to_list(GIOP_CONNECTION(fd_cnx));
++
++ return fd_cnx;
++}
++
++/*
++ * iiop_connection_server
++ *
++ * Outputs: 'server_cnx'
++ *
++ * Description: Creates a special IIOPConnection on which incoming
++ * connections come.
++ */
++IIOPConnection *
++iiop_connection_server(void)
++{
++ struct hostent *hent;
++ char hn_tmp[65];
++ socklen_t n;
++ IIOPConnection *server_cnx = g_new0(IIOPConnection, 1);
++
++ iiop_connection_init(server_cnx, GIOP_CONNECTION_SERVER, IIOP_IPV4);
++
++ server_cnx->is_serversock = TRUE;
++ GIOP_CONNECTION(server_cnx)->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
++
++ if(GIOP_CONNECTION_GET_FD(server_cnx) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_server: socket_error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ server_cnx->u.ipv4.location.sin_family = AF_INET;
++ server_cnx->u.ipv4.location.sin_addr.s_addr = INADDR_ANY;
++ bind(GIOP_CONNECTION_GET_FD(server_cnx),
++ (struct sockaddr *)&server_cnx->u.ipv4.location,
++ sizeof(struct sockaddr_in));
++
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_SETFD,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_GETFD, 0)
++ | FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ n = sizeof(struct sockaddr_in);
++ getsockname(GIOP_CONNECTION_GET_FD(server_cnx),
++ (struct sockaddr *)&server_cnx->u.ipv4.location, &n);
++
++ gethostname(hn_tmp, sizeof(hn_tmp) - 1);
++
++ hent = gethostbyname(hn_tmp);
++ if(hent)
++ {
++ if (strchr (hent->h_name, '.'))
++ server_cnx->u.ipv4.hostname = g_strdup(hent->h_name);
++ else
++ {
++ struct in_addr * addr = (struct in_addr *) hent->h_addr_list[0];
++ g_assert (hent->h_length == sizeof (struct in_addr) && addr);
++ server_cnx->u.ipv4.hostname = g_strdup (inet_ntoa (*addr));
++ }
++ }
++ else
++ server_cnx->u.ipv4.hostname = g_strdup(hn_tmp);
++
++ listen(GIOP_CONNECTION_GET_FD(server_cnx), 5);
++
++ giop_connection_add_to_list(GIOP_CONNECTION(server_cnx));
++
++ return server_cnx;
++
++failed:
++ close(GIOP_CONNECTION_GET_FD(server_cnx));
++ GIOP_CONNECTION(server_cnx)->fd = -1;
++ giop_connection_free(GIOP_CONNECTION(server_cnx));
++ server_cnx = NULL;
++ /*
++ * FIXME: GET_LOCK and DEFINE_LOCK never called for server_cnx
++ RELEASE_LOCK(server_cnx);
++ */
++ return NULL;
++}
++
++/*
++ * iiop_connection_server_ipv6
++ * Outputs: 'server_cnx'
++ *
++ * Description: Create a special IIOPConnection on which incoming
++ * connections come.
++ */
++IIOPConnection *
++iiop_connection_server_ipv6(void)
++{
++#ifdef HAVE_IPV6
++ struct hostent *hent, *hent2;
++
++ char hn_tmp[65];
++ int n;
++ IIOPConnection *server_cnx;
++
++ g_error("IPv6 support is baroquen! (Actually just never worked)");
++
++ server_cnx = g_new0(IIOPConnection, 1);
++
++ iiop_connection_init(server_cnx, GIOP_CONNECTION_SERVER, IIOP_IPV6);
++
++ server_cnx->is_serversock = TRUE;
++ GIOP_CONNECTION(server_cnx)->fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
++
++ if(GIOP_CONNECTION_GET_FD(server_cnx) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_server_ipv6: socket_error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ server_cnx->u.ipv6.location.sin6_family = AF_INET6;
++ bind(GIOP_CONNECTION_GET_FD(server_cnx),
++ (struct sockaddr *)&server_cnx->u.ipv6.location,
++ sizeof(struct sockaddr_in6));
++
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_SETFD,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_GETFD, 0)
++ | FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ n = sizeof(struct sockaddr_in6);
++ getsockname(GIOP_CONNECTION_GET_FD(server_cnx), &server_cnx->u.ipv6.location, &n);
++
++ gethostname(hn_tmp, sizeof(hn_tmp) - 1);
++
++ hent = gethostbyname(hn_tmp);
++ if(hent) {
++ hent2 = gethostbyaddr(hent->h_addr, sizeof(server_cnx->u.ipv6.location.sin6_addr), AF_INET6);
++ if(hent2)
++ server_cnx->hostname = g_strdup(hent2->h_name);
++ else
++ server_cnx->hostname = g_strdup(hn_tmp);
++ } else
++ server_cnx->hostname = g_strdup(hn_tmp);
++
++ listen(GIOP_CONNECTION_GET_FD(server_cnx), 5);
++
++ giop_connection_add_to_list(GIOP_CONNECTION(server_cnx));
++
++ return server_cnx;
++
++failed:
++ close(GIOP_CONNECTION_GET_FD(server_cnx));
++ GIOP_CONNECTION(server_cnx)->fd = -1;
++ giop_connection_free(GIOP_CONNECTION(server_cnx));
++ server_cnx = NULL;
++ /*
++ * FIXME: GET_LOCK and DEFINE_LOCK never called for server_cnx
++ RELEASE_LOCK(server_cnx);
++ */
++#endif
++ return NULL;
++}
++
++/*
++ * iiop_connection_server_unix
++ *
++ * Outputs: 'server_cnx_unix'
++ *
++ * Side effects: Initializes 'server_cnx_unix' if not initialized.
++ *
++ * Description: Return a special IIOPConnection on which incoming connections
++ * come. If not already initialized, it creates the connection,
++ * otherwise it returns the existing one.
++ * This is
++ */
++IIOPConnection *
++iiop_connection_server_unix(const char *sockpath)
++{
++ IIOPConnection *server_cnx_unix;
++
++ g_assert(sockpath && *sockpath);
++
++ server_cnx_unix = g_new0(IIOPConnection, 1);
++
++ iiop_connection_init(server_cnx_unix, GIOP_CONNECTION_SERVER, IIOP_USOCK);
++
++ server_cnx_unix->is_serversock = TRUE;
++ GIOP_CONNECTION(server_cnx_unix)->fd = socket(AF_UNIX, SOCK_STREAM, 0);
++
++ if(GIOP_CONNECTION_GET_FD(server_cnx_unix) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_server_unix: socket_error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ strcpy(server_cnx_unix->u.usock.sun_path, sockpath);
++
++ server_cnx_unix->u.usock.sun_family = AF_UNIX;
++ if(bind(GIOP_CONNECTION_GET_FD(server_cnx_unix),
++ (struct sockaddr *)&server_cnx_unix->u.usock,
++ SUN_LEN(&server_cnx_unix->u.usock)) != 0) {
++ /* see the comment in iiop_connection_destroy switch as to why we
++ close it here. bad hack */
++ close(GIOP_CONNECTION_GET_FD(server_cnx_unix));
++ GIOP_CONNECTION(server_cnx_unix)->fd = -1;
++ goto failed;
++ }
++
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx_unix), F_SETFD,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx_unix), F_GETFD, 0)
++ | FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx_unix), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(server_cnx_unix), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ if(listen(GIOP_CONNECTION_GET_FD(server_cnx_unix), 5) != 0)
++ goto failed;
++
++ giop_connection_add_to_list(GIOP_CONNECTION(server_cnx_unix));
++ iiop_unix_socket_list = g_slist_prepend(iiop_unix_socket_list,
++ server_cnx_unix);
++
++ /*
++ * FIXME: GET_LOCK and DEFINE_LOCK never called for server_cnx_unix
++ RELEASE_LOCK(server_cnx_unix);
++ */
++
++ return server_cnx_unix;
++
++failed:
++ close(GIOP_CONNECTION_GET_FD(server_cnx_unix));
++ GIOP_CONNECTION(server_cnx_unix)->fd = -1;
++ giop_connection_free(GIOP_CONNECTION(server_cnx_unix));
++ server_cnx_unix = NULL;
++ /*
++ * FIXME: GET_LOCK and DEFINE_LOCK never called for server_cnx_unix
++ RELEASE_LOCK(server_cnx_unix);
++ */
++ return NULL;
++}
++
++/*
++ * iiop_unlink_unix_sockets(void)
++ *
++ * Inputs: None
++ * Outputs: None
++ *
++ * Side effects: Modifies iiop_unix_socket_list
++ * Global data structures used: iiop_unix_socket_list
++ *
++ * Description:
++ * Unlinks any Unix server sockets created.
++ * Called during program termination.
++ */
++static void
++iiop_unlink_unix_sockets(void)
++{
++ GSList *item;
++
++ for (item = iiop_unix_socket_list;
++ item; item = g_slist_next(item)) {
++ GIOPConnection *cnx;
++
++ cnx = GIOP_CONNECTION(item->data);
++ if(cnx->connection_class == GIOP_CONNECTION_SERVER)
++ unlink(IIOP_CONNECTION(cnx)->u.usock.sun_path);
++ }
++
++ if (iiop_unix_socket_list) {
++ g_slist_free(iiop_unix_socket_list);
++ iiop_unix_socket_list = NULL;
++ }
++}
++
++/*
++ * iiop_connection_get
++ *
++ * Inputs: 'host' - the hostname (or dotted quad) of the remote host that
++ * will be connected
++ * 'port' - the port number on the above host to connect to.
++ * 'existing_only' - don't create a new connection if
++ * an existing one with the specified host:port
++ * doesn't exist.
++ *
++ * Outputs: 'cnx' - the connection to the specified host:port, or
++ * NULL upon error.
++ *
++ * Description: Returns an IIOPConnection that is connected to the
++ * specified host:port. If a connection already exists to the
++ * host:port, just returns it. Otherwise, calls
++ * 'iiop_connection_new' to create a new connection
++ * to host:port.
++ */
++IIOPConnection *
++iiop_connection_get(const char *host, gushort port, gboolean existing_only)
++{
++ IIOPConnection *cnx = NULL, *tmp;
++ GList *link;
++
++ g_assert(host);
++ g_assert(port);
++
++ GET_LOCK(giop_connection_list);
++ for(link = giop_connection_list.list; link; link = link->next)
++ {
++ tmp = IIOP_CONNECTION(link->data);
++ if(GIOP_CONNECTION(tmp)->connection_type != GIOP_CONNECTION_IIOP)
++ continue;
++
++ if(!GIOP_CONNECTION(tmp)->is_valid)
++ continue;
++
++ if(GIOP_CONNECTION(tmp)->connection_class != GIOP_CONNECTION_CLIENT)
++ continue;
++
++ if(IIOP_CONNECTION(tmp)->icnxtype != IIOP_IPV4)
++ continue;
++
++ if(!strcmp(host, tmp->u.ipv4.hostname)
++ && htons(port) == tmp->u.ipv4.location.sin_port) {
++ cnx = tmp;
++ break;
++ }
++ }
++ RELEASE_LOCK(giop_connection_list);
++
++ if(!cnx && !existing_only)
++ cnx = iiop_connection_new(host, port);
++
++ return cnx;
++}
++
++
++/*
++ * iiop_connection_new
++ *
++ * Inputs: same meanings as in 'iiop_connection_get'
++ * Outputs: 'retval' - newly created IIOPConnection
++ *
++ * Description: Allocates and initializes a new IIOPConnection,
++ * turns 'host' into an IP address, and then makes a TCP
++ * connection to host:port. Adds it to the list of active
++ * connections.
++ */
++IIOPConnection *
++iiop_connection_new(const char *host, gushort port)
++{
++ IIOPConnection *retval;
++
++ g_return_val_if_fail(host != NULL && port != 0, NULL);
++
++ retval = g_new0(IIOPConnection, 1);
++
++ iiop_connection_init(retval, GIOP_CONNECTION_CLIENT, IIOP_IPV4);
++
++ GIOP_CONNECTION(retval)->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
++ if(GIOP_CONNECTION_GET_FD(retval) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_new: socket_error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ retval->u.ipv4.hostname = g_strdup(host);
++
++ retval->u.ipv4.location.sin_port = htons(port);
++ retval->u.ipv4.location.sin_family = AF_INET;
++ if(!inet_aton(host, &retval->u.ipv4.location.sin_addr))
++ {
++ struct hostent *hent;
++ hent = gethostbyname(host);
++ if(!hent) {
++ /* a (char *)h_strerror(int) function would be nice here */
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_new: gethostbyname error: %d\n", h_errno);
++ goto failed;
++ }
++ memcpy(&retval->u.ipv4.location.sin_addr, hent->h_addr, (size_t) sizeof(retval->u.ipv4.location.sin_addr));
++ }
++ if(connect(GIOP_CONNECTION_GET_FD(retval), (struct sockaddr *)&retval->u.ipv4.location, sizeof(retval->u.ipv4.location)) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_new: connect error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "iiop_connection_new connect [%d] to %s:%d\n",
++ GIOP_CONNECTION_GET_FD(retval),
++ host, (guint)port);
++
++
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_SETFD, FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ GIOP_CONNECTION(retval)->was_initiated = TRUE;
++ GIOP_CONNECTION(retval)->is_auth = TRUE;
++
++ giop_connection_add_to_list(GIOP_CONNECTION(retval));
++
++ return retval;
++
++failed:
++ close(GIOP_CONNECTION_GET_FD(retval));
++ GIOP_CONNECTION(retval)->fd = -1;
++ giop_connection_free(GIOP_CONNECTION(retval));
++ return NULL;
++}
++
++/*
++ * iiop_connection_unix_get
++ *
++ * Inputs: 'sockpath' - Of the format 'path'
++ *
++ * Outputs: 'cnx' - the connection to the specified path, or
++ * NULL upon error.
++ *
++ * Description: Returns an IIOPConnection that is connected to the
++ * specified UNIX socket, if possible. If a connection
++ * already exists, just returns it. Otherwise,
++ * calls 'iiop_connection_unix_new' to create a new
++ * connection to sockpath.
++ */
++IIOPConnection *
++iiop_connection_unix_get(const char *sockpath, gboolean existing_only)
++{
++ IIOPConnection *cnx = NULL, *tmp;
++ GList *link;
++
++ GET_LOCK(giop_connection_list);
++ for(link = giop_connection_list.list; link; link = link->next)
++ {
++ tmp = IIOP_CONNECTION(link->data);
++
++ if(GIOP_CONNECTION(tmp)->connection_type != GIOP_CONNECTION_IIOP)
++ continue;
++
++ if(!GIOP_CONNECTION(tmp)->is_valid)
++ continue;
++
++ if(GIOP_CONNECTION(tmp)->connection_class != GIOP_CONNECTION_CLIENT)
++ continue;
++
++ if(IIOP_CONNECTION(tmp)->icnxtype != IIOP_USOCK)
++ continue;
++
++ if(!strcmp(sockpath, tmp->u.usock.sun_path)) {
++ cnx = tmp;
++ break;
++ }
++ }
++ RELEASE_LOCK(giop_connection_list);
++
++ if(!cnx && !existing_only)
++ cnx = iiop_connection_unix_new(sockpath);
++
++ return cnx;
++}
++
++/*
++ * iiop_connection_unix_new
++ *
++ * Inputs:
++ *
++ * Outputs: 'retval' - newly created IIOPConnection, or NULL upon error
++ *
++ * Description: Creates a connection to a UNIX socket (if possible)
++ * Adds it to the list of active connections.
++ */
++static IIOPConnection *
++iiop_connection_unix_new(const char *sockpath)
++{
++ IIOPConnection *retval;
++
++ retval = g_new0(IIOPConnection, 1);
++
++ retval->u.usock.sun_family = AF_UNIX;
++
++ g_snprintf(retval->u.usock.sun_path,
++ sizeof(retval->u.usock.sun_path), "%s", sockpath);
++
++ iiop_connection_init(retval, GIOP_CONNECTION_CLIENT, IIOP_USOCK);
++
++ GIOP_CONNECTION(retval)->fd = socket(AF_UNIX, SOCK_STREAM, 0);
++ if(GIOP_CONNECTION_GET_FD(retval) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_new: socket_error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ if(connect(GIOP_CONNECTION_GET_FD(retval), (struct sockaddr *)&retval->u.usock, SUN_LEN(&retval->u.usock)) < 0) {
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug, "iiop_connection_new: connect error: %s\n", strerror(errno));
++ goto failed;
++ }
++
++ GIOP_CONNECTION(retval)->was_initiated = TRUE;
++ GIOP_CONNECTION(retval)->is_auth = TRUE;
++
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_SETFD, FD_CLOEXEC);
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_SETFL,
++ fcntl(GIOP_CONNECTION_GET_FD(retval), F_GETFL, 0)
++ | O_NONBLOCK);
++
++ giop_connection_add_to_list(GIOP_CONNECTION(retval));
++
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "iiop_connection_unix_new connect [%d] to %s\n",
++ GIOP_CONNECTION_GET_FD(retval),
++ sockpath);
++
++ return retval;
++
++failed:
++ close(GIOP_CONNECTION_GET_FD(retval));
++ GIOP_CONNECTION(retval)->fd = -1;
++ giop_connection_free(GIOP_CONNECTION(retval));
++ return NULL;
++}
++
++/*
++ * iiop_connection_server_accept
++ * Inputs: 'connection' - a server IIOPConnection.
++ *
++ * Description: Performs accept(), TCP wrapper, access checking and related
++ * duties on a connection
++ */
++int allow_severity = LOG_INFO, deny_severity = LOG_NOTICE;
++
++#if defined(HAVE_HOSTS_ACCESS) && defined(HAVE_TCPD_H)
++DEFINE_LOCK(tcp_wrappers_usage);
++
++#endif
++static void
++iiop_connection_server_accept(GIOPConnection *connection)
++{
++ struct sockaddr sock;
++ socklen_t n;
++ int newfd;
++ GIOPConnection *newcnx;
++
++// printk("iiop_conncetion_server_accept( %d )\n",
++// GIOP_CONNECTION_GET_FD(connection));
++
++ n = sizeof(sock);
++
++ switch(IIOP_CONNECTION(connection)->icnxtype) {
++ case IIOP_IPV4: sock.sa_family = AF_INET; break;
++ case IIOP_USOCK: sock.sa_family = AF_UNIX; break;
++ case IIOP_IPV6:
++#ifdef HAVE_IPV6
++ sock.sa_family = AF_INET6;
++#endif
++ break;
++ }
++
++ newfd = accept(GIOP_CONNECTION_GET_FD(connection), &sock, &n);
++
++#if defined(HAVE_HOSTS_ACCESS) && defined(HAVE_TCPD_H)
++ /* tcp wrappers access checking */
++ switch(IIOP_CONNECTION(connection)->icnxtype) {
++ case IIOP_IPV4:
++ {
++ struct request_info request;
++
++ GET_LOCK(tcp_wrappers_usage);
++
++ request_init(&request, RQ_DAEMON, argv0_val, RQ_FILE, newfd, 0);
++
++ fromhost(&request);
++ if(!hosts_access(&request)) {
++ syslog(deny_severity, "[orbit] refused connect from %s", eval_client(&request));
++ close(newfd); newfd = -1;
++ } else
++ syslog(allow_severity, "[orbit] connect from %s", eval_client(&request));
++
++ RELEASE_LOCK(tcp_wrappers_usage);
++ }
++ break;
++ default:
++ /* No access controls for these transports */
++ break;
++ }
++#endif
++
++ if(newfd >= 0) {
++ newcnx = GIOP_CONNECTION(iiop_connection_from_fd(newfd,
++ IIOP_CONNECTION(connection)));
++ GIOP_CONNECTION(newcnx)->orb_data = connection->orb_data;
++ switch(IIOP_CONNECTION(connection)->icnxtype) {
++ case IIOP_USOCK: newcnx->is_auth = TRUE; break;
++ default:
++ break;
++ }
++ }
++}
++
++/*
++ * iiop_connection_destroy
++ *
++ * Inputs: 'iiop_connection' - an IIOPConnection to be finalized
++ *
++ * Side effects: invalidates 'iiop_connection' for use as an IIOPConnection
++ *
++ * Description: Performs the IIOP-specific parts of connection shutdown,
++ * including sending a CLOSECONNECTION message to the remote side.
++ */
++static void
++iiop_connection_destroy(IIOPConnection *iiop_connection)
++{
++ const GIOPMessageHeader mh = {"GIOP", {1,0}, FLAG_ENDIANNESS,
++ GIOP_CLOSECONNECTION, 0};
++
++ switch(iiop_connection->icnxtype) {
++ case IIOP_IPV4:
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "iiop_connection_destroy connect [%d] of %s:%d\n",
++ GIOP_CONNECTION_GET_FD(iiop_connection),
++ iiop_connection->u.ipv4.hostname,
++ ntohs(iiop_connection->u.ipv4.location.sin_port));
++ g_free(iiop_connection->u.ipv4.hostname);
++ break;
++ case IIOP_IPV6:
++#ifdef HAVE_IPV6
++ g_free(iiop_connection->u.ipv6.hostname);
++#else
++ g_warning("IPv6 unsupported, can't free it!");
++#endif
++ break;
++ case IIOP_USOCK:
++ /* why do we check if fd is > 0 here?
++ the orb code tries to reuse existing socket connection points.
++ If binding to any of those fails because another process is using it,
++ we don't want to unlink the other server's socket!
++ if the bind fails, iiop_connection_server_unix closes the fd for us */
++ if(GIOP_CONNECTION(iiop_connection)->connection_class == GIOP_CONNECTION_SERVER
++ && GIOP_CONNECTION(iiop_connection)->fd >= 0)
++ unlink(iiop_connection->u.usock.sun_path);
++ break;
++ default:
++ break;
++ }
++
++ if(GIOP_CONNECTION_GET_FD(iiop_connection) >= 0) {
++ if(GIOP_CONNECTION(iiop_connection)->is_valid
++ && !GIOP_CONNECTION(iiop_connection)->was_initiated)
++ {
++ write(GIOP_CONNECTION_GET_FD(iiop_connection), &mh, sizeof(mh));
++ }
++
++ shutdown(GIOP_CONNECTION_GET_FD(iiop_connection), 2);
++ close(GIOP_CONNECTION_GET_FD(iiop_connection));
++ GIOP_CONNECTION(iiop_connection)->fd = -1;
++ }
++}
++
++static int giop_nloops = 0;
++
++void giop_main_quit(void) { giop_nloops--; }
++
++void
++giop_main(void)
++{
++ int looplevel;
++
++ looplevel = ++giop_nloops;
++
++ while(giop_nloops > 0) {
++
++ giop_main_iterate(TRUE);
++
++ if(giop_nloops != looplevel) {
++ giop_nloops = --looplevel;
++ return;
++ }
++ }
++}
++
++GIOPRecvBuffer *
++giop_main_next_message(gboolean blocking)
++{
++ return giop_main_next_message_2(blocking, NULL);
++}
++
++GIOPRecvBuffer *
++giop_main_next_message_2(gboolean blocking,
++ GIOPConnection *monitor)
++{
++ GIOPConnection *connection;
++ GIOPRecvBuffer *recv_buffer = NULL;
++
++ do {
++ recv_buffer = giop_received_list_pop();
++// printk("giop_main_next_message_2 : recv_buffer = 0x%08X\n", recv_buffer);
++ if(recv_buffer)
++ break;
++
++ connection = giop_check_connections(blocking);
++// printk("giop_main_next_message_2 : connection = 0x%08X\n", connection);
++ if(!connection)
++ {
++ return NULL;
++ }
++
++ if(GIOP_CONNECTION_GET_FD(connection) < 0) {
++ g_assert(!"connection has -ve fd!");
++ }
++
++// printk("giop_main_next_message_2 : connection class = %d\n",
++// connection->connection_class);
++ if(connection->connection_class == GIOP_CONNECTION_SERVER)
++ iiop_connection_server_accept(connection);
++ else
++ recv_buffer = giop_recv_message_buffer_use(connection);
++
++ if(monitor && !monitor->is_valid)
++ {
++ return NULL;
++ }
++
++ } while(!recv_buffer);
++
++ return recv_buffer;
++}
++
++void
++giop_main_handle_connection(GIOPConnection *connection)
++{
++ GIOPRecvBuffer *recv_buffer;
++
++ //printk("giop_main_handle_connection\n");
++
++ g_return_if_fail(connection != NULL);
++ g_return_if_fail(connection->is_valid);
++
++ if(connection->connection_class == GIOP_CONNECTION_SERVER) {
++ iiop_connection_server_accept(connection);
++ return;
++ } else
++ recv_buffer = giop_recv_message_buffer_use(connection);
++
++ if(recv_buffer) {
++ if(IIOPIncomingMessageHandler)
++ IIOPIncomingMessageHandler(recv_buffer);
++ else
++ giop_received_list_push(recv_buffer);
++ }
++}
++
++/*
++ * giop_main_handle_connection_exception
++ *
++ * Input: GIOPConnection *connection
++ *
++ * Output:
++ *
++ * Side effects: invalidates connection
++ *
++ * Description:
++ * When poll() or select() indicates that a file descriptor
++ * has been closed at the remote end, we must invalidate the associated
++ * GIOPConnection structure.
++ */
++void
++giop_main_handle_connection_exception(GIOPConnection *connection)
++{
++ g_return_if_fail(connection != NULL);
++ g_return_if_fail(connection->is_valid);
++
++// printk("giop_main_handle_connection_exception(0x%X)\n", GIOP_CONNECTION_GET_FD(connection));
++
++ giop_connection_ref(connection);
++
++ giop_connection_remove_from_list(connection);
++
++ shutdown(GIOP_CONNECTION_GET_FD(connection), 2);
++ close(GIOP_CONNECTION_GET_FD(connection));
++ GIOP_CONNECTION(connection)->fd = -1;
++ connection->is_valid = FALSE;
++
++ if(connection->incoming_msg) {
++ giop_recv_buffer_unuse(connection->incoming_msg);
++ connection->incoming_msg = NULL;
++ }
++
++ giop_connection_unref(connection);
++}
++
++/*
++ * giop_main_iterate
++ *
++ * Input: 'blocking' - flag to indicate whether to wait for incoming
++ * messages (TRUE), or whether to return immediately if no
++ * incoming messages are available (FALSE).
++ * Output: None
++ * Description:
++ * Gets the next message into recv_buffer (see
++ * giop_main_next_message) If we have a handler for incoming
++ * messages, then pass recv_buffer to the handler (handler
++ * becomes the new owner of recv_buffer's contents). Otherwise,
++ * tosses it onto the list of received-but-unprocessed buffers.
++ *
++ * Warnings:
++ * If you don't have an IIOPIncomingMessageHandler set, you're
++ * probably really screwed in the long run.
++ */
++void
++giop_main_iterate(gboolean blocking)
++{
++ GIOPRecvBuffer *recv_buffer;
++
++// printk("giop_main_iterate: blocking: %d\n", blocking);
++schedule();
++
++ recv_buffer = giop_main_next_message(blocking);
++
++// printk("giop_main_iterate: recv_buffer = 0x%08X\n", recv_buffer);
++
++ if(recv_buffer) {
++ if(IIOPIncomingMessageHandler)
++ IIOPIncomingMessageHandler(recv_buffer);
++ else
++ giop_received_list_push(recv_buffer);
++ }
++}
++
++/*
++ * giop_check_connections
++ *
++ * Inputs: 'block_for_reply' - If no incoming data is immediately available
++ * should this routine wait for incoming data (TRUE) or return
++ * immediately (FALSE).
++ *
++ * Outputs: 'connection' - the first connection that has incoming
++ * data available for reading (supposedly a GIOP message, but
++ * could be anything).
++ *
++ * Side effects: Removes closed connections from the active list.
++ *
++ * Global data structures used: giop_connection_list
++ *
++ * Description: Does a poll or select (OS-dependant) on the list of file
++ * descriptors in giop_connection_list.
++ *
++ * If a file descriptor has been closed, call
++ * giop_connection_handle_exception() on it and (as
++ * appropriated by 'block_for_reply') either return
++ * NULL or do another poll/select.
++ *
++ * If a file descriptor has data available for
++ * reading, find the associated GIOPConnection (using
++ * giop_connection_list.fd_to_connection_mapping) and
++ * return that.
++ *
++ */
++GIOPConnection *
++giop_check_connections(gboolean block_for_reply)
++{
++ GIOPConnection *connection = NULL;
++ int pollret;
++ int numcnx_checks;
++ int i;
++#ifndef USE_POLL
++ fd_set selectset_rd, selectset_ex;
++
++ struct timeval immediate_timeout = {0,0};
++#endif
++
++// printk("giop_check_connections\n");
++
++ do_read_msg:
++
++ if(!giop_connection_list.list)
++ {
++// printk("giop_check_connections : list = NULL\n");
++ BUG();
++ return NULL;
++ }
++
++#if 0
++ giop_connection_list_recreate(); /* easiest way to get valid
++ select sets... */
++#endif
++
++#ifdef USE_POLL
++ numcnx_checks = giop_connection_list.pollset->len;
++#else
++ memcpy(&selectset_rd, &giop_connection_list.selectset_rd,
++ sizeof(selectset_rd));
++ memcpy(&selectset_ex, &giop_connection_list.selectset_ex,
++ sizeof(selectset_ex));
++
++ numcnx_checks = giop_connection_list.max_fd+1;
++#endif
++
++ restart:
++#ifdef USE_POLL
++ pollret = poll((struct pollfd *)giop_connection_list.pollset->data,
++ giop_connection_list.pollset->len,
++ block_for_reply?-1:0);
++
++#if KORBIT_DEBUG_WRITING
++{
++ int ix;
++ struct pollfd *fds = (struct pollfd *)giop_connection_list.pollset->data;
++// printk("back from poll(#fds = %d, block = %d) = %d)\n", giop_connection_list.pollset->len, block_for_reply, pollret);
++// for (ix = 0; ix < giop_connection_list.pollset->len; ix++)
++ // printk(" [fd = 0x%X, event = 0x%X, revent = 0x%X]\n",
++// fds[ix].fd, fds[ix].events, fds[ix].revents);
++
++}
++#endif /* KORBIT_DEBUG_WRITING */
++
++
++# else /* !USE_POLL */
++
++ {
++ pollret = select (giop_connection_list.max_fd + 1,
++ &selectset_rd,
++ NULL, &selectset_ex,
++ block_for_reply?NULL:&immediate_timeout);
++ }
++# endif /* !USE_POLL */
++
++// printk("giop_check_connections : pollret == %d\n", pollret);
++ if(pollret <= 0) {
++ if(pollret < 0) {
++ if(errno == EINTR)
++ goto restart;
++ else
++ g_warning("Error code from select/poll: %s", g_strerror(errno));
++ } else
++ return NULL;
++ }
++
++ /* Check for data to be read on the fd's.
++ Note we have to do the hangup/exception checking in a separate loop,
++ because there may be data waiting to be read on a connection that the
++ other end has closed. */
++ for(i = 0; i < numcnx_checks; i++) {
++ struct fd_hash_elem *el;
++
++#ifdef USE_POLL
++ struct pollfd *p =
++ &g_array_index(giop_connection_list.pollset,
++ struct pollfd,
++ i);
++ g_assert(p->fd <= giop_connection_list.max_fd);
++#ifndef __KORBIT__
++ connection = giop_connection_list.fd_to_connection_mapping->pdata[p->fd];
++#else
++ el = g_hash_table_lookup(giop_connection_list.fd_to_connection_mapping,
++ &(p->fd));
++ if (el)
++ connection = el->cnx;
++#endif
++ if(p->revents & POLLIN)
++ goto got_connection;
++#else
++#ifndef __KORBIT__
++ connection = giop_connection_list.fd_to_connection_mapping->pdata[i];
++#else
++ el = g_hash_table_lookup(giop_connection_list.fd_to_connection_mapping,
++ &i);
++ if (el)
++ connection = el->cnx;
++#endif
++ if (FD_ISSET(i, &selectset_rd)) {
++ goto got_connection;
++ }
++#endif
++ }
++
++ /* Handle fd exceptions */
++ for(i = 0; i < numcnx_checks; i++)
++ {
++ struct fd_hash_elem *el;
++#ifdef USE_POLL
++ struct pollfd *p =
++ &g_array_index(giop_connection_list.pollset,
++ struct pollfd,
++ i);
++
++ g_assert(p->fd <= giop_connection_list.max_fd);
++ if(p->revents & (POLLHUP|POLLNVAL)) {
++#ifndef __KORBIT__
++ connection = giop_connection_list.fd_to_connection_mapping->pdata[p->fd];
++#else
++ el = g_hash_table_lookup(giop_connection_list.fd_to_connection_mapping,
++ &(p->fd));
++ if (el)
++ connection = el->cnx;
++#endif
++ giop_main_handle_connection_exception(connection);
++ }
++#else /* !USE_POLL */
++ if(FD_ISSET(i, &selectset_ex)) {
++#ifndef __KORBIT__
++ connection = giop_connection_list.fd_to_connection_mapping->pdata[i];
++#else
++ el = g_hash_table_lookup(giop_connection_list.fd_to_connection_mapping,
++ &i);
++ if (el)
++ connection = el->cnx;
++#endif
++ giop_main_handle_connection_exception(connection);
++ }
++#endif /* !USE_POLL */
++ }
++
++ /* Only reached if we didn't find a connection to read data from */
++ if(block_for_reply)
++ goto do_read_msg;
++
++ got_connection:
++// printk("giop_check_connections : got connection\n");
++ return connection;
++}
++
+diff -urN linux-2.4.1/net/korbit/IIOP/encoders.c linux-2.4.1-korbit/net/korbit/IIOP/encoders.c
+--- linux-2.4.1/net/korbit/IIOP/encoders.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/encoders.c Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,46 @@
++#include "config.h"
++#include <string.h>
++#include "IIOP.h"
++
++ENCODER_DEC(IOP_ServiceContext)
++{
++ APA(&mem->context_id, sizeof(mem->context_id));
++ ENCODER_CALL(CORBA_sequence_octet, &mem->context_data);
++}
++
++ENCODER_DEC(IOP_ServiceContextList)
++{
++ int i;
++
++ if(!mem)
++ {
++ APA((gpointer)giop_scratch_space, sizeof(mem->_length));
++ return;
++ }
++
++ APA(&mem->_length, sizeof(mem->_length));
++
++ for(i = 0; i < mem->_length; i++)
++ ENCODER_CALL(IOP_ServiceContext, &mem->_buffer[i]);
++}
++
++ENCODER_DEC(CORBA_sequence_octet)
++{
++ if(!mem)
++ {
++ APA((gpointer)giop_scratch_space, sizeof(mem->_length));
++ return;
++ }
++
++ APIA(&mem->_length, sizeof(mem->_length));
++ if(mem->_length > 0)
++ AP(mem->_buffer, mem->_length);
++}
++
++ENCODER_DEC(CORBA_char)
++{
++ GIOP_unsigned_long len = strlen(mem) + 1;
++
++ APIA(&len, sizeof(len));
++ AP(mem, len);
++}
+diff -urN linux-2.4.1/net/korbit/IIOP/giop-msg-buffer.c linux-2.4.1-korbit/net/korbit/IIOP/giop-msg-buffer.c
+--- linux-2.4.1/net/korbit/IIOP/giop-msg-buffer.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/giop-msg-buffer.c Fri Feb 2 01:23:46 2001
+@@ -0,0 +1,1443 @@
++/* The big picture:
++ * For every outgoing request, we have to have the network-ready data
++ * somewhere in memory.
++ *
++ * Using writev, any pieces that do not need endian conversion can
++ * be written in-place.
++ *
++ * The pieces that do need endian conversion can be put into one or more
++ * buffers.
++ *
++ * WHOA WHOA newsflash
++ * Because IIOP lets the message sender specify the endianness,
++ * we do not need to do endian conversion _ever_! The receiver can do all
++ * conversions if need be, or if they are the same endianness as sender they
++ * can just pull it in right off the wire :)
++ *
++ */
++
++#include "config.h"
++#include "iiop-endianP.h"
++#include <string.h>
++#include <unistd.h>
++#include <stdio.h>
++#include <errno.h>
++#include <sys/types.h>
++#include <fcntl.h>
++#include <string.h>
++
++#ifdef HAVE_POLL
++# include <sys/poll.h>
++#else
++# include <sys/types.h>
++# include <sys/time.h>
++#endif
++#include "IIOP.h"
++#include "IIOP-private.h"
++
++#ifdef HAVE_LIMITED_WRITEV
++#define writev g_writev
++#endif
++
++/*
++#ifdef O_NONBLOCK
++#undef O_NONBLOCK
++#endif
++#define O_NONBLOCK 0
++*/
++
++
++/* type defs */
++
++#ifdef __GNUC__
++#define PACKED __attribute__((packed))
++#else
++#define PACKED
++#endif
++
++/*
++ * Overlaps with struct _GIOPMessageHeader on purpose
++ * - we save time because this stuff never changes
++ */
++struct _GIOPMessageHeaderConstants {
++ GIOP_char magic[4];
++ GIOP_char GIOP_version[2];
++ GIOP_octet flags;
++} PACKED;
++
++/* functions */
++static gint giop_recv_decode_message(GIOPRecvBuffer *buf);
++static gboolean num_on_list(GIOP_unsigned_long num,
++ const GIOP_unsigned_long *request_ids,
++ GIOP_unsigned_long req_count);
++static gint giop_recv_reply_decode_message(GIOPRecvBuffer *buf);
++static gint giop_recv_request_decode_message(GIOPRecvBuffer *buf);
++static gint giop_recv_locate_reply_decode_message(GIOPRecvBuffer *buf);
++static gint giop_recv_locate_request_decode_message(GIOPRecvBuffer *buf);
++static GIOPRecvBuffer *giop_received_list_check_reply(GIOP_unsigned_long request_id);
++
++#ifdef NOT_REENTRANT
++extern DEFINE_LOCK(iiop_connection_list);
++#endif
++GList *iiop_connection_list = NULL;
++
++/* global variables */
++char giop_scratch_space[2048];
++
++static const struct _GIOPMessageHeaderConstants
++giop_message_header_constants = {
++ "GIOP",
++ {1,0},
++ FLAG_ENDIANNESS,
++};
++
++struct iovec
++giop_first_message_vec = {NULL,
++ sizeof(struct _GIOPMessageHeaderConstants)};
++
++DEFINE_LOCK(sendbufferlist);
++GSList *sendbufferlist = NULL;
++
++DEFINE_LOCK(recvbufferlist);
++GSList *recvbufferlist = NULL;
++
++DEFINE_LOCK(incoming_bufs);
++GList *incoming_bufs = NULL; /* List of incoming messages that had to be
++ shunted aside */
++
++DEFINE_LOCK(sendbuffers);
++DEFINE_LOCK(recvbuffers);
++GMemChunk *sendbuffers = NULL, *recvbuffers = NULL;
++
++DEFINE_LOCK(request_id_counter);
++GIOP_unsigned_long request_id_counter;
++
++#if 0
++inline
++void giop_message_buffer_append_iovec(GIOPMessageBuffer *msgbuf,
++ const struct iovec *iovec)
++{
++ /* g_print("Appending iovec %d bytes @ %p\n", iovec->iov_len, iovec->iov_base); */
++ g_array_append_val(msgbuf->iovecs, *iovec);
++}
++#else
++#define giop_message_buffer_append_iovec(msgbuf, iovec) g_array_append_val((msgbuf)->iovecs, *(iovec))
++#endif
++
++void
++giop_message_buffer_init(void)
++{
++ giop_first_message_vec.iov_base = (gpointer)&giop_message_header_constants;
++ INIT_LOCK(sendbufferlist);
++ INIT_LOCK(recvbufferlist);
++ request_id_counter = 1;
++ INIT_LOCK(request_id_counter);
++
++ INIT_LOCK(sendbuffers);
++ sendbuffers = g_mem_chunk_create(GIOPSendBuffer, 2, G_ALLOC_ONLY);
++ INIT_LOCK(recvbuffers);
++ recvbuffers = g_mem_chunk_create(GIOPRecvBuffer, 2, G_ALLOC_ONLY);
++}
++
++static void
++giop_message_buffer_new(GIOPMessageBuffer *buf)
++{
++ buf->iovecs = g_array_new(FALSE, FALSE, sizeof(struct iovec));
++}
++
++#define STRUCT_OFFSET(t, f) ((int) ((char*) &((t*) 0)->f))
++
++/* Send buffers only */
++static GIOPSendBuffer *
++giop_send_buffer_new(void)
++{
++ GIOPSendBuffer *msgbuf;
++ struct iovec firstvec;
++
++ GET_LOCK(sendbuffers);
++ msgbuf = g_chunk_new(GIOPSendBuffer, sendbuffers);
++ RELEASE_LOCK(sendbuffers);
++
++ giop_message_buffer_new(GIOP_MESSAGE_BUFFER(msgbuf));
++
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(msgbuf),
++ &giop_first_message_vec);
++
++ firstvec.iov_base = &(GIOP_MESSAGE_BUFFER(msgbuf)->message_header.message_type);
++ firstvec.iov_len = sizeof(GIOPMessageHeader)
++ - STRUCT_OFFSET(GIOPMessageHeader, message_type);
++ GIOP_MESSAGE_BUFFER(msgbuf)->message_header.message_size = 0;
++
++ msgbuf->indirects = g_mem_chunk_create(char[GIOP_INDIRECT_CHUNK_SIZE],
++ 2, G_ALLOC_ONLY);
++
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(msgbuf), &firstvec);
++
++ return msgbuf;
++}
++
++gint
++giop_send_buffer_write(GIOPSendBuffer *send_buffer)
++{
++ gulong nvecs;
++ glong res, sum, t;
++ struct iovec *curvec;
++ int fd;
++ GIOPConnection *cnx;
++ gint retval = -1;
++
++// printf("giop_send_buffer_write\n");
++
++ cnx = GIOP_MESSAGE_BUFFER(send_buffer)->connection;
++ if(!cnx->is_valid)
++ return -1;
++
++ fd = GIOP_CONNECTION_GET_FD(cnx);
++ nvecs = GIOP_MESSAGE_BUFFER(send_buffer)->iovecs->len;
++ curvec = (struct iovec *)GIOP_MESSAGE_BUFFER(send_buffer)->iovecs->data;
++
++#if defined(ORBIT_DEBUG) && 0
++ g_print("Message of length %d looks like:\n",
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size);
++{ int i = 0;
++ for(sum = 0; i < nvecs; i++) {
++ sum += curvec[i].iov_len;
++ g_print(" [%p, %d]: %d\n", curvec[i].iov_base, curvec[i].iov_len,
++ sum);
++ }
++}
++#endif
++
++ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
++ res = writev(fd, curvec, nvecs);
++// printk("writev wrote %d byte\n", res);
++
++ sum = (GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size + sizeof(GIOPMessageHeader));
++ if(res < sum) {
++ if(res < 0) {
++//printf("writev returned %d\n", res);
++ if(errno != EAGAIN) {
++ giop_main_handle_connection_exception(cnx);
++ goto out;
++ }
++
++ res = 0;
++ }
++
++ /* wrote 7, iovecs 3, 2, 2, 4:
++ 0 + 3 !> 7
++ 3 + 2 !> 7
++ 5 + 2 !> 7
++ */
++
++ for(t = 0; ; t += curvec->iov_len, curvec++, nvecs--) {
++ if((t + curvec->iov_len) > res)
++ break;
++ }
++ if((res - t) > 0) {
++ curvec->iov_len -= (res - t);
++ curvec->iov_base = (gpointer)((char *)curvec->iov_base + (res - t));
++ }
++
++
++ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
++ t = writev(fd, curvec, nvecs);
++
++ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
++
++ if((t < 0) || ((res + t) < sum)) {
++//printf("crap, t = %d res = %d sum = %d\n", t, res, sum);
++ giop_main_handle_connection_exception(cnx);
++ goto out;
++ }
++ }
++
++ retval = 0;
++
++ out:
++
++ return retval;
++}
++
++static GIOPSendBuffer *
++giop_send_buffer_use(GIOPConnection *connection)
++{
++ GIOPSendBuffer *retval;
++
++ if(!connection->is_valid)
++ return NULL;
++
++ GET_LOCK(sendbufferlist);
++
++ if(sendbufferlist)
++ {
++ GSList *head;
++
++ retval = sendbufferlist->data;
++
++ head = sendbufferlist;
++ sendbufferlist = g_slist_remove_link(sendbufferlist, sendbufferlist);
++ g_slist_free_1 (head);
++
++ g_array_set_size(GIOP_MESSAGE_BUFFER(retval)->iovecs, 2);
++ GIOP_MESSAGE_BUFFER(retval)->message_header.message_size = 0;
++ }
++ else
++ retval = giop_send_buffer_new();
++
++ RELEASE_LOCK(sendbufferlist);
++
++ giop_connection_ref(connection);
++ GIOP_MESSAGE_BUFFER(retval)->connection = connection;
++
++ g_mem_chunk_reset(retval->indirects);
++ retval->indirect = g_chunk_new(gpointer, retval->indirects);
++#ifdef ORBIT_DEBUG
++ memset(retval->indirect, '\xFE', GIOP_INDIRECT_CHUNK_SIZE);
++#endif
++ retval->indirect_used = 0;
++
++ return retval;
++}
++
++GIOPSendBuffer *
++giop_send_reply_buffer_use(GIOPConnection *connection,
++ const IOP_ServiceContextList *service_context,
++ GIOP_unsigned_long request_id,
++ GIOPReplyStatusType reply_status)
++{
++ GIOPSendBuffer *send_buffer;
++
++ send_buffer = giop_send_buffer_use(connection);
++
++ if(!send_buffer)
++ return NULL;
++
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_type = GIOP_REPLY;
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ if(!service_context) {
++ static const GIOP_unsigned_long sc_zero_int = 0;
++ AP(&sc_zero_int, sizeof(service_context->_length));
++ } else {
++ int i, n;
++ n = service_context->_length;
++ AP(&service_context->_length, sizeof(service_context->_length));
++ for(i = 0; i < n; i++) {
++ int j, o;
++ CORBA_sequence_octet *seqo;
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ AP(&service_context->_buffer[i].context_id,
++ sizeof(service_context->_buffer[i].context_id));
++ seqo = &service_context->_buffer[i].context_data;
++ o = seqo->_length;
++ AP(&seqo->_length, sizeof(GIOP_unsigned_long));
++ for(j = 0; j < o; j++)
++ AP(seqo->_buffer, seqo->_length);
++ }
++ }
++ send_buffer->message.u.reply.request_id = request_id;
++ send_buffer->message.u.reply.reply_status = reply_status;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ AP(&send_buffer->message.u.reply.request_id,
++ sizeof(GIOP_unsigned_long));
++ AP(&send_buffer->message.u.reply.reply_status,
++ sizeof(GIOP_unsigned_long));
++
++ return send_buffer;
++}
++
++GIOPSendBuffer *
++giop_send_locate_reply_buffer_use(GIOPConnection *connection,
++ GIOP_unsigned_long request_id,
++ GIOPLocateStatusType locate_reply_status)
++{
++ GIOPSendBuffer *send_buffer;
++
++ send_buffer = giop_send_buffer_use(connection);
++
++ if(!send_buffer)
++ return NULL;
++
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_type = GIOP_LOCATEREPLY;
++
++ APIA(&request_id, sizeof(request_id));
++ APIA(&locate_reply_status, sizeof(locate_reply_status));
++
++ return send_buffer;
++}
++
++GIOPSendBuffer *
++giop_send_request_buffer_use(GIOPConnection *connection,
++ const IOP_ServiceContextList *service_context,
++ GIOP_unsigned_long request_id,
++ GIOP_boolean response_expected,
++ const struct iovec *object_key_vec,
++ const struct iovec *operation_vec,
++ const struct iovec *principal_vec)
++{
++ GIOPSendBuffer *send_buffer;
++#if 0
++ static const struct {
++ CORBA_unsigned_long _length;
++ char _buffer[7];
++ } default_principal = { sizeof("nobody"), "nobody" };
++ static const struct iovec default_principal_vec =
++ {(void *)&default_principal,
++ sizeof(CORBA_unsigned_long) + sizeof("nobody")};
++#endif
++
++ if (!connection)
++ return NULL;
++ if(!object_key_vec)
++ return NULL;
++ if(!operation_vec)
++ return NULL;
++
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "Sending request %s id %d to %s\n",
++ ((guchar *)operation_vec->iov_base) + 4,
++ request_id, ((guchar *)object_key_vec->iov_base) + 4);
++
++ send_buffer = giop_send_buffer_use(connection);
++
++ if (!send_buffer)
++ return NULL;
++
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_type = GIOP_REQUEST;
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ if(!service_context) {
++ static const GIOP_unsigned_long sc_zero_int = 0;
++ AP(&sc_zero_int, sizeof(GIOP_unsigned_long));
++ } else {
++ int i, n;
++ n = service_context->_length;
++ AP(&service_context->_length, sizeof(service_context->_length));
++ for(i = 0; i < n; i++) {
++ int j, o;
++ CORBA_sequence_octet *seqo;
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ AP(&service_context->_buffer[i].context_id,
++ sizeof(service_context->_buffer[i].context_id));
++ seqo = &service_context->_buffer[i].context_data;
++ o = seqo->_length;
++ AP(&seqo->_length, sizeof(GIOP_unsigned_long));
++ for(j = 0; j < o; j++)
++ AP(seqo->_buffer, seqo->_length);
++ }
++ }
++ send_buffer->message.u.request.request_id = request_id;
++ send_buffer->message.u.request.response_expected = response_expected;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(GIOP_unsigned_long));
++ AP(&send_buffer->message.u.request.request_id,
++ sizeof(GIOP_unsigned_long));
++ AP(&send_buffer->message.u.request.response_expected,
++ sizeof(GIOP_boolean));
++#if 0
++ API(&response_expected, 1);
++ AP((gpointer)giop_scratch_space, 3);
++#endif
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(send_buffer),
++ object_key_vec);
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size +=
++ object_key_vec->iov_len;
++
++ /*
++ * We can know the length at compile time - don't calculate it at runtime
++ * if we can help it :)
++ */
++ /* ENCODER_CALL(CORBA_string, (CORBA_string *)operation); */
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(send_buffer),
++ operation_vec);
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size +=
++ operation_vec->iov_len;
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(send_buffer),
++ principal_vec);
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size +=
++ principal_vec->iov_len;
++
++ return send_buffer;
++}
++
++GIOPSendBuffer *
++giop_send_locate_request_buffer_use(GIOPConnection *connection,
++ GIOP_unsigned_long request_id,
++ const struct iovec *object_key_vec)
++{
++ GIOPSendBuffer *send_buffer;
++
++ if (!connection)
++ return NULL;
++ if (!object_key_vec)
++ return NULL;
++
++ ORBit_Trace(TraceMod_IIOP, TraceLevel_Debug,
++ "Sending locate request id %d to %s\n",
++ request_id, ((guchar *)object_key_vec->iov_base) + 4);
++
++ send_buffer = giop_send_buffer_use(connection);
++
++ if (!send_buffer)
++ return NULL;
++
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_type = GIOP_LOCATEREQUEST;
++
++ APIA(&request_id, sizeof(request_id));
++
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_iovec(GIOP_MESSAGE_BUFFER(send_buffer),
++ object_key_vec);
++ GIOP_MESSAGE_BUFFER(send_buffer)->message_header.message_size +=
++ object_key_vec->iov_len;
++
++ return send_buffer;
++}
++
++void
++giop_send_buffer_unuse(GIOPSendBuffer *send_buffer)
++{
++ if (send_buffer == NULL)
++ return;
++
++ giop_connection_unref(GIOP_MESSAGE_BUFFER(send_buffer)->connection);
++
++ GET_LOCK(sendbufferlist);
++ sendbufferlist = g_slist_prepend(sendbufferlist, send_buffer);
++ RELEASE_LOCK(sendbufferlist);
++}
++
++gulong
++giop_message_buffer_do_alignment(GIOPMessageBuffer *buffer,
++ gulong align_for)
++{
++ struct iovec newvec;
++ struct iovec *lastvec;
++ guint alignme;
++ gulong real_msgsize;
++ gulong align_diff;
++
++ if(align_for < 2) return 0;
++ if(align_for >
++ MAX(sizeof(GIOP_long_long),sizeof(GIOP_long_double)))
++ align_for = MAX(sizeof(GIOP_long_long), sizeof(GIOP_long_double));
++
++ real_msgsize = buffer->message_header.message_size+sizeof(GIOPMessageHeader);
++
++ alignme = (gulong)ALIGN_ADDRESS(real_msgsize, align_for);
++
++ align_diff = alignme - real_msgsize;
++ if(align_diff > 0)
++ {
++ lastvec = (struct iovec *)(buffer->iovecs->data)
++ + buffer->iovecs->len - 1;
++
++ if(lastvec->iov_base == giop_scratch_space)
++ {
++ newvec.iov_len = align_diff;
++ lastvec->iov_len += align_diff;
++ buffer->message_header.message_size += align_diff;
++ }
++ else
++ {
++ newvec.iov_base = (gpointer)giop_scratch_space;
++ newvec.iov_len = align_diff;
++ buffer->message_header.message_size += align_diff;
++ giop_message_buffer_append_iovec(buffer, &newvec);
++ }
++ return newvec.iov_len;
++ }
++ else
++ return 0;
++}
++
++void
++giop_message_buffer_append_mem_a(GIOPMessageBuffer *buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length)
++{
++ struct iovec newvec;
++ struct iovec *lastvec;
++ gint alignfor;
++
++ alignfor = giop_message_buffer_do_alignment(buffer, mem_region_length);
++
++ lastvec = (struct iovec *)(buffer->iovecs->data) +
++ + buffer->iovecs->len - 1;
++
++ if((mem_region == giop_scratch_space && lastvec->iov_base == giop_scratch_space)
++ || (alignfor == 0 && (((guchar *)lastvec->iov_base) + lastvec->iov_len) == mem_region))
++ {
++ lastvec->iov_len += mem_region_length;
++ }
++ else
++ {
++ newvec.iov_base = (gpointer)mem_region;
++ newvec.iov_len = mem_region_length;
++ giop_message_buffer_append_iovec(buffer, &newvec);
++ }
++
++ buffer->message_header.message_size += mem_region_length;
++}
++
++void
++giop_message_buffer_append_mem(GIOPMessageBuffer *buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length)
++{
++ struct iovec newvec;
++ struct iovec *lastvec;
++
++ lastvec = (struct iovec *)(buffer->iovecs->data)
++ + buffer->iovecs->len - 1;
++
++ if((mem_region == giop_scratch_space
++ && lastvec->iov_base == giop_scratch_space)
++ || ((((guchar *)lastvec->iov_base) + lastvec->iov_len) == mem_region))
++ {
++ lastvec->iov_len += mem_region_length;
++ }
++ else
++ {
++ newvec.iov_base = (gpointer)mem_region;
++ newvec.iov_len = mem_region_length;
++ giop_message_buffer_append_iovec(buffer, &newvec);
++ }
++
++ buffer->message_header.message_size += mem_region_length;
++}
++
++/* I think we need a WE_WANT_NEW_CRAPPY_BUGGY_CODE ifdef here - this
++ tiny routine seems to be horribly hard to get right.
++
++ Basically we have to paste the whole of 'mem_region' into our
++ memory chunks, possibly subdividing it up to fit it into multiple
++ 1K chunks. Because we have to return the first paste point in case
++ the client wants to manipulate it afterwards, if mem_region_length
++ >= sizeof(CORBA_unsigned_long), we also have to guarantee that the
++ pasted stuff doesn't get divided on a finer boundary than
++ sizeof(CORBA_unsigned_long).
++*/
++gpointer
++giop_send_buffer_append_mem_indirect(GIOPSendBuffer *send_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length)
++{
++ gulong offset = 0, thisblock_size;
++ gpointer blockstart = NULL;
++
++ while(offset < mem_region_length) {
++ thisblock_size = MIN(mem_region_length - offset,
++ GIOP_INDIRECT_CHUNK_SIZE - send_buffer->indirect_used);
++
++ if((thisblock_size >= sizeof(CORBA_unsigned_long))
++ || (mem_region_length - offset) < sizeof(CORBA_unsigned_long)) {
++ if (!blockstart)
++ blockstart =
++ ((guchar*) send_buffer->indirect) + send_buffer->indirect_used;
++
++ memcpy((guchar*)send_buffer->indirect + send_buffer->indirect_used,
++ (guchar*)mem_region + offset, thisblock_size);
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer),
++ (guchar*)send_buffer->indirect +
++ send_buffer->indirect_used,
++ thisblock_size);
++ offset += thisblock_size;
++ send_buffer->indirect_used += thisblock_size;
++ }
++
++ if(send_buffer->indirect_used >= (GIOP_INDIRECT_CHUNK_SIZE - sizeof(CORBA_unsigned_long))) {
++#ifdef I_CANT_FIGURE_OUT_WHAT_THIS_LOGIC_WAS_MEANT_TO_DO
++ || (thisblock_size >= sizeof(CORBA_unsigned_long)
++ && (mem_region_length - offset) > 0)) {
++#endif
++ send_buffer->indirect_used = 0;
++ send_buffer->indirect = g_chunk_new(gpointer,
++ send_buffer->indirects);
++ }
++ }
++
++ return blockstart;
++}
++
++#ifdef WE_WANT_OLD_DEAD_CRAPPY_BUGGY_CODE
++gpointer
++_giop_send_buffer_append_mem_indirect(GIOPSendBuffer *send_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length)
++{
++ gpointer blockstart = NULL;
++ gulong offset, new_offset;
++
++ for(offset = new_offset = 0; new_offset < mem_region_length;)
++ {
++ new_offset =
++ MIN(mem_region_length - offset,
++ GIOP_INDIRECT_CHUNK_SIZE - send_buffer->indirect_used);
++
++ if((new_offset - offset) > sizeof(CORBA_unsigned_long)
++ || mem_region_length >= sizeof(CORBA_unsigned_long)) {
++
++ if(!blockstart)
++ blockstart = send_buffer->indirect + send_buffer->indirect_used;
++ }
++
++ memcpy(send_buffer->indirect + send_buffer->indirect_used,
++ mem_region + offset, new_offset - offset);
++
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer),
++ send_buffer->indirect + send_buffer->indirect_used,
++ new_offset - offset);
++
++ send_buffer->indirect_used += new_offset - offset;
++
++ offset = new_offset;
++
++ if(new_offset >= GIOP_INDIRECT_CHUNK_SIZE)
++ {
++ send_buffer->indirect_used = 0;
++ send_buffer->indirect = g_chunk_new(gpointer,
++ send_buffer->indirects);
++#ifdef ORBIT_DEBUG
++ memset(send_buffer->indirect, '\xFE', GIOP_INDIRECT_CHUNK_SIZE);
++#endif
++ }
++ }
++
++ return blockstart;
++}
++#endif
++
++gpointer
++giop_send_buffer_append_mem_indirect_a(GIOPSendBuffer *send_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length)
++{
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(send_buffer),
++ mem_region_length);
++ return giop_send_buffer_append_mem_indirect(send_buffer,
++ mem_region, mem_region_length);
++}
++
++GIOP_unsigned_long
++giop_get_request_id(void)
++{
++ GIOP_unsigned_long retval;
++ GET_LOCK(request_id_counter);
++ retval = request_id_counter++;
++ RELEASE_LOCK(request_id_counter);
++ return retval;
++}
++
++/****************************************************
++ * GIOPRecvBuffer routines
++ ****************************************************/
++
++static GIOPRecvBuffer *
++giop_recv_buffer_new(void)
++{
++ GIOPRecvBuffer *msgbuf;
++
++ GET_LOCK(recvbuffers);
++ msgbuf = g_chunk_new(GIOPRecvBuffer, recvbuffers);
++ RELEASE_LOCK(recvbuffers);
++
++ giop_message_buffer_new(GIOP_MESSAGE_BUFFER(msgbuf));
++ msgbuf->message_body = NULL;
++
++ return msgbuf;
++}
++
++void
++giop_recv_buffer_unuse(GIOPRecvBuffer *buffer)
++{
++ if (buffer == NULL)
++ return;
++
++ if(buffer->message_body) {
++ buffer->message_body = ((guchar *)buffer->message_body)
++ - sizeof(GIOPMessageHeader);
++
++ g_free(buffer->message_body);
++ buffer->message_body = NULL;
++ }
++
++ if(GIOP_MESSAGE_BUFFER(buffer)->connection->incoming_msg == buffer)
++ GIOP_MESSAGE_BUFFER(buffer)->connection->incoming_msg = NULL;
++
++ giop_connection_unref(GIOP_MESSAGE_BUFFER(buffer)->connection);
++
++ GET_LOCK(recvbufferlist);
++ recvbufferlist = g_slist_prepend(recvbufferlist, buffer);
++ RELEASE_LOCK(recvbufferlist);
++}
++
++static GIOPRecvBuffer *
++giop_recv_buffer_use(GIOPConnection *connection)
++{
++ GIOPRecvBuffer *retval;
++
++ if(!connection || !connection->is_valid)
++ return NULL;
++
++ GET_LOCK(recvbufferlist);
++
++ if(recvbufferlist)
++ {
++ GSList *head;
++
++ retval = recvbufferlist->data;
++
++ head = recvbufferlist;
++ recvbufferlist = g_slist_remove_link(recvbufferlist, recvbufferlist);
++ g_slist_free_1 (head);
++
++ GIOP_MESSAGE_BUFFER(retval)->message_header.message_size = 0;
++ retval->message_body = NULL;
++ }
++ else
++ retval = giop_recv_buffer_new();
++
++ retval->state = GIOP_MSG_READING_HEADER;
++ retval->left_to_read = sizeof(GIOPMessageHeader);
++
++ RELEASE_LOCK(recvbufferlist);
++
++ giop_connection_ref(connection);
++ GIOP_MESSAGE_BUFFER(retval)->connection = connection;
++
++ return retval;
++}
++
++GIOPRecvBuffer *
++giop_recv_message_buffer_use(GIOPConnection *connection)
++{
++ GIOPRecvBuffer *retval;
++ char *bptr;
++ int sysret;
++ guint message_size;
++
++// printf("giop_recv_message_buffer_use: connection = 0x%X\n", connection);
++
++ if(!connection || !connection->is_valid)
++ return NULL;
++
++ if(connection->incoming_msg)
++ retval = connection->incoming_msg;
++ else {
++ retval = giop_recv_buffer_use(connection);
++ connection->incoming_msg = retval;
++ }
++
++ if(!retval) return NULL;
++
++ do {
++ switch(retval->state) {
++ case GIOP_MSG_READING_HEADER:
++ bptr = ((char *)&(GIOP_MESSAGE_BUFFER(retval)->message_header));
++ bptr += sizeof(GIOP_MESSAGE_BUFFER(retval)->message_header)
++ - retval->left_to_read;
++ break;
++ case GIOP_MSG_READING_BODY:
++ bptr = retval->cur; /* Reason for not using retval->message_body:
++ See note XXX1 below */
++ bptr += GIOP_MESSAGE_BUFFER(retval)->message_header.message_size;
++ bptr -= retval->left_to_read;
++ break;
++ default:
++ bptr = NULL;
++ }
++
++//printf("#1p1: READ %d bytes: errno %d state = %d\n", retval->left_to_read, errno, retval->state);
++ sysret = read(GIOP_CONNECTION_GET_FD(connection), bptr,
++ retval->left_to_read);
++
++ if((sysret == 0)
++ || ((sysret < 0) && (errno != EAGAIN))) {
++//printf("#1: sysret = %d bptr = 0x%X errno = %d\n", sysret, bptr, errno);
++ goto errout;
++ }
++
++ if(sysret > 0)
++ retval->left_to_read -= sysret;
++
++ if(retval->left_to_read == 0) {
++ /* we change states here */
++
++ switch(retval->state) {
++ case GIOP_MSG_READING_HEADER:
++ /* Check the magic stuff */
++ if(strncmp(GIOP_MESSAGE_BUFFER(retval)->message_header.magic, "GIOP", 4)
++ || GIOP_MESSAGE_BUFFER(retval)->message_header.GIOP_version[0] != 1) {
++//printf("#2: Not a GIOP thinger? '%s'\n", GIOP_MESSAGE_BUFFER(retval)->message_header.magic);
++ goto errout;
++ }
++ if(GIOP_MESSAGE_BUFFER(retval)->message_header.message_size == 0
++ && GIOP_MESSAGE_BUFFER(retval)->message_header.message_type != GIOP_CLOSECONNECTION) {
++// printf("Unexpected 0-length IIOP message\n");
++ goto errout;
++ }
++
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(retval))) {
++ CORBA_unsigned_long t = GIOP_MESSAGE_BUFFER(retval)->message_header.message_size;
++ retval->decoder = (void (*)(gpointer, gpointer, gulong))iiop_byteswap;
++
++ iiop_byteswap((gpointer)&GIOP_MESSAGE_BUFFER(retval)->message_header.message_size,
++ (gpointer)&t, sizeof(t));
++ } else {
++#ifdef __KERNEL__
++ retval->decoder = (void (*)(gpointer,gpointer,gulong))__memcpy;
++#else
++ retval->decoder = (void (*)(gpointer,gpointer,gulong))memcpy;
++#endif
++ }
++
++ message_size = GIOP_MESSAGE_BUFFER(retval)->message_header.message_size;
++ if(!connection->is_auth
++ && message_size > 131072) {
++// printf("message size is bigger than 128k (%d)\n", message_size);
++ goto errout;
++ }
++
++ retval->message_body = g_malloc(message_size+sizeof(GIOPMessageHeader));
++ /* XXX1 This is a lame hack to work with the fact that
++ alignment is relative to the MessageHeader, not the RequestHeader */
++ retval->message_body = ((guchar *)retval->message_body) + sizeof(GIOPMessageHeader);
++ retval->cur = retval->message_body;
++ retval->state = GIOP_MSG_READING_BODY;
++ retval->left_to_read = message_size;
++ break;
++ case GIOP_MSG_READING_BODY:
++ if(giop_recv_decode_message(retval)) {
++//printf("giop_recv_decode_message FAILURE!\n");
++ goto errout;
++ }
++ connection->incoming_msg = NULL;
++ retval->state = GIOP_MSG_READY;
++ break;
++ default:
++ break;
++ }
++ } else if(retval->left_to_read < 0) {
++// printf("Whoa, we overstepped the number of bytes we were supposed to read by %d\n", -retval->left_to_read);
++ goto errout;
++ } else /* retval->left_to_read > 0 */ {
++ /* couldn't read the whole piece, save it */
++ retval = NULL;
++ }
++ } while(retval && retval->state != GIOP_MSG_READY);
++
++ return retval;
++
++ errout:
++ giop_recv_buffer_unuse(retval);
++ giop_main_handle_connection_exception(connection);
++ return NULL;
++}
++
++void
++giop_received_list_push(GIOPRecvBuffer *recv_buffer)
++{
++ GET_LOCK(incoming_bufs);
++ incoming_bufs = g_list_prepend(incoming_bufs, recv_buffer);
++ RELEASE_LOCK(incoming_bufs);
++}
++
++GIOPRecvBuffer *giop_received_list_pop(void)
++{
++ GList *head;
++ GIOPRecvBuffer *retval;
++
++ GET_LOCK(incoming_bufs);
++
++ head = incoming_bufs;
++
++ if(!head)
++ return NULL;
++
++ retval = head->data;
++ incoming_bufs = g_list_remove_link(incoming_bufs, head);
++ g_list_free_1 (head);
++
++ RELEASE_LOCK(incoming_bufs);
++
++ return retval;
++}
++
++static GIOPRecvBuffer *
++giop_received_list_check_reply(GIOP_unsigned_long request_id)
++{
++ GIOPRecvBuffer *retval = NULL;
++ GList *item = NULL;
++
++ GET_LOCK(incoming_bufs);
++
++ for(item = incoming_bufs; item; item = g_list_next(item))
++ {
++ if(GIOP_MESSAGE_BUFFER(item->data)->message_header.message_type == GIOP_REPLY
++ && GIOP_RECV_BUFFER(item->data)->message.u.reply.request_id == request_id) {
++ retval = item->data;
++ break;
++ }
++ }
++
++ if(retval)
++ incoming_bufs = g_list_remove(incoming_bufs, retval);
++
++ RELEASE_LOCK(incoming_bufs);
++
++ return retval;
++}
++
++/** giop_recv_reply_buffer_use_multiple
++ */
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_multiple(GArray *request_ids,
++ gboolean block_for_reply)
++{
++ return giop_recv_reply_buffer_use_multiple_2(NULL, request_ids, block_for_reply);
++}
++
++/* here is how it will be:
++ one routine for getting next message with a specified reply ID.
++ */
++
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_multiple_2(GIOPConnection *request_cnx,
++ GArray *request_ids,
++ gboolean block_for_reply)
++{
++ int i;
++ GIOPRecvBuffer *retval = NULL;
++ GSList *pushme = NULL;
++
++ do {
++ /*
++ * We _do_ want to put this inside the loop,
++ * because we may call ourselves recursively for different request_id's
++ */
++ for(i = 0; i < request_ids->len && !retval; i++)
++ retval = giop_received_list_check_reply(g_array_index(request_ids, GIOP_unsigned_long, i));
++
++ if(retval)
++ break;
++
++ retval = giop_main_next_message_2(block_for_reply, request_cnx);
++
++ if(retval) {
++ if(GIOP_MESSAGE_BUFFER(retval)->message_header.message_type == GIOP_REPLY) {
++ if(num_on_list(retval->message.u.reply.request_id,
++ (GIOP_unsigned_long *)request_ids->data,
++ request_ids->len))
++ break;
++ else {
++ pushme = g_slist_prepend(pushme, retval); retval = NULL;
++ }
++ } else {
++ if(IIOPIncomingMessageHandler)
++ IIOPIncomingMessageHandler(retval);
++ else {
++ pushme = g_slist_prepend(pushme, retval); retval = NULL;
++ }
++ retval = NULL;
++ }
++ } else
++ return NULL;
++
++ } while(!retval && block_for_reply);
++
++ g_slist_foreach(pushme, (GFunc)giop_received_list_push, NULL);
++ g_slist_free(pushme);
++
++ return retval;
++}
++
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use(GIOP_unsigned_long request_id,
++ gboolean block_for_reply)
++{
++ return giop_recv_reply_buffer_use_2(NULL, request_id, block_for_reply);
++}
++
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_2(GIOPConnection *request_cnx,
++ GIOP_unsigned_long request_id,
++ gboolean block_for_reply)
++{
++ GArray fakeme;
++
++ fakeme.len = 1;
++ fakeme.data = (gpointer)&request_id;
++
++ return giop_recv_reply_buffer_use_multiple_2(request_cnx,
++ &fakeme,
++ block_for_reply);
++}
++
++GIOPRecvBuffer *
++giop_recv_locate_reply_buffer_use(GIOP_unsigned_long request_id,
++ gboolean block_for_reply)
++{
++ GIOPRecvBuffer *retval = NULL;
++
++ do {
++ /*
++ * We _do_ want to put this inside the loop,
++ * because we may call ourselves recursively for different request_id's
++ */
++ retval = giop_received_list_check_reply(request_id);
++
++ if(retval)
++ break;
++
++ retval = giop_main_next_message_2(TRUE, NULL);
++
++ if(retval) {
++ if(GIOP_MESSAGE_BUFFER(retval)->message_header.message_type == GIOP_LOCATEREPLY
++ && retval->message.u.locate_reply.request_id == request_id)
++ break;
++ else {
++ if(IIOPIncomingMessageHandler)
++ IIOPIncomingMessageHandler(retval);
++ else
++ giop_received_list_push(retval);
++ retval = NULL;
++ }
++ } else
++ return NULL;
++ } while(!retval && block_for_reply);
++
++ return retval;
++}
++
++static gint
++giop_recv_decode_message(GIOPRecvBuffer *buf)
++{
++ switch(GIOP_MESSAGE_BUFFER(buf)->message_header.message_type)
++ {
++ case GIOP_REPLY:
++ return giop_recv_reply_decode_message(buf);
++ break;
++ case GIOP_REQUEST:
++ return giop_recv_request_decode_message(buf);
++ break;
++ case GIOP_LOCATEREQUEST:
++ return(giop_recv_locate_request_decode_message(buf));
++ break;
++ case GIOP_LOCATEREPLY:
++ return(giop_recv_locate_reply_decode_message(buf));
++ break;
++ case GIOP_CLOSECONNECTION:
++ return 0;
++ break;
++ default:
++// printf("Don't know how to decode message type %d\n",
++// GIOP_MESSAGE_BUFFER(buf)->message_header.message_type);
++ return -1;
++ }
++}
++
++/* if(currptr+len > end || currptr + len < currptr) */
++
++/* This whole mess needs redoing. */
++#define CHECK_NEW_POS(buf, requested_increment) \
++if(!( (( ((guchar*)GIOP_RECV_BUFFER(buf)->cur) \
++ + (requested_increment) ) \
++ <= ( ((guchar *)GIOP_RECV_BUFFER(buf)->message_body) \
++ + GIOP_MESSAGE_BUFFER(buf)->message_header.message_size)) \
++ && ( ( ((guchar*)GIOP_RECV_BUFFER(buf)->cur) \
++ + (requested_increment) ) \
++ >= ((guchar*)GIOP_RECV_BUFFER(buf)->cur) ))) goto out;
++
++#define NEW_POS_OUT out: return -1
++
++#define SAFE_ALIGN_ADDRESS(buf, amt) G_STMT_START { \
++guchar *newval; \
++newval = ALIGN_ADDRESS(GIOP_RECV_BUFFER(buf)->cur, amt); \
++CHECK_NEW_POS(buf, newval-((guchar *)GIOP_RECV_BUFFER(buf)->cur)); \
++GIOP_RECV_BUFFER(buf)->cur = newval; \
++} G_STMT_END
++
++#define GET_ULONG(x) G_STMT_START{ \
++ (x) = GUINT32_SWAP_LE_BE((*(CORBA_unsigned_long *)buf->cur)); \
++ CHECK_NEW_POS(buf, sizeof(CORBA_unsigned_long)); \
++ buf->cur = ((guchar *)buf->cur) + sizeof(CORBA_unsigned_long); \
++ }G_STMT_END
++
++#define GET_ULONG_NC(x) G_STMT_START{ \
++ *(x) = (*((CORBA_unsigned_long *)(buf->cur))); \
++ CHECK_NEW_POS(buf, sizeof(CORBA_unsigned_long)); \
++ buf->cur = ((guchar *)buf->cur) + sizeof(CORBA_unsigned_long); \
++ }G_STMT_END
++
++/* There be dragons in here. */
++static gint
++giop_recv_reply_decode_message(GIOPRecvBuffer *buf)
++{
++ /*
++ enum ReplyStatusType {
++ NO_EXCEPTION,
++ USER_EXCEPTION,
++ SYSTEM_EXCEPTION,
++ LOCATION_FORWARD
++ };
++
++ struct ReplyHeader {
++ IOP::ServiceContextList service_context;
++ unsigned long request_id;
++ ReplyStatusType reply_status;
++ };
++ */
++ int i;
++
++ buf->message.u.reply.service_context._maximum = 0;
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(buf)))
++ {
++ GET_ULONG(buf->message.u.reply.service_context._length);
++/* XXX bad hardcoded hack until someone gives a "right answer" to how to
++solve this problem */
++ if(buf->message.u.reply.service_context._length > 128) return -1;
++ buf->message.u.reply.service_context._buffer =
++ g_new(IOP_ServiceContext, buf->message.u.reply.service_context._length);
++
++ for(i = 0; i < buf->message.u.reply.service_context._length; i++)
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.reply.service_context._buffer[i].context_id);
++ GET_ULONG(buf->message.u.reply.service_context._buffer[i].context_data._length);
++ buf->message.u.reply.service_context._buffer[i].context_data._buffer =
++ buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.reply.service_context._buffer[i].context_data._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.reply.service_context._buffer[i].context_data._length;
++ }
++ GET_ULONG(buf->message.u.reply.request_id);
++ GET_ULONG(buf->message.u.reply.reply_status);
++ }
++ else
++ {
++
++ GET_ULONG_NC(&buf->message.u.reply.service_context._length);
++/* XXX bad hardcoded hack until someone gives a "right answer" to how to
++solve this problem */
++ if(buf->message.u.reply.service_context._length > 128) return -1;
++ buf->message.u.reply.service_context._buffer =
++ g_new(IOP_ServiceContext, buf->message.u.reply.service_context._length);
++
++ for(i = 0; i < buf->message.u.reply.service_context._length; i++)
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(CORBA_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.reply.service_context._buffer[i].context_id);
++ GET_ULONG_NC(&buf->message.u.reply.service_context._buffer[i].context_data._length);
++ buf->message.u.reply.service_context._buffer[i].context_data._buffer =
++ buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.reply.service_context._buffer[i].context_data._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.reply.service_context._buffer[i].context_data._length;
++ }
++ GET_ULONG_NC(&buf->message.u.reply.request_id);
++ GET_ULONG_NC(&buf->message.u.reply.reply_status);
++ }
++
++#if 0
++ g_message("[%d] Received reply %d size %d to request %d",
++ getpid(),
++ buf->message.u.reply.reply_status,
++ GIOP_MESSAGE_BUFFER(buf)->message_header.message_size,
++ buf->message.u.reply.request_id);
++#endif
++
++ return 0;
++
++ NEW_POS_OUT;
++}
++
++static gint
++giop_recv_locate_reply_decode_message(GIOPRecvBuffer *buf)
++{
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(buf)))
++ {
++ GET_ULONG(buf->message.u.locate_reply.request_id);
++ GET_ULONG(buf->message.u.locate_reply.locate_status);
++ }
++ else
++ {
++ GET_ULONG_NC(&buf->message.u.locate_reply.request_id);
++ GET_ULONG_NC(&buf->message.u.locate_reply.locate_status);
++ }
++
++ return 0;
++ NEW_POS_OUT;
++}
++
++static gint
++giop_recv_request_decode_message(GIOPRecvBuffer *buf)
++{
++ GIOP_unsigned_long len;
++ int i;
++
++ buf->message.u.request.service_context._maximum = 0;
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(buf)))
++ {
++ GET_ULONG(buf->message.u.request.service_context._length);
++
++ /* XXX bad hardcoded hack until someone gives a "right answer"
++ to how to solve this problem */
++
++ if(buf->message.u.request.service_context._length > 128) return -1;
++ buf->message.u.request.service_context._buffer =
++ g_new(IOP_ServiceContext, buf->message.u.request.service_context._length);
++
++ for(i = 0; i < buf->message.u.request.service_context._length; i++)
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.request.service_context._buffer[i].context_id);
++ GET_ULONG(buf->message.u.request.service_context._buffer[i].context_data._length);
++ buf->message.u.request.service_context._buffer[i].context_data._buffer =
++ buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.request.service_context._buffer[i].context_data._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.service_context._buffer[i].context_data._length;
++ }
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.request.request_id);
++ buf->message.u.request.response_expected = *((GIOP_boolean *)buf->cur);
++ CHECK_NEW_POS(buf, sizeof(GIOP_boolean));
++ buf->cur = ((guchar *)buf->cur) + sizeof(GIOP_boolean);
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.request.object_key._length);
++ buf->message.u.request.object_key._buffer = buf->cur;
++
++ CHECK_NEW_POS(buf, buf->message.u.request.object_key._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.object_key._length;
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(len);
++ buf->message.u.request.operation = buf->cur;
++
++ CHECK_NEW_POS(buf, len);
++ buf->cur = ((guchar *)buf->cur) + len;
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.request.requesting_principal._length);
++ buf->message.u.request.requesting_principal._buffer = buf->cur;
++
++ CHECK_NEW_POS(buf, buf->message.u.request.requesting_principal._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.requesting_principal._length;
++ }
++ else
++ {
++ GET_ULONG_NC(&buf->message.u.request.service_context._length);
++
++ /* XXX bad hardcoded hack until someone gives a "right answer"
++ to how to solve this problem */
++ if(buf->message.u.request.service_context._length > 128) return -1;
++ buf->message.u.request.service_context._buffer =
++ g_new(IOP_ServiceContext, buf->message.u.request.service_context._length);
++
++ for(i = 0; i < buf->message.u.request.service_context._length; i++)
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.request.service_context._buffer[i].context_id);
++ GET_ULONG_NC(&buf->message.u.request.service_context._buffer[i].context_data._length);
++ buf->message.u.request.service_context._buffer[i].context_data._buffer =
++ buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.request.service_context._buffer[i].context_data._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.service_context._buffer[i].context_data._length;
++ }
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.request.request_id);
++ buf->message.u.request.response_expected = *((GIOP_boolean *)buf->cur);
++ CHECK_NEW_POS(buf, sizeof(GIOP_boolean));
++ buf->cur = ((guchar *)buf->cur) + sizeof(GIOP_boolean);
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.request.object_key._length);
++ buf->message.u.request.object_key._buffer = buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.request.object_key._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.object_key._length;
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&len);
++ buf->message.u.request.operation = buf->cur;
++ CHECK_NEW_POS(buf, len);
++ buf->cur = ((guchar *)buf->cur) + len;
++
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.request.requesting_principal._length);
++ buf->message.u.request.requesting_principal._buffer = buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.request.requesting_principal._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.request.requesting_principal._length;
++ }
++
++#if 0
++ g_message("[%d] Received request %s size %d ID %d",
++ getpid(),
++ buf->message.u.request.operation,
++ GIOP_MESSAGE_BUFFER(buf)->message_header.message_size,
++ buf->message.u.request.request_id);
++#endif
++
++ return 0;
++
++ NEW_POS_OUT;
++}
++
++static gint
++giop_recv_locate_request_decode_message(GIOPRecvBuffer *buf)
++{
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(buf)))
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.locate_request.request_id);
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG(buf->message.u.locate_request.object_key._length);
++ buf->message.u.locate_request.object_key._buffer = buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.locate_request.object_key._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.locate_request.object_key._length;
++ }
++ else
++ {
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.locate_request.request_id);
++ SAFE_ALIGN_ADDRESS(buf, sizeof(GIOP_unsigned_long));
++ GET_ULONG_NC(&buf->message.u.locate_request.object_key._length);
++ buf->message.u.locate_request.object_key._buffer = buf->cur;
++ CHECK_NEW_POS(buf, buf->message.u.locate_request.object_key._length);
++ buf->cur = ((guchar *)buf->cur) + buf->message.u.locate_request.object_key._length;
++ }
++
++ return 0;
++
++ NEW_POS_OUT;
++}
++
++gboolean
++num_on_list(GIOP_unsigned_long num,
++ const GIOP_unsigned_long *request_ids,
++ GIOP_unsigned_long req_count)
++{
++ int i;
++ for(i = 0; i < req_count; i++)
++ {
++ if(num == request_ids[i])
++ return TRUE;
++ }
++
++ return FALSE;
++}
+diff -urN linux-2.4.1/net/korbit/IIOP/giop-msg-buffer.h linux-2.4.1-korbit/net/korbit/IIOP/giop-msg-buffer.h
+--- linux-2.4.1/net/korbit/IIOP/giop-msg-buffer.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/giop-msg-buffer.h Thu Feb 1 16:19:47 2001
+@@ -0,0 +1,228 @@
++#ifndef GIOP_MSG_BUFFER_H
++#define GIOP_MSG_BUFFER_H 1
++
++#include "IIOP.h"
++/* For struct iovec */
++#include <sys/uio.h>
++
++typedef enum {
++ GIOP_REQUEST,
++ GIOP_REPLY,
++ GIOP_CANCELREQUEST,
++ GIOP_LOCATEREQUEST,
++ GIOP_LOCATEREPLY,
++ GIOP_CLOSECONNECTION,
++ GIOP_MESSAGEERROR,
++ GIOP_FRAGMENT
++} GIOPMsgType;
++
++/* GIOP message header */
++typedef struct _GIOPMessageHeader {
++ GIOP_char magic[4];
++ GIOP_char GIOP_version[2];
++ GIOP_octet flags;
++
++ /*
++ * We should really use GIOPMsgType
++ * but that enum winds up being an int...
++ */
++ GIOP_octet message_type;
++
++ GIOP_unsigned_long message_size;
++} GIOPMessageHeader;
++
++#define GIOP_MESSAGE_BUFFER(x) ((GIOPMessageBuffer *)x)
++typedef struct _GIOPMessageBuffer
++{
++ /* The connection that this message will go out over... */
++ GIOPConnection *connection;
++
++ GArray *iovecs;
++ GIOPMessageHeader message_header;
++} GIOPMessageBuffer;
++
++#include "../orb/iop.h"
++
++/* GIOP_REQUEST header */
++typedef enum {
++ GIOP_NO_EXCEPTION,
++ GIOP_USER_EXCEPTION,
++ GIOP_SYSTEM_EXCEPTION,
++ GIOP_LOCATION_FORWARD
++} GIOPReplyStatusType;
++
++typedef struct _GIOPMessageRequest {
++ IOP_ServiceContextList service_context;
++ GIOP_unsigned_long request_id;
++ GIOP_boolean response_expected;
++ CORBA_sequence_octet object_key;
++ CORBA_char *operation;
++ CORBA_Principal requesting_principal;
++} GIOPMessageRequest;
++
++typedef struct _GIOPMessageReply {
++ IOP_ServiceContextList service_context;
++ GIOP_unsigned_long request_id;
++ GIOPReplyStatusType reply_status;
++} GIOPMessageReply;
++
++typedef struct _GIOPMessageCancelRequest {
++ GIOP_unsigned_long request_id;
++} GIOPMessageCancelRequest;
++
++typedef struct _GIOPMessageLocateRequest {
++ GIOP_unsigned_long request_id;
++ CORBA_sequence_octet object_key;
++} GIOPMessageLocateRequest;
++
++typedef enum {
++ GIOP_UNKNOWN_OBJECT,
++ GIOP_OBJECT_HERE,
++ GIOP_OBJECT_FORWARD
++} GIOPLocateStatusType;
++
++typedef struct _GIOPMessageLocateReply {
++ GIOP_unsigned_long request_id;
++ GIOPLocateStatusType locate_status;
++} GIOPMessageLocateReply;
++
++typedef struct _GIOPMessage
++{
++ union {
++ GIOPMessageRequest request;
++ GIOPMessageReply reply;
++ GIOPMessageCancelRequest cancel_request;
++ GIOPMessageLocateRequest locate_request;
++ GIOPMessageLocateReply locate_reply;
++ } u;
++} GIOPMessage;
++
++typedef enum {
++ GIOP_MSG_READING_HEADER,
++ GIOP_MSG_READING_BODY,
++ GIOP_MSG_READY
++} GIOPMessageBufferState;
++
++#define GIOP_SEND_BUFFER(x) ((GIOPSendBuffer *)x)
++typedef struct _GIOPSendBuffer
++{
++ GIOPMessageBuffer message_buffer;
++
++ gpointer indirect;
++
++ GMemChunk *indirects; /* Request buffers only (at present) */
++ gulong indirect_used;
++
++ GIOPMessage message;
++ CORBA_unsigned_long scontext_tmp;
++} GIOPSendBuffer;
++
++#define GIOP_RECV_BUFFER(x) ((GIOPRecvBuffer *)x)
++typedef struct _GIOPRecvBuffer
++{
++ GIOPMessageBuffer message_buffer;
++ GIOPMessage message;
++
++ gpointer message_body;
++ gpointer cur;
++
++ void (*decoder)(gpointer dest, gpointer src, gulong len);
++
++ GIOPMessageBufferState state;
++ gint left_to_read;
++} GIOPRecvBuffer;
++
++/* This function needs to be called before useful things happen */
++void giop_message_buffer_init(void);
++
++gint giop_send_buffer_write(GIOPSendBuffer *request_buffer);
++
++void
++giop_message_buffer_append_mem_a(GIOPMessageBuffer *request_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length);
++void
++giop_message_buffer_append_mem(GIOPMessageBuffer *request_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length);
++
++/*
++ * This copies the value into a request-specific buffer before
++ * adding it to the list
++ */
++gpointer
++giop_send_buffer_append_mem_indirect_a(GIOPSendBuffer *request_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length);
++gpointer
++giop_send_buffer_append_mem_indirect(GIOPSendBuffer *request_buffer,
++ gconstpointer mem_region,
++ gulong mem_region_length);
++
++GIOPSendBuffer *
++giop_send_request_buffer_use(GIOPConnection *connection,
++ const IOP_ServiceContextList *service_context,
++ GIOP_unsigned_long request_id,
++ GIOP_boolean response_expected,
++ const struct iovec *object_key_vec,
++ const struct iovec *operation_vec,
++ const struct iovec *principal_vec);
++GIOPSendBuffer *
++giop_send_reply_buffer_use(GIOPConnection *connection,
++ const IOP_ServiceContextList *service_context,
++ GIOP_unsigned_long request_id,
++ GIOPReplyStatusType reply_status);
++GIOPSendBuffer *
++giop_send_locate_request_buffer_use(GIOPConnection *connection,
++ GIOP_unsigned_long request_id,
++ const struct iovec *object_key_vec);
++GIOPSendBuffer *
++giop_send_locate_reply_buffer_use(GIOPConnection *connection,
++ GIOP_unsigned_long request_id,
++ GIOPLocateStatusType reply_status);
++
++void giop_send_buffer_unuse(GIOPSendBuffer *send_buffer);
++
++GIOP_unsigned_long giop_get_request_id(void);
++
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use(GIOP_unsigned_long request_id,
++ gboolean block_for_reply);
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_2(GIOPConnection *request_cnx,
++ GIOP_unsigned_long request_id,
++ gboolean block_for_reply);
++
++/* For DII - hands back the first received request matching an id on the list */
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_multiple(GArray *request_ids,
++ gboolean block_for_reply);
++GIOPRecvBuffer *
++giop_recv_reply_buffer_use_multiple_2(GIOPConnection *request_cnx,
++ GArray *request_ids,
++ gboolean block_for_reply);
++
++GIOPRecvBuffer *
++giop_recv_locate_reply_buffer_use(GIOP_unsigned_long request_id,
++ gboolean block_for_reply);
++
++/*
++ * For server-side use. It's the responsibility of the caller to do
++ * any select()ion desired
++ */
++GIOPRecvBuffer *
++giop_recv_message_buffer_use(GIOPConnection *connection);
++
++void giop_recv_buffer_unuse(GIOPRecvBuffer *buffer);
++
++/*
++ * This is used for sending (and recving, if we ever
++ * get zero-copy receives implemented) alignment bytes
++ */
++extern char giop_scratch_space[2048];
++gulong giop_message_buffer_do_alignment(GIOPMessageBuffer *buffer,
++ gulong align_for);
++
++#define giop_msg_conversion_needed(msgbuf) (conversion_needed(GIOP_MESSAGE_BUFFER(msgbuf)->message_header.flags & 1))
++
++#endif /* GIOP_MSG_BUFFER_H */
+diff -urN linux-2.4.1/net/korbit/IIOP/iiop-encoders.h linux-2.4.1-korbit/net/korbit/IIOP/iiop-encoders.h
+--- linux-2.4.1/net/korbit/IIOP/iiop-encoders.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/iiop-encoders.h Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,25 @@
++#ifndef ENCODERS_H
++#define ENCODERS_H 1
++
++#define ENCODER_DEC(typename) \
++void giop_encoder_##typename##(GIOPSendBuffer *send_buffer, \
++ const typename *mem)
++
++#define ENCODER_CALL(typename, mem) \
++giop_encoder_##typename##(send_buffer, mem)
++
++#define AP(m, l) giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer), m, l)
++#define APA(m, l) giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(send_buffer), m, l)
++
++#define API(m, l) giop_send_buffer_append_mem_indirect(send_buffer, m, l)
++#define APIA(m, l) giop_send_buffer_append_mem_indirect_a(send_buffer, m, l)
++
++ENCODER_DEC(IOP_ServiceContext);
++ENCODER_DEC(IOP_ServiceContextList);
++ENCODER_DEC(CORBA_sequence_octet);
++ENCODER_DEC(CORBA_Principal);
++#define giop_encoder_CORBA_Principal(rb, mem) \
++ giop_encoder_CORBA_sequence_octet(rb, mem)
++ENCODER_DEC(CORBA_char);
++
++#endif /* ENCODERS_H */
+diff -urN linux-2.4.1/net/korbit/IIOP/iiop-endian.c linux-2.4.1-korbit/net/korbit/IIOP/iiop-endian.c
+--- linux-2.4.1/net/korbit/IIOP/iiop-endian.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/iiop-endian.c Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,12 @@
++#define IIOP_DO_NOT_INLINE_IIOP_BYTESWAP
++#include "iiop-endian.h"
++
++void iiop_byteswap(guchar *outdata,
++ const guchar *data,
++ gulong datalen)
++{
++ const guchar *source_ptr = data;
++ guchar *dest_ptr = (guchar *)outdata + datalen - 1;
++ while(dest_ptr >= outdata)
++ *dest_ptr-- = *source_ptr++;
++}
+diff -urN linux-2.4.1/net/korbit/IIOP/iiop-endian.h linux-2.4.1-korbit/net/korbit/IIOP/iiop-endian.h
+--- linux-2.4.1/net/korbit/IIOP/iiop-endian.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/iiop-endian.h Thu Feb 1 11:46:51 2001
+@@ -0,0 +1,42 @@
++#ifndef IIOP_ENDIAN_H
++#define IIOP_ENDIAN_H 1
++
++#include <glib.h>
++
++#if G_BYTE_ORDER == G_BIG_ENDIAN
++
++# define FLAG_ENDIANNESS FLAG_BIG_ENDIAN
++# define conversion_needed(to_endianness) ((to_endianness)!=FLAG_BIG_ENDIAN)
++
++#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
++
++# define FLAG_ENDIANNESS FLAG_LITTLE_ENDIAN
++# define conversion_needed(to_endianness) ((to_endianness)!=FLAG_LITTLE_ENDIAN)
++
++#else
++
++#error "Unsupported endianness on this system."
++
++#endif
++
++#define FLAG_BIG_ENDIAN 0
++#define FLAG_LITTLE_ENDIAN 1
++
++/* This is also defined in IIOP-types.c */
++void iiop_byteswap(guchar *outdata,
++ const guchar *data,
++ gulong datalen);
++
++#if defined(G_CAN_INLINE) && !defined(IIOP_DO_NOT_INLINE_IIOP_BYTESWAP)
++G_INLINE_FUNC void iiop_byteswap(guchar *outdata,
++ const guchar *data,
++ gulong datalen)
++{
++ const guchar *source_ptr = data;
++ guchar *dest_ptr = outdata + datalen - 1;
++ while(dest_ptr >= outdata)
++ *dest_ptr-- = *source_ptr++;
++}
++#endif
++
++#endif
+diff -urN linux-2.4.1/net/korbit/IIOP/iiop-endianP.h linux-2.4.1-korbit/net/korbit/IIOP/iiop-endianP.h
+--- linux-2.4.1/net/korbit/IIOP/iiop-endianP.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/IIOP/iiop-endianP.h Thu Feb 1 16:19:47 2001
+@@ -0,0 +1,11 @@
++#ifndef IIOP_ENDIANP_H
++#define IIOP_ENDIANP_H 1
++
++/* This is pretty much "here" */
++
++#include "config.h"
++#include "IIOP.h"
++
++#include "iiop-endian.h"
++
++#endif /* !IIOP_ENDIANP_H */
+diff -urN linux-2.4.1/net/korbit/Makefile linux-2.4.1-korbit/net/korbit/Makefile
+--- linux-2.4.1/net/korbit/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/Makefile Thu Feb 1 15:57:33 2001
+@@ -0,0 +1,22 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := korbit.o
++
++subdir-y := kglib orb IIOP ORBitutil modules
++subdir-m := modules
++
++obj-y := kglib/kglib.o orb/orblib.o IIOP/IIOPlib.o ORBitutil/ORBitutillib.o exported_symbols.o
++
++export-objs := exported_symbols.o
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -I. -I./include -I./kglib -I./ORBitutil -nostdinc
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/ORBitutil/CVS/Entries linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Entries
+--- linux-2.4.1/net/korbit/ORBitutil/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Entries Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,13 @@
++/Makefile/1.4/Thu Feb 1 09:46:52 2001//
++/basic_types.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/compat.c/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/compat.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/orbit-os-config.h/1.2/Thu Feb 1 09:46:52 2001//
++/os-feature-alloca.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/os-specifics.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/thread-safety.c/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/thread-safety.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/trace.c/1.2/Thu Feb 1 09:46:52 2001//
++/trace.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++/util.h/1.1.1.1/Thu Feb 1 09:46:52 2001//
++D
+diff -urN linux-2.4.1/net/korbit/ORBitutil/CVS/Repository linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Repository
+--- linux-2.4.1/net/korbit/ORBitutil/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Repository Thu Feb 1 11:46:51 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/ORBitutil
+diff -urN linux-2.4.1/net/korbit/ORBitutil/CVS/Root linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Root
+--- linux-2.4.1/net/korbit/ORBitutil/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/CVS/Root Thu Feb 1 11:46:51 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/ORBitutil/Makefile linux-2.4.1-korbit/net/korbit/ORBitutil/Makefile
+--- linux-2.4.1/net/korbit/ORBitutil/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/Makefile Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,17 @@
++#
++# Makefile for KORBit/ORBitutil
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .o file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := ORBitutillib.o
++
++#obj-m := $(O_TARGET)
++obj-y := compat.o thread-safety.o trace.o
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -I. -I.. -I../include -I../kglib -I../ORBitutil -nostdinc
++
++include $(TOPDIR)/Rules.make
+diff -urN linux-2.4.1/net/korbit/ORBitutil/basic_types.h linux-2.4.1-korbit/net/korbit/ORBitutil/basic_types.h
+--- linux-2.4.1/net/korbit/ORBitutil/basic_types.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/basic_types.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,46 @@
++#ifndef BASIC_TYPES_H
++#define BASIC_TYPES_H 1
++
++#include <glib.h>
++
++typedef gint16 CORBA_short;
++typedef gint32 CORBA_long;
++typedef guint16 CORBA_unsigned_short;
++typedef guint32 CORBA_unsigned_long;
++typedef gfloat CORBA_float;
++typedef gdouble CORBA_double;
++typedef char CORBA_char;
++typedef guchar CORBA_boolean;
++typedef guchar CORBA_octet;
++typedef gdouble CORBA_long_double;
++typedef guint16 CORBA_wchar; /* I'm not sure what size a wchar is supposed to be */
++
++/* Just a peeve */
++typedef CORBA_char GIOP_char;
++typedef CORBA_wchar GIOP_wchar;
++typedef CORBA_short GIOP_short;
++typedef CORBA_long GIOP_long;
++typedef CORBA_unsigned_short GIOP_unsigned_short;
++typedef CORBA_unsigned_long GIOP_unsigned_long;
++typedef CORBA_octet GIOP_octet;
++typedef CORBA_long GIOP_enum;
++typedef CORBA_boolean GIOP_boolean;
++typedef CORBA_float GIOP_float;
++typedef CORBA_double GIOP_double;
++typedef CORBA_long_double GIOP_long_double;
++
++#ifdef G_HAVE_GINT64
++#define HAVE_CORBA_LONG_LONG
++/* According to the spec, these two are optional. We support them if we can. */
++typedef gint64 CORBA_long_long;
++typedef guint64 CORBA_unsigned_long_long;
++typedef CORBA_long_long GIOP_long_long;
++typedef CORBA_unsigned_long_long GIOP_unsigned_long_long;
++#else
++#warning ""
++#warning "You don't G_HAVE_GINT64 defined in glib."
++#warning "Please make sure you don't have an old glibconfig.h lying around."
++#warning ""
++#endif
++
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/compat.c linux-2.4.1-korbit/net/korbit/ORBitutil/compat.c
+--- linux-2.4.1/net/korbit/ORBitutil/compat.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/compat.c Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,43 @@
++#include "config.h"
++#include "util.h"
++
++#define MAX_IOVS 16
++
++int g_writev(int fd, const struct iovec * vector, size_t count)
++{
++ int retval = 0;
++
++ while(count > MAX_IOVS) {
++ retval += writev(fd, vector, MAX_IOVS);
++ vector += MAX_IOVS; count -= MAX_IOVS;
++ }
++
++ return writev(fd, vector, count) + retval;
++}
++
++#ifndef HAVE_INET_ATON
++#include <netinet/in.h>
++#include <string.h>
++int inet_aton(const char *cp, struct in_addr *inp)
++{
++ union {
++ unsigned int n;
++ char parts[4];
++ } u;
++ int a=0,b=0,c=0,d=0, i;
++
++ i = sscanf(cp, "%d.%d.%d.%d%*s", &a, &b, &c, &d);
++
++ if(i != 4)
++ return 0;
++
++ u.parts[0] = a;
++ u.parts[1] = b;
++ u.parts[2] = c;
++ u.parts[3] = d;
++
++ inp->s_addr = u.n;
++
++ return 1;
++}
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/compat.h linux-2.4.1-korbit/net/korbit/ORBitutil/compat.h
+--- linux-2.4.1/net/korbit/ORBitutil/compat.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/compat.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,8 @@
++#ifndef ORBITUTIL_COMPAT_H
++#define ORBITUTIL_COMPAT_H 1
++#include <sys/types.h>
++#include <sys/uio.h>
++
++int g_writev(int fd, const struct iovec * vector, size_t count);
++
++#endif /*#define ORBITUTIL_COMPAT_H 1 */
+diff -urN linux-2.4.1/net/korbit/ORBitutil/orbit-os-config.h linux-2.4.1-korbit/net/korbit/ORBitutil/orbit-os-config.h
+--- linux-2.4.1/net/korbit/ORBitutil/orbit-os-config.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/orbit-os-config.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,8 @@
++#ifndef OS_CONFIG_H
++#define OS_CONFIG_H 1
++
++#ifndef __KORBIT__
++#define ORBIT_HAVE_ALLOCA_H 1
++#endif
++
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/os-feature-alloca.h linux-2.4.1-korbit/net/korbit/ORBitutil/os-feature-alloca.h
+--- linux-2.4.1/net/korbit/ORBitutil/os-feature-alloca.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/os-feature-alloca.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,26 @@
++#ifndef OS_FEATURE_ALLOCA_H
++#define OS_FEATURE_ALLOCA_H 1
++
++# if ORBIT_HAVE_ALLOCA_H
++# include <alloca.h>
++# endif
++
++# include <string.h>
++
++# if defined(__GNUC__)
++
++# if defined(__STRICT_ANSI__)
++# define alloca __builtin_alloca
++# endif
++
++# elif !(ORBIT_HAVE_ALLOCA_H)
++
++# if defined(_AIX)
++ #pragma alloca
++# elif !defined(alloca) /* predefined by HP cc +Olibcalls */
++char *alloca ();
++# endif
++
++# endif /* __GNUC__ etc. */
++
++#endif /* OS_FEATURE_ALLOCA_H */
+diff -urN linux-2.4.1/net/korbit/ORBitutil/os-specifics.h linux-2.4.1-korbit/net/korbit/ORBitutil/os-specifics.h
+--- linux-2.4.1/net/korbit/ORBitutil/os-specifics.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/os-specifics.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,12 @@
++#ifndef ORBITUTIL_OS_SPECIFICS_H
++#define ORBITUTIL_OS_SPECIFICS_H 1
++
++#include <ORBitutil/orbit-os-config.h>
++
++#include <ORBitutil/os-feature-alloca.h>
++
++/* This file should be a bunch of #ifdef's to #include the
++ os-<osname>.h for the current OS. It is intended to abstract the
++ gunkiness necessary to get some OS's to build ORBit properly. */
++
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/thread-safety.c linux-2.4.1-korbit/net/korbit/ORBitutil/thread-safety.c
+--- linux-2.4.1/net/korbit/ORBitutil/thread-safety.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/thread-safety.c Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,19 @@
++#include "util.h"
++
++#ifdef NOT_REENTRANT
++#include <pthread.h>
++
++pthread_key_t thread_data;
++
++void init_thread_data(void) __attribute__ ((constructor));
++
++void init_thread_data(void)
++{
++ pthread_key_create(&thread_data, NULL);
++}
++
++#else
++
++gpointer prog_data = NULL;
++
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/thread-safety.h linux-2.4.1-korbit/net/korbit/ORBitutil/thread-safety.h
+--- linux-2.4.1/net/korbit/ORBitutil/thread-safety.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/thread-safety.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,36 @@
++#ifndef THREAD_SAFETY_H
++#define THREAD_SAFETY_H 1
++
++#ifdef NOT_REENTRANT
++
++#include <pthread.h>
++
++#define DEFINE_LOCK(x) pthread_mutex_t x##_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
++#define INIT_LOCK(x) /* We use static initialization, see above */
++#define GET_LOCK(x) pthread_mutex_lock(&x##_lock)
++#define RELEASE_LOCK(x) pthread_mutex_unlock(&x##_lock)
++#define PARAM_LOCK(x) pthread_mutex_t x##_lock
++#define LOCK_NAME(x) x##_lock
++#define EXTERN_LOCK(x) extern pthread_mutex_t x##_lock
++extern pthread_key_t thread_data;
++#define GET_THREAD_DATA() pthread_getspecific(thread_data)
++#define SET_THREAD_DATA(x) pthread_setspecific(thread_data, (x))
++
++#else
++
++/* stupid work around ANSI & empty semicolons. */
++#define DEFINE_LOCK(x)
++#define INIT_LOCK(x)
++#define GET_LOCK(x)
++#define RELEASE_LOCK(x)
++#define PARAM_LOCK(x) gpointer x##_lock
++#define LOCK_NAME(x) NULL
++#define EXTERN_LOCK(x)
++
++extern gpointer prog_data;
++#define GET_THREAD_DATA() prog_data
++#define SET_THREAD_DATA(x) (prog_data = (x))
++
++#endif
++
++#endif /* THREAD_SAFETY_H */
+diff -urN linux-2.4.1/net/korbit/ORBitutil/trace.c linux-2.4.1-korbit/net/korbit/ORBitutil/trace.c
+--- linux-2.4.1/net/korbit/ORBitutil/trace.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/trace.c Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,94 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ *
++ */
++
++#include <stdio.h>
++#include <stdarg.h>
++
++#include "trace.h"
++
++/*
++ * The function to call to handle trace messages, or NULL to use the default
++ * of printing to stderr.
++ */
++#ifdef ORBIT_DEBUG
++static int (* TraceCallback)(char *, va_list)=NULL;
++static int TraceModules=0;
++static ORBit_TraceLevel TraceMaxLevel=0;
++
++const char *ORBit_Trace_levellist[] = {
++ "ALERT ",
++ "CRITICAL",
++ "ERROR ",
++ "WARNING ",
++ "NOTICE ",
++ "INFO ",
++ "DEBUG "
++};
++
++void ORBit_Trace_setCallback(int (*cbf)(char *, va_list))
++{
++ TraceCallback=cbf;
++}
++
++int (*ORBit_Trace_getCallback(void))(char *, va_list)
++{
++ return(TraceCallback);
++}
++
++void ORBit_Trace_setModules(int modules)
++{
++ TraceModules=modules;
++}
++
++void ORBit_Trace_setLevel(ORBit_TraceLevel level)
++{
++ TraceMaxLevel=level;
++}
++
++int ORBit_Trace(ORBit_TraceModule module, ORBit_TraceLevel level, char *fmt, ...)
++{
++ va_list args;
++
++ if(!BitTest(TraceModules, module))
++ return 0;
++ if(TraceMaxLevel < level)
++ return 0;
++
++ va_start(args, fmt);
++ if(TraceCallback!=NULL)
++ return((*TraceCallback)(fmt, args));
++
++#ifdef __KORBIT__
++ printf("[%s]: ", ORBit_Trace_levellist[level]);
++
++ printf("%s", g_strdup_vprintf(fmt, args));
++ return 0; // breaks semantics, but return value is never used
++#else /* !__KORBIT__ */
++ fprintf(stderr, "[%s]: ", ORBit_Trace_levellist[level]);
++
++ return vfprintf(stderr, fmt, args);
++#endif /* !__KORBIT__ */
++}
++#endif
+diff -urN linux-2.4.1/net/korbit/ORBitutil/trace.h linux-2.4.1-korbit/net/korbit/ORBitutil/trace.h
+--- linux-2.4.1/net/korbit/ORBitutil/trace.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/trace.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,68 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ *
++ */
++
++#ifndef _ORBIT_TRACE_H_
++#define _ORBIT_TRACE_H_
++
++#include <stdarg.h>
++#include "util.h"
++
++typedef enum {
++ TraceMod_ORB,
++ TraceMod_CDR,
++ TraceMod_IIOP,
++ TraceMod_TC,
++ TraceMod_IR,
++ TraceMod_User=32
++} ORBit_TraceModule;
++
++typedef enum {
++ TraceLevel_Alert=0,
++ TraceLevel_Critical,
++ TraceLevel_Error,
++ TraceLevel_Warning,
++ TraceLevel_Notice,
++ TraceLevel_Info,
++ TraceLevel_Debug
++} ORBit_TraceLevel;
++
++extern const char *ORBit_Trace_levellist[];
++
++#ifdef ORBIT_DEBUG
++extern void ORBit_Trace_setCallback(int (*)(char *, va_list));
++extern int (*ORBit_Trace_getCallback(void))(char *, va_list);
++extern void ORBit_Trace_setModules(int);
++extern void ORBit_Trace_setLevel(ORBit_TraceLevel);
++extern int ORBit_Trace(ORBit_TraceModule, ORBit_TraceLevel, char *, ...);
++#else
++#define ORBit_Trace_setCallback(x)
++#define ORBit_Trace_getCallback() NULL
++#define ORBit_Trace_setModules(x)
++#define ORBit_Trace_setLevel(x)
++#define ORBit_Trace(module,level,fmt,args...)
++#endif
++
++
++#endif /* !_ORBIT_TRACE_H_ */
+diff -urN linux-2.4.1/net/korbit/ORBitutil/util.h linux-2.4.1-korbit/net/korbit/ORBitutil/util.h
+--- linux-2.4.1/net/korbit/ORBitutil/util.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/ORBitutil/util.h Thu Feb 1 11:46:52 2001
+@@ -0,0 +1,35 @@
++#ifndef UTIL_H
++#define UTIL_H 1
++
++#include <glib.h>
++
++#define ORBIT_DEBUG 1
++
++#ifdef ORBIT_DEBUG
++#define ORBIT_DEBUG_NOTE(x) (x)
++#else
++#define ORBIT_DEBUG_NOTE(x)
++#endif
++
++
++#define BitTest(f, bit) ((f) & (1<<(bit)))
++#define BitSet(f, bit) ((f) |= (1<<(bit)))
++#define BitClr(f, bit) ((f) &= ~(1<<(bit)))
++/* Align an address upward to a boundary, expressed as a number of bytes.
++ E.g. align to an 8-byte boundary with argument of 8. */
++
++/*
++ * (this + boundary - 1)
++ * &
++ * ~(boundary - 1)
++ */
++
++#define ALIGN_ADDRESS(this, boundary) \
++ ((gpointer)((( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))))
++
++#include <ORBitutil/thread-safety.h>
++#include <ORBitutil/trace.h>
++#include <ORBitutil/compat.h>
++#include <ORBitutil/os-specifics.h>
++
++#endif
+diff -urN linux-2.4.1/net/korbit/config.h linux-2.4.1-korbit/net/korbit/config.h
+--- linux-2.4.1/net/korbit/config.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/config.h Thu Feb 1 11:46:49 2001
+@@ -0,0 +1,73 @@
++
++/* Define if you have alloca, as a function or macro. */
++#define HAVE_ALLOCA 1
++
++#define HAVE_ATEXIT 1
++#define NO_SYS_SIGLIST 1 /* reduce dependencies */
++#define NO_SYS_ERRLIST 1 /* reduce dependencies */
++
++/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
++/* #define HAVE_ALLOCA_H 1 */
++
++/* Define if you have the vprintf function. */
++#define HAVE_VPRINTF 1
++
++/* Define if you have the ANSI C header files. */
++#define STDC_HEADERS 1
++
++#define HAVE_INET_ATON 1
++/* #undef ORBIT_SERIAL */
++
++/* Define to 'int' if it isn't defined in the header files. */
++/* #undef socklen_t */
++
++#define ALIGNOF_CORBA_BOOLEAN 1
++#define ALIGNOF_CORBA_CHAR 1
++#define ALIGNOF_CORBA_DOUBLE 4
++#define ALIGNOF_CORBA_FLOAT 4
++#define ALIGNOF_CORBA_LONG 4
++#define ALIGNOF_CORBA_LONG_DOUBLE 4
++#define ALIGNOF_CORBA_LONG_LONG 4
++#define ALIGNOF_CORBA_OCTET 1
++#define ALIGNOF_CORBA_SHORT 2
++#define ALIGNOF_CORBA_STRUCT 1
++#define ALIGNOF_CORBA_UNSIGNED_LONG 4
++#define ALIGNOF_CORBA_UNSIGNED_LONG_LONG 4
++#define ALIGNOF_CORBA_UNSIGNED_SHORT 2
++#define ALIGNOF_CORBA_WCHAR 2
++#define ALIGNOF_CORBA_POINTER 4
++
++/* TCP wrappers */
++#define HAVE_TCPD_H 1
++
++#ifdef HAVE_ALLOCA_H
++#include <alloca.h>
++#endif
++
++/* Define if you have the basename function. */
++#define HAVE_BASENAME 1
++
++/* Define if you have the poll function. */
++#define HAVE_POLL 1
++#define I_WANT_POLL 1
++
++/* Define if you have the <endian.h> header file. */
++#define HAVE_ENDIAN_H 1
++
++/* Define if you have the <fcntl.h> header file. */
++#define HAVE_FCNTL_H 1
++
++/* Define if you have the <stddef.h> header file. */
++#define HAVE_STDDEF_H 1
++
++/* Define if you have the <sys/poll.h> header file. */
++#define HAVE_SYS_POLL_H 1
++
++/* Define if you have the <tcpd.h> header file. */
++#define HAVE_TCPD_H 1
++
++/* Define if you have the <unistd.h> header file. */
++#define HAVE_UNISTD_H 1
++
++/* Define if you have the <wchar.h> header file. */
++#define HAVE_WCHAR_H 1
+diff -urN linux-2.4.1/net/korbit/exported_symbols.c linux-2.4.1-korbit/net/korbit/exported_symbols.c
+--- linux-2.4.1/net/korbit/exported_symbols.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/exported_symbols.c Thu Feb 1 11:46:49 2001
+@@ -0,0 +1,93 @@
++/*
++ * #include whatever it takes to get the EXPORT_SYMBOL macro, and
++ * whatever header files from korbit (for things that are being
++ * exported.
++ */
++#include <linux/config.h>
++#include <linux/module.h>
++#include "errno.h"
++#include "orb/orbit.h"
++
++/*
++ * Stuff that's good to export
++ */
++EXPORT_SYMBOL(errno);
++
++/*
++ * kglib exports...
++ */
++EXPORT_SYMBOL(g_malloc0);
++EXPORT_SYMBOL(g_free);
++EXPORT_SYMBOL(g_snprintf);
++
++/*
++ * Mainline CORBA symbols.
++ */
++EXPORT_SYMBOL(CORBA_exception_init);
++EXPORT_SYMBOL(CORBA_ORB_init);
++EXPORT_SYMBOL(CORBA_ORB_resolve_initial_references);
++EXPORT_SYMBOL(CORBA_ORB_object_to_string);
++EXPORT_SYMBOL(CORBA_free);
++EXPORT_SYMBOL(CORBA_ORB_run);
++EXPORT_SYMBOL(CORBA_Object_release);
++EXPORT_SYMBOL(CORBA_Object_duplicate);
++EXPORT_SYMBOL(CORBA_octet_allocbuf);
++EXPORT_SYMBOL(CORBA_exception_set);
++EXPORT_SYMBOL(CORBA_string__free);
++EXPORT_SYMBOL(CORBA_ORB_string_to_object);
++EXPORT_SYMBOL(CORBA_string_alloc);
++EXPORT_SYMBOL(CORBA_exception_set_system);
++
++/*
++ * ORBIT Specific symbols to export
++ */
++EXPORT_SYMBOL(ORBit_TypeCode_epv);
++EXPORT_SYMBOL(ORBit_send_system_exception);
++EXPORT_SYMBOL(ORBit_register_class);
++EXPORT_SYMBOL(ORBit_marshal_object);
++EXPORT_SYMBOL(ORBit_alloc);
++EXPORT_SYMBOL(ORBit_free);
++EXPORT_SYMBOL(ORBit_send_user_exception);
++EXPORT_SYMBOL(ORBit_delete_profiles);
++EXPORT_SYMBOL(ORBit_demarshal_object);
++EXPORT_SYMBOL(_ORBit_object_get_connection);
++EXPORT_SYMBOL(ORBit_handle_exception);
++EXPORT_SYMBOL(ORBit_object_get_forwarded_connection);
++EXPORT_SYMBOL(ORBit_default_principal_iovec);
++EXPORT_SYMBOL(ORBit_demarshal_IOR);
++
++/*
++ * CORBA giop functions
++ */
++EXPORT_SYMBOL(giop_send_buffer_write);
++EXPORT_SYMBOL(giop_send_buffer_unuse);
++EXPORT_SYMBOL(giop_message_buffer_do_alignment);
++EXPORT_SYMBOL(giop_message_buffer_append_mem);
++EXPORT_SYMBOL(giop_send_reply_buffer_use);
++EXPORT_SYMBOL(giop_send_request_buffer_use);
++EXPORT_SYMBOL(giop_recv_buffer_unuse);
++EXPORT_SYMBOL(giop_recv_reply_buffer_use_2);
++
++/*
++ * POA Symbols.
++ */
++EXPORT_SYMBOL(PortableServer_POAManager_activate);
++EXPORT_SYMBOL(PortableServer_POA_activate_object_with_id);
++EXPORT_SYMBOL(PortableServer_POA_servant_to_reference);
++EXPORT_SYMBOL(PortableServer_POA_deactivate_object);
++EXPORT_SYMBOL(PortableServer_POA__get_the_POAManager);
++EXPORT_SYMBOL(PortableServer_ServantBase__init);
++EXPORT_SYMBOL(PortableServer_ServantBase__fini);
++EXPORT_SYMBOL(PortableServer_POA_reference_to_servant);
++EXPORT_SYMBOL(PortableServer_POA_servant_to_id);
++EXPORT_SYMBOL(PortableServer_POA_activate_object);
++EXPORT_SYMBOL(PortableServer_POA_reference_to_id);
++
++/*
++ * TC Stuff (whatever that is)
++ */
++EXPORT_SYMBOL(TC_octet_struct);
++EXPORT_SYMBOL(TC_long_struct);
++EXPORT_SYMBOL(TC_ulong_struct);
++EXPORT_SYMBOL(TC_short_struct);
++EXPORT_SYMBOL(TC_string_struct);
+diff -urN linux-2.4.1/net/korbit/include/.cvsignore linux-2.4.1-korbit/net/korbit/include/.cvsignore
+--- linux-2.4.1/net/korbit/include/.cvsignore Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/.cvsignore Thu Feb 1 11:46:53 2001
+@@ -0,0 +1 @@
++stdarg.h
+diff -urN linux-2.4.1/net/korbit/include/CVS/Entries linux-2.4.1-korbit/net/korbit/include/CVS/Entries
+--- linux-2.4.1/net/korbit/include/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/CVS/Entries Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,24 @@
++/.cvsignore/1.1/Thu Feb 1 09:46:53 2001//
++/alloca.h/1.3/Thu Feb 1 09:46:53 2001//
++/assert.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/ctype.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/dirent.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/errno.h/1.2/Thu Feb 1 09:46:53 2001//
++/fcntl.h/1.3/Thu Feb 1 09:46:53 2001//
++/host_list.h/1.7/Thu Feb 1 09:46:53 2001//
++/limits.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/locale.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/math.h/1.2/Thu Feb 1 09:46:53 2001//
++/netdb.h/1.17/Thu Feb 1 09:46:53 2001//
++/pwd.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/signal.h/1.1.1.1/Thu Feb 1 09:46:53 2001//
++/stdarg.h/1.3/Thu Feb 1 09:46:54 2001//
++/stddef.h/1.1.1.1/Thu Feb 1 09:46:54 2001//
++/stdio.h/1.19/Thu Feb 1 09:46:54 2001//
++/stdlib.h/1.4/Thu Feb 1 09:46:54 2001//
++/string.h/1.3/Thu Feb 1 09:46:54 2001//
++/syslog.h/1.1.1.1/Thu Feb 1 09:46:54 2001//
++/time.h/1.1.1.1/Thu Feb 1 09:46:54 2001//
++/unistd.h/1.3/Thu Feb 1 09:46:54 2001//
++/utime.h/1.1.1.1/Thu Feb 1 09:46:54 2001//
++D
+diff -urN linux-2.4.1/net/korbit/include/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/include/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/include/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/CVS/Entries.Log Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,3 @@
++A D/arpa////
++A D/netinet////
++A D/sys////
+diff -urN linux-2.4.1/net/korbit/include/CVS/Repository linux-2.4.1-korbit/net/korbit/include/CVS/Repository
+--- linux-2.4.1/net/korbit/include/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/CVS/Repository Thu Feb 1 11:46:53 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/include
+diff -urN linux-2.4.1/net/korbit/include/CVS/Root linux-2.4.1-korbit/net/korbit/include/CVS/Root
+--- linux-2.4.1/net/korbit/include/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/CVS/Root Thu Feb 1 11:46:53 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/include/alloca.h linux-2.4.1-korbit/net/korbit/include/alloca.h
+--- linux-2.4.1/net/korbit/include/alloca.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/alloca.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,6 @@
++#ifndef __KORBIT_ALLOCA_H__
++#define __KORBIT_ALLOCA_H__
++
++#include <stdlib.h>
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/arpa/CVS/Entries linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Entries
+--- linux-2.4.1/net/korbit/include/arpa/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Entries Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,2 @@
++/inet.h/1.4/Thu Feb 1 09:46:54 2001//
++D
+diff -urN linux-2.4.1/net/korbit/include/arpa/CVS/Repository linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Repository
+--- linux-2.4.1/net/korbit/include/arpa/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Repository Thu Feb 1 11:46:54 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/include/arpa
+diff -urN linux-2.4.1/net/korbit/include/arpa/CVS/Root linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Root
+--- linux-2.4.1/net/korbit/include/arpa/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/arpa/CVS/Root Thu Feb 1 11:46:54 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/include/arpa/inet.h linux-2.4.1-korbit/net/korbit/include/arpa/inet.h
+--- linux-2.4.1/net/korbit/include/arpa/inet.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/arpa/inet.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,50 @@
++#ifndef __KORBIT_ARPA_INET_H__
++#define __KORBIT_ARPA_INET_H__
++
++#include <linux/inet.h>
++#include <linux/in.h>
++
++static inline char* inet_ntoa(struct in_addr in)
++{
++ return in_ntoa(in.s_addr);
++}
++
++static inline int inet_aton(const char *cp, struct in_addr *inp)
++{
++ unsigned long l;
++ unsigned int val;
++ int i;
++
++ if (!cp || !inp)
++ return 0;
++
++ l = 0;
++ for (i = 0; i < 4; i++)
++ {
++ l <<= 8;
++ if (*cp != '\0')
++ {
++ val = 0;
++ while (*cp != '\0' && *cp != '.')
++ {
++ if (*cp < '0' || '9' < *cp)
++ return 0;
++
++ val *= 10;
++ val += *cp - '0';
++ cp++;
++ }
++ if (val > 255)
++ return 0;
++
++ l |= val;
++ if (*cp != '\0')
++ cp++;
++ }
++ }
++ inp->s_addr = htonl(l);
++
++ return 1;
++}
++
++#endif /* __KORBIT_ARPA_INET_H__ */
+diff -urN linux-2.4.1/net/korbit/include/assert.h linux-2.4.1-korbit/net/korbit/include/assert.h
+--- linux-2.4.1/net/korbit/include/assert.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/assert.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_ASSERT_H__
++#define __KORBIT_ASSERT_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/ctype.h linux-2.4.1-korbit/net/korbit/include/ctype.h
+--- linux-2.4.1/net/korbit/include/ctype.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/ctype.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,4 @@
++#ifndef __KORBIT_CTYPE_H__
++#define __KORBIT_CTYPE_H__
++#include <linux/ctype.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/include/dirent.h linux-2.4.1-korbit/net/korbit/include/dirent.h
+--- linux-2.4.1/net/korbit/include/dirent.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/dirent.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_DIRENT_H__
++#define __KORBIT_DIRENT_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/errno.h linux-2.4.1-korbit/net/korbit/include/errno.h
+--- linux-2.4.1/net/korbit/include/errno.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/errno.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,9 @@
++#ifndef __KORBIT_ERRNO_H__
++#define __KORBIT_ERRNO_H__
++
++#include <asm/errno.h>
++
++#define errno korbit_errno
++extern int korbit_errno;
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/fcntl.h linux-2.4.1-korbit/net/korbit/include/fcntl.h
+--- linux-2.4.1/net/korbit/include/fcntl.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/fcntl.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,49 @@
++#ifndef __KORBIT_FCNTL_H__
++#define __KORBIT_FCNTL_H__
++
++#include <linux/mm.h>
++#include <linux/file.h>
++#include <linux/smp_lock.h>
++
++#include <asm/fcntl.h>
++
++#include <stdio.h>
++
++#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC)
++
++static inline int fcntl(int fd, int cmd, long arg)
++{
++ struct file *filp = fd2file(fd);
++ long err = -EINVAL;
++
++ switch (cmd)
++ {
++ case F_SETFD:
++ case F_GETFD:
++ err = 0;
++ break;
++ case F_GETFL:
++ if (filp)
++ err = filp->f_flags;
++ break;
++ case F_SETFL:
++ if (filp)
++ {
++ lock_kernel();
++
++ /* required for strict SunOS emulation */
++ if (O_NONBLOCK != O_NDELAY)
++ if (arg & O_NDELAY)
++ arg |= O_NONBLOCK;
++
++ filp->f_flags = (arg & SETFL_MASK) |
++ (filp->f_flags & ~SETFL_MASK);
++ err = 0;
++ unlock_kernel();
++ }
++ break;
++ }
++ return err;
++}
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/host_list.h linux-2.4.1-korbit/net/korbit/include/host_list.h
+--- linux-2.4.1/net/korbit/include/host_list.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/host_list.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,24 @@
++/*
++ * A statically-allocated list of Hostnames<->IPv4 addresses.
++ */
++#ifndef __KORBIT_HOST_LIST_H
++#define __KORBIT_HOST_LIST_H
++
++static struct {
++ char *name;
++ char *IP;
++} host_table[] = {
++ {"redefine.dyndns.org", "206.221.225.140"},
++ {"csil-sunb4.cs.uiuc.edu", "128.174.243.204"},
++ {"kazoo.cs.uiuc.edu", "128.174.237.133"},
++ {"opus0.cs.uiuc.edu", "128.174.236.20"},
++ {"wakeland-56.flexabit.net", "64.198.239.56"},
++ {"es-dcl-border1.cso.uiuc.edu", "127.0.0.1"},
++ {"es-dcl-border1", "127.0.0.1"}
++// {"es-dcl-border1.cso.uiuc.edu", "130.126.112.222"},
++// {"es-dcl-border1", "130.126.112.222"}
++};
++
++#define __MAX_STATIC_NAMES (sizeof(host_table) / sizeof(host_table[0]))
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/limits.h linux-2.4.1-korbit/net/korbit/include/limits.h
+--- linux-2.4.1/net/korbit/include/limits.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/limits.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,7 @@
++#ifndef __KORBIT_LIMITS_H__
++#define __KORBIT_LIMITS_H__
++
++#include <linux/limits.h>
++#include <linux/kernel.h>
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/locale.h linux-2.4.1-korbit/net/korbit/include/locale.h
+--- linux-2.4.1/net/korbit/include/locale.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/locale.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_LOCALE_H__
++#define __KORBIT_LOCALE_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/math.h linux-2.4.1-korbit/net/korbit/include/math.h
+--- linux-2.4.1/net/korbit/include/math.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/math.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,16 @@
++#ifndef __KORBIT_MATH_H__
++#define __KORBIT_MATH_H__
++
++#include <asm/page.h>
++
++static inline double pow(double x, double y) {
++ double Q = 1.0;
++ if (y < 0)
++ BUG();
++/* return 1.0/pow(x,-y);*/
++ while (y-- > 0)
++ Q *= x;
++ return Q;
++}
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/netdb.h linux-2.4.1-korbit/net/korbit/include/netdb.h
+--- linux-2.4.1/net/korbit/include/netdb.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/netdb.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,197 @@
++#ifndef __KORBIT_NETDB_H__
++#define __KORBIT_NETDB_H__
++
++#include <sys/socket.h>
++#include <linux/in.h>
++#include <arpa/inet.h>
++#include "host_list.h"
++
++#define h_errno 0
++/* static int h_errno; */
++
++/* Description of data base entry for a single host. */
++struct hostent
++{
++ char *h_name; /* Official name of host. */
++ char **h_aliases; /* Alias list. */
++ int h_addrtype; /* Host address type. */
++ socklen_t h_length; /* Length of address. */
++ char **h_addr_list; /* List of addresses from name server. */
++#define h_addr h_addr_list[0] /* Address, for backward compatibility. */
++};
++
++/* Is this defined somewhere else? */
++/*struct in_addr {
++ __uint32_t s_addr;
++};*/
++
++/*
++ * Set h_errno?
++ * #define HOST_NOT_FOUND 1
++ * #define TRY_AGAIN 2
++ * #define NO_RECOVERY 3
++ * #define NO_DATA 4
++ */
++static inline struct hostent *gethostbyname (char *host)
++{
++ int c;
++ static struct in_addr tmp_in;
++ static struct hostent ret_host;
++ static char *aliases[2];
++ static char *addrs[2];
++
++ if (host == NULL)
++ {
++ printf ("** gethostbyname() Error: Got NULL parameter! **\n");
++ return (NULL);
++ }
++
++ /*
++ * The actual lookup.
++ */
++ for (c = 0; c < __MAX_STATIC_NAMES; c++)
++ {
++ if (host_table[c].name && strncmp (host, host_table[c].name, strlen(host_table[c].name)) == 0)
++ {
++/* printf ("Name '%s' found at position %d!\n", argv[1], c);*/
++/* printf ("IP address is: '%s'.\n", IPs[c]);*/
++ break;
++ }
++ }
++
++ if (c == __MAX_STATIC_NAMES)
++ {
++ /* Host not found, return NULL. */
++ return (NULL);
++ }
++ /* else, names[c] is gold! */
++
++ /* make a new hostent, ret_host */
++
++ ret_host.h_addrtype = AF_INET;
++ ret_host.h_aliases = aliases;
++ aliases[0] = host_table[c].name;
++ aliases[1] = NULL;
++ ret_host.h_name = host_table[c].name;
++ if (!inet_aton (host_table[c].IP, &tmp_in))
++ {
++ printf ("** gethostbyname() Error: Invalid IP address in table! **\n");
++ return (NULL);
++ }
++ ret_host.h_addr_list = addrs;
++ addrs[0] = (char *)&tmp_in.s_addr;
++ addrs[1] = NULL;
++ ret_host.h_length = sizeof (tmp_in.s_addr);
++ return (&ret_host);
++} /* End gethostbyname(). */
++
++/*
++ * TODO: getpeername(), gethostbyaddr(), getsockname(), gethostname()
++ * Everything from here-on has been untested (in userland). Buyer beware.
++ */
++static inline struct hostent *gethostbyaddr (const char *addr, int len, int type)
++{
++ struct in_addr tin;
++ char *inp_addr;
++ int c;
++ static struct hostent ret_host;
++ static char *aliases[1];
++ static char *addrs[2];
++ static struct in_addr tmp_in;
++
++
++ if ((type != AF_INET) || (len != 4))
++ {
++ printf ("** gethostbyaddr Error: Don't know how to deal with non-AF_INET addresses! **\n");
++ return (NULL);
++ }
++
++ tin.s_addr = *((__u32 *)addr);
++ inp_addr = inet_ntoa (tin);
++ if (inp_addr == NULL)
++ {
++ /* We got some invalid input, baby. */
++ return (NULL);
++
++ }
++
++ /*
++ * The actual lookup.
++ */
++ for (c = 0; c < __MAX_STATIC_NAMES; c++)
++ {
++ if (host_table[c].IP && strncmp (inp_addr, host_table[c].IP, strlen(host_table[c].IP)) == 0)
++ {
++ break;
++ }
++ }
++
++ if (c == __MAX_STATIC_NAMES)
++ {
++ /* Host not found, return NULL. */
++ return (NULL);
++ }
++ /* else, host_table[c].IP is gold! */
++
++ ret_host.h_addrtype = AF_INET;
++ ret_host.h_aliases = aliases;
++ aliases[0] = NULL;
++ ret_host.h_name = host_table[c].name;
++ if (!inet_aton (host_table[c].IP, &tmp_in))
++ {
++ printf ("** gethostbyname() Error: Invalid IP address in table! **\n");
++ return (NULL);
++ }
++ ret_host.h_addr_list = addrs;
++ addrs[0] = (char *)&tmp_in.s_addr;
++ addrs[1] = NULL;
++ ret_host.h_length = sizeof (tmp_in.s_addr);
++ return (&ret_host);
++} /* End gethostbyaddr(). */
++
++/*
++ * If successful, return 0. Else, return -1 and set errno.
++ * Errors:
++ * EBADF The argument s is not a valid file descriptor.
++ *
++ * ENOMEM
++ * There was insufficient memory available for the opera-
++ * tion to complete.
++ *
++ * ENOSR There were insufficient STREAMS resources available
++ * for the operation to complete.
++ *
++ * ENOTSOCK
++ * The argument s is not a socket.
++ */
++static inline int getsockname (int s, struct sockaddr *name, socklen_t *namelen)
++{
++ struct socket *sock = fd2sock(s);
++
++ if (sock == NULL)
++ return -1;
++
++ /*
++ * getname() wants an 'int *' for the length, will it by this
++ * 'socklen_t *' business? (even though it is just an 'int *'?).
++ */
++ if (sock->ops->getname(sock, name, namelen, 0) == 0)
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++} /* End getsockname(). */
++
++static inline int getpeername (int s, struct sockaddr *name, socklen_t *namelen)
++{
++ struct socket *sock = fd2sock(s);
++
++ if (sock == NULL)
++ return -1;
++
++ if (sock->ops->getname(sock, name, namelen, 1) == 0)
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++} /* End getpeername(). */
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/netinet/CVS/Entries linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Entries
+--- linux-2.4.1/net/korbit/include/netinet/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Entries Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,2 @@
++/in.h/1.1.1.1/Thu Feb 1 09:46:55 2001//
++D
+diff -urN linux-2.4.1/net/korbit/include/netinet/CVS/Repository linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Repository
+--- linux-2.4.1/net/korbit/include/netinet/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Repository Thu Feb 1 11:46:55 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/include/netinet
+diff -urN linux-2.4.1/net/korbit/include/netinet/CVS/Root linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Root
+--- linux-2.4.1/net/korbit/include/netinet/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/netinet/CVS/Root Thu Feb 1 11:46:55 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/include/netinet/in.h linux-2.4.1-korbit/net/korbit/include/netinet/in.h
+--- linux-2.4.1/net/korbit/include/netinet/in.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/netinet/in.h Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,5 @@
++#ifndef __KORBIT_NETINET_IN_H__
++#define __KORBIT_NETINET_IN_H__
++#include <linux/socket.h>
++#include <linux/in.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/include/pwd.h linux-2.4.1-korbit/net/korbit/include/pwd.h
+--- linux-2.4.1/net/korbit/include/pwd.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/pwd.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_PWD_H__
++#define __KORBIT_PWD_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/signal.h linux-2.4.1-korbit/net/korbit/include/signal.h
+--- linux-2.4.1/net/korbit/include/signal.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/signal.h Thu Feb 1 11:46:53 2001
+@@ -0,0 +1,6 @@
++#ifndef __KORBIT_SIGNAL_H__
++#define __KORBIT_SIGNAL_H__
++
++#include <asm/signal.h>
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/stdarg.h linux-2.4.1-korbit/net/korbit/include/stdarg.h
+--- linux-2.4.1/net/korbit/include/stdarg.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/stdarg.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,13 @@
++#ifndef __KORBIT_STDARG_H__
++#define __KORBIT_STDARG_H__
++
++#define ANDY 1
++
++#if FREDRIK
++#include "/usr/lib/gcc-lib/i386-glibc21-linux/egcs-2.91.66/include/stdarg.h"
++#elif CHRIS
++#include "/usr/lib/gcc-lib/i586-mandrake-linux/egcs-2.91.66/include/stdarg.h"
++#elif ANDY
++#include "/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h"
++#endif
++#endif
+diff -urN linux-2.4.1/net/korbit/include/stddef.h linux-2.4.1-korbit/net/korbit/include/stddef.h
+--- linux-2.4.1/net/korbit/include/stddef.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/stddef.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_STDDEF_H__
++#define __KORBIT_STDDEF_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/stdio.h linux-2.4.1-korbit/net/korbit/include/stdio.h
+--- linux-2.4.1/net/korbit/include/stdio.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/stdio.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,402 @@
++#ifndef __KORBIT_STDIO_H__
++#define __KORBIT_STDIO_H__
++
++#include <asm/segment.h>
++#include <asm/uaccess.h>
++#include <linux/smp_lock.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/sched.h>
++#include <linux/uio.h>
++#include <linux/dcache.h>
++#include <linux/file.h>
++#include <linux/highuid.h>
++#include <sys/socket.h>
++
++#include <errno.h>
++
++#define KORBIT_DEBUG_WRITING 0
++
++
++#define printf(format,args...) printk(format,##args)
++#define fflush(x)
++
++#define SEEK_SET 0 /* Seek from beginning of file. */
++#define SEEK_CUR 1 /* Seek from current position. */
++#define SEEK_END 2 /* Seek from end of file. */
++
++static inline int unlink(const char *pathname) {
++ printf("KERNEL UNLINK('%s') CALLED!\n", pathname);
++ return -1;
++}
++
++static inline struct file *fd2file(int fd) {
++ if (fd & 1) /* can't convert a socket! */
++ return NULL;
++
++ return (struct file *)(-(fd & ~1));
++}
++
++static inline int open(const char *filename, int flags, int mode) {
++ struct file *RetVal = filp_open(filename, flags, mode);
++ if (IS_ERR(RetVal))
++ {
++ errno = PTR_ERR(RetVal);
++ return -1;
++ }
++ return -(int)RetVal;
++}
++
++static inline int creat(const char *filename, mode_t mode)
++{
++ return open(filename, O_CREAT | O_WRONLY | O_TRUNC, mode);
++}
++
++static inline int lseek(int fd, long offset, int whence)
++{
++ if ((fd & 1) == 1)
++ {
++ printk("KERNEL FSEEK() CALLED ON SOCKET!\n");
++ return -1;
++ }
++ else
++ {
++ struct file *F = fd2file(fd);
++ loff_t (*fn)(struct file *, loff_t, int);
++ int retval = -1;
++
++ if (whence <= 2)
++ {
++ fn = default_llseek;
++ if (F->f_op && F->f_op->llseek)
++ fn = F->f_op->llseek;
++
++ lock_kernel();
++ retval = fn(F, offset, whence);
++ unlock_kernel();
++ }
++ if (retval < 0)
++ {
++ errno = -retval;
++ retval = -1;
++ }
++ return retval;
++ }
++}
++
++
++asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
++static inline int stat(char *filename, struct stat *buf)
++{
++ mm_segment_t oldfs;
++ int retval;
++
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ retval = sys_newstat(filename, buf);
++ set_fs(oldfs);
++ if (retval < 0)
++ {
++ errno = -retval;
++ retval = -1;
++ }
++ return retval;
++}
++
++asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
++static inline int lstat(char *filename, struct stat *buf)
++{
++ mm_segment_t oldfs;
++ int retval;
++
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ retval = sys_newlstat(filename, buf);
++ set_fs(oldfs);
++ if (retval < 0)
++ {
++ errno = -retval;
++ retval = -1;
++ }
++ return retval;
++}
++
++
++static inline int do_revalidate(struct dentry *dentry)
++{
++ struct inode * inode = dentry->d_inode;
++ if (inode->i_op && inode->i_op->revalidate)
++ return inode->i_op->revalidate(dentry);
++ return 0;
++}
++
++
++static inline int cp_new_stat(struct inode * inode, struct stat * statbuf)
++{
++ struct stat tmp;
++
++ memset(&tmp, 0, sizeof(tmp));
++ tmp.st_dev = kdev_t_to_nr(inode->i_dev);
++ tmp.st_ino = inode->i_ino;
++ tmp.st_mode = inode->i_mode;
++ tmp.st_nlink = inode->i_nlink;
++ SET_STAT_UID(tmp, inode->i_uid);
++ SET_STAT_GID(tmp, inode->i_gid);
++ tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
++#if BITS_PER_LONG == 32
++ if (inode->i_size > 0x7fffffff)
++ return -EOVERFLOW;
++ else
++#endif
++ {
++ tmp.st_size = inode->i_size;
++ tmp.st_atime = inode->i_atime;
++ tmp.st_mtime = inode->i_mtime;
++ tmp.st_ctime = inode->i_ctime;
++
++ tmp.st_blocks = inode->i_blocks;
++ tmp.st_blksize = inode->i_blksize;
++
++ memcpy(statbuf, &tmp, sizeof(tmp));
++ return 0;
++ }
++}
++
++
++static inline int fstat(int fd, struct stat *buf)
++{
++ if ((fd & 1) == 1)
++ {
++ printk("TODO : FSTAT FOR SOCKETS, DO WE WANT THIS?\n");
++ errno = EBADF;
++ return -1;
++ }
++ else
++ {
++ struct file *file = fd2file(fd);
++ struct dentry *dentry;
++ int retval = -EBADF;
++
++ if (file)
++ {
++ dentry = file->f_dentry;
++ retval = do_revalidate(dentry);
++
++ if (!retval)
++ retval = cp_new_stat(dentry->d_inode, buf);
++ }
++ if (retval < 0)
++ {
++ errno = -retval;
++ retval = -1;
++ }
++ return retval;
++ }
++}
++
++
++asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz);
++static inline int readlink(const char *path, char *buf, size_t bufsiz)
++{
++ int retval;
++ mm_segment_t oldfs;
++
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ retval = sys_readlink(path, buf, bufsiz);
++ set_fs(oldfs);
++ if (retval < 0)
++ {
++ errno = -retval;
++ retval = -1;
++ }
++ return retval;
++}
++
++
++static inline int read(int fd, void *buffer, size_t count) {
++ if ((fd & 1) == 1)
++ {
++ struct socket *sock = fd2sock(fd);
++ struct iovec iov;
++ struct msghdr msg;
++ mm_segment_t oldfs;
++ int flags = 0;
++ int RetVal;
++
++ msg.msg_name = NULL;
++ msg.msg_namelen = 0;
++ msg.msg_iov = &iov;
++ msg.msg_iovlen = 1;
++ msg.msg_control = NULL;
++ msg.msg_controllen = 0;
++ msg.msg_flags = 0;
++ iov.iov_base = buffer;
++ iov.iov_len = count;
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ RetVal = sock_recvmsg(sock, &msg, count, flags);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++ else
++ {
++ struct file *F = fd2file(fd);
++ mm_segment_t oldfs;
++ int RetVal;
++
++ oldfs = get_fs();
++ set_fs(KERNEL_DS);
++ RetVal = F->f_op->read(F, buffer, count, &F->f_pos);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++}
++
++static inline int write(int fd, const void *buffer, size_t count) {
++ if ((fd & 1) == 1)
++ {
++ struct socket *sock = fd2sock(fd);
++ struct iovec iov;
++ struct msghdr msg;
++ mm_segment_t oldfs;
++ int RetVal;
++ msg.msg_name = NULL;
++ msg.msg_namelen = 0;
++ msg.msg_iov = &iov;
++ msg.msg_iovlen = 1;
++ msg.msg_control = NULL;
++ msg.msg_controllen = 0;
++ msg.msg_flags = MSG_NOSIGNAL;
++ if (sock->type == SOCK_SEQPACKET)
++ msg.msg_flags |= MSG_EOR;
++ iov.iov_base = (void *)buffer;
++ iov.iov_len = count;
++
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ RetVal = sock_sendmsg(sock, &msg, count);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++ else
++ {
++ struct file *F = fd2file(fd);
++ mm_segment_t oldfs;
++ int RetVal;
++
++ oldfs = get_fs();
++ set_fs(KERNEL_DS);
++ RetVal = F->f_op->write(F, buffer, count, &F->f_pos);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++}
++
++static inline int writev(int fd, const struct iovec *vector, int count) {
++#ifndef DONT_USE_SIMPLE_WRITEV
++ int i, amount = 0;
++#if KORBIT_DEBUG_WRITING
++ printk("writev (fd = 0x%X, vec=0x%p, count = %d)\n", fd, vector, count);
++#endif
++ for (i = 0; i < count; i++) {
++ char *Buf = vector[i].iov_base;
++ int Amount = vector[i].iov_len;
++ while (Amount > 0) {
++ int A = write(fd, Buf, Amount);
++//#if KORBIT_DEBUG_WRITING
++if (A < Amount)
++ printk(" write(fd = 0x%X, buf = 0x%p, size = 0x%X) "
++ "= 0x%X errno = 0x%X\n", fd, Buf, Amount, A, errno);
++//#endif
++ Amount -= A;
++ amount += A;
++ Buf += A;
++ if (Amount > 0) schedule(); // Behave somewhat nicely...
++ }
++ }
++
++#if KORBIT_DEBUG_WRITING
++ printk("writev returning 0x%X[%d]\n", amount, amount);
++#endif
++ return amount;
++
++#else
++ if ((fd & 1) == 1)
++ {
++ struct socket *sock = fd2sock(fd);
++ struct msghdr msg;
++ mm_segment_t oldfs;
++ int i, RetVal;
++ size_t tot_len = 0;
++
++ for (i = 0; i < count; i++)
++ tot_len += vector[i].iov_len;
++
++ msg.msg_name = NULL;
++ msg.msg_namelen = 0;
++ msg.msg_iov = (struct iovec *)vector;
++ msg.msg_iovlen = count;
++ msg.msg_control = NULL;
++ msg.msg_controllen = 0;
++ if (sock->type == SOCK_SEQPACKET)
++ msg.msg_flags |= MSG_EOR;
++
++ oldfs = get_fs(); set_fs(KERNEL_DS);
++ RetVal = sock_sendmsg(sock, &msg, tot_len);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++ else
++ {
++ struct file *F = fd2file(fd);
++ mm_segment_t oldfs;
++ int RetVal;
++
++ oldfs = get_fs();
++ set_fs(KERNEL_DS);
++ RetVal = F->f_op->writev(F, vector, (unsigned)count, &F->f_pos);
++ set_fs(oldfs);
++ if (RetVal < 0)
++ {
++ errno = -RetVal;
++ RetVal = -1;
++ }
++ return RetVal;
++ }
++#endif
++}
++
++static inline int close(int fd) {
++ int err = 0;
++ if ((fd & 1) == 1) {
++ struct socket *sock = fd2sock(fd);
++ sock_release(sock);
++ } else {
++ struct file *file = fd2file(fd);
++ fput(file);
++ }
++ return err;
++}
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/stdlib.h linux-2.4.1-korbit/net/korbit/include/stdlib.h
+--- linux-2.4.1/net/korbit/include/stdlib.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/stdlib.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,99 @@
++#ifndef __KORBIT_STDLIB_H__
++#define __KORBIT_STDLIB_H__
++
++#include <linux/kernel.h>
++#include <linux/malloc.h>
++#include <linux/types.h>
++#include <asm/string.h>
++
++#define strtol(nptr,endptr,base) simple_strtol(nptr,endptr,base)
++
++#if 0
++#define malloc(size) kmalloc(size, GFP_KERNEL)
++#define free(ptr) kfree(ptr)
++#endif
++
++static inline void *malloc(size_t size)
++{
++ void *ptr = NULL;
++
++ if (size == 0)
++ size = 4;
++
++ ptr = kmalloc(size + sizeof(size), GFP_KERNEL);
++
++ if (ptr)
++ {
++ *((size_t *)ptr) = size;
++ ptr = (size_t *)ptr + 1;
++ }
++
++ return ptr;
++}
++
++static inline void free(void *ptr)
++{
++ if (ptr)
++ kfree((size_t *)ptr - 1);
++}
++
++#define alloca(size) malloc(size)
++
++/* freeca(ptr) - free a mem allocation if ptr points to one, otherwise do
++ * nothing.
++ */
++static inline void freeca(void *ptr)
++{
++ if (ptr != NULL) { /* Don't free it if it's already free */
++ free(ptr);
++ }
++}
++
++static inline void *calloc(size_t nmemb, size_t size)
++{
++ void *ptr = malloc(nmemb*size);
++ if (ptr)
++ memset(ptr,0,nmemb*size);
++ return ptr;
++}
++
++static inline void *realloc(void *ptr, size_t size)
++{
++ void *newptr = NULL;
++
++ if (size != 0)
++ newptr = malloc(size);
++
++ if (ptr && newptr) /* Copy old contents */
++ {
++ size_t *p1 = (size_t *)ptr - 1;
++ size_t *p2 = (size_t *)newptr - 1;
++ size_t n = *p1 < *p2 ? *p1 : *p2;
++ memcpy(newptr, ptr, n);
++ }
++
++ if (ptr)
++ free(ptr);
++
++ return newptr;
++}
++
++/* Returned by `div'. */
++typedef struct
++{
++ int quot; /* Quotient. */
++ int rem; /* Remainder. */
++} div_t;
++
++static inline div_t div(int number, int denom)
++{
++ div_t result;
++ result.quot = number/denom;
++ result.rem = number-(number*result.quot);
++ return result;
++}
++
++#define atexit(fn) -1
++#define getenv(name) 0
++
++#endif /* __KORBIT_STDLIB_H__ */
+diff -urN linux-2.4.1/net/korbit/include/string.h linux-2.4.1-korbit/net/korbit/include/string.h
+--- linux-2.4.1/net/korbit/include/string.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/string.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,11 @@
++#ifndef __KORBIT_STRING_H__
++#define __KORBIT_STRING_H__
++
++#include <linux/types.h>
++#include <asm/string.h>
++
++#include <glib.h>
++
++#define strerror(errno) g_strerror(errno)
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/CVS/Entries linux-2.4.1-korbit/net/korbit/include/sys/CVS/Entries
+--- linux-2.4.1/net/korbit/include/sys/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/CVS/Entries Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,10 @@
++/ioctl.h/1.1.1.1/Thu Feb 1 09:46:55 2001//
++/poll.h/1.25/Thu Feb 1 09:46:55 2001//
++/socket.h/1.20/Thu Feb 1 09:46:55 2001//
++/stat.h/1.1.1.1/Thu Feb 1 09:46:55 2001//
++/time.h/1.1.1.1/Thu Feb 1 09:46:55 2001//
++/types.h/1.1.1.1/Thu Feb 1 09:46:56 2001//
++/uio.h/1.1.1.1/Thu Feb 1 09:46:56 2001//
++/un.h/1.1.1.1/Thu Feb 1 09:46:56 2001//
++/wait.h/1.1.1.1/Thu Feb 1 09:46:56 2001//
++D
+diff -urN linux-2.4.1/net/korbit/include/sys/CVS/Repository linux-2.4.1-korbit/net/korbit/include/sys/CVS/Repository
+--- linux-2.4.1/net/korbit/include/sys/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/CVS/Repository Thu Feb 1 11:46:55 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/include/sys
+diff -urN linux-2.4.1/net/korbit/include/sys/CVS/Root linux-2.4.1-korbit/net/korbit/include/sys/CVS/Root
+--- linux-2.4.1/net/korbit/include/sys/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/CVS/Root Thu Feb 1 11:46:55 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/include/sys/ioctl.h linux-2.4.1-korbit/net/korbit/include/sys/ioctl.h
+--- linux-2.4.1/net/korbit/include/sys/ioctl.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/ioctl.h Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_SYS_IOCTL_H__
++#define __KORBIT_SYS_IOCTL_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/poll.h linux-2.4.1-korbit/net/korbit/include/sys/poll.h
+--- linux-2.4.1/net/korbit/include/sys/poll.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/poll.h Fri Feb 2 01:22:10 2001
+@@ -0,0 +1,112 @@
++#ifndef __KORBIT_SYS_POLL_H__
++#define __KORBIT_SYS_POLL_H__
++
++#include <asm/poll.h>
++#include <asm/param.h>
++#include <linux/net.h>
++#include <linux/tcp.h>
++#include <linux/socket.h>
++#include <net/tcp.h>
++#include <net/sock.h>
++#include <linux/skbuff.h>
++#include <linux/sched.h>
++#include "stdlib.h"
++#include "sys/socket.h"
++
++/* Poll the file descriptors described by the NFDS structures starting at
++ * FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for
++ * an event to occur; if TIMEOUT is -1, block until an event occurs.
++ * Returns the number of file descriptors with events, zero if timed
++ * out, or -1 for errors.
++ */
++
++/* This implementation of poll assumes that we are sitting on the wait
++ * queues for all of the file descriptors already. Therefore if we are about
++ * to block, all we have to do is perform the schedule call which will
++ * automatically cause us to "block".
++ */
++static int poll_CheckFDs(struct pollfd *fds, unsigned long int nfds)
++{
++ int NumReady = 0, i;
++
++ // Loop over the file descriptors seeing if there is already work to be
++ // done...
++ for (i = 0; i < nfds; i++) {
++ struct socket *sock = fd2sock(fds[i].fd);
++ fds[i].revents = 0;
++
++ // Check to see if stuff is available to read
++ if (sock) {
++ // It's a socket baby
++ fds[i].revents = tcp_poll(0, sock, 0);
++
++ // Apparently tcp_poll doesn't look at the CLOSE_WAIT value,
++ // and we have a lot of sockets that end up in this state.
++ // This is a hack to shortcircuit some read failures from
++ // later. This breaks "poll semantics" strictly speaking, but
++ // it's basically the "right thing to do" (tm).
++ if (sock->sk->state == TCP_CLOSE_WAIT)
++ fds[i].revents = POLLHUP;
++ fds[i].revents &= fds[i].events | POLLERR | POLLHUP;
++ } else {
++ // It's a file
++ //struct file *f = fd2file(fd);
++// printk("POLL NOT IMPLEMENTED FOR FILES YET\n");
++ BUG();
++ }
++
++ if (fds[i].revents) {
++ NumReady++;
++// printk("FD #%d: Event = 0x%X\n", i, fds[i].revents);
++ }
++
++ } /* for */
++
++ return NumReady;
++} /* End poll_CheckFDs(). */
++
++
++static int poll(struct pollfd *fds, unsigned long int nfds, int timeout) {
++ wait_queue_t *WaitQueues = 0;
++ int NumReady = poll_CheckFDs(fds, nfds);
++ int i;
++
++ if (NumReady || timeout == 0)
++ return NumReady;
++
++// printk("Starting to Poll... %d fds...\n", nfds);
++ WaitQueues = (wait_queue_t*)malloc(nfds*sizeof(wait_queue_t));
++ if (WaitQueues == 0) return 0; // Crap, nomem...
++
++ for (i = 0; i < nfds; i++) {
++ struct socket *sock = fd2sock(fds[i].fd);
++ init_waitqueue_entry(WaitQueues+i, current);
++
++ if (sock)
++ add_wait_queue_exclusive(sock->sk->sleep, WaitQueues+i);
++// else
++// printk("I don't know how to wait on fd #%d = 0x%X\n", i, fds[i].fd);
++ }
++
++ // Wait for us to get notified by one of the socket wait queue notifiers!
++ do {
++ // Change our task state so that we are not immediately rescheduled.
++ // This lets the scheduler know that we are waiting for something to happen
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule();
++ } while (!(NumReady = poll_CheckFDs(fds, nfds)));
++
++ set_current_state(TASK_RUNNING);
++
++ for (i = 0; i < nfds; i++) {
++ struct socket *sock = fd2sock(fds[i].fd);
++ if (sock)
++ remove_wait_queue(sock->sk->sleep, WaitQueues+i);
++ }
++
++ free(WaitQueues);
++// printk("Returning %d\n", NumReady);
++ return NumReady;
++}
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/socket.h linux-2.4.1-korbit/net/korbit/include/sys/socket.h
+--- linux-2.4.1/net/korbit/include/sys/socket.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/socket.h Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,126 @@
++#ifndef __KORBIT_SYS_SOCKET_H__
++#define __KORBIT_SYS_SOCKET_H__
++typedef unsigned int socklen_t;
++
++#include <linux/socket.h>
++#include <linux/wait.h>
++#include <asm/semaphore.h>
++#include <net/sock.h>
++
++/* These functions are declared in net/socket.c */
++asmlinkage long sys_socket(int family, int type, int protocol);
++struct socket *sockfd_lookup(int fd, int *err);
++
++
++static inline int sock2fd(struct socket *s)
++{
++ return (-(int)s) | 1;
++}
++
++static inline struct socket *fd2sock(int sockfd)
++{
++ if ((sockfd & 1) == 0) /* can't convert a file! */
++ return NULL;
++
++ return (struct socket *)(-(sockfd & ~1));
++}
++
++
++static inline int socket(int domain, int type, int protocol) {
++ struct socket *sock;
++ int retval = sock_create(domain, type, protocol, &sock);
++
++ if (retval < 0) return (int)NULL;
++ return sock2fd(sock);
++}
++
++
++static inline int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
++{
++ struct socket *sock = fd2sock(sockfd);
++
++ if (sock == NULL)
++ return -1;
++ if (!sock->ops->bind(sock, my_addr, addrlen))
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++}
++
++
++static inline int connect(int sockfd, const struct sockaddr *serv_addr,
++ socklen_t addrlen)
++{
++ struct socket *sock = fd2sock(sockfd);
++ int flags = 0; /* TODO : what is flags supposed to be? */
++
++ if (sock == NULL)
++ return -1;
++
++ if (sock->ops->connect(sock, (struct sockaddr *)serv_addr, addrlen, flags) == 0)
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++}
++
++
++static inline int listen(int sockfd, int backlog)
++{
++ struct socket *sock = fd2sock(sockfd);
++
++ if (sock == NULL)
++ return -1;
++
++ if (sock->ops->listen(sock, backlog) == 0)
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++}
++
++
++static inline int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
++{
++ struct socket *sock = fd2sock(sockfd);
++ struct socket *newsock;
++ struct sockaddr_in *newaddr = (struct sockaddr_in *)addr; /* check? */
++ int flags = 0; /* Should be ok */
++
++ if (sock == 0)
++ return -1;
++
++ newsock = sock_alloc();
++ if (newsock == 0)
++ return -1;
++
++ newsock->type = sock->type;
++ newsock->ops = sock->ops;
++ if (sock->ops->accept(sock, newsock, flags) < 0)
++ {
++ sock_release(newsock);
++ return -1; /* should normally also set errno */
++ }
++
++ newaddr->sin_family = AF_INET;
++ newaddr->sin_port = newsock->sk->dport;
++ newaddr->sin_addr.s_addr = newsock->sk->daddr;
++
++ *addrlen = sizeof(newaddr);
++
++ return sock2fd(newsock);
++}
++
++
++static inline int shutdown(int sockfd, int how)
++{
++ struct socket *sock = fd2sock(sockfd);
++
++ if (sock == NULL)
++ return -1;
++
++ if (sock->ops->shutdown(sock, how) == 0)
++ return 0;
++ else
++ return -1; /* should normally also set errno */
++}
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/stat.h linux-2.4.1-korbit/net/korbit/include/sys/stat.h
+--- linux-2.4.1/net/korbit/include/sys/stat.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/stat.h Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_SYS_STAT_H__
++#define __KORBIT_SYS_STAT_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/time.h linux-2.4.1-korbit/net/korbit/include/sys/time.h
+--- linux-2.4.1/net/korbit/include/sys/time.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/time.h Thu Feb 1 11:46:55 2001
+@@ -0,0 +1,6 @@
++#ifndef __KORBIT_TIME_H__
++#define __KORBIT_TIME_H__
++
++#include <linux/time.h>
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/types.h linux-2.4.1-korbit/net/korbit/include/sys/types.h
+--- linux-2.4.1/net/korbit/include/sys/types.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/types.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,4 @@
++#ifndef __KORBIT_SYS_TYPES_H__
++#define __KORBIT_SYS_TYPES_H__
++#include <linux/types.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/uio.h linux-2.4.1-korbit/net/korbit/include/sys/uio.h
+--- linux-2.4.1/net/korbit/include/sys/uio.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/uio.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,4 @@
++#ifndef __KORBIT_SYS_UIO_H__
++#define __KORBIT_SYS_UIO_H__
++#include <linux/uio.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/un.h linux-2.4.1-korbit/net/korbit/include/sys/un.h
+--- linux-2.4.1/net/korbit/include/sys/un.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/un.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,5 @@
++#ifndef __KORBIT_SYS_UN_H__
++#define __KORBIT_SYS_UN_H__
++#include <linux/socket.h>
++#include <linux/un.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/include/sys/wait.h linux-2.4.1-korbit/net/korbit/include/sys/wait.h
+--- linux-2.4.1/net/korbit/include/sys/wait.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/sys/wait.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,3 @@
++#ifndef __KORBIT_SYS_WAIT_H__
++#define __KORBIT_SYS_WAIT_H__
++#endif
+diff -urN linux-2.4.1/net/korbit/include/syslog.h linux-2.4.1-korbit/net/korbit/include/syslog.h
+--- linux-2.4.1/net/korbit/include/syslog.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/syslog.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,7 @@
++#ifndef __KORBIT_SYSLOG_H__
++#define __KORBIT_SYSLOG_H__
++
++#define LOG_NOTICE 5 /* normal but significant condition */
++#define LOG_INFO 6 /* informational */
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/time.h linux-2.4.1-korbit/net/korbit/include/time.h
+--- linux-2.4.1/net/korbit/include/time.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/time.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,4 @@
++#ifndef __KORBIT_TIME_H__
++#define __KORBIT_TIME_H__
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/unistd.h linux-2.4.1-korbit/net/korbit/include/unistd.h
+--- linux-2.4.1/net/korbit/include/unistd.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/unistd.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,19 @@
++#ifndef __KORBIT_UNISTD_H__
++#define __KORBIT_UNISTD_H__
++
++#include <linux/types.h>
++#include <linux/utsname.h>
++#include <asm/string.h>
++#include <asm/semaphore.h>
++/* extern char *getcwd(char * buf, size_t size); */
++
++static inline int gethostname(char *name, size_t len) {
++ down_read(&uts_sem);
++ strncpy(name, system_utsname.nodename, len);
++ up_read(&uts_sem);
++printk("gethostname() = %s\n", name);
++ return 0;
++}
++
++
++#endif
+diff -urN linux-2.4.1/net/korbit/include/utime.h linux-2.4.1-korbit/net/korbit/include/utime.h
+--- linux-2.4.1/net/korbit/include/utime.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/include/utime.h Thu Feb 1 11:46:54 2001
+@@ -0,0 +1,4 @@
++#ifndef __KORBIT_UTIME_H__
++#define __KORBIT_UTIME_H__
++#include <linux/utime.h>
++#endif
+diff -urN linux-2.4.1/net/korbit/kglib/CVS/Entries linux-2.4.1-korbit/net/korbit/kglib/CVS/Entries
+--- linux-2.4.1/net/korbit/kglib/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/CVS/Entries Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,15 @@
++/Makefile/1.4/Thu Feb 1 09:46:56 2001//
++/garray.c/1.3/Thu Feb 1 09:46:56 2001//
++/ghash.c/1.2/Thu Feb 1 09:46:56 2001//
++/glib.h/1.3/Thu Feb 1 09:46:56 2001//
++/glibconfig.h/1.2/Thu Feb 1 09:46:56 2001//
++/glist.c/1.1.1.1/Thu Feb 1 09:46:57 2001//
++/gmem.c/1.2/Thu Feb 1 09:46:57 2001//
++/gprimes.c/1.1.1.1/Thu Feb 1 09:46:57 2001//
++/gslist.c/1.1.1.1/Thu Feb 1 09:46:57 2001//
++/gstrfuncs.c/1.2/Thu Feb 1 09:46:57 2001//
++/gstring.c/1.1.1.1/Thu Feb 1 09:46:57 2001//
++/gtree.c/1.1.1.1/Thu Feb 1 09:46:57 2001//
++/gutils.c/1.2/Thu Feb 1 09:46:57 2001//
++/korbit_errno.c/1.1/Thu Feb 1 09:46:57 2001//
++D
+diff -urN linux-2.4.1/net/korbit/kglib/CVS/Repository linux-2.4.1-korbit/net/korbit/kglib/CVS/Repository
+--- linux-2.4.1/net/korbit/kglib/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/CVS/Repository Thu Feb 1 11:46:56 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/kglib
+diff -urN linux-2.4.1/net/korbit/kglib/CVS/Root linux-2.4.1-korbit/net/korbit/kglib/CVS/Root
+--- linux-2.4.1/net/korbit/kglib/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/CVS/Root Thu Feb 1 11:46:56 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/kglib/Makefile linux-2.4.1-korbit/net/korbit/kglib/Makefile
+--- linux-2.4.1/net/korbit/kglib/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/Makefile Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,18 @@
++#
++# Makefile for KORBit/kglib
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := kglib.o
++
++#obj-m := $(O_TARGET)
++obj-y := garray.o glist.o gprimes.o gstrfuncs.o gtree.o \
++ ghash.o gmem.o gslist.o gstring.o gutils.o korbit_errno.o
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -DHAVE_UNISTD_H -I. -I.. -I../include -nostdinc
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/kglib/garray.c linux-2.4.1-korbit/net/korbit/kglib/garray.c
+--- linux-2.4.1/net/korbit/kglib/garray.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/garray.c Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,431 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include <string.h>
++#include "glib.h"
++
++
++#define MIN_ARRAY_SIZE 16
++
++
++typedef struct _GRealArray GRealArray;
++
++struct _GRealArray
++{
++ guint8 *data;
++ guint len;
++ guint alloc;
++ guint elt_size;
++ guint zero_terminated : 1;
++ guint clear : 1;
++};
++
++
++static gint g_nearest_pow (gint num);
++static void g_array_maybe_expand (GRealArray *array,
++ gint len);
++
++static GMemChunk *array_mem_chunk = NULL;
++G_LOCK_DEFINE_STATIC (array_mem_chunk);
++
++GArray*
++g_array_new (gboolean zero_terminated,
++ gboolean clear,
++ guint elt_size)
++{
++ GRealArray *array;
++
++ G_LOCK (array_mem_chunk);
++ if (!array_mem_chunk)
++ array_mem_chunk = g_mem_chunk_new ("array mem chunk",
++ sizeof (GRealArray),
++ 1024, G_ALLOC_AND_FREE);
++
++ array = g_chunk_new (GRealArray, array_mem_chunk);
++ G_UNLOCK (array_mem_chunk);
++
++ array->data = NULL;
++ array->len = 0;
++ array->alloc = 0;
++ array->zero_terminated = (zero_terminated ? 1 : 0);
++ array->clear = (clear ? 1 : 0);
++ array->elt_size = elt_size;
++
++ return (GArray*) array;
++}
++
++void
++g_array_free (GArray *array,
++ gboolean free_segment)
++{
++ if (free_segment)
++ g_free (array->data);
++
++ G_LOCK (array_mem_chunk);
++ g_mem_chunk_free (array_mem_chunk, array);
++ G_UNLOCK (array_mem_chunk);
++}
++
++GArray*
++g_array_append_vals (GArray *farray,
++ gconstpointer data,
++ guint len)
++{
++ GRealArray *array = (GRealArray*) farray;
++
++ g_array_maybe_expand (array, len);
++
++ memcpy (array->data + array->elt_size * array->len, data, array->elt_size * len);
++
++ array->len += len;
++
++ return farray;
++}
++
++GArray*
++g_array_prepend_vals (GArray *farray,
++ gconstpointer data,
++ guint len)
++{
++ GRealArray *array = (GRealArray*) farray;
++
++ g_array_maybe_expand (array, len);
++
++ g_memmove (array->data + array->elt_size * len, array->data, array->elt_size * array->len);
++
++ memcpy (array->data, data, len * array->elt_size);
++
++ array->len += len;
++
++ return farray;
++}
++
++GArray*
++g_array_insert_vals (GArray *farray,
++ guint index,
++ gconstpointer data,
++ guint len)
++{
++ GRealArray *array = (GRealArray*) farray;
++
++ g_array_maybe_expand (array, len);
++
++ g_memmove (array->data + array->elt_size * (len + index),
++ array->data + array->elt_size * index,
++ array->elt_size * (array->len - index));
++
++ memcpy (array->data + array->elt_size * index, data, len * array->elt_size);
++
++ array->len += len;
++
++ return farray;
++}
++
++GArray*
++g_array_set_size (GArray *farray,
++ guint length)
++{
++ GRealArray *array = (GRealArray*) farray;
++
++ if (array->len < length)
++ g_array_maybe_expand (array, length - array->len);
++
++ array->len = length;
++
++ return farray;
++}
++
++GArray*
++g_array_remove_index (GArray* farray,
++ guint index)
++{
++ GRealArray* array = (GRealArray*) farray;
++
++ g_return_val_if_fail (array, NULL);
++
++ g_return_val_if_fail (index < array->len, NULL);
++
++ if (index != array->len - 1)
++ g_memmove (array->data + array->elt_size * index,
++ array->data + array->elt_size * (index + 1),
++ array->elt_size * (array->len - index - 1));
++
++ if (array->zero_terminated)
++ memset (array->data + array->elt_size * (array->len - 1), 0,
++ array->elt_size);
++
++ array->len -= 1;
++
++ return farray;
++}
++
++GArray*
++g_array_remove_index_fast (GArray* farray,
++ guint index)
++{
++ GRealArray* array = (GRealArray*) farray;
++
++ g_return_val_if_fail (array, NULL);
++
++ g_return_val_if_fail (index < array->len, NULL);
++
++ if (index != array->len - 1)
++ g_memmove (array->data + array->elt_size * index,
++ array->data + array->elt_size * (array->len - 1),
++ array->elt_size);
++
++ if (array->zero_terminated)
++ memset (array->data + array->elt_size * (array->len - 1), 0,
++ array->elt_size);
++
++ array->len -= 1;
++
++ return farray;
++}
++
++static gint
++g_nearest_pow (gint num)
++{
++ gint n = 1;
++
++ while (n < num)
++ n <<= 1;
++
++ return n;
++}
++
++static void
++g_array_maybe_expand (GRealArray *array,
++ gint len)
++{
++ guint want_alloc = (array->len + len + array->zero_terminated) * array->elt_size;
++
++ if (want_alloc > array->alloc)
++ {
++ guint old_alloc = array->alloc;
++
++ array->alloc = g_nearest_pow (want_alloc);
++ array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
++
++ array->data = g_realloc (array->data, array->alloc);
++
++ if (array->clear || array->zero_terminated)
++ memset (array->data + old_alloc, 0, array->alloc - old_alloc);
++ }
++}
++
++/* Pointer Array
++ */
++
++typedef struct _GRealPtrArray GRealPtrArray;
++
++struct _GRealPtrArray
++{
++ gpointer *pdata;
++ guint len;
++ guint alloc;
++};
++
++static void g_ptr_array_maybe_expand (GRealPtrArray *array,
++ gint len);
++
++static GMemChunk *ptr_array_mem_chunk = NULL;
++G_LOCK_DEFINE_STATIC (ptr_array_mem_chunk);
++
++
++GPtrArray*
++g_ptr_array_new (void)
++{
++ GRealPtrArray *array;
++
++ G_LOCK (ptr_array_mem_chunk);
++ if (!ptr_array_mem_chunk)
++ ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
++ sizeof (GRealPtrArray),
++ 1024, G_ALLOC_AND_FREE);
++
++ array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
++ G_UNLOCK (ptr_array_mem_chunk);
++
++ array->pdata = NULL;
++ array->len = 0;
++ array->alloc = 0;
++
++ return (GPtrArray*) array;
++}
++
++void
++g_ptr_array_free (GPtrArray *array,
++ gboolean free_segment)
++{
++ g_return_if_fail (array);
++
++ if (free_segment)
++ g_free (array->pdata);
++
++ G_LOCK (ptr_array_mem_chunk);
++ g_mem_chunk_free (ptr_array_mem_chunk, array);
++ G_UNLOCK (ptr_array_mem_chunk);
++}
++
++static void
++g_ptr_array_maybe_expand (GRealPtrArray *array,
++ gint len)
++{
++ guint old_alloc;
++
++ if ((array->len + len) > array->alloc)
++ {
++ old_alloc = array->alloc;
++
++ array->alloc = g_nearest_pow (array->len + len);
++ array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
++ if (array->pdata)
++ array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
++ else
++ array->pdata = g_new0 (gpointer, array->alloc);
++
++ memset (array->pdata + old_alloc, 0,
++ sizeof (gpointer) * (array->alloc - old_alloc));
++ }
++}
++
++void
++g_ptr_array_set_size (GPtrArray *farray,
++ gint length)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++
++ g_return_if_fail (array);
++
++ if (length > array->len)
++ g_ptr_array_maybe_expand (array, (length - array->len));
++
++ array->len = length;
++}
++
++gpointer
++g_ptr_array_remove_index (GPtrArray* farray,
++ guint index)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++ gpointer result;
++
++ g_return_val_if_fail (array, NULL);
++
++ g_return_val_if_fail (index < array->len, NULL);
++
++ result = array->pdata[index];
++
++ if (index != array->len - 1)
++ g_memmove (array->pdata + index, array->pdata + index + 1,
++ sizeof (gpointer) * (array->len - index - 1));
++
++ array->pdata[array->len - 1] = NULL;
++
++ array->len -= 1;
++
++ return result;
++}
++
++gpointer
++g_ptr_array_remove_index_fast (GPtrArray* farray,
++ guint index)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++ gpointer result;
++
++ g_return_val_if_fail (array, NULL);
++
++ g_return_val_if_fail (index < array->len, NULL);
++
++ result = array->pdata[index];
++
++ if (index != array->len - 1)
++ array->pdata[index] = array->pdata[array->len - 1];
++
++ array->pdata[array->len - 1] = NULL;
++
++ array->len -= 1;
++
++ return result;
++}
++
++gboolean
++g_ptr_array_remove (GPtrArray* farray,
++ gpointer data)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++ int i;
++
++ g_return_val_if_fail (array, FALSE);
++
++ for (i = 0; i < array->len; i += 1)
++ {
++ if (array->pdata[i] == data)
++ {
++ g_ptr_array_remove_index (farray, i);
++ return TRUE;
++ }
++ }
++
++ return FALSE;
++}
++
++gboolean
++g_ptr_array_remove_fast (GPtrArray* farray,
++ gpointer data)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++ int i;
++
++ g_return_val_if_fail (array, FALSE);
++
++ for (i = 0; i < array->len; i += 1)
++ {
++ if (array->pdata[i] == data)
++ {
++ g_ptr_array_remove_index_fast (farray, i);
++ return TRUE;
++ }
++ }
++
++ return FALSE;
++}
++
++void
++g_ptr_array_add (GPtrArray* farray,
++ gpointer data)
++{
++ GRealPtrArray* array = (GRealPtrArray*) farray;
++
++ g_return_if_fail (array);
++
++ g_ptr_array_maybe_expand (array, 1);
++
++ array->pdata[array->len++] = data;
++}
++
+diff -urN linux-2.4.1/net/korbit/kglib/ghash.c linux-2.4.1-korbit/net/korbit/kglib/ghash.c
+--- linux-2.4.1/net/korbit/kglib/ghash.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/ghash.c Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,404 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include "glib.h"
++
++
++#define HASH_TABLE_MIN_SIZE 11
++#define HASH_TABLE_MAX_SIZE 13845163
++
++
++typedef struct _GHashNode GHashNode;
++
++struct _GHashNode
++{
++ gpointer key;
++ gpointer value;
++ GHashNode *next;
++};
++
++struct _GHashTable
++{
++ gint size;
++ gint nnodes;
++ guint frozen;
++ GHashNode **nodes;
++ GHashFunc hash_func;
++ GCompareFunc key_compare_func;
++};
++
++
++static void g_hash_table_resize (GHashTable *hash_table);
++static GHashNode** g_hash_table_lookup_node (GHashTable *hash_table,
++ gconstpointer key);
++static GHashNode* g_hash_node_new (gpointer key,
++ gpointer value);
++static void g_hash_node_destroy (GHashNode *hash_node);
++static void g_hash_nodes_destroy (GHashNode *hash_node);
++
++
++G_LOCK_DEFINE_STATIC (g_hash_global);
++
++static GMemChunk *node_mem_chunk = NULL;
++static GHashNode *node_free_list = NULL;
++
++
++GHashTable*
++g_hash_table_new (GHashFunc hash_func,
++ GCompareFunc key_compare_func)
++{
++ GHashTable *hash_table;
++ guint i;
++
++ hash_table = g_new (GHashTable, 1);
++ hash_table->size = HASH_TABLE_MIN_SIZE;
++ hash_table->nnodes = 0;
++ hash_table->frozen = FALSE;
++ hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
++ hash_table->key_compare_func = key_compare_func;
++ hash_table->nodes = g_new (GHashNode*, hash_table->size);
++
++ for (i = 0; i < hash_table->size; i++)
++ hash_table->nodes[i] = NULL;
++
++ return hash_table;
++}
++
++void
++g_hash_table_destroy (GHashTable *hash_table)
++{
++ guint i;
++
++ g_return_if_fail (hash_table != NULL);
++
++ for (i = 0; i < hash_table->size; i++)
++ g_hash_nodes_destroy (hash_table->nodes[i]);
++
++ g_free (hash_table->nodes);
++ g_free (hash_table);
++}
++
++static inline GHashNode**
++g_hash_table_lookup_node (GHashTable *hash_table,
++ gconstpointer key)
++{
++ GHashNode **node;
++
++ node = &hash_table->nodes
++ [(* hash_table->hash_func) (key) % hash_table->size];
++
++ /* Hash table lookup needs to be fast.
++ * We therefore remove the extra conditional of testing
++ * whether to call the key_compare_func or not from
++ * the inner loop.
++ */
++ if (hash_table->key_compare_func)
++ while (*node && !(*hash_table->key_compare_func) ((*node)->key, key))
++ node = &(*node)->next;
++ else
++ while (*node && (*node)->key != key)
++ node = &(*node)->next;
++
++ return node;
++}
++
++gpointer
++g_hash_table_lookup (GHashTable *hash_table,
++ gconstpointer key)
++{
++ GHashNode *node;
++
++ g_return_val_if_fail (hash_table != NULL, NULL);
++
++ node = *g_hash_table_lookup_node (hash_table, key);
++
++ return node ? node->value : NULL;
++}
++
++void
++g_hash_table_insert (GHashTable *hash_table,
++ gpointer key,
++ gpointer value)
++{
++ GHashNode **node;
++
++ g_return_if_fail (hash_table != NULL);
++
++ node = g_hash_table_lookup_node (hash_table, key);
++
++ if (*node)
++ {
++ /* do not reset node->key in this place, keeping
++ * the old key might be intended.
++ * a g_hash_table_remove/g_hash_table_insert pair
++ * can be used otherwise.
++ *
++ * node->key = key; */
++ (*node)->value = value;
++ }
++ else
++ {
++ *node = g_hash_node_new (key, value);
++ hash_table->nnodes++;
++ if (!hash_table->frozen)
++ g_hash_table_resize (hash_table);
++ }
++}
++
++void
++g_hash_table_remove (GHashTable *hash_table,
++ gconstpointer key)
++{
++ GHashNode **node, *dest;
++
++ g_return_if_fail (hash_table != NULL);
++
++ node = g_hash_table_lookup_node (hash_table, key);
++
++ if (*node)
++ {
++ dest = *node;
++ (*node) = dest->next;
++ g_hash_node_destroy (dest);
++ hash_table->nnodes--;
++
++ if (!hash_table->frozen)
++ g_hash_table_resize (hash_table);
++ }
++}
++
++gboolean
++g_hash_table_lookup_extended (GHashTable *hash_table,
++ gconstpointer lookup_key,
++ gpointer *orig_key,
++ gpointer *value)
++{
++ GHashNode *node;
++
++ g_return_val_if_fail (hash_table != NULL, FALSE);
++
++ node = *g_hash_table_lookup_node (hash_table, lookup_key);
++
++ if (node)
++ {
++ if (orig_key)
++ *orig_key = node->key;
++ if (value)
++ *value = node->value;
++ return TRUE;
++ }
++ else
++ return FALSE;
++}
++
++void
++g_hash_table_freeze (GHashTable *hash_table)
++{
++ g_return_if_fail (hash_table != NULL);
++
++ hash_table->frozen++;
++}
++
++void
++g_hash_table_thaw (GHashTable *hash_table)
++{
++ g_return_if_fail (hash_table != NULL);
++
++ if (hash_table->frozen)
++ if (!(--hash_table->frozen))
++ g_hash_table_resize (hash_table);
++}
++
++guint
++g_hash_table_foreach_remove (GHashTable *hash_table,
++ GHRFunc func,
++ gpointer user_data)
++{
++ GHashNode *node, *prev;
++ guint i;
++ guint deleted = 0;
++
++ g_return_val_if_fail (hash_table != NULL, 0);
++ g_return_val_if_fail (func != NULL, 0);
++
++ for (i = 0; i < hash_table->size; i++)
++ {
++ restart:
++
++ prev = NULL;
++
++ for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
++ {
++ if ((* func) (node->key, node->value, user_data))
++ {
++ deleted += 1;
++
++ hash_table->nnodes -= 1;
++
++ if (prev)
++ {
++ prev->next = node->next;
++ g_hash_node_destroy (node);
++ node = prev;
++ }
++ else
++ {
++ hash_table->nodes[i] = node->next;
++ g_hash_node_destroy (node);
++ goto restart;
++ }
++ }
++ }
++ }
++
++ if (!hash_table->frozen)
++ g_hash_table_resize (hash_table);
++
++ return deleted;
++}
++
++void
++g_hash_table_foreach (GHashTable *hash_table,
++ GHFunc func,
++ gpointer user_data)
++{
++ GHashNode *node;
++ gint i;
++
++ g_return_if_fail (hash_table != NULL);
++ g_return_if_fail (func != NULL);
++
++ for (i = 0; i < hash_table->size; i++)
++ for (node = hash_table->nodes[i]; node; node = node->next)
++ (* func) (node->key, node->value, user_data);
++}
++
++/* Returns the number of elements contained in the hash table. */
++guint
++g_hash_table_size (GHashTable *hash_table)
++{
++ g_return_val_if_fail (hash_table != NULL, 0);
++
++ return hash_table->nnodes;
++}
++
++static void
++g_hash_table_resize (GHashTable *hash_table)
++{
++ GHashNode **new_nodes;
++ GHashNode *node;
++ GHashNode *next;
++#ifdef __KORBIT__
++ guint nodes_per_list;
++#else
++ gfloat nodes_per_list;
++#endif
++ guint hash_val;
++ gint new_size;
++ gint i;
++
++ nodes_per_list = (hash_table->nnodes * 10) / hash_table->size;
++
++ if ((nodes_per_list > 3 || hash_table->size <= HASH_TABLE_MIN_SIZE) &&
++ (nodes_per_list < 30 || hash_table->size >= HASH_TABLE_MAX_SIZE))
++ return;
++
++ new_size = CLAMP(g_spaced_primes_closest (hash_table->nnodes),
++ HASH_TABLE_MIN_SIZE,
++ HASH_TABLE_MAX_SIZE);
++ new_nodes = g_new0 (GHashNode*, new_size);
++
++ for (i = 0; i < hash_table->size; i++)
++ for (node = hash_table->nodes[i]; node; node = next)
++ {
++ next = node->next;
++
++ hash_val = (* hash_table->hash_func) (node->key) % new_size;
++
++ node->next = new_nodes[hash_val];
++ new_nodes[hash_val] = node;
++ }
++
++ g_free (hash_table->nodes);
++ hash_table->nodes = new_nodes;
++ hash_table->size = new_size;
++}
++
++static GHashNode*
++g_hash_node_new (gpointer key,
++ gpointer value)
++{
++ GHashNode *hash_node;
++
++ G_LOCK (g_hash_global);
++ if (node_free_list)
++ {
++ hash_node = node_free_list;
++ node_free_list = node_free_list->next;
++ }
++ else
++ {
++ if (!node_mem_chunk)
++ node_mem_chunk = g_mem_chunk_new ("hash node mem chunk",
++ sizeof (GHashNode),
++ 1024, G_ALLOC_ONLY);
++
++ hash_node = g_chunk_new (GHashNode, node_mem_chunk);
++ }
++ G_UNLOCK (g_hash_global);
++
++ hash_node->key = key;
++ hash_node->value = value;
++ hash_node->next = NULL;
++
++ return hash_node;
++}
++
++static void
++g_hash_node_destroy (GHashNode *hash_node)
++{
++ G_LOCK (g_hash_global);
++ hash_node->next = node_free_list;
++ node_free_list = hash_node;
++ G_UNLOCK (g_hash_global);
++}
++
++static void
++g_hash_nodes_destroy (GHashNode *hash_node)
++{
++ if (hash_node)
++ {
++ GHashNode *node = hash_node;
++
++ while (node->next)
++ node = node->next;
++
++ G_LOCK (g_hash_global);
++ node->next = node_free_list;
++ node_free_list = hash_node;
++ G_UNLOCK (g_hash_global);
++ }
++}
+diff -urN linux-2.4.1/net/korbit/kglib/glib.h linux-2.4.1-korbit/net/korbit/kglib/glib.h
+--- linux-2.4.1/net/korbit/kglib/glib.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/glib.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,1671 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#ifndef __G_LIB_H__
++#define __G_LIB_H__
++
++#ifdef __KORBIT__
++#define G_DISABLE_ASSERT 1
++#include <stdio.h>
++#endif
++
++#include "config.h"
++
++/* system specific config file glibconfig.h provides definitions for
++ * the extrema of many of the standard types. These are:
++ *
++ * G_MINSHORT, G_MAXSHORT
++ * G_MININT, G_MAXINT
++ * G_MINLONG, G_MAXLONG
++ * G_MINFLOAT, G_MAXFLOAT
++ * G_MINDOUBLE, G_MAXDOUBLE
++ *
++ * It also provides the following typedefs:
++ *
++ * gint8, guint8
++ * gint16, guint16
++ * gint32, guint32
++ * gint64, guint64
++ *
++ * It defines the G_BYTE_ORDER symbol to one of G_*_ENDIAN (see later in
++ * this file).
++ *
++ * And it provides a way to store and retrieve a `gint' in/from a `gpointer'.
++ * This is useful to pass an integer instead of a pointer to a callback.
++ *
++ * GINT_TO_POINTER(i), GUINT_TO_POINTER(i)
++ * GPOINTER_TO_INT(p), GPOINTER_TO_UINT(p)
++ *
++ * Finally, it provide the following wrappers to STDC functions:
++ *
++ * g_ATEXIT
++ * To register hooks which are executed on exit().
++ * Usually a wrapper for STDC atexit.
++ *
++ * void *g_memmove(void *dest, const void *src, guint count);
++ * A wrapper for STDC memmove, or an implementation, if memmove doesn't
++ * exist. The prototype looks like the above, give or take a const,
++ * or size_t.
++ */
++#include <glibconfig.h>
++
++/* include varargs functions for assertment macros
++ */
++#include <stdarg.h>
++
++#define G_DIR_SEPARATOR '/'
++#define G_DIR_SEPARATOR_S "/"
++#define G_SEARCHPATH_SEPARATOR ':'
++#define G_SEARCHPATH_SEPARATOR_S ":"
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++
++/* Provide definitions for some commonly used macros.
++ * Some of them are only provided if they haven't already
++ * been defined. It is assumed that if they are already
++ * defined then the current definition is correct.
++ */
++#ifndef NULL
++#define NULL ((void*) 0)
++#endif
++
++#ifndef FALSE
++#define FALSE (0)
++#endif
++
++#ifndef TRUE
++#define TRUE (!FALSE)
++#endif
++
++#undef MAX
++#define MAX(a, b) (((a) > (b)) ? (a) : (b))
++
++#undef MIN
++#define MIN(a, b) (((a) < (b)) ? (a) : (b))
++
++#undef ABS
++#define ABS(a) (((a) < 0) ? -(a) : (a))
++
++#undef CLAMP
++#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
++
++
++/* Define G_VA_COPY() to do the right thing for copying va_list variables.
++ * glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy.
++ */
++#if !defined (G_VA_COPY)
++# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
++# define G_VA_COPY(ap1, ap2) (*(ap1) = *(ap2))
++# elif defined (G_VA_COPY_AS_ARRAY)
++# define G_VA_COPY(ap1, ap2) g_memmove ((ap1), (ap2), sizeof (va_list))
++# else /* va_list is a pointer */
++# define G_VA_COPY(ap1, ap2) ((ap1) = (ap2))
++# endif /* va_list is a pointer */
++#endif /* !G_VA_COPY */
++
++
++/* Provide convenience macros for handling structure
++ * fields through their offsets.
++ */
++#define G_STRUCT_OFFSET(struct_type, member) \
++ ((gulong) ((gchar*) &((struct_type*) 0)->member))
++#define G_STRUCT_MEMBER_P(struct_p, struct_offset) \
++ ((gpointer) ((gchar*) (struct_p) + (gulong) (struct_offset)))
++#define G_STRUCT_MEMBER(member_type, struct_p, struct_offset) \
++ (*(member_type*) G_STRUCT_MEMBER_P ((struct_p), (struct_offset)))
++
++
++/* inlining hassle. for compilers that don't allow the `inline' keyword,
++ * mostly because of strict ANSI C compliance or dumbness, we try to fall
++ * back to either `__inline__' or `__inline'.
++ * we define G_CAN_INLINE, if the compiler seems to be actually
++ * *capable* to do function inlining, in which case inline function bodys
++ * do make sense. we also define G_INLINE_FUNC to properly export the
++ * function prototypes if no inlining can be performed.
++ * we special case most of the stuff, so inline functions can have a normal
++ * implementation by defining G_INLINE_FUNC to extern and G_CAN_INLINE to 1.
++ */
++#ifndef G_INLINE_FUNC
++# define G_CAN_INLINE 1
++#endif
++#ifdef G_HAVE_INLINE
++# if defined (__GNUC__) && defined (__STRICT_ANSI__)
++# undef inline
++# define inline __inline__
++# endif
++#else /* !G_HAVE_INLINE */
++# undef inline
++# if defined (G_HAVE___INLINE__)
++# define inline __inline__
++# else /* !inline && !__inline__ */
++# if defined (G_HAVE___INLINE)
++# define inline __inline
++# else /* !inline && !__inline__ && !__inline */
++# define inline /* don't inline, then */
++# ifndef G_INLINE_FUNC
++# undef G_CAN_INLINE
++# endif
++# endif
++# endif
++#endif
++#ifndef G_INLINE_FUNC
++# ifdef __GNUC__
++# ifdef __OPTIMIZE__
++# define G_INLINE_FUNC extern inline
++# else
++# undef G_CAN_INLINE
++# define G_INLINE_FUNC extern
++# endif
++# else /* !__GNUC__ */
++# ifdef G_CAN_INLINE
++# define G_INLINE_FUNC static inline
++# else
++# define G_INLINE_FUNC extern
++# endif
++# endif /* !__GNUC__ */
++#endif /* !G_INLINE_FUNC */
++
++
++/* Provide simple macro statement wrappers (adapted from Perl):
++ * G_STMT_START { statements; } G_STMT_END;
++ * can be used as a single statement, as in
++ * if (x) G_STMT_START { ... } G_STMT_END; else ...
++ *
++ * For gcc we will wrap the statements within `({' and `})' braces.
++ * For SunOS they will be wrapped within `if (1)' and `else (void) 0',
++ * and otherwise within `do' and `while (0)'.
++ */
++#if !(defined (G_STMT_START) && defined (G_STMT_END))
++# if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
++# define G_STMT_START (void)(
++# define G_STMT_END )
++# else
++# if (defined (sun) || defined (__sun__))
++# define G_STMT_START if (1)
++# define G_STMT_END else (void)0
++# else
++# define G_STMT_START do
++# define G_STMT_END while (0)
++# endif
++# endif
++#endif
++
++
++/* Provide macros to feature the GCC function attribute.
++ */
++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
++#define G_GNUC_PRINTF( format_idx, arg_idx ) \
++ __attribute__((format (printf, format_idx, arg_idx)))
++#define G_GNUC_SCANF( format_idx, arg_idx ) \
++ __attribute__((format (scanf, format_idx, arg_idx)))
++#define G_GNUC_FORMAT( arg_idx ) \
++ __attribute__((format_arg (arg_idx)))
++#define G_GNUC_NORETURN \
++ __attribute__((noreturn))
++#define G_GNUC_CONST \
++ __attribute__((const))
++#define G_GNUC_UNUSED \
++ __attribute__((unused))
++#else /* !__GNUC__ */
++#define G_GNUC_PRINTF( format_idx, arg_idx )
++#define G_GNUC_SCANF( format_idx, arg_idx )
++#define G_GNUC_FORMAT( arg_idx )
++#define G_GNUC_NORETURN
++#define G_GNUC_CONST
++#define G_GNUC_UNUSED
++#endif /* !__GNUC__ */
++
++
++/* Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with
++ * macros, so we can refer to them as strings unconditionally.
++ */
++#ifdef __GNUC__
++#define G_GNUC_FUNCTION __FUNCTION__
++#define G_GNUC_PRETTY_FUNCTION __PRETTY_FUNCTION__
++#else /* !__GNUC__ */
++#define G_GNUC_FUNCTION ""
++#define G_GNUC_PRETTY_FUNCTION ""
++#endif /* !__GNUC__ */
++
++/* we try to provide a usefull equivalent for ATEXIT if it is
++ * not defined, but use is actually abandoned. people should
++ * use g_atexit() instead.
++ */
++#ifndef ATEXIT
++# define ATEXIT(proc) g_ATEXIT(proc)
++#else
++# define G_NATIVE_ATEXIT
++#endif /* ATEXIT */
++
++/* Hacker macro to place breakpoints for elected machines.
++ * Actual use is strongly deprecated of course ;)
++ */
++#if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
++#define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("int $03"); }G_STMT_END
++#elif defined (__alpha__) && defined (__GNUC__) && __GNUC__ >= 2
++#define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("bpt"); }G_STMT_END
++#else /* !__i386__ && !__alpha__ */
++#define G_BREAKPOINT()
++#endif /* __i386__ */
++
++
++/* Provide macros for easily allocating memory. The macros
++ * will cast the allocated memory to the specified type
++ * in order to avoid compiler warnings. (Makes the code neater).
++ */
++
++#ifdef __DMALLOC_H__
++# define g_new(type, count) (ALLOC (type, count))
++# define g_new0(type, count) (CALLOC (type, count))
++# define g_renew(type, mem, count) (REALLOC (mem, type, count))
++#else /* __DMALLOC_H__ */
++# define g_new(type, count) \
++ ((type *) g_malloc ((unsigned) sizeof (type) * (count)))
++# define g_new0(type, count) \
++ ((type *) g_malloc0 ((unsigned) sizeof (type) * (count)))
++# define g_renew(type, mem, count) \
++ ((type *) g_realloc (mem, (unsigned) sizeof (type) * (count)))
++#endif /* __DMALLOC_H__ */
++
++#define g_mem_chunk_create(type, pre_alloc, alloc_type) ( \
++ g_mem_chunk_new (#type " mem chunks (" #pre_alloc ")", \
++ sizeof (type), \
++ sizeof (type) * (pre_alloc), \
++ (alloc_type)) \
++)
++#define g_chunk_new(type, chunk) ( \
++ (type *) g_mem_chunk_alloc (chunk) \
++)
++#define g_chunk_new0(type, chunk) ( \
++ (type *) g_mem_chunk_alloc0 (chunk) \
++)
++#define g_chunk_free(mem, mem_chunk) G_STMT_START { \
++ g_mem_chunk_free ((mem_chunk), (mem)); \
++} G_STMT_END
++
++
++#define g_string(x) #x
++
++
++/* Provide macros for error handling. The "assert" macros will
++ * exit on failure. The "return" macros will exit the current
++ * function. Two different definitions are given for the macros
++ * if G_DISABLE_ASSERT is not defined, in order to support gcc's
++ * __PRETTY_FUNCTION__ capability.
++ */
++
++#ifdef G_DISABLE_ASSERT
++
++#define g_assert(expr)
++#define g_assert_not_reached()
++
++#else /* !G_DISABLE_ASSERT */
++
++#ifdef __GNUC__
++
++#define g_assert(expr) G_STMT_START{ \
++ if (!(expr)) \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_ERROR, \
++ "file %s: line %d (%s): assertion failed: (%s)", \
++ __FILE__, \
++ __LINE__, \
++ __PRETTY_FUNCTION__, \
++ #expr); }G_STMT_END
++
++#define g_assert_not_reached() G_STMT_START{ \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_ERROR, \
++ "file %s: line %d (%s): should not be reached", \
++ __FILE__, \
++ __LINE__, \
++ __PRETTY_FUNCTION__); }G_STMT_END
++
++#else /* !__GNUC__ */
++
++#define g_assert(expr) G_STMT_START{ \
++ if (!(expr)) \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_ERROR, \
++ "file %s: line %d: assertion failed: (%s)", \
++ __FILE__, \
++ __LINE__, \
++ #expr); }G_STMT_END
++
++#define g_assert_not_reached() G_STMT_START{ \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_ERROR, \
++ "file %s: line %d: should not be reached", \
++ __FILE__, \
++ __LINE__); }G_STMT_END
++
++#endif /* __GNUC__ */
++
++#endif /* !G_DISABLE_ASSERT */
++
++
++#ifdef __KORBIT__
++
++#define g_return_if_fail(expr) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ return; \
++ }; }G_STMT_END
++
++#define g_return_val_if_fail(expr,val) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ return val; \
++ }; }G_STMT_END
++
++#else /* !__KORBIT__ */
++
++#ifdef G_DISABLE_CHECKS
++
++#define g_return_if_fail(expr)
++#define g_return_val_if_fail(expr,val)
++
++#else /* !G_DISABLE_CHECKS */
++
++#ifdef __GNUC__
++
++#define g_return_if_fail(expr) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_CRITICAL, \
++ "file %s: line %d (%s): assertion `%s' failed.", \
++ __FILE__, \
++ __LINE__, \
++ __PRETTY_FUNCTION__, \
++ #expr); \
++ return; \
++ }; }G_STMT_END
++
++#define g_return_val_if_fail(expr,val) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_CRITICAL, \
++ "file %s: line %d (%s): assertion `%s' failed.", \
++ __FILE__, \
++ __LINE__, \
++ __PRETTY_FUNCTION__, \
++ #expr); \
++ return val; \
++ }; }G_STMT_END
++
++#else /* !__GNUC__ */
++
++#define g_return_if_fail(expr) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_CRITICAL, \
++ "file %s: line %d: assertion `%s' failed.", \
++ __FILE__, \
++ __LINE__, \
++ #expr); \
++ return; \
++ }; }G_STMT_END
++
++#define g_return_val_if_fail(expr, val) G_STMT_START{ \
++ if (!(expr)) \
++ { \
++ g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_CRITICAL, \
++ "file %s: line %d: assertion `%s' failed.", \
++ __FILE__, \
++ __LINE__, \
++ #expr); \
++ return val; \
++ }; }G_STMT_END
++
++#endif /* !__GNUC__ */
++
++#endif /* !G_DISABLE_CHECKS */
++
++#endif /* !__KORBIT__ */
++
++
++/* Provide type definitions for commonly used types.
++ * These are useful because a "gint8" can be adjusted
++ * to be 1 byte (8 bits) on all platforms. Similarly and
++ * more importantly, "gint32" can be adjusted to be
++ * 4 bytes (32 bits) on all platforms.
++ */
++
++typedef char gchar;
++typedef short gshort;
++typedef long glong;
++typedef int gint;
++typedef gint gboolean;
++
++typedef unsigned char guchar;
++typedef unsigned short gushort;
++typedef unsigned long gulong;
++typedef unsigned int guint;
++
++typedef float gfloat;
++typedef double gdouble;
++
++/* HAVE_LONG_DOUBLE doesn't work correctly on all platforms.
++ * Since gldouble isn't used anywhere, just disable it for now */
++
++#if 0
++#ifdef HAVE_LONG_DOUBLE
++typedef long double gldouble;
++#else /* HAVE_LONG_DOUBLE */
++typedef double gldouble;
++#endif /* HAVE_LONG_DOUBLE */
++#endif /* 0 */
++
++typedef void* gpointer;
++typedef const void *gconstpointer;
++
++
++typedef gint32 gssize;
++typedef guint32 gsize;
++typedef guint32 GQuark;
++typedef gint32 GTime;
++
++
++/* Portable endian checks and conversions
++ *
++ * glibconfig.h defines G_BYTE_ORDER which expands to one of
++ * the below macros.
++ */
++#define G_LITTLE_ENDIAN 1234
++#define G_BIG_ENDIAN 4321
++#define G_PDP_ENDIAN 3412 /* unused, need specific PDP check */
++
++
++/* Basic bit swapping functions
++ */
++#define GUINT16_SWAP_LE_BE_CONSTANT(val) ((guint16) ( \
++ (((guint16) (val) & (guint16) 0x00ffU) << 8) | \
++ (((guint16) (val) & (guint16) 0xff00U) >> 8)))
++#define GUINT32_SWAP_LE_BE_CONSTANT(val) ((guint32) ( \
++ (((guint32) (val) & (guint32) 0x000000ffU) << 24) | \
++ (((guint32) (val) & (guint32) 0x0000ff00U) << 8) | \
++ (((guint32) (val) & (guint32) 0x00ff0000U) >> 8) | \
++ (((guint32) (val) & (guint32) 0xff000000U) >> 24)))
++
++/* Intel specific stuff for speed
++ */
++#if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
++# define GUINT16_SWAP_LE_BE_X86(val) \
++ (__extension__ \
++ ({ register guint16 __v; \
++ if (__builtin_constant_p (val)) \
++ __v = GUINT16_SWAP_LE_BE_CONSTANT (val); \
++ else \
++ __asm__ __const__ ("rorw $8, %w0" \
++ : "=r" (__v) \
++ : "0" ((guint16) (val))); \
++ __v; }))
++# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_X86 (val))
++# if !defined(__i486__) && !defined(__i586__) \
++ && !defined(__pentium__) && !defined(__i686__) && !defined(__pentiumpro__)
++# define GUINT32_SWAP_LE_BE_X86(val) \
++ (__extension__ \
++ ({ register guint32 __v; \
++ if (__builtin_constant_p (val)) \
++ __v = GUINT32_SWAP_LE_BE_CONSTANT (val); \
++ else \
++ __asm__ __const__ ("rorw $8, %w0\n\t" \
++ "rorl $16, %0\n\t" \
++ "rorw $8, %w0" \
++ : "=r" (__v) \
++ : "0" ((guint32) (val))); \
++ __v; }))
++# else /* 486 and higher has bswap */
++# define GUINT32_SWAP_LE_BE_X86(val) \
++ (__extension__ \
++ ({ register guint32 __v; \
++ if (__builtin_constant_p (val)) \
++ __v = GUINT32_SWAP_LE_BE_CONSTANT (val); \
++ else \
++ __asm__ __const__ ("bswap %0" \
++ : "=r" (__v) \
++ : "0" ((guint32) (val))); \
++ __v; }))
++# endif /* processor specific 32-bit stuff */
++# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_X86 (val))
++#else /* !__i386__ */
++# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
++# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val))
++#endif /* __i386__ */
++
++#ifdef G_HAVE_GINT64
++# define GUINT64_SWAP_LE_BE_CONSTANT(val) ((guint64) ( \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x00000000000000ffU)) << 56) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x000000000000ff00U)) << 40) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x0000000000ff0000U)) << 24) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x00000000ff000000U)) << 8) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x000000ff00000000U)) >> 8) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x0000ff0000000000U)) >> 24) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0x00ff000000000000U)) >> 40) | \
++ (((guint64) (val) & \
++ (guint64) G_GINT64_CONSTANT(0xff00000000000000U)) >> 56)))
++# if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
++# define GUINT64_SWAP_LE_BE_X86(val) \
++ (__extension__ \
++ ({ union { guint64 __ll; \
++ guint32 __l[2]; } __r; \
++ if (__builtin_constant_p (val)) \
++ __r.__ll = GUINT64_SWAP_LE_BE_CONSTANT (val); \
++ else \
++ { \
++ union { guint64 __ll; \
++ guint32 __l[2]; } __w; \
++ __w.__ll = ((guint64) val); \
++ __r.__l[0] = GUINT32_SWAP_LE_BE (__w.__l[1]); \
++ __r.__l[1] = GUINT32_SWAP_LE_BE (__w.__l[0]); \
++ } \
++ __r.__ll; }))
++# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_X86 (val))
++# else /* !__i386__ */
++# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT(val))
++# endif
++#endif
++
++#define GUINT16_SWAP_LE_PDP(val) ((guint16) (val))
++#define GUINT16_SWAP_BE_PDP(val) (GUINT16_SWAP_LE_BE (val))
++#define GUINT32_SWAP_LE_PDP(val) ((guint32) ( \
++ (((guint32) (val) & (guint32) 0x0000ffffU) << 16) | \
++ (((guint32) (val) & (guint32) 0xffff0000U) >> 16)))
++#define GUINT32_SWAP_BE_PDP(val) ((guint32) ( \
++ (((guint32) (val) & (guint32) 0x00ff00ffU) << 8) | \
++ (((guint32) (val) & (guint32) 0xff00ff00U) >> 8)))
++
++/* The G*_TO_?E() macros are defined in glibconfig.h.
++ * The transformation is symmetric, so the FROM just maps to the TO.
++ */
++#define GINT16_FROM_LE(val) (GINT16_TO_LE (val))
++#define GUINT16_FROM_LE(val) (GUINT16_TO_LE (val))
++#define GINT16_FROM_BE(val) (GINT16_TO_BE (val))
++#define GUINT16_FROM_BE(val) (GUINT16_TO_BE (val))
++#define GINT32_FROM_LE(val) (GINT32_TO_LE (val))
++#define GUINT32_FROM_LE(val) (GUINT32_TO_LE (val))
++#define GINT32_FROM_BE(val) (GINT32_TO_BE (val))
++#define GUINT32_FROM_BE(val) (GUINT32_TO_BE (val))
++
++#ifdef G_HAVE_GINT64
++#define GINT64_FROM_LE(val) (GINT64_TO_LE (val))
++#define GUINT64_FROM_LE(val) (GUINT64_TO_LE (val))
++#define GINT64_FROM_BE(val) (GINT64_TO_BE (val))
++#define GUINT64_FROM_BE(val) (GUINT64_TO_BE (val))
++#endif
++
++#define GLONG_FROM_LE(val) (GLONG_TO_LE (val))
++#define GULONG_FROM_LE(val) (GULONG_TO_LE (val))
++#define GLONG_FROM_BE(val) (GLONG_TO_BE (val))
++#define GULONG_FROM_BE(val) (GULONG_TO_BE (val))
++
++#define GINT_FROM_LE(val) (GINT_TO_LE (val))
++#define GUINT_FROM_LE(val) (GUINT_TO_LE (val))
++#define GINT_FROM_BE(val) (GINT_TO_BE (val))
++#define GUINT_FROM_BE(val) (GUINT_TO_BE (val))
++
++
++/* Portable versions of host-network order stuff
++ */
++#define g_ntohl(val) (GUINT32_FROM_BE (val))
++#define g_ntohs(val) (GUINT16_FROM_BE (val))
++#define g_htonl(val) (GUINT32_TO_BE (val))
++#define g_htons(val) (GUINT16_TO_BE (val))
++
++
++/* Glib version.
++ * we prefix variable declarations so they can
++ * properly get exported in windows dlls.
++ */
++#define GUTILS_C_VAR extern
++
++
++GUTILS_C_VAR const guint glib_major_version;
++GUTILS_C_VAR const guint glib_minor_version;
++GUTILS_C_VAR const guint glib_micro_version;
++GUTILS_C_VAR const guint glib_interface_age;
++GUTILS_C_VAR const guint glib_binary_age;
++
++#define GLIB_CHECK_VERSION(major,minor,micro) \
++ (GLIB_MAJOR_VERSION > (major) || \
++ (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION > (minor)) || \
++ (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION == (minor) && \
++ GLIB_MICRO_VERSION >= (micro)))
++
++/* Forward declarations of glib types.
++ */
++typedef struct _GAllocator GAllocator;
++typedef struct _GArray GArray;
++typedef struct _GByteArray GByteArray;
++typedef struct _GDebugKey GDebugKey;
++typedef struct _GHashTable GHashTable;
++typedef struct _GList GList;
++typedef struct _GMemChunk GMemChunk;
++typedef struct _GNode GNode;
++typedef struct _GPtrArray GPtrArray;
++typedef struct _GSList GSList;
++typedef struct _GString GString;
++typedef struct _GStringChunk GStringChunk;
++typedef struct _GTree GTree;
++typedef struct _GTuples GTuples;
++
++/* Tree traverse flags */
++typedef enum
++{
++ G_TRAVERSE_LEAFS = 1 << 0,
++ G_TRAVERSE_NON_LEAFS = 1 << 1,
++ G_TRAVERSE_ALL = G_TRAVERSE_LEAFS | G_TRAVERSE_NON_LEAFS,
++ G_TRAVERSE_MASK = 0x03
++} GTraverseFlags;
++
++/* Tree traverse orders */
++typedef enum
++{
++ G_IN_ORDER,
++ G_PRE_ORDER,
++ G_POST_ORDER,
++ G_LEVEL_ORDER
++} GTraverseType;
++
++/* Log level shift offset for user defined
++ * log levels (0-7 are used by GLib).
++ */
++#define G_LOG_LEVEL_USER_SHIFT (8)
++
++/* Glib log levels and flags.
++ */
++typedef enum
++{
++ /* log flags */
++ G_LOG_FLAG_RECURSION = 1 << 0,
++ G_LOG_FLAG_FATAL = 1 << 1,
++
++ /* GLib log levels */
++ G_LOG_LEVEL_ERROR = 1 << 2, /* always fatal */
++ G_LOG_LEVEL_CRITICAL = 1 << 3,
++ G_LOG_LEVEL_WARNING = 1 << 4,
++ G_LOG_LEVEL_MESSAGE = 1 << 5,
++ G_LOG_LEVEL_INFO = 1 << 6,
++ G_LOG_LEVEL_DEBUG = 1 << 7,
++
++ G_LOG_LEVEL_MASK = ~(G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL)
++} GLogLevelFlags;
++
++/* GLib log levels that are considered fatal by default */
++#define G_LOG_FATAL_MASK (G_LOG_FLAG_RECURSION | G_LOG_LEVEL_ERROR)
++
++
++typedef gint (*GCompareFunc) (gconstpointer a,
++ gconstpointer b);
++typedef gchar* (*GCompletionFunc) (gpointer);
++typedef void (*GDestroyNotify) (gpointer data);
++typedef void (*GDataForeachFunc) (GQuark key_id,
++ gpointer data,
++ gpointer user_data);
++typedef void (*GFunc) (gpointer data,
++ gpointer user_data);
++typedef guint (*GHashFunc) (gconstpointer key);
++typedef void (*GFreeFunc) (gpointer data);
++typedef void (*GHFunc) (gpointer key,
++ gpointer value,
++ gpointer user_data);
++typedef gboolean (*GHRFunc) (gpointer key,
++ gpointer value,
++ gpointer user_data);
++typedef void (*GLogFunc) (const gchar *log_domain,
++ GLogLevelFlags log_level,
++ const gchar *message,
++ gpointer user_data);
++typedef gboolean (*GNodeTraverseFunc) (GNode *node,
++ gpointer data);
++typedef void (*GNodeForeachFunc) (GNode *node,
++ gpointer data);
++typedef gint (*GSearchFunc) (gpointer key,
++ gpointer data);
++typedef gint (*GTraverseFunc) (gpointer key,
++ gpointer value,
++ gpointer data);
++typedef void (*GVoidFunc) (void);
++
++
++struct _GList
++{
++ gpointer data;
++ GList *next;
++ GList *prev;
++};
++
++struct _GSList
++{
++ gpointer data;
++ GSList *next;
++};
++
++struct _GString
++{
++ gchar *str;
++ gint len;
++};
++
++struct _GArray
++{
++ gchar *data;
++ guint len;
++};
++
++struct _GByteArray
++{
++ guint8 *data;
++ guint len;
++};
++
++struct _GPtrArray
++{
++ gpointer *pdata;
++ guint len;
++};
++
++struct _GTuples
++{
++ guint len;
++};
++
++struct _GDebugKey
++{
++ gchar *key;
++ guint value;
++};
++
++
++/* Doubly linked lists
++ */
++void g_list_push_allocator (GAllocator *allocator);
++void g_list_pop_allocator (void);
++GList* g_list_alloc (void);
++void g_list_free (GList *list);
++void g_list_free_1 (GList *list);
++GList* g_list_append (GList *list,
++ gpointer data);
++GList* g_list_prepend (GList *list,
++ gpointer data);
++GList* g_list_insert (GList *list,
++ gpointer data,
++ gint position);
++GList* g_list_insert_sorted (GList *list,
++ gpointer data,
++ GCompareFunc func);
++GList* g_list_concat (GList *list1,
++ GList *list2);
++GList* g_list_remove (GList *list,
++ gpointer data);
++GList* g_list_remove_link (GList *list,
++ GList *llink);
++GList* g_list_reverse (GList *list);
++GList* g_list_copy (GList *list);
++GList* g_list_nth (GList *list,
++ guint n);
++GList* g_list_find (GList *list,
++ gpointer data);
++GList* g_list_find_custom (GList *list,
++ gpointer data,
++ GCompareFunc func);
++gint g_list_position (GList *list,
++ GList *llink);
++gint g_list_index (GList *list,
++ gpointer data);
++GList* g_list_last (GList *list);
++GList* g_list_first (GList *list);
++guint g_list_length (GList *list);
++void g_list_foreach (GList *list,
++ GFunc func,
++ gpointer user_data);
++GList* g_list_sort (GList *list,
++ GCompareFunc compare_func);
++gpointer g_list_nth_data (GList *list,
++ guint n);
++#define g_list_previous(list) ((list) ? (((GList *)(list))->prev) : NULL)
++#define g_list_next(list) ((list) ? (((GList *)(list))->next) : NULL)
++
++
++/* Singly linked lists
++ */
++void g_slist_push_allocator (GAllocator *allocator);
++void g_slist_pop_allocator (void);
++GSList* g_slist_alloc (void);
++void g_slist_free (GSList *list);
++void g_slist_free_1 (GSList *list);
++GSList* g_slist_append (GSList *list,
++ gpointer data);
++GSList* g_slist_prepend (GSList *list,
++ gpointer data);
++GSList* g_slist_insert (GSList *list,
++ gpointer data,
++ gint position);
++GSList* g_slist_insert_sorted (GSList *list,
++ gpointer data,
++ GCompareFunc func);
++GSList* g_slist_concat (GSList *list1,
++ GSList *list2);
++GSList* g_slist_remove (GSList *list,
++ gpointer data);
++GSList* g_slist_remove_link (GSList *list,
++ GSList *llink);
++GSList* g_slist_reverse (GSList *list);
++GSList* g_slist_copy (GSList *list);
++GSList* g_slist_nth (GSList *list,
++ guint n);
++GSList* g_slist_find (GSList *list,
++ gpointer data);
++GSList* g_slist_find_custom (GSList *list,
++ gpointer data,
++ GCompareFunc func);
++gint g_slist_position (GSList *list,
++ GSList *llink);
++gint g_slist_index (GSList *list,
++ gpointer data);
++GSList* g_slist_last (GSList *list);
++guint g_slist_length (GSList *list);
++void g_slist_foreach (GSList *list,
++ GFunc func,
++ gpointer user_data);
++GSList* g_slist_sort (GSList *list,
++ GCompareFunc compare_func);
++gpointer g_slist_nth_data (GSList *list,
++ guint n);
++#define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL)
++
++
++/* Hash tables
++ */
++GHashTable* g_hash_table_new (GHashFunc hash_func,
++ GCompareFunc key_compare_func);
++void g_hash_table_destroy (GHashTable *hash_table);
++void g_hash_table_insert (GHashTable *hash_table,
++ gpointer key,
++ gpointer value);
++void g_hash_table_remove (GHashTable *hash_table,
++ gconstpointer key);
++gpointer g_hash_table_lookup (GHashTable *hash_table,
++ gconstpointer key);
++gboolean g_hash_table_lookup_extended(GHashTable *hash_table,
++ gconstpointer lookup_key,
++ gpointer *orig_key,
++ gpointer *value);
++void g_hash_table_freeze (GHashTable *hash_table);
++void g_hash_table_thaw (GHashTable *hash_table);
++void g_hash_table_foreach (GHashTable *hash_table,
++ GHFunc func,
++ gpointer user_data);
++guint g_hash_table_foreach_remove (GHashTable *hash_table,
++ GHRFunc func,
++ gpointer user_data);
++guint g_hash_table_size (GHashTable *hash_table);
++
++
++
++
++/* Balanced binary trees
++ */
++GTree* g_tree_new (GCompareFunc key_compare_func);
++void g_tree_destroy (GTree *tree);
++void g_tree_insert (GTree *tree,
++ gpointer key,
++ gpointer value);
++void g_tree_remove (GTree *tree,
++ gpointer key);
++gpointer g_tree_lookup (GTree *tree,
++ gpointer key);
++void g_tree_traverse (GTree *tree,
++ GTraverseFunc traverse_func,
++ GTraverseType traverse_type,
++ gpointer data);
++gpointer g_tree_search (GTree *tree,
++ GSearchFunc search_func,
++ gpointer data);
++gint g_tree_height (GTree *tree);
++gint g_tree_nnodes (GTree *tree);
++
++
++
++/* N-way tree implementation
++ */
++struct _GNode
++{
++ gpointer data;
++ GNode *next;
++ GNode *prev;
++ GNode *parent;
++ GNode *children;
++};
++
++#define G_NODE_IS_ROOT(node) (((GNode*) (node))->parent == NULL && \
++ ((GNode*) (node))->prev == NULL && \
++ ((GNode*) (node))->next == NULL)
++#define G_NODE_IS_LEAF(node) (((GNode*) (node))->children == NULL)
++
++void g_node_push_allocator (GAllocator *allocator);
++void g_node_pop_allocator (void);
++GNode* g_node_new (gpointer data);
++void g_node_destroy (GNode *root);
++void g_node_unlink (GNode *node);
++GNode* g_node_insert (GNode *parent,
++ gint position,
++ GNode *node);
++GNode* g_node_insert_before (GNode *parent,
++ GNode *sibling,
++ GNode *node);
++GNode* g_node_prepend (GNode *parent,
++ GNode *node);
++guint g_node_n_nodes (GNode *root,
++ GTraverseFlags flags);
++GNode* g_node_get_root (GNode *node);
++gboolean g_node_is_ancestor (GNode *node,
++ GNode *descendant);
++guint g_node_depth (GNode *node);
++GNode* g_node_find (GNode *root,
++ GTraverseType order,
++ GTraverseFlags flags,
++ gpointer data);
++
++/* convenience macros */
++#define g_node_append(parent, node) \
++ g_node_insert_before ((parent), NULL, (node))
++#define g_node_insert_data(parent, position, data) \
++ g_node_insert ((parent), (position), g_node_new (data))
++#define g_node_insert_data_before(parent, sibling, data) \
++ g_node_insert_before ((parent), (sibling), g_node_new (data))
++#define g_node_prepend_data(parent, data) \
++ g_node_prepend ((parent), g_node_new (data))
++#define g_node_append_data(parent, data) \
++ g_node_insert_before ((parent), NULL, g_node_new (data))
++
++/* traversal function, assumes that `node' is root
++ * (only traverses `node' and its subtree).
++ * this function is just a high level interface to
++ * low level traversal functions, optimized for speed.
++ */
++void g_node_traverse (GNode *root,
++ GTraverseType order,
++ GTraverseFlags flags,
++ gint max_depth,
++ GNodeTraverseFunc func,
++ gpointer data);
++
++/* return the maximum tree height starting with `node', this is an expensive
++ * operation, since we need to visit all nodes. this could be shortened by
++ * adding `guint height' to struct _GNode, but then again, this is not very
++ * often needed, and would make g_node_insert() more time consuming.
++ */
++guint g_node_max_height (GNode *root);
++
++void g_node_children_foreach (GNode *node,
++ GTraverseFlags flags,
++ GNodeForeachFunc func,
++ gpointer data);
++void g_node_reverse_children (GNode *node);
++guint g_node_n_children (GNode *node);
++GNode* g_node_nth_child (GNode *node,
++ guint n);
++GNode* g_node_last_child (GNode *node);
++GNode* g_node_find_child (GNode *node,
++ GTraverseFlags flags,
++ gpointer data);
++gint g_node_child_position (GNode *node,
++ GNode *child);
++gint g_node_child_index (GNode *node,
++ gpointer data);
++
++GNode* g_node_first_sibling (GNode *node);
++GNode* g_node_last_sibling (GNode *node);
++
++#define g_node_prev_sibling(node) ((node) ? \
++ ((GNode*) (node))->prev : NULL)
++#define g_node_next_sibling(node) ((node) ? \
++ ((GNode*) (node))->next : NULL)
++#define g_node_first_child(node) ((node) ? \
++ ((GNode*) (node))->children : NULL)
++
++
++
++/* Fatal error handlers.
++ * g_on_error_query() will prompt the user to either
++ * [E]xit, [H]alt, [P]roceed or show [S]tack trace.
++ * g_on_error_stack_trace() invokes gdb, which attaches to the current
++ * process and shows a stack trace.
++ * These function may cause different actions on non-unix platforms.
++ * The prg_name arg is required by gdb to find the executable, if it is
++ * passed as NULL, g_on_error_query() will try g_get_prgname().
++ */
++void g_on_error_query (const gchar *prg_name);
++void g_on_error_stack_trace (const gchar *prg_name);
++
++
++/* Logging mechanism
++ */
++extern const gchar *g_log_domain_glib;
++guint g_log_set_handler (const gchar *log_domain,
++ GLogLevelFlags log_levels,
++ GLogFunc log_func,
++ gpointer user_data);
++void g_log_remove_handler (const gchar *log_domain,
++ guint handler_id);
++void g_log_default_handler (const gchar *log_domain,
++ GLogLevelFlags log_level,
++ const gchar *message,
++ gpointer unused_data);
++#ifdef __KORBIT__
++#define g_log(log_domain, log_level, format, args...) \
++G_STMT_START { printf(format, ##args); printf("\n"); } G_STMT_END
++#define g_logv(log_domain, log_level, format, args...)
++#else /* !__KORBIT__ */
++void g_log (const gchar *log_domain,
++ GLogLevelFlags log_level,
++ const gchar *format,
++ ...) G_GNUC_PRINTF (3, 4);
++void g_logv (const gchar *log_domain,
++ GLogLevelFlags log_level,
++ const gchar *format,
++ va_list args);
++#endif /* !__KORBIT__ */
++GLogLevelFlags g_log_set_fatal_mask (const gchar *log_domain,
++ GLogLevelFlags fatal_mask);
++GLogLevelFlags g_log_set_always_fatal (GLogLevelFlags fatal_mask);
++#ifndef G_LOG_DOMAIN
++#define G_LOG_DOMAIN ((gchar*) 0)
++#endif /* G_LOG_DOMAIN */
++#ifdef __GNUC__
++#define g_error(format, args...) g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_ERROR, \
++ format, ##args)
++#define g_message(format, args...) g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_MESSAGE, \
++ format, ##args)
++#define g_warning(format, args...) g_log (G_LOG_DOMAIN, \
++ G_LOG_LEVEL_WARNING, \
++ format, ##args)
++#else /* !__GNUC__ */
++static void
++g_error (const gchar *format,
++ ...)
++{
++ va_list args;
++ va_start (args, format);
++ g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args);
++ va_end (args);
++}
++static void
++g_message (const gchar *format,
++ ...)
++{
++ va_list args;
++ va_start (args, format);
++ g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, args);
++ va_end (args);
++}
++static void
++g_warning (const gchar *format,
++ ...)
++{
++ va_list args;
++ va_start (args, format);
++ g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, args);
++ va_end (args);
++}
++#endif /* !__GNUC__ */
++
++typedef void (*GPrintFunc) (const gchar *string);
++#ifdef __KORBIT__
++#define g_print(format, args...) printf(format, ##args)
++#else
++void g_print (const gchar *format,
++ ...) G_GNUC_PRINTF (1, 2);
++#endif
++GPrintFunc g_set_print_handler (GPrintFunc func);
++void g_printerr (const gchar *format,
++ ...) G_GNUC_PRINTF (1, 2);
++GPrintFunc g_set_printerr_handler (GPrintFunc func);
++
++/* deprecated compatibility functions, use g_log_set_handler() instead */
++typedef void (*GErrorFunc) (const gchar *str);
++typedef void (*GWarningFunc) (const gchar *str);
++GErrorFunc g_set_error_handler (GErrorFunc func);
++GWarningFunc g_set_warning_handler (GWarningFunc func);
++GPrintFunc g_set_message_handler (GPrintFunc func);
++
++
++gpointer g_malloc (gulong size);
++gpointer g_malloc0 (gulong size);
++gpointer g_realloc (gpointer mem,
++ gulong size);
++void g_free (gpointer mem);
++
++/* Generic allocators
++ */
++GAllocator* g_allocator_new (const gchar *name,
++ guint n_preallocs);
++void g_allocator_free (GAllocator *allocator);
++
++#define G_ALLOCATOR_LIST (1)
++#define G_ALLOCATOR_SLIST (2)
++#define G_ALLOCATOR_NODE (3)
++
++
++/* "g_mem_chunk_new" creates a new memory chunk.
++ * Memory chunks are used to allocate pieces of memory which are
++ * always the same size. Lists are a good example of such a data type.
++ * The memory chunk allocates and frees blocks of memory as needed.
++ * Just be sure to call "g_mem_chunk_free" and not "g_free" on data
++ * allocated in a mem chunk. ("g_free" will most likely cause a seg
++ * fault...somewhere).
++ *
++ * Oh yeah, GMemChunk is an opaque data type. (You don't really
++ * want to know what's going on inside do you?)
++ */
++
++/* ALLOC_ONLY MemChunk's can only allocate memory. The free operation
++ * is interpreted as a no op. ALLOC_ONLY MemChunk's save 4 bytes per
++ * atom. (They are also useful for lists which use MemChunk to allocate
++ * memory but are also part of the MemChunk implementation).
++ * ALLOC_AND_FREE MemChunk's can allocate and free memory.
++ */
++
++#define G_ALLOC_ONLY 1
++#define G_ALLOC_AND_FREE 2
++
++GMemChunk* g_mem_chunk_new (gchar *name,
++ gint atom_size,
++ gulong area_size,
++ gint type);
++void g_mem_chunk_destroy (GMemChunk *mem_chunk);
++gpointer g_mem_chunk_alloc (GMemChunk *mem_chunk);
++gpointer g_mem_chunk_alloc0 (GMemChunk *mem_chunk);
++void g_mem_chunk_free (GMemChunk *mem_chunk,
++ gpointer mem);
++void g_mem_chunk_clean (GMemChunk *mem_chunk);
++void g_mem_chunk_reset (GMemChunk *mem_chunk);
++void g_mem_chunk_print (GMemChunk *mem_chunk);
++void g_mem_chunk_info (void);
++
++/* Ah yes...we have a "g_blow_chunks" function.
++ * "g_blow_chunks" simply compresses all the chunks. This operation
++ * consists of freeing every memory area that should be freed (but
++ * which we haven't gotten around to doing yet). And, no,
++ * "g_blow_chunks" doesn't follow the naming scheme, but it is a
++ * much better name than "g_mem_chunk_clean_all" or something
++ * similar.
++ */
++void g_blow_chunks (void);
++
++
++/* String utility functions that modify a string argument or
++ * return a constant string that must not be freed.
++ */
++#define G_STR_DELIMITERS "_-|> <."
++gchar* g_strdelimit (gchar *string,
++ const gchar *delimiters,
++ gchar new_delimiter);
++#ifndef __KORBIT__
++gdouble g_strtod (const gchar *nptr,
++ gchar **endptr);
++#endif /* !__KORBIT__ */
++gchar* g_strerror (gint errnum);
++gchar* g_strsignal (gint signum);
++gint g_strcasecmp (const gchar *s1,
++ const gchar *s2);
++gint g_strncasecmp (const gchar *s1,
++ const gchar *s2,
++ guint n);
++void g_strdown (gchar *string);
++void g_strup (gchar *string);
++void g_strreverse (gchar *string);
++/* removes leading spaces */
++gchar* g_strchug (gchar *string);
++/* removes trailing spaces */
++gchar* g_strchomp (gchar *string);
++/* removes leading & trailing spaces */
++#define g_strstrip( string ) g_strchomp (g_strchug (string))
++
++/* String utility functions that return a newly allocated string which
++ * ought to be freed from the caller at some point.
++ */
++gchar* g_strdup (const gchar *str);
++gchar* g_strdup_printf (const gchar *format,
++ ...) G_GNUC_PRINTF (1, 2);
++gchar* g_strdup_vprintf (const gchar *format,
++ va_list args);
++gchar* g_strndup (const gchar *str,
++ guint n);
++gchar* g_strnfill (guint length,
++ gchar fill_char);
++gchar* g_strconcat (const gchar *string1,
++ ...); /* NULL terminated */
++gchar* g_strjoin (const gchar *separator,
++ ...); /* NULL terminated */
++gchar* g_strescape (gchar *string);
++gpointer g_memdup (gconstpointer mem,
++ guint byte_size);
++
++/* NULL terminated string arrays.
++ * g_strsplit() splits up string into max_tokens tokens at delim and
++ * returns a newly allocated string array.
++ * g_strjoinv() concatenates all of str_array's strings, sliding in an
++ * optional separator, the returned string is newly allocated.
++ * g_strfreev() frees the array itself and all of its strings.
++ */
++gchar** g_strsplit (const gchar *string,
++ const gchar *delimiter,
++ gint max_tokens);
++gchar* g_strjoinv (const gchar *separator,
++ gchar **str_array);
++void g_strfreev (gchar **str_array);
++
++
++
++/* calculate a string size, guarranteed to fit format + args.
++ */
++guint g_printf_string_upper_bound (const gchar* format,
++ va_list args);
++
++
++/* Retrive static string info
++ */
++gchar* g_get_user_name (void);
++gchar* g_get_real_name (void);
++gchar* g_get_home_dir (void);
++gchar* g_get_tmp_dir (void);
++gchar* g_get_prgname (void);
++void g_set_prgname (const gchar *prgname);
++
++
++/* Miscellaneous utility functions
++ */
++guint g_parse_debug_string (const gchar *string,
++ GDebugKey *keys,
++ guint nkeys);
++gint g_snprintf (gchar *string,
++ gulong n,
++ gchar const *format,
++ ...) G_GNUC_PRINTF (3, 4);
++gint g_vsnprintf (gchar *string,
++ gulong n,
++ gchar const *format,
++ va_list args);
++gchar* g_basename (const gchar *file_name);
++/* Check if a file name is an absolute path */
++gboolean g_path_is_absolute (const gchar *file_name);
++/* In case of absolute paths, skip the root part */
++gchar* g_path_skip_root (gchar *file_name);
++
++/* strings are newly allocated with g_malloc() */
++gchar* g_dirname (const gchar *file_name);
++gchar* g_get_current_dir (void);
++gchar* g_getenv (const gchar *variable);
++
++
++/* we use a GLib function as a replacement for ATEXIT, so
++ * the programmer is not required to check the return value
++ * (if there is any in the implementation) and doesn't encounter
++ * missing include files.
++ */
++void g_atexit (GVoidFunc func);
++
++
++/* Bit tests
++ */
++G_INLINE_FUNC gint g_bit_nth_lsf (guint32 mask,
++ gint nth_bit);
++#ifdef G_CAN_INLINE
++G_INLINE_FUNC gint
++g_bit_nth_lsf (guint32 mask,
++ gint nth_bit)
++{
++ do
++ {
++ nth_bit++;
++ if (mask & (1 << (guint) nth_bit))
++ return nth_bit;
++ }
++ while (nth_bit < 32);
++ return -1;
++}
++#endif /* G_CAN_INLINE */
++
++G_INLINE_FUNC gint g_bit_nth_msf (guint32 mask,
++ gint nth_bit);
++#ifdef G_CAN_INLINE
++G_INLINE_FUNC gint
++g_bit_nth_msf (guint32 mask,
++ gint nth_bit)
++{
++ if (nth_bit < 0)
++ nth_bit = 32;
++ do
++ {
++ nth_bit--;
++ if (mask & (1 << (guint) nth_bit))
++ return nth_bit;
++ }
++ while (nth_bit > 0);
++ return -1;
++}
++#endif /* G_CAN_INLINE */
++
++G_INLINE_FUNC guint g_bit_storage (guint number);
++#ifdef G_CAN_INLINE
++G_INLINE_FUNC guint
++g_bit_storage (guint number)
++{
++ register guint n_bits = 0;
++
++ do
++ {
++ n_bits++;
++ number >>= 1;
++ }
++ while (number);
++ return n_bits;
++}
++#endif /* G_CAN_INLINE */
++
++/* String Chunks
++ */
++GStringChunk* g_string_chunk_new (gint size);
++void g_string_chunk_free (GStringChunk *chunk);
++gchar* g_string_chunk_insert (GStringChunk *chunk,
++ const gchar *string);
++gchar* g_string_chunk_insert_const (GStringChunk *chunk,
++ const gchar *string);
++
++
++/* Strings
++ */
++GString* g_string_new (const gchar *init);
++GString* g_string_sized_new (guint dfl_size);
++void g_string_free (GString *string,
++ gint free_segment);
++GString* g_string_assign (GString *lval,
++ const gchar *rval);
++GString* g_string_truncate (GString *string,
++ gint len);
++GString* g_string_append (GString *string,
++ const gchar *val);
++GString* g_string_append_c (GString *string,
++ gchar c);
++GString* g_string_prepend (GString *string,
++ const gchar *val);
++GString* g_string_prepend_c (GString *string,
++ gchar c);
++GString* g_string_insert (GString *string,
++ gint pos,
++ const gchar *val);
++GString* g_string_insert_c (GString *string,
++ gint pos,
++ gchar c);
++GString* g_string_erase (GString *string,
++ gint pos,
++ gint len);
++GString* g_string_down (GString *string);
++GString* g_string_up (GString *string);
++void g_string_sprintf (GString *string,
++ const gchar *format,
++ ...) G_GNUC_PRINTF (2, 3);
++void g_string_sprintfa (GString *string,
++ const gchar *format,
++ ...) G_GNUC_PRINTF (2, 3);
++
++
++/* Resizable arrays, remove fills any cleared spot and shortens the
++ * array, while preserving the order. remove_fast will distort the
++ * order by moving the last element to the position of the removed
++ */
++
++#define g_array_append_val(a,v) g_array_append_vals (a, &v, 1)
++#define g_array_prepend_val(a,v) g_array_prepend_vals (a, &v, 1)
++#define g_array_insert_val(a,i,v) g_array_insert_vals (a, i, &v, 1)
++#define g_array_index(a,t,i) (((t*) (a)->data) [(i)])
++
++GArray* g_array_new (gboolean zero_terminated,
++ gboolean clear,
++ guint element_size);
++void g_array_free (GArray *array,
++ gboolean free_segment);
++GArray* g_array_append_vals (GArray *array,
++ gconstpointer data,
++ guint len);
++GArray* g_array_prepend_vals (GArray *array,
++ gconstpointer data,
++ guint len);
++GArray* g_array_insert_vals (GArray *array,
++ guint index,
++ gconstpointer data,
++ guint len);
++GArray* g_array_set_size (GArray *array,
++ guint length);
++GArray* g_array_remove_index (GArray *array,
++ guint index);
++GArray* g_array_remove_index_fast (GArray *array,
++ guint index);
++
++/* Resizable pointer array. This interface is much less complicated
++ * than the above. Add appends appends a pointer. Remove fills any
++ * cleared spot and shortens the array. remove_fast will again distort
++ * order.
++ */
++#define g_ptr_array_index(array,index) (array->pdata)[index]
++GPtrArray* g_ptr_array_new (void);
++void g_ptr_array_free (GPtrArray *array,
++ gboolean free_seg);
++void g_ptr_array_set_size (GPtrArray *array,
++ gint length);
++gpointer g_ptr_array_remove_index (GPtrArray *array,
++ guint index);
++gpointer g_ptr_array_remove_index_fast (GPtrArray *array,
++ guint index);
++gboolean g_ptr_array_remove (GPtrArray *array,
++ gpointer data);
++gboolean g_ptr_array_remove_fast (GPtrArray *array,
++ gpointer data);
++void g_ptr_array_add (GPtrArray *array,
++ gpointer data);
++
++/* Hash Functions
++ */
++gint g_str_equal (gconstpointer v,
++ gconstpointer v2);
++guint g_str_hash (gconstpointer v);
++
++gint g_int_equal (gconstpointer v,
++ gconstpointer v2);
++guint g_int_hash (gconstpointer v);
++
++/* This "hash" function will just return the key's adress as an
++ * unsigned integer. Useful for hashing on plain adresses or
++ * simple integer values.
++ * passing NULL into g_hash_table_new() as GHashFunc has the
++ * same effect as passing g_direct_hash().
++ */
++guint g_direct_hash (gconstpointer v);
++gint g_direct_equal (gconstpointer v,
++ gconstpointer v2);
++
++
++
++/* Prime numbers.
++ */
++
++/* This function returns prime numbers spaced by approximately 1.5-2.0
++ * and is for use in resizing data structures which prefer
++ * prime-valued sizes. The closest spaced prime function returns the
++ * next largest prime, or the highest it knows about which is about
++ * MAXINT/4.
++ */
++guint g_spaced_primes_closest (guint num);
++
++
++
++#ifndef __KORBIT__
++/* GLib Thread support
++ */
++typedef struct _GMutex GMutex;
++typedef struct _GCond GCond;
++typedef struct _GPrivate GPrivate;
++typedef struct _GStaticPrivate GStaticPrivate;
++typedef struct _GThreadFunctions GThreadFunctions;
++struct _GThreadFunctions
++{
++ GMutex* (*mutex_new) (void);
++ void (*mutex_lock) (GMutex *mutex);
++ gboolean (*mutex_trylock) (GMutex *mutex);
++ void (*mutex_unlock) (GMutex *mutex);
++ void (*mutex_free) (GMutex *mutex);
++ GCond* (*cond_new) (void);
++ void (*cond_signal) (GCond *cond);
++ void (*cond_broadcast) (GCond *cond);
++ void (*cond_wait) (GCond *cond,
++ GMutex *mutex);
++ gboolean (*cond_timed_wait) (GCond *cond,
++ GMutex *mutex,
++ GTimeVal *end_time);
++ void (*cond_free) (GCond *cond);
++ GPrivate* (*private_new) (GDestroyNotify destructor);
++ gpointer (*private_get) (GPrivate *private_key);
++ void (*private_set) (GPrivate *private_key,
++ gpointer data);
++};
++
++GUTILS_C_VAR GThreadFunctions g_thread_functions_for_glib_use;
++GUTILS_C_VAR gboolean g_thread_use_default_impl;
++GUTILS_C_VAR gboolean g_threads_got_initialized;
++
++/* initializes the mutex/cond/private implementation for glib, might
++ * only be called once, and must not be called directly or indirectly
++ * from another glib-function, e.g. as a callback.
++ */
++void g_thread_init (GThreadFunctions *vtable);
++
++/* internal function for fallback static mutex implementation */
++GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
++
++/* shorthands for conditional and unconditional function calls */
++#define G_THREAD_UF(name, arglist) \
++ (*g_thread_functions_for_glib_use . name) arglist
++#define G_THREAD_CF(name, fail, arg) \
++ (g_thread_supported () ? G_THREAD_UF (name, arg) : (fail))
++/* keep in mind, all those mutexes and static mutexes are not
++ * recursive in general, don't rely on that
++ */
++#define g_thread_supported() (g_threads_got_initialized)
++#define g_mutex_new() G_THREAD_UF (mutex_new, ())
++#define g_mutex_lock(mutex) G_THREAD_CF (mutex_lock, (void)0, (mutex))
++#define g_mutex_trylock(mutex) G_THREAD_CF (mutex_trylock, TRUE, (mutex))
++#define g_mutex_unlock(mutex) G_THREAD_CF (mutex_unlock, (void)0, (mutex))
++#define g_mutex_free(mutex) G_THREAD_CF (mutex_free, (void)0, (mutex))
++#define g_cond_new() G_THREAD_UF (cond_new, ())
++#define g_cond_signal(cond) G_THREAD_CF (cond_signal, (void)0, (cond))
++#define g_cond_broadcast(cond) G_THREAD_CF (cond_broadcast, (void)0, (cond))
++#define g_cond_wait(cond, mutex) G_THREAD_CF (cond_wait, (void)0, (cond, \
++ mutex))
++#define g_cond_free(cond) G_THREAD_CF (cond_free, (void)0, (cond))
++#define g_cond_timed_wait(cond, mutex, abs_time) G_THREAD_CF (cond_timed_wait, \
++ TRUE, \
++ (cond, mutex, \
++ abs_time))
++#define g_private_new(destructor) G_THREAD_UF (private_new, (destructor))
++#define g_private_get(private_key) G_THREAD_CF (private_get, \
++ ((gpointer)private_key), \
++ (private_key))
++#define g_private_set(private_key, value) G_THREAD_CF (private_set, \
++ (void) (private_key = \
++ (GPrivate*) (value)), \
++ (private_key, value))
++/* GStaticMutexes can be statically initialized with the value
++ * G_STATIC_MUTEX_INIT, and then they can directly be used, that is
++ * much easier, than having to explicitly allocate the mutex before
++ * use
++ */
++#define g_static_mutex_lock(mutex) \
++ g_mutex_lock (g_static_mutex_get_mutex (mutex))
++#define g_static_mutex_trylock(mutex) \
++ g_mutex_trylock (g_static_mutex_get_mutex (mutex))
++#define g_static_mutex_unlock(mutex) \
++ g_mutex_unlock (g_static_mutex_get_mutex (mutex))
++struct _GStaticPrivate
++{
++ guint index;
++};
++#define G_STATIC_PRIVATE_INIT { 0 }
++gpointer g_static_private_get (GStaticPrivate *private_key);
++void g_static_private_set (GStaticPrivate *private_key,
++ gpointer data,
++ GDestroyNotify notify);
++#endif /* __KORBIT__ */
++
++/* these are some convenience macros that expand to nothing if GLib
++ * was configured with --disable-threads. for using StaticMutexes,
++ * you define them with G_LOCK_DEFINE_STATIC (name) or G_LOCK_DEFINE (name)
++ * if you need to export the mutex. With G_LOCK_EXTERN (name) you can
++ * declare such an globally defined lock. name is a unique identifier
++ * for the protected varibale or code portion. locking, testing and
++ * unlocking of such mutexes can be done with G_LOCK(), G_UNLOCK() and
++ * G_TRYLOCK() respectively.
++ */
++#ifdef __KORBIT__
++#undef G_THREADS_ENABLED
++#endif
++
++extern void glib_dummy_decl (void);
++#define G_LOCK_NAME(name) (g__ ## name ## _lock)
++#ifdef G_THREADS_ENABLED
++# define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name)
++# define G_LOCK_DEFINE(name) \
++ GStaticMutex G_LOCK_NAME (name) = G_STATIC_MUTEX_INIT
++# define G_LOCK_EXTERN(name) extern GStaticMutex G_LOCK_NAME (name)
++
++# define G_LOCK(name) g_static_mutex_lock (&G_LOCK_NAME (name))
++# define G_UNLOCK(name) g_static_mutex_unlock (&G_LOCK_NAME (name))
++# define G_TRYLOCK(name) g_static_mutex_trylock (&G_LOCK_NAME (name))
++#else /* !G_THREADS_ENABLED */
++# define G_LOCK_DEFINE_STATIC(name) extern void glib_dummy_decl (void)
++# define G_LOCK_DEFINE(name) extern void glib_dummy_decl (void)
++# define G_LOCK_EXTERN(name) extern void glib_dummy_decl (void)
++# define G_LOCK(name)
++# define G_UNLOCK(name)
++# define G_TRYLOCK(name) (FALSE)
++#endif /* !G_THREADS_ENABLED */
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++
++#endif /* __G_LIB_H__ */
+diff -urN linux-2.4.1/net/korbit/kglib/glibconfig.h linux-2.4.1-korbit/net/korbit/kglib/glibconfig.h
+--- linux-2.4.1/net/korbit/kglib/glibconfig.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/glibconfig.h Thu Feb 1 11:46:56 2001
+@@ -0,0 +1,131 @@
++/* glibconfig.h
++ *
++ * This is a generated file. Please modify `configure.in'
++ */
++
++#ifndef GLIBCONFIG_H
++#define GLIBCONFIG_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++#include <limits.h>
++/*#include <float.h>*/
++#define GLIB_HAVE_SYS_POLL_H
++
++#define G_MINFLOAT FLT_MIN
++#define G_MAXFLOAT FLT_MAX
++#define G_MINDOUBLE DBL_MIN
++#define G_MAXDOUBLE DBL_MAX
++#define G_MINSHORT SHRT_MIN
++#define G_MAXSHORT SHRT_MAX
++#define G_MININT INT_MIN
++#define G_MAXINT INT_MAX
++#define G_MINLONG LONG_MIN
++#define G_MAXLONG LONG_MAX
++
++typedef signed char gint8;
++typedef unsigned char guint8;
++typedef signed short gint16;
++typedef unsigned short guint16;
++typedef signed int gint32;
++typedef unsigned int guint32;
++
++#if defined (__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
++# define G_GNUC_EXTENSION __extension__
++#else
++# define G_GNUC_EXTENSION
++#endif
++
++#define G_HAVE_GINT64 1
++
++G_GNUC_EXTENSION typedef signed long long gint64;
++G_GNUC_EXTENSION typedef unsigned long long guint64;
++
++#define G_GINT64_CONSTANT(val) (G_GNUC_EXTENSION (val##LL))
++
++#define GPOINTER_TO_INT(p) ((gint) (p))
++#define GPOINTER_TO_UINT(p) ((guint) (p))
++
++#define GINT_TO_POINTER(i) ((gpointer) (i))
++#define GUINT_TO_POINTER(u) ((gpointer) (u))
++
++#ifdef NeXT /* @#%@! NeXTStep */
++# define g_ATEXIT(proc) (!atexit (proc))
++#else
++# define g_ATEXIT(proc) (atexit (proc))
++#endif
++
++#define g_memmove(d,s,n) G_STMT_START { memmove ((d), (s), (n)); } G_STMT_END
++
++#define GLIB_MAJOR_VERSION 1
++#define GLIB_MINOR_VERSION 2
++#define GLIB_MICRO_VERSION 8
++
++
++#define G_VA_COPY __va_copy
++
++#ifdef __cplusplus
++#define G_HAVE_INLINE 1
++#else /* !__cplusplus */
++#define G_HAVE_INLINE 1
++#define G_HAVE___INLINE 1
++#define G_HAVE___INLINE__ 1
++#endif /* !__cplusplus */
++
++#define G_THREADS_ENABLED
++#define G_THREADS_IMPL_POSIX
++typedef struct _GStaticMutex GStaticMutex;
++struct _GStaticMutex
++{
++ struct _GMutex *runtime_mutex;
++ union {
++ char pad[24];
++ double dummy_double;
++ void *dummy_pointer;
++ long dummy_long;
++ } aligned_pad_u;
++};
++#define G_STATIC_MUTEX_INIT { NULL, { { 0,0,0,0,0,0,77,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} } }
++#define g_static_mutex_get_mutex(mutex) (g_thread_use_default_impl ? ((GMutex*) &((mutex)->aligned_pad_u)) : g_static_mutex_get_mutex_impl (&((mutex)->runtime_mutex)))
++
++#define GINT16_TO_BE(val) ((gint16) (val))
++#define GUINT16_TO_BE(val) ((guint16) (val))
++#define GINT16_TO_LE(val) ((gint16) GUINT16_SWAP_LE_BE (val))
++#define GUINT16_TO_LE(val) (GUINT16_SWAP_LE_BE (val))
++#define GINT32_TO_BE(val) ((gint32) (val))
++#define GUINT32_TO_BE(val) ((guint32) (val))
++#define GINT32_TO_LE(val) ((gint32) GUINT32_SWAP_LE_BE (val))
++#define GUINT32_TO_LE(val) (GUINT32_SWAP_LE_BE (val))
++#define GINT64_TO_BE(val) ((gint64) (val))
++#define GUINT64_TO_BE(val) ((guint64) (val))
++#define GINT64_TO_LE(val) ((gint64) GUINT64_SWAP_LE_BE (val))
++#define GUINT64_TO_LE(val) (GUINT64_SWAP_LE_BE (val))
++#define GLONG_TO_LE(val) ((glong) GINT32_TO_LE (val))
++#define GULONG_TO_LE(val) ((gulong) GUINT32_TO_LE (val))
++#define GLONG_TO_BE(val) ((glong) GINT32_TO_BE (val))
++#define GULONG_TO_BE(val) ((gulong) GUINT32_TO_BE (val))
++#define GINT_TO_LE(val) ((gint) GINT32_TO_LE (val))
++#define GUINT_TO_LE(val) ((guint) GUINT32_TO_LE (val))
++#define GINT_TO_BE(val) ((gint) GINT32_TO_BE (val))
++#define GUINT_TO_BE(val) ((guint) GUINT32_TO_BE (val))
++#define G_BYTE_ORDER G_LITTLE_ENDIAN
++
++#define GLIB_SYSDEF_POLLIN =1
++#define GLIB_SYSDEF_POLLOUT =4
++#define GLIB_SYSDEF_POLLPRI =2
++#define GLIB_SYSDEF_POLLERR =8
++#define GLIB_SYSDEF_POLLHUP =16
++#define GLIB_SYSDEF_POLLNVAL =32
++
++
++#define G_HAVE_WCHAR_H 1
++#define G_HAVE_WCTYPE_H 1
++
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* GLIBCONFIG_H */
+diff -urN linux-2.4.1/net/korbit/kglib/glist.c linux-2.4.1-korbit/net/korbit/kglib/glist.c
+--- linux-2.4.1/net/korbit/kglib/glist.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/glist.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,666 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include "glib.h"
++
++
++struct _GAllocator /* from gmem.c */
++{
++ gchar *name;
++ guint16 n_preallocs;
++ guint is_unused : 1;
++ guint type : 4;
++ GAllocator *last;
++ GMemChunk *mem_chunk;
++ GList *free_lists; /* implementation specific */
++};
++
++static GAllocator *current_allocator = NULL;
++G_LOCK_DEFINE_STATIC (current_allocator);
++
++/* HOLDS: current_allocator_lock */
++static void
++g_list_validate_allocator (GAllocator *allocator)
++{
++ g_return_if_fail (allocator != NULL);
++ g_return_if_fail (allocator->is_unused == TRUE);
++
++ if (allocator->type != G_ALLOCATOR_LIST)
++ {
++ allocator->type = G_ALLOCATOR_LIST;
++ if (allocator->mem_chunk)
++ {
++ g_mem_chunk_destroy (allocator->mem_chunk);
++ allocator->mem_chunk = NULL;
++ }
++ }
++
++ if (!allocator->mem_chunk)
++ {
++ allocator->mem_chunk = g_mem_chunk_new (allocator->name,
++ sizeof (GList),
++ sizeof (GList) * allocator->n_preallocs,
++ G_ALLOC_ONLY);
++ allocator->free_lists = NULL;
++ }
++
++ allocator->is_unused = FALSE;
++}
++
++void
++g_list_push_allocator(GAllocator *allocator)
++{
++ G_LOCK (current_allocator);
++ g_list_validate_allocator ( allocator );
++ allocator->last = current_allocator;
++ current_allocator = allocator;
++ G_UNLOCK (current_allocator);
++}
++
++void
++g_list_pop_allocator (void)
++{
++ G_LOCK (current_allocator);
++ if (current_allocator)
++ {
++ GAllocator *allocator;
++
++ allocator = current_allocator;
++ current_allocator = allocator->last;
++ allocator->last = NULL;
++ allocator->is_unused = TRUE;
++ }
++ G_UNLOCK (current_allocator);
++}
++
++GList*
++g_list_alloc (void)
++{
++ GList *list;
++
++ G_LOCK (current_allocator);
++ if (!current_allocator)
++ {
++ GAllocator *allocator = g_allocator_new ("GLib default GList allocator",
++ 128);
++ g_list_validate_allocator (allocator);
++ allocator->last = NULL;
++ current_allocator = allocator;
++ }
++ if (!current_allocator->free_lists)
++ {
++ list = g_chunk_new (GList, current_allocator->mem_chunk);
++ list->data = NULL;
++ }
++ else
++ {
++ if (current_allocator->free_lists->data)
++ {
++ list = current_allocator->free_lists->data;
++ current_allocator->free_lists->data = list->next;
++ list->data = NULL;
++ }
++ else
++ {
++ list = current_allocator->free_lists;
++ current_allocator->free_lists = list->next;
++ }
++ }
++ G_UNLOCK (current_allocator);
++ list->next = NULL;
++ list->prev = NULL;
++
++ return list;
++}
++
++void
++g_list_free (GList *list)
++{
++ if (list)
++ {
++ list->data = list->next;
++ G_LOCK (current_allocator);
++ list->next = current_allocator->free_lists;
++ current_allocator->free_lists = list;
++ G_UNLOCK (current_allocator);
++ }
++}
++
++void
++g_list_free_1 (GList *list)
++{
++ if (list)
++ {
++ list->data = NULL;
++ G_LOCK (current_allocator);
++ list->next = current_allocator->free_lists;
++ current_allocator->free_lists = list;
++ G_UNLOCK (current_allocator);
++ }
++}
++
++GList*
++g_list_append (GList *list,
++ gpointer data)
++{
++ GList *new_list;
++ GList *last;
++
++ new_list = g_list_alloc ();
++ new_list->data = data;
++
++ if (list)
++ {
++ last = g_list_last (list);
++ /* g_assert (last != NULL); */
++ last->next = new_list;
++ new_list->prev = last;
++
++ return list;
++ }
++ else
++ return new_list;
++}
++
++GList*
++g_list_prepend (GList *list,
++ gpointer data)
++{
++ GList *new_list;
++
++ new_list = g_list_alloc ();
++ new_list->data = data;
++
++ if (list)
++ {
++ if (list->prev)
++ {
++ list->prev->next = new_list;
++ new_list->prev = list->prev;
++ }
++ list->prev = new_list;
++ new_list->next = list;
++ }
++
++ return new_list;
++}
++
++GList*
++g_list_insert (GList *list,
++ gpointer data,
++ gint position)
++{
++ GList *new_list;
++ GList *tmp_list;
++
++ if (position < 0)
++ return g_list_append (list, data);
++ else if (position == 0)
++ return g_list_prepend (list, data);
++
++ tmp_list = g_list_nth (list, position);
++ if (!tmp_list)
++ return g_list_append (list, data);
++
++ new_list = g_list_alloc ();
++ new_list->data = data;
++
++ if (tmp_list->prev)
++ {
++ tmp_list->prev->next = new_list;
++ new_list->prev = tmp_list->prev;
++ }
++ new_list->next = tmp_list;
++ tmp_list->prev = new_list;
++
++ if (tmp_list == list)
++ return new_list;
++ else
++ return list;
++}
++
++GList *
++g_list_concat (GList *list1, GList *list2)
++{
++ GList *tmp_list;
++
++ if (list2)
++ {
++ tmp_list = g_list_last (list1);
++ if (tmp_list)
++ tmp_list->next = list2;
++ else
++ list1 = list2;
++ list2->prev = tmp_list;
++ }
++
++ return list1;
++}
++
++GList*
++g_list_remove (GList *list,
++ gpointer data)
++{
++ GList *tmp;
++
++ tmp = list;
++ while (tmp)
++ {
++ if (tmp->data != data)
++ tmp = tmp->next;
++ else
++ {
++ if (tmp->prev)
++ tmp->prev->next = tmp->next;
++ if (tmp->next)
++ tmp->next->prev = tmp->prev;
++
++ if (list == tmp)
++ list = list->next;
++
++ g_list_free_1 (tmp);
++
++ break;
++ }
++ }
++ return list;
++}
++
++GList*
++g_list_remove_link (GList *list,
++ GList *link)
++{
++ if (link)
++ {
++ if (link->prev)
++ link->prev->next = link->next;
++ if (link->next)
++ link->next->prev = link->prev;
++
++ if (link == list)
++ list = list->next;
++
++ link->next = NULL;
++ link->prev = NULL;
++ }
++
++ return list;
++}
++
++GList*
++g_list_copy (GList *list)
++{
++ GList *new_list = NULL;
++
++ if (list)
++ {
++ GList *last;
++
++ new_list = g_list_alloc ();
++ new_list->data = list->data;
++ last = new_list;
++ list = list->next;
++ while (list)
++ {
++ last->next = g_list_alloc ();
++ last->next->prev = last;
++ last = last->next;
++ last->data = list->data;
++ list = list->next;
++ }
++ }
++
++ return new_list;
++}
++
++GList*
++g_list_reverse (GList *list)
++{
++ GList *last;
++
++ last = NULL;
++ while (list)
++ {
++ last = list;
++ list = last->next;
++ last->next = last->prev;
++ last->prev = list;
++ }
++
++ return last;
++}
++
++GList*
++g_list_nth (GList *list,
++ guint n)
++{
++ while ((n-- > 0) && list)
++ list = list->next;
++
++ return list;
++}
++
++gpointer
++g_list_nth_data (GList *list,
++ guint n)
++{
++ while ((n-- > 0) && list)
++ list = list->next;
++
++ return list ? list->data : NULL;
++}
++
++GList*
++g_list_find (GList *list,
++ gpointer data)
++{
++ while (list)
++ {
++ if (list->data == data)
++ break;
++ list = list->next;
++ }
++
++ return list;
++}
++
++GList*
++g_list_find_custom (GList *list,
++ gpointer data,
++ GCompareFunc func)
++{
++ g_return_val_if_fail (func != NULL, list);
++
++ while (list)
++ {
++ if (! func (list->data, data))
++ return list;
++ list = list->next;
++ }
++
++ return NULL;
++}
++
++
++gint
++g_list_position (GList *list,
++ GList *link)
++{
++ gint i;
++
++ i = 0;
++ while (list)
++ {
++ if (list == link)
++ return i;
++ i++;
++ list = list->next;
++ }
++
++ return -1;
++}
++
++gint
++g_list_index (GList *list,
++ gpointer data)
++{
++ gint i;
++
++ i = 0;
++ while (list)
++ {
++ if (list->data == data)
++ return i;
++ i++;
++ list = list->next;
++ }
++
++ return -1;
++}
++
++GList*
++g_list_last (GList *list)
++{
++ if (list)
++ {
++ while (list->next)
++ list = list->next;
++ }
++
++ return list;
++}
++
++GList*
++g_list_first (GList *list)
++{
++ if (list)
++ {
++ while (list->prev)
++ list = list->prev;
++ }
++
++ return list;
++}
++
++guint
++g_list_length (GList *list)
++{
++ guint length;
++
++ length = 0;
++ while (list)
++ {
++ length++;
++ list = list->next;
++ }
++
++ return length;
++}
++
++void
++g_list_foreach (GList *list,
++ GFunc func,
++ gpointer user_data)
++{
++ while (list)
++ {
++ (*func) (list->data, user_data);
++ list = list->next;
++ }
++}
++
++
++GList*
++g_list_insert_sorted (GList *list,
++ gpointer data,
++ GCompareFunc func)
++{
++ GList *tmp_list = list;
++ GList *new_list;
++ gint cmp;
++
++ g_return_val_if_fail (func != NULL, list);
++
++ if (!list)
++ {
++ new_list = g_list_alloc();
++ new_list->data = data;
++ return new_list;
++ }
++
++ cmp = (*func) (data, tmp_list->data);
++
++ while ((tmp_list->next) && (cmp > 0))
++ {
++ tmp_list = tmp_list->next;
++ cmp = (*func) (data, tmp_list->data);
++ }
++
++ new_list = g_list_alloc();
++ new_list->data = data;
++
++ if ((!tmp_list->next) && (cmp > 0))
++ {
++ tmp_list->next = new_list;
++ new_list->prev = tmp_list;
++ return list;
++ }
++
++ if (tmp_list->prev)
++ {
++ tmp_list->prev->next = new_list;
++ new_list->prev = tmp_list->prev;
++ }
++ new_list->next = tmp_list;
++ tmp_list->prev = new_list;
++
++ if (tmp_list == list)
++ return new_list;
++ else
++ return list;
++}
++
++static GList *
++g_list_sort_merge (GList *l1,
++ GList *l2,
++ GCompareFunc compare_func)
++{
++ GList list, *l, *lprev;
++
++ l = &list;
++ lprev = NULL;
++
++ while (l1 && l2)
++ {
++ if (compare_func (l1->data, l2->data) < 0)
++ {
++ l->next = l1;
++ l = l->next;
++ l->prev = lprev;
++ lprev = l;
++ l1 = l1->next;
++ }
++ else
++ {
++ l->next = l2;
++ l = l->next;
++ l->prev = lprev;
++ lprev = l;
++ l2 = l2->next;
++ }
++ }
++ l->next = l1 ? l1 : l2;
++ l->next->prev = l;
++
++ return list.next;
++}
++
++GList*
++g_list_sort (GList *list,
++ GCompareFunc compare_func)
++{
++ GList *l1, *l2;
++
++ if (!list)
++ return NULL;
++ if (!list->next)
++ return list;
++
++ l1 = list;
++ l2 = list->next;
++
++ while ((l2 = l2->next) != NULL)
++ {
++ if ((l2 = l2->next) == NULL)
++ break;
++ l1 = l1->next;
++ }
++ l2 = l1->next;
++ l1->next = NULL;
++
++ return g_list_sort_merge (g_list_sort (list, compare_func),
++ g_list_sort (l2, compare_func),
++ compare_func);
++}
++
++GList*
++g_list_sort2 (GList *list,
++ GCompareFunc compare_func)
++{
++ GSList *runs = NULL;
++ GList *tmp;
++
++ /* Degenerate case. */
++ if (!list) return NULL;
++
++ /* Assume: list = [12,2,4,11,2,4,6,1,1,12]. */
++ for (tmp = list; tmp; )
++ {
++ GList *tmp2;
++ for (tmp2 = tmp;
++ tmp2->next && compare_func (tmp2->data, tmp2->next->data) <= 0;
++ tmp2 = tmp2->next)
++ /* Nothing */;
++ runs = g_slist_append (runs, tmp);
++ tmp = tmp2->next;
++ tmp2->next = NULL;
++ }
++ /* Now: runs = [[12],[2,4,11],[2,4,6],[1,1,12]]. */
++
++ while (runs->next)
++ {
++ /* We have more than one run. Merge pairwise. */
++ GSList *dst, *src, *dstprev = NULL;
++ dst = src = runs;
++ while (src && src->next)
++ {
++ dst->data = g_list_sort_merge (src->data,
++ src->next->data,
++ compare_func);
++ dstprev = dst;
++ dst = dst->next;
++ src = src->next->next;
++ }
++
++ /* If number of runs was odd, just keep the last. */
++ if (src)
++ {
++ dst->data = src->data;
++ dstprev = dst;
++ dst = dst->next;
++ }
++
++ dstprev->next = NULL;
++ g_slist_free (dst);
++ }
++
++ /* After 1st loop: runs = [[2,4,11,12],[1,1,2,4,6,12]]. */
++ /* After 2nd loop: runs = [[1,1,2,2,4,4,6,11,12,12]]. */
++
++ list = runs->data;
++ g_slist_free (runs);
++ return list;
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gmem.c linux-2.4.1-korbit/net/korbit/kglib/gmem.c
+--- linux-2.4.1/net/korbit/kglib/gmem.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gmem.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,767 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ *
++ * Mutilated on 10/22/00 by Fredrik and Chris
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdlib.h>
++#include <string.h>
++#include "glib.h"
++
++#define MEM_PROFILE_TABLE_SIZE 8192
++#define ENTER_MEM_CHUNK_ROUTINE()
++#define LEAVE_MEM_CHUNK_ROUTINE()
++
++/*
++ * This library can check for some attempts to do illegal things to
++ * memory (ENABLE_MEM_CHECK), and can do profiling
++ * (ENABLE_MEM_PROFILE). Both features are implemented by storing
++ * words before the start of the memory chunk.
++ *
++ * The first, at offset -2*SIZEOF_LONG, is used only if
++ * ENABLE_MEM_CHECK is set, and stores 0 after the memory has been
++ * allocated and 1 when it has been freed. The second, at offset
++ * -SIZEOF_LONG, is used if either flag is set and stores the size of
++ * the block.
++ *
++ * The MEM_CHECK flag is checked when memory is realloc'd and free'd,
++ * and it can be explicitly checked before using a block by calling
++ * g_mem_check().
++ */
++
++#define MEM_AREA_SIZE 4L
++
++#define MEM_ALIGN sizeof(long)
++
++
++typedef struct _GFreeAtom GFreeAtom;
++typedef struct _GMemArea GMemArea;
++typedef struct _GRealMemChunk GRealMemChunk;
++
++struct _GFreeAtom
++{
++ GFreeAtom *next;
++};
++
++struct _GMemArea
++{
++ GMemArea *next; /* the next mem area */
++ GMemArea *prev; /* the previous mem area */
++ gulong index; /* the current index into the "mem" array */
++ gulong free; /* the number of free bytes in this mem area */
++ gulong allocated; /* the number of atoms allocated from this area */
++ gulong mark; /* is this mem area marked for deletion */
++ gchar mem[MEM_AREA_SIZE]; /* the mem array from which atoms get allocated
++ * the actual size of this array is determined by
++ * the mem chunk "area_size". ANSI says that it
++ * must be declared to be the maximum size it
++ * can possibly be (even though the actual size
++ * may be less).
++ */
++};
++
++struct _GRealMemChunk
++{
++ gchar *name; /* name of this MemChunk...used for debugging output */
++ gint type; /* the type of MemChunk: ALLOC_ONLY or ALLOC_AND_FREE */
++ gint num_mem_areas; /* the number of memory areas */
++ gint num_marked_areas; /* the number of areas marked for deletion */
++ guint atom_size; /* the size of an atom */
++ gulong area_size; /* the size of a memory area */
++ GMemArea *mem_area; /* the current memory area */
++ GMemArea *mem_areas; /* a list of all the mem areas owned by this chunk */
++ GMemArea *free_mem_area; /* the free area...which is about to be destroyed */
++ GFreeAtom *free_atoms; /* the free atoms list */
++ GTree *mem_tree; /* tree of mem areas sorted by memory address */
++ GRealMemChunk *next; /* pointer to the next chunk */
++ GRealMemChunk *prev; /* pointer to the previous chunk */
++};
++
++
++static gulong g_mem_chunk_compute_size (gulong size,
++ gulong min_size);
++static gint g_mem_chunk_area_compare (GMemArea *a,
++ GMemArea *b);
++static gint g_mem_chunk_area_search (GMemArea *a,
++ gchar *addr);
++
++
++/* here we can't use StaticMutexes, as they depend upon a working
++ * g_malloc, the same holds true for StaticPrivate */
++#ifndef __KORBIT__
++static GMutex* mem_chunks_lock = NULL;
++#endif /* !__KORBIT__ */
++static GRealMemChunk *mem_chunks = NULL;
++
++
++gpointer
++g_malloc (gulong size)
++{
++ gpointer p;
++
++ if (size == 0)
++ return NULL;
++
++ p = (gpointer) malloc (size);
++ if (!p)
++ g_error ("could not allocate %ld bytes", size);
++
++ return p;
++}
++
++gpointer
++g_malloc0 (gulong size)
++{
++ gpointer p;
++
++ if (size == 0)
++ return NULL;
++
++ p = (gpointer) calloc (size, 1);
++ if (!p)
++ g_error ("could not allocate %ld bytes", size);
++
++ return p;
++}
++
++gpointer
++g_realloc (gpointer mem,
++ gulong size)
++{
++ gpointer p;
++
++ if (size == 0)
++ {
++ g_free (mem);
++
++ return NULL;
++ }
++
++ if (!mem)
++ {
++#ifdef REALLOC_0_WORKS
++ p = (gpointer) realloc (NULL, size);
++#else /* !REALLOC_0_WORKS */
++ p = (gpointer) malloc (size);
++#endif /* !REALLOC_0_WORKS */
++ }
++ else
++ {
++ p = (gpointer) realloc (mem, size);
++ }
++
++ if (!p)
++ g_error ("could not reallocate %lu bytes", (gulong) size);
++
++ return p;
++}
++
++void
++g_free (gpointer mem)
++{
++ if (mem)
++ {
++ free (mem);
++ }
++}
++
++
++void
++g_mem_profile (void)
++{
++}
++
++void
++g_mem_check (gpointer mem)
++{
++}
++
++GMemChunk*
++g_mem_chunk_new (gchar *name,
++ gint atom_size,
++ gulong area_size,
++ gint type)
++{
++ GRealMemChunk *mem_chunk;
++ gulong rarea_size;
++
++ g_return_val_if_fail (atom_size > 0, NULL);
++ g_return_val_if_fail (area_size >= atom_size, NULL);
++
++ ENTER_MEM_CHUNK_ROUTINE();
++
++ area_size = (area_size + atom_size - 1) / atom_size;
++ area_size *= atom_size;
++
++ mem_chunk = g_new (struct _GRealMemChunk, 1);
++ mem_chunk->name = name;
++ mem_chunk->type = type;
++ mem_chunk->num_mem_areas = 0;
++ mem_chunk->num_marked_areas = 0;
++ mem_chunk->mem_area = NULL;
++ mem_chunk->free_mem_area = NULL;
++ mem_chunk->free_atoms = NULL;
++ mem_chunk->mem_tree = NULL;
++ mem_chunk->mem_areas = NULL;
++ mem_chunk->atom_size = atom_size;
++
++ if (mem_chunk->type == G_ALLOC_AND_FREE)
++ mem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare);
++
++ if (mem_chunk->atom_size % MEM_ALIGN)
++ mem_chunk->atom_size += MEM_ALIGN - (mem_chunk->atom_size % MEM_ALIGN);
++
++ rarea_size = area_size + sizeof (GMemArea) - MEM_AREA_SIZE;
++ rarea_size = g_mem_chunk_compute_size (rarea_size, atom_size + sizeof (GMemArea) - MEM_AREA_SIZE);
++ mem_chunk->area_size = rarea_size - (sizeof (GMemArea) - MEM_AREA_SIZE);
++
++#ifndef __KORBIT__
++ g_mutex_lock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ mem_chunk->next = mem_chunks;
++ mem_chunk->prev = NULL;
++ if (mem_chunks)
++ mem_chunks->prev = mem_chunk;
++ mem_chunks = mem_chunk;
++#ifndef __KORBIT__
++ g_mutex_unlock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++
++ LEAVE_MEM_CHUNK_ROUTINE();
++
++ return ((GMemChunk*) mem_chunk);
++}
++
++void
++g_mem_chunk_destroy (GMemChunk *mem_chunk)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *mem_areas;
++ GMemArea *temp_area;
++
++ g_return_if_fail (mem_chunk != NULL);
++
++ ENTER_MEM_CHUNK_ROUTINE();
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ mem_areas = rmem_chunk->mem_areas;
++ while (mem_areas)
++ {
++ temp_area = mem_areas;
++ mem_areas = mem_areas->next;
++ g_free (temp_area);
++ }
++
++ if (rmem_chunk->next)
++ rmem_chunk->next->prev = rmem_chunk->prev;
++ if (rmem_chunk->prev)
++ rmem_chunk->prev->next = rmem_chunk->next;
++
++#ifndef __KORBIT__
++ g_mutex_lock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ if (rmem_chunk == mem_chunks)
++ mem_chunks = mem_chunks->next;
++#ifndef __KORBIT__
++ g_mutex_unlock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ g_tree_destroy (rmem_chunk->mem_tree);
++
++ g_free (rmem_chunk);
++
++ LEAVE_MEM_CHUNK_ROUTINE();
++}
++
++gpointer
++g_mem_chunk_alloc (GMemChunk *mem_chunk)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *temp_area;
++ gpointer mem;
++
++ ENTER_MEM_CHUNK_ROUTINE();
++
++ g_return_val_if_fail (mem_chunk != NULL, NULL);
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ while (rmem_chunk->free_atoms)
++ {
++ /* Get the first piece of memory on the "free_atoms" list.
++ * We can go ahead and destroy the list node we used to keep
++ * track of it with and to update the "free_atoms" list to
++ * point to its next element.
++ */
++ mem = rmem_chunk->free_atoms;
++ rmem_chunk->free_atoms = rmem_chunk->free_atoms->next;
++
++ /* Determine which area this piece of memory is allocated from */
++ temp_area = g_tree_search (rmem_chunk->mem_tree,
++ (GSearchFunc) g_mem_chunk_area_search,
++ mem);
++
++ /* If the area has been marked, then it is being destroyed.
++ * (ie marked to be destroyed).
++ * We check to see if all of the segments on the free list that
++ * reference this area have been removed. This occurs when
++ * the ammount of free memory is less than the allocatable size.
++ * If the chunk should be freed, then we place it in the "free_mem_area".
++ * This is so we make sure not to free the mem area here and then
++ * allocate it again a few lines down.
++ * If we don't allocate a chunk a few lines down then the "free_mem_area"
++ * will be freed.
++ * If there is already a "free_mem_area" then we'll just free this mem area.
++ */
++ if (temp_area->mark)
++ {
++ /* Update the "free" memory available in that area */
++ temp_area->free += rmem_chunk->atom_size;
++
++ if (temp_area->free == rmem_chunk->area_size)
++ {
++ if (temp_area == rmem_chunk->mem_area)
++ rmem_chunk->mem_area = NULL;
++
++ if (rmem_chunk->free_mem_area)
++ {
++ rmem_chunk->num_mem_areas -= 1;
++
++ if (temp_area->next)
++ temp_area->next->prev = temp_area->prev;
++ if (temp_area->prev)
++ temp_area->prev->next = temp_area->next;
++ if (temp_area == rmem_chunk->mem_areas)
++ rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
++
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ g_tree_remove (rmem_chunk->mem_tree, temp_area);
++ g_free (temp_area);
++ }
++ else
++ rmem_chunk->free_mem_area = temp_area;
++
++ rmem_chunk->num_marked_areas -= 1;
++ }
++ }
++ else
++ {
++ /* Update the number of allocated atoms count.
++ */
++ temp_area->allocated += 1;
++
++ /* The area wasn't marked...return the memory
++ */
++ goto outa_here;
++ }
++ }
++
++ /* If there isn't a current mem area or the current mem area is out of space
++ * then allocate a new mem area. We'll first check and see if we can use
++ * the "free_mem_area". Otherwise we'll just malloc the mem area.
++ */
++ if ((!rmem_chunk->mem_area) ||
++ ((rmem_chunk->mem_area->index + rmem_chunk->atom_size) > rmem_chunk->area_size))
++ {
++ if (rmem_chunk->free_mem_area)
++ {
++ rmem_chunk->mem_area = rmem_chunk->free_mem_area;
++ rmem_chunk->free_mem_area = NULL;
++ }
++ else
++ {
++ rmem_chunk->mem_area = (GMemArea*) g_malloc (sizeof (GMemArea) -
++ MEM_AREA_SIZE +
++ rmem_chunk->area_size);
++
++ rmem_chunk->num_mem_areas += 1;
++ rmem_chunk->mem_area->next = rmem_chunk->mem_areas;
++ rmem_chunk->mem_area->prev = NULL;
++
++ if (rmem_chunk->mem_areas)
++ rmem_chunk->mem_areas->prev = rmem_chunk->mem_area;
++ rmem_chunk->mem_areas = rmem_chunk->mem_area;
++
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ g_tree_insert (rmem_chunk->mem_tree, rmem_chunk->mem_area, rmem_chunk->mem_area);
++ }
++
++ rmem_chunk->mem_area->index = 0;
++ rmem_chunk->mem_area->free = rmem_chunk->area_size;
++ rmem_chunk->mem_area->allocated = 0;
++ rmem_chunk->mem_area->mark = 0;
++ }
++
++ /* Get the memory and modify the state variables appropriately.
++ */
++ mem = (gpointer) &rmem_chunk->mem_area->mem[rmem_chunk->mem_area->index];
++ rmem_chunk->mem_area->index += rmem_chunk->atom_size;
++ rmem_chunk->mem_area->free -= rmem_chunk->atom_size;
++ rmem_chunk->mem_area->allocated += 1;
++
++outa_here:
++
++ LEAVE_MEM_CHUNK_ROUTINE();
++
++ return mem;
++}
++
++gpointer
++g_mem_chunk_alloc0 (GMemChunk *mem_chunk)
++{
++ gpointer mem;
++
++ mem = g_mem_chunk_alloc (mem_chunk);
++ if (mem)
++ {
++ GRealMemChunk *rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ memset (mem, 0, rmem_chunk->atom_size);
++ }
++
++ return mem;
++}
++
++void
++g_mem_chunk_free (GMemChunk *mem_chunk,
++ gpointer mem)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *temp_area;
++ GFreeAtom *free_atom;
++
++ g_return_if_fail (mem_chunk != NULL);
++ g_return_if_fail (mem != NULL);
++
++ ENTER_MEM_CHUNK_ROUTINE();
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ /* Don't do anything if this is an ALLOC_ONLY chunk
++ */
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ {
++ /* Place the memory on the "free_atoms" list
++ */
++ free_atom = (GFreeAtom*) mem;
++ free_atom->next = rmem_chunk->free_atoms;
++ rmem_chunk->free_atoms = free_atom;
++
++ temp_area = g_tree_search (rmem_chunk->mem_tree,
++ (GSearchFunc) g_mem_chunk_area_search,
++ mem);
++
++ temp_area->allocated -= 1;
++
++ if (temp_area->allocated == 0)
++ {
++ temp_area->mark = 1;
++ rmem_chunk->num_marked_areas += 1;
++ }
++ }
++
++ LEAVE_MEM_CHUNK_ROUTINE();
++}
++
++/* This doesn't free the free_area if there is one */
++void
++g_mem_chunk_clean (GMemChunk *mem_chunk)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *mem_area;
++ GFreeAtom *prev_free_atom;
++ GFreeAtom *temp_free_atom;
++ gpointer mem;
++
++ g_return_if_fail (mem_chunk != NULL);
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ {
++ prev_free_atom = NULL;
++ temp_free_atom = rmem_chunk->free_atoms;
++
++ while (temp_free_atom)
++ {
++ mem = (gpointer) temp_free_atom;
++
++ mem_area = g_tree_search (rmem_chunk->mem_tree,
++ (GSearchFunc) g_mem_chunk_area_search,
++ mem);
++
++ /* If this mem area is marked for destruction then delete the
++ * area and list node and decrement the free mem.
++ */
++ if (mem_area->mark)
++ {
++ if (prev_free_atom)
++ prev_free_atom->next = temp_free_atom->next;
++ else
++ rmem_chunk->free_atoms = temp_free_atom->next;
++ temp_free_atom = temp_free_atom->next;
++
++ mem_area->free += rmem_chunk->atom_size;
++ if (mem_area->free == rmem_chunk->area_size)
++ {
++ rmem_chunk->num_mem_areas -= 1;
++ rmem_chunk->num_marked_areas -= 1;
++
++ if (mem_area->next)
++ mem_area->next->prev = mem_area->prev;
++ if (mem_area->prev)
++ mem_area->prev->next = mem_area->next;
++ if (mem_area == rmem_chunk->mem_areas)
++ rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
++ if (mem_area == rmem_chunk->mem_area)
++ rmem_chunk->mem_area = NULL;
++
++ if (rmem_chunk->type == G_ALLOC_AND_FREE)
++ g_tree_remove (rmem_chunk->mem_tree, mem_area);
++ g_free (mem_area);
++ }
++ }
++ else
++ {
++ prev_free_atom = temp_free_atom;
++ temp_free_atom = temp_free_atom->next;
++ }
++ }
++ }
++}
++
++void
++g_mem_chunk_reset (GMemChunk *mem_chunk)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *mem_areas;
++ GMemArea *temp_area;
++
++ g_return_if_fail (mem_chunk != NULL);
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++
++ mem_areas = rmem_chunk->mem_areas;
++ rmem_chunk->num_mem_areas = 0;
++ rmem_chunk->mem_areas = NULL;
++ rmem_chunk->mem_area = NULL;
++
++ while (mem_areas)
++ {
++ temp_area = mem_areas;
++ mem_areas = mem_areas->next;
++ g_free (temp_area);
++ }
++
++ rmem_chunk->free_atoms = NULL;
++
++ if (rmem_chunk->mem_tree)
++ g_tree_destroy (rmem_chunk->mem_tree);
++ rmem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare);
++}
++
++void
++g_mem_chunk_print (GMemChunk *mem_chunk)
++{
++ GRealMemChunk *rmem_chunk;
++ GMemArea *mem_areas;
++ gulong mem;
++
++ g_return_if_fail (mem_chunk != NULL);
++
++ rmem_chunk = (GRealMemChunk*) mem_chunk;
++ mem_areas = rmem_chunk->mem_areas;
++ mem = 0;
++
++ while (mem_areas)
++ {
++ mem += rmem_chunk->area_size - mem_areas->free;
++ mem_areas = mem_areas->next;
++ }
++
++ g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
++ "%s: %ld bytes using %d mem areas",
++ rmem_chunk->name, mem, rmem_chunk->num_mem_areas);
++}
++
++void
++g_mem_chunk_info (void)
++{
++ GRealMemChunk *mem_chunk;
++ gint count;
++
++ count = 0;
++#ifndef __KORBIT__
++ g_mutex_lock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ mem_chunk = mem_chunks;
++ while (mem_chunk)
++ {
++ count += 1;
++ mem_chunk = mem_chunk->next;
++ }
++#ifndef __KORBIT__
++ g_mutex_unlock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks", count);
++
++#ifndef __KORBIT__
++ g_mutex_lock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ mem_chunk = mem_chunks;
++#ifndef __KORBIT__
++ g_mutex_unlock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++
++ while (mem_chunk)
++ {
++ g_mem_chunk_print ((GMemChunk*) mem_chunk);
++ mem_chunk = mem_chunk->next;
++ }
++}
++
++void
++g_blow_chunks (void)
++{
++ GRealMemChunk *mem_chunk;
++
++#ifndef __KORBIT__
++ g_mutex_lock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ mem_chunk = mem_chunks;
++#ifndef __KORBIT__
++ g_mutex_unlock (mem_chunks_lock);
++#endif /* !__KORBIT__ */
++ while (mem_chunk)
++ {
++ g_mem_chunk_clean ((GMemChunk*) mem_chunk);
++ mem_chunk = mem_chunk->next;
++ }
++}
++
++
++static gulong
++g_mem_chunk_compute_size (gulong size,
++ gulong min_size)
++{
++ gulong power_of_2;
++ gulong lower, upper;
++
++ power_of_2 = 16;
++ while (power_of_2 < size)
++ power_of_2 <<= 1;
++
++ lower = power_of_2 >> 1;
++ upper = power_of_2;
++
++ if (size - lower < upper - size && lower >= min_size)
++ return lower;
++ else
++ return upper;
++}
++
++static gint
++g_mem_chunk_area_compare (GMemArea *a,
++ GMemArea *b)
++{
++ if (a->mem > b->mem)
++ return 1;
++ else if (a->mem < b->mem)
++ return -1;
++ return 0;
++}
++
++static gint
++g_mem_chunk_area_search (GMemArea *a,
++ gchar *addr)
++{
++ if (a->mem <= addr)
++ {
++ if (addr < &a->mem[a->index])
++ return 0;
++ return 1;
++ }
++ return -1;
++}
++
++/* generic allocators
++ */
++struct _GAllocator /* from gmem.c */
++{
++ gchar *name;
++ guint16 n_preallocs;
++ guint is_unused : 1;
++ guint type : 4;
++ GAllocator *last;
++ GMemChunk *mem_chunk;
++ gpointer dummy; /* implementation specific */
++};
++
++GAllocator*
++g_allocator_new (const gchar *name,
++ guint n_preallocs)
++{
++ GAllocator *allocator;
++
++ g_return_val_if_fail (name != NULL, NULL);
++
++ allocator = g_new0 (GAllocator, 1);
++ allocator->name = g_strdup (name);
++ allocator->n_preallocs = CLAMP (n_preallocs, 1, 65535);
++ allocator->is_unused = TRUE;
++ allocator->type = 0;
++ allocator->last = NULL;
++ allocator->mem_chunk = NULL;
++ allocator->dummy = NULL;
++
++ return allocator;
++}
++
++void
++g_allocator_free (GAllocator *allocator)
++{
++ g_return_if_fail (allocator != NULL);
++ g_return_if_fail (allocator->is_unused == TRUE);
++
++ g_free (allocator->name);
++ if (allocator->mem_chunk)
++ g_mem_chunk_destroy (allocator->mem_chunk);
++
++ g_free (allocator);
++}
++
++void
++g_mem_init (void)
++{
++#ifndef __KORBIT__
++ mem_chunks_lock = g_mutex_new();
++#endif /* !__KORBIT__ */
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gprimes.c linux-2.4.1-korbit/net/korbit/kglib/gprimes.c
+--- linux-2.4.1/net/korbit/kglib/gprimes.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gprimes.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,79 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include "glib.h"
++
++static const guint g_primes[] =
++{
++ 11,
++ 19,
++ 37,
++ 73,
++ 109,
++ 163,
++ 251,
++ 367,
++ 557,
++ 823,
++ 1237,
++ 1861,
++ 2777,
++ 4177,
++ 6247,
++ 9371,
++ 14057,
++ 21089,
++ 31627,
++ 47431,
++ 71143,
++ 106721,
++ 160073,
++ 240101,
++ 360163,
++ 540217,
++ 810343,
++ 1215497,
++ 1823231,
++ 2734867,
++ 4102283,
++ 6153409,
++ 9230113,
++ 13845163,
++};
++
++static const guint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
++
++guint
++g_spaced_primes_closest (guint num)
++{
++ gint i;
++
++ for (i = 0; i < g_nprimes; i++)
++ if (g_primes[i] > num)
++ return g_primes[i];
++
++ return g_primes[g_nprimes - 1];
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gslist.c linux-2.4.1-korbit/net/korbit/kglib/gslist.c
+--- linux-2.4.1/net/korbit/kglib/gslist.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gslist.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,591 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include "glib.h"
++
++
++struct _GAllocator /* from gmem.c */
++{
++ gchar *name;
++ guint16 n_preallocs;
++ guint is_unused : 1;
++ guint type : 4;
++ GAllocator *last;
++ GMemChunk *mem_chunk;
++ GSList *free_lists; /* implementation specific */
++};
++
++G_LOCK_DEFINE_STATIC (current_allocator);
++static GAllocator *current_allocator = NULL;
++
++/* HOLDS: current_allocator_lock */
++static void
++g_slist_validate_allocator (GAllocator *allocator)
++{
++ g_return_if_fail (allocator != NULL);
++ g_return_if_fail (allocator->is_unused == TRUE);
++
++ if (allocator->type != G_ALLOCATOR_SLIST)
++ {
++ allocator->type = G_ALLOCATOR_SLIST;
++ if (allocator->mem_chunk)
++ {
++ g_mem_chunk_destroy (allocator->mem_chunk);
++ allocator->mem_chunk = NULL;
++ }
++ }
++
++ if (!allocator->mem_chunk)
++ {
++ allocator->mem_chunk = g_mem_chunk_new (allocator->name,
++ sizeof (GSList),
++ sizeof (GSList) * allocator->n_preallocs,
++ G_ALLOC_ONLY);
++ allocator->free_lists = NULL;
++ }
++
++ allocator->is_unused = FALSE;
++}
++
++void
++g_slist_push_allocator (GAllocator *allocator)
++{
++ G_LOCK (current_allocator);
++ g_slist_validate_allocator (allocator);
++ allocator->last = current_allocator;
++ current_allocator = allocator;
++ G_UNLOCK (current_allocator);
++}
++
++void
++g_slist_pop_allocator (void)
++{
++ G_LOCK (current_allocator);
++ if (current_allocator)
++ {
++ GAllocator *allocator;
++
++ allocator = current_allocator;
++ current_allocator = allocator->last;
++ allocator->last = NULL;
++ allocator->is_unused = TRUE;
++ }
++ G_UNLOCK (current_allocator);
++}
++
++GSList*
++g_slist_alloc (void)
++{
++ GSList *list;
++
++ G_LOCK (current_allocator);
++ if (!current_allocator)
++ {
++ GAllocator *allocator = g_allocator_new ("GLib default GSList allocator",
++ 128);
++ g_slist_validate_allocator (allocator);
++ allocator->last = NULL;
++ current_allocator = allocator;
++ }
++ if (!current_allocator->free_lists)
++ {
++ list = g_chunk_new (GSList, current_allocator->mem_chunk);
++ list->data = NULL;
++ }
++ else
++ {
++ if (current_allocator->free_lists->data)
++ {
++ list = current_allocator->free_lists->data;
++ current_allocator->free_lists->data = list->next;
++ list->data = NULL;
++ }
++ else
++ {
++ list = current_allocator->free_lists;
++ current_allocator->free_lists = list->next;
++ }
++ }
++ G_UNLOCK (current_allocator);
++
++ list->next = NULL;
++
++ return list;
++}
++
++void
++g_slist_free (GSList *list)
++{
++ if (list)
++ {
++ list->data = list->next;
++ G_LOCK (current_allocator);
++ list->next = current_allocator->free_lists;
++ current_allocator->free_lists = list;
++ G_UNLOCK (current_allocator);
++ }
++}
++
++void
++g_slist_free_1 (GSList *list)
++{
++ if (list)
++ {
++ list->data = NULL;
++ G_LOCK (current_allocator);
++ list->next = current_allocator->free_lists;
++ current_allocator->free_lists = list;
++ G_UNLOCK (current_allocator);
++ }
++}
++
++GSList*
++g_slist_append (GSList *list,
++ gpointer data)
++{
++ GSList *new_list;
++ GSList *last;
++
++ new_list = g_slist_alloc ();
++ new_list->data = data;
++
++ if (list)
++ {
++ last = g_slist_last (list);
++ /* g_assert (last != NULL); */
++ last->next = new_list;
++
++ return list;
++ }
++ else
++ return new_list;
++}
++
++GSList*
++g_slist_prepend (GSList *list,
++ gpointer data)
++{
++ GSList *new_list;
++
++ new_list = g_slist_alloc ();
++ new_list->data = data;
++ new_list->next = list;
++
++ return new_list;
++}
++
++GSList*
++g_slist_insert (GSList *list,
++ gpointer data,
++ gint position)
++{
++ GSList *prev_list;
++ GSList *tmp_list;
++ GSList *new_list;
++
++ if (position < 0)
++ return g_slist_append (list, data);
++ else if (position == 0)
++ return g_slist_prepend (list, data);
++
++ new_list = g_slist_alloc ();
++ new_list->data = data;
++
++ if (!list)
++ return new_list;
++
++ prev_list = NULL;
++ tmp_list = list;
++
++ while ((position-- > 0) && tmp_list)
++ {
++ prev_list = tmp_list;
++ tmp_list = tmp_list->next;
++ }
++
++ if (prev_list)
++ {
++ new_list->next = prev_list->next;
++ prev_list->next = new_list;
++ }
++ else
++ {
++ new_list->next = list;
++ list = new_list;
++ }
++
++ return list;
++}
++
++GSList *
++g_slist_concat (GSList *list1, GSList *list2)
++{
++ if (list2)
++ {
++ if (list1)
++ g_slist_last (list1)->next = list2;
++ else
++ list1 = list2;
++ }
++
++ return list1;
++}
++
++GSList*
++g_slist_remove (GSList *list,
++ gpointer data)
++{
++ GSList *tmp;
++ GSList *prev;
++
++ prev = NULL;
++ tmp = list;
++
++ while (tmp)
++ {
++ if (tmp->data == data)
++ {
++ if (prev)
++ prev->next = tmp->next;
++ if (list == tmp)
++ list = list->next;
++
++ tmp->next = NULL;
++ g_slist_free (tmp);
++
++ break;
++ }
++
++ prev = tmp;
++ tmp = tmp->next;
++ }
++
++ return list;
++}
++
++GSList*
++g_slist_remove_link (GSList *list,
++ GSList *link)
++{
++ GSList *tmp;
++ GSList *prev;
++
++ prev = NULL;
++ tmp = list;
++
++ while (tmp)
++ {
++ if (tmp == link)
++ {
++ if (prev)
++ prev->next = tmp->next;
++ if (list == tmp)
++ list = list->next;
++
++ tmp->next = NULL;
++ break;
++ }
++
++ prev = tmp;
++ tmp = tmp->next;
++ }
++
++ return list;
++}
++
++GSList*
++g_slist_copy (GSList *list)
++{
++ GSList *new_list = NULL;
++
++ if (list)
++ {
++ GSList *last;
++
++ new_list = g_slist_alloc ();
++ new_list->data = list->data;
++ last = new_list;
++ list = list->next;
++ while (list)
++ {
++ last->next = g_slist_alloc ();
++ last = last->next;
++ last->data = list->data;
++ list = list->next;
++ }
++ }
++
++ return new_list;
++}
++
++GSList*
++g_slist_reverse (GSList *list)
++{
++ GSList *prev = NULL;
++
++ while (list)
++ {
++ GSList *next = list->next;
++
++ list->next = prev;
++
++ prev = list;
++ list = next;
++ }
++
++ return prev;
++}
++
++GSList*
++g_slist_nth (GSList *list,
++ guint n)
++{
++ while ((n-- > 0) && list)
++ list = list->next;
++
++ return list;
++}
++
++gpointer
++g_slist_nth_data (GSList *list,
++ guint n)
++{
++ while ((n-- > 0) && list)
++ list = list->next;
++
++ return list ? list->data : NULL;
++}
++
++GSList*
++g_slist_find (GSList *list,
++ gpointer data)
++{
++ while (list)
++ {
++ if (list->data == data)
++ break;
++ list = list->next;
++ }
++
++ return list;
++}
++
++GSList*
++g_slist_find_custom (GSList *list,
++ gpointer data,
++ GCompareFunc func)
++{
++ g_return_val_if_fail (func != NULL, list);
++
++ while (list)
++ {
++ if (! func (list->data, data))
++ return list;
++ list = list->next;
++ }
++
++ return NULL;
++}
++
++gint
++g_slist_position (GSList *list,
++ GSList *link)
++{
++ gint i;
++
++ i = 0;
++ while (list)
++ {
++ if (list == link)
++ return i;
++ i++;
++ list = list->next;
++ }
++
++ return -1;
++}
++
++gint
++g_slist_index (GSList *list,
++ gpointer data)
++{
++ gint i;
++
++ i = 0;
++ while (list)
++ {
++ if (list->data == data)
++ return i;
++ i++;
++ list = list->next;
++ }
++
++ return -1;
++}
++
++GSList*
++g_slist_last (GSList *list)
++{
++ if (list)
++ {
++ while (list->next)
++ list = list->next;
++ }
++
++ return list;
++}
++
++guint
++g_slist_length (GSList *list)
++{
++ guint length;
++
++ length = 0;
++ while (list)
++ {
++ length++;
++ list = list->next;
++ }
++
++ return length;
++}
++
++void
++g_slist_foreach (GSList *list,
++ GFunc func,
++ gpointer user_data)
++{
++ while (list)
++ {
++ (*func) (list->data, user_data);
++ list = list->next;
++ }
++}
++
++GSList*
++g_slist_insert_sorted (GSList *list,
++ gpointer data,
++ GCompareFunc func)
++{
++ GSList *tmp_list = list;
++ GSList *prev_list = NULL;
++ GSList *new_list;
++ gint cmp;
++
++ g_return_val_if_fail (func != NULL, list);
++
++ if (!list)
++ {
++ new_list = g_slist_alloc();
++ new_list->data = data;
++ return new_list;
++ }
++
++ cmp = (*func) (data, tmp_list->data);
++
++ while ((tmp_list->next) && (cmp > 0))
++ {
++ prev_list = tmp_list;
++ tmp_list = tmp_list->next;
++ cmp = (*func) (data, tmp_list->data);
++ }
++
++ new_list = g_slist_alloc();
++ new_list->data = data;
++
++ if ((!tmp_list->next) && (cmp > 0))
++ {
++ tmp_list->next = new_list;
++ return list;
++ }
++
++ if (prev_list)
++ {
++ prev_list->next = new_list;
++ new_list->next = tmp_list;
++ return list;
++ }
++ else
++ {
++ new_list->next = list;
++ return new_list;
++ }
++}
++
++static GSList*
++g_slist_sort_merge (GSList *l1,
++ GSList *l2,
++ GCompareFunc compare_func)
++{
++ GSList list, *l;
++
++ l=&list;
++
++ while (l1 && l2)
++ {
++ if (compare_func(l1->data,l2->data) < 0)
++ {
++ l=l->next=l1;
++ l1=l1->next;
++ }
++ else
++ {
++ l=l->next=l2;
++ l2=l2->next;
++ }
++ }
++ l->next= l1 ? l1 : l2;
++
++ return list.next;
++}
++
++GSList*
++g_slist_sort (GSList *list,
++ GCompareFunc compare_func)
++{
++ GSList *l1, *l2;
++
++ if (!list)
++ return NULL;
++ if (!list->next)
++ return list;
++
++ l1 = list;
++ l2 = list->next;
++
++ while ((l2 = l2->next) != NULL)
++ {
++ if ((l2 = l2->next) == NULL)
++ break;
++ l1=l1->next;
++ }
++ l2 = l1->next;
++ l1->next = NULL;
++
++ return g_slist_sort_merge (g_slist_sort (list, compare_func),
++ g_slist_sort (l2, compare_func),
++ compare_func);
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gstrfuncs.c linux-2.4.1-korbit/net/korbit/kglib/gstrfuncs.c
+--- linux-2.4.1/net/korbit/kglib/gstrfuncs.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gstrfuncs.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,1308 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdarg.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <locale.h>
++#include <ctype.h> /* For tolower() */
++#if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
++#include <signal.h>
++#endif
++#include "glib.h"
++/* do not include <unistd.h> in this place since it
++ * inteferes with g_strsignal() on some OSes
++ */
++
++gchar*
++g_strdup (const gchar *str) {
++ gchar *new_str;
++
++ if (str)
++ {
++ new_str = g_new (char, strlen (str) + 1);
++ strcpy (new_str, str);
++ }
++ else
++ new_str = NULL;
++
++ return new_str;
++}
++
++gpointer
++g_memdup (gconstpointer mem,
++ guint byte_size)
++{
++ gpointer new_mem;
++
++ if (mem)
++ {
++ new_mem = g_malloc (byte_size);
++ memcpy (new_mem, mem, byte_size);
++ }
++ else
++ new_mem = NULL;
++
++ return new_mem;
++}
++
++gchar*
++g_strndup (const gchar *str,
++ guint n)
++{
++ gchar *new_str;
++
++ if (str)
++ {
++ new_str = g_new (gchar, n + 1);
++ strncpy (new_str, str, n);
++ new_str[n] = '\0';
++ }
++ else
++ new_str = NULL;
++
++ return new_str;
++}
++
++gchar*
++g_strnfill (guint length,
++ gchar fill_char)
++{
++ register gchar *str, *s, *end;
++
++ str = g_new (gchar, length + 1);
++ s = str;
++ end = str + length;
++ while (s < end)
++ *(s++) = fill_char;
++ *s = 0;
++
++ return str;
++}
++
++gchar*
++g_strdup_vprintf (const gchar *format,
++ va_list args1)
++{
++ gchar *buffer;
++ va_list args2;
++
++ G_VA_COPY (args2, args1);
++
++ buffer = g_new (gchar, g_printf_string_upper_bound (format, args1));
++
++ vsprintf (buffer, format, args2);
++ va_end (args2);
++
++ return buffer;
++}
++
++gchar*
++g_strdup_printf (const gchar *format,
++ ...)
++{
++ gchar *buffer;
++ va_list args;
++
++ va_start (args, format);
++ buffer = g_strdup_vprintf (format, args);
++ va_end (args);
++
++ return buffer;
++}
++
++gchar*
++g_strconcat (const gchar *string1, ...)
++{
++ guint l;
++ va_list args;
++ gchar *s;
++ gchar *concat;
++
++ g_return_val_if_fail (string1 != NULL, NULL);
++
++ l = 1 + strlen (string1);
++ va_start (args, string1);
++ s = va_arg (args, gchar*);
++ while (s)
++ {
++ l += strlen (s);
++ s = va_arg (args, gchar*);
++ }
++ va_end (args);
++
++ concat = g_new (gchar, l);
++ concat[0] = 0;
++
++ strcat (concat, string1);
++ va_start (args, string1);
++ s = va_arg (args, gchar*);
++ while (s)
++ {
++ strcat (concat, s);
++ s = va_arg (args, gchar*);
++ }
++ va_end (args);
++
++ return concat;
++}
++
++#ifndef __KORBIT__
++gdouble
++g_strtod (const gchar *nptr,
++ gchar **endptr)
++{
++ gchar *fail_pos_1;
++ gchar *fail_pos_2;
++ gdouble val_1;
++ gdouble val_2 = 0;
++
++ g_return_val_if_fail (nptr != NULL, 0);
++
++ fail_pos_1 = NULL;
++ fail_pos_2 = NULL;
++
++ val_1 = strtod (nptr, &fail_pos_1);
++
++ if (fail_pos_1 && fail_pos_1[0] != 0)
++ {
++ gchar *old_locale;
++
++ old_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
++ setlocale (LC_NUMERIC, "C");
++ val_2 = strtod (nptr, &fail_pos_2);
++ setlocale (LC_NUMERIC, old_locale);
++ g_free (old_locale);
++ }
++
++ if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
++ {
++ if (endptr)
++ *endptr = fail_pos_1;
++ return val_1;
++ }
++ else
++ {
++ if (endptr)
++ *endptr = fail_pos_2;
++ return val_2;
++ }
++}
++#endif /* !__KORBIT__ */
++
++gchar*
++g_strerror (gint errnum)
++{
++#ifndef __KORBIT__
++ static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
++ char *msg;
++#endif
++
++#ifdef __KORBIT__
++#undef HAVE_STRERROR
++#define NO_SYS_ERRLIST 1
++#endif
++
++#if defined(HAVE_STRERROR)
++ return strerror (errnum);
++#elif NO_SYS_ERRLIST
++ switch (errnum)
++ {
++#ifdef E2BIG
++ case E2BIG: return "argument list too long";
++#endif
++#ifdef EACCES
++ case EACCES: return "permission denied";
++#endif
++#ifdef EADDRINUSE
++ case EADDRINUSE: return "address already in use";
++#endif
++#ifdef EADDRNOTAVAIL
++ case EADDRNOTAVAIL: return "can't assign requested address";
++#endif
++#ifdef EADV
++ case EADV: return "advertise error";
++#endif
++#ifdef EAFNOSUPPORT
++ case EAFNOSUPPORT: return "address family not supported by protocol family";
++#endif
++#ifdef EAGAIN
++ case EAGAIN: return "try again";
++#endif
++#ifdef EALIGN
++ case EALIGN: return "EALIGN";
++#endif
++#ifdef EALREADY
++ case EALREADY: return "operation already in progress";
++#endif
++#ifdef EBADE
++ case EBADE: return "bad exchange descriptor";
++#endif
++#ifdef EBADF
++ case EBADF: return "bad file number";
++#endif
++#ifdef EBADFD
++ case EBADFD: return "file descriptor in bad state";
++#endif
++#ifdef EBADMSG
++ case EBADMSG: return "not a data message";
++#endif
++#ifdef EBADR
++ case EBADR: return "bad request descriptor";
++#endif
++#ifdef EBADRPC
++ case EBADRPC: return "RPC structure is bad";
++#endif
++#ifdef EBADRQC
++ case EBADRQC: return "bad request code";
++#endif
++#ifdef EBADSLT
++ case EBADSLT: return "invalid slot";
++#endif
++#ifdef EBFONT
++ case EBFONT: return "bad font file format";
++#endif
++#ifdef EBUSY
++ case EBUSY: return "mount device busy";
++#endif
++#ifdef ECHILD
++ case ECHILD: return "no children";
++#endif
++#ifdef ECHRNG
++ case ECHRNG: return "channel number out of range";
++#endif
++#ifdef ECOMM
++ case ECOMM: return "communication error on send";
++#endif
++#ifdef ECONNABORTED
++ case ECONNABORTED: return "software caused connection abort";
++#endif
++#ifdef ECONNREFUSED
++ case ECONNREFUSED: return "connection refused";
++#endif
++#ifdef ECONNRESET
++ case ECONNRESET: return "connection reset by peer";
++#endif
++#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK)) && (!defined(EDEADLOCK) || (EDEADLK != EDEADLOCK))
++ case EDEADLK: return "resource deadlock avoided";
++#endif
++#ifdef EDEADLOCK
++ case EDEADLOCK: return "resource deadlock avoided";
++#endif
++#ifdef EDESTADDRREQ
++ case EDESTADDRREQ: return "destination address required";
++#endif
++#ifdef EDIRTY
++ case EDIRTY: return "mounting a dirty fs w/o force";
++#endif
++#ifdef EDOM
++ case EDOM: return "math argument out of range";
++#endif
++#ifdef EDOTDOT
++ case EDOTDOT: return "cross mount point";
++#endif
++#ifdef EDQUOT
++ case EDQUOT: return "disk quota exceeded";
++#endif
++#ifdef EDUPPKG
++ case EDUPPKG: return "duplicate package name";
++#endif
++#ifdef EEXIST
++ case EEXIST: return "file already exists";
++#endif
++#ifdef EFAULT
++ case EFAULT: return "bad address in system call argument";
++#endif
++#ifdef EFBIG
++ case EFBIG: return "file too large";
++#endif
++#ifdef EHOSTDOWN
++ case EHOSTDOWN: return "host is down";
++#endif
++#ifdef EHOSTUNREACH
++ case EHOSTUNREACH: return "host is unreachable";
++#endif
++#ifdef EIDRM
++ case EIDRM: return "identifier removed";
++#endif
++#ifdef EINIT
++ case EINIT: return "initialization error";
++#endif
++#ifdef EINPROGRESS
++ case EINPROGRESS: return "operation now in progress";
++#endif
++#ifdef EINTR
++ case EINTR: return "interrupted system call";
++#endif
++#ifdef EINVAL
++ case EINVAL: return "invalid argument";
++#endif
++#ifdef EIO
++ case EIO: return "I/O error";
++#endif
++#ifdef EISCONN
++ case EISCONN: return "socket is already connected";
++#endif
++#ifdef EISDIR
++ case EISDIR: return "illegal operation on a directory";
++#endif
++#ifdef EISNAME
++ case EISNAM: return "is a name file";
++#endif
++#ifdef ELBIN
++ case ELBIN: return "ELBIN";
++#endif
++#ifdef EL2HLT
++ case EL2HLT: return "level 2 halted";
++#endif
++#ifdef EL2NSYNC
++ case EL2NSYNC: return "level 2 not synchronized";
++#endif
++#ifdef EL3HLT
++ case EL3HLT: return "level 3 halted";
++#endif
++#ifdef EL3RST
++ case EL3RST: return "level 3 reset";
++#endif
++#ifdef ELIBACC
++ case ELIBACC: return "can not access a needed shared library";
++#endif
++#ifdef ELIBBAD
++ case ELIBBAD: return "accessing a corrupted shared library";
++#endif
++#ifdef ELIBEXEC
++ case ELIBEXEC: return "can not exec a shared library directly";
++#endif
++#ifdef ELIBMAX
++ case ELIBMAX: return "attempting to link in more shared libraries than system limit";
++#endif
++#ifdef ELIBSCN
++ case ELIBSCN: return ".lib section in a.out corrupted";
++#endif
++#ifdef ELNRNG
++ case ELNRNG: return "link number out of range";
++#endif
++#ifdef ELOOP
++ case ELOOP: return "too many levels of symbolic links";
++#endif
++#ifdef EMFILE
++ case EMFILE: return "too many open files";
++#endif
++#ifdef EMLINK
++ case EMLINK: return "too many links";
++#endif
++#ifdef EMSGSIZE
++ case EMSGSIZE: return "message too long";
++#endif
++#ifdef EMULTIHOP
++ case EMULTIHOP: return "multihop attempted";
++#endif
++#ifdef ENAMETOOLONG
++ case ENAMETOOLONG: return "file name too long";
++#endif
++#ifdef ENAVAIL
++ case ENAVAIL: return "not available";
++#endif
++#ifdef ENET
++ case ENET: return "ENET";
++#endif
++#ifdef ENETDOWN
++ case ENETDOWN: return "network is down";
++#endif
++#ifdef ENETRESET
++ case ENETRESET: return "network dropped connection on reset";
++#endif
++#ifdef ENETUNREACH
++ case ENETUNREACH: return "network is unreachable";
++#endif
++#ifdef ENFILE
++ case ENFILE: return "file table overflow";
++#endif
++#ifdef ENOANO
++ case ENOANO: return "anode table overflow";
++#endif
++#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
++ case ENOBUFS: return "no buffer space available";
++#endif
++#ifdef ENOCSI
++ case ENOCSI: return "no CSI structure available";
++#endif
++#ifdef ENODATA
++ case ENODATA: return "no data available";
++#endif
++#ifdef ENODEV
++ case ENODEV: return "no such device";
++#endif
++#ifdef ENOENT
++ case ENOENT: return "no such file or directory";
++#endif
++#ifdef ENOEXEC
++ case ENOEXEC: return "exec format error";
++#endif
++#ifdef ENOLCK
++ case ENOLCK: return "no locks available";
++#endif
++#ifdef ENOLINK
++ case ENOLINK: return "link has be severed";
++#endif
++#ifdef ENOMEM
++ case ENOMEM: return "not enough memory";
++#endif
++#ifdef ENOMSG
++ case ENOMSG: return "no message of desired type";
++#endif
++#ifdef ENONET
++ case ENONET: return "machine is not on the network";
++#endif
++#ifdef ENOPKG
++ case ENOPKG: return "package not installed";
++#endif
++#ifdef ENOPROTOOPT
++ case ENOPROTOOPT: return "bad proocol option";
++#endif
++#ifdef ENOSPC
++ case ENOSPC: return "no space left on device";
++#endif
++#ifdef ENOSR
++ case ENOSR: return "out of stream resources";
++#endif
++#ifdef ENOSTR
++ case ENOSTR: return "not a stream device";
++#endif
++#ifdef ENOSYM
++ case ENOSYM: return "unresolved symbol name";
++#endif
++#ifdef ENOSYS
++ case ENOSYS: return "function not implemented";
++#endif
++#ifdef ENOTBLK
++ case ENOTBLK: return "block device required";
++#endif
++#ifdef ENOTCONN
++ case ENOTCONN: return "socket is not connected";
++#endif
++#ifdef ENOTDIR
++ case ENOTDIR: return "not a directory";
++#endif
++#ifdef ENOTEMPTY
++ case ENOTEMPTY: return "directory not empty";
++#endif
++#ifdef ENOTNAM
++ case ENOTNAM: return "not a name file";
++#endif
++#ifdef ENOTSOCK
++ case ENOTSOCK: return "socket operation on non-socket";
++#endif
++#ifdef ENOTTY
++ case ENOTTY: return "inappropriate device for ioctl";
++#endif
++#ifdef ENOTUNIQ
++ case ENOTUNIQ: return "name not unique on network";
++#endif
++#ifdef ENXIO
++ case ENXIO: return "no such device or address";
++#endif
++#ifdef EOPNOTSUPP
++ case EOPNOTSUPP: return "operation not supported on socket";
++#endif
++#ifdef EPERM
++ case EPERM: return "not owner";
++#endif
++#ifdef EPFNOSUPPORT
++ case EPFNOSUPPORT: return "protocol family not supported";
++#endif
++#ifdef EPIPE
++ case EPIPE: return "broken pipe";
++#endif
++#ifdef EPROCLIM
++ case EPROCLIM: return "too many processes";
++#endif
++#ifdef EPROCUNAVAIL
++ case EPROCUNAVAIL: return "bad procedure for program";
++#endif
++#ifdef EPROGMISMATCH
++ case EPROGMISMATCH: return "program version wrong";
++#endif
++#ifdef EPROGUNAVAIL
++ case EPROGUNAVAIL: return "RPC program not available";
++#endif
++#ifdef EPROTO
++ case EPROTO: return "protocol error";
++#endif
++#ifdef EPROTONOSUPPORT
++ case EPROTONOSUPPORT: return "protocol not suppored";
++#endif
++#ifdef EPROTOTYPE
++ case EPROTOTYPE: return "protocol wrong type for socket";
++#endif
++#ifdef ERANGE
++ case ERANGE: return "math result unrepresentable";
++#endif
++#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
++ case EREFUSED: return "EREFUSED";
++#endif
++#ifdef EREMCHG
++ case EREMCHG: return "remote address changed";
++#endif
++#ifdef EREMDEV
++ case EREMDEV: return "remote device";
++#endif
++#ifdef EREMOTE
++ case EREMOTE: return "pathname hit remote file system";
++#endif
++#ifdef EREMOTEIO
++ case EREMOTEIO: return "remote i/o error";
++#endif
++#ifdef EREMOTERELEASE
++ case EREMOTERELEASE: return "EREMOTERELEASE";
++#endif
++#ifdef EROFS
++ case EROFS: return "read-only file system";
++#endif
++#ifdef ERPCMISMATCH
++ case ERPCMISMATCH: return "RPC version is wrong";
++#endif
++#ifdef ERREMOTE
++ case ERREMOTE: return "object is remote";
++#endif
++#ifdef ESHUTDOWN
++ case ESHUTDOWN: return "can't send afer socket shutdown";
++#endif
++#ifdef ESOCKTNOSUPPORT
++ case ESOCKTNOSUPPORT: return "socket type not supported";
++#endif
++#ifdef ESPIPE
++ case ESPIPE: return "invalid seek";
++#endif
++#ifdef ESRCH
++ case ESRCH: return "no such process";
++#endif
++#ifdef ESRMNT
++ case ESRMNT: return "srmount error";
++#endif
++#ifdef ESTALE
++ case ESTALE: return "stale remote file handle";
++#endif
++#ifdef ESUCCESS
++ case ESUCCESS: return "Error 0";
++#endif
++#ifdef ETIME
++ case ETIME: return "timer expired";
++#endif
++#ifdef ETIMEDOUT
++ case ETIMEDOUT: return "connection timed out";
++#endif
++#ifdef ETOOMANYREFS
++ case ETOOMANYREFS: return "too many references: can't splice";
++#endif
++#ifdef ETXTBSY
++ case ETXTBSY: return "text file or pseudo-device busy";
++#endif
++#ifdef EUCLEAN
++ case EUCLEAN: return "structure needs cleaning";
++#endif
++#ifdef EUNATCH
++ case EUNATCH: return "protocol driver not attached";
++#endif
++#ifdef EUSERS
++ case EUSERS: return "too many users";
++#endif
++#ifdef EVERSION
++ case EVERSION: return "version mismatch";
++#endif
++#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
++ case EWOULDBLOCK: return "operation would block";
++#endif
++#ifdef EXDEV
++ case EXDEV: return "cross-domain link";
++#endif
++#ifdef EXFULL
++ case EXFULL: return "message tables full";
++#endif
++ }
++#else /* NO_SYS_ERRLIST */
++ extern int sys_nerr;
++ extern char *sys_errlist[];
++
++ if ((errnum > 0) && (errnum <= sys_nerr))
++ return sys_errlist [errnum];
++#endif /* NO_SYS_ERRLIST */
++
++#ifndef __KORBIT__
++ msg = g_static_private_get (&msg_private);
++ if (!msg)
++ {
++ msg = g_new (gchar, 64);
++ g_static_private_set (&msg_private, msg, g_free);
++ }
++
++ sprintf (msg, "unknown error (%d)", errnum);
++
++ return msg;
++#else
++ return "unknown error";
++#endif /* !__KORBIT__ */
++}
++
++gchar*
++g_strsignal (gint signum)
++{
++#ifndef __KORBIT__
++ static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
++ char *msg;
++#endif
++
++#ifdef HAVE_STRSIGNAL
++ extern char *strsignal (int sig);
++ return strsignal (signum);
++#elif NO_SYS_SIGLIST
++ switch (signum)
++ {
++#ifdef SIGHUP
++ case SIGHUP: return "Hangup";
++#endif
++#ifdef SIGINT
++ case SIGINT: return "Interrupt";
++#endif
++#ifdef SIGQUIT
++ case SIGQUIT: return "Quit";
++#endif
++#ifdef SIGILL
++ case SIGILL: return "Illegal instruction";
++#endif
++#ifdef SIGTRAP
++ case SIGTRAP: return "Trace/breakpoint trap";
++#endif
++#ifdef SIGABRT
++ case SIGABRT: return "IOT trap/Abort";
++#endif
++#ifdef SIGBUS
++ case SIGBUS: return "Bus error";
++#endif
++#ifdef SIGFPE
++ case SIGFPE: return "Floating point exception";
++#endif
++#ifdef SIGKILL
++ case SIGKILL: return "Killed";
++#endif
++#ifdef SIGUSR1
++ case SIGUSR1: return "User defined signal 1";
++#endif
++#ifdef SIGSEGV
++ case SIGSEGV: return "Segmentation fault";
++#endif
++#ifdef SIGUSR2
++ case SIGUSR2: return "User defined signal 2";
++#endif
++#ifdef SIGPIPE
++ case SIGPIPE: return "Broken pipe";
++#endif
++#ifdef SIGALRM
++ case SIGALRM: return "Alarm clock";
++#endif
++#ifdef SIGTERM
++ case SIGTERM: return "Terminated";
++#endif
++#ifdef SIGSTKFLT
++ case SIGSTKFLT: return "Stack fault";
++#endif
++#ifdef SIGCHLD
++ case SIGCHLD: return "Child exited";
++#endif
++#ifdef SIGCONT
++ case SIGCONT: return "Continued";
++#endif
++#ifdef SIGSTOP
++ case SIGSTOP: return "Stopped (signal)";
++#endif
++#ifdef SIGTSTP
++ case SIGTSTP: return "Stopped";
++#endif
++#ifdef SIGTTIN
++ case SIGTTIN: return "Stopped (tty input)";
++#endif
++#ifdef SIGTTOU
++ case SIGTTOU: return "Stopped (tty output)";
++#endif
++#ifdef SIGURG
++ case SIGURG: return "Urgent condition";
++#endif
++#ifdef SIGXCPU
++ case SIGXCPU: return "CPU time limit exceeded";
++#endif
++#ifdef SIGXFSZ
++ case SIGXFSZ: return "File size limit exceeded";
++#endif
++#ifdef SIGVTALRM
++ case SIGVTALRM: return "Virtual time alarm";
++#endif
++#ifdef SIGPROF
++ case SIGPROF: return "Profile signal";
++#endif
++#ifdef SIGWINCH
++ case SIGWINCH: return "Window size changed";
++#endif
++#ifdef SIGIO
++ case SIGIO: return "Possible I/O";
++#endif
++#ifdef SIGPWR
++ case SIGPWR: return "Power failure";
++#endif
++#ifdef SIGUNUSED
++ case SIGUNUSED: return "Unused signal";
++#endif
++ }
++#else /* NO_SYS_SIGLIST */
++
++#ifdef NO_SYS_SIGLIST_DECL
++ extern char *sys_siglist[]; /*(see Tue Jan 19 00:44:24 1999 in changelog)*/
++#endif
++
++ return (char*) /* this function should return const --josh */ sys_siglist [signum];
++#endif /* NO_SYS_SIGLIST */
++
++#ifndef __KORBIT__
++ msg = g_static_private_get (&msg_private);
++ if (!msg)
++ {
++ msg = g_new (gchar, 64);
++ g_static_private_set (&msg_private, msg, g_free);
++ }
++
++ sprintf (msg, "unknown signal (%d)", signum);
++
++ return msg;
++#else
++ return "unknown error";
++#endif /* !__KORBIT__ */
++}
++
++guint
++g_printf_string_upper_bound (const gchar* format,
++ va_list args)
++{
++ guint len = 1;
++
++ while (*format)
++ {
++ gboolean long_int = FALSE;
++ gboolean extra_long = FALSE;
++ gchar c;
++
++ c = *format++;
++
++ if (c == '%')
++ {
++ gboolean done = FALSE;
++
++ while (*format && !done)
++ {
++ switch (*format++)
++ {
++ gchar *string_arg;
++
++ case '*':
++ len += va_arg (args, int);
++ break;
++ case '1':
++ case '2':
++ case '3':
++ case '4':
++ case '5':
++ case '6':
++ case '7':
++ case '8':
++ case '9':
++ /* add specified format length, since it might exceed the
++ * size we assume it to have.
++ */
++ format -= 1;
++ len += strtol (format, (char**) &format, 10);
++ break;
++ case 'h':
++ /* ignore short int flag, since all args have at least the
++ * same size as an int
++ */
++ break;
++ case 'l':
++ if (long_int)
++ extra_long = TRUE; /* linux specific */
++ else
++ long_int = TRUE;
++ break;
++ case 'q':
++ case 'L':
++ long_int = TRUE;
++ extra_long = TRUE;
++ break;
++ case 's':
++ string_arg = va_arg (args, char *);
++ if (string_arg)
++ len += strlen (string_arg);
++ else
++ {
++ /* add enough padding to hold "(null)" identifier */
++ len += 16;
++ }
++ done = TRUE;
++ break;
++ case 'd':
++ case 'i':
++ case 'o':
++ case 'u':
++ case 'x':
++ case 'X':
++#ifdef G_HAVE_GINT64
++ if (extra_long)
++ (void) va_arg (args, gint64);
++ else
++#endif /* G_HAVE_GINT64 */
++ {
++ if (long_int)
++ (void) va_arg (args, long);
++ else
++ (void) va_arg (args, int);
++ }
++ len += extra_long ? 64 : 32;
++ done = TRUE;
++ break;
++ case 'D':
++ case 'O':
++ case 'U':
++ (void) va_arg (args, long);
++ len += 32;
++ done = TRUE;
++ break;
++ case 'e':
++ case 'E':
++ case 'f':
++ case 'g':
++#ifdef HAVE_LONG_DOUBLE
++ if (extra_long)
++ (void) va_arg (args, long double);
++ else
++#endif /* HAVE_LONG_DOUBLE */
++ (void) va_arg (args, double);
++ len += extra_long ? 128 : 64;
++ done = TRUE;
++ break;
++ case 'c':
++ (void) va_arg (args, int);
++ len += 1;
++ done = TRUE;
++ break;
++ case 'p':
++ case 'n':
++ (void) va_arg (args, void*);
++ len += 32;
++ done = TRUE;
++ break;
++ case '%':
++ len += 1;
++ done = TRUE;
++ break;
++ default:
++ /* ignore unknow/invalid flags */
++ break;
++ }
++ }
++ }
++ else
++ len += 1;
++ }
++
++ return len;
++}
++
++void
++g_strdown (gchar *string)
++{
++ register guchar *s;
++
++ g_return_if_fail (string != NULL);
++
++ s = string;
++
++ while (*s)
++ {
++ *s = tolower (*s);
++ s++;
++ }
++}
++
++void
++g_strup (gchar *string)
++{
++ register guchar *s;
++
++ g_return_if_fail (string != NULL);
++
++ s = string;
++
++ while (*s)
++ {
++ *s = toupper (*s);
++ s++;
++ }
++}
++
++void
++g_strreverse (gchar *string)
++{
++ g_return_if_fail (string != NULL);
++
++ if (*string)
++ {
++ register gchar *h, *t;
++
++ h = string;
++ t = string + strlen (string) - 1;
++
++ while (h < t)
++ {
++ register gchar c;
++
++ c = *h;
++ *h = *t;
++ h++;
++ *t = c;
++ t--;
++ }
++ }
++}
++
++gint
++g_strcasecmp (const gchar *s1,
++ const gchar *s2)
++{
++#ifdef HAVE_STRCASECMP
++ g_return_val_if_fail (s1 != NULL, 0);
++ g_return_val_if_fail (s2 != NULL, 0);
++
++ return strcasecmp (s1, s2);
++#else
++ gint c1, c2;
++
++ g_return_val_if_fail (s1 != NULL, 0);
++ g_return_val_if_fail (s2 != NULL, 0);
++
++ while (*s1 && *s2)
++ {
++ /* According to A. Cox, some platforms have islower's that
++ * don't work right on non-uppercase
++ */
++ c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
++ c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
++ if (c1 != c2)
++ return (c1 - c2);
++ s1++; s2++;
++ }
++
++ return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
++#endif
++}
++
++gint
++g_strncasecmp (const gchar *s1,
++ const gchar *s2,
++ guint n)
++{
++#ifdef HAVE_STRNCASECMP
++ return strncasecmp (s1, s2, n);
++#else
++ gint c1, c2;
++
++ g_return_val_if_fail (s1 != NULL, 0);
++ g_return_val_if_fail (s2 != NULL, 0);
++
++ while (n-- && *s1 && *s2)
++ {
++ /* According to A. Cox, some platforms have islower's that
++ * don't work right on non-uppercase
++ */
++ c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
++ c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
++ if (c1 != c2)
++ return (c1 - c2);
++ s1++; s2++;
++ }
++
++ if (n)
++ return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
++ else
++ return 0;
++#endif
++}
++
++gchar*
++g_strdelimit (gchar *string,
++ const gchar *delimiters,
++ gchar new_delim)
++{
++ register gchar *c;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ if (!delimiters)
++ delimiters = G_STR_DELIMITERS;
++
++ for (c = string; *c; c++)
++ {
++ if (strchr (delimiters, *c))
++ *c = new_delim;
++ }
++
++ return string;
++}
++
++gchar*
++g_strescape (gchar *string)
++{
++ gchar *q;
++ gchar *escaped;
++ guint backslashes = 0;
++ gchar *p = string;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ while (*p != '\000')
++ backslashes += (*p++ == '\\');
++
++ if (!backslashes)
++ return g_strdup (string);
++
++ escaped = g_new (gchar, strlen (string) + backslashes + 1);
++
++ p = string;
++ q = escaped;
++
++ while (*p != '\000')
++ {
++ if (*p == '\\')
++ *q++ = '\\';
++ *q++ = *p++;
++ }
++ *q = '\000';
++
++ return escaped;
++}
++
++/* blame Elliot for these next five routines */
++gchar*
++g_strchug (gchar *string)
++{
++ guchar *start;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ for (start = string; *start && isspace (*start); start++)
++ ;
++
++ g_memmove(string, start, strlen(start) + 1);
++
++ return string;
++}
++
++gchar*
++g_strchomp (gchar *string)
++{
++ gchar *s;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ if (!*string)
++ return string;
++
++ for (s = string + strlen (string) - 1; s >= string && isspace ((guchar)*s);
++ s--)
++ *s = '\0';
++
++ return string;
++}
++
++gchar**
++g_strsplit (const gchar *string,
++ const gchar *delimiter,
++ gint max_tokens)
++{
++ GSList *string_list = NULL, *slist;
++ gchar **str_array, *s;
++ guint i, n = 1;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (delimiter != NULL, NULL);
++
++ if (max_tokens < 1)
++ max_tokens = G_MAXINT;
++
++ s = strstr (string, delimiter);
++ if (s)
++ {
++ guint delimiter_len = strlen (delimiter);
++
++ do
++ {
++ guint len;
++ gchar *new_string;
++
++ len = s - string;
++ new_string = g_new (gchar, len + 1);
++ strncpy (new_string, string, len);
++ new_string[len] = 0;
++ string_list = g_slist_prepend (string_list, new_string);
++ n++;
++ string = s + delimiter_len;
++ s = strstr (string, delimiter);
++ }
++ while (--max_tokens && s);
++ }
++ if (*string)
++ {
++ n++;
++ string_list = g_slist_prepend (string_list, g_strdup (string));
++ }
++
++ str_array = g_new (gchar*, n);
++
++ i = n - 1;
++
++ str_array[i--] = NULL;
++ for (slist = string_list; slist; slist = slist->next)
++ str_array[i--] = slist->data;
++
++ g_slist_free (string_list);
++
++ return str_array;
++}
++
++void
++g_strfreev (gchar **str_array)
++{
++ if (str_array)
++ {
++ int i;
++
++ for(i = 0; str_array[i] != NULL; i++)
++ g_free(str_array[i]);
++
++ g_free (str_array);
++ }
++}
++
++gchar*
++g_strjoinv (const gchar *separator,
++ gchar **str_array)
++{
++ gchar *string;
++
++ g_return_val_if_fail (str_array != NULL, NULL);
++
++ if (separator == NULL)
++ separator = "";
++
++ if (*str_array)
++ {
++ guint i, len;
++ guint separator_len;
++
++ separator_len = strlen (separator);
++ len = 1 + strlen (str_array[0]);
++ for(i = 1; str_array[i] != NULL; i++)
++ len += separator_len + strlen(str_array[i]);
++
++ string = g_new (gchar, len);
++ *string = 0;
++ strcat (string, *str_array);
++ for (i = 1; str_array[i] != NULL; i++)
++ {
++ strcat (string, separator);
++ strcat (string, str_array[i]);
++ }
++ }
++ else
++ string = g_strdup ("");
++
++ return string;
++}
++
++gchar*
++g_strjoin (const gchar *separator,
++ ...)
++{
++ gchar *string, *s;
++ va_list args;
++ guint len;
++ guint separator_len;
++
++ if (separator == NULL)
++ separator = "";
++
++ separator_len = strlen (separator);
++
++ va_start (args, separator);
++
++ s = va_arg (args, gchar*);
++
++ if (s)
++ {
++ len = strlen (s);
++
++ s = va_arg (args, gchar*);
++ while (s)
++ {
++ len += separator_len + strlen (s);
++ s = va_arg (args, gchar*);
++ }
++ va_end (args);
++
++ string = g_new (gchar, len + 1);
++ *string = 0;
++
++ va_start (args, separator);
++
++ s = va_arg (args, gchar*);
++ strcat (string, s);
++
++ s = va_arg (args, gchar*);
++ while (s)
++ {
++ strcat (string, separator);
++ strcat (string, s);
++ s = va_arg (args, gchar*);
++ }
++ }
++ else
++ string = g_strdup ("");
++
++ va_end (args);
++
++ return string;
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gstring.c linux-2.4.1-korbit/net/korbit/kglib/gstring.c
+--- linux-2.4.1/net/korbit/kglib/gstring.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gstring.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,508 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include <stdarg.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <ctype.h>
++#include "glib.h"
++
++
++typedef struct _GRealStringChunk GRealStringChunk;
++typedef struct _GRealString GRealString;
++
++struct _GRealStringChunk
++{
++ GHashTable *const_table;
++ GSList *storage_list;
++ gint storage_next;
++ gint this_size;
++ gint default_size;
++};
++
++struct _GRealString
++{
++ gchar *str;
++ gint len;
++ gint alloc;
++};
++
++G_LOCK_DEFINE_STATIC (string_mem_chunk);
++static GMemChunk *string_mem_chunk = NULL;
++
++/* Hash Functions.
++ */
++
++gint
++g_str_equal (gconstpointer v, gconstpointer v2)
++{
++ return strcmp ((const gchar*) v, (const gchar*)v2) == 0;
++}
++
++/* 31 bit hash function */
++guint
++g_str_hash (gconstpointer key)
++{
++ const char *p = key;
++ guint h = *p;
++
++ if (h)
++ for (p += 1; *p != '\0'; p++)
++ h = (h << 5) - h + *p;
++
++ return h;
++}
++
++/* String Chunks.
++ */
++
++GStringChunk*
++g_string_chunk_new (gint default_size)
++{
++ GRealStringChunk *new_chunk = g_new (GRealStringChunk, 1);
++ gint size = 1;
++
++ while (size < default_size)
++ size <<= 1;
++
++ new_chunk->const_table = NULL;
++ new_chunk->storage_list = NULL;
++ new_chunk->storage_next = size;
++ new_chunk->default_size = size;
++ new_chunk->this_size = size;
++
++ return (GStringChunk*) new_chunk;
++}
++
++void
++g_string_chunk_free (GStringChunk *fchunk)
++{
++ GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
++ GSList *tmp_list;
++
++ g_return_if_fail (chunk != NULL);
++
++ if (chunk->storage_list)
++ {
++ for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
++ g_free (tmp_list->data);
++
++ g_slist_free (chunk->storage_list);
++ }
++
++ if (chunk->const_table)
++ g_hash_table_destroy (chunk->const_table);
++
++ g_free (chunk);
++}
++
++gchar*
++g_string_chunk_insert (GStringChunk *fchunk,
++ const gchar *string)
++{
++ GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
++ gint len = strlen (string);
++ char* pos;
++
++ g_return_val_if_fail (chunk != NULL, NULL);
++
++ if ((chunk->storage_next + len + 1) > chunk->this_size)
++ {
++ gint new_size = chunk->default_size;
++
++ while (new_size < len+1)
++ new_size <<= 1;
++
++ chunk->storage_list = g_slist_prepend (chunk->storage_list,
++ g_new (char, new_size));
++
++ chunk->this_size = new_size;
++ chunk->storage_next = 0;
++ }
++
++ pos = ((char*)chunk->storage_list->data) + chunk->storage_next;
++
++ strcpy (pos, string);
++
++ chunk->storage_next += len + 1;
++
++ return pos;
++}
++
++gchar*
++g_string_chunk_insert_const (GStringChunk *fchunk,
++ const gchar *string)
++{
++ GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
++ char* lookup;
++
++ g_return_val_if_fail (chunk != NULL, NULL);
++
++ if (!chunk->const_table)
++ chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal);
++
++ lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string);
++
++ if (!lookup)
++ {
++ lookup = g_string_chunk_insert (fchunk, string);
++ g_hash_table_insert (chunk->const_table, lookup, lookup);
++ }
++
++ return lookup;
++}
++
++/* Strings.
++ */
++static gint
++nearest_pow (gint num)
++{
++ gint n = 1;
++
++ while (n < num)
++ n <<= 1;
++
++ return n;
++}
++
++static void
++g_string_maybe_expand (GRealString* string, gint len)
++{
++ if (string->len + len >= string->alloc)
++ {
++ string->alloc = nearest_pow (string->len + len + 1);
++ string->str = g_realloc (string->str, string->alloc);
++ }
++}
++
++GString*
++g_string_sized_new (guint dfl_size)
++{
++ GRealString *string;
++
++ G_LOCK (string_mem_chunk);
++ if (!string_mem_chunk)
++ string_mem_chunk = g_mem_chunk_new ("string mem chunk",
++ sizeof (GRealString),
++ 1024, G_ALLOC_AND_FREE);
++
++ string = g_chunk_new (GRealString, string_mem_chunk);
++ G_UNLOCK (string_mem_chunk);
++
++ string->alloc = 0;
++ string->len = 0;
++ string->str = NULL;
++
++ g_string_maybe_expand (string, MAX (dfl_size, 2));
++ string->str[0] = 0;
++
++ return (GString*) string;
++}
++
++GString*
++g_string_new (const gchar *init)
++{
++ GString *string;
++
++ string = g_string_sized_new (2);
++
++ if (init)
++ g_string_append (string, init);
++
++ return string;
++}
++
++void
++g_string_free (GString *string,
++ gint free_segment)
++{
++ g_return_if_fail (string != NULL);
++
++ if (free_segment)
++ g_free (string->str);
++
++ G_LOCK (string_mem_chunk);
++ g_mem_chunk_free (string_mem_chunk, string);
++ G_UNLOCK (string_mem_chunk);
++}
++
++GString*
++g_string_assign (GString *lval,
++ const gchar *rval)
++{
++ g_return_val_if_fail (lval != NULL, NULL);
++ g_return_val_if_fail (rval != NULL, NULL);
++
++ g_string_truncate (lval, 0);
++ g_string_append (lval, rval);
++
++ return lval;
++}
++
++GString*
++g_string_truncate (GString* fstring,
++ gint len)
++{
++ GRealString *string = (GRealString*)fstring;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (len >= 0, NULL);
++
++ string->len = len;
++
++ string->str[len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_append (GString *fstring,
++ const gchar *val)
++{
++ GRealString *string = (GRealString*)fstring;
++ int len;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (val != NULL, fstring);
++
++ len = strlen (val);
++ g_string_maybe_expand (string, len);
++
++ strcpy (string->str + string->len, val);
++
++ string->len += len;
++
++ return fstring;
++}
++
++GString*
++g_string_append_c (GString *fstring,
++ gchar c)
++{
++ GRealString *string = (GRealString*)fstring;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_string_maybe_expand (string, 1);
++
++ string->str[string->len++] = c;
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_prepend (GString *fstring,
++ const gchar *val)
++{
++ GRealString *string = (GRealString*)fstring;
++ gint len;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (val != NULL, fstring);
++
++ len = strlen (val);
++ g_string_maybe_expand (string, len);
++
++ g_memmove (string->str + len, string->str, string->len);
++
++ strncpy (string->str, val, len);
++
++ string->len += len;
++
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_prepend_c (GString *fstring,
++ gchar c)
++{
++ GRealString *string = (GRealString*)fstring;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_string_maybe_expand (string, 1);
++
++ g_memmove (string->str + 1, string->str, string->len);
++
++ string->str[0] = c;
++
++ string->len += 1;
++
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_insert (GString *fstring,
++ gint pos,
++ const gchar *val)
++{
++ GRealString *string = (GRealString*)fstring;
++ gint len;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (val != NULL, fstring);
++ g_return_val_if_fail (pos >= 0, fstring);
++ g_return_val_if_fail (pos <= string->len, fstring);
++
++ len = strlen (val);
++ g_string_maybe_expand (string, len);
++
++ g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
++
++ strncpy (string->str + pos, val, len);
++
++ string->len += len;
++
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString *
++g_string_insert_c (GString *fstring,
++ gint pos,
++ gchar c)
++{
++ GRealString *string = (GRealString*)fstring;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (pos <= string->len, fstring);
++
++ g_string_maybe_expand (string, 1);
++
++ g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
++
++ string->str[pos] = c;
++
++ string->len += 1;
++
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_erase (GString *fstring,
++ gint pos,
++ gint len)
++{
++ GRealString *string = (GRealString*)fstring;
++
++ g_return_val_if_fail (string != NULL, NULL);
++ g_return_val_if_fail (len >= 0, fstring);
++ g_return_val_if_fail (pos >= 0, fstring);
++ g_return_val_if_fail (pos <= string->len, fstring);
++ g_return_val_if_fail (pos + len <= string->len, fstring);
++
++ if (pos + len < string->len)
++ g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
++
++ string->len -= len;
++
++ string->str[string->len] = 0;
++
++ return fstring;
++}
++
++GString*
++g_string_down (GString *fstring)
++{
++ GRealString *string = (GRealString*)fstring;
++ guchar *s;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ s = string->str;
++
++ while (*s)
++ {
++ *s = tolower (*s);
++ s++;
++ }
++
++ return fstring;
++}
++
++GString*
++g_string_up (GString *fstring)
++{
++ GRealString *string = (GRealString*)fstring;
++ guchar *s;
++
++ g_return_val_if_fail (string != NULL, NULL);
++
++ s = string->str;
++
++ while (*s)
++ {
++ *s = toupper (*s);
++ s++;
++ }
++
++ return fstring;
++}
++
++static void
++g_string_sprintfa_int (GString *string,
++ const gchar *fmt,
++ va_list args)
++{
++ gchar *buffer;
++
++ buffer = g_strdup_vprintf (fmt, args);
++ g_string_append (string, buffer);
++ g_free (buffer);
++}
++
++void
++g_string_sprintf (GString *string,
++ const gchar *fmt,
++ ...)
++{
++ va_list args;
++
++ g_string_truncate (string, 0);
++
++ va_start (args, fmt);
++ g_string_sprintfa_int (string, fmt, args);
++ va_end (args);
++}
++
++void
++g_string_sprintfa (GString *string,
++ const gchar *fmt,
++ ...)
++{
++ va_list args;
++
++ va_start (args, fmt);
++ g_string_sprintfa_int (string, fmt, args);
++ va_end (args);
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gtree.c linux-2.4.1-korbit/net/korbit/kglib/gtree.c
+--- linux-2.4.1/net/korbit/kglib/gtree.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gtree.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,740 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#include "glib.h"
++
++
++typedef struct _GRealTree GRealTree;
++typedef struct _GTreeNode GTreeNode;
++
++struct _GRealTree
++{
++ GTreeNode *root;
++ GCompareFunc key_compare;
++};
++
++struct _GTreeNode
++{
++ gint balance; /* height (left) - height (right) */
++ GTreeNode *left; /* left subtree */
++ GTreeNode *right; /* right subtree */
++ gpointer key; /* key for this node */
++ gpointer value; /* value stored at this node */
++};
++
++
++static GTreeNode* g_tree_node_new (gpointer key,
++ gpointer value);
++static void g_tree_node_destroy (GTreeNode *node);
++static GTreeNode* g_tree_node_insert (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key,
++ gpointer value,
++ gint *inserted);
++static GTreeNode* g_tree_node_remove (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key);
++static GTreeNode* g_tree_node_balance (GTreeNode *node);
++static GTreeNode* g_tree_node_remove_leftmost (GTreeNode *node,
++ GTreeNode **leftmost);
++static GTreeNode* g_tree_node_restore_left_balance (GTreeNode *node,
++ gint old_balance);
++static GTreeNode* g_tree_node_restore_right_balance (GTreeNode *node,
++ gint old_balance);
++static gpointer g_tree_node_lookup (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key);
++static gint g_tree_node_count (GTreeNode *node);
++static gint g_tree_node_pre_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data);
++static gint g_tree_node_in_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data);
++static gint g_tree_node_post_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data);
++static gpointer g_tree_node_search (GTreeNode *node,
++ GSearchFunc search_func,
++ gpointer data);
++static gint g_tree_node_height (GTreeNode *node);
++static GTreeNode* g_tree_node_rotate_left (GTreeNode *node);
++static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
++static void g_tree_node_check (GTreeNode *node);
++
++
++G_LOCK_DEFINE_STATIC (g_tree_global);
++static GMemChunk *node_mem_chunk = NULL;
++static GTreeNode *node_free_list = NULL;
++
++
++static GTreeNode*
++g_tree_node_new (gpointer key,
++ gpointer value)
++{
++ GTreeNode *node;
++
++ G_LOCK (g_tree_global);
++ if (node_free_list)
++ {
++ node = node_free_list;
++ node_free_list = node->right;
++ }
++ else
++ {
++ if (!node_mem_chunk)
++ node_mem_chunk = g_mem_chunk_new ("GLib GTreeNode mem chunk",
++ sizeof (GTreeNode),
++ 1024,
++ G_ALLOC_ONLY);
++
++ node = g_chunk_new (GTreeNode, node_mem_chunk);
++ }
++ G_UNLOCK (g_tree_global);
++
++ node->balance = 0;
++ node->left = NULL;
++ node->right = NULL;
++ node->key = key;
++ node->value = value;
++
++ return node;
++}
++
++static void
++g_tree_node_destroy (GTreeNode *node)
++{
++ if (node)
++ {
++ g_tree_node_destroy (node->right);
++ g_tree_node_destroy (node->left);
++ G_LOCK (g_tree_global);
++ node->right = node_free_list;
++ node_free_list = node;
++ G_UNLOCK (g_tree_global);
++ }
++}
++
++
++GTree*
++g_tree_new (GCompareFunc key_compare_func)
++{
++ GRealTree *rtree;
++
++ g_return_val_if_fail (key_compare_func != NULL, NULL);
++
++ rtree = g_new (GRealTree, 1);
++ rtree->root = NULL;
++ rtree->key_compare = key_compare_func;
++
++ return (GTree*) rtree;
++}
++
++void
++g_tree_destroy (GTree *tree)
++{
++ GRealTree *rtree;
++
++ g_return_if_fail (tree != NULL);
++
++ rtree = (GRealTree*) tree;
++
++ g_tree_node_destroy (rtree->root);
++ g_free (rtree);
++}
++
++void
++g_tree_insert (GTree *tree,
++ gpointer key,
++ gpointer value)
++{
++ GRealTree *rtree;
++ gint inserted;
++
++ g_return_if_fail (tree != NULL);
++
++ rtree = (GRealTree*) tree;
++
++ inserted = FALSE;
++ rtree->root = g_tree_node_insert (rtree->root, rtree->key_compare,
++ key, value, &inserted);
++}
++
++void
++g_tree_remove (GTree *tree,
++ gpointer key)
++{
++ GRealTree *rtree;
++
++ g_return_if_fail (tree != NULL);
++
++ rtree = (GRealTree*) tree;
++
++ rtree->root = g_tree_node_remove (rtree->root, rtree->key_compare, key);
++}
++
++gpointer
++g_tree_lookup (GTree *tree,
++ gpointer key)
++{
++ GRealTree *rtree;
++
++ g_return_val_if_fail (tree != NULL, NULL);
++
++ rtree = (GRealTree*) tree;
++
++ return g_tree_node_lookup (rtree->root, rtree->key_compare, key);
++}
++
++void
++g_tree_traverse (GTree *tree,
++ GTraverseFunc traverse_func,
++ GTraverseType traverse_type,
++ gpointer data)
++{
++ GRealTree *rtree;
++
++ g_return_if_fail (tree != NULL);
++
++ rtree = (GRealTree*) tree;
++
++ if (!rtree->root)
++ return;
++
++ switch (traverse_type)
++ {
++ case G_PRE_ORDER:
++ g_tree_node_pre_order (rtree->root, traverse_func, data);
++ break;
++
++ case G_IN_ORDER:
++ g_tree_node_in_order (rtree->root, traverse_func, data);
++ break;
++
++ case G_POST_ORDER:
++ g_tree_node_post_order (rtree->root, traverse_func, data);
++ break;
++
++ case G_LEVEL_ORDER:
++ g_warning ("g_tree_traverse(): traverse type G_LEVEL_ORDER isn't implemented.");
++ break;
++ }
++}
++
++gpointer
++g_tree_search (GTree *tree,
++ GSearchFunc search_func,
++ gpointer data)
++{
++ GRealTree *rtree;
++
++ g_return_val_if_fail (tree != NULL, NULL);
++
++ rtree = (GRealTree*) tree;
++
++ if (rtree->root)
++ return g_tree_node_search (rtree->root, search_func, data);
++ else
++ return NULL;
++}
++
++gint
++g_tree_height (GTree *tree)
++{
++ GRealTree *rtree;
++
++ g_return_val_if_fail (tree != NULL, 0);
++
++ rtree = (GRealTree*) tree;
++
++ if (rtree->root)
++ return g_tree_node_height (rtree->root);
++ else
++ return 0;
++}
++
++gint
++g_tree_nnodes (GTree *tree)
++{
++ GRealTree *rtree;
++
++ g_return_val_if_fail (tree != NULL, 0);
++
++ rtree = (GRealTree*) tree;
++
++ if (rtree->root)
++ return g_tree_node_count (rtree->root);
++ else
++ return 0;
++}
++
++static GTreeNode*
++g_tree_node_insert (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key,
++ gpointer value,
++ gint *inserted)
++{
++ gint old_balance;
++ gint cmp;
++
++ if (!node)
++ {
++ *inserted = TRUE;
++ return g_tree_node_new (key, value);
++ }
++
++ cmp = (* compare) (key, node->key);
++ if (cmp == 0)
++ {
++ *inserted = FALSE;
++ node->value = value;
++ return node;
++ }
++
++ if (cmp < 0)
++ {
++ if (node->left)
++ {
++ old_balance = node->left->balance;
++ node->left = g_tree_node_insert (node->left, compare, key, value, inserted);
++
++ if ((old_balance != node->left->balance) && node->left->balance)
++ node->balance -= 1;
++ }
++ else
++ {
++ *inserted = TRUE;
++ node->left = g_tree_node_new (key, value);
++ node->balance -= 1;
++ }
++ }
++ else if (cmp > 0)
++ {
++ if (node->right)
++ {
++ old_balance = node->right->balance;
++ node->right = g_tree_node_insert (node->right, compare, key, value, inserted);
++
++ if ((old_balance != node->right->balance) && node->right->balance)
++ node->balance += 1;
++ }
++ else
++ {
++ *inserted = TRUE;
++ node->right = g_tree_node_new (key, value);
++ node->balance += 1;
++ }
++ }
++
++ if (*inserted)
++ {
++ if ((node->balance < -1) || (node->balance > 1))
++ node = g_tree_node_balance (node);
++ }
++
++ return node;
++}
++
++static GTreeNode*
++g_tree_node_remove (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key)
++{
++ GTreeNode *new_root;
++ gint old_balance;
++ gint cmp;
++
++ if (!node)
++ return NULL;
++
++ cmp = (* compare) (key, node->key);
++ if (cmp == 0)
++ {
++ GTreeNode *garbage;
++
++ garbage = node;
++
++ if (!node->right)
++ {
++ node = node->left;
++ }
++ else
++ {
++ old_balance = node->right->balance;
++ node->right = g_tree_node_remove_leftmost (node->right, &new_root);
++ new_root->left = node->left;
++ new_root->right = node->right;
++ new_root->balance = node->balance;
++ node = g_tree_node_restore_right_balance (new_root, old_balance);
++ }
++
++ G_LOCK (g_tree_global);
++ garbage->right = node_free_list;
++ node_free_list = garbage;
++ G_UNLOCK (g_tree_global);
++ }
++ else if (cmp < 0)
++ {
++ if (node->left)
++ {
++ old_balance = node->left->balance;
++ node->left = g_tree_node_remove (node->left, compare, key);
++ node = g_tree_node_restore_left_balance (node, old_balance);
++ }
++ }
++ else if (cmp > 0)
++ {
++ if (node->right)
++ {
++ old_balance = node->right->balance;
++ node->right = g_tree_node_remove (node->right, compare, key);
++ node = g_tree_node_restore_right_balance (node, old_balance);
++ }
++ }
++
++ return node;
++}
++
++static GTreeNode*
++g_tree_node_balance (GTreeNode *node)
++{
++ if (node->balance < -1)
++ {
++ if (node->left->balance > 0)
++ node->left = g_tree_node_rotate_left (node->left);
++ node = g_tree_node_rotate_right (node);
++ }
++ else if (node->balance > 1)
++ {
++ if (node->right->balance < 0)
++ node->right = g_tree_node_rotate_right (node->right);
++ node = g_tree_node_rotate_left (node);
++ }
++
++ return node;
++}
++
++static GTreeNode*
++g_tree_node_remove_leftmost (GTreeNode *node,
++ GTreeNode **leftmost)
++{
++ gint old_balance;
++
++ if (!node->left)
++ {
++ *leftmost = node;
++ return node->right;
++ }
++
++ old_balance = node->left->balance;
++ node->left = g_tree_node_remove_leftmost (node->left, leftmost);
++ return g_tree_node_restore_left_balance (node, old_balance);
++}
++
++static GTreeNode*
++g_tree_node_restore_left_balance (GTreeNode *node,
++ gint old_balance)
++{
++ if (!node->left)
++ node->balance += 1;
++ else if ((node->left->balance != old_balance) &&
++ (node->left->balance == 0))
++ node->balance += 1;
++
++ if (node->balance > 1)
++ return g_tree_node_balance (node);
++ return node;
++}
++
++static GTreeNode*
++g_tree_node_restore_right_balance (GTreeNode *node,
++ gint old_balance)
++{
++ if (!node->right)
++ node->balance -= 1;
++ else if ((node->right->balance != old_balance) &&
++ (node->right->balance == 0))
++ node->balance -= 1;
++
++ if (node->balance < -1)
++ return g_tree_node_balance (node);
++ return node;
++}
++
++static gpointer
++g_tree_node_lookup (GTreeNode *node,
++ GCompareFunc compare,
++ gpointer key)
++{
++ gint cmp;
++
++ if (!node)
++ return NULL;
++
++ cmp = (* compare) (key, node->key);
++ if (cmp == 0)
++ return node->value;
++
++ if (cmp < 0)
++ {
++ if (node->left)
++ return g_tree_node_lookup (node->left, compare, key);
++ }
++ else if (cmp > 0)
++ {
++ if (node->right)
++ return g_tree_node_lookup (node->right, compare, key);
++ }
++
++ return NULL;
++}
++
++static gint
++g_tree_node_count (GTreeNode *node)
++{
++ gint count;
++
++ count = 1;
++ if (node->left)
++ count += g_tree_node_count (node->left);
++ if (node->right)
++ count += g_tree_node_count (node->right);
++
++ return count;
++}
++
++static gint
++g_tree_node_pre_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data)
++{
++ if ((*traverse_func) (node->key, node->value, data))
++ return TRUE;
++ if (node->left)
++ {
++ if (g_tree_node_pre_order (node->left, traverse_func, data))
++ return TRUE;
++ }
++ if (node->right)
++ {
++ if (g_tree_node_pre_order (node->right, traverse_func, data))
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++static gint
++g_tree_node_in_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data)
++{
++ if (node->left)
++ {
++ if (g_tree_node_in_order (node->left, traverse_func, data))
++ return TRUE;
++ }
++ if ((*traverse_func) (node->key, node->value, data))
++ return TRUE;
++ if (node->right)
++ {
++ if (g_tree_node_in_order (node->right, traverse_func, data))
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++static gint
++g_tree_node_post_order (GTreeNode *node,
++ GTraverseFunc traverse_func,
++ gpointer data)
++{
++ if (node->left)
++ {
++ if (g_tree_node_post_order (node->left, traverse_func, data))
++ return TRUE;
++ }
++ if (node->right)
++ {
++ if (g_tree_node_post_order (node->right, traverse_func, data))
++ return TRUE;
++ }
++ if ((*traverse_func) (node->key, node->value, data))
++ return TRUE;
++
++ return FALSE;
++}
++
++static gpointer
++g_tree_node_search (GTreeNode *node,
++ GSearchFunc search_func,
++ gpointer data)
++{
++ gint dir;
++
++ if (!node)
++ return NULL;
++
++ do {
++ dir = (* search_func) (node->key, data);
++ if (dir == 0)
++ return node->value;
++
++ if (dir < 0)
++ node = node->left;
++ else if (dir > 0)
++ node = node->right;
++ } while (node && (dir != 0));
++
++ return NULL;
++}
++
++static gint
++g_tree_node_height (GTreeNode *node)
++{
++ gint left_height;
++ gint right_height;
++
++ if (node)
++ {
++ left_height = 0;
++ right_height = 0;
++
++ if (node->left)
++ left_height = g_tree_node_height (node->left);
++
++ if (node->right)
++ right_height = g_tree_node_height (node->right);
++
++ return MAX (left_height, right_height) + 1;
++ }
++
++ return 0;
++}
++
++static GTreeNode*
++g_tree_node_rotate_left (GTreeNode *node)
++{
++ GTreeNode *left;
++ GTreeNode *right;
++ gint a_bal;
++ gint b_bal;
++
++ left = node->left;
++ right = node->right;
++
++ node->right = right->left;
++ right->left = node;
++
++ a_bal = node->balance;
++ b_bal = right->balance;
++
++ if (b_bal <= 0)
++ {
++ if (a_bal >= 1)
++ right->balance = b_bal - 1;
++ else
++ right->balance = a_bal + b_bal - 2;
++ node->balance = a_bal - 1;
++ }
++ else
++ {
++ if (a_bal <= b_bal)
++ right->balance = a_bal - 2;
++ else
++ right->balance = b_bal - 1;
++ node->balance = a_bal - b_bal - 1;
++ }
++
++ return right;
++}
++
++static GTreeNode*
++g_tree_node_rotate_right (GTreeNode *node)
++{
++ GTreeNode *left;
++ gint a_bal;
++ gint b_bal;
++
++ left = node->left;
++
++ node->left = left->right;
++ left->right = node;
++
++ a_bal = node->balance;
++ b_bal = left->balance;
++
++ if (b_bal <= 0)
++ {
++ if (b_bal > a_bal)
++ left->balance = b_bal + 1;
++ else
++ left->balance = a_bal + 2;
++ node->balance = a_bal - b_bal + 1;
++ }
++ else
++ {
++ if (a_bal <= -1)
++ left->balance = b_bal + 1;
++ else
++ left->balance = a_bal + b_bal + 2;
++ node->balance = a_bal + 1;
++ }
++
++ return left;
++}
++
++static void
++g_tree_node_check (GTreeNode *node)
++{
++ gint left_height;
++ gint right_height;
++ gint balance;
++
++ if (node)
++ {
++ left_height = 0;
++ right_height = 0;
++
++ if (node->left)
++ left_height = g_tree_node_height (node->left);
++ if (node->right)
++ right_height = g_tree_node_height (node->right);
++
++ balance = right_height - left_height;
++ if (balance != node->balance)
++ g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
++ "g_tree_node_check: failed: %d ( %d )\n",
++ balance, node->balance);
++
++ if (node->left)
++ g_tree_node_check (node->left);
++ if (node->right)
++ g_tree_node_check (node->right);
++ }
++}
+diff -urN linux-2.4.1/net/korbit/kglib/gutils.c linux-2.4.1-korbit/net/korbit/kglib/gutils.c
+--- linux-2.4.1/net/korbit/kglib/gutils.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/gutils.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1,915 @@
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-1999. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#define G_INLINE_FUNC extern
++#define G_CAN_INLINE 1
++
++#ifdef HAVE_UNISTD_H
++#include <unistd.h>
++#endif
++#include <stdarg.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <errno.h>
++#ifdef HAVE_PWD_H
++#include <pwd.h>
++#endif
++#include <sys/types.h>
++#ifdef HAVE_SYS_PARAM_H
++#include <sys/param.h>
++#endif
++
++#ifdef NATIVE_WIN32
++# define STRICT /* Strict typing, please */
++# include <windows.h>
++# include <direct.h>
++# include <errno.h>
++# include <ctype.h>
++# ifdef _MSC_VER
++# include <io.h>
++# endif /* _MSC_VER */
++#endif /* NATIVE_WIN32 */
++
++/* implement Glib's inline functions
++ */
++#include "glib.h"
++
++#ifdef MAXPATHLEN
++#define G_PATH_LENGTH (MAXPATHLEN + 1)
++#elif defined (PATH_MAX)
++#define G_PATH_LENGTH (PATH_MAX + 1)
++#else /* !MAXPATHLEN */
++#define G_PATH_LENGTH (2048 + 1)
++#endif /* !MAXPATHLEN && !PATH_MAX */
++
++const guint glib_major_version = 1;
++const guint glib_minor_version = 2;
++const guint glib_micro_version = 8;
++const guint glib_interface_age = 8;
++const guint glib_binary_age = 8;
++
++#if defined (NATIVE_WIN32) && defined (__LCC__)
++int __stdcall
++LibMain (void *hinstDll,
++ unsigned long dwReason,
++ void *reserved)
++{
++ return 1;
++}
++#endif /* NATIVE_WIN32 && __LCC__ */
++
++void
++g_atexit (GVoidFunc func)
++{
++ gint result;
++ gchar *error = NULL;
++
++ /* keep this in sync with glib.h */
++
++#ifdef G_NATIVE_ATEXIT
++ result = ATEXIT (func);
++ if (result)
++ error = g_strerror (errno);
++#elif defined (HAVE_ATEXIT)
++# ifdef NeXT /* @#%@! NeXTStep */
++ result = !atexit ((void (*)(void)) func);
++ if (result)
++ error = g_strerror (errno);
++# else
++ result = atexit ((void (*)(void)) func);
++ if (result)
++ error = g_strerror (errno);
++# endif /* NeXT */
++#elif defined (HAVE_ON_EXIT)
++ result = on_exit ((void (*)(int, void *)) func, NULL);
++ if (result)
++ error = g_strerror (errno);
++#else
++ result = 0;
++ error = "no implementation";
++#endif /* G_NATIVE_ATEXIT */
++
++ if (error)
++ g_error ("Could not register atexit() function: %s", error);
++}
++
++gint
++g_snprintf (gchar *str,
++ gulong n,
++ gchar const *fmt,
++ ...)
++{
++#ifdef HAVE_VSNPRINTF
++ va_list args;
++ gint retval;
++
++ g_return_val_if_fail (str != NULL, 0);
++ g_return_val_if_fail (n > 0, 0);
++ g_return_val_if_fail (fmt != NULL, 0);
++
++ va_start (args, fmt);
++ retval = vsnprintf (str, n, fmt, args);
++ va_end (args);
++
++ if (retval < 0)
++ {
++ str[n-1] = '\0';
++ retval = strlen (str);
++ }
++
++ return retval;
++#else /* !HAVE_VSNPRINTF */
++ gchar *printed;
++ va_list args;
++
++ g_return_val_if_fail (str != NULL, 0);
++ g_return_val_if_fail (n > 0, 0);
++ g_return_val_if_fail (fmt != NULL, 0);
++
++ va_start (args, fmt);
++ printed = g_strdup_vprintf (fmt, args);
++ va_end (args);
++
++ strncpy (str, printed, n);
++ str[n-1] = '\0';
++
++ g_free (printed);
++
++ return strlen (str);
++#endif /* !HAVE_VSNPRINTF */
++}
++
++gint
++g_vsnprintf (gchar *str,
++ gulong n,
++ gchar const *fmt,
++ va_list args)
++{
++#ifdef HAVE_VSNPRINTF
++ gint retval;
++
++ g_return_val_if_fail (str != NULL, 0);
++ g_return_val_if_fail (n > 0, 0);
++ g_return_val_if_fail (fmt != NULL, 0);
++
++ retval = vsnprintf (str, n, fmt, args);
++
++ if (retval < 0)
++ {
++ str[n-1] = '\0';
++ retval = strlen (str);
++ }
++
++ return retval;
++#else /* !HAVE_VSNPRINTF */
++ gchar *printed;
++
++ g_return_val_if_fail (str != NULL, 0);
++ g_return_val_if_fail (n > 0, 0);
++ g_return_val_if_fail (fmt != NULL, 0);
++
++ printed = g_strdup_vprintf (fmt, args);
++ strncpy (str, printed, n);
++ str[n-1] = '\0';
++
++ g_free (printed);
++
++ return strlen (str);
++#endif /* !HAVE_VSNPRINTF */
++}
++
++guint
++g_parse_debug_string (const gchar *string,
++ GDebugKey *keys,
++ guint nkeys)
++{
++ guint i;
++ guint result = 0;
++
++ g_return_val_if_fail (string != NULL, 0);
++
++ if (!g_strcasecmp (string, "all"))
++ {
++ for (i=0; i<nkeys; i++)
++ result |= keys[i].value;
++ }
++ else
++ {
++ gchar *str = g_strdup (string);
++ gchar *p = str;
++ gchar *q;
++ gboolean done = FALSE;
++
++ while (*p && !done)
++ {
++ q = strchr (p, ':');
++ if (!q)
++ {
++ q = p + strlen(p);
++ done = TRUE;
++ }
++
++ *q = 0;
++
++ for (i=0; i<nkeys; i++)
++ if (!g_strcasecmp(keys[i].key, p))
++ result |= keys[i].value;
++
++ p = q+1;
++ }
++
++ g_free (str);
++ }
++
++ return result;
++}
++
++gchar*
++g_basename (const gchar *file_name)
++{
++ register gchar *base;
++
++ g_return_val_if_fail (file_name != NULL, NULL);
++
++ base = strrchr (file_name, G_DIR_SEPARATOR);
++ if (base)
++ return base + 1;
++
++#ifdef NATIVE_WIN32
++ if (isalpha (file_name[0]) && file_name[1] == ':')
++ return (gchar*) file_name + 2;
++#endif /* NATIVE_WIN32 */
++
++ return (gchar*) file_name;
++}
++
++gboolean
++g_path_is_absolute (const gchar *file_name)
++{
++ g_return_val_if_fail (file_name != NULL, FALSE);
++
++ if (file_name[0] == G_DIR_SEPARATOR)
++ return TRUE;
++
++#ifdef NATIVE_WIN32
++ if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
++ return TRUE;
++#endif
++
++ return FALSE;
++}
++
++gchar*
++g_path_skip_root (gchar *file_name)
++{
++ g_return_val_if_fail (file_name != NULL, NULL);
++
++ if (file_name[0] == G_DIR_SEPARATOR)
++ return file_name + 1;
++
++#ifdef NATIVE_WIN32
++ if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
++ return file_name + 3;
++#endif
++
++ return NULL;
++}
++
++gchar*
++g_dirname (const gchar *file_name)
++{
++ register gchar *base;
++ register guint len;
++
++ g_return_val_if_fail (file_name != NULL, NULL);
++
++ base = strrchr (file_name, G_DIR_SEPARATOR);
++ if (!base)
++ return g_strdup (".");
++ while (base > file_name && *base == G_DIR_SEPARATOR)
++ base--;
++ len = (guint) 1 + base - file_name;
++
++ base = g_new (gchar, len + 1);
++ g_memmove (base, file_name, len);
++ base[len] = 0;
++
++ return base;
++}
++
++#ifndef __KORBIT__
++gchar*
++g_get_current_dir (void)
++{
++ gchar *buffer;
++ gchar *dir;
++
++ buffer = g_new (gchar, G_PATH_LENGTH);
++ *buffer = 0;
++
++ /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
++ * and, if that wasn't bad enough, hangs in doing so.
++ */
++#if defined (sun) && !defined (__SVR4)
++ dir = getwd (buffer);
++#else /* !sun */
++ dir = getcwd (buffer, G_PATH_LENGTH - 1);
++#endif /* !sun */
++
++ if (!dir || !*buffer)
++ {
++ /* hm, should we g_error() out here?
++ * this can happen if e.g. "./" has mode \0000
++ */
++ buffer[0] = G_DIR_SEPARATOR;
++ buffer[1] = 0;
++ }
++
++ dir = g_strdup (buffer);
++ g_free (buffer);
++
++ return dir;
++}
++#endif /* !__KORBIT__ */
++
++gchar*
++g_getenv (const gchar *variable)
++{
++#ifndef NATIVE_WIN32
++ g_return_val_if_fail (variable != NULL, NULL);
++
++ return getenv (variable);
++#else
++ gchar *v;
++ guint k;
++ static gchar *p = NULL;
++ static gint l;
++ gchar dummy[2];
++
++ g_return_val_if_fail (variable != NULL, NULL);
++
++ v = getenv (variable);
++ if (!v)
++ return NULL;
++
++ /* On Windows NT, it is relatively typical that environment variables
++ * contain references to other environment variables. Handle that by
++ * calling ExpandEnvironmentStrings.
++ */
++
++ /* First check how much space we need */
++ k = ExpandEnvironmentStrings (v, dummy, 2);
++ /* Then allocate that much, and actualy do the expansion */
++ if (p == NULL)
++ {
++ p = g_malloc (k);
++ l = k;
++ }
++ else if (k > l)
++ {
++ p = g_realloc (p, k);
++ l = k;
++ }
++ ExpandEnvironmentStrings (v, p, k);
++ return p;
++#endif
++}
++
++
++G_LOCK_DEFINE_STATIC (g_utils_global);
++
++static gchar *g_tmp_dir = NULL;
++static gchar *g_user_name = NULL;
++static gchar *g_real_name = NULL;
++static gchar *g_home_dir = NULL;
++
++/* HOLDS: g_utils_global_lock */
++static void
++g_get_any_init (void)
++{
++ if (!g_tmp_dir)
++ {
++ g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
++ if (!g_tmp_dir)
++ g_tmp_dir = g_strdup (g_getenv ("TMP"));
++ if (!g_tmp_dir)
++ g_tmp_dir = g_strdup (g_getenv ("TEMP"));
++
++#ifdef P_tmpdir
++ if (!g_tmp_dir)
++ {
++ int k;
++ g_tmp_dir = g_strdup (P_tmpdir);
++ k = strlen (g_tmp_dir);
++ if (g_tmp_dir[k-1] == G_DIR_SEPARATOR)
++ g_tmp_dir[k-1] = '\0';
++ }
++#endif
++
++ if (!g_tmp_dir)
++ {
++#ifndef NATIVE_WIN32
++ g_tmp_dir = g_strdup ("/tmp");
++#else /* NATIVE_WIN32 */
++ g_tmp_dir = g_strdup ("C:\\");
++#endif /* NATIVE_WIN32 */
++ }
++
++ if (!g_home_dir)
++ g_home_dir = g_strdup (g_getenv ("HOME"));
++
++#ifdef NATIVE_WIN32
++ if (!g_home_dir)
++ {
++ /* The official way to specify a home directory on NT is
++ * the HOMEDRIVE and HOMEPATH environment variables.
++ *
++ * This is inside #ifdef NATIVE_WIN32 because with the cygwin dll,
++ * HOME should be a POSIX style pathname.
++ */
++
++ if (getenv ("HOMEDRIVE") != NULL && getenv ("HOMEPATH") != NULL)
++ {
++ gchar *homedrive, *homepath;
++
++ homedrive = g_strdup (g_getenv ("HOMEDRIVE"));
++ homepath = g_strdup (g_getenv ("HOMEPATH"));
++
++ g_home_dir = g_strconcat (homedrive, homepath, NULL);
++ g_free (homedrive);
++ g_free (homepath);
++ }
++ }
++#endif /* !NATIVE_WIN32 */
++
++#ifdef HAVE_PWD_H
++ {
++ struct passwd *pw = NULL;
++ gpointer buffer = NULL;
++
++# ifdef HAVE_GETPWUID_R
++ struct passwd pwd;
++ guint bufsize = 64;
++ gint error;
++
++ do
++ {
++ g_free (buffer);
++ buffer = g_malloc (bufsize);
++ errno = 0;
++
++# ifdef HAVE_GETPWUID_R_POSIX
++ error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
++ error = error < 0 ? errno : error;
++# else /* !HAVE_GETPWUID_R_POSIX */
++# ifdef _AIX
++ error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
++ pw = error == 0 ? &pwd : NULL;
++# else /* !_AIX */
++ pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
++ error = pw ? 0 : errno;
++# endif /* !_AIX */
++# endif /* !HAVE_GETPWUID_R_POSIX */
++
++ if (!pw)
++ {
++ /* we bail out prematurely if the user id can't be found
++ * (should be pretty rare case actually), or if the buffer
++ * should be sufficiently big and lookups are still not
++ * successfull.
++ */
++ if (error == 0 || error == ENOENT)
++ {
++ g_warning ("getpwuid_r(): failed due to: No such user %d.",
++ getuid ());
++ break;
++ }
++ if (bufsize > 32 * 1024)
++ {
++ g_warning ("getpwuid_r(): failed due to: %s.",
++ g_strerror (error));
++ break;
++ }
++
++ bufsize *= 2;
++ }
++ }
++ while (!pw);
++# endif /* !HAVE_GETPWUID_R */
++
++ if (!pw)
++ {
++ setpwent ();
++ pw = getpwuid (getuid ());
++ endpwent ();
++ }
++ if (pw)
++ {
++ g_user_name = g_strdup (pw->pw_name);
++ g_real_name = g_strdup (pw->pw_gecos);
++ if (!g_home_dir)
++ g_home_dir = g_strdup (pw->pw_dir);
++ }
++ g_free (buffer);
++ }
++
++#else /* !HAVE_PWD_H */
++
++# ifdef NATIVE_WIN32
++ {
++ guint len = 17;
++ gchar buffer[17];
++
++ if (GetUserName (buffer, &len))
++ {
++ g_user_name = g_strdup (buffer);
++ g_real_name = g_strdup (buffer);
++ }
++ }
++# endif /* NATIVE_WIN32 */
++
++#endif /* !HAVE_PWD_H */
++
++ if (!g_user_name)
++ g_user_name = g_strdup ("somebody");
++ if (!g_real_name)
++ g_real_name = g_strdup ("Unknown");
++ else
++ {
++ gchar *p;
++
++ for (p = g_real_name; *p; p++)
++ if (*p == ',')
++ {
++ *p = 0;
++ p = g_strdup (g_real_name);
++ g_free (g_real_name);
++ g_real_name = p;
++ break;
++ }
++ }
++ }
++}
++
++gchar*
++g_get_user_name (void)
++{
++ G_LOCK (g_utils_global);
++ if (!g_tmp_dir)
++ g_get_any_init ();
++ G_UNLOCK (g_utils_global);
++
++ return g_user_name;
++}
++
++gchar*
++g_get_real_name (void)
++{
++ G_LOCK (g_utils_global);
++ if (!g_tmp_dir)
++ g_get_any_init ();
++ G_UNLOCK (g_utils_global);
++
++ return g_real_name;
++}
++
++/* Return the home directory of the user. If there is a HOME
++ * environment variable, its value is returned, otherwise use some
++ * system-dependent way of finding it out. If no home directory can be
++ * deduced, return NULL.
++ */
++
++gchar*
++g_get_home_dir (void)
++{
++ G_LOCK (g_utils_global);
++ if (!g_tmp_dir)
++ g_get_any_init ();
++ G_UNLOCK (g_utils_global);
++
++ return g_home_dir;
++}
++
++/* Return a directory to be used to store temporary files. This is the
++ * value of the TMPDIR, TMP or TEMP environment variables (they are
++ * checked in that order). If none of those exist, use P_tmpdir from
++ * stdio.h. If that isn't defined, return "/tmp" on POSIXly systems,
++ * and C:\ on Windows.
++ */
++
++gchar*
++g_get_tmp_dir (void)
++{
++ G_LOCK (g_utils_global);
++ if (!g_tmp_dir)
++ g_get_any_init ();
++ G_UNLOCK (g_utils_global);
++
++ return g_tmp_dir;
++}
++
++static gchar *g_prgname = NULL;
++
++gchar*
++g_get_prgname (void)
++{
++ gchar* retval;
++
++ G_LOCK (g_utils_global);
++ retval = g_prgname;
++ G_UNLOCK (g_utils_global);
++
++ return retval;
++}
++
++void
++g_set_prgname (const gchar *prgname)
++{
++ gchar *c;
++
++ G_LOCK (g_utils_global);
++ c = g_prgname;
++ g_prgname = g_strdup (prgname);
++ g_free (c);
++ G_UNLOCK (g_utils_global);
++}
++
++guint
++g_direct_hash (gconstpointer v)
++{
++ return GPOINTER_TO_UINT (v);
++}
++
++gint
++g_direct_equal (gconstpointer v1,
++ gconstpointer v2)
++{
++ return v1 == v2;
++}
++
++gint
++g_int_equal (gconstpointer v1,
++ gconstpointer v2)
++{
++ return *((const gint*) v1) == *((const gint*) v2);
++}
++
++guint
++g_int_hash (gconstpointer v)
++{
++ return *(const gint*) v;
++}
++
++#if 0 /* Old IO Channels */
++
++GIOChannel*
++g_iochannel_new (gint fd)
++{
++ GIOChannel *channel = g_new (GIOChannel, 1);
++
++ channel->fd = fd;
++
++#ifdef NATIVE_WIN32
++ channel->peer = 0;
++ channel->peer_fd = 0;
++ channel->offset = 0;
++ channel->need_wakeups = 0;
++#endif /* NATIVE_WIN32 */
++
++ return channel;
++}
++
++void
++g_iochannel_free (GIOChannel *channel)
++{
++ g_return_if_fail (channel != NULL);
++
++ g_free (channel);
++}
++
++void
++g_iochannel_close_and_free (GIOChannel *channel)
++{
++ g_return_if_fail (channel != NULL);
++
++ close (channel->fd);
++
++ g_iochannel_free (channel);
++}
++
++#undef g_iochannel_wakeup_peer
++
++void
++g_iochannel_wakeup_peer (GIOChannel *channel)
++{
++#ifdef NATIVE_WIN32
++ static guint message = 0;
++#endif
++
++ g_return_if_fail (channel != NULL);
++
++#ifdef NATIVE_WIN32
++ if (message == 0)
++ message = RegisterWindowMessage ("gdk-pipe-readable");
++
++# if 0
++ g_print ("g_iochannel_wakeup_peer: calling PostThreadMessage (%#x, %d, %d, %d)\n",
++ channel->peer, message, channel->peer_fd, channel->offset);
++# endif
++ PostThreadMessage (channel->peer, message,
++ channel->peer_fd, channel->offset);
++#endif /* NATIVE_WIN32 */
++}
++
++#endif /* Old IO Channels */
++
++#ifdef NATIVE_WIN32
++#ifdef _MSC_VER
++
++int
++gwin_ftruncate (gint fd,
++ guint size)
++{
++ HANDLE hfile;
++ guint curpos;
++
++ g_return_val_if_fail (fd >= 0, -1);
++
++ hfile = (HANDLE) _get_osfhandle (fd);
++ curpos = SetFilePointer (hfile, 0, NULL, FILE_CURRENT);
++ if (curpos == 0xFFFFFFFF
++ || SetFilePointer (hfile, size, NULL, FILE_BEGIN) == 0xFFFFFFFF
++ || !SetEndOfFile (hfile))
++ {
++ gint error = GetLastError ();
++
++ switch (error)
++ {
++ case ERROR_INVALID_HANDLE:
++ errno = EBADF;
++ break;
++ default:
++ errno = EIO;
++ break;
++ }
++
++ return -1;
++ }
++
++ return 0;
++}
++
++DIR*
++gwin_opendir (const char *dirname)
++{
++ DIR *result;
++ gchar *mask;
++ guint k;
++
++ g_return_val_if_fail (dirname != NULL, NULL);
++
++ result = g_new0 (DIR, 1);
++ result->find_file_data = g_new0 (WIN32_FIND_DATA, 1);
++ result->dir_name = g_strdup (dirname);
++
++ k = strlen (result->dir_name);
++ if (k && result->dir_name[k - 1] == '\\')
++ {
++ result->dir_name[k - 1] = '\0';
++ k--;
++ }
++ mask = g_strdup_printf ("%s\\*", result->dir_name);
++
++ result->find_file_handle = (guint) FindFirstFile (mask,
++ (LPWIN32_FIND_DATA) result->find_file_data);
++ g_free (mask);
++
++ if (result->find_file_handle == (guint) INVALID_HANDLE_VALUE)
++ {
++ int error = GetLastError ();
++
++ g_free (result->dir_name);
++ g_free (result->find_file_data);
++ g_free (result);
++ switch (error)
++ {
++ default:
++ errno = EIO;
++ return NULL;
++ }
++ }
++ result->just_opened = TRUE;
++
++ return result;
++}
++
++struct dirent*
++gwin_readdir (DIR *dir)
++{
++ static struct dirent result;
++
++ g_return_val_if_fail (dir != NULL, NULL);
++
++ if (dir->just_opened)
++ dir->just_opened = FALSE;
++ else
++ {
++ if (!FindNextFile ((HANDLE) dir->find_file_handle,
++ (LPWIN32_FIND_DATA) dir->find_file_data))
++ {
++ int error = GetLastError ();
++
++ switch (error)
++ {
++ case ERROR_NO_MORE_FILES:
++ return NULL;
++ default:
++ errno = EIO;
++ return NULL;
++ }
++ }
++ }
++ strcpy (result.d_name, g_basename (((LPWIN32_FIND_DATA) dir->find_file_data)->cFileName));
++
++ return &result;
++}
++
++void
++gwin_rewinddir (DIR *dir)
++{
++ gchar *mask;
++
++ g_return_if_fail (dir != NULL);
++
++ if (!FindClose ((HANDLE) dir->find_file_handle))
++ g_warning ("gwin_rewinddir(): FindClose() failed\n");
++
++ mask = g_strdup_printf ("%s\\*", dir->dir_name);
++ dir->find_file_handle = (guint) FindFirstFile (mask,
++ (LPWIN32_FIND_DATA) dir->find_file_data);
++ g_free (mask);
++
++ if (dir->find_file_handle == (guint) INVALID_HANDLE_VALUE)
++ {
++ int error = GetLastError ();
++
++ switch (error)
++ {
++ default:
++ errno = EIO;
++ return;
++ }
++ }
++ dir->just_opened = TRUE;
++}
++
++gint
++gwin_closedir (DIR *dir)
++{
++ g_return_val_if_fail (dir != NULL, -1);
++
++ if (!FindClose ((HANDLE) dir->find_file_handle))
++ {
++ int error = GetLastError ();
++
++ switch (error)
++ {
++ default:
++ errno = EIO; return -1;
++ }
++ }
++
++ g_free (dir->dir_name);
++ g_free (dir->find_file_data);
++ g_free (dir);
++
++ return 0;
++}
++
++#endif /* _MSC_VER */
++
++#endif /* NATIVE_WIN32 */
+diff -urN linux-2.4.1/net/korbit/kglib/korbit_errno.c linux-2.4.1-korbit/net/korbit/kglib/korbit_errno.c
+--- linux-2.4.1/net/korbit/kglib/korbit_errno.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/kglib/korbit_errno.c Thu Feb 1 11:46:57 2001
+@@ -0,0 +1 @@
++int korbit_errno;
+diff -urN linux-2.4.1/net/korbit/korbit.h linux-2.4.1-korbit/net/korbit/korbit.h
+--- linux-2.4.1/net/korbit/korbit.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/korbit.h Thu Feb 1 11:46:49 2001
+@@ -0,0 +1,53 @@
++
++#ifndef KORBIT_H
++#define KORBIT_H
++
++#ifdef __KERNEL__
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/proc_fs.h>
++#endif
++
++#include "stdlib.h"
++
++#ifdef __KERNEL__
++static int korbit_get_ior_func(char *buffer, char **start, off_t offset,
++ int length, int *eof, void *data) {
++ int Len = strlen((char*)data);
++ memcpy(buffer, data, Len); // Data is the ior...
++ buffer[Len++] = '\n'; // Add a newline to make fredrik happy
++ buffer[Len] = 0; // Null terminate the buffer...
++ *start = buffer + offset;
++ *eof = 1;
++
++ Len -= offset;
++ if (Len > length)
++ Len = length;
++ if (Len < 0)
++ Len = 0;
++
++ return Len;
++}
++
++#endif
++
++
++static inline void korbit_register_ior(const char *name, CORBA_Object obj,
++ CORBA_ORB orb, CORBA_Environment *ev) {
++ char *retval = CORBA_ORB_object_to_string(orb, obj, ev);
++#if defined(__KERNEL__) && defined(CONFIG_PROC_FS)
++ char *procdirname = malloc(strlen(name)+7); // 7 = len("corba/\0")
++ strcpy(procdirname, "corba/");
++ strcpy(procdirname+6, name);
++
++ create_proc_read_entry(procdirname, 0, 0, korbit_get_ior_func, retval);
++
++ free(procdirname);
++ // Don't free the ior in the /proc handling case...
++#else
++ // No procfs support, just print to console... :(
++ g_print("%s IOR:\n%s\n", name, retval);
++ CORBA_free(retval);
++#endif
++}
++#endif
+diff -urN linux-2.4.1/net/korbit/modules/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CVS/Entries Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,5 @@
++/Config.in/1.8/Thu Feb 1 09:46:58 2001//
++/Makefile/1.8/Thu Feb 1 09:46:58 2001//
++/Makefile.module/1.2/Thu Feb 1 09:46:58 2001//
++/README/1.1/Thu Feb 1 09:46:58 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CVS/Entries.Log Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,6 @@
++A D/CharDev////
++A D/Console////
++A D/CorbaFS////
++A D/Echo////
++A D/FileServer////
++A D/UserFS////
+diff -urN linux-2.4.1/net/korbit/modules/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CVS/Repository Thu Feb 1 11:46:57 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules
+diff -urN linux-2.4.1/net/korbit/modules/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CVS/Root Thu Feb 1 11:46:57 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CharDev/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Entries Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,4 @@
++/Makefile/1.3/Thu Feb 1 09:46:58 2001//
++/README/1.1/Thu Feb 1 09:46:58 2001//
++/chardev.idl/1.1/Thu Feb 1 09:46:58 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/CharDev/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Entries.Log Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,3 @@
++A D/kernel////
++A D/kernel-perl////
++A D/userspace////
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CharDev/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Repository Thu Feb 1 11:46:58 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CharDev
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CharDev/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/CVS/Root Thu Feb 1 11:46:58 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/Makefile linux-2.4.1-korbit/net/korbit/modules/CharDev/Makefile
+--- linux-2.4.1/net/korbit/modules/CharDev/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/Makefile Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,11 @@
++#
++# Makefile for KORBit - CharDev
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_CHARDEV) := kernel
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/README linux-2.4.1-korbit/net/korbit/modules/CharDev/README
+--- linux-2.4.1/net/korbit/modules/CharDev/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/README Thu Feb 1 11:46:58 2001
+@@ -0,0 +1 @@
++This module is used to implement a character device with kORBit.
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/chardev.idl linux-2.4.1-korbit/net/korbit/modules/CharDev/chardev.idl
+--- linux-2.4.1/net/korbit/modules/CharDev/chardev.idl Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/chardev.idl Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,5 @@
++typedef sequence<octet> Buffer;
++
++interface CharDev {
++ long read(out Buffer buffer, in long size);
++};
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Entries Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,4 @@
++/Makefile/1.2/Thu Feb 1 09:46:59 2001//
++/README/1.2/Thu Feb 1 09:46:59 2001//
++/chardev-kernel.c/1.9/Thu Feb 1 09:46:59 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Repository Thu Feb 1 11:46:59 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CharDev/kernel
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/CVS/Root Thu Feb 1 11:46:59 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/Makefile linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/Makefile
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/Makefile Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,20 @@
++#
++# Makefile for KORBit / chardev
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-chardev-kernel.o
++
++obj-y := chardev-common.o chardev-stubs.o chardev-kernel.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++chardev-kernel.c: chardev.h
++
++chardev.h chardev-stubs.c chardev-common.c: ../chardev.idl
++ $(ORBIT_IDL) ../chardev.idl
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/README linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/README
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/README Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,5 @@
++This module is used to implement the kernel side of the CORBA Character
++device.
++
++ORB: kORBit
++Status: Working!!!
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel/chardev-kernel.c linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/chardev-kernel.c
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel/chardev-kernel.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel/chardev-kernel.c Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,140 @@
++//-----------------------------------------------------------------------------
++//
++// chardev-kernel - Kernel miscdevice to CORBA glue.
++//
++// This file implements a standard Linux Kernel "miscdevice". This device
++// operates by forwarding all calls across to a remote CORBA server. This
++// server is located by reading the file /tmp/chardev-ior at the time the
++// device is opened. The device exported is major #10, minor #42. Create this
++// device with 'mknod' like all the others.
++//
++// No implementations of CORBA functions should block, although I think it
++// might be just fine, I'm not sure. Let's just make this a TODO. :) -CAL
++//
++// TODO: Locking, finish exporting all "miscdevice" functions, send position
++// on READ request.
++//
++// History:
++// Keith Wessel - Initial hack, initial idea
++// Andy Reitz - Get it to compile
++// Chris Lattner - Make it work. :)
++//
++//-----------------------------------------------------------------------------
++
++
++#include "chardev.h"
++#include <stdio.h>
++#include "orb/orbit.h"
++#include "korbit.h"
++#include <linux/miscdevice.h>
++
++#define DEV_MINOR 42
++
++CORBA_ORB orb;
++CORBA_Environment *ev;
++
++static int open_dev(struct inode *inode, struct file *file) {
++ char *iorstr = (char *)malloc(10240);
++ int error = -EINVAL;
++ int fd, len;
++
++ if (iorstr == 0) return -ENOMEM;
++
++ if ((fd = open ("/tmp/chardev-ior", O_RDONLY, 0)) == -1) {
++ printk("kORBit: chararacter driver couldn't open /tmp/chardev-ior!\n");
++ goto outfree;
++ }
++
++ len = read(fd, iorstr, 10240);
++ close(fd);
++ if (len == -1)
++ goto outfree;
++
++ iorstr[len] = 0; // Null terminate string!
++
++ printk("CharDEV IOR String = %s\n", iorstr);
++ file->private_data = (void*)CORBA_ORB_string_to_object(orb, iorstr, ev);
++ if (!file->private_data)
++ goto outfree;
++
++ // TODO: Send create_dev message out over CORBA
++
++ error = 0;
++ outfree:
++ free(iorstr);
++ return error;
++}
++
++static int release_dev(struct inode *inode, struct file *file) {
++ // TODO: Send release_dev message out over CORBA...
++ if (file->private_data)
++ CORBA_free(file->private_data);
++ return 0;
++}
++
++
++static ssize_t read_dev(struct file * file, char * buf, size_t count,
++ loff_t *ppos) {
++ Buffer *octet_buffer = NULL;
++ if (!file->private_data) return -EINVAL;
++ if (!count) return 0;
++
++ if (!access_ok(VERIFY_WRITE, buf, count))
++ return -EFAULT;
++
++ CharDev_read(file->private_data, &octet_buffer, count, ev);
++
++ if (!octet_buffer)
++ return -EPERM;
++
++ if (copy_to_user(buf, octet_buffer->_buffer, octet_buffer->_length))
++ return -EFAULT;
++
++ // TODO: Should free octet_buffer here!?!?!?
++
++ return octet_buffer->_length;
++}
++
++
++//-----------------------------------------------------------------------------
++// Kernel Callbacks for miscdevice
++//-----------------------------------------------------------------------------
++
++
++static struct file_operations dev_fops = {
++ owner: THIS_MODULE,
++ open: open_dev,
++ read: read_dev,
++ release: release_dev,
++ // mmap: mmap_dev,
++ // llseek: llseek_dev,
++ // write: write_dev,
++};
++
++static struct miscdevice cdev = {
++ DEV_MINOR,
++ "CORBA Character device",
++ &dev_fops
++};
++
++
++//-----------------------------------------------------------------------------
++// Module Initializion/Finalization
++//-----------------------------------------------------------------------------
++
++static int __init CharDev_init(void) {
++ int argc = 1;
++ char *argv[] = { "CharDev-kernel", 0 };
++ ev = g_new0(CORBA_Environment,1);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++
++ // Register the device
++ return misc_register(&cdev);
++}
++
++static void __exit CharDev_exit(void) {
++ misc_deregister(&cdev);
++}
++
++module_init(CharDev_init)
++module_exit(CharDev_exit)
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Entries Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,3 @@
++/PerlTest/1.1/Thu Feb 1 09:46:59 2001//
++/README/1.1/Thu Feb 1 09:46:59 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Repository Thu Feb 1 11:46:59 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CharDev/kernel-perl
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/CVS/Root Thu Feb 1 11:46:59 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/PerlTest linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/PerlTest
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/PerlTest Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/PerlTest Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,17 @@
++#!/usr/bin/perl -w
++
++use CORBA::ORBit idl => [ qw(../chardev.idl) ];
++use Error qw(:try);
++use strict;
++
++my $orb = CORBA::ORB_init("orbit-local-orb");
++open IOR, "/tmp/chardev-ior" or die "no chardev server found!";
++my $ior = <IOR>;
++close IOR;
++#chomp($ior); # Kill fredrik's newline...
++
++my $chardev = $orb->string_to_object($ior);
++# Echo echoString(in string astring, out long anum);
++my ($ressize, $buf) = $chardev->read(10);
++
++print "Return size = $ressize\nresult = $buf\n";
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/README linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/README
+--- linux-2.4.1/net/korbit/modules/CharDev/kernel-perl/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/kernel-perl/README Thu Feb 1 11:46:59 2001
+@@ -0,0 +1,6 @@
++This module is used to test the user side of the CORBA Character
++device. It doesn't do anything really complex, just implements a quick
++sanity test for the server.
++
++ORB: ORBit - Perl
++Status: Working!
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Entries Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,6 @@
++/Makefile/1.5/Thu Feb 1 09:47:00 2001//
++/README/1.1/Thu Feb 1 09:47:00 2001//
++/RunServer.sh/1.1/Thu Feb 1 09:47:00 2001//
++/chardev-server.c/1.5/Thu Feb 1 09:47:00 2001//
++/chardev-skelimpl.c/1.5/Thu Feb 1 09:47:00 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Repository Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CharDev/userspace
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/CVS/Root Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/Makefile linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/Makefile
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/Makefile Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,30 @@
++#
++# Makefile for KORBit / CharDev
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++CFLAGS = -Wall -I/usr/lib/glib/include
++LDFLAGS = -lORBit -lIIOP -lORBitutil
++OBJS = chardev-common.o chardev-skels.o chardev-server.o
++ORBIT-IDL = /usr/bin/orbit-idl
++
++chardev-server: $(OBJS)
++ gcc -o chardev-server $(OBJS) $(LDFLAGS)
++
++chardev-server.o: chardev.h chardev-skelimpl.c
++
++chardev.h chardev-skels.c chardev-common.c: ../chardev.idl
++ $(ORBIT-IDL) ../chardev.idl
++
++chardev-skelimpl.c:
++
++%.o: %.c
++ gcc -c $< $(CFLAGS)
++clean:
++ rm -f $(OBJS) chardev-server chardev-common.c chardev-skels.c \
++ chardev-stubs.c chardev.h
++
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/README linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/README
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/README Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,4 @@
++This is an example character driver.
++
++ORB: ORBit
++Status: not yet working
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/RunServer.sh linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/RunServer.sh
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/RunServer.sh Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/RunServer.sh Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++./chardev-server -ORBIIOPUSock=0 -ORBIIOPIPv4=1
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/chardev-server.c linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/chardev-server.c
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/chardev-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/chardev-server.c Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,77 @@
++//-----------------------------------------------------------------------------
++//
++// chardev-server.c - TEST Kernel miscdevice implementation
++//
++// This file implements the standard server code for a userspace server. This
++// is basically cut and paste boilerplate code adapted from the CorbaFS server
++// by Fredrik Vraalsen.
++//
++// TODO: Locking, finish exporting all "miscdevice" functions, send position
++// on READ request.
++//
++// History:
++// Keith Wessel - Initial hack, initial idea
++// Andy Reitz - Get it to compile
++// Chris Lattner - Hack'n'slash, make it work, comment it, kill warnings.
++//
++//-----------------------------------------------------------------------------
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <signal.h>
++#include <orb/orbit.h>
++
++// #include the C file because all the functions are static. Bizarre.
++#include "chardev-skelimpl.c"
++
++int main(int argc, char *argv[]) {
++ PortableServer_POA poa;
++ PortableServer_POAManager pm;
++
++ CharDev chardev = CORBA_OBJECT_NIL;
++ impl_POA_CharDev *chardev_impl;
++ PortableServer_ObjectId *objid;
++
++ CORBA_Environment ev;
++ char *retval;
++ CORBA_ORB orb;
++ FILE *IORFILE;
++
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
++ poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", &ev);
++
++ chardev = impl_CharDev__create(poa, &ev);
++ pm = PortableServer_POA__get_the_POAManager(poa, &ev);
++ PortableServer_POAManager_activate(pm, &ev);
++
++ if (!chardev) {
++ printf("Cannot get objref\n");
++ return 1;
++ }
++
++ chardev_impl = PortableServer_POA_reference_to_servant(poa, chardev, &ev);
++ objid = PortableServer_POA_servant_to_id(poa, chardev_impl, &ev);
++
++ retval = CORBA_ORB_object_to_string(orb, chardev, &ev);
++
++ g_print("FYI, this also goes into /tmp/chardev-ior for you.\n");
++ g_print("%s\n", retval); fflush(stdout);
++
++ IORFILE = fopen ("/tmp/chardev-ior", "w");
++ if (IORFILE == NULL) {
++ perror("ERROR: IOR_WRITE_TO_DISK");
++ exit(1);
++ }
++
++ fprintf(IORFILE, "%s", retval);
++ fclose(IORFILE);
++
++ CORBA_free(retval); // Free the corba string like a good little CORBear
++
++
++ // La dee dah... I will never return for you mister.
++ CORBA_ORB_run(orb, &ev);
++ return 0;
++}
++
+diff -urN linux-2.4.1/net/korbit/modules/CharDev/userspace/chardev-skelimpl.c linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/chardev-skelimpl.c
+--- linux-2.4.1/net/korbit/modules/CharDev/userspace/chardev-skelimpl.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CharDev/userspace/chardev-skelimpl.c Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,119 @@
++//-----------------------------------------------------------------------------
++//
++// chardev-skelimpl.c - TEST Kernel miscdevice implementation
++//
++// This file implements a CORBA "miscdevice" (character device node).
++// This device simply outputs a fixed string (set by "message", below) when
++// cat'd. Pretty simple stuff, but you can obviously do much more creative
++// things with it.
++//
++// TODO: Locking, finish exporting all "miscdevice" functions, send position
++// on READ request.
++//
++// Right now we have ONE server object with global state, so that when you
++// read the string from that object, it is finished. This should be reset
++// whenever an open request is had or when the file position is reset (duh).
++//
++// History:
++// Keith Wessel - Initial hack, initial idea
++// Andy Reitz - Get it to compile
++// Chris Lattner - Make it work, comment it, no warnings.
++//
++//-----------------------------------------------------------------------------
++
++#include "chardev.h"
++
++// The message to spit out.
++const char *message = "Hello world!\nI love kORBit\n";
++
++
++/*** App-specific servant structures ***/
++
++typedef struct
++{
++ POA_CharDev servant;
++ PortableServer_POA poa;
++ int AmountRead;
++
++}
++impl_POA_CharDev;
++
++/*** Implementation stub prototypes ***/
++
++static inline void impl_CharDev__destroy(impl_POA_CharDev * servant,
++ CORBA_Environment * ev);
++static CORBA_long
++impl_CharDev_read(impl_POA_CharDev * servant,
++ Buffer ** buffer, CORBA_long size, CORBA_Environment * ev);
++
++/*** epv structures ***/
++
++static PortableServer_ServantBase__epv impl_CharDev_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_CharDev__epv impl_CharDev_epv = {
++ NULL, /* _private */
++ (gpointer) & impl_CharDev_read,
++
++};
++
++/*** vepv structures ***/
++
++static POA_CharDev__vepv impl_CharDev_vepv = {
++ &impl_CharDev_base_epv,
++ &impl_CharDev_epv,
++};
++
++/*** Stub implementations ***/
++
++static CharDev
++impl_CharDev__create(PortableServer_POA poa, CORBA_Environment * ev)
++{
++ CharDev retval;
++ impl_POA_CharDev *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_CharDev, 1);
++ newservant->servant.vepv = &impl_CharDev_vepv;
++ newservant->poa = poa;
++ newservant->AmountRead = 0; // Initialize chardev stuff...
++
++ POA_CharDev__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static inline void
++impl_CharDev__destroy(impl_POA_CharDev * servant, CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_CharDev__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static CORBA_long
++impl_CharDev_read(impl_POA_CharDev * servant,
++ Buffer ** buffer, CORBA_long ReqSize, CORBA_Environment * ev)
++{
++ int AvailSize = strlen(message)-servant->AmountRead;
++ CORBA_long retval = (ReqSize > AvailSize) ? AvailSize : ReqSize;
++
++ *buffer = Buffer__alloc();
++ (*buffer)->_buffer = CORBA_octet_allocbuf(retval);
++ (*buffer)->_length = retval;
++
++ strncpy((*buffer)->_buffer, message + servant->AmountRead, retval);
++ servant->AmountRead += retval;
++ return retval;
++}
++
+diff -urN linux-2.4.1/net/korbit/modules/Config.in linux-2.4.1-korbit/net/korbit/modules/Config.in
+--- linux-2.4.1/net/korbit/modules/Config.in Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Config.in Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,11 @@
++# Console server
++#
++dep_tristate ' CORBA Console Server (EXPERIMENTAL)' CONFIG_CORBA_CONSOLE $CONFIG_KORBIT
++
++dep_tristate ' CORBA Echo Server (EXPERIMENTAL)' CONFIG_CORBA_ECHO $CONFIG_KORBIT
++
++dep_tristate ' CORBA FileSystem Access (EXPERIMENTAL)' CONFIG_CORBA_FILESERVER $CONFIG_KORBIT
++
++dep_tristate ' CORBA User-space FileSystem (EXPERIMENTAL)' CONFIG_CORBA_CORBAFS $CONFIG_KORBIT
++
++dep_tristate ' CORBA Character Device Interface (EXPERIMENTAL)' CONFIG_CORBA_CHARDEV $CONFIG_KORBIT
+diff -urN linux-2.4.1/net/korbit/modules/Console/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Console/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Entries Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,4 @@
++/Makefile/1.2/Thu Feb 1 09:47:00 2001//
++/README/1.1/Thu Feb 1 09:47:00 2001//
++/console.idl/1.1/Thu Feb 1 09:47:00 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Console/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/Console/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Entries.Log Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,3 @@
++A D/PerlClient////
++A D/client////
++A D/server////
+diff -urN linux-2.4.1/net/korbit/modules/Console/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Console/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Repository Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Console
+diff -urN linux-2.4.1/net/korbit/modules/Console/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Console/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/CVS/Root Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Console/Makefile linux-2.4.1-korbit/net/korbit/modules/Console/Makefile
+--- linux-2.4.1/net/korbit/modules/Console/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/Makefile Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,11 @@
++#
++# Makefile for KORBit/modules/Console
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_CONSOLE) := server
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Entries Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,3 @@
++/Client/1.1/Thu Feb 1 09:47:01 2001//
++/README/1.1/Thu Feb 1 09:47:01 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Repository Thu Feb 1 11:47:01 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Console/PerlClient
+diff -urN linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Console/PerlClient/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/CVS/Root Thu Feb 1 11:47:01 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Console/PerlClient/Client linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/Client
+--- linux-2.4.1/net/korbit/modules/Console/PerlClient/Client Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/Client Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,14 @@
++#!/usr/bin/perl -w
++
++use CORBA::ORBit idl => [ qw(../console.idl) ];
++use Error qw(:try);
++use strict;
++
++my $orb = CORBA::ORB_init("orbit-local-orb");
++open IOR, "/proc/corba/console-server" or die "no console server found!";
++my $ior = <IOR>;
++close IOR;
++chomp($ior); # Kill fredrik's newline...
++
++my $console = $orb->string_to_object($ior);
++$console->print("Hello Strange World");
+diff -urN linux-2.4.1/net/korbit/modules/Console/PerlClient/README linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/README
+--- linux-2.4.1/net/korbit/modules/Console/PerlClient/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/PerlClient/README Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,3 @@
++This is a perl client for the Console server.
++
++ORB: ORBit
+diff -urN linux-2.4.1/net/korbit/modules/Console/README linux-2.4.1-korbit/net/korbit/modules/Console/README
+--- linux-2.4.1/net/korbit/modules/Console/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/README Thu Feb 1 11:47:00 2001
+@@ -0,0 +1 @@
++The "hello world" testcase. This is used to write a string to the linux console.
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Console/client/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Entries Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,4 @@
++/Makefile/1.2/Thu Feb 1 09:47:01 2001//
++/README/1.1/Thu Feb 1 09:47:01 2001//
++/console-client.c/1.1/Thu Feb 1 09:47:01 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Console/client/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Repository Thu Feb 1 11:47:01 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Console/client
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Console/client/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/CVS/Root Thu Feb 1 11:47:01 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/Makefile linux-2.4.1-korbit/net/korbit/modules/Console/client/Makefile
+--- linux-2.4.1/net/korbit/modules/Console/client/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/Makefile Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = console
++
++CFLAGS = -Wall `orbit-config --cflags client` -I../../..
++LDFLAGS = `orbit-config --libs client`
++OBJS = $(PROJECT)-common.o $(PROJECT)-stubs.o $(PROJECT)-client.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-client: $(OBJS)
++ gcc -o $(PROJECT)-client $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-client.c: $(PROJECT).h
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-stubs.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --noskels ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-client
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-stubs.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/README linux-2.4.1-korbit/net/korbit/modules/Console/client/README
+--- linux-2.4.1/net/korbit/modules/Console/client/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/README Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,3 @@
++C Client to access console server.
++
++ORB: ORBit
+diff -urN linux-2.4.1/net/korbit/modules/Console/client/console-client.c linux-2.4.1-korbit/net/korbit/modules/Console/client/console-client.c
+--- linux-2.4.1/net/korbit/modules/Console/client/console-client.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/client/console-client.c Thu Feb 1 11:47:01 2001
+@@ -0,0 +1,63 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <orb/orbit.h>
++
++#include "console.h"
++
++Console console_client;
++
++int
++main (int argc, char *argv[])
++{
++ CORBA_Environment ev;
++ CORBA_ORB orb;
++ char *Message = "Hey dood, nice hair";
++ int i;
++
++ int niters = 10;
++
++ CORBA_exception_init(&ev);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
++
++#if 0
++ for(i = 0; i < (sizeof(theblah) - 1); i++)
++ theblah[i] = 'a';
++ theblah[sizeof(theblah) - 1] = '\0';
++#endif
++
++ if(argc < 2)
++ {
++ printf("Need a binding ID thing as argv[1]\n");
++ return 1;
++ }
++
++ if(argc >= 3)
++ niters = atoi(argv[2]);
++
++ if (argc >= 4)
++ Message = argv[3];
++
++ console_client = CORBA_ORB_string_to_object(orb, argv[1], &ev);
++ if (!console_client) {
++ printf("Cannot bind to %s\n", argv[1]);
++ return 1;
++ }
++
++ printf("corba = %d, console = %d, foobar = %d\n",
++ CORBA_Object_is_a(console_client, "IDL:CORBA/Object:1.0", &ev),
++ CORBA_Object_is_a(console_client, "IDL:Empty:1.0", &ev),
++ CORBA_Object_is_a(console_client, "IDL:Foo/Bar:1.0", &ev));
++
++ for(i = 0; i < niters; i++) {
++ Console_print(console_client, Message, &ev);
++ if(ev._major != CORBA_NO_EXCEPTION) {
++ printf("we got exception %d from doNothing!\n", ev._major);
++ return 1;
++ }
++ }
++
++ CORBA_Object_release(console_client, &ev);
++ CORBA_Object_release((CORBA_Object)orb, &ev);
++
++ return 0;
++}
+diff -urN linux-2.4.1/net/korbit/modules/Console/console.idl linux-2.4.1-korbit/net/korbit/modules/Console/console.idl
+--- linux-2.4.1/net/korbit/modules/Console/console.idl Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/console.idl Thu Feb 1 11:47:00 2001
+@@ -0,0 +1,3 @@
++interface Console {
++ void print(in string TheString);
++};
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Console/server/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Entries Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,5 @@
++/Makefile/1.7/Thu Feb 1 09:47:02 2001//
++/Makefile.user/1.1/Thu Feb 1 09:47:02 2001//
++/README/1.1/Thu Feb 1 09:47:02 2001//
++/console-server.c/1.7/Thu Feb 1 09:47:02 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Console/server/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Repository Thu Feb 1 11:47:02 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Console/server
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Console/server/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/CVS/Root Thu Feb 1 11:47:02 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/Makefile linux-2.4.1-korbit/net/korbit/modules/Console/server/Makefile
+--- linux-2.4.1/net/korbit/modules/Console/server/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/Makefile Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,21 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-cons-server.o
++
++obj-y := console-server.o console-skels.o console-common.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++console-server.c: console.h console-common.c console-skels.c
++
++
++console.h console-skels.c: ../console.idl
++ $(ORBIT_IDL) ../console.idl
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/Makefile.user linux-2.4.1-korbit/net/korbit/modules/Console/server/Makefile.user
+--- linux-2.4.1/net/korbit/modules/Console/server/Makefile.user Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/Makefile.user Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = console
++
++CFLAGS = -Wall `orbit-config --cflags server` -I../../..
++LDFLAGS = `orbit-config --libs server`
++OBJS = $(PROJECT)-common.o $(PROJECT)-skels.o $(PROJECT)-server.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-server: $(OBJS)
++ gcc -o $(PROJECT)-server $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-server.c: $(PROJECT).h
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-skels.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --nostubs ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-server
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-skels.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/README linux-2.4.1-korbit/net/korbit/modules/Console/server/README
+--- linux-2.4.1/net/korbit/modules/Console/server/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/README Thu Feb 1 11:47:02 2001
+@@ -0,0 +1 @@
++Kernel module to implement Console server.
+diff -urN linux-2.4.1/net/korbit/modules/Console/server/console-server.c linux-2.4.1-korbit/net/korbit/modules/Console/server/console-server.c
+--- linux-2.4.1/net/korbit/modules/Console/server/console-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Console/server/console-server.c Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,85 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <signal.h>
++#include <orb/orbit.h>
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include "console.h"
++#include "glib.h"
++#include "korbit.h"
++
++Console console_client = CORBA_OBJECT_NIL;
++
++static void corba_console_print(PortableServer_Servant _servant,
++ CORBA_char *TheString,
++ CORBA_Environment *ev);
++
++PortableServer_ServantBase__epv base_epv = {
++ NULL,
++ NULL,
++ NULL
++};
++POA_Console__epv console_epv = { NULL, corba_console_print };
++POA_Console__vepv poa_console_vepv = { &base_epv, &console_epv };
++POA_Console poa_console_servant = { NULL, &poa_console_vepv };
++
++// MAke this global so that I can unregister the module...
++PortableServer_ObjectId objid = {0, sizeof("myFoo"), "myFoo"};
++CORBA_Environment *ev;
++PortableServer_POA poa;
++
++#ifdef __KERNEL__
++int __init corba_console_init(void)
++#else
++int main(int argc, char *argv[])
++#endif
++{
++#ifdef __KERNEL__
++ int argc = 1; char *argv[] = { "server", 0 };
++#endif
++ CORBA_ORB orb;
++
++ ev = g_new0(CORBA_Environment, 1);
++ CORBA_exception_init(ev);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++
++ poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", ev);
++ PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, ev), ev);
++
++ POA_Console__init(&poa_console_servant, ev);
++
++ PortableServer_POA_activate_object_with_id(poa,
++ &objid, &poa_console_servant, ev);
++
++ console_client =
++ PortableServer_POA_servant_to_reference(poa, &poa_console_servant, ev);
++ if (!console_client) {
++ printf("Cannot get objref\n");
++ return 1;
++ }
++
++ korbit_register_ior("console-server", console_client, orb, ev);
++
++ CORBA_ORB_run(orb, ev);
++
++ return 0;
++}
++
++#ifdef __KERNEL__
++void corba_console_exit(void) {
++ PortableServer_POA_deactivate_object(poa, &objid, ev);
++ remove_proc_entry("corba/console-server", 0);
++}
++
++module_init(corba_console_init)
++module_exit(corba_console_exit)
++#endif
++
++static void corba_console_print(PortableServer_Servant _servant,
++ CORBA_char *TheString,
++ CORBA_Environment *ev) {
++ printf("Yo. Dood. You said: '%s'!\n", TheString);
++}
++
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Entries Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,4 @@
++/CorbaFS.idl/1.7/Thu Feb 1 09:47:02 2001//
++/Makefile/1.4/Thu Feb 1 09:47:02 2001//
++/README/1.2/Thu Feb 1 09:47:02 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Entries.Log Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,3 @@
++A D/client////
++A D/server////
++A D/server-perl////
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Repository Thu Feb 1 11:47:02 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CorbaFS
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CorbaFS/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CVS/Root Thu Feb 1 11:47:02 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/CorbaFS.idl linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CorbaFS.idl
+--- linux-2.4.1/net/korbit/modules/CorbaFS/CorbaFS.idl Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/CorbaFS.idl Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,38 @@
++// -----------------------------------------------------------------------------
++// CorbaDS Module - Implement Kernel functionality in Korba
++// -----------------------------------------------------------------------------
++//
++// Main source of information:
++// http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html
++//
++module CorbaFS {
++
++ struct dirent
++ {
++ long inode; // inode number
++ string name; // file name (null-terminated)
++ };
++
++ typedef sequence<dirent> DirEntSeq;
++ typedef sequence<octet> Buffer;
++
++ interface Inode {
++ void getStatus(out unsigned short mode, out unsigned long uid, out unsigned long gid,
++ out unsigned long size, out unsigned long inodeNum, out unsigned short numLinks,
++ out long atime, out long mtime, out long ctime);
++ void readpage(out Buffer buffer, in long size, in long offset);
++ void release();
++ };
++
++ interface FileSystem {
++ Inode getInode(in string path);
++
++ // DirectoryInode getStatus implementation must have S_IFDIR in the S_IFMT
++ // field of the mode value.
++ DirEntSeq readdir(in string path);
++
++ // SymlinkInode getStatus implementation must have S_IFLNK in the S_IFMT
++ // field of the mode value.
++ string readlink(in string filename);
++ };
++};
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/Makefile linux-2.4.1-korbit/net/korbit/modules/CorbaFS/Makefile
+--- linux-2.4.1/net/korbit/modules/CorbaFS/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/Makefile Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,11 @@
++#
++# Makefile for KORBit - CorbaFS
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_CORBAFS) := client
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/README linux-2.4.1-korbit/net/korbit/modules/CorbaFS/README
+--- linux-2.4.1/net/korbit/modules/CorbaFS/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/README Thu Feb 1 11:47:02 2001
+@@ -0,0 +1,14 @@
++This interface is used to implement linux FileSystems in CORBA.
++
++Status: Working for readonly filesystems. Write capability is a todo.
++
++This lets you do all kinds of interesting things (just like the user level
++filesystem proposals would let you do):
++ server/ implements NFS like capability of just exporting an existing FS
++ TODO: webfs, ftpfs, cvsfs, mysqlfs...
++
++Usage:
++ insmod corba-corbafs.o
++ mount -t corbafs -o IOR:... none /mnt/corbafs
++
++Where the IOR comes from a filesystem server that you run somewhere...
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Entries Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,6 @@
++/CorbaFS-client.c/1.9/Thu Feb 1 09:47:03 2001//
++/CorbaFS-user-client.c/1.3/Thu Feb 1 09:47:03 2001//
++/Makefile/1.4/Thu Feb 1 09:47:03 2001//
++/Makefile.user/1.1/Thu Feb 1 09:47:03 2001//
++/README/1.1/Thu Feb 1 09:47:03 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Repository Thu Feb 1 11:47:03 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CorbaFS/client
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CVS/Root Thu Feb 1 11:47:03 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-client.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-client.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-client.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-client.c Fri Feb 2 02:20:21 2001
+@@ -0,0 +1,469 @@
++/*
++ * corbafs - Interface glue between native linux VFS layer and CORBA
++ */
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/pagemap.h>
++#include <linux/init.h>
++#include <linux/string.h>
++#include <linux/locks.h>
++#include <linux/dirent.h>
++#include <linux/module.h>
++
++#include <asm/uaccess.h>
++#include "CorbaFS.h"
++
++/* some random number */
++#define CORBAFS_MAGIC 0xC02BAF5
++
++// CORBA Stuff...
++CORBA_ORB orb;
++CORBA_Environment *ev;
++
++
++/*
++ * FILE OPERATIONS FILE OPERATIONS FILE OPERATIONS FILE OPERATIONS
++ */
++
++/* Declarations for the file_operations structure for normal files...
++ */
++static struct file_operations corbafs_file_operations = {
++ read: generic_file_read,
++};
++
++
++/* Declarations for the file_operations structure for directories...
++ */
++static int corbafs_readdir(struct file *file, void *data, filldir_t filldir);
++
++static struct file_operations corbafs_dir_operations = {
++ read: generic_read_dir,
++ readdir: corbafs_readdir,
++};
++
++
++/*
++ * INODE OPERATIONS INODE OPERATIONS INODE OPERATIONS INODE OPERATIONS
++ */
++
++/* Declarations for the inode_operations structure for symlinks...
++ */
++static int corbafs_readlink(struct dentry *dentry, char *buffer, int buflen);
++static int corbafs_followlink(struct dentry *link, struct nameidata *nd);
++
++static struct inode_operations corbafs_symlink_inode_operations = {
++ readlink: corbafs_readlink,
++ follow_link: corbafs_followlink,
++};
++
++
++/* Declarations for the inode_operations structure for directories...
++ */
++static struct dentry *corbafs_lookup(struct inode *dir, struct dentry *dentry);
++
++static struct inode_operations corbafs_dir_inode_operations = {
++ lookup: corbafs_lookup,
++};
++
++
++/*
++ * OTHER OPERATIONS OTHER OPERATIONS OTHER OPERATIONS OTHER OPERATIONS
++ */
++
++/* Declarations for the corba FS's address space ops...
++ */
++static int corbafs_readpage(struct file *file, struct page * page);
++
++static struct address_space_operations corbafs_aops = {
++ readpage: corbafs_readpage,
++};
++
++
++/* Declarations for the super_operations structure...
++ */
++static int corbafs_statfs(struct super_block *sb, struct statfs *buf);
++static void corbafs_delete_inode(struct inode *);
++
++static struct super_operations corbafs_ops = {
++ statfs: corbafs_statfs,
++ delete_inode: corbafs_delete_inode,
++};
++
++
++
++
++/* do_local_path - Modified version of d_path that is used to get the remote
++ * filename that a dentry represents...
++ */
++static char *d_local_path(struct dentry *dentry, char *buffer, int buflen) {
++ char * end = buffer+buflen;
++ char * retval;
++ int namelen;
++
++ *--end = '\0';
++ buflen--;
++
++ /* Get '/' right */
++ retval = end-1;
++ *retval = '/';
++ for (;;) {
++ if (IS_ROOT(dentry)) {
++ if (dentry->d_name.len > 1 ||
++ dentry->d_name.name[0] != '/' ||
++ retval != end) { /* Only for root directory */
++ namelen = dentry->d_name.len;
++ buflen -= namelen;
++ if (buflen >= 0) {
++ end -= namelen;
++ memcpy(end, dentry->d_name.name, namelen);
++ }
++ }
++ return end;
++ }
++ namelen = dentry->d_name.len;
++ buflen -= namelen + 1;
++ if (buflen < 0)
++ break;
++ end -= namelen;
++ memcpy(end, dentry->d_name.name, namelen);
++ *--end = '/';
++ retval = end;
++ if (dentry == dentry->d_parent) break;
++ dentry = dentry->d_parent;
++ }
++ return retval;
++}
++
++
++/* corbafs_readpage - This request should be between a file_open and a
++ * file_release, so file_fd(f) should be valid. Just read the buffer...
++ */
++static int corbafs_readpage(struct file *f, struct page * page)
++{
++ struct inode *d_inode = f->f_dentry->d_inode;
++ CorbaFS_Inode inode;
++ CorbaFS_Buffer *buffer = NULL;
++
++ int offset = page->index*PAGE_CACHE_SIZE;
++ int bytesRead;
++
++#if 0
++ printk("*** READPAGE 0x%p: 0x%lX->0x%lX to 0x%p\n",
++ f,
++ page->index,
++ page->index*PAGE_CACHE_SIZE,
++ page_address(page));
++#endif
++
++ inode = d_inode->u.generic_ip;
++ if (!inode) return -EPERM;
++
++ CorbaFS_Inode_readpage(inode, &buffer, PAGE_CACHE_SIZE, offset, ev);
++ if (!buffer) return -EPERM; /* ??? */
++
++ bytesRead = buffer->_length;
++ memcpy(page_address(page), buffer->_buffer, bytesRead);
++
++ if (bytesRead != PAGE_CACHE_SIZE) { /* EOF? */
++ /* Zero out rest of page for security. */
++ memset((void*)(page_address(page)+bytesRead), 0,
++ PAGE_CACHE_SIZE-bytesRead);
++ }
++
++ SetPageUptodate(page);
++ UnlockPage(page);
++ return 0;
++}
++
++
++
++struct inode *corbafs_get_inode(struct super_block *sb, const char *path)
++{
++ struct inode * inode = get_empty_inode();
++ CorbaFS_FileSystem fs_client;
++ CorbaFS_Inode newInode;
++
++ if (!inode) return 0;
++
++ inode->i_sb = sb;
++ inode->i_dev = sb->s_dev;
++
++ fs_client = sb->u.generic_sbp;
++//printk("\n \n \nCorbaFS_FileSystem_getInode(0x%X, %s)\n", fs_client, path);
++ newInode = CorbaFS_FileSystem_getInode(fs_client, path, ev);
++//printk("NewInode = 0x%X\n \n \n \n", newInode);
++ if (!newInode) {
++ iput(inode);
++ return NULL;
++ }
++
++//printk("CorbaFS_Inode_getStatus\n");
++ CorbaFS_Inode_getStatus(newInode,
++ &inode->i_mode, &inode->i_uid, &inode->i_gid,
++ (CORBA_unsigned_long *)&inode->i_size,
++ (CORBA_unsigned_long *)&inode->i_ino,
++ &inode->i_nlink,
++ (CORBA_long *)&inode->i_atime,
++ (CORBA_long *)&inode->i_mtime,
++ (CORBA_long *)&inode->i_ctime,
++ ev);
++//printk("Back from CorbaFS_Inode_getStatus\n \n \n \n");
++
++ inode->u.generic_ip = (void*)newInode;
++
++ /* TODO: Map things back correctly??? */
++ inode->i_uid = 0 /*current->fsuid */;
++ inode->i_gid = 0 /*current->fsgid */;
++
++ inode->i_blksize = PAGE_CACHE_SIZE;
++ inode->i_blocks = 0;
++ inode->i_rdev = 0;
++ inode->i_op = NULL;
++ inode->i_fop = NULL;
++ inode->i_mapping->a_ops = &corbafs_aops;
++ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
++
++ switch (inode->i_mode & S_IFMT) {
++ default:
++ /* Do I really want to expose device inodes? */
++ init_special_inode(inode, inode->i_mode, sb->s_dev);
++ break;
++ case S_IFREG:
++ inode->i_fop = &corbafs_file_operations;
++ break;
++ case S_IFDIR:
++ inode->i_op = &corbafs_dir_inode_operations;
++ inode->i_fop = &corbafs_dir_operations;
++ break;
++ case S_IFLNK:
++ inode->i_op = &corbafs_symlink_inode_operations;
++ break;
++ }
++ insert_inode_hash(inode);
++
++ return inode;
++}
++
++static int corbafs_readdir(struct file *file, void *data, filldir_t filldir)
++{
++ struct inode *inode = file->f_dentry->d_inode;
++ struct super_block *sb = file->f_dentry->d_sb;
++ unsigned offset = file->f_pos;
++ char *path, *page = (char *)__get_free_page(GFP_KERNEL);
++ int i;
++ unsigned char d_type = DT_UNKNOWN;
++ CorbaFS_FileSystem fs_client;
++ CorbaFS_DirEntSeq *dirEntSeq;
++ CorbaFS_dirent *dirEnts;
++
++ if (offset >= inode->i_size) return 0;
++
++ path = d_local_path(file->f_dentry, page, PAGE_SIZE);
++
++ fs_client = sb->u.generic_sbp;
++ if (!fs_client)
++ return -EPERM; /* ??? */
++
++// printk("\n \n \nCorbaFS_FileSystem_readdir(%s)\n", path);
++
++ dirEntSeq = CorbaFS_FileSystem_readdir(fs_client, path, ev);
++
++// printk("CorbaFS_FileSystem_readdir = %d\n \n \n \n", dirEntSeq->_length);
++
++ if (dirEntSeq->_length == 0) goto full;
++
++ dirEnts = dirEntSeq->_buffer;
++ i = 0;
++ if (offset) { // We have read PART of the directory
++ int idxadj = offset; // Start reading now from where we left
++ while (idxadj > 0) { // off...
++ idxadj -= sizeof(struct dirent)+
++ strlen(dirEnts[i].name);
++ i++;
++ }
++
++ if (idxadj < 0) { // We should end up with exactly 0.
++ printf("Alert! Readdir can't resume in the middle "
++ "of a directory! stopage.\n");
++ goto full;
++ }
++ }
++
++ for (; i < dirEntSeq->_length; i++) {
++ int myinode = dirEnts[i].inode;
++ char *myname = dirEnts[i].name;
++ int namelen = strlen(myname);
++
++ if (filldir(data, myname, namelen, offset, myinode, d_type))
++ goto full;
++ offset += sizeof(struct dirent)+namelen;
++ }
++
++ full:
++ file->f_pos = offset;
++ return 0;
++}
++
++static int corbafs_statfs(struct super_block *sb, struct statfs *buf) {
++ buf->f_type = CORBAFS_MAGIC;
++ buf->f_bsize = PAGE_CACHE_SIZE;
++ buf->f_namelen = 255;
++ return 0;
++}
++
++/*
++ * Lookup the data. Most of the grunt work is done by corbafs_get_inode.
++ */
++static struct dentry *corbafs_lookup(struct inode *dir, struct dentry *dentry)
++{
++ struct inode *New;
++ char *Path, *Page = (char *)__get_free_page(GFP_KERNEL);
++ if (Page == 0) goto out; /* nomem? */
++
++ Path = d_local_path(dentry, Page, PAGE_SIZE);
++
++ New = corbafs_get_inode(dir->i_sb, Path);
++ free_page((unsigned long)Page);
++
++ if (New) {
++ d_add(dentry, New);
++ return 0;
++ }
++
++out:
++ d_add(dentry, NULL);
++ return 0;
++}
++
++
++static char *corbafs_read_a_link(struct dentry *dentry) {
++ char *path, *page, *s = 0;
++ struct super_block *sb = dentry->d_sb;
++ CorbaFS_FileSystem fs_client;
++
++ page = (char *)__get_free_page(GFP_KERNEL);
++ if (page == 0) goto out; /* nomem? */
++
++ path = d_local_path(dentry, page, PAGE_SIZE);
++
++ fs_client = sb->u.generic_sbp;
++// printk("\n \n \nCorbaFS_FileSystem_readlink(%s)\n", path);
++ s = CorbaFS_FileSystem_readlink(fs_client, path, ev);
++// printk("CorbaFS_FileSystem_readlink = %s\n \n \n \n", s);
++
++ if (ev->_major != CORBA_NO_EXCEPTION) {
++ if (s) {
++ // CORBA_string_free(s,..);
++ s = 0;
++ }
++ goto outfree;
++ }
++ outfree:
++ free_page((unsigned long)page);
++ out:
++ return s;
++}
++
++
++static int corbafs_readlink(struct dentry *dentry, char *buffer, int buflen) {
++ char *str = corbafs_read_a_link(dentry);
++ int error = -EINVAL;
++
++ if (str) {
++ error = vfs_readlink(dentry, buffer, buflen, str);
++ // TODO: CORBA_string__free the string str.
++ }
++ return error;
++}
++
++/* Fill in nd->dentry
++ */
++static int corbafs_followlink(struct dentry *link, struct nameidata *nd) {
++ int Error = -ENOMEM;
++ char *Path = corbafs_read_a_link(link);
++ if (!Path) goto out;
++
++#if 1
++ printk("Followlink: %s\n", Path);
++#endif
++ Error = vfs_follow_link(nd, Path);
++ // TODO: CORBA_string__free the string str.
++
++ out:
++ return Error;
++}
++
++static void corbafs_delete_inode(struct inode *inode) {
++ CorbaFS_Inode Inode = inode->u.generic_ip;
++// printk("\n \n \nCorbaFS_Inode_Release\n");
++ CorbaFS_Inode_release(Inode, ev);
++// printk("CorbaFS_Inode_Release done\n \n \n \n");
++}
++
++static void corbafs_put_super(struct super_block *sb) {
++// MOD_DEC_USE_COUNT;
++}
++
++static struct super_block *corbafs_read_super(struct super_block * sb, void * data, int silent) {
++ struct dentry *root = 0;
++ struct inode *root_inode = 0;
++
++ CorbaFS_FileSystem fs_client;
++
++ sb->s_blocksize = PAGE_CACHE_SIZE;
++ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
++ sb->s_magic = CORBAFS_MAGIC;
++ sb->s_op = &corbafs_ops;
++
++//printk("corbafs_read_super: '%s'\n", (char*)data);
++
++ // Note that the CORBA IOR is now in *data
++ fs_client = CORBA_ORB_string_to_object(orb, data, ev);
++
++//printk("fs_client: 0x%X\n", fs_client);
++ if (!fs_client)
++ return NULL;
++
++ sb->u.generic_sbp = fs_client;
++
++ root_inode = corbafs_get_inode(sb, "/");
++//printk("root_inode = 0x%X\n", root_inode);
++ root = d_alloc_root(root_inode);
++ if (!root) {
++ iput(root_inode);
++ return NULL;
++ }
++ sb->s_root = root;
++
++// MOD_INC_USE_COUNT;
++ return sb;
++}
++
++static DECLARE_FSTYPE(corbafs_fs_type, "corbafs", corbafs_read_super, 0);
++
++static int __init init_corbafs_fs(void) {
++ int argc = 1;
++ char *argv[] = { "client", 0 };
++ ev = g_new0(CORBA_Environment,1);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++
++ return register_filesystem(&corbafs_fs_type);
++}
++
++static void __exit exit_corbafs_fs(void)
++{
++ // remove object from orb.
++ printf("\n \n \nCorbaFS_exit()\n");
++ unregister_filesystem(&corbafs_fs_type);
++ CORBA_Object_release((CORBA_Object)orb, ev);
++}
++
++module_init(init_corbafs_fs)
++module_exit(exit_corbafs_fs)
++
++/*
++ * Local variables:
++ * c-file-style: "linux"
++ * End:
++ */
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-common.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-common.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-common.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-common.c Thu Feb 1 16:36:08 2001
+@@ -0,0 +1,370 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "CorbaFS.h"
++
++#if ( (TC_IMPL_TC_CorbaFS_dirent_0 == 'C') \
++&& (TC_IMPL_TC_CorbaFS_dirent_1 == 'o') \
++&& (TC_IMPL_TC_CorbaFS_dirent_2 == 'r') \
++&& (TC_IMPL_TC_CorbaFS_dirent_3 == 'b') \
++&& (TC_IMPL_TC_CorbaFS_dirent_4 == 'a') \
++&& (TC_IMPL_TC_CorbaFS_dirent_5 == 'F') \
++&& (TC_IMPL_TC_CorbaFS_dirent_6 == 'S') \
++) && !defined(TC_DEF_TC_CorbaFS_dirent)
++#define TC_DEF_TC_CorbaFS_dirent 1
++static const char *anon_subnames_array1[] = { "inode", "name" };
++static const CORBA_TypeCode anon_subtypes_array2[] =
++ { (CORBA_TypeCode) & TC_CORBA_long_struct,
++ (CORBA_TypeCode) & TC_CORBA_string_struct };
++const struct CORBA_TypeCode_struct TC_CorbaFS_dirent_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_struct, "dirent", "IDL:CorbaFS/dirent:1.0",
++ 0, 2,
++ (const char **) anon_subnames_array1,
++ (CORBA_TypeCode *) anon_subtypes_array2,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_0 == 'C') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_1 == 'o') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_2 == 'r') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_3 == 'b') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_4 == 'a') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_5 == 'F') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_6 == 'S') \
++) && !defined(TC_DEF_TC_CORBA_sequence_CorbaFS_dirent)
++#define TC_DEF_TC_CORBA_sequence_CorbaFS_dirent 1
++static const CORBA_TypeCode anon_subtypes_array6[] =
++ { (CORBA_TypeCode) & TC_CorbaFS_dirent_struct };
++const struct CORBA_TypeCode_struct TC_CORBA_sequence_CorbaFS_dirent_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_sequence, NULL, NULL,
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array6,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_0 == 'C') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_1 == 'o') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_2 == 'r') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_3 == 'b') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_4 == 'a') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_5 == 'F') \
++&& (TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_6 == 'S') \
++) && !defined(TC_DEF_TC_CORBA_sequence_CorbaFS_dirent)
++#define TC_DEF_TC_CORBA_sequence_CorbaFS_dirent 1
++static const CORBA_TypeCode anon_subtypes_array15[] =
++ { (CORBA_TypeCode) & TC_CorbaFS_dirent_struct };
++const struct CORBA_TypeCode_struct TC_CORBA_sequence_CorbaFS_dirent_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_sequence, NULL, NULL,
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array15,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CorbaFS_DirEntSeq_0 == 'C') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_1 == 'o') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_2 == 'r') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_3 == 'b') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_4 == 'a') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_5 == 'F') \
++&& (TC_IMPL_TC_CorbaFS_DirEntSeq_6 == 'S') \
++) && !defined(TC_DEF_TC_CorbaFS_DirEntSeq)
++#define TC_DEF_TC_CorbaFS_DirEntSeq 1
++static const CORBA_TypeCode anon_subtypes_array19[] =
++ { (CORBA_TypeCode) & TC_CORBA_sequence_CorbaFS_dirent_struct };
++const struct CORBA_TypeCode_struct TC_CorbaFS_DirEntSeq_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_alias, "DirEntSeq", "IDL:CorbaFS/DirEntSeq:1.0",
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array19,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CORBA_sequence_CORBA_octet_0 == 'C') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_1 == 'o') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_2 == 'r') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_3 == 'b') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_4 == 'a') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_5 == 'F') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_6 == 'S') \
++) && !defined(TC_DEF_TC_CORBA_sequence_CORBA_octet)
++#define TC_DEF_TC_CORBA_sequence_CORBA_octet 1
++static const CORBA_TypeCode anon_subtypes_array23[] =
++ { (CORBA_TypeCode) & TC_CORBA_octet_struct };
++const struct CORBA_TypeCode_struct TC_CORBA_sequence_CORBA_octet_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_sequence, NULL, NULL,
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array23,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CORBA_sequence_CORBA_octet_0 == 'C') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_1 == 'o') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_2 == 'r') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_3 == 'b') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_4 == 'a') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_5 == 'F') \
++&& (TC_IMPL_TC_CORBA_sequence_CORBA_octet_6 == 'S') \
++) && !defined(TC_DEF_TC_CORBA_sequence_CORBA_octet)
++#define TC_DEF_TC_CORBA_sequence_CORBA_octet 1
++static const CORBA_TypeCode anon_subtypes_array32[] =
++ { (CORBA_TypeCode) & TC_CORBA_octet_struct };
++const struct CORBA_TypeCode_struct TC_CORBA_sequence_CORBA_octet_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_sequence, NULL, NULL,
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array32,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CorbaFS_Buffer_0 == 'C') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_1 == 'o') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_2 == 'r') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_3 == 'b') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_4 == 'a') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_5 == 'F') \
++&& (TC_IMPL_TC_CorbaFS_Buffer_6 == 'S') \
++) && !defined(TC_DEF_TC_CorbaFS_Buffer)
++#define TC_DEF_TC_CorbaFS_Buffer 1
++static const CORBA_TypeCode anon_subtypes_array36[] =
++ { (CORBA_TypeCode) & TC_CORBA_sequence_CORBA_octet_struct };
++const struct CORBA_TypeCode_struct TC_CorbaFS_Buffer_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_alias, "Buffer", "IDL:CorbaFS/Buffer:1.0",
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array36,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CorbaFS_Inode_0 == 'C') \
++&& (TC_IMPL_TC_CorbaFS_Inode_1 == 'o') \
++&& (TC_IMPL_TC_CorbaFS_Inode_2 == 'r') \
++&& (TC_IMPL_TC_CorbaFS_Inode_3 == 'b') \
++&& (TC_IMPL_TC_CorbaFS_Inode_4 == 'a') \
++&& (TC_IMPL_TC_CorbaFS_Inode_5 == 'F') \
++&& (TC_IMPL_TC_CorbaFS_Inode_6 == 'S') \
++) && !defined(TC_DEF_TC_CorbaFS_Inode)
++#define TC_DEF_TC_CorbaFS_Inode 1
++const struct CORBA_TypeCode_struct TC_CorbaFS_Inode_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_objref, "Inode", "IDL:CorbaFS/Inode:1.0",
++ 0, 0,
++ NULL,
++ NULL,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++#if ( (TC_IMPL_TC_CorbaFS_FileSystem_0 == 'C') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_1 == 'o') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_2 == 'r') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_3 == 'b') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_4 == 'a') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_5 == 'F') \
++&& (TC_IMPL_TC_CorbaFS_FileSystem_6 == 'S') \
++) && !defined(TC_DEF_TC_CorbaFS_FileSystem)
++#define TC_DEF_TC_CorbaFS_FileSystem 1
++const struct CORBA_TypeCode_struct TC_CorbaFS_FileSystem_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_objref, "FileSystem", "IDL:CorbaFS/FileSystem:1.0",
++ 0, 0,
++ NULL,
++ NULL,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++gpointer
++CorbaFS_dirent__free(gpointer mem, gpointer dat, CORBA_boolean free_strings)
++{
++ CorbaFS_dirent *var = mem;
++
++ if (free_strings) {
++ CORBA_string__free(&(var->name), NULL, free_strings);
++ }
++ return (gpointer) (var + 1);
++}
++
++CorbaFS_dirent *
++CorbaFS_dirent__alloc(void)
++{
++ CorbaFS_dirent *retval;
++
++ retval =
++ ORBit_alloc(sizeof(CorbaFS_dirent),
++ (ORBit_free_childvals) CorbaFS_dirent__free,
++ GUINT_TO_POINTER(1));
++ memset(&(retval->name), '\0', sizeof(retval->name));
++ return retval;
++}
++
++#if ( (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_0 == 'C') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_1 == 'o') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_2 == 'r') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_3 == 'b') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_4 == 'a') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_5 == 'F') \
++&& (ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_6 == 'S') \
++) && !defined(ORBIT_DEF_CORBA_sequence_CorbaFS_dirent)
++#define ORBIT_DEF_CORBA_sequence_CorbaFS_dirent 1
++
++gpointer
++CORBA_sequence_CorbaFS_dirent__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings)
++{
++ CORBA_sequence_CorbaFS_dirent *val = mem;
++
++ if (val->_release)
++ ORBit_free(val->_buffer, free_strings);
++ return (gpointer) (val + 1);
++}
++
++CORBA_sequence_CorbaFS_dirent *
++CORBA_sequence_CorbaFS_dirent__alloc(void)
++{
++ CORBA_sequence_CorbaFS_dirent *retval;
++
++ retval =
++ ORBit_alloc(sizeof(CORBA_sequence_CorbaFS_dirent),
++ (ORBit_free_childvals) CORBA_sequence_CorbaFS_dirent__free,
++ GUINT_TO_POINTER(1));
++ retval->_maximum = 0;
++ retval->_length = 0;
++ retval->_buffer = NULL;
++ retval->_release = CORBA_FALSE;
++ return retval;
++}
++
++CorbaFS_dirent *
++CORBA_sequence_CorbaFS_dirent_allocbuf(CORBA_unsigned_long len)
++{
++ CorbaFS_dirent *retval =
++ ORBit_alloc(sizeof(CorbaFS_dirent) * len,
++ (ORBit_free_childvals) CorbaFS_dirent__free,
++ GUINT_TO_POINTER(len));
++
++ memset(retval, '\0', sizeof(CorbaFS_dirent) * len);
++ return retval;
++}
++#endif
++
++gpointer
++CorbaFS_DirEntSeq__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings)
++{
++ return CORBA_sequence_CorbaFS_dirent__free(mem, dat, free_strings);
++}
++
++CorbaFS_DirEntSeq *
++CorbaFS_DirEntSeq__alloc(void)
++{
++ return CORBA_sequence_CorbaFS_dirent__alloc();
++}
++
++#if ( (ORBIT_IMPL_CORBA_sequence_CORBA_octet_0 == 'C') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_1 == 'o') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_2 == 'r') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_3 == 'b') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_4 == 'a') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_5 == 'F') \
++&& (ORBIT_IMPL_CORBA_sequence_CORBA_octet_6 == 'S') \
++) && !defined(ORBIT_DEF_CORBA_sequence_CORBA_octet)
++#define ORBIT_DEF_CORBA_sequence_CORBA_octet 1
++
++gpointer
++CORBA_sequence_CORBA_octet__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings)
++{
++ CORBA_sequence_CORBA_octet *val = mem;
++
++ if (val->_release)
++ ORBit_free(val->_buffer, free_strings);
++ return (gpointer) (val + 1);
++}
++
++CORBA_sequence_CORBA_octet *
++CORBA_sequence_CORBA_octet__alloc(void)
++{
++ CORBA_sequence_CORBA_octet *retval;
++
++ retval =
++ ORBit_alloc(sizeof(CORBA_sequence_CORBA_octet),
++ (ORBit_free_childvals) CORBA_sequence_CORBA_octet__free,
++ GUINT_TO_POINTER(1));
++ retval->_maximum = 0;
++ retval->_length = 0;
++ retval->_buffer = NULL;
++ retval->_release = CORBA_FALSE;
++ return retval;
++}
++
++CORBA_octet *
++CORBA_sequence_CORBA_octet_allocbuf(CORBA_unsigned_long len)
++{
++ CORBA_octet *retval =
++ ORBit_alloc(sizeof(CORBA_octet) * len, (ORBit_free_childvals) NULL,
++ GUINT_TO_POINTER(len));
++
++ return retval;
++}
++#endif
++
++gpointer
++CorbaFS_Buffer__free(gpointer mem, gpointer dat, CORBA_boolean free_strings)
++{
++ return CORBA_sequence_CORBA_octet__free(mem, dat, free_strings);
++}
++
++CorbaFS_Buffer *
++CorbaFS_Buffer__alloc(void)
++{
++ return CORBA_sequence_CORBA_octet__alloc();
++}
++
++CORBA_unsigned_long CorbaFS_Inode__classid = 0;
++CORBA_unsigned_long CorbaFS_FileSystem__classid = 0;
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-stubs.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-stubs.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-stubs.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-stubs.c Thu Feb 1 16:36:08 2001
+@@ -0,0 +1,791 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "CorbaFS.h"
++
++void
++CorbaFS_Inode_getStatus(CorbaFS_Inode _obj, CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid, CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks, CORBA_long * atime,
++ CORBA_long * mtime, CORBA_long * ctime,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_Inode__classid) {
++
++ ((POA_CorbaFS_Inode__epv *) _obj->vepv[CorbaFS_Inode__classid])->
++ getStatus(_obj->servant, mode, uid, gid, size, inodeNum, numLinks,
++ atime, mtime, ctime, ev);
++ return;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[10];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 10, "getStatus"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 14 };
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 2);
++
++ (*((guint16 *) & ((*mode)))) =
++ GUINT16_SWAP_LE_BE(*((guint16 *) _ORBIT_curptr));
++ _ORBIT_curptr += 2;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & ((*uid)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint32 *) & ((*gid)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint32 *) & ((*size)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint32 *) & ((*inodeNum)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint16 *) & ((*numLinks)))) =
++ GUINT16_SWAP_LE_BE(*((guint16 *) _ORBIT_curptr));
++ _ORBIT_curptr += 2;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & ((*atime)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint32 *) & ((*mtime)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ (*((guint32 *) & ((*ctime)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));} else {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 2);
++ (*mode) = *((CORBA_unsigned_short *) _ORBIT_curptr);
++ _ORBIT_curptr += 2;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*uid) = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*gid) = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*size) = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*inodeNum) = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*numLinks) = *((CORBA_unsigned_short *) _ORBIT_curptr);
++ _ORBIT_curptr += 2;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*atime) = *((CORBA_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*mtime) = *((CORBA_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ (*ctime) = *((CORBA_long *) _ORBIT_curptr);
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ }
++ }
++}
++void
++CorbaFS_Inode_readpage(CorbaFS_Inode _obj, CorbaFS_Buffer ** buffer,
++ const CORBA_long size, const CORBA_long offset,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ register CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_Inode__classid) {
++
++ ((POA_CorbaFS_Inode__epv *) _obj->vepv[CorbaFS_Inode__classid])->
++ readpage(_obj->servant, buffer, size, offset, ev);
++ return;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[9];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 9, "readpage"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 13 };
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ &(size), sizeof(size));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ &(offset), sizeof(offset));
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ *buffer = CorbaFS_Buffer__alloc();
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & (((**buffer))._length))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++
++ ((**buffer))._buffer =
++ CORBA_sequence_CORBA_octet_allocbuf(((**buffer))._length);
++ ((**buffer))._release = CORBA_TRUE;
++ memcpy(((**buffer))._buffer, _ORBIT_curptr,
++ sizeof(((**buffer))._buffer[_ORBIT_tmpvar_1]) *
++ ((**buffer))._length);
++ _ORBIT_curptr +=
++ sizeof(((**buffer))._buffer[_ORBIT_tmpvar_1]) *
++ ((**buffer))._length;
++ } else {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ ((**buffer))._length = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++
++ ((**buffer))._buffer =
++ CORBA_sequence_CORBA_octet_allocbuf(((**buffer))._length);
++ ((**buffer))._release = CORBA_TRUE;
++ memcpy(((**buffer))._buffer, _ORBIT_curptr,
++ sizeof(((**buffer))._buffer[_ORBIT_tmpvar_1]) *
++ ((**buffer))._length);
++ _ORBIT_curptr +=
++ sizeof(((**buffer))._buffer[_ORBIT_tmpvar_1]) *
++ ((**buffer))._length;
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ }
++ }
++}
++void
++CorbaFS_Inode_release(CorbaFS_Inode _obj, CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_Inode__classid) {
++
++ ((POA_CorbaFS_Inode__epv *) _obj->vepv[CorbaFS_Inode__classid])->
++ release(_obj->servant, ev);
++ return;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[8];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 8, "release"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 12 };
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ } else {
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return;
++ }
++ }
++}
++CorbaFS_Inode
++CorbaFS_FileSystem_getInode(CorbaFS_FileSystem _obj, const CORBA_char * path,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ CorbaFS_Inode _ORBIT_retval;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_FileSystem__classid) {
++ _ORBIT_retval =
++ ((POA_CorbaFS_FileSystem__epv *) _obj->
++ vepv[CorbaFS_FileSystem__classid])->getInode(_obj->servant, path,
++ ev);
++ return _ORBIT_retval;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[9];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 9, "getInode"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 13 };
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(path) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ {
++ guchar *_ORBIT_t;
++
++ _ORBIT_t = alloca(sizeof(_ORBIT_tmpvar_1));
++ memcpy(_ORBIT_t, &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), (_ORBIT_t),
++ sizeof(_ORBIT_tmpvar_1));
++ }
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ (path),
++ sizeof(path[_ORBIT_tmpvar_0]) *
++ _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ } else {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++}
++CorbaFS_DirEntSeq *
++CorbaFS_FileSystem_readdir(CorbaFS_FileSystem _obj, const CORBA_char * path,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ CorbaFS_DirEntSeq *_ORBIT_retval;
++ register CORBA_unsigned_long _ORBIT_tmpvar_5;
++ register CORBA_unsigned_long _ORBIT_tmpvar_6;
++ CORBA_unsigned_long _ORBIT_tmpvar_7;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_FileSystem__classid) {
++ _ORBIT_retval =
++ ((POA_CorbaFS_FileSystem__epv *) _obj->
++ vepv[CorbaFS_FileSystem__classid])->readdir(_obj->servant, path,
++ ev);
++ return _ORBIT_retval;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[8];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 8, "readdir"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 12 };
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(path) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ {
++ guchar *_ORBIT_t;
++
++ _ORBIT_t = alloca(sizeof(_ORBIT_tmpvar_1));
++ memcpy(_ORBIT_t, &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), (_ORBIT_t),
++ sizeof(_ORBIT_tmpvar_1));
++ }
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ (path),
++ sizeof(path[_ORBIT_tmpvar_0]) *
++ _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_retval = CorbaFS_DirEntSeq__alloc();
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & ((*_ORBIT_retval)._length))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++
++ (*_ORBIT_retval)._buffer =
++ CORBA_sequence_CorbaFS_dirent_allocbuf((*_ORBIT_retval)._length);
++ (*_ORBIT_retval)._release = CORBA_TRUE;
++ for (_ORBIT_tmpvar_5 = 0; _ORBIT_tmpvar_5 < (*_ORBIT_retval)._length;
++ _ORBIT_tmpvar_5++) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*
++ ((guint32 *) &
++ ((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].inode))) =
++GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++
++ (*((guint32 *) & (_ORBIT_tmpvar_7))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++
++ (*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].name =
++ CORBA_string_alloc(_ORBIT_tmpvar_7);
++ memcpy((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].name,
++ _ORBIT_curptr,
++ sizeof((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].
++ name[_ORBIT_tmpvar_6]) * _ORBIT_tmpvar_7);
++ _ORBIT_curptr +=
++ sizeof((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].
++ name[_ORBIT_tmpvar_6]) * _ORBIT_tmpvar_7;
++ }
++
++ } else {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*_ORBIT_retval)._length = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++
++ (*_ORBIT_retval)._buffer =
++ CORBA_sequence_CorbaFS_dirent_allocbuf((*_ORBIT_retval)._length);
++ (*_ORBIT_retval)._release = CORBA_TRUE;
++ for (_ORBIT_tmpvar_5 = 0; _ORBIT_tmpvar_5 < (*_ORBIT_retval)._length;
++ _ORBIT_tmpvar_5++) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].inode = *((CORBA_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ _ORBIT_tmpvar_7 = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++
++ (*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].name =
++ CORBA_string_alloc(_ORBIT_tmpvar_7);
++ memcpy((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].name,
++ _ORBIT_curptr,
++ sizeof((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].
++ name[_ORBIT_tmpvar_6]) * _ORBIT_tmpvar_7);
++ _ORBIT_curptr +=
++ sizeof((*_ORBIT_retval)._buffer[_ORBIT_tmpvar_5].
++ name[_ORBIT_tmpvar_6]) * _ORBIT_tmpvar_7;
++ }
++
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++}
++CORBA_char *
++CorbaFS_FileSystem_readlink(CorbaFS_FileSystem _obj,
++ const CORBA_char * filename,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ CORBA_char *_ORBIT_retval;
++ register CORBA_unsigned_long _ORBIT_tmpvar_4;
++ CORBA_unsigned_long _ORBIT_tmpvar_5;
++
++ if (_obj->servant && _obj->vepv && CorbaFS_FileSystem__classid) {
++ _ORBIT_retval =
++ ((POA_CorbaFS_FileSystem__epv *) _obj->
++ vepv[CorbaFS_FileSystem__classid])->readlink(_obj->servant,
++ filename, ev);
++ return _ORBIT_retval;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[9];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 9, "readlink"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 13 };
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(filename) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ {
++ guchar *_ORBIT_t;
++
++ _ORBIT_t = alloca(sizeof(_ORBIT_tmpvar_1));
++ memcpy(_ORBIT_t, &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), (_ORBIT_t),
++ sizeof(_ORBIT_tmpvar_1));
++ }
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ (filename),
++ sizeof(filename[_ORBIT_tmpvar_0]) *
++ _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & (_ORBIT_tmpvar_5))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ _ORBIT_retval = CORBA_string_alloc(_ORBIT_tmpvar_5);
++ memcpy(_ORBIT_retval, _ORBIT_curptr,
++ sizeof(_ORBIT_retval[_ORBIT_tmpvar_4]) * _ORBIT_tmpvar_5);
++ _ORBIT_curptr +=
++ sizeof(_ORBIT_retval[_ORBIT_tmpvar_4]) * _ORBIT_tmpvar_5;
++ } else {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ _ORBIT_tmpvar_5 = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ _ORBIT_retval = CORBA_string_alloc(_ORBIT_tmpvar_5);
++ memcpy(_ORBIT_retval, _ORBIT_curptr,
++ sizeof(_ORBIT_retval[_ORBIT_tmpvar_4]) * _ORBIT_tmpvar_5);
++ _ORBIT_curptr +=
++ sizeof(_ORBIT_retval[_ORBIT_tmpvar_4]) * _ORBIT_tmpvar_5;
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++}
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-user-client.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-user-client.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS-user-client.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS-user-client.c Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,92 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <orb/orbit.h>
++
++#include "CorbaFS.h"
++
++CorbaFS_FileSystem fs;
++
++int
++main (int argc, char *argv[])
++{
++ CORBA_Environment ev;
++ CORBA_ORB orb;
++ CorbaFS_Inode inode;
++ CorbaFS_Buffer *buffer;
++ CorbaFS_DirEntSeq *dirents;
++ CorbaFS_dirent *dirent;
++
++ CORBA_unsigned_short mode;
++ CORBA_unsigned_long uid;
++ CORBA_unsigned_long gid;
++ CORBA_unsigned_long size;
++ CORBA_unsigned_long inodeNum;
++ CORBA_unsigned_short numLinks;
++ CORBA_long atime;
++ CORBA_long mtime;
++ CORBA_long ctime;
++
++ int i;
++
++ int niters = 10;
++
++ CORBA_exception_init(&ev);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
++
++ if(argc < 2)
++ {
++ printf("Need a binding ID thing as argv[1]\n");
++ return 1;
++ }
++
++
++ fs = CORBA_ORB_string_to_object(orb, argv[1], &ev);
++ if (!fs) {
++ printf("Cannot bind to %s\n", argv[1]);
++ return 1;
++ }
++
++ if (argc >= 3)
++ inode = CorbaFS_FileSystem_getInode(fs, argv[2], &ev);
++ else
++ inode = CorbaFS_FileSystem_getInode(fs, "/proc/cpuinfo", &ev);
++
++ if (!inode)
++ {
++ printf("Cannot get inode\n");
++ }
++
++ CorbaFS_Inode_getStatus(inode,
++ &mode,
++ &uid,
++ &gid,
++ &size,
++ &inodeNum,
++ &numLinks,
++ &atime,
++ &mtime,
++ &ctime,
++ &ev);
++
++ printf("inode = %x\n", inode);
++ CorbaFS_Inode_readpage(inode, &buffer, 1000, 100, &ev);
++ printf("readpage got %d bytes\n", buffer->_length);
++ printf("readpage returned : %s\n", buffer->_buffer);
++
++ if (argc >= 3)
++ dirents = CorbaFS_FileSystem_readdir(fs, argv[2], &ev);
++ else
++ dirents = CorbaFS_FileSystem_readdir(fs, "/", &ev);
++
++ dirent = dirents->_buffer;
++ for (i = 0; i < dirents->_length; i++)
++ {
++ printf("%d = %s\n", dirent->inode, dirent->name);
++ dirent++;
++ }
++
++ CORBA_Object_release(fs, &ev);
++ CORBA_Object_release((CORBA_Object)orb, &ev);
++
++ return 0;
++}
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS.h linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS.h
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/CorbaFS.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/CorbaFS.h Thu Feb 1 16:36:08 2001
+@@ -0,0 +1,349 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <glib.h>
++#define ORBIT_IDL_SERIAL 9
++#include <orb/orbit.h>
++
++#ifndef CorbaFS_H
++#define CorbaFS_H 1
++#ifdef __cplusplus
++extern "C"
++{
++#endif /* __cplusplus */
++
++/** typedefs **/
++#if !defined(_CorbaFS_dirent_defined)
++#define _CorbaFS_dirent_defined 1
++ typedef struct
++ {
++ CORBA_long inode;
++ CORBA_char *name;
++ }
++ CorbaFS_dirent;
++
++#if !defined(TC_IMPL_TC_CorbaFS_dirent_0)
++#define TC_IMPL_TC_CorbaFS_dirent_0 'C'
++#define TC_IMPL_TC_CorbaFS_dirent_1 'o'
++#define TC_IMPL_TC_CorbaFS_dirent_2 'r'
++#define TC_IMPL_TC_CorbaFS_dirent_3 'b'
++#define TC_IMPL_TC_CorbaFS_dirent_4 'a'
++#define TC_IMPL_TC_CorbaFS_dirent_5 'F'
++#define TC_IMPL_TC_CorbaFS_dirent_6 'S'
++ extern const struct CORBA_TypeCode_struct TC_CorbaFS_dirent_struct;
++#define TC_CorbaFS_dirent ((CORBA_TypeCode)&TC_CorbaFS_dirent_struct)
++#endif
++ extern CorbaFS_dirent *CorbaFS_dirent__alloc(void);
++ extern gpointer CorbaFS_dirent__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings); /* ORBit internal use */
++#endif
++#if !defined(ORBIT_DECL_CORBA_sequence_CorbaFS_dirent) && !defined(_CORBA_sequence_CorbaFS_dirent_defined)
++#define ORBIT_DECL_CORBA_sequence_CorbaFS_dirent 1
++#define _CORBA_sequence_CorbaFS_dirent_defined 1
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_0 'C'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_1 'o'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_2 'r'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_3 'b'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_4 'a'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_5 'F'
++#define ORBIT_IMPL_CORBA_sequence_CorbaFS_dirent_6 'S'
++ typedef struct
++ {
++ CORBA_unsigned_long _maximum,
++ _length;
++ CorbaFS_dirent *_buffer;
++ CORBA_boolean _release;
++ }
++ CORBA_sequence_CorbaFS_dirent;
++#if !defined(TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_0)
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_0 'C'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_1 'o'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_2 'r'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_3 'b'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_4 'a'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_5 'F'
++#define TC_IMPL_TC_CORBA_sequence_CorbaFS_dirent_6 'S'
++ extern const struct CORBA_TypeCode_struct
++ TC_CORBA_sequence_CorbaFS_dirent_struct;
++#define TC_CORBA_sequence_CorbaFS_dirent ((CORBA_TypeCode)&TC_CORBA_sequence_CorbaFS_dirent_struct)
++#endif
++ extern CORBA_sequence_CorbaFS_dirent
++ *CORBA_sequence_CorbaFS_dirent__alloc(void);
++ extern gpointer CORBA_sequence_CorbaFS_dirent__free(gpointer mem,
++ gpointer dat,
++ CORBA_boolean free_strings); /* ORBit internal use */
++ CorbaFS_dirent *CORBA_sequence_CorbaFS_dirent_allocbuf(CORBA_unsigned_long
++ len);
++#endif
++#if !defined(_CorbaFS_DirEntSeq_defined)
++#define _CorbaFS_DirEntSeq_defined 1
++ typedef CORBA_sequence_CorbaFS_dirent CorbaFS_DirEntSeq;
++#if !defined(TC_IMPL_TC_CorbaFS_DirEntSeq_0)
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_0 'C'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_1 'o'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_2 'r'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_3 'b'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_4 'a'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_5 'F'
++#define TC_IMPL_TC_CorbaFS_DirEntSeq_6 'S'
++ extern const struct CORBA_TypeCode_struct TC_CorbaFS_DirEntSeq_struct;
++#define TC_CorbaFS_DirEntSeq ((CORBA_TypeCode)&TC_CorbaFS_DirEntSeq_struct)
++#endif
++ extern CorbaFS_DirEntSeq *CorbaFS_DirEntSeq__alloc(void);
++ extern gpointer CorbaFS_DirEntSeq__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings); /* ORBit internal use */
++#endif
++#if !defined(ORBIT_DECL_CORBA_sequence_CORBA_octet) && !defined(_CORBA_sequence_CORBA_octet_defined)
++#define ORBIT_DECL_CORBA_sequence_CORBA_octet 1
++#define _CORBA_sequence_CORBA_octet_defined 1
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_0 'C'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_1 'o'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_2 'r'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_3 'b'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_4 'a'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_5 'F'
++#define ORBIT_IMPL_CORBA_sequence_CORBA_octet_6 'S'
++ typedef struct
++ {
++ CORBA_unsigned_long _maximum,
++ _length;
++ CORBA_octet *_buffer;
++ CORBA_boolean _release;
++ }
++ CORBA_sequence_CORBA_octet;
++#if !defined(TC_IMPL_TC_CORBA_sequence_CORBA_octet_0)
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_0 'C'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_1 'o'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_2 'r'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_3 'b'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_4 'a'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_5 'F'
++#define TC_IMPL_TC_CORBA_sequence_CORBA_octet_6 'S'
++ extern const struct CORBA_TypeCode_struct
++ TC_CORBA_sequence_CORBA_octet_struct;
++#define TC_CORBA_sequence_CORBA_octet ((CORBA_TypeCode)&TC_CORBA_sequence_CORBA_octet_struct)
++#endif
++ extern CORBA_sequence_CORBA_octet *CORBA_sequence_CORBA_octet__alloc(void);
++ extern gpointer CORBA_sequence_CORBA_octet__free(gpointer mem,
++ gpointer dat,
++ CORBA_boolean free_strings); /* ORBit internal use */
++ CORBA_octet *CORBA_sequence_CORBA_octet_allocbuf(CORBA_unsigned_long len);
++#endif
++#if !defined(_CorbaFS_Buffer_defined)
++#define _CorbaFS_Buffer_defined 1
++ typedef CORBA_sequence_CORBA_octet CorbaFS_Buffer;
++#if !defined(TC_IMPL_TC_CorbaFS_Buffer_0)
++#define TC_IMPL_TC_CorbaFS_Buffer_0 'C'
++#define TC_IMPL_TC_CorbaFS_Buffer_1 'o'
++#define TC_IMPL_TC_CorbaFS_Buffer_2 'r'
++#define TC_IMPL_TC_CorbaFS_Buffer_3 'b'
++#define TC_IMPL_TC_CorbaFS_Buffer_4 'a'
++#define TC_IMPL_TC_CorbaFS_Buffer_5 'F'
++#define TC_IMPL_TC_CorbaFS_Buffer_6 'S'
++ extern const struct CORBA_TypeCode_struct TC_CorbaFS_Buffer_struct;
++#define TC_CorbaFS_Buffer ((CORBA_TypeCode)&TC_CorbaFS_Buffer_struct)
++#endif
++ extern CorbaFS_Buffer *CorbaFS_Buffer__alloc(void);
++ extern gpointer CorbaFS_Buffer__free(gpointer mem, gpointer dat,
++ CORBA_boolean free_strings); /* ORBit internal use */
++#endif
++#if !defined(ORBIT_DECL_CorbaFS_Inode) && !defined(_CorbaFS_Inode_defined)
++#define ORBIT_DECL_CorbaFS_Inode 1
++#define _CorbaFS_Inode_defined 1
++#define CorbaFS_Inode__free CORBA_Object__free
++ typedef CORBA_Object CorbaFS_Inode;
++ extern CORBA_unsigned_long CorbaFS_Inode__classid;
++#if !defined(TC_IMPL_TC_CorbaFS_Inode_0)
++#define TC_IMPL_TC_CorbaFS_Inode_0 'C'
++#define TC_IMPL_TC_CorbaFS_Inode_1 'o'
++#define TC_IMPL_TC_CorbaFS_Inode_2 'r'
++#define TC_IMPL_TC_CorbaFS_Inode_3 'b'
++#define TC_IMPL_TC_CorbaFS_Inode_4 'a'
++#define TC_IMPL_TC_CorbaFS_Inode_5 'F'
++#define TC_IMPL_TC_CorbaFS_Inode_6 'S'
++ extern const struct CORBA_TypeCode_struct TC_CorbaFS_Inode_struct;
++#define TC_CorbaFS_Inode ((CORBA_TypeCode)&TC_CorbaFS_Inode_struct)
++#endif
++#endif
++#if !defined(ORBIT_DECL_CorbaFS_FileSystem) && !defined(_CorbaFS_FileSystem_defined)
++#define ORBIT_DECL_CorbaFS_FileSystem 1
++#define _CorbaFS_FileSystem_defined 1
++#define CorbaFS_FileSystem__free CORBA_Object__free
++ typedef CORBA_Object CorbaFS_FileSystem;
++ extern CORBA_unsigned_long CorbaFS_FileSystem__classid;
++#if !defined(TC_IMPL_TC_CorbaFS_FileSystem_0)
++#define TC_IMPL_TC_CorbaFS_FileSystem_0 'C'
++#define TC_IMPL_TC_CorbaFS_FileSystem_1 'o'
++#define TC_IMPL_TC_CorbaFS_FileSystem_2 'r'
++#define TC_IMPL_TC_CorbaFS_FileSystem_3 'b'
++#define TC_IMPL_TC_CorbaFS_FileSystem_4 'a'
++#define TC_IMPL_TC_CorbaFS_FileSystem_5 'F'
++#define TC_IMPL_TC_CorbaFS_FileSystem_6 'S'
++ extern const struct CORBA_TypeCode_struct TC_CorbaFS_FileSystem_struct;
++#define TC_CorbaFS_FileSystem ((CORBA_TypeCode)&TC_CorbaFS_FileSystem_struct)
++#endif
++#endif
++
++/** POA structures **/
++ typedef struct
++ {
++ void *_private;
++ void (*getStatus) (PortableServer_Servant _servant,
++ CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid, CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks, CORBA_long * atime,
++ CORBA_long * mtime, CORBA_long * ctime,
++ CORBA_Environment * ev);
++ void (*readpage) (PortableServer_Servant _servant,
++ CorbaFS_Buffer ** buffer, const CORBA_long size,
++ const CORBA_long offset, CORBA_Environment * ev);
++ void (*release) (PortableServer_Servant _servant,
++ CORBA_Environment * ev);
++ }
++ POA_CorbaFS_Inode__epv;
++ typedef struct
++ {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_CorbaFS_Inode__epv *CorbaFS_Inode_epv;
++ }
++ POA_CorbaFS_Inode__vepv;
++ typedef struct
++ {
++ void *_private;
++ POA_CorbaFS_Inode__vepv *vepv;
++ }
++ POA_CorbaFS_Inode;
++ extern void POA_CorbaFS_Inode__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++ extern void POA_CorbaFS_Inode__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++ typedef struct
++ {
++ void *_private;
++
++ CorbaFS_Inode(*getInode) (PortableServer_Servant _servant,
++ const CORBA_char * path,
++ CORBA_Environment * ev);
++ CorbaFS_DirEntSeq *(*readdir) (PortableServer_Servant _servant,
++ const CORBA_char * path,
++ CORBA_Environment * ev);
++ CORBA_char *(*readlink) (PortableServer_Servant _servant,
++ const CORBA_char * filename,
++ CORBA_Environment * ev);
++ }
++ POA_CorbaFS_FileSystem__epv;
++ typedef struct
++ {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_CorbaFS_FileSystem__epv *CorbaFS_FileSystem_epv;
++ }
++ POA_CorbaFS_FileSystem__vepv;
++ typedef struct
++ {
++ void *_private;
++ POA_CorbaFS_FileSystem__vepv *vepv;
++ }
++ POA_CorbaFS_FileSystem;
++ extern void POA_CorbaFS_FileSystem__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++ extern void POA_CorbaFS_FileSystem__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++
++/** prototypes **/
++ void CorbaFS_Inode_getStatus(CorbaFS_Inode _obj,
++ CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid,
++ CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks,
++ CORBA_long * atime, CORBA_long * mtime,
++ CORBA_long * ctime, CORBA_Environment * ev);
++ void CorbaFS_Inode_readpage(CorbaFS_Inode _obj, CorbaFS_Buffer ** buffer,
++ const CORBA_long size, const CORBA_long offset,
++ CORBA_Environment * ev);
++ void CorbaFS_Inode_release(CorbaFS_Inode _obj, CORBA_Environment * ev);
++ CorbaFS_Inode CorbaFS_FileSystem_getInode(CorbaFS_FileSystem _obj,
++ const CORBA_char * path,
++ CORBA_Environment * ev);
++ CorbaFS_DirEntSeq *CorbaFS_FileSystem_readdir(CorbaFS_FileSystem _obj,
++ const CORBA_char * path,
++ CORBA_Environment * ev);
++ CORBA_char *CorbaFS_FileSystem_readlink(CorbaFS_FileSystem _obj,
++ const CORBA_char * filename,
++ CORBA_Environment * ev);
++
++ void _ORBIT_skel_CorbaFS_Inode_getStatus(POA_CorbaFS_Inode *
++ _ORBIT_servant,
++ GIOPRecvBuffer *
++ _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ void (*_impl_getStatus)
++ (PortableServer_Servant _servant,
++ CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid,
++ CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks,
++ CORBA_long * atime,
++ CORBA_long * mtime,
++ CORBA_long * ctime,
++ CORBA_Environment * ev));
++ void _ORBIT_skel_CorbaFS_Inode_readpage(POA_CorbaFS_Inode * _ORBIT_servant,
++ GIOPRecvBuffer *
++ _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ void (*_impl_readpage)
++ (PortableServer_Servant _servant,
++ CorbaFS_Buffer ** buffer,
++ const CORBA_long size,
++ const CORBA_long offset,
++ CORBA_Environment * ev));
++ void _ORBIT_skel_CorbaFS_Inode_release(POA_CorbaFS_Inode * _ORBIT_servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ void (*_impl_release)
++ (PortableServer_Servant _servant,
++ CORBA_Environment * ev));
++ void _ORBIT_skel_CorbaFS_FileSystem_getInode(POA_CorbaFS_FileSystem *
++ _ORBIT_servant,
++ GIOPRecvBuffer *
++ _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ CorbaFS_Inode(*_impl_getInode)
++ (PortableServer_Servant
++ _servant,
++ const CORBA_char * path,
++ CORBA_Environment * ev));
++ void _ORBIT_skel_CorbaFS_FileSystem_readdir(POA_CorbaFS_FileSystem *
++ _ORBIT_servant,
++ GIOPRecvBuffer *
++ _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ CorbaFS_DirEntSeq *
++ (*_impl_readdir)
++ (PortableServer_Servant
++ _servant,
++ const CORBA_char * path,
++ CORBA_Environment * ev));
++ void _ORBIT_skel_CorbaFS_FileSystem_readlink(POA_CorbaFS_FileSystem *
++ _ORBIT_servant,
++ GIOPRecvBuffer *
++ _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ CORBA_char *
++ (*_impl_readlink)
++ (PortableServer_Servant
++ _servant,
++ const CORBA_char * filename,
++ CORBA_Environment * ev));
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif
++#undef ORBIT_IDL_SERIAL
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/Makefile linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/Makefile
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/Makefile Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,20 @@
++#
++# Makefile for KORBit CorbaFS client
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-corbafs-client.o
++
++obj-y := CorbaFS-common.o CorbaFS-stubs.o CorbaFS-client.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++CorbaFS-client.c: CorbaFS.h
++
++CorbaFS.h CorbaFS-common.c CorbaFS-stubs.c: ../CorbaFS.idl
++ $(ORBIT_IDL) --noskels ../CorbaFS.idl
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/Makefile.user linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/Makefile.user
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/Makefile.user Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/Makefile.user Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = CorbaFS
++
++CFLAGS = -Wall `orbit-config --cflags client` -I../../..
++LDFLAGS = `orbit-config --libs client`
++OBJS = $(PROJECT)-common.o $(PROJECT)-stubs.o $(PROJECT)-user-client.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-user-client: $(OBJS)
++ gcc -o $(PROJECT)-user-client $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-user-client.o: $(PROJECT).h
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-stubs.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --noskels ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-user-client
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-skels.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/client/README linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/README
+--- linux-2.4.1/net/korbit/modules/CorbaFS/client/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/client/README Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,4 @@
++This module implements the kernel VFS->kORBit interface. This is called a 'client'
++because it actually USES a CORBA object that is exported from someplace else.
++
++ORB: kORBit
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Entries Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,6 @@
++/CorbaFS-server.c/1.8/Thu Feb 1 09:47:03 2001//
++/CorbaFS-skelimpl.c/1.10/Thu Feb 1 09:47:04 2001//
++/Makefile/1.5/Thu Feb 1 09:47:04 2001//
++/README/1.2/Thu Feb 1 09:47:04 2001//
++/RunServer.sh/1.1/Thu Feb 1 09:47:04 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Repository Thu Feb 1 11:47:03 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CorbaFS/server
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CVS/Root Thu Feb 1 11:47:03 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/CorbaFS-server.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CorbaFS-server.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/CorbaFS-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CorbaFS-server.c Thu Feb 1 11:47:03 2001
+@@ -0,0 +1,37 @@
++#include <stdio.h>
++#include "CorbaFS-skelimpl.c"
++
++CORBA_ORB orb;
++PortableServer_POA poa;
++CORBA_Environment *ev;
++PortableServer_ObjectId *objid;
++
++int main(int argc, char *argv[]) {
++ CorbaFS_FileSystem fs;
++ impl_POA_CorbaFS_FileSystem *fs_impl;
++
++ PortableServer_POAManager pm;
++ ev = g_new0(CORBA_Environment,1);
++
++ CORBA_exception_init(ev);
++ printf("Make sure you use TCP/IP and not Unix sockets!\n");
++
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++ poa = (PortableServer_POA)
++ CORBA_ORB_resolve_initial_references(orb,
++ "RootPOA",
++ ev);
++ fs = impl_CorbaFS_FileSystem__create(poa, ev);
++
++ pm = PortableServer_POA__get_the_POAManager(poa, ev);
++ PortableServer_POAManager_activate(pm, ev);
++
++ fs_impl = PortableServer_POA_reference_to_servant( poa, fs, ev );
++ objid = PortableServer_POA_servant_to_id( poa, fs_impl, ev );
++
++ printf("CorbaFS-server:\n%s\n", CORBA_ORB_object_to_string(orb, fs, ev));
++
++ CORBA_ORB_run(orb, ev);
++
++ return 0;
++}
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/CorbaFS-skelimpl.c linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CorbaFS-skelimpl.c
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/CorbaFS-skelimpl.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/CorbaFS-skelimpl.c Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,353 @@
++#include <sys/param.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
++#include <fcntl.h>
++#include <dirent.h>
++
++#include "CorbaFS.h"
++
++/*** App-specific servant structures ***/
++
++#define printf(fmt, args...) fprintf(stderr, fmt, ##args);
++
++typedef struct
++{
++ POA_CorbaFS_Inode servant;
++ PortableServer_POA poa;
++
++ CORBA_char *path;
++#if 0
++ CORBA_unsigned_short mode;
++ CORBA_unsigned_long uid;
++ CORBA_unsigned_long gid;
++ CORBA_unsigned_long size;
++ CORBA_unsigned_long inodeNum;
++ CORBA_unsigned_short numLinks;
++ CORBA_long atime;
++ CORBA_long mtime;
++ CORBA_long ctime;
++#endif
++}
++impl_POA_CorbaFS_Inode;
++
++typedef struct
++{
++ POA_CorbaFS_FileSystem servant;
++ PortableServer_POA poa;
++
++}
++impl_POA_CorbaFS_FileSystem;
++
++/*** Implementation stub prototypes ***/
++
++static void impl_CorbaFS_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
++ CORBA_Environment * ev);
++static void
++impl_CorbaFS_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
++ CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid,
++ CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks,
++ CORBA_long * atime,
++ CORBA_long * mtime,
++ CORBA_long * ctime, CORBA_Environment * ev);
++
++static void
++impl_CorbaFS_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
++ CorbaFS_Buffer ** buffer,
++ CORBA_long size,
++ CORBA_long offset, CORBA_Environment * ev);
++
++static void
++impl_CorbaFS_Inode_release(impl_POA_CorbaFS_Inode * servant,
++ CORBA_Environment * ev);
++
++static void impl_CorbaFS_FileSystem__destroy(impl_POA_CorbaFS_FileSystem *
++ servant, CORBA_Environment * ev);
++static CorbaFS_Inode
++impl_CorbaFS_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * path, CORBA_Environment * ev);
++
++static CorbaFS_DirEntSeq
++ *impl_CorbaFS_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * path,
++
++ CORBA_Environment * ev);
++
++static CORBA_char
++ *impl_CorbaFS_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * filename,
++ CORBA_Environment * ev);
++
++/*** epv structures ***/
++
++static PortableServer_ServantBase__epv impl_CorbaFS_Inode_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_CorbaFS_Inode__epv impl_CorbaFS_Inode_epv = {
++ NULL, /* _private */
++ (gpointer) & impl_CorbaFS_Inode_getStatus,
++
++ (gpointer) & impl_CorbaFS_Inode_readpage,
++
++ (gpointer) & impl_CorbaFS_Inode_release,
++
++};
++static PortableServer_ServantBase__epv impl_CorbaFS_FileSystem_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_CorbaFS_FileSystem__epv impl_CorbaFS_FileSystem_epv = {
++ NULL, /* _private */
++ (gpointer) & impl_CorbaFS_FileSystem_getInode,
++
++ (gpointer) & impl_CorbaFS_FileSystem_readdir,
++
++ (gpointer) & impl_CorbaFS_FileSystem_readlink,
++
++};
++
++/*** vepv structures ***/
++
++static POA_CorbaFS_Inode__vepv impl_CorbaFS_Inode_vepv = {
++ &impl_CorbaFS_Inode_base_epv,
++ &impl_CorbaFS_Inode_epv,
++};
++static POA_CorbaFS_FileSystem__vepv impl_CorbaFS_FileSystem_vepv = {
++ &impl_CorbaFS_FileSystem_base_epv,
++ &impl_CorbaFS_FileSystem_epv,
++};
++
++/*** Stub implementations ***/
++
++static CorbaFS_Inode
++impl_CorbaFS_Inode__create(PortableServer_POA poa, CORBA_Environment * ev)
++{
++ CorbaFS_Inode retval;
++ impl_POA_CorbaFS_Inode *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_CorbaFS_Inode, 1);
++ newservant->servant.vepv = &impl_CorbaFS_Inode_vepv;
++ newservant->poa = poa;
++ POA_CorbaFS_Inode__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static void
++impl_CorbaFS_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_CorbaFS_Inode__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static void
++impl_CorbaFS_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
++ CORBA_unsigned_short * mode,
++ CORBA_unsigned_long * uid,
++ CORBA_unsigned_long * gid,
++ CORBA_unsigned_long * size,
++ CORBA_unsigned_long * inodeNum,
++ CORBA_unsigned_short * numLinks,
++ CORBA_long * atime,
++ CORBA_long * mtime,
++ CORBA_long * ctime, CORBA_Environment * ev)
++{
++ struct stat buf;
++
++ printf("Inode_getStatus()\n");
++ printf("Inode path = %s\n", servant->path);
++ lstat(servant->path, &buf);
++
++ *mode = buf.st_mode;
++ *uid = buf.st_uid;
++ *gid = buf.st_gid;
++ *size = buf.st_size;
++ *inodeNum = buf.st_ino;
++ *numLinks = buf.st_nlink;
++ *atime = buf.st_atime;
++ *mtime = buf.st_mtime;
++ *ctime = buf.st_ctime;
++}
++
++static void
++impl_CorbaFS_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
++ CorbaFS_Buffer ** buffer,
++ CORBA_long size,
++ CORBA_long offset, CORBA_Environment * ev)
++{
++ int fd = -1, c = 0;
++
++ printf("Inode_readpage(buffer, %d, %d)\n", size, offset);
++ printf("Inode_readpage : path = %s\n", servant->path);
++
++ *buffer = CorbaFS_Buffer__alloc();
++ (*buffer)->_maximum = size;
++ (*buffer)->_buffer = CORBA_octet_allocbuf(size);
++
++ memset((*buffer)->_buffer, size, 0);
++
++ fd = open(servant->path, O_RDONLY);
++ printf("Inode_readpage : fd = %d\n", fd);
++ lseek(fd, offset, SEEK_SET);
++ c = read(fd, (*buffer)->_buffer, size);
++ printf("Inode_readpage : read %d bytes\n", c);
++ (*buffer)->_length = c;
++ close(fd);
++}
++
++static void
++impl_CorbaFS_Inode_release(impl_POA_CorbaFS_Inode * servant,
++ CORBA_Environment * ev)
++{
++ printf("Inode_release()\n");
++}
++
++static CorbaFS_FileSystem
++impl_CorbaFS_FileSystem__create(PortableServer_POA poa,
++ CORBA_Environment * ev)
++{
++ CorbaFS_FileSystem retval;
++ impl_POA_CorbaFS_FileSystem *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_CorbaFS_FileSystem, 1);
++ newservant->servant.vepv = &impl_CorbaFS_FileSystem_vepv;
++ newservant->poa = poa;
++ POA_CorbaFS_FileSystem__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static void
++impl_CorbaFS_FileSystem__destroy(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_CorbaFS_FileSystem__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static CorbaFS_Inode
++impl_CorbaFS_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * path, CORBA_Environment * ev)
++{
++ CorbaFS_Inode retval;
++ impl_POA_CorbaFS_Inode *inode;
++
++ printf("FileSystem_getInode(%s)\n", path);
++
++ retval = impl_CorbaFS_Inode__create(servant->poa, ev);
++
++ inode = PortableServer_POA_reference_to_servant( servant->poa, retval, ev );
++ inode->path = CORBA_string_dup(path);
++#if 0
++ inode->mode = 0040777; /* world-readable directory */
++ inode->uid = 0;
++ inode->gid = 0;
++ inode->size = 4096;
++ inode->inodeNum = inodeNum++;
++ inode->numLinks = 1;
++ inode->atime = 0;
++ inode->mtime = 100;
++ inode->ctime = 10000;
++#endif
++
++ return retval;
++}
++
++static CorbaFS_DirEntSeq *
++impl_CorbaFS_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * path, CORBA_Environment * ev)
++{
++ CorbaFS_DirEntSeq *retval;
++ CorbaFS_dirent *dirent;
++
++ DIR *dir;
++ struct dirent *dirp;
++ int c;
++
++ printf("FileSystem_readdir(%s)\n", path);
++
++ retval = CorbaFS_DirEntSeq__alloc();
++ retval->_maximum = 0;
++ retval->_length = 0;
++
++ dir = opendir(path);
++ if (dir == NULL)
++ return retval;
++
++ c = 0;
++ while ((dirp = readdir(dir)))
++ c++;
++
++ rewinddir(dir);
++
++ printf("%d directories\n", c);
++
++ retval->_buffer = CORBA_sequence_CorbaFS_dirent_allocbuf(c);
++ retval->_maximum = c;
++ dirent = retval->_buffer;
++
++ c = 0;
++ while ((dirp = readdir(dir)) && (c < retval->_maximum))
++ {
++ printf("Adding directory %d : %s (%d)\n", c, dirp->d_name, dirp->d_ino);
++
++ dirent[c].inode = dirp->d_ino;
++ dirent[c].name = CORBA_string_dup(dirp->d_name);
++ c++;
++ }
++ retval->_length = c;
++
++ closedir(dir);
++
++ return retval;
++}
++
++static CORBA_char *
++impl_CorbaFS_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
++ CORBA_char * filename,
++ CORBA_Environment * ev)
++{
++ CORBA_char *retval = CORBA_OBJECT_NIL;
++ char tmp[MAXPATHLEN + 1];
++ int len;
++
++ printf("FileSystem_readlink(%s) = ", filename);
++ len = readlink(filename, tmp, MAXPATHLEN);
++ if (len != -1)
++ {
++ tmp[len] = '\0';
++ retval = CORBA_string_dup(tmp);
++ }
++
++ printf("%s\n", retval);
++
++ return retval;
++}
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/Makefile linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/Makefile
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/Makefile Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = CorbaFS
++
++CFLAGS = -Wall `orbit-config --cflags server` -I../../..
++LDFLAGS = `orbit-config --libs server`
++OBJS = $(PROJECT)-common.o $(PROJECT)-skels.o $(PROJECT)-server.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-server: $(OBJS)
++ gcc -o $(PROJECT)-server $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-server.o: $(PROJECT).h $(PROJECT)-skelimpl.c
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-skels.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --nostubs ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-server
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-skels.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/README linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/README
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/README Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,8 @@
++This server provides an NFS like capability of exporting an existing filesystem.
++
++ORB: ORBit
++Status: Working! (for readonly fs's)
++
++NOTE!!!!: When starting this server make sure you pass ORBit the options to
++ have it use ipv4 sockets and not unix domain sockets, or else bad
++ things will happen. You can use the included RunServer script.
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server/RunServer.sh linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/RunServer.sh
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server/RunServer.sh Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server/RunServer.sh Thu Feb 1 11:47:04 2001
+@@ -0,0 +1 @@
++./CorbaFS-server -ORBIIOPUSock=0 -ORBIIOPIPv4=1
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Entries Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,3 @@
++/PerlServer/1.2/Thu Feb 1 09:47:04 2001//
++/README/1.1/Thu Feb 1 09:47:04 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Repository Thu Feb 1 11:47:04 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/CorbaFS/server-perl
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Root linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Root
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/CVS/Root Thu Feb 1 11:47:04 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/PerlServer linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/PerlServer
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/PerlServer Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/PerlServer Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,67 @@
++#!/usr/bin/perl -w
++use CORBA::ORBit idl => [ qw(../CorbaFS.idl) ];
++use Error qw(:try);
++use strict;
++
++
++package MyFSInode;
++@MyFSInode::ISA = qw(POA_CorbaFS::Inode);
++
++sub new {
++ my $self = bless { name => shift };
++ print "INODE CREATED: $self->{name}!\n";
++}
++
++sub getStatus {
++ my ($self) = @_;
++ print "$self->getStatus()\n";
++}
++
++sub readpage {
++ return "";
++}
++
++sub release {
++}
++
++
++package MyFileSystem;
++@MyFileSystem::ISA = qw(POA_CorbaFS::FileSystem);
++
++sub new {
++ my $self = bless { root => '/home' };
++}
++
++sub getInode {
++ my $path = shift;
++ print "getInode($path)\n";
++ return new MyFSInode($path);
++}
++
++sub readdir {
++ my $path = shift;
++ print "readdir($path)\n";
++ return [ { inode => 1, name => '...' } ];
++}
++
++sub readlink {
++ my $path = shift;
++ print "readlink($path)\n";
++ return "fredrik";
++}
++
++
++package Main;
++
++my $orb = CORBA::ORB_init("orbit-local-orb");
++my $poa = $orb->resolve_initial_references("RootPOA");
++
++my $Server = new MyFileSystem();
++my $id = $poa->activate_object($Server);
++my $ref = $orb->object_to_string($poa->id_to_reference($id));
++
++print "$ref\n";
++
++print "Running orb:\n";
++$orb->run();
++exit(0);
+diff -urN linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/README linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/README
+--- linux-2.4.1/net/korbit/modules/CorbaFS/server-perl/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/CorbaFS/server-perl/README Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,4 @@
++Test filesystem implementation in Perl.
++
++ORB: ORBit/Perl
++Status: horribly broken
+diff -urN linux-2.4.1/net/korbit/modules/Echo/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Echo/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Entries Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,4 @@
++/Makefile/1.3/Thu Feb 1 09:47:04 2001//
++/README/1.1/Thu Feb 1 09:47:05 2001//
++/echo.idl/1.1/Thu Feb 1 09:47:05 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Echo/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/Echo/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Entries.Log Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,3 @@
++A D/client////
++A D/client-perl////
++A D/server////
+diff -urN linux-2.4.1/net/korbit/modules/Echo/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Echo/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Repository Thu Feb 1 11:47:04 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Echo
+diff -urN linux-2.4.1/net/korbit/modules/Echo/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Echo/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/CVS/Root Thu Feb 1 11:47:04 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Echo/Makefile linux-2.4.1-korbit/net/korbit/modules/Echo/Makefile
+--- linux-2.4.1/net/korbit/modules/Echo/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/Makefile Thu Feb 1 11:47:04 2001
+@@ -0,0 +1,11 @@
++#
++# Makefile for KORBit/modules/Console
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_ECHO) := client server
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/Echo/README linux-2.4.1-korbit/net/korbit/modules/Echo/README
+--- linux-2.4.1/net/korbit/modules/Echo/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/README Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,2 @@
++The Echo test is very similar to the console test, but it also "returns" a
++"random" number. The random number, in our case, is simply a constant.
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Echo/client/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Entries Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,6 @@
++/Makefile/1.4/Thu Feb 1 09:47:05 2001//
++/Makefile.user/1.1/Thu Feb 1 09:47:05 2001//
++/README/1.1/Thu Feb 1 09:47:05 2001//
++/RunClient.sh/1.1/Thu Feb 1 09:47:05 2001//
++/echo-client.c/1.6/Thu Feb 1 09:47:05 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Echo/client/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Repository Thu Feb 1 11:47:05 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Echo/client
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Echo/client/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/CVS/Root Thu Feb 1 11:47:05 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/Makefile linux-2.4.1-korbit/net/korbit/modules/Echo/client/Makefile
+--- linux-2.4.1/net/korbit/modules/Echo/client/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/Makefile Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,20 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-echo-client.o
++
++obj-y := echo-common.o echo-stubs.o echo-client.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++echo-client.c: echo.h
++
++echo.h echo-common.c echo-stubs.c: ../echo.idl
++ $(ORBIT_IDL) --noskels ../echo.idl
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/Makefile.user linux-2.4.1-korbit/net/korbit/modules/Echo/client/Makefile.user
+--- linux-2.4.1/net/korbit/modules/Echo/client/Makefile.user Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/Makefile.user Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = echo
++
++CFLAGS = -Wall `orbit-config --cflags client` -I../../..
++LDFLAGS = `orbit-config --libs client`
++OBJS = $(PROJECT)-common.o $(PROJECT)-stubs.o $(PROJECT)-client.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-client: $(OBJS)
++ gcc -o $(PROJECT)-client $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-client.c: $(PROJECT).h
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-stubs.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --noskels ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-client
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-stubs.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/README linux-2.4.1-korbit/net/korbit/modules/Echo/client/README
+--- linux-2.4.1/net/korbit/modules/Echo/client/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/README Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,4 @@
++This simply tests the Echo service.
++
++ORB: ORBit
++Status: working
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/RunClient.sh linux-2.4.1-korbit/net/korbit/modules/Echo/client/RunClient.sh
+--- linux-2.4.1/net/korbit/modules/Echo/client/RunClient.sh Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/RunClient.sh Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,3 @@
++#!/bin/sh
++date
++./echo-client `cat /proc/corba/echo-server` 5
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/echo-client.c linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-client.c
+--- linux-2.4.1/net/korbit/modules/Echo/client/echo-client.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-client.c Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,119 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <sys/time.h>
++#include <unistd.h>
++#include <orb/orbit.h>
++
++#ifdef __KERNEL__
++#include <linux/init.h>
++#include <linux/module.h>
++#include "korbit.h"
++#endif
++#include "echo.h"
++
++Echo echo_client, bec;
++
++#define BATCH_SIZE 1
++
++
++#ifndef __KERNEL__
++int main (int argc, char *argv[]) {
++#else
++int __init corba_echo_init(void) {
++ int argc = 1; char *argv[] = { "echo-client", 0, 0 };
++#endif
++ CORBA_Environment ev;
++ CORBA_ORB orb;
++ CORBA_long rv;
++ char buf[30];
++ int i, j;
++
++ int niters = 5;
++
++#ifndef __KERNEL__
++ struct timeval start, end;
++ long diff, diffsum = 0;
++#endif
++
++ CORBA_exception_init(&ev);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
++
++#ifdef __KERNEL__
++ {
++ int c, fd = open("/tmp/echo-ior", O_RDONLY, 0);
++ if (fd == -1)
++ return -1;
++ printf("Reading IOR from /tmp/echo-ior\n");
++ argv[1] = malloc(501);
++ c = read(fd, argv[1], 500);
++ argv[1][c] = '\0';
++ printf("Reading %d bytes: %s\n", c, argv[1]);
++ }
++#else
++ if(argc < 2)
++ {
++ printf("Need an IOR as argv[1]\n");
++ return 1;
++ }
++
++ if(argc == 3)
++ niters = atoi(argv[2]);
++#endif
++
++ echo_client = CORBA_ORB_string_to_object(orb, argv[1], &ev);
++ if (!echo_client) {
++ printf("Cannot bind to %s\n", argv[1]);
++ return 1;
++ }
++
++ for(i = 0; i < niters; i++) {
++ g_snprintf(buf, sizeof(buf), "Hello, world [%d]", i);
++#ifdef __KERNEL__
++ bec = Echo_echoString(echo_client, buf, &rv, &ev);
++#else
++ gettimeofday(&start, NULL);
++ for (j = BATCH_SIZE; j > 0; j--) {
++ bec = Echo_echoString(echo_client, buf, &rv, &ev);
++ if (j != 1) CORBA_Object_release(bec, &ev);
++ }
++ gettimeofday(&end, NULL);
++ diff = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
++ diff /= BATCH_SIZE;
++ diffsum += diff;
++
++ printf("duration = %d usec\t", diff);
++#endif
++
++ if(ev._major != CORBA_NO_EXCEPTION) {
++ printf("\nWe got exception %d from echoString!\n", ev._major);
++ return 1;
++ }
++
++ CORBA_Object_release(echo_client, &ev);
++ if(ev._major != CORBA_NO_EXCEPTION) {
++ printf("we got exception %d from release!\n", ev._major);
++ return 1;
++ }
++
++ printf("[client] %d\n", rv);
++
++ echo_client = bec; bec = CORBA_OBJECT_NIL;
++ }
++
++#ifndef __KERNEL__
++ printf("duration average = %d usec\n", diffsum / niters);
++ CORBA_Object_release(echo_client, &ev);
++ CORBA_Object_release((CORBA_Object)orb, &ev);
++#endif
++
++ return 0;
++}
++
++
++#ifdef __KERNEL__
++void corba_echo_exit(void) {
++}
++
++module_init(corba_echo_init)
++module_exit(corba_echo_exit)
++#endif
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/echo-common.c linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-common.c
+--- linux-2.4.1/net/korbit/modules/Echo/client/echo-common.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-common.c Thu Feb 1 16:36:36 2001
+@@ -0,0 +1,27 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "echo.h"
++
++#if ( (TC_IMPL_TC_Echo_0 == 'e') \
++&& (TC_IMPL_TC_Echo_1 == 'c') \
++&& (TC_IMPL_TC_Echo_2 == 'h') \
++&& (TC_IMPL_TC_Echo_3 == 'o') \
++) && !defined(TC_DEF_TC_Echo)
++#define TC_DEF_TC_Echo 1
++const struct CORBA_TypeCode_struct TC_Echo_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_objref, "Echo", "IDL:Echo:1.0",
++ 0, 0,
++ NULL,
++ NULL,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++CORBA_unsigned_long Echo__classid = 0;
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/echo-stubs.c linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-stubs.c
+--- linux-2.4.1/net/korbit/modules/Echo/client/echo-stubs.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo-stubs.c Thu Feb 1 16:36:36 2001
+@@ -0,0 +1,134 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "echo.h"
++
++Echo
++Echo_echoString(Echo _obj, const CORBA_char * astring, CORBA_long * anum,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ Echo _ORBIT_retval;
++
++ if (_obj->servant && _obj->vepv && Echo__classid) {
++ _ORBIT_retval =
++ ((POA_Echo__epv *) _obj->vepv[Echo__classid])->echoString(_obj->
++ servant,
++ astring,
++ anum, ev);
++ return _ORBIT_retval;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[11];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 11, "echoString"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 15 };
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(astring) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ {
++ guchar *_ORBIT_t;
++
++ _ORBIT_t = alloca(sizeof(_ORBIT_tmpvar_1));
++ memcpy(_ORBIT_t, &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), (_ORBIT_t),
++ sizeof(_ORBIT_tmpvar_1));
++ }
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ (astring),
++ sizeof(astring[_ORBIT_tmpvar_0]) *
++ _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & ((*anum)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));} else {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*anum) = *((CORBA_long *) _ORBIT_curptr);
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++}
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client/echo.h linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo.h
+--- linux-2.4.1/net/korbit/modules/Echo/client/echo.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client/echo.h Thu Feb 1 16:36:36 2001
+@@ -0,0 +1,77 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <glib.h>
++#define ORBIT_IDL_SERIAL 9
++#include <orb/orbit.h>
++
++#ifndef echo_H
++#define echo_H 1
++#ifdef __cplusplus
++extern "C"
++{
++#endif /* __cplusplus */
++
++/** typedefs **/
++#if !defined(ORBIT_DECL_Echo) && !defined(_Echo_defined)
++#define ORBIT_DECL_Echo 1
++#define _Echo_defined 1
++#define Echo__free CORBA_Object__free
++ typedef CORBA_Object Echo;
++ extern CORBA_unsigned_long Echo__classid;
++#if !defined(TC_IMPL_TC_Echo_0)
++#define TC_IMPL_TC_Echo_0 'e'
++#define TC_IMPL_TC_Echo_1 'c'
++#define TC_IMPL_TC_Echo_2 'h'
++#define TC_IMPL_TC_Echo_3 'o'
++ extern const struct CORBA_TypeCode_struct TC_Echo_struct;
++#define TC_Echo ((CORBA_TypeCode)&TC_Echo_struct)
++#endif
++#endif
++
++/** POA structures **/
++ typedef struct
++ {
++ void *_private;
++
++ Echo(*echoString) (PortableServer_Servant _servant,
++ const CORBA_char * astring, CORBA_long * anum,
++ CORBA_Environment * ev);
++ }
++ POA_Echo__epv;
++ typedef struct
++ {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_Echo__epv *Echo_epv;
++ }
++ POA_Echo__vepv;
++ typedef struct
++ {
++ void *_private;
++ POA_Echo__vepv *vepv;
++ }
++ POA_Echo;
++ extern void POA_Echo__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++ extern void POA_Echo__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++
++/** prototypes **/
++ Echo Echo_echoString(Echo _obj, const CORBA_char * astring,
++ CORBA_long * anum, CORBA_Environment * ev);
++
++ void _ORBIT_skel_Echo_echoString(POA_Echo * _ORBIT_servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ Echo(*_impl_echoString)
++ (PortableServer_Servant _servant,
++ const CORBA_char * astring,
++ CORBA_long * anum,
++ CORBA_Environment * ev));
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif
++#undef ORBIT_IDL_SERIAL
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Entries Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,3 @@
++/PerlTest/1.2/Thu Feb 1 09:47:06 2001//
++/README/1.1/Thu Feb 1 09:47:06 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Repository Thu Feb 1 11:47:06 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Echo/client-perl
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Echo/client-perl/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/CVS/Root Thu Feb 1 11:47:06 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client-perl/PerlTest linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/PerlTest
+--- linux-2.4.1/net/korbit/modules/Echo/client-perl/PerlTest Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/PerlTest Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,17 @@
++#!/usr/bin/perl -w
++
++use CORBA::ORBit idl => [ qw(../echo.idl) ];
++use Error qw(:try);
++use strict;
++
++my $orb = CORBA::ORB_init("orbit-local-orb");
++open IOR, "/proc/corba/echo-server" or die "no console server found!";
++my $ior = <IOR>;
++close IOR;
++chomp($ior); # Kill fredrik's newline...
++
++my $echo = $orb->string_to_object($ior);
++# Echo echoString(in string astring, out long anum);
++my ($echo2, $num) = $echo->echoString("Echo Strange World");
++
++print "Return Echo = $echo2\nnum = $num\n";
+diff -urN linux-2.4.1/net/korbit/modules/Echo/client-perl/README linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/README
+--- linux-2.4.1/net/korbit/modules/Echo/client-perl/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/client-perl/README Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,4 @@
++Another test of the echo server.
++
++ORB: ORBit/Perl
++Status: Working fine
+diff -urN linux-2.4.1/net/korbit/modules/Echo/echo.idl linux-2.4.1-korbit/net/korbit/modules/Echo/echo.idl
+--- linux-2.4.1/net/korbit/modules/Echo/echo.idl Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/echo.idl Thu Feb 1 11:47:05 2001
+@@ -0,0 +1,3 @@
++interface Echo {
++ Echo echoString(in string astring, out long anum);
++};
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/Echo/server/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Entries Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,6 @@
++/Makefile/1.2/Thu Feb 1 09:47:06 2001//
++/Makefile.user/1.3/Thu Feb 1 09:47:06 2001//
++/README/1.1/Thu Feb 1 09:47:06 2001//
++/RunServer.sh/1.1/Thu Feb 1 09:47:06 2001//
++/echo-server.c/1.8/Thu Feb 1 09:47:06 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/Echo/server/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Repository Thu Feb 1 11:47:06 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/Echo/server
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/CVS/Root linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Root
+--- linux-2.4.1/net/korbit/modules/Echo/server/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/CVS/Root Thu Feb 1 11:47:06 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/Makefile linux-2.4.1-korbit/net/korbit/modules/Echo/server/Makefile
+--- linux-2.4.1/net/korbit/modules/Echo/server/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/Makefile Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,21 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-echo-server.o
++
++obj-y := echo-server.o echo-skels.o echo-common.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++echo-server.c: echo.h echo-skels.c
++
++
++echo.h echo-common.c echo-skels.c: ../echo.idl
++ $(ORBIT_IDL) ../echo.idl
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/Makefile.user linux-2.4.1-korbit/net/korbit/modules/Echo/server/Makefile.user
+--- linux-2.4.1/net/korbit/modules/Echo/server/Makefile.user Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/Makefile.user Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,27 @@
++#
++# Makefile for user level server
++#
++
++PROJECT = echo
++
++CFLAGS = -Wall `orbit-config --cflags server` -I../../..
++LDFLAGS = `orbit-config --libs server`
++OBJS = $(PROJECT)-common.o $(PROJECT)-skels.o $(PROJECT)-server.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-server: $(OBJS)
++ gcc -o $(PROJECT)-server $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-server.c: $(PROJECT).h
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-skels.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --nostubs ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-server
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-skels.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/README linux-2.4.1-korbit/net/korbit/modules/Echo/server/README
+--- linux-2.4.1/net/korbit/modules/Echo/server/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/README Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,5 @@
++This server implements the kernel side interface in terms of printk.
++
++This server also builds in user space with ORBit. Build with
++ make -f Makefile.user
++
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/RunServer.sh linux-2.4.1-korbit/net/korbit/modules/Echo/server/RunServer.sh
+--- linux-2.4.1/net/korbit/modules/Echo/server/RunServer.sh Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/RunServer.sh Thu Feb 1 11:47:06 2001
+@@ -0,0 +1 @@
++./echo-server -ORBIIOPUSock=0 -ORBIIOPIPv4=1
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/echo-common.c linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-common.c
+--- linux-2.4.1/net/korbit/modules/Echo/server/echo-common.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-common.c Thu Feb 1 16:36:57 2001
+@@ -0,0 +1,27 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "echo.h"
++
++#if ( (TC_IMPL_TC_Echo_0 == 'e') \
++&& (TC_IMPL_TC_Echo_1 == 'c') \
++&& (TC_IMPL_TC_Echo_2 == 'h') \
++&& (TC_IMPL_TC_Echo_3 == 'o') \
++) && !defined(TC_DEF_TC_Echo)
++#define TC_DEF_TC_Echo 1
++const struct CORBA_TypeCode_struct TC_Echo_struct = {
++
++ {{(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1},
++ ORBIT_PSEUDO_TYPECODE},
++
++ CORBA_tk_objref, "Echo", "IDL:Echo:1.0",
++ 0, 0,
++ NULL,
++ NULL,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++CORBA_unsigned_long Echo__classid = 0;
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/echo-server.c linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-server.c
+--- linux-2.4.1/net/korbit/modules/Echo/server/echo-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-server.c Thu Feb 1 11:47:06 2001
+@@ -0,0 +1,103 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <signal.h>
++#include <orb/orbit.h>
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include "echo.h"
++#include "glib.h"
++#include "korbit.h"
++
++Echo echo_client = CORBA_OBJECT_NIL;
++
++static CORBA_Object
++do_echoString(PortableServer_Servant servant,
++ CORBA_char *astring,
++ CORBA_long *outnum,
++ CORBA_Environment *ev);
++
++PortableServer_ServantBase__epv base_epv = {
++ NULL,
++ NULL,
++ NULL
++};
++POA_Echo__epv echo_epv = { NULL, do_echoString };
++POA_Echo__vepv poa_echo_vepv = { &base_epv, &echo_epv };
++POA_Echo poa_echo_servant = { NULL, &poa_echo_vepv };
++
++PortableServer_ObjectId objid = {0, sizeof("myEchoString"), "myEchoString"};
++PortableServer_POA poa;
++CORBA_Environment *ev;
++
++#ifdef __KERNEL__
++int __init corba_echo_init(void)
++#else
++int main(int argc, char *argv[])
++#endif
++{
++#ifdef __KERNEL__
++ int argc = 1; char *argv[] = { "server", 0 };
++#endif
++ CORBA_ORB orb;
++ ev = g_new0(CORBA_Environment, 1);
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++ if (!orb) {
++ printf("Error getting ORB!\n");
++ return 1;
++ }
++
++ poa = (PortableServer_POA)
++ CORBA_ORB_resolve_initial_references(orb, "RootPOA", ev);
++ if (!poa) {
++ printf("Error getting POA!\n");
++ return 1;
++ }
++
++ PortableServer_POAManager_activate(
++ PortableServer_POA__get_the_POAManager(poa, ev), ev);
++
++
++ POA_Echo__init(&poa_echo_servant, ev);
++ PortableServer_POA_activate_object_with_id(poa,
++ &objid, &poa_echo_servant, ev);
++
++ echo_client = PortableServer_POA_servant_to_reference(poa,
++ &poa_echo_servant,
++ ev);
++ if (!echo_client) {
++ printf("Cannot get objref\n");
++ return 1;
++ }
++
++ korbit_register_ior("echo-server", echo_client, orb, ev);
++
++ CORBA_ORB_run(orb, ev);
++ return 0;
++}
++
++#ifdef __KERNEL__
++void corba_echo_exit(void) {
++ PortableServer_POA_deactivate_object(poa, &objid, ev);
++ remove_proc_entry("corba/echo-server", 0);
++}
++
++module_init(corba_echo_init)
++module_exit(corba_echo_exit)
++#endif
++
++static CORBA_Object
++do_echoString(PortableServer_Servant servant,
++ CORBA_char *astring,
++ CORBA_long *outnum,
++ CORBA_Environment *ev)
++{
++ *outnum = 12345678;
++
++#if 1
++ g_message("[server] %s -> %d", astring, *outnum);
++#endif
++
++ return CORBA_Object_duplicate(echo_client, ev);
++}
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/echo-skels.c linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-skels.c
+--- linux-2.4.1/net/korbit/modules/Echo/server/echo-skels.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-skels.c Thu Feb 1 16:36:57 2001
+@@ -0,0 +1,115 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "echo.h"
++
++void
++_ORBIT_skel_Echo_echoString(POA_Echo * _ORBIT_servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ Echo(*_impl_echoString) (PortableServer_Servant
++ _servant,
++ const CORBA_char *
++ astring,
++ CORBA_long * anum,
++ CORBA_Environment * ev))
++{
++ Echo _ORBIT_retval;
++ CORBA_char *astring;
++ CORBA_long anum;
++
++ { /* demarshalling */
++ guchar *_ORBIT_curptr;
++ register CORBA_unsigned_long _ORBIT_tmpvar_2;
++ CORBA_unsigned_long _ORBIT_tmpvar_3;
++
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & (_ORBIT_tmpvar_3))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));
++ _ORBIT_curptr += 4;
++ astring = (void *) _ORBIT_curptr;
++ _ORBIT_curptr += sizeof(astring[_ORBIT_tmpvar_2]) * _ORBIT_tmpvar_3;
++ } else {
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ _ORBIT_tmpvar_3 = *((CORBA_unsigned_long *) _ORBIT_curptr);
++ _ORBIT_curptr += 4;
++ astring = (void *) _ORBIT_curptr;
++ _ORBIT_curptr += sizeof(astring[_ORBIT_tmpvar_2]) * _ORBIT_tmpvar_3;
++ }
++ }
++ _ORBIT_retval = _impl_echoString(_ORBIT_servant, astring, &(anum), ev);
++ { /* marshalling */
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++
++ _ORBIT_send_buffer =
++ giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection, NULL,
++ _ORBIT_recv_buffer->message.u.request.
++ request_id, ev->_major);
++ if (_ORBIT_send_buffer) {
++ if (ev->_major == CORBA_NO_EXCEPTION) {
++ ORBit_marshal_object(_ORBIT_send_buffer, _ORBIT_retval);
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), &(anum),
++ sizeof(anum));
++ } else
++ ORBit_send_system_exception(_ORBIT_send_buffer, ev);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ }
++ if (ev->_major == CORBA_NO_EXCEPTION)
++ CORBA_Object_release(_ORBIT_retval, ev);
++ }
++}
++static ORBitSkeleton
++get_skel_Echo(POA_Echo * servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer, gpointer * impl)
++{
++ gchar *opname = _ORBIT_recv_buffer->message.u.request.operation;
++
++ switch (opname[0]) {
++ case 'e':
++ if (strcmp((opname + 1), "choString"))
++ break;
++ *impl = (gpointer) servant->vepv->Echo_epv->echoString;
++ return (ORBitSkeleton) _ORBIT_skel_Echo_echoString;
++ break;
++ default:
++ break;
++ }
++ return NULL;
++}
++
++static void
++init_local_objref_Echo(CORBA_Object obj, POA_Echo * servant)
++{
++ obj->vepv[Echo__classid] = servant->vepv->Echo_epv;
++}
++
++void
++POA_Echo__init(PortableServer_Servant servant, CORBA_Environment * env)
++{
++ static const PortableServer_ClassInfo class_info =
++ { (ORBit_impl_finder) & get_skel_Echo, "IDL:Echo:1.0",
++ (ORBit_local_objref_init) & init_local_objref_Echo };
++
++ PortableServer_ServantBase__init(((PortableServer_ServantBase *) servant),
++ env);
++ ORBIT_OBJECT_KEY(((PortableServer_ServantBase *) servant)->_private)->
++ class_info = (PortableServer_ClassInfo *) & class_info;
++ if (!Echo__classid)
++ Echo__classid = ORBit_register_class(&class_info);
++}
++
++void
++POA_Echo__fini(PortableServer_Servant servant, CORBA_Environment * env)
++{
++ PortableServer_ServantBase__fini(servant, env);
++}
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/echo-stubs.c linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-stubs.c
+--- linux-2.4.1/net/korbit/modules/Echo/server/echo-stubs.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo-stubs.c Thu Feb 1 16:36:57 2001
+@@ -0,0 +1,134 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <string.h>
++#include "echo.h"
++
++Echo
++Echo_echoString(Echo _obj, const CORBA_char * astring, CORBA_long * anum,
++ CORBA_Environment * ev)
++{
++ register GIOP_unsigned_long _ORBIT_request_id,
++ _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++ Echo _ORBIT_retval;
++
++ if (_obj->servant && _obj->vepv && Echo__classid) {
++ _ORBIT_retval =
++ ((POA_Echo__epv *) _obj->vepv[Echo__classid])->echoString(_obj->
++ servant,
++ astring,
++ anum, ev);
++ return _ORBIT_retval;
++ }
++ _cnx = ORBit_object_get_connection(_obj);
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ _ORBIT_request_id = GPOINTER_TO_UINT(alloca(0));
++ { /* marshalling */
++ static const struct
++ {
++ CORBA_unsigned_long len;
++ char opname[11];
++ }
++ _ORBIT_operation_name_data =
++ {
++ 11, "echoString"};
++ static const struct iovec _ORBIT_operation_vec =
++ { (gpointer) & _ORBIT_operation_name_data, 15 };
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id,
++ CORBA_TRUE,
++ &(_obj->active_profile->object_key_vec),
++ &_ORBIT_operation_vec,
++ &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(astring) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), 4);
++ {
++ guchar *_ORBIT_t;
++
++ _ORBIT_t = alloca(sizeof(_ORBIT_tmpvar_1));
++ memcpy(_ORBIT_t, &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER
++ (_ORBIT_send_buffer), (_ORBIT_t),
++ sizeof(_ORBIT_tmpvar_1));
++ }
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer),
++ (astring),
++ sizeof(astring[_ORBIT_tmpvar_0]) *
++ _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++
++ _ORBIT_recv_buffer =
++ giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status !=
++ GIOP_NO_EXCEPTION) goto _ORBIT_msg_exception;
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++
++ (*((guint32 *) & ((*anum)))) =
++ GUINT32_SWAP_LE_BE(*((guint32 *) _ORBIT_curptr));} else {
++ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = _ORBIT_curptr;
++ _ORBIT_retval =
++ ORBit_demarshal_object(_ORBIT_recv_buffer,
++ GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->
++ connection->orb_data);
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_curptr = ALIGN_ADDRESS(_ORBIT_curptr, 4);
++ (*anum) = *((CORBA_long *) _ORBIT_curptr);
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor,
++ _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status ==
++ GIOP_LOCATION_FORWARD) {
++ if (_obj->forward_locations != NULL)
++ ORBit_delete_profiles(_obj->forward_locations);
++ _obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(_obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, _obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++}
+diff -urN linux-2.4.1/net/korbit/modules/Echo/server/echo.h linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo.h
+--- linux-2.4.1/net/korbit/modules/Echo/server/echo.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Echo/server/echo.h Thu Feb 1 16:36:57 2001
+@@ -0,0 +1,77 @@
++/*
++ * This file was generated by orbit-idl - DO NOT EDIT!
++ */
++
++#include <glib.h>
++#define ORBIT_IDL_SERIAL 9
++#include <orb/orbit.h>
++
++#ifndef echo_H
++#define echo_H 1
++#ifdef __cplusplus
++extern "C"
++{
++#endif /* __cplusplus */
++
++/** typedefs **/
++#if !defined(ORBIT_DECL_Echo) && !defined(_Echo_defined)
++#define ORBIT_DECL_Echo 1
++#define _Echo_defined 1
++#define Echo__free CORBA_Object__free
++ typedef CORBA_Object Echo;
++ extern CORBA_unsigned_long Echo__classid;
++#if !defined(TC_IMPL_TC_Echo_0)
++#define TC_IMPL_TC_Echo_0 'e'
++#define TC_IMPL_TC_Echo_1 'c'
++#define TC_IMPL_TC_Echo_2 'h'
++#define TC_IMPL_TC_Echo_3 'o'
++ extern const struct CORBA_TypeCode_struct TC_Echo_struct;
++#define TC_Echo ((CORBA_TypeCode)&TC_Echo_struct)
++#endif
++#endif
++
++/** POA structures **/
++ typedef struct
++ {
++ void *_private;
++
++ Echo(*echoString) (PortableServer_Servant _servant,
++ const CORBA_char * astring, CORBA_long * anum,
++ CORBA_Environment * ev);
++ }
++ POA_Echo__epv;
++ typedef struct
++ {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_Echo__epv *Echo_epv;
++ }
++ POA_Echo__vepv;
++ typedef struct
++ {
++ void *_private;
++ POA_Echo__vepv *vepv;
++ }
++ POA_Echo;
++ extern void POA_Echo__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++ extern void POA_Echo__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++
++/** prototypes **/
++ Echo Echo_echoString(Echo _obj, const CORBA_char * astring,
++ CORBA_long * anum, CORBA_Environment * ev);
++
++ void _ORBIT_skel_Echo_echoString(POA_Echo * _ORBIT_servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment * ev,
++ Echo(*_impl_echoString)
++ (PortableServer_Servant _servant,
++ const CORBA_char * astring,
++ CORBA_long * anum,
++ CORBA_Environment * ev));
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif
++#undef ORBIT_IDL_SERIAL
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/FileServer/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Entries Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,4 @@
++/FileServer.idl/1.3/Thu Feb 1 09:47:07 2001//
++/Makefile/1.2/Thu Feb 1 09:47:07 2001//
++/README/1.1/Thu Feb 1 09:47:07 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/FileServer/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Entries.Log Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,4 @@
++A D/client////
++A D/server////
++A D/server-user////
++A D/wrapper////
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/FileServer/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Repository Thu Feb 1 11:47:07 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/FileServer
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/CVS/Root linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Root
+--- linux-2.4.1/net/korbit/modules/FileServer/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/CVS/Root Thu Feb 1 11:47:07 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/FileServer.idl linux-2.4.1-korbit/net/korbit/modules/FileServer/FileServer.idl
+--- linux-2.4.1/net/korbit/modules/FileServer/FileServer.idl Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/FileServer.idl Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,158 @@
++// -----------------------------------------------------------------------------
++// FileServer.idl
++// -----------------------------------------------------------------------------
++//
++// This file is used to define the Kernel CORBA API for accessing the filesystem
++// on a machine. This defines mappings both to access the files in the kernel
++// and to implement a filesystem for the kernel. This should probably be split
++// into two files eventually.
++//
++// Currently unimplemented: KernelAccessAPI::FileSystem::ReadDirectory
++// KernelAccessAPI::FileSystem::Select
++// KernelImplementationAPI::SuperBlock::getDiskQuotaOps
++//
++// -----------------------------------------------------------------------------
++
++
++// These are the exceptions that may be thrown and what they map to in the
++// Linux kernel. This interface is extended by other interfaces so that the
++// names don't have to be typedef'd into each interface that wants to use these
++// errors.
++//
++interface Errors {
++ exception IsDirectory {}; // EISDIR
++ exception PermissionDenied {}; // EACCES
++ exception FileExists {}; // EEXIST
++ exception FileNotFound {}; // ENOENT
++ exception IsNotDirectory {}; // ENOTDIR
++ exception ReadOnlyFile {}; // EROFS, ETXTBSY
++ exception RecursiveSymlink {}; // ELOOP
++ exception IsBusy {}; // EBUSY
++ exception OtherError{}; // Misc other ones...
++};
++
++
++// -----------------------------------------------------------------------------
++// KernelAccessAPI Module - Allow user level programs to call into the kernel
++// -----------------------------------------------------------------------------
++
++module FileServer {
++ struct FileStatus { // Corba equilivant of struct stat
++ long DeviceNum; // st_dev
++ long InodeNum; // st_ino
++ short Mode; // st_mode
++ short NumLinks; // st_nlink
++ long UserID; // st_uid
++ long GroupID; // st_gid
++ long DeviceType; // st_rdev
++ unsigned long Size; // st_size
++ unsigned long BlockSize; // st_blksize
++ unsigned long NumBlocks; // st_blocks;
++ unsigned long AccessTime; // st_blocks;
++ unsigned long ModifiedTime; // st_blocks;
++ unsigned long ChangeTime; // st_blocks;
++ };
++
++ typedef sequence<octet> buffer;
++
++ // ---------------------------------------------------------------------------
++ // FileSystem Interface - Access to filesystem and File object factory
++ // ---------------------------------------------------------------------------
++
++ interface File : Errors {
++ void Read(in long count, out buffer buf)
++ raises (IsDirectory, OtherError);
++ void Write(in buffer buf)
++ raises (OtherError);
++ void Close();
++
++ long FileControl(in long command) raises (OtherError);
++
++ FileStatus GetStatus() raises (OtherError);
++
++ void ChangeDirectoryTo() // This implements fchdir...
++ raises (IsNotDirectory, PermissionDenied, OtherError);
++
++ enum SeekDirection { FromStart, FromCurrent, FromEnd };
++ long Seek(in long Offset, in SeekDirection Direction) raises (OtherError);
++
++ File Duplicate() raises (OtherError);
++ };
++
++
++
++ // ---------------------------------------------------------------------------
++ // FileSystem Interface - Access to filesystem and File object factory
++ // ---------------------------------------------------------------------------
++
++ interface FileSystem : Errors {
++
++ // -------------------------------------------------------------------------
++ // File Manipulation Routines
++ // -------------------------------------------------------------------------
++
++ File Open(in string Filename, in long openFlags, in short mode)
++ raises (FileExists, IsDirectory, PermissionDenied, FileNotFound,
++ IsNotDirectory, ReadOnlyFile, RecursiveSymlink, OtherError);
++
++ File Create(in string Filename, in short mode)
++ raises (FileExists, IsDirectory, PermissionDenied, FileNotFound,
++ IsNotDirectory, ReadOnlyFile, RecursiveSymlink, OtherError);
++
++ void Link(in string FromPath, in string ToPath)
++ raises (PermissionDenied, IsNotDirectory, RecursiveSymlink, FileExists);
++
++ void Unlink(in string Filename)
++ raises (PermissionDenied, FileNotFound, IsNotDirectory, IsDirectory);
++
++ void Rename(in string OldName, in string NewName)
++ raises (IsDirectory, FileExists, IsBusy, IsNotDirectory, PermissionDenied,
++ RecursiveSymlink);
++
++ void ReadLink(in string Linkname, out string LinkValue)
++ raises (FileNotFound, PermissionDenied, RecursiveSymlink, OtherError);
++
++
++ FileStatus GetStatus(in string Filename)
++ raises (FileNotFound, PermissionDenied, RecursiveSymlink, IsNotDirectory,
++ OtherError);
++
++ FileStatus GetLinkStatus(in string Filename)
++ raises (FileNotFound, PermissionDenied, RecursiveSymlink, IsNotDirectory,
++ OtherError);
++
++
++ // -------------------------------------------------------------------------
++ // Directory Manipulation Routines
++ // -------------------------------------------------------------------------
++
++ void MakeDirectory(in string PathName, in short mode)
++ raises (FileExists, PermissionDenied, FileNotFound, IsNotDirectory,
++ ReadOnlyFile, RecursiveSymlink, OtherError);
++
++ void RemoveDirectory(in string PathName)
++ raises (PermissionDenied, FileNotFound, IsNotDirectory);
++
++ // ChangeDirectory returns CWD so that you can implement getcwd as
++ // { return ChangeDirectory("."); }
++ string ChangeDirectory(in string PathName)
++ raises (IsNotDirectory, PermissionDenied, FileNotFound, RecursiveSymlink);
++
++
++ // -------------------------------------------------------------------------
++ // Special Purpose Routines...
++ // -------------------------------------------------------------------------
++
++ void MakeNode(in string FileName, in short Mode, in long DeviceNum)
++ raises (PermissionDenied, FileExists, FileNotFound, IsNotDirectory,
++ RecursiveSymlink);
++
++ void Mount(in string DeviceFile, in string Location, in string FSType,
++ in long Flags)
++ raises (PermissionDenied, FileNotFound, IsBusy, IsNotDirectory);
++
++ void Unmount(in string Filename)
++ raises (PermissionDenied, FileNotFound, IsBusy);
++ };
++
++};
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/Makefile linux-2.4.1-korbit/net/korbit/modules/FileServer/Makefile
+--- linux-2.4.1/net/korbit/modules/FileServer/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/Makefile Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,11 @@
++#
++# Makefile for KORBit/modules/CorbaFS
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_FILESERVER) := server
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/README linux-2.4.1-korbit/net/korbit/modules/FileServer/README
+--- linux-2.4.1/net/korbit/modules/FileServer/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/README Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,8 @@
++This interface lets you export file related syscalls through CORBA. This is
++genuinely useful, however, when you use the 'wrapper' library, that can be
++LD_PRELOADED before you run your application. This allows you to forward
++filesystem calls through CORBA without having to modify your application.
++
++Being able to forward filesystem calls though CORBA, of course, means that
++you can attach to any remote machine you want. :)
++
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Entries Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,4 @@
++/FileServer-client.cpp/1.1/Thu Feb 1 09:47:07 2001//
++/Makefile/1.1/Thu Feb 1 09:47:07 2001//
++/README/1.1/Thu Feb 1 09:47:07 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Repository Thu Feb 1 11:47:07 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/FileServer/client
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Root linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Root
+--- linux-2.4.1/net/korbit/modules/FileServer/client/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/CVS/Root Thu Feb 1 11:47:07 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/FileServer-client.cpp linux-2.4.1-korbit/net/korbit/modules/FileServer/client/FileServer-client.cpp
+--- linux-2.4.1/net/korbit/modules/FileServer/client/FileServer-client.cpp Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/FileServer-client.cpp Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,78 @@
++#include <OB/CORBA.h>
++#include <OB/Util.h>
++#include <OB/CosNaming.h>
++#include <stdlib.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++
++#include "FileServer.h"
++
++int main(int argc, char* argv[])
++{
++ if (argc < 3)
++ {
++ cout << "Usage : " << argv[0] << " ior filename" << endl;
++ exit(1);
++ }
++
++ cout << "FileServer client initializing" << endl;
++
++ CORBA_ORB_var orb = CORBA_ORB_init(argc, argv);
++ cout << "ORB initialized" << endl;
++
++ try
++ {
++ CORBA_Object_var obj = orb->string_to_object( argv[1] );
++ assert(!CORBA_is_nil(obj));
++ cout << "got object... " << orb->object_to_string(obj) << endl;
++
++ FileServer_FileSystem_var fs = FileServer_FileSystem::_narrow(obj);
++ assert(!CORBA_is_nil(fs));
++ cout << "it's a FileServer!" << endl;
++
++ obj = fs->Open(argv[2], O_RDONLY, 0);
++ assert(!CORBA_is_nil(obj));
++ cout << "got object... " << orb->object_to_string(obj) << endl;
++
++ FileServer_File_var file = FileServer_File::_narrow(obj);
++ assert(!CORBA_is_nil(file));
++ cout << "it's a FileServer_File!" << endl;
++
++ FileServer_buffer *buf = new FileServer_buffer;
++ cout << "reading 1000 bytes" << endl;
++ file->Read(1000, buf);
++
++ cout << "got " << buf->length() << " bytes" << endl;
++ cout << buf->data() << endl;
++
++ file->Close();
++
++ delete buf;
++ }
++ catch (const CORBA_SystemException& ex) {
++ OBPrintException(ex);
++ return 1;
++ }
++ catch (const Errors::FileNotFound& ex) {
++ cout << "ERROR : File not found" << endl;
++ return 1;
++ }
++ catch (const Errors::PermissionDenied& ex) {
++ cout << "ERROR : Permission denied" << endl;
++ return 1;
++ }
++ catch (const Errors::IsDirectory& ex) {
++ cout << "ERROR : Is directory" << endl;
++ return 1;
++ }
++ catch (const Errors::OtherError& ex) {
++ cout << "ERROR : Other error" << endl;
++ return 1;
++ }
++ catch (const CORBA_UserException& ex)
++ {
++ cout << "ERROR : Uncaught exception" << endl;
++ return 1;
++ }
++}
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/Makefile linux-2.4.1-korbit/net/korbit/modules/FileServer/client/Makefile
+--- linux-2.4.1/net/korbit/modules/FileServer/client/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/Makefile Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,32 @@
++CC = CC -mt -pta
++OBDIR = /home/class/cs423/local
++IDL = $(OBDIR)/bin/idl
++CPPFLAGS = -I. -I$(OBDIR)/include
++LDFLAGS = -L$(OBDIR)/lib
++LIBS = -lCosNaming -lOB -lJTC -lsocket -lnsl -lposix4
++
++all: FileServer-client
++
++FileServer-client: FileServer.o FileServer-client.o
++ $(CC) $(LDFLAGS) -o FileServer-client FileServer-client.o FileServer.o $(LIBS)
++
++nameserv:
++ nameserv -i -OAport 10000
++
++FileServer.h FileServer.cpp: ../FileServer.idl
++ rm -f FileServer.cpp FileServer.h
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ $(IDL) ../FileServer.idl
++
++FileServer_skel.cpp FileServer_skel.h: FileServer.cpp
++
++%.o: %.cpp
++ $(CC) $(CPPFLAGS) -c $<
++
++clean:
++ rm -f FileServer-client *.o *~
++
++realclean: clean
++ rm -f FileServer.h FileServer.cpp
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ rm -rf SunWS_cache
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/client/README linux-2.4.1-korbit/net/korbit/modules/FileServer/client/README
+--- linux-2.4.1/net/korbit/modules/FileServer/client/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/client/README Thu Feb 1 11:47:07 2001
+@@ -0,0 +1,4 @@
++Very minimal test of the FileServer capability.
++
++ORB: Orbacus
++
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Entries Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,6 @@
++/FileServer-server.c/1.2/Thu Feb 1 09:47:08 2001//
++/FileServer-skelimpl.c/1.8/Thu Feb 1 09:47:08 2001//
++/Makefile/1.3/Thu Feb 1 09:47:08 2001//
++/Makefile.user/1.4/Thu Feb 1 09:47:08 2001//
++/README/1.1/Thu Feb 1 09:47:08 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Repository Thu Feb 1 11:47:08 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/FileServer/server
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Root linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Root
+--- linux-2.4.1/net/korbit/modules/FileServer/server/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/CVS/Root Thu Feb 1 11:47:08 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/FileServer-server.c linux-2.4.1-korbit/net/korbit/modules/FileServer/server/FileServer-server.c
+--- linux-2.4.1/net/korbit/modules/FileServer/server/FileServer-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/FileServer-server.c Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,57 @@
++#include <stdio.h>
++#include "FileServer-skelimpl.c"
++#include "korbit.h"
++
++CORBA_ORB orb;
++PortableServer_POA poa;
++CORBA_Environment *ev;
++PortableServer_ObjectId *objid;
++
++#ifdef __KERNEL__
++int __init FileServer_init(void) {
++#else
++int main(int argc, char *argv[]) {
++#endif
++ FileServer_FileSystem fs;
++ impl_POA_FileServer_FileSystem *fs_impl;
++
++ PortableServer_POAManager pm;
++#ifdef __KERNEL__
++ int argc = 1;
++ char *argv[] = { "server", 0 };
++#endif
++ ev = g_new0(CORBA_Environment,1);
++
++ CORBA_exception_init(ev);
++
++ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
++ poa = (PortableServer_POA)
++ CORBA_ORB_resolve_initial_references(orb,
++ "RootPOA",
++ ev);
++ fs = impl_FileServer_FileSystem__create(poa, ev);
++
++ pm = PortableServer_POA__get_the_POAManager(poa, ev);
++ PortableServer_POAManager_activate(pm, ev);
++
++ fs_impl = PortableServer_POA_reference_to_servant( poa, fs, ev );
++ objid = PortableServer_POA_servant_to_id( poa, fs_impl, ev );
++
++ korbit_register_ior("FileServer-server", fs, orb, ev);
++
++ CORBA_ORB_run(orb, ev);
++
++ return 0;
++}
++
++#ifdef __KERNEL__
++void FileServer_exit(void)
++{
++ PortableServer_POA_deactivate_object(poa, objid, ev);
++ remove_proc_entry("corba/FileServer-server", 0);
++ printf("FileServer_exit()\n");
++}
++
++module_init(FileServer_init)
++module_exit(FileServer_exit)
++#endif
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/FileServer-skelimpl.c linux-2.4.1-korbit/net/korbit/modules/FileServer/server/FileServer-skelimpl.c
+--- linux-2.4.1/net/korbit/modules/FileServer/server/FileServer-skelimpl.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/FileServer-skelimpl.c Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,804 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <errno.h>
++
++#include "FileServer.h"
++
++static void set_exception(int errno, CORBA_Environment *ev)
++{
++ switch (errno)
++ {
++ case ENOENT:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_FileNotFound,
++ Errors_FileNotFound__alloc());
++ break;
++ case EEXIST:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_FileExists,
++ Errors_FileExists__alloc());
++ break;
++ case EACCES:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_PermissionDenied,
++ Errors_PermissionDenied__alloc());
++ break;
++ case EISDIR:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_IsDirectory,
++ Errors_IsDirectory__alloc());
++ break;
++ case ENOTDIR:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_IsNotDirectory,
++ Errors_IsNotDirectory__alloc());
++ break;
++ case EROFS:
++ case ETXTBSY:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_ReadOnlyFile,
++ Errors_ReadOnlyFile__alloc());
++ break;
++ case ELOOP:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_RecursiveSymlink,
++ Errors_RecursiveSymlink__alloc());
++ break;
++ case EBUSY:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_IsBusy,
++ Errors_IsBusy__alloc());
++ break;
++ default:
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_Errors_OtherError,
++ Errors_OtherError__alloc());
++ break;
++ }
++}
++
++
++/*** App-specific servant structures ***/
++typedef struct
++{
++ POA_Errors servant;
++ PortableServer_POA poa;
++
++}
++impl_POA_Errors;
++
++typedef struct
++{
++ POA_FileServer_File servant;
++ PortableServer_POA poa;
++
++ int fd;
++}
++impl_POA_FileServer_File;
++
++typedef struct
++{
++ POA_FileServer_FileSystem servant;
++ PortableServer_POA poa;
++
++}
++impl_POA_FileServer_FileSystem;
++
++/*** Implementation stub prototypes ***/
++static void impl_Errors__destroy(impl_POA_Errors * servant,
++ CORBA_Environment * ev);
++
++static void impl_FileServer_File__destroy(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev);
++static void
++impl_FileServer_File_Read(impl_POA_FileServer_File * servant,
++ CORBA_long count,
++ FileServer_buffer ** buf, CORBA_Environment * ev);
++
++static void
++impl_FileServer_File_Write(impl_POA_FileServer_File * servant,
++ FileServer_buffer * buf, CORBA_Environment * ev);
++
++static void
++impl_FileServer_File_Close(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev);
++
++static CORBA_long
++impl_FileServer_File_FileControl(impl_POA_FileServer_File * servant,
++ CORBA_long command, CORBA_Environment * ev);
++
++static FileServer_FileStatus
++impl_FileServer_File_GetStatus(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_File_ChangeDirectoryTo(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev);
++
++static CORBA_long
++impl_FileServer_File_Seek(impl_POA_FileServer_File * servant,
++ CORBA_long Offset,
++ FileServer_File_SeekDirection Direction,
++ CORBA_Environment * ev);
++
++static FileServer_File
++impl_FileServer_File_Duplicate(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev);
++
++static void impl_FileServer_FileSystem__destroy(impl_POA_FileServer_FileSystem
++ * servant,
++
++ CORBA_Environment * ev);
++static FileServer_File
++impl_FileServer_FileSystem_Open(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename, CORBA_long openFlags,
++ CORBA_short mode, CORBA_Environment * ev);
++
++static FileServer_File
++impl_FileServer_FileSystem_Create(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_short mode, CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_Link(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * FromPath,
++ CORBA_char * ToPath, CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_Unlink(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_Rename(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * OldName,
++ CORBA_char * NewName,
++
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_ReadLink(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Linkname,
++ CORBA_char ** LinkValue,
++ CORBA_Environment * ev);
++
++static FileServer_FileStatus
++impl_FileServer_FileSystem_GetStatus(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_Environment * ev);
++
++static FileServer_FileStatus
++impl_FileServer_FileSystem_GetLinkStatus(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * Filename,
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_MakeDirectory(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * PathName,
++ CORBA_short mode,
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_RemoveDirectory(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * PathName,
++ CORBA_Environment * ev);
++
++static CORBA_char
++ *impl_FileServer_FileSystem_ChangeDirectory(impl_POA_FileServer_FileSystem
++ * servant,
++ CORBA_char * PathName,
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_MakeNode(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * FileName,
++ CORBA_short Mode,
++ CORBA_long DeviceNum,
++
++ CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_Mount(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * DeviceFile,
++ CORBA_char * Location,
++ CORBA_char * FSType,
++ CORBA_long Flags, CORBA_Environment * ev);
++
++static void
++impl_FileServer_FileSystem_Unmount(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++
++ CORBA_Environment * ev);
++
++/*** epv structures ***/
++static PortableServer_ServantBase__epv impl_Errors_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_Errors__epv impl_Errors_epv = {
++ NULL, /* _private */
++
++};
++
++static PortableServer_ServantBase__epv impl_FileServer_File_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_FileServer_File__epv impl_FileServer_File_epv = {
++ NULL, /* _private */
++ (gpointer) & impl_FileServer_File_Read,
++
++ (gpointer) & impl_FileServer_File_Write,
++
++ (gpointer) & impl_FileServer_File_Close,
++
++ (gpointer) & impl_FileServer_File_FileControl,
++
++ (gpointer) & impl_FileServer_File_GetStatus,
++
++ (gpointer) & impl_FileServer_File_ChangeDirectoryTo,
++
++ (gpointer) & impl_FileServer_File_Seek,
++
++ (gpointer) & impl_FileServer_File_Duplicate,
++
++};
++static POA_Errors__epv impl_FileServer_File_Errors_epv = {
++ NULL, /* _private */
++};
++static PortableServer_ServantBase__epv impl_FileServer_FileSystem_base_epv = {
++ NULL, /* _private data */
++ NULL, /* finalize routine */
++ NULL, /* default_POA routine */
++};
++static POA_FileServer_FileSystem__epv impl_FileServer_FileSystem_epv = {
++ NULL, /* _private */
++ (gpointer) & impl_FileServer_FileSystem_Open,
++
++ (gpointer) & impl_FileServer_FileSystem_Create,
++
++ (gpointer) & impl_FileServer_FileSystem_Link,
++
++ (gpointer) & impl_FileServer_FileSystem_Unlink,
++
++ (gpointer) & impl_FileServer_FileSystem_Rename,
++
++ (gpointer) & impl_FileServer_FileSystem_ReadLink,
++
++ (gpointer) & impl_FileServer_FileSystem_GetStatus,
++
++ (gpointer) & impl_FileServer_FileSystem_GetLinkStatus,
++
++ (gpointer) & impl_FileServer_FileSystem_MakeDirectory,
++
++ (gpointer) & impl_FileServer_FileSystem_RemoveDirectory,
++
++ (gpointer) & impl_FileServer_FileSystem_ChangeDirectory,
++
++ (gpointer) & impl_FileServer_FileSystem_MakeNode,
++
++ (gpointer) & impl_FileServer_FileSystem_Mount,
++
++ (gpointer) & impl_FileServer_FileSystem_Unmount,
++
++};
++static POA_Errors__epv impl_FileServer_FileSystem_Errors_epv = {
++ NULL, /* _private */
++};
++
++/*** vepv structures ***/
++static POA_Errors__vepv impl_Errors_vepv = {
++ &impl_Errors_base_epv,
++ &impl_Errors_epv,
++};
++
++static POA_FileServer_File__vepv impl_FileServer_File_vepv = {
++ &impl_FileServer_File_base_epv,
++ &impl_FileServer_File_Errors_epv,
++ &impl_FileServer_File_epv,
++};
++static POA_FileServer_FileSystem__vepv impl_FileServer_FileSystem_vepv = {
++ &impl_FileServer_FileSystem_base_epv,
++ &impl_FileServer_FileSystem_Errors_epv,
++ &impl_FileServer_FileSystem_epv,
++};
++
++/*** Stub implementations ***/
++static Errors
++impl_Errors__create(PortableServer_POA poa, CORBA_Environment * ev)
++{
++ Errors retval;
++ impl_POA_Errors *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_Errors, 1);
++ newservant->servant.vepv = &impl_Errors_vepv;
++ newservant->poa = poa;
++ POA_Errors__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static void
++impl_Errors__destroy(impl_POA_Errors * servant, CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_Errors__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static FileServer_File
++impl_FileServer_File__create(PortableServer_POA poa, CORBA_Environment * ev)
++{
++ FileServer_File retval;
++ impl_POA_FileServer_File *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_FileServer_File, 1);
++ newservant->servant.vepv = &impl_FileServer_File_vepv;
++ newservant->poa = poa;
++ newservant->fd = -1;
++
++ POA_FileServer_File__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static void
++impl_FileServer_File__destroy(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_FileServer_File__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static void
++impl_FileServer_File_Read(impl_POA_FileServer_File * servant,
++ CORBA_long count,
++ FileServer_buffer ** buf, CORBA_Environment * ev)
++{
++ size_t num_read;
++
++ *buf = FileServer_buffer__alloc();
++ (*buf)->_maximum = count;
++ (*buf)->_buffer = CORBA_octet_allocbuf(count);
++ (*buf)->_length = 0;
++
++ printf("File->Read(%d, char *buf)\n", count);
++
++ if (servant->fd == -1) /* Trying to read from a closed file */
++ {
++ printf("File->Read ERROR : fd == -1\n");
++ set_exception(EBADF, ev);
++ return;
++ }
++
++ num_read = read(servant->fd, (*buf)->_buffer, count);
++ if (num_read == -1)
++ {
++ printf("File->Read ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ return;
++ }
++
++ (*buf)->_length = num_read;
++}
++
++static void
++impl_FileServer_File_Write(impl_POA_FileServer_File * servant,
++ FileServer_buffer * buf, CORBA_Environment * ev)
++{
++ printf("UNIMP: FileServer::File::Write called and unimplemented\n");
++}
++
++static void
++impl_FileServer_File_Close(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev)
++{
++ printf("File->Close()\n");
++
++ if (servant->fd == -1) /* This should never happen !?! */
++ {
++ printf("File->Close ERROR : fd == -1\n");
++ set_exception(EBADF, ev);
++ return;
++ }
++
++ close(servant->fd);
++ servant->fd = 0;
++ impl_FileServer_File__destroy(servant, ev);
++}
++
++static CORBA_long
++impl_FileServer_File_FileControl(impl_POA_FileServer_File * servant,
++ CORBA_long command, CORBA_Environment * ev)
++{
++ CORBA_long retval;
++
++ if (servant->fd == -1)
++ {
++ printf("File->FileControl ERROR : fd == -1\n");
++ set_exception(EBADF, ev);
++ return -1;
++ }
++
++ retval = fcntl(servant->fd, command, 0); /* FIXME arg? */
++ if (retval == -1)
++ {
++ printf("File->FileControl ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ }
++
++ return retval;
++}
++
++
++FileServer_FileStatus
++stat2FileStatus(struct stat buf)
++{
++ FileServer_FileStatus retval;
++
++ retval.DeviceNum = buf.st_dev;
++ retval.InodeNum = buf.st_ino;
++ retval.Mode = buf.st_mode;
++ retval.NumLinks = buf.st_nlink;
++ retval.UserID = buf.st_uid;
++ retval.GroupID = buf.st_gid;
++ retval.DeviceType = buf.st_rdev;
++ retval.Size = buf.st_size;
++ retval.BlockSize = buf.st_blksize;
++ retval.NumBlocks = buf.st_blocks;
++ retval.AccessTime = buf.st_atime;
++ retval.ModifiedTime = buf.st_mtime;
++ retval.ChangeTime = buf.st_ctime;
++
++ return retval;
++}
++
++
++static FileServer_FileStatus
++impl_FileServer_File_GetStatus(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev)
++{
++ FileServer_FileStatus retval;
++
++ struct stat buf;
++ int res;
++
++ if (servant->fd == -1)
++ {
++ printf("File->GetStatus ERROR : fd == -1\n");
++ set_exception(EBADF, ev);
++ return retval;
++ }
++
++ res = fstat(servant->fd, &buf);
++ if (res == -1)
++ {
++ printf("File->GetStatus ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ return retval;
++ }
++
++ retval = stat2FileStatus(buf);
++
++ return retval;
++}
++
++static void
++impl_FileServer_File_ChangeDirectoryTo(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_File_ChangeDirectoryTo\n");
++}
++
++static CORBA_long
++impl_FileServer_File_Seek(impl_POA_FileServer_File * servant,
++ CORBA_long Offset,
++ FileServer_File_SeekDirection Direction,
++ CORBA_Environment * ev)
++{
++ CORBA_long retval = -1;
++ int whence;
++
++ if (servant->fd == -1)
++ {
++ printf("File->Seek ERROR : fd == -1\n");
++ set_exception(EBADF, ev);
++ return retval;
++ }
++
++ switch (Direction)
++ {
++ case FileServer_File_FromStart :
++ whence = SEEK_SET;
++ break;
++ case FileServer_File_FromCurrent :
++ whence = SEEK_CUR;
++ break;
++ case FileServer_File_FromEnd :
++ whence = SEEK_END;
++ break;
++ default :
++ set_exception(EINVAL, ev);
++ return retval;
++ }
++
++ retval = lseek(servant->fd, Offset, whence);
++ if (retval == -1)
++ {
++ printf("File->Seek ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ }
++
++ return retval;
++}
++
++static FileServer_File
++impl_FileServer_File_Duplicate(impl_POA_FileServer_File * servant,
++ CORBA_Environment * ev)
++{
++ FileServer_File retval;
++ printf("UNIMP: impl_FileServer_File_Duplicate\n");
++ return retval;
++}
++
++static FileServer_FileSystem
++impl_FileServer_FileSystem__create(PortableServer_POA poa,
++ CORBA_Environment * ev)
++{
++ FileServer_FileSystem retval;
++ impl_POA_FileServer_FileSystem *newservant;
++ PortableServer_ObjectId *objid;
++
++ newservant = g_new0(impl_POA_FileServer_FileSystem, 1);
++ newservant->servant.vepv = &impl_FileServer_FileSystem_vepv;
++ newservant->poa = poa;
++ POA_FileServer_FileSystem__init((PortableServer_Servant) newservant, ev);
++ objid = PortableServer_POA_activate_object(poa, newservant, ev);
++ CORBA_free(objid);
++ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
++
++ return retval;
++}
++
++static void
++impl_FileServer_FileSystem__destroy(impl_POA_FileServer_FileSystem * servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ObjectId *objid;
++
++ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
++ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
++ CORBA_free(objid);
++
++ POA_FileServer_FileSystem__fini((PortableServer_Servant) servant, ev);
++ g_free(servant);
++}
++
++static FileServer_File
++impl_FileServer_FileSystem_Open(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_long openFlags,
++ CORBA_short mode, CORBA_Environment * ev)
++{
++ FileServer_File retval = CORBA_OBJECT_NIL;
++
++ impl_POA_FileServer_File *file;
++
++ printf("FileSystem->Open(%s,%x)\n", Filename, openFlags);
++
++ retval = impl_FileServer_File__create(servant->poa, ev);
++
++ file = PortableServer_POA_reference_to_servant( servant->poa, retval, ev );
++ file->fd = open(Filename, openFlags, mode);
++
++ if (file->fd == -1) {
++ printf("FileSystem->Open ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ }
++
++ return retval;
++}
++
++static FileServer_File
++impl_FileServer_FileSystem_Create(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_short mode, CORBA_Environment * ev)
++{
++ FileServer_File retval = CORBA_OBJECT_NIL;
++
++ impl_POA_FileServer_File *file;
++
++ printf("FileSystem->Create(%s,%x)\n", Filename, mode);
++
++ retval = impl_FileServer_File__create(servant->poa, ev);
++
++ file = PortableServer_POA_reference_to_servant( servant->poa, retval, ev );
++ file->fd = creat(Filename, mode);
++
++ if (file->fd == -1) {
++ printf("FileSystem->Create ERROR : %d\n", errno);
++ set_exception(errno, ev);
++ }
++
++ return retval;
++}
++
++static void
++impl_FileServer_FileSystem_Link(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * FromPath,
++ CORBA_char * ToPath, CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_Link\n");
++}
++
++static void
++impl_FileServer_FileSystem_Unlink(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_Unlink\n");
++}
++
++static void
++impl_FileServer_FileSystem_Rename(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * OldName,
++ CORBA_char * NewName,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_Rename\n");
++}
++
++static void
++impl_FileServer_FileSystem_ReadLink(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Linkname,
++ CORBA_char ** LinkValue,
++ CORBA_Environment * ev)
++{
++ char tmp[PATH_MAX + 1];
++ int res, len;
++
++ printf("FileSystem->ReadLink(%s, value)\n", Linkname);
++
++ res = readlink(Linkname, tmp, PATH_MAX);
++ if (res == -1)
++ {
++ set_exception(errno, ev);
++ return;
++ }
++
++ len = strlen(tmp);
++ *LinkValue = (char *)malloc(len * sizeof(char));
++ memcpy(*LinkValue, tmp, len);
++ (*LinkValue)[len] = '\0';
++}
++
++static FileServer_FileStatus
++impl_FileServer_FileSystem_GetStatus(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_Environment * ev)
++{
++ FileServer_FileStatus retval;
++ struct stat buf;
++ int res;
++
++ printf("FileSystem->GetStatus(%s)\n", Filename);
++
++ res = stat(Filename, &buf);
++
++ if (res == -1)
++ {
++ printf("FileSystem->GetStatus(%s)\n", Filename);
++ set_exception(errno, ev);
++ return retval;
++ }
++
++ retval = stat2FileStatus(buf);
++
++ return retval;
++}
++
++static FileServer_FileStatus
++impl_FileServer_FileSystem_GetLinkStatus(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * Filename,
++ CORBA_Environment * ev)
++{
++ FileServer_FileStatus retval;
++ struct stat buf;
++ int res;
++
++ printf("FileSystem->GetLinkStatus(%s)\n", Filename);
++
++ res = lstat(Filename, &buf);
++
++ if (res == -1)
++ {
++ printf("FileSystem->GetLinkStatus(%s)\n", Filename);
++ set_exception(errno, ev);
++ return retval;
++ }
++
++ retval = stat2FileStatus(buf);
++
++ return retval;
++}
++
++static void
++impl_FileServer_FileSystem_MakeDirectory(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * PathName,
++ CORBA_short mode,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_MakeDirectory\n");
++}
++
++static void
++impl_FileServer_FileSystem_RemoveDirectory(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * PathName,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_RemoveDirectory\n");
++}
++
++static CORBA_char *
++impl_FileServer_FileSystem_ChangeDirectory(impl_POA_FileServer_FileSystem *
++ servant, CORBA_char * PathName,
++ CORBA_Environment * ev)
++{
++ CORBA_char *retval;
++ printf("UNIMP: impl_FileServer_FileSystem_ChangeDirectory\n");
++ return retval;
++}
++
++static void
++impl_FileServer_FileSystem_MakeNode(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * FileName,
++ CORBA_short Mode,
++ CORBA_long DeviceNum,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_MakeNode\n");
++}
++
++static void
++impl_FileServer_FileSystem_Mount(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * DeviceFile,
++ CORBA_char * Location,
++ CORBA_char * FSType,
++ CORBA_long Flags, CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_Mount: ARE YOU CRAZY!?!?\n");
++}
++
++static void
++impl_FileServer_FileSystem_Unmount(impl_POA_FileServer_FileSystem * servant,
++ CORBA_char * Filename,
++ CORBA_Environment * ev)
++{
++ printf("UNIMP: impl_FileServer_FileSystem_Unmount: Ha ha ha funny guy!\n");
++}
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/Makefile linux-2.4.1-korbit/net/korbit/modules/FileServer/server/Makefile
+--- linux-2.4.1/net/korbit/modules/FileServer/server/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/Makefile Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,20 @@
++#
++# Makefile for KORBit / FileServer
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := corba-fileserver-server.o
++
++obj-y := FileServer-common.o FileServer-skels.o FileServer-server.o
++obj-m := $(O_TARGET)
++
++include ../../Makefile.module
++
++FileServer-server.c: FileServer.h FileServer-common.c FileServer-skels.c FileServer-skelimpl.c
++
++FileServer.h FileServer-skels.c FileServer-common.c: ../FileServer.idl
++ $(ORBIT_IDL) ../FileServer.idl
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/Makefile.user linux-2.4.1-korbit/net/korbit/modules/FileServer/server/Makefile.user
+--- linux-2.4.1/net/korbit/modules/FileServer/server/Makefile.user Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/Makefile.user Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,32 @@
++#
++# Makefile for KORBit
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++PROJECT = FileServer
++
++CFLAGS = -Wall `orbit-config --cflags server` -I../../..
++LDFLAGS = `orbit-config --libs server`
++OBJS = $(PROJECT)-common.o $(PROJECT)-skels.o $(PROJECT)-server.o
++ORBIT-IDL = orbit-idl
++
++$(PROJECT)-server: $(OBJS)
++ gcc -o $(PROJECT)-server $(OBJS) $(LDFLAGS)
++
++$(PROJECT)-server.c: $(PROJECT).h $(PROJECT)-skelimpl.c
++
++$(PROJECT).h $(PROJECT)-common.c $(PROJECT)-skels.c $(PROJECT)-skelimpl.c: ../$(PROJECT).idl
++ $(ORBIT-IDL) --nostubs ../$(PROJECT).idl
++
++clean:
++ rm -f $(OBJS) $(PROJECT)-server
++
++realclean: clean
++ rm -f $(PROJECT).h
++ rm -f $(PROJECT)-common.c
++ rm -f $(PROJECT)-skels.c
++ rm -f *~
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server/README linux-2.4.1-korbit/net/korbit/modules/FileServer/server/README
+--- linux-2.4.1/net/korbit/modules/FileServer/server/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server/README Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,4 @@
++Kernel side implementation of the file server functionality.
++
++ORB: kORBit
++Status: Mostly unimplemented.
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Entries Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,4 @@
++/FileServer-server.c/1.1/Thu Feb 1 09:47:08 2001//
++/Makefile/1.1/Thu Feb 1 09:47:08 2001//
++/README/1.1/Thu Feb 1 09:47:08 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Repository Thu Feb 1 11:47:08 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/FileServer/server-user
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Root linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Root
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/CVS/Root Thu Feb 1 11:47:08 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/FileServer-server.c linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/FileServer-server.c
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/FileServer-server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/FileServer-server.c Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,234 @@
++#include <OB/CORBA.h>
++#include <OB/Util.h>
++#include <OB/CosNaming.h>
++#include <stdlib.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <errno.h>
++
++#include "FileServer_skel.h"
++
++static void ThrowErr() {
++ switch (errno) {
++ case 0: return;
++ case EISDIR:
++ throw Errors::IsDirectory();
++ case EPERM:
++ throw Errors::PermissionDenied();
++ case EEXIST:
++ throw Errors::FileExists();
++ case ENOENT:
++ throw Errors::FileNotFound();
++ case ENOTDIR:
++ throw Errors::IsNotDirectory();
++ case EROFS:
++ case ETXTBSY:
++ throw Errors::ReadOnlyFile();
++ case ELOOP:
++ throw Errors::RecursiveSymlink();
++ case EBUSY:
++ throw Errors::IsBusy();
++ default:
++ throw Errors::OtherError();
++ }
++}
++
++
++class FileServer_File_impl : public FileServer_File_skel {
++ int FD;
++ public:
++ FileServer_File_impl(int fd) { FD = fd; }
++
++ virtual void Read(CORBA_Long count, FileServer_buffer*& buf) {
++ errno = 0;
++ cout << "Read\n";
++ buf = new FileServer_buffer();
++ ThrowErr();
++ }
++
++ virtual void Write(const FileServer_buffer& buf) {
++ errno = 0;
++ cout << "Write\n";
++ ThrowErr();
++ }
++
++ virtual void Close() {
++ errno = 0;
++ close(FD);
++ cout << "Close()\n";
++ ThrowErr();
++ }
++
++ virtual CORBA_Long FileControl(CORBA_Long command) {
++ errno = 0;
++ cout << "filecontrol\n";
++ ThrowErr();
++ return 0;
++ }
++
++ virtual FileServer_FileStatus GetStatus() {
++ errno = 0;
++ cout << "stat\n";
++ FileServer_FileStatus Stat;
++ ThrowErr();
++ return Stat;
++ }
++
++ virtual void ChangeDirectoryTo() {
++ errno = 0;
++ cout << "ChangeDirectoryTo()\n";
++ ThrowErr();
++ }
++
++ virtual CORBA_Long Seek(CORBA_Long Offset, SeekDirection Direction) {
++ errno = 0;
++ cout << "Seek(" << Offset << ")\n";
++ ThrowErr();
++ return -1;
++ }
++
++ virtual FileServer_File_ptr Duplicate() {
++ errno = 0;
++ cout << "Duplicate!\n";
++ ThrowErr();
++ return 0;
++ }
++};
++
++
++class FileServer_impl : public FileServer_FileSystem_skel {
++ public :
++ virtual FileServer_File_ptr Open(const char* Filename,
++ CORBA_Long openFlags,
++ CORBA_Short mode) {
++ errno = 0;
++ int fd = open(Filename, openFlags, mode);
++ if (fd != -1) return new FileServer_File_impl(fd);
++ cout << "open\n";
++ ThrowErr();
++ return 0;
++ }
++
++ virtual FileServer_File_ptr Create(const char* Filename,
++ CORBA_Short mode) {
++ errno = 0;
++ cout << "create\n";
++ ThrowErr();
++ return 0;
++ }
++
++
++ virtual void Link(const char* FromPath,
++ const char* ToPath) {
++ errno = 0;
++ cout << "link\n";
++ ThrowErr();
++ }
++
++ virtual void Unlink(const char* Filename) {
++ errno = 0;
++ cout << "unlink\n";
++ ThrowErr();
++ }
++
++ virtual void Rename(const char* OldName,
++ const char* NewName) {
++ errno = 0;
++ cout << "rename\n";
++ ThrowErr();
++ }
++
++
++ virtual void ReadLink(const char* Linkname,
++ char*& LinkValue) {
++ errno = 0;
++ cout << "readlink\n";
++ ThrowErr();
++ }
++
++ virtual FileServer_FileStatus GetStatus(const char* Filename) {
++ errno = 0;
++ cout << "stat\n";
++ FileServer_FileStatus Stat;
++ ThrowErr();
++ return Stat;
++ }
++
++
++ virtual FileServer_FileStatus GetLinkStatus(const char* Filename) {
++ errno = 0;
++ cout << "lstat\n";
++ FileServer_FileStatus Stat;
++ ThrowErr();
++ return Stat;
++ }
++
++
++ virtual void MakeDirectory(const char* PathName,
++ CORBA_Short mode) {
++ errno = 0;
++ cout << "mkdir\n";
++ ThrowErr();
++ }
++
++ virtual void RemoveDirectory(const char* PathName) {
++ errno = 0;
++ cout << "rmdir\n";
++ ThrowErr();
++ }
++
++
++ virtual char* ChangeDirectory(const char* PathName) {
++ errno = 0;
++ cout << "chdir\n";
++ ThrowErr();
++ return CORBA_string_dup("hello");
++ }
++
++ virtual void MakeNode(const char* FileName,
++ CORBA_Short Mode,
++ CORBA_Long DeviceNum) {
++ errno = 0;
++ cout << "mknod\n";
++ ThrowErr();
++ }
++
++
++ virtual void Mount(const char* DeviceFile,
++ const char* Location,
++ const char* FSType,
++ CORBA_Long Flags) {
++ errno = 0;
++ cout << "Mount\n";
++ ThrowErr();
++ }
++
++ virtual void Unmount(const char* Filename) {
++ errno = 0;
++ cout << "Unmount\n";
++ ThrowErr();
++ }
++};
++
++
++int main(int argc, char* argv[]) {
++ cout << "FileServer UserSpace Server initializing" << endl;
++
++ try {
++ CORBA_ORB_var orb = CORBA_ORB_init(argc, argv);
++ CORBA_BOA_var boa = orb->BOA_init(argc, argv);
++
++ FileServer_FileSystem_var FS = new FileServer_impl();
++
++ cout << orb->object_to_string(FS) << endl;
++
++ //
++ // Run implementation
++ //
++ boa -> impl_is_ready(CORBA_ImplementationDef::_nil());
++ } catch(CORBA_SystemException& ex) {
++ OBPrintException(ex);
++ return 1;
++ }
++}
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/Makefile linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/Makefile
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/Makefile Thu Feb 1 11:47:08 2001
+@@ -0,0 +1,29 @@
++CC = CC -mt -pta
++OBDIR = /home/class/cs423/local
++IDL = $(OBDIR)/bin/idl
++CPPFLAGS = -I. -I$(OBDIR)/include
++LDFLAGS = -L$(OBDIR)/lib
++LIBS = -lCosNaming -lOB -lJTC -lsocket -lnsl -lposix4
++
++all: FileServer
++
++FileServer: FileServer.o FileServer-server.o FileServer_skel.o
++ $(CC) $(LDFLAGS) -o FileServer FileServer-server.o FileServer.o FileServer_skel.o $(LIBS)
++
++FileServer.h FileServer.cpp: ../FileServer.idl
++ rm -f FileServer.cpp FileServer.h
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ $(IDL) ../FileServer.idl
++
++FileServer_skel.cpp FileServer_skel.h: FileServer.cpp
++
++%.o: %.cpp
++ $(CC) $(CPPFLAGS) -c $<
++
++clean:
++ rm -f FileServer *.o *~
++
++realclean: clean
++ rm -f FileServer.h FileServer.cpp
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ rm -rf SunWS_cache
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/server-user/README linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/README
+--- linux-2.4.1/net/korbit/modules/FileServer/server-user/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/server-user/README Thu Feb 1 11:47:08 2001
+@@ -0,0 +1 @@
++This is a user space implementation of the FileServer interface.
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Entries Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,6 @@
++/FileServer_wrapper.cpp/1.2/Thu Feb 1 09:47:09 2001//
++/FileServer_wrapper.h/1.2/Thu Feb 1 09:47:09 2001//
++/Makefile/1.1/Thu Feb 1 09:47:09 2001//
++/README/1.1/Thu Feb 1 09:47:09 2001//
++/test.c/1.2/Thu Feb 1 09:47:09 2001//
++D
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Repository Thu Feb 1 11:47:09 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/FileServer/wrapper
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Root linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Root
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/CVS/Root Thu Feb 1 11:47:09 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.cpp linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.cpp
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.cpp Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.cpp Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,135 @@
++/*
++ * FileServer_wrapper.cpp
++ *
++ * We want to intercept *all* file I/O, so that once the LD_PRELOAD
++ * variable is set, everything you see is on the remote side.
++ *
++ * Needed environment variables:
++ * LD_PRELOAD - duh (what's the lib name?)
++ * KORBIT_IOR - IOR of the file servin' ORB to connect to.
++ *
++ */
++
++#include <stdio.h>
++#include <dlfcn.h>
++#include <stdarg.h>
++#include <stdlib.h>
++#include <string.h>
++#include <dirent.h>
++#include <errno.h>
++
++#include "OB/CORBA.h"
++//#include "OB/Util.h"
++//#include "OB/CosNaming.h"
++
++#include "FileServer.h"
++#include "FileServer_wrapper.h"
++
++#define DEBUG
++
++#ifdef DEBUG
++#define debugOut(X) cerr << X << flush;
++#else
++#define debugOut(X)
++#endif
++
++
++FileSystemState::FileSystemState() {
++ char *argv[] = { (char*)"/usr/bin/mkdir", 0 };
++ int argc = 1;
++
++ debugOut ("FS_wrapper: InitializeOrb(): start.\n");
++
++ /* Set 'PerformingInitialization = true'? */
++
++ orb = CORBA_ORB_init(argc, argv);
++ if (CORBA_is_nil(orb)) {
++ cerr << "Error initializing ORB!\n";
++ exit(1);
++ }
++ debugOut ("\tORB initialized successfully.\n");
++
++ const char *env = getenv("KORBIT_IOR");
++ if (!env) {
++ // This should check /proc/corba/FileServer-server also!
++ cerr << "InitializeOrb Error: KORBIT_IOR not found in environment!\n";
++ exit(1);
++ }
++
++ cout << "IOR = " << env << endl;
++
++ // WHY DO I HANG IN string_to_object??
++ CORBA_Object_var obj = orb->string_to_object(env);
++ debugOut("\tORB initialized successfully.\n");
++
++ if (CORBA_is_nil(obj)) {
++ cerr << "InitializeOrb Error: IOR is invalid: " << env << endl;
++ exit (1);
++ }
++
++ debugOut ("\tORB initialized successfully.\n");
++ try {
++ FS = FileServer_FileSystem::_narrow(obj);
++ } catch (...) {
++ cerr << "InitializeOrb Error: Got an exception from _narrow().\n";
++ exit (1);
++ }
++
++ /* Initialize my data structure 'o file descriptors. */
++
++ // Set up mapping for stdin, stdout, stderr. Set up a new fd, #4 for
++ // console/debug output
++
++ // stderr can go to console for now.
++
++ debugOut ("FS_wrapper: InitializeOrb(): finished successfully.\n");
++} /* End InitializeOrb(). */
++
++
++FileSystemState::~FileSystemState() (void) {
++} /* End CleanupOrb(). */
++
++
++void HandleException(CORBA_UserException &Exception) {
++ try {
++ throw Exception; // get the type back...
++ } catch (Errors::FileExists &) {
++ errno = EEXIST;
++ } catch (Errors::PermissionDenied &) {
++ errno = EACCES;
++ } catch (Errors::FileNotFound &) {
++ errno = ENOENT;
++ } catch (Errors::IsNotDirectory &) {
++ errno = ENOTDIR;
++ } catch (Errors::ReadOnlyFile &) {
++ errno = EROFS;
++ } catch (Errors::RecursiveSymlink &) {
++ errno = ELOOP;
++ } catch (Errors::OtherError &) {
++ errno = EIO; /* I/O error */
++ } catch (CORBA_UserException &Exception) {
++ cerr << "unknown exception occurred! \n";
++ }
++}
++
++//int open(const char *path, int oflag, mode_t mode) {
++
++
++// return -1;
++//}
++
++int mkdir(const char *pathname, mode_t mode) {
++ debugOut("FS_wrapper: mkdir(" << pathname << "): start.\n");
++
++ try {
++ FileSystemState::get().getFS()->MakeDirectory(pathname, mode);
++ } catch (CORBA_UserException &ex) {
++ HandleException(ex);
++ return -1;
++ }
++
++ // Success!
++ debugOut("FS wrapper: mkdir(): finish successfully.\n");
++ return 0;
++} // End mkdir()
++
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.h linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.h
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/FileServer_wrapper.h Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,81 @@
++// The KORBit FileServer wrapper, which is a shared library that gets
++// hit with the LD_PRELOAD action, so as to redirect all FS calls
++// out the CORBA hole.
++//
++// Note that most of these functions have the side effect of modifying errno.
++//
++#ifndef FILESERVER_WRAPPER_H
++#define FILESERVER_WRAPPER_H
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++
++// This class contains all the global variables for this file. It is very
++// important that we use this mechanism so that our library is initialized as
++// early as possible, but no earlier. In particular this means that we cannot
++// be initialized before iostreams are, which we use for debugging. This scheme
++// the only way to that we are constructed and descructed on demand.
++//
++class FileSystemState {
++private:
++ FileSystemState(); // private ctor/dtor. The only way to get one of these is
++ ~FileSystemState(); // to call FileSystemState::get()
++
++ FileSystemState(const FileSystemState &); // do not implement
++ FileSystemState &operator=(const FileSystemState &); // do not implement
++
++
++ CORBA_ORB_var orb; // Global reference to the orb.
++ FileServer_FileSystem_var FS; // Global reference to FS object...
++public:
++ static FileSystemState &get() {
++ // Static objects like this are intialized the first time they are used, and
++ // destroyed when the project shuts down. This is exactly the semantics we
++ // want.
++ static FileSystemState FSS;
++ return FSS;
++ }
++
++ CORBA_ORB_var getORB() { return orb; }
++ FileServer_FileSystem_var getFS() { return FS; }
++};
++
++extern "C" {
++
++ //
++ // interface File
++ //
++ // pread, readv, pwrite, writev
++ int read(int FD, void *Buffer, size_t NumBytes);
++ int write(int FD, void *Buffer, size_t NumBytes);
++ int close(int FD);
++ // fcntl
++ // fstat
++ // fchdir
++ // seek
++ int dup(int FD);
++ int dup2(int FDFrom, int FDTo);
++
++ //
++ // interface FileSystem
++ //
++ // int open(const char *path, int oflag, mode_t mode);
++ int creat(const char *path, mode_t mode);
++
++// link
++// unlink
++// rename
++// readlink
++// stat
++// lstat
++ int mkdir(const char *Path, mode_t Mode);
++// rmdir
++ int chdir(const char *Path);
++}
++
++//
++// Local function prototypes.
++//
++
++#endif
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/Makefile linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/Makefile
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/Makefile Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,29 @@
++CC = CC -mt -pta -g
++OBDIR = /home/class/cs423/local
++IDL = $(OBDIR)/bin/idl
++CPPFLAGS = -I. -I$(OBDIR)/include
++LDFLAGS = -L$(OBDIR)/lib -G -fPIC
++LIBS = -lCosNaming -lOB -lJTC -lsocket -lnsl -lposix4 -lCstd -lCrun
++
++all: libfswrapper.so
++
++libfswrapper.so: FileServer.o FileServer_wrapper.o
++ CC $(LDFLAGS) -o $@ FileServer_wrapper.o FileServer.o $(LIBS)
++
++FileServer.h FileServer.cpp: ../FileServer.idl
++ rm -f FileServer.cpp FileServer.h
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ $(IDL) ../FileServer.idl
++
++FileServer_skel.cpp FileServer_skel.h: FileServer.cpp
++
++%.o: %.cpp
++ $(CC) $(CPPFLAGS) -c $<
++
++clean:
++ rm -f libfswrapper.so *.o *~
++
++realclean: clean
++ rm -f FileServer.h FileServer.cpp
++ rm -f FileServer_skel.h FileServer_skel.cpp
++ rm -rf SunWS_cache
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/README linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/README
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/README Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,5 @@
++This is a library that may be LD_PRELOAD'd to forward filesystem related calls
++through the FileServer interface.
++
++ORB: ORBacus
++Status: Mostly not working
+diff -urN linux-2.4.1/net/korbit/modules/FileServer/wrapper/test.c linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/test.c
+--- linux-2.4.1/net/korbit/modules/FileServer/wrapper/test.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/FileServer/wrapper/test.c Thu Feb 1 11:47:09 2001
+@@ -0,0 +1,15 @@
++#include <stdlib.h>
++#include <stdio.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++
++int main(void)
++{
++ if (mkdir("test", 0666) == -1)
++ {
++ perror ("mkdir failed because: ");
++ return (1);
++ }
++
++ return (0);
++}
+diff -urN linux-2.4.1/net/korbit/modules/Makefile linux-2.4.1-korbit/net/korbit/modules/Makefile
+--- linux-2.4.1/net/korbit/modules/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Makefile Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,15 @@
++#
++# Makefile for KORBit/modules
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++
++subdir-$(CONFIG_CORBA_CONSOLE) += Console
++subdir-$(CONFIG_CORBA_ECHO) += Echo
++subdir-$(CONFIG_CORBA_FILESERVER) += FileServer
++subdir-$(CONFIG_CORBA_CORBAFS) += CorbaFS
++subdir-$(CONFIG_CORBA_CHARDEV) += CharDev
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/Makefile.module linux-2.4.1-korbit/net/korbit/modules/Makefile.module
+--- linux-2.4.1/net/korbit/modules/Makefile.module Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/Makefile.module Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,9 @@
++M_OBJS := $(O_TARGET)
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -I. -I../../.. -I../../../include -I../../../kglib -nostdinc
++
++
++ORBIT_IDL = orbit-idl
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/modules/README linux-2.4.1-korbit/net/korbit/modules/README
+--- linux-2.4.1/net/korbit/modules/README Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/README Thu Feb 1 11:46:58 2001
+@@ -0,0 +1,7 @@
++Modules included so far:
++
++CharDev : Implement Linux character device drivers
++Console : Print strings to the Linux console
++CorbaFS : Implement Linux filesystems through the VFS layer
++Echo : Testcase to test orb two-way communication
++FileServer: Access a filesystem through CORBA
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/UserFS/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Entries Thu Feb 1 11:47:09 2001
+@@ -0,0 +1 @@
++D
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/CVS/Entries.Log linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Entries.Log
+--- linux-2.4.1/net/korbit/modules/UserFS/CVS/Entries.Log Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Entries.Log Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++A D/client////
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/UserFS/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Repository Thu Feb 1 11:47:09 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/UserFS
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/CVS/Root linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Root
+--- linux-2.4.1/net/korbit/modules/UserFS/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/CVS/Root Thu Feb 1 11:47:09 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Entries linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Entries
+--- linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Entries Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++D
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Repository linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Repository
+--- linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Repository Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/modules/UserFS/client
+diff -urN linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Root linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Root
+--- linux-2.4.1/net/korbit/modules/UserFS/client/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/modules/UserFS/client/CVS/Root Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/orb/CVS/Entries linux-2.4.1-korbit/net/korbit/orb/CVS/Entries
+--- linux-2.4.1/net/korbit/orb/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/CVS/Entries Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,60 @@
++/Makefile/1.6/Thu Feb 1 09:47:10 2001//
++/allocator-defs.h/1.1.1.1/Thu Feb 1 09:47:10 2001//
++/allocators.c/1.2/Thu Feb 1 09:47:10 2001//
++/allocators.h/1.1.1.1/Thu Feb 1 09:47:10 2001//
++/cdr.c/1.1.1.1/Thu Feb 1 09:47:10 2001//
++/cdr.h/1.1.1.1/Thu Feb 1 09:47:10 2001//
++/corba_any.c/1.3/Thu Feb 1 09:47:10 2001//
++/corba_any.h/1.1.1.1/Thu Feb 1 09:47:10 2001//
++/corba_any_proto.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_any_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_basic_sequences_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_context.c/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_context.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_env.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_env_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_object.c/1.7/Thu Feb 1 09:47:11 2001//
++/corba_object.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_object_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_orb.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_orb_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_portableserver.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_portableserver_type.h/1.1.1.1/Thu Feb 1 09:47:11 2001//
++/corba_sequences.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/corba_sequences_type.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/corba_typecode.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/corba_typecode_type.h/1.3/Thu Feb 1 09:47:12 2001//
++/dii.c/1.2/Thu Feb 1 09:47:12 2001//
++/dii.h/1.2/Thu Feb 1 09:47:12 2001//
++/env.c/1.2/Thu Feb 1 09:47:12 2001//
++/env.h/1.2/Thu Feb 1 09:47:12 2001//
++/genrand.c/1.4/Thu Feb 1 09:47:12 2001//
++/genrand.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/iop.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/ir.c/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/ir.h/1.1.1.1/Thu Feb 1 09:47:12 2001//
++/options.c/1.2/Thu Feb 1 09:47:12 2001//
++/options.h/1.2/Thu Feb 1 09:47:13 2001//
++/orb.c/1.13/Thu Feb 1 09:47:13 2001//
++/orb.h/1.2/Thu Feb 1 09:47:13 2001//
++/orbit.c/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit.h/1.2/Thu Feb 1 09:47:13 2001//
++/orbit.h.in/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_config.h/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_object.c/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_object.h/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_object_type.h/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_poa.c/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_poa.h/1.3/Thu Feb 1 09:47:13 2001//
++/orbit_poa_type.h/1.1.1.1/Thu Feb 1 09:47:13 2001//
++/orbit_typecode.c/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/orbit_typecode.h/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/orbit_types.h/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/poa.c/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/poa.h/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/sequences.c/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/sequences.h/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/server.c/1.5/Thu Feb 1 09:47:14 2001//
++/typecode.c/1.1.1.1/Thu Feb 1 09:47:14 2001//
++/typecode.h/1.1.1.1/Thu Feb 1 09:47:14 2001//
++D
+diff -urN linux-2.4.1/net/korbit/orb/CVS/Repository linux-2.4.1-korbit/net/korbit/orb/CVS/Repository
+--- linux-2.4.1/net/korbit/orb/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/CVS/Repository Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/orb
+diff -urN linux-2.4.1/net/korbit/orb/CVS/Root linux-2.4.1-korbit/net/korbit/orb/CVS/Root
+--- linux-2.4.1/net/korbit/orb/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/CVS/Root Thu Feb 1 11:47:10 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
+diff -urN linux-2.4.1/net/korbit/orb/Makefile linux-2.4.1-korbit/net/korbit/orb/Makefile
+--- linux-2.4.1/net/korbit/orb/Makefile Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/Makefile Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,25 @@
++#
++# Makefile for KORBit/orb
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .o file).
++#
++# Note 2! The CFLAGS definition is now in the main makefile...
++
++O_TARGET := orblib.o
++
++#obj-m := $(O_TARGET)
++obj-y := allocators.o options.o poa.o \
++ cdr.o env.o orb.o sequences.o \
++ corba_any.o genrand.o orbit.o server.o \
++ corba_context.o orbit_object.o typecode.o \
++ corba_object.o orbit_poa.o \
++ dii.o ir.o orbit_typecode.o
++
++EXTRA_CFLAGS = -D__KORBIT__ -DHAVE_CONFIG_H -I. -I.. -I../include -I../kglib -I../ORBitutil -nostdinc \
++ -DORBit_SYSRC=\"/etc/orbitrc\" \
++ -DORBIT_MAJOR_VERSION="0" -DORBIT_MINOR_VERSION="5" -DORBIT_MICRO_VERSION="3" -DORBIT_VERSION=\"0.5.3\"
++
++include $(TOPDIR)/Rules.make
++
+diff -urN linux-2.4.1/net/korbit/orb/allocator-defs.h linux-2.4.1-korbit/net/korbit/orb/allocator-defs.h
+--- linux-2.4.1/net/korbit/orb/allocator-defs.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/allocator-defs.h Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,40 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/* By Elliot Lee. Copyright (c) 1998 Red Hat Software */
++
++
++/********************************************************
++ * Never include this header file directly. Only allocators.[ch]
++ * should do this
++ ********************************************************/
++
++/* Macro crap */
++
++#ifdef ALLOCATOR_DEFINITION
++
++#define ORBIT_DEFINE_CHUNK(x, xsize) \
++DEFINE_LOCK(x##_allocator); \
++GMemChunk *x##_allocator = NULL
++
++#elif defined(ALLOCATOR_INITIALIZATION)
++
++#define ORBIT_DEFINE_CHUNK(x, xsize) INIT_LOCK(x##_allocator); \
++x##_allocator = g_mem_chunk_new(#x, (xsize), \
++(xsize) * ORBIT_CHUNKS_PREALLOC, G_ALLOC_AND_FREE)
++
++#else
++
++#define ORBIT_DEFINE_CHUNK(x, xsize) \
++EXTERN_LOCK(x##_allocator); \
++extern GMemChunk *x##_allocator
++
++#endif
++
++/*****************************************************
++ * Here's where we define the actual chunks that are used
++ *****************************************************/
++ORBIT_DEFINE_CHUNK(CORBA_TypeCode, sizeof(struct CORBA_TypeCode_struct));
++ORBIT_DEFINE_CHUNK(CORBA_Object, sizeof(struct CORBA_Object_struct));
++ORBIT_DEFINE_CHUNK(CORBA_NVList, sizeof(struct CORBA_NVList_type));
++
++#undef ORBIT_DEFINE_CHUNK
+diff -urN linux-2.4.1/net/korbit/orb/allocators.c linux-2.4.1-korbit/net/korbit/orb/allocators.c
+--- linux-2.4.1/net/korbit/orb/allocators.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/allocators.c Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,241 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/* By Elliot Lee. Copyright (c) 1998 Red Hat Software */
++
++#include "orbit.h"
++
++#if 0
++#define CORBA_Object_release(x, y) ({ g_message(__FILE__ ":%d Releasing object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_release(x, y); })
++#define CORBA_Object_duplicate(x, y) ({ g_message(__FILE__ ":%d Duping object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_duplicate(x, y); })
++#endif
++
++/* The memory chunk stuff */
++
++#define ALLOCATOR_DEFINITION
++#include "allocator-defs.h"
++#undef ALLOCATOR_DEFINITION
++
++void
++ORBit_chunks_init(void)
++{
++#define ALLOCATOR_INITIALIZATION
++#include "allocator-defs.h"
++#undef ALLOCATOR_INTIALIZATION
++}
++
++gpointer
++ORBit_chunk_alloc(GMemChunk *chunk,
++ PARAM_LOCK(chunk))
++{
++ gpointer retval;
++
++ GET_LOCK(chunk);
++ retval = g_mem_chunk_alloc(chunk);
++ RELEASE_LOCK(chunk);
++
++ return retval;
++}
++
++void
++ORBit_chunk_free(GMemChunk *chunk,
++ PARAM_LOCK(chunk),
++ gpointer mem)
++{
++ GET_LOCK(chunk);
++ g_mem_chunk_free(chunk, mem);
++ RELEASE_LOCK(chunk);
++}
++
++/* end memory chunk routines */
++
++/****************************************************************/
++
++/************* begin funky memory alloc/free system */
++
++/****** functions */
++
++gpointer ORBit_alloc(size_t block_size,
++ ORBit_free_childvals freefunc,
++ gpointer func_data)
++{
++ return ORBit_alloc_2(block_size, freefunc, func_data, 0);
++}
++
++gpointer
++ORBit_alloc_2(size_t block_size,
++ ORBit_free_childvals freefunc,
++ gpointer func_data,
++ size_t before_size)
++{
++ ORBit_mem_info *block;
++
++ if(block_size == 0) return NULL;
++
++ block = (ORBit_mem_info *)((char *)
++ g_malloc(block_size + sizeof(ORBit_mem_info) + before_size)
++ + before_size);
++
++#ifdef ORBIT_DEBUG
++ block->magic = 0xdeadbeef;
++#endif
++ block->free = freefunc;
++ block->func_data = func_data;
++
++ return MEMINFO_TO_PTR(block);
++}
++
++/*
++ ORBit_free
++ ----------
++
++ Frees a corba primitive type.
++
++ mem = pointer to the memory block. (must have a preceeding pointer to a meminfo block)
++
++ 1)obtains a pointer to the preceeding meminfo structure
++ 2)Uses the meminfo structure to find the number of elements in the memory block
++ 3)iterates through the memory block, calling the free function for each item.
++
++ */
++
++void
++ORBit_free(gpointer mem, CORBA_boolean free_strings)
++{
++ ORBit_mem_info *block;
++
++ if(!mem)
++ return;
++
++ block = PTR_TO_MEMINFO(mem);
++
++#ifdef ORBIT_DEBUG
++ g_assert(block->magic == 0xdeadbeef);
++#endif
++
++ if(block->free) {
++ int i;
++ gpointer x;
++ gpointer my_data;
++
++ if((gpointer)block->free == (gpointer)ORBit_free_via_TypeCode)
++ my_data = ((guchar *)block) - sizeof(CORBA_TypeCode);
++ else
++ my_data = NULL;
++
++#ifdef ORBIT_DEBUG
++ if(block->func_data == NULL)
++ g_warning("block with freefunc %p has no items", block->free);
++#endif
++
++ for(i = 0, x = mem; i < (gulong)block->func_data; i++)
++ x = block->free(x, my_data, free_strings);
++
++ if((gpointer)block->free == (gpointer)ORBit_free_via_TypeCode)
++ /* ((guchar *)block) -= sizeof(CORBA_TypeCode); */
++ block = (ORBit_mem_info *)
++ (((guchar *)block) - sizeof(CORBA_TypeCode));
++ g_free(block);
++ } else
++ g_free(block);
++}
++
++/******************************************************************/
++/* These aren't currently used... */
++
++gpointer
++ORBit_free_via_TypeCode(gpointer mem, gpointer tcp, gboolean free_strings)
++{
++ CORBA_TypeCode tc = *(CORBA_TypeCode *)tcp, subtc;
++ int i;
++ guchar *retval = NULL;
++
++ switch(tc->kind) {
++ case CORBA_tk_any:
++ {
++ CORBA_any *anyval = mem;
++ if(anyval->_release)
++ CORBA_free(anyval->_value);
++ retval = (guchar *)(anyval + 1);
++ }
++ break;
++ case CORBA_tk_TypeCode:
++ case CORBA_tk_objref:
++ {
++ CORBA_Object_release(*(CORBA_Object *)mem, NULL);
++
++ retval = (guchar *)mem + sizeof(CORBA_Object);
++ }
++ break;
++ case CORBA_tk_Principal:
++ {
++ CORBA_Principal *pval = mem;
++ if(pval->_release)
++ CORBA_free(pval->_buffer);
++ retval = (guchar *)(pval + 1);
++ }
++ break;
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++ mem = ALIGN_ADDRESS(mem, ORBit_find_alignment(tc));
++ for(i = 0; i < tc->sub_parts; i++) {
++ subtc = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)tc->subtypes[i], NULL);
++ mem = ORBit_free_via_TypeCode(mem, &subtc,
++ free_strings);
++ }
++ retval = mem;
++ break;
++ case CORBA_tk_union:
++ subtc = (CORBA_TypeCode)CORBA_Object_duplicate(
++ (CORBA_Object)ORBit_get_union_tag(tc, &mem, TRUE), NULL);
++ {
++ int sz = 0;
++ int al = 1;
++ for(i = 0; i < tc->sub_parts; i++) {
++ al = MAX(al, ORBit_find_alignment(tc->subtypes[i]));
++ sz = MAX(sz, ORBit_gather_alloc_info(tc->subtypes[i]));
++ }
++ mem = ALIGN_ADDRESS(mem, al);
++ ORBit_free_via_TypeCode(mem, &subtc, free_strings);
++ /* the end of the body (subtc) may not be the
++ * same as the end of the union */
++ retval = mem + sz;
++ }
++ break;
++ case CORBA_tk_wstring:
++ case CORBA_tk_string:
++ if(free_strings)
++ CORBA_free(*(char **)mem);
++ retval = (guchar *)mem + sizeof(char *);
++ break;
++ case CORBA_tk_sequence:
++ {
++ CORBA_sequence_octet *pval = mem;
++ if(pval->_release)
++ CORBA_free(pval->_buffer);
++
++ retval = (guchar *)mem + sizeof(CORBA_sequence_octet);
++ }
++ break;
++ case CORBA_tk_array:
++ for(i = 0; i < tc->length; i++) {
++ subtc = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)tc->subtypes[0], NULL);
++ mem = ORBit_free_via_TypeCode(mem, &subtc,
++ free_strings);
++ }
++ retval = mem;
++ break;
++ case CORBA_tk_alias:
++ subtc = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)tc->subtypes[0], NULL);
++ retval = ORBit_free_via_TypeCode(mem, &subtc, free_strings);
++ break;
++ default:
++ retval = ((guchar *)mem) + ORBit_gather_alloc_info(tc);
++ break;
++ }
++
++ CORBA_Object_release((CORBA_Object)tc, NULL);
++
++ return (gpointer)retval;
++}
+diff -urN linux-2.4.1/net/korbit/orb/allocators.h linux-2.4.1-korbit/net/korbit/orb/allocators.h
+--- linux-2.4.1/net/korbit/orb/allocators.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/allocators.h Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,61 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/* By Elliot Lee. Copyright (c) 1998 Red Hat Software */
++
++#ifndef ALLOCATORS_H
++#define ALLOCATORS_H 1
++
++#include <orb/orbit.h>
++
++#include <orb/allocator-defs.h>
++
++#define ORBIT_CHUNK_ALLOC(typename) \
++ORBit_chunk_alloc(typename##_allocator, LOCK_NAME(typename##_allocator))
++
++#define ORBIT_CHUNK_FREE(typename, mem) \
++ORBit_chunk_free(typename##_allocator, LOCK_NAME(typename##_allocator), (mem))
++
++void ORBit_chunks_init(void);
++
++gpointer ORBit_chunk_alloc(GMemChunk *chunk,
++ PARAM_LOCK(chunk_lock));
++
++void ORBit_chunk_free(GMemChunk *chunk,
++ PARAM_LOCK(chunk_lock),
++ gpointer mem);
++
++/* General memory allocation routines */
++
++#define PTR_TO_MEMINFO(x) (((ORBit_mem_info *)(x)) - 1)
++#define MEMINFO_TO_PTR(x) ((gpointer)((x) + 1))
++
++typedef gpointer (*ORBit_free_childvals)(gpointer mem,
++ gpointer func_data,
++ CORBA_boolean free_strings);
++
++typedef struct {
++#ifdef ORBIT_DEBUG
++ gulong magic;
++#endif
++ /* If this routine returns FALSE, it indicates that it already free'd
++ the memory block itself */
++ ORBit_free_childvals free; /* function pointer to free function */
++ gpointer func_data;
++} ORBit_mem_info;
++
++gpointer ORBit_alloc(size_t block_size,
++ ORBit_free_childvals freefunc,
++ gpointer func_data);
++gpointer ORBit_alloc_2(size_t block_size,
++ ORBit_free_childvals freefunc,
++ gpointer func_data,
++ size_t before_size);
++
++void ORBit_free(gpointer mem, CORBA_boolean free_strings);
++
++/* internal stuff */
++gpointer ORBit_free_via_TypeCode(gpointer mem,
++ gpointer tcp,
++ gboolean free_strings);
++
++#endif /* ALLOCATORS_H */
+diff -urN linux-2.4.1/net/korbit/orb/cdr.c linux-2.4.1-korbit/net/korbit/orb/cdr.c
+--- linux-2.4.1/net/korbit/orb/cdr.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/cdr.c Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,643 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#include "config.h"
++#include "../IIOP/iiop-endianP.h"
++#include <stdlib.h>
++#include <string.h>
++#include <ctype.h>
++#include <assert.h>
++
++#include "orbit.h"
++
++#define CDR_GROW_AMOUNT 128
++
++static CORBA_boolean CDR_buffer_grow(CDR_Codec *codec, const unsigned int growth)
++{
++ unsigned int real_growth;
++ div_t divvy;
++
++ if(codec->release_buffer) {
++ divvy=div(growth, CDR_GROW_AMOUNT);
++ real_growth=CDR_GROW_AMOUNT * (divvy.quot+1);
++
++ codec->buffer=(CORBA_octet *)g_realloc(codec->buffer,
++ codec->buf_len
++ +real_growth);
++ }
++
++ return CORBA_TRUE;
++}
++
++static void CDR_buffer_puts(CDR_Codec *codec, const void *data, const unsigned int len)
++{
++ if(codec->wptr+len > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, len);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ memcpy(&codec->buffer[codec->wptr], data, len);
++ codec->wptr+=len;
++}
++
++CORBA_boolean CDR_buffer_gets(CDR_Codec *codec, void *dest, const unsigned int len)
++{
++ if(codec->rptr+len > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_gets: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ memcpy(dest, &codec->buffer[codec->rptr], len);
++ codec->rptr+=len;
++
++ return(CORBA_TRUE);
++}
++
++static void CDR_buffer_put(CDR_Codec *codec, void *datum)
++{
++ if(codec->wptr+1 > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, 1);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ codec->buffer[codec->wptr++]=*(unsigned char *)datum;
++}
++
++static CORBA_boolean CDR_buffer_get(CDR_Codec *codec, void *dest)
++{
++ if(codec->rptr+1 > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_get: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ *(CORBA_octet *)dest=codec->buffer[codec->rptr++];
++ return(CORBA_TRUE);
++}
++
++#ifdef lame_slow_code
++static void CDR_buffer_put2(CDR_Codec *codec, void *datum)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(codec->readonly!=CORBA_TRUE);
++ g_assert(codec->wptr<=codec->buf_len);
++
++ align=((codec->wptr+1)&~1L);
++
++ if(align+2 > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, align+2-codec->wptr);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ while(codec->wptr < align) {
++ codec->buffer[codec->wptr++]='\0';
++ }
++
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[0];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[1];
++}
++
++static CORBA_boolean CDR_buffer_get2(CDR_Codec *codec, void *dest)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(dest!=NULL);
++ g_assert(codec->rptr<=codec->buf_len);
++
++ align=((codec->rptr+1)&~1L);
++
++ if(align+2 > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_get2: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ codec->rptr=align;
++
++ ((CORBA_octet *)dest)[0]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[1]=codec->buffer[codec->rptr++];
++
++ return(CORBA_TRUE);
++}
++
++static void CDR_buffer_put4(CDR_Codec *codec, void *datum)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(codec->readonly!=CORBA_TRUE);
++ g_assert(codec->wptr<=codec->buf_len);
++
++ align=((codec->wptr+3)&~3L);
++
++ if(align+4 > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, align+4-codec->wptr);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ while(codec->wptr < align) {
++ codec->buffer[codec->wptr++]='\0';
++ }
++
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[0];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[1];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[2];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[3];
++}
++
++static CORBA_boolean CDR_buffer_get4(CDR_Codec *codec, void *dest)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(dest!=NULL);
++ g_assert(codec->rptr<=codec->buf_len);
++
++ align=((codec->rptr+3)&~3L);
++
++ if(align+4 > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_get4: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ codec->rptr=align;
++
++ ((CORBA_octet *)dest)[0]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[1]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[2]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[3]=codec->buffer[codec->rptr++];
++
++ return(CORBA_TRUE);
++}
++
++static void CDR_buffer_put8(CDR_Codec *codec, void *datum)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(codec->readonly!=CORBA_TRUE);
++ g_assert(codec->wptr<=codec->buf_len);
++
++ align=((codec->wptr+7)&~7L);
++
++ if(align+8 > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, align+8-codec->wptr);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ while(codec->wptr < align) {
++ codec->buffer[codec->wptr++]='\0';
++ }
++
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[0];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[1];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[2];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[3];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[4];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[5];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[6];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[7];
++}
++
++#if 0
++static CORBA_boolean CDR_buffer_get8(CDR_Codec *codec, void *dest)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(dest!=NULL);
++ g_assert(codec->rptr<=codec->buf_len);
++
++ align=((codec->rptr+7)&~7L);
++
++ if(align+8 > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_get8: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ codec->rptr=align;
++
++ ((CORBA_octet *)dest)[0]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[1]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[2]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[3]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[4]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[5]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[6]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[7]=codec->buffer[codec->rptr++];
++
++ return(CORBA_TRUE);
++}
++#endif
++
++static void CDR_buffer_put16(CDR_Codec *codec, void *datum)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(codec->readonly!=CORBA_TRUE);
++ g_assert(codec->wptr<=codec->buf_len);
++
++ align=((codec->wptr+15)&~15L);
++
++ if(align+16 > codec->buf_len) {
++ CORBA_boolean res=CDR_buffer_grow(codec, align+16-codec->wptr);
++
++ if(res==CORBA_FALSE) {
++ /* just bail out for now */
++ g_assert(!"Malloc error");
++ }
++ }
++
++ while(codec->wptr < align) {
++ codec->buffer[codec->wptr++]='\0';
++ }
++
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[0];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[1];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[2];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[3];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[4];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[5];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[6];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[7];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[8];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[9];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[10];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[11];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[12];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[13];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[14];
++ codec->buffer[codec->wptr++]=((CORBA_octet *)datum)[15];
++}
++
++#if 0
++static CORBA_boolean CDR_buffer_get16(CDR_Codec *codec, void *dest)
++{
++ unsigned long align;
++
++ g_assert(codec!=NULL);
++ g_assert(dest!=NULL);
++ g_assert(codec->rptr<=codec->buf_len);
++
++ align=((codec->rptr+15)&~15L);
++
++ if(align+16 > codec->buf_len) {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Debug, "CDR_buffer_get16: attempt to read past end of buffer\n");
++ return(CORBA_FALSE);
++ }
++
++ codec->rptr=align;
++
++ ((CORBA_octet *)dest)[0]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[1]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[2]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[3]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[4]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[5]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[6]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[7]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[8]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[9]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[10]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[11]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[12]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[13]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[14]=codec->buffer[codec->rptr++];
++ ((CORBA_octet *)dest)[15]=codec->buffer[codec->rptr++];
++
++ return(CORBA_TRUE);
++}
++#endif
++#endif /* lame_slow_code */
++
++#define CDR_buffer_put2(codec, datum) CDR_buffer_putn(codec, datum, 2)
++#define CDR_buffer_put4(codec, datum) CDR_buffer_putn(codec, datum, 4)
++#define CDR_buffer_put8(codec, datum) CDR_buffer_putn(codec, datum, 8)
++#define CDR_buffer_put16(codec, datum) CDR_buffer_putn(codec, datum, 16)
++#define CDR_buffer_get2(codec, dest) CDR_buffer_getn(codec, dest, 2)
++#define CDR_buffer_get4(codec, dest) CDR_buffer_getn(codec, dest, 4)
++#define CDR_buffer_get8(codec, dest) CDR_buffer_getn(codec, dest, 8)
++#define CDR_buffer_get16(codec, dest) CDR_buffer_getn(codec, dest, 16)
++
++static CORBA_boolean
++CDR_buffer_getn(CDR_Codec *codec, void *dest, int bsize)
++{
++ codec->rptr = (unsigned long)ALIGN_ADDRESS(codec->rptr, bsize);
++ if(codec->host_endian==codec->data_endian)
++ memcpy(dest, codec->buffer + codec->rptr, bsize);
++ else
++ iiop_byteswap(dest, codec->buffer + codec->rptr, bsize);
++ codec->rptr += bsize;
++
++ return CORBA_TRUE;
++}
++
++static CORBA_boolean
++CDR_buffer_putn(CDR_Codec *codec, void *datum, int bsize)
++{
++ codec->wptr = (unsigned long)ALIGN_ADDRESS(codec->wptr, bsize);
++ if(codec->host_endian==codec->data_endian)
++ memcpy(codec->buffer + codec->wptr, datum, bsize);
++ else
++ iiop_byteswap(codec->buffer + codec->wptr, datum, bsize);
++ codec->wptr += bsize;
++
++ return CORBA_TRUE;
++}
++
++#define CDR_swap2(d,s) iiop_byteswap((d), (s), 2)
++#define CDR_swap4(d,s) iiop_byteswap((d), (s), 4)
++#define CDR_swap8(d,s) iiop_byteswap((d), (s), 8)
++#define CDR_swap16(d,s) iiop_byteswap((d), (s), 16)
++
++#ifdef lame_slow_code
++static void CDR_swap2(void *d, void *s)
++{
++ ((CORBA_octet *)d)[0]=((CORBA_octet *)s)[1];
++ ((CORBA_octet *)d)[1]=((CORBA_octet *)s)[0];
++}
++
++static void CDR_swap4(void *d, void *s)
++{
++ ((CORBA_octet *)d)[0]=((CORBA_octet *)s)[3];
++ ((CORBA_octet *)d)[1]=((CORBA_octet *)s)[2];
++ ((CORBA_octet *)d)[2]=((CORBA_octet *)s)[1];
++ ((CORBA_octet *)d)[3]=((CORBA_octet *)s)[0];
++}
++
++static void CDR_swap8(void *d, void *s)
++{
++ ((CORBA_octet *)d)[0]=((CORBA_octet *)s)[7];
++ ((CORBA_octet *)d)[1]=((CORBA_octet *)s)[6];
++ ((CORBA_octet *)d)[2]=((CORBA_octet *)s)[5];
++ ((CORBA_octet *)d)[3]=((CORBA_octet *)s)[4];
++ ((CORBA_octet *)d)[4]=((CORBA_octet *)s)[3];
++ ((CORBA_octet *)d)[5]=((CORBA_octet *)s)[2];
++ ((CORBA_octet *)d)[6]=((CORBA_octet *)s)[1];
++ ((CORBA_octet *)d)[7]=((CORBA_octet *)s)[0];
++}
++
++static void CDR_swap16(void *d, void *s)
++{
++ ((CORBA_octet *)d)[0]=((CORBA_octet *)s)[15];
++ ((CORBA_octet *)d)[1]=((CORBA_octet *)s)[14];
++ ((CORBA_octet *)d)[2]=((CORBA_octet *)s)[13];
++ ((CORBA_octet *)d)[3]=((CORBA_octet *)s)[12];
++ ((CORBA_octet *)d)[4]=((CORBA_octet *)s)[11];
++ ((CORBA_octet *)d)[5]=((CORBA_octet *)s)[10];
++ ((CORBA_octet *)d)[6]=((CORBA_octet *)s)[9];
++ ((CORBA_octet *)d)[7]=((CORBA_octet *)s)[8];
++ ((CORBA_octet *)d)[8]=((CORBA_octet *)s)[7];
++ ((CORBA_octet *)d)[9]=((CORBA_octet *)s)[6];
++ ((CORBA_octet *)d)[10]=((CORBA_octet *)s)[5];
++ ((CORBA_octet *)d)[11]=((CORBA_octet *)s)[4];
++ ((CORBA_octet *)d)[12]=((CORBA_octet *)s)[3];
++ ((CORBA_octet *)d)[13]=((CORBA_octet *)s)[2];
++ ((CORBA_octet *)d)[14]=((CORBA_octet *)s)[1];
++ ((CORBA_octet *)d)[15]=((CORBA_octet *)s)[0];
++}
++#endif
++
++
++void CDR_put_short(CDR_Codec *codec, CORBA_short s)
++{
++ CDR_buffer_put2(codec, &s);
++}
++
++CORBA_boolean CDR_get_short(CDR_Codec *codec, CORBA_short *s)
++{
++ return CDR_buffer_get2(codec, s);
++}
++
++void CDR_put_ushort(CDR_Codec *codec, CORBA_unsigned_short us)
++{
++ CDR_buffer_put2(codec, &us);
++}
++
++CORBA_boolean CDR_get_ushort(CDR_Codec *codec, CORBA_unsigned_short *us)
++{
++ return CDR_buffer_get2(codec, us);
++}
++
++void CDR_put_long(CDR_Codec *codec, CORBA_long l)
++{
++ CDR_buffer_put4(codec, &l);
++}
++
++CORBA_boolean CDR_get_long(CDR_Codec *codec, CORBA_long *l)
++{
++ return CDR_buffer_get4(codec, l);
++}
++
++void CDR_put_ulong(CDR_Codec *codec, CORBA_unsigned_long ul)
++{
++ CDR_buffer_put4(codec, &ul);
++}
++
++CORBA_boolean CDR_get_ulong(CDR_Codec *codec, CORBA_unsigned_long *ul)
++{
++ return CDR_buffer_get4(codec, ul);
++}
++
++#ifdef HAVE_CORBA_LONG_LONG
++CORBA_boolean CDR_get_long_long(CDR_Codec *codec, CORBA_long_long *ul)
++{
++ return CDR_buffer_get8(codec, ul);
++}
++
++void CDR_put_long_long(CDR_Codec *codec, CORBA_long_long ll)
++{
++ CDR_buffer_put8(codec, &ll);
++}
++
++void CDR_put_ulong_long(CDR_Codec *codec, CORBA_unsigned_long_long ll)
++{
++ CDR_buffer_put8(codec, &ll);
++}
++
++CORBA_boolean CDR_get_ulong_long(CDR_Codec *codec, CORBA_unsigned_long_long *ull)
++{
++ return CDR_buffer_get8(codec, ull);
++}
++#endif
++
++void CDR_put_float(CDR_Codec *codec, CORBA_float f)
++{
++ CDR_buffer_put4(codec, &f);
++}
++
++void CDR_put_double(CDR_Codec *codec, CORBA_double d)
++{
++ CDR_buffer_put8(codec, &d);
++}
++
++void CDR_put_long_double(CDR_Codec *codec, CORBA_long_double ld)
++{
++ CDR_buffer_put16(codec, &ld);
++}
++
++void CDR_put_octet(CDR_Codec *codec, CORBA_octet datum)
++{
++ CDR_buffer_put(codec, &datum);
++}
++
++CORBA_boolean CDR_get_octet(CDR_Codec *codec, CORBA_octet *datum)
++{
++ return(CDR_buffer_get(codec, datum));
++}
++
++void CDR_put_octets(CDR_Codec *codec, void *data, unsigned long len)
++{
++ CDR_buffer_puts(codec, data, len);
++}
++
++void CDR_put_char(CDR_Codec *codec, CORBA_char c)
++{
++ CDR_buffer_put(codec, &c);
++}
++
++CORBA_boolean CDR_get_char(CDR_Codec *codec, CORBA_char *c)
++{
++ return CDR_buffer_get(codec, c);
++}
++
++void CDR_put_boolean(CDR_Codec *codec, CORBA_boolean datum)
++{
++ datum = datum&&1;
++ CDR_buffer_put(codec, &datum);
++}
++
++CORBA_boolean CDR_get_boolean(CDR_Codec *codec, CORBA_boolean *b)
++{
++ return CDR_buffer_get(codec, b);
++}
++
++void CDR_put_string(CDR_Codec *codec, const char *str)
++{
++ unsigned int len;
++
++ len=strlen(str)+1;
++
++ CDR_put_ulong(codec, len);
++ CDR_buffer_puts(codec, str, len);
++}
++
++CORBA_boolean CDR_get_string_static(CDR_Codec *codec,
++ CORBA_char **str)
++{
++ CORBA_unsigned_long len;
++
++ if(CDR_get_ulong(codec, &len)==CORBA_FALSE)
++ return CORBA_FALSE;
++
++ if((codec->rptr + len) > codec->buf_len)
++ return CORBA_FALSE;
++
++ *str = ((CORBA_char *)codec->buffer) + codec->rptr;
++
++ codec->rptr += len;
++
++ return CORBA_TRUE;
++}
++
++CORBA_boolean CDR_get_string(CDR_Codec *codec, CORBA_char **str)
++{
++ CORBA_unsigned_long len;
++
++ if(CDR_get_ulong(codec, &len)==CORBA_FALSE)
++ return(CORBA_FALSE);
++
++ if(len==0)
++ return(CORBA_FALSE);
++
++ *str=g_new(CORBA_char, len);
++
++ if(CDR_buffer_gets(codec, *str, len)==CORBA_FALSE) {
++ g_free(*str);
++ return(CORBA_FALSE);
++ }
++
++ if((*str)[len-1]!='\0') {
++ ORBit_Trace(TraceMod_CDR, TraceLevel_Notice, "CDR_get_string: string was not NULL-terminated, terminating it now\n");
++ (*str)[len-1]='\0';
++ }
++
++ return(CORBA_TRUE);
++}
++
++CORBA_boolean CDR_get_seq_begin(CDR_Codec *codec, CORBA_unsigned_long *ul)
++{
++ return(CDR_get_ulong(codec, ul));
++}
++
++CDR_Codec *CDR_codec_init_static(CDR_Codec *codec)
++{
++ memset(codec, 0, sizeof(CDR_Codec));
++
++ codec->host_endian = FLAG_ENDIANNESS;
++
++ return codec;
++}
++
++CDR_Codec *CDR_codec_init(void)
++{
++ CDR_Codec *new;
++
++ new=g_new0(CDR_Codec, 1);
++ CDR_codec_init_static(new);
++ new->release_buffer = CORBA_TRUE;
++
++ return(new);
++}
++
++void CDR_codec_free(CDR_Codec *codec)
++{
++ if(codec->release_buffer)
++ g_free(codec->buffer);
++
++ g_free(codec);
++}
+diff -urN linux-2.4.1/net/korbit/orb/cdr.h linux-2.4.1-korbit/net/korbit/orb/cdr.h
+--- linux-2.4.1/net/korbit/orb/cdr.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/cdr.h Thu Feb 1 16:22:12 2001
+@@ -0,0 +1,83 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CDR_H_
++#define _ORBIT_CDR_H_
++
++#include "orbit_types.h"
++
++typedef enum {
++ BigEndian=0,
++ LittleEndian=1
++} CDR_Endianness;
++
++typedef struct {
++ CDR_Endianness host_endian;
++ CDR_Endianness data_endian;
++ CORBA_octet *buffer;
++ unsigned int buf_len;
++ unsigned int wptr, rptr;
++ CORBA_boolean readonly;
++ CORBA_boolean release_buffer;
++} CDR_Codec;
++
++#define HEXDIGIT(c) (isdigit((guchar)(c))?(c)-'0':tolower((guchar)(c))-'a'+10)
++#define HEXOCTET(a,b) ((HEXDIGIT((a)) << 4) | HEXDIGIT((b)))
++
++extern CDR_Codec *CDR_codec_init(void);
++extern CDR_Codec *CDR_codec_init_static(CDR_Codec *codec);
++extern void CDR_codec_free(CDR_Codec *);
++
++extern void CDR_put_short(CDR_Codec *codec, CORBA_short s);
++extern void CDR_put_ushort(CDR_Codec *codec, CORBA_unsigned_short us);
++extern void CDR_put_long(CDR_Codec *codec, CORBA_long l);
++extern void CDR_put_ulong(CDR_Codec *codec, CORBA_unsigned_long ul);
++#ifdef HAVE_CORBA_LONG_LONG
++extern void CDR_put_long_long(CDR_Codec *codec, CORBA_long_long ll);
++extern void CDR_put_ulong_long(CDR_Codec *codec, CORBA_unsigned_long_long ull);
++extern CORBA_boolean CDR_get_ulong_long(CDR_Codec *codec, CORBA_unsigned_long_long *ul);
++extern CORBA_boolean CDR_get_long_long(CDR_Codec *codec, CORBA_long_long *ul);
++#endif
++extern void CDR_put_float(CDR_Codec *codec, CORBA_float f);
++extern void CDR_put_double(CDR_Codec *codec, CORBA_double d);
++extern void CDR_put_long_double(CDR_Codec *codec, CORBA_long_double ld);
++extern void CDR_put_octet(CDR_Codec *codec, CORBA_octet datum);
++extern void CDR_put_octets(CDR_Codec *codec, void *data, unsigned long len);
++extern void CDR_put_char(CDR_Codec *codec, CORBA_char c);
++extern void CDR_put_boolean(CDR_Codec *codec, CORBA_boolean datum);
++extern void CDR_put_string(CDR_Codec *codec, const char *str);
++extern CORBA_boolean CDR_buffer_gets(CDR_Codec *codec, void *dest, const unsigned int len);
++extern CORBA_boolean CDR_get_short(CDR_Codec *codec, CORBA_short *us);
++extern CORBA_boolean CDR_get_ushort(CDR_Codec *codec, CORBA_unsigned_short *us);
++extern CORBA_boolean CDR_get_long(CDR_Codec *codec, CORBA_long *l);
++extern CORBA_boolean CDR_get_ulong(CDR_Codec *codec, CORBA_unsigned_long *ul);
++extern CORBA_boolean CDR_get_octet(CDR_Codec *codec, CORBA_octet *datum);
++extern CORBA_boolean CDR_get_boolean(CDR_Codec *codec, CORBA_boolean *b);
++extern CORBA_boolean CDR_get_char(CDR_Codec *codec, CORBA_char *c);
++extern CORBA_boolean CDR_get_string(CDR_Codec *codec, CORBA_char **str);
++extern CORBA_boolean CDR_get_string_static(CDR_Codec *codec, CORBA_char **str);
++extern CORBA_boolean CDR_get_seq_begin(CDR_Codec *codec, CORBA_unsigned_long *ul);
++
++#endif /* !_ORBIT_CDR_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_any.c linux-2.4.1-korbit/net/korbit/orb/corba_any.c
+--- linux-2.4.1/net/korbit/orb/corba_any.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_any.c Thu Feb 1 11:47:10 2001
+@@ -0,0 +1,914 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++#include <config.h>
++#include <IIOP/IIOP.h>
++#include "orbit.h"
++
++#if 0
++#define CORBA_Object_release(x, y) ({ g_message(__FILE__ ":%d Releasing object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_release(x, y); })
++#define CORBA_Object_duplicate(x, y) ({ g_message(__FILE__ ":%d Duping object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_duplicate(x, y); })
++#endif
++
++gint
++ORBit_find_alignment(CORBA_TypeCode tc)
++{
++ gint retval = 1;
++ int i;
++
++ switch(tc->kind) {
++ case CORBA_tk_union:
++ retval = MAX(retval, ORBit_find_alignment(tc->discriminator));
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++#if ALIGNOF_CORBA_STRUCT > 1
++ retval = MAX(retval, ALIGNOF_CORBA_STRUCT);
++#endif
++ for(i = 0; i < tc->sub_parts; i++)
++ retval = MAX(retval, ORBit_find_alignment(tc->subtypes[i]));
++ return retval;
++ case CORBA_tk_ulong:
++ case CORBA_tk_long:
++ case CORBA_tk_enum:
++ return ALIGNOF_CORBA_LONG;
++ case CORBA_tk_ushort:
++ case CORBA_tk_short:
++ case CORBA_tk_wchar:
++ return ALIGNOF_CORBA_SHORT;
++ case CORBA_tk_longlong:
++ case CORBA_tk_ulonglong:
++ return ALIGNOF_CORBA_LONG_LONG;
++ case CORBA_tk_longdouble:
++ return ALIGNOF_CORBA_LONG_DOUBLE;
++ case CORBA_tk_float:
++ return ALIGNOF_CORBA_FLOAT;
++ case CORBA_tk_double:
++ return ALIGNOF_CORBA_DOUBLE;
++ case CORBA_tk_boolean:
++ case CORBA_tk_char:
++ case CORBA_tk_octet:
++ return ALIGNOF_CORBA_CHAR;
++ case CORBA_tk_string:
++ case CORBA_tk_wstring:
++ case CORBA_tk_TypeCode:
++ case CORBA_tk_objref:
++ return ALIGNOF_CORBA_POINTER;
++ case CORBA_tk_sequence:
++ case CORBA_tk_any:
++ return MAX(MAX(ALIGNOF_CORBA_LONG, ALIGNOF_CORBA_STRUCT), ALIGNOF_CORBA_POINTER);
++ case CORBA_tk_array:
++ case CORBA_tk_alias:
++ return ORBit_find_alignment(tc->subtypes[0]);
++ case CORBA_tk_fixed:
++ return MAX(ALIGNOF_CORBA_SHORT, ALIGNOF_CORBA_STRUCT);
++ default:
++ return 1;
++ }
++}
++
++static void
++ORBit_marshal_value(GIOPSendBuffer *buf,
++ gpointer *val,
++ CORBA_TypeCode tc,
++ ORBit_marshal_value_info *mi)
++{
++ CORBA_unsigned_long i, ulval;
++ gpointer subval;
++ ORBit_marshal_value_info submi;
++
++#if 0
++ g_message("Marshalling a %d value from %#x to offset %d",
++ tc->kind, (gulong)*val,
++ GIOP_MESSAGE_BUFFER(buf)->message_header.message_size);
++#endif
++
++ switch(tc->kind) {
++ case CORBA_tk_wchar:
++ case CORBA_tk_ushort:
++ case CORBA_tk_short:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_SHORT);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_short));
++ *val = ((guchar *)*val) + sizeof(CORBA_short);
++ break;
++ case CORBA_tk_enum:
++ case CORBA_tk_long:
++ case CORBA_tk_ulong:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_long));
++ *val = ((guchar *)*val) + sizeof(CORBA_long);
++ break;
++ case CORBA_tk_float:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_FLOAT);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_float));
++ *val = ((guchar *)*val) + sizeof(CORBA_float);
++ break;
++ case CORBA_tk_double:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_DOUBLE);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_double));
++ *val = ((guchar *)*val) + sizeof(CORBA_double);
++ break;
++ case CORBA_tk_boolean:
++ case CORBA_tk_char:
++ case CORBA_tk_octet:
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_octet));
++ *val = ((guchar *)*val) + sizeof(CORBA_octet);
++ break;
++ case CORBA_tk_any:
++ *val = ALIGN_ADDRESS(*val, MAX(ALIGNOF_CORBA_STRUCT, ALIGNOF_CORBA_POINTER));
++ ORBit_marshal_any(buf, *val);
++ *val = ((guchar *)*val) + sizeof(CORBA_any);
++ break;
++ case CORBA_tk_TypeCode:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ ORBit_encode_CORBA_TypeCode(*val, buf);
++ *val = ((guchar *)*val) + sizeof(CORBA_TypeCode);
++ break;
++ case CORBA_tk_Principal:
++ *val = ALIGN_ADDRESS(*val,
++ MAX(MAX(ALIGNOF_CORBA_LONG, ALIGNOF_CORBA_STRUCT),
++ ALIGNOF_CORBA_POINTER));
++
++ ulval = *(CORBA_unsigned_long *)(*val);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_unsigned_long));
++
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf),
++ *(char**)((char *)*val+sizeof(CORBA_unsigned_long)),
++ ulval);
++ *val = ((guchar *)*val) + sizeof(CORBA_Principal);
++ break;
++ case CORBA_tk_objref:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ ORBit_marshal_object(buf, *val);
++ *val = ((guchar *)*val) + sizeof(CORBA_Object);
++ break;
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++ *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc));
++ for(i = 0; i < tc->sub_parts; i++) {
++ ORBit_marshal_value(buf, val, tc->subtypes[i], mi);
++ }
++ break;
++ case CORBA_tk_union:
++ /* Basic algorithm:
++ marshal the discriminator
++ find out which value we want to use */
++ {
++ CORBA_TypeCode utc;
++
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_STRUCT);
++
++ utc = ORBit_get_union_tag(tc, val, TRUE);
++
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_STRUCT);
++
++ ORBit_marshal_value(buf, val, tc->discriminator, mi);
++ *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc));
++ ORBit_marshal_value(buf, val, utc, mi);
++ }
++ break;
++ case CORBA_tk_wstring:
++ ulval = strlen(*(char **)*val) + 1;
++
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ giop_send_buffer_append_mem_indirect_a(buf,
++ &ulval,
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf), *(char **)*val, ulval);
++
++ *val = ((guchar *)*val) + sizeof(char *);
++ break;
++ case CORBA_tk_string:
++ ulval = strlen(*(char **)*val) + 1;
++
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++
++ giop_send_buffer_append_mem_indirect_a(buf,
++ &ulval,
++ sizeof(CORBA_unsigned_long));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf), *(char **)*val, ulval);
++
++ *val = ((guchar *)*val) + sizeof(char *);
++ break;
++ case CORBA_tk_sequence:
++ {
++ CORBA_sequence_octet *sval = *val;
++
++ *val = ALIGN_ADDRESS(*val,
++ MAX(MAX(ALIGNOF_CORBA_LONG, ALIGNOF_CORBA_STRUCT), ALIGNOF_CORBA_POINTER));
++
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf),
++ &sval->_length,
++ sizeof(sval->_length));
++
++ subval = sval->_buffer;
++
++ for(i = 0; i < sval->_length; i++)
++ ORBit_marshal_value(buf, &subval, tc->subtypes[0], mi);
++
++ *val = ((guchar *)*val) + sizeof(CORBA_sequence_octet);
++ }
++ break;
++ case CORBA_tk_array:
++ submi.alias_element_type = tc->subtypes[0];
++ for(i = 0; i < tc->length; i++) {
++ ORBit_marshal_value(buf, val, submi.alias_element_type, &submi);
++ *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc->subtypes[0]));
++ }
++ break;
++ case CORBA_tk_alias:
++ submi.alias_element_type = tc->subtypes[0];
++ ORBit_marshal_value(buf, val, submi.alias_element_type, &submi);
++ break;
++ case CORBA_tk_longlong:
++ case CORBA_tk_ulonglong:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_LONG);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_long_long));
++ return /* *val + sizeof(CORBA_long_long)*/;
++ break;
++ case CORBA_tk_longdouble:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_DOUBLE);
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), *val, sizeof(CORBA_long_double));
++ return /* *val + sizeof(CORBA_long_double)*/;
++ break;
++ case CORBA_tk_fixed:
++ /* XXX todo */
++ g_error("CORBA_fixed NYI");
++
++ break;
++ case CORBA_tk_null:
++ case CORBA_tk_void:
++ break;
++ default:
++ g_error("Can't encode unknown type %d", tc->kind);
++ }
++}
++
++static glong ORBit_get_union_switch(CORBA_TypeCode tc, gpointer *val, gboolean update)
++{
++#ifdef __KORBIT__
++ glong retval = 0;
++#else
++ glong retval;
++#endif
++
++ switch(tc->kind) {
++ case CORBA_tk_ulong:
++ case CORBA_tk_long:
++ case CORBA_tk_enum:
++ retval = *(CORBA_long *)*val;
++ if(update) *val += sizeof(CORBA_long);
++ break;
++ case CORBA_tk_ushort:
++ case CORBA_tk_short:
++ retval = *(CORBA_short *)*val;
++ if(update) *val += sizeof(CORBA_short);
++ break;
++ case CORBA_tk_char:
++ case CORBA_tk_boolean:
++ case CORBA_tk_octet:
++ retval = *(CORBA_octet *)*val;
++ if(update) *val += sizeof(CORBA_char);
++ break;
++ case CORBA_tk_alias:
++ return ORBit_get_union_switch(tc->subtypes[0], val, update);
++ break;
++ default:
++ g_error("Wow, some nut has passed us a weird type[%d] as a union discriminator!", tc->kind);
++ }
++
++ return retval;
++}
++
++/* This function (and the one above it) exist for the
++ sole purpose of finding out which CORBA_TypeCode a union discriminator value
++ indicates.
++
++ If {update} is TRUE, {*val} will be advanced by the native size
++ of the descriminator type.
++
++ Hairy stuff.
++*/
++CORBA_TypeCode
++ORBit_get_union_tag(CORBA_TypeCode union_tc, gpointer *val, gboolean update)
++{
++ glong discrim_val, case_val;
++ int i;
++ CORBA_TypeCode retval = CORBA_OBJECT_NIL;
++
++ discrim_val = ORBit_get_union_switch(union_tc->discriminator, val, update);
++
++ for(i = 0; i < union_tc->sub_parts; i++) {
++ if(i == union_tc->default_index)
++ continue;
++
++ case_val = ORBit_get_union_switch(union_tc->sublabels[i]._type,
++ &union_tc->sublabels[i]._value, FALSE);
++ if(case_val == discrim_val) {
++ retval = union_tc->subtypes[i];
++ break;
++ }
++ }
++
++ if(retval)
++ return retval;
++ else if(union_tc->default_index >= 0)
++ return union_tc->subtypes[union_tc->default_index];
++ else {
++ return TC_null;
++ }
++}
++
++void
++ORBit_marshal_arg(GIOPSendBuffer *buf,
++ gpointer val,
++ CORBA_TypeCode tc)
++{
++ ORBit_marshal_value_info mi;
++
++ ORBit_marshal_value(buf, &val, tc, &mi);
++}
++
++
++void
++ORBit_marshal_any(GIOPSendBuffer *buf, const CORBA_any *val)
++{
++ ORBit_marshal_value_info mi;
++
++ gpointer mval = val->_value;
++
++ ORBit_encode_CORBA_TypeCode(val->_type, buf);
++
++ ORBit_marshal_value(buf, &mval, val->_type, &mi);
++}
++
++size_t
++ORBit_gather_alloc_info(CORBA_TypeCode tc)
++{
++ int i, n, align=1, prevalign, sum, prev;
++ size_t block_size;
++
++ switch(tc->kind) {
++ case CORBA_tk_long:
++ case CORBA_tk_ulong:
++ case CORBA_tk_enum:
++ return sizeof(CORBA_long);
++ break;
++ case CORBA_tk_short:
++ case CORBA_tk_ushort:
++ return sizeof(CORBA_short);
++ break;
++ case CORBA_tk_float:
++ return sizeof(CORBA_float);
++ break;
++ case CORBA_tk_double:
++ return sizeof(CORBA_double);
++ break;
++ case CORBA_tk_boolean:
++ case CORBA_tk_char:
++ case CORBA_tk_octet:
++ return sizeof(CORBA_octet);
++ break;
++ case CORBA_tk_any:
++ return sizeof(CORBA_any);
++ break;
++ case CORBA_tk_TypeCode:
++ return sizeof(CORBA_TypeCode);
++ break;
++ case CORBA_tk_Principal:
++ return sizeof(CORBA_Principal);
++ break;
++ case CORBA_tk_objref:
++ return sizeof(CORBA_Object);
++ break;
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++ sum = 0;
++ for(i = 0; i < tc->sub_parts; i++) {
++ sum = GPOINTER_TO_INT(ALIGN_ADDRESS(sum, ORBit_find_alignment(tc->subtypes[i])));
++ sum += ORBit_gather_alloc_info(tc->subtypes[i]);
++ }
++ sum = GPOINTER_TO_INT(ALIGN_ADDRESS(sum, ORBit_find_alignment(tc)));
++ return sum;
++ break;
++ case CORBA_tk_union:
++ sum = ORBit_gather_alloc_info(tc->discriminator);
++ n = -1;
++ align = 1;
++ for(prev = prevalign = i = 0; i < tc->sub_parts; i++) {
++ prevalign = align;
++ align = ORBit_find_alignment(tc->subtypes[i]);
++ if(align > prevalign)
++ n = i;
++
++ prev = MAX(prev, ORBit_gather_alloc_info(tc->subtypes[i]));
++ }
++ if(n >= 0)
++ sum = GPOINTER_TO_INT(ALIGN_ADDRESS(sum, ORBit_find_alignment(tc->subtypes[n])));
++ sum += prev;
++ sum = GPOINTER_TO_INT(ALIGN_ADDRESS(sum, ORBit_find_alignment(tc)));
++ return sum;
++ break;
++ case CORBA_tk_wstring:
++ case CORBA_tk_string:
++ return sizeof(char *);
++ break;
++ case CORBA_tk_sequence:
++ return sizeof(CORBA_sequence_octet);
++ break;
++ case CORBA_tk_array:
++ block_size = ORBit_gather_alloc_info(tc->subtypes[0]);
++ return block_size * tc->length;
++ break;
++ case CORBA_tk_alias:
++ return ORBit_gather_alloc_info(tc->subtypes[0]);
++ case CORBA_tk_longlong:
++ case CORBA_tk_ulonglong:
++ return sizeof(CORBA_long_long);
++ case CORBA_tk_longdouble:
++ return sizeof(CORBA_long_double);
++ case CORBA_tk_wchar:
++ return sizeof(CORBA_wchar);
++ case CORBA_tk_fixed:
++ return sizeof(CORBA_fixed_d_s);
++ default:
++ return 0;
++ }
++}
++
++/* to allocate a block, we need to know of any important data
++ contained in it.
++*/
++static gpointer
++ORBit_demarshal_allocate_mem(CORBA_TypeCode tc, gint nelements)
++{
++ size_t block_size;
++ gpointer retval = NULL;
++
++ if(!nelements) return retval;
++
++ block_size = ORBit_gather_alloc_info(tc);
++
++ if(block_size) {
++ retval = ORBit_alloc_2(block_size * nelements,
++ (ORBit_free_childvals)ORBit_free_via_TypeCode,
++ GINT_TO_POINTER(nelements),
++ sizeof(CORBA_TypeCode));
++
++ *(CORBA_TypeCode *)((char *)retval-sizeof(ORBit_mem_info)-sizeof(CORBA_TypeCode)) = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)tc, NULL);
++ }
++
++ return retval;
++}
++
++#define DM_GET_ATOM(x, n) G_STMT_START{ GIOP_RECV_BUFFER(buf)->decoder(x, (GIOP_RECV_BUFFER(buf)->cur), n); GIOP_RECV_BUFFER(buf)->cur = ((guchar *)GIOP_RECV_BUFFER(buf)->cur) + n; }G_STMT_END
++
++static void
++ORBit_demarshal_value(GIOPRecvBuffer *buf,
++ gpointer *val,
++ CORBA_TypeCode tc,
++ gboolean dup_strings,
++ CORBA_ORB orb)
++{
++ CORBA_long i, n;
++
++#if 0
++ g_message("Demarshalling a %d value from offset %d into %#x",
++ tc->kind, buf->cur - buf->message_body, (gulong)*val);
++#endif
++
++ switch(tc->kind) {
++ case CORBA_tk_short:
++ case CORBA_tk_ushort:
++ case CORBA_tk_wchar:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_SHORT);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_short));
++ DM_GET_ATOM(*val, sizeof(CORBA_short));
++ *val = ((guchar *)*val) + sizeof(CORBA_short);
++ break;
++ case CORBA_tk_long:
++ case CORBA_tk_ulong:
++ case CORBA_tk_enum:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long));
++ DM_GET_ATOM(*val, sizeof(CORBA_long));
++ *val = ((guchar *)*val) + sizeof(CORBA_long);
++ break;
++ case CORBA_tk_longlong:
++ case CORBA_tk_ulonglong:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_LONG);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long_long));
++ DM_GET_ATOM(*val, sizeof(CORBA_long_long));
++ *val = ((guchar *)*val) + sizeof(CORBA_long_long);
++ break;
++ case CORBA_tk_longdouble:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_DOUBLE);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long_double));
++ DM_GET_ATOM(*val, sizeof(CORBA_long_double));
++ *val = ((guchar *)*val) + sizeof(CORBA_long_double);
++ break;
++ case CORBA_tk_float:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_FLOAT);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_float));
++ DM_GET_ATOM(*val, sizeof(CORBA_float));
++ *val = ((guchar *)*val) + sizeof(CORBA_float);
++ break;
++ case CORBA_tk_double:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_DOUBLE);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_double));
++ DM_GET_ATOM(*val, sizeof(CORBA_double));
++ *val = ((guchar *)*val) + sizeof(CORBA_double);
++ break;
++ case CORBA_tk_boolean:
++ case CORBA_tk_char:
++ case CORBA_tk_octet:
++ DM_GET_ATOM(*val, sizeof(CORBA_octet));
++ *val = ((guchar *)*val) + sizeof(CORBA_octet);
++ break;
++ case CORBA_tk_any:
++ {
++ CORBA_any *decoded;
++
++ *val = ALIGN_ADDRESS(*val,
++ MAX(ALIGNOF_CORBA_LONG,
++ MAX(ALIGNOF_CORBA_POINTER, ALIGNOF_CORBA_STRUCT)));
++ decoded = *val;
++ decoded->_release = CORBA_FALSE;
++ ORBit_demarshal_any(buf, decoded, dup_strings, orb);
++ *val = ((guchar *)*val) + sizeof(CORBA_any);
++ }
++ break;
++ case CORBA_tk_TypeCode:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ ORBit_decode_CORBA_TypeCode(*val, buf);
++ CORBA_Object_duplicate(*(CORBA_Object *)*val, NULL);
++ *val = ((guchar *)*val) + sizeof(CORBA_TypeCode);
++ break;
++ case CORBA_tk_Principal:
++ {
++ CORBA_Principal *p;
++
++ *val = ALIGN_ADDRESS(*val, MAX(ALIGNOF_CORBA_STRUCT,
++ MAX(ALIGNOF_CORBA_LONG, ALIGNOF_CORBA_POINTER)));
++
++ p = *val;
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long));
++ CORBA_sequence_set_release(p, dup_strings);
++ DM_GET_ATOM(&p->_length, sizeof(CORBA_long));
++ p->_buffer = ORBit_alloc(p->_length, NULL, GINT_TO_POINTER(1));
++ memcpy(p->_buffer, buf->cur, p->_length);
++ buf->cur = ((guchar *)buf->cur) + p->_length;
++ *val = ((guchar *)*val) + sizeof(CORBA_sequence_octet);
++ }
++ break;
++ case CORBA_tk_objref:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ *(CORBA_Object *)*val = ORBit_demarshal_object(buf, orb);
++ *val = ((guchar *)*val) + sizeof(CORBA_Object);
++ break;
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++ *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc));
++ for(i = 0; i < tc->sub_parts; i++) {
++ ORBit_demarshal_value(buf, val, tc->subtypes[i], dup_strings, orb);
++ }
++ break;
++ case CORBA_tk_union:
++ {
++ gpointer discrimptr;
++
++ discrimptr = *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc));
++ ORBit_demarshal_value(buf, val, tc->discriminator, dup_strings, orb);
++ n = 1;
++ for(i = 0; i < tc->sub_parts; i++) {
++ n = MAX(n, ORBit_find_alignment(tc->subtypes[i]));
++ }
++ *val = ALIGN_ADDRESS(*val, n);
++ ORBit_demarshal_value(buf, val,
++ ORBit_get_union_tag(tc, &discrimptr, FALSE),
++ dup_strings, orb);
++ }
++ break;
++ case CORBA_tk_string:
++ case CORBA_tk_wstring:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long));
++ DM_GET_ATOM(&i, sizeof(CORBA_long));
++ if(dup_strings)
++ *(char **)*val = CORBA_string_dup(buf->cur);
++ else
++ *(char **)*val = buf->cur;
++ *val = ((guchar *)*val) + sizeof(CORBA_char *);
++ buf->cur = (gpointer)((char *)buf->cur + i);
++ break;
++ case CORBA_tk_sequence:
++ {
++ CORBA_sequence_octet *p;
++ gpointer subval;
++
++ *val = ALIGN_ADDRESS(*val, MAX(ALIGNOF_CORBA_STRUCT,
++ MAX(ALIGNOF_CORBA_LONG, ALIGNOF_CORBA_POINTER)));
++ p = *val;
++ buf->cur = ALIGN_ADDRESS(buf->cur, sizeof(CORBA_long));
++ DM_GET_ATOM(&p->_length, sizeof(CORBA_long));
++ if(tc->subtypes[0]->kind == CORBA_tk_octet
++ || tc->subtypes[0]->kind == CORBA_tk_boolean
++ || tc->subtypes[0]->kind == CORBA_tk_char) {
++ /* This special-casing could be taken further to apply to
++ all atoms... */
++ p->_buffer = ORBit_alloc(p->_length, NULL, GINT_TO_POINTER(1));
++ memcpy(p->_buffer, buf->cur, p->_length);
++ buf->cur = ((guchar *)buf->cur) + p->_length;
++ } else {
++ p->_buffer = ORBit_demarshal_allocate_mem(tc->subtypes[0],
++ p->_length);
++ subval = p->_buffer;
++
++ for(i = 0; i < p->_length; i++)
++ ORBit_demarshal_value(buf, &subval,
++ tc->subtypes[0],
++ dup_strings,
++ orb);
++ }
++
++ *val = ((guchar *)*val) + sizeof(CORBA_sequence_octet);
++ }
++ break;
++ case CORBA_tk_array:
++ for(i = 0; i < tc->length; i++)
++ ORBit_demarshal_value(buf, val, tc->subtypes[0], dup_strings, orb);
++ break;
++ case CORBA_tk_alias:
++ ORBit_demarshal_value(buf, val, tc->subtypes[0], dup_strings, orb);
++ break;
++ case CORBA_tk_fixed:
++ g_error("CORBA_fixed NYI");
++ break;
++ default:
++ break;
++ }
++}
++
++gpointer
++ORBit_demarshal_arg(GIOPRecvBuffer *buf,
++ CORBA_TypeCode tc,
++ gboolean dup_strings,
++ CORBA_ORB orb)
++{
++ gpointer retval, val;
++
++ retval = val = ORBit_demarshal_allocate_mem(tc, 1);
++
++ ORBit_demarshal_value(buf, &val, tc, dup_strings, orb);
++
++ return retval;
++}
++
++void
++ORBit_demarshal_any(GIOPRecvBuffer *buf, CORBA_any *retval,
++ gboolean dup_strings,
++ CORBA_ORB orb)
++{
++ gpointer val;
++
++#if 0
++ /* I wish I knew whether this was correct or not. It breaks things like 'any anop();' for sure,
++ since we can't always initialize every single possible 'any' underneath _ORBIT_retval */
++ if(retval->_release)
++ CORBA_free(retval->_value);
++#endif
++
++ CORBA_any_set_release(retval, CORBA_TRUE);
++
++ ORBit_decode_CORBA_TypeCode(&retval->_type, buf);
++ CORBA_Object_duplicate((CORBA_Object)retval->_type, NULL);
++
++ val = retval->_value = ORBit_demarshal_allocate_mem(retval->_type, 1);
++ ORBit_demarshal_value(buf, &val, retval->_type, dup_strings, orb);
++}
++
++void
++_ORBit_copy_value(gpointer *val, gpointer *newval, CORBA_TypeCode tc)
++{
++ CORBA_long i;
++ gpointer pval1, pval2;
++
++ switch(tc->kind) {
++ case CORBA_tk_wchar:
++ case CORBA_tk_short:
++ case CORBA_tk_ushort:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_SHORT);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_SHORT);
++ *(CORBA_short *)*newval = *(CORBA_short *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_short);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_short);
++ break;
++ case CORBA_tk_enum:
++ case CORBA_tk_long:
++ case CORBA_tk_ulong:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_LONG);
++ *(CORBA_long *)*newval = *(CORBA_long *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_long);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_long);
++ break;
++ case CORBA_tk_longlong:
++ case CORBA_tk_ulonglong:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_LONG);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_LONG_LONG);
++ *(CORBA_long_long *)*newval = *(CORBA_long_long *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_long_long);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_long_long);
++ break;
++ case CORBA_tk_longdouble:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_LONG_DOUBLE);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_LONG_DOUBLE);
++ *(CORBA_long_double *)*newval = *(CORBA_long_double *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_long_double);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_long_double);
++ break;
++ case CORBA_tk_float:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_FLOAT);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_FLOAT);
++ *(CORBA_long *)*newval = *(CORBA_long *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_float);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_float);
++ break;
++ case CORBA_tk_double:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_DOUBLE);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_DOUBLE);
++ *(CORBA_double *)*newval = *(CORBA_double *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_double);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_double);
++ break;
++ case CORBA_tk_boolean:
++ case CORBA_tk_char:
++ case CORBA_tk_octet:
++ *(CORBA_octet *)*newval = *(CORBA_octet *)*val;
++ *val = ((guchar *)*val) + sizeof(CORBA_octet);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_octet);
++ break;
++ case CORBA_tk_any:
++ {
++ CORBA_any *oldany, *newany;
++ *val = ALIGN_ADDRESS(*val, MAX(ALIGNOF_CORBA_STRUCT, ALIGNOF_CORBA_POINTER));
++ *newval = ALIGN_ADDRESS(*newval, MAX(ALIGNOF_CORBA_STRUCT, ALIGNOF_CORBA_POINTER));
++ oldany = *val;
++ newany = *newval;
++ newany->_type = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)oldany->_type, NULL);
++ /* XXX are we supposed to do this even if oldany->_release
++ == FALSE? */
++ newany->_value = ORBit_copy_value(oldany->_value, oldany->_type);
++ newany->_release = CORBA_TRUE;
++ *val = ((guchar *)*val) + sizeof(CORBA_any);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_any);
++ }
++ break;
++ case CORBA_tk_Principal:
++ *val = ALIGN_ADDRESS(*val,
++ MAX(MAX(ALIGNOF_CORBA_LONG,
++ ALIGNOF_CORBA_STRUCT),
++ ALIGNOF_CORBA_POINTER));
++ *newval = ALIGN_ADDRESS(*newval,
++ MAX(MAX(ALIGNOF_CORBA_LONG,
++ ALIGNOF_CORBA_STRUCT),
++ ALIGNOF_CORBA_POINTER));
++ *(CORBA_Principal *)*newval = *(CORBA_Principal *)*val;
++ ((CORBA_Principal *)*newval)->_buffer =
++ CORBA_octet_allocbuf(((CORBA_Principal *)*newval)->_length);
++ memcpy(((CORBA_Principal *)*newval)->_buffer,
++ ((CORBA_Principal *)*val)->_buffer,
++ ((CORBA_Principal *)*val)->_length);
++ *val = ((guchar *)*val) + sizeof(CORBA_Principal);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_Principal);
++ break;
++ case CORBA_tk_TypeCode:
++ case CORBA_tk_objref:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_POINTER);
++ *(CORBA_Object *)*newval = CORBA_Object_duplicate(*(CORBA_Object *)*val,
++ NULL);
++ *val = ((guchar *)*val) + sizeof(CORBA_Object);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_Object);
++ break;
++ case CORBA_tk_struct:
++ case CORBA_tk_except:
++ *val = ALIGN_ADDRESS(*val, ORBit_find_alignment(tc));
++ *newval = ALIGN_ADDRESS(*newval, ORBit_find_alignment(tc));
++ for(i = 0; i < tc->sub_parts; i++) {
++ _ORBit_copy_value(val, newval, tc->subtypes[i]);
++ }
++ break;
++ case CORBA_tk_union:
++ {
++ CORBA_TypeCode utc = ORBit_get_union_tag(tc, val, FALSE);
++ gint union_align = ORBit_find_alignment(tc);
++ size_t union_size = ORBit_gather_alloc_info(tc);
++
++ /* need to advance val,newval by size of union, not just
++ * current tagged field within it */
++ pval1 = *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_STRUCT);
++ pval2 = *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_STRUCT);
++ _ORBit_copy_value(&pval1, &pval2, tc->discriminator);
++ pval1 = ALIGN_ADDRESS(pval1, union_align);
++ pval2 = ALIGN_ADDRESS(pval2, union_align);
++ _ORBit_copy_value(&pval1, &pval2, utc);
++ *val = ((guchar *)*val) + union_size;
++ *newval = ((guchar *)*newval) + union_size;
++ }
++ break;
++ case CORBA_tk_wstring:
++ case CORBA_tk_string:
++ *val = ALIGN_ADDRESS(*val, ALIGNOF_CORBA_POINTER);
++ *newval = ALIGN_ADDRESS(*newval, ALIGNOF_CORBA_POINTER);
++
++ *(CORBA_char **)*newval = CORBA_string_dup(*(CORBA_char **)*val);
++ *val = ((guchar *)*val) + sizeof(CORBA_char *);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_char *);
++ break;
++ case CORBA_tk_sequence:
++ *val = ALIGN_ADDRESS(*val,
++ MAX(MAX(ALIGNOF_CORBA_LONG,
++ ALIGNOF_CORBA_STRUCT),
++ ALIGNOF_CORBA_POINTER));
++ *newval = ALIGN_ADDRESS(*newval,
++ MAX(MAX(ALIGNOF_CORBA_LONG,
++ ALIGNOF_CORBA_STRUCT),
++ ALIGNOF_CORBA_POINTER));
++ ((CORBA_Principal *)*newval)->_release = CORBA_TRUE;
++ ((CORBA_Principal *)*newval)->_length =
++ ((CORBA_Principal *)*newval)->_maximum =
++ ((CORBA_Principal *)*val)->_length;
++ ((CORBA_Principal *)*newval)->_buffer = pval2 =
++ ORBit_demarshal_allocate_mem(tc->subtypes[0],
++ ((CORBA_Principal *)*val)->_length);
++ pval1 = ((CORBA_Principal *)*val)->_buffer;
++
++ for(i = 0; i < ((CORBA_Principal *)*newval)->_length; i++) {
++ _ORBit_copy_value(&pval1, &pval2, tc->subtypes[0]);
++ }
++ *val = ((guchar *)*val) + sizeof(CORBA_sequence_octet);
++ *newval = ((guchar *)*newval) + sizeof(CORBA_sequence_octet);
++ break;
++ case CORBA_tk_array:
++ for(i = 0; i < tc->length; i++) {
++ _ORBit_copy_value(val, newval, tc->subtypes[0]);
++ }
++ break;
++ case CORBA_tk_alias:
++ _ORBit_copy_value(val, newval, tc->subtypes[0]);
++ break;
++ case CORBA_tk_fixed:
++ g_error("CORBA_fixed NYI!");
++ break;
++ case CORBA_tk_void:
++ case CORBA_tk_null:
++ *val = NULL;
++ break;
++ default:
++ g_error("Can't handle copy of value kind %d", tc->kind);
++ }
++}
++
++gpointer
++ORBit_copy_value(gpointer value, CORBA_TypeCode tc)
++{
++ gpointer retval, newval;
++
++ retval = newval = ORBit_demarshal_allocate_mem(tc, 1);
++ _ORBit_copy_value(&value, &newval, tc);
++
++ return retval;
++}
++
++void
++CORBA_any__copy(CORBA_any *out, CORBA_any *in)
++{
++ out->_type = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)in->_type,
++ NULL);
++ out->_value = ORBit_copy_value(in->_value, in->_type);
++ out->_release = CORBA_TRUE;
++}
+diff -urN linux-2.4.1/net/korbit/orb/corba_any.h linux-2.4.1-korbit/net/korbit/orb/corba_any.h
+--- linux-2.4.1/net/korbit/orb/corba_any.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_any.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,45 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ANY_H_
++#define _ORBIT_CORBA_ANY_H_
++
++#include "orbit_types.h"
++#include "corba_typecode.h"
++
++#include <unistd.h>
++
++typedef struct CORBA_any_type CORBA_any;
++
++size_t ORBit_gather_alloc_info(CORBA_TypeCode tc);
++gint ORBit_find_alignment(CORBA_TypeCode tc);
++CORBA_TypeCode ORBit_get_union_tag(CORBA_TypeCode union_tc,
++ gpointer *val, gboolean update);
++gpointer ORBit_copy_value(gpointer value, CORBA_TypeCode tc);
++void _ORBit_copy_value(gpointer *val, gpointer *newval, CORBA_TypeCode tc);
++
++void CORBA_any__copy(CORBA_any *out, CORBA_any *in);
++
++#endif /* !_ORBIT_CORBA_ANY_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_any_proto.h linux-2.4.1-korbit/net/korbit/orb/corba_any_proto.h
+--- linux-2.4.1/net/korbit/orb/corba_any_proto.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_any_proto.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,16 @@
++#ifndef _ORBIT_CORBA_ANY_PROTO_H_
++#define _ORBIT_CORBA_ANY_PROTO_H_
++
++void ORBit_marshal_arg(GIOPSendBuffer *buf,
++ gpointer val,
++ CORBA_TypeCode tc);
++void ORBit_marshal_any(GIOPSendBuffer *buf, const CORBA_any *val);
++gpointer ORBit_demarshal_arg(GIOPRecvBuffer *buf,
++ CORBA_TypeCode tc,
++ gboolean dup_strings,
++ CORBA_ORB orb);
++void ORBit_demarshal_any(GIOPRecvBuffer *buf, CORBA_any *retval,
++ gboolean dup_strings,
++ CORBA_ORB orb);
++
++#endif /* !_ORBIT_CORBA_ANY_PROTO_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_any_type.h linux-2.4.1-korbit/net/korbit/orb/corba_any_type.h
+--- linux-2.4.1/net/korbit/orb/corba_any_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_any_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,48 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ANY_TYPE_H_
++#define _ORBIT_CORBA_ANY_TYPE_H_
++
++#include "corba_any.h"
++#include "corba_typecode.h"
++
++struct CORBA_any_type {
++ CORBA_TypeCode _type;
++ gpointer _value;
++ CORBA_boolean _release;
++};
++
++typedef struct ORBit_marshal_value_info_struct {
++ CORBA_TypeCode alias_element_type;
++} ORBit_marshal_value_info;
++
++#define CORBA_ANYFLAGS_RELEASE 1
++
++
++#endif /* !_ORBIT_CORBA_ANY_TYPE_H_ */
++
++
++
+diff -urN linux-2.4.1/net/korbit/orb/corba_basic_sequences_type.h linux-2.4.1-korbit/net/korbit/orb/corba_basic_sequences_type.h
+--- linux-2.4.1/net/korbit/orb/corba_basic_sequences_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_basic_sequences_type.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,43 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_BASIC_SEQUENCES_TYPE_H_
++#define _ORBIT_CORBA_BASIC_SEQUENCES_TYPE_H_
++
++#include <ORBitutil/basic_types.h>
++
++#ifndef _CORBA_sequence_octet_defined
++#define _CORBA_sequence_octet_defined 1
++
++typedef struct CORBA_sequence_octet_struct {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_octet *_buffer;
++ CORBA_boolean _release;
++} CORBA_sequence_octet;
++#endif /* !_CORBA_sequence_octet_defined */
++
++#include <orb/corba_sequences.h>
++#endif /* !_ORBIT_CORBA_BASIC_SEQUENCES_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_context.c linux-2.4.1-korbit/net/korbit/orb/corba_context.c
+--- linux-2.4.1/net/korbit/orb/corba_context.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_context.c Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,390 @@
++#include "orb/orbit.h"
++
++#define o_return_val_if_fail(expr, val) if(!(expr)) { CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM, CORBA_COMPLETED_NO); return (val); }
++#define o_return_if_fail(expr) if(!(expr)) { CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM, CORBA_COMPLETED_NO); return; }
++
++static gboolean
++free_entry(gpointer key, gpointer value, gpointer user_data)
++{
++ g_free(key);
++ g_free(value);
++
++ return TRUE;
++}
++
++static void
++ORBit_Context_release(CORBA_Context ctx, CORBA_Environment *ev);
++
++static gboolean
++free_child(gpointer value, gpointer user_data)
++{
++ CORBA_Context ctx = value;
++
++ ORBIT_ROOT_OBJECT(ctx)->refs = 1;
++ ctx->parent_ctx = CORBA_OBJECT_NIL;
++ ORBit_Context_release(ctx, NULL);
++
++ return TRUE;
++}
++
++static void
++ORBit_Context_release(CORBA_Context ctx,
++ CORBA_Environment *ev)
++{
++ ORBIT_ROOT_OBJECT_UNREF(ctx);
++
++ if(ORBIT_ROOT_OBJECT(ctx)->refs <= 0) {
++ if(ctx->children) {
++ g_slist_foreach(ctx->children, (GFunc)free_child, ctx);
++ g_slist_free(ctx->children);
++ }
++
++ if(ctx->mappings) {
++ g_hash_table_foreach_remove(ctx->mappings, free_entry, ctx);
++ g_hash_table_destroy(ctx->mappings);
++ }
++
++ if(ctx->parent_ctx != CORBA_OBJECT_NIL)
++ ctx->parent_ctx->children = g_slist_remove(ctx->parent_ctx->children, ctx->the_name);
++
++ g_free(ctx->the_name);
++
++ g_free(ctx);
++ }
++}
++
++static const ORBit_RootObject_Interface CORBA_Context_epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))ORBit_Context_release,
++};
++
++static CORBA_Context
++CORBA_Context_new(CORBA_Context parent, const char *name, CORBA_Environment *ev)
++{
++ CORBA_Context retval;
++
++ retval = g_new0(struct CORBA_Context_type, 1);
++
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(retval), ORBIT_PSEUDO_CONTEXT, ev);
++
++ ORBIT_ROOT_OBJECT(retval)->refs = 0;
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(retval), (gpointer)&CORBA_Context_epv, ev);
++
++ if(name)
++ retval->the_name = g_strdup(name);
++
++ retval->parent_ctx = parent;
++ if(parent)
++ parent->children = g_slist_prepend(parent->children, retval);
++
++ return retval;
++}
++
++/* Section 5.6.1 */
++CORBA_Status CORBA_ORB_get_default_context(CORBA_ORB orb, CORBA_Context *ctx, CORBA_Environment *ev)
++{
++ g_return_if_fail(ev != NULL);
++ o_return_if_fail(orb && ctx);
++
++ if(!orb->default_ctx)
++ orb->default_ctx = CORBA_Context_new(CORBA_OBJECT_NIL, NULL, ev);
++
++ *ctx = (CORBA_Context)CORBA_Object_duplicate((CORBA_Object)orb->default_ctx, ev);
++}
++
++/********* XXX todo - CORBA_Context support */
++CORBA_Status CORBA_Context_set_one_value(CORBA_Context ctx, CORBA_Identifier prop_name, char *value, CORBA_Environment *ev)
++{
++ gpointer old_nom, old_value;
++ g_return_if_fail(ev != NULL);
++ o_return_if_fail(ctx && prop_name && value);
++
++ if(!ctx->mappings)
++ ctx->mappings = g_hash_table_new(g_str_hash, g_str_equal);
++
++ if(g_hash_table_lookup_extended(ctx->mappings, prop_name, &old_nom, &old_value)) {
++ g_free(old_nom);
++ g_free(old_value);
++ }
++
++ g_hash_table_insert(ctx->mappings, g_strdup(prop_name), g_strdup(value));
++}
++
++/* Section 5.6.3 */
++CORBA_Status CORBA_Context_set_values(CORBA_Context ctx, CORBA_NVList *values, CORBA_Environment *ev)
++{
++ int i;
++
++ for(i = 0; i < values->list->len; i++) {
++ CORBA_NamedValue *nvp;
++
++ nvp = ((CORBA_NamedValue *)values->list->data) + i;
++
++ g_assert(nvp->argument._type == TC_string);
++
++ CORBA_Context_set_one_value(ctx, nvp->name, nvp->argument._value, ev);
++ }
++}
++
++/* Section 5.6.4 */
++
++typedef struct {
++ CORBA_Context ctx;
++ CORBA_Identifier prop_name;
++ CORBA_NVList *values;
++ CORBA_Environment *ev;
++ int len;
++} CTXSearchInfo;
++
++static gboolean
++list_has_key(CORBA_NVList *list, const char *key)
++{
++ int i;
++
++ for(i = 0; i < list->list->len; i++) {
++ CORBA_NamedValue *nvp;
++
++ nvp = ((CORBA_NamedValue *)list->list->data) + i;
++
++ if(!strcmp(nvp->name, key))
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++static void
++search_props(gpointer key, gpointer value, CTXSearchInfo *csi)
++{
++ if(strncmp(key, csi->prop_name, csi->len))
++ return;
++
++ if(list_has_key(csi->values, key))
++ return;
++
++ CORBA_NVList_add_item(csi->values, key, TC_string, &value, strlen(value) + 1, CORBA_IN_COPY_VALUE, NULL);
++}
++
++static void
++ctx_get_values(CORBA_Context ctx, CORBA_Flags op_flags,
++ CORBA_Identifier prop_name, CORBA_NVList **values,
++ gint is_wc,
++ CORBA_Environment *ev)
++{
++ gboolean go_up = FALSE;
++
++ if(is_wc >= 0) {
++ CTXSearchInfo csi;
++
++ csi.ctx = ctx;
++ csi.prop_name = prop_name;
++ csi.values = *values;
++ csi.ev = ev;
++ csi.len = is_wc;
++
++ if(ctx->mappings)
++ g_hash_table_foreach(ctx->mappings, (GHFunc)search_props, &csi);
++
++ go_up = TRUE;
++
++ } else {
++ char *val = NULL;
++
++ if(ctx->mappings)
++ val = g_hash_table_lookup(ctx->mappings, prop_name);
++
++ if(val)
++ CORBA_NVList_add_item(*values, prop_name, TC_string, &val, strlen(val) + 1, CORBA_IN_COPY_VALUE, ev);
++ else
++ go_up = TRUE;
++ }
++
++ if(go_up
++ && ctx->parent_ctx
++ && !(op_flags & CORBA_CTX_RESTRICT_SCOPE))
++ ctx_get_values(ctx->parent_ctx, op_flags, prop_name, values, is_wc, ev);
++}
++
++CORBA_Status CORBA_Context_get_values(CORBA_Context ctx,
++ CORBA_Identifier start_scope,
++ CORBA_Flags op_flags,
++ CORBA_Identifier prop_name,
++ CORBA_NVList **values,
++ CORBA_Environment *ev)
++{
++ char *ctmp;
++ int wc_pos;
++
++ CORBA_ORB_create_list(CORBA_OBJECT_NIL, 0, values, ev);
++
++ if(start_scope && *start_scope) {
++ while(ctx && (!ctx->the_name || strcmp(ctx->the_name, start_scope)))
++ ctx = ctx->parent_ctx;
++
++ if(!ctx) {
++ CORBA_exception_set_system(ev, ex_CORBA_INV_IDENT, CORBA_COMPLETED_NO);
++ return;
++ }
++ }
++
++ ctmp = strchr(prop_name, '*');
++ if(ctmp)
++ wc_pos = ctmp - prop_name;
++ else
++ wc_pos = -1;
++
++ CORBA_ORB_create_list(CORBA_OBJECT_NIL, 0, values, ev);
++
++ ctx_get_values(ctx, op_flags, prop_name, values, (prop_name[strlen(prop_name) - 1] == '*'), ev);
++
++ if((*values)->list->len == 0)
++ {
++ CORBA_NVList_free(*values, ev);
++ *values = NULL;
++ CORBA_exception_set_system(ev, ex_CORBA_UNKNOWN, CORBA_COMPLETED_NO);
++ }
++}
++
++/* Section 5.6.5 */
++static void
++delete_props(gpointer key, gpointer value, CTXSearchInfo *csi)
++{
++ if(strncmp(key, csi->prop_name, csi->len))
++ return;
++
++ g_hash_table_remove(csi->ctx->mappings, key);
++ g_free(key);
++ g_free(value);
++}
++
++CORBA_Status CORBA_Context_delete_values(CORBA_Context ctx, CORBA_Identifier prop_name, CORBA_Environment *ev)
++{
++ char *ctmp;
++ int wc_pos;
++
++ if(!ctx->mappings)
++ return;
++
++ ctmp = strchr(prop_name, '*');
++ if(ctmp)
++ wc_pos = ctmp - prop_name;
++ else
++ wc_pos = -1;
++
++ if(wc_pos >= 0) {
++ CTXSearchInfo csi;
++
++ memset(&csi, 0, sizeof(csi));
++ csi.ctx = ctx;
++ csi.prop_name = prop_name;
++ csi.ev = ev;
++ csi.len = wc_pos;
++
++ g_hash_table_foreach(ctx->mappings, (GHFunc)delete_props, &csi);
++ } else {
++ gpointer old_nom, old_value;
++
++ if(g_hash_table_lookup_extended(ctx->mappings, prop_name, &old_nom, &old_value)) {
++ g_free(old_nom);
++ g_free(old_value);
++ }
++ }
++}
++
++/* Section 5.6.6 */
++CORBA_Status CORBA_Context_create_child(CORBA_Context ctx, CORBA_Identifier ctx_name, CORBA_Context *child_ctx, CORBA_Environment *ev)
++{
++ *child_ctx = CORBA_Context_new(ctx, ctx_name, ev);
++}
++
++/* Section 5.6.7 */
++CORBA_Status CORBA_Context_delete(CORBA_Context ctx, CORBA_Flags del_flags, CORBA_Environment *ev)
++{
++ if((del_flags & CORBA_CTX_DELETE_DESCENDENTS)
++ || !ctx->children)
++ free_child(ctx, NULL);
++}
++
++void
++ORBit_Context_marshal(CORBA_Context ctx, const ORBit_ContextMarshalItem *mlist, CORBA_unsigned_long nitems, GIOPSendBuffer *buf)
++{
++ int i;
++ CORBA_unsigned_long *real_nitems, ltmp;
++
++ real_nitems = giop_send_buffer_append_mem_indirect_a(buf, &nitems, sizeof(nitems));
++ if(!ctx->mappings) {
++ *real_nitems = 0;
++ return;
++ }
++
++ for(*real_nitems = i = 0; i < nitems; i++) {
++ char *value;
++
++ value = g_hash_table_lookup(ctx->mappings, mlist[i].str);
++ if(!value)
++ continue;
++
++ /* Key */
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(buf), &(mlist[i].len), sizeof(mlist[i].len));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf), mlist[i].str, mlist[i].len);
++ (*real_nitems)++;
++
++ /* Value */
++ ltmp = strlen(value) + 1;
++ giop_send_buffer_append_mem_indirect_a(buf, &ltmp, sizeof(ltmp));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(buf), value, ltmp);
++ (*real_nitems)++;
++ }
++}
++
++#define GET_ATOM(x) G_STMT_START{ GIOP_RECV_BUFFER(recv_buffer)->decoder(&x, (GIOP_RECV_BUFFER(recv_buffer)->cur), sizeof(x)); \
++GIOP_RECV_BUFFER(recv_buffer)->cur = ((guchar *)GIOP_RECV_BUFFER(recv_buffer)->cur) + sizeof(x); \
++}G_STMT_END
++#define ALIGNFOR(x) recv_buffer->cur = ALIGN_ADDRESS(recv_buffer->cur, sizeof(x))
++
++void
++ORBit_Context_demarshal(CORBA_Context parent, CORBA_Context initme, GIOPRecvBuffer *recv_buffer)
++{
++ CORBA_unsigned_long nstrings, keylen, vallen, i;
++ char *key, *value;
++
++ memset(initme, 0, sizeof(struct CORBA_Context_type));
++ ORBIT_ROOT_OBJECT(initme)->refs = -1;
++
++ initme->parent_ctx = parent;
++
++ ALIGNFOR(nstrings);
++ GET_ATOM(nstrings);
++
++ if(nstrings)
++ initme->mappings = g_hash_table_new(g_str_hash, g_str_equal);
++ else
++ return;
++
++ g_hash_table_freeze(initme->mappings);
++ for(i = 0; i < nstrings; ) {
++ ALIGNFOR(keylen);
++ GET_ATOM(keylen);
++ key = recv_buffer->cur;
++ recv_buffer->cur = ((char *)recv_buffer->cur) + keylen;
++ i++;
++
++ if(i >= nstrings)
++ break;
++
++ ALIGNFOR(vallen);
++ GET_ATOM(vallen);
++ value = recv_buffer->cur;
++ recv_buffer->cur = ((char *)recv_buffer->cur) + vallen;
++ i++;
++
++ g_hash_table_insert(initme->mappings, key, value);
++ }
++ g_hash_table_thaw(initme->mappings);
++}
++
++void
++ORBit_Context_server_free(CORBA_Context ctx)
++{
++ g_hash_table_destroy(ctx->mappings);
++}
+diff -urN linux-2.4.1/net/korbit/orb/corba_context.h linux-2.4.1-korbit/net/korbit/orb/corba_context.h
+--- linux-2.4.1/net/korbit/orb/corba_context.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_context.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,65 @@
++#ifndef CORBA_CONTEXT_H
++#define CORBA_CONTEXT_H 1
++
++#include "orbit_object_type.h"
++#include "orbit_object.h"
++
++typedef struct {
++ CORBA_unsigned_long len;
++ const CORBA_char *str;
++} ORBit_ContextMarshalItem;
++
++typedef struct CORBA_Context_type *CORBA_Context;
++
++struct CORBA_Context_type {
++ struct ORBit_PseudoObject_struct parent;
++ GHashTable *mappings;
++ GSList *children;
++
++ char *the_name;
++
++ CORBA_Context parent_ctx;
++};
++
++
++extern CORBA_Status CORBA_Context_set_one_value(
++ CORBA_Context ctx,
++ CORBA_Identifier prop_name,
++ char *value,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Context_set_values(
++ CORBA_Context ctx,
++ CORBA_NVList *values,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Context_get_values(
++ CORBA_Context ctx,
++ CORBA_Identifier start_scope,
++ CORBA_Flags op_flags,
++ CORBA_Identifier prop_name,
++ CORBA_NVList **values,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Context_delete_values(
++ CORBA_Context ctx,
++ CORBA_Identifier prop_name,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Context_create_child(
++ CORBA_Context ctx,
++ CORBA_Identifier ctx_name,
++ CORBA_Context *child_ctx,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Context_delete(
++ CORBA_Context ctx,
++ CORBA_Flags del_flags,
++ CORBA_Environment *ev);
++
++void ORBit_Context_marshal(CORBA_Context ctx, const ORBit_ContextMarshalItem *mlist,
++ CORBA_unsigned_long nitems, GIOPSendBuffer *buf);
++void ORBit_Context_demarshal(CORBA_Context parent, CORBA_Context initme, GIOPRecvBuffer *recv_buffer);
++void ORBit_Context_server_free(CORBA_Context ctx);
++
++#endif
+diff -urN linux-2.4.1/net/korbit/orb/corba_env.h linux-2.4.1-korbit/net/korbit/orb/corba_env.h
+--- linux-2.4.1/net/korbit/orb/corba_env.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_env.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,79 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ENV_H_
++#define _ORBIT_CORBA_ENV_H_
++
++typedef struct CORBA_Environment_type CORBA_Environment;
++
++/* 3.15 */
++typedef enum {
++ CORBA_COMPLETED_YES=0,
++ CORBA_COMPLETED_NO,
++ CORBA_COMPLETED_MAYBE
++} CORBA_completion_status;
++
++typedef enum {
++ CORBA_NO_EXCEPTION=0,
++ CORBA_USER_EXCEPTION,
++ CORBA_SYSTEM_EXCEPTION
++} CORBA_exception_type;
++
++
++#define ex_CORBA_UNKNOWN 1
++#define ex_CORBA_BAD_PARAM 2
++#define ex_CORBA_NO_MEMORY 3
++#define ex_CORBA_IMP_LIMIT 4
++#define ex_CORBA_COMM_FAILURE 5
++#define ex_CORBA_INV_OBJREF 6
++#define ex_CORBA_NO_PERMISSION 7
++#define ex_CORBA_INTERNAL 8
++#define ex_CORBA_MARSHAL 9
++#define ex_CORBA_INITIALIZE 10
++#define ex_CORBA_NO_IMPLEMENT 11
++#define ex_CORBA_BAD_TYPECODE 12
++#define ex_CORBA_BAD_OPERATION 13
++#define ex_CORBA_NO_RESOURCES 14
++#define ex_CORBA_NO_RESPONSE 15
++#define ex_CORBA_PERSIST_STORE 16
++#define ex_CORBA_BAD_INV_ORDER 17
++#define ex_CORBA_TRANSIENT 18
++#define ex_CORBA_FREE_MEM 19
++#define ex_CORBA_INV_IDENT 20
++#define ex_CORBA_INV_FLAG 21
++#define ex_CORBA_INTF_REPOS 22
++#define ex_CORBA_BAD_CONTEXT 23
++#define ex_CORBA_OBJ_ADAPTER 24
++#define ex_CORBA_DATA_CONVERSION 25
++#define ex_CORBA_OBJECT_NOT_EXIST 26
++#define ex_CORBA_TRANSACTION_REQUIRED 27
++#define ex_CORBA_TRANSACTION_ROLLEDBACK 28
++#define ex_CORBA_INVALID_TRANSACTION 29
++
++
++#endif /* !_ORBIT_CORBA_ENV_H_ */
++
++
++
+diff -urN linux-2.4.1/net/korbit/orb/corba_env_type.h linux-2.4.1-korbit/net/korbit/orb/corba_env_type.h
+--- linux-2.4.1/net/korbit/orb/corba_env_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_env_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,79 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ENV_TYPE_H_
++#define _ORBIT_CORBA_ENV_TYPE_H_
++
++#include "corba_env.h"
++#include "corba_any.h"
++
++typedef struct CORBA_system_exception {
++ CORBA_unsigned_long minor;
++ CORBA_completion_status completed;
++} CORBA_SystemException;
++
++#define SYSEXC(name) typedef CORBA_SystemException name;
++
++SYSEXC(CORBA_UNKNOWN)
++SYSEXC(CORBA_BAD_PARAM)
++SYSEXC(CORBA_NO_MEMORY)
++SYSEXC(CORBA_IMP_LIMIT)
++SYSEXC(CORBA_COMM_FAILURE)
++SYSEXC(CORBA_INV_OBJREF)
++SYSEXC(CORBA_NO_PERMISSION)
++SYSEXC(CORBA_INTERNAL)
++SYSEXC(CORBA_MARSHAL)
++SYSEXC(CORBA_INITIALIZE)
++SYSEXC(CORBA_NO_IMPLEMENT)
++SYSEXC(CORBA_BAD_TYPECODE)
++SYSEXC(CORBA_BAD_OPERATION)
++SYSEXC(CORBA_NO_RESOURCES)
++SYSEXC(CORBA_NO_RESPONSE)
++SYSEXC(CORBA_PERSIST_STORE)
++SYSEXC(CORBA_BAD_INV_ORDER)
++SYSEXC(CORBA_TRANSIENT)
++SYSEXC(CORBA_FREE_MEM)
++SYSEXC(CORBA_INV_IDENT)
++SYSEXC(CORBA_INV_FLAG)
++SYSEXC(CORBA_INTF_REPOS)
++SYSEXC(CORBA_BAD_CONTEXT)
++SYSEXC(CORBA_OBJ_ADAPTER)
++SYSEXC(CORBA_DATA_CONVERSION)
++SYSEXC(CORBA_OBJECT_NOT_EXIST)
++SYSEXC(CORBA_TRANSACTION_REQUIRED)
++SYSEXC(CORBA_TRANSACTION_ROLLEDBACK)
++SYSEXC(CORBA_INVALID_TRANSACTION)
++
++
++/* 19.22 */
++struct CORBA_Environment_type {
++ CORBA_exception_type _major;
++ CORBA_char *_repo_id;
++ void *_params;
++ CORBA_any *_any;
++};
++
++
++#endif /* !_ORBIT_CORBA_ENV_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_object.c linux-2.4.1-korbit/net/korbit/orb/corba_object.c
+--- linux-2.4.1/net/korbit/orb/corba_object.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_object.c Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,467 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++#include "config.h"
++#include <IIOP/IIOP.h>
++#include "orbit_types.h"
++#include "corba_object.h"
++#include "corba_object_type.h"
++#include "env.h"
++#include "orb.h"
++#ifdef __KORBIT__
++#include "orbit.h"
++#else /* !__KORBIT__ */
++#include "interface_repository.h"
++#endif /* !__KORBIT__ */
++#include <signal.h>
++#include <sys/types.h>
++#include <sys/wait.h>
++#include <alloca.h>
++
++#ifndef __KERNEL__
++#define freeca(ptr)
++#endif
++
++#ifndef __KORBIT__
++/* Section 4.2.1 */
++CORBA_InterfaceDef CORBA_Object_get_interface(CORBA_Object obj, CORBA_Environment *ev)
++{
++ CORBA_Repository repo;
++ CORBA_InterfaceDef interface;
++
++ if(obj==CORBA_OBJECT_NIL)
++ return(CORBA_OBJECT_NIL); /* no exception defined in spec */
++
++ repo=CORBA_ORB_resolve_initial_references(obj->orb, "InterfaceRepository", ev);
++ if(repo==CORBA_OBJECT_NIL)
++ return(CORBA_OBJECT_NIL);
++
++ interface=CORBA_Repository_lookup_id(repo, obj->object_id, ev);
++ CORBA_Object_release(repo, ev);
++
++ return(interface);
++}
++#endif /* !__KORBIT__ */
++
++/* Section 4.2.3 */
++CORBA_boolean CORBA_Object_is_nil(CORBA_Object obj, CORBA_Environment *ev)
++{
++ if(obj==CORBA_OBJECT_NIL) {
++ return(CORBA_TRUE);
++ } else {
++ return(CORBA_FALSE);
++ }
++}
++
++/* Section 4.2.2 */
++/* XXXX Big warning: lots of places inside ORBit expect this to
++ always return 'obj'. Do not change this, upon pain
++ of death... */
++CORBA_Object CORBA_Object_duplicate(CORBA_Object obj, CORBA_Environment *ev)
++{
++ if(obj == CORBA_OBJECT_NIL)
++ return CORBA_OBJECT_NIL;
++
++ if(ORBIT_ROOT_OBJECT(obj)->refs >= 0)
++ ORBIT_ROOT_OBJECT_REF(obj);
++
++ return(obj);
++}
++
++
++/* Section 4.2.2 */
++void CORBA_Object_release(CORBA_Object obj, CORBA_Environment *ev)
++{
++ if(obj != CORBA_OBJECT_NIL)
++ ORBIT_ROOT_OBJECT_release(obj,ev);
++}
++
++extern GHashTable *ORBit_class_assignments;
++
++void ORBit_impl_CORBA_Object_is_a(gpointer servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment *ev,
++ gpointer dummy)
++{
++ GIOPSendBuffer *_ORBIT_send_buffer;
++ struct CORBA_Object_struct objdummy; /* XXX badhack to save backwards compat */
++ CORBA_boolean retval;
++ char *repo_id;
++ CORBA_unsigned_long slen;
++ guchar *curptr;
++ ORBit_ObjectKey *objkey;
++ gpointer *tmp_vepv;
++ guint sz;
++ CORBA_unsigned_long clsid;
++ PortableServer_ServantBase *_ORBIT_servant;
++
++ _ORBIT_servant = servant;
++
++ /* XXX security implications */
++ curptr = _ORBIT_recv_buffer->cur;
++ curptr = ALIGN_ADDRESS(curptr, 4);
++ if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)))
++ iiop_byteswap((guchar *)&slen, curptr, sizeof(CORBA_unsigned_long));
++ else
++ slen = *((CORBA_unsigned_long *)curptr);
++ curptr += 4;
++ repo_id = curptr;
++
++ repo_id[slen] = '\0';
++
++ objkey = ORBIT_OBJECT_KEY(_ORBIT_servant->_private);
++
++ sz = sizeof(gpointer) * (ORBit_class_assignment_counter + 1);
++ tmp_vepv = alloca(sz);
++ memset(tmp_vepv, '\0', sz);
++
++ objdummy.vepv = tmp_vepv;
++ objkey->class_info->init_local_objref(&objdummy, servant);
++
++ clsid = GPOINTER_TO_UINT(g_hash_table_lookup(ORBit_class_assignments, repo_id));
++ retval = (clsid && tmp_vepv[clsid]);
++
++ _ORBIT_send_buffer = giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->connection, NULL,
++ _ORBIT_recv_buffer->message.u.request.request_id, ev->_major);
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), &retval, sizeof(retval));
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ freeca(tmp_vepv);
++}
++
++/* Section 4.2.4 */
++CORBA_boolean CORBA_Object_is_a(CORBA_Object obj, CORBA_char *logical_type_id, CORBA_Environment *ev)
++{
++ if(obj == CORBA_OBJECT_NIL)
++ return CORBA_FALSE;
++
++ if (obj->servant && obj->vepv) {
++ CORBA_unsigned_long clsid;
++
++ clsid = GPOINTER_TO_UINT(g_hash_table_lookup(ORBit_class_assignments, logical_type_id));
++
++ return (clsid && (clsid < obj->vepv_size) && obj->vepv[clsid]);
++ } else if(!strcmp(obj->object_id, logical_type_id)
++ || !strcmp("IDL:CORBA/Object:1.0", logical_type_id)) {
++ return CORBA_TRUE;
++ } else {
++ /* Cut and paste from orbit-idl output */
++ /* XXX security implications */
++ GIOP_unsigned_long _ORBIT_request_id;
++ register GIOP_unsigned_long _ORBIT_system_exception_minor;
++ register CORBA_completion_status _ORBIT_completion_status;
++ register GIOPSendBuffer *_ORBIT_send_buffer;
++ register GIOPRecvBuffer *_ORBIT_recv_buffer;
++ register GIOPConnection *_cnx;
++
++ _cnx = ORBit_object_get_connection(obj);
++
++ _ORBIT_retry_request:
++ _ORBIT_send_buffer = NULL;
++ _ORBIT_recv_buffer = NULL;
++ _ORBIT_completion_status = CORBA_COMPLETED_NO;
++ /* A unique uint pointer is anything on the stack,
++ so set this variable to point to its own address on the
++ stack. :) */
++ _ORBIT_request_id = GPOINTER_TO_UINT(&_ORBIT_request_id);
++ { /* marshalling */
++ static const struct {
++ CORBA_unsigned_long len;
++ char opname[6];
++ } _ORBIT_operation_name_data = {
++ 6, "_is_a"
++ };
++ static const struct iovec _ORBIT_operation_vec =
++ {(gpointer) & _ORBIT_operation_name_data, 10};
++ register CORBA_unsigned_long _ORBIT_tmpvar_0;
++ CORBA_unsigned_long _ORBIT_tmpvar_1;
++
++ _ORBIT_send_buffer =
++ giop_send_request_buffer_use(_cnx, NULL, _ORBIT_request_id, CORBA_TRUE,
++ &(obj->active_profile->object_key_vec), &_ORBIT_operation_vec, &ORBit_default_principal_iovec);
++
++ _ORBIT_system_exception_minor = ex_CORBA_COMM_FAILURE;
++ if (!_ORBIT_send_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_tmpvar_1 = strlen(logical_type_id) + 1;
++ giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), 4);
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), &(_ORBIT_tmpvar_1), sizeof(_ORBIT_tmpvar_1));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), (logical_type_id), sizeof(logical_type_id[_ORBIT_tmpvar_0]) * _ORBIT_tmpvar_1);
++ giop_send_buffer_write(_ORBIT_send_buffer);
++ _ORBIT_completion_status = CORBA_COMPLETED_MAYBE;
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ _ORBIT_send_buffer = NULL;
++ }
++ { /* demarshalling */
++ register guchar *_ORBIT_curptr;
++ CORBA_boolean _ORBIT_retval;
++
++ _ORBIT_recv_buffer = giop_recv_reply_buffer_use_2(_cnx, _ORBIT_request_id, TRUE);
++ if (!_ORBIT_recv_buffer)
++ goto _ORBIT_system_exception;
++ _ORBIT_completion_status = CORBA_COMPLETED_YES;
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status != GIOP_NO_EXCEPTION)
++ goto _ORBIT_msg_exception;
++ if (giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_retval = *((CORBA_boolean *) _ORBIT_curptr);
++ } else {
++ _ORBIT_curptr = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;
++ _ORBIT_retval = *((CORBA_boolean *) _ORBIT_curptr);
++ }
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ _ORBIT_system_exception:
++ CORBA_exception_set_system(ev, _ORBIT_system_exception_minor, _ORBIT_completion_status);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ giop_send_buffer_unuse(_ORBIT_send_buffer);
++ return _ORBIT_retval;
++ _ORBIT_msg_exception:
++ if (_ORBIT_recv_buffer->message.u.reply.reply_status == GIOP_LOCATION_FORWARD) {
++ if (obj->forward_locations != NULL)
++ ORBit_delete_profiles(obj->forward_locations);
++ obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
++ _cnx = ORBit_object_get_forwarded_connection(obj);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++
++ goto _ORBIT_retry_request;
++ } else {
++ ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL, obj->orb);
++ giop_recv_buffer_unuse(_ORBIT_recv_buffer);
++ return _ORBIT_retval;
++ }
++ }
++
++ }
++}
++
++/* Section 4.2.5 */
++#ifndef __KORBIT__
++static void do_exit(int signum) {
++ _exit(5);
++#warning "This should be removed... use BUG instead..."
++}
++#endif
++
++/* Lovely hack to try and figure out without hanging whether an object exists or not. */
++CORBA_boolean CORBA_Object_non_existent(CORBA_Object obj, CORBA_Environment *ev)
++{
++#ifndef __KORBIT__
++ int childpid, exitstatus, itmp;
++#endif
++
++ ev->_major = CORBA_NO_EXCEPTION;
++
++ if(obj == CORBA_OBJECT_NIL)
++ return TRUE;
++
++ if(obj->servant)
++ return FALSE;
++
++ if(obj->connection && obj->connection->is_valid)
++ return FALSE;
++
++#ifndef __KORBIT__
++ childpid = fork();
++
++ if(!childpid) {
++ GIOPConnection* cnx = NULL;
++ struct sigaction sa;
++
++ memset(&sa, 0, sizeof(sa));
++ sa.sa_handler = do_exit;
++ sigaction(SIGALRM, &sa, NULL);
++ alarm(2);
++ cnx = _ORBit_object_get_connection(obj);
++
++ /* XXX todo - try invoking a strange operation on the object, and see what type of exception we get. */
++
++ _exit((cnx == NULL)?1:0);
++ }
++
++ itmp = waitpid(childpid, &exitstatus, 0);
++
++ if(itmp < 0) return TRUE;
++ return WEXITSTATUS(exitstatus) && TRUE;
++#else /* __KORBIT__ */
++ return FALSE;
++#endif /* __KORBIT__ */
++}
++
++gboolean
++g_CORBA_Object_equal(CORBA_Object obj1, CORBA_Object obj2)
++{
++ gboolean retval;
++ CORBA_Environment ev;
++
++ CORBA_exception_init(&ev);
++
++ retval = (gboolean)CORBA_Object_is_equivalent(obj1, obj2, &ev);
++
++ CORBA_exception_free(&ev);
++
++ return retval;
++}
++
++/* Section 4.2.6 */
++CORBA_boolean CORBA_Object_is_equivalent(CORBA_Object obj, CORBA_Object other_object, CORBA_Environment *ev)
++{
++ ORBit_Object_info *obj_profile, *other_object_profile;
++ int i,j, obj_profile_count, other_object_profile_count;
++
++ if(obj == CORBA_OBJECT_NIL
++ && other_object == CORBA_OBJECT_NIL)
++ return CORBA_TRUE;
++
++ if(obj == CORBA_OBJECT_NIL
++ || other_object == CORBA_OBJECT_NIL)
++ goto ret_false;
++
++ /*
++ * If one profile in "obj" matches one in "other_object", then these
++ * objects are equivalent.
++ *
++ * This is O(n*m) at worst case :-( Hopefully though most objects will
++ * only have 1 or 2 profiles.
++ *
++ * The profile list could be indexed as a hash table (the linked list
++ * is still needed, as the profile order is significant)
++ */
++
++ obj_profile_count = g_slist_length(obj->profile_list);
++ other_object_profile_count = g_slist_length(other_object->profile_list);
++
++ for(i=0;i<obj_profile_count;i++) {
++ obj_profile=(ORBit_Object_info *)g_slist_nth_data(obj->profile_list, i);
++
++ for(j=0;j<other_object_profile_count;j++) {
++ other_object_profile=(ORBit_Object_info *)g_slist_nth_data(other_object->profile_list, j);
++
++ if(obj_profile->profile_type != other_object_profile->profile_type)
++ continue;
++
++ if(obj_profile->object_key._length != other_object_profile->object_key._length)
++ continue;
++
++ if(memcmp(obj_profile->object_key._buffer, other_object_profile->object_key._buffer, obj_profile->object_key._length))
++ continue;
++
++ if(obj_profile->profile_type == IOP_TAG_INTERNET_IOP) {
++ TAG_INTERNET_IOP_info *ii1, *ii2;
++
++ ii1 = &obj_profile->tag.iopinfo;
++ ii2 = &other_object_profile->tag.iopinfo;
++
++ if(ii1->port != ii2->port)
++ continue;
++ if(strcmp(ii1->host, ii2->host))
++ continue;
++
++ return(CORBA_TRUE);
++ } else if(obj_profile->profile_type == IOP_TAG_ORBIT_SPECIFIC) {
++ TAG_ORBIT_SPECIFIC_info *oi1, *oi2;
++
++ oi1 = &obj_profile->tag.orbitinfo;
++ oi2 = &other_object_profile->tag.orbitinfo;
++
++ if(strcmp(oi1->unix_sock_path, oi2->unix_sock_path))
++ continue;
++ if(oi1->ipv6_port != oi2->ipv6_port)
++ continue;
++
++ return(CORBA_TRUE);
++ }
++ }
++ }
++
++ ret_false:
++ return CORBA_FALSE;
++}
++
++guint
++g_CORBA_Object_hash(CORBA_Object obj)
++{
++ guint retval;
++ CORBA_Environment ev;
++
++ CORBA_exception_init(&ev);
++
++ retval = (guint)CORBA_Object_hash(obj, UINT_MAX, &ev);
++
++ CORBA_exception_free(&ev);
++
++ return retval;
++}
++
++static void profile_hash(gpointer item, gpointer data)
++{
++ ORBit_Object_info *info = (ORBit_Object_info *)item;
++ CORBA_unsigned_long *retval = (CORBA_unsigned_long *)data;
++
++ g_assert(info);
++ g_assert(retval);
++
++ *retval ^= info->object_key._length;
++
++ if(info->profile_type == IOP_TAG_INTERNET_IOP) {
++ *retval ^= !info->tag.iopinfo.port;
++ } else if(info->profile_type == IOP_TAG_ORBIT_SPECIFIC) {
++ *retval ^= g_str_hash(info->tag.orbitinfo.unix_sock_path);
++ *retval ^= !info->tag.orbitinfo.ipv6_port;
++ }
++}
++
++/* Section 4.2.6 */
++CORBA_unsigned_long CORBA_Object_hash(CORBA_Object obj,
++ CORBA_unsigned_long maximum,
++ CORBA_Environment *ev)
++{
++ CORBA_unsigned_long retval = 0;
++ char *tptr;
++
++ g_assert(obj);
++
++ tptr = obj->object_id;
++ while(*tptr) {
++ retval = (retval << 8) ^ *tptr;
++ tptr++;
++ }
++
++ if(g_slist_length(obj->profile_list)>0) {
++ g_slist_foreach(obj->profile_list, profile_hash, &retval);
++ } else {
++ g_warning("Object of type %s doesn't seem to have any connection info!", obj->object_id);
++ }
++
++ return (retval % maximum);
++}
++
++/* Section 4.2.7 */
++CORBA_Policy CORBA_Object_get_policy(CORBA_Object obj, CORBA_PolicyType policy_type, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
+diff -urN linux-2.4.1/net/korbit/orb/corba_object.h linux-2.4.1-korbit/net/korbit/orb/corba_object.h
+--- linux-2.4.1/net/korbit/orb/corba_object.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_object.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,59 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_OBJECT_H_
++#define _ORBIT_CORBA_OBJECT_H_
++
++#include <ORBitutil/basic_types.h>
++
++#include "corba_env.h"
++#include "corba_orb.h"
++#include "corba_sequences.h"
++
++#define CORBA_OBJECT_NIL NULL
++
++typedef struct CORBA_Object_struct *CORBA_Object;
++
++#define CORBA_OBJECT(x) ((CORBA_Object)(x))
++
++/* Used for internal stuff mostly, but also good if you want to store
++ a hash of objects */
++gboolean g_CORBA_Object_equal(CORBA_Object obj1, CORBA_Object obj2);
++guint g_CORBA_Object_hash(CORBA_Object obj);
++
++void ORBit_impl_CORBA_Object_is_a(gpointer servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ CORBA_Environment *ev, gpointer dummy);
++#define ORBIT_IMPLEMENTS_IS_A
++
++extern CORBA_boolean CORBA_Object_is_a(
++ CORBA_Object obj,
++ CORBA_char *logical_type_id,
++ CORBA_Environment *ev);
++
++#endif /* !_ORBIT_CORBA_OBJECT_H_ */
++
++
++
+diff -urN linux-2.4.1/net/korbit/orb/corba_object_type.h linux-2.4.1-korbit/net/korbit/orb/corba_object_type.h
+--- linux-2.4.1/net/korbit/orb/corba_object_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_object_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,54 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_OBJECT_TYPE_H_
++#define _ORBIT_CORBA_OBJECT_TYPE_H_
++
++#include <sys/uio.h> /* for struct iovec */
++
++#include <IIOP/IIOP.h> /* for giop_connection */
++
++#include "corba_object.h"
++#include "corba_basic_sequences_type.h"
++
++#include "orbit_object_type.h"
++
++struct CORBA_Object_struct {
++ struct ORBit_RootObject_struct parent;
++ CORBA_ORB orb;
++ GIOPConnection *connection;
++ CORBA_char *object_id;
++ GSList *profile_list;
++ GSList *forward_locations;
++ ORBit_Object_info *active_profile; /* points at a member of profile_list or forward_locations */
++
++ /* Used for direct calls */
++ gpointer *vepv;
++ /* PortableServer_Servant - looping includes :( */ gpointer servant;
++ guint vepv_size;
++};
++
++
++#endif /* !_ORBIT_CORBA_OBJECT_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_orb.h linux-2.4.1-korbit/net/korbit/orb/corba_orb.h
+--- linux-2.4.1/net/korbit/orb/corba_orb.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_orb.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,48 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ORB_H_
++#define _ORBIT_CORBA_ORB_H_
++
++typedef char *CORBA_ORB_ObjectId;
++
++#ifndef CORBA_POLICY_TYPE
++#define CORBA_POLICY_TYPE 1
++/* We need to define this in corba_orb_type.h as well, sometimes... */
++typedef struct CORBA_Policy_type *CORBA_Policy;
++#endif
++
++typedef CORBA_unsigned_long CORBA_PolicyType;
++
++typedef struct CORBA_ORB_type *CORBA_ORB;
++
++typedef struct CORBA_DomainManager_type *CORBA_DomainManager;
++
++typedef struct CORBA_ConstructionPolicy_type *CORBA_ConstructionPolicy;
++
++#define ex_CORBA_ORB_InvalidName "IDL:CORBA/ORB/InvalidName:1.0"
++
++#endif /* !_ORBIT_CORBA_ORB_H_ */
++
+diff -urN linux-2.4.1/net/korbit/orb/corba_orb_type.h linux-2.4.1-korbit/net/korbit/orb/corba_orb_type.h
+--- linux-2.4.1/net/korbit/orb/corba_orb_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_orb_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,77 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_ORB_TYPE_H_
++#define _ORBIT_CORBA_ORB_TYPE_H_
++
++#include "corba_object.h"
++
++struct CORBA_ORB_type {
++ struct ORBit_PseudoObject_struct parent;
++ CORBA_ORBid orb_identifier;
++ CORBA_RepositoryId repoid;
++ CORBA_boolean use_poa;
++
++ CORBA_Object imr, ir, naming, root_poa;
++ struct {
++ GIOPConnection *ipv4;
++ GIOPConnection *ipv6;
++ GIOPConnection *usock;
++ } cnx;
++
++ GHashTable *objrefs;
++
++ GPtrArray *poas;
++
++ CORBA_Context default_ctx;
++};
++
++#define CORBA_ORB_CAST(orb) ((CORBA_ORB)orb)
++
++typedef struct CORBA_ORB_InvalidName {
++ int dummy;
++} CORBA_ORB_InvalidName;
++
++struct CORBA_Policy_type {
++ struct ORBit_PseudoObject_struct parent;
++ CORBA_PolicyType policy_type;
++};
++#ifndef CORBA_POLICY_TYPE
++#define CORBA_POLICY_TYPE 1
++typedef struct CORBA_Policy_type *CORBA_Policy;
++#endif
++
++struct CORBA_DomainManager_type {
++ struct ORBit_PseudoObject_struct parent;
++};
++
++#define CORBA_SecConstruction (11)
++
++struct CORBA_ConstructionPolicy_type {
++ int fill_me_in;
++};
++
++
++#endif /* !_ORBIT_CORBA_ORB_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_portableserver.h linux-2.4.1-korbit/net/korbit/orb/corba_portableserver.h
+--- linux-2.4.1/net/korbit/orb/corba_portableserver.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_portableserver.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,80 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_PORTABLESERVER_H_
++#define _ORBIT_CORBA_PORTABLESERVER_H_
++
++typedef struct PortableServer_ThreadPolicy_type *PortableServer_ThreadPolicy;
++typedef struct PortableServer_LifespanPolicy_type *PortableServer_LifespanPolicy;
++typedef struct PortableServer_IdUniquenessPolicy_type *PortableServer_IdUniquenessPolicy;
++typedef struct PortableServer_IdAssignmentPolicy_type *PortableServer_IdAssignmentPolicy;
++typedef struct PortableServer_ImplicitActivationPolicy_type *PortableServer_ImplicitActivationPolicy;
++typedef struct PortableServer_ServantRetentionPolicy_type *PortableServer_ServantRetentionPolicy;
++typedef struct PortableServer_RequestProcessingPolicy_type *PortableServer_RequestProcessingPolicy;
++typedef struct PortableServer_POAManager_type* PortableServer_POAManager;
++typedef struct PortableServer_AdapterActivator_type *PortableServer_AdapterActivator;
++typedef struct PortableServer_ServantManager_type *PortableServer_ServantManager;
++typedef struct PortableServer_ServantActivator_type *PortableServer_ServantActivator;
++typedef struct PortableServer_ServantLocator_type *PortableServer_ServantLocator;
++typedef struct PortableServer_POA_type *PortableServer_POA;
++typedef struct PortableServer_Current_type *PortableServer_Current;
++
++typedef enum {
++ PortableServer_ORB_CTRL_MODEL=0,
++ PortableServer_SINGLE_THREAD_MODEL
++} PortableServer_ThreadPolicyValue;
++
++typedef enum {
++ PortableServer_TRANSIENT=0,
++ PortableServer_PERSISTENT
++} PortableServer_LifespanPolicyValue;
++
++typedef enum {
++ PortableServer_UNIQUE_ID=0,
++ PortableServer_MULTIPLE_ID
++} PortableServer_IdUniquenessPolicyValue;
++
++typedef enum {
++ PortableServer_USER_ID=0,
++ PortableServer_SYSTEM_ID
++} PortableServer_IdAssignmentPolicyValue;
++
++typedef enum {
++ PortableServer_IMPLICIT_ACTIVATION=0,
++ PortableServer_NO_IMPLICIT_ACTIVATION
++} PortableServer_ImplicitActivationPolicyValue;
++
++typedef enum {
++ PortableServer_RETAIN=0,
++ PortableServer_NON_RETAIN
++} PortableServer_ServantRetentionPolicyValue;
++
++typedef enum {
++ PortableServer_USE_ACTIVE_OBJECT_MAP_ONLY=0,
++ PortableServer_USE_DEFAULT_SERVANT,
++ PortableServer_USE_SERVANT_MANAGER
++} PortableServer_RequestProcessingPolicyValue;
++
++#endif /* !_ORBIT_CORBA_PORTABLESERVER_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_portableserver_type.h linux-2.4.1-korbit/net/korbit/orb/corba_portableserver_type.h
+--- linux-2.4.1/net/korbit/orb/corba_portableserver_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_portableserver_type.h Thu Feb 1 11:47:11 2001
+@@ -0,0 +1,361 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_PORTABLESERVER_TYPE_H_
++#define _ORBIT_CORBA_PORTABLESERVER_TYPE_H_
++
++/* 19.26 */
++
++typedef void *PortableServer_ServantLocator_Cookie;
++typedef void *PortableServer_Servant;
++
++#ifndef _PortableServer_ForwardRequest_defined
++#define _PortableServer_ForwardRequest_defined
++
++typedef struct PortableServer_ForwardRequest {
++ CORBA_Object forward_reference;
++} PortableServer_ForwardRequest;
++
++#define ex_PortableServer_ForwardRequest "IDL:PortableServer/ForwardRequest:1.0"
++#endif /* !_PortableServer_ForwardRequest_defined */
++
++#define PortableServer_THREAD_POLICY_ID 16
++struct PortableServer_ThreadPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_ThreadPolicyValue value;
++};
++
++#define PortableServer_LIFESPAN_POLICY_ID 17
++extern const CORBA_PolicyType PortableServer_LifespanPolicy_PolicyType;
++struct PortableServer_LifespanPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_LifespanPolicyValue value;
++};
++
++#define PortableServer_ID_UNIQUENESS_POLICY_ID 18
++struct PortableServer_IdUniquenessPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_IdUniquenessPolicyValue value;
++};
++
++#define PortableServer_ID_ASSIGNMENT_POLICY_ID 19
++struct PortableServer_IdAssignmentPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_IdAssignmentPolicyValue value;
++};
++
++#define PortableServer_IMPLICIT_ACTIVATION_POLICY_ID 20
++struct PortableServer_ImplicitActivationPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_ImplicitActivationPolicyValue value;
++};
++
++#define PortableServer_SERVANT_RETENTION_POLICY_ID 21
++struct PortableServer_ServantRetentionPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_ServantRetentionPolicyValue value;
++};
++
++#define PortableServer_REQUEST_PROCESSING_POLICY_ID 22
++struct PortableServer_RequestProcessingPolicy_type {
++ struct CORBA_Policy_type corba_policy;
++ PortableServer_RequestProcessingPolicyValue value;
++};
++
++#ifndef _PortableServer_POAManager_AdapterInactive_defined
++#define _PortableServer_POAManager_AdapterInactive_defined
++
++typedef struct PortableServer_POAManager_AdapterInactive {
++ int fill_me_in;
++} PortableServer_POAManager_AdapterInactive;
++
++#define ex_PortableServer_POAManager_AdapterInactive "IDL:PortableServer/POAManager/AdapterInactive:1.0"
++#endif /* !_PortableServer_POAManager_AdapterInactive_defined */
++
++typedef enum { PortableServer_POAManager_HOLDING,
++ PortableServer_POAManager_ACTIVE,
++ PortableServer_POAManager_DISCARDING,
++ PortableServer_POAManager_INACTIVE
++} PortableServer_POAManager_State;
++
++struct PortableServer_POAManager_type {
++ struct ORBit_PseudoObject_struct parent;
++ GSList* poa_collection;
++ CORBA_ORB orb;
++ PortableServer_POAManager_State state;
++};
++
++struct PortableServer_AdapterActivator_type {
++ int fill_me_in;
++};
++
++struct PortableServer_ServantManager_type {
++ int fill_me_in;
++};
++
++#ifndef _PortableServer_POA_AdapterAlreadyExists_defined
++#define _PortableServer_POA_AdapterAlreadyExists_defined
++
++typedef struct PortableServer_POA_AdapterAlreadyExists {
++ int fill_me_in;
++} PortableServer_POA_AdapterAlreadyExists;
++
++#define ex_PortableServer_POA_AdapterAlreadyExists "IDL:PortableServer/POA/AdapterAlreadyExists:1.0"
++#endif /* !_PortableServer_POA_AdapterAlreadyExists_defined */
++
++#ifndef _PortableServer_POAManager_AdapterInactive_defined
++#define _PortableServer_POAManager_AdapterInactive_defined
++
++typedef struct PortableServer_POAManager_AdapterInactive {
++ int fill_me_in;
++} PortableServer_POAManager_AdapterInactive;
++
++#define ex_PortableServer_POAManager_AdapterInactive "IDL:PortableServer/POAManager/AdapterInactive:1.0"
++#endif /* !_PortableServer_POAManager_AdapterInactive_defined */
++
++#ifndef _PortableServer_POA_AdapterNonExistent_defined
++#define _PortableServer_POA_AdapterNonExistent_defined
++
++typedef struct PortableServer_POA_AdapterNonExistent {
++ int fill_me_in;
++} PortableServer_POA_AdapterNonExistent;
++
++#define ex_PortableServer_POA_AdapterNonExistent "IDL:PortableServer/POA/AdapterNonExistent:1.0"
++#endif /* !_PortableServer_POA_AdapterNonExistent_defined */
++
++#ifndef _PortableServer_POA_InvalidPolicy_defined
++#define _PortableServer_POA_InvalidPolicy_defined
++
++typedef struct PortableServer_POA_InvalidPolicy {
++ CORBA_unsigned_short index;
++} PortableServer_POA_InvalidPolicy;
++
++#define ex_PortableServer_POA_InvalidPolicy "IDL:PortableServer/POA/InvalidPolicy:1.0"
++#endif /* !_PortableServer_POA_InvalidPolicy_defined */
++
++#ifndef _PortableServer_POA_NoServant_defined
++#define _PortableServer_POA_NoServant_defined
++
++typedef struct PortableServer_POA_NoServant {
++ int fill_me_in;
++} PortableServer_POA_NoServant;
++
++#define ex_PortableServer_POA_NoServant "IDL:PortableServer/POA/NoServant:1.0"
++#endif /* !_PortableServer_POA_NoServant_defined */
++
++#ifndef _PortableServer_POA_ObjectAlreadyActive_defined
++#define _PortableServer_POA_ObjectAlreadyActive_defined
++
++typedef struct PortableServer_POA_ObjectAlreadyActive {
++ int fill_me_in;
++} PortableServer_POA_ObjectAlreadyActive;
++
++#define ex_PortableServer_POA_ObjectAlreadyActive "IDL:PortableServer/POA/ObjectAlreadyActive:1.0"
++#endif /* !_PortableServer_POA_ObjectAlreadyActive_defined */
++
++#ifndef _PortableServer_POA_ObjectNotActive_defined
++#define _PortableServer_POA_ObjectNotActive_defined
++
++typedef struct PortableServer_POA_ObjectNotActive {
++ int fill_me_in;
++} PortableServer_POA_ObjectNotActive;
++
++#define ex_PortableServer_POA_ObjectNotActive "IDL:PortableServer/POA/ObjectNotActive:1.0"
++#endif /* !_PortableServer_POA_ObjectNotActive_defined */
++
++#ifndef _PortableServer_POA_ServantAlreadyActive_defined
++#define _PortableServer_POA_ServantAlreadyActive_defined
++
++typedef struct PortableServer_POA_ServantAlreadyActive {
++ int fill_me_in;
++} PortableServer_POA_ServantAlreadyActive;
++
++#define ex_PortableServer_POA_ServantAlreadyActive "IDL:PortableServer/POA/ServantAlreadyActive:1.0"
++#endif /* !_PortableServer_POA_ServantAlreadyActive_defined */
++
++#ifndef _PortableServer_POA_ServantNotActive_defined
++#define _PortableServer_POA_ServantNotActive_defined
++
++typedef struct PortableServer_POA_ServantNotActive {
++ int fill_me_in;
++} PortableServer_POA_ServantNotActive;
++
++#define ex_PortableServer_POA_ServantNotActive "IDL:PortableServer/POA/ServantNotActive:1.0"
++#endif /* !_PortableServer_POA_ServantNotActive_defined */
++
++#ifndef _PortableServer_POA_WrongAdapter_defined
++#define _PortableServer_POA_WrongAdapter_defined
++
++typedef struct PortableServer_POA_WrongAdapter {
++ int fill_me_in;
++} PortableServer_POA_WrongAdapter;
++
++#define ex_PortableServer_POA_WrongAdapter "IDL:PortableServer/POA/WrongAdapter:1.0"
++#endif /* !_PortableServer_POA_WrongAdapter_defined */
++
++#ifndef _PortableServer_POA_WrongPolicy_defined
++#define _PortableServer_POA_WrongPolicy_defined
++
++typedef struct PortableServer_POA_WrongPolicy {
++ int fill_me_in;
++} PortableServer_POA_WrongPolicy;
++
++#define ex_PortableServer_POA_WrongPolicy "IDL:PortableServer/POA/WrongPolicy:1.0"
++#endif /* !_PortableServer_POA_WrongPolicy_defined */
++
++#ifndef _PortableServer_Current_NoContext_defined
++#define _PortableServer_Current_NoContext_defined
++
++typedef struct PortableServer_Current_NoContext {
++ int fill_me_in;
++} PortableServer_Current_NoContext;
++
++#define ex_PortableServer_Current_NoContext "IDL:PortableServer/Current/NoContext:1.0"
++#endif /* !_PortableServer_Current_NoContext_defined */
++
++struct PortableServer_Current_type {
++ int fill_me_in;
++};
++
++typedef struct PortableServer_ServantBase__epv {
++ void *_private;
++ void (*finalize)(PortableServer_Servant, CORBA_Environment *);
++ PortableServer_POA (*default_POA)(PortableServer_Servant, CORBA_Environment *);
++} PortableServer_ServantBase__epv;
++
++typedef PortableServer_ServantBase__epv *PortableServer_ServantBase__vepv;
++
++typedef struct PortableServer_ServantBase {
++ void *_private;
++ PortableServer_ServantBase__vepv *vepv;
++} PortableServer_ServantBase;
++
++/* 19.27 */
++
++typedef void (*PortableServer_DynamicImplRoutine) (PortableServer_Servant servant, CORBA_ServerRequest request);
++
++typedef struct PortableServer_DynamicImpl__epv {
++ void *_private;
++ PortableServer_DynamicImplRoutine invoke;
++ CORBA_RepositoryId (*primary_interface) (PortableServer_Servant svt, PortableServer_ObjectId id, PortableServer_POA poa, CORBA_Environment *env);
++} PortableServer_DynamicImpl__epv;
++
++typedef struct PortableServer_DynamicImpl__vepv {
++ PortableServer_ServantBase__epv *_base_epv;
++ PortableServer_DynamicImpl__epv *PortableServer_DynamicImpl_epv;
++} PortableServer_DynamicImpl__vepv;
++
++typedef struct PortableServer_DynamicImpl {
++ void *_private;
++ PortableServer_DynamicImpl__vepv *vepv;
++} PortableServer_DynamicImpl;
++
++typedef struct {
++ void *_private;
++} POA_PortableServer_ServantManager__epv;
++
++typedef struct {
++ void *_private;
++
++ PortableServer_Servant (*incarnate) (PortableServer_Servant servant,
++ PortableServer_ObjectId * oid,
++ PortableServer_POA adapter,
++ CORBA_Environment * ev);
++
++ void (*etherealize) (PortableServer_Servant servant,
++ PortableServer_ObjectId* oid,
++ PortableServer_POA adapter,
++ PortableServer_Servant serv,
++ CORBA_boolean cleanup_in_progress,
++ CORBA_boolean remaining_activations,
++ CORBA_Environment * ev);
++
++} POA_PortableServer_ServantActivator__epv;
++
++typedef struct {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_PortableServer_ServantManager__epv *PortableServer_ServantManager_epv;
++ POA_PortableServer_ServantActivator__epv *PortableServer_ServantActivator_epv;
++} POA_PortableServer_ServantActivator__vepv;
++
++typedef struct {
++ void *_private;
++ POA_PortableServer_ServantActivator__vepv *vepv;
++} POA_PortableServer_ServantActivator;
++
++extern void
++POA_PortableServer_ServantActivator__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++extern void
++POA_PortableServer_ServantActivator__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++
++typedef struct {
++ void *_private;
++
++ PortableServer_Servant (*preinvoke) (PortableServer_Servant servant,
++ PortableServer_ObjectId * oid,
++ PortableServer_POA adapter,
++ CORBA_Identifier operation,
++ PortableServer_ServantLocator_Cookie *the_cookie,
++ CORBA_Environment * ev);
++
++ void (*postinvoke) (PortableServer_Servant servant,
++ PortableServer_ObjectId * oid,
++ PortableServer_POA adapter,
++ CORBA_Identifier operation,
++ PortableServer_ServantLocator_Cookie the_cookie,
++ PortableServer_Servant the_servant,
++ CORBA_Environment * ev);
++} POA_PortableServer_ServantLocator__epv;
++
++typedef struct {
++ PortableServer_ServantBase__epv *_base_epv;
++ POA_PortableServer_ServantManager__epv *PortableServer_ServantManager_epv;
++ POA_PortableServer_ServantLocator__epv *PortableServer_ServantLocator_epv;
++} POA_PortableServer_ServantLocator__vepv;
++
++typedef struct {
++ void *_private;
++ POA_PortableServer_ServantLocator__vepv *vepv;
++} POA_PortableServer_ServantLocator;
++
++extern void
++POA_PortableServer_ServantLocator__init(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++extern void
++POA_PortableServer_ServantLocator__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev);
++
++struct CORBA_ServerRequest_type {
++ struct ORBit_PseudoObject_struct parent;
++ GIOPRecvBuffer *rbuf;
++ GIOPSendBuffer *sbuf;
++ CORBA_NVList *params;
++ CORBA_ORB orb;
++ guchar did_ctx, did_exc;
++};
++
++#endif /* !_ORBIT_CORBA_PORTABLESERVER_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_sequences.h linux-2.4.1-korbit/net/korbit/orb/corba_sequences.h
+--- linux-2.4.1/net/korbit/orb/corba_sequences.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_sequences.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,74 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_SEQUENCES_H_
++#define _ORBIT_CORBA_SEQUENCES_H_
++
++
++/* moved from sequences.h */
++#include "corba_basic_sequences_type.h"
++
++typedef CORBA_sequence_octet CORBA_ReferenceData;
++
++#define _CORBA_sequence_ServiceOption_defined
++typedef struct CORBA_sequence_ServiceOption CORBA_sequence_ServiceOption;
++
++#define _CORBA_sequence_ServiceDetail_defined
++typedef struct CORBA_sequence_ServiceDetail CORBA_sequence_ServiceDetail;
++
++#define _CORBA_sequence_ORB_ObjectId_defined
++typedef struct CORBA_sequence_ORB_ObjectId CORBA_ORB_ObjectIdList;
++
++#define _CORBA_sequence_NameValuePair_defined
++typedef struct CORBA_sequence_NameValuePair CORBA_NameValuePairSeq;
++
++#define _CORBA_sequence_CORBA_any_defined
++typedef struct CORBA_sequence_CORBA_any_struct CORBA_AnySeq;
++typedef struct CORBA_sequence_CORBA_any_struct CORBA_sequence_CORBA_any;
++
++#define _CORBA_sequence_Policy_defined
++typedef struct CORBA_sequence_Policy CORBA_PolicyList;
++
++#define _CORBA_sequence_DomainManager_defined
++typedef struct CORBA_sequence_DomainManager CORBA_DomainManagerList;
++
++#define _PortableServer_sequence_octet_defined
++typedef struct PortableServer_sequence_octet PortableServer_ObjectId;
++
++
++/* Moved from orbit_types.h */
++#ifndef HAVE_CORBA_PRINCIPAL
++#define HAVE_CORBA_PRINCIPAL 1
++typedef CORBA_sequence_octet CORBA_Principal;
++#endif
++typedef CORBA_sequence_octet CORBA_DynAny_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynFixed_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynEnum_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynStruct_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynUnion_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynSequence_OctetSeq;
++typedef CORBA_sequence_octet CORBA_DynArray_OctetSeq;
++
++#endif /* !_ORBIT_CORBA_SEQUENCES_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_sequences_type.h linux-2.4.1-korbit/net/korbit/orb/corba_sequences_type.h
+--- linux-2.4.1/net/korbit/orb/corba_sequences_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_sequences_type.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,98 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_SEQUENCES_TYPE_H_
++#define _ORBIT_CORBA_SEQUENCES_TYPE_H_
++
++#include "corba_sequences.h"
++
++struct CORBA_sequence_ServiceOption {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_ServiceOption *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_ServiceDetail {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_ServiceDetail *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_ORB_ObjectId {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_ORB_ObjectId *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_NameValuePair {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ struct CORBA_NameValuePair *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_CORBA_any_struct {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_any *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_Policy {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_Policy *_buffer;
++ CORBA_boolean _release;
++};
++
++struct CORBA_sequence_DomainManager {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_DomainManager *_buffer;
++ CORBA_boolean _release;
++};
++
++struct PortableServer_sequence_octet {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CORBA_octet *_buffer;
++ CORBA_boolean _release;
++};
++
++/* Generic sequence */
++struct CORBA_Sequence_type {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ void *_buffer;
++ CORBA_boolean _release;
++};
++
++#define CORBA_SEQFLAGS_RELEASE 1
++
++
++#endif /* !_ORBIT_CORBA_SEQUENCES_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/corba_typecode.h linux-2.4.1-korbit/net/korbit/orb/corba_typecode.h
+--- linux-2.4.1/net/korbit/orb/corba_typecode.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_typecode.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,167 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_TYPECODE_H_
++#define _ORBIT_CORBA_TYPECODE_H_
++
++/* moved from orbit_types.h */
++typedef struct CORBA_TypeCode_struct *CORBA_TypeCode;
++
++typedef enum {
++ CORBA_tk_null=0,
++ CORBA_tk_void=1,
++ CORBA_tk_short=2,
++ CORBA_tk_long=3,
++ CORBA_tk_ushort=4,
++ CORBA_tk_ulong=5,
++ CORBA_tk_float=6,
++ CORBA_tk_double=7,
++ CORBA_tk_boolean=8,
++ CORBA_tk_char=9,
++ CORBA_tk_octet=10,
++ CORBA_tk_any=11,
++ CORBA_tk_TypeCode=12,
++ CORBA_tk_Principal=13,
++ CORBA_tk_objref=14,
++ CORBA_tk_struct=15,
++ CORBA_tk_union=16,
++ CORBA_tk_enum=17,
++ CORBA_tk_string=18,
++ CORBA_tk_sequence=19,
++ CORBA_tk_array=20,
++ CORBA_tk_alias=21,
++ CORBA_tk_except=22,
++ CORBA_tk_longlong=23,
++ CORBA_tk_ulonglong=24,
++ CORBA_tk_longdouble=25,
++ CORBA_tk_wchar=26,
++ CORBA_tk_wstring=27,
++ CORBA_tk_fixed=28,
++ CORBA_tk_recursive=0xffffffff,
++ CORBA_tk_last=29 /* hack for GIOP */
++} CORBA_TCKind;
++
++#define TC_CORBA_short TC_short
++#define TC_CORBA_long TC_long
++#define TC_CORBA_longlong TC_longlong
++#define TC_CORBA_long_long TC_longlong
++#define TC_CORBA_ushort TC_ushort
++#define TC_CORBA_unsigned_short TC_ushort
++#define TC_CORBA_ulong TC_ulong
++#define TC_CORBA_unsigned_long TC_ulong
++#define TC_CORBA_ulonglong TC_ulonglong
++#define TC_CORBA_unsigned_long_long TC_ulonglong
++#define TC_CORBA_float TC_float
++#define TC_CORBA_double TC_double
++#define TC_CORBA_longdouble TC_longdouble
++#define TC_CORBA_long_double TC_longdouble
++#define TC_CORBA_boolean TC_boolean
++#define TC_CORBA_char TC_char
++#define TC_CORBA_wchar TC_wchar
++#define TC_CORBA_octet TC_octet
++#define TC_CORBA_any TC_any
++#define TC_CORBA_TypeCode TC_TypeCode
++#define TC_CORBA_Principal TC_Principal
++#define TC_CORBA_Object TC_Object
++#define TC_CORBA_string TC_string
++#define TC_CORBA_wstring TC_wstring
++
++#define TC_null ((CORBA_TypeCode)&TC_null_struct)
++#define TC_void ((CORBA_TypeCode)&TC_void_struct)
++#define TC_short ((CORBA_TypeCode)&TC_short_struct)
++#define TC_long ((CORBA_TypeCode)&TC_long_struct)
++#define TC_longlong ((CORBA_TypeCode)&TC_longlong_struct)
++#define TC_ushort ((CORBA_TypeCode)&TC_ushort_struct)
++#define TC_ulong ((CORBA_TypeCode)&TC_ulong_struct)
++#define TC_ulonglong ((CORBA_TypeCode)&TC_ulonglong_struct)
++#define TC_float ((CORBA_TypeCode)&TC_float_struct)
++#define TC_double ((CORBA_TypeCode)&TC_double_struct)
++#define TC_longdouble ((CORBA_TypeCode)&TC_longdouble_struct)
++#define TC_boolean ((CORBA_TypeCode)&TC_boolean_struct)
++#define TC_char ((CORBA_TypeCode)&TC_char_struct)
++#define TC_wchar ((CORBA_TypeCode)&TC_wchar_struct)
++#define TC_octet ((CORBA_TypeCode)&TC_octet_struct)
++#define TC_any ((CORBA_TypeCode)&TC_any_struct)
++#define TC_TypeCode ((CORBA_TypeCode)&TC_TypeCode_struct)
++#define TC_Principal ((CORBA_TypeCode)&TC_Principal_struct)
++#define TC_Object ((CORBA_TypeCode)&TC_Object_struct)
++#define TC_string ((CORBA_TypeCode)&TC_string_struct)
++#define TC_wstring ((CORBA_TypeCode)&TC_wstring_struct)
++#define TC_CORBA_NamedValue ((CORBA_TypeCode)&TC_CORBA_NamedValue_struct)
++
++#define TC_CORBA_short_struct TC_short_struct
++#define TC_CORBA_long_struct TC_long_struct
++#define TC_CORBA_longlong_struct TC_longlong_struct
++#define TC_CORBA_long_long_struct TC_longlong_struct
++#define TC_CORBA_ushort_struct TC_ushort_struct
++#define TC_CORBA_unsigned_short_struct TC_ushort_struct
++#define TC_CORBA_ulong_struct TC_ulong_struct
++#define TC_CORBA_unsigned_long_struct TC_ulong_struct
++#define TC_CORBA_ulonglong_struct TC_ulonglong_struct
++#define TC_CORBA_unsigned_long_long_struct TC_ulonglong_struct
++#define TC_CORBA_float_struct TC_float_struct
++#define TC_CORBA_double_struct TC_double_struct
++#define TC_CORBA_longdouble_struct TC_longdouble_struct
++#define TC_CORBA_long_double_struct TC_longdouble_struct
++#define TC_CORBA_boolean_struct TC_boolean_struct
++#define TC_CORBA_char_struct TC_char_struct
++#define TC_CORBA_wchar_struct TC_wchar_struct
++#define TC_CORBA_octet_struct TC_octet_struct
++#define TC_CORBA_any_struct TC_any_struct
++#define TC_CORBA_TypeCode_struct TC_TypeCode_struct
++#define TC_CORBA_Principal_struct TC_Principal_struct
++#define TC_CORBA_Object_struct TC_Object_struct
++#define TC_CORBA_string_struct TC_string_struct
++#define TC_CORBA_wstring_struct TC_wstring_struct
++
++extern const struct CORBA_TypeCode_struct TC_null_struct;
++extern const struct CORBA_TypeCode_struct TC_void_struct;
++extern const struct CORBA_TypeCode_struct TC_short_struct;
++extern const struct CORBA_TypeCode_struct TC_long_struct;
++extern const struct CORBA_TypeCode_struct TC_longlong_struct;
++extern const struct CORBA_TypeCode_struct TC_ushort_struct;
++extern const struct CORBA_TypeCode_struct TC_ulong_struct;
++extern const struct CORBA_TypeCode_struct TC_ulonglong_struct;
++extern const struct CORBA_TypeCode_struct TC_float_struct;
++extern const struct CORBA_TypeCode_struct TC_double_struct;
++extern const struct CORBA_TypeCode_struct TC_longdouble_struct;
++extern const struct CORBA_TypeCode_struct TC_boolean_struct;
++extern const struct CORBA_TypeCode_struct TC_char_struct;
++extern const struct CORBA_TypeCode_struct TC_wchar_struct;
++extern const struct CORBA_TypeCode_struct TC_octet_struct;
++extern const struct CORBA_TypeCode_struct TC_any_struct;
++extern const struct CORBA_TypeCode_struct TC_TypeCode_struct;
++extern const struct CORBA_TypeCode_struct TC_Principal_struct;
++extern const struct CORBA_TypeCode_struct TC_Object_struct;
++extern const struct CORBA_TypeCode_struct TC_string_struct;
++extern const struct CORBA_TypeCode_struct TC_wstring_struct;
++extern const struct CORBA_TypeCode_struct TC_CORBA_NamedValue_struct;
++
++
++#endif /* !_ORBIT_CORBA_TYPECODE_H_ */
++
++
++
++
+diff -urN linux-2.4.1/net/korbit/orb/corba_typecode_type.h linux-2.4.1-korbit/net/korbit/orb/corba_typecode_type.h
+--- linux-2.4.1/net/korbit/orb/corba_typecode_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/corba_typecode_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,66 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_CORBA_TYPECODE_TYPE_H_
++#define _ORBIT_CORBA_TYPECODE_TYPE_H_
++
++#include <ORBitutil/basic_types.h>
++#include "corba_typecode.h"
++#include "corba_any.h"
++
++typedef struct CORBA_TypeCode_Bounds {
++ int dummy;
++} CORBA_TypeCode_Bounds;
++
++typedef struct CORBA_TypeCode_BadKind {
++ int dummy;
++} CORBA_TypeCode_BadKind;
++
++struct CORBA_TypeCode_struct {
++ struct ORBit_PseudoObject_struct parent;
++ CORBA_TCKind kind;
++#ifndef __KORBIT__
++ const
++#endif
++ char *name;
++#ifndef __KORBIT__
++ const
++#endif
++ char *repo_id;
++ CORBA_unsigned_long length;
++ CORBA_unsigned_long sub_parts;
++ const char **subnames; /* for struct, exception, union, enum */
++ CORBA_TypeCode *subtypes; /* for struct, exception, union, alias, array, sequence */
++ CORBA_any *sublabels; /* for union */
++ CORBA_TypeCode discriminator; /* for union */
++ CORBA_unsigned_long recurse_depth; /* for recursive sequence */
++ CORBA_long default_index; /* for union */
++ CORBA_unsigned_short digits; /* for fixed */
++ CORBA_short scale; /* for fixed */
++};
++
++
++#endif /* !_ORBIT_CORBA_TYPECODE_TYPE_H_ */
++
+diff -urN linux-2.4.1/net/korbit/orb/dii.c linux-2.4.1-korbit/net/korbit/orb/dii.c
+--- linux-2.4.1/net/korbit/orb/dii.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/dii.c Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,454 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Red Hat Software, Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Elliot Lee <sopwith@redhat.com>
++ * Dick Porter <dick@cymru.net>
++ *
++ */
++
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++
++#include "orbit.h"
++#ifndef __KORBIT__
++#include "interface_repository.h"
++#endif /* !__KORBIT__ */
++
++struct CORBA_Request_type {
++ struct ORBit_PseudoObject_struct parent;
++
++ CORBA_Object obj;
++ CORBA_Context ctx;
++
++ CORBA_Flags req_flags;
++ CORBA_Identifier operation;
++
++ CORBA_NamedValue *result;
++ CORBA_NVList *arg_list;
++
++ CORBA_unsigned_long request_id;
++ GIOPSendBuffer *request_buffer;
++ GIOPRecvBuffer *reply_buffer;
++};
++
++static const ORBit_RootObject_Interface interface_CORBA_Request = {
++ (void (*)(gpointer,CORBA_Environment *))CORBA_Request_delete
++};
++
++/* Section 5.2.1 */
++CORBA_Status
++CORBA_Object_create_request(CORBA_Object obj,
++ CORBA_Context ctx,
++ CORBA_Identifier operation,
++ CORBA_NVList *arg_list,
++ CORBA_NamedValue *result,
++ CORBA_Request *request,
++ CORBA_Flags req_flags,
++ CORBA_Environment *ev)
++{
++ CORBA_Request new;
++
++ new=g_new0(struct CORBA_Request_type, 1);
++ ORBit_pseudo_object_init((ORBit_PseudoObject)new, ORBIT_PSEUDO_REQUEST, ev);
++ ORBit_RootObject_set_interface((ORBit_RootObject)new,
++ (ORBit_RootObject_Interface *)&interface_CORBA_Request, ev);
++
++ if(new==NULL) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_NO_MEMORY,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ new->obj=CORBA_Object_duplicate(obj, ev);
++ new->ctx=(CORBA_Context)CORBA_Object_duplicate((CORBA_Object)ctx, ev);
++ new->operation=CORBA_string_dup(operation);
++
++ new->result=result;
++
++ new->req_flags=req_flags;
++ new->request_id = giop_get_request_id();
++ new->arg_list = arg_list;
++
++ *request=(CORBA_Request)CORBA_Object_duplicate((CORBA_Object)new, ev);
++}
++
++/* Section 5.2, 5.2.2 */
++CORBA_Status
++CORBA_Request_add_arg(CORBA_Request req,
++ CORBA_Identifier name,
++ CORBA_TypeCode arg_type,
++ void *value,
++ CORBA_long len,
++ CORBA_Flags arg_flags,
++ CORBA_Environment *ev)
++{
++ gpointer new_value;
++
++ g_assert(req!=NULL);
++
++ if((arg_flags & CORBA_IN_COPY_VALUE) && (arg_flags & CORBA_ARG_IN)) {
++ new_value = ORBit_copy_value(value, arg_type);
++ if(new_value==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++ } else
++ new_value=value;
++
++ CORBA_NVList_add_item(req->arg_list, name, arg_type,
++ new_value, len, arg_flags | req->req_flags, ev);
++}
++
++/* Section 5.2, 5.2.3 */
++CORBA_Status
++CORBA_Request_invoke(CORBA_Request req,
++ CORBA_Flags invoke_flags,
++ CORBA_Environment *ev)
++{
++ CORBA_Request_send(req, invoke_flags, ev);
++ if(ev->_major == CORBA_NO_EXCEPTION)
++ CORBA_Request_get_response(req, invoke_flags, ev);
++}
++
++/* Section 5.2, 5.2.4 */
++CORBA_Status CORBA_Request_delete(CORBA_Request req, CORBA_Environment *ev)
++{
++ CORBA_Object_release(req->obj, ev);
++ CORBA_Object_release((CORBA_Object)req->ctx, ev);
++
++ if(req->operation != NULL)
++ CORBA_free(req->operation);
++
++ if(req->arg_list != NULL) {
++ if(req->req_flags & CORBA_OUT_LIST_MEMORY)
++ CORBA_NVList_free(req->arg_list, ev);
++ else {
++ int i;
++ for(i = 0; i < req->arg_list->list->len; i++)
++ ORBit_NamedValue_free(&g_array_index(req->arg_list->list,
++ CORBA_NamedValue, i));
++ g_array_free(req->arg_list->list, TRUE);
++
++ g_free(req->arg_list);
++ }
++ }
++
++ if(req->result!=NULL)
++ ORBit_NamedValue_free(req->result);
++
++ if(req->request_buffer)
++ giop_send_buffer_unuse(req->request_buffer);
++
++ if(req->reply_buffer)
++ giop_recv_buffer_unuse(req->reply_buffer);
++
++ g_free(req);
++}
++
++/* Section 5.2, 5.3.1 */
++CORBA_Status
++CORBA_Request_send(CORBA_Request req,
++ CORBA_Flags invoke_flags,
++ CORBA_Environment *ev)
++{
++ int i;
++ GIOPConnection *cnx;
++
++ struct { CORBA_unsigned_long opstrlen; char opname[1]; } *opnameinfo;
++ struct iovec opvec = { NULL, 0 };
++
++ opvec.iov_len = strlen(req->operation)+1+sizeof(CORBA_unsigned_long);
++
++ opnameinfo = g_malloc(strlen(req->operation)+1+sizeof(CORBA_unsigned_long));
++ opvec.iov_base = (gpointer)opnameinfo;
++ opnameinfo->opstrlen = strlen(req->operation) + 1;
++ strcpy(opnameinfo->opname, req->operation);
++
++ cnx = ORBit_object_get_connection(req->obj);
++
++ g_assert(req->obj->active_profile);
++ req->request_buffer =
++ giop_send_request_buffer_use(req->obj->connection,
++ NULL,
++ req->request_id,
++ req->result?TRUE:FALSE,
++ &(req->obj->active_profile->object_key_vec),
++ &opvec,
++ &ORBit_default_principal_iovec
++ );
++
++ if(!req->request_buffer) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_COMM_FAILURE,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ for(i = 0; i < req->arg_list->list->len; i++) {
++ CORBA_NamedValue *nv;
++
++ nv = &g_array_index(req->arg_list->list, CORBA_NamedValue, i);
++
++ if((nv->arg_modes & CORBA_ARG_IN)
++ || (nv->arg_modes & CORBA_ARG_INOUT))
++ ORBit_marshal_arg(req->request_buffer,
++ nv->argument._value,
++ nv->argument._type);
++ }
++
++ giop_send_buffer_write(req->request_buffer);
++
++ giop_send_buffer_unuse(req->request_buffer);
++ req->request_buffer = 0;
++
++ g_free(opnameinfo);
++}
++
++/* Section 5.3.2 */
++CORBA_Status
++CORBA_send_multiple_requests(CORBA_Request *reqs,
++ CORBA_Environment *env,
++ CORBA_long count,
++ CORBA_Flags invoke_flags)
++{
++ int i;
++
++ for(i = 0; i < count; i++)
++ CORBA_Request_send(reqs[i], invoke_flags, env);
++}
++
++void
++ORBit_handle_dii_reply(CORBA_Request req, CORBA_Environment *ev)
++{
++ int i;
++
++ /* XXX TODO - handle exceptions, location forwards(?), all that */
++ req->result->argument._value =
++ ORBit_demarshal_arg(req->reply_buffer, req->result->argument._type,
++ TRUE, req->obj->orb);
++ req->result->argument._release = CORBA_TRUE;
++
++ for(i = 0; i < req->arg_list->list->len; i++) {
++ CORBA_NamedValue *nv;
++
++ nv = &g_array_index(req->arg_list->list, CORBA_NamedValue, i);
++
++ if(nv->arg_modes & CORBA_ARG_INOUT) {
++ CORBA_Object_duplicate((CORBA_Object)nv->argument._type, NULL);
++ CORBA_any__free(&nv->argument, NULL, TRUE);
++ }
++
++ if((nv->arg_modes & CORBA_ARG_OUT)
++ || (nv->arg_modes & CORBA_ARG_INOUT))
++ nv->argument._value = ORBit_demarshal_arg(req->reply_buffer,
++ nv->argument._type,
++ TRUE, req->obj->orb);
++ }
++
++ giop_recv_buffer_unuse(req->reply_buffer);
++ req->reply_buffer = 0;
++}
++
++/* Section 5.2, 5.3.3
++ *
++ * Raises: WrongTransaction
++ */
++CORBA_Status
++CORBA_Request_get_response(CORBA_Request req,
++ CORBA_Flags response_flags,
++ CORBA_Environment *ev)
++{
++ req->reply_buffer = giop_recv_reply_buffer_use(req->request_id,
++ !(response_flags & CORBA_RESP_NO_WAIT));
++
++ if(!req->reply_buffer) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_COMM_FAILURE,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ ORBit_handle_dii_reply(req, ev);
++}
++
++/* Section 5.3.4
++ *
++ * Raises: WrongTransaction
++ */
++CORBA_Status
++CORBA_Request_get_next_response(CORBA_Environment *env,
++ CORBA_Flags response_flags,
++ CORBA_Request *req)
++{
++ int i;
++ GIOPRecvBuffer *rb;
++ GArray *reqids = g_array_new(FALSE, FALSE,
++ sizeof(CORBA_unsigned_long));
++
++ for(i = 0; req[i]; i++) {
++ g_array_append_val(reqids, req[i]->request_id);
++ }
++
++ rb = giop_recv_reply_buffer_use_multiple(reqids,
++ !(response_flags & CORBA_RESP_NO_WAIT));
++
++ if(rb) {
++ for(i = 0; i < reqids->len; i++) {
++ if(g_array_index(reqids, CORBA_unsigned_long, i)
++ == rb->message.u.reply.request_id) {
++ req[i]->reply_buffer = rb;
++ break;
++ }
++ }
++
++ if(i < reqids->len)
++ ORBit_handle_dii_reply(req[i], env);
++ }
++
++ g_array_free(reqids, TRUE);
++}
++
++
++/* Section 5.4.1 */
++CORBA_Status
++CORBA_ORB_create_list(CORBA_ORB orb,
++ CORBA_long count,
++ CORBA_NVList **new_list,
++ CORBA_Environment *ev)
++{
++ CORBA_NVList *new;
++
++ new = g_new0(CORBA_NVList, 1);
++ if(new==NULL) goto new_alloc_failed;
++
++ new->list = g_array_new(FALSE, TRUE, sizeof(CORBA_NamedValue));
++
++ *new_list = new;
++
++ return;
++
++ new_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++}
++
++#ifndef __KORBIT__
++/* Section 5.4.6 */
++CORBA_Status
++CORBA_ORB_create_operation_list(CORBA_ORB orb,
++ CORBA_OperationDef oper,
++ CORBA_NVList **new_list,
++ CORBA_Environment *ev)
++{
++ if(!new_list) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ g_warning("CORBA_ORB_create_operation_list NYI");
++
++ CORBA_exception_set_system(ev,
++ ex_CORBA_IMP_LIMIT,
++ CORBA_COMPLETED_NO);
++}
++#endif /* !__KORBIT__ */
++
++/* Section 5.4.2 */
++CORBA_Status
++CORBA_NVList_add_item(CORBA_NVList *list,
++ CORBA_Identifier item_name,
++ CORBA_TypeCode item_type,
++ void *value,
++ CORBA_long value_len,
++ CORBA_Flags item_flags,
++ CORBA_Environment *ev)
++{
++ CORBA_NamedValue newval;
++
++ g_assert(list!=NULL);
++
++ newval.name = CORBA_string_dup(item_name);
++ newval.argument._type = (CORBA_TypeCode)CORBA_Object_duplicate((CORBA_Object)item_type, ev);
++ if(item_flags & CORBA_IN_COPY_VALUE) {
++ newval.argument._value = ORBit_copy_value(value, item_type);
++ newval.argument._release = CORBA_TRUE;
++ } else {
++ newval.argument._value = value;
++ newval.argument._release = CORBA_FALSE;
++ }
++
++ newval.len = value_len; /* Is this even useful? *sigh* */
++ newval.arg_modes = item_flags;
++
++ g_array_append_val(list->list, newval);
++}
++
++void ORBit_NamedValue_free(CORBA_NamedValue *nv)
++{
++ CORBA_free(nv->name);
++}
++
++/* Section 5.4.3 */
++CORBA_Status
++CORBA_NVList_free(CORBA_NVList *list,
++ CORBA_Environment *ev)
++{
++ int i;
++
++ CORBA_NVList_free_memory(list, ev);
++
++ for(i = 0; i < list->list->len; i++)
++ ORBit_NamedValue_free(&g_array_index(list->list, CORBA_NamedValue, i));
++
++ g_array_free(list->list, TRUE);
++
++ g_free(list);
++}
++
++/* Section 5.4.4 */
++CORBA_Status
++CORBA_NVList_free_memory(CORBA_NVList *list,
++ CORBA_Environment *ev)
++{
++ int i;
++
++ for(i = 0; i < list->list->len; i++) {
++ CORBA_free(g_array_index(list->list, CORBA_NamedValue, i).argument._value);
++ g_array_index(list->list, CORBA_NamedValue, i).argument._value = NULL;
++ CORBA_Object_release((CORBA_Object)g_array_index(list->list, CORBA_NamedValue, i).argument._type, ev);
++ g_array_index(list->list, CORBA_NamedValue, i).argument._release = CORBA_FALSE;
++ }
++}
++
++
++/* Section 5.4.5 */
++CORBA_Status
++CORBA_NVList_get_count(CORBA_NVList *list,
++ CORBA_long *count,
++ CORBA_Environment *ev)
++{
++ *count = list->list->len;
++}
++
+diff -urN linux-2.4.1/net/korbit/orb/dii.h linux-2.4.1-korbit/net/korbit/orb/dii.h
+--- linux-2.4.1/net/korbit/orb/dii.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/dii.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,124 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_DII_H_
++#define _ORBIT_DII_H_
++
++#include "orb/orbit_types.h"
++#ifndef __KORBIT__
++#include "orb/interface_repository.h"
++#endif /* !__KORBIT__ */
++
++extern CORBA_Status CORBA_Object_create_request(
++ CORBA_Object obj,
++ CORBA_Context ctx,
++ CORBA_Identifier operation,
++ CORBA_NVList *arg_list,
++ CORBA_NamedValue *result,
++ CORBA_Request *request,
++ CORBA_Flags req_flags,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Request_add_arg(
++ CORBA_Request req,
++ CORBA_Identifier name,
++ CORBA_TypeCode arg_type,
++ void *value,
++ CORBA_long len,
++ CORBA_Flags arg_flags,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Request_invoke(
++ CORBA_Request req,
++ CORBA_Flags invoke_flags,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Request_delete(
++ CORBA_Request req,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_Request_send(
++ CORBA_Request req,
++ CORBA_Flags invoke_flags,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_send_multiple_requests(
++ CORBA_Request reqs[],
++ CORBA_Environment *env,
++ CORBA_long count,
++ CORBA_Flags invoke_flags);
++
++extern CORBA_Status CORBA_Request_get_response(
++ CORBA_Request req,
++ CORBA_Flags response_flags,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_get_next_response(
++ CORBA_Environment *env,
++ CORBA_Flags response_flags,
++ CORBA_Request *req);
++
++extern CORBA_Status CORBA_NVList_add_item(
++ CORBA_NVList *list,
++ CORBA_Identifier item_name,
++ CORBA_TypeCode item_type,
++ void *value,
++ CORBA_long value_len,
++ CORBA_Flags item_flags,
++ CORBA_Environment *ev);
++
++extern void ORBit_NamedValue_free(
++ CORBA_NamedValue *nv);
++
++
++extern CORBA_Status CORBA_ORB_create_list(
++ CORBA_ORB orb,
++ CORBA_long count,
++ CORBA_NVList **new_list,
++ CORBA_Environment *ev);
++
++#ifndef __KORBIT__
++extern CORBA_Status CORBA_ORB_create_operation_list(
++ CORBA_ORB orb,
++ CORBA_OperationDef oper,
++ CORBA_NVList **new_list,
++ CORBA_Environment *ev);
++#endif /* !__KORBIT__ */
++
++extern CORBA_Status CORBA_NVList_free(CORBA_NVList *list,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_NVList_free_memory(
++ CORBA_NVList *list,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_NVList_get_count(
++ CORBA_NVList *list,
++ CORBA_long *count,
++ CORBA_Environment *ev);
++
++extern const int sizeofs[], container_sizeofs[];
++
++#endif /* _ORBIT_DII_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/env.c linux-2.4.1-korbit/net/korbit/orb/env.c
+--- linux-2.4.1/net/korbit/orb/env.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/env.c Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,345 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++/*
++ * CORBA_Environment handling functions
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++
++#include "orbit.h"
++#ifndef __KORBIT__
++#include "interface_repository.h"
++#endif /* !__KORBIT__ */
++
++struct SysExInfo {
++ const char *repo_id;
++ const int exnum;
++};
++
++static const struct SysExInfo exception_table[] = {
++ {NULL, 0},
++ {"IDL:CORBA/UNKNOWN:1.0", 1},
++ {"IDL:CORBA/BAD_PARAM:1.0", 2},
++ {"IDL:CORBA/NO_MEMORY:1.0", 3},
++ {"IDL:CORBA/IMP_LIMIT:1.0", 4},
++ {"IDL:CORBA/COMM_FAILURE:1.0", 5},
++ {"IDL:CORBA/INV_OBJREF:1.0", 6},
++ {"IDL:CORBA/NO_PERMISSION:1.0", 7},
++ {"IDL:CORBA/INTERNAL:1.0", 8},
++ {"IDL:CORBA/MARSHAL:1.0", 9},
++ {"IDL:CORBA/INITIALIZE:1.0", 10},
++ {"IDL:CORBA/NO_IMPLEMENT:1.0", 11},
++ {"IDL:CORBA/BAD_TYPECODE:1.0", 12},
++ {"IDL:CORBA/BAD_OPERATION:1.0", 13},
++ {"IDL:CORBA/NO_RESOURCES:1.0", 14},
++ {"IDL:CORBA/NO_RESPONSE:1.0", 15},
++ {"IDL:CORBA/PERSIST_STORE:1.0", 16},
++ {"IDL:CORBA/BAD_INV_ORDER:1.0", 17},
++ {"IDL:CORBA/TRANSIENT:1.0", 18},
++ {"IDL:CORBA/FREE_MEM:1.0", 19},
++ {"IDL:CORBA/INV_IDENT:1.0", 20},
++ {"IDL:CORBA/INV_FLAG:1.0", 21},
++ {"IDL:CORBA/INTF_REPOS:1.0", 22},
++ {"IDL:CORBA/BAD_CONTEXT:1.0", 23},
++ {"IDL:CORBA/OBJ_ADAPTER:1.0", 24},
++ {"IDL:CORBA/DATA_CONVERSION:1.0", 25},
++ {"IDL:CORBA/OBJECT_NOT_EXIST:1.0", 26},
++ {"IDL:CORBA/TRANSACTION_REQUIRED:1.0", 27},
++ {"IDL:CORBA/TRANSACTION_ROLLEDBACK:1.0", 28},
++ {"IDL:CORBA/INVALID_TRANSACTION:1.0", 29},
++ {NULL,0}
++};
++
++void CORBA_exception_free(CORBA_Environment *ev)
++{
++ g_assert(ev!=NULL);
++
++ ev->_major=CORBA_NO_EXCEPTION;
++
++ if(ev->_repo_id) {
++ CORBA_free(ev->_repo_id);
++ ev->_repo_id=NULL;
++ }
++
++ if(ev->_params) {
++ CORBA_free(ev->_params);
++ ev->_params=NULL;
++ }
++
++ if(ev->_any) {
++ CORBA_free(ev->_any);
++ ev->_any=NULL;
++ }
++}
++
++void CORBA_exception_set(CORBA_Environment *ev, CORBA_exception_type major,
++ const CORBA_char *except_repos_id, void *param)
++{
++ g_assert(ev!=NULL);
++
++ if(ev->_major != CORBA_NO_EXCEPTION)
++ CORBA_exception_free(ev);
++
++ ev->_major=major;
++
++ if(except_repos_id==NULL) {
++ ev->_repo_id=NULL;
++ } else {
++ ev->_repo_id=CORBA_string_dup(except_repos_id);
++ }
++
++ ev->_params=param;
++}
++
++void CORBA_exception_set_system(CORBA_Environment *ev, CORBA_unsigned_long ex_value,
++ CORBA_completion_status completed)
++{
++ CORBA_SystemException *new;
++
++ new=ORBit_alloc(sizeof(CORBA_SystemException), NULL, NULL);
++ if(new!=NULL) {
++ new->minor=0;
++ new->completed=completed;
++
++ /* XXX what should the repo ID be? */
++ CORBA_exception_set(ev, CORBA_SYSTEM_EXCEPTION,
++ exception_table[ex_value].repo_id,
++ new);
++ }
++}
++
++void CORBA_exception_init(CORBA_Environment *ev)
++{
++ g_assert(ev!=NULL);
++
++ ev->_major=CORBA_NO_EXCEPTION;
++ ev->_repo_id=NULL;
++ ev->_params=NULL;
++ ev->_any=NULL;
++}
++
++CORBA_char *CORBA_exception_id(CORBA_Environment *ev)
++{
++ g_assert(ev!=NULL);
++
++ if(ev->_major==CORBA_NO_EXCEPTION) {
++ return(NULL);
++ } else {
++ return(ev->_repo_id);
++ }
++}
++
++void *CORBA_exception_value(CORBA_Environment *ev)
++{
++ g_assert(ev!=NULL);
++
++ if(ev->_major==CORBA_NO_EXCEPTION) {
++ return(NULL);
++ } else {
++ return(ev->_params);
++ }
++}
++
++#ifndef __KORBIT__
++CORBA_any *CORBA_exception_as_any(CORBA_Environment *ev)
++{
++ g_assert(ev!=NULL);
++
++ if(ev->_major==CORBA_NO_EXCEPTION) {
++ return(NULL);
++ }
++
++ if(ev->_any!=NULL) {
++ return(ev->_any);
++ }
++
++ ev->_any=g_new(CORBA_any, 1);
++ if(ev->_any!=NULL) {
++ /* XXX is this the correct type? */
++ ev->_any->_type = (CORBA_TypeCode)TC_CORBA_ExceptionDescription;
++ ev->_any->_value = ev->_params;
++ ev->_any->_release = 0;
++ }
++
++ return(ev->_any);
++}
++#endif /* !__KORBIT__ */
++
++/**** ORBit_handle_exception
++ Inputs: 'rb' - a receive buffer for which an exception condition has
++ been determined
++ 'ev' - memory in which to store the exception information
++
++ 'user_exceptions' - list of user exceptions raisable
++ for this particular operation.
++ Side-effects: reinitializes '*ev'
++
++ Description:
++ During demarshalling a reply, if reply_status != CORBA_NO_EXCEPTION,
++ we must find out what exception was raised and place that information
++ in '*ev'. */
++
++void ORBit_handle_exception(GIOPRecvBuffer *rb, CORBA_Environment *ev,
++ const ORBit_exception_demarshal_info *user_exceptions,
++ CORBA_ORB orb)
++{
++ CORBA_SystemException *new;
++ CORBA_unsigned_long len, completion_status;
++ CORBA_char *my_repoid;
++
++ g_return_if_fail(GIOP_MESSAGE_BUFFER(rb)->message_header.message_type == GIOP_REPLY);
++
++ CORBA_exception_free(ev);
++
++ rb->cur = ALIGN_ADDRESS(rb->cur, sizeof(len));
++ rb->decoder(&len, rb->cur, sizeof(len));
++ /* (guchar *)rb->cur += sizeof(len); */
++ rb->cur = ((guchar *)rb->cur) + sizeof(len);
++
++ if(len) {
++ my_repoid = rb->cur;
++ rb->cur = ((guchar *)rb->cur) + len;
++ } else
++ my_repoid = NULL;
++
++ if(rb->message.u.reply.reply_status == CORBA_SYSTEM_EXCEPTION) {
++ CORBA_unsigned_long minor;
++
++ ev->_major = CORBA_SYSTEM_EXCEPTION;
++
++ rb->cur = ALIGN_ADDRESS(rb->cur, sizeof(minor));
++ rb->decoder(&minor, rb->cur, sizeof(minor));
++ rb->cur = ((guchar *)rb->cur) + sizeof(minor);
++
++ rb->cur = ALIGN_ADDRESS(rb->cur, sizeof(completion_status));
++ rb->decoder(&completion_status, rb->cur, sizeof(completion_status));
++ rb->cur = ((guchar *)rb->cur) + sizeof(completion_status);
++
++ new=ORBit_alloc(sizeof(CORBA_SystemException), NULL, NULL);
++
++ if(new!=NULL) {
++ new->minor=minor;
++ new->completed=completion_status;
++
++ /* XXX what should the repo ID be? */
++ CORBA_exception_set(ev, CORBA_SYSTEM_EXCEPTION,
++ my_repoid,
++ new);
++ }
++ } else if(rb->message.u.reply.reply_status == CORBA_USER_EXCEPTION) {
++ int i;
++
++ if(!user_exceptions) {
++ /* weirdness; they raised an exception that we don't
++ know about */
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_MAYBE);
++ } else {
++ for(i = 0; user_exceptions[i].tc != CORBA_OBJECT_NIL;
++ i++) {
++ if(!strcmp(user_exceptions[i].tc->repo_id,
++ my_repoid))
++ break;
++ }
++
++ if(user_exceptions[i].tc == CORBA_OBJECT_NIL) {
++ /* weirdness; they raised an exception
++ that we don't know about */
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_MAYBE);
++ } else {
++ user_exceptions[i].demarshal(rb, ev);
++ }
++ }
++ };
++
++ /* ignore LOCATION_FORWARD here, that gets handled in the stub */
++}
++
++void
++ORBit_send_system_exception(GIOPSendBuffer *send_buffer,
++ CORBA_Environment *ev)
++{
++ CORBA_unsigned_long minor;
++ CORBA_unsigned_long completion_status;
++ CORBA_SystemException *se = ev->_params;
++
++ minor = se->minor;
++ completion_status = se->completed;
++
++ ENCODER_CALL(CORBA_char, ev->_repo_id);
++ giop_send_buffer_append_mem_indirect_a(send_buffer, &minor,
++ sizeof(minor));
++ giop_send_buffer_append_mem_indirect_a(send_buffer,
++ &completion_status,
++ sizeof(completion_status));
++}
++
++void
++ORBit_send_user_exception(GIOPSendBuffer *send_buffer,
++ CORBA_Environment *ev,
++ const ORBit_exception_marshal_info *user_exceptions)
++{
++ int i;
++
++ for(i = 0; user_exceptions[i].tc != CORBA_OBJECT_NIL; i++) {
++ if(!strcmp(user_exceptions[i].tc->repo_id, ev->_repo_id))
++ break;
++ }
++
++ if(user_exceptions[i].tc == CORBA_OBJECT_NIL) {
++ CORBA_Environment fakeev;
++ CORBA_exception_init(&fakeev);
++ CORBA_exception_set_system(&fakeev, ex_CORBA_UNKNOWN,
++ CORBA_COMPLETED_MAYBE);
++ ORBit_send_system_exception(send_buffer, &fakeev);
++ CORBA_exception_free(&fakeev);
++ } else {
++ ENCODER_CALL(CORBA_char, ev->_repo_id);
++
++ if(user_exceptions[i].marshal && ev->_params)
++ user_exceptions[i].marshal(send_buffer, ev);
++ }
++}
++
++void
++ORBit_handle_system_exception(CORBA_Environment *ev,
++ CORBA_unsigned_long system_exception_minor,
++ CORBA_unsigned_long completion_status,
++ GIOPRecvBuffer *recv_buffer,
++ GIOPSendBuffer *send_buffer)
++{
++ CORBA_exception_set_system(ev, system_exception_minor, completion_status);
++
++ if(send_buffer)
++ giop_send_buffer_unuse(send_buffer);
++
++ if(recv_buffer)
++ giop_recv_buffer_unuse(recv_buffer);
++}
+diff -urN linux-2.4.1/net/korbit/orb/env.h linux-2.4.1-korbit/net/korbit/orb/env.h
+--- linux-2.4.1/net/korbit/orb/env.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/env.h Thu Feb 1 16:21:56 2001
+@@ -0,0 +1,79 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998, 1999 Richard H. Porter, Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_ENV_H_
++#define _ORBIT_ENV_H_
++
++#include "orbit_types.h"
++
++extern void CORBA_exception_set(CORBA_Environment *ev,
++ CORBA_exception_type major,
++ const CORBA_char *except_repos_id,
++ void *param);
++
++extern void CORBA_exception_set_system(CORBA_Environment *ev,
++ CORBA_unsigned_long ex_value,
++ CORBA_completion_status completed);
++
++extern void CORBA_exception_init(CORBA_Environment *ev);
++
++extern CORBA_char *CORBA_exception_id(CORBA_Environment *e);
++
++extern void *CORBA_exception_value(CORBA_Environment *ev);
++
++extern void CORBA_exception_free(CORBA_Environment *ev);
++
++#ifndef __KORBIT__
++extern CORBA_any *CORBA_exception_as_any(CORBA_Environment *ev);
++#endif /* !__KORBIT__ */
++
++typedef struct {
++ const CORBA_TypeCode tc;
++ void (*demarshal)(GIOPRecvBuffer *_ORBIT_recv_buffer, CORBA_Environment *ev);
++} ORBit_exception_demarshal_info;
++
++typedef struct {
++ const CORBA_TypeCode tc;
++ void (*marshal)(GIOPSendBuffer *_ORBIT_send_buffer, CORBA_Environment *ev);
++} ORBit_exception_marshal_info;
++
++/* ORBit-specific */
++void ORBit_handle_exception(GIOPRecvBuffer *rb, CORBA_Environment *ev,
++ const ORBit_exception_demarshal_info *user_exceptions,
++ CORBA_ORB orb);
++void ORBit_send_system_exception(GIOPSendBuffer *send_buffer,
++ CORBA_Environment *ev);
++void ORBit_send_user_exception(GIOPSendBuffer *send_buffer,
++ CORBA_Environment *ev,
++ const ORBit_exception_marshal_info *user_exceptions);
++
++/* Used by stubs */
++void ORBit_handle_system_exception(CORBA_Environment *ev,
++ CORBA_unsigned_long system_exception_minor,
++ CORBA_unsigned_long completion_status,
++ GIOPRecvBuffer *recv_buffer,
++ GIOPSendBuffer *send_buffer);
++
++#endif /* !_ORBIT_ENV_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/genrand.c linux-2.4.1-korbit/net/korbit/orb/genrand.c
+--- linux-2.4.1/net/korbit/orb/genrand.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/genrand.c Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,131 @@
++#include "genrand.h"
++#include "ORBitutil/util.h"
++#include <unistd.h>
++#include <sys/types.h>
++#include <fcntl.h>
++#include <glib.h>
++#include <signal.h>
++#include <sys/time.h>
++#include <limits.h>
++#include <stdio.h>
++#ifdef __KERNEL__
++#include <linux/random.h>
++#endif
++
++static gboolean
++genrand_dev(guchar *buffer, int buf_len)
++{
++#ifdef __KERNEL__
++ get_random_bytes(buffer, buf_len);
++#else /*! __KERNEL__*/
++ int fd;
++
++ fd = open("/dev/urandom", O_RDONLY);
++ if(fd < 0)
++ return FALSE;
++
++ if(read(fd, buffer, buf_len) < buf_len)
++ {
++ close(fd);
++ return FALSE;
++ }
++
++ close(fd);
++#endif /*! __KERNEL__*/
++
++ return TRUE;
++}
++
++#ifndef __KORBIT__
++static volatile int received_alarm = 0;
++
++static void
++handle_alarm(int signum)
++{
++ received_alarm = 1;
++}
++
++static inline guchar
++hashlong(long val)
++{
++ guchar retval, *ptr;
++ int i;
++
++ for(ptr = (guchar *)&val, i = 0; i < sizeof(val); i++)
++ retval ^= ptr[i];
++
++ return retval;
++}
++
++static gboolean
++genrand_unix(guchar *buffer, int buf_len)
++{
++ struct sigaction sa, oldsa;
++ struct itimerval it, oldit;
++ int i;
++ long min, max;
++ long *counts;
++ double diff;
++ long *uninit;
++
++ counts = alloca(buf_len * sizeof(long));
++
++ memset(&sa, 0, sizeof(sa));
++ sa.sa_handler = handle_alarm;
++ sigaction(SIGALRM, &sa, &oldsa);
++ memset(&it, 0, sizeof(it));
++ it.it_value.tv_usec = 1;
++ getitimer(ITIMER_REAL, &oldit);
++
++ for(i = 0, min = LONG_MAX, max = 0; i < buf_len; i++)
++ {
++ received_alarm = 0;
++ setitimer(ITIMER_REAL, &it, NULL);
++ for(counts[i] = 0; !received_alarm; counts[i]++);
++
++ max = MAX(counts[i], max);
++ min = MIN(counts[i], min);
++ }
++
++ if(!(max - min))
++ {
++ freeca(counts);
++ return FALSE;
++ }
++
++ diff = max - min;
++
++ uninit = alloca(buf_len * sizeof(long)); /* Purposely not initialized */
++ for(i = 0; i < buf_len; i++)
++ {
++ long diffval;
++ diffval = counts[i] - min;
++
++ buffer[i] ^= (guchar)( ((double) (diffval*256) / diff )) ^ hashlong(uninit[i]);
++ }
++
++ setitimer(ITIMER_REAL, &oldit, NULL);
++ sigaction(SIGALRM, &oldsa, NULL);
++
++ freeca(counts);
++ freeca(uninit);
++
++ return TRUE;
++}
++#endif /* !__KORBIT__ */
++
++void
++orbit_genrand(guchar *buffer, int buf_len)
++{
++ g_return_if_fail(buf_len);
++
++ if(genrand_dev(buffer, buf_len))
++ return;
++#ifndef __KORBIT__
++ else if(genrand_unix(buffer, buf_len))
++ return;
++#endif
++ else
++ g_error("Couldn't generate random data!");
++}
++
+diff -urN linux-2.4.1/net/korbit/orb/genrand.h linux-2.4.1-korbit/net/korbit/orb/genrand.h
+--- linux-2.4.1/net/korbit/orb/genrand.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/genrand.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,8 @@
++#ifndef ORBIT_GENRAND_H
++#define ORBIT_GENRAND_H 1
++
++#include <glib.h>
++
++void orbit_genrand(guchar *buffer, int buf_len);
++
++#endif /* ORBIT_GENRAND_H */
+diff -urN linux-2.4.1/net/korbit/orb/iop.h linux-2.4.1-korbit/net/korbit/orb/iop.h
+--- linux-2.4.1/net/korbit/orb/iop.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/iop.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,207 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_IOP_H_
++#define _ORBIT_IOP_H_
++
++#include <ORBitutil/basic_types.h>
++
++#include <orb/corba_basic_sequences_type.h>
++
++#ifndef HAVE_CORBA_PRINCIPAL
++#define HAVE_CORBA_PRINCIPAL 1
++typedef CORBA_sequence_octet CORBA_Principal;
++#endif
++
++typedef CORBA_unsigned_long IOP_ProfileId;
++
++#define IOP_TAG_INTERNET_IOP 0
++#define IOP_TAG_MULTIPLE_COMPONENTS 1
++#define IOP_TAG_ORBIT_SPECIFIC 0xbadfaecal
++
++typedef struct IOP_TaggedProfile {
++ IOP_ProfileId tag;
++ CORBA_sequence_octet profile_data;
++} IOP_TaggedProfile;
++
++typedef struct CORBA_sequence_TaggedProfile {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ IOP_TaggedProfile *_buffer;
++} CORBA_sequence_TaggedProfile;
++
++typedef struct IOP_IOR {
++ CORBA_char *type_id;
++ CORBA_sequence_TaggedProfile profiles;
++} IOP_IOR;
++
++typedef CORBA_unsigned_long IOP_ComponentId;
++
++typedef struct IOP_TaggedComponent {
++ IOP_ComponentId tag;
++ CORBA_sequence_octet component_data;
++} IOP_TaggedComponent;
++
++typedef struct CORBA_sequence_TaggedComponent {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ IOP_TaggedComponent *_buffer;
++} CORBA_sequence_TaggedComponent;
++
++typedef struct CORBA_sequence_TaggedComponent IOP_MultipleComponentProfile;
++
++#define IOP_TAG_ORB_TYPE 0
++#define IOP_TAG_CODE_SETS 1
++#define IOP_TAG_SEC_NAME 14
++#define IOP_TAG_ASSOCIATION_OPTIONS 13
++#define IOP_TAG_GENERIC_SEC_MECH 12
++
++typedef CORBA_unsigned_long IOP_ServiceId;
++
++typedef struct IOP_ServiceContext {
++ IOP_ServiceId context_id;
++ CORBA_sequence_octet context_data;
++} IOP_ServiceContext;
++
++typedef struct CORBA_sequence_ServiceContext {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ IOP_ServiceContext *_buffer;
++} CORBA_sequence_ServiceContext;
++
++typedef struct CORBA_sequence_ServiceContext IOP_ServiceContextList;
++
++#define IOP_TransactionService 0
++#define IOP_CodeSets 1
++
++typedef CORBA_unsigned_long CONV_FRAME_CodeSetId;
++
++typedef struct CORBA_sequence_CodeSetId {
++ CORBA_unsigned_long _maximum;
++ CORBA_unsigned_long _length;
++ CONV_FRAME_CodeSetId *_buffer;
++} CORBA_sequence_CodeSetId;
++
++typedef struct CONV_FRAME_CodeSetComponent {
++ CONV_FRAME_CodeSetId native_code_set;
++ CORBA_sequence_CodeSetId conversion_code_sets;
++} CONV_FRAME_CodeSetComponent;
++
++typedef struct CONV_FRAME_CodeSetComponentInfo {
++ CONV_FRAME_CodeSetComponent ForCharData;
++ CONV_FRAME_CodeSetComponent ForWcharData;
++} CONV_FRAME_CodeSetComponentInfo;
++
++typedef struct CONV_FRAME_CodeSetContext {
++ CONV_FRAME_CodeSetId char_data;
++ CONV_FRAME_CodeSetId wchar_data;
++} CONV_FRAME_CodeSetContext;
++
++typedef struct GIOP_Version {
++ CORBA_octet major;
++ CORBA_octet minor;
++} GIOP_Version;
++
++typedef enum {
++ GIOP_Request=0,
++ GIOP_Reply,
++ GIOP_CancelRequest,
++ GIOP_LocateRequest,
++ GIOP_LocateReply,
++ GIOP_CloseConnection,
++ GIOP_MessageError
++} GIOP_MsgType_1_0;
++
++typedef struct GIOP_MessageHeader_1_0 {
++ CORBA_char magic[4];
++ GIOP_Version GIOP_version;
++ CORBA_boolean byte_order;
++ CORBA_octet message_type;
++ CORBA_unsigned_long message_size;
++} GIOP_MessageHeader_1_0;
++
++typedef struct GIOP_MessageHeader_1_1 {
++ CORBA_char magic[4];
++ GIOP_Version GIOP_version;
++ CORBA_octet flags;
++ CORBA_octet message_type;
++ CORBA_unsigned_long message_size;
++} GIOP_MessageHeader_1_1;
++
++typedef struct GIOP_RequestHeader_1_0 {
++ IOP_ServiceContextList service_context;
++ CORBA_unsigned_long request_id;
++ CORBA_boolean response_expected;
++ CORBA_sequence_octet object_key;
++ CORBA_char *operation;
++ CORBA_Principal requesting_principal;
++} GIOP_RequestHeader_1_0;
++
++typedef struct GIOP_RequestHeader_1_1 {
++ IOP_ServiceContextList service_context;
++ CORBA_unsigned_long request_id;
++ CORBA_boolean response_expected;
++ CORBA_octet reserved[3];
++ CORBA_sequence_octet object_key;
++ CORBA_char *operation;
++ CORBA_Principal requesting_principal;
++} GIOP_RequestHeader_1_1;
++
++typedef struct GIOP_SystemExceptionReplyBody {
++ CORBA_char *exception_id;
++ CORBA_unsigned_long minor_code_value;
++ CORBA_unsigned_long completion_status;
++} GIOP_SystemExceptionReplyBody;
++
++typedef struct GIOP_CancelRequestHeader {
++ CORBA_unsigned_long request_id;
++} GIOP_CancelRequestHeader;
++
++typedef struct GIOP_LocateRequestHeader {
++ CORBA_unsigned_long request_id;
++ CORBA_sequence_octet object_key;
++} GIOP_LocateRequestHeader;
++
++typedef struct IIOP_Version {
++ CORBA_octet major;
++ CORBA_octet minor;
++} IIOP_Version;
++
++typedef struct IIOP_ProfileBody_1_0 {
++ IIOP_Version iiop_version;
++ CORBA_char *host;
++ CORBA_unsigned_short port;
++ CORBA_sequence_octet object_key;
++} IIOP_ProfileBody_1_0;
++
++typedef struct IIOP_ProfileBody_1_1 {
++ IIOP_Version iiop_version;
++ CORBA_char *host;
++ CORBA_unsigned_short port;
++ CORBA_sequence_octet object_key;
++ CORBA_sequence_TaggedComponent components;
++} IIOP_ProfileBody_1_1;
++
++#endif /* !_ORBIT_IOP_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/ir.c linux-2.4.1-korbit/net/korbit/orb/ir.c
+--- linux-2.4.1/net/korbit/orb/ir.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/ir.c Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,293 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#include <stdlib.h>
++#include <assert.h>
++
++#include "orbit.h"
++
++/* FIXME: Right now this function doesn't record whether or not it has
++ already visited a given TypeCode. I'm not sure if every recursive
++ type will have a tk_recursive node in it; if not, then this will
++ need to be reworked a bit. */
++CORBA_boolean CORBA_TypeCode_equal(CORBA_TypeCode obj, CORBA_TypeCode tc, CORBA_Environment *ev)
++{
++ int i;
++
++ g_return_val_if_fail(obj!=NULL, CORBA_FALSE);
++ g_return_val_if_fail(tc!=NULL, CORBA_FALSE);
++
++ if (obj->kind != tc->kind) {
++ return CORBA_FALSE;
++ }
++
++ switch (obj->kind) {
++ case CORBA_tk_wstring:
++ case CORBA_tk_string:
++ return obj->length == tc->length;
++ case CORBA_tk_objref:
++ return ! strcmp (obj->repo_id, tc->repo_id);
++ case CORBA_tk_except:
++ case CORBA_tk_struct:
++ if (strcmp (obj->repo_id, tc->repo_id)
++ || obj->sub_parts != tc->sub_parts)
++ return CORBA_FALSE;
++ for (i = 0; i < obj->sub_parts; ++i)
++ if (! CORBA_TypeCode_equal (obj->subtypes[i],
++ tc->subtypes[i], ev))
++ return CORBA_FALSE;
++ break;
++ case CORBA_tk_union:
++ if (strcmp (obj->repo_id, tc->repo_id)
++ || obj->sub_parts != tc->sub_parts
++ || ! CORBA_TypeCode_equal (obj->discriminator,
++ tc->discriminator, ev)
++ || obj->default_index != tc->default_index)
++ return CORBA_FALSE;
++ for (i = 0; i < obj->sub_parts; ++i)
++
++ if (! CORBA_TypeCode_equal (obj->subtypes[i],
++ tc->subtypes[i], ev)
++ || ! ORBit_any_equivalent (obj->sublabels[i],
++ tc->sublabels[i], ev))
++ return CORBA_FALSE;
++
++ break;
++ case CORBA_tk_enum:
++ if (obj->sub_parts != tc->sub_parts
++ || strcmp (obj->repo_id, tc->repo_id))
++ return CORBA_FALSE;
++ for (i = 0; i < obj->sub_parts; ++i)
++ if (strcmp (obj->subnames[i], tc->subnames[i]))
++ return CORBA_FALSE;
++ break;
++ case CORBA_tk_sequence:
++ case CORBA_tk_array:
++ if (obj->length != tc->length)
++ return CORBA_FALSE;
++ g_assert (obj->sub_parts == 1);
++ g_assert (tc->sub_parts == 1);
++ return CORBA_TypeCode_equal (obj->subtypes[0], tc->subtypes[0],
++ ev);
++ case CORBA_tk_alias:
++ if (strcmp (obj->repo_id, tc->repo_id))
++ return CORBA_FALSE;
++
++ g_assert (obj->sub_parts == 1);
++ g_assert (tc->sub_parts == 1);
++
++ return CORBA_TypeCode_equal (obj->subtypes[0], tc->subtypes[0],
++ ev);
++ break;
++ case CORBA_tk_recursive:
++ return obj->recurse_depth == tc->recurse_depth;
++ case CORBA_tk_fixed:
++ return obj->digits == tc->digits && obj->scale == tc->scale;
++
++ default:
++ /* Everything else is primitive. */
++ break;
++ }
++
++ return CORBA_TRUE;
++}
++
++CORBA_TCKind CORBA_TypeCode_kind(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ return obj->kind;
++}
++
++static void bad_kind (CORBA_Environment *ev)
++{
++ CORBA_TypeCode_BadKind *err;
++ err = g_new (CORBA_TypeCode_BadKind, 1);
++ if (err == NULL) {
++ CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY,
++ CORBA_COMPLETED_NO);
++ } else {
++ err->dummy = 23;
++ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
++ "IDL:omg.org/CORBA/TypeCode/BadKind/1.0",
++ err);
++ }
++}
++
++CORBA_RepositoryId CORBA_TypeCode_id(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_objref || obj->kind == CORBA_tk_struct
++ || obj->kind == CORBA_tk_enum || obj->kind == CORBA_tk_alias
++ || obj->kind == CORBA_tk_except)) {
++ bad_kind (ev);
++ return NULL;
++ }
++ return obj->repo_id;
++}
++
++CORBA_Identifier CORBA_TypeCode_name(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_objref || obj->kind == CORBA_tk_struct
++ || obj->kind == CORBA_tk_enum || obj->kind == CORBA_tk_alias
++ || obj->kind == CORBA_tk_except)) {
++ bad_kind (ev);
++ return NULL;
++ }
++
++ return obj->name;
++}
++
++CORBA_unsigned_long CORBA_TypeCode_member_count(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_union
++ || obj->kind == CORBA_tk_enum)) {
++ bad_kind (ev);
++ return 0;
++ }
++ return obj->sub_parts;
++}
++
++static void bounds_error (CORBA_Environment *ev)
++{
++ CORBA_TypeCode_Bounds *err;
++ err = g_new (CORBA_TypeCode_Bounds, 1);
++ if (err == NULL) {
++ CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY,
++ CORBA_COMPLETED_NO);
++ } else {
++ err->dummy = 23;
++ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
++ "IDL:omg.org/CORBA/TypeCode/Bounds/1.0",
++ err);
++ }
++}
++
++CORBA_Identifier CORBA_TypeCode_member_name(CORBA_TypeCode obj, CORBA_unsigned_long index, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_union
++ || obj->kind == CORBA_tk_enum)) {
++ bad_kind (ev);
++ return NULL;
++ }
++ if (index > obj->sub_parts) {
++ bounds_error (ev);
++ return NULL;
++ }
++ return obj->subnames[index];
++}
++
++CORBA_TypeCode CORBA_TypeCode_member_type(CORBA_TypeCode obj, CORBA_unsigned_long index, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_union
++ || obj->kind == CORBA_tk_enum)) {
++ bad_kind (ev);
++ return NULL;
++ }
++ if (index > obj->sub_parts) {
++ bounds_error (ev);
++ return NULL;
++ }
++ return obj->subtypes[index];
++}
++
++CORBA_any *CORBA_TypeCode_member_label(CORBA_TypeCode obj, CORBA_unsigned_long index, CORBA_Environment *ev)
++{
++ if (obj->kind != CORBA_tk_union) {
++ bad_kind (ev);
++ return NULL;
++ }
++ if (index > obj->sub_parts) {
++ bounds_error (ev);
++ return NULL;
++ }
++ return &obj->sublabels[index];
++}
++
++CORBA_TypeCode CORBA_TypeCode_discriminator_type(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (obj->kind != CORBA_tk_union) {
++ bad_kind (ev);
++ return NULL;
++ }
++ return obj->discriminator;
++}
++
++CORBA_long CORBA_TypeCode_default_index(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (obj->kind != CORBA_tk_union) {
++ bad_kind (ev);
++ return 0;
++ }
++ return obj->default_index;
++}
++
++CORBA_unsigned_long CORBA_TypeCode_length(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_string || obj->kind == CORBA_tk_wstring
++ || obj->kind == CORBA_tk_array)) {
++ bad_kind (ev);
++ return 0;
++ }
++ return obj->length;
++}
++
++CORBA_TypeCode CORBA_TypeCode_content_type(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (! (obj->kind == CORBA_tk_sequence || obj->kind == CORBA_tk_array
++ || obj->kind == CORBA_tk_alias)) {
++ bad_kind (ev);
++ return NULL;
++ }
++ g_assert (obj->sub_parts == 1);
++ return obj->subtypes[0];
++}
++
++CORBA_unsigned_short CORBA_TypeCode_fixed_digits(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (obj->kind != CORBA_tk_fixed) {
++ bad_kind (ev);
++ return 0;
++ }
++ return obj->digits;
++}
++
++CORBA_short CORBA_TypeCode_fixed_scale(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ if (obj->kind != CORBA_tk_fixed) {
++ bad_kind (ev);
++ return 0;
++ }
++ return obj->scale;
++}
++
++CORBA_long CORBA_TypeCode_param_count(CORBA_TypeCode obj, CORBA_Environment *ev)
++{
++ g_assert(!"Deprecated");
++ return(0);
++}
++
++CORBA_any *CORBA_TypeCode_parameter(CORBA_TypeCode obj, CORBA_long index, CORBA_Environment *ev)
++{
++ g_assert(!"Deprecated");
++ return(NULL);
++}
+diff -urN linux-2.4.1/net/korbit/orb/ir.h linux-2.4.1-korbit/net/korbit/orb/ir.h
+--- linux-2.4.1/net/korbit/orb/ir.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/ir.h Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,100 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_IR_H_
++#define _ORBIT_IR_H_
++
++#include "orbit_types.h"
++
++extern CORBA_boolean CORBA_TypeCode_equal(
++ CORBA_TypeCode obj,
++ CORBA_TypeCode tc,
++ CORBA_Environment *ev);
++
++extern CORBA_TCKind CORBA_TypeCode_kind(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_RepositoryId CORBA_TypeCode_id(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Identifier CORBA_TypeCode_name(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_unsigned_long CORBA_TypeCode_member_count(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Identifier CORBA_TypeCode_member_name(
++ CORBA_TypeCode obj,
++ CORBA_unsigned_long index,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_TypeCode_member_type(
++ CORBA_TypeCode obj,
++ CORBA_unsigned_long index,
++ CORBA_Environment *ev);
++
++extern CORBA_any *CORBA_TypeCode_member_label(
++ CORBA_TypeCode obj,
++ CORBA_unsigned_long index,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_TypeCode_discriminator_type(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_long CORBA_TypeCode_default_index(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_unsigned_long CORBA_TypeCode_length(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_TypeCode_content_type(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_unsigned_short CORBA_TypeCode_fixed_digits(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_short CORBA_TypeCode_fixed_scale(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_long CORBA_TypeCode_param_count(
++ CORBA_TypeCode obj,
++ CORBA_Environment *ev);
++
++extern CORBA_any *CORBA_TypeCode_parameter(
++ CORBA_TypeCode obj,
++ CORBA_long index,
++ CORBA_Environment *ev);
++
++#endif /* !_ORBIT_IR_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/options.c linux-2.4.1-korbit/net/korbit/orb/options.c
+--- linux-2.4.1/net/korbit/orb/options.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/options.c Thu Feb 1 11:47:12 2001
+@@ -0,0 +1,160 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++/*
++ * Option parsing
++ *
++ * All ORB options are stripped from the application's argv, and argc is
++ * adjusted accordingly
++ */
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <glib.h>
++
++#include "options.h"
++
++#ifndef __KORBIT__
++void ORBit_option_set(ORBit_orb_options *option, const char *val)
++{
++ g_assert(option!=NULL);
++
++ if(option->type==no_arg && option->arg!=NULL) {
++ /* Treat as an int arg with val=1
++ */
++ int *int_arg=(int *)option->arg;
++
++ *int_arg=1;
++ } else {
++ if(option->type==string_arg && option->arg!=NULL) {
++ char **str_arg=(char **)option->arg;
++
++ /* free any existing value */
++ if(*str_arg!=NULL) {
++ g_free(*str_arg);
++ }
++ *str_arg=g_strdup(val);
++ } else if(option->type==int_arg && option->arg!=NULL) {
++ int *int_arg=(int *)option->arg;
++
++ *int_arg=atoi(val);
++ }
++
++ }
++}
++
++void ORBit_option_parse(int *argc, char **argv, ORBit_orb_options *options)
++{
++ int i,j,numargs;
++ char name[1024], *val;
++ ORBit_orb_options *search=NULL;
++ int *erase;
++
++ numargs=*argc;
++
++ erase=g_new0(int, *argc);
++
++ for(i=1; i< *argc; i++) {
++ if(argv[i][0]!='-') {
++ if(search==NULL) {
++ /* Skip non-option */
++ continue;
++ } else {
++ /* an required option value has been found */
++ erase[i]=1;
++ numargs-=1;
++
++ if(search->arg==NULL) {
++ /* dont store any values, just strip
++ * the argv
++ */
++ search=NULL;
++ continue;
++ }
++
++ ORBit_option_set(search, argv[i]);
++
++ search=NULL;
++ continue;
++ }
++ } else {
++ if(search!=NULL &&
++ (search->type==string_arg || search->type==int_arg)) {
++ fprintf(stderr, "Option %s requires an argument\n", search->name);
++ }
++ }
++
++ val=argv[i];
++ while(*val && *val=='-')
++ val++;
++
++ strncpy(name,val,1023);
++ name[1023]='\0';
++
++ val=strchr(name, '=');
++ if(val!=NULL) {
++ *val++='\0';
++ }
++
++ for(search=options;search->name!=NULL;search++) {
++ if(!strcmp(name, search->name)) {
++ break;
++ }
++ }
++
++ if(search->name==NULL) {
++ /* Didn't find it in our list of interesting options */
++ search=NULL;
++ } else {
++ /* Found it */
++ erase[i]=1;
++ numargs-=1;
++
++ if(search->type==no_arg || val!=NULL) {
++ ORBit_option_set(search, val);
++ search=NULL;
++ }
++ }
++ }
++
++ j=1;
++ for(i=1; i< *argc; i++) {
++ if(erase[i]==1) {
++ continue;
++ } else {
++ if(j<numargs) {
++ argv[j++]=argv[i];
++ } else {
++ argv[j++]='\0';
++ }
++ }
++ }
++
++ *argc=numargs;
++
++ g_free(erase);
++}
++#endif /* !__KORBIT__ */
+diff -urN linux-2.4.1/net/korbit/orb/options.h linux-2.4.1-korbit/net/korbit/orb/options.h
+--- linux-2.4.1/net/korbit/orb/options.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/options.h Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,46 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_OPTIONS_H_
++#define _ORBIT_OPTIONS_H_
++
++typedef enum {
++ no_arg=0,
++ string_arg,
++ int_arg
++} ORBit_opt_type;
++
++typedef struct {
++ char *name;
++ ORBit_opt_type type;
++ void *arg;
++} ORBit_orb_options;
++
++#ifndef __KORBIT__
++extern void ORBit_option_set(ORBit_orb_options *found, const char *val);
++extern void ORBit_option_parse(int *argc, char **argv, ORBit_orb_options *options);
++#endif
++
++#endif /* !_ORBIT_OPTIONS_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orb.c linux-2.4.1-korbit/net/korbit/orb/orb.c
+--- linux-2.4.1/net/korbit/orb/orb.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orb.c Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,1700 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++#define o_return_val_if_fail(expr, val) if(!(expr)) { CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM, CORBA_COMPLETED_NO); return (val); }
++#define o_return_if_fail(expr) if(!(expr)) { CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM, CORBA_COMPLETED_NO); return; }
++
++#include "config.h"
++
++#include <unistd.h>
++#include <errno.h>
++#include <sys/stat.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <ctype.h>
++#include <assert.h>
++#include <pwd.h>
++#include <time.h>
++#include <sys/types.h>
++#include <dirent.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <sys/un.h>
++#include <utime.h>
++
++#include "../IIOP/iiop-endianP.h"
++#include "orbit.h"
++
++#include "orbit_poa.h"
++#include "orbit_object.h"
++#include "orbit_object_type.h"
++
++#ifndef __KERNEL__
++#define freeca(ptr)
++#endif
++
++#ifndef SUN_LEN
++/* This system is not POSIX.1g. */
++#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
++ + strlen ((ptr)->sun_path))
++#endif
++
++static void ORBit_ORB_release(CORBA_ORB orb, CORBA_Environment *ev);
++
++static const ORBit_RootObject_Interface CORBA_ORB_epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))ORBit_ORB_release
++};
++
++
++static int ORBit_ORBid_setup(CORBA_ORB orb, CORBA_ORBid id)
++{
++ g_assert(orb!=NULL);
++ g_assert(id!=NULL);
++
++ if(strcmp(id, "orbit-local-orb")) {
++#ifdef __KORBIT__
++ printf("ORBit_ORBid_setup: Unknown ORB id: %s\n", id);
++#else
++ fprintf(stderr, "ORBit_ORBid_setup: Unknown ORB id: %s\n", id);
++#endif
++ return(0);
++ }
++
++ orb->orb_identifier=g_strdup(id);
++
++ return(1);
++}
++
++#ifndef __KORBIT__
++static gboolean
++free_key_and_data(gpointer key, gpointer data, gpointer user_data)
++{
++ g_free(key); g_free(data);
++
++ return TRUE;
++}
++
++static void ORBit_rc_load(const char *rcfile, ORBit_orb_options *options)
++{
++ FILE *fp;
++ GHashTable *read_options;
++ ORBit_orb_options *search;
++
++ fp=fopen(rcfile, "r");
++
++ if(fp==NULL)
++ return;
++
++ read_options=g_hash_table_new(g_str_hash, g_str_equal);
++
++ while(!feof(fp)) {
++ char buf[1024];
++
++ if(fgets(buf, 1024, fp)!=NULL) {
++ guchar *bptr, *tmp, *key, *data;
++ size_t start, len;
++
++ if(buf[0]=='#')
++ continue;
++
++ bptr=buf;
++ tmp=strpbrk(bptr, " \t\n=");
++ if(tmp==NULL) continue;
++ *tmp++='\0';
++ key=g_strdup(bptr);
++ bptr=tmp;
++
++ start=0;
++ while(bptr+start != '\0' &&
++ (isspace(bptr[start]) || bptr[start]=='='))
++ start++;
++ len=strcspn(bptr+start, " \t\n");
++ bptr[start+len]='\0';
++ if(len>0) {
++ data=g_strdup(bptr+start);
++ } else {
++ data=g_strdup("TRUE");
++ }
++
++ g_hash_table_insert(read_options, key, data);
++ }
++ }
++ fclose(fp);
++
++ for(search=options;search->name!=NULL;search++) {
++ char *read_val;
++
++ read_val=g_hash_table_lookup(read_options, search->name);
++ if(read_val!=NULL) {
++ ORBit_option_set(search, read_val);
++ }
++ }
++
++ g_hash_table_foreach_remove(read_options, free_key_and_data, NULL);
++ g_hash_table_destroy(read_options);
++}
++#endif /* !__KORBIT__ */
++
++static void ORBit_ORB_release(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ g_assert(orb!=NULL);
++
++ if(--(ORBIT_ROOT_OBJECT(orb)->refs))
++ return;
++
++ if(orb->orb_identifier!=NULL) {
++ g_free(orb->orb_identifier);
++ }
++ if(!CORBA_Object_is_nil(orb->imr, ev)) {
++ CORBA_Object_release(orb->imr, ev);
++ }
++ if(!CORBA_Object_is_nil(orb->ir, ev)) {
++ CORBA_Object_release(orb->ir, ev);
++ }
++ if(!CORBA_Object_is_nil(orb->naming, ev)) {
++ CORBA_Object_release(orb->naming, ev);
++ }
++ if(!CORBA_Object_is_nil(orb->root_poa, ev)) {
++ CORBA_Object_release(orb->root_poa, ev);
++ }
++ if(orb->cnx.ipv4)
++ giop_connection_unref(orb->cnx.ipv4);
++ if(orb->cnx.ipv6)
++ giop_connection_unref(orb->cnx.ipv6);
++#ifndef __KORBIT__
++ if(orb->cnx.usock)
++ giop_connection_unref(orb->cnx.usock);
++#endif
++
++ g_free(orb);
++}
++
++#ifndef __KORBIT__
++static GIOPConnection*
++ORBit_ORB_make_usock_connection(void)
++{
++ GIOPConnection *retval = NULL;
++ GString *tmpstr;
++ struct stat statbuf;
++
++ tmpstr = g_string_new(NULL);
++
++ g_string_sprintf(tmpstr, "/tmp/orbit-%s", g_get_user_name());
++
++ if(mkdir(tmpstr->str, 0700) != 0) {
++ int e = errno;
++
++ switch (e) {
++ case 0:
++ case EEXIST:
++ if (stat(tmpstr->str, &statbuf) != 0)
++ g_error ("Can not stat %s\n", tmpstr->str);
++
++ if (statbuf.st_uid != getuid ())
++ g_error ("Owner of %s is not the current user\n",
++ tmpstr->str);
++
++ if((statbuf.st_mode & (S_IRWXG|S_IRWXO))
++ || !S_ISDIR(statbuf.st_mode))
++ g_error ("Wrong permissions for %s\n",
++ tmpstr->str);
++ break;
++
++ default:
++ g_error("Unknown error on directory creation of %s (%s)\n",
++ tmpstr->str, g_strerror (e));
++ }
++ }
++
++ {
++ struct utimbuf utb;
++ memset(&utb, 0, sizeof(utb));
++ utime(tmpstr->str, &utb);
++ }
++
++
++#ifdef WE_DONT_CARE_ABOUT_STUPID_2DOT0DOTX_KERNELS
++ g_string_sprintf(tmpstr, "/tmp/orbit-%s",
++ g_get_user_name());
++ dirh = opendir(tmpstr->str);
++ while(!retval && (dent = readdir(dirh))) {
++ int usfd, ret;
++ struct sockaddr_un saddr;
++
++ saddr.sun_family = AF_UNIX;
++
++ if(strncmp(dent->d_name, "orb-", 4))
++ continue;
++
++ g_snprintf(saddr.sun_path, sizeof(saddr.sun_path),
++ "/tmp/orbit-%s/%s",
++ g_get_user_name(), dent->d_name);
++
++ usfd = socket(AF_UNIX, SOCK_STREAM, 0);
++ g_assert(usfd >= 0);
++
++ ret = connect(usfd, &saddr, SUN_LEN(&saddr));
++ close(usfd);
++
++ if(ret >= 0)
++ continue;
++
++ unlink(saddr.sun_path);
++ }
++ closedir(dirh);
++#endif /* WE_DONT_CARE_ABOUT_STUPID_2DOT0DOTX_KERNELS */
++
++ srand(time(NULL));
++ while(!retval) {
++ g_string_sprintf(tmpstr, "/tmp/orbit-%s/orb-%d%d",
++ g_get_user_name(), rand(), rand());
++ retval =
++ GIOP_CONNECTION(iiop_connection_server_unix(tmpstr->str));
++ }
++
++ g_string_free(tmpstr, TRUE);
++
++ return retval;
++}
++#endif /* !__KORBIT__ */
++
++
++// Synchronize between the user process starting up the orb and the ORB thread
++// this mutex gets released when the orb is all fired up and ready to go.
++static DECLARE_MUTEX(StartupSem);
++static CORBA_ORB TheOneTrueOrb = 0;
++
++struct CORBA_ORB_init_args { // A pointer to this struct is passed to
++ int *argc; // __CORBA_ORB_init
++ char **argv;
++ CORBA_ORBid orb_identifier;
++ CORBA_Environment *ev;
++};
++
++
++CORBA_ORB __CORBA_ORB_init(struct CORBA_ORB_init_args *Args) {
++ int *argc = Args->argc;
++ char **argv = Args->argv;
++ CORBA_ORBid orb_identifier = Args->orb_identifier;
++ CORBA_Environment *ev = Args->ev;
++
++ int no_iiop_server=0;
++ int no_iiop_proxy=0;
++#ifdef __KORBIT__
++ int use_ipv4=1;
++#else
++ int use_ipv4=0;
++#endif
++ int use_ipv6=0;
++ int use_usock=1;
++ int debug_level=0;
++ int debug_modules=0;
++ int nosysrc=0;
++ int nouserrc=0;
++ char *imr_ior=NULL, *imr_addr=NULL;
++ char *ir_ior=NULL, *ir_addr=NULL;
++ char *naming_ior=NULL, *naming_addr=NULL;
++ char *root_poa_ior=NULL, *root_poa_addr=NULL;
++ char *orb_id_opt=NULL;
++#ifndef __KORBIT__
++ char *ctmp;
++#endif
++ CORBA_ORB orb = 0;
++
++ /* The variable addresses in these structs need to be assigned at
++ * run-time if you want to compile with -pedantic
++ *
++ * (You will also get scads of warnings about "long long" too)
++ */
++
++ ORBit_orb_options pre_rc_options[]={
++ {"ORBNoSystemRC", no_arg, NULL},
++ {"ORBNoUserRC", no_arg, NULL},
++ {NULL, 0, NULL},
++ };
++
++ /* These options are compatible with MICO */
++ ORBit_orb_options options[]={
++ {"ORBNoIIOPServer", no_arg, NULL},
++ {"ORBNoIIOPProxy", no_arg, NULL},
++ {"ORBid", string_arg, NULL},
++ {"ORBImplRepoIOR", string_arg, NULL},
++ {"ORBImplRepoAddr", string_arg, NULL},
++ {"ORBIfaceRepoIOR", string_arg, NULL},
++ {"ORBIfaceRepoAddr", string_arg, NULL},
++ {"ORBNamingIOR", string_arg, NULL},
++ {"ORBNamingAddr", string_arg, NULL},
++ {"ORBDebugLevel", int_arg, NULL},
++ {"ORBBindAddr", string_arg, NULL}, /* XXX need to make
++ libIIOP support this */
++ {"ORBIIOPAddr", string_arg, NULL},
++
++ /* These options aren't */
++ {"ORBDebugModules", int_arg, NULL},
++ {"ORBRootPOAIOR", string_arg, NULL},
++ {"ORBRootPOAAddr", string_arg, NULL},
++ {"ORBIIOPUSock", int_arg, NULL},
++ {"ORBIIOPIPv4", int_arg, NULL},
++ {"ORBIIOPIPv6", int_arg, NULL},
++ {NULL,0,NULL},
++ };
++
++ if (ev == NULL || !argc || !argv || !orb_identifier) {
++ if (ev) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ }
++ up(&StartupSem); // Okay, let the insmod thread continue...
++ return 0;
++ }
++
++ pre_rc_options[0].arg = (void *) &nosysrc;
++ pre_rc_options[1].arg = (void *) &nouserrc;
++ options[0].arg = (void *) &no_iiop_server;
++ options[1].arg = (void *) &no_iiop_proxy;
++ options[2].arg = (void *) &orb_id_opt;
++ options[3].arg = (void *) &imr_ior;
++ options[4].arg = (void *) &imr_addr;
++ options[5].arg = (void *) &ir_ior;
++ options[6].arg = (void *) &ir_addr;
++ options[7].arg = (void *) &naming_ior;
++ options[8].arg = (void *) &naming_addr;
++ options[9].arg = (void *) &debug_level;
++ options[12].arg = (void *) &debug_modules;
++ options[13].arg = (void *) &root_poa_ior;
++ options[14].arg = (void *) &root_poa_addr;
++ options[15].arg = (void *) &use_usock;
++ options[16].arg = (void *) &use_ipv4;
++ options[17].arg = (void *) &use_ipv6;
++
++#ifndef __KORBIT__
++ ORBit_option_parse(argc, argv, pre_rc_options);
++
++ if(!nosysrc) {
++ ORBit_rc_load(ORBit_SYSRC, options);
++ }
++
++ if(!nouserrc) {
++ char *buf;
++
++ ctmp = g_get_home_dir();
++
++ buf = alloca(strlen(ctmp) + sizeof("/.orbitrc"));
++ sprintf(buf, "%s/.orbitrc", ctmp);
++ ORBit_rc_load(buf, options);
++ freeca(buf);
++ }
++
++ ORBit_option_parse(argc, argv, options);
++#endif /* !__KORBIT__ */
++
++ ORBit_Trace_setLevel(debug_level);
++ ORBit_Trace_setModules(debug_modules);
++
++ CORBA_exception_init(ev);
++
++ ORBit_chunks_init();
++
++ giop_init(argv[0]);
++
++ orb=g_new0(struct CORBA_ORB_type, 1);
++
++ if(orb==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ goto error;
++ }
++
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(orb), ORBIT_PSEUDO_ORB, ev);
++
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(orb),
++ (gpointer)&CORBA_ORB_epv, ev);
++
++ ORBIT_ROOT_OBJECT(orb)->refs = 1;
++
++ if(orb_id_opt!=NULL) {
++ if(!ORBit_ORBid_setup(orb, orb_id_opt))
++ goto error;
++ g_free(orb_id_opt);
++ } else if(orb_identifier!=NULL) {
++ if(!ORBit_ORBid_setup(orb, orb_identifier))
++ goto error;
++ } else {
++ orb->orb_identifier=g_strdup("orbit-local-orb");
++ }
++
++ if(orb->orb_identifier==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ goto error;
++ }
++
++ if(use_ipv4) {
++ orb->cnx.ipv4 = GIOP_CONNECTION(iiop_connection_server());
++
++ giop_connection_ref(orb->cnx.ipv4);
++ GIOP_CONNECTION(orb->cnx.ipv4)->orb_data = orb;
++ }
++
++ if(use_ipv6) {
++ orb->cnx.ipv6 = GIOP_CONNECTION(iiop_connection_server_ipv6());
++ giop_connection_ref(orb->cnx.ipv6);
++ GIOP_CONNECTION(orb->cnx.ipv6)->orb_data = orb;
++ }
++
++#ifndef __KORBIT__
++ if(use_usock) {
++ orb->cnx.usock = ORBit_ORB_make_usock_connection();
++
++ giop_connection_ref(orb->cnx.usock);
++ GIOP_CONNECTION(orb->cnx.usock)->orb_data = orb;
++ }
++#endif
++
++ orb->objrefs = g_hash_table_new((GHashFunc)g_CORBA_Object_hash,
++ (GCompareFunc)g_CORBA_Object_equal);
++ orb->poas = g_ptr_array_new();
++
++ /* when I figure out what MICO is doing with the iiop_proxy and
++ * iiop_server stuff, it'll get handled here.
++ */
++
++ /*
++ * Connect to / create implementation repository
++ */
++
++ {
++ CORBA_Object imr=NULL;
++
++ if(imr_ior!=NULL) {
++ imr=CORBA_ORB_string_to_object(orb, imr_ior, ev);
++ g_free(imr_ior);
++ } else if(imr_addr!=NULL) {
++ /*imr=CORBA_ORB_bind(orb, "IDL:omg.org/CORBA/ImplRepository:1.0", imr_addr, ev);*/
++ g_free(imr_addr);
++ }
++
++ if(!CORBA_Object_is_nil(imr, ev)) {
++ CORBA_ORB_set_initial_reference(orb, "ImplementationRepository", imr, ev);
++ }
++ }
++
++ /*
++ * Connect to / create interface repository
++ */
++
++ {
++ CORBA_Object ir=NULL;
++
++ if(ir_ior!=NULL) {
++ ir=CORBA_ORB_string_to_object(orb, ir_ior, ev);
++ g_free(ir_ior);
++ } else if(ir_addr!=NULL) {
++ /*ir=CORBA_ORB_bind(orb, "IDL:omg.org/CORBA/Repository:1.0", ir_addr, ev);*/
++ g_free(ir_addr);
++ }
++
++ if(!CORBA_Object_is_nil(ir, ev)) {
++ CORBA_ORB_set_initial_reference(orb, "InterfaceRepository", ir, ev);
++ }
++ }
++
++ /*
++ * Connect to naming service
++ */
++
++ {
++ CORBA_Object naming=NULL;
++
++ if(naming_ior!=NULL) {
++ naming=CORBA_ORB_string_to_object(orb, naming_ior, ev);
++ g_free(naming_ior);
++ } else if(naming_addr!=NULL) {
++ /*CORBA_ORB_ObjectTag tag=CORBA_ORB_string_to_tag(orb, "root", ev);*/
++
++ /*naming=CORBA_ORB_bind_tag(orb, "IDL:omg.org/CosNaming/NamingContext:1.0", tag, naming_addr, ev);*/
++ g_free(naming_addr);
++ }
++
++ if(!CORBA_Object_is_nil(naming, ev)) {
++ CORBA_ORB_set_initial_reference(orb, "NameService", naming, ev);
++ }
++ }
++
++ /*
++ * Connect to / create RootPOA
++ */
++
++ {
++ PortableServer_POA root_poa=CORBA_OBJECT_NIL;
++
++ if(root_poa_ior!=NULL) {
++ root_poa=(PortableServer_POA)
++ CORBA_ORB_string_to_object(orb,
++ root_poa_ior, ev);
++ g_free(root_poa_ior);
++ }
++
++ /* And attatch it to the orb */
++
++ if(!CORBA_Object_is_nil((CORBA_Object)root_poa, ev)) {
++ CORBA_ORB_set_initial_reference((CORBA_ORB)orb,
++ "RootPOA",
++ (CORBA_Object)root_poa,
++ ev);
++ }
++ }
++
++ ORBit_custom_run_setup(orb, ev);
++
++ if (!strcmp("server", argv[0])) // Only do this for servers.
++ TheOneTrueOrb = orb;
++ up(&StartupSem); // Okay, let the insmod thread continue...
++ return orb;
++
++error:
++ if(orb!=NULL) {
++ ORBit_ORB_release(orb, ev);
++ orb = NULL;
++ }
++ g_free(imr_ior);
++ g_free(imr_addr);
++ g_free(ir_ior);
++ g_free(ir_addr);
++ g_free(naming_ior);
++ g_free(naming_addr);
++ g_free(root_poa_ior);
++ g_free(root_poa_addr);
++ g_free(orb_id_opt);
++
++ TheOneTrueOrb = 0;
++ up(&StartupSem); // Okay, let the insmod thread continue...
++ return 0;
++}
++
++
++#if __KERNEL__
++#include <linux/smp_lock.h>
++#include <linux/proc_fs.h>
++
++// This is the main corba thread function...
++//
++void __CORBA_ORB_run(CORBA_ORB orb, CORBA_Environment *ev);
++int MainCORBAThread(void *Args) {
++ // Make a directory in /proc... yaay...
++ proc_mkdir("corba", 0);
++
++ __CORBA_ORB_init((struct CORBA_ORB_init_args*)Args);
++ if (TheOneTrueOrb == 0) return 0;
++
++ strcpy(current->comm, "korbit"); // Set the thread name...
++
++ lock_kernel(); /* This seems to be required for exit_mm */
++ exit_mm(current);
++
++ __CORBA_ORB_run(TheOneTrueOrb,
++ ((struct CORBA_ORB_init_args*)Args)->ev);
++ return 0;
++}
++#endif
++
++
++/* Section 4.4
++ *
++ * Adjusts argc and argv appropriately
++ */
++
++CORBA_ORB CORBA_ORB_init(int *argc, char **argv, CORBA_ORBid orb_identifier,
++ CORBA_Environment *ev) {
++
++ struct CORBA_ORB_init_args Args;
++ Args.argc = argc;
++ Args.argv = argv;
++ Args.orb_identifier = orb_identifier;
++ Args.ev = ev;
++
++#ifdef __KERNEL__
++ if (!strcmp(argv[0], "server")) { // Are we a server?
++ down(&StartupSem); // Grab the semaphore...
++ if (TheOneTrueOrb) {
++ CORBA_exception_init(ev);
++ goto out_success;
++ }
++
++ // This releases the semaphore when it is done initializing.
++ (void)kernel_thread(MainCORBAThread, &Args,
++ CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
++
++ // This will block until the semaphore is released by the
++ // ORB thread.
++ down(&StartupSem);
++ } else { // If we are a corba client, like CorbaFS...
++ return __CORBA_ORB_init(&Args);
++ }
++
++ out_success:
++ up(&StartupSem); // Okay, we're now here.
++#else
++ __CORBA_ORB_init(&Args);
++#endif
++ if (TheOneTrueOrb)
++ return (CORBA_ORB)CORBA_Object_duplicate((CORBA_Object)TheOneTrueOrb, ev);
++ return 0;
++}
++
++
++
++
++typedef struct {
++ CORBA_Object obj;
++ CDR_Codec *codec;
++ gboolean emit_active;
++} profile_user_data;
++
++static void ORBit_emit_profile(gpointer item, gpointer userdata)
++{
++ ORBit_Object_info *profile=(ORBit_Object_info *)item;
++ profile_user_data *data=(profile_user_data *)userdata;
++ CORBA_Object obj=data->obj;
++ CDR_Codec encaps_codec_d;
++ CDR_Codec *codec=data->codec, *encaps = &encaps_codec_d;
++ gboolean emit_active=data->emit_active;
++ static const CORBA_octet iiopversion[] = {1,0};
++ CORBA_octet codecbuf[2048];
++
++ g_assert(obj!=NULL);
++ g_assert(codec!=NULL);
++ g_assert(profile!=NULL);
++
++ if((profile == obj->active_profile) && (emit_active == FALSE))
++ return; /* we already did this one */
++
++ switch(profile->profile_type) {
++ case IOP_TAG_INTERNET_IOP:
++ CDR_codec_init_static(encaps);
++ encaps->buffer = codecbuf;
++ encaps->release_buffer = CORBA_FALSE;
++ encaps->buf_len = 2048;
++ encaps->readonly = CORBA_FALSE;
++ encaps->host_endian = encaps->data_endian = FLAG_ENDIANNESS;
++
++ CDR_put_ulong(codec, IOP_TAG_INTERNET_IOP);
++ CDR_put_octet(encaps, FLAG_ENDIANNESS);
++ CDR_put_octets(encaps, (gpointer)iiopversion, sizeof(iiopversion));
++ CDR_put_string(encaps, profile->tag.iopinfo.host);
++ CDR_put_ushort(encaps, profile->tag.iopinfo.port);
++ CDR_put_ulong(encaps, profile->object_key._length);
++ CDR_put_octets(encaps, profile->object_key._buffer,
++ profile->object_key._length);
++ CDR_put_ulong(codec, encaps->wptr);
++ CDR_put_octets(codec, encaps->buffer, encaps->wptr);
++ break;
++
++ case IOP_TAG_ORBIT_SPECIFIC:
++ CDR_codec_init_static(encaps);
++ encaps->buffer = codecbuf;
++ encaps->release_buffer = CORBA_FALSE;
++ encaps->buf_len = 2048;
++ encaps->readonly = CORBA_FALSE;
++ encaps->host_endian = encaps->data_endian = FLAG_ENDIANNESS;
++
++ CDR_put_ulong(codec, IOP_TAG_ORBIT_SPECIFIC);
++ CDR_put_octet(encaps, FLAG_ENDIANNESS);
++ CDR_put_octets(encaps, (gpointer)iiopversion, sizeof(iiopversion));
++ CDR_put_string(encaps, profile->tag.orbitinfo.unix_sock_path);
++ CDR_put_ushort(encaps, profile->tag.orbitinfo.ipv6_port);
++ CDR_put_ulong(encaps, profile->object_key._length);
++ CDR_put_octets(encaps, profile->object_key._buffer,
++ profile->object_key._length);
++ CDR_put_ulong(codec, encaps->wptr);
++ CDR_put_octets(codec, encaps->buffer, encaps->wptr);
++ break;
++
++ default:
++ g_warning("Skipping tag %d", profile->profile_type);
++ break;
++ }
++}
++
++CORBA_char *CORBA_ORB_object_to_string(CORBA_ORB orb,
++ CORBA_Object obj,
++ CORBA_Environment *ev)
++{
++ int i;
++ CDR_Codec codec_d;
++ CDR_Codec *codec = &codec_d;
++ CORBA_char *rc = NULL;
++ CORBA_unsigned_long ntags;
++ profile_user_data data;
++ CORBA_octet codecbuf[2048];
++ char *ctmp;
++
++ g_return_val_if_fail(ev, NULL);
++ o_return_val_if_fail(orb && obj, NULL);
++
++ if(!obj || !orb) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ if(ORBIT_ROOT_OBJECT(obj)->is_pseudo_object) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ CDR_codec_init_static(codec);
++
++ codec->buffer = codecbuf;
++ codec->release_buffer = CORBA_FALSE;
++ codec->buf_len = 2048;
++ codec->readonly = CORBA_FALSE;
++ codec->host_endian = codec->data_endian = FLAG_ENDIANNESS;
++
++ CDR_put_octet(codec, FLAG_ENDIANNESS);
++
++ CDR_put_string(codec, obj->object_id);
++ ntags = g_slist_length(obj->profile_list);
++ CDR_put_ulong(codec, ntags);
++
++ data.obj=obj;
++ data.codec=codec;
++ data.emit_active=TRUE;
++ if(obj->active_profile != NULL)
++ ORBit_emit_profile(obj->active_profile, &data); /* do this one first */
++
++ data.emit_active=FALSE;
++ g_slist_foreach(obj->profile_list, ORBit_emit_profile, &data);
++
++ rc = CORBA_string_alloc(4 + (codec->wptr * 2) + 1);
++ strcpy(rc, "IOR:");
++
++#define hexdigit(n) (((n)>9)?(n+'a'-10):(n+'0'))
++
++ for(i = 0, ctmp = rc + strlen("IOR:"); i < codec->wptr; i++) {
++ *(ctmp++) = hexdigit((((codec->buffer[i]) & 0xF0) >> 4));
++ *(ctmp++) = hexdigit(((codec->buffer[i]) & 0xF));
++ }
++ *ctmp = '\0';
++
++ {
++ /* Debug check */
++ CORBA_Object obj;
++ CORBA_Environment myev;
++
++ CORBA_exception_init(&myev);
++
++ obj = CORBA_ORB_string_to_object(orb, rc, &myev);
++
++ if (CORBA_Object_is_nil(obj, &myev)) {
++ g_warning("Bug in %s, created bad IOR `%s'\n",
++ __FUNCTION__, rc);
++ CORBA_free(rc);
++ return NULL;
++ }
++
++ CORBA_Object_release(obj, &myev);
++ }
++
++ return rc;
++}
++
++/* Quote from the GNU libc manual:
++
++ "If you try to allocate more storage than the machine can provide,
++ you don't get a clean error message. Instead you get a fatal
++ signal like the one you would get from an infinite recursion;
++ probably a segmentation violation (see section Program Error
++ Signals)."
++
++ The man page claims alloca() returns NULL on failure; this appears
++ to be a load of shit on Linux where you just get flaming death, but
++ we check anyway in case other systems work that way.
++
++ On Linux we check that the size is less than MAX_STACK_ALLOC
++
++ Note that the CORBA_alloc() calls in here can still cause
++ program abort, and really that should be fixed in a similar
++ way since our lengths are coming in from unpredictable sources
++ like files or the network.
++*/
++
++#define MAX_STACK_ALLOC 8192
++
++CORBA_Object CORBA_ORB_string_to_object(CORBA_ORB orb, CORBA_char *str,
++ CORBA_Environment *ev)
++{
++ GSList *profiles=NULL;
++ CORBA_Object retval = NULL;
++ CORBA_char *type_id;
++ ORBit_Object_info *object_info;
++ CDR_Codec codec_d, encaps_codec_d;
++ CDR_Codec *codec = &codec_d, *encaps_codec = &encaps_codec_d;
++ CORBA_octet *buffer, endian;
++ int i, j;
++ CORBA_unsigned_long len, seq_len, misclen;
++
++ g_return_val_if_fail(ev, CORBA_OBJECT_NIL);
++ o_return_val_if_fail(orb && str, CORBA_OBJECT_NIL);
++
++ if(strncmp(str, "IOR:", 4)) {
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_NO);
++ return(CORBA_OBJECT_NIL);
++ }
++
++ CDR_codec_init_static(codec);
++ len = strlen(str);
++
++ if((len % 2) || len <= 4) {
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_NO);
++ return(CORBA_OBJECT_NIL);
++ }
++
++ codec->buf_len = (len-4)/2;
++ buffer = alloca(codec->buf_len);
++
++ codec->buffer=buffer;
++ codec->release_buffer = CORBA_FALSE;
++ codec->readonly = TRUE;
++
++ for(j = 0, i = 4; i < len; i+=2) {
++ buffer[j++] = HEXOCTET(str[i], str[i+1]);
++ };
++
++ CDR_get_octet(codec, &endian);
++
++ codec->data_endian = endian;
++ codec->host_endian = FLAG_ENDIANNESS;
++
++ CDR_get_string_static(codec, &type_id);
++
++ CDR_get_seq_begin(codec, &seq_len);
++
++ for(i = 0; i < seq_len; i++) {
++ IOP_ProfileId tag;
++
++ object_info=g_new0(ORBit_Object_info, 1);
++
++ if (!CDR_get_ulong(codec, &tag))
++ goto error_out;
++
++ switch(tag) {
++ case IOP_TAG_INTERNET_IOP:
++ if (!CDR_get_ulong(codec, &misclen))
++ goto error_out;
++
++ CDR_codec_init_static(encaps_codec);
++
++ if (misclen > MAX_STACK_ALLOC)
++ goto error_out;
++
++ encaps_codec->buffer = alloca(misclen);
++ if (encaps_codec->buffer == NULL)
++ /* misclen was probably junk */
++ goto error_out;
++
++ encaps_codec->release_buffer = FALSE;
++ if(!CDR_buffer_gets(codec, encaps_codec->buffer, misclen))
++ goto error_out;
++
++ encaps_codec->buf_len = misclen;
++ encaps_codec->readonly = CORBA_TRUE;
++ if(!CDR_get_octet(encaps_codec, &endian))
++ goto error_out;
++ encaps_codec->data_endian = endian;
++ encaps_codec->host_endian = FLAG_ENDIANNESS;
++
++ if (encaps_codec->data_endian > 1)
++ goto error_out;
++
++ object_info->profile_type = IOP_TAG_INTERNET_IOP;
++ if(!CDR_get_octet(encaps_codec, &object_info->iiop_major))
++ goto error_out;
++ if(object_info->iiop_major != 1)
++ goto error_out;
++ if(!CDR_get_octet(encaps_codec, &object_info->iiop_minor))
++ goto error_out;
++ if(!CDR_get_string(encaps_codec, &object_info->tag.iopinfo.host))
++ goto error_out;
++ if(!CDR_get_ushort(encaps_codec, &object_info->tag.iopinfo.port))
++ goto error_out;
++ if(!CDR_get_seq_begin(encaps_codec, &object_info->object_key._length))
++ goto error_out;
++
++ object_info->object_key._maximum = 0;
++
++ /* The POA gives out ORBit_alloc()d profiles, so we have to too */
++ object_info->object_key._buffer = ORBit_alloc(object_info->object_key._length, NULL, NULL);
++ if(!CDR_buffer_gets(encaps_codec, object_info->object_key._buffer,
++ object_info->object_key._length))
++ goto error_out;
++
++ ORBit_set_object_key(object_info);
++ profiles=g_slist_append(profiles, object_info);
++ break;
++
++ case IOP_TAG_MULTIPLE_COMPONENTS:
++ /* Just skip any multiple_components data, for now */
++ if(!CDR_get_ulong(codec, &misclen))
++ goto error_out;
++
++ CDR_codec_init_static(encaps_codec);
++
++ if (misclen > MAX_STACK_ALLOC)
++ goto error_out;
++
++ encaps_codec->buf_len = misclen;
++ encaps_codec->buffer = alloca(misclen);
++ if (encaps_codec->buffer == NULL)
++ /* misclen was probably junk */
++ goto error_out;
++
++ encaps_codec->release_buffer = FALSE;
++ encaps_codec->readonly = CORBA_TRUE;
++ if(!CDR_buffer_gets(codec, encaps_codec->buffer, misclen))
++ goto error_out;
++ break;
++
++ case IOP_TAG_ORBIT_SPECIFIC:
++ if(!CDR_get_ulong(codec, &misclen))
++ goto error_out;
++
++ CDR_codec_init_static(encaps_codec);
++
++ if (misclen > MAX_STACK_ALLOC)
++ goto error_out;
++
++ encaps_codec->buffer = alloca(misclen);
++ if (encaps_codec->buffer == NULL)
++ /* misclen was probably junk */
++ goto error_out;
++
++ encaps_codec->release_buffer = FALSE;
++ if(!CDR_buffer_gets(codec, encaps_codec->buffer, misclen))
++ goto error_out;
++
++ encaps_codec->buf_len = misclen;
++ encaps_codec->readonly = CORBA_TRUE;
++
++ if(!CDR_get_octet(encaps_codec, &endian))
++ goto error_out;
++
++ encaps_codec->data_endian = endian;
++ encaps_codec->host_endian = FLAG_ENDIANNESS;
++
++ if (encaps_codec->data_endian > 1)
++ goto error_out;
++
++ object_info->profile_type=IOP_TAG_ORBIT_SPECIFIC;
++ if(!CDR_get_octet(encaps_codec, &object_info->iiop_major))
++ goto error_out;
++
++ if(object_info->iiop_major != 1)
++ goto error_out;
++ if(!CDR_get_octet(encaps_codec, &object_info->iiop_minor))
++ goto error_out;
++
++ if(!CDR_get_string(encaps_codec, &object_info->tag.orbitinfo.unix_sock_path))
++ goto error_out;
++
++ if(!CDR_get_ushort(encaps_codec, &object_info->tag.orbitinfo.ipv6_port))
++ goto error_out;
++ if(!CDR_get_seq_begin(encaps_codec, &object_info->object_key._length))
++ goto error_out;
++ object_info->object_key._maximum = 0;
++
++ /* The POA gives out ORBit_alloc()d profiles, so we have to too */
++ object_info->object_key._buffer = ORBit_alloc(object_info->object_key._length, NULL, NULL);
++ if(!CDR_buffer_gets(encaps_codec, object_info->object_key._buffer,
++ object_info->object_key._length))
++ goto error_out;
++
++ ORBit_set_object_key(object_info);
++ profiles=g_slist_append(profiles, object_info);
++ break;
++ default:
++ g_warning("Unknown tag 0x%x", tag);
++
++ /* Skip it */
++ if(!CDR_get_ulong(codec, &misclen))
++ goto error_out;
++
++ CDR_codec_init_static(encaps_codec);
++
++ if (misclen > MAX_STACK_ALLOC)
++ goto error_out;
++
++ encaps_codec->buf_len = misclen;
++ encaps_codec->buffer = alloca(misclen);
++ if (encaps_codec->buffer == NULL)
++ /* misclen was probably junk */
++ goto error_out;
++
++ encaps_codec->release_buffer = FALSE;
++ encaps_codec->readonly = CORBA_TRUE;
++ if(!CDR_buffer_gets(codec, encaps_codec->buffer, misclen))
++ goto error_out;
++
++ break;
++ }
++ }
++
++ freeca(buffer); /* Same as codec->buffer */
++ freeca(encaps_codec->buffer);
++
++ return ORBit_create_object_with_info(profiles, type_id, orb, ev);
++
++ error_out:
++
++ if(object_info) {
++ CORBA_free(object_info->object_key._buffer);
++ g_free(object_info);
++ ORBit_delete_profiles(profiles);
++ }
++
++ freeca(buffer); /* Same as codec->buffer */
++ freeca(encaps_codec->buffer);
++
++ return retval;
++}
++
++/* Section 4.1.2 */
++CORBA_boolean CORBA_ORB_get_service_information(CORBA_ORB orb, CORBA_ServiceType service_type, CORBA_ServiceInformation *service_information, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(CORBA_FALSE);
++}
++
++CORBA_Current *CORBA_ORB_get_current(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, NULL);
++ o_return_val_if_fail(orb, NULL);
++
++ /* XXX check this over */
++ return (CORBA_Current *)GET_THREAD_DATA();
++}
++
++/* Section 4.5 */
++CORBA_ORB_ObjectIdList *CORBA_ORB_list_initial_services(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ static const char *services[] = {"RootPOA"};
++ CORBA_ORB_ObjectIdList *list;
++
++ g_return_val_if_fail(ev, NULL);
++ o_return_val_if_fail(orb, NULL);
++
++ list = (CORBA_ORB_ObjectIdList *)CORBA_sequence_octet__alloc();
++ list->_maximum=list->_length= 1;
++ list->_buffer = (CORBA_ORB_ObjectId *)services;
++ CORBA_sequence_set_release((void *)list, CORBA_FALSE);
++
++ /* defined reserved references are:
++ * RootPOA
++ * POACurrent
++ * InterfaceRepository
++ * NameService
++ * TradingService
++ * SecurityCurrent
++ * TransactionCurrent
++ */
++
++ return list;
++}
++
++/* Section 4.5
++ *
++ * raises InvalidName
++ */
++CORBA_Object CORBA_ORB_resolve_initial_references(CORBA_ORB orb, CORBA_ORB_ObjectId identifier, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, CORBA_OBJECT_NIL);
++ o_return_val_if_fail(orb, CORBA_OBJECT_NIL);
++
++ if(!strcmp(identifier, "ImplementationRepository"))
++ return CORBA_Object_duplicate(orb->imr, ev);
++ else if(!strcmp(identifier, "InterfaceRepository"))
++ return CORBA_Object_duplicate(orb->ir, ev);
++ else if(!strcmp(identifier, "NameService"))
++ return CORBA_Object_duplicate(orb->naming, ev);
++ else if(!strcmp(identifier, "RootPOA")) {
++ if(CORBA_Object_is_nil(orb->root_poa, ev)) {
++ CORBA_PolicyList policies = {0,0,NULL,CORBA_FALSE};
++ PortableServer_POAManager poa_mgr;
++ /* Create a poa manager */
++ poa_mgr = ORBit_POAManager_new(ev);
++ poa_mgr->orb = orb;
++
++ /* Create the root poa */
++ orb->root_poa = (CORBA_Object)
++ ORBit_POA_new(orb,
++ "RootPOA",
++ poa_mgr,
++ &policies,
++ ev);
++ CORBA_Object_duplicate(orb->root_poa, ev);
++ }
++
++ return CORBA_Object_duplicate(orb->root_poa, ev);
++ }
++
++ /* throw user exception: InvalidName */
++ CORBA_exception_set(ev,CORBA_USER_EXCEPTION,
++ ex_CORBA_ORB_InvalidName,
++ NULL);
++
++ goto error;
++error:
++ return(NULL);
++}
++
++/* This is a MICO extension
++ *
++ * raises InvalidName
++ */
++void CORBA_ORB_set_initial_reference(CORBA_ORB orb, CORBA_ORB_ObjectId identifier, CORBA_Object obj, CORBA_Environment *ev)
++{
++ g_return_if_fail(ev);
++ o_return_if_fail(orb && identifier && obj);
++
++ if(!strcmp(identifier, "ImplementationRepository")) {
++ if(!CORBA_Object_is_nil(orb->imr, ev)) {
++ CORBA_Object_release(orb->imr, ev);
++ }
++ orb->imr=CORBA_Object_duplicate(obj, ev);
++ } else if(!strcmp(identifier, "InterfaceRepository")) {
++ if(!CORBA_Object_is_nil(orb->ir, ev)) {
++ CORBA_Object_release(orb->ir, ev);
++ }
++ orb->ir=CORBA_Object_duplicate(obj, ev);
++ } else if(!strcmp(identifier, "NameService")) {
++ if(!CORBA_Object_is_nil(orb->naming, ev)) {
++ CORBA_Object_release(orb->naming, ev);
++ }
++ orb->naming=CORBA_Object_duplicate(obj, ev);
++ } else if(!strcmp(identifier, "RootPOA")) {
++ if(!CORBA_Object_is_nil(orb->root_poa, ev)) {
++ CORBA_Object_release(orb->root_poa, ev);
++ }
++ orb->root_poa=CORBA_Object_duplicate(obj, ev);
++ } else {
++ /* throw user exception: InvalidName */
++ CORBA_exception_set(ev,CORBA_USER_EXCEPTION,ex_CORBA_ORB_InvalidName,NULL);
++ goto error;
++ }
++
++ return;
++error:
++ return;
++}
++
++/* Section 4.9.1 */
++CORBA_boolean CORBA_ORB_work_pending(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(CORBA_FALSE);
++}
++
++/* Section 4.9.2 */
++void CORBA_ORB_perform_work(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return;
++}
++
++/* Section 4.9.4 */
++void
++CORBA_ORB_shutdown(CORBA_ORB orb,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev)
++{
++ g_return_if_fail(ev);
++ o_return_if_fail(orb);
++
++ /* XXX implement on a per-ORB basis, and also
++ handle whatever wait_for_completion means */
++
++ if(orb->cnx.ipv4)
++ giop_connection_unref(orb->cnx.ipv4);
++ if(orb->cnx.ipv6)
++ giop_connection_unref(orb->cnx.ipv6);
++#ifndef __KORBIT__
++ if(orb->cnx.usock)
++ giop_connection_unref(orb->cnx.usock);
++#endif
++
++ giop_main_quit();
++}
++
++/* Section 4.9.3 */
++/* CORBA_ORB_run is in server.c */
++
++/* Section 4.7 */
++CORBA_PolicyType
++CORBA_Policy__get_policy_type(CORBA_Policy obj, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, 0);
++ o_return_val_if_fail(obj, 0);
++
++ return obj->policy_type;
++}
++
++/* Section 4.7 */
++CORBA_Policy CORBA_Policy_copy(CORBA_Policy obj, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, CORBA_OBJECT_NIL);
++ o_return_val_if_fail(obj, CORBA_OBJECT_NIL);
++
++ ORBIT_ROOT_OBJECT_REF(obj);
++
++ return obj;
++}
++
++/* Section 4.7
++ *
++ * raises CORBA_NO_PERMISSION
++ */
++void CORBA_Policy_destroy(CORBA_Policy obj, CORBA_Environment *ev)
++{
++ g_return_if_fail(ev);
++ o_return_if_fail(obj);
++
++ ORBIT_ROOT_OBJECT_UNREF(obj);
++ if(ORBIT_ROOT_OBJECT(obj)->refs <= 0)
++ ORBIT_ROOT_OBJECT_release(obj, ev);
++}
++
++#ifndef __KORBIT__
++/* Section 4.8.2 */
++CORBA_Policy CORBA_DomainManager_get_domain_policy(CORBA_DomainManager obj, CORBA_PolicyType policy_type, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, CORBA_OBJECT_NIL);
++ o_return_val_if_fail(obj, CORBA_OBJECT_NIL);
++
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++/* Section 4.8.2 */
++void CORBA_ConstructionPolicy_make_domain_manager(CORBA_ConstructionPolicy obj, CORBA_InterfaceDef object_type, CORBA_boolean constr_policy, CORBA_Environment *
++ev)
++{
++ g_return_if_fail(ev);
++ o_return_if_fail(obj && object_type);
++
++ g_assert(!"Not yet implemented");
++ return;
++}
++
++/* Section 4.2.8 */
++CORBA_DomainManagerList *CORBA_Object_get_domain_managers(CORBA_Object obj, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(ev, NULL);
++ o_return_val_if_fail(obj, NULL);
++
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++CORBA_TypeCode CORBA_ORB_create_struct_tc(CORBA_ORB obj, CORBA_RepositoryId id, CORBA_Identifier name, CORBA_StructMemberSeq members, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++ int i;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc == NULL)
++ goto tc_alloc_failed;
++
++ tc->subtypes=g_new0(CORBA_TypeCode, members._length);
++ if(tc->subtypes == NULL)
++ goto subtypes_alloc_failed;
++
++ tc->subnames=g_new0(char *, members._length);
++ if(tc->subnames == NULL)
++ goto subnames_alloc_failed;
++
++ tc->kind=CORBA_tk_struct;
++ tc->name=g_strdup(name);
++ tc->repo_id=g_strdup(id);
++ tc->sub_parts=members._length;
++ tc->length=members._length;
++
++ for(i=0;i<members._length;i++) {
++ CORBA_StructMember *mem=(CORBA_StructMember *)&(members._buffer[i]);
++
++ g_assert(&(mem->type)!=NULL);
++
++ tc->subtypes[i] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[i], mem->type, (size_t)sizeof(struct CORBA_TypeCode_struct));
++ tc->subnames[i]=g_strdup(mem->name);
++ }
++
++ return(tc);
++
++ subnames_alloc_failed:
++ g_free(tc->subtypes);
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return NULL;
++}
++
++CORBA_TypeCode
++CORBA_ORB_create_union_tc(CORBA_ORB obj, CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_TypeCode discriminator_type,
++ CORBA_UnionMemberSeq members,
++ CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++ int i;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++
++ if(tc == NULL)
++ goto tc_alloc_failed;
++
++ tc->discriminator = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++
++ if(tc->discriminator == NULL)
++ goto discriminator_alloc_failed;
++
++ memcpy(tc->discriminator, discriminator_type, (size_t)sizeof(CORBA_TypeCode));
++
++ tc->subtypes=g_new0(CORBA_TypeCode, members._length);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->subnames=g_new0(char *, members._length);
++ if(tc->subnames==NULL)
++ goto subnames_alloc_failed;
++
++ tc->sublabels=g_new0(CORBA_any, members._length);
++ if(tc->sublabels == NULL)
++ goto sublabels_alloc_failed;
++
++ tc->kind=CORBA_tk_union;
++ tc->name=g_strdup(name);
++ tc->repo_id=g_strdup(id);
++ tc->sub_parts=members._length;
++ tc->length=members._length;
++ tc->default_index=-1;
++
++ for(i=0;i<members._length;i++) {
++ CORBA_UnionMember *mem=(CORBA_UnionMember *)&(members._buffer[i]);
++
++ g_assert(&(mem->label)!=NULL);
++ memcpy(&(tc->sublabels[i]), &(mem->label), (size_t)sizeof(CORBA_any));
++ g_assert(&(mem->type)!=NULL);
++ tc->subtypes[i] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[i], mem->type, (size_t)sizeof(struct CORBA_TypeCode_struct));
++ tc->subnames[i]=g_strdup(mem->name);
++
++ if(mem->label._type->kind==CORBA_tk_octet) {
++ tc->default_index=i;
++ }
++ }
++
++ return(tc);
++
++sublabels_alloc_failed:
++ g_free(tc->sublabels);
++subnames_alloc_failed:
++ g_free(tc->subtypes);
++subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc->discriminator);
++discriminator_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return NULL;
++}
++
++CORBA_TypeCode CORBA_ORB_create_enum_tc(CORBA_ORB obj, CORBA_RepositoryId id, CORBA_Identifier name, CORBA_EnumMemberSeq members, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++ int i;
++
++ tc = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc == NULL)
++ goto tc_alloc_failed;
++
++ tc->subnames=g_new0(char *, members._length);
++ if(tc->subnames==NULL)
++ goto subnames_alloc_failed;
++
++ tc->kind = CORBA_tk_enum;
++ tc->name = g_strdup(name);
++ tc->repo_id = g_strdup(id);
++ tc->sub_parts = members._length;
++ tc->length = members._length;
++
++ for(i=0;i<members._length;i++) {
++ tc->subnames[i]=g_strdup(members._buffer[i]);
++ }
++
++ return(tc);
++
++ subnames_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++}
++
++CORBA_TypeCode CORBA_ORB_create_alias_tc(CORBA_ORB obj, CORBA_RepositoryId id, CORBA_Identifier name, CORBA_TypeCode original_type, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL)
++ goto tc_alloc_failed;
++
++ /* Can't use chunks here, because it's sometimes an array. Doh! */
++ tc->subtypes=g_new0(CORBA_TypeCode, 1);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->kind=CORBA_tk_alias;
++ tc->name=g_strdup(name);
++ tc->repo_id=g_strdup(id);
++ tc->sub_parts=1;
++ tc->length=1;
++
++ tc->subtypes[0] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[0], original_type, (size_t)sizeof(struct CORBA_TypeCode_struct));
++
++ return(tc);
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return NULL;
++}
++
++CORBA_TypeCode CORBA_ORB_create_exception_tc(CORBA_ORB obj, CORBA_RepositoryId id, CORBA_Identifier name, CORBA_StructMemberSeq members, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++ int i;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL)
++ goto tc_alloc_failed;
++
++ tc->subtypes=g_new0(CORBA_TypeCode, members._length);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->subnames=g_new0(char *, members._length);
++ if(tc->subnames==NULL)
++ goto subnames_alloc_failed;
++
++ tc->kind=CORBA_tk_except;
++ tc->name=g_strdup(name);
++ tc->repo_id=g_strdup(id);
++ tc->sub_parts=members._length;
++ tc->length=members._length;
++
++ for(i=0;i<members._length;i++) {
++ CORBA_StructMember *mem=(CORBA_StructMember *)&(members._buffer[i]);
++
++ g_assert(mem->type != NULL);
++ tc->subtypes[i] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[i], mem->type, (size_t)sizeof(struct CORBA_TypeCode_struct));
++ tc->subnames[i]=g_strdup(mem->name);
++ }
++
++ return(tc);
++
++ subnames_alloc_failed:
++ g_free(tc->subtypes);
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++}
++
++CORBA_TypeCode CORBA_ORB_create_interface_tc(CORBA_ORB obj, CORBA_RepositoryId id, CORBA_Identifier name, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY,
++ CORBA_COMPLETED_NO);
++ return(NULL);
++ }
++
++ tc->kind=CORBA_tk_objref;
++ tc->name=g_strdup(name);
++ tc->repo_id=g_strdup(id);
++
++ return(tc);
++}
++
++CORBA_TypeCode CORBA_ORB_create_string_tc(CORBA_ORB obj, CORBA_unsigned_long bound, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++ }
++
++ tc->kind=CORBA_tk_string;
++ tc->length=bound;
++
++ return(tc);
++}
++
++CORBA_TypeCode CORBA_ORB_create_wstring_tc(CORBA_ORB obj, CORBA_unsigned_long bound, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++ }
++
++ tc->kind=CORBA_tk_wstring;
++ tc->length=bound;
++
++ return(tc);
++}
++
++CORBA_TypeCode CORBA_ORB_create_fixed_tc(CORBA_ORB obj, CORBA_unsigned_short digits, CORBA_short scale, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++ }
++
++ tc->kind=CORBA_tk_fixed;
++ tc->digits=digits;
++ tc->scale=scale;
++
++ return(tc);
++}
++
++CORBA_TypeCode CORBA_ORB_create_sequence_tc(CORBA_ORB obj, CORBA_unsigned_long bound, CORBA_TypeCode element_type, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL)
++ goto tc_alloc_failed;
++
++ /* Can't use chunks here because we can only be sure of getting
++ one consecutive chunk from glib */
++ tc->subtypes=g_new0(CORBA_TypeCode, 1);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->kind=CORBA_tk_sequence;
++ tc->sub_parts=1;
++ tc->length=bound;
++
++ tc->subtypes[0] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[0], element_type,
++ (size_t)sizeof(struct CORBA_TypeCode_struct));
++
++ return(tc);
++
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++}
++
++CORBA_TypeCode CORBA_ORB_create_recursive_sequence_tc(CORBA_ORB obj, CORBA_unsigned_long bound, CORBA_unsigned_long offset, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL)
++ goto tc_alloc_failed;
++
++ tc->subtypes=g_new0(CORBA_TypeCode, 1);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->kind=CORBA_tk_sequence;
++ tc->sub_parts=1;
++ tc->length=bound;
++
++ tc->subtypes[0] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ tc->subtypes[0]->kind=CORBA_tk_recursive;
++ tc->subtypes[0]->recurse_depth=offset;
++
++ return(tc);
++
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++}
++
++CORBA_TypeCode CORBA_ORB_create_array_tc(CORBA_ORB obj, CORBA_unsigned_long length, CORBA_TypeCode element_type, CORBA_Environment *ev)
++{
++ CORBA_TypeCode tc;
++
++ tc=ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ if(tc==NULL)
++ goto tc_alloc_failed;
++
++ tc->subtypes=g_new0(CORBA_TypeCode, 1);
++ if(tc->subtypes==NULL)
++ goto subtypes_alloc_failed;
++
++ tc->kind=CORBA_tk_array;
++ tc->sub_parts=1;
++ tc->length=length;
++
++ tc->subtypes[0] = ORBIT_CHUNK_ALLOC(CORBA_TypeCode);
++ memcpy(tc->subtypes[0], element_type, (size_t)sizeof(CORBA_TypeCode));
++
++ return(tc);
++
++ subtypes_alloc_failed:
++ ORBIT_CHUNK_FREE(CORBA_TypeCode, tc);
++ tc_alloc_failed:
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ return(NULL);
++}
++#endif /* !__KORBIT__ */
+diff -urN linux-2.4.1/net/korbit/orb/orb.h linux-2.4.1-korbit/net/korbit/orb/orb.h
+--- linux-2.4.1/net/korbit/orb/orb.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orb.h Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,231 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_ORB_H_
++#define _ORBIT_ORB_H_
++
++#include "orb/orbit_types.h"
++#ifndef __KORBIT__
++#include "orb/interface_repository.h"
++#endif /* !__KORBIT__ */
++
++extern CORBA_ORB CORBA_ORB_init(
++ int *argc,
++ char **argv,
++ CORBA_ORBid orb_identifier,
++ CORBA_Environment *ev);
++
++extern CORBA_char *CORBA_ORB_object_to_string(
++ CORBA_ORB orb,
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Object CORBA_ORB_string_to_object(
++ CORBA_ORB orb,
++ CORBA_char *str,
++ CORBA_Environment *ev);
++
++extern CORBA_Status CORBA_ORB_get_default_context(
++ CORBA_ORB orb,
++ CORBA_Context *ctx,
++ CORBA_Environment *ev);
++
++extern CORBA_boolean CORBA_ORB_get_service_information(
++ CORBA_ORB orb,
++ CORBA_ServiceType service_type,
++ CORBA_ServiceInformation *service_information,
++ CORBA_Environment *ev);
++
++extern CORBA_Current *CORBA_ORB_get_current(
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++extern CORBA_ORB_ObjectIdList* CORBA_ORB_list_initial_services(
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++extern CORBA_Object CORBA_ORB_resolve_initial_references(
++ CORBA_ORB orb,
++ CORBA_ORB_ObjectId identifier,
++ CORBA_Environment *ev);
++
++extern void CORBA_ORB_set_initial_reference(
++ CORBA_ORB orb,
++ CORBA_ORB_ObjectId identifier,
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_boolean CORBA_ORB_work_pending(
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++extern void CORBA_ORB_perform_work(
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++extern void CORBA_ORB_shutdown(
++ CORBA_ORB orb,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev);
++
++extern void CORBA_ORB_run(
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++extern CORBA_PolicyType CORBA_Policy__get_policy_type(
++ CORBA_Policy obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Policy CORBA_Policy_copy(
++ CORBA_Policy obj,
++ CORBA_Environment *ev);
++
++extern void CORBA_Policy_destroy(
++ CORBA_Policy obj,
++ CORBA_Environment *ev);
++
++#ifndef __KORBIT__
++extern CORBA_InterfaceDef CORBA_Object_get_interface(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++#endif /* !__KORBIT__ */
++
++extern CORBA_boolean CORBA_Object_is_nil(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Object CORBA_Object_duplicate(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern void CORBA_Object_release(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_boolean CORBA_Object_non_existent(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_boolean CORBA_Object_is_equivalent(
++ CORBA_Object obj,
++ CORBA_Object other_object,
++ CORBA_Environment *ev);
++
++extern CORBA_unsigned_long CORBA_Object_hash(
++ CORBA_Object obj,
++ CORBA_unsigned_long maximum,
++ CORBA_Environment *ev);
++
++extern CORBA_Policy CORBA_Object_get_policy(
++ CORBA_Object obj,
++ CORBA_PolicyType policy_type,
++ CORBA_Environment *ev);
++
++#ifndef __KORBIT__
++extern CORBA_DomainManagerList *CORBA_Object_get_domain_managers(
++ CORBA_Object obj,
++ CORBA_Environment *ev);
++
++extern CORBA_Policy CORBA_DomainManager_get_domain_policy(
++ CORBA_DomainManager obj,
++ CORBA_PolicyType policy_type,
++ CORBA_Environment *ev);
++
++extern void CORBA_ConstructionPolicy_make_domain_manager(
++ CORBA_ConstructionPolicy obj,
++ CORBA_Object /*CORBA_InterfaceDef*/ object_type,
++ CORBA_boolean constr_policy,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_struct_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_StructMemberSeq members,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_union_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_TypeCode discriminator_type,
++ CORBA_UnionMemberSeq members,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_enum_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_EnumMemberSeq members,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_alias_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_TypeCode original_type,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_exception_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_StructMemberSeq members,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_interface_tc(CORBA_ORB obj,
++ CORBA_RepositoryId id,
++ CORBA_Identifier name,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_string_tc(CORBA_ORB obj,
++ CORBA_unsigned_long bound,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_wstring_tc(CORBA_ORB obj,
++ CORBA_unsigned_long bound,
++ CORBA_Environment *ev);
++
++CORBA_TypeCode CORBA_ORB_create_fixed_tc(CORBA_ORB obj,
++ CORBA_unsigned_short digits,
++ CORBA_short scale,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_ORB_create_sequence_tc(
++ CORBA_ORB obj,
++ CORBA_unsigned_long bound,
++ CORBA_TypeCode element_type,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_ORB_create_recursive_sequence_tc(
++ CORBA_ORB obj,
++ CORBA_unsigned_long bound,
++ CORBA_unsigned_long offset,
++ CORBA_Environment *ev);
++
++extern CORBA_TypeCode CORBA_ORB_create_array_tc(
++ CORBA_ORB obj,
++ CORBA_unsigned_long length,
++ CORBA_TypeCode element_type,
++ CORBA_Environment *ev);
++
++#endif /* !__KORBIT__ */
++
++#endif /* !_ORBIT_ORB_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit.c linux-2.4.1-korbit/net/korbit/orb/orbit.c
+--- linux-2.4.1/net/korbit/orb/orbit.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit.c Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,387 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++/*
++ * This file is a repository for random functions that don't fit anywhere
++ * else, and for ORBit-specific stuff.
++ */
++
++#include <stdlib.h>
++#include <string.h>
++#include <sys/types.h>
++#include <netdb.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <assert.h>
++#include <math.h>
++
++#include "orbit.h"
++
++const guint orbit_major_version = ORBIT_MAJOR_VERSION,
++ orbit_minor_version = ORBIT_MINOR_VERSION,
++ orbit_micro_version = ORBIT_MICRO_VERSION;
++const char orbit_version[] = ORBIT_VERSION;
++
++typedef struct ORBitClassInfo ORBitClassInfo;
++
++typedef void (*ORBitObjectInitFunc)(CORBA_Object _handle_to_be, gpointer class_data);
++
++struct ORBitClassInfo {
++ char *name;
++ gulong id;
++ gpointer method_stubs, method_skels;
++ ORBitObjectInitFunc class_vtable_init_func;
++ ORBitClassInfo **parent_classes;
++};
++
++GHashTable *orbit_class_list = NULL, *orbit_class_byid;
++glong class_id_counter = -1;
++
++void CORBA_any_set_release(CORBA_any *any, CORBA_boolean flag)
++{
++ g_assert(any!=NULL);
++
++ if(flag==CORBA_TRUE) {
++ any->_release |= CORBA_ANYFLAGS_RELEASE;
++ } else {
++ any->_release &= ~CORBA_ANYFLAGS_RELEASE;
++ }
++
++}
++
++CORBA_boolean CORBA_any_get_release(CORBA_any *any)
++{
++ g_assert(any!=NULL);
++
++ if(any->_release & CORBA_ANYFLAGS_RELEASE)
++ return(CORBA_TRUE);
++ else
++ return(CORBA_FALSE);
++}
++
++void CORBA_sequence_set_release(void *seq, CORBA_boolean flag)
++{
++ struct CORBA_Sequence_type *sequence;
++
++ g_assert(seq!=NULL);
++
++ sequence=(struct CORBA_Sequence_type *)seq;
++
++ if(flag==CORBA_TRUE) {
++ sequence->_release |= CORBA_ANYFLAGS_RELEASE;
++ } else {
++ sequence->_release &= ~CORBA_ANYFLAGS_RELEASE;
++ }
++}
++
++CORBA_boolean CORBA_sequence_get_release(void *seq)
++{
++ struct CORBA_Sequence_type *sequence;
++
++ g_assert(seq!=NULL);
++
++ sequence=(struct CORBA_Sequence_type *)seq;
++
++ if(sequence->_release & CORBA_ANYFLAGS_RELEASE)
++ return(CORBA_TRUE);
++ else
++ return(CORBA_FALSE);
++}
++
++/*
++ * As far as I understand, values returned by CORBA_*_alloc() are supposed to be
++ * freeable by CORBA_free(), so we can't use memory chunks here in any reasonable
++ * fashion.
++ */
++gpointer
++CORBA_any__free(gpointer mem, gpointer func_data, CORBA_boolean free_strings)
++{
++ CORBA_any *aval = mem;
++
++ if(aval->_release)
++ ORBit_free(aval->_value, free_strings);
++ CORBA_Object_release((CORBA_Object)aval->_type, NULL);
++
++ return aval + 1;
++}
++
++CORBA_any *CORBA_any_alloc(void)
++{
++ CORBA_any *retval = ORBit_alloc(sizeof(CORBA_any), &CORBA_any__free,
++ GINT_TO_POINTER(1));
++
++ memset(retval, 0, sizeof(CORBA_any)); /* Make things easier on stubs */
++
++ return retval;
++}
++
++/*
++ * Compares the typecodes of each any
++ */
++CORBA_boolean ORBit_any_equivalent(CORBA_any obj, CORBA_any any, CORBA_Environment *ev)
++{
++ return(CORBA_FALSE);
++}
++
++/* This is needed by skels, that generate a __free function when they see
++ the TypeCode interface */
++gpointer
++CORBA_TypeCode__free(gpointer mem, gpointer func_data, CORBA_boolean free_strings)
++{
++ CORBA_Object_release(*(CORBA_Object *)mem, NULL);
++ return ((guchar *)mem) + sizeof(CORBA_TypeCode);
++}
++
++CORBA_char *CORBA_string_dup(const CORBA_char *string)
++{
++ if(!string)
++ return NULL;
++
++ return strcpy(ORBit_alloc(strlen(string)+1, NULL, NULL), string);
++}
++
++CORBA_char *CORBA_string_alloc(CORBA_unsigned_long len)
++{
++ return ORBit_alloc(len + 1, NULL, NULL);
++}
++
++CORBA_wchar *CORBA_wstring_alloc(CORBA_unsigned_long len)
++{
++ return ORBit_alloc(len + 1, NULL, NULL);
++}
++
++gpointer
++CORBA_string__free(gpointer str, gpointer dat, CORBA_boolean free_strings)
++{
++ if(free_strings)
++ CORBA_free(*((gpointer *)str));
++ return (gpointer)((guchar *)str + sizeof(CORBA_char *));
++}
++
++gpointer CORBA_Object__free(gpointer str, gpointer dat, CORBA_boolean free_strings)
++{
++ CORBA_Environment ev;
++ CORBA_exception_init(&ev);
++ CORBA_Object_release(*((gpointer *)str), &ev);
++ CORBA_exception_free(&ev);
++ return (gpointer)((guchar *)str + sizeof(CORBA_Object));
++}
++
++/* 19.14 */
++
++/* The big picture for fixeds.
++ We have to represent a number in memory.
++
++ 1 2 3 . 4 5 6 7
++
++ There are three pieces of information in a fixed:
++
++ - Number of significant digits. (_digits)
++
++ - The scale. The number of places the decimal point is to the right
++ of the first significant digit. (_scale)
++
++ - The digits themselves (_value)
++
++ */
++CORBA_long CORBA_fixed_integer_part(const void *fp)
++{
++ CORBA_long retval = 0;
++ int i, power_of_ten, digit;
++ const CORBA_fixed_d_s *val = fp;
++
++ g_return_val_if_fail(fp != NULL, INT_MIN);
++
++ for(i = 0; i < (val->_digits - val->_scale); i++) {
++ power_of_ten = val->_digits - i - val->_scale - 1;
++ digit = val->_value[i];
++ retval += digit * ((int)pow(10, power_of_ten));
++ }
++
++ return retval;
++}
++
++CORBA_long CORBA_fixed_fraction_part(const void *fp)
++{
++ CORBA_long retval = 0;
++ int i, power_of_ten, digit;
++ const CORBA_fixed_d_s *val = fp;
++
++ g_return_val_if_fail(fp != NULL, INT_MIN);
++
++ for(i = val->_digits - val->_scale; i < val->_digits; i++){
++ power_of_ten = val->_digits - i - 1;
++ digit = val->_value[i];
++ retval += digit * ((int)pow(10, power_of_ten));
++ }
++
++ return retval;
++}
++
++static inline
++CORBA_long do_div (CORBA_long *n)
++{
++ int __res;
++
++ __res = (*n) % (unsigned) 10;
++ *n = (*n) / (unsigned) 10;
++
++ return __res;
++}
++
++void CORBA_fixed_set(void *rp, CORBA_long i, CORBA_long f)
++{
++ CORBA_fixed_d_s *val = rp;
++ CORBA_long left_to_eat, cur;
++ signed char sign = 1;
++
++ g_return_if_fail(rp != NULL);
++
++ memset(val->_value, 0, val->_digits);
++
++ if(i) sign = i/abs(i);
++ val->_sign = sign;
++ i = abs(i);
++ f = abs(f);
++
++ for(cur = 0, left_to_eat = i;
++ left_to_eat != 0 && cur < val->_digits; cur++) {
++ val->_value[cur] = do_div(&left_to_eat) * sign;
++ sign = 1;
++ }
++
++ val->_scale = cur - 1;
++
++ for(left_to_eat = f;
++ left_to_eat != 0 && cur < val->_digits; cur++) {
++ val->_value[cur] = do_div(&left_to_eat);
++ }
++}
++
++void CORBA_fixed_add(void *rp, const void *f1p, const void *f2p)
++{
++ g_assert(!"Not yet implemented");
++}
++
++void CORBA_fixed_sub(void *rp, const void *f1p, const void *f2p)
++{
++ g_assert(!"Not yet implemented");
++}
++
++void CORBA_fixed_mul(void *rp, const void *f1p, const void *f2p)
++{
++ g_assert(!"Not yet implemented");
++}
++
++void CORBA_fixed_div(void *rp, const void *f1p, const void *f2p)
++{
++ g_assert(!"Not yet implemented");
++}
++
++CORBA_fixed_d_s *CORBA_fixed_alloc(CORBA_unsigned_short d)
++{
++ return (CORBA_fixed_d_s *)
++ g_malloc(sizeof(CORBA_fixed_d_s) + d + 1);
++}
++
++void CORBA_free(void *storage)
++{
++ ORBit_free(storage, CORBA_TRUE);
++}
++
++int ORBit_parse_unixsock(CORBA_Object obj,
++ char *sockpath,
++ gboolean existing_only)
++{
++ if(!sockpath || !*sockpath)
++ return -1;
++
++ obj->connection =
++ GIOP_CONNECTION(iiop_connection_unix_get(sockpath,
++ existing_only));
++
++ if(!obj->connection)
++ return -1;
++
++ giop_connection_ref(obj->connection);
++ return 0;
++}
++
++int ORBit_parse_inet(CORBA_Object obj, char *hostname, unsigned short port,
++ gboolean existing_only)
++{
++ obj->connection = GIOP_CONNECTION(iiop_connection_get(hostname, port, existing_only));
++
++ if(!obj->connection)
++ return -1;
++ giop_connection_ref(obj->connection);
++ return 0;
++}
++
++static const CORBA_unsigned_long zero_int = 0;
++struct iovec ORBit_default_principal_iovec = {(gpointer)&zero_int, sizeof(zero_int)};
++
++void ORBit_set_default_principal(CORBA_Principal *principal)
++{
++ gpointer t;
++
++ if((gpointer)ORBit_default_principal_iovec.iov_base != (gpointer)&zero_int)
++ g_free(ORBit_default_principal_iovec.iov_base);
++
++ ORBit_default_principal_iovec.iov_len = principal->_length
++ + sizeof(CORBA_unsigned_long);
++
++ t = ORBit_default_principal_iovec.iov_base =
++ g_malloc(ORBit_default_principal_iovec.iov_len);
++
++ memcpy(t, &principal->_length, sizeof(principal->_length));
++
++ t = ((guchar *)t) + sizeof(principal->_length);
++ memcpy(t, principal->_buffer, principal->_length);
++}
++
++CORBA_unsigned_long ORBit_class_assignment_counter = 0;
++GHashTable *ORBit_class_assignments = NULL;
++
++/* XXX not thread-safe */
++CORBA_unsigned_long
++ORBit_register_class(const PortableServer_ClassInfo *class_info)
++{
++ CORBA_unsigned_long retval;
++
++ if(!ORBit_class_assignments)
++ ORBit_class_assignments = g_hash_table_new(g_str_hash, g_str_equal);
++
++ /* This needs to be pre-increment - we don't want to give out
++ classid 0, because (a) that is reserved for the base Object class
++ (b) all the routines allocate a new id if the variable
++ storing their ID == 0 */
++ retval = ++ORBit_class_assignment_counter;
++
++ g_hash_table_insert(ORBit_class_assignments, (gpointer)class_info->class_name,
++ GINT_TO_POINTER(retval));
++
++ return retval;
++}
+diff -urN linux-2.4.1/net/korbit/orb/orbit.h linux-2.4.1-korbit/net/korbit/orb/orbit.h
+--- linux-2.4.1/net/korbit/orb/orbit.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit.h Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,207 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++/* these two blocks are outside of the main header for good reason...
++ People may include headers from many different stubs, and we want to
++ have the version checked on all of them.
++ */
++#ifndef ORBIT_SERIAL
++#define ORBIT_SERIAL 9
++#endif
++
++#ifdef ORBIT_IDL_SERIAL
++#if ORBIT_IDL_SERIAL < 9
++#error "You need to rerun 'orbit-idl' on the .idl file whose stubs you are using. These stubs were generated with an older version of ORBit, and need to be regenerated."
++#endif
++#endif
++
++#ifndef _ORBIT_H_
++#define _ORBIT_H_
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++#include <glib.h>
++
++#define BACKWARDS_COMPAT_0_4
++#undef NOT_BACKWARDS_COMPAT_0_4
++
++#include <sys/types.h>
++#include <sys/uio.h>
++#include <IIOP/IIOP.h>
++#include <ORBitutil/util.h>
++#include <orb/orbit_config.h>
++#include <orb/orbit_types.h>
++#include <orb/allocators.h>
++#include <orb/cdr.h>
++#include <orb/dii.h>
++#ifndef __KORBIT__
++#include <orb/dynany.h>
++#endif
++#include <orb/env.h>
++#include <orb/iop.h>
++#include <orb/ir.h>
++#include <orb/options.h>
++#include <orb/orb.h>
++#include <orb/poa.h>
++#include <orb/sequences.h>
++#include <orb/orbit_typecode.h>
++#include <orb/typecode.h>
++
++#ifndef ORBIT_MAJOR_VERSION
++#define ORBIT_MAJOR_VERSION (0)
++#define ORBIT_MINOR_VERSION (5)
++#define ORBIT_MICRO_VERSION (3)
++#endif
++
++extern const guint orbit_major_version,
++ orbit_minor_version,
++ orbit_micro_version;
++extern const char orbit_version[];
++
++extern void CORBA_any_set_release(
++ CORBA_any *,
++ CORBA_boolean);
++
++extern CORBA_boolean CORBA_any_get_release(
++ CORBA_any *);
++
++extern void CORBA_sequence_set_release(
++ void *,
++ CORBA_boolean);
++
++extern CORBA_boolean CORBA_sequence_get_release(
++ void *);
++
++#define CORBA_any__alloc CORBA_any_alloc
++extern CORBA_any *CORBA_any_alloc(
++ void);
++
++extern gpointer CORBA_any__free(gpointer mem, gpointer func_data,
++ CORBA_boolean free_strings);
++extern gpointer CORBA_TypeCode__free(gpointer mem, gpointer func_data,
++ CORBA_boolean free_strings);
++
++extern CORBA_boolean ORBit_any_equivalent(
++ CORBA_any obj,
++ CORBA_any any,
++ CORBA_Environment *ev);
++
++extern CORBA_char *CORBA_string_dup(const CORBA_char *string);
++extern CORBA_char *CORBA_string_alloc(CORBA_unsigned_long len);
++extern gpointer CORBA_string__free(gpointer str, gpointer dat, CORBA_boolean free_strings);
++
++gpointer CORBA_Object__free(gpointer str, gpointer dat, CORBA_boolean free_strings);
++
++extern CORBA_wchar *CORBA_wstring_alloc(CORBA_unsigned_long len);
++#define CORBA_wstring_free CORBA_string_free
++
++/* 19.14 */
++extern CORBA_long CORBA_fixed_integer_part(
++ const void *fp);
++
++extern CORBA_long CORBA_fixed_fraction_part(
++ const void *fp);
++
++extern void CORBA_fixed_set(
++ void *rp,
++ CORBA_long i,
++ CORBA_long f);
++
++extern void CORBA_fixed_add(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_sub(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_mul(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_div(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern CORBA_fixed_d_s *CORBA_fixed_alloc(
++ CORBA_unsigned_short d);
++
++extern void CORBA_free(
++ void *storage);
++
++extern int ORBit_parse_inet(
++ CORBA_Object obj,
++ char *hostname,
++ unsigned short port,
++ gboolean existing_only);
++
++extern int ORBit_parse_unixsock(CORBA_Object obj,
++ char *sockpath,
++ gboolean existing_only);
++
++/****
++ This function lets you use your own event loop, if you so wish.
++ Also see IIOP.h's IIOP{Add,Remove}ConnectionHandler function pointers,
++ which are app-settable (you should set them before CORBA_ORB_init,
++ if you want them to be useful)
++ ****/
++
++ /* needs to be called by your event loop when data comes in on one of the
++ GIOPConnection fd's */
++void ORBit_custom_run_setup(CORBA_ORB orb, CORBA_Environment *ev);
++ void ORBit_handle_incoming(GIOPConnection *connection);
++
++/* Returns CORBA_TRUE if the request is OK to proceed. */
++typedef enum {
++ ORBIT_MESSAGE_BAD,
++ ORBIT_MESSAGE_ALLOW,
++ ORBIT_MESSAGE_ALLOW_ALL /* Allow all subsequent messages on
++ this connection with no checking */
++} ORBit_MessageValidationResult;
++typedef ORBit_MessageValidationResult (*ORBit_request_validate)
++ (CORBA_unsigned_long request_id,
++ CORBA_Principal *principal,
++ CORBA_char *operation);
++void ORBit_set_request_validation_handler(ORBit_request_validate validator);
++
++extern struct iovec ORBit_default_principal_iovec;
++void ORBit_set_default_principal(CORBA_Principal *principal);
++
++extern CORBA_unsigned_long ORBit_class_assignment_counter;
++
++CORBA_unsigned_long ORBit_register_class(const PortableServer_ClassInfo *class_info);
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* !_ORBIT_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit.h.in linux-2.4.1-korbit/net/korbit/orb/orbit.h.in
+--- linux-2.4.1/net/korbit/orb/orbit.h.in Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit.h.in Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,205 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@acm.org>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++/* these two blocks are outside of the main header for good reason...
++ People may include headers from many different stubs, and we want to
++ have the version checked on all of them.
++ */
++#ifndef ORBIT_SERIAL
++#define ORBIT_SERIAL @ORBIT_SERIAL@
++#endif
++
++#ifdef ORBIT_IDL_SERIAL
++#if ORBIT_IDL_SERIAL < @ORBIT_SERIAL@
++#error "You need to rerun 'orbit-idl' on the .idl file whose stubs you are using. These stubs were generated with an older version of ORBit, and need to be regenerated."
++#endif
++#endif
++
++#ifndef _ORBIT_H_
++#define _ORBIT_H_
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++#include <glib.h>
++
++#define BACKWARDS_COMPAT_0_4
++#undef NOT_BACKWARDS_COMPAT_0_4
++
++#include <sys/types.h>
++#include <sys/uio.h>
++#include <IIOP/IIOP.h>
++#include <ORBitutil/util.h>
++#include <orb/orbit_config.h>
++#include <orb/orbit_types.h>
++#include <orb/allocators.h>
++#include <orb/cdr.h>
++#include <orb/dii.h>
++#include <orb/dynany.h>
++#include <orb/env.h>
++#include <orb/iop.h>
++#include <orb/ir.h>
++#include <orb/options.h>
++#include <orb/orb.h>
++#include <orb/poa.h>
++#include <orb/sequences.h>
++#include <orb/orbit_typecode.h>
++#include <orb/typecode.h>
++
++#ifndef ORBIT_MAJOR_VERSION
++#define ORBIT_MAJOR_VERSION (@ORBIT_MAJOR_VERSION@)
++#define ORBIT_MINOR_VERSION (@ORBIT_MINOR_VERSION@)
++#define ORBIT_MICRO_VERSION (@ORBIT_MICRO_VERSION@)
++#endif
++
++extern const guint orbit_major_version,
++ orbit_minor_version,
++ orbit_micro_version;
++extern const char orbit_version[];
++
++extern void CORBA_any_set_release(
++ CORBA_any *,
++ CORBA_boolean);
++
++extern CORBA_boolean CORBA_any_get_release(
++ CORBA_any *);
++
++extern void CORBA_sequence_set_release(
++ void *,
++ CORBA_boolean);
++
++extern CORBA_boolean CORBA_sequence_get_release(
++ void *);
++
++#define CORBA_any__alloc CORBA_any_alloc
++extern CORBA_any *CORBA_any_alloc(
++ void);
++
++extern gpointer CORBA_any__free(gpointer mem, gpointer func_data,
++ CORBA_boolean free_strings);
++extern gpointer CORBA_TypeCode__free(gpointer mem, gpointer func_data,
++ CORBA_boolean free_strings);
++
++extern CORBA_boolean ORBit_any_equivalent(
++ CORBA_any obj,
++ CORBA_any any,
++ CORBA_Environment *ev);
++
++extern CORBA_char *CORBA_string_dup(const CORBA_char *string);
++extern CORBA_char *CORBA_string_alloc(CORBA_unsigned_long len);
++extern gpointer CORBA_string__free(gpointer str, gpointer dat, CORBA_boolean free_strings);
++
++gpointer CORBA_Object__free(gpointer str, gpointer dat, CORBA_boolean free_strings);
++
++extern CORBA_wchar *CORBA_wstring_alloc(CORBA_unsigned_long len);
++#define CORBA_wstring_free CORBA_string_free
++
++/* 19.14 */
++extern CORBA_long CORBA_fixed_integer_part(
++ const void *fp);
++
++extern CORBA_long CORBA_fixed_fraction_part(
++ const void *fp);
++
++extern void CORBA_fixed_set(
++ void *rp,
++ CORBA_long i,
++ CORBA_long f);
++
++extern void CORBA_fixed_add(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_sub(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_mul(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern void CORBA_fixed_div(
++ void *rp,
++ const void *f1p,
++ const void *f2p);
++
++extern CORBA_fixed_d_s *CORBA_fixed_alloc(
++ CORBA_unsigned_short d);
++
++extern void CORBA_free(
++ void *storage);
++
++extern int ORBit_parse_inet(
++ CORBA_Object obj,
++ char *hostname,
++ unsigned short port,
++ gboolean existing_only);
++
++extern int ORBit_parse_unixsock(CORBA_Object obj,
++ char *sockpath,
++ gboolean existing_only);
++
++/****
++ This function lets you use your own event loop, if you so wish.
++ Also see IIOP.h's IIOP{Add,Remove}ConnectionHandler function pointers,
++ which are app-settable (you should set them before CORBA_ORB_init,
++ if you want them to be useful)
++ ****/
++
++ /* needs to be called by your event loop when data comes in on one of the
++ GIOPConnection fd's */
++void ORBit_custom_run_setup(CORBA_ORB orb, CORBA_Environment *ev);
++ void ORBit_handle_incoming(GIOPConnection *connection);
++
++/* Returns CORBA_TRUE if the request is OK to proceed. */
++typedef enum {
++ ORBIT_MESSAGE_BAD,
++ ORBIT_MESSAGE_ALLOW,
++ ORBIT_MESSAGE_ALLOW_ALL /* Allow all subsequent messages on
++ this connection with no checking */
++} ORBit_MessageValidationResult;
++typedef ORBit_MessageValidationResult (*ORBit_request_validate)
++ (CORBA_unsigned_long request_id,
++ CORBA_Principal *principal,
++ CORBA_char *operation);
++void ORBit_set_request_validation_handler(ORBit_request_validate validator);
++
++extern struct iovec ORBit_default_principal_iovec;
++void ORBit_set_default_principal(CORBA_Principal *principal);
++
++extern CORBA_unsigned_long ORBit_class_assignment_counter;
++
++CORBA_unsigned_long ORBit_register_class(const PortableServer_ClassInfo *class_info);
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* !_ORBIT_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_config.h linux-2.4.1-korbit/net/korbit/orb/orbit_config.h
+--- linux-2.4.1/net/korbit/orb/orbit_config.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_config.h Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,9 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++#ifndef ORB_CONFIG_H
++#define ORB_CONFIG_H 1
++
++/* When creating a memory pool for a particular type, how many chunks
++ do we want to pre-allocated? */
++#define ORBIT_CHUNKS_PREALLOC 2
++
++#endif /* ORB_CONFIG_H */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_object.c linux-2.4.1-korbit/net/korbit/orb/orbit_object.c
+--- linux-2.4.1/net/korbit/orb/orbit_object.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_object.c Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,699 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Phil Dawes <philipd@parallax.co.uk>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++/*
++ * ORBit specific CORBA_Object functions.
++ *
++ */
++
++#include <string.h>
++#include "config.h"
++#include "../IIOP/iiop-endianP.h"
++#include "orbit_object_type.h"
++#include "corba_object_type.h"
++#include "allocators.h"
++#include "iop.h"
++#include <IIOP/IIOP.h>
++
++static void ORBit_object_try_existing_connections(CORBA_Object obj);
++static void CORBA_Object_release_fn(CORBA_Object obj, CORBA_Environment *ev);
++
++static ORBit_RootObject_Interface CORBA_Object_epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))CORBA_Object_release_fn,
++};
++
++void ORBit_pseudo_object_init(ORBit_PseudoObject obj,
++ ORBit_PseudoObject_type obj_type,
++ CORBA_Environment *ev)
++{
++ ORBIT_ROOT_OBJECT(obj)->is_pseudo_object = TRUE;
++ ORBIT_ROOT_OBJECT(obj)->refs = 0;
++ ORBIT_PSEUDO_OBJECT(obj)->pseudo_object_type = obj_type;
++}
++
++static const ORBit_RootObject_Interface CORBA_Policy__epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))CORBA_Policy_destroy
++};
++
++void ORBit_policy_object_init(CORBA_Policy obj,
++ CORBA_PolicyType obj_type,
++ CORBA_Environment *ev)
++{
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(obj),
++ ORBIT_PSEUDO_POLICY, ev);
++
++ obj->policy_type = obj_type;
++
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(obj),
++ (gpointer)&CORBA_Policy__epv,
++ ev);
++}
++
++void ORBit_object_reference_init(CORBA_Object obj, CORBA_Environment *ev)
++{
++ /* set the interface up */
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(obj),&CORBA_Object_epv,ev);
++ /* initialise the reference count */
++ ORBIT_ROOT_OBJECT(obj)->refs = 0;
++ ORBIT_ROOT_OBJECT(obj)->is_pseudo_object = FALSE;
++}
++
++CORBA_Object
++ORBit_CORBA_Object_new(CORBA_Environment *ev)
++{
++ CORBA_Object obj;
++ /* Create the object */
++ obj = ORBIT_CHUNK_ALLOC(CORBA_Object);
++ memset(obj, '\0', sizeof(struct CORBA_Object_struct));
++
++ ORBit_object_reference_init(obj, ev);
++
++ return obj;
++
++}
++
++void
++ORBit_set_object_key(ORBit_Object_info *info)
++{
++ g_assert(info);
++
++ g_assert(info->object_key._length);
++
++ info->object_key_data = g_malloc(sizeof(CORBA_unsigned_long) + info->object_key._length);
++ info->object_key_data->_length = info->object_key._length;
++ memcpy(info->object_key_data->_buffer, info->object_key._buffer, info->object_key._length);
++
++ info->object_key_vec.iov_base =
++ (gpointer)info->object_key_data;
++ info->object_key_vec.iov_len = sizeof(CORBA_unsigned_long) + info->object_key._length;
++}
++
++static void ORBit_free_profile(gpointer item, gpointer data)
++{
++ ORBit_Object_info *info=(ORBit_Object_info *)item;
++
++ g_assert(info);
++
++ g_free(info->object_key_data);
++ CORBA_free(info->object_key._buffer);
++
++ if(info->profile_type == IOP_TAG_INTERNET_IOP) {
++ g_free(info->tag.iopinfo.host);
++ } else if(info->profile_type == IOP_TAG_ORBIT_SPECIFIC) {
++ g_free(info->tag.orbitinfo.unix_sock_path);
++ } else {
++ g_warning("ORBit_free_profile asked to free type %d", info->profile_type);
++ }
++
++ g_free(info); /* Check its safe to free the item within a foreach func */
++}
++
++void ORBit_delete_profiles(GSList *profile_list)
++{
++ g_slist_foreach(profile_list, ORBit_free_profile, NULL);
++ g_slist_free(profile_list);
++}
++
++/* this function is wired up to the RootObject interface */
++void
++CORBA_Object_release_fn(CORBA_Object obj, CORBA_Environment *ev)
++{
++
++ g_assert(obj!=NULL);
++
++ ORBIT_ROOT_OBJECT_UNREF(obj);
++
++ if(ORBIT_ROOT_OBJECT(obj)->refs <= 0) {
++ g_hash_table_remove(obj->orb->objrefs, obj);
++
++ if(obj->connection)
++ giop_connection_unref(obj->connection);
++
++ g_free(obj->object_id);
++ ORBit_delete_profiles(obj->profile_list);
++ ORBit_delete_profiles(obj->forward_locations);
++
++ ORBIT_CHUNK_FREE(CORBA_Object, obj);
++ }
++}
++
++
++/* Sets the interface member in the RootObject to the epv specified*/
++void
++ORBit_RootObject_set_interface(ORBit_RootObject obj,
++ ORBit_RootObject_Interface* epv,
++ CORBA_Environment *ev)
++{
++ g_assert(obj!=NULL);
++ g_assert(epv!=NULL);
++
++ obj->interface = epv;
++}
++
++#define GET_ATOM(x) G_STMT_START{ GIOP_RECV_BUFFER(recv_buffer)->decoder(&x, (GIOP_RECV_BUFFER(recv_buffer)->cur), sizeof(x)); \
++GIOP_RECV_BUFFER(recv_buffer)->cur = ((guchar *)GIOP_RECV_BUFFER(recv_buffer)->cur) + sizeof(x); \
++}G_STMT_END
++#define ALIGNFOR(x) recv_buffer->cur = ALIGN_ADDRESS(recv_buffer->cur, sizeof(x))
++
++CORBA_Object
++ORBit_create_object_with_info(GSList *profiles,
++ const CORBA_char *type_id,
++ CORBA_ORB orb,
++ CORBA_Environment *ev)
++{
++ CORBA_Object new;
++ struct CORBA_Object_struct refcheck;
++
++ if(!type_id || !*type_id) {
++ g_warning("Failing object creation because object has no type");
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_MAYBE);
++ return CORBA_OBJECT_NIL;
++ }
++
++ if(g_slist_length(profiles) < 1) {
++ g_warning("Failing object creation because object has no profiles");
++ CORBA_exception_set_system(ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_MAYBE);
++ return CORBA_OBJECT_NIL;
++ }
++
++ /* XXX badhack :) */
++ refcheck.object_id = type_id;
++ refcheck.profile_list = profiles;
++
++ new = g_hash_table_lookup(orb->objrefs, &refcheck);
++ if(new) {
++ ORBit_delete_profiles(profiles);
++ return CORBA_Object_duplicate(new, ev);
++ }
++
++ new = ORBit_CORBA_Object_new(ev);
++ new->connection = NULL;
++ new->object_id = g_strdup(type_id);
++ new->orb = (CORBA_ORB)CORBA_Object_duplicate((CORBA_Object)orb, ev);
++ new->profile_list = profiles;
++ new->active_profile = NULL;
++
++ ORBit_object_try_existing_connections(new);
++
++ g_hash_table_insert(orb->objrefs, new, new);
++
++ return CORBA_Object_duplicate(new, ev);
++}
++
++static ORBit_Object_info *
++ORBit_demarshal_profile(GIOPRecvBuffer *recv_buffer, IOP_ProfileId profile_id)
++{
++ ORBit_Object_info *object_info;
++ CORBA_unsigned_long subpart_len;
++ CORBA_octet o;
++ CDR_Codec codec_d;
++ CDR_Codec *codec=&codec_d;
++
++ object_info = g_new0(ORBit_Object_info, 1);
++
++ switch(profile_id) {
++ case IOP_TAG_INTERNET_IOP:
++ GET_ATOM(subpart_len); /* The length of the embedded sequence */
++ CDR_codec_init_static(codec);
++ codec->buffer = recv_buffer->cur;
++ codec->release_buffer = CORBA_FALSE;
++ recv_buffer->cur = ((guchar *)recv_buffer->cur) + subpart_len;
++
++ codec->readonly = CORBA_TRUE;
++ codec->host_endian = codec->data_endian = FLAG_ENDIANNESS;
++ codec->buf_len = subpart_len;
++
++ CDR_get_octet(codec, &o);
++ codec->data_endian = o;
++
++ object_info->profile_type = IOP_TAG_INTERNET_IOP;
++ CDR_get_octet(codec, &object_info->iiop_major);
++
++ if(object_info->iiop_major != 1)
++ goto error_exit;
++ /* XXX should we check for a specific minor version? */
++ CDR_get_octet(codec, &object_info->iiop_minor);
++
++ CDR_get_string(codec, &object_info->tag.iopinfo.host);
++
++ CDR_get_ushort(codec, &object_info->tag.iopinfo.port);
++
++ CDR_get_seq_begin(codec, &object_info->object_key._length);
++ object_info->object_key._buffer =
++ ORBit_alloc(object_info->object_key._length, NULL, NULL);
++ CDR_buffer_gets(codec, object_info->object_key._buffer,
++ object_info->object_key._length);
++ object_info->object_key._maximum = object_info->object_key._release = 0;
++
++ ORBit_set_object_key(object_info);
++
++ return(object_info);
++ break;
++
++ case IOP_TAG_MULTIPLE_COMPONENTS:
++ default:
++ GET_ATOM(subpart_len);
++ g_warning("IOP_TAG_MULTIPLE_COMPONENTS decoding needs finishing");
++ object_info->profile_type = IOP_TAG_MULTIPLE_COMPONENTS;
++ recv_buffer->cur = ((guchar *)recv_buffer->cur) + subpart_len;
++ return(object_info);
++ break;
++
++ case IOP_TAG_ORBIT_SPECIFIC:
++ GET_ATOM(subpart_len);
++ CDR_codec_init_static(codec);
++ codec->buffer = recv_buffer->cur;
++ codec->release_buffer = CORBA_FALSE;
++ recv_buffer->cur = ((guchar *)recv_buffer->cur) + subpart_len;
++
++ codec->readonly = CORBA_TRUE;
++ codec->host_endian = codec->data_endian = FLAG_ENDIANNESS;
++ codec->buf_len = subpart_len;
++
++ CDR_get_octet(codec, &o);
++ codec->data_endian = o;
++
++ object_info->profile_type = IOP_TAG_ORBIT_SPECIFIC;
++ CDR_get_octet(codec, &object_info->iiop_major);
++
++ if(object_info->iiop_major != 1)
++ goto error_exit;
++ /* XXX should we check for a specific minor version? */
++ CDR_get_octet(codec, &object_info->iiop_minor);
++
++ CDR_get_string(codec, &object_info->tag.orbitinfo.unix_sock_path);
++ CDR_get_ushort(codec, &object_info->tag.orbitinfo.ipv6_port);
++
++ CDR_get_seq_begin(codec, &object_info->object_key._length);
++ object_info->object_key._buffer =
++ ORBit_alloc(object_info->object_key._length, NULL, NULL);
++ CDR_buffer_gets(codec, object_info->object_key._buffer,
++ object_info->object_key._length);
++ object_info->object_key._maximum = object_info->object_key._release = 0;
++
++ ORBit_set_object_key(object_info);
++
++ return(object_info);
++ break;
++ }
++
++error_exit:
++ g_message("demarshal_profile(): IIOP major is %d",
++ object_info->iiop_major);
++ g_free(object_info);
++
++ return(NULL);
++}
++
++GSList *ORBit_demarshal_IOR(GIOPRecvBuffer *recv_buffer)
++{
++ GSList *profiles=NULL;
++ ORBit_Object_info *object_info;
++ CORBA_unsigned_long len, seq_len;
++ IOP_ProfileId profile_id;
++ int i;
++
++ /* Get type_id */
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(len);
++
++ if(len == 0)
++ return(NULL);
++
++ recv_buffer->cur = ((guchar *)recv_buffer->cur) + len;
++
++ /* Decode the sequence<TaggedProfile> */
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(seq_len);
++ for(i = 0; i < seq_len; i++) {
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(profile_id);
++ object_info=ORBit_demarshal_profile(recv_buffer, profile_id);
++ if(object_info==NULL) {
++ goto error_exit;
++ } else {
++ profiles=g_slist_append(profiles, object_info);
++ }
++ }
++
++ return(profiles);
++
++error_exit:
++ ORBit_delete_profiles(profiles);
++ return(NULL);
++}
++
++CORBA_Object
++ORBit_demarshal_object(GIOPRecvBuffer *recv_buffer, CORBA_ORB orb)
++{
++ GSList *profiles=NULL;
++ ORBit_Object_info *object_info;
++ CORBA_char *type_id;
++ CORBA_unsigned_long len, seq_len;
++ IOP_ProfileId profile_id;
++ int i;
++ CORBA_Environment ev;
++ CORBA_Object retval;
++
++ CORBA_exception_init(&ev);
++
++ /* Get type_id */
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(len);
++
++ type_id = recv_buffer->cur;
++ recv_buffer->cur = ((guchar *)recv_buffer->cur) + len;
++
++ /* Decode the sequence<TaggedProfile> */
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(seq_len);
++
++ if(!seq_len)
++ return CORBA_OBJECT_NIL;
++
++ for(i = 0; i < seq_len; i++) {
++ ALIGNFOR(CORBA_unsigned_long);
++ GET_ATOM(profile_id);
++ object_info=ORBit_demarshal_profile(recv_buffer, profile_id);
++ if(object_info)
++ profiles=g_slist_append(profiles, object_info);
++ }
++
++ if(!profiles)
++ goto error_exit;
++
++ retval = ORBit_create_object_with_info(profiles, type_id, orb, &ev);
++
++ return retval;
++
++ error_exit:
++ ORBit_delete_profiles(profiles);
++
++ CORBA_exception_set_system(&ev, ex_CORBA_MARSHAL,
++ CORBA_COMPLETED_MAYBE);
++ return CORBA_OBJECT_NIL;
++}
++
++static void ORBit_marshal_profile(gpointer item, gpointer data)
++{
++ ORBit_Object_info *info = (ORBit_Object_info *)item;
++ GIOPSendBuffer *send_buffer = (GIOPSendBuffer *)data;
++ static const CORBA_unsigned_long ioptag = IOP_TAG_INTERNET_IOP,
++ orbittag = IOP_TAG_ORBIT_SPECIFIC;
++ CDR_Codec codec_d;
++ CDR_Codec *codec = &codec_d;
++ CORBA_unsigned_long len;
++ CORBA_octet codecbuf[2048];
++ static const CORBA_octet oc_endian = FLAG_ENDIANNESS;
++ static const CORBA_octet iiopversion[] = {1,0};
++
++ g_assert(info);
++ g_assert(send_buffer);
++
++ if(info->profile_type == IOP_TAG_INTERNET_IOP) {
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer),
++ &ioptag, sizeof(ioptag));
++
++ CDR_codec_init_static(codec);
++ codec->buffer = codecbuf;
++ codec->buf_len = 2048;
++ codec->release_buffer = CORBA_FALSE;
++ codec->readonly = CORBA_FALSE;
++ codec->data_endian = codec->host_endian = FLAG_ENDIANNESS;
++ CDR_put_octet(codec, oc_endian);
++ CDR_put_octet(codec, iiopversion[0]);
++ CDR_put_octet(codec, iiopversion[1]);
++ CDR_put_string(codec, info->tag.iopinfo.host);
++ CDR_put_ushort(codec, info->tag.iopinfo.port);
++ CDR_put_ulong(codec, info->object_key._length);
++ CDR_put_octets(codec, info->object_key._buffer,
++ info->object_key._length);
++ len = codec->wptr;
++ giop_send_buffer_append_mem_indirect_a(send_buffer,
++ &len, sizeof(len));
++ giop_send_buffer_append_mem_indirect(send_buffer,
++ codec->buffer, codec->wptr);
++ } else if(info->profile_type==IOP_TAG_ORBIT_SPECIFIC) {
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(send_buffer),
++ &orbittag, sizeof(orbittag));
++ CDR_codec_init_static(codec);
++ codec->buffer = codecbuf;
++ codec->release_buffer = CORBA_FALSE;
++ codec->buf_len = 2048;
++ codec->readonly = CORBA_FALSE;
++ codec->data_endian = codec->host_endian = FLAG_ENDIANNESS;
++ CDR_put_octet(codec, oc_endian);
++ CDR_put_octets(codec, (gpointer)iiopversion, sizeof(iiopversion));
++ CDR_put_string(codec, info->tag.orbitinfo.unix_sock_path);
++ CDR_put_ushort(codec, info->tag.orbitinfo.ipv6_port);
++ CDR_put_ulong(codec, info->object_key._length);
++ CDR_put_octets(codec, info->object_key._buffer,
++ info->object_key._length);
++ len = codec->wptr;
++ giop_send_buffer_append_mem_indirect_a(send_buffer,
++ &len, sizeof(len));
++ giop_send_buffer_append_mem_indirect(send_buffer,
++ codec->buffer, codec->wptr);
++ } else {
++ g_warning("ORBit_marshal_profile ask to marshal type %d\n", info->profile_type);
++ }
++}
++
++void
++ORBit_marshal_object(GIOPSendBuffer *send_buffer, CORBA_Object obj)
++{
++ CORBA_unsigned_long len;
++
++
++ if(!obj) {
++ static const CORBA_unsigned_long zero = 0, one = 1;
++ /* zero-length typename */
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(send_buffer),
++ &one, sizeof(one));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer),
++ &zero, 1);
++
++ /* zero profiles */
++ giop_message_buffer_append_mem_a(GIOP_MESSAGE_BUFFER(send_buffer),
++ &zero, sizeof(zero));
++ return;
++ }
++ g_return_if_fail(ORBIT_ROOT_OBJECT(obj)->refs > 0);
++
++ len = strlen(obj->object_id) + 1;
++ giop_send_buffer_append_mem_indirect_a(send_buffer, &len,
++ sizeof(len));
++ giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(send_buffer),
++ obj->object_id, len);
++
++ len = g_slist_length(obj->profile_list);
++ giop_send_buffer_append_mem_indirect_a(GIOP_SEND_BUFFER(send_buffer),
++ &len, sizeof(len));
++
++ /* Marshal active first? */
++ g_slist_foreach(obj->profile_list, ORBit_marshal_profile, send_buffer);
++}
++
++static void ORBit_test_profile(gpointer item, gpointer data)
++{
++ ORBit_Object_info *info = (ORBit_Object_info *)item;
++ CORBA_Object obj = (CORBA_Object)data;
++
++ if(obj->active_profile != NULL)
++ return; /* we already have a good profile */
++
++ if(info->profile_type == IOP_TAG_ORBIT_SPECIFIC) {
++ if(!ORBit_parse_unixsock(obj, info->tag.orbitinfo.unix_sock_path, TRUE)) {
++ /* success */
++ obj->active_profile=info;
++ }
++ } else if(info->profile_type == IOP_TAG_INTERNET_IOP) {
++ if(!ORBit_parse_inet(obj, info->tag.iopinfo.host, info->tag.iopinfo.port, TRUE)) {
++ /* success */
++ obj->active_profile=info;
++ }
++ }
++}
++
++static void
++ORBit_object_try_existing_connections(CORBA_Object obj)
++{
++ g_slist_foreach(obj->profile_list, ORBit_test_profile, obj);
++}
++
++static void ORBit_activate_profile(gpointer item, gpointer data)
++{
++ ORBit_Object_info *info = (ORBit_Object_info *)item;
++ CORBA_Object obj = (CORBA_Object)data;
++
++ if(obj->active_profile != NULL)
++ return; /* we already have a good profile */
++
++ if(info->profile_type == IOP_TAG_ORBIT_SPECIFIC) {
++ if(!ORBit_parse_unixsock(obj, info->tag.orbitinfo.unix_sock_path, FALSE)) {
++ /* success */
++ obj->active_profile=info;
++ }
++ } else if(info->profile_type == IOP_TAG_INTERNET_IOP) {
++ if(!ORBit_parse_inet(obj, info->tag.iopinfo.host, info->tag.iopinfo.port, FALSE)) {
++ /* success */
++ obj->active_profile=info;
++ }
++ }
++}
++
++GIOPConnection *
++_ORBit_object_get_connection(CORBA_Object obj)
++{
++ g_return_val_if_fail(obj, NULL);
++
++ if (obj->connection) {
++ giop_connection_unref(obj->connection);
++ obj->connection = NULL;
++ obj->active_profile = NULL;
++ }
++
++ g_slist_foreach(obj->profile_list, ORBit_activate_profile, obj);
++
++ if(obj->active_profile == NULL || !obj->connection)
++ return NULL;
++
++ obj->connection->orb_data = obj->orb;
++
++ return obj->connection;
++}
++
++GIOPConnection *
++ORBit_object_get_forwarded_connection(CORBA_Object obj)
++{
++ g_return_val_if_fail(obj, NULL);
++
++ if (obj->connection) {
++ giop_connection_unref(obj->connection);
++ obj->connection = NULL;
++ obj->active_profile = NULL;
++ }
++
++ g_slist_foreach(obj->forward_locations, ORBit_activate_profile, obj);
++
++ if(obj->active_profile == NULL || !obj->connection)
++ return NULL;
++
++ obj->connection->orb_data = obj->orb;
++
++ return obj->connection;
++}
++
++/* This function is heavily based on the idl stubs output. Any changes there
++ will probably have to be reflected here also. */
++
++void ORBit_object_locate(CORBA_Object obj, CORBA_Environment *ev)
++{
++ GIOPConnection *cnx;
++ GIOPSendBuffer *send_buffer;
++ GIOPRecvBuffer *recv_buffer;
++ GIOP_unsigned_long request_id;
++
++ g_return_if_fail(obj!=NULL);
++ g_return_if_fail(ev!=NULL);
++
++ /* Send a LOCATE_REQUEST, wait for a LOCATE_REPLY. The reply will
++ either say "Object here", or will carry a new location. We set
++ obj->active_profile appropriately */
++
++ cnx=ORBit_object_get_connection(obj);
++ if((cnx==NULL) || (obj->active_profile==NULL)) {
++ CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_NO);
++ return;
++ }
++ request_id=giop_get_request_id();
++ send_buffer=giop_send_locate_request_buffer_use(cnx, request_id, &(obj->active_profile->object_key_vec));
++ if(!send_buffer) {
++ CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_NO);
++ return;
++ }
++
++ giop_send_buffer_write(send_buffer);
++ giop_send_buffer_unuse(send_buffer);
++
++ recv_buffer=giop_recv_locate_reply_buffer_use(request_id, TRUE);
++ if(recv_buffer==NULL || recv_buffer->message_buffer.message_header.message_type!=GIOP_LOCATEREPLY) {
++ CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_MAYBE);
++ if(recv_buffer)
++ giop_recv_buffer_unuse(recv_buffer);
++
++ return;
++ }
++
++ ev->_major=CORBA_NO_EXCEPTION;
++ switch(recv_buffer->message.u.locate_reply.locate_status) {
++ case GIOP_UNKNOWN_OBJECT:
++ CORBA_exception_set_system(ev, ex_CORBA_OBJECT_NOT_EXIST, CORBA_COMPLETED_NO);
++ break;
++
++ case GIOP_OBJECT_HERE:
++ /* No further processing necessary */
++ break;
++
++ case GIOP_OBJECT_FORWARD:
++ /* We've been forwarded onto somewhere else. The message body
++ contains the new IOR */
++ if(obj->forward_locations != NULL) {
++ ORBit_delete_profiles(obj->forward_locations);
++ }
++ obj->forward_locations=ORBit_demarshal_IOR(recv_buffer);
++
++ /* This will adjust obj->active_profile */
++ cnx=ORBit_object_get_forwarded_connection(obj);
++ break;
++
++ default:
++ g_message("Bad Reply in ORBit_locate_object()\n");
++ break;
++
++ }
++
++ giop_recv_buffer_unuse(recv_buffer);
++}
++
++GIOPConnection *
++ORBit_handle_location_forward(GIOPRecvBuffer *rb, CORBA_Object obj)
++{
++ GIOPConnection *retval;
++
++ if(obj->forward_locations)
++ ORBit_delete_profiles(obj->forward_locations);
++ obj->forward_locations = ORBit_demarshal_IOR(rb);
++
++ retval = ORBit_object_get_forwarded_connection(obj);
++ giop_recv_buffer_unuse(rb);
++
++ return retval;
++}
+diff -urN linux-2.4.1/net/korbit/orb/orbit_object.h linux-2.4.1-korbit/net/korbit/orb/orbit_object.h
+--- linux-2.4.1/net/korbit/orb/orbit_object.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_object.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,114 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Phil Dawes <philipd@parallax.co.uk>
++ *
++ */
++
++/*
++ * ORBit specific CORBA_Object funcitons.
++ *
++ */
++#ifndef _ORBIT_ORBIT_OBJECT_H_
++#define _ORBIT_ORBIT_OBJECT_H_
++
++#include <IIOP/IIOP.h>
++#include "corba_object.h"
++
++extern CORBA_Object ORBit_CORBA_Object_new(CORBA_Environment *ev);
++extern void ORBit_CORBA_Object_free(CORBA_Object obj, CORBA_Environment *ev);
++
++
++typedef enum {
++ ORBIT_PSEUDO_ORB,
++ ORBIT_PSEUDO_POA,
++ ORBIT_PSEUDO_POAMANAGER,
++ ORBIT_PSEUDO_POLICY,
++ ORBIT_PSEUDO_TYPECODE,
++ ORBIT_PSEUDO_REQUEST,
++ ORBIT_PSEUDO_SERVERREQUEST,
++ ORBIT_PSEUDO_CONTEXT
++} ORBit_PseudoObject_type;
++typedef struct ORBit_PseudoObject_struct *ORBit_PseudoObject;
++
++void ORBit_pseudo_object_init(ORBit_PseudoObject obj,
++ ORBit_PseudoObject_type obj_type,
++ CORBA_Environment *ev);
++void ORBit_policy_object_init(CORBA_Policy obj,
++ CORBA_PolicyType obj_type,
++ CORBA_Environment *ev);
++
++/* Use ORBit_CORBA_Object_new() */
++void ORBit_object_reference_init(CORBA_Object obj, CORBA_Environment *ev);
++
++typedef struct {
++ CORBA_char *host;
++ CORBA_unsigned_short port;
++} TAG_INTERNET_IOP_info;
++
++typedef struct {
++ CORBA_char *unix_sock_path;
++ CORBA_unsigned_short ipv6_port;
++} TAG_ORBIT_SPECIFIC_info;
++
++typedef struct {
++ int fill_me_in;
++} TAG_MULTIPLE_COMPONENTS_info;
++
++typedef struct {
++ CORBA_octet iiop_major, iiop_minor;
++ IOP_ProfileId profile_type;
++ union {
++ TAG_INTERNET_IOP_info iopinfo;
++ TAG_ORBIT_SPECIFIC_info orbitinfo;
++ TAG_MULTIPLE_COMPONENTS_info mcinfo;
++ } tag;
++
++ /* If the object key is invariant wrt to the various profiles, then
++ this should probably go in CORBA_Object_struct
++ */
++ CORBA_sequence_octet object_key;
++ struct { CORBA_unsigned_long _length; char _buffer[1]; } *object_key_data;
++ struct iovec object_key_vec;
++} ORBit_Object_info;
++
++void ORBit_set_object_key(ORBit_Object_info *info);
++
++CORBA_Object ORBit_create_object_with_info(GSList *profiles,
++ const CORBA_char *type_id,
++ CORBA_ORB orb,
++ CORBA_Environment *ev);
++
++#define ORBit_object_get_connection(obj) \
++ ((obj)->connection && (obj)->connection->is_valid)?((obj)->connection):_ORBit_object_get_connection(obj)
++GIOPConnection *_ORBit_object_get_connection(CORBA_Object obj);
++GIOPConnection *ORBit_object_get_forwarded_connection(CORBA_Object obj);
++void ORBit_object_locate(CORBA_Object obj, CORBA_Environment *ev);
++
++void ORBit_marshal_object(GIOPSendBuffer *send_buffer, CORBA_Object obj);
++CORBA_Object ORBit_demarshal_object(GIOPRecvBuffer *recv_buffer,
++ CORBA_ORB orb);
++GSList *ORBit_demarshal_IOR(GIOPRecvBuffer *recv_buffer);
++
++extern void ORBit_delete_profiles(GSList *profile_list);
++GIOPConnection *ORBit_handle_location_forward(GIOPRecvBuffer *rb, CORBA_Object obj);
++
++#endif /* _ORBIT_ORBIT_OBJECT_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_object_type.h linux-2.4.1-korbit/net/korbit/orb/orbit_object_type.h
+--- linux-2.4.1/net/korbit/orb/orbit_object_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_object_type.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,87 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ * Philip Dawes
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++#ifndef _ORBIT_ORBIT_OBJECT_TYPE_H_
++#define _ORBIT_ORBIT_OBJECT_TYPE_H_
++
++#include "orbit_object.h"
++
++
++/****** Root object **********/
++/*****************************/
++
++typedef struct ORBit_RootObject_Interface_struct ORBit_RootObject_Interface;
++struct ORBit_RootObject_Interface_struct
++{
++ void (*release)(gpointer obj, CORBA_Environment *ev);
++};
++
++
++
++#define ORBIT_ROOT_OBJECT(x) ((ORBit_RootObject)(x))
++
++
++typedef struct ORBit_RootObject_struct *ORBit_RootObject;
++struct ORBit_RootObject_struct {
++ ORBit_RootObject_Interface* interface; /* the interface */
++
++ guchar is_pseudo_object;
++ gint refs;
++};
++
++
++/* Reference counting interface */
++
++#define ORBIT_ROOT_OBJECT_REF(obj) (ORBIT_ROOT_OBJECT(obj)->refs++)
++#define ORBIT_ROOT_OBJECT_UNREF(obj) (ORBIT_ROOT_OBJECT(obj)->refs--)
++
++
++ /* Virtual function interface*/
++
++#define ORBIT_ROOT_OBJECT_release(obj,ev) \
++(ORBIT_ROOT_OBJECT(obj)->interface->release(obj,ev))
++
++
++
++extern void ORBit_RootObject_set_interface(ORBit_RootObject obj,
++ ORBit_RootObject_Interface* epv,
++ CORBA_Environment *ev);
++
++
++
++/****** Pseudo object --> RootObject ********/
++/*********************************************/
++
++#define ORBIT_PSEUDO_OBJECT(x) ((ORBit_PseudoObject)(x))
++
++struct ORBit_PseudoObject_struct {
++ struct ORBit_RootObject_struct parent;
++ ORBit_PseudoObject_type pseudo_object_type;
++};
++
++
++#endif /* !_ORBIT_CORBA_OBJECT_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_poa.c linux-2.4.1-korbit/net/korbit/orb/orbit_poa.c
+--- linux-2.4.1/net/korbit/orb/orbit_poa.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_poa.c Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,809 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Phil Dawes <philipd@parallax.co.uk>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++/*
++ * ORBit specific POA funcitons.
++ *
++ */
++
++#include <string.h>
++#include "orbit.h"
++#include "orbit_poa_type.h"
++#include "orbit_poa.h"
++#include "genrand.h"
++
++#define POA_KEY_LEN (sizeof(CORBA_unsigned_long) + ORBIT_RAND_KEY_LEN)
++#define OBJ_KEY_LEN (sizeof(CORBA_unsigned_long) + ORBIT_RAND_KEY_LEN)
++
++static void ORBit_POAManager_release(PortableServer_POAManager poa_mgr,
++ CORBA_Environment *ev);
++
++static void ORBit_POA_release(PortableServer_POA poa,
++ CORBA_Environment *ev);
++
++static PortableServer_Servant
++ORBit_POA_ServantManager_use_servant(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer,
++ PortableServer_ServantLocator_Cookie *the_cookie,
++ PortableServer_ObjectId *oid,
++ ORBit_POAObject *fake_obj_impl,
++ CORBA_Environment *ev);
++static void
++ORBit_POA_ServantManager_unuse_servant(PortableServer_Servant servant,
++ PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer,
++ PortableServer_ServantLocator_Cookie cookie,
++ PortableServer_ObjectId *oid,
++ ORBit_POAObject *fake_obj_impl,
++ CORBA_Environment *ev);
++
++static const ORBit_RootObject_Interface CORBA_POAManager_epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))ORBit_POAManager_release,
++};
++
++static const ORBit_RootObject_Interface CORBA_POA_epv =
++{
++ (void (*)(gpointer, CORBA_Environment *))ORBit_POA_release,
++};
++
++guint
++g_sequence_octet_hash(CORBA_sequence_octet *so)
++{
++ const char *s = (char*)so->_buffer;
++ const char *p, *e = ((char *)so->_buffer) + so->_length;
++ guint h=0, g;
++
++ for(p = s; p < e; p ++) {
++ h = ( h << 4 ) + *p;
++ if ( ( g = h & 0xf0000000 ) ) {
++ h = h ^ (g >> 24);
++ h = h ^ g;
++ }
++ }
++
++ return h;
++}
++
++gint
++g_sequence_octet_compare(CORBA_sequence_octet *s1, CORBA_sequence_octet *s2)
++{
++ if(s2->_length != s1->_length)
++ return FALSE;
++
++ return !memcmp(s1->_buffer, s2->_buffer, s1->_length);
++}
++
++PortableServer_POAManager
++ORBit_POAManager_new(CORBA_Environment *ev)
++{
++ PortableServer_POAManager poa_mgr;
++
++ poa_mgr = g_new0(struct PortableServer_POAManager_type, 1);
++
++ if(poa_mgr == NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ goto error;
++ }
++
++ /* Initialise poa manager */
++
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(poa_mgr),
++ ORBIT_PSEUDO_POAMANAGER, ev);
++ ORBIT_ROOT_OBJECT(poa_mgr)->refs = 0;
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(poa_mgr),
++ (gpointer)&CORBA_POAManager_epv, ev);
++
++ poa_mgr->poa_collection = NULL;
++ poa_mgr->state = PortableServer_POAManager_HOLDING;
++
++ return poa_mgr;
++
++error:
++ if(poa_mgr != NULL){
++ ORBit_POAManager_release(poa_mgr, ev);
++ }
++ return NULL;
++}
++
++static void
++ORBit_POAManager_release(PortableServer_POAManager poa_mgr,
++ CORBA_Environment *ev)
++{
++
++ if(--(ORBIT_ROOT_OBJECT(poa_mgr)->refs) > 0)
++ return;
++
++ if(poa_mgr != NULL) {
++ if(poa_mgr->poa_collection != NULL) {
++ g_slist_free(poa_mgr->poa_collection);
++ poa_mgr->poa_collection = NULL;
++ }
++ g_free(poa_mgr);
++ poa_mgr = NULL;
++ }
++}
++
++static void
++ORBit_POAManager_register_poa(PortableServer_POAManager poa_mgr,
++ PortableServer_POA poa,
++ CORBA_Environment *ev)
++{
++ poa_mgr->poa_collection = g_slist_remove(poa_mgr->poa_collection, poa);
++ poa_mgr->poa_collection =
++ g_slist_append(poa_mgr->poa_collection, poa);
++}
++
++static void
++ORBit_POAManager_unregister_poa(PortableServer_POAManager poa_mgr,
++ PortableServer_POA poa,
++ CORBA_Environment *ev)
++{
++ poa_mgr->poa_collection = g_slist_remove(poa_mgr->poa_collection, poa);
++}
++
++static void
++ORBit_POA_set_policy(PortableServer_POA poa,
++ CORBA_Policy policy,
++ CORBA_Environment *ev)
++{
++ switch(policy->policy_type) {
++ case PortableServer_THREAD_POLICY_ID:
++ poa->thread = ((PortableServer_ThreadPolicy)policy)->value;
++ break;
++ case PortableServer_LIFESPAN_POLICY_ID:
++ poa->lifespan = ((PortableServer_LifespanPolicy)policy)->value;
++ break;
++ case PortableServer_ID_UNIQUENESS_POLICY_ID:
++ poa->id_uniqueness = ((PortableServer_IdUniquenessPolicy)policy)->value;
++ break;
++ case PortableServer_ID_ASSIGNMENT_POLICY_ID:
++ poa->id_assignment = ((PortableServer_IdAssignmentPolicy)policy)->value;
++ break;
++ case PortableServer_IMPLICIT_ACTIVATION_POLICY_ID:
++ poa->implicit_activation = ((PortableServer_ImplicitActivationPolicy)policy)->value;
++ break;
++ case PortableServer_SERVANT_RETENTION_POLICY_ID:
++ poa->servant_retention = ((PortableServer_ServantRetentionPolicy)policy)->value;
++ break;
++ case PortableServer_REQUEST_PROCESSING_POLICY_ID:
++ poa->request_processing = ((PortableServer_ServantRetentionPolicy)policy)->value;
++ break;
++ default:
++ g_warning("Unknown policy type, cannot set it on this POA");
++ }
++}
++
++
++static void
++ORBit_POA_check_policy_conflicts(PortableServer_POA poa,
++ CORBA_Environment *ev)
++{
++
++ /* Check for those policy combinations that aren't allowed */
++ if ((poa->servant_retention == PortableServer_NON_RETAIN &&
++ poa->request_processing == PortableServer_USE_ACTIVE_OBJECT_MAP_ONLY) ||
++
++ (poa->request_processing == PortableServer_USE_DEFAULT_SERVANT &&
++ poa->id_uniqueness == PortableServer_UNIQUE_ID) ||
++
++ (poa->implicit_activation == PortableServer_IMPLICIT_ACTIVATION &&
++ (poa->id_assignment == PortableServer_USER_ID ||
++ poa->servant_retention == PortableServer_NON_RETAIN))
++ )
++ {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_InvalidPolicy,
++ NULL);
++ }
++}
++
++
++static void
++ORBit_POA_set_policylist(PortableServer_POA poa,
++ CORBA_PolicyList *policies,
++ CORBA_Environment *ev)
++{
++ CORBA_unsigned_long i;
++
++ for(i = 0; i < policies->_length; i++) {
++ if(ev->_major != CORBA_NO_EXCEPTION)
++ break;
++ ORBit_POA_set_policy(poa, policies->_buffer[i], ev);
++ }
++}
++
++PortableServer_POA
++ORBit_POA_new(CORBA_ORB orb,
++ CORBA_char *adapter_name,
++ PortableServer_POAManager the_POAManager,
++ CORBA_PolicyList *policies,
++ CORBA_Environment *ev)
++{
++ PortableServer_POA poa;
++
++ /* Create the object */
++ poa = (PortableServer_POA) g_new0(struct PortableServer_POA_type, 1);
++ if(poa == NULL) {
++ CORBA_exception_set_system(ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
++ goto error;
++ }
++
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(poa), ORBIT_PSEUDO_POA, ev);
++
++ ORBIT_ROOT_OBJECT(poa)->refs = 0;
++ ORBit_RootObject_set_interface(ORBIT_ROOT_OBJECT(poa),
++ (gpointer)&CORBA_POA_epv, ev);
++
++ if(ev->_major != CORBA_NO_EXCEPTION) goto error;
++
++ /* If no POAManager was specified, create one */
++ if(the_POAManager == NULL) {
++ the_POAManager = ORBit_POAManager_new(ev);
++ }
++
++ /* Register this poa with the poa manager */
++ if(the_POAManager != NULL)
++ ORBit_POAManager_register_poa(the_POAManager,poa,ev);
++ if(ev->_major != CORBA_NO_EXCEPTION) goto error;
++
++ /* Wire up the poa_manager */
++ poa->the_POAManager = the_POAManager;
++
++ /* Initialise the child poas table */
++ poa->child_POAs = NULL; /* initialise the slist */
++
++ poa->held_requests = NULL;
++
++ poa->poaID = orb->poas->len;
++ g_ptr_array_set_size(orb->poas, orb->poas->len + 1);
++ g_ptr_array_index(orb->poas, poa->poaID) = poa;
++
++ poa->orb = orb;
++
++ g_return_val_if_fail(ev->_major == CORBA_NO_EXCEPTION, NULL);
++
++ /* Need to initialise poa policies etc.. here */
++ poa->thread = PortableServer_ORB_CTRL_MODEL;
++ poa->lifespan = PortableServer_TRANSIENT;
++ poa->id_uniqueness = PortableServer_UNIQUE_ID;
++ poa->id_assignment = PortableServer_SYSTEM_ID;
++ poa->servant_retention = PortableServer_RETAIN;
++ poa->request_processing = PortableServer_USE_ACTIVE_OBJECT_MAP_ONLY;
++ poa->implicit_activation = PortableServer_NO_IMPLICIT_ACTIVATION;
++ if (policies) {
++ ORBit_POA_set_policylist(poa, policies, ev);
++ ORBit_POA_check_policy_conflicts(poa, ev);
++ if(ev->_major != CORBA_NO_EXCEPTION) goto error;
++ }
++
++ /* copy the name */
++ poa->the_name = CORBA_string_dup(adapter_name);
++
++ poa->active_object_map = g_hash_table_new((GHashFunc)g_sequence_octet_hash,
++ (GCompareFunc)g_sequence_octet_compare);
++ poa->objnum_to_obj = g_ptr_array_new();
++ g_ptr_array_set_size(poa->objnum_to_obj, 1);
++ g_ptr_array_index(poa->objnum_to_obj, 0) = NULL;
++
++ orbit_genrand(poa->rand_data, ORBIT_RAND_KEY_LEN);
++
++ return poa;
++
++error:
++ if(poa && poa->the_name){
++ CORBA_free(poa->the_name);
++ }
++
++ if(poa != NULL){
++ ORBit_POA_release(poa, NULL);
++ }
++ return NULL;
++}
++
++static void
++ORBit_POA_release(PortableServer_POA poa,
++ CORBA_Environment *ev)
++{
++ ORBIT_ROOT_OBJECT_UNREF(poa);
++
++ if(ORBIT_ROOT_OBJECT(poa)->refs <= 0) {
++ CORBA_free(poa->the_name);
++
++ g_slist_foreach(poa->child_POAs, (GFunc)CORBA_Object_release,
++ ev);
++
++ if(poa->parent_poa)
++ ORBit_POA_remove_child(poa->parent_poa, poa, ev);
++
++ ORBit_POAManager_unregister_poa(poa->the_POAManager,
++ poa, ev);
++
++ g_ptr_array_index(poa->orb->poas, poa->poaID) = NULL;
++
++ g_free(poa);
++ }
++}
++
++void
++ORBit_POA_add_child(PortableServer_POA poa,
++ PortableServer_POA child_poa,
++ CORBA_Environment *ev)
++
++{
++ g_return_if_fail(poa != NULL);
++ g_return_if_fail(child_poa != NULL);
++
++ poa->child_POAs = g_slist_prepend(poa->child_POAs, child_poa);
++}
++
++void
++ORBit_POA_remove_child(PortableServer_POA poa,
++ PortableServer_POA child_poa,
++ CORBA_Environment *ev)
++{
++ g_return_if_fail(poa != NULL);
++ g_return_if_fail(child_poa != NULL);
++
++ poa->child_POAs = g_slist_remove(poa->child_POAs, child_poa);
++}
++
++extern ORBit_request_validate ORBIT_request_validator;
++
++gboolean
++ORBit_POA_handle_request(GIOPRecvBuffer *recv_buffer,
++ PortableServer_POA poa)
++{
++ PortableServer_ServantBase *servant;
++ PortableServer_ServantLocator_Cookie cookie;
++ ORBit_POAObject *obj_impl = NULL, tmp_obj_impl;
++ ORBitSkeleton skel;
++ gpointer imp = NULL;
++ CORBA_Environment ev;
++ GIOPSendBuffer *send_buffer;
++ guchar *opname;
++ PortableServer_ObjectId *oid = NULL;
++
++ CORBA_exception_init(&ev);
++
++ switch(poa->the_POAManager->state) {
++ case PortableServer_POAManager_HOLDING:
++ poa->held_requests = g_slist_prepend(poa->held_requests,
++ recv_buffer);
++ return FALSE;
++ break;
++ case PortableServer_POAManager_DISCARDING:
++ send_buffer = giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(recv_buffer)->connection,
++ NULL,
++ recv_buffer->message.u.request.request_id,
++ CORBA_SYSTEM_EXCEPTION);
++ CORBA_exception_set_system(&ev,
++ ex_CORBA_TRANSIENT,
++ CORBA_COMPLETED_NO);
++ ORBit_send_system_exception(send_buffer, &ev);
++ giop_send_buffer_write(send_buffer);
++ giop_recv_buffer_unuse(recv_buffer);
++ giop_send_buffer_unuse(send_buffer);
++ CORBA_exception_free(&ev);
++ return TRUE;
++ break;
++ case PortableServer_POAManager_INACTIVE:
++ send_buffer = giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(recv_buffer)->connection,
++ NULL,
++ recv_buffer->message.u.request.request_id,
++ CORBA_SYSTEM_EXCEPTION);
++ CORBA_exception_set_system(&ev,
++ ex_CORBA_OBJ_ADAPTER,
++ CORBA_COMPLETED_NO);
++ ORBit_send_system_exception(send_buffer, &ev);
++ giop_send_buffer_write(send_buffer);
++ giop_recv_buffer_unuse(recv_buffer);
++ giop_send_buffer_unuse(send_buffer);
++ CORBA_exception_free(&ev);
++ return TRUE;
++ break;
++ case PortableServer_POAManager_ACTIVE:
++ default:
++ break;
++ }
++
++ servant = NULL;
++
++ if(recv_buffer->message.u.request.object_key._length
++ < (POA_KEY_LEN + sizeof(CORBA_unsigned_long))) {
++ CORBA_exception_set_system(&ev,
++ ex_CORBA_OBJECT_NOT_EXIST,
++ CORBA_COMPLETED_NO);
++ goto errout;
++ }
++
++ obj_impl = ORBit_POA_find_oid_for_object_key(poa, &(recv_buffer->message.u.request.object_key), &oid);
++
++ if(poa->servant_retention == PortableServer_RETAIN
++ && obj_impl) {
++ servant = obj_impl->servant;
++ oid = obj_impl->object_id;
++ }
++
++ if(!servant) {
++ switch(poa->request_processing) {
++ case PortableServer_USE_SERVANT_MANAGER:
++ servant = ORBit_POA_ServantManager_use_servant(poa,
++ recv_buffer,
++ &cookie,
++ oid,
++ &tmp_obj_impl,
++ &ev);
++ break;
++ case PortableServer_USE_DEFAULT_SERVANT:
++ servant = poa->default_servant;
++ if(servant == NULL) {
++ CORBA_exception_set_system(&ev,
++ ex_CORBA_OBJ_ADAPTER,
++ CORBA_COMPLETED_NO);
++ goto errout;
++ }
++ break;
++ default:
++ break;
++ }
++ }
++
++ if(!poa || !servant || !servant->_private) {
++ CORBA_exception_set_system(&ev,
++ ex_CORBA_OBJECT_NOT_EXIST,
++ CORBA_COMPLETED_NO);
++ goto errout;
++ }
++
++ opname = recv_buffer->message.u.request.operation;
++
++ skel = ORBIT_OBJECT_KEY(servant->_private)->class_info->relay_call(servant, recv_buffer, &imp);
++
++ if(!skel) {
++ if (opname[0] == '_' && strcmp(opname + 1, "is_a") == 0) {
++ skel = (gpointer)&ORBit_impl_CORBA_Object_is_a;
++ }
++ else {
++ CORBA_exception_set_system(&ev, ex_CORBA_BAD_OPERATION,
++ CORBA_COMPLETED_NO);
++ goto errout;
++ }
++ }
++ else if (!imp) {
++ CORBA_exception_set_system(&ev, ex_CORBA_NO_IMPLEMENT,
++ CORBA_COMPLETED_NO);
++ goto errout;
++ }
++
++ /* If it got through the random keys, and nobody else had the opportunity to say otherwise, it must be auth'd */
++
++ if(!ORBIT_request_validator)
++ GIOP_MESSAGE_BUFFER(recv_buffer)->connection->is_auth = TRUE;
++
++ skel(servant, recv_buffer, &ev, imp);
++
++ if(poa->request_processing == PortableServer_USE_SERVANT_MANAGER) {
++ ORBit_POA_ServantManager_unuse_servant(servant,
++ poa,
++ recv_buffer,
++ cookie, oid,
++ &tmp_obj_impl,
++ &ev);
++ }
++
++ if(!obj_impl)
++ CORBA_free(oid);
++
++ CORBA_exception_free(&ev);
++
++ return TRUE;
++
++ errout:
++ if(ev._major == CORBA_SYSTEM_EXCEPTION) {
++ GIOPSendBuffer *reply_buf;
++
++ reply_buf =
++ giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(recv_buffer)->connection,
++ NULL,
++ recv_buffer->message.u.request.request_id,
++ CORBA_SYSTEM_EXCEPTION);
++
++ ORBit_send_system_exception(reply_buf, &ev);
++
++ giop_send_buffer_write(reply_buf);
++ giop_send_buffer_unuse(reply_buf);
++ } else /* User exceptions are handled in the skels! */
++ g_assert(ev._major == CORBA_NO_EXCEPTION);
++
++ if(!obj_impl)
++ CORBA_free(oid);
++
++ CORBA_exception_free(&ev);
++
++ return TRUE;
++}
++
++PortableServer_POA
++ORBit_POA_find_POA_for_object_key(PortableServer_POA root_poa,
++ CORBA_sequence_octet *key)
++{
++ CORBA_unsigned_long pid;
++
++ if(key->_length < (sizeof(CORBA_unsigned_long) + ORBIT_RAND_KEY_LEN))
++ return NULL;
++
++ pid = *((CORBA_unsigned_long *)key->_buffer);
++
++ if(pid < root_poa->orb->poas->len) {
++ PortableServer_POA poa;
++ poa = g_ptr_array_index(root_poa->orb->poas, pid);
++ if(!poa)
++ return NULL;
++ if(memcmp(poa->rand_data, key->_buffer + sizeof(CORBA_unsigned_long), ORBIT_RAND_KEY_LEN))
++ return NULL;
++ return poa;
++ } else
++ return NULL;
++}
++
++void
++ORBit_POA_find_object_key_for_oid(PortableServer_POA poa,
++ ORBit_POAObject *obj,
++ PortableServer_ObjectId *oid,
++ CORBA_sequence_octet *retval)
++{
++ CORBA_long *vptr;
++
++ g_return_if_fail(poa && (obj || oid));
++ g_return_if_fail(retval);
++
++ if(oid)
++ g_assert(!oid->_buffer[oid->_length - 1]);
++
++ if(obj)
++ retval->_length = POA_KEY_LEN + OBJ_KEY_LEN;
++ else
++ retval->_length = POA_KEY_LEN + sizeof(CORBA_long) + oid->_length;
++ retval->_buffer = CORBA_octet_allocbuf(retval->_length);
++ CORBA_sequence_set_release(retval, CORBA_TRUE);
++
++ vptr = (CORBA_long *)retval->_buffer;
++ *vptr = poa->poaID;
++ memcpy(retval->_buffer + sizeof(CORBA_unsigned_long), poa->rand_data, ORBIT_RAND_KEY_LEN);
++
++ vptr = (CORBA_long *)(retval->_buffer + POA_KEY_LEN);
++ if(obj) {
++ *vptr = obj->objnum;
++ memcpy(retval->_buffer + POA_KEY_LEN + sizeof(CORBA_unsigned_long), obj->rand_data, ORBIT_RAND_KEY_LEN);
++ } else {
++ *vptr = -((CORBA_long)oid->_length);
++ memcpy(retval->_buffer + POA_KEY_LEN + sizeof(CORBA_unsigned_long), oid->_buffer, oid->_length);
++ }
++}
++
++ORBit_POAObject *
++ORBit_POA_find_oid_for_object_key(PortableServer_POA poa,
++ CORBA_sequence_octet *object_key,
++ PortableServer_ObjectId **oid)
++{
++ CORBA_long onum;
++ guchar *nptr;
++ ORBit_POAObject *objinfo;
++
++ *oid = NULL;
++ nptr = object_key->_buffer + POA_KEY_LEN;
++
++ if(object_key->_length < (POA_KEY_LEN + sizeof(CORBA_long))) {
++ return NULL;
++ }
++
++ onum = *((CORBA_long *)nptr);
++
++ if(onum < 0) {
++ /* onum will be the -strlen(ObjectId) */
++ if(object_key->_length < (POA_KEY_LEN + sizeof(CORBA_long) - onum))
++ return NULL;
++
++ *oid = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++ (*oid)->_length = -onum;
++ (*oid)->_buffer = CORBA_octet_allocbuf((*oid)->_length);
++ memcpy((*oid)->_buffer, object_key->_buffer + POA_KEY_LEN + sizeof(CORBA_long), (*oid)->_length);
++
++ return NULL;
++ }
++
++ if(onum >= poa->objnum_to_obj->len)
++ return NULL;
++
++ objinfo = g_ptr_array_index(poa->objnum_to_obj, onum);
++
++ if(GPOINTER_TO_UINT(objinfo) <= poa->objnum_to_obj->len)
++ return NULL;
++
++ if(object_key->_length < (POA_KEY_LEN + OBJ_KEY_LEN))
++ return NULL;
++
++ if(memcmp(object_key->_buffer + POA_KEY_LEN + sizeof(CORBA_long), objinfo->rand_data, ORBIT_RAND_KEY_LEN))
++ return NULL;
++
++ return objinfo;
++}
++
++DEFINE_LOCK(id_assignment_counter);
++static int id_assignment_counter = 0;
++
++PortableServer_ObjectId *
++ORBit_POA_allocate_oid(PortableServer_POA poa,
++ const char *basis)
++{
++ PortableServer_ObjectId *new_objid;
++ char buf[512];
++ int len;
++
++ new_objid = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++
++ GET_LOCK(id_assignment_counter);
++ g_snprintf(buf, sizeof(buf), "%s%d", basis?basis:"Object",
++ id_assignment_counter);
++ id_assignment_counter++;
++ RELEASE_LOCK(id_assignment_counter);
++
++ len = strlen(buf)+1;
++ new_objid->_buffer = CORBA_octet_allocbuf(len);
++ new_objid->_length = len;
++ new_objid->_maximum = len;
++ new_objid->_release = CORBA_TRUE;
++
++ strcpy((CORBA_char *)new_objid->_buffer, buf);
++
++ return new_objid;
++}
++
++static PortableServer_Servant
++ORBit_POA_ServantManager_use_servant(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer,
++ PortableServer_ServantLocator_Cookie *the_cookie,
++ PortableServer_ObjectId *oid,
++ ORBit_POAObject *fake_obj_impl,
++ CORBA_Environment *ev)
++{
++ if(poa->servant_retention == PortableServer_RETAIN) {
++ POA_PortableServer_ServantActivator *sm;
++ POA_PortableServer_ServantActivator__epv *epv;
++
++ sm = (POA_PortableServer_ServantActivator *)poa->servant_manager;
++ epv = sm->vepv->PortableServer_ServantActivator_epv;
++ return epv->incarnate(sm, oid, poa, ev);
++ } else {
++ POA_PortableServer_ServantLocator *sm;
++ POA_PortableServer_ServantLocator__epv *epv;
++ PortableServer_ServantBase *retval;
++
++ sm = (POA_PortableServer_ServantLocator *)poa->servant_manager;
++ epv = sm->vepv->PortableServer_ServantLocator_epv;
++ retval = epv->preinvoke(sm, oid,
++ poa, recv_buffer->message.u.request.operation,
++ the_cookie,
++ ev);
++
++ ((ORBit_ObjectKey *)retval->_private)->object = fake_obj_impl;
++ fake_obj_impl->object_id = oid;
++ fake_obj_impl->poa = poa;
++ fake_obj_impl->orb = poa->orb;
++ fake_obj_impl->objnum = -1;
++#ifdef NOT_BACKWARDS_COMPAT_0_4
++ fake_obj_impl->use_count = NULL;
++ fake_obj_impl->death_callback = NULL;
++#endif
++
++ return retval;
++ }
++}
++
++static void
++ORBit_POA_ServantManager_unuse_servant(PortableServer_Servant servant,
++ PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer,
++ PortableServer_ServantLocator_Cookie cookie,
++ PortableServer_ObjectId *oid,
++ ORBit_POAObject *fake_obj_impl,
++ CORBA_Environment *ev)
++{
++ POA_PortableServer_ServantLocator *sm;
++ POA_PortableServer_ServantLocator__epv *epv;
++
++ if(poa->servant_retention != PortableServer_NON_RETAIN)
++ return;
++
++ sm = (POA_PortableServer_ServantLocator *)poa->servant_manager;
++ epv = sm->vepv->PortableServer_ServantLocator_epv;
++
++ ((ORBit_ObjectKey *)((PortableServer_ServantBase *)servant)->_private)->object = NULL;
++ epv->postinvoke(sm, oid,
++ poa, recv_buffer->message.u.request.operation,
++ cookie, servant, ev);
++
++}
++
++typedef struct {
++ PortableServer_POA poa;
++ CORBA_Environment *ev;
++} EtherealizeInfo;
++
++void
++ORBit_POA_etherealize_object(PortableServer_ObjectId *oid,
++ ORBit_POAObject *obj_impl,
++ EtherealizeInfo *ei)
++{
++ POA_PortableServer_ServantActivator__epv *epv;
++ POA_PortableServer_ServantActivator *sm;
++
++ g_assert(ei->poa->servant_manager);
++
++ g_hash_table_remove(ei->poa->active_object_map,
++ obj_impl->object_id);
++
++ sm = (POA_PortableServer_ServantActivator *)ei->poa->servant_manager;
++ epv = sm->vepv->PortableServer_ServantActivator_epv;
++ epv->etherealize(sm, obj_impl->object_id, ei->poa,
++ obj_impl->servant,
++ CORBA_TRUE, CORBA_FALSE, ei->ev);
++}
++
++void
++ORBit_POA_etherealize_objects(PortableServer_POA poa,
++ CORBA_Environment *ev)
++{
++ EtherealizeInfo ei;
++
++ ei.poa = poa;
++ ei.ev = ev;
++
++ if(poa->servant_retention == PortableServer_RETAIN
++ && poa->request_processing == PortableServer_USE_SERVANT_MANAGER) {
++
++ g_hash_table_foreach(poa->active_object_map,
++ (GHFunc)ORBit_POA_etherealize_object,
++ &ei);
++ }
++}
++
++#ifdef NOT_BACKWARDS_COMPAT_0_4
++void ORBit_servant_set_deathwatch(PortableServer_ServantBase *servant,
++ int *use_count,
++ GFunc death_func,
++ gpointer user_data)
++{
++ ORBit_POAObject *pobj;
++
++ pobj = ORBIT_OBJECT_KEY(servant->_private)->object;
++
++ pobj->use_count = use_count;
++ pobj->death_callback = death_func;
++ pobj->user_data = user_data;
++}
++#endif
+diff -urN linux-2.4.1/net/korbit/orb/orbit_poa.h linux-2.4.1-korbit/net/korbit/orb/orbit_poa.h
+--- linux-2.4.1/net/korbit/orb/orbit_poa.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_poa.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,89 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Phil Dawes <philipd@parallax.co.uk>
++ *
++ */
++
++/*
++ * ORBit specific POA funcitons.
++ *
++ */
++
++#ifndef _ORBIT_ORBIT_POA_H_
++#define _ORBIT_ORBIT_POA_H_
++
++#include "orbit_types.h"
++#include "orbit_poa_type.h"
++
++/*
++ * Creates a new POAManager
++ */
++
++extern PortableServer_POAManager ORBit_POAManager_new(CORBA_Environment *ev);
++
++extern void ORBit_POAManager_free(PortableServer_POAManager poa_mgr,
++ CORBA_Environment *ev);
++
++extern PortableServer_POA ORBit_POA_new(CORBA_ORB orb,
++ CORBA_char *adapter_name,
++ PortableServer_POAManager the_POAManager,
++ CORBA_PolicyList *policies,
++ CORBA_Environment *ev);
++
++extern void ORBit_POA_free(PortableServer_POA poa, CORBA_Environment *ev);
++
++extern void ORBit_POA_add_child(PortableServer_POA poa,
++ PortableServer_POA child_poa,
++ CORBA_Environment *ev);
++void ORBit_POA_remove_child(PortableServer_POA poa,
++ PortableServer_POA child_poa,
++ CORBA_Environment *ev);
++
++gboolean ORBit_POA_handle_request(GIOPRecvBuffer *recv_buffer,
++ PortableServer_POA poa);
++PortableServer_POA
++ORBit_POA_find_POA_for_object_key(PortableServer_POA root_poa,
++ CORBA_sequence_octet *key);
++void
++ORBit_POA_find_object_key_for_oid(PortableServer_POA poa,
++ ORBit_POAObject *obj,
++ PortableServer_ObjectId *oid,
++ CORBA_sequence_octet *retval);
++ORBit_POAObject *
++ORBit_POA_find_oid_for_object_key(PortableServer_POA poa,
++ CORBA_sequence_octet *object_key,
++ PortableServer_ObjectId **oid);
++
++PortableServer_ObjectId *ORBit_POA_allocate_oid(PortableServer_POA poa,
++ const char *basis);
++
++void ORBit_POA_etherealize_objects(PortableServer_POA poa, CORBA_Environment *ev);
++
++#ifdef NOT_BACKWARDS_COMPAT_0_4
++/* Bad hack for shared libraries */
++void ORBit_servant_set_deathwatch(PortableServer_ServantBase *servant,
++ int *use_count,
++ GFunc death_func,
++ gpointer user_data);
++#endif
++
++#endif /* !_ORBIT_ORBIT_POA_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_poa_type.h linux-2.4.1-korbit/net/korbit/orb/orbit_poa_type.h
+--- linux-2.4.1/net/korbit/orb/orbit_poa_type.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_poa_type.h Thu Feb 1 11:47:13 2001
+@@ -0,0 +1,112 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Phil Dawes <philipd@parallax.co.uk>
++ *
++ */
++
++/*
++ * ORBit specific POA funcitons.
++ *
++ */
++
++#ifndef _ORBIT_ORBIT_POA_TYPE_H_
++#define _ORBIT_ORBIT_POA_TYPE_H_
++
++typedef void (*ORBitSkeleton)(PortableServer_ServantBase *_ORBIT_servant,
++ gpointer _ORBIT_recv_buffer,
++ CORBA_Environment *ev,
++ gpointer implementation);
++typedef ORBitSkeleton (*ORBit_impl_finder)(PortableServer_ServantBase *servant,
++ gpointer _ORBIT_recv_buffer,
++ gpointer *implementation);
++typedef void (*ORBit_local_objref_init)(CORBA_Object obj,
++ PortableServer_ServantBase *servant);
++typedef struct {
++ ORBit_impl_finder relay_call;
++ const gchar *class_name;
++ ORBit_local_objref_init init_local_objref;
++} PortableServer_ClassInfo;
++
++#define ORBIT_RAND_KEY_LEN 8
++
++typedef struct {
++ PortableServer_ObjectId *object_id;
++ PortableServer_Servant servant;
++ PortableServer_POA poa;
++ CORBA_ORB orb;
++ CORBA_unsigned_long objnum;
++
++ /* Stuff for doing shared libraries nicely */
++ guchar rand_data[ORBIT_RAND_KEY_LEN];
++
++#ifdef NOT_BACKWARDS_COMPAT_0_4
++ int *use_count;
++ GFunc death_callback;
++ gpointer user_data;
++#endif
++} ORBit_POAObject;
++
++typedef struct {
++ PortableServer_ClassInfo *class_info;
++ ORBit_POAObject *object;
++} ORBit_ObjectKey;
++
++#define ORBIT_OBJECT_KEY(x) ((ORBit_ObjectKey *)(x))
++
++struct PortableServer_POA_type {
++ struct ORBit_PseudoObject_struct parent;
++
++ PortableServer_POA parent_poa;
++ CORBA_ORB orb;
++ CORBA_unsigned_long poaID;
++
++ GHashTable *active_object_map;
++ GPtrArray *objnum_to_obj; /* maps objnums to ORBit_POAObject's */
++ CORBA_long first_free_id;
++
++ /* Requests received while in a HOLDING state */
++ GSList *held_requests;
++
++ /* this'll be a hash table when I can be arsed to look up
++ how to implement efficient hash tables - Phil.*/
++ GSList *child_POAs;
++
++ CORBA_char *the_name;
++ PortableServer_POAManager the_POAManager;
++
++ PortableServer_AdapterActivator the_activator;
++
++ PortableServer_ServantManager servant_manager;
++ PortableServer_Servant default_servant;
++
++ PortableServer_ThreadPolicyValue thread;
++ PortableServer_LifespanPolicyValue lifespan;
++ PortableServer_IdUniquenessPolicyValue id_uniqueness;
++ PortableServer_IdAssignmentPolicyValue id_assignment;
++ PortableServer_ImplicitActivationPolicyValue implicit_activation;
++ PortableServer_ServantRetentionPolicyValue servant_retention;
++ PortableServer_RequestProcessingPolicyValue request_processing;
++
++ guchar rand_data[ORBIT_RAND_KEY_LEN];
++};
++
++#endif /* !_ORBIT_ORBIT_POA_TYPE_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/orbit_typecode.c linux-2.4.1-korbit/net/korbit/orb/orbit_typecode.c
+--- linux-2.4.1/net/korbit/orb/orbit_typecode.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_typecode.c Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,593 @@
++#include "orbit.h"
++#include "orbit_typecode.h"
++#include "cdr.h"
++#include "corba_typecode_type.h"
++#include <IIOP/giop-msg-buffer.h>
++#include "../IIOP/iiop-endianP.h"
++
++#if 0
++#define CORBA_Object_release(x, y) ({ g_message(__FILE__ ":%d Releasing object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_release(x, y); })
++#define CORBA_Object_duplicate(x, y) ({ g_message(__FILE__ ":%d Duping object %#x from %d", __LINE__, \
++x, ORBIT_ROOT_OBJECT(x)->refs); CORBA_Object_duplicate(x, y); })
++#endif
++
++typedef struct{
++ CORBA_TypeCode tc;
++ guint index;
++}TCRecursionNode;
++
++typedef struct{
++ GSList* prior_tcs; /* Could be a hash table by typecode */
++ guint current_idx; /* The "top-level" index of the start of the current codec */
++}TCEncodeContext;
++
++typedef struct{
++ GSList* prior_tcs; /* Could be a hash table by offset */
++ guint current_idx;
++}TCDecodeContext;
++
++
++
++static void tc_enc(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec(CORBA_TypeCode* t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_objref(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_objref(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_sequence(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_sequence(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_string(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_string(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_struct(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_struct(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_union(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_union(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_enum(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_enum(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_alias(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_alias(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_except(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_except(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_array(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_array(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_fixed(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_fixed(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++static void tc_enc_tk_wstring(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx);
++static void tc_dec_tk_wstring(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx);
++
++
++
++typedef void
++(*CORBA_TypeCodeEncoder)(CORBA_TypeCode t,
++ CDR_Codec* c,
++ TCEncodeContext* ctx);
++
++typedef void
++(*CORBA_TypeCodeDecoder)(CORBA_TypeCode t,
++ CDR_Codec* c,
++ TCDecodeContext* ctx);
++
++
++typedef enum{
++ TK_EMPTY,
++ TK_SIMPLE,
++ TK_COMPLEX
++} TkType;
++
++typedef struct{
++ TkType type;
++ CORBA_TypeCodeEncoder encoder;
++ CORBA_TypeCodeDecoder decoder;
++} TkInfo;
++
++static const TkInfo tk_info[CORBA_tk_last]={
++ {TK_EMPTY, NULL, NULL}, /* tk_null */
++ {TK_EMPTY, NULL, NULL}, /* tk_void */
++ {TK_EMPTY, NULL, NULL}, /* tk_short */
++ {TK_EMPTY, NULL, NULL}, /* tk_long */
++ {TK_EMPTY, NULL, NULL}, /* tk_ushort */
++ {TK_EMPTY, NULL, NULL}, /* tk_ulong */
++ {TK_EMPTY, NULL, NULL}, /* tk_float */
++ {TK_EMPTY, NULL, NULL}, /* tk_double */
++ {TK_EMPTY, NULL, NULL}, /* tk_boolean */
++ {TK_EMPTY, NULL, NULL}, /* tk_char */
++ {TK_EMPTY, NULL, NULL}, /* tk_octet */
++ {TK_EMPTY, NULL, NULL}, /* tk_any */
++ {TK_EMPTY, NULL, NULL}, /* tk_TypeCode */
++ {TK_EMPTY, NULL, NULL}, /* tk_Principal */
++ {TK_COMPLEX, tc_enc_tk_objref, tc_dec_tk_objref}, /* tk_objref */
++ {TK_COMPLEX, tc_enc_tk_struct, tc_dec_tk_struct}, /* tk_struct */
++ {TK_COMPLEX, tc_enc_tk_union, tc_dec_tk_union}, /* tk_union */
++ {TK_COMPLEX, tc_enc_tk_enum, tc_dec_tk_enum}, /* tk_enum */
++ {TK_SIMPLE, tc_enc_tk_string, tc_dec_tk_string}, /* tk_string */
++ {TK_COMPLEX, tc_enc_tk_sequence, tc_dec_tk_sequence}, /* tk_sequence */
++ {TK_COMPLEX, tc_enc_tk_array, tc_dec_tk_array}, /* tk_array */
++ {TK_COMPLEX, tc_enc_tk_alias, tc_dec_tk_alias}, /* tk_alias */
++ {TK_COMPLEX, tc_enc_tk_except, tc_dec_tk_except}, /* tk_except */
++ {TK_EMPTY, NULL, NULL}, /* tk_longlong */
++ {TK_EMPTY, NULL, NULL}, /* tk_ulonglong */
++ {TK_EMPTY, NULL, NULL}, /* tk_longdouble */
++ {TK_EMPTY, NULL, NULL}, /* tk_wchar */
++ {TK_SIMPLE, tc_enc_tk_wstring, tc_dec_tk_wstring}, /* tk_wstring */
++ {TK_SIMPLE, tc_enc_tk_fixed, tc_dec_tk_fixed} /* tk_fixed */
++};
++
++void ORBit_encode_CORBA_TypeCode(CORBA_TypeCode t, GIOPSendBuffer* buf)
++{
++ CDR_Codec codec_d;
++ CDR_Codec* codec = &codec_d;
++ TCEncodeContext ctx;
++ GSList* l;
++ CORBA_octet codecbuf[2048];
++
++ CDR_codec_init_static(codec);
++
++ codec->wptr = 0;
++ codec->buffer = codecbuf;
++ codec->release_buffer = FALSE;
++ codec->buf_len = 2048;
++ codec->data_endian=FLAG_ENDIANNESS;
++
++ ctx.current_idx=0;
++ ctx.prior_tcs=NULL;
++ tc_enc(t, codec, &ctx);
++ for(l=ctx.prior_tcs;l;l=l->next)
++ g_free(l->data);
++ g_slist_free(ctx.prior_tcs);
++ giop_send_buffer_append_mem_indirect(buf,
++ codec->buffer,
++ codec->wptr);
++}
++
++void ORBit_decode_CORBA_TypeCode(CORBA_TypeCode* t, GIOPRecvBuffer* buf)
++{
++ CDR_Codec codec_d;
++ CDR_Codec* codec = &codec_d;
++ TCDecodeContext ctx;
++ GSList* l;
++
++ CDR_codec_init_static(codec);
++ codec->buffer=buf->cur;
++ codec->release_buffer=CORBA_FALSE;
++ codec->readonly=CORBA_TRUE;
++ codec->buf_len = /* hope this is correct */
++ ((guchar *)buf->message_body) +
++ GIOP_MESSAGE_BUFFER(buf)->message_header.message_size
++ - ((guchar *)buf->cur);
++
++ codec->data_endian=GIOP_MESSAGE_BUFFER(buf)->message_header.flags & 1;
++
++ ctx.current_idx=0;
++ ctx.prior_tcs=NULL;
++ tc_dec(t, codec, &ctx);
++ for(l=ctx.prior_tcs;l;l=l->next)
++ g_free(l->data);
++ g_slist_free(ctx.prior_tcs);
++ buf->cur = ((guchar *)buf->cur) + codec->rptr;
++}
++
++
++/* Encode a typecode to a codec, possibly recursively */
++
++static void tc_enc(CORBA_TypeCode tc,
++ CDR_Codec* codec,
++ TCEncodeContext* ctx)
++{
++ TCRecursionNode* node;
++ const TkInfo* info;
++ GSList* l;
++ CORBA_octet codecbuf[2048];
++ CDR_Codec encaps_d;
++ CDR_Codec* encaps = &encaps_d;
++
++ g_assert(CLAMP(0, tc->kind, CORBA_tk_last) == tc->kind);
++
++ for(l=ctx->prior_tcs;l;l=l->next){
++ TCRecursionNode* node=l->data;
++ /* CORBA_CORBA_TypeCode_equal might save space, but is slow.. */
++ if(node->tc==tc){
++ CDR_put_ulong(codec, CORBA_tk_recursive);
++ CDR_put_long(codec,
++ node->index
++ -ctx->current_idx
++ -codec->wptr);
++ return;
++ }
++ }
++
++ /* All right, this isn't a previously met type. So record it. */
++ /* NOTE: put kind before recording index so alignment is dealt with! */
++ CDR_put_ulong(codec, tc->kind);
++
++ node=g_new(TCRecursionNode, 1);
++ node->tc=tc;
++ node->index=ctx->current_idx+codec->wptr - 4; /* -4 for kind */
++ ctx->prior_tcs=g_slist_prepend(ctx->prior_tcs, node);
++
++ info=&tk_info[tc->kind];
++ switch(info->type){
++ guint tmp_index;
++ case TK_EMPTY:
++ break;
++ case TK_COMPLEX:
++ tmp_index=ctx->current_idx;
++ ctx->current_idx+=codec->wptr+4; /* +4 for the length */
++ CDR_codec_init_static(encaps);
++ encaps->wptr = 0;
++ encaps->buffer = codecbuf;
++ encaps->release_buffer = FALSE;
++ encaps->buf_len = 2048;
++ encaps->data_endian=FLAG_ENDIANNESS;
++ CDR_put_octet(encaps, FLAG_ENDIANNESS);
++ (info->encoder)(tc, encaps, ctx);
++ CDR_put_ulong(codec, encaps->wptr);
++ /* Now this is a time hog */
++ CDR_put_octets(codec, encaps->buffer, encaps->wptr);
++ ctx->current_idx=tmp_index;
++ break;
++ case TK_SIMPLE:
++ (info->encoder)(tc, codec, ctx);
++ }
++}
++
++static void
++ORBit_TypeCode_release(gpointer obj, CORBA_Environment *ev)
++{
++ /* we will initialize the TC_ constants with a negative refcount */
++ if(ORBIT_ROOT_OBJECT(obj)->refs >= 0) {
++ ORBIT_ROOT_OBJECT_UNREF(obj);
++
++ if(ORBIT_ROOT_OBJECT(obj)->refs <= 0) {
++ CORBA_TypeCode tc = obj;
++ int i;
++
++ g_free(tc->name);
++ g_free(tc->repo_id);
++
++ for(i = 0; i < tc->sub_parts; i++) {
++ if(tc->subnames)
++ g_free(tc->subnames[i]);
++
++ if(tc->subtypes)
++ CORBA_Object_release((CORBA_Object)tc->subtypes[i], ev);
++
++ if(tc->sublabels)
++ CORBA_any__free(&tc->sublabels[i], NULL, TRUE);
++ }
++
++ g_free(tc->subnames);
++ g_free(tc->subtypes);
++ g_free(tc->sublabels);
++
++ if(tc->discriminator)
++ CORBA_Object_release((CORBA_Object)tc->discriminator, ev);
++
++ g_free(obj);
++ }
++
++ }
++}
++
++const ORBit_RootObject_Interface ORBit_TypeCode_epv = {
++ &ORBit_TypeCode_release
++};
++
++static void tc_dec(CORBA_TypeCode* t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CORBA_TCKind kind;
++ CORBA_TypeCode tc;
++ const TkInfo* info;
++ TCRecursionNode* node;
++ CDR_Codec encaps_d;
++ CDR_Codec* encaps = &encaps_d;
++
++ CDR_get_ulong(c, &kind);
++
++ g_assert(CLAMP(0, kind, CORBA_tk_last) == kind);
++
++ if(kind==CORBA_tk_recursive){
++ CORBA_long offset;
++ GSList* l;
++ CDR_get_ulong(c, &offset);
++ for(l=ctx->prior_tcs;l;l=l->next){
++ node=l->data;
++ /* NOTE: below, -4 is b/c we already read offset */
++ if(node->index==ctx->current_idx+c->rptr+offset-4){
++ *t=node->tc;
++ return;
++ }
++ }
++ ORBit_Trace(TraceMod_ORB, TraceLevel_Error,
++ "tc_dec: Invalid CORBA_TypeCode recursion offset "
++ "in input buffer\n");
++ g_assert_not_reached();
++ }
++
++ ORBit_Trace(TraceMod_TC, TraceLevel_Debug, "codec->host_endian: %d, codec->data_endian: %d\n", c->host_endian, c->data_endian);
++ ORBit_Trace(TraceMod_TC, TraceLevel_Debug, "kind: %d, CORBA_tk_last: %d\n", kind, CORBA_tk_last);
++ g_assert(kind<CORBA_tk_last);
++
++ node=g_new(TCRecursionNode, 1);
++ node->index=ctx->current_idx+c->rptr-4; /* -4 for the TCKind */
++ info=&tk_info[kind];
++
++ tc=g_new0(struct CORBA_TypeCode_struct, 1);
++
++ /* Passing in NULL for CORBA_Environment is patently dangerous. */
++ ORBit_pseudo_object_init((ORBit_PseudoObject)tc,
++ ORBIT_PSEUDO_TYPECODE, NULL);
++ ORBit_RootObject_set_interface((ORBit_RootObject)tc,
++ (ORBit_RootObject_Interface *)&ORBit_TypeCode_epv,
++ NULL);
++
++ tc->kind=kind;
++ switch(info->type){
++ guint tmp_index;
++ CORBA_octet o;
++
++ case TK_EMPTY:
++ break;
++
++ case TK_COMPLEX:
++ tmp_index=ctx->current_idx;
++ CDR_codec_init_static(encaps);
++ CDR_get_ulong(c, &encaps->buf_len);
++ ctx->current_idx+=c->rptr;
++ encaps->buffer=&c->buffer[c->rptr];
++ encaps->release_buffer=CORBA_FALSE;
++ CDR_get_octet(encaps, &o);
++ encaps->data_endian=o;
++ (info->decoder)(tc, encaps, ctx);
++ c->rptr += encaps->buf_len;
++ ctx->current_idx=tmp_index;
++ break;
++ case TK_SIMPLE:
++ (info->decoder)(tc, c, ctx);
++ break;
++ }
++ node->tc=tc;
++ ctx->prior_tcs=g_slist_prepend(ctx->prior_tcs, node);
++ *t=tc;
++}
++
++
++
++static void tc_enc_tk_objref(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++}
++
++static void tc_dec_tk_objref(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++}
++
++static void tc_enc_tk_sequence(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ tc_enc(*t->subtypes, c, ctx);
++ CDR_put_ulong(c, t->length);
++}
++
++static void tc_dec_tk_sequence(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ t->subtypes=g_new(CORBA_TypeCode, 1);
++ tc_dec(&t->subtypes[0], c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[0], NULL);
++ CDR_get_ulong(c, &t->length);
++}
++
++static void tc_enc_tk_string(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CDR_put_ulong(c, t->length);
++}
++
++static void tc_dec_tk_string(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CDR_get_ulong(c, &t->length);
++}
++
++static void tc_enc_tk_struct(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++ CDR_put_ulong(c, t->sub_parts);
++ for(i=0;i<t->sub_parts;i++){
++ CDR_put_string(c, t->subnames[i]);
++ tc_enc(t->subtypes[i], c, ctx);
++ }
++}
++
++static void tc_dec_tk_struct(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++ CDR_get_ulong(c, &t->sub_parts);
++ t->subnames=g_new(gchar*, t->sub_parts);
++ t->subtypes=g_new(CORBA_TypeCode, t->sub_parts);
++ for(i=0;i<t->sub_parts;i++){
++ CDR_get_string(c, &t->subnames[i]);
++ tc_dec(&t->subtypes[i], c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[i], NULL);
++ }
++}
++
++#define UNION_MEMBERS(dir) \
++ MEMBER_LOOPER_##dir(ulong, long, long); \
++ case CORBA_tk_enum: /* fall through */ \
++ MEMBER_LOOPER_##dir(ulong, unsigned_long, ulong); \
++ MEMBER_LOOPER_##dir(octet, boolean, boolean); \
++ MEMBER_LOOPER_##dir(octet, char, char); \
++ MEMBER_LOOPER_##dir(ushort, short, short); \
++ MEMBER_LOOPER_##dir(ushort, unsigned_short, ushort); \
++ MEMBER_LOOPER_##dir(ulong_long, long_long, longlong); \
++ MEMBER_LOOPER_##dir(ulong_long, unsigned_long_long, ulonglong); \
++ /* MEMBER_LOOPER_##dir(wchar, wchar, wchar); */
++
++
++static void tc_enc_tk_union(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++ tc_enc(t->discriminator, c, ctx);
++ CDR_put_long(c, t->default_index);
++ CDR_put_ulong(c, t->sub_parts);
++ i=t->sub_parts;
++ /* Thank goodness the discriminator types are rather limited,
++ we can do the marshalling inline.. */
++#define MEMBER_LOOPER_ENC(putname, typename, tkname) \
++ case CORBA_tk_##tkname: \
++ for(i=0;i<t->sub_parts;i++){ \
++ CDR_put_##putname(c, *(CORBA_##typename*) \
++ (t->sublabels[i]._value)); \
++ CDR_put_string(c, t->subnames[i]); \
++ tc_enc(t->subtypes[i], c, ctx); \
++ } \
++ break
++
++ switch(t->discriminator->kind){
++ UNION_MEMBERS(ENC);
++ default:
++ ORBit_Trace(TraceMod_ORB, TraceLevel_Error,
++ "tc_enc_tk_union: Illegal union discriminator "
++ "type %s\n", t->discriminator->name);
++ }
++}
++
++static void tc_dec_tk_union(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++ tc_dec(&t->discriminator, c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->discriminator, NULL);
++ CDR_get_ulong(c, &t->default_index);
++ CDR_get_ulong(c, &t->sub_parts);
++
++ t->sublabels=g_new(CORBA_any, t->sub_parts);
++ t->subnames=g_new(gchar*, t->sub_parts);
++ t->subtypes=g_new(CORBA_TypeCode, t->sub_parts);
++
++#define MEMBER_LOOPER_DEC(getname, typename, tkname) \
++ case CORBA_tk_##tkname: \
++ for(i=0;i<t->sub_parts;i++){ \
++ t->sublabels[i]._type = \
++ CORBA_Object_duplicate((CORBA_Object)t->discriminator, NULL); \
++ t->sublabels[i]._value = g_new(CORBA_##typename,1); \
++ t->sublabels[i]._release = CORBA_TRUE; \
++ CDR_get_##getname(c, t->sublabels[i]._value); \
++ CDR_get_string(c, &t->subnames[i]); \
++ tc_dec(&t->subtypes[i], c, ctx); \
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[i], NULL); \
++ } \
++ break
++
++ switch(t->discriminator->kind){
++ UNION_MEMBERS(DEC);
++ default:
++ /* XXX: what is correct error handling */
++ g_assert(!"Not yet implemented.");
++ }
++}
++
++static void tc_enc_tk_enum(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++ CDR_put_ulong(c, t->sub_parts);
++ for(i=0;i<t->sub_parts;i++)
++ CDR_put_string(c, t->subnames[i]);
++}
++
++static void tc_dec_tk_enum(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CORBA_unsigned_long i;
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++ CDR_get_ulong(c, &t->sub_parts);
++ t->subnames=g_new(gchar*, t->sub_parts);
++ for(i=0;i<t->sub_parts;i++)
++ CDR_get_string(c, &t->subnames[i]);
++}
++
++static void tc_enc_tk_alias(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++ tc_enc(*t->subtypes, c, ctx);
++}
++
++static void tc_dec_tk_alias(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++ t->subtypes=g_new(CORBA_TypeCode, 1);
++ tc_dec(t->subtypes, c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[0], NULL);
++}
++
++
++static void tc_enc_tk_except(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ gulong i;
++ CDR_put_string(c, t->repo_id);
++ CDR_put_string(c, t->name);
++ CDR_put_ulong(c, t->sub_parts);
++ for(i=0;i<t->length;i++){
++ CDR_put_string(c, t->subnames[i]);
++ tc_enc(t->subtypes[i], c, ctx);
++ }
++}
++
++static void tc_dec_tk_except(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ gulong i;
++ CDR_get_string(c, &t->repo_id);
++ CDR_get_string(c, &t->name);
++ CDR_get_ulong(c, &t->sub_parts);
++ t->subtypes=g_new(CORBA_TypeCode, t->sub_parts);
++ t->subnames=g_new(gchar*, t->sub_parts);
++ for(i=0;i<t->length;i++){
++ CDR_get_string(c, &t->subnames[i]);
++ tc_dec(&t->subtypes[i], c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[i], NULL);
++ }
++}
++
++static void tc_enc_tk_array(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ tc_enc(*t->subtypes, c, ctx);
++ CDR_put_ulong(c, t->length);
++}
++
++static void tc_dec_tk_array(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ t->subtypes=g_new(CORBA_TypeCode, 1);
++ tc_dec(t->subtypes, c, ctx);
++ CORBA_Object_duplicate((CORBA_Object)t->subtypes[0], NULL);
++ CDR_get_ulong(c, &t->length);
++}
++
++static void tc_enc_tk_wstring(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ g_assert(!"Not yet implemented.");
++}
++
++static void tc_dec_tk_wstring(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ g_assert(!"Not yet implemented.");
++}
++
++static void tc_enc_tk_fixed(CORBA_TypeCode t, CDR_Codec* c, TCEncodeContext* ctx)
++{
++ g_assert(!"Not yet implemented.");
++}
++
++static void tc_dec_tk_fixed(CORBA_TypeCode t, CDR_Codec* c, TCDecodeContext* ctx)
++{
++ g_assert(!"Not yet implemented.");
++}
+diff -urN linux-2.4.1/net/korbit/orb/orbit_typecode.h linux-2.4.1-korbit/net/korbit/orb/orbit_typecode.h
+--- linux-2.4.1/net/korbit/orb/orbit_typecode.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_typecode.h Thu Feb 1 16:21:53 2001
+@@ -0,0 +1,10 @@
++#ifndef _ORBIT_ORBIT_TYPECODE_H_
++#define _ORBIT_ORBIT_TYPECODE_H_
++
++#include "orbit_types.h"
++
++extern const ORBit_RootObject_Interface ORBit_TypeCode_epv;
++void ORBit_encode_CORBA_TypeCode(CORBA_TypeCode tc, GIOPSendBuffer* buf);
++void ORBit_decode_CORBA_TypeCode(CORBA_TypeCode* tc, GIOPRecvBuffer* buf);
++
++#endif
+diff -urN linux-2.4.1/net/korbit/orb/orbit_types.h linux-2.4.1-korbit/net/korbit/orb/orbit_types.h
+--- linux-2.4.1/net/korbit/orb/orbit_types.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/orbit_types.h Thu Feb 1 16:20:50 2001
+@@ -0,0 +1,176 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_TYPES_H_
++#define _ORBIT_TYPES_H_
++
++#include <stddef.h> /* for wchar_t */
++#include <sys/types.h> /* for sysdep types */
++#include <netinet/in.h> /* for sockaddr_in */
++#include <sys/uio.h> /* for struct iovec */
++
++#include <ORBitutil/basic_types.h>
++
++#define CORBA_TRUE 1
++#define CORBA_FALSE 0
++
++typedef CORBA_char *CORBA_ORBid;
++
++typedef CORBA_unsigned_long CORBA_ServiceOption;
++typedef CORBA_unsigned_long CORBA_ServiceDetailType;
++
++#include "corba_orb.h"
++
++/*
++ * CORBA_RepositoryId and CORBA_Identifier are defined in the Interface
++ * Repository, but are needed in other interfaces in the ORB itself.
++ */
++#if !defined(_CORBA_Identifier_defined)
++#define _CORBA_Identifier_defined 1
++typedef CORBA_char *CORBA_Identifier;
++#define CORBA_Identifier__free CORBA_string__free
++#endif
++
++#if !defined(_CORBA_RepositoryId_defined)
++#define _CORBA_RepositoryId_defined 1
++typedef CORBA_char *CORBA_RepositoryId;
++#define CORBA_RepositoryId__free CORBA_string__free
++#endif
++
++#include "corba_any.h"
++
++typedef struct CORBA_ServiceDetail_type CORBA_ServiceDetail;
++typedef struct CORBA_Request_type *CORBA_Request;
++typedef struct CORBA_ServerRequest_type *CORBA_ServerRequest;
++typedef struct CORBA_DynFixed_type *CORBA_DynFixed;
++typedef struct CORBA_Current_type *CORBA_Current;
++typedef void CORBA_Status;
++typedef CORBA_unsigned_long CORBA_enum;
++typedef CORBA_unsigned_long CORBA_Flags;
++
++typedef struct CORBA_NVList_type {
++ CORBA_Flags flags;
++ GArray *list;
++} CORBA_NVList;
++
++#include "corba_context.h"
++
++#include "corba_portableserver.h"
++
++#include "corba_env.h"
++
++#include "corba_sequences_type.h"
++
++#include "corba_basic_sequences_type.h"
++
++#include "corba_object.h"
++
++#include "orbit_object_type.h"
++
++#include "corba_object_type.h"
++
++#include "corba_orb_type.h"
++
++#include "corba_typecode.h"
++#include "corba_typecode_type.h"
++#include "corba_any_type.h"
++#include "corba_any_proto.h"
++
++#if !defined(TC_IMPL_TC_CORBA_Identifier_0)
++#define TC_IMPL_TC_CORBA_Identifier_0 '/'
++#define TC_CORBA_Identifier ((CORBA_TypeCode)&TC_CORBA_Identifier_struct)
++extern const struct CORBA_TypeCode_struct TC_CORBA_Identifier_struct;
++#endif
++
++#if !defined(TC_IMPL_TC_CORBA_RepositoryId_0)
++#define TC_IMPL_TC_CORBA_RepositoryId_0 '/'
++extern const struct CORBA_TypeCode_struct TC_CORBA_RepositoryId_struct;
++#define TC_CORBA_RepositoryId ((CORBA_TypeCode)&TC_CORBA_RepositoryId_struct)
++#endif
++
++/* 19.14 */
++
++/* XXX */
++typedef struct CORBA_fixed_d_s {
++ CORBA_unsigned_short _digits;
++ CORBA_short _scale;
++ signed char _sign;
++ signed char _value[1];
++} CORBA_fixed_d_s;
++
++#include "corba_env_type.h"
++
++
++typedef struct CORBA_WrongTransaction {
++ int dummy;
++} CORBA_WrongTransaction;
++
++#define CORBA_ARG_IN (1<<0)
++#define CORBA_ARG_OUT (1<<1)
++#define CORBA_ARG_INOUT (1<<2)
++#define CORBA_CTX_RESTRICT_SCOPE (1<<3)
++#define CORBA_CTX_DELETE_DESCENDENTS (1<<4)
++#define CORBA_OUT_LIST_MEMORY (1<<5)
++#define CORBA_IN_COPY_VALUE (1<<6)
++#define CORBA_DEPENDENT_LIST (1<<7)
++#define CORBA_INV_NO_RESPONSE (1<<8)
++#define CORBA_INV_TERM_ON_ERROR (1<<9)
++#define CORBA_RESP_NO_WAIT (1<<10)
++
++typedef struct CORBA_NamedValue {
++ CORBA_Identifier name; /* argument name */
++ CORBA_any argument; /* argument */
++ CORBA_long len; /* length/count of argument value */
++ CORBA_Flags arg_modes; /* argument mode flags */
++} CORBA_NamedValue;
++
++typedef CORBA_char *CORBA_FieldName;
++
++typedef struct CORBA_NameValuePair {
++ CORBA_FieldName id;
++ CORBA_any value;
++} CORBA_NameValuePair;
++
++struct CORBA_Current_type {
++ int fill_me_in;
++};
++
++#include "corba_portableserver_type.h"
++
++typedef CORBA_unsigned_short CORBA_ServiceType;
++
++#define CORBA_Security (1)
++
++struct CORBA_ServiceDetail_type {
++ CORBA_ServiceDetailType service_detail_type;
++ CORBA_sequence_octet service_detail;
++};
++
++typedef struct CORBA_ServiceInformation_struct {
++ CORBA_sequence_ServiceOption service_options;
++ CORBA_sequence_ServiceDetail service_details;
++} CORBA_ServiceInformation;
++
++#endif /* !_ORBIT_TYPES_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/poa.c linux-2.4.1-korbit/net/korbit/orb/poa.c
+--- linux-2.4.1/net/korbit/orb/poa.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/poa.c Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,1387 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter, and Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ * Elliot Lee <sopwith@redhat.com>
++ *
++ */
++
++#include <string.h>
++#include <stdio.h>
++#include <assert.h>
++
++#include "orbit.h"
++#include "orbit_poa.h"
++#include "genrand.h"
++
++PortableServer_ThreadPolicyValue
++PortableServer_ThreadPolicy__get_value(PortableServer_ThreadPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++ ev->_major = CORBA_NO_EXCEPTION;
++
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_LifespanPolicyValue
++PortableServer_LifespanPolicy__get_value(PortableServer_LifespanPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_IdUniquenessPolicyValue
++PortableServer_IdUniquenessPolicy__get_value(PortableServer_IdUniquenessPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_IdAssignmentPolicyValue
++PortableServer_IdAssignmentPolicy__get_value(PortableServer_IdAssignmentPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_ImplicitActivationPolicyValue
++PortableServer_ImplicitActivationPolicy__get_value(PortableServer_ImplicitActivationPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_ServantRetentionPolicyValue
++PortableServer_ServantRetentionPolicy__get_value(PortableServer_ServantRetentionPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++PortableServer_RequestProcessingPolicyValue
++PortableServer_RequestProcessingPolicy__get_value(PortableServer_RequestProcessingPolicy obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ ev->_major = 2 ;
++ goto error_exit;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->value;
++
++error_exit:
++ CORBA_exception_set_system(ev, 0, CORBA_COMPLETED_NO);
++ return 0;
++}
++
++/* make emacs happy; */
++
++PortableServer_POAManager_State
++PortableServer_POAManager_get_state(PortableServer_POAManager obj,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return -1;
++ }
++
++ ev->_major = CORBA_NO_EXCEPTION;
++ return obj->state;
++}
++
++/**** PortableServer_POAManager_activate
++ Inputs: 'obj' - a POAManager to activate
++ Outputs: '*ev' - result of the activate operation
++
++ Side effect: Clears the 'held_requests' lists for all POA's
++ associated with the 'obj' POAManager.
++
++ Description: Sets the POAManager state to 'ACTIVE', then
++ goes through all the POA's associated with this
++ POAManager, and makes them re-process their
++ 'held_requests'
++ */
++void
++PortableServer_POAManager_activate(PortableServer_POAManager obj,
++ CORBA_Environment *ev)
++{
++ GSList *todo;
++ GSList *curitem;
++ PortableServer_POA curpoa;
++
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->state == PortableServer_POAManager_INACTIVE) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POAManager_AdapterInactive,
++ NULL);
++ return;
++ }
++
++ obj->state = PortableServer_POAManager_ACTIVE;
++
++ for(curitem = obj->poa_collection; curitem;
++ curitem = g_slist_next(curitem)) {
++ curpoa = (PortableServer_POA)curitem->data;
++
++ todo = curpoa->held_requests;
++ curpoa->held_requests = NULL;
++
++ g_slist_foreach(todo, (GFunc)ORBit_POA_handle_request,
++ curpoa);
++ g_slist_foreach(todo, (GFunc)giop_recv_buffer_unuse,
++ NULL);
++
++ g_slist_free(todo);
++ }
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++void
++PortableServer_POAManager_hold_requests(PortableServer_POAManager obj,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->state == PortableServer_POAManager_INACTIVE) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POAManager_AdapterInactive,
++ NULL);
++ return;
++ }
++
++ obj->state = PortableServer_POAManager_HOLDING;
++ if(!wait_for_completion)
++ g_warning("hold_requests not finished - don't know how to kill outstanding request fulfillments");
++
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++void
++PortableServer_POAManager_discard_requests(PortableServer_POAManager obj,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->state == PortableServer_POAManager_INACTIVE) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POAManager_AdapterInactive,
++ NULL);
++ return;
++ }
++
++ obj->state = PortableServer_POAManager_DISCARDING;
++ if(!wait_for_completion)
++ g_warning("discard_requests not finished - don't know how to kill outstanding request fulfillments");
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++void
++PortableServer_POAManager_deactivate(PortableServer_POAManager obj,
++ CORBA_boolean etherealize_objects,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->state == PortableServer_POAManager_INACTIVE) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POAManager_AdapterInactive,
++ NULL);
++ return;
++ }
++
++ obj->state = PortableServer_POAManager_INACTIVE;
++
++ if(etherealize_objects)
++ g_slist_foreach(obj->poa_collection, (GFunc)ORBit_POA_etherealize_objects, ev);
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++
++CORBA_boolean
++PortableServer_AdapterActivator_unknown_adapter(PortableServer_AdapterActivator obj,
++ PortableServer_POA parent,
++ CORBA_char *name,
++ CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(CORBA_FALSE);
++}
++
++
++/**** PortableServer_ServantActivator_incarnate
++ */
++PortableServer_Servant
++
++PortableServer_ServantActivator_incarnate
++(PortableServer_ServantActivator obj,
++ PortableServer_ObjectId *oid,
++ PortableServer_POA adapter,
++ CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++void
++PortableServer_ServantActivator_etherealize
++(PortableServer_ServantActivator obj,
++ PortableServer_ObjectId *oid, PortableServer_POA adapter,
++ PortableServer_Servant serv,
++ CORBA_boolean cleanup_in_progress,
++ CORBA_boolean remaining_activations,
++ CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return;
++}
++
++PortableServer_POA
++PortableServer_POA_create_POA
++ (PortableServer_POA poa,
++ CORBA_char *adapter_name,
++ PortableServer_POAManager a_POAManager,
++ CORBA_PolicyList* policies,
++ CORBA_Environment *ev)
++{
++ PortableServer_POA new_poa = NULL;
++ PortableServer_POA check_poa = NULL;
++
++ /* Check for a child POA by the same name in parent */
++ check_poa = PortableServer_POA_find_POA(poa,adapter_name,
++ FALSE, ev);
++ CORBA_exception_free (ev);
++
++ if (!check_poa) {
++ new_poa = ORBit_POA_new(poa->orb,
++ adapter_name, a_POAManager, policies, ev);
++ } else {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_AdapterAlreadyExists,
++ NULL);
++ new_poa = NULL;
++ }
++
++ if(ev->_major == CORBA_NO_EXCEPTION) {
++ new_poa->parent_poa = poa;
++ ORBit_POA_add_child(poa, new_poa, ev);
++ }
++
++ return new_poa;
++}
++
++/**** PortableServer_POA_find_POA
++ Inputs: 'obj' - a POA
++ 'activate_it' - whether to activate unknown POA's
++
++ Outputs: 'child_poa'
++
++ Description: Finds (and optionally activates) a child POA of 'obj'
++ with the specified names.
++
++ TODO: Activate non-existent adapters if asked.
++
++ */
++PortableServer_POA
++PortableServer_POA_find_POA(PortableServer_POA obj,
++ CORBA_char *adapter_name,
++ CORBA_boolean activate_it,
++ CORBA_Environment *ev)
++{
++ GSList *curitem;
++ PortableServer_POA child_poa;
++
++ for(curitem = obj->child_POAs; curitem;
++ curitem = g_slist_next(curitem)) {
++ child_poa = (PortableServer_POA)curitem->data;
++ if(!strcmp(child_poa->the_name, adapter_name)) {
++ ev->_major = CORBA_NO_EXCEPTION;
++ return child_poa;
++ }
++ }
++
++ if(activate_it)
++ g_warning("Don't yet know how to activate POA named \"%s\"",
++ adapter_name);
++
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_AdapterNonExistent,
++ NULL);
++
++ return NULL;
++}
++
++/**** PortableServer_POA_destroy
++ Inputs: 'obj' - the POA to be destroyed
++ 'etherealize_objects' - flag indicating whether any servant
++ manager should be asked to etherealize
++ objects in the active object map
++ 'wait_for_completion' - flag indicating whether to wait for
++ requests currently being handled
++ */
++void
++PortableServer_POA_destroy(PortableServer_POA obj,
++ CORBA_boolean etherealize_objects,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev)
++{
++ if(etherealize_objects || !wait_for_completion)
++ g_warning("PortableServer_POA_destroy not yet fully implemented; ignoring flags");
++
++ if(ORBIT_ROOT_OBJECT(obj)->refs > 1)
++ g_warning("POA has multiple refs [%d]",
++ ORBIT_ROOT_OBJECT(obj)->refs);
++
++ CORBA_Object_release((CORBA_Object)obj, ev);
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++PortableServer_ThreadPolicy PortableServer_POA_create_thread_policy(PortableServer_POA obj, PortableServer_ThreadPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_ThreadPolicy retval;
++
++ retval = g_new(struct PortableServer_ThreadPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_THREAD_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_ThreadPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_LifespanPolicy PortableServer_POA_create_lifespan_policy(PortableServer_POA obj, PortableServer_LifespanPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_LifespanPolicy retval;
++
++ retval = g_new(struct PortableServer_LifespanPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_LIFESPAN_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_LifespanPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_IdUniquenessPolicy PortableServer_POA_create_id_uniqueness_policy(PortableServer_POA obj, PortableServer_IdUniquenessPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_IdUniquenessPolicy retval;
++
++ retval = g_new(struct PortableServer_IdUniquenessPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_ID_UNIQUENESS_POLICY_ID,
++ ev);
++
++ retval->value = value;
++
++ return (PortableServer_IdUniquenessPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_IdAssignmentPolicy PortableServer_POA_create_id_assignment_policy(PortableServer_POA obj, PortableServer_IdAssignmentPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_IdAssignmentPolicy retval;
++
++ retval = g_new(struct PortableServer_IdAssignmentPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_ID_ASSIGNMENT_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_IdAssignmentPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_ImplicitActivationPolicy PortableServer_POA_create_implicit_activation_policy(PortableServer_POA obj, PortableServer_ImplicitActivationPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_ImplicitActivationPolicy retval;
++
++ retval = g_new(struct PortableServer_ImplicitActivationPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_IMPLICIT_ACTIVATION_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_ImplicitActivationPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_ServantRetentionPolicy PortableServer_POA_create_servant_retention_policy(PortableServer_POA obj, PortableServer_ServantRetentionPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_ServantRetentionPolicy retval;
++
++ retval = g_new(struct PortableServer_ServantRetentionPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_SERVANT_RETENTION_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_ServantRetentionPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++PortableServer_RequestProcessingPolicy PortableServer_POA_create_request_processing_policy(PortableServer_POA obj, PortableServer_RequestProcessingPolicyValue value, CORBA_Environment *ev)
++{
++ PortableServer_RequestProcessingPolicy retval;
++
++ retval = g_new(struct PortableServer_RequestProcessingPolicy_type, 1);
++ ORBit_policy_object_init((CORBA_Policy)retval,
++ PortableServer_REQUEST_PROCESSING_POLICY_ID, ev);
++
++ retval->value = value;
++
++ return (PortableServer_RequestProcessingPolicy)CORBA_Object_duplicate((CORBA_Object)retval, ev);
++}
++
++CORBA_char *PortableServer_POA__get_the_name(PortableServer_POA obj, CORBA_Environment *ev)
++{
++ g_assert(obj);
++ g_assert(obj->the_name);
++ return obj->the_name;
++}
++
++PortableServer_POA
++PortableServer_POA__get_the_parent(PortableServer_POA obj,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ return obj->parent_poa;
++}
++
++PortableServer_POAManager
++PortableServer_POA__get_the_POAManager(PortableServer_POA obj,
++ CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ return obj->the_POAManager;
++}
++
++PortableServer_AdapterActivator PortableServer_POA__get_the_activator(PortableServer_POA obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ return obj->the_activator;
++}
++
++void PortableServer_POA__set_the_activator(PortableServer_POA obj, PortableServer_AdapterActivator the_activator, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev,
++ ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ obj->the_activator = the_activator;
++}
++
++PortableServer_ServantManager PortableServer_POA_get_servant_manager(PortableServer_POA obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ if(obj->request_processing != PortableServer_USE_SERVANT_MANAGER) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ return obj->servant_manager;
++}
++
++void PortableServer_POA_set_servant_manager(PortableServer_POA obj, PortableServer_ServantManager imgr, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->request_processing != PortableServer_USE_SERVANT_MANAGER) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return;
++ }
++
++ obj->servant_manager = imgr;
++}
++
++PortableServer_Servant PortableServer_POA_get_servant(PortableServer_POA obj, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ if(obj->request_processing != PortableServer_USE_DEFAULT_SERVANT) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ return obj->default_servant;
++}
++
++void PortableServer_POA_set_servant(PortableServer_POA obj, PortableServer_Servant p_servant, CORBA_Environment *ev)
++{
++ if(!obj) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ if(obj->request_processing != PortableServer_USE_DEFAULT_SERVANT) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return;
++ }
++
++ obj->default_servant = p_servant;
++}
++
++static CORBA_unsigned_long
++get_objnum_for_obj(PortableServer_POA poa, ORBit_POAObject *obj)
++{
++ CORBA_unsigned_long retval;
++
++ if(poa->first_free_id) {
++ retval = poa->first_free_id;
++ poa->first_free_id = GPOINTER_TO_UINT(g_ptr_array_index(poa->objnum_to_obj,
++ retval));
++ g_ptr_array_index(poa->objnum_to_obj, retval) = obj;
++ } else {
++ retval = poa->objnum_to_obj->len;
++ g_ptr_array_add(poa->objnum_to_obj,
++ obj);
++ }
++
++ return retval;
++}
++
++static CORBA_ORB
++get_orb_for_poa(PortableServer_POA poa)
++{
++ if(poa->orb)
++ return poa->orb;
++ if(poa->parent_poa)
++ return get_orb_for_poa(poa->parent_poa);
++
++ return CORBA_OBJECT_NIL;
++}
++
++PortableServer_ObjectId *
++PortableServer_POA_activate_object(PortableServer_POA obj,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev)
++{
++ PortableServer_ServantBase *servant;
++ PortableServer_ObjectId *new_objid;
++ ORBit_POAObject *new_obj;
++
++ servant = p_servant;
++
++ if(obj->servant_retention != PortableServer_RETAIN
++ || obj->id_assignment != PortableServer_SYSTEM_ID) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ /* Servant Already Active */
++ if((obj->id_uniqueness==PortableServer_UNIQUE_ID) &&
++ (ORBIT_OBJECT_KEY(servant->_private)->object != 0)) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_ServantAlreadyActive,
++ NULL);
++ return NULL;
++ }
++
++
++ new_obj = g_new0(ORBit_POAObject, 1);
++ new_obj->object_id = (PortableServer_ObjectId*)CORBA_sequence_octet__alloc();
++
++ new_objid =
++ ORBit_POA_allocate_oid(obj,
++ ORBIT_OBJECT_KEY(servant->_private)->class_info->class_name);
++
++ new_obj->object_id->_buffer = CORBA_octet_allocbuf(new_objid->_length);
++ new_obj->object_id->_length = new_objid->_length;
++ memcpy(new_obj->object_id->_buffer, new_objid->_buffer,
++ new_objid->_length);
++ CORBA_sequence_set_release(new_obj->object_id, CORBA_TRUE);
++
++ new_obj->servant = p_servant;
++ ORBIT_OBJECT_KEY(servant->_private)->object = new_obj;
++ new_obj->orb = get_orb_for_poa(obj);
++ new_obj->poa = obj;
++ new_obj->objnum = get_objnum_for_obj(obj, new_obj);
++ orbit_genrand(new_obj->rand_data, ORBIT_RAND_KEY_LEN);
++
++ g_hash_table_insert(obj->active_object_map,
++ new_obj->object_id,
++ new_obj);
++
++ ev->_major = CORBA_NO_EXCEPTION;
++
++ return new_objid;
++}
++
++void
++PortableServer_POA_activate_object_with_id(PortableServer_POA obj,
++ PortableServer_ObjectId *id,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev)
++{
++ PortableServer_ServantBase *servant = p_servant;
++ ORBit_POAObject *newobj;
++
++ if(!obj || !id || !p_servant) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ newobj = g_hash_table_lookup(obj->active_object_map,
++ id);
++
++ if(newobj) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_ObjectAlreadyActive, NULL);
++ return;
++ }
++
++ newobj = g_new0(ORBit_POAObject, 1);
++ newobj->object_id = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++ newobj->object_id->_length = id->_length;
++ newobj->object_id->_buffer = CORBA_octet_allocbuf(id->_length);
++ newobj->object_id->_release = CORBA_TRUE;
++ memcpy(newobj->object_id->_buffer, id->_buffer, id->_length);
++ newobj->poa = obj;
++ newobj->orb = get_orb_for_poa(obj);
++ newobj->objnum = get_objnum_for_obj(obj, newobj);
++ orbit_genrand(newobj->rand_data, ORBIT_RAND_KEY_LEN);
++
++ newobj->servant = p_servant;
++
++ g_hash_table_insert(obj->active_object_map,
++ newobj->object_id,
++ newobj);
++
++ ORBIT_OBJECT_KEY(servant->_private)->object = newobj;
++
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++void
++PortableServer_POA_deactivate_object(PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_Environment *ev)
++{
++ ORBit_POAObject *oldobj;
++
++ if(!obj || !oid) {
++ CORBA_exception_set_system(ev, ex_CORBA_BAD_PARAM,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ oldobj = g_hash_table_lookup(obj->active_object_map,
++ oid);
++
++ if(!oldobj) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_ObjectNotActive,
++ NULL);
++ return;
++ }
++
++ g_ptr_array_index(obj->objnum_to_obj, oldobj->objnum) = GUINT_TO_POINTER(obj->first_free_id);
++ obj->first_free_id = oldobj->objnum;
++
++ g_hash_table_remove(obj->active_object_map, oid);
++
++ if(obj->request_processing == PortableServer_USE_SERVANT_MANAGER) {
++ POA_PortableServer_ServantActivator__epv *epv;
++ POA_PortableServer_ServantActivator *sm;
++
++ sm = (POA_PortableServer_ServantActivator *)obj->servant_manager;
++ epv = sm->vepv->PortableServer_ServantActivator_epv;
++ epv->etherealize(sm, oldobj->object_id, obj,
++ oldobj->servant,
++ CORBA_FALSE,
++ CORBA_FALSE,
++ ev);
++ }
++
++ CORBA_free(oldobj->object_id);
++
++ g_free(oldobj);
++ ev->_major = CORBA_NO_EXCEPTION;
++}
++
++CORBA_Object
++PortableServer_POA_create_reference(PortableServer_POA obj,
++ CORBA_RepositoryId intf,
++ CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++PortableServer_ObjectId *PortableServer_POA_servant_to_id(PortableServer_POA obj, PortableServer_Servant p_servant, CORBA_Environment *ev)
++{
++ PortableServer_ObjectId *retval, *orig;
++ PortableServer_ServantBase *serv = p_servant;
++ g_return_val_if_fail(p_servant != NULL, NULL);
++
++ orig = ORBIT_OBJECT_KEY(serv->_private)->object->object_id;
++ retval = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++ retval->_length = retval->_maximum = orig->_length;
++ retval->_buffer = CORBA_octet_allocbuf(retval->_length);
++ memcpy(retval->_buffer, orig->_buffer, retval->_length);
++ CORBA_sequence_set_release(retval, CORBA_TRUE);
++
++ return retval;
++}
++
++CORBA_Object
++PortableServer_POA_servant_to_reference(PortableServer_POA obj, PortableServer_Servant p_servant, CORBA_Environment *ev)
++{
++ CORBA_Object retval;
++ PortableServer_ObjectId *orig_id;
++ PortableServer_ServantBase *servant = p_servant;
++ ORBit_ObjectKey *obj_key = ORBIT_OBJECT_KEY(servant->_private);
++
++ int implicit = (obj->implicit_activation == PortableServer_IMPLICIT_ACTIVATION);
++ int activate_able = (obj_key->object == 0) ||
++ (obj->id_uniqueness==PortableServer_MULTIPLE_ID);
++ /* ImplicitActivationPolicy */
++ if( implicit && activate_able) {
++ orig_id = PortableServer_POA_activate_object(obj, p_servant, ev);
++ } else {
++ orig_id = obj_key->object->object_id;
++ }
++ retval = PortableServer_POA_id_to_reference(obj,orig_id,ev);
++
++ return retval;
++}
++
++PortableServer_Servant
++PortableServer_POA_reference_to_servant(PortableServer_POA obj, CORBA_Object reference, CORBA_Environment *ev)
++{
++ GSList *cur;
++
++ g_assert(reference);
++
++ if(obj->request_processing != PortableServer_USE_DEFAULT_SERVANT
++ && obj->servant_retention != PortableServer_RETAIN) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ if(reference->servant)
++ return reference->servant;
++
++ for(cur = reference->profile_list; cur; cur = cur->next) {
++ PortableServer_ObjectId *oid;
++ ORBit_Object_info *curprof = cur->data;
++ ORBit_POAObject *objinfo;
++
++ objinfo = ORBit_POA_find_oid_for_object_key(obj, &(curprof->object_key), &oid);
++ CORBA_free(oid);
++ if(objinfo)
++ return objinfo->servant;
++ }
++
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_ObjectNotActive,
++ NULL);
++ return NULL;
++}
++
++PortableServer_ObjectId *PortableServer_POA_reference_to_id(PortableServer_POA obj, CORBA_Object reference, CORBA_Environment *ev)
++{
++ PortableServer_ObjectId *retval;
++ ORBit_POAObject *objinfo;
++
++ g_assert(reference);
++ g_assert(reference->active_profile);
++
++ if(obj->request_processing != PortableServer_USE_DEFAULT_SERVANT
++ && obj->servant_retention != PortableServer_RETAIN) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ objinfo = ORBit_POA_find_oid_for_object_key(obj, &(reference->active_profile->object_key), &retval);
++ if(objinfo) {
++ CORBA_free(retval);
++ retval = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++ retval->_length = retval->_maximum = objinfo->object_id->_length;
++ retval->_buffer = CORBA_octet_allocbuf(retval->_length);
++ memcpy(retval->_buffer, objinfo->object_id->_buffer, retval->_length);
++ CORBA_sequence_set_release(retval, CORBA_TRUE);
++ return retval;
++ } else if(retval)
++ return retval;
++
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_ObjectNotActive,
++ NULL);
++ return NULL;
++}
++
++PortableServer_Servant PortableServer_POA_id_to_servant(PortableServer_POA obj, PortableServer_ObjectId *oid, CORBA_Environment *ev)
++{
++ ORBit_POAObject *objinfo;
++
++ if(obj->servant_retention != PortableServer_RETAIN) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ objinfo = g_hash_table_lookup(obj->active_object_map,
++ oid);
++
++ if(!objinfo) {
++ CORBA_exception_set(ev, CORBA_USER_EXCEPTION,
++ ex_PortableServer_POA_WrongPolicy,
++ NULL);
++ return NULL;
++ }
++
++ return objinfo->servant;
++}
++
++static CORBA_Object
++my_PortableServer_POA_id_to_reference(PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ const char *type_id,
++ CORBA_Environment *ev)
++{
++ GSList *profiles=NULL;
++ ORBit_Object_info *object_info;
++ CORBA_Object retval;
++ CORBA_ORB orb;
++ ORBit_POAObject *pobj;
++ ORBit_ObjectKey *objkey = NULL;
++
++ orb = obj->the_POAManager->orb;
++
++ g_assert(!oid->_buffer[oid->_length - 1]);
++
++ pobj = g_hash_table_lookup(obj->active_object_map, oid);
++
++ if(pobj) {
++ objkey = ORBIT_OBJECT_KEY(((PortableServer_ServantBase *)pobj->servant)->_private);
++ type_id= objkey->class_info->class_name;
++ }
++
++ /* Do the local connection first, so it will be attempted first by
++ the client parsing the IOR string
++ */
++ if(orb->cnx.ipv6 || orb->cnx.usock) {
++ object_info = g_new0(ORBit_Object_info, 1);
++
++ object_info->profile_type=IOP_TAG_ORBIT_SPECIFIC;
++ object_info->iiop_major = 1;
++ object_info->iiop_minor = 0;
++
++ ORBit_POA_find_object_key_for_oid(obj, pobj, oid, &object_info->object_key);
++
++#ifdef HAVE_IPV6
++ if(orb->cnx.ipv6) {
++ object_info->tag.orbitinfo.ipv6_port =
++ ntohs(IIOP_CONNECTION(orb->cnx.ipv6)->u.ipv6.location.sin_port);
++ }
++#endif
++ if(orb->cnx.usock) {
++ object_info->tag.orbitinfo.unix_sock_path =
++ g_strdup(IIOP_CONNECTION(orb->cnx.usock)->u.usock.sun_path);
++ }
++ ORBit_set_object_key(object_info);
++ profiles=g_slist_append(profiles, object_info);
++ }
++
++ if(orb->cnx.ipv4) {
++ object_info=g_new0(ORBit_Object_info, 1);
++
++ object_info->profile_type = IOP_TAG_INTERNET_IOP;
++ object_info->iiop_major = 1;
++ object_info->iiop_minor = 0;
++ ORBit_POA_find_object_key_for_oid(obj, pobj, oid, &object_info->object_key);
++
++ object_info->tag.iopinfo.host = g_strdup(IIOP_CONNECTION(orb->cnx.ipv4)->u.ipv4.hostname);
++ object_info->tag.iopinfo.port = ntohs(IIOP_CONNECTION(orb->cnx.ipv4)->u.ipv4.location.sin_port);
++
++ ORBit_set_object_key(object_info);
++ profiles=g_slist_append(profiles, object_info);
++ }
++
++ retval = ORBit_create_object_with_info(profiles, type_id, orb, ev);
++
++ if(retval != CORBA_OBJECT_NIL
++ && ev->_major == CORBA_NO_EXCEPTION
++ && objkey && objkey->class_info && objkey->class_info->init_local_objref) {
++ /* XXX potential memleak if we get an already-valid objref */
++ retval->vepv = g_new0(gpointer, ORBit_class_assignment_counter + 1);
++ retval->vepv_size = ORBit_class_assignment_counter + 1;
++ objkey->class_info->init_local_objref(retval, pobj->servant);
++ retval->servant = pobj->servant;
++ } else
++ retval->vepv = retval->servant = NULL;
++
++ return retval;
++}
++
++CORBA_Object PortableServer_POA_id_to_reference(PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_Environment *ev)
++{
++ return my_PortableServer_POA_id_to_reference(obj, oid, NULL, ev);
++}
++
++CORBA_Object
++PortableServer_POA_create_reference_with_id(PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_RepositoryId intf,
++ CORBA_Environment *ev)
++{
++ return my_PortableServer_POA_id_to_reference(obj, oid, intf, ev);
++}
++
++PortableServer_POA PortableServer_Current_get_POA(PortableServer_Current obj, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++PortableServer_ObjectId *PortableServer_Current_get_object_id(PortableServer_Current obj, CORBA_Environment *ev)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++
++CORBA_char *PortableServer_ObjectId_to_string(PortableServer_ObjectId *id, CORBA_Environment *env)
++{
++ return CORBA_string_dup((CORBA_char *)id->_buffer);
++}
++
++CORBA_wchar *PortableServer_ObjectId_to_wstring(PortableServer_ObjectId *id, CORBA_Environment *env)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++PortableServer_ObjectId *PortableServer_string_to_ObjectId(CORBA_char *str, CORBA_Environment *env)
++{
++ PortableServer_ObjectId *retval;
++
++ retval = (PortableServer_ObjectId *)CORBA_sequence_octet__alloc();
++
++ retval->_length = strlen(str) + 1;
++ retval->_buffer = CORBA_octet_allocbuf(retval->_length);
++
++ memcpy(retval->_buffer, str, retval->_length);
++
++ return retval;
++}
++
++PortableServer_ObjectId *PortableServer_wstring_to_ObjectId(CORBA_wchar *str, CORBA_Environment *env)
++{
++ g_assert(!"Not yet implemented");
++ return(NULL);
++}
++
++
++PortableServer_POA PortableServer_ServantBase__default_POA(PortableServer_Servant servant, CORBA_Environment *ev)
++{
++ g_return_val_if_fail(servant, NULL);
++
++ return ORBIT_OBJECT_KEY(((PortableServer_ServantBase *)servant)->_private)->object->poa;
++}
++
++void PortableServer_ServantLocator_preinvoke(PortableServer_ObjectId *oid, PortableServer_POA adapter, CORBA_Identifier op_name, PortableServer_ServantLocator_Cookie *cookie)
++{
++ g_assert(!"Not yet implemented");
++ return;
++}
++
++void PortableServer_ServantLocator_postinvoke(PortableServer_ObjectId *oid, PortableServer_POA adapter, CORBA_Identifier op_name, PortableServer_ServantLocator_Cookie cookie, PortableServer_Servant servant)
++{
++ g_assert(!"Not yet implemented");
++ return;
++}
++
++void PortableServer_ServantBase__init(PortableServer_Servant servant,
++ CORBA_Environment *ev)
++{
++ PortableServer_ServantBase *serv = servant;
++
++ if(!serv->_private) /* If not already initialized, create the place to
++ stick our info */
++ serv->_private = g_new0(ORBit_ObjectKey, 1);
++}
++
++void PortableServer_ServantBase__fini(PortableServer_Servant servant,
++ CORBA_Environment *ev)
++{
++ PortableServer_ServantBase *serv = servant;
++
++ g_free(serv->_private);
++ serv->_private = NULL;
++}
++
++
++/************************ ServerRequest stuff ********************/
++
++CORBA_Identifier CORBA_ServerRequest_operation(CORBA_ServerRequest req, CORBA_Environment *env)
++{
++ return CORBA_string_dup(req->rbuf->message.u.request.operation);
++}
++
++CORBA_Context
++CORBA_ServerRequest_ctx(CORBA_ServerRequest req, CORBA_Environment *env)
++{
++ if(!req->params || req->did_ctx) {
++ CORBA_exception_set_system(env, ex_CORBA_BAD_INV_ORDER,
++ CORBA_COMPLETED_NO);
++ return NULL;
++ }
++
++ return NULL;
++}
++
++void
++CORBA_ServerRequest_arguments(CORBA_ServerRequest req,
++ CORBA_NVList *parameters,
++ CORBA_Environment *env)
++{
++ int i;
++
++ if(req->params) {
++ CORBA_exception_set_system(env, ex_CORBA_BAD_INV_ORDER,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ req->params = parameters;
++
++ for(i = 0; i < parameters->list->len; i++) {
++ CORBA_NamedValue *cur;
++
++ cur = &g_array_index(parameters->list, CORBA_NamedValue, i);
++
++ if(cur->arg_modes & CORBA_ARG_OUT) continue;
++ cur->argument._value = ORBit_demarshal_arg(req->rbuf,
++ cur->argument._type,
++ TRUE,
++ (CORBA_ORB)req->orb);
++ CORBA_any_set_release(&cur->argument, TRUE);
++ }
++}
++
++void
++CORBA_ServerRequest_set_result(CORBA_ServerRequest req,
++ CORBA_any *value,
++ CORBA_Environment *env)
++{
++ if(req->sbuf) {
++ CORBA_exception_set_system(env, ex_CORBA_BAD_INV_ORDER,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ req->sbuf = giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(req->rbuf)->connection,
++ NULL,
++ req->rbuf->message.u.request.request_id,
++ CORBA_NO_EXCEPTION);
++ if(!req->sbuf) {
++ CORBA_exception_set_system(env, ex_CORBA_COMM_FAILURE,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ ORBit_marshal_arg(req->sbuf, value->_value, value->_type);
++}
++
++void
++CORBA_ServerRequest_set_exception(CORBA_ServerRequest req,
++ CORBA_exception_type major,
++ CORBA_any *value,
++ CORBA_Environment *env)
++{
++ if(req->sbuf) {
++ CORBA_exception_set_system(env, ex_CORBA_BAD_INV_ORDER,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ req->sbuf = giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(req->rbuf)->connection,
++ NULL,
++ req->rbuf->message.u.request.request_id,
++ major);
++ if(!req->sbuf) {
++ CORBA_exception_set_system(env, ex_CORBA_COMM_FAILURE,
++ CORBA_COMPLETED_NO);
++ return;
++ }
++
++ req->did_exc = TRUE;
++
++ /* XXX do we really need to copy the repo_id into the
++ send buffer? Or is there a way to assume that the CORBA_TypeCode
++ value->_type will be around until after we send the message? */
++ {
++ CORBA_unsigned_long slen;
++ slen = strlen(value->_type->repo_id) + 1;
++ giop_send_buffer_append_mem_indirect_a(req->sbuf, &slen,
++ sizeof(slen));
++ giop_send_buffer_append_mem_indirect(req->sbuf,
++ value->_type->repo_id,
++ slen);
++ }
++
++ ORBit_marshal_arg(req->sbuf, value->_value, value->_type);
++}
++
++void
++POA_PortableServer_ServantActivator__init(PortableServer_Servant servant,
++ CORBA_Environment * ev)
++{
++ static const PortableServer_ClassInfo class_info =
++ {NULL,
++ "IDL:omg.org/PortableServer/ServantActivator:1.0",
++ NULL};
++
++ PortableServer_ServantBase__init(((PortableServer_ServantBase *) servant), ev);
++
++ ORBIT_OBJECT_KEY(((PortableServer_ServantBase *)servant)->_private)->class_info = (gpointer)&class_info;
++}
++
++void
++POA_PortableServer_ServantActivator__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ServantBase__fini(servant, ev);
++}
++
++void
++POA_PortableServer_ServantLocator__init(PortableServer_Servant servant,
++ CORBA_Environment * ev)
++{
++ static const PortableServer_ClassInfo class_info =
++ {NULL,
++ "IDL:omg.org/PortableServer/ServantLocator:1.0",
++ NULL};
++
++ PortableServer_ServantBase__init(((PortableServer_ServantBase *)servant), ev);
++
++ ORBIT_OBJECT_KEY(((PortableServer_ServantBase *)servant)->_private)->class_info = (gpointer)&class_info;
++}
++
++void
++POA_PortableServer_ServantLocator__fini(PortableServer_Servant servant,
++ CORBA_Environment * ev)
++{
++ PortableServer_ServantBase__fini(servant, ev);
++}
++
++/* POA-related DSI stuff */
++static void
++dynamic_impl_skel(PortableServer_DynamicImpl *_ORBIT_servant,
++ GIOPRecvBuffer *_ORBIT_recv_buffer,
++ CORBA_Environment *ev,
++ PortableServer_DynamicImplRoutine invoke)
++{
++ /* here the magic occurs... */
++ struct CORBA_ServerRequest_type sr;
++
++ ORBit_pseudo_object_init(ORBIT_PSEUDO_OBJECT(&sr),
++ ORBIT_PSEUDO_SERVERREQUEST, ev);
++
++ CORBA_Object_duplicate((CORBA_Object)&sr, ev); /* just to make
++ sure it doesn't die
++ elsewhere */
++
++ sr.rbuf = _ORBIT_recv_buffer;
++ sr.orb = GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->connection->orb_data;
++
++ _ORBIT_servant->vepv->PortableServer_DynamicImpl_epv->invoke(_ORBIT_servant,
++ &sr);
++
++ if(sr.sbuf) {
++ int i;
++ for(i = 0; i < sr.params->list->len; i++) {
++ CORBA_NamedValue *cur;
++
++ cur = &g_array_index(sr.params->list, CORBA_NamedValue, i);
++
++ if(cur->arg_modes & CORBA_ARG_IN) continue;
++
++ ORBit_marshal_arg(sr.sbuf, cur->argument._value,
++ cur->argument._type);
++ }
++
++ giop_send_buffer_write(sr.sbuf);
++ giop_send_buffer_unuse(sr.sbuf);
++ } else
++ g_warning("Yo, your DSI code is messed up! You forgot to set_result|set_exception");
++
++ CORBA_NVList_free(sr.params, ev);
++}
++
++static ORBitSkeleton
++dynamic_impl_get_skel(PortableServer_DynamicImpl * servant,
++ GIOPRecvBuffer * _ORBIT_recv_buffer,
++ gpointer * impl)
++{
++ *impl = (gpointer)servant->vepv->PortableServer_DynamicImpl_epv->invoke;
++
++ return (ORBitSkeleton)dynamic_impl_skel;
++}
++
++void
++PortableServer_DynamicImpl__init(PortableServer_Servant servant,
++ CORBA_Environment *ev)
++{
++ static const PortableServer_ClassInfo class_info =
++ {(ORBitSkeleton (*)(PortableServer_ServantBase *, gpointer, gpointer *))
++ &dynamic_impl_get_skel, "IDL:CORBA/Object:1.0", NULL};
++
++ PortableServer_ServantBase__init(servant, ev);
++
++ ORBIT_OBJECT_KEY(((PortableServer_ServantBase *)servant)->_private)->class_info =
++ (PortableServer_ClassInfo *) & class_info;
++
++}
++
++void PortableServer_DynamicImpl__fini(PortableServer_Servant servant,
++ CORBA_Environment *ev)
++{
++ PortableServer_ServantBase__fini(servant, ev);
++}
++
+diff -urN linux-2.4.1/net/korbit/orb/poa.h linux-2.4.1-korbit/net/korbit/orb/poa.h
+--- linux-2.4.1/net/korbit/orb/poa.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/poa.h Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,337 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_POA_H_
++#define _ORBIT_POA_H_
++
++#include "orbit_types.h"
++
++extern PortableServer_ThreadPolicyValue PortableServer_ThreadPolicy__get_value(
++ PortableServer_ThreadPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_LifespanPolicyValue PortableServer_LifespanPolicy__get_value(
++ PortableServer_LifespanPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_IdUniquenessPolicyValue PortableServer_IdUniquenessPolicy__get_value(
++ PortableServer_IdUniquenessPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_IdAssignmentPolicyValue PortableServer_IdAssignmentPolicy__get_value(
++ PortableServer_IdAssignmentPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_ImplicitActivationPolicyValue PortableServer_ImplicitActivationPolicy__get_value(
++ PortableServer_ImplicitActivationPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_ServantRetentionPolicyValue PortableServer_ServantRetentionPolicy__get_value(
++ PortableServer_ServantRetentionPolicy obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_RequestProcessingPolicyValue PortableServer_RequestProcessingPolicy__get_value(
++ PortableServer_RequestProcessingPolicy obj,
++ CORBA_Environment *ev);
++
++PortableServer_POAManager_State
++PortableServer_POAManager_get_state(PortableServer_POAManager obj,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POAManager_activate(
++ PortableServer_POAManager obj,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POAManager_hold_requests(
++ PortableServer_POAManager obj,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POAManager_discard_requests(
++ PortableServer_POAManager obj,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POAManager_deactivate(
++ PortableServer_POAManager obj,
++ CORBA_boolean etherealize_objects,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev);
++
++extern CORBA_boolean PortableServer_AdapterActivator_unknown_adapter(
++ PortableServer_AdapterActivator obj,
++ PortableServer_POA parent,
++ CORBA_char *name,
++ CORBA_Environment *ev);
++
++extern PortableServer_Servant PortableServer_ServantActivator_incarnate(
++ PortableServer_ServantActivator obj,
++ PortableServer_ObjectId *oid,
++ PortableServer_POA adapter,
++ CORBA_Environment *ev);
++
++extern void PortableServer_ServantActivator_etherealize(
++ PortableServer_ServantActivator obj,
++ PortableServer_ObjectId *oid,
++ PortableServer_POA adapter,
++ PortableServer_Servant serv,
++ CORBA_boolean cleanup_in_progress,
++ CORBA_boolean remaining_activations,
++ CORBA_Environment *ev);
++
++extern PortableServer_POA PortableServer_POA_create_POA(
++ PortableServer_POA obj,
++ CORBA_char *adapter_name,
++ PortableServer_POAManager a_POAManager,
++ CORBA_PolicyList *policies,
++ CORBA_Environment *ev);
++
++extern PortableServer_POA PortableServer_POA_find_POA(
++ PortableServer_POA obj,
++ CORBA_char *adapter_name,
++ CORBA_boolean activate_it,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA_destroy(
++ PortableServer_POA obj,
++ CORBA_boolean etherealize_objects,
++ CORBA_boolean wait_for_completion,
++ CORBA_Environment *ev);
++
++extern PortableServer_ThreadPolicy PortableServer_POA_create_thread_policy(
++ PortableServer_POA obj,
++ PortableServer_ThreadPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_LifespanPolicy PortableServer_POA_create_lifespan_policy(
++ PortableServer_POA obj,
++ PortableServer_LifespanPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_IdUniquenessPolicy PortableServer_POA_create_id_uniqueness_policy(
++ PortableServer_POA obj,
++ PortableServer_IdUniquenessPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_IdAssignmentPolicy PortableServer_POA_create_id_assignment_policy(
++ PortableServer_POA obj,
++ PortableServer_IdAssignmentPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_ImplicitActivationPolicy PortableServer_POA_create_implicit_activation_policy(
++ PortableServer_POA obj,
++ PortableServer_ImplicitActivationPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_ServantRetentionPolicy PortableServer_POA_create_servant_retention_policy(
++ PortableServer_POA obj,
++ PortableServer_ServantRetentionPolicyValue value,
++ CORBA_Environment *ev);
++
++extern PortableServer_RequestProcessingPolicy PortableServer_POA_create_request_processing_policy(
++ PortableServer_POA obj,
++ PortableServer_RequestProcessingPolicyValue value,
++ CORBA_Environment *ev);
++
++extern CORBA_char *PortableServer_POA__get_the_name(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_POA PortableServer_POA__get_the_parent(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_POAManager PortableServer_POA__get_the_POAManager(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_AdapterActivator PortableServer_POA__get_the_activator(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA__set_the_activator(
++ PortableServer_POA obj,
++ PortableServer_AdapterActivator the_activator,
++ CORBA_Environment *ev);
++
++extern PortableServer_ServantManager PortableServer_POA_get_servant_manager(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA_set_servant_manager(
++ PortableServer_POA obj,
++ PortableServer_ServantManager imgr,
++ CORBA_Environment *ev);
++
++extern PortableServer_Servant PortableServer_POA_get_servant(
++ PortableServer_POA obj,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA_set_servant(
++ PortableServer_POA obj,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev);
++
++extern PortableServer_ObjectId *PortableServer_POA_activate_object(
++ PortableServer_POA obj,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA_activate_object_with_id(
++ PortableServer_POA obj,
++ PortableServer_ObjectId *id,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev);
++
++extern void PortableServer_POA_deactivate_object(
++ PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_Environment *ev);
++
++extern CORBA_Object PortableServer_POA_create_reference(
++ PortableServer_POA obj,
++ CORBA_RepositoryId intf,
++ CORBA_Environment *ev);
++
++extern CORBA_Object PortableServer_POA_create_reference_with_id(
++ PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_RepositoryId intf,
++ CORBA_Environment *ev);
++
++extern PortableServer_ObjectId *PortableServer_POA_servant_to_id(
++ PortableServer_POA obj,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev);
++
++extern CORBA_Object PortableServer_POA_servant_to_reference(
++ PortableServer_POA obj,
++ PortableServer_Servant p_servant,
++ CORBA_Environment *ev);
++
++extern PortableServer_Servant PortableServer_POA_reference_to_servant(
++ PortableServer_POA obj,
++ CORBA_Object reference,
++ CORBA_Environment *ev);
++
++extern PortableServer_ObjectId *PortableServer_POA_reference_to_id(
++ PortableServer_POA obj,
++ CORBA_Object reference,
++ CORBA_Environment *ev);
++
++extern PortableServer_Servant PortableServer_POA_id_to_servant(
++ PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_Environment *ev);
++
++extern CORBA_Object PortableServer_POA_id_to_reference(
++ PortableServer_POA obj,
++ PortableServer_ObjectId *oid,
++ CORBA_Environment *ev);
++
++extern PortableServer_POA PortableServer_Current_get_POA(
++ PortableServer_Current obj,
++ CORBA_Environment *ev);
++
++extern PortableServer_ObjectId *PortableServer_Current_get_object_id(
++ PortableServer_Current obj,
++ CORBA_Environment *ev);
++
++extern CORBA_char *PortableServer_ObjectId_to_string(
++ PortableServer_ObjectId *id,
++ CORBA_Environment *env);
++
++extern CORBA_wchar *PortableServer_ObjectId_to_wstring(
++ PortableServer_ObjectId *id,
++ CORBA_Environment *env);
++
++extern PortableServer_ObjectId *PortableServer_string_to_ObjectId(
++ CORBA_char *str,
++ CORBA_Environment *env);
++
++extern PortableServer_ObjectId *PortableServer_wstring_to_ObjectId(
++ CORBA_wchar *str,
++ CORBA_Environment *env);
++
++extern PortableServer_POA PortableServer_ServantBase__default_POA(
++ PortableServer_Servant,
++ CORBA_Environment *);
++
++extern void PortableServer_ServantLocator_preinvoke(
++ PortableServer_ObjectId *oid,
++ PortableServer_POA adapter,
++ CORBA_Identifier op_name,
++ PortableServer_ServantLocator_Cookie *cookie);
++
++extern void PortableServer_ServantLocator_postinvoke(
++ PortableServer_ObjectId *oid,
++ PortableServer_POA adapter,
++ CORBA_Identifier op_name,
++ PortableServer_ServantLocator_Cookie cookie,
++ PortableServer_Servant servant);
++
++extern void PortableServer_ServantBase__init(
++ PortableServer_Servant,
++ CORBA_Environment *);
++
++extern void PortableServer_ServantBase__fini(
++ PortableServer_Servant,
++ CORBA_Environment *);
++
++/* 19.27 */
++extern CORBA_Identifier CORBA_ServerRequest_operation(
++ CORBA_ServerRequest req,
++ CORBA_Environment *env);
++
++extern CORBA_Context CORBA_ServerRequest_ctx(
++ CORBA_ServerRequest req,
++ CORBA_Environment *env);
++
++extern void CORBA_ServerRequest_arguments(
++ CORBA_ServerRequest req,
++ CORBA_NVList *parameters,
++ CORBA_Environment *env);
++
++extern void CORBA_ServerRequest_set_result(
++ CORBA_ServerRequest req,
++ CORBA_any *value,
++ CORBA_Environment *env);
++
++extern void CORBA_ServerRequest_set_exception(
++ CORBA_ServerRequest req,
++ CORBA_exception_type major,
++ CORBA_any *value,
++ CORBA_Environment *env);
++
++extern void PortableServer_DynamicImpl__init(PortableServer_Servant,
++ CORBA_Environment *ev);
++
++extern void PortableServer_DynamicImpl__fini(PortableServer_Servant,
++ CORBA_Environment *ev);
++
++
++#include "orbit_poa_type.h"
++
++#endif /* !_ORBIT_POA_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/sequences.c linux-2.4.1-korbit/net/korbit/orb/sequences.c
+--- linux-2.4.1/net/korbit/orb/sequences.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/sequences.c Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,35 @@
++#include "orbit.h"
++#include "sequences.h"
++
++gpointer CORBA_sequence_octet_free(gpointer mem,
++ gpointer func_data)
++{
++ CORBA_sequence_octet *seqo = mem;
++
++ if(seqo->_release)
++ CORBA_free(seqo->_buffer);
++
++ return (gpointer)((guchar *)mem + sizeof(CORBA_sequence_octet));
++}
++
++CORBA_octet *
++CORBA_octet_allocbuf(CORBA_unsigned_long len)
++{
++ return (CORBA_octet *)ORBit_alloc(len, NULL, NULL);
++}
++
++CORBA_sequence_octet *CORBA_sequence_octet__alloc(void)
++{
++ CORBA_sequence_octet *seqo;
++
++ seqo = ORBit_alloc(sizeof(CORBA_sequence_octet),
++ (ORBit_free_childvals)CORBA_sequence_octet_free,
++ GUINT_TO_POINTER(1));
++
++ seqo->_length = seqo->_maximum = 0;
++ seqo->_buffer = NULL;
++ seqo->_release = CORBA_TRUE;
++
++ return seqo;
++}
++
+diff -urN linux-2.4.1/net/korbit/orb/sequences.h linux-2.4.1-korbit/net/korbit/orb/sequences.h
+--- linux-2.4.1/net/korbit/orb/sequences.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/sequences.h Thu Feb 1 16:21:19 2001
+@@ -0,0 +1,35 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_SEQUENCES_H_
++#define _ORBIT_SEQUENCES_H_
++
++/* #include "corba_sequences_type.h" */
++#include "orbit_types.h"
++
++CORBA_octet *CORBA_octet_allocbuf(CORBA_unsigned_long len);
++CORBA_sequence_octet *CORBA_sequence_octet__alloc(void);
++
++#endif /* !_ORBIT_SEQUENCES_H_ */
+diff -urN linux-2.4.1/net/korbit/orb/server.c linux-2.4.1-korbit/net/korbit/orb/server.c
+--- linux-2.4.1/net/korbit/orb/server.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/server.c Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,217 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/* Elliot's stuff */
++/* This is somewhat a mess, because I tried to make it easy to add
++ select() support, and as a result #ifdef's litter the land. */
++
++#include "orbit.h"
++#include "orbit_poa.h"
++#include "orbit_poa_type.h"
++#include <IIOP/IIOP-private.h>
++#ifdef HAVE_SYS_POLL_H
++#include <sys/poll.h>
++#endif
++#include <sys/types.h>
++#include <sys/socket.h>
++
++/* We need:
++ a way to find out what FD's need to be selected on
++ a dummy main loop to implement the CORBA_ORB_run() routine;
++*/
++
++gboolean orb_server_keep_running = FALSE;
++
++ORBit_request_validate ORBIT_request_validator = NULL;
++
++/* function protos */
++static PortableServer_POA ORBit_find_POA_for_request(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer);
++static PortableServer_POA ORBit_find_POA_for_locate_request(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer);
++
++static void ORBit_handle_incoming_message(GIOPRecvBuffer *recv_buffer);
++
++void
++ORBit_custom_run_setup(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ IIOPIncomingMessageHandler = ORBit_handle_incoming_message;
++}
++
++
++#if __KERNEL__
++// Modules don't do anything when they call this...
++void CORBA_ORB_run(CORBA_ORB orb, CORBA_Environment *ev) {
++ // This should probably free the ORB pointer, because it is a
++ // duplicated pointer from the one true orb.
++
++}
++
++// The ORB thread calls __CORBA_ORB_run by itself.
++#define CORBA_ORB_run __CORBA_ORB_run
++
++#endif
++
++void
++CORBA_ORB_run(CORBA_ORB orb, CORBA_Environment *ev)
++{
++ ORBit_custom_run_setup(orb, ev);
++
++ orb_server_keep_running = TRUE;
++
++ giop_main();
++}
++
++static void
++ORBit_handle_incoming_request(GIOPRecvBuffer *recv_buffer)
++{
++ CORBA_ORB orb;
++ PortableServer_POA poa;
++ GIOPConnection *connection;
++ ORBit_MessageValidationResult mvr;
++ gboolean do_unuse = TRUE;
++
++ g_assert(recv_buffer);
++
++ connection = GIOP_MESSAGE_BUFFER(recv_buffer)->connection;
++ g_return_if_fail(connection != NULL);
++
++ orb = connection->orb_data;
++
++ g_return_if_fail(orb != NULL);
++
++ ORBit_Trace(TraceMod_ORB, TraceLevel_Debug,
++ "Received request %s, id %d, on %s",
++ recv_buffer->message.u.request.operation,
++ recv_buffer->message.u.request.request_id,
++ recv_buffer->message.u.request.object_key._buffer);
++
++ if(ORBIT_request_validator)
++ mvr = ORBIT_request_validator(recv_buffer->message.u.request.request_id,
++ &recv_buffer->message.u.request.requesting_principal,
++ recv_buffer->message.u.request.operation);
++ else
++ mvr = ORBIT_MESSAGE_ALLOW;
++
++ if(mvr == ORBIT_MESSAGE_ALLOW_ALL)
++ connection->is_auth = TRUE;
++
++ if(mvr != ORBIT_MESSAGE_BAD) {
++ /* Find the POA for this incoming request */
++ poa = ORBit_find_POA_for_request((PortableServer_POA)orb->root_poa,
++ recv_buffer);
++
++ if(poa)
++ do_unuse = ORBit_POA_handle_request(recv_buffer, poa);
++ else
++ g_warning("No POA found for operation %s [%d]",
++ recv_buffer->message.u.request.operation,
++ recv_buffer->message.u.request.request_id);
++ } else {
++ g_warning("Request %s, ID %d was rejected by the authentication mechanism!",
++ recv_buffer->message.u.request.operation,
++ recv_buffer->message.u.request.request_id);
++ }
++
++ if(do_unuse)
++ giop_recv_buffer_unuse(recv_buffer);
++}
++
++static void
++ORBit_handle_incoming_locate_request(GIOPRecvBuffer *recv_buffer)
++{
++ CORBA_ORB orb;
++ PortableServer_POA poa;
++ GIOPConnection *connection;
++ GIOPSendBuffer *send_buffer;
++
++ g_assert(recv_buffer!=NULL);
++
++ connection = GIOP_MESSAGE_BUFFER(recv_buffer)->connection;
++ g_return_if_fail(connection != NULL);
++
++ orb = connection->orb_data;
++
++ g_return_if_fail(orb != NULL);
++
++ ORBit_Trace(TraceMod_ORB, TraceLevel_Debug,
++ "Received locate request id %d, on %s",
++ recv_buffer->message.u.locate_request.request_id,
++ recv_buffer->message.u.locate_request.object_key._buffer);
++ /* Find the POA for this incoming request */
++ poa = ORBit_find_POA_for_locate_request((PortableServer_POA)orb->root_poa, recv_buffer);
++
++ if(poa) {
++ /* Object found, reply with "Object Here" */
++ send_buffer = giop_send_locate_reply_buffer_use(connection,
++ recv_buffer->message.u.locate_request.request_id,
++ GIOP_OBJECT_HERE);
++ giop_send_buffer_write(send_buffer);
++ giop_send_buffer_unuse(send_buffer);
++ } else {
++ /* Object not found, reply with "Unknown Object" */
++ send_buffer = giop_send_locate_reply_buffer_use(connection,
++ recv_buffer->message.u.locate_request.request_id,
++ GIOP_UNKNOWN_OBJECT);
++ giop_send_buffer_write(send_buffer);
++ giop_send_buffer_unuse(send_buffer);
++ }
++
++ giop_recv_buffer_unuse(recv_buffer);
++}
++
++static void
++ORBit_handle_incoming_message(GIOPRecvBuffer *recv_buffer)
++{
++ GIOPConnection *connection;
++
++ g_assert(recv_buffer);
++
++ connection = GIOP_MESSAGE_BUFFER(recv_buffer)->connection;
++ g_return_if_fail(connection != NULL);
++
++ switch(GIOP_MESSAGE_BUFFER(recv_buffer)->message_header.message_type) {
++ case GIOP_REQUEST:
++ ORBit_handle_incoming_request(recv_buffer);
++ break;
++ case GIOP_LOCATEREQUEST:
++ ORBit_handle_incoming_locate_request(recv_buffer);
++ break;
++ case GIOP_CLOSECONNECTION:
++ /* Lame hack - need to do this in a manner that isn't
++ IIOP-specific */
++ giop_recv_buffer_unuse(recv_buffer);
++ giop_main_handle_connection_exception(connection);
++ break;
++ case GIOP_REPLY:
++ /* the above comment probably applies here also... */
++ giop_received_list_push(recv_buffer);
++ break;
++ default:
++ g_warning("discarding message type %d (id possibly %d)",
++ GIOP_MESSAGE_BUFFER(recv_buffer)->message_header.message_type,
++ GIOP_MESSAGE_BUFFER(recv_buffer)->message_header.message_type?recv_buffer->message.u.reply.request_id:recv_buffer->message.u.request.request_id);
++ break;
++ }
++}
++
++static PortableServer_POA
++ORBit_find_POA_for_request(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer)
++{
++ return ORBit_POA_find_POA_for_object_key(poa,
++ &recv_buffer->message.u.request.object_key);
++}
++
++static PortableServer_POA
++ORBit_find_POA_for_locate_request(PortableServer_POA poa,
++ GIOPRecvBuffer *recv_buffer)
++{
++ return ORBit_POA_find_POA_for_object_key(poa,
++ &recv_buffer->message.u.locate_request.object_key);
++}
++
++void
++ORBit_set_request_validation_handler(ORBit_request_validate validator)
++{
++ ORBIT_request_validator = validator;
++}
+diff -urN linux-2.4.1/net/korbit/orb/typecode.c linux-2.4.1-korbit/net/korbit/orb/typecode.c
+--- linux-2.4.1/net/korbit/orb/typecode.c Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/typecode.c Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,104 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter, Red Hat Software
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ * Elliot Lee <sopwith@cuc.edu>
++ *
++ */
++
++#include "orbit.h"
++#include "orbit_typecode.h"
++
++const struct CORBA_TypeCode_struct TC_null_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_null, "null", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_void_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_void, "void", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_short_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_short, "short", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_long_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_long, "long", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_longlong_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_longlong, "long long", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_ushort_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_ushort, "unsigned short", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_ulong_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_ulong, "unsigned long", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_ulonglong_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_ulonglong, "unsigned long long", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_float_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_float, "float", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_double_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_double, "double", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_longdouble_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_longdouble, "long double", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_boolean_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_boolean, "boolean", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_char_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_char, "char", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_wchar_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_wchar, "wide char", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_octet_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_octet, "octet", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_any_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_any, "any", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_TypeCode_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_TypeCode, "TypeCode", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_Principal_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_Principal, "Principal", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_Object_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_objref, "Object Reference", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_string_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_string, "string", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_wstring_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_wstring, "wide string", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++const struct CORBA_TypeCode_struct TC_CORBA_NamedValue_struct=
++ {{{(ORBit_RootObject_Interface *)&ORBit_TypeCode_epv, CORBA_FALSE, -1}, ORBIT_PSEUDO_TYPECODE}, CORBA_tk_struct, "CORBA NamedValue", "", 0, 0, NULL, NULL, NULL, NULL, -1, 0, 0, 0};
++
++static const CORBA_TypeCode anon_subtypes_array7[] =
++{(CORBA_TypeCode) & TC_CORBA_string_struct};
++
++#if (TC_IMPL_TC_CORBA_Identifier_0 == '/')
++const struct CORBA_TypeCode_struct TC_CORBA_Identifier_struct =
++{
++ {
++ {(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1}, ORBIT_PSEUDO_TYPECODE},
++ CORBA_tk_alias, "Identifier", "IDL:omg.org/CORBA/Identifier:1.0",
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array7,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
++
++#if (TC_IMPL_TC_CORBA_RepositoryId_0 == '/')
++const struct CORBA_TypeCode_struct TC_CORBA_RepositoryId_struct =
++{
++ {
++ {(ORBit_RootObject_Interface *) & ORBit_TypeCode_epv, TRUE, -1}, ORBIT_PSEUDO_TYPECODE},
++ CORBA_tk_alias, "RepositoryId", "IDL:omg.org/CORBA/RepositoryId:1.0",
++ 0, 1,
++ NULL,
++ (CORBA_TypeCode *) anon_subtypes_array7,
++ NULL,
++ CORBA_OBJECT_NIL, 0, -1, 0, 0
++};
++#endif
+diff -urN linux-2.4.1/net/korbit/orb/typecode.h linux-2.4.1-korbit/net/korbit/orb/typecode.h
+--- linux-2.4.1/net/korbit/orb/typecode.h Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/orb/typecode.h Thu Feb 1 11:47:14 2001
+@@ -0,0 +1,31 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++
++/*
++ * ORBit: A CORBA v2.2 ORB
++ *
++ * Copyright (C) 1998 Richard H. Porter
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the Free
++ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Author: Dick Porter <dick@cymru.net>
++ *
++ */
++
++#ifndef _ORBIT_TYPECODE_H_
++#define _ORBIT_TYPECODE_H_
++
++#include "orbit_types.h"
++
++#endif /* !_ORBIT_TYPECODE_H_ */
+diff -urN linux-2.4.1/net/korbit/sup/CVS/Entries linux-2.4.1-korbit/net/korbit/sup/CVS/Entries
+--- linux-2.4.1/net/korbit/sup/CVS/Entries Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/sup/CVS/Entries Thu Feb 1 11:47:15 2001
+@@ -0,0 +1 @@
++D
+diff -urN linux-2.4.1/net/korbit/sup/CVS/Repository linux-2.4.1-korbit/net/korbit/sup/CVS/Repository
+--- linux-2.4.1/net/korbit/sup/CVS/Repository Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/sup/CVS/Repository Thu Feb 1 11:47:15 2001
+@@ -0,0 +1 @@
++/cvsroot/korbit/linux/net/korbit/sup
+diff -urN linux-2.4.1/net/korbit/sup/CVS/Root linux-2.4.1-korbit/net/korbit/sup/CVS/Root
+--- linux-2.4.1/net/korbit/sup/CVS/Root Thu Jan 1 03:00:00 1970
++++ linux-2.4.1-korbit/net/korbit/sup/CVS/Root Thu Feb 1 11:47:15 2001
+@@ -0,0 +1 @@
++vraalsen@cvs.korbit.sourceforge.net:/cvsroot/korbit
diff --git a/fs/libmysqlfs.c b/fs/libmysqlfs.c
new file mode 100644
index 00000000000..fde325c3c42
--- /dev/null
+++ b/fs/libmysqlfs.c
@@ -0,0 +1,151 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "libmysqlfs.h"
+
+int search_and_replace(char *search, char* replace, char* string)
+{
+ char buff[1024];
+ int found=0;
+ char *ptr1;
+ const char *ptr2=buff;
+ char *strptr=string;
+
+ DBUG_ENTER("search_and_replace");
+ DBUG_PRINT("enter",("search: '%s' replace:'%s' string:'%s'",search,replace,string));
+ strcpy(buff,string);
+ while(ptr1=strstr(ptr2,search))
+ {
+ strncpy(strptr,ptr2,ptr1-buff);
+ strptr+=ptr1-buff;
+ ptr2+=ptr1-buff+strlen(search);
+ strcpy(strptr,replace);
+ strptr+=strlen(replace);
+ found++;
+ }
+ DBUG_RETURN(found);
+}
+
+int show_functions(char *b, function_type type)
+{
+ int i=0,j=0;
+ struct func_st func;
+ DBUG_ENTER("show_functions");
+ get_dynamic(&functions_array,(gptr)&func,i);
+ while(func.length) {
+ if (func.type == type)
+ strcpy(&b[j++*BUFLEN],func.filename);
+ get_dynamic(&functions_array,(gptr)&func,++i);
+ }
+ DBUG_RETURN(j);
+}
+
+struct func_st * check_if_function(char *name, function_type type)
+{
+ int pathlen;
+ int j,i=0, len;
+ static struct func_st function;
+ char buffer[BUFLEN];
+
+ DBUG_ENTER("check_if_function");
+ DBUG_PRINT("enter",("name: '%s' type: '%d'", name, type));
+ pathlen=strlen(name);
+
+ /* We try to compare last element in path to function names */
+ get_dynamic(&functions_array,(gptr)&function,i);
+ while(function.length) {
+ function.continuous ?
+ (j=!strncasecmp(function.filename, name, function.length))
+ : (j=!strcasecmp(function.filename,name));
+ if(j) { /* This happens when function was matched */
+ DBUG_PRINT("info",("Function %s detected!",function.filename));
+ break;
+ }
+ get_dynamic(&functions_array,(gptr)&function,++i);
+ }
+
+ /* Copy path to buffer and trip function name (if found) from it */
+ if(function.length != 0)
+ {
+ DBUG_RETURN(&function);
+ } else {
+ DBUG_RETURN(0);
+ }
+}
+
+/*
+ * parse - splits "path" into different variables
+ * in way "/server/database/table/(field|key)/(value|function)". If path is shorter,
+ * then other fields will be NULL. If path is longer than four levels or
+ * shorter than one level, FS_NOTEXIST is returned.
+ */
+int parse(const char * path, char *server, char * database, char *table,
+ char* field, char* value, struct func_st **funce)
+{
+ char buffer[BUFLEN];
+ char *p=buffer;
+ char *x;
+ int len;
+
+ DBUG_ENTER("parse");
+ DBUG_PRINT("enter",("path: '%s'", path));
+
+ *server=*database=*table=*field=*value='\0';
+
+ /* Search for first slash and drop it */
+ strcpy(buffer,path);
+ x=strtok_r(p,"/",&p);
+ if(x)
+ {
+ strcpy(server,x); /* First argument is server name */
+ if(*p)
+ strcpy(database,strtok_r(p,"/",&p)); /* Second is database */
+ if(p && *p)
+ strcpy(table ,strtok_r(p,"/",&p)); /* Third is table name */
+ if(p && *p)
+ strcpy(field ,strtok_r(p,"/",&p)); /* Fourth is field or key name */
+ if(p && *p)
+ strcpy(value ,strtok_r(p,"/",&p)); /* Fifth is field/key value or function */
+ }
+
+ /* We have to find if last argument is function,
+ * In which case we clear it
+ */
+ if(*value) {
+ *funce=check_if_function(value,VALUE_FUNCTION);
+ if(*funce) *value='\0';
+ } else if (*field) {
+ *funce=check_if_function(field,FIELD_FUNCTION);
+ if(*funce) *field='\0';
+ } else if (*table) {
+ *funce=check_if_function(table,TABLE_FUNCTION);
+ if(*funce) *table='\0';
+ } else if (*database) {
+ *funce=check_if_function(database,DATABASE_FUNCTION);
+ if(*funce) *database='\0';
+ } else if (*server) {
+ *funce=check_if_function(server,SERVER_FUNCTION);
+ if(*funce) *server='\0';
+ } else
+ *funce=NULL;
+
+ DBUG_PRINT("info",("path: '%s', server: '%s', db: '%s', table: '%s', field: '%s', value: '%s', function: '%x'",
+ buffer, server, database, table, field, value, funce ));
+ if(p && *p) /* Something is in buffer - too deep in levels */
+ DBUG_RETURN(-1)
+ else
+ DBUG_RETURN(0)
+}
diff --git a/fs/libmysqlfs.h b/fs/libmysqlfs.h
new file mode 100644
index 00000000000..0e95daaa791
--- /dev/null
+++ b/fs/libmysqlfs.h
@@ -0,0 +1,81 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "CorbaFS.h"
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+
+#define BUFLEN 1024
+#define MAXDIRS 1024
+
+typedef enum {
+ FUNC_NONE,
+ FUNC_SERVER_UPTIME,
+ FUNC_SERVER_THREADS,
+ FUNC_SERVER_VERSION,
+ FUNC_DATABASE_CREATED,
+ FUNC_TABLE_COUNT,
+ FUNC_TABLE_CREATED,
+ FUNC_FIELD_LENGTH,
+ FUNC_KEY_AVG,
+ FUNC_KEY_SUM,
+ FUNC_KEY_MAX,
+ FUNC_KEY_MIN
+} func_enum;
+
+
+typedef enum {
+ NONE_FUNCTION,
+ ROOT_FUNCTION,
+ SERVER_FUNCTION,
+ DATABASE_FUNCTION,
+ TABLE_FUNCTION,
+ KEY_FUNCTION,
+ FIELD_FUNCTION,
+ VALUE_FUNCTION
+} function_type;
+
+struct func_st {
+ char type_s[20];
+ char filename[20];
+ char function[80];
+ function_type type;
+ int length;
+ my_bool continuous;
+} ;
+
+
+int parse(const char* path,
+ char* root,
+ char* database,
+ char* table,
+ char* key,
+ char* field,
+ struct func_st **func
+);
+
+gptr db_load_functions();
+int db_function(char *b,const char *server, const char *database,const char *table,const char *field,
+ const char *value, const char *path, struct func_st *function);
+int fix_filenames(char *buf);
+
+DYNAMIC_ARRAY functions_array;
+
+
diff --git a/fs/my.cnf b/fs/my.cnf
new file mode 100644
index 00000000000..e70f2c30cbf
--- /dev/null
+++ b/fs/my.cnf
@@ -0,0 +1,5 @@
+[mysqlcorbafs]
+socket=/var/lib/mysql/mysql.sock
+host=127.0.0.1
+user=root
+#password=xxxxxx
diff --git a/fs/mysqlcorbafs.c b/fs/mysqlcorbafs.c
new file mode 100644
index 00000000000..4bc27618d4d
--- /dev/null
+++ b/fs/mysqlcorbafs.c
@@ -0,0 +1,998 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/*
+ *
+ * fsck.mysql
+ */
+
+#include "libmysqlfs.h"
+#include "mysqlcorbafs.h"
+#include <my_getopt.h>
+#define MAXPATHLEN 256
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+
+#include <my_sys.h>
+static long inodeNum;
+
+extern DYNAMIC_ARRAY functions_array;
+enum options {OPT_FTB=256, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_KEYWORDS,
+ OPT_LOCKS, OPT_DROP, OPT_OPTIMIZE, OPT_DELAYED, OPT_TABLES,
+ OPT_CHARSETS_DIR, OPT_DEFAULT_CHARSET};
+
+CHANGEABLE_VAR changeable_vars[] = {
+ { "max_allowed_packet", (long*) &max_allowed_packet,24*1024*1024,4096,
+ 24*1024L*1024L,MALLOC_OVERHEAD,1024},
+ { "net_buffer_length", (long*) &net_buffer_length,1024*1024L-1025,4096,
+ 24*1024L*1024L,MALLOC_OVERHEAD,1024},
+ { 0, 0, 0, 0, 0, 0, 0}
+};
+
+CORBA_ORB orb;
+PortableServer_POA poa;
+CORBA_Environment *ev;
+PortableServer_ObjectId *objid;
+static my_bool verbose=0,opt_compress=0,extended_insert=0, lock_tables=0,
+ opt_quoted=0, opt_lock=0, opt_delayed=0, ignore_errors=0;
+
+gptr fptr;
+
+static const char *load_default_groups[]= { "mysqlcorbafs","client",0 };
+static char *default_charset, *current_host, *current_user, *opt_password,
+ *path,*fields_terminated=0, *lines_terminated=0, *enclosed=0,
+ *opt_enclosed=0, *escaped=0;
+
+
+/* This should be fixed to use my_getopt when the program is ready
+
+
+static struct option long_options[] =
+{
+ {"add-locks", no_argument, 0,OPT_LOCKS},
+ {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
+ {"compress", no_argument, 0, 'C'},
+ {"database",required_argument, 0, 'D'},
+ {"debug",optional_argument, 0, '#'},
+ {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
+ {"delayed-insert",no_argument, 0, OPT_DELAYED},
+ {"fields-terminated-by", required_argument, 0, (int) OPT_FTB},
+ {"fields-enclosed-by", required_argument,0, (int) OPT_ENC},
+ {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC},
+ {"fields-escaped-by", required_argument,0, (int) OPT_ESC},
+ {"functions",required_argument, 0, 'f'},
+ {"help", no_argument, 0,'?'},
+ {"host", required_argument,0, 'h'},
+ {"lines-terminated-by", required_argument, 0, (int) OPT_LTB},
+ {"lock-tables", no_argument, 0, 'l'},
+ {"no-data", no_argument, 0, 'd'},
+ {"password", optional_argument, 0, 'p'},
+#ifdef __WIN__
+ {"pipe",no_argument,0, 'W'},
+#endif
+ {"port", required_argument,0, 'P'},
+// {"quick", no_argument,0, 'q'},
+ {"quote-names",no_argument,0, 'Q'},
+ {"set-variable",required_argument,0, 'O'},
+ {"socket", required_argument,0, 'S'},
+#include "sslopt-longopts.h"
+#ifndef DONT_ALLOW_USER_CHANGE
+ {"user", required_argument,0, 'u'},
+#endif
+ {"verbose", no_argument,0, 'v'},
+ {"version", no_argument,0, 'V'},
+ {0, 0, 0, 0}
+};
+
+*/
+
+/*
+void
+print_table_data(MYSQL_RES *result)
+{
+ String separator(256);
+ MYSQL_ROW cur;
+ MYSQL_FIELD *field;
+ bool *num_flag;
+
+ num_flag=(bool*) my_alloca(sizeof(bool)*mysql_num_fields(result));
+ if (info_flag)
+ {
+ print_field_types(result);
+ mysql_field_seek(result,0);
+ }
+ separator.copy("+",1);
+ while ((field = mysql_fetch_field(result)))
+ {
+ uint length=skip_column_names ? 0 : (uint) strlen(field->name);
+ if (quick)
+ length=max(length,field->length);
+ else
+ length=max(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length+1;
+ separator.fill(separator.length()+length+2,'-');
+ separator.append('+');
+ }
+ tee_puts(separator.c_ptr(), PAGER);
+ if (!skip_column_names)
+ {
+ mysql_field_seek(result,0);
+ (void) tee_fputs("|", PAGER);
+ for (uint off=0; (field = mysql_fetch_field(result)) ; off++)
+ {
+ tee_fprintf(PAGER, " %-*s|",min(field->max_length,MAX_COLUMN_LENGTH),
+ field->name);
+ num_flag[off]= IS_NUM(field->type);
+ }
+ (void) tee_fputs("\n", PAGER);
+ tee_puts(separator.c_ptr(), PAGER);
+ }
+
+ while ((cur = mysql_fetch_row(result)))
+ {
+ (void) tee_fputs("|", PAGER);
+ mysql_field_seek(result,0);
+ for (uint off=0 ; off < mysql_num_fields(result); off++)
+ {
+ const char *str=cur[off] ? cur[off] : "NULL";
+ field = mysql_fetch_field(result);
+ uint length=field->max_length;
+ if (length > MAX_COLUMN_LENGTH)
+ {
+ tee_fputs(str,PAGER); tee_fputs(" |",PAGER);
+ }
+ else
+ tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|",
+ length, str);
+ }
+ (void) tee_fputs("\n", PAGER);
+ }
+ tee_puts(separator.c_ptr(), PAGER);
+ my_afree((gptr) num_flag);
+}
+
+void
+print_table_data_html(MYSQL_RES *result)
+{
+ MYSQL_ROW cur;
+ MYSQL_FIELD *field;
+
+ mysql_field_seek(result,0);
+ (void) tee_fputs("<TABLE BORDER=1><TR>", PAGER);
+ if (!skip_column_names)
+ {
+ while((field = mysql_fetch_field(result)))
+ {
+ tee_fprintf(PAGER, "<TH>%s</TH>", (field->name ?
+ (field->name[0] ? field->name :
+ " &nbsp; ") : "NULL"));
+ }
+ (void) tee_fputs("</TR>", PAGER);
+ }
+ while ((cur = mysql_fetch_row(result)))
+ {
+ (void) tee_fputs("<TR>", PAGER);
+ for (uint i=0; i < mysql_num_fields(result); i++)
+ {
+ ulong *lengths=mysql_fetch_lengths(result);
+ (void) tee_fputs("<TD>", PAGER);
+ safe_put_field(cur[i],lengths[i]);
+ (void) tee_fputs("</TD>", PAGER);
+ }
+ (void) tee_fputs("</TR>", PAGER);
+ }
+ (void) tee_fputs("</TABLE>", PAGER);
+}
+
+
+void
+print_table_data_xml(MYSQL_RES *result)
+{
+ MYSQL_ROW cur;
+ MYSQL_FIELD *fields;
+
+ mysql_field_seek(result,0);
+
+ char *statement;
+ statement=(char*) my_malloc(strlen(glob_buffer.ptr())*5+1, MYF(MY_WME));
+ xmlencode(statement, (char*) glob_buffer.ptr());
+
+ (void) my_chomp(strend(statement));
+
+ tee_fprintf(PAGER,"<?xml version=\"1.0\"?>\n\n<resultset statement=\"%s\">", statement);
+
+ my_free(statement,MYF(MY_ALLOW_ZERO_PTR));
+
+ fields = mysql_fetch_fields(result);
+
+ while ((cur = mysql_fetch_row(result)))
+ {
+ (void) tee_fputs("\n <row>\n", PAGER);
+ for (uint i=0; i < mysql_num_fields(result); i++)
+ {
+ char *data;
+ ulong *lengths=mysql_fetch_lengths(result);
+ data=(char*) my_malloc(lengths[i]*5+1, MYF(MY_WME));
+ tee_fprintf(PAGER, "\t<%s>", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ xmlencode(data, cur[i]);
+ safe_put_field(data, strlen(data));
+ tee_fprintf(PAGER, "</%s>\n", (fields[i].name ?
+ (fields[i].name[0] ? fields[i].name :
+ " &nbsp; ") : "NULL"));
+ my_free(data,MYF(MY_ALLOW_ZERO_PTR));
+ }
+ (void) tee_fputs(" </row>\n", PAGER);
+ }
+ (void) tee_fputs("</resultset>\n", PAGER);
+}
+
+
+void
+print_table_data_vertically(MYSQL_RES *result)
+{
+ MYSQL_ROW cur;
+ uint max_length=0;
+ MYSQL_FIELD *field;
+
+ while ((field = mysql_fetch_field(result)))
+ {
+ uint length=(uint) strlen(field->name);
+ if (length > max_length)
+ max_length= length;
+ field->max_length=length;
+ }
+
+ mysql_field_seek(result,0);
+ for (uint row_count=1; (cur= mysql_fetch_row(result)); row_count++)
+ {
+ mysql_field_seek(result,0);
+ tee_fprintf(PAGER,
+ "*************************** %d. row ***************************\n", row_count);
+ for (uint off=0; off < mysql_num_fields(result); off++)
+ {
+ field= mysql_fetch_field(result);
+ tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name);
+ tee_fprintf(PAGER, "%s\n",cur[off] ? (char*) cur[off] : "NULL");
+ }
+ }
+}
+
+
+
+*/
+
+
+
+static my_bool test_if_special_chars(const char *str)
+{
+ for ( ; *str ; str++)
+ if (!isvar(*str) && *str != '$')
+ return 1;
+ return 0;
+} /* test_if_special_chars */
+
+char *quote_name(char *name, char *buff)
+{
+ char *end;
+ DBUG_ENTER("quote_name");
+ if (!opt_quoted && !test_if_special_chars(name))
+ return name;
+ buff[0]=QUOTE_CHAR;
+ *end=strmov(buff+1,name);
+ end[0]=QUOTE_CHAR;
+ end[1]=0;
+ DBUG_RETURN(buff);
+} /* quote_name */
+
+/*
+ * Allow the user to specify field terminator strings like:
+ * "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
+ * This is done by doubleing ' and add a end -\ if needed to avoid
+ * syntax errors from the SQL parser.
+ */
+
+char *field_escape(char *to,const char *from,uint length)
+{
+ const char *end;
+ uint end_backslashes=0;
+ DBUG_ENTER("field_escape");
+
+ {
+ *to++= *from;
+ if (*from == '\\')
+ end_backslashes^=1; /* find odd number of backslashes */
+ else {
+ if (*from == '\'' && !end_backslashes)
+ *to++= *from; /* We want a duplicate of "'" for MySQL */
+ end_backslashes=0;
+ }
+ }
+ /* Add missing backslashes if user has specified odd number of backs.*/
+ if (end_backslashes)
+ *to++= '\\';
+ DBUG_RETURN(to);
+} /* field_escape */
+
+void safe_exit(int error)
+{
+ if (!first_error)
+ first_error= error;
+ if (ignore_errors)
+ return;
+ if (sock)
+ mysql_close(sock);
+ exit(error);
+}
+/* safe_exit */
+
+
+/*
+ * ** DBerror -- prints mysql error message and exits the program.
+ */
+void DBerror(MYSQL *mysql, const char *when)
+{
+ DBUG_ENTER("DBerror");
+ my_printf_error(0,"Got error: %d: %s %s", MYF(0),
+ mysql_errno(mysql), mysql_error(mysql), when);
+ safe_exit(EX_MYSQLERR);
+ DBUG_VOID_RETURN;
+} /* DBerror */
+
+void print_version(void)
+{
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,CORBAFS_VERSION,
+ MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+} /* print_version */
+
+void usage(void)
+{
+ uint i;
+ print_version();
+ puts("By Tõnu Samuel. Some code is partially from other geeks around the world");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
+ puts("Dumping definition and data mysql database or table");
+ printf("Usage: %s [OPTIONS]\n", my_progname);
+ printf("\n\
+ -#, --debug=... Output debug log. Often this is 'd:t:o,filename`.\n\
+ --character-sets-dir=...\n\
+ Directory where character sets are\n\
+ -?, --help Display this help message and exit.\n\
+ -c, --complete-insert Use complete insert statements.\n\
+ -C, --compress Use compression in server/client protocol.\n\
+ --default-character-set=...\n\
+ Set the default character set\n\
+ -e, --extended-insert Allows utilization of the new, much faster\n\
+ INSERT syntax.\n\
+ --add-locks Add locks around insert statements.\n\
+ --allow-keywords Allow creation of column names that are keywords.\n\
+ --delayed-insert Insert rows with INSERT DELAYED.\n\
+ -f, --force Continue even if we get an sql-error.\n\
+ -h, --host=... Connect to host.\n");
+puts("\
+ -l, --lock-tables Lock all tables for read.\n\
+ -t, --no-create-info Don't write table creation info.\n\
+ -d, --no-data No row information.\n\
+ -O, --set-variable var=option\n\
+ give a variable a value. --help lists variables\n\
+ -p, --password[=...] Password to use when connecting to server.\n\
+ If password is not given it's solicited on the tty.\n");
+#ifdef __WIN__
+ puts("-W, --pipe Use named pipes to connect to server");
+#endif
+ printf("\
+ -P, --port=... Port number to use for connection.\n\
+ -q, --quick Don't buffer query, dump directly to stdout.\n\
+ -S, --socket=... Socket file to use for connection.\n\
+ --tables Overrides option --databases (-B).\n");
+#include "sslopt-usage.h"
+#ifndef DONT_ALLOW_USER_CHANGE
+ printf("\
+ -u, --user=# User for login if not current user.\n");
+#endif
+ printf("\
+ -v, --verbose Print info about the various stages.\n\
+ -V, --version Output version information and exit.\n\
+");
+ print_defaults("my",load_default_groups);
+
+ printf("\nPossible variables for option --set-variable (-O) are:\n");
+ for (i=0 ; changeable_vars[i].name ; i++)
+ printf("%-20s current value: %lu\n",
+ changeable_vars[i].name,
+ (ulong) *changeable_vars[i].varptr);
+} /* usage */
+
+
+
+static int get_options(int *argc,char ***argv)
+{
+ int c,option_index;
+ my_bool tty_password=0;
+ DBUG_ENTER("get_options");
+ load_defaults("my",load_default_groups,argc,argv);
+
+ /* change this to use my_getopt when program is ready */
+ set_all_changeable_vars(changeable_vars);
+ while ((c=getopt_long(*argc,*argv,"#::p::h:u:O:P:S:T:EBaAcCdefFlnqtvVw:?Ix",
+ long_options, &option_index)) != EOF)
+ {
+ switch(c) {
+ case 'e':
+ extended_insert=1;
+ break;
+ case OPT_DEFAULT_CHARSET:
+ default_charset= optarg;
+ break;
+ case OPT_CHARSETS_DIR:
+ charsets_dir= optarg;
+ break;
+
+ ignore_errors=1;
+ break;
+ case 'h':
+ my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
+ current_host=my_strdup(optarg,MYF(MY_WME));
+ break;
+#ifndef DONT_ALLOW_USER_CHANGE
+ case 'u':
+ current_user=optarg;
+ break;
+#endif
+ case 'O':
+ if (set_changeable_var(optarg, changeable_vars))
+ {
+ usage();
+ return(1);
+ }
+ break;
+ case 'p':
+ if (optarg)
+ {
+ char *start=optarg;
+ my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ opt_password=my_strdup(optarg,MYF(MY_FAE));
+ while (*optarg) *optarg++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]=0; /* Cut length of argument */
+ } else
+ tty_password=1;
+ break;
+ case 'P':
+ opt_mysql_port= (unsigned int) atoi(optarg);
+ break;
+ case 'S':
+ opt_mysql_unix_port= optarg;
+ break;
+ case 'W':
+#ifdef __WIN__
+ opt_mysql_unix_port=MYSQL_NAMEDPIPE;
+#endif
+ break;
+ case 'T':
+ path= optarg;
+ break;
+ case '#':
+ DBUG_PUSH(optarg ? optarg : "d:t:o");
+ break;
+ case 'C':
+ opt_compress=1;
+ break;
+ case 'l': lock_tables=1; break;
+ case 'Q': opt_quoted=1; break;
+ case 'v': verbose=1; break;
+ case 'V': print_version(); exit(0);
+ default:
+ fprintf(stderr,"%s: Illegal option character '%c'\n",my_progname,opterr);
+ /* Fall throught */
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ case (int) OPT_FTB:
+ fields_terminated= optarg;
+ break;
+ case (int) OPT_LTB:
+ lines_terminated= optarg;
+ break;
+ case (int) OPT_ENC:
+ enclosed= optarg;
+ break;
+ case (int) OPT_O_ENC:
+ opt_enclosed= optarg;
+ break;
+ case (int) OPT_ESC:
+ escaped= optarg;
+ break;
+ case (int) OPT_LOCKS:
+ opt_lock=1;
+ break;
+ case (int) OPT_OPTIMIZE:
+ extended_insert=opt_lock=lock_tables=1;
+ break;
+ case (int) OPT_DELAYED:
+ opt_delayed=1;
+ break;
+#include "sslopt-case.h"
+ }
+ }
+ if (opt_delayed)
+ opt_lock=0; /* Can't have lock with delayed */
+ if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
+ fields_terminated))
+ {
+ fprintf(stderr, "%s: You must use option --tab with --fields-...\n", my_progname);
+ return(1);
+ }
+
+ if (enclosed && opt_enclosed)
+ {
+ fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname);
+ return(1);
+ }
+ if (default_charset)
+ {
+ if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
+ exit(1);
+ }
+ (*argc)-=optind;
+ (*argv)+=optind;
+ if (tty_password)
+ opt_password=get_tty_password(NullS);
+ DBUG_RETURN(0);
+} /* get_options */
+
+
+/*** epv structures ***/
+
+static PortableServer_ServantBase__epv impl_Inode_base_epv = {
+ NULL, /* _private data */
+ NULL, /* finalize routine */
+ NULL, /* default_POA routine */
+};
+static POA_CorbaFS_Inode__epv impl_Inode_epv = {
+ NULL, /* _private */
+ (gpointer) & impl_Inode_getStatus,
+ (gpointer) & impl_Inode_readpage,
+ (gpointer) & impl_Inode_release,
+
+};
+static PortableServer_ServantBase__epv impl_FileSystem_base_epv = {
+ NULL, /* _private data */
+ NULL, /* finalize routine */
+ NULL, /* default_POA routine */
+};
+static POA_CorbaFS_FileSystem__epv impl_FileSystem_epv = {
+ NULL, /* _private */
+ (gpointer) & impl_FileSystem_getInode,
+ (gpointer) & impl_FileSystem_readdir,
+ (gpointer) & impl_FileSystem_readlink,
+};
+
+/*** vepv structures ***/
+
+static POA_CorbaFS_Inode__vepv impl_Inode_vepv = {
+ &impl_Inode_base_epv,
+ &impl_Inode_epv,
+};
+static POA_CorbaFS_FileSystem__vepv impl_FileSystem_vepv = {
+ &impl_FileSystem_base_epv,
+ &impl_FileSystem_epv,
+};
+
+/*** Stub implementations ***/
+
+static CorbaFS_Inode
+impl_Inode__create(PortableServer_POA poa, CORBA_Environment * ev)
+{
+ CorbaFS_Inode retval;
+ impl_POA_CorbaFS_Inode *newservant;
+ PortableServer_ObjectId *objid;
+
+ DBUG_ENTER("impl_Inode__create");
+ newservant = g_new0(impl_POA_CorbaFS_Inode, 1);
+ newservant->servant.vepv = &impl_Inode_vepv;
+ newservant->poa = poa;
+ POA_CorbaFS_Inode__init((PortableServer_Servant) newservant, ev);
+ objid = PortableServer_POA_activate_object(poa, newservant, ev);
+ CORBA_free(objid);
+ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
+
+ DBUG_RETURN(retval);
+}
+
+static void
+impl_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
+ CORBA_Environment * ev)
+{
+ PortableServer_ObjectId *objid;
+
+ DBUG_ENTER("impl_Inode__destroy");
+ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
+ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
+ CORBA_free(objid);
+
+ POA_CorbaFS_Inode__fini((PortableServer_Servant) servant, ev);
+ g_free(servant);
+ DBUG_VOID_RETURN;
+}
+
+static void
+impl_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
+ CORBA_unsigned_short * mode,
+ CORBA_unsigned_long * uid,
+ CORBA_unsigned_long * gid,
+ CORBA_unsigned_long * size,
+ CORBA_unsigned_long * inodeNum,
+ CORBA_unsigned_short * numLinks,
+ CORBA_long * atime,
+ CORBA_long * mtime,
+ CORBA_long * ctime, CORBA_Environment * ev)
+{
+ struct stat buf;
+ char
+ server[BUFLEN],
+ database[BUFLEN],
+ table[BUFLEN],
+ key[BUFLEN],
+ field[BUFLEN],
+ value[BUFLEN];
+
+ struct func_st *func;
+
+ DBUG_ENTER("impl_Inode_getStatus");
+ DBUG_PRINT("enter",("path: '%s', mode: '%o', uid: '%d', gid: '%d', size: '%d',
+ inodeNum: '%d', numLinks: '%d', atime: '%d',mtime: '%d', ctime: '%d'",
+ servant->path, mode, uid, gid, size, inodeNum, numLinks, atime, mtime, ctime));
+ DBUG_PRINT("info",("func: %x",&func));
+ if(parse(servant->path, server, database, table, field, value, &func)>0)
+ {
+ DBUG_PRINT("info",("ENOENT"));
+ *mode=0;
+ } else if (func != NULL){
+ DBUG_PRINT("info",("func: %x",&func));
+ DBUG_PRINT("info",("Argument is function at %x, returning S_IFREG",func));
+ *mode = S_IFREG; // File
+ } else if (*field){
+ DBUG_PRINT("info",("Argument is file, returning S_IFREG"));
+ *mode = S_IFREG; // File
+ } else {
+ DBUG_PRINT("info",("Argument is directory, returning S_IFDIR"));
+ *mode = S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH ; // Dir
+ }
+
+ *mode |= S_IRUSR | S_IRGRP | S_IROTH;
+ *uid = 0;
+ *gid = 0;
+ *size = 4096;
+ *inodeNum = servant->inodeNum;
+ *numLinks = 1;
+ *atime = 3;
+ *mtime = 2;
+ *ctime = 1;
+
+// lstat(servant->path, &buf);
+// *mode = buf.st_mode;
+/* *uid = buf.st_uid;
+ *gid = buf.st_gid;
+ *size = buf.st_size;
+ *inodeNum = buf.st_ino;
+ *numLinks = buf.st_nlink;
+ *atime = buf.st_atime;
+ *mtime = buf.st_mtime;
+ *ctime = buf.st_ctime;*/
+ DBUG_VOID_RETURN;
+}
+
+static void
+impl_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
+ CorbaFS_Buffer ** buffer,
+ CORBA_long size,
+ CORBA_long offset, CORBA_Environment * ev)
+{
+ int type;
+ int fd = -1, c = 0;
+ int res;
+ char
+ server[BUFLEN],
+ database[BUFLEN],
+ table[BUFLEN],
+ key[BUFLEN],
+ field[BUFLEN],
+ value[BUFLEN];
+ struct func_st *func;
+
+ DBUG_ENTER("impl_Inode_readpage");
+ DBUG_PRINT("enter",("path: '%s'", servant->path));
+ *buffer = CorbaFS_Buffer__alloc();
+ (*buffer)->_maximum = size;
+ (*buffer)->_buffer = CORBA_octet_allocbuf(size);
+ printf("requested to read %d bytes\n",size);
+ memset((*buffer)->_buffer, size, 0);
+ type = parse(servant->path, server, database, table, field, value, &func);
+ if (func != NULL)
+ res=db_function((*buffer)->_buffer, server, database, table, field, value, servant->path, func);
+ else
+ res=db_show_field((*buffer)->_buffer, database, table, field, path, value);
+ if(res>0)
+ (*buffer)->_length = strlen((*buffer)->_buffer);
+ else
+ (*buffer)->_length = 0;
+/*
+ fd = open(servant->path, O_RDONLY);
+ printf("Inode_readpage : fd = %d\n", fd);
+ lseek(fd, offset, SEEK_SET);
+ c = read(fd, (*buffer)->_buffer, size);
+ printf("Inode_readpage : read %d bytes\n", c);
+ (*buffer)->_length = c;
+ close(fd);
+*/
+ DBUG_VOID_RETURN;
+}
+
+static void
+impl_Inode_release(impl_POA_CorbaFS_Inode * servant,
+ CORBA_Environment * ev)
+{
+ DBUG_ENTER("impl_Inode_readpage");
+ DBUG_PRINT("enter",("path: '%s'", servant->path));
+ DBUG_VOID_RETURN;
+}
+
+/*
+ * This function is called when we get mounted
+ */
+CorbaFS_FileSystem
+impl_FileSystem__create(PortableServer_POA poa,
+ CORBA_Environment * ev)
+{
+ CorbaFS_FileSystem retval;
+ impl_POA_CorbaFS_FileSystem *newservant;
+ PortableServer_ObjectId *objid;
+
+ DBUG_ENTER("impl_FileSystem__create");
+ newservant = g_new0(impl_POA_CorbaFS_FileSystem, 1);
+ newservant->servant.vepv = &impl_FileSystem_vepv;
+ newservant->poa = poa;
+ POA_CorbaFS_FileSystem__init((PortableServer_Servant) newservant, ev);
+ objid = PortableServer_POA_activate_object(poa, newservant, ev);
+ CORBA_free(objid);
+ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
+
+ DBUG_RETURN(retval);
+}
+
+/*
+ * This function is called when we get unmounted
+ */
+static void
+impl_FileSystem__destroy(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_Environment * ev)
+{
+ PortableServer_ObjectId *objid;
+ DBUG_ENTER("impl_FileSystem__destroy");
+
+ objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
+ PortableServer_POA_deactivate_object(servant->poa, objid, ev);
+ CORBA_free(objid);
+
+ POA_CorbaFS_FileSystem__fini((PortableServer_Servant) servant, ev);
+ g_free(servant);
+ DBUG_VOID_RETURN;
+}
+
+static CorbaFS_Inode
+impl_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * path, CORBA_Environment * ev)
+{
+ CorbaFS_Inode retval;
+ impl_POA_CorbaFS_Inode *inode;
+ char
+ database[BUFLEN],
+ table[BUFLEN],
+ key[BUFLEN],
+ field[BUFLEN];
+ char buffer[MAXDIRS][BUFLEN];
+ int c;
+
+ DBUG_ENTER("impl_FileSystem_getInode");
+ DBUG_PRINT("enter",("path: '%s'", path));
+
+ //FIXME: We should verify the existense of file/dir here
+ //
+ retval = impl_Inode__create(servant->poa, ev);
+ inode = PortableServer_POA_reference_to_servant( servant->poa, retval, ev );
+ inode->path = CORBA_string_dup(path);
+ //FIXME: inodeNum Generation goes here
+ //
+ inode->inodeNum= inodeNum++;
+#if 0
+ inode->mode = 0040777; /* world-readable directory */
+ inode->uid = 0;
+ inode->gid = 0;
+ inode->size = 4096;
+ inode->inodeNum = inodeNum++;
+ inode->numLinks = 1;
+ inode->atime = 0;
+ inode->mtime = 100;
+ inode->ctime = 10000;
+#endif
+ DBUG_RETURN(retval);
+}
+
+
+static CorbaFS_DirEntSeq *
+impl_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * path, CORBA_Environment * ev)
+{
+ CorbaFS_DirEntSeq *retval;
+ CorbaFS_dirent *dirent;
+
+ struct func_st *func;
+ int c, c2,i;
+ char
+ server[BUFLEN],
+ table[BUFLEN],
+ field[BUFLEN],
+ value[BUFLEN],
+ buffer[MAXDIRS][BUFLEN],
+ buffer2[MAXDIRS][BUFLEN],
+ database[BUFLEN];
+
+ DBUG_ENTER("impl_FileSystem_readdir");
+ DBUG_PRINT("enter",("path: '%s'", path));
+ retval = CorbaFS_DirEntSeq__alloc();
+ retval->_maximum = 0;
+ retval->_length = 0;
+
+ parse(path, server, database, table, field, value, &func);
+ if (func != NULL) {
+ c2 = db_function((char *)buffer, server, database, table, field, value, path, func);
+ } else if(!*server) {
+ c2 = db_show_servers(buffer2,MAXDIRS);
+ c = show_functions((char *)buffer, ROOT_FUNCTION);
+ } else if(!*database) {
+ c2 = db_show_databases(buffer2,MAXDIRS);
+ c = show_functions((char *)buffer, SERVER_FUNCTION);
+ } else if(!*table){
+ c2 = db_show_tables(buffer2, database);
+ c = show_functions((char *)buffer, DATABASE_FUNCTION);
+ } else if(!*field){
+ c2 = db_show_primary_keys(buffer2, database,table);
+ if(c2>=0) {
+ c = show_functions((char *)buffer, TABLE_FUNCTION);
+ }
+ } else {
+ c2 = db_show_fields(buffer2, database, table, field);
+ c = show_functions((char *)buffer, FIELD_FUNCTION);
+ c = show_functions((char *)buffer, KEY_FUNCTION);
+ }
+ if(c2 < 0)
+ c=c2=0; // Error occured in database routines
+
+ /* Allocate space to hold all found entries plus "." and ".." */
+ retval->_maximum = c + c2 + 2;
+ retval->_buffer = CORBA_sequence_CorbaFS_dirent_allocbuf(retval->_maximum) ;
+ dirent = retval->_buffer;
+
+ i = 0;
+ while (i < c) {
+ long inode = 123L;
+ dirent[i].inode = inode;
+ dirent[i].name = CORBA_string_dup(buffer[i]);
+ i++;
+ }
+ i = 0;
+ while (i < c2) {
+ long inode = 123L;
+ dirent[c+i].inode = inode;
+ dirent[c+i].name = CORBA_string_dup(buffer2[i]);
+ i++;
+ }
+ dirent[c+i].inode = 123L;
+ dirent[c+i].name = CORBA_string_dup(".");
+ i++;
+ dirent[c+i].inode = 123L;
+ dirent[c+i].name = CORBA_string_dup("..");
+
+ retval->_length = retval->_maximum;
+ DBUG_RETURN(retval);
+}
+
+static CORBA_char *
+impl_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * filename,
+ CORBA_Environment * ev)
+{
+ CORBA_char *retval = CORBA_OBJECT_NIL;
+ char tmp[MAXPATHLEN + 1];
+ int len;
+
+ DBUG_ENTER("impl_FileSystem_readlink");
+ DBUG_PRINT("enter",("path: '%s'", filename));
+
+/* len = readlink(filename, tmp, MAXPATHLEN);
+ if (len != -1)
+ {
+ tmp[len] = '\0';
+ retval = CORBA_string_dup(tmp);
+ }
+
+ printf("%s\n", retval);
+ */
+ DBUG_RETURN(retval);
+}
+
+int fix_filenames(char *buf)
+{
+ int i;
+ for(i=0; i<strlen(buf);i++)
+ if(buf[i]=='/')
+ buf[i]='_';
+}
+
+int main(int argc, char *argv[]) {
+ CorbaFS_FileSystem fs;
+ impl_POA_CorbaFS_FileSystem *fs_impl;
+ FILE *f;
+ PortableServer_POAManager pm;
+
+ DBUG_ENTER("main");
+ DBUG_PROCESS(argv[0]);
+ ev = g_new0(CORBA_Environment,1);
+ CORBA_exception_init(ev);
+ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", ev);
+ MY_INIT(argv[0]);
+
+ /*
+ ** Check out the args
+ */
+ if (get_options(&argc, &argv))
+ {
+ my_end(0);
+ exit(EX_USAGE);
+ }
+ if (db_connect(current_host, current_user, opt_password))
+ exit(EX_MYSQLERR);
+ fptr = db_load_functions();
+ db_load_formats();
+ poa = (PortableServer_POA)
+ CORBA_ORB_resolve_initial_references(orb, "RootPOA", ev);
+ fs = impl_FileSystem__create(poa, ev);
+
+ pm = PortableServer_POA__get_the_POAManager(poa, ev);
+ PortableServer_POAManager_activate(pm, ev);
+
+ fs_impl = PortableServer_POA_reference_to_servant( poa, fs, ev );
+ objid = PortableServer_POA_servant_to_id( poa, fs_impl, ev );
+ printf("CorbaFS-server:\n%s\n", CORBA_ORB_object_to_string(orb, fs, ev));
+ f=fopen("/tmp/mysqlcorbafs.ior","w");
+ fputs(CORBA_ORB_object_to_string(orb, fs, ev),f);
+ fclose(f);
+ CORBA_ORB_run(orb, ev);
+ db_disconnect(current_host);
+
+ return 0;
+}
diff --git a/fs/mysqlcorbafs.h b/fs/mysqlcorbafs.h
new file mode 100644
index 00000000000..f805a1fb584
--- /dev/null
+++ b/fs/mysqlcorbafs.h
@@ -0,0 +1,157 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "CorbaFS.h"
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+
+#define QUOTE_CHAR '`'
+/* Exit codes */
+
+#define EX_USAGE 1
+#define EX_MYSQLERR 2
+#define EX_CONSCHECK 3
+#define EX_EOM 4
+
+#define CORBAFS_VERSION "0.01"
+
+typedef struct
+{
+ POA_CorbaFS_Inode servant;
+ PortableServer_POA poa;
+
+ CORBA_char *path;
+ CORBA_unsigned_long inodeNum;
+#if 0
+ CORBA_unsigned_short mode;
+ CORBA_unsigned_long uid;
+ CORBA_unsigned_long gid;
+ CORBA_unsigned_long size;
+ CORBA_unsigned_short numLinks;
+ CORBA_long atime;
+ CORBA_long mtime;
+ CORBA_long ctime;
+#endif
+}
+impl_POA_CorbaFS_Inode;
+
+typedef struct
+{
+ POA_CorbaFS_FileSystem servant;
+ PortableServer_POA poa;
+
+}
+impl_POA_CorbaFS_FileSystem;
+
+/*** Implementation stub prototypes ***/
+CorbaFS_FileSystem
+impl_FileSystem__create(PortableServer_POA poa, CORBA_Environment * ev);
+
+static void
+impl_Inode__destroy(impl_POA_CorbaFS_Inode * servant,
+ CORBA_Environment * ev);
+static void
+impl_Inode_getStatus(impl_POA_CorbaFS_Inode * servant,
+ CORBA_unsigned_short * mode,
+ CORBA_unsigned_long * uid,
+ CORBA_unsigned_long * gid,
+ CORBA_unsigned_long * size,
+ CORBA_unsigned_long * inodeNum,
+ CORBA_unsigned_short * numLinks,
+ CORBA_long * atime,
+ CORBA_long * mtime,
+ CORBA_long * ctime, CORBA_Environment * ev);
+
+static void
+impl_Inode_readpage(impl_POA_CorbaFS_Inode * servant,
+ CorbaFS_Buffer ** buffer,
+ CORBA_long size,
+ CORBA_long offset, CORBA_Environment * ev);
+
+static void
+impl_Inode_release(impl_POA_CorbaFS_Inode * servant,
+ CORBA_Environment * ev);
+
+static void impl_FileSystem__destroy(impl_POA_CorbaFS_FileSystem *
+ servant, CORBA_Environment * ev);
+
+static CorbaFS_Inode
+impl_FileSystem_getInode(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * path, CORBA_Environment * ev);
+
+static CorbaFS_DirEntSeq *
+impl_FileSystem_readdir(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * path,
+ CORBA_Environment * ev);
+
+static CORBA_char *
+impl_FileSystem_readlink(impl_POA_CorbaFS_FileSystem * servant,
+ CORBA_char * filename,
+ CORBA_Environment * ev);
+
+static my_bool verbose,opt_compress;
+static uint opt_mysql_port=0;
+static my_string opt_mysql_unix_port=0;
+static int first_error=0;
+static MYSQL connection, *sock=0;
+
+extern uint opt_mysql_port;
+extern my_string opt_mysql_unix_port,host,user,password;
+
+
+
+static struct format {
+ char *tablestart;
+
+ char *headerrowstart;
+ char *headercellstart;
+ char *headercellseparator;
+ char *headercellend;
+ char *headerrowend;
+ int headerformat; /* 0 - simple, 1 - left padded, 2 - right padded */
+
+ char *contentrowstart;
+ char *contentcellstart;
+ char *contentcellseparator;
+ char *contentcellend;
+ char *contentrowend;
+ int contentformat;
+
+ char *footerrowstart;
+ char *footercellstart;
+ char *footercellseparator;
+ char *footercellend;
+ char *footerrowend;
+ int footerformat;
+
+ char *tableend;
+
+ char *leftuppercorner;
+ char *rightuppercorner;
+ char *leftdowncorner;
+ char *rightdowncorner;
+ char *leftcross;
+ char *rightcross;
+ char *topcross;
+ char *middlecross;
+ char *bottomcross;
+
+
+} Human, HTML, CSF, XML;
diff --git a/fs/mysqlcorbafs_test.c b/fs/mysqlcorbafs_test.c
new file mode 100644
index 00000000000..bd7d9381744
--- /dev/null
+++ b/fs/mysqlcorbafs_test.c
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <orb/orbit.h>
+
+#include "CorbaFS.h"
+
+CorbaFS_FileSystem fs;
+
+int
+main (int argc, char *argv[])
+{
+ CORBA_Environment ev;
+ CORBA_ORB orb;
+ CorbaFS_Inode inode;
+ CorbaFS_Buffer *buffer;
+ CorbaFS_DirEntSeq *dirents;
+ CorbaFS_dirent *dirent;
+
+ CORBA_unsigned_short mode;
+ CORBA_unsigned_long uid;
+ CORBA_unsigned_long gid;
+ CORBA_unsigned_long size;
+ CORBA_unsigned_long inodeNum;
+ CORBA_unsigned_short numLinks;
+ CORBA_long atime;
+ CORBA_long mtime;
+ CORBA_long ctime;
+
+ int i;
+
+ int niters = 10;
+
+ CORBA_exception_init(&ev);
+ orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
+
+ if(argc < 2)
+ {
+ printf("Need a binding ID thing as argv[1]\n");
+ return 1;
+ }
+
+
+ fs = CORBA_ORB_string_to_object(orb, argv[1], &ev);
+ if (!fs) {
+ printf("Cannot bind to %s\n", argv[1]);
+ return 1;
+ }
+
+ if (argc >= 3)
+ inode = CorbaFS_FileSystem_getInode(fs, argv[2], &ev);
+ else
+ inode = CorbaFS_FileSystem_getInode(fs, "/proc/cpuinfo", &ev);
+
+ if (!inode)
+ {
+ printf("Cannot get inode\n");
+ }
+
+ CorbaFS_Inode_getStatus(inode,
+ &mode,
+ &uid,
+ &gid,
+ &size,
+ &inodeNum,
+ &numLinks,
+ &atime,
+ &mtime,
+ &ctime,
+ &ev);
+
+ printf("inode = %x\n", inode);
+ CorbaFS_Inode_readpage(inode, &buffer, 100000, 100, &ev);
+ printf("readpage got %d bytes\n", buffer->_length);
+ printf("readpage returned : %s\n", buffer->_buffer);
+
+ if (argc >= 3)
+ dirents = CorbaFS_FileSystem_readdir(fs, argv[2], &ev);
+ else
+ dirents = CorbaFS_FileSystem_readdir(fs, "/", &ev);
+
+ dirent = dirents->_buffer;
+ for (i = 0; i < dirents->_length; i++)
+ {
+ printf("%d = %s\n", dirent->inode, dirent->name);
+ dirent++;
+ }
+
+ CORBA_Object_release(fs, &ev);
+ CORBA_Object_release((CORBA_Object)orb, &ev);
+
+ return 0;
+}
diff --git a/fs/mysqlfsck b/fs/mysqlfsck
new file mode 100755
index 00000000000..7b4e049b1e3
--- /dev/null
+++ b/fs/mysqlfsck
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+mountpoint=$*
+
+if [#($mountpoint) -eq "0"];
+then
+ exit;
+fi
+
+
+
diff --git a/heap/_check.c b/heap/_check.c
index e22eb5e7e4a..6cc19aba137 100644
--- a/heap/_check.c
+++ b/heap/_check.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,19 +21,70 @@
static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
ulong blength, my_bool print_status);
-/* Returns 0 if the HEAP is ok */
+/*
+ Check if keys and rows are ok in a heap table
+
+ SYNOPSIS
+ heap_check_heap()
+ info Table handler
+ print_status Prints some extra status
+
+ NOTES
+ Doesn't change the state of the table handler
+
+ RETURN VALUES
+ 0 ok
+ 1 error
+*/
int heap_check_heap(HP_INFO *info,my_bool print_status)
{
int error;
uint key;
+ ulong records=0, deleted=0, pos, next_block;
HP_SHARE *share=info->s;
- DBUG_ENTER("heap_check_keys");
+ HP_INFO save_info= *info; /* Needed because scan_init */
+ DBUG_ENTER("heap_check_heap");
- for (error=key=0 ; key < share->keys ; key++)
+ for (error=key= 0 ; key < share->keys ; key++)
error|=check_one_key(share->keydef+key,key, share->records,share->blength,
print_status);
+ /*
+ This is basicly the same code as in hp_scan, but we repeat it here to
+ get shorter DBUG log file.
+ */
+ for (pos=next_block= 0 ; ; pos++)
+ {
+ if (pos < next_block)
+ {
+ info->current_ptr+= share->block.recbuffer;
+ }
+ else
+ {
+ next_block+= share->block.records_in_block;
+ if (next_block >= share->records+share->deleted)
+ {
+ next_block= share->records+share->deleted;
+ if (pos >= next_block)
+ break; /* End of file */
+ }
+ }
+ _hp_find_record(info,pos);
+
+ if (!info->current_ptr[share->reclength])
+ deleted++;
+ else
+ records++;
+ }
+
+ if (records != share->records || deleted != share->deleted)
+ {
+ DBUG_PRINT("error",("Found rows: %lu (%lu) deleted %lu (%lu)",
+ records, share->records, deleted, share->deleted));
+ error= 1;
+ }
+ *info= save_info;
DBUG_RETURN(error);
}
@@ -79,9 +130,11 @@ static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
}
DBUG_PRINT("info",
("records: %ld seeks: %d max links: %d hitrate: %.2f",
- records,seek,max_links,(float) seek / (float) (records ? records : 1)));
+ records,seek,max_links,
+ (float) seek / (float) (records ? records : 1)));
if (print_status)
printf("Key: %d records: %ld seeks: %d max links: %d hitrate: %.2f\n",
- keynr, records, seek, max_links, (float) seek / (float) records);
+ keynr, records, seek, max_links,
+ (float) seek / (float) (records ? records : 1));
return error;
}
diff --git a/heap/_rectest.c b/heap/_rectest.c
index 3368fbeeffa..522940286fd 100644
--- a/heap/_rectest.c
+++ b/heap/_rectest.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/heapdef.h b/heap/heapdef.h
index 6b85e234c5e..ef55cf5efd2 100644
--- a/heap/heapdef.h
+++ b/heap/heapdef.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -81,6 +81,7 @@ extern int _hp_rec_key_cmp(HP_KEYDEF *keydef,const byte *rec1,
extern int _hp_key_cmp(HP_KEYDEF *keydef,const byte *rec,
const byte *key);
extern void _hp_make_key(HP_KEYDEF *keydef,byte *key,const byte *rec);
+extern my_bool hp_if_null_in_key(HP_KEYDEF *keyinfo, const byte *record);
extern int _hp_close(register HP_INFO *info);
extern void _hp_clear(HP_SHARE *info);
diff --git a/heap/hp_block.c b/heap/hp_block.c
index 510d89d6d1e..5c052218e58 100644
--- a/heap/hp_block.c
+++ b/heap/hp_block.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_clear.c b/heap/hp_clear.c
index 702c2e09d29..2dcf91c03d7 100644
--- a/heap/hp_clear.c
+++ b/heap/hp_clear.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -44,7 +44,7 @@ void _hp_clear(HP_SHARE *info)
block->levels=0;
block->last_allocated=0;
}
- info->records=info->deleted=info->data_length=info->index_length=0;;
+ info->records=info->deleted=info->data_length=info->index_length=0;
info->blength=1;
info->changed=0;
info->del_link=0;
diff --git a/heap/hp_close.c b/heap/hp_close.c
index 583602e98cb..9e7d9ab31d1 100644
--- a/heap/hp_close.c
+++ b/heap/hp_close.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -19,7 +19,7 @@
#include "heapdef.h"
/* Close a database open by hp_open() */
- /* Data is not deallocated */
+ /* Data is normally not deallocated */
int heap_close(HP_INFO *info)
{
@@ -43,9 +43,9 @@ int _hp_close(register HP_INFO *info)
}
#endif
info->s->changed=0;
- info->s->open_count--;
heap_open_list=list_delete(heap_open_list,&info->open_list);
+ if (!--info->s->open_count && info->s->delete_on_close)
+ _hp_free(info->s); /* Table was deleted */
my_free((gptr) info,MYF(0));
DBUG_RETURN(error);
}
-
diff --git a/heap/hp_create.c b/heap/hp_create.c
index 01c5f43adfd..1307fab1d12 100644
--- a/heap/hp_create.c
+++ b/heap/hp_create.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,33 +21,49 @@
#include "heapdef.h"
+
int heap_create(const char *name)
{
+ reg1 HP_SHARE *share;
DBUG_ENTER("heap_create");
- (void) heap_delete_all(name);
+ pthread_mutex_lock(&THR_LOCK_heap);
+ if ((share=_hp_find_named_heap(name)))
+ {
+ if (share->open_count == 0)
+ _hp_free(share);
+ }
+ else
+ {
+ my_errno=ENOENT;
+ }
+ pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0);
}
-int heap_delete_all(const char *name)
+int heap_delete_table(const char *name)
{
- reg1 HP_SHARE *info;
- int found;
- DBUG_ENTER("heap_delete_all");
+ int result;
+ reg1 HP_SHARE *share;
+ DBUG_ENTER("heap_delete_table");
+
pthread_mutex_lock(&THR_LOCK_heap);
- if ((info=_hp_find_named_heap(name)))
+ if ((share=_hp_find_named_heap(name)))
{
- if (info->open_count == 0)
- _hp_free(info);
- found=0;
+ if (share->open_count == 0)
+ _hp_free(share);
+ else
+ share->delete_on_close=1;
+ result=0;
}
else
{
- found=my_errno=ENOENT;
+ result=my_errno=ENOENT;
}
pthread_mutex_unlock(&THR_LOCK_heap);
- DBUG_RETURN(found);
+ DBUG_RETURN(result);
}
+
void _hp_free(HP_SHARE *share)
{
heap_share_list=list_delete(heap_share_list,&share->open_list);
diff --git a/heap/hp_delete.c b/heap/hp_delete.c
index a6e77fe5f27..6ed6a045543 100644
--- a/heap/hp_delete.c
+++ b/heap/hp_delete.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -48,9 +48,14 @@ int heap_delete(HP_INFO *info, const byte *record)
pos[share->reclength]=0; /* Record deleted */
share->deleted++;
info->current_hash_ptr=0;
+#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
+ DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
+#endif
+
DBUG_RETURN(0);
err:
- if( ++(share->records) == share->blength) share->blength+= share->blength;
+ if (++(share->records) == share->blength)
+ share->blength+= share->blength;
DBUG_RETURN(my_errno);
}
@@ -66,7 +71,8 @@ int _hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
DBUG_ENTER("_hp_delete_key");
blength=share->blength;
- if (share->records+1 == blength) blength+= blength;
+ if (share->records+1 == blength)
+ blength+= blength;
lastpos=hp_find_hash(&keyinfo->block,share->records);
last_ptr=0;
diff --git a/heap/hp_extra.c b/heap/hp_extra.c
index 133be01c676..46e3f529f34 100644
--- a/heap/hp_extra.c
+++ b/heap/hp_extra.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_hash.c b/heap/hp_hash.c
index eb35b947871..e29e51d2b75 100644
--- a/heap/hp_hash.c
+++ b/heap/hp_hash.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -158,11 +158,22 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
{
uchar *pos=(uchar*) key;
key+=seg->length;
+ if (seg->null_bit)
+ {
+ key++; /* Skipp null byte */
+ if (*pos) /* Found null */
+ {
+ nr^= (nr << 1) | 1;
+ continue;
+ }
+ pos++;
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
for (; pos < (uchar*) key ; pos++)
{
- nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) my_sort_order[(uint) *pos]))+ (nr << 8);
+ nr^=(ulong) ((((uint) nr & 63)+nr2) *
+ ((uint) my_sort_order[(uint) *pos])) + (nr << 8);
nr2+=3;
}
}
@@ -170,7 +181,7 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
{
for (; pos < (uchar*) key ; pos++)
{
- nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8);
+ nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8);
nr2+=3;
}
}
@@ -188,11 +199,20 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{
uchar *pos=(uchar*) rec+seg->start,*end=pos+seg->length;
+ if (seg->null_bit)
+ {
+ if (rec[seg->null_pos] & seg->null_bit)
+ {
+ nr^= (nr << 1) | 1;
+ continue;
+ }
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
for (; pos < end ; pos++)
{
- nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) my_sort_order[(uint) *pos]))+ (nr << 8);
+ nr^=(ulong) ((((uint) nr & 63)+nr2)*
+ ((uint) my_sort_order[(uint) *pos]))+ (nr << 8);
nr2+=3;
}
}
@@ -234,6 +254,16 @@ ulong _hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
{
uchar *pos=(uchar*) key;
key+=seg->length;
+ if (seg->null_bit)
+ {
+ key++;
+ if (*pos)
+ {
+ nr^= (nr << 1) | 1;
+ continue;
+ }
+ pos++;
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
for (; pos < (uchar*) key ; pos++)
@@ -264,6 +294,14 @@ ulong _hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{
uchar *pos=(uchar*) rec+seg->start,*end=pos+seg->length;
+ if (seg->null_bit)
+ {
+ if (rec[seg->null_pos] & seg->null_bit)
+ {
+ nr^= (nr << 1) | 1;
+ continue;
+ }
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
for ( ; pos < end ; pos++)
@@ -295,6 +333,14 @@ int _hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{
+ if (seg->null_bit)
+ {
+ if ((rec1[seg->null_pos] & seg->null_bit) !=
+ (rec2[seg->null_pos] & seg->null_bit))
+ return 1;
+ if (rec1[seg->null_pos] & seg->null_bit)
+ continue;
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
if (my_sortcmp(rec1+seg->start,rec2+seg->start,seg->length))
@@ -309,14 +355,24 @@ int _hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
return 0;
}
- /* Compare a key in a record to a hole key */
+ /* Compare a key in a record to a whole key */
int _hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
{
HP_KEYSEG *seg,*endseg;
- for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
+ for (seg=keydef->seg,endseg=seg+keydef->keysegs ;
+ seg < endseg ;
+ key+= (seg++)->length)
{
+ if (seg->null_bit)
+ {
+ int found_null=test(rec[seg->null_pos] & seg->null_bit);
+ if (found_null != (int) *key++)
+ return 1;
+ if (found_null)
+ continue;
+ }
if (seg->type == HA_KEYTYPE_TEXT)
{
if (my_sortcmp(rec+seg->start,key,seg->length))
@@ -327,7 +383,6 @@ int _hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
if (bcmp(rec+seg->start,key,seg->length))
return 1;
}
- key+=seg->length;
}
return 0;
}
@@ -341,7 +396,28 @@ void _hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec)
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
{
+ if (seg->null_bit)
+ *key++= test(rec[seg->null_pos] & seg->null_bit);
memcpy(key,rec+seg->start,(size_t) seg->length);
key+=seg->length;
}
}
+
+
+/*
+ Test if any of the key parts are NULL.
+ Return:
+ 1 if any of the key parts was NULL
+ 0 otherwise
+*/
+
+my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record)
+{
+ HP_KEYSEG *seg,*endseg;
+ for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
+ {
+ if (seg->null_bit && (record[seg->null_pos] & seg->null_bit))
+ return 1;
+ }
+ return 0;
+}
diff --git a/heap/hp_info.c b/heap/hp_info.c
index 379f4d9ec0f..c8cdfc58c2d 100644
--- a/heap/hp_info.c
+++ b/heap/hp_info.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -48,12 +48,13 @@ int heap_info(reg1 HP_INFO *info,reg2 HEAPINFO *x,
int flag __attribute__((unused)))
{
DBUG_ENTER("heap_info");
- x->records = info->s->records;
- x->deleted = info->s->deleted;
- x->reclength = info->s->reclength;
- x->data_length = info->s->data_length;
- x->index_length= info->s->index_length;
- x->max_records = info->s->max_records;
- x->errkey = info->errkey;
+ x->records = info->s->records;
+ x->deleted = info->s->deleted;
+ x->reclength = info->s->reclength;
+ x->data_length = info->s->data_length;
+ x->index_length = info->s->index_length;
+ x->max_records = info->s->max_records;
+ x->errkey = info->errkey;
+ x->implicit_emptied= info->implicit_emptied;
DBUG_RETURN(0);
} /* heap_info */
diff --git a/heap/hp_open.c b/heap/hp_open.c
index e0615879193..3bf2881667a 100644
--- a/heap/hp_open.c
+++ b/heap/hp_open.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -30,6 +30,7 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
uint reclength, ulong max_records, ulong min_records)
{
uint i,j,key_segs,max_length,length;
+ my_bool implicit_emptied= 0;
HP_INFO *info;
HP_SHARE *share;
HP_KEYSEG *keyseg;
@@ -39,12 +40,21 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
if (!(share=_hp_find_named_heap(name)))
{
DBUG_PRINT("info",("Initializing new table"));
+ implicit_emptied= 1;
for (i=key_segs=max_length=0 ; i < keys ; i++)
{
key_segs+= keydef[i].keysegs;
bzero((char*) &keydef[i].block,sizeof(keydef[i].block));
for (j=length=0 ; j < keydef[i].keysegs; j++)
+ {
length+=keydef[i].seg[j].length;
+ if (keydef[i].seg[j].null_bit)
+ {
+ length++;
+ if (!(keydef[i].flag & HA_NULL_ARE_EQUAL))
+ keydef[i].flag |= HA_NULL_PART_KEY;
+ }
+ }
keydef[i].length=length;
if (length > max_length)
max_length=length;
@@ -119,6 +129,7 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
#ifndef DBUG_OFF
info->opt_flag=READ_CHECK_USED; /* Check when changing */
#endif
+ info->implicit_emptied= implicit_emptied;
DBUG_PRINT("exit",("heap: %lx reclength: %d records_in_block: %d",
info,share->reclength,share->block.records_in_block));
DBUG_RETURN(info);
diff --git a/heap/hp_panic.c b/heap/hp_panic.c
index cfd370a56d0..4b93190b7e1 100644
--- a/heap/hp_panic.c
+++ b/heap/hp_panic.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rename.c b/heap/hp_rename.c
index 267c16b589d..118c5931f43 100644
--- a/heap/hp_rename.c
+++ b/heap/hp_rename.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rfirst.c b/heap/hp_rfirst.c
index e3b9654061d..9a1f09244a0 100644
--- a/heap/hp_rfirst.c
+++ b/heap/hp_rfirst.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rkey.c b/heap/hp_rkey.c
index 157267f7149..e7a1d81fba6 100644
--- a/heap/hp_rkey.c
+++ b/heap/hp_rkey.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,7 +20,7 @@ int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key)
{
byte *pos;
HP_SHARE *share=info->s;
- DBUG_ENTER("hp_rkey");
+ DBUG_ENTER("heap_rkey");
DBUG_PRINT("enter",("base: %lx inx: %d",info,inx));
if ((uint) inx >= share->keys)
diff --git a/heap/hp_rlast.c b/heap/hp_rlast.c
index 38e07fde2bb..463b6dc9aac 100644
--- a/heap/hp_rlast.c
+++ b/heap/hp_rlast.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rnext.c b/heap/hp_rnext.c
index 6aa3cf06d97..af08a0e68a2 100644
--- a/heap/hp_rnext.c
+++ b/heap/hp_rnext.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -23,7 +23,7 @@ int heap_rnext(HP_INFO *info, byte *record)
byte *pos;
HP_SHARE *share=info->s;
DBUG_ENTER("heap_rnext");
-
+
if (info->lastinx < 0)
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
diff --git a/heap/hp_rprev.c b/heap/hp_rprev.c
index 28a821c143e..c7c649e6b9f 100644
--- a/heap/hp_rprev.c
+++ b/heap/hp_rprev.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rrnd.c b/heap/hp_rrnd.c
index 63181967a29..78abebcaf47 100644
--- a/heap/hp_rrnd.c
+++ b/heap/hp_rrnd.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_rsame.c b/heap/hp_rsame.c
index 888fb349f5a..a346707641b 100644
--- a/heap/hp_rsame.c
+++ b/heap/hp_rsame.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_scan.c b/heap/hp_scan.c
index b7684cd2673..0bbe40ba773 100644
--- a/heap/hp_scan.c
+++ b/heap/hp_scan.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -62,6 +62,7 @@ int heap_scan(register HP_INFO *info, byte *record)
}
if (!info->current_ptr[share->reclength])
{
+ DBUG_PRINT("warning",("Found deleted record"));
info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND;
DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
}
diff --git a/heap/hp_static.c b/heap/hp_static.c
index 5e5326ca76b..a458b742b9c 100644
--- a/heap/hp_static.c
+++ b/heap/hp_static.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/heap/hp_test1.c b/heap/hp_test1.c
index f44752af3bc..e07af2761f0 100644
--- a/heap/hp_test1.c
+++ b/heap/hp_test1.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,7 +20,7 @@
raderas.
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include "heap.h"
diff --git a/heap/hp_test2.c b/heap/hp_test2.c
index a76aa19e082..36016797447 100644
--- a/heap/hp_test2.c
+++ b/heap/hp_test2.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -30,7 +30,7 @@
#include <signal.h>
#define MAX_RECORDS 100000
-#define MAX_KEYS 3
+#define MAX_KEYS 4
static int get_options(int argc, char *argv[]);
static int rnd(int max_value);
@@ -40,16 +40,20 @@ static uint flag=0,verbose=0,testflag=0,recant=10000,silent=0;
static uint keys=MAX_KEYS;
static uint16 key1[1001];
static my_bool key3[MAX_RECORDS];
+static int reclength=39;
+
static int calc_check(byte *buf,uint length);
+static void make_record(char *record, uint n1, uint n2, uint n3,
+ const char *mark, uint count);
- /* Huvudprogrammet */
+/* Main program */
int main(int argc, char *argv[])
{
register uint i,j;
uint ant,n1,n2,n3;
- uint reclength,write_count,update,opt_delete,check2,dupp_keys,found_key;
+ uint write_count,update,opt_delete,check2,dupp_keys,found_key;
int error;
ulong pos;
unsigned long key_check;
@@ -66,7 +70,6 @@ int main(int argc, char *argv[])
filename2= "test2_2";
file=file2=0;
get_options(argc,argv);
- reclength=37;
write_count=update=opt_delete=0;
key_check=0;
@@ -77,21 +80,33 @@ int main(int argc, char *argv[])
keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[0].seg[0].start=0;
keyinfo[0].seg[0].length=6;
+ keyinfo[0].seg[0].null_bit=0;
keyinfo[1].seg=keyseg+1;
keyinfo[1].keysegs=2;
keyinfo[1].flag=0;
keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[1].seg[0].start=7;
keyinfo[1].seg[0].length=6;
+ keyinfo[1].seg[0].null_bit=0;
keyinfo[1].seg[1].type=HA_KEYTYPE_TEXT;
- keyinfo[1].seg[1].start=0; /* Tv}delad nyckel */
+ keyinfo[1].seg[1].start=0; /* key in two parts */
keyinfo[1].seg[1].length=6;
+ keyinfo[1].seg[1].null_bit=0;
keyinfo[2].seg=keyseg+3;
keyinfo[2].keysegs=1;
keyinfo[2].flag=HA_NOSAME;
keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY;
keyinfo[2].seg[0].start=12;
keyinfo[2].seg[0].length=8;
+ keyinfo[2].seg[0].null_bit=0;
+ keyinfo[3].keysegs=1;
+ keyinfo[3].flag=HA_NOSAME;
+ keyinfo[3].seg=keyseg+4;
+ keyinfo[3].seg[0].type=HA_KEYTYPE_BINARY;
+ keyinfo[3].seg[0].start=37;
+ keyinfo[3].seg[0].length=1;
+ keyinfo[3].seg[0].null_bit=1;
+ keyinfo[3].seg[0].null_pos=38;
bzero((char*) key1,sizeof(key1));
bzero((char*) key3,sizeof(key3));
@@ -110,7 +125,7 @@ int main(int argc, char *argv[])
for (i=0 ; i < recant ; i++)
{
n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
- sprintf(record,"%6d:%4d:%8d:Pos: %4d ",n1,n2,n3,write_count);
+ make_record(record,n1,n2,n3,"Pos",write_count);
if (heap_write(file,record))
{
@@ -191,7 +206,7 @@ int main(int argc, char *argv[])
for (i=0 ; i < write_count/10 ; i++)
{
n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
- sprintf(record2,"%6d:%4d:%8d:XXX: %4d ",n1,n2,n3,update);
+ make_record(record2, n1, n2, n3, "XXX", update);
if (rnd(2) == 1)
{
if (heap_scan_init(file))
@@ -222,12 +237,12 @@ int main(int argc, char *argv[])
{
if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
{
- printf("error: %d; can't uppdate:\nFrom: \"%s\"\nTo: \"%s\"\n",
+ printf("error: %d; can't update:\nFrom: \"%s\"\nTo: \"%s\"\n",
my_errno,record,record2);
goto err;
}
if (verbose)
- printf("Double key when tryed to uppdate:\nFrom: \"%s\"\nTo: \"%s\"\n",record,record2);
+ printf("Double key when tried to update:\nFrom: \"%s\"\nTo: \"%s\"\n",record,record2);
}
else
{
@@ -572,7 +587,7 @@ end:
heap_clear(file);
if (heap_close(file) || (file2 && heap_close(file2)))
goto err;
- heap_delete_all(filename2);
+ heap_delete_table(filename2);
heap_panic(HA_PANIC_CLOSE);
my_end(MY_GIVE_INFO);
return(0);
@@ -654,3 +669,13 @@ static int calc_check(byte *buf, uint length)
check+= (int) (uchar) *(buf++);
return check;
}
+
+static void make_record(char *record, uint n1, uint n2, uint n3,
+ const char *mark, uint count)
+{
+ bfill(record,reclength,' ');
+ sprintf(record,"%6d:%4d:%8d:%3.3s: %4d",
+ n1,n2,n3,mark,count);
+ record[37]='A'; /* Store A in null key */
+ record[38]=1; /* set as null */
+}
diff --git a/heap/hp_update.c b/heap/hp_update.c
index a1d9c51e9dd..b0a1926e14a 100644
--- a/heap/hp_update.c
+++ b/heap/hp_update.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -46,6 +46,10 @@ int heap_update(HP_INFO *info, const byte *old, const byte *heap_new)
memcpy(pos,heap_new,(size_t) share->reclength);
if (++(share->records) == share->blength) share->blength+= share->blength;
+
+#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
+ DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
+#endif
DBUG_RETURN(0);
err:
diff --git a/heap/hp_write.c b/heap/hp_write.c
index 12b5c638f78..18fa95e7760 100644
--- a/heap/hp_write.c
+++ b/heap/hp_write.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -60,8 +60,13 @@ int heap_write(HP_INFO *info, const byte *record)
info->current_ptr=pos;
info->current_hash_ptr=0;
info->update|=HA_STATE_AKTIV;
+#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
+ DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
+#endif
DBUG_RETURN(0);
+
err:
+ DBUG_PRINT("info",("Duplicate key: %d",key));
info->errkey= key;
do
{
@@ -73,6 +78,7 @@ err:
*((byte**) pos)=share->del_link;
share->del_link=pos;
pos[share->reclength]=0; /* Record deleted */
+
DBUG_RETURN(my_errno);
} /* heap_write */
@@ -237,8 +243,10 @@ int _hp_write_key(register HP_SHARE *info, HP_KEYDEF *keyinfo,
_hp_movelink(pos,gpos,empty);
}
- /* Check if dupplicated keys */
- if ((keyinfo->flag & HA_NOSAME) && pos == gpos)
+ /* Check if duplicated keys */
+ if ((keyinfo->flag & HA_NOSAME) && pos == gpos &&
+ (!(keyinfo->flag & HA_NULL_PART_KEY) ||
+ !hp_if_null_in_key(keyinfo, record)))
{
pos=empty;
do
diff --git a/include/Makefile.am b/include/Makefile.am
index 393dac3fd82..4b881d0e7ed 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -16,28 +16,27 @@
# MA 02111-1307, USA
BUILT_SOURCES = mysql_version.h m_ctype.h my_config.h
-pkginclude_HEADERS = dbug.h m_string.h my_sys.h mysql.h mysql_com.h \
- mysqld_error.h my_list.h \
- my_pthread.h my_no_pthread.h raid.h errmsg.h \
- my_global.h my_net.h \
- sslopt-case.h sslopt-longopts.h sslopt-usage.h \
- sslopt-vars.h $(BUILT_SOURCES)
-noinst_HEADERS = global.h config-win.h config-os2.h\
+pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h \
+ mysql.h mysql_com.h mysqld_error.h mysql_embed.h \
+ my_semaphore.h my_pthread.h my_no_pthread.h raid.h \
+ errmsg.h my_global.h my_net.h my_alloc.h \
+ my_getopt.h sslopt-longopts.h my_dir.h \
+ sslopt-vars.h sslopt-case.h $(BUILT_SOURCES)
+noinst_HEADERS = config-win.h config-os2.h config-netware.h \
nisam.h heap.h merge.h my_bitmap.h\
myisam.h myisampack.h myisammrg.h ft_global.h\
- my_dir.h mysys_err.h my_base.h \
- my_nosys.h my_alarm.h queues.h \
- my_tree.h hash.h thr_alarm.h thr_lock.h \
- getopt.h t_ctype.h violite.h \
- mysql_version.h.in
+ mysys_err.h my_base.h \
+ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \
+ my_aes.h my_tree.h hash.h thr_alarm.h \
+ thr_lock.h t_ctype.h violite.h md5.h mysql_version.h.in
# mysql_version.h are generated
-SUPERCLEANFILES = mysql_version.h my_global.h my_config.h
+SUPERCLEANFILES = mysql_version.h my_config.h
# Some include files that may be moved and patched by configure
-DISTCLEANFILES = sched.h
+DISTCLEANFILES = sched.h $(SUPERCLEANFILES)
-all-local: my_global.h my_config.h
+all-local: my_config.h
# Since we include my_config.h it better exist from the beginning
link_sources:
@@ -48,11 +47,6 @@ link_sources:
my_config.h: ../config.h
$(CP) ../config.h my_config.h
-# This should be changed in the source and removed.
-my_global.h: global.h
- $(RM) -f my_global.h
- $(CP) global.h my_global.h
-
# These files should not be included in distributions since they are
# generated by configure from the .h.in files
dist-hook:
diff --git a/include/config-netware.h b/include/config-netware.h
new file mode 100644
index 00000000000..dab365a7127
--- /dev/null
+++ b/include/config-netware.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Defines for netware compatible with MySQL */
+
+/* required headers */
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <screen.h>
+#include <limits.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <time.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <termios.h>
+
+/* required adjustments */
+#undef HAVE_READDIR_R
+#undef HAVE_RWLOCK_INIT
+#undef HAVE_SCHED_H
+#undef HAVE_SYS_MMAN_H
+#undef HAVE_SYNCH_H
+#undef HAVE_CRYPT
+#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
+#define HAVE_PTHREAD_SIGMASK 1
+#define HAVE_PTHREAD_YIELD_ZERO_ARG 1
+#define HAVE_BROKEN_REALPATH 1
+
+/* include the old function apis */
+#define USE_OLD_FUNCTIONS 1
+
+/* no case sensitivity */
+#define FN_NO_CASE_SENCE 1
+
+/* the thread alarm is not used */
+#define DONT_USE_THR_ALARM 1
+
+/* signals do not interrupt sockets */
+#define SIGNALS_DONT_BREAK_READ 1
+
+/* signal by closing the sockets */
+#define SIGNAL_WITH_VIO_CLOSE 1
+
+/* default directory information */
+#define DEFAULT_MYSQL_HOME "sys:/mysql"
+#define PACKAGE "mysql"
+#define DEFAULT_BASEDIR "sys:/"
+#define SHAREDIR "share/"
+#define DEFAULT_CHARSET_HOME "sys:/mysql/"
+#define DATADIR "data/"
+
+/* 64-bit file system calls */
+#define SIZEOF_OFF_T 8
+#define off_t off64_t
+#define chsize chsize64
+#define ftruncate ftruncate64
+#define lseek lseek64
+#define pread pread64
+#define pwrite pwrite64
+#define tell tell64
+
+/* do not use the extended time in LibC sys\stat.h */
+#define _POSIX_SOURCE
+
+/* Some macros for portability */
+
+#define set_timespec(ABSTIME,SEC) { (ABSTIME).tv_sec=(SEC); (ABSTIME).tv_nsec=0; }
diff --git a/include/config-os2.h b/include/config-os2.h
index e23f4eb75e8..7e9684ae3f5 100644
--- a/include/config-os2.h
+++ b/include/config-os2.h
@@ -67,10 +67,10 @@
#define NO_FCNTL_NONBLOCK
#define EFBIG E2BIG
-//#define ENFILE EMFILE
-//#define ENAMETOOLONG (EOS2ERR+2)
-//#define ETIMEDOUT 145
-//#define EPIPE 146
+/*#define ENFILE EMFILE */
+/*#define ENAMETOOLONG (EOS2ERR+2) */
+/*#define ETIMEDOUT 145 */
+/*#define EPIPE 146 */
#define EROFS 147
#define sleep(A) DosSleep((A)*1000)
@@ -132,7 +132,7 @@ typedef unsigned long long os_off_t;
#define HAVE_ALLOCA 1
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
-//#define HAVE_ALLOCA_H 1
+/* #define HAVE_ALLOCA_H 1 */
/* Define if you don't have vprintf but do have _doprnt. */
/* #undef HAVE_DOPRNT */
@@ -148,7 +148,7 @@ typedef unsigned long long os_off_t;
#define HAVE_ST_RDEV 1
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
-//#define HAVE_SYS_WAIT_H 1
+/* #define HAVE_SYS_WAIT_H 1 */
/* Define if you don't have tm_zone but do have the external array
tzname. */
@@ -219,7 +219,7 @@ typedef unsigned long long os_off_t;
#define HAVE_BOOL 1
/* Have berkeley db installed */
-//#define HAVE_BERKELEY_DB 1
+/* #define HAVE_BERKELEY_DB 1 */
/* DSB style signals ? */
/* #undef HAVE_BSD_SIGNALS */
@@ -398,7 +398,7 @@ typedef unsigned long long os_off_t;
#define HAVE_CHSIZE 1
/* Define if you have the cuserid function. */
-//#define HAVE_CUSERID 1
+/* #define HAVE_CUSERID 1 */
/* Define if you have the dlerror function. */
#define HAVE_DLERROR 1
@@ -410,7 +410,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_FCHMOD */
/* Define if you have the fcntl function. */
-//#define HAVE_FCNTL 1
+/* #define HAVE_FCNTL 1 */
/* Define if you have the fconvert function. */
/* #undef HAVE_FCONVERT */
@@ -428,7 +428,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_FSEEKO */
/* Define if you have the ftruncate function. */
-//#define HAVE_FTRUNCATE 1
+/* #define HAVE_FTRUNCATE 1 */
/* Define if you have the getcwd function. */
#define HAVE_GETCWD 1
@@ -443,16 +443,16 @@ typedef unsigned long long os_off_t;
#define HAVE_GETPAGESIZE 1
/* Define if you have the getpass function. */
-//#define HAVE_GETPASS 1
+/*#define HAVE_GETPASS 1 */
/* Define if you have the getpassphrase function. */
/* #undef HAVE_GETPASSPHRASE */
/* Define if you have the getpwnam function. */
-//#define HAVE_GETPWNAM 1
+/* #define HAVE_GETPWNAM 1 */
/* Define if you have the getpwuid function. */
-//#define HAVE_GETPWUID 1
+/* #define HAVE_GETPWUID 1 */
/* Define if you have the getrlimit function. */
/* #undef HAVE_GETRLIMIT */
@@ -494,7 +494,7 @@ typedef unsigned long long os_off_t;
#define HAVE_MEMMOVE 1
/* Define if you have the mkstemp function. */
-//#define HAVE_MKSTEMP 1
+/* #define HAVE_MKSTEMP 1 */
/* Define if you have the mlockall function. */
/* #undef HAVE_MLOCKALL */
@@ -584,7 +584,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_SIGTHREADMASK */
/* Define if you have the snprintf function. */
-//#define HAVE_SNPRINTF 1
+/* #define HAVE_SNPRINTF 1 */
/* Define if you have the socket function. */
#define HAVE_SOCKET 1
@@ -638,7 +638,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_VIDATTR */
/* Define if you have the <alloca.h> header file. */
-//#define HAVE_ALLOCA_H 1
+/* #define HAVE_ALLOCA_H 1 */
/* Define if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
@@ -650,10 +650,10 @@ typedef unsigned long long os_off_t;
#define HAVE_CRYPT_H 1
/* Define if you have the <curses.h> header file. */
-//#define HAVE_CURSES_H 1
+/* #define HAVE_CURSES_H 1 */
/* Define if you have the <dirent.h> header file. */
-//#define HAVE_DIRENT_H 1
+/* #define HAVE_DIRENT_H 1 */
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
@@ -665,7 +665,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_FLOATINGPOINT_H */
/* Define if you have the <grp.h> header file. */
-//#define HAVE_GRP_H 1
+/* #define HAVE_GRP_H 1 */
/* Define if you have the <ieeefp.h> header file. */
/* #undef HAVE_IEEEFP_H */
@@ -689,7 +689,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_PATHS_H */
/* Define if you have the <pwd.h> header file. */
-//#define HAVE_PWD_H 1
+/* #define HAVE_PWD_H 1 */
/* Define if you have the <sched.h> header file. */
/* #undef HAVE_SCHED_H */
@@ -710,16 +710,16 @@ typedef unsigned long long os_off_t;
#define HAVE_STRING_H 1
/* Define if you have the <strings.h> header file. */
-//#define HAVE_STRINGS_H 1
+/* #define HAVE_STRINGS_H 1 */
/* Define if you have the <synch.h> header file. */
/* #undef HAVE_SYNCH_H */
/* Define if you have the <sys/dir.h> header file. */
-//#define HAVE_SYS_DIR_H 1
+/* #define HAVE_SYS_DIR_H 1 */
/* Define if you have the <sys/file.h> header file. */
-//#define HAVE_SYS_FILE_H 1
+/* #define HAVE_SYS_FILE_H 1 */
/* Define if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
@@ -761,7 +761,7 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_SYS_VADVISE_H */
/* Define if you have the <sys/wait.h> header file. */
-//#define HAVE_SYS_WAIT_H 1
+/* #define HAVE_SYS_WAIT_H 1 */
/* Define if you have the <term.h> header file. */
/* #undef HAVE_TERM_H */
@@ -770,13 +770,13 @@ typedef unsigned long long os_off_t;
/* #undef HAVE_TERMBITS_H */
/* Define if you have the <termcap.h> header file. */
-//#define HAVE_TERMCAP_H 1
+/* #define HAVE_TERMCAP_H 1 */
/* Define if you have the <termio.h> header file. */
-//#define HAVE_TERMIO_H 1
+/* /#define HAVE_TERMIO_H 1 */
/* Define if you have the <termios.h> header file. */
-//#define HAVE_TERMIOS_H 1
+/* #define HAVE_TERMIOS_H 1 */
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
@@ -829,4 +829,4 @@ typedef unsigned long long os_off_t;
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
-#endif // __CONFIG_OS2_H__
+#endif /* __CONFIG_OS2_H__ */
diff --git a/include/config-win.h b/include/config-win.h
index 4e4088f07dd..e6f03a10afb 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Defines for Win32 to make it compatible for MySQL */
@@ -25,14 +24,14 @@
#include <malloc.h>
#if defined(__NT__)
-#define SYSTEM_TYPE "NT"
+#define SYSTEM_TYPE "NT"
#elif defined(__WIN2000__)
-#define SYSTEM_TYPE "WIN2000"
+#define SYSTEM_TYPE "WIN2000"
#else
-#define SYSTEM_TYPE "Win95/Win98"
+#define SYSTEM_TYPE "Win95/Win98"
#endif
-#ifdef _WIN64
+#if defined(_WIN64) || defined(WIN64)
#define MACHINE_TYPE "ia64" /* Define to machine type name */
#else
#define MACHINE_TYPE "i32" /* Define to machine type name */
@@ -44,23 +43,23 @@
#endif
#endif /* _WIN64 */
#ifndef __WIN__
-#define __WIN__ /* To make it easier in VC++ */
+#define __WIN__ /* To make it easier in VC++ */
#endif
/* File and lock constants */
-#define O_SHARE 0x1000 /* Open file in sharing mode */
+#define O_SHARE 0x1000 /* Open file in sharing mode */
#ifdef __BORLANDC__
-#define F_RDLCK LK_NBLCK /* read lock */
-#define F_WRLCK LK_NBRLCK /* write lock */
-#define F_UNLCK LK_UNLCK /* remove lock(s) */
+#define F_RDLCK LK_NBLCK /* read lock */
+#define F_WRLCK LK_NBRLCK /* write lock */
+#define F_UNLCK LK_UNLCK /* remove lock(s) */
#else
-#define F_RDLCK _LK_NBLCK /* read lock */
-#define F_WRLCK _LK_NBRLCK /* write lock */
-#define F_UNLCK _LK_UNLCK /* remove lock(s) */
+#define F_RDLCK _LK_NBLCK /* read lock */
+#define F_WRLCK _LK_NBRLCK /* write lock */
+#define F_UNLCK _LK_UNLCK /* remove lock(s) */
#endif
-#define F_EXCLUSIVE 1 /* We have only exclusive locking */
-#define F_TO_EOF (INT_MAX32/2) /* size for lock of all file */
+#define F_EXCLUSIVE 1 /* We have only exclusive locking */
+#define F_TO_EOF (INT_MAX32/2) /* size for lock of all file */
#define F_OK 0 /* parameter to access() */
#define S_IROTH S_IREAD /* for my_lib */
@@ -71,34 +70,35 @@
#define O_SHORT_LIVED 0
#define SH_DENYNO _SH_DENYNO
#else
-#define O_BINARY _O_BINARY /* compability with MSDOS */
-#define FILE_BINARY _O_BINARY /* my_fopen in binary mode */
-#define O_TEMPORARY _O_TEMPORARY
-#define O_SHORT_LIVED _O_SHORT_LIVED
-#define SH_DENYNO _SH_DENYNO
+#define O_BINARY _O_BINARY /* compability with MSDOS */
+#define FILE_BINARY _O_BINARY /* my_fopen in binary mode */
+#define O_TEMPORARY _O_TEMPORARY
+#define O_SHORT_LIVED _O_SHORT_LIVED
+#define SH_DENYNO _SH_DENYNO
#endif
#define NO_OPEN_3 /* For my_create() */
-#define SIGQUIT SIGTERM /* No SIGQUIT */
+#define SIGQUIT SIGTERM /* No SIGQUIT */
#undef _REENTRANT /* Crashes something for win32 */
#undef SAFE_MUTEX /* Can't be used on windows */
#define LONGLONG_MIN ((__int64) 0x8000000000000000)
#define LONGLONG_MAX ((__int64) 0x7FFFFFFFFFFFFFFF)
+#define ULONGLONG_MAX ((unsigned __int64) 0xFFFFFFFFFFFFFFFF)
#define LL(A) ((__int64) A)
/* Type information */
-typedef unsigned short ushort;
-typedef unsigned int uint;
+typedef unsigned short ushort;
+typedef unsigned int uint;
typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */
-typedef __int64 longlong;
+typedef __int64 longlong;
typedef int sigset_t;
#define longlong_defined
/* off_t should not be __int64 because of conflicts in header files;
Use my_off_t or os_off_t instead */
-typedef long off_t;
+typedef long off_t;
typedef __int64 os_off_t;
#ifdef _WIN64
typedef UINT_PTR rf_SetTimer;
@@ -110,7 +110,7 @@ typedef uint rf_SetTimer;
#define Socket_defined
#define my_socket SOCKET
#define bool BOOL
-#define SIGPIPE SIGINT
+#define SIGPIPE SIGINT
#define RETQSORTTYPE void
#define QSORT_TYPE_IS_VOID
#define RETSIGTYPE void
@@ -119,7 +119,9 @@ typedef uint rf_SetTimer;
#define bool_defined
#define byte_defined
#define HUGE_PTR
-#define STDCALL __stdcall /* Used by libmysql.dll */
+#define STDCALL __stdcall /* Used by libmysql.dll */
+#define isnan(X) _isnan(X)
+#define finite(X) _finite(X)
#ifndef UNDEF_THREAD_HACK
#define THREAD
@@ -129,16 +131,33 @@ typedef uint rf_SetTimer;
#define SIZEOF_LONG 4
#define SIZEOF_LONG_LONG 8
#define SIZEOF_OFF_T 8
+#ifdef _WIN64
+#define SIZEOF_CHARP 8
+#else
+#define SIZEOF_CHARP 4
+#endif
#define HAVE_BROKEN_NETINET_INCLUDES
#ifdef __NT__
#define HAVE_NAMED_PIPE /* We can only create pipes on NT */
#endif
+/* We need to close files to break connections on shutdown */
+#ifndef SIGNAL_WITH_VIO_CLOSE
+#define SIGNAL_WITH_VIO_CLOSE
+#endif
+
/* Use all character sets in MySQL */
#define USE_MB 1
#define USE_MB_IDENT 1
#define USE_STRCOLL 1
-
+
+/* All windows servers should support .sym files */
+#undef USE_SYMDIR
+#define USE_SYMDIR
+
+/* If LOAD DATA LOCAL INFILE should be enabled by default */
+#define ENABLED_LOCAL_INFILE 1
+
/* Convert some simple functions to Posix */
#define sigset(A,B) signal((A),(B))
@@ -159,8 +178,8 @@ inline double rint(double nr)
}
#ifdef _WIN64
-#define ulonglong2double(A) ((double) (A))
-#define my_off_t2double(A) ((double) (A))
+#define ulonglong2double(A) ((double) (ulonglong) (A))
+#define my_off_t2double(A) ((double) (my_off_t) (A))
#else
inline double ulonglong2double(ulonglong value)
@@ -181,10 +200,13 @@ inline double ulonglong2double(ulonglong value)
#define tell(A) _telli64(A)
#endif
+#define set_timespec(ABSTIME,SEC) { (ABSTIME).tv_sec=time((time_t*)0) + (time_t) (SEC); (ABSTIME).tv_nsec=0; }
+
#define STACK_DIRECTION -1
/* Optimized store functions for Intel x86 */
+#ifndef _WIN64
#define sint2korr(A) (*((int16 *) (A)))
#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
(((uint32) 255L << 24) | \
@@ -202,7 +224,7 @@ inline double ulonglong2double(ulonglong value)
(((uint32) ((uchar) (A)[1])) << 8) +\
(((uint32) ((uchar) (A)[2])) << 16) +\
(((uint32) ((uchar) (A)[3])) << 24)) +\
- (((ulonglong) ((uchar) (A)[4])) << 32))
+ (((ulonglong) ((uchar) (A)[4])) << 32))
#define uint8korr(A) (*((ulonglong *) (A)))
#define sint8korr(A) (*((longlong *) (A)))
#define int2store(T,A) *((uint16*) (T))= (uint16) (A)
@@ -225,11 +247,10 @@ inline double ulonglong2double(ulonglong value)
#define float8get(V,M) doubleget((V),(M))
#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
#define float8store(V,M) doublestore((V),(M))
-
+#endif /* _WIN64 */
#define HAVE_PERROR
#define HAVE_VFPRINT
-#define HAVE_CHSIZE /* System has chsize() function */
#define HAVE_RENAME /* Have rename() as function */
#define HAVE_BINARY_STREAMS /* Have "b" flag in streams */
#define HAVE_LONG_JMP /* Have long jump function */
@@ -248,12 +269,19 @@ inline double ulonglong2double(ulonglong value)
#define HAVE_FLOAT_H
#define HAVE_LIMITS_H
#define HAVE_STDDEF_H
-#define HAVE_RINT /* defined in this file */
-#define NO_FCNTL_NONBLOCK /* No FCNTL */
+#define HAVE_RINT /* defined in this file */
+#define NO_FCNTL_NONBLOCK /* No FCNTL */
#define HAVE_ALLOCA
#define HAVE_STRPBRK
#define HAVE_STRSTR
#define HAVE_COMPRESS
+#define HAVE_CREATESEMAPHORE
+#define HAVE_ISNAN
+#define HAVE_FINITE
+#define HAVE_ISAM /* We want to have support for ISAM in 4.0 */
+#define HAVE_QUERY_CACHE
+#define SPRINTF_RETURNS_INT
+#define HAVE_SETFILEPOINTER
#ifdef NOT_USED
#define HAVE_SNPRINTF /* Gave link error */
@@ -269,13 +297,14 @@ inline double ulonglong2double(ulonglong value)
#define my_reinterpret_cast(A) reinterpret_cast <A>
#define my_const_cast(A) const_cast<A>
+
/* MYSQL OPTIONS */
#ifdef _CUSTOMCONFIG_
#include <custom_conf.h>
#else
-#define DEFAULT_MYSQL_HOME "c:\\mysql"
-#define PACKAGE "mysql"
+#define DEFAULT_MYSQL_HOME "c:\\mysql"
+#define PACKAGE "mysql"
#define DEFAULT_BASEDIR "C:\\"
#define SHAREDIR "share"
#define DEFAULT_CHARSET_HOME "C:/mysql/"
@@ -301,6 +330,6 @@ inline double ulonglong2double(ulonglong value)
pthread_mutex_lock((L)); (V)+=(C); pthread_mutex_unlock((L));
#define thread_safe_sub(V,C,L) \
pthread_mutex_lock((L)); (V)-=(C); pthread_mutex_unlock((L));
-#define statistic_add(V,C,L) (V)+=(C)
+#define statistic_add(V,C,L) (V)+=(C)
#endif
#define statistic_increment(V,L) thread_safe_increment((V),(L))
diff --git a/include/dbug.h b/include/dbug.h
deleted file mode 100644
index 3c86cbb8ac2..00000000000
--- a/include/dbug.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-#ifndef _dbug_h
-#define _dbug_h
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if !defined(DBUG_OFF) && !defined(_lint)
-extern int _db_on_,_no_db_;
-extern FILE *_db_fp_;
-extern char *_db_process_;
-extern int _db_keyword_(const char *keyword);
-extern void _db_setjmp_(void);
-extern void _db_longjmp_(void);
-extern void _db_push_(const char *control);
-extern void _db_pop_(void);
-extern void _db_enter_(const char *_func_,const char *_file_,uint _line_,
- const char **_sfunc_,const char **_sfile_,
- uint *_slevel_, char ***);
-extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_,
- uint *_slevel_);
-extern void _db_pargs_(uint _line_,const char *keyword);
-extern void _db_doprnt_ _VARARGS((const char *format,...));
-extern void _db_dump_(uint _line_,const char *keyword,const char *memory,
- uint length);
-extern void _db_lock_file();
-extern void _db_unlock_file();
-
-#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \
- char **_db_framep_; \
- _db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \
- &_db_framep_)
-#define DBUG_LEAVE \
- (_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_))
-#define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);}
-#define DBUG_VOID_RETURN {DBUG_LEAVE; return;}
-#define DBUG_EXECUTE(keyword,a1) \
- {if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}}
-#define DBUG_PRINT(keyword,arglist) \
- {if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}}
-#define DBUG_PUSH(a1) _db_push_ (a1)
-#define DBUG_POP() _db_pop_ ()
-#define DBUG_PROCESS(a1) (_db_process_ = a1)
-#define DBUG_FILE (_db_fp_)
-#define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1))
-#define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2))
-#define DBUG_DUMP(keyword,a1,a2)\
- {if (_db_on_) {_db_dump_(__LINE__,keyword,a1,a2);}}
-#define DBUG_IN_USE (_db_fp_ && _db_fp_ != stderr)
-#define DEBUGGER_OFF _no_db_=1;_db_on_=0;
-#define DEBUGGER_ON _no_db_=0
-#define DBUG_LOCK_FILE { _db_lock_file(); }
-#define DBUG_UNLOCK_FILE { _db_unlock_file(); }
-#define DBUG_ASSERT(A) assert(A)
-#else /* No debugger */
-
-#define DBUG_ENTER(a1)
-#define DBUG_RETURN(a1) return(a1)
-#define DBUG_VOID_RETURN return
-#define DBUG_EXECUTE(keyword,a1) {}
-#define DBUG_PRINT(keyword,arglist) {}
-#define DBUG_PUSH(a1) {}
-#define DBUG_POP() {}
-#define DBUG_PROCESS(a1) {}
-#define DBUG_FILE (stderr)
-#define DBUG_SETJMP setjmp
-#define DBUG_LONGJMP longjmp
-#define DBUG_DUMP(keyword,a1,a2) {}
-#define DBUG_IN_USE 0
-#define DEBUGGER_OFF
-#define DEBUGGER_ON
-#define DBUG_LOCK_FILE
-#define DBUG_UNLOCK_FILE
-#define DBUG_ASSERT(A) {}
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/include/errmsg.h b/include/errmsg.h
index 8087c526937..5136af5b87a 100644
--- a/include/errmsg.h
+++ b/include/errmsg.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Error messages for mysql clients */
/* error messages for the demon is in share/language/errmsg.sys */
@@ -29,7 +28,7 @@ extern const char *client_errors[]; /* Error messages */
#define CR_MIN_ERROR 2000 /* For easier client code */
#define CR_MAX_ERROR 2999
-#if defined(OS2) && defined( MYSQL_SERVER)
+#if defined(OS2) && defined(MYSQL_SERVER)
#define CER(X) client_errors[(X)-CR_MIN_ERROR]
#else
#define ER(X) client_errors[(X)-CR_MIN_ERROR]
@@ -52,8 +51,16 @@ extern const char *client_errors[]; /* Error messages */
#define CR_SERVER_LOST 2013
#define CR_COMMANDS_OUT_OF_SYNC 2014
#define CR_NAMEDPIPE_CONNECTION 2015
-#define CR_NAMEDPIPEWAIT_ERROR 2016
-#define CR_NAMEDPIPEOPEN_ERROR 2017
+#define CR_NAMEDPIPEWAIT_ERROR 2016
+#define CR_NAMEDPIPEOPEN_ERROR 2017
#define CR_NAMEDPIPESETSTATE_ERROR 2018
#define CR_CANT_READ_CHARSET 2019
#define CR_NET_PACKET_TOO_LARGE 2020
+#define CR_EMBEDDED_CONNECTION 2021
+#define CR_PROBE_SLAVE_STATUS 2022
+#define CR_PROBE_SLAVE_HOSTS 2023
+#define CR_PROBE_SLAVE_CONNECT 2024
+#define CR_PROBE_MASTER_CONNECT 2025
+#define CR_SSL_CONNECTION_ERROR 2026
+#define CR_MALFORMED_PACKET 2027
+
diff --git a/include/ft_global.h b/include/ft_global.h
index 3937bd87c7f..9acdf6aaaf3 100644
--- a/include/ft_global.h
+++ b/include/ft_global.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,29 +27,39 @@ extern "C" {
#endif
#define FT_QUERY_MAXLEN 1024
+#define HA_FT_MAXLEN 254
-typedef struct ft_doc_rec {
- my_off_t dpos;
- double weight;
-} FT_DOC;
+typedef struct st_ft_info FT_INFO;
+struct _ft_vft
+{
+ int (*read_next)(FT_INFO *, char *);
+ float (*find_relevance)(FT_INFO *, byte *, uint);
+ void (*close_search)(FT_INFO *);
+ float (*get_relevance)(FT_INFO *);
+ void (*reinit_search)(FT_INFO *);
+};
-typedef struct st_ft_doclist {
- int ndocs;
- int curdoc;
- void *info; /* actually (MI_INFO *) but don't want to include myisam.h */
- FT_DOC doc[1];
-} FT_DOCLIST;
+#ifndef FT_CORE
+struct st_ft_info
+{
+ struct _ft_vft *please; /* INTERCAL style :-) */
+};
+#endif
+extern const char *ft_stopword_file;
extern const char *ft_precompiled_stopwords[];
-int ft_init_stopwords(const char **);
+extern ulong ft_min_word_len;
+extern ulong ft_max_word_len;
+extern ulong ft_max_word_len_for_sort;
+extern const char *ft_boolean_syntax;
+
+int ft_init_stopwords(void);
void ft_free_stopwords(void);
-FT_DOCLIST * ft_init_search(void *, uint, byte *, uint, my_bool);
-int ft_read_next(FT_DOCLIST *, char *);
-#define ft_close_search(handler) my_free(((gptr)(handler)),MYF(0))
-#define ft_get_relevance(handler) ((handler)->doc[(handler)->curdoc].weight)
-#define ft_reinit_search(handler) (((FT_DOCLIST *)(handler))->curdoc=-1)
+#define FT_NL 0
+#define FT_BOOL 1
+FT_INFO *ft_init_search(uint,void *, uint, byte *, uint, my_bool);
#ifdef __cplusplus
}
diff --git a/include/getopt.h b/include/getopt.h
deleted file mode 100644
index 790915b97df..00000000000
--- a/include/getopt.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Declarations for getopt.
- Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
-
-This file is part of the GNU C Library. Its master source is NOT part of
-the C library, however. The master source lives in /gd/gnu/lib.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#ifndef _GETOPT_H
-#define _GETOPT_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns EOF, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
- for unrecognized options. */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized. */
-
-extern int optopt;
-
-/* Describe the long-named options requested by the application.
- The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
- of `struct option' terminated by an element containing a name which is
- zero.
-
- The field `has_arg' is:
- no_argument (or 0) if the option does not take an argument,
- required_argument (or 1) if the option requires an argument,
- optional_argument (or 2) if the option takes an optional argument.
-
- If the field `flag' is not NULL, it points to a variable that is set
- to the value given in the field `val' when the option is found, but
- left unchanged if the option is not found.
-
- To have a long-named option do something other than set an `int' to
- a compiled-in constant, such as set a value from `optarg', set the
- option's `flag' field to zero and its `val' field to a nonzero
- value (the equivalent single-letter option character, if there is
- one). For long options that have a zero `flag' field, `getopt'
- returns the contents of the `val' field. */
-
-struct option
-{
-#if defined (__STDC__) && __STDC__ || defined(__cplusplus)
- const char *name;
-#else
- char *name;
-#endif
- /* has_arg can't be an enum because some compilers complain about
- type mismatches in all the code that assumes it is an int. */
- int has_arg;
- int *flag;
- int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'. */
-
-#define no_argument 0
-#define required_argument 1
-#define optional_argument 2
-
-#if ( defined (__STDC__) && __STDC__ ) || defined(__cplusplus) || defined(MSDOS)
-#ifdef __EMX__
-int getopt (int, char **, __const__ char *);
-#elif defined( __GNU_LIBRARY__)
-/* Many other libraries have conflicting prototypes for getopt, with
- differences in the consts, in stdlib.h. To avoid compilation
- errors, only prototype getopt for the GNU C library. */
-extern int getopt (int argc, char *const *argv, const char *shortopts);
-#else /* not __GNU_LIBRARY__ */
-extern int getopt (int argc, char *const *argv, const char *optstring);
-#endif /* __GNU_LIBRARY__ */
-extern int getopt_long (int argc, char *const *argv, const char *shortopts,
- const struct option *longopts, int *longind);
-extern int getopt_long_only (int argc, char *const *argv,
- const char *shortopts,
- const struct option *longopts, int *longind);
-
-/* Internal only. Users should not call this directly. */
-extern int _getopt_internal (int argc, char *const *argv,
- const char *shortopts,
- const struct option *longopts, int *longind,
- int long_only);
-#else /* not __STDC__ */
-extern int getopt ();
-extern int getopt_long ();
-extern int getopt_long_only ();
-
-extern int _getopt_internal ();
-#endif /* __STDC__ */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _GETOPT_H */
diff --git a/include/global.h b/include/global.h
deleted file mode 100644
index 94b0f5bab03..00000000000
--- a/include/global.h
+++ /dev/null
@@ -1,1006 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* This is the main include file that should included 'first' in every
- C file. */
-
-#ifndef _global_h
-#define _global_h
-
-#if defined( __EMX__) && !defined( MYSQL_SERVER)
-/* moved here to use below VOID macro redefinition */
-#define INCL_BASE
-#define INCL_NOPMAPI
-#include <os2.h>
-#endif /* __EMX__ */
-
-#ifdef __CYGWIN__
-/* We use a Unix API, so pretend it's not Windows */
-#undef WIN
-#undef WIN32
-#undef _WIN
-#undef _WIN32
-#undef _WIN64
-#undef __WIN__
-#undef __WIN32__
-#define HAVE_ERRNO_AS_DEFINE
-#endif /* __CYGWIN__ */
-
-
-#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
-#include <config-win.h>
-#elif defined(OS2)
-#include <config-os2.h>
-#else
-#include <my_config.h>
-#if defined(__cplusplus) && defined(inline)
-#undef inline /* fix configure problem */
-#endif
-#endif /* _WIN32... */
-
-/* Fix problem with S_ISLNK() on Linux */
-#if defined(HAVE_LINUXTHREADS)
-#undef _GNU_SOURCE
-#define _GNU_SOURCE 1
-#endif
-
-/* The client defines this to avoid all thread code */
-#if defined(UNDEF_THREADS_HACK)
-#undef THREAD
-#undef HAVE_mit_thread
-#undef HAVE_LINUXTHREADS
-#undef HAVE_UNIXWARE7_THREADS
-#endif
-
-#ifdef HAVE_THREADS_WITHOUT_SOCKETS
-/* MIT pthreads does not work with unix sockets */
-#undef HAVE_SYS_UN_H
-#endif
-
-#define __EXTENSIONS__ 1 /* We want some extension */
-#ifndef __STDC_EXT__
-#define __STDC_EXT__ 1 /* To get large file support on hpux */
-#endif
-
-#if defined(THREAD) && !defined(__WIN__) && !defined(OS2)
-#ifndef _POSIX_PTHREAD_SEMANTICS
-#define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */
-#endif
-/* was #if defined(HAVE_LINUXTHREADS) || defined(HAVE_DEC_THREADS) || defined(HPUX) */
-#if !defined(SCO)
-#define _REENTRANT 1 /* Some thread libraries require this */
-#endif
-#if !defined(_THREAD_SAFE) && !defined(_AIX)
-#define _THREAD_SAFE /* Required for OSF1 */
-#endif
-#ifndef HAVE_mit_thread
-#ifdef HAVE_UNIXWARE7_THREADS
-#include <thread.h>
-#else
-#include <pthread.h> /* AIX must have this included first */
-#endif /* HAVE_UNIXWARE7_THREADS */
-#endif /* HAVE_mit_thread */
-#if !defined(SCO) && !defined(_REENTRANT)
-#define _REENTRANT 1 /* Threads requires reentrant code */
-#endif
-#endif /* THREAD */
-
-/* Go around some bugs in different OS and compilers */
-#ifdef _AIX /* By soren@t.dk */
-#define _H_STRINGS
-#define _SYS_STREAM_H
-#define _AIX32_CURSES
-#define ulonglong2double(A) my_ulonglong2double(A)
-#define my_off_t2double(A) my_ulonglong2double(A)
-#ifdef __cplusplus
-extern "C" {
-#endif
-double my_ulonglong2double(unsigned long long A);
-#ifdef __cplusplus
-}
-#endif
-#endif /* _AIX */
-
-#ifdef HAVE_BROKEN_SNPRINTF /* HPUX 10.20 don't have this defined */
-#undef HAVE_SNPRINTF
-#endif
-#ifdef HAVE_BROKEN_PREAD /* These doesn't work on HPUX 11.x */
-#undef HAVE_PREAD
-#undef HAVE_PWRITE
-#endif
-#if defined(HAVE_BROKEN_INLINE) && !defined(__cplusplus)
-#undef inline
-#define inline
-#endif
-
-#ifdef UNDEF_HAVE_GETHOSTBYNAME_R /* For OSF4.x */
-#undef HAVE_GETHOSTBYNAME_R
-#endif
-#ifdef UNDEF_HAVE_INITGROUPS /* For AIX 4.3 */
-#undef HAVE_INITGROUPS
-#endif
-
-/* Fix a bug in gcc 2.8.0 on IRIX 6.2 */
-#if SIZEOF_LONG == 4 && defined(__LONG_MAX__)
-#undef __LONG_MAX__ /* Is a longlong value in gcc 2.8.0 ??? */
-#define __LONG_MAX__ 2147483647
-#endif
-
-/* Fix problem when linking c++ programs with gcc 3.x */
-#ifdef DEFINE_CXA_PURE_VIRTUAL
-#define FIX_GCC_LINKING_PROBLEM extern "C" { int __cxa_pure_virtual() {return 0;} }
-#else
-#define FIX_GCC_LINKING_PROBLEM
-#endif
-
-/* egcs 1.1.2 has a problem with memcpy on Alpha */
-#if defined(__GNUC__) && defined(__alpha__) && ! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
-#define BAD_MEMCPY
-#endif
-
-/* In Linux-alpha we have atomic.h if we are using gcc */
-#if defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__alpha__) && (__GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95)) && !defined(HAVE_ATOMIC_ADD)
-#define HAVE_ATOMIC_ADD
-#define HAVE_ATOMIC_SUB
-#endif
-
-/* In Linux-ia64 including atomic.h will give us an error */
-#if (defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && (defined(__ia64__) || defined(__powerpc64__))) || !defined(THREAD)
-#undef HAVE_ATOMIC_ADD
-#undef HAVE_ATOMIC_SUB
-#endif
-
-#if defined(_lint) && !defined(lint)
-#define lint
-#endif
-#if SIZEOF_LONG_LONG > 4 && !defined(_LONG_LONG)
-#define _LONG_LONG 1 /* For AIX string library */
-#endif
-
-#ifndef stdin
-#include <stdio.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STDDEF_H
-#include <stddef.h>
-#endif
-
-#include <math.h>
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_FLOAT_H
-#include <float.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_TIMEB_H
-#include <sys/timeb.h> /* Avoid warnings on SCO */
-#endif
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif /* TIME_WITH_SYS_TIME */
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if defined(__cplusplus) && defined(NO_CPLUSPLUS_ALLOCA)
-#undef HAVE_ALLOCA
-#undef HAVE_ALLOCA_H
-#endif
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-#ifdef HAVE_ATOMIC_ADD
-#define __SMP__
-#define CONFIG_SMP
-#include <asm/atomic.h>
-#endif
-#include <errno.h> /* Recommended by debian */
-
-/* Go around some bugs in different OS and compilers */
-#if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H)
-#include <sys/stream.h> /* HPUX 10.20 defines ulong here. UGLY !!! */
-#define HAVE_ULONG
-#endif
-#ifdef DONT_USE_FINITE /* HPUX 11.x has is_finite() */
-#undef HAVE_FINITE
-#endif
-#if defined(HPUX) && defined(_LARGEFILE64_SOURCE) && defined(THREAD)
-/* Fix bug in setrlimit */
-#undef setrlimit
-#define setrlimit cma_setrlimit64
-#endif
-
-/* We can not live without these */
-
-#define USE_MYFUNC 1 /* Must use syscall indirection */
-#define MASTER 1 /* Compile without unireg */
-#define ENGLISH 1 /* Messages in English */
-#define POSIX_MISTAKE 1 /* regexp: Fix stupid spec error */
-#define USE_REGEX 1 /* We want the use the regex library */
-/* Do not define for ultra sparcs */
-#ifndef OS2
-#define USE_BMOVE512 1 /* Use this unless the system bmove is faster */
-#endif
-
-/* Paranoid settings. Define I_AM_PARANOID if you are paranoid */
-#ifdef I_AM_PARANOID
-#define DONT_ALLOW_USER_CHANGE 1
-#define DONT_USE_MYSQL_PWD 1
-#endif
-
-/* #define USE_some_charset 1 was deprecated by changes to configure */
-/* my_ctype my_to_upper, my_to_lower, my_sort_order gain theit right value */
-/* automagically during configuration */
-
-/* Does the system remember a signal handler after a signal ? */
-#ifndef HAVE_BSD_SIGNALS
-#define DONT_REMEMBER_SIGNAL
-#endif
-
-/* Define void to stop lint from generating "null effekt" comments */
-#ifndef DONT_DEFINE_VOID
-#ifdef _lint
-int __void__;
-#define VOID(X) (__void__ = (int) (X))
-#else
-#undef VOID
-#define VOID(X) (X)
-#endif
-#endif /* DONT_DEFINE_VOID */
-
-#if defined(_lint) || defined(FORCE_INIT_OF_VARS)
-#define LINT_INIT(var) var=0 /* No uninitialize-warning */
-#else
-#define LINT_INIT(var)
-#endif
-
-/* Define some useful general macros */
-#if defined(__cplusplus) && defined(__GNUC__)
-#define max(a, b) ((a) >? (b))
-#define min(a, b) ((a) <? (b))
-#elif !defined(max)
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
-#if defined(__EMX__) || !defined(HAVE_UINT)
-typedef unsigned int uint;
-typedef unsigned short ushort;
-#endif
-
-#define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0)
-#define swap(t,a,b) { register t dummy; dummy = a; a = b; b = dummy; }
-#define test(a) ((a) ? 1 : 0)
-#define set_if_bigger(a,b) { if ((a) < (b)) (a)=(b); }
-#define set_if_smaller(a,b) { if ((a) > (b)) (a)=(b); }
-#define test_all_bits(a,b) (((a) & (b)) == (b))
-#define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1))
-#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))
-#ifndef HAVE_RINT
-#define rint(A) floor((A)+0.5)
-#endif
-
-/* Define some general constants */
-#ifndef TRUE
-#define TRUE (1) /* Logical true */
-#define FALSE (0) /* Logical false */
-#endif
-
-#if defined(__GNUC__)
-#define function_volatile volatile
-#define my_reinterpret_cast(A) reinterpret_cast<A>
-#define my_const_cast(A) const_cast<A>
-#elif !defined(my_reinterpret_cast)
-#define my_reinterpret_cast(A) (A)
-#define my_const_cast(A) (A)
-#endif
-#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
-#define __attribute__(A)
-#endif
-
-/* From old s-system.h */
-
-/*
- Support macros for non ansi & other old compilers. Since such
- things are no longer supported we do nothing. We keep then since
- some of our code may still be needed to upgrade old customers.
-*/
-#define _VARARGS(X) X
-#define _STATIC_VARARGS(X) X
-#define _PC(X) X
-
-#if defined(DBUG_ON) && defined(DBUG_OFF)
-#undef DBUG_OFF
-#endif
-
-#if defined(_lint) && !defined(DBUG_OFF)
-#define DBUG_OFF
-#endif
-
-#include <dbug.h>
-#ifndef DBUG_OFF
-#define dbug_assert(A) assert(A)
-#else
-#define dbug_assert(A)
-#endif
-
-#define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/
-#define ASCII_BITS_USED 8 /* Bit char used */
-#define NEAR_F /* No near function handling */
-
-/* Some types that is different between systems */
-
-typedef int File; /* File descriptor */
-#ifndef Socket_defined
-typedef int my_socket; /* File descriptor for sockets */
-#define INVALID_SOCKET -1
-#endif
-/* Type for fuctions that handles signals */
-#define sig_handler RETSIGTYPE
-typedef void (*sig_return)();/* Returns type from signal */
-#if defined(__GNUC__) && !defined(_lint)
-typedef char pchar; /* Mixed prototypes can take char */
-typedef char puchar; /* Mixed prototypes can take char */
-typedef char pbool; /* Mixed prototypes can take char */
-typedef short pshort; /* Mixed prototypes can take short int */
-typedef float pfloat; /* Mixed prototypes can take float */
-#else
-typedef int pchar; /* Mixed prototypes can't take char */
-typedef uint puchar; /* Mixed prototypes can't take char */
-typedef int pbool; /* Mixed prototypes can't take char */
-typedef int pshort; /* Mixed prototypes can't take short int */
-typedef double pfloat; /* Mixed prototypes can't take float */
-#endif
-typedef int (*qsort_cmp)(const void *,const void *);
-#ifdef HAVE_mit_thread
-#define qsort_t void
-#undef QSORT_TYPE_IS_VOID
-#define QSORT_TYPE_IS_VOID
-#else
-#define qsort_t RETQSORTTYPE /* Broken GCC cant handle typedef !!!! */
-#endif
-#ifdef HAVE_mit_thread
-#define size_socket socklen_t /* Type of last arg to accept */
-#else
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-typedef SOCKET_SIZE_TYPE size_socket;
-#endif
-
-#ifndef SOCKOPT_OPTLEN_TYPE
-#define SOCKOPT_OPTLEN_TYPE size_socket
-#endif
-
-/* file create flags */
-
-#ifndef O_SHARE
-#define O_SHARE 0 /* Flag to my_open for shared files */
-#ifndef O_BINARY
-#define O_BINARY 0 /* Flag to my_open for binary files */
-#endif
-#define FILE_BINARY 0 /* Flag to my_fopen for binary streams */
-#ifdef HAVE_FCNTL
-#define HAVE_FCNTL_LOCK
-#define F_TO_EOF 0L /* Param to lockf() to lock rest of file */
-#endif
-#endif /* O_SHARE */
-#ifndef O_TEMPORARY
-#define O_TEMPORARY 0
-#endif
-#ifndef O_SHORT_LIVED
-#define O_SHORT_LIVED 0
-#endif
-
-/* #define USE_RECORD_LOCK */
-
- /* Unsigned types supported by the compiler */
-#define UNSINT8 /* unsigned int8 (char) */
-#define UNSINT16 /* unsigned int16 */
-#define UNSINT32 /* unsigned int32 */
-
- /* General constants */
-#define SC_MAXWIDTH 256 /* Max width of screen (for error messages) */
-#define FN_LEN 256 /* Max file name len */
-#define FN_HEADLEN 253 /* Max length of filepart of file name */
-#define FN_EXTLEN 20 /* Max length of extension (part of FN_LEN) */
-#define FN_REFLEN 512 /* Max length of full path-name */
-#define FN_EXTCHAR '.'
-#define FN_HOMELIB '~' /* ~/ is used as abbrev for home dir */
-#define FN_CURLIB '.' /* ./ is used as abbrev for current dir */
-#define FN_PARENTDIR ".." /* Parentdirectory; Must be a string */
-#define FN_DEVCHAR ':'
-
-#ifndef FN_LIBCHAR
-#ifdef __EMX__
-#define FN_LIBCHAR '\\'
-#define FN_ROOTDIR "\\"
-#else
-#define FN_LIBCHAR '/'
-#define FN_ROOTDIR "/"
-#endif
-#define MY_NFILE 1024 /* This is only used to save filenames */
-#endif
-
-/* #define EXT_IN_LIBNAME */
-/* #define FN_NO_CASE_SENCE */
-/* #define FN_UPPER_CASE TRUE */
-
-/*
- Io buffer size; Must be a power of 2 and a multiple of 512. May be
- smaller what the disk page size. This influences the speed of the
- isam btree library. eg to big to slow.
-*/
-#define IO_SIZE 4096
-/*
- How much overhead does malloc have. The code often allocates
- something like 1024-MALLOC_OVERHEAD bytes
-*/
-#ifdef SAFEMALLOC
-#define MALLOC_OVERHEAD (8+24+4)
-#else
-#define MALLOC_OVERHEAD 8
-#endif
- /* get memory in huncs */
-#define ONCE_ALLOC_INIT (uint) (4096-MALLOC_OVERHEAD)
- /* Typical record cash */
-#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD)
- /* Typical key cash */
-#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD)
-
- /* Some things that this system doesn't have */
-
-#define ONLY_OWN_DATABASES /* We are using only databases by monty */
-#define NO_PISAM /* Not needed anymore */
-#define NO_MISAM /* Not needed anymore */
-#define NO_HASH /* Not needed anymore */
-#ifdef __WIN__
-#define NO_DIR_LIBRARY /* Not standar dir-library */
-#define USE_MY_STAT_STRUCT /* For my_lib */
-#endif
-
-/* Some things that this system does have */
-
-#ifndef HAVE_ITOA
-#define USE_MY_ITOA /* There is no itoa */
-#endif
-
-/* Some defines of functions for portability */
-
-#ifndef HAVE_ATOD
-#define atod atof
-#endif
-#ifdef USE_MY_ATOF
-#define atof my_atof
-extern void init_my_atof(void);
-extern double my_atof(const char*);
-#endif
-#undef remove /* Crashes MySQL on SCO 5.0.0 */
-#ifndef __WIN__
-#ifdef OS2
-#define closesocket(A) soclose(A)
-#else
-#define closesocket(A) close(A)
-#endif
-#ifndef ulonglong2double
-#define ulonglong2double(A) ((double) (A))
-#define my_off_t2double(A) ((double) (A))
-#endif
-#endif
-
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-#define ulong_to_double(X) ((double) (ulong) (X))
-#define SET_STACK_SIZE(X) /* Not needed on real machines */
-
-#if !defined(HAVE_mit_thread) && !defined(HAVE_STRTOK_R)
-#define strtok_r(A,B,C) strtok((A),(B))
-#endif
-
-#ifdef HAVE_LINUXTHREADS
-/* #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) */
-/* #define sigset(A,B) signal((A),(B)) */
-#endif
-
-/* Remove some things that mit_thread break or doesn't support */
-#if defined(HAVE_mit_thread) && defined(THREAD)
-#undef HAVE_PREAD
-#undef HAVE_REALPATH
-#undef HAVE_MLOCK
-#undef HAVE_TEMPNAM /* Use ours */
-#undef HAVE_PTHREAD_SETPRIO
-#undef HAVE_FTRUNCATE
-#undef HAVE_READLINK
-#endif
-
-/* This is from the old m-machine.h file */
-
-#if SIZEOF_LONG_LONG > 4
-#define HAVE_LONG_LONG 1
-#endif
-
-#if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN)
-#define LONGLONG_MIN ((long long) 0x8000000000000000LL)
-#define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL)
-#endif
-
-#if SIZEOF_LONG == 4
-#define INT_MIN32 (long) 0x80000000L
-#define INT_MAX32 (long) 0x7FFFFFFFL
-#define INT_MIN24 ((long) 0xff800000L)
-#define INT_MAX24 0x007fffffL
-#define INT_MIN16 ((short int) 0x8000)
-#define INT_MAX16 0x7FFF
-#define INT_MIN8 ((char) 0x80)
-#define INT_MAX8 ((char) 0x7F)
-#else /* Probably Alpha */
-#define INT_MIN32 ((long) (int) 0x80000000)
-#define INT_MAX32 ((long) (int) 0x7FFFFFFF)
-#define INT_MIN24 ((long) (int) 0xff800000)
-#define INT_MAX24 ((long) (int) 0x007fffff)
-#define INT_MIN16 ((short int) 0xffff8000)
-#define INT_MAX16 ((short int) 0x00007FFF)
-#endif
-
-/* From limits.h instead */
-#ifndef DBL_MIN
-#define DBL_MIN 4.94065645841246544e-324
-#define FLT_MIN ((float)1.40129846432481707e-45)
-#endif
-#ifndef DBL_MAX
-#define DBL_MAX 1.79769313486231470e+308
-#define FLT_MAX ((float)3.40282346638528860e+38)
-#endif
-
-/*
- Max size that must be added to a so that we know Size to make
- adressable obj.
-*/
-typedef long my_ptrdiff_t;
-#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1))
-#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
-/* Size to make adressable obj. */
-#define ALIGN_PTR(A, t) ((t*) MY_ALIGN((A),sizeof(t)))
- /* Offset of filed f in structure t */
-#define OFFSET(t, f) ((size_t)(char *)&((t *)0)->f)
-#define ADD_TO_PTR(ptr,size,type) (type) ((byte*) (ptr)+size)
-#define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((byte*) (A) - (byte*) (B))
-
-#define NullS (char *) 0
-/* Nowdays we do not support MessyDos */
-#ifndef NEAR
-#define NEAR /* Who needs segments ? */
-#define FAR /* On a good machine */
-#ifndef HUGE_PTR
-#define HUGE_PTR
-#endif
-#endif
-#if defined(__IBMC__) || defined(__IBMCPP__)
-#define STDCALL _System _Export
-#elif !defined( STDCALL)
-#define STDCALL
-#endif
-
-/* Typdefs for easyier portability */
-
-#if defined(VOIDTYPE)
-typedef void *gptr; /* Generic pointer */
-#else
-typedef char *gptr; /* Generic pointer */
-#endif
-#ifndef HAVE_INT_8_16_32
-typedef char int8; /* Signed integer >= 8 bits */
-typedef short int16; /* Signed integer >= 16 bits */
-#endif
-#ifndef HAVE_UCHAR
-typedef unsigned char uchar; /* Short for unsigned char */
-#endif
-typedef unsigned char uint8; /* Short for unsigned integer >= 8 bits */
-typedef unsigned short uint16; /* Short for unsigned integer >= 16 bits */
-
-#if SIZEOF_INT == 4
-#ifndef HAVE_INT_8_16_32
-typedef int int32;
-#endif
-typedef unsigned int uint32; /* Short for unsigned integer >= 32 bits */
-#elif SIZEOF_LONG == 4
-#ifndef HAVE_INT_8_16_32
-typedef long int32;
-#endif
-typedef unsigned long uint32; /* Short for unsigned integer >= 32 bits */
-#else
-error "Neither int or long is of 4 bytes width"
-#endif
-
-#if !defined(HAVE_ULONG) && !defined(HAVE_LINUXTHREADS) && !defined(__USE_MISC)
-typedef unsigned long ulong; /* Short for unsigned long */
-#endif
-#ifndef longlong_defined
-#if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8
-typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
-typedef long long int longlong;
-#else
-typedef unsigned long ulonglong; /* ulong or unsigned long long */
-typedef long longlong;
-#endif
-#endif
-
-#ifdef USE_RAID
-/*
- The following is done with a if to not get problems with pre-processors
- with late define evaluation
-*/
-#if SIZEOF_OFF_T == 4
-#define SYSTEM_SIZEOF_OFF_T 4
-#else
-#define SYSTEM_SIZEOF_OFF_T 8
-#endif
-#undef SIZEOF_OFF_T
-#define SIZEOF_OFF_T 8
-#else
-#define SYSTEM_SIZEOF_OFF_T SIZEOF_OFF_T
-#endif /* USE_RAID */
-
-#if SIZEOF_OFF_T > 4
-typedef ulonglong my_off_t;
-#else
-typedef unsigned long my_off_t;
-#endif
-#define MY_FILEPOS_ERROR (~(my_off_t) 0)
-#if !defined(__WIN__) && !defined(OS2)
-typedef off_t os_off_t;
-#endif
-
-#if defined(__WIN__)
-#define socket_errno WSAGetLastError()
-#define SOCKET_EINTR WSAEINTR
-#define SOCKET_EAGAIN WSAEINPROGRESS
-#define SOCKET_ENFILE ENFILE
-#define SOCKET_EMFILE EMFILE
-#elif defined(OS2)
-#define socket_errno sock_errno()
-#define SOCKET_EINTR SOCEINTR
-#define SOCKET_EAGAIN SOCEINPROGRESS
-#define SOCKET_EWOULDBLOCK SOCEWOULDBLOCK
-#define SOCKET_ENFILE SOCENFILE
-#define SOCKET_EMFILE SOCEMFILE
-#define closesocket(A) soclose(A)
-#else /* Unix */
-#define socket_errno errno
-#define closesocket(A) close(A)
-#define SOCKET_EINTR EINTR
-#define SOCKET_EAGAIN EAGAIN
-#define SOCKET_EWOULDBLOCK EWOULDBLOCK
-#define SOCKET_ENFILE ENFILE
-#define SOCKET_EMFILE EMFILE
-#endif
-
-typedef uint8 int7; /* Most effective integer 0 <= x <= 127 */
-typedef short int15; /* Most effective integer 0 <= x <= 32767 */
-typedef char *my_string; /* String of characters */
-typedef unsigned long size_s; /* Size of strings (In string-funcs) */
-typedef int myf; /* Type of MyFlags in my_funcs */
-#ifndef byte_defined
-typedef char byte; /* Smallest addressable unit */
-#endif
-typedef char my_bool; /* Small bool */
-#if !defined(bool) && !defined(bool_defined) && (!defined(HAVE_BOOL) || !defined(__cplusplus))
-typedef char bool; /* Ordinary boolean values 0 1 */
-#endif
- /* Macros for converting *constants* to the right type */
-#define INT8(v) (int8) (v)
-#define INT16(v) (int16) (v)
-#define INT32(v) (int32) (v)
-#define MYF(v) (myf) (v)
-
-/*
- Defines to make it possible to prioritize register assignments. No
- longer that important with modern compilers.
-*/
-#ifndef USING_X
-#define reg1 register
-#define reg2 register
-#define reg3 register
-#define reg4 register
-#define reg5 register
-#define reg6 register
-#define reg7 register
-#define reg8 register
-#define reg9 register
-#define reg10 register
-#define reg11 register
-#define reg12 register
-#define reg13 register
-#define reg14 register
-#define reg15 register
-#define reg16 register
-#endif
-
-/* Defines for time function */
-#define SCALE_SEC 100
-#define SCALE_USEC 10000
-#define MY_HOW_OFTEN_TO_ALARM 2 /* How often we want info on screen */
-#define MY_HOW_OFTEN_TO_WRITE 1000 /* How often we want info on screen */
-
-/*
-** Define-funktions for reading and storing in machine independent format
-** (low byte first)
-*/
-
-/* Optimized store functions for Intel x86 */
-#ifdef __i386__
-#define sint2korr(A) (*((int16 *) (A)))
-#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
- (((uint32) 255L << 24) | \
- (((uint32) (uchar) (A)[2]) << 16) |\
- (((uint32) (uchar) (A)[1]) << 8) | \
- ((uint32) (uchar) (A)[0])) : \
- (((uint32) (uchar) (A)[2]) << 16) |\
- (((uint32) (uchar) (A)[1]) << 8) | \
- ((uint32) (uchar) (A)[0])))
-#define sint4korr(A) (*((long *) (A)))
-#define uint2korr(A) (*((uint16 *) (A)))
-#define uint3korr(A) (long) (*((unsigned long *) (A)) & 0xFFFFFF)
-#define uint4korr(A) (*((unsigned long *) (A)))
-#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
- (((uint32) ((uchar) (A)[1])) << 8) +\
- (((uint32) ((uchar) (A)[2])) << 16) +\
- (((uint32) ((uchar) (A)[3])) << 24)) +\
- (((ulonglong) ((uchar) (A)[4])) << 32))
-#define uint8korr(A) (*((ulonglong *) (A)))
-#define sint8korr(A) (*((longlong *) (A)))
-#define int2store(T,A) *((uint16*) (T))= (uint16) (A)
-#define int3store(T,A) { *(T)= (uchar) ((A));\
- *(T+1)=(uchar) (((uint) (A) >> 8));\
- *(T+2)=(uchar) (((A) >> 16)); }
-#define int4store(T,A) *((long *) (T))= (long) (A)
-#define int5store(T,A) { *(T)= (uchar)((A));\
- *((T)+1)=(uchar) (((A) >> 8));\
- *((T)+2)=(uchar) (((A) >> 16));\
- *((T)+3)=(uchar) (((A) >> 24)); \
- *((T)+4)=(uchar) (((A) >> 32)); }
-#define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A)
-
-typedef union {
- double v;
- long m[2];
-} doubleget_union;
-#define doubleget(V,M) \
-{ doubleget_union _tmp; \
- _tmp.m[0] = *((long*)(M)); \
- _tmp.m[1] = *(((long*) (M))+1); \
- (V) = _tmp.v; }
-#define doublestore(T,V) { *((long *) T) = ((doubleget_union *)&V)->m[0]; \
- *(((long *) T)+1) = ((doubleget_union *)&V)->m[1]; }
-#define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); }
-#define float8get(V,M) doubleget((V),(M))
-#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
-#define float8store(V,M) doublestore((V),(M))
-#endif /* __i386__ */
-
-#ifndef sint2korr
-#define sint2korr(A) (int16) (((int16) ((uchar) (A)[0])) +\
- ((int16) ((int16) (A)[1]) << 8))
-#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
- (((uint32) 255L << 24) | \
- (((uint32) (uchar) (A)[2]) << 16) |\
- (((uint32) (uchar) (A)[1]) << 8) | \
- ((uint32) (uchar) (A)[0])) : \
- (((uint32) (uchar) (A)[2]) << 16) |\
- (((uint32) (uchar) (A)[1]) << 8) | \
- ((uint32) (uchar) (A)[0])))
-#define sint4korr(A) (int32) (((int32) ((uchar) (A)[0])) +\
- (((int32) ((uchar) (A)[1]) << 8)) +\
- (((int32) ((uchar) (A)[2]) << 16)) +\
- (((int32) ((int16) (A)[3]) << 24)))
-#define sint8korr(A) (longlong) uint8korr(A)
-#define uint2korr(A) (uint16) (((uint16) ((uchar) (A)[0])) +\
- ((uint16) ((uchar) (A)[1]) << 8))
-#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
- (((uint32) ((uchar) (A)[1])) << 8) +\
- (((uint32) ((uchar) (A)[2])) << 16))
-#define uint4korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
- (((uint32) ((uchar) (A)[1])) << 8) +\
- (((uint32) ((uchar) (A)[2])) << 16) +\
- (((uint32) ((uchar) (A)[3])) << 24))
-#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
- (((uint32) ((uchar) (A)[1])) << 8) +\
- (((uint32) ((uchar) (A)[2])) << 16) +\
- (((uint32) ((uchar) (A)[3])) << 24)) +\
- (((ulonglong) ((uchar) (A)[4])) << 32))
-#define uint8korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
- (((uint32) ((uchar) (A)[1])) << 8) +\
- (((uint32) ((uchar) (A)[2])) << 16) +\
- (((uint32) ((uchar) (A)[3])) << 24)) +\
- (((ulonglong) (((uint32) ((uchar) (A)[4])) +\
- (((uint32) ((uchar) (A)[5])) << 8) +\
- (((uint32) ((uchar) (A)[6])) << 16) +\
- (((uint32) ((uchar) (A)[7])) << 24))) <<\
- 32))
-#define int2store(T,A) { uint def_temp= (uint) (A) ;\
- *((uchar*) (T))= (uchar)(def_temp); \
- *((uchar*) (T+1))=(uchar)((def_temp >> 8)); }
-#define int3store(T,A) { /*lint -save -e734 */\
- *((T))=(char) ((A));\
- *((T)+1)=(char) (((A) >> 8));\
- *((T)+2)=(char) (((A) >> 16)); \
- /*lint -restore */}
-#define int4store(T,A) { *(T)=(char) ((A));\
- *((T)+1)=(char) (((A) >> 8));\
- *((T)+2)=(char) (((A) >> 16));\
- *((T)+3)=(char) (((A) >> 24)); }
-#define int5store(T,A) { *(T)=((A));\
- *((T)+1)=(((A) >> 8));\
- *((T)+2)=(((A) >> 16));\
- *((T)+3)=(((A) >> 24)); \
- *((T)+4)=(((A) >> 32)); }
-#define int8store(T,A) { uint def_temp= (uint) (A), def_temp2= (uint) ((A) >> 32); \
- int4store((T),def_temp); \
- int4store((T+4),def_temp2); \
- }
-#ifdef WORDS_BIGENDIAN
-#define float4store(T,A) { *(T)= ((byte *) &A)[3];\
- *((T)+1)=(char) ((byte *) &A)[2];\
- *((T)+2)=(char) ((byte *) &A)[1];\
- *((T)+3)=(char) ((byte *) &A)[0]; }
-
-#define float4get(V,M) { float def_temp;\
- ((byte*) &def_temp)[0]=(M)[3];\
- ((byte*) &def_temp)[1]=(M)[2];\
- ((byte*) &def_temp)[2]=(M)[1];\
- ((byte*) &def_temp)[3]=(M)[0];\
- (V)=def_temp; }
-#define float8store(T,V) { *(T)= ((byte *) &V)[7];\
- *((T)+1)=(char) ((byte *) &V)[6];\
- *((T)+2)=(char) ((byte *) &V)[5];\
- *((T)+3)=(char) ((byte *) &V)[4];\
- *((T)+4)=(char) ((byte *) &V)[3];\
- *((T)+5)=(char) ((byte *) &V)[2];\
- *((T)+6)=(char) ((byte *) &V)[1];\
- *((T)+7)=(char) ((byte *) &V)[0]; }
-
-#define float8get(V,M) { double def_temp;\
- ((byte*) &def_temp)[0]=(M)[7];\
- ((byte*) &def_temp)[1]=(M)[6];\
- ((byte*) &def_temp)[2]=(M)[5];\
- ((byte*) &def_temp)[3]=(M)[4];\
- ((byte*) &def_temp)[4]=(M)[3];\
- ((byte*) &def_temp)[5]=(M)[2];\
- ((byte*) &def_temp)[6]=(M)[1];\
- ((byte*) &def_temp)[7]=(M)[0];\
- (V) = def_temp; }
-#else
-#define float4get(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(float))
-#define float4store(V,M) memcpy_fixed((byte*) V,(byte*) (&M),sizeof(float))
-
-#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
-#define doublestore(T,V) { *(T)= ((byte *) &V)[4];\
- *((T)+1)=(char) ((byte *) &V)[5];\
- *((T)+2)=(char) ((byte *) &V)[6];\
- *((T)+3)=(char) ((byte *) &V)[7];\
- *((T)+4)=(char) ((byte *) &V)[0];\
- *((T)+5)=(char) ((byte *) &V)[1];\
- *((T)+6)=(char) ((byte *) &V)[2];\
- *((T)+7)=(char) ((byte *) &V)[3]; }
-#define doubleget(V,M) { double def_temp;\
- ((byte*) &def_temp)[0]=(M)[4];\
- ((byte*) &def_temp)[1]=(M)[5];\
- ((byte*) &def_temp)[2]=(M)[6];\
- ((byte*) &def_temp)[3]=(M)[7];\
- ((byte*) &def_temp)[4]=(M)[0];\
- ((byte*) &def_temp)[5]=(M)[1];\
- ((byte*) &def_temp)[6]=(M)[2];\
- ((byte*) &def_temp)[7]=(M)[3];\
- (V) = def_temp; }
-#endif /* __FLOAT_WORD_ORDER */
-
-#define float8get(V,M) doubleget((V),(M))
-#define float8store(V,M) doublestore((V),(M))
-#endif /* WORDS_BIGENDIAN */
-
-#endif /* sint2korr */
-
-/*
- Define-funktions for reading and storing in machine format from/to
- short/long to/from some place in memory V should be a (not
- register) variable, M is a pointer to byte
-*/
-
-#ifdef WORDS_BIGENDIAN
-
-#define ushortget(V,M) { V = (uint16) (((uint16) ((uchar) (M)[1]))+\
- ((uint16) ((uint16) (M)[0]) << 8)); }
-#define shortget(V,M) { V = (short) (((short) ((uchar) (M)[1]))+\
- ((short) ((short) (M)[0]) << 8)); }
-#define longget(V,M) { int32 def_temp;\
- ((byte*) &def_temp)[0]=(M)[0];\
- ((byte*) &def_temp)[1]=(M)[1];\
- ((byte*) &def_temp)[2]=(M)[2];\
- ((byte*) &def_temp)[3]=(M)[3];\
- (V)=def_temp; }
-#define ulongget(V,M) { uint32 def_temp;\
- ((byte*) &def_temp)[0]=(M)[0];\
- ((byte*) &def_temp)[1]=(M)[1];\
- ((byte*) &def_temp)[2]=(M)[2];\
- ((byte*) &def_temp)[3]=(M)[3];\
- (V)=def_temp; }
-#define shortstore(T,A) { uint def_temp=(uint) (A) ;\
- *(T+1)=(char)(def_temp); \
- *(T+0)=(char)(def_temp >> 8); }
-#define longstore(T,A) { *((T)+3)=((A));\
- *((T)+2)=(((A) >> 8));\
- *((T)+1)=(((A) >> 16));\
- *((T)+0)=(((A) >> 24)); }
-
-#define doubleget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(double))
-#define doublestore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(double))
-#define longlongget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(ulonglong))
-#define longlongstore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(ulonglong))
-
-#else
-
-#define ushortget(V,M) { V = uint2korr(M); }
-#define shortget(V,M) { V = sint2korr(M); }
-#define longget(V,M) { V = sint4korr(M); }
-#define ulongget(V,M) { V = uint4korr(M); }
-#define shortstore(T,V) int2store(T,V)
-#define longstore(T,V) int4store(T,V)
-#ifndef doubleget
-#define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double))
-#define doublestore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(double))
-#endif /* doubleget */
-#define longlongget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(ulonglong))
-#define longlongstore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(ulonglong))
-
-#endif /* WORDS_BIGENDIAN */
-
-/* sprintf does not always return the number of bytes :- */
-#ifdef SPRINTF_RETURNS_INT
-#define my_sprintf(buff,args) sprintf args
-#else
-#ifdef SPRINTF_RETURNS_PTR
-#define my_sprintf(buff,args) ((int)(sprintf args - buff))
-#else
-#define my_sprintf(buff,args) sprintf args,strlen(buff)
-#endif
-#endif
-
-#ifndef THREAD
-#define thread_safe_increment(V,L) (V)++
-#define thread_safe_add(V,C,L) (V)+=(C)
-#define thread_safe_sub(V,C,L) (V)-=(C)
-#define statistic_increment(V,L) (V)++
-#define statistic_add(V,C,L) (V)+=(C)
-#endif
-
-#endif /* _global_h */
diff --git a/include/hash.h b/include/hash.h
index 2f6a424fb3c..e9c8c73c05b 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Dynamic hashing of record with different key-length */
@@ -55,6 +54,7 @@ gptr hash_next(HASH *info,const byte *key,uint length);
my_bool hash_insert(HASH *info,const byte *data);
my_bool hash_delete(HASH *hash,byte *record);
my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length);
+void hash_replace(HASH *hash, uint idx, byte *new_row);
my_bool hash_check(HASH *hash); /* Only in debug library */
#define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
diff --git a/include/heap.h b/include/heap.h
index 14698810297..ed023133469 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using heap_database_funktions */
/* Author: Michael Widenius */
@@ -48,6 +47,7 @@ typedef struct st_heapinfo /* Struct from heap_info */
ulong index_length;
uint reclength; /* Length of one record */
int errkey;
+ my_bool implicit_emptied;
} HEAPINFO;
@@ -79,11 +79,13 @@ typedef struct st_hp_keyseg /* Key-portion */
uint start; /* Start of key in record (from 0) */
uint length; /* Keylength */
uint type;
+ uint null_bit; /* bit set in row+null_pos */
+ uint null_pos;
} HP_KEYSEG;
typedef struct st_hp_keydef /* Key definition with open */
{
- uint flag; /* NOSAME */
+ uint flag; /* HA_NOSAME | HA_NULL_PART_KEY */
uint keysegs; /* Number of key-segment */
uint length; /* Length of key (automatic) */
HP_KEYSEG *seg;
@@ -109,6 +111,7 @@ typedef struct st_heap_share
THR_LOCK lock;
pthread_mutex_t intern_lock; /* Locking for use with _locking */
#endif
+ my_bool delete_on_close;
LIST open_list;
} HP_SHARE;
@@ -124,6 +127,7 @@ typedef struct st_heap_info
int mode; /* Mode of file (READONLY..) */
uint opt_flag,update;
byte *lastkey; /* Last used key with rkey */
+ my_bool implicit_emptied;
#ifdef THREAD
THR_LOCK_DATA lock;
#endif
@@ -144,7 +148,7 @@ extern int heap_scan(register HP_INFO *info, byte *record);
extern int heap_delete(HP_INFO *info,const byte *buff);
extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag);
extern int heap_create(const char *name);
-extern int heap_delete_all(const char *name);
+extern int heap_delete_table(const char *name);
extern int heap_extra(HP_INFO *info,enum ha_extra_function function);
extern int heap_rename(const char *old_name,const char *new_name);
extern int heap_panic(enum ha_panic_function flag);
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 645c07b79ae..b3e50cec58f 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
A better inplementation of the UNIX ctype(3) library.
- Notes: global.h should be included before ctype.h
+ Notes: my_global.h should be included before ctype.h
*/
#ifndef _m_ctype_h
@@ -57,13 +56,12 @@ extern CHARSET_INFO *default_charset_info;
extern CHARSET_INFO *find_compiled_charset(uint cs_number);
extern CHARSET_INFO *find_compiled_charset_by_name(const char *name);
extern CHARSET_INFO compiled_charsets[];
+extern uint compiled_charset_number(const char *name);
+extern const char *compiled_charset_name(uint charset_number);
#define MY_CHARSET_UNDEFINED 0
#define MY_CHARSET_CURRENT (default_charset_info->number)
-#ifdef __WIN__
-#include <ctype.h>
-#endif
/* Don't include std ctype.h when this is included */
#define _CTYPE_H
#define _CTYPE_H_
@@ -71,12 +69,32 @@ extern CHARSET_INFO compiled_charsets[];
#define __CTYPE_INCLUDED
#define _CTYPE_USING /* Don't put names in global namespace. */
+/* Fix things, if ctype.h would have been included before */
+#undef toupper
+#undef _toupper
+#undef _tolower
+#undef toupper
+#undef tolower
+#undef isalpha
+#undef isupper
+#undef islower
+#undef isdigit
+#undef isxdigit
+#undef isalnum
+#undef isspace
+#undef ispunct
+#undef isprint
+#undef isgraph
+#undef iscntrl
+#undef isascii
+#undef toascii
+
#define _U 01 /* Upper case */
#define _L 02 /* Lower case */
-#define _N 04 /* Numeral (digit) */
-#define _S 010 /* Spacing character */
-#define _P 020 /* Punctuation */
-#define _C 040 /* Control character */
+#define _NMR 04 /* Numeral (digit) */
+#define _SPC 010 /* Spacing character */
+#define _PNT 020 /* Punctuation */
+#define _CTR 040 /* Control character */
#define _B 0100 /* Blank */
#define _X 0200 /* heXadecimal digit */
@@ -85,7 +103,6 @@ extern CHARSET_INFO compiled_charsets[];
#define my_to_lower (default_charset_info->to_lower)
#define my_sort_order (default_charset_info->sort_order)
-#ifndef __WIN__
#define _toupper(c) (char) my_to_upper[(uchar) (c)]
#define _tolower(c) (char) my_to_lower[(uchar) (c)]
#define toupper(c) (char) my_to_upper[(uchar) (c)]
@@ -94,14 +111,14 @@ extern CHARSET_INFO compiled_charsets[];
#define isalpha(c) ((my_ctype+1)[(uchar) (c)] & (_U | _L))
#define isupper(c) ((my_ctype+1)[(uchar) (c)] & _U)
#define islower(c) ((my_ctype+1)[(uchar) (c)] & _L)
-#define isdigit(c) ((my_ctype+1)[(uchar) (c)] & _N)
+#define isdigit(c) ((my_ctype+1)[(uchar) (c)] & _NMR)
#define isxdigit(c) ((my_ctype+1)[(uchar) (c)] & _X)
-#define isalnum(c) ((my_ctype+1)[(uchar) (c)] & (_U | _L | _N))
-#define isspace(c) ((my_ctype+1)[(uchar) (c)] & _S)
-#define ispunct(c) ((my_ctype+1)[(uchar) (c)] & _P)
-#define isprint(c) ((my_ctype+1)[(uchar) (c)] & (_P | _U | _L | _N | _B))
-#define isgraph(c) ((my_ctype+1)[(uchar) (c)] & (_P | _U | _L | _N))
-#define iscntrl(c) ((my_ctype+1)[(uchar) (c)] & _C)
+#define isalnum(c) ((my_ctype+1)[(uchar) (c)] & (_U | _L | _NMR))
+#define isspace(c) ((my_ctype+1)[(uchar) (c)] & _SPC)
+#define ispunct(c) ((my_ctype+1)[(uchar) (c)] & _PNT)
+#define isprint(c) ((my_ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR | _B))
+#define isgraph(c) ((my_ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR))
+#define iscntrl(c) ((my_ctype+1)[(uchar) (c)] & _CTR)
#define isascii(c) (!((c) & ~0177))
#define toascii(c) ((c) & 0177)
@@ -109,25 +126,22 @@ extern CHARSET_INFO compiled_charsets[];
#undef ctype
#endif /* ctype */
-#endif /* __WIN__ */
-
#define my_isalpha(s, c) (((s)->ctype+1)[(uchar) (c)] & (_U | _L))
#define my_isupper(s, c) (((s)->ctype+1)[(uchar) (c)] & _U)
#define my_islower(s, c) (((s)->ctype+1)[(uchar) (c)] & _L)
-#define my_isdigit(s, c) (((s)->ctype+1)[(uchar) (c)] & _N)
+#define my_isdigit(s, c) (((s)->ctype+1)[(uchar) (c)] & _NMR)
#define my_isxdigit(s, c) (((s)->ctype+1)[(uchar) (c)] & _X)
-#define my_isalnum(s, c) (((s)->ctype+1)[(uchar) (c)] & (_U | _L | _N))
-#define my_isspace(s, c) (((s)->ctype+1)[(uchar) (c)] & _S)
-#define my_ispunct(s, c) (((s)->ctype+1)[(uchar) (c)] & _P)
-#define my_isprint(s, c) (((s)->ctype+1)[(uchar) (c)] & (_P | _U | _L | _N | _B))
-#define my_isgraph(s, c) (((s)->ctype+1)[(uchar) (c)] & (_P | _U | _L | _N))
-#define my_iscntrl(s, c) (((s)->ctype+1)[(uchar) (c)] & _C)
+#define my_isalnum(s, c) (((s)->ctype+1)[(uchar) (c)] & (_U | _L | _NMR))
+#define my_isspace(s, c) (((s)->ctype+1)[(uchar) (c)] & _SPC)
+#define my_ispunct(s, c) (((s)->ctype+1)[(uchar) (c)] & _PNT)
+#define my_isprint(s, c) (((s)->ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR | _B))
+#define my_isgraph(s, c) (((s)->ctype+1)[(uchar) (c)] & (_PNT | _U | _L | _NMR))
+#define my_iscntrl(s, c) (((s)->ctype+1)[(uchar) (c)] & _CTR)
#define use_strcoll(s) ((s)->strcoll != NULL)
#define MY_STRXFRM_MULTIPLY (default_charset_info->strxfrm_multiply)
#define my_strnxfrm(s, a, b, c, d) ((s)->strnxfrm((a), (b), (c), (d)))
#define my_strnncoll(s, a, b, c, d) ((s)->strnncoll((a), (b), (c), (d)))
-#define my_strxfrm(s, a, b, c, d) ((s)->strnxfrm((a), (b), (c)))
#define my_strcoll(s, a, b) ((s)->strcoll((a), (b)))
#define my_like_range(s, a, b, c, d, e, f, g, h) \
((s)->like_range((a), (b), (c), (d), (e), (f), (g), (h)))
diff --git a/include/m_string.h b/include/m_string.h
index 7eb2f1fe690..eac1552f8c1 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* There may be prolems include all of theese. Try to test in
configure with ones are needed? */
@@ -120,6 +119,16 @@ extern void bmove_allign(gptr dst,const gptr src,uint len);
#define bmove512(A,B,C) memcpy(A,B,C)
#endif
+#ifdef HAVE_purify
+#include <assert.h>
+#define memcpy_overlap(A,B,C) \
+DBUG_ASSERT((A) == (B) || ((A)+(C)) <= (B) || ((B)+(C)) <= (A)); \
+bmove((byte*) key,(byte*) from,(size_t) length);
+#else
+#define memcpy_overlap(A,B,C) memcpy((A), (B), (C))
+#endif /* HAVE_purify */
+
+
/* Prototypes for string functions */
#if !defined(bfill) && !defined(HAVE_BFILL)
@@ -132,11 +141,12 @@ extern void bzero(gptr dst,uint len);
#if !defined(bcmp) && !defined(HAVE_BCMP)
extern int bcmp(const char *s1,const char *s2,uint len);
+#endif
#ifdef HAVE_purify
extern int my_bcmp(const char *s1,const char *s2,uint len);
+#undef bcmp
#define bcmp(A,B,C) my_bcmp((A),(B),(C))
#endif
-#endif
#ifndef bmove512
extern void bmove512(gptr dst,const gptr src,uint len);
diff --git a/include/md5.h b/include/md5.h
new file mode 100644
index 00000000000..aa4116ff17f
--- /dev/null
+++ b/include/md5.h
@@ -0,0 +1,93 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* GLOBAL.H - RSAREF types and constants
+ */
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+ function argument prototyping.
+The following makes PROTOTYPES default to 0 if it has not already
+ been defined with C compiler flags.
+ */
+
+/* egcs 1.1.2 under linux didn't defined it.... :( */
+
+#ifndef PROTOTYPES
+#define PROTOTYPES 1 /* Assume prototypes */
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef uint16 UINT2; /* Fix for MySQL / Alpha */
+
+/* UINT4 defines a four byte word */
+typedef uint32 UINT4; /* Fix for MySQL / Alpha */
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+ returns an empty list.
+ */
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else
+#define PROTO_LIST(list) ()
+#endif
+/* MD5 context. */
+typedef struct {
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} my_MD5_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void my_MD5Init PROTO_LIST ((my_MD5_CTX *));
+ void my_MD5Update PROTO_LIST
+ ((my_MD5_CTX *, unsigned char *, unsigned int));
+ void my_MD5Final PROTO_LIST ((unsigned char [16], my_MD5_CTX *));
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/merge.h b/include/merge.h
index c661e03a0c7..97cea5fabb1 100644
--- a/include/merge.h
+++ b/include/merge.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using merge_isam_funktions */
/* Author: Michael Widenius */
diff --git a/include/my_aes.h b/include/my_aes.h
new file mode 100644
index 00000000000..5852baa5892
--- /dev/null
+++ b/include/my_aes.h
@@ -0,0 +1,66 @@
+/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/* Header file for my_aes.c */
+/* Wrapper to give simple interface for MySQL to AES standard encryption */
+
+#include "rijndael.h"
+
+C_MODE_START
+
+#define AES_KEY_LENGTH 128 /* Must be 128 192 or 256 */
+
+/*
+ my_aes_encrypt - Crypt buffer with AES encryption algorithm.
+ source - Pointer to data for encryption
+ source_length - size of encryption data
+ dest - buffer to place encrypted data (must be large enough)
+ key - Key to be used for encryption
+ kel_length - Length of the key. Will handle keys of any length
+
+ returns - size of encrypted data, or negative in case of error.
+*/
+
+int my_aes_encrypt(const char *source, int source_length, char *dest,
+ const char *key, int key_length);
+
+/*
+ my_aes_decrypt - DeCrypt buffer with AES encryption algorithm.
+ source - Pointer to data for decryption
+ source_length - size of encrypted data
+ dest - buffer to place decrypted data (must be large enough)
+ key - Key to be used for decryption
+ kel_length - Length of the key. Will handle keys of any length
+
+ returns - size of original data, or negative in case of error.
+*/
+
+
+int my_aes_decrypt(const char *source, int source_length, char *dest,
+ const char *key, int key_length);
+
+/*
+ my_aes_get_size - get size of buffer which will be large enough for encrypted
+ data
+ source_length - length of data to be encrypted
+
+ returns - size of buffer required to store encrypted data
+*/
+
+int my_aes_get_size(int source_length);
+
+C_MODE_END
diff --git a/include/my_alarm.h b/include/my_alarm.h
index b6c5ca6a3f4..fdfce9c65c9 100644
--- a/include/my_alarm.h
+++ b/include/my_alarm.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
File to include when we want to use alarm or a loop_counter to display
diff --git a/include/my_alloc.h b/include/my_alloc.h
new file mode 100644
index 00000000000..a3dd35d7ea3
--- /dev/null
+++ b/include/my_alloc.h
@@ -0,0 +1,52 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Data structures for mysys/my_alloc.c (root memory allocator)
+*/
+
+#ifndef _my_alloc_h
+#define _my_alloc_h
+
+#define ALLOC_MAX_BLOCK_TO_DROP 4096
+#define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10
+
+typedef struct st_used_mem
+{ /* struct for once_alloc (block) */
+ struct st_used_mem *next; /* Next block in use */
+ unsigned int left; /* memory left in block */
+ unsigned int size; /* size of block */
+} USED_MEM;
+
+
+typedef struct st_mem_root
+{
+ USED_MEM *free; /* blocks with free memory in it */
+ USED_MEM *used; /* blocks almost without free memory */
+ USED_MEM *pre_alloc; /* preallocated block */
+ /* if block have less memory it will be put in 'used' list */
+ unsigned int min_malloc;
+ unsigned int block_size; /* initial block size */
+ unsigned int block_num; /* allocated blocks counter */
+ /*
+ first free block in queue test counter (if it exceed
+ MAX_BLOCK_USAGE_BEFORE_DROP block will be droped in 'used' list)
+ */
+ unsigned int first_block_usage;
+
+ void (*error_handler)(void);
+} MEM_ROOT;
+#endif
diff --git a/include/my_base.h b/include/my_base.h
index dff1553cf20..5344d876f99 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file includes constants used with all databases */
/* Author: Michael Widenius */
@@ -24,7 +23,7 @@
#ifndef stdin /* Included first in handler */
#define USES_TYPES /* my_dir with sys/types is included */
#define CHSIZE_USED
-#include <global.h>
+#include <my_global.h>
#include <my_dir.h> /* This includes types */
#include <my_sys.h>
#include <m_string.h>
@@ -50,6 +49,21 @@
/* The following is parameter to ha_rkey() how to use key */
+/* We define a complete-field prefix of a key value as a prefix where the
+last included field in the prefix contains the full field, not just some bytes
+from the start of the field. A partial-field prefix is allowed to
+contain only a few first bytes from the last included field.
+
+Below HA_READ_KEY_EXACT, ..., HA_READ_BEFORE_KEY can take a
+complete-field prefix of a key value as the search key. HA_READ_PREFIX
+and HA_READ_PREFIX_LAST could also take a partial-field prefix, but
+currently (4.0.10) they are only used with complete-field prefixes. MySQL uses
+a padding trick to implement LIKE 'abc%' queries.
+
+NOTE that in InnoDB HA_READ_PREFIX_LAST will NOT work with a partial-field
+prefix because InnoDB currently strips spaces from the end of varchar
+fields! */
+
enum ha_rkey_function {
HA_READ_KEY_EXACT, /* Find first record else error */
HA_READ_KEY_OR_NEXT, /* Record or next record */
@@ -57,7 +71,22 @@ enum ha_rkey_function {
HA_READ_AFTER_KEY, /* Find next rec. after key-record */
HA_READ_BEFORE_KEY, /* Find next rec. before key-record */
HA_READ_PREFIX, /* Key which as same prefix */
- HA_READ_PREFIX_LAST /* Last key with the same prefix */
+ HA_READ_PREFIX_LAST, /* Last key with the same prefix */
+ HA_READ_MBR_CONTAIN,
+ HA_READ_MBR_INTERSECT,
+ HA_READ_MBR_WITHIN,
+ HA_READ_MBR_DISJOINT,
+ HA_READ_MBR_EQUAL
+};
+
+ /* Key algorithm types */
+
+enum ha_key_alg {
+ HA_KEY_ALG_UNDEF= 0, /* Not specified (old file) */
+ HA_KEY_ALG_BTREE= 1, /* B-tree, default one */
+ HA_KEY_ALG_RTREE= 2, /* R-tree, for spatial searches */
+ HA_KEY_ALG_HASH= 3, /* HASH keys (HEAP tables) */
+ HA_KEY_ALG_FULLTEXT= 4 /* FULLTEXT (MyISAM tables) */
};
/* The following is parameter to ha_extra() */
@@ -91,7 +120,9 @@ enum ha_extra_function {
HA_EXTRA_RESET_STATE, /* Reset positions */
HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/
HA_EXTRA_NO_IGNORE_DUP_KEY,
- HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE /* Cursor will not be used for update */
+ HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE, /* Cursor will not be used for update */
+ HA_EXTRA_PREPARE_FOR_DELETE,
+ HA_EXTRA_PREPARE_FOR_UPDATE /* Remove read cache if problems */
};
/* The following is parameter to ha_panic() */
@@ -134,8 +165,10 @@ enum ha_base_keytype {
#define HA_BINARY_PACK_KEY 32 /* Packing of all keys to prev key */
#define HA_FULLTEXT 128 /* SerG: for full-text search */
#define HA_UNIQUE_CHECK 256 /* Check the key for uniqueness */
+#define HA_SPATIAL 1024 /* Alex Barkov: for spatial search */
#define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */
+
/* Automatic bits in key-flag */
#define HA_SPACE_PACK_USED 4 /* Test for if SPACE_PACK used */
@@ -147,16 +180,23 @@ enum ha_base_keytype {
/* poor old NISAM has 8-bit flags :-( */
#define HA_SORT_ALLOWS_SAME 128 /* Intern bit when sorting records */
#endif
+/*
+ Key has a part that can have end space. If this is an unique key
+ we have to handle it differently from other unique keys as we can find
+ many matching rows for one key (becaue end space are not compared)
+*/
+#define HA_END_SPACE_KEY 4096
- /* These flags can be order to key-seg-flag */
+ /* These flags can be added to key-seg-flag */
#define HA_SPACE_PACK 1 /* Pack space in key-seg */
-#define HA_PART_KEY 4 /* Used by MySQL for part-key-cols */
+#define HA_PART_KEY_SEG 4 /* Used by MySQL for part-key-cols */
#define HA_VAR_LENGTH 8
#define HA_NULL_PART 16
#define HA_BLOB_PART 32
#define HA_SWAP_KEY 64
#define HA_REVERSE_SORT 128 /* Sort key in reverse order */
+#define HA_NO_SORT 256 /* do not bother sorting on this keyseg */
/* optionbits for database */
#define HA_OPTION_PACK_RECORD 1
@@ -190,6 +230,7 @@ enum ha_base_keytype {
/* Errorcodes given by functions */
+/* opt_sum_query() assumes these codes are > 1 */
#define HA_ERR_KEY_NOT_FOUND 120 /* Didn't find key on read or update */
#define HA_ERR_FOUND_DUPP_KEY 121 /* Dupplicate key on write */
#define HA_ERR_RECORD_CHANGED 123 /* Uppdate with is recoverable */
@@ -197,6 +238,7 @@ enum ha_base_keytype {
#define HA_ERR_CRASHED 126 /* Indexfile is crashed */
#define HA_ERR_WRONG_IN_RECORD 127 /* Record-file is crashed */
#define HA_ERR_OUT_OF_MEM 128 /* Record-file is crashed */
+#define HA_ERR_NOT_A_TABLE 130 /* not a MYI file - no signature */
#define HA_ERR_WRONG_COMMAND 131 /* Command not supported */
#define HA_ERR_OLD_FILE 132 /* old databasfile */
#define HA_ERR_NO_ACTIVE_RECORD 133 /* No record read in update() */
@@ -209,20 +251,22 @@ enum ha_base_keytype {
#define HA_WRONG_CREATE_OPTION 140 /* Wrong create option */
#define HA_ERR_FOUND_DUPP_UNIQUE 141 /* Dupplicate unique on write */
#define HA_ERR_UNKNOWN_CHARSET 142 /* Can't open charset */
-#define HA_ERR_WRONG_TABLE_DEF 143
+#define HA_ERR_WRONG_MRG_TABLE_DEF 143 /* conflicting MyISAM tables in MERGE */
#define HA_ERR_CRASHED_ON_REPAIR 144 /* Last (automatic?) repair failed */
#define HA_ERR_CRASHED_ON_USAGE 145 /* Table must be repaired */
-#define HA_ERR_LOCK_WAIT_TIMEOUT 146
+#define HA_ERR_LOCK_WAIT_TIMEOUT 146
#define HA_ERR_LOCK_TABLE_FULL 147
#define HA_ERR_READ_ONLY_TRANSACTION 148 /* Updates not allowed */
#define HA_ERR_LOCK_DEADLOCK 149
#define HA_ERR_CANNOT_ADD_FOREIGN 150 /* Cannot add a foreign key constr. */
#define HA_ERR_NO_REFERENCED_ROW 151 /* Cannot add a child row */
#define HA_ERR_ROW_IS_REFERENCED 152 /* Cannot delete a parent row */
+#define HA_ERR_NO_SAVEPOINT 153 /* No savepoint with that name */
/* Other constants */
#define HA_NAMELEN 64 /* Max length of saved filename */
+#define NO_SUCH_KEY ((uint)~0) /* used as a key no. */
/* Intern constants in databases */
@@ -236,7 +280,14 @@ enum ha_base_keytype {
#define SEARCH_UPDATE 64
#define SEARCH_PREFIX 128
#define SEARCH_LAST 256
+#define MBR_CONTAIN 512
+#define MBR_INTERSECT 1024
+#define MBR_WITHIN 2048
+#define MBR_DISJOINT 4096
+#define MBR_EQUAL 8192
+#define MBR_DATA 16384
#define SEARCH_NULL_ARE_EQUAL 32768 /* NULL in keys are equal */
+#define SEARCH_NULL_ARE_NOT_EQUAL 65536 /* NULL in keys are not equal */
/* bits in opt_flag */
#define QUICK_USED 1
@@ -261,8 +312,8 @@ enum ha_base_keytype {
#define HA_STATE_EXTEND_BLOCK 2048
enum en_fieldtype {
- FIELD_LAST=-1,FIELD_NORMAL,FIELD_SKIPP_ENDSPACE,FIELD_SKIPP_PRESPACE,
- FIELD_SKIPP_ZERO,FIELD_BLOB,FIELD_CONSTANT,FIELD_INTERVALL,FIELD_ZERO,
+ FIELD_LAST=-1,FIELD_NORMAL,FIELD_SKIP_ENDSPACE,FIELD_SKIP_PRESPACE,
+ FIELD_SKIP_ZERO,FIELD_BLOB,FIELD_CONSTANT,FIELD_INTERVALL,FIELD_ZERO,
FIELD_VARCHAR,FIELD_CHECK
};
@@ -272,8 +323,10 @@ enum data_file_type {
/* For number of records */
#ifdef BIG_TABLES
+#define rows2double(A) ulonglong2double(A)
typedef my_off_t ha_rows;
#else
+#define rows2double(A) (double) (A)
typedef ulong ha_rows;
#endif
diff --git a/include/my_bitmap.h b/include/my_bitmap.h
index 3243e5f0b24..ca0037addfb 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _my_bitmap_h_
#define _my_bitmap_h_
diff --git a/include/my_dbug.h b/include/my_dbug.h
new file mode 100644
index 00000000000..5c88e2e42db
--- /dev/null
+++ b/include/my_dbug.h
@@ -0,0 +1,93 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef _dbug_h
+#define _dbug_h
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if !defined(DBUG_OFF) && !defined(_lint)
+extern int _db_on_,_no_db_;
+extern FILE *_db_fp_;
+extern char *_db_process_;
+extern int _db_keyword_(const char *keyword);
+extern void _db_setjmp_(void);
+extern void _db_longjmp_(void);
+extern void _db_push_(const char *control);
+extern void _db_pop_(void);
+extern void _db_enter_(const char *_func_,const char *_file_,uint _line_,
+ const char **_sfunc_,const char **_sfile_,
+ uint *_slevel_, char ***);
+extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_,
+ uint *_slevel_);
+extern void _db_pargs_(uint _line_,const char *keyword);
+extern void _db_doprnt_ _VARARGS((const char *format,...));
+extern void _db_dump_(uint _line_,const char *keyword,const char *memory,
+ uint length);
+extern void _db_lock_file();
+extern void _db_unlock_file();
+
+#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \
+ char **_db_framep_; \
+ _db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \
+ &_db_framep_)
+#define DBUG_LEAVE \
+ (_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_))
+#define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);}
+#define DBUG_VOID_RETURN {DBUG_LEAVE; return;}
+#define DBUG_EXECUTE(keyword,a1) \
+ {if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}}
+#define DBUG_PRINT(keyword,arglist) \
+ {if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}}
+#define DBUG_PUSH(a1) _db_push_ (a1)
+#define DBUG_POP() _db_pop_ ()
+#define DBUG_PROCESS(a1) (_db_process_ = a1)
+#define DBUG_FILE (_db_fp_)
+#define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1))
+#define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2))
+#define DBUG_DUMP(keyword,a1,a2)\
+ {if (_db_on_) {_db_dump_(__LINE__,keyword,a1,a2);}}
+#define DBUG_IN_USE (_db_fp_ && _db_fp_ != stderr)
+#define DEBUGGER_OFF _no_db_=1;_db_on_=0;
+#define DEBUGGER_ON _no_db_=0
+#define DBUG_LOCK_FILE { _db_lock_file(); }
+#define DBUG_UNLOCK_FILE { _db_unlock_file(); }
+#define DBUG_ASSERT(A) assert(A)
+#else /* No debugger */
+
+#define DBUG_ENTER(a1)
+#define DBUG_RETURN(a1) return(a1)
+#define DBUG_VOID_RETURN return
+#define DBUG_EXECUTE(keyword,a1) {}
+#define DBUG_PRINT(keyword,arglist) {}
+#define DBUG_PUSH(a1) {}
+#define DBUG_POP() {}
+#define DBUG_PROCESS(a1) {}
+#define DBUG_FILE (stderr)
+#define DBUG_SETJMP setjmp
+#define DBUG_LONGJMP longjmp
+#define DBUG_DUMP(keyword,a1,a2) {}
+#define DBUG_IN_USE 0
+#define DEBUGGER_OFF
+#define DEBUGGER_ON
+#define DBUG_LOCK_FILE
+#define DBUG_UNLOCK_FILE
+#define DBUG_ASSERT(A) {}
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/my_dir.h b/include/my_dir.h
index 1961ca79549..851b6d8d7e9 100644
--- a/include/my_dir.h
+++ b/include/my_dir.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _my_dir_h
#define _my_dir_h
@@ -75,14 +74,21 @@ typedef struct my_stat
#endif /* USE_MY_STAT_STRUCT */
-typedef struct fileinfo /* Struct returned from my_dir & my_stat */
+/* Struct describing one file returned from my_dir */
+typedef struct fileinfo
{
char *name;
- MY_STAT mystat;
+ MY_STAT *mystat;
} FILEINFO;
typedef struct st_my_dir /* Struct returned from my_dir */
{
+ /*
+ These members are just copies of parts of DYNAMIC_ARRAY structure,
+ which is allocated right after the end of MY_DIR structure (MEM_ROOT
+ for storing names is also resides there). We've left them here because
+ we don't want to change code that uses my_dir.
+ */
struct fileinfo *dir_entry;
uint number_off_files;
} MY_DIR;
diff --git a/include/my_getopt.h b/include/my_getopt.h
new file mode 100644
index 00000000000..3b4551b445e
--- /dev/null
+++ b/include/my_getopt.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+C_MODE_START
+
+enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_INT, GET_UINT, GET_LONG,
+ GET_ULONG, GET_LL, GET_ULL, GET_STR, GET_STR_ALLOC };
+enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };
+
+struct my_option
+{
+ const char *name; /* Name of the option */
+ int id; /* unique id or short option */
+ const char *comment; /* option comment, for autom. --help */
+ gptr *value; /* The variable value */
+ gptr *u_max_value; /* The user def. max variable value */
+ const char **str_values; /* Pointer to possible values */
+ enum get_opt_var_type var_type;
+ enum get_opt_arg_type arg_type;
+ longlong def_value; /* Default value */
+ longlong min_value; /* Min allowed value */
+ longlong max_value; /* Max allowed value */
+ longlong sub_size; /* Subtract this from given value */
+ long block_size; /* Value should be a mult. of this */
+ int app_type; /* To be used by an application */
+};
+
+extern char *disabled_my_option;
+extern my_bool my_getopt_print_errors;
+
+extern int handle_options (int *argc, char ***argv,
+ const struct my_option *longopts,
+ my_bool (*get_one_option)(int,
+ const struct my_option *,
+ char *));
+extern void my_print_help(const struct my_option *options);
+extern void my_print_variables(const struct my_option *options);
+
+ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp);
+my_bool getopt_compare_strings(const char *s, const char *t, uint length);
+C_MODE_END
diff --git a/include/my_global.h b/include/my_global.h
new file mode 100644
index 00000000000..e4c0fb44337
--- /dev/null
+++ b/include/my_global.h
@@ -0,0 +1,1138 @@
+/* Copyright (C) 2000-2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* This is the include file that should be included 'first' in every C file. */
+
+#ifndef _global_h
+#define _global_h
+
+#ifndef EMBEDDED_LIBRARY
+#define HAVE_REPLICATION
+#define HAVE_EXTERNAL_CLIENT
+#endif
+
+#if defined( __EMX__) && !defined( MYSQL_SERVER)
+/* moved here to use below VOID macro redefinition */
+#define INCL_BASE
+#define INCL_NOPMAPI
+#include <os2.h>
+#endif /* __EMX__ */
+
+#ifdef __CYGWIN__
+/* We use a Unix API, so pretend it's not Windows */
+#undef WIN
+#undef WIN32
+#undef _WIN
+#undef _WIN32
+#undef _WIN64
+#undef __WIN__
+#undef __WIN32__
+#define HAVE_ERRNO_AS_DEFINE
+#endif /* __CYGWIN__ */
+
+#if defined(i386) && !defined(__i386__)
+#define __i386__
+#endif
+
+/* Macros to make switching between C and C++ mode easier */
+#ifdef __cplusplus
+#define C_MODE_START extern "C" {
+#define C_MODE_END }
+#else
+#define C_MODE_START
+#define C_MODE_END
+#endif
+
+#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
+#include <config-win.h>
+#elif defined(OS2)
+#include <config-os2.h>
+#elif defined(__NETWARE__)
+#include <my_config.h>
+#include <config-netware.h>
+#if defined(__cplusplus) && defined(inline)
+#undef inline /* fix configure problem */
+#endif
+#else
+#include <my_config.h>
+#if defined(__cplusplus) && defined(inline)
+#undef inline /* fix configure problem */
+#endif
+#endif /* _WIN32... */
+
+/*
+ The macros below are borrowed from include/linux/compiler.h in the
+ Linux kernel. Use them to indicate the likelyhood of the truthfulness
+ of a condition. This serves two purposes - newer versions of gcc will be
+ able to optimize for branch predication, which could yield siginficant
+ performance gains in frequently executed sections of the code, and the
+ other reason to use them is for documentation
+*/
+
+#if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
+#define __builtin_expect(x, expected_value) (x)
+#endif
+
+#define likely(x) __builtin_expect((x),1)
+#define unlikely(x) __builtin_expect((x),0)
+
+
+/* Fix problem with S_ISLNK() on Linux */
+#if defined(HAVE_LINUXTHREADS)
+#undef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+/* The client defines this to avoid all thread code */
+#if defined(UNDEF_THREADS_HACK)
+#undef THREAD
+#undef HAVE_mit_thread
+#undef HAVE_LINUXTHREADS
+#undef HAVE_UNIXWARE7_THREADS
+#endif
+
+#ifdef HAVE_THREADS_WITHOUT_SOCKETS
+/* MIT pthreads does not work with unix sockets */
+#undef HAVE_SYS_UN_H
+#endif
+
+#define __EXTENSIONS__ 1 /* We want some extension */
+#ifndef __STDC_EXT__
+#define __STDC_EXT__ 1 /* To get large file support on hpux */
+#endif
+
+#if defined(THREAD) && !defined(__WIN__) && !defined(OS2)
+#ifndef _POSIX_PTHREAD_SEMANTICS
+#define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */
+#endif
+
+#if !defined(SCO)
+#define _REENTRANT 1 /* Some thread libraries require this */
+#endif
+#if !defined(_THREAD_SAFE) && !defined(_AIX)
+#define _THREAD_SAFE /* Required for OSF1 */
+#endif
+#ifndef HAVE_mit_thread
+#ifdef HAVE_UNIXWARE7_THREADS
+#include <thread.h>
+#else
+#include <pthread.h> /* AIX must have this included first */
+#endif /* HAVE_UNIXWARE7_THREADS */
+#endif /* HAVE_mit_thread */
+#if !defined(SCO) && !defined(_REENTRANT)
+#define _REENTRANT 1 /* Threads requires reentrant code */
+#endif
+#endif /* THREAD */
+
+/* Go around some bugs in different OS and compilers */
+#ifdef _AIX /* By soren@t.dk */
+#define _H_STRINGS
+#define _SYS_STREAM_H
+/* #define _AIX32_CURSES */ /* XXX: this breaks AIX 4.3.3 (others?). */
+#define ulonglong2double(A) my_ulonglong2double(A)
+#define my_off_t2double(A) my_ulonglong2double(A)
+C_MODE_START
+double my_ulonglong2double(unsigned long long A);
+C_MODE_END
+#endif /* _AIX */
+
+#ifdef HAVE_BROKEN_SNPRINTF /* HPUX 10.20 don't have this defined */
+#undef HAVE_SNPRINTF
+#endif
+#ifdef HAVE_BROKEN_PREAD /* These doesn't work on HPUX 11.x */
+#undef HAVE_PREAD
+#undef HAVE_PWRITE
+#endif
+#if defined(HAVE_BROKEN_INLINE) && !defined(__cplusplus)
+#undef inline
+#define inline
+#endif
+
+#ifdef UNDEF_HAVE_GETHOSTBYNAME_R /* For OSF4.x */
+#undef HAVE_GETHOSTBYNAME_R
+#endif
+#ifdef UNDEF_HAVE_INITGROUPS /* For AIX 4.3 */
+#undef HAVE_INITGROUPS
+#endif
+
+/* gcc/egcs issues */
+
+#if defined(__GNUC) && defined(__EXCEPTIONS)
+#error "Please add -fno-exceptions to CXXFLAGS and reconfigure/recompile"
+#endif
+
+
+/* Fix a bug in gcc 2.8.0 on IRIX 6.2 */
+#if SIZEOF_LONG == 4 && defined(__LONG_MAX__)
+#undef __LONG_MAX__ /* Is a longlong value in gcc 2.8.0 ??? */
+#define __LONG_MAX__ 2147483647
+#endif
+
+/* Fix problem when linking c++ programs with gcc 3.x */
+#ifdef DEFINE_CXA_PURE_VIRTUAL
+#define FIX_GCC_LINKING_PROBLEM extern "C" { int __cxa_pure_virtual() {return 0;} }
+#else
+#define FIX_GCC_LINKING_PROBLEM
+#endif
+
+/* egcs 1.1.2 has a problem with memcpy on Alpha */
+#if defined(__GNUC__) && defined(__alpha__) && ! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
+#define BAD_MEMCPY
+#endif
+
+/* In Linux-alpha we have atomic.h if we are using gcc */
+#if defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__alpha__) && (__GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95)) && !defined(HAVE_ATOMIC_ADD)
+#define HAVE_ATOMIC_ADD
+#define HAVE_ATOMIC_SUB
+#endif
+
+/* In Linux-ia64 including atomic.h will give us an error */
+#if (defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && (defined(__ia64__)||defined(__powerpc64__))) || !defined(THREAD)
+#undef HAVE_ATOMIC_ADD
+#undef HAVE_ATOMIC_SUB
+#endif
+
+#if defined(_lint) && !defined(lint)
+#define lint
+#endif
+#if SIZEOF_LONG_LONG > 4 && !defined(_LONG_LONG)
+#define _LONG_LONG 1 /* For AIX string library */
+#endif
+
+#ifndef stdin
+#include <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#include <math.h>
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_TIMEB_H
+#include <sys/timeb.h> /* Avoid warnings on SCO */
+#endif
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif /* TIME_WITH_SYS_TIME */
+#ifdef HAVE_UNISTD_H
+#if defined(HAVE_OPENSSL) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__)
+#define crypt unistd_crypt
+#endif
+#include <unistd.h>
+#ifdef HAVE_OPENSSL
+#undef crypt
+#endif
+#endif
+#if defined(__cplusplus) && defined(NO_CPLUSPLUS_ALLOCA)
+#undef HAVE_ALLOCA
+#undef HAVE_ALLOCA_H
+#endif
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+#ifdef HAVE_ATOMIC_ADD
+#define __SMP__
+#ifdef HAVE_LINUX_CONFIG_H
+#include <linux/config.h> /* May define CONFIG_SMP */
+#endif
+#ifndef CONFIG_SMP
+#define CONFIG_SMP
+#endif
+C_MODE_START
+#include <asm/atomic.h>
+C_MODE_END
+#endif
+#include <errno.h> /* Recommended by debian */
+/* We need the following to go around a problem with openssl on solaris */
+#if defined(HAVE_CRYPT_H)
+#include <crypt.h>
+#endif
+
+/* Go around some bugs in different OS and compilers */
+#if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H)
+#include <sys/stream.h> /* HPUX 10.20 defines ulong here. UGLY !!! */
+#define HAVE_ULONG
+#endif
+#ifdef DONT_USE_FINITE /* HPUX 11.x has is_finite() */
+#undef HAVE_FINITE
+#endif
+#if defined(HPUX10) && defined(_LARGEFILE64_SOURCE) && defined(THREAD)
+/* Fix bug in setrlimit */
+#undef setrlimit
+#define setrlimit cma_setrlimit64
+#endif
+
+#ifdef __QNXNTO__
+/* This has to be after include limits.h */
+#define HAVE_ERRNO_AS_DEFINE
+#define HAVE_FCNTL_LOCK
+#undef HAVE_FINITE
+#undef LONGLONG_MIN /* These get wrongly defined in QNX 6.2 */
+#undef LONGLONG_MAX /* standard system library 'limits.h' */
+#endif
+
+/* We can not live without the following defines */
+
+#define USE_MYFUNC 1 /* Must use syscall indirection */
+#define MASTER 1 /* Compile without unireg */
+#define ENGLISH 1 /* Messages in English */
+#define POSIX_MISTAKE 1 /* regexp: Fix stupid spec error */
+#define USE_REGEX 1 /* We want the use the regex library */
+/* Do not define for ultra sparcs */
+#ifndef OS2
+#define USE_BMOVE512 1 /* Use this unless system bmove is faster */
+#endif
+
+/* Paranoid settings. Define I_AM_PARANOID if you are paranoid */
+#ifdef I_AM_PARANOID
+#define DONT_ALLOW_USER_CHANGE 1
+#define DONT_USE_MYSQL_PWD 1
+#endif
+
+/* Does the system remember a signal handler after a signal ? */
+#ifndef HAVE_BSD_SIGNALS
+#define DONT_REMEMBER_SIGNAL
+#endif
+
+/* Define void to stop lint from generating "null effekt" comments */
+#ifndef DONT_DEFINE_VOID
+#ifdef _lint
+int __void__;
+#define VOID(X) (__void__ = (int) (X))
+#else
+#undef VOID
+#define VOID(X) (X)
+#endif
+#endif /* DONT_DEFINE_VOID */
+
+#if defined(_lint) || defined(FORCE_INIT_OF_VARS)
+#define LINT_INIT(var) var=0 /* No uninitialize-warning */
+#else
+#define LINT_INIT(var)
+#endif
+
+/* Define some useful general macros */
+#if defined(__cplusplus) && defined(__GNUC__)
+#define max(a, b) ((a) >? (b))
+#define min(a, b) ((a) <? (b))
+#elif !defined(max)
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#if defined(__EMX__) || !defined(HAVE_UINT)
+typedef unsigned int uint;
+typedef unsigned short ushort;
+#endif
+
+#define CMP_NUM(a,b) (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1)
+#define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0)
+#define swap(t,a,b) { register t dummy; dummy = a; a = b; b = dummy; }
+#define test(a) ((a) ? 1 : 0)
+#define set_if_bigger(a,b) { if ((a) < (b)) (a)=(b); }
+#define set_if_smaller(a,b) { if ((a) > (b)) (a)=(b); }
+#define test_all_bits(a,b) (((a) & (b)) == (b))
+#define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1))
+#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))
+#ifndef HAVE_RINT
+#define rint(A) floor((A)+(((A) < 0)? -0.5 : 0.5))
+#endif
+
+/* Define some general constants */
+#ifndef TRUE
+#define TRUE (1) /* Logical true */
+#define FALSE (0) /* Logical false */
+#endif
+
+#if defined(__GNUC__)
+#define function_volatile volatile
+#define my_reinterpret_cast(A) reinterpret_cast<A>
+#define my_const_cast(A) const_cast<A>
+#elif !defined(my_reinterpret_cast)
+#define my_reinterpret_cast(A) (A)
+#define my_const_cast(A) (A)
+#endif
+#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+#define __attribute__(A)
+#endif
+
+/* From old s-system.h */
+
+/*
+ Support macros for non ansi & other old compilers. Since such
+ things are no longer supported we do nothing. We keep then since
+ some of our code may still be needed to upgrade old customers.
+*/
+#define _VARARGS(X) X
+#define _STATIC_VARARGS(X) X
+#define _PC(X) X
+
+#if defined(DBUG_ON) && defined(DBUG_OFF)
+#undef DBUG_OFF
+#endif
+
+#if defined(_lint) && !defined(DBUG_OFF)
+#define DBUG_OFF
+#endif
+
+#include <my_dbug.h>
+
+#define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/
+#define ASCII_BITS_USED 8 /* Bit char used */
+#define NEAR_F /* No near function handling */
+
+/* Some types that is different between systems */
+
+typedef int File; /* File descriptor */
+#ifndef Socket_defined
+typedef int my_socket; /* File descriptor for sockets */
+#define INVALID_SOCKET -1
+#endif
+/* Type for fuctions that handles signals */
+#define sig_handler RETSIGTYPE
+C_MODE_START
+typedef void (*sig_return)();/* Returns type from signal */
+C_MODE_END
+#if defined(__GNUC__) && !defined(_lint)
+typedef char pchar; /* Mixed prototypes can take char */
+typedef char puchar; /* Mixed prototypes can take char */
+typedef char pbool; /* Mixed prototypes can take char */
+typedef short pshort; /* Mixed prototypes can take short int */
+typedef float pfloat; /* Mixed prototypes can take float */
+#else
+typedef int pchar; /* Mixed prototypes can't take char */
+typedef uint puchar; /* Mixed prototypes can't take char */
+typedef int pbool; /* Mixed prototypes can't take char */
+typedef int pshort; /* Mixed prototypes can't take short int */
+typedef double pfloat; /* Mixed prototypes can't take float */
+#endif
+C_MODE_START
+typedef int (*qsort_cmp)(const void *,const void *);
+typedef int (*qsort_cmp2)(void*, const void *,const void *);
+C_MODE_END
+#ifdef HAVE_mit_thread
+#define qsort_t void
+#undef QSORT_TYPE_IS_VOID
+#define QSORT_TYPE_IS_VOID
+#else
+#define qsort_t RETQSORTTYPE /* Broken GCC cant handle typedef !!!! */
+#endif
+#ifdef HAVE_mit_thread
+#define size_socket socklen_t /* Type of last arg to accept */
+#else
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+typedef SOCKET_SIZE_TYPE size_socket;
+#endif
+
+#ifndef SOCKOPT_OPTLEN_TYPE
+#define SOCKOPT_OPTLEN_TYPE size_socket
+#endif
+
+/* file create flags */
+
+#ifndef O_SHARE /* Probably not windows */
+#define O_SHARE 0 /* Flag to my_open for shared files */
+#ifndef O_BINARY
+#define O_BINARY 0 /* Flag to my_open for binary files */
+#endif
+#ifndef FILE_BINARY
+#define FILE_BINARY O_BINARY /* Flag to my_fopen for binary streams */
+#endif
+#ifdef HAVE_FCNTL
+#define HAVE_FCNTL_LOCK
+#define F_TO_EOF 0L /* Param to lockf() to lock rest of file */
+#endif
+#endif /* O_SHARE */
+
+#ifndef O_TEMPORARY
+#define O_TEMPORARY 0
+#endif
+#ifndef O_SHORT_LIVED
+#define O_SHORT_LIVED 0
+#endif
+
+/* #define USE_RECORD_LOCK */
+
+ /* Unsigned types supported by the compiler */
+#define UNSINT8 /* unsigned int8 (char) */
+#define UNSINT16 /* unsigned int16 */
+#define UNSINT32 /* unsigned int32 */
+
+ /* General constants */
+#define SC_MAXWIDTH 256 /* Max width of screen (for error messages) */
+#define FN_LEN 256 /* Max file name len */
+#define FN_HEADLEN 253 /* Max length of filepart of file name */
+#define FN_EXTLEN 20 /* Max length of extension (part of FN_LEN) */
+#define FN_REFLEN 512 /* Max length of full path-name */
+#define FN_EXTCHAR '.'
+#define FN_HOMELIB '~' /* ~/ is used as abbrev for home dir */
+#define FN_CURLIB '.' /* ./ is used as abbrev for current dir */
+#define FN_PARENTDIR ".." /* Parentdirectory; Must be a string */
+#define FN_DEVCHAR ':'
+
+#ifndef FN_LIBCHAR
+#ifdef __EMX__
+#define FN_LIBCHAR '\\'
+#define FN_ROOTDIR "\\"
+#else
+#define FN_LIBCHAR '/'
+#define FN_ROOTDIR "/"
+#endif
+#define MY_NFILE 1024 /* This is only used to save filenames */
+#endif
+
+/* #define EXT_IN_LIBNAME */
+/* #define FN_NO_CASE_SENCE */
+/* #define FN_UPPER_CASE TRUE */
+
+/*
+ Io buffer size; Must be a power of 2 and a multiple of 512. May be
+ smaller what the disk page size. This influences the speed of the
+ isam btree library. eg to big to slow.
+*/
+#define IO_SIZE 4096
+/*
+ How much overhead does malloc have. The code often allocates
+ something like 1024-MALLOC_OVERHEAD bytes
+*/
+#ifdef SAFEMALLOC
+#define MALLOC_OVERHEAD (8+24+4)
+#else
+#define MALLOC_OVERHEAD 8
+#endif
+ /* get memory in huncs */
+#define ONCE_ALLOC_INIT (uint) (4096-MALLOC_OVERHEAD)
+ /* Typical record cash */
+#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD)
+ /* Typical key cash */
+#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD)
+
+ /* Some things that this system doesn't have */
+
+#define NO_HASH /* Not needed anymore */
+#ifdef __WIN__
+#define NO_DIR_LIBRARY /* Not standar dir-library */
+#define USE_MY_STAT_STRUCT /* For my_lib */
+#endif
+
+/* Some things that this system does have */
+
+#ifndef HAVE_ITOA
+#define USE_MY_ITOA /* There is no itoa */
+#endif
+
+/* Some defines of functions for portability */
+
+#ifndef HAVE_ATOD
+#define atod atof
+#endif
+#ifdef USE_MY_ATOF
+#define atof my_atof
+extern void init_my_atof(void);
+extern double my_atof(const char*);
+#endif
+#undef remove /* Crashes MySQL on SCO 5.0.0 */
+#ifndef __WIN__
+#ifdef OS2
+#define closesocket(A) soclose(A)
+#else
+#define closesocket(A) close(A)
+#endif
+#ifndef ulonglong2double
+#define ulonglong2double(A) ((double) (ulonglong) (A))
+#define my_off_t2double(A) ((double) (my_off_t) (A))
+#endif
+#endif
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+#define ulong_to_double(X) ((double) (ulong) (X))
+#define SET_STACK_SIZE(X) /* Not needed on real machines */
+
+#if !defined(HAVE_mit_thread) && !defined(HAVE_STRTOK_R)
+#define strtok_r(A,B,C) strtok((A),(B))
+#endif
+
+/* Remove some things that mit_thread break or doesn't support */
+#if defined(HAVE_mit_thread) && defined(THREAD)
+#undef HAVE_PREAD
+#undef HAVE_REALPATH
+#undef HAVE_MLOCK
+#undef HAVE_TEMPNAM /* Use ours */
+#undef HAVE_PTHREAD_SETPRIO
+#undef HAVE_FTRUNCATE
+#undef HAVE_READLINK
+#endif
+
+/* This is from the old m-machine.h file */
+
+#if SIZEOF_LONG_LONG > 4
+#define HAVE_LONG_LONG 1
+#endif
+
+/*
+ Some pre-ANSI-C99 systems like AIX 5.1 and Linux/GCC 2.95 define
+ ULONGLONG_MAX, LONGLONG_MIN, LONGLONG_MAX; we use them if they're defined.
+ Also on Windows we define these constants by hand in config-win.h.
+*/
+
+#if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN)
+#define LONGLONG_MIN ((long long) 0x8000000000000000LL)
+#define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL)
+#endif
+
+#if defined(HAVE_LONG_LONG) && !defined(ULONGLONG_MAX)
+/* First check for ANSI C99 definition: */
+#ifdef ULLONG_MAX
+#define ULONGLONG_MAX ULLONG_MAX
+#else
+#define ULONGLONG_MAX ((unsigned long long)(~0ULL))
+#endif
+#endif /* defined (HAVE_LONG_LONG) && !defined(ULONGLONG_MAX)*/
+
+#if SIZEOF_LONG == 4
+#define INT_MIN32 (long) 0x80000000L
+#define INT_MAX32 (long) 0x7FFFFFFFL
+#define INT_MIN24 ((long) 0xff800000L)
+#define INT_MAX24 0x007fffffL
+#define INT_MIN16 ((short int) 0x8000)
+#define INT_MAX16 0x7FFF
+#define INT_MIN8 ((char) 0x80)
+#define INT_MAX8 ((char) 0x7F)
+#else /* Probably Alpha */
+#define INT_MIN32 ((long) (int) 0x80000000)
+#define INT_MAX32 ((long) (int) 0x7FFFFFFF)
+#define INT_MIN24 ((long) (int) 0xff800000)
+#define INT_MAX24 ((long) (int) 0x007fffff)
+#define INT_MIN16 ((short int) 0xffff8000)
+#define INT_MAX16 ((short int) 0x00007FFF)
+#endif
+
+/* From limits.h instead */
+#ifndef DBL_MIN
+#define DBL_MIN 4.94065645841246544e-324
+#define FLT_MIN ((float)1.40129846432481707e-45)
+#endif
+#ifndef DBL_MAX
+#define DBL_MAX 1.79769313486231470e+308
+#define FLT_MAX ((float)3.40282346638528860e+38)
+#endif
+
+/*
+ Max size that must be added to a so that we know Size to make
+ adressable obj.
+*/
+#if SIZEOF_CHARP == 4
+typedef long my_ptrdiff_t;
+#else
+typedef long long my_ptrdiff_t;
+#endif
+
+#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1))
+#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
+/* Size to make adressable obj. */
+#define ALIGN_PTR(A, t) ((t*) MY_ALIGN((A),sizeof(t)))
+ /* Offset of filed f in structure t */
+#define OFFSET(t, f) ((size_t)(char *)&((t *)0)->f)
+#define ADD_TO_PTR(ptr,size,type) (type) ((byte*) (ptr)+size)
+#define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((byte*) (A) - (byte*) (B))
+
+#define NullS (char *) 0
+/* Nowdays we do not support MessyDos */
+#ifndef NEAR
+#define NEAR /* Who needs segments ? */
+#define FAR /* On a good machine */
+#ifndef HUGE_PTR
+#define HUGE_PTR
+#endif
+#endif
+#if defined(__IBMC__) || defined(__IBMCPP__)
+#define STDCALL _System _Export
+#elif !defined( STDCALL)
+#define STDCALL
+#endif
+
+/* Typdefs for easyier portability */
+
+#if defined(VOIDTYPE)
+typedef void *gptr; /* Generic pointer */
+#else
+typedef char *gptr; /* Generic pointer */
+#endif
+#ifndef HAVE_INT_8_16_32
+typedef char int8; /* Signed integer >= 8 bits */
+typedef short int16; /* Signed integer >= 16 bits */
+#endif
+#ifndef HAVE_UCHAR
+typedef unsigned char uchar; /* Short for unsigned char */
+#endif
+typedef unsigned char uint8; /* Short for unsigned integer >= 8 bits */
+typedef unsigned short uint16; /* Short for unsigned integer >= 16 bits */
+
+#if SIZEOF_INT == 4
+#ifndef HAVE_INT_8_16_32
+typedef int int32;
+#endif
+typedef unsigned int uint32; /* Short for unsigned integer >= 32 bits */
+#elif SIZEOF_LONG == 4
+#ifndef HAVE_INT_8_16_32
+typedef long int32;
+#endif
+typedef unsigned long uint32; /* Short for unsigned integer >= 32 bits */
+#else
+error "Neither int or long is of 4 bytes width"
+#endif
+
+#if !defined(HAVE_ULONG) && !defined(HAVE_LINUXTHREADS) && !defined(__USE_MISC)
+typedef unsigned long ulong; /* Short for unsigned long */
+#endif
+#ifndef longlong_defined
+#if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8
+typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
+typedef long long int longlong;
+#else
+typedef unsigned long ulonglong; /* ulong or unsigned long long */
+typedef long longlong;
+#endif
+#endif
+
+/* typedef used for length of string; Should be unsigned! */
+typedef ulong size_str;
+
+#ifdef USE_RAID
+/*
+ The following is done with a if to not get problems with pre-processors
+ with late define evaluation
+*/
+#if SIZEOF_OFF_T == 4
+#define SYSTEM_SIZEOF_OFF_T 4
+#else
+#define SYSTEM_SIZEOF_OFF_T 8
+#endif
+#undef SIZEOF_OFF_T
+#define SIZEOF_OFF_T 8
+#else
+#define SYSTEM_SIZEOF_OFF_T SIZEOF_OFF_T
+#endif /* USE_RAID */
+
+#if SIZEOF_OFF_T > 4
+typedef ulonglong my_off_t;
+#else
+typedef unsigned long my_off_t;
+#endif
+#define MY_FILEPOS_ERROR (~(my_off_t) 0)
+#if !defined(__WIN__) && !defined(OS2)
+typedef off_t os_off_t;
+#endif
+
+#if defined(__WIN__)
+#define socket_errno WSAGetLastError()
+#define SOCKET_EINTR WSAEINTR
+#define SOCKET_EAGAIN WSAEINPROGRESS
+#define SOCKET_EWOULDBLOCK WSAEINPROGRESS
+#define SOCKET_ENFILE ENFILE
+#define SOCKET_EMFILE EMFILE
+#elif defined(OS2)
+#define socket_errno sock_errno()
+#define SOCKET_EINTR SOCEINTR
+#define SOCKET_EAGAIN SOCEINPROGRESS
+#define SOCKET_EWOULDBLOCK SOCEWOULDBLOCK
+#define SOCKET_ENFILE SOCENFILE
+#define SOCKET_EMFILE SOCEMFILE
+#define closesocket(A) soclose(A)
+#else /* Unix */
+#define socket_errno errno
+#define closesocket(A) close(A)
+#define SOCKET_EINTR EINTR
+#define SOCKET_EAGAIN EAGAIN
+#define SOCKET_EWOULDBLOCK EWOULDBLOCK
+#define SOCKET_ENFILE ENFILE
+#define SOCKET_EMFILE EMFILE
+#endif
+
+typedef uint8 int7; /* Most effective integer 0 <= x <= 127 */
+typedef short int15; /* Most effective integer 0 <= x <= 32767 */
+typedef char *my_string; /* String of characters */
+typedef unsigned long size_s; /* Size of strings (In string-funcs) */
+typedef int myf; /* Type of MyFlags in my_funcs */
+#ifndef byte_defined
+typedef char byte; /* Smallest addressable unit */
+#endif
+typedef char my_bool; /* Small bool */
+#if !defined(bool) && !defined(bool_defined) && (!defined(HAVE_BOOL) || !defined(__cplusplus))
+typedef char bool; /* Ordinary boolean values 0 1 */
+#endif
+ /* Macros for converting *constants* to the right type */
+#define INT8(v) (int8) (v)
+#define INT16(v) (int16) (v)
+#define INT32(v) (int32) (v)
+#define MYF(v) (myf) (v)
+
+#ifndef LL
+#ifdef HAVE_LONG_LONG
+#define LL(A) A ## LL
+#else
+#define LL(A) A ## L
+#endif
+#endif
+
+/*
+ Defines to make it possible to prioritize register assignments. No
+ longer that important with modern compilers.
+*/
+#ifndef USING_X
+#define reg1 register
+#define reg2 register
+#define reg3 register
+#define reg4 register
+#define reg5 register
+#define reg6 register
+#define reg7 register
+#define reg8 register
+#define reg9 register
+#define reg10 register
+#define reg11 register
+#define reg12 register
+#define reg13 register
+#define reg14 register
+#define reg15 register
+#define reg16 register
+#endif
+
+/*
+ Sometimes we want to make sure that the variable is not put into
+ a register in debugging mode so we can see its value in the core
+*/
+
+#ifndef DBUG_OFF
+#define dbug_volatile volatile
+#else
+#define dbug_volatile
+#endif
+
+/* Defines for time function */
+#define SCALE_SEC 100
+#define SCALE_USEC 10000
+#define MY_HOW_OFTEN_TO_ALARM 2 /* How often we want info on screen */
+#define MY_HOW_OFTEN_TO_WRITE 1000 /* How often we want info on screen */
+
+#ifndef set_timespec
+#ifdef HAVE_TIMESPEC_TS_SEC
+#define set_timespec(ABSTIME,SEC) { (ABSTIME).ts_sec=time(0) + (time_t) (SEC); (ABSTIME).ts_nsec=0; }
+#else
+#define set_timespec(ABSTIME,SEC) \
+{\
+ struct timeval tv;\
+ gettimeofday(&tv,0);\
+ (ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\
+ (ABSTIME).tv_nsec=tv.tv_usec*1000;\
+}
+#endif /* HAVE_TIMESPEC_TS_SEC */
+#endif /* set_timespec */
+
+/*
+ Define-funktions for reading and storing in machine independent format
+ (low byte first)
+*/
+
+/* Optimized store functions for Intel x86 */
+#if defined(__i386__) && !defined(_WIN64)
+#define sint2korr(A) (*((int16 *) (A)))
+#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
+ (((uint32) 255L << 24) | \
+ (((uint32) (uchar) (A)[2]) << 16) |\
+ (((uint32) (uchar) (A)[1]) << 8) | \
+ ((uint32) (uchar) (A)[0])) : \
+ (((uint32) (uchar) (A)[2]) << 16) |\
+ (((uint32) (uchar) (A)[1]) << 8) | \
+ ((uint32) (uchar) (A)[0])))
+#define sint4korr(A) (*((long *) (A)))
+#define uint2korr(A) (*((uint16 *) (A)))
+#ifdef HAVE_purify
+#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16))
+#else
+#define uint3korr(A) (long) (*((unsigned long *) (A)) & 0xFFFFFF)
+#endif
+#define uint4korr(A) (*((unsigned long *) (A)))
+#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16) +\
+ (((uint32) ((uchar) (A)[3])) << 24)) +\
+ (((ulonglong) ((uchar) (A)[4])) << 32))
+#define uint8korr(A) (*((ulonglong *) (A)))
+#define sint8korr(A) (*((longlong *) (A)))
+#define int2store(T,A) *((uint16*) (T))= (uint16) (A)
+#define int3store(T,A) { *(T)= (uchar) ((A));\
+ *(T+1)=(uchar) (((uint) (A) >> 8));\
+ *(T+2)=(uchar) (((A) >> 16)); }
+#define int4store(T,A) *((long *) (T))= (long) (A)
+#define int5store(T,A) { *(T)= (uchar)((A));\
+ *((T)+1)=(uchar) (((A) >> 8));\
+ *((T)+2)=(uchar) (((A) >> 16));\
+ *((T)+3)=(uchar) (((A) >> 24)); \
+ *((T)+4)=(uchar) (((A) >> 32)); }
+#define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A)
+
+typedef union {
+ double v;
+ long m[2];
+} doubleget_union;
+#define doubleget(V,M) \
+{ doubleget_union _tmp; \
+ _tmp.m[0] = *((long*)(M)); \
+ _tmp.m[1] = *(((long*) (M))+1); \
+ (V) = _tmp.v; }
+#define doublestore(T,V) { *((long *) T) = ((doubleget_union *)&V)->m[0]; \
+ *(((long *) T)+1) = ((doubleget_union *)&V)->m[1]; }
+#define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); }
+#define float8get(V,M) doubleget((V),(M))
+#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
+#define float8store(V,M) doublestore((V),(M))
+#endif /* __i386__ */
+
+#ifndef sint2korr
+#define sint2korr(A) (int16) (((int16) ((uchar) (A)[0])) +\
+ ((int16) ((int16) (A)[1]) << 8))
+#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
+ (((uint32) 255L << 24) | \
+ (((uint32) (uchar) (A)[2]) << 16) |\
+ (((uint32) (uchar) (A)[1]) << 8) | \
+ ((uint32) (uchar) (A)[0])) : \
+ (((uint32) (uchar) (A)[2]) << 16) |\
+ (((uint32) (uchar) (A)[1]) << 8) | \
+ ((uint32) (uchar) (A)[0])))
+#define sint4korr(A) (int32) (((int32) ((uchar) (A)[0])) +\
+ (((int32) ((uchar) (A)[1]) << 8)) +\
+ (((int32) ((uchar) (A)[2]) << 16)) +\
+ (((int32) ((int16) (A)[3]) << 24)))
+#define sint8korr(A) (longlong) uint8korr(A)
+#define uint2korr(A) (uint16) (((uint16) ((uchar) (A)[0])) +\
+ ((uint16) ((uchar) (A)[1]) << 8))
+#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16))
+#define uint4korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16) +\
+ (((uint32) ((uchar) (A)[3])) << 24))
+#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16) +\
+ (((uint32) ((uchar) (A)[3])) << 24)) +\
+ (((ulonglong) ((uchar) (A)[4])) << 32))
+#define uint8korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
+ (((uint32) ((uchar) (A)[1])) << 8) +\
+ (((uint32) ((uchar) (A)[2])) << 16) +\
+ (((uint32) ((uchar) (A)[3])) << 24)) +\
+ (((ulonglong) (((uint32) ((uchar) (A)[4])) +\
+ (((uint32) ((uchar) (A)[5])) << 8) +\
+ (((uint32) ((uchar) (A)[6])) << 16) +\
+ (((uint32) ((uchar) (A)[7])) << 24))) <<\
+ 32))
+#define int2store(T,A) { uint def_temp= (uint) (A) ;\
+ *((uchar*) (T))= (uchar)(def_temp); \
+ *((uchar*) (T+1))=(uchar)((def_temp >> 8)); }
+#define int3store(T,A) { /*lint -save -e734 */\
+ *((uchar*)(T))=(uchar) ((A));\
+ *((uchar*) (T)+1)=(uchar) (((A) >> 8));\
+ *((uchar*)(T)+2)=(uchar) (((A) >> 16)); \
+ /*lint -restore */}
+#define int4store(T,A) { *(T)=(char) ((A));\
+ *((T)+1)=(char) (((A) >> 8));\
+ *((T)+2)=(char) (((A) >> 16));\
+ *((T)+3)=(char) (((A) >> 24)); }
+#define int5store(T,A) { *(T)=((A));\
+ *((T)+1)=(((A) >> 8));\
+ *((T)+2)=(((A) >> 16));\
+ *((T)+3)=(((A) >> 24)); \
+ *((T)+4)=(((A) >> 32)); }
+#define int8store(T,A) { uint def_temp= (uint) (A), def_temp2= (uint) ((A) >> 32); \
+ int4store((T),def_temp); \
+ int4store((T+4),def_temp2); \
+ }
+#ifdef WORDS_BIGENDIAN
+#define float4store(T,A) { *(T)= ((byte *) &A)[3];\
+ *((T)+1)=(char) ((byte *) &A)[2];\
+ *((T)+2)=(char) ((byte *) &A)[1];\
+ *((T)+3)=(char) ((byte *) &A)[0]; }
+
+#define float4get(V,M) { float def_temp;\
+ ((byte*) &def_temp)[0]=(M)[3];\
+ ((byte*) &def_temp)[1]=(M)[2];\
+ ((byte*) &def_temp)[2]=(M)[1];\
+ ((byte*) &def_temp)[3]=(M)[0];\
+ (V)=def_temp; }
+#define float8store(T,V) { *(T)= ((byte *) &V)[7];\
+ *((T)+1)=(char) ((byte *) &V)[6];\
+ *((T)+2)=(char) ((byte *) &V)[5];\
+ *((T)+3)=(char) ((byte *) &V)[4];\
+ *((T)+4)=(char) ((byte *) &V)[3];\
+ *((T)+5)=(char) ((byte *) &V)[2];\
+ *((T)+6)=(char) ((byte *) &V)[1];\
+ *((T)+7)=(char) ((byte *) &V)[0]; }
+
+#define float8get(V,M) { double def_temp;\
+ ((byte*) &def_temp)[0]=(M)[7];\
+ ((byte*) &def_temp)[1]=(M)[6];\
+ ((byte*) &def_temp)[2]=(M)[5];\
+ ((byte*) &def_temp)[3]=(M)[4];\
+ ((byte*) &def_temp)[4]=(M)[3];\
+ ((byte*) &def_temp)[5]=(M)[2];\
+ ((byte*) &def_temp)[6]=(M)[1];\
+ ((byte*) &def_temp)[7]=(M)[0];\
+ (V) = def_temp; }
+#else
+#define float4get(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(float))
+#define float4store(V,M) memcpy_fixed((byte*) V,(byte*) (&M),sizeof(float))
+
+#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
+#define doublestore(T,V) { *(T)= ((byte *) &V)[4];\
+ *((T)+1)=(char) ((byte *) &V)[5];\
+ *((T)+2)=(char) ((byte *) &V)[6];\
+ *((T)+3)=(char) ((byte *) &V)[7];\
+ *((T)+4)=(char) ((byte *) &V)[0];\
+ *((T)+5)=(char) ((byte *) &V)[1];\
+ *((T)+6)=(char) ((byte *) &V)[2];\
+ *((T)+7)=(char) ((byte *) &V)[3]; }
+#define doubleget(V,M) { double def_temp;\
+ ((byte*) &def_temp)[0]=(M)[4];\
+ ((byte*) &def_temp)[1]=(M)[5];\
+ ((byte*) &def_temp)[2]=(M)[6];\
+ ((byte*) &def_temp)[3]=(M)[7];\
+ ((byte*) &def_temp)[4]=(M)[0];\
+ ((byte*) &def_temp)[5]=(M)[1];\
+ ((byte*) &def_temp)[6]=(M)[2];\
+ ((byte*) &def_temp)[7]=(M)[3];\
+ (V) = def_temp; }
+#endif /* __FLOAT_WORD_ORDER */
+
+#define float8get(V,M) doubleget((V),(M))
+#define float8store(V,M) doublestore((V),(M))
+#endif /* WORDS_BIGENDIAN */
+
+#endif /* sint2korr */
+
+/*
+ Define-funktions for reading and storing in machine format from/to
+ short/long to/from some place in memory V should be a (not
+ register) variable, M is a pointer to byte
+*/
+
+#ifdef WORDS_BIGENDIAN
+
+#define ushortget(V,M) { V = (uint16) (((uint16) ((uchar) (M)[1]))+\
+ ((uint16) ((uint16) (M)[0]) << 8)); }
+#define shortget(V,M) { V = (short) (((short) ((uchar) (M)[1]))+\
+ ((short) ((short) (M)[0]) << 8)); }
+#define longget(V,M) { int32 def_temp;\
+ ((byte*) &def_temp)[0]=(M)[0];\
+ ((byte*) &def_temp)[1]=(M)[1];\
+ ((byte*) &def_temp)[2]=(M)[2];\
+ ((byte*) &def_temp)[3]=(M)[3];\
+ (V)=def_temp; }
+#define ulongget(V,M) { uint32 def_temp;\
+ ((byte*) &def_temp)[0]=(M)[0];\
+ ((byte*) &def_temp)[1]=(M)[1];\
+ ((byte*) &def_temp)[2]=(M)[2];\
+ ((byte*) &def_temp)[3]=(M)[3];\
+ (V)=def_temp; }
+#define shortstore(T,A) { uint def_temp=(uint) (A) ;\
+ *(T+1)=(char)(def_temp); \
+ *(T+0)=(char)(def_temp >> 8); }
+#define longstore(T,A) { *((T)+3)=((A));\
+ *((T)+2)=(((A) >> 8));\
+ *((T)+1)=(((A) >> 16));\
+ *((T)+0)=(((A) >> 24)); }
+
+#define doubleget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(double))
+#define doublestore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(double))
+#define longlongget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(ulonglong))
+#define longlongstore(T,V) memcpy((byte*) (T),(byte*) &V,sizeof(ulonglong))
+
+#else
+
+#define ushortget(V,M) { V = uint2korr(M); }
+#define shortget(V,M) { V = sint2korr(M); }
+#define longget(V,M) { V = sint4korr(M); }
+#define ulongget(V,M) { V = uint4korr(M); }
+#define shortstore(T,V) int2store(T,V)
+#define longstore(T,V) int4store(T,V)
+#ifndef doubleget
+#define doubleget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(double))
+#define doublestore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(double))
+#endif /* doubleget */
+#define longlongget(V,M) memcpy_fixed((byte*) &V,(byte*) (M),sizeof(ulonglong))
+#define longlongstore(T,V) memcpy_fixed((byte*) (T),(byte*) &V,sizeof(ulonglong))
+
+#endif /* WORDS_BIGENDIAN */
+
+/* sprintf does not always return the number of bytes :- */
+#ifdef SPRINTF_RETURNS_INT
+#define my_sprintf(buff,args) sprintf args
+#else
+#ifdef SPRINTF_RETURNS_PTR
+#define my_sprintf(buff,args) ((int)(sprintf args - buff))
+#else
+#define my_sprintf(buff,args) ((ulong) sprintf args, (ulong) strlen(buff))
+#endif
+#endif
+
+#ifndef THREAD
+#define thread_safe_increment(V,L) (V)++
+#define thread_safe_add(V,C,L) (V)+=(C)
+#define thread_safe_sub(V,C,L) (V)-=(C)
+#define statistic_increment(V,L) (V)++
+#define statistic_add(V,C,L) (V)+=(C)
+#endif
+
+#ifdef HAVE_OPENSSL
+#include <openssl/opensslv.h>
+#if OPENSSL_VERSION_NUMBER < 0x0090700f
+#define DES_cblock des_cblock
+#define DES_key_schedule des_key_schedule
+#define DES_set_key_unchecked(k,ks) des_set_key_unchecked((k),*(ks))
+#define DES_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e) des_ede3_cbc_encrypt((i),(o),(l),*(k1),*(k2),*(k3),(iv),(e))
+#endif
+#endif
+
+#endif /* my_global_h */
diff --git a/include/my_list.h b/include/my_list.h
index 7391db70e27..0f56d4c532b 100644
--- a/include/my_list.h
+++ b/include/my_list.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _list_h_
#define _list_h_
diff --git a/include/my_net.h b/include/my_net.h
index a4910d8af1d..7b42afa1f3a 100644
--- a/include/my_net.h
+++ b/include/my_net.h
@@ -1,28 +1,33 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* thread safe version of some common functions */
-
-/* for thread safe my_inet_ntoa */
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(__BEOS__)
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ thread safe version of some common functions:
+ my_inet_ntoa
+
+ This file is also used to make handling of sockets and ioctl()
+ portable accross systems.
+
+*/
+
+#ifndef _my_net_h
+#define _my_net_h
+C_MODE_START
+
+#include <errno.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
@@ -32,7 +37,42 @@ extern "C" {
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
-#endif /* !defined(MSDOS) && !defined(__WIN__) */
+#ifdef HAVE_POLL
+#include <sys/poll.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) && !defined(__NETWARE__)
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#if !defined(alpha_linux_port)
+#include <netinet/tcp.h>
+#endif
+#endif
+
+#if defined(__EMX__)
+#include <sys/ioctl.h>
+#define ioctlsocket(A,B,C) ioctl((A),(B),(void *)(C),sizeof(*(C)))
+#undef HAVE_FCNTL
+#endif /* defined(__EMX__) */
+
+#if defined(MSDOS) || defined(__WIN__)
+#define O_NONBLOCK 1 /* For emulation of fcntl() */
+#endif
+
+/*
+ On OSes which don't have the in_addr_t, we guess that using uint32 is the best
+ possible choice. We guess this from the fact that on HP-UX64bit & FreeBSD64bit
+ & Solaris64bit, in_addr_t is equivalent to uint32. And on Linux32bit too.
+*/
+#ifndef HAVE_IN_ADDR_T
+#define in_addr_t uint32
+#endif
+
+/* Thread safe or portable version of some functions */
void my_inet_ntoa(struct in_addr in, char *buf);
@@ -40,7 +80,7 @@ void my_inet_ntoa(struct in_addr in, char *buf);
Handling of gethostbyname_r()
*/
-#if !defined(HPUX)
+#if !defined(HPUX10)
struct hostent;
#endif /* HPUX */
#if !defined(HAVE_GETHOSTBYNAME_R)
@@ -53,7 +93,7 @@ struct hostent *my_gethostbyname_r(const char *name,
struct hostent *result, char *buffer,
int buflen, int *h_errnop);
#define my_gethostbyname_r_free()
-#if !defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE) && !defined(HPUX)
+#if !defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE) && !defined(HPUX10)
#define GETHOSTBYNAME_BUFF_SIZE sizeof(struct hostent_data)
#endif /* !defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE) */
@@ -78,6 +118,5 @@ struct hostent *my_gethostbyname_r(const char *name,
#define h_errno errno
#endif
-#ifdef __cplusplus
-}
+C_MODE_END
#endif
diff --git a/include/my_no_pthread.h b/include/my_no_pthread.h
index 328086ec388..0a034f78192 100644
--- a/include/my_no_pthread.h
+++ b/include/my_no_pthread.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
This undefs some pthread mutex locks when one isn't using threads
diff --git a/include/my_nosys.h b/include/my_nosys.h
index 5991904f260..605906f0e07 100644
--- a/include/my_nosys.h
+++ b/include/my_nosys.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Header to remove use of my_functions in functions where we need speed and
diff --git a/include/my_pthread.h b/include/my_pthread.h
index f31fa113064..40302f48bd5 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Defines to make different thread packages compatible */
@@ -116,6 +115,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
#undef SAFE_MUTEX /* This will cause conflicts */
#define pthread_key(T,V) DWORD V
#define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF)
+#define pthread_key_delete(A) TlsFree(A)
#define pthread_getspecific(A) (TlsGetValue(A))
#define my_pthread_getspecific(T,A) ((T) TlsGetValue(A))
#define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V))
@@ -124,6 +124,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
#else
#define pthread_key(T,V) __declspec(thread) T V
#define pthread_key_create(A,B) pthread_dummy(0)
+#define pthread_key_delete(A) pthread_dummy(0)
#define pthread_getspecific(A) (&(A))
#define my_pthread_getspecific(T,A) (&(A))
#define my_pthread_getspecific_ptr(T,V) (V)
@@ -179,6 +180,7 @@ extern int pthread_mutex_destroy (pthread_mutex_t *);
typedef int pthread_attr_t; /* Needed by Unixware 7.0.0 */
#define pthread_key_create(A,B) thr_keycreate((A),(B))
+#define pthread_key_delete(A) thr_keydelete(A)
#define pthread_handler_decl(A,B) void *A(void *B)
#define pthread_key(T,V) pthread_key_t V
@@ -248,6 +250,11 @@ extern int my_sigwait(const sigset_t *set,int *sig);
#error Requires at least rev 2 of EMX pthreads library.
#endif
+#ifdef __NETWARE__
+void my_pthread_exit(void *status);
+#define pthread_exit(A) my_pthread_exit(A)
+#endif
+
extern int my_pthread_getprio(pthread_t thread_id);
#define pthread_key(T,V) pthread_key_t V
@@ -377,6 +384,11 @@ struct tm *localtime_r(const time_t *clock, struct tm *res);
#define pthread_condattr_destroy pthread_condattr_delete
#endif
+/* FSU THREADS */
+#if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete)
+#define pthread_key_delete(A) pthread_dummy(0)
+#endif
+
#ifdef HAVE_CTHREADS_WRAPPER /* For MacOSX */
#define pthread_cond_destroy(A) pthread_dummy(0)
#define pthread_mutex_destroy(A) pthread_dummy(0)
@@ -423,19 +435,24 @@ struct tm *localtime_r(const time_t *clock, struct tm *res);
#define pthread_kill(A,B) pthread_dummy(0)
#undef pthread_detach_this_thread
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
-#else /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */
+#elif !defined(__NETWARE__) /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */
#define HAVE_PTHREAD_KILL
#endif
#endif /* defined(__WIN__) */
-#if defined(HPUX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
+#if defined(HPUX10) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
#undef pthread_cond_timedwait
#define pthread_cond_timedwait(a,b,c) my_pthread_cond_timedwait((a),(b),(c))
int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec *abstime);
#endif
+#if defined(HPUX10)
+#define pthread_attr_getstacksize(A,B) my_pthread_attr_getstacksize(A,B)
+void my_pthread_attr_getstacksize(pthread_attr_t *attrib, size_t *size);
+#endif
+
#if defined(HAVE_POSIX1003_4a_MUTEX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
#undef pthread_mutex_trylock
#define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a))
@@ -444,15 +461,39 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
/* safe_mutex adds checking to mutex for easier debugging */
+#if defined(__NETWARE__) && !defined(SAFE_MUTEX_DETECT_DESTROY)
+#define SAFE_MUTEX_DETECT_DESTROY
+#endif
+
typedef struct st_safe_mutex_t
{
pthread_mutex_t global,mutex;
char *file;
uint line,count;
pthread_t thread;
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+ struct st_safe_mutex_info_t *info; /* to track destroying of mutexes */
+#endif
} safe_mutex_t;
-int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr);
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+/*
+ Used to track the destroying of mutexes. This needs to be a seperate
+ structure because the safe_mutex_t structure could be freed before
+ the mutexes are destroyed.
+*/
+
+typedef struct st_safe_mutex_info_t
+{
+ struct st_safe_mutex_info_t *next;
+ struct st_safe_mutex_info_t *prev;
+ char *init_file;
+ uint32 init_line;
+} safe_mutex_info_t;
+#endif /* SAFE_MUTEX_DETECT_DESTROY */
+
+int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
+ const char *file, uint line);
int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line);
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
@@ -460,6 +501,8 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
uint line);
int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
struct timespec *abstime, const char *file, uint line);
+void safe_mutex_global_init(void);
+void safe_mutex_end(FILE *file);
/* Wrappers if safe mutex is actually used */
#ifdef SAFE_MUTEX
@@ -473,7 +516,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
#undef pthread_cond_wait
#undef pthread_cond_timedwait
#undef pthread_mutex_trylock
-#define pthread_mutex_init(A,B) safe_mutex_init((A),(B))
+#define pthread_mutex_init(A,B) safe_mutex_init((A),(B),__FILE__,__LINE__)
#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__)
#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__)
@@ -488,6 +531,12 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
/* READ-WRITE thread locking */
+#ifdef HAVE_BROKEN_RWLOCK /* For OpenUnix */
+#undef HAVE_PTHREAD_RWLOCK_RDLOCK
+#undef HAVE_RWLOCK_INIT
+#undef HAVE_RWLOCK_T
+#endif
+
#if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS)
/* use these defs for simple mutex locking */
#define rw_lock_t pthread_mutex_t
@@ -576,9 +625,13 @@ extern int pthread_dummy(int);
#define THREAD_NAME_SIZE 10
#if defined(__ia64__)
-#define DEFAULT_THREAD_STACK (128*1024)
+/*
+ MySQL can survive with 32K, but some glibc libraries require > 128K stack
+ To resolve hostnames
+*/
+#define DEFAULT_THREAD_STACK (192*1024L)
#else
-#define DEFAULT_THREAD_STACK (64*1024)
+#define DEFAULT_THREAD_STACK (192*1024L)
#endif
struct st_my_thread_var
@@ -592,6 +645,7 @@ struct st_my_thread_var
long id;
int cmp_length;
int volatile abort;
+ my_bool init;
#ifndef DBUG_OFF
gptr dbug;
char name[THREAD_NAME_SIZE+1];
@@ -601,6 +655,11 @@ struct st_my_thread_var
extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
#define my_thread_var (_my_thread_var())
#define my_errno my_thread_var->thr_errno
+/*
+ Keep track of shutdown,signal, and main threads so that my_end() will not
+ report errors with them
+*/
+extern pthread_t shutdown_th, main_th, signal_th;
/* statistics_xxx functions are for not essential statistic */
@@ -631,5 +690,4 @@ extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
#ifdef __cplusplus
}
#endif
-
#endif /* _my_ptread_h */
diff --git a/include/my_semaphore.h b/include/my_semaphore.h
new file mode 100644
index 00000000000..7f182bea6bf
--- /dev/null
+++ b/include/my_semaphore.h
@@ -0,0 +1,64 @@
+/*
+ * Module: semaphore.h
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA
+ */
+
+/* This is hacked by Monty to be included in mysys library */
+
+#ifndef _my_semaphore_h_
+#define _my_semaphore_h_
+
+#ifdef THREAD
+
+C_MODE_START
+#ifdef HAVE_SEMAPHORE_H
+#include <semaphore.h>
+#elif !defined(__bsdi__)
+#ifdef __WIN__
+typedef HANDLE sem_t;
+#else
+typedef struct {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ uint count;
+} sem_t;
+#endif /* __WIN__ */
+
+int sem_init(sem_t * sem, int pshared, unsigned int value);
+int sem_destroy(sem_t * sem);
+int sem_trywait(sem_t * sem);
+int sem_wait(sem_t * sem);
+int sem_post(sem_t * sem);
+int sem_post_multiple(sem_t * sem, unsigned int count);
+int sem_getvalue(sem_t * sem, unsigned int * sval);
+
+#endif /* !__bsdi__ */
+
+C_MODE_END
+
+#endif /* THREAD */
+
+#endif /* !_my_semaphore_h_ */
diff --git a/include/my_sys.h b/include/my_sys.h
index 924a6094416..75e22629a19 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -1,25 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _my_sys_h
#define _my_sys_h
-#ifdef __cplusplus
-extern "C" {
-#endif
+C_MODE_START
#ifdef HAVE_AIOWAIT
#include <sys/asynch.h> /* Used by record-cache */
@@ -39,7 +36,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#include <m_ctype.h> /* for CHARSET_INFO */
#endif
-#include <stdarg.h>
+#include <stdarg.h>
#define MYSYS_PROGRAM_USES_CURSES() { error_handler_hook = my_message_curses; mysys_uses_curses=1; }
#define MYSYS_PROGRAM_DONT_USE_CURSES() { error_handler_hook = my_message_no_curses; mysys_uses_curses=0;}
@@ -59,6 +56,9 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_WME 16 /* Write message on error */
#define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */
#define MY_RAID 64 /* Support for RAID (not the "Johnson&Johnson"-s one ;) */
+#define MY_FULL_IO 512 /* For my_read - loop intil I/O
+ is complete
+ */
#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */
#define MY_LINK_WARNING 32 /* my_redel() gives warning if links */
#define MY_COPYTIME 64 /* my_redel() copys time */
@@ -91,6 +91,16 @@ extern int NEAR my_errno; /* Last error in mysys */
#define ME_COLOUR2 ((2 << ME_HIGHBYTE))
#define ME_COLOUR3 ((3 << ME_HIGHBYTE))
+ /* Bits in last argument to fn_format */
+#define MY_REPLACE_DIR 1 /* replace dir in name with 'dir' */
+#define MY_REPLACE_EXT 2 /* replace extension with 'ext' */
+#define MY_UNPACK_FILENAME 4 /* Unpack name (~ -> home) */
+#define MY_PACK_FILENAME 8 /* Pack name (home -> ~) */
+#define MY_RESOLVE_SYMLINKS 16 /* Resolve all symbolic links */
+#define MY_RETURN_REAL_PATH 32 /* return full path for file */
+#define MY_SAFE_PATH 64 /* Return NULL if too long path */
+#define MY_RELATIVE_PATH 128 /* name is relative to 'dir' */
+
/* My seek flags */
#define MY_SEEK_SET 0
#define MY_SEEK_CUR 1
@@ -107,30 +117,34 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */
#define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */
#define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */
-#define KEYCACHE_BLOCK_SIZE 1024
+#define DEFAULT_KEYCACHE_BLOCK_SIZE 1024
+#define MAX_KEYCACHE_BLOCK_SIZE 16384
/* root_alloc flags */
#define MY_KEEP_PREALLOC 1
+#define MY_MARK_BLOCKS_FREE 2 /* move used to free list and reuse them */
/* defines when allocating data */
#ifdef SAFEMALLOC
-#define my_malloc(SZ,FLAG) _mymalloc( SZ, __FILE__, __LINE__, FLAG )
-#define my_malloc_ci(SZ,FLAG) _mymalloc( SZ, sFile, uLine, FLAG )
-#define my_realloc(PTR,SZ,FLAG) _myrealloc( PTR, SZ, __FILE__, __LINE__, FLAG )
+#define my_malloc(SZ,FLAG) _mymalloc((SZ), __FILE__, __LINE__, FLAG )
+#define my_malloc_ci(SZ,FLAG) _mymalloc((SZ), sFile, uLine, FLAG )
+#define my_realloc(PTR,SZ,FLAG) _myrealloc((PTR), (SZ), __FILE__, __LINE__, FLAG )
#define my_checkmalloc() _sanity( __FILE__, __LINE__ )
-#define my_free(PTR,FLAG) _myfree( PTR, __FILE__, __LINE__,FLAG)
-#define my_memdup(A,B,C) _my_memdup(A,B,__FILE__,__LINE__,C)
-#define my_strdup(A,C) _my_strdup(A,__FILE__,__LINE__,C)
+#define my_free(PTR,FLAG) _myfree((PTR), __FILE__, __LINE__,FLAG)
+#define my_memdup(A,B,C) _my_memdup((A),(B), __FILE__,__LINE__,C)
+#define my_strdup(A,C) _my_strdup((A), __FILE__,__LINE__,C)
+#define my_strdup_with_length(A,B,C) _my_strdup_with_length((A),(B),__FILE__,__LINE__,C)
#define QUICK_SAFEMALLOC sf_malloc_quick=1
#define NORMAL_SAFEMALLOC sf_malloc_quick=0
extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick;
-extern ulonglong safemalloc_mem_limit;
+extern ulonglong sf_malloc_mem_limit;
+
#define CALLER_INFO_PROTO , const char *sFile, uint uLine
#define CALLER_INFO , __FILE__, __LINE__
#define ORIG_CALLER_INFO , sFile, uLine
#else
-#define my_checkmalloc() (0)
+#define my_checkmalloc()
#undef TERMINATE
#define TERMINATE(A) {}
#define QUICK_SAFEMALLOC
@@ -140,7 +154,9 @@ extern gptr my_malloc(uint Size,myf MyFlags);
extern gptr my_realloc(gptr oldpoint,uint Size,myf MyFlags);
extern void my_no_flags_free(gptr ptr);
extern gptr my_memdup(const byte *from,uint length,myf MyFlags);
-extern my_string my_strdup(const char *from,myf MyFlags);
+extern char *my_strdup(const char *from,myf MyFlags);
+extern char *my_strdup_with_length(const byte *from, uint length,
+ myf MyFlags);
#define my_free(PTR,FG) my_no_flags_free(PTR)
#define CALLER_INFO_PROTO /* nothing */
#define CALLER_INFO /* nothing */
@@ -151,7 +167,7 @@ extern my_string my_strdup(const char *from,myf MyFlags);
#if defined(_AIX) && !defined(__GNUC__)
#pragma alloca
#endif /* _AIX */
-#if defined(__GNUC__) && !defined(HAVE_ALLOCA_H)
+#if defined(__GNUC__) && !defined(HAVE_ALLOCA_H) && ! defined(alloca)
#define alloca __builtin_alloca
#endif /* GNUC */
#define my_alloca(SZ) alloca((size_t) (SZ))
@@ -206,9 +222,10 @@ extern char *get_charsets_dir(char *buf);
/* statistics */
extern ulong _my_cache_w_requests,_my_cache_write,_my_cache_r_requests,
_my_cache_read;
-extern ulong _my_blocks_used,_my_blocks_changed;
+extern ulong _my_blocks_used,_my_blocks_changed;
+extern uint key_cache_block_size;
extern ulong my_file_opened,my_stream_opened, my_tmp_file_created;
-extern my_bool key_cache_inited;
+extern my_bool key_cache_inited, my_init_done;
/* Point to current my_message() */
extern void (*my_sigtstp_cleanup)(void),
@@ -222,7 +239,7 @@ extern int NEAR my_umask, /* Default creation mask */
NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */
NEAR my_dont_interrupt; /* call remember_intr when set */
extern my_bool NEAR mysys_uses_curses, my_use_symdir;
-extern long lCurMemory,lMaxMemory; /* from safemalloc */
+extern ulong sf_malloc_cur_memory, sf_malloc_max_memory;
extern ulong my_default_record_cache_size;
extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
@@ -240,13 +257,20 @@ typedef struct wild_file_pack /* Struct to hold info when selecting files */
typedef struct st_typelib { /* Different types saved here */
uint count; /* How many types */
- const char *name; /* Name of typelib */
+ const char *name; /* Name of typelib */
const char **type_names;
} TYPELIB;
-enum cache_type {READ_CACHE,WRITE_CACHE,READ_FIFO,READ_NET,WRITE_NET};
-enum flush_type { FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED,
- FLUSH_FORCE_WRITE};
+enum cache_type
+{
+ READ_CACHE,WRITE_CACHE,
+ SEQ_READ_APPEND /* sequential read or append */,
+ READ_FIFO, READ_NET,WRITE_NET};
+
+enum flush_type
+{
+ FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, FLUSH_FORCE_WRITE
+};
typedef struct st_record_cache /* Used when cacheing records */
{
@@ -262,45 +286,168 @@ typedef struct st_record_cache /* Used when cacheing records */
enum cache_type type;
} RECORD_CACHE;
-enum file_type { UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE,
- STREAM_BY_FOPEN, STREAM_BY_FDOPEN, FILE_BY_MKSTEMP };
+enum file_type
+{
+ UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE, STREAM_BY_FOPEN, STREAM_BY_FDOPEN,
+ FILE_BY_MKSTEMP, FILE_BY_DUP
+};
extern struct my_file_info
{
my_string name;
enum file_type type;
-#if defined(THREAD) && !defined(HAVE_PREAD)
+#if defined(THREAD) && !defined(HAVE_PREAD)
pthread_mutex_t mutex;
#endif
} my_file_info[MY_NFILE];
-typedef struct st_dynamic_array {
+typedef struct st_dynamic_array
+{
char *buffer;
uint elements,max_element;
uint alloc_increment;
uint size_of_element;
} DYNAMIC_ARRAY;
-typedef struct st_dynamic_string {
+typedef struct st_dynamic_string
+{
char *str;
uint length,max_length,alloc_increment;
} DYNAMIC_STRING;
+struct st_io_cache;
+typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
+
+#ifdef THREAD
+typedef struct st_io_cache_share
+{
+ /* to sync on reads into buffer */
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int count, total;
+ /* actual IO_CACHE that filled the buffer */
+ struct st_io_cache *active;
+#ifdef NOT_YET_IMPLEMENTED
+ /* whether the structure should be free'd */
+ my_bool alloced;
+#endif
+} IO_CACHE_SHARE;
+#endif
typedef struct st_io_cache /* Used when cacheing files */
{
- my_off_t pos_in_file,end_of_file;
- byte *rc_pos,*rc_end,*buffer,*rc_request_pos;
+ /* Offset in file corresponding to the first byte of byte* buffer. */
+ my_off_t pos_in_file;
+ /*
+ The offset of end of file for READ_CACHE and WRITE_CACHE.
+ For SEQ_READ_APPEND it the maximum of the actual end of file and
+ the position represented by read_end.
+ */
+ my_off_t end_of_file;
+ /* Points to current read position in the buffer */
+ byte *read_pos;
+ /* the non-inclusive boundary in the buffer for the currently valid read */
+ byte *read_end;
+ byte *buffer; /* The read buffer */
+ /* Used in ASYNC_IO */
+ byte *request_pos;
+
+ /* Only used in WRITE caches and in SEQ_READ_APPEND to buffer writes */
+ byte *write_buffer;
+ /*
+ Only used in SEQ_READ_APPEND, and points to the current read position
+ in the write buffer. Note that reads in SEQ_READ_APPEND caches can
+ happen from both read buffer (byte* buffer) and write buffer
+ (byte* write_buffer).
+ */
+ byte *append_read_pos;
+ /* Points to current write position in the write buffer */
+ byte *write_pos;
+ /* The non-inclusive boundary of the valid write area */
+ byte *write_end;
+
+ /*
+ Current_pos and current_end are convenience variables used by
+ my_b_tell() and other routines that need to know the current offset
+ current_pos points to &write_pos, and current_end to &write_end in a
+ WRITE_CACHE, and &read_pos and &read_end respectively otherwise
+ */
+ byte **current_pos, **current_end;
+#ifdef THREAD
+ /*
+ The lock is for append buffer used in SEQ_READ_APPEND cache
+ need mutex copying from append buffer to read buffer.
+ */
+ pthread_mutex_t append_buffer_lock;
+ /*
+ The following is used when several threads are reading the
+ same file in parallel. They are synchronized on disk
+ accesses reading the cached part of the file asynchronously.
+ It should be set to NULL to disable the feature. Only
+ READ_CACHE mode is supported.
+ */
+ IO_CACHE_SHARE *share;
+#endif
+ /*
+ A caller will use my_b_read() macro to read from the cache
+ if the data is already in cache, it will be simply copied with
+ memcpy() and internal variables will be accordinging updated with
+ no functions invoked. However, if the data is not fully in the cache,
+ my_b_read() will call read_function to fetch the data. read_function
+ must never be invoked directly.
+ */
int (*read_function)(struct st_io_cache *,byte *,uint);
+ /*
+ Same idea as in the case of read_function, except my_b_write() needs to
+ be replaced with my_b_append() for a SEQ_READ_APPEND cache
+ */
+ int (*write_function)(struct st_io_cache *,const byte *,uint);
+ /*
+ Specifies the type of the cache. Depending on the type of the cache
+ certain operations might not be available and yield unpredicatable
+ results. Details to be documented later
+ */
+ enum cache_type type;
+ /*
+ Callbacks when the actual read I/O happens. These were added and
+ are currently used for binary logging of LOAD DATA INFILE - when a
+ block is read from the file, we create a block create/append event, and
+ when IO_CACHE is closed, we create an end event. These functions could,
+ of course be used for other things
+ */
+ IO_CACHE_CALLBACK pre_read;
+ IO_CACHE_CALLBACK post_read;
+ IO_CACHE_CALLBACK pre_close;
+ void* arg; /* for use by pre/post_read */
char *file_name; /* if used with 'open_cached_file' */
char *dir,*prefix;
- File file;
+ File file; /* file descriptor */
+ /*
+ seek_not_done is set by my_b_seek() to inform the upcoming read/write
+ operation that a seek needs to be preformed prior to the actual I/O
+ error is 0 if the cache operation was successful, -1 if there was a
+ "hard" error, and the actual number of I/O-ed bytes if the read/write was
+ partial.
+ */
int seek_not_done,error;
- uint buffer_length,read_length;
+ /* buffer_length is memory size allocated for buffer or write_buffer */
+ uint buffer_length;
+ /* read_length is the same as buffer_length except when we use async io */
+ uint read_length;
myf myflags; /* Flags used to my_read/my_write */
- enum cache_type type;
+ /*
+ alloced_buffer is 1 if the buffer was allocated by init_io_cache() and
+ 0 if it was supplied by the user.
+ Currently READ_NET is the only one that will use a buffer allocated
+ somewhere else
+ */
+ my_bool alloced_buffer;
#ifdef HAVE_AIOWAIT
+ /*
+ As inidicated by ifdef, this is for async I/O, which is not currently
+ used (because it's not reliable on all systems)
+ */
uint inited;
my_off_t aio_read_pos;
my_aio_result aio_result;
@@ -317,67 +464,41 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *);
#define my_b_EOF INT_MIN
#define my_b_read(info,Buffer,Count) \
- ((info)->rc_pos + (Count) <= (info)->rc_end ?\
- (memcpy(Buffer,(info)->rc_pos,(size_t) (Count)), \
- ((info)->rc_pos+=(Count)),0) :\
+ ((info)->read_pos + (Count) <= (info)->read_end ?\
+ (memcpy(Buffer,(info)->read_pos,(size_t) (Count)), \
+ ((info)->read_pos+=(Count)),0) :\
(*(info)->read_function)((info),Buffer,Count))
+#define my_b_write(info,Buffer,Count) \
+ ((info)->write_pos + (Count) <=(info)->write_end ?\
+ (memcpy((info)->write_pos, (Buffer), (size_t)(Count)),\
+ ((info)->write_pos+=(Count)),0) : \
+ (*(info)->write_function)((info),(Buffer),(Count)))
+
#define my_b_get(info) \
- ((info)->rc_pos != (info)->rc_end ?\
- ((info)->rc_pos++, (int) (uchar) (info)->rc_pos[-1]) :\
+ ((info)->read_pos != (info)->read_end ?\
+ ((info)->read_pos++, (int) (uchar) (info)->read_pos[-1]) :\
_my_b_get(info))
-#define my_b_write(info,Buffer,Count) \
- ((info)->rc_pos + (Count) <= (info)->rc_end ?\
- (memcpy((info)->rc_pos,Buffer,(size_t) (Count)), \
- ((info)->rc_pos+=(Count)),0) :\
- _my_b_write(info,Buffer,Count))
-
/* my_b_write_byte dosn't have any err-check */
#define my_b_write_byte(info,chr) \
- (((info)->rc_pos < (info)->rc_end) ?\
- ((*(info)->rc_pos++)=(chr)) :\
- (_my_b_write(info,0,0) , ((*(info)->rc_pos++)=(chr))))
+ (((info)->write_pos < (info)->write_end) ?\
+ ((*(info)->write_pos++)=(chr)) :\
+ (_my_b_write(info,0,0) , ((*(info)->write_pos++)=(chr))))
#define my_b_fill_cache(info) \
- (((info)->rc_end=(info)->rc_pos),(*(info)->read_function)(info,0,0))
+ (((info)->read_end=(info)->read_pos),(*(info)->read_function)(info,0,0))
#define my_b_tell(info) ((info)->pos_in_file + \
- ((info)->rc_pos - (info)->rc_request_pos))
-
-#define my_b_bytes_in_cache(info) ((uint) ((info)->rc_end - (info)->rc_pos))
-
-typedef struct st_changeable_var {
- const char *name; /* Name of variable */
- long *varptr; /* Pointer to variable */
- long def_value, /* Default value */
- min_value, /* Min allowed value */
- max_value, /* Max allowed value */
- sub_size, /* Subtract this from given value */
- block_size; /* Value should be a mult. of this */
-} CHANGEABLE_VAR;
-
-
-/* structs for alloc_root */
-
-#ifndef ST_USED_MEM_DEFINED
-#define ST_USED_MEM_DEFINED
-typedef struct st_used_mem { /* struct for once_alloc */
- struct st_used_mem *next; /* Next block in use */
- unsigned int left; /* memory left in block */
- unsigned int size; /* Size of block */
-} USED_MEM;
-
-typedef struct st_mem_root {
- USED_MEM *free;
- USED_MEM *used;
- USED_MEM *pre_alloc;
- unsigned int min_malloc;
- unsigned int block_size;
-
- void (*error_handler)(void);
-} MEM_ROOT;
-#endif
+ (uint) (*(info)->current_pos - (info)->request_pos))
+
+/* tell write offset in the SEQ_APPEND cache */
+my_off_t my_b_append_tell(IO_CACHE* info);
+
+#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
+ *(info)->current_pos)
+
+#include <my_alloc.h>
/* Prototypes for mysys and my_func functions */
@@ -397,6 +518,7 @@ extern File my_register_filename(File fd, const char *FileName,
extern File my_create(const char *FileName,int CreateFlags,
int AccsesFlags, myf MyFlags);
extern int my_close(File Filedes,myf MyFlags);
+extern File my_dup(File file, myf MyFlags);
extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
extern int my_readlink(char *to, const char *filename, myf MyFlags);
extern int my_realpath(char *to, const char *filename, myf MyFlags);
@@ -432,6 +554,10 @@ extern gptr _my_memdup(const byte *from,uint length,
const char *sFile, uint uLine,myf MyFlag);
extern my_string _my_strdup(const char *from, const char *sFile, uint uLine,
myf MyFlag);
+extern char *_my_strdup_with_length(const byte *from, uint length,
+ const char *sFile, uint uLine,
+ myf MyFlag);
+
#ifndef TERMINATE
extern void TERMINATE(FILE *file);
#endif
@@ -439,7 +565,8 @@ extern void init_glob_errs(void);
extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
extern int my_fclose(FILE *fd,myf MyFlags);
-extern int my_chsize(File fd,my_off_t newlength,myf MyFlags);
+extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
+extern int my_sync(File fd, myf my_flags);
extern int my_error _VARARGS((int nr,myf MyFlags, ...));
extern int my_printf_error _VARARGS((uint my_err, const char *format,
myf MyFlags, ...)
@@ -450,7 +577,7 @@ extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
extern int my_message(uint my_err, const char *str,myf MyFlags);
extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags);
extern int my_message_curses(uint my_err, const char *str,myf MyFlags);
-extern void my_init(void);
+extern my_bool my_init(void);
extern void my_end(int infoflag);
extern int my_redel(const char *from, const char *to, int MyFlags);
extern int my_copystat(const char *from, const char *to, int MyFlags);
@@ -474,12 +601,12 @@ extern uint dirname_part(my_string to,const char *name);
extern uint dirname_length(const char *name);
#define base_name(A) (A+dirname_length(A))
extern int test_if_hard_path(const char *dir_name);
-extern char *convert_dirname(my_string name);
+extern char *convert_dirname(char *to, const char *from, const char *from_end);
extern void to_unix_path(my_string name);
extern my_string fn_ext(const char *name);
extern my_string fn_same(my_string toname,const char *name,int flag);
-extern my_string fn_format(my_string to,const char *name,const char *dsk,
- const char *form,int flag);
+extern my_string fn_format(my_string to,const char *name,const char *dir,
+ const char *form, uint flag);
extern size_s strlength(const char *str);
extern void pack_dirname(my_string to,const char *from);
extern uint unpack_dirname(my_string to,const char *from);
@@ -517,7 +644,8 @@ extern int flush_write_cache(RECORD_CACHE *info);
extern long my_clock(void);
extern sig_handler sigtstp_handler(int signal_number);
extern void handle_recived_signals(void);
-extern int init_key_cache(ulong use_mem,ulong leave_this_much_mem);
+extern int init_key_cache(ulong use_mem);
+extern int resize_key_cache(ulong use_mem);
extern byte *key_cache_read(File file,my_off_t filepos,byte* buff,uint length,
uint block_length,int return_buffer);
extern int key_cache_write(File file,my_off_t filepos,byte* buff,uint length,
@@ -538,17 +666,31 @@ extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type,
my_off_t seek_offset,pbool use_async_io,
pbool clear_cache);
extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count);
+#ifdef THREAD
+extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count);
+extern void init_io_cache_share(IO_CACHE *info,
+ IO_CACHE_SHARE *s, uint num_threads);
+extern void remove_io_thread(IO_CACHE *info);
+#endif
+extern int _my_b_seq_read(IO_CACHE *info,byte *Buffer,uint Count);
extern int _my_b_net_read(IO_CACHE *info,byte *Buffer,uint Count);
extern int _my_b_get(IO_CACHE *info);
extern int _my_b_async_read(IO_CACHE *info,byte *Buffer,uint Count);
extern int _my_b_write(IO_CACHE *info,const byte *Buffer,uint Count);
+extern int my_b_append(IO_CACHE *info,const byte *Buffer,uint Count);
+extern int my_b_safe_write(IO_CACHE *info,const byte *Buffer,uint Count);
+
extern int my_block_write(IO_CACHE *info, const byte *Buffer,
uint Count, my_off_t pos);
-extern int flush_io_cache(IO_CACHE *info);
+extern int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock);
+
+#define flush_io_cache(info) _flush_io_cache((info),1)
+
extern int end_io_cache(IO_CACHE *info);
extern uint my_b_fill(IO_CACHE *info);
extern void my_b_seek(IO_CACHE *info,my_off_t pos);
extern uint my_b_gets(IO_CACHE *info, char *to, uint max_length);
+extern my_off_t my_b_filelength(IO_CACHE *info);
extern uint my_b_printf(IO_CACHE *info, const char* fmt, ...);
extern uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,
@@ -585,10 +727,6 @@ my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
extern my_bool dynstr_realloc(DYNAMIC_STRING *str, ulong additional_size);
extern void dynstr_free(DYNAMIC_STRING *str);
-void set_all_changeable_vars(CHANGEABLE_VAR *vars);
-my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars);
-my_bool set_changeable_varval(const char *var, ulong val,
- CHANGEABLE_VAR *vars);
#ifdef HAVE_MLOCK
extern byte *my_malloc_lock(uint length,myf flags);
extern void my_free_lock(byte *ptr,myf flags);
@@ -597,29 +735,36 @@ extern void my_free_lock(byte *ptr,myf flags);
#define my_free_lock(A,B) my_free((A),(B))
#endif
#define alloc_root_inited(A) ((A)->min_malloc != 0)
-void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size);
-gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
-void free_root(MEM_ROOT *root, myf MyFLAGS);
-char *strdup_root(MEM_ROOT *root,const char *str);
-char *memdup_root(MEM_ROOT *root,const char *str,uint len);
-void load_defaults(const char *conf_file, const char **groups,
- int *argc, char ***argv);
-void free_defaults(char **argv);
-void print_defaults(const char *conf_file, const char **groups);
-my_bool my_compress(byte *, ulong *, ulong *);
-my_bool my_uncompress(byte *, ulong *, ulong *);
-byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen);
-ulong checksum(const byte *mem, uint count);
-
-#if defined(_MSC_VER) && !defined(__WIN__)
-extern void sleep(int sec);
-#endif
+extern void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
+ uint pre_alloc_size);
+extern gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
+extern void free_root(MEM_ROOT *root, myf MyFLAGS);
+extern void set_prealloc_root(MEM_ROOT *root, char *ptr);
+extern void reset_root_defaults(MEM_ROOT *mem_root, uint block_size,
+ uint prealloc_size);
+extern char *strdup_root(MEM_ROOT *root,const char *str);
+extern char *strmake_root(MEM_ROOT *root,const char *str,uint len);
+extern char *memdup_root(MEM_ROOT *root,const char *str,uint len);
+extern int load_defaults(const char *conf_file, const char **groups,
+ int *argc, char ***argv);
+extern void free_defaults(char **argv);
+extern void print_defaults(const char *conf_file, const char **groups);
+extern my_bool my_compress(byte *, ulong *, ulong *);
+extern my_bool my_uncompress(byte *, ulong *, ulong *);
+extern byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen);
+extern ulong checksum(const byte *mem, uint count);
+extern uint my_bit_log2(ulong value);
+uint my_count_bits(ulonglong v);
+extern void my_sleep(ulong m_seconds);
+
#ifdef __WIN__
extern my_bool have_tcpip; /* Is set if tcpip is used */
#endif
-
-#ifdef __cplusplus
-}
+#ifdef __NETWARE__
+void netware_reg_user(const char *ip, const char *user,
+ const char *application);
#endif
+
+C_MODE_END
#include "raid.h"
#endif /* _my_sys_h */
diff --git a/include/my_tree.h b/include/my_tree.h
index 0a227ea3944..7cc7c615ba6 100644
--- a/include/my_tree.h
+++ b/include/my_tree.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _tree_h
#define _tree_h
@@ -32,6 +31,9 @@ typedef enum { left_root_right, right_root_left } TREE_WALK;
typedef uint32 element_count;
typedef int (*tree_walk_action)(void *,element_count,void *);
+typedef enum { free_init, free_free, free_end } TREE_FREE;
+typedef void (*tree_element_free)(void*, TREE_FREE, void *);
+
#ifdef MSDOS
typedef struct st_tree_element {
struct st_tree_element *left,*right;
@@ -49,18 +51,22 @@ typedef struct st_tree_element {
typedef struct st_tree {
TREE_ELEMENT *root,null_element;
TREE_ELEMENT **parents[MAX_TREE_HIGHT];
- uint offset_to_key,elements_in_tree,size_of_element;
- qsort_cmp compare;
+ uint offset_to_key,elements_in_tree,size_of_element,memory_limit,allocated;
+ qsort_cmp2 compare;
+ void* custom_arg;
MEM_ROOT mem_root;
my_bool with_delete;
- void (*free)(void *);
+ tree_element_free free;
} TREE;
- /* Functions on hole tree */
-void init_tree(TREE *tree,uint default_alloc_size, int element_size,
- qsort_cmp compare, my_bool with_delete,
- void (*free_element)(void*));
+ /* Functions on whole tree */
+void init_tree(TREE *tree, uint default_alloc_size, uint memory_limit,
+ int size, qsort_cmp2 compare, my_bool with_delete,
+ tree_element_free free_element, void *custom_arg);
void delete_tree(TREE*);
+void reset_tree(TREE*);
+ /* similar to delete tree, except we do not my_free() blocks in mem_root
+ */
#define is_tree_inited(tree) ((tree)->root != 0)
/* Functions on leafs */
@@ -70,6 +76,8 @@ int tree_walk(TREE *tree,tree_walk_action action,
void *argument, TREE_WALK visit);
int tree_delete(TREE *tree,void *key);
+#define TREE_ELEMENT_EXTRA_SIZE (sizeof(TREE_ELEMENT) + sizeof(void*))
+
#ifdef __cplusplus
}
#endif
diff --git a/include/myisam.h b/include/myisam.h
index 9ecb5ef4294..87a40b50c73 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using myisam_funktions */
@@ -46,6 +45,11 @@ extern "C" {
/* Max extra space to use when sorting keys */
#define MI_MAX_TEMP_LENGTH 256*1024L*1024L
+/* Possible values for myisam_block_size (must be power of 2) */
+#define MI_KEY_BLOCK_LENGTH 1024 /* default key block length */
+#define MI_MIN_KEY_BLOCK_LENGTH 1024 /* Min key block length */
+#define MI_MAX_KEY_BLOCK_LENGTH 16384
+
#define mi_portable_sizeof_char_ptr 8
typedef uint32 ha_checksum;
@@ -68,6 +72,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */
ulong mean_reclength; /* Mean recordlength (if packed) */
ulonglong auto_increment;
ulonglong key_map; /* Which keys are used */
+ char *data_file_name, *index_file_name;
uint keys; /* Number of keys in use */
uint options; /* HA_OPTION_... used */
int errkey, /* With key was dupplicated on err */
@@ -86,6 +91,7 @@ typedef struct st_mi_isaminfo /* Struct from h_info */
typedef struct st_mi_create_info
{
+ const char *index_file_name, *data_file_name; /* If using symlinks */
ha_rows max_rows;
ha_rows reloc_rows;
ulonglong auto_increment;
@@ -94,6 +100,7 @@ typedef struct st_mi_create_info
ulong raid_chunksize;
uint old_options;
uint8 language;
+ my_bool with_auto_increment;
} MI_CREATE_INFO;
struct st_myisam_info; /* For referense */
@@ -120,6 +127,7 @@ typedef struct st_mi_keydef /* Key definition with open & info */
uint16 keysegs; /* Number of key-segment */
uint16 flag; /* NOSAME, PACK_USED */
+ uint8 key_alg; /* BTREE, RTREE */
uint16 block_length; /* Length of keyblock (auto) */
uint16 underflow_block_length; /* When to execute underflow */
uint16 keylength; /* Tot length of keyparts (auto) */
@@ -163,9 +171,11 @@ typedef struct st_mi_decode_tree /* Decode huff-table */
struct st_mi_bit_buff;
-/* Note that null markers should always be first in a row !
- When creating a column, one should only specify:
- type, length, null_bit and null_pos */
+/*
+ Note that null markers should always be first in a row !
+ When creating a column, one should only specify:
+ type, length, null_bit and null_pos
+*/
typedef struct st_columndef /* column information */
{
@@ -184,12 +194,15 @@ typedef struct st_columndef /* column information */
#endif
} MI_COLUMNDEF;
+/* invalidator function reference for Query Cache */
+typedef void (* invalidator_by_filename)(const char * filename);
extern my_string myisam_log_filename; /* Name of logfile */
extern uint myisam_block_size;
-extern my_bool myisam_flush,myisam_delay_key_write;
+extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user;
extern my_bool myisam_concurrent_insert;
extern my_off_t myisam_max_temp_length,myisam_max_extra_temp_length;
+extern ulong myisam_bulk_insert_tree_size;
/* Prototypes for myisam-functions */
@@ -219,13 +232,14 @@ extern my_off_t mi_position(struct st_myisam_info *file);
extern int mi_status(struct st_myisam_info *info, MI_ISAMINFO *x, uint flag);
extern int mi_lock_database(struct st_myisam_info *file,int lock_type);
extern int mi_create(const char *name,uint keys,MI_KEYDEF *keydef,
- uint columns, MI_COLUMNDEF *columndef,
+ uint columns, MI_COLUMNDEF *columndef,
uint uniques, MI_UNIQUEDEF *uniquedef,
MI_CREATE_INFO *create_info, uint flags);
extern int mi_delete_table(const char *name);
extern int mi_rename(const char *from, const char *to);
extern int mi_extra(struct st_myisam_info *file,
- enum ha_extra_function function);
+ enum ha_extra_function function,
+ void *extra_arg);
extern ha_rows mi_records_in_range(struct st_myisam_info *info,int inx,
const byte *start_key,uint start_key_len,
enum ha_rkey_function start_search_flag,
@@ -239,42 +253,60 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def);
/* this is used to pass to mysql_myisamchk_table -- by Sasha Pachev */
-#define MYISAMCHK_REPAIR 1 /* equivalent to myisamchk -r*/
-#define MYISAMCHK_VERIFY 2 /* run equivalent of myisamchk -c,
- * if corruption is detected, do myisamchk -r*/
-
-/* definitions needed for myisamchk.c -- by Sasha Pachev */
-
-#define T_VERBOSE 1
-#define T_SILENT 2
-#define T_DESCRIPT 4
-#define T_EXTEND 8
-#define T_INFO 16
-#define T_REP 32
-#define T_OPT 64 /* Not currently used */
-#define T_FORCE_CREATE 128
-#define T_WRITE_LOOP 256
-#define T_UNPACK 512
-#define T_STATISTICS 1024
-#define T_VERY_SILENT 2048
-#define T_SORT_RECORDS 4096
-#define T_SORT_INDEX 8192
-#define T_WAIT_FOREVER 16384
-#define T_REP_BY_SORT 32768L
-#define T_FAST 65536L
-#define T_READONLY 131072L
-#define T_MEDIUM T_READONLY*2
-#define T_AUTO_INC T_MEDIUM*2
-#define T_CHECK T_AUTO_INC*2
-#define T_UPDATE_STATE T_CHECK*2
-#define T_CHECK_ONLY_CHANGED T_UPDATE_STATE*2
-#define T_DONT_CHECK_CHECKSUM T_CHECK_ONLY_CHANGED*2
-#define T_TRUST_HEADER T_DONT_CHECK_CHECKSUM*2
-#define T_CREATE_MISSING_KEYS T_TRUST_HEADER*2
-#define T_SAFE_REPAIR T_CREATE_MISSING_KEYS*2
-#define T_AUTO_REPAIR T_SAFE_REPAIR*2
-#define T_BACKUP_DATA T_AUTO_REPAIR*2
-#define T_CALC_CHECKSUM T_BACKUP_DATA*2
+#define MYISAMCHK_REPAIR 1 /* equivalent to myisamchk -r */
+#define MYISAMCHK_VERIFY 2 /* Verify, run repair if failure */
+
+/*
+ Definitions needed for myisamchk.c
+
+ Entries marked as "QQ to be removed" are NOT used to
+ pass check/repair options to mi_check.c. They are used
+ internally by myisamchk.c or/and ha_myisam.cc and should NOT
+ be stored together with other flags. They should be removed
+ from the following list to make addition of new flags possible.
+*/
+
+#define T_AUTO_INC 1
+#define T_AUTO_REPAIR 2 /* QQ to be removed */
+#define T_BACKUP_DATA 4
+#define T_CALC_CHECKSUM 8
+#define T_CHECK 16 /* QQ to be removed */
+#define T_CHECK_ONLY_CHANGED 32 /* QQ to be removed */
+#define T_CREATE_MISSING_KEYS 64
+#define T_DESCRIPT 128
+#define T_DONT_CHECK_CHECKSUM 256
+#define T_EXTEND 512
+#define T_FAST (1L << 10) /* QQ to be removed */
+#define T_FORCE_CREATE (1L << 11) /* QQ to be removed */
+#define T_FORCE_UNIQUENESS (1L << 12)
+#define T_INFO (1L << 13)
+#define T_MEDIUM (1L << 14)
+#define T_QUICK (1L << 15) /* QQ to be removed */
+#define T_READONLY (1L << 16) /* QQ to be removed */
+#define T_REP (1L << 17)
+#define T_REP_BY_SORT (1L << 18) /* QQ to be removed */
+#define T_REP_PARALLEL (1L << 19) /* QQ to be removed */
+#define T_RETRY_WITHOUT_QUICK (1L << 20)
+#define T_SAFE_REPAIR (1L << 21)
+#define T_SILENT (1L << 22)
+#define T_SORT_INDEX (1L << 23) /* QQ to be removed */
+#define T_SORT_RECORDS (1L << 24) /* QQ to be removed */
+#define T_STATISTICS (1L << 25)
+#define T_UNPACK (1L << 26)
+#define T_UPDATE_STATE (1L << 27)
+#define T_VERBOSE (1L << 28)
+#define T_VERY_SILENT (1L << 29)
+#define T_WAIT_FOREVER (1L << 30)
+#define T_WRITE_LOOP ((ulong) 1L << 31)
+
+#define T_REP_ANY (T_REP | T_REP_BY_SORT | T_REP_PARALLEL)
+
+/*
+ Flags used by myisamchk.c or/and ha_myisam.cc that are NOT passed
+ to mi_check.c follows:
+*/
+
+#define TT_USEFRM 1
#define O_NEW_INDEX 1 /* Bits set in out_flag */
#define O_NEW_DATA 2
@@ -282,31 +314,14 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def);
/* these struct is used by my_check to tell it what to do */
-typedef struct st_sort_key_blocks { /* Used when sorting */
+typedef struct st_sort_key_blocks /* Used when sorting */
+{
uchar *buff,*end_pos;
uchar lastkey[MI_MAX_POSSIBLE_KEY_BUFF];
uint last_length;
int inited;
} SORT_KEY_BLOCKS;
-struct st_mi_check_param;
-
-typedef struct st_sort_info {
- MI_INFO *info;
- struct st_mi_check_param *param;
- enum data_file_type new_data_file_type;
- SORT_KEY_BLOCKS *key_block,*key_block_end;
- uint key,find_length;
- my_off_t pos,max_pos,filepos,start_recpos,filelength,dupp,buff_length;
- ha_rows max_records;
- ulonglong unique[MI_MAX_KEY_SEG+1];
- my_bool fix_datafile;
- char *record,*buff;
- MI_KEYDEF *keyinfo;
- MI_KEYSEG *keyseg;
-} SORT_INFO;
-
-
typedef struct st_mi_check_param
{
ulonglong auto_increment_value;
@@ -319,18 +334,16 @@ typedef struct st_mi_check_param
ha_checksum record_checksum,glob_crc;
ulong use_buffers,read_buffer_length,write_buffer_length,
sort_buffer_length,sort_key_blocks;
- uint out_flag,warning_printed,error_printed,
- opt_rep_quick,verbose;
+ uint out_flag,warning_printed,error_printed,verbose;
uint opt_sort_key,total_files,max_level;
uint testflag;
uint8 language;
my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
- my_bool retry_repair,retry_without_quick, force_sort, calc_checksum;
+ my_bool retry_repair, force_sort, calc_checksum;
char temp_filename[FN_REFLEN],*isam_file_name,*tmpdir;
int tmpfile_createflag;
myf myf_rw;
IO_CACHE read_cache;
- SORT_INFO sort_info;
ulonglong unique_count[MI_MAX_KEY_SEG+1];
ha_checksum key_crc[MI_MAX_POSSIBLE_KEY];
ulong rec_per_key_part[MI_MAX_KEY_SEG*MI_MAX_POSSIBLE_KEY];
@@ -340,18 +353,52 @@ typedef struct st_mi_check_param
} MI_CHECK;
-typedef struct st_mi_sortinfo {
+typedef struct st_sort_info
+{
+ my_off_t filelength,dupp,buff_length;
ha_rows max_records;
+ uint current_key, total_keys;
+ myf myf_rw;
+ enum data_file_type new_data_file_type;
+ MI_INFO *info;
+ MI_CHECK *param;
+ char *buff;
+ SORT_KEY_BLOCKS *key_block,*key_block_end;
+ /* sync things*/
+ uint got_error, threads_running;
+#ifdef THREAD
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+#endif
+} SORT_INFO;
+
+
+typedef struct st_mi_sort_param
+{
+#ifdef THREAD
+ pthread_t thr;
+#endif
+ IO_CACHE read_cache, tempfile, tempfile_for_exceptions;
+ DYNAMIC_ARRAY buffpek;
+ ulonglong unique[MI_MAX_KEY_SEG+1];
+ my_off_t pos,max_pos,filepos,start_recpos;
+ uint key, key_length,real_key_length,sortbuff_size;
+ uint maxbuffers, keys, find_length, sort_keys_length;
+ my_bool fix_datafile, master;
+ MI_KEYDEF *keyinfo;
SORT_INFO *sort_info;
+ uchar **sort_keys;
+ byte *rec_buff;
+ void *wordlist, *wordptr;
+ char *record;
char *tmpdir;
- int (*key_cmp)(SORT_INFO *info, const void *, const void *);
- int (*key_read)(SORT_INFO *info,void *buff);
- int (*key_write)(SORT_INFO *info, const void *buff);
- void (*lock_in_memory)(MI_CHECK *info);
- uint key_length;
- myf myf_rw;
+ int (*key_cmp)(struct st_mi_sort_param *, const void *, const void *);
+ int (*key_read)(struct st_mi_sort_param *,void *);
+ int (*key_write)(struct st_mi_sort_param *, const void *);
+ void (*lock_in_memory)(MI_CHECK *);
} MI_SORT_PARAM;
+
/* functions in mi_check */
void myisamchk_init(MI_CHECK *param);
int chk_status(MI_CHECK *param, MI_INFO *info);
@@ -364,6 +411,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name);
int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
const char * name, int rep_quick);
+int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
+ const char * name, int rep_quick);
int change_to_newfile(const char * filename, const char * old_ext,
const char * new_ext, uint raid_chunks,
myf myflags);
@@ -374,20 +423,25 @@ int flush_blocks(MI_CHECK *param, File file);
void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
my_bool repair);
int update_state_info(MI_CHECK *param, MI_INFO *info,uint update);
+void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part,
+ ulonglong *unique, ulonglong records);
int filecopy(MI_CHECK *param, File to,File from,my_off_t start,
my_off_t length, const char *type);
int movepoint(MI_INFO *info,byte *record,my_off_t oldpos,
my_off_t newpos, uint prot_key);
-int sort_write_record(SORT_INFO *sort_info);
- int write_data_suffix(MI_CHECK *param, MI_INFO *info);
-int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
- ulong);
+int sort_write_record(MI_SORT_PARAM *sort_param);
+int write_data_suffix(SORT_INFO *sort_info, my_bool fix_datafile);
+int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, ulong);
int test_if_almost_full(MI_INFO *info);
int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename);
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map,
my_bool force);
+int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows);
+void mi_flush_bulk_insert(MI_INFO *info, uint inx);
+void mi_end_bulk_insert(MI_INFO *info);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/myisammrg.h b/include/myisammrg.h
index a797c954614..ea882450eef 100644
--- a/include/myisammrg.h
+++ b/include/myisammrg.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using merge_isam_funktions */
@@ -34,6 +33,13 @@ extern "C" {
#define MYRG_NAME_EXT ".MRG"
+/* In which table to INSERT rows */
+#define MERGE_INSERT_DISABLED 0
+#define MERGE_INSERT_TO_FIRST 1
+#define MERGE_INSERT_TO_LAST 2
+
+extern TYPELIB merge_insert_method;
+
/* Param to/from myrg_info */
typedef struct st_mymerge_info /* Struct from h_info */
@@ -44,7 +50,8 @@ typedef struct st_mymerge_info /* Struct from h_info */
ulonglong data_file_length;
uint reclength; /* Recordlength */
int errkey; /* With key was dupplicated on err */
- uint options; /* HA_OPTIONS_... used */
+ uint options; /* HA_OPTION_... used */
+ ulong *rec_per_key; /* for sql optimizing */
} MYMERGE_INFO;
typedef struct st_myrg_table_info
@@ -59,10 +66,13 @@ typedef struct st_myrg_info
ulonglong records; /* records in tables */
ulonglong del; /* Removed records */
ulonglong data_file_length;
+ ulong cache_size;
+ uint merge_insert_method;
uint tables,options,reclength,keys;
my_bool cache_in_use;
- LIST open_list;
- QUEUE by_key;
+ LIST open_list;
+ QUEUE by_key;
+ ulong *rec_per_key_part; /* for sql optimizing */
} MYRG_INFO;
@@ -81,11 +91,14 @@ extern int myrg_rkey(MYRG_INFO *file,byte *buf,int inx,const byte *key,
extern int myrg_rrnd(MYRG_INFO *file,byte *buf,ulonglong pos);
extern int myrg_rsame(MYRG_INFO *file,byte *record,int inx);
extern int myrg_update(MYRG_INFO *file,const byte *old,byte *new_rec);
+extern int myrg_write(MYRG_INFO *info,byte *rec);
extern int myrg_status(MYRG_INFO *file,MYMERGE_INFO *x,int flag);
extern int myrg_lock_database(MYRG_INFO *file,int lock_type);
-extern int myrg_create(const char *name,const char **table_names,
- my_bool fix_names);
-extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function);
+extern int myrg_create(const char *name, const char **table_names,
+ uint insert_method, my_bool fix_names);
+extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function,
+ void *extra_arg);
+extern void myrg_extrafunc(MYRG_INFO *info,invalidator_by_filename inv);
extern ha_rows myrg_records_in_range(MYRG_INFO *info,int inx,
const byte *start_key,uint start_key_len,
enum ha_rkey_function start_search_flag,
diff --git a/include/myisampack.h b/include/myisampack.h
index a51cdc7e6eb..6004177cfb0 100644
--- a/include/myisampack.h
+++ b/include/myisampack.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Storing of values in high byte first order.
@@ -213,9 +212,9 @@
/* Fix to avoid warnings when sizeof(ha_rows) == sizeof(long) */
-#ifdef BIG_TABLE
+#ifdef BIG_TABLES
#define mi_rowstore(T,A) mi_int8store(T,A)
-#define mi_rowkorr(T,A) mi_uint8korr(T)
+#define mi_rowkorr(T) mi_uint8korr(T)
#else
#define mi_rowstore(T,A) { mi_int4store(T,0); mi_int4store(((T)+4),A); }
#define mi_rowkorr(T) mi_uint4korr((T)+4)
diff --git a/include/mysql.h b/include/mysql.h
index 0bd5b7092b8..3ffc014c449 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -1,21 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000-2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-/* defines for the libmysql library */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _mysql_h
#define _mysql_h
@@ -28,12 +25,10 @@
#undef __WIN__
#endif
-#ifndef MYSQL_SERVER
#ifdef __cplusplus
extern "C" {
#endif
-#endif
-
+
#ifndef _global_h /* If not standard header */
#include <sys/types.h>
#ifdef __LCC__
@@ -50,38 +45,28 @@ typedef char my_bool;
#endif
typedef char * gptr;
-#ifndef ST_USED_MEM_DEFINED
-#define ST_USED_MEM_DEFINED
-typedef struct st_used_mem { /* struct for once_alloc */
- struct st_used_mem *next; /* Next block in use */
- unsigned int left; /* memory left in block */
- unsigned int size; /* size of block */
-} USED_MEM;
-typedef struct st_mem_root {
- USED_MEM *free;
- USED_MEM *used;
- USED_MEM *pre_alloc;
- unsigned int min_malloc;
- unsigned int block_size;
-
- void (*error_handler)(void);
-} MEM_ROOT;
-#endif
-
#ifndef my_socket_defined
#ifdef __WIN__
#define my_socket SOCKET
#else
typedef int my_socket;
-#endif
-#endif
-#endif
+#endif /* __WIN__ */
+#endif /* my_socket_defined */
+#endif /* _global_h */
+
#include "mysql_com.h"
#include "mysql_version.h"
extern unsigned int mysql_port;
extern char *mysql_unix_port;
+#define CLIENT_NET_READ_TIMEOUT 365*24*3600 /* Timeout on read */
+#define CLIENT_NET_WRITE_TIMEOUT 365*24*3600 /* Timeout on write */
+
+#ifdef __NETWARE__
+#pragma pack(push, 8) /* 8 byte alignment */
+#endif
+
#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG)
#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG)
#define IS_BLOB(n) ((n) & BLOB_FLAG)
@@ -92,12 +77,14 @@ extern char *mysql_unix_port;
typedef struct st_mysql_field {
char *name; /* Name of column */
char *table; /* Table of column if column was a field */
+ char *org_table; /* Org table name if table was an alias */
+ char *db; /* Database for table */
char *def; /* Default value (set by mysql_list_fields) */
- enum enum_field_types type; /* Type of field. Se mysql_com.h for types */
- unsigned int length; /* Width of column */
- unsigned int max_length; /* Max width of selected set */
+ unsigned long length; /* Width of column */
+ unsigned long max_length; /* Max width of selected set */
unsigned int flags; /* Div flags */
unsigned int decimals; /* Number of decimals in field */
+ enum enum_field_types type; /* Type of field. Se mysql_com.h for types */
} MYSQL_FIELD;
typedef char **MYSQL_ROW; /* return data as array of strings */
@@ -120,6 +107,8 @@ typedef struct st_mysql_rows {
typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */
+#include "my_alloc.h"
+
typedef struct st_mysql_data {
my_ulonglong rows;
unsigned int fields;
@@ -129,15 +118,32 @@ typedef struct st_mysql_data {
struct st_mysql_options {
unsigned int connect_timeout,client_flag;
- my_bool compress,named_pipe;
unsigned int port;
char *host,*init_command,*user,*password,*unix_socket,*db;
char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
- my_bool use_ssl; /* if to use SSL or not */
char *ssl_key; /* PEM key file */
char *ssl_cert; /* PEM cert file */
char *ssl_ca; /* PEM CA file */
char *ssl_capath; /* PEM directory of CA-s? */
+ char *ssl_cipher; /* cipher to use */
+ unsigned long max_allowed_packet;
+ my_bool use_ssl; /* if to use SSL or not */
+ my_bool compress,named_pipe;
+ /*
+ On connect, find out the replication role of the server, and
+ establish connections to all the peers
+ */
+ my_bool rpl_probe;
+ /*
+ Each call to mysql_real_query() will parse it to tell if it is a read
+ or a write, and direct it to the slave or the master
+ */
+ my_bool rpl_parse;
+ /*
+ If set, never read from a master,only from slave, when doing
+ a read that is replication-aware
+ */
+ my_bool no_master_reads;
};
enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS,
@@ -149,48 +155,116 @@ enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS,
enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,
MYSQL_STATUS_USE_RESULT};
+/*
+ There are three types of queries - the ones that have to go to
+ the master, the ones that go to a slave, and the adminstrative
+ type which must happen on the pivot connectioin
+*/
+enum mysql_rpl_type { MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE,
+ MYSQL_RPL_ADMIN };
+
+
typedef struct st_mysql {
NET net; /* Communication parameters */
gptr connector_fd; /* ConnectorFd for SSL */
char *host,*user,*passwd,*unix_socket,*server_version,*host_info,
*info,*db;
- unsigned int port,client_flag,server_capabilities;
- unsigned int protocol_version;
- unsigned int field_count;
- unsigned int server_status;
- unsigned long thread_id; /* Id for connection in server */
+ struct charset_info_st *charset;
+ MYSQL_FIELD *fields;
+ MEM_ROOT field_alloc;
my_ulonglong affected_rows;
my_ulonglong insert_id; /* id if insert on table with NEXTNR */
my_ulonglong extra_info; /* Used by mysqlshow */
+ unsigned long thread_id; /* Id for connection in server */
unsigned long packet_length;
+ unsigned int port,client_flag,server_capabilities;
+ unsigned int protocol_version;
+ unsigned int field_count;
+ unsigned int server_status;
+ unsigned int server_language;
+ struct st_mysql_options options;
enum mysql_status status;
- MYSQL_FIELD *fields;
- MEM_ROOT field_alloc;
my_bool free_me; /* If free in mysql_close */
my_bool reconnect; /* set to 1 if automatic reconnect */
- struct st_mysql_options options;
char scramble_buff[9];
- struct charset_info_st *charset;
- unsigned int server_language;
+
+ /*
+ Set if this is the original connection, not a master or a slave we have
+ added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave()
+ */
+ my_bool rpl_pivot;
+ /*
+ Pointers to the master, and the next slave connections, points to
+ itself if lone connection.
+ */
+ struct st_mysql* master, *next_slave;
+
+ struct st_mysql* last_used_slave; /* needed for round-robin slave pick */
+ /* needed for send/read/store/use result to work correctly with replication */
+ struct st_mysql* last_used_con;
} MYSQL;
typedef struct st_mysql_res {
my_ulonglong row_count;
- unsigned int field_count, current_field;
MYSQL_FIELD *fields;
MYSQL_DATA *data;
MYSQL_ROWS *data_cursor;
+ unsigned long *lengths; /* column lengths of current row */
+ MYSQL *handle; /* for unbuffered reads */
MEM_ROOT field_alloc;
+ unsigned int field_count, current_field;
MYSQL_ROW row; /* If unbuffered read */
MYSQL_ROW current_row; /* buffer to current row */
- unsigned long *lengths; /* column lengths of current row */
- MYSQL *handle; /* for unbuffered reads */
- my_bool eof; /* Used my mysql_fetch_row */
+ my_bool eof; /* Used by mysql_fetch_row */
} MYSQL_RES;
-/* Functions to get information from the MYSQL and MYSQL_RES structures */
-/* Should definitely be used if one uses shared libraries */
+#define MAX_MYSQL_MANAGER_ERR 256
+#define MAX_MYSQL_MANAGER_MSG 256
+
+#define MANAGER_OK 200
+#define MANAGER_INFO 250
+#define MANAGER_ACCESS 401
+#define MANAGER_CLIENT_ERR 450
+#define MANAGER_INTERNAL_ERR 500
+
+
+
+typedef struct st_mysql_manager
+{
+ NET net;
+ char *host,*user,*passwd;
+ unsigned int port;
+ my_bool free_me;
+ my_bool eof;
+ int cmd_status;
+ int last_errno;
+ char* net_buf,*net_buf_pos,*net_data_end;
+ int net_buf_size;
+ char last_error[MAX_MYSQL_MANAGER_ERR];
+} MYSQL_MANAGER;
+
+/*
+ Set up and bring down the server; to ensure that applications will
+ work when linked against either the standard client library or the
+ embedded server library, these functions should be called.
+*/
+int STDCALL mysql_server_init(int argc, char **argv, char **groups);
+void STDCALL mysql_server_end(void);
+
+/*
+ Set up and bring down a thread; these function should be called
+ for each thread in an application which opens at least one MySQL
+ connection. All uses of the connection(s) should be between these
+ function calls.
+*/
+my_bool STDCALL mysql_thread_init(void);
+void STDCALL mysql_thread_end(void);
+
+/*
+ Functions to get information from the MYSQL and MYSQL_RES structures
+ Should definitely be used if one uses shared libraries.
+*/
my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res);
unsigned int STDCALL mysql_num_fields(MYSQL_RES *res);
@@ -198,31 +272,24 @@ my_bool STDCALL mysql_eof(MYSQL_RES *res);
MYSQL_FIELD *STDCALL mysql_fetch_field_direct(MYSQL_RES *res,
unsigned int fieldnr);
MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res);
-MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res);
-unsigned int STDCALL mysql_field_tell(MYSQL_RES *res);
+MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res);
+MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res);
unsigned int STDCALL mysql_field_count(MYSQL *mysql);
my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
unsigned int STDCALL mysql_errno(MYSQL *mysql);
-char * STDCALL mysql_error(MYSQL *mysql);
-char * STDCALL mysql_info(MYSQL *mysql);
+const char * STDCALL mysql_error(MYSQL *mysql);
+const char * STDCALL mysql_info(MYSQL *mysql);
unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
const char * STDCALL mysql_character_set_name(MYSQL *mysql);
MYSQL * STDCALL mysql_init(MYSQL *mysql);
-#ifdef HAVE_OPENSSL
int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
const char *cert, const char *ca,
- const char *capath);
-char * STDCALL mysql_ssl_cipher(MYSQL *mysql);
-int STDCALL mysql_ssl_clear(MYSQL *mysql);
-#endif /* HAVE_OPENSSL */
-MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host,
- const char *user, const char *passwd);
+ const char *capath, const char *cipher);
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db);
-#if MYSQL_VERSION_ID >= 32200
MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
const char *user,
const char *passwd,
@@ -230,34 +297,66 @@ MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
unsigned int port,
const char *unix_socket,
unsigned int clientflag);
-#else
-MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
- const char *user,
- const char *passwd,
- unsigned int port,
- const char *unix_socket,
- unsigned int clientflag);
-#endif
void STDCALL mysql_close(MYSQL *sock);
int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
int STDCALL mysql_query(MYSQL *mysql, const char *q);
int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
- unsigned int length);
+ unsigned long length);
int STDCALL mysql_read_query_result(MYSQL *mysql);
int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
- unsigned int length);
-int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
-int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
+ unsigned long length);
+/* perform query on master */
+int STDCALL mysql_master_query(MYSQL *mysql, const char *q,
+ unsigned long length);
+int STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
+ unsigned long length);
+/* perform query on slave */
+int STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
+ unsigned long length);
+int STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
+ unsigned long length);
+
+/*
+ enable/disable parsing of all queries to decide if they go on master or
+ slave
+*/
+void STDCALL mysql_enable_rpl_parse(MYSQL* mysql);
+void STDCALL mysql_disable_rpl_parse(MYSQL* mysql);
+/* get the value of the parse flag */
+int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql);
+
+/* enable/disable reads from master */
+void STDCALL mysql_enable_reads_from_master(MYSQL* mysql);
+void STDCALL mysql_disable_reads_from_master(MYSQL* mysql);
+/* get the value of the master read flag */
+int STDCALL mysql_reads_from_master_enabled(MYSQL* mysql);
+
+enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len);
+
+/* discover the master and its slaves */
+int STDCALL mysql_rpl_probe(MYSQL* mysql);
+
+/* set the master, close/free the old one, if it is not a pivot */
+int STDCALL mysql_set_master(MYSQL* mysql, const char* host,
+ unsigned int port,
+ const char* user,
+ const char* passwd);
+int STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
+ unsigned int port,
+ const char* user,
+ const char* passwd);
+
int STDCALL mysql_shutdown(MYSQL *mysql);
int STDCALL mysql_dump_debug_info(MYSQL *mysql);
int STDCALL mysql_refresh(MYSQL *mysql,
unsigned int refresh_options);
int STDCALL mysql_kill(MYSQL *mysql,unsigned long pid);
int STDCALL mysql_ping(MYSQL *mysql);
-char * STDCALL mysql_stat(MYSQL *mysql);
-char * STDCALL mysql_get_server_info(MYSQL *mysql);
-char * STDCALL mysql_get_client_info(void);
-char * STDCALL mysql_get_host_info(MYSQL *mysql);
+const char * STDCALL mysql_stat(MYSQL *mysql);
+const char * STDCALL mysql_get_server_info(MYSQL *mysql);
+const char * STDCALL mysql_get_client_info(void);
+unsigned long STDCALL mysql_get_client_version(void);
+const char * STDCALL mysql_get_host_info(MYSQL *mysql);
unsigned int STDCALL mysql_get_proto_info(MYSQL *mysql);
MYSQL_RES * STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild);
MYSQL_RES * STDCALL mysql_list_tables(MYSQL *mysql,const char *wild);
@@ -271,7 +370,8 @@ int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
void STDCALL mysql_free_result(MYSQL_RES *result);
void STDCALL mysql_data_seek(MYSQL_RES *result,
my_ulonglong offset);
-MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET);
+MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result,
+ MYSQL_ROW_OFFSET offset);
MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result,
MYSQL_FIELD_OFFSET offset);
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
@@ -295,18 +395,47 @@ char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
unsigned long *length));
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int STDCALL mysql_thread_safe(void);
-
-
+MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con);
+MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
+ const char* host,
+ const char* user,
+ const char* passwd,
+ unsigned int port);
+void STDCALL mysql_manager_close(MYSQL_MANAGER* con);
+int STDCALL mysql_manager_command(MYSQL_MANAGER* con,
+ const char* cmd, int cmd_len);
+int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con,
+ char* res_buf,
+ int res_buf_size);
#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
-/* new api functions */
-
+#ifdef USE_OLD_FUNCTIONS
+MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host,
+ const char *user, const char *passwd);
+int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
+int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
+#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
+#endif
#define HAVE_MYSQL_REAL_CONNECT
-#ifndef MYSQL_SERVER
+/*
+ The following functions are mainly exported because of mysqlbinlog;
+ They are not for general usage
+*/
+
+int simple_command(MYSQL *mysql,enum enum_server_command command,
+ const char *arg, unsigned long length, my_bool skipp_check);
+unsigned long net_safe_read(MYSQL* mysql);
+int mysql_once_init(void);
+
+extern my_bool server_inited;
+
+#ifdef __NETWARE__
+#pragma pack(pop) /* restore alignment */
+#endif
+
#ifdef __cplusplus
}
#endif
-#endif
-#endif
+#endif /* _mysql_h */
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 4ea1a77c836..e183a0ed423 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
** Common definition between mysql server & client
@@ -22,7 +21,6 @@
#ifndef _mysql_com_h
#define _mysql_com_h
-
#define NAME_LEN 64 /* Field/table name length */
#define HOSTNAME_LENGTH 60
#define USERNAME_LENGTH 16
@@ -33,16 +31,17 @@
#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
#define MYSQL_NAMEDPIPE "MySQL"
-#define MYSQL_SERVICENAME "MySql"
+#define MYSQL_SERVICENAME "MySQL"
#endif /* __WIN__ */
-enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
- COM_FIELD_LIST,COM_CREATE_DB,COM_DROP_DB,COM_REFRESH,
- COM_SHUTDOWN,COM_STATISTICS,
- COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL,
- COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT,
- COM_CHANGE_USER, COM_BINLOG_DUMP,
- COM_TABLE_DUMP, COM_CONNECT_OUT};
+enum enum_server_command {
+ COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST,
+ COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS,
+ COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING,
+ COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP,
+ COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE,
+ COM_END /* Must be last! */
+};
#define NOT_NULL_FLAG 1 /* Field can't be NULL */
#define PRI_KEY_FLAG 2 /* Field is part of a primary key */
@@ -77,6 +76,12 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
#define REFRESH_READ_LOCK 16384 /* Lock tables for read */
#define REFRESH_FAST 32768 /* Intern flag */
+/* RESET (remove all queries) from query cache */
+#define REFRESH_QUERY_CACHE 65536
+#define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */
+#define REFRESH_DES_KEY_FILE 0x40000L
+#define REFRESH_USER_RESOURCES 0x80000L
+
#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
#define CLIENT_LONG_FLAG 4 /* Get all column flags */
@@ -99,39 +104,37 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
#define NET_WRITE_TIMEOUT 60 /* Timeout on write */
#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */
-#ifndef Vio_defined
-#define Vio_defined
-#ifdef HAVE_VIO
-class Vio; /* Fill Vio class in C++ */
-#else
struct st_vio; /* Only C */
typedef struct st_vio Vio;
-#endif
-#endif
#define MAX_CHAR_WIDTH 255 /* Max length for a CHAR colum */
#define MAX_BLOB_WIDTH 8192 /* Default width for blob */
typedef struct st_net {
Vio* vio;
+ unsigned char *buff,*buff_end,*write_pos,*read_pos;
my_socket fd; /* For Perl DBI/dbd */
+ unsigned long max_packet,max_packet_size;
+ unsigned int last_errno,pkt_nr,compress_pkt_nr;
+ unsigned int write_timeout, read_timeout, retry_count;
int fcntl;
- unsigned char *buff,*buff_end,*write_pos,*read_pos;
char last_error[MYSQL_ERRMSG_SIZE];
- unsigned int last_errno,max_packet,timeout,pkt_nr;
unsigned char error;
my_bool return_errno,compress;
- my_bool no_send_ok; /* needed if we are doing several
- queries in one command ( as in LOAD TABLE ... FROM MASTER ),
- and do not want to confuse the client with OK at the wrong time
- */
+ /*
+ The following variable is set if we are doing several queries in one
+ command ( as in LOAD TABLE ... FROM MASTER ),
+ and do not want to confuse the client with OK at the wrong time
+ */
unsigned long remain_in_buf,length, buf_length, where_b;
unsigned int *return_status;
unsigned char reading_or_writing;
char save_char;
+ my_bool no_send_ok;
+ gptr query_cache_query;
} NET;
-#define packet_error ((unsigned int) -1)
+#define packet_error (~(unsigned long) 0)
enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY,
FIELD_TYPE_SHORT, FIELD_TYPE_LONG,
@@ -148,18 +151,21 @@ enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY,
FIELD_TYPE_LONG_BLOB=251,
FIELD_TYPE_BLOB=252,
FIELD_TYPE_VAR_STRING=253,
- FIELD_TYPE_STRING=254
+ FIELD_TYPE_STRING=254,
+ FIELD_TYPE_GEOMETRY=255
};
#define FIELD_TYPE_CHAR FIELD_TYPE_TINY /* For compability */
#define FIELD_TYPE_INTERVAL FIELD_TYPE_ENUM /* For compability */
-extern unsigned long max_allowed_packet;
-extern unsigned long net_buffer_length;
-
#define net_new_transaction(net) ((net)->pkt_nr=0)
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int my_net_init(NET *net, Vio* vio);
+void my_net_local_init(NET *net);
void net_end(NET *net);
void net_clear(NET *net);
int net_flush(NET *net);
@@ -167,13 +173,22 @@ int my_net_write(NET *net,const char *packet,unsigned long len);
int net_write_command(NET *net,unsigned char command,const char *packet,
unsigned long len);
int net_real_write(NET *net,const char *packet,unsigned long len);
-unsigned int my_net_read(NET *net);
+unsigned long my_net_read(NET *net);
+
+/* The following function is not meant for normal usage */
+struct sockaddr;
+int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
+ unsigned int timeout);
struct rand_struct {
unsigned long seed1,seed2,max_value;
double max_value_dbl;
};
+#ifdef __cplusplus
+}
+#endif
+
/* The following is for user defined functions */
enum Item_result {STRING_RESULT,REAL_RESULT,INT_RESULT};
@@ -193,7 +208,7 @@ typedef struct st_udf_init
{
my_bool maybe_null; /* 1 if function can return NULL */
unsigned int decimals; /* for real functions */
- unsigned int max_length; /* For string functions */
+ unsigned long max_length; /* For string functions */
char *ptr; /* free pointer for function data */
my_bool const_item; /* 0 if result is independent of arguments */
} UDF_INIT;
@@ -207,10 +222,13 @@ typedef struct st_udf_init
#ifdef __cplusplus
extern "C" {
#endif
-
+
+extern unsigned long max_allowed_packet;
+extern unsigned long net_buffer_length;
+
void randominit(struct rand_struct *,unsigned long seed1,
unsigned long seed2);
-double rnd(struct rand_struct *);
+double my_rnd(struct rand_struct *);
void make_scrambled_password(char *to,const char *password);
void get_salt_from_password(unsigned long *res,const char *password);
void make_password_from_salt(char *to, unsigned long *hash_res);
@@ -223,9 +241,9 @@ void hash_password(unsigned long *result, const char *password);
/* Some other useful functions */
-void my_init(void);
-void load_defaults(const char *conf_file, const char **groups,
- int *argc, char ***argv);
+my_bool my_init(void);
+int load_defaults(const char *conf_file, const char **groups,
+ int *argc, char ***argv);
my_bool my_thread_init(void);
void my_thread_end(void);
diff --git a/include/mysql_embed.h b/include/mysql_embed.h
new file mode 100644
index 00000000000..bc75c3fbcb8
--- /dev/null
+++ b/include/mysql_embed.h
@@ -0,0 +1,34 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Defines that are unique to the embedded version of MySQL */
+
+#ifdef EMBEDDED_LIBRARY
+
+/* Things we don't need in the embedded version of MySQL */
+
+#undef HAVE_PSTACK /* No stacktrace */
+#undef HAVE_DLOPEN /* No udf functions */
+#undef HAVE_OPENSSL
+#undef HAVE_VIO
+#undef HAVE_ISAM
+
+#define DONT_USE_RAID
+
+#undef MYSQL_SERVER_SUFFIX
+#define MYSQL_SERVER_SUFFIX "-embedded"
+
+#endif /* EMBEDDED_LIBRARY */
diff --git a/include/mysql_version.h.in b/include/mysql_version.h.in
index 989b1a95494..41d4ce081fb 100644
--- a/include/mysql_version.h.in
+++ b/include/mysql_version.h.in
@@ -3,20 +3,27 @@
/* Version numbers for protocol & mysqld */
+#ifndef _mysql_version_h
+#define _mysql_version_h
#ifdef _CUSTOMCONFIG_
#include <custom_conf.h>
#else
#define PROTOCOL_VERSION @PROTOCOL_VERSION@
#define MYSQL_SERVER_VERSION "@VERSION@"
+#define MYSQL_BASE_VERSION "mysqld-@MYSQL_BASE_VERSION@"
+#ifndef MYSQL_SERVER_SUFFIX
#define MYSQL_SERVER_SUFFIX "@MYSQL_SERVER_SUFFIX@"
+#endif
#define FRM_VER @DOT_FRM_VERSION@
#define MYSQL_VERSION_ID @MYSQL_VERSION_ID@
#define MYSQL_PORT @MYSQL_TCP_PORT@
#define MYSQL_UNIX_ADDR "@MYSQL_UNIX_ADDR@"
#define MYSQL_CONFIG_NAME "my"
+#define MYSQL_COMPILATION_COMMENT "@COMPILATION_COMMENT@"
/* mysqld compile time options */
#ifndef MYSQL_CHARSET
#define MYSQL_CHARSET "@default_charset@"
-#endif
-#endif
+#endif /* MYSQL_CHARSET */
+#endif /* _CUSTOMCONFIG_ */
+#endif /* _mysql_version_h */
diff --git a/include/mysqld_error.h b/include/mysqld_error.h
index f0fb11c1832..acc9b5961c6 100644
--- a/include/mysqld_error.h
+++ b/include/mysqld_error.h
@@ -234,4 +234,25 @@
#define ER_CANNOT_ADD_FOREIGN 1215
#define ER_NO_REFERENCED_ROW 1216
#define ER_ROW_IS_REFERENCED 1217
-#define ER_ERROR_MESSAGES 218
+#define ER_CONNECT_TO_MASTER 1218
+#define ER_QUERY_ON_MASTER 1219
+#define ER_ERROR_WHEN_EXECUTING_COMMAND 1220
+#define ER_WRONG_USAGE 1221
+#define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1222
+#define ER_CANT_UPDATE_WITH_READLOCK 1223
+#define ER_MIXING_NOT_ALLOWED 1224
+#define ER_DUP_ARGUMENT 1225
+#define ER_USER_LIMIT_REACHED 1226
+#define ER_SPECIFIC_ACCESS_DENIED_ERROR 1227
+#define ER_LOCAL_VARIABLE 1228
+#define ER_GLOBAL_VARIABLE 1229
+#define ER_NO_DEFAULT 1230
+#define ER_WRONG_VALUE_FOR_VAR 1231
+#define ER_WRONG_TYPE_FOR_VAR 1232
+#define ER_VAR_CANT_BE_READ 1233
+#define ER_CANT_USE_OPTION_HERE 1234
+#define ER_NOT_SUPPORTED_YET 1235
+#define ER_MASTER_FATAL_ERROR_READING_BINLOG 1236
+#define ER_SLAVE_IGNORED_TABLE 1237 /* only the slave SQL thread can be sent this */
+#define ER_INCORRECT_GLOBAL_LOCAL_VAR 1238
+#define ER_ERROR_MESSAGES 239
diff --git a/include/mysys_err.h b/include/mysys_err.h
index 2d23ead36b6..0ee89e91ee4 100644
--- a/include/mysys_err.h
+++ b/include/mysys_err.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _mysys_err_h
#define _mysys_err_h
@@ -22,7 +21,7 @@ extern "C" {
#endif
#define GLOB 0 /* Error maps */
-#define GLOBERRS 27 /* Max number of error messages in map's */
+#define GLOBERRS 28 /* Max number of error messages in map's */
#define EE(X) globerrs[ X ] /* Defines to add error to right map */
extern const char * NEAR globerrs[]; /* my_error_messages is here */
@@ -54,8 +53,25 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */
#define EE_CANT_READLINK 24
#define EE_CANT_SYMLINK 25
#define EE_REALPATH 26
+#define EE_SYNC 27
+
+ /* exit codes for all MySQL programs */
+
+#define EXIT_UNSPECIFIED_ERROR 1
+#define EXIT_UNKNOWN_OPTION 2
+#define EXIT_AMBIGUOUS_OPTION 3
+#define EXIT_NO_ARGUMENT_ALLOWED 4
+#define EXIT_ARGUMENT_REQUIRED 5
+#define EXIT_VAR_PREFIX_NOT_UNIQUE 6
+#define EXIT_UNKNOWN_VARIABLE 7
+#define EXIT_OUT_OF_MEMORY 8
+#define EXIT_UNKNOWN_SUFFIX 9
+#define EXIT_NO_PTR_TO_VARIABLE 10
+#define EXIT_CANNOT_CONNECT_TO_SERVICE 11
+
#ifdef __cplusplus
}
#endif
#endif
+
diff --git a/include/nisam.h b/include/nisam.h
index 7ce2b44ee79..e8f29991a4e 100644
--- a/include/nisam.h
+++ b/include/nisam.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file should be included when using nisam_funktions */
/* Author: Michael Widenius */
diff --git a/include/queues.h b/include/queues.h
index 66125e650ca..ac15b09719b 100644
--- a/include/queues.h
+++ b/include/queues.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Code for generell handling of priority Queues.
@@ -42,17 +41,20 @@ typedef struct st_queue {
#define queue_element(queue,index) ((queue)->root[index+1])
#define queue_end(queue) ((queue)->root[(queue)->elements])
#define queue_replaced(queue) _downheap(queue,1)
+typedef int (*queue_compare)(void *,byte *, byte *);
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
- pbool max_at_top, int (*compare)(void *,byte *, byte *),
+ pbool max_at_top, queue_compare compare,
void *first_cmp_arg);
int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
- pbool max_at_top, int (*compare)(void *,byte *, byte *),
+ pbool max_at_top, queue_compare compare,
void *first_cmp_arg);
+int resize_queue(QUEUE *queue, uint max_elements);
void delete_queue(QUEUE *queue);
void queue_insert(QUEUE *queue,byte *element);
byte *queue_remove(QUEUE *queue,uint idx);
void _downheap(QUEUE *queue,uint idx);
+void queue_fix(QUEUE *queue);
#define is_queue_inited(queue) ((queue)->root != 0)
#ifdef __cplusplus
diff --git a/include/raid.h b/include/raid.h
index 8cbd0f1a442..b5a5e665824 100644
--- a/include/raid.h
+++ b/include/raid.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Parser needs these defines always, even if USE_RAID is not defined */
#define RAID_TYPE_0 1 /* Striping */
@@ -23,17 +22,15 @@
#define RAID_DEFAULT_CHUNKS 4
#define RAID_DEFAULT_CHUNKSIZE 256*1024 /* 256kB */
+C_MODE_START
+#define my_raid_type(raid_type) raid_type_string[(int)(raid_type)]
extern const char *raid_type_string[];
+C_MODE_END
-#ifdef __cplusplus
-extern "C" {
-#endif
-const char *my_raid_type(int raid_type);
-#ifdef __cplusplus
-}
+#ifdef DONT_USE_RAID
+#undef USE_RAID
#endif
-
-#if defined(USE_RAID) && !defined(DONT_USE_RAID)
+#if defined(USE_RAID)
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
@@ -47,7 +44,7 @@ const char *my_raid_type(int raid_type);
#define my_write(A,B,C,D) my_raid_write(A,B,C,D)
#define my_pwrite(A,B,C,D,E) my_raid_pwrite(A,B,C,D,E)
#define my_pread(A,B,C,D,E) my_raid_pread(A,B,C,D,E)
-#define my_chsize(A,B,C) my_raid_chsize(A,B,C)
+#define my_chsize(A,B,C,D) my_raid_chsize(A,B,C,D)
#define my_close(A,B) my_raid_close(A,B)
#define my_tell(A,B) my_raid_tell(A,B)
#define my_seek(A,B,C,D) my_raid_seek(A,B,C,D)
@@ -88,7 +85,7 @@ extern "C" {
int my_raid_lock(File,int locktype, my_off_t start, my_off_t length,
myf MyFlags);
- int my_raid_chsize(File fd, my_off_t newlength, myf MyFlags);
+ int my_raid_chsize(File fd, my_off_t newlength, int filler, myf MyFlags);
int my_raid_close(File, myf MyFlags);
int my_raid_fstat(int Filedes, struct stat *buf, myf MyFlags);
@@ -119,7 +116,7 @@ class RaidFd {
int Write(const byte *Buffer, uint Count, myf MyFlags);
int Read(const byte *Buffer, uint Count, myf MyFlags);
int Lock(int locktype, my_off_t start, my_off_t length, myf MyFlags);
- int Chsize(File fd, my_off_t newlength, myf MyFlags);
+ int Chsize(File fd, my_off_t newlength, int filler, myf MyFlags);
int Fstat(int fd, MY_STAT *stat_area, myf MyFlags );
int Close(myf MyFlags);
static bool IsRaid(File fd);
diff --git a/include/rijndael.h b/include/rijndael.h
new file mode 100644
index 00000000000..e286c89cbdc
--- /dev/null
+++ b/include/rijndael.h
@@ -0,0 +1,42 @@
+/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ rijndael-alg-fst.h
+
+ @version 3.0 (December 2000)
+ Optimised ANSI C code for the Rijndael cipher (now AES)
+ @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ @author Paulo Barreto <paulo.barreto@terra.com.br>
+
+ This code is hereby placed in the public domain.
+ Modified by Peter Zaitsev to fit MySQL coding style.
+ */
+
+#define AES_MAXKC (256/32)
+#define AES_MAXKB (256/8)
+#define AES_MAXNR 14
+
+int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
+ int keyBits);
+int rijndaelKeySetupDec(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
+ int keyBits);
+void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
+ const uint8 pt[16], uint8 ct[16]);
+void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
+ const uint8 ct[16], uint8 pt[16]);
diff --git a/include/sha1.h b/include/sha1.h
new file mode 100644
index 00000000000..1c345469d3c
--- /dev/null
+++ b/include/sha1.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ This is the header file for code which implements the Secure
+ Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
+ April 17, 1995.
+
+ Many of the variable names in this code, especially the
+ single character names, were used because those were the names
+ used in the publication.
+
+ Please read the file sha1.c for more information.
+
+ Modified 2002 by Peter Zaitsev to better follow MySQL standards
+*/
+
+
+enum sha_result_codes
+{
+ SHA_SUCCESS = 0,
+ SHA_NULL, /* Null pointer parameter */
+ SHA_INPUT_TOO_LONG, /* input data too long */
+ SHA_STATE_ERROR /* called Input after Result */
+};
+
+#define SHA1_HASH_SIZE 20 /* Hash size in bytes */
+
+/*
+ This structure will hold context information for the SHA-1
+ hashing operation
+*/
+
+typedef struct SHA1_CONTEXT
+{
+ ulonglong Length; /* Message length in bits */
+ uint32 Intermediate_Hash[SHA1_HASH_SIZE/4]; /* Message Digest */
+ int Computed; /* Is the digest computed? */
+ int Corrupted; /* Is the message digest corrupted? */
+ int16 Message_Block_Index; /* Index into message block array */
+ uint8 Message_Block[64]; /* 512-bit message blocks */
+} SHA1_CONTEXT;
+
+/*
+ Function Prototypes
+*/
+
+C_MODE_START
+
+int sha1_reset( SHA1_CONTEXT* );
+int sha1_input( SHA1_CONTEXT*, const uint8 *, unsigned int );
+int sha1_result( SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE] );
+
+C_MODE_END
diff --git a/include/sslopt-case.h b/include/sslopt-case.h
index d995e31044e..ea23c31aa82 100644
--- a/include/sslopt-case.h
+++ b/include/sslopt-case.h
@@ -1,42 +1,29 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef HAVE_OPENSSL
- case OPT_SSL_SSL:
- opt_use_ssl = 1; /* true */
- break;
case OPT_SSL_KEY:
- opt_use_ssl = 1; /* true */
- my_free(opt_ssl_key, MYF(MY_ALLOW_ZERO_PTR));
- opt_ssl_key = my_strdup(optarg, MYF(0));
- break;
case OPT_SSL_CERT:
- opt_use_ssl = 1; /* true */
- my_free(opt_ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
- opt_ssl_cert = my_strdup(optarg, MYF(0));
- break;
case OPT_SSL_CA:
- opt_use_ssl = 1; /* true */
- my_free(opt_ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
- opt_ssl_ca = my_strdup(optarg, MYF(0));
- break;
case OPT_SSL_CAPATH:
- opt_use_ssl = 1; /* true */
- my_free(opt_ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
- opt_ssl_ca = my_strdup(optarg, MYF(0));
+ case OPT_SSL_CIPHER:
+ /*
+ Enable use of SSL if we are using any ssl option
+ One can disable SSL later by using --skip-ssl or --ssl=0
+ */
+ opt_use_ssl= 1;
break;
#endif
diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h
index 2f58f0e9265..397d8baa9d6 100644
--- a/include/sslopt-longopts.h
+++ b/include/sslopt-longopts.h
@@ -1,31 +1,41 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef HAVE_OPENSSL
-#define OPT_SSL_SSL 200
-#define OPT_SSL_KEY 201
-#define OPT_SSL_CERT 202
-#define OPT_SSL_CA 203
-#define OPT_SSL_CAPATH 204
- {"ssl", no_argument, 0, OPT_SSL_SSL},
- {"ssl-key", required_argument, 0, OPT_SSL_KEY},
- {"ssl-cert", required_argument, 0, OPT_SSL_CERT},
- {"ssl-ca", required_argument, 0, OPT_SSL_CA},
- {"ssl-capath", required_argument, 0, OPT_SSL_CAPATH},
+ {"ssl", OPT_SSL_SSL,
+ "Enable SSL for connection (automatically enabled with other flags). Disable with --skip-ssl",
+ (gptr*) &opt_use_ssl, (gptr*) &opt_use_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl)",
+ (gptr*) &opt_ssl_key, (gptr*) &opt_ssl_key, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format (implies --ssl)",
+ (gptr*) &opt_ssl_cert, (gptr*) &opt_ssl_cert, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"ssl-ca", OPT_SSL_CA,
+ "CA file in PEM format (check OpenSSL docs, implies --ssl)",
+ (gptr*) &opt_ssl_ca, (gptr*) &opt_ssl_ca, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"ssl-capath", OPT_SSL_CAPATH,
+ "CA directory (check OpenSSL docs, implies --ssl)",
+ (gptr*) &opt_ssl_capath, (gptr*) &opt_ssl_capath, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"ssl-cipher", OPT_SSL_CIPHER, "SSL cipher to use (implies --ssl)",
+ (gptr*) &opt_ssl_cipher, (gptr*) &opt_ssl_cipher, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
#endif /* HAVE_OPENSSL */
diff --git a/include/sslopt-usage.h b/include/sslopt-usage.h
deleted file mode 100644
index 406d94572b8..00000000000
--- a/include/sslopt-usage.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-#ifdef HAVE_OPENSSL
- puts("\
- --ssl Use SSL for connection (automatically set with other flags\n\
- --ssl-key X509 key in PEM format (implies --ssl)\n\
- --ssl-cert X509 cert in PEM format (implies --ssl)\n\
- --ssl-ca CA file in PEM format (check OpenSSL docs, implies --ssl)\n\
- --ssl-capath CA directory (check OpenSSL docs, implies --ssl)");
-#endif
diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h
index 597ab4d9fa6..164cf541381 100644
--- a/include/sslopt-vars.h
+++ b/include/sslopt-vars.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef HAVE_OPENSSL
static my_bool opt_use_ssl = 0;
@@ -21,4 +20,5 @@ static char *opt_ssl_key = 0;
static char *opt_ssl_cert = 0;
static char *opt_ssl_ca = 0;
static char *opt_ssl_capath = 0;
+static char *opt_ssl_cipher = 0;
#endif
diff --git a/include/t_ctype.h b/include/t_ctype.h
index f6e799828e6..3e190977e6c 100644
--- a/include/t_ctype.h
+++ b/include/t_ctype.h
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/*
Copyright (C) 1998, 1999 by Pruet Boonma, all rights reserved.
Copyright (C) 1998 by Theppitak Karoonboonyanan, all rights reserved.
@@ -121,7 +137,7 @@ enum l1_symbols {
L1_SARA_AI_MAIMUAN,
L1_SARA_AI_MAIMALAI
};
-
+
/* level 2 symbols & order */
enum l2_symbols {
L2_BLANK = TOT_LEVELS,
@@ -135,7 +151,7 @@ enum l2_symbols {
L2_TONE3,
L2_TONE4
};
-
+
/* level 3 symbols & order */
enum l3_symbols {
L3_BLANK = TOT_LEVELS,
diff --git a/include/thr_alarm.h b/include/thr_alarm.h
index 1f3fed1d29b..0dbb700b4fc 100644
--- a/include/thr_alarm.h
+++ b/include/thr_alarm.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Prototypes when using thr_alarm library functions */
@@ -39,24 +38,33 @@ extern "C" {
#define THR_SERVER_ALARM SIGALRM
#endif
-#if defined(DONT_USE_THR_ALARM)
+typedef struct st_alarm_info
+{
+ ulong next_alarm_time;
+ uint active_alarms;
+ uint max_used_alarms;
+} ALARM_INFO;
+
+void thr_alarm_info(ALARM_INFO *info);
+
+#if defined(DONT_USE_THR_ALARM) || !defined(THREAD)
#define USE_ALARM_THREAD
#undef USE_ONE_SIGNAL_HAND
-typedef struct st_thr_alarm_entry
-{
- uint crono;
-} thr_alarm_entry;
+typedef my_bool thr_alarm_t;
+typedef my_bool ALARM;
-#define thr_alarm_init(A) (A)->crono=0
-#define thr_alarm_in_use(A) (A)->crono
+#define thr_alarm_init(A) (*(A))=0
+#define thr_alarm_in_use(A) (*(A) != 0)
+#define thr_end_alarm(A)
+#define thr_alarm(A,B,C) ((*(A)=1)-1)
+/* The following should maybe be (*(A)) */
+#define thr_got_alarm(A) 0
#define init_thr_alarm(A)
#define thr_alarm_kill(A)
+#define resize_thr_alarm(N)
#define end_thr_alarm()
-#define thr_alarm(A,B) (((A)->crono=1)-1)
-#define thr_got_alarm(A) (A)->crono
-#define thr_end_alarm(A)
#else
#if defined(__WIN__)
@@ -93,10 +101,11 @@ typedef struct st_alarm {
#define thr_alarm_init(A) (*(A))=0
#define thr_alarm_in_use(A) (*(A)!= 0)
void init_thr_alarm(uint max_alarm);
-bool thr_alarm(thr_alarm_t *alarmed, uint sec, ALARM *buff);
+void resize_thr_alarm(uint max_alarms);
+my_bool thr_alarm(thr_alarm_t *alarmed, uint sec, ALARM *buff);
void thr_alarm_kill(pthread_t thread_id);
void thr_end_alarm(thr_alarm_t *alarmed);
-void end_thr_alarm(void);
+void end_thr_alarm(my_bool free_structures);
sig_handler process_alarm(int);
#ifndef thr_got_alarm
bool thr_got_alarm(thr_alarm_t *alrm);
@@ -109,4 +118,3 @@ bool thr_got_alarm(thr_alarm_t *alrm);
}
#endif /* __cplusplus */
#endif /* _thr_alarm_h */
-
diff --git a/include/thr_lock.h b/include/thr_lock.h
index 6dd59f80e64..f1bda0ce6b4 100644
--- a/include/thr_lock.h
+++ b/include/thr_lock.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* For use with thr_lock:s */
@@ -28,7 +27,7 @@ extern "C" {
struct st_thr_lock;
extern ulong locks_immediate,locks_waited ;
-
+
enum thr_lock_type { TL_IGNORE=-1,
TL_UNLOCK, /* UNLOCK ANY LOCK */
TL_READ, /* Read lock */
@@ -44,8 +43,8 @@ enum thr_lock_type { TL_IGNORE=-1,
*/
TL_WRITE_ALLOW_WRITE,
/*
- Write lock, but allow other threads to read / write.
- Used by ALTER TABLE in MySQL to mark to allow readers
+ Write lock, but allow other threads to read.
+ Used by ALTER TABLE in MySQL to allow readers
to use the table until ALTER TABLE is finished.
*/
TL_WRITE_ALLOW_READ,
@@ -108,6 +107,7 @@ void thr_unlock(THR_LOCK_DATA *data);
int thr_multi_lock(THR_LOCK_DATA **data,uint count);
void thr_multi_unlock(THR_LOCK_DATA **data,uint count);
void thr_abort_locks(THR_LOCK *lock);
+void thr_abort_locks_for_thread(THR_LOCK *lock, pthread_t thread);
void thr_print_locks(void); /* For debugging */
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data);
my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data);
diff --git a/include/violite.h b/include/violite.h
index 49df6994d53..18f862d4b77 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* Vio Lite.
@@ -25,9 +24,6 @@
#include "my_net.h" /* needed because of struct in_addr */
-#ifdef HAVE_VIO
-#include <Vio.h> /* Full VIO interface */
-#else
/* Simple vio interface in C; The functions are implemented in violite.c */
@@ -35,83 +31,146 @@
extern "C" {
#endif /* __cplusplus */
-#ifndef Vio_defined
-#define Vio_defined
-struct st_vio; /* Only C */
-typedef struct st_vio Vio;
-#endif
-
enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
-Vio* vio_new(my_socket sd,
- enum enum_vio_type type,
- my_bool localhost);
+#ifndef __WIN__
+#define HANDLE void *
+#endif
+
+Vio* vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost);
#ifdef __WIN__
-Vio* vio_new_win32pipe(HANDLE hPipe);
+Vio* vio_new_win32pipe(HANDLE hPipe);
#endif
-void vio_delete(Vio* vio);
+void vio_delete(Vio* vio);
+int vio_close(Vio* vio);
-/*
- * vio_read and vio_write should have the same semantics
- * as read(2) and write(2).
- */
-int vio_read( Vio* vio,
- gptr buf, int size);
-int vio_write( Vio* vio,
- const gptr buf,
- int size);
-/*
- * Whenever the socket is set to blocking mode or not.
- */
-int vio_blocking( Vio* vio,
- my_bool onoff);
-my_bool vio_is_blocking( Vio* vio);
-/*
- * setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible.
- */
- int vio_fastsend( Vio* vio);
-/*
- * setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible.
- */
-int vio_keepalive( Vio* vio,
- my_bool onoff);
-/*
- * Whenever we should retry the last read/write operation.
- */
-my_bool vio_should_retry( Vio* vio);
-/*
- * When the workday is over...
- */
-int vio_close( Vio* vio);
-/*
- * Short text description of the socket for those, who are curious..
- */
-const char* vio_description( Vio* vio);
+#ifdef EMBEDDED_LIBRARY
+void vio_reset(Vio *vio);
+#else
+void vio_reset(Vio* vio, enum enum_vio_type type,
+ my_socket sd, HANDLE hPipe, my_bool localhost);
+#endif
+int vio_read(Vio *vio, gptr buf, int size);
+int vio_write(Vio *vio, const gptr buf, int size);
+int vio_blocking(Vio *vio, my_bool onoff, my_bool *old_mode);
+my_bool vio_is_blocking(Vio *vio);
+/* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible */
+int vio_fastsend(Vio *vio);
+/* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible */
+int vio_keepalive(Vio *vio, my_bool onoff);
+/* Whenever we should retry the last read/write operation. */
+my_bool vio_should_retry(Vio *vio);
+/* Short text description of the socket for those, who are curious.. */
+const char* vio_description(Vio *vio);
/* Return the type of the connection */
- enum enum_vio_type vio_type(Vio* vio);
-
+enum enum_vio_type vio_type(Vio* vio);
/* Return last error number */
-int vio_errno(Vio *vio);
-
+int vio_errno(Vio*vio);
/* Get socket number */
-my_socket vio_fd(Vio *vio);
-
-/*
- * Remote peer's address and name in text form.
- */
-my_bool vio_peer_addr(Vio * vio, char *buf);
-
+my_socket vio_fd(Vio*vio);
+/* Remote peer's address and name in text form */
+my_bool vio_peer_addr(Vio* vio, char *buf, uint16 *port);
/* Remotes in_addr */
-
void vio_in_addr(Vio *vio, struct in_addr *in);
-
- /* Return 1 if there is data to be read */
my_bool vio_poll_read(Vio *vio,uint timeout);
+void vio_timeout(Vio *vio,uint timeout);
+
+#ifdef HAVE_OPENSSL
+#define HEADER_DES_LOCL_H dummy_something
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+struct st_VioSSLAcceptorFd
+{
+ SSL_CTX *ssl_context;
+ SSL_METHOD *ssl_method;
+ struct st_VioSSLAcceptorFd *session_id_context;
+};
+
+/* One copy for client */
+struct st_VioSSLConnectorFd
+{
+ SSL_CTX *ssl_context;
+ /* function pointers which are only once for SSL client */
+ SSL_METHOD *ssl_method;
+};
+
+int sslaccept(struct st_VioSSLAcceptorFd*, Vio *, long timeout);
+int sslconnect(struct st_VioSSLConnectorFd*, Vio *, long timeout);
+
+struct st_VioSSLConnectorFd
+*new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
+ const char *ca_file, const char *ca_path,
+ const char *cipher);
+struct st_VioSSLAcceptorFd
+*new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
+ const char *ca_file,const char *ca_path,
+ const char *cipher);
+Vio *new_VioSSL(struct st_VioSSLAcceptorFd *fd, Vio *sd, int state);
+#endif
#ifdef __cplusplus
}
#endif
+
+#if defined(HAVE_VIO) && !defined(DONT_MAP_VIO)
+#define vio_delete(vio) (vio)->viodelete(vio)
+#define vio_errno(vio) (vio)->vioerrno(vio)
+#define vio_read(vio, buf, size) (vio)->read(vio,buf,size)
+#define vio_write(vio, buf, size) (vio)->write(vio, buf, size)
+#define vio_blocking(vio, set_blocking_mode, old_mode)\
+ (vio)->vioblocking(vio, set_blocking_mode, old_mode)
+#define vio_is_blocking(vio) (vio)->is_blocking(vio)
+#define vio_fastsend(vio) (vio)->fastsend(vio)
+#define vio_keepalive(vio, set_keep_alive) (vio)->viokeepalive(vio, set_keep_alive)
+#define vio_should_retry(vio) (vio)->should_retry(vio)
+#define vio_close(vio) ((vio)->vioclose)(vio)
+#define vio_peer_addr(vio, buf, prt) (vio)->peer_addr(vio, buf, prt)
+#define vio_in_addr(vio, in) (vio)->in_addr(vio, in)
+#define vio_timeout(vio, seconds) (vio)->timeout(vio, seconds)
+#endif /* defined(HAVE_VIO) && !defined(DONT_MAP_VIO) */
+
+/* This enumerator is used in parser - should be always visible */
+enum SSL_type
+{
+ SSL_TYPE_NOT_SPECIFIED= -1,
+ SSL_TYPE_NONE,
+ SSL_TYPE_ANY,
+ SSL_TYPE_X509,
+ SSL_TYPE_SPECIFIED
+};
+
+#ifndef EMBEDDED_LIBRARY
+/* This structure is for every connection on both sides */
+struct st_vio
+{
+ my_socket sd; /* my_socket - real or imaginary */
+ HANDLE hPipe;
+ my_bool localhost; /* Are we from localhost? */
+ int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
+ struct sockaddr_in local; /* Local internet address */
+ struct sockaddr_in remote; /* Remote internet address */
+ enum enum_vio_type type; /* Type of connection */
+ char desc[30]; /* String description */
+#ifdef HAVE_VIO
+ /* function pointers. They are similar for socket/SSL/whatever */
+ void (*viodelete)(Vio*);
+ int (*vioerrno)(Vio*);
+ int (*read)(Vio*, gptr, int);
+ int (*write)(Vio*, gptr, int);
+ int (*vioblocking)(Vio*, my_bool, my_bool *);
+ my_bool (*is_blocking)(Vio*);
+ int (*viokeepalive)(Vio*, my_bool);
+ int (*fastsend)(Vio*);
+ my_bool (*peer_addr)(Vio*, char *, uint16*);
+ void (*in_addr)(Vio*, struct in_addr*);
+ my_bool (*should_retry)(Vio*);
+ int (*vioclose)(Vio*);
+ void (*timeout)(Vio*, unsigned int timeout);
+ void *ssl_arg;
#endif /* HAVE_VIO */
+};
+#endif /* EMBEDDED_LIBRARY */
#endif /* vio_violite_h_ */
diff --git a/innobase/btr/Makefile.am b/innobase/btr/Makefile.am
index 6e3dd4fb007..ed61facb695 100644
--- a/innobase/btr/Makefile.am
+++ b/innobase/btr/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libbtr.a
+noinst_LIBRARIES = libbtr.a
libbtr_a_SOURCES = btr0btr.c btr0cur.c btr0pcur.c btr0sea.c
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c
index 32750201c8e..1af9336ce72 100644
--- a/innobase/btr/btr0btr.c
+++ b/innobase/btr/btr0btr.c
@@ -22,6 +22,25 @@ Created 6/2/1994 Heikki Tuuri
#include "ibuf0ibuf.h"
/*
+Latching strategy of the InnoDB B-tree
+--------------------------------------
+A tree latch protects all non-leaf nodes of the tree. Each node of a tree
+also has a latch of its own.
+
+A B-tree operation normally first acquires an S-latch on the tree. It
+searches down the tree and releases the tree latch when it has the
+leaf node latch. To save CPU time we do not acquire any latch on
+non-leaf nodes of the tree during a search, those pages are only bufferfixed.
+
+If an operation needs to restructure the tree, it acquires an X-latch on
+the tree before searching to a leaf node. If it needs, for example, to
+split a leaf,
+(1) InnoDB decides the split point in the leaf,
+(2) allocates a new page,
+(3) inserts the appropriate node pointer to the first non-leaf level,
+(4) releases the tree X-latch,
+(5) and then moves records from the leaf to the new allocated page.
+
Node pointers
-------------
Leaf pages of a B-tree contain the index records stored in the
@@ -127,9 +146,6 @@ btr_root_get(
ulint space;
ulint root_page_no;
page_t* root;
-
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_X_LOCK)
- || mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_S_LOCK));
space = dict_tree_get_space(tree);
root_page_no = dict_tree_get_page(tree);
@@ -255,6 +271,7 @@ btr_page_create(
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
page_create(page, mtr);
+ buf_block_align(page)->check_index_page_at_flush = TRUE;
btr_page_set_index_id(page, tree->id, mtr);
}
@@ -314,8 +331,6 @@ btr_page_alloc(
page_t* new_page;
ulint new_page_no;
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
- MTR_MEMO_X_LOCK));
if (tree->type & DICT_IBUF) {
return(btr_page_alloc_for_ibuf(tree, mtr));
@@ -694,6 +709,7 @@ btr_create(
/* Create a new index page on the the allocated segment page */
page = page_create(frame, mtr);
+ buf_block_align(page)->check_index_page_at_flush = TRUE;
/* Set the index id of the page */
btr_page_set_index_id(page, index_id, mtr);
@@ -806,9 +822,16 @@ btr_page_reorganize_low(
{
page_t* new_page;
ulint log_mode;
+ ulint data_size1;
+ ulint data_size2;
+ ulint max_ins_size1;
+ ulint max_ins_size2;
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
+ data_size1 = page_get_data_size(page);
+ max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1);
+
/* Write the log record */
mlog_write_initial_log_record(page, MLOG_PAGE_REORGANIZE, mtr);
@@ -828,6 +851,7 @@ btr_page_reorganize_low(
segment headers, next page-field, etc.) is preserved intact */
page_create(page, mtr);
+ buf_block_align(page)->check_index_page_at_flush = TRUE;
/* Copy the records from the temporary space to the recreated page;
do not copy the lock bits yet */
@@ -842,6 +866,19 @@ btr_page_reorganize_low(
lock_move_reorganize_page(page, new_page);
}
+ data_size2 = page_get_data_size(page);
+ max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1);
+
+ if (data_size1 != data_size2 || max_ins_size1 != max_ins_size2) {
+ buf_page_print(page);
+ buf_page_print(new_page);
+ fprintf(stderr,
+"InnoDB: Error: page old data size %lu new data size %lu\n"
+"InnoDB: Error: page old max ins size %lu new max ins size %lu\n"
+"InnoDB: Make a detailed bug report and send it to mysql@lists.mysql.com\n",
+ data_size1, data_size2, max_ins_size1, max_ins_size2);
+ }
+
buf_frame_free(new_page);
/* Restore logging mode */
@@ -868,7 +905,7 @@ btr_parse_page_reorganize(
/*======================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -900,6 +937,7 @@ btr_page_empty(
segment headers, next page-field, etc.) is preserved intact */
page_create(page, mtr);
+ buf_block_align(page)->check_index_page_at_flush = TRUE;
}
/*****************************************************************
@@ -1469,7 +1507,7 @@ btr_page_split_and_insert(
page_t* insert_page;
page_cur_t* page_cursor;
rec_t* first_rec;
- byte* buf;
+ byte* buf = 0; /* remove warning */
rec_t* move_limit;
ibool insert_will_fit;
ulint n_iterations = 0;
@@ -1647,7 +1685,7 @@ static
void
btr_level_list_remove(
/*==================*/
- dict_tree_t* tree, /* in: index tree */
+ dict_tree_t* tree __attribute__((unused)), /* in: index tree */
page_t* page, /* in: page to remove */
mtr_t* mtr) /* in: mtr */
{
@@ -1927,11 +1965,20 @@ btr_compress(
btr_page_reorganize(merge_page, mtr);
+ max_ins_size = page_get_max_insert_size(merge_page, n_recs);
+
ut_ad(page_validate(merge_page, cursor->index));
ut_ad(page_get_max_insert_size(merge_page, n_recs)
== max_ins_size_reorg);
}
+ if (data_size > max_ins_size) {
+
+ /* Add fault tolerance, though this should never happen */
+
+ return;
+ }
+
btr_search_drop_page_hash_index(page);
/* Remove the page from the level list */
@@ -2272,29 +2319,54 @@ btr_check_node_ptr(
/****************************************************************
Checks the size and number of fields in a record based on the definition of
the index. */
-static
+
ibool
btr_index_rec_validate(
/*====================*/
- /* out: TRUE if ok */
- rec_t* rec, /* in: index record */
- dict_index_t* index) /* in: index */
+ /* out: TRUE if ok */
+ rec_t* rec, /* in: index record */
+ dict_index_t* index, /* in: index */
+ ibool dump_on_error) /* in: TRUE if the function
+ should print hex dump of record
+ and page on error */
{
dtype_t* type;
byte* data;
ulint len;
ulint n;
ulint i;
+ page_t* page;
char err_buf[1000];
+
+ page = buf_frame_align(rec);
+ if (index->type & DICT_UNIVERSAL) {
+ /* The insert buffer index tree can contain records from any
+ other index: we cannot check the number of fields or
+ their length */
+
+ return(TRUE);
+ }
+
n = dict_index_get_n_fields(index);
if (rec_get_n_fields(rec) != n) {
- fprintf(stderr, "Record has %lu fields, should have %lu\n",
- rec_get_n_fields(rec), n);
+ fprintf(stderr,
+"InnoDB: Record in index %s in table %s, page %lu, at offset %lu\n"
+"InnoDB: has %lu fields, should have %lu\n",
+ index->name, index->table_name,
+ buf_frame_get_page_no(page), (ulint)(rec - page),
+ rec_get_n_fields(rec), n);
+
+ if (!dump_on_error) {
+
+ return(FALSE);
+ }
+
+ buf_page_print(page);
rec_sprintf(err_buf, 900, rec);
- fprintf(stderr, "InnoDB: record %s\n", err_buf);
+ fprintf(stderr, "InnoDB: corrupt record %s\n", err_buf);
return(FALSE);
}
@@ -2304,14 +2376,33 @@ btr_index_rec_validate(
type = dict_index_get_nth_type(index, i);
- if (len != UNIV_SQL_NULL && dtype_is_fixed_size(type)
- && len != dtype_get_fixed_size(type)) {
+ if ((dict_index_get_nth_field(index, i)->prefix_len == 0
+ && len != UNIV_SQL_NULL && dtype_is_fixed_size(type)
+ && len != dtype_get_fixed_size(type))
+ ||
+ (dict_index_get_nth_field(index, i)->prefix_len > 0
+ && len != UNIV_SQL_NULL && dtype_is_fixed_size(type)
+ && len !=
+ dict_index_get_nth_field(index, i)->prefix_len)) {
+
fprintf(stderr,
- "Record field %lu len is %lu, should be %lu\n",
+"InnoDB: Record in index %s in table %s, page %lu, at offset %lu\n"
+"InnoDB: field %lu len is %lu, should be %lu\n",
+ index->name, index->table_name,
+ buf_frame_get_page_no(page),
+ (ulint)(rec - page),
i, len, dtype_get_fixed_size(type));
+ if (!dump_on_error) {
+
+ return(FALSE);
+ }
+
+ buf_page_print(page);
+
rec_sprintf(err_buf, 900, rec);
- fprintf(stderr, "InnoDB: record %s\n", err_buf);
+ fprintf(stderr,
+ "InnoDB: corrupt record %s\n", err_buf);
return(FALSE);
}
@@ -2342,12 +2433,13 @@ btr_index_page_validate(
rec = (&cur)->rec;
if (page_cur_is_after_last(&cur)) {
+
break;
}
- if (!btr_index_rec_validate(rec, index)) {
+ if (!btr_index_rec_validate(rec, index, TRUE)) {
- ret = FALSE;
+ return(FALSE);
}
page_cur_move_to_next(&cur);
@@ -2368,7 +2460,7 @@ btr_validate_level(
{
ulint space;
page_t* page;
- page_t* right_page;
+ page_t* right_page = 0; /* remove warning */
page_t* father_page;
page_t* right_father_page;
rec_t* node_ptr;
@@ -2404,25 +2496,26 @@ btr_validate_level(
index = UT_LIST_GET_FIRST(tree->tree_indexes);
- /* Now we are on the desired level */
+ /* Now we are on the desired level. Loop through the pages on that
+ level. */
loop:
mtr_x_lock(dict_tree_get_lock(tree), &mtr);
/* Check ordering etc. of records */
if (!page_validate(page, index)) {
- fprintf(stderr, "Error in page %lu in index %s\n",
- buf_frame_get_page_no(page), index->name);
+ fprintf(stderr,
+"InnoDB: Error in page %lu in index %s table %s, index tree level %lu\n",
+ buf_frame_get_page_no(page), index->name,
+ index->table_name, level);
ret = FALSE;
- }
+ } else if (level == 0) {
+ /* We are on level 0. Check that the records have the right
+ number of fields, and field lengths are right. */
- if (level == 0) {
if (!btr_index_page_validate(page, index)) {
- fprintf(stderr,
- "Error in page %lu in index %s, level %lu\n",
- buf_frame_get_page_no(page), index->name,
- level);
+
ret = FALSE;
}
}
@@ -2445,14 +2538,17 @@ loop:
UT_LIST_GET_FIRST(tree->tree_indexes)) >= 0) {
fprintf(stderr,
- "InnoDB: Error on pages %lu and %lu in index %s\n",
+ "InnoDB: Error on pages %lu and %lu in index %s table %s\n",
buf_frame_get_page_no(page),
right_page_no,
- index->name);
+ index->name, index->table_name);
fprintf(stderr,
"InnoDB: records in wrong order on adjacent pages\n");
+ buf_page_print(page);
+ buf_page_print(right_page);
+
rec_sprintf(err_buf, 900,
page_rec_get_prev(page_get_supremum_rec(page)));
fprintf(stderr, "InnoDB: record %s\n", err_buf);
@@ -2475,6 +2571,7 @@ loop:
/* Check father node pointers */
node_ptr = btr_page_get_father_node_ptr(tree, page, &mtr);
+ father_page = buf_frame_align(node_ptr);
if (btr_node_ptr_get_child_page_no(node_ptr) !=
buf_frame_get_page_no(page)
@@ -2482,13 +2579,16 @@ loop:
page_rec_get_prev(page_get_supremum_rec(page)),
&mtr)) {
fprintf(stderr,
- "InnoDB: Error on page %lu in index %s\n",
+ "InnoDB: Error on page %lu in index %s table %s\n",
buf_frame_get_page_no(page),
- index->name);
+ index->name, index->table_name);
fprintf(stderr,
"InnoDB: node pointer to the page is wrong\n");
+ buf_page_print(father_page);
+ buf_page_print(page);
+
rec_sprintf(err_buf, 900, node_ptr);
fprintf(stderr, "InnoDB: node ptr %s\n", err_buf);
@@ -2509,8 +2609,6 @@ loop:
goto node_ptr_fails;
}
- father_page = buf_frame_align(node_ptr);
-
if (btr_page_get_level(page, &mtr) > 0) {
heap = mem_heap_create(256);
@@ -2524,9 +2622,12 @@ loop:
if (cmp_dtuple_rec(node_ptr_tuple, node_ptr) != 0) {
fprintf(stderr,
- "InnoDB: Error on page %lu in index %s\n",
+ "InnoDB: Error on page %lu in index %s table %s\n",
buf_frame_get_page_no(page),
- index->name);
+ index->name, index->table_name);
+
+ buf_page_print(father_page);
+ buf_page_print(page);
fprintf(stderr,
"InnoDB: Error: node ptrs differ on levels > 0\n");
@@ -2576,9 +2677,13 @@ loop:
"InnoDB: node pointer to the right page is wrong\n");
fprintf(stderr,
- "InnoDB: Error on page %lu in index %s\n",
+ "InnoDB: Error on page %lu in index %s table %s\n",
buf_frame_get_page_no(page),
- index->name);
+ index->name, index->table_name);
+
+ buf_page_print(father_page);
+ buf_page_print(page);
+ buf_page_print(right_page);
}
} else {
right_father_page = buf_frame_align(
@@ -2592,9 +2697,14 @@ loop:
"InnoDB: node pointer 2 to the right page is wrong\n");
fprintf(stderr,
- "InnoDB: Error on page %lu in index %s\n",
+ "InnoDB: Error on page %lu in index %s table %s\n",
buf_frame_get_page_no(page),
- index->name);
+ index->name, index->table_name);
+
+ buf_page_print(father_page);
+ buf_page_print(right_father_page);
+ buf_page_print(page);
+ buf_page_print(right_page);
}
if (buf_frame_get_page_no(right_father_page)
@@ -2605,9 +2715,14 @@ loop:
"InnoDB: node pointer 3 to the right page is wrong\n");
fprintf(stderr,
- "InnoDB: Error on page %lu in index %s\n",
+ "InnoDB: Error on page %lu in index %s table %s\n",
buf_frame_get_page_no(page),
- index->name);
+ index->name, index->table_name);
+
+ buf_page_print(father_page);
+ buf_page_print(right_father_page);
+ buf_page_print(page);
+ buf_page_print(right_page);
}
}
}
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c
index 420de3c8f77..d506c5a91a7 100644
--- a/innobase/btr/btr0cur.c
+++ b/innobase/btr/btr0cur.c
@@ -110,7 +110,7 @@ static
void
btr_cur_latch_leaves(
/*=================*/
- dict_tree_t* tree, /* in: index tree */
+ dict_tree_t* tree __attribute__((unused)), /* in: index tree */
page_t* page, /* in: leaf page where the search
converged */
ulint space, /* in: space id */
@@ -121,16 +121,19 @@ btr_cur_latch_leaves(
{
ulint left_page_no;
ulint right_page_no;
-
+ page_t* get_page;
+
ut_ad(tree && page && mtr);
if (latch_mode == BTR_SEARCH_LEAF) {
- btr_page_get(space, page_no, RW_S_LATCH, mtr);
+ get_page = btr_page_get(space, page_no, RW_S_LATCH, mtr);
+ buf_block_align(get_page)->check_index_page_at_flush = TRUE;
} else if (latch_mode == BTR_MODIFY_LEAF) {
- btr_page_get(space, page_no, RW_X_LATCH, mtr);
+ get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr);
+ buf_block_align(get_page)->check_index_page_at_flush = TRUE;
} else if (latch_mode == BTR_MODIFY_TREE) {
@@ -138,15 +141,22 @@ btr_cur_latch_leaves(
left_page_no = btr_page_get_prev(page, mtr);
if (left_page_no != FIL_NULL) {
- btr_page_get(space, left_page_no, RW_X_LATCH, mtr);
+ get_page = btr_page_get(space, left_page_no,
+ RW_X_LATCH, mtr);
+ buf_block_align(get_page)->check_index_page_at_flush =
+ TRUE;
}
- btr_page_get(space, page_no, RW_X_LATCH, mtr);
+ get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr);
+ buf_block_align(get_page)->check_index_page_at_flush = TRUE;
right_page_no = btr_page_get_next(page, mtr);
if (right_page_no != FIL_NULL) {
- btr_page_get(space, right_page_no, RW_X_LATCH, mtr);
+ get_page = btr_page_get(space, right_page_no,
+ RW_X_LATCH, mtr);
+ buf_block_align(get_page)->check_index_page_at_flush =
+ TRUE;
}
} else if (latch_mode == BTR_SEARCH_PREV) {
@@ -157,9 +167,12 @@ btr_cur_latch_leaves(
if (left_page_no != FIL_NULL) {
cursor->left_page = btr_page_get(space, left_page_no,
RW_S_LATCH, mtr);
+ buf_block_align(
+ cursor->left_page)->check_index_page_at_flush = TRUE;
}
- btr_page_get(space, page_no, RW_S_LATCH, mtr);
+ get_page = btr_page_get(space, page_no, RW_S_LATCH, mtr);
+ buf_block_align(get_page)->check_index_page_at_flush = TRUE;
} else if (latch_mode == BTR_MODIFY_PREV) {
@@ -169,9 +182,12 @@ btr_cur_latch_leaves(
if (left_page_no != FIL_NULL) {
cursor->left_page = btr_page_get(space, left_page_no,
RW_X_LATCH, mtr);
+ buf_block_align(
+ cursor->left_page)->check_index_page_at_flush = TRUE;
}
- btr_page_get(space, page_no, RW_X_LATCH, mtr);
+ get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr);
+ buf_block_align(get_page)->check_index_page_at_flush = TRUE;
} else {
ut_error;
}
@@ -232,7 +248,7 @@ btr_cur_search_to_nth_level(
ulint buf_mode;
ulint estimate;
ulint ignore_sec_unique;
- ulint root_height;
+ ulint root_height = 0; /* remove warning */
#ifdef BTR_CUR_ADAPT
btr_search_t* info;
#endif
@@ -274,6 +290,7 @@ btr_cur_search_to_nth_level(
if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED
&& latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ
&& !estimate
+ && mode != PAGE_CUR_LE_OR_EXTENDS
&& btr_search_guess_on_hash(index, info, tuple, mode,
latch_mode, cursor,
has_search_latch, mtr)) {
@@ -334,12 +351,18 @@ btr_cur_search_to_nth_level(
rw_latch = RW_NO_LATCH;
buf_mode = BUF_GET;
+ /* We use these modified search modes on non-leaf levels of the
+ B-tree. These let us end up in the right B-tree leaf. In that leaf
+ we use the original search mode. */
+
if (mode == PAGE_CUR_GE) {
page_mode = PAGE_CUR_L;
} else if (mode == PAGE_CUR_G) {
page_mode = PAGE_CUR_LE;
} else if (mode == PAGE_CUR_LE) {
page_mode = PAGE_CUR_LE;
+ } else if (mode == PAGE_CUR_LE_OR_EXTENDS) {
+ page_mode = PAGE_CUR_LE_OR_EXTENDS;
} else {
ut_ad(mode == PAGE_CUR_L);
page_mode = PAGE_CUR_L;
@@ -390,6 +413,8 @@ retry_page_get:
goto retry_page_get;
}
+
+ buf_block_align(page)->check_index_page_at_flush = TRUE;
#ifdef UNIV_SYNC_DEBUG
if (rw_latch != RW_NO_LATCH) {
@@ -506,7 +531,7 @@ btr_cur_open_at_index_side(
ulint page_no;
ulint space;
ulint height;
- ulint root_height;
+ ulint root_height = 0; /* remove warning */
rec_t* node_ptr;
ulint estimate;
ulint savepoint;
@@ -543,6 +568,8 @@ btr_cur_open_at_index_side(
ut_ad(0 == ut_dulint_cmp(tree->id,
btr_page_get_index_id(page)));
+ buf_block_align(page)->check_index_page_at_flush = TRUE;
+
if (height == ULINT_UNDEFINED) {
/* We are in the root node */
@@ -837,7 +864,7 @@ btr_cur_optimistic_insert(
if (!dtuple_check_typed_no_assert(entry)) {
fprintf(stderr,
-"InnoDB: Error in a tuple to insert into table %lu index %s\n",
+"InnoDB: Error in a tuple to insert into table %s index %s\n",
index->table_name, index->name);
}
@@ -1080,6 +1107,10 @@ btr_cur_pessimistic_insert(
if (big_rec_vec == NULL) {
+ if (n_extents > 0) {
+ fil_space_release_free_extents(index->space,
+ n_extents);
+ }
return(DB_TOO_BIG_RECORD);
}
}
@@ -1115,7 +1146,6 @@ btr_cur_pessimistic_insert(
}
/*==================== B-TREE UPDATE =========================*/
-/* Only clustered index records are modified using these functions */
/*****************************************************************
For an update, checks the locks and does the undo logging. */
@@ -1139,12 +1169,16 @@ btr_cur_upd_lock_and_undo(
ut_ad(cursor && update && thr && roll_ptr);
- /* Only clustered index records are updated using this function */
- ut_ad((cursor->index)->type & DICT_CLUSTERED);
-
rec = btr_cur_get_rec(cursor);
index = cursor->index;
+ if (!(index->type & DICT_CLUSTERED)) {
+ /* We do undo logging only when we update a clustered index
+ record */
+ return(lock_sec_rec_modify_check_and_lock(flags, rec, index,
+ thr));
+ }
+
/* Check if we have to wait for a lock: enqueue an explicit lock
request if yes */
@@ -1191,6 +1225,13 @@ btr_cur_update_in_place_log(
mach_write_to_1(log_ptr, flags);
log_ptr++;
+ /* The code below assumes index is a clustered index: change index to
+ the clustered index if we are updating a secondary index record (or we
+ could as well skip writing the sys col values to the log in this case
+ because they are not needed for a secondary index record update) */
+
+ index = dict_table_get_first_index(index->table);
+
log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr,
mtr);
mach_write_to_2(log_ptr, rec - buf_frame_align(rec));
@@ -1277,66 +1318,6 @@ btr_cur_parse_update_in_place(
}
/*****************************************************************
-Updates a secondary index record when the update causes no size
-changes in its fields. The only case when this function is currently
-called is that in a char field characters change to others which
-are identified in the collation order. */
-
-ulint
-btr_cur_update_sec_rec_in_place(
-/*============================*/
- /* out: DB_SUCCESS or error number */
- btr_cur_t* cursor, /* in: cursor on the record to update;
- cursor stays valid and positioned on the
- same record */
- upd_t* update, /* in: update vector */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr */
-{
- dict_index_t* index = cursor->index;
- dict_index_t* clust_index;
- ulint err;
- rec_t* rec;
- dulint roll_ptr = ut_dulint_zero;
- trx_t* trx = thr_get_trx(thr);
-
- /* Only secondary index records are updated using this function */
- ut_ad(0 == (index->type & DICT_CLUSTERED));
-
- rec = btr_cur_get_rec(cursor);
-
- if (btr_cur_print_record_ops && thr) {
- printf(
- "Trx with id %lu %lu going to update table %s index %s\n",
- ut_dulint_get_high(thr_get_trx(thr)->id),
- ut_dulint_get_low(thr_get_trx(thr)->id),
- index->table_name, index->name);
- rec_print(rec);
- }
-
- err = lock_sec_rec_modify_check_and_lock(0, rec, index, thr);
-
- if (err != DB_SUCCESS) {
-
- return(err);
- }
-
- /* Remove possible hash index pointer to this record */
- btr_search_update_hash_on_delete(cursor);
-
- row_upd_rec_in_place(rec, update);
-
- clust_index = dict_table_get_first_index(index->table);
-
- /* Note that roll_ptr is really just a dummy value since
- a secondary index record does not contain any sys columns */
-
- btr_cur_update_in_place_log(BTR_KEEP_SYS_FLAG, rec, clust_index,
- update, trx, roll_ptr, mtr);
- return(DB_SUCCESS);
-}
-
-/*****************************************************************
Updates a record when the update causes no size changes in its fields. */
ulint
@@ -1357,13 +1338,10 @@ btr_cur_update_in_place(
buf_block_t* block;
ulint err;
rec_t* rec;
- dulint roll_ptr;
+ dulint roll_ptr = ut_dulint_zero;
trx_t* trx;
ibool was_delete_marked;
- /* Only clustered index records are updated using this function */
- ut_ad(cursor->index->type & DICT_CLUSTERED);
-
rec = btr_cur_get_rec(cursor);
index = cursor->index;
trx = thr_get_trx(thr);
@@ -1388,7 +1366,12 @@ btr_cur_update_in_place(
block = buf_block_align(rec);
if (block->is_hashed) {
- if (row_upd_changes_ord_field_binary(NULL, index, update)) {
+ /* The function row_upd_changes_ord_field_binary works only
+ if the update vector was built for a clustered index, we must
+ NOT call it if index is secondary */
+
+ if (!(index->type & DICT_CLUSTERED)
+ || row_upd_changes_ord_field_binary(NULL, index, update)) {
/* Remove possible hash index pointer to this record */
btr_search_update_hash_on_delete(cursor);
@@ -1428,7 +1411,8 @@ btr_cur_update_in_place(
Tries to update a record on a page in an index tree. It is assumed that mtr
holds an x-latch on the page. The operation does not succeed if there is too
little space on the page or if the update would result in too empty a page,
-so that tree compression is recommended. */
+so that tree compression is recommended. We assume here that the ordering
+fields of the record do not change. */
ulint
btr_cur_optimistic_update(
@@ -1461,9 +1445,6 @@ btr_cur_optimistic_update(
mem_heap_t* heap;
ibool reorganized = FALSE;
ulint i;
-
- /* Only clustered index records are updated using this function */
- ut_ad((cursor->index)->type & DICT_CLUSTERED);
page = btr_cur_get_page(cursor);
rec = btr_cur_get_rec(cursor);
@@ -1480,10 +1461,11 @@ btr_cur_optimistic_update(
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
- if (!row_upd_changes_field_size(rec, index, update)) {
+ if (!row_upd_changes_field_size_or_external(rec, index, update)) {
- /* The simplest and most common case: the update does not
- change the size of any field */
+ /* The simplest and the most common case: the update does not
+ change the size of any field and none of the updated fields is
+ externally stored in rec or update */
return(btr_cur_update_in_place(flags, cursor, update,
cmpl_info, thr, mtr));
@@ -1512,8 +1494,8 @@ btr_cur_optimistic_update(
new_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
- row_upd_clust_index_replace_new_col_vals(new_entry, update);
-
+ row_upd_index_replace_new_col_vals_index_pos(new_entry, index, update,
+ NULL);
old_rec_size = rec_get_size(rec);
new_rec_size = rec_get_converted_size(new_entry);
@@ -1642,54 +1624,13 @@ btr_cur_pess_upd_restore_supremum(
lock_rec_reset_and_inherit_gap_locks(page_get_supremum_rec(prev_page),
rec);
}
-
-/***************************************************************
-Replaces and copies the data in the new column values stored in the
-update vector to the clustered index entry given. */
-static
-void
-btr_cur_copy_new_col_vals(
-/*======================*/
- dtuple_t* entry, /* in/out: index entry where replaced */
- upd_t* update, /* in: update vector */
- mem_heap_t* heap) /* in: heap where data is copied */
-{
- upd_field_t* upd_field;
- dfield_t* dfield;
- dfield_t* new_val;
- ulint field_no;
- byte* data;
- ulint i;
-
- dtuple_set_info_bits(entry, update->info_bits);
-
- for (i = 0; i < upd_get_n_fields(update); i++) {
-
- upd_field = upd_get_nth_field(update, i);
-
- field_no = upd_field->field_no;
-
- dfield = dtuple_get_nth_field(entry, field_no);
-
- new_val = &(upd_field->new_val);
-
- if (new_val->len == UNIV_SQL_NULL) {
- data = NULL;
- } else {
- data = mem_heap_alloc(heap, new_val->len);
-
- ut_memcpy(data, new_val->data, new_val->len);
- }
-
- dfield_set_data(dfield, data, new_val->len);
- }
-}
/*****************************************************************
Performs an update of a record on a page of a tree. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. If the
update is made on the leaf level, to avoid deadlocks, mtr must also
-own x-latches to brothers of page, if those brothers exist. */
+own x-latches to brothers of page, if those brothers exist. We assume
+here that the ordering fields of the record do not change. */
ulint
btr_cur_pessimistic_update(
@@ -1736,7 +1677,6 @@ btr_cur_pessimistic_update(
index = cursor->index;
tree = index->tree;
- ut_ad(index->type & DICT_CLUSTERED);
ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
MTR_MEMO_X_LOCK));
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
@@ -1786,8 +1726,8 @@ btr_cur_pessimistic_update(
new_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
- btr_cur_copy_new_col_vals(new_entry, update, heap);
-
+ row_upd_index_replace_new_col_vals_index_pos(new_entry, index, update,
+ heap);
if (!(flags & BTR_KEEP_SYS_FLAG)) {
row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR,
roll_ptr);
@@ -1795,21 +1735,6 @@ btr_cur_pessimistic_update(
trx->id);
}
- page_cursor = btr_cur_get_page_cur(cursor);
-
- /* Store state of explicit locks on rec on the page infimum record,
- before deleting rec. The page infimum acts as a dummy carrier of the
- locks, taking care also of lock releases, before we can move the locks
- back on the actual record. There is a special case: if we are
- inserting on the root page and the insert causes a call of
- btr_root_raise_and_insert. Therefore we cannot in the lock system
- delete the lock structs set on the root page even if the root
- page carries just node pointers. */
-
- lock_rec_store_on_page_infimum(rec);
-
- btr_search_update_hash_on_delete(cursor);
-
if (flags & BTR_NO_UNDO_LOG_FLAG) {
/* We are in a transaction rollback undoing a row
update: we must free possible externally stored fields
@@ -1830,10 +1755,6 @@ btr_cur_pessimistic_update(
ext_vect = mem_heap_alloc(heap, sizeof(ulint) * rec_get_n_fields(rec));
n_ext_vect = btr_push_update_extern_fields(ext_vect, rec, update);
- page_cur_delete_rec(page_cursor, mtr);
-
- page_cur_move_to_prev(page_cursor);
-
if ((rec_get_converted_size(new_entry) >=
page_get_free_space_of_empty() / 2)
|| (rec_get_converted_size(new_entry) >= REC_MAX_DATA_SIZE)) {
@@ -1844,10 +1765,31 @@ btr_cur_pessimistic_update(
mem_heap_free(heap);
+ err = DB_TOO_BIG_RECORD;
+
goto return_after_reservations;
}
}
+ page_cursor = btr_cur_get_page_cur(cursor);
+
+ /* Store state of explicit locks on rec on the page infimum record,
+ before deleting rec. The page infimum acts as a dummy carrier of the
+ locks, taking care also of lock releases, before we can move the locks
+ back on the actual record. There is a special case: if we are
+ inserting on the root page and the insert causes a call of
+ btr_root_raise_and_insert. Therefore we cannot in the lock system
+ delete the lock structs set on the root page even if the root
+ page carries just node pointers. */
+
+ lock_rec_store_on_page_infimum(rec);
+
+ btr_search_update_hash_on_delete(cursor);
+
+ page_cur_delete_rec(page_cursor, mtr);
+
+ page_cur_move_to_prev(page_cursor);
+
rec = btr_cur_insert_if_possible(cursor, new_entry,
&dummy_reorganized, mtr);
ut_a(rec || optim_err != DB_UNDERFLOW);
@@ -2696,7 +2638,7 @@ btr_estimate_number_of_different_key_vals(
ulint n_cols;
ulint matched_fields;
ulint matched_bytes;
- ulint* n_diff;
+ ib_longlong* n_diff;
ulint not_empty_flag = 0;
ulint total_external_size = 0;
ulint i;
@@ -2768,7 +2710,8 @@ btr_estimate_number_of_different_key_vals(
for (j = 0; j <= n_cols; j++) {
index->stat_n_diff_key_vals[j] =
- (n_diff[j] * index->stat_n_leaf_pages
+ (n_diff[j]
+ * (ib_longlong)index->stat_n_leaf_pages
+ BTR_KEY_VAL_ESTIMATE_N_PAGES - 1
+ total_external_size
+ not_empty_flag)
@@ -3137,8 +3080,9 @@ btr_store_big_rec_extern_fields(
rec_t* rec, /* in: record */
big_rec_t* big_rec_vec, /* in: vector containing fields
to be stored externally */
- mtr_t* local_mtr) /* in: mtr containing the latch to
- rec and to the tree */
+ mtr_t* local_mtr __attribute__((unused))) /* in: mtr
+ containing the latch to rec and to the
+ tree */
{
byte* data;
ulint local_len;
@@ -3156,7 +3100,7 @@ btr_store_big_rec_extern_fields(
ut_ad(mtr_memo_contains(local_mtr, dict_tree_get_lock(index->tree),
MTR_MEMO_X_LOCK));
- ut_ad(mtr_memo_contains(local_mtr, buf_block_align(data),
+ ut_ad(mtr_memo_contains(local_mtr, buf_block_align(rec),
MTR_MEMO_PAGE_X_FIX));
ut_a(index->type & DICT_CLUSTERED);
@@ -3291,7 +3235,13 @@ void
btr_free_externally_stored_field(
/*=============================*/
dict_index_t* index, /* in: index of the data, the index
- tree MUST be X-latched */
+ tree MUST be X-latched; if the tree
+ height is 1, then also the root page
+ must be X-latched! (this is relevant
+ in the case this function is called
+ from purge where 'data' is located on
+ an undo log page, not an index
+ page) */
byte* data, /* in: internally stored data
+ reference to the externally
stored part */
@@ -3299,9 +3249,9 @@ btr_free_externally_stored_field(
ibool do_not_free_inherited,/* in: TRUE if called in a
rollback and we do not want to free
inherited fields */
- mtr_t* local_mtr) /* in: mtr containing the latch to
- data an an X-latch to the index
- tree */
+ mtr_t* local_mtr __attribute__((unused))) /* in: mtr
+ containing the latch to data an an
+ X-latch to the index tree */
{
page_t* page;
page_t* rec_page;
@@ -3335,8 +3285,8 @@ btr_free_externally_stored_field(
page_no = mach_read_from_4(data + local_len
+ BTR_EXTERN_PAGE_NO);
- offset = mach_read_from_4(data + local_len + BTR_EXTERN_OFFSET);
-
+ offset = mach_read_from_4(data + local_len
+ + BTR_EXTERN_OFFSET);
extern_len = mach_read_from_4(data + local_len
+ BTR_EXTERN_LEN + 4);
diff --git a/innobase/btr/btr0pcur.c b/innobase/btr/btr0pcur.c
index 2b9dc11e683..63e7763ef87 100644
--- a/innobase/btr/btr0pcur.c
+++ b/innobase/btr/btr0pcur.c
@@ -293,10 +293,9 @@ btr_pcur_restore_position(
mem_heap_free(heap);
/* We have to store position information, modify clock value, etc.
- because the cursor may now be on a different page */
-
- btr_pcur_store_position(cursor, mtr);
+ because the cursor may now be on a different page */
+ btr_pcur_store_position(cursor, mtr);
return(FALSE);
}
@@ -360,10 +359,13 @@ btr_pcur_move_to_next_page(
ut_ad(next_page_no != FIL_NULL);
next_page = btr_page_get(space, next_page_no, cursor->latch_mode, mtr);
+ buf_block_align(next_page)->check_index_page_at_flush = TRUE;
btr_leaf_page_release(page, cursor->latch_mode, mtr);
page_cur_set_before_first(next_page, btr_pcur_get_page_cur(cursor));
+
+ page_check_dir(next_page);
}
/*************************************************************
diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c
index fd65a98cc0f..5c5ed934a9b 100644
--- a/innobase/btr/btr0sea.c
+++ b/innobase/btr/btr0sea.c
@@ -19,6 +19,9 @@ Created 2/17/1996 Heikki Tuuri
#include "btr0btr.h"
#include "ha0ha.h"
+ulint btr_search_this_is_zero = 0; /* A dummy variable to fool the
+ compiler */
+
ulint btr_search_n_succ = 0;
ulint btr_search_n_hash_fail = 0;
@@ -56,16 +59,20 @@ before hash index building is started */
/************************************************************************
Builds a hash index on a page with the given parameters. If the page already
-has a hash index with different parameters, the old hash index is removed. */
+has a hash index with different parameters, the old hash index is removed.
+If index is non-NULL, this function checks if n_fields and n_bytes are
+sensible values, and does not build a hash index if not. */
static
void
btr_search_build_page_hash_index(
/*=============================*/
- page_t* page, /* in: index page, s- or x-latched */
- ulint n_fields, /* in: hash this many full fields */
- ulint n_bytes, /* in: hash this many bytes from the next
+ dict_index_t* index, /* in: index for which to build, or NULL if
+ not known */
+ page_t* page, /* in: index page, s- or x-latched */
+ ulint n_fields,/* in: hash this many full fields */
+ ulint n_bytes,/* in: hash this many bytes from the next
field */
- ulint side); /* in: hash for searches from this side */
+ ulint side); /* in: hash for searches from this side */
/*********************************************************************
This function should be called before reserving any btr search mutex, if
@@ -173,7 +180,9 @@ btr_search_info_create(
}
/*************************************************************************
-Updates the search info of an index about hash successes. */
+Updates the search info of an index about hash successes. NOTE that info
+is NOT protected by any semaphore, to save CPU time! Do not assume its fields
+are consistent. */
static
void
btr_search_info_update_hash(
@@ -295,7 +304,9 @@ set_new_recomm:
}
/*************************************************************************
-Updates the block search info on hash successes. */
+Updates the block search info on hash successes. NOTE that info and
+block->n_hash_helps, n_fields, n_bytes, side are NOT protected by any
+semaphore, to save CPU time! Do not assume the fields are consistent. */
static
ibool
btr_search_update_block_hash_info(
@@ -425,12 +436,19 @@ btr_search_info_update_slow(
{
buf_block_t* block;
ibool build_index;
-
+ ulint* params;
+ ulint* params2;
+
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED)
&& !rw_lock_own(&btr_search_latch, RW_LOCK_EX));
block = buf_block_align(btr_cur_get_rec(cursor));
+ /* NOTE that the following two function calls do NOT protect
+ info or block->n_fields etc. with any semaphore, to save CPU time!
+ We cannot assume the fields are consistent when we return from
+ those functions! */
+
btr_search_info_update_hash(info, cursor);
build_index = btr_search_update_block_hash_info(info, block, cursor);
@@ -439,7 +457,7 @@ btr_search_info_update_slow(
btr_search_check_free_space_in_heap();
}
-
+
if (cursor->flag == BTR_CUR_HASH_FAIL) {
/* Update the hash node reference, if appropriate */
@@ -453,10 +471,30 @@ btr_search_info_update_slow(
}
if (build_index) {
- btr_search_build_page_hash_index(block->frame,
- block->n_fields,
- block->n_bytes,
- block->side);
+ /* Note that since we did not protect block->n_fields etc.
+ with any semaphore, the values can be inconsistent. We have
+ to check inside the function call that they make sense. We
+ also malloc an array and store the values there to make sure
+ the compiler does not let the function call parameters change
+ inside the called function. It might be that the compiler
+ would optimize the call just to pass pointers to block. */
+
+ params = mem_alloc(3 * sizeof(ulint));
+ params[0] = block->n_fields;
+ params[1] = block->n_bytes;
+ params[2] = block->side;
+
+ /* Make sure the compiler cannot deduce the values and do
+ optimizations */
+
+ params2 = params + btr_search_this_is_zero;
+
+ btr_search_build_page_hash_index(cursor->index,
+ block->frame,
+ params2[0],
+ params2[1],
+ params2[2]);
+ mem_free(params);
}
}
@@ -471,6 +509,13 @@ btr_search_check_guess(
/* out: TRUE if success */
btr_cur_t* cursor, /* in: guessed cursor position */
ibool can_only_compare_to_cursor_rec,
+ /* in: if we do not have a latch on the page
+ of cursor, but only a latch on
+ btr_search_latch, then ONLY the columns
+ of the record UNDER the cursor are
+ protected, not the next or previous record
+ in the chain: we cannot look at the next or
+ previous record to check our guess! */
dtuple_t* tuple, /* in: data tuple */
ulint mode, /* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
or PAGE_CUR_GE */
@@ -530,7 +575,10 @@ btr_search_check_guess(
}
if (can_only_compare_to_cursor_rec) {
- return(FALSE);
+ /* Since we could not determine if our guess is right just by
+ looking at the record under the cursor, return FALSE */
+
+ return(FALSE);
}
match = 0;
@@ -745,9 +793,15 @@ btr_search_guess_on_hash(
fold);
*/
} else {
+ /* If we only have the latch on btr_search_latch, not on the
+ page, it only protects the columns of the record the cursor
+ is positioned on. We cannot look at the next of the previous
+ record to determine if our guess for the cursor position is
+ right. */
+
success = btr_search_check_guess(cursor,
- can_only_compare_to_cursor_rec,
- tuple, mode, mtr);
+ can_only_compare_to_cursor_rec,
+ tuple, mode, mtr);
}
if (!success) {
@@ -984,16 +1038,20 @@ btr_search_drop_page_hash_when_freed(
/************************************************************************
Builds a hash index on a page with the given parameters. If the page already
-has a hash index with different parameters, the old hash index is removed. */
+has a hash index with different parameters, the old hash index is removed.
+If index is non-NULL, this function checks if n_fields and n_bytes are
+sensible values, and does not build a hash index if not. */
static
void
btr_search_build_page_hash_index(
/*=============================*/
- page_t* page, /* in: index page, s- or x-latched */
- ulint n_fields, /* in: hash this many full fields */
- ulint n_bytes, /* in: hash this many bytes from the next
+ dict_index_t* index, /* in: index for which to build, or NULL if
+ not known */
+ page_t* page, /* in: index page, s- or x-latched */
+ ulint n_fields,/* in: hash this many full fields */
+ ulint n_bytes,/* in: hash this many bytes from the next
field */
- ulint side) /* in: hash for searches from this side */
+ ulint side) /* in: hash for searches from this side */
{
hash_table_t* table;
buf_block_t* block;
@@ -1036,9 +1094,17 @@ btr_search_build_page_hash_index(
return;
}
+ /* Check that the values for hash index build are sensible */
+
if (n_fields + n_bytes == 0) {
- return;
+ return;
+ }
+
+ if (index && (dict_index_get_n_unique_in_tree(index) < n_fields
+ || (dict_index_get_n_unique_in_tree(index) == n_fields
+ && n_bytes > 0))) {
+ return;
}
/* Calculate and cache fold values and corresponding records into
@@ -1197,8 +1263,8 @@ btr_search_move_or_delete_hash_entries(
ut_a(n_fields + n_bytes > 0);
- btr_search_build_page_hash_index(new_page, n_fields, n_bytes,
- side);
+ btr_search_build_page_hash_index(NULL, new_page, n_fields,
+ n_bytes, side);
ut_a(n_fields == block->curr_n_fields);
ut_a(n_bytes == block->curr_n_bytes);
ut_a(side == block->curr_side);
@@ -1318,7 +1384,7 @@ btr_search_update_hash_on_insert(
dulint tree_id;
ulint fold;
ulint ins_fold;
- ulint next_fold;
+ ulint next_fold = 0; /* remove warning (??? bug ???) */
ulint n_fields;
ulint n_bytes;
ulint side;
diff --git a/innobase/buf/Makefile.am b/innobase/buf/Makefile.am
index b1463c2220e..3f56c8b02d7 100644
--- a/innobase/buf/Makefile.am
+++ b/innobase/buf/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libbuf.a
+noinst_LIBRARIES = libbuf.a
libbuf_a_SOURCES = buf0buf.c buf0flu.c buf0lru.c buf0rea.c
diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c
index ee8e8b91f8d..3f2476c715b 100644
--- a/innobase/buf/buf0buf.c
+++ b/innobase/buf/buf0buf.c
@@ -34,6 +34,7 @@ Created 11/5/1995 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "dict0dict.h"
#include "log0recv.h"
+#include "log0log.h"
#include "trx0undo.h"
#include "srv0srv.h"
@@ -209,12 +210,12 @@ ibool buf_debug_prints = FALSE; /* If this is set TRUE,
/************************************************************************
Calculates a page checksum which is stored to the page when it is written
-to a file. Note that we must be careful to calculate the same value
-on 32-bit and 64-bit architectures. */
+to a file. Note that we must be careful to calculate the same value on
+32-bit and 64-bit architectures. */
ulint
-buf_calc_page_checksum(
-/*===================*/
+buf_calc_page_new_checksum(
+/*=======================*/
/* out: checksum */
byte* page) /* in: buffer page */
{
@@ -222,12 +223,39 @@ buf_calc_page_checksum(
/* Since the fields FIL_PAGE_FILE_FLUSH_LSN and ..._ARCH_LOG_NO
are written outside the buffer pool to the first pages of data
- files, we have to skip them in page checksum calculation */
+ files, we have to skip them in the page checksum calculation.
+ We must also skip the field FIL_PAGE_SPACE_OR_CHKSUM where the
+ checksum is stored, and also the last 8 bytes of page because
+ there we store the old formula checksum. */
+
+ checksum = ut_fold_binary(page + FIL_PAGE_OFFSET,
+ FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
+ + ut_fold_binary(page + FIL_PAGE_DATA,
+ UNIV_PAGE_SIZE - FIL_PAGE_DATA
+ - FIL_PAGE_END_LSN_OLD_CHKSUM);
+ checksum = checksum & 0xFFFFFFFF;
+
+ return(checksum);
+}
+
+/************************************************************************
+In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
+looked at the first few bytes of the page. This calculates that old
+checksum.
+NOTE: we must first store the new formula checksum to
+FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
+because this takes that field as an input! */
+
+ulint
+buf_calc_page_old_checksum(
+/*=======================*/
+ /* out: checksum */
+ byte* page) /* in: buffer page */
+{
+ ulint checksum;
checksum = ut_fold_binary(page, FIL_PAGE_FILE_FLUSH_LSN);
- + ut_fold_binary(page + FIL_PAGE_DATA,
- UNIV_PAGE_SIZE - FIL_PAGE_DATA
- - FIL_PAGE_END_LSN);
+
checksum = checksum & 0xFFFFFFFF;
return(checksum);
@@ -243,27 +271,69 @@ buf_page_is_corrupted(
byte* read_buf) /* in: a database page */
{
ulint checksum;
+ ulint old_checksum;
+ ulint checksum_field;
+ ulint old_checksum_field;
+ dulint current_lsn;
+
+ if (mach_read_from_4(read_buf + FIL_PAGE_LSN + 4)
+ != mach_read_from_4(read_buf + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
+
+ /* Stored log sequence numbers at the start and the end
+ of page do not match */
+
+ return(TRUE);
+ }
- checksum = buf_calc_page_checksum(read_buf);
+#ifndef UNIV_HOTBACKUP
+ if (recv_lsn_checks_on && log_peek_lsn(&current_lsn)) {
+ if (ut_dulint_cmp(current_lsn,
+ mach_read_from_8(read_buf + FIL_PAGE_LSN))
+ < 0) {
+ ut_print_timestamp(stderr);
- /* Note that InnoDB initializes empty pages to zero, and
- early versions of InnoDB did not store page checksum to
- the 4 most significant bytes of the page lsn field at the
- end of a page: */
+ fprintf(stderr,
+" InnoDB: Error: page %lu log sequence number %lu %lu\n"
+"InnoDB: is in the future! Current system log sequence number %lu %lu.\n"
+"InnoDB: Your database may be corrupt.\n",
+ mach_read_from_4(read_buf + FIL_PAGE_OFFSET),
+ ut_dulint_get_high(
+ mach_read_from_8(read_buf + FIL_PAGE_LSN)),
+ ut_dulint_get_low(
+ mach_read_from_8(read_buf + FIL_PAGE_LSN)),
+ ut_dulint_get_high(current_lsn),
+ ut_dulint_get_low(current_lsn));
+ }
+ }
+#endif
+ old_checksum = buf_calc_page_old_checksum(read_buf);
+
+ old_checksum_field = mach_read_from_4(read_buf + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM);
+
+ /* There are 2 valid formulas for old_checksum_field:
+ 1. Very old versions of InnoDB only stored 8 byte lsn to the start
+ and the end of the page.
+ 2. Newer InnoDB versions store the old formula checksum there. */
- if ((mach_read_from_4(read_buf + FIL_PAGE_LSN + 4)
- != mach_read_from_4(read_buf + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN + 4))
- || (checksum != mach_read_from_4(read_buf
- + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN)
- && mach_read_from_4(read_buf + FIL_PAGE_LSN)
- != mach_read_from_4(read_buf
- + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN))) {
+ if (old_checksum_field != mach_read_from_4(read_buf + FIL_PAGE_LSN)
+ && old_checksum_field != old_checksum) {
+
return(TRUE);
}
+ checksum = buf_calc_page_new_checksum(read_buf);
+ checksum_field = mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM);
+
+ /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
+ (always equal to 0), to FIL_PAGE_SPACE_SPACE_OR_CHKSUM */
+
+ if (checksum_field != 0 && checksum_field != checksum) {
+
+ return(TRUE);
+ }
+
return(FALSE);
}
@@ -277,6 +347,7 @@ buf_page_print(
{
dict_index_t* index;
ulint checksum;
+ ulint old_checksum;
char* buf;
buf = mem_alloc(4 * UNIV_PAGE_SIZE);
@@ -291,19 +362,23 @@ buf_page_print(
mem_free(buf);
- checksum = buf_calc_page_checksum(read_buf);
+ checksum = buf_calc_page_new_checksum(read_buf);
+ old_checksum = buf_calc_page_old_checksum(read_buf);
ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Page checksum %lu stored checksum %lu\n",
- checksum, mach_read_from_4(read_buf
- + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN));
+ fprintf(stderr,
+" InnoDB: Page checksum %lu, prior-to-4.0.14-form checksum %lu\n"
+"InnoDB: stored checksum %lu, prior-to-4.0.14-form stored checksum %lu\n",
+ checksum, old_checksum,
+ mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM),
+ mach_read_from_4(read_buf + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM));
fprintf(stderr,
"InnoDB: Page lsn %lu %lu, low 4 bytes of lsn at page end %lu\n",
mach_read_from_4(read_buf + FIL_PAGE_LSN),
mach_read_from_4(read_buf + FIL_PAGE_LSN + 4),
mach_read_from_4(read_buf + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN + 4));
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4));
if (mach_read_from_2(read_buf + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE)
== TRX_UNDO_INSERT) {
fprintf(stderr,
@@ -324,13 +399,26 @@ buf_page_print(
ut_dulint_get_high(btr_page_get_index_id(read_buf)),
ut_dulint_get_low(btr_page_get_index_id(read_buf)));
- index = dict_index_find_on_id_low(
+ /* If the code is in ibbackup, dict_sys may be uninitialized,
+ i.e., NULL */
+
+ if (dict_sys != NULL) {
+
+ index = dict_index_find_on_id_low(
btr_page_get_index_id(read_buf));
- if (index) {
- fprintf(stderr, "InnoDB: and table %s index %s\n",
+ if (index) {
+ fprintf(stderr,
+ "InnoDB: and table %s index %s\n",
index->table_name,
index->name);
+ }
}
+
+ } else if (fil_page_get_type(read_buf) == FIL_PAGE_INODE) {
+ fprintf(stderr, "InnoDB: Page may be an 'inode' page\n");
+ } else if (fil_page_get_type(read_buf) == FIL_PAGE_IBUF_FREE_LIST) {
+ fprintf(stderr,
+ "InnoDB: Page may be an insert buffer free list page\n");
}
}
@@ -351,6 +439,8 @@ buf_block_init(
block->file_page_was_freed = FALSE;
+ block->check_index_page_at_flush = FALSE;
+
rw_lock_create(&(block->lock));
ut_ad(rw_lock_validate(&(block->lock)));
@@ -465,9 +555,6 @@ buf_pool_create(
block = buf_pool_get_nth_block(buf_pool, i);
- /* Wipe contents of page to eliminate a Purify warning */
- memset(block->frame, '\0', UNIV_PAGE_SIZE);
-
UT_LIST_ADD_FIRST(free, buf_pool->free, block);
}
@@ -617,6 +704,29 @@ buf_page_peek_block(
}
/************************************************************************
+Resets the check_index_page_at_flush field of a page if found in the buffer
+pool. */
+
+void
+buf_reset_check_index_page_at_flush(
+/*================================*/
+ ulint space, /* in: space id */
+ ulint offset) /* in: page number */
+{
+ buf_block_t* block;
+
+ mutex_enter_fast(&(buf_pool->mutex));
+
+ block = buf_page_hash_get(space, offset);
+
+ if (block) {
+ block->check_index_page_at_flush = FALSE;
+ }
+
+ mutex_exit(&(buf_pool->mutex));
+}
+
+/************************************************************************
Returns the current state of is_hashed of a page. FALSE if the page is
not in the pool. NOTE that this operation does not fix the page in the
pool if it is found there. */
@@ -1185,6 +1295,8 @@ buf_page_init(
block->space = space;
block->offset = offset;
+ block->check_index_page_at_flush = FALSE;
+
block->lock_hash_val = lock_rec_hash(space, offset);
block->lock_mutex = NULL;
@@ -1325,11 +1437,6 @@ buf_page_create(
ut_ad(mtr);
free_block = buf_LRU_get_free_block();
-
- /* Delete possible entries for the page from the insert buffer:
- such can exist if the page belonged to an index which was dropped */
-
- ibuf_merge_or_delete_for_page(NULL, space, offset);
mutex_enter(&(buf_pool->mutex));
@@ -1378,6 +1485,11 @@ buf_page_create(
mutex_exit(&(buf_pool->mutex));
+ /* Delete possible entries for the page from the insert buffer:
+ such can exist if the page belonged to an index which was dropped */
+
+ ibuf_merge_or_delete_for_page(NULL, space, offset);
+
/* Flush pages from the end of the LRU list if necessary */
buf_flush_free_margin();
@@ -1576,7 +1688,7 @@ buf_pool_invalidate(void)
freed = TRUE;
while (freed) {
- freed = buf_LRU_search_and_free_block(0);
+ freed = buf_LRU_search_and_free_block(100);
}
mutex_enter(&(buf_pool->mutex));
@@ -1796,6 +1908,29 @@ buf_get_n_pending_ios(void)
}
/*************************************************************************
+Returns the ratio in percents of modified pages in the buffer pool /
+database pages in the buffer pool. */
+
+ulint
+buf_get_modified_ratio_pct(void)
+/*============================*/
+{
+ ulint ratio;
+
+ mutex_enter(&(buf_pool->mutex));
+
+ ratio = (100 * UT_LIST_GET_LEN(buf_pool->flush_list))
+ / (1 + UT_LIST_GET_LEN(buf_pool->LRU)
+ + UT_LIST_GET_LEN(buf_pool->free));
+
+ /* 1 + is there to avoid division by zero */
+
+ mutex_exit(&(buf_pool->mutex));
+
+ return(ratio);
+}
+
+/*************************************************************************
Prints info of the buffer i/o. */
void
@@ -1839,8 +1974,10 @@ buf_print_io(
buf += sprintf(buf,
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
- buf_pool->n_flush[BUF_FLUSH_LRU],
- buf_pool->n_flush[BUF_FLUSH_LIST],
+ buf_pool->n_flush[BUF_FLUSH_LRU]
+ + buf_pool->init_flush[BUF_FLUSH_LRU],
+ buf_pool->n_flush[BUF_FLUSH_LIST]
+ + buf_pool->init_flush[BUF_FLUSH_LIST],
buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
current_time = time(NULL);
@@ -1867,7 +2004,7 @@ buf_print_io(
/ (buf_pool->n_page_gets - buf_pool->n_page_gets_old)));
} else {
buf += sprintf(buf,
- "No buffer pool activity since the last printout\n");
+ "No buffer pool page gets since the last printout\n");
}
buf_pool->n_page_gets_old = buf_pool->n_page_gets;
diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c
index 4c6850af078..c0999ee4841 100644
--- a/innobase/buf/buf0flu.c
+++ b/innobase/buf/buf0flu.c
@@ -15,6 +15,7 @@ Created 11/11/1995 Heikki Tuuri
#include "ut0byte.h"
#include "ut0lst.h"
+#include "page0page.h"
#include "fil0fil.h"
#include "buf0buf.h"
#include "buf0lru.h"
@@ -105,7 +106,7 @@ buf_flush_ready_for_replace(
BUF_BLOCK_FILE_PAGE and in the LRU list*/
{
ut_ad(mutex_own(&(buf_pool->mutex)));
- ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
+ ut_a(block->state == BUF_BLOCK_FILE_PAGE);
if ((ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0)
|| (block->buf_fix_count != 0)
@@ -225,6 +226,28 @@ buf_flush_buffered_writes(void)
return;
}
+ for (i = 0; i < trx_doublewrite->first_free; i++) {
+
+ block = trx_doublewrite->buf_block_arr[i];
+ ut_a(block->state == BUF_BLOCK_FILE_PAGE);
+
+ if (block->check_index_page_at_flush
+ && !page_simple_validate(block->frame)) {
+
+ buf_page_print(block->frame);
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Apparent corruption of an index page n:o %lu in space %lu\n"
+ "InnoDB: to be written to data file. We intentionally crash server\n"
+ "InnoDB: to prevent corrupt data from ending up in data\n"
+ "InnoDB: files.\n",
+ block->offset, block->space);
+
+ ut_a(0);
+ }
+ }
+
if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
len = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
} else {
@@ -338,21 +361,29 @@ buf_flush_init_for_writing(
ulint space, /* in: space id */
ulint page_no) /* in: page number */
{
- /* Write the newest modification lsn to the page */
- mach_write_to_8(page + FIL_PAGE_LSN, newest_lsn);
+ UT_NOT_USED(space);
- mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN, newest_lsn);
+ /* Write the newest modification lsn to the page header and trailer */
+ mach_write_to_8(page + FIL_PAGE_LSN, newest_lsn);
- /* Write to the page the space id and page number */
+ mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
+ newest_lsn);
+ /* Write the page number */
- mach_write_to_4(page + FIL_PAGE_SPACE, space);
mach_write_to_4(page + FIL_PAGE_OFFSET, page_no);
+ /* Store the new formula checksum */
+
+ mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
+ buf_calc_page_new_checksum(page));
+
/* We overwrite the first 4 bytes of the end lsn field to store
- a page checksum */
+ the old formula checksum. Since it depends also on the field
+ FIL_PAGE_SPACE_OR_CHKSUM, it has to be calculated after storing the
+ new formula checksum. */
- mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN,
- buf_calc_page_checksum(page));
+ mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
+ buf_calc_page_old_checksum(page));
}
/************************************************************************
@@ -375,7 +406,7 @@ buf_flush_write_block_low(
"Warning: cannot force log to disk in the log debug version!\n");
#else
/* Force the log to the disk before writing the modified block */
- log_flush_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS);
+ log_write_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS, TRUE);
#endif
buf_flush_init_for_writing(block->frame, block->newest_modification,
block->space, block->offset);
@@ -413,6 +444,8 @@ buf_flush_try_page(
block = buf_page_hash_get(space, offset);
+ ut_a(block->state == BUF_BLOCK_FILE_PAGE);
+
if (flush_type == BUF_FLUSH_LIST
&& block && buf_flush_ready_for_flush(block, flush_type)) {
@@ -506,7 +539,8 @@ buf_flush_try_page(
rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE);
if (buf_debug_prints) {
- printf("Flushing single page space %lu, page no %lu \n",
+ printf(
+ "Flushing single page space %lu, page no %lu \n",
block->space, block->offset);
}
@@ -547,15 +581,7 @@ buf_flush_try_neighbors(
low = offset;
high = offset + 1;
- } else if (flush_type == BUF_FLUSH_LIST) {
- /* Since semaphore waits require us to flush the
- doublewrite buffer to disk, it is best that the
- search area is just the page itself, to minimize
- chances for semaphore waits */
-
- low = offset;
- high = offset + 1;
- }
+ }
/* printf("Flush area: low %lu high %lu\n", low, high); */
@@ -572,13 +598,20 @@ buf_flush_try_neighbors(
if (block && flush_type == BUF_FLUSH_LRU && i != offset
&& !block->old) {
- /* We avoid flushing 'non-old' blocks in an LRU flush,
- because the flushed blocks are soon freed */
+ /* We avoid flushing 'non-old' blocks in an LRU flush,
+ because the flushed blocks are soon freed */
- continue;
+ continue;
}
- if (block && buf_flush_ready_for_flush(block, flush_type)) {
+ if (block && buf_flush_ready_for_flush(block, flush_type)
+ && (i == offset || block->buf_fix_count == 0)) {
+ /* We only try to flush those neighbors != offset
+ where the buf fix count is zero, as we then know that
+ we probably can latch the page without a semaphore
+ wait. Semaphore waits are expensive because we must
+ flush the doublewrite buffer before we start
+ waiting. */
mutex_exit(&(buf_pool->mutex));
@@ -697,7 +730,6 @@ buf_flush_batch(
page_count +=
buf_flush_try_neighbors(space, offset,
flush_type);
-
/* printf(
"Flush type %lu, page no %lu, neighb %lu\n",
flush_type, offset,
@@ -823,11 +855,19 @@ buf_flush_free_margin(void)
/*=======================*/
{
ulint n_to_flush;
+ ulint n_flushed;
n_to_flush = buf_flush_LRU_recommendation();
if (n_to_flush > 0) {
- buf_flush_batch(BUF_FLUSH_LRU, n_to_flush, ut_dulint_zero);
+ n_flushed = buf_flush_batch(BUF_FLUSH_LRU, n_to_flush,
+ ut_dulint_zero);
+ if (n_flushed == ULINT_UNDEFINED) {
+ /* There was an LRU type flush batch already running;
+ let us wait for it to end */
+
+ buf_flush_wait_batch_end(BUF_FLUSH_LRU);
+ }
}
}
diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c
index bd69dff740c..a8729efb999 100644
--- a/innobase/buf/buf0lru.c
+++ b/innobase/buf/buf0lru.c
@@ -104,11 +104,15 @@ ibool
buf_LRU_search_and_free_block(
/*==========================*/
/* out: TRUE if freed */
- ulint n_iterations) /* in: how many times this has been called
- repeatedly without result: a high value
- means that we should search farther */
+ ulint n_iterations) /* in: how many times this has been called
+ repeatedly without result: a high value means
+ that we should search farther; if value is
+ k < 10, then we only search k/10 * [number
+ of pages in the buffer pool] from the end
+ of the LRU list */
{
buf_block_t* block;
+ ulint distance = 0;
ibool freed;
mutex_enter(&(buf_pool->mutex));
@@ -145,6 +149,18 @@ buf_LRU_search_and_free_block(
}
block = UT_LIST_GET_PREV(LRU, block);
+ distance++;
+
+ if (!freed && n_iterations <= 10
+ && distance > 100 + (n_iterations * buf_pool->curr_size)
+ / 10) {
+
+ buf_pool->LRU_flush_ended = 0;
+
+ mutex_exit(&(buf_pool->mutex));
+
+ return(FALSE);
+ }
}
if (buf_pool->LRU_flush_ended > 0) {
@@ -179,7 +195,7 @@ buf_LRU_try_free_flushed_blocks(void)
mutex_exit(&(buf_pool->mutex));
- buf_LRU_search_and_free_block(0);
+ buf_LRU_search_and_free_block(1);
mutex_enter(&(buf_pool->mutex));
}
@@ -199,8 +215,8 @@ buf_LRU_get_free_block(void)
{
buf_block_t* block = NULL;
ibool freed;
- ulint n_iterations = 0;
- ibool mon_value_was;
+ ulint n_iterations = 1;
+ ibool mon_value_was = FALSE;
ibool started_monitor = FALSE;
loop:
mutex_enter(&(buf_pool->mutex));
@@ -219,20 +235,26 @@ loop:
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) {
+ if (!srv_print_innodb_monitor) {
- /* Over 80 % of the buffer pool is occupied by lock heaps
- or the adaptive hash index. This may be a memory leak! */
+ /* Over 80 % of the buffer pool is occupied by lock
+ heaps or the adaptive hash index. This may be a memory
+ leak! */
- ut_print_timestamp(stderr);
- fprintf(stderr,
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
" InnoDB: WARNING: over 4 / 5 of the buffer pool is occupied by\n"
"InnoDB: lock heaps or the adaptive hash index! Check that your\n"
-"InnoDB: transactions do not set too many row locks. Starting InnoDB\n"
-"InnoDB: Monitor to print diagnostics, including lock heap and hash index\n"
-"InnoDB: sizes.\n");
-
- srv_print_innodb_monitor = TRUE;
-
+"InnoDB: transactions do not set too many row locks.\n"
+"InnoDB: Your buffer pool size is %lu MB. Maybe you should make\n"
+"InnoDB: the buffer pool bigger?\n"
+"InnoDB: Starting the InnoDB Monitor to print diagnostics, including\n"
+"InnoDB: lock heap and hash index sizes.\n",
+ buf_pool->curr_size / (1024 * 1024 / UNIV_PAGE_SIZE));
+
+ srv_print_innodb_monitor = TRUE;
+ os_event_set(srv_lock_timeout_thread_event);
+ }
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) {
@@ -242,14 +264,6 @@ loop:
srv_print_innodb_monitor = FALSE;
}
-
- if (buf_pool->LRU_flush_ended > 0) {
- mutex_exit(&(buf_pool->mutex));
-
- buf_LRU_try_free_flushed_blocks();
-
- mutex_enter(&(buf_pool->mutex));
- }
/* If there is a block in the free list, take it */
if (UT_LIST_GET_LEN(buf_pool->free) > 0) {
@@ -307,6 +321,7 @@ loop:
mon_value_was = srv_print_innodb_monitor;
started_monitor = TRUE;
srv_print_innodb_monitor = TRUE;
+ os_event_set(srv_lock_timeout_thread_event);
}
/* No free block was found: try to flush the LRU list */
@@ -315,6 +330,20 @@ loop:
os_aio_simulated_wake_handler_threads();
+ mutex_enter(&(buf_pool->mutex));
+
+ if (buf_pool->LRU_flush_ended > 0) {
+ /* We have written pages in an LRU flush. To make the insert
+ buffer more efficient, we try to move these pages to the free
+ list. */
+
+ mutex_exit(&(buf_pool->mutex));
+
+ buf_LRU_try_free_flushed_blocks();
+ } else {
+ mutex_exit(&(buf_pool->mutex));
+ }
+
if (n_iterations > 10) {
os_thread_sleep(500000);
diff --git a/innobase/com/Makefile.am b/innobase/com/Makefile.am
index 27ae396bc6e..a3d2f8a76c6 100644
--- a/innobase/com/Makefile.am
+++ b/innobase/com/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libcom.a
+noinst_LIBRARIES = libcom.a
libcom_a_SOURCES = com0com.c com0shm.c
diff --git a/innobase/com/com0shm.c b/innobase/com/com0shm.c
index 72ab23b9be8..ed185ccdf47 100644
--- a/innobase/com/com0shm.c
+++ b/innobase/com/com0shm.c
@@ -103,7 +103,8 @@ struct com_shm_endpoint_struct{
the area currently may contain a datagram;
NOTE: automatic event */
os_event_t empty; /* this is in the signaled state if the area
- currently may be empty; NOTE: automatic event */
+ currently may be empty; NOTE: automatic
+ event */
ip_mutex_hdl_t* ip_mutex; /* handle to the interprocess mutex
protecting the shared memory */
UT_LIST_NODE_T(com_shm_endpoint_t) list; /* If the endpoint struct
@@ -793,16 +794,18 @@ com_shm_create_or_open(
ut_strcpy(buf + len, (char*)"_IBSHM_EV_NE"),
- event_ne = os_event_create_auto(buf);
+ event_ne = os_event_create(buf);
ut_ad(event_ne);
ut_strcpy(buf + len, (char*)"_IBSHM_EV_EM"),
- event_em = os_event_create_auto(buf);
+ event_em = os_event_create(buf);
ut_ad(event_em);
+ ut_a(0); /* event_ne and event_em should be auto events! */
+
com_shm_endpoint_set_shm(ep, shm);
com_shm_endpoint_set_map(ep, map);
diff --git a/innobase/configure.in b/innobase/configure.in
index 51782579720..29309a2c0a5 100644
--- a/innobase/configure.in
+++ b/innobase/configure.in
@@ -36,6 +36,7 @@ AC_PROG_RANLIB
AC_PROG_INSTALL
AC_CHECK_HEADERS(aio.h sched.h)
AC_CHECK_SIZEOF(int, 4)
+AC_CHECK_SIZEOF(long, 4)
AC_CHECK_FUNCS(sched_yield)
AC_CHECK_FUNCS(fdatasync)
#AC_CHECK_FUNCS(localtime_r) # Already checked by MySQL
@@ -85,6 +86,8 @@ else
fi
case "$target_os" in
+ lin*)
+ CFLAGS="$CFLAGS -DUNIV_LINUX";;
hpux10*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE -DUNIV_HPUX -DUNIV_HPUX10";;
hp*)
@@ -98,7 +101,7 @@ case "$target_os" in
sysv5uw7*)
# Problem when linking on SCO
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
- openbsd*)
+ openbsd*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
esac
@@ -107,14 +110,14 @@ case "$target" in
CFLAGS="$CFLAGS -DUNIV_INTEL_X86";;
esac
-AC_OUTPUT(Makefile os/Makefile ut/Makefile btr/Makefile
- buf/Makefile com/Makefile data/Makefile
- dict/Makefile dyn/Makefile
- eval/Makefile fil/Makefile fsp/Makefile fut/Makefile
- ha/Makefile ibuf/Makefile include/Makefile
- lock/Makefile log/Makefile
- mach/Makefile mem/Makefile mtr/Makefile odbc/Makefile
- page/Makefile pars/Makefile que/Makefile
- read/Makefile rem/Makefile row/Makefile
- srv/Makefile sync/Makefile thr/Makefile trx/Makefile
+AC_OUTPUT(Makefile os/Makefile ut/Makefile btr/Makefile dnl
+ buf/Makefile com/Makefile data/Makefile dnl
+ dict/Makefile dyn/Makefile dnl
+ eval/Makefile fil/Makefile fsp/Makefile fut/Makefile dnl
+ ha/Makefile ibuf/Makefile include/Makefile dnl
+ lock/Makefile log/Makefile dnl
+ mach/Makefile mem/Makefile mtr/Makefile odbc/Makefile dnl
+ page/Makefile pars/Makefile que/Makefile dnl
+ read/Makefile rem/Makefile row/Makefile dnl
+ srv/Makefile sync/Makefile thr/Makefile trx/Makefile dnl
usr/Makefile)
diff --git a/innobase/data/Makefile.am b/innobase/data/Makefile.am
index 0e502708e85..eeb6f129de0 100644
--- a/innobase/data/Makefile.am
+++ b/innobase/data/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libdata.a
+noinst_LIBRARIES = libdata.a
libdata_a_SOURCES = data0data.c data0type.c
diff --git a/innobase/data/data0data.c b/innobase/data/data0data.c
index 61a02f7efd0..f2f94cc47ce 100644
--- a/innobase/data/data0data.c
+++ b/innobase/data/data0data.c
@@ -584,8 +584,7 @@ dtuple_convert_big_rec(
* sizeof(big_rec_field_t));
/* Decide which fields to shorten: the algorithm is to look for
- the longest field which does not occur in the ordering part
- of any index on the table */
+ the longest field whose type is DATA_BLOB */
n_fields = 0;
@@ -610,12 +609,9 @@ dtuple_convert_big_rec(
}
}
- /* Skip over fields which are ordering in some index */
-
- if (!is_externally_stored &&
- dict_field_get_col(
- dict_index_get_nth_field(index, i))
- ->ord_part == 0) {
+ if (!is_externally_stored
+ && dict_index_get_nth_type(index, i)->mtype
+ == DATA_BLOB) {
dfield = dtuple_get_nth_field(entry, i);
@@ -629,9 +625,13 @@ dtuple_convert_big_rec(
}
}
- if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10
- + REC_1BYTE_OFFS_LIMIT) {
+ /* We do not store externally fields which are smaller than
+ DICT_MAX_COL_PREFIX_LEN */
+ ut_a(DICT_MAX_COL_PREFIX_LEN > REC_1BYTE_OFFS_LIMIT);
+
+ if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10
+ + DICT_MAX_COL_PREFIX_LEN) {
/* Cannot shorten more */
mem_heap_free(heap);
@@ -644,13 +644,19 @@ dtuple_convert_big_rec(
drop below 128 which is the limit for the 2-byte
offset storage format in a physical record. This
we accomplish by storing 128 bytes of data in entry
- itself, and only the remaining part to big rec vec. */
+ itself, and only the remaining part to big rec vec.
+
+ We store the first bytes locally to the record. Then
+ we can calculate all ordering fields in all indexes
+ from locally stored data. */
dfield = dtuple_get_nth_field(entry, longest_i);
vector->fields[n_fields].field_no = longest_i;
+ ut_a(dfield->len > DICT_MAX_COL_PREFIX_LEN);
+
vector->fields[n_fields].len = dfield->len
- - REC_1BYTE_OFFS_LIMIT;
+ - DICT_MAX_COL_PREFIX_LEN;
vector->fields[n_fields].data = mem_heap_alloc(heap,
vector->fields[n_fields].len);
@@ -683,7 +689,7 @@ from entry with dtuple_convert_big_rec. */
void
dtuple_convert_back_big_rec(
/*========================*/
- dict_index_t* index, /* in: index */
+ dict_index_t* index __attribute__((unused)), /* in: index */
dtuple_t* entry, /* in: entry whose data was put to vector */
big_rec_t* vector) /* in, own: big rec vector; it is
freed in this function */
diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c
index 5d0ddf3e887..df430f06bcb 100644
--- a/innobase/data/data0type.c
+++ b/innobase/data/data0type.c
@@ -85,8 +85,6 @@ dtype_print(
printf("DATA_MIX_ID");
} else if (prtype == DATA_ENGLISH) {
printf("DATA_ENGLISH");
- } else if (prtype == DATA_FINNISH) {
- printf("DATA_FINNISH");
} else {
printf("prtype %lu", mtype);
}
diff --git a/innobase/dict/Makefile.am b/innobase/dict/Makefile.am
index 693048b6784..0034d2f8f1e 100644
--- a/innobase/dict/Makefile.am
+++ b/innobase/dict/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libdict.a
+noinst_LIBRARIES = libdict.a
libdict_a_SOURCES = dict0boot.c dict0crea.c dict0dict.c dict0load.c\
dict0mem.c
diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c
index 206fbe32940..0bf2ace3324 100644
--- a/innobase/dict/dict0boot.c
+++ b/innobase/dict/dict0boot.c
@@ -254,27 +254,29 @@ dict_boot(void)
/* Insert into the dictionary cache the descriptions of the basic
system tables */
/*-------------------------*/
- table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8);
-
- dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "N_COLS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "MIX_ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "MIX_LEN", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "CLUSTER_NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
+ table = dict_mem_table_create((char *) "SYS_TABLES", DICT_HDR_SPACE,8);
+
+ dict_mem_table_add_col(table, (char *) "NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "ID", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "N_COLS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "TYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "MIX_ID", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "MIX_LEN", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "CLUSTER_NAME", DATA_BINARY,
+ 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "SPACE", DATA_INT, 0, 4, 0);
table->id = DICT_TABLES_ID;
dict_table_add_to_cache(table);
dict_sys->sys_tables = table;
- index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
- DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 1);
+ index = dict_mem_index_create((char *) "SYS_TABLES", (char *)
+ "CLUST_IND",
+ DICT_HDR_SPACE,
+ DICT_UNIQUE | DICT_CLUSTERED, 1);
- dict_mem_index_add_field(index, "NAME", 0);
+ dict_mem_index_add_field(index, (char *) "NAME", 0, 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLES,
MLOG_4BYTES, &mtr);
@@ -282,51 +284,52 @@ dict_boot(void)
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- index = dict_mem_index_create("SYS_TABLES", "ID_IND", DICT_HDR_SPACE,
- DICT_UNIQUE, 1);
- dict_mem_index_add_field(index, "ID", 0);
+ index = dict_mem_index_create((char *) "SYS_TABLES",
+ (char *) "ID_IND", DICT_HDR_SPACE,
+ DICT_UNIQUE, 1);
+ dict_mem_index_add_field(index, (char *) "ID", 0, 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLE_IDS,
MLOG_4BYTES, &mtr);
index->id = DICT_TABLE_IDS_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7);
-
- dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "MTYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "PRTYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "LEN", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "PREC", DATA_INT, 0, 4, 0);
+ table = dict_mem_table_create((char *) "SYS_COLUMNS",DICT_HDR_SPACE,7);
+
+ dict_mem_table_add_col(table, (char *) "TABLE_ID", DATA_BINARY,0,0,0);
+ dict_mem_table_add_col(table, (char *) "POS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "MTYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "PRTYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "LEN", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "PREC", DATA_INT, 0, 4, 0);
table->id = DICT_COLUMNS_ID;
dict_table_add_to_cache(table);
dict_sys->sys_columns = table;
- index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
- DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 2);
+ index = dict_mem_index_create((char *) "SYS_COLUMNS",
+ (char *) "CLUST_IND", DICT_HDR_SPACE,
+ DICT_UNIQUE | DICT_CLUSTERED, 2);
- dict_mem_index_add_field(index, "TABLE_ID", 0);
- dict_mem_index_add_field(index, "POS", 0);
+ dict_mem_index_add_field(index, (char *) "TABLE_ID", 0, 0);
+ dict_mem_index_add_field(index, (char *) "POS", 0, 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_COLUMNS,
MLOG_4BYTES, &mtr);
index->id = DICT_COLUMNS_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7);
+ table = dict_mem_table_create((char *) "SYS_INDEXES",DICT_HDR_SPACE,7);
- dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "N_FIELDS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "PAGE_NO", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "TABLE_ID", DATA_BINARY, 0,0,0);
+ dict_mem_table_add_col(table, (char *) "ID", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "N_FIELDS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "TYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "SPACE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "PAGE_NO", DATA_INT, 0, 4, 0);
/* The '+ 2' below comes from the 2 system fields */
ut_ad(DICT_SYS_INDEXES_PAGE_NO_FIELD == 6 + 2);
@@ -336,34 +339,34 @@ dict_boot(void)
dict_table_add_to_cache(table);
dict_sys->sys_indexes = table;
- index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
- DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 2);
+ index = dict_mem_index_create((char *) "SYS_INDEXES",
+ (char *) "CLUST_IND", DICT_HDR_SPACE,
+ DICT_UNIQUE | DICT_CLUSTERED, 2);
- dict_mem_index_add_field(index, "TABLE_ID", 0);
- dict_mem_index_add_field(index, "ID", 0);
+ dict_mem_index_add_field(index, (char *) "TABLE_ID", 0, 0);
+ dict_mem_index_add_field(index, (char *) "ID", 0, 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_INDEXES,
MLOG_4BYTES, &mtr);
index->id = DICT_INDEXES_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3);
+ table = dict_mem_table_create((char *) "SYS_FIELDS", DICT_HDR_SPACE,3);
- dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, "COL_NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, (char *) "INDEX_ID", DATA_BINARY, 0,0,0);
+ dict_mem_table_add_col(table, (char *) "POS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, (char *) "COL_NAME", DATA_BINARY, 0,0,0);
table->id = DICT_FIELDS_ID;
dict_table_add_to_cache(table);
dict_sys->sys_fields = table;
- index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
- DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 2);
+ index = dict_mem_index_create((char *) "SYS_FIELDS",
+ (char *) "CLUST_IND", DICT_HDR_SPACE,
+ DICT_UNIQUE | DICT_CLUSTERED, 2);
- dict_mem_index_add_field(index, "INDEX_ID", 0);
- dict_mem_index_add_field(index, "POS", 0);
+ dict_mem_index_add_field(index, (char *) "INDEX_ID", 0, 0);
+ dict_mem_index_add_field(index, (char *) "POS", 0, 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_FIELDS,
MLOG_4BYTES, &mtr);
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index d981dc59036..9139e589a0a 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -337,7 +337,7 @@ dict_create_index_for_cluster_step(
for (i = 0; i < table->n_cols; i++) {
col = dict_table_get_nth_col(table, i);
- dict_mem_index_add_field(index, col->name, 0);
+ dict_mem_index_add_field(index, col->name, 0, 0);
}
(node->cluster)->index = index;
@@ -450,9 +450,17 @@ dict_create_sys_fields_tuple(
dict_field_t* field;
dfield_t* dfield;
byte* ptr;
+ ibool index_contains_column_prefix_field = FALSE;
+ ulint j;
ut_ad(index && heap);
+ for (j = 0; j < index->n_fields; j++) {
+ if (dict_index_get_nth_field(index, j)->prefix_len > 0) {
+ index_contains_column_prefix_field = TRUE;
+ }
+ }
+
field = dict_index_get_nth_field(index, i);
sys_fields = dict_sys->sys_fields;
@@ -466,11 +474,25 @@ dict_create_sys_fields_tuple(
mach_write_to_8(ptr, index->id);
dfield_set_data(dfield, ptr, 8);
- /* 1: POS ----------------------------*/
+ /* 1: POS + PREFIX LENGTH ----------------------------*/
+
dfield = dtuple_get_nth_field(entry, 1);
ptr = mem_heap_alloc(heap, 4);
- mach_write_to_4(ptr, i);
+
+ if (index_contains_column_prefix_field) {
+ /* If there are column prefix fields in the index, then
+ we store the number of the field to the 2 HIGH bytes
+ and the prefix length to the 2 low bytes, */
+
+ mach_write_to_4(ptr, (i << 16) + field->prefix_len);
+ } else {
+ /* Else we store the number of the field to the 2 LOW bytes.
+ This is to keep the storage format compatible with
+ InnoDB versions < 4.0.14. */
+
+ mach_write_to_4(ptr, i);
+ }
dfield_set_data(dfield, ptr, 4);
/* 4: COL_NAME -------------------------*/
@@ -1041,12 +1063,12 @@ dict_create_or_check_foreign_constraint_tables(void)
que_t* graph;
ulint error;
trx_t* trx;
- char* str;
+ char* str;
mutex_enter(&(dict_sys->mutex));
- table1 = dict_table_get_low("SYS_FOREIGN");
- table2 = dict_table_get_low("SYS_FOREIGN_COLS");
+ table1 = dict_table_get_low((char *) "SYS_FOREIGN");
+ table2 = dict_table_get_low((char *) "SYS_FOREIGN_COLS");
if (table1 && table2
&& UT_LIST_GET_LEN(table1->indexes) == 3
@@ -1060,20 +1082,24 @@ dict_create_or_check_foreign_constraint_tables(void)
return(DB_SUCCESS);
}
+ mutex_exit(&(dict_sys->mutex));
+
trx = trx_allocate_for_mysql();
- trx->op_info = "creating foreign key sys tables";
+ trx->op_info = (char *) "creating foreign key sys tables";
+
+ row_mysql_lock_data_dictionary(trx);
if (table1) {
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN table\n");
- row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
+ row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx);
}
if (table2) {
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN_COLS table\n");
- row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
+ row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS", trx);
}
fprintf(stderr,
@@ -1083,7 +1109,7 @@ dict_create_or_check_foreign_constraint_tables(void)
there are 2 secondary indexes on SYS_FOREIGN, and they
are defined just like below */
- str =
+ str = (char *)
"PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
"BEGIN\n"
"CREATE TABLE\n"
@@ -1122,15 +1148,17 @@ dict_create_or_check_foreign_constraint_tables(void)
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN tables\n");
- row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
- row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
+ row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx);
+ row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS", trx);
error = DB_MUST_GET_MORE_FILE_SPACE;
}
que_graph_free(graph);
- trx->op_info = "";
+ trx->op_info = (char *) "";
+
+ row_mysql_unlock_data_dictionary(trx);
trx_free_for_mysql(trx);
@@ -1139,8 +1167,6 @@ dict_create_or_check_foreign_constraint_tables(void)
"InnoDB: Foreign key constraint system tables created\n");
}
- mutex_exit(&(dict_sys->mutex));
-
return(error);
}
@@ -1166,9 +1192,10 @@ dict_create_add_foreigns_to_dictionary(
ut_ad(mutex_own(&(dict_sys->mutex)));
- if (NULL == dict_table_get_low("SYS_FOREIGN")) {
+ if (NULL == dict_table_get_low((char *) "SYS_FOREIGN")) {
fprintf(stderr,
"InnoDB: table SYS_FOREIGN not found from internal data dictionary\n");
+
return(DB_ERROR);
}
@@ -1255,6 +1282,13 @@ loop:
"InnoDB: at http://www.innodb.com/ibman.html\n");
}
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Internal error in foreign key constraint creation for table %.500s.\n"
+"See the MySQL .err log in the datadir for more information.\n", table->name);
+ mutex_exit(&dict_foreign_err_mutex);
+
return(error);
}
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index eb9610a6e73..87505656d5a 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -29,7 +29,17 @@ Created 1/8/1996 Heikki Tuuri
dict_sys_t* dict_sys = NULL; /* the dictionary system */
-rw_lock_t dict_foreign_key_check_lock;
+rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve
+ this in X-mode; implicit or backround
+ operations purge, rollback, foreign
+ key checks reserve this in S-mode; we
+ cannot trust that MySQL protects
+ implicit or background operations
+ a table drop since MySQL does not
+ know of them; therefore we need this;
+ NOTE: a transaction which reserves
+ this must keep book on the mode in
+ trx->dict_operation_lock_mode */
#define DICT_HEAP_SIZE 100 /* initial memory heap size when
creating a table or index object */
@@ -42,7 +52,7 @@ rw_lock_t dict_foreign_key_check_lock;
hash table fixed size in bytes */
#define DICT_POOL_PER_VARYING 4 /* buffer pool max size per data
dictionary varying size in bytes */
-
+
/**************************************************************************
Adds a column to the data dictionary hash table. */
static
@@ -78,15 +88,6 @@ dict_index_remove_from_cache(
dict_table_t* table, /* in: table */
dict_index_t* index); /* in, own: index */
/***********************************************************************
-Adds a column to index. */
-UNIV_INLINE
-void
-dict_index_add_col(
-/*===============*/
- dict_index_t* index, /* in: index */
- dict_col_t* col, /* in: column */
- ulint order); /* in: order criterion */
-/***********************************************************************
Copies fields contained in index2 to index1. */
static
void
@@ -175,6 +176,66 @@ dict_foreign_free(
/*==============*/
dict_foreign_t* foreign); /* in, own: foreign key struct */
+/* Buffers for storing detailed information about the latest foreign key
+and unique key errors */
+char* dict_foreign_err_buf = NULL;
+char* dict_unique_err_buf = NULL;
+mutex_t dict_foreign_err_mutex; /* mutex protecting the foreign
+ and unique error buffers */
+
+
+/************************************************************************
+Checks if the database name in two table names is the same. */
+static
+ibool
+dict_tables_have_same_db(
+/*=====================*/
+ /* out: TRUE if same db name */
+ char* name1, /* in: table name in the form dbname '/' tablename */
+ char* name2) /* in: table name in the form dbname '/' tablename */
+{
+ ulint i;
+
+ for (i = 0; i < 100000; i++) {
+ if (name1[i] == '/' && name2[i] == '/') {
+
+ return(TRUE);
+ }
+
+ if (name1[i] != name2[i]) {
+
+ return(FALSE);
+ }
+ }
+
+ ut_a(0);
+
+ return(FALSE);
+}
+
+/************************************************************************
+Return the end of table name where we have removed dbname and '/'. */
+static
+char*
+dict_remove_db_name(
+/*================*/
+ /* out: table name */
+ char* name) /* in: table name in the form dbname '/' tablename */
+{
+ ulint i;
+
+ for (i = 0; i < 100000 ; i++) {
+ if (name[i] == '/') {
+
+ return(name + i + 1);
+ }
+ }
+
+ ut_a(0);
+
+ return(NULL);
+}
+
/************************************************************************
Reserves the dictionary system mutex for MySQL. */
@@ -308,13 +369,28 @@ dict_table_autoinc_get(
}
/************************************************************************
-Reads the autoinc counter value, 0 if not yet initialized. Does not
-increment the counter. */
+Decrements the autoinc counter value by 1. */
+
+void
+dict_table_autoinc_decrement(
+/*=========================*/
+ dict_table_t* table) /* in: table */
+{
+ mutex_enter(&(table->autoinc_mutex));
+
+ table->autoinc = table->autoinc - 1;
+
+ mutex_exit(&(table->autoinc_mutex));
+}
+
+/************************************************************************
+Reads the next autoinc value (== autoinc counter value), 0 if not yet
+initialized. */
ib_longlong
dict_table_autoinc_read(
/*====================*/
- /* out: value of the counter */
+ /* out: value for a new row, or 0 */
dict_table_t* table) /* in: table */
{
ib_longlong value;
@@ -397,8 +473,9 @@ dict_index_get_nth_col_pos(
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+ col = dict_table_get_nth_col(index->table, n);
+
if (index->type & DICT_CLUSTERED) {
- col = dict_table_get_nth_col(index->table, n);
return(col->clust_pos);
}
@@ -407,9 +484,8 @@ dict_index_get_nth_col_pos(
for (pos = 0; pos < n_fields; pos++) {
field = dict_index_get_nth_field(index, pos);
- col = field->col;
- if (dict_col_get_no(col) == n) {
+ if (col == field->col && field->prefix_len == 0) {
return(pos);
}
@@ -417,7 +493,86 @@ dict_index_get_nth_col_pos(
return(ULINT_UNDEFINED);
}
+
+/************************************************************************
+Returns TRUE if the index contains a column or a prefix of that column. */
+
+ibool
+dict_index_contains_col_or_prefix(
+/*==============================*/
+ /* out: TRUE if contains the column or its
+ prefix */
+ dict_index_t* index, /* in: index */
+ ulint n) /* in: column number */
+{
+ dict_field_t* field;
+ dict_col_t* col;
+ ulint pos;
+ ulint n_fields;
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+
+ if (index->type & DICT_CLUSTERED) {
+
+ return(TRUE);
+ }
+
+ col = dict_table_get_nth_col(index->table, n);
+
+ n_fields = dict_index_get_n_fields(index);
+
+ for (pos = 0; pos < n_fields; pos++) {
+ field = dict_index_get_nth_field(index, pos);
+
+ if (col == field->col) {
+
+ return(TRUE);
+ }
+ }
+
+ return(FALSE);
+}
+
+/************************************************************************
+Looks for a matching field in an index. The column and the prefix len have
+to be the same. */
+
+ulint
+dict_index_get_nth_field_pos(
+/*=========================*/
+ /* out: position in internal representation
+ of the index; if not contained, returns
+ ULINT_UNDEFINED */
+ dict_index_t* index, /* in: index from which to search */
+ dict_index_t* index2, /* in: index */
+ ulint n) /* in: field number in index2 */
+{
+ dict_field_t* field;
+ dict_field_t* field2;
+ ulint n_fields;
+ ulint pos;
+
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+
+ field2 = dict_index_get_nth_field(index2, n);
+
+ n_fields = dict_index_get_n_fields(index);
+
+ for (pos = 0; pos < n_fields; pos++) {
+ field = dict_index_get_nth_field(index, pos);
+
+ if (field->col == field2->col
+ && field->prefix_len == field2->prefix_len) {
+
+ return(pos);
+ }
+ }
+
+ return(ULINT_UNDEFINED);
+}
+
/**************************************************************************
Returns a table object, based on table id, and memoryfixes it. */
@@ -494,9 +649,15 @@ dict_init(void)
UT_LIST_INIT(dict_sys->table_LRU);
- rw_lock_create(&dict_foreign_key_check_lock);
- rw_lock_set_level(&dict_foreign_key_check_lock,
- SYNC_FOREIGN_KEY_CHECK);
+ rw_lock_create(&dict_operation_lock);
+ rw_lock_set_level(&dict_operation_lock, SYNC_DICT_OPERATION);
+
+ dict_foreign_err_buf = mem_alloc(DICT_FOREIGN_ERR_BUF_LEN);
+ dict_foreign_err_buf[0] = '\0';
+ dict_unique_err_buf = mem_alloc(DICT_FOREIGN_ERR_BUF_LEN);
+ dict_unique_err_buf[0] = '\0';
+ mutex_create(&dict_foreign_err_mutex);
+ mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
}
/**************************************************************************
@@ -531,8 +692,7 @@ dict_table_get(
}
/**************************************************************************
-Returns a table object and increments MySQL open handle count on the table.
-*/
+Returns a table object and increments MySQL open handle count on the table. */
dict_table_t*
dict_table_get_and_increment_handle_count(
@@ -594,15 +754,19 @@ dict_table_add_to_cache(
The clustered index will not always physically contain all
system columns. */
- dict_mem_table_add_col(table, "DB_ROW_ID", DATA_SYS, DATA_ROW_ID, 0, 0);
+ dict_mem_table_add_col(table, (char *) "DB_ROW_ID", DATA_SYS,
+ DATA_ROW_ID, 0, 0);
ut_ad(DATA_ROW_ID == 0);
- dict_mem_table_add_col(table, "DB_TRX_ID", DATA_SYS, DATA_TRX_ID, 0, 0);
+ dict_mem_table_add_col(table, (char *) "DB_TRX_ID", DATA_SYS,
+ DATA_TRX_ID, 0, 0);
ut_ad(DATA_TRX_ID == 1);
- dict_mem_table_add_col(table, "DB_ROLL_PTR", DATA_SYS, DATA_ROLL_PTR,
+ dict_mem_table_add_col(table, (char *) "DB_ROLL_PTR", DATA_SYS,
+ DATA_ROLL_PTR,
0, 0);
ut_ad(DATA_ROLL_PTR == 2);
- dict_mem_table_add_col(table, "DB_MIX_ID", DATA_SYS, DATA_MIX_ID, 0, 0);
+ dict_mem_table_add_col(table, (char *) "DB_MIX_ID", DATA_SYS,
+ DATA_MIX_ID, 0, 0);
ut_ad(DATA_MIX_ID == 3);
ut_ad(DATA_N_SYS_COLS == 4); /* This assert reminds that if a new
system column is added to the program,
@@ -637,11 +801,12 @@ dict_table_add_to_cache(
}
/* Add table to hash table of tables */
- HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table);
+ HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold,
+ table);
/* Add table to hash table of tables based on table id */
HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, id_fold,
- table);
+ table);
/* Add table to LRU list of tables */
UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
@@ -733,7 +898,7 @@ dict_table_rename_in_cache(
/* Remove table from the hash tables of tables */
HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash,
- ut_fold_string(table->name), table);
+ ut_fold_string(table->name), table);
name_buf = mem_heap_alloc(table->heap, ut_strlen(new_name) + 1);
@@ -742,7 +907,8 @@ dict_table_rename_in_cache(
table->name = name_buf;
/* Add table to hash table of tables */
- HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table);
+ HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold,
+ table);
dict_sys->size += (mem_heap_get_size(table->heap) - old_size);
@@ -1033,7 +1199,6 @@ dict_index_add_to_cache(
ulint n_ord;
ibool success;
ulint i;
- ulint j;
ut_ad(index);
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -1063,26 +1228,6 @@ dict_index_add_to_cache(
return(FALSE);
}
-
- /* Check that the same column does not appear twice in the index.
- InnoDB assumes this in its algorithms, e.g., update of an index
- entry */
-
- for (i = 0; i < dict_index_get_n_fields(index); i++) {
-
- for (j = 0; j < i; j++) {
- if (dict_index_get_nth_field(index, j)->col
- == dict_index_get_nth_field(index, i)->col) {
-
- fprintf(stderr,
-"InnoDB: Error: column %s appears twice in index %s of table %s\n"
-"InnoDB: This is not allowed in InnoDB.\n"
-"InnoDB: UPDATE can cause such an index to become corrupt in InnoDB.\n",
- dict_index_get_nth_field(index, i)->col->name,
- index->name, table->name);
- }
- }
- }
/* Build the cache internal representation of the index,
containing also the added system fields */
@@ -1126,8 +1271,8 @@ dict_index_add_to_cache(
cluster = dict_table_get_low(table->cluster_name);
- tree = dict_index_get_tree(UT_LIST_GET_FIRST(cluster->indexes));
-
+ tree = dict_index_get_tree(
+ UT_LIST_GET_FIRST(cluster->indexes));
new_index->tree = tree;
new_index->page_no = tree->page;
} else {
@@ -1255,13 +1400,14 @@ UNIV_INLINE
void
dict_index_add_col(
/*===============*/
- dict_index_t* index, /* in: index */
- dict_col_t* col, /* in: column */
- ulint order) /* in: order criterion */
+ dict_index_t* index, /* in: index */
+ dict_col_t* col, /* in: column */
+ ulint order, /* in: order criterion */
+ ulint prefix_len) /* in: column prefix length */
{
dict_field_t* field;
- dict_mem_index_add_field(index, col->name, order);
+ dict_mem_index_add_field(index, col->name, order, prefix_len);
field = dict_index_get_nth_field(index, index->n_def - 1);
@@ -1287,7 +1433,8 @@ dict_index_copy(
for (i = start; i < end; i++) {
field = dict_index_get_nth_field(index2, i);
- dict_index_add_col(index1, field->col, field->order);
+ dict_index_add_col(index1, field->col, field->order,
+ field->prefix_len);
}
}
@@ -1390,7 +1537,7 @@ dict_index_build_internal_clust(
/* Add the mix id column */
dict_index_add_col(new_index,
- dict_table_get_sys_col(table, DATA_MIX_ID), 0);
+ dict_table_get_sys_col(table, DATA_MIX_ID), 0, 0);
/* Copy the rest of fields */
dict_index_copy(new_index, index, table->mix_len,
@@ -1428,14 +1575,15 @@ dict_index_build_internal_clust(
if (!(index->type & DICT_UNIQUE)) {
dict_index_add_col(new_index,
- dict_table_get_sys_col(table, DATA_ROW_ID), 0);
+ dict_table_get_sys_col(table, DATA_ROW_ID), 0, 0);
trx_id_pos++;
}
dict_index_add_col(new_index,
- dict_table_get_sys_col(table, DATA_TRX_ID), 0);
+ dict_table_get_sys_col(table, DATA_TRX_ID), 0, 0);
+
dict_index_add_col(new_index,
- dict_table_get_sys_col(table, DATA_ROLL_PTR), 0);
+ dict_table_get_sys_col(table, DATA_ROLL_PTR), 0, 0);
for (i = 0; i < trx_id_pos; i++) {
@@ -1448,6 +1596,13 @@ dict_index_build_internal_clust(
break;
}
+ if (dict_index_get_nth_field(new_index, i)->prefix_len
+ > 0) {
+ new_index->trx_id_offset = 0;
+
+ break;
+ }
+
new_index->trx_id_offset += fixed_size;
}
@@ -1464,7 +1619,14 @@ dict_index_build_internal_clust(
for (i = 0; i < new_index->n_def; i++) {
field = dict_index_get_nth_field(new_index, i);
- (field->col)->aux = 0;
+
+ /* If there is only a prefix of the column in the index
+ field, do not mark the column as contained in the index */
+
+ if (field->prefix_len == 0) {
+
+ field->col->aux = 0;
+ }
}
/* Add to new_index non-system columns of table not yet included
@@ -1475,7 +1637,7 @@ dict_index_build_internal_clust(
ut_ad(col->type.mtype != DATA_SYS);
if (col->aux == ULINT_UNDEFINED) {
- dict_index_add_col(new_index, col, 0);
+ dict_index_add_col(new_index, col, 0, 0);
}
}
@@ -1487,7 +1649,11 @@ dict_index_build_internal_clust(
for (i = 0; i < new_index->n_def; i++) {
field = dict_index_get_nth_field(new_index, i);
- (field->col)->clust_pos = i;
+
+ if (field->prefix_len == 0) {
+
+ field->col->clust_pos = i;
+ }
}
new_index->cached = TRUE;
@@ -1549,25 +1715,33 @@ dict_index_build_internal_non_clust(
for (i = 0; i < clust_index->n_uniq; i++) {
field = dict_index_get_nth_field(clust_index, i);
- (field->col)->aux = ULINT_UNDEFINED;
+ field->col->aux = ULINT_UNDEFINED;
}
/* Mark with 0 table columns already contained in new_index */
for (i = 0; i < new_index->n_def; i++) {
field = dict_index_get_nth_field(new_index, i);
- (field->col)->aux = 0;
+
+ /* If there is only a prefix of the column in the index
+ field, do not mark the column as contained in the index */
+
+ if (field->prefix_len == 0) {
+
+ field->col->aux = 0;
+ }
}
- /* Add to new_index columns necessary to determine the clustered
+ /* Add to new_index the columns necessary to determine the clustered
index entry uniquely */
for (i = 0; i < clust_index->n_uniq; i++) {
field = dict_index_get_nth_field(clust_index, i);
- if ((field->col)->aux == ULINT_UNDEFINED) {
- dict_index_add_col(new_index, field->col, 0);
+ if (field->col->aux == ULINT_UNDEFINED) {
+ dict_index_add_col(new_index, field->col, 0,
+ field->prefix_len);
}
}
@@ -1690,6 +1864,14 @@ dict_foreign_find_index(
for (i = 0; i < n_cols; i++) {
col_name = dict_index_get_nth_field(index, i)
->col->name;
+ if (dict_index_get_nth_field(index, i)
+ ->prefix_len != 0) {
+ /* We do not accept column prefix
+ indexes here */
+
+ break;
+ }
+
if (ut_strlen(columns[i]) !=
ut_strlen(col_name)
|| 0 != ut_cmp_in_lower_case(columns[i],
@@ -1736,6 +1918,7 @@ dict_foreign_add_to_cache(
dict_foreign_t* for_in_cache = NULL;
dict_index_t* index;
ibool added_to_referenced_list = FALSE;
+ char* buf = dict_foreign_err_buf;
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -1768,9 +1951,29 @@ dict_foreign_add_to_cache(
for_in_cache->foreign_index);
if (index == NULL) {
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s:\n"
+"there is no index in referenced table which would contain\n"
+"the columns as the first columns, or the data types in the\n"
+"referenced table do not match to the ones in table. Constraint:\n",
+ for_in_cache->foreign_table_name);
+ dict_print_info_on_foreign_key_in_create_format(
+ for_in_cache, buf + strlen(buf));
+ if (for_in_cache->foreign_index) {
+ sprintf(buf + strlen(buf),
+"\nThe index in the foreign key in table is %.500s\n"
+"See http://www.innodb.com/ibman.html about correct foreign key definition.\n",
+ for_in_cache->foreign_index->name);
+ }
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
if (for_in_cache == foreign) {
mem_heap_free(foreign->heap);
}
+
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -1789,6 +1992,25 @@ dict_foreign_add_to_cache(
for_in_cache->referenced_index);
if (index == NULL) {
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s:\n"
+"there is no index in the table which would contain\n"
+"the columns as the first columns, or the data types in the\n"
+"table do not match to the ones in the referenced table. Constraint:\n",
+ for_in_cache->foreign_table_name);
+ dict_print_info_on_foreign_key_in_create_format(
+ for_in_cache, buf + strlen(buf));
+ if (for_in_cache->foreign_index) {
+ sprintf(buf + strlen(buf),
+"\nIndex of the foreign key in the referenced table is %.500s\n"
+"See http://www.innodb.com/ibman.html about correct foreign key definition.\n",
+ for_in_cache->referenced_index->name);
+ }
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
if (for_in_cache == foreign) {
if (added_to_referenced_list) {
UT_LIST_REMOVE(referenced_list,
@@ -1821,8 +2043,8 @@ char*
dict_scan_to(
/*=========*/
- char* ptr, /* in: scan from */
- char* string) /* in: look for this */
+ char* ptr, /* in: scan from */
+ const char *string) /* in: look for this */
{
ibool success;
ulint i;
@@ -1853,14 +2075,14 @@ loop:
/*************************************************************************
Accepts a specified string. Comparisons are case-insensitive. */
-static
+
char*
dict_accept(
/*========*/
/* out: if string was accepted, the pointer
is moved after that, else ptr is returned */
char* ptr, /* in: scan from this */
- char* string, /* in: accept only this string as the next
+ const char* string,/* in: accept only this string as the next
non-whitespace string */
ibool* success)/* out: TRUE if accepted */
{
@@ -1887,6 +2109,68 @@ dict_accept(
}
/*************************************************************************
+Scans an id. For the lexical definition of an 'id', see the code below.
+Strips backquotes or double quotes from around the id. */
+static
+char*
+dict_scan_id(
+/*=========*/
+ /* out: scanned to */
+ char* ptr, /* in: scanned to */
+ char** start, /* out: start of the id; NULL if no id was
+ scannable */
+ ulint* len, /* out: length of the id */
+ ibool accept_also_dot)/* in: TRUE if also a dot can appear in a
+ non-quoted id; in a quoted id it can appear
+ always */
+{
+ char quote = '\0';
+
+ *start = NULL;
+
+ while (isspace(*ptr)) {
+ ptr++;
+ }
+
+ if (*ptr == '\0') {
+
+ return(ptr);
+ }
+
+ if (*ptr == '`' || *ptr == '"') {
+ quote = *ptr++;
+ }
+
+ *start = ptr;
+
+ if (quote) {
+ while (*ptr != quote && *ptr != '\0') {
+ ptr++;
+ }
+ } else {
+ while (!isspace(*ptr) && *ptr != '(' && *ptr != ')'
+ && (accept_also_dot || *ptr != '.')
+ && *ptr != ',' && *ptr != '\0') {
+
+ ptr++;
+ }
+ }
+
+ *len = (ulint) (ptr - *start);
+
+ if (quote) {
+ if (*ptr == quote) {
+ ptr++;
+ } else {
+ /* Syntax error */
+ *start = NULL;
+ }
+ }
+
+ return(ptr);
+}
+
+/*************************************************************************
Tries to scan a column name. */
static
char*
@@ -1902,45 +2186,29 @@ dict_scan_col(
ulint* column_name_len)/* out: column name length */
{
dict_col_t* col;
- char* old_ptr;
ulint i;
*success = FALSE;
- while (isspace(*ptr)) {
- ptr++;
- }
-
- if (*ptr == '\0') {
-
- return(ptr);
- }
+ ptr = dict_scan_id(ptr, column_name, column_name_len, TRUE);
- if (*ptr == '`') {
- ptr++;
- }
+ if (column_name == NULL) {
- old_ptr = ptr;
-
- while (!isspace(*ptr) && *ptr != ',' && *ptr != ')' && *ptr != '`') {
-
- ptr++;
+ return(ptr); /* Syntax error */
}
- *column_name_len = (ulint)(ptr - old_ptr);
-
if (table == NULL) {
*success = TRUE;
*column = NULL;
- *column_name = old_ptr;
} else {
for (i = 0; i < dict_table_get_n_cols(table); i++) {
col = dict_table_get_nth_col(table, i);
- if (ut_strlen(col->name) == (ulint)(ptr - old_ptr)
- && 0 == ut_cmp_in_lower_case(col->name, old_ptr,
- (ulint)(ptr - old_ptr))) {
+ if (ut_strlen(col->name) == *column_name_len
+ && 0 == ut_cmp_in_lower_case(col->name,
+ *column_name,
+ *column_name_len)) {
/* Found */
*success = TRUE;
@@ -1952,10 +2220,6 @@ dict_scan_col(
}
}
- if (*ptr == '`') {
- ptr++;
- }
-
return(ptr);
}
@@ -1974,78 +2238,141 @@ dict_scan_table_name(
the referenced table name; must be at least
2500 bytes */
{
- char* dot_ptr = NULL;
- char* old_ptr;
+ char* database_name = NULL;
+ ulint database_name_len = 999999999; /* init to a dummy value to
+ suppress a compiler warning */
+ char* table_name = NULL;
+ ulint table_name_len;
+ char* scanned_id;
+ ulint scanned_id_len;
ulint i;
*success = FALSE;
*table = NULL;
+
+ ptr = dict_scan_id(ptr, &scanned_id, &scanned_id_len, FALSE);
- while (isspace(*ptr)) {
- ptr++;
+ if (scanned_id == NULL) {
+
+ return(ptr); /* Syntax error */
}
- if (*ptr == '\0') {
-
- return(ptr);
- }
+ if (*ptr == '.') {
+ /* We scanned the database name; scan also the table name */
- if (*ptr == '`') {
ptr++;
+
+ database_name = scanned_id;
+ database_name_len = scanned_id_len;
+
+ ptr = dict_scan_id(ptr, &table_name, &table_name_len, FALSE);
+
+ if (table_name == NULL) {
+
+ return(ptr); /* Syntax error */
+ }
+ } else {
+ /* To be able to read table dumps made with InnoDB-4.0.17 or
+ earlier, we must allow the dot separator between the database
+ name and the table name also to appear within a quoted
+ identifier! InnoDB used to print a constraint as:
+ ... REFERENCES `databasename.tablename` ...
+ starting from 4.0.18 it is
+ ... REFERENCES `databasename`.`tablename` ... */
+
+ for (i = 0; i < scanned_id_len; i++) {
+ if (scanned_id[i] == '.') {
+ database_name = scanned_id;
+ database_name_len = i;
+
+ scanned_id = scanned_id + i + 1;
+ scanned_id_len -= i + 1;
+ }
+ }
+
+ table_name = scanned_id;
+ table_name_len = scanned_id_len;
}
- old_ptr = ptr;
-
- while (!isspace(*ptr) && *ptr != '(' && *ptr != '`') {
- if (*ptr == '.') {
- dot_ptr = ptr;
+ if (database_name == NULL) {
+ /* Use the database name of the foreign key table */
+
+ database_name = name;
+
+ i = 0;
+ while (name[i] != '/') {
+ i++;
}
- ptr++;
+ database_name_len = i;
}
- if (ptr - old_ptr > 2000) {
- return(old_ptr);
+ if (table_name_len + database_name_len > 2000) {
+
+ return(ptr); /* Too long name */
}
- if (dot_ptr == NULL) {
- /* Copy the database name from 'name' to the start */
- for (i = 0;; i++) {
- second_table_name[i] = name[i];
- if (name[i] == '/') {
- i++;
- break;
- }
- }
#ifdef __WIN__
- ut_cpy_in_lower_case(second_table_name + i, old_ptr,
- ptr - old_ptr);
+ ut_cpy_in_lower_case(second_table_name, database_name,
+ database_name_len);
#else
- ut_memcpy(second_table_name + i, old_ptr, ptr - old_ptr);
-#endif
- second_table_name[i + (ptr - old_ptr)] = '\0';
+ if (srv_lower_case_table_names) {
+ ut_cpy_in_lower_case(second_table_name, database_name,
+ database_name_len);
} else {
+ ut_memcpy(second_table_name, database_name,
+ database_name_len);
+ }
+#endif
+ second_table_name[database_name_len] = '/';
+
#ifdef __WIN__
- ut_cpy_in_lower_case(second_table_name, old_ptr,
- ptr - old_ptr);
+ ut_cpy_in_lower_case(second_table_name + database_name_len + 1,
+ table_name, table_name_len);
#else
- ut_memcpy(second_table_name, old_ptr, ptr - old_ptr);
-#endif
- second_table_name[dot_ptr - old_ptr] = '/';
- second_table_name[ptr - old_ptr] = '\0';
+ if (srv_lower_case_table_names) {
+ ut_cpy_in_lower_case(second_table_name + database_name_len + 1,
+ table_name, table_name_len);
+ } else {
+ ut_memcpy(second_table_name + database_name_len + 1,
+ table_name, table_name_len);
}
+#endif
+ second_table_name[database_name_len + 1 + table_name_len] = '\0';
*success = TRUE;
*table = dict_table_get_low(second_table_name);
- if (*ptr == '`') {
- ptr++;
- }
+ return(ptr);
+}
+
+/*************************************************************************
+Skips one id. The id is allowed to contain also '.'. */
+static
+char*
+dict_skip_word(
+/*===========*/
+ /* out: scanned to */
+ char* ptr, /* in: scanned to */
+ ibool* success)/* out: TRUE if success, FALSE if just spaces left in
+ string or a syntax error */
+{
+ char* start;
+ ulint len;
+
+ *success = FALSE;
+ ptr = dict_scan_id(ptr, &start, &len, TRUE);
+
+ if (start) {
+ *success = TRUE;
+ }
+
return(ptr);
}
+#ifdef currentlynotused
/*************************************************************************
Returns the number of opening brackets '(' subtracted by the number
of closing brackets ')' between string and ptr. */
@@ -2072,6 +2399,109 @@ dict_bracket_count(
return(count);
}
+#endif
+
+/*************************************************************************
+Removes MySQL comments from an SQL string. A comment is either
+(a) '#' to the end of the line,
+(b) '--<space>' to the end of the line, or
+(c) '<slash><asterisk>' till the next '<asterisk><slash>' (like the familiar
+C comment syntax). */
+static
+char*
+dict_strip_comments(
+/*================*/
+ /* out, own: SQL string stripped from
+ comments; the caller must free this
+ with mem_free()! */
+ char* sql_string) /* in: SQL string */
+{
+ char* str;
+ char* sptr;
+ char* ptr;
+
+ str = mem_alloc(strlen(sql_string) + 1);
+
+ sptr = sql_string;
+ ptr = str;
+
+ for (;;) {
+scan_more:
+ if (*sptr == '\0') {
+ *ptr = '\0';
+
+ ut_a(ptr <= str + strlen(sql_string));
+
+ return(str);
+ }
+
+ if (*sptr == '#'
+ || (strlen(sptr) >= 3 && 0 == memcmp("-- ", sptr, 3))) {
+ for (;;) {
+ /* In Unix a newline is 0x0D while in Windows
+ it is 0x0A followed by 0x0D */
+
+ if (*sptr == (char)0x0A
+ || *sptr == (char)0x0D
+ || *sptr == '\0') {
+
+ goto scan_more;
+ }
+
+ sptr++;
+ }
+ }
+
+ if (strlen(sptr) >= 2 && *sptr == '/' && *(sptr + 1) == '*') {
+ for (;;) {
+ if (strlen(sptr) >= 2
+ && *sptr == '*' && *(sptr + 1) == '/') {
+
+ sptr += 2;
+
+ goto scan_more;
+ }
+
+ if (*sptr == '\0') {
+
+ goto scan_more;
+ }
+
+ sptr++;
+ }
+ }
+
+ *ptr = *sptr;
+
+ ptr++;
+ sptr++;
+ }
+}
+
+/*************************************************************************
+Reports a simple foreign key create clause syntax error. */
+static
+void
+dict_foreign_report_syntax_err(
+/*===========================*/
+ char* name, /* in: table name */
+ char* start_of_latest_foreign,/* in: start of the foreign key clause
+ in the SQL string */
+ char* ptr) /* in: place of the syntax error */
+{
+ char* buf = dict_foreign_err_buf;
+
+ mutex_enter(&dict_foreign_err_mutex);
+
+ ut_sprintf_timestamp(buf);
+
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s,\n%.500s.\n"
+"Syntax error close to:\n%.500s\n", name, start_of_latest_foreign, ptr);
+
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+}
/*************************************************************************
Scans a table create SQL string and adds to the data dictionary the foreign
@@ -2079,10 +2509,10 @@ key constraints declared in the string. This function should be called after
the indexes for a table have been created. Each foreign key constraint must
be accompanied with indexes in both participating tables. The indexes are
allowed to contain more fields than mentioned in the constraint. */
-
+static
ulint
-dict_create_foreign_constraints(
-/*============================*/
+dict_create_foreign_constraints_low(
+/*================================*/
/* out: error code or DB_SUCCESS */
trx_t* trx, /* in: transaction */
char* sql_string, /* in: table create or ALTER TABLE
@@ -2098,11 +2528,16 @@ dict_create_foreign_constraints(
dict_table_t* referenced_table;
dict_index_t* index;
dict_foreign_t* foreign;
- char* ptr = sql_string;
+ char* ptr = sql_string;
+ char* start_of_latest_foreign = sql_string;
+ char* buf = dict_foreign_err_buf;
ibool success;
ulint error;
ulint i;
ulint j;
+ ibool is_on_delete;
+ ulint n_on_deletes;
+ ulint n_on_updates;
dict_col_t* columns[500];
char* column_names[500];
ulint column_name_lens[500];
@@ -2113,11 +2548,19 @@ dict_create_foreign_constraints(
table = dict_table_get_low(name);
if (table == NULL) {
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s.\n"
+"Cannot find the table from the internal data dictionary of InnoDB.\n"
+"Create table statement:\n%.2000\n", name, sql_string);
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
return(DB_ERROR);
}
-
loop:
- ptr = dict_scan_to(ptr, "FOREIGN");
+ ptr = dict_scan_to(ptr, (char *) "FOREIGN");
if (*ptr == '\0') {
@@ -2129,22 +2572,42 @@ loop:
return(error);
}
- ptr = dict_accept(ptr, "FOREIGN", &success);
+ start_of_latest_foreign = ptr;
+
+ ptr = dict_accept(ptr, (char *) "FOREIGN", &success);
if (!isspace(*ptr)) {
goto loop;
}
- ptr = dict_accept(ptr, "KEY", &success);
+ ptr = dict_accept(ptr, (char *) "KEY", &success);
if (!success) {
goto loop;
}
- ptr = dict_accept(ptr, "(", &success);
+ ptr = dict_accept(ptr, (char *) "(", &success);
if (!success) {
- goto loop;
+ /* MySQL allows also an index id before the '('; we
+ skip it */
+ ptr = dict_skip_word(ptr, &success);
+
+ if (!success) {
+ dict_foreign_report_syntax_err(name,
+ start_of_latest_foreign, ptr);
+
+ return(DB_CANNOT_ADD_CONSTRAINT);
+ }
+
+ ptr = dict_accept(ptr, (char *) "(", &success);
+
+ if (!success) {
+ /* We do not flag a syntax error here because in an
+ ALTER TABLE we may also have DROP FOREIGN KEY abc */
+
+ goto loop;
+ }
}
i = 0;
@@ -2154,20 +2617,31 @@ col_loop1:
ptr = dict_scan_col(ptr, &success, table, columns + i,
column_names + i, column_name_lens + i);
if (!success) {
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s,\n%.500s.\n"
+"Cannot resolve column name close to:\n%.500s\n", name,
+ start_of_latest_foreign, ptr);
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
return(DB_CANNOT_ADD_CONSTRAINT);
}
i++;
- ptr = dict_accept(ptr, ",", &success);
+ ptr = dict_accept(ptr, (char *) ",", &success);
if (success) {
goto col_loop1;
}
- ptr = dict_accept(ptr, ")", &success);
+ ptr = dict_accept(ptr, (char *) ")", &success);
if (!success) {
+ dict_foreign_report_syntax_err(name, start_of_latest_foreign,
+ ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -2177,12 +2651,24 @@ col_loop1:
index = dict_foreign_find_index(table, column_names, i, NULL);
if (!index) {
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s:\n"
+"There is no index in the table %.500s where the columns appear\n"
+"as the first columns. Constraint:\n%.500s\n"
+"See http://www.innodb.com/ibman.html for correct foreign key definition.\n",
+ name, name, start_of_latest_foreign);
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
return(DB_CANNOT_ADD_CONSTRAINT);
}
-
- ptr = dict_accept(ptr, "REFERENCES", &success);
+ ptr = dict_accept(ptr, (char *) "REFERENCES", &success);
if (!success || !isspace(*ptr)) {
+ dict_foreign_report_syntax_err(name, start_of_latest_foreign,
+ ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -2212,13 +2698,24 @@ col_loop1:
if (!success || (!referenced_table && trx->check_foreigns)) {
dict_foreign_free(foreign);
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s,\n%.500s.\n"
+"Cannot resolve table name close to:\n"
+"%.500s\n", name, start_of_latest_foreign, ptr);
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, "(", &success);
+ ptr = dict_accept(ptr, (char *) "(", &success);
if (!success) {
dict_foreign_free(foreign);
+ dict_foreign_report_syntax_err(name, start_of_latest_foreign,
+ ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -2232,23 +2729,41 @@ col_loop2:
if (!success) {
dict_foreign_free(foreign);
+
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s,\n%.500s\n"
+"Cannot resolve column name close to:\n"
+"%.500s\n", name, start_of_latest_foreign, ptr);
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
return(DB_CANNOT_ADD_CONSTRAINT);
}
- ptr = dict_accept(ptr, ",", &success);
+ ptr = dict_accept(ptr, (char *) ",", &success);
if (success) {
goto col_loop2;
}
- ptr = dict_accept(ptr, ")", &success);
+ ptr = dict_accept(ptr, (char *) ")", &success);
if (!success || foreign->n_fields != i) {
dict_foreign_free(foreign);
+ dict_foreign_report_syntax_err(name, start_of_latest_foreign,
+ ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
}
+ n_on_deletes = 0;
+ n_on_updates = 0;
+
+scan_on_conditions:
+ /* Loop here as long as we can find ON ... conditions */
+
ptr = dict_accept(ptr, "ON", &success);
if (!success) {
@@ -2259,48 +2774,130 @@ col_loop2:
ptr = dict_accept(ptr, "DELETE", &success);
if (!success) {
+ ptr = dict_accept(ptr, "UPDATE", &success);
- goto try_find_index;
+ if (!success) {
+ dict_foreign_free(foreign);
+
+ dict_foreign_report_syntax_err(name,
+ start_of_latest_foreign, ptr);
+ return(DB_CANNOT_ADD_CONSTRAINT);
+ }
+
+ is_on_delete = FALSE;
+ n_on_updates++;
+ } else {
+ is_on_delete = TRUE;
+ n_on_deletes++;
+ }
+
+ ptr = dict_accept(ptr, "RESTRICT", &success);
+
+ if (success) {
+ goto scan_on_conditions;
}
ptr = dict_accept(ptr, "CASCADE", &success);
if (success) {
+ if (is_on_delete) {
+ foreign->type |= DICT_FOREIGN_ON_DELETE_CASCADE;
+ } else {
+ foreign->type |= DICT_FOREIGN_ON_UPDATE_CASCADE;
+ }
+
+ goto scan_on_conditions;
+ }
+
+ ptr = dict_accept(ptr, "NO", &success);
+
+ if (success) {
+ ptr = dict_accept(ptr, "ACTION", &success);
+
+ if (!success) {
+ dict_foreign_free(foreign);
+ dict_foreign_report_syntax_err(name,
+ start_of_latest_foreign, ptr);
+
+ return(DB_CANNOT_ADD_CONSTRAINT);
+ }
- foreign->type = DICT_FOREIGN_ON_DELETE_CASCADE;
+ if (is_on_delete) {
+ foreign->type |= DICT_FOREIGN_ON_DELETE_NO_ACTION;
+ } else {
+ foreign->type |= DICT_FOREIGN_ON_UPDATE_NO_ACTION;
+ }
- goto try_find_index;
+ goto scan_on_conditions;
}
ptr = dict_accept(ptr, "SET", &success);
if (!success) {
-
- goto try_find_index;
+ dict_foreign_free(foreign);
+ dict_foreign_report_syntax_err(name, start_of_latest_foreign,
+ ptr);
+ return(DB_CANNOT_ADD_CONSTRAINT);
}
ptr = dict_accept(ptr, "NULL", &success);
- if (success) {
- for (j = 0; j < foreign->n_fields; j++) {
- if ((dict_index_get_nth_type(
+ if (!success) {
+ dict_foreign_free(foreign);
+ dict_foreign_report_syntax_err(name, start_of_latest_foreign,
+ ptr);
+ return(DB_CANNOT_ADD_CONSTRAINT);
+ }
+
+ for (j = 0; j < foreign->n_fields; j++) {
+ if ((dict_index_get_nth_type(
foreign->foreign_index, j)->prtype)
& DATA_NOT_NULL) {
- /* It is not sensible to define SET NULL
- if the column is not allowed to be NULL! */
+ /* It is not sensible to define SET NULL
+ if the column is not allowed to be NULL! */
- dict_foreign_free(foreign);
- return(DB_CANNOT_ADD_CONSTRAINT);
- }
- }
+ dict_foreign_free(foreign);
- foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL;
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s,\n%.500s.\n"
+"You have defined a SET NULL condition though some of the\n"
+"columns is defined as NOT NULL.\n", name, start_of_latest_foreign);
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
- goto try_find_index;
+ return(DB_CANNOT_ADD_CONSTRAINT);
+ }
+ }
+
+ if (is_on_delete) {
+ foreign->type |= DICT_FOREIGN_ON_DELETE_SET_NULL;
+ } else {
+ foreign->type |= DICT_FOREIGN_ON_UPDATE_SET_NULL;
}
+ goto scan_on_conditions;
+
try_find_index:
+ if (n_on_deletes > 1 || n_on_updates > 1) {
+ /* It is an error to define more than 1 action */
+
+ dict_foreign_free(foreign);
+
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s,\n%.500s.\n"
+"You have twice an ON DELETE clause or twice an ON UPDATE clause.\n",
+ name, start_of_latest_foreign);
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
+ return(DB_CANNOT_ADD_CONSTRAINT);
+ }
+
/* Try to find an index which contains the columns as the first fields
and in the right order, and the types are the same as in
foreign->foreign_index */
@@ -2311,6 +2908,18 @@ try_find_index:
foreign->foreign_index);
if (!index) {
dict_foreign_free(foreign);
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in foreign key constraint of table %.500s:\n"
+"Cannot find an index in the referenced table where the\n"
+"referenced columns appear as the first columns, or column types\n"
+"in the table and the referenced table do not match for constraint:\n%.500s\n"
+"See http://www.innodb.com/ibman.html for correct foreign key definition.\n",
+ name, start_of_latest_foreign);
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
return(DB_CANNOT_ADD_CONSTRAINT);
}
} else {
@@ -2347,9 +2956,169 @@ try_find_index:
referenced_table->referenced_list,
foreign);
}
+
goto loop;
}
+/*************************************************************************
+Scans a table create SQL string and adds to the data dictionary the foreign
+key constraints declared in the string. This function should be called after
+the indexes for a table have been created. Each foreign key constraint must
+be accompanied with indexes in both participating tables. The indexes are
+allowed to contain more fields than mentioned in the constraint. */
+
+ulint
+dict_create_foreign_constraints(
+/*============================*/
+ /* out: error code or DB_SUCCESS */
+ trx_t* trx, /* in: transaction */
+ char* sql_string, /* in: table create or ALTER TABLE
+ statement where foreign keys are declared like:
+ FOREIGN KEY (a, b) REFERENCES table2(c, d),
+ table2 can be written also with the database
+ name before it: test.table2; the default
+ database id the database of parameter name */
+ char* name) /* in: table full name in the normalized form
+ database_name/table_name */
+{
+ char* str;
+ ulint err;
+
+ str = dict_strip_comments(sql_string);
+
+ err = dict_create_foreign_constraints_low(trx, str, name);
+
+ mem_free(str);
+
+ return(err);
+}
+
+/**************************************************************************
+Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. */
+
+ulint
+dict_foreign_parse_drop_constraints(
+/*================================*/
+ /* out: DB_SUCCESS or
+ DB_CANNOT_DROP_CONSTRAINT if
+ syntax error or the constraint
+ id does not match */
+ mem_heap_t* heap, /* in: heap from which we can
+ allocate memory */
+ trx_t* trx, /* in: transaction */
+ dict_table_t* table, /* in: table */
+ ulint* n, /* out: number of constraints
+ to drop */
+ char*** constraints_to_drop) /* out: id's of the
+ constraints to drop */
+{
+ dict_foreign_t* foreign;
+ ibool success;
+ char* str;
+ char* ptr;
+ char* buf = dict_foreign_err_buf;
+ char* start;
+ char* id;
+ ulint len;
+
+ *n = 0;
+
+ *constraints_to_drop = mem_heap_alloc(heap, 1000 * sizeof(char*));
+
+ str = dict_strip_comments(*(trx->mysql_query_str));
+ ptr = str;
+
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+loop:
+ ptr = dict_scan_to(ptr, (char *) "DROP");
+
+ if (*ptr == '\0') {
+ ut_a(*n < 1000);
+
+ mem_free(str);
+
+ return(DB_SUCCESS);
+ }
+
+ ptr = dict_accept(ptr, (char *) "DROP", &success);
+
+ if (!isspace(*ptr)) {
+
+ goto loop;
+ }
+
+ ptr = dict_accept(ptr, (char *) "FOREIGN", &success);
+
+ if (!success) {
+
+ goto loop;
+ }
+
+ ptr = dict_accept(ptr, (char *) "KEY", &success);
+
+ if (!success) {
+
+ goto syntax_error;
+ }
+
+ ptr = dict_scan_id(ptr, &start, &len, TRUE);
+
+ if (start == NULL) {
+
+ goto syntax_error;
+ }
+
+ id = mem_heap_alloc(heap, len + 1);
+ ut_memcpy(id, start, len);
+ id[len] = '\0';
+ (*constraints_to_drop)[*n] = id;
+ (*n)++;
+
+ /* Look for the given constraint id */
+
+ foreign = UT_LIST_GET_FIRST(table->foreign_list);
+
+ while (foreign != NULL) {
+ if (0 == ut_strcmp(foreign->id, id)) {
+
+ /* Found */
+ break;
+ }
+
+ foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
+ }
+
+ if (foreign == NULL) {
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Error in dropping of a foreign key constraint of table %.500s,\n"
+"just before:\n%s\n in SQL command\n%s\nCannot find a constraint with the\n"
+"given id %s.\n", table->name, ptr, str, id);
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
+ mem_free(str);
+
+ return(DB_CANNOT_DROP_CONSTRAINT);
+ }
+
+ goto loop;
+
+syntax_error:
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf),
+" Syntax error in dropping of a foreign key constraint of table %.500s,\n"
+"close to:\n%s\n in SQL command\n%s\n", table->name, ptr, str);
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
+ mem_free(str);
+
+ return(DB_CANNOT_DROP_CONSTRAINT);
+}
+
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
/**************************************************************************
@@ -2837,13 +3606,22 @@ void
dict_update_statistics_low(
/*=======================*/
dict_table_t* table, /* in: table */
- ibool has_dict_mutex) /* in: TRUE if the caller has the
+ ibool has_dict_mutex __attribute__((unused)))
+ /* in: TRUE if the caller has the
dictionary mutex */
{
dict_index_t* index;
ulint size;
ulint sum_of_index_sizes = 0;
+ /* If we have set a high innodb_force_recovery level, do not calculate
+ statistics, as a badly corrupted index can cause a crash in it. */
+
+ if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
+
+ return;
+ }
+
/* Find out the sizes of the indexes and how many different values
for the key they approximately have */
@@ -3062,7 +3840,6 @@ dict_index_print_low(
n_vals = index->stat_n_diff_key_vals[1];
}
-
printf(
" INDEX: name %s, table name %s, id %lu %lu, fields %lu/%lu, type %lu\n",
index->name, index->table_name,
@@ -3101,6 +3878,111 @@ dict_field_print_low(
ut_ad(mutex_own(&(dict_sys->mutex)));
printf(" %s", field->name);
+
+ if (field->prefix_len != 0) {
+ printf("(%lu)", field->prefix_len);
+ }
+}
+
+/**************************************************************************
+Sprintfs to a string info on a foreign key of a table in a format suitable
+for CREATE TABLE. */
+
+char*
+dict_print_info_on_foreign_key_in_create_format(
+/*============================================*/
+ /* out: how far in buf we printed */
+ dict_foreign_t* foreign,/* in: foreign key constraint */
+ char* buf) /* in: buffer of at least 5000 bytes */
+{
+ char* buf2 = buf;
+ ulint cpy_len;
+ ulint i;
+
+ buf2 += sprintf(buf2, ",\n CONSTRAINT `%s` FOREIGN KEY (",
+ foreign->id);
+ for (i = 0; i < foreign->n_fields; i++) {
+ if ((ulint)(buf2 - buf) >= 4000) {
+
+ goto no_space;
+ }
+ buf2 += sprintf(buf2, "`%.250s`",
+ foreign->foreign_col_names[i]);
+
+ if (i + 1 < foreign->n_fields) {
+ buf2 += sprintf(buf2, ", ");
+ }
+ }
+
+ if (dict_tables_have_same_db(foreign->foreign_table_name,
+ foreign->referenced_table_name)) {
+ /* Do not print the database name of the referenced table */
+ buf2 += sprintf(buf2, ") REFERENCES `%.500s` (",
+ dict_remove_db_name(
+ foreign->referenced_table_name));
+ } else {
+ buf2 += sprintf(buf2, ") REFERENCES `");
+
+ /* Look for the '/' in the table name */
+
+ i = 0;
+ while (foreign->referenced_table_name[i] != '/') {
+ i++;
+ }
+
+ cpy_len = i;
+
+ if (cpy_len > 500) {
+ cpy_len = 500;
+ }
+
+ memcpy(buf2, foreign->referenced_table_name, cpy_len);
+ buf2 += cpy_len;
+
+ buf2 += sprintf(buf2, "`.`%.500s` (",
+ foreign->referenced_table_name + i + 1);
+ }
+
+ for (i = 0; i < foreign->n_fields; i++) {
+ if ((ulint)(buf2 - buf) >= 4000) {
+
+ goto no_space;
+ }
+ buf2 += sprintf(buf2, "`%.250s`",
+ foreign->referenced_col_names[i]);
+ if (i + 1 < foreign->n_fields) {
+ buf2 += sprintf(buf2, ", ");
+ }
+ }
+
+ buf2 += sprintf(buf2, ")");
+
+ if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) {
+ buf2 += sprintf(buf2, " ON DELETE CASCADE");
+ }
+
+ if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) {
+ buf2 += sprintf(buf2, " ON DELETE SET NULL");
+ }
+
+ if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) {
+ buf2 += sprintf(buf2, " ON DELETE NO ACTION");
+ }
+
+ if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) {
+ buf2 += sprintf(buf2, " ON UPDATE CASCADE");
+ }
+
+ if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) {
+ buf2 += sprintf(buf2, " ON UPDATE SET NULL");
+ }
+
+ if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) {
+ buf2 += sprintf(buf2, " ON UPDATE NO ACTION");
+ }
+
+no_space:
+ return(buf2);
}
/**************************************************************************
@@ -3110,14 +3992,14 @@ static
void
dict_print_info_on_foreign_keys_in_create_format(
/*=============================================*/
- char* buf, /* in: auxiliary buffer of 10000 chars */
+ char* buf, /* in: auxiliary buffer */
char* str, /* in/out: pointer to a string */
- ulint len, /* in: space in str available for info */
+ ulint len, /* in: buf has to be a buffer of at least
+ len + 5000 bytes; str must have at least
+ len + 1 bytes */
dict_table_t* table) /* in: table */
{
-
dict_foreign_t* foreign;
- ulint i;
char* buf2;
buf2 = buf;
@@ -3133,51 +4015,16 @@ dict_print_info_on_foreign_keys_in_create_format(
}
while (foreign != NULL) {
- buf2 += sprintf(buf2, ",\n FOREIGN KEY (");
-
- for (i = 0; i < foreign->n_fields; i++) {
- buf2 += sprintf(buf2, "`%s`",
- foreign->foreign_col_names[i]);
-
- if (i + 1 < foreign->n_fields) {
- buf2 += sprintf(buf2, ", ");
- }
- }
-
- buf2 += sprintf(buf2, ") REFERENCES `%s` (",
- foreign->referenced_table_name);
- /* Change the '/' in the table name to '.' */
-
- for (i = ut_strlen(buf); i > 0; i--) {
- if (buf[i] == '/') {
-
- buf[i] = '.';
-
- break;
- }
- }
-
- for (i = 0; i < foreign->n_fields; i++) {
- buf2 += sprintf(buf2, "`%s`",
- foreign->referenced_col_names[i]);
- if (i + 1 < foreign->n_fields) {
- buf2 += sprintf(buf2, ", ");
- }
- }
+ if ((ulint)(buf2 - buf) >= len) {
+ goto no_space;
+ }
- buf2 += sprintf(buf2, ")");
-
- if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) {
- buf2 += sprintf(buf2, " ON DELETE CASCADE");
- }
-
- if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) {
- buf2 += sprintf(buf2, " ON DELETE SET NULL");
- }
+ buf2 = dict_print_info_on_foreign_key_in_create_format(
+ foreign, buf2);
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
-
+no_space:
mutex_exit(&(dict_sys->mutex));
buf[len - 1] = '\0';
@@ -3201,16 +4048,17 @@ dict_print_info_on_foreign_keys(
dict_foreign_t* foreign;
ulint i;
char* buf2;
- char buf[10000];
+ char* buf;
+
+ buf = mem_alloc(len + 5000);
if (create_table_format) {
dict_print_info_on_foreign_keys_in_create_format(
buf, str, len, table);
+ mem_free(buf);
return;
}
- buf2 = buf;
-
mutex_enter(&(dict_sys->mutex));
foreign = UT_LIST_GET_FIRST(table->foreign_list);
@@ -3218,14 +4066,22 @@ dict_print_info_on_foreign_keys(
if (foreign == NULL) {
mutex_exit(&(dict_sys->mutex));
+ mem_free(buf);
return;
}
+ buf2 = buf;
+
while (foreign != NULL) {
+
buf2 += sprintf(buf2, "; (");
for (i = 0; i < foreign->n_fields; i++) {
- buf2 += sprintf(buf2, "%s",
+ if ((ulint)(buf2 - buf) >= len) {
+ goto no_space;
+ }
+
+ buf2 += sprintf(buf2, "%.500s",
foreign->foreign_col_names[i]);
if (i + 1 < foreign->n_fields) {
@@ -3233,11 +4089,14 @@ dict_print_info_on_foreign_keys(
}
}
- buf2 += sprintf(buf2, ") REFER %s(",
+ buf2 += sprintf(buf2, ") REFER %.500s(",
foreign->referenced_table_name);
for (i = 0; i < foreign->n_fields; i++) {
- buf2 += sprintf(buf2, "%s",
+ if ((ulint)(buf2 - buf) >= len) {
+ goto no_space;
+ }
+ buf2 += sprintf(buf2, "%.500s",
foreign->referenced_col_names[i]);
if (i + 1 < foreign->n_fields) {
buf2 += sprintf(buf2, " ");
@@ -3254,11 +4113,29 @@ dict_print_info_on_foreign_keys(
buf2 += sprintf(buf2, " ON DELETE SET NULL");
}
+ if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) {
+ buf2 += sprintf(buf2, " ON DELETE NO ACTION");
+ }
+
+ if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) {
+ buf2 += sprintf(buf2, " ON UPDATE CASCADE");
+ }
+
+ if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) {
+ buf2 += sprintf(buf2, " ON UPDATE SET NULL");
+ }
+
+ if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) {
+ buf2 += sprintf(buf2, " ON UPDATE NO ACTION");
+ }
+
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
-
+no_space:
mutex_exit(&(dict_sys->mutex));
buf[len - 1] = '\0';
ut_memcpy(str, buf, len);
+
+ mem_free(buf);
}
diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c
index 6d48ddf4d95..48c445fa0c9 100644
--- a/innobase/dict/dict0load.c
+++ b/innobase/dict/dict0load.c
@@ -48,7 +48,7 @@ dict_get_first_table_name_in_db(
mtr_start(&mtr);
- sys_tables = dict_table_get_low("SYS_TABLES");
+ sys_tables = dict_table_get_low((char *) "SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
tuple = dtuple_create(heap, 1);
@@ -127,7 +127,7 @@ dict_print(void)
mtr_start(&mtr);
- sys_tables = dict_table_get_low("SYS_TABLES");
+ sys_tables = dict_table_get_low((char *) "SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur,
@@ -216,7 +216,7 @@ dict_load_columns(
mtr_start(&mtr);
- sys_columns = dict_table_get_low("SYS_COLUMNS");
+ sys_columns = dict_table_get_low((char*) "SYS_COLUMNS");
sys_index = UT_LIST_GET_FIRST(sys_columns->indexes);
tuple = dtuple_create(heap, 1);
@@ -246,7 +246,7 @@ dict_load_columns(
ut_ad(len == 4);
ut_a(i == mach_read_from_4(field));
- ut_a(0 == ut_strcmp("NAME",
+ ut_a(0 == ut_strcmp((char*) "NAME",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_columns), 4))->name));
@@ -268,7 +268,7 @@ dict_load_columns(
field = rec_get_nth_field(rec, 7, &len);
col_len = mach_read_from_4(field);
- ut_a(0 == ut_strcmp("PREC",
+ ut_a(0 == ut_strcmp((char*) "PREC",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_columns), 8))->name));
@@ -301,6 +301,8 @@ dict_load_fields(
dtuple_t* tuple;
dfield_t* dfield;
char* col_name;
+ ulint pos_and_prefix_len;
+ ulint prefix_len;
rec_t* rec;
byte* field;
ulint len;
@@ -314,7 +316,7 @@ dict_load_fields(
mtr_start(&mtr);
- sys_fields = dict_table_get_low("SYS_FIELDS");
+ sys_fields = dict_table_get_low((char*) "SYS_FIELDS");
sys_index = UT_LIST_GET_FIRST(sys_fields->indexes);
tuple = dtuple_create(heap, 1);
@@ -335,7 +337,7 @@ dict_load_fields(
ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
if (rec_get_deleted_flag(rec)) {
fprintf(stderr,
-"InnoDB: Error: data dictionary entry for table %s is corrupt!\n",
+"InnoDB: Error: data dictionary entry for table %s is corrupt!\n"
"InnoDB: An index field is delete marked.\n",
table->name);
}
@@ -345,10 +347,30 @@ dict_load_fields(
ut_a(ut_memcmp(buf, field, len) == 0);
field = rec_get_nth_field(rec, 1, &len);
- ut_ad(len == 4);
- ut_a(i == mach_read_from_4(field));
+ ut_a(len == 4);
+
+ /* The next field stores the field position in the index
+ and a possible column prefix length if the index field
+ does not contain the whole column. The storage format is
+ like this: if there is at least one prefix field in the index,
+ then the HIGH 2 bytes contain the field number (== i) and the
+ low 2 bytes the prefix length for the field. Otherwise the
+ field number (== i) is contained in the 2 LOW bytes. */
+
+ pos_and_prefix_len = mach_read_from_4(field);
+
+ ut_a((pos_and_prefix_len & 0xFFFF) == i
+ || (pos_and_prefix_len & 0xFFFF0000) == (i << 16));
+
+ if ((i == 0 && pos_and_prefix_len > 0)
+ || (pos_and_prefix_len & 0xFFFF0000) > 0) {
+
+ prefix_len = pos_and_prefix_len & 0xFFFF;
+ } else {
+ prefix_len = 0;
+ }
- ut_a(0 == ut_strcmp("COL_NAME",
+ ut_a(0 == ut_strcmp((char*) "COL_NAME",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_fields), 4))->name));
@@ -359,7 +381,7 @@ dict_load_fields(
ut_memcpy(col_name, field, len);
col_name[len] = '\0';
- dict_mem_index_add_field(index, col_name, 0);
+ dict_mem_index_add_field(index, col_name, 0, prefix_len);
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
@@ -411,7 +433,7 @@ dict_load_indexes(
mtr_start(&mtr);
- sys_indexes = dict_table_get_low("SYS_INDEXES");
+ sys_indexes = dict_table_get_low((char*) "SYS_INDEXES");
sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes);
tuple = dtuple_create(heap, 1);
@@ -456,7 +478,7 @@ dict_load_indexes(
ut_ad(len == 8);
id = mach_read_from_8(field);
- ut_a(0 == ut_strcmp("NAME",
+ ut_a(0 == ut_strcmp((char*)"NAME",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_indexes), 4))->name));
@@ -476,7 +498,7 @@ dict_load_indexes(
field = rec_get_nth_field(rec, 7, &len);
space = mach_read_from_4(field);
- ut_a(0 == ut_strcmp("PAGE_NO",
+ ut_a(0 == ut_strcmp((char*) "PAGE_NO",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_indexes), 8))->name));
@@ -515,7 +537,7 @@ dict_load_indexes(
&& ((type & DICT_CLUSTERED)
|| ((table == dict_sys->sys_tables)
&& (name_len == ut_strlen("ID_IND"))
- && (0 == ut_memcmp(name_buf, "ID_IND",
+ && (0 == ut_memcmp(name_buf, (char*)"ID_IND",
name_len))))) {
/* The index was created in memory already in
@@ -566,6 +588,7 @@ dict_load_table(
char* buf;
ulint space;
ulint n_cols;
+ ulint err;
mtr_t mtr;
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -574,7 +597,7 @@ dict_load_table(
mtr_start(&mtr);
- sys_tables = dict_table_get_low("SYS_TABLES");
+ sys_tables = dict_table_get_low((char *) "SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
tuple = dtuple_create(heap, 1);
@@ -610,7 +633,7 @@ dict_load_table(
return(NULL);
}
- ut_a(0 == ut_strcmp("SPACE",
+ ut_a(0 == ut_strcmp((char *) "SPACE",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_tables), 9))->name));
@@ -618,7 +641,7 @@ dict_load_table(
field = rec_get_nth_field(rec, 9, &len);
space = mach_read_from_4(field);
- ut_a(0 == ut_strcmp("N_COLS",
+ ut_a(0 == ut_strcmp((char *) "N_COLS",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_tables), 4))->name));
@@ -628,7 +651,7 @@ dict_load_table(
table = dict_mem_table_create(name, space, n_cols);
- ut_a(0 == ut_strcmp("ID",
+ ut_a(0 == ut_strcmp((char *) "ID",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_tables), 3))->name));
@@ -674,8 +697,25 @@ dict_load_table(
dict_load_indexes(table, heap);
- ut_a(DB_SUCCESS == dict_load_foreigns(table->name));
+ err = dict_load_foreigns(table->name);
+/*
+ if (err != DB_SUCCESS) {
+
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" InnoDB: Error: could not make a foreign key definition to match\n"
+"InnoDB: the foreign key table or the referenced table!\n"
+"InnoDB: The data dictionary of InnoDB is corrupt. You may need to drop\n"
+"InnoDB: and recreate the foreign key table or the referenced table.\n"
+"InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n"
+"InnoDB: Latest foreign key error printout:\n%s\n", dict_foreign_err_buf);
+
+ mutex_exit(&dict_foreign_err_mutex);
+ }
+*/
mem_heap_free(heap);
return(table);
@@ -829,7 +869,7 @@ dict_load_foreign_cols(
foreign->n_fields * sizeof(void*));
mtr_start(&mtr);
- sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS");
+ sys_foreign_cols = dict_table_get_low((char *) "SYS_FOREIGN_COLS");
sys_index = UT_LIST_GET_FIRST(sys_foreign_cols->indexes);
tuple = dtuple_create(foreign->heap, 1);
@@ -907,7 +947,7 @@ dict_load_foreign(
mtr_start(&mtr);
- sys_foreign = dict_table_get_low("SYS_FOREIGN");
+ sys_foreign = dict_table_get_low((char *) "SYS_FOREIGN");
sys_index = UT_LIST_GET_FIRST(sys_foreign->indexes);
tuple = dtuple_create(heap2, 1);
@@ -978,8 +1018,8 @@ dict_load_foreign(
field = rec_get_nth_field(rec, 4, &len);
- foreign->referenced_table_name = mem_heap_alloc(foreign->heap, 1 + len);
-
+ foreign->referenced_table_name = mem_heap_alloc(foreign->heap,
+ 1 + len);
ut_memcpy(foreign->referenced_table_name, field, len);
foreign->referenced_table_name[len] = '\0';
@@ -988,10 +1028,19 @@ dict_load_foreign(
dict_load_foreign_cols(id, foreign);
+ /* If the foreign table is not yet in the dictionary cache, we
+ have to load it so that we are able to make type comparisons
+ in the next function call. */
+
+ dict_table_get_low(foreign->foreign_table_name);
+
/* Note that there may already be a foreign constraint object in
the dictionary cache for this constraint: then the following
call only sets the pointers in it to point to the appropriate table
- and index objects and frees the newly created object foreign. */
+ and index objects and frees the newly created object foreign.
+ Adding to the cache should always succeed since we are not creating
+ a new foreign key constraint but loading one from the data
+ dictionary. */
err = dict_foreign_add_to_cache(foreign);
@@ -1026,7 +1075,7 @@ dict_load_foreigns(
ut_ad(mutex_own(&(dict_sys->mutex)));
- sys_foreign = dict_table_get_low("SYS_FOREIGN");
+ sys_foreign = dict_table_get_low((char *) "SYS_FOREIGN");
if (sys_foreign == NULL) {
/* No foreign keys defined yet in this database */
diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c
index 9a4c94de885..56efc0a0117 100644
--- a/innobase/dict/dict0mem.c
+++ b/innobase/dict/dict0mem.c
@@ -74,6 +74,8 @@ dict_mem_table_create(
table->auto_inc_lock = mem_heap_alloc(heap, lock_get_size());
+ table->query_cache_inv_trx_id = ut_dulint_zero;
+
UT_LIST_INIT(table->locks);
UT_LIST_INIT(table->foreign_list);
UT_LIST_INIT(table->referenced_list);
@@ -264,10 +266,13 @@ by the column name may be released only after publishing the index. */
void
dict_mem_index_add_field(
/*=====================*/
- dict_index_t* index, /* in: index */
- char* name, /* in: column name */
- ulint order) /* in: order criterion; 0 means an ascending
- order */
+ dict_index_t* index, /* in: index */
+ char* name, /* in: column name */
+ ulint order, /* in: order criterion; 0 means an
+ ascending order */
+ ulint prefix_len) /* in: 0 or the column prefix length
+ in a MySQL index like
+ INDEX (textcol(25)) */
{
dict_field_t* field;
@@ -280,6 +285,8 @@ dict_mem_index_add_field(
field->name = name;
field->order = order;
+
+ field->prefix_len = prefix_len;
}
/**************************************************************************
diff --git a/innobase/dyn/Makefile.am b/innobase/dyn/Makefile.am
index 79c0000868c..ec33a3c18a9 100644
--- a/innobase/dyn/Makefile.am
+++ b/innobase/dyn/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libdyn.a
+noinst_LIBRARIES = libdyn.a
libdyn_a_SOURCES = dyn0dyn.c
diff --git a/innobase/eval/Makefile.am b/innobase/eval/Makefile.am
index 5dd0eab4c9b..aebffb91be3 100644
--- a/innobase/eval/Makefile.am
+++ b/innobase/eval/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libeval.a
+noinst_LIBRARIES = libeval.a
libeval_a_SOURCES = eval0eval.c eval0proc.c
diff --git a/innobase/eval/eval0eval.c b/innobase/eval/eval0eval.c
index 110387d8373..157d4e4f98d 100644
--- a/innobase/eval/eval0eval.c
+++ b/innobase/eval/eval0eval.c
@@ -164,8 +164,8 @@ eval_logical(
que_node_t* arg1;
que_node_t* arg2;
ibool val1;
- ibool val2;
- ibool val;
+ ibool val2 = 0; /* remove warning */
+ ibool val = 0; /* remove warning */
int func;
ut_ad(que_node_get_type(logical_node) == QUE_NODE_FUNC);
@@ -205,7 +205,7 @@ eval_arith(
que_node_t* arg1;
que_node_t* arg2;
lint val1;
- lint val2;
+ lint val2 = 0; /* remove warning */
lint val;
int func;
@@ -283,7 +283,7 @@ eval_predefined_2(
{
que_node_t* arg;
que_node_t* arg1;
- que_node_t* arg2;
+ que_node_t* arg2 = 0; /* remove warning (??? bug ???) */
lint int_val;
byte* data;
ulint len1;
diff --git a/innobase/fil/Makefile.am b/innobase/fil/Makefile.am
index a9473fdb762..dc0baff7d1a 100644
--- a/innobase/fil/Makefile.am
+++ b/innobase/fil/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libfil.a
+noinst_LIBRARIES = libfil.a
libfil_a_SOURCES = fil0fil.c
diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c
index 29bd52ff94f..f55df90846c 100644
--- a/innobase/fil/fil0fil.c
+++ b/innobase/fil/fil0fil.c
@@ -632,7 +632,7 @@ fil_space_create(
/* Spaces with an odd id number are reserved to replicate spaces
used in log debugging */
- ut_a((purpose == FIL_LOG) || (id % 2 == 0));
+ ut_anp((purpose == FIL_LOG) || (id % 2 == 0));
#endif
mutex_enter(&(system->mutex));
@@ -831,6 +831,34 @@ fil_space_release_free_extents(
mutex_exit(&(system->mutex));
}
+/***********************************************************************
+Gets the number of reserved extents. If the database is silent, this number
+should be zero. */
+
+ulint
+fil_space_get_n_reserved_extents(
+/*=============================*/
+ ulint id) /* in: space id */
+{
+ fil_space_t* space;
+ fil_system_t* system = fil_system;
+ ulint n;
+
+ ut_ad(system);
+
+ mutex_enter(&(system->mutex));
+
+ HASH_SEARCH(hash, system->spaces, id, space, space->id == id);
+
+ ut_a(space);
+
+ n = space->n_reserved_extents;
+
+ mutex_exit(&(system->mutex));
+
+ return(n);
+}
+
/************************************************************************
Prepares a file node for i/o. Opens the file if it is closed. Updates the
pending i/o's field in the node and the system appropriately. Takes the node
@@ -967,6 +995,7 @@ fil_extend_last_data_file(
fil_node_t* node;
fil_space_t* space;
fil_system_t* system = fil_system;
+ byte* buf2;
byte* buf;
ibool success;
ulint i;
@@ -981,19 +1010,23 @@ fil_extend_last_data_file(
fil_node_prepare_for_io(node, system, space);
- buf = mem_alloc(1024 * 1024);
+ buf2 = mem_alloc(1024 * 1024 + UNIV_PAGE_SIZE);
+ buf = ut_align(buf2, UNIV_PAGE_SIZE);
memset(buf, '\0', 1024 * 1024);
for (i = 0; i < size_increase / ((1024 * 1024) / UNIV_PAGE_SIZE); i++) {
- success = os_file_write(node->name, node->handle, buf,
+ /* If we use native Windows aio, then also this write is
+ done using it */
+
+ success = os_aio(OS_FILE_WRITE, OS_AIO_SYNC,
+ node->name, node->handle, buf,
(node->size << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFF,
node->size >> (32 - UNIV_PAGE_SIZE_SHIFT),
- 1024 * 1024);
+ 1024 * 1024, NULL, NULL);
if (!success) {
-
break;
}
@@ -1003,7 +1036,7 @@ fil_extend_last_data_file(
os_has_said_disk_full = FALSE;
}
- mem_free(buf);
+ mem_free(buf2);
fil_node_complete_io(node, system, OS_FILE_WRITE);
@@ -1197,8 +1230,8 @@ loop:
/* Do aio */
- ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
- ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
+ ut_anp(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_anp((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
/* Queue the aio request */
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
@@ -1290,7 +1323,7 @@ fil_aio_wait(
ut_ad(fil_validate());
if (os_aio_use_native_aio) {
- srv_io_thread_op_info[segment] = "native aio handle";
+ srv_io_thread_op_info[segment] = (char *) "native aio handle";
#ifdef WIN_ASYNC_IO
ret = os_aio_windows_handle(segment, 0, &fil_node, &message,
&type);
@@ -1301,7 +1334,7 @@ fil_aio_wait(
ut_a(0);
#endif
} else {
- srv_io_thread_op_info[segment] = "simulated aio handle";
+ srv_io_thread_op_info[segment] =(char *)"simulated aio handle";
ret = os_aio_simulated_handle(segment, (void**) &fil_node,
&message, &type);
@@ -1309,7 +1342,7 @@ fil_aio_wait(
ut_a(ret);
- srv_io_thread_op_info[segment] = "complete io for fil node";
+ srv_io_thread_op_info[segment] = (char *) "complete io for fil node";
mutex_enter(&(system->mutex));
@@ -1322,10 +1355,11 @@ fil_aio_wait(
/* Do the i/o handling */
if (buf_pool_is_block(message)) {
- srv_io_thread_op_info[segment] = "complete io for buf page";
+ srv_io_thread_op_info[segment] =
+ (char *) "complete io for buf page";
buf_page_io_complete(message);
} else {
- srv_io_thread_op_info[segment] = "complete io for log";
+ srv_io_thread_op_info[segment] =(char *) "complete io for log";
log_io_complete(message);
}
}
@@ -1527,7 +1561,6 @@ fil_page_set_type(
ulint type) /* in: type */
{
ut_ad(page);
- ut_ad((type == FIL_PAGE_INDEX) || (type == FIL_PAGE_UNDO_LOG));
mach_write_to_2(page + FIL_PAGE_TYPE, type);
}
diff --git a/innobase/fsp/Makefile.am b/innobase/fsp/Makefile.am
index b3e9ab44d9b..edf06bda0d6 100644
--- a/innobase/fsp/Makefile.am
+++ b/innobase/fsp/Makefile.am
@@ -18,7 +18,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libfsp.a
+noinst_LIBRARIES = libfsp.a
libfsp_a_SOURCES = fsp0fsp.c
diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c
index 10370731edf..8727c5156e4 100644
--- a/innobase/fsp/fsp0fsp.c
+++ b/innobase/fsp/fsp0fsp.c
@@ -769,6 +769,8 @@ fsp_init_file_page_low(
#endif
page = buf_frame_align(ptr);
+ buf_block_align(page)->check_index_page_at_flush = FALSE;
+
#ifdef UNIV_BASIC_LOG_DEBUG
/* printf("In log debug version: Erase the contents of the file page\n");
*/
@@ -776,7 +778,7 @@ fsp_init_file_page_low(
page[i] = 0xFF;
}
#endif
- mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN,
+ mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
ut_dulint_zero);
mach_write_to_8(page + FIL_PAGE_LSN, ut_dulint_zero);
}
@@ -803,7 +805,7 @@ fsp_parse_init_file_page(
/*=====================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page) /* in: page or NULL */
{
ut_ad(ptr && end_ptr);
@@ -1097,7 +1099,7 @@ fsp_fill_free_list(
/* Initialize the ibuf page in a separate
mini-transaction because it is low in the latching
- order, and we must be able to release the its latch
+ order, and we must be able to release its latch
before returning from the fsp routine */
mtr_start(&ibuf_mtr);
@@ -1264,7 +1266,12 @@ fsp_alloc_free_page(
free = xdes_find_bit(descr, XDES_FREE_BIT, TRUE,
hint % FSP_EXTENT_SIZE, mtr);
- ut_a(free != ULINT_UNDEFINED);
+ if (free == ULINT_UNDEFINED) {
+
+ ut_print_buf(((byte*)descr) - 500, 1000);
+
+ ut_a(0);
+ }
xdes_set_bit(descr, XDES_FREE_BIT, free, FALSE, mtr);
@@ -1412,7 +1419,12 @@ fsp_free_extent(
descr = xdes_get_descriptor_with_space_hdr(header, space, page, mtr);
- ut_a(xdes_get_state(descr, mtr) != XDES_FREE);
+ if (xdes_get_state(descr, mtr) == XDES_FREE) {
+
+ ut_print_buf(((byte*)descr) - 500, 1000);
+
+ ut_a(0);
+ }
xdes_init(descr, mtr);
@@ -1428,7 +1440,7 @@ fsp_seg_inode_page_get_nth_inode(
/* out: segment inode */
page_t* page, /* in: segment inode page */
ulint i, /* in: inode index on page */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
{
ut_ad(i < FSP_SEG_INODES_PER_PAGE);
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
@@ -1523,6 +1535,10 @@ fsp_alloc_seg_inode_page(
page = buf_page_get(space, page_no, RW_X_LATCH, mtr);
+ buf_block_align(page)->check_index_page_at_flush = FALSE;
+
+ fil_page_set_type(page, FIL_PAGE_INODE);
+
buf_page_dbg_add_level(page, SYNC_FSP_PAGE);
for (i = 0; i < FSP_SEG_INODES_PER_PAGE; i++) {
@@ -1670,7 +1686,7 @@ fseg_get_nth_frag_page_no(
/* out: page number, FIL_NULL if not in use */
fseg_inode_t* inode, /* in: segment inode */
ulint n, /* in: slot index */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr __attribute__((unused))) /* in: mtr handle */
{
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
@@ -1808,7 +1824,7 @@ fseg_create_general(
fsp_header_t* space_header;
fseg_inode_t* inode;
dulint seg_id;
- fseg_header_t* header;
+ fseg_header_t* header = 0; /* remove warning */
rw_lock_t* latch;
ibool success;
page_t* ret = NULL;
@@ -2298,6 +2314,8 @@ fseg_alloc_free_page_low(
fseg_mark_page_used(seg_inode, space, ret_page, mtr);
}
+ buf_reset_check_index_page_at_flush(space, ret_page);
+
return(ret_page);
}
@@ -2461,20 +2479,20 @@ try_again:
n_free = n_free_list_ext + n_free_up;
if (alloc_type == FSP_NORMAL) {
- /* We reserve 1 extent + 4 % of the space size to undo logs
- and 1 extent + 1 % to cleaning operations; NOTE: this source
+ /* We reserve 1 extent + 0.5 % of the space size to undo logs
+ and 1 extent + 0.5 % to cleaning operations; NOTE: this source
code is duplicated in the function below! */
- reserve = 2 + ((size / FSP_EXTENT_SIZE) * 5) / 100;
+ reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200;
if (n_free <= reserve + n_ext) {
goto try_to_extend;
}
} else if (alloc_type == FSP_UNDO) {
- /* We reserve 1 % of the space size to cleaning operations */
+ /* We reserve 0.5 % of the space size to cleaning operations */
- reserve = 1 + ((size / FSP_EXTENT_SIZE) * 1) / 100;
+ reserve = 1 + ((size / FSP_EXTENT_SIZE) * 1) / 200;
if (n_free <= reserve + n_ext) {
@@ -2554,11 +2572,11 @@ fsp_get_available_space_in_free_extents(
n_free = n_free_list_ext + n_free_up;
- /* We reserve 1 extent + 4 % of the space size to undo logs
- and 1 extent + 1 % to cleaning operations; NOTE: this source
+ /* We reserve 1 extent + 0.5 % of the space size to undo logs
+ and 1 extent + 0.5 % to cleaning operations; NOTE: this source
code is duplicated in the function above! */
- reserve = 2 + ((size / FSP_EXTENT_SIZE) * 5) / 100;
+ reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200;
if (reserve > n_free) {
return(0);
@@ -2638,7 +2656,13 @@ fseg_free_page_low(
ulint not_full_n_used;
ulint state;
ulint i;
- char errbuf[200];
+ char errbuf[200];
+
+#ifdef __WIN__
+ dulint desm;
+ dulint segm;
+#endif
+
ut_ad(seg_inode && mtr);
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) ==
@@ -2691,10 +2715,75 @@ fseg_free_page_low(
return;
}
+/*
+ fprintf(stderr,
+"InnoDB: InnoDB is freeing space %lu page %lu,\n"
+"InnoDB: which belongs to descr seg %lu %lu\n"
+"InnoDB: segment %lu %lu.\n",
+ space, page,
+ ut_dulint_get_high(
+ mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr)),
+ ut_dulint_get_low(
+ mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr)),
+ ut_dulint_get_high(
+ mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr)),
+ ut_dulint_get_low(
+ mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr)));
+*/
/* If we get here, the page is in some extent of the segment */
- ut_a(0 == ut_dulint_cmp(
+ if (0 != ut_dulint_cmp(
mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr),
- mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr)));
+ mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr))) {
+
+ ut_sprintf_buf(errbuf, descr, 40);
+ fprintf(stderr,
+"InnoDB: Dump of the tablespace extent descriptor: %s\n", errbuf);
+ ut_sprintf_buf(errbuf, seg_inode, 40);
+ fprintf(stderr,
+"InnoDB: Dump of the segment inode: %s\n", errbuf);
+
+
+#ifndef __WIN__
+
+ fprintf(stderr,
+"InnoDB: Serious error: InnoDB is trying to free space %lu page %lu,\n"
+"InnoDB: which does not belong to segment %lu %lu but belongs\n"
+"InnoDB: to segment %lu %lu.\n",
+ space, page,
+ ut_dulint_get_high(
+ mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr)),
+ ut_dulint_get_low(
+ mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr)),
+ ut_dulint_get_high(
+ mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr)),
+ ut_dulint_get_low(
+ mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr)));
+
+#else
+
+/* More pedantic usage to avoid VC++ 6.0 compiler errors due to inline
+ function expansion issues */
+
+ desm = mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr);
+ segm = mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr);
+
+ fprintf(stderr,
+"InnoDB: Serious error: InnoDB is trying to free space %lu page %lu,\n"
+"InnoDB: which does not belong to segment %lu %lu but belongs\n"
+"InnoDB: to segment %lu %lu.\n",
+ space, page,
+ ut_dulint_get_high(desm),
+ ut_dulint_get_low(desm),
+ ut_dulint_get_high(segm),
+ ut_dulint_get_low(segm));
+
+#endif
+
+ fprintf(stderr,
+"InnoDB: If the InnoDB recovery crashes here, see section 6.1\n"
+"InnoDB: of http://www.innodb.com/ibman.html about forcing recovery.\n");
+ ut_a(0);
+ }
not_full_n_used = mtr_read_ulint(seg_inode + FSEG_NOT_FULL_N_USED,
MLOG_4BYTES, mtr);
@@ -2857,7 +2946,7 @@ fseg_free_step(
freed yet */
ut_a(descr);
- ut_a(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header)
+ ut_anp(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header)
% FSP_EXTENT_SIZE, mtr) == FALSE);
inode = fseg_inode_get(header, mtr);
diff --git a/innobase/fut/Makefile.am b/innobase/fut/Makefile.am
index a4b1e30e03c..839fdb1580e 100644
--- a/innobase/fut/Makefile.am
+++ b/innobase/fut/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libfut.a
+noinst_LIBRARIES = libfut.a
libfut_a_SOURCES = fut0fut.c fut0lst.c
diff --git a/innobase/ha/Makefile.am b/innobase/ha/Makefile.am
index ce846d37622..121bafe167d 100644
--- a/innobase/ha/Makefile.am
+++ b/innobase/ha/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libha.a
+noinst_LIBRARIES = libha.a
libha_a_SOURCES = ha0ha.c hash0hash.c
diff --git a/innobase/ha/ha0ha.c b/innobase/ha/ha0ha.c
index 4489b25ec2b..eb28e15215d 100644
--- a/innobase/ha/ha0ha.c
+++ b/innobase/ha/ha0ha.c
@@ -293,11 +293,13 @@ ha_print_info(
hash_table_t* table) /* in: hash table */
{
hash_cell_t* cell;
-/* ha_node_t* node; */
- ulint nodes = 0;
- ulint cells = 0;
+/*
+ ha_node_t* node;
ulint len = 0;
ulint max_len = 0;
+ ulint nodes = 0;
+*/
+ ulint cells = 0;
ulint n_bufs;
ulint i;
diff --git a/innobase/ibuf/Makefile.am b/innobase/ibuf/Makefile.am
index 1c1d196c40c..fb813d38ee5 100644
--- a/innobase/ibuf/Makefile.am
+++ b/innobase/ibuf/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libibuf.a
+noinst_LIBRARIES = libibuf.a
libibuf_a_SOURCES = ibuf0ibuf.c
diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c
index 9774ffaf589..7c31ca7c320 100644
--- a/innobase/ibuf/ibuf0ibuf.c
+++ b/innobase/ibuf/ibuf0ibuf.c
@@ -170,7 +170,7 @@ dropped! So, there seems to be no problem. */
/**********************************************************************
Validates the ibuf data structures when the caller owns ibuf_mutex. */
-static
+
ibool
ibuf_validate_low(void);
/*===================*/
@@ -292,6 +292,7 @@ ibuf_count_get(
/**********************************************************************
Sets the ibuf count for a given page. */
+#ifdef UNIV_IBUF_DEBUG
static
void
ibuf_count_set(
@@ -306,6 +307,7 @@ ibuf_count_set(
*(ibuf_counts[space] + page_no) = val;
}
+#endif
/**********************************************************************
Creates the insert buffer data structure at a database startup and
@@ -472,19 +474,18 @@ ibuf_data_init_for_space(
table = dict_mem_table_create(buf, space, 2);
- dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table,(char *) "PAGE_NO", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table,(char *) "TYPES", DATA_BINARY, 0, 0, 0);
table->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
dict_table_add_to_cache(table);
- index = dict_mem_index_create(buf, "CLUST_IND", space,
- DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
- 2);
+ index = dict_mem_index_create(buf, (char *) "CLUST_IND", space,
+ DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,2);
- dict_mem_index_add_field(index, "PAGE_NO", 0);
- dict_mem_index_add_field(index, "TYPES", 0);
+ dict_mem_index_add_field(index, (char *) "PAGE_NO", 0, 0);
+ dict_mem_index_add_field(index, (char *) "TYPES", 0, 0);
index->page_no = FSP_IBUF_TREE_ROOT_PAGE_NO;
@@ -538,7 +539,7 @@ ibuf_parse_bitmap_init(
/*===================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -561,7 +562,8 @@ ibuf_bitmap_page_get_bits(
page_t* page, /* in: bitmap page */
ulint page_no,/* in: page whose bits to get */
ulint bit, /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */
- mtr_t* mtr) /* in: mtr containing an x-latch to the bitmap page */
+ mtr_t* mtr __attribute__((unused))) /* in: mtr containing an x-latch
+ to the bitmap page */
{
ulint byte_offset;
ulint bit_offset;
@@ -1293,6 +1295,8 @@ ibuf_add_free_page(
flst_add_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
+ fil_page_set_type(page, FIL_PAGE_IBUF_FREE_LIST);
+
ibuf_data->seg_size++;
ibuf_data->free_list_len++;
@@ -1303,6 +1307,7 @@ ibuf_add_free_page(
ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
TRUE, &mtr);
+
mtr_commit(&mtr);
mutex_exit(&ibuf_mutex);
@@ -2386,7 +2391,7 @@ ibuf_delete_rec(
ut_ad(ibuf_inside());
- success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr);
+ success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr);
if (success) {
#ifdef UNIV_IBUF_DEBUG
@@ -2396,7 +2401,7 @@ ibuf_delete_rec(
return(FALSE);
}
- /* We have to resort to a pessimistic delete from ibuf */
+ /* We have to resort to a pessimistic delete from ibuf */
btr_pcur_store_position(pcur, mtr);
btr_pcur_commit_specify_mtr(pcur, mtr);
@@ -2415,17 +2420,22 @@ ibuf_delete_rec(
fprintf(stderr, "InnoDB: ibuf cursor restoration fails!\n");
fprintf(stderr, "InnoDB: ibuf record inserted to page %lu\n",
page_no);
+ fflush(stderr);
+
rec_print(btr_pcur_get_rec(pcur));
rec_print(pcur->old_rec);
dtuple_print(search_tuple);
rec_print(page_rec_get_next(btr_pcur_get_rec(pcur)));
+ fflush(stdout);
mtr_commit(mtr);
fprintf(stderr, "InnoDB: Validating insert buffer tree:\n");
- ut_a(btr_validate_tree(ibuf_data->index->tree));
- fprintf(stderr, "InnoDB: Ibuf tree ok\n");
+ ut_a(btr_validate_tree(ibuf_data->index->tree));
+
+ fprintf(stderr, "InnoDB: ibuf tree ok\n");
+ fflush(stderr);
}
ut_a(success);
@@ -2612,6 +2622,14 @@ loop:
goto reset_bit;
}
+ /* Do NOT merge to the 4.1 code base! */
+ if (trx_sys_downgrading_from_4_1_1) {
+ fprintf(stderr,
+"InnoDB: Fatal error: you are downgrading from >= 4.1.1 to 4.0, but\n"
+"InnoDB: the insert buffer was not empty.\n");
+ ut_a(0);
+ }
+
if (corruption_noticed) {
rec_sprintf(err_buf, 450, ibuf_rec);
@@ -2691,10 +2709,7 @@ reset_bit:
new_bits, &mtr);
}
}
-
- ibuf_data->n_merges++;
- ibuf_data->n_merged_recs += n_inserts;
-
+
#ifdef UNIV_IBUF_DEBUG
/* printf("Ibuf merge %lu records volume %lu to page no %lu\n",
n_inserts, volume, page_no); */
@@ -2704,6 +2719,14 @@ reset_bit:
mem_heap_free(heap);
+ /* Protect our statistics keeping from race conditions */
+ mutex_enter(&ibuf_mutex);
+
+ ibuf_data->n_merges++;
+ ibuf_data->n_merged_recs += n_inserts;
+
+ mutex_exit(&ibuf_mutex);
+
ibuf_exit();
#ifdef UNIV_IBUF_DEBUG
ut_a(ibuf_count_get(space, page_no) == 0);
@@ -2712,7 +2735,7 @@ reset_bit:
/**********************************************************************
Validates the ibuf data structures when the caller owns ibuf_mutex. */
-static
+
ibool
ibuf_validate_low(void)
/*===================*/
diff --git a/innobase/include/Makefile.am b/innobase/include/Makefile.am
index fd5cc8b1a80..8664f6dfc17 100644
--- a/innobase/include/Makefile.am
+++ b/innobase/include/Makefile.am
@@ -55,5 +55,7 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \
ut0dbg.h ut0lst.h ut0mem.h ut0mem.ic ut0rnd.h ut0rnd.ic \
ut0sort.h ut0ut.h ut0ut.ic
+EXTRA_DIST = Makefile.i
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/innobase/include/Makefile.i b/innobase/include/Makefile.i
index 8c7e9910f26..f3e3fbe989e 100644
--- a/innobase/include/Makefile.i
+++ b/innobase/include/Makefile.i
@@ -1,8 +1,6 @@
# Makefile included in Makefile.am in every subdirectory
-libsdir = ../libs
-
-INCLUDES = -I../../include -I../include
+INCLUDES = -I$(srcdir)/../include -I$(srcdir)/../../include -I../../include
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/innobase/include/btr0btr.h b/innobase/include/btr0btr.h
index 7e9d4b73d90..8606fcd2a5c 100644
--- a/innobase/include/btr0btr.h
+++ b/innobase/include/btr0btr.h
@@ -408,6 +408,19 @@ btr_print_tree(
dict_tree_t* tree, /* in: tree */
ulint width); /* in: print this many entries from start
and end */
+/****************************************************************
+Checks the size and number of fields in a record based on the definition of
+the index. */
+
+ibool
+btr_index_rec_validate(
+/*====================*/
+ /* out: TRUE if ok */
+ rec_t* rec, /* in: index record */
+ dict_index_t* index, /* in: index */
+ ibool dump_on_error); /* in: TRUE if the function
+ should print hex dump of record
+ and page on error */
/******************************************************************
Checks the consistency of an index tree. */
diff --git a/innobase/include/btr0btr.ic b/innobase/include/btr0btr.ic
index 5c1c89e9840..09006828cc9 100644
--- a/innobase/include/btr0btr.ic
+++ b/innobase/include/btr0btr.ic
@@ -89,7 +89,7 @@ btr_page_get_level(
/*===============*/
/* out: level, leaf level == 0 */
page_t* page, /* in: index page */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
{
ut_ad(page && mtr);
@@ -121,7 +121,7 @@ btr_page_get_next(
/*==============*/
/* out: next page number */
page_t* page, /* in: index page */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
{
ut_ad(page && mtr);
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
@@ -155,7 +155,7 @@ btr_page_get_prev(
/*==============*/
/* out: prev page number */
page_t* page, /* in: index page */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
{
ut_ad(page && mtr);
diff --git a/innobase/include/btr0cur.h b/innobase/include/btr0cur.h
index 7039ceba245..31aecef8104 100644
--- a/innobase/include/btr0cur.h
+++ b/innobase/include/btr0cur.h
@@ -188,22 +188,6 @@ btr_cur_pessimistic_insert(
que_thr_t* thr, /* in: query thread or NULL */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
-Updates a secondary index record when the update causes no size
-changes in its fields. The only case when this function is currently
-called is that in a char field characters change to others which
-are identified in the collation order. */
-
-ulint
-btr_cur_update_sec_rec_in_place(
-/*============================*/
- /* out: DB_SUCCESS or error number */
- btr_cur_t* cursor, /* in: cursor on the record to update;
- cursor stays valid and positioned on the
- same record */
- upd_t* update, /* in: update vector */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
Updates a record when the update causes no size changes in its fields. */
ulint
@@ -507,7 +491,13 @@ void
btr_free_externally_stored_field(
/*=============================*/
dict_index_t* index, /* in: index of the data, the index
- tree MUST be X-latched */
+ tree MUST be X-latched; if the tree
+ height is 1, then also the root page
+ must be X-latched! (this is relevant
+ in the case this function is called
+ from purge where 'data' is located on
+ an undo log page, not an index
+ page) */
byte* data, /* in: internally stored data
+ reference to the externally
stored part */
@@ -684,7 +674,13 @@ and sleep this many microseconds in between */
#define BTR_CUR_RETRY_DELETE_N_TIMES 100
#define BTR_CUR_RETRY_SLEEP_TIME 50000
-/* The reference in a field of which data is stored on a different page */
+/* The reference in a field for which data is stored on a different page.
+The reference is at the end of the 'locally' stored part of the field.
+'Locally' means storage in the index record.
+We store locally a long enough prefix of each column so that we can determine
+the ordering parts of each index record without looking into the externally
+stored part. */
+
/*--------------------------------------*/
#define BTR_EXTERN_SPACE_ID 0 /* space id where stored */
#define BTR_EXTERN_PAGE_NO 4 /* page no where stored */
diff --git a/innobase/include/btr0pcur.h b/innobase/include/btr0pcur.h
index 05b55e4491d..9d07dd0de18 100644
--- a/innobase/include/btr0pcur.h
+++ b/innobase/include/btr0pcur.h
@@ -298,6 +298,14 @@ btr_pcur_move_to_prev(
function may release the page latch */
mtr_t* mtr); /* in: mtr */
/*************************************************************
+Moves the persistent cursor to the last record on the same page. */
+UNIV_INLINE
+void
+btr_pcur_move_to_last_on_page(
+/*==========================*/
+ btr_pcur_t* cursor, /* in: persistent cursor */
+ mtr_t* mtr); /* in: mtr */
+/*************************************************************
Moves the persistent cursor to the next user record in the tree. If no user
records are left, the cursor ends up 'after last in tree'. */
UNIV_INLINE
diff --git a/innobase/include/btr0pcur.ic b/innobase/include/btr0pcur.ic
index a60140e4aa9..a1db2cc52dd 100644
--- a/innobase/include/btr0pcur.ic
+++ b/innobase/include/btr0pcur.ic
@@ -285,6 +285,24 @@ btr_pcur_move_to_prev_on_page(
}
/*************************************************************
+Moves the persistent cursor to the last record on the same page. */
+UNIV_INLINE
+void
+btr_pcur_move_to_last_on_page(
+/*==========================*/
+ btr_pcur_t* cursor, /* in: persistent cursor */
+ mtr_t* mtr) /* in: mtr */
+{
+ UT_NOT_USED(mtr);
+ ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
+
+ page_cur_set_after_last(buf_frame_align(btr_pcur_get_rec(cursor)),
+ btr_pcur_get_page_cur(cursor));
+
+ cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
+}
+
+/*************************************************************
Moves the persistent cursor to the next user record in the tree. If no user
records are left, the cursor ends up 'after last in tree'. */
UNIV_INLINE
diff --git a/innobase/include/btr0sea.h b/innobase/include/btr0sea.h
index 14feca5d5c5..ee762a12221 100644
--- a/innobase/include/btr0sea.h
+++ b/innobase/include/btr0sea.h
@@ -234,10 +234,16 @@ struct btr_search_sys_struct{
extern btr_search_sys_t* btr_search_sys;
/* The latch protecting the adaptive search system: this latch protects the
-(1) positions of records on those pages where a hash index has been built.
-NOTE: It does not protect values of non-ordering fields within a record from
-being updated in-place! We can use fact (1) to perform unique searches to
-indexes. */
+(1) hash index;
+(2) columns of a record to which we have a pointer in the hash index;
+
+but does NOT protect:
+
+(3) next record offset field in a record;
+(4) next or previous records on the same page.
+
+Bear in mind (3) and (4) when using the hash index.
+*/
extern rw_lock_t* btr_search_latch_temp;
diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h
index 591c0ec54ab..2963efd6396 100644
--- a/innobase/include/buf0buf.h
+++ b/innobase/include/buf0buf.h
@@ -274,6 +274,15 @@ buf_page_peek_block(
ulint space, /* in: space id */
ulint offset);/* in: page number */
/************************************************************************
+Resets the check_index_page_at_flush field of a page if found in the buffer
+pool. */
+
+void
+buf_reset_check_index_page_at_flush(
+/*================================*/
+ ulint space, /* in: space id */
+ ulint offset);/* in: page number */
+/************************************************************************
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
@@ -355,11 +364,24 @@ to a file. Note that we must be careful to calculate the same value
on 32-bit and 64-bit architectures. */
ulint
-buf_calc_page_checksum(
-/*===================*/
+buf_calc_page_new_checksum(
+/*=======================*/
/* out: checksum */
byte* page); /* in: buffer page */
/************************************************************************
+In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
+looked at the first few bytes of the page. This calculates that old
+checksum.
+NOTE: we must first store the new formula checksum to
+FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
+because this takes that field as an input! */
+
+ulint
+buf_calc_page_old_checksum(
+/*=======================*/
+ /* out: checksum */
+ byte* page); /* in: buffer page */
+/************************************************************************
Checks if a page is corrupt. */
ibool
@@ -463,6 +485,13 @@ buf_print_io(
/*=========*/
char* buf, /* in/out: buffer where to print */
char* buf_end);/* in: buffer end */
+/*************************************************************************
+Returns the ratio in percents of modified pages in the buffer pool /
+database pages in the buffer pool. */
+
+ulint
+buf_get_modified_ratio_pct(void);
+/*============================*/
/**************************************************************************
Refreshes the statistics used to print per-second averages. */
@@ -648,6 +677,14 @@ struct buf_block_struct{
then it can wait for this rw-lock */
buf_block_t* hash; /* node used in chaining to the page
hash table */
+ ibool check_index_page_at_flush;
+ /* TRUE if we know that this is
+ an index page, and want the database
+ to check its consistency before flush;
+ note that there may be pages in the
+ buffer pool which are index pages,
+ but this flag is not set because
+ we do not keep track of all pages */
/* 2. Page flushing fields */
UT_LIST_NODE_T(buf_block_t) flush_list;
@@ -711,8 +748,8 @@ struct buf_block_struct{
bufferfixed, or (2) the thread has an
x-latch on the block */
- /* 5. Hash search fields: NOTE that these fields are protected by
- btr_search_mutex */
+ /* 5. Hash search fields: NOTE that the first 4 fields are NOT
+ protected by any semaphore! */
ulint n_hash_helps; /* counter which controls building
of a new hash index for the page */
@@ -725,6 +762,9 @@ struct buf_block_struct{
whether the leftmost record of several
records with the same prefix should be
indexed in the hash index */
+
+ /* The following 4 fields are protected by btr_search_latch: */
+
ibool is_hashed; /* TRUE if hash index has already been
built on this page; note that it does
not guarantee that the index is
diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic
index 51e2541e04d..7227c79dc6a 100644
--- a/innobase/include/buf0buf.ic
+++ b/innobase/include/buf0buf.ic
@@ -652,9 +652,10 @@ UNIV_INLINE
void
buf_page_dbg_add_level(
/*===================*/
- buf_frame_t* frame, /* in: buffer page where we have acquired
- a latch */
- ulint level) /* in: latching order level */
+ buf_frame_t* frame __attribute__((unused)), /* in: buffer page
+ where we have acquired latch */
+ ulint level __attribute__((unused))) /* in: latching order
+ level */
{
#ifdef UNIV_SYNC_DEBUG
sync_thread_add_level(&(buf_block_align(frame)->lock), level);
diff --git a/innobase/include/buf0lru.h b/innobase/include/buf0lru.h
index 946b6c4e31d..eb9d43d3b93 100644
--- a/innobase/include/buf0lru.h
+++ b/innobase/include/buf0lru.h
@@ -46,6 +46,20 @@ buf_LRU_get_recent_limit(void);
/*==========================*/
/* out: the limit; zero if could not determine it */
/**********************************************************************
+Look for a replaceable block from the end of the LRU list and put it to
+the free list if found. */
+
+ibool
+buf_LRU_search_and_free_block(
+/*==========================*/
+ /* out: TRUE if freed */
+ ulint n_iterations); /* in: how many times this has been called
+ repeatedly without result: a high value means
+ that we should search farther; if value is
+ k < 10, then we only search k/10 * number
+ of pages in the buffer pool from the end
+ of the LRU list */
+/**********************************************************************
Returns a free block from the buf_pool. The block is taken off the
free list. If it is empty, blocks are moved from the end of the
LRU list to the free list. */
@@ -86,17 +100,6 @@ void
buf_LRU_make_block_old(
/*===================*/
buf_block_t* block); /* in: control block */
-/**********************************************************************
-Look for a replaceable block from the end of the LRU list and put it to
-the free list if found. */
-
-ibool
-buf_LRU_search_and_free_block(
-/*==========================*/
- /* out: TRUE if freed */
- ulint n_iterations); /* in: how many times this has been called
- repeatedly without result: a high value
- means that we should search farther */
/**************************************************************************
Validates the LRU list. */
diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h
index e0fb06e5018..2ec94a9517a 100644
--- a/innobase/include/data0data.h
+++ b/innobase/include/data0data.h
@@ -262,6 +262,14 @@ dtuple_set_types_binary(
/*====================*/
dtuple_t* tuple, /* in: data tuple */
ulint n); /* in: number of fields to set */
+/**************************************************************************
+Checks if a dtuple contains an SQL null value. */
+UNIV_INLINE
+ibool
+dtuple_contains_null(
+/*=================*/
+ /* out: TRUE if some field is SQL null */
+ dtuple_t* tuple); /* in: dtuple */
/**************************************************************
Checks that a data field is typed. Asserts an error if not. */
@@ -453,8 +461,6 @@ struct dfield_struct{
void* data; /* pointer to data */
ulint len; /* data length; UNIV_SQL_NULL if SQL null; */
dtype_t type; /* type of data */
- ulint col_no; /* when building index entries, the column
- number can be stored here */
};
struct dtuple_struct {
diff --git a/innobase/include/data0data.ic b/innobase/include/data0data.ic
index d356664df21..def80d3f430 100644
--- a/innobase/include/data0data.ic
+++ b/innobase/include/data0data.ic
@@ -406,3 +406,28 @@ data_write_sql_null(
data[j] = '\0';
}
}
+
+/**************************************************************************
+Checks if a dtuple contains an SQL null value. */
+UNIV_INLINE
+ibool
+dtuple_contains_null(
+/*=================*/
+ /* out: TRUE if some field is SQL null */
+ dtuple_t* tuple) /* in: dtuple */
+{
+ ulint n;
+ ulint i;
+
+ n = dtuple_get_n_fields(tuple);
+
+ for (i = 0; i < n; i++) {
+ if (dfield_get_len(dtuple_get_nth_field(tuple, i))
+ == UNIV_SQL_NULL) {
+
+ return(TRUE);
+ }
+ }
+
+ return(FALSE);
+}
diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h
index b53a70a8909..4da686bf2e1 100644
--- a/innobase/include/data0type.h
+++ b/innobase/include/data0type.h
@@ -18,14 +18,16 @@ typedef struct dtype_struct dtype_t;
data type */
extern dtype_t* dtype_binary;
-/* Data main types of SQL data; NOTE! character data types requiring
-collation transformation must have the smallest codes! All codes must be
-less than 256! */
+/* Data main types of SQL data */
#define DATA_VARCHAR 1 /* character varying */
#define DATA_CHAR 2 /* fixed length character */
#define DATA_FIXBINARY 3 /* binary string of fixed length */
#define DATA_BINARY 4 /* binary string */
-#define DATA_BLOB 5 /* binary large object */
+#define DATA_BLOB 5 /* binary large object, or a TEXT type; if
+ prtype & DATA_NONLATIN1 != 0 the data must
+ be compared by MySQL as a whole field; if
+ prtype & DATA_BINARY_TYPE == 0, then this is
+ actually a TEXT column */
#define DATA_INT 6 /* integer: can be any size 1 - 8 bytes */
#define DATA_SYS_CHILD 7 /* address of the child page in node pointer */
#define DATA_SYS 8 /* system column */
@@ -34,35 +36,55 @@ binary strings */
#define DATA_FLOAT 9
#define DATA_DOUBLE 10
#define DATA_DECIMAL 11 /* decimal number stored as an ASCII string */
-#define DATA_VARMYSQL 12 /* data types for which comparisons must be */
-#define DATA_MYSQL 13 /* made by MySQL */
-#define DATA_ERROR 111 /* error value */
-#define DATA_MTYPE_MAX 255
+#define DATA_VARMYSQL 12 /* non-latin1 varying length char */
+#define DATA_MYSQL 13 /* non-latin1 fixed length char */
+#define DATA_MTYPE_MAX 63 /* dtype_store_for_order_and_null_size()
+ requires the values are <= 63 */
/*-------------------------------------------*/
-/* Precise data types for system columns; NOTE: the values must run
-from 0 up in the order given! All codes must be less than 256! */
+/* In the lowest byte in the precise type we store the MySQL type code
+(not applicable for system columns). */
+
+#define DATA_ENGLISH 4 /* English language character string: this
+ is a relic from pre-MySQL time and only used
+ for InnoDB's own system tables */
+#define DATA_ERROR 111 /* another relic from pre-MySQL time */
+
+#define DATA_MYSQL_TYPE_MASK 255 /* AND with this mask to extract the MySQL
+ type from the precise type */
+
+/* Precise data types for system columns and the length of those columns;
+NOTE: the values must run from 0 up in the order given! All codes must
+be less than 256 */
#define DATA_ROW_ID 0 /* row id: a dulint */
#define DATA_ROW_ID_LEN 6 /* stored length for row id */
+
#define DATA_TRX_ID 1 /* transaction id: 6 bytes */
#define DATA_TRX_ID_LEN 6
+
#define DATA_ROLL_PTR 2 /* rollback data pointer: 7 bytes */
#define DATA_ROLL_PTR_LEN 7
+
#define DATA_MIX_ID 3 /* mixed index label: a dulint, stored in
a row in a compressed form */
#define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a
compressed dulint form) */
#define DATA_N_SYS_COLS 4 /* number of system columns defined above */
+/*-------------------------------------------*/
+/* Flags ORed to the precise data type */
#define DATA_NOT_NULL 256 /* this is ORed to the precise type when
the column is declared as NOT NULL */
#define DATA_UNSIGNED 512 /* this id ORed to the precise type when
we have an unsigned integer type */
+#define DATA_BINARY_TYPE 1024 /* if the data type is a binary character
+ string, this is ORed to the precise type:
+ this only holds for tables created with
+ >= MySQL-4.0.14 */
+#define DATA_NONLATIN1 2048 /* if the data type is a DATA_BLOB (actually
+ TEXT) of a non-latin1 type, this is ORed to
+ the precise type: this only holds for tables
+ created with >= MySQL-4.0.14 */
/*-------------------------------------------*/
-/* Precise types of a char or varchar data. All codes must be less than 256! */
-#define DATA_ENGLISH 4 /* English language character string */
-#define DATA_FINNISH 5 /* Finnish */
-#define DATA_PRTYPE_MAX 255
-
/* This many bytes we need to store the type information affecting the
alphabetical order for a single field and decide the storage size of an
SQL null*/
@@ -123,7 +145,7 @@ dtype_get_pad_char(
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
- dtype_t* type); /* in: typeumn */
+ dtype_t* type); /* in: type */
/***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE
@@ -150,24 +172,24 @@ dtype_is_fixed_size(
/* out: TRUE if fixed size */
dtype_t* type); /* in: type */
/**************************************************************************
-Stores to a type the information which determines its alphabetical
-ordering. */
+Stores for a type the information which determines its alphabetical ordering
+and the storage size of an SQL NULL value. */
UNIV_INLINE
void
dtype_store_for_order_and_null_size(
/*================================*/
byte* buf, /* in: buffer for DATA_ORDER_NULL_TYPE_BUF_SIZE
- bytes */
+ bytes where we store the info */
dtype_t* type); /* in: type struct */
/**************************************************************************
-Reads of a type the stored information which determines its alphabetical
-ordering. */
+Reads to a type the stored information which determines its alphabetical
+ordering and the storage size of an SQL NULL value. */
UNIV_INLINE
void
dtype_read_for_order_and_null_size(
/*===============================*/
dtype_t* type, /* in: type struct */
- byte* buf); /* in: buffer for type order info */
+ byte* buf); /* in: buffer for the stored order info */
/*************************************************************************
Validates a data type structure. */
diff --git a/innobase/include/data0type.ic b/innobase/include/data0type.ic
index d82d976d076..ddd0b0ae8cc 100644
--- a/innobase/include/data0type.ic
+++ b/innobase/include/data0type.ic
@@ -110,7 +110,9 @@ dtype_get_pad_char(
if (type->mtype == DATA_CHAR
|| type->mtype == DATA_VARCHAR
|| type->mtype == DATA_BINARY
- || type->mtype == DATA_FIXBINARY) {
+ || type->mtype == DATA_FIXBINARY
+ || type->mtype == DATA_MYSQL
+ || type->mtype == DATA_VARMYSQL) {
/* Space is the padding character for all char and binary
strings */
@@ -124,39 +126,56 @@ dtype_get_pad_char(
}
/**************************************************************************
-Stores to a type the information which determines its alphabetical
-ordering. */
+Stores for a type the information which determines its alphabetical ordering
+and the storage size of an SQL NULL value. */
UNIV_INLINE
void
dtype_store_for_order_and_null_size(
/*================================*/
byte* buf, /* in: buffer for DATA_ORDER_NULL_TYPE_BUF_SIZE
- bytes */
+ bytes where we store the info */
dtype_t* type) /* in: type struct */
{
ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE);
buf[0] = (byte)(type->mtype & 0xFF);
+
+ if (type->prtype & DATA_BINARY_TYPE) {
+ buf[0] = buf[0] | 128;
+ }
+
+ if (type->prtype & DATA_NONLATIN1) {
+ buf[0] = buf[0] | 64;
+ }
+
buf[1] = (byte)(type->prtype & 0xFF);
mach_write_to_2(buf + 2, type->len & 0xFFFF);
}
/**************************************************************************
-Reads of a type the stored information which determines its alphabetical
-ordering. */
+Reads to a type the stored information which determines its alphabetical
+ordering and the storage size of an SQL NULL value. */
UNIV_INLINE
void
dtype_read_for_order_and_null_size(
/*===============================*/
dtype_t* type, /* in: type struct */
- byte* buf) /* in: buffer for type order info */
+ byte* buf) /* in: buffer for stored type order info */
{
ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE);
- type->mtype = buf[0];
+ type->mtype = buf[0] & 63;
type->prtype = buf[1];
+ if (buf[0] & 128) {
+ type->prtype = type->prtype | DATA_BINARY_TYPE;
+ }
+
+ if (buf[0] & 64) {
+ type->prtype = type->prtype | DATA_NONLATIN1;
+ }
+
type->len = mach_read_from_2(buf + 2);
}
diff --git a/innobase/include/db0err.h b/innobase/include/db0err.h
index df74b06dfc0..854b9794c00 100644
--- a/innobase/include/db0err.h
+++ b/innobase/include/db0err.h
@@ -41,9 +41,14 @@ Created 5/24/1996 Heikki Tuuri
which is referenced */
#define DB_CANNOT_ADD_CONSTRAINT 38 /* adding a foreign key constraint
to a table failed */
-
-#define DB_COL_APPEARS_TWICE_IN_INDEX 40
-
+#define DB_CORRUPTION 39 /* data structure corruption noticed */
+#define DB_COL_APPEARS_TWICE_IN_INDEX 40 /* InnoDB cannot handle an index
+ where same column appears twice */
+#define DB_CANNOT_DROP_CONSTRAINT 41 /* dropping a foreign key constraint
+ from a table failed */
+#define DB_NO_SAVEPOINT 42 /* no savepoint exists with the given
+ name */
+
/* The following are partial failure codes */
#define DB_FAIL 1000
#define DB_OVERFLOW 1001
diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h
index 832654d2666..b5ec5381db2 100644
--- a/innobase/include/dict0dict.h
+++ b/innobase/include/dict0dict.h
@@ -26,6 +26,18 @@ Created 1/8/1996 Heikki Tuuri
#include "ut0byte.h"
#include "trx0types.h"
+/*************************************************************************
+Accepts a specified string. Comparisons are case-insensitive. */
+
+char*
+dict_accept(
+/*========*/
+ /* out: if string was accepted, the pointer
+ is moved after that, else ptr is returned */
+ char* ptr, /* in: scan from this */
+ const char* string,/* in: accept only this string as the next
+ non-whitespace string */
+ ibool* success);/* out: TRUE if accepted */
/************************************************************************
Decrements the count of open MySQL handles to a table. */
@@ -114,13 +126,20 @@ dict_table_autoinc_get(
/* out: value for a new row, or 0 */
dict_table_t* table); /* in: table */
/************************************************************************
-Reads the autoinc counter value, 0 if not yet initialized. Does not
-increment the counter. */
+Decrements the autoinc counter value by 1. */
+
+void
+dict_table_autoinc_decrement(
+/*=========================*/
+ dict_table_t* table); /* in: table */
+/************************************************************************
+Reads the next autoinc value (== autoinc counter value), 0 if not yet
+initialized. */
ib_longlong
dict_table_autoinc_read(
/*====================*/
- /* out: value of the counter */
+ /* out: value for a new row, or 0 */
dict_table_t* table); /* in: table */
/************************************************************************
Peeks the autoinc counter value, 0 if not yet initialized. Does not
@@ -200,6 +219,24 @@ dict_create_foreign_constraints(
char* name); /* in: table full name in the normalized form
database_name/table_name */
/**************************************************************************
+Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. */
+
+ulint
+dict_foreign_parse_drop_constraints(
+/*================================*/
+ /* out: DB_SUCCESS or
+ DB_CANNOT_DROP_CONSTRAINT if
+ syntax error or the constraint
+ id does not match */
+ mem_heap_t* heap, /* in: heap from which we can
+ allocate memory */
+ trx_t* trx, /* in: transaction */
+ dict_table_t* table, /* in: table */
+ ulint* n, /* out: number of constraints
+ to drop */
+ char*** constraints_to_drop); /* out: id's of the
+ constraints to drop */
+/**************************************************************************
Returns a table object and memoryfixes it. NOTE! This is a high-level
function to be used mainly from outside the 'dict' directory. Inside this
directory dict_table_get_low is usually the appropriate function. */
@@ -314,6 +351,16 @@ dict_print_info_on_foreign_keys(
char* str, /* in/out: pointer to a string */
ulint len, /* in: space in str available for info */
dict_table_t* table); /* in: table */
+/**************************************************************************
+Sprintfs to a string info on a foreign key of a table in a format suitable
+for CREATE TABLE. */
+
+char*
+dict_print_info_on_foreign_key_in_create_format(
+/*============================================*/
+ /* out: how far in buf we printed */
+ dict_foreign_t* foreign,/* in: foreign key constraint */
+ char* buf); /* in: buffer of at least 5000 bytes */
/************************************************************************
Gets the first index on the table (the clustered index). */
UNIV_INLINE
@@ -522,6 +569,29 @@ dict_index_get_nth_col_pos(
dict_index_t* index, /* in: index */
ulint n); /* in: column number */
/************************************************************************
+Returns TRUE if the index contains a column or a prefix of that column. */
+
+ibool
+dict_index_contains_col_or_prefix(
+/*==============================*/
+ /* out: TRUE if contains the column or its
+ prefix */
+ dict_index_t* index, /* in: index */
+ ulint n); /* in: column number */
+/************************************************************************
+Looks for a matching field in an index. The column and the prefix len has
+to be the same. */
+
+ulint
+dict_index_get_nth_field_pos(
+/*=========================*/
+ /* out: position in internal representation
+ of the index; if not contained, returns
+ ULINT_UNDEFINED */
+ dict_index_t* index, /* in: index from which to search */
+ dict_index_t* index2, /* in: index */
+ ulint n); /* in: field number in index2 */
+/************************************************************************
Looks for column n position in the clustered index. */
ulint
@@ -789,9 +859,17 @@ void
dict_mutex_exit_for_mysql(void);
/*===========================*/
+/* The following len must be at least 10000 bytes! */
+#define DICT_FOREIGN_ERR_BUF_LEN 10000
+
+/* Buffers for storing detailed information about the latest foreign key
+and unique key errors */
+extern char* dict_foreign_err_buf;
+extern char* dict_unique_err_buf;
+extern mutex_t dict_foreign_err_mutex; /* mutex protecting the buffers */
extern dict_sys_t* dict_sys; /* the dictionary system */
-extern rw_lock_t dict_foreign_key_check_lock;
+extern rw_lock_t dict_operation_lock;
/* Dictionary system struct */
struct dict_sys_struct{
diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic
index 821465f96a8..c5982c162a7 100644
--- a/innobase/include/dict0dict.ic
+++ b/innobase/include/dict0dict.ic
@@ -106,7 +106,7 @@ dict_table_get_n_sys_cols(
/*======================*/
/* out: number of system (e.g.,
ROW_ID) columns of a table */
- dict_table_t* table) /* in: table */
+ dict_table_t* table __attribute__((unused))) /* in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -203,7 +203,6 @@ dict_index_get_n_fields(
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
- ut_ad(index->cached);
return(index->n_fields);
}
diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h
index cc27f2bad12..03dc913a7c9 100644
--- a/innobase/include/dict0mem.h
+++ b/innobase/include/dict0mem.h
@@ -111,10 +111,13 @@ by the column name may be released only after publishing the index. */
void
dict_mem_index_add_field(
/*=====================*/
- dict_index_t* index, /* in: index */
- char* name, /* in: column name */
- ulint order); /* in: order criterion; 0 means an ascending
- order */
+ dict_index_t* index, /* in: index */
+ char* name, /* in: column name */
+ ulint order, /* in: order criterion; 0 means an
+ ascending order */
+ ulint prefix_len); /* in: 0 or the column prefix length
+ in a MySQL index like
+ INDEX (textcol(25)) */
/**************************************************************************
Frees an index memory object. */
@@ -158,12 +161,18 @@ struct dict_col_struct{
in some of the functions below */
};
+#define DICT_MAX_COL_PREFIX_LEN 512
+
/* Data structure for a field in an index */
struct dict_field_struct{
- dict_col_t* col; /* pointer to the table column */
- char* name; /* name of the column */
- ulint order; /* flags for ordering this field:
- DICT_DESCEND, ... */
+ dict_col_t* col; /* pointer to the table column */
+ char* name; /* name of the column */
+ ulint order; /* flags for ordering this field:
+ DICT_DESCEND, ... */
+ ulint prefix_len; /* 0 or the length of the column
+ prefix in a MySQL index of type, e.g.,
+ INDEX (textcol(25)); must be smaller
+ than DICT_MAX_COL_PREFIX_LEN */
};
/* Data structure for an index tree */
@@ -280,8 +289,15 @@ struct dict_foreign_struct{
table */
};
+/* The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
+a foreign key constraint is enforced, therefore RESTRICT just means no flag */
#define DICT_FOREIGN_ON_DELETE_CASCADE 1
#define DICT_FOREIGN_ON_DELETE_SET_NULL 2
+#define DICT_FOREIGN_ON_UPDATE_CASCADE 4
+#define DICT_FOREIGN_ON_UPDATE_SET_NULL 8
+#define DICT_FOREIGN_ON_DELETE_NO_ACTION 16
+#define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32
+
#define DICT_INDEX_MAGIC_N 76789786
@@ -333,6 +349,13 @@ struct dict_table_struct{
space from the lock heap of the trx:
otherwise the lock heap would grow rapidly
if we do a large insert from a select */
+ dulint query_cache_inv_trx_id;
+ /* transactions whose trx id < than this
+ number are not allowed to store to the MySQL
+ query cache or retrieve from it; when a trx
+ with undo logs commits, it sets this to the
+ value of the trx id counter for the tables it
+ had an IX lock on */
UT_LIST_BASE_NODE_T(lock_t)
locks; /* list of locks on the table */
/*----------------------*/
diff --git a/innobase/include/dyn0dyn.h b/innobase/include/dyn0dyn.h
index cca302994c1..501fde05e90 100644
--- a/innobase/include/dyn0dyn.h
+++ b/innobase/include/dyn0dyn.h
@@ -19,7 +19,6 @@ typedef dyn_block_t dyn_array_t;
/* This is the initial 'payload' size of a dynamic array;
this must be > MLOG_BUF_MARGIN + 30! */
-
#define DYN_ARRAY_DATA_SIZE 512
/*************************************************************************
diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h
index 63e20221c16..ad3149f0b36 100644
--- a/innobase/include/fil0fil.h
+++ b/innobase/include/fil0fil.h
@@ -43,7 +43,10 @@ struct fil_addr_struct{
extern fil_addr_t fil_addr_null;
/* The byte offsets on a file page for various variables */
-#define FIL_PAGE_SPACE 0 /* space id the page belongs to */
+#define FIL_PAGE_SPACE_OR_CHKSUM 0 /* in < MySQL-4.0.14 space id the
+ page belongs to (== 0) but in later
+ versions the 'new' checksum of the
+ page */
#define FIL_PAGE_OFFSET 4 /* page offset inside space */
#define FIL_PAGE_PREV 8 /* if there is a 'natural' predecessor
of the page, its offset */
@@ -64,7 +67,7 @@ extern fil_addr_t fil_addr_null;
#define FIL_PAGE_DATA 38 /* start of the data on the page */
/* File page trailer */
-#define FIL_PAGE_END_LSN 8 /* the low 4 bytes of this are used
+#define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /* the low 4 bytes of this are used
to store the page checksum, the
last 4 bytes should be identical
to the last 4 bytes of FIL_PAGE_LSN */
@@ -73,6 +76,8 @@ extern fil_addr_t fil_addr_null;
/* File page types */
#define FIL_PAGE_INDEX 17855
#define FIL_PAGE_UNDO_LOG 2
+#define FIL_PAGE_INODE 3
+#define FIL_PAGE_IBUF_FREE_LIST 4
/* Space types */
#define FIL_TABLESPACE 501
@@ -381,6 +386,14 @@ fil_space_release_free_extents(
/*===========================*/
ulint id, /* in: space id */
ulint n_reserved); /* in: how many one reserved */
+/***********************************************************************
+Gets the number of reserved extents. If the database is silent, this number
+should be zero. */
+
+ulint
+fil_space_get_n_reserved_extents(
+/*=============================*/
+ ulint id); /* in: space id */
typedef struct fil_space_struct fil_space_t;
diff --git a/innobase/include/ha0ha.ic b/innobase/include/ha0ha.ic
index 1aad7d5a36f..761bc3b20de 100644
--- a/innobase/include/ha0ha.ic
+++ b/innobase/include/ha0ha.ic
@@ -49,7 +49,7 @@ ha_node_t*
ha_chain_get_next(
/*==============*/
/* out: next node, NULL if none */
- hash_table_t* table, /* in: hash table */
+ hash_table_t* table __attribute__((unused)), /* in: hash table */
ha_node_t* node) /* in: hash chain node */
{
ut_ad(table);
diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h
index 80afba97416..5608ba020b7 100644
--- a/innobase/include/lock0lock.h
+++ b/innobase/include/lock0lock.h
@@ -292,16 +292,12 @@ lock_sec_rec_modify_check_and_lock(
dict_index_t* index, /* in: secondary index */
que_thr_t* thr); /* in: query thread */
/*************************************************************************
-Checks if locks of other transactions prevent an immediate read, or passing
-over by a read cursor, of a clustered index record. If they do, first tests
-if the query thread should anyway be suspended for some reason; if not, then
-puts the transaction and the query thread to the lock wait state and inserts a
-waiting request for a record lock to the lock queue. Sets the requested mode
-lock on the record. */
+Like the counterpart for a clustered index below, but now we read a
+secondary index record. */
ulint
-lock_clust_rec_read_check_and_lock(
-/*===============================*/
+lock_sec_rec_read_check_and_lock(
+/*=============================*/
/* out: DB_SUCCESS, DB_LOCK_WAIT,
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
@@ -309,18 +305,24 @@ lock_clust_rec_read_check_and_lock(
rec_t* rec, /* in: user record or page supremum record
which should be read or passed over by a read
cursor */
- dict_index_t* index, /* in: clustered index */
+ dict_index_t* index, /* in: secondary index */
ulint mode, /* in: mode of the lock which the read cursor
should set on records: LOCK_S or LOCK_X; the
latter is possible in SELECT FOR UPDATE */
+ ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ LOCK_REC_NOT_GAP */
que_thr_t* thr); /* in: query thread */
/*************************************************************************
-Like the counterpart for a clustered index above, but now we read a
-secondary index record. */
+Checks if locks of other transactions prevent an immediate read, or passing
+over by a read cursor, of a clustered index record. If they do, first tests
+if the query thread should anyway be suspended for some reason; if not, then
+puts the transaction and the query thread to the lock wait state and inserts a
+waiting request for a record lock to the lock queue. Sets the requested mode
+lock on the record. */
ulint
-lock_sec_rec_read_check_and_lock(
-/*=============================*/
+lock_clust_rec_read_check_and_lock(
+/*===============================*/
/* out: DB_SUCCESS, DB_LOCK_WAIT,
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
@@ -328,10 +330,12 @@ lock_sec_rec_read_check_and_lock(
rec_t* rec, /* in: user record or page supremum record
which should be read or passed over by a read
cursor */
- dict_index_t* index, /* in: secondary index */
+ dict_index_t* index, /* in: clustered index */
ulint mode, /* in: mode of the lock which the read cursor
should set on records: LOCK_S or LOCK_X; the
latter is possible in SELECT FOR UPDATE */
+ ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ LOCK_REC_NOT_GAP */
que_thr_t* thr); /* in: query thread */
/*************************************************************************
Checks that a record is seen in a consistent read. */
@@ -446,6 +450,18 @@ lock_rec_get_mutex_for_addr(
ulint space, /* in: space id */
ulint page_no);/* in: page number */
/*************************************************************************
+Checks that a transaction id is sensible, i.e., not in the future. */
+
+ibool
+lock_check_trx_id_sanity(
+/*=====================*/
+ /* out: TRUE if ok */
+ dulint trx_id, /* in: trx id */
+ rec_t* rec, /* in: user record */
+ dict_index_t* index, /* in: clustered index */
+ ibool has_kernel_mutex);/* in: TRUE if the caller owns the
+ kernel mutex */
+/*************************************************************************
Validates the lock queue on a single record. */
ibool
@@ -509,6 +525,7 @@ lock_validate(void);
extern lock_sys_t* lock_sys;
/* Lock modes and types */
+/* Basic modes */
#define LOCK_NONE 0 /* this flag is used elsewhere to note
consistent read */
#define LOCK_IS 2 /* intention shared */
@@ -519,15 +536,20 @@ extern lock_sys_t* lock_sys;
in an exclusive mode */
#define LOCK_MODE_MASK 0xF /* mask used to extract mode from the
type_mode field in a lock */
+/* Lock types */
#define LOCK_TABLE 16 /* these type values should be so high that */
#define LOCK_REC 32 /* they can be ORed to the lock mode */
#define LOCK_TYPE_MASK 0xF0 /* mask used to extract lock type from the
type_mode field in a lock */
+/* Waiting lock flag */
#define LOCK_WAIT 256 /* this wait bit should be so high that
it can be ORed to the lock mode and type;
when this bit is set, it means that the
lock has not yet been granted, it is just
waiting for its turn in the wait queue */
+/* Precise modes */
+#define LOCK_ORDINARY 0 /* this flag denotes an ordinary next-key lock
+ in contrast to LOCK_GAP or LOCK_REC_NOT_GAP */
#define LOCK_GAP 512 /* this gap bit should be so high that
it can be ORed to the other flags;
when this bit is set, it means that the
@@ -537,7 +559,23 @@ extern lock_sys_t* lock_sys;
the bit is set; locks of this type are created
when records are removed from the index chain
of records */
-
+#define LOCK_REC_NOT_GAP 1024 /* this bit means that the lock is only on
+ the index record and does NOT block inserts
+ to the gap before the index record; this is
+ used in the case when we retrieve a record
+ with a unique key, and is also used in
+ locking plain SELECTs (not part of UPDATE
+ or DELETE) when the user has set the READ
+ COMMITTED isolation level */
+#define LOCK_INSERT_INTENTION 2048 /* this bit is set when we place a waiting
+ gap type record lock request in order to let
+ an insert of an index record to wait until
+ there are no conflicting locks by other
+ transactions on the gap; note that this flag
+ remains set when the waiting lock is granted,
+ or if the lock is inherited to a neighboring
+ record */
+
/* When lock bits are reset, the following flags are available: */
#define LOCK_RELEASE_WAIT 1
#define LOCK_NOT_RELEASE_WAIT 2
diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h
index f200371de9d..24ec28a56e6 100644
--- a/innobase/include/log0log.h
+++ b/innobase/include/log0log.h
@@ -20,7 +20,7 @@ typedef struct log_group_struct log_group_t;
extern ibool log_do_write;
extern ibool log_debug_writes;
-/* Wait modes for log_flush_up_to */
+/* Wait modes for log_write_up_to */
#define LOG_NO_WAIT 91
#define LOG_WAIT_ONE_GROUP 92
#define LOG_WAIT_ALL_GROUPS 93
@@ -157,26 +157,27 @@ log_io_complete(
/*============*/
log_group_t* group); /* in: log group */
/**********************************************************
-Flushes the log files to the disk, using, for example, the Unix fsync.
-This function does the flush even if the user has set
-srv_flush_log_at_trx_commit = FALSE. */
-
-void
-log_flush_to_disk(void);
-/*===================*/
-/**********************************************************
This function is called, e.g., when a transaction wants to commit. It checks
-that the log has been flushed to disk up to the last log entry written by the
-transaction. If there is a flush running, it waits and checks if the flush
-flushed enough. If not, starts a new flush. */
+that the log has been written to the log file up to the last log entry written
+by the transaction. If there is a flush running, it waits and checks if the
+flush flushed enough. If not, starts a new flush. */
void
-log_flush_up_to(
+log_write_up_to(
/*============*/
dulint lsn, /* in: log sequence number up to which the log should
- be flushed, ut_dulint_max if not specified */
- ulint wait); /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
+ be written, ut_dulint_max if not specified */
+ ulint wait, /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
or LOG_WAIT_ALL_GROUPS */
+ ibool flush_to_disk);
+ /* in: TRUE if we want the written log also to be
+ flushed to disk */
+/********************************************************************
+Does a syncronous flush of the log buffer to disk. */
+
+void
+log_buffer_flush_to_disk(void);
+/*==========================*/
/********************************************************************
Advances the smallest lsn for which there are unflushed dirty blocks in the
buffer pool and also may make a new checkpoint. NOTE: this function may only
@@ -512,6 +513,15 @@ log_print(
/*======*/
char* buf, /* in/out: buffer where to print */
char* buf_end);/* in: buffer end */
+/**********************************************************
+Peeks the current lsn. */
+
+ibool
+log_peek_lsn(
+/*=========*/
+ /* out: TRUE if success, FALSE if could not get the
+ log system mutex */
+ dulint* lsn); /* out: if returns TRUE, current lsn is here */
/**************************************************************************
Refreshes the statistics used to print per-second averages. */
@@ -741,27 +751,37 @@ struct log_struct{
be advanced, it is enough that the
write i/o has been completed for all
log groups */
- dulint flush_lsn; /* end lsn for the current flush */
- ulint flush_end_offset;/* the data in buffer has been flushed
+ dulint write_lsn; /* end lsn for the current running
+ write */
+ ulint write_end_offset;/* the data in buffer has been written
up to this offset when the current
- flush ends: this field will then
+ write ends: this field will then
be copied to buf_next_to_write */
- ulint n_pending_writes;/* number of currently pending flush
- writes */
+ dulint current_flush_lsn;/* end lsn for the current running
+ write + flush operation */
+ dulint flushed_to_disk_lsn;
+ /* how far we have written the log
+ AND flushed to disk */
+ ulint n_pending_writes;/* number of currently pending flushes
+ or writes */
+ /* NOTE on the 'flush' in names of the fields below: starting from
+ 4.0.14, we separate the write of the log file and the actual fsync()
+ or other method to flush it to disk. The names below shhould really
+ be 'flush_or_write'! */
os_event_t no_flush_event; /* this event is in the reset state
- when a flush is running; a thread
- should wait for this without owning
- the log mutex, but NOTE that to set or
- reset this event, the thread MUST own
- the log mutex! */
+ when a flush or a write is running;
+ a thread should wait for this without
+ owning the log mutex, but NOTE that
+ to set or reset this event, the
+ thread MUST own the log mutex! */
ibool one_flushed; /* during a flush, this is first FALSE
and becomes TRUE when one log group
- has been flushed */
+ has been written or flushed */
os_event_t one_flushed_event;/* this event is reset when the
- flush has not yet completed for any
- log group; e.g., this means that a
- transaction has been committed when
- this is set; a thread should wait
+ flush or write has not yet completed
+ for any log group; e.g., this means
+ that a transaction has been committed
+ when this is set; a thread should wait
for this without owning the log mutex,
but NOTE that to set or reset this
event, the thread MUST own the log
@@ -774,6 +794,11 @@ struct log_struct{
called */
/* Fields involved in checkpoints */
+ ulint log_group_capacity; /* capacity of the log group; if
+ the checkpoint age exceeds this, it is
+ a serious error because it is possible
+ we will then overwrite log and spoil
+ crash recovery */
ulint max_modified_age_async;
/* when this recommended value for lsn
- buf_pool_get_oldest_modification()
diff --git a/innobase/include/log0recv.h b/innobase/include/log0recv.h
index baa2ba50c7d..e5a5bc05563 100644
--- a/innobase/include/log0recv.h
+++ b/innobase/include/log0recv.h
@@ -333,7 +333,10 @@ extern ibool recv_recovery_on;
extern ibool recv_no_ibuf_operations;
extern ibool recv_needed_recovery;
+extern ibool recv_lsn_checks_on;
+
extern ibool recv_is_making_a_backup;
+extern ulint recv_max_parsed_page_no;
/* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
times! */
diff --git a/innobase/include/mem0mem.h b/innobase/include/mem0mem.h
index bfd25f5bdbe..9ab3b2cd754 100644
--- a/innobase/include/mem0mem.h
+++ b/innobase/include/mem0mem.h
@@ -127,16 +127,18 @@ mem_heap_create_func(
ulint line /* in: line where created */
);
/*********************************************************************
-NOTE: Use the corresponding macro instead of this function.
-Frees the space occupied by a memory heap. */
+NOTE: Use the corresponding macro instead of this function. Frees the space
+occupied by a memory heap. In the debug version erases the heap memory
+blocks. */
UNIV_INLINE
void
mem_heap_free_func(
/*===============*/
- mem_heap_t* heap, /* in, own: heap to be freed */
- char* file_name, /* in: file name where freed */
- ulint line /* in: line where freed */
-);
+ mem_heap_t* heap, /* in, own: heap to be freed */
+ char* file_name __attribute__((unused)),
+ /* in: file name where freed */
+ ulint line __attribute__((unused)));
+ /* in: line where freed */
/*******************************************************************
Allocates n bytes of memory from a memory heap. */
UNIV_INLINE
diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic
index a7abb93d91d..1ff8c66e80a 100644
--- a/innobase/include/mem0mem.ic
+++ b/innobase/include/mem0mem.ic
@@ -440,9 +440,10 @@ void
mem_heap_free_func(
/*===============*/
mem_heap_t* heap, /* in, own: heap to be freed */
- char* file_name, /* in: file name where freed */
- ulint line /* in: line where freed */
- )
+ char* file_name __attribute__((unused)),
+ /* in: file name where freed */
+ ulint line __attribute__((unused)))
+ /* in: line where freed */
{
mem_block_t* block;
mem_block_t* prev_block;
diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h
index d65c7fd47e3..5c52f0e92bf 100644
--- a/innobase/include/os0file.h
+++ b/innobase/include/os0file.h
@@ -111,6 +111,7 @@ log. */
#define OS_WIN31 1
#define OS_WIN95 2
#define OS_WINNT 3
+#define OS_WIN2000 4
extern ulint os_n_file_reads;
extern ulint os_n_file_writes;
@@ -122,7 +123,7 @@ Gets the operating system version. Currently works only on Windows. */
ulint
os_get_os_version(void);
/*===================*/
- /* out: OS_WIN95, OS_WIN31, OS_WINNT (2000 == NT) */
+ /* out: OS_WIN95, OS_WIN31, OS_WINNT, or OS_WIN2000 */
/********************************************************************
Creates the seek mutexes used in positioned reads and writes. */
@@ -145,6 +146,21 @@ os_file_create_simple(
ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */
ibool* success);/* out: TRUE if succeed, FALSE if error */
/********************************************************************
+A simple function to open or create a file. */
+
+os_file_t
+os_file_create_simple_no_error_handling(
+/*====================================*/
+ /* out, own: handle to the file, not defined if error,
+ error number can be retrieved with os_get_last_error */
+ char* name, /* in: name of the file or path as a null-terminated
+ string */
+ ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened
+ (if does not exist, error), or OS_FILE_CREATE if a new
+ file is created (if exists, error) */
+ ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */
+ ibool* success);/* out: TRUE if succeed, FALSE if error */
+/********************************************************************
Opens an existing file or creates a new. */
os_file_t
@@ -159,7 +175,11 @@ os_file_create(
file is created (if exists, error), OS_FILE_OVERWRITE
if a new file is created or an old overwritten */
ulint purpose,/* in: OS_FILE_AIO, if asynchronous, non-buffered i/o
- is desired, OS_FILE_NORMAL, if any normal file */
+ is desired, OS_FILE_NORMAL, if any normal file;
+ NOTE that it also depends on type, os_aio_.. and srv_..
+ variables whether we really use async i/o or
+ unbuffered i/o: look in the function source code for
+ the exact rules */
ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */
ibool* success);/* out: TRUE if succeed, FALSE if error */
/***************************************************************************
@@ -172,6 +192,14 @@ os_file_close(
/* out: TRUE if success */
os_file_t file); /* in, own: handle to a file */
/***************************************************************************
+Closes a file handle. */
+
+ibool
+os_file_close_no_error_handling(
+/*============================*/
+ /* out: TRUE if success */
+ os_file_t file); /* in, own: handle to a file */
+/***************************************************************************
Gets a file size. */
ibool
@@ -300,6 +328,13 @@ os_aio(
are ignored */
void* message2);
/****************************************************************************
+Wakes up all async i/o threads so that they know to exit themselves in
+shutdown. */
+
+void
+os_aio_wake_all_threads_at_shutdown(void);
+/*=====================================*/
+/****************************************************************************
Waits until there are no pending writes in os_aio_write_array. There can
be other, synchronous, pending writes. */
diff --git a/innobase/include/os0proc.h b/innobase/include/os0proc.h
index 9da1f33e070..79750e5c1f7 100644
--- a/innobase/include/os0proc.h
+++ b/innobase/include/os0proc.h
@@ -16,6 +16,15 @@ typedef void* os_process_t;
typedef unsigned long int os_process_id_t;
/********************************************************************
+Converts the current process id to a number. It is not guaranteed that the
+number is unique. In Linux returns the 'process number' of the current
+thread. That number is the same as one sees in 'top', for example. In Linux
+the thread id is not the same as one sees in 'top'. */
+
+ulint
+os_proc_get_number(void);
+/*====================*/
+/********************************************************************
Allocates non-cacheable memory. */
void*
diff --git a/innobase/include/os0sync.h b/innobase/include/os0sync.h
index b2d613c4619..e1cf263216e 100644
--- a/innobase/include/os0sync.h
+++ b/innobase/include/os0sync.h
@@ -10,25 +10,43 @@ Created 9/6/1995 Heikki Tuuri
#define os0sync_h
#include "univ.i"
+#include "ut0lst.h"
#ifdef __WIN__
#define os_fast_mutex_t CRITICAL_SECTION
-typedef void* os_event_t;
-#else
+typedef HANDLE os_native_event_t;
+
+typedef struct os_event_struct os_event_struct_t;
+typedef os_event_struct_t* os_event_t;
+struct os_event_struct {
+ os_native_event_t handle;
+ /* Windows event */
+ UT_LIST_NODE_T(os_event_struct_t) os_event_list;
+ /* list of all created events */
+};
+#else
typedef pthread_mutex_t os_fast_mutex_t;
+
+typedef struct os_event_struct os_event_struct_t;
+typedef os_event_struct_t* os_event_t;
+
struct os_event_struct {
os_fast_mutex_t os_mutex; /* this mutex protects the next
fields */
- ibool is_set; /* this is TRUE if the next mutex is
- not reserved */
+ ibool is_set; /* this is TRUE when the event is
+ in the signaled state, i.e., a thread
+ does not stop if it tries to wait for
+ this event */
+ ib_longlong signal_count; /* this is incremented each time
+ the event becomes signaled */
pthread_cond_t cond_var; /* condition variable is used in
waiting for the event */
+ UT_LIST_NODE_T(os_event_struct_t) os_event_list;
+ /* list of all created events */
};
-typedef struct os_event_struct os_event_struct_t;
-typedef os_event_struct_t* os_event_t;
#endif
typedef struct os_mutex_struct os_mutex_str_t;
@@ -38,10 +56,32 @@ typedef os_mutex_str_t* os_mutex_t;
#define OS_SYNC_TIME_EXCEEDED 1
+/* Mutex protecting counts and the event and OS 'slow' mutex lists */
+extern os_mutex_t os_sync_mutex;
+
+/* This is incremented by 1 in os_thread_create and decremented by 1 in
+os_thread_exit */
+extern ulint os_thread_count;
+
+extern ulint os_event_count;
+extern ulint os_mutex_count;
+extern ulint os_fast_mutex_count;
+
+/*************************************************************
+Initializes global event and OS 'slow' mutex lists. */
+
+void
+os_sync_init(void);
+/*==============*/
/*************************************************************
-Creates an event semaphore, i.e., a semaphore which may
-just have two states: signaled and nonsignaled.
-The created event is manual reset: it must be reset
+Frees created events and OS 'slow' mutexes. */
+
+void
+os_sync_free(void);
+/*==============*/
+/*************************************************************
+Creates an event semaphore, i.e., a semaphore which may just have two states:
+signaled and nonsignaled. The created event is manual reset: it must be reset
explicitly by calling sync_os_reset_event. */
os_event_t
@@ -50,10 +90,10 @@ os_event_create(
/* out: the event handle */
char* name); /* in: the name of the event, if NULL
the event is created without a name */
+#ifdef __WIN__
/*************************************************************
-Creates an auto-reset event semaphore, i.e., an event
-which is automatically reset when a single thread is
-released. */
+Creates an auto-reset event semaphore, i.e., an event which is automatically
+reset when a single thread is released. Works only in Windows. */
os_event_t
os_event_create_auto(
@@ -61,6 +101,7 @@ os_event_create_auto(
/* out: the event handle */
char* name); /* in: the name of the event, if NULL
the event is created without a name */
+#endif
/**************************************************************
Sets an event semaphore to the signaled state: lets waiting threads
proceed. */
@@ -85,7 +126,10 @@ os_event_free(
/*==========*/
os_event_t event); /* in: event to free */
/**************************************************************
-Waits for an event object until it is in the signaled state. */
+Waits for an event object until it is in the signaled state. If
+srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
+waiting thread when the event becomes signaled (or immediately if the
+event is already in the signaled state). */
void
os_event_wait(
@@ -93,7 +137,7 @@ os_event_wait(
os_event_t event); /* in: event to wait */
/**************************************************************
Waits for an event object until it is in the signaled state or
-a timeout is exceeded. */
+a timeout is exceeded. In Unix the timeout is always infinite. */
ulint
os_event_wait_time(
@@ -104,8 +148,9 @@ os_event_wait_time(
os_event_t event, /* in: event to wait */
ulint time); /* in: timeout in microseconds, or
OS_SYNC_INFINITE_TIME */
+#ifdef __WIN__
/**************************************************************
-Waits for any event in an event array. Returns if even a single
+Waits for any event in an OS native event array. Returns if even a single
one is signaled or becomes signaled. */
ulint
@@ -113,14 +158,15 @@ os_event_wait_multiple(
/*===================*/
/* out: index of the event
which was signaled */
- ulint n, /* in: number of events in the
+ ulint n, /* in: number of events in the
array */
- os_event_t* event_array); /* in: pointer to an array of event
+ os_native_event_t* native_event_array);
+ /* in: pointer to an array of event
handles */
+#endif
/*************************************************************
-Creates an operating system mutex semaphore.
-Because these are slow, the mutex semaphore of the database
-itself (sync_mutex_t) should be used where possible. */
+Creates an operating system mutex semaphore. Because these are slow, the
+mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
os_mutex_t
os_mutex_create(
diff --git a/innobase/include/os0sync.ic b/innobase/include/os0sync.ic
index 10b85c435e3..1337e97152a 100644
--- a/innobase/include/os0sync.ic
+++ b/innobase/include/os0sync.ic
@@ -44,4 +44,3 @@ os_fast_mutex_trylock(
#endif
#endif
}
-
diff --git a/innobase/include/os0thread.h b/innobase/include/os0thread.h
index 8355afa46e9..554ca0563e4 100644
--- a/innobase/include/os0thread.h
+++ b/innobase/include/os0thread.h
@@ -15,16 +15,9 @@ Created 9/8/1995 Heikki Tuuri
/* Maximum number of threads which can be created in the program;
this is also the size of the wait slot array for MySQL threads which
can wait inside InnoDB */
-#ifdef __WIN__
-/* Windows 95/98/ME seemed to have difficulties creating the all
-the event semaphores for the wait array slots. If the computer had
-<= 64 MB memory, InnoDB startup could take minutes or even crash.
-That is why we set this to only 1000 in Windows. */
-#define OS_THREAD_MAX_N 1000
-#else
-#define OS_THREAD_MAX_N 10000
-#endif
+#define OS_THREAD_MAX_N srv_max_n_threads
+
/* Possible fixed priorities for threads */
#define OS_THREAD_PRIORITY_NONE 100
@@ -43,7 +36,6 @@ typedef os_thread_t os_thread_id_t; /* In Unix we use the thread
the thread */
#endif
-
/* Define a function pointer type to use in a typecast */
typedef void* (*os_posix_f_t) (void*);
@@ -68,7 +60,9 @@ os_thread_pf(
/********************************************************************
Creates a new thread of execution. The execution starts from
the function given. The start function takes a void* parameter
-and returns a ulint. */
+and returns a ulint.
+NOTE: We count the number of threads in os_thread_exit(). A created
+thread should always use that to exit and not use return() to exit. */
os_thread_t
os_thread_create(
@@ -85,12 +79,13 @@ os_thread_create(
os_thread_id_t* thread_id); /* out: id of the created
thread */
/*********************************************************************
-A thread calling this function ends its execution. */
+Exits the current thread. */
void
os_thread_exit(
/*===========*/
- ulint code); /* in: exit code */
+ void* exit_value); /* in: exit value; in Windows this void*
+ is cast as a DWORD */
/*********************************************************************
Returns the thread identifier of current thread. */
@@ -146,7 +141,6 @@ ulint
os_thread_get_last_error(void);
/*==========================*/
-
#ifndef UNIV_NONINL
#include "os0thread.ic"
#endif
diff --git a/innobase/include/page0cur.h b/innobase/include/page0cur.h
index 144e0e02b21..c3f0decdb4b 100644
--- a/innobase/include/page0cur.h
+++ b/innobase/include/page0cur.h
@@ -26,7 +26,12 @@ Created 10/4/1994 Heikki Tuuri
#define PAGE_CUR_GE 2
#define PAGE_CUR_L 3
#define PAGE_CUR_LE 4
-#define PAGE_CUR_DBG 5
+#define PAGE_CUR_LE_OR_EXTENDS 5 /* This is a search mode used in
+ "column LIKE 'abc%' ORDER BY column DESC";
+ we have to find strings which are <= 'abc' or
+ which extend it */
+#define PAGE_CUR_DBG 6
+
extern ulint page_cur_short_succ;
diff --git a/innobase/include/page0page.h b/innobase/include/page0page.h
index 2f77127466f..04f771c3abd 100644
--- a/innobase/include/page0page.h
+++ b/innobase/include/page0page.h
@@ -666,6 +666,25 @@ page_rec_validate(
/* out: TRUE if ok */
rec_t* rec); /* in: record on the page */
/*******************************************************************
+Checks that the first directory slot points to the infimum record and
+the last to the supremum. This function is intended to track if the
+bug fixed in 4.0.14 has caused corruption to users' databases. */
+
+void
+page_check_dir(
+/*===========*/
+ page_t* page); /* in: index page */
+/*******************************************************************
+This function checks the consistency of an index page when we do not
+know the index. This is also resilient so that this should never crash
+even if the page is total garbage. */
+
+ibool
+page_simple_validate(
+/*=================*/
+ /* out: TRUE if ok */
+ page_t* page); /* in: index page */
+/*******************************************************************
This function checks the consistency of an index page. */
ibool
diff --git a/innobase/include/que0que.h b/innobase/include/que0que.h
index cdaeeae1fde..a3ed18e2b14 100644
--- a/innobase/include/que0que.h
+++ b/innobase/include/que0que.h
@@ -117,6 +117,7 @@ que_thr_stop(
/**************************************************************************
Moves a thread from another state to the QUE_THR_RUNNING state. Increments
the n_active_thrs counters of the query graph and transaction. */
+
void
que_thr_move_to_run_state_for_mysql(
/*================================*/
@@ -125,14 +126,17 @@ que_thr_move_to_run_state_for_mysql(
/**************************************************************************
A patch for MySQL used to 'stop' a dummy query thread used in MySQL
select, when there is no error or lock wait. */
+
void
que_thr_stop_for_mysql_no_error(
/*============================*/
que_thr_t* thr, /* in: query thread */
trx_t* trx); /* in: transaction */
/**************************************************************************
-A patch for MySQL used to 'stop' a dummy query thread used in MySQL
-select. */
+A patch for MySQL used to 'stop' a dummy query thread used in MySQL. The
+query thread is stopped and made inactive, except in the case where
+it was put to the lock wait state in lock0lock.c, but the lock has already
+been granted or the transaction chosen as a victim in deadlock resolution. */
void
que_thr_stop_for_mysql(
diff --git a/innobase/include/read0read.h b/innobase/include/read0read.h
index cebb2d6701c..db6bf888095 100644
--- a/innobase/include/read0read.h
+++ b/innobase/include/read0read.h
@@ -45,6 +45,14 @@ read_view_close(
/*============*/
read_view_t* view); /* in: read view */
/*************************************************************************
+Closes a consistent read view for MySQL. This function is called at an SQL
+statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
+
+void
+read_view_close_for_mysql(
+/*======================*/
+ trx_t* trx); /* in: trx which has a read view */
+/*************************************************************************
Checks if a read view sees the specified transaction. */
UNIV_INLINE
ibool
diff --git a/innobase/include/rem0cmp.h b/innobase/include/rem0cmp.h
index 6f2a99fc8c2..712e263350e 100644
--- a/innobase/include/rem0cmp.h
+++ b/innobase/include/rem0cmp.h
@@ -42,6 +42,22 @@ cmp_data_data(
buffer) */
ulint len2); /* in: data field length or UNIV_SQL_NULL */
/*****************************************************************
+This function is used to compare two data fields for which we know the
+data type. */
+
+int
+cmp_data_data_slow(
+/*===============*/
+ /* out: 1, 0, -1, if data1 is greater, equal,
+ less than data2, respectively */
+ dtype_t* cur_type,/* in: data type of the fields */
+ byte* data1, /* in: data field (== a pointer to a memory
+ buffer) */
+ ulint len1, /* in: data field length or UNIV_SQL_NULL */
+ byte* data2, /* in: data field (== a pointer to a memory
+ buffer) */
+ ulint len2); /* in: data field length or UNIV_SQL_NULL */
+/*****************************************************************
This function is used to compare two dfields where at least the first
has its data type field set. */
UNIV_INLINE
diff --git a/innobase/include/rem0rec.h b/innobase/include/rem0rec.h
index 12e3a8b39d6..b28f39925c1 100644
--- a/innobase/include/rem0rec.h
+++ b/innobase/include/rem0rec.h
@@ -148,12 +148,22 @@ data field in the record. */
byte*
rec_get_nth_field(
/*==============*/
- /* out: pointer to the field, NULL if SQL null */
+ /* out: pointer to the field */
rec_t* rec, /* in: record */
ulint n, /* in: index of the field */
ulint* len); /* out: length of the field; UNIV_SQL_NULL
if SQL null */
/****************************************************************
+Return field length or UNIV_SQL_NULL. */
+UNIV_INLINE
+ulint
+rec_get_nth_field_len(
+/*==================*/
+ /* out: length of the field; UNIV_SQL_NULL if SQL
+ null */
+ rec_t* rec, /* in: record */
+ ulint n); /* in: index of the field */
+/****************************************************************
Gets the physical size of a field. Also an SQL null may have a field of
size > 0, if the data type is of a fixed size. */
UNIV_INLINE
diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic
index aaa3c58a003..9dfd4faeec8 100644
--- a/innobase/include/rem0rec.ic
+++ b/innobase/include/rem0rec.ic
@@ -65,6 +65,24 @@ a field stored to another page: */
#define REC_2BYTE_EXTERN_MASK 0x4000
+/****************************************************************
+Return field length or UNIV_SQL_NULL. */
+UNIV_INLINE
+ulint
+rec_get_nth_field_len(
+/*==================*/
+ /* out: length of the field; UNIV_SQL_NULL if SQL
+ null */
+ rec_t* rec, /* in: record */
+ ulint n) /* in: index of the field */
+{
+ ulint len;
+
+ rec_get_nth_field(rec, n, &len);
+
+ return(len);
+}
+
/***************************************************************
Sets the value of the ith field SQL null bit. */
diff --git a/innobase/include/row0ins.h b/innobase/include/row0ins.h
index cc3b9fa7e9a..a5b4b74e7fc 100644
--- a/innobase/include/row0ins.h
+++ b/innobase/include/row0ins.h
@@ -35,7 +35,6 @@ row_ins_check_foreign_constraint(
dictionary cache if they exist at all */
dict_table_t* table, /* in: if check_ref is TRUE, then the foreign
table, else the referenced table */
- dict_index_t* index, /* in: index in table */
dtuple_t* entry, /* in: index entry for index */
que_thr_t* thr); /* in: query thread */
/*************************************************************************
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index 75c16384458..940b4c61b2f 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -230,18 +230,35 @@ row_update_cascade_for_mysql(
or set null operation */
dict_table_t* table); /* in: table where we do the operation */
/*************************************************************************
-Locks the data dictionary exclusively for performing a table create
-operation. */
+Locks the data dictionary exclusively for performing a table create or other
+data dictionary modification operation. */
void
-row_mysql_lock_data_dictionary(void);
-/*================================*/
+row_mysql_lock_data_dictionary(
+/*===========================*/
+ trx_t* trx); /* in: transaction */
+/*************************************************************************
+Unlocks the data dictionary exclusive lock. */
+
+void
+row_mysql_unlock_data_dictionary(
+/*=============================*/
+ trx_t* trx); /* in: transaction */
+/*************************************************************************
+Locks the data dictionary in shared mode from modifications, for performing
+foreign key check, rollback, or other operation invisible to MySQL. */
+
+void
+row_mysql_freeze_data_dictionary(
+/*=============================*/
+ trx_t* trx); /* in: transaction */
/*************************************************************************
-Unlocks the data dictionary exclusively lock. */
+Unlocks the data dictionary shared lock. */
void
-row_mysql_unlock_data_dictionary(void);
-/*==================================*/
+row_mysql_unfreeze_data_dictionary(
+/*===============================*/
+ trx_t* trx); /* in: transaction */
/*************************************************************************
Does a table creation operation for MySQL. If the name of the created
table ends to characters INNODB_MONITOR, then this also starts
@@ -310,11 +327,9 @@ output by the master thread. */
int
row_drop_table_for_mysql(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- char* name, /* in: table name */
- trx_t* trx, /* in: transaction handle */
- ibool has_dict_mutex);/* in: TRUE if the caller already owns the
- dictionary system mutex */
+ /* out: error code or DB_SUCCESS */
+ char* name, /* in: table name */
+ trx_t* trx); /* in: transaction handle */
/*************************************************************************
Drops a database for MySQL. */
@@ -393,7 +408,10 @@ struct row_prebuilt_struct {
an SQL statement: we may have to set
an intention lock on the table,
create a consistent read view etc. */
- ibool mysql_has_locked;
+ ibool mysql_has_locked; /* this is set TRUE when MySQL
+ calls external_lock on this handle
+ with a lock flag, and set FALSE when
+ with the F_UNLOCK flag */
ibool clust_index_was_generated;
/* if the user did not define a
primary key in MySQL, then Innobase
@@ -401,13 +419,21 @@ struct row_prebuilt_struct {
index where the ordering column is
the row id: in this case this flag
is set to TRUE */
- dict_index_t* index; /* current index for a search, if any */
+ dict_index_t* index; /* current index for a search, if
+ any */
ulint read_just_key; /* set to 1 when MySQL calls
ha_innobase::extra with the
argument HA_EXTRA_KEYREAD; it is enough
to read just columns defined in
the index (i.e., no read of the
clustered index record necessary) */
+ ibool used_in_HANDLER;/* TRUE if we have been using this
+ handle in a MySQL HANDLER low level
+ index cursor command: then we must
+ store the pcur position even in a
+ unique search from a clustered index,
+ because HANDLER allows NEXT and PREV
+ in such a situation */
ulint template_type; /* ROW_MYSQL_WHOLE_ROW,
ROW_MYSQL_REC_FIELDS,
ROW_MYSQL_DUMMY_TEMPLATE, or
@@ -474,7 +500,11 @@ struct row_prebuilt_struct {
fetch many rows from the same cursor:
it saves CPU time to fetch them in a
batch; we reserve mysql_row_len
- bytes for each such row */
+ bytes for each such row; these
+ pointers point 4 bytes past the
+ allocated mem buf start, because
+ there is a 4 byte magic number at the
+ start and at the end */
ulint fetch_cache_first;/* position of the first not yet
fetched row in fetch_cache */
ulint n_fetch_cached; /* number of not yet fetched rows
@@ -483,8 +513,12 @@ struct row_prebuilt_struct {
to this heap */
mem_heap_t* old_vers_heap; /* memory heap where a previous
version is built in consistent read */
+ ulint magic_n2; /* this should be the same as
+ magic_n */
};
+#define ROW_PREBUILT_FETCH_MAGIC_N 465765687
+
#define ROW_MYSQL_WHOLE_ROW 0
#define ROW_MYSQL_REC_FIELDS 1
#define ROW_MYSQL_NO_TEMPLATE 2
diff --git a/innobase/include/row0mysql.ic b/innobase/include/row0mysql.ic
index 6096e5771f7..4ecd66e06ec 100644
--- a/innobase/include/row0mysql.ic
+++ b/innobase/include/row0mysql.ic
@@ -15,7 +15,8 @@ row_mysql_store_var_len(
/*====================*/
/* out: dest + 2 */
byte* dest, /* in: where to store */
- ulint len) /* in: length, must fit in two bytes */
+ ulint len __attribute__((unused))) /* in: length, must fit in two
+ bytes */
{
ut_ad(len < 256 * 256);
/*
@@ -57,7 +58,8 @@ row_mysql_store_col_in_innobase_format(
/*===================================*/
dfield_t* dfield, /* in/out: dfield */
byte* buf, /* in/out: buffer for the converted
- value */
+ value; this must be at least col_len
+ long! */
byte* mysql_data, /* in: MySQL column value, not
SQL NULL; NOTE that dfield may also
get a pointer to mysql_data,
@@ -95,7 +97,6 @@ row_mysql_store_col_in_innobase_format(
while (col_len > 0 && ptr[col_len - 1] == ' ') {
col_len--;
}
-
} else if (type == DATA_BLOB) {
ptr = row_mysql_read_blob_ref(&col_len, mysql_data, col_len);
}
diff --git a/innobase/include/row0row.h b/innobase/include/row0row.h
index 09a79e19fd7..d1befbbbad3 100644
--- a/innobase/include/row0row.h
+++ b/innobase/include/row0row.h
@@ -86,9 +86,10 @@ dtuple_t*
row_build(
/*======*/
/* out, own: row built; see the NOTE below! */
- ulint type, /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
- the former copies also the data fields to
- heap as the latter only places pointers to
+ ulint type, /* in: ROW_COPY_POINTERS, ROW_COPY_DATA, or
+ ROW_COPY_ALSO_EXTERNALS,
+ the two last copy also the data fields to
+ heap as the first only places pointers to
data fields on the index page, and thus is
more efficient */
dict_index_t* index, /* in: clustered index */
diff --git a/innobase/include/row0sel.h b/innobase/include/row0sel.h
index a64d3f8e425..5ef7ff9399a 100644
--- a/innobase/include/row0sel.h
+++ b/innobase/include/row0sel.h
@@ -87,9 +87,11 @@ row_printf_step(
/* out: query thread to run next or NULL */
que_thr_t* thr); /* in: query thread */
/********************************************************************
-Converts a key value stored in MySQL format to an Innobase dtuple.
-The last field of the key value may be just a prefix of a fixed length
-field: hence the parameter key_len. */
+Converts a key value stored in MySQL format to an Innobase dtuple. The last
+field of the key value may be just a prefix of a fixed length field: hence
+the parameter key_len. But currently we do not allow search keys where the
+last field is only a prefix of the full key field len and print a warning if
+such appears. */
void
row_sel_convert_mysql_key_to_innobase(
@@ -100,6 +102,7 @@ row_sel_convert_mysql_key_to_innobase(
to index! */
byte* buf, /* in: buffer to use in field
conversions */
+ ulint buf_len, /* in: buffer length */
dict_index_t* index, /* in: index of the key value */
byte* key_ptr, /* in: MySQL key value */
ulint key_len); /* in: MySQL key value length */
@@ -133,6 +136,18 @@ row_search_for_mysql(
then prebuilt must have a pcur
with stored position! In opening of a
cursor 'direction' should be 0. */
+/***********************************************************************
+Checks if MySQL at the moment is allowed for this table to retrieve a
+consistent read result, or store it to the query cache. */
+
+ibool
+row_search_check_if_query_cache_permitted(
+/*======================================*/
+ /* out: TRUE if storing or retrieving from
+ the query cache is permitted */
+ trx_t* trx, /* in: transaction object */
+ char* norm_name); /* in: concatenation of database name, '/'
+ char, table name */
/* A structure for caching column values for prefetched rows */
diff --git a/innobase/include/row0upd.h b/innobase/include/row0upd.h
index 9a3e2463267..f5e0a88231f 100644
--- a/innobase/include/row0upd.h
+++ b/innobase/include/row0upd.h
@@ -114,15 +114,17 @@ row_upd_index_write_log(
closed within this function */
mtr_t* mtr); /* in: mtr into whose log to write */
/***************************************************************
-Returns TRUE if row update changes size of some field in index. */
+Returns TRUE if row update changes size of some field in index or if some
+field to be updated is stored externally in rec or update. */
ibool
-row_upd_changes_field_size(
-/*=======================*/
+row_upd_changes_field_size_or_external(
+/*===================================*/
/* out: TRUE if the update changes the size of
- some field in index */
- rec_t* rec, /* in: record in clustered index */
- dict_index_t* index, /* in: clustered index */
+ some field in index or the field is external
+ in rec or update */
+ rec_t* rec, /* in: record in index */
+ dict_index_t* index, /* in: index */
upd_t* update);/* in: update vector */
/***************************************************************
Replaces the new column values stored in the update vector to the record
@@ -170,21 +172,33 @@ Replaces the new column values stored in the update vector to the index entry
given. */
void
-row_upd_index_replace_new_col_vals(
-/*===============================*/
+row_upd_index_replace_new_col_vals_index_pos(
+/*=========================================*/
dtuple_t* entry, /* in/out: index entry where replaced */
- dict_index_t* index, /* in: index; NOTE that may also be a
+ dict_index_t* index, /* in: index; NOTE that this may also be a
non-clustered index */
- upd_t* update); /* in: update vector */
+ upd_t* update, /* in: an update vector built for the index so
+ that the field number in an upd_field is the
+ index position */
+ mem_heap_t* heap); /* in: memory heap to which we allocate and
+ copy the new values, set this as NULL if you
+ do not want allocation */
/***************************************************************
-Replaces the new column values stored in the update vector to the
-clustered index entry given. */
+Replaces the new column values stored in the update vector to the index entry
+given. */
void
-row_upd_clust_index_replace_new_col_vals(
-/*=====================================*/
+row_upd_index_replace_new_col_vals(
+/*===============================*/
dtuple_t* entry, /* in/out: index entry where replaced */
- upd_t* update); /* in: update vector */
+ dict_index_t* index, /* in: index; NOTE that this may also be a
+ non-clustered index */
+ upd_t* update, /* in: an update vector built for the
+ CLUSTERED index so that the field number in
+ an upd_field is the clustered index position */
+ mem_heap_t* heap); /* in: memory heap to which we allocate and
+ copy the new values, set this as NULL if you
+ do not want allocation */
/***************************************************************
Checks if an update vector changes an ordering field of an index record.
This function is fast if the update vector is short or the number of ordering
@@ -203,7 +217,9 @@ row_upd_changes_ord_field_binary(
known when this function is called, e.g., at
compile time */
dict_index_t* index, /* in: index of the record */
- upd_t* update);/* in: update vector for the row */
+ upd_t* update);/* in: update vector for the row; NOTE: the
+ field numbers in this MUST be clustered index
+ positions! */
/***************************************************************
Checks if an update vector changes an ordering field of an index record.
This function is fast if the update vector is short or the number of ordering
@@ -275,7 +291,10 @@ row_upd_index_parse(
/* Update vector field */
struct upd_field_struct{
- ulint field_no; /* field number in the clustered
+ ulint field_no; /* field number in an index, usually
+ the clustered index, but in updating
+ a secondary index record in btr0cur.c
+ this is the position in the secondary
index */
que_node_t* exp; /* expression for calculating a new
value: it refers to column values and
@@ -312,8 +331,11 @@ struct upd_node_struct{
ibool in_mysql_interface;
/* TRUE if the update node was created
for the MySQL interface */
+ dict_foreign_t* foreign;/* NULL or pointer to a foreign key
+ constraint if this update node is used in
+ doing an ON DELETE or ON UPDATE operation */
upd_node_t* cascade_node;/* NULL or an update node template which
- is used to implement ON DELETE CASCADE
+ is used to implement ON DELETE/UPDATE CASCADE
or ... SET NULL for foreign keys */
mem_heap_t* cascade_heap;/* NULL or a mem heap where the cascade
node is created */
@@ -355,9 +377,9 @@ struct upd_node_struct{
externally in the clustered index record of
row */
ulint n_ext_vec;/* number of fields in ext_vec */
- mem_heap_t* heap; /* memory heap used as auxiliary storage for
- row; this must be emptied after a successful
- update if node->row != NULL */
+ mem_heap_t* heap; /* memory heap used as auxiliary storage;
+ this must be emptied after a successful
+ update */
/*----------------------*/
sym_node_t* table_sym;/* table node in symbol table */
que_node_t* col_assign_list;
diff --git a/innobase/include/row0vers.ic b/innobase/include/row0vers.ic
index aa7a7aa2299..5ece47c35d1 100644
--- a/innobase/include/row0vers.ic
+++ b/innobase/include/row0vers.ic
@@ -60,7 +60,7 @@ row_vers_sec_rec_may_see_older(
/*===========================*/
/* out: FALSE if can be read immediately */
rec_t* rec, /* in: record which should be read or passed */
- dict_index_t* index, /* in: secondary index */
+ dict_index_t* index __attribute__((unused)),/* in: secondary index */
read_view_t* view) /* in: read view */
{
page_t* page;
diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
index f457d52dec7..02d3d3bba0a 100644
--- a/innobase/include/srv0srv.h
+++ b/innobase/include/srv0srv.h
@@ -17,6 +17,8 @@ Created 10/10/1995 Heikki Tuuri
#include "que0types.h"
#include "trx0types.h"
+extern char* srv_main_thread_op_info;
+
/* Buffer which can be used in printing fatal error messages */
extern char srv_fatal_errbuf[];
@@ -28,6 +30,9 @@ extern os_event_t srv_lock_timeout_thread_event;
at a time */
#define SRV_AUTO_EXTEND_INCREMENT (8 * ((1024 * 1024) / UNIV_PAGE_SIZE))
+/* This is set to TRUE if the MySQL user has set it in MySQL */
+extern ibool srv_lower_case_table_names;
+
/* Server parameters which are read from the initfile */
extern char* srv_data_home;
@@ -57,8 +62,6 @@ extern ulint srv_flush_log_at_trx_commit;
extern byte srv_latin1_ordering[256];/* The sort order table of the latin1
character set */
-extern ibool srv_use_native_aio;
-
extern ulint srv_pool_size;
extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size;
@@ -70,11 +73,17 @@ extern dulint srv_archive_recovery_limit_lsn;
extern ulint srv_lock_wait_timeout;
-extern char* srv_unix_file_flush_method_str;
+extern char* srv_file_flush_method_str;
extern ulint srv_unix_file_flush_method;
+extern ulint srv_win_file_flush_method;
+
+extern ulint srv_max_dirty_pages_pct;
+
extern ulint srv_force_recovery;
extern ulint srv_thread_concurrency;
+extern ulint srv_max_n_threads;
+
extern lint srv_conc_n_threads;
extern ibool srv_fast_shutdown;
@@ -94,6 +103,7 @@ extern ulint srv_n_rows_read;
extern ibool srv_print_innodb_monitor;
extern ibool srv_print_innodb_lock_monitor;
extern ibool srv_print_innodb_tablespace_monitor;
+extern ibool srv_print_verbose_log;
extern ibool srv_print_innodb_table_monitor;
extern ibool srv_lock_timeout_and_monitor_active;
@@ -147,18 +157,26 @@ extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
/* Array of English strings describing the current state of an
i/o handler thread */
extern char* srv_io_thread_op_info[];
+extern char* srv_io_thread_function[];
typedef struct srv_sys_struct srv_sys_t;
/* The server system */
extern srv_sys_t* srv_sys;
-/* Alternatives for the field flush option in Unix; see the InnoDB manual about
+/* Alternatives for the file flush option in Unix; see the InnoDB manual about
what these mean */
-#define SRV_UNIX_FDATASYNC 1
+#define SRV_UNIX_FDATASYNC 1 /* This is the default; it is currently mapped
+ to a call of fsync() because fdatasync()
+ seemed to corrupt files in Linux and Solaris */
#define SRV_UNIX_O_DSYNC 2
#define SRV_UNIX_LITTLESYNC 3
#define SRV_UNIX_NOSYNC 4
+#define SRV_UNIX_O_DIRECT 5
+
+/* Alternatives for file i/o in Windows */
+#define SRV_WIN_IO_NORMAL 1
+#define SRV_WIN_IO_UNBUFFERED 2 /* This is the default */
/* Alternatives for srv_force_recovery. Non-zero values are intended
to help the user get a damaged database up so that he can dump intact
@@ -197,6 +215,12 @@ void
srv_init(void);
/*==========*/
/*************************************************************************
+Frees the OS fast mutex created in srv_init(). */
+
+void
+srv_free(void);
+/*==========*/
+/*************************************************************************
Initializes the synchronization primitives, memory system, and the thread
local storage. */
@@ -310,15 +334,17 @@ srv_conc_exit_innodb(
trx_t* trx); /* in: transaction object associated with the
thread */
/*******************************************************************
-Puts a MySQL OS thread to wait for a lock to be released. */
+Puts a MySQL OS thread to wait for a lock to be released. If an error
+occurs during the wait trx->error_state associated with thr is
+!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
+are possible errors. DB_DEADLOCK is returned if selective deadlock
+resolution chose this transaction as a victim. */
-ibool
+void
srv_suspend_mysql_thread(
/*=====================*/
- /* out: TRUE if the lock wait timeout was
- exceeded */
- que_thr_t* thr); /* in: query thread associated with
- the MySQL OS thread */
+ que_thr_t* thr); /* in: query thread associated with the MySQL
+ OS thread */
/************************************************************************
Releases a MySQL OS thread waiting for a lock to be released, if the
thread is already suspended. */
@@ -406,3 +432,4 @@ struct srv_sys_struct{
extern ulint srv_n_threads_active[];
#endif
+
diff --git a/innobase/include/srv0start.h b/innobase/include/srv0start.h
index 646d2c1bb06..8d2c3fa12c5 100644
--- a/innobase/include/srv0start.h
+++ b/innobase/include/srv0start.h
@@ -79,15 +79,19 @@ innobase_shutdown_for_mysql(void);
/*=============================*/
/* out: DB_SUCCESS or error code */
+extern ulint srv_sizeof_trx_t_in_ha_innodb_cc;
+
+extern ibool srv_is_being_started;
extern ibool srv_startup_is_before_trx_rollback_phase;
extern ibool srv_is_being_shut_down;
/* At a shutdown the value first climbs from 0 to SRV_SHUTDOWN_CLEANUP
-and then to SRV_SHUTDOWN_LAST_PHASE */
+and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
extern ulint srv_shutdown_state;
-#define SRV_SHUTDOWN_CLEANUP 1
-#define SRV_SHUTDOWN_LAST_PHASE 2
+#define SRV_SHUTDOWN_CLEANUP 1
+#define SRV_SHUTDOWN_LAST_PHASE 2
+#define SRV_SHUTDOWN_EXIT_THREADS 3
#endif
diff --git a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h
index 7ad38f5bc7f..5aa3dcdffc3 100644
--- a/innobase/include/sync0rw.h
+++ b/innobase/include/sync0rw.h
@@ -335,7 +335,8 @@ ibool
rw_lock_own(
/*========*/
rw_lock_t* lock, /* in: rw-lock */
- ulint lock_type); /* in: lock type */
+ ulint lock_type); /* in: lock type: RW_LOCK_SHARED,
+ RW_LOCK_EX */
/**********************************************************************
Checks if somebody has locked the rw-lock in the specified mode. */
diff --git a/innobase/include/sync0rw.ic b/innobase/include/sync0rw.ic
index 7015ff34b99..36ef0a985ed 100644
--- a/innobase/include/sync0rw.ic
+++ b/innobase/include/sync0rw.ic
@@ -126,7 +126,8 @@ rw_lock_s_lock_low(
/*===============*/
/* out: TRUE if success */
rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will be
+ ulint pass __attribute__((unused)),
+ /* in: pass value; != 0, if the lock will be
passed to another thread to unlock */
char* file_name, /* in: file name where lock requested */
ulint line) /* in: line where requested */
diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h
index 5bfa0bc2d48..320f8faf12d 100644
--- a/innobase/include/sync0sync.h
+++ b/innobase/include/sync0sync.h
@@ -371,10 +371,12 @@ or row lock! */
#define SYNC_NO_ORDER_CHECK 3000 /* this can be used to suppress
latching order checking */
#define SYNC_LEVEL_NONE 2000 /* default: level not defined */
-#define SYNC_FOREIGN_KEY_CHECK 1001
+#define SYNC_DICT_OPERATION 1001 /* table create, drop, etc. reserve
+ this in X-mode, implicit or backround
+ operations purge, rollback, foreign
+ key checks reserve this in S-mode */
#define SYNC_DICT 1000
#define SYNC_DICT_AUTOINC_MUTEX 999
-#define SYNC_PURGE_IS_RUNNING 997
#define SYNC_DICT_HEADER 995
#define SYNC_IBUF_HEADER 914
#define SYNC_IBUF_PESS_INSERT_MUTEX 912
diff --git a/innobase/include/trx0purge.h b/innobase/include/trx0purge.h
index 087be2f060e..049c79aec9b 100644
--- a/innobase/include/trx0purge.h
+++ b/innobase/include/trx0purge.h
@@ -111,9 +111,6 @@ struct trx_purge_struct{
of the trx system and it never ends */
que_t* query; /* The query graph which will do the
parallelized purge operation */
- rw_lock_t purge_is_running;/* Purge operation set an x-latch here
- while it is accessing a table: this
- prevents dropping of the table */
rw_lock_t latch; /* The latch protecting the purge view.
A purge operation must acquire an
x-latch here for the instant at which
diff --git a/innobase/include/trx0roll.h b/innobase/include/trx0roll.h
index 820af4cd014..0d7126c9c57 100644
--- a/innobase/include/trx0roll.h
+++ b/innobase/include/trx0roll.h
@@ -177,6 +177,55 @@ trx_general_rollback_for_mysql(
ibool partial,/* in: TRUE if partial rollback requested */
trx_savept_t* savept);/* in: pointer to savepoint undo number, if
partial rollback requested */
+/***********************************************************************
+Rolls back a transaction back to a named savepoint. Modifications after the
+savepoint are undone but InnoDB does NOT release the corresponding locks
+which are stored in memory. If a lock is 'implicit', that is, a new inserted
+row holds a lock where the lock information is carried by the trx id stored in
+the row, these locks are naturally released in the rollback. Savepoints which
+were set after this savepoint are deleted. */
+
+ulint
+trx_rollback_to_savepoint_for_mysql(
+/*================================*/
+ /* out: if no savepoint
+ of the name found then
+ DB_NO_SAVEPOINT,
+ otherwise DB_SUCCESS */
+ trx_t* trx, /* in: transaction handle */
+ char* savepoint_name, /* in: savepoint name */
+ ib_longlong* mysql_binlog_cache_pos);/* out: the MySQL binlog cache
+ position corresponding to this
+ savepoint; MySQL needs this
+ information to remove the
+ binlog entries of the queries
+ executed after the savepoint */
+/***********************************************************************
+Creates a named savepoint. If the transaction is not yet started, starts it.
+If there is already a savepoint of the same name, this call erases that old
+savepoint and replaces it with a new. Savepoints are deleted in a transaction
+commit or rollback. */
+
+ulint
+trx_savepoint_for_mysql(
+/*====================*/
+ /* out: always DB_SUCCESS */
+ trx_t* trx, /* in: transaction handle */
+ char* savepoint_name, /* in: savepoint name */
+ ib_longlong binlog_cache_pos); /* in: MySQL binlog cache
+ position corresponding to this
+ connection at the time of the
+ savepoint */
+/***********************************************************************
+Frees savepoint structs. */
+
+void
+trx_roll_savepoints_free(
+/*=====================*/
+ trx_t* trx, /* in: transaction handle */
+ trx_named_savept_t* savep); /* in: free all savepoints > this one;
+ if this is NULL, free all savepoints
+ of trx */
extern sess_t* trx_dummy_sess;
@@ -207,6 +256,21 @@ struct roll_node_struct{
case of a partial rollback */
};
+/* A savepoint set with SQL's "SAVEPOINT savepoint_id" command */
+struct trx_named_savept_struct{
+ char* name; /* savepoint name */
+ trx_savept_t savept; /* the undo number corresponding to
+ the savepoint */
+ ib_longlong mysql_binlog_cache_pos;
+ /* the MySQL binlog cache position
+ corresponding to this savepoint, not
+ defined if the MySQL binlogging is not
+ enabled */
+ UT_LIST_NODE_T(trx_named_savept_t)
+ trx_savepoints; /* the list of savepoints of a
+ transaction */
+};
+
/* Rollback node states */
#define ROLL_NODE_SEND 1
#define ROLL_NODE_WAIT 2
diff --git a/innobase/include/trx0sys.h b/innobase/include/trx0sys.h
index a54a6424a4f..a8ed675a8a5 100644
--- a/innobase/include/trx0sys.h
+++ b/innobase/include/trx0sys.h
@@ -24,6 +24,18 @@ Created 3/26/1996 Heikki Tuuri
#include "fsp0fsp.h"
#include "read0types.h"
+/* Do NOT merge this to the 4.1 code base! */
+extern ibool trx_sys_downgrading_from_4_1_1;
+
+/********************************************************************
+Do NOT merge this to the 4.1 code base!
+Marks the trx sys header when we have successfully downgraded from the >= 4.1.1
+multiple tablespace format back to the 4.0 format. */
+
+void
+trx_sys_mark_downgraded_from_4_1_1(void);
+/*====================================*/
+
/* In a MySQL replication slave, in crash recovery we store the master log
file name and position here. We have successfully got the updates to InnoDB
up to this position. If .._pos is -1, it means no crash recovery was needed,
@@ -354,8 +366,14 @@ this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
sys header is half-written
to disk, we still may be able
to recover the information */
+#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED (24 + FSEG_HEADER_SIZE)
+ /* If this is set to
+ .._N, then we are
+ DOWNGRADING from >= 4.1.1 to
+ 4.0 */
/*-------------------------------------------------------------*/
#define TRX_SYS_DOUBLEWRITE_MAGIC_N 536853855
+#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N 1783657386
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
diff --git a/innobase/include/trx0sys.ic b/innobase/include/trx0sys.ic
index ada2d8cb19c..343e6d7c2fa 100644
--- a/innobase/include/trx0sys.ic
+++ b/innobase/include/trx0sys.ic
@@ -296,6 +296,16 @@ trx_is_active(
return(FALSE);
}
+ if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) {
+
+ /* There must be corruption: we return TRUE because this
+ function is only called by lock_clust_rec_some_has_impl()
+ and row_vers_impl_x_locked_off_kernel() and they have
+ diagnostic prints in this case */
+
+ return(TRUE);
+ }
+
trx = trx_get_on_id(trx_id);
if (trx && (trx->conc_state == TRX_ACTIVE)) {
diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h
index e1f65e9da0f..6b08b674db8 100644
--- a/innobase/include/trx0trx.h
+++ b/innobase/include/trx0trx.h
@@ -118,6 +118,14 @@ trx_start_if_not_started(
/*=====================*/
trx_t* trx); /* in: transaction */
/*****************************************************************
+Starts the transaction if it is not yet started. Assumes we have reserved
+the kernel mutex! */
+UNIV_INLINE
+void
+trx_start_if_not_started_low(
+/*=========================*/
+ trx_t* trx); /* in: transaction */
+/*****************************************************************
Starts the transaction if it is not yet started. */
void
@@ -149,6 +157,15 @@ trx_commit_for_mysql(
/* out: 0 or error number */
trx_t* trx); /* in: trx handle */
/**************************************************************************
+If required, flushes the log to disk if we called trx_commit_for_mysql()
+with trx->flush_log_later == TRUE. */
+
+ulint
+trx_commit_complete_for_mysql(
+/*==========================*/
+ /* out: 0 or error number */
+ trx_t* trx); /* in: trx handle */
+/**************************************************************************
Marks the latest SQL statement ended. */
void
@@ -319,6 +336,7 @@ struct trx_struct{
time_t start_time; /* time the trx object was created
or the state last time became
TRX_ACTIVE */
+ ulint isolation_level;/* TRX_ISO_REPEATABLE_READ, ... */
ibool check_foreigns; /* normally TRUE, but if the user
wants to suppress foreign key checks,
(in table imports, for example) we
@@ -334,6 +352,11 @@ struct trx_struct{
dulint no; /* transaction serialization number ==
max trx id when the transaction is
moved to COMMITTED_IN_MEMORY state */
+ ibool flush_log_later;/* when we commit the transaction
+ in MySQL's binlog write, we will
+ flush the log to disk later in
+ a separate call */
+ dulint commit_lsn; /* lsn at the time of the commit */
ibool dict_operation; /* TRUE if the trx is used to create
a table, create an index, or drop a
table */
@@ -342,6 +365,9 @@ struct trx_struct{
/*------------------------------*/
void* mysql_thd; /* MySQL thread handle corresponding
to this trx, or NULL */
+ char** mysql_query_str;/* pointer to the field in mysqld_thd
+ which contains the pointer to the
+ current SQL query string */
char* mysql_log_file_name;
/* if MySQL binlog is used, this field
contains a pointer to the latest file
@@ -355,7 +381,8 @@ struct trx_struct{
replication slave, we have here the
master binlog name up to which
replication has processed; otherwise
- this is a pointer to a null character */
+ this is a pointer to a null
+ character */
ib_longlong mysql_master_log_pos;
/* if the database server is a MySQL
replication slave, this is the
@@ -363,6 +390,9 @@ struct trx_struct{
replication has processed */
os_thread_id_t mysql_thread_id;/* id of the MySQL thread associated
with this transaction object */
+ ulint mysql_process_no;/* since in Linux, 'top' reports
+ process id's and not thread id's, we
+ store the process number too */
/*------------------------------*/
ulint n_mysql_tables_in_use; /* number of Innobase tables
used in the processing of the current
@@ -371,9 +401,10 @@ struct trx_struct{
/* how many tables the current SQL
statement uses, except those
in consistent read */
- ibool has_dict_foreign_key_check_lock;
- /* TRUE if the trx currently holds
- an s-lock on dict_foreign_... */
+ ibool dict_operation_lock_mode;
+ /* 0, RW_S_LATCH, or RW_X_LATCH:
+ the latch mode trx currently holds
+ on dict_operation_lock */
ibool has_search_latch;
/* TRUE if this trx has latched the
search system latch in S-mode */
@@ -402,46 +433,17 @@ struct trx_struct{
lock_t* auto_inc_lock; /* possible auto-inc lock reserved by
the transaction; note that it is also
in the lock list trx_locks */
- ibool ignore_duplicates_in_insert;
- /* in an insert roll back only insert
- of the latest row in case
- of a duplicate key error */
UT_LIST_NODE_T(trx_t)
trx_list; /* list of transactions */
UT_LIST_NODE_T(trx_t)
mysql_trx_list; /* list of transactions created for
MySQL */
/*------------------------------*/
- mutex_t undo_mutex; /* mutex protecting the fields in this
- section (down to undo_no_arr), EXCEPT
- last_sql_stat_start, which can be
- accessed only when we know that there
- cannot be any activity in the undo
- logs! */
- dulint undo_no; /* next undo log record number to
- assign */
- trx_savept_t last_sql_stat_start;
- /* undo_no when the last sql statement
- was started: in case of an error, trx
- is rolled back down to this undo
- number; see note at undo_mutex! */
- trx_rseg_t* rseg; /* rollback segment assigned to the
- transaction, or NULL if not assigned
- yet */
- trx_undo_t* insert_undo; /* pointer to the insert undo log, or
- NULL if no inserts performed yet */
- trx_undo_t* update_undo; /* pointer to the update undo log, or
- NULL if no update performed yet */
- dulint roll_limit; /* least undo number to undo during
- a rollback */
- ulint pages_undone; /* number of undo log pages undone
- since the last undo log truncation */
- trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
- records which are currently processed
- by a rollback operation */
- /*------------------------------*/
ulint error_state; /* 0 if no error, otherwise error
- number */
+ number; NOTE That ONLY the thread
+ doing the transaction is allowed to
+ set this field: this is NOT protected
+ by the kernel mutex */
void* error_info; /* if the error number indicates a
duplicate key error, a pointer to
the problematic index is stored here */
@@ -478,6 +480,12 @@ struct trx_struct{
TRX_QUE_LOCK_WAIT, this points to
the lock request, otherwise this is
NULL */
+ ibool was_chosen_as_deadlock_victim;
+ /* when the transaction decides to wait
+ for a lock, this it sets this to FALSE;
+ if another transaction chooses this
+ transaction as a victim in deadlock
+ resolution, it sets this to TRUE */
time_t wait_started; /* lock wait started at this time */
UT_LIST_BASE_NODE_T(que_thr_t)
wait_thrs; /* query threads belonging to this
@@ -493,6 +501,38 @@ struct trx_struct{
/*------------------------------*/
mem_heap_t* read_view_heap; /* memory heap for the read view */
read_view_t* read_view; /* consistent read view or NULL */
+ /*------------------------------*/
+ UT_LIST_BASE_NODE_T(trx_named_savept_t)
+ trx_savepoints; /* savepoints set with SAVEPOINT ...,
+ oldest first */
+ /*------------------------------*/
+ mutex_t undo_mutex; /* mutex protecting the fields in this
+ section (down to undo_no_arr), EXCEPT
+ last_sql_stat_start, which can be
+ accessed only when we know that there
+ cannot be any activity in the undo
+ logs! */
+ dulint undo_no; /* next undo log record number to
+ assign */
+ trx_savept_t last_sql_stat_start;
+ /* undo_no when the last sql statement
+ was started: in case of an error, trx
+ is rolled back down to this undo
+ number; see note at undo_mutex! */
+ trx_rseg_t* rseg; /* rollback segment assigned to the
+ transaction, or NULL if not assigned
+ yet */
+ trx_undo_t* insert_undo; /* pointer to the insert undo log, or
+ NULL if no inserts performed yet */
+ trx_undo_t* update_undo; /* pointer to the update undo log, or
+ NULL if no update performed yet */
+ dulint roll_limit; /* least undo number to undo during
+ a rollback */
+ ulint pages_undone; /* number of undo log pages undone
+ since the last undo log truncation */
+ trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
+ records which are currently processed
+ by a rollback operation */
};
#define TRX_MAX_N_THREADS 32 /* maximum number of concurrent
@@ -515,6 +555,41 @@ struct trx_struct{
#define TRX_QUE_ROLLING_BACK 3 /* transaction is rolling back */
#define TRX_QUE_COMMITTING 4 /* transaction is committing */
+/* Transaction isolation levels */
+#define TRX_ISO_READ_UNCOMMITTED 1 /* dirty read: non-locking
+ SELECTs are performed so that
+ we do not look at a possible
+ earlier version of a record;
+ thus they are not 'consistent'
+ reads under this isolation
+ level; otherwise like level
+ 2 */
+
+#define TRX_ISO_READ_COMMITTED 2 /* somewhat Oracle-like
+ isolation, except that in
+ range UPDATE and DELETE we
+ must block phantom rows
+ with next-key locks;
+ SELECT ... FOR UPDATE and ...
+ LOCK IN SHARE MODE only lock
+ the index records, NOT the
+ gaps before them, and thus
+ allow free inserting;
+ each consistent read reads its
+ own snapshot */
+
+#define TRX_ISO_REPEATABLE_READ 3 /* this is the default;
+ all consistent reads in the
+ same trx read the same
+ snapshot;
+ full next-key locking used
+ in locking reads to block
+ insertions into gaps */
+
+#define TRX_ISO_SERIALIZABLE 4 /* all plain SELECTs are
+ converted to LOCK IN SHARE
+ MODE reads */
+
/* Types of a trx signal */
#define TRX_SIG_NO_SIGNAL 100
#define TRX_SIG_TOTAL_ROLLBACK 1
diff --git a/innobase/include/trx0trx.ic b/innobase/include/trx0trx.ic
index 9d453047600..78e5acda148 100644
--- a/innobase/include/trx0trx.ic
+++ b/innobase/include/trx0trx.ic
@@ -21,3 +21,22 @@ trx_start_if_not_started(
trx_start(trx, ULINT_UNDEFINED);
}
}
+
+/*****************************************************************
+Starts the transaction if it is not yet started. Assumes we have reserved
+the kernel mutex! */
+UNIV_INLINE
+void
+trx_start_if_not_started_low(
+/*=========================*/
+ trx_t* trx) /* in: transaction */
+{
+ ut_ad(trx->conc_state != TRX_COMMITTED_IN_MEMORY);
+
+ if (trx->conc_state == TRX_NOT_STARTED) {
+
+ trx_start_low(trx, ULINT_UNDEFINED);
+ }
+}
+
+
diff --git a/innobase/include/trx0types.h b/innobase/include/trx0types.h
index b8befe7172f..2965eb4451f 100644
--- a/innobase/include/trx0types.h
+++ b/innobase/include/trx0types.h
@@ -24,6 +24,7 @@ typedef struct trx_undo_inf_struct trx_undo_inf_t;
typedef struct trx_purge_struct trx_purge_t;
typedef struct roll_node_struct roll_node_t;
typedef struct commit_node_struct commit_node_t;
+typedef struct trx_named_savept_struct trx_named_savept_t;
/* Transaction savepoint */
typedef struct trx_savept_struct trx_savept_t;
diff --git a/innobase/include/univ.i b/innobase/include/univ.i
index b511ec044a2..4854e5a7b78 100644
--- a/innobase/include/univ.i
+++ b/innobase/include/univ.i
@@ -9,7 +9,8 @@ Created 1/20/1994 Heikki Tuuri
#ifndef univ_i
#define univ_i
-#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER)
+#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__)
+#undef __WIN__
#define __WIN__
#include <windows.h>
@@ -29,7 +30,7 @@ Created 1/20/1994 Heikki Tuuri
in compiling more Posix-compatible. These headers also define __WIN__
if we are compiling on Windows. */
-#include <global.h>
+#include <my_global.h>
#include <my_pthread.h>
/* Include <sys/stat.h> to get S_I... macros defined for os0file.c */
@@ -56,6 +57,7 @@ of the 32-bit x86 assembler in mutex operations. */
Microsoft Visual C++ */
#if !defined(__GNUC__) && !defined(__WIN__)
+#undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */
#define UNIV_MUST_NOT_INLINE
#endif
@@ -98,6 +100,15 @@ memory is read outside the allocated blocks. */
#define YYDEBUG 1
+#ifdef HAVE_purify
+/* The following sets all new allocated memory to zero before use:
+this can be used to eliminate unnecessary Purify warnings, but note that
+it also masks many bugs Purify could detect. For detailed Purify analysis it
+is best to remove the define below and look through the warnings one
+by one. */
+#define UNIV_SET_MEM_TO_ZERO
+#endif
+
/*
#define UNIV_SQL_DEBUG
#define UNIV_LOG_DEBUG
@@ -176,7 +187,11 @@ management to ensure correct alignment for doubles etc. */
/* Another basic type we use is unsigned long integer which is intended to be
equal to the word size of the machine. */
+#ifdef _WIN64
+typedef unsigned __int64 ulint;
+#else
typedef unsigned long int ulint;
+#endif
typedef long int lint;
diff --git a/innobase/include/ut0dbg.h b/innobase/include/ut0dbg.h
index 3407483696c..802557099fc 100644
--- a/innobase/include/ut0dbg.h
+++ b/innobase/include/ut0dbg.h
@@ -20,7 +20,6 @@ extern ibool ut_dbg_stop_threads;
extern ulint* ut_dbg_null_ptr;
-
#define ut_a(EXPR)\
{\
ulint dbg_i;\
@@ -31,8 +30,41 @@ extern ulint* ut_dbg_null_ptr;
" InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\
os_thread_pf(os_thread_get_curr_id()), IB__FILE__,\
(ulint)__LINE__);\
+ fprintf(stderr,\
+ "InnoDB: Failing assertion: " #EXPR);\
fprintf(stderr,\
- "InnoDB: We intentionally generate a memory trap.\n");\
+ "\nInnoDB: We intentionally generate a memory trap.\n");\
+ fprintf(stderr,\
+ "InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n");\
+ ut_dbg_stop_threads = TRUE;\
+ dbg_i = *(ut_dbg_null_ptr);\
+ if (dbg_i) {\
+ ut_dbg_null_ptr = NULL;\
+ }\
+ }\
+ if (ut_dbg_stop_threads) {\
+ fprintf(stderr,\
+ "InnoDB: Thread %lu stopped in file %s line %lu\n",\
+ os_thread_pf(os_thread_get_curr_id()), IB__FILE__, (ulint)__LINE__);\
+ os_thread_sleep(1000000000);\
+ }\
+}
+
+/* This can be used if there are % characters in the assertion formula:
+if we try to printf the formula gcc would complain of illegal print
+format characters */
+#define ut_anp(EXPR)\
+{\
+ ulint dbg_i;\
+\
+ if (!((ulint)(EXPR) + ut_dbg_zero)) {\
+ ut_print_timestamp(stderr);\
+ fprintf(stderr,\
+ " InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\
+ os_thread_pf(os_thread_get_curr_id()), IB__FILE__,\
+ (ulint)__LINE__);\
+ fprintf(stderr,\
+ "\nInnoDB: We intentionally generate a memory trap.\n");\
fprintf(stderr,\
"InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n");\
ut_dbg_stop_threads = TRUE;\
diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h
index 2d245e5f72f..4e8566eba1b 100644
--- a/innobase/include/ut0mem.h
+++ b/innobase/include/ut0mem.h
@@ -57,7 +57,7 @@ ut_free(
/*====*/
void* ptr); /* in, own: memory block */
/**************************************************************************
-Frees all allocated memory not freed yet. */
+Frees in shutdown all allocated memory not freed yet. */
void
ut_free_all_mem(void);
@@ -69,7 +69,7 @@ ut_strcpy(char* dest, char* sour);
UNIV_INLINE
ulint
-ut_strlen(char* str);
+ut_strlen(const char* str);
UNIV_INLINE
int
diff --git a/innobase/include/ut0mem.ic b/innobase/include/ut0mem.ic
index 7ae9bc8bd74..1049aee8ecc 100644
--- a/innobase/include/ut0mem.ic
+++ b/innobase/include/ut0mem.ic
@@ -36,7 +36,7 @@ ut_strcpy(char* dest, char* sour)
UNIV_INLINE
ulint
-ut_strlen(char* str)
+ut_strlen(const char* str)
{
return(strlen(str));
}
diff --git a/innobase/lock/Makefile.am b/innobase/lock/Makefile.am
index f9e1b227f3c..549eb2604e3 100644
--- a/innobase/lock/Makefile.am
+++ b/innobase/lock/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = liblock.a
+noinst_LIBRARIES = liblock.a
liblock_a_SOURCES = lock0lock.c
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index c180ecb50ce..4b39368c540 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -14,6 +14,8 @@ Created 5/7/1996 Heikki Tuuri
#include "usr0sess.h"
#include "trx0purge.h"
+#include "dict0mem.h"
+#include "trx0sys.h"
/* Restricts the length of search we will do in the waits-for
graph of transactions */
@@ -53,10 +55,9 @@ bump into an x-lock set there.
Different transaction can have conflicting locks set on the gap at the
same time. The locks on the gap are purely inhibitive: an insert cannot
-be made, or a select cursor may have to wait, if a different transaction
+be made, or a select cursor may have to wait if a different transaction
has a conflicting lock on the gap. An x-lock on the gap does not give
-the right to insert into the gap if there are conflicting locks granted
-on the gap at the same time.
+the right to insert into the gap.
An explicit lock can be placed on a user record or the supremum record of
a page. The locks on the supremum record are always thought to be of the gap
@@ -69,6 +70,11 @@ A waiting record lock can also be of the gap type. A waiting lock request
can be granted when there is no conflicting mode lock request by another
transaction ahead of it in the explicit lock queue.
+In version 4.0.5 we added yet another explicit lock type: LOCK_REC_NOT_GAP.
+It only locks the record it is placed on, not the gap before the record.
+This lock type is necessary to emulate an Oracle-like READ COMMITTED isolation
+level.
+
-------------------------------------------------------------------------
RULE 1: If there is an implicit x-lock on a record, and there are non-gap
-------
@@ -77,10 +83,6 @@ x-lock also has an explicit non-gap record x-lock. Therefore, as locks are
released, we can grant locks to waiting lock requests purely by looking at
the explicit lock requests in the queue.
-RULE 2: Granted non-gap locks on a record are always ahead in the queue
--------
-of waiting non-gap locks on a record.
-
RULE 3: Different transactions cannot have conflicting granted non-gap locks
-------
on a record at the same time. However, they can have conflicting granted gap
@@ -88,7 +90,7 @@ locks.
RULE 4: If a there is a waiting lock request in a queue, no lock request,
-------
gap or not, can be inserted ahead of it in the queue. In record deletes
-and page splits, new gap type locks can be created by the database manager
+and page splits new gap type locks can be created by the database manager
for a transaction, and without rule 4, the waits-for graph of transactions
might become cyclic without the database noticing it, as the deadlock check
is only performed when a transaction itself requests a lock!
@@ -96,7 +98,9 @@ is only performed when a transaction itself requests a lock!
An insert is allowed to a gap if there are no explicit lock requests by
other transactions on the next record. It does not matter if these lock
-requests are granted or waiting, gap bit set or not. On the other hand, an
+requests are granted or waiting, gap bit set or not, with the exception
+that a gap type request set by another transaction to wait for
+its turn to do an insert is ignored. On the other hand, an
implicit x-lock by another transaction does not prevent an insert, which
allows for more concurrency when using an Oracle-style sequence number
generator for the primary key with many transactions doing inserts
@@ -291,7 +295,9 @@ struct lock_struct{
UT_LIST_NODE_T(lock_t)
trx_locks; /* list of the locks of the
transaction */
- ulint type_mode; /* lock type, mode, gap flag, and
+ ulint type_mode; /* lock type, mode, LOCK_GAP or
+ LOCK_REC_NOT_GAP,
+ LOCK_INSERT_INTENTION,
wait flag, ORed */
hash_node_t hash; /* hash chain node for a record lock */
dict_index_t* index; /* index for a record lock */
@@ -306,6 +312,10 @@ Monitor will then fetch it and print */
ibool lock_deadlock_found = FALSE;
char* lock_latest_err_buf; /* We allocate 5000 bytes for this */
+/* Flags for recursive deadlock search */
+#define LOCK_VICTIM_IS_START 1
+#define LOCK_VICTIM_IS_OTHER 2
+
/************************************************************************
Checks if a lock request results in a deadlock. */
static
@@ -329,6 +339,11 @@ lock_deadlock_recursive(
ulint* cost); /* in/out: number of calculation steps thus
far: if this exceeds LOCK_MAX_N_STEPS_...
we return TRUE */
+
+#define lock_mutex_enter_kernel() mutex_enter(&kernel_mutex)
+#define lock_mutex_exit_kernel() mutex_exit(&kernel_mutex)
+
+#ifdef notdefined
/*************************************************************************
Reserves the kernel mutex. This function is used in this module to allow
monitoring the contention degree on the kernel mutex caused by the lock
@@ -342,7 +357,7 @@ lock_mutex_enter_kernel(void)
}
/*************************************************************************
-Releses the kernel mutex. This function is used in this module to allow
+Releases the kernel mutex. This function is used in this module to allow
monitoring the contention degree on the kernel mutex caused by the lock
operations. */
UNIV_INLINE
@@ -352,6 +367,7 @@ lock_mutex_exit_kernel(void)
{
mutex_exit(&kernel_mutex);
}
+#endif
#ifdef notdefined
@@ -501,6 +517,53 @@ lock_rec_mutex_own_all(void)
#endif
/*************************************************************************
+Checks that a transaction id is sensible, i.e., not in the future. */
+
+ibool
+lock_check_trx_id_sanity(
+/*=====================*/
+ /* out: TRUE if ok */
+ dulint trx_id, /* in: trx id */
+ rec_t* rec, /* in: user record */
+ dict_index_t* index, /* in: clustered index */
+ ibool has_kernel_mutex)/* in: TRUE if the caller owns the
+ kernel mutex */
+{
+ char err_buf[500];
+ ibool is_ok = TRUE;
+
+ if (!has_kernel_mutex) {
+ mutex_enter(&kernel_mutex);
+ }
+
+ /* A sanity check: the trx_id in rec must be smaller than the global
+ trx id counter */
+
+ if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) {
+ rec_sprintf(err_buf, 400, rec);
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+"InnoDB: Error: transaction id associated with record\n%s\n"
+"InnoDB: in table %s index %s\n"
+"InnoDB: is %lu %lu which is higher than the global trx id counter %lu %lu!\n"
+"InnoDB: The table is corrupt. You have to do dump + drop + reimport.\n",
+ err_buf, index->table_name, index->name,
+ ut_dulint_get_high(trx_id),
+ ut_dulint_get_low(trx_id),
+ ut_dulint_get_high(trx_sys->max_trx_id),
+ ut_dulint_get_low(trx_sys->max_trx_id));
+
+ is_ok = FALSE;
+ }
+
+ if (!has_kernel_mutex) {
+ mutex_exit(&kernel_mutex);
+ }
+
+ return(is_ok);
+}
+
+/*************************************************************************
Checks that a record is seen in a consistent read. */
ibool
@@ -518,6 +581,10 @@ lock_clust_rec_cons_read_sees(
ut_ad(index->type & DICT_CLUSTERED);
ut_ad(page_rec_is_user_rec(rec));
+ /* NOTE that we call this function while holding the search
+ system latch. To obey the latching order we must NOT reserve the
+ kernel mutex here! */
+
trx_id = row_get_rec_trx_id(rec, index);
if (read_view_sees_trx_id(view, trx_id)) {
@@ -548,10 +615,16 @@ lock_sec_rec_cons_read_sees(
read_view_t* view) /* in: consistent read view */
{
dulint max_trx_id;
-
+
+ UT_NOT_USED(index);
+
ut_ad(!(index->type & DICT_CLUSTERED));
ut_ad(page_rec_is_user_rec(rec));
+ /* NOTE that we might call this function while holding the search
+ system latch. To obey the latching order we must NOT reserve the
+ kernel mutex here! */
+
if (recv_recovery_is_on()) {
return(FALSE);
@@ -615,7 +688,7 @@ UNIV_INLINE
ulint
lock_get_type(
/*==========*/
- /* out: LOCK_TABLE or LOCK_RECa */
+ /* out: LOCK_TABLE or LOCK_REC */
lock_t* lock) /* in: lock */
{
ut_ad(lock);
@@ -697,23 +770,43 @@ lock_rec_get_gap(
}
/*************************************************************************
-Sets the gap flag of a record lock. */
+Gets the LOCK_REC_NOT_GAP flag of a record lock. */
UNIV_INLINE
-void
-lock_rec_set_gap(
-/*=============*/
- lock_t* lock, /* in: record lock */
- ibool val) /* in: value to set: TRUE or FALSE */
+ibool
+lock_rec_get_rec_not_gap(
+/*=====================*/
+ /* out: TRUE if LOCK_REC_NOT_GAP flag set */
+ lock_t* lock) /* in: record lock */
{
ut_ad(lock);
- ut_ad((val == TRUE) || (val == FALSE));
ut_ad(lock_get_type(lock) == LOCK_REC);
- if (val) {
- lock->type_mode = lock->type_mode | LOCK_GAP;
- } else {
- lock->type_mode = lock->type_mode & ~LOCK_GAP;
+ if (lock->type_mode & LOCK_REC_NOT_GAP) {
+
+ return(TRUE);
+ }
+
+ return(FALSE);
+}
+
+/*************************************************************************
+Gets the waiting insert flag of a record lock. */
+UNIV_INLINE
+ibool
+lock_rec_get_insert_intention(
+/*==========================*/
+ /* out: TRUE if gap flag set */
+ lock_t* lock) /* in: record lock */
+{
+ ut_ad(lock);
+ ut_ad(lock_get_type(lock) == LOCK_REC);
+
+ if (lock->type_mode & LOCK_INSERT_INTENTION) {
+
+ return(TRUE);
}
+
+ return(FALSE);
}
/*************************************************************************
@@ -797,40 +890,95 @@ lock_mode_compatible(
}
/*************************************************************************
-Returns LOCK_X if mode is LOCK_S, and vice versa. */
+Checks if a lock request for a new lock has to wait for request lock2. */
UNIV_INLINE
-ulint
-lock_get_confl_mode(
-/*================*/
- /* out: conflicting basic lock mode */
- ulint mode) /* in: LOCK_S or LOCK_X */
+ibool
+lock_rec_has_to_wait(
+/*=================*/
+ /* out: TRUE if new lock has to wait for lock2 to be
+ removed */
+ trx_t* trx, /* in: trx of new lock */
+ ulint type_mode,/* in: precise mode of the new lock to set:
+ LOCK_S or LOCK_X, possibly ORed to
+ LOCK_GAP or LOCK_REC_NOT_GAP, LOCK_INSERT_INTENTION */
+ lock_t* lock2) /* in: another record lock; NOTE that it is assumed
+ that this has a lock bit set on the same record as
+ in the new lock we are setting */
{
- ut_ad(mode == LOCK_X || mode == LOCK_S);
+ ut_ad(trx && lock2);
+ ut_ad(lock_get_type(lock2) == LOCK_REC);
+
+ if (trx != lock2->trx
+ && !lock_mode_compatible(LOCK_MODE_MASK & type_mode,
+ lock_get_mode(lock2))) {
- if (mode == LOCK_S) {
+ /* We have somewhat complex rules when gap type record locks
+ cause waits */
+
+ if ((type_mode & LOCK_REC_NOT_GAP)
+ && lock_rec_get_gap(lock2)) {
+ /* Lock on just the record does not need to wait for
+ a gap type lock */
+
+ return(FALSE);
+ }
+
+ if ((type_mode & LOCK_GAP)
+ && lock_rec_get_rec_not_gap(lock2)) {
+
+ /* Lock on gap does not need to wait for
+ a LOCK_REC_NOT_GAP type lock */
+
+ return(FALSE);
+ }
- return(LOCK_X);
+ if (lock_rec_get_insert_intention(lock2)) {
+
+ /* No lock request needs to wait for an insert
+ intention lock to be removed. This is ok since our
+ rules allow conflicting locks on gaps. This eliminates
+ a spurious deadlock caused by a next-key lock waiting
+ for an insert intention lock; when the insert
+ intention lock was granted, the insert deadlocked on
+ the waiting next-key lock.
+
+ Also, insert intention locks do not disturb each
+ other. */
+
+ return(FALSE);
+ }
+
+ return(TRUE);
}
- return(LOCK_S);
+ return(FALSE);
}
/*************************************************************************
-Checks if a lock request lock1 has to wait for request lock2. NOTE that we,
-for simplicity, ignore the gap bits in locks, and treat gap type lock
-requests like non-gap lock requests. */
-UNIV_INLINE
+Checks if a lock request lock1 has to wait for request lock2. */
+static
ibool
lock_has_to_wait(
/*=============*/
- /* out: TRUE if lock1 has to wait lock2 to be removed */
- lock_t* lock1, /* in: waiting record lock */
+ /* out: TRUE if lock1 has to wait for lock2 to be
+ removed */
+ lock_t* lock1, /* in: waiting lock */
lock_t* lock2) /* in: another lock; NOTE that it is assumed that this
- has a lock bit set on the same record as in lock1 */
+ has a lock bit set on the same record as in lock1 if
+ the locks are record locks */
{
+ ut_ad(lock1 && lock2);
+
if (lock1->trx != lock2->trx
&& !lock_mode_compatible(lock_get_mode(lock1),
lock_get_mode(lock2))) {
+ if (lock_get_type(lock1) == LOCK_REC) {
+ ut_ad(lock_get_type(lock2) == LOCK_REC);
+
+ return(lock_rec_has_to_wait(lock1->trx,
+ lock1->type_mode, lock2));
+ }
+
return(TRUE);
}
@@ -979,6 +1127,7 @@ lock_rec_get_next_on_page(
ulint page_no;
ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(lock_get_type(lock) == LOCK_REC);
space = lock->un_member.rec_lock.space;
page_no = lock->un_member.rec_lock.page_no;
@@ -1105,6 +1254,7 @@ lock_rec_get_next(
lock_t* lock) /* in: lock */
{
ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(lock_get_type(lock) == LOCK_REC);
for (;;) {
lock = lock_rec_get_next_on_page(lock);
@@ -1162,6 +1312,8 @@ lock_rec_bitmap_reset(
ulint n_bytes;
ulint i;
+ ut_ad(lock_get_type(lock) == LOCK_REC);
+
/* Reset to zero the bitmap which resides immediately after the lock
struct */
@@ -1191,6 +1343,8 @@ lock_rec_copy(
lock_t* dupl_lock;
ulint size;
+ ut_ad(lock_get_type(lock) == LOCK_REC);
+
size = sizeof(lock_t) + lock_rec_get_n_bits(lock) / 8;
dupl_lock = mem_heap_alloc(heap, size);
@@ -1284,30 +1438,42 @@ lock_table_has(
/*============= FUNCTIONS FOR ANALYZING RECORD LOCK QUEUE ================*/
/*************************************************************************
-Checks if a transaction has a GRANTED explicit non-gap lock on rec, stronger
-or equal to mode. */
+Checks if a transaction has a GRANTED explicit lock on rec stronger or equal
+to precise_mode. */
UNIV_INLINE
lock_t*
lock_rec_has_expl(
/*==============*/
/* out: lock or NULL */
- ulint mode, /* in: lock mode */
+ ulint precise_mode,/* in: LOCK_S or LOCK_X possibly ORed to
+ LOCK_GAP or LOCK_REC_NOT_GAP,
+ for a supremum record we regard this always a gap
+ type request */
rec_t* rec, /* in: record */
trx_t* trx) /* in: transaction */
{
lock_t* lock;
-
- ut_ad(mutex_own(&kernel_mutex));
- ut_ad((mode == LOCK_X) || (mode == LOCK_S));
+ ut_ad(mutex_own(&kernel_mutex));
+ ut_ad((precise_mode & LOCK_MODE_MASK) == LOCK_S
+ || (precise_mode & LOCK_MODE_MASK) == LOCK_X);
+ ut_ad(!(precise_mode & LOCK_INSERT_INTENTION));
+
lock = lock_rec_get_first(rec);
while (lock) {
if (lock->trx == trx
- && lock_mode_stronger_or_eq(lock_get_mode(lock), mode)
+ && lock_mode_stronger_or_eq(lock_get_mode(lock),
+ precise_mode & LOCK_MODE_MASK)
&& !lock_get_wait(lock)
- && !(lock_rec_get_gap(lock)
- || page_rec_is_supremum(rec))) {
+ && (!lock_rec_get_rec_not_gap(lock)
+ || (precise_mode & LOCK_REC_NOT_GAP)
+ || page_rec_is_supremum(rec))
+ && (!lock_rec_get_gap(lock)
+ || (precise_mode & LOCK_GAP)
+ || page_rec_is_supremum(rec))
+ && (!lock_rec_get_insert_intention(lock))) {
+
return(lock);
}
@@ -1318,26 +1484,27 @@ lock_rec_has_expl(
}
/*************************************************************************
-Checks if some other transaction has an explicit lock request stronger or
-equal to mode on rec or gap, waiting or granted, in the lock queue. */
-UNIV_INLINE
+Checks if some other transaction has a lock request in the queue. */
+static
lock_t*
lock_rec_other_has_expl_req(
/*========================*/
/* out: lock or NULL */
- ulint mode, /* in: lock mode */
+ ulint mode, /* in: LOCK_S or LOCK_X */
ulint gap, /* in: LOCK_GAP if also gap locks are taken
into account, or 0 if not */
ulint wait, /* in: LOCK_WAIT if also waiting locks are
taken into account, or 0 if not */
rec_t* rec, /* in: record to look at */
- trx_t* trx) /* in: transaction, or NULL if requests
- by any transaction are wanted */
+ trx_t* trx) /* in: transaction, or NULL if requests by all
+ transactions are taken into account */
{
lock_t* lock;
ut_ad(mutex_own(&kernel_mutex));
- ut_ad((mode == LOCK_X) || (mode == LOCK_S));
+ ut_ad(mode == LOCK_X || mode == LOCK_S);
+ ut_ad(gap == 0 || gap == LOCK_GAP);
+ ut_ad(wait == 0 || wait == LOCK_WAIT);
lock = lock_rec_get_first(rec);
@@ -1358,6 +1525,38 @@ lock_rec_other_has_expl_req(
}
/*************************************************************************
+Checks if some other transaction has a conflicting explicit lock request
+in the queue, so that we have to wait. */
+static
+lock_t*
+lock_rec_other_has_conflicting(
+/*===========================*/
+ /* out: lock or NULL */
+ ulint mode, /* in: LOCK_S or LOCK_X,
+ possibly ORed to LOCK_GAP or LOC_REC_NOT_GAP,
+ LOCK_INSERT_INTENTION */
+ rec_t* rec, /* in: record to look at */
+ trx_t* trx) /* in: our transaction */
+{
+ lock_t* lock;
+
+ ut_ad(mutex_own(&kernel_mutex));
+
+ lock = lock_rec_get_first(rec);
+
+ while (lock) {
+ if (lock_rec_has_to_wait(trx, mode, lock)) {
+
+ return(lock);
+ }
+
+ lock = lock_rec_get_next(rec, lock);
+ }
+
+ return(NULL);
+}
+
+/*************************************************************************
Looks for a suitable type record lock struct by the same trx on the same page.
This can be used to save space when a new record lock should be set on a page:
no new struct is needed, if a suitable old is found. */
@@ -1429,6 +1628,15 @@ lock_sec_rec_some_has_impl_off_kernel(
/* Ok, in this case it is possible that some transaction has an
implicit x-lock. We have to look in the clustered index. */
+ if (!lock_check_trx_id_sanity(page_get_max_trx_id(page), rec, index,
+ TRUE)) {
+ buf_page_print(page);
+
+ /* The page is corrupt: try to avoid a crash by returning
+ NULL */
+ return(NULL);
+ }
+
return(row_vers_impl_x_locked_off_kernel(rec, index));
}
@@ -1463,14 +1671,14 @@ lock_rec_create(
page_no = buf_frame_get_page_no(page);
heap_no = rec_get_heap_no(rec);
- /* If rec is the supremum record, then we reset the gap bit, as
- all locks on the supremum are automatically of the gap type, and
- we try to avoid unnecessary memory consumption of a new record lock
- struct for a gap type lock */
+ /* If rec is the supremum record, then we reset the gap and
+ LOCK_REC_NOT_GAP bits, as all locks on the supremum are
+ automatically of the gap type */
if (rec == page_get_supremum_rec(page)) {
+ ut_ad(!(type_mode & LOCK_REC_NOT_GAP));
- type_mode = type_mode & ~LOCK_GAP;
+ type_mode = type_mode & ~(LOCK_GAP | LOCK_REC_NOT_GAP);
}
/* Make lock bitmap bigger by a safety margin */
@@ -1522,10 +1730,17 @@ ulint
lock_rec_enqueue_waiting(
/*=====================*/
/* out: DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
+ DB_QUE_THR_SUSPENDED, or DB_SUCCESS;
+ DB_SUCCESS means that there was a deadlock,
+ but another transaction was chosen as a
+ victim, and we got the lock immediately:
+ no need to wait then */
ulint type_mode,/* in: lock mode this transaction is
- requesting: LOCK_S or LOCK_X, ORed with
- LOCK_GAP if a gap lock is requested */
+ requesting: LOCK_S or LOCK_X, possibly ORed
+ with LOCK_GAP or LOCK_REC_NOT_GAP, ORed
+ with LOCK_INSERT_INTENTION if this waiting
+ lock request is set when performing an
+ insert of an index record */
rec_t* rec, /* in: record */
dict_index_t* index, /* in: index of record */
que_thr_t* thr) /* in: query thread */
@@ -1571,7 +1786,16 @@ index->table_name);
return(DB_DEADLOCK);
}
+ /* If there was a deadlock but we chose another transaction as a
+ victim, it is possible that we already have the lock now granted! */
+
+ if (trx->wait_lock == NULL) {
+
+ return(DB_SUCCESS);
+ }
+
trx->que_state = TRX_QUE_LOCK_WAIT;
+ trx->was_chosen_as_deadlock_victim = FALSE;
trx->wait_started = time(NULL);
ut_a(que_thr_stop(thr));
@@ -1597,8 +1821,8 @@ lock_rec_add_to_queue(
/*==================*/
/* out: lock where the bit was set, NULL if out
of memory */
- ulint type_mode,/* in: lock mode, wait, and gap flags; type
- is ignored and replaced by LOCK_REC */
+ ulint type_mode,/* in: lock mode, wait, gap etc. flags;
+ type is ignored and replaced by LOCK_REC */
rec_t* rec, /* in: record on page */
dict_index_t* index, /* in: index of record */
trx_t* trx) /* in: transaction */
@@ -1616,7 +1840,7 @@ lock_rec_add_to_queue(
ut_ad((type_mode & (LOCK_WAIT | LOCK_GAP))
|| ((type_mode & LOCK_MODE_MASK) != LOCK_X)
|| !lock_rec_other_has_expl_req(LOCK_S, 0, LOCK_WAIT, rec, trx));
-
+
type_mode = type_mode | LOCK_REC;
page = buf_frame_align(rec);
@@ -1627,12 +1851,15 @@ lock_rec_add_to_queue(
struct for a gap type lock */
if (rec == page_get_supremum_rec(page)) {
+ ut_ad(!(type_mode & LOCK_REC_NOT_GAP));
- type_mode = type_mode & ~LOCK_GAP;
+ /* There should never be LOCK_REC_NOT_GAP on a supremum
+ record, but let us play safe */
+
+ type_mode = type_mode & ~(LOCK_GAP | LOCK_REC_NOT_GAP);
}
- /* Look for a waiting lock request on the same record, or for a
- similar record lock on the same page */
+ /* Look for a waiting lock request on the same record or on a gap */
heap_no = rec_get_heap_no(rec);
lock = lock_rec_get_first_on_page(rec);
@@ -1647,6 +1874,9 @@ lock_rec_add_to_queue(
lock = lock_rec_get_next_on_page(lock);
}
+ /* Look for a similar record lock on the same page: if one is found
+ and there are no waiting lock requests, we can just set the bit */
+
similar_lock = lock_rec_find_similar_on_page(type_mode, rec, trx);
if (similar_lock && !somebody_waits && !(type_mode & LOCK_WAIT)) {
@@ -1664,7 +1894,8 @@ This is a fast routine for locking a record in the most common cases:
there are no explicit locks on the page, or there is just one lock, owned
by this transaction, and of the right type_mode. This is a low-level function
which does NOT look at implicit locks! Checks lock compatibility within
-explicit locks. */
+explicit locks. This function sets a normal next-key lock, or in the case of
+a page supremum record, a gap type lock. */
UNIV_INLINE
ibool
lock_rec_lock_fast(
@@ -1673,7 +1904,8 @@ lock_rec_lock_fast(
ibool impl, /* in: if TRUE, no lock is set if no wait
is necessary: we assume that the caller will
set an implicit lock */
- ulint mode, /* in: lock mode */
+ ulint mode, /* in: lock mode: LOCK_X or LOCK_S possibly
+ ORed to either LOCK_GAP or LOCK_REC_NOT_GAP */
rec_t* rec, /* in: record */
dict_index_t* index, /* in: index of record */
que_thr_t* thr) /* in: query thread */
@@ -1682,8 +1914,16 @@ lock_rec_lock_fast(
ulint heap_no;
ut_ad(mutex_own(&kernel_mutex));
- ut_ad((mode == LOCK_X) || (mode == LOCK_S));
-
+ ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
+ || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS));
+ ut_ad((LOCK_MODE_MASK & mode) != LOCK_X
+ || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
+ ut_ad((LOCK_MODE_MASK & mode) == LOCK_S
+ || (LOCK_MODE_MASK & mode) == LOCK_X);
+ ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
+ || mode - (LOCK_MODE_MASK & mode) == 0
+ || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
+
heap_no = rec_get_heap_no(rec);
lock = lock_rec_get_first_on_page(rec);
@@ -1717,7 +1957,8 @@ lock_rec_lock_fast(
/*************************************************************************
This is the general, and slower, routine for locking a record. This is a
low-level function which does NOT look at implicit locks! Checks lock
-compatibility within explicit locks. */
+compatibility within explicit locks. This function sets a normal next-key
+lock, or in the case of a page supremum record, a gap type lock. */
static
ulint
lock_rec_lock_slow(
@@ -1727,32 +1968,35 @@ lock_rec_lock_slow(
ibool impl, /* in: if TRUE, no lock is set if no wait is
necessary: we assume that the caller will set
an implicit lock */
- ulint mode, /* in: lock mode */
+ ulint mode, /* in: lock mode: LOCK_X or LOCK_S possibly
+ ORed to either LOCK_GAP or LOCK_REC_NOT_GAP */
rec_t* rec, /* in: record */
dict_index_t* index, /* in: index of record */
que_thr_t* thr) /* in: query thread */
{
- ulint confl_mode;
trx_t* trx;
ulint err;
ut_ad(mutex_own(&kernel_mutex));
- ut_ad((mode == LOCK_X) || (mode == LOCK_S));
-
+ ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
+ || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS));
+ ut_ad((LOCK_MODE_MASK & mode) != LOCK_X
+ || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
+ ut_ad((LOCK_MODE_MASK & mode) == LOCK_S
+ || (LOCK_MODE_MASK & mode) == LOCK_X);
+ ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
+ || mode - (LOCK_MODE_MASK & mode) == 0
+ || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
+
trx = thr_get_trx(thr);
- confl_mode = lock_get_confl_mode(mode);
-
- ut_ad((mode != LOCK_S) || lock_table_has(trx, index->table,
- LOCK_IS));
- ut_ad((mode != LOCK_X) || lock_table_has(trx, index->table,
- LOCK_IX));
+
if (lock_rec_has_expl(mode, rec, trx)) {
/* The trx already has a strong enough lock on rec: do
nothing */
err = DB_SUCCESS;
- } else if (lock_rec_other_has_expl_req(confl_mode, 0, LOCK_WAIT, rec,
- trx)) {
+ } else if (lock_rec_other_has_conflicting(mode, rec, trx)) {
+
/* If another transaction has a non-gap conflicting request in
the queue, as this transaction does not have a lock strong
enough already granted on the record, we have to wait. */
@@ -1776,7 +2020,8 @@ lock_rec_lock_slow(
Tries to lock the specified record in the mode requested. If not immediately
possible, enqueues a waiting lock request. This is a low-level function
which does NOT look at implicit locks! Checks lock compatibility within
-explicit locks. */
+explicit locks. This function sets a normal next-key lock, or in the case
+of a page supremum record, a gap type lock. */
ulint
lock_rec_lock(
@@ -1786,7 +2031,8 @@ lock_rec_lock(
ibool impl, /* in: if TRUE, no lock is set if no wait is
necessary: we assume that the caller will set
an implicit lock */
- ulint mode, /* in: lock mode */
+ ulint mode, /* in: lock mode: LOCK_X or LOCK_S possibly
+ ORed to either LOCK_GAP or LOCK_REC_NOT_GAP */
rec_t* rec, /* in: record */
dict_index_t* index, /* in: index of record */
que_thr_t* thr) /* in: query thread */
@@ -1794,11 +2040,16 @@ lock_rec_lock(
ulint err;
ut_ad(mutex_own(&kernel_mutex));
- ut_ad((mode != LOCK_S) || lock_table_has(thr_get_trx(thr),
- index->table, LOCK_IS));
- ut_ad((mode != LOCK_X) || lock_table_has(thr_get_trx(thr),
- index->table, LOCK_IX));
-
+ ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
+ || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS));
+ ut_ad((LOCK_MODE_MASK & mode) != LOCK_X
+ || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
+ ut_ad((LOCK_MODE_MASK & mode) == LOCK_S
+ || (LOCK_MODE_MASK & mode) == LOCK_X);
+ ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
+ || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP
+ || mode - (LOCK_MODE_MASK & mode) == 0);
+
if (lock_rec_lock_fast(impl, mode, rec, index, thr)) {
/* We try a simplified and faster subroutine for the most
@@ -1813,9 +2064,7 @@ lock_rec_lock(
}
/*************************************************************************
-Checks if a waiting record lock request still has to wait in a queue.
-NOTE that we, for simplicity, ignore the gap bits in locks, and treat
-gap type lock requests like non-gap lock requests. */
+Checks if a waiting record lock request still has to wait in a queue. */
static
ibool
lock_rec_has_to_wait_in_queue(
@@ -1830,6 +2079,7 @@ lock_rec_has_to_wait_in_queue(
ut_ad(mutex_own(&kernel_mutex));
ut_ad(lock_get_wait(wait_lock));
+ ut_ad(lock_get_type(wait_lock) == LOCK_REC);
space = wait_lock->un_member.rec_lock.space;
page_no = wait_lock->un_member.rec_lock.page_no;
@@ -1839,8 +2089,8 @@ lock_rec_has_to_wait_in_queue(
while (lock != wait_lock) {
- if (lock_has_to_wait(wait_lock, lock)
- && lock_rec_get_nth_bit(lock, heap_no)) {
+ if (lock_rec_get_nth_bit(lock, heap_no)
+ && lock_has_to_wait(wait_lock, lock)) {
return(TRUE);
}
@@ -1863,26 +2113,33 @@ lock_grant(
ut_ad(mutex_own(&kernel_mutex));
lock_reset_lock_and_trx_wait(lock);
-
- if (lock_get_mode(lock) == LOCK_AUTO_INC) {
- if (lock->trx->auto_inc_lock != NULL) {
- fprintf(stderr,
- "InnoDB: Error: trx already had an AUTO-INC lock!\n");
- }
+ if (lock_get_mode(lock) == LOCK_AUTO_INC) {
- /* Store pointer to lock to trx so that we know to
- release it at the end of the SQL statement */
+ if (lock->trx->auto_inc_lock != NULL) {
+ fprintf(stderr,
+ "InnoDB: Error: trx already had an AUTO-INC lock!\n");
+ }
- lock->trx->auto_inc_lock = lock;
- }
+ /* Store pointer to lock to trx so that we know to
+ release it at the end of the SQL statement */
+
+ lock->trx->auto_inc_lock = lock;
+ }
if (lock_print_waits) {
printf("Lock wait for trx %lu ends\n",
ut_dulint_get_low(lock->trx->id));
}
+
+ /* If we are resolving a deadlock by choosing another transaction
+ as a victim, then our original transaction may not be in the
+ TRX_QUE_LOCK_WAIT state, and there is no need to end the lock wait
+ for it */
- trx_end_lock_wait(lock->trx);
+ if (lock->trx->que_state == TRX_QUE_LOCK_WAIT) {
+ trx_end_lock_wait(lock->trx);
+ }
}
/*****************************************************************
@@ -1896,6 +2153,7 @@ lock_rec_cancel(
lock_t* lock) /* in: waiting record lock request */
{
ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(lock_get_type(lock) == LOCK_REC);
/* Reset the bit (there can be only one set bit) in the lock bitmap */
lock_rec_reset_nth_bit(lock, lock_rec_find_set_bit(lock));
@@ -1931,7 +2189,7 @@ lock_rec_dequeue_from_page(
ut_ad(lock_get_type(in_lock) == LOCK_REC);
trx = in_lock->trx;
-
+
space = in_lock->un_member.rec_lock.space;
page_no = in_lock->un_member.rec_lock.page_no;
@@ -2050,9 +2308,10 @@ lock_rec_reset_and_release_wait(
}
/*****************************************************************
-Makes a record to inherit the locks of another record as gap type locks, but
-does not reset the lock bits of the other record. Also waiting lock requests
-on rec are inherited as GRANTED gap locks. */
+Makes a record to inherit the locks (except LOCK_INSERT_INTENTION type)
+of another record as gap type locks, but does not reset the lock bits of
+the other record. Also waiting lock requests on rec are inherited as
+GRANTED gap locks. */
void
lock_rec_inherit_to_gap(
@@ -2068,8 +2327,45 @@ lock_rec_inherit_to_gap(
lock = lock_rec_get_first(rec);
while (lock != NULL) {
- lock_rec_add_to_queue((lock->type_mode | LOCK_GAP) & ~LOCK_WAIT,
+ if (!lock_rec_get_insert_intention(lock)) {
+
+ lock_rec_add_to_queue(LOCK_REC | lock_get_mode(lock)
+ | LOCK_GAP,
+ heir, lock->index, lock->trx);
+ }
+
+ lock = lock_rec_get_next(rec, lock);
+ }
+}
+
+/*****************************************************************
+Makes a record to inherit the gap locks (except LOCK_INSERT_INTENTION type)
+of another record as gap type locks, but does not reset the lock bits of the
+other record. Also waiting lock requests are inherited as GRANTED gap locks. */
+
+void
+lock_rec_inherit_to_gap_if_gap_lock(
+/*================================*/
+ rec_t* heir, /* in: record which inherits */
+ rec_t* rec) /* in: record from which inherited; does NOT reset
+ the locks on this record */
+{
+ lock_t* lock;
+
+ ut_ad(mutex_own(&kernel_mutex));
+
+ lock = lock_rec_get_first(rec);
+
+ while (lock != NULL) {
+ if (!lock_rec_get_insert_intention(lock)
+ && (page_rec_is_supremum(rec)
+ || !lock_rec_get_rec_not_gap(lock))) {
+
+ lock_rec_add_to_queue(LOCK_REC | lock_get_mode(lock)
+ | LOCK_GAP,
heir, lock->index, lock->trx);
+ }
+
lock = lock_rec_get_next(rec, lock);
}
}
@@ -2337,7 +2633,7 @@ lock_move_rec_list_start(
ulint heap_no;
ulint type_mode;
- ut_ad(new_page);
+ ut_a(new_page);
lock_mutex_enter_kernel();
@@ -2628,9 +2924,10 @@ lock_update_insert(
{
lock_mutex_enter_kernel();
- /* Inherit the locks for rec, in gap mode, from the next record */
+ /* Inherit the gap-locking locks for rec, in gap mode, from the next
+ record */
- lock_rec_inherit_to_gap(rec, page_rec_get_next(rec));
+ lock_rec_inherit_to_gap_if_gap_lock(rec, page_rec_get_next(rec));
lock_mutex_exit_kernel();
}
@@ -2709,20 +3006,23 @@ static
ibool
lock_deadlock_occurs(
/*=================*/
- /* out: TRUE if a deadlock was detected */
+ /* out: TRUE if a deadlock was detected and we
+ chose trx as a victim; FALSE if no deadlock, or
+ there was a deadlock, but we chose other
+ transaction(s) as victim(s) */
lock_t* lock, /* in: lock the transaction is requesting */
trx_t* trx) /* in: transaction */
{
dict_table_t* table;
dict_index_t* index;
trx_t* mark_trx;
- ibool ret;
+ ulint ret;
ulint cost = 0;
char* err_buf;
ut_ad(trx && lock);
ut_ad(mutex_own(&kernel_mutex));
-
+retry:
/* We check that adding this trx to the waits-for graph
does not produce a cycle. First mark all active transactions
with 0: */
@@ -2736,7 +3036,14 @@ lock_deadlock_occurs(
ret = lock_deadlock_recursive(trx, trx, lock, &cost);
- if (ret) {
+ if (ret == LOCK_VICTIM_IS_OTHER) {
+ /* We chose some other trx as a victim: retry if there still
+ is a deadlock */
+
+ goto retry;
+ }
+
+ if (ret == LOCK_VICTIM_IS_START) {
if (lock_get_type(lock) == LOCK_TABLE) {
table = lock->un_member.tab_lock.table;
index = NULL;
@@ -2748,19 +3055,6 @@ lock_deadlock_occurs(
lock_deadlock_found = TRUE;
err_buf = lock_latest_err_buf + strlen(lock_latest_err_buf);
-
- err_buf += sprintf(err_buf,
- "*** (2) WAITING FOR THIS LOCK TO BE GRANTED:\n");
-
- ut_a(err_buf <= lock_latest_err_buf + 4000);
-
- if (lock_get_type(lock) == LOCK_REC) {
- lock_rec_print(err_buf, lock);
- err_buf += strlen(err_buf);
- } else {
- lock_table_print(err_buf, lock);
- err_buf += strlen(err_buf);
- }
ut_a(err_buf <= lock_latest_err_buf + 4000);
@@ -2773,30 +3067,39 @@ lock_deadlock_occurs(
sess_raise_error_low(trx, DB_DEADLOCK, lock->type_mode, table,
index, NULL, NULL, NULL);
*/
+
+ return(TRUE);
}
- return(ret);
+ return(FALSE);
}
/************************************************************************
Looks recursively for a deadlock. */
static
-ibool
+ulint
lock_deadlock_recursive(
/*====================*/
- /* out: TRUE if a deadlock was detected
- or the calculation took too long */
+ /* out: 0 if no deadlock found,
+ LOCK_VICTIM_IS_START if there was a deadlock
+ and we chose 'start' as the victim,
+ LOCK_VICTIM_IS_OTHER if a deadlock
+ was found and we chose some other trx as a
+ victim: we must do the search again in this
+ last case because there may be another
+ deadlock! */
trx_t* start, /* in: recursion starting point */
trx_t* trx, /* in: a transaction waiting for a lock */
lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
ulint* cost) /* in/out: number of calculation steps thus
far: if this exceeds LOCK_MAX_N_STEPS_...
- we return TRUE */
+ we return LOCK_VICTIM_IS_START */
{
lock_t* lock;
- ulint bit_no;
+ ulint bit_no = ULINT_UNDEFINED;
trx_t* lock_trx;
char* err_buf;
+ ulint ret;
ut_a(trx && start && wait_lock);
ut_ad(mutex_own(&kernel_mutex));
@@ -2805,14 +3108,14 @@ lock_deadlock_recursive(
/* We have already exhaustively searched the subtree starting
from this trx */
- return(FALSE);
+ return(0);
}
*cost = *cost + 1;
if (*cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK) {
- return(TRUE);
+ return(LOCK_VICTIM_IS_START);
}
lock = wait_lock;
@@ -2832,6 +3135,7 @@ lock_deadlock_recursive(
lock = UT_LIST_GET_PREV(un_member.tab_lock.locks, lock);
} else {
ut_ad(lock_get_type(lock) == LOCK_REC);
+ ut_a(bit_no != ULINT_UNDEFINED);
lock = lock_rec_get_prev(lock, bit_no);
}
@@ -2848,14 +3152,16 @@ lock_deadlock_recursive(
lock_trx = lock->trx;
if (lock_trx == start) {
+ /* We came back to the recursion starting
+ point: a deadlock detected */
+
err_buf = lock_latest_err_buf;
ut_sprintf_timestamp(err_buf);
err_buf += strlen(err_buf);
err_buf += sprintf(err_buf,
- " LATEST DETECTED DEADLOCK:\n"
- "*** (1) TRANSACTION:\n");
+ "\n*** (1) TRANSACTION:\n");
trx_print(err_buf, wait_lock->trx);
err_buf += strlen(err_buf);
@@ -2895,11 +3201,60 @@ lock_deadlock_recursive(
ut_a(err_buf <= lock_latest_err_buf + 4000);
+ err_buf += sprintf(err_buf,
+ "*** (2) WAITING FOR THIS LOCK TO BE GRANTED:\n");
+
+ ut_a(err_buf <= lock_latest_err_buf + 4000);
+
+ if (lock_get_type(start->wait_lock)
+ == LOCK_REC) {
+ lock_rec_print(err_buf,
+ start->wait_lock);
+ err_buf += strlen(err_buf);
+ } else {
+ lock_table_print(err_buf,
+ start->wait_lock);
+ err_buf += strlen(err_buf);
+ }
+
if (lock_print_waits) {
printf("Deadlock detected\n");
}
- return(TRUE);
+ if (ut_dulint_cmp(wait_lock->trx->undo_no,
+ start->undo_no) >= 0) {
+ /* Our recursion starting point
+ transaction is 'smaller', let us
+ choose 'start' as the victim and roll
+ back it */
+
+ return(LOCK_VICTIM_IS_START);
+ }
+
+ lock_deadlock_found = TRUE;
+
+ ut_a(err_buf <= lock_latest_err_buf + 4000);
+
+ /* Let us choose the transaction of wait_lock
+ as a victim to try to avoid deadlocking our
+ recursion starting point transaction */
+
+ err_buf += sprintf(err_buf,
+ "*** WE ROLL BACK TRANSACTION (1)\n");
+
+ wait_lock->trx->was_chosen_as_deadlock_victim
+ = TRUE;
+
+ lock_cancel_waiting_and_release(wait_lock);
+
+ /* Since trx and wait_lock are no longer
+ in the waits-for graph, we can return FALSE;
+ note that our selective algorithm can choose
+ several transactions as victims, but still
+ we may end up rolling back also the recursion
+ starting point transaction! */
+
+ return(LOCK_VICTIM_IS_OTHER);
}
if (lock_trx->que_state == TRX_QUE_LOCK_WAIT) {
@@ -2908,10 +3263,11 @@ lock_deadlock_recursive(
incompatible mode, and is itself waiting for
a lock */
- if (lock_deadlock_recursive(start, lock_trx,
- lock_trx->wait_lock, cost)) {
+ ret = lock_deadlock_recursive(start, lock_trx,
+ lock_trx->wait_lock, cost);
+ if (ret != 0) {
- return(TRUE);
+ return(ret);
}
}
}
@@ -3003,12 +3359,16 @@ lock_table_remove_low(
/*************************************************************************
Enqueues a waiting request for a table lock which cannot be granted
immediately. Checks for deadlocks. */
-
+static
ulint
lock_table_enqueue_waiting(
/*=======================*/
/* out: DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
+ DB_QUE_THR_SUSPENDED, or DB_SUCCESS;
+ DB_SUCCESS means that there was a deadlock,
+ but another transaction was chosen as a
+ victim, and we got the lock immediately:
+ no need to wait then */
ulint mode, /* in: lock mode this transaction is
requesting */
dict_table_t* table, /* in: table */
@@ -3055,7 +3415,15 @@ table->name);
return(DB_DEADLOCK);
}
+ if (trx->wait_lock == NULL) {
+ /* Deadlock resolution chose another transaction as a victim,
+ and we accidentally got our lock granted! */
+
+ return(DB_SUCCESS);
+ }
+
trx->que_state = TRX_QUE_LOCK_WAIT;
+ trx->was_chosen_as_deadlock_victim = FALSE;
trx->wait_started = time(NULL);
ut_a(que_thr_stop(thr));
@@ -3142,7 +3510,7 @@ lock_table(
if (lock_table_other_has_incompatible(trx, LOCK_WAIT, table, mode)) {
/* Another trx has a request on the table in an incompatible
- mode: this trx must wait */
+ mode: this trx may have to wait */
err = lock_table_enqueue_waiting(mode, table, thr);
@@ -3281,8 +3649,9 @@ lock_release_off_kernel(
/*====================*/
trx_t* trx) /* in: transaction */
{
- ulint count;
- lock_t* lock;
+ dict_table_t* table;
+ ulint count;
+ lock_t* lock;
ut_ad(mutex_own(&kernel_mutex));
@@ -3300,6 +3669,19 @@ lock_release_off_kernel(
} else {
ut_ad(lock_get_type(lock) == LOCK_TABLE);
+ if (lock_get_mode(lock) != LOCK_IS
+ && (trx->insert_undo || trx->update_undo)) {
+
+ /* The trx may have modified the table.
+ We block the use of the MySQL query cache
+ for all currently active transactions. */
+
+ table = lock->un_member.tab_lock.table;
+
+ table->query_cache_inv_trx_id =
+ trx_sys->max_trx_id;
+ }
+
lock_table_dequeue(lock);
}
@@ -3495,7 +3877,15 @@ lock_rec_print(
}
if (lock_rec_get_gap(lock)) {
- buf += sprintf(buf, " gap type lock");
+ buf += sprintf(buf, " locks gap before rec");
+ }
+
+ if (lock_rec_get_rec_not_gap(lock)) {
+ buf += sprintf(buf, " locks rec but not gap");
+ }
+
+ if (lock_rec_get_insert_intention(lock)) {
+ buf += sprintf(buf, " insert intention");
}
if (lock_get_wait(lock)) {
@@ -3515,6 +3905,15 @@ lock_rec_print(
IB__FILE__, __LINE__, &mtr);
if (page) {
page = buf_page_get_nowait(space, page_no, RW_S_LATCH, &mtr);
+
+ if (!page) {
+ /* Let us try to get an X-latch. If the current thread
+ is holding an X-latch on the page, we cannot get an
+ S-latch. */
+
+ page = buf_page_get_nowait(space, page_no, RW_X_LATCH,
+ &mtr);
+ }
}
if (page) {
@@ -3599,34 +3998,25 @@ lock_print_info(
mtr_t mtr;
if (buf_end - buf < 600) {
- sprintf(buf, "... output truncated!\n");
-
+ sprintf(buf, "... output truncated!\n");
+
return;
}
-
- buf += sprintf(buf, "Trx id counter %lu %lu\n",
- ut_dulint_get_high(trx_sys->max_trx_id),
- ut_dulint_get_low(trx_sys->max_trx_id));
-
- buf += sprintf(buf,
- "Purge done for trx's n:o < %lu %lu undo n:o < %lu %lu\n",
- ut_dulint_get_high(purge_sys->purge_trx_no),
- ut_dulint_get_low(purge_sys->purge_trx_no),
- ut_dulint_get_high(purge_sys->purge_undo_no),
- ut_dulint_get_low(purge_sys->purge_undo_no));
lock_mutex_enter_kernel();
- buf += sprintf(buf,
- "Total number of lock structs in row lock hash table %lu\n",
- lock_get_n_rec_locks());
if (lock_deadlock_found) {
+
+ buf += sprintf(buf,
+"------------------------\n"
+"LATEST DETECTED DEADLOCK\n"
+"------------------------\n");
if ((ulint)(buf_end - buf)
< 100 + strlen(lock_latest_err_buf)) {
- lock_mutex_exit_kernel();
- sprintf(buf, "... output truncated!\n");
+ lock_mutex_exit_kernel();
+ sprintf(buf, "... output truncated!\n");
return;
}
@@ -3641,6 +4031,26 @@ lock_print_info(
return;
}
+ buf += sprintf(buf,
+"------------\n"
+"TRANSACTIONS\n"
+"------------\n");
+
+ buf += sprintf(buf, "Trx id counter %lu %lu\n",
+ ut_dulint_get_high(trx_sys->max_trx_id),
+ ut_dulint_get_low(trx_sys->max_trx_id));
+
+ buf += sprintf(buf,
+ "Purge done for trx's n:o < %lu %lu undo n:o < %lu %lu\n",
+ ut_dulint_get_high(purge_sys->purge_trx_no),
+ ut_dulint_get_low(purge_sys->purge_trx_no),
+ ut_dulint_get_high(purge_sys->purge_undo_no),
+ ut_dulint_get_low(purge_sys->purge_undo_no));
+
+ buf += sprintf(buf,
+ "Total number of lock structs in row lock hash table %lu\n",
+ lock_get_n_rec_locks());
+
buf += sprintf(buf, "LIST OF TRANSACTIONS FOR EACH SESSION:\n");
/* First print info on non-active transactions */
@@ -3649,8 +4059,8 @@ lock_print_info(
while (trx) {
if (buf_end - buf < 900) {
- lock_mutex_exit_kernel();
- sprintf(buf, "... output truncated!\n");
+ lock_mutex_exit_kernel();
+ sprintf(buf, "... output truncated!\n");
return;
}
@@ -3702,8 +4112,8 @@ loop:
buf += strlen(buf);
if (buf_end - buf < 500) {
- lock_mutex_exit_kernel();
- sprintf(buf, "... output truncated!\n");
+ lock_mutex_exit_kernel();
+ sprintf(buf, "... output truncated!\n");
return;
}
@@ -3759,7 +4169,7 @@ loop:
}
if (buf_end - buf < 500) {
- lock_mutex_exit_kernel();
+ lock_mutex_exit_kernel();
sprintf(buf, "... output truncated!\n");
return;
@@ -3863,7 +4273,6 @@ lock_rec_queue_validate(
{
trx_t* impl_trx;
lock_t* lock;
- ibool is_waiting;
ut_a(rec);
@@ -3901,9 +4310,10 @@ lock_rec_queue_validate(
impl_trx = lock_clust_rec_some_has_impl(rec, index);
if (impl_trx && lock_rec_other_has_expl_req(LOCK_S, 0,
- LOCK_WAIT, rec, impl_trx)) {
+ LOCK_WAIT, rec, impl_trx)) {
- ut_a(lock_rec_has_expl(LOCK_X, rec, impl_trx));
+ ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec,
+ impl_trx));
}
}
@@ -3916,14 +4326,13 @@ lock_rec_queue_validate(
impl_trx = lock_sec_rec_some_has_impl_off_kernel(rec, index);
if (impl_trx && lock_rec_other_has_expl_req(LOCK_S, 0,
- LOCK_WAIT, rec, impl_trx)) {
+ LOCK_WAIT, rec, impl_trx)) {
- ut_a(lock_rec_has_expl(LOCK_X, rec, impl_trx));
+ ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec,
+ impl_trx));
}
}
- is_waiting = FALSE;
-
lock = lock_rec_get_first(rec);
while (lock) {
@@ -3936,22 +4345,17 @@ lock_rec_queue_validate(
}
if (!lock_rec_get_gap(lock) && !lock_get_wait(lock)) {
-
- ut_a(!is_waiting);
if (lock_get_mode(lock) == LOCK_S) {
ut_a(!lock_rec_other_has_expl_req(LOCK_X,
- 0, 0, rec,
- lock->trx));
+ 0, 0, rec, lock->trx));
} else {
ut_a(!lock_rec_other_has_expl_req(LOCK_S,
- 0, 0, rec,
- lock->trx));
+ 0, 0, rec, lock->trx));
}
} else if (lock_get_wait(lock) && !lock_rec_get_gap(lock)) {
- is_waiting = TRUE;
ut_a(lock_rec_has_to_wait_in_queue(lock));
}
@@ -4184,13 +4588,23 @@ lock_rec_insert_check_and_lock(
*inherit = TRUE;
- /* If another transaction has an explicit lock request, gap or not,
- waiting or granted, on the successor, the insert has to wait */
+ /* If another transaction has an explicit lock request which locks
+ the gap, waiting or granted, on the successor, the insert has to wait.
+
+ An exception is the case where the lock by the another transaction
+ is a gap type lock which it placed to wait for its turn to insert. We
+ do not consider that kind of a lock conflicting with our insert. This
+ eliminates an unnecessary deadlock which resulted when 2 transactions
+ had to wait for their insert. Both had waiting gap type lock requests
+ on the successor, which produced an unnecessary deadlock. */
- if (lock_rec_other_has_expl_req(LOCK_S, LOCK_GAP, LOCK_WAIT, next_rec,
- trx)) {
- err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP, next_rec,
- index, thr);
+ if (lock_rec_other_has_conflicting(LOCK_X | LOCK_GAP
+ | LOCK_INSERT_INTENTION, next_rec, trx)) {
+
+ /* Note that we may get DB_SUCCESS also here! */
+ err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP
+ | LOCK_INSERT_INTENTION,
+ next_rec, index, thr);
} else {
err = DB_SUCCESS;
}
@@ -4235,9 +4649,11 @@ lock_rec_convert_impl_to_expl(
/* If the transaction has no explicit x-lock set on the
record, set one for it */
- if (!lock_rec_has_expl(LOCK_X, rec, impl_trx)) {
+ if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec,
+ impl_trx)) {
- lock_rec_add_to_queue(LOCK_REC | LOCK_X, rec, index,
+ lock_rec_add_to_queue(LOCK_REC | LOCK_X
+ | LOCK_REC_NOT_GAP, rec, index,
impl_trx);
}
}
@@ -4283,7 +4699,7 @@ lock_clust_rec_modify_check_and_lock(
lock_rec_convert_impl_to_expl(rec, index);
- err = lock_rec_lock(TRUE, LOCK_X, rec, index, thr);
+ err = lock_rec_lock(TRUE, LOCK_X | LOCK_REC_NOT_GAP, rec, index, thr);
lock_mutex_exit_kernel();
@@ -4328,7 +4744,7 @@ lock_sec_rec_modify_check_and_lock(
ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
- err = lock_rec_lock(TRUE, LOCK_X, rec, index, thr);
+ err = lock_rec_lock(TRUE, LOCK_X | LOCK_REC_NOT_GAP, rec, index, thr);
lock_mutex_exit_kernel();
@@ -4362,6 +4778,8 @@ lock_sec_rec_read_check_and_lock(
ulint mode, /* in: mode of the lock which the read cursor
should set on records: LOCK_S or LOCK_X; the
latter is possible in SELECT FOR UPDATE */
+ ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ LOCK_REC_NOT_GAP */
que_thr_t* thr) /* in: query thread */
{
ulint err;
@@ -4393,7 +4811,7 @@ lock_sec_rec_read_check_and_lock(
lock_rec_convert_impl_to_expl(rec, index);
}
- err = lock_rec_lock(FALSE, mode, rec, index, thr);
+ err = lock_rec_lock(FALSE, mode | gap_mode, rec, index, thr);
lock_mutex_exit_kernel();
@@ -4424,13 +4842,16 @@ lock_clust_rec_read_check_and_lock(
ulint mode, /* in: mode of the lock which the read cursor
should set on records: LOCK_S or LOCK_X; the
latter is possible in SELECT FOR UPDATE */
+ ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ LOCK_REC_NOT_GAP */
que_thr_t* thr) /* in: query thread */
{
ulint err;
ut_ad(index->type & DICT_CLUSTERED);
ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec));
-
+ ut_ad(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP
+ || gap_mode == LOCK_REC_NOT_GAP);
if (flags & BTR_NO_LOCKING_FLAG) {
return(DB_SUCCESS);
@@ -4448,7 +4869,7 @@ lock_clust_rec_read_check_and_lock(
lock_rec_convert_impl_to_expl(rec, index);
}
- err = lock_rec_lock(FALSE, mode, rec, index, thr);
+ err = lock_rec_lock(FALSE, mode | gap_mode, rec, index, thr);
lock_mutex_exit_kernel();
diff --git a/innobase/log/Makefile.am b/innobase/log/Makefile.am
index 3910a25ab1a..2dbaf93e6d9 100644
--- a/innobase/log/Makefile.am
+++ b/innobase/log/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = liblog.a
+noinst_LIBRARIES = liblog.a
liblog_a_SOURCES = log0log.c log0recv.c
diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c
index 9e40e4898a5..5df63e39296 100644
--- a/innobase/log/log0log.c
+++ b/innobase/log/log0log.c
@@ -33,6 +33,11 @@ log_t* log_sys = NULL;
ibool log_do_write = TRUE;
ibool log_debug_writes = FALSE;
+/* These control how often we print warnings if the last checkpoint is too
+old */
+ibool log_has_printed_chkp_warning = FALSE;
+time_t log_last_warning_time;
+
/* Pointer to this variable is used as the i/o-message when we do i/o to an
archive */
byte log_archive_io;
@@ -178,7 +183,8 @@ loop:
/* Not enough free space, do a syncronous flush of the log
buffer */
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ALL_GROUPS);
+
+ log_buffer_flush_to_disk();
count++;
@@ -298,6 +304,7 @@ log_close(void)
dulint oldest_lsn;
dulint lsn;
log_t* log = log_sys;
+ ulint checkpoint_age;
ut_ad(mutex_own(&(log->mutex)));
@@ -321,8 +328,34 @@ log_close(void)
log->check_flush_or_checkpoint = TRUE;
}
- if (ut_dulint_minus(lsn, log->last_checkpoint_lsn)
- <= log->max_modified_age_async) {
+ checkpoint_age = ut_dulint_minus(lsn, log->last_checkpoint_lsn);
+
+ if (checkpoint_age >= log->log_group_capacity) {
+ /* TODO: split btr_store_big_rec_extern_fields() into small
+ steps so that we can release all latches in the middle, and
+ call log_free_check() to ensure we never write over log written
+ after the latest checkpoint. In principle, we should split all
+ big_rec operations, but other operations are smaller. */
+
+ if (!log_has_printed_chkp_warning
+ || difftime(time(NULL), log_last_warning_time) > 15) {
+
+ log_has_printed_chkp_warning = TRUE;
+ log_last_warning_time = time(NULL);
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: ERROR: the age of the last checkpoint is %lu,\n"
+"InnoDB: which exceeds the log group capacity %lu.\n"
+"InnoDB: If you are using big BLOB or TEXT rows, you must set the\n"
+"InnoDB: combined size of log files at least 10 times bigger than the\n"
+"InnoDB: largest such row.\n",
+ checkpoint_age, log->log_group_capacity);
+ }
+ }
+
+ if (checkpoint_age <= log->max_modified_age_async) {
+
goto function_exit;
}
@@ -331,8 +364,7 @@ log_close(void)
if (ut_dulint_is_zero(oldest_lsn)
|| (ut_dulint_minus(lsn, oldest_lsn)
> log->max_modified_age_async)
- || (ut_dulint_minus(lsn, log->last_checkpoint_lsn)
- > log->max_checkpoint_age_async)) {
+ || checkpoint_age > log->max_checkpoint_age_async) {
log->check_flush_or_checkpoint = TRUE;
}
@@ -375,7 +407,7 @@ log_pad_current_log_block(void)
log_close();
log_release();
- ut_a((ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE)
+ ut_anp((ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE)
== LOG_BLOCK_HDR_SIZE);
}
@@ -468,7 +500,7 @@ log_group_calc_lsn_offset(
offset = (gr_lsn_size_offset + difference) % group_size;
- ut_a(offset <= 0xFFFFFFFF);
+ ut_a(offset < (((ib_longlong) 1) << 32)); /* offset must be < 4 GB */
/* printf("Offset is %lu gr_lsn_offset is %lu difference is %lu\n",
(ulint)offset,(ulint)gr_lsn_size_offset, (ulint)difference);
@@ -550,7 +582,6 @@ log_calc_max_ages(void)
the database server */
{
log_group_t* group;
- ulint n_threads;
ulint margin;
ulint free;
ibool success = TRUE;
@@ -560,8 +591,6 @@ log_calc_max_ages(void)
ut_ad(!mutex_own(&(log_sys->mutex)));
- n_threads = srv_get_n_threads();
-
mutex_enter(&(log_sys->mutex));
group = UT_LIST_GET_FIRST(log_sys->log_groups);
@@ -589,12 +618,15 @@ log_calc_max_ages(void)
group = UT_LIST_GET_NEXT(log_groups, group);
}
+ /* Add extra safety */
+ smallest_capacity = smallest_capacity - smallest_capacity / 10;
+
/* For each OS thread we must reserve so much free space in the
smallest log group that it can accommodate the log entries produced
by single query steps: running out of free log space is a serious
system error which requires rebooting the database. */
- free = LOG_CHECKPOINT_FREE_PER_THREAD * n_threads
+ free = LOG_CHECKPOINT_FREE_PER_THREAD * (10 + srv_thread_concurrency)
+ LOG_CHECKPOINT_EXTRA_FREE;
if (free >= smallest_capacity / 2) {
success = FALSE;
@@ -606,6 +638,10 @@ log_calc_max_ages(void)
margin = ut_min(margin, log_sys->adm_checkpoint_interval);
+ margin = margin - margin / 10; /* Add still some extra safety */
+
+ log_sys->log_group_capacity = smallest_capacity;
+
log_sys->max_modified_age_async = margin
- margin / LOG_POOL_PREFLUSH_RATIO_ASYNC;
log_sys->max_modified_age_sync = margin
@@ -625,7 +661,18 @@ failure:
if (!success) {
fprintf(stderr,
- "Error: log file group too small for the number of threads\n");
+"InnoDB: Error: ib_logfiles are too small for innodb_thread_concurrency %lu.\n"
+"InnoDB: The combined size of ib_logfiles should be bigger than\n"
+"InnoDB: 200 kB * innodb_thread_concurrency.\n"
+"InnoDB: To get mysqld to start up, set innodb_thread_concurrency in my.cnf\n"
+"InnoDB: to a lower value, for example, to 8. After an ERROR-FREE shutdown\n"
+"InnoDB: of mysqld you can adjust the size of ib_logfiles, as explained in\n"
+"InnoDB: section 5 of http://www.innodb.com/ibman.php",
+ (ulong)srv_thread_concurrency);
+ fprintf(stderr,
+"InnoDB: Cannot continue operation. Calling exit(1).\n");
+
+ exit(1);
}
return(success);
@@ -675,7 +722,9 @@ log_init(void)
log_sys->buf_next_to_write = 0;
- log_sys->flush_lsn = ut_dulint_zero;
+ log_sys->write_lsn = ut_dulint_zero;
+ log_sys->current_flush_lsn = ut_dulint_zero;
+ log_sys->flushed_to_disk_lsn = ut_dulint_zero;
log_sys->written_to_some_lsn = log_sys->lsn;
log_sys->written_to_all_lsn = log_sys->lsn;
@@ -867,7 +916,7 @@ log_group_check_flush_completion(
printf("Log flushed first to group %lu\n", group->id);
}
- log_sys->written_to_some_lsn = log_sys->flush_lsn;
+ log_sys->written_to_some_lsn = log_sys->write_lsn;
log_sys->one_flushed = TRUE;
return(LOG_UNLOCK_NONE_FLUSHED_LOCK);
@@ -896,15 +945,15 @@ log_sys_check_flush_completion(void)
if (log_sys->n_pending_writes == 0) {
- log_sys->written_to_all_lsn = log_sys->flush_lsn;
- log_sys->buf_next_to_write = log_sys->flush_end_offset;
+ log_sys->written_to_all_lsn = log_sys->write_lsn;
+ log_sys->buf_next_to_write = log_sys->write_end_offset;
- if (log_sys->flush_end_offset > log_sys->max_buf_free / 2) {
+ if (log_sys->write_end_offset > log_sys->max_buf_free / 2) {
/* Move the log buffer content to the start of the
buffer */
move_start = ut_calc_align_down(
- log_sys->flush_end_offset,
+ log_sys->write_end_offset,
OS_FILE_LOG_BLOCK_SIZE);
move_end = ut_calc_align(log_sys->buf_free,
OS_FILE_LOG_BLOCK_SIZE);
@@ -982,57 +1031,6 @@ log_io_complete(
}
/**********************************************************
-Flushes the log files to the disk, using, for example, the Unix fsync.
-This function does the flush even if the user has set
-srv_flush_log_at_trx_commit = FALSE. */
-
-void
-log_flush_to_disk(void)
-/*===================*/
-{
- log_group_t* group;
-loop:
- mutex_enter(&(log_sys->mutex));
-
- if (log_sys->n_pending_writes > 0) {
- /* A log file write is running */
-
- mutex_exit(&(log_sys->mutex));
-
- /* Wait for the log file write to complete and try again */
-
- os_event_wait(log_sys->no_flush_event);
-
- goto loop;
- }
-
- group = UT_LIST_GET_FIRST(log_sys->log_groups);
-
- log_sys->n_pending_writes++;
- group->n_pending_writes++;
-
- os_event_reset(log_sys->no_flush_event);
- os_event_reset(log_sys->one_flushed_event);
-
- mutex_exit(&(log_sys->mutex));
-
- fil_flush(group->space_id);
-
- mutex_enter(&(log_sys->mutex));
-
- ut_a(group->n_pending_writes == 1);
- ut_a(log_sys->n_pending_writes == 1);
-
- group->n_pending_writes--;
- log_sys->n_pending_writes--;
-
- os_event_set(log_sys->no_flush_event);
- os_event_set(log_sys->one_flushed_event);
-
- mutex_exit(&(log_sys->mutex));
-}
-
-/**********************************************************
Writes a log file header to a log file space. */
static
void
@@ -1047,6 +1045,8 @@ log_group_file_header_flush(
{
byte* buf;
ulint dest_offset;
+
+ UT_NOT_USED(type);
ut_ad(mutex_own(&(log_sys->mutex)));
@@ -1117,8 +1117,8 @@ log_group_write_buf(
ulint i;
ut_ad(mutex_own(&(log_sys->mutex)));
- ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0);
- ut_a(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_anp(len % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_anp(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
if (new_data_offset == 0) {
write_header = TRUE;
@@ -1205,12 +1205,15 @@ by the transaction. If there is a flush running, it waits and checks if the
flush flushed enough. If not, starts a new flush. */
void
-log_flush_up_to(
+log_write_up_to(
/*============*/
dulint lsn, /* in: log sequence number up to which the log should
be written, ut_dulint_max if not specified */
- ulint wait) /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
+ ulint wait, /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
or LOG_WAIT_ALL_GROUPS */
+ ibool flush_to_disk)
+ /* in: TRUE if we want the written log also to be
+ flushed to disk */
{
log_group_t* group;
ulint start_offset;
@@ -1239,9 +1242,18 @@ loop:
mutex_enter(&(log_sys->mutex));
- if ((ut_dulint_cmp(log_sys->written_to_all_lsn, lsn) >= 0)
- || ((ut_dulint_cmp(log_sys->written_to_some_lsn, lsn) >= 0)
- && (wait != LOG_WAIT_ALL_GROUPS))) {
+ if (flush_to_disk
+ && ut_dulint_cmp(log_sys->flushed_to_disk_lsn, lsn) >= 0) {
+
+ mutex_exit(&(log_sys->mutex));
+
+ return;
+ }
+
+ if (!flush_to_disk
+ && (ut_dulint_cmp(log_sys->written_to_all_lsn, lsn) >= 0
+ || (ut_dulint_cmp(log_sys->written_to_some_lsn, lsn) >= 0
+ && wait != LOG_WAIT_ALL_GROUPS))) {
mutex_exit(&(log_sys->mutex));
@@ -1249,10 +1261,19 @@ loop:
}
if (log_sys->n_pending_writes > 0) {
- /* A flush is running */
+ /* A write (+ possibly flush to disk) is running */
+
+ if (flush_to_disk
+ && ut_dulint_cmp(log_sys->current_flush_lsn, lsn) >= 0) {
+ /* The write + flush will write enough: wait for it to
+ complete */
+
+ goto do_waits;
+ }
- if (ut_dulint_cmp(log_sys->flush_lsn, lsn) >= 0) {
- /* The flush will flush enough: wait for it to
+ if (!flush_to_disk
+ && ut_dulint_cmp(log_sys->write_lsn, lsn) >= 0) {
+ /* The write will write enough: wait for it to
complete */
goto do_waits;
@@ -1260,16 +1281,17 @@ loop:
mutex_exit(&(log_sys->mutex));
- /* Wait for the flush to complete and try to start a new
- flush */
+ /* Wait for the write to complete and try to start a new
+ write */
os_event_wait(log_sys->no_flush_event);
goto loop;
}
- if (log_sys->buf_free == log_sys->buf_next_to_write) {
- /* Nothing to flush */
+ if (!flush_to_disk
+ && log_sys->buf_free == log_sys->buf_next_to_write) {
+ /* Nothing to write and no flush to disk requested */
mutex_exit(&(log_sys->mutex));
@@ -1277,7 +1299,7 @@ loop:
}
if (log_debug_writes) {
- printf("Flushing log from %lu %lu up to lsn %lu %lu\n",
+ printf("Writing log from %lu %lu up to lsn %lu %lu\n",
ut_dulint_get_high(log_sys->written_to_all_lsn),
ut_dulint_get_low(log_sys->written_to_all_lsn),
ut_dulint_get_high(log_sys->lsn),
@@ -1301,7 +1323,12 @@ loop:
ut_ad(area_end - area_start > 0);
- log_sys->flush_lsn = log_sys->lsn;
+ log_sys->write_lsn = log_sys->lsn;
+
+ if (flush_to_disk) {
+ log_sys->current_flush_lsn = log_sys->lsn;
+ }
+
log_sys->one_flushed = FALSE;
log_block_set_flush_bit(log_sys->buf + area_start, TRUE);
@@ -1318,10 +1345,12 @@ loop:
OS_FILE_LOG_BLOCK_SIZE);
log_sys->buf_free += OS_FILE_LOG_BLOCK_SIZE;
- log_sys->flush_end_offset = log_sys->buf_free;
+ log_sys->write_end_offset = log_sys->buf_free;
group = UT_LIST_GET_FIRST(log_sys->log_groups);
+ /* Do the write to the log files */
+
while (group) {
log_group_write_buf(LOG_FLUSH, group,
log_sys->buf + area_start,
@@ -1330,20 +1359,25 @@ loop:
OS_FILE_LOG_BLOCK_SIZE),
start_offset - area_start);
- log_group_set_fields(group, log_sys->flush_lsn);
+ log_group_set_fields(group, log_sys->write_lsn);
group = UT_LIST_GET_NEXT(log_groups, group);
}
mutex_exit(&(log_sys->mutex));
- if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC
- && srv_unix_file_flush_method != SRV_UNIX_NOSYNC
- && srv_flush_log_at_trx_commit != 2) {
+ if (srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
+ /* O_DSYNC means the OS did not buffer the log file at all:
+ so we have also flushed to disk what we have written */
+
+ log_sys->flushed_to_disk_lsn = log_sys->write_lsn;
+
+ } else if (flush_to_disk) {
group = UT_LIST_GET_FIRST(log_sys->log_groups);
fil_flush(group->space_id);
+ log_sys->flushed_to_disk_lsn = log_sys->write_lsn;
}
mutex_enter(&(log_sys->mutex));
@@ -1378,6 +1412,24 @@ do_waits:
}
/********************************************************************
+Does a syncronous flush of the log buffer to disk. */
+
+void
+log_buffer_flush_to_disk(void)
+/*==========================*/
+{
+ dulint lsn;
+
+ mutex_enter(&(log_sys->mutex));
+
+ lsn = log_sys->lsn;
+
+ mutex_exit(&(log_sys->mutex));
+
+ log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE);
+}
+
+/********************************************************************
Tries to establish a big enough margin of free space in the log buffer, such
that a new log entry can be catenated without an immediate need for a flush. */
static
@@ -1387,6 +1439,7 @@ log_flush_margin(void)
{
ibool do_flush = FALSE;
log_t* log = log_sys;
+ dulint lsn;
mutex_enter(&(log->mutex));
@@ -1397,13 +1450,14 @@ log_flush_margin(void)
free space */
} else {
do_flush = TRUE;
+ lsn = log->lsn;
}
}
mutex_exit(&(log->mutex));
if (do_flush) {
- log_flush_up_to(ut_dulint_max, LOG_NO_WAIT);
+ log_write_up_to(lsn, LOG_NO_WAIT, FALSE);
}
}
@@ -1555,7 +1609,8 @@ log_group_checkpoint(
buf = group->checkpoint_buf;
mach_write_to_8(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no);
- mach_write_to_8(buf + LOG_CHECKPOINT_LSN, log_sys->next_checkpoint_lsn);
+ mach_write_to_8(buf + LOG_CHECKPOINT_LSN,
+ log_sys->next_checkpoint_lsn);
mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,
log_group_calc_lsn_offset(
@@ -1664,8 +1719,10 @@ log_reset_first_header_and_checkpoint(
lsn = ut_dulint_add(start, LOG_BLOCK_HDR_SIZE);
/* Write the label of ibbackup --restore */
- sprintf(hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, "ibbackup ");
- ut_sprintf_timestamp(hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP
+ sprintf((char*) hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
+ "ibbackup ");
+ ut_sprintf_timestamp(
+ (char*) hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP
+ strlen("ibbackup "));
buf = hdr_buf + LOG_CHECKPOINT_1;
@@ -1773,7 +1830,7 @@ log_checkpoint(
write-ahead-logging algorithm ensures that the log has been flushed
up to oldest_lsn. */
- log_flush_up_to(oldest_lsn, LOG_WAIT_ALL_GROUPS);
+ log_write_up_to(oldest_lsn, LOG_WAIT_ALL_GROUPS, TRUE);
mutex_enter(&(log_sys->mutex));
@@ -2121,7 +2178,7 @@ log_group_archive(
os_file_t file_handle;
dulint start_lsn;
dulint end_lsn;
- char name[100];
+ char name[1024];
byte* buf;
ulint len;
ibool ret;
@@ -2133,11 +2190,11 @@ log_group_archive(
start_lsn = log_sys->archived_lsn;
- ut_ad(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_anp(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
end_lsn = log_sys->next_archived_lsn;
- ut_ad(ut_dulint_get_low(end_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_anp(ut_dulint_get_low(end_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
buf = log_sys->archive_buf;
@@ -2244,7 +2301,7 @@ loop:
group->next_archived_file_no = group->archived_file_no + n_files;
group->next_archived_offset = next_offset % group->file_size;
- ut_ad(group->next_archived_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_anp(group->next_archived_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
}
/*********************************************************
@@ -2439,8 +2496,8 @@ loop:
start_lsn = log_sys->archived_lsn;
if (calc_new_limit) {
- ut_ad(log_sys->archive_buf_size % OS_FILE_LOG_BLOCK_SIZE == 0);
-
+ ut_anp(log_sys->archive_buf_size % OS_FILE_LOG_BLOCK_SIZE
+ == 0);
limit_lsn = ut_dulint_add(start_lsn,
log_sys->archive_buf_size);
@@ -2466,7 +2523,7 @@ loop:
mutex_exit(&(log_sys->mutex));
- log_flush_up_to(limit_lsn, LOG_WAIT_ALL_GROUPS);
+ log_write_up_to(limit_lsn, LOG_WAIT_ALL_GROUPS, TRUE);
calc_new_limit = FALSE;
@@ -2913,9 +2970,10 @@ logs_empty_and_mark_files_at_shutdown(void)
dulint lsn;
ulint arch_log_no;
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Starting shutdown...\n");
-
+ if (srv_print_verbose_log) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Starting shutdown...\n");
+ }
/* Wait until the master thread and all other operations are idle: our
algorithm only works if the server is idle at shutdown */
@@ -2925,6 +2983,7 @@ loop:
mutex_enter(&kernel_mutex);
+ /* Check that there are no longer transactions */
if (trx_n_mysql_transactions > 0
|| UT_LIST_GET_LEN(trx_sys->trx_list) > 0) {
@@ -2933,6 +2992,8 @@ loop:
goto loop;
}
+ /* Check that the master thread is suspended */
+
if (srv_n_threads_active[SRV_MASTER] != 0) {
mutex_exit(&kernel_mutex);
@@ -2961,7 +3022,6 @@ loop:
}
log_archive_all();
-
log_make_checkpoint_at(ut_dulint_max, TRUE);
mutex_enter(&(log_sys->mutex));
@@ -2970,8 +3030,9 @@ loop:
if (ut_dulint_cmp(lsn, log_sys->last_checkpoint_lsn) != 0
|| (srv_log_archive_on
- && ut_dulint_cmp(lsn,
- ut_dulint_add(log_sys->archived_lsn, LOG_BLOCK_HDR_SIZE)) != 0)) {
+ && ut_dulint_cmp(lsn,
+ ut_dulint_add(log_sys->archived_lsn, LOG_BLOCK_HDR_SIZE))
+ != 0)) {
mutex_exit(&(log_sys->mutex));
@@ -2990,10 +3051,22 @@ loop:
mutex_exit(&(log_sys->mutex));
+ mutex_enter(&kernel_mutex);
+ /* Check that the master thread has stayed suspended */
+ if (srv_n_threads_active[SRV_MASTER] != 0) {
+ fprintf(stderr,
+"InnoDB: Warning: the master thread woke up during shutdown\n");
+
+ mutex_exit(&kernel_mutex);
+
+ goto loop;
+ }
+ mutex_exit(&kernel_mutex);
+
fil_flush_file_spaces(FIL_TABLESPACE);
fil_flush_file_spaces(FIL_LOG);
- /* The following fil_write_... will pass the buffer pool: therefore
+ /* The next fil_write_... will pass the buffer pool: therefore
it is essential that the buffer pool has been completely flushed
to disk! */
@@ -3002,12 +3075,14 @@ loop:
goto loop;
}
+ /* The lock timeout thread should now have exited */
+
if (srv_lock_timeout_and_monitor_active) {
goto loop;
}
- /* We now suspend also the InnoDB error monitor thread */
+ /* We now let also the InnoDB error monitor thread to exit */
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
@@ -3016,12 +3091,19 @@ loop:
goto loop;
}
+ /* Make some checks that the server really is quiet */
+ ut_a(srv_n_threads_active[SRV_MASTER] == 0);
+ ut_a(buf_all_freed());
+ ut_a(0 == ut_dulint_cmp(lsn, log_sys->lsn));
+
fil_write_flushed_lsn_to_data_files(lsn, arch_log_no);
fil_flush_file_spaces(FIL_TABLESPACE);
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Shutdown completed\n");
+ /* Make some checks that the server really is quiet */
+ ut_a(srv_n_threads_active[SRV_MASTER] == 0);
+ ut_a(buf_all_freed());
+ ut_a(0 == ut_dulint_cmp(lsn, log_sys->lsn));
}
/**********************************************************
@@ -3076,6 +3158,28 @@ log_check_log_recs(
}
/**********************************************************
+Peeks the current lsn. */
+
+ibool
+log_peek_lsn(
+/*=========*/
+ /* out: TRUE if success, FALSE if could not get the
+ log system mutex */
+ dulint* lsn) /* out: if returns TRUE, current lsn is here */
+{
+ if (0 == mutex_enter_nowait(&(log_sys->mutex), (char*)__FILE__,
+ __LINE__)) {
+ *lsn = log_sys->lsn;
+
+ mutex_exit(&(log_sys->mutex));
+
+ return(TRUE);
+ }
+
+ return(FALSE);
+}
+
+/**********************************************************
Prints info of the log. */
void
@@ -3099,8 +3203,8 @@ log_print(
"Last checkpoint at %lu %lu\n",
ut_dulint_get_high(log_sys->lsn),
ut_dulint_get_low(log_sys->lsn),
- ut_dulint_get_high(log_sys->written_to_some_lsn),
- ut_dulint_get_low(log_sys->written_to_some_lsn),
+ ut_dulint_get_high(log_sys->flushed_to_disk_lsn),
+ ut_dulint_get_low(log_sys->flushed_to_disk_lsn),
ut_dulint_get_high(log_sys->last_checkpoint_lsn),
ut_dulint_get_low(log_sys->last_checkpoint_lsn));
diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c
index 1223f9b6041..9c9ad568d98 100644
--- a/innobase/log/log0recv.c
+++ b/innobase/log/log0recv.c
@@ -46,6 +46,8 @@ ibool recv_recovery_from_backup_on = FALSE;
ibool recv_needed_recovery = FALSE;
+ibool recv_lsn_checks_on = FALSE;
+
/* If the following is TRUE, the buffer pool file pages must be invalidated
after recovery and no ibuf operations are allowed; this becomes TRUE if
the log record hash table becomes too full, and log records must be merged
@@ -69,6 +71,14 @@ ulint recv_previous_parsed_rec_type = 999999;
ulint recv_previous_parsed_rec_offset = 0;
ulint recv_previous_parsed_rec_is_multi = 0;
+ulint recv_max_parsed_page_no = 0;
+
+/* The maximum lsn we see for a page during the recovery process. If this
+is bigger than the lsn we are able to scan up to, that is an indication that
+the recovery failed and the database may be corrupt. */
+
+dulint recv_max_page_lsn;
+
/************************************************************
Creates the recovery system. */
@@ -130,6 +140,8 @@ recv_sys_init(
OS_FILE_LOG_BLOCK_SIZE);
recv_sys->found_corrupt_log = FALSE;
+ recv_max_page_lsn = ut_dulint_zero;
+
mutex_exit(&(recv_sys->mutex));
}
@@ -141,7 +153,13 @@ recv_sys_empty_hash(void)
/*=====================*/
{
ut_ad(mutex_own(&(recv_sys->mutex)));
- ut_a(recv_sys->n_addrs == 0);
+ if (recv_sys->n_addrs != 0) {
+ fprintf(stderr,
+"InnoDB: Error: %lu pages with log records were left unprocessed!\n"
+"InnoDB: Maximum page number with log records on it %lu\n",
+ recv_sys->n_addrs, recv_max_parsed_page_no);
+ ut_a(0);
+ }
hash_table_free(recv_sys->addr_hash);
mem_heap_empty(recv_sys->heap);
@@ -965,7 +983,7 @@ recv_recover_page(
ulint space, /* in: space id */
ulint page_no) /* in: page number */
{
- buf_block_t* block;
+ buf_block_t* block = NULL;
recv_addr_t* recv_addr;
recv_t* recv;
byte* buf;
@@ -1077,7 +1095,7 @@ recv_recover_page(
page_lsn = page_newest_lsn;
mach_write_to_8(page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN, ut_dulint_zero);
+ - FIL_PAGE_END_LSN_OLD_CHKSUM, ut_dulint_zero);
mach_write_to_8(page + FIL_PAGE_LSN, ut_dulint_zero);
}
@@ -1099,7 +1117,7 @@ recv_recover_page(
recv_parse_or_apply_log_rec_body(recv->type, buf,
buf + recv->len, page, &mtr);
mach_write_to_8(page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN,
+ - FIL_PAGE_END_LSN_OLD_CHKSUM,
ut_dulint_add(recv->start_lsn,
recv->len));
mach_write_to_8(page + FIL_PAGE_LSN,
@@ -1116,6 +1134,10 @@ recv_recover_page(
mutex_enter(&(recv_sys->mutex));
+ if (ut_dulint_cmp(recv_max_page_lsn, page_lsn) < 0) {
+ recv_max_page_lsn = page_lsn;
+ }
+
recv_addr->state = RECV_PROCESSED;
ut_a(recv_sys->n_addrs);
@@ -1124,6 +1146,8 @@ recv_recover_page(
mutex_exit(&(recv_sys->mutex));
if (!recover_backup && modification_to_page) {
+ ut_a(block);
+
buf_flush_recv_note_modification(block, start_lsn, end_lsn);
}
@@ -1331,6 +1355,7 @@ loop:
mutex_exit(&(recv_sys->mutex));
}
+#ifdef UNIV_HOTBACKUP
/***********************************************************************
Applies log records in the hash table to a backup. */
@@ -1361,6 +1386,14 @@ recv_apply_log_recs_for_backup(
n_pages_total += file_sizes[i];
}
+ if (recv_max_parsed_page_no >= n_pages_total) {
+ printf(
+"InnoDB: Error: tablespace size %lu pages, but a log record on page %lu!\n"
+"InnoDB: Are you sure you have specified all the ibdata files right in\n"
+"InnoDB: the my.cnf file you gave as the argument to ibbackup --restore?\n",
+ n_pages_total, recv_max_parsed_page_no);
+ }
+
printf(
"InnoDB: Starting an apply batch of log records to the database...\n"
"InnoDB: Progress in percents: ");
@@ -1381,7 +1414,7 @@ recv_apply_log_recs_for_backup(
&success);
if (!success) {
printf(
-"InnoDB: Error: cannot open %lu'th data file %s\n", nth_file);
+"InnoDB: Error: cannot open %lu'th data file\n", nth_file);
exit(1);
}
@@ -1397,7 +1430,7 @@ recv_apply_log_recs_for_backup(
UNIV_PAGE_SIZE);
if (!success) {
printf(
-"InnoDB: Error: cannot read page no %lu from %lu'th data file %s\n",
+"InnoDB: Error: cannot read page no %lu from %lu'th data file\n",
nth_page_in_file, nth_file);
exit(1);
@@ -1425,7 +1458,7 @@ recv_apply_log_recs_for_backup(
UNIV_PAGE_SIZE);
if (!success) {
printf(
-"InnoDB: Error: cannot write page no %lu to %lu'th data file %s\n",
+"InnoDB: Error: cannot write page no %lu to %lu'th data file\n",
nth_page_in_file, nth_file);
exit(1);
@@ -1504,8 +1537,8 @@ recv_check_identical(
for (i = 0; i < len; i++) {
if (str1[i] != str2[i]) {
- fprintf(stderr, "Strings do not match at offset %lu\n", i);
-
+ fprintf(stderr,
+ "Strings do not match at offset %lu\n", i);
ut_print_buf(str1 + i, 16);
fprintf(stderr, "\n");
ut_print_buf(str2 + i, 16);
@@ -1638,6 +1671,7 @@ recv_compare_spaces_low(
recv_compare_spaces(space1, space2, n_pages);
}
+#endif
/***********************************************************************
Tries to parse a single log record and returns its length. */
@@ -1701,6 +1735,10 @@ recv_parse_log_rec(
return(0);
}
+ if (*page_no > recv_max_parsed_page_no) {
+ recv_max_parsed_page_no = *page_no;
+ }
+
return(new_ptr - ptr);
}
@@ -1779,7 +1817,7 @@ recv_report_corrupt_log(
"InnoDB: Recv offset %lu, prev %lu\n",
recv_previous_parsed_rec_type,
recv_previous_parsed_rec_is_multi,
- ptr - recv_sys->buf,
+ (ulint)(ptr - recv_sys->buf),
recv_previous_parsed_rec_offset);
if ((ulint)(ptr - recv_sys->buf + 100)
@@ -1805,7 +1843,12 @@ recv_report_corrupt_log(
"InnoDB: WARNING: the log file may have been corrupt and it\n"
"InnoDB: is possible that the log scan did not proceed\n"
"InnoDB: far enough in recovery! Please run CHECK TABLE\n"
- "InnoDB: on your InnoDB tables to check that they are ok!\n");
+ "InnoDB: on your InnoDB tables to check that they are ok!\n"
+ "InnoDB: If mysqld crashes after this recovery, look at\n"
+ "InnoDB: section 6.1 of http://www.innodb.com/ibman.html\n"
+ "InnoDB: about forcing recovery.\n");
+
+ fflush(stderr);
}
/***********************************************************
@@ -2163,9 +2206,12 @@ recv_scan_log_recs(
while (log_block < buf + len && !finished) {
no = log_block_get_hdr_no(log_block);
+/*
+ fprintf(stderr, "Log block header no %lu\n", no);
- /* fprintf(stderr, "Log block header no %lu\n", no); */
-
+ fprintf(stderr, "Scanned lsn no %lu\n",
+ log_block_convert_lsn_to_no(scanned_lsn));
+*/
if (no != log_block_convert_lsn_to_no(scanned_lsn)
|| !log_block_checksum_is_ok_or_old_format(log_block)) {
@@ -2442,7 +2488,7 @@ recv_recovery_from_checkpoint_start(
log_hdr_buf, max_cp_group);
if (0 == ut_memcmp(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
- "ibbackup", ut_strlen("ibbackup"))) {
+ (byte*)"ibbackup", ut_strlen((char*)"ibbackup"))) {
/* This log file was created by ibbackup --restore: print
a note to the user about it */
@@ -2453,7 +2499,7 @@ recv_recovery_from_checkpoint_start(
/* Wipe over the label now */
ut_memcpy(log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
- " ", 4);
+ (char*)" ", 4);
/* Write to the log file to wipe over the label */
fil_io(OS_FILE_WRITE | OS_FILE_LOG, TRUE,
max_cp_group->space_id,
@@ -2557,7 +2603,6 @@ recv_recovery_from_checkpoint_start(
recv_group_scan_log_recs(group, &contiguous_lsn,
&group_scanned_lsn);
-
group->scanned_lsn = group_scanned_lsn;
if (ut_dulint_cmp(old_scanned_lsn, group_scanned_lsn) < 0) {
@@ -2574,6 +2619,31 @@ recv_recovery_from_checkpoint_start(
group = UT_LIST_GET_NEXT(log_groups, group);
}
+ /* We currently have only one log group */
+ if (ut_dulint_cmp(group_scanned_lsn, checkpoint_lsn) < 0) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: ERROR: We were only able to scan the log up to\n"
+"InnoDB: %lu %lu, but a checkpoint was at %lu %lu.\n"
+"InnoDB: It is possible that the database is now corrupt!\n",
+ ut_dulint_get_high(group_scanned_lsn),
+ ut_dulint_get_low(group_scanned_lsn),
+ ut_dulint_get_high(checkpoint_lsn),
+ ut_dulint_get_low(checkpoint_lsn));
+ }
+
+ if (ut_dulint_cmp(group_scanned_lsn, recv_max_page_lsn) < 0) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: ERROR: We were only able to scan the log up to %lu %lu\n"
+"InnoDB: but a database page a had an lsn %lu %lu. It is possible that the\n"
+"InnoDB: database is now corrupt!\n",
+ ut_dulint_get_high(group_scanned_lsn),
+ ut_dulint_get_low(group_scanned_lsn),
+ ut_dulint_get_high(recv_max_page_lsn),
+ ut_dulint_get_low(recv_max_page_lsn));
+ }
+
if (ut_dulint_cmp(recv_sys->recovered_lsn, checkpoint_lsn) < 0) {
mutex_exit(&(log_sys->mutex));
@@ -2627,6 +2697,8 @@ recv_recovery_from_checkpoint_start(
sync_order_checks_on = FALSE;
+ recv_lsn_checks_on = TRUE;
+
/* The database is now ready to start almost normal processing of user
transactions: transaction rollbacks and the application of the log
records in the hash table can be run in background. */
diff --git a/innobase/mach/Makefile.am b/innobase/mach/Makefile.am
index 8195831e92e..ce827c8033f 100644
--- a/innobase/mach/Makefile.am
+++ b/innobase/mach/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libmach.a
+noinst_LIBRARIES = libmach.a
libmach_a_SOURCES = mach0data.c
diff --git a/innobase/mem/Makefile.am b/innobase/mem/Makefile.am
index 84f642e4469..10b7771b580 100644
--- a/innobase/mem/Makefile.am
+++ b/innobase/mem/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libmem.a
+noinst_LIBRARIES = libmem.a
libmem_a_SOURCES = mem0mem.c mem0pool.c
diff --git a/innobase/mem/mem0dbg.c b/innobase/mem/mem0dbg.c
index 6bedbd40fef..22d0bab0da2 100644
--- a/innobase/mem/mem0dbg.c
+++ b/innobase/mem/mem0dbg.c
@@ -347,9 +347,19 @@ mem_hash_remove(
NULL, NULL);
if (error) {
printf("Inconsistency in memory heap or buffer n:o %lu created\n",
- node->nth_heap);
+ node->nth_heap);
printf("in %s line %lu and tried to free in %s line %lu.\n",
node->file_name, node->line, file_name, line);
+
+ printf(
+ "Hex dump of 400 bytes around memory heap first block start:\n");
+
+ ut_print_buf((byte*)(node->heap) - 200, 400);
+
+ printf("\nDump of the mem heap:\n");
+
+ mem_heap_validate_or_print(node->heap, NULL, TRUE, &error, &size,
+ NULL, NULL);
ut_error;
}
@@ -372,7 +382,8 @@ void
mem_heap_validate_or_print(
/*=======================*/
mem_heap_t* heap, /* in: memory heap */
- byte* top, /* in: calculate and validate only until
+ byte* top __attribute__((unused)),
+ /* in: calculate and validate only until
this top pointer in the heap is reached,
if this pointer is NULL, ignored */
ibool print, /* in: if TRUE, prints the contents
@@ -578,7 +589,8 @@ static
void
mem_print_info_low(
/*===============*/
- ibool print_all) /* in: if TRUE, all heaps are printed,
+ ibool print_all __attribute__((unused)))
+ /* in: if TRUE, all heaps are printed,
else only the heaps allocated after the
previous call of this function */
{
diff --git a/innobase/mem/mem0pool.c b/innobase/mem/mem0pool.c
index 61cf1e50ce9..b004a8c4df7 100644
--- a/innobase/mem/mem0pool.c
+++ b/innobase/mem/mem0pool.c
@@ -15,6 +15,7 @@ Created 5/12/1997 Heikki Tuuri
#include "ut0mem.h"
#include "ut0lst.h"
#include "ut0byte.h"
+#include "mem0mem.h"
/* We would like to use also the buffer frames to allocate memory. This
would be desirable, because then the memory consumption of the database
@@ -98,6 +99,12 @@ mem_pool_t* mem_comm_pool = NULL;
ulint mem_out_of_mem_err_msg_count = 0;
+/* We use this counter to check that the mem pool mutex does not leak;
+this is to track a strange assertion failure reported at
+mysql@lists.mysql.com */
+
+ulint mem_n_threads_inside = 0;
+
/************************************************************************
Reserves the mem pool mutex. */
@@ -251,7 +258,6 @@ mem_pool_fill_free_list(
mem_area_t* area;
mem_area_t* area2;
ibool ret;
- char err_buf[500];
ut_ad(mutex_own(&(pool->mutex)));
@@ -259,19 +265,6 @@ mem_pool_fill_free_list(
/* We come here when we have run out of space in the
memory pool: */
- if (mem_out_of_mem_err_msg_count % 1000000000 == 0) {
- /* We do not print the message every time: */
-
- ut_print_timestamp(stderr);
-
- fprintf(stderr,
- " InnoDB: Out of memory in additional memory pool.\n"
- "InnoDB: InnoDB will start allocating memory from the OS.\n"
- "InnoDB: You may get better performance if you configure a bigger\n"
- "InnoDB: value in the MySQL my.cnf file for\n"
- "InnoDB: innodb_additional_mem_pool_size.\n");
- }
-
mem_out_of_mem_err_msg_count++;
return(FALSE);
@@ -300,11 +293,8 @@ mem_pool_fill_free_list(
}
if (UT_LIST_GET_LEN(pool->free_list[i + 1]) == 0) {
- ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100);
- fprintf(stderr,
-"InnoDB: Error: Removing element from mem pool free list %lu\n"
-"InnoDB: though the list length is 0! Dump of 100 bytes around element:\n%s\n",
- i + 1, err_buf);
+ mem_analyze_corruption((byte*)area);
+
ut_a(0);
}
@@ -340,11 +330,13 @@ mem_area_alloc(
mem_area_t* area;
ulint n;
ibool ret;
- char err_buf[500];
n = ut_2_log(ut_max(size + MEM_AREA_EXTRA_SIZE, MEM_AREA_MIN_SIZE));
mutex_enter(&(pool->mutex));
+ mem_n_threads_inside++;
+
+ ut_a(mem_n_threads_inside == 1);
area = UT_LIST_GET_FIRST(pool->free_list[n]);
@@ -355,6 +347,7 @@ mem_area_alloc(
/* Out of memory in memory pool: we try to allocate
from the operating system with the regular malloc: */
+ mem_n_threads_inside--;
mutex_exit(&(pool->mutex));
return(ut_malloc(size));
@@ -364,20 +357,32 @@ mem_area_alloc(
}
if (!mem_area_get_free(area)) {
- ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100);
fprintf(stderr,
"InnoDB: Error: Removing element from mem pool free list %lu though the\n"
-"InnoDB: element is not marked free! Dump of 100 bytes around element:\n%s\n",
- n, err_buf);
+"InnoDB: element is not marked free!\n",
+ n);
+
+ mem_analyze_corruption((byte*)area);
+
+ /* Try to analyze a strange assertion failure reported at
+ mysql@lists.mysql.com where the free bit IS 1 in the
+ hex dump above */
+
+ if (mem_area_get_free(area)) {
+ fprintf(stderr,
+"InnoDB: Probably a race condition because now the area is marked free!\n");
+ }
+
ut_a(0);
}
if (UT_LIST_GET_LEN(pool->free_list[n]) == 0) {
- ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100);
fprintf(stderr,
"InnoDB: Error: Removing element from mem pool free list %lu\n"
-"InnoDB: though the list length is 0! Dump of 100 bytes around element:\n%s\n",
- n, err_buf);
+"InnoDB: though the list length is 0!\n",
+ n);
+ mem_analyze_corruption((byte*)area);
+
ut_a(0);
}
@@ -389,6 +394,7 @@ mem_area_alloc(
pool->reserved += mem_area_get_size(area);
+ mem_n_threads_inside--;
mutex_exit(&(pool->mutex));
ut_ad(mem_pool_validate(pool));
@@ -451,7 +457,6 @@ mem_area_free(
void* new_ptr;
ulint size;
ulint n;
- char err_buf[500];
if (mem_out_of_mem_err_msg_count > 0) {
/* It may be that the area was really allocated from the
@@ -468,18 +473,25 @@ mem_area_free(
area = (mem_area_t*) (((byte*)ptr) - MEM_AREA_EXTRA_SIZE);
- if (mem_area_get_free(area)) {
- ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100);
+ if (mem_area_get_free(area)) {
fprintf(stderr,
"InnoDB: Error: Freeing element to mem pool free list though the\n"
-"InnoDB: element is marked free! Dump of 100 bytes around element:\n%s\n",
- err_buf);
+"InnoDB: element is marked free!\n");
+
+ mem_analyze_corruption((byte*)area);
ut_a(0);
}
size = mem_area_get_size(area);
- ut_ad(size != 0);
+ if (size == 0) {
+ fprintf(stderr,
+"InnoDB: Error: Mem area size is 0. Possibly a memory overrun of the\n"
+"InnoDB: previous allocated area!\n");
+
+ mem_analyze_corruption((byte*)area);
+ ut_a(0);
+ }
#ifdef UNIV_LIGHT_MEM_DEBUG
if (((byte*)area) + size < pool->buf + pool->size) {
@@ -488,7 +500,15 @@ mem_area_free(
next_size = mem_area_get_size(
(mem_area_t*)(((byte*)area) + size));
- ut_a(ut_2_power_up(next_size) == next_size);
+ if (ut_2_power_up(next_size) != next_size) {
+ fprintf(stderr,
+"InnoDB: Error: Memory area size %lu, next area size %lu not a power of 2!\n"
+"InnoDB: Possibly a memory overrun of the buffer being freed here.\n",
+ size, next_size);
+ mem_analyze_corruption((byte*)area);
+
+ ut_a(0);
+ }
}
#endif
buddy = mem_area_get_buddy(area, size, pool);
@@ -496,6 +516,9 @@ mem_area_free(
n = ut_2_log(size);
mutex_enter(&(pool->mutex));
+ mem_n_threads_inside++;
+
+ ut_a(mem_n_threads_inside == 1);
if (buddy && mem_area_get_free(buddy)
&& (size == mem_area_get_size(buddy))) {
@@ -519,6 +542,7 @@ mem_area_free(
pool->reserved += ut_2_exp(n);
+ mem_n_threads_inside--;
mutex_exit(&(pool->mutex));
mem_area_free(new_ptr, pool);
@@ -534,6 +558,7 @@ mem_area_free(
pool->reserved -= size;
}
+ mem_n_threads_inside--;
mutex_exit(&(pool->mutex));
ut_ad(mem_pool_validate(pool));
@@ -578,7 +603,7 @@ mem_pool_validate(
}
}
- ut_a(free + pool->reserved == pool->size
+ ut_anp(free + pool->reserved == pool->size
- (pool->size % MEM_AREA_MIN_SIZE));
mutex_exit(&(pool->mutex));
diff --git a/innobase/mtr/Makefile.am b/innobase/mtr/Makefile.am
index 972dcaca80e..1e93a34ce23 100644
--- a/innobase/mtr/Makefile.am
+++ b/innobase/mtr/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libmtr.a
+noinst_LIBRARIES = libmtr.a
libmtr_a_SOURCES = mtr0mtr.c mtr0log.c
diff --git a/innobase/mtr/mtr0mtr.c b/innobase/mtr/mtr0mtr.c
index 565489613ae..e9a6e39d98f 100644
--- a/innobase/mtr/mtr0mtr.c
+++ b/innobase/mtr/mtr0mtr.c
@@ -469,7 +469,8 @@ mtr_read_ulint(
/* out: value read */
byte* ptr, /* in: pointer from where to read */
ulint type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr __attribute__((unused)))
+ /* in: mini-transaction handle */
{
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(mtr_memo_contains(mtr, buf_block_align(ptr),
@@ -494,8 +495,9 @@ mtr_read_dulint(
/*===========*/
/* out: value read */
byte* ptr, /* in: pointer from where to read */
- ulint type, /* in: MLOG_8BYTES */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint type __attribute__((unused)), /* in: MLOG_8BYTES */
+ mtr_t* mtr __attribute__((unused)))
+ /* in: mini-transaction handle */
{
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(ptr && mtr);
diff --git a/innobase/odbc/Makefile.am b/innobase/odbc/Makefile.am
index d1a47bd8c18..f4282ba3907 100644
--- a/innobase/odbc/Makefile.am
+++ b/innobase/odbc/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libodbc.a
+noinst_LIBRARIES = libodbc.a
libodbc_a_SOURCES = odbc0odbc.c
diff --git a/innobase/odbc/odbc0odbc.c b/innobase/odbc/odbc0odbc.c
index 640a88a2503..0deb17c6714 100644
--- a/innobase/odbc/odbc0odbc.c
+++ b/innobase/odbc/odbc0odbc.c
@@ -421,7 +421,7 @@ SQLError(
}
*pfNativeError = 0;
- ut_memcpy(szSqlState, "S1000", 6);
+ ut_memcpy(szSqlState, (char *) "S1000", 6);
len = (ulint)cbErrorMsgMax - 1;
diff --git a/innobase/os/Makefile.am b/innobase/os/Makefile.am
index b06670bc703..132ce07c83b 100644
--- a/innobase/os/Makefile.am
+++ b/innobase/os/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libos.a
+noinst_LIBRARIES = libos.a
libos_a_SOURCES = os0proc.c os0shm.c os0sync.c os0thread.c os0file.c
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index 46474d3576a..55d0ade1bf7 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -60,6 +60,7 @@ struct os_aio_slot_struct{
ulint pos; /* index of the slot in the aio
array */
ibool reserved; /* TRUE if this slot is reserved */
+ time_t reservation_time;/* time when reserved */
ulint len; /* length of the block to read or
write */
byte* buf; /* buffer used in i/o */
@@ -80,6 +81,8 @@ struct os_aio_slot_struct{
which pending aio operation was
completed */
#ifdef WIN_ASYNC_IO
+ os_event_t event; /* event object we need in the
+ OVERLAPPED struct */
OVERLAPPED control; /* Windows control block for the
aio request */
#elif defined(POSIX_ASYNC_IO)
@@ -107,11 +110,14 @@ struct os_aio_array_struct{
ulint n_reserved;/* Number of reserved slots in the
aio array outside the ibuf segment */
os_aio_slot_t* slots; /* Pointer to the slots in the array */
- os_event_t* events; /* Pointer to an array of event handles
- where we copied the handles from slots,
- in the same order. This can be used in
- WaitForMultipleObjects; used only in
+#ifdef __WIN__
+ os_native_event_t* native_events;
+ /* Pointer to an array of OS native event
+ handles where we copied the handles from
+ slots, in the same order. This can be used
+ in WaitForMultipleObjects; used only in
Windows */
+#endif
};
/* Array of events used in simulated aio */
@@ -142,6 +148,12 @@ time_t os_last_printout;
ibool os_has_said_disk_full = FALSE;
+/* The mutex protecting the following counts of pending pread and pwrite
+operations */
+os_mutex_t os_file_count_mutex;
+ulint os_file_n_pending_preads = 0;
+ulint os_file_n_pending_pwrites = 0;
+
/***************************************************************************
Gets the operating system version. Currently works only on Windows. */
@@ -149,7 +161,7 @@ Gets the operating system version. Currently works only on Windows. */
ulint
os_get_os_version(void)
/*===================*/
- /* out: OS_WIN95, OS_WIN31, OS_WINNT (2000 == NT) */
+ /* out: OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */
{
#ifdef __WIN__
OSVERSIONINFO os_info;
@@ -163,7 +175,11 @@ os_get_os_version(void)
} else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
return(OS_WIN95);
} else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- return(OS_WINNT);
+ if (os_info.dwMajorVersion <= 4) {
+ return(OS_WINNT);
+ } else {
+ return(OS_WIN2000);
+ }
} else {
ut_error;
return(0);
@@ -192,12 +208,12 @@ os_file_get_last_error(void)
err = (ulint) GetLastError();
- if (err != ERROR_FILE_EXISTS && err != ERROR_DISK_FULL) {
+ if (err != ERROR_DISK_FULL && err != ERROR_FILE_EXISTS) {
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Operating system error number %li in a file operation.\n"
+ " InnoDB: Operating system error number %lu in a file operation.\n"
"InnoDB: See http://www.innodb.com/ibman.html for installation help.\n",
- (long) err);
+ err);
if (err == ERROR_PATH_NOT_FOUND) {
fprintf(stderr,
@@ -210,12 +226,14 @@ os_file_get_last_error(void)
"InnoDB: the directory. It may also be you have created a subdirectory\n"
"InnoDB: of the same name as a data file.\n");
} else {
- fprintf(stderr,
- "InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n"
- "InnoDB: what the error number means.\n");
+ fprintf(stderr,
+ "InnoDB: See section 13.2 at http://www.innodb.com/ibman.html\n"
+ "InnoDB: about operating system error numbers.\n");
}
}
+ fflush(stderr);
+
if (err == ERROR_FILE_NOT_FOUND) {
return(OS_FILE_NOT_FOUND);
} else if (err == ERROR_DISK_FULL) {
@@ -228,13 +246,13 @@ os_file_get_last_error(void)
#else
err = (ulint) errno;
- if (err != EEXIST && err != ENOSPC ) {
+ if (err != ENOSPC && err != EEXIST) {
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Operating system error number %li in a file operation.\n"
+ " InnoDB: Operating system error number %lu in a file operation.\n"
"InnoDB: See http://www.innodb.com/ibman.html for installation help.\n",
- (long) err);
+ err);
if (err == ENOENT) {
fprintf(stderr,
@@ -246,12 +264,19 @@ os_file_get_last_error(void)
"InnoDB: The error means mysqld does not have the access rights to\n"
"InnoDB: the directory.\n");
} else {
- fprintf(stderr,
- "InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n"
- "InnoDB: what the error number means or use the perror program of MySQL.\n");
+ if (strerror((int)err) != NULL) {
+ fprintf(stderr,
+ "InnoDB: Error number %lu means '%s'.\n", err, strerror((int)err));
+ }
+
+ fprintf(stderr,
+ "InnoDB: See also section 13.2 at http://www.innodb.com/ibman.html\n"
+ "InnoDB: about operating system error numbers.\n");
}
}
+ fflush(stderr);
+
if (err == ENOSPC ) {
return(OS_FILE_DISK_FULL);
#ifdef POSIX_ASYNC_IO
@@ -269,16 +294,16 @@ os_file_get_last_error(void)
}
/********************************************************************
-Does error handling when a file operation fails. If we have run out
-of disk space, then the user can clean the disk. If we do not find
-a specified file, then the user can copy it to disk. */
+Does error handling when a file operation fails. */
static
ibool
os_file_handle_error(
/*=================*/
- /* out: TRUE if we should retry the operation */
+ /* out: TRUE if we should retry the
+ operation */
os_file_t file, /* in: file pointer */
- char* name) /* in: name of a file or NULL */
+ char* name, /* in: name of a file or NULL */
+ const char* operation)/* in: operation */
{
ulint err;
@@ -306,20 +331,27 @@ os_file_handle_error(
os_has_said_disk_full = TRUE;
+ fflush(stderr);
+
return(FALSE);
} else if (err == OS_FILE_AIO_RESOURCES_RESERVED) {
return(TRUE);
} else if (err == OS_FILE_ALREADY_EXISTS) {
+
return(FALSE);
} else {
if (name) {
fprintf(stderr, "InnoDB: File name %s\n", name);
}
+ fprintf(stderr, "InnoDB: File operation call: '%s'.\n",
+ operation);
fprintf(stderr, "InnoDB: Cannot continue operation.\n");
+ fflush(stderr);
+
exit(1);
}
@@ -335,6 +367,8 @@ os_io_init_simple(void)
{
ulint i;
+ os_file_count_mutex = os_mutex_create(NULL);
+
for (i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) {
os_file_seek_mutexes[i] = os_mutex_create(NULL);
}
@@ -386,8 +420,7 @@ try_again:
file = CreateFile(name,
access,
- FILE_SHARE_READ,
- /* file can be read also by other
+ FILE_SHARE_READ,/* file can be read also by other
processes */
NULL, /* default security attributes */
create_flag,
@@ -397,8 +430,9 @@ try_again:
if (file == INVALID_HANDLE_VALUE) {
*success = FALSE;
- retry = os_file_handle_error(file, name);
-
+ retry = os_file_handle_error(file, name,
+ create_mode == OS_FILE_OPEN ?
+ "open" : "create");
if (retry) {
goto try_again;
}
@@ -438,8 +472,9 @@ try_again:
if (file == -1) {
*success = FALSE;
- retry = os_file_handle_error(file, name);
-
+ retry = os_file_handle_error(file, name,
+ create_mode == OS_FILE_OPEN ?
+ "open" : "create");
if (retry) {
goto try_again;
}
@@ -450,6 +485,101 @@ try_again:
return(file);
#endif
}
+
+/********************************************************************
+A simple function to open or create a file. */
+
+os_file_t
+os_file_create_simple_no_error_handling(
+/*====================================*/
+ /* out, own: handle to the file, not defined if error,
+ error number can be retrieved with os_get_last_error */
+ char* name, /* in: name of the file or path as a null-terminated
+ string */
+ ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened
+ (if does not exist, error), or OS_FILE_CREATE if a new
+ file is created (if exists, error) */
+ ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */
+ ibool* success)/* out: TRUE if succeed, FALSE if error */
+{
+#ifdef __WIN__
+ os_file_t file;
+ DWORD create_flag;
+ DWORD access;
+ DWORD attributes = 0;
+
+ ut_a(name);
+
+ if (create_mode == OS_FILE_OPEN) {
+ create_flag = OPEN_EXISTING;
+ } else if (create_mode == OS_FILE_CREATE) {
+ create_flag = CREATE_NEW;
+ } else {
+ create_flag = 0;
+ ut_error;
+ }
+
+ if (access_type == OS_FILE_READ_ONLY) {
+ access = GENERIC_READ;
+ } else if (access_type == OS_FILE_READ_WRITE) {
+ access = GENERIC_READ | GENERIC_WRITE;
+ } else {
+ access = 0;
+ ut_error;
+ }
+
+ file = CreateFile(name,
+ access,
+ FILE_SHARE_READ,/* file can be read also by other
+ processes */
+ NULL, /* default security attributes */
+ create_flag,
+ attributes,
+ NULL); /* no template file */
+
+ if (file == INVALID_HANDLE_VALUE) {
+ *success = FALSE;
+ } else {
+ *success = TRUE;
+ }
+
+ return(file);
+#else
+ os_file_t file;
+ int create_flag;
+
+ ut_a(name);
+
+ if (create_mode == OS_FILE_OPEN) {
+ if (access_type == OS_FILE_READ_ONLY) {
+ create_flag = O_RDONLY;
+ } else {
+ create_flag = O_RDWR;
+ }
+ } else if (create_mode == OS_FILE_CREATE) {
+ create_flag = O_RDWR | O_CREAT | O_EXCL;
+ } else {
+ create_flag = 0;
+ ut_error;
+ }
+
+ if (create_mode == OS_FILE_CREATE) {
+ file = open(name, create_flag, S_IRUSR | S_IWUSR
+ | S_IRGRP | S_IWGRP);
+ } else {
+ file = open(name, create_flag);
+ }
+
+ if (file == -1) {
+ *success = FALSE;
+ } else {
+ *success = TRUE;
+ }
+
+ return(file);
+#endif
+}
+
/********************************************************************
Opens an existing file or creates a new. */
@@ -465,7 +595,11 @@ os_file_create(
file is created (if exists, error), OS_FILE_OVERWRITE
if a new is created or an old overwritten */
ulint purpose,/* in: OS_FILE_AIO, if asynchronous, non-buffered i/o
- is desired, OS_FILE_NORMAL, if any normal file */
+ is desired, OS_FILE_NORMAL, if any normal file;
+ NOTE that it also depends on type, os_aio_.. and srv_..
+ variables whether we really use async i/o or
+ unbuffered i/o: look in the function source code for
+ the exact rules */
ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */
ibool* success)/* out: TRUE if succeed, FALSE if error */
{
@@ -490,8 +624,8 @@ try_again:
}
if (purpose == OS_FILE_AIO) {
- /* use asynchronous (overlapped) io and no buffering
- of writes in the OS */
+ /* If specified, use asynchronous (overlapped) io and no
+ buffering of writes in the OS */
attributes = 0;
#ifdef WIN_ASYNC_IO
if (os_aio_use_native_aio) {
@@ -503,7 +637,8 @@ try_again:
/* Do not use unbuffered i/o to log files because
value 2 denotes that we do not flush the log at every
commit, but only once per second */
- } else {
+ } else if (srv_win_file_flush_method ==
+ SRV_WIN_IO_UNBUFFERED) {
attributes = attributes | FILE_FLAG_NO_BUFFERING;
}
#endif
@@ -514,7 +649,8 @@ try_again:
/* Do not use unbuffered i/o to log files because
value 2 denotes that we do not flush the log at every
commit, but only once per second */
- } else {
+ } else if (srv_win_file_flush_method ==
+ SRV_WIN_IO_UNBUFFERED) {
attributes = attributes | FILE_FLAG_NO_BUFFERING;
}
#endif
@@ -542,8 +678,9 @@ try_again:
if (file == INVALID_HANDLE_VALUE) {
*success = FALSE;
- retry = os_file_handle_error(file, name);
-
+ retry = os_file_handle_error(file, name,
+ create_mode == OS_FILE_OPEN ?
+ "open" : "create");
if (retry) {
goto try_again;
}
@@ -556,30 +693,70 @@ try_again:
os_file_t file;
int create_flag;
ibool retry;
+ const char* mode_str = NULL;
+ const char* type_str = NULL;
+ const char* purpose_str = NULL;
try_again:
ut_a(name);
if (create_mode == OS_FILE_OPEN) {
+ mode_str = "OPEN";
+
create_flag = O_RDWR;
} else if (create_mode == OS_FILE_CREATE) {
+ mode_str = "CREATE";
+
create_flag = O_RDWR | O_CREAT | O_EXCL;
} else if (create_mode == OS_FILE_OVERWRITE) {
+ mode_str = "OVERWRITE";
+
create_flag = O_RDWR | O_CREAT | O_TRUNC;
} else {
create_flag = 0;
ut_error;
}
- UT_NOT_USED(purpose);
+ if (type == OS_LOG_FILE) {
+ type_str = "LOG";
+ } else if (type == OS_DATA_FILE) {
+ type_str = "DATA";
+ } else {
+ ut_a(0);
+ }
+
+ if (purpose == OS_FILE_AIO) {
+ purpose_str = "AIO";
+ } else if (purpose == OS_FILE_NORMAL) {
+ purpose_str = "NORMAL";
+ } else {
+ ut_a(0);
+ }
+/* printf("Opening file %s, mode %s, type %s, purpose %s\n",
+ name, mode_str, type_str, purpose_str); */
#ifdef O_SYNC
- if ((!srv_use_doublewrite_buf || type != OS_DATA_FILE)
+ /* We let O_SYNC only affect log files; note that we map O_DSYNC to
+ O_SYNC because the datasync options seemed to corrupt files in 2001
+ in both Linux and Solaris */
+ if (type == OS_LOG_FILE
&& srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
+/* printf("Using O_SYNC for file %s\n", name); */
+
create_flag = create_flag | O_SYNC;
}
#endif
+#ifdef O_DIRECT
+ /* We let O_DIRECT only affect data files */
+ if (type != OS_LOG_FILE
+ && srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
+
+/* printf("Using O_DIRECT for file %s\n", name); */
+
+ create_flag = create_flag | O_DIRECT;
+ }
+#endif
if (create_mode == OS_FILE_CREATE) {
file = open(name, create_flag, os_innodb_umask);
} else {
@@ -589,8 +766,9 @@ try_again:
if (file == -1) {
*success = FALSE;
- retry = os_file_handle_error(file, name);
-
+ retry = os_file_handle_error(file, name,
+ create_mode == OS_FILE_OPEN ?
+ "open" : "create");
if (retry) {
goto try_again;
}
@@ -623,7 +801,42 @@ os_file_close(
return(TRUE);
}
- os_file_handle_error(file, NULL);
+ os_file_handle_error(file, NULL, "close");
+ return(FALSE);
+#else
+ int ret;
+
+ ret = close(file);
+
+ if (ret == -1) {
+ os_file_handle_error(file, NULL, "close");
+ return(FALSE);
+ }
+
+ return(TRUE);
+#endif
+}
+
+/***************************************************************************
+Closes a file handle. */
+
+ibool
+os_file_close_no_error_handling(
+/*============================*/
+ /* out: TRUE if success */
+ os_file_t file) /* in, own: handle to a file */
+{
+#ifdef __WIN__
+ BOOL ret;
+
+ ut_a(file);
+
+ ret = CloseHandle(file);
+
+ if (ret) {
+ return(TRUE);
+ }
+
return(FALSE);
#else
int ret;
@@ -631,7 +844,7 @@ os_file_close(
ret = close(file);
if (ret == -1) {
- os_file_handle_error(file, NULL);
+
return(FALSE);
}
@@ -726,7 +939,12 @@ os_file_set_size(
offset = 0;
low = (ib_longlong)size + (((ib_longlong)size_high) << 32);
+
+ if (low >= (ib_longlong)(100 * 1024 * 1024)) {
+ fprintf(stderr, "InnoDB: Progress in MB:");
+ }
+
while (offset < low) {
if (low - offset < UNIV_PAGE_SIZE * 512) {
n_bytes = (ulint)(low - offset);
@@ -742,9 +960,24 @@ os_file_set_size(
ut_free(buf2);
goto error_handling;
}
+
+ /* Print about progress for each 100 MB written */
+ if ((offset + n_bytes) / (ib_longlong)(100 * 1024 * 1024)
+ != offset / (ib_longlong)(100 * 1024 * 1024)) {
+
+ fprintf(stderr, " %lu00",
+ (ulint)((offset + n_bytes)
+ / (ib_longlong)(100 * 1024 * 1024)));
+ }
+
offset += n_bytes;
}
+ if (low >= (ib_longlong)(100 * 1024 * 1024)) {
+
+ fprintf(stderr, "\n");
+ }
+
ut_free(buf2);
ret = os_file_flush(file);
@@ -779,7 +1012,7 @@ os_file_flush(
return(TRUE);
}
- os_file_handle_error(file, NULL);
+ os_file_handle_error(file, NULL, "flush");
/* It is a fatal error if a file flush does not succeed, because then
the database can get corrupt on disk */
@@ -792,6 +1025,7 @@ os_file_flush(
#ifdef HAVE_FDATASYNC
ret = fdatasync(file);
#else
+/* printf("Flushing to file %lu\n", (ulint)file); */
ret = fsync(file);
#endif
os_n_fsyncs++;
@@ -812,7 +1046,7 @@ os_file_flush(
fprintf(stderr,
" InnoDB: Error: the OS said file flush did not succeed\n");
- os_file_handle_error(file, NULL);
+ os_file_handle_error(file, NULL, "flush");
/* It is a fatal error if a file flush does not succeed, because then
the database can get corrupt on disk */
@@ -839,6 +1073,7 @@ os_file_pread(
offset */
{
off_t offs;
+ ssize_t n_bytes;
ut_a((offset & 0xFFFFFFFF) == offset);
@@ -860,7 +1095,17 @@ os_file_pread(
os_n_file_reads++;
#ifdef HAVE_PREAD
- return(pread(file, buf, n, offs));
+ os_mutex_enter(os_file_count_mutex);
+ os_file_n_pending_preads++;
+ os_mutex_exit(os_file_count_mutex);
+
+ n_bytes = pread(file, buf, n, offs);
+
+ os_mutex_enter(os_file_count_mutex);
+ os_file_n_pending_preads--;
+ os_mutex_exit(os_file_count_mutex);
+
+ return(n_bytes);
#else
{
ssize_t ret;
@@ -925,8 +1170,16 @@ os_file_pwrite(
os_n_file_writes++;
#ifdef HAVE_PWRITE
+ os_mutex_enter(os_file_count_mutex);
+ os_file_n_pending_pwrites++;
+ os_mutex_exit(os_file_count_mutex);
+
ret = pwrite(file, buf, n, offs);
+ os_mutex_enter(os_file_count_mutex);
+ os_file_n_pending_pwrites--;
+ os_mutex_exit(os_file_count_mutex);
+
if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC
&& srv_unix_file_flush_method != SRV_UNIX_NOSYNC
&& !os_do_not_call_flush_at_each_write) {
@@ -1053,12 +1306,22 @@ try_again:
#ifdef __WIN__
error_handling:
#endif
- retry = os_file_handle_error(file, NULL);
+ retry = os_file_handle_error(file, NULL, "read");
if (retry) {
goto try_again;
}
-
+
+ fprintf(stderr,
+"InnoDB: Fatal error: cannot read from file. OS error number %lu.\n",
+#ifdef __WIN__
+ (ulint)GetLastError()
+#else
+ (ulint)errno
+#endif
+ );
+ fflush(stderr);
+
ut_error;
return(FALSE);
@@ -1090,6 +1353,7 @@ os_file_write(
DWORD high;
ulint i;
ulint n_retries = 0;
+ ulint err;
ut_a((offset & 0xFFFFFFFF) == offset);
@@ -1157,18 +1421,27 @@ retry:
if (!os_has_said_disk_full) {
+ err = (ulint)GetLastError();
+
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: Write to file %s failed at offset %lu %lu.\n"
"InnoDB: %lu bytes should have been written, only %lu were written.\n"
"InnoDB: Operating system error number %lu.\n"
-"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n"
-"InnoDB: what the error number means.\n"
"InnoDB: Check that your OS and file system support files of this size.\n"
"InnoDB: Check also that the disk is not full or a disk quota exceeded.\n",
name, offset_high, offset, n, (ulint)len,
- (ulint)GetLastError());
+ err);
+
+ if (strerror((int)err) != NULL) {
+ fprintf(stderr,
+"InnoDB: Error number %lu means '%s'.\n", err, strerror((int)err));
+ }
+
+ fprintf(stderr,
+"InnoDB: See also section 13.2 at http://www.innodb.com/ibman.html\n"
+"InnoDB: about operating system error numbers.\n");
os_has_said_disk_full = TRUE;
}
@@ -1192,12 +1465,19 @@ retry:
" InnoDB: Error: Write to file %s failed at offset %lu %lu.\n"
"InnoDB: %lu bytes should have been written, only %ld were written.\n"
"InnoDB: Operating system error number %lu.\n"
-"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n"
-"InnoDB: what the error number means or use the perror program of MySQL.\n"
"InnoDB: Check that your OS and file system support files of this size.\n"
"InnoDB: Check also that the disk is not full or a disk quota exceeded.\n",
name, offset_high, offset, n, (long int)ret,
(ulint)errno);
+ if (strerror(errno) != NULL) {
+ fprintf(stderr,
+"InnoDB: Error number %lu means '%s'.\n", (ulint)errno, strerror(errno));
+ }
+
+ fprintf(stderr,
+"InnoDB: See also section 13.2 at http://www.innodb.com/ibman.html\n"
+"InnoDB: about operating system error numbers.\n");
+
os_has_said_disk_full = TRUE;
}
@@ -1239,7 +1519,6 @@ os_aio_array_create(
#endif
ut_a(n > 0);
ut_a(n_segments > 0);
- ut_a(n % n_segments == 0);
array = ut_malloc(sizeof(os_aio_array_t));
@@ -1253,19 +1532,22 @@ os_aio_array_create(
array->n_segments = n_segments;
array->n_reserved = 0;
array->slots = ut_malloc(n * sizeof(os_aio_slot_t));
- array->events = ut_malloc(n * sizeof(os_event_t));
-
+#ifdef __WIN__
+ array->native_events = ut_malloc(n * sizeof(os_native_event_t));
+#endif
for (i = 0; i < n; i++) {
slot = os_aio_array_get_nth_slot(array, i);
slot->pos = i;
slot->reserved = FALSE;
#ifdef WIN_ASYNC_IO
+ slot->event = os_event_create(NULL);
+
over = &(slot->control);
- over->hEvent = os_event_create(NULL);
+ over->hEvent = slot->event->handle;
- *((array->events) + i) = over->hEvent;
+ *((array->native_events) + i) = over->hEvent;
#endif
}
@@ -1303,19 +1585,35 @@ os_aio_init(
os_io_init_simple();
+ for (i = 0; i < n_segments; i++) {
+ srv_io_thread_op_info[i] = (char*)"not started yet";
+ }
+
n_per_seg = n / n_segments;
n_write_segs = (n_segments - 2) / 2;
n_read_segs = n_segments - 2 - n_write_segs;
/* printf("Array n per seg %lu\n", n_per_seg); */
+ os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1);
+
+ srv_io_thread_function[0] = (char*)"insert buffer thread";
+
+ os_aio_log_array = os_aio_array_create(n_per_seg, 1);
+
+ srv_io_thread_function[1] = (char*)"log thread";
+
os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg,
n_read_segs);
+ for (i = 2; i < 2 + n_read_segs; i++) {
+ srv_io_thread_function[i] = (char*)"read thread";
+ }
+
os_aio_write_array = os_aio_array_create(n_write_segs * n_per_seg,
n_write_segs);
- os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1);
-
- os_aio_log_array = os_aio_array_create(n_per_seg, 1);
+ for (i = 2 + n_read_segs; i < n_segments; i++) {
+ srv_io_thread_function[i] = (char*)"write thread";
+ }
os_aio_sync_array = os_aio_array_create(n_slots_sync, 1);
@@ -1348,6 +1646,50 @@ os_aio_init(
pthread_sigmask(SIG_BLOCK, &sigset, NULL); */
#endif
}
+
+#ifdef WIN_ASYNC_IO
+/****************************************************************************
+Wakes up all async i/o threads in the array in Windows async i/o at
+shutdown. */
+static
+void
+os_aio_array_wake_win_aio_at_shutdown(
+/*==================================*/
+ os_aio_array_t* array) /* in: aio array */
+{
+ ulint i;
+
+ for (i = 0; i < array->n_slots; i++) {
+
+ os_event_set((array->slots + i)->event);
+ }
+}
+#endif
+
+/****************************************************************************
+Wakes up all async i/o threads so that they know to exit themselves in
+shutdown. */
+
+void
+os_aio_wake_all_threads_at_shutdown(void)
+/*=====================================*/
+{
+ ulint i;
+
+#ifdef WIN_ASYNC_IO
+ /* This code wakes up all ai/o threads in Windows native aio */
+ os_aio_array_wake_win_aio_at_shutdown(os_aio_read_array);
+ os_aio_array_wake_win_aio_at_shutdown(os_aio_write_array);
+ os_aio_array_wake_win_aio_at_shutdown(os_aio_ibuf_array);
+ os_aio_array_wake_win_aio_at_shutdown(os_aio_log_array);
+#endif
+ /* This loop wakes up all simulated ai/o threads */
+
+ for (i = 0; i < os_aio_n_segments; i++) {
+
+ os_event_set(os_aio_segment_wait_events[i]);
+ }
+}
/****************************************************************************
Waits until there are no pending writes in os_aio_write_array. There can
@@ -1564,6 +1906,7 @@ loop:
}
slot->reserved = TRUE;
+ slot->reservation_time = time(NULL);
slot->message1 = message1;
slot->message2 = message2;
slot->file = file;
@@ -1579,7 +1922,7 @@ loop:
control = &(slot->control);
control->Offset = (DWORD)offset;
control->OffsetHigh = (DWORD)offset_high;
- os_event_reset(control->hEvent);
+ os_event_reset(slot->event);
#elif defined(POSIX_ASYNC_IO)
@@ -1637,7 +1980,7 @@ os_aio_array_free_slot(
}
#ifdef WIN_ASYNC_IO
- os_event_reset(slot->control.hEvent);
+ os_event_reset(slot->event);
#endif
os_mutex_exit(array->mutex);
}
@@ -1762,7 +2105,7 @@ os_aio(
offset where to read or write */
ulint offset_high, /* in: most significant 32 bits of
offset */
- ulint n, /* in: number of bytes to read or write */
+ ulint n, /* in: number of bytes to read or write */
void* message1,/* in: messages for the aio handler (these
can be used to identify a completed aio
operation); if mode is OS_AIO_SYNC, these
@@ -1772,6 +2115,7 @@ os_aio(
os_aio_array_t* array;
os_aio_slot_t* slot;
#ifdef WIN_ASYNC_IO
+ ibool retval;
BOOL ret = TRUE;
DWORD len = n;
void* dummy_mess1;
@@ -1805,7 +2149,8 @@ os_aio(
wait in the Windows case. */
if (type == OS_FILE_READ) {
- return(os_file_read(file, buf, offset, offset_high, n));
+ return(os_file_read(file, buf, offset,
+ offset_high, n));
}
ut_a(type == OS_FILE_WRITE);
@@ -1844,6 +2189,8 @@ try_again:
if (os_aio_use_native_aio) {
#ifdef WIN_ASYNC_IO
os_n_file_reads++;
+ os_bytes_read_since_printout += len;
+
ret = ReadFile(file, buf, (DWORD)n, &len,
&(slot->control));
#elif defined(POSIX_ASYNC_IO)
@@ -1881,8 +2228,7 @@ try_again:
#ifdef WIN_ASYNC_IO
if (os_aio_use_native_aio) {
if ((ret && len == n)
- || (!ret && GetLastError() == ERROR_IO_PENDING)) {
-
+ || (!ret && GetLastError() == ERROR_IO_PENDING)) {
/* aio was queued successfully! */
if (mode == OS_AIO_SYNC) {
@@ -1890,10 +2236,12 @@ try_again:
where we also use async i/o: in Windows we must
use the same wait mechanism as for async i/o */
- return(os_aio_windows_handle(ULINT_UNDEFINED,
+ retval = os_aio_windows_handle(ULINT_UNDEFINED,
slot->pos,
&dummy_mess1, &dummy_mess2,
- &dummy_type));
+ &dummy_type);
+
+ return(retval);
}
return(TRUE);
@@ -1910,15 +2258,13 @@ try_again:
os_aio_array_free_slot(array, slot);
- retry = os_file_handle_error(file, name);
-
+ retry = os_file_handle_error(file, name,
+ type == OS_FILE_READ ? "aio read" : "aio write");
if (retry) {
goto try_again;
}
- ut_error;
-
return(FALSE);
}
@@ -1978,15 +2324,15 @@ os_aio_windows_handle(
n = array->n_slots / array->n_segments;
if (array == os_aio_sync_array) {
- srv_io_thread_op_info[orig_seg] = "wait windows aio for 1 page";
-
- ut_ad(pos < array->n_slots);
- os_event_wait(array->events[pos]);
+ srv_io_thread_op_info[orig_seg] =
+ "wait Windows aio for 1 page";
+ os_event_wait(os_aio_array_get_nth_slot(array, pos)->event);
i = pos;
} else {
srv_io_thread_op_info[orig_seg] =
- "wait windows aio for n pages";
- i = os_event_wait_multiple(n, (array->events) + segment * n);
+ "wait Windows aio";
+ i = os_event_wait_multiple(n,
+ (array->native_events) + segment * n);
}
os_mutex_enter(array->mutex);
@@ -2011,10 +2357,8 @@ os_aio_windows_handle(
ut_a(TRUE == os_file_flush(slot->file));
}
} else {
- os_file_get_last_error();
-
- ut_error;
-
+ os_file_handle_error(slot->file, slot->name, "Windows aio");
+
ret_val = FALSE;
}
@@ -2135,8 +2479,10 @@ os_aio_simulated_handle(
ulint total_len;
ulint offs;
ulint lowest_offset;
+ ulint biggest_age;
+ ulint age;
byte* combined_buf;
- byte* combined_buf2;
+ byte* combined_buf2= 0; /* Remove warning */
ibool ret;
ulint n;
ulint i;
@@ -2187,22 +2533,55 @@ restart:
n_consecutive = 0;
- /* Look for an i/o request at the lowest offset in the array
- (we ignore the high 32 bits of the offset in these heuristics) */
+ /* If there are at least 2 seconds old requests, then pick the oldest
+ one to prevent starvation. If several requests have the same age,
+ then pick the one at the lowest offset. */
+ biggest_age = 0;
lowest_offset = ULINT_MAX;
-
+
for (i = 0; i < n; i++) {
slot = os_aio_array_get_nth_slot(array, i + segment * n);
- if (slot->reserved && slot->offset < lowest_offset) {
+ if (slot->reserved) {
+ age = (ulint)difftime(time(NULL),
+ slot->reservation_time);
+
+ if ((age >= 2 && age > biggest_age)
+ || (age >= 2 && age == biggest_age
+ && slot->offset < lowest_offset)) {
- /* Found an i/o request */
- consecutive_ios[0] = slot;
+ /* Found an i/o request */
+ consecutive_ios[0] = slot;
- n_consecutive = 1;
+ n_consecutive = 1;
- lowest_offset = slot->offset;
+ biggest_age = age;
+ lowest_offset = slot->offset;
+ }
+ }
+ }
+
+ if (n_consecutive == 0) {
+ /* There were no old requests. Look for an i/o request at the
+ lowest offset in the array (we ignore the high 32 bits of the
+ offset in these heuristics) */
+
+ lowest_offset = ULINT_MAX;
+
+ for (i = 0; i < n; i++) {
+ slot = os_aio_array_get_nth_slot(array,
+ i + segment * n);
+
+ if (slot->reserved && slot->offset < lowest_offset) {
+
+ /* Found an i/o request */
+ consecutive_ios[0] = slot;
+
+ n_consecutive = 1;
+
+ lowest_offset = slot->offset;
+ }
}
}
@@ -2297,7 +2676,15 @@ consecutive_loop:
/* Do the i/o with ordinary, synchronous i/o functions: */
if (slot->type == OS_FILE_WRITE) {
if (array == os_aio_write_array) {
-
+ if ((total_len % UNIV_PAGE_SIZE != 0)
+ || (slot->offset % UNIV_PAGE_SIZE != 0)) {
+ fprintf(stderr,
+"InnoDB: Error: trying a displaced write to %s %lu %lu, len %lu\n",
+ slot->name, slot->offset_high,
+ slot->offset, total_len);
+ ut_a(0);
+ }
+
/* Do a 'last millisecond' check that the page end
is sensible; reported page checksum errors from
Linux seem to wipe over the page end */
@@ -2308,7 +2695,7 @@ consecutive_loop:
+ FIL_PAGE_LSN + 4)
!= mach_read_from_4(combined_buf + len2
+ UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN + 4)) {
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: ERROR: The page to be written seems corrupt!\n");
@@ -2469,14 +2856,15 @@ os_aio_print(
double avg_bytes_read;
ulint i;
- if (buf_end - buf < 1000) {
+ if (buf_end - buf < 1200) {
return;
}
for (i = 0; i < srv_n_file_io_threads; i++) {
- buf += sprintf(buf, "I/O thread %lu state: %s\n", i,
- srv_io_thread_op_info[i]);
+ buf += sprintf(buf, "I/O thread %lu state: %s (%s)\n", i,
+ srv_io_thread_op_info[i],
+ srv_io_thread_function[i]);
}
buf += sprintf(buf, "Pending normal aio reads:");
@@ -2551,6 +2939,12 @@ loop:
"%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n",
os_n_file_reads, os_n_file_writes, os_n_fsyncs);
+ if (os_file_n_pending_preads != 0 || os_file_n_pending_pwrites != 0) {
+ buf += sprintf(buf,
+ "%lu pending preads, %lu pending pwrites\n",
+ os_file_n_pending_preads, os_file_n_pending_pwrites);
+ }
+
if (os_n_file_reads == os_n_file_reads_old) {
avg_bytes_read = 0.0;
} else {
diff --git a/innobase/os/os0proc.c b/innobase/os/os0proc.c
index 43a2db4d306..1ee448a4a44 100644
--- a/innobase/os/os0proc.c
+++ b/innobase/os/os0proc.c
@@ -19,6 +19,23 @@ Created 9/30/1995 Heikki Tuuri
#include "ut0mem.h"
/********************************************************************
+Converts the current process id to a number. It is not guaranteed that the
+number is unique. In Linux returns the 'process number' of the current
+thread. That number is the same as one sees in 'top', for example. In Linux
+the thread id is not the same as one sees in 'top'. */
+
+ulint
+os_proc_get_number(void)
+/*====================*/
+{
+#ifdef __WIN__
+ return((ulint)GetCurrentProcessId());
+#else
+ return((ulint)getpid());
+#endif
+}
+
+/********************************************************************
Allocates non-cacheable memory. */
void*
diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c
index e212b115806..827d68501db 100644
--- a/innobase/os/os0sync.c
+++ b/innobase/os/os0sync.c
@@ -17,6 +17,7 @@ Created 9/6/1995 Heikki Tuuri
#endif
#include "ut0mem.h"
+#include "srv0start.h"
/* Type definition for an operating system mutex struct */
struct os_mutex_struct{
@@ -26,14 +27,84 @@ struct os_mutex_struct{
recursively lock the mutex: we
do not assume that the OS mutex
supports recursive locking, though
- NT seems to do that */
+ NT seems to do that */
+ UT_LIST_NODE_T(os_mutex_str_t) os_mutex_list;
+ /* list of all 'slow' OS mutexes created */
};
+/* Mutex protecting counts and the lists of OS mutexes and events */
+os_mutex_t os_sync_mutex;
+ibool os_sync_mutex_inited = FALSE;
+
+/* This is incremented by 1 in os_thread_create and decremented by 1 in
+os_thread_exit */
+ulint os_thread_count = 0;
+
+/* The list of all events created */
+UT_LIST_BASE_NODE_T(os_event_struct_t) os_event_list;
+
+/* The list of all OS 'slow' mutexes */
+UT_LIST_BASE_NODE_T(os_mutex_str_t) os_mutex_list;
+
+ulint os_event_count = 0;
+ulint os_mutex_count = 0;
+ulint os_fast_mutex_count = 0;
+
+
+/*************************************************************
+Initializes global event and OS 'slow' mutex lists. */
+
+void
+os_sync_init(void)
+/*==============*/
+{
+ UT_LIST_INIT(os_event_list);
+ UT_LIST_INIT(os_mutex_list);
+
+ os_sync_mutex = os_mutex_create(NULL);
+
+ os_sync_mutex_inited = TRUE;
+}
+
+/*************************************************************
+Frees created events and OS 'slow' mutexes. */
+
+void
+os_sync_free(void)
+/*==============*/
+{
+ os_event_t event;
+ os_mutex_t mutex;
+
+ event = UT_LIST_GET_FIRST(os_event_list);
+
+ while (event) {
+
+ os_event_free(event);
+
+ event = UT_LIST_GET_FIRST(os_event_list);
+ }
+
+ mutex = UT_LIST_GET_FIRST(os_mutex_list);
+
+ while (mutex) {
+ if (mutex == os_sync_mutex) {
+ /* Set the flag to FALSE so that we do not try to
+ reserve os_sync_mutex any more in remaining freeing
+ operations in shutdown */
+ os_sync_mutex_inited = FALSE;
+ }
+
+ os_mutex_free(mutex);
+
+ mutex = UT_LIST_GET_FIRST(os_mutex_list);
+ }
+}
+
/*************************************************************
-Creates an event semaphore, i.e., a semaphore which may
-just have two states: signaled and nonsignaled.
-The created event is manual reset: it must be reset
-explicitly by calling sync_os_reset_event. */
+Creates an event semaphore, i.e., a semaphore which may just have two
+states: signaled and nonsignaled. The created event is manual reset: it
+must be reset explicitly by calling sync_os_reset_event. */
os_event_t
os_event_create(
@@ -43,22 +114,20 @@ os_event_create(
the event is created without a name */
{
#ifdef __WIN__
- HANDLE event;
-
- event = CreateEvent(NULL, /* No security attributes */
+ os_event_t event;
+
+ event = ut_malloc(sizeof(struct os_event_struct));
+
+ event->handle = CreateEvent(NULL,/* No security attributes */
TRUE, /* Manual reset */
FALSE, /* Initial state nonsignaled */
name);
- if (!event) {
+ if (!event->handle) {
fprintf(stderr,
"InnoDB: Could not create a Windows event semaphore; Windows error %lu\n",
(ulint)GetLastError());
}
-
- ut_a(event);
-
- return(event);
-#else
+#else /* Unix */
os_event_t event;
UT_NOT_USED(name);
@@ -66,18 +135,33 @@ os_event_create(
event = ut_malloc(sizeof(struct os_event_struct));
os_fast_mutex_init(&(event->os_mutex));
- pthread_cond_init(&(event->cond_var), NULL);
+#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
+ ut_a(0 == pthread_cond_init(&(event->cond_var),
+ pthread_condattr_default));
+#else
+ ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
+#endif
event->is_set = FALSE;
+ event->signal_count = 0;
+#endif /* __WIN__ */
+
+ /* Put to the list of events */
+ os_mutex_enter(os_sync_mutex);
+
+ UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
+
+ os_event_count++;
+
+ os_mutex_exit(os_sync_mutex);
return(event);
-#endif
}
+#ifdef __WIN__
/*************************************************************
-Creates an auto-reset event semaphore, i.e., an event
-which is automatically reset when a single thread is
-released. */
+Creates an auto-reset event semaphore, i.e., an event which is automatically
+reset when a single thread is released. Works only in Windows. */
os_event_t
os_event_create_auto(
@@ -86,24 +170,33 @@ os_event_create_auto(
char* name) /* in: the name of the event, if NULL
the event is created without a name */
{
-#ifdef __WIN__
- HANDLE event;
+ os_event_t event;
+
+ event = ut_malloc(sizeof(struct os_event_struct));
- event = CreateEvent(NULL, /* No security attributes */
+ event->handle = CreateEvent(NULL,/* No security attributes */
FALSE, /* Auto-reset */
FALSE, /* Initial state nonsignaled */
name);
- ut_a(event);
- return(event);
-#else
- /* Does nothing in Posix because we do not need this with MySQL */
+ if (!event->handle) {
+ fprintf(stderr,
+"InnoDB: Could not create a Windows auto event semaphore; Windows error %lu\n",
+ (ulint)GetLastError());
+ }
- UT_NOT_USED(name);
+ /* Put to the list of events */
+ os_mutex_enter(os_sync_mutex);
- return(NULL);
-#endif
+ UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
+
+ os_event_count++;
+
+ os_mutex_exit(os_sync_mutex);
+
+ return(event);
}
+#endif
/**************************************************************
Sets an event semaphore to the signaled state: lets waiting threads
@@ -116,7 +209,7 @@ os_event_set(
{
#ifdef __WIN__
ut_a(event);
- ut_a(SetEvent(event));
+ ut_a(SetEvent(event->handle));
#else
ut_a(event);
@@ -126,7 +219,8 @@ os_event_set(
/* Do nothing */
} else {
event->is_set = TRUE;
- pthread_cond_broadcast(&(event->cond_var));
+ event->signal_count += 1;
+ ut_a(0 == pthread_cond_broadcast(&(event->cond_var)));
}
os_fast_mutex_unlock(&(event->os_mutex));
@@ -145,7 +239,7 @@ os_event_reset(
#ifdef __WIN__
ut_a(event);
- ut_a(ResetEvent(event));
+ ut_a(ResetEvent(event->handle));
#else
ut_a(event);
@@ -173,19 +267,31 @@ os_event_free(
#ifdef __WIN__
ut_a(event);
- ut_a(CloseHandle(event));
+ ut_a(CloseHandle(event->handle));
#else
ut_a(event);
os_fast_mutex_free(&(event->os_mutex));
- pthread_cond_destroy(&(event->cond_var));
+ ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
+#endif
+ /* Remove from the list of events */
+
+ os_mutex_enter(os_sync_mutex);
+
+ UT_LIST_REMOVE(os_event_list, os_event_list, event);
+
+ os_event_count--;
+
+ os_mutex_exit(os_sync_mutex);
ut_free(event);
-#endif
}
/**************************************************************
-Waits for an event object until it is in the signaled state. */
+Waits for an event object until it is in the signaled state. If
+srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
+waiting thread when the event becomes signaled (or immediately if the
+event is already in the signaled state). */
void
os_event_wait(
@@ -198,15 +304,29 @@ os_event_wait(
ut_a(event);
/* Specify an infinite time limit for waiting */
- err = WaitForSingleObject(event, INFINITE);
+ err = WaitForSingleObject(event->handle, INFINITE);
ut_a(err == WAIT_OBJECT_0);
+
+ if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ os_thread_exit(NULL);
+ }
#else
+ ib_longlong old_signal_count;
+
os_fast_mutex_lock(&(event->os_mutex));
+
+ old_signal_count = event->signal_count;
loop:
- if (event->is_set == TRUE) {
+ if (event->is_set == TRUE
+ || event->signal_count != old_signal_count) {
+
os_fast_mutex_unlock(&(event->os_mutex));
+ if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+
+ os_thread_exit(NULL);
+ }
/* Ok, we may return */
return;
@@ -214,8 +334,9 @@ loop:
pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
- /* Solaris manual said that spurious wakeups may occur: we have
- to check the 'is_set' variable again */
+ /* Solaris manual said that spurious wakeups may occur: we have to
+ check if the event really has been signaled after we came here to
+ wait */
goto loop;
#endif
@@ -223,7 +344,7 @@ loop:
/**************************************************************
Waits for an event object until it is in the signaled state or
-a timeout is exceeded. */
+a timeout is exceeded. In Unix the timeout is always infinite. */
ulint
os_event_wait_time(
@@ -240,9 +361,9 @@ os_event_wait_time(
ut_a(event);
if (time != OS_SYNC_INFINITE_TIME) {
- err = WaitForSingleObject(event, time / 1000);
+ err = WaitForSingleObject(event->handle, time / 1000);
} else {
- err = WaitForSingleObject(event, INFINITE);
+ err = WaitForSingleObject(event->handle, INFINITE);
}
if (err == WAIT_OBJECT_0) {
@@ -266,8 +387,9 @@ os_event_wait_time(
#endif
}
+#ifdef __WIN__
/**************************************************************
-Waits for any event in an event array. Returns if even a single
+Waits for any event in an OS native event array. Returns if even a single
one is signaled or becomes signaled. */
ulint
@@ -275,41 +397,35 @@ os_event_wait_multiple(
/*===================*/
/* out: index of the event
which was signaled */
- ulint n, /* in: number of events in the
+ ulint n, /* in: number of events in the
array */
- os_event_t* event_array) /* in: pointer to an array of event
+ os_native_event_t* native_event_array)
+ /* in: pointer to an array of event
handles */
{
-#ifdef __WIN__
DWORD index;
- ut_a(event_array);
+ ut_a(native_event_array);
ut_a(n > 0);
- index = WaitForMultipleObjects(n,
- event_array,
+ index = WaitForMultipleObjects(n, native_event_array,
FALSE, /* Wait for any 1 event */
INFINITE); /* Infinite wait time
limit */
ut_a(index >= WAIT_OBJECT_0);
ut_a(index < WAIT_OBJECT_0 + n);
- return(index - WAIT_OBJECT_0);
-#else
- ut_a(n == 0);
-
- /* In Posix we can only wait for a single event */
-
- os_event_wait(*event_array);
+ if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ os_thread_exit(NULL);
+ }
- return(0);
-#endif
+ return(index - WAIT_OBJECT_0);
}
+#endif
/*************************************************************
-Creates an operating system mutex semaphore.
-Because these are slow, the mutex semaphore of the database
-itself (sync_mutex_t) should be used where possible. */
+Creates an operating system mutex semaphore. Because these are slow, the
+mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
os_mutex_t
os_mutex_create(
@@ -326,30 +442,35 @@ os_mutex_create(
FALSE, /* Initial state: no owner */
name);
ut_a(mutex);
-
- mutex_str = ut_malloc(sizeof(os_mutex_str_t));
-
- mutex_str->handle = mutex;
- mutex_str->count = 0;
-
- return(mutex_str);
#else
- os_fast_mutex_t* os_mutex;
+ os_fast_mutex_t* mutex;
os_mutex_t mutex_str;
UT_NOT_USED(name);
- os_mutex = ut_malloc(sizeof(os_fast_mutex_t));
-
- os_fast_mutex_init(os_mutex);
+ mutex = ut_malloc(sizeof(os_fast_mutex_t));
+ os_fast_mutex_init(mutex);
+#endif
mutex_str = ut_malloc(sizeof(os_mutex_str_t));
- mutex_str->handle = os_mutex;
+ mutex_str->handle = mutex;
mutex_str->count = 0;
+ if (os_sync_mutex_inited) {
+ /* When creating os_sync_mutex itself we cannot reserve it */
+ os_mutex_enter(os_sync_mutex);
+ }
+
+ UT_LIST_ADD_FIRST(os_mutex_list, os_mutex_list, mutex_str);
+
+ os_mutex_count++;
+
+ if (os_sync_mutex_inited) {
+ os_mutex_exit(os_sync_mutex);
+ }
+
return(mutex_str);
-#endif
}
/**************************************************************
@@ -389,21 +510,14 @@ os_mutex_exit(
/*==========*/
os_mutex_t mutex) /* in: mutex to release */
{
-#ifdef __WIN__
ut_a(mutex);
ut_a(mutex->count == 1);
(mutex->count)--;
-
+#ifdef __WIN__
ut_a(ReleaseMutex(mutex->handle));
#else
- ut_a(mutex);
-
- ut_a(mutex->count == 1);
-
- (mutex->count)--;
-
os_fast_mutex_unlock(mutex->handle);
#endif
}
@@ -416,10 +530,23 @@ os_mutex_free(
/*==========*/
os_mutex_t mutex) /* in: mutex to free */
{
-#ifdef __WIN__
ut_a(mutex);
+ if (os_sync_mutex_inited) {
+ os_mutex_enter(os_sync_mutex);
+ }
+
+ UT_LIST_REMOVE(os_mutex_list, os_mutex_list, mutex);
+
+ os_mutex_count--;
+
+ if (os_sync_mutex_inited) {
+ os_mutex_exit(os_sync_mutex);
+ }
+
+#ifdef __WIN__
ut_a(CloseHandle(mutex->handle));
+
ut_free(mutex);
#else
os_fast_mutex_free(mutex->handle);
@@ -441,8 +568,24 @@ os_fast_mutex_init(
InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
#else
- pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
+#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
+ ut_a(0 == pthread_mutex_init(fast_mutex, pthread_mutexattr_default));
+#else
+ ut_a(0 == pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST));
+#endif
#endif
+ if (os_sync_mutex_inited) {
+ /* When creating os_sync_mutex itself (in Unix) we cannot
+ reserve it */
+
+ os_mutex_enter(os_sync_mutex);
+ }
+
+ os_fast_mutex_count++;
+
+ if (os_sync_mutex_inited) {
+ os_mutex_exit(os_sync_mutex);
+ }
}
/**************************************************************
@@ -488,6 +631,18 @@ os_fast_mutex_free(
DeleteCriticalSection((LPCRITICAL_SECTION) fast_mutex);
#else
- pthread_mutex_destroy(fast_mutex);
+ ut_a(0 == pthread_mutex_destroy(fast_mutex));
#endif
+ if (os_sync_mutex_inited) {
+ /* When freeing the last mutexes, we have
+ already freed os_sync_mutex */
+
+ os_mutex_enter(os_sync_mutex);
+ }
+
+ os_fast_mutex_count--;
+
+ if (os_sync_mutex_inited) {
+ os_mutex_exit(os_sync_mutex);
+ }
}
diff --git a/innobase/os/os0thread.c b/innobase/os/os0thread.c
index 1f40508df26..1252cc5e4b7 100644
--- a/innobase/os/os0thread.c
+++ b/innobase/os/os0thread.c
@@ -1,6 +1,5 @@
/******************************************************
-The interface to the operating system
-process and thread control primitives
+The interface to the operating system thread control primitives
(c) 1995 Innobase Oy
@@ -17,6 +16,7 @@ Created 9/8/1995 Heikki Tuuri
#endif
#include "srv0srv.h"
+#include "os0sync.h"
/*******************************************************************
Compares two thread ids for equality. */
@@ -102,6 +102,10 @@ os_thread_create(
os_thread_t thread;
ulint win_thread_id;
+ os_mutex_enter(os_sync_mutex);
+ os_thread_count++;
+ os_mutex_exit(os_sync_mutex);
+
thread = CreateThread(NULL, /* no security attributes */
0, /* default size stack */
(LPTHREAD_START_ROUTINE)start_f,
@@ -126,8 +130,10 @@ os_thread_create(
os_thread_t pthread;
pthread_attr_t attr;
+#if !(defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10))
pthread_attr_init(&attr);
-
+#endif
+
#ifdef UNIV_AIX
/* We must make sure a thread stack is at least 32 kB, otherwise
InnoDB might crash; we do not know if the default stack size on
@@ -142,16 +148,24 @@ os_thread_create(
exit(1);
}
#endif
- ret = pthread_create(&pthread, &attr, start_f, arg);
+ os_mutex_enter(os_sync_mutex);
+ os_thread_count++;
+ os_mutex_exit(os_sync_mutex);
+#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
+ ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
+#else
+ ret = pthread_create(&pthread, &attr, start_f, arg);
+#endif
if (ret) {
fprintf(stderr,
"InnoDB: Error: pthread_create returned %d\n", ret);
exit(1);
}
+#if !(defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10))
pthread_attr_destroy(&attr);
-
+#endif
if (srv_set_thread_priorities) {
my_pthread_setprio(pthread, srv_query_thread_priority);
@@ -164,6 +178,30 @@ os_thread_create(
}
/*********************************************************************
+Exits the current thread. */
+
+void
+os_thread_exit(
+/*===========*/
+ void* exit_value) /* in: exit value; in Windows this void*
+ is cast as a DWORD */
+{
+#ifdef UNIV_DEBUG_THREAD_CREATION
+ printf("Thread exits, id %lu\n",
+ os_thread_pf(os_thread_get_curr_id()));
+#endif
+ os_mutex_enter(os_sync_mutex);
+ os_thread_count--;
+ os_mutex_exit(os_sync_mutex);
+
+#ifdef __WIN__
+ ExitThread((DWORD)exit_value);
+#else
+ pthread_exit(exit_value);
+#endif
+}
+
+/*********************************************************************
Returns handle to the current thread. */
os_thread_t
@@ -207,6 +245,8 @@ os_thread_sleep(
{
#ifdef __WIN__
Sleep(tm / 1000);
+#elif defined(__NETWARE__)
+ delay(tm / 1000);
#else
struct timeval t;
@@ -253,7 +293,8 @@ ulint
os_thread_get_priority(
/*===================*/
/* out: priority */
- os_thread_t handle) /* in: OS handle to the thread */
+ os_thread_t handle __attribute__((unused)))
+ /* in: OS handle to the thread */
{
#ifdef __WIN__
int os_pri;
diff --git a/innobase/page/Makefile.am b/innobase/page/Makefile.am
index 85fe585a633..2e260787438 100644
--- a/innobase/page/Makefile.am
+++ b/innobase/page/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libpage.a
+noinst_LIBRARIES = libpage.a
libpage_a_SOURCES = page0page.c page0cur.c
diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c
index 6ce7008dce0..7e2fc19c00f 100644
--- a/innobase/page/page0cur.c
+++ b/innobase/page/page0cur.c
@@ -14,6 +14,7 @@ Created 10/4/1994 Heikki Tuuri
#include "rem0cmp.h"
#include "mtr0log.h"
#include "log0recv.h"
+#include "rem0cmp.h"
ulint page_cur_short_succ = 0;
@@ -121,6 +122,53 @@ page_cur_try_search_shortcut(
#endif
/********************************************************************
+Checks if the nth field in a record is a character type field which extends
+the nth field in tuple, i.e., the field is longer or equal in length and has
+common first characters. */
+static
+ibool
+page_cur_rec_field_extends(
+/*=======================*/
+ /* out: TRUE if rec field extends tuple
+ field */
+ dtuple_t* tuple, /* in: data tuple */
+ rec_t* rec, /* in: record */
+ ulint n) /* in: compare nth field */
+{
+ dtype_t* type;
+ dfield_t* dfield;
+ byte* rec_f;
+ ulint rec_f_len;
+
+ dfield = dtuple_get_nth_field(tuple, n);
+
+ type = dfield_get_type(dfield);
+
+ rec_f = rec_get_nth_field(rec, n, &rec_f_len);
+
+ if (type->mtype == DATA_VARCHAR
+ || type->mtype == DATA_CHAR
+ || type->mtype == DATA_FIXBINARY
+ || type->mtype == DATA_BINARY
+ || type->mtype == DATA_BLOB
+ || type->mtype == DATA_VARMYSQL
+ || type->mtype == DATA_MYSQL) {
+
+ if (dfield_get_len(dfield) != UNIV_SQL_NULL
+ && rec_f_len != UNIV_SQL_NULL
+ && rec_f_len >= dfield_get_len(dfield)
+ && 0 == cmp_data_data_slow(type, dfield_get_data(dfield),
+ dfield_get_len(dfield),
+ rec_f, dfield_get_len(dfield))) {
+
+ return(TRUE);
+ }
+ }
+
+ return(FALSE);
+}
+
+/********************************************************************
Searches the right position for a page cursor. */
void
@@ -169,8 +217,10 @@ page_cur_search_with_match(
ut_ad(dtuple_check_typed(tuple));
ut_ad((mode == PAGE_CUR_L) || (mode == PAGE_CUR_LE)
|| (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)
- || (mode == PAGE_CUR_DBG));
+ || (mode == PAGE_CUR_LE_OR_EXTENDS) || (mode == PAGE_CUR_DBG));
+ page_check_dir(page);
+
#ifdef PAGE_CUR_ADAPT
if ((page_header_get_field(page, PAGE_LEVEL) == 0)
&& (mode == PAGE_CUR_LE)
@@ -193,6 +243,11 @@ page_cur_search_with_match(
}
/*#endif */
#endif
+
+ /* The following flag does not work for non-latin1 char sets because
+ cmp_full_field does not tell how many bytes matched */
+ ut_a(mode != PAGE_CUR_LE_OR_EXTENDS);
+
/* If mode PAGE_CUR_G is specified, we are trying to position the
cursor to answer a query of the form "tuple < X", where tuple is
the input parameter, and X denotes an arbitrary physical record on
@@ -232,11 +287,21 @@ page_cur_search_with_match(
low_matched_bytes = cur_matched_bytes;
} else if (cmp == -1) {
- up = mid;
- up_matched_fields = cur_matched_fields;
- up_matched_bytes = cur_matched_bytes;
- } else if ((mode == PAGE_CUR_G) || (mode == PAGE_CUR_LE)) {
+ if (mode == PAGE_CUR_LE_OR_EXTENDS
+ && page_cur_rec_field_extends(tuple, mid_rec,
+ cur_matched_fields)) {
+ low = mid;
+ low_matched_fields = cur_matched_fields;
+ low_matched_bytes = cur_matched_bytes;
+ } else {
+ up = mid;
+ up_matched_fields = cur_matched_fields;
+ up_matched_bytes = cur_matched_bytes;
+ }
+
+ } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE
+ || mode == PAGE_CUR_LE_OR_EXTENDS) {
low = mid;
low_matched_fields = cur_matched_fields;
low_matched_bytes = cur_matched_bytes;
@@ -252,8 +317,8 @@ page_cur_search_with_match(
slot = page_dir_get_nth_slot(page, up);
up_rec = page_dir_slot_get_rec(slot);
- /* Perform linear search until the upper and lower records
- come to distance 1 of each other. */
+ /* Perform linear search until the upper and lower records come to
+ distance 1 of each other. */
while (page_rec_get_next(low_rec) != up_rec) {
@@ -272,11 +337,19 @@ page_cur_search_with_match(
low_matched_bytes = cur_matched_bytes;
} else if (cmp == -1) {
- up_rec = mid_rec;
- up_matched_fields = cur_matched_fields;
- up_matched_bytes = cur_matched_bytes;
-
- } else if ((mode == PAGE_CUR_G) || (mode == PAGE_CUR_LE)) {
+ if (mode == PAGE_CUR_LE_OR_EXTENDS
+ && page_cur_rec_field_extends(tuple, mid_rec,
+ cur_matched_fields)) {
+ low_rec = mid_rec;
+ low_matched_fields = cur_matched_fields;
+ low_matched_bytes = cur_matched_bytes;
+ } else {
+ up_rec = mid_rec;
+ up_matched_fields = cur_matched_fields;
+ up_matched_bytes = cur_matched_bytes;
+ }
+ } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE
+ || mode == PAGE_CUR_LE_OR_EXTENDS) {
low_rec = mid_rec;
low_matched_fields = cur_matched_fields;
low_matched_bytes = cur_matched_bytes;
@@ -518,14 +591,15 @@ page_cur_parse_insert_rec(
mtr_t* mtr) /* in: mtr or NULL */
{
ulint extra_info_yes;
- ulint offset;
+ ulint offset = 0; /* remove warning */
ulint origin_offset;
ulint end_seg_len;
ulint mismatch_index;
rec_t* cursor_rec;
byte buf1[1024];
byte* buf;
- ulint info_bits;
+ byte* ptr2 = ptr;
+ ulint info_bits = 0; /* remove warning */
page_cur_t cursor;
if (!is_short) {
@@ -627,7 +701,20 @@ page_cur_parse_insert_rec(
/* Build the inserted record to buf */
- ut_a(mismatch_index < UNIV_PAGE_SIZE);
+ if (mismatch_index >= UNIV_PAGE_SIZE) {
+ printf("Is short %lu, info_bits %lu, offset %lu, o_offset %lu\n"
+ "mismatch index %lu, end_seg_len %lu\n"
+ "parsed len %lu\n",
+ is_short, info_bits, offset, origin_offset,
+ mismatch_index, end_seg_len, (ulint)(ptr - ptr2));
+
+ printf("Dump of 300 bytes of log:\n");
+ ut_print_buf(ptr2, 300);
+
+ buf_page_print(page);
+
+ ut_a(0);
+ }
ut_memcpy(buf, rec_get_start(cursor_rec), mismatch_index);
ut_memcpy(buf + mismatch_index, ptr, end_seg_len);
@@ -862,9 +949,9 @@ page_copy_rec_list_end_to_created_page(
rec_t* rec, /* in: first record to copy */
mtr_t* mtr) /* in: mtr */
{
- page_dir_slot_t* slot;
+ page_dir_slot_t* slot = 0; /* remove warning */
byte* heap_top;
- rec_t* insert_rec;
+ rec_t* insert_rec = 0; /* remove warning */
rec_t* prev_rec;
ulint count;
ulint n_recs;
@@ -909,6 +996,7 @@ page_copy_rec_list_end_to_created_page(
slot_index = 0;
n_recs = 0;
+ /* should be do ... until, comment by Jani */
while (rec != page_get_supremum_rec(page)) {
insert_rec = rec_copy(heap_top, rec);
diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c
index af1ccb92016..e087941a970 100644
--- a/innobase/page/page0page.c
+++ b/innobase/page/page0page.c
@@ -270,7 +270,7 @@ page_parse_create(
/*==============*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -343,7 +343,7 @@ page_create(
tuple = dtuple_create(heap, 1);
field = dtuple_get_nth_field(tuple, 0);
- dfield_set_data(field, "infimum", strlen("infimum") + 1);
+ dfield_set_data(field,(char *) "infimum", strlen("infimum") + 1);
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 20, 0);
/* Set the corresponding physical record to its place in the page
@@ -353,7 +353,7 @@ page_create(
infimum_rec = rec_convert_dtuple_to_rec(heap_top, tuple);
- ut_ad(infimum_rec == page + PAGE_INFIMUM);
+ ut_a(infimum_rec == page + PAGE_INFIMUM);
rec_set_n_owned(infimum_rec, 1);
rec_set_heap_no(infimum_rec, 0);
@@ -365,12 +365,12 @@ page_create(
tuple = dtuple_create(heap, 1);
field = dtuple_get_nth_field(tuple, 0);
- dfield_set_data(field, "supremum", strlen("supremum") + 1);
+ dfield_set_data(field, (char *) "supremum", strlen("supremum") + 1);
dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 20, 0);
supremum_rec = rec_convert_dtuple_to_rec(heap_top, tuple);
- ut_ad(supremum_rec == page + PAGE_SUPREMUM);
+ ut_a(supremum_rec == page + PAGE_SUPREMUM);
rec_set_n_owned(supremum_rec, 1);
rec_set_heap_no(supremum_rec, 1);
@@ -389,6 +389,8 @@ page_create(
page_header_set_ptr(page, PAGE_FREE, NULL);
page_header_set_field(page, PAGE_GARBAGE, 0);
page_header_set_ptr(page, PAGE_LAST_INSERT, NULL);
+ page_header_set_field(page, PAGE_DIRECTION, PAGE_NO_DIRECTION);
+ page_header_set_field(page, PAGE_N_DIRECTION, 0);
page_header_set_field(page, PAGE_N_RECS, 0);
page_set_max_trx_id(page, ut_dulint_zero);
@@ -402,11 +404,22 @@ page_create(
slot = page_dir_get_nth_slot(page, 1);
page_dir_slot_set_rec(slot, supremum_rec);
- /* Set next pointers in infimum and supremum */
+ /* Set the next pointers in infimum and supremum */
rec_set_next_offs(infimum_rec, (ulint)(supremum_rec - page));
rec_set_next_offs(supremum_rec, 0);
-
+
+#ifdef notdefined
+ /* Disable the use of page_template: there is a race condition here:
+ while one thread is creating page_template, another one can start
+ using it before the memcpy completes! */
+
+ if (page_template == NULL) {
+ page_template = mem_alloc(UNIV_PAGE_SIZE);
+
+ ut_memcpy(page_template, page, UNIV_PAGE_SIZE);
+ }
+#endif
return(page);
}
@@ -433,6 +446,8 @@ page_copy_rec_list_end_no_locks(
page_cur_move_to_next(&cur1);
}
+ ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == PAGE_INFIMUM);
+
page_cur_set_before_first(new_page, &cur2);
/* Copy records from the original page to the new page */
@@ -440,8 +455,22 @@ page_copy_rec_list_end_no_locks(
sup = page_get_supremum_rec(page);
while (sup != page_cur_get_rec(&cur1)) {
- ut_a(
- page_cur_rec_insert(&cur2, page_cur_get_rec(&cur1), mtr));
+ if (!page_cur_rec_insert(&cur2,
+ page_cur_get_rec(&cur1), mtr)) {
+ /* Track an assertion failure reported on the mailing
+ list on June 18th, 2003 */
+
+ buf_page_print(new_page);
+ buf_page_print(page);
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+"InnoDB: rec offset %lu, cur1 offset %lu, cur2 offset %lu\n",
+ (ulint)(rec - page),
+ (ulint)(page_cur_get_rec(&cur1) - page),
+ (ulint)(page_cur_get_rec(&cur2) - new_page));
+ ut_a(0);
+ }
page_cur_move_to_next(&cur1);
page_cur_move_to_next(&cur2);
@@ -1293,20 +1322,243 @@ page_rec_validate(
heap_no = rec_get_heap_no(rec);
if (!(n_owned <= PAGE_DIR_SLOT_MAX_N_OWNED)) {
- fprintf(stderr, "Dir slot n owned too big %lu\n", n_owned);
+ fprintf(stderr,
+ "InnoDB: Dir slot of rec %lu, n owned too big %lu\n",
+ (ulint)(rec - page), n_owned);
return(FALSE);
}
if (!(heap_no < page_header_get_field(page, PAGE_N_HEAP))) {
- fprintf(stderr, "Heap no too big %lu %lu\n", heap_no,
+ fprintf(stderr,
+ "InnoDB: Heap no of rec %lu too big %lu %lu\n",
+ (ulint)(rec - page), heap_no,
page_header_get_field(page, PAGE_N_HEAP));
return(FALSE);
}
return(TRUE);
}
+
+/*******************************************************************
+Checks that the first directory slot points to the infimum record and
+the last to the supremum. This function is intended to track if the
+bug fixed in 4.0.14 has caused corruption to users' databases. */
+
+void
+page_check_dir(
+/*===========*/
+ page_t* page) /* in: index page */
+{
+ ulint n_slots;
+
+ n_slots = page_dir_get_n_slots(page);
+
+ if (page_dir_slot_get_rec(page_dir_get_nth_slot(page, 0))
+ != page_get_infimum_rec(page)) {
+
+ fprintf(stderr,
+"InnoDB: Page directory corruption: supremum not pointed to\n");
+ buf_page_print(page);
+ }
+
+ if (page_dir_slot_get_rec(page_dir_get_nth_slot(page, n_slots - 1))
+ != page_get_supremum_rec(page)) {
+
+ fprintf(stderr,
+"InnoDB: Page directory corruption: supremum not pointed to\n");
+ buf_page_print(page);
+ }
+}
/*******************************************************************
+This function checks the consistency of an index page when we do not
+know the index. This is also resilient so that this should never crash
+even if the page is total garbage. */
+
+ibool
+page_simple_validate(
+/*=================*/
+ /* out: TRUE if ok */
+ page_t* page) /* in: index page */
+{
+ page_cur_t cur;
+ page_dir_slot_t* slot;
+ ulint slot_no;
+ ulint n_slots;
+ rec_t* rec;
+ byte* rec_heap_top;
+ ulint count;
+ ulint own_count;
+ ibool ret = FALSE;
+
+ /* Check first that the record heap and the directory do not
+ overlap. */
+
+ n_slots = page_dir_get_n_slots(page);
+
+ if (n_slots > UNIV_PAGE_SIZE / 4) {
+ fprintf(stderr,
+ "InnoDB: Nonsensical number %lu of page dir slots\n", n_slots);
+
+ goto func_exit;
+ }
+
+ rec_heap_top = page_header_get_ptr(page, PAGE_HEAP_TOP);
+
+ if (rec_heap_top > page_dir_get_nth_slot(page, n_slots - 1)) {
+
+ fprintf(stderr,
+ "InnoDB: Record heap and dir overlap on a page, heap top %lu, dir %lu\n",
+ (ulint)(page_header_get_ptr(page, PAGE_HEAP_TOP) - page),
+ (ulint)(page_dir_get_nth_slot(page, n_slots - 1) - page));
+
+ goto func_exit;
+ }
+
+ /* Validate the record list in a loop checking also that it is
+ consistent with the page record directory. */
+
+ count = 0;
+ own_count = 1;
+ slot_no = 0;
+ slot = page_dir_get_nth_slot(page, slot_no);
+
+ page_cur_set_before_first(page, &cur);
+
+ for (;;) {
+ rec = (&cur)->rec;
+
+ if (rec > rec_heap_top) {
+ fprintf(stderr,
+ "InnoDB: Record %lu is above rec heap top %lu\n",
+ (ulint)(rec - page), (ulint)(rec_heap_top - page));
+
+ goto func_exit;
+ }
+
+ if (rec_get_n_owned(rec) != 0) {
+ /* This is a record pointed to by a dir slot */
+ if (rec_get_n_owned(rec) != own_count) {
+
+ fprintf(stderr,
+ "InnoDB: Wrong owned count %lu, %lu, rec %lu\n",
+ rec_get_n_owned(rec), own_count,
+ (ulint)(rec - page));
+
+ goto func_exit;
+ }
+
+ if (page_dir_slot_get_rec(slot) != rec) {
+ fprintf(stderr,
+ "InnoDB: Dir slot does not point to right rec %lu\n",
+ (ulint)(rec - page));
+
+ goto func_exit;
+ }
+
+ own_count = 0;
+
+ if (!page_cur_is_after_last(&cur)) {
+ slot_no++;
+ slot = page_dir_get_nth_slot(page, slot_no);
+ }
+ }
+
+ if (page_cur_is_after_last(&cur)) {
+
+ break;
+ }
+
+ if (rec_get_next_offs(rec) < FIL_PAGE_DATA
+ || rec_get_next_offs(rec) >= UNIV_PAGE_SIZE) {
+ fprintf(stderr,
+ "InnoDB: Next record offset nonsensical %lu for rec %lu\n",
+ rec_get_next_offs(rec),
+ (ulint)(rec - page));
+
+ goto func_exit;
+ }
+
+ count++;
+
+ if (count > UNIV_PAGE_SIZE) {
+ fprintf(stderr,
+ "InnoDB: Page record list appears to be circular %lu\n",
+ count);
+ goto func_exit;
+ }
+
+ page_cur_move_to_next(&cur);
+ own_count++;
+ }
+
+ if (rec_get_n_owned(rec) == 0) {
+ fprintf(stderr, "InnoDB: n owned is zero in a supremum rec\n");
+
+ goto func_exit;
+ }
+
+ if (slot_no != n_slots - 1) {
+ fprintf(stderr, "InnoDB: n slots wrong %lu, %lu\n",
+ slot_no, n_slots - 1);
+ goto func_exit;
+ }
+
+ if (page_header_get_field(page, PAGE_N_RECS) + 2 != count + 1) {
+ fprintf(stderr, "InnoDB: n recs wrong %lu %lu\n",
+ page_header_get_field(page, PAGE_N_RECS) + 2, count + 1);
+
+ goto func_exit;
+ }
+
+ /* Check then the free list */
+ rec = page_header_get_ptr(page, PAGE_FREE);
+
+ while (rec != NULL) {
+ if (rec < page + FIL_PAGE_DATA
+ || rec >= page + UNIV_PAGE_SIZE) {
+ fprintf(stderr,
+ "InnoDB: Free list record has a nonsensical offset %lu\n",
+ (ulint)(rec - page));
+
+ goto func_exit;
+ }
+
+ if (rec > rec_heap_top) {
+ fprintf(stderr,
+ "InnoDB: Free list record %lu is above rec heap top %lu\n",
+ (ulint)(rec - page), (ulint)(rec_heap_top - page));
+
+ goto func_exit;
+ }
+
+ count++;
+
+ if (count > UNIV_PAGE_SIZE) {
+ fprintf(stderr,
+ "InnoDB: Page free list appears to be circular %lu\n",
+ count);
+ goto func_exit;
+ }
+
+ rec = page_rec_get_next(rec);
+ }
+
+ if (page_header_get_field(page, PAGE_N_HEAP) != count + 1) {
+
+ fprintf(stderr, "InnoDB: N heap is wrong %lu, %lu\n",
+ page_header_get_field(page, PAGE_N_HEAP), count + 1);
+
+ goto func_exit;
+ }
+
+ ret = TRUE;
+
+func_exit:
+ return(ret);
+}
+
+/*******************************************************************
This function checks the consistency of an index page. */
ibool
@@ -1333,6 +1585,17 @@ page_validate(
ulint i;
char err_buf[1000];
+ if (!page_simple_validate(page)) {
+ fprintf(stderr,
+"InnoDB: Apparent corruption in page %lu in index %s in table %s\n",
+ buf_frame_get_page_no(page), index->name,
+ index->table_name);
+
+ buf_page_print(page);
+
+ return(FALSE);
+ }
+
heap = mem_heap_create(UNIV_PAGE_SIZE);
/* The following buffer is used to check that the
@@ -1351,7 +1614,7 @@ page_validate(
if (!(page_header_get_ptr(page, PAGE_HEAP_TOP) <=
page_dir_get_nth_slot(page, n_slots - 1))) {
fprintf(stderr,
- "Record heap and dir overlap on a page in index %s, %lu, %lu\n",
+"InnoDB: Record heap and dir overlap on a page in index %s, %lu, %lu\n",
index->name, (ulint)page_header_get_ptr(page, PAGE_HEAP_TOP),
(ulint)page_dir_get_nth_slot(page, n_slots - 1));
@@ -1379,13 +1642,18 @@ page_validate(
if ((count >= 2) && (!page_cur_is_after_last(&cur))) {
if (!(1 == cmp_rec_rec(rec, old_rec, index))) {
fprintf(stderr,
- "Records in wrong order in index %s\n",
- index->name);
+"InnoDB: Records in wrong order on page %lu index %s table %s\n",
+ buf_frame_get_page_no(page),
+ index->name,
+ index->table_name);
+
rec_sprintf(err_buf, 900, old_rec);
- fprintf(stderr, "InnoDB: record %s\n", err_buf);
+ fprintf(stderr,
+ "InnoDB: previous record %s\n", err_buf);
rec_sprintf(err_buf, 900, rec);
- fprintf(stderr, "InnoDB: record %s\n", err_buf);
+ fprintf(stderr,
+ "InnoDB: record %s\n", err_buf);
goto func_exit;
}
@@ -1404,7 +1672,7 @@ page_validate(
/* No other record may overlap this */
fprintf(stderr,
- "Record overlaps another in index %s \n",
+ "InnoDB: Record overlaps another in index %s \n",
index->name);
goto func_exit;
@@ -1417,7 +1685,7 @@ page_validate(
/* This is a record pointed to by a dir slot */
if (rec_get_n_owned(rec) != own_count) {
fprintf(stderr,
- "Wrong owned count %lu, %lu, in index %s\n",
+ "InnoDB: Wrong owned count %lu, %lu, in index %s\n",
rec_get_n_owned(rec), own_count,
index->name);
@@ -1426,7 +1694,7 @@ page_validate(
if (page_dir_slot_get_rec(slot) != rec) {
fprintf(stderr,
- "Dir slot does not point to right rec in %s\n",
+ "InnoDB: Dir slot does not point to right rec in %s\n",
index->name);
goto func_exit;
@@ -1448,7 +1716,7 @@ page_validate(
if (rec_get_next_offs(rec) < FIL_PAGE_DATA
|| rec_get_next_offs(rec) >= UNIV_PAGE_SIZE) {
fprintf(stderr,
- "Next record offset wrong %lu in index %s\n",
+ "InnoDB: Next record offset wrong %lu in index %s\n",
rec_get_next_offs(rec), index->name);
goto func_exit;
@@ -1461,19 +1729,20 @@ page_validate(
}
if (rec_get_n_owned(rec) == 0) {
- fprintf(stderr, "n owned is zero in index %s\n", index->name);
+ fprintf(stderr,
+ "InnoDB: n owned is zero in index %s\n", index->name);
goto func_exit;
}
if (slot_no != n_slots - 1) {
- fprintf(stderr, "n slots wrong %lu %lu in index %s\n",
+ fprintf(stderr, "InnoDB: n slots wrong %lu %lu in index %s\n",
slot_no, n_slots - 1, index->name);
goto func_exit;
}
if (page_header_get_field(page, PAGE_N_RECS) + 2 != count + 1) {
- fprintf(stderr, "n recs wrong %lu %lu in index %s\n",
+ fprintf(stderr, "InnoDB: n recs wrong %lu %lu in index %s\n",
page_header_get_field(page, PAGE_N_RECS) + 2, count + 1,
index->name);
@@ -1481,7 +1750,8 @@ page_validate(
}
if (data_size != page_get_data_size(page)) {
- fprintf(stderr, "Summed data size %lu, returned by func %lu\n",
+ fprintf(stderr,
+ "InnoDB: Summed data size %lu, returned by func %lu\n",
data_size, page_get_data_size(page));
goto func_exit;
}
@@ -1502,7 +1772,7 @@ page_validate(
if (buf[offs + i] != 0) {
fprintf(stderr,
- "Record overlaps another in free list, index %s \n",
+ "InnoDB: Record overlaps another in free list, index %s \n",
index->name);
goto func_exit;
@@ -1516,9 +1786,11 @@ page_validate(
if (page_header_get_field(page, PAGE_N_HEAP) != count + 1) {
- fprintf(stderr, "N heap is wrong %lu %lu in index %s\n",
- page_header_get_field(page, PAGE_N_HEAP), count + 1,
- index->name);
+ fprintf(stderr,
+ "InnoDB: N heap is wrong %lu %lu in index %s\n",
+ page_header_get_field(page, PAGE_N_HEAP), count + 1,
+ index->name);
+ goto func_exit;
}
ret = TRUE;
@@ -1526,6 +1798,15 @@ page_validate(
func_exit:
mem_heap_free(heap);
+ if (ret == FALSE) {
+ fprintf(stderr,
+"InnoDB: Apparent corruption in page %lu in index %s in table %s\n",
+ buf_frame_get_page_no(page), index->name,
+ index->table_name);
+
+ buf_page_print(page);
+ }
+
return(ret);
}
diff --git a/innobase/pars/Makefile.am b/innobase/pars/Makefile.am
index e5611f9dfc6..2356f330486 100644
--- a/innobase/pars/Makefile.am
+++ b/innobase/pars/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libpars.a
+noinst_LIBRARIES = libpars.a
noinst_HEADERS = pars0grm.h
diff --git a/innobase/pars/lexyy.c b/innobase/pars/lexyy.c
index 81adf909d01..71507ccd868 100644
--- a/innobase/pars/lexyy.c
+++ b/innobase/pars/lexyy.c
@@ -4,12 +4,11 @@
* $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
*/
-#include "univ.i"
-
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
+#include "univ.i"
#include <stdio.h>
@@ -608,11 +607,8 @@ How to make the InnoDB parser and lexer C files:
6. Remove the #include of unistd.h from about line 2500 of lexyy.c
-7. Move #include <math.h> in pars0grm.c after #include "univ.i" to remove
- a large file compilation error on AIX.
-
-8. Move #include "univ.i" in lexyy.c to the file start to remove a large
- file compilation error on AIX.
+7. Add '#include "univ.i"' before #include <stdio.h> in lexyy.c
+ (Needed for AIX)
These instructions seem to work at least with bison-1.28 and flex-2.5.4 on
Linux.
@@ -620,6 +616,7 @@ Linux.
#line 36 "pars0lex.l"
#define YYSTYPE que_node_t*
+#include "univ.i"
#include "pars0pars.h"
#include "pars0grm.h"
#include "pars0sym.h"
diff --git a/innobase/pars/pars0grm.c b/innobase/pars/pars0grm.c
index 206534a5352..05b75398084 100644
--- a/innobase/pars/pars0grm.c
+++ b/innobase/pars/pars0grm.c
@@ -95,14 +95,13 @@
que_node_t */
#include "univ.i"
+#include <math.h> /* Can't be before univ.i */
#include "pars0pars.h"
#include "mem0mem.h"
#include "que0types.h"
#include "que0que.h"
#include "row0sel.h"
-#include <math.h>
-
#define YYSTYPE que_node_t*
/* #define __STDC__ */
diff --git a/innobase/pars/pars0grm.y b/innobase/pars/pars0grm.y
index eedc42bee57..a142d04301e 100644
--- a/innobase/pars/pars0grm.y
+++ b/innobase/pars/pars0grm.y
@@ -15,7 +15,7 @@ the InnoDB parser.
que_node_t */
#include "univ.i"
-#include <math.h>
+#include <math.h> /* Can't be before univ.i */
#include "pars0pars.h"
#include "mem0mem.h"
#include "que0types.h"
diff --git a/innobase/pars/pars0lex.l b/innobase/pars/pars0lex.l
index e9b39861dd2..97875ffcc45 100644
--- a/innobase/pars/pars0lex.l
+++ b/innobase/pars/pars0lex.l
@@ -28,6 +28,9 @@ How to make the InnoDB parser and lexer C files:
6. Remove the #include of unistd.h from about line 2500 of lexyy.c
+7. Add '#include "univ.i"' before #include <stdio.h> in lexyy.c
+ (Needed for AIX)
+
These instructions seem to work at least with bison-1.28 and flex-2.5.4 on
Linux.
*******************************************************/
diff --git a/innobase/pars/pars0opt.c b/innobase/pars/pars0opt.c
index 9814c4b21cc..4faf83b47a3 100644
--- a/innobase/pars/pars0opt.c
+++ b/innobase/pars/pars0opt.c
@@ -373,7 +373,8 @@ opt_calc_index_goodness(
}
}
- if (index->type & DICT_CLUSTERED) {
+ /* We have to test for goodness here, as last_op may note be set */
+ if (goodness && index->type & DICT_CLUSTERED) {
goodness++;
}
@@ -529,7 +530,7 @@ opt_search_plan_for_table(
ulint last_op = 75946965; /* Eliminate a Purify
warning */
ulint best_goodness;
- ulint best_last_op;
+ ulint best_last_op = 0; /* remove warning */
ulint mix_id_pos;
que_node_t* index_plan[128];
que_node_t* best_index_plan[128];
@@ -547,6 +548,7 @@ opt_search_plan_for_table(
best_index = index; /* Eliminate compiler warning */
best_goodness = 0;
+ /* should be do ... until ? comment by Jani */
while (index) {
goodness = opt_calc_index_goodness(index, sel_node, i,
index_plan, &last_op);
@@ -1056,7 +1058,6 @@ opt_clust_access(
dfield_t* dfield;
mem_heap_t* heap;
ulint n_fields;
- ulint col_no;
ulint pos;
ulint i;
@@ -1091,8 +1092,7 @@ opt_clust_access(
plan->clust_map = mem_heap_alloc(heap, n_fields * sizeof(ulint));
for (i = 0; i < n_fields; i++) {
- col_no = dict_index_get_nth_col_no(clust_index, i);
- pos = dict_index_get_nth_col_pos(index, col_no);
+ pos = dict_index_get_nth_field_pos(index, clust_index, i);
*(plan->clust_map + i) = pos;
@@ -1107,7 +1107,8 @@ opt_clust_access(
dfield = dtuple_get_nth_field(plan->clust_ref, table->mix_len);
- dfield_set_data(dfield, mem_heap_alloc(heap, table->mix_id_len),
+ dfield_set_data(dfield, mem_heap_alloc(heap,
+ table->mix_id_len),
table->mix_id_len);
ut_memcpy(dfield_get_data(dfield), table->mix_id_buf,
table->mix_id_len);
diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c
index 8ffbca579b8..3e43b6ae262 100644
--- a/innobase/pars/pars0pars.c
+++ b/innobase/pars/pars0pars.c
@@ -244,13 +244,11 @@ pars_resolve_func_data_type(
/* Inherit the data type from the first argument (which must
not be the SQL null literal whose type is DATA_ERROR) */
- ut_a(dtype_get_mtype(que_node_get_data_type(arg))
- != DATA_ERROR);
dtype_copy(que_node_get_data_type(node),
que_node_get_data_type(arg));
- ut_a(dtype_get_mtype(que_node_get_data_type(node)) == DATA_INT);
-
+ ut_a(dtype_get_mtype(que_node_get_data_type(node))
+ == DATA_INT);
} else if (func == PARS_COUNT_TOKEN) {
ut_a(arg);
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0);
@@ -1596,7 +1594,7 @@ pars_create_index(
column = column_list;
while (column) {
- dict_mem_index_add_field(index, column->name, 0);
+ dict_mem_index_add_field(index, column->name, 0, 0);
column->resolved = TRUE;
column->token_type = SYM_COLUMN;
@@ -1942,7 +1940,7 @@ Called by yyparse on error. */
void
yyerror(
/*====*/
- char* s) /* in: error message string */
+ char* s __attribute__((unused))) /* in: error message string */
{
ut_ad(s);
diff --git a/innobase/que/Makefile.am b/innobase/que/Makefile.am
index b74d4dbf6a0..d9c046b4f4c 100644
--- a/innobase/que/Makefile.am
+++ b/innobase/que/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libque.a
+noinst_LIBRARIES = libque.a
libque_a_SOURCES = que0que.c
diff --git a/innobase/que/que0que.c b/innobase/que/que0que.c
index 41a90a7fb42..a96c8840a03 100644
--- a/innobase/que/que0que.c
+++ b/innobase/que/que0que.c
@@ -103,7 +103,7 @@ que_thr_add_update_info(
mach_write_to_8(thr->msg_buf + SESS_SRV_MSG_N_DELETES,
graph->n_deletes);
}
-#endif
+#endif
/***************************************************************************
Adds a query graph to the session's list of graphs. */
@@ -395,7 +395,7 @@ graph so that the graph can communicate an error message to the client.) */
void
que_fork_error_handle(
/*==================*/
- trx_t* trx, /* in: trx */
+ trx_t* trx __attribute__((unused)), /* in: trx */
que_t* fork) /* in: query graph which was run before signal
handling started, NULL not allowed */
{
@@ -1046,14 +1046,16 @@ que_thr_stop(
}
/**************************************************************************
-A patch for MySQL used to 'stop' a dummy query thread used in MySQL. */
+A patch for MySQL used to 'stop' a dummy query thread used in MySQL. The
+query thread is stopped and made inactive, except in the case where
+it was put to the lock wait state in lock0lock.c, but the lock has already
+been granted or the transaction chosen as a victim in deadlock resolution. */
void
que_thr_stop_for_mysql(
/*===================*/
que_thr_t* thr) /* in: query thread */
{
- ibool stopped = FALSE;
trx_t* trx;
trx = thr_get_trx(thr);
@@ -1067,13 +1069,10 @@ que_thr_stop_for_mysql(
/* Error handling built for the MySQL interface */
thr->state = QUE_THR_COMPLETED;
-
- stopped = TRUE;
- }
-
- if (!stopped) {
- /* It must have been a lock wait but the
- lock was already released */
+ } else {
+ /* It must have been a lock wait but the lock was
+ already released, or this transaction was chosen
+ as a victim in selective deadlock resolution */
mutex_exit(&kernel_mutex);
@@ -1081,6 +1080,10 @@ que_thr_stop_for_mysql(
}
}
+ ut_ad(thr->is_active == TRUE);
+ ut_ad(trx->n_active_thrs == 1);
+ ut_ad(thr->graph->n_active_thrs == 1);
+
thr->is_active = FALSE;
(thr->graph)->n_active_thrs--;
@@ -1132,6 +1135,9 @@ que_thr_stop_for_mysql_no_error(
trx_t* trx) /* in: transaction */
{
ut_ad(thr->state == QUE_THR_RUNNING);
+ ut_ad(thr->is_active == TRUE);
+ ut_ad(trx->n_active_thrs == 1);
+ ut_ad(thr->graph->n_active_thrs == 1);
if (thr->magic_n != QUE_THR_MAGIC_N) {
fprintf(stderr,
@@ -1167,47 +1173,47 @@ que_node_print_info(
addr = (ulint)node;
if (type == QUE_NODE_SELECT) {
- str = "SELECT";
+ str = (char *) "SELECT";
} else if (type == QUE_NODE_INSERT) {
- str = "INSERT";
+ str = (char *) "INSERT";
} else if (type == QUE_NODE_UPDATE) {
- str = "UPDATE";
+ str = (char *) "UPDATE";
} else if (type == QUE_NODE_WHILE) {
- str = "WHILE";
+ str = (char *) "WHILE";
} else if (type == QUE_NODE_ASSIGNMENT) {
- str = "ASSIGNMENT";
+ str = (char *) "ASSIGNMENT";
} else if (type == QUE_NODE_IF) {
- str = "IF";
+ str = (char *) "IF";
} else if (type == QUE_NODE_FETCH) {
- str = "FETCH";
+ str = (char *) "FETCH";
} else if (type == QUE_NODE_OPEN) {
- str = "OPEN";
+ str = (char *) "OPEN";
} else if (type == QUE_NODE_PROC) {
- str = "STORED PROCEDURE";
+ str = (char *) "STORED PROCEDURE";
} else if (type == QUE_NODE_FUNC) {
- str = "FUNCTION";
+ str = (char *) "FUNCTION";
} else if (type == QUE_NODE_LOCK) {
- str = "LOCK";
+ str = (char *) "LOCK";
} else if (type == QUE_NODE_THR) {
- str = "QUERY THREAD";
+ str = (char *) "QUERY THREAD";
} else if (type == QUE_NODE_COMMIT) {
- str = "COMMIT";
+ str = (char *) "COMMIT";
} else if (type == QUE_NODE_UNDO) {
- str = "UNDO ROW";
+ str = (char *) "UNDO ROW";
} else if (type == QUE_NODE_PURGE) {
- str = "PURGE ROW";
+ str = (char *) "PURGE ROW";
} else if (type == QUE_NODE_ROLLBACK) {
- str = "ROLLBACK";
+ str = (char *) "ROLLBACK";
} else if (type == QUE_NODE_CREATE_TABLE) {
- str = "CREATE TABLE";
+ str = (char *) "CREATE TABLE";
} else if (type == QUE_NODE_CREATE_INDEX) {
- str = "CREATE INDEX";
+ str = (char *) "CREATE INDEX";
} else if (type == QUE_NODE_FOR) {
- str = "FOR LOOP";
+ str = (char *) "FOR LOOP";
} else if (type == QUE_NODE_RETURN) {
- str = "RETURN";
+ str = (char *) "RETURN";
} else {
- str = "UNKNOWN NODE TYPE";
+ str = (char *) "UNKNOWN NODE TYPE";
}
printf("Node type %lu: %s, address %lx\n", type, str, addr);
diff --git a/innobase/read/Makefile.am b/innobase/read/Makefile.am
index 16224f4f7f4..7edf2a5a2e1 100644
--- a/innobase/read/Makefile.am
+++ b/innobase/read/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libread.a
+noinst_LIBRARIES = libread.a
libread_a_SOURCES = read0read.c
diff --git a/innobase/read/read0read.c b/innobase/read/read0read.c
index a5048c0c909..5c1d2d5418e 100644
--- a/innobase/read/read0read.c
+++ b/innobase/read/read0read.c
@@ -201,6 +201,28 @@ read_view_close(
}
/*************************************************************************
+Closes a consistent read view for MySQL. This function is called at an SQL
+statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
+
+void
+read_view_close_for_mysql(
+/*======================*/
+ trx_t* trx) /* in: trx which has a read view */
+{
+ ut_a(trx->read_view);
+
+ mutex_enter(&kernel_mutex);
+
+ read_view_close(trx->read_view);
+
+ mem_heap_empty(trx->read_view_heap);
+
+ trx->read_view = NULL;
+
+ mutex_exit(&kernel_mutex);
+}
+
+/*************************************************************************
Prints a read view to stderr. */
void
diff --git a/innobase/rem/Makefile.am b/innobase/rem/Makefile.am
index ef0cde9bd7a..e2b2fdaf669 100644
--- a/innobase/rem/Makefile.am
+++ b/innobase/rem/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = librem.a
+noinst_LIBRARIES = librem.a
librem_a_SOURCES = rem0rec.c rem0cmp.c
diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c
index 31c76705c4b..2e18e68ec43 100644
--- a/innobase/rem/rem0cmp.c
+++ b/innobase/rem/rem0cmp.c
@@ -38,7 +38,7 @@ Used in debug checking of cmp_dtuple_... .
This function is used to compare a data tuple to a physical record. If
dtuple has n fields then rec must have either m >= n fields, or it must
differ from dtuple in some of the m fields rec has. */
-static
+
int
cmp_debug_dtuple_rec_with_match(
/*============================*/
@@ -50,9 +50,10 @@ cmp_debug_dtuple_rec_with_match(
dtuple in some of the common fields, or which
has an equal number or more fields than
dtuple */
- ulint* matched_fields);/* in/out: number of already completely
- matched fields; when function returns,
- contains the value for current comparison */
+ ulint* matched_fields);/* in/out: number of already
+ completely matched fields; when function
+ returns, contains the value for current
+ comparison */
/*****************************************************************
This function is used to compare two data fields for which the data type
is such that we must use MySQL code to compare them. The prototype here
@@ -79,17 +80,12 @@ UNIV_INLINE
ulint
cmp_collate(
/*========*/
- /* out: collation order position */
- dtype_t* type, /* in: type */
- ulint code) /* in: code of a character stored in database
- record */
-{
- ut_ad((type->mtype == DATA_CHAR) || (type->mtype == DATA_VARCHAR));
-
+ /* out: collation order position */
+ ulint code) /* in: code of a character stored in database record */
+{
return((ulint) srv_latin1_ordering[code]);
}
-
/*****************************************************************
Returns TRUE if two types are equal for comparison purposes. */
@@ -118,7 +114,8 @@ cmp_types_are_equal(
if (type1->mtype == DATA_INT
&& (type1->prtype & DATA_UNSIGNED)
- != (type2->prtype & DATA_UNSIGNED)) {
+ != (type2->prtype & DATA_UNSIGNED)) {
+
/* The storage format of an unsigned integer is different
from a signed integer: in a signed integer we OR
0x8000... to the value of positive integers. */
@@ -131,12 +128,17 @@ cmp_types_are_equal(
return(FALSE);
}
+ if (type1->mtype == DATA_BLOB && (type1->prtype & DATA_BINARY_TYPE)
+ != (type2->prtype & DATA_BINARY_TYPE)) {
+ return(FALSE);
+ }
+
return(TRUE);
}
/*****************************************************************
-Innobase uses this function is to compare two data fields for which the
-data type is such that we must compare whole fields. */
+Innobase uses this function to compare two data fields for which the data type
+is such that we must compare whole fields or call MySQL to do the comparison */
static
int
cmp_whole_field(
@@ -239,8 +241,34 @@ cmp_whole_field(
return(0);
case DATA_VARMYSQL:
case DATA_MYSQL:
+ case DATA_BLOB:
+ if (data_type == DATA_BLOB
+ && 0 != (type->prtype & DATA_BINARY_TYPE)) {
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Error: comparing a binary BLOB with a character set sensitive\n"
+"InnoDB: comparison!\n");
+ }
+
+ /* MySQL does not pad the ends of strings with spaces in a
+ comparison. That would cause a foreign key check to fail for
+ non-latin1 character sets if we have different length columns.
+ To prevent that we remove trailing spaces here before doing
+ the comparison. NOTE that if we in the future map more MySQL
+ types to DATA_MYSQL or DATA_VARMYSQL, we have to change this
+ code. */
+
+ while (a_length > 0 && a[a_length - 1] == ' ') {
+ a_length--;
+ }
+
+ while (b_length > 0 && b[b_length - 1] == ' ') {
+ b_length--;
+ }
+
return(innobase_mysql_cmp(
- (int)(type->prtype & ~DATA_NOT_NULL),
+ (int)(type->prtype & DATA_MYSQL_TYPE_MASK),
a, a_length, b, b_length));
default:
fprintf(stderr,
@@ -291,7 +319,10 @@ cmp_data_data_slow(
return(1);
}
- if (cur_type->mtype >= DATA_FLOAT) {
+ if (cur_type->mtype >= DATA_FLOAT
+ || (cur_type->mtype == DATA_BLOB
+ && (cur_type->prtype & DATA_NONLATIN1))) {
+
return(cmp_whole_field(cur_type, data1, len1, data2, len2));
}
@@ -334,9 +365,12 @@ cmp_data_data_slow(
goto next_byte;
}
- if (cur_type->mtype <= DATA_CHAR) {
- data1_byte = cmp_collate(cur_type, data1_byte);
- data2_byte = cmp_collate(cur_type, data2_byte);
+ if (cur_type->mtype <= DATA_CHAR
+ || (cur_type->mtype == DATA_BLOB
+ && 0 == (cur_type->prtype & DATA_BINARY_TYPE))) {
+
+ data1_byte = cmp_collate(data1_byte);
+ data2_byte = cmp_collate(data2_byte);
}
if (data1_byte > data2_byte) {
@@ -353,7 +387,7 @@ cmp_data_data_slow(
data2++;
}
- return(0);
+ return(0); /* Not reached */
}
/*****************************************************************
@@ -487,7 +521,9 @@ cmp_dtuple_rec_with_match(
}
}
- if (cur_type->mtype >= DATA_FLOAT) {
+ if (cur_type->mtype >= DATA_FLOAT
+ || (cur_type->mtype == DATA_BLOB
+ && (cur_type->prtype & DATA_NONLATIN1))) {
ret = cmp_whole_field(cur_type,
dfield_get_data(dtuple_field), dtuple_f_len,
@@ -547,10 +583,13 @@ cmp_dtuple_rec_with_match(
goto next_byte;
}
- if (cur_type->mtype <= DATA_CHAR) {
- rec_byte = cmp_collate(cur_type, rec_byte);
- dtuple_byte = cmp_collate(cur_type,
- dtuple_byte);
+ if (cur_type->mtype <= DATA_CHAR
+ || (cur_type->mtype == DATA_BLOB
+ && 0 ==
+ (cur_type->prtype & DATA_BINARY_TYPE))) {
+
+ rec_byte = cmp_collate(rec_byte);
+ dtuple_byte = cmp_collate(dtuple_byte);
}
if (dtuple_byte > rec_byte) {
@@ -583,8 +622,8 @@ order_resolved:
matched_fields));
ut_ad(*matched_fields == cur_field); /* In the debug version, the
above cmp_debug_... sets
- *matched_fields to a value */
- *matched_fields = cur_field;
+ *matched_fields to a value */
+ *matched_fields = cur_field;
*matched_bytes = cur_bytes;
return(ret);
@@ -804,7 +843,10 @@ cmp_rec_rec_with_match(
}
}
- if (cur_type->mtype >= DATA_FLOAT) {
+ if (cur_type->mtype >= DATA_FLOAT
+ || (cur_type->mtype == DATA_BLOB
+ && (cur_type->prtype & DATA_NONLATIN1))) {
+
ret = cmp_whole_field(cur_type,
rec1_b_ptr, rec1_f_len,
rec2_b_ptr, rec2_f_len);
@@ -861,9 +903,13 @@ cmp_rec_rec_with_match(
goto next_byte;
}
- if (cur_type->mtype <= DATA_CHAR) {
- rec1_byte = cmp_collate(cur_type, rec1_byte);
- rec2_byte = cmp_collate(cur_type, rec2_byte);
+ if (cur_type->mtype <= DATA_CHAR
+ || (cur_type->mtype == DATA_BLOB
+ && 0 ==
+ (cur_type->prtype & DATA_BINARY_TYPE))) {
+
+ rec1_byte = cmp_collate(rec1_byte);
+ rec2_byte = cmp_collate(rec2_byte);
}
if (rec1_byte < rec2_byte) {
@@ -906,7 +952,7 @@ This function is used to compare a data tuple to a physical record. If
dtuple has n fields then rec must have either m >= n fields, or it must
differ from dtuple in some of the m fields rec has. If encounters an
externally stored field, returns 0. */
-static
+
int
cmp_debug_dtuple_rec_with_match(
/*============================*/
@@ -918,9 +964,10 @@ cmp_debug_dtuple_rec_with_match(
dtuple in some of the common fields, or which
has an equal number or more fields than
dtuple */
- ulint* matched_fields) /* in/out: number of already completely
- matched fields; when function returns,
- contains the value for current comparison */
+ ulint* matched_fields) /* in/out: number of already
+ completely matched fields; when function
+ returns, contains the value for current
+ comparison */
{
dtype_t* cur_type; /* pointer to type of the current
field in dtuple */
diff --git a/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c
index 3889f62afa2..a151389798d 100644
--- a/innobase/rem/rem0rec.c
+++ b/innobase/rem/rem0rec.c
@@ -528,9 +528,9 @@ rec_print(
ut_ad(rec);
if (rec_get_1byte_offs_flag(rec)) {
- offs = "TRUE";
+ offs = (char *) "TRUE";
} else {
- offs = "FALSE";
+ offs = (char *) "FALSE";
}
n = rec_get_n_fields(rec);
diff --git a/innobase/row/Makefile.am b/innobase/row/Makefile.am
index e4fcbe8f715..bd09f9a237d 100644
--- a/innobase/row/Makefile.am
+++ b/innobase/row/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = librow.a
+noinst_LIBRARIES = librow.a
librow_a_SOURCES = row0ins.c row0mysql.c row0purge.c row0row.c row0sel.c\
row0uins.c row0umod.c row0undo.c row0upd.c row0vers.c
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index 1f0d0f40114..d589cc8c9bc 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -32,6 +32,25 @@ Created 4/20/1996 Heikki Tuuri
#define ROW_INS_PREV 1
#define ROW_INS_NEXT 2
+
+/*********************************************************************
+This prototype is copied from /mysql/sql/ha_innodb.cc.
+Invalidates the MySQL query cache for the table.
+NOTE that the exact prototype of this function has to be in
+/innobase/row/row0ins.c! */
+
+void
+innobase_invalidate_query_cache(
+/*============================*/
+ trx_t* trx, /* in: transaction which modifies the table */
+ char* full_name, /* in: concatenation of database name, null
+ char '\0', table name, null char'\0';
+ NOTE that in Windows this is always
+ in LOWER CASE! */
+ ulint full_name_len); /* in: full name length where also the null
+ chars count */
+
+
/*************************************************************************
Creates an insert node struct. */
@@ -198,19 +217,23 @@ ins_node_set_new_row(
}
/***********************************************************************
-Does an insert operation by updating a delete marked existing record
-in the index. This situation can occur if the delete marked record is
+Does an insert operation by updating a delete-marked existing record
+in the index. This situation can occur if the delete-marked record is
kept in the index for consistent reads. */
static
ulint
row_ins_sec_index_entry_by_modify(
/*==============================*/
/* out: DB_SUCCESS or error code */
+ ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
+ depending on whether mtr holds just a leaf
+ latch or also a tree latch */
btr_cur_t* cursor, /* in: B-tree cursor */
dtuple_t* entry, /* in: index entry to insert */
que_thr_t* thr, /* in: query thread */
mtr_t* mtr) /* in: mtr */
{
+ big_rec_t* dummy_big_rec;
mem_heap_t* heap;
upd_t* update;
rec_t* rec;
@@ -221,17 +244,29 @@ row_ins_sec_index_entry_by_modify(
ut_ad((cursor->index->type & DICT_CLUSTERED) == 0);
ut_ad(rec_get_deleted_flag(rec));
- /* We know that in the ordering entry and rec are identified.
- But in their binary form there may be differences if there
- are char fields in them. Therefore we have to calculate the
- difference and do an update-in-place if necessary. */
+ /* We know that in the alphabetical ordering, entry and rec are
+ identified. But in their binary form there may be differences if
+ there are char fields in them. Therefore we have to calculate the
+ difference. */
heap = mem_heap_create(1024);
update = row_upd_build_sec_rec_difference_binary(cursor->index,
entry, rec, heap);
+ if (mode == BTR_MODIFY_LEAF) {
+ /* Try an optimistic updating of the record, keeping changes
+ within the page */
- err = btr_cur_update_sec_rec_in_place(cursor, update, thr, mtr);
+ err = btr_cur_optimistic_update(BTR_KEEP_SYS_FLAG, cursor,
+ update, 0, thr, mtr);
+ if (err == DB_OVERFLOW || err == DB_UNDERFLOW) {
+ err = DB_FAIL;
+ }
+ } else {
+ ut_a(mode == BTR_MODIFY_TREE);
+ err = btr_cur_pessimistic_update(BTR_KEEP_SYS_FLAG, cursor,
+ &dummy_big_rec, update, 0, thr, mtr);
+ }
mem_heap_free(heap);
@@ -286,8 +321,8 @@ row_ins_clust_index_entry_by_modify(
/* Try optimistic updating of the record, keeping changes
within the page */
- err = btr_cur_optimistic_update(0, cursor, update, 0, thr, mtr);
-
+ err = btr_cur_optimistic_update(0, cursor, update, 0, thr,
+ mtr);
if (err == DB_OVERFLOW || err == DB_UNDERFLOW) {
err = DB_FAIL;
}
@@ -302,67 +337,292 @@ row_ins_clust_index_entry_by_modify(
return(err);
}
-/*******************************************************************
-Checks if a unique key violation to rec would occur at the index entry
-insert. */
+/*************************************************************************
+Returns TRUE if in a cascaded update/delete an ancestor node of node
+updates (not DELETE, but UPDATE) table. */
static
ibool
-row_ins_dupl_error_with_rec(
-/*========================*/
- /* out: TRUE if error */
- rec_t* rec, /* in: user record; NOTE that we assume
- that the caller already has a record lock on
- the record! */
- dtuple_t* entry, /* in: entry to insert */
- dict_index_t* index) /* in: index */
+row_ins_cascade_ancestor_updates_table(
+/*===================================*/
+ /* out: TRUE if an ancestor updates table */
+ que_node_t* node, /* in: node in a query graph */
+ dict_table_t* table) /* in: table */
{
- ulint matched_fields;
- ulint matched_bytes;
- ulint n_unique;
- ulint i;
+ que_node_t* parent;
+ upd_node_t* upd_node;
+
+ parent = que_node_get_parent(node);
- n_unique = dict_index_get_n_unique(index);
+ while (que_node_get_type(parent) == QUE_NODE_UPDATE) {
- matched_fields = 0;
- matched_bytes = 0;
+ upd_node = parent;
- cmp_dtuple_rec_with_match(entry, rec, &matched_fields, &matched_bytes);
+ if (upd_node->table == table && upd_node->is_delete == FALSE) {
- if (matched_fields < n_unique) {
+ return(TRUE);
+ }
- return(FALSE);
+ parent = que_node_get_parent(parent);
+
+ ut_a(parent);
}
- /* In a unique secondary index we allow equal key values if they
- contain SQL NULLs */
+ return(FALSE);
+}
+
+/**********************************************************************
+Calculates the update vector node->cascade->update for a child table in
+a cascaded update. */
+static
+ulint
+row_ins_cascade_calc_update_vec(
+/*============================*/
+ /* out: number of fields in the
+ calculated update vector; the value
+ can also be 0 if no foreign key
+ fields changed; the returned value
+ is ULINT_UNDEFINED if the column
+ type in the child table is too short
+ to fit the new value in the parent
+ table: that means the update fails */
+ upd_node_t* node, /* in: update node of the parent
+ table */
+ dict_foreign_t* foreign, /* in: foreign key constraint whose
+ type is != 0 */
+ mem_heap_t* heap) /* in: memory heap to use as
+ temporary storage */
+{
+ upd_node_t* cascade = node->cascade_node;
+ dict_table_t* table = foreign->foreign_table;
+ dict_index_t* index = foreign->foreign_index;
+ upd_t* update;
+ upd_field_t* ufield;
+ dict_table_t* parent_table;
+ dict_index_t* parent_index;
+ upd_t* parent_update;
+ upd_field_t* parent_ufield;
+ ulint n_fields_updated;
+ ulint parent_field_no;
+ dtype_t* type;
+ ulint i;
+ ulint j;
+
+ ut_a(node && foreign && cascade && table && index);
+
+ /* Calculate the appropriate update vector which will set the fields
+ in the child index record to the same value (possibly padded with
+ spaces if the column is a fixed length CHAR or FIXBINARY column) as
+ the referenced index record will get in the update. */
+
+ parent_table = node->table;
+ ut_a(parent_table == foreign->referenced_table);
+ parent_index = foreign->referenced_index;
+ parent_update = node->update;
+
+ update = cascade->update;
- if (!(index->type & DICT_CLUSTERED)) {
+ update->info_bits = 0;
+ update->n_fields = foreign->n_fields;
+
+ n_fields_updated = 0;
- for (i = 0; i < n_unique; i++) {
- if (UNIV_SQL_NULL == dfield_get_len(
- dtuple_get_nth_field(entry, i))) {
+ for (i = 0; i < foreign->n_fields; i++) {
- return(FALSE);
- }
- }
+ parent_field_no = dict_table_get_nth_col_pos(
+ parent_table,
+ dict_index_get_nth_col_no(
+ parent_index, i));
+
+ for (j = 0; j < parent_update->n_fields; j++) {
+ parent_ufield = parent_update->fields + j;
+
+ if (parent_ufield->field_no == parent_field_no) {
+
+ /* A field in the parent index record is
+ updated. Let us make the update vector
+ field for the child table. */
+
+ ufield = update->fields + n_fields_updated;
+
+ ufield->field_no =
+ dict_table_get_nth_col_pos(table,
+ dict_index_get_nth_col_no(index, i));
+ ufield->exp = NULL;
+
+ ufield->new_val = parent_ufield->new_val;
+
+ type = dict_index_get_nth_type(index, i);
+
+ /* Do not allow a NOT NULL column to be
+ updated as NULL */
+
+ if (ufield->new_val.len == UNIV_SQL_NULL
+ && (type->prtype & DATA_NOT_NULL)) {
+
+ return(ULINT_UNDEFINED);
+ }
+
+ /* If the new value would not fit in the
+ column, do not allow the update */
+
+ if (ufield->new_val.len != UNIV_SQL_NULL
+ && ufield->new_val.len
+ > dtype_get_len(type)) {
+
+ return(ULINT_UNDEFINED);
+ }
+
+ /* If the parent column type has a different
+ length than the child column type, we may
+ need to pad with spaces the new value of the
+ child column */
+
+ if (dtype_is_fixed_size(type)
+ && ufield->new_val.len != UNIV_SQL_NULL
+ && ufield->new_val.len
+ < dtype_get_fixed_size(type)) {
+
+ ufield->new_val.data =
+ mem_heap_alloc(heap,
+ dtype_get_fixed_size(type));
+ ufield->new_val.len =
+ dtype_get_fixed_size(type);
+ ut_a(dtype_get_pad_char(type)
+ != ULINT_UNDEFINED);
+
+ memset(ufield->new_val.data,
+ (byte)dtype_get_pad_char(type),
+ dtype_get_fixed_size(type));
+ ut_memcpy(ufield->new_val.data,
+ parent_ufield->new_val.data,
+ parent_ufield->new_val.len);
+ }
+
+ ufield->extern_storage = FALSE;
+
+ n_fields_updated++;
+ }
+ }
}
- if (!rec_get_deleted_flag(rec)) {
+ update->n_fields = n_fields_updated;
- return(TRUE);
+ return(n_fields_updated);
+}
+
+/*************************************************************************
+Reports a foreign key error associated with an update or a delete of a
+parent table index entry. */
+static
+void
+row_ins_foreign_report_err(
+/*=======================*/
+ char* errstr, /* in: error string from the viewpoint
+ of the parent table */
+ que_thr_t* thr, /* in: query thread whose run_node
+ is an update node */
+ dict_foreign_t* foreign, /* in: foreign key constraint */
+ rec_t* rec, /* in: a matching index record in the
+ child table */
+ dtuple_t* entry) /* in: index entry in the parent
+ table */
+{
+ char* buf = dict_foreign_err_buf;
+
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf), " Transaction:\n");
+ trx_print(buf + strlen(buf), thr_get_trx(thr));
+
+ sprintf(buf + strlen(buf),
+"Foreign key constraint fails for table %.500s:\n",
+ foreign->foreign_table_name);
+ dict_print_info_on_foreign_key_in_create_format(
+ foreign, buf + strlen(buf));
+ sprintf(buf + strlen(buf), "\n%s", errstr);
+ sprintf(buf + strlen(buf),
+" in parent table, in index %.500s tuple:\n",
+ foreign->referenced_index->name);
+ if (entry) {
+ dtuple_sprintf(buf + strlen(buf), 1000, entry);
+ }
+ sprintf(buf + strlen(buf),
+"\nBut in child table %.500s, in index %.500s, there is a record:\n",
+ foreign->foreign_table_name, foreign->foreign_index->name);
+ if (rec) {
+ rec_sprintf(buf + strlen(buf), 1000, rec);
}
+ sprintf(buf + strlen(buf), "\n");
+
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
- return(FALSE);
-}
+ mutex_exit(&dict_foreign_err_mutex);
+}
/*************************************************************************
-Either deletes or sets the referencing columns SQL NULL in a child row.
-Used in ON DELETE ... clause for foreign keys when a parent row is
-deleted. */
+Reports a foreign key error to dict_foreign_err_buf when we are trying
+to add an index entry to a child table. Note that the adding may be the result
+of an update, too. */
+static
+void
+row_ins_foreign_report_add_err(
+/*===========================*/
+ que_thr_t* thr, /* in: query thread whose run_node
+ is an insert node */
+ dict_foreign_t* foreign, /* in: foreign key constraint */
+ rec_t* rec, /* in: a record in the parent table:
+ it does not match entry because we
+ have an error! */
+ dtuple_t* entry) /* in: index entry to insert in the
+ child table */
+{
+ char* buf = dict_foreign_err_buf;
+
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf), " Transaction:\n");
+ trx_print(buf + strlen(buf), thr_get_trx(thr));
+ sprintf(buf + strlen(buf),
+"Foreign key constraint fails for table %.500s:\n",
+ foreign->foreign_table_name);
+ dict_print_info_on_foreign_key_in_create_format(
+ foreign, buf + strlen(buf));
+ sprintf(buf + strlen(buf),
+"\nTrying to add in child table, in index %.500s tuple:\n",
+ foreign->foreign_index->name);
+ if (entry) {
+ dtuple_sprintf(buf + strlen(buf), 1000, entry);
+ }
+ sprintf(buf + strlen(buf),
+"\nBut in parent table %.500s, in index %.500s,\n"
+"the closest match we can find is record:\n",
+ foreign->referenced_table_name,
+ foreign->referenced_index->name);
+ if (rec && page_rec_is_supremum(rec)) {
+ /* If the cursor ended on a supremum record, it is better
+ to report the previous record in the error message, so that
+ the user gets a more descriptive error message. */
+ rec = page_rec_get_prev(rec);
+ }
+
+ if (rec) {
+ rec_sprintf(buf + strlen(buf), 1000, rec);
+ }
+ sprintf(buf + strlen(buf), "\n");
+
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+
+ mutex_exit(&dict_foreign_err_mutex);
+}
+
+/*************************************************************************
+Perform referential actions or checks when a parent row is deleted or updated
+and the constraint had an ON DELETE or ON UPDATE condition which was not
+RESTRICT. */
static
ulint
-row_ins_foreign_delete_or_set_null(
-/*===============================*/
+row_ins_foreign_check_on_constraint(
+/*================================*/
/* out: DB_SUCCESS, DB_LOCK_WAIT,
or error code */
que_thr_t* thr, /* in: query thread whose run_node
@@ -371,6 +631,8 @@ row_ins_foreign_delete_or_set_null(
type is != 0 */
btr_pcur_t* pcur, /* in: cursor placed on a matching
index record in the child table */
+ dtuple_t* entry, /* in: index entry in the parent
+ table */
mtr_t* mtr) /* in: mtr holding the latch of pcur
page */
{
@@ -381,26 +643,61 @@ row_ins_foreign_delete_or_set_null(
dict_index_t* clust_index;
dtuple_t* ref;
mem_heap_t* tmp_heap;
+ mem_heap_t* upd_vec_heap = NULL;
rec_t* rec;
rec_t* clust_rec;
upd_t* update;
+ ulint n_to_update;
ulint err;
ulint i;
+ char* ptr;
+ char table_name_buf[1000];
char err_buf[1000];
ut_a(thr && foreign && pcur && mtr);
+ /* Since we are going to delete or update a row, we have to invalidate
+ the MySQL query cache for table */
+
+ ut_a(ut_strlen(table->name) < 998);
+
+ ut_memcpy(table_name_buf, table->name, ut_strlen(table->name) + 1);
+
+ ptr = table_name_buf;
+
+ while (*ptr != '/') {
+ ptr++;
+ }
+
+ *ptr = '\0';
+
+ /* We call a function in ha_innodb.cc */
+#ifndef UNIV_HOTBACKUP
+ innobase_invalidate_query_cache(thr_get_trx(thr), table_name_buf,
+ ut_strlen(table->name) + 1);
+#endif
node = thr->run_node;
- ut_a(que_node_get_type(node) == QUE_NODE_UPDATE);
+ if (node->is_delete && 0 == (foreign->type &
+ (DICT_FOREIGN_ON_DELETE_CASCADE
+ | DICT_FOREIGN_ON_DELETE_SET_NULL))) {
- if (!node->is_delete) {
- /* According to SQL-92 an UPDATE with respect to FOREIGN
- KEY constraints is not semantically equivalent to a
- DELETE + INSERT. Therefore we do not perform any action
- here and consequently the child rows would be left
- orphaned if we would let the UPDATE happen. Thus we return
- an error. */
+ row_ins_foreign_report_err((char*)"Trying to delete",
+ thr, foreign,
+ btr_pcur_get_rec(pcur), entry);
+
+ return(DB_ROW_IS_REFERENCED);
+ }
+
+ if (!node->is_delete && 0 == (foreign->type &
+ (DICT_FOREIGN_ON_UPDATE_CASCADE
+ | DICT_FOREIGN_ON_UPDATE_SET_NULL))) {
+
+ /* This is an UPDATE */
+
+ row_ins_foreign_report_err((char*)"Trying to update",
+ thr, foreign,
+ btr_pcur_get_rec(pcur), entry);
return(DB_ROW_IS_REFERENCED);
}
@@ -425,7 +722,10 @@ row_ins_foreign_delete_or_set_null(
cascade->table = table;
- if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE ) {
+ cascade->foreign = foreign;
+
+ if (node->is_delete
+ && (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE)) {
cascade->is_delete = TRUE;
} else {
cascade->is_delete = FALSE;
@@ -439,8 +739,33 @@ row_ins_foreign_delete_or_set_null(
}
}
+ /* We do not allow cyclic cascaded updating (DELETE is allowed,
+ but not UPDATE) of the same table, as this can lead to an infinite
+ cycle. Check that we are not updating the same table which is
+ already being modified in this cascade chain. We have to check
+ this also because the modification of the indexes of a 'parent'
+ table may still be incomplete, and we must avoid seeing the indexes
+ of the parent table in an inconsistent state! */
+
+ if (!cascade->is_delete
+ && row_ins_cascade_ancestor_updates_table(cascade, table)) {
+
+ /* We do not know if this would break foreign key
+ constraints, but play safe and return an error */
+
+ err = DB_ROW_IS_REFERENCED;
+
+ row_ins_foreign_report_err(
+(char*)"Trying an update, possibly causing a cyclic cascaded update\n"
+"in the child table,", thr, foreign, btr_pcur_get_rec(pcur), entry);
+
+ goto nonstandard_exit_func;
+ }
+
index = btr_pcur_get_btr_cur(pcur)->index;
+ ut_a(index == foreign->foreign_index);
+
rec = btr_pcur_get_rec(pcur);
if (index->type & DICT_CLUSTERED) {
@@ -466,27 +791,30 @@ row_ins_foreign_delete_or_set_null(
mem_heap_free(tmp_heap);
clust_rec = btr_pcur_get_rec(cascade->pcur);
- }
- if (!page_rec_is_user_rec(clust_rec)) {
- fprintf(stderr,
+ if (!page_rec_is_user_rec(clust_rec)
+ || btr_pcur_get_low_match(cascade->pcur)
+ < dict_index_get_n_unique(clust_index)) {
+
+ fprintf(stderr,
"InnoDB: error in cascade of a foreign key op\n"
"InnoDB: index %s table %s\n", index->name,
index->table->name);
- rec_sprintf(err_buf, 900, rec);
- fprintf(stderr, "InnoDB: record %s\n", err_buf);
-
- rec_sprintf(err_buf, 900, clust_rec);
- fprintf(stderr, "InnoDB: clustered record %s\n", err_buf);
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr, "InnoDB: record %s\n", err_buf);
- fprintf(stderr,
+ rec_sprintf(err_buf, 900, clust_rec);
+ fprintf(stderr, "InnoDB: clustered record %s\n",
+ err_buf);
+ fprintf(stderr,
"InnoDB: Make a detailed bug report and send it\n");
- fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
+ fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
- err = DB_SUCCESS;
+ err = DB_SUCCESS;
- goto nonstandard_exit_func;
+ goto nonstandard_exit_func;
+ }
}
/* Set an X-lock on the row to delete or update in the child table */
@@ -494,8 +822,12 @@ row_ins_foreign_delete_or_set_null(
err = lock_table(0, table, LOCK_IX, thr);
if (err == DB_SUCCESS) {
+ /* Here it suffices to use a LOCK_REC_NOT_GAP type lock;
+ we already have a normal shared lock on the appropriate
+ gap if the search criterion was not unique */
+
err = lock_clust_rec_read_check_and_lock(0, clust_rec,
- clust_index, LOCK_X, thr);
+ clust_index, LOCK_X, LOCK_REC_NOT_GAP, thr);
}
if (err != DB_SUCCESS) {
@@ -530,7 +862,11 @@ row_ins_foreign_delete_or_set_null(
goto nonstandard_exit_func;
}
- if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) {
+ if ((node->is_delete
+ && (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL))
+ || (!node->is_delete
+ && (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL))) {
+
/* Build the appropriate update vector which sets
foreign->n_fields first fields in rec to SQL NULL */
@@ -550,6 +886,40 @@ row_ins_foreign_delete_or_set_null(
}
}
+ if (!node->is_delete
+ && (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)) {
+
+ /* Build the appropriate update vector which sets changing
+ foreign->n_fields first fields in rec to new values */
+
+ upd_vec_heap = mem_heap_create(256);
+
+ n_to_update = row_ins_cascade_calc_update_vec(node, foreign,
+ upd_vec_heap);
+ if (n_to_update == ULINT_UNDEFINED) {
+ err = DB_ROW_IS_REFERENCED;
+
+ row_ins_foreign_report_err(
+(char*)"Trying a cascaded update where the updated value in the child\n"
+"table would not fit in the length of the column, or the value would\n"
+"be NULL and the column is declared as not NULL in the child table,",
+ thr, foreign, btr_pcur_get_rec(pcur), entry);
+
+ goto nonstandard_exit_func;
+ }
+
+ if (cascade->update->n_fields == 0) {
+
+ /* The update does not change any columns referred
+ to in this foreign key constraint: no need to do
+ anything */
+
+ err = DB_SUCCESS;
+
+ goto nonstandard_exit_func;
+ }
+ }
+
/* Store pcur position and initialize or store the cascade node
pcur stored position */
@@ -575,10 +945,18 @@ row_ins_foreign_delete_or_set_null(
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr);
+ if (upd_vec_heap) {
+ mem_heap_free(upd_vec_heap);
+ }
+
return(err);
nonstandard_exit_func:
+ if (upd_vec_heap) {
+ mem_heap_free(upd_vec_heap);
+ }
+
btr_pcur_store_position(pcur, mtr);
mtr_commit(mtr);
@@ -591,12 +969,14 @@ nonstandard_exit_func:
/*************************************************************************
Sets a shared lock on a record. Used in locking possible duplicate key
-records. */
+records and also in checking foreign key constraints. */
static
ulint
row_ins_set_shared_rec_lock(
/*========================*/
/* out: DB_SUCCESS or error code */
+ ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
+ LOCK_REC_NOT_GAP type lock */
rec_t* rec, /* in: record */
dict_index_t* index, /* in: index */
que_thr_t* thr) /* in: query thread */
@@ -605,10 +985,10 @@ row_ins_set_shared_rec_lock(
if (index->type & DICT_CLUSTERED) {
err = lock_clust_rec_read_check_and_lock(0, rec, index, LOCK_S,
- thr);
+ type, thr);
} else {
err = lock_sec_rec_read_check_and_lock(0, rec, index, LOCK_S,
- thr);
+ type, thr);
}
return(err);
@@ -617,7 +997,7 @@ row_ins_set_shared_rec_lock(
/*******************************************************************
Checks if foreign key constraint fails for an index entry. Sets shared locks
which lock either the success or the failure of the constraint. NOTE that
-the caller must have a shared latch on dict_foreign_key_check_lock. */
+the caller must have a shared latch on dict_operation_lock. */
ulint
row_ins_check_foreign_constraint(
@@ -633,24 +1013,27 @@ row_ins_check_foreign_constraint(
dictionary cache if they exist at all */
dict_table_t* table, /* in: if check_ref is TRUE, then the foreign
table, else the referenced table */
- dict_index_t* index, /* in: index in table */
dtuple_t* entry, /* in: index entry for index */
que_thr_t* thr) /* in: query thread */
{
+ upd_node_t* upd_node;
dict_table_t* check_table;
dict_index_t* check_index;
ulint n_fields_cmp;
- ibool timeout_expired;
+ ibool unique_search;
rec_t* rec;
btr_pcur_t pcur;
ibool moved;
int cmp;
ulint err;
ulint i;
+ char* buf = dict_foreign_err_buf;
mtr_t mtr;
run_again:
- ut_ad(rw_lock_own(&dict_foreign_key_check_lock, RW_LOCK_SHARED));
+ ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_SHARED));
+
+ err = DB_SUCCESS;
if (thr_get_trx(thr)->check_foreigns == FALSE) {
/* The user has suppressed foreign key checks currently for
@@ -671,6 +1054,30 @@ run_again:
}
}
+ if (que_node_get_type(thr->run_node) == QUE_NODE_UPDATE) {
+ upd_node = thr->run_node;
+
+ if (!(upd_node->is_delete) && upd_node->foreign == foreign) {
+ /* If a cascaded update is done as defined by a
+ foreign key constraint, do not check that
+ constraint for the child row. In ON UPDATE CASCADE
+ the update of the parent row is only half done when
+ we come here: if we would check the constraint here
+ for the child row it would fail.
+
+ A QUESTION remains: if in the child table there are
+ several constraints which refer to the same parent
+ table, we should merge all updates to the child as
+ one update? And the updates can be contradictory!
+ Currently we just perform the update associated
+ with each foreign key constraint, one after
+ another, and the user has problems predicting in
+ which order they are performed. */
+
+ return(DB_SUCCESS);
+ }
+ }
+
if (check_ref) {
check_table = foreign->referenced_table;
check_index = foreign->referenced_index;
@@ -681,6 +1088,25 @@ run_again:
if (check_table == NULL) {
if (check_ref) {
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf), " Transaction:\n");
+ trx_print(buf + strlen(buf), thr_get_trx(thr));
+ sprintf(buf + strlen(buf),
+"Foreign key constraint fails for table %.500s:\n",
+ foreign->foreign_table_name);
+ dict_print_info_on_foreign_key_in_create_format(
+ foreign, buf + strlen(buf));
+ sprintf(buf + strlen(buf),
+"\nTrying to add to index %.500s tuple:\n", foreign->foreign_index->name);
+ dtuple_sprintf(buf + strlen(buf), 1000, entry);
+ sprintf(buf + strlen(buf),
+"\nBut the parent table %.500s does not currently exist!\n",
+ foreign->referenced_table_name);
+
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+ mutex_exit(&dict_foreign_err_mutex);
+
return(DB_NO_REFERENCED_ROW);
}
@@ -709,6 +1135,14 @@ run_again:
dtuple_set_n_fields_cmp(entry, foreign->n_fields);
+ if (dict_index_get_n_unique(check_index) <= foreign->n_fields) {
+ /* We can just set a LOCK_REC_NOT_GAP type lock */
+
+ unique_search = TRUE;
+ } else {
+ unique_search = FALSE;
+ }
+
btr_pcur_open(check_index, entry, PAGE_CUR_GE,
BTR_SEARCH_LEAF, &pcur, &mtr);
@@ -722,25 +1156,46 @@ run_again:
goto next_rec;
}
- /* Try to place a lock on the index record */
-
- err = row_ins_set_shared_rec_lock(rec, check_index, thr);
-
- if (err != DB_SUCCESS) {
-
- break;
- }
-
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
+ err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, rec,
+ check_index, thr);
+ if (err != DB_SUCCESS) {
+
+ break;
+ }
+
goto next_rec;
}
cmp = cmp_dtuple_rec(entry, rec);
if (cmp == 0) {
- if (!rec_get_deleted_flag(rec)) {
+ if (rec_get_deleted_flag(rec)) {
+ err = row_ins_set_shared_rec_lock(
+ LOCK_ORDINARY,
+ rec, check_index, thr);
+ if (err != DB_SUCCESS) {
+
+ break;
+ }
+ } else {
/* Found a matching record */
+
+ if (unique_search) {
+ err = row_ins_set_shared_rec_lock(
+ LOCK_REC_NOT_GAP,
+ rec, check_index, thr);
+ } else {
+ err = row_ins_set_shared_rec_lock(
+ LOCK_ORDINARY,
+ rec, check_index, thr);
+ }
+
+ if (err != DB_SUCCESS) {
+
+ break;
+ }
/* printf(
"FOREIGN: Found matching record from %s %s\n",
@@ -752,15 +1207,23 @@ run_again:
break;
} else if (foreign->type != 0) {
- err =
- row_ins_foreign_delete_or_set_null(
- thr, foreign, &pcur, &mtr);
+ /* There is an ON UPDATE or ON DELETE
+ condition: check them in a separate
+ function */
+ err =
+ row_ins_foreign_check_on_constraint(
+ thr, foreign, &pcur, entry,
+ &mtr);
if (err != DB_SUCCESS) {
break;
}
} else {
+ row_ins_foreign_report_err(
+ (char*)"Trying to delete or update",
+ thr, foreign, rec, entry);
+
err = DB_ROW_IS_REFERENCED;
break;
}
@@ -768,8 +1231,17 @@ run_again:
}
if (cmp < 0) {
+ err = row_ins_set_shared_rec_lock(LOCK_GAP,
+ rec, check_index, thr);
+ if (err != DB_SUCCESS) {
+
+ break;
+ }
+
if (check_ref) {
err = DB_NO_REFERENCED_ROW;
+ row_ins_foreign_report_add_err(
+ thr, foreign, rec, entry);
} else {
err = DB_SUCCESS;
}
@@ -783,6 +1255,9 @@ next_rec:
if (!moved) {
if (check_ref) {
+ rec = btr_pcur_get_rec(&pcur);
+ row_ins_foreign_report_add_err(
+ thr, foreign, rec, entry);
err = DB_NO_REFERENCED_ROW;
} else {
err = DB_SUCCESS;
@@ -805,14 +1280,14 @@ do_possible_lock_wait:
que_thr_stop_for_mysql(thr);
- timeout_expired = srv_suspend_mysql_thread(thr);
+ srv_suspend_mysql_thread(thr);
- if (!timeout_expired) {
+ if (thr_get_trx(thr)->error_state == DB_SUCCESS) {
goto run_again;
}
- err = DB_LOCK_WAIT_TIMEOUT;
+ err = thr_get_trx(thr)->error_state;
}
return(err);
@@ -851,21 +1326,16 @@ row_ins_check_foreign_constraints(
trx);
}
- if (!trx->has_dict_foreign_key_check_lock) {
+ if (0 == trx->dict_operation_lock_mode) {
got_s_lock = TRUE;
- rw_lock_s_lock(&dict_foreign_key_check_lock);
-
- trx->has_dict_foreign_key_check_lock = TRUE;
+ row_mysql_freeze_data_dictionary(trx);
}
err = row_ins_check_foreign_constraint(TRUE, foreign,
- table, index, entry, thr);
+ table, entry, thr);
if (got_s_lock) {
-
- rw_lock_s_unlock(&dict_foreign_key_check_lock);
-
- trx->has_dict_foreign_key_check_lock = FALSE;
+ row_mysql_unfreeze_data_dictionary(trx);
}
if (err != DB_SUCCESS) {
@@ -879,6 +1349,111 @@ row_ins_check_foreign_constraints(
return(DB_SUCCESS);
}
+/*************************************************************************
+Reports a UNIQUE key error to dict_unique_err_buf so that SHOW INNODB
+STATUS can print it. */
+static
+void
+row_ins_unique_report_err(
+/*======================*/
+ que_thr_t* thr, /* in: query thread */
+ rec_t* rec, /* in: a record in the index */
+ dtuple_t* entry, /* in: index entry to insert in the index */
+ dict_index_t* index) /* in: index */
+{
+ UT_NOT_USED(thr);
+ UT_NOT_USED(rec);
+ UT_NOT_USED(entry);
+ UT_NOT_USED(index);
+
+#ifdef notdefined
+ /* Disable reporting to test if the slowdown of REPLACE in 4.0.13 was
+ caused by this! */
+
+ char* buf = dict_unique_err_buf;
+
+ /* The foreign err mutex protects also dict_unique_err_buf */
+
+ mutex_enter(&dict_foreign_err_mutex);
+
+ ut_sprintf_timestamp(buf);
+ sprintf(buf + strlen(buf), " Transaction:\n");
+ trx_print(buf + strlen(buf), thr_get_trx(thr));
+
+ sprintf(buf + strlen(buf),
+"Unique key constraint fails for table %.500s.\n", index->table_name);
+ sprintf(buf + strlen(buf),
+"Trying to add in index %.500s (%lu fields unique) tuple:\n", index->name,
+ dict_index_get_n_unique(index));
+
+ dtuple_sprintf(buf + strlen(buf), 1000, entry);
+
+ sprintf(buf + strlen(buf),
+"\nBut there is already a record:\n");
+
+ rec_sprintf(buf + strlen(buf), 1000, rec);
+
+ sprintf(buf + strlen(buf), "\n");
+
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+
+ mutex_exit(&dict_foreign_err_mutex);
+#endif
+}
+
+/*******************************************************************
+Checks if a unique key violation to rec would occur at the index entry
+insert. */
+static
+ibool
+row_ins_dupl_error_with_rec(
+/*========================*/
+ /* out: TRUE if error */
+ rec_t* rec, /* in: user record; NOTE that we assume
+ that the caller already has a record lock on
+ the record! */
+ dtuple_t* entry, /* in: entry to insert */
+ dict_index_t* index) /* in: index */
+{
+ ulint matched_fields;
+ ulint matched_bytes;
+ ulint n_unique;
+ ulint i;
+
+ n_unique = dict_index_get_n_unique(index);
+
+ matched_fields = 0;
+ matched_bytes = 0;
+
+ cmp_dtuple_rec_with_match(entry, rec, &matched_fields, &matched_bytes);
+
+ if (matched_fields < n_unique) {
+
+ return(FALSE);
+ }
+
+ /* In a unique secondary index we allow equal key values if they
+ contain SQL NULLs */
+
+ if (!(index->type & DICT_CLUSTERED)) {
+
+ for (i = 0; i < n_unique; i++) {
+ if (UNIV_SQL_NULL == dfield_get_len(
+ dtuple_get_nth_field(entry, i))) {
+
+ return(FALSE);
+ }
+ }
+ }
+
+ if (!rec_get_deleted_flag(rec)) {
+
+ return(TRUE);
+ }
+
+ return(FALSE);
+}
+
/*******************************************************************
Scans a unique non-clustered index at a given index entry to determine
whether a uniqueness violation has occurred for the key value of the entry.
@@ -937,9 +1512,10 @@ row_ins_scan_sec_index_for_duplicate(
goto next_rec;
}
- /* Try to place a lock on the index record */
+ /* Try to place a lock on the index record */
- err = row_ins_set_shared_rec_lock(rec, index, thr);
+ err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, rec, index,
+ thr);
if (err != DB_SUCCESS) {
@@ -955,10 +1531,8 @@ row_ins_scan_sec_index_for_duplicate(
if (cmp == 0) {
if (row_ins_dupl_error_with_rec(rec, entry, index)) {
- /* printf("Duplicate key in index %s\n",
- index->name);
- dtuple_print(entry); */
-
+ row_ins_unique_report_err(thr, rec, entry,
+ index);
err = DB_DUPLICATE_KEY;
thr_get_trx(thr)->error_info = index;
@@ -1043,8 +1617,8 @@ row_ins_duplicate_error_in_clust(
sure that in roll-forward we get the same duplicate
errors as in original execution */
- err = row_ins_set_shared_rec_lock(rec, cursor->index,
- thr);
+ err = row_ins_set_shared_rec_lock(LOCK_REC_NOT_GAP,
+ rec, cursor->index, thr);
if (err != DB_SUCCESS) {
return(err);
@@ -1053,7 +1627,8 @@ row_ins_duplicate_error_in_clust(
if (row_ins_dupl_error_with_rec(rec, entry,
cursor->index)) {
trx->error_info = cursor->index;
-
+ row_ins_unique_report_err(thr, rec, entry,
+ cursor->index);
return(DB_DUPLICATE_KEY);
}
}
@@ -1066,8 +1641,8 @@ row_ins_duplicate_error_in_clust(
if (rec != page_get_supremum_rec(page)) {
- err = row_ins_set_shared_rec_lock(rec, cursor->index,
- thr);
+ err = row_ins_set_shared_rec_lock(LOCK_REC_NOT_GAP,
+ rec, cursor->index, thr);
if (err != DB_SUCCESS) {
return(err);
@@ -1077,6 +1652,8 @@ row_ins_duplicate_error_in_clust(
cursor->index)) {
trx->error_info = cursor->index;
+ row_ins_unique_report_err(thr, rec, entry,
+ cursor->index);
return(DB_DUPLICATE_KEY);
}
}
@@ -1159,7 +1736,7 @@ row_ins_index_entry_low(
{
btr_cur_t cursor;
ulint ignore_sec_unique = 0;
- ulint modify;
+ ulint modify = 0; /* remove warning */
rec_t* insert_rec;
rec_t* rec;
ulint err;
@@ -1252,7 +1829,8 @@ row_ins_index_entry_low(
ext_vec, n_ext_vec,
thr, &mtr);
} else {
- err = row_ins_sec_index_entry_by_modify(&cursor, entry,
+ err = row_ins_sec_index_entry_by_modify(mode, &cursor,
+ entry,
thr, &mtr);
}
@@ -1330,7 +1908,7 @@ row_ins_index_entry(
/* Try first optimistic descent to the B-tree */
err = row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry,
- ext_vec, n_ext_vec, thr);
+ ext_vec, n_ext_vec, thr);
if (err != DB_FAIL) {
return(err);
@@ -1346,13 +1924,15 @@ row_ins_index_entry(
/***************************************************************
Sets the values of the dtuple fields in entry from the values of appropriate
columns in row. */
-UNIV_INLINE
+static
void
row_ins_index_entry_set_vals(
/*=========================*/
+ dict_index_t* index, /* in: index */
dtuple_t* entry, /* in: index entry to make */
dtuple_t* row) /* in: row */
{
+ dict_field_t* ind_field;
dfield_t* field;
dfield_t* row_field;
ulint n_fields;
@@ -1364,11 +1944,21 @@ row_ins_index_entry_set_vals(
for (i = 0; i < n_fields; i++) {
field = dtuple_get_nth_field(entry, i);
+ ind_field = dict_index_get_nth_field(index, i);
+
+ row_field = dtuple_get_nth_field(row, ind_field->col->ind);
- row_field = dtuple_get_nth_field(row, field->col_no);
+ /* Check column prefix indexes */
+ if (ind_field->prefix_len > 0
+ && dfield_get_len(row_field) != UNIV_SQL_NULL
+ && dfield_get_len(row_field) > ind_field->prefix_len) {
+
+ field->len = ind_field->prefix_len;
+ } else {
+ field->len = row_field->len;
+ }
field->data = row_field->data;
- field->len = row_field->len;
}
}
@@ -1387,7 +1977,7 @@ row_ins_index_entry_step(
ut_ad(dtuple_check_typed(node->row));
- row_ins_index_entry_set_vals(node->entry, node->row);
+ row_ins_index_entry_set_vals(node->index, node->entry, node->row);
ut_ad(dtuple_check_typed(node->entry));
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index ae2f3514f4d..257756ff8aa 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -6,7 +6,7 @@ Contains also create table and other data dictionary operations.
Created 9/17/2000 Heikki Tuuri
*******************************************************/
-
+
#include "row0mysql.h"
#ifdef UNIV_NONINL
@@ -27,6 +27,7 @@ Created 9/17/2000 Heikki Tuuri
#include "lock0lock.h"
#include "rem0cmp.h"
#include "log0log.h"
+#include "btr0sea.h"
/* A dummy variable used to fool the compiler */
ibool row_mysql_identically_false = FALSE;
@@ -75,9 +76,6 @@ row_mysql_store_blob_ref(
also to set the NULL bit in the MySQL record
header! */
{
- ulint sum = 0;
- ulint i;
-
/* MySQL might assume the field is set to zero except the length and
the pointer fields */
@@ -92,22 +90,6 @@ row_mysql_store_blob_ref(
ut_a(col_len - 8 > 2 || len < 256 * 256);
ut_a(col_len - 8 > 3 || len < 256 * 256 * 256);
- /* We try to track an elusive bug which probably was fixed
- May 9, 2002, but better be sure: we probe the data buffer
- to make sure it is in valid allocated memory */
-
- for (i = 0; i < len; i++) {
-
- sum += (ulint)(data + i);
- }
-
- /* The variable below is identically false, we just fool the
- compiler to not optimize away our loop */
- if (row_mysql_identically_false) {
-
- printf("Sum %lu\n", sum);
- }
-
mach_write_to_n_little_endian(dest, col_len - 8, len);
ut_memcpy(dest + col_len - 8, (byte*)&data, sizeof(byte*));
@@ -197,13 +179,13 @@ row_mysql_handle_errors(
/* out: TRUE if it was a lock wait and
we should continue running the query thread */
ulint* new_err,/* out: possible new error encountered in
- rollback, or the old error which was
- during the function entry */
+ lock wait, or if no new error, the value
+ of trx->error_state at the entry of this
+ function */
trx_t* trx, /* in: transaction */
que_thr_t* thr, /* in: query thread */
trx_savept_t* savept) /* in: savepoint or NULL */
{
- ibool timeout_expired;
ulint err;
handle_new_error:
@@ -240,11 +222,9 @@ handle_new_error:
/* MySQL will roll back the latest SQL statement */
} else if (err == DB_LOCK_WAIT) {
- timeout_expired = srv_suspend_mysql_thread(thr);
-
- if (timeout_expired) {
- trx->error_state = DB_LOCK_WAIT_TIMEOUT;
+ srv_suspend_mysql_thread(thr);
+ if (trx->error_state != DB_SUCCESS) {
que_thr_stop_for_mysql(thr);
goto handle_new_error;
@@ -277,6 +257,17 @@ handle_new_error:
"InnoDB: my.cnf and restart the database.\n");
exit(1);
+ } else if (err == DB_CORRUPTION) {
+
+ fprintf(stderr,
+ "InnoDB: We detected index corruption in an InnoDB type table.\n"
+ "InnoDB: You have to dump + drop + reimport the table or, in\n"
+ "InnoDB: a case of widespread corruption, dump all InnoDB\n"
+ "InnoDB: tables and recreate the whole InnoDB tablespace.\n"
+ "InnoDB: If the mysqld server crashes after the startup or when\n"
+ "InnoDB: you dump the tables, look at section 6.1 of\n"
+ "InnoDB: http://www.innodb.com/ibman.html for help.\n");
+
} else {
fprintf(stderr, "InnoDB: unknown error code %lu\n", err);
ut_a(0);
@@ -314,15 +305,20 @@ row_create_prebuilt(
prebuilt = mem_heap_alloc(heap, sizeof(row_prebuilt_t));
prebuilt->magic_n = ROW_PREBUILT_ALLOCATED;
+ prebuilt->magic_n2 = ROW_PREBUILT_ALLOCATED;
prebuilt->table = table;
prebuilt->trx = NULL;
prebuilt->sql_stat_start = TRUE;
+
prebuilt->mysql_has_locked = FALSE;
prebuilt->index = NULL;
+
+ prebuilt->used_in_HANDLER = FALSE;
+
prebuilt->n_template = 0;
prebuilt->mysql_template = NULL;
@@ -378,11 +374,12 @@ row_prebuilt_free(
{
ulint i;
- if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
+ if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED
+ || prebuilt->magic_n2 != ROW_PREBUILT_ALLOCATED) {
fprintf(stderr,
- "InnoDB: Error: trying to free a corrupt\n"
- "InnoDB: table handle. Magic n %lu, table name %s\n",
- prebuilt->magic_n, prebuilt->table->name);
+"InnoDB: Error: trying to free a corrupt\n"
+"InnoDB: table handle. Magic n %lu, magic n2 %lu, table name %s\n",
+ prebuilt->magic_n, prebuilt->magic_n2, prebuilt->table->name);
mem_analyze_corruption((byte*)prebuilt);
@@ -390,6 +387,7 @@ row_prebuilt_free(
}
prebuilt->magic_n = ROW_PREBUILT_FREED;
+ prebuilt->magic_n2 = ROW_PREBUILT_FREED;
btr_pcur_free_for_mysql(prebuilt->pcur);
btr_pcur_free_for_mysql(prebuilt->clust_pcur);
@@ -420,7 +418,23 @@ row_prebuilt_free(
for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) {
if (prebuilt->fetch_cache[i] != NULL) {
- mem_free(prebuilt->fetch_cache[i]);
+
+ if ((ROW_PREBUILT_FETCH_MAGIC_N !=
+ mach_read_from_4((prebuilt->fetch_cache[i]) - 4))
+ || (ROW_PREBUILT_FETCH_MAGIC_N !=
+ mach_read_from_4((prebuilt->fetch_cache[i])
+ + prebuilt->mysql_row_len))) {
+ fprintf(stderr,
+ "InnoDB: Error: trying to free a corrupt\n"
+ "InnoDB: fetch buffer.\n");
+
+ mem_analyze_corruption(
+ prebuilt->fetch_cache[i]);
+
+ ut_a(0);
+ }
+
+ mem_free((prebuilt->fetch_cache[i]) - 4);
}
}
@@ -493,6 +507,7 @@ row_get_prebuilt_insert_row(
ins_node_t* node;
dtuple_t* row;
dict_table_t* table = prebuilt->table;
+ ulint i;
ut_ad(prebuilt && table && prebuilt->trx);
@@ -516,6 +531,14 @@ row_get_prebuilt_insert_row(
dict_table_copy_types(row, table);
+ /* We init the value of every field to the SQL NULL to avoid
+ a debug assertion from failing */
+
+ for (i = 0; i < dtuple_get_n_fields(row); i++) {
+
+ dtuple_get_nth_field(row, i)->len = UNIV_SQL_NULL;
+ }
+
ins_node_set_new_row(node, row);
prebuilt->ins_graph =
@@ -601,7 +624,7 @@ row_lock_table_autoinc_for_mysql(
return(DB_SUCCESS);
}
- trx->op_info = "setting auto-inc lock";
+ trx->op_info = (char *) "setting auto-inc lock";
if (node == NULL) {
row_get_prebuilt_insert_row(prebuilt);
@@ -637,14 +660,14 @@ run_again:
goto run_again;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
que_thr_stop_for_mysql_no_error(thr, trx);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -692,7 +715,7 @@ row_insert_for_mysql(
return(DB_ERROR);
}
- trx->op_info = "inserting";
+ trx->op_info = (char *) "inserting";
trx_start_if_not_started(trx);
@@ -733,7 +756,7 @@ run_again:
goto run_again;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
@@ -750,7 +773,7 @@ run_again:
}
row_update_statistics_if_needed(prebuilt->table);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -908,7 +931,7 @@ row_update_for_mysql(
return(DB_ERROR);
}
- trx->op_info = "updating or deleting";
+ trx->op_info = (char *) "updating or deleting";
trx_start_if_not_started(trx);
@@ -919,7 +942,8 @@ row_update_for_mysql(
if (prebuilt->pcur->btr_cur.index == clust_index) {
btr_pcur_copy_stored_position(node->pcur, prebuilt->pcur);
} else {
- btr_pcur_copy_stored_position(node->pcur, prebuilt->clust_pcur);
+ btr_pcur_copy_stored_position(node->pcur,
+ prebuilt->clust_pcur);
}
ut_a(node->pcur->rel_pos == BTR_PCUR_ON);
@@ -954,7 +978,7 @@ run_again:
if (err == DB_RECORD_NOT_FOUND) {
trx->error_state = DB_SUCCESS;
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -965,7 +989,7 @@ run_again:
goto run_again;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
@@ -984,7 +1008,7 @@ run_again:
row_update_statistics_if_needed(prebuilt->table);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -1024,7 +1048,9 @@ run_again:
srv_suspend_mysql_thread(thr);
- /* Note that a lock wait may also end in a lock wait timeout */
+ /* Note that a lock wait may also end in a lock wait timeout,
+ or this transaction is picked as a victim in selective
+ deadlock resolution */
if (trx->error_state != DB_SUCCESS) {
@@ -1135,7 +1161,7 @@ row_mysql_recover_tmp_table(
return(DB_ERROR);
}
- if (0 == ut_memcmp(ptr, "/rsql", 5)) {
+ if (0 == ut_memcmp(ptr, (char*)"/rsql", 5)) {
ptr++;
*ptr = '#';
@@ -1152,32 +1178,73 @@ row_mysql_recover_tmp_table(
}
/*************************************************************************
-Locks the data dictionary exclusively for performing a table create
-operation. */
+Locks the data dictionary in shared mode from modifications, for performing
+foreign key check, rollback, or other operation invisible to MySQL. */
+
+void
+row_mysql_freeze_data_dictionary(
+/*=============================*/
+ trx_t* trx) /* in: transaction */
+{
+ ut_a(trx->dict_operation_lock_mode == 0);
+
+ rw_lock_s_lock(&dict_operation_lock);
+
+ trx->dict_operation_lock_mode = RW_S_LATCH;
+}
+
+/*************************************************************************
+Unlocks the data dictionary shared lock. */
void
-row_mysql_lock_data_dictionary(void)
-/*================================*/
+row_mysql_unfreeze_data_dictionary(
+/*===============================*/
+ trx_t* trx) /* in: transaction */
+{
+ ut_a(trx->dict_operation_lock_mode == RW_S_LATCH);
+
+ rw_lock_s_unlock(&dict_operation_lock);
+
+ trx->dict_operation_lock_mode = 0;
+}
+
+/*************************************************************************
+Locks the data dictionary exclusively for performing a table create or other
+data dictionary modification operation. */
+
+void
+row_mysql_lock_data_dictionary(
+/*===========================*/
+ trx_t* trx) /* in: transaction */
{
+ ut_a(trx->dict_operation_lock_mode == 0);
+
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks or lock waits can occur then in these operations */
- rw_lock_x_lock(&(dict_foreign_key_check_lock));
+ rw_lock_x_lock(&dict_operation_lock);
+ trx->dict_operation_lock_mode = RW_X_LATCH;
+
mutex_enter(&(dict_sys->mutex));
}
/*************************************************************************
-Unlocks the data dictionary exclusively lock. */
+Unlocks the data dictionary exclusive lock. */
void
-row_mysql_unlock_data_dictionary(void)
-/*==================================*/
+row_mysql_unlock_data_dictionary(
+/*=============================*/
+ trx_t* trx) /* in: transaction */
{
+ ut_a(trx->dict_operation_lock_mode == RW_X_LATCH);
+
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
mutex_exit(&(dict_sys->mutex));
- rw_lock_x_unlock(&(dict_foreign_key_check_lock));
+ rw_lock_x_unlock(&dict_operation_lock);
+
+ trx->dict_operation_lock_mode = 0;
}
/*************************************************************************
@@ -1200,13 +1267,10 @@ row_create_table_for_mysql(
ulint err;
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
+ ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
+ ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
ut_ad(mutex_own(&(dict_sys->mutex)));
- /* We allow a create table also if innodb_force_recovery is used. This
- enables the user to stop a runaway rollback or a crash caused by
- a temporary table #sql... He can use the trick explained in the
- manual to rename the temporary table to rsql..., and then drop it. */
-
if (srv_created_new_raw) {
fprintf(stderr,
"InnoDB: A new raw disk partition was initialized or\n"
@@ -1220,11 +1284,11 @@ row_create_table_for_mysql(
return(DB_ERROR);
}
- trx->op_info = "creating table";
-
- if (0 == ut_strcmp(table->name, "mysql/host")
- || 0 == ut_strcmp(table->name, "mysql/user")
- || 0 == ut_strcmp(table->name, "mysql/db")) {
+ trx->op_info = (char *) "creating table";
+
+ if (0 == ut_strcmp(table->name, (char*)"mysql/host")
+ || 0 == ut_strcmp(table->name, (char*)"mysql/user")
+ || 0 == ut_strcmp(table->name, (char*)"mysql/db")) {
fprintf(stderr,
"InnoDB: Error: trying to create a MySQL system table %s of type InnoDB.\n"
@@ -1244,7 +1308,7 @@ row_create_table_for_mysql(
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
- "_recover_innodb_tmp_table", keywordlen)) {
+ (char*)"_recover_innodb_tmp_table", keywordlen)) {
/* MySQL prevents accessing of tables whose name begins
with #sql, that is temporary tables. If mysqld crashes in
@@ -1258,11 +1322,11 @@ row_create_table_for_mysql(
namelen = ut_strlen(table->name);
- keywordlen = ut_strlen("innodb_monitor");
+ keywordlen = ut_strlen((char *) "innodb_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
- "innodb_monitor", keywordlen)) {
+ (char *) "innodb_monitor", keywordlen)) {
/* Table name ends to characters innodb_monitor:
start monitor prints */
@@ -1275,32 +1339,34 @@ row_create_table_for_mysql(
os_event_set(srv_lock_timeout_thread_event);
}
- keywordlen = ut_strlen("innodb_lock_monitor");
+ keywordlen = ut_strlen((char *) "innodb_lock_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
- "innodb_lock_monitor", keywordlen)) {
+ (char *) "innodb_lock_monitor", keywordlen)) {
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
os_event_set(srv_lock_timeout_thread_event);
}
- keywordlen = ut_strlen("innodb_tablespace_monitor");
+ keywordlen = ut_strlen((char *) "innodb_tablespace_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
- "innodb_tablespace_monitor", keywordlen)) {
+ (char *) "innodb_tablespace_monitor",
+ keywordlen)) {
srv_print_innodb_tablespace_monitor = TRUE;
os_event_set(srv_lock_timeout_thread_event);
}
- keywordlen = ut_strlen("innodb_table_monitor");
+ keywordlen = ut_strlen((char *) "innodb_table_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
- "innodb_table_monitor", keywordlen)) {
+ (char *) "innodb_table_monitor",
+ keywordlen)) {
srv_print_innodb_table_monitor = TRUE;
os_event_set(srv_lock_timeout_thread_event);
@@ -1310,7 +1376,7 @@ row_create_table_for_mysql(
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
- "innodb_mem_validate", keywordlen)) {
+ (char*)"innodb_mem_validate", keywordlen)) {
/* We define here a debugging feature intended for
developers */
@@ -1351,7 +1417,7 @@ row_create_table_for_mysql(
fprintf(stderr,
"InnoDB: Warning: cannot create table %s because tablespace full\n",
table->name);
- row_drop_table_for_mysql(table->name, trx, TRUE);
+ row_drop_table_for_mysql(table->name, trx);
} else {
ut_a(err == DB_DUPLICATE_KEY);
@@ -1379,7 +1445,7 @@ row_create_table_for_mysql(
que_graph_free((que_t*) que_node_get_parent(thr));
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -1402,43 +1468,31 @@ row_create_index_for_mysql(
ulint namelen;
ulint keywordlen;
ulint err;
- ulint i;
- ulint j;
+ ulint i, j;
+ ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
ut_ad(mutex_own(&(dict_sys->mutex)));
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
trx->op_info = (char *) "creating index";
- trx_start_if_not_started(trx);
-
- namelen = ut_strlen(index->table_name);
-
- keywordlen = ut_strlen("_recover_innodb_tmp_table");
-
- if (namelen >= keywordlen
- && 0 == ut_memcmp(
- index->table_name + namelen - keywordlen,
- "_recover_innodb_tmp_table", keywordlen)) {
-
- return(DB_SUCCESS);
- }
-
/* Check that the same column does not appear twice in the index.
- InnoDB assumes this in its algorithms, e.g., update of an index
- entry */
+ Starting from 4.0.14 InnoDB should be able to cope with that, but
+ safer not to allow them. */
for (i = 0; i < dict_index_get_n_fields(index); i++) {
for (j = 0; j < i; j++) {
if (0 == ut_strcmp(
- dict_index_get_nth_field(index, j)->name,
- dict_index_get_nth_field(index, i)->name)) {
+ dict_index_get_nth_field(index, j)->name,
+ dict_index_get_nth_field(index, i)->name)) {
+
+ ut_print_timestamp(stderr);
fprintf(stderr,
-"InnoDB: Error: column %s appears twice in index %s\n"
+" InnoDB: Error: column %s appears twice in index %s of table %s\n"
"InnoDB: This is not allowed in InnoDB.\n",
dict_index_get_nth_field(index, i)->name,
- index->name);
+ index->name, index->table_name);
err = DB_COL_APPEARS_TWICE_IN_INDEX;
@@ -1447,6 +1501,20 @@ row_create_index_for_mysql(
}
}
+ trx_start_if_not_started(trx);
+
+ namelen = ut_strlen(index->table_name);
+
+ keywordlen = ut_strlen("_recover_innodb_tmp_table");
+
+ if (namelen >= keywordlen
+ && 0 == ut_memcmp(
+ index->table_name + namelen - keywordlen,
+ (char*)"_recover_innodb_tmp_table", keywordlen)) {
+
+ return(DB_SUCCESS);
+ }
+
heap = mem_heap_create(512);
trx->dict_operation = TRUE;
@@ -1464,6 +1532,7 @@ row_create_index_for_mysql(
que_graph_free((que_t*) que_node_get_parent(thr));
error_handling:
+
if (err != DB_SUCCESS) {
/* We have special error handling here */
@@ -1471,7 +1540,7 @@ error_handling:
trx_general_rollback_for_mysql(trx, FALSE, NULL);
- row_drop_table_for_mysql(index->table_name, trx, TRUE);
+ row_drop_table_for_mysql(index->table_name, trx);
trx->error_state = DB_SUCCESS;
}
@@ -1508,9 +1577,10 @@ row_table_add_foreign_constraints(
ulint err;
ut_ad(mutex_own(&(dict_sys->mutex)));
+ ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
ut_a(sql_string);
- trx->op_info = "adding foreign keys";
+ trx->op_info = (char *) "adding foreign keys";
trx_start_if_not_started(trx);
@@ -1521,7 +1591,7 @@ row_table_add_foreign_constraints(
if (namelen >= keywordlen
&& 0 == ut_memcmp(
name + namelen - keywordlen,
- "_recover_innodb_tmp_table", keywordlen)) {
+ (char*)"_recover_innodb_tmp_table", keywordlen)) {
return(DB_SUCCESS);
}
@@ -1542,7 +1612,7 @@ row_table_add_foreign_constraints(
trx_general_rollback_for_mysql(trx, FALSE, NULL);
- row_drop_table_for_mysql(name, trx, TRUE);
+ row_drop_table_for_mysql(name, trx);
trx->error_state = DB_SUCCESS;
}
@@ -1573,7 +1643,7 @@ row_drop_table_for_mysql_in_background(
name); */
/* Drop the table in InnoDB */
- error = row_drop_table_for_mysql(name, trx, FALSE);
+ error = row_drop_table_for_mysql(name, trx);
if (error != DB_SUCCESS) {
fprintf(stderr,
@@ -1585,7 +1655,7 @@ row_drop_table_for_mysql_in_background(
the InnoDB data dictionary get out-of-sync if the user runs
with innodb_flush_log_at_trx_commit = 0 */
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
+ log_buffer_flush_to_disk();
trx_commit_for_mysql(trx);
@@ -1732,10 +1802,9 @@ row_drop_table_for_mysql(
/*=====================*/
/* out: error code or DB_SUCCESS */
char* name, /* in: table name */
- trx_t* trx, /* in: transaction handle */
- ibool has_dict_mutex) /* in: TRUE if the caller already owns the
- dictionary system mutex */
+ trx_t* trx) /* in: transaction handle */
{
+ dict_foreign_t* foreign;
dict_table_t* table;
que_thr_t* thr;
que_t* graph;
@@ -1745,18 +1814,12 @@ row_drop_table_for_mysql(
ulint len;
ulint namelen;
ulint keywordlen;
- ulint rounds = 0;
+ ibool locked_dictionary = FALSE;
char buf[10000];
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
ut_a(name != NULL);
- /* Note that we allow dropping of a table even if innodb_force_recovery
- is used. If a rollback or purge would crash because of a corrupt
- table, the user can try dropping it to avoid the crash. This is also
- a nice way to stop a runaway rollback caused by a failing big
- table import in a single transaction. */
-
if (srv_created_new_raw) {
fprintf(stderr,
"InnoDB: A new raw disk partition was initialized or\n"
@@ -1768,16 +1831,16 @@ row_drop_table_for_mysql(
return(DB_ERROR);
}
- trx->op_info = "dropping table";
+ trx->op_info = (char *) "dropping table";
trx_start_if_not_started(trx);
namelen = ut_strlen(name);
- keywordlen = ut_strlen("innodb_monitor");
+ keywordlen = ut_strlen((char *) "innodb_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(name + namelen - keywordlen,
- "innodb_monitor", keywordlen)) {
+ (char *) "innodb_monitor", keywordlen)) {
/* Table name ends to characters innodb_monitor:
stop monitor prints */
@@ -1786,30 +1849,33 @@ row_drop_table_for_mysql(
srv_print_innodb_lock_monitor = FALSE;
}
- keywordlen = ut_strlen("innodb_lock_monitor");
+ keywordlen = ut_strlen((char *) "innodb_lock_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(name + namelen - keywordlen,
- "innodb_lock_monitor", keywordlen)) {
+ (char *) "innodb_lock_monitor",
+ keywordlen)) {
srv_print_innodb_monitor = FALSE;
srv_print_innodb_lock_monitor = FALSE;
}
- keywordlen = ut_strlen("innodb_tablespace_monitor");
+ keywordlen = ut_strlen((char *) "innodb_tablespace_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(name + namelen - keywordlen,
- "innodb_tablespace_monitor", keywordlen)) {
+ (char *) "innodb_tablespace_monitor",
+ keywordlen)) {
srv_print_innodb_tablespace_monitor = FALSE;
}
- keywordlen = ut_strlen("innodb_table_monitor");
+ keywordlen = ut_strlen((char *) "innodb_table_monitor");
if (namelen >= keywordlen
&& 0 == ut_memcmp(name + namelen - keywordlen,
- "innodb_table_monitor", keywordlen)) {
+ (char *) "innodb_table_monitor",
+ keywordlen)) {
srv_print_innodb_table_monitor = FALSE;
}
@@ -1819,7 +1885,7 @@ row_drop_table_for_mysql(
tables in Innobase. Deleting a row from SYS_INDEXES table also
frees the file segments of the B-tree associated with the index. */
- str1 =
+ str1 = (char *)
"PROCEDURE DROP_TABLE_PROC () IS\n"
"table_name CHAR;\n"
"sys_foreign_id CHAR;\n"
@@ -1830,7 +1896,7 @@ row_drop_table_for_mysql(
"BEGIN\n"
"table_name := '";
- str2 =
+ str2 = (char *)
"';\n"
"SELECT ID INTO table_id\n"
"FROM SYS_TABLES\n"
@@ -1872,7 +1938,8 @@ row_drop_table_for_mysql(
" found := 0;\n"
" ELSE"
" DELETE FROM SYS_FIELDS WHERE INDEX_ID = index_id;\n"
- " DELETE FROM SYS_INDEXES WHERE ID = index_id;\n"
+ " DELETE FROM SYS_INDEXES WHERE ID = index_id\n"
+ " AND TABLE_ID = table_id;\n"
" END IF;\n"
"END LOOP;\n"
"DELETE FROM SYS_COLUMNS WHERE TABLE_ID = table_id;\n"
@@ -1892,13 +1959,18 @@ row_drop_table_for_mysql(
/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */
- if (!has_dict_mutex) {
- /* Prevent foreign key checks while we are dropping the table */
- rw_lock_x_lock(&(dict_foreign_key_check_lock));
+ if (trx->dict_operation_lock_mode != RW_X_LATCH) {
+ /* Prevent foreign key checks etc. while we are dropping the
+ table */
- mutex_enter(&(dict_sys->mutex));
+ row_mysql_lock_data_dictionary(trx);
+
+ locked_dictionary = TRUE;
}
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+ ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
+
graph = pars_sql(buf);
ut_a(graph);
@@ -1908,9 +1980,6 @@ row_drop_table_for_mysql(
graph->fork_type = QUE_FORK_MYSQL_INTERFACE;
- /* Prevent purge from running while we are dropping the table */
- rw_lock_s_lock(&(purge_sys->purge_is_running));
-
table = dict_table_get_low(name);
if (!table) {
@@ -1928,6 +1997,31 @@ row_drop_table_for_mysql(
goto funct_exit;
}
+ foreign = UT_LIST_GET_FIRST(table->referenced_list);
+
+ if (foreign && trx->check_foreigns) {
+ char* buf = dict_foreign_err_buf;
+
+ /* We only allow dropping a referenced table if
+ FOREIGN_KEY_CHECKS is set to 0 */
+
+ err = DB_CANNOT_DROP_CONSTRAINT;
+
+ mutex_enter(&dict_foreign_err_mutex);
+ ut_sprintf_timestamp(buf);
+
+ sprintf(buf + strlen(buf),
+ " Cannot drop table %.500s\n", name);
+ sprintf(buf + strlen(buf),
+"because it is referenced by %.500s\n", foreign->foreign_table_name);
+
+ ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
+
+ mutex_exit(&dict_foreign_err_mutex);
+
+ goto funct_exit;
+ }
+
if (table->n_mysql_handles_opened > 0) {
ut_print_timestamp(stderr);
@@ -1991,19 +2085,17 @@ row_drop_table_for_mysql(
}
}
-funct_exit:
- rw_lock_s_unlock(&(purge_sys->purge_is_running));
+funct_exit:
- if (!has_dict_mutex) {
- mutex_exit(&(dict_sys->mutex));
- rw_lock_x_unlock(&(dict_foreign_key_check_lock));
+ if (locked_dictionary) {
+ row_mysql_unlock_data_dictionary(trx);
}
que_graph_free(graph);
trx_commit_for_mysql(trx);
- trx->op_info = "";
+ trx->op_info = (char *) "";
srv_wake_master_thread();
@@ -2028,14 +2120,13 @@ row_drop_database_for_mysql(
ut_a(name != NULL);
ut_a(name[strlen(name) - 1] == '/');
- trx->op_info = "dropping database";
+ trx->op_info = (char *) "dropping database";
trx_start_if_not_started(trx);
loop:
- rw_lock_x_lock(&(dict_foreign_key_check_lock));
- mutex_enter(&(dict_sys->mutex));
+ row_mysql_lock_data_dictionary(trx);
- while (table_name = dict_get_first_table_name_in_db(name)) {
+ while ((table_name = dict_get_first_table_name_in_db(name))) {
ut_a(memcmp(table_name, name, strlen(name)) == 0);
table = dict_table_get_low(table_name);
@@ -2046,8 +2137,7 @@ loop:
the table */
if (table->n_mysql_handles_opened > 0) {
- mutex_exit(&(dict_sys->mutex));
- rw_lock_x_unlock(&(dict_foreign_key_check_lock));
+ row_mysql_unlock_data_dictionary(trx);
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -2062,7 +2152,7 @@ loop:
goto loop;
}
- err = row_drop_table_for_mysql(table_name, trx, TRUE);
+ err = row_drop_table_for_mysql(table_name, trx);
mem_free(table_name);
@@ -2074,12 +2164,11 @@ loop:
}
}
- mutex_exit(&(dict_sys->mutex));
- rw_lock_x_unlock(&(dict_foreign_key_check_lock));
+ row_mysql_unlock_data_dictionary(trx);
trx_commit_for_mysql(trx);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
@@ -2097,7 +2186,7 @@ row_is_mysql_tmp_table_name(
ulint i;
for (i = 0; i <= ut_strlen(name) - 5; i++) {
- if (ut_memcmp(name + i, "/#sql", 5) == 0) {
+ if (ut_memcmp(name + i, (char*)"/#sql", 5) == 0) {
return(TRUE);
}
@@ -2119,12 +2208,19 @@ row_rename_table_for_mysql(
{
dict_table_t* table;
que_thr_t* thr;
- que_t* graph;
+ que_t* graph = NULL;
ulint err;
char* str1;
char* str2;
char* str3;
+ mem_heap_t* heap = NULL;
+ char** constraints_to_drop = NULL;
+ ulint n_constraints_to_drop = 0;
+ ibool recovering_temp_table = FALSE;
+ ulint namelen;
+ ulint keywordlen;
ulint len;
+ ulint i;
char buf[10000];
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
@@ -2142,10 +2238,10 @@ row_rename_table_for_mysql(
trx_commit_for_mysql(trx);
return(DB_ERROR);
}
-
- if (0 == ut_strcmp(new_name, "mysql/host")
- || 0 == ut_strcmp(new_name, "mysql/user")
- || 0 == ut_strcmp(new_name, "mysql/db")) {
+
+ if (0 == ut_strcmp(new_name, (char*)"mysql/host")
+ || 0 == ut_strcmp(new_name, (char*)"mysql/user")
+ || 0 == ut_strcmp(new_name, (char*)"mysql/db")) {
fprintf(stderr,
"InnoDB: Error: trying to create a MySQL system table %s of type InnoDB.\n"
@@ -2156,31 +2252,86 @@ row_rename_table_for_mysql(
return(DB_ERROR);
}
- trx->op_info = "renaming table";
+ trx->op_info = (char *) "renaming table";
trx_start_if_not_started(trx);
- str1 =
+ namelen = ut_strlen(new_name);
+
+ keywordlen = ut_strlen("_recover_innodb_tmp_table");
+
+ if (namelen >= keywordlen
+ && 0 == ut_memcmp(new_name + namelen - keywordlen,
+ (char*)"_recover_innodb_tmp_table", keywordlen)) {
+
+ recovering_temp_table = TRUE;
+ }
+
+ /* Serialize data dictionary operations with dictionary mutex:
+ no deadlocks can occur then in these operations */
+
+ if (!recovering_temp_table) {
+ row_mysql_lock_data_dictionary(trx);
+ }
+
+ table = dict_table_get_low(old_name);
+
+ if (!table) {
+ err = DB_TABLE_NOT_FOUND;
+
+ goto funct_exit;
+ }
+
+ str1 = (char *)
"PROCEDURE RENAME_TABLE_PROC () IS\n"
"new_table_name CHAR;\n"
"old_table_name CHAR;\n"
"BEGIN\n"
"new_table_name :='";
- str2 =
+ str2 = (char *)
"';\nold_table_name := '";
if (row_is_mysql_tmp_table_name(new_name)) {
- /* We want to preserve the original foreign key
- constraint definitions despite the name change */
+ /* MySQL is doing an ALTER TABLE command and it renames the
+ original table to a temporary table name. We want to preserve
+ the original foreign key constraint definitions despite the
+ name change. An exception is those constraints for which
+ the ALTER TABLE contained DROP FOREIGN KEY <foreign key id>.*/
- str3 =
- "';\n"
- "UPDATE SYS_TABLES SET NAME = new_table_name\n"
- "WHERE NAME = old_table_name;\n"
- "END;\n";
+ heap = mem_heap_create(100);
+
+ err = dict_foreign_parse_drop_constraints(heap, trx,
+ table,
+ &n_constraints_to_drop,
+ &constraints_to_drop);
+ if (err != DB_SUCCESS) {
+
+ goto funct_exit;
+ }
+
+ str3 = mem_heap_alloc(heap,
+ 1000 + 500 * n_constraints_to_drop);
+ *str3 = '\0';
+ sprintf(str3,
+ "';\n"
+ "UPDATE SYS_TABLES SET NAME = new_table_name\n"
+ "WHERE NAME = old_table_name;\n");
+
+ for (i = 0; i < n_constraints_to_drop; i++) {
+ sprintf(str3 + strlen(str3),
+ "DELETE FROM SYS_FOREIGN_COLS WHERE ID = '%s';\n"
+ "DELETE FROM SYS_FOREIGN WHERE ID = '%s';\n",
+ constraints_to_drop[i],
+ constraints_to_drop[i]);
+ }
+
+ sprintf(str3 + strlen(str3),
+ "END;\n");
+
+ ut_a(strlen(str3) < 1000 + 500 * n_constraints_to_drop);
} else {
- str3 =
+ str3 = (char*)
"';\n"
"UPDATE SYS_TABLES SET NAME = new_table_name\n"
"WHERE NAME = old_table_name;\n"
@@ -2209,14 +2360,6 @@ row_rename_table_for_mysql(
ut_memcpy(buf + len, str3, ut_strlen(str3) + 1);
- /* Serialize data dictionary operations with dictionary mutex:
- no deadlocks can occur then in these operations */
-
- rw_lock_x_lock(&(dict_foreign_key_check_lock));
- mutex_enter(&(dict_sys->mutex));
-
- table = dict_table_get_low(old_name);
-
graph = pars_sql(buf);
ut_a(graph);
@@ -2226,12 +2369,6 @@ row_rename_table_for_mysql(
graph->fork_type = QUE_FORK_MYSQL_INTERFACE;
- if (!table) {
- err = DB_TABLE_NOT_FOUND;
-
- goto funct_exit;
- }
-
ut_a(thr = que_fork_start_command(graph, SESS_COMM_EXECUTE, 0));
que_run_threads(thr);
@@ -2272,6 +2409,13 @@ row_rename_table_for_mysql(
if (row_is_mysql_tmp_table_name(old_name)) {
+ /* MySQL is doing an ALTER TABLE command and it
+ renames the created temporary table to the name
+ of the original table. In the ALTER TABLE we maybe
+ created some FOREIGN KEY constraints for the temporary
+ table. But we want to load also the foreign key
+ constraint definitions for the original table name. */
+
err = dict_load_foreigns(new_name);
if (err != DB_SUCCESS) {
@@ -2294,15 +2438,22 @@ row_rename_table_for_mysql(
}
}
}
-funct_exit:
- mutex_exit(&(dict_sys->mutex));
- rw_lock_x_unlock(&(dict_foreign_key_check_lock));
+funct_exit:
+ if (!recovering_temp_table) {
+ row_mysql_unlock_data_dictionary(trx);
+ }
- que_graph_free(graph);
+ if (graph) {
+ que_graph_free(graph);
+ }
+
+ if (heap) {
+ mem_heap_free(heap);
+ }
trx_commit_for_mysql(trx);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return((int) err);
}
@@ -2426,7 +2577,7 @@ loop:
prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
- ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, ROW_SEL_NEXT);
+ ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, ROW_SEL_NEXT);
goto loop;
}
@@ -2441,18 +2592,28 @@ row_check_table_for_mysql(
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
handle */
{
- dict_table_t* table = prebuilt->table;
+ dict_table_t* table = prebuilt->table;
dict_index_t* index;
ulint n_rows;
ulint n_rows_in_table = ULINT_UNDEFINED;
- ulint ret = DB_SUCCESS;
+ ulint ret = DB_SUCCESS;
+ ulint old_isolation_level;
+
+ prebuilt->trx->op_info = (char *) "checking table";
+
+ old_isolation_level = prebuilt->trx->isolation_level;
- prebuilt->trx->op_info = "checking table";
+ /* We must run the index record counts at an isolation level
+ >= READ COMMITTED, because a dirty read can see a wrong number
+ of records in some index; to play safe, we use always
+ REPEATABLE READ here */
+ prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ;
+
index = dict_table_get_first_index(table);
while (index != NULL) {
- /* fprintf(stderr, "Validating index %s\n", index->name); */
+ /* fprintf(stderr, "Validating index %s\n", index->name); */
if (!btr_validate_tree(index->tree)) {
ret = DB_ERROR;
@@ -2480,6 +2641,9 @@ row_check_table_for_mysql(
index = dict_table_get_next_index(index);
}
+ /* Restore the original isolation level */
+ prebuilt->trx->isolation_level = old_isolation_level;
+
/* We validate also the whole adaptive hash index for all tables
at every CHECK TABLE */
@@ -2488,7 +2652,7 @@ row_check_table_for_mysql(
ret = DB_ERROR;
}
- prebuilt->trx->op_info = "";
+ prebuilt->trx->op_info = (char *) "";
return(ret);
}
diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c
index d24b296ec50..104d71eda2d 100644
--- a/innobase/row/row0purge.c
+++ b/innobase/row/row0purge.c
@@ -24,6 +24,7 @@ Created 3/14/1997 Heikki Tuuri
#include "row0row.h"
#include "row0upd.h"
#include "row0vers.h"
+#include "row0mysql.h"
#include "log0log.h"
/************************************************************************
@@ -204,7 +205,7 @@ row_purge_remove_sec_if_poss_low(
btr_pcur_t pcur;
btr_cur_t* btr_cur;
ibool success;
- ibool old_has;
+ ibool old_has = 0; /* remove warning */
ibool found;
ulint err;
mtr_t mtr;
@@ -429,6 +430,15 @@ skip_secondaries:
mtr_x_lock(dict_tree_get_lock(index->tree), &mtr);
+ /* NOTE: we must also acquire an X-latch to the
+ root page of the tree. We will need it when we
+ free pages from the tree. If the tree is of height 1,
+ the tree X-latch does NOT protect the root page,
+ because it is also a leaf page. Since we will have a
+ latch on an undo log page, we would break the
+ latching order if we would only later latch the
+ root page of such a tree! */
+
btr_root_get(index->tree, &mtr);
/* We assume in purge of externally stored fields
@@ -455,7 +465,9 @@ static
ibool
row_purge_parse_undo_rec(
/*=====================*/
- /* out: TRUE if purge operation required */
+ /* out: TRUE if purge operation required:
+ NOTE that then the CALLER must unfreeze
+ data dictionary! */
purge_node_t* node, /* in: row undo node */
ibool* updated_extern,
/* out: TRUE if an externally stored field
@@ -464,6 +476,7 @@ row_purge_parse_undo_rec(
{
dict_index_t* clust_index;
byte* ptr;
+ trx_t* trx;
dulint undo_no;
dulint table_id;
dulint trx_id;
@@ -473,6 +486,8 @@ row_purge_parse_undo_rec(
ulint cmpl_info;
ut_ad(node && thr);
+
+ trx = thr_get_trx(thr);
ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &cmpl_info,
updated_extern, &undo_no, &table_id);
@@ -495,18 +510,21 @@ row_purge_parse_undo_rec(
return(FALSE);
}
- mutex_enter(&(dict_sys->mutex));
+ /* Prevent DROP TABLE etc. from running when we are doing the purge
+ for this row */
- node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr));
+ row_mysql_freeze_data_dictionary(trx);
- rw_lock_x_lock(&(purge_sys->purge_is_running));
+ mutex_enter(&(dict_sys->mutex));
- mutex_exit(&(dict_sys->mutex));
+ node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr));
+ mutex_exit(&(dict_sys->mutex));
+
if (node->table == NULL) {
/* The table has been dropped: no need to do purge */
- rw_lock_x_unlock(&(purge_sys->purge_is_running));
+ row_mysql_unfreeze_data_dictionary(trx);
return(FALSE);
}
@@ -516,7 +534,7 @@ row_purge_parse_undo_rec(
if (clust_index == NULL) {
/* The table was corrupt in the data dictionary */
- rw_lock_x_unlock(&(purge_sys->purge_is_running));
+ row_mysql_unfreeze_data_dictionary(trx);
return(FALSE);
}
@@ -554,9 +572,12 @@ row_purge(
dulint roll_ptr;
ibool purge_needed;
ibool updated_extern;
+ trx_t* trx;
ut_ad(node && thr);
+ trx = thr_get_trx(thr);
+
node->undo_rec = trx_purge_fetch_next_rec(&roll_ptr,
&(node->reservation),
node->heap);
@@ -575,6 +596,8 @@ row_purge(
} else {
purge_needed = row_purge_parse_undo_rec(node, &updated_extern,
thr);
+ /* If purge_needed == TRUE, we must also remember to unfreeze
+ data dictionary! */
}
if (purge_needed) {
@@ -596,7 +619,7 @@ row_purge(
btr_pcur_close(&(node->pcur));
}
- rw_lock_x_unlock(&(purge_sys->purge_is_running));
+ row_mysql_unfreeze_data_dictionary(trx);
}
/* Do some cleanup */
diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c
index 40a775143f4..6c0c6c04cd5 100644
--- a/innobase/row/row0row.c
+++ b/innobase/row/row0row.c
@@ -136,7 +136,14 @@ row_build_index_entry(
dfield2 = dtuple_get_nth_field(row, dict_col_get_no(col));
dfield_copy(dfield, dfield2);
- dfield->col_no = dict_col_get_no(col);
+
+ /* If a column prefix index, take only the prefix */
+ if (ind_field->prefix_len > 0
+ && dfield_get_len(dfield2) != UNIV_SQL_NULL
+ && dfield_get_len(dfield2) > ind_field->prefix_len) {
+
+ dfield_set_len(dfield, ind_field->prefix_len);
+ }
}
ut_ad(dtuple_check_typed(entry));
@@ -146,8 +153,7 @@ row_build_index_entry(
/***********************************************************************
An inverse function to dict_row_build_index_entry. Builds a row from a
-record in a clustered index. NOTE that externally stored (often big)
-fields are always copied to heap. */
+record in a clustered index. */
dtuple_t*
row_build(
@@ -172,6 +178,7 @@ row_build(
{
dtuple_t* row;
dict_table_t* table;
+ dict_field_t* ind_field;
dict_col_t* col;
dfield_t* dfield;
ulint n_fields;
@@ -204,19 +211,24 @@ row_build(
dict_table_copy_types(row, table);
for (i = 0; i < n_fields; i++) {
+ ind_field = dict_index_get_nth_field(index, i);
- col = dict_field_get_col(dict_index_get_nth_field(index, i));
- dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- field = rec_get_nth_field(rec, i, &len);
+ if (ind_field->prefix_len == 0) {
- if (type == ROW_COPY_ALSO_EXTERNALS
- && rec_get_nth_field_extern_bit(rec, i)) {
+ col = dict_field_get_col(ind_field);
+ dfield = dtuple_get_nth_field(row,
+ dict_col_get_no(col));
+ field = rec_get_nth_field(rec, i, &len);
- field = btr_rec_copy_externally_stored_field(rec,
- i, &len, heap);
- }
+ if (type == ROW_COPY_ALSO_EXTERNALS
+ && rec_get_nth_field_extern_bit(rec, i)) {
- dfield_set_data(dfield, field, len);
+ field = btr_rec_copy_externally_stored_field(
+ rec, i, &len, heap);
+ }
+
+ dfield_set_data(dfield, field, len);
+ }
}
ut_ad(dtuple_check_typed(row));
@@ -371,7 +383,6 @@ row_build_row_ref(
dict_table_t* table;
dict_index_t* clust_index;
dfield_t* dfield;
- dict_col_t* col;
dtuple_t* ref;
byte* field;
ulint len;
@@ -403,24 +414,13 @@ row_build_row_ref(
for (i = 0; i < ref_len; i++) {
dfield = dtuple_get_nth_field(ref, i);
- col = dict_field_get_col(
- dict_index_get_nth_field(clust_index, i));
- pos = dict_index_get_nth_col_pos(index, dict_col_get_no(col));
+ pos = dict_index_get_nth_field_pos(index, clust_index, i);
- if (pos != ULINT_UNDEFINED) {
- field = rec_get_nth_field(rec, pos, &len);
+ ut_a(pos != ULINT_UNDEFINED);
+
+ field = rec_get_nth_field(rec, pos, &len);
- dfield_set_data(dfield, field, len);
- } else {
- ut_ad(table->type == DICT_TABLE_CLUSTER_MEMBER);
- ut_ad(i == table->mix_len);
-
- dfield_set_data(dfield,
- mem_heap_alloc(heap, table->mix_id_len),
- table->mix_id_len);
- ut_memcpy(dfield_get_data(dfield), table->mix_id_buf,
- table->mix_id_len);
- }
+ dfield_set_data(dfield, field, len);
}
ut_ad(dtuple_check_typed(ref));
@@ -448,7 +448,6 @@ row_build_row_ref_in_tuple(
dict_table_t* table;
dict_index_t* clust_index;
dfield_t* dfield;
- dict_col_t* col;
byte* field;
ulint len;
ulint ref_len;
@@ -483,19 +482,13 @@ row_build_row_ref_in_tuple(
for (i = 0; i < ref_len; i++) {
dfield = dtuple_get_nth_field(ref, i);
- col = dict_field_get_col(
- dict_index_get_nth_field(clust_index, i));
- pos = dict_index_get_nth_col_pos(index, dict_col_get_no(col));
+ pos = dict_index_get_nth_field_pos(index, clust_index, i);
- if (pos != ULINT_UNDEFINED) {
- field = rec_get_nth_field(rec, pos, &len);
+ ut_a(pos != ULINT_UNDEFINED);
+
+ field = rec_get_nth_field(rec, pos, &len);
- dfield_set_data(dfield, field, len);
- } else {
- ut_ad(table->type == DICT_TABLE_CLUSTER_MEMBER);
- ut_ad(i == table->mix_len);
- ut_a(0);
- }
+ dfield_set_data(dfield, field, len);
}
ut_ad(dtuple_check_typed(ref));
@@ -517,6 +510,7 @@ row_build_row_ref_from_row(
directly into data of this row */
{
dict_index_t* clust_index;
+ dict_field_t* field;
dfield_t* dfield;
dfield_t* dfield2;
dict_col_t* col;
@@ -533,13 +527,21 @@ row_build_row_ref_from_row(
for (i = 0; i < ref_len; i++) {
dfield = dtuple_get_nth_field(ref, i);
-
- col = dict_field_get_col(
- dict_index_get_nth_field(clust_index, i));
-
+
+ field = dict_index_get_nth_field(clust_index, i);
+
+ col = dict_field_get_col(field);
+
dfield2 = dtuple_get_nth_field(row, dict_col_get_no(col));
dfield_copy(dfield, dfield2);
+
+ if (field->prefix_len > 0
+ && dfield->len != UNIV_SQL_NULL
+ && dfield->len > field->prefix_len) {
+
+ dfield->len = field->prefix_len;
+ }
}
ut_ad(dtuple_check_typed(ref));
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index b06476219c6..fce47a8f9af 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -30,6 +30,7 @@ Created 12/19/1997 Heikki Tuuri
#include "pars0sym.h"
#include "pars0pars.h"
#include "row0mysql.h"
+#include "read0read.h"
/* Maximum number of rows to prefetch; MySQL interface has another parameter */
#define SEL_MAX_N_PREFETCH 16
@@ -50,7 +51,8 @@ to que_run_threads: this is to allow canceling runaway queries */
/************************************************************************
Returns TRUE if the user-defined column values in a secondary index record
-are the same as the corresponding columns in the clustered index record.
+are alphabetically the same as the corresponding columns in the clustered
+index record.
NOTE: the comparison is NOT done as a binary comparison, but character
fields are compared with collation! */
static
@@ -66,38 +68,43 @@ row_sel_sec_rec_is_for_clust_rec(
rec_t* clust_rec, /* in: clustered index record */
dict_index_t* clust_index) /* in: clustered index */
{
- dict_col_t* col;
- byte* sec_field;
- ulint sec_len;
- byte* clust_field;
- ulint clust_len;
- ulint n;
- ulint i;
-
- n = dict_index_get_n_ordering_defined_by_user(sec_index);
-
- for (i = 0; i < n; i++) {
- col = dict_field_get_col(
- dict_index_get_nth_field(sec_index, i));
-
- clust_field = rec_get_nth_field(clust_rec,
- dict_col_get_clust_pos(col),
- &clust_len);
- sec_field = rec_get_nth_field(sec_rec, i, &sec_len);
-
- if (sec_len != clust_len) {
-
- return(FALSE);
- }
-
- if (0 != cmp_data_data(dict_col_get_type(col),
- clust_field, clust_len,
- sec_field, sec_len)) {
- return(FALSE);
- }
- }
-
- return(TRUE);
+ dict_field_t* ifield;
+ dict_col_t* col;
+ byte* sec_field;
+ ulint sec_len;
+ byte* clust_field;
+ ulint clust_len;
+ ulint n;
+ ulint i;
+
+ UT_NOT_USED(clust_index);
+
+ n = dict_index_get_n_ordering_defined_by_user(sec_index);
+
+ for (i = 0; i < n; i++) {
+ ifield = dict_index_get_nth_field(sec_index, i);
+ col = dict_field_get_col(ifield);
+
+ clust_field = rec_get_nth_field(clust_rec,
+ dict_col_get_clust_pos(col),
+ &clust_len);
+ sec_field = rec_get_nth_field(sec_rec, i, &sec_len);
+
+ if (ifield->prefix_len > 0
+ && clust_len != UNIV_SQL_NULL
+ && clust_len > ifield->prefix_len) {
+
+ clust_len = ifield->prefix_len;
+ }
+
+ if (0 != cmp_data_data(dict_col_get_type(col),
+ clust_field, clust_len,
+ sec_field, sec_len)) {
+ return(FALSE);
+ }
+ }
+
+ return(TRUE);
}
/*************************************************************************
@@ -598,20 +605,35 @@ row_sel_get_clust_rec(
clust_rec = btr_pcur_get_rec(&(plan->clust_pcur));
+ /* Note: only if the search ends up on a non-infimum record is the
+ low_match value the real match to the search tuple */
+
if (!page_rec_is_user_rec(clust_rec)
|| btr_pcur_get_low_match(&(plan->clust_pcur))
< dict_index_get_n_unique(index)) {
+
+ ut_a(rec_get_deleted_flag(rec));
+ ut_a(node->read_view);
- clust_rec = NULL;
+ /* In a rare case it is possible that no clust rec is found
+ for a delete-marked secondary index record: if in row0umod.c
+ in row_undo_mod_remove_clust_low() we have already removed
+ the clust rec, while purge is still cleaning and removing
+ secondary index records associated with earlier versions of
+ the clustered index record. In that case we know that the
+ clustered index record did not exist in the read view of
+ trx. */
- goto func_exit;
+ clust_rec = NULL;
+
+ goto func_exit;
}
if (!node->read_view) {
/* Try to place a lock on the index record */
err = lock_clust_rec_read_check_and_lock(0, clust_rec, index,
- node->row_lock_mode, thr);
+ node->row_lock_mode, LOCK_ORDINARY, thr);
if (err != DB_SUCCESS) {
return(err);
@@ -626,7 +648,7 @@ row_sel_get_clust_rec(
node->read_view)) {
err = row_sel_build_prev_vers(node->read_view, plan,
- clust_rec, &old_vers, mtr);
+ clust_rec, &old_vers, mtr);
if (err != DB_SUCCESS) {
return(err);
@@ -661,7 +683,7 @@ row_sel_get_clust_rec(
*out_rec = clust_rec;
return(DB_SUCCESS);
- }
+ }
}
/* Fetch the columns needed in test conditions */
@@ -684,16 +706,17 @@ sel_set_rec_lock(
rec_t* rec, /* in: record */
dict_index_t* index, /* in: index */
ulint mode, /* in: lock mode */
+ ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or LOC_REC_NOT_GAP */
que_thr_t* thr) /* in: query thread */
{
ulint err;
if (index->type & DICT_CLUSTERED) {
err = lock_clust_rec_read_check_and_lock(0, rec, index, mode,
- thr);
+ type, thr);
} else {
err = lock_sec_rec_read_check_and_lock(0, rec, index, mode,
- thr);
+ type, thr);
}
return(err);
@@ -1160,7 +1183,7 @@ rec_loop:
if (!consistent_read) {
err = sel_set_rec_lock(page_rec_get_next(rec), index,
- node->row_lock_mode, thr);
+ node->row_lock_mode, LOCK_ORDINARY, thr);
if (err != DB_SUCCESS) {
/* Note that in this case we will store in pcur
the PREDECESSOR of the record we are waiting
@@ -1186,8 +1209,8 @@ rec_loop:
if (!consistent_read) {
/* Try to place a lock on the index record */
- err = sel_set_rec_lock(rec, index, node->row_lock_mode, thr);
-
+ err = sel_set_rec_lock(rec, index, node->row_lock_mode,
+ LOCK_ORDINARY, thr);
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
@@ -1249,6 +1272,8 @@ rec_loop:
/* PHASE 3: Get previous version in a consistent read */
+ cons_read_requires_clust_rec = FALSE;
+
if (consistent_read) {
/* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */
@@ -1855,9 +1880,11 @@ row_printf_step(
}
/********************************************************************
-Converts a key value stored in MySQL format to an Innobase dtuple.
-The last field of the key value may be just a prefix of a fixed length
-field: hence the parameter key_len. */
+Converts a key value stored in MySQL format to an Innobase dtuple. The last
+field of the key value may be just a prefix of a fixed length field: hence
+the parameter key_len. But currently we do not allow search keys where the
+last field is only a prefix of the full key field len and print a warning if
+such appears. */
void
row_sel_convert_mysql_key_to_innobase(
@@ -1868,17 +1895,24 @@ row_sel_convert_mysql_key_to_innobase(
to index! */
byte* buf, /* in: buffer to use in field
conversions */
+ ulint buf_len, /* in: buffer length */
dict_index_t* index, /* in: index of the key value */
byte* key_ptr, /* in: MySQL key value */
ulint key_len) /* in: MySQL key value length */
{
+ byte* original_buf = buf;
+ dict_field_t* field;
dfield_t* dfield;
- ulint offset;
- ulint len;
+ ulint data_offset;
+ ulint data_len;
+ ulint data_field_len;
+ ibool is_null;
byte* key_end;
ulint n_fields = 0;
+ ulint type;
- UT_NOT_USED(index);
+ /* For documentation of the key value storage format in MySQL, see
+ ha_innobase::store_key_val_for_row() in ha_innodb.cc. */
key_end = key_ptr + key_len;
@@ -1887,11 +1921,14 @@ row_sel_convert_mysql_key_to_innobase(
dtuple_set_n_fields(tuple, ULINT_MAX);
dfield = dtuple_get_nth_field(tuple, 0);
+ field = dict_index_get_nth_field(index, 0);
if (dfield_get_type(dfield)->mtype == DATA_SYS) {
- /* A special case: we are looking for a position in a
- generated clustered index: the first and the only
- ordering column is ROW_ID */
+ /* A special case: we are looking for a position in the
+ generated clustered index which InnoDB automatically added
+ to a table with no primary key: the first and the only
+ ordering column is ROW_ID which InnoDB stored to the key_ptr
+ buffer. */
ut_a(key_len == DATA_ROW_ID_LEN);
@@ -1902,58 +1939,114 @@ row_sel_convert_mysql_key_to_innobase(
return;
}
- while (key_ptr < key_end) {
- offset = 0;
- len = dfield_get_type(dfield)->len;
+ while (key_ptr < key_end) {
- n_fields++;
+ ut_a(dict_col_get_type(field->col)->mtype
+ == dfield_get_type(dfield)->mtype);
+
+ data_offset = 0;
+ is_null = FALSE;
if (!(dfield_get_type(dfield)->prtype & DATA_NOT_NULL)) {
/* The first byte in the field tells if this is
an SQL NULL value */
- offset = 1;
+ data_offset = 1;
- if (*key_ptr != 0) {
+ if (*key_ptr != 0) {
dfield_set_data(dfield, NULL, UNIV_SQL_NULL);
- goto next_part;
+ is_null = TRUE;
}
}
- row_mysql_store_col_in_innobase_format(
- dfield, buf, key_ptr + offset, len,
- dfield_get_type(dfield)->mtype,
+ type = dfield_get_type(dfield)->mtype;
+
+ /* Calculate data length and data field total length */
+
+ if (type == DATA_BLOB) {
+ /* The key field is a column prefix of a BLOB or
+ TEXT type column */
+
+ ut_a(field->prefix_len > 0);
+
+ /* MySQL stores the actual data length to the first 2
+ bytes after the optional SQL NULL marker byte. The
+ storage format is little-endian. */
+
+ /* There are no key fields > 255 bytes currently in
+ MySQL */
+ if (key_ptr[data_offset + 1] != 0) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Error: BLOB or TEXT prefix > 255 bytes in query to table %s\n",
+ index->table_name);
+ }
+
+ data_len = key_ptr[data_offset];
+ data_field_len = data_offset + 2 + field->prefix_len;
+ data_offset += 2;
+
+ type = DATA_CHAR; /* now that we know the length, we
+ store the column value like it would
+ be a fixed char field */
+ } else if (field->prefix_len > 0) {
+ data_len = field->prefix_len;
+ data_field_len = data_offset + data_len;
+ } else {
+ data_len = dfield_get_type(dfield)->len;
+ data_field_len = data_offset + data_len;
+ }
+
+ /* Storing may use at most data_len bytes of buf */
+
+ if (!is_null) {
+ row_mysql_store_col_in_innobase_format(
+ dfield, buf, key_ptr + data_offset,
+ data_len, type,
dfield_get_type(dfield)->prtype
& DATA_UNSIGNED);
- next_part:
- key_ptr += (offset + len);
+ buf += data_len;
+ }
+
+ key_ptr += data_field_len;
if (key_ptr > key_end) {
- /* The last field in key was not a complete
- field but a prefix of it */
+ /* The last field in key was not a complete key field
+ but a prefix of it.
+
+ Print a warning about this! HA_READ_PREFIX_LAST does
+ not currently work in InnoDB with partial-field key
+ value prefixes. Since MySQL currently uses a padding
+ trick to calculate LIKE 'abc%' type queries there
+ should never be partial-field prefixes in searches. */
- ut_ad(dfield_get_len(dfield) != UNIV_SQL_NULL);
+ ut_print_timestamp(stderr);
- dfield_set_data(dfield, buf,
- len - (ulint)(key_ptr - key_end));
+ fprintf(stderr,
+ " InnoDB: Warning: using a partial-field key prefix in search\n");
+
+ if (!is_null) {
+ dfield->len -= (ulint)(key_ptr - key_end);
+ }
}
- buf += len;
-
+ n_fields++;
+ field++;
dfield++;
}
- /* We set the length of tuple to n_fields: we assume that
- the memory area allocated for it is big enough (usually
- bigger than n_fields). */
+ ut_a(buf <= original_buf + buf_len);
+
+ /* We set the length of tuple to n_fields: we assume that the memory
+ area allocated for it is big enough (usually bigger than n_fields). */
dtuple_set_n_fields(tuple, n_fields);
}
/******************************************************************
Stores the row id to the prebuilt struct. */
-UNIV_INLINE
+static
void
row_sel_store_row_id_to_prebuilt(
/*=============================*/
@@ -1963,11 +2056,22 @@ row_sel_store_row_id_to_prebuilt(
{
byte* data;
ulint len;
+ char err_buf[1000];
data = rec_get_nth_field(index_rec,
dict_index_get_sys_col_pos(index, DATA_ROW_ID), &len);
- ut_a(len == DATA_ROW_ID_LEN);
+ if (len != DATA_ROW_ID_LEN) {
+ rec_sprintf(err_buf, 900, index_rec);
+
+ fprintf(stderr,
+"InnoDB: Error: Row id field is wrong length %lu in table %s index %s\n"
+"InnoDB: Field number %lu, record:\n%s\n",
+ len, index->table_name, index->name,
+ dict_index_get_sys_col_pos(index, DATA_ROW_ID),
+ err_buf);
+ ut_a(0);
+ }
ut_memcpy(prebuilt->row_id, data, len);
}
@@ -2186,7 +2290,10 @@ row_sel_get_clust_rec_for_mysql(
/* out: DB_SUCCESS or error code */
row_prebuilt_t* prebuilt,/* in: prebuilt struct in the handle */
dict_index_t* sec_index,/* in: secondary index where rec resides */
- rec_t* rec, /* in: record in a non-clustered index */
+ rec_t* rec, /* in: record in a non-clustered index; if
+ this is a locking read, then rec is not
+ allowed to be delete-marked, and that would
+ not make sense either */
que_thr_t* thr, /* in: query thread */
rec_t** out_rec,/* out: clustered record or an old version of
it, NULL if the old version did not exist
@@ -2201,7 +2308,8 @@ row_sel_get_clust_rec_for_mysql(
rec_t* old_vers;
ulint err;
trx_t* trx;
-
+ char err_buf[1000];
+
*out_rec = NULL;
row_build_row_ref_in_tuple(prebuilt->clust_ref, sec_index, rec);
@@ -2220,18 +2328,56 @@ row_sel_get_clust_rec_for_mysql(
if (!page_rec_is_user_rec(clust_rec)
|| btr_pcur_get_low_match(prebuilt->clust_pcur)
< dict_index_get_n_unique(clust_index)) {
+
+ /* In a rare case it is possible that no clust rec is found
+ for a delete-marked secondary index record: if in row0umod.c
+ in row_undo_mod_remove_clust_low() we have already removed
+ the clust rec, while purge is still cleaning and removing
+ secondary index records associated with earlier versions of
+ the clustered index record. In that case we know that the
+ clustered index record did not exist in the read view of
+ trx. */
+
+ if (!rec_get_deleted_flag(rec)
+ || prebuilt->select_lock_type != LOCK_NONE) {
- clust_rec = NULL;
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: error clustered record for sec rec not found\n"
+ "InnoDB: index %s table %s\n", sec_index->name,
+ sec_index->table->name);
- goto func_exit;
+ rec_sprintf(err_buf, 900, rec);
+ fprintf(stderr,
+ "InnoDB: sec index record %s\n", err_buf);
+
+ rec_sprintf(err_buf, 900, clust_rec);
+ fprintf(stderr,
+ "InnoDB: clust index record %s\n", err_buf);
+
+ trx = thr_get_trx(thr);
+ trx_print(err_buf, trx);
+
+ fprintf(stderr,
+ "%s\nInnoDB: Make a detailed bug report and send it\n",
+ err_buf);
+ fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
+ }
+
+ clust_rec = NULL;
+
+ goto func_exit;
}
if (prebuilt->select_lock_type != LOCK_NONE) {
- /* Try to place a lock on the index record */
+ /* Try to place a lock on the index record; we are searching
+ the clust rec with a unique condition, hence
+ we set a LOCK_REC_NOT_GAP type lock */
err = lock_clust_rec_read_check_and_lock(0, clust_rec,
clust_index,
- prebuilt->select_lock_type, thr);
+ prebuilt->select_lock_type,
+ LOCK_REC_NOT_GAP, thr);
if (err != DB_SUCCESS) {
return(err);
@@ -2243,8 +2389,12 @@ row_sel_get_clust_rec_for_mysql(
trx = thr_get_trx(thr);
old_vers = NULL;
-
- if (!lock_clust_rec_cons_read_sees(clust_rec, clust_index,
+
+ /* If the isolation level allows reading of uncommitted data,
+ then we never look for an earlier version */
+
+ if (trx->isolation_level > TRX_ISO_READ_UNCOMMITTED
+ && !lock_clust_rec_cons_read_sees(clust_rec, clust_index,
trx->read_view)) {
err = row_sel_build_prev_vers_for_mysql(
@@ -2393,6 +2543,7 @@ row_sel_push_cache_row_for_mysql(
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
rec_t* rec) /* in: record to push */
{
+ byte* buf;
ulint i;
ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE);
@@ -2402,8 +2553,18 @@ row_sel_push_cache_row_for_mysql(
/* Allocate memory for the fetch cache */
for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) {
- prebuilt->fetch_cache[i] = mem_alloc(
- prebuilt->mysql_row_len);
+
+ /* A user has reported memory corruption in these
+ buffers in Linux. Put magic numbers there to help
+ to track a possible bug. */
+
+ buf = mem_alloc(prebuilt->mysql_row_len + 8);
+
+ prebuilt->fetch_cache[i] = buf + 4;
+
+ mach_write_to_4(buf, ROW_PREBUILT_FETCH_MAGIC_N);
+ mach_write_to_4(buf + 4 + prebuilt->mysql_row_len,
+ ROW_PREBUILT_FETCH_MAGIC_N);
}
}
@@ -2415,11 +2576,11 @@ row_sel_push_cache_row_for_mysql(
prebuilt->n_fetch_cached++;
}
-
+
/*************************************************************************
Tries to do a shortcut to fetch a clustered index record with a unique key,
using the hash index if possible (not always). We assume that the search
-mode is PAGE_CUR_GE, it is a consistent read, trx has already a read view,
+mode is PAGE_CUR_GE, it is a consistent read, there is a read view in trx,
btr search latch has been locked in S-mode. */
static
ulint
@@ -2438,7 +2599,7 @@ row_sel_try_search_shortcut_for_mysql(
ut_ad(index->type & DICT_CLUSTERED);
ut_ad(!prebuilt->templ_contains_blob);
-
+
btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
BTR_SEARCH_LEAF, pcur,
#ifndef UNIV_SEARCH_DEBUG
@@ -2528,17 +2689,23 @@ row_search_for_mysql(
ibool was_lock_wait;
ulint ret;
ulint shortcut;
+ ibool unique_search = FALSE;
ibool unique_search_from_clust_index = FALSE;
ibool mtr_has_extra_clust_latch = FALSE;
ibool moves_up = FALSE;
+ ibool set_also_gap_locks = TRUE;
+ /* if the query is a plain
+ locking SELECT, and the isolation
+ level is <= TRX_ISO_READ_COMMITTED,
+ then this is set to FALSE */
+ ibool success;
ulint cnt = 0;
+ ulint next_offs;
mtr_t mtr;
ut_ad(index && pcur && search_tuple);
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
-
- ut_ad(sync_thread_levels_empty_gen(FALSE));
-
+
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
fprintf(stderr,
"InnoDB: Error: trying to free a corrupt\n"
@@ -2555,8 +2722,29 @@ row_search_for_mysql(
printf("N tables locked %lu\n", trx->mysql_n_tables_locked);
*/
+ /*-------------------------------------------------------------*/
+ /* PHASE 0: Release a possible s-latch we are holding on the
+ adaptive hash index latch if there is someone waiting behind */
+
+ if (trx->has_search_latch
+ && btr_search_latch.writer != RW_LOCK_NOT_LOCKED) {
+
+ /* There is an x-latch request on the adaptive hash index:
+ release the s-latch to reduce starvation and wait for
+ BTR_SEA_TIMEOUT rounds before trying to keep it again over
+ calls from MySQL */
+
+ rw_lock_s_unlock(&btr_search_latch);
+ trx->has_search_latch = FALSE;
+
+ trx->search_latch_timeout = BTR_SEA_TIMEOUT;
+ }
+
+ /*-------------------------------------------------------------*/
+ /* PHASE 1: Try to pop the row from the prefetch cache */
+
if (direction == 0) {
- trx->op_info = "starting index read";
+ trx->op_info = (char *) "starting index read";
prebuilt->n_rows_fetched = 0;
prebuilt->n_fetch_cached = 0;
@@ -2567,7 +2755,7 @@ row_search_for_mysql(
row_prebuild_sel_graph(prebuilt);
}
} else {
- trx->op_info = "fetching rows";
+ trx->op_info = (char *) "fetching rows";
if (prebuilt->n_rows_fetched == 0) {
prebuilt->fetch_direction = direction;
@@ -2592,7 +2780,7 @@ row_search_for_mysql(
prebuilt->n_rows_fetched++;
srv_n_rows_read++;
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(DB_SUCCESS);
}
@@ -2604,7 +2792,7 @@ row_search_for_mysql(
cache, but the cache was not full at the time of the
popping: no more rows can exist in the result set */
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(DB_RECORD_NOT_FOUND);
}
@@ -2618,66 +2806,81 @@ row_search_for_mysql(
mode = pcur->search_mode;
}
- mtr_start(&mtr);
+ /* In a search where at most one record in the index may match, we
+ can use a LOCK_REC_NOT_GAP type record lock when locking a non-delete-
+ marked matching record.
- /* Since we must release the search system latch when we retrieve an
- externally stored field, we cannot use the adaptive hash index in a
- search in the case the row may be long and there may be externally
- stored fields */
+ Note that in a unique secondary index there may be different delete-
+ marked versions of a record where only the primary key values differ:
+ thus in a secondary index we must use next-key locks when locking
+ delete-marked records. */
if (match_mode == ROW_SEL_EXACT
- && index->type & DICT_UNIQUE
- && index->type & DICT_CLUSTERED
- && !prebuilt->templ_contains_blob
- && (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)
- && dtuple_get_n_fields(search_tuple)
- == dict_index_get_n_unique(index)) {
+ && index->type & DICT_UNIQUE
+ && dtuple_get_n_fields(search_tuple)
+ == dict_index_get_n_unique(index)
+ && (index->type & DICT_CLUSTERED
+ || !dtuple_contains_null(search_tuple))) {
+
+ /* Note above that a UNIQUE secondary index can contain many
+ rows with the same key value if one of the columns is the SQL
+ null. A clustered index under MySQL can never contain null
+ columns because we demand that all the columns in primary key
+ are non-null. */
+
+ unique_search = TRUE;
+
+ /* Even if the condition is unique, MySQL seems to try to
+ retrieve also a second row if a primary key contains more than
+ 1 column. Return immediately if this is not a HANDLER
+ command. */
+
+ if (direction != 0 && !prebuilt->used_in_HANDLER) {
+
+ trx->op_info = (char*)"";
+ return(DB_RECORD_NOT_FOUND);
+ }
+ }
- if (direction == ROW_SEL_NEXT) {
- /* MySQL sometimes seems to do fetch next even
- if the search condition is unique; we do not store
- pcur position in this case, so we cannot
- restore cursor position, and must return
- immediately */
+ mtr_start(&mtr);
- mtr_commit(&mtr);
+ /*-------------------------------------------------------------*/
+ /* PHASE 2: Try fast adaptive hash index search if possible */
- /* printf("%s record not found 1\n", index->name); */
-
- trx->op_info = "";
- return(DB_RECORD_NOT_FOUND);
- }
+ /* Next test if this is the special case where we can use the fast
+ adaptive hash index to try the search. Since we must release the
+ search system latch when we retrieve an externally stored field, we
+ cannot use the adaptive hash index in a search in the case the row
+ may be long and there may be externally stored fields */
+
+ if (unique_search
+ && index->type & DICT_CLUSTERED
+ && direction == 0
+ && !prebuilt->templ_contains_blob
+ && !prebuilt->used_in_HANDLER
+ && (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)) {
- ut_a(direction == 0); /* We cannot do fetch prev, as we have
- not stored the cursor position */
mode = PAGE_CUR_GE;
unique_search_from_clust_index = TRUE;
if (trx->mysql_n_tables_locked == 0
- && !prebuilt->sql_stat_start) {
+ && prebuilt->select_lock_type == LOCK_NONE
+ && trx->isolation_level > TRX_ISO_READ_UNCOMMITTED
+ && trx->read_view) {
/* This is a SELECT query done as a consistent read,
and the read view has already been allocated:
let us try a search shortcut through the hash
- index */
-
- if (btr_search_latch.writer != RW_LOCK_NOT_LOCKED) {
- /* There is an x-latch request: release
- a possible s-latch to reduce starvation
- and wait for BTR_SEA_TIMEOUT rounds before
- trying to keep it again over calls from
- MySQL */
-
- if (trx->has_search_latch) {
- rw_lock_s_unlock(&btr_search_latch);
- trx->has_search_latch = FALSE;
- }
+ index.
+ NOTE that we must also test that
+ mysql_n_tables_locked == 0, because this might
+ also be INSERT INTO ... SELECT ... or
+ CREATE TABLE ... SELECT ... . Our algorithm is
+ NOT prepared to inserts interleaved with the SELECT,
+ and if we try that, we can deadlock on the adaptive
+ hash index semaphore! */
- trx->search_latch_timeout = BTR_SEA_TIMEOUT;
-
- goto no_shortcut;
- }
#ifndef UNIV_SEARCH_DEBUG
if (!trx->has_search_latch) {
rw_lock_s_lock(&btr_search_latch);
@@ -2707,7 +2910,11 @@ row_search_for_mysql(
trx->has_search_latch = FALSE;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
+
+ /* NOTE that we do NOT store the cursor
+ position */
+
return(DB_SUCCESS);
} else if (shortcut == SEL_EXHAUSTED) {
@@ -2726,7 +2933,11 @@ row_search_for_mysql(
trx->has_search_latch = FALSE;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
+
+ /* NOTE that we do NOT store the cursor
+ position */
+
return(DB_RECORD_NOT_FOUND);
}
@@ -2734,13 +2945,33 @@ row_search_for_mysql(
mtr_start(&mtr);
}
}
-no_shortcut:
+
+ /*-------------------------------------------------------------*/
+ /* PHASE 3: Open or restore index cursor position */
+
if (trx->has_search_latch) {
rw_lock_s_unlock(&btr_search_latch);
trx->has_search_latch = FALSE;
}
trx_start_if_not_started(trx);
+
+ if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
+ && prebuilt->select_lock_type != LOCK_NONE
+ && trx->mysql_query_str) {
+
+ /* Scan the MySQL query string; check if SELECT is the first
+ word there */
+
+ dict_accept(*trx->mysql_query_str, "SELECT", &success);
+
+ if (success) {
+ /* It is a plain locking SELECT and the isolation
+ level is low: do not lock gaps */
+
+ set_also_gap_locks = FALSE;
+ }
+ }
/* Note that if the search mode was GE or G, then the cursor
naturally moves upward (in fetch next) in alphabetical order,
@@ -2805,10 +3036,10 @@ no_shortcut:
prebuilt->sql_stat_start = FALSE;
}
- /*-------------------------------------------------------------*/
rec_loop:
- cons_read_requires_clust_rec = FALSE;
-
+ /*-------------------------------------------------------------*/
+ /* PHASE 4: Look for matching records in a loop */
+
rec = btr_pcur_get_rec(pcur);
/*
printf("Using index %s cnt %lu ", index->name, cnt);
@@ -2824,29 +3055,88 @@ rec_loop:
goto next_rec;
}
-
- if (prebuilt->select_lock_type != LOCK_NONE) {
- /* Try to place a lock on the index record */
- err = sel_set_rec_lock(rec, index, prebuilt->select_lock_type,
- thr);
- if (err != DB_SUCCESS) {
+ if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
- goto lock_wait_or_error;
- }
- }
+ if (prebuilt->select_lock_type != LOCK_NONE
+ && set_also_gap_locks) {
- if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
+ /* Try to place a lock on the index record */
+ err = sel_set_rec_lock(rec, index,
+ prebuilt->select_lock_type,
+ LOCK_ORDINARY, thr);
+ if (err != DB_SUCCESS) {
+
+ goto lock_wait_or_error;
+ }
+ }
/* A page supremum record cannot be in the result set: skip
- it now when we have placed a possible lock on it */
+ it now that we have placed a possible lock on it */
goto next_rec;
}
- ut_ad(page_rec_is_user_rec(rec));
+ /*-------------------------------------------------------------*/
+ /* Do sanity checks in case our cursor has bumped into page
+ corruption */
+
+ next_offs = rec_get_next_offs(rec);
+
+ if (next_offs >= UNIV_PAGE_SIZE || next_offs < PAGE_SUPREMUM) {
+
+ if (srv_force_recovery == 0 || moves_up == FALSE) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
+"InnoDB: index %s, table %s. Run CHECK TABLE to table. You may need to\n"
+"InnoDB: restore from a backup, or dump + drop + reimport the table.\n",
+ (ulint)(rec - buf_frame_align(rec)), next_offs,
+ buf_frame_get_page_no(rec), index->name,
+ index->table_name);
+
+ err = DB_CORRUPTION;
+
+ goto lock_wait_or_error;
+ } else {
+ /* The user may be dumping a corrupt table. Jump
+ over the corruption to recover as much as possible. */
+
+ fprintf(stderr,
+"InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
+"InnoDB: index %s, table %s. We try to skip the rest of the page.\n",
+ (ulint)(rec - buf_frame_align(rec)), next_offs,
+ buf_frame_get_page_no(rec), index->name,
+ index->table_name);
+
+ btr_pcur_move_to_last_on_page(pcur, &mtr);
+
+ goto next_rec;
+ }
+ }
- if (match_mode == ROW_SEL_EXACT) {
+ if (srv_force_recovery > 0) {
+ if (!rec_validate(rec) || !btr_index_rec_validate(rec, index,
+ FALSE)) {
+ fprintf(stderr,
+"InnoDB: Index record corruption: rec offs %lu next offs %lu, page no %lu,\n"
+"InnoDB: index %s, table %s. We try to skip the record.\n",
+ (ulint)(rec - buf_frame_align(rec)), next_offs,
+ buf_frame_get_page_no(rec), index->name,
+ index->table_name);
+
+ goto next_rec;
+ }
+ }
+
+ /*-------------------------------------------------------------*/
+
+ /* Note that we cannot trust the up_match value in the cursor at this
+ place because we can arrive here after moving the cursor! Thus
+ we have to recompare rec and search_tuple to determine if they
+ match enough. */
+
+ if (match_mode == ROW_SEL_EXACT) {
/* Test if the index record matches completely to search_tuple
in prebuilt: if not, then we return with DB_RECORD_NOT_FOUND */
@@ -2854,6 +3144,19 @@ rec_loop:
if (0 != cmp_dtuple_rec(search_tuple, rec)) {
+ if (prebuilt->select_lock_type != LOCK_NONE
+ && set_also_gap_locks) {
+ /* Try to place a lock on the index record */
+
+ err = sel_set_rec_lock(rec, index,
+ prebuilt->select_lock_type,
+ LOCK_GAP, thr);
+ if (err != DB_SUCCESS) {
+
+ goto lock_wait_or_error;
+ }
+ }
+
btr_pcur_store_position(pcur, &mtr);
ret = DB_RECORD_NOT_FOUND;
@@ -2866,6 +3169,19 @@ rec_loop:
if (!cmp_dtuple_is_prefix_of_rec(search_tuple, rec)) {
+ if (prebuilt->select_lock_type != LOCK_NONE
+ && set_also_gap_locks) {
+ /* Try to place a lock on the index record */
+
+ err = sel_set_rec_lock(rec, index,
+ prebuilt->select_lock_type,
+ LOCK_GAP, thr);
+ if (err != DB_SUCCESS) {
+
+ goto lock_wait_or_error;
+ }
+ }
+
btr_pcur_store_position(pcur, &mtr);
ret = DB_RECORD_NOT_FOUND;
@@ -2878,18 +3194,47 @@ rec_loop:
/* We are ready to look at a possible new index entry in the result
set: the cursor is now placed on a user record */
- /* Get the right version of the row in a consistent read */
+ cons_read_requires_clust_rec = FALSE;
- if (prebuilt->select_lock_type == LOCK_NONE) {
+ if (prebuilt->select_lock_type != LOCK_NONE) {
+ /* Try to place a lock on the index record; note that delete
+ marked records are a special case in a unique search. If there
+ is a non-delete marked record, then it is enough to lock its
+ existence with LOCK_REC_NOT_GAP. */
+
+ if (!set_also_gap_locks
+ || (unique_search && !rec_get_deleted_flag(rec))) {
+ err = sel_set_rec_lock(rec, index,
+ prebuilt->select_lock_type,
+ LOCK_REC_NOT_GAP, thr);
+ } else {
+ err = sel_set_rec_lock(rec, index,
+ prebuilt->select_lock_type,
+ LOCK_ORDINARY, thr);
+ }
+
+ if (err != DB_SUCCESS) {
+ goto lock_wait_or_error;
+ }
+ } else {
/* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */
- cons_read_requires_clust_rec = FALSE;
+ if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) {
- if (index == clust_index) {
-
- if (!lock_clust_rec_cons_read_sees(rec, index,
+ /* Do nothing: we let a non-locking SELECT read the
+ latest version of the record */
+
+ } else if (index == clust_index) {
+
+ /* Fetch a previous version of the row if the current
+ one is not visible in the snapshot; if we have a very
+ high force recovery level set, we try to avoid crashes
+ by skipping this lookup */
+
+ if (srv_force_recovery < 5
+ && !lock_clust_rec_cons_read_sees(rec, index,
trx->read_view)) {
err = row_sel_build_prev_vers_for_mysql(
@@ -2925,7 +3270,7 @@ rec_loop:
if (rec_get_deleted_flag(rec) && !cons_read_requires_clust_rec) {
- /* The record is delete marked: we can skip it if this is
+ /* The record is delete-marked: we can skip it if this is
not a consistent read which might see an earlier version
of a non-clustered index record */
@@ -2977,6 +3322,7 @@ rec_loop:
&& prebuilt->select_lock_type == LOCK_NONE
&& !prebuilt->templ_contains_blob
&& !prebuilt->clust_index_was_generated
+ && !prebuilt->used_in_HANDLER
&& prebuilt->template_type
!= ROW_MYSQL_DUMMY_TEMPLATE) {
@@ -2985,7 +3331,9 @@ rec_loop:
update, that is why we require ...lock_type == LOCK_NONE.
Since we keep space in prebuilt only for the BLOBs of
a single row, we cannot cache rows in the case there
- are BLOBs in the fields to be fetched. */
+ are BLOBs in the fields to be fetched. In HANDLER we do
+ not cache rows because there the cursor is a scrollable
+ cursor. */
row_sel_push_cache_row_for_mysql(prebuilt, rec);
@@ -3010,11 +3358,16 @@ rec_loop:
}
}
got_row:
- /* TODO: should we in every case store the cursor position, even
- if this is just a join, for example? */
+ /* We have an optimization to save CPU time: if this is a consistent
+ read on a unique condition on the clustered index, then we do not
+ store the pcur position, because any fetch next or prev will anyway
+ return 'end of file'. An exception is the MySQL HANDLER command
+ where the user can move the cursor with PREV or NEXT even after
+ a unique search. */
if (!unique_search_from_clust_index
- || prebuilt->select_lock_type == LOCK_X) {
+ || prebuilt->select_lock_type == LOCK_X
+ || prebuilt->used_in_HANDLER) {
/* Inside an update always store the cursor position */
@@ -3024,8 +3377,11 @@ got_row:
ret = DB_SUCCESS;
goto normal_return;
- /*-------------------------------------------------------------*/
+
next_rec:
+ /*-------------------------------------------------------------*/
+ /* PHASE 5: Move the cursor to the next index record */
+
if (mtr_has_extra_clust_latch) {
/* We must commit mtr if we are moving to the next
non-clustered index record, because we could break the
@@ -3068,8 +3424,10 @@ next_rec:
cnt++;
goto rec_loop;
- /*-------------------------------------------------------------*/
+
lock_wait_or_error:
+ /*-------------------------------------------------------------*/
+
btr_pcur_store_position(pcur, &mtr);
mtr_commit(&mtr);
@@ -3095,11 +3453,12 @@ lock_wait_or_error:
/* printf("Using index %s cnt %lu ret value %lu err\n", index->name,
cnt, err); */
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
normal_return:
+ /*-------------------------------------------------------------*/
que_thr_stop_for_mysql_no_error(thr, trx);
mtr_commit(&mtr);
@@ -3116,7 +3475,62 @@ normal_return:
srv_n_rows_read++;
}
- trx->op_info = "";
+ trx->op_info = (char *) "";
+
+ return(ret);
+}
+
+/***********************************************************************
+Checks if MySQL at the moment is allowed for this table to retrieve a
+consistent read result, or store it to the query cache. */
+
+ibool
+row_search_check_if_query_cache_permitted(
+/*======================================*/
+ /* out: TRUE if storing or retrieving from
+ the query cache is permitted */
+ trx_t* trx, /* in: transaction object */
+ char* norm_name) /* in: concatenation of database name, '/'
+ char, table name */
+{
+ dict_table_t* table;
+ ibool ret = FALSE;
+
+ table = dict_table_get(norm_name, trx);
+
+ if (table == NULL) {
+
+ return(FALSE);
+ }
+
+ mutex_enter(&kernel_mutex);
+
+ /* Start the transaction if it is not started yet */
+
+ trx_start_if_not_started_low(trx);
+
+ /* If there are locks on the table or some trx has invalidated the
+ cache up to our trx id, then ret = FALSE.
+ We do not check what type locks there are on the table, though only
+ IX type locks actually would require ret = FALSE. */
+
+ if (UT_LIST_GET_LEN(table->locks) == 0
+ && ut_dulint_cmp(trx->id, table->query_cache_inv_trx_id) >= 0) {
+
+ ret = TRUE;
+
+ /* If the isolation level is high, assign a read view for the
+ transaction if it does not yet have one */
+
+ if (trx->isolation_level >= TRX_ISO_REPEATABLE_READ
+ && !trx->read_view) {
+
+ trx->read_view = read_view_open_now(trx,
+ trx->read_view_heap);
+ }
+ }
+
+ mutex_exit(&kernel_mutex);
return(ret);
}
diff --git a/innobase/row/row0uins.c b/innobase/row/row0uins.c
index 27d1fbcb9ba..fff67dcd627 100644
--- a/innobase/row/row0uins.c
+++ b/innobase/row/row0uins.c
@@ -234,7 +234,7 @@ void
row_undo_ins_parse_undo_rec(
/*========================*/
undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr __attribute__((unused))) /* in: query thread */
{
dict_index_t* clust_index;
byte* ptr;
@@ -254,7 +254,8 @@ row_undo_ins_parse_undo_rec(
node->table = dict_table_get_on_id(table_id, node->trx);
if (node->table == NULL) {
- return;
+
+ return;
}
clust_index = dict_table_get_first_index(node->table);
@@ -281,7 +282,7 @@ row_undo_ins(
ut_ad(node && thr);
ut_ad(node->state == UNDO_NODE_INSERT);
-
+
row_undo_ins_parse_undo_rec(node, thr);
if (node->table == NULL) {
@@ -292,6 +293,7 @@ row_undo_ins(
if (!found) {
trx_undo_rec_release(node->trx, node->undo_no);
+
return(DB_SUCCESS);
}
diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c
index bbffda39352..34c3aaf9142 100644
--- a/innobase/row/row0umod.c
+++ b/innobase/row/row0umod.c
@@ -139,7 +139,7 @@ row_undo_mod_remove_clust_low(
/* out: DB_SUCCESS, DB_FAIL, or error code:
we may run out of file space */
undo_node_t* node, /* in: row undo node */
- que_thr_t* thr, /* in: query thread */
+ que_thr_t* thr __attribute__((unused)), /* in: query thread */
mtr_t* mtr, /* in: mtr */
ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
@@ -377,8 +377,14 @@ row_undo_mod_del_mark_or_remove_sec_low(
}
/***************************************************************
-Delete marks or removes a secondary index entry if found. */
-UNIV_INLINE
+Delete marks or removes a secondary index entry if found.
+NOTE that if we updated the fields of a delete-marked secondary index record
+so that alphabetically they stayed the same, e.g., 'abc' -> 'aBc', we cannot
+return to the original values because we do not know them. But this should
+not cause problems because in row0sel.c, in queries we always retrieve the
+clustered index record or an earlier version of it, if the secondary index
+record through which we do the search is delete-marked. */
+static
ulint
row_undo_mod_del_mark_or_remove_sec(
/*================================*/
@@ -403,20 +409,31 @@ row_undo_mod_del_mark_or_remove_sec(
}
/***************************************************************
-Delete unmarks a secondary index entry which must be found. */
+Delete unmarks a secondary index entry which must be found. It might not be
+delete-marked at the moment, but it does not harm to unmark it anyway. We also
+need to update the fields of the secondary index record if we updated its
+fields but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'. */
static
-void
-row_undo_mod_del_unmark_sec(
-/*========================*/
+ulint
+row_undo_mod_del_unmark_sec_and_undo_update(
+/*========================================*/
+ /* out: DB_FAIL or DB_SUCCESS or
+ DB_OUT_OF_FILE_SPACE */
+ ulint mode, /* in: search mode: BTR_MODIFY_LEAF or
+ BTR_MODIFY_TREE */
undo_node_t* node, /* in: row undo node */
que_thr_t* thr, /* in: query thread */
dict_index_t* index, /* in: index */
dtuple_t* entry) /* in: index entry */
{
+ mem_heap_t* heap;
btr_pcur_t pcur;
btr_cur_t* btr_cur;
- ulint err;
+ upd_t* update;
+ rec_t* rec;
+ ulint err = DB_SUCCESS;
ibool found;
+ big_rec_t* dummy_big_rec;
mtr_t mtr;
char err_buf[1000];
@@ -425,10 +442,11 @@ row_undo_mod_del_unmark_sec(
log_free_check();
mtr_start(&mtr);
- found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
- &mtr);
+ found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
+
if (!found) {
- fprintf(stderr, "InnoDB: error in sec index entry del undo in\n"
+ fprintf(stderr,
+ "InnoDB: error in sec index entry del undo in\n"
"InnoDB: index %s table %s\n", index->name,
index->table->name);
dtuple_sprintf(err_buf, 900, entry);
@@ -442,17 +460,47 @@ row_undo_mod_del_unmark_sec(
"%s\nInnoDB: Make a detailed bug report and send it\n",
err_buf);
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
-
} else {
btr_cur = btr_pcur_get_btr_cur(&pcur);
+ rec = btr_cur_get_rec(btr_cur);
+
err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG,
btr_cur, FALSE, thr, &mtr);
- ut_ad(err == DB_SUCCESS);
+ ut_a(err == DB_SUCCESS);
+ heap = mem_heap_create(100);
+
+ update = row_upd_build_sec_rec_difference_binary(index, entry,
+ rec, heap);
+ if (upd_get_n_fields(update) == 0) {
+
+ /* Do nothing */
+
+ } else if (mode == BTR_MODIFY_LEAF) {
+ /* Try an optimistic updating of the record, keeping
+ changes within the page */
+
+ err = btr_cur_optimistic_update(BTR_KEEP_SYS_FLAG
+ | BTR_NO_LOCKING_FLAG,
+ btr_cur, update, 0, thr, &mtr);
+ if (err == DB_OVERFLOW || err == DB_UNDERFLOW) {
+ err = DB_FAIL;
+ }
+ } else {
+ ut_a(mode == BTR_MODIFY_TREE);
+ err = btr_cur_pessimistic_update(BTR_KEEP_SYS_FLAG
+ | BTR_NO_LOCKING_FLAG,
+ btr_cur, &dummy_big_rec,
+ update, 0, thr, &mtr);
+ }
+
+ mem_heap_free(heap);
}
btr_pcur_close(&pcur);
mtr_commit(&mtr);
+
+ return(err);
}
/***************************************************************
@@ -500,13 +548,14 @@ static
ulint
row_undo_mod_del_mark_sec(
/*======================*/
- /* out: DB_SUCCESS */
+ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
undo_node_t* node, /* in: row undo node */
que_thr_t* thr) /* in: query thread */
{
mem_heap_t* heap;
dtuple_t* entry;
dict_index_t* index;
+ ulint err;
heap = mem_heap_create(1024);
@@ -515,7 +564,21 @@ row_undo_mod_del_mark_sec(
entry = row_build_index_entry(node->row, index, heap);
- row_undo_mod_del_unmark_sec(node, thr, index, entry);
+ err = row_undo_mod_del_unmark_sec_and_undo_update(
+ BTR_MODIFY_LEAF,
+ node, thr, index, entry);
+ if (err == DB_FAIL) {
+ err = row_undo_mod_del_unmark_sec_and_undo_update(
+ BTR_MODIFY_TREE,
+ node, thr, index, entry);
+ }
+
+ if (err != DB_SUCCESS) {
+
+ mem_heap_free(heap);
+
+ return(err);
+ }
node->index = dict_table_get_next_index(node->index);
}
@@ -531,7 +594,7 @@ static
ulint
row_undo_mod_upd_exist_sec(
/*=======================*/
- /* out: DB_SUCCESS or error code */
+ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
undo_node_t* node, /* in: row undo node */
que_thr_t* thr) /* in: query thread */
{
@@ -557,22 +620,48 @@ row_undo_mod_upd_exist_sec(
/* Build the newest version of the index entry */
entry = row_build_index_entry(node->row, index, heap);
+ /* NOTE that if we updated the fields of a
+ delete-marked secondary index record so that
+ alphabetically they stayed the same, e.g.,
+ 'abc' -> 'aBc', we cannot return to the original
+ values because we do not know them. But this should
+ not cause problems because in row0sel.c, in queries
+ we always retrieve the clustered index record or an
+ earlier version of it, if the secondary index record
+ through which we do the search is delete-marked. */
+
err = row_undo_mod_del_mark_or_remove_sec(node, thr,
- index, entry);
+ index, entry);
if (err != DB_SUCCESS) {
mem_heap_free(heap);
return(err);
}
-
+
/* We may have to update the delete mark in the
secondary index record of the previous version of
- the row */
+ the row. We also need to update the fields of
+ the secondary index record if we updated its fields
+ but alphabetically they stayed the same, e.g.,
+ 'abc' -> 'aBc'. */
row_upd_index_replace_new_col_vals(entry, index,
- node->update);
+ node->update, NULL);
+ err = row_undo_mod_del_unmark_sec_and_undo_update(
+ BTR_MODIFY_LEAF,
+ node, thr, index, entry);
+ if (err == DB_FAIL) {
+ err =
+ row_undo_mod_del_unmark_sec_and_undo_update(
+ BTR_MODIFY_TREE,
+ node, thr, index, entry);
+ }
- row_undo_mod_del_unmark_sec(node, thr, index, entry);
+ if (err != DB_SUCCESS) {
+ mem_heap_free(heap);
+
+ return(err);
+ }
}
node->index = dict_table_get_next_index(node->index);
diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c
index 5119254f405..01b0b1ab41e 100644
--- a/innobase/row/row0undo.c
+++ b/innobase/row/row0undo.c
@@ -24,6 +24,7 @@ Created 1/8/1997 Heikki Tuuri
#include "row0row.h"
#include "row0uins.h"
#include "row0umod.h"
+#include "row0mysql.h"
#include "srv0srv.h"
/* How to undo row operations?
@@ -204,6 +205,7 @@ row_undo(
ulint err;
trx_t* trx;
dulint roll_ptr;
+ ibool froze_data_dict = FALSE;
ut_ad(node && thr);
@@ -211,7 +213,6 @@ row_undo(
if (node->state == UNDO_NODE_FETCH_NEXT) {
- /* The call below also starts &mtr */
node->undo_rec = trx_roll_pop_top_rec_of_trx(trx,
trx->roll_limit,
&roll_ptr,
@@ -254,6 +255,18 @@ row_undo(
}
}
+ /* Prevent DROP TABLE etc. while we are rolling back this row.
+ If we are doing a TABLE CREATE or some other dictionary operation,
+ then we already have dict_operation_lock locked in x-mode. Do not
+ try to lock again in s-mode, because that would cause a hang. */
+
+ if (trx->dict_operation_lock_mode == 0) {
+
+ row_mysql_freeze_data_dictionary(trx);
+
+ froze_data_dict = TRUE;
+ }
+
if (node->state == UNDO_NODE_INSERT) {
err = row_undo_ins(node, thr);
@@ -264,6 +277,11 @@ row_undo(
err = row_undo_mod(node, thr);
}
+ if (froze_data_dict) {
+
+ row_mysql_unfreeze_data_dictionary(trx);
+ }
+
/* Do some cleanup */
btr_pcur_close(&(node->pcur));
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index 6eaab79060e..e3725c8b39e 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -71,6 +71,21 @@ the x-latch freed? The most efficient way for performing a
searched delete is obviously to keep the x-latch for several
steps of query graph execution. */
+/***************************************************************
+Checks if an update vector changes some of the first ordering fields of an
+index record. This is only used in foreign key checks and we can assume
+that index does not contain column prefixes. */
+static
+ibool
+row_upd_changes_first_fields(
+/*=========================*/
+ /* out: TRUE if changes */
+ dtuple_t* entry, /* in: old value of index entry */
+ dict_index_t* index, /* in: index of entry */
+ upd_t* update, /* in: update vector for the row */
+ ulint n); /* in: how many first fields to check */
+
+
/*************************************************************************
Checks if index currently is mentioned as a referenced index in a foreign
key constraint. */
@@ -79,7 +94,7 @@ ibool
row_upd_index_is_referenced(
/*========================*/
/* out: TRUE if referenced; NOTE that since
- we do not hold dict_foreign_key_check_lock
+ we do not hold dict_operation_lock
when leaving the function, it may be that
the referencing table has been dropped when
we leave this function: this function is only
@@ -89,14 +104,16 @@ row_upd_index_is_referenced(
{
dict_table_t* table = index->table;
dict_foreign_t* foreign;
+ ibool froze_data_dict = FALSE;
if (!UT_LIST_GET_FIRST(table->referenced_list)) {
return(FALSE);
}
- if (!trx->has_dict_foreign_key_check_lock) {
- rw_lock_s_lock(&dict_foreign_key_check_lock);
+ if (trx->dict_operation_lock_mode == 0) {
+ row_mysql_freeze_data_dictionary(trx);
+ froze_data_dict = TRUE;
}
foreign = UT_LIST_GET_FIRST(table->referenced_list);
@@ -104,8 +121,8 @@ row_upd_index_is_referenced(
while (foreign) {
if (foreign->referenced_index == index) {
- if (!trx->has_dict_foreign_key_check_lock) {
- rw_lock_s_unlock(&dict_foreign_key_check_lock);
+ if (froze_data_dict) {
+ row_mysql_unfreeze_data_dictionary(trx);
}
return(TRUE);
@@ -114,8 +131,8 @@ row_upd_index_is_referenced(
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
- if (!trx->has_dict_foreign_key_check_lock) {
- rw_lock_s_unlock(&dict_foreign_key_check_lock);
+ if (froze_data_dict) {
+ row_mysql_unfreeze_data_dictionary(trx);
}
return(FALSE);
@@ -130,6 +147,7 @@ ulint
row_upd_check_references_constraints(
/*=================================*/
/* out: DB_SUCCESS or an error code */
+ upd_node_t* node, /* in: row update node */
btr_pcur_t* pcur, /* in: cursor positioned on a record; NOTE: the
cursor position is lost in this function! */
dict_table_t* table, /* in: table in question */
@@ -162,18 +180,25 @@ row_upd_check_references_constraints(
mtr_start(mtr);
- if (!trx->has_dict_foreign_key_check_lock) {
+ if (trx->dict_operation_lock_mode == 0) {
got_s_lock = TRUE;
- rw_lock_s_lock(&dict_foreign_key_check_lock);
-
- trx->has_dict_foreign_key_check_lock = TRUE;
+ row_mysql_freeze_data_dictionary(trx);
}
foreign = UT_LIST_GET_FIRST(table->referenced_list);
while (foreign) {
- if (foreign->referenced_index == index) {
+ /* Note that we may have an update which updates the index
+ record, but does NOT update the first fields which are
+ referenced in a foreign key constraint. Then the update does
+ NOT break the constraint. */
+
+ if (foreign->referenced_index == index
+ && (node->is_delete
+ || row_upd_changes_first_fields(entry, index,
+ node->update, foreign->n_fields))) {
+
if (foreign->foreign_table == NULL) {
dict_table_get(foreign->foreign_table_name,
trx);
@@ -189,13 +214,12 @@ row_upd_check_references_constraints(
}
/* NOTE that if the thread ends up waiting for a lock
- we will release dict_foreign_key_check_lock
- temporarily! But the counter on the table
- protects 'foreign' from being dropped while the check
- is running. */
+ we will release dict_operation_lock temporarily!
+ But the counter on the table protects 'foreign' from
+ being dropped while the check is running. */
err = row_ins_check_foreign_constraint(FALSE, foreign,
- table, index, entry, thr);
+ table, entry, thr);
if (foreign->foreign_table) {
mutex_enter(&(dict_sys->mutex));
@@ -211,10 +235,8 @@ row_upd_check_references_constraints(
if (err != DB_SUCCESS) {
if (got_s_lock) {
- rw_lock_s_unlock(
- &dict_foreign_key_check_lock);
- trx->has_dict_foreign_key_check_lock
- = FALSE;
+ row_mysql_unfreeze_data_dictionary(
+ trx);
}
mem_heap_free(heap);
@@ -227,8 +249,7 @@ row_upd_check_references_constraints(
}
if (got_s_lock) {
- rw_lock_s_unlock(&dict_foreign_key_check_lock);
- trx->has_dict_foreign_key_check_lock = FALSE;
+ row_mysql_unfreeze_data_dictionary(trx);
}
mem_heap_free(heap);
@@ -259,6 +280,7 @@ upd_node_create(
node->index = NULL;
node->update = NULL;
+ node->foreign = NULL;
node->cascade_heap = NULL;
node->cascade_node = NULL;
@@ -330,16 +352,17 @@ row_upd_index_entry_sys_field(
}
/***************************************************************
-Returns TRUE if row update changes size of some field in index
-or if some field to be updated is stored externally in rec or update. */
+Returns TRUE if row update changes size of some field in index or if some
+field to be updated is stored externally in rec or update. */
ibool
-row_upd_changes_field_size(
-/*=======================*/
+row_upd_changes_field_size_or_external(
+/*===================================*/
/* out: TRUE if the update changes the size of
- some field in index */
- rec_t* rec, /* in: record in clustered index */
- dict_index_t* index, /* in: clustered index */
+ some field in index or the field is external
+ in rec or update */
+ rec_t* rec, /* in: record in index */
+ dict_index_t* index, /* in: index */
upd_t* update) /* in: update vector */
{
upd_field_t* upd_field;
@@ -349,8 +372,6 @@ row_upd_changes_field_size(
ulint n_fields;
ulint i;
- ut_ad(index->type & DICT_CLUSTERED);
-
n_fields = upd_get_n_fields(update);
for (i = 0; i < n_fields; i++) {
@@ -428,7 +449,7 @@ row_upd_write_sys_vals_to_log(
dulint roll_ptr,/* in: roll ptr of the undo log record */
byte* log_ptr,/* pointer to a buffer of size > 20 opened
in mlog */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr __attribute__((unused))) /* in: mtr */
{
ut_ad(index->type & DICT_CLUSTERED);
ut_ad(mtr);
@@ -675,7 +696,7 @@ row_upd_build_sec_rec_difference_binary(
ulint i;
/* This function is used only for a secondary index */
- ut_ad(0 == (index->type & DICT_CLUSTERED));
+ ut_a(0 == (index->type & DICT_CLUSTERED));
update = upd_create(dtuple_get_n_fields(entry), heap);
@@ -687,7 +708,13 @@ row_upd_build_sec_rec_difference_binary(
dfield = dtuple_get_nth_field(entry, i);
- ut_a(len == dfield_get_len(dfield));
+ /* NOTE that it may be that len != dfield_get_len(dfield) if we
+ are updating in a character set and collation where strings of
+ different length can be equal in an alphabetical comparison,
+ and also in the case where we have a column prefix index
+ and the last characters in the index field are spaces; the
+ latter case probably caused the assertion failures reported at
+ row0upd.c line 713 in versions 4.0.14 - 4.0.16. */
/* NOTE: we compare the fields as binary strings!
(No collation) */
@@ -797,72 +824,122 @@ Replaces the new column values stored in the update vector to the index entry
given. */
void
-row_upd_index_replace_new_col_vals(
-/*===============================*/
+row_upd_index_replace_new_col_vals_index_pos(
+/*=========================================*/
dtuple_t* entry, /* in/out: index entry where replaced */
- dict_index_t* index, /* in: index; NOTE that may also be a
+ dict_index_t* index, /* in: index; NOTE that this may also be a
non-clustered index */
- upd_t* update) /* in: update vector */
+ upd_t* update, /* in: an update vector built for the index so
+ that the field number in an upd_field is the
+ index position */
+ mem_heap_t* heap) /* in: memory heap to which we allocate and
+ copy the new values, set this as NULL if you
+ do not want allocation */
{
+ dict_field_t* field;
upd_field_t* upd_field;
dfield_t* dfield;
dfield_t* new_val;
- ulint field_no;
- dict_index_t* clust_index;
+ ulint j;
ulint i;
ut_ad(index);
- clust_index = dict_table_get_first_index(index->table);
-
dtuple_set_info_bits(entry, update->info_bits);
- for (i = 0; i < upd_get_n_fields(update); i++) {
+ for (j = 0; j < dict_index_get_n_fields(index); j++) {
- upd_field = upd_get_nth_field(update, i);
+ field = dict_index_get_nth_field(index, j);
- field_no = dict_index_get_nth_col_pos(index,
- dict_index_get_nth_col_no(clust_index,
- upd_field->field_no));
- if (field_no != ULINT_UNDEFINED) {
- dfield = dtuple_get_nth_field(entry, field_no);
+ for (i = 0; i < upd_get_n_fields(update); i++) {
- new_val = &(upd_field->new_val);
+ upd_field = upd_get_nth_field(update, i);
- dfield_set_data(dfield, new_val->data, new_val->len);
+ if (upd_field->field_no == j) {
+
+ dfield = dtuple_get_nth_field(entry, j);
+
+ new_val = &(upd_field->new_val);
+
+ dfield_set_data(dfield, new_val->data,
+ new_val->len);
+ if (heap && new_val->len != UNIV_SQL_NULL) {
+ dfield->data = mem_heap_alloc(heap,
+ new_val->len);
+ ut_memcpy(dfield->data, new_val->data,
+ new_val->len);
+ }
+
+ if (field->prefix_len > 0
+ && new_val->len != UNIV_SQL_NULL
+ && new_val->len > field->prefix_len) {
+
+ dfield->len = field->prefix_len;
+ }
+ }
}
}
}
/***************************************************************
-Replaces the new column values stored in the update vector to the
-clustered index entry given. */
+Replaces the new column values stored in the update vector to the index entry
+given. */
void
-row_upd_clust_index_replace_new_col_vals(
-/*=====================================*/
+row_upd_index_replace_new_col_vals(
+/*===============================*/
dtuple_t* entry, /* in/out: index entry where replaced */
- upd_t* update) /* in: update vector */
+ dict_index_t* index, /* in: index; NOTE that this may also be a
+ non-clustered index */
+ upd_t* update, /* in: an update vector built for the
+ CLUSTERED index so that the field number in
+ an upd_field is the clustered index position */
+ mem_heap_t* heap) /* in: memory heap to which we allocate and
+ copy the new values, set this as NULL if you
+ do not want allocation */
{
+ dict_field_t* field;
upd_field_t* upd_field;
dfield_t* dfield;
dfield_t* new_val;
- ulint field_no;
+ ulint j;
ulint i;
+ ut_ad(index);
+
dtuple_set_info_bits(entry, update->info_bits);
- for (i = 0; i < upd_get_n_fields(update); i++) {
+ for (j = 0; j < dict_index_get_n_fields(index); j++) {
- upd_field = upd_get_nth_field(update, i);
+ field = dict_index_get_nth_field(index, j);
- field_no = upd_field->field_no;
+ for (i = 0; i < upd_get_n_fields(update); i++) {
- dfield = dtuple_get_nth_field(entry, field_no);
+ upd_field = upd_get_nth_field(update, i);
- new_val = &(upd_field->new_val);
+ if (upd_field->field_no == field->col->clust_pos) {
+
+ dfield = dtuple_get_nth_field(entry, j);
+
+ new_val = &(upd_field->new_val);
- dfield_set_data(dfield, new_val->data, new_val->len);
+ dfield_set_data(dfield, new_val->data,
+ new_val->len);
+ if (heap && new_val->len != UNIV_SQL_NULL) {
+ dfield->data = mem_heap_alloc(heap,
+ new_val->len);
+ ut_memcpy(dfield->data, new_val->data,
+ new_val->len);
+ }
+
+ if (field->prefix_len > 0
+ && new_val->len != UNIV_SQL_NULL
+ && new_val->len > field->prefix_len) {
+
+ dfield->len = field->prefix_len;
+ }
+ }
+ }
}
}
@@ -884,7 +961,9 @@ row_upd_changes_ord_field_binary(
known when this function is called, e.g., at
compile time */
dict_index_t* index, /* in: index of the record */
- upd_t* update) /* in: update vector for the row */
+ upd_t* update) /* in: update vector for the row; NOTE: the
+ field numbers in this MUST be clustered index
+ positions! */
{
upd_field_t* upd_field;
dict_field_t* ind_field;
@@ -911,9 +990,15 @@ row_upd_changes_ord_field_binary(
upd_field = upd_get_nth_field(update, j);
+ /* Note that if the index field is a column prefix
+ then it may be that row does not contain an externally
+ stored part of the column value, and we cannot compare
+ the datas */
+
if (col_pos == upd_field->field_no
- && (row == NULL
- || !dfield_datas_are_binary_equal(
+ && (row == NULL
+ || ind_field->prefix_len > 0
+ || !dfield_datas_are_binary_equal(
dtuple_get_nth_field(row, col_no),
&(upd_field->new_val)))) {
return(TRUE);
@@ -957,6 +1042,55 @@ row_upd_changes_some_index_ord_field_binary(
return(FALSE);
}
+/***************************************************************
+Checks if an update vector changes some of the first ordering fields of an
+index record. This is only used in foreign key checks and we can assume
+that index does not contain column prefixes. */
+static
+ibool
+row_upd_changes_first_fields(
+/*=========================*/
+ /* out: TRUE if changes */
+ dtuple_t* entry, /* in: index entry */
+ dict_index_t* index, /* in: index of entry */
+ upd_t* update, /* in: update vector for the row */
+ ulint n) /* in: how many first fields to check */
+{
+ upd_field_t* upd_field;
+ dict_field_t* ind_field;
+ dict_col_t* col;
+ ulint n_upd_fields;
+ ulint col_pos;
+ ulint i, j;
+
+ ut_a(update && index);
+ ut_a(n <= dict_index_get_n_fields(index));
+
+ n_upd_fields = upd_get_n_fields(update);
+
+ for (i = 0; i < n; i++) {
+
+ ind_field = dict_index_get_nth_field(index, i);
+ col = dict_field_get_col(ind_field);
+ col_pos = dict_col_get_clust_pos(col);
+
+ for (j = 0; j < n_upd_fields; j++) {
+
+ upd_field = upd_get_nth_field(update, j);
+
+ if (col_pos == upd_field->field_no
+ && (ind_field->prefix_len > 0
+ || 0 != cmp_dfield_dfield(
+ dtuple_get_nth_field(entry, i),
+ &(upd_field->new_val)))) {
+ return(TRUE);
+ }
+ }
+ }
+
+ return(FALSE);
+}
+
/*************************************************************************
Copies the column values from a record. */
UNIV_INLINE
@@ -1110,9 +1244,11 @@ row_upd_sec_index_entry(
err = btr_cur_del_mark_set_sec_rec(0, btr_cur, TRUE,
thr, &mtr);
if (err == DB_SUCCESS && check_ref) {
+
/* NOTE that the following call loses
the position of pcur ! */
err = row_upd_check_references_constraints(
+ node,
&pcur, index->table,
index, thr, &mtr);
if (err != DB_SUCCESS) {
@@ -1135,7 +1271,7 @@ close_cur:
}
/* Build a new index entry */
- row_upd_index_replace_new_col_vals(entry, index, node->update);
+ row_upd_index_replace_new_col_vals(entry, index, node->update, NULL);
/* Insert new index entry */
err = row_ins_index_entry(index, entry, NULL, 0, thr);
@@ -1228,7 +1364,7 @@ row_upd_clust_rec_by_insert(
if (check_ref) {
/* NOTE that the following call loses
the position of pcur ! */
- err = row_upd_check_references_constraints(
+ err = row_upd_check_references_constraints(node,
pcur, table,
index, thr, mtr);
if (err != DB_SUCCESS) {
@@ -1248,12 +1384,12 @@ row_upd_clust_rec_by_insert(
entry = row_build_index_entry(node->row, index, heap);
- row_upd_clust_index_replace_new_col_vals(entry, node->update);
+ row_upd_index_replace_new_col_vals(entry, index, node->update, NULL);
row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id);
/* If we return from a lock wait, for example, we may have
- extern fields marked as not-owned in entry (marked if the
+ extern fields marked as not-owned in entry (marked in the
if-branch above). We must unmark them. */
btr_cur_unmark_dtuple_extern_fields(entry, node->ext_vec,
@@ -1396,7 +1532,8 @@ row_upd_del_mark_clust_rec(
if (err == DB_SUCCESS && check_ref) {
/* NOTE that the following call loses the position of pcur ! */
- err = row_upd_check_references_constraints(pcur, index->table,
+ err = row_upd_check_references_constraints(node,
+ pcur, index->table,
index, thr, mtr);
if (err != DB_SUCCESS) {
mtr_commit(mtr);
@@ -1632,9 +1769,9 @@ function_exit:
/* Do some cleanup */
if (node->row != NULL) {
- mem_heap_empty(node->heap);
node->row = NULL;
node->n_ext_vec = 0;
+ mem_heap_empty(node->heap);
}
node->state = UPD_NODE_UPDATE_CLUSTERED;
diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c
index baef6bca4ea..fca56389e45 100644
--- a/innobase/row/row0vers.c
+++ b/innobase/row/row0vers.c
@@ -27,6 +27,7 @@ Created 2/6/1997 Heikki Tuuri
#include "row0upd.h"
#include "rem0cmp.h"
#include "read0read.h"
+#include "lock0lock.h"
/*********************************************************************
Finds out if an active transaction has inserted or modified a secondary
@@ -58,7 +59,6 @@ row_vers_impl_x_locked_off_kernel(
ibool rec_del;
ulint err;
mtr_t mtr;
- char err_buf[1000];
ut_ad(mutex_own(&kernel_mutex));
ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
@@ -76,8 +76,20 @@ row_vers_impl_x_locked_off_kernel(
clust_rec = row_get_clust_rec(BTR_SEARCH_LEAF, rec, index,
&clust_index, &mtr);
if (!clust_rec) {
- mutex_enter(&kernel_mutex);
- mtr_commit(&mtr);
+ /* In a rare case it is possible that no clust rec is found
+ for a secondary index record: if in row0umod.c
+ row_undo_mod_remove_clust_low() we have already removed the
+ clust rec, while purge is still cleaning and removing
+ secondary index records associated with earlier versions of
+ the clustered index record. In that case there cannot be
+ any implicit lock on the secondary index record, because
+ an active transaction which has modified the secondary index
+ record has also modified the clustered index record. And in
+ a rollback we always undo the modifications to secondary index
+ records before the clustered index record. */
+
+ mutex_enter(&kernel_mutex);
+ mtr_commit(&mtr);
return(NULL);
}
@@ -97,9 +109,18 @@ row_vers_impl_x_locked_off_kernel(
return(NULL);
}
- /* We look up if some earlier version of the clustered index record
- would require rec to be in a different state (delete marked or
- unmarked, or not existing). If there is such a version, then rec was
+ if (!lock_check_trx_id_sanity(trx_id, clust_rec, clust_index, TRUE)) {
+ /* Corruption noticed: try to avoid a crash by returning */
+
+ mtr_commit(&mtr);
+
+ return(NULL);
+ }
+
+ /* We look up if some earlier version, which was modified by the trx_id
+ transaction, of the clustered index record would require rec to be in
+ a different state (delete marked or unmarked, or have different field
+ values, or not existing). If there is such a version, then rec was
modified by the trx_id transaction, and it has an implicit x-lock on
rec. Note that if clust_rec itself would require rec to be in a
different state, then the trx_id transaction has not yet had time to
@@ -163,10 +184,13 @@ row_vers_impl_x_locked_off_kernel(
/* If we get here, we know that the trx_id transaction is
still active and it has modified prev_version. Let us check
- if prev_version would require rec to be in a different state. */
+ if prev_version would require rec to be in a different
+ state. */
vers_del = rec_get_deleted_flag(prev_version);
+ /* We check if entry and rec are identified in the alphabetical
+ ordering */
if (0 == cmp_dtuple_rec(entry, rec)) {
/* The delete marks of rec and prev_version should be
equal for rec to be in the state required by
@@ -177,6 +201,20 @@ row_vers_impl_x_locked_off_kernel(
break;
}
+
+ /* It is possible that the row was updated so that the
+ secondary index record remained the same in
+ alphabetical ordering, but the field values changed
+ still. For example, 'abc' -> 'ABC'. Check also that. */
+
+ dtuple_set_types_binary(entry,
+ dtuple_get_n_fields(entry));
+ if (0 != cmp_dtuple_rec(entry, rec)) {
+
+ trx = trx_get_on_id(trx_id);
+
+ break;
+ }
} else if (!rec_del) {
/* The delete mark should be set in rec for it to be
in the state required by prev_version */
@@ -235,8 +273,8 @@ row_vers_must_preserve_del_marked(
Finds out if a version of the record, where the version >= the current
purge view, should have ientry as its secondary index entry. We check
if there is any not delete marked version of the record where the trx
-id >= purge view, and the secondary index entry == ientry; exactly in
-this case we return TRUE. */
+id >= purge view, and the secondary index entry and ientry are identified in
+the alphabetical ordering; exactly in this case we return TRUE. */
ibool
row_vers_old_has_index_entry(
diff --git a/innobase/srv/Makefile.am b/innobase/srv/Makefile.am
index b4bdeb7c03b..752683b82b8 100644
--- a/innobase/srv/Makefile.am
+++ b/innobase/srv/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libsrv.a
+noinst_LIBRARIES = libsrv.a
libsrv_a_SOURCES = srv0srv.c srv0que.c srv0start.c
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index ac2622df78a..8aba1b4f414 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -51,6 +51,10 @@ Created 10/8/1995 Heikki Tuuri
#include "srv0start.h"
#include "row0mysql.h"
+/* This is set to TRUE if the MySQL user has set it in MySQL; currently
+affects only FOREIGN KEY definition parsing */
+ibool srv_lower_case_table_names = FALSE;
+
/* Buffer which can be used in printing fatal error messages */
char srv_fatal_errbuf[5000];
@@ -61,7 +65,7 @@ ulint srv_activity_count = 0;
ibool srv_lock_timeout_and_monitor_active = FALSE;
ibool srv_error_monitor_active = FALSE;
-char* srv_main_thread_op_info = "";
+char* srv_main_thread_op_info = (char*) "";
/* Server parameters which are read from the initfile */
@@ -135,12 +139,10 @@ byte srv_latin1_ordering[256] /* The sort order table of the latin1
, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x5D, 0xF7
, 0xD8, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0xFF
};
-
-ibool srv_use_native_aio = FALSE;
ulint srv_pool_size = ULINT_MAX; /* size in database pages;
MySQL originally sets this
- value in megabytes */
+ value in bytes */
ulint srv_mem_pool_size = ULINT_MAX; /* size in bytes */
ulint srv_lock_table_size = ULINT_MAX;
@@ -151,14 +153,28 @@ dulint srv_archive_recovery_limit_lsn;
ulint srv_lock_wait_timeout = 1024 * 1024 * 1024;
-char* srv_unix_file_flush_method_str = NULL;
-ulint srv_unix_file_flush_method = 0;
+char* srv_file_flush_method_str = NULL;
+ulint srv_unix_file_flush_method = SRV_UNIX_FDATASYNC;
+ulint srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
+
+/* The InnoDB main thread tries to keep the ratio of modified pages
+in the buffer pool to all database pages in the buffer pool smaller than
+the following number. But it is not guaranteed that the value stays below
+that during a time of heavy update/insert activity. */
+
+ulint srv_max_buf_pool_modified_pct = 90;
/* If the following is != 0 we do not allow inserts etc. This protects
the user from forgetting the innodb_force_recovery keyword to my.cnf */
ulint srv_force_recovery = 0;
/*-----------------------*/
+/* We are prepared for a situation that we have this many threads waiting for
+a semaphore inside InnoDB. innobase_start_or_create_for_mysql() sets the
+value. */
+
+ulint srv_max_n_threads = 0;
+
/* The following controls how many threads we let inside InnoDB concurrently:
threads waiting for locks are not counted into the number because otherwise
we could get a deadlock. MySQL creates a thread for each user session, and
@@ -198,7 +214,7 @@ struct srv_conc_slot_struct{
UT_LIST_BASE_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue of threads
waiting to get in */
-srv_conc_slot_t srv_conc_slots[OS_THREAD_MAX_N]; /* array of wait
+srv_conc_slot_t* srv_conc_slots; /* array of wait
slots */
/* Number of times a thread is allowed to enter InnoDB within the same
@@ -238,6 +254,11 @@ ulint srv_n_rows_updated_old = 0;
ulint srv_n_rows_deleted_old = 0;
ulint srv_n_rows_read_old = 0;
+/*
+ Set the following to 0 if you want InnoDB to write messages on
+ stderr on startup/shutdown
+*/
+ibool srv_print_verbose_log = TRUE;
ibool srv_print_innodb_monitor = FALSE;
ibool srv_print_innodb_lock_monitor = FALSE;
ibool srv_print_innodb_tablespace_monitor = FALSE;
@@ -271,11 +292,15 @@ ulint srv_test_n_mutexes = ULINT_MAX;
i/o handler thread */
char* srv_io_thread_op_info[SRV_MAX_N_IO_THREADS];
+char* srv_io_thread_function[SRV_MAX_N_IO_THREADS];
time_t srv_last_monitor_time;
mutex_t srv_innodb_monitor_mutex;
+ulint srv_main_thread_process_no = 0;
+ulint srv_main_thread_id = 0;
+
/*
IMPLEMENTATION OF THE SERVER MAIN PROGRAM
=========================================
@@ -838,6 +863,7 @@ srv_release_max_if_no_queries(void)
mutex_exit(&kernel_mutex);
}
+#ifdef notdefined
/***********************************************************************
Releases one utility thread if no queries are active and
the high-water mark 2 for the utility is exceeded. */
@@ -872,7 +898,6 @@ srv_release_one_if_no_queries(void)
mutex_exit(&kernel_mutex);
}
-#ifdef notdefined
/***********************************************************************
Decrements the utility meter by the value given and suspends the calling
thread, which must be an utility thread of the type given, if necessary. */
@@ -982,6 +1007,8 @@ srv_communication_init(
ut_a(ret == 0);
}
+
+#ifdef notdefined
/*************************************************************************
Implements the recovery utility. */
@@ -1042,6 +1069,7 @@ srv_purge_thread(
return(0);
}
+#endif /* notdefined */
/*************************************************************************
Creates the utility threads. */
@@ -1072,6 +1100,7 @@ srv_create_utility_threads(void)
ut_a(thread); */
}
+#ifdef notdefined
/*************************************************************************
Implements the communication threads. */
static
@@ -1121,6 +1150,7 @@ srv_com_thread(
return(0);
}
+#endif
/*************************************************************************
Creates the communication threads. */
@@ -1141,6 +1171,7 @@ srv_create_com_threads(void)
}
}
+#ifdef notdefined
/*************************************************************************
Implements the worker threads. */
static
@@ -1185,6 +1216,7 @@ srv_worker_thread(
return(0);
}
+#endif
/*************************************************************************
Creates the worker threads. */
@@ -1629,6 +1661,7 @@ srv_init(void)
for (i = 0; i < OS_THREAD_MAX_N; i++) {
slot = srv_table_get_nth_slot(i);
slot->in_use = FALSE;
+ slot->type=0; /* Avoid purify errors */
slot->event = os_event_create(NULL);
ut_a(slot->event);
}
@@ -1666,6 +1699,8 @@ srv_init(void)
os_fast_mutex_init(&srv_conc_mutex);
UT_LIST_INIT(srv_conc_queue);
+
+ srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t));
for (i = 0; i < OS_THREAD_MAX_N; i++) {
conc_slot = srv_conc_slots + i;
@@ -1674,7 +1709,17 @@ srv_init(void)
ut_a(conc_slot->event);
}
}
-
+
+/*************************************************************************
+Frees the OS fast mutex created in srv_init(). */
+
+void
+srv_free(void)
+/*==========*/
+{
+ os_fast_mutex_free(&srv_conc_mutex);
+}
+
/*************************************************************************
Initializes the synchronization primitives, memory system, and the thread
local storage. */
@@ -1683,6 +1728,7 @@ void
srv_general_init(void)
/*==================*/
{
+ os_sync_init();
sync_init();
mem_init(srv_mem_pool_size);
thr_local_init();
@@ -1690,6 +1736,7 @@ srv_general_init(void)
/*======================= InnoDB Server FIFO queue =======================*/
+
/*************************************************************************
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
@@ -1700,9 +1747,10 @@ srv_conc_enter_innodb(
trx_t* trx) /* in: transaction object associated with the
thread */
{
- ibool has_slept = FALSE;
- srv_conc_slot_t* slot;
+ ibool has_slept = FALSE;
+ srv_conc_slot_t* slot = NULL;
ulint i;
+ char err_buf[1000];
if (srv_thread_concurrency >= 500) {
/* Disable the concurrency check */
@@ -1718,8 +1766,21 @@ srv_conc_enter_innodb(
return;
}
-retry:
+
os_fast_mutex_lock(&srv_conc_mutex);
+retry:
+ if (trx->declared_to_be_inside_innodb) {
+ ut_print_timestamp(stderr);
+
+ trx_print(err_buf, trx);
+
+ fprintf(stderr,
+" InnoDB: Error: trying to declare trx to enter InnoDB, but\n"
+"InnoDB: it already is declared.\n%s\n", err_buf);
+ os_fast_mutex_unlock(&srv_conc_mutex);
+
+ return;
+ }
if (srv_conc_n_threads < (lint)srv_thread_concurrency) {
@@ -1732,21 +1793,31 @@ retry:
return;
}
- /* If the transaction is not holding resources, let it sleep
- for 100 milliseconds, and try again then */
-
+ /* If the transaction is not holding resources, let it sleep for 50
+ milliseconds, and try again then */
+
if (!has_slept && !trx->has_search_latch
&& NULL == UT_LIST_GET_FIRST(trx->trx_locks)) {
- has_slept = TRUE; /* We let is sleep only once to avoid
- starvation */
+ has_slept = TRUE; /* We let is sleep only once to avoid
+ starvation */
+
+ srv_conc_n_waiting_threads++;
+
+ os_fast_mutex_unlock(&srv_conc_mutex);
+
+ trx->op_info = (char*)"sleeping before joining InnoDB queue";
- os_fast_mutex_unlock(&srv_conc_mutex);
+ os_thread_sleep(50000);
- os_thread_sleep(100000);
+ trx->op_info = (char*)"";
+
+ os_fast_mutex_lock(&srv_conc_mutex);
+
+ srv_conc_n_waiting_threads--;
goto retry;
- }
+ }
/* Too many threads inside: put the current thread to a queue */
@@ -1791,8 +1862,12 @@ retry:
/* Go to wait for the event; when a thread leaves InnoDB it will
release this thread */
+ trx->op_info = (char*)"waiting in InnoDB queue";
+
os_event_wait(slot->event);
+ trx->op_info = (char*)"";
+
os_fast_mutex_lock(&srv_conc_mutex);
srv_conc_n_waiting_threads--;
@@ -2040,13 +2115,15 @@ srv_table_reserve_slot_for_mysql(void)
}
/*******************************************************************
-Puts a MySQL OS thread to wait for a lock to be released. */
+Puts a MySQL OS thread to wait for a lock to be released. If an error
+occurs during the wait trx->error_state associated with thr is
+!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
+are possible errors. DB_DEADLOCK is returned if selective deadlock
+resolution chose this transaction as a victim. */
-ibool
+void
srv_suspend_mysql_thread(
/*=====================*/
- /* out: TRUE if the lock wait timeout was
- exceeded */
que_thr_t* thr) /* in: query thread associated with the MySQL
OS thread */
{
@@ -2054,6 +2131,8 @@ srv_suspend_mysql_thread(
os_event_t event;
double wait_time;
trx_t* trx;
+ ibool had_dict_lock = FALSE;
+ ibool was_declared_inside_innodb = FALSE;
ut_ad(!mutex_own(&kernel_mutex));
@@ -2063,15 +2142,28 @@ srv_suspend_mysql_thread(
mutex_enter(&kernel_mutex);
+ trx->error_state = DB_SUCCESS;
+
if (thr->state == QUE_THR_RUNNING) {
- /* The lock has already been released: no need to suspend */
+ ut_ad(thr->is_active == TRUE);
+
+ /* The lock has already been released or this transaction
+ was chosen as a deadlock victim: no need to suspend */
+
+ if (trx->was_chosen_as_deadlock_victim) {
+
+ trx->error_state = DB_DEADLOCK;
+ trx->was_chosen_as_deadlock_victim = FALSE;
+ }
mutex_exit(&kernel_mutex);
- return(FALSE);
+ return;
}
+ ut_ad(thr->is_active == FALSE);
+
slot = srv_table_reserve_slot_for_mysql();
event = slot->event;
@@ -2088,30 +2180,42 @@ srv_suspend_mysql_thread(
mutex_exit(&kernel_mutex);
- /* We must declare this OS thread to exit InnoDB, since a possible
- other thread holding a lock which this thread waits for must be
- allowed to enter, sooner or later */
+ if (trx->declared_to_be_inside_innodb) {
+
+ was_declared_inside_innodb = TRUE;
+
+ /* We must declare this OS thread to exit InnoDB, since a
+ possible other thread holding a lock which this thread waits
+ for must be allowed to enter, sooner or later */
- srv_conc_force_exit_innodb(thr_get_trx(thr));
+ srv_conc_force_exit_innodb(trx);
+ }
/* Release possible foreign key check latch */
- if (trx->has_dict_foreign_key_check_lock) {
+ if (trx->dict_operation_lock_mode == RW_S_LATCH) {
+
+ had_dict_lock = TRUE;
- rw_lock_s_unlock(&dict_foreign_key_check_lock);
+ row_mysql_unfreeze_data_dictionary(trx);
}
+ ut_a(trx->dict_operation_lock_mode == 0);
+
/* Wait for the release */
os_event_wait(event);
- if (trx->has_dict_foreign_key_check_lock) {
+ if (had_dict_lock) {
- rw_lock_s_lock(&dict_foreign_key_check_lock);
+ row_mysql_freeze_data_dictionary(trx);
}
- /* Return back inside InnoDB */
+ if (was_declared_inside_innodb) {
+
+ /* Return back inside InnoDB */
- srv_conc_force_enter_innodb(thr_get_trx(thr));
+ srv_conc_force_enter_innodb(trx);
+ }
mutex_enter(&kernel_mutex);
@@ -2121,14 +2225,19 @@ srv_suspend_mysql_thread(
wait_time = ut_difftime(ut_time(), slot->suspend_time);
+ if (trx->was_chosen_as_deadlock_victim) {
+
+ trx->error_state = DB_DEADLOCK;
+ trx->was_chosen_as_deadlock_victim = FALSE;
+ }
+
mutex_exit(&kernel_mutex);
if (srv_lock_wait_timeout < 100000000 &&
wait_time > (double)srv_lock_wait_timeout) {
- return(TRUE);
- }
- return(FALSE);
+ trx->error_state = DB_LOCK_WAIT_TIMEOUT;
+ }
}
/************************************************************************
@@ -2202,6 +2311,7 @@ srv_sprintf_innodb_monitor(
char* buf_end = buf + len - 2000;
double time_elapsed;
time_t current_time;
+ ulint n_reserved;
mutex_enter(&srv_innodb_monitor_mutex);
@@ -2239,12 +2349,35 @@ srv_sprintf_innodb_monitor(
buf = buf + strlen(buf);
ut_a(buf < buf_end + 1500);
- buf += sprintf(buf, "------------\n"
- "TRANSACTIONS\n"
- "------------\n");
+ if (*dict_foreign_err_buf != '\0') {
+ buf += sprintf(buf,
+ "------------------------\n"
+ "LATEST FOREIGN KEY ERROR\n"
+ "------------------------\n");
+
+ if (buf_end - buf > 6000) {
+ buf+= sprintf(buf, "%.4000s", dict_foreign_err_buf);
+ }
+ }
+
+ ut_a(buf < buf_end + 1500);
+
+ if (*dict_unique_err_buf != '\0') {
+ buf += sprintf(buf,
+"---------------------------------------------------------------\n"
+"LATEST UNIQUE KEY ERROR (is masked in REPLACE or INSERT IGNORE)\n"
+"---------------------------------------------------------------\n");
+
+ if (buf_end - buf > 6000) {
+ buf+= sprintf(buf, "%.4000s", dict_unique_err_buf);
+ }
+ }
+
+ ut_a(buf < buf_end + 1500);
+
lock_print_info(buf, buf_end);
buf = buf + strlen(buf);
-
+
buf += sprintf(buf, "--------\n"
"FILE I/O\n"
"--------\n");
@@ -2294,9 +2427,28 @@ srv_sprintf_innodb_monitor(
"ROW OPERATIONS\n"
"--------------\n");
buf += sprintf(buf,
- "%ld queries inside InnoDB, %ld queries in queue; main thread: %s\n",
- srv_conc_n_threads, srv_conc_n_waiting_threads,
+ "%ld queries inside InnoDB, %lu queries in queue\n",
+ srv_conc_n_threads, srv_conc_n_waiting_threads);
+
+ n_reserved = fil_space_get_n_reserved_extents(0);
+ if (n_reserved > 0) {
+ buf += sprintf(buf,
+ "%lu tablespace extents now reserved for B-tree split operations\n",
+ n_reserved);
+ }
+
+#ifdef UNIV_LINUX
+ buf += sprintf(buf,
+ "Main thread process no. %lu, id %lu, state: %s\n",
+ srv_main_thread_process_no,
+ srv_main_thread_id,
+ srv_main_thread_op_info);
+#else
+ buf += sprintf(buf,
+ "Main thread id %lu, state: %s\n",
+ srv_main_thread_id,
srv_main_thread_op_info);
+#endif
buf += sprintf(buf,
"Number of rows inserted %lu, updated %lu, deleted %lu, read %lu\n",
srv_n_rows_inserted,
@@ -2352,6 +2504,10 @@ srv_lock_timeout_and_monitor_thread(
char* buf;
ulint i;
+#ifdef UNIV_DEBUG_THREAD_CREATION
+ printf("Lock timeout thread starts, id %lu\n",
+ os_thread_pf(os_thread_get_curr_id()));
+#endif
UT_NOT_USED(arg);
srv_last_monitor_time = time(NULL);
last_table_monitor_time = time(NULL);
@@ -2492,6 +2648,10 @@ loop:
exit_func:
srv_lock_timeout_and_monitor_active = FALSE;
+ /* We count the number of threads in os_thread_exit(). A created
+ thread should always use that to exit and not use return() to exit. */
+
+ os_thread_exit(NULL);
#ifndef __WIN__
return(NULL);
#else
@@ -2517,6 +2677,10 @@ srv_error_monitor_thread(
ulint cnt = 0;
UT_NOT_USED(arg);
+#ifdef UNIV_DEBUG_THREAD_CREATION
+ printf("Error monitor thread starts, id %lu\n",
+ os_thread_pf(os_thread_get_curr_id()));
+#endif
loop:
srv_error_monitor_active = TRUE;
@@ -2553,6 +2717,11 @@ loop:
srv_error_monitor_active = FALSE;
+ /* We count the number of threads in os_thread_exit(). A created
+ thread should always use that to exit and not use return() to exit. */
+
+ os_thread_exit(NULL);
+
#ifndef __WIN__
return(NULL);
#else
@@ -2626,10 +2795,18 @@ srv_master_thread(
ulint n_ios_old;
ulint n_ios_very_old;
ulint n_pend_ios;
+ ibool skip_sleep = FALSE;
ulint i;
UT_NOT_USED(arg);
+#ifdef UNIV_DEBUG_THREAD_CREATION
+ printf("Master thread starts, id %lu\n",
+ os_thread_pf(os_thread_get_curr_id()));
+#endif
+ srv_main_thread_process_no = os_proc_get_number();
+ srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
+
srv_table_reserve_slot(SRV_MASTER);
mutex_enter(&kernel_mutex);
@@ -2640,24 +2817,42 @@ srv_master_thread(
os_event_set(srv_sys->operational);
loop:
- srv_main_thread_op_info = "reserving kernel mutex";
+ /*****************************************************************/
+ /* ---- When there is database activity by users, we cycle in this
+ loop */
+
+ srv_main_thread_op_info = (char*) "reserving kernel mutex";
n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
mutex_enter(&kernel_mutex);
+ /* Store the user activity counter at the start of this loop */
old_activity_count = srv_activity_count;
mutex_exit(&kernel_mutex);
- /* We run purge and a batch of ibuf_contract every 10 seconds, even
- if the server were active: */
+ if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) {
+
+ goto suspend_thread;
+ }
+
+ /* ---- We run the following loop approximately once per second
+ when there is database activity */
+
+ skip_sleep = FALSE;
for (i = 0; i < 10; i++) {
n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
srv_main_thread_op_info = (char*)"sleeping";
- os_thread_sleep(1000000);
+
+ if (!skip_sleep) {
+
+ os_thread_sleep(1000000);
+ }
+
+ skip_sleep = FALSE;
/* ALTER TABLE in MySQL requires on Unix that the table handler
can drop tables lazily after there no longer are SELECT
@@ -2670,9 +2865,9 @@ loop:
srv_main_thread_op_info = (char*)"";
- if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) {
+ if (srv_fast_shutdown && srv_shutdown_state > 0) {
- goto suspend_thread;
+ goto background_loop;
}
/* We flush the log once in a second even if no commit
@@ -2680,10 +2875,9 @@ loop:
at transaction commit */
srv_main_thread_op_info = (char*)"flushing log";
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
- log_flush_to_disk();
+ log_buffer_flush_to_disk();
- /* If there were less than 10 i/os during the
+ /* If there were less than 5 i/os during the
one second sleep, we assume that there is free
disk i/o capacity available, and it makes sense to
do an insert buffer merge. */
@@ -2692,35 +2886,44 @@ loop:
+ log_sys->n_pending_writes;
n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
- if (n_pend_ios < 3 && (n_ios - n_ios_old < 10)) {
+ if (n_pend_ios < 3 && (n_ios - n_ios_old < 5)) {
srv_main_thread_op_info =
(char*)"doing insert buffer merge";
ibuf_contract_for_n_pages(TRUE, 5);
- srv_main_thread_op_info =
- (char*)"flushing log";
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
- log_flush_to_disk();
+ srv_main_thread_op_info = (char*)"flushing log";
+
+ log_buffer_flush_to_disk();
}
-
- if (srv_fast_shutdown && srv_shutdown_state > 0) {
- goto background_loop;
+ if (buf_get_modified_ratio_pct() >
+ srv_max_buf_pool_modified_pct) {
+
+ /* Try to keep the number of modified pages in the
+ buffer pool under the limit wished by the user */
+
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
+ ut_dulint_max);
+
+ /* If we had to do the flush, it may have taken
+ even more than 1 second, and also, there may be more
+ to flush. Do not sleep 1 second during the next
+ iteration of this loop. */
+
+ skip_sleep = TRUE;
}
if (srv_activity_count == old_activity_count) {
- if (srv_print_thread_releases) {
- printf("Master thread wakes up!\n");
- }
+ /* There is no user activity at the moment, go to
+ the background loop */
goto background_loop;
}
}
- if (srv_print_thread_releases) {
- printf("Master thread wakes up!\n");
- }
+ /* ---- We perform the following code approximately once per
+ 10 seconds when there is database activity */
#ifdef MEM_PERIODIC_CHECK
/* Check magic numbers of every allocated mem block once in 10
@@ -2729,19 +2932,18 @@ loop:
#endif
/* If there were less than 200 i/os during the 10 second period,
we assume that there is free disk i/o capacity available, and it
- makes sense to do a buffer pool flush. */
+ makes sense to flush 100 pages. */
n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
if (n_pend_ios < 3 && (n_ios - n_ios_very_old < 200)) {
- srv_main_thread_op_info = "flushing buffer pool pages";
- buf_flush_batch(BUF_FLUSH_LIST, 50, ut_dulint_max);
+ srv_main_thread_op_info = (char*) "flushing buffer pool pages";
+ buf_flush_batch(BUF_FLUSH_LIST, 100, ut_dulint_max);
- srv_main_thread_op_info = "flushing log";
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
- log_flush_to_disk();
+ srv_main_thread_op_info = (char*) "flushing log";
+ log_buffer_flush_to_disk();
}
/* We run a batch of insert buffer merge every 10 seconds,
@@ -2751,8 +2953,7 @@ loop:
ibuf_contract_for_n_pages(TRUE, 5);
srv_main_thread_op_info = (char*)"flushing log";
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
- log_flush_to_disk();
+ log_buffer_flush_to_disk();
/* We run a full purge every 10 seconds, even if the server
were active */
@@ -2774,39 +2975,34 @@ loop:
current_time = time(NULL);
if (difftime(current_time, last_flush_time) > 1) {
- srv_main_thread_op_info = "flushing log";
+ srv_main_thread_op_info = (char*) "flushing log";
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
- log_flush_to_disk();
+ log_buffer_flush_to_disk();
last_flush_time = current_time;
}
}
+
+ srv_main_thread_op_info = (char*)"flushing buffer pool pages";
-background_loop:
- /* In this loop we run background operations when the server
- is quiet and we also come here about once in 10 seconds */
+ /* Flush a few oldest pages to make a new checkpoint younger */
- srv_main_thread_op_info = (char*)"doing background drop tables";
+ if (buf_get_modified_ratio_pct() > 70) {
- n_tables_to_drop = row_drop_tables_for_mysql_in_background();
+ /* If there are lots of modified pages in the buffer pool
+ (> 70 %), we assume we can afford reserving the disk(s) for
+ the time it requires to flush 100 pages */
- if (n_tables_to_drop > 0) {
- /* Do not monopolize the CPU even if there are tables waiting
- in the background drop queue. (It is essentially a bug if
- MySQL tries to drop a table while there are still open handles
- to it and we had to put it to the background drop queue.) */
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
+ ut_dulint_max);
+ } else {
+ /* Otherwise, we only flush a small number of pages so that
+ we do not unnecessarily use much disk i/o capacity from
+ other work */
- os_thread_sleep(100000);
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10,
+ ut_dulint_max);
}
- srv_main_thread_op_info = (char*)"";
-
- srv_main_thread_op_info = (char*)"flushing buffer pool pages";
-
- /* Flush a few oldest pages to make the checkpoint younger */
-
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10, ut_dulint_max);
-
srv_main_thread_op_info = (char*)"making checkpoint";
/* Make a new checkpoint about once in 10 seconds */
@@ -2816,22 +3012,65 @@ background_loop:
srv_main_thread_op_info = (char*)"reserving kernel mutex";
mutex_enter(&kernel_mutex);
+
+ /* ---- When there is database activity, we jump from here back to
+ the start of loop */
+
if (srv_activity_count != old_activity_count) {
mutex_exit(&kernel_mutex);
goto loop;
}
- old_activity_count = srv_activity_count;
+
mutex_exit(&kernel_mutex);
+ /* If the database is quiet, we enter the background loop */
+
+ /*****************************************************************/
+background_loop:
+ /* ---- In this loop we run background operations when the server
+ is quiet from user activity */
+
/* The server has been quiet for a while: start running background
operations */
+ srv_main_thread_op_info = (char*)"doing background drop tables";
+
+ n_tables_to_drop = row_drop_tables_for_mysql_in_background();
+
+ if (n_tables_to_drop > 0) {
+ /* Do not monopolize the CPU even if there are tables waiting
+ in the background drop queue. (It is essentially a bug if
+ MySQL tries to drop a table while there are still open handles
+ to it and we had to put it to the background drop queue.) */
+
+ os_thread_sleep(100000);
+ }
+
srv_main_thread_op_info = (char*)"purging";
- if (srv_fast_shutdown && srv_shutdown_state > 0) {
- n_pages_purged = 0;
- } else {
- n_pages_purged = trx_purge();
+ /* Run a full purge */
+
+ n_pages_purged = 1;
+
+ last_flush_time = time(NULL);
+
+ while (n_pages_purged) {
+ if (srv_fast_shutdown && srv_shutdown_state > 0) {
+
+ break;
+ }
+
+ srv_main_thread_op_info = (char*)"purging";
+ n_pages_purged = trx_purge();
+
+ current_time = time(NULL);
+
+ if (difftime(current_time, last_flush_time) > 1) {
+ srv_main_thread_op_info = (char*) "flushing log";
+
+ log_buffer_flush_to_disk();
+ last_flush_time = current_time;
+ }
}
srv_main_thread_op_info = (char*)"reserving kernel mutex";
@@ -2860,6 +3099,7 @@ background_loop:
}
mutex_exit(&kernel_mutex);
+flush_loop:
srv_main_thread_op_info = (char*)"flushing buffer pool pages";
n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100, ut_dulint_max);
@@ -2872,13 +3112,26 @@ background_loop:
}
mutex_exit(&kernel_mutex);
- srv_main_thread_op_info = "waiting for buffer pool flush to end";
+ srv_main_thread_op_info =
+ (char*) "waiting for buffer pool flush to end";
buf_flush_wait_batch_end(BUF_FLUSH_LIST);
+ srv_main_thread_op_info = (char*) "flushing log";
+
+ log_buffer_flush_to_disk();
+
srv_main_thread_op_info = (char*)"making checkpoint";
log_checkpoint(TRUE, FALSE);
+ if (buf_get_modified_ratio_pct() > srv_max_buf_pool_modified_pct) {
+
+ /* Try to keep the number of modified pages in the
+ buffer pool under the limit wished by the user */
+
+ goto flush_loop;
+ }
+
srv_main_thread_op_info = (char*)"reserving kernel mutex";
mutex_enter(&kernel_mutex);
@@ -2893,15 +3146,24 @@ background_loop:
log_archive_do(FALSE, &n_bytes_archived);
+ /* Keep looping in the background loop if still work to do */
+
if (srv_fast_shutdown && srv_shutdown_state > 0) {
if (n_tables_to_drop + n_pages_flushed
+ n_bytes_archived != 0) {
+ /* If we are doing a fast shutdown (= the default)
+ we do not do purge or insert buffer merge. But we
+ flush the buffer pool completely to disk. */
+
goto background_loop;
}
} else if (n_tables_to_drop +
- n_pages_purged + n_bytes_merged + n_pages_flushed
+ n_pages_purged + n_bytes_merged + n_pages_flushed
+ n_bytes_archived != 0) {
+ /* In a 'slow' shutdown we run purge and the insert buffer
+ merge to completion */
+
goto background_loop;
}
@@ -2933,8 +3195,25 @@ suspend_thread:
os_event_wait(event);
+ if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ /* This is only extra safety, the thread should exit
+ already when the event wait ends */
+
+ os_thread_exit(NULL);
+ }
+
+ /* When there is user activity, InnoDB will set the event and the main
+ thread goes back to loop: */
+
goto loop;
+ /* We count the number of threads in os_thread_exit(). A created
+ thread should always use that to exit and not use return() to exit.
+ The thread actually never comes here because it is exited in an
+ os_event_wait(). */
+
+ os_thread_exit(NULL);
+
#ifndef __WIN__
return(NULL);
#else
diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
index ea0ed7c961e..8ff2076d5d1 100644
--- a/innobase/srv/srv0start.c
+++ b/innobase/srv/srv0start.c
@@ -56,6 +56,10 @@ Created 2/16/1996 Heikki Tuuri
#include "srv0start.h"
#include "que0que.h"
+ibool srv_start_has_been_called = FALSE;
+
+ulint srv_sizeof_trx_t_in_ha_innodb_cc;
+
ibool srv_startup_is_before_trx_rollback_phase = FALSE;
ibool srv_is_being_started = FALSE;
ibool srv_was_started = FALSE;
@@ -157,13 +161,13 @@ srv_parse_data_file_paths_and_sizes(
}
if (strlen(str) >= ut_strlen(":autoextend")
- && 0 == ut_memcmp(str, ":autoextend",
+ && 0 == ut_memcmp(str, (char*)":autoextend",
ut_strlen(":autoextend"))) {
str += ut_strlen(":autoextend");
if (strlen(str) >= ut_strlen(":max:")
- && 0 == ut_memcmp(str, ":max:",
+ && 0 == ut_memcmp(str, (char*)":max:",
ut_strlen(":max:"))) {
str += ut_strlen(":max:");
@@ -261,7 +265,7 @@ srv_parse_data_file_paths_and_sizes(
(*data_file_sizes)[i] = size;
if (strlen(str) >= ut_strlen(":autoextend")
- && 0 == ut_memcmp(str, ":autoextend",
+ && 0 == ut_memcmp(str, (char*)":autoextend",
ut_strlen(":autoextend"))) {
*is_auto_extending = TRUE;
@@ -269,7 +273,7 @@ srv_parse_data_file_paths_and_sizes(
str += ut_strlen(":autoextend");
if (strlen(str) >= ut_strlen(":max:")
- && 0 == ut_memcmp(str, ":max:",
+ && 0 == ut_memcmp(str, (char*)":max:",
ut_strlen(":max:"))) {
str += ut_strlen(":max:");
@@ -410,8 +414,10 @@ io_handler_thread(
segment = *((ulint*)arg);
-/* printf("Io handler thread %lu starts\n", segment); */
-
+#ifdef UNIV_DEBUG_THREAD_CREATION
+ printf("Io handler thread %lu starts, id %lu\n", segment,
+ os_thread_pf(os_thread_get_curr_id()));
+#endif
for (i = 0;; i++) {
fil_aio_wait(segment);
@@ -420,6 +426,13 @@ io_handler_thread(
mutex_exit(&ios_mutex);
}
+ /* We count the number of threads in os_thread_exit(). A created
+ thread should always use that to exit and not use return() to exit.
+ The thread actually never comes here because it is exited in an
+ os_event_wait(). */
+
+ os_thread_exit(NULL);
+
#ifndef __WIN__
return(NULL);
#else
@@ -439,7 +452,7 @@ Normalizes a directory path for Windows: converts slashes to backslashes. */
void
srv_normalize_path_for_win(
/*=======================*/
- char* str) /* in/out: null-terminated character string */
+ char* str __attribute__((unused))) /* in/out: null-terminated character string */
{
#ifdef __WIN__
ulint i;
@@ -515,7 +528,7 @@ srv_calc_high32(
}
/*************************************************************************
-Creates or opens the log files. */
+Creates or opens the log files and closes them. */
static
ulint
open_or_create_log_file(
@@ -525,6 +538,9 @@ open_or_create_log_file(
new database */
ibool* log_file_created, /* out: TRUE if new log file
created */
+ ibool log_file_has_been_opened,/* in: TRUE if a log file has been
+ opened before: then it is an error
+ to try to create another log file */
ulint k, /* in: log group number */
ulint i) /* in: log file number in group */
{
@@ -570,19 +586,27 @@ open_or_create_log_file(
|| size_high != srv_calc_high32(srv_log_file_size)) {
fprintf(stderr,
- "InnoDB: Error: log file %s is of different size\n"
- "InnoDB: than specified in the .cnf file!\n", name);
+"InnoDB: Error: log file %s is of different size %lu %lu bytes\n"
+"InnoDB: than specified in the .cnf file %lu %lu bytes!\n",
+ name, size_high, size,
+ srv_calc_high32(srv_log_file_size),
+ srv_calc_low32(srv_log_file_size));
return(DB_ERROR);
}
} else {
*log_file_created = TRUE;
-
+
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Log file %s did not exist: new to be created\n",
name);
+ if (log_file_has_been_opened) {
+
+ return(DB_ERROR);
+ }
+
fprintf(stderr, "InnoDB: Setting log file %s size to %lu MB\n",
name, srv_log_file_size
>> (20 - UNIV_PAGE_SIZE_SHIFT));
@@ -624,7 +648,7 @@ open_or_create_log_file(
if (k == 0 && i == 0) {
arch_space_id = 2 * k + 1 + SRV_LOG_SPACE_FIRST_ID;
- fil_space_create("arch_log_space", arch_space_id, FIL_LOG);
+ fil_space_create((char*) "arch_log_space", arch_space_id, FIL_LOG);
} else {
arch_space_id = ULINT_UNDEFINED;
}
@@ -640,7 +664,7 @@ open_or_create_log_file(
}
/*************************************************************************
-Creates or opens database data files. */
+Creates or opens database data files and closes them. */
static
ulint
open_or_create_data_files(
@@ -758,8 +782,13 @@ open_or_create_data_files(
rounded_size_pages)) {
fprintf(stderr,
- "InnoDB: Error: data file %s is of a different size\n"
- "InnoDB: than specified in the .cnf file!\n", name);
+"InnoDB: Error: auto-extending data file %s is of a different size\n"
+"InnoDB: %lu pages (rounded down to MB) than specified in the .cnf file:\n"
+"InnoDB: initial %lu pages, max %lu (relevant if non-zero) pages!\n",
+ name, rounded_size_pages,
+ srv_data_file_sizes[i], srv_last_file_size_max);
+
+ return(DB_ERROR);
}
srv_data_file_sizes[i] =
@@ -770,8 +799,11 @@ open_or_create_data_files(
!= srv_data_file_sizes[i]) {
fprintf(stderr,
- "InnoDB: Error: data file %s is of a different size\n"
- "InnoDB: than specified in the .cnf file!\n", name);
+"InnoDB: Error: data file %s is of a different size\n"
+"InnoDB: %lu pages (rounded down to MB)\n"
+"InnoDB: than specified in the .cnf file %lu pages!\n", name,
+ rounded_size_pages,
+ srv_data_file_sizes[i]);
return(DB_ERROR);
}
@@ -841,6 +873,7 @@ open_or_create_data_files(
return(DB_SUCCESS);
}
+#ifdef notdefined
/*********************************************************************
This thread is used to measure contention of latches. */
static
@@ -912,6 +945,7 @@ test_measure_cont(
return(0);
}
+#endif
/********************************************************************
Starts InnoDB and creates a new database if database files
@@ -960,36 +994,121 @@ innobase_start_or_create_for_mysql(void)
"InnoDB: !!!!!!!!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!!!!!!!\n");
#endif
+ if (srv_sizeof_trx_t_in_ha_innodb_cc != (ulint)sizeof(trx_t)) {
+ fprintf(stderr,
+ "InnoDB: Error: trx_t size is %lu in ha_innodb.cc but %lu in srv0start.c\n"
+ "InnoDB: Check that pthread_mutex_t is defined in the same way in these\n"
+ "InnoDB: compilation modules. Cannot continue.\n",
+ srv_sizeof_trx_t_in_ha_innodb_cc, (ulint)sizeof(trx_t));
+ return(DB_ERROR);
+ }
+
+ /* Since InnoDB does not currently clean up all its internal data
+ structures in MySQL Embedded Server Library server_end(), we
+ print an error message if someone tries to start up InnoDB a
+ second time during the process lifetime. */
+
+ if (srv_start_has_been_called) {
+ fprintf(stderr,
+"InnoDB: Error:startup called second time during the process lifetime.\n"
+"InnoDB: In the MySQL Embedded Server Library you cannot call server_init()\n"
+"InnoDB: more than once during the process lifetime.\n");
+ }
+
+ srv_start_has_been_called = TRUE;
+
log_do_write = TRUE;
/* yydebug = TRUE; */
srv_is_being_started = TRUE;
srv_startup_is_before_trx_rollback_phase = TRUE;
+ os_aio_use_native_aio = FALSE;
+
+#ifdef __WIN__
+ if (os_get_os_version() == OS_WIN95
+ || os_get_os_version() == OS_WIN31
+ || os_get_os_version() == OS_WINNT) {
+
+ /* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
+ and NT use simulated aio. In NT Windows provides async i/o,
+ but when run in conjunction with InnoDB Hot Backup, it seemed
+ to corrupt the data files. */
+
+ os_aio_use_native_aio = FALSE;
+ } else {
+ /* On Win 2000 and XP use async i/o */
+ os_aio_use_native_aio = TRUE;
+ }
+#endif
+ if (srv_file_flush_method_str == NULL) {
+ /* These are the default options */
+
+ srv_unix_file_flush_method = SRV_UNIX_FDATASYNC;
- if (0 == ut_strcmp(srv_unix_file_flush_method_str, "fdatasync")) {
+ srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
+#ifndef __WIN__
+ } else if (0 == ut_strcmp(srv_file_flush_method_str,
+ (char*)"fdatasync")) {
srv_unix_file_flush_method = SRV_UNIX_FDATASYNC;
- } else if (0 == ut_strcmp(srv_unix_file_flush_method_str, "O_DSYNC")) {
+ } else if (0 == ut_strcmp(srv_file_flush_method_str,
+ (char*)"O_DSYNC")) {
srv_unix_file_flush_method = SRV_UNIX_O_DSYNC;
- } else if (0 == ut_strcmp(srv_unix_file_flush_method_str,
- "littlesync")) {
+ } else if (0 == ut_strcmp(srv_file_flush_method_str,
+ (char*)"O_DIRECT")) {
+ srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
+
+ } else if (0 == ut_strcmp(srv_file_flush_method_str,
+ (char*)"littlesync")) {
srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
- } else if (0 == ut_strcmp(srv_unix_file_flush_method_str, "nosync")) {
+ } else if (0 == ut_strcmp(srv_file_flush_method_str,
+ (char*)"nosync")) {
srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
+#else
+ } else if (0 == ut_strcmp(srv_file_flush_method_str,
+ (char*)"normal")) {
+ srv_win_file_flush_method = SRV_WIN_IO_NORMAL;
+ os_aio_use_native_aio = FALSE;
+
+ } else if (0 == ut_strcmp(srv_file_flush_method_str, "unbuffered")) {
+ srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
+ os_aio_use_native_aio = FALSE;
+
+ } else if (0 == ut_strcmp(srv_file_flush_method_str,
+ "async_unbuffered")) {
+ srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
+#endif
} else {
fprintf(stderr,
"InnoDB: Unrecognized value %s for innodb_flush_method\n",
- srv_unix_file_flush_method_str);
+ srv_file_flush_method_str);
return(DB_ERROR);
}
- /*
- printf("srv_unix set to %lu\n", srv_unix_file_flush_method);
- */
- os_aio_use_native_aio = srv_use_native_aio;
+ /* Set the maximum number of threads which can wait for a semaphore
+ inside InnoDB */
+#if defined(__WIN__) || defined(__NETWARE__)
+/* Create less event semaphores because Win 98/ME had difficulty creating
+40000 event semaphores.
+Comment from Novell, Inc.: also, these just take a lot of memory on
+NetWare. */
+ srv_max_n_threads = 1000;
+#else
+ if (srv_pool_size >= 8 * 1024 * 1024) {
+ /* Here we still have srv_pool_size counted
+ in bytes, srv_boot converts the value to
+ pages; if buffer pool is less than 8 MB,
+ assume fewer threads. */
+ srv_max_n_threads = 10000;
+ } else {
+ srv_max_n_threads = 1000; /* saves several MB of memory,
+ especially in 64-bit
+ computers */
+ }
+#endif
err = srv_boot();
if (err != DB_SUCCESS) {
@@ -999,34 +1118,15 @@ innobase_start_or_create_for_mysql(void)
/* Restrict the maximum number of file i/o threads */
if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) {
+
srv_n_file_io_threads = SRV_MAX_N_IO_THREADS;
}
-#if !(defined(WIN_ASYNC_IO) || defined(POSIX_ASYNC_IO))
- /* In simulated aio we currently have use only for 4 threads */
-
- os_aio_use_native_aio = FALSE;
-
- srv_n_file_io_threads = 4;
-#endif
-
-#ifdef __WIN__
- if (os_get_os_version() == OS_WIN95
- || os_get_os_version() == OS_WIN31) {
+ if (!os_aio_use_native_aio) {
+ /* In simulated aio we currently have use only for 4 threads */
- /* On Win 95, 98, ME, and Win32 subsystem for Windows 3.1 use
- simulated aio */
+ srv_n_file_io_threads = 4;
- os_aio_use_native_aio = FALSE;
- srv_n_file_io_threads = 4;
- } else {
- /* On NT and Win 2000 always use aio */
- os_aio_use_native_aio = TRUE;
- }
-#endif
- os_aio_use_native_aio = FALSE;
-
- if (!os_aio_use_native_aio) {
os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD
* srv_n_file_io_threads,
srv_n_file_io_threads,
@@ -1047,15 +1147,6 @@ innobase_start_or_create_for_mysql(void)
lock_sys_create(srv_lock_table_size);
-#ifdef POSIX_ASYNC_IO
- if (os_aio_use_native_aio) {
- /* There is only one thread per async io array:
- one for ibuf i/o, one for log i/o, one for ordinary reads,
- one for ordinary writes; we need only 4 i/o threads */
-
- srv_n_file_io_threads = 4;
- }
-#endif
/* Create i/o-handler threads: */
for (i = 0; i < srv_n_file_io_threads; i++) {
@@ -1107,7 +1198,14 @@ innobase_start_or_create_for_mysql(void)
&max_flushed_lsn, &max_arch_log_no,
&sum_of_new_sizes);
if (err != DB_SUCCESS) {
- fprintf(stderr, "InnoDB: Could not open data files\n");
+ fprintf(stderr,
+"InnoDB: Could not open or create data files.\n"
+"InnoDB: If you tried to add new data files, and it failed here,\n"
+"InnoDB: you should now edit innodb_data_file_path in my.cnf back\n"
+"InnoDB: to what it was, and remove the new ibdata files InnoDB created\n"
+"InnoDB: in this failed attempt. InnoDB only wrote those files full of\n"
+"InnoDB: zeros, but did not yet use them in any way. But be careful: do not\n"
+"InnoDB: remove old data files which contain your precious data!\n");
return((int) err);
}
@@ -1118,7 +1216,10 @@ innobase_start_or_create_for_mysql(void)
and restore them from the doublewrite buffer if
possible */
- trx_sys_doublewrite_restore_corrupt_pages();
+ if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
+
+ trx_sys_doublewrite_restore_corrupt_pages();
+ }
}
srv_normalize_path_for_win(srv_arch_dir);
@@ -1129,7 +1230,8 @@ innobase_start_or_create_for_mysql(void)
for (i = 0; i < srv_n_log_files; i++) {
err = open_or_create_log_file(create_new_db,
- &log_file_created, k, i);
+ &log_file_created,
+ log_opened, k, i);
if (err != DB_SUCCESS) {
return((int) err);
@@ -1365,7 +1467,7 @@ innobase_start_or_create_for_mysql(void)
if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) {
fprintf(stderr,
"InnoDB: Error: pthread_mutex_trylock returns an unexpected value on\n"
- "InnoDB: success! Cannot continue.\n");
+"InnoDB: success! Cannot continue.\n");
exit(1);
}
@@ -1375,8 +1477,45 @@ innobase_start_or_create_for_mysql(void)
os_fast_mutex_unlock(&srv_os_test_mutex);
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Started\n");
+ os_fast_mutex_free(&srv_os_test_mutex);
+
+ /***********************************************************/
+ /* Do NOT merge to the 4.1 code base! */
+ if (trx_sys_downgrading_from_4_1_1) {
+ fprintf(stderr,
+"InnoDB: You are downgrading from an InnoDB version which allows multiple\n"
+"InnoDB: tablespaces. Wait that purge and insert buffer merge run to\n"
+"InnoDB: completion...\n");
+ for (;;) {
+ os_thread_sleep(10000000);
+
+ if (0 == strcmp(srv_main_thread_op_info,
+ "waiting for server activity")) {
+ break;
+ }
+ }
+ fprintf(stderr,
+"InnoDB: Full purge and insert buffer merge completed.\n");
+
+ trx_sys_mark_downgraded_from_4_1_1();
+
+ fprintf(stderr,
+"InnoDB: Downgraded from >= 4.1.1 to 4.0\n");
+ }
+ /***********************************************************/
+
+ if (srv_print_verbose_log) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Started\n");
+ }
+
+ if (srv_force_recovery > 0) {
+ fprintf(stderr,
+ "InnoDB: !!! innodb_force_recovery is set to %lu !!!\n",
+ srv_force_recovery);
+ }
+
+ fflush(stderr);
return((int) DB_SUCCESS);
}
@@ -1389,6 +1528,8 @@ innobase_shutdown_for_mysql(void)
/*=============================*/
/* out: DB_SUCCESS or error code */
{
+ ulint i;
+
if (!srv_was_started) {
if (srv_is_being_started) {
ut_print_timestamp(stderr);
@@ -1401,8 +1542,10 @@ innobase_shutdown_for_mysql(void)
return(DB_SUCCESS);
}
- /* Flush buffer pool to disk, write the current lsn to
- the tablespace header(s), and copy all log data to archive */
+ /* 1. Flush buffer pool to disk, write the current lsn to
+ the tablespace header(s), and copy all log data to archive.
+ The step 1 is the real InnoDB shutdown. The remaining steps
+ just free data structures after the shutdown. */
logs_empty_and_mark_files_at_shutdown();
@@ -1413,14 +1556,88 @@ innobase_shutdown_for_mysql(void)
srv_conc_n_threads);
}
- /*
- TODO: We should exit the i/o-handler and other utility threads
- before freeing all memory. Now this can potentially cause a seg
- fault!
- */
-#ifdef NOT_WORKING_YET
+ /* 2. Make all threads created by InnoDB to exit */
+
+ srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
+
+ /* All threads end up waiting for certain events. Put those events
+ to the signaled state. Then the threads will exit themselves in
+ os_thread_event_wait(). */
+
+ for (i = 0; i < 1000; i++) {
+ /* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM
+ HERE OR EARLIER */
+
+ /* 1. Let the lock timeout thread exit */
+ os_event_set(srv_lock_timeout_thread_event);
+
+ /* 2. srv error monitor thread exits automatically, no need
+ to do anything here */
+
+ /* 3. We wake the master thread so that it exits */
+ srv_wake_master_thread();
+
+ /* 4. Exit the i/o threads */
+
+ os_aio_wake_all_threads_at_shutdown();
+
+ os_mutex_enter(os_sync_mutex);
+
+ if (os_thread_count == 0) {
+ /* All the threads have exited or are just exiting;
+ NOTE that the threads may not have completed their
+ exit yet. Should we use pthread_join() to make sure
+ they have exited? Now we just sleep 0.1 seconds and
+ hope that is enough! */
+
+ os_mutex_exit(os_sync_mutex);
+
+ os_thread_sleep(100000);
+
+ break;
+ }
+
+ os_mutex_exit(os_sync_mutex);
+
+ os_thread_sleep(100000);
+ }
+
+ if (i == 1000) {
+ fprintf(stderr,
+"InnoDB: Warning: %lu threads created by InnoDB had not exited at shutdown!\n",
+ os_thread_count);
+ }
+
+ /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
+ them */
+
+ sync_close();
+
+ /* 4. Free the os_conc_mutex and all os_events and os_mutexes */
+
+ srv_free();
+ os_sync_free();
+
+ /* 5. Free all allocated memory and the os_fast_mutex created in
+ ut0mem.c */
+
ut_free_all_mem();
-#endif
+
+ if (os_thread_count != 0
+ || os_event_count != 0
+ || os_mutex_count != 0
+ || os_fast_mutex_count != 0) {
+ fprintf(stderr,
+"InnoDB: Warning: some resources were not cleaned up in shutdown:\n"
+"InnoDB: threads %lu, events %lu, os_mutexes %lu, os_fast_mutexes %lu\n",
+ os_thread_count, os_event_count, os_mutex_count,
+ os_fast_mutex_count);
+ }
+
+ if (srv_print_verbose_log) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Shutdown completed\n");
+ }
return((int) DB_SUCCESS);
}
diff --git a/innobase/sync/Makefile.am b/innobase/sync/Makefile.am
index 7504525bf84..4acd4516e35 100644
--- a/innobase/sync/Makefile.am
+++ b/innobase/sync/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libsync.a
+noinst_LIBRARIES = libsync.a
libsync_a_SOURCES = sync0arr.c sync0ipm.c sync0rw.c sync0sync.c
diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c
index 80122cdc63a..4854b40409e 100644
--- a/innobase/sync/sync0arr.c
+++ b/innobase/sync/sync0arr.c
@@ -447,7 +447,7 @@ sync_array_cell_print(
{
mutex_t* mutex;
rw_lock_t* rwlock;
- char* str = NULL;
+ char* str __attribute__((unused)) = NULL;
ulint type;
type = cell->request_type;
diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c
index 93db9b9d507..b214bca0470 100644
--- a/innobase/sync/sync0rw.c
+++ b/innobase/sync/sync0rw.c
@@ -115,8 +115,8 @@ rw_lock_create_func(
lock->cfile_name = cfile_name;
lock->cline = cline;
- lock->last_s_file_name = "not yet reserved";
- lock->last_x_file_name = "not yet reserved";
+ lock->last_s_file_name = (char *) "not yet reserved";
+ lock->last_x_file_name = (char *) "not yet reserved";
lock->last_s_line = 0;
lock->last_x_line = 0;
@@ -663,7 +663,8 @@ rw_lock_own(
/*========*/
/* out: TRUE if locked */
rw_lock_t* lock, /* in: rw-lock */
- ulint lock_type) /* in: lock type */
+ ulint lock_type) /* in: lock type: RW_LOCK_SHARED,
+ RW_LOCK_EX */
{
rw_lock_debug_t* info;
@@ -792,7 +793,7 @@ Prints debug info of an rw-lock. */
void
rw_lock_print(
/*==========*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock __attribute__((unused))) /* in: rw-lock */
{
#ifndef UNIV_SYNC_DEBUG
printf(
diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c
index 61bd8e587e6..773b239189c 100644
--- a/innobase/sync/sync0sync.c
+++ b/innobase/sync/sync0sync.c
@@ -159,7 +159,7 @@ struct sync_thread_struct{
};
/* Number of slots reserved for each OS thread in the sync level array */
-#define SYNC_THREAD_N_LEVELS 10000
+#define SYNC_THREAD_N_LEVELS 250
struct sync_level_struct{
void* latch; /* pointer to a mutex or an rw-lock; NULL means that
@@ -220,7 +220,7 @@ mutex_create_func(
char* cfile_name, /* in: file name where created */
ulint cline) /* in: file line where created */
{
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
+#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) && !defined(__NETWARE)
mutex_reset_lock_word(mutex);
#else
os_fast_mutex_init(&(mutex->os_fast_mutex));
@@ -229,14 +229,13 @@ mutex_create_func(
mutex_set_waiters(mutex, 0);
mutex->magic_n = MUTEX_MAGIC_N;
mutex->line = 0;
- mutex->file_name = "not yet reserved";
+ mutex->file_name = (char *) "not yet reserved";
mutex->level = SYNC_LEVEL_NONE;
mutex->cfile_name = cfile_name;
mutex->cline = cline;
/* Check that lock_word is aligned; this is important on Intel */
-
- ut_a(((ulint)(&(mutex->lock_word))) % 4 == 0);
+ ut_ad(((ulint)(&(mutex->lock_word))) % 4 == 0);
/* NOTE! The very first mutexes are not put to the mutex list */
@@ -266,11 +265,14 @@ mutex_free(
ut_a(mutex_get_lock_word(mutex) == 0);
ut_a(mutex_get_waiters(mutex) == 0);
- mutex_enter(&mutex_list_mutex);
+ if (mutex != &mutex_list_mutex && mutex != &sync_thread_mutex) {
- UT_LIST_REMOVE(list, mutex_list, mutex);
+ mutex_enter(&mutex_list_mutex);
- mutex_exit(&mutex_list_mutex);
+ UT_LIST_REMOVE(list, mutex_list, mutex);
+
+ mutex_exit(&mutex_list_mutex);
+ }
#if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER)
os_fast_mutex_free(&(mutex->os_fast_mutex));
@@ -901,8 +903,7 @@ sync_thread_levels_empty_gen(
if (slot->latch != NULL && (!dict_mutex_allowed ||
(slot->level != SYNC_DICT
- && slot->level != SYNC_FOREIGN_KEY_CHECK
- && slot->level != SYNC_PURGE_IS_RUNNING))) {
+ && slot->level != SYNC_DICT_OPERATION))) {
lock = slot->latch;
mutex = slot->latch;
@@ -1087,12 +1088,10 @@ sync_thread_add_level(
SYNC_IBUF_PESS_INSERT_MUTEX));
} else if (level == SYNC_DICT_AUTOINC_MUTEX) {
ut_a(sync_thread_levels_g(array, SYNC_DICT_AUTOINC_MUTEX));
- } else if (level == SYNC_FOREIGN_KEY_CHECK) {
- ut_a(sync_thread_levels_g(array, SYNC_FOREIGN_KEY_CHECK));
+ } else if (level == SYNC_DICT_OPERATION) {
+ ut_a(sync_thread_levels_g(array, SYNC_DICT_OPERATION));
} else if (level == SYNC_DICT_HEADER) {
ut_a(sync_thread_levels_g(array, SYNC_DICT_HEADER));
- } else if (level == SYNC_PURGE_IS_RUNNING) {
- ut_a(sync_thread_levels_g(array, SYNC_PURGE_IS_RUNNING));
} else if (level == SYNC_DICT) {
ut_a(buf_debug_prints
|| sync_thread_levels_g(array, SYNC_DICT));
@@ -1233,13 +1232,26 @@ sync_init(void)
}
/**********************************************************************
-Frees the resources in synchronization data structures. */
+Frees the resources in InnoDB's own synchronization data structures. Use
+os_sync_free() after calling this. */
void
sync_close(void)
/*===========*/
{
+ mutex_t* mutex;
+
sync_array_free(sync_primary_wait_array);
+
+ mutex = UT_LIST_GET_FIRST(mutex_list);
+
+ while (mutex) {
+ mutex_free(mutex);
+ mutex = UT_LIST_GET_FIRST(mutex_list);
+ }
+
+ mutex_free(&mutex_list_mutex);
+ mutex_free(&sync_thread_mutex);
}
/***********************************************************************
diff --git a/innobase/thr/Makefile.am b/innobase/thr/Makefile.am
index 5f42138e734..62c39492c07 100644
--- a/innobase/thr/Makefile.am
+++ b/innobase/thr/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libthr.a
+noinst_LIBRARIES = libthr.a
libthr_a_SOURCES = thr0loc.c
diff --git a/innobase/thr/thr0loc.c b/innobase/thr/thr0loc.c
index fbf3e3a1dad..839cb024f25 100644
--- a/innobase/thr/thr0loc.c
+++ b/innobase/thr/thr0loc.c
@@ -14,6 +14,7 @@ Created 10/5/1995 Heikki Tuuri
#include "sync0sync.h"
#include "hash0hash.h"
#include "mem0mem.h"
+#include "srv0srv.h"
/*
IMPLEMENTATION OF THREAD LOCAL STORAGE
diff --git a/innobase/trx/Makefile.am b/innobase/trx/Makefile.am
index 63b2c52da33..9e2b3c398e3 100644
--- a/innobase/trx/Makefile.am
+++ b/innobase/trx/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libtrx.a
+noinst_LIBRARIES = libtrx.a
libtrx_a_SOURCES = trx0purge.c trx0rec.c trx0roll.c trx0rseg.c\
trx0sys.c trx0trx.c trx0undo.c
diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c
index b73629c9fa4..fa9c287b0ad 100644
--- a/innobase/trx/trx0purge.c
+++ b/innobase/trx/trx0purge.c
@@ -209,9 +209,6 @@ trx_purge_sys_create(void)
purge_sys->purge_undo_no = ut_dulint_zero;
purge_sys->next_stored = FALSE;
- rw_lock_create(&(purge_sys->purge_is_running));
- rw_lock_set_level(&(purge_sys->purge_is_running),
- SYNC_PURGE_IS_RUNNING);
rw_lock_create(&(purge_sys->latch));
rw_lock_set_level(&(purge_sys->latch), SYNC_PURGE_LATCH);
@@ -596,7 +593,7 @@ trx_purge_rseg_get_next_history_log(
mutex_enter(&(rseg->mutex));
- ut_ad(rseg->last_page_no != FIL_NULL);
+ ut_a(rseg->last_page_no != FIL_NULL);
purge_sys->purge_trx_no = ut_dulint_add(rseg->last_trx_no, 1);
purge_sys->purge_undo_no = ut_dulint_zero;
@@ -609,16 +606,9 @@ trx_purge_rseg_get_next_history_log(
log_hdr = undo_page + rseg->last_offset;
seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
- if ((mach_read_from_2(log_hdr + TRX_UNDO_NEXT_LOG) == 0)
- && (mach_read_from_2(seg_hdr + TRX_UNDO_STATE)
- == TRX_UNDO_TO_PURGE)) {
-
- /* This is the last log header on this page and the log
- segment cannot be reused: we may increment the number of
- pages handled */
+ /* Increase the purge page count by one for every handled log */
- purge_sys->n_pages_handled++;
- }
+ purge_sys->n_pages_handled++;
prev_log_addr = trx_purge_get_log_from_hist(
flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE,
@@ -674,9 +664,9 @@ trx_purge_choose_next_log(void)
trx_rseg_t* rseg;
trx_rseg_t* min_rseg;
dulint min_trx_no;
- ulint space;
- ulint page_no;
- ulint offset;
+ ulint space = 0; /* remove warning (??? bug ???) */
+ ulint page_no = 0; /* remove warning (??? bug ???) */
+ ulint offset = 0; /* remove warning (??? bug ???) */
mtr_t mtr;
ut_ad(mutex_own(&(purge_sys->mutex)));
diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c
index abce470bd1c..9453189d598 100644
--- a/innobase/trx/trx0rec.c
+++ b/innobase/trx/trx0rec.c
@@ -272,8 +272,8 @@ trx_undo_page_report_insert(
mach_write_to_2(undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE,
ptr - undo_page);
- /* Write the log entry to the REDO log of this change in the UNDO log */
-
+ /* Write the log entry to the REDO log of this change in the UNDO
+ log */
trx_undof_page_add_undo_rec_log(undo_page, first_free,
ptr - undo_page, mtr);
return(first_free);
@@ -492,7 +492,8 @@ trx_undo_page_report_modify(
/* Reserve 2 bytes for the pointer to the next undo log record */
ptr += 2;
- /* Store first some general parameters to the undo log */
+ /* Store first some general parameters to the undo log */
+
if (update) {
if (rec_get_deleted_flag(rec)) {
type_cmpl = TRX_UNDO_UPD_DEL_REC;
@@ -526,8 +527,7 @@ trx_undo_page_report_modify(
/* Store the values of the system columns */
trx_id = dict_index_rec_get_sys_col(index, DATA_TRX_ID, rec);
- roll_ptr = dict_index_rec_get_sys_col(index, DATA_ROLL_PTR, rec);
-
+ roll_ptr = dict_index_rec_get_sys_col(index, DATA_ROLL_PTR, rec);
len = mach_dulint_write_compressed(ptr, trx_id);
ptr += len;
@@ -632,7 +632,11 @@ trx_undo_page_report_modify(
columns which occur as ordering fields in any index. This info is used
in the purge of old versions where we use it to build and search the
delete marked index records, to look if we can remove them from the
- index tree. */
+ index tree. Note that starting from 4.0.14 also externally stored
+ fields can be ordering in some index. But we always store at least
+ 384 first bytes locally to the clustered index record, which means
+ we can construct the column prefix fields in the index from the
+ stored data. */
if (!update || !(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
@@ -989,7 +993,7 @@ trx_undo_parse_erase_page_end(
/*==========================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -1263,7 +1267,8 @@ trx_undo_prev_version_build(
DB_ERROR if corrupted record */
rec_t* index_rec,/* in: clustered index record in the
index tree */
- mtr_t* index_mtr,/* in: mtr which contains the latch to
+ mtr_t* index_mtr __attribute__((unused)),
+ /* in: mtr which contains the latch to
index_rec page and purge_view */
rec_t* rec, /* in: version of a clustered index record */
dict_index_t* index, /* in: clustered index */
@@ -1407,11 +1412,11 @@ trx_undo_prev_version_build(
return(DB_ERROR);
}
- if (row_upd_changes_field_size(rec, index, update)) {
-
- entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
+ if (row_upd_changes_field_size_or_external(rec, index, update)) {
- row_upd_clust_index_replace_new_col_vals(entry, update);
+ entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec,
+ heap);
+ row_upd_index_replace_new_col_vals(entry, index, update, heap);
buf = mem_heap_alloc(heap, rec_get_converted_size(entry));
diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c
index 0a951484b59..7d1b341221c 100644
--- a/innobase/trx/trx0roll.c
+++ b/innobase/trx/trx0roll.c
@@ -21,6 +21,7 @@ Created 3/26/1996 Heikki Tuuri
#include "que0que.h"
#include "usr0sess.h"
#include "srv0que.h"
+#include "srv0start.h"
#include "row0undo.h"
#include "row0mysql.h"
#include "lock0lock.h"
@@ -29,6 +30,12 @@ Created 3/26/1996 Heikki Tuuri
/* This many pages must be undone before a truncate is tried within rollback */
#define TRX_ROLL_TRUNC_THRESHOLD 1
+/* In crash recovery we set this to the undo n:o of the current trx to be
+rolled back. Then we can print how many % the rollback has progressed. */
+ib_longlong trx_roll_max_undo_no;
+/* Auxiliary variable which tells the previous progress % we printed */
+ulint trx_roll_progress_printed_pct;
+
/***********************************************************************
Rollback a transaction used in MySQL. */
@@ -45,6 +52,11 @@ trx_general_rollback_for_mysql(
que_thr_t* thr;
roll_node_t* roll_node;
+ /* Tell Innobase server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
trx_start_if_not_started(trx);
heap = mem_heap_create(512);
@@ -82,6 +94,11 @@ trx_general_rollback_for_mysql(
ut_a(trx->error_state == DB_SUCCESS);
+ /* Tell Innobase server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
return((int) trx->error_state);
}
@@ -101,23 +118,11 @@ trx_rollback_for_mysql(
return(DB_SUCCESS);
}
- trx->op_info = "rollback";
+ trx->op_info = (char *) "rollback";
- /* Tell Innobase server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
- trx_mark_sql_stat_end(trx);
-
- /* Tell Innobase server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(err);
}
@@ -138,28 +143,194 @@ trx_rollback_last_sql_stat_for_mysql(
return(DB_SUCCESS);
}
- trx->op_info = "rollback of SQL statement";
+ trx->op_info = (char *) "rollback of SQL statement";
- /* Tell Innobase server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
err = trx_general_rollback_for_mysql(trx, TRUE,
&(trx->last_sql_stat_start));
+ /* The following call should not be needed, but we play safe: */
trx_mark_sql_stat_end(trx);
- /* Tell Innobase server that there might be work for
- utility threads: */
+ trx->op_info = (char *) "";
+
+ return(err);
+}
- srv_active_wake_master_thread();
+/***********************************************************************
+Frees savepoint structs. */
+
+void
+trx_roll_savepoints_free(
+/*=====================*/
+ trx_t* trx, /* in: transaction handle */
+ trx_named_savept_t* savep) /* in: free all savepoints > this one;
+ if this is NULL, free all savepoints
+ of trx */
+{
+ trx_named_savept_t* next_savep;
- trx->op_info = "";
+ if (savep == NULL) {
+ savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
+ } else {
+ savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
+ }
+ while (savep != NULL) {
+ next_savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
+
+ UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
+ mem_free(savep->name);
+ mem_free(savep);
+
+ savep = next_savep;
+ }
+}
+
+/***********************************************************************
+Rolls back a transaction back to a named savepoint. Modifications after the
+savepoint are undone but InnoDB does NOT release the corresponding locks
+which are stored in memory. If a lock is 'implicit', that is, a new inserted
+row holds a lock where the lock information is carried by the trx id stored in
+the row, these locks are naturally released in the rollback. Savepoints which
+were set after this savepoint are deleted. */
+
+ulint
+trx_rollback_to_savepoint_for_mysql(
+/*================================*/
+ /* out: if no savepoint
+ of the name found then
+ DB_NO_SAVEPOINT,
+ otherwise DB_SUCCESS */
+ trx_t* trx, /* in: transaction handle */
+ char* savepoint_name, /* in: savepoint name */
+ ib_longlong* mysql_binlog_cache_pos) /* out: the MySQL binlog cache
+ position corresponding to this
+ savepoint; MySQL needs this
+ information to remove the
+ binlog entries of the queries
+ executed after the savepoint */
+{
+ trx_named_savept_t* savep;
+ ulint err;
+
+ savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
+
+ while (savep != NULL) {
+ if (0 == ut_strcmp(savep->name, savepoint_name)) {
+ /* Found */
+ break;
+ }
+ savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
+ }
+
+ if (savep == NULL) {
+
+ return(DB_NO_SAVEPOINT);
+ }
+
+ if (trx->conc_state == TRX_NOT_STARTED) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Error: transaction has a savepoint %s though it is not started\n",
+ savep->name);
+ return(DB_ERROR);
+ }
+
+ /* We can now free all savepoints strictly later than this one */
+
+ trx_roll_savepoints_free(trx, savep);
+
+ *mysql_binlog_cache_pos = savep->mysql_binlog_cache_pos;
+
+ trx->op_info = (char *) "rollback to a savepoint";
+
+ err = trx_general_rollback_for_mysql(trx, TRUE, &(savep->savept));
+
+ /* Store the current undo_no of the transaction so that we know where
+ to roll back if we have to roll back the next SQL statement: */
+
+ trx_mark_sql_stat_end(trx);
+
+ trx->op_info = (char *) "";
+
return(err);
}
/***********************************************************************
+Creates a named savepoint. If the transaction is not yet started, starts it.
+If there is already a savepoint of the same name, this call erases that old
+savepoint and replaces it with a new. Savepoints are deleted in a transaction
+commit or rollback. */
+
+ulint
+trx_savepoint_for_mysql(
+/*====================*/
+ /* out: always DB_SUCCESS */
+ trx_t* trx, /* in: transaction handle */
+ char* savepoint_name, /* in: savepoint name */
+ ib_longlong binlog_cache_pos) /* in: MySQL binlog cache
+ position corresponding to this
+ connection at the time of the
+ savepoint */
+{
+ trx_named_savept_t* savep;
+
+ ut_a(trx);
+ ut_a(savepoint_name);
+
+ trx_start_if_not_started(trx);
+
+ savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
+
+ while (savep != NULL) {
+ if (0 == ut_strcmp(savep->name, savepoint_name)) {
+ /* Found */
+ break;
+ }
+ savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
+ }
+
+ if (savep) {
+ /* There is a savepoint with the same name: free that */
+
+ UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
+
+ mem_free(savep->name);
+ mem_free(savep);
+ }
+
+ /* Create a new savepoint and add it as the last in the list */
+
+ savep = mem_alloc(sizeof(trx_named_savept_t));
+
+ savep->name = mem_alloc(1 + ut_strlen(savepoint_name));
+ ut_memcpy(savep->name, savepoint_name, 1 + ut_strlen(savepoint_name));
+
+ savep->savept = trx_savept_take(trx);
+
+ savep->mysql_binlog_cache_pos = binlog_cache_pos;
+
+ UT_LIST_ADD_LAST(trx_savepoints, trx->trx_savepoints, savep);
+
+ return(DB_SUCCESS);
+}
+
+/***********************************************************************
+Returns a transaction savepoint taken at this point in time. */
+
+trx_savept_t
+trx_savept_take(
+/*============*/
+ /* out: savepoint */
+ trx_t* trx) /* in: transaction */
+{
+ trx_savept_t savept;
+
+ savept.least_undo_no = trx->undo_no;
+
+ return(savept);
+}
+
+/***********************************************************************
Rollback or clean up transactions which have no user session. If the
transaction already was committed, then we clean up a possible insert
undo log. If the transaction was not yet committed, then we roll it back. */
@@ -174,6 +345,8 @@ trx_rollback_or_clean_all_without_sess(void)
roll_node_t* roll_node;
trx_t* trx;
dict_table_t* table;
+ ib_longlong rows_to_undo;
+ char* unit = (char*)"";
int err;
mutex_enter(&kernel_mutex);
@@ -182,7 +355,7 @@ trx_rollback_or_clean_all_without_sess(void)
if (!trx_dummy_sess) {
trx_dummy_sess = sess_open(NULL, (byte*)"Dummy sess",
- ut_strlen("Dummy sess"));
+ ut_strlen((char *) "Dummy sess"));
}
mutex_exit(&kernel_mutex);
@@ -219,8 +392,7 @@ loop:
trx->sess = trx_dummy_sess;
- if (trx->conc_state == TRX_COMMITTED_IN_MEMORY) {
-
+ if (trx->conc_state == TRX_COMMITTED_IN_MEMORY) {
fprintf(stderr, "InnoDB: Cleaning up trx with id %lu %lu\n",
ut_dulint_get_high(trx->id),
ut_dulint_get_low(trx->id));
@@ -248,13 +420,23 @@ loop:
ut_a(thr == que_fork_start_command(fork, SESS_COMM_EXECUTE, 0));
- fprintf(stderr, "InnoDB: Rolling back trx with id %lu %lu\n",
+ trx_roll_max_undo_no = ut_conv_dulint_to_longlong(trx->undo_no);
+ trx_roll_progress_printed_pct = 0;
+ rows_to_undo = trx_roll_max_undo_no;
+ if (rows_to_undo > 1000000000) {
+ rows_to_undo = rows_to_undo / 1000000;
+ unit = (char*)"M";
+ }
+
+ fprintf(stderr,
+"InnoDB: Rolling back trx with id %lu %lu, %lu%s rows to undo",
ut_dulint_get_high(trx->id),
- ut_dulint_get_low(trx->id));
+ ut_dulint_get_low(trx->id),
+ (ulint)rows_to_undo, unit);
mutex_exit(&kernel_mutex);
if (trx->dict_operation) {
- mutex_enter(&(dict_sys->mutex));
+ row_mysql_lock_data_dictionary(trx);
}
que_run_threads(thr);
@@ -290,39 +472,23 @@ loop:
fprintf(stderr,
"InnoDB: Table found: dropping table %s in recovery\n", table->name);
- err = row_drop_table_for_mysql(table->name, trx,
- TRUE);
+ err = row_drop_table_for_mysql(table->name, trx);
+
ut_a(err == (int) DB_SUCCESS);
}
}
if (trx->dict_operation) {
- mutex_exit(&(dict_sys->mutex));
+ row_mysql_unlock_data_dictionary(trx);
}
- fprintf(stderr, "InnoDB: Rolling back of trx id %lu %lu completed\n",
+ fprintf(stderr, "\nInnoDB: Rolling back of trx id %lu %lu completed\n",
ut_dulint_get_high(trx->id),
ut_dulint_get_low(trx->id));
mem_heap_free(heap);
goto loop;
}
-
-/***********************************************************************
-Returns a transaction savepoint taken at this point in time. */
-
-trx_savept_t
-trx_savept_take(
-/*============*/
- /* out: savepoint */
- trx_t* trx) /* in: transaction */
-{
- trx_savept_t savept;
-
- savept.least_undo_no = trx->undo_no;
-
- return(savept);
-}
/***********************************************************************
Creates an undo number array. */
@@ -614,6 +780,7 @@ trx_roll_pop_top_rec_of_trx(
dulint undo_no;
ibool is_insert;
trx_rseg_t* rseg;
+ ulint progress_pct;
mtr_t mtr;
rseg = trx->rseg;
@@ -676,6 +843,26 @@ try_again:
ut_ad(ut_dulint_cmp(ut_dulint_add(undo_no, 1), trx->undo_no) == 0);
+ /* We print rollback progress info if we are in a crash recovery
+ and the transaction has at least 1000 row operations to undo */
+
+ if (srv_is_being_started && trx_roll_max_undo_no > 1000) {
+ progress_pct = 100 - (ulint)
+ ((ut_conv_dulint_to_longlong(undo_no) * 100)
+ / trx_roll_max_undo_no);
+ if (progress_pct != trx_roll_progress_printed_pct) {
+ if (trx_roll_progress_printed_pct == 0) {
+ fprintf(stderr,
+ "\nInnoDB: Progress in percents: %lu", progress_pct);
+ } else {
+ fprintf(stderr,
+ " %lu", progress_pct);
+ }
+ fflush(stderr);
+ trx_roll_progress_printed_pct = progress_pct;
+ }
+ }
+
trx->undo_no = undo_no;
if (!trx_undo_arr_store_info(trx, undo_no)) {
diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c
index 33c962772e8..3b5f024d39e 100644
--- a/innobase/trx/trx0sys.c
+++ b/innobase/trx/trx0sys.c
@@ -34,6 +34,43 @@ or there was no master log position info inside InnoDB. */
char trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
ib_longlong trx_sys_mysql_master_log_pos = -1;
+/* Do NOT merge this to the 4.1 code base! */
+ibool trx_sys_downgrading_from_4_1_1 = FALSE;
+
+/********************************************************************
+Do NOT merge this to the 4.1 code base!
+Marks the trx sys header when we have successfully downgraded from the >= 4.1.1
+multiple tablespace format back to the 4.0 format. */
+
+void
+trx_sys_mark_downgraded_from_4_1_1(void)
+/*====================================*/
+{
+ page_t* page;
+ byte* doublewrite;
+ mtr_t mtr;
+
+ /* Let us mark to the trx_sys header that the downgrade has been
+ done. */
+
+ mtr_start(&mtr);
+
+ page = buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO, RW_X_LATCH, &mtr);
+ buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK);
+
+ doublewrite = page + TRX_SYS_DOUBLEWRITE;
+
+ mlog_write_ulint(doublewrite + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED,
+ TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N + 1,
+ MLOG_4BYTES, &mtr);
+ mtr_commit(&mtr);
+
+ /* Flush the modified pages to disk and make a checkpoint */
+ log_make_checkpoint_at(ut_dulint_max, TRUE);
+
+ trx_sys_downgrading_from_4_1_1 = FALSE;
+}
+
/********************************************************************
Determines if a page number is located inside the doublewrite buffer. */
@@ -138,12 +175,36 @@ start_again:
if (mach_read_from_4(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC)
== TRX_SYS_DOUBLEWRITE_MAGIC_N) {
+ /* Do NOT merge to the 4.1 code base! */
+ if (mach_read_from_4(doublewrite
+ + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED)
+ == TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N) {
+
+ fprintf(stderr,
+"InnoDB: You are downgrading from the multiple tablespace format of\n"
+"InnoDB: >= MySQL-4.1.1 back to the old format of MySQL-4.0.\n"
+"InnoDB:\n"
+"InnoDB: MAKE SURE that the mysqld server is idle, and purge and the insert\n"
+"InnoDB: buffer merge have run to completion under >= 4.1.1 before trying to\n"
+"InnoDB: downgrade! You can determine this by looking at SHOW INNODB STATUS:\n"
+"InnoDB: if the Main thread is 'waiting for server activity' and SHOW\n"
+"InnoDB: PROCESSLIST shows that you have ended all other connections\n"
+"InnoDB: to mysqld, then purge and the insert buffer merge have been\n"
+"InnoDB: completed.\n"
+"InnoDB: If you have already created tables in >= 4.1.1, then those\n"
+"InnoDB: tables cannot be used under 4.0.\n"
+"InnoDB: NOTE THAT this downgrade procedure has not been properly tested!\n"
+"InnoDB: The safe way to downgrade is to dump all InnoDB tables and recreate\n"
+"InnoDB: the whole tablespace.\n");
+
+ trx_sys_downgrading_from_4_1_1 = TRUE;
+ }
/* The doublewrite buffer has already been created:
just read in some numbers */
trx_doublewrite_init(doublewrite);
-
+
mtr_commit(&mtr);
} else {
fprintf(stderr,
@@ -295,6 +356,31 @@ trx_sys_doublewrite_restore_corrupt_pages(void)
== TRX_SYS_DOUBLEWRITE_MAGIC_N) {
/* The doublewrite buffer has been created */
+ /* Do NOT merge to the 4.1 code base! */
+ if (mach_read_from_4(doublewrite
+ + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED)
+ == TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N) {
+
+ fprintf(stderr,
+"InnoDB: You are downgrading from the multiple tablespace format of\n"
+"InnoDB: >= MySQL-4.1.1 back to the old format of MySQL-4.0.\n"
+"InnoDB:\n"
+"InnoDB: MAKE SURE that the mysqld server is idle, and purge and the insert\n"
+"InnoDB: buffer merge have run to completion under >= 4.1.1 before trying to\n"
+"InnoDB: downgrade! You can determine this by looking at SHOW INNODB STATUS:\n"
+"InnoDB: if the Main thread is 'waiting for server activity' and SHOW\n"
+"InnoDB: PROCESSLIST shows that you have ended all other connections\n"
+"InnoDB: to mysqld, then purge and the insert buffer merge have been\n"
+"InnoDB: completed.\n"
+"InnoDB: If you have already created tables in >= 4.1.1, then those\n"
+"InnoDB: tables cannot be used under 4.0.\n"
+"InnoDB: NOTE THAT this downgrade procedure has not been properly tested!\n"
+"InnoDB: The safe way to downgrade is to dump all InnoDB tables and recreate\n"
+"InnoDB: the whole tablespace.\n");
+
+ trx_sys_downgrading_from_4_1_1 = TRUE;
+ }
+
trx_doublewrite_init(doublewrite);
block1 = trx_doublewrite->block1;
@@ -321,8 +407,8 @@ trx_sys_doublewrite_restore_corrupt_pages(void)
for (i = 0; i < TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 2; i++) {
- space_id = mach_read_from_4(page + FIL_PAGE_SPACE);
page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
+ space_id = 0;
if (!fil_check_adress_in_tablespace(space_id, page_no)) {
fprintf(stderr,
@@ -340,7 +426,6 @@ trx_sys_doublewrite_restore_corrupt_pages(void)
/* It is an unwritten doublewrite buffer page:
do nothing */
-
} else {
/* Read in the actual page from the data files */
@@ -357,9 +442,19 @@ trx_sys_doublewrite_restore_corrupt_pages(void)
"InnoDB: Trying to recover it from the doublewrite buffer.\n");
if (buf_page_is_corrupted(page)) {
+ fprintf(stderr,
+ "InnoDB: Dump of the page:\n");
+ buf_page_print(read_buf);
+ fprintf(stderr,
+ "InnoDB: Dump of corresponding page in doublewrite buffer:\n");
+ buf_page_print(page);
+
fprintf(stderr,
"InnoDB: Also the page in the doublewrite buffer is corrupt.\n"
- "InnoDB: Cannot continue operation.\n");
+ "InnoDB: Cannot continue operation.\n"
+ "InnoDB: You can try to recover the database with the my.cnf\n"
+ "InnoDB: option:\n"
+ "InnoDB: set-variable=innodb_force_recovery=6\n");
exit(1);
}
@@ -472,9 +567,9 @@ trx_sys_update_mysql_binlog_offset(
if (0 != ut_memcmp(sys_header + field + TRX_SYS_MYSQL_LOG_NAME,
file_name, 1 + ut_strlen(file_name))) {
- mlog_write_string(sys_header + field
- + TRX_SYS_MYSQL_LOG_NAME,
- file_name, 1 + ut_strlen(file_name), mtr);
+ mlog_write_string((byte*) (sys_header + field
+ + TRX_SYS_MYSQL_LOG_NAME),
+ (byte*) file_name, 1 + ut_strlen(file_name), mtr);
}
if (mach_read_from_4(sys_header + field
@@ -699,6 +794,9 @@ trx_sys_init_at_db_start(void)
/*==========================*/
{
trx_sysf_t* sys_header;
+ ib_longlong rows_to_undo = 0;
+ char* unit = (char*)"";
+ trx_t* trx;
mtr_t mtr;
mtr_start(&mtr);
@@ -734,9 +832,28 @@ trx_sys_init_at_db_start(void)
trx_lists_init_at_db_start();
if (UT_LIST_GET_LEN(trx_sys->trx_list) > 0) {
+ trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
+
+ for (;;) {
+ rows_to_undo +=
+ ut_conv_dulint_to_longlong(trx->undo_no);
+ trx = UT_LIST_GET_NEXT(trx_list, trx);
+
+ if (!trx) {
+ break;
+ }
+ }
+
+ if (rows_to_undo > 1000000000) {
+ unit = (char*)"M";
+ rows_to_undo = rows_to_undo / 1000000;
+ }
+
fprintf(stderr,
- "InnoDB: %lu transaction(s) which must be rolled back or cleaned up\n",
- UT_LIST_GET_LEN(trx_sys->trx_list));
+"InnoDB: %lu transaction(s) which must be rolled back or cleaned up\n"
+"InnoDB: in total %lu%s row operations to undo\n",
+ UT_LIST_GET_LEN(trx_sys->trx_list),
+ (ulint)rows_to_undo, unit);
fprintf(stderr, "InnoDB: Trx id counter is %lu %lu\n",
ut_dulint_get_high(trx_sys->max_trx_id),
diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c
index b8cf7ad4a6d..47c39290b15 100644
--- a/innobase/trx/trx0trx.c
+++ b/innobase/trx/trx0trx.c
@@ -23,7 +23,7 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0srv.h"
#include "thr0loc.h"
#include "btr0sea.h"
-
+#include "os0proc.h"
/* Copy of the prototype for innobase_mysql_print_thd: this
copy MUST be equal to the one in mysql/sql/ha_innobase.cc ! */
@@ -79,29 +79,35 @@ trx_create(
trx->magic_n = TRX_MAGIC_N;
- trx->op_info = "";
+ trx->op_info = (char *) "";
trx->type = TRX_USER;
trx->conc_state = TRX_NOT_STARTED;
trx->start_time = time(NULL);
+ trx->isolation_level = TRX_ISO_REPEATABLE_READ;
+
+ trx->id = ut_dulint_zero;
+ trx->no = ut_dulint_max;
+
trx->check_foreigns = TRUE;
trx->check_unique_secondary = TRUE;
+ trx->flush_log_later = FALSE;
+
trx->dict_operation = FALSE;
trx->mysql_thd = NULL;
+ trx->mysql_query_str = NULL;
trx->n_mysql_tables_in_use = 0;
trx->mysql_n_tables_locked = 0;
trx->mysql_log_file_name = NULL;
trx->mysql_log_offset = 0;
- trx->mysql_master_log_file_name = "";
+ trx->mysql_master_log_file_name = (char*) "";
trx->mysql_master_log_pos = 0;
- trx->ignore_duplicates_in_insert = FALSE;
-
mutex_create(&(trx->undo_mutex));
mutex_set_level(&(trx->undo_mutex), SYNC_TRX_UNDO);
@@ -127,12 +133,15 @@ trx_create(
trx->graph = NULL;
trx->wait_lock = NULL;
+ trx->was_chosen_as_deadlock_victim = FALSE;
UT_LIST_INIT(trx->wait_thrs);
trx->lock_heap = mem_heap_create_in_buffer(256);
UT_LIST_INIT(trx->trx_locks);
- trx->has_dict_foreign_key_check_lock = FALSE;
+ UT_LIST_INIT(trx->trx_savepoints);
+
+ trx->dict_operation_lock_mode = 0;
trx->has_search_latch = FALSE;
trx->search_latch_timeout = BTR_SEA_TIMEOUT;
@@ -163,7 +172,7 @@ trx_allocate_for_mysql(void)
if (!trx_dummy_sess) {
trx_dummy_sess = sess_open(NULL, (byte*)"Dummy sess",
- ut_strlen("Dummy sess"));
+ ut_strlen((char *) "Dummy sess"));
}
trx = trx_create(trx_dummy_sess);
@@ -175,6 +184,8 @@ trx_allocate_for_mysql(void)
mutex_exit(&kernel_mutex);
trx->mysql_thread_id = os_thread_get_curr_id();
+
+ trx->mysql_process_no = os_proc_get_number();
return(trx);
}
@@ -228,8 +239,19 @@ trx_free(
/*=====*/
trx_t* trx) /* in, own: trx object */
{
+ char err_buf[1000];
+
ut_ad(mutex_own(&kernel_mutex));
+ if (trx->declared_to_be_inside_innodb) {
+ ut_print_timestamp(stderr);
+ trx_print(err_buf, trx);
+
+ fprintf(stderr,
+" InnoDB: Error: Freeing a trx which is declared to be processing\n"
+"InnoDB: inside InnoDB.\n%s\n", err_buf);
+ }
+
ut_a(trx->magic_n == TRX_MAGIC_N);
trx->magic_n = 11112222;
@@ -257,6 +279,8 @@ trx_free(
ut_a(!trx->has_search_latch);
ut_a(!trx->auto_inc_lock);
+ ut_a(trx->dict_operation_lock_mode == 0);
+
if (trx->lock_heap) {
mem_heap_free(trx->lock_heap);
}
@@ -758,24 +782,64 @@ trx_commit_off_kernel(
efficient here: call os_thread_yield here to allow also other
trxs to come to commit! */
- /* We now flush the log, as the transaction made changes to
- the database, making the transaction committed on disk. It is
- enough that any one of the log groups gets written to disk. */
-
/*-------------------------------------*/
- /* Most MySQL users run with srv_flush_.. set to FALSE: */
-
- if (srv_flush_log_at_trx_commit) {
+ /* Depending on the my.cnf options, we may now write the log
+ buffer to the log files, making the transaction durable if
+ the OS does not crash. We may also flush the log files to
+ disk, making the transaction durable also at an OS crash or a
+ power outage.
+
+ The idea in InnoDB's group commit is that a group of
+ transactions gather behind a trx doing a physical disk write
+ to log files, and when that physical write has been completed,
+ one of those transactions does a write which commits the whole
+ group. Note that this group commit will only bring benefit if
+ there are > 2 users in the database. Then at least 2 users can
+ gather behind one doing the physical log write to disk.
+
+ If we are calling trx_commit() under MySQL's binlog mutex, we
+ will delay possible log write and flush to a separate function
+ trx_commit_complete_for_mysql(), which is only called when the
+ thread has released the binlog mutex. This is to make the
+ group commit algorithm to work. Otherwise, the MySQL binlog
+ mutex would serialize all commits and prevent a group of
+ transactions from gathering. */
+
+ if (trx->flush_log_later) {
+ /* Do nothing yet */
+ } else if (srv_flush_log_at_trx_commit == 0) {
+ /* Do nothing */
+ } else if (srv_flush_log_at_trx_commit == 1) {
+ if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
+ /* Write the log but do not flush it to disk */
+
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
+ } else {
+ /* Write the log to the log files AND flush
+ them to disk */
+
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
+ }
+ } else if (srv_flush_log_at_trx_commit == 2) {
+
+ /* Write the log but do not flush it to disk */
+
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
+ } else {
+ ut_a(0);
+ }
+
+ trx->commit_lsn = lsn;
- log_flush_up_to(lsn, LOG_WAIT_ONE_GROUP);
- }
-
/*-------------------------------------*/
mutex_enter(&kernel_mutex);
}
+ /* Free savepoints */
+ trx_roll_savepoints_free(trx, NULL);
+
trx->conc_state = TRX_NOT_STARTED;
trx->rseg = NULL;
trx->undo_no = ut_dulint_zero;
@@ -1135,7 +1199,7 @@ trx_sig_send(
ut_a(0);
sess_raise_error_low(trx, 0, 0, NULL, NULL, NULL, NULL,
- "Signal from another session, or a break execution signal");
+ (char *) "Signal from another session, or a break execution signal");
}
/* If there were no other signals ahead in the queue, try to start
@@ -1436,7 +1500,7 @@ trx_commit_for_mysql(
ut_a(trx);
- trx->op_info = "committing";
+ trx->op_info = (char *) "committing";
trx_start_if_not_started(trx);
@@ -1446,12 +1510,55 @@ trx_commit_for_mysql(
mutex_exit(&kernel_mutex);
- trx->op_info = "";
+ trx->op_info = (char *) "";
return(0);
}
/**************************************************************************
+If required, flushes the log to disk if we called trx_commit_for_mysql()
+with trx->flush_log_later == TRUE. */
+
+ulint
+trx_commit_complete_for_mysql(
+/*==========================*/
+ /* out: 0 or error number */
+ trx_t* trx) /* in: trx handle */
+{
+ dulint lsn = trx->commit_lsn;
+
+ ut_a(trx);
+
+ trx->op_info = (char*)"flushing log";
+
+ if (srv_flush_log_at_trx_commit == 0) {
+ /* Do nothing */
+ } else if (srv_flush_log_at_trx_commit == 1) {
+ if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
+ /* Write the log but do not flush it to disk */
+
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
+ } else {
+ /* Write the log to the log files AND flush them to
+ disk */
+
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
+ }
+ } else if (srv_flush_log_at_trx_commit == 2) {
+
+ /* Write the log but do not flush it to disk */
+
+ log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
+ } else {
+ ut_a(0);
+ }
+
+ trx->op_info = (char*)"";
+
+ return(0);
+}
+
+/**************************************************************************
Marks the latest SQL statement ended. */
void
@@ -1497,6 +1604,9 @@ trx_print(
default: buf += sprintf(buf, " state %lu", trx->conc_state);
}
+#ifdef UNIV_LINUX
+ buf += sprintf(buf, ", process no %lu", trx->mysql_process_no);
+#endif
buf += sprintf(buf, ", OS thread id %lu",
os_thread_pf(trx->mysql_thread_id));
@@ -1508,7 +1618,19 @@ trx_print(
buf += sprintf(buf, " purge trx");
}
+ if (trx->declared_to_be_inside_innodb) {
+ buf += sprintf(buf, ", thread declared inside InnoDB %lu",
+ trx->n_tickets_to_enter_innodb);
+ }
+
buf += sprintf(buf, "\n");
+
+ if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) {
+
+ buf += sprintf(buf, "mysql tables in use %lu, locked %lu\n",
+ trx->n_mysql_tables_in_use,
+ trx->mysql_n_tables_locked);
+ }
start_of_line = buf;
diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c
index b0a281110ae..34f56dba130 100644
--- a/innobase/trx/trx0undo.c
+++ b/innobase/trx/trx0undo.c
@@ -374,7 +374,7 @@ trx_undo_seg_create(
/*================*/
/* out: segment header page x-latched, NULL
if no space left */
- trx_rseg_t* rseg, /* in: rollback segment */
+ trx_rseg_t* rseg __attribute__((unused)),/* in: rollback segment */
trx_rsegf_t* rseg_hdr,/* in: rollback segment header, page
x-latched */
ulint type, /* in: type of the segment: TRX_UNDO_INSERT or
@@ -661,7 +661,7 @@ trx_undo_parse_discard_latest(
/*==========================*/
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
+ byte* end_ptr __attribute__((unused)), /* in: buffer end */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -848,7 +848,7 @@ static
void
trx_undo_free_page_in_rollback(
/*===========================*/
- trx_t* trx, /* in: transaction */
+ trx_t* trx __attribute__((unused)), /* in: transaction */
trx_undo_t* undo, /* in: undo log memory copy */
ulint page_no,/* in: page number to free: must not be the
header page */
@@ -1568,7 +1568,7 @@ trx_undo_set_state_at_finish(
/*=========================*/
/* out: undo log segment header page,
x-latched */
- trx_t* trx, /* in: transaction */
+ trx_t* trx __attribute__((unused)), /* in: transaction */
trx_undo_t* undo, /* in: undo log memory copy */
mtr_t* mtr) /* in: mtr */
{
diff --git a/innobase/usr/Makefile.am b/innobase/usr/Makefile.am
index a71d0d41ac0..bdcc832a76e 100644
--- a/innobase/usr/Makefile.am
+++ b/innobase/usr/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libusr.a
+noinst_LIBRARIES = libusr.a
libusr_a_SOURCES = usr0sess.c
diff --git a/innobase/ut/Makefile.am b/innobase/ut/Makefile.am
index de3cf41b767..2fdbb99e0f3 100644
--- a/innobase/ut/Makefile.am
+++ b/innobase/ut/Makefile.am
@@ -17,7 +17,7 @@
include ../include/Makefile.i
-libs_LIBRARIES = libut.a
+noinst_LIBRARIES = libut.a
libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c
diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c
index 2a7643551ad..f5d207d8bba 100644
--- a/innobase/ut/ut0mem.c
+++ b/innobase/ut/ut0mem.c
@@ -80,7 +80,7 @@ ut_malloc_low(
fprintf(stderr,
"InnoDB: Fatal error: cannot allocate %lu bytes of\n"
"InnoDB: memory with malloc! Total allocated memory\n"
- "InnoDB: by InnoDB %lu bytes. Operating system errno: %d\n"
+ "InnoDB: by InnoDB %lu bytes. Operating system errno: %lu\n"
"InnoDB: Cannot continue operation!\n"
"InnoDB: Check if you should increase the swap file or\n"
"InnoDB: ulimits of your operating system.\n"
@@ -88,7 +88,19 @@ ut_malloc_low(
"InnoDB: a big enough maximum process size.\n"
"InnoDB: We now intentionally generate a seg fault so that\n"
"InnoDB: on Linux we get a stack trace.\n",
- n, ut_total_allocated_memory, errno);
+ n, ut_total_allocated_memory,
+#ifdef __WIN__
+ (ulint)GetLastError()
+#else
+ (ulint)errno
+#endif
+ );
+
+ /* Flush stderr to make more probable that the error
+ message gets in the error file before we generate a seg
+ fault */
+
+ fflush(stderr);
os_fast_mutex_unlock(&ut_list_mutex);
@@ -154,7 +166,7 @@ ut_free(
}
/**************************************************************************
-Frees all allocated memory not freed yet. */
+Frees in shutdown all allocated memory not freed yet. */
void
ut_free_all_mem(void)
@@ -162,7 +174,7 @@ ut_free_all_mem(void)
{
ut_mem_block_t* block;
- os_fast_mutex_lock(&ut_list_mutex);
+ os_fast_mutex_free(&ut_list_mutex);
while ((block = UT_LIST_GET_FIRST(ut_mem_block_list))) {
@@ -175,9 +187,11 @@ ut_free_all_mem(void)
free(block);
}
- os_fast_mutex_unlock(&ut_list_mutex);
-
- ut_a(ut_total_allocated_memory == 0);
+ if (ut_total_allocated_memory != 0) {
+ fprintf(stderr,
+"InnoDB: Warning: after shutdown total allocated memory is %lu\n",
+ ut_total_allocated_memory);
+ }
}
/**************************************************************************
diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c
index 2274e723be9..06bfb5c45ba 100644
--- a/innobase/ut/ut0ut.c
+++ b/innobase/ut/ut0ut.c
@@ -52,11 +52,13 @@ ut_get_high32(
/* out: a >> 32 */
ulint a) /* in: ulint */
{
- if (sizeof(ulint) == 4) {
- return(0);
- }
+#if SIZEOF_LONG == 4
+ UT_NOT_USED(a);
+ return 0;
+#else
return(a >> 32);
+#endif
}
/************************************************************
@@ -197,7 +199,6 @@ ut_get_year_month_day(
*month = (ulint)cal_tm.wMonth;
*day = (ulint)cal_tm.wDay;
#else
- struct tm cal_tm;
struct tm* cal_tm_ptr;
time_t tm;
@@ -205,7 +206,7 @@ ut_get_year_month_day(
cal_tm_ptr = localtime(&tm);
- *year = (ulint)cal_tm_ptr->tm_year;
+ *year = (ulint)cal_tm_ptr->tm_year + 1900;
*month = (ulint)cal_tm_ptr->tm_mon + 1;
*day = (ulint)cal_tm_ptr->tm_mday;
#endif
@@ -262,7 +263,7 @@ ut_print_buf(
data = buf;
for (i = 0; i < len; i++) {
- if (isprint((char)(*data))) {
+ if (isprint((int)(*data))) {
printf("%c", (char)*data);
}
data++;
@@ -302,7 +303,7 @@ ut_sprintf_buf(
data = buf;
for (i = 0; i < len; i++) {
- if (isprint((char)(*data))) {
+ if (isprint((int)(*data))) {
n += sprintf(str + n, "%c", (char)*data);
} else {
n += sprintf(str + n, ".");
diff --git a/isam/_cache.c b/isam/_cache.c
index 53619126660..bca9a699a85 100644
--- a/isam/_cache.c
+++ b/isam/_cache.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -46,11 +46,11 @@ int _nisam_read_cache(IO_CACHE *info, byte *buff, ulong pos, uint length,
buff+=read_length;
}
if ((offset=pos - (ulong) info->pos_in_file) <
- (ulong) (info->rc_end - info->rc_request_pos))
+ (ulong) (info->read_end - info->request_pos))
{
- in_buff_pos=info->rc_request_pos+(uint) offset;
- in_buff_length= min(length,(uint) (info->rc_end-in_buff_pos));
- memcpy(buff,info->rc_request_pos+(uint) offset,(size_t) in_buff_length);
+ in_buff_pos=info->request_pos+(uint) offset;
+ in_buff_length= min(length,(uint) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
if (!(length-=in_buff_length))
return 0;
pos+=in_buff_length;
@@ -61,14 +61,14 @@ int _nisam_read_cache(IO_CACHE *info, byte *buff, ulong pos, uint length,
if (flag & READING_NEXT)
{
if (pos != ((info)->pos_in_file +
- (uint) ((info)->rc_end - (info)->rc_request_pos)))
+ (uint) ((info)->read_end - (info)->request_pos)))
{
info->pos_in_file=pos; /* Force start here */
- info->rc_pos=info->rc_end=info->rc_request_pos; /* Everything used */
+ info->read_pos=info->read_end=info->request_pos; /* Everything used */
info->seek_not_done=1;
}
else
- info->rc_pos=info->rc_end; /* All block used */
+ info->read_pos=info->read_end; /* All block used */
if (!(*info->read_function)(info,buff,length))
return 0;
if (!(flag & READING_HEADER) || info->error == -1 ||
diff --git a/isam/_dbug.c b/isam/_dbug.c
index 18e671793ed..0a52dbbc916 100644
--- a/isam/_dbug.c
+++ b/isam/_dbug.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/_dynrec.c b/isam/_dynrec.c
index 2a908f5b42c..d17d34e6778 100644
--- a/isam/_dynrec.c
+++ b/isam/_dynrec.c
@@ -432,7 +432,7 @@ uint _nisam_rec_pack(N_INFO *info, register byte *to, register const byte *from)
blob++;
from+=sizeof(char*); /* Skipp blob-pointer */
}
- else if (type == FIELD_SKIPP_ZERO)
+ else if (type == FIELD_SKIP_ZERO)
{
if (memcmp((byte*) from,zero_string,length) == 0)
flag|=bit;
@@ -441,11 +441,11 @@ uint _nisam_rec_pack(N_INFO *info, register byte *to, register const byte *from)
memcpy((byte*) to,from,(size_t) length); to+=length;
}
}
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
pos= (byte*) from; end= (byte*) from + length;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{ /* Pack trailing spaces */
while (end > from && *(end-1) == ' ')
end--;
@@ -532,7 +532,7 @@ my_bool _nisam_rec_check(N_INFO *info,const char *from)
to+=length+ blob_length;
from+=sizeof(char*);
}
- else if (type == FIELD_SKIPP_ZERO)
+ else if (type == FIELD_SKIP_ZERO)
{
if (memcmp((byte*) from,zero_string,length) == 0)
{
@@ -542,11 +542,11 @@ my_bool _nisam_rec_check(N_INFO *info,const char *from)
else
to+=length;
}
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
pos= (byte*) from; end= (byte*) from + length;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{ /* Pack trailing spaces */
while (end > from && *(end-1) == ' ')
end--;
@@ -641,10 +641,10 @@ uint _nisam_rec_unpack(register N_INFO *info, register byte *to, byte *from,
bzero((byte*) to,rec_length+sizeof(char*));
to+=sizeof(char*);
}
- else if (type == FIELD_SKIPP_ZERO)
+ else if (type == FIELD_SKIP_ZERO)
bzero((byte*) to,rec_length);
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
if (rec->base.length > 255 && *from & 128)
{
@@ -662,7 +662,7 @@ uint _nisam_rec_unpack(register N_INFO *info, register byte *to, byte *from,
if (length >= rec_length ||
min_pack_length + length > (uint) (from_end - from))
goto err;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{
memcpy(to,(byte*) from,(size_t) length);
bfill((byte*) to+length,rec_length-length,' ');
@@ -690,7 +690,7 @@ uint _nisam_rec_unpack(register N_INFO *info, register byte *to, byte *from,
}
else
{
- if (type == FIELD_SKIPP_ENDSPACE || type == FIELD_SKIPP_PRESPACE)
+ if (type == FIELD_SKIP_ENDSPACE || type == FIELD_SKIP_PRESPACE)
min_pack_length--;
if (min_pack_length + rec_length > (uint) (from_end - from))
goto err;
diff --git a/isam/_key.c b/isam/_key.c
index 62f080af172..c0d667cb32d 100644
--- a/isam/_key.c
+++ b/isam/_key.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/_locking.c b/isam/_locking.c
index ca38c611812..be9741a4237 100644
--- a/isam/_locking.c
+++ b/isam/_locking.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -306,8 +306,8 @@ int _nisam_writeinfo(register N_INFO *info, uint flags)
MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
DBUG_RETURN(1);
}
- }
#endif
+ }
my_errno=olderror;
}
else if (flags)
diff --git a/isam/_packrec.c b/isam/_packrec.c
index 5c387f011ad..74a45852e63 100644
--- a/isam/_packrec.c
+++ b/isam/_packrec.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -456,7 +456,7 @@ int _nisam_pack_rec_unpack(register N_INFO *info, register byte *to,
static void (*get_unpack_function(N_RECINFO *rec))(N_RECINFO *, BIT_BUFF *, uchar *, uchar *)
{
switch (rec->base_type) {
- case FIELD_SKIPP_ZERO:
+ case FIELD_SKIP_ZERO:
if (rec->pack_type & PACK_TYPE_ZERO_FILL)
return &uf_zerofill_skipp_zero;
return &uf_skipp_zero;
@@ -466,7 +466,7 @@ static void (*get_unpack_function(N_RECINFO *rec))(N_RECINFO *, BIT_BUFF *, ucha
if (rec->pack_type & PACK_TYPE_ZERO_FILL)
return &uf_zerofill_normal;
return &decode_bytes;
- case FIELD_SKIPP_ENDSPACE:
+ case FIELD_SKIP_ENDSPACE:
if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
{
if (rec->pack_type & PACK_TYPE_SELECTED)
@@ -476,7 +476,7 @@ static void (*get_unpack_function(N_RECINFO *rec))(N_RECINFO *, BIT_BUFF *, ucha
if (rec->pack_type & PACK_TYPE_SELECTED)
return &uf_endspace_selected;
return &uf_endspace;
- case FIELD_SKIPP_PRESPACE:
+ case FIELD_SKIP_PRESPACE:
if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
{
if (rec->pack_type & PACK_TYPE_SELECTED)
diff --git a/isam/_page.c b/isam/_page.c
index 6f6d632e85d..65733d66b77 100644
--- a/isam/_page.c
+++ b/isam/_page.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/_search.c b/isam/_search.c
index c005e9ddb69..32492f83929 100644
--- a/isam/_search.c
+++ b/isam/_search.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/_statrec.c b/isam/_statrec.c
index d93f4fe27f5..9dbc948440f 100644
--- a/isam/_statrec.c
+++ b/isam/_statrec.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -187,7 +187,7 @@ int _nisam_read_rnd_static_record(N_INFO *info, byte *buf,
(skipp_deleted_blocks || !filepos))
{
cache_read=1; /* Read record using cache */
- cache_length=(uint) (info->rec_cache.rc_end - info->rec_cache.rc_pos);
+ cache_length=(uint) (info->rec_cache.read_end - info->rec_cache.read_pos);
}
else
info->rec_cache.seek_not_done=1; /* Filepos is changed */
diff --git a/isam/changed.c b/isam/changed.c
index 4f87a45aa2d..b8132538b86 100644
--- a/isam/changed.c
+++ b/isam/changed.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/close.c b/isam/close.c
index 6741e7b23f0..f1465990100 100644
--- a/isam/close.c
+++ b/isam/close.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/create.c b/isam/create.c
index fcf54ddc731..4c23f3edd11 100644
--- a/isam/create.c
+++ b/isam/create.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -96,8 +96,8 @@ int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo,
pack_reclength+=sizeof(char*)+(1 << (rec->base.length*8));
}
}
- else if (type == FIELD_SKIPP_PRESPACE ||
- type == FIELD_SKIPP_ENDSPACE)
+ else if (type == FIELD_SKIP_PRESPACE ||
+ type == FIELD_SKIP_ENDSPACE)
{
if (pack_reclength != NI_POS_ERROR)
pack_reclength+= rec->base.length > 255 ? 2 : 1;
@@ -105,7 +105,7 @@ int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo,
}
else if (type == FIELD_ZERO)
packed--;
- else if (type != FIELD_SKIPP_ZERO)
+ else if (type != FIELD_SKIP_ZERO)
{
min_pack_length+=rec->base.length;
packed--; /* Not a pack record type */
@@ -119,7 +119,7 @@ int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo,
while (rec != recinfo)
{
rec--;
- if (rec->base.type == (int) FIELD_SKIPP_ZERO && rec->base.length == 1)
+ if (rec->base.type == (int) FIELD_SKIP_ZERO && rec->base.length == 1)
{
rec->base.type=(int) FIELD_NORMAL;
packed--;
@@ -294,13 +294,13 @@ int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo,
goto err;
/* Enlarge files */
- if (my_chsize(file,(ulong) share.base.keystart,MYF(0)))
+ if (my_chsize(file, (ulong) share.base.keystart, 0, MYF(0)))
goto err;
if (! (flags & HA_DONT_TOUCH_DATA))
{
#ifdef USE_RELOC
- if (my_chsize(dfile,share.base.min_pack_length*reloc,MYF(0)))
+ if (my_chsize(dfile, share.base.min_pack_length*reloc, 0, MYF(0)))
goto err;
#endif
errpos=1;
diff --git a/isam/delete.c b/isam/delete.c
index e50ad72c767..5aa542561c1 100644
--- a/isam/delete.c
+++ b/isam/delete.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -613,5 +613,3 @@ static uint remove_key(N_KEYDEF *keyinfo, uint nod_flag,
(uint) (page_end-start-s_length));
DBUG_RETURN((uint) s_length);
} /* remove_key */
-
-
diff --git a/isam/extra.c b/isam/extra.c
index 1d333fa372f..3bf1dd012ed 100644
--- a/isam/extra.c
+++ b/isam/extra.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -123,6 +123,7 @@ int nisam_extra(N_INFO *info, enum ha_extra_function function)
}
#endif
if (!(info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED)))
+ {
if (!(init_io_cache(&info->rec_cache,info->dfile,0,
WRITE_CACHE,info->s->state.data_file_length,
(pbool) (info->lock_type != F_UNLCK),
@@ -131,7 +132,12 @@ int nisam_extra(N_INFO *info, enum ha_extra_function function)
info->opt_flag|=WRITE_CACHE_USED;
info->update&= ~HA_STATE_ROW_CHANGED;
}
+ }
break;
+ case HA_EXTRA_PREPARE_FOR_UPDATE:
+ if (info->s->data_file_type != DYNAMIC_RECORD)
+ break;
+ /* Remove read/write cache if dynamic rows */
case HA_EXTRA_NO_CACHE:
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
{
@@ -204,6 +210,7 @@ int nisam_extra(N_INFO *info, enum ha_extra_function function)
info->s->changed=1; /* Update on close */
break;
case HA_EXTRA_FORCE_REOPEN:
+ case HA_EXTRA_PREPARE_FOR_DELETE:
pthread_mutex_lock(&THR_LOCK_isam);
info->s->last_version= 0L; /* Impossible version */
#ifdef __WIN__
@@ -243,17 +250,15 @@ int nisam_extra(N_INFO *info, enum ha_extra_function function)
pthread_mutex_unlock(&THR_LOCK_isam);
break;
case HA_EXTRA_FLUSH:
-#ifdef __WIN__
if (info->s->not_flushed)
{
info->s->not_flushed=0;
- if (_commit(info->s->kfile))
- error=errno;
- if (_commit(info->dfile))
- error=errno;
+ if (my_sync(info->s->kfile, MYF(0)))
+ error= my_errno;
+ if (my_sync(info->dfile, MYF(0)))
+ error= my_errno;
}
break;
-#endif
case HA_EXTRA_NORMAL: /* Theese isn't in use */
case HA_EXTRA_QUICK:
case HA_EXTRA_KEY_CACHE:
diff --git a/isam/info.c b/isam/info.c
index 43c15af908d..a23494e4876 100644
--- a/isam/info.c
+++ b/isam/info.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/isamchk.c b/isam/isamchk.c
index 3aa1cf4e3c2..35b4e881962 100644
--- a/isam/isamchk.c
+++ b/isam/isamchk.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,7 +20,7 @@
#include <m_ctype.h>
#include <stdarg.h>
-#include <getopt.h>
+#include <my_getopt.h>
#ifdef HAVE_SYS_VADVICE_H
#include <sys/vadvise.h>
#endif
@@ -62,7 +62,7 @@ SET_STACK_SIZE(9000) /* Minimum stack size for program */
#define MIN_SORT_BUFFER (4096-MALLOC_OVERHEAD)
#endif
-#define NEAD_MEM ((uint) 10*4*(IO_SIZE+32)+32) /* Nead for recursion */
+#define NEED_MEM ((uint) 10*4*(IO_SIZE+32)+32) /* Nead for recursion */
#define MAXERR 20
#define BUFFERS_WHEN_SORTING 16 /* Alloc for sort-key-tree */
#define WRITE_COUNT MY_HOW_OFTEN_TO_WRITE
@@ -94,12 +94,16 @@ typedef struct st_isam_sort_info {
N_KEYSEG *keyseg;
} ISAM_SORT_INFO;
-enum ic_options {OPT_CHARSETS_DIR_IC=256};
+enum ic_options {OPT_CHARSETS_DIR_IC=256, OPT_KEY_BUFFER_SIZE,
+ OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE,
+ OPT_SORT_BUFFER_SIZE, OPT_SORT_KEY_BLOCKS,
+ OPT_DECODE_BITS};
static ulong use_buffers=0,read_buffer_length=0,write_buffer_length=0,
sort_buffer_length=0,sort_key_blocks=0,crc=0,unique_count=0;
static uint testflag=0,out_flag=0,warning_printed=0,error_printed=0,
- rep_quick=0,verbose=0,opt_follow_links=1;
+ verbose=0,opt_follow_links=1;
+static my_bool rep_quick= 0;
static uint opt_sort_key=0,total_files=0,max_level=0,max_key=N_MAXKEY;
static ulong keydata=0,totaldata=0,key_blocks=0;
static ulong new_file_pos=0,record_checksum=0,key_file_blocks=0,decode_bits;
@@ -234,118 +238,118 @@ int main( int argc, char **argv)
} /* main */
-static CHANGEABLE_VAR changeable_vars[] = {
- { "key_buffer_size",(long*) &use_buffers,(long) USE_BUFFER_INIT,
- (long) MALLOC_OVERHEAD, (long) ~0L,(long) MALLOC_OVERHEAD,(long) IO_SIZE },
- { "read_buffer_size", (long*) &read_buffer_length,(long) READ_BUFFER_INIT,
- (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L },
- { "write_buffer_size", (long*) &write_buffer_length,(long) READ_BUFFER_INIT,
- (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L },
- { "sort_buffer_size",(long*) &sort_buffer_length,(long) SORT_BUFFER_INIT,
- (long) (MIN_SORT_BUFFER+MALLOC_OVERHEAD),(long) ~0L,
- (long) MALLOC_OVERHEAD,(long) 1L },
- { "sort_key_blocks",(long*) &sort_key_blocks,BUFFERS_WHEN_SORTING,4L,100L,0L,
- 1L },
- { "decode_bits",(long*) &decode_bits,9L,4L,17L,0L,1L },
- { NullS,(long*) 0,0L,0L,0L,0L,0L,} };
-
-
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"analyze", no_argument, 0, 'a'},
- {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR_IC},
+ {"analyze", 'a',
+ "Analyze distribution of keys. Will make some joins in MySQL faster.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR_IC,
+ "Directory where character sets are", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", required_argument, 0, '#'},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"default-character-set", required_argument, 0, 'C'},
- {"description", no_argument, 0, 'd'},
- {"extend-check", no_argument, 0, 'e'},
- {"information", no_argument, 0, 'i'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"keys-used", required_argument, 0, 'k'},
- {"no-symlinks", no_argument, 0, 'l'},
- {"quick", no_argument, 0, 'q'},
- {"recover", no_argument, 0, 'r'},
- {"safe-recover", no_argument, 0, 'o'},
- {"block-search", required_argument, 0, 'b'},
- {"set-variable", required_argument, 0, 'O'},
- {"silent", no_argument, 0, 's'},
- {"sort-index", no_argument, 0, 'S'},
- {"sort-records", required_argument, 0, 'R'},
- {"unpack", no_argument, 0, 'u'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"wait", no_argument, 0, 'w'},
- {0, 0, 0, 0}
+ {"default-character-set", 'C', "Set the default character set",
+ (gptr*) &default_charset, (gptr*) &default_charset, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"description", 'd', "Prints some information about table.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"extend-check", 'e',
+ "Check the table VERY thoroughly. One need to use this only in extreme cases, because isamchk should normally find all errors even without this switch.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"information", 'i', "Print statistics information about the table",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"force", 'f',
+ "Overwrite old temporary files. If one uses -f when checking tables (running isamchk without -r), isamchk will automatically restart with -r on any wrong table.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"keys-used", 'k',
+ "Used with '-r'. Tell ISAM to update only the first # keys. This can be used to get faster inserts!",
+ (gptr*) &max_key, (gptr*) &max_key, 0, GET_UINT, REQUIRED_ARG, N_MAXKEY, 0,
+ 0, 0, 0, 0},
+ {"no-symlinks", 'l',
+ "Do not follow symbolic links when repairing. Normally isamchk repairs the table a symlink points at.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"quick", 'q',
+ "Used with -r to get a faster repair. (The data file isn't touched.) One can give a second '-q' to force isamchk to modify the original datafile.",
+ (gptr*) &rep_quick, (gptr*) &rep_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"recover", 'r',
+ "Can fix almost anything except unique keys that aren't unique.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"safe-recover", 'o',
+ "Uses old recovery method; slower than '-r' but can handle a couple of cases that '-r' cannot handle.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"block-search", 'b', "For debugging.", (gptr*) &search_after_block,
+ (gptr*) &search_after_block, 0, GET_ULONG, REQUIRED_ARG, NI_POS_ERROR, 0,
+ 0, 0, 0, 0},
+ {"silent", 's',
+ "Only print errors. One can use two -s to make isamchk very silent.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sort-index", 'S',
+ "Sort index blocks. This speeds up 'read-next' in applications.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sort-records", 'R',
+ "Sort records according to an index. This makes your data much more localized and may speed up things (It may be VERY slow to do a sort the first time!)",
+ (gptr*) &opt_sort_key, (gptr*) &opt_sort_key, 0, GET_UINT, REQUIRED_ARG,
+ 0, 0, (N_MAXKEY - 1), 1, 0, 0},
+ {"unpack", 'u', "Unpack file packed with pack_isam.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v',
+ "Print more information. This can be used with -d and -e. Use many -v for more verbosity!",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Print version and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"wait", 'w', "Wait if table is locked.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_buffer_size", OPT_KEY_BUFFER_SIZE, "", (gptr*) &use_buffers,
+ (gptr*) &use_buffers, 0, GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT,
+ (long) MALLOC_OVERHEAD, (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE,
+ 0},
+ {"read_buffer_size", OPT_READ_BUFFER_SIZE, "",
+ (gptr*) &read_buffer_length, (gptr*) &read_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
+ (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ {"write_buffer_size", OPT_WRITE_BUFFER_SIZE, "",
+ (gptr*) &write_buffer_length, (gptr*) &write_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, (long) ~0L,
+ (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ {"sort_buffer_size", OPT_SORT_BUFFER_SIZE, "",
+ (gptr*) &sort_buffer_length, (gptr*) &sort_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, (long) SORT_BUFFER_INIT,
+ (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), (long) ~0L,
+ (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ {"sort_key_blocks", OPT_SORT_KEY_BLOCKS, "",
+ (gptr*) &sort_key_blocks, (gptr*) &sort_key_blocks, 0, GET_ULONG,
+ REQUIRED_ARG, BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0},
+ {"decode_bits", OPT_DECODE_BITS, "",
+ (gptr*) &decode_bits, (gptr*) &decode_bits, 0, GET_ULONG, REQUIRED_ARG,
+ 9L, 4L, 17L, 0L, 1L, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void print_version(void)
{
- printf("%s Ver 5.17 for %s at %s\n",my_progname,SYSTEM_TYPE,
+ printf("%s Ver 6.01 for %s at %s\n", my_progname, SYSTEM_TYPE,
MACHINE_TYPE);
}
static void usage(void)
{
- uint i;
print_version();
- puts("TCX Datakonsult AB, by Monty, for your professional use");
+ puts("MySQL AB, by Monty, for your professional use");
puts("This software comes with NO WARRANTY: see the PUBLIC for details.\n");
puts("Description, check and repair of ISAM tables.");
puts("Used without options all tables on the command will be checked for errors");
printf("Usage: %s [OPTIONS] tables[.ISM]\n", my_progname);
- puts("\n\
- -a, --analyze Analyze distribution of keys. Will make some joins in\n\
- MySQL faster.\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename`\n\
- --character-sets-dir=...\n\
- Directory where character sets are\n\
- -C, --default-character-set=...\n\
- Set the default character set\n\
- -d, --description Prints some information about table.\n\
- -e, --extend-check Check the table VERY thoroughly. One need use this\n\
- only in extreme cases as isamchk should normally find\n\
- all errors even without this switch\n\
- -f, --force Overwrite old temporary files.\n\
- If one uses -f when checking tables (running isamchk\n\
- without -r), isamchk will automatically restart with\n\
- -r on any wrong table.\n\
- -?, --help Display this help and exit.\n\
- -i, --information Print statistics information about the table\n\
- -k, --keys-used=# Used with '-r'. Tell ISAM to update only the first\n\
- # keys. This can be used to get faster inserts!\n\
- -l, --no-symlinks Do not follow symbolic links when repairing. Normally\n\
- isamchk repairs the table a symlink points at.\n\
- -q, --quick Used with -r to get a faster repair. (The data file\n\
- isn't touched.) One can give a second '-q' to force\n\
- isamchk to modify the original datafile.");
- puts("\
- -r, --recover Can fix almost anything except unique keys that aren't\n\
- unique.\n\
- -o, --safe-recover Uses old recovery method; slower than '-r' but can\n\
- handle a couple of cases that '-r' cannot handle.\n\
- -O, --set-variable var=option\n\
- Change the value of a variable.\n\
- -s, --silent Only print errors. One can use two -s to make isamchk\n\
- very silent\n\
- -S, --sort-index Sort index blocks. This speeds up 'read-next' in\n\
- applications\n\
- -R, --sort-records=#\n\
- Sort records according to an index. This makes your\n\
- data much more localized and may speed up things\n\
- (It may be VERY slow to do a sort the first time!)\n\
- -u, --unpack Unpack file packed with pack_isam.\n\
- -v, --verbose Print more information. This can be used with\n\
- -d and -e. Use many -v for more verbosity!\n\
- -V, --version Print version and exit.\n\
- -w, --wait Wait if table is locked.");
- print_defaults("my",load_default_groups);
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (i=0; changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- changeable_vars[i].name,
- *changeable_vars[i].varptr);
+ my_print_help(my_long_options);
+ print_defaults("my", load_default_groups);
+ my_print_variables(my_long_options);
}
/* Check table */
@@ -512,7 +516,7 @@ static int nisamchk(my_string filename)
if (!rep_quick)
{
if (testflag & T_EXTEND)
- VOID(init_key_cache(use_buffers,(uint) NEAD_MEM));
+ VOID(init_key_cache(use_buffers));
VOID(init_io_cache(&read_cache,datafile,(uint) read_buffer_length,
READ_CACHE,share->pack.header_length,1,
MYF(MY_WME)));
@@ -575,112 +579,94 @@ end2:
} /* nisamchk */
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+
+{
+ switch(optid) {
+ case 'a':
+ testflag|= T_STATISTICS;
+ break;
+ case 's': /* silent */
+ if (testflag & T_SILENT)
+ testflag|=T_VERY_SILENT;
+ testflag|= T_SILENT;
+ testflag&= ~T_WRITE_LOOP;
+ break;
+ case 'w':
+ testflag|= T_WAIT_FOREVER;
+ break;
+ case 'd': /* description if isam-file */
+ testflag|= T_DESCRIPT;
+ break;
+ case 'e': /* extend check */
+ testflag|= T_EXTEND;
+ break;
+ case 'i':
+ testflag|= T_INFO;
+ break;
+ case 'f':
+ tmpfile_createflag= O_RDWR | O_TRUNC;
+ testflag|=T_FORCE_CREATE;
+ break;
+ case 'l':
+ opt_follow_links=0;
+ break;
+ case 'r': /* Repair table */
+ testflag= (testflag & ~T_REP) | T_REP_BY_SORT;
+ break;
+ case 'o':
+ testflag= (testflag & ~T_REP_BY_SORT) | T_REP;
+ my_disable_async_io=1; /* More safety */
+ break;
+ case 'u':
+ testflag|= T_UNPACK | T_REP_BY_SORT;
+ break;
+ case 'v': /* Verbose */
+ testflag|= T_VERBOSE;
+ verbose++;
+ break;
+ case 'R': /* Sort records */
+ testflag|= T_SORT_RECORDS;
+ if (opt_sort_key >= N_MAXKEY)
+ {
+ fprintf(stderr,
+ "The value of the sort key is bigger than max key: %d.\n",
+ N_MAXKEY);
+ exit(1);
+ }
+ break;
+ case 'S': /* Sort index */
+ testflag|= T_SORT_INDEX;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o,/tmp/isamchk.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
/* Read options */
-static void get_options(register int *argc,register char ***argv)
+static void get_options(register int *argc, register char ***argv)
{
- int c,option_index=0;
+ int ho_error;
load_defaults("my",load_default_groups,argc,argv);
defaults_alloc= *argv;
- set_all_changeable_vars(changeable_vars);
if (isatty(fileno(stdout)))
testflag|=T_WRITE_LOOP;
- while ((c=getopt_long(*argc,*argv,"adeif?lqrosSuvVw#:b:k:O:R:C:",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'a':
- testflag|= T_STATISTICS;
- break;
- case 'C':
- default_charset=optarg;
- break;
- case OPT_CHARSETS_DIR_IC:
- charsets_dir = optarg;
- break;
- case 'b':
- search_after_block=strtoul(optarg,NULL,10);
- break;
- case 's': /* silent */
- if (testflag & T_SILENT)
- testflag|=T_VERY_SILENT;
- testflag|= T_SILENT;
- testflag&= ~T_WRITE_LOOP;
- break;
- case 'w':
- testflag|= T_WAIT_FOREVER;
- break;
- case 'd': /* description if isam-file */
- testflag|= T_DESCRIPT;
- break;
- case 'e': /* extend check */
- testflag|= T_EXTEND;
- break;
- case 'i':
- testflag|= T_INFO;
- break;
- case 'f':
- tmpfile_createflag= O_RDWR | O_TRUNC;
- testflag|=T_FORCE_CREATE;
- break;
- case 'k':
- max_key= (uint) atoi(optarg);
- break;
- case 'l':
- opt_follow_links=0;
- break;
- case 'r': /* Repair table */
- testflag= (testflag & ~T_REP) | T_REP_BY_SORT;
- break;
- case 'o':
- testflag= (testflag & ~T_REP_BY_SORT) | T_REP;
- my_disable_async_io=1; /* More safety */
- break;
- case 'q':
- rep_quick++;
- break;
- case 'u':
- testflag|= T_UNPACK | T_REP_BY_SORT;
- break;
- case 'v': /* Verbose */
- testflag|= T_VERBOSE;
- verbose++;
- break;
- case 'O':
- if (set_changeable_var(optarg, changeable_vars))
- {
- usage();
- exit(1);
- }
- break;
- case 'R': /* Sort records */
- testflag|= T_SORT_RECORDS;
- opt_sort_key=(uint) atoi(optarg)-1;
- if (opt_sort_key >= N_MAXKEY)
- {
- fprintf(stderr,
- "The value of the sort key is bigger than max key: %d.\n",
- N_MAXKEY);
- exit(1);
- }
- break;
- case 'S': /* Sort index */
- testflag|= T_SORT_INDEX;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/isamchk.trace");
- break;
- case 'V':
- print_version();
- exit(0);
- case '?':
- usage();
- exit(0);
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (*argc == 0)
{
usage();
@@ -1473,7 +1459,7 @@ my_string name;
printf("Data records: %lu\n",(ulong) share->state.records);
}
- VOID(init_key_cache(use_buffers,NEAD_MEM));
+ VOID(init_key_cache(use_buffers));
if (init_io_cache(&read_cache,info->dfile,(uint) read_buffer_length,
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)))
goto err;
@@ -1566,7 +1552,7 @@ my_string name;
{
VOID(fputs(" \r",stdout)); VOID(fflush(stdout));
}
- if (my_chsize(share->kfile,share->state.key_file_length,MYF(0)))
+ if (my_chsize(share->kfile, share->state.key_file_length, 0, MYF(0)))
{
print_warning("Can't change size of indexfile, error: %d",my_errno);
goto err;
@@ -1950,7 +1936,7 @@ int write_info;
if (share->state.key_root[sort_key] == NI_POS_ERROR)
DBUG_RETURN(0); /* Nothing to do */
- init_key_cache(use_buffers,NEAD_MEM);
+ init_key_cache(use_buffers);
if (init_io_cache(&info->rec_cache,-1,(uint) write_buffer_length,
WRITE_CACHE,share->pack.header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
@@ -2528,10 +2514,10 @@ my_string name;
skr=share->base.reloc*share->base.min_pack_length;
#endif
if (skr != sort_info.filelength)
- if (my_chsize(info->dfile,skr,MYF(0)))
+ if (my_chsize(info->dfile, skr, 0, MYF(0)))
print_warning("Can't change size of datafile, error: %d",my_errno);
}
- if (my_chsize(share->kfile,share->state.key_file_length,MYF(0)))
+ if (my_chsize(share->kfile, share->state.key_file_length, 0, MYF(0)))
print_warning("Can't change size of indexfile, error: %d",my_errno);
if (!(testflag & T_SILENT))
diff --git a/isam/isamdef.h b/isam/isamdef.h
index da08b5f6a14..0884b18e997 100644
--- a/isam/isamdef.h
+++ b/isam/isamdef.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/isamlog.c b/isam/isamlog.c
index 5763b697d07..0367c03e08a 100644
--- a/isam/isamlog.c
+++ b/isam/isamlog.c
@@ -327,9 +327,9 @@ static int examine_log(my_string file_name, char **table_names)
init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0));
bzero((gptr) com_count,sizeof(com_count));
- init_tree(&tree,0,sizeof(file_info),(qsort_cmp) file_info_compare,1,
- (void(*)(void*)) file_info_free);
- VOID(init_key_cache(KEY_CACHE_SIZE,(uint) (10*4*(IO_SIZE+MALLOC_OVERHEAD))));
+ init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
+ (tree_element_free) file_info_free, NULL);
+ VOID(init_key_cache(KEY_CACHE_SIZE));
files_open=0; access_time=0;
while (access_time++ != number_of_commands &&
@@ -400,11 +400,7 @@ static int examine_log(my_string file_name, char **table_names)
}
to=isam_file_name;
if (filepath)
- {
- strmov(isam_file_name,filepath);
- convert_dirname(isam_file_name);
- to=strend(isam_file_name);
- }
+ to=convert_dirname(isam_file_name, filepath, NullS);
strmov(to,pos);
fn_ext(isam_file_name)[0]=0; /* Remove extension */
}
diff --git a/isam/log.c b/isam/log.c
index a95b53b5110..78b56690401 100644
--- a/isam/log.c
+++ b/isam/log.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/open.c b/isam/open.c
index 8969b2fa8b8..9dc27981507 100644
--- a/isam/open.c
+++ b/isam/open.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/pack_isam.c b/isam/pack_isam.c
index 5a66a9cb33c..b2e21afc743 100644
--- a/isam/pack_isam.c
+++ b/isam/pack_isam.c
@@ -30,7 +30,7 @@
#ifndef __GNU_LIBRARY__
#define __GNU_LIBRARY__ /* Skipp warnings in getopt.h */
#endif
-#include <getopt.h>
+#include <my_getopt.h>
#if INT_MAX > 32767
#define BITS_SAVED 32
@@ -67,7 +67,7 @@ struct st_file_buffer {
char *buffer,*pos,*end;
my_off_t pos_in_file;
int bits;
- uint byte;
+ uint bytes;
};
struct st_huff_tree;
@@ -182,8 +182,9 @@ static int mrg_rrnd(MRG_INFO *info,byte *buf);
static void mrg_reset(MRG_INFO *mrg);
-static int backup=0,error_on_write=0,test_only=0,verbose=0,silent=0,
- write_loop=0,force_pack=0,opt_wait=0,isamchk_neaded=0;
+static int error_on_write=0,test_only=0,verbose=0,silent=0,
+ write_loop=0,force_pack=0,isamchk_neaded=0;
+static my_bool backup, opt_wait;
static int tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL;
static uint tree_buff_length=8196-MALLOC_OVERHEAD,force_pack_ref_length;
static char tmp_dir[FN_REFLEN]={0},*join_table;
@@ -240,26 +241,44 @@ int main(int argc, char **argv)
}
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"backup", no_argument, 0, 'b'},
- {"debug", optional_argument, 0, '#'},
- {"force", no_argument, 0, 'f'},
- {"join", required_argument, 0, 'j'},
- {"help", no_argument, 0, '?'},
- {"packlength",required_argument, 0, 'p'},
- {"silent", no_argument, 0, 's'},
- {"tmpdir", required_argument, 0, 'T'},
- {"test", no_argument, 0, 't'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"wait", no_argument, 0, 'w'},
- {0, 0, 0, 0}
+ {"backup", 'b', "Make a backup of the table as table_name.OLD",
+ (gptr*) &backup, (gptr*) &backup, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"force", 'f',
+ "Force packing of table even if it's gets bigger or tempfile exists.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"join", 'j',
+ "Join all given tables into 'new_table_name'. All tables MUST have the identical layout.",
+ (gptr*) &join_table, (gptr*) &join_table, 0, GET_STR, REQUIRED_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"packlength", 'p', "Force storage size of recordlength (1, 2 or 3)",
+ (gptr*) &force_pack_ref_length, (gptr*) &force_pack_ref_length, 0,
+ GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Be more silent.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0 ,0},
+ {"tmpdir", 'T', "Use temporary directory to store temporary table",
+ (gptr*) &tmp_dir, (gptr*) &tmp_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"test", 't', "Don't pack table, only test packing it",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0 ,0},
+ {"verbose", 'v', "Write info about progress and packing result",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0 ,0},
+ {"version", 'V', "output version information and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0 ,0},
+ {"wait", 'w', "Wait and retry if table is in use", (gptr*) &opt_wait,
+ (gptr*) &opt_wait, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static void print_version(void)
{
- printf("%s Ver 5.8 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE);
+ printf("%s Ver 5.10 for %s on %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
}
static void usage(void)
@@ -275,92 +294,72 @@ static void usage(void)
puts("You should give the .ISM file as the filename argument");
printf("\nUsage: %s [OPTIONS] filename...\n", my_progname);
- puts("\n\
- -b, --backup Make a backup of the table as table_name.OLD\n\
- -f, --force Force packing of table even if it's gets bigger or\n\
- tempfile exists.\n\
- -j, --join='new_table_name'\n\
- Join all given tables into 'new_table_name'.\n\
- All tables MUST have the identical layout.\n\
- -p, --packlength=# Force storage size of recordlength (1,2 or 3)\n\
- -s, --silent Be more silent.\n\
- -t, --test Don't pack table, only test packing it\n\
- -v, --verbose Write info about progress and packing result\n\
- -w, --wait Wait and retry if table is in use\n\
- -T, --tmpdir=# Use temporary directory to store temporary table\n\
- -#, --debug=... output debug log. Often this is 'd:t:o,filename`\n\
- -?, --help display this help and exit\n\
- -V, --version output version information and exit\n");
- print_defaults("my",load_default_groups);
+ my_print_help(my_long_options);
+ print_defaults("my", load_default_groups);
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ uint length;
+
+ switch(optid) {
+ case 'f':
+ force_pack= 1;
+ tmpfile_createflag= O_RDWR | O_TRUNC;
+ break;
+ case 'p':
+ if (force_pack_ref_length > 3)
+ force_pack_ref_length= 0;
+ break;
+ case 's':
+ write_loop= verbose= 0;
+ silent= 1;
+ break;
+ case 't':
+ test_only= verbose= 1;
+ break;
+ case 'T':
+ length=(uint) (strmov(tmp_dir, argument) - tmp_dir);
+ if (length != dirname_length(tmp_dir))
+ {
+ tmp_dir[length]= FN_LIBCHAR;
+ tmp_dir[length + 1]= 0;
+ }
+ break;
+ case 'v':
+ verbose= 1;
+ silent= 0;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+ case 'V': print_version(); exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
}
/* reads options */
/* Initiates DEBUG - but no debugging here ! */
-static void get_options(int *argc,char ***argv)
+static void get_options(int *argc, char ***argv)
{
- int c,option_index=0;
- uint length;
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
my_progname= argv[0][0];
if (isatty(fileno(stdout)))
write_loop=1;
- while ((c=getopt_long(*argc,*argv,"bfj:p:stvwT:#::?V",long_options,
- &option_index)) != EOF)
- {
- switch(c) {
- case 'b':
- backup=1;
- break;
- case 'f':
- force_pack=1;
- tmpfile_createflag=O_RDWR | O_TRUNC;
- break;
- case 'j':
- join_table=optarg;
- break;
- case 'p':
- force_pack_ref_length=(uint) atoi(optarg);
- if (force_pack_ref_length > 3)
- force_pack_ref_length=0;
- break;
- case 's':
- write_loop=verbose=0; silent=1;
- break;
- case 't':
- test_only=verbose=1;
- break;
- case 'T':
- length=(uint) (strmov(tmp_dir,optarg)-tmp_dir);
- if (length != dirname_length(tmp_dir))
- {
- tmp_dir[length]=FN_LIBCHAR;
- tmp_dir[length+1]=0;
- }
- break;
- case 'v':
- verbose=1; silent=0;
- break;
- case 'w':
- opt_wait=1;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case 'V': print_version(); exit(0);
- case 'I':
- case '?':
- usage();
- exit(0);
- default:
- fprintf(stderr,"%s: Illegal option: -%c\n",my_progname,opterr);
- usage();
- exit(1);
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
if (!*argc)
{
usage();
@@ -686,9 +685,9 @@ static HUFF_COUNTS *init_huff_count(N_INFO *info,my_off_t records)
type = FIELD_NORMAL;
if (count[i].field_length <= 8 &&
(type == FIELD_NORMAL ||
- type == FIELD_SKIPP_ZERO))
+ type == FIELD_SKIP_ZERO))
count[i].max_zero_fill= count[i].field_length;
- init_tree(&count[i].int_tree,0,-1,(qsort_cmp) compare_tree,0,NULL);
+ init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0,NULL,NULL);
if (records)
count[i].tree_pos=count[i].tree_buff =
my_malloc(count[i].field_length > 1 ? tree_buff_length : 2,
@@ -790,7 +789,7 @@ static int get_statistic(MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
/* Save character counters and space-counts and zero-field-counts */
if (count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_ENDSPACE)
+ count->field_type == FIELD_SKIP_ENDSPACE)
{
for ( ; end_pos > pos ; end_pos--)
if (end_pos[-1] != ' ')
@@ -809,7 +808,7 @@ static int get_statistic(MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
count->max_end_space = length;
}
if (count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_PRESPACE)
+ count->field_type == FIELD_SKIP_PRESPACE)
{
for (pos=start_pos; pos < end_pos ; pos++)
if (pos[0] != ' ')
@@ -829,7 +828,7 @@ static int get_statistic(MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
}
if (count->field_length <= 8 &&
(count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_ZERO))
+ count->field_type == FIELD_SKIP_ZERO))
{
uint i;
if (!memcmp((byte*) start_pos,zero_string,count->field_length))
@@ -910,7 +909,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, my_off_t records)
new_length=calc_packed_length(huff_counts,0);
if (old_length < new_length && huff_counts->field_length > 1)
{
- huff_counts->field_type=FIELD_SKIPP_ZERO;
+ huff_counts->field_type=FIELD_SKIP_ZERO;
huff_counts->counts[0]-=length;
huff_counts->bytes_packed=old_length- records/8;
goto found_pack;
@@ -954,7 +953,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, my_off_t records)
huff_counts->counts[' ']+=huff_counts->tot_pre_space;
if (test_space_compress(huff_counts,records,huff_counts->max_end_space,
huff_counts->end_space,
- huff_counts->tot_end_space,FIELD_SKIPP_ENDSPACE))
+ huff_counts->tot_end_space,FIELD_SKIP_ENDSPACE))
goto found_pack;
huff_counts->counts[' ']-=huff_counts->tot_pre_space;
}
@@ -962,7 +961,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, my_off_t records)
{
if (test_space_compress(huff_counts,records,huff_counts->max_pre_space,
huff_counts->pre_space,
- huff_counts->tot_pre_space,FIELD_SKIPP_PRESPACE))
+ huff_counts->tot_pre_space,FIELD_SKIP_PRESPACE))
goto found_pack;
}
@@ -972,10 +971,10 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, my_off_t records)
if (huff_counts->max_zero_fill &&
(huff_counts->field_type == FIELD_NORMAL ||
- huff_counts->field_type == FIELD_SKIPP_ZERO))
+ huff_counts->field_type == FIELD_SKIP_ZERO))
{
huff_counts->counts[0]-=huff_counts->max_zero_fill*
- (huff_counts->field_type == FIELD_SKIPP_ZERO ?
+ (huff_counts->field_type == FIELD_SKIP_ZERO ?
records - huff_counts->zero_fields : records);
huff_counts->pack_type|=PACK_TYPE_ZERO_FILL;
huff_counts->bytes_packed=calc_packed_length(huff_counts,0);
@@ -1015,9 +1014,9 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees, my_off_t records)
if (verbose)
printf("\nnormal: %3d empty-space: %3d empty-zero: %3d empty-fill: %3d\npre-space: %3d end-space: %3d table-lookup: %3d zero: %3d\n",
field_count[FIELD_NORMAL],space_fields,
- field_count[FIELD_SKIPP_ZERO],fill_zero_fields,
- field_count[FIELD_SKIPP_PRESPACE],
- field_count[FIELD_SKIPP_ENDSPACE],
+ field_count[FIELD_SKIP_ZERO],fill_zero_fields,
+ field_count[FIELD_SKIP_PRESPACE],
+ field_count[FIELD_SKIP_ENDSPACE],
field_count[FIELD_INTERVALL],
field_count[FIELD_ZERO]);
DBUG_VOID_RETURN;
@@ -1672,7 +1671,7 @@ static int compress_isam_file(MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
field_length-=count->max_zero_fill;
switch(count->field_type) {
- case FIELD_SKIPP_ZERO:
+ case FIELD_SKIP_ZERO:
if (!memcmp((byte*) start_pos,zero_string,field_length))
{
write_bits(1,1);
@@ -1686,7 +1685,7 @@ static int compress_isam_file(MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
write_bits(tree->code[(uchar) *start_pos],
(uint) tree->code_len[(uchar) *start_pos]);
break;
- case FIELD_SKIPP_ENDSPACE:
+ case FIELD_SKIP_ENDSPACE:
for (pos=end_pos ; pos > start_pos && pos[-1] == ' ' ; pos--) ;
length=(uint) (end_pos-pos);
if (count->pack_type & PACK_TYPE_SELECTED)
@@ -1709,7 +1708,7 @@ static int compress_isam_file(MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
(uint) tree->code_len[(uchar) *start_pos]);
start_pos=end_pos;
break;
- case FIELD_SKIPP_PRESPACE:
+ case FIELD_SKIP_PRESPACE:
for (pos=start_pos ; pos < end_pos && pos[0] == ' ' ; pos++) ;
length=(uint) (pos-start_pos);
if (count->pack_type & PACK_TYPE_SELECTED)
@@ -1833,7 +1832,7 @@ static void init_file_buffer(File file, pbool read_buffer)
file_buffer.pos=file_buffer.buffer;
file_buffer.bits=BITS_SAVED;
}
- file_buffer.byte=0;
+ file_buffer.bytes=0;
}
@@ -1864,13 +1863,13 @@ static void write_bits (register ulong value, register uint bits)
{
if ((file_buffer.bits-=(int) bits) >= 0)
{
- file_buffer.byte|=value << file_buffer.bits;
+ file_buffer.bytes|=value << file_buffer.bits;
}
else
{
reg3 uint byte_buff;
bits= (uint) -file_buffer.bits;
- byte_buff=file_buffer.byte | (uint) (value >> bits);
+ byte_buff=file_buffer.bytes | (uint) (value >> bits);
#if BITS_SAVED == 32
*file_buffer.pos++= (byte) (byte_buff >> 24) ;
*file_buffer.pos++= (byte) (byte_buff >> 16) ;
@@ -1896,7 +1895,7 @@ static void write_bits (register ulong value, register uint bits)
if (file_buffer.pos >= file_buffer.end)
VOID(flush_buffer((uint) ~0));
file_buffer.bits=(int) (BITS_SAVED - bits);
- file_buffer.byte=(uint) (value << (BITS_SAVED - bits));
+ file_buffer.bytes=(uint) (value << (BITS_SAVED - bits));
}
return;
}
@@ -1908,7 +1907,7 @@ static void flush_bits (void)
uint bits,byte_buff;
bits=(file_buffer.bits) & ~7;
- byte_buff = file_buffer.byte >> bits;
+ byte_buff = file_buffer.bytes >> bits;
bits=BITS_SAVED - bits;
while (bits > 0)
{
@@ -1916,7 +1915,7 @@ static void flush_bits (void)
*file_buffer.pos++= (byte) (uchar) (byte_buff >> bits) ;
}
file_buffer.bits=BITS_SAVED;
- file_buffer.byte=0;
+ file_buffer.bytes=0;
return;
}
@@ -1960,7 +1959,7 @@ static void save_state(N_INFO *isam_file,MRG_INFO *mrg,my_off_t new_length,
isam_file->update|=(HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
isam_file->this_uniq=crc; /* Save crc here */
share->changed=1; /* Force write of header */
- VOID(my_chsize(share->kfile,share->state.key_file_length,
+ VOID(my_chsize(share->kfile, share->state.key_file_length, 0,
MYF(0)));
if (share->state.keys != share->base.keys)
isamchk_neaded=1;
diff --git a/isam/panic.c b/isam/panic.c
index 52a5d1eb3b6..e51e83671df 100644
--- a/isam/panic.c
+++ b/isam/panic.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/range.c b/isam/range.c
index 5594991cfc3..3b79b6d93a9 100644
--- a/isam/range.c
+++ b/isam/range.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rfirst.c b/isam/rfirst.c
index 82fd3994bdf..cc1cbee92bf 100644
--- a/isam/rfirst.c
+++ b/isam/rfirst.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rkey.c b/isam/rkey.c
index 8f1f2f11ab5..bbe4576418b 100644
--- a/isam/rkey.c
+++ b/isam/rkey.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rlast.c b/isam/rlast.c
index df2b1bc39af..a91f1f1011b 100644
--- a/isam/rlast.c
+++ b/isam/rlast.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rnext.c b/isam/rnext.c
index 451624bb42b..be26098c901 100644
--- a/isam/rnext.c
+++ b/isam/rnext.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rprev.c b/isam/rprev.c
index 50f22c838fd..0997a04fbbe 100644
--- a/isam/rprev.c
+++ b/isam/rprev.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rrnd.c b/isam/rrnd.c
index 7fd197a6d58..16b3ab1b859 100644
--- a/isam/rrnd.c
+++ b/isam/rrnd.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rsame.c b/isam/rsame.c
index fe617cf258c..9a2a03da054 100644
--- a/isam/rsame.c
+++ b/isam/rsame.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/rsamepos.c b/isam/rsamepos.c
index 500dfc60e38..c64ac492d1a 100644
--- a/isam/rsamepos.c
+++ b/isam/rsamepos.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/sort.c b/isam/sort.c
index 72c4c7564f8..d22b0e648a0 100644
--- a/isam/sort.c
+++ b/isam/sort.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/static.c b/isam/static.c
index 941c4defea2..9c68a0cfdba 100644
--- a/isam/static.c
+++ b/isam/static.c
@@ -1,21 +1,21 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
- Static variables for pisam library. All definied here for easy making of
+ Static variables for ISAM library. All definied here for easy making of
a shared library
*/
diff --git a/isam/test1.c b/isam/test1.c
index 33c61a53d4a..9ebc7af041d 100644
--- a/isam/test1.c
+++ b/isam/test1.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -19,7 +19,7 @@
static void get_options(int argc, char *argv[]);
static int rec_pointer_size=0,verbose=0,remove_ant=0,pack_keys=1,flags[50],
- packed_field=FIELD_SKIPP_PRESPACE;
+ packed_field=FIELD_SKIP_PRESPACE;
int main(int argc, char *argv[])
{
diff --git a/isam/test2.c b/isam/test2.c
index def6a4d3d5c..5b09cc8b716 100644
--- a/isam/test2.c
+++ b/isam/test2.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -115,17 +115,17 @@ int main(int argc, char *argv[])
keyinfo[5].seg[1].base.type=0;
keyinfo[5].base.flag = (uint8) (pack_type ? HA_PACK_KEY : 0);
- recinfo[0].base.type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[0].base.type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[0].base.length=7;
- recinfo[1].base.type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[1].base.type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[1].base.length=5;
- recinfo[2].base.type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[2].base.type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[2].base.length=9;
recinfo[3].base.type=FIELD_NORMAL;
recinfo[3].base.length=STANDAR_LENGTH-7-5-9-4;
- recinfo[4].base.type=pack_fields ? FIELD_SKIPP_ZERO : 0;
+ recinfo[4].base.type=pack_fields ? FIELD_SKIP_ZERO : 0;
recinfo[4].base.length=4;
- recinfo[5].base.type=pack_fields ? FIELD_SKIPP_ENDSPACE : 0;
+ recinfo[5].base.type=pack_fields ? FIELD_SKIP_ENDSPACE : 0;
recinfo[5].base.length=60;
if (use_blob)
{
@@ -156,7 +156,7 @@ int main(int argc, char *argv[])
goto err;
printf("- Writing key:s\n");
if (key_cacheing)
- init_key_cache(IO_SIZE*16,(uint) IO_SIZE*4*10); /* Use a small cache */
+ init_key_cache(IO_SIZE*16); /* Use a small cache */
if (locking)
nisam_lock_database(file,F_WRLCK);
if (write_cacheing)
@@ -265,12 +265,12 @@ int main(int argc, char *argv[])
{
if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
{
- printf("error: %d; can't uppdate:\nFrom: \"%s\"\nTo: \"%s\"\n",
+ printf("error: %d; can't update:\nFrom: \"%s\"\nTo: \"%s\"\n",
my_errno,read_record,record2);
goto err;
}
if (verbose)
- printf("Double key when tryed to uppdate:\nFrom: \"%s\"\nTo: \"%s\"\n",record,record2);
+ printf("Double key when tried to update:\nFrom: \"%s\"\nTo: \"%s\"\n",record,record2);
}
else
{
diff --git a/isam/test3.c b/isam/test3.c
index 935c194106d..228030f5832 100644
--- a/isam/test3.c
+++ b/isam/test3.c
@@ -1,21 +1,23 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Test av locking */
+#ifndef __NETWARE__
+
#include "nisam.h"
#include <sys/types.h>
#ifdef HAVE_SYS_WAIT_H
@@ -171,8 +173,8 @@ void start_test(int id)
exit(1);
}
if (key_cacheing && rnd(2) == 0)
- init_key_cache(65536L,(uint) IO_SIZE*4*10);
- printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
+ init_key_cache(65536L);
+ printf("Process %d, pid: %d\n",id,(int) getpid()); fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)
{
@@ -356,7 +358,7 @@ int test_write(N_INFO *file,int id,int lock_type)
nisam_extra(file,HA_EXTRA_WRITE_CACHE);
}
- sprintf(record.id,"%7d",getpid());
+ sprintf(record.id,"%7d",(int) getpid());
strmov(record.text,"Testing...");
tries=(uint) rnd(100)+10;
@@ -477,3 +479,15 @@ int test_update(N_INFO *file,int id,int lock_type)
printf("%2d: update: %5d\n",id,update); fflush(stdout);
return 0;
}
+
+#else /* __NETWARE__ */
+
+#include <stdio.h>
+
+main()
+{
+ fprintf(stderr,"this test has not been ported to NetWare\n");
+ return 0;
+}
+
+#endif /* __NETWARE__ */
diff --git a/isam/update.c b/isam/update.c
index 82dab4140e3..b3b676f967d 100644
--- a/isam/update.c
+++ b/isam/update.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/isam/write.c b/isam/write.c
index 49b0916afc4..f2c0d8dbc45 100644
--- a/isam/write.c
+++ b/isam/write.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -262,7 +262,7 @@ int _nisam_insert(register N_INFO *info, register N_KEYDEF *keyinfo,
/* This may happen if a key was deleted and the next key could be
compressed better than before */
DBUG_DUMP("anc_buff",(byte*) anc_buff,a_length);
-
+
bmove(key_pos,key_pos - (int) t_length,(uint)key_offset);
}
_nisam_store_key(keyinfo,key_pos,&s_temp);
diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am
index 0032d77561f..686f7807949 100644
--- a/libmysql/Makefile.am
+++ b/libmysql/Makefile.am
@@ -17,11 +17,11 @@
# This file is public domain and comes with NO WARRANTY of any kind
-target = libmysqlclient.la
-target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@
-LIBS = @CLIENT_LIBS@
+target = libmysqlclient.la
+target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ -DMYSQL_CLIENT
+LIBS = @CLIENT_LIBS@
INCLUDES = -I$(srcdir)/../include -I../include \
- -I$(srcdir)/.. -I$(top_srcdir) -I..
+ -I$(srcdir)/.. -I$(top_srcdir) -I.. $(openssl_includes)
include $(srcdir)/Makefile.shared
@@ -36,10 +36,15 @@ link_sources:
ss=`echo $(mystringsobjects) | sed "s;\.lo;.c;g"`; \
ds=`echo $(dbugobjects) | sed "s;\.lo;.c;g"`; \
ms=`echo $(mysysobjects) | sed "s;\.lo;.c;g"`; \
+ vs=`echo $(vio_objects) | sed "s;\.lo;.c;g"`; \
for f in $$ss; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
done; \
+ for f in $$vs $(vioheaders); do \
+ rm -f $(srcdir)/$$f; \
+ @LN_CP_F@ $(srcdir)/../vio/$$f $(srcdir)/$$f; \
+ done; \
for f in $(mystringsextra); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
@@ -57,7 +62,9 @@ link_sources:
@LN_CP_F@ $(srcdir)/../mysys/$$f $(srcdir)/$$f; \
done; \
rm -f $(srcdir)/net.c; \
- @LN_CP_F@ $(srcdir)/../sql/net_serv.cc $(srcdir)/net.c
+ @LN_CP_F@ $(srcdir)/../sql/net_serv.cc $(srcdir)/net.c ; \
+ rm -f $(srcdir)/password.c; \
+ @LN_CP_F@ $(srcdir)/../sql/password.c $(srcdir)/password.c
# This part requires GNUmake
#
@@ -68,13 +75,13 @@ link_sources:
# keep only the stubs for safemalloc.c and debug.c
#
# A list of needed headers collected from the deps information 000213
-nh = global.h config-win32.h dbug.h errmsg.h global.h \
+nh = my_global.h config-win32.h dbug.h errmsg.h \
m_ctype.h m_string.h \
my_alarm.h my_config.h my_dir.h my_list.h my_net.h my_sys.h \
- mysql.h mysql_com.h mysql_version.h mysqld_error.h mysys_err.h \
- my_pthread.h thr_alarm.h violite.h hash.h
+ mysql.h mysql_com.h mysql_version.h mysqld_error.h \
+ mysys_err.h my_pthread.h thr_alarm.h violite.h hash.h
# Get a list of the needed objects
-lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects)
+lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects) $(sqlobjects)
do-lib-dist:
dir=libmysql-$(MYSQL_NO_DASH_VERSION); \
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index b1c7438543f..764983506d1 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -31,13 +31,14 @@ noinst_PROGRAMS = conf_to_src
CHARSET_OBJS=@CHARSET_OBJS@
LTCHARSET_OBJS= ${CHARSET_OBJS:.o=.lo}
-target_sources = libmysql.c net.c violite.c password.c \
- get_password.c errmsg.c
+target_sources = libmysql.c password.c manager.c \
+ get_password.c errmsg.c
-mystringsobjects = strmov.lo strxmov.lo strnmov.lo strmake.lo strend.lo \
+mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
+ strmake.lo strend.lo \
strnlen.lo strfill.lo is_prefix.lo \
int2str.lo str2int.lo strinstr.lo strcont.lo \
- strcend.lo \
+ strcend.lo bcmp.lo \
bchange.lo bmove.lo bmove_upp.lo longlong2str.lo \
strtoull.lo strtoll.lo llstr.lo \
ctype.lo $(LTCHARSET_OBJS)
@@ -45,6 +46,7 @@ mystringsextra= strto.c
mystringsgen= ctype_autoconf.c
dbugobjects = dbug.lo # IT IS IN SAFEMALLOC.C sanity.lo
mysysheaders = mysys_priv.h my_static.h
+vioheaders = vio_priv.h
mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
my_create.lo my_delete.lo mf_tempfile.lo my_open.lo \
mf_casecnv.lo my_read.lo my_write.lo errors.lo \
@@ -56,13 +58,19 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
mf_loadpath.lo my_pthread.lo my_thr_init.lo \
thr_mutex.lo mulalloc.lo string.lo default.lo \
my_compress.lo array.lo my_once.lo list.lo my_net.lo \
- charset.lo hash.lo mf_iocache.lo my_seek.lo \
- my_pread.lo mf_cache.lo my_gethostbyname.lo my_port.lo
+ charset.lo hash.lo mf_iocache.lo \
+ mf_iocache2.lo my_seek.lo my_sleep.lo \
+ my_pread.lo mf_cache.lo my_vsnprintf.lo md5.lo \
+ my_getopt.lo my_gethostbyname.lo my_port.lo
+sqlobjects = net.lo
+
# Not needed in the minimum library
-mysysobjects2 = getopt.lo getopt1.lo getvar.lo my_lib.lo
+mysysobjects2 = my_lib.lo
mysysobjects = $(mysysobjects1) $(mysysobjects2)
-target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects)
+target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \
+ $(vio_objects) $(sqlobjects)
target_ldflags = -version-info @SHARED_LIB_VERSION@
+vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo
CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
$(target)
DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
@@ -79,8 +87,8 @@ clean-local:
`echo $(mysysobjects) | sed "s;\.lo;.c;g"` \
`echo $(vio_objects) | sed "s;\.lo;.c;g"` \
$(CHARSET_SRCS) $(CHARSET_OBJS) \
- $(mystringsextra) $(mystringsgen) $(mysysheaders) \
- ctype_extra_sources.c ../linked_client_sources
+ $(mystringsextra) $(mystringsgen) $(mysysheaders) $(vioheaders)\
+ ctype_extra_sources.c net.c ../linked_client_sources
ctype_extra_sources.c: conf_to_src
./conf_to_src $(top_srcdir) @CHARSETS_NEED_SOURCE@ > \
diff --git a/libmysql/conf_to_src.c b/libmysql/conf_to_src.c
index 76316638153..95ffcf1cb2b 100644
--- a/libmysql/conf_to_src.c
+++ b/libmysql/conf_to_src.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* can't use -lmysys because this prog is used to create -lstrings */
diff --git a/libmysql/dll.c b/libmysql/dll.c
index d1a23794025..92aa611000b 100644
--- a/libmysql/dll.c
+++ b/libmysql/dll.c
@@ -1,25 +1,24 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
** Handling initialization of the dll library
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <my_pthread.h>
@@ -113,12 +112,13 @@ int _export FAR PASCAL libmain(HANDLE hModule,short cbHeapSize,
#ifdef OS2
-//
-// This function is called automatically by _DLL_InitTerm
-// Every dll runtime enviroment is not tz enabled, so tzset()
-// must be called to enable TZ handling
-// Also timezone is fixed.
-//
+/*
+ This function is called automatically by _DLL_InitTerm
+ Every dll runtime enviroment is not tz enabled, so tzset()
+ must be called to enable TZ handling
+ Also timezone is fixed.
+*/
+
extern "C" unsigned long _System DllMain(unsigned long modhandle,
unsigned long flag)
{
diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c
index 67cfe874f77..7accbf8f1d2 100644
--- a/libmysql/errmsg.c
+++ b/libmysql/errmsg.c
@@ -1,24 +1,23 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Error messages for MySQL clients */
-/* error messages for the demon is in share/language/errmsg.sys */
+/* error messages for the daemon is in share/language/errmsg.sys */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "errmsg.h"
@@ -27,25 +26,32 @@ const char *client_errors[]=
{
"Unbekannter MySQL Fehler",
"Kann UNIX-Socket nicht anlegen (%d)",
- "Keine Verbindung zu lokalem MySQL Server, socket: '%-.64s' (%d)",
- "Keine Verbindung zu MySQL Server auf %-.64s (%d)",
+ "Keine Verbindung zu lokalem MySQL Server, socket: '%-.100s' (%d)",
+ "Keine Verbindung zu MySQL Server auf %-.100s (%d)",
"Kann TCP/IP-Socket nicht anlegen (%d)",
- "Unbekannter MySQL Server Host (%-.64s) (%d)",
+ "Unbekannter MySQL Server Host (%-.100s) (%d)",
"MySQL Server nicht vorhanden",
"Protokolle ungleich. Server Version = % d Client Version = %d",
"MySQL client got out of memory",
"Wrong host info",
"Localhost via UNIX socket",
- "%-.64s via TCP/IP",
+ "%-.100s via TCP/IP",
"Error in server handshake",
"Lost connection to MySQL server during query",
"Commands out of sync; You can't run this command now",
- "Verbindung ueber Named Pipe; Host: %-.64s",
+ "Verbindung ueber Named Pipe; Host: %-.100s",
"Kann nicht auf Named Pipe warten. Host: %-.64s pipe: %-.32s (%lu)",
"Kann Named Pipe nicht oeffnen. Host: %-.64s pipe: %-.32s (%lu)",
"Kann den Status der Named Pipe nicht setzen. Host: %-.64s pipe: %-.32s (%lu)",
- "Can't initialize character set %-.64s (path: %-.64s)",
- "Got packet bigger than 'max_allowed_packet'"
+ "Can't initialize character set %-.32s (path: %-.100s)",
+ "Got packet bigger than 'max_allowed_packet'",
+ "Embedded server",
+ "Error on SHOW SLAVE STATUS:",
+ "Error on SHOW SLAVE HOSTS:",
+ "Error connecting to slave:",
+ "Error connecting to master:",
+ "SSL connection error",
+ "Malformed packet"
};
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
@@ -55,25 +61,32 @@ const char *client_errors[]=
{
"Erro desconhecido do MySQL",
"Não pode criar 'UNIX socket' (%d)",
- "Não pode se conectar ao servidor MySQL local através do 'socket' '%-.64s' (%d)",
- "Não pode se conectar ao servidor MySQL em '%-.64s' (%d)",
+ "Não pode se conectar ao servidor MySQL local através do 'socket' '%-.100s' (%d)",
+ "Não pode se conectar ao servidor MySQL em '%-.100s' (%d)",
"Não pode criar 'socket TCP/IP' (%d)",
- "'Host' servidor MySQL '%-.64s' (%d) desconhecido",
+ "'Host' servidor MySQL '%-.100s' (%d) desconhecido",
"Servidor MySQL desapareceu",
"Incompatibilidade de protocolos. Versão do Servidor: %d - Versão do Cliente: %d",
"Cliente do MySQL com falta de memória",
"Informação inválida de 'host'",
"Localhost via 'UNIX socket'",
- "%-.64s via 'TCP/IP'",
+ "%-.100s via 'TCP/IP'",
"Erro na negociação de acesso ao servidor",
"Conexão perdida com servidor MySQL durante 'query'",
"Comandos fora de sincronismo. Você não pode executar este comando agora",
- "%-.64s via 'named pipe'",
+ "%-.100s via 'named pipe'",
"Não pode esperar pelo 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"Não pode abrir 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
"Não pode estabelecer o estado do 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
- "Não pode inicializar conjunto de caracteres %-.64s (caminho %-.64s)",
- "Obteve pacote maior do que 'max_allowed_packet'"
+ "Não pode inicializar conjunto de caracteres %-.32s (caminho %-.100s)",
+ "Obteve pacote maior do que 'max_allowed_packet'",
+ "Embedded server"
+ "Error on SHOW SLAVE STATUS:",
+ "Error on SHOW SLAVE HOSTS:",
+ "Error connecting to slave:",
+ "Error connecting to master:",
+ "SSL connection error",
+ "Malformed packet"
};
#else /* ENGLISH */
@@ -81,25 +94,32 @@ const char *client_errors[]=
{
"Unknown MySQL error",
"Can't create UNIX socket (%d)",
- "Can't connect to local MySQL server through socket '%-.64s' (%d)",
- "Can't connect to MySQL server on '%-.64s' (%d)",
+ "Can't connect to local MySQL server through socket '%-.100s' (%d)",
+ "Can't connect to MySQL server on '%-.100s' (%d)",
"Can't create TCP/IP socket (%d)",
- "Unknown MySQL Server Host '%-.64s' (%d)",
+ "Unknown MySQL Server Host '%-.100s' (%d)",
"MySQL server has gone away",
"Protocol mismatch. Server Version = %d Client Version = %d",
"MySQL client run out of memory",
"Wrong host info",
"Localhost via UNIX socket",
- "%-.64s via TCP/IP",
+ "%-.100s via TCP/IP",
"Error in server handshake",
"Lost connection to MySQL server during query",
"Commands out of sync; You can't run this command now",
- "%-.64s via named pipe",
+ "%-.100s via named pipe",
"Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)",
"Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)",
"Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)",
- "Can't initialize character set %-.64s (path: %-.64s)",
- "Got packet bigger than 'max_allowed_packet'"
+ "Can't initialize character set %-.32s (path: %-.100s)",
+ "Got packet bigger than 'max_allowed_packet'",
+ "Embedded server",
+ "Error on SHOW SLAVE STATUS:",
+ "Error on SHOW SLAVE HOSTS:",
+ "Error connecting to slave:",
+ "Error connecting to master:",
+ "SSL connection error",
+ "Malformed packet"
};
#endif
diff --git a/libmysql/get_password.c b/libmysql/get_password.c
index 989de9dd11a..0e3b2dcb0ae 100644
--- a/libmysql/get_password.c
+++ b/libmysql/get_password.c
@@ -1,30 +1,28 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000-2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
** Ask for a password from tty
** This is an own file to avoid conflicts with curses
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "mysql.h"
#include <m_string.h>
#include <m_ctype.h>
-#include <dbug.h>
#if defined(HAVE_BROKEN_GETPASS) && !defined(HAVE_GETPASSPHRASE)
#undef HAVE_GETPASS
@@ -35,7 +33,7 @@
#include <pwd.h>
#endif /* HAVE_PWD_H */
#else /* ! HAVE_GETPASS */
-#if !defined( __WIN__) && !defined(OS2)
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
#include <sys/ioctl.h>
#ifdef HAVE_TERMIOS_H /* For tty-password */
#include <termios.h>
@@ -54,7 +52,9 @@
#include <asm/termiobits.h>
#endif
#else
+#ifndef __NETWARE__
#include <conio.h>
+#endif /* __NETWARE__ */
#endif /* __WIN__ */
#endif /* HAVE_GETPASS */
@@ -62,16 +62,23 @@
#define getpass(A) getpassphrase(A)
#endif
-#if defined( __WIN__) || defined(OS2)
+#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
/* were just going to fake it here and get input from the keyboard */
+#ifdef __NETWARE__
+#undef _getch
+#undef _cputs
+#define _getch getcharacter
+#define _cputs(A) putstring(A)
+#endif
+
char *get_tty_password(char *opt_message)
{
char to[80];
char *pos=to,*end=to+sizeof(to)-1;
int i=0;
DBUG_ENTER("get_tty_password");
- fprintf(stdout,opt_message ? opt_message : "Enter password: ");
+ _cputs(opt_message ? opt_message : "Enter password: ");
for (;;)
{
char tmp;
@@ -101,12 +108,11 @@ char *get_tty_password(char *opt_message)
#else
-
#ifndef HAVE_GETPASS
/*
-** Can't use fgets, because readline will get confused
-** length is max number of chars in to, not counting \0
-* to will not include the eol characters.
+ Can't use fgets, because readline will get confused
+ length is max number of chars in to, not counting \0
+ to will not include the eol characters.
*/
static void get_password(char *to,uint length,int fd,bool echo)
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index c50193c5e2c..607d8af6e50 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1,21 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000-2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include <global.h>
+#include <my_global.h>
#if defined(__WIN__) || defined(_WIN32) || defined(_WIN64)
#include <winsock.h>
#include <odbcinst.h>
@@ -41,14 +40,17 @@
#include <arpa/inet.h>
#include <netdb.h>
#ifdef HAVE_SELECT_H
-# include <select.h>
+#include <select.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
+#ifdef HAVE_POLL
+#include <sys/poll.h>
#endif
+#endif /* !defined(MSDOS) && !defined(__WIN__) */
#ifdef HAVE_SYS_UN_H
-# include <sys/un.h>
+#include <sys/un.h>
#endif
#if defined(THREAD) && !defined(__WIN__)
#include <my_pthread.h> /* because of signal() */
@@ -60,6 +62,10 @@
static my_bool mysql_client_init=0;
uint mysql_port=0;
my_string mysql_unix_port=0;
+ulong net_buffer_length=8192;
+ulong max_allowed_packet= 1024L*1024L*1024L;
+ulong net_read_timeout= CLIENT_NET_READ_TIMEOUT;
+ulong net_write_timeout= CLIENT_NET_WRITE_TIMEOUT;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS)
@@ -70,14 +76,13 @@ my_string mysql_unix_port=0;
#endif
#if defined(MSDOS) || defined(__WIN__)
-// socket_errno is defined in global.h for all platforms
+/* socket_errno is defined in my_global.h for all platforms */
#define perror(A)
#else
#include <errno.h>
#define SOCKET_ERROR -1
#endif /* __WIN__ */
-static void mysql_once_init(void);
static MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields,
uint field_count);
static int read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
@@ -91,6 +96,47 @@ static sig_handler pipe_sig_handler(int sig);
static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
const char *from, ulong length);
+static my_bool org_my_init_done=0;
+
+int STDCALL mysql_server_init(int argc __attribute__((unused)),
+ char **argv __attribute__((unused)),
+ char **groups __attribute__((unused)))
+{
+ return (int) mysql_once_init();
+}
+
+void STDCALL mysql_server_end()
+{
+ /* If library called my_init(), free memory allocated by it */
+ if (!org_my_init_done)
+ {
+ my_end(0);
+#ifndef THREAD
+ /* Remove TRACING, if enabled by mysql_debug() */
+ DBUG_POP();
+#endif
+ }
+ else
+ mysql_thread_end();
+ mysql_client_init= org_my_init_done= 0;
+}
+
+my_bool STDCALL mysql_thread_init()
+{
+#ifdef THREAD
+ return my_thread_init();
+#else
+ return 0;
+#endif
+}
+
+void STDCALL mysql_thread_end()
+{
+#ifdef THREAD
+ my_thread_end();
+#endif
+}
+
/*
Let the user specify that we don't want SIGPIPE; This doesn't however work
with threaded applications as we can have multiple read in progress.
@@ -106,26 +152,31 @@ static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
#define reset_sigpipe(mysql)
#endif
+static MYSQL* spawn_init(MYSQL* parent, const char* host,
+ unsigned int port,
+ const char* user,
+ const char* passwd);
+
+#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__))
+static int wait_for_data(my_socket fd, uint timeout);
+#endif
+
/****************************************************************************
-* A modified version of connect(). connect2() allows you to specify
-* a timeout value, in seconds, that we should wait until we
-* derermine we can't connect to a particular host. If timeout is 0,
-* connect2() will behave exactly like connect().
-*
-* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
+ A modified version of connect(). my_connect() allows you to specify
+ a timeout value, in seconds, that we should wait until we
+ derermine we can't connect to a particular host. If timeout is 0,
+ my_connect() will behave exactly like connect().
+
+ Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/
-static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
- uint timeout)
+int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
+ uint timeout)
{
-#if defined(__WIN__) || defined(OS2)
- return connect(s, (struct sockaddr*) name, namelen);
+#if defined(__WIN__) || defined(OS2) || defined(__NETWARE__)
+ return connect(fd, (struct sockaddr*) name, namelen);
#else
int flags, res, s_err;
- SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
- fd_set sfds;
- struct timeval tv;
- time_t start_time, now_time;
/*
If they passed us a timeout of zero, we should behave
@@ -133,30 +184,68 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
*/
if (timeout == 0)
- return connect(s, (struct sockaddr*) name, namelen);
+ return connect(fd, (struct sockaddr*) name, namelen);
- flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
+ flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */
#ifdef O_NONBLOCK
- fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
+ fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
#endif
- res = connect(s, (struct sockaddr*) name, namelen);
- s_err = errno; /* Save the error... */
- fcntl(s, F_SETFL, flags);
+ res= connect(fd, (struct sockaddr*) name, namelen);
+ s_err= errno; /* Save the error... */
+ fcntl(fd, F_SETFL, flags);
if ((res != 0) && (s_err != EINPROGRESS))
{
- errno = s_err; /* Restore it */
+ errno= s_err; /* Restore it */
return(-1);
}
if (res == 0) /* Connected quickly! */
return(0);
+ return wait_for_data(fd, timeout);
+#endif
+}
+
+
+/*
+ Wait up to timeout seconds for a connection to be established.
+
+ We prefer to do this with poll() as there is no limitations with this.
+ If not, we will use select()
+*/
+
+#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__))
+
+static int wait_for_data(my_socket fd, uint timeout)
+{
+#ifdef HAVE_POLL
+ struct pollfd ufds;
+ int res;
+
+ ufds.fd= fd;
+ ufds.events= POLLIN | POLLPRI;
+ if (!(res= poll(&ufds, 1, (int) timeout*1000)))
+ {
+ errno= EINTR;
+ return -1;
+ }
+ if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
+ return -1;
+ return 0;
+#else
+ SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
+ fd_set sfds;
+ struct timeval tv;
+ time_t start_time, now_time;
+ int res, s_err;
+
+ if (fd >= FD_SETSIZE) /* Check if wrong error */
+ return 0; /* Can't use timeout */
/*
- Otherwise, our connection is "in progress." We can use
- the select() call to wait up to a specified period of time
- for the connection to suceed. If select() returns 0
- (after waiting howevermany seconds), our socket never became
- writable (host is probably unreachable.) Otherwise, if
+ Our connection is "in progress." We can use the select() call to wait
+ up to a specified period of time for the connection to suceed.
+ If select() returns 0 (after waiting howevermany seconds), our socket
+ never became writable (host is probably unreachable.) Otherwise, if
select() returns 1, then one of two conditions exist:
1. An error occured. We use getsockopt() to check for this.
@@ -169,7 +258,7 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
*/
FD_ZERO(&sfds);
- FD_SET(s, &sfds);
+ FD_SET(fd, &sfds);
/*
select could be interrupted by a signal, and if it is,
the timeout should be adjusted and the select restarted
@@ -182,11 +271,11 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
{
tv.tv_sec = (long) timeout;
tv.tv_usec = 0;
-#if defined(HPUX) && defined(THREAD)
- if ((res = select(s+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
+#if defined(HPUX10) && defined(THREAD)
+ if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
break;
#else
- if ((res = select(s+1, NULL, &sfds, NULL, &tv)) > 0)
+ if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
break;
#endif
if (res == 0) /* timeout */
@@ -204,7 +293,7 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
*/
s_err=0;
- if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
return(-1);
if (s_err)
@@ -213,12 +302,12 @@ static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
return(-1); /* but return an error... */
}
return (0); /* ok */
-
-#endif
+#endif /* HAVE_POLL */
}
+#endif /* defined(__WIN__) || defined(OS2) || defined(__NETWARE__) */
/*
-** Create a named pipe connection
+ Create a named pipe connection
*/
#ifdef __WIN__
@@ -291,15 +380,15 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
/*****************************************************************************
-** read a packet from server. Give error message if socket was down
-** or packet is an error message
+ read a packet from server. Give error message if socket was down
+ or packet is an error message
*****************************************************************************/
-uint
+ulong
net_safe_read(MYSQL *mysql)
{
NET *net= &mysql->net;
- uint len=0;
+ ulong len=0;
init_sigpipe_variables
/* Don't give sigpipe errors if the client doesn't want them */
@@ -317,26 +406,18 @@ net_safe_read(MYSQL *mysql)
CR_NET_PACKET_TOO_LARGE:
CR_SERVER_LOST);
strmov(net->last_error,ER(net->last_errno));
- return(packet_error);
+ return (packet_error);
}
if (net->read_pos[0] == 255)
{
if (len > 3)
{
char *pos=(char*) net->read_pos+1;
- if (mysql->protocol_version > 9)
- { /* New client protocol */
- net->last_errno=uint2korr(pos);
- pos+=2;
- len-=2;
- }
- else
- {
- net->last_errno=CR_UNKNOWN_ERROR;
- len--;
- }
+ net->last_errno=uint2korr(pos);
+ pos+=2;
+ len-=2;
(void) strmake(net->last_error,(char*) pos,
- min(len,sizeof(net->last_error)-1));
+ min((uint) len,(uint) sizeof(net->last_error)-1));
}
else
{
@@ -427,7 +508,7 @@ static void free_rows(MYSQL_DATA *cur)
int
simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
- uint length, my_bool skipp_check)
+ ulong length, my_bool skipp_check)
{
NET *net= &mysql->net;
int result= -1;
@@ -438,11 +519,7 @@ simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
if (mysql->net.vio == 0)
{ /* Do reconnect if possible */
if (mysql_reconnect(mysql))
- {
- net->last_errno=CR_SERVER_GONE_ERROR;
- strmov(net->last_error,ER(net->last_errno));
goto end;
- }
}
if (mysql->status != MYSQL_STATUS_READY)
{
@@ -461,7 +538,8 @@ simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
if (net_write_command(net,(uchar) command,arg,
length ? length : (ulong) strlen(arg)))
{
- DBUG_PRINT("error",("Can't send command to server. Error: %d",socket_errno));
+ DBUG_PRINT("error",("Can't send command to server. Error: %d",
+ socket_errno));
if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
{
net->last_errno=CR_NET_PACKET_TOO_LARGE;
@@ -474,7 +552,7 @@ simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
if (net_write_command(net,(uchar) command,arg,
length ? length : (ulong) strlen(arg)))
{
- net->last_errno= CR_SERVER_GONE_ERROR;
+ net->last_errno=CR_SERVER_GONE_ERROR;
strmov(net->last_error,ER(net->last_errno));
goto end;
}
@@ -505,7 +583,17 @@ struct passwd *getpwuid(uid_t);
char* getlogin(void);
#endif
-#if !defined(MSDOS) && ! defined(VMS) && !defined(__WIN__) && !defined(OS2)
+
+#if defined(__NETWARE__)
+/* default to "root" on NetWare */
+static void read_user_name(char *name)
+{
+ char *str=getenv("USER");
+ strmake(name, str ? str : "UNKNOWN_USER", USERNAME_LENGTH);
+}
+
+#elif !defined(MSDOS) && ! defined(VMS) && !defined(__WIN__) && !defined(OS2)
+
static void read_user_name(char *name)
{
DBUG_ENTER("read_user_name");
@@ -553,7 +641,7 @@ static my_bool is_NT(void)
#endif
/*
-** Expand wildcard to a sql string
+ Expand wildcard to a sql string
*/
static void
@@ -579,7 +667,7 @@ append_wild(char *to, char *end, const char *wild)
/**************************************************************************
-** Init debugging if MYSQL_DEBUG environment variable is found
+ Init debugging if MYSQL_DEBUG environment variable is found
**************************************************************************/
void STDCALL
@@ -616,7 +704,7 @@ mysql_debug(const char *debug __attribute__((unused)))
/**************************************************************************
-** Close the server connection if we get a SIGPIPE
+ Close the server connection if we get a SIGPIPE
ARGSUSED
**************************************************************************/
@@ -631,7 +719,7 @@ pipe_sig_handler(int sig __attribute__((unused)))
/**************************************************************************
-** Shut down connection
+ Shut down connection
**************************************************************************/
static void
@@ -665,8 +753,8 @@ mysql_free_result(MYSQL_RES *result)
DBUG_PRINT("warning",("Not all rows in set were read; Ignoring rows"));
for (;;)
{
- uint pkt_len;
- if ((pkt_len=(uint) net_safe_read(result->handle)) == packet_error)
+ ulong pkt_len;
+ if ((pkt_len=net_safe_read(result->handle)) == packet_error)
break;
if (pkt_len == 1 && result->handle->net.read_pos[0] == 254)
break; /* End of data */
@@ -685,7 +773,7 @@ mysql_free_result(MYSQL_RES *result)
/****************************************************************************
-** Get options from my.cnf
+ Get options from my.cnf
****************************************************************************/
static const char *default_options[]=
@@ -695,7 +783,9 @@ static const char *default_options[]=
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
"character-sets-dir", "default-character-set", "interactive-timeout",
"connect-timeout", "local-infile", "disable-local-infile",
- NullS
+ "replication-probe", "enable-reads-from-master", "repl-parse-query",
+ "ssl-cipher", "max-allowed-packet",
+ NullS
};
static TYPELIB option_types={array_elements(default_options)-1,
@@ -839,6 +929,19 @@ static void mysql_read_default_options(struct st_mysql_options *options,
break;
case 22:
options->client_flag&= CLIENT_LOCAL_FILES;
+ break;
+ case 23: /* replication probe */
+ options->rpl_probe= 1;
+ break;
+ case 24: /* enable-reads-from-master */
+ options->no_master_reads= 0;
+ break;
+ case 25: /* repl-parse-query */
+ options->rpl_parse= 1;
+ break;
+ case 27:
+ if (opt_arg)
+ options->max_allowed_packet= atoi(opt_arg);
break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
@@ -852,7 +955,7 @@ static void mysql_read_default_options(struct st_mysql_options *options,
/***************************************************************************
-** Change field rows to field structs
+ Change field rows to field structs
***************************************************************************/
static MYSQL_FIELD *
@@ -863,13 +966,14 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
MYSQL_FIELD *field,*result;
DBUG_ENTER("unpack_fields");
- field=result=(MYSQL_FIELD*) alloc_root(alloc,sizeof(MYSQL_FIELD)*fields);
+ field=result=(MYSQL_FIELD*) alloc_root(alloc,
+ (uint) sizeof(MYSQL_FIELD)*fields);
if (!result)
DBUG_RETURN(0);
for (row=data->data; row ; row = row->next,field++)
{
- field->table= strdup_root(alloc,(char*) row->data[0]);
+ field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]);
field->name= strdup_root(alloc,(char*) row->data[1]);
field->length= (uint) uint3korr(row->data[2]);
field->type= (enum enum_field_types) (uchar) row->data[3][0];
@@ -901,7 +1005,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
uint fields)
{
- uint field,pkt_len;
+ uint field;
+ ulong pkt_len;
ulong len;
uchar *cp;
char *to, *end_to;
@@ -910,7 +1015,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
NET *net = &mysql->net;
DBUG_ENTER("read_rows");
- if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error)
+ if ((pkt_len= net_safe_read(mysql)) == packet_error)
DBUG_RETURN(0);
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
MYF(MY_WME | MY_ZEROFILL))))
@@ -955,7 +1060,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
if (len > (ulong) (end_to - to))
{
free_rows(result);
- net->last_errno=CR_UNKNOWN_ERROR;
+ net->last_errno=CR_MALFORMED_PACKET;
strmov(net->last_error,ER(net->last_errno));
DBUG_RETURN(0);
}
@@ -983,8 +1088,8 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
/*
-** Read one row. Uses packet buffer as storage for fields.
-** When next packet is read, the previous field values are destroyed
+ Read one row. Uses packet buffer as storage for fields.
+ When next packet is read, the previous field values are destroyed
*/
@@ -995,7 +1100,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
ulong pkt_len,len;
uchar *pos,*prev_pos, *end_pos;
- if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error)
+ if ((pkt_len=net_safe_read(mysql)) == packet_error)
return -1;
if (pkt_len == 1 && mysql->net.read_pos[0] == 254)
return 1; /* End of data */
@@ -1030,28 +1135,324 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
return 0;
}
+/* perform query on master */
+int STDCALL mysql_master_query(MYSQL *mysql, const char *q,
+ unsigned long length)
+{
+ DBUG_ENTER("mysql_master_query");
+ if (mysql_master_send_query(mysql, q, length))
+ DBUG_RETURN(1);
+ DBUG_RETURN(mysql_read_query_result(mysql));
+}
+
+int STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
+ unsigned long length)
+{
+ MYSQL *master = mysql->master;
+ DBUG_ENTER("mysql_master_send_query");
+ if (!master->net.vio && !mysql_real_connect(master,0,0,0,0,0,0,0))
+ DBUG_RETURN(1);
+ mysql->last_used_con = master;
+ DBUG_RETURN(simple_command(master, COM_QUERY, q, length, 1));
+}
+
+
+/* perform query on slave */
+int STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
+ unsigned long length)
+{
+ DBUG_ENTER("mysql_slave_query");
+ if (mysql_slave_send_query(mysql, q, length))
+ DBUG_RETURN(1);
+ DBUG_RETURN(mysql_read_query_result(mysql));
+}
+
+int STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
+ unsigned long length)
+{
+ MYSQL* last_used_slave, *slave_to_use = 0;
+ DBUG_ENTER("mysql_slave_send_query");
+
+ if ((last_used_slave = mysql->last_used_slave))
+ slave_to_use = last_used_slave->next_slave;
+ else
+ slave_to_use = mysql->next_slave;
+ /*
+ Next_slave is always safe to use - we have a circular list of slaves
+ if there are no slaves, mysql->next_slave == mysql
+ */
+ mysql->last_used_con = mysql->last_used_slave = slave_to_use;
+ if (!slave_to_use->net.vio && !mysql_real_connect(slave_to_use, 0,0,0,
+ 0,0,0,0))
+ DBUG_RETURN(1);
+ DBUG_RETURN(simple_command(slave_to_use, COM_QUERY, q, length, 1));
+}
+
+
+/* enable/disable parsing of all queries to decide
+ if they go on master or slave */
+void STDCALL mysql_enable_rpl_parse(MYSQL* mysql)
+{
+ mysql->options.rpl_parse = 1;
+}
+
+void STDCALL mysql_disable_rpl_parse(MYSQL* mysql)
+{
+ mysql->options.rpl_parse = 0;
+}
+
+/* get the value of the parse flag */
+int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql)
+{
+ return mysql->options.rpl_parse;
+}
+
+/* enable/disable reads from master */
+void STDCALL mysql_enable_reads_from_master(MYSQL* mysql)
+{
+ mysql->options.no_master_reads = 0;
+}
+
+void STDCALL mysql_disable_reads_from_master(MYSQL* mysql)
+{
+ mysql->options.no_master_reads = 1;
+}
+
+/* get the value of the master read flag */
+int STDCALL mysql_reads_from_master_enabled(MYSQL* mysql)
+{
+ return !(mysql->options.no_master_reads);
+}
+
+
+/*
+ We may get an error while doing replication internals.
+ In this case, we add a special explanation to the original
+ error
+*/
+
+static void expand_error(MYSQL* mysql, int error)
+{
+ char tmp[MYSQL_ERRMSG_SIZE];
+ char *p;
+ uint err_length;
+ strmake(tmp, mysql->net.last_error, MYSQL_ERRMSG_SIZE-1);
+ p = strmake(mysql->net.last_error, ER(error), MYSQL_ERRMSG_SIZE-1);
+ err_length= (uint) (p - mysql->net.last_error);
+ strmake(p, tmp, MYSQL_ERRMSG_SIZE-1 - err_length);
+ mysql->net.last_errno = error;
+}
+
+/*
+ This function assumes we have just called SHOW SLAVE STATUS and have
+ read the given result and row
+*/
+
+static int get_master(MYSQL* mysql, MYSQL_RES* res, MYSQL_ROW row)
+{
+ MYSQL* master;
+ DBUG_ENTER("get_master");
+ if (mysql_num_fields(res) < 3)
+ DBUG_RETURN(1); /* safety */
+
+ /* use the same username and password as the original connection */
+ if (!(master = spawn_init(mysql, row[0], atoi(row[2]), 0, 0)))
+ DBUG_RETURN(1);
+ mysql->master = master;
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Assuming we already know that mysql points to a master connection,
+ retrieve all the slaves
+*/
+
+static int get_slaves_from_master(MYSQL* mysql)
+{
+ MYSQL_RES* res = 0;
+ MYSQL_ROW row;
+ int error = 1;
+ int has_auth_info;
+ int port_ind;
+ DBUG_ENTER("get_slaves_from_master");
+
+ if (!mysql->net.vio && !mysql_real_connect(mysql,0,0,0,0,0,0,0))
+ {
+ expand_error(mysql, CR_PROBE_MASTER_CONNECT);
+ DBUG_RETURN(1);
+ }
+
+ if (mysql_query(mysql, "SHOW SLAVE HOSTS") ||
+ !(res = mysql_store_result(mysql)))
+ {
+ expand_error(mysql, CR_PROBE_SLAVE_HOSTS);
+ DBUG_RETURN(1);
+ }
+
+ switch (mysql_num_fields(res)) {
+ case 5:
+ has_auth_info = 0;
+ port_ind=2;
+ break;
+ case 7:
+ has_auth_info = 1;
+ port_ind=4;
+ break;
+ default:
+ goto err;
+ }
+
+ while ((row = mysql_fetch_row(res)))
+ {
+ MYSQL* slave;
+ const char* tmp_user, *tmp_pass;
+
+ if (has_auth_info)
+ {
+ tmp_user = row[2];
+ tmp_pass = row[3];
+ }
+ else
+ {
+ tmp_user = mysql->user;
+ tmp_pass = mysql->passwd;
+ }
+
+ if (!(slave = spawn_init(mysql, row[1], atoi(row[port_ind]),
+ tmp_user, tmp_pass)))
+ goto err;
+
+ /* Now add slave into the circular linked list */
+ slave->next_slave = mysql->next_slave;
+ mysql->next_slave = slave;
+ }
+ error = 0;
+err:
+ if (res)
+ mysql_free_result(res);
+ DBUG_RETURN(error);
+}
+
+
+int STDCALL mysql_rpl_probe(MYSQL* mysql)
+{
+ MYSQL_RES *res= 0;
+ MYSQL_ROW row;
+ int error = 1;
+ DBUG_ENTER("mysql_rpl_probe");
+
+ /*
+ First determine the replication role of the server we connected to
+ the most reliable way to do this is to run SHOW SLAVE STATUS and see
+ if we have a non-empty master host. This is still not fool-proof -
+ it is not a sin to have a master that has a dormant slave thread with
+ a non-empty master host. However, it is more reliable to check
+ for empty master than whether the slave thread is actually running
+ */
+ if (mysql_query(mysql, "SHOW SLAVE STATUS") ||
+ !(res = mysql_store_result(mysql)))
+ {
+ expand_error(mysql, CR_PROBE_SLAVE_STATUS);
+ DBUG_RETURN(1);
+ }
+
+ row= mysql_fetch_row(res);
+ /*
+ Check master host for emptiness/NULL
+ For MySQL 4.0 it's enough to check for row[0]
+ */
+ if (row && row[0] && *(row[0]))
+ {
+ /* this is a slave, ask it for the master */
+ if (get_master(mysql, res, row) || get_slaves_from_master(mysql))
+ goto err;
+ }
+ else
+ {
+ mysql->master = mysql;
+ if (get_slaves_from_master(mysql))
+ goto err;
+ }
+
+ error = 0;
+err:
+ if (res)
+ mysql_free_result(res);
+ DBUG_RETURN(error);
+}
+
+
+/*
+ Make a not so fool-proof decision on where the query should go, to
+ the master or the slave. Ideally the user should always make this
+ decision himself with mysql_master_query() or mysql_slave_query().
+ However, to be able to more easily port the old code, we support the
+ option of an educated guess - this should work for most applications,
+ however, it may make the wrong decision in some particular cases. If
+ that happens, the user would have to change the code to call
+ mysql_master_query() or mysql_slave_query() explicitly in the place
+ where we have made the wrong decision
+*/
+
+enum mysql_rpl_type
+STDCALL mysql_rpl_query_type(const char* q, int len)
+{
+ const char *q_end= q + len;
+ for (; q < q_end; ++q)
+ {
+ char c;
+ if (isalpha(c=*q))
+ {
+ switch(tolower(c)) {
+ case 'i': /* insert */
+ case 'u': /* update or unlock tables */
+ case 'l': /* lock tables or load data infile */
+ case 'd': /* drop or delete */
+ case 'a': /* alter */
+ return MYSQL_RPL_MASTER;
+ case 'c': /* create or check */
+ return tolower(q[1]) == 'h' ? MYSQL_RPL_ADMIN : MYSQL_RPL_MASTER ;
+ case 's': /* select or show */
+ return tolower(q[1]) == 'h' ? MYSQL_RPL_ADMIN : MYSQL_RPL_SLAVE;
+ case 'f': /* flush */
+ case 'r': /* repair */
+ case 'g': /* grant */
+ return MYSQL_RPL_ADMIN;
+ default:
+ return MYSQL_RPL_SLAVE;
+ }
+ }
+ }
+ return MYSQL_RPL_MASTER; /* By default, send to master */
+}
+
+
/****************************************************************************
-** Init MySQL structure or allocate one
+ Init MySQL structure or allocate one
****************************************************************************/
MYSQL * STDCALL
mysql_init(MYSQL *mysql)
{
- mysql_once_init();
+ if (mysql_once_init())
+ return 0;
if (!mysql)
{
if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
return 0;
mysql->free_me=1;
- mysql->net.vio = 0;
}
else
bzero((char*) (mysql),sizeof(*(mysql)));
mysql->options.connect_timeout=CONNECT_TIMEOUT;
-#if defined(SIGPIPE) && defined(THREAD) && !defined(__WIN__)
- if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE))
- (void) signal(SIGPIPE,pipe_sig_handler);
-#endif
+ mysql->last_used_con = mysql->next_slave = mysql->master = mysql;
+
+ /*
+ By default, we are a replication pivot. The caller must reset it
+ after we return if this is not the case.
+ */
+ mysql->rpl_pivot = 1;
/*
Only enable LOAD DATA INFILE by default if configured with
@@ -1064,12 +1465,31 @@ mysql_init(MYSQL *mysql)
}
-static void mysql_once_init()
+/*
+ Initialize the MySQL library
+
+ SYNOPSIS
+ mysql_once_init()
+
+ NOTES
+ Can't be static on NetWare
+ This function is called by mysql_init() and indirectly called
+ by mysql_query(), so one should never have to call this from an
+ outside program.
+
+ RETURN
+ 0 ok
+ 1 could not initialize environment (out of memory or thread keys)
+*/
+
+int mysql_once_init(void)
{
if (!mysql_client_init)
{
mysql_client_init=1;
- my_init(); /* Will init threads */
+ org_my_init_done=my_init_done;
+ if (my_init()) /* Will init threads */
+ return 1;
init_client_errs();
if (!mysql_port)
{
@@ -1097,73 +1517,79 @@ static void mysql_once_init()
mysql_unix_port = env;
}
mysql_debug(NullS);
-#if defined(SIGPIPE) && !defined(THREAD) && !defined(__WIN__)
- (void) signal(SIGPIPE,SIG_IGN);
+#if defined(SIGPIPE) && !defined(__WIN__)
+ (void) signal(SIGPIPE, SIG_IGN);
#endif
}
#ifdef THREAD
else
- my_thread_init(); /* Init if new thread */
+ {
+ if (my_thread_init()) /* Init if new thread */
+ return 1;
+ }
#endif
-}
-
-#ifdef HAVE_OPENSSL
-/**************************************************************************
-** Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
-** NB! Errors are not reported until you do mysql_real_connect.
-**************************************************************************/
-
-int STDCALL
-mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert,
- const char *ca, const char *capath)
-{
- mysql->options.ssl_key = key==0 ? 0 : my_strdup(key,MYF(0));
- mysql->options.ssl_cert = cert==0 ? 0 : my_strdup(cert,MYF(0));
- mysql->options.ssl_ca = ca==0 ? 0 : my_strdup(ca,MYF(0));
- mysql->options.ssl_capath = capath==0 ? 0 : my_strdup(capath,MYF(0));
- mysql->options.use_ssl = true;
- mysql->connector_fd = new_VioSSLConnectorFd(key, cert, ca, capath);
return 0;
}
+
/**************************************************************************
+ Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
+ NB! Errors are not reported until you do mysql_real_connect.
**************************************************************************/
-char * STDCALL
-mysql_ssl_cipher(MYSQL *mysql)
+#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
+
+int STDCALL
+mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
+ const char *key __attribute__((unused)),
+ const char *cert __attribute__((unused)),
+ const char *ca __attribute__((unused)),
+ const char *capath __attribute__((unused)),
+ const char *cipher __attribute__((unused)))
{
- return (char *)mysql->net.vio->cipher_description();
+#ifdef HAVE_OPENSSL
+ mysql->options.ssl_key= strdup_if_not_null(key);
+ mysql->options.ssl_cert= strdup_if_not_null(cert);
+ mysql->options.ssl_ca= strdup_if_not_null(ca);
+ mysql->options.ssl_capath= strdup_if_not_null(capath);
+ mysql->options.ssl_cipher= strdup_if_not_null(cipher);
+#endif
+ return 0;
}
/**************************************************************************
-** Free strings in the SSL structure and clear 'use_ssl' flag.
-** NB! Errors are not reported until you do mysql_real_connect.
+ Free strings in the SSL structure and clear 'use_ssl' flag.
+ NB! Errors are not reported until you do mysql_real_connect.
**************************************************************************/
-int STDCALL
-mysql_ssl_clear(MYSQL *mysql)
+static int
+mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
{
+#ifdef HAVE_OPENSSL
my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.ssl_key = 0;
mysql->options.ssl_cert = 0;
mysql->options.ssl_ca = 0;
mysql->options.ssl_capath = 0;
- mysql->options.use_ssl = false;
- mysql->connector_fd->delete();
+ mysql->options.ssl_cipher= 0;
+ mysql->options.use_ssl = FALSE;
mysql->connector_fd = 0;
+#endif /* HAVE_OPENSSL */
return 0;
}
-#endif /* HAVE_OPENSSL */
/**************************************************************************
-** Connect to sql server
-** If host == 0 then use localhost
+ Connect to sql server
+ If host == 0 then use localhost
**************************************************************************/
+#ifdef USE_OLD_FUNCTIONS
MYSQL * STDCALL
mysql_connect(MYSQL *mysql,const char *host,
const char *user, const char *passwd)
@@ -1180,11 +1606,24 @@ mysql_connect(MYSQL *mysql,const char *host,
DBUG_RETURN(res);
}
}
+#endif
/*
-** Note that the mysql argument must be initialized with mysql_init()
-** before calling mysql_real_connect !
+ The following union is used to force a struct to be double allgined.
+ This is to avoid warings with gethostname_r() on Linux itanium systems
+*/
+
+typedef union
+{
+ double tmp;
+ char buff[GETHOSTBYNAME_BUFF_SIZE];
+} gethostbyname_buff;
+
+
+/*
+ Note that the mysql argument must be initialized with mysql_init()
+ before calling mysql_real_connect !
*/
MYSQL * STDCALL
@@ -1195,9 +1634,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16];
char *end,*host_info,*charset_name;
my_socket sock;
- uint32 ip_addr;
+ in_addr_t ip_addr;
struct sockaddr_in sock_addr;
- uint pkt_length;
+ ulong pkt_length;
NET *net= &mysql->net;
#ifdef __WIN__
HANDLE hPipe=INVALID_HANDLE_VALUE;
@@ -1207,6 +1646,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
#endif
init_sigpipe_variables
DBUG_ENTER("mysql_real_connect");
+ LINT_INIT(host_info);
DBUG_PRINT("enter",("host: %s db: %s user: %s",
host ? host : "(Null)",
@@ -1272,8 +1712,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
net->vio = vio_new(sock, VIO_TYPE_SOCKET, TRUE);
bzero((char*) &UNIXaddr,sizeof(UNIXaddr));
UNIXaddr.sun_family = AF_UNIX;
- strmov(UNIXaddr.sun_path, unix_socket);
- if (connect2(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
+ strmake(UNIXaddr.sun_path, unix_socket, sizeof(UNIXaddr.sun_path)-1);
+ if (my_connect(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
mysql->options.connect_timeout) <0)
{
DBUG_PRINT("error",("Got error %d on connect to local server",socket_errno));
@@ -1304,7 +1744,11 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (mysql->options.named_pipe ||
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
+ {
+ net->last_errno= CR_SERVER_LOST;
+ strmov(net->last_error,ER(net->last_errno));
goto error; /* User only requested named pipes */
+ }
/* Try also with TCP/IP */
}
else
@@ -1348,21 +1792,21 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
{
int tmp_errno;
struct hostent tmp_hostent,*hp;
- char buff2[GETHOSTBYNAME_BUFF_SIZE];
- hp = my_gethostbyname_r(host,&tmp_hostent,buff2,sizeof(buff2),
+ gethostbyname_buff buff2;
+ hp = my_gethostbyname_r(host,&tmp_hostent,buff2.buff,sizeof(buff2),
&tmp_errno);
if (!hp)
{
+ my_gethostbyname_r_free();
net->last_errno=CR_UNKNOWN_HOST;
sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, tmp_errno);
- my_gethostbyname_r_free();
goto error;
}
memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length);
my_gethostbyname_r_free();
}
sock_addr.sin_port = (ushort) htons((ushort) port);
- if (connect2(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
+ if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
mysql->options.connect_timeout) <0)
{
DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,host));
@@ -1400,8 +1844,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
DBUG_DUMP("packet",(char*) net->read_pos,10);
DBUG_PRINT("info",("mysql protocol version %d, server=%d",
PROTOCOL_VERSION, mysql->protocol_version));
- if (mysql->protocol_version != PROTOCOL_VERSION &&
- mysql->protocol_version != PROTOCOL_VERSION-1)
+ if (mysql->protocol_version != PROTOCOL_VERSION)
{
net->last_errno= CR_VERSION_ERROR;
sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version,
@@ -1437,7 +1880,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
charset_name=charset_name_buff;
sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */
if (!(mysql->charset =
- get_charset((uint8) mysql->server_language, MYF(MY_WME))))
+ get_charset((uint8) mysql->server_language, MYF(0))))
mysql->charset = default_charset_info; /* shouldn't be fatal */
}
@@ -1493,6 +1936,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
client_flag|=CLIENT_CAPABILITIES;
#ifdef HAVE_OPENSSL
+ if (mysql->options.ssl_key || mysql->options.ssl_cert ||
+ mysql->options.ssl_ca || mysql->options.ssl_capath ||
+ mysql->options.ssl_cipher)
+ mysql->options.use_ssl= 1;
if (mysql->options.use_ssl)
client_flag|=CLIENT_SSL;
#endif /* HAVE_OPENSSL */
@@ -1527,19 +1974,40 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
mysql->client_flag=client_flag;
#ifdef HAVE_OPENSSL
- /* Oops.. are we careful enough to not send ANY information */
- /* without encryption? */
+ /*
+ Oops.. are we careful enough to not send ANY information without
+ encryption?
+ */
if (client_flag & CLIENT_SSL)
{
+ struct st_mysql_options *options= &mysql->options;
if (my_net_write(net,buff,(uint) (2)) || net_flush(net))
+ {
+ net->last_errno= CR_SERVER_LOST;
+ strmov(net->last_error,ER(net->last_errno));
goto error;
+ }
/* Do the SSL layering. */
+ if (!(mysql->connector_fd=
+ (gptr) new_VioSSLConnectorFd(options->ssl_key,
+ options->ssl_cert,
+ options->ssl_ca,
+ options->ssl_capath,
+ options->ssl_cipher)))
+ {
+ net->last_errno= CR_SSL_CONNECTION_ERROR;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
+ }
DBUG_PRINT("info", ("IO layer change in progress..."));
- VioSSLConnectorFd* connector_fd = (VioSSLConnectorFd*)
- (mysql->connector_fd);
- VioSocket* vio_socket = (VioSocket*)(mysql->net.vio);
- VioSSL* vio_ssl = connector_fd->connect(vio_socket);
- mysql->net.vio = (NetVio*)(vio_ssl);
+ if(sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),
+ mysql->net.vio, (long) (mysql->options.connect_timeout)))
+ {
+ net->last_errno= CR_SSL_CONNECTION_ERROR;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
+ }
+ DBUG_PRINT("info", ("IO layer change done!"));
}
#endif /* HAVE_OPENSSL */
@@ -1547,6 +2015,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
mysql->server_version,mysql->server_capabilities,
mysql->server_status, client_flag));
+ /* This needs to be changed as it's not useful with big packets */
int3store(buff+2,max_allowed_packet);
if (user && user[0])
strmake(buff+5,user,32); /* Max user name */
@@ -1564,11 +2033,18 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
mysql->db=my_strdup(db,MYF(MY_WME));
db=0;
}
- if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net) ||
- net_safe_read(mysql) == packet_error)
+ if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
+ {
+ net->last_errno= CR_SERVER_LOST;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
+ }
+ if (net_safe_read(mysql) == packet_error)
goto error;
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
net->compress=1;
+ if (mysql->options.max_allowed_packet)
+ net->max_packet_size= mysql->options.max_allowed_packet;
if (db && mysql_select_db(mysql,db))
goto error;
if (mysql->options.init_command)
@@ -1581,6 +2057,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
mysql->reconnect=reconnect;
}
+ if (mysql->options.rpl_probe && mysql_rpl_probe(mysql))
+ goto error;
+
DBUG_PRINT("exit",("Mysql handler: %lx",mysql));
reset_sigpipe(mysql);
DBUG_RETURN(mysql);
@@ -1600,6 +2079,26 @@ error:
}
+/* needed when we move MYSQL structure to a different address */
+
+static void mysql_fix_pointers(MYSQL* mysql, MYSQL* old_mysql)
+{
+ MYSQL *tmp, *tmp_prev;
+ if (mysql->master == old_mysql)
+ mysql->master = mysql;
+ if (mysql->last_used_con == old_mysql)
+ mysql->last_used_con = mysql;
+ if (mysql->last_used_slave == old_mysql)
+ mysql->last_used_slave = mysql;
+ for (tmp_prev = mysql, tmp = mysql->next_slave;
+ tmp != old_mysql;tmp = tmp->next_slave)
+ {
+ tmp_prev = tmp;
+ }
+ tmp_prev->next_slave = mysql;
+}
+
+
static my_bool mysql_reconnect(MYSQL *mysql)
{
MYSQL tmp_mysql;
@@ -1608,21 +2107,29 @@ static my_bool mysql_reconnect(MYSQL *mysql)
if (!mysql->reconnect ||
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
{
- /* Allov reconnect next time */
+ /* Allow reconnect next time */
mysql->server_status&= ~SERVER_STATUS_IN_TRANS;
+ mysql->net.last_errno=CR_SERVER_GONE_ERROR;
+ strmov(mysql->net.last_error,ER(mysql->net.last_errno));
DBUG_RETURN(1);
}
mysql_init(&tmp_mysql);
tmp_mysql.options=mysql->options;
bzero((char*) &mysql->options,sizeof(mysql->options));
+ tmp_mysql.rpl_pivot = mysql->rpl_pivot;
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
mysql->db, mysql->port, mysql->unix_socket,
mysql->client_flag))
+ {
+ mysql->net.last_errno= tmp_mysql.net.last_errno;
+ strmov(mysql->net.last_error, tmp_mysql.net.last_error);
DBUG_RETURN(1);
+ }
tmp_mysql.free_me=mysql->free_me;
mysql->free_me=0;
mysql_close(mysql);
*mysql=tmp_mysql;
+ mysql_fix_pointers(mysql, &tmp_mysql); /* adjust connection pointers */
net_clear(&mysql->net);
mysql->affected_rows= ~(my_ulonglong) 0;
DBUG_RETURN(0);
@@ -1630,7 +2137,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
/**************************************************************************
-** Change user and database
+ Change user and database
**************************************************************************/
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
@@ -1648,7 +2155,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
pos=scramble(pos, mysql->scramble_buff, passwd,
(my_bool) (mysql->protocol_version == 9));
pos=strmov(pos+1,db ? db : "");
- if (simple_command(mysql,COM_CHANGE_USER, buff,(uint) (pos-buff),0))
+ if (simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (pos-buff),0))
DBUG_RETURN(1);
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
@@ -1663,7 +2170,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
/**************************************************************************
-** Set current database
+ Set current database
**************************************************************************/
int STDCALL
@@ -1673,7 +2180,7 @@ mysql_select_db(MYSQL *mysql, const char *db)
DBUG_ENTER("mysql_select_db");
DBUG_PRINT("enter",("db: '%s'",db));
- if ((error=simple_command(mysql,COM_INIT_DB,db,(uint) strlen(db),0)))
+ if ((error=simple_command(mysql,COM_INIT_DB,db,(ulong) strlen(db),0)))
DBUG_RETURN(error);
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
mysql->db=my_strdup(db,MYF(MY_WME));
@@ -1682,8 +2189,8 @@ mysql_select_db(MYSQL *mysql, const char *db)
/*************************************************************************
-** Send a QUIT to the server and close the connection
-** If handle is alloced by mysql connect free it.
+ Send a QUIT to the server and close the connection
+ If handle is alloced by mysql connect free it.
*************************************************************************/
void STDCALL
@@ -1698,7 +2205,7 @@ mysql_close(MYSQL *mysql)
mysql->status=MYSQL_STATUS_READY; /* Force command */
mysql->reconnect=0;
simple_command(mysql,COM_QUIT,NullS,0,1);
- end_server(mysql);
+ end_server(mysql); /* Sets mysql->net.vio= 0 */
}
my_free((gptr) mysql->host_info,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
@@ -1714,14 +2221,28 @@ mysql_close(MYSQL *mysql)
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
+#ifdef HAVE_OPENSSL
+ mysql_ssl_free(mysql);
+#endif /* HAVE_OPENSSL */
/* Clear pointers for better safety */
mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
bzero((char*) &mysql->options,sizeof(mysql->options));
- mysql->net.vio = 0;
-#ifdef HAVE_OPENSSL
- ((VioConnectorFd*)(mysql->connector_fd))->delete();
- mysql->connector_fd = 0;
-#endif /* HAVE_OPENSSL */
+
+ /* free/close slave list */
+ if (mysql->rpl_pivot)
+ {
+ MYSQL* tmp;
+ for (tmp = mysql->next_slave; tmp != mysql; )
+ {
+ /* trick to avoid following freed pointer */
+ MYSQL* tmp1 = tmp->next_slave;
+ mysql_close(tmp);
+ tmp = tmp1;
+ }
+ mysql->rpl_pivot=0;
+ }
+ if (mysql != mysql->master)
+ mysql_close(mysql->master);
if (mysql->free_me)
my_free((gptr) mysql,MYF(0));
}
@@ -1730,8 +2251,8 @@ mysql_close(MYSQL *mysql)
/**************************************************************************
-** Do a query. If query returned rows, free old rows.
-** Read data by mysql_store_result or by repeat call of mysql_fetch_row
+ Do a query. If query returned rows, free old rows.
+ Read data by mysql_store_result or by repeat call of mysql_fetch_row
**************************************************************************/
int STDCALL
@@ -1740,6 +2261,69 @@ mysql_query(MYSQL *mysql, const char *query)
return mysql_real_query(mysql,query, (uint) strlen(query));
}
+
+static MYSQL* spawn_init(MYSQL* parent, const char* host,
+ unsigned int port, const char* user,
+ const char* passwd)
+{
+ MYSQL* child;
+ DBUG_ENTER("spawn_init");
+ if (!(child= mysql_init(0)))
+ DBUG_RETURN(0);
+
+ child->options.user= my_strdup((user) ? user :
+ (parent->user ? parent->user :
+ parent->options.user), MYF(0));
+ child->options.password= my_strdup((passwd) ? passwd :
+ (parent->passwd ?
+ parent->passwd :
+ parent->options.password), MYF(0));
+ child->options.port= port;
+ child->options.host= my_strdup((host) ? host :
+ (parent->host ?
+ parent->host :
+ parent->options.host), MYF(0));
+ if (parent->db)
+ child->options.db= my_strdup(parent->db, MYF(0));
+ else if (parent->options.db)
+ child->options.db= my_strdup(parent->options.db, MYF(0));
+
+ /*
+ rpl_pivot is set to 1 in mysql_init(); Reset it as we are not doing
+ replication here
+ */
+ child->rpl_pivot= 0;
+ DBUG_RETURN(child);
+}
+
+
+int
+STDCALL mysql_set_master(MYSQL* mysql, const char* host,
+ unsigned int port, const char* user,
+ const char* passwd)
+{
+ if (mysql->master != mysql && !mysql->master->rpl_pivot)
+ mysql_close(mysql->master);
+ if (!(mysql->master = spawn_init(mysql, host, port, user, passwd)))
+ return 1;
+ return 0;
+}
+
+int
+STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
+ unsigned int port,
+ const char* user,
+ const char* passwd)
+{
+ MYSQL* slave;
+ if (!(slave = spawn_init(mysql, host, port, user, passwd)))
+ return 1;
+ slave->next_slave = mysql->next_slave;
+ mysql->next_slave = slave;
+ return 0;
+}
+
+
/*
Send the query and return so we can do something else.
Needs to be followed by mysql_read_query_result() when we want to
@@ -1747,19 +2331,42 @@ mysql_query(MYSQL *mysql, const char *query)
*/
int STDCALL
-mysql_send_query(MYSQL* mysql, const char* query, uint length)
+mysql_send_query(MYSQL* mysql, const char* query, ulong length)
{
- return simple_command(mysql, COM_QUERY, query, length, 1);
+ DBUG_ENTER("mysql_send_query");
+ DBUG_PRINT("enter",("rpl_parse: %d rpl_pivot: %d",
+ mysql->options.rpl_parse, mysql->rpl_pivot));
+
+ if (mysql->options.rpl_parse && mysql->rpl_pivot)
+ {
+ switch (mysql_rpl_query_type(query, length)) {
+ case MYSQL_RPL_MASTER:
+ DBUG_RETURN(mysql_master_send_query(mysql, query, length));
+ case MYSQL_RPL_SLAVE:
+ DBUG_RETURN(mysql_slave_send_query(mysql, query, length));
+ case MYSQL_RPL_ADMIN:
+ break; /* fall through */
+ }
+ }
+
+ mysql->last_used_con = mysql;
+ DBUG_RETURN(simple_command(mysql, COM_QUERY, query, length, 1));
}
+
int STDCALL mysql_read_query_result(MYSQL *mysql)
{
uchar *pos;
ulong field_count;
MYSQL_DATA *fields;
- uint length;
+ ulong length;
DBUG_ENTER("mysql_read_query_result");
+ /* read from the connection which we actually used, which
+ could differ from the original connection if we have slaves
+ */
+ mysql = mysql->last_used_con;
+
if ((length = net_safe_read(mysql)) == packet_error)
DBUG_RETURN(-1);
free_old_query(mysql); /* Free old result */
@@ -1796,80 +2403,86 @@ get_info:
CLIENT_LONG_FLAG))))
DBUG_RETURN(-1);
mysql->status=MYSQL_STATUS_GET_RESULT;
- mysql->field_count=field_count;
+ mysql->field_count= (uint) field_count;
DBUG_RETURN(0);
}
+
int STDCALL
-mysql_real_query(MYSQL *mysql, const char *query, uint length)
+mysql_real_query(MYSQL *mysql, const char *query, ulong length)
{
DBUG_ENTER("mysql_real_query");
DBUG_PRINT("enter",("handle: %lx",mysql));
- DBUG_PRINT("query",("Query = \"%s\"",query));
- if (simple_command(mysql,COM_QUERY,query,length,1))
+ DBUG_PRINT("query",("Query = '%-.4096s'",query));
+
+ if (mysql_send_query(mysql,query,length))
DBUG_RETURN(-1);
DBUG_RETURN(mysql_read_query_result(mysql));
}
+
static int
send_file_to_server(MYSQL *mysql, const char *filename)
{
- int fd, readcount;
- char buf[IO_SIZE*15],*tmp_name;
+ int fd, readcount, result= -1;
+ uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE);
+ char *buf, tmp_name[FN_REFLEN];
DBUG_ENTER("send_file_to_server");
- fn_format(buf,filename,"","",4); /* Convert to client format */
- if (!(tmp_name=my_strdup(buf,MYF(0))))
+ if (!(buf=my_malloc(packet_length,MYF(0))))
{
strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY));
DBUG_RETURN(-1);
}
+
+ fn_format(tmp_name,filename,"","",4); /* Convert to client format */
if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0)
{
+ my_net_write(&mysql->net,"",0); /* Server needs one packet */
+ net_flush(&mysql->net);
mysql->net.last_errno=EE_FILENOTFOUND;
- sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno);
- strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1);
- my_net_write(&mysql->net,"",0); net_flush(&mysql->net);
- my_free(tmp_name,MYF(0));
- DBUG_RETURN(-1);
+ my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1,
+ EE(mysql->net.last_errno),tmp_name, errno);
+ goto err;
}
- while ((readcount = (int) my_read(fd,buf,sizeof(buf),MYF(0))) > 0)
+ while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0)
{
if (my_net_write(&mysql->net,buf,readcount))
{
+ DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file"));
mysql->net.last_errno=CR_SERVER_LOST;
strmov(mysql->net.last_error,ER(mysql->net.last_errno));
- DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file"));
- (void) my_close(fd,MYF(0));
- my_free(tmp_name,MYF(0));
- DBUG_RETURN(-1);
+ goto err;
}
}
- (void) my_close(fd,MYF(0));
/* Send empty packet to mark end of file */
if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net))
{
mysql->net.last_errno=CR_SERVER_LOST;
- sprintf(mysql->net.last_error,ER(mysql->net.last_errno),socket_errno);
- my_free(tmp_name,MYF(0));
- DBUG_RETURN(-1);
+ sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno);
+ goto err;
}
if (readcount < 0)
{
mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */
- sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno);
- strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1);
- my_free(tmp_name,MYF(0));
- DBUG_RETURN(-1);
+ my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1,
+ tmp_name,errno);
+ goto err;
}
- DBUG_RETURN(0);
+ result=0; /* Ok */
+
+err:
+ if (fd >= 0)
+ (void) my_close(fd,MYF(0));
+ my_free(buf,MYF(0));
+ DBUG_RETURN(result);
}
/**************************************************************************
-** Alloc result struct for buffered results. All rows are read to buffer.
-** mysql_data_seek may be used.
+ Alloc result struct for buffered results. All rows are read to buffer.
+ mysql_data_seek may be used.
**************************************************************************/
MYSQL_RES * STDCALL
@@ -1878,6 +2491,9 @@ mysql_store_result(MYSQL *mysql)
MYSQL_RES *result;
DBUG_ENTER("mysql_store_result");
+ /* read from the actually used connection */
+ mysql = mysql->last_used_con;
+
if (!mysql->fields)
DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT)
@@ -1887,8 +2503,9 @@ mysql_store_result(MYSQL *mysql)
DBUG_RETURN(0);
}
mysql->status=MYSQL_STATUS_READY; /* server is ready */
- if (!(result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+
- sizeof(ulong)*mysql->field_count,
+ if (!(result=(MYSQL_RES*) my_malloc((uint) (sizeof(MYSQL_RES)+
+ sizeof(ulong) *
+ mysql->field_count),
MYF(MY_WME | MY_ZEROFILL))))
{
mysql->net.last_errno=CR_OUT_OF_MEMORY;
@@ -1915,13 +2532,13 @@ mysql_store_result(MYSQL *mysql)
/**************************************************************************
-** Alloc struct for use with unbuffered reads. Data is fetched by domand
-** when calling to mysql_fetch_row.
-** mysql_data_seek is a noop.
-**
-** No other queries may be specified with the same MYSQL handle.
-** There shouldn't be much processing per row because mysql server shouldn't
-** have to wait for the client (and will not wait more than 30 sec/packet).
+ Alloc struct for use with unbuffered reads. Data is fetched by domand
+ when calling to mysql_fetch_row.
+ mysql_data_seek is a noop.
+
+ No other queries may be specified with the same MYSQL handle.
+ There shouldn't be much processing per row because mysql server shouldn't
+ have to wait for the client (and will not wait more than 30 sec/packet).
**************************************************************************/
MYSQL_RES * STDCALL
@@ -1930,6 +2547,8 @@ mysql_use_result(MYSQL *mysql)
MYSQL_RES *result;
DBUG_ENTER("mysql_use_result");
+ mysql = mysql->last_used_con;
+
if (!mysql->fields)
DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT)
@@ -1963,7 +2582,7 @@ mysql_use_result(MYSQL *mysql)
/**************************************************************************
-** Return next field of the query results
+ Return next field of the query results
**************************************************************************/
MYSQL_FIELD * STDCALL
@@ -1976,7 +2595,7 @@ mysql_fetch_field(MYSQL_RES *result)
/**************************************************************************
-** Return next row of the query results
+ Return next row of the query results
**************************************************************************/
MYSQL_ROW STDCALL
@@ -2017,9 +2636,9 @@ mysql_fetch_row(MYSQL_RES *res)
}
/**************************************************************************
-** Get column lengths of the current row
-** If one uses mysql_use_result, res->lengths contains the length information,
-** else the lengths are calculated from the offset between pointers.
+ Get column lengths of the current row
+ If one uses mysql_use_result, res->lengths contains the length information,
+ else the lengths are calculated from the offset between pointers.
**************************************************************************/
ulong * STDCALL
@@ -2044,7 +2663,7 @@ mysql_fetch_lengths(MYSQL_RES *res)
continue;
}
if (start) /* Found end of prev string */
- *prev_length= (uint) (*column-start-1);
+ *prev_length= (ulong) (*column-start-1);
start= *column;
prev_length=lengths;
}
@@ -2053,7 +2672,7 @@ mysql_fetch_lengths(MYSQL_RES *res)
}
/**************************************************************************
-** Move to a specific row and column
+ Move to a specific row and column
**************************************************************************/
void STDCALL
@@ -2068,9 +2687,9 @@ mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
}
/*************************************************************************
-** put the row or field cursor one a position one got from mysql_row_tell()
-** This doesn't restore any data. The next mysql_fetch_row or
-** mysql_fetch_field will return the next row or field after the last used
+ put the row or field cursor one a position one got from mysql_row_tell()
+ This doesn't restore any data. The next mysql_fetch_row or
+ mysql_fetch_field will return the next row or field after the last used
*************************************************************************/
MYSQL_ROW_OFFSET STDCALL
@@ -2092,7 +2711,7 @@ mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET field_offset)
}
/*****************************************************************************
-** List all databases
+ List all databases
*****************************************************************************/
MYSQL_RES * STDCALL
@@ -2109,8 +2728,8 @@ mysql_list_dbs(MYSQL *mysql, const char *wild)
/*****************************************************************************
-** List all tables in a database
-** If wild is given then only the tables matching wild is returned
+ List all tables in a database
+ If wild is given then only the tables matching wild is returned
*****************************************************************************/
MYSQL_RES * STDCALL
@@ -2127,10 +2746,10 @@ mysql_list_tables(MYSQL *mysql, const char *wild)
/**************************************************************************
-** List all fields in a table
-** If wild is given then only the fields matching wild is returned
-** Instead of this use query:
-** show fields in 'table' like "wild"
+ List all fields in a table
+ If wild is given then only the fields matching wild is returned
+ Instead of this use query:
+ show fields in 'table' like "wild"
**************************************************************************/
MYSQL_RES * STDCALL
@@ -2145,7 +2764,7 @@ mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
LINT_INIT(query);
end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
- if (simple_command(mysql,COM_FIELD_LIST,buff,(uint) (end-buff),1) ||
+ if (simple_command(mysql,COM_FIELD_LIST,buff,(ulong) (end-buff),1) ||
!(query = read_rows(mysql,(MYSQL_FIELD*) 0,6)))
DBUG_RETURN(NULL);
@@ -2195,12 +2814,13 @@ mysql_list_processes(MYSQL *mysql)
}
+#ifdef USE_OLD_FUNCTIONS
int STDCALL
mysql_create_db(MYSQL *mysql, const char *db)
{
DBUG_ENTER("mysql_createdb");
DBUG_PRINT("enter",("db: %s",db));
- DBUG_RETURN(simple_command(mysql,COM_CREATE_DB,db, (uint) strlen(db),0));
+ DBUG_RETURN(simple_command(mysql,COM_CREATE_DB,db, (ulong) strlen(db),0));
}
@@ -2209,8 +2829,9 @@ mysql_drop_db(MYSQL *mysql, const char *db)
{
DBUG_ENTER("mysql_drop_db");
DBUG_PRINT("enter",("db: %s",db));
- DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(uint) strlen(db),0));
+ DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(ulong) strlen(db),0));
}
+#endif
int STDCALL
@@ -2247,7 +2868,7 @@ mysql_dump_debug_info(MYSQL *mysql)
DBUG_RETURN(simple_command(mysql,COM_DEBUG,0,0,0));
}
-char * STDCALL
+const char * STDCALL
mysql_stat(MYSQL *mysql)
{
DBUG_ENTER("mysql_stat");
@@ -2272,14 +2893,14 @@ mysql_ping(MYSQL *mysql)
}
-char * STDCALL
+const char * STDCALL
mysql_get_server_info(MYSQL *mysql)
{
return((char*) mysql->server_version);
}
-char * STDCALL
+const char * STDCALL
mysql_get_host_info(MYSQL *mysql)
{
return(mysql->host_info);
@@ -2292,12 +2913,17 @@ mysql_get_proto_info(MYSQL *mysql)
return (mysql->protocol_version);
}
-char * STDCALL
+const char * STDCALL
mysql_get_client_info(void)
{
return (char*) MYSQL_SERVER_VERSION;
}
+ulong STDCALL mysql_get_client_version(void)
+{
+ return MYSQL_VERSION_ID;
+}
+
int STDCALL
mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
@@ -2347,8 +2973,8 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
}
/****************************************************************************
-** Functions to get information from the MySQL structure
-** These are functions to make shared libraries more usable.
+ Functions to get information from the MySQL structure
+ These are functions to make shared libraries more usable.
****************************************************************************/
/* MYSQL_RES */
@@ -2377,12 +3003,12 @@ MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res)
return (res)->fields;
}
-MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res)
+MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res)
{
return res->data_cursor;
}
-uint STDCALL mysql_field_tell(MYSQL_RES *res)
+MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res)
{
return (res)->current_field;
}
@@ -2391,32 +3017,32 @@ uint STDCALL mysql_field_tell(MYSQL_RES *res)
unsigned int STDCALL mysql_field_count(MYSQL *mysql)
{
- return mysql->field_count;
+ return mysql->last_used_con->field_count;
}
my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql)
{
- return (mysql)->affected_rows;
+ return mysql->last_used_con->affected_rows;
}
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql)
{
- return (mysql)->insert_id;
+ return mysql->last_used_con->insert_id;
}
uint STDCALL mysql_errno(MYSQL *mysql)
{
- return (mysql)->net.last_errno;
+ return mysql->net.last_errno;
}
-char * STDCALL mysql_error(MYSQL *mysql)
+const char * STDCALL mysql_error(MYSQL *mysql)
{
- return (mysql)->net.last_error;
+ return mysql->net.last_error;
}
-char *STDCALL mysql_info(MYSQL *mysql)
+const char *STDCALL mysql_info(MYSQL *mysql)
{
- return (mysql)->info;
+ return mysql->info;
}
ulong STDCALL mysql_thread_id(MYSQL *mysql)
@@ -2440,13 +3066,26 @@ uint STDCALL mysql_thread_safe(void)
}
/****************************************************************************
-** Some support functions
+ Some support functions
****************************************************************************/
/*
-** Add escape characters to a string (blob?) to make it suitable for a insert
-** to should at least have place for length*2+1 chars
-** Returns the length of the to string
+ Functions called my my_net_init() to set some application specific variables
+*/
+
+void my_net_local_init(NET *net)
+{
+ net->max_packet= (uint) net_buffer_length;
+ net->read_timeout= (uint) net_read_timeout;
+ net->write_timeout=(uint) net_write_timeout;
+ net->retry_count= 1;
+ net->max_packet_size= max(net_buffer_length, max_allowed_packet);
+}
+
+/*
+ Add escape characters to a string (blob?) to make it suitable for a insert
+ to should at least have place for length*2+1 chars
+ Returns the length of the to string
*/
ulong STDCALL
diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def
new file mode 100644
index 00000000000..721097905a8
--- /dev/null
+++ b/libmysql/libmysql.def
@@ -0,0 +1,129 @@
+LIBRARY LIBMYSQL
+DESCRIPTION 'MySQL 4.0 Client Library'
+VERSION 5.0
+EXPORTS
+ mysql_affected_rows
+ mysql_close
+ mysql_data_seek
+ mysql_debug
+ mysql_dump_debug_info
+ mysql_eof
+ mysql_errno
+ mysql_error
+ mysql_escape_string
+ mysql_fetch_field
+ mysql_fetch_field_direct
+ mysql_fetch_fields
+ mysql_fetch_lengths
+ mysql_fetch_row
+ mysql_field_count
+ mysql_field_seek
+ mysql_field_tell
+ mysql_free_result
+ mysql_get_client_info
+ mysql_get_host_info
+ mysql_get_proto_info
+ mysql_get_server_info
+ mysql_get_client_version
+ mysql_info
+ mysql_init
+ mysql_insert_id
+ mysql_kill
+ mysql_list_dbs
+ mysql_list_fields
+ mysql_list_processes
+ mysql_list_tables
+ mysql_num_fields
+ mysql_num_rows
+ mysql_odbc_escape_string
+ mysql_options
+ mysql_ping
+ mysql_query
+ mysql_real_connect
+ mysql_real_query
+ mysql_refresh
+ mysql_row_seek
+ mysql_row_tell
+ mysql_select_db
+ mysql_shutdown
+ mysql_stat
+ mysql_store_result
+ mysql_thread_id
+ mysql_use_result
+ bmove_upp
+ delete_dynamic
+ _dig_vec
+ init_dynamic_array
+ insert_dynamic
+ int2str
+ is_prefix
+ list_add
+ list_delete
+ max_allowed_packet
+ my_casecmp
+ my_init
+ my_end
+ my_strdup
+ my_malloc
+ my_memdup
+ my_no_flags_free
+ my_realloc
+ mysql_thread_end
+ mysql_thread_init
+ net_buffer_length
+ set_dynamic
+ strcend
+ strdup_root
+ strfill
+ strinstr
+ strmake
+ strmov
+ strxmov
+ myodbc_remove_escape
+ mysql_thread_safe
+ mysql_character_set_name
+ mysql_change_user
+ mysql_send_query
+ mysql_read_query_result
+ mysql_real_escape_string
+ mysql_ssl_set
+ mysql_real_connect
+ mysql_master_query
+ mysql_master_send_query
+ mysql_slave_query
+ mysql_slave_send_query
+ mysql_enable_rpl_parse
+ mysql_disable_rpl_parse
+ mysql_rpl_parse_enabled
+ mysql_enable_reads_from_master
+ mysql_disable_reads_from_master
+ mysql_reads_from_master_enabled
+ mysql_rpl_query_type
+ mysql_rpl_probe
+ mysql_set_master
+ mysql_add_slave
+ my_getopt_print_errors
+ handle_options
+ my_print_help
+ my_print_variables
+ getopt_ull_limit_value
+ getopt_compare_strings
+ load_defaults
+ free_defaults
+ my_path
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libmysql/manager.c b/libmysql/manager.c
new file mode 100644
index 00000000000..1a4ac718ef9
--- /dev/null
+++ b/libmysql/manager.c
@@ -0,0 +1,268 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#if defined(THREAD)
+#include <my_pthread.h> /* because of signal() */
+#endif
+#include "mysql.h"
+#include "mysql_version.h"
+#include "mysqld_error.h"
+#include <my_sys.h>
+#include <mysys_err.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include <my_net.h>
+#include <errmsg.h>
+#include <violite.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <errno.h>
+
+#if defined(OS2)
+# include <sys/un.h>
+#elif defined(__NETWARE__)
+#include <netdb.h>
+#include <sys/select.h>
+#include <sys/utsname.h>
+#elif !defined( __WIN__)
+#include <sys/resource.h>
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+#include <netdb.h>
+#ifdef HAVE_SELECT_H
+# include <select.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <sys/utsname.h>
+#endif /* __WIN__ */
+
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif
+
+#define RES_BUF_SHIFT 5
+#define NET_BUF_SIZE 2048
+
+MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con)
+{
+ int net_buf_size=NET_BUF_SIZE;
+ if (!con)
+ {
+ if (!(con=(MYSQL_MANAGER*)my_malloc(sizeof(*con)+net_buf_size,
+ MYF(MY_WME|MY_ZEROFILL))))
+ return 0;
+ con->free_me=1;
+ con->net_buf=(char*)con+sizeof(*con);
+ }
+ else
+ {
+ bzero((char*)con,sizeof(*con));
+ if (!(con->net_buf=my_malloc(net_buf_size,MYF(0))))
+ return 0;
+ }
+ con->net_buf_pos=con->net_data_end=con->net_buf;
+ con->net_buf_size=net_buf_size;
+ return con;
+}
+
+MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
+ const char* host,
+ const char* user,
+ const char* passwd,
+ unsigned int port)
+{
+ my_socket sock;
+ struct sockaddr_in sock_addr;
+ in_addr_t ip_addr;
+ char msg_buf[MAX_MYSQL_MANAGER_MSG];
+ int msg_len;
+ Vio* vio;
+ my_bool not_used;
+
+ if (!host)
+ host="localhost";
+ if (!user)
+ user="root";
+ if (!passwd)
+ passwd="";
+
+ if ((sock=(my_socket)socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
+ {
+ con->last_errno=errno;
+ strmov(con->last_error,"Cannot create socket");
+ goto err;
+ }
+ if (!(vio=vio_new(sock,VIO_TYPE_TCPIP,FALSE)))
+ {
+ con->last_errno=ENOMEM;
+ strmov(con->last_error,"Cannot create network I/O object");
+ goto err;
+ }
+ vio_blocking(vio, TRUE, &not_used);
+ my_net_init(&con->net,vio);
+ bzero((char*) &sock_addr,sizeof(sock_addr));
+ sock_addr.sin_family = AF_INET;
+ if ((int) (ip_addr = inet_addr(host)) != (int) INADDR_NONE)
+ {
+ memcpy_fixed(&sock_addr.sin_addr,&ip_addr,sizeof(ip_addr));
+ }
+ else
+ {
+ int tmp_errno;
+ struct hostent tmp_hostent,*hp;
+ char buff2[GETHOSTBYNAME_BUFF_SIZE];
+ hp = my_gethostbyname_r(host,&tmp_hostent,buff2,sizeof(buff2),
+ &tmp_errno);
+ if (!hp)
+ {
+ con->last_errno=tmp_errno;
+ sprintf(con->last_error,"Could not resolve host '%s'",host);
+ my_gethostbyname_r_free();
+ goto err;
+ }
+ memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length);
+ my_gethostbyname_r_free();
+ }
+ sock_addr.sin_port = (ushort) htons((ushort) port);
+ if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
+ 0) <0)
+ {
+ con->last_errno=errno;
+ sprintf(con->last_error ,"Could not connect to %-.64s", host);
+ goto err;
+ }
+ /* read the greating */
+ if (my_net_read(&con->net) == packet_error)
+ {
+ con->last_errno=errno;
+ strmov(con->last_error,"Read error on socket");
+ goto err;
+ }
+ sprintf(msg_buf,"%-.16s %-.16s\n",user,passwd);
+ msg_len=strlen(msg_buf);
+ if (my_net_write(&con->net,msg_buf,msg_len) || net_flush(&con->net))
+ {
+ con->last_errno=con->net.last_errno;
+ strmov(con->last_error,"Write error on socket");
+ goto err;
+ }
+ if (my_net_read(&con->net) == packet_error)
+ {
+ con->last_errno=errno;
+ strmov(con->last_error,"Read error on socket");
+ goto err;
+ }
+ if ((con->cmd_status=atoi((char*) con->net.read_pos)) != MANAGER_OK)
+ {
+ strmov(con->last_error,"Access denied");
+ goto err;
+ }
+ if (!my_multi_malloc(MYF(0), &con->host, (uint)strlen(host)+1,
+ &con->user, (uint)strlen(user)+1,
+ &con->passwd, (uint)strlen(passwd)+1,
+ NullS))
+ {
+ con->last_errno=ENOMEM;
+ strmov(con->last_error,"Out of memory");
+ goto err;
+ }
+ strmov(con->host,host);
+ strmov(con->user,user);
+ strmov(con->passwd,passwd);
+ return con;
+
+err:
+ {
+ my_bool free_me=con->free_me;
+ con->free_me=0;
+ mysql_manager_close(con);
+ con->free_me=free_me;
+ }
+ return 0;
+}
+
+void STDCALL mysql_manager_close(MYSQL_MANAGER* con)
+{
+ /*
+ No need to free con->user and con->passwd, because they were
+ allocated in my_multimalloc() along with con->host, freeing
+ con->hosts frees the whole block
+ */
+ my_free((gptr)con->host,MYF(MY_ALLOW_ZERO_PTR));
+ net_end(&con->net);
+ if (con->free_me)
+ my_free((gptr)con,MYF(0));
+}
+
+
+int STDCALL mysql_manager_command(MYSQL_MANAGER* con,const char* cmd,
+ int cmd_len)
+{
+ if (!cmd_len)
+ cmd_len=strlen(cmd);
+ if (my_net_write(&con->net,(char*)cmd,cmd_len) || net_flush(&con->net))
+ {
+ con->last_errno=errno;
+ strmov(con->last_error,"Write error on socket");
+ return 1;
+ }
+ con->eof=0;
+ return 0;
+}
+
+
+int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf,
+ int res_buf_size)
+{
+ char* res_buf_end=res_buf+res_buf_size;
+ char* net_buf=(char*) con->net.read_pos, *net_buf_end;
+ int res_buf_shift=RES_BUF_SHIFT;
+ uint num_bytes;
+
+ if (res_buf_size<RES_BUF_SHIFT)
+ {
+ con->last_errno=ENOMEM;
+ strmov(con->last_error,"Result buffer too small");
+ return 1;
+ }
+
+ if ((num_bytes=my_net_read(&con->net)) == packet_error)
+ {
+ con->last_errno=errno;
+ strmov(con->last_error,"socket read failed");
+ return 1;
+ }
+
+ net_buf_end=net_buf+num_bytes;
+
+ if ((con->eof=(net_buf[3]==' ')))
+ res_buf_shift--;
+ net_buf+=res_buf_shift;
+ res_buf_end[-1]=0;
+ for (;net_buf<net_buf_end && res_buf < res_buf_end;res_buf++,net_buf++)
+ {
+ if ((*res_buf=*net_buf) == '\r')
+ {
+ *res_buf=0;
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/libmysql/password.c b/libmysql/password.c
deleted file mode 100644
index 71ed68c6b2c..00000000000
--- a/libmysql/password.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* password checking routines */
-/*****************************************************************************
- The main idea is that no password are sent between client & server on
- connection and that no password are saved in mysql in a decodable form.
-
- On connection a random string is generated and sent to the client.
- The client generates a new string with a random generator inited with
- the hash values from the password and the sent string.
- This 'check' string is sent to the server where it is compared with
- a string generated from the stored hash_value of the password and the
- random string.
-
- The password is saved (in user.password) by using the PASSWORD() function in
- mysql.
-
- Example:
- update user set password=PASSWORD("hello") where user="test"
- This saves a hashed number as a string in the password field.
-*****************************************************************************/
-
-#include <global.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include "mysql.h"
-
-
-void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2)
-{ /* For mysql 3.21.# */
-#ifdef HAVE_purify
- bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
-#endif
- rand_st->max_value= 0x3FFFFFFFL;
- rand_st->max_value_dbl=(double) rand_st->max_value;
- rand_st->seed1=seed1%rand_st->max_value ;
- rand_st->seed2=seed2%rand_st->max_value;
-}
-
-static void old_randominit(struct rand_struct *rand_st,ulong seed1)
-{ /* For mysql 3.20.# */
- rand_st->max_value= 0x01FFFFFFL;
- rand_st->max_value_dbl=(double) rand_st->max_value;
- seed1%=rand_st->max_value;
- rand_st->seed1=seed1 ; rand_st->seed2=seed1/2;
-}
-
-double rnd(struct rand_struct *rand_st)
-{
- rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
- rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
- return (((double) rand_st->seed1)/rand_st->max_value_dbl);
-}
-
-void hash_password(ulong *result, const char *password)
-{
- register ulong nr=1345345333L, add=7, nr2=0x12345671L;
- ulong tmp;
- for (; *password ; password++)
- {
- if (*password == ' ' || *password == '\t')
- continue; /* skipp space in password */
- tmp= (ulong) (uchar) *password;
- nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
- nr2+=(nr2 << 8) ^ nr;
- add+=tmp;
- }
- result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
- result[1]=nr2 & (((ulong) 1L << 31) -1L);
- return;
-}
-
-void make_scrambled_password(char *to,const char *password)
-{
- ulong hash_res[2];
- hash_password(hash_res,password);
- sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
-}
-
-static inline unsigned int char_val(char X)
-{
- return (uint) (X >= '0' && X <= '9' ? X-'0' :
- X >= 'A' && X <= 'Z' ? X-'A'+10 :
- X-'a'+10);
-}
-
-/*
-** This code assumes that len(password) is divideable with 8 and that
-** res is big enough (2 in mysql)
-*/
-
-void get_salt_from_password(ulong *res,const char *password)
-{
- res[0]=res[1]=0;
- if (password)
- {
- while (*password)
- {
- ulong val=0;
- uint i;
- for (i=0 ; i < 8 ; i++)
- val=(val << 4)+char_val(*password++);
- *res++=val;
- }
- }
- return;
-}
-
-void make_password_from_salt(char *to, ulong *hash_res)
-{
- sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
-}
-
-
-/*
- * Genererate a new message based on message and password
- * The same thing is done in client and server and the results are checked.
- */
-
-char *scramble(char *to,const char *message,const char *password,
- my_bool old_ver)
-{
- struct rand_struct rand_st;
- ulong hash_pass[2],hash_message[2];
- if (password && password[0])
- {
- char *to_start=to;
- hash_password(hash_pass,password);
- hash_password(hash_message,message);
- if (old_ver)
- old_randominit(&rand_st,hash_pass[0] ^ hash_message[0]);
- else
- randominit(&rand_st,hash_pass[0] ^ hash_message[0],
- hash_pass[1] ^ hash_message[1]);
- while (*message++)
- *to++= (char) (floor(rnd(&rand_st)*31)+64);
- if (!old_ver)
- { /* Make it harder to break */
- char extra=(char) (floor(rnd(&rand_st)*31));
- while (to_start != to)
- *(to_start++)^=extra;
- }
- }
- *to=0;
- return to;
-}
-
-
-my_bool check_scramble(const char *scrambled, const char *message,
- ulong *hash_pass, my_bool old_ver)
-{
- struct rand_struct rand_st;
- ulong hash_message[2];
- char buff[16],*to,extra; /* Big enough for check */
- const char *pos;
-
- hash_password(hash_message,message);
- if (old_ver)
- old_randominit(&rand_st,hash_pass[0] ^ hash_message[0]);
- else
- randominit(&rand_st,hash_pass[0] ^ hash_message[0],
- hash_pass[1] ^ hash_message[1]);
- to=buff;
- for (pos=scrambled ; *pos ; pos++)
- *to++=(char) (floor(rnd(&rand_st)*31)+64);
- if (old_ver)
- extra=0;
- else
- extra=(char) (floor(rnd(&rand_st)*31));
- to=buff;
- while (*scrambled)
- {
- if (*scrambled++ != (char) (*to++ ^ extra))
- return 1; /* Wrong password */
- }
- return 0;
-}
diff --git a/libmysql/violite.c b/libmysql/violite.c
deleted file mode 100644
index 37fee6fad3d..00000000000
--- a/libmysql/violite.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/*
- Note that we can't have assertion on file descriptors; The reason for
- this is that during mysql shutdown, another thread can close a file
- we are working on. In this case we should just return read errors from
- the file descriptior.
-*/
-
-#include <global.h>
-
-#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
-
-#include <errno.h>
-#include <assert.h>
-#include <violite.h>
-#include <my_sys.h>
-#include <my_net.h>
-#include <m_string.h>
-#ifdef HAVE_POLL
-#include <sys/poll.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) && !defined(__FreeBSD__)
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#if !defined(alpha_linux_port)
-#include <netinet/tcp.h>
-#endif
-#endif
-
-#if defined(__EMX__) || defined(OS2)
-#define ioctlsocket ioctl
-#endif /* defined(__EMX__) */
-
-#if defined(MSDOS) || defined(__WIN__)
-#define O_NONBLOCK 1 /* For emulation of fcntl() */
-#endif
-#ifndef EWOULDBLOCK
-#define SOCKET_EWOULDBLOCK SOCKET_EAGAIN
-#endif
-
-#ifndef __WIN__
-#define HANDLE void *
-#endif
-
-struct st_vio
-{
- my_socket sd; /* my_socket - real or imaginary */
- HANDLE hPipe;
- my_bool localhost; /* Are we from localhost? */
- int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
- struct sockaddr_in local; /* Local internet address */
- struct sockaddr_in remote; /* Remote internet address */
- enum enum_vio_type type; /* Type of connection */
- char desc[30]; /* String description */
-};
-
-typedef void *vio_ptr;
-typedef char *vio_cstring;
-
-/*
- * Helper to fill most of the Vio* with defaults.
- */
-
-static void vio_reset(Vio* vio, enum enum_vio_type type,
- my_socket sd, HANDLE hPipe,
- my_bool localhost)
-{
- bzero((char*) vio, sizeof(*vio));
- vio->type = type;
- vio->sd = sd;
- vio->hPipe = hPipe;
- vio->localhost= localhost;
-}
-
-/* Open the socket or TCP/IP connection and read the fnctl() status */
-
-Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
-{
- Vio *vio;
- DBUG_ENTER("vio_new");
- DBUG_PRINT("enter", ("sd=%d", sd));
- if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
- {
- vio_reset(vio, type, sd, 0, localhost);
- sprintf(vio->desc,
- (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
- vio->sd);
-#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
-#if !defined(NO_FCNTL_NONBLOCK)
- vio->fcntl_mode = fcntl(sd, F_GETFL);
-#elif defined(HAVE_SYS_IOCTL_H) /* hpux */
- /* Non blocking sockets doesn't work good on HPUX 11.0 */
- (void) ioctl(sd,FIOSNBIO,0);
-#endif
-#else /* !defined(__WIN__) && !defined(__EMX__) */
- {
- /* set to blocking mode by default */
- ulong arg=0, r;
- r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
- }
-#endif
- }
- DBUG_RETURN(vio);
-}
-
-
-#ifdef __WIN__
-
-Vio *vio_new_win32pipe(HANDLE hPipe)
-{
- Vio *vio;
- DBUG_ENTER("vio_new_handle");
- if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
- {
- vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
- strmov(vio->desc, "named pipe");
- }
- DBUG_RETURN(vio);
-}
-
-#endif
-
-void vio_delete(Vio * vio)
-{
- /* It must be safe to delete null pointers. */
- /* This matches the semantics of C++'s delete operator. */
- if (vio)
- {
- if (vio->type != VIO_CLOSED)
- vio_close(vio);
- my_free((gptr) vio,MYF(0));
- }
-}
-
-int vio_errno(Vio *vio __attribute__((unused)))
-{
- return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
-}
-
-
-int vio_read(Vio * vio, gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_read");
- DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
-#if defined( __WIN__) || defined(OS2)
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
-#ifdef OS2
- if (!DosRead((HFILE)vio->hPipe, buf, size, &length))
- DBUG_RETURN(-1);
-#else
- if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
- DBUG_RETURN(-1);
-#endif
- DBUG_RETURN(length);
- }
- r = recv(vio->sd, buf, size,0);
-#else
- errno=0; /* For linux */
- r = read(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("vio_error", ("Got error %d during read",socket_errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_write(Vio * vio, const gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_write");
- DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
-#if defined( __WIN__) || defined(OS2)
- if ( vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
-#ifdef OS2
- if (!DosWrite((HFILE)vio->hPipe, (char*) buf, size, &length))
- DBUG_RETURN(-1);
-#else
- if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
- DBUG_RETURN(-1);
-#endif
- DBUG_RETURN(length);
- }
- r = send(vio->sd, buf, size,0);
-#else
- r = write(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_blocking(Vio * vio, my_bool set_blocking_mode)
-{
- int r=0;
- DBUG_ENTER("vio_blocking");
- DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
-
-#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
-#if !defined(NO_FCNTL_NONBLOCK)
-
- if (vio->sd >= 0)
- {
- int old_fcntl=vio->fcntl_mode;
- if (set_blocking_mode)
- vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
- else
- vio->fcntl_mode |= O_NONBLOCK; /* set bit */
- if (old_fcntl != vio->fcntl_mode)
- r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
- }
-#endif /* !defined(NO_FCNTL_NONBLOCK) */
-#else /* !defined(__WIN__) && !defined(__EMX__) */
-#ifndef __EMX__
- if (vio->type != VIO_TYPE_NAMEDPIPE)
-#endif
- {
- ulong arg;
- int old_fcntl=vio->fcntl_mode;
- if (set_blocking_mode)
- {
- arg = 0;
- vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
- }
- else
- {
- arg = 1;
- vio->fcntl_mode |= O_NONBLOCK; /* set bit */
- }
- if (old_fcntl != vio->fcntl_mode)
- r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
- }
-#endif /* !defined(__WIN__) && !defined(__EMX__) */
- DBUG_RETURN(r);
-}
-
-my_bool
-vio_is_blocking(Vio * vio)
-{
- my_bool r;
- DBUG_ENTER("vio_is_blocking");
- r = !(vio->fcntl_mode & O_NONBLOCK);
- DBUG_PRINT("exit", ("%d", (int) r));
- DBUG_RETURN(r);
-}
-
-
-int vio_fastsend(Vio * vio __attribute__((unused)))
-{
- int r=0;
- DBUG_ENTER("vio_fastsend");
-
-#ifdef IPTOS_THROUGHPUT
- {
-#ifndef __EMX__
- int tos = IPTOS_THROUGHPUT;
- if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
-#endif /* !__EMX__ */
- {
- int nodelay = 1;
- if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
- sizeof(nodelay))) {
- DBUG_PRINT("warning",
- ("Couldn't set socket option for fast send"));
- r= -1;
- }
- }
- }
-#endif /* IPTOS_THROUGHPUT */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-int vio_keepalive(Vio* vio, my_bool set_keep_alive)
-{
- int r=0;
- uint opt = 0;
- DBUG_ENTER("vio_keepalive");
- DBUG_PRINT("enter", ("sd=%d set_keep_alive=%d", vio->sd, (int)
- set_keep_alive));
- if (vio->type != VIO_TYPE_NAMEDPIPE)
- {
- if (set_keep_alive)
- opt = 1;
- r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
- sizeof(opt));
- }
- DBUG_RETURN(r);
-}
-
-
-my_bool
-vio_should_retry(Vio * vio __attribute__((unused)))
-{
- int en = socket_errno;
- return en == SOCKET_EAGAIN || en == SOCKET_EINTR || en == SOCKET_EWOULDBLOCK;
-}
-
-
-int vio_close(Vio * vio)
-{
- int r;
- DBUG_ENTER("vio_close");
-#ifdef __WIN__
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
-#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIo(vio->hPipe);
- DisconnectNamedPipe(vio->hPipe);
-#endif
- r=CloseHandle(vio->hPipe);
- }
- else if (vio->type != VIO_CLOSED)
-#endif /* __WIN__ */
- {
- r=0;
- if (shutdown(vio->sd,2))
- r= -1;
- if (closesocket(vio->sd))
- r= -1;
- }
- if (r)
- {
- DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno));
- /* FIXME: error handling (not critical for MySQL) */
- }
- vio->type= VIO_CLOSED;
- vio->sd= -1;
- DBUG_RETURN(r);
-}
-
-
-const char *vio_description(Vio * vio)
-{
- return vio->desc;
-}
-
-enum enum_vio_type vio_type(Vio* vio)
-{
- return vio->type;
-}
-
-my_socket vio_fd(Vio* vio)
-{
- return vio->sd;
-}
-
-
-my_bool vio_peer_addr(Vio * vio, char *buf)
-{
- DBUG_ENTER("vio_peer_addr");
- DBUG_PRINT("enter", ("sd=%d", vio->sd));
- if (vio->localhost)
- {
- strmov(buf,"127.0.0.1");
- }
- else
- {
- size_socket addrLen = sizeof(struct sockaddr);
- if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
- &addrLen) != 0)
- {
- DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
- DBUG_RETURN(1);
- }
- my_inet_ntoa(vio->remote.sin_addr,buf);
- }
- DBUG_PRINT("exit", ("addr=%s", buf));
- DBUG_RETURN(0);
-}
-
-
-void vio_in_addr(Vio *vio, struct in_addr *in)
-{
- DBUG_ENTER("vio_in_addr");
- if (vio->localhost)
- bzero((char*) in, sizeof(*in)); /* This should never be executed */
- else
- *in=vio->remote.sin_addr;
- DBUG_VOID_RETURN;
-}
-
-
-/* Return 0 if there is data to be read */
-
-my_bool vio_poll_read(Vio *vio,uint timeout)
-{
-#ifndef HAVE_POLL
- return 0;
-#else
- struct pollfd fds;
- int res;
- DBUG_ENTER("vio_poll");
- fds.fd=vio->sd;
- fds.events=POLLIN;
- fds.revents=0;
- if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
- {
- DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
- }
- DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
-#endif
-}
-
-#endif /* HAVE_VIO */
diff --git a/libmysql_r/Makefile.am b/libmysql_r/Makefile.am
index f95ee0661da..ae091d86a88 100644
--- a/libmysql_r/Makefile.am
+++ b/libmysql_r/Makefile.am
@@ -19,10 +19,10 @@
target = libmysqlclient_r.la
target_defs = -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@
-## LIBS = @LIBS@
+LIBS = @LIBS@ @openssl_libs@
INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include \
- -I$(srcdir)/.. -I$(top_srcdir) -I..
+ -I$(srcdir)/.. -I$(top_srcdir) -I.. $(openssl_includes)
## automake barfs if you don't use $(srcdir) or $(top_srcdir) in include
include $(top_srcdir)/libmysql/Makefile.shared
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
new file mode 100644
index 00000000000..54bfd6503d4
--- /dev/null
+++ b/libmysqld/Makefile.am
@@ -0,0 +1,123 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+#
+# This file is public domain and comes with NO WARRANTY of any kind
+
+MYSQLDATAdir = $(localstatedir)
+MYSQLSHAREdir = $(pkgdatadir)
+MYSQLBASEdir= $(prefix)
+
+DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
+ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
+ -DDATADIR="\"$(MYSQLDATAdir)\"" \
+ -DSHAREDIR="\"$(MYSQLSHAREdir)\""
+INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(srcdir)/../include \
+ -I../include -I$(srcdir)/.. -I$(top_srcdir) -I.. \
+ -I../sql -I../regex
+
+noinst_LIBRARIES = libmysqld_int.a
+pkglib_LIBRARIES = libmysqld.a
+SUBDIRS = . examples
+libmysqld_sources= libmysqld.c lib_sql.cc
+libmysqlsources = errmsg.c get_password.c
+
+noinst_HEADERS = embedded_priv.h
+
+sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \
+ ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \
+ ha_myisam.cc ha_myisammrg.cc handler.cc sql_handler.cc \
+ hostname.cc init.cc password.c \
+ item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
+ item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
+ item_uniq.cc key.cc lock.cc log.cc log_event.cc mf_iocache.cc\
+ mini_client.cc net_pkg.cc net_serv.cc opt_ft.cc opt_range.cc \
+ opt_sum.cc procedure.cc records.cc sql_acl.cc \
+ repl_failsafe.cc slave.cc sql_load.cc sql_olap.cc \
+ sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
+ sql_crypt.cc sql_db.cc sql_delete.cc sql_insert.cc sql_lex.cc \
+ sql_list.cc sql_manager.cc sql_map.cc set_var.cc sql_parse.cc \
+ sql_rename.cc sql_repl.cc sql_select.cc sql_do.cc sql_show.cc \
+ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
+ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
+ unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc
+
+EXTRA_DIST = lib_vio.c
+
+libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
+libmysqld_a_SOURCES=
+
+# automake misses these
+sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy
+
+# The following libraries should be included in libmysqld.a
+INC_LIB= $(top_builddir)/regex/libregex.a \
+ $(top_builddir)/myisam/libmyisam.a \
+ $(top_builddir)/myisammrg/libmyisammrg.a \
+ $(top_builddir)/heap/libheap.a \
+ @innodb_libs@ @bdb_libs_with_path@ \
+ $(top_builddir)/mysys/libmysys.a \
+ $(top_builddir)/strings/libmystrings.a \
+ $(top_builddir)/dbug/libdbug.a \
+ $(top_builddir)/regex/libregex.a
+
+#
+# To make it easy for the end user to use the embedded library we
+# generate a total libmysqld.a from all library files,
+
+libmysqld.a: libmysqld_int.a $(INC_LIB)
+ if test ! -d tmp ; then mkdir tmp ; fi
+ rm -f $@ libmysqld_int2.a tmp/*.o tmp/*.a
+ cp $(INC_LIB) tmp
+ cp libmysqld_int.a libmysqld_int2.a ; \
+ cd tmp ; \
+ for file in *.a ; do \
+ bfile=`basename $$file .a` ; \
+ ar x $$file; \
+ for obj in *.o ; do mv $$obj $${bfile}_$$obj ; done ; \
+ ar q ../libmysqld_int2.a *.o ; \
+ rm -f *.o ; \
+ done
+ mv libmysqld_int2.a libmysqld.a
+ rm -f tmp/*
+ $(RANLIB) libmysqld.a
+
+## XXX: any time the client interface changes, we'll need to bump
+## the version info for libmysqld; however, it's possible for the
+## libmysqld interface to change without affecting the standard
+## libmysqlclient interface. Should we make a separate version
+## string for the two?
+#libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@
+#CLEANFILES = $(libmysqld_la_LIBADD) libmysqld.la
+
+# This is called from the toplevel makefile
+link_sources:
+ set -x; \
+ for f in $(sqlsources); do \
+ rm -f $(srcdir)/$$f; \
+ @LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \
+ done; \
+ for f in $(libmysqlsources); do \
+ rm -f $(srcdir)/$$f; \
+ @LN_CP_F@ $(srcdir)/../libmysql/$$f $(srcdir)/$$f; \
+ done
+
+clean-local:
+ rm -f `echo $(sqlsources) $(libmysqlsources) | sed "s;\.lo;.c;g"` \
+ $(top_srcdir)/linked_libmysqld_sources
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/libmysqld/copyright b/libmysqld/copyright
new file mode 100644
index 00000000000..0b4dd1725a2
--- /dev/null
+++ b/libmysqld/copyright
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2000
+ * SWsoft company
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ */
diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h
new file mode 100644
index 00000000000..e17b72e84d8
--- /dev/null
+++ b/libmysqld/embedded_priv.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Prototypes for the embedded version of MySQL */
+
+#include <my_global.h>
+#include <mysql.h>
+#include <mysql_embed.h>
+#include <mysqld_error.h>
+#include <my_pthread.h>
+
+C_MODE_START
+extern void start_embedded_connection(NET * net);
+extern void end_embedded_connection(NET * net);
+extern void lib_connection_phase(NET *net, int phase);
+extern bool lib_dispatch_command(enum enum_server_command command, NET *net,
+ const char *arg, ulong length);
+C_MODE_END
diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am
new file mode 100644
index 00000000000..61f54b88b2e
--- /dev/null
+++ b/libmysqld/examples/Makefile.am
@@ -0,0 +1,28 @@
+noinst_PROGRAMS = mysqltest mysql
+client_sources = $(mysqltest_SOURCES) $(mysql_SOURCES)
+
+link_sources:
+ for f in $(client_sources); do \
+ rm -f $(srcdir)/$$f; \
+ @LN_CP_F@ $(srcdir)/../../client/$$f $(srcdir)/$$f; \
+ done;
+
+DEFS = -DEMBEDDED_LIBRARY
+INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include -I$(srcdir) \
+ -I$(top_srcdir) -I$(top_srcdir)/client $(openssl_includes)
+LIBS = @LIBS@ @WRAPLIBS@
+LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS)
+
+mysqltest_LINK = $(CXXLINK)
+
+mysqltest_SOURCES = mysqltest.c
+
+mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \
+ my_readline.h sql_string.h completion_hash.h
+mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD)
+
+clean:
+ rm -f $(client_sources)
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/libmysqld/examples/builder-sample/emb_sample.bpr b/libmysqld/examples/builder-sample/emb_sample.bpr
new file mode 100644
index 00000000000..07b39a6832b
--- /dev/null
+++ b/libmysqld/examples/builder-sample/emb_sample.bpr
@@ -0,0 +1,192 @@
+# ---------------------------------------------------------------------------
+!if !$d(BCB)
+BCB = $(MAKEDIR)\..
+!endif
+
+# ---------------------------------------------------------------------------
+# IDE SECTION
+# ---------------------------------------------------------------------------
+# The following section of the project makefile is managed by the BCB IDE.
+# It is recommended to use the IDE to change any of the values in this
+# section.
+# ---------------------------------------------------------------------------
+
+VERSION = BCB.04.04
+# ---------------------------------------------------------------------------
+PROJECT = emb_sample.exe
+OBJFILES = emb_sample.obj emb_samples.obj
+RESFILES = emb_sample.res
+RESDEPEN = $(RESFILES) emb_samples.dfm
+LIBFILES = libmysqld.lib
+LIBRARIES =
+SPARELIBS = Vcl40.lib
+PACKAGES = Vcl40.bpi Vclx40.bpi vcljpg40.bpi bcbsmp40.bpi Qrpt40.bpi Vcldb40.bpi \
+ ibsmp40.bpi vcldbx40.bpi TeeUI40.bpi teedb40.bpi tee40.bpi nmfast40.bpi \
+ dclocx40.bpi
+DEFFILE =
+# ---------------------------------------------------------------------------
+PATHCPP = .;
+PATHASM = .;
+PATHPAS = .;
+PATHRC = .;
+DEBUGLIBPATH = $(BCB)\lib\debug
+RELEASELIBPATH = $(BCB)\lib\release
+USERDEFINES =
+SYSDEFINES = _RTLDLL;NO_STRICT;USEPACKAGES
+# ---------------------------------------------------------------------------
+CFLAG1 = -I$(BCB)\include;$(BCB)\include\vcl;..\..\..\include -Od -Hc \
+ -H=$(BCB)\lib\vcl40.csm -w -Ve -r- -a8 -k -y -v -vi- -c -b- -w-par -w-inl -Vx \
+ -tW -tWM -D$(SYSDEFINES);$(USERDEFINES)
+PFLAGS = -U$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELIBPATH) \
+ -I$(BCB)\include;$(BCB)\include\vcl;..\..\..\include -$YD -$W -$O- -v -JPHNE -M
+RFLAGS = -i$(BCB)\include;$(BCB)\include\vcl;..\..\..\include
+AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /i..\..\..\include /mx /w2 /zd
+LFLAGS = -L$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELIBPATH) -aa -Tpe -x -Gn -v
+# ---------------------------------------------------------------------------
+ALLOBJ = c0w32.obj Memmgr.Lib $(PACKAGES) sysinit.obj $(OBJFILES)
+ALLRES = $(RESFILES)
+ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mti.lib
+# ---------------------------------------------------------------------------
+!ifdef IDEOPTIONS
+
+[Version Info]
+IncludeVerInfo=1
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=0
+Locale=1046
+CodePage=1252
+
+[Version Info Keys]
+CompanyName=MySQL AB
+FileDescription=Embedded Server Sample
+FileVersion=1.0.0.0
+InternalName=Builder Embedded Server Sample
+LegalCopyright=GNU
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=1.0.0.0
+Comments=
+
+[HistoryLists\hlIncludePath]
+Count=2
+Item0=$(BCB)\include;$(BCB)\include\vcl;..\..\..\include
+Item1=$(BCB)\include;$(BCB)\include\vcl;..\..\..\inluce
+
+[HistoryLists\hlLibraryPath]
+Count=1
+Item0=$(BCB)\lib\obj;$(BCB)\lib
+
+[HistoryLists\hlDebugSourcePath]
+Count=1
+Item0=$(BCB)\source\vcl
+
+[Debugging]
+DebugSourceDirs=$(BCB)\source\vcl
+
+[Parameters]
+RunParams=
+HostApplication=
+RemoteHost=
+RemotePath=
+RemoteDebug=0
+
+[Compiler]
+InMemoryExe=0
+ShowInfoMsgs=0
+
+!endif
+
+# ---------------------------------------------------------------------------
+# MAKE SECTION
+# ---------------------------------------------------------------------------
+# This section of the project file is not used by the BCB IDE. It is for
+# the benefit of building from the command-line using the MAKE utility.
+# ---------------------------------------------------------------------------
+
+.autodepend
+# ---------------------------------------------------------------------------
+!if !$d(BCC32)
+BCC32 = bcc32
+!endif
+
+!if !$d(CPP32)
+CPP32 = cpp32
+!endif
+
+!if !$d(DCC32)
+DCC32 = dcc32
+!endif
+
+!if !$d(TASM32)
+TASM32 = tasm32
+!endif
+
+!if !$d(LINKER)
+LINKER = ilink32
+!endif
+
+!if !$d(BRCC32)
+BRCC32 = brcc32
+!endif
+
+# ---------------------------------------------------------------------------
+!if $d(PATHCPP)
+.PATH.CPP = $(PATHCPP)
+.PATH.C = $(PATHCPP)
+!endif
+
+!if $d(PATHPAS)
+.PATH.PAS = $(PATHPAS)
+!endif
+
+!if $d(PATHASM)
+.PATH.ASM = $(PATHASM)
+!endif
+
+!if $d(PATHRC)
+.PATH.RC = $(PATHRC)
+!endif
+# ---------------------------------------------------------------------------
+$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE)
+ $(BCB)\BIN\$(LINKER) @&&!
+ $(LFLAGS) +
+ $(ALLOBJ), +
+ $(PROJECT),, +
+ $(ALLLIB), +
+ $(DEFFILE), +
+ $(ALLRES)
+!
+# ---------------------------------------------------------------------------
+.pas.hpp:
+ $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }
+
+.pas.obj:
+ $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }
+
+.cpp.obj:
+ $(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< }
+
+.c.obj:
+ $(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< }
+
+.c.i:
+ $(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< }
+
+.cpp.i:
+ $(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< }
+
+.asm.obj:
+ $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@
+
+.rc.res:
+ $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $<
+# ---------------------------------------------------------------------------
diff --git a/libmysqld/examples/builder-sample/emb_sample.cpp b/libmysqld/examples/builder-sample/emb_sample.cpp
new file mode 100644
index 00000000000..5ad3bd69319
--- /dev/null
+++ b/libmysqld/examples/builder-sample/emb_sample.cpp
@@ -0,0 +1,23 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+USERES("emb_sample.res");
+USEFORM("emb_samples.cpp", Form1);
+USELIB("libmysqld.lib");
+//---------------------------------------------------------------------------
+WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
+{
+ try
+ {
+ Application->Initialize();
+ Application->Title = "MySQL Embedded Server Sample";
+ Application->CreateForm(__classid(TForm1), &Form1);
+ Application->Run();
+ }
+ catch (Exception &exception)
+ {
+ Application->ShowException(&exception);
+ }
+ return 0;
+}
+//---------------------------------------------------------------------------
diff --git a/libmysqld/examples/builder-sample/emb_sample.tds b/libmysqld/examples/builder-sample/emb_sample.tds
new file mode 100644
index 00000000000..2471b6c112f
--- /dev/null
+++ b/libmysqld/examples/builder-sample/emb_sample.tds
Binary files differ
diff --git a/libmysqld/examples/builder-sample/emb_samples.cpp b/libmysqld/examples/builder-sample/emb_samples.cpp
new file mode 100644
index 00000000000..4dfde111f84
--- /dev/null
+++ b/libmysqld/examples/builder-sample/emb_samples.cpp
@@ -0,0 +1,283 @@
+//---------------------------------------------------------------------------
+#include <vcl.h>
+#pragma hdrstop
+
+#include "emb_samples.h"
+#include <winsock.h>
+#include <mysql.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <deque.h>
+bool b_new_line = false;
+const char *server_groups[] = {
+ "", "embedded", "server", NULL
+};
+MYSQL *MySQL;
+deque<string> fill_rows(MYSQL_RES *res);
+//---------------------------------------------------------------------------
+#pragma package(smart_init)
+#pragma resource "*.dfm"
+TForm1 *Form1;
+//---------------------------------------------------------------------------
+deque<string> fill_rows(MYSQL_RES *res)
+{
+ MYSQL_ROW row;
+ deque<string> rows;
+
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+ for (unsigned int i=0 ; i < mysql_num_fields(res); i++)
+ rows.push_back(row[i]);
+ }
+ return rows;
+}
+//---------------------------------------------------------------------------
+__fastcall TForm1::TForm1(TComponent* Owner)
+ : TForm(Owner)
+{
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::Timer1Timer(TObject *Sender)
+{
+ if (is_server_started)
+ {
+ ToggleButton->Caption = "Quit";
+ Timer1->Enabled = false;
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::FormCreate(TObject *Sender)
+{
+ is_server_started = false;
+ computer_ip(); /* get the computer name and IP number */
+ /* init the tree database screen */
+ db_root = DBView->Items->Add(NULL, db_root_caption.UpperCase());
+ db_root->ImageIndex = 0;
+}
+//---------------------------------------------------------------------------
+/* button which handle the init of mysql server or quit the app */
+void __fastcall TForm1::ToggleButtonClick(TObject *Sender)
+{
+ if (!is_server_started)
+ {
+ mysql_server_init(NULL, NULL, (char **)server_groups) ;
+ connect_server();
+ get_dbs();
+ }
+ else
+ {
+ mysql_server_end();
+ Close();
+ }
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::computer_ip(void)
+{
+ WORD wVersionRequested;
+ WSADATA WSAData;
+ wVersionRequested = MAKEWORD(1,1);
+ WSAStartup(wVersionRequested,&WSAData);
+ hostent *P;
+ char s[128];
+ in_addr in;
+ char *P2;
+
+ gethostname(s, 128);
+ P = gethostbyname(s);
+ db_root_caption = P->h_name;
+ in.S_un.S_un_b.s_b1 = P->h_addr_list[0][0];
+ in.S_un.S_un_b.s_b2 = P->h_addr_list[0][1];
+ in.S_un.S_un_b.s_b3 = P->h_addr_list[0][2];
+ in.S_un.S_un_b.s_b4 = P->h_addr_list[0][3];
+ P2 = inet_ntoa(in);
+ db_root_caption += " ( " + (AnsiString)P2 + " )";
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::connect_server()
+{
+ bool ret_value = false;
+
+ MySQL = mysql_init(MySQL);
+ if (!MySQL)
+ return ret_value;
+ if (mysql_real_connect(MySQL, NULL, NULL, NULL, NULL, 0, NULL, 0))
+ {
+ ret_value = true;
+ is_server_started = true;
+ }
+ return ret_value;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::FormDestroy(TObject *Sender)
+{
+ if (is_server_started)
+ mysql_server_end();
+}
+//---------------------------------------------------------------------------
+
+void __fastcall TForm1::DBViewClick(TObject *Sender)
+{
+ if (DBView->Selected != db_root && DBView->Selected != NULL)
+ {
+ get_tables(DBView->Selected->Text);
+ clean_desc_grid();
+ }
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::get_tables(String db_name)
+{
+ MYSQL_RES *res;
+ AnsiString s_cmd;
+
+ TableView->Items->Clear();
+ s_cmd = "use ";
+ s_cmd+= db_name.c_str();
+
+ if (mysql_query(MySQL, s_cmd.c_str()) ||
+ !(res=mysql_list_tables(MySQL,"%")))
+ return false;
+
+ tables_node = TableView->Items->Add(NULL, db_name.c_str());
+ tables_node->ImageIndex = 1;
+ tables_node->SelectedIndex = 1;
+
+ deque<string> rows = fill_rows(res);
+
+ mysql_free_result(res);
+ fill_tree(rows,tables_tree,tables_node,TableView,2);
+
+ return true;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::get_dbs(void)
+{
+ MYSQL_RES *res;
+
+ if (!is_server_started)
+ return false;
+
+ if (!(res=mysql_list_dbs(MySQL,"%")))
+ return false;
+
+ deque<string> rows = fill_rows(res);
+
+ mysql_free_result(res);
+ fill_tree(rows,MySQLDbs,db_root,DBView,1);
+ info_server->Text = mysql_get_server_info(MySQL);
+
+ return true;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::fill_tree(deque<string> rows,
+ TTreeNode *root,
+ TTreeNode *child,
+ TTreeView *View,
+ int image_index)
+{
+ deque<string>::iterator r;
+ for(r = rows.begin(); r != rows.end() ; r++)
+ {
+ root = View->Items->AddChild(child, (*r).c_str());
+ root->ImageIndex = image_index;
+ root->SelectedIndex = image_index;
+ }
+ child->Expanded = true;
+}
+//---------------------------------------------------------------------------
+bool __fastcall TForm1::get_desc_table(String table_name)
+{
+ MYSQL_RES *res, *res1;
+ MYSQL_ROW row;
+ AnsiString use_db, show_cols, show_desc;
+ unsigned int num_fields;
+ int fields_control = 0, grid_row = 1, fields_number;
+ b_new_line= true;
+
+ clean_desc_grid();
+ use_db = "use ";
+ use_db+= DBView->Selected->Text.c_str();
+ show_desc = "desc ";
+ show_cols = "show full columns from ";
+ show_cols+= table_name.c_str();
+ show_desc+= table_name.c_str();
+
+ if (mysql_query(MySQL, use_db.c_str() ))
+ return false;
+
+ if (mysql_query(MySQL, show_cols.c_str() ) ||
+ !(res1=mysql_store_result(MySQL)))
+ {
+ if (mysql_query(MySQL, show_desc.c_str() ) ||
+ !(res1=mysql_store_result(MySQL)))
+ return false ;
+ }
+ mysql_fetch_row(res1);
+ mysql_field_seek(res1,0);
+ fields_number = (mysql_num_fields(res1) - 2);
+ mysql_free_result(res1);
+
+ if (mysql_query(MySQL, show_cols.c_str() ) ||
+ !(res=mysql_store_result(MySQL)))
+ {
+ if (mysql_query(MySQL, show_desc.c_str() ) ||
+ !(res=mysql_store_result(MySQL)))
+ return false ;
+ }
+ titles_grid();
+ while ((row=mysql_fetch_row(res)) != 0)
+ {
+ mysql_field_seek(res,0);
+ for (num_fields=0 ; num_fields < mysql_num_fields(res); num_fields++)
+ {
+ if (fields_control <= fields_number )
+ {
+ desc_table_grid->Cells[fields_control][grid_row] = row[num_fields];
+ fields_control++;
+ }
+ else
+ {
+ desc_table_grid->Cells[(fields_control)][grid_row] = row[num_fields];
+ fields_control = 0;
+ grid_row++ ;
+ desc_table_grid->RowCount++;
+ }
+ }
+ }
+ desc_table_grid->RowCount--;
+ mysql_free_result(res);
+ return true;
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::TableViewClick(TObject *Sender)
+{
+ if (DBView->Selected != db_root && DBView->Selected != NULL)
+ if (DBView->Selected != tables_tree)
+ get_desc_table(TableView->Selected->Text);
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::clean_desc_grid(void)
+{
+ desc_table_grid->RowCount= 2;
+ desc_table_grid->Cells[0][1] = "";
+ desc_table_grid->Cells[1][1] = "";
+ desc_table_grid->Cells[2][1] = "";
+ desc_table_grid->Cells[3][1] = "";
+ desc_table_grid->Cells[4][1] = "";
+ desc_table_grid->Cells[5][1] = "";
+}
+//---------------------------------------------------------------------------
+void __fastcall TForm1::titles_grid(void)
+{
+ desc_table_grid->Cells[0][0] = "Field";
+ desc_table_grid->Cells[1][0] = "Type";
+ desc_table_grid->Cells[2][0] = "Null";
+ desc_table_grid->Cells[3][0] = "Key";
+ desc_table_grid->Cells[4][0] = "Default";
+ desc_table_grid->Cells[5][0] = "Extra";
+ desc_table_grid->Cells[6][0] = "Privileges";
+}
+
diff --git a/libmysqld/examples/builder-sample/emb_samples.dfm b/libmysqld/examples/builder-sample/emb_samples.dfm
new file mode 100644
index 00000000000..399509eeb8e
--- /dev/null
+++ b/libmysqld/examples/builder-sample/emb_samples.dfm
Binary files differ
diff --git a/libmysqld/examples/builder-sample/emb_samples.h b/libmysqld/examples/builder-sample/emb_samples.h
new file mode 100644
index 00000000000..0562bc783cd
--- /dev/null
+++ b/libmysqld/examples/builder-sample/emb_samples.h
@@ -0,0 +1,61 @@
+//---------------------------------------------------------------------------
+#ifndef emb_samplesH
+#define emb_samplesH
+//---------------------------------------------------------------------------
+#include <Classes.hpp>
+#include <Controls.hpp>
+#include <StdCtrls.hpp>
+#include <Forms.hpp>
+#include <ComCtrls.hpp>
+#include <Grids.hpp>
+#include <ImgList.hpp>
+#include <ExtCtrls.hpp>
+#include <Graphics.hpp>
+#include <Buttons.hpp>
+#include <deque.h>
+//---------------------------------------------------------------------------
+class TForm1 : public TForm
+{
+__published: // IDE-managed Components
+ TGroupBox *GroupBox1;
+ TTreeView *DBView;
+ TTreeView *TableView;
+ TStringGrid *desc_table_grid;
+ TImageList *ImageList2;
+ TStatusBar *StatusBar1;
+ TImage *Image1;
+ TBitBtn *ToggleButton;
+ TTimer *Timer1;
+ TLabel *Label1;
+ TEdit *info_server;
+ TLabel *Label2;
+ void __fastcall Timer1Timer(TObject *Sender);
+ void __fastcall FormCreate(TObject *Sender);
+ void __fastcall ToggleButtonClick(TObject *Sender);
+ void __fastcall FormDestroy(TObject *Sender);
+ void __fastcall DBViewClick(TObject *Sender);
+ void __fastcall TableViewClick(TObject *Sender);
+private: // User declarations
+public: // User declarations
+ bool is_server_started;
+ AnsiString db_root_caption;
+ TTreeNode *db_root, *MySQLDbs, *tables_node, *tables_tree;
+ void __fastcall computer_ip(void);
+ bool __fastcall get_dbs(void);
+ bool __fastcall get_tables(String db_name);
+ bool __fastcall get_desc_table(String table_name);
+ bool __fastcall connect_server();
+ void __fastcall clean_desc_grid(void);
+ void __fastcall titles_grid(void);
+ void __fastcall fill_tree(deque<string> rows,
+ TTreeNode *root,
+ TTreeNode *child,
+ TTreeView *View,
+ int image_index);
+
+ __fastcall TForm1(TComponent* Owner);
+};
+//---------------------------------------------------------------------------
+extern PACKAGE TForm1 *Form1;
+//---------------------------------------------------------------------------
+#endif
diff --git a/libmysqld/examples/builder-sample/images/db.ico b/libmysqld/examples/builder-sample/images/db.ico
new file mode 100644
index 00000000000..ca749002acc
--- /dev/null
+++ b/libmysqld/examples/builder-sample/images/db.ico
Binary files differ
diff --git a/libmysqld/examples/builder-sample/images/find.ico b/libmysqld/examples/builder-sample/images/find.ico
new file mode 100644
index 00000000000..2e0f96c52f9
--- /dev/null
+++ b/libmysqld/examples/builder-sample/images/find.ico
Binary files differ
diff --git a/libmysqld/examples/builder-sample/images/logo.ico b/libmysqld/examples/builder-sample/images/logo.ico
new file mode 100644
index 00000000000..9409cad72b6
--- /dev/null
+++ b/libmysqld/examples/builder-sample/images/logo.ico
Binary files differ
diff --git a/libmysqld/examples/builder-sample/images/mysql.bmp b/libmysqld/examples/builder-sample/images/mysql.bmp
new file mode 100644
index 00000000000..ed5c7f9051f
--- /dev/null
+++ b/libmysqld/examples/builder-sample/images/mysql.bmp
Binary files differ
diff --git a/libmysqld/examples/builder-sample/images/net.ico b/libmysqld/examples/builder-sample/images/net.ico
new file mode 100644
index 00000000000..bb11e34bd1d
--- /dev/null
+++ b/libmysqld/examples/builder-sample/images/net.ico
Binary files differ
diff --git a/libmysqld/examples/builder-sample/libmysqld.lib b/libmysqld/examples/builder-sample/libmysqld.lib
new file mode 100644
index 00000000000..994e67e675e
--- /dev/null
+++ b/libmysqld/examples/builder-sample/libmysqld.lib
Binary files differ
diff --git a/libmysqld/examples/builder-sample/snapshot.jpg b/libmysqld/examples/builder-sample/snapshot.jpg
new file mode 100644
index 00000000000..b132fac8376
--- /dev/null
+++ b/libmysqld/examples/builder-sample/snapshot.jpg
Binary files differ
diff --git a/libmysqld/examples/test-run b/libmysqld/examples/test-run
new file mode 100755
index 00000000000..c7434488259
--- /dev/null
+++ b/libmysqld/examples/test-run
@@ -0,0 +1,138 @@
+#! /bin/sh
+
+# This is slapped together as a quick way to run the tests and
+# is not meant for prime time. Please hack at it and submit
+# changes, though, so we can gradually turn it into something
+# that will run on all platforms (or incorporate it into the
+# standard mysql-test-run).
+
+# All paths below must be relative to $test_data_dir
+top_builddir=../..
+mysql_test_dir=$top_builddir/mysql-test
+examples=$top_builddir/libmysqld/examples
+mysqltest=$examples/mysqltest
+datadir=$mysql_test_dir/var/master-data
+test_data_dir=test
+gdb=0
+list=0
+run=
+tests=
+start=
+clean=1
+
+cr="
+"
+er="\b\b\b\b\b\b\b\b"
+
+usage () {
+ cat <<EOF
+usage: $0 [-g|-h|-r] [test-name ...]
+
+ -C | --noclean Do not remove old innodb and bdb files at start.
+ -g | --gdb run $mysqltest in gdb
+ -h | --help show this help
+ -l | --list ) list all available tests
+ -r | --run automatically 'run' program in gdb
+ -s t | --start=t start with test t (skip all tests before t)
+EOF
+}
+
+init_args="--server-arg=--language=$top_builddir/sql/share/english"
+while test $# -gt 0
+do
+ arg=
+ argset=0
+ case "$1" in
+ --?*=* ) arg=`echo "$1" | sed -e 's,^[^=][^=]*=,,'`; argset=1 ;;
+ esac
+
+ case "$1" in
+ -g | --gdb ) gdb=1; shift;;
+ -h | --help | -\? ) usage; exit 0;;
+ -l | --list ) list=1 ; shift ;;
+ -r | --run ) run="${cr}run"; shift;;
+ --debug) init_args="$init_args --debug" ; shift ;;
+ -C | --noclean) clean=0 ; shift ;;
+ -s | --start=* )
+ test $argset -eq 0 && { shift; arg="$1"; }
+ start="$arg"
+ shift
+ ;;
+ -* ) usage; exit 1;;
+ * ) tests="$tests $1"; shift;;
+ esac
+done
+
+if test ! -d "$datadir/$test_data_dir"
+then
+ echo "bad setup (is '$datadir/$test_data_dir'', missing ?)" >&2
+ exit 1
+fi
+
+test -n "$tests" ||
+ tests=`/bin/ls -1 "$mysql_test_dir"/t/*.test | grep -v '^.*/rpl[^/]*$' | \
+ sed -e 's,^.*/,,' -e 's,.test$,,'`
+
+echo "cleaning data directory '$datadir/$test_data_dir'"
+if test $clean = 1
+then
+ rm -f $datadir/ib_* $datadir/ibdata*
+ rm -f $datadir/log.00*
+ rm -f $datadir/test/*.db
+fi
+rm -f $datadir/../tmp/*
+rm -f test-gdbinit
+
+TZ=GMT-3; export TZ
+
+# At least one of the tests needs the following environment variable
+MYSQL_TEST_DIR=`( cd $mysql_test_dir ; pwd )` ; export MYSQL_TEST_DIR
+
+skip=1
+test -z "$start" && skip=0
+
+for b in $tests
+do
+ test $list -eq 1 && { echo " $b"; continue; }
+ test $skip -eq 1 && test -n "$start" && test "$start" = "$b" && skip=0
+ test $skip -eq 1 && { echo "skipping '$b'"; continue; }
+
+ t="t/$b.test"
+ r="r/$b.result"
+
+ # Only test if $t exists; there is no $r for some tests
+ test -f $mysql_test_dir/$t || {
+ echo "test '$mysql_test_dir/$t' doesn't exist" >&2
+ continue
+ }
+ args="$init_args -v --basedir=$mysql_test_dir/ -R $r -x $t --server-arg=--datadir=$datadir"
+ if test -f "$mysql_test_dir/t/$b-master.opt" ; then
+ args="$args --server-file=t/$b-master.opt"
+ fi
+
+ args="$args $test_data_dir" # Add database last
+ echo "set args $args$run" > test-gdbinit
+ #if false && test -n "$run"
+ if test -n "$run" -o $gdb -eq 1
+ then
+ echo -e "$er>>> $b"
+ else
+ echo -e "$er>>> $b> \c"
+ read junk
+ fi
+ if test $gdb -eq 1
+ then
+ if [ -x "$top_builddir/libtool" ]; then
+ $top_builddir/libtool gdb -x test-gdbinit -q $mysqltest
+ else
+ gdb -x test-gdbinit -q $mysqltest
+ fi
+ res=$?
+ rm -f test-gdbinit
+ else
+ $mysqltest $args
+ res=$?
+ fi
+
+ test $res -eq 0 -o $res -eq 2 || echo "!!! error: $res"
+done
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
new file mode 100644
index 00000000000..2c54603ea7a
--- /dev/null
+++ b/libmysqld/lib_sql.cc
@@ -0,0 +1,663 @@
+/*
+ * Copyright (c) 2000
+ * SWsoft company
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+
+ This code was modified by the MySQL team
+*/
+
+/*
+ The following is needed to not cause conflicts when we include mysqld.cc
+*/
+
+#define main main1
+#define mysql_unix_port mysql_inix_port1
+#define mysql_port mysql_port1
+
+#if defined (__WIN__)
+#include "../sql/mysqld.cpp"
+#else
+#include "../sql/mysqld.cc"
+#endif
+
+#define SCRAMBLE_LENGTH 8
+C_MODE_START
+#include "lib_vio.c"
+
+static int check_connections1(THD * thd);
+static int check_connections2(THD * thd);
+static bool check_user(THD *thd, enum_server_command command,
+ const char *user, const char *passwd, const char *db,
+ bool check_count);
+char * get_mysql_home(){ return mysql_home;};
+char * get_mysql_real_data_home(){ return mysql_real_data_home;};
+
+bool lib_dispatch_command(enum enum_server_command command, NET *net,
+ const char *arg, ulong length)
+{
+ THD *thd=(THD *) net->vio->dest_thd;
+ thd->store_globals(); // Fix if more than one connect
+ thd->net.last_error[0]=0; // Clear error message
+ thd->net.last_errno=0;
+
+ net_new_transaction(&thd->net);
+ return dispatch_command(command, thd, (char *) arg, length + 1);
+}
+
+
+void lib_connection_phase(NET * net, int phase)
+{
+ THD * thd;
+ thd = (THD *)(net->vio->dest_thd);
+ if (thd)
+ {
+ switch (phase)
+ {
+ case 2:
+ check_connections2(thd);
+ break;
+ }
+ }
+}
+C_MODE_END
+
+
+void start_embedded_conn1(NET * net)
+{
+ THD * thd = new THD;
+ my_net_init(&thd->net,NULL);
+ /* if (protocol_version>9) */
+ thd->net.return_errno=1;
+ thd->thread_id = thread_id++;
+
+ Vio * v = net->vio;
+ if (!v)
+ {
+ v = vio_new(0,VIO_CLOSED,0);
+ net->vio = v;
+ }
+ if (v)
+ {
+ v -> dest_thd = thd;
+ }
+ thd->net.vio = v;
+ if (thd->store_globals())
+ {
+ fprintf(stderr,"store_globals failed.\n");
+ return;
+ }
+
+ thd->mysys_var=my_thread_var;
+ thd->dbug_thread_id=my_thread_id();
+ thd->thread_stack= (char*) &thd;
+
+ if (thd->variables.max_join_size == (ulong) HA_POS_ERROR)
+ thd->options |= OPTION_BIG_SELECTS;
+
+ thd->proc_info=0; // Remove 'login'
+ thd->command=COM_SLEEP;
+ thd->version=refresh_version;
+ thd->set_time();
+ bzero(thd->scramble, sizeof(thd->scramble));
+ init_sql_alloc(&thd->mem_root,8192,8192);
+
+ check_connections1(thd);
+}
+
+
+
+
+static int
+check_connections1(THD *thd)
+{
+ uint connect_errors=0;
+ NET *net= &thd->net;
+ /*
+ ** store the connection details
+ */
+ DBUG_PRINT("info", (("check_connections called by thread %d"),
+ thd->thread_id));
+ DBUG_PRINT("general",("New connection received on %s",
+ vio_description(net->vio)));
+ if (!thd->host) // If TCP/IP connection
+ {
+ thd->host=(char*) localhost;
+ }
+ else /* Hostname given means that the connection was on a socket */
+ {
+ DBUG_PRINT("general",("Host: %s",thd->host));
+ thd->ip=0;
+ bzero((char*) &thd->remote,sizeof(struct sockaddr));
+ }
+ //vio_keepalive(net->vio, TRUE);
+
+ /* nasty, but any other way? */
+ uint pkt_len = 0;
+
+ char buff[80],*end;
+ int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
+ CLIENT_TRANSACTIONS;
+ LINT_INIT(pkt_len);
+
+ end=strmov(buff,server_version)+1;
+ int4store((uchar*) end,thd->thread_id);
+ end+=4;
+ memcpy(end,thd->scramble,SCRAMBLE_LENGTH+1);
+ end+=SCRAMBLE_LENGTH +1;
+ int2store(end,client_flags);
+ end[2]=MY_CHARSET_CURRENT;
+
+#define MIN_HANDSHAKE_SIZE 6
+
+ int2store(end+3,thd->server_status);
+ bzero(end+5,13);
+ end+=18;
+ if (net_write_command(net,protocol_version, buff,
+ (uint) (end-buff)))
+ {
+ inc_host_errors(&thd->remote.sin_addr);
+ return(ER_HANDSHAKE_ERROR);
+ }
+ return 0;
+}
+
+static int
+check_connections2(THD * thd)
+{
+ uint connect_errors=0;
+ uint pkt_len = 0;
+ NET * net = &thd -> net;
+ if (protocol_version>9) net -> return_errno=1;
+
+ if ( (pkt_len=my_net_read(net)) == packet_error ||
+ pkt_len < MIN_HANDSHAKE_SIZE)
+ {
+ inc_host_errors(&thd->remote.sin_addr);
+ return(ER_HANDSHAKE_ERROR);
+ }
+
+#ifdef _CUSTOMCONFIG_
+#include "_cust_sql_parse.h"
+#endif
+ if (connect_errors)
+ reset_host_errors(&thd->remote.sin_addr);
+ if (thd->packet.alloc(thd->variables.net_buffer_length))
+ return(ER_OUT_OF_RESOURCES);
+
+ thd->client_capabilities=uint2korr(net->read_pos);
+
+ thd->max_client_packet_length=uint3korr(net->read_pos+2);
+ char *user= (char*) net->read_pos+5;
+ char *passwd= strend(user)+1;
+ char *db=0;
+ if (passwd[0] && strlen(passwd) != SCRAMBLE_LENGTH)
+ return ER_HANDSHAKE_ERROR;
+ if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
+ db=strend(passwd)+1;
+ if (thd->client_capabilities & CLIENT_TRANSACTIONS)
+ thd->net.return_status= &thd->server_status;
+ net->read_timeout=thd->variables.net_read_timeout;
+ if (check_user(thd,COM_CONNECT, user, passwd, db, 1))
+ return (-1);
+ thd->password=test(passwd[0]);
+ return 0;
+}
+
+static bool check_user(THD *thd,enum_server_command command, const char *user,
+ const char *passwd, const char *db, bool check_count)
+{
+ NET *net= &thd->net;
+ USER_RESOURCES ur;
+ thd->db=0;
+
+ if (!(thd->user = my_strdup(user, MYF(0))))
+ {
+ send_error(net,ER_OUT_OF_RESOURCES);
+ return 1;
+ }
+ strmake(thd->priv_host, LOCAL_HOST, sizeof(thd->priv_host)-1);
+ thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user,
+ passwd, thd->scramble,
+ &thd->priv_user, thd->priv_host,
+ protocol_version == 9 ||
+ !(thd->client_capabilities &
+ CLIENT_LONG_PASSWORD),&ur);
+ DBUG_PRINT("info",
+ ("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
+ thd->client_capabilities, thd->max_client_packet_length,
+ thd->host_or_ip, thd->priv_user,
+ passwd[0] ? "yes": "no",
+ thd->master_access, thd->db ? thd->db : "*none*"));
+ if (thd->master_access & NO_ACCESS)
+ {
+ net_printf(net, ER_ACCESS_DENIED_ERROR,
+ thd->user,
+ thd->host_or_ip,
+ passwd[0] ? ER(ER_YES) : ER(ER_NO));
+ mysql_log.write(thd,COM_CONNECT,ER(ER_ACCESS_DENIED_ERROR),
+ thd->user,
+ thd->host_or_ip,
+ passwd[0] ? ER(ER_YES) : ER(ER_NO));
+ return(1); // Error already given
+ }
+ if (check_count)
+ {
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ bool tmp=(thread_count - delayed_insert_threads >= max_connections &&
+ !(thd->master_access & PROCESS_ACL));
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ if (tmp)
+ { // Too many connections
+ send_error(net, ER_CON_COUNT_ERROR);
+ return(1);
+ }
+ }
+ mysql_log.write(thd,command,
+ (thd->priv_user == thd->user ?
+ (char*) "%s@%s on %s" :
+ (char*) "%s@%s as anonymous on %s"),
+ user,
+ thd->host_or_ip,
+ db ? db : (char*) "");
+ thd->db_access=0;
+ if (db && db[0])
+ return test(mysql_change_db(thd,db));
+ else
+ send_ok(net); // Ready to handle questions
+ return 0; // ok
+}
+
+
+void THD::clear_error()
+{
+ net.last_error[0]= 0;
+ net.last_errno= 0;
+}
+
+/*
+ Make a copy of array and the strings array points to
+*/
+
+char **copy_arguments(int argc, char **argv)
+{
+ uint length= 0;
+ char **from, **res, **end= argv+argc;
+
+ for (from=argv ; from != end ; from++)
+ length+= strlen(*from);
+
+ if ((res= (char**) my_malloc(sizeof(argv)*(argc+1)+length+argc,
+ MYF(MY_WME))))
+ {
+ char **to= res, *to_str= (char*) (res+argc+1);
+ for (from=argv ; from != end ;)
+ {
+ *to++= to_str;
+ to_str= strmov(to_str, *from++)+1;
+ }
+ *to= 0; // Last ptr should be null
+ }
+ return res;
+}
+
+
+extern "C"
+{
+
+static my_bool org_my_init_done;
+my_bool server_inited;
+ulong max_allowed_packet, net_buffer_length;
+char ** copy_arguments_ptr= 0;
+
+int STDCALL mysql_server_init(int argc, char **argv, char **groups)
+{
+ char glob_hostname[FN_REFLEN];
+
+ /* This mess is to allow people to call the init function without
+ * having to mess with a fake argv */
+ int *argcp;
+ char ***argvp;
+ int fake_argc = 1;
+ char *fake_argv[] = { (char *)"", 0 };
+ const char *fake_groups[] = { "server", "embedded", 0 };
+ if (argc)
+ {
+ argcp = &argc;
+ argvp = (char***) &argv;
+ }
+ else
+ {
+ argcp = &fake_argc;
+ argvp = (char ***) &fake_argv;
+ }
+ if (!groups)
+ groups = (char**) fake_groups;
+
+ my_umask=0660; // Default umask for new files
+ my_umask_dir=0700; // Default umask for new directories
+
+ /* Only call MY_INIT() if it hasn't been called before */
+ if (!server_inited)
+ {
+ server_inited=1;
+ org_my_init_done=my_init_done;
+ }
+ if (!org_my_init_done)
+ {
+ MY_INIT((char *)"mysql_embedded"); // init my_sys library & pthreads
+ }
+
+ /*
+ Make a copy of the arguments to guard against applications that
+ may change or move the initial arguments.
+ */
+ if (argvp == &argv)
+ if (!(copy_arguments_ptr= argv= copy_arguments(argc, argv)))
+ return 1;
+
+ tzset(); // Set tzname
+
+ start_time=time((time_t*) 0);
+#ifdef HAVE_TZNAME
+#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
+ {
+ struct tm tm_tmp;
+ localtime_r(&start_time,&tm_tmp);
+ strmov(time_zone,tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]);
+ }
+#else
+ {
+ struct tm *start_tm;
+ start_tm=localtime(&start_time);
+ strmov(time_zone,tzname[start_tm->tm_isdst != 0 ? 1 : 0]);
+ }
+#endif
+#endif
+
+ if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
+ strmov(glob_hostname,"mysql");
+#ifndef DBUG_OFF
+ strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS);
+#else
+ strmov(strend(server_version),MYSQL_SERVER_SUFFIX);
+#endif
+ load_defaults("my", (const char **) groups, argcp, argvp);
+ defaults_argv=*argvp;
+
+ /* Get default temporary directory */
+ opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
+#if defined( __WIN__) || defined(OS2)
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TEMP");
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TMP");
+#endif
+ if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
+ opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
+
+ set_options();
+ get_options(*argcp, *argvp);
+
+ if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
+ strcat(server_version,"-log");
+ DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
+ server_version, SYSTEM_TYPE,MACHINE_TYPE));
+
+ if (opt_error_log)
+ {
+ if (!log_error_file_ptr[0])
+ fn_format(log_error_file, glob_hostname, mysql_data_home, ".err", 0);
+ else
+ fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
+ MY_UNPACK_FILENAME | MY_SAFE_PATH);
+ if (!log_error_file[0])
+ opt_error_log= 1; // Too long file name
+ else
+ {
+ freopen(log_error_file, "a+", stderr);
+ }
+ }
+
+ /* These must be set early */
+
+ (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
+ (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
+ (void) pthread_mutex_init(&LOCK_grant,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_open,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
+ (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW);
+ (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
+ (void) pthread_cond_init(&COND_thread_count,NULL);
+ (void) pthread_cond_init(&COND_refresh,NULL);
+ (void) pthread_cond_init(&COND_thread_cache,NULL);
+ (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
+ (void) pthread_cond_init(&COND_manager,NULL);
+ (void) pthread_cond_init(&COND_rpl_status, NULL);
+
+ if (set_default_charset_by_name(sys_charset.value, MYF(MY_WME)))
+ {
+ mysql_server_end();
+ return 1;
+ }
+ charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS));
+
+ /* Parameter for threads created for connections */
+ (void) pthread_attr_init(&connection_attrib);
+ (void) pthread_attr_setdetachstate(&connection_attrib,
+ PTHREAD_CREATE_DETACHED);
+ pthread_attr_setstacksize(&connection_attrib,thread_stack);
+ pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
+
+#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
+ /* connections and databases needs lots of files */
+ {
+ uint wanted_files=10+(uint) max(max_connections*5,
+ max_connections+table_cache_size*2);
+ set_if_bigger(wanted_files, open_files_limit);
+ // Note that some system returns 0 if we succeed here:
+ uint files=set_maximum_open_files(wanted_files);
+ if (files && files < wanted_files && ! open_files_limit)
+ {
+ max_connections= (ulong) min((files-10),max_connections);
+ table_cache_size= (ulong) max((files-10-max_connections)/2,64);
+ DBUG_PRINT("warning",
+ ("Changed limits: max_connections: %ld table_cache: %ld",
+ max_connections,table_cache_size));
+ sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size);
+ }
+ }
+#endif
+ unireg_init(opt_specialflag); /* Set up extern variabels */
+ init_errmessage(); /* Read error messages from file */
+ lex_init();
+ item_init();
+ set_var_init();
+ mysys_uses_curses=0;
+#ifdef USE_REGEX
+ regex_init();
+#endif
+ if (use_temp_pool && bitmap_init(&temp_pool,1024,1))
+ {
+ mysql_server_end();
+ return 1;
+ }
+
+ /*
+ We have enough space for fiddling with the argv, continue
+ */
+ umask(((~my_umask) & 0666));
+ table_cache_init();
+ hostname_cache_init();
+ query_cache_result_size_limit(query_cache_limit);
+ query_cache_resize(query_cache_size);
+ randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
+ reset_floating_point_exceptions();
+ init_thr_lock();
+ init_slave_list();
+
+ /* Setup log files */
+ if (opt_log)
+ open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS,
+ LOG_NORMAL, 0, 0, 0);
+ if (opt_update_log)
+ {
+ open_log(&mysql_update_log, glob_hostname, opt_update_logname, "",
+ NullS, LOG_NEW, 0, 0, 0);
+ using_update_log=1;
+ }
+
+ if (opt_slow_log)
+ open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
+ NullS, LOG_NORMAL, 0, 0, 0);
+ if (ha_init())
+ {
+ sql_print_error("Can't init databases");
+ exit(1);
+ }
+ ha_key_cache();
+#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
+ if (locked_in_memory && !geteuid())
+ {
+ if (mlockall(MCL_CURRENT))
+ {
+ sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno);
+ }
+ else
+ locked_in_memory=1;
+ }
+#else
+ locked_in_memory=0;
+#endif
+
+ if (opt_myisam_log)
+ (void) mi_log( 1 );
+ ft_init_stopwords();
+
+ /*
+ init signals & alarm
+ After this we can't quit by a simple unireg_abort
+ */
+ error_handler_hook = my_message_sql;
+ if (pthread_key_create(&THR_THD,NULL) || pthread_key_create(&THR_NET,NULL) ||
+ pthread_key_create(&THR_MALLOC,NULL))
+ {
+ sql_print_error("Can't create thread-keys");
+ exit(1);
+ }
+ opt_noacl = 1; // No permissions
+ if (acl_init((THD*) 0,opt_noacl))
+ {
+ mysql_server_end();
+ return 1;
+ }
+ if (!opt_noacl)
+ (void) grant_init((THD*) 0);
+ init_max_user_conn();
+ init_update_queries();
+
+#ifdef HAVE_DLOPEN
+ if (!opt_noacl)
+ udf_init();
+#endif
+
+ if (opt_bin_log)
+ {
+ if (!opt_bin_logname)
+ {
+ char tmp[FN_REFLEN];
+ /* TODO: The following should be using fn_format(); We just need to
+ first change fn_format() to cut the file name if it's too long.
+ */
+ strmake(tmp,glob_hostname,FN_REFLEN-5);
+ strmov(strcend(tmp,'.'),"-bin");
+ opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
+ }
+ open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
+ opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size);
+ using_update_log=1;
+ }
+
+ (void) thr_setconcurrency(concurrency); // 10 by default
+
+ if (
+#ifdef HAVE_BERKELEY_DB
+ !berkeley_skip ||
+#endif
+ (flush_time && flush_time != ~(ulong) 0L))
+ {
+ pthread_t hThread;
+ if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
+ sql_print_error("Warning: Can't create thread to manage maintenance");
+ }
+
+ /*
+ Update mysqld variables from client variables if set
+ The client variables are set also by get_one_option() in mysqld.cc
+ */
+ if (max_allowed_packet)
+ global_system_variables.max_allowed_packet= max_allowed_packet;
+ if (net_buffer_length)
+ global_system_variables.net_buffer_length= net_buffer_length;
+ return 0;
+}
+
+
+void STDCALL mysql_server_end()
+{
+ my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR));
+ copy_arguments_ptr=0;
+ clean_up(0);
+ /* If library called my_init(), free memory allocated by it */
+ if (!org_my_init_done)
+ my_end(0);
+}
+
+my_bool STDCALL mysql_thread_init()
+{
+#ifdef THREAD
+ return my_thread_init();
+#else
+ return 0;
+#endif
+}
+
+void STDCALL mysql_thread_end()
+{
+#ifdef THREAD
+ my_thread_end();
+#endif
+}
+
+void start_embedded_connection(NET * net)
+{
+ start_embedded_conn1(net);
+}
+
+void end_embedded_connection(NET * net)
+{
+ THD *thd = (THD *) net->vio->dest_thd;
+ delete thd;
+}
+
+} /* extern "C" */
diff --git a/libmysqld/lib_vio.c b/libmysqld/lib_vio.c
new file mode 100644
index 00000000000..ccad6ac8b7e
--- /dev/null
+++ b/libmysqld/lib_vio.c
@@ -0,0 +1,226 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Note that we can't have assertion on file descriptors; The reason for
+ this is that during mysql shutdown, another thread can close a file
+ we are working on. In this case we should just return read errors from
+ the file descriptior.
+*/
+
+#include <my_global.h>
+#include "mysql_embed.h"
+#include "mysql.h"
+
+#ifndef HAVE_VIO /* is Vio enabled */
+
+#include <errno.h>
+#include <my_sys.h>
+#include <violite.h>
+#include <my_sys.h>
+#include <my_net.h>
+#include <m_string.h>
+#include <assert.h>
+
+#ifndef __WIN__
+#define HANDLE void *
+#endif
+
+struct st_vio
+{
+ my_socket sd; /* my_socket - real or imaginary */
+ HANDLE hPipe;
+ my_bool localhost; /* Are we from localhost? */
+ int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
+ struct sockaddr_in local; /* Local internet address */
+ struct sockaddr_in remote; /* Remote internet address */
+ enum enum_vio_type type; /* Type of connection */
+ char desc[30]; /* String description */
+ void *dest_thd;
+ char *packets, **last_packet;
+ char *where_in_packet, *end_of_packet;
+ my_bool reading;
+ MEM_ROOT root;
+};
+
+/* Initialize the communication buffer */
+
+Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
+{
+ DBUG_ENTER("vio_new");
+ Vio * vio;
+
+ if ((vio= (Vio *) my_malloc(sizeof(*vio),MYF(MY_WME|MY_ZEROFILL))))
+ {
+ init_alloc_root(&vio->root, 8192, 8192);
+ vio->root.min_malloc = sizeof(char *) + 4;
+ vio->last_packet = &vio->packets;
+ }
+ DBUG_RETURN(vio);
+}
+
+
+#ifdef __WIN__
+
+Vio *vio_new_win32pipe(HANDLE hPipe)
+{
+ return (NULL);
+}
+
+#endif
+
+void vio_delete(Vio * vio)
+{
+ DBUG_ENTER("vio_delete");
+ if (vio)
+ {
+ if (vio->type != VIO_CLOSED)
+ vio_close(vio);
+ free_root(&vio->root, MYF(0));
+ my_free((gptr) vio, MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
+
+void vio_reset(Vio *vio)
+{
+ DBUG_ENTER("vio_reset");
+ free_root(&vio->root, MYF(MY_KEEP_PREALLOC));
+ vio->packets = vio->where_in_packet = vio->end_of_packet = 0;
+ vio->last_packet = &vio->packets;
+ DBUG_VOID_RETURN;
+}
+
+int vio_errno(Vio *vio __attribute__((unused)))
+{
+ return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
+}
+
+int vio_read(Vio * vio, gptr buf, int size)
+{
+ vio->reading = 1;
+ if (vio->where_in_packet >= vio->end_of_packet)
+ {
+ DBUG_ASSERT(vio->packets);
+ vio->where_in_packet = vio->packets + sizeof(char *) + 4;
+ vio->end_of_packet = vio->where_in_packet +
+ uint4korr(vio->packets + sizeof(char *));
+ vio->packets = *(char **)vio->packets;
+ }
+ if (vio->where_in_packet + size > vio->end_of_packet)
+ size = vio->end_of_packet - vio->where_in_packet;
+ memcpy(buf, vio->where_in_packet, size);
+ vio->where_in_packet += size;
+ return (size);
+}
+
+int vio_write(Vio * vio, const gptr buf, int size)
+{
+ DBUG_ENTER("vio_write");
+ char *packet;
+ if (vio->reading)
+ {
+ vio->reading = 0;
+ vio_reset(vio);
+ }
+ if ((packet = alloc_root(&vio->root, sizeof(char*) + 4 + size)))
+ {
+ *vio->last_packet = packet;
+ vio->last_packet = (char **)packet;
+ *((char **)packet) = 0; /* Set forward link to 0 */
+ packet += sizeof(char *);
+ int4store(packet, size);
+ memcpy(packet + 4, buf, size);
+ }
+ else
+ size= -1;
+ DBUG_RETURN(size);
+}
+
+int vio_blocking(Vio * vio, my_bool set_blocking_mode, my_bool *old_mode)
+{
+ return (0);
+}
+
+my_bool
+vio_is_blocking(Vio * vio)
+{
+ return(0);
+}
+
+int vio_fastsend(Vio * vio)
+{
+ return(0);
+}
+
+int vio_keepalive(Vio* vio, my_bool set_keep_alive)
+{
+ return (0);
+}
+
+
+my_bool
+vio_should_retry(Vio * vio __attribute__((unused)))
+{
+ int en = socket_errno;
+ return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
+ en == SOCKET_EWOULDBLOCK);
+}
+
+
+int vio_close(Vio * vio)
+{
+ return(0);
+}
+
+
+const char *vio_description(Vio * vio)
+{
+ return "embedded vio";
+}
+
+enum enum_vio_type vio_type(Vio* vio)
+{
+ return VIO_CLOSED;
+}
+
+my_socket vio_fd(Vio* vio)
+{
+ return 0;
+}
+
+
+my_bool vio_peer_addr(Vio * vio, char *buf, uint16 *port)
+{
+ return(0);
+}
+
+
+void vio_in_addr(Vio *vio, struct in_addr *in)
+{
+}
+
+my_bool vio_poll_read(Vio *vio,uint timeout)
+{
+ return 0;
+}
+
+
+void vio_timeout(Vio *vio __attribute__((unused)),
+ uint timeout __attribute__((unused)))
+{
+}
+#endif /* HAVE_VIO */
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
new file mode 100644
index 00000000000..2e8cd2a4861
--- /dev/null
+++ b/libmysqld/libmysqld.c
@@ -0,0 +1,2103 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "embedded_priv.h"
+#include <my_sys.h>
+#include <mysys_err.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "errmsg.h"
+#include <violite.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <time.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#if !defined(MSDOS) && !defined(__WIN__)
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#ifdef HAVE_SELECT_H
+# include <select.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#endif
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif
+
+static my_bool mysql_client_init=0;
+uint mysql_port=0;
+my_string mysql_unix_port=0;
+
+#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS)
+
+#if defined(MSDOS) || defined(__WIN__)
+#define ERRNO WSAGetLastError()
+#define perror(A)
+#else
+#include <errno.h>
+#define ERRNO errno
+#define SOCKET_ERROR -1
+#define closesocket(A) close(A)
+#endif
+
+static void mysqld_once_init(void);
+static MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields,
+ uint field_count);
+static int read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
+ ulong *lengths);
+static void end_server(MYSQL *mysql);
+static void read_user_name(char *name);
+static void append_wild(char *to,char *end,const char *wild);
+static int send_file_to_server(MYSQL *mysql,const char *filename);
+static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
+ const char *from, ulong length);
+
+#define init_sigpipe_variables
+#define set_sigpipe(mysql)
+#define reset_sigpipe(mysql)
+
+/*****************************************************************************
+** read a packet from server. Give error message if socket was down
+** or packet is an error message
+*****************************************************************************/
+
+ulong
+net_safe_read(MYSQL *mysql)
+{
+ NET *net= &mysql->net;
+ uint len=0;
+ /* init_sigpipe_variables */
+ /* Don't give sigpipe errors if the client doesn't want them */
+ set_sigpipe(mysql);
+ if (net->vio != 0)
+ len=my_net_read(net);
+ reset_sigpipe(mysql);
+ if (len == packet_error || len == 0)
+ {
+ DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %d",
+ vio_description(net->vio),len));
+ end_server(mysql);
+ net->last_errno=(net->last_errno == ER_NET_PACKET_TOO_LARGE ?
+ CR_NET_PACKET_TOO_LARGE:
+ CR_SERVER_LOST);
+ strmov(net->last_error,ER(net->last_errno));
+ return(packet_error);
+ }
+ if (net->read_pos[0] == 255)
+ {
+
+ if (len > 3)
+ {
+ char *pos=(char*) net->read_pos+1;
+ if (mysql->protocol_version > 9)
+ { /* New client protocol */
+ net->last_errno=uint2korr(pos);
+ pos+=2;
+ len-=2;
+ }
+ else
+ {
+ net->last_errno=CR_UNKNOWN_ERROR;
+ len--;
+ }
+ (void) strmake(net->last_error,(char*) pos,
+ min(len,sizeof(net->last_error)-1));
+ }
+ else
+ {
+ net->last_errno=CR_UNKNOWN_ERROR;
+ (void) strmov(net->last_error,ER(net->last_errno));
+ }
+ DBUG_PRINT("error",("Got error: %d (%s)", net->last_errno,
+ net->last_error));
+ return(packet_error);
+ }
+ return len;
+}
+
+
+/* Get the length of next field. Change parameter to point at fieldstart */
+static ulong
+net_field_length(uchar **packet)
+{
+ reg1 uchar *pos= *packet;
+ if (*pos < 251)
+ {
+ (*packet)++;
+ return (ulong) *pos;
+ }
+ if (*pos == 251)
+ {
+ (*packet)++;
+ return NULL_LENGTH;
+ }
+ if (*pos == 252)
+ {
+ (*packet)+=3;
+ return (ulong) uint2korr(pos+1);
+ }
+ if (*pos == 253)
+ {
+ (*packet)+=4;
+ return (ulong) uint3korr(pos+1);
+ }
+ (*packet)+=9; /* Must be 254 when here */
+ return (ulong) uint4korr(pos+1);
+}
+
+/* Same as above, but returns ulonglong values */
+
+static my_ulonglong
+net_field_length_ll(uchar **packet)
+{
+ reg1 uchar *pos= *packet;
+ if (*pos < 251)
+ {
+ (*packet)++;
+ return (my_ulonglong) *pos;
+ }
+ if (*pos == 251)
+ {
+ (*packet)++;
+ return (my_ulonglong) NULL_LENGTH;
+ }
+ if (*pos == 252)
+ {
+ (*packet)+=3;
+ return (my_ulonglong) uint2korr(pos+1);
+ }
+ if (*pos == 253)
+ {
+ (*packet)+=4;
+ return (my_ulonglong) uint3korr(pos+1);
+ }
+ (*packet)+=9; /* Must be 254 when here */
+#ifdef NO_CLIENT_LONGLONG
+ return (my_ulonglong) uint4korr(pos+1);
+#else
+ return (my_ulonglong) uint8korr(pos+1);
+#endif
+}
+
+
+static void free_rows(MYSQL_DATA *cur)
+{
+ if (cur)
+ {
+ free_root(&cur->alloc,MYF(0));
+ my_free((gptr) cur,MYF(0));
+ }
+}
+
+
+int
+simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
+ ulong length, my_bool skipp_check)
+{
+ NET *net= &mysql->net;
+ int result= -1;
+
+ /* Check that we are calling the client functions in right order */
+ if (mysql->status != MYSQL_STATUS_READY)
+ {
+ strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
+ goto end;
+ }
+
+ /* Clear result variables */
+ mysql->net.last_error[0]=0;
+ mysql->net.last_errno=0;
+ mysql->info=0;
+ mysql->affected_rows= ~(my_ulonglong) 0;
+
+ /* Clear receive buffer and vio packet list */
+ net_clear(net);
+ vio_reset(net->vio);
+
+ result = lib_dispatch_command(command, net, arg,length);
+ if (!skipp_check)
+ result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ?
+ -1 : 0);
+ end:
+ return result;
+}
+
+
+static void free_old_query(MYSQL *mysql)
+{
+ DBUG_ENTER("free_old_query");
+ if (mysql->fields)
+ free_root(&mysql->field_alloc,MYF(0));
+ init_alloc_root(&mysql->field_alloc,8192,0); /* Assume rowlength < 8192 */
+ mysql->fields=0;
+ mysql->field_count=0; /* For API */
+ DBUG_VOID_RETURN;
+}
+
+#ifdef HAVE_GETPWUID
+struct passwd *getpwuid(uid_t);
+char* getlogin(void);
+#endif
+
+#if !defined(MSDOS) && ! defined(VMS) && !defined(__WIN__)
+static void read_user_name(char *name)
+{
+ DBUG_ENTER("read_user_name");
+ if (geteuid() == 0)
+ (void) strmov(name,"root"); /* allow use of surun */
+ else
+ {
+#ifdef HAVE_GETPWUID
+ struct passwd *skr;
+ const char *str;
+/*#ifdef __cplusplus
+ extern "C" struct passwd *getpwuid(uid_t);
+ extern "C" { char* getlogin(void); }
+#else
+ char * getlogin();
+ struct passwd *getpwuid(uid_t);
+#endif
+*/
+ if ((str=getlogin()) == NULL)
+ {
+ if ((skr=getpwuid(geteuid())) != NULL)
+ str=skr->pw_name;
+ else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) &&
+ !(str=getenv("LOGIN")))
+ str="UNKNOWN_USER";
+ }
+ (void) strmake(name,str,USERNAME_LENGTH);
+#elif HAVE_CUSERID
+ (void) cuserid(name);
+#else
+ strmov(name,"UNKNOWN_USER");
+#endif
+ }
+ DBUG_VOID_RETURN;
+}
+
+#else /* If MSDOS || VMS */
+
+static void read_user_name(char *name)
+{
+ char *str=getenv("USER");
+ strmov(name,str ? str : "ODBC"); /* ODBC will send user variable */
+}
+
+#endif
+
+#ifdef __WIN__
+static my_bool is_NT(void)
+{
+ char *os=getenv("OS");
+ return (os && !strcmp(os, "Windows_NT")) ? 1 : 0;
+}
+#endif
+
+/*
+** Expand wildcard to a sql string
+*/
+
+static void
+append_wild(char *to, char *end, const char *wild)
+{
+ end-=5; /* Some extra */
+ if (wild && wild[0])
+ {
+ to=strmov(to," like '");
+ while (*wild && to < end)
+ {
+ if (*wild == '\\' || *wild == '\'')
+ *to++='\\';
+ *to++= *wild++;
+ }
+ if (*wild) /* Too small buffer */
+ *to++='%'; /* Nicer this way */
+ to[0]='\'';
+ to[1]=0;
+ }
+}
+
+
+
+/**************************************************************************
+** Init debugging if MYSQL_DEBUG environment variable is found
+**************************************************************************/
+
+void STDCALL
+mysql_debug(const char *debug)
+{
+#ifndef DBUG_OFF
+ char *env;
+ if (_db_on_)
+ return; /* Already using debugging */
+ if (debug)
+ {
+ DEBUGGER_ON;
+ DBUG_PUSH(debug);
+ }
+ else if ((env = getenv("MYSQL_DEBUG")))
+ {
+ DEBUGGER_ON;
+ DBUG_PUSH(env);
+#if !defined(_WINVER) && !defined(WINVER)
+ puts("\n-------------------------------------------------------");
+ puts("MYSQL_DEBUG found. libmysql started with the following:");
+ puts(env);
+ puts("-------------------------------------------------------\n");
+#else
+ {
+ char buff[80];
+ strmov(strmov(buff,"libmysql: "),env);
+ MessageBox((HWND) 0,"Debugging variable MYSQL_DEBUG used",buff,MB_OK);
+ }
+#endif
+ }
+#endif
+}
+
+/**************************************************************************
+** Shut down connection
+**************************************************************************/
+
+static void
+end_server(MYSQL *mysql)
+{
+ DBUG_ENTER("end_server");
+ if (mysql->net.vio != 0)
+ {
+ end_embedded_connection(&mysql->net);
+ mysql->net.vio= 0; /* Marker */
+ }
+ net_end(&mysql->net);
+ free_old_query(mysql);
+ DBUG_VOID_RETURN;
+}
+
+
+void STDCALL
+mysql_free_result(MYSQL_RES *result)
+{
+ DBUG_ENTER("mysql_free_result");
+ DBUG_PRINT("enter",("mysql_res: %lx",result));
+ if (result)
+ {
+ if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT)
+ {
+ DBUG_PRINT("warning",("Not all rows in set were read; Ignoring rows"));
+ for (;;)
+ {
+ uint pkt_len;
+ if ((pkt_len=(uint) net_safe_read(result->handle)) == packet_error)
+ break;
+ if (pkt_len == 1 && result->handle->net.read_pos[0] == 254)
+ break; /* End of data */
+ }
+ result->handle->status=MYSQL_STATUS_READY;
+ }
+ free_rows(result->data);
+ if (result->fields)
+ free_root(&result->field_alloc,MYF(0));
+ if (result->row)
+ my_free((gptr) result->row,MYF(0));
+ my_free((gptr) result,MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/****************************************************************************
+** Get options from my.cnf
+****************************************************************************/
+
+static const char *default_options[]=
+{"port","socket","compress","password","pipe", "timeout", "user",
+ "init-command", "host", "database", "debug", "return-found-rows",
+ "ssl_key" ,"ssl_cert" ,"ssl_ca" ,"ssl_capath",
+ "character-set-dir", "default-character-set",
+ NullS
+};
+
+static TYPELIB option_types={array_elements(default_options)-1,
+ "options",default_options};
+
+static void mysql_read_default_options(struct st_mysql_options *options,
+ const char *filename,const char *group)
+{
+ int argc;
+ char *argv_buff[1],**argv;
+ const char *groups[3];
+ DBUG_ENTER("mysql_read_default_options");
+ DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL"));
+
+ argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
+ groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
+
+ load_defaults(filename, groups, &argc, &argv);
+ if (argc != 1) /* If some default option */
+ {
+ char **option=argv;
+ while (*++option)
+ {
+ /* DBUG_PRINT("info",("option: %s",option[0])); */
+ if (option[0][0] == '-' && option[0][1] == '-')
+ {
+ char *end=strcend(*option,'=');
+ char *opt_arg=0;
+ if (*end)
+ {
+ opt_arg=end+1;
+ *end=0; /* Remove '=' */
+ }
+ switch (find_type(*option+2,&option_types,2)) {
+ case 1: /* port */
+ if (opt_arg)
+ options->port=atoi(opt_arg);
+ break;
+ case 2: /* socket */
+ if (opt_arg)
+ {
+ my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
+ options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 3: /* compress */
+ options->compress=1;
+ break;
+ case 4: /* password */
+ if (opt_arg)
+ {
+ my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
+ options->password=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 5: /* pipe */
+ options->named_pipe=1; /* Force named pipe */
+ break;
+ case 6: /* timeout */
+ if (opt_arg)
+ options->connect_timeout=atoi(opt_arg);
+ break;
+ case 7: /* user */
+ if (opt_arg)
+ {
+ my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
+ options->user=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 8: /* init-command */
+ if (opt_arg)
+ {
+ my_free(options->init_command,MYF(MY_ALLOW_ZERO_PTR));
+ options->init_command=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 9: /* host */
+ if (opt_arg)
+ {
+ my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
+ options->host=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 10: /* database */
+ if (opt_arg)
+ {
+ my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
+ options->db=my_strdup(opt_arg,MYF(MY_WME));
+ }
+ break;
+ case 11: /* debug */
+ mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace");
+ break;
+ case 12: /* return-found-rows */
+ options->client_flag|=CLIENT_FOUND_ROWS;
+ break;
+ case 13: /* Ignore SSL options */
+ case 14:
+ case 15:
+ case 16:
+ break;
+ case 17: /* charset-lib */
+ my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
+ options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
+ break;
+ case 18:
+ my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
+ options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
+ break;
+ default:
+ DBUG_PRINT("warning",("unknown option: %s",option[0]));
+ }
+ }
+ }
+ }
+ free_defaults(argv);
+ DBUG_VOID_RETURN;
+}
+
+
+/***************************************************************************
+** Change field rows to field structs
+***************************************************************************/
+
+static MYSQL_FIELD *
+unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
+ my_bool default_value, my_bool long_flag_protocol)
+{
+ MYSQL_ROWS *row;
+ MYSQL_FIELD *field,*result;
+ DBUG_ENTER("unpack_fields");
+
+ field=result=(MYSQL_FIELD*) alloc_root(alloc,sizeof(MYSQL_FIELD)*fields);
+ if (!result)
+ DBUG_RETURN(0);
+
+ for (row=data->data; row ; row = row->next,field++)
+ {
+ field->table= strdup_root(alloc,(char*) row->data[0]);
+ field->name= strdup_root(alloc,(char*) row->data[1]);
+ field->length= (uint) uint3korr(row->data[2]);
+ field->type= (enum enum_field_types) (uchar) row->data[3][0];
+ if (long_flag_protocol)
+ {
+ field->flags= uint2korr(row->data[4]);
+ field->decimals=(uint) (uchar) row->data[4][2];
+ }
+ else
+ {
+ field->flags= (uint) (uchar) row->data[4][0];
+ field->decimals=(uint) (uchar) row->data[4][1];
+ }
+ if (INTERNAL_NUM_FIELD(field))
+ field->flags|= NUM_FLAG;
+ if (default_value && row->data[5])
+ field->def=strdup_root(alloc,(char*) row->data[5]);
+ else
+ field->def=0;
+ field->max_length= 0;
+ }
+ free_rows(data); /* Free old data */
+ DBUG_RETURN(result);
+}
+
+
+/* Read all rows (fields or data) from server */
+
+static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
+ uint fields)
+{
+ uint field,pkt_len;
+ ulong len;
+ uchar *cp;
+ char *to;
+ MYSQL_DATA *result;
+ MYSQL_ROWS **prev_ptr,*cur;
+ NET *net = &mysql->net;
+ DBUG_ENTER("read_rows");
+
+ if ((pkt_len=(uint) net_safe_read(mysql)) == packet_error)
+ DBUG_RETURN(0);
+ if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
+ MYF(MY_WME | MY_ZEROFILL))))
+ {
+ net->last_errno=CR_OUT_OF_MEMORY;
+ strmov(net->last_error,ER(net->last_errno));
+ DBUG_RETURN(0);
+ }
+ init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
+ result->alloc.min_malloc=sizeof(MYSQL_ROWS);
+ prev_ptr= &result->data;
+ result->rows=0;
+ result->fields=fields;
+
+ while (*(cp=net->read_pos) != 254 || pkt_len != 1)
+ {
+ result->rows++;
+ if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
+ sizeof(MYSQL_ROWS))) ||
+ !(cur->data= ((MYSQL_ROW)
+ alloc_root(&result->alloc,
+ (fields+1)*sizeof(char *)+pkt_len))))
+ {
+ free_rows(result);
+ net->last_errno=CR_OUT_OF_MEMORY;
+ strmov(net->last_error,ER(net->last_errno));
+ DBUG_RETURN(0);
+ }
+ *prev_ptr=cur;
+ prev_ptr= &cur->next;
+ to= (char*) (cur->data+fields+1);
+ for (field=0 ; field < fields ; field++)
+ {
+ if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH)
+ { /* null field */
+ cur->data[field] = 0;
+ }
+ else
+ {
+ cur->data[field] = to;
+ memcpy(to,(char*) cp,len); to[len]=0;
+ to+=len+1;
+ cp+=len;
+ if (mysql_fields)
+ {
+ if (mysql_fields[field].max_length < len)
+ mysql_fields[field].max_length=len;
+ }
+ }
+ }
+ cur->data[field]=to; /* End of last field */
+ if ((pkt_len=net_safe_read(mysql)) == packet_error)
+ {
+ free_rows(result);
+ DBUG_RETURN(0);
+ }
+ }
+ *prev_ptr=0; /* last pointer is null */
+ DBUG_PRINT("exit",("Got %d rows",result->rows));
+ DBUG_RETURN(result);
+}
+
+
+/*
+** Read one row. Uses packet buffer as storage for fields.
+** When next packet is read, the previous field values are destroyed
+*/
+
+
+static int
+read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
+{
+ uint field;
+ ulong pkt_len,len;
+ uchar *pos,*prev_pos;
+
+ if ((pkt_len=net_safe_read(mysql)) == packet_error)
+ return -1;
+ if (pkt_len == 1 && mysql->net.read_pos[0] == 254)
+ return 1; /* End of data */
+ prev_pos= 0; /* allowed to write at packet[-1] */
+ pos=mysql->net.read_pos;
+ for (field=0 ; field < fields ; field++)
+ {
+ if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH)
+ { /* null field */
+ row[field] = 0;
+ *lengths++=0;
+ }
+ else
+ {
+ row[field] = (char*) pos;
+ pos+=len;
+ *lengths++=len;
+ }
+ if (prev_pos)
+ *prev_pos=0; /* Terminate prev field */
+ prev_pos=pos;
+ }
+ row[field]=(char*) prev_pos+1; /* End of last field */
+ *prev_pos=0; /* Terminate last field */
+ return 0;
+}
+
+/****************************************************************************
+** Init MySQL structure or allocate one
+****************************************************************************/
+
+MYSQL * STDCALL
+mysql_init(MYSQL *mysql)
+{
+ mysqld_once_init();
+ if (!mysql)
+ {
+ if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
+ return 0;
+ mysql->free_me=1;
+ mysql->net.vio = 0;
+ }
+ else
+ bzero((char*) (mysql),sizeof(*(mysql)));
+ return mysql;
+}
+
+
+static void mysqld_once_init()
+{
+ if (!mysql_client_init)
+ {
+ mysql_client_init=1;
+ my_init(); /* Will init threads */
+ init_client_errs();
+ mysql_port = MYSQL_PORT;
+ mysql_debug(NullS);
+ }
+#ifdef THREAD
+ else
+ my_thread_init(); /* Init if new thread */
+#endif
+}
+
+/**************************************************************************
+** Connect to sql server
+** If host == 0 then use localhost
+**************************************************************************/
+
+MYSQL * STDCALL
+mysql_connect(MYSQL *mysql,const char *host,
+ const char *user, const char *passwd)
+{
+ MYSQL *res;
+ mysql=mysql_init(mysql); /* Make it thread safe */
+ {
+ DBUG_ENTER("mysql_connect");
+ if (!(res=mysql_real_connect(mysql,host,user,passwd,NullS,0,NullS,0)))
+ {
+ if (mysql->free_me)
+ my_free((gptr) mysql,MYF(0));
+ }
+ DBUG_RETURN(res);
+ }
+}
+
+
+/*
+** Note that the mysql argument must be initialized with mysql_init()
+** before calling mysql_real_connect !
+*/
+
+MYSQL * STDCALL
+mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
+ const char *passwd, const char *db,
+ uint port, const char *unix_socket,uint client_flag)
+{
+ char buff[100],charset_name_buff[16],*end,*host_info, *charset_name;
+ uint pkt_length;
+ ulong max_allowed_packet;
+ NET *net= &mysql->net;
+ DBUG_ENTER("mysql_real_connect");
+ DBUG_PRINT("enter",("host: %s db: %s user: %s",
+ host ? host : "(Null)",
+ db ? db : "(Null)",
+ user ? user : "(Null)"));
+
+ /*
+ Check mysql_server_init was called.
+ This code shouldn't be merged to 4.1
+ */
+ if (!server_inited)
+ {
+ net->last_errno=CR_UNKNOWN_ERROR;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
+ }
+
+ net->vio = 0; /* If something goes wrong */
+ /* use default options */
+ if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
+ {
+ mysql_read_default_options(&mysql->options,
+ (mysql->options.my_cnf_file ?
+ mysql->options.my_cnf_file : "my"),
+ mysql->options.my_cnf_group);
+ my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
+ }
+
+ /* Some empty-string-tests are done because of ODBC */
+ if (!host || !host[0])
+ host=mysql->options.host;
+ if (!user || !user[0])
+ user=mysql->options.user;
+ if (!passwd)
+ {
+ passwd=mysql->options.password;
+ }
+ if (!db || !db[0])
+ db=mysql->options.db;
+ port=0;
+ unix_socket=0;
+ mysql->reconnect=1; /* Reconnect as default */
+ mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
+ host_info=(char*) ER(CR_EMBEDDED_CONNECTION);
+ if (my_net_init(net, net->vio))
+ {
+ vio_delete(net->vio);
+ net->last_errno=CR_OUT_OF_MEMORY;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
+ }
+
+ /* Get version info */
+ mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
+ start_embedded_connection(net);
+
+ if ((pkt_length=net_safe_read(mysql)) == packet_error)
+ goto error;
+
+ /* Check if version of protocoll matches current one */
+
+ mysql->protocol_version= net->read_pos[0];
+ DBUG_DUMP("packet",(char*) net->read_pos,10);
+ DBUG_PRINT("info",("mysql protocol version %d, server=%d",
+ PROTOCOL_VERSION, mysql->protocol_version));
+ if (mysql->protocol_version != PROTOCOL_VERSION &&
+ mysql->protocol_version != PROTOCOL_VERSION-1)
+ {
+ net->last_errno= CR_VERSION_ERROR;
+ sprintf(net->last_error, ER(CR_VERSION_ERROR), mysql->protocol_version,
+ PROTOCOL_VERSION);
+ goto error;
+ }
+ end=strend((char*) net->read_pos+1);
+ mysql->thread_id=uint4korr(end+1);
+ end+=5;
+ strmake(mysql->scramble_buff,end,8);
+ end+=9;
+ if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
+ mysql->server_capabilities=uint2korr(end);
+ if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
+ {
+ /* New protocol with 16 bytes to describe server characteristics */
+ mysql->server_language=end[2];
+ mysql->server_status=uint2korr(end+3);
+ }
+
+ /* Set character set */
+ if ((charset_name=mysql->options.charset_name))
+ {
+ const char *save=charsets_dir;
+ if (mysql->options.charset_dir)
+ charsets_dir=mysql->options.charset_dir;
+ mysql->charset=get_charset_by_name(mysql->options.charset_name,
+ MYF(MY_WME));
+ charsets_dir=save;
+ }
+ else if (mysql->server_language)
+ {
+ charset_name=charset_name_buff;
+ sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */
+ mysql->charset=get_charset((uint8) mysql->server_language, MYF(MY_WME));
+ }
+ else
+ mysql->charset=default_charset_info;
+
+ if (!mysql->charset)
+ {
+ net->last_errno=CR_CANT_READ_CHARSET;
+ if (mysql->options.charset_dir)
+ sprintf(net->last_error,ER(net->last_errno),
+ charset_name ? charset_name : "unknown",
+ mysql->options.charset_dir);
+ else
+ {
+ char cs_dir_name[FN_REFLEN];
+ get_charsets_dir(cs_dir_name);
+ sprintf(net->last_error,ER(net->last_errno),
+ charset_name ? charset_name : "unknown",
+ cs_dir_name);
+ }
+ goto error;
+ }
+
+ /* Save connection information */
+ if (!user) user="";
+ if (!passwd) passwd="";
+ host=LOCAL_HOST;
+ if (!my_multi_malloc(MYF(0),
+ &mysql->host_info, (uint) strlen(host_info)+1,
+ &mysql->host, (uint) strlen(host)+1,
+ &mysql->unix_socket,unix_socket ?
+ (uint) strlen(unix_socket)+1 : (uint) 1,
+ &mysql->server_version,
+ (uint) (end - (char*) net->read_pos),
+ NullS) ||
+ !(mysql->user=my_strdup(user,MYF(0))) ||
+ !(mysql->passwd=my_strdup(passwd,MYF(0))))
+ {
+ strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
+ goto error;
+ }
+ strmov(mysql->host_info,host_info);
+ strmov(mysql->host,host);
+ if (unix_socket)
+ strmov(mysql->unix_socket,unix_socket);
+ else
+ mysql->unix_socket=0;
+ strmov(mysql->server_version,(char*) net->read_pos+1);
+ mysql->port=port;
+ mysql->client_flag=client_flag | mysql->options.client_flag;
+ DBUG_PRINT("info",("Server version = '%s' capabilites: %ld status: %d",
+ mysql->server_version,mysql->server_capabilities,
+ mysql->server_status));
+
+ /* Send client information for access check */
+ client_flag|=CLIENT_CAPABILITIES;
+ client_flag&= ~CLIENT_COMPRESS;
+ if (db)
+ client_flag|=CLIENT_CONNECT_WITH_DB;
+ int2store(buff,client_flag);
+ mysql->client_flag=client_flag;
+
+ max_allowed_packet=net->max_packet_size;
+ int3store(buff+2,max_allowed_packet);
+ if (user && user[0])
+ strmake(buff+5,user,32);
+ else
+ read_user_name((char*) buff+5);
+#ifdef _CUSTOMCONFIG_
+#include "_cust_libmysql.h";
+#endif
+ DBUG_PRINT("info",("user: %s",buff+5));
+ end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd,
+ (my_bool) (mysql->protocol_version == 9));
+
+ if (db)
+ {
+ end=strmov(end+1,db);
+ mysql->db=my_strdup(db,MYF(MY_WME));
+ db=0;
+ }
+ if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
+ goto error;
+
+ lib_connection_phase(net,2);
+
+ if( net_safe_read(mysql) == packet_error)
+ goto error;
+ if (db && mysql_select_db(mysql,db))
+ goto error;
+ if (mysql->options.init_command)
+ {
+ my_bool reconnect=mysql->reconnect;
+ mysql->reconnect=0;
+ if (mysql_query(mysql,mysql->options.init_command))
+ goto error;
+ mysql_free_result(mysql_use_result(mysql));
+ mysql->reconnect=reconnect;
+ }
+
+ DBUG_PRINT("exit",("Mysql handler: %lx",mysql));
+ reset_sigpipe(mysql);
+ DBUG_RETURN(mysql);
+
+error:
+ reset_sigpipe(mysql);
+ DBUG_PRINT("error",("message: %u (%s)",net->last_errno,net->last_error));
+ {
+ /* Free alloced memory */
+ my_bool free_me=mysql->free_me;
+ end_server(mysql);
+ mysql->free_me=0;
+ mysql_close(mysql);
+ mysql->free_me=free_me;
+ }
+ DBUG_RETURN(0);
+}
+
+
+/**************************************************************************
+** Change user and database
+**************************************************************************/
+
+my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
+ const char *passwd, const char *db)
+{
+ char buff[512],*pos=buff;
+ DBUG_ENTER("mysql_change_user");
+
+ if (!user)
+ user="";
+ if (!passwd)
+ passwd="";
+
+ pos=strmov(pos,user)+1;
+ pos=scramble(pos, mysql->scramble_buff, passwd,
+ (my_bool) (mysql->protocol_version == 9));
+ pos=strmov(pos+1,db ? db : "");
+ if (simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (pos-buff),0))
+ DBUG_RETURN(1);
+
+ my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+
+ mysql->user= my_strdup(user,MYF(MY_WME));
+ mysql->passwd=my_strdup(passwd,MYF(MY_WME));
+ mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
+ DBUG_RETURN(0);
+}
+
+
+/**************************************************************************
+** Set current database
+**************************************************************************/
+
+int STDCALL
+mysql_select_db(MYSQL *mysql, const char *db)
+{
+ int error;
+ DBUG_ENTER("mysql_select_db");
+ DBUG_PRINT("enter",("db: '%s'",db));
+
+ if ((error=simple_command(mysql,COM_INIT_DB,db,(ulong) strlen(db),0)))
+ DBUG_RETURN(error);
+ my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->db=my_strdup(db,MYF(MY_WME));
+ DBUG_RETURN(0);
+}
+
+
+/*************************************************************************
+** Send a QUIT to the server and close the connection
+** If handle is alloced by mysql connect free it.
+*************************************************************************/
+
+void STDCALL
+mysql_close(MYSQL *mysql)
+{
+ DBUG_ENTER("mysql_close");
+ if (mysql) /* Some simple safety */
+ {
+ if (mysql->net.vio != 0)
+ {
+ free_old_query(mysql);
+ mysql->status=MYSQL_STATUS_READY; /* Force command */
+ simple_command(mysql,COM_QUIT,"",0,1);
+ end_server(mysql);
+ }
+ my_free((gptr) mysql->host_info,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.user,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.host,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.db,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
+ /* Clear pointers for better safety */
+ mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
+ bzero((char*) &mysql->options,sizeof(mysql->options));
+ mysql->net.vio = 0;
+#ifdef HAVE_OPENSSL
+ ((VioConnectorFd*)(mysql->connector_fd))->delete();
+ mysql->connector_fd = 0;
+#endif /* HAVE_OPENSSL */
+ if (mysql->free_me)
+ my_free((gptr) mysql,MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/**************************************************************************
+** Do a query. If query returned rows, free old rows.
+** Read data by mysql_store_result or by repeat call of mysql_fetch_row
+**************************************************************************/
+
+int STDCALL
+mysql_query(MYSQL *mysql, const char *query)
+{
+ return mysql_real_query(mysql,query, (ulong) strlen(query));
+}
+
+int STDCALL
+mysql_send_query(MYSQL* mysql, const char* query, ulong length)
+{
+ return simple_command(mysql, COM_QUERY, query, length, 1);
+}
+
+
+int STDCALL
+mysql_read_query_result(MYSQL *mysql)
+{
+ uchar *pos;
+ ulong field_count;
+ MYSQL_DATA *fields;
+ uint length;
+ DBUG_ENTER("mysql_read_query_result");
+
+ if ((length=net_safe_read(mysql)) == packet_error)
+ DBUG_RETURN(-1);
+ free_old_query(mysql); /* Free old result */
+get_info:
+ pos=(uchar*) mysql->net.read_pos;
+ if ((field_count= net_field_length(&pos)) == 0)
+ {
+ mysql->affected_rows= net_field_length_ll(&pos);
+ mysql->insert_id= net_field_length_ll(&pos);
+ if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
+ {
+ mysql->server_status=uint2korr(pos); pos+=2;
+ }
+ if (pos < mysql->net.read_pos+length && net_field_length(&pos))
+ mysql->info=(char*) pos;
+ DBUG_RETURN(0);
+ }
+ if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
+ {
+ int error=send_file_to_server(mysql,(char*) pos);
+ if ((length=net_safe_read(mysql)) == packet_error || error)
+ DBUG_RETURN(-1);
+ goto get_info; /* Get info packet */
+ }
+ if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
+ mysql->server_status|= SERVER_STATUS_IN_TRANS;
+
+ mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
+ if (!(fields=read_rows(mysql,(MYSQL_FIELD*) 0,5)))
+ DBUG_RETURN(-1);
+ if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
+ (uint) field_count,0,
+ (my_bool) test(mysql->server_capabilities &
+ CLIENT_LONG_FLAG))))
+ DBUG_RETURN(-1);
+ mysql->status=MYSQL_STATUS_GET_RESULT;
+ mysql->field_count=field_count;
+ DBUG_RETURN(0);
+}
+
+/****************************************************************************
+* A modified version of connect(). connect2() allows you to specify
+* a timeout value, in seconds, that we should wait until we
+* derermine we can't connect to a particular host. If timeout is 0,
+* my_connect() will behave exactly like connect().
+*
+* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
+*****************************************************************************/
+
+int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
+ uint timeout)
+{
+#if defined(__WIN__) || defined(OS2)
+ return connect(s, (struct sockaddr*) name, namelen);
+#else
+ int flags, res, s_err;
+ SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
+ fd_set sfds;
+ struct timeval tv;
+ time_t start_time, now_time;
+
+ /* If they passed us a timeout of zero, we should behave
+ * exactly like the normal connect() call does.
+ */
+
+ if (timeout == 0)
+ return connect(s, (struct sockaddr*) name, namelen);
+
+ flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
+#ifdef O_NONBLOCK
+ fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
+#endif
+
+ res = connect(s, (struct sockaddr*) name, namelen);
+ s_err = errno; /* Save the error... */
+ fcntl(s, F_SETFL, flags);
+ if ((res != 0) && (s_err != EINPROGRESS))
+ {
+ errno = s_err; /* Restore it */
+ return(-1);
+ }
+ if (res == 0) /* Connected quickly! */
+ return(0);
+
+ /* Otherwise, our connection is "in progress." We can use
+ * the select() call to wait up to a specified period of time
+ * for the connection to suceed. If select() returns 0
+ * (after waiting howevermany seconds), our socket never became
+ * writable (host is probably unreachable.) Otherwise, if
+ * select() returns 1, then one of two conditions exist:
+ *
+ * 1. An error occured. We use getsockopt() to check for this.
+ * 2. The connection was set up sucessfully: getsockopt() will
+ * return 0 as an error.
+ *
+ * Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
+ * who posted this method of timing out a connect() in
+ * comp.unix.programmer on August 15th, 1997.
+ */
+
+ FD_ZERO(&sfds);
+ FD_SET(s, &sfds);
+ /*
+ * select could be interrupted by a signal, and if it is,
+ * the timeout should be adjusted and the select restarted
+ * to work around OSes that don't restart select and
+ * implementations of select that don't adjust tv upon
+ * failure to reflect the time remaining
+ */
+ start_time = time(NULL);
+ for (;;)
+ {
+ tv.tv_sec = (long) timeout;
+ tv.tv_usec = 0;
+ if ((res = select(s+1, NULL, &sfds, NULL, &tv)) >= 0)
+ break;
+ now_time=time(NULL);
+ timeout-= (uint) (now_time - start_time);
+ if (errno != EINTR || (int) timeout <= 0)
+ return -1;
+ }
+
+ /* select() returned something more interesting than zero, let's
+ * see if we have any errors. If the next two statements pass,
+ * we've got an open socket!
+ */
+
+ s_err=0;
+ if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
+ return(-1);
+
+ if (s_err)
+ { /* getsockopt could succeed */
+ errno = s_err;
+ return(-1); /* but return an error... */
+ }
+ return(0); /* It's all good! */
+#endif
+}
+
+
+int STDCALL
+mysql_real_query(MYSQL *mysql, const char *query, ulong length)
+{
+ DBUG_ENTER("mysql_real_query");
+ DBUG_PRINT("enter",("handle: %lx",mysql));
+ DBUG_PRINT("query",("Query = \"%s\"",query));
+ if (mysql_send_query(mysql, query, length))
+ DBUG_RETURN(-1);
+ DBUG_RETURN(mysql_read_query_result(mysql));
+}
+
+
+static int
+send_file_to_server(MYSQL *mysql, const char *filename)
+{
+ int fd, readcount;
+ char buf[IO_SIZE*15],*tmp_name;
+ DBUG_ENTER("send_file_to_server");
+
+ fn_format(buf,filename,"","",4); /* Convert to client format */
+ if (!(tmp_name=my_strdup(buf,MYF(0))))
+ {
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY));
+ DBUG_RETURN(-1);
+ }
+ if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0)
+ {
+ mysql->net.last_errno=EE_FILENOTFOUND;
+ sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno);
+ strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1);
+ my_net_write(&mysql->net,"",0); net_flush(&mysql->net);
+ my_free(tmp_name,MYF(0));
+ DBUG_RETURN(-1);
+ }
+
+ while ((readcount = (int) my_read(fd,buf,sizeof(buf),MYF(0))) > 0)
+ {
+ if (my_net_write(&mysql->net,buf,readcount))
+ {
+ mysql->net.last_errno=CR_SERVER_LOST;
+ strmov(mysql->net.last_error,ER(mysql->net.last_errno));
+ DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file"));
+ (void) my_close(fd,MYF(0));
+ my_free(tmp_name,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ }
+ (void) my_close(fd,MYF(0));
+ /* Send empty packet to mark end of file */
+ if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net))
+ {
+ mysql->net.last_errno=CR_SERVER_LOST;
+ sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno);
+ my_free(tmp_name,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ if (readcount < 0)
+ {
+ mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */
+ sprintf(buf,EE(mysql->net.last_errno),tmp_name,errno);
+ strmake(mysql->net.last_error,buf,sizeof(mysql->net.last_error)-1);
+ my_free(tmp_name,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ DBUG_RETURN(0);
+}
+
+
+/**************************************************************************
+** Alloc result struct for buffered results. All rows are read to buffer.
+** mysql_data_seek may be used.
+**************************************************************************/
+
+MYSQL_RES * STDCALL
+mysql_store_result(MYSQL *mysql)
+{
+ MYSQL_RES *result;
+ DBUG_ENTER("mysql_store_result");
+
+ if (!mysql->fields)
+ DBUG_RETURN(0);
+ if (mysql->status != MYSQL_STATUS_GET_RESULT)
+ {
+ strmov(mysql->net.last_error,
+ ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
+ DBUG_RETURN(0);
+ }
+ mysql->status=MYSQL_STATUS_READY; /* server is ready */
+ if (!(result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+
+ sizeof(ulong)*mysql->field_count,
+ MYF(MY_WME | MY_ZEROFILL))))
+ {
+ mysql->net.last_errno=CR_OUT_OF_MEMORY;
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno));
+ DBUG_RETURN(0);
+ }
+ result->eof=1; /* Marker for buffered */
+ result->lengths=(ulong*) (result+1);
+ if (!(result->data=read_rows(mysql,mysql->fields,mysql->field_count)))
+ {
+ my_free((gptr) result,MYF(0));
+ DBUG_RETURN(0);
+ }
+ mysql->affected_rows= result->row_count= result->data->rows;
+ result->data_cursor= result->data->data;
+ result->fields= mysql->fields;
+ result->field_alloc= mysql->field_alloc;
+ result->field_count= mysql->field_count;
+ result->current_field=0;
+ result->current_row=0; /* Must do a fetch first */
+ mysql->fields=0; /* fields is now in result */
+ DBUG_RETURN(result); /* Data fetched */
+}
+
+
+/**************************************************************************
+** Alloc struct for use with unbuffered reads. Data is fetched by domand
+** when calling to mysql_fetch_row.
+** mysql_data_seek is a noop.
+**
+** No other queries may be specified with the same MYSQL handle.
+** There shouldn't be much processing per row because mysql server shouldn't
+** have to wait for the client (and will not wait more than 30 sec/packet).
+**************************************************************************/
+
+MYSQL_RES * STDCALL
+mysql_use_result(MYSQL *mysql)
+{
+ MYSQL_RES *result;
+ DBUG_ENTER("mysql_use_result");
+
+ if (!mysql->fields)
+ DBUG_RETURN(0);
+ if (mysql->status != MYSQL_STATUS_GET_RESULT)
+ {
+ strmov(mysql->net.last_error,
+ ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
+ DBUG_RETURN(0);
+ }
+ if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result)+
+ sizeof(ulong)*mysql->field_count,
+ MYF(MY_WME | MY_ZEROFILL))))
+ DBUG_RETURN(0);
+ result->lengths=(ulong*) (result+1);
+ if (!(result->row=(MYSQL_ROW)
+ my_malloc(sizeof(result->row[0])*(mysql->field_count+1), MYF(MY_WME))))
+ { /* Ptrs: to one row */
+ my_free((gptr) result,MYF(0));
+ DBUG_RETURN(0);
+ }
+ result->fields= mysql->fields;
+ result->field_alloc= mysql->field_alloc;
+ result->field_count= mysql->field_count;
+ result->current_field=0;
+ result->handle= mysql;
+ result->current_row= 0;
+ mysql->fields=0; /* fields is now in result */
+ mysql->status=MYSQL_STATUS_USE_RESULT;
+ DBUG_RETURN(result); /* Data is read to be fetched */
+}
+
+
+
+/**************************************************************************
+** Return next field of the query results
+**************************************************************************/
+
+MYSQL_FIELD * STDCALL
+mysql_fetch_field(MYSQL_RES *result)
+{
+ if (result->current_field >= result->field_count)
+ return(NULL);
+ return &result->fields[result->current_field++];
+}
+
+
+/**************************************************************************
+** Return next row of the query results
+**************************************************************************/
+
+MYSQL_ROW STDCALL
+mysql_fetch_row(MYSQL_RES *res)
+{
+ DBUG_ENTER("mysql_fetch_row");
+ if (!res->data)
+ { /* Unbufferred fetch */
+ if (!res->eof)
+ {
+ if (!(read_one_row(res->handle,res->field_count,res->row, res->lengths)))
+ {
+ res->row_count++;
+ DBUG_RETURN(res->current_row=res->row);
+ }
+ else
+ {
+ DBUG_PRINT("info",("end of data"));
+ res->eof=1;
+ res->handle->status=MYSQL_STATUS_READY;
+ }
+ }
+ DBUG_RETURN((MYSQL_ROW) NULL);
+ }
+ {
+ MYSQL_ROW tmp;
+ if (!res->data_cursor)
+ {
+ DBUG_PRINT("info",("end of data"));
+ DBUG_RETURN(res->current_row=(MYSQL_ROW) NULL);
+ }
+ tmp = res->data_cursor->data;
+ res->data_cursor = res->data_cursor->next;
+ DBUG_RETURN(res->current_row=tmp);
+ }
+}
+
+/**************************************************************************
+** Get column lengths of the current row
+** If one uses mysql_use_result, res->lengths contains the length information,
+** else the lengths are calculated from the offset between pointers.
+**************************************************************************/
+
+ulong * STDCALL
+mysql_fetch_lengths(MYSQL_RES *res)
+{
+ ulong *lengths,*prev_length;
+ byte *start;
+ MYSQL_ROW column,end;
+
+ if (!(column=res->current_row))
+ return 0; /* Something is wrong */
+ if (res->data)
+ {
+ start=0;
+ prev_length=0; /* Keep gcc happy */
+ lengths=res->lengths;
+ for (end=column+res->field_count+1 ; column != end ; column++,lengths++)
+ {
+ if (!*column)
+ {
+ *lengths=0; /* Null */
+ continue;
+ }
+ if (start) /* Found end of prev string */
+ *prev_length= (uint) (*column-start-1);
+ start= *column;
+ prev_length=lengths;
+ }
+ }
+ return res->lengths;
+}
+
+/**************************************************************************
+** Move to a specific row and column
+**************************************************************************/
+
+void STDCALL
+mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
+{
+ MYSQL_ROWS *tmp=0;
+ DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row));
+ if (result->data)
+ for (tmp=result->data->data; row-- && tmp ; tmp = tmp->next) ;
+ result->current_row=0;
+ result->data_cursor = tmp;
+}
+
+/*************************************************************************
+** put the row or field cursor one a position one got from mysql_row_tell()
+** This doesn't restore any data. The next mysql_fetch_row or
+** mysql_fetch_field will return the next row or field after the last used
+*************************************************************************/
+
+MYSQL_ROW_OFFSET STDCALL
+mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET row)
+{
+ MYSQL_ROW_OFFSET return_value=result->data_cursor;
+ result->current_row= 0;
+ result->data_cursor= row;
+ return return_value;
+}
+
+
+MYSQL_FIELD_OFFSET STDCALL
+mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET field_offset)
+{
+ MYSQL_FIELD_OFFSET return_value=result->current_field;
+ result->current_field=field_offset;
+ return return_value;
+}
+
+/*****************************************************************************
+** List all databases
+*****************************************************************************/
+
+MYSQL_RES * STDCALL
+mysql_list_dbs(MYSQL *mysql, const char *wild)
+{
+ char buff[255];
+ DBUG_ENTER("mysql_list_dbs");
+
+ append_wild(strmov(buff,"show databases"),buff+sizeof(buff),wild);
+ if (mysql_query(mysql,buff))
+ DBUG_RETURN(0);
+ DBUG_RETURN (mysql_store_result(mysql));
+}
+
+
+/*****************************************************************************
+** List all tables in a database
+** If wild is given then only the tables matching wild is returned
+*****************************************************************************/
+
+MYSQL_RES * STDCALL
+mysql_list_tables(MYSQL *mysql, const char *wild)
+{
+ char buff[255];
+ DBUG_ENTER("mysql_list_tables");
+
+ append_wild(strmov(buff,"show tables"),buff+sizeof(buff),wild);
+ if (mysql_query(mysql,buff))
+ DBUG_RETURN(0);
+ DBUG_RETURN (mysql_store_result(mysql));
+}
+
+
+/**************************************************************************
+** List all fields in a table
+** If wild is given then only the fields matching wild is returned
+** Instead of this use query:
+** show fields in 'table' like "wild"
+**************************************************************************/
+
+MYSQL_RES * STDCALL
+mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
+{
+ MYSQL_RES *result;
+ MYSQL_DATA *query;
+ char buff[257],*end;
+ DBUG_ENTER("mysql_list_fields");
+ DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : ""));
+
+ LINT_INIT(query);
+
+ end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
+ if (simple_command(mysql,COM_FIELD_LIST,buff,(uint) (end-buff),1) ||
+ !(query = read_rows(mysql,(MYSQL_FIELD*) 0,6)))
+ DBUG_RETURN(NULL);
+
+ free_old_query(mysql);
+ if (!(result = (MYSQL_RES *) my_malloc(sizeof(MYSQL_RES),
+ MYF(MY_WME | MY_ZEROFILL))))
+ {
+ free_rows(query);
+ DBUG_RETURN(NULL);
+ }
+ result->field_alloc=mysql->field_alloc;
+ mysql->fields=0;
+ result->field_count = (uint) query->rows;
+ result->fields= unpack_fields(query,&result->field_alloc,
+ result->field_count,1,
+ (my_bool) test(mysql->server_capabilities &
+ CLIENT_LONG_FLAG));
+ result->eof=1;
+ DBUG_RETURN(result);
+}
+
+/* List all running processes (threads) in server */
+
+MYSQL_RES * STDCALL
+mysql_list_processes(MYSQL *mysql)
+{
+ MYSQL_DATA *fields;
+ uint field_count;
+ uchar *pos;
+ DBUG_ENTER("mysql_list_processes");
+
+ LINT_INIT(fields);
+ if (simple_command(mysql,COM_PROCESS_INFO,"",0,0))
+ DBUG_RETURN(0);
+ free_old_query(mysql);
+ pos=(uchar*) mysql->net.read_pos;
+ field_count=(uint) net_field_length(&pos);
+ if (!(fields = read_rows(mysql,(MYSQL_FIELD*) 0,5)))
+ DBUG_RETURN(NULL);
+ if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0,
+ (my_bool) test(mysql->server_capabilities &
+ CLIENT_LONG_FLAG))))
+ DBUG_RETURN(0);
+ mysql->status=MYSQL_STATUS_GET_RESULT;
+ mysql->field_count=field_count;
+ DBUG_RETURN(mysql_store_result(mysql));
+}
+
+
+int STDCALL
+mysql_create_db(MYSQL *mysql, const char *db)
+{
+ DBUG_ENTER("mysql_createdb");
+ DBUG_PRINT("enter",("db: %s",db));
+ DBUG_RETURN(simple_command(mysql,COM_CREATE_DB,db, (ulong) strlen(db),0));
+}
+
+
+int STDCALL
+mysql_drop_db(MYSQL *mysql, const char *db)
+{
+ DBUG_ENTER("mysql_drop_db");
+ DBUG_PRINT("enter",("db: %s",db));
+ DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(ulong) strlen(db),0));
+}
+
+
+int STDCALL
+mysql_shutdown(MYSQL *mysql)
+{
+ DBUG_ENTER("mysql_shutdown");
+ DBUG_RETURN(simple_command(mysql,COM_SHUTDOWN,"",0,0));
+}
+
+
+int STDCALL
+mysql_refresh(MYSQL *mysql,uint options)
+{
+ uchar bits[1];
+ DBUG_ENTER("mysql_refresh");
+ bits[0]= (uchar) options;
+ DBUG_RETURN(simple_command(mysql,COM_REFRESH,(char*) bits,1,0));
+}
+
+int STDCALL
+mysql_kill(MYSQL *mysql,ulong pid)
+{
+ char buff[12];
+ DBUG_ENTER("mysql_kill");
+ int4store(buff,pid);
+ DBUG_RETURN(simple_command(mysql,COM_PROCESS_KILL,buff,4,0));
+}
+
+
+int STDCALL
+mysql_dump_debug_info(MYSQL *mysql)
+{
+ DBUG_ENTER("mysql_dump_debug_info");
+ DBUG_RETURN(simple_command(mysql,COM_DEBUG,"",0,0));
+}
+
+const char * STDCALL
+mysql_stat(MYSQL *mysql)
+{
+ DBUG_ENTER("mysql_stat");
+ if (simple_command(mysql,COM_STATISTICS,"",0,0))
+ return mysql->net.last_error;
+ mysql->net.read_pos[mysql->packet_length]=0; /* End of stat string */
+ if (!mysql->net.read_pos[0])
+ {
+ mysql->net.last_errno=CR_WRONG_HOST_INFO;
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno));
+ return mysql->net.last_error;
+ }
+ DBUG_RETURN((char*) mysql->net.read_pos);
+}
+
+
+int STDCALL
+mysql_ping(MYSQL *mysql)
+{
+ DBUG_ENTER("mysql_ping");
+ DBUG_RETURN(simple_command(mysql,COM_PING,"",0,0));
+}
+
+
+const char * STDCALL
+mysql_get_server_info(MYSQL *mysql)
+{
+ return((char*) mysql->server_version);
+}
+
+
+const char * STDCALL
+mysql_get_host_info(MYSQL *mysql)
+{
+ return(mysql->host_info);
+}
+
+
+uint STDCALL
+mysql_get_proto_info(MYSQL *mysql)
+{
+ return (mysql->protocol_version);
+}
+
+const char * STDCALL
+mysql_get_client_info(void)
+{
+ return MYSQL_SERVER_VERSION;
+}
+
+
+int STDCALL
+mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
+{
+ DBUG_ENTER("mysql_option");
+ DBUG_PRINT("enter",("option: %d",(int) option));
+ switch (option) {
+ case MYSQL_OPT_CONNECT_TIMEOUT:
+ mysql->options.connect_timeout= *(uint*) arg;
+ break;
+ case MYSQL_OPT_COMPRESS:
+ mysql->options.compress=1; /* Remember for connect */
+ break;
+ case MYSQL_OPT_NAMED_PIPE:
+ mysql->options.named_pipe=1; /* Force named pipe */
+ break;
+ case MYSQL_INIT_COMMAND:
+ my_free(mysql->options.init_command,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.init_command=my_strdup(arg,MYF(MY_WME));
+ break;
+ case MYSQL_READ_DEFAULT_FILE:
+ my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.my_cnf_file=my_strdup(arg,MYF(MY_WME));
+ break;
+ case MYSQL_READ_DEFAULT_GROUP:
+ my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.my_cnf_group=my_strdup(arg,MYF(MY_WME));
+ break;
+ case MYSQL_SET_CHARSET_DIR:
+ my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.charset_dir=my_strdup(arg,MYF(MY_WME));
+ break;
+ case MYSQL_SET_CHARSET_NAME:
+ my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.charset_name=my_strdup(arg,MYF(MY_WME));
+ break;
+ default:
+ DBUG_RETURN(-1);
+ }
+ DBUG_RETURN(0);
+}
+
+/****************************************************************************
+** Functions to get information from the MySQL structure
+** These are functions to make shared libraries more usable.
+****************************************************************************/
+
+/* MYSQL_RES */
+my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res)
+{
+ return res->row_count;
+}
+
+unsigned int STDCALL mysql_num_fields(MYSQL_RES *res)
+{
+ return res->field_count;
+}
+
+my_bool STDCALL mysql_eof(MYSQL_RES *res)
+{
+ return res->eof;
+}
+
+MYSQL_FIELD * STDCALL mysql_fetch_field_direct(MYSQL_RES *res,uint fieldnr)
+{
+ return &(res)->fields[fieldnr];
+}
+
+MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res)
+{
+ return (res)->fields;
+}
+
+MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res)
+{
+ return res->data_cursor;
+}
+
+uint STDCALL mysql_field_tell(MYSQL_RES *res)
+{
+ return (res)->current_field;
+}
+
+/* MYSQL */
+
+unsigned int STDCALL mysql_field_count(MYSQL *mysql)
+{
+ return mysql->field_count;
+}
+
+my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql)
+{
+ return (mysql)->affected_rows;
+}
+
+my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql)
+{
+ return (mysql)->insert_id;
+}
+
+uint STDCALL mysql_errno(MYSQL *mysql)
+{
+ return (mysql)->net.last_errno;
+}
+
+const char * STDCALL mysql_error(MYSQL *mysql)
+{
+ return (mysql)->net.last_error;
+}
+
+const char *STDCALL mysql_info(MYSQL *mysql)
+{
+ return (mysql)->info;
+}
+
+ulong STDCALL mysql_thread_id(MYSQL *mysql)
+{
+ return (mysql)->thread_id;
+}
+
+const char * STDCALL mysql_character_set_name(MYSQL *mysql)
+{
+ return mysql->charset->name;
+}
+
+
+uint STDCALL mysql_thread_safe(void)
+{
+#ifdef THREAD
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+/****************************************************************************
+** Some support functions
+****************************************************************************/
+
+/*
+** Add escape characters to a string (blob?) to make it suitable for a insert
+** to should at least have place for length*2+1 chars
+** Returns the length of the to string
+*/
+
+ulong STDCALL
+mysql_escape_string(char *to,const char *from,ulong length)
+{
+ return mysql_sub_escape_string(default_charset_info,to,from,length);
+}
+
+ulong STDCALL
+mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
+ ulong length)
+{
+ return mysql_sub_escape_string(mysql->charset,to,from,length);
+}
+
+
+static ulong
+mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
+ const char *from, ulong length)
+{
+ const char *to_start=to;
+ const char *end;
+#ifdef USE_MB
+ my_bool use_mb_flag=use_mb(charset_info);
+#endif
+ for (end=from+length; from != end ; from++)
+ {
+#ifdef USE_MB
+ int l;
+ if (use_mb_flag && (l = my_ismbchar(charset_info, from, end)))
+ {
+ while (l--)
+ *to++ = *from++;
+ from--;
+ continue;
+ }
+#endif
+ switch (*from) {
+ case 0: /* Must be escaped for 'mysql' */
+ *to++= '\\';
+ *to++= '0';
+ break;
+ case '\n': /* Must be escaped for logs */
+ *to++= '\\';
+ *to++= 'n';
+ break;
+ case '\r':
+ *to++= '\\';
+ *to++= 'r';
+ break;
+ case '\\':
+ *to++= '\\';
+ *to++= '\\';
+ break;
+ case '\'':
+ *to++= '\\';
+ *to++= '\'';
+ break;
+ case '"': /* Better safe than sorry */
+ *to++= '\\';
+ *to++= '"';
+ break;
+ case '\032': /* This gives problems on Win32 */
+ *to++= '\\';
+ *to++= 'Z';
+ break;
+ default:
+ *to++= *from;
+ }
+ }
+ *to=0;
+ return (ulong) (to-to_start);
+}
+
+
+char * STDCALL
+mysql_odbc_escape_string(MYSQL *mysql,
+ char *to, ulong to_length,
+ const char *from, ulong from_length,
+ void *param,
+ char * (*extend_buffer)
+ (void *, char *, ulong *))
+{
+ char *to_end=to+to_length-5;
+ const char *end;
+#ifdef USE_MB
+ my_bool use_mb_flag=use_mb(mysql->charset);
+#endif
+
+ for (end=from+from_length; from != end ; from++)
+ {
+ if (to >= to_end)
+ {
+ to_length = (ulong) (end-from)+512; /* We want this much more */
+ if (!(to=(*extend_buffer)(param, to, &to_length)))
+ return to;
+ to_end=to+to_length-5;
+ }
+#ifdef USE_MB
+ {
+ int l;
+ if (use_mb_flag && (l = my_ismbchar(mysql->charset, from, end)))
+ {
+ while (l--)
+ *to++ = *from++;
+ from--;
+ continue;
+ }
+ }
+#endif
+ switch (*from) {
+ case 0: /* Must be escaped for 'mysql' */
+ *to++= '\\';
+ *to++= '0';
+ break;
+ case '\n': /* Must be escaped for logs */
+ *to++= '\\';
+ *to++= 'n';
+ break;
+ case '\r':
+ *to++= '\\';
+ *to++= 'r';
+ break;
+ case '\\':
+ *to++= '\\';
+ *to++= '\\';
+ break;
+ case '\'':
+ *to++= '\\';
+ *to++= '\'';
+ break;
+ case '"': /* Better safe than sorry */
+ *to++= '\\';
+ *to++= '"';
+ break;
+ case '\032': /* This gives problems on Win32 */
+ *to++= '\\';
+ *to++= 'Z';
+ break;
+ default:
+ *to++= *from;
+ }
+ }
+ return to;
+}
+
+void STDCALL
+myodbc_remove_escape(MYSQL *mysql,char *name)
+{
+ char *to;
+#ifdef USE_MB
+ my_bool use_mb_flag=use_mb(mysql->charset);
+ char *end;
+ LINT_INIT(end);
+ if (use_mb_flag)
+ for (end=name; *end ; end++) ;
+#endif
+
+ for (to=name ; *name ; name++)
+ {
+#ifdef USE_MB
+ int l;
+ if (use_mb_flag && (l = my_ismbchar( mysql->charset, name , end ) ) )
+ {
+ while (l--)
+ *to++ = *name++;
+ name--;
+ continue;
+ }
+#endif
+ if (*name == '\\' && name[1])
+ name++;
+ *to++= *name;
+ }
+ *to=0;
+}
diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def
new file mode 100644
index 00000000000..c6615ee971c
--- /dev/null
+++ b/libmysqld/libmysqld.def
@@ -0,0 +1,65 @@
+LIBRARY LIBMYSQLD
+DESCRIPTION 'MySQL 4.0 Embedded Server Library'
+VERSION 4.0
+EXPORTS
+ mysql_server_end
+ mysql_server_init
+ mysql_use_result
+ mysql_thread_safe
+ mysql_thread_id
+ mysql_store_result
+ mysql_stat
+ mysql_shutdown
+ mysql_select_db
+ mysql_row_tell
+ mysql_row_seek
+ mysql_real_query
+ mysql_real_connect
+ mysql_query
+ mysql_ping
+ mysql_options
+ mysql_num_rows
+ mysql_num_fields
+ mysql_list_tables
+ mysql_list_processes
+ mysql_list_fields
+ mysql_list_dbs
+ mysql_kill
+ mysql_insert_id
+ mysql_init
+ mysql_info
+ mysql_get_server_info
+ mysql_get_proto_info
+ mysql_get_host_info
+ mysql_get_client_info
+ mysql_free_result
+ mysql_field_tell
+ mysql_field_count
+ mysql_field_seek
+ mysql_fetch_row
+ mysql_fetch_lengths
+ mysql_fetch_fields
+ mysql_fetch_field_direct
+ mysql_fetch_field
+ mysql_escape_string
+ mysql_real_escape_string
+ mysql_error
+ mysql_errno
+ mysql_eof
+ mysql_dump_debug_info
+ mysql_drop_db
+ mysql_debug
+ mysql_data_seek
+ mysql_create_db
+ mysql_character_set_name
+ mysql_change_user
+ mysql_connect
+ mysql_close
+ mysql_affected_rows
+ mysql_thread_init
+ mysql_thread_end
+ mysql_send_query
+ mysql_read_query_result
+ mysql_refresh
+ mysql_odbc_escape_string
+ myodbc_remove_escape
diff --git a/ltmain.sh b/ltmain.sh
index e82e48a9ca0..8bf1b20bc85 100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -1,7 +1,7 @@
# ltmain.sh - Provide generalized library-building support services.
# NOTE: Changing this file will not affect anything until you rerun configure.
#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
# Free Software Foundation, Inc.
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
@@ -49,14 +49,14 @@ EOF
fi
# The name of this program.
-progname=`$echo "$0" | sed 's%^.*/%%'`
+progname=`$echo "$0" | ${SED} 's%^.*/%%'`
modename="$progname"
# Constants.
PROGRAM=ltmain.sh
PACKAGE=libtool
-VERSION=1.4.2
-TIMESTAMP=" (1.922.2.53 2001/09/11 03:18:52)"
+VERSION=1.5
+TIMESTAMP=" (1.1220.2.1 2003/04/14 22:48:00)"
default_mode=
help="Try \`$progname --help' for more information."
@@ -67,10 +67,19 @@ rm="rm -f"
# Sed substitution that helps us do robust quoting. It backslashifies
# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e 1s/^X//'
+Xsed="${SED}"' -e 1s/^X//'
sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
-SP2NL='tr \040 \012'
-NL2SP='tr \015\012 \040\040'
+# test EBCDIC or ASCII
+case `echo A|od -x` in
+ *[Cc]1*) # EBCDIC based system
+ SP2NL="tr '\100' '\n'"
+ NL2SP="tr '\r\n' '\100\100'"
+ ;;
+ *) # Assume ASCII based system
+ SP2NL="tr '\040' '\012'"
+ NL2SP="tr '\015\012' '\040\040'"
+ ;;
+esac
# NLS nuisances.
# Only set LANG and LC_ALL to C if already set.
@@ -88,8 +97,8 @@ fi
: ${IFS=" "}
if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
- echo "$modename: not configured to build any kind of library" 1>&2
- echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ $echo "$modename: not configured to build any kind of library" 1>&2
+ $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
exit 1
fi
@@ -105,8 +114,51 @@ execute_dlfiles=
lo2o="s/\\.lo\$/.${objext}/"
o2lo="s/\\.${objext}\$/.lo/"
+#####################################
+# Shell function definitions:
+# This seems to be the best place for them
+
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+win32_libid () {
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
+ grep -E 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+ win32_nmres=`eval $NM -f posix -A $1 | \
+ sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'`
+ if test "X$win32_nmres" = "Ximport" ; then
+ win32_libid_type="x86 archive import"
+ else
+ win32_libid_type="x86 archive static"
+ fi
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $echo $win32_libid_type
+}
+
+# End of Shell function definitions
+#####################################
+
# Parse our command line options once, thoroughly.
-while test $# -gt 0
+while test "$#" -gt 0
do
arg="$1"
shift
@@ -122,6 +174,33 @@ do
execute_dlfiles)
execute_dlfiles="$execute_dlfiles $arg"
;;
+ tag)
+ tagname="$arg"
+
+ # Check whether tagname contains only valid characters
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ $echo "$progname: invalid tag name: $tagname" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case $tagname in
+ CC)
+ # Don't test for the "default" C tag, as we know, it's there, but
+ # not specially marked.
+ ;;
+ *)
+ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$0" > /dev/null; then
+ taglist="$taglist $tagname"
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $0`"
+ else
+ $echo "$progname: ignoring unknown tag $tagname" 1>&2
+ fi
+ ;;
+ esac
+ ;;
*)
eval "$prev=\$arg"
;;
@@ -139,17 +218,25 @@ do
;;
--version)
- echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+ $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+ $echo
+ $echo "Copyright (C) 2003 Free Software Foundation, Inc."
+ $echo "This is free software; see the source for copying conditions. There is NO"
+ $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
exit 0
;;
--config)
- sed -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0
+ ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$0"
+ done
exit 0
;;
--debug)
- echo "$progname: enabling shell trace mode"
+ $echo "$progname: enabling shell trace mode"
set -x
;;
@@ -158,16 +245,16 @@ do
;;
--features)
- echo "host: $host"
+ $echo "host: $host"
if test "$build_libtool_libs" = yes; then
- echo "enable shared libraries"
+ $echo "enable shared libraries"
else
- echo "disable shared libraries"
+ $echo "disable shared libraries"
fi
if test "$build_old_libs" = yes; then
- echo "enable static libraries"
+ $echo "enable static libraries"
else
- echo "disable static libraries"
+ $echo "disable static libraries"
fi
exit 0
;;
@@ -177,10 +264,19 @@ do
--mode) prevopt="--mode" prev=mode ;;
--mode=*) mode="$optarg" ;;
+ --preserve-dup-deps) duplicate_deps="yes" ;;
+
--quiet | --silent)
show=:
;;
+ --tag) prevopt="--tag" prev=tag ;;
+ --tag=*)
+ set tag "$optarg" ${1+"$@"}
+ shift
+ prev=tag
+ ;;
+
-dlopen)
prevopt="-dlopen"
prev=execute_dlfiles
@@ -214,8 +310,10 @@ if test -z "$show_help"; then
# Infer the operation mode.
if test -z "$mode"; then
+ $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
+ $echo "*** Future versions of Libtool will require -mode=MODE be specified." 1>&2
case $nonopt in
- *cc | *++ | gcc* | *-gcc*)
+ *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
mode=link
for arg
do
@@ -270,158 +368,127 @@ if test -z "$show_help"; then
modename="$modename: compile"
# Get the compilation command and the source file.
base_compile=
- prev=
- lastarg=
- srcfile="$nonopt"
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
suppress_output=
+ arg_mode=normal
+ libobj=
- user_target=no
for arg
do
- case $prev in
- "") ;;
- xcompiler)
- # Aesthetically quote the previous argument.
- prev=
- lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-
- case $arg in
- # Double-quote args containing other shell metacharacters.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
+ case "$arg_mode" in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
- # Add the previous argument to base_compile.
- if test -z "$base_compile"; then
- base_compile="$lastarg"
- else
- base_compile="$base_compile $lastarg"
- fi
+ target )
+ libobj="$arg"
+ arg_mode=normal
continue
;;
- esac
- # Accept any command-line options.
- case $arg in
- -o)
- if test "$user_target" != "no"; then
- $echo "$modename: you cannot specify \`-o' more than once" 1>&2
- exit 1
- fi
- user_target=next
- ;;
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ if test -n "$libobj" ; then
+ $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+ exit 1
+ fi
+ arg_mode=target
+ continue
+ ;;
- -static)
- build_old_libs=yes
- continue
- ;;
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
- -prefer-pic)
- pic_mode=yes
- continue
- ;;
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
- -prefer-non-pic)
- pic_mode=no
- continue
- ;;
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
- -Xcompiler)
- prev=xcompiler
- continue
- ;;
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
- -Wc,*)
- args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
- lastarg=
- save_ifs="$IFS"; IFS=','
- for arg in $args; do
- IFS="$save_ifs"
+ -Wc,*)
+ args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
- # Double-quote args containing other shell metacharacters.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- arg="\"$arg\""
- ;;
- esac
- lastarg="$lastarg $arg"
- done
- IFS="$save_ifs"
- lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ lastarg="$lastarg $arg"
+ done
+ IFS="$save_ifs"
+ lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
- # Add the arguments to base_compile.
- if test -z "$base_compile"; then
- base_compile="$lastarg"
- else
+ # Add the arguments to base_compile.
base_compile="$base_compile $lastarg"
- fi
- continue
- ;;
- esac
+ continue
+ ;;
- case $user_target in
- next)
- # The next one is the -o target name
- user_target=yes
- continue
- ;;
- yes)
- # We got the output file
- user_target=set
- libobj="$arg"
- continue
+ * )
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
;;
- esac
-
- # Accept the current argument as the source file.
- lastarg="$srcfile"
- srcfile="$arg"
+ esac # case $arg_mode
# Aesthetically quote the previous argument.
-
- # Backslashify any backslashes, double quotes, and dollar signs.
- # These are the only characters that are still specially
- # interpreted inside of double-quoted scrings.
lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+ case $lastarg in
# Double-quote args containing other shell metacharacters.
# Many Bourne shells cannot handle close brackets correctly
# in scan sets, so we specify it separately.
- case $lastarg in
*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
lastarg="\"$lastarg\""
;;
esac
- # Add the previous argument to base_compile.
- if test -z "$base_compile"; then
- base_compile="$lastarg"
- else
- base_compile="$base_compile $lastarg"
- fi
- done
+ base_compile="$base_compile $lastarg"
+ done # for arg
- case $user_target in
- set)
- ;;
- no)
- # Get the name of the library object.
- libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ case $arg_mode in
+ arg)
+ $echo "$modename: you must specify an argument for -Xcompile"
+ exit 1
;;
- *)
+ target)
$echo "$modename: you must specify a target with \`-o'" 1>&2
exit 1
;;
+ *)
+ # Get the name of the library object.
+ [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ ;;
esac
# Recognize several different file suffixes.
# If the user specifies -o file.o, it is replaced with file.lo
- xform='[cCFSfmso]'
+ xform='[cCFSifmso]'
case $libobj in
*.ada) xform=ada ;;
*.adb) xform=adb ;;
@@ -429,10 +496,13 @@ if test -z "$show_help"; then
*.asm) xform=asm ;;
*.c++) xform=c++ ;;
*.cc) xform=cc ;;
+ *.ii) xform=ii ;;
+ *.class) xform=class ;;
*.cpp) xform=cpp ;;
*.cxx) xform=cxx ;;
*.f90) xform=f90 ;;
*.for) xform=for ;;
+ *.java) xform=java ;;
esac
libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
@@ -445,6 +515,56 @@ if test -z "$show_help"; then
;;
esac
+ # Infer tagged configuration to use if any are available and
+ # if one wasn't chosen via the "--tag" command line option.
+ # Only attempt this if the compiler in the base compile
+ # command doesn't match the default compiler.
+ if test -n "$available_tags" && test -z "$tagname"; then
+ case $base_compile in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`"
+ case "$base_compile " in
+ "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ $echo "$modename: unable to infer tagged configuration"
+ $echo "$modename: specify a tag with \`--tag'" 1>&2
+ exit 1
+# else
+# $echo "$modename: using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+
+ objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir=
+ else
+ xdir=$xdir/
+ fi
+ lobj=${xdir}$objdir/$objname
+
if test -z "$base_compile"; then
$echo "$modename: you must specify a compilation command" 1>&2
$echo "$help" 1>&2
@@ -453,9 +573,9 @@ if test -z "$show_help"; then
# Delete any leftover library objects.
if test "$build_old_libs" = yes; then
- removelist="$obj $libobj"
+ removelist="$obj $lobj $libobj ${libobj}T"
else
- removelist="$libobj"
+ removelist="$lobj $libobj ${libobj}T"
fi
$run $rm $removelist
@@ -467,7 +587,7 @@ if test -z "$show_help"; then
pic_mode=default
;;
esac
- if test $pic_mode = no && test "$deplibs_check_method" != pass_all; then
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
# non-PIC code in shared libraries is not supported
pic_mode=default
fi
@@ -480,6 +600,7 @@ if test -z "$show_help"; then
removelist="$removelist $output_obj $lockfile"
trap "$run $rm $removelist; exit 1" 1 2 15
else
+ output_obj=
need_locks=no
lockfile=
fi
@@ -493,7 +614,7 @@ if test -z "$show_help"; then
done
elif test "$need_locks" = warn; then
if test -f "$lockfile"; then
- echo "\
+ $echo "\
*** ERROR, $lockfile exists and contains:
`cat $lockfile 2>/dev/null`
@@ -507,56 +628,55 @@ compiler."
$run $rm $removelist
exit 1
fi
- echo $srcfile > "$lockfile"
+ $echo $srcfile > "$lockfile"
fi
if test -n "$fix_srcfile_path"; then
eval srcfile=\"$fix_srcfile_path\"
fi
+ $run $rm "$libobj" "${libobj}T"
+
+ # Create a libtool object file (analogous to a ".la" file),
+ # but don't create it if we're doing a dry run.
+ test -z "$run" && cat > ${libobj}T <<EOF
+# $libobj - a libtool object file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+EOF
+
# Only build a PIC object if we are building libtool libraries.
if test "$build_libtool_libs" = yes; then
# Without this assignment, base_compile gets emptied.
fbsd_hideous_sh_bug=$base_compile
if test "$pic_mode" != no; then
- # All platforms use -DPIC, to notify preprocessed assembler code.
- command="$base_compile $srcfile $pic_flag -DPIC"
+ command="$base_compile $srcfile $pic_flag"
else
# Don't build PIC code
command="$base_compile $srcfile"
fi
- if test "$build_old_libs" = yes; then
- lo_libobj="$libobj"
- dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$dir" = "X$libobj"; then
- dir="$objdir"
- else
- dir="$dir/$objdir"
- fi
- libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
- if test -d "$dir"; then
- $show "$rm $libobj"
- $run $rm $libobj
- else
- $show "$mkdir $dir"
- $run $mkdir $dir
- status=$?
- if test $status -ne 0 && test ! -d $dir; then
- exit $status
- fi
+ if test ! -d "${xdir}$objdir"; then
+ $show "$mkdir ${xdir}$objdir"
+ $run $mkdir ${xdir}$objdir
+ status=$?
+ if test "$status" -ne 0 && test ! -d "${xdir}$objdir"; then
+ exit $status
fi
fi
- if test "$compiler_o_lo" = yes; then
- output_obj="$libobj"
- command="$command -o $output_obj"
- elif test "$compiler_c_o" = yes; then
- output_obj="$obj"
- command="$command -o $output_obj"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ command="$command -o $lobj"
fi
- $run $rm "$output_obj"
+ $run $rm "$lobj" "$output_obj"
+
$show "$command"
if $run eval "$command"; then :
else
@@ -565,8 +685,8 @@ compiler."
fi
if test "$need_locks" = warn &&
- test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
- echo "\
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $echo "\
*** ERROR, $lockfile contains:
`cat $lockfile 2>/dev/null`
@@ -585,9 +705,9 @@ compiler."
fi
# Just move the object if needed, then go on to compile the next one
- if test x"$output_obj" != x"$libobj"; then
- $show "$mv $output_obj $libobj"
- if $run $mv $output_obj $libobj; then :
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ $show "$mv $output_obj $lobj"
+ if $run $mv $output_obj $lobj; then :
else
error=$?
$run $rm $removelist
@@ -595,48 +715,21 @@ compiler."
fi
fi
- # If we have no pic_flag, then copy the object into place and finish.
- if (test -z "$pic_flag" || test "$pic_mode" != default) &&
- test "$build_old_libs" = yes; then
- # Rename the .lo from within objdir to obj
- if test -f $obj; then
- $show $rm $obj
- $run $rm $obj
- fi
-
- $show "$mv $libobj $obj"
- if $run $mv $libobj $obj; then :
- else
- error=$?
- $run $rm $removelist
- exit $error
- fi
+ # Append the name of the PIC object to the libtool object file.
+ test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object='$objdir/$objname'
- xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$xdir" = "X$obj"; then
- xdir="."
- else
- xdir="$xdir"
- fi
- baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
- libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
- # Now arrange that obj and lo_libobj become the same file
- $show "(cd $xdir && $LN_S $baseobj $libobj)"
- if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
- # Unlock the critical section if it was locked
- if test "$need_locks" != no; then
- $run $rm "$lockfile"
- fi
- exit 0
- else
- error=$?
- $run $rm $removelist
- exit $error
- fi
- fi
+EOF
# Allow error messages only from the first compilation.
suppress_output=' >/dev/null 2>&1'
+ else
+ # No PIC object so indicate it doesn't exist in the libtool
+ # object file.
+ test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object=none
+
+EOF
fi
# Only build a position-dependent object if we build old libraries.
@@ -645,17 +738,15 @@ compiler."
# Don't build PIC code
command="$base_compile $srcfile"
else
- # All platforms use -DPIC, to notify preprocessed assembler code.
- command="$base_compile $srcfile $pic_flag -DPIC"
+ command="$base_compile $srcfile $pic_flag"
fi
if test "$compiler_c_o" = yes; then
command="$command -o $obj"
- output_obj="$obj"
fi
# Suppress compiler output if we already did a PIC compilation.
command="$command$suppress_output"
- $run $rm "$output_obj"
+ $run $rm "$obj" "$output_obj"
$show "$command"
if $run eval "$command"; then :
else
@@ -664,8 +755,8 @@ compiler."
fi
if test "$need_locks" = warn &&
- test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
- echo "\
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $echo "\
*** ERROR, $lockfile contains:
`cat $lockfile 2>/dev/null`
@@ -684,7 +775,7 @@ compiler."
fi
# Just move the object if needed
- if test x"$output_obj" != x"$obj"; then
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
$show "$mv $output_obj $obj"
if $run $mv $output_obj $obj; then :
else
@@ -694,23 +785,25 @@ compiler."
fi
fi
- # Create an invalid libtool object if no PIC, so that we do not
- # accidentally link it into a program.
- if test "$build_libtool_libs" != yes; then
- $show "echo timestamp > $libobj"
- $run eval "echo timestamp > \$libobj" || exit $?
- else
- # Move the .lo from within objdir
- $show "$mv $libobj $lo_libobj"
- if $run $mv $libobj $lo_libobj; then :
- else
- error=$?
- $run $rm $removelist
- exit $error
- fi
- fi
+ # Append the name of the non-PIC object the libtool object file.
+ # Only append if the libtool object file exists.
+ test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object='$objname'
+
+EOF
+ else
+ # Append the name of the non-PIC object the libtool object file.
+ # Only append if the libtool object file exists.
+ test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object=none
+
+EOF
fi
+ $run $mv "${libobj}T" "${libobj}"
+
# Unlock the critical section if it was locked
if test "$need_locks" != no; then
$run $rm "$lockfile"
@@ -727,7 +820,7 @@ compiler."
# It is impossible to link a dll without this setting, and
# we shouldn't force the makefile maintainer to figure out
# which system we are compiling for in order to pass an extra
- # flag for every libtool invokation.
+ # flag for every libtool invocation.
# allow_undefined=no
# FIXME: Unfortunately, there are problems with the above when trying
@@ -742,6 +835,7 @@ compiler."
;;
esac
libtool_args="$nonopt"
+ base_compile="$nonopt"
compile_command="$nonopt"
finalize_command="$nonopt"
@@ -757,6 +851,7 @@ compiler."
linker_flags=
dllsearchpath=
lib_search_path=`pwd`
+ inst_prefix_dir=
avoid_version=no
dlfiles=
@@ -771,6 +866,7 @@ compiler."
module=no
no_install=no
objs=
+ non_pic_objects=
prefer_static_libs=no
preload=no
prev=
@@ -782,6 +878,7 @@ compiler."
temp_rpath=
thread_safe=no
vinfo=
+ vinfo_number=no
# We need to know -static, to get the right output filenames.
for arg
@@ -812,8 +909,9 @@ compiler."
test -n "$old_archive_from_new_cmds" && build_old_libs=yes
# Go through the arguments, transforming them on the way.
- while test $# -gt 0; do
+ while test "$#" -gt 0; do
arg="$1"
+ base_compile="$base_compile $arg"
shift
case $arg in
*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
@@ -887,11 +985,123 @@ compiler."
prev=
continue
;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
release)
release="-$arg"
prev=
continue
;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat $save_arg`
+ do
+# moreargs="$moreargs $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ # If there is no directory component, then add one.
+ case $arg in
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
+ esac
+
+ if test -z "$pic_object" || \
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none && \
+ test "$non_pic_object" = none; then
+ $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Extract subdirectory from the argument.
+ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$arg"; then
+ xdir=
+ else
+ xdir="$xdir/"
+ fi
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ libobjs="$libobjs $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ non_pic_objects="$non_pic_objects $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if test -z "$run"; then
+ $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+ exit 1
+ else
+ # Dry-run case.
+
+ # Extract subdirectory from the argument.
+ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$arg"; then
+ xdir=
+ else
+ xdir="$xdir/"
+ fi
+
+ pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+ non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+ libobjs="$libobjs $pic_object"
+ non_pic_objects="$non_pic_objects $non_pic_object"
+ fi
+ fi
+ done
+ else
+ $echo "$modename: link input file \`$save_arg' does not exist"
+ exit 1
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
rpath | xrpath)
# We need an absolute path.
case $arg in
@@ -930,13 +1140,21 @@ compiler."
finalize_command="$finalize_command $wl$qarg"
continue
;;
+ xcclinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ compile_command="$compile_command $qarg"
+ finalize_command="$finalize_command $qarg"
+ continue
+ ;;
*)
eval "$prev=\"\$arg\""
prev=
continue
;;
esac
- fi # test -n $prev
+ fi # test -n "$prev"
prevarg="$arg"
@@ -988,11 +1206,16 @@ compiler."
continue
;;
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
# The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
# so, if we see these flags be careful not to treat them like -L
-L[A-Z][A-Z]*:*)
case $with_gcc/$host in
- no/*-*-irix*)
+ no/*-*-irix* | /*-*-irix*)
compile_command="$compile_command $arg"
finalize_command="$finalize_command $arg"
;;
@@ -1043,18 +1266,22 @@ compiler."
# These systems don't actually have a C library (as such)
test "X$arg" = "X-lc" && continue
;;
- *-*-openbsd*)
+ *-*-openbsd* | *-*-freebsd*)
# Do not include libc due to us having libc/libc_r.
test "X$arg" = "X-lc" && continue
;;
- esac
- elif test "X$arg" = "X-lc_r"; then
- case $host in
- *-*-openbsd*)
- # Do not include libc_r directly, use -pthread flag.
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ deplibs="$deplibs -framework System"
continue
- ;;
esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
fi
deplibs="$deplibs $arg"
continue
@@ -1065,6 +1292,34 @@ compiler."
continue
;;
+ # gcc -m* arguments should be passed to the linker via $compiler_flags
+ # in order to pass architecture information to the linker
+ # (e.g. 32 vs 64-bit). This may also be accomplished via -Wl,-mfoo
+ # but this is not reliable with gcc because gcc may use -mfoo to
+ # select a different linker, different libraries, etc, while
+ # -Wl,-mfoo simply passes -mfoo to the linker.
+ -m*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ if test "$with_gcc" = "yes" ; then
+ compiler_flags="$compiler_flags $arg"
+ fi
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
-no-fast-install)
fast_install=no
continue
@@ -1089,6 +1344,11 @@ compiler."
continue
;;
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
-o) prev=output ;;
-release)
@@ -1141,6 +1401,11 @@ compiler."
prev=vinfo
continue
;;
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
-Wc,*)
args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
@@ -1189,6 +1454,11 @@ compiler."
continue
;;
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
# Some other compiler flag.
-* | +*)
# Unknown arguments in both finalize_command and compile_command need
@@ -1201,29 +1471,101 @@ compiler."
esac
;;
- *.lo | *.$objext)
- # A library or standard object.
- if test "$prev" = dlfiles; then
- # This file was specified with -dlopen.
- if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
- dlfiles="$dlfiles $arg"
- prev=
- continue
- else
- # If libtool objects are unsupported, then we need to preload.
- prev=dlprefiles
- fi
- fi
+ *.$objext)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
- if test "$prev" = dlprefiles; then
- # Preload the old-style object.
- dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
- prev=
- else
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ # If there is no directory component, then add one.
case $arg in
- *.lo) libobjs="$libobjs $arg" ;;
- *) objs="$objs $arg" ;;
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
esac
+
+ if test -z "$pic_object" || \
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none && \
+ test "$non_pic_object" = none; then
+ $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Extract subdirectory from the argument.
+ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$arg"; then
+ xdir=
+ else
+ xdir="$xdir/"
+ fi
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ libobjs="$libobjs $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ non_pic_objects="$non_pic_objects $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if test -z "$run"; then
+ $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+ exit 1
+ else
+ # Dry-run case.
+
+ # Extract subdirectory from the argument.
+ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$arg"; then
+ xdir=
+ else
+ xdir="$xdir/"
+ fi
+
+ pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+ non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+ libobjs="$libobjs $pic_object"
+ non_pic_objects="$non_pic_objects $non_pic_object"
+ fi
fi
;;
@@ -1277,12 +1619,54 @@ compiler."
exit 1
fi
+ # Infer tagged configuration to use if any are available and
+ # if one wasn't chosen via the "--tag" command line option.
+ # Only attempt this if the compiler in the base link
+ # command doesn't match the default compiler.
+ if test -n "$available_tags" && test -z "$tagname"; then
+ case $base_compile in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`"
+ case $base_compile in
+ "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*)
+ # The compiler in $compile_command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ $echo "$modename: unable to infer tagged configuration"
+ $echo "$modename: specify a tag with \`--tag'" 1>&2
+ exit 1
+# else
+# $echo "$modename: using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+
if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
eval arg=\"$export_dynamic_flag_spec\"
compile_command="$compile_command $arg"
finalize_command="$finalize_command $arg"
fi
+ oldlibs=
# calculate the name of the file, without its directory
outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
libobjs_save="$libobjs"
@@ -1303,11 +1687,11 @@ compiler."
output_objdir="$output_objdir/$objdir"
fi
# Create the object directory.
- if test ! -d $output_objdir; then
+ if test ! -d "$output_objdir"; then
$show "$mkdir $output_objdir"
$run $mkdir $output_objdir
status=$?
- if test $status -ne 0 && test ! -d $output_objdir; then
+ if test "$status" -ne 0 && test ! -d "$output_objdir"; then
exit $status
fi
fi
@@ -1325,16 +1709,47 @@ compiler."
*) linkmode=prog ;; # Anything else should be a program.
esac
+ case $host in
+ *cygwin* | *mingw* | *pw32*)
+ # don't eliminate duplcations in $postdeps and $predeps
+ duplicate_compiler_generated_deps=yes
+ ;;
+ *)
+ duplicate_compiler_generated_deps=$duplicate_deps
+ ;;
+ esac
specialdeplibs=
+
libs=
# Find all interdependent deplibs by searching for libraries
# that are linked more than once (e.g. -la -lb -la)
for deplib in $deplibs; do
- case "$libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
libs="$libs $deplib"
done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+ esac
+ pre_post_deps="$pre_post_deps $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
deplibs=
newdependency_libs=
newlib_search_path=
@@ -1366,28 +1781,33 @@ compiler."
;;
esac
for pass in $passes; do
- if test $linkmode = prog; then
- # Determine which files to process
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
case $pass in
- dlopen)
- libs="$dlfiles"
- save_deplibs="$deplibs" # Collect dlpreopened libraries
- deplibs=
- ;;
+ dlopen) libs="$dlfiles" ;;
dlpreopen) libs="$dlprefiles" ;;
link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
esac
fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
for deplib in $libs; do
lib=
found=no
case $deplib in
-l*)
- if test $linkmode = oldlib && test $linkmode = obj; then
- $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
continue
fi
- if test $pass = conv; then
+ if test "$pass" = conv; then
deplibs="$deplib $deplibs"
continue
fi
@@ -1407,25 +1827,61 @@ compiler."
finalize_deplibs="$deplib $finalize_deplibs"
else
deplibs="$deplib $deplibs"
- test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
fi
continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if (${SED} -e '2q' $lib |
+ grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ library_names=
+ old_library=
+ case $lib in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$ladir" = "X$lib" && ladir="."
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
fi
;; # -l
-L*)
case $linkmode in
lib)
deplibs="$deplib $deplibs"
- test $pass = conv && continue
+ test "$pass" = conv && continue
newdependency_libs="$deplib $newdependency_libs"
newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
;;
prog)
- if test $pass = conv; then
+ if test "$pass" = conv; then
deplibs="$deplib $deplibs"
continue
fi
- if test $pass = scan; then
+ if test "$pass" = scan; then
deplibs="$deplib $deplibs"
newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
else
@@ -1434,13 +1890,13 @@ compiler."
fi
;;
*)
- $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2
+ $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
;;
esac # linkmode
continue
;; # -L
-R*)
- if test $pass = link; then
+ if test "$pass" = link; then
dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
# Make sure the xrpath contains only unique directories.
case "$xrpath " in
@@ -1453,28 +1909,30 @@ compiler."
;;
*.la) lib="$deplib" ;;
*.$libext)
- if test $pass = conv; then
+ if test "$pass" = conv; then
deplibs="$deplib $deplibs"
continue
fi
case $linkmode in
lib)
if test "$deplibs_check_method" != pass_all; then
- echo
- echo "*** Warning: This library needs some functionality provided by $deplib."
- echo "*** I have the capability to make that library automatically link in when"
- echo "*** you link to this library. But I can only do this if you have a"
- echo "*** shared version of the library, which you do not appear to have."
+ $echo
+ $echo "*** Warning: Trying to link with static lib archive $deplib."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have"
+ $echo "*** because the file extensions .$libext of this argument makes me believe"
+ $echo "*** that it is just a static archive that I should not used here."
else
- echo
- echo "*** Warning: Linking the shared library $output against the"
- echo "*** static library $deplib is not portable!"
+ $echo
+ $echo "*** Warning: Linking the shared library $output against the"
+ $echo "*** static library $deplib is not portable!"
deplibs="$deplib $deplibs"
fi
continue
;;
prog)
- if test $pass != link; then
+ if test "$pass" != link; then
deplibs="$deplib $deplibs"
else
compile_deplibs="$deplib $compile_deplibs"
@@ -1485,14 +1943,18 @@ compiler."
esac # linkmode
;; # *.$libext
*.lo | *.$objext)
- if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
- # If there is no dlopen support or we're linking statically,
- # we need to preload.
- newdlprefiles="$newdlprefiles $deplib"
- compile_deplibs="$deplib $compile_deplibs"
- finalize_deplibs="$deplib $finalize_deplibs"
- else
- newdlfiles="$newdlfiles $deplib"
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ newdlprefiles="$newdlprefiles $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ newdlfiles="$newdlfiles $deplib"
+ fi
fi
continue
;;
@@ -1501,14 +1963,14 @@ compiler."
continue
;;
esac # case $deplib
- if test $found = yes || test -f "$lib"; then :
+ if test "$found" = yes || test -f "$lib"; then :
else
$echo "$modename: cannot find the library \`$lib'" 1>&2
exit 1
fi
# Check to see that this really is a libtool archive.
- if (sed -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
else
$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
exit 1
@@ -1524,8 +1986,9 @@ compiler."
library_names=
old_library=
# If the library was installed with an old release of libtool,
- # it will not redefine variable installed.
+ # it will not redefine variables installed, or shouldnotlink
installed=yes
+ shouldnotlink=no
# Read the .la file
case $lib in
@@ -1535,13 +1998,12 @@ compiler."
if test "$linkmode,$pass" = "lib,link" ||
test "$linkmode,$pass" = "prog,scan" ||
- { test $linkmode = oldlib && test $linkmode = obj; }; then
- # Add dl[pre]opened files of deplib
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
fi
- if test $pass = conv; then
+ if test "$pass" = conv; then
# Only check for convenience libraries
deplibs="$lib $deplibs"
if test -z "$libdir"; then
@@ -1555,18 +2017,21 @@ compiler."
tmp_libs=
for deplib in $dependency_libs; do
deplibs="$deplib $deplibs"
- case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
tmp_libs="$tmp_libs $deplib"
done
- elif test $linkmode != prog && test $linkmode != lib; then
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
$echo "$modename: \`$lib' is not a convenience library" 1>&2
exit 1
fi
continue
fi # $pass = conv
+
# Get the name of the library we link against.
linklib=
for l in $old_library $library_names; do
@@ -1578,15 +2043,17 @@ compiler."
fi
# This library was specified with -dlopen.
- if test $pass = dlopen; then
+ if test "$pass" = dlopen; then
if test -z "$libdir"; then
$echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
exit 1
fi
if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
# If there is no dlname, no dlopen support or we're linking
- # statically, we need to preload.
- dlprefiles="$dlprefiles $lib"
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ dlprefiles="$dlprefiles $lib $dependency_libs"
else
newdlfiles="$newdlfiles $lib"
fi
@@ -1627,7 +2094,7 @@ compiler."
name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
# This library was specified with -dlpreopen.
- if test $pass = dlpreopen; then
+ if test "$pass" = dlpreopen; then
if test -z "$libdir"; then
$echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
exit 1
@@ -1646,18 +2113,19 @@ compiler."
if test -z "$libdir"; then
# Link the convenience library
- if test $linkmode = lib; then
+ if test "$linkmode" = lib; then
deplibs="$dir/$old_library $deplibs"
elif test "$linkmode,$pass" = "prog,link"; then
compile_deplibs="$dir/$old_library $compile_deplibs"
finalize_deplibs="$dir/$old_library $finalize_deplibs"
else
- deplibs="$lib $deplibs"
+ deplibs="$lib $deplibs" # used for prog,scan pass
fi
continue
fi
- if test $linkmode = prog && test $pass != link; then
+
+ if test "$linkmode" = prog && test "$pass" != link; then
newlib_search_path="$newlib_search_path $ladir"
deplibs="$lib $deplibs"
@@ -1673,28 +2141,36 @@ compiler."
-L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
esac
# Need to link against all dependency_libs?
- if test $linkalldeplibs = yes; then
+ if test "$linkalldeplibs" = yes; then
deplibs="$deplib $deplibs"
else
# Need to hardcode shared library paths
# or/and link against static libraries
newdependency_libs="$deplib $newdependency_libs"
fi
- case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
tmp_libs="$tmp_libs $deplib"
done # for deplib
continue
fi # $linkmode = prog...
- link_static=no # Whether the deplib will be linked statically
- if test -n "$library_names" &&
- { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
- # Link against this shared library
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *" $absdir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
- if test "$linkmode,$pass" = "prog,link" ||
- { test $linkmode = lib && test $hardcode_into_libs = yes; }; then
# Hardcode the library path.
# Skip directories that are in the system default run-time
# search path.
@@ -1716,17 +2192,6 @@ compiler."
esac
;;
esac
- if test $linkmode = prog; then
- # We need to hardcode the library path
- if test -n "$shlibpath_var"; then
- # Make sure the rpath contains only unique directories.
- case "$temp_rpath " in
- *" $dir "*) ;;
- *" $absdir "*) ;;
- *) temp_rpath="$temp_rpath $dir" ;;
- esac
- fi
- fi
fi # $linkmode,$pass = prog,link...
if test "$alldeplibs" = yes &&
@@ -1736,11 +2201,51 @@ compiler."
# We only need to search for static libraries
continue
fi
+ fi
+ link_static=no # Whether the deplib will be linked statically
+ if test -n "$library_names" &&
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
if test "$installed" = no; then
notinst_deplibs="$notinst_deplibs $lib"
need_relink=yes
fi
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some systems (darwin)
+ if test "$shouldnotlink" = yes && test "$pass" = link ; then
+ $echo
+ if test "$linkmode" = prog; then
+ $echo "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $echo "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $echo "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi
if test -n "$old_archive_from_expsyms_cmds"; then
# figure out the soname
@@ -1754,7 +2259,7 @@ compiler."
elif test -n "$soname_spec"; then
# bleh windows
case $host in
- *cygwin*)
+ *cygwin* | mingw*)
major=`expr $current - $age`
versuffix="-$major"
;;
@@ -1766,8 +2271,8 @@ compiler."
# Make a new name for the extract_expsyms_cmds to use
soroot="$soname"
- soname=`echo $soroot | sed -e 's/^.*\///'`
- newlib="libimp-`echo $soname | sed 's/^lib//;s/\.dll$//'`.a"
+ soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
+ newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
# If the library has no export list, then create one now
if test -f "$output_objdir/$soname-def"; then :
@@ -1798,9 +2303,9 @@ compiler."
# make sure the library variables are pointing to the new library
dir=$output_objdir
linklib=$newlib
- fi # test -n $old_archive_from_expsyms_cmds
+ fi # test -n "$old_archive_from_expsyms_cmds"
- if test $linkmode = prog || test "$mode" != relink; then
+ if test "$linkmode" = prog || test "$mode" != relink; then
add_shlibpath=
add_dir=
add=
@@ -1809,6 +2314,22 @@ compiler."
immediate | unsupported)
if test "$hardcode_direct" = no; then
add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5* ) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a module then we can not link against it, someone
+ # is ignoring the new warnings I added
+ if /usr/bin/file -L $add 2> /dev/null | grep "bundle" >/dev/null ; then
+ $echo "** Warning, lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ $echo
+ $echo "** And there doesn't seem to be a static archive available"
+ $echo "** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
elif test "$hardcode_minus_L" = no; then
case $host in
*-*-sunos*) add_shlibpath="$dir" ;;
@@ -1827,6 +2348,14 @@ compiler."
add="$dir/$linklib"
elif test "$hardcode_minus_L" = yes; then
add_dir="-L$dir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case "$libdir" in
+ [\\/]*)
+ add_dir="-L$inst_prefix_dir$libdir $add_dir"
+ ;;
+ esac
+ fi
add="-l$name"
elif test "$hardcode_shlibpath_var" = yes; then
add_shlibpath="$dir"
@@ -1849,7 +2378,7 @@ compiler."
*) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
esac
fi
- if test $linkmode = prog; then
+ if test "$linkmode" = prog; then
test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
test -n "$add" && compile_deplibs="$add $compile_deplibs"
else
@@ -1866,7 +2395,7 @@ compiler."
fi
fi
- if test $linkmode = prog || test "$mode" = relink; then
+ if test "$linkmode" = prog || test "$mode" = relink; then
add_shlibpath=
add_dir=
add=
@@ -1882,17 +2411,27 @@ compiler."
*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
esac
add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
else
# We cannot seem to hardcode it, guess we'll fake it.
- if test "X$installed" = Xyes; then
- add_dir="-L$libdir"
- else
- add_dir="-L$DESTDIR$libdir"
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case "$libdir" in
+ [\\/]*)
+ add_dir="-L$inst_prefix_dir$libdir $add_dir"
+ ;;
+ esac
fi
add="-l$name"
fi
- if test $linkmode = prog; then
+ if test "$linkmode" = prog; then
test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
else
@@ -1900,16 +2439,7 @@ compiler."
test -n "$add" && deplibs="$add $deplibs"
fi
fi
- elif test $linkmode = prog; then
- if test "$alldeplibs" = yes &&
- { test "$deplibs_check_method" = pass_all ||
- { test "$build_libtool_libs" = yes &&
- test -n "$library_names"; }; }; then
- # We only need to search for static libraries
- continue
- fi
-
- # Try to link the static library
+ elif test "$linkmode" = prog; then
# Here we assume that one of hardcode_direct or hardcode_minus_L
# is not unsupported. This is valid on all known static and
# shared platforms.
@@ -1929,20 +2459,21 @@ compiler."
# Just print a warning and add the library to dependency_libs so
# that the program can be linked against the static library.
- echo
- echo "*** Warning: This library needs some functionality provided by $lib."
- echo "*** I have the capability to make that library automatically link in when"
- echo "*** you link to this library. But I can only do this if you have a"
- echo "*** shared version of the library, which you do not appear to have."
+ $echo
+ $echo "*** Warning: This system can not link to static lib archive $lib."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have."
if test "$module" = yes; then
- echo "*** Therefore, libtool will create a static module, that should work "
- echo "*** as long as the dlopening application is linked with the -dlopen flag."
+ $echo "*** But as you try to build a module library, libtool will still create "
+ $echo "*** a static module, that should work as long as the dlopening application"
+ $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
if test -z "$global_symbol_pipe"; then
- echo
- echo "*** However, this would only work if libtool was able to extract symbol"
- echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
- echo "*** not find such a program. So, this module is probably useless."
- echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ $echo
+ $echo "*** However, this would only work if libtool was able to extract symbol"
+ $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $echo "*** not find such a program. So, this module is probably useless."
+ $echo "*** \`nm' from GNU binutils and a full rebuild may help."
fi
if test "$build_old_libs" = no; then
build_libtool_libs=module
@@ -1959,10 +2490,10 @@ compiler."
fi
fi # link shared/static library?
- if test $linkmode = lib; then
+ if test "$linkmode" = lib; then
if test -n "$dependency_libs" &&
- { test $hardcode_into_libs != yes || test $build_old_libs = yes ||
- test $link_static = yes; }; then
+ { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
# Extract -R from dependency_libs
temp_deplibs=
for libdir in $dependency_libs; do
@@ -1985,13 +2516,15 @@ compiler."
tmp_libs=
for deplib in $dependency_libs; do
newdependency_libs="$deplib $newdependency_libs"
- case "$tmp_libs " in
- *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
- esac
+ if test "X$duplicate_deps" = "Xyes" ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
tmp_libs="$tmp_libs $deplib"
done
- if test $link_all_deplibs != no; then
+ if test "$link_all_deplibs" != no; then
# Add the search paths of all dependency libraries
for deplib in $dependency_libs; do
case $deplib in
@@ -2011,9 +2544,9 @@ compiler."
;;
esac
if grep "^installed=no" $deplib > /dev/null; then
- path="-L$absdir/$objdir"
+ path="$absdir/$objdir"
else
- eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
if test -z "$libdir"; then
$echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
exit 1
@@ -2021,12 +2554,53 @@ compiler."
if test "$absdir" != "$libdir"; then
$echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
fi
- path="-L$absdir"
+ path="$absdir"
fi
+ depdepl=
+ case $host in
+ *-*-darwin*)
+ # we do not want to link against static libs, but need to link against shared
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$path/$depdepl" ; then
+ depdepl="$path/$depdepl"
+ fi
+ newlib_search_path="$newlib_search_path $path"
+ path=""
+ fi
+ ;;
+ *)
+ path="-L$path"
+ ;;
+ esac
+
+ ;;
+ -l*)
+ case $host in
+ *-*-darwin*)
+ # Again, we only want to link against shared libraries
+ eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
+ for tmp in $newlib_search_path ; do
+ if test -f "$tmp/lib$tmp_libs.dylib" ; then
+ eval depdepl="$tmp/lib$tmp_libs.dylib"
+ break
+ fi
+ done
+ path=""
+ ;;
+ *) continue ;;
+ esac
;;
*) continue ;;
esac
case " $deplibs " in
+ *" $depdepl "*) ;;
+ *) deplibs="$deplibs $depdepl" ;;
+ esac
+ case " $deplibs " in
*" $path "*) ;;
*) deplibs="$deplibs $path" ;;
esac
@@ -2034,15 +2608,15 @@ compiler."
fi # link_all_deplibs != no
fi # linkmode = lib
done # for deplib in $libs
- if test $pass = dlpreopen; then
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
# Link the dlpreopened libraries before other libraries
for deplib in $save_deplibs; do
deplibs="$deplib $deplibs"
done
fi
- if test $pass != dlopen; then
- test $pass != scan && dependency_libs="$newdependency_libs"
- if test $pass != conv; then
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
# Make sure lib_search_path contains only unique directories.
lib_search_path=
for dir in $newlib_search_path; do
@@ -2064,9 +2638,30 @@ compiler."
eval tmp_libs=\"\$$var\"
new_libs=
for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
case $deplib in
-L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
*)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
case " $specialdeplibs " in
*" $deplib "*) new_libs="$deplib $new_libs" ;;
*)
@@ -2094,19 +2689,31 @@ compiler."
eval $var=\"$tmp_libs\"
done # for var
fi
- if test "$pass" = "conv" &&
- { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then
- libs="$deplibs" # reset libs
- deplibs=
- fi
+ # Last step: remove runtime libs from dependency_libs (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ tmp_libs="$tmp_libs $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
done # for pass
- if test $linkmode = prog; then
+ if test "$linkmode" = prog; then
dlfiles="$newdlfiles"
dlprefiles="$newdlprefiles"
fi
case $linkmode in
oldlib)
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+ fi
+
if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
fi
@@ -2120,7 +2727,7 @@ compiler."
fi
if test -n "$vinfo"; then
- $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+ $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
fi
if test -n "$release"; then
@@ -2142,6 +2749,7 @@ compiler."
case $outputname in
lib*)
name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval shared_ext=\"$shrext\"
eval libname=\"$libname_spec\"
;;
*)
@@ -2153,6 +2761,7 @@ compiler."
if test "$need_lib_prefix" != no; then
# Add the "lib" prefix for modules if required
name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ eval shared_ext=\"$shrext\"
eval libname=\"$libname_spec\"
else
libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
@@ -2165,9 +2774,9 @@ compiler."
$echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
exit 1
else
- echo
- echo "*** Warning: Linking the shared library $output against the non-libtool"
- echo "*** objects $objs is not portable!"
+ $echo
+ $echo "*** Warning: Linking the shared library $output against the non-libtool"
+ $echo "*** objects $objs is not portable!"
libobjs="$libobjs $objs"
fi
fi
@@ -2177,7 +2786,7 @@ compiler."
fi
set dummy $rpath
- if test $# -gt 2; then
+ if test "$#" -gt 2; then
$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
fi
install_libdir="$2"
@@ -2186,14 +2795,16 @@ compiler."
if test -z "$rpath"; then
if test "$build_libtool_libs" = yes; then
# Building a libtool convenience library.
- libext=al
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
oldlibs="$output_objdir/$libname.$libext $oldlibs"
build_libtool_libs=convenience
build_old_libs=yes
fi
if test -n "$vinfo"; then
- $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+ $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
fi
if test -n "$release"; then
@@ -2212,9 +2823,46 @@ compiler."
exit 1
fi
- current="$2"
- revision="$3"
- age="$4"
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$2"
+ number_minor="$3"
+ number_revision="$4"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ darwin|linux|osf|windows)
+ current=`expr $number_major + $number_minor`
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ current=`expr $number_major + $number_minor - 1`
+ age="$number_minor"
+ revision="$number_minor"
+ ;;
+ esac
+ ;;
+ no)
+ current="$2"
+ revision="$3"
+ age="$4"
+ ;;
+ esac
# Check that each of the things are valid numbers.
case $current in
@@ -2244,7 +2892,7 @@ compiler."
;;
esac
- if test $age -gt $current; then
+ if test "$age" -gt "$current"; then
$echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
$echo "$modename: \`$vinfo' is not valid version information" 1>&2
exit 1
@@ -2277,16 +2925,21 @@ compiler."
versuffix=".$current";
;;
- irix)
+ irix | nonstopux)
major=`expr $current - $age + 1`
- verstring="sgi$major.$revision"
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
# Add in all the interfaces that we are compatible with.
loop=$revision
- while test $loop != 0; do
+ while test "$loop" -ne 0; do
iface=`expr $revision - $loop`
loop=`expr $loop - 1`
- verstring="sgi$major.$iface:$verstring"
+ verstring="$verstring_prefix$major.$iface:$verstring"
done
# Before this point, $major must not contain `.'.
@@ -2300,13 +2953,13 @@ compiler."
;;
osf)
- major=`expr $current - $age`
+ major=.`expr $current - $age`
versuffix=".$current.$age.$revision"
verstring="$current.$age.$revision"
# Add in all the interfaces that we are compatible with.
loop=$age
- while test $loop != 0; do
+ while test "$loop" -ne 0; do
iface=`expr $current - $loop`
loop=`expr $loop - 1`
verstring="$verstring:${iface}.0"
@@ -2330,7 +2983,7 @@ compiler."
*)
$echo "$modename: unknown library version type \`$version_type'" 1>&2
- echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
exit 1
;;
esac
@@ -2338,12 +2991,11 @@ compiler."
# Clear the version info if we defaulted, and they specified a release.
if test -z "$vinfo" && test -n "$release"; then
major=
- verstring="0.0"
case $version_type in
darwin)
# we can't check for "0.0" in archive_cmds due to quoting
# problems, so we reset it completely
- verstring=""
+ verstring=
;;
*)
verstring="0.0"
@@ -2377,9 +3029,24 @@ compiler."
fi
if test "$mode" != relink; then
- # Remove our outputs.
- $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
- $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$echo "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ removelist="$removelist $p"
+ ;;
+ *) ;;
+ esac
+ done
+ if test -n "$removelist"; then
+ $show "${rm}r $removelist"
+ $run ${rm}r $removelist
+ fi
fi
# Now set the variables for building old libraries.
@@ -2392,9 +3059,9 @@ compiler."
# Eliminate all temporary directories.
for path in $notinst_path; do
- lib_search_path=`echo "$lib_search_path " | sed -e 's% $path % %g'`
- deplibs=`echo "$deplibs " | sed -e 's% -L$path % %g'`
- dependency_libs=`echo "$dependency_libs " | sed -e 's% -L$path % %g'`
+ lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'`
+ deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'`
+ dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'`
done
if test -n "$xrpath"; then
@@ -2407,7 +3074,7 @@ compiler."
*) finalize_rpath="$finalize_rpath $libdir" ;;
esac
done
- if test $hardcode_into_libs != yes || test $build_old_libs = yes; then
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
dependency_libs="$temp_xrpath $dependency_libs"
fi
fi
@@ -2445,12 +3112,13 @@ compiler."
*-*-netbsd*)
# Don't link with libc until the a.out ld.so is fixed.
;;
- *-*-openbsd*)
+ *-*-openbsd* | *-*-freebsd*)
# Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
;;
- *)
+ *)
# Add libc to deplibs on all other systems if necessary.
- if test $build_libtool_need_lc = "yes"; then
+ if test "$build_libtool_need_lc" = "yes"; then
deplibs="$deplibs -lc"
fi
;;
@@ -2477,7 +3145,7 @@ compiler."
# This might be a little naive. We might want to check
# whether the library exists or not. But this is on
# osf3 & osf4 and I'm not really sure... Just
- # implementing what was already the behaviour.
+ # implementing what was already the behavior.
newdeplibs=$deplibs
;;
test_compile)
@@ -2490,64 +3158,88 @@ compiler."
int main() { return 0; }
EOF
$rm conftest
- $CC -o conftest conftest.c $deplibs
- if test $? -eq 0 ; then
+ $LTCC -o conftest conftest.c $deplibs
+ if test "$?" -eq 0 ; then
ldd_output=`ldd conftest`
for i in $deplibs; do
name="`expr $i : '-l\(.*\)'`"
# If $name is empty we are operating on a -L argument.
- if test -n "$name" && test "$name" != "0"; then
- libname=`eval \\$echo \"$libname_spec\"`
- deplib_matches=`eval \\$echo \"$library_names_spec\"`
- set dummy $deplib_matches
- deplib_match=$2
- if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
- newdeplibs="$newdeplibs $i"
- else
- droppeddeps=yes
- echo
- echo "*** Warning: This library needs some functionality provided by $i."
- echo "*** I have the capability to make that library automatically link in when"
- echo "*** you link to this library. But I can only do this if you have a"
- echo "*** shared version of the library, which you do not appear to have."
+ if test "$name" != "" && test "$name" -ne "0"; then
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $echo
+ $echo "*** Warning: dynamic linker does not accept needed library $i."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which I believe you do not have"
+ $echo "*** because a test_compile did reveal that the linker did not use it for"
+ $echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
fi
else
newdeplibs="$newdeplibs $i"
fi
done
else
- # Error occured in the first compile. Let's try to salvage the situation:
- # Compile a seperate program for each library.
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
for i in $deplibs; do
name="`expr $i : '-l\(.*\)'`"
- # If $name is empty we are operating on a -L argument.
- if test -n "$name" && test "$name" != "0"; then
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" && test "$name" != "0"; then
$rm conftest
- $CC -o conftest conftest.c $i
+ $LTCC -o conftest conftest.c $i
# Did it work?
- if test $? -eq 0 ; then
+ if test "$?" -eq 0 ; then
ldd_output=`ldd conftest`
- libname=`eval \\$echo \"$libname_spec\"`
- deplib_matches=`eval \\$echo \"$library_names_spec\"`
- set dummy $deplib_matches
- deplib_match=$2
- if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
- newdeplibs="$newdeplibs $i"
- else
- droppeddeps=yes
- echo
- echo "*** Warning: This library needs some functionality provided by $i."
- echo "*** I have the capability to make that library automatically link in when"
- echo "*** you link to this library. But I can only do this if you have a"
- echo "*** shared version of the library, which you do not appear to have."
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $echo
+ $echo "*** Warning: dynamic linker does not accept needed library $i."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have"
+ $echo "*** because a test_compile did reveal that the linker did not use this one"
+ $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
fi
else
droppeddeps=yes
- echo
- echo "*** Warning! Library $i is needed by this library but I was not able to"
- echo "*** make it link in! You will probably need to install it or some"
- echo "*** library that it depends on before this library will be fully"
- echo "*** functional. Installing it before continuing would be even better."
+ $echo
+ $echo "*** Warning! Library $i is needed by this library but I was not able to"
+ $echo "*** make it link in! You will probably need to install it or some"
+ $echo "*** library that it depends on before this library will be fully"
+ $echo "*** functional. Installing it before continuing would be even better."
fi
else
newdeplibs="$newdeplibs $i"
@@ -2561,11 +3253,20 @@ EOF
for a_deplib in $deplibs; do
name="`expr $a_deplib : '-l\(.*\)'`"
# If $name is empty we are operating on a -L argument.
- if test -n "$name" && test "$name" != "0"; then
- libname=`eval \\$echo \"$libname_spec\"`
- for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
- potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
- for potent_lib in $potential_libs; do
+ if test "$name" != "" && test "$name" != "0"; then
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
# Follow soft links.
if ls -lLd "$potent_lib" 2>/dev/null \
| grep " -> " >/dev/null; then
@@ -2578,28 +3279,36 @@ EOF
# but so what?
potlib="$potent_lib"
while test -h "$potlib" 2>/dev/null; do
- potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
case $potliblink in
[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
esac
done
if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
- | sed 10q \
- | egrep "$file_magic_regex" > /dev/null; then
+ | ${SED} 10q \
+ | $EGREP "$file_magic_regex" > /dev/null; then
newdeplibs="$newdeplibs $a_deplib"
a_deplib=""
break 2
fi
- done
- done
+ done
+ done
+ fi
if test -n "$a_deplib" ; then
droppeddeps=yes
- echo
- echo "*** Warning: This library needs some functionality provided by $a_deplib."
- echo "*** I have the capability to make that library automatically link in when"
- echo "*** you link to this library. But I can only do this if you have a"
- echo "*** shared version of the library, which you do not appear to have."
+ $echo
+ $echo "*** Warning: linker path does not have real file for library $a_deplib."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have"
+ $echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $echo "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $echo "*** with $libname and none of the candidates passed a file format test"
+ $echo "*** using a file magic. Last file checked: $potlib"
+ fi
fi
else
# Add a -L argument.
@@ -2614,26 +3323,44 @@ EOF
name="`expr $a_deplib : '-l\(.*\)'`"
# If $name is empty we are operating on a -L argument.
if test -n "$name" && test "$name" != "0"; then
- libname=`eval \\$echo \"$libname_spec\"`
- for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
- potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
- for potent_lib in $potential_libs; do
- if eval echo \"$potent_lib\" 2>/dev/null \
- | sed 10q \
- | egrep "$match_pattern_regex" > /dev/null; then
- newdeplibs="$newdeplibs $a_deplib"
- a_deplib=""
- break 2
- fi
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval $echo \"$potent_lib\" 2>/dev/null \
+ | ${SED} 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
done
- done
+ fi
if test -n "$a_deplib" ; then
droppeddeps=yes
- echo
- echo "*** Warning: This library needs some functionality provided by $a_deplib."
- echo "*** I have the capability to make that library automatically link in when"
- echo "*** you link to this library. But I can only do this if you have a"
- echo "*** shared version of the library, which you do not appear to have."
+ $echo
+ $echo "*** Warning: linker path does not have real file for library $a_deplib."
+ $echo "*** I have the capability to make that library automatically link in when"
+ $echo "*** you link to this library. But I can only do this if you have a"
+ $echo "*** shared version of the library, which you do not appear to have"
+ $echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $echo "*** with $libname and none of the candidates passed a file format test"
+ $echo "*** using a regex pattern. Last file checked: $potlib"
+ fi
fi
else
# Add a -L argument.
@@ -2643,16 +3370,23 @@ EOF
;;
none | unknown | *)
newdeplibs=""
- if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
- -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' |
- grep . >/dev/null; then
- echo
+ tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+ -e 's/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
+ done
+ fi
+ if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \
+ | grep . >/dev/null; then
+ $echo
if test "X$deplibs_check_method" = "Xnone"; then
- echo "*** Warning: inter-library dependencies are not supported in this platform."
+ $echo "*** Warning: inter-library dependencies are not supported in this platform."
else
- echo "*** Warning: inter-library dependencies are not known to be supported."
+ $echo "*** Warning: inter-library dependencies are not known to be supported."
fi
- echo "*** All declared inter-library dependencies are being dropped."
+ $echo "*** All declared inter-library dependencies are being dropped."
droppeddeps=yes
fi
;;
@@ -2672,17 +3406,17 @@ EOF
if test "$droppeddeps" = yes; then
if test "$module" = yes; then
- echo
- echo "*** Warning: libtool could not satisfy all declared inter-library"
- echo "*** dependencies of module $libname. Therefore, libtool will create"
- echo "*** a static module, that should work as long as the dlopening"
- echo "*** application is linked with the -dlopen flag."
+ $echo
+ $echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $echo "*** dependencies of module $libname. Therefore, libtool will create"
+ $echo "*** a static module, that should work as long as the dlopening"
+ $echo "*** application is linked with the -dlopen flag."
if test -z "$global_symbol_pipe"; then
- echo
- echo "*** However, this would only work if libtool was able to extract symbol"
- echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
- echo "*** not find such a program. So, this module is probably useless."
- echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ $echo
+ $echo "*** However, this would only work if libtool was able to extract symbol"
+ $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $echo "*** not find such a program. So, this module is probably useless."
+ $echo "*** \`nm' from GNU binutils and a full rebuild may help."
fi
if test "$build_old_libs" = no; then
oldlibs="$output_objdir/$libname.$libext"
@@ -2692,16 +3426,16 @@ EOF
build_libtool_libs=no
fi
else
- echo "*** The inter-library dependencies that have been dropped here will be"
- echo "*** automatically added whenever a program is linked with this library"
- echo "*** or is declared to -dlopen it."
-
- if test $allow_undefined = no; then
- echo
- echo "*** Since this library must not contain undefined symbols,"
- echo "*** because either the platform does not support them or"
- echo "*** it was explicitly requested with -no-undefined,"
- echo "*** libtool will only create a static version of it."
+ $echo "*** The inter-library dependencies that have been dropped here will be"
+ $echo "*** automatically added whenever a program is linked with this library"
+ $echo "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ $echo
+ $echo "*** Since this library must not contain undefined symbols,"
+ $echo "*** because either the platform does not support them or"
+ $echo "*** it was explicitly requested with -no-undefined,"
+ $echo "*** libtool will only create a static version of it."
if test "$build_old_libs" = no; then
oldlibs="$output_objdir/$libname.$libext"
build_libtool_libs=module
@@ -2723,7 +3457,7 @@ EOF
# Test again, we may have decided not to build it any more
if test "$build_libtool_libs" = yes; then
- if test $hardcode_into_libs = yes; then
+ if test "$hardcode_into_libs" = yes; then
# Hardcode the library paths
hardcode_libdirs=
dep_rpath=
@@ -2759,7 +3493,11 @@ EOF
if test -n "$hardcode_libdir_separator" &&
test -n "$hardcode_libdirs"; then
libdir="$hardcode_libdirs"
- eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+ if test -n "$hardcode_libdir_flag_spec_ld"; then
+ eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+ else
+ eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+ fi
fi
if test -n "$runpath_var" && test -n "$perm_rpath"; then
# We should set the runpath_var.
@@ -2779,6 +3517,7 @@ EOF
fi
# Get the real and link names of the library.
+ eval shared_ext=\"$shrext\"
eval library_names=\"$library_names_spec\"
set dummy $library_names
realname="$2"
@@ -2789,7 +3528,9 @@ EOF
else
soname="$realname"
fi
- test -z "$dlname" && dlname=$soname
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
lib="$output_objdir/$realname"
for link
@@ -2797,23 +3538,6 @@ EOF
linknames="$linknames $link"
done
- # Ensure that we have .o objects for linkers which dislike .lo
- # (e.g. aix) in case we are running --disable-static
- for obj in $libobjs; do
- xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$xdir" = "X$obj"; then
- xdir="."
- else
- xdir="$xdir"
- fi
- baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
- oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
- if test ! -f $xdir/$oldobj; then
- $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
- $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
- fi
- done
-
# Use standard objects if they are pic
test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
@@ -2827,13 +3551,21 @@ EOF
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
- $show "$cmd"
- $run eval "$cmd" || exit $?
+ if len=`expr "X$cmd" : ".*"` &&
+ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ $show "using reloadable object file for export list..."
+ skipped_export=:
+ fi
done
IFS="$save_ifs"
if test -n "$export_symbols_regex"; then
- $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
- $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+ $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
$show "$mv \"${export_symbols}T\" \"$export_symbols\""
$run eval '$mv "${export_symbols}T" "$export_symbols"'
fi
@@ -2844,17 +3576,29 @@ EOF
$run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
fi
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ tmp_deplibs="$tmp_deplibs $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
if test -n "$convenience"; then
if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
else
gentop="$output_objdir/${outputname}x"
$show "${rm}r $gentop"
$run ${rm}r "$gentop"
- $show "mkdir $gentop"
- $run mkdir "$gentop"
+ $show "$mkdir $gentop"
+ $run $mkdir "$gentop"
status=$?
- if test $status -ne 0 && test ! -d "$gentop"; then
+ if test "$status" -ne 0 && test ! -d "$gentop"; then
exit $status
fi
generated="$generated $gentop"
@@ -2870,16 +3614,42 @@ EOF
$show "${rm}r $xdir"
$run ${rm}r "$xdir"
- $show "mkdir $xdir"
- $run mkdir "$xdir"
+ $show "$mkdir $xdir"
+ $run $mkdir "$xdir"
status=$?
- if test $status -ne 0 && test ! -d "$xdir"; then
+ if test "$status" -ne 0 && test ! -d "$xdir"; then
exit $status
fi
+ # We will extract separately just the conflicting names and we will no
+ # longer touch any unique names. It is faster to leave these extract
+ # automatically by $AR in one run.
$show "(cd $xdir && $AR x $xabs)"
$run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+ if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+ $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+ $AR t "$xabs" | sort | uniq -cd | while read -r count name
+ do
+ i=1
+ while test "$i" -le "$count"
+ do
+ # Put our $i before any first dot (extension)
+ # Never overwrite any file
+ name_to="$name"
+ while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+ do
+ name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+ done
+ $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+ $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+ i=`expr $i + 1`
+ done
+ done
+ fi
- libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ libobjs="$libobjs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
done
fi
fi
@@ -2895,10 +3665,130 @@ EOF
fi
# Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval cmds=\"$module_expsym_cmds\"
+ else
+ eval cmds=\"$module_cmds\"
+ fi
+ else
if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
eval cmds=\"$archive_expsym_cmds\"
else
eval cmds=\"$archive_cmds\"
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" && len=`expr "X$cmds" : ".*"` &&
+ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise.
+ $echo "creating reloadable object files..."
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ delfiles=
+ last_robj=
+ k=1
+ output=$output_objdir/$save_output-${k}.$objext
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ eval test_cmds=\"$reload_cmds $objlist $last_robj\"
+ if test "X$objlist" = X ||
+ { len=`expr "X$test_cmds" : ".*"` &&
+ test "$len" -le "$max_cmd_len"; }; then
+ objlist="$objlist $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
+ fi
+ last_robj=$output_objdir/$save_output-${k}.$objext
+ k=`expr $k + 1`
+ output=$output_objdir/$save_output-${k}.$objext
+ objlist=$obj
+ len=1
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+
+ if ${skipped_export-false}; then
+ $show "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $run $rm $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
+ fi
+
+ # Set up a command to remove the reloadale object files
+ # after they are used.
+ i=0
+ while test "$i" -lt "$k"
+ do
+ i=`expr $i + 1`
+ delfiles="$delfiles $output_objdir/$save_output-${i}.$objext"
+ done
+
+ $echo "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval cmds=\"$archive_expsym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+
+ # Append the command to remove the reloadable object files
+ # to the just-reset $cmds.
+ eval cmds=\"\$cmds~$rm $delfiles\"
fi
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
@@ -2990,10 +3880,10 @@ EOF
gentop="$output_objdir/${obj}x"
$show "${rm}r $gentop"
$run ${rm}r "$gentop"
- $show "mkdir $gentop"
- $run mkdir "$gentop"
+ $show "$mkdir $gentop"
+ $run $mkdir "$gentop"
status=$?
- if test $status -ne 0 && test ! -d "$gentop"; then
+ if test "$status" -ne 0 && test ! -d "$gentop"; then
exit $status
fi
generated="$generated $gentop"
@@ -3009,16 +3899,42 @@ EOF
$show "${rm}r $xdir"
$run ${rm}r "$xdir"
- $show "mkdir $xdir"
- $run mkdir "$xdir"
+ $show "$mkdir $xdir"
+ $run $mkdir "$xdir"
status=$?
- if test $status -ne 0 && test ! -d "$xdir"; then
+ if test "$status" -ne 0 && test ! -d "$xdir"; then
exit $status
fi
+ # We will extract separately just the conflicting names and we will no
+ # longer touch any unique names. It is faster to leave these extract
+ # automatically by $AR in one run.
$show "(cd $xdir && $AR x $xabs)"
$run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+ if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+ $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+ $AR t "$xabs" | sort | uniq -cd | while read -r count name
+ do
+ i=1
+ while test "$i" -le "$count"
+ do
+ # Put our $i before any first dot (extension)
+ # Never overwrite any file
+ name_to="$name"
+ while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+ do
+ name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+ done
+ $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+ $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+ i=`expr $i + 1`
+ done
+ done
+ fi
- reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ reload_conv_objs="$reload_objs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
done
fi
fi
@@ -3054,8 +3970,8 @@ EOF
# Create an invalid libtool object if no PIC, so that we don't
# accidentally link it into a program.
- $show "echo timestamp > $libobj"
- $run eval "echo timestamp > $libobj" || exit $?
+ # $show "echo timestamp > $libobj"
+ # $run eval "echo timestamp > $libobj" || exit $?
exit 0
fi
@@ -3071,20 +3987,6 @@ EOF
$run eval "$cmd" || exit $?
done
IFS="$save_ifs"
- else
- # Just create a symlink.
- $show $rm $libobj
- $run $rm $libobj
- xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$xdir" = "X$libobj"; then
- xdir="."
- else
- xdir="$xdir"
- fi
- baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
- oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
- $show "(cd $xdir && $LN_S $oldobj $baseobj)"
- $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
fi
if test -n "$gentop"; then
@@ -3097,7 +3999,7 @@ EOF
prog)
case $host in
- *cygwin*) output=`echo $output | sed -e 's,.exe$,,;s,$,.exe,'` ;;
+ *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
esac
if test -n "$vinfo"; then
$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
@@ -3122,6 +4024,16 @@ EOF
;;
esac
+ case $host in
+ *darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ if test "$tagname" = CXX ; then
+ compile_command="$compile_command ${wl}-bind_at_load"
+ finalize_command="$finalize_command ${wl}-bind_at_load"
+ fi
+ ;;
+ esac
+
compile_command="$compile_command $compile_deplibs"
finalize_command="$finalize_command $finalize_deplibs"
@@ -3272,12 +4184,12 @@ extern \"C\" {
done
if test -n "$exclude_expsyms"; then
- $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
$run eval '$mv "$nlist"T "$nlist"'
fi
if test -n "$export_symbols_regex"; then
- $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
$run eval '$mv "$nlist"T "$nlist"'
fi
@@ -3285,9 +4197,9 @@ extern \"C\" {
if test -z "$export_symbols"; then
export_symbols="$output_objdir/$output.exp"
$run $rm $export_symbols
- $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
else
- $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+ $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
$run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
$run eval 'mv "$nlist"T "$nlist"'
fi
@@ -3295,8 +4207,8 @@ extern \"C\" {
for arg in $dlprefiles; do
$show "extracting global C symbols from \`$arg'"
- name=`echo "$arg" | sed -e 's%^.*/%%'`
- $run eval 'echo ": $name " >> "$nlist"'
+ name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
+ $run eval '$echo ": $name " >> "$nlist"'
$run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
done
@@ -3305,12 +4217,18 @@ extern \"C\" {
test -f "$nlist" || : > "$nlist"
if test -n "$exclude_expsyms"; then
- egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
$mv "$nlist"T "$nlist"
fi
# Try sorting and uniquifying the output.
- if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+ if grep -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
:
else
grep -v "^: " < "$nlist" > "$nlist"S
@@ -3319,7 +4237,7 @@ extern \"C\" {
if test -f "$nlist"S; then
eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
else
- echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ $echo '/* NONE */' >> "$output_objdir/$dlsyms"
fi
$echo >> "$output_objdir/$dlsyms" "\
@@ -3371,18 +4289,18 @@ static const void *lt_preloaded_setup() {
*-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
case "$compile_command " in
*" -static "*) ;;
- *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+ *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
esac;;
*-*-hpux*)
case "$compile_command " in
*" -static "*) ;;
- *) pic_flag_for_symtable=" $pic_flag -DPIC";;
+ *) pic_flag_for_symtable=" $pic_flag";;
esac
esac
# Now compile the dynamic symbol file.
- $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
- $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+ $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+ $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
# Clean up the generated files.
$show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
@@ -3407,7 +4325,7 @@ static const void *lt_preloaded_setup() {
finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
fi
- if test $need_relink = no || test "$build_libtool_libs" != yes; then
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
# Replace the output file specification.
compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
link_command="$compile_command$compile_rpath"
@@ -3532,7 +4450,7 @@ static const void *lt_preloaded_setup() {
relink_command="$var=\"$var_value\"; export $var; $relink_command"
fi
done
- relink_command="cd `pwd`; $relink_command"
+ relink_command="(cd `pwd`; $relink_command)"
relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
fi
@@ -3552,13 +4470,228 @@ static const void *lt_preloaded_setup() {
# win32 will think the script is a binary if it has
# a .exe suffix, so we strip it off here.
case $output in
- *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+ *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
esac
# test for cygwin because mv fails w/o .exe extensions
case $host in
- *cygwin*) exeext=.exe ;;
+ *cygwin*)
+ exeext=.exe
+ outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
*) exeext= ;;
esac
+ case $host in
+ *cygwin* | *mingw* )
+ cwrappersource=`$echo ${objdir}/lt-${output}.c`
+ cwrapper=`$echo ${output}.exe`
+ $rm $cwrappersource $cwrapper
+ trap "$rm $cwrappersource $cwrapper; exit 1" 1 2 15
+
+ cat > $cwrappersource <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+
+ Currently, it simply execs the wrapper *script* "/bin/sh $output",
+ but could eventually absorb all of the scripts functionality and
+ exec $objdir/$outputname directly.
+*/
+EOF
+ cat >> $cwrappersource<<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef DIR_SEPARATOR
+#define DIR_SEPARATOR '/'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+#define HAVE_DOS_BASED_FILE_SYSTEM
+#ifndef DIR_SEPARATOR_2
+#define DIR_SEPARATOR_2 '\\'
+#endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+const char *program_name = NULL;
+
+void * xmalloc (size_t num);
+char * xstrdup (const char *string);
+char * basename (const char *name);
+char * fnqualify(const char *path);
+char * strendzap(char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int i;
+
+ program_name = (char *) xstrdup ((char *) basename (argv[0]));
+ newargz = XMALLOC(char *, argc+2);
+EOF
+
+ cat >> $cwrappersource <<EOF
+ newargz[0] = "$SHELL";
+EOF
+
+ cat >> $cwrappersource <<"EOF"
+ newargz[1] = fnqualify(argv[0]);
+ /* we know the script has the same name, without the .exe */
+ /* so make sure newargz[1] doesn't end in .exe */
+ strendzap(newargz[1],".exe");
+ for (i = 1; i < argc; i++)
+ newargz[i+1] = xstrdup(argv[i]);
+ newargz[argc+1] = NULL;
+EOF
+
+ cat >> $cwrappersource <<EOF
+ execv("$SHELL",newargz);
+EOF
+
+ cat >> $cwrappersource <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void * p = (void *) malloc (num);
+ if (!p)
+ lt_fatal ("Memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
+;
+}
+
+char *
+basename (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha (name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return (char *) base;
+}
+
+char *
+fnqualify(const char *path)
+{
+ size_t size;
+ char *p;
+ char tmp[LT_PATHMAX + 1];
+
+ assert(path != NULL);
+
+ /* Is it qualified already? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha (path[0]) && path[1] == ':')
+ return xstrdup (path);
+#endif
+ if (IS_DIR_SEPARATOR (path[0]))
+ return xstrdup (path);
+
+ /* prepend the current directory */
+ /* doesn't handle '~' */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */
+ p = XMALLOC(char, size);
+ sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path);
+ return p;
+}
+
+char *
+strendzap(char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert(str != NULL);
+ assert(pat != NULL);
+
+ len = strlen(str);
+ patlen = strlen(pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp(str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+static void
+lt_error_core (int exit_status, const char * mode,
+ const char * message, va_list ap)
+{
+ fprintf (stderr, "%s: %s: ", program_name, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+ va_end (ap);
+}
+EOF
+ # we should really use a build-platform specific compiler
+ # here, but OTOH, the wrappers (shell script and this C one)
+ # are only useful if you want to execute the "real" binary.
+ # Since the "real" binary is built for $host, then this
+ # wrapper might as well be built for $host, too.
+ $run $LTCC -s -o $cwrapper $cwrappersource
+ ;;
+ esac
$rm $output
trap "$rm $output; exit 1" 1 2 15
@@ -3576,7 +4709,7 @@ static const void *lt_preloaded_setup() {
# Sed substitution that helps us do robust quoting. It backslashifies
# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e 1s/^X//'
+Xsed='${SED} -e 1s/^X//'
sed_quote_subst='$sed_quote_subst'
# The HP-UX ksh and POSIX shell print the target directory to stdout
@@ -3614,7 +4747,7 @@ else
test \"x\$thisdir\" = \"x\$file\" && thisdir=.
# Follow symbolic links until we get to the real thisdir.
- file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+ file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
while test -n \"\$file\"; do
destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
@@ -3627,7 +4760,7 @@ else
fi
file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
- file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
done
# Try to get the absolute directory name.
@@ -3636,12 +4769,12 @@ else
"
if test "$fast_install" = yes; then
- echo >> $output "\
+ $echo >> $output "\
program=lt-'$outputname'$exeext
progdir=\"\$thisdir/$objdir\"
if test ! -f \"\$progdir/\$program\" || \\
- { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
test \"X\$file\" != \"X\$progdir/\$program\"; }; then
file=\"\$\$-\$program\"
@@ -3652,7 +4785,7 @@ else
$rm \"\$progdir/\$file\"
fi"
- echo >> $output "\
+ $echo >> $output "\
# relink executable if necessary
if test -n \"\$relink_command\"; then
@@ -3670,13 +4803,13 @@ else
$rm \"\$progdir/\$file\"
fi"
else
- echo >> $output "\
+ $echo >> $output "\
program='$outputname'
progdir=\"\$thisdir/$objdir\"
"
fi
- echo >> $output "\
+ $echo >> $output "\
if test -f \"\$progdir/\$program\"; then"
@@ -3707,14 +4840,6 @@ else
# Run the actual program with our arguments.
"
case $host in
- # win32 systems need to use the prog path for dll
- # lookup to work
- *-*-cygwin* | *-*-pw32*)
- $echo >> $output "\
- exec \$progdir/\$program \${1+\"\$@\"}
-"
- ;;
-
# Backslashes separate directories on plain windows
*-*-mingw | *-*-os2*)
$echo >> $output "\
@@ -3724,11 +4849,7 @@ else
*)
$echo >> $output "\
- # Export the path to the program.
- PATH=\"\$progdir:\$PATH\"
- export PATH
-
- exec \$program \${1+\"\$@\"}
+ exec \$progdir/\$program \${1+\"\$@\"}
"
;;
esac
@@ -3740,7 +4861,7 @@ else
# The program doesn't exist.
\$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
\$echo \"This script is just a wrapper for \$program.\" 1>&2
- echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ $echo \"See the $PACKAGE documentation for more information.\" 1>&2
exit 1
fi
fi\
@@ -3763,7 +4884,7 @@ fi\
oldobjs="$libobjs_save"
build_libtool_libs=no
else
- oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+ oldobjs="$old_deplibs $non_pic_objects"
fi
addlibs="$old_convenience"
fi
@@ -3772,10 +4893,10 @@ fi\
gentop="$output_objdir/${outputname}x"
$show "${rm}r $gentop"
$run ${rm}r "$gentop"
- $show "mkdir $gentop"
- $run mkdir "$gentop"
+ $show "$mkdir $gentop"
+ $run $mkdir "$gentop"
status=$?
- if test $status -ne 0 && test ! -d "$gentop"; then
+ if test "$status" -ne 0 && test ! -d "$gentop"; then
exit $status
fi
generated="$generated $gentop"
@@ -3792,14 +4913,40 @@ fi\
$show "${rm}r $xdir"
$run ${rm}r "$xdir"
- $show "mkdir $xdir"
- $run mkdir "$xdir"
+ $show "$mkdir $xdir"
+ $run $mkdir "$xdir"
status=$?
- if test $status -ne 0 && test ! -d "$xdir"; then
+ if test "$status" -ne 0 && test ! -d "$xdir"; then
exit $status
fi
+ # We will extract separately just the conflicting names and we will no
+ # longer touch any unique names. It is faster to leave these extract
+ # automatically by $AR in one run.
$show "(cd $xdir && $AR x $xabs)"
$run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+ if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+ $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+ $AR t "$xabs" | sort | uniq -cd | while read -r count name
+ do
+ i=1
+ while test "$i" -le "$count"
+ do
+ # Put our $i before any first dot (extension)
+ # Never overwrite any file
+ name_to="$name"
+ while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+ do
+ name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+ done
+ $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+ $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+ i=`expr $i + 1`
+ done
+ done
+ fi
oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
done
@@ -3809,25 +4956,65 @@ fi\
if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
eval cmds=\"$old_archive_from_new_cmds\"
else
- # Ensure that we have .o objects in place in case we decided
- # not to build a shared library, and have fallen back to building
- # static libs even though --disable-static was passed!
- for oldobj in $oldobjs; do
- if test ! -f $oldobj; then
- xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$xdir" = "X$oldobj"; then
- xdir="."
+ eval cmds=\"$old_archive_cmds\"
+
+ if len=`expr "X$cmds" : ".*"` &&
+ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # the command line is too long to link in one step, link in parts
+ $echo "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ # GNU ar 2.10+ was changed to match POSIX; thus no paths are
+ # encoded into archives. This makes 'ar r' malfunction in
+ # this piecewise linking case whenever conflicting object
+ # names appear in distinct ar calls; check, warn and compensate.
+ if (for obj in $save_oldobjs
+ do
+ $echo "X$obj" | $Xsed -e 's%^.*/%%'
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2
+ $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2
+ AR_FLAGS=cq
+ fi
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ for obj in $save_oldobjs
+ do
+ oldobjs="$objlist $obj"
+ objlist="$objlist $obj"
+ eval test_cmds=\"$old_archive_cmds\"
+ if len=`expr "X$test_cmds" : ".*"` &&
+ test "$len" -le "$max_cmd_len"; then
+ :
else
- xdir="$xdir"
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
fi
- baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
- obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
- $show "(cd $xdir && ${LN_S} $obj $baseobj)"
- $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~$old_archive_cmds\"
fi
- done
-
- eval cmds=\"$old_archive_cmds\"
+ fi
fi
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
@@ -3862,7 +5049,7 @@ fi\
fi
done
# Quote the link command for shipping.
- relink_command="cd `pwd`; $SHELL $0 --mode=relink $libtool_args"
+ relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)"
relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
# Only create the output if not a dry run.
@@ -3879,7 +5066,7 @@ fi\
case $deplib in
*.la)
name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
- eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
if test -z "$libdir"; then
$echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
exit 1
@@ -3893,7 +5080,7 @@ fi\
newdlfiles=
for lib in $dlfiles; do
name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
- eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
if test -z "$libdir"; then
$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
exit 1
@@ -3904,7 +5091,7 @@ fi\
newdlprefiles=
for lib in $dlprefiles; do
name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
- eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
if test -z "$libdir"; then
$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
exit 1
@@ -3917,7 +5104,7 @@ fi\
# place dlname in correct position for cygwin
tdlname=$dlname
case $host,$output,$installed,$module,$dlname in
- *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
esac
$echo > $output "\
# $outputname - a libtool library file
@@ -3946,13 +5133,16 @@ revision=$revision
# Is this an already installed library?
installed=$installed
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
# Files to dlopen/dlpreopen
dlopen='$dlfiles'
dlpreopen='$dlprefiles'
# Directory that this library needs to be installed in:
libdir='$install_libdir'"
- if test "$installed" = no && test $need_relink = yes; then
+ if test "$installed" = no && test "$need_relink" = yes; then
$echo >> $output "\
relink_command=\"$relink_command\""
fi
@@ -4088,7 +5278,7 @@ relink_command=\"$relink_command\""
# Not a directory, so check to see that there is only one file specified.
set dummy $files
- if test $# -gt 2; then
+ if test "$#" -gt 2; then
$echo "$modename: \`$dest' is not a directory" 1>&2
$echo "$help" 1>&2
exit 1
@@ -4128,7 +5318,7 @@ relink_command=\"$relink_command\""
*.la)
# Check to see that this really is a libtool archive.
- if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
else
$echo "$modename: \`$file' is not a valid libtool archive" 1>&2
$echo "$help" 1>&2
@@ -4145,21 +5335,12 @@ relink_command=\"$relink_command\""
esac
# Add the libdir to current_libdirs if it is the destination.
- DESTDIR=
if test "X$destdir" = "X$libdir"; then
case "$current_libdirs " in
*" $libdir "*) ;;
*) current_libdirs="$current_libdirs $libdir" ;;
esac
else
- case "$destdir" in
- *"$libdir")
- DESTDIR=`$echo "$destdir" | sed -e 's!'"$libdir"'$!!'`
- if test "X$destdir" != "X$DESTDIR$libdir"; then
- DESTDIR=
- fi
- ;;
- esac
# Note the libdir as a future libdir.
case "$future_libdirs " in
*" $libdir "*) ;;
@@ -4172,16 +5353,35 @@ relink_command=\"$relink_command\""
dir="$dir$objdir"
if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ if test "$inst_prefix_dir" = "$destdir"; then
+ $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
+ exit 1
+ fi
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
$echo "$modename: warning: relinking \`$file'" 1>&2
- export DESTDIR
$show "$relink_command"
if $run eval "$relink_command"; then :
else
$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
- continue
+ exit 1
fi
fi
- unset DESTDIR
# See the names of the shared library.
set dummy $library_names
@@ -4201,7 +5401,7 @@ relink_command=\"$relink_command\""
$run eval "$striplib $destdir/$realname" || exit $?
fi
- if test $# -gt 0; then
+ if test "$#" -gt 0; then
# Delete the old symlinks, and create new ones.
for linkname
do
@@ -4287,20 +5487,48 @@ relink_command=\"$relink_command\""
destfile="$destdir/$destfile"
fi
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ file=`$echo $file|${SED} 's,.exe$,,'`
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
# Do a test to see if this is really a libtool program.
- if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ case $host in
+ *cygwin*|*mingw*)
+ wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
notinst_deplibs=
relink_command=
+ # To insure that "foo" is sourced, and not "foo.exe",
+ # finese the cygwin/MSYS system by explicitly sourcing "foo."
+ # which disallows the automatic-append-.exe behavior.
+ case $build in
+ *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
+ *) wrapperdot=${wrapper} ;;
+ esac
# If there is no directory component, then add one.
case $file in
- */* | *\\*) . $file ;;
- *) . ./$file ;;
+ */* | *\\*) . ${wrapperdot} ;;
+ *) . ./${wrapperdot} ;;
esac
# Check the variables that should have been set.
if test -z "$notinst_deplibs"; then
- $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+ $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
exit 1
fi
@@ -4323,10 +5551,17 @@ relink_command=\"$relink_command\""
done
relink_command=
+ # To insure that "foo" is sourced, and not "foo.exe",
+ # finese the cygwin/MSYS system by explicitly sourcing "foo."
+ # which disallows the automatic-append-.exe behavior.
+ case $build in
+ *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
+ *) wrapperdot=${wrapper} ;;
+ esac
# If there is no directory component, then add one.
case $file in
- */* | *\\*) . $file ;;
- *) . ./$file ;;
+ */* | *\\*) . ${wrapperdot} ;;
+ *) . ./${wrapperdot} ;;
esac
outputname=
@@ -4334,13 +5569,14 @@ relink_command=\"$relink_command\""
if test "$finalize" = yes && test -z "$run"; then
tmpdir="/tmp"
test -n "$TMPDIR" && tmpdir="$TMPDIR"
- tmpdir="$tmpdir/libtool-$$"
+ tmpdir=`mktemp -d $tmpdir/libtool-XXXXXX 2> /dev/null` ||
+ tmpdir="$tmpdir/libtool-$$"
if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
else
$echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
continue
fi
- file=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
outputname="$tmpdir/$file"
# Replace the output file specification.
relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
@@ -4358,14 +5594,14 @@ relink_command=\"$relink_command\""
fi
else
# Install the binary that we compiled earlier.
- file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
fi
fi
# remove .exe since cygwin /usr/bin/install will append another
# one anyways
case $install_prog,$host in
- /usr/bin/install*,*cygwin*)
+ */usr/bin/install*,*cygwin*)
case $file:$destfile in
*.exe:*.exe)
# this is ok
@@ -4374,7 +5610,7 @@ relink_command=\"$relink_command\""
destfile=$destfile.exe
;;
*:*.exe)
- destfile=`echo $destfile | sed -e 's,.exe$,,'`
+ destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
;;
esac
;;
@@ -4459,42 +5695,42 @@ relink_command=\"$relink_command\""
fi
# Exit here if they wanted silent mode.
- test "$show" = ":" && exit 0
+ test "$show" = : && exit 0
- echo "----------------------------------------------------------------------"
- echo "Libraries have been installed in:"
+ $echo "----------------------------------------------------------------------"
+ $echo "Libraries have been installed in:"
for libdir in $libdirs; do
- echo " $libdir"
+ $echo " $libdir"
done
- echo
- echo "If you ever happen to want to link against installed libraries"
- echo "in a given directory, LIBDIR, you must either use libtool, and"
- echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
- echo "flag during linking and do at least one of the following:"
+ $echo
+ $echo "If you ever happen to want to link against installed libraries"
+ $echo "in a given directory, LIBDIR, you must either use libtool, and"
+ $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ $echo "flag during linking and do at least one of the following:"
if test -n "$shlibpath_var"; then
- echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
- echo " during execution"
+ $echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ $echo " during execution"
fi
if test -n "$runpath_var"; then
- echo " - add LIBDIR to the \`$runpath_var' environment variable"
- echo " during linking"
+ $echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ $echo " during linking"
fi
if test -n "$hardcode_libdir_flag_spec"; then
libdir=LIBDIR
eval flag=\"$hardcode_libdir_flag_spec\"
- echo " - use the \`$flag' linker flag"
+ $echo " - use the \`$flag' linker flag"
fi
if test -n "$admincmds"; then
- echo " - have your system administrator run these commands:$admincmds"
+ $echo " - have your system administrator run these commands:$admincmds"
fi
if test -f /etc/ld.so.conf; then
- echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
fi
- echo
- echo "See any operating system documentation about shared libraries for"
- echo "more information, such as the ld(1) and ld.so(8) manual pages."
- echo "----------------------------------------------------------------------"
+ $echo
+ $echo "See any operating system documentation about shared libraries for"
+ $echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ $echo "----------------------------------------------------------------------"
exit 0
;;
@@ -4522,7 +5758,7 @@ relink_command=\"$relink_command\""
case $file in
*.la)
# Check to see that this really is a libtool archive.
- if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
else
$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
$echo "$help" 1>&2
@@ -4593,7 +5829,7 @@ relink_command=\"$relink_command\""
-*) ;;
*)
# Do a test to see if this is really a libtool program.
- if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
# If there is no directory component, then add one.
case $file in
*/* | *\\*) . $file ;;
@@ -4616,7 +5852,7 @@ relink_command=\"$relink_command\""
eval "export $shlibpath_var"
fi
- # Restore saved enviroment variables
+ # Restore saved environment variables
if test "${save_LC_ALL+set}" = set; then
LC_ALL="$save_LC_ALL"; export LC_ALL
fi
@@ -4625,14 +5861,14 @@ relink_command=\"$relink_command\""
fi
# Now prepare to actually exec the command.
- exec_cmd='"$cmd"$args'
+ exec_cmd="\"\$cmd\"$args"
else
# Display what would be done.
if test -n "$shlibpath_var"; then
eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
$echo "export $shlibpath_var"
fi
- $echo "$cmd$args"
+ eval \$echo \"\$cmd\"$args
exit 0
fi
;;
@@ -4666,19 +5902,20 @@ relink_command=\"$relink_command\""
rmdirs=
+ origobjdir="$objdir"
for file in $files; do
dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
if test "X$dir" = "X$file"; then
dir=.
- objdir="$objdir"
+ objdir="$origobjdir"
else
- objdir="$dir/$objdir"
+ objdir="$dir/$origobjdir"
fi
name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
- test $mode = uninstall && objdir="$dir"
+ test "$mode" = uninstall && objdir="$dir"
# Remember objdir for removal later, being careful to avoid duplicates
- if test $mode = clean; then
+ if test "$mode" = clean; then
case " $rmdirs " in
*" $objdir "*) ;;
*) rmdirs="$rmdirs $objdir" ;;
@@ -4702,7 +5939,7 @@ relink_command=\"$relink_command\""
case $name in
*.la)
# Possibly a libtool archive, so verify it.
- if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
. $dir/$name
# Delete the libtool libraries and symlinks.
@@ -4710,9 +5947,9 @@ relink_command=\"$relink_command\""
rmfiles="$rmfiles $objdir/$n"
done
test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
- test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+ test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
- if test $mode = uninstall; then
+ if test "$mode" = uninstall; then
if test -n "$library_names"; then
# Do each command in the postuninstall commands.
eval cmds=\"$postuninstall_cmds\"
@@ -4721,7 +5958,7 @@ relink_command=\"$relink_command\""
IFS="$save_ifs"
$show "$cmd"
$run eval "$cmd"
- if test $? != 0 && test "$rmforce" != yes; then
+ if test "$?" -ne 0 && test "$rmforce" != yes; then
exit_status=1
fi
done
@@ -4736,7 +5973,7 @@ relink_command=\"$relink_command\""
IFS="$save_ifs"
$show "$cmd"
$run eval "$cmd"
- if test $? != 0 && test "$rmforce" != yes; then
+ if test "$?" -ne 0 && test "$rmforce" != yes; then
exit_status=1
fi
done
@@ -4748,22 +5985,52 @@ relink_command=\"$relink_command\""
;;
*.lo)
- if test "$build_old_libs" = yes; then
- oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
- rmfiles="$rmfiles $dir/$oldobj"
+ # Possibly a libtool object, so verify it.
+ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+
+ # Read the .lo file
+ . $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" \
+ && test "$pic_object" != none; then
+ rmfiles="$rmfiles $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" \
+ && test "$non_pic_object" != none; then
+ rmfiles="$rmfiles $dir/$non_pic_object"
+ fi
fi
;;
*)
- # Do a test to see if this is a libtool program.
- if test $mode = clean &&
- (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
- relink_command=
- . $dir/$file
+ if test "$mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ file=`$echo $file|${SED} 's,.exe$,,'`
+ noexename=`$echo $name|${SED} 's,.exe$,,'`
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ rmfiles="$rmfiles $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ relink_command=
+ . $dir/$noexename
- rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
- if test "$fast_install" = yes && test -n "$relink_command"; then
- rmfiles="$rmfiles $objdir/lt-$name"
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ rmfiles="$rmfiles $objdir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+ fi
fi
fi
;;
@@ -4771,6 +6038,7 @@ relink_command=\"$relink_command\""
$show "$rm $rmfiles"
$run $rm $rmfiles || exit_status=1
done
+ objdir="$origobjdir"
# Try to remove the ${objdir}s in the directories where we deleted files
for dir in $rmdirs; do
@@ -4818,6 +6086,7 @@ Provide generalized library-building support services.
--mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
--quiet same as \`--silent'
--silent don't print informational messages
+ --tag=TAG use configuration variables from tag TAG
--version print version information
MODE must be one of the following:
@@ -4831,7 +6100,9 @@ MODE must be one of the following:
uninstall remove libraries from an installed directory
MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
-a more detailed description of MODE."
+a more detailed description of MODE.
+
+Report bugs to <bug-libtool@gnu.org>."
exit 0
;;
@@ -4943,6 +6214,7 @@ The following components of LINK-COMMAND are treated specially:
-no-install link a not-installable executable
-no-undefined declare that a library does not refer to external symbols
-o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
-release RELEASE specify package release information
-rpath LIBDIR the created library will eventually be installed in LIBDIR
-R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
@@ -4988,11 +6260,31 @@ Otherwise, only FILE itself is deleted using RM."
;;
esac
-echo
+$echo
$echo "Try \`$modename --help' for more information about other modes."
exit 0
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
# Local Variables:
# mode:shell-script
# sh-indentation:2
diff --git a/man/Makefile.am b/man/Makefile.am
index 186fc01685e..37eb8a13f4e 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -19,9 +19,28 @@
man_MANS = mysql.1 isamchk.1 isamlog.1 mysql_zap.1 mysqlaccess.1 \
mysqladmin.1 mysqld.1 mysqld_multi.1 mysqldump.1 mysqlshow.1 \
- perror.1 replace.1 safe_mysqld.1
+ perror.1 replace.1 mysqld_safe.1 mysql_fix_privilege_tables.1
-EXTRA_DIST = $(man_MANS)
+EXTRA_DIST = mysql.1.in isamchk.1.in isamlog.1.in mysql_zap.1.in \
+ mysqlaccess.1.in mysqladmin.1.in mysqld.1.in mysqld_multi.1.in \
+ mysqldump.1.in mysqlshow.1.in perror.1.in replace.1.in \
+ mysqld_safe.1.in mysql_fix_privilege_tables.1.in
+
+CLEANFILES = $(man_MANS)
+
+SUFFIXES = .in
+
+.in:
+ @RM@ -f $@ $@-t
+ @SED@ \
+ -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \
+ -e 's!@''sysconfdir''@!@sysconfdir@!' \
+ -e 's!@''bindir''@!$(bindir)!g' \
+ -e 's!@''libexecdir''@!$(libexecdir)!g' \
+ -e 's!@''localstatedir''@!$(localstatedir)!g' \
+ -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \
+ $< > $@-t
+ @MV@ $@-t $@
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/man/isamchk.1 b/man/isamchk.1
deleted file mode 100755
index 6bf83abab5b..00000000000
--- a/man/isamchk.1
+++ /dev/null
@@ -1,140 +0,0 @@
-.TH isamchk 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-.BR isamchk
- \- Description, check and repair of ISAM tables.
-Used without options all tables on the command will be checked for errors
-.SH USAGE
-isamchk [OPTIONS] tables[.ISM]
-.SH SYNOPSIS
-.B isamchk
-.RB [ \-a | \-\-analyze ]
-.RB [ \-# | \-\-debug=... ]
-.RB [ \-\-character\-sets\-dir=...]
-.RB [ \-C | \-\-default\-character\-set=...]
-.RB [ \-d | \-\-description ]
-.RB [ \-e | \-\-extend\-check ]
-.RB [ \-f | \-\-force ]
-.RB [ \-? | \-\-help ]
-.RB [ \-i | \-\-information ]
-.RB [ \-k | \-\-keys\-used=# ]
-.RB [ \-l | \-\-no\-symlinks]
-.RB [ \-q | \-\-quick ]
-.RB [ \-r | \-\-recover ]
-.RB [ \-o | \-\-safe\-recover ]
-.RB [ \-O | "\-\-set\-variable var=option"]
-.RB [ \-s | \-\-silent ]
-.RB [ \-S | \-\-sort\-index ]
-.RB [ \-R | \-\-sort\-records=#]
-.RB [ \-u | \-\-unpack ]
-.RB [ \-v | \-\-verbose ]
-.RB [ \-V | \-\-version ]
-.RB [ \-w | \-\-wait ]
-.SH DESCRIPTION
-.TP
-.BR \-a | \-\-analyze
-Analyze distribution of keys. Will make some joins in
-MySQL faster.
-.TP
-.BR \-# | \-\-debug=...
-Output debug log. Often this is 'd:t:o ,filename`
-.TP
-.BR \-\-character\-sets\-dir=...
-Directory where character sets are
-.TP
-.BR \-C | \-\-default\-character\-set=...
-Set the default character set
-.TP
-.BR \-d | \-\-description
-Prints some information about table.
-.TP
-.BR \-e | \-\-extend\-check
-Check the table VERY thoroughly. One need use this
-only in extreme cases as isamchk should normally find
-all errors even without this switch
-.TP
-.BR \-f | \-\-force
-Overwrite old temporary files.
-If one uses \-f when checking tables (running isamchk
-without \-r), isamchk will automatically restart with
-\-r on any wrong table.
-.TP
-.BR \-? | \-\-help
-Display help and exit.
-.TP
-.BR \-i | \-\-information
-Print statistics information about the table
-.TP
-.BR \-k | \-\-keys\-used=#
-Used with '\-r'. Tell ISAM to update only the first
-# keys. This can be used to get faster inserts!
-.TP
-.BR \-l | \-\-no\-symlinks
-Do not follow symbolic links when repairing. Normally
-isamchk repairs the table a symlink points at.
-.TP
-.BR \-q | \-\-quick
-Used with \-r to get a faster repair. (The data file
-isn't touched.) One can give a second '\-q' to force
-isamchk to modify the original datafile.
-.TP
-.BR \-r | \-\-recover
-Can fix almost anything except unique keys that aren't
-unique.
-.TP
-.BR \-o | \-\-safe\-recover
-Uses old recovery method; slower than '\-r' but can
-handle a couple of cases that '\-r' cannot handle.
-.TP
-.BR \-O | " \-\-set\-variable var=option "
-Change the value of a variable.
-.TP
-.BR \-s | \-\-silent
-Only print errors. One can use two \-s to make isamchk
-very silent
-.TP
-.BR \-S | \-\-sort\-index
-Sort index blocks. This speeds up 'read\-next' in
-applications
-.TP
-.BR \-R | \-\-sort\-records=#
-Sort records according to an index. This makes your
-data much more localized and may speed up things
-(It may be VERY slow to do a sort the first time!)
-.TP
-.BR \-u | \-\-unpack
-Unpack file packed with pack_isam.
-.TP
-.BR \-v | \-\-verbose
-Print more information. This can be used with
-\-d and \-e. Use many \-v for more verbosity!
-.TP
-.BR \-V | \-\-version
-Print version and exit.
-.TP
-.BR \-w | \-\-wait
-Wait if table is locked.
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-
-.\" end of man page
diff --git a/man/isamchk.1.in b/man/isamchk.1.in
new file mode 100644
index 00000000000..cad1303ee55
--- /dev/null
+++ b/man/isamchk.1.in
@@ -0,0 +1,145 @@
+.TH isamchk 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+.BR isamchk
+ \- Description, check and repair of ISAM tables.
+Used without options all tables on the command will be checked for errors
+.SH USAGE
+isamchk [OPTIONS] tables[.ISM]
+.SH SYNOPSIS
+.B isamchk
+.RB [ \-a | \-\-analyze ]
+.RB [ \-# | \-\-debug=... ]
+.RB [ \-\-character\-sets\-dir=...]
+.RB [ \-C | \-\-default\-character\-set=...]
+.RB [ \-d | \-\-description ]
+.RB [ \-e | \-\-extend\-check ]
+.RB [ \-f | \-\-force ]
+.RB [ \-? | \-\-help ]
+.RB [ \-i | \-\-information ]
+.RB [ \-k | \-\-keys\-used=# ]
+.RB [ \-l | \-\-no\-symlinks]
+.RB [ \-q | \-\-quick ]
+.RB [ \-r | \-\-recover ]
+.RB [ \-o | \-\-safe\-recover ]
+.RB [ \-O | "\-\-set\-variable var=option"]
+.RB [ \-s | \-\-silent ]
+.RB [ \-S | \-\-sort\-index ]
+.RB [ \-R | \-\-sort\-records=#]
+.RB [ \-u | \-\-unpack ]
+.RB [ \-v | \-\-verbose ]
+.RB [ \-V | \-\-version ]
+.RB [ \-w | \-\-wait ]
+.SH DESCRIPTION
+.TP
+.BR \-a | \-\-analyze
+Analyze distribution of keys. Will make some joins in
+MySQL faster.
+.TP
+.BR \-# | \-\-debug=...
+Output debug log. Often this is 'd:t:o ,filename`
+.TP
+.BR \-\-character\-sets\-dir=...
+Directory where character sets are
+.TP
+.BR \-C | \-\-default\-character\-set=...
+Set the default character set
+.TP
+.BR \-d | \-\-description
+Prints some information about table.
+.TP
+.BR \-e | \-\-extend\-check
+Check the table VERY thoroughly. One need use this
+only in extreme cases as isamchk should normally find
+all errors even without this switch
+.TP
+.BR \-f | \-\-force
+Overwrite old temporary files.
+If one uses \-f when checking tables (running isamchk
+without \-r), isamchk will automatically restart with
+\-r on any wrong table.
+.TP
+.BR \-? | \-\-help
+Display help and exit.
+.TP
+.BR \-i | \-\-information
+Print statistics information about the table
+.TP
+.BR \-k | \-\-keys\-used=#
+Used with '\-r'. Tell ISAM to update only the first
+# keys. This can be used to get faster inserts!
+.TP
+.BR \-l | \-\-no\-symlinks
+Do not follow symbolic links when repairing. Normally
+isamchk repairs the table a symlink points at.
+.TP
+.BR \-q | \-\-quick
+Used with \-r to get a faster repair. (The data file
+isn't touched.) One can give a second '\-q' to force
+isamchk to modify the original datafile.
+.TP
+.BR \-r | \-\-recover
+Can fix almost anything except unique keys that aren't
+unique.
+.TP
+.BR \-o | \-\-safe\-recover
+Uses old recovery method; slower than '\-r' but can
+handle a couple of cases that '\-r' cannot handle.
+.TP
+.BR \-O | " \-\-set\-variable var=option "
+Change the value of a variable.
+.TP
+.BR \-s | \-\-silent
+Only print errors. One can use two \-s to make isamchk
+very silent
+.TP
+.BR \-S | \-\-sort\-index
+Sort index blocks. This speeds up 'read\-next' in
+applications
+.TP
+.BR \-R | \-\-sort\-records=#
+Sort records according to an index. This makes your
+data much more localized and may speed up things
+(It may be VERY slow to do a sort the first time!)
+.TP
+.BR \-u | \-\-unpack
+Unpack file packed with pack_isam.
+.TP
+.BR \-v | \-\-verbose
+Print more information. This can be used with
+\-d and \-e. Use many \-v for more verbosity!
+.TP
+.BR \-V | \-\-version
+Print version and exit.
+.TP
+.BR \-w | \-\-wait
+Wait if table is locked.
+.SH "SEE ALSO"
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+
+.\" end of man page
diff --git a/man/isamlog.1 b/man/isamlog.1
deleted file mode 100644
index 430b1d3d396..00000000000
--- a/man/isamlog.1
+++ /dev/null
@@ -1,103 +0,0 @@
-.TH isamlog 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-isamlog - Write info about whats in a nisam log file.
-.SH USAGE
-isamlog [-?iruvIV] [-c #] [-f #] [-F filepath/] [-o #] [-R file recordpos] [-w write_file] [log-filename [table ...]]
-.SH SYNOPSIS
-.B isamlog
-.RB [ -? | -I ]
-.RB [ -V ]
-.RB [ -c ]
-.RB [ -f ]
-.RB [ -F ]
-.RB [ -i ]
-.RB [ -o ]
-.RB [ "-p #" ]
-.RB [ -r ]
-.RB [ -R ]
-.RB [ -u ]
-.RB [ -v ]
-.RB [ -w ]
-.SH DESCRIPTION
-.TP
-.BR isamlog
-.TP
-.BR -? | -I
-info
-.TP
-.BR -V
-version
-.TP
-.BR -c
-do only # commands
-.TP
-.BR -f
-max open files
-.TP
-.BR -F
-file path
-.TP
-.BR -i
-extra info
-.TP
-.BR -o
-offset
-.TP
-.BR "-p #"
-remove # components from path
-.TP
-.BR -r
-recover
-.TP
-.BR -R
-file recordposition
-.TP
-.BR -u
-update
-.TP
-.BR -v
-verbose
-.TP
-.BR -w
-write file
-.SH NOTE
-If no file name is given isam.log is used
-One can give a second and a third '-v' for more verbose.
-Normaly one does a update (-u).
-If a recover is done all writes and all possibly updates and deletes is done
-and errors are only counted.
-If one gives table names as arguments only these tables will be updated
-
-
-
-.SH "SEE ALSO"
-
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-
-.SH AUTHOR
-
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-
-
-.\" end of man page
-
-
diff --git a/man/isamlog.1.in b/man/isamlog.1.in
new file mode 100644
index 00000000000..6040f6c4ad8
--- /dev/null
+++ b/man/isamlog.1.in
@@ -0,0 +1,107 @@
+.TH isamlog 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+isamlog - Write info about whats in a nisam log file.
+.SH USAGE
+isamlog [-?iruvIV] [-c #] [-f #] [-F filepath/] [-o #] [-R file recordpos] [-w write_file] [log-filename [table ...]]
+.SH SYNOPSIS
+.B isamlog
+.RB [ -? | -I ]
+.RB [ -V ]
+.RB [ -c ]
+.RB [ -f ]
+.RB [ -F ]
+.RB [ -i ]
+.RB [ -o ]
+.RB [ "-p #" ]
+.RB [ -r ]
+.RB [ -R ]
+.RB [ -u ]
+.RB [ -v ]
+.RB [ -w ]
+.SH DESCRIPTION
+.TP
+.BR isamlog
+.TP
+.BR -? | -I
+info
+.TP
+.BR -V
+version
+.TP
+.BR -c
+do only # commands
+.TP
+.BR -f
+max open files
+.TP
+.BR -F
+file path
+.TP
+.BR -i
+extra info
+.TP
+.BR -o
+offset
+.TP
+.BR "-p #"
+remove # components from path
+.TP
+.BR -r
+recover
+.TP
+.BR -R
+file recordposition
+.TP
+.BR -u
+update
+.TP
+.BR -v
+verbose
+.TP
+.BR -w
+write file
+.SH NOTE
+If no file name is given isam.log is used
+One can give a second and a third '-v' for more verbose.
+Normaly one does a update (-u).
+If a recover is done all writes and all possibly updates and deletes is done
+and errors are only counted.
+If one gives table names as arguments only these tables will be updated
+
+
+
+.SH "SEE ALSO"
+isamchk(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+
+.SH AUTHOR
+
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+
+
+.\" end of man page
+
+
diff --git a/man/mysql.1 b/man/mysql.1
deleted file mode 100644
index baf212015bd..00000000000
--- a/man/mysql.1
+++ /dev/null
@@ -1,150 +0,0 @@
-.TH mysql 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysql \- text-based client for mysqld, a SQL-based relational database daemon
-.SH SYNOPSIS
-.B mysql
-.RB [ \-B | \-\-batch ]
-.RB [ \-# | \-\-debug=
-.IR logfile ]
-.RB [ \-T | \-\-debug-info ]
-.RB [ \-e | \-\-exec=
-.IR command ]
-.RB [ \-f | \-\-force ]
-.RB [ \-? | \-\-help ]
-.RB [ \-h | \-\-host=
-.IR hostname ]
-.RB [ \-n | \-\-unbuffered ]
-.RB [ \-p[pwd] ]
-.RI [ \-\-password=[pwd] ]
-.RB [ \-P | \-\-port=
-.IR pnum ]
-.RB [ \-q | \-\-quick ]
-.RB [ \-r | \-\-raw ]
-.RB [ \-s | \-\-silent ]
-.RB [ \-S | \-\-socket=
-.IR snum ]
-.RB [ \-u | \-\-user=
-.IR uname ]
-.RB [ \-v | \-\-verbose ]
-.RB [ \-V | \-\-version ]
-.RB [ \-w | \-\-wait ]
-.SH DESCRIPTION
-The
-.IR mysql
-program provides a curses-based interface to the SQL-based database
-server daemon,
-.IR mysqld (1).
-Full fuller documentation, refer to the HTML documents installed with
-the package.
-.SH OPTIONS
-.TP
-.BR \-B | \-\-batch
-Print results with a tab as separator,
-each row on a new line.
-.TP
-\fB\-#\fP|\fB\-\-debug=\fP\fIlogfile\fP
-Employ the specified debug log.
-.TP
-.BR \-T | \-\-debug-info
-Print debug information upon exiting.
-.TP
-\fB\-e | \-\-exec=\fP\fPcommand\fP
-Execute the specified command and quit
-.BR ( \-\-batch
-is implicit).
-.TP
-.BR \-f | \-\-force
-Continue even if the face of a SQL error.
-.TP
-.BR \-? | \-\-help
-Display a help message and exit.
-.TP
-\fB\-h\fP|\fP\-\-host=\fP\fIhostname\fP
-Connect to the specified host.
-.TP
-.BR \-n | \-\-unbuffered
-Flush the buffer after each query.
-.TP
-\fB\-p\fP|\fB\-\-password\fP[\fB=\fP\fIpwd\fP]
-Employ the specified password when connecting to the database server.
-If a password is not supplied, it will be requested interactively.
-.TP
-\fB\-P\fR|\fB\-\-port=\fP\fIpnum\fP
-Employ the specified port number for connecting to the database server.
-.TP
-.BR \-q | \-\-quick
-Do not cache the result; print it row by row.
-This may slow down the server if the output is suspended.
-.TP
-.BR \-r | \-\-raw
-Write fields without conversion.
-(used with
-.BR \-\-batch ).
-.TP
-.BR \-s | \-\-silent
-Silent mode: reduce the amount of output.
-.TP
-\fB\-S\fP|\fB\-\-socket=\fP\fIsnum\fP
-Employ the specified socket file for connecting to the database server.
-.TP
-\fB\-u\fP|\fB\-\-user=\fP\fIuname\fP
-Employ the specified user name for logging in to the server.
-.TP
-.BR \-v | \-\-verbose
-Verbose mode: write more
-Specifying this option
-.I twice
-produces a tabular output format.
-.TP
-.BR \-V | \-\-version
-Print the
-.I mysql
-version number and exit.
-.TP
-.BR \-w | \-\-wait
-Wait and retry if the database server connection is down.
-.SH FILES
-.TP 2.2i
-.I /depot/bin/mysql
-executable
-.TP
-.I /depot/bin/mysqld
-executable
-.TP
-.I /depot/bin/safe_mysqld
-executable shell script for starting mysqld safely
-.TP
-.I /site/var/mysql/data
-location of database files
-.SH EXAMPLE
-You can also read a backup dump file back into MySQL with:
-.TP
-.BR mysql
-\fP\fIdatabase\fP
-.BR <
-backup-file.sql
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 6.3, distribution 3.20.20
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by R. P. C. Rodgers,
-Lister Hill National Center for Biomedical Communication,
-U.S. National Library of Medicine
-(rodgers@nlm.nih.gov).
-.\" end of man page
diff --git a/man/mysql.1.in b/man/mysql.1.in
new file mode 100644
index 00000000000..35ff48693e1
--- /dev/null
+++ b/man/mysql.1.in
@@ -0,0 +1,160 @@
+.TH mysql 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+mysql \- text-based client for mysqld, a SQL-based relational database daemon
+.SH USAGE
+mysql [OPTIONS] [Database]
+.SH SYNOPSIS
+.B mysql
+.RB [ \-B | \-\-batch ]
+.RB [ \-# | \-\-debug=
+.IR logfile ]
+.RB [ \-T | \-\-debug-info ]
+.RB [ \-e | \-\-exec=
+.IR command ]
+.RB [ \-f | \-\-force ]
+.RB [ \-? | \-\-help ]
+.RB [ \-h | \-\-host=
+.IR hostname ]
+.RB [ \-n | \-\-unbuffered ]
+.RB [ \-p[pwd] ]
+.RI [ \-\-password=[pwd] ]
+.RB [ \-P | \-\-port=
+.IR pnum ]
+.RB [ \-q | \-\-quick ]
+.RB [ \-r | \-\-raw ]
+.RB [ \-s | \-\-silent ]
+.RB [ \-S | \-\-socket=
+.IR snum ]
+.RB [ \-u | \-\-user=
+.IR uname ]
+.RB [ \-v | \-\-verbose ]
+.RB [ \-V | \-\-version ]
+.RB [ \-w | \-\-wait ]
+.SH DESCRIPTION
+The
+.IR mysql
+program provides a curses-based interface to the SQL-based database
+server daemon,
+.IR mysqld (1).
+Full fuller documentation, refer to the HTML documents installed with
+the package.
+.SH OPTIONS
+.TP
+.BR \-B | \-\-batch
+Print results with a tab as separator,
+each row on a new line.
+.TP
+\fB\-#\fP|\fB\-\-debug=\fP\fIlogfile\fP
+Employ the specified debug log.
+.TP
+.BR \-T | \-\-debug-info
+Print debug information upon exiting.
+.TP
+\fB\-e | \-\-exec=\fP\fPcommand\fP
+Execute the specified command and quit
+.BR ( \-\-batch
+is implicit).
+.TP
+.BR \-f | \-\-force
+Continue even if the face of a SQL error.
+.TP
+.BR \-? | \-\-help
+Display a help message and exit.
+.TP
+\fB\-h\fP|\fP\-\-host=\fP\fIhostname\fP
+Connect to the specified host.
+.TP
+.BR \-n | \-\-unbuffered
+Flush the buffer after each query.
+.TP
+\fB\-p\fP|\fB\-\-password\fP[\fB=\fP\fIpwd\fP]
+Employ the specified password when connecting to the database server.
+If a password is not supplied, it will be requested interactively.
+.TP
+\fB\-P\fR|\fB\-\-port=\fP\fIpnum\fP
+Employ the specified port number for connecting to the database server.
+.TP
+.BR \-q | \-\-quick
+Do not cache the result; print it row by row.
+This may slow down the server if the output is suspended.
+.TP
+.BR \-r | \-\-raw
+Write fields without conversion.
+(used with
+.BR \-\-batch ).
+.TP
+.BR \-s | \-\-silent
+Silent mode: reduce the amount of output.
+.TP
+\fB\-S\fP|\fB\-\-socket=\fP\fIsnum\fP
+Employ the specified socket file for connecting to the database server.
+.TP
+\fB\-u\fP|\fB\-\-user=\fP\fIuname\fP
+Employ the specified user name for logging in to the server.
+.TP
+.BR \-v | \-\-verbose
+Verbose mode: write more
+Specifying this option
+.I twice
+produces a tabular output format.
+.TP
+.BR \-V | \-\-version
+Print the
+.I mysql
+version number and exit.
+.TP
+.BR \-w | \-\-wait
+Wait and retry if the database server connection is down.
+.SH FILES
+.TP 2.2i
+.I @sysconfdir@/my.cnf
+MySQL configuration file
+.TP
+.I @bindir@/mysql
+Client executable
+.TP
+.I @libexecdir@/mysqld
+Server executable
+.TP
+.I @bindir@/mysqld_safe
+executable shell script for starting mysqld safely
+.TP
+.I @localstatedir@
+location of database files
+.SH EXAMPLE
+You can also read a backup dump file back into MySQL with:
+.TP
+.BR mysql
+\fP\fIdatabase\fP
+.BR <
+backup-file.sql
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 6.3, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/)
+This software comes with no warranty.
+Manual page by R. P. C. Rodgers,
+Lister Hill National Center for Biomedical Communication,
+U.S. National Library of Medicine
+(rodgers@nlm.nih.gov).
+.\" end of man page
diff --git a/man/mysql_fix_privilege_tables.1.in b/man/mysql_fix_privilege_tables.1.in
new file mode 100644
index 00000000000..1d42681f298
--- /dev/null
+++ b/man/mysql_fix_privilege_tables.1.in
@@ -0,0 +1,40 @@
+.TH mysql 1 "17 March 2003" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+mysql_fix_privilege_tables \- Fixes MySQL privilege tables.
+.SH SYNOPSIS
+mysql_fix_privilege_tables [mysql_root_password]
+.SH DESCRIPTION
+This scripts updates the mysql.user, mysql.db, mysql.host and the
+mysql.func tables to MySQL 3.22.14 and above.
+
+This is needed if you want to use the new GRANT functions,
+CREATE AGGREGATE FUNCTION or want to use the more secure passwords in 3.23
+
+If you get 'Access denied' errors, run the script again
+and give the MySQL root user password as an argument.
+
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+This manpage was written by Christian Hammers <ch@debian.org>.
+
+MySQL is available at http://www.mysql.com/.
+.\" end of man page
diff --git a/man/mysql_zap.1 b/man/mysql_zap.1
deleted file mode 100644
index e6ff7f4a0d1..00000000000
--- a/man/mysql_zap.1
+++ /dev/null
@@ -1,34 +0,0 @@
-.TH zap 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-zap - a perl script used to kill processes
-.SH USAGE
-/usr/bin/mysql_zap [-signal] [-?Ift] pattern
-.SH SYNOPSIS
-.B zap
-.RB [ \-I | \-? ]
-.RB [ \-f ]
-.RB [ \-t ]
-.SH DESCRIPTION
-.TP
-.BR zap
-supports by executing
-.TP
-.BR \-I | \-?
-info
-.TP
-.BR \-f
-force
-.TP
-.BR \-t
-test
-.SH NOTE
-If
-.BR -f
-isn't given, ask user for confirmation for each process to kill. If signal isn't given, try first with signal 15 and after that with signal 9. If
-.BR -t
-is given the processes is only shown on stdout.
-.SH "SEE ALSO"
-isamchk (1), isamlog (1), mysqlaccess (1), mysqladmin (1), mysqlbug (1), mysqld (1), mysqldump (1), mysqlshow (1), msql2mysql (1), perror (1), replace (1), safe_mysqld (1), which1 (1), zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a Michael (Monty) Widenius (monty@tcx.se), TCX Datakonsult AB (http://www.tcx.se). This software comes with no warranty. Manual page by L. (Kill-9) Pedersen (kill-9@kill-9.dk), Mercurmedia Data Model Architect / system developer (http://www.mercurmedia.com)
-.\" end of man page \ No newline at end of file
diff --git a/man/mysql_zap.1.in b/man/mysql_zap.1.in
new file mode 100644
index 00000000000..511a8feaa7c
--- /dev/null
+++ b/man/mysql_zap.1.in
@@ -0,0 +1,52 @@
+.TH zap 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+zap - a perl script used to kill processes
+.SH USAGE
+/usr/bin/mysql_zap [-signal] [-?Ift] pattern
+.SH SYNOPSIS
+.B zap
+.RB [ \-I | \-? ]
+.RB [ \-f ]
+.RB [ \-t ]
+.SH DESCRIPTION
+.TP
+.BR zap
+supports by executing
+.TP
+.BR \-I | \-?
+info
+.TP
+.BR \-f
+force
+.TP
+.BR \-t
+test
+.SH NOTE
+If
+.BR -f
+isn't given, ask user for confirmation for each process to kill. If signal isn't given, try first with signal 15 and after that with signal 9. If
+.BR -t
+is given the processes is only shown on stdout.
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ Michael (Monty) Widenius (monty@mysql.com), MySQL AB (http://www.mysql.com/). This software comes with no warranty. Manual page by L. (Kill-9) Pedersen (kill-9@kill-9.dk), Mercurmedia Data Model Architect / system developer (http://www.mercurmedia.com)
+.\" end of man page
diff --git a/man/mysqlaccess.1 b/man/mysqlaccess.1
deleted file mode 100755
index 2e0d40c823a..00000000000
--- a/man/mysqlaccess.1
+++ /dev/null
@@ -1,121 +0,0 @@
-.TH mysqlaccess 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-.BR mysqlaccess
- \- Create new users to mysql.
-.SH USAGE
-mysqlaccess [host [user [db]]] OPTIONS
-.SH SYNOPSIS
-.B mysqlaccess
-.RB [ \-? | \-\-help ]
-.RB [ \-v | \-\-version ]
-.RB [ \-p | \-\-password=# ]
-.RB [ \-h | \-\-host=# ]
-.RB [ \-d | \-\-db=# ]
-.RB [ \-U | \-\-superuser=# ]
-.RB [ \-P | \-\-spassword=# ]
-.RB [ \-H | \-\-rhost=# ]
-.RB [ \-\-old_server ]
-.RB [ \-b | \-\-brief ]
-.RB [ \-t | \-\-table ]
-.RB [ \-\-relnotes]
-.RB [ \-\-plan ]
-.RB [ \-\-howto ]
-.RB [ \-\-debug=N ]
-.RB [ \-\-copy ]
-.RB [ \-\-preview ]
-.RB [ \-\-commit ]
-.RB [ \-\-rollback ]
-.SH DESCRIPTION
-.TP
-.BR \-? | \-\-help
-display this helpscreen and exit
-.TP
-.BR \-v | \-\-version
-print information on the program `mysqlaccess'
-.TP
-.BR \-u | \-\-user=#
-username for logging in to the db
-.TP
-.BR \-p | \-\-password=#
-validate password for user
-.TP
-.BR \-h | \-\-host=#
-name or IP\-number of the host
-.TP
-.BR \-d | \-\-db=#
-name of the database
-.TP
-.BR \-U | \-\-superuser=#
-connect as superuser
-.TP
-.BR \-P | \-\-spassword=#
-password for superuser
-.TP
-.BR \-H | \-\-rhost=#
-remote MySQL\-server to connect to
-.TP
-.BR \-\-old_server
-connect to old MySQL\-server (before v3.21) which
-does not yet know how to handle full where clauses.
-.TP
-.BR \-b | \-\-brief
-single\-line tabular report
-.TP
-.BR \-t | \-\-table
-report in table\-format
-.TP
-.BR \-\-relnotes
-print release\-notes
-.TP
-.BR \-\-plan
-print suggestions/ideas for future releases
-.TP
-.BR \-\-howto
-some examples of how to run `mysqlaccess'
-.TP
-.BR \-\-debug=N
-enter debuglevel N (0..3)
-.TP
-.BR \-\-copy
-reload temporary grant\-tables from original ones
-.TP
-.BR \-\-preview
-show differences in privileges after making
-changes in (temporary) grant\-tables
-.TP
-.BR \-\-commit
-copy grant\-rules from temporary tables to grant\-tables
-(!don't forget to do an mysqladmin reload)
-.TP
-.BR \-\-rollback
-undo the last changes to the grant\-tables.
-.SH NOTE
- + At least the user and the db must be given (even with wildcards)
- + If no host is given, `localhost' is assumed
- + Wilcards (*,?,%,_) are allowed for host, user and db, but be sure
- to escape them from your shell!! (ie type \* or '*')
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-
-.\" end of man page
diff --git a/man/mysqlaccess.1.in b/man/mysqlaccess.1.in
new file mode 100644
index 00000000000..9a5e58541d2
--- /dev/null
+++ b/man/mysqlaccess.1.in
@@ -0,0 +1,126 @@
+.TH mysqlaccess 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+.BR mysqlaccess
+ \- Create new users to mysql.
+.SH USAGE
+mysqlaccess [host [user [db]]] OPTIONS
+.SH SYNOPSIS
+.B mysqlaccess
+.RB [ \-? | \-\-help ]
+.RB [ \-v | \-\-version ]
+.RB [ \-p | \-\-password=# ]
+.RB [ \-h | \-\-host=# ]
+.RB [ \-d | \-\-db=# ]
+.RB [ \-U | \-\-superuser=# ]
+.RB [ \-P | \-\-spassword=# ]
+.RB [ \-H | \-\-rhost=# ]
+.RB [ \-\-old_server ]
+.RB [ \-b | \-\-brief ]
+.RB [ \-t | \-\-table ]
+.RB [ \-\-relnotes]
+.RB [ \-\-plan ]
+.RB [ \-\-howto ]
+.RB [ \-\-debug=N ]
+.RB [ \-\-copy ]
+.RB [ \-\-preview ]
+.RB [ \-\-commit ]
+.RB [ \-\-rollback ]
+.SH DESCRIPTION
+.TP
+.BR \-? | \-\-help
+display this helpscreen and exit
+.TP
+.BR \-v | \-\-version
+print information on the program `mysqlaccess'
+.TP
+.BR \-u | \-\-user=#
+username for logging in to the db
+.TP
+.BR \-p | \-\-password=#
+validate password for user
+.TP
+.BR \-h | \-\-host=#
+name or IP\-number of the host
+.TP
+.BR \-d | \-\-db=#
+name of the database
+.TP
+.BR \-U | \-\-superuser=#
+connect as superuser
+.TP
+.BR \-P | \-\-spassword=#
+password for superuser
+.TP
+.BR \-H | \-\-rhost=#
+remote MySQL\-server to connect to
+.TP
+.BR \-\-old_server
+connect to old MySQL\-server (before v3.21) which
+does not yet know how to handle full where clauses.
+.TP
+.BR \-b | \-\-brief
+single\-line tabular report
+.TP
+.BR \-t | \-\-table
+report in table\-format
+.TP
+.BR \-\-relnotes
+print release\-notes
+.TP
+.BR \-\-plan
+print suggestions/ideas for future releases
+.TP
+.BR \-\-howto
+some examples of how to run `mysqlaccess'
+.TP
+.BR \-\-debug=N
+enter debuglevel N (0..3)
+.TP
+.BR \-\-copy
+reload temporary grant\-tables from original ones
+.TP
+.BR \-\-preview
+show differences in privileges after making
+changes in (temporary) grant\-tables
+.TP
+.BR \-\-commit
+copy grant\-rules from temporary tables to grant\-tables
+(!don't forget to do an mysqladmin reload)
+.TP
+.BR \-\-rollback
+undo the last changes to the grant\-tables.
+.SH NOTE
+At least the user and the db must be given (even with wildcards)
+If no host is given, `localhost' is assumed
+Wildcards (*,?,%,_) are allowed for host, user and db, but be sure
+to escape them from your shell!! (i.e., type \\* or '*')
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+
+.\" end of man page
diff --git a/man/mysqladmin.1 b/man/mysqladmin.1
deleted file mode 100755
index a67977dcb75..00000000000
--- a/man/mysqladmin.1
+++ /dev/null
@@ -1,208 +0,0 @@
-.TH mysqladmin 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
- mysqladmin [OPTIONS] command command.... \- A utility for performing administrative operations
-.SH OPTION SYNOPSIS
-.B mysqladmin
-.RB [ \-# | \-\-debug=
-.IR logfile ]
-.RB [ \-f | \-\-force ]
-.RB [ \-? | \-\-help ]
-.BR [ --character-sets-dir=\fP\fIdirectory\fP ]
-.RB [ \-C | \-\-compress ]
-.RB [ \-h | \-\-host=[#] ]
-.RB [ \-p[pwd] ]
-.RI [ \-\-password=[pwd] ]
-.RB [ \-P | \-\-port=
-.IR pnum ]
-.RB [ \-i | \-\-sleep=
-.IR sec ]
-.RB [ \-E | \-\-vertical ]
-.RB [ \-s | \-\-silent ]
-.RB [ \-S | \-\-socket=
-.IR # ]
-.RB [ \-r | \-\-relative ]
-.RB [ \-t | \-\-timeout=
-.IR # ]
-.RB [ \-u | \-\-user=
-.IR uname ]
-.RB [ \-v | \-\-verbose ]
-.RB [ \-V | \-\-version ]
-.RB [ \-w | \-\-wait[=retries] ]
-.SH OPTION DESCRIPTION
-You can get a list of the options your version of
-.IR mysqladmin
-supports by executing
-.BR "mysqladmin \-\-help"
-.SH OPTIONS
-.TP
-.BR \-# | \-\-debug=\fP\fIlogfile\fP
-Output debug log. Often this is 'd:t:o,filename`
-.TP
-.BR \-f | \-\-force
-Don't ask for confirmation on drop database; with
-multiple commands, continue even if an error occurs
-.TP
-.BR \-? | \-\-help
- Display help and exit
-.TP
-.BR --character-sets-dir=\fP\fIdirectory\fP
-Set the character set directory
-.TP
-.BR \-C | \-\-compress
-Use compression in server/client protocol
-.TP
-\fB\-h\fP|\fP\-\-host=\fP\fIhostname\fP
-Connect to host
-.TP
-\fB\-p\fP|\fB\-\-password\fP[\fB=\fP\fIpwd\fP]
-Password to use when connecting to server
-If password is not given it's asked from the tty
-.TP
-\fB\-P\fR|\fB\-\-port=\fP\fIpnum\fP
-Port number to use for connection
-.TP
-\fB\-i\fR|\fB\-\-sleep=\fP\fIsec\fP
-Execute commands again and again with a sleep between
-.TP
-.BR \-r | \-\-relative
-Show difference between current and previous values
-when used with
-.BR -i
-. Currently works only with
-extended-status
-.TP
-.BR \-E | \-\-vertical
-Print output vertically. Is similar to
-.BR --relative,
-but prints output vertically.
-.TP
-.BR \-s | \-\-silent
-Silently exit if one can't connect to server
-.TP
-\fB\-S\fR|\fB\-\-socket=\fP\fIfile\fP
-Socket file to use for connection
-.TP
-\fB\-t\fR|\fB\-\-timeout=\fP\fIsec\fP
-Timeout for connection to the mysqld server
-.TP
-\fB\-u\fP|\fB\-\-user=\fP\fIuname\fP
-User for login if not current user
-.TP
-.BR \-v | \-\-verbose
-Write more information
-.TP
-.BR \-V | \-\-version
-Output version information and exit
-.TP
-.BR \-w | \-\-wait
- Wait and retry if connection is down
-.SH COMMAND SYNOPSIS
-.B MySQLADMIN
-.RB [ "create \fP\fIdatabasename\fP "]
-.RB [ "drop \fP\fIdatabasename\fP" ]
-.RB [ extended-status ]
-.RB [ flush-hosts ]
-.RB [ flush-logs ]
-.RB [ flush-tables ]
-.RB [ flush-privileges ]
-.RB [ " kill id,id,... " ]
-.RB [ "password \fP\fInew-password\fP "]
-.RB [ ping ]
-.RB [ processlist ]
-.RB [ reload ]
-.RB [ refresh ]
-.RB [ shutdown ]
-.RB [ slave-start ]
-.RB [ slave-stop ]
-.RB [ status ]
-.RB [ variables ]
-.RB [ version ]
-
-.SH COMMANDS
-Where command is a one or more of: (Commands may be shortened)
-.TP
-.BR "create databasename"
-Create a new database
-.TP
-.BR "drop databasename"
-Delete a database and all its tables
-.TP
-.BR extended-status
-Gives an extended status message from the server
-.TP
-.BR flush-hosts
-Flush all cached hosts
-.TP
-.BR flush-logs
-Flush all logs
-.TP
-.BR flush-status
-Clear status variables
-.TP
-.BR flush-tables
-Flush all tables
-.TP
-.BR flush-threads
-Flush the thread cache
-.TP
-.BR flush-privileges
-Reload grant tables (same as reload)
-.TP
-.BR "kill id,id,..."
-Kill mysql threads
-.TP
-.BR "password \fP\fInew-password\fP"
-Change old password to new-password
-.TP
-.BR ping
-Check if mysqld is alive
-.TP
-.BR processlist
-Show list of active threads in server
-.TP
-.BR reload
-Reload grant tables
-.TP
-.BR refresh
-Flush all tables and close and open logfiles
-.TP
-.BR shutdown
-Take server down
-.TP
-.BR status
-Gives a short status message from the server
-.TP
-.BR variables
-Prints variables available
-.TP
-.BR version
-Get version info from server
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-.\" end of man page
-
-
-
-
-
diff --git a/man/mysqladmin.1.in b/man/mysqladmin.1.in
new file mode 100644
index 00000000000..a549f1c0e22
--- /dev/null
+++ b/man/mysqladmin.1.in
@@ -0,0 +1,209 @@
+.TH mysqladmin 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+ mysqladmin [OPTIONS] command command.... \- A utility for performing administrative operations
+.SH OPTION SYNOPSIS
+.B mysqladmin
+.RB [ \-# | \-\-debug=
+.IR logfile ]
+.RB [ \-f | \-\-force ]
+.RB [ \-? | \-\-help ]
+.BR [ --character-sets-dir=\fP\fIdirectory\fP ]
+.RB [ \-C | \-\-compress ]
+.RB [ \-h | \-\-host=[#] ]
+.RB [ \-p[pwd] ]
+.RI [ \-\-password=[pwd] ]
+.RB [ \-P | \-\-port=
+.IR pnum ]
+.RB [ \-i | \-\-sleep=
+.IR sec ]
+.RB [ \-E | \-\-vertical ]
+.RB [ \-s | \-\-silent ]
+.RB [ \-S | \-\-socket=
+.IR # ]
+.RB [ \-r | \-\-relative ]
+.RB [ \-t | \-\-timeout=
+.IR # ]
+.RB [ \-u | \-\-user=
+.IR uname ]
+.RB [ \-v | \-\-verbose ]
+.RB [ \-V | \-\-version ]
+.RB [ \-w | \-\-wait[=retries] ]
+.SH OPTION DESCRIPTION
+You can get a list of the options your version of
+.IR mysqladmin
+supports by executing
+.BR "mysqladmin \-\-help"
+.SH OPTIONS
+.TP
+.BR \-# | \-\-debug=\fP\fIlogfile\fP
+Output debug log. Often this is 'd:t:o,filename`
+.TP
+.BR \-f | \-\-force
+Don't ask for confirmation on drop database; with
+multiple commands, continue even if an error occurs
+.TP
+.BR \-? | \-\-help
+ Display help and exit
+.TP
+.BR --character-sets-dir=\fP\fIdirectory\fP
+Set the character set directory
+.TP
+.BR \-C | \-\-compress
+Use compression in server/client protocol
+.TP
+\fB\-h\fP|\fP\-\-host=\fP\fIhostname\fP
+Connect to host
+.TP
+\fB\-p\fP|\fB\-\-password\fP[\fB=\fP\fIpwd\fP]
+Password to use when connecting to server
+If password is not given it's asked from the tty
+.TP
+\fB\-P\fR|\fB\-\-port=\fP\fIpnum\fP
+Port number to use for connection
+.TP
+\fB\-i\fR|\fB\-\-sleep=\fP\fIsec\fP
+Execute commands again and again with a sleep between
+.TP
+.BR \-r | \-\-relative
+Show difference between current and previous values
+when used with
+.BR -i
+. Currently works only with
+extended-status
+.TP
+.BR \-E | \-\-vertical
+Print output vertically. Is similar to
+.BR --relative,
+but prints output vertically.
+.TP
+.BR \-s | \-\-silent
+Silently exit if one can't connect to server
+.TP
+\fB\-S\fR|\fB\-\-socket=\fP\fIfile\fP
+Socket file to use for connection
+.TP
+\fB\-t\fR|\fB\-\-timeout=\fP\fIsec\fP
+Timeout for connection to the mysqld server
+.TP
+\fB\-u\fP|\fB\-\-user=\fP\fIuname\fP
+User for login if not current user
+.TP
+.BR \-v | \-\-verbose
+Write more information
+.TP
+.BR \-V | \-\-version
+Output version information and exit
+.TP
+.BR \-w | \-\-wait
+ Wait and retry if connection is down
+.SH COMMAND SYNOPSIS
+.B MySQLADMIN
+.RB [ "create \fP\fIdatabasename\fP "]
+.RB [ "drop \fP\fIdatabasename\fP" ]
+.RB [ extended-status ]
+.RB [ flush-hosts ]
+.RB [ flush-logs ]
+.RB [ flush-tables ]
+.RB [ flush-privileges ]
+.RB [ " kill id,id,... " ]
+.RB [ "password \fP\fInew-password\fP "]
+.RB [ ping ]
+.RB [ processlist ]
+.RB [ reload ]
+.RB [ refresh ]
+.RB [ shutdown ]
+.RB [ slave-start ]
+.RB [ slave-stop ]
+.RB [ status ]
+.RB [ variables ]
+.RB [ version ]
+
+.SH COMMANDS
+Where command is a one or more of: (Commands may be shortened)
+.TP
+.BR "create databasename"
+Create a new database
+.TP
+.BR "drop databasename"
+Delete a database and all its tables
+.TP
+.BR extended-status
+Gives an extended status message from the server
+.TP
+.BR flush-hosts
+Flush all cached hosts
+.TP
+.BR flush-logs
+Flush all logs
+.TP
+.BR flush-status
+Clear status variables
+.TP
+.BR flush-tables
+Flush all tables
+.TP
+.BR flush-threads
+Flush the thread cache
+.TP
+.BR flush-privileges
+Reload grant tables (same as reload)
+.TP
+.BR "kill id,id,..."
+Kill mysql threads
+.TP
+.BR "password \fP\fInew-password\fP"
+Change old password to new-password
+.TP
+.BR ping
+Check if mysqld is alive
+.TP
+.BR processlist
+Show list of active threads in server
+.TP
+.BR reload
+Reload grant tables
+.TP
+.BR refresh
+Flush all tables and close and open logfiles
+.TP
+.BR shutdown
+Take server down
+.TP
+.BR status
+Gives a short status message from the server
+.TP
+.BR variables
+Prints variables available
+.TP
+.BR version
+Get version info from server
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+.\" end of man page
+
diff --git a/man/mysqld.1 b/man/mysqld.1
deleted file mode 100755
index b25606ceda0..00000000000
--- a/man/mysqld.1
+++ /dev/null
@@ -1,230 +0,0 @@
-.TH mysqld 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-.BR mysqld
- \- Starts the MySQL server demon
-.SH USAGE
-mysqld [OPTIONS]
-.SH SYNOPSIS
-.B mysqld
-.RB [ \-\-ansi ]
-.RB [ \-b | \-\-basedir=\fP\fIpath\fP ]
-.RB [ \-\-big-tables ]
-.RB [ \-\-bind\-address=IP ]
-.RB [ \-\-character\-sets\-dir=\fP\fIpath\fP ]
-.RB [ \-\-chroot=\fP\fIpath\fP ]
-.RB [ \-h | \-\-datadir=\fP\fIpath\fP ]
-.RB [ \-\-default\-character\-set=\fP\fIcharset\fP ]
-.RB [ \-\-default\-table\-type=\fP\fItype \fP]
-.RB [ \-\-delay\-key\-write\-for\-all\-tables ]
-.RB [ \-\-enable\-locking ]
-.RB [ \-T | \-\-exit\-info]
-.RB [ \-\-flush ]
-.RB [ \-? | \-\-help ]
-.RB [ \-\-init\-file=file ]
-.RB [ \-L | \-\-language=... ]
-.RB [ \-l | \-\-log[=file] ]
-.RB [ \-\-log\-isam[=file] ]
-.RB [ \-\-log\-slow\-queries\fP\fI[=file]\fP ]
-.RB [ \-\-log\-update\fP\fI[=file]\fP ]
-.RB [ \-\-log\-long\-format ]
-.RB [ \-\-low\-priority\-updates ]
-.RB [ \-\-memlock ]
-.RB [ " \-\-myisam\-recover [=option[,option...]]] where option is one of DEFAULT, BACKUP, FORCE or QUICK." ]
-.RB [ \-\-pid\-file=\fP\fIpath\fP ]
-.RB [ \-P | \-\-port=... ]
-.RB [ \-o | \-\-old\-protocol ]
-.RB [ \-\-one\-thread ]
-.RB [ \-O | \-\-set\-variable var=\fP\fIoption\fP ]
-.RB [ \-Sg | \-\-skip\-grant\-tables ]
-.RB [ \-\-safe\-mode ]
-.RB [ \-\-secure ]
-.RB [ \-\-skip\-concurrent\-insert ]
-.RB [ \-\-skip\-delay\-key\-write ]
-.RB [ \-\-skip\-locking ]
-.RB [ \-\-skip\-name\-resolve ]
-.RB [ \-\-skip\-networking ]
-.RB [ \-\-skip\-new ]
-.RB [ \-\-skip\-host\-cache ]
-.RB [ \-\-skip\-show\-database ]
-.RB [ \-\-skip\-thread\-priority ]
-.RB [ \-\-socket=path ]
-.RB [ \-t | \-\-tmpdir=\fP\fIpath \fP]
-.RB [ \-u | \-\-user=\fP\fIuser_name\fP ]
-.RB [ \-V | \-\-version ]
-.SH DESCRIPTION
-.TP
-.BR --ansi
-Use ANSI SQL syntax instead of MySQL syntax. See section 5.2 Running MySQL in ANSI Mode.
-.TP
-.BR -b | --basedir=\fP\fIpath \fP
-Path to installation directory. All paths are usually resolved relative to this.
-.TP
-.BR --big-tables
-Allow big result sets by saving all temporary sets on file. It solves most 'table full' errors, but also slows down the queries where in\-memory tables would suffice. Since Version 3.23.2, MySQL is able to solve it automaticaly by using memory for small temporary tables and switching to disk tables where necessary.
-.TP
-.BR \-\-bind\-address=\fP\fIIP \fP
-IP address to bind to.
-.TP
-.BR \-\-character\-sets\-dir=\fP\fIpath \fP
-Directory where character sets are. See section 10.1.1 The Character Set Used for Data and Sorting.
-.TP
-.BR \-\-chroot=\fP\fIpath \fP
-Chroot mysqld daemon during startup. Recommended security measure. It will somewhat limit LOAD DATA INFILE and SELECT ... INTO OUTFILE though.
-.TP
-.BR \-h | \-\-datadir=\fP\fIpath \fP
-Path to the database root.
-.TP
-.BR \-\-default\-character\-set=\fP\fIcharset \fP
-Set the default character set. See section 10.1.1 The Character Set Used for Data and Sorting.
-.TP
-.BR \-\-default\-table\-type=\fP\fItype \fP
-Set the default table type for tables. See section 8 MySQL Table Types.
-.TP
-.BR \-\-delay\-key\-write\-for\-all\-tables
-Don't flush key buffers between writes for any MyISAM table. See Mysql Manual section 12.2.3 Tuning Server Parameters.
-.TP
-.BR \-\-enable\-locking
-Enable system locking.
-.TP
-.BR \-T | \-\-exit\-info
-Print some debug info at exit.
-.TP
-.BR \-\-flush
-Flush all changes to disk after each SQL command. Normally MySQL only does a write of all changes to disk after each SQL command and lets the operating system handle the syncing to disk. See section 20.2 What to Do if MySQL Keeps Crashing.
-.TP
-.BR \-? | \-\-help
-Display short help and exit.
-.TP
-.BR \-\-init\-file=\fP\fIfile \fP
-Read SQL commands from this file at startup.
-.TP
-.BR \-L | \-\-language=...
-Client error messages in given language. May be given as a full path. See Mysql Manual section 10.1 What Languages Are Supported by MySQL?.
-.TP
-.BR \-l | \-\-log\fP\fI[=file] \fP
-Log connections and queries to file.
-.TP
-.BR \-\-log\-isam\fP\fI[=file] \fP
-Log all ISAM/MyISAM changes to file (only used when debugging ISAM/MyISAM).
-.TP
-.BR \-\-log\-slow\-queries\fP\fI[=file] \fP
-Log all queries that have taken more than long_query_time seconds to execute to file. See Mysql Manual section 21.5 The Slow Query Log.
-.TP
-.BR \-\-log\-update\fP\fI[=file] \fP
-Log updates to file.# where # is a unique number if not given. See Mysql Manual section 21.3 The Update Log.
-.TP
-.BR \-\-log\-long\-format
-Log some extra information to update log. If you are using
-.BR \-\-log\-slow\-queries
-then queries that are not using indexes are logged to the slow query log.
-.TP
-.BR \-\-low\-priority\-updates
-Table\-modifying operations (INSERT/DELETE/UPDATE) will have lower priority than selects. It can also be done via {INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ... to lower the priority of only one query, or by SET OPTION SQL_LOW_PRIORITY_UPDATES=1 to change the priority in one thread. See Mysql Manual section 12.2.9 Table Locking Issues.
-.TP
-.BR \-\-memlock
-Lock the mysqld process in memory. This works only if your system supports the mlockall() system call. This may help if you have a problem where the operating system is causing mysqld to swap on disk.
-.TP
-.BR " \-\-myisam\-recover [=option[,option...]]] where option is one of DEFAULT, BACKUP, FORCE or QUICK. "
-If this option is used, mysqld will on open check if the table is marked as crashed or if if the table wasn't closed properly (The last option only works if you are running with \-\-skip\-locking). If this is the case mysqld will run check on the table. If the table was corrupted, mysqld will attempt to repair it. The following options affects how the repair works.
-.BR DEFAULT
-The same as not giving any option to \-\-myisam\-recover.
-.BR BACKUP
-If the data table was changed during recover, save a backup of the `table_name.MYD' data file as `table_name\-datetime.BAK'.
-.BR FORCE
-Run recover even if we will loose more than one row from the .MYD file.
-.BR QUICK
-Don't check the rows in the table if there isn't any delete blocks.
-Before a table is automaticly repaired, mysqld will add a note about this in the error log. If you want to be able to recover from most things without user intervention, you should use the options BACKUP,FORCE. This will force a repair of a table even if some rows would be deleted, but it will keep the old data file as a backup so that you can later examine what happened.
-.TP
-.BR \-\-pid\-file=\fP\fIpath \fP
-Path to pid file used by safe_mysqld.
-.TP
-.BR \-P | \-\-port=...
-Port number to listen for TCP/IP connections.
-.TP
-.BR \-o | \-\-old\-protocol
-Use the 3.20 protocol for compatibility with some very old clients. See Mysql Manual section 4.17.3 Upgrading from Version 3.20 to Version 3.21.
-.TP
-.BR \-\-one\-thread
-Only use one thread (for debugging under Linux). See Mysql Manual section H.1 Debugging a MySQL server.
-.TP
-.BR \-O | " \-\-set\-variable var=\fP\fIoption\fP "
-Give a variable a value. \-\-help lists variables. You can find a full description for all variables in the SHOW VARIABLES section in this manual. See Mysql Manual section 7.28.4 SHOW VARIABLES. The tuning server parameters section includes information of how to optimize these. See Mysql Manual section 12.2.3 Tuning Server Parameters.
-.TP
-.BR \-Sg | \-\-skip\-grant\-tables
-This option causes the server not to use the privilege system at all. This gives everyone full access to all databases! (You can tell a running server to start using the grant tables again by executing mysqladmin flush\-privileges or mysqladmin reload.)
-.TP
-.BR \-\-safe\-mode
-Skip some optimize stages. Implies
-.BR \-\-skip\-delay\-key\-write.
-.TP
-.BR \-\-secure
-IP numbers returned by the gethostbyname() system call are checked to make sure they resolve back to the original hostname. This makes it harder for someone on the outside to get access by pretending to be another host. This option also adds some sanity checks of hostnames. The option is turned off by default in MySQL Version 3.21 because sometimes it takes a long time to perform backward resolutions. MySQL Version 3.22 caches hostnames (unless \-\-skip\-host\-cache is used) and has this option enabled by default.
-.TP
-.BR \-\-skip\-concurrent\-insert
-Turn off the ability to select and insert at the same time on MyISAM tables. (This is only to be used if you think you have found a bug in this feature).
-.TP
-.BR \-\-skip\-delay\-key\-write
-Ignore the delay_key_write option for all tables. See Mysql Manual section 12.2.3 Tuning Server Parameters.
-.TP
-.BR \-\-skip\-locking
-Don't use system locking. To use isamchk or myisamchk you must shut down the server. See Mysql Manual section 1.6 How Stable Is MySQL?. Note that in MySQL Version 3.23 you can use REPAIR and CHECK to repair/check MyISAM tables.
-.TP
-.BR \-\-skip\-name\-resolve
-Hostnames are not resolved. All Host column values in the grant tables must be IP numbers or localhost.
-.TP
-.BR \-\-skip\-networking
-Don't listen for TCP/IP connections at all. All interaction with mysqld must be made via Unix sockets. This option is highly recommended for systems where only local requests are allowed. However, this option is unsuitable for systems that use MIT\-pthreads, because the MIT\-pthreads package doesn't support Unix sockets.
-.TP
-.BR \-\-skip\-new
-Don't use new, possible wrong routines. Implies
-.BR \-\-skip\-delay\-key\-write
-. This will also set default table type to ISAM. See Mysql Manual section 8.3 ISAM Tables.
-.TP
-.BR \-\-skip\-host\-cache
-Never use host name cache for faster name\-ip resolution, but query DNS server on every connect instead.
-.TP
-.BR \-\-skip\-show\-database
-Don't allow 'SHOW DATABASE' commands, unless the user has process privilege.
-.TP
-.BR \-\-skip\-thread\-priority
-Disable using thread priorities for faster response time.
-.TP
-.BR \-\-socket=\fP\fIpath \fP
-Socket file to use for local connections instead of default /tmp/mysql.sock.
-.TP
-.BR \-t | \-\-tmpdir=\fP\fIpath\fP
-Path for temporary files. It may be useful if your default /tmp directory resides on a partition too small to hold temporary tables.
-.TP
-.BR \-u | \-\-user=\fP\fIuser_name \fP
-Run mysqld daemon as user user_name. This option is mandatory when starting mysqld as root.
-.TP
-.BR \-V | \-\-version
-Output version information and exit.
-
-.SH NOTE
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-
-.\" end of man page
diff --git a/man/mysqld.1.in b/man/mysqld.1.in
new file mode 100644
index 00000000000..719711edca2
--- /dev/null
+++ b/man/mysqld.1.in
@@ -0,0 +1,234 @@
+.TH mysqld 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+mysqld \- The MySQL server demon
+.SH USAGE
+mysqld [OPTIONS]
+.SH SYNOPSIS
+.B mysqld
+.RB [ \-\-ansi ]
+.RB [ \-b | \-\-basedir=\fP\fIpath\fP ]
+.RB [ \-\-big-tables ]
+.RB [ \-\-bind\-address=IP ]
+.RB [ \-\-character\-sets\-dir=\fP\fIpath\fP ]
+.RB [ \-\-chroot=\fP\fIpath\fP ]
+.RB [ \-h | \-\-datadir=\fP\fIpath\fP ]
+.RB [ \-\-default\-character\-set=\fP\fIcharset\fP ]
+.RB [ \-\-default\-table\-type=\fP\fItype \fP]
+.RB [ \-\-delay\-key\-write\-for\-all\-tables ]
+.RB [ \-\-enable\-locking ]
+.RB [ \-T | \-\-exit\-info]
+.RB [ \-\-flush ]
+.RB [ \-? | \-\-help ]
+.RB [ \-\-init\-file=file ]
+.RB [ \-L | \-\-language=... ]
+.RB [ \-l | \-\-log[=file] ]
+.RB [ \-\-log\-isam[=file] ]
+.RB [ \-\-log\-slow\-queries\fP\fI[=file]\fP ]
+.RB [ \-\-log\-update\fP\fI[=file]\fP ]
+.RB [ \-\-log\-long\-format ]
+.RB [ \-\-low\-priority\-updates ]
+.RB [ \-\-memlock ]
+.RB [ " \-\-myisam\-recover [=option[,option...]]] where option is one of DEFAULT, BACKUP, FORCE or QUICK." ]
+.RB [ \-\-pid\-file=\fP\fIpath\fP ]
+.RB [ \-P | \-\-port=... ]
+.RB [ \-o | \-\-old\-protocol ]
+.RB [ \-\-one\-thread ]
+.RB [ \-O | \-\-set\-variable var=\fP\fIoption\fP ]
+.RB [ \-Sg | \-\-skip\-grant\-tables ]
+.RB [ \-\-safe\-mode ]
+.RB [ \-\-secure ]
+.RB [ \-\-skip\-concurrent\-insert ]
+.RB [ \-\-skip\-delay\-key\-write ]
+.RB [ \-\-skip\-locking ]
+.RB [ \-\-skip\-name\-resolve ]
+.RB [ \-\-skip\-networking ]
+.RB [ \-\-skip\-new ]
+.RB [ \-\-skip\-host\-cache ]
+.RB [ \-\-skip\-show\-database ]
+.RB [ \-\-skip\-thread\-priority ]
+.RB [ \-\-socket=path ]
+.RB [ \-t | \-\-tmpdir=\fP\fIpath \fP]
+.RB [ \-u | \-\-user=\fP\fIuser_name\fP ]
+.RB [ \-V | \-\-version ]
+.SH DESCRIPTION
+.TP
+.BR --ansi
+Use ANSI SQL syntax instead of MySQL syntax. See section 5.2 Running MySQL in ANSI Mode.
+.TP
+.BR -b | --basedir=\fP\fIpath \fP
+Path to installation directory. All paths are usually resolved relative to this.
+.TP
+.BR --big-tables
+Allow big result sets by saving all temporary sets on file. It solves most 'table full' errors, but also slows down the queries where in\-memory tables would suffice. Since Version 3.23.2, MySQL is able to solve it automaticaly by using memory for small temporary tables and switching to disk tables where necessary.
+.TP
+.BR \-\-bind\-address=\fP\fIIP \fP
+IP address to bind to.
+.TP
+.BR \-\-character\-sets\-dir=\fP\fIpath \fP
+Directory where character sets are. See section 10.1.1 The Character Set Used for Data and Sorting.
+.TP
+.BR \-\-chroot=\fP\fIpath \fP
+Chroot mysqld daemon during startup. Recommended security measure. It will somewhat limit LOAD DATA INFILE and SELECT ... INTO OUTFILE though.
+.TP
+.BR \-h | \-\-datadir=\fP\fIpath \fP
+Path to the database root.
+.TP
+.BR \-\-default\-character\-set=\fP\fIcharset \fP
+Set the default character set. See section 10.1.1 The Character Set Used for Data and Sorting.
+.TP
+.BR \-\-default\-table\-type=\fP\fItype \fP
+Set the default table type for tables. See section 8 MySQL Table Types.
+.TP
+.BR \-\-delay\-key\-write\-for\-all\-tables
+Don't flush key buffers between writes for any MyISAM table. See Mysql Manual section 12.2.3 Tuning Server Parameters.
+.TP
+.BR \-\-enable\-locking
+Enable system locking.
+.TP
+.BR \-T | \-\-exit\-info
+Print some debug info at exit.
+.TP
+.BR \-\-flush
+Flush all changes to disk after each SQL command. Normally MySQL only does a write of all changes to disk after each SQL command and lets the operating system handle the syncing to disk. See section 20.2 What to Do if MySQL Keeps Crashing.
+.TP
+.BR \-? | \-\-help
+Display short help and exit.
+.TP
+.BR \-\-init\-file=\fP\fIfile \fP
+Read SQL commands from this file at startup.
+.TP
+.BR \-L | \-\-language=...
+Client error messages in given language. May be given as a full path. See Mysql Manual section 10.1 What Languages Are Supported by MySQL?.
+.TP
+.BR \-l | \-\-log\fP\fI[=file] \fP
+Log connections and queries to file.
+.TP
+.BR \-\-log\-isam\fP\fI[=file] \fP
+Log all ISAM/MyISAM changes to file (only used when debugging ISAM/MyISAM).
+.TP
+.BR \-\-log\-slow\-queries\fP\fI[=file] \fP
+Log all queries that have taken more than long_query_time seconds to execute to file. See Mysql Manual section 21.5 The Slow Query Log.
+.TP
+.BR \-\-log\-update\fP\fI[=file] \fP
+Log updates to file.# where # is a unique number if not given. See Mysql Manual section 21.3 The Update Log.
+.TP
+.BR \-\-log\-long\-format
+Log some extra information to update log. If you are using
+.BR \-\-log\-slow\-queries
+then queries that are not using indexes are logged to the slow query log.
+.TP
+.BR \-\-low\-priority\-updates
+Table\-modifying operations (INSERT/DELETE/UPDATE) will have lower priority than selects. It can also be done via {INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ... to lower the priority of only one query, or by SET OPTION SQL_LOW_PRIORITY_UPDATES=1 to change the priority in one thread. See Mysql Manual section 12.2.9 Table Locking Issues.
+.TP
+.BR \-\-memlock
+Lock the mysqld process in memory. This works only if your system supports the mlockall() system call. This may help if you have a problem where the operating system is causing mysqld to swap on disk.
+.TP
+.BR " \-\-myisam\-recover [=option[,option...]]] where option is one of DEFAULT, BACKUP, FORCE or QUICK. "
+If this option is used, mysqld will on open check if the table is marked as crashed or if if the table wasn't closed properly (The last option only works if you are running with \-\-skip\-locking). If this is the case mysqld will run check on the table. If the table was corrupted, mysqld will attempt to repair it. The following options affects how the repair works.
+.BR DEFAULT
+The same as not giving any option to \-\-myisam\-recover.
+.BR BACKUP
+If the data table was changed during recover, save a backup of the `table_name.MYD' data file as `table_name\-datetime.BAK'.
+.BR FORCE
+Run recover even if we will loose more than one row from the .MYD file.
+.BR QUICK
+Don't check the rows in the table if there isn't any delete blocks.
+Before a table is automaticly repaired, mysqld will add a note about this in the error log. If you want to be able to recover from most things without user intervention, you should use the options BACKUP,FORCE. This will force a repair of a table even if some rows would be deleted, but it will keep the old data file as a backup so that you can later examine what happened.
+.TP
+.BR \-\-pid\-file=\fP\fIpath \fP
+Path to pid file used by mysqld_safe.
+.TP
+.BR \-P | \-\-port=...
+Port number to listen for TCP/IP connections.
+.TP
+.BR \-o | \-\-old\-protocol
+Use the 3.20 protocol for compatibility with some very old clients. See Mysql Manual section 4.17.3 Upgrading from Version 3.20 to Version 3.21.
+.TP
+.BR \-\-one\-thread
+Only use one thread (for debugging under Linux). See Mysql Manual section H.1 Debugging a MySQL server.
+.TP
+.BR \-O | " \-\-set\-variable var=\fP\fIoption\fP "
+Give a variable a value. \-\-help lists variables. You can find a full description for all variables in the SHOW VARIABLES section in this manual. See Mysql Manual section 7.28.4 SHOW VARIABLES. The tuning server parameters section includes information of how to optimize these. See Mysql Manual section 12.2.3 Tuning Server Parameters.
+.TP
+.BR \-Sg | \-\-skip\-grant\-tables
+This option causes the server not to use the privilege system at all. This gives everyone full access to all databases! (You can tell a running server to start using the grant tables again by executing mysqladmin flush\-privileges or mysqladmin reload.)
+.TP
+.BR \-\-safe\-mode
+Skip some optimize stages. Implies
+.BR \-\-skip\-delay\-key\-write.
+.TP
+.BR \-\-secure
+IP numbers returned by the gethostbyname() system call are checked to make sure they resolve back to the original hostname. This makes it harder for someone on the outside to get access by pretending to be another host. This option also adds some sanity checks of hostnames. The option is turned off by default in MySQL Version 3.21 because sometimes it takes a long time to perform backward resolutions. MySQL Version 3.22 caches hostnames (unless \-\-skip\-host\-cache is used) and has this option enabled by default.
+.TP
+.BR \-\-skip\-concurrent\-insert
+Turn off the ability to select and insert at the same time on MyISAM tables. (This is only to be used if you think you have found a bug in this feature).
+.TP
+.BR \-\-skip\-delay\-key\-write
+Ignore the delay_key_write option for all tables. See Mysql Manual section 12.2.3 Tuning Server Parameters.
+.TP
+.BR \-\-skip\-locking
+Don't use system locking. To use isamchk or myisamchk you must shut down the server. See Mysql Manual section 1.6 How Stable Is MySQL?. Note that in MySQL Version 3.23 you can use REPAIR and CHECK to repair/check MyISAM tables.
+.TP
+.BR \-\-skip\-name\-resolve
+Hostnames are not resolved. All Host column values in the grant tables must be IP numbers or localhost.
+.TP
+.BR \-\-skip\-networking
+Don't listen for TCP/IP connections at all. All interaction with mysqld must be made via Unix sockets. This option is highly recommended for systems where only local requests are allowed. However, this option is unsuitable for systems that use MIT\-pthreads, because the MIT\-pthreads package doesn't support Unix sockets.
+.TP
+.BR \-\-skip\-new
+Don't use new, possible wrong routines. Implies
+.BR \-\-skip\-delay\-key\-write
+. This will also set default table type to ISAM. See Mysql Manual section 8.3 ISAM Tables.
+.TP
+.BR \-\-skip\-host\-cache
+Never use host name cache for faster name\-ip resolution, but query DNS server on every connect instead.
+.TP
+.BR \-\-skip\-show\-database
+Don't allow 'SHOW DATABASE' commands, unless the user has process privilege.
+.TP
+.BR \-\-skip\-thread\-priority
+Disable using thread priorities for faster response time.
+.TP
+.BR \-\-socket=\fP\fIpath \fP
+Socket file to use for local connections instead of default /tmp/mysql.sock.
+.TP
+.BR \-t | \-\-tmpdir=\fP\fIpath\fP
+Path for temporary files. It may be useful if your default /tmp directory resides on a partition too small to hold temporary tables.
+.TP
+.BR \-u | \-\-user=\fP\fIuser_name \fP
+Run mysqld daemon as user user_name. This option is mandatory when starting mysqld as root.
+.TP
+.BR \-V | \-\-version
+Output version information and exit.
+
+.SH NOTE
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+
+.\" end of man page
diff --git a/man/mysqld_multi.1 b/man/mysqld_multi.1
deleted file mode 100644
index 8e77626ad3c..00000000000
--- a/man/mysqld_multi.1
+++ /dev/null
@@ -1,90 +0,0 @@
-.TH mysqld_multi 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysqld_multi - is meant for managing several mysqld processes running in different UNIX sockets and TCP/IP ports.
-.SH USAGE
-mysqld_multi [OPTIONS] {start|stop|report} [GNR,GNR,GNR...]
-.SH SYNOPSIS
-.B mysqld_multi
-.RB [ --config-file=... ]
-.RB [ --example ]
-.RB [ --help ]
-.RB [ --log=... ]
-.RB [ --mysqladmin=... ]
-.RB [ --mysqld=... ]
-.RB [ --no-log ]
-.RB [ --password=... ]
-.RB [ --tcp-ip ]
-.RB [ --user=... ]
-.RB [ --version ]
-.SH DESCRIPTION
-.TP
-.BR mysqld_multi
-.TP
-.BR --config-file=...
-Alternative config file. NOTE: This will not affect this program\'s own options (group [mysqld_multi]), but only groups [mysqld#]. Without this option everything will be searched from the ordinary my.cnf file.
-.TP
-.BR --example
-Give an example of a config file.
-.TP
-.BR --help
-Print this help and exit.
-.TP
-.BR --log=...
-Log file. Full path to and the name for the log file. NOTE: If the file exists, everything will be appended.
-.TP
-.BR --mysqladmin=...
-mysqladmin binary to be used for a server shutdown.
-.TP
-.BR --mysqld=...
-mysqld binary to be used. Note that you can give safe_mysqld to this option also. The options are passed to mysqld. Just make sure you have mysqld in your environment variable PATH or fix safe_mysqld.
-.TP
-.BR --no-log
-Print to stdout instead of the log file. By default the log file is turned on.
-.TP
-.BR --password=...
-Password for user for mysqladmin.
-.TP
-.BR --tcp-ip
-Connect to the MySQL server(s) via the TCP/IP port instead of the UNIX socket. This affects stopping and reporting. If a socket file is missing, the server may still be running, but can be accessed only via the TCP/IP port. By default connecting is done via the UNIX socket.
-.TP
-.BR --user=...
-MySQL user for mysqladmin.
-.TP
-.BR --version
-Print the version number and exit.
-.SH NOTE
-Please see the mysql manual for more detailed information on this.
-
-
-
-.SH "SEE ALSO"
-
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-
-.SH AUTHOR
-
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-
-
-.\" end of man page
-
-
diff --git a/man/mysqld_multi.1.in b/man/mysqld_multi.1.in
new file mode 100644
index 00000000000..26e7a091b60
--- /dev/null
+++ b/man/mysqld_multi.1.in
@@ -0,0 +1,94 @@
+.TH mysqld_multi 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+mysqld_multi - is meant for managing several mysqld processes running in different UNIX sockets and TCP/IP ports.
+.SH USAGE
+mysqld_multi [OPTIONS] {start|stop|report} [GNR,GNR,GNR...]
+.SH SYNOPSIS
+.B mysqld_multi
+.RB [ --config-file=... ]
+.RB [ --example ]
+.RB [ --help ]
+.RB [ --log=... ]
+.RB [ --mysqladmin=... ]
+.RB [ --mysqld=... ]
+.RB [ --no-log ]
+.RB [ --password=... ]
+.RB [ --tcp-ip ]
+.RB [ --user=... ]
+.RB [ --version ]
+.SH DESCRIPTION
+.TP
+.BR mysqld_multi
+.TP
+.BR --config-file=...
+Alternative config file. NOTE: This will not affect this program\'s own options (group [mysqld_multi]), but only groups [mysqld#]. Without this option everything will be searched from the ordinary my.cnf file.
+.TP
+.BR --example
+Give an example of a config file.
+.TP
+.BR --help
+Print this help and exit.
+.TP
+.BR --log=...
+Log file. Full path to and the name for the log file. NOTE: If the file exists, everything will be appended.
+.TP
+.BR --mysqladmin=...
+mysqladmin binary to be used for a server shutdown.
+.TP
+.BR --mysqld=...
+mysqld binary to be used. Note that you can give mysqld_safe to this option also. The options are passed to mysqld. Just make sure you have mysqld in your environment variable PATH or fix mysqld_safe.
+.TP
+.BR --no-log
+Print to stdout instead of the log file. By default the log file is turned on.
+.TP
+.BR --password=...
+Password for user for mysqladmin.
+.TP
+.BR --tcp-ip
+Connect to the MySQL server(s) via the TCP/IP port instead of the UNIX socket. This affects stopping and reporting. If a socket file is missing, the server may still be running, but can be accessed only via the TCP/IP port. By default connecting is done via the UNIX socket.
+.TP
+.BR --user=...
+MySQL user for mysqladmin.
+.TP
+.BR --version
+Print the version number and exit.
+.SH NOTE
+Please see the mysql manual for more detailed information on this.
+
+
+
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+
+.SH AUTHOR
+
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+
+
+.\" end of man page
+
+
diff --git a/man/mysqld_safe.1.in b/man/mysqld_safe.1.in
new file mode 100644
index 00000000000..641f34677c7
--- /dev/null
+++ b/man/mysqld_safe.1.in
@@ -0,0 +1,91 @@
+.TH safe_mysqld 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+mysqld_safe \- start the mysqld daemon on Unix.
+.SH SYNOPSIS
+.B mysqld_safe
+.RB [ \-\-basedir=\fP\fIpath\fP ]
+.RB [ \-\-core\-file\-size=# ]
+.RB [ \-\-defaults\-extra\-file=\fP\fIpath\fP ]
+.RB [ \-\-defaults\-file=\fP\fIpath\fP ]
+.RB [ \-\-open\-files=# ]
+.RB [ \-\-datadir=\fP\fIpath\fP ]
+.RB [ \-\-err\-log=\fP\fIpath \fP]
+.RB [ \-\-ledir=path ]
+.RB [ \-\-log=\fP\fIpath\fP ]
+.RB [ \-\-no\-defaults ]
+.RB [ \-\-open\-files=# ]
+.RB [ \-\-pid\-file=\fP\fIpath\fP ]
+.RB [ \-\-port=# ]
+.RB [ \-\-socket=\fP\fIpath\fP ]
+.RB [ \-\-timezone=# ]
+.RB [ \-\-user=# ]
+.SH DESCRIPTION
+mysqld_safe adds some safety features such as restarting the server when an
+error occurs and logging run-time information to a log file.
+.BR
+.TP
+.BR \-\-basedir=\fP\fIpath \fP
+.TP
+.BR \-\-core\-file\-size=#
+Size of the core file mysqld should be able to create. Passed to ulimit \-c.
+.TP
+.BR \-\-defaults\-extra\-file=\fP\fIpath \fP
+.TP
+.BR \-\-defaults\-file=\fP\fIpath \fP
+.TP
+.BR \-\-datadir=\fP\fIpath \fP
+.TP
+.BR \-\-err\-log=\fP\fIpath \fP
+.TP
+.BR \-\-ledir=\fP\fIpath \fP
+Path to mysqld
+.TP
+.BR \-\-log=\fP\fIpath \fP
+.TP
+.BR \-\-no\-defaults
+.TP
+.BR \-\-open\-files=#
+Number of files mysqld should be able to open. Passed to ulimit \-n.
+.TP
+.BR \-\-pid\-file=\fP\fIpath \fP
+.TP
+.BR \-\-port=#
+.TP
+.BR \-\-socket=\fP\fIpath \fP
+.TP
+.BR \-\-timezone=#
+Set the timezone (the TZ) variable to the value of this parameter.
+.TP
+.BR \-\-user=#
+.SH NOTE
+Note that all options on the command line to mysqld_safe are passed to mysqld. If you wants to use any options in mysqld_safe that mysqld doesn't support, you must specify these in the option file.
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+
+.\" end of man page
diff --git a/man/mysqldump.1 b/man/mysqldump.1
deleted file mode 100755
index 85c0e2e0c50..00000000000
--- a/man/mysqldump.1
+++ /dev/null
@@ -1,273 +0,0 @@
-.TH mysqldump 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysqldump \- text-based client for dumping or backing up mysql databases , tables and or data.
-
-.SH USAGE
-.BR "mysqldump [\fP\fIOPTIONS\fP] database [\fP\fItables\fP]"
-.TP
-OR
-.BR "mysqldump [\fP\fIOPTIONS\fP] \-\-databases [\fP\fIOPTIONS\fP] DB1 [\fP\fIDB2 DB3...\fP]"
-.TP
-OR
-.BR "mysqldump [\fP\fIOPTIONS\fP] \-\-all-databases [\fP\fIOPTIONS\fP]"
-
-.SH OPTION SYNOPSIS
-.B mysqldump
-.RB [ \-A | \-\-all-databases ]
-.RB [ \-a | \-\-all ]
-.RB [ \-# | \-\-debug=... ]
-.RB [ \-\-character-sets-dir=...]
-.RB [ \-? | \-\-help ]
-.RB [ \-B | \-\-databases ]
-.RB [ \-c | \-\-complete-insert ]
-.RB [ \-C | \-\-compress ]
-.RB [ \-\-default-character-set=...]
-.RB [ \-e | \-\-extended-insert ]
-.RB [ \-\-add-drop-table ]
-.RB [ \-\-add-locks ]
-.RB [ \-\-allow-keywords ]
-.RB [ \-\-delayed-insert ]
-.RB [ \-F | \-\-flush-logs ]
-.RB [ \-f | \-\-force ]
-.RB [ \-h | \-\-host=... ]
-.RB [ \-l | \-\-lock-tables ]
-.RB [ \-n | \-\-no-create-db ]
-.RB [ \-t | \-\-no-create-info ]
-.RB [ \-d | \-\-no-data ]
-.RB [ \-O | \-\-set-variable var=\fP\fIoption\fP ]
-.RB [ \-\-opt ]
-.RB [ \-p | \-\-password\fP\fI[=...]\fP ]
-.RB [ \-P | \-\-port=... ]
-.RB [ \-q | \-\-quick ]
-.RB [ \-Q | \-\-quote-names ]
-.RB [ \-S | \-\-socket=... ]
-.RB [ \-\-tables ]
-.RB [ \-T | \-\-tab=... ]
-.RB [ \-u | \-\-user=# ]
-.RB [ \-v | \-\-verbose ]
-.RB [ \-V | \-\-version ]
-.RB [ \-w | \-\-where= ]
-.RB [ \-\-delayed ]
-.RB [ \-e | \-\-extended-insert ]
-.RB [ \-\-fields\-terminated\-by=... ]
-.RB [ \-\-fields\-enclosed\-by=... ]
-.RB [ \-\-fields-optionally\-enclosed\-by=... ]
-.RB [ \-\-fields\-escaped\-by=... ]
-.RB [ \-\-lines\-terminated\-by=... ]
-.RB [ \-v | \-\-verbose ]
-.RB [ \-V | \-\-version ]
-.RB [ "\-O net_buffer_length=#, where # < 16M" ]
-.SH DESCRIPTION
-Dumping definition and data mysql database or table
-.IR mysqldump
-supports by executing
-.TP
-.BR \-A | \-\-all\-databases
-Dump all the databases. This will be same as
-.BR\-\-databases
-with all databases selected.
-.TP
-.BR \-a | \-\-all
-Include all MySQL specific create options.
-.TP
-.BR \-# | \-\-debug=...
-Output debug log. Often this is 'd:t:o,filename`.
-.TP
-.BR \-\-character\-sets\-dir=...
-Directory where character sets are
-.TP
-.BR \-? | \-\-help
-Display this help message and exit.
-.TP
-.BR \-B | \-\-databases
-To dump several databases. Note the difference in
-usage; In this case no tables are given. All name
-arguments are regarded as databasenames.
-'USE db_name;' will be included in the output
-.TP
-.BR \-c | \-\-complete\-insert
-Use complete insert statements.
-.TP
-.BR \-C | \-\-compress
-Use compression in server/client protocol.
-.TP
-.BR \-\-default\-character\-set=...
-Set the default character set
-.TP
-.BR \-e | \-\-extended\-insert
-Allows utilization of the new, much faster
-INSERT syntax.
-.TP
-.BR \-\-add\-drop\-table
-Add a 'drop table' before each create.
-.TP
-.BR \-\-add\-locks
-Add locks around insert statements.
-.TP
-.BR \-\-allow\-keywords
-Allow creation of column names that are keywords.
-.TP
-.BR \-\-delayed\-insert
-Insert rows with INSERT DELAYED.
-.TP
-.BR \-F | \-\-flush\-logs
-Flush logs file in server before starting dump.
-.TP
-.BR \-f | \-\-force
-Continue even if we get an sql\-error.
-.TP
-.BR \-h | \-\-host=...
-Connect to host.
-.TP
-.BR \-l | \-\-lock\-tables
-Lock all tables for read.
-.TP
-.BR \-n | \-\-no\-create\-db
-\&'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'
-will not be put in the output. The above line will
-be added otherwise, if
-.BR \-\-databases
-or
-.BR \-\-all\-databases
-option was given.
-.TP
-.BR \-t | \-\-no\-create\-info
-Don't write table creation info.
-.TP
-.BR \-d | \-\-no\-data
-No row information.
-.TP
-.BR \-O | "\-\-set\-variable var=option"
-give a variable a value.
-.BR \-\-help
-lists variables
-.TP
-.BR \-\-opt
-Same as
-.BR " \-\-add\-drop\-table \-\-add\-locks \-\-all \-\-extended\-insert \-\-quick \-\-lock\-tables "
-.TP
-.BR \-p | \-\-password[=...]
-Password to use when connecting to server.
-If password is not given it's solicited on the tty.
-.TP
-.BR \-P | \-\-port=...
-Port number to use for connection.
-.TP
-.BR \-q | \-\-quick
-Don't buffer query, dump directly to stdout.
-.TP
-.BR \-Q | \-\-quote\-names
-Quote table and column names with `
-.TP
-.BR \-S | \-\-socket=...
-Socket file to use for connection.
-.TP
-.BR \-\-tables
-\fP\fIOverrides \fPoption
-.BR \-\-databases (\-B).
-.TP
-.BR \-T | \-\-tab=...
-Creates tab separated textfile for each table to
-given path. (creates .sql and .txt files).
-NOTE: This only works if mysqldump is run on
-the same machine as the mysqld daemon.
-.TP
-.BR \-u | \-\-user=#
-User for login if not current user.
-.TP
-.BR \-v | \-\-verbose
-Print info about the various stages.
-.TP
-.BR \-V | \-\-version
-Output version information and exit.
-.TP
-.BR \-w | \-\-where=
-dump only selected records; QUOTES mandatory!
-.TP
-.BR \-\-delayed
-Insert rows with the INSERT DELAYED command.
-.TP
-.BR \-e | \-\-extended-insert
-Use the new multiline INSERT syntax. (Gives more compact and faster inserts statements.)
-.TP
-.BR \-\-fields\-terminated\-by=...
-.TP
-.BR \-\-fields\-enclosed\-by=...
-.TP
-.TP
-.BR \-\-fields-optionally\-enclosed\-by=...
-.TP
-.BR \-\-fields\-escaped\-by=...
-.TP
-.BR \-\-lines\-terminated\-by=...
-These options are used with the
-.BR -T
-option and have the same meaning as the corresponding clauses for LOAD DATA INFILE. See Mysql manual section 7.23 LOAD DATA INFILE Syntax.
-.TP
-.BR \-v | \-\-verbose
-Verbose mode. Print out more information on what the program does.
-.TP
-.BR \-V | \-\-version
-Print version information and exit.
-.TP
-.BR "\-O net_buffer_length=#, where # < 16M "
-When creating multi-row-insert statements (as with option
-.BR --extended-insert
-or
-.BR --opt
-), mysqldump will create rows up to net_buffer_length length. If you increase this variable, you should also ensure that the max_allowed_packet variable in the MySQL server is bigger than the net_buffer_length.
-.SH EXAMPLES
-.TP
-The most normal use of mysqldump is probably for making a backup of whole databases. See Mysql Manual section 21.2 Database Backups.
-.TP
-mysqldump \-\-opt \fP\fIdatabase\fP > backup-file.sql
-.TP
-You can read this back into MySQL with:
-.TP
-.BR mysql
-\fP\fIdatabase\fP
-.BR <
-backup-file.sql
-.TP
-or
-.TP
-.BR mysql
-\-e 'source /patch\-to\-backup/backup\-file.sql' database
-.TP
-However, it's also very useful to populate another MySQL server with information from a database:
-.TP
-mysqldump \-\-opt \fP\fIdatabase\fP | mysql \-\-host=\fP\fIremote\-host\fP \-C database
-.TP
-It is possible to dump several databases with one command:
-.TP
-mysqldump \-\-databases database1 [ database2 database3... ] > my_databases.sql
-.TP
-If all the databases are wanted, one can use:
-.TP
-mysqldump \fP\fI\-\-all\-databases\fP > all_databases.sql
-
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-
-.\" end of man page
diff --git a/man/mysqldump.1.in b/man/mysqldump.1.in
new file mode 100644
index 00000000000..34d83dbe0b3
--- /dev/null
+++ b/man/mysqldump.1.in
@@ -0,0 +1,278 @@
+.TH mysqldump 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+mysqldump \- text-based client for dumping or backing up mysql databases , tables and or data.
+
+.SH USAGE
+.BR "mysqldump [\fP\fIOPTIONS\fP] database [\fP\fItables\fP]"
+.TP
+OR
+.BR "mysqldump [\fP\fIOPTIONS\fP] \-\-databases [\fP\fIOPTIONS\fP] DB1 [\fP\fIDB2 DB3...\fP]"
+.TP
+OR
+.BR "mysqldump [\fP\fIOPTIONS\fP] \-\-all-databases [\fP\fIOPTIONS\fP]"
+
+.SH OPTION SYNOPSIS
+.B mysqldump
+.RB [ \-A | \-\-all-databases ]
+.RB [ \-a | \-\-all ]
+.RB [ \-# | \-\-debug=... ]
+.RB [ \-\-character-sets-dir=...]
+.RB [ \-? | \-\-help ]
+.RB [ \-B | \-\-databases ]
+.RB [ \-c | \-\-complete-insert ]
+.RB [ \-C | \-\-compress ]
+.RB [ \-\-default-character-set=...]
+.RB [ \-e | \-\-extended-insert ]
+.RB [ \-\-add-drop-table ]
+.RB [ \-\-add-locks ]
+.RB [ \-\-allow-keywords ]
+.RB [ \-\-delayed-insert ]
+.RB [ \-F | \-\-flush-logs ]
+.RB [ \-f | \-\-force ]
+.RB [ \-h | \-\-host=... ]
+.RB [ \-l | \-\-lock-tables ]
+.RB [ \-n | \-\-no-create-db ]
+.RB [ \-t | \-\-no-create-info ]
+.RB [ \-d | \-\-no-data ]
+.RB [ \-O | \-\-set-variable var=\fP\fIoption\fP ]
+.RB [ \-\-opt ]
+.RB [ \-p | \-\-password\fP\fI[=...]\fP ]
+.RB [ \-P | \-\-port=... ]
+.RB [ \-q | \-\-quick ]
+.RB [ \-Q | \-\-quote-names ]
+.RB [ \-S | \-\-socket=... ]
+.RB [ \-\-tables ]
+.RB [ \-T | \-\-tab=... ]
+.RB [ \-u | \-\-user=# ]
+.RB [ \-v | \-\-verbose ]
+.RB [ \-V | \-\-version ]
+.RB [ \-w | \-\-where= ]
+.RB [ \-\-delayed ]
+.RB [ \-e | \-\-extended-insert ]
+.RB [ \-\-fields\-terminated\-by=... ]
+.RB [ \-\-fields\-enclosed\-by=... ]
+.RB [ \-\-fields-optionally\-enclosed\-by=... ]
+.RB [ \-\-fields\-escaped\-by=... ]
+.RB [ \-\-lines\-terminated\-by=... ]
+.RB [ \-v | \-\-verbose ]
+.RB [ \-V | \-\-version ]
+.RB [ "\-O net_buffer_length=#, where # < 16M" ]
+.SH DESCRIPTION
+Dumping definition and data mysql database or table
+.IR mysqldump
+supports by executing
+.TP
+.BR \-A | \-\-all\-databases
+Dump all the databases. This will be same as
+.BR \-\-databases
+with all databases selected.
+.TP
+.BR \-a | \-\-all
+Include all MySQL specific create options.
+.TP
+.BR \-# | \-\-debug=...
+Output debug log. Often this is 'd:t:o,filename`.
+.TP
+.BR \-\-character\-sets\-dir=...
+Directory where character sets are
+.TP
+.BR \-? | \-\-help
+Display this help message and exit.
+.TP
+.BR \-B | \-\-databases
+To dump several databases. Note the difference in
+usage; In this case no tables are given. All name
+arguments are regarded as databasenames.
+'USE db_name;' will be included in the output
+.TP
+.BR \-c | \-\-complete\-insert
+Use complete insert statements.
+.TP
+.BR \-C | \-\-compress
+Use compression in server/client protocol.
+.TP
+.BR \-\-default\-character\-set=...
+Set the default character set
+.TP
+.BR \-e | \-\-extended\-insert
+Allows utilization of the new, much faster
+INSERT syntax.
+.TP
+.BR \-\-add\-drop\-table
+Add a 'drop table' before each create.
+.TP
+.BR \-\-add\-locks
+Add locks around insert statements.
+.TP
+.BR \-\-allow\-keywords
+Allow creation of column names that are keywords.
+.TP
+.BR \-\-delayed\-insert
+Insert rows with INSERT DELAYED.
+.TP
+.BR \-F | \-\-flush\-logs
+Flush logs file in server before starting dump.
+.TP
+.BR \-f | \-\-force
+Continue even if we get an sql\-error.
+.TP
+.BR \-h | \-\-host=...
+Connect to host.
+.TP
+.BR \-l | \-\-lock\-tables
+Lock all tables for read.
+.TP
+.BR \-n | \-\-no\-create\-db
+\&'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'
+will not be put in the output. The above line will
+be added otherwise, if
+.BR \-\-databases
+or
+.BR \-\-all\-databases
+option was given.
+.TP
+.BR \-t | \-\-no\-create\-info
+Don't write table creation info.
+.TP
+.BR \-d | \-\-no\-data
+No row information.
+.TP
+.BR \-O | "\-\-set\-variable var=option"
+give a variable a value.
+.BR \-\-help
+lists variables
+.TP
+.BR \-\-opt
+Same as
+.BR " \-\-add\-drop\-table \-\-add\-locks \-\-all \-\-extended\-insert \-\-quick \-\-lock\-tables "
+.TP
+.BR \-p | \-\-password[=...]
+Password to use when connecting to server.
+If password is not given it's solicited on the tty.
+.TP
+.BR \-P | \-\-port=...
+Port number to use for connection.
+.TP
+.BR \-q | \-\-quick
+Don't buffer query, dump directly to stdout.
+.TP
+.BR \-Q | \-\-quote\-names
+Quote table and column names with `
+.TP
+.BR \-S | \-\-socket=...
+Socket file to use for connection.
+.TP
+.BR \-\-tables
+\fP\fIOverrides \fPoption
+.BR \-\-databases (\-B).
+.TP
+.BR \-T | \-\-tab=...
+Creates tab separated textfile for each table to
+given path. (creates .sql and .txt files).
+NOTE: This only works if mysqldump is run on
+the same machine as the mysqld daemon.
+.TP
+.BR \-u | \-\-user=#
+User for login if not current user.
+.TP
+.BR \-v | \-\-verbose
+Print info about the various stages.
+.TP
+.BR \-V | \-\-version
+Output version information and exit.
+.TP
+.BR \-w | \-\-where=
+dump only selected records; QUOTES mandatory!
+.TP
+.BR \-\-delayed
+Insert rows with the INSERT DELAYED command.
+.TP
+.BR \-e | \-\-extended-insert
+Use the new multiline INSERT syntax. (Gives more compact and faster inserts statements.)
+.TP
+.BR \-\-fields\-terminated\-by=...
+.TP
+.BR \-\-fields\-enclosed\-by=...
+.TP
+.TP
+.BR \-\-fields-optionally\-enclosed\-by=...
+.TP
+.BR \-\-fields\-escaped\-by=...
+.TP
+.BR \-\-lines\-terminated\-by=...
+These options are used with the
+.BR -T
+option and have the same meaning as the corresponding clauses for LOAD DATA INFILE. See Mysql manual section 7.23 LOAD DATA INFILE Syntax.
+.TP
+.BR \-v | \-\-verbose
+Verbose mode. Print out more information on what the program does.
+.TP
+.BR \-V | \-\-version
+Print version information and exit.
+.TP
+.BR "\-O net_buffer_length=#, where # < 16M "
+When creating multi-row-insert statements (as with option
+.BR --extended-insert
+or
+.BR --opt
+), mysqldump will create rows up to net_buffer_length length. If you increase this variable, you should also ensure that the max_allowed_packet variable in the MySQL server is bigger than the net_buffer_length.
+.SH EXAMPLES
+.TP
+The most normal use of mysqldump is probably for making a backup of whole databases. See Mysql Manual section 21.2 Database Backups.
+.TP
+mysqldump \-\-opt \fP\fIdatabase\fP > backup-file.sql
+.TP
+You can read this back into MySQL with:
+.TP
+.BR mysql
+\fP\fIdatabase\fP
+.BR <
+backup-file.sql
+.TP
+or
+.TP
+.BR mysql
+\-e 'source /patch\-to\-backup/backup\-file.sql' database
+.TP
+However, it's also very useful to populate another MySQL server with information from a database:
+.TP
+mysqldump \-\-opt \fP\fIdatabase\fP | mysql \-\-host=\fP\fIremote\-host\fP \-C database
+.TP
+It is possible to dump several databases with one command:
+.TP
+mysqldump \-\-databases database1 [ database2 database3... ] > my_databases.sql
+.TP
+If all the databases are wanted, one can use:
+.TP
+mysqldump \fP\fI\-\-all\-databases\fP > all_databases.sql
+
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+
+.\" end of man page
diff --git a/man/mysqlshow.1 b/man/mysqlshow.1
deleted file mode 100755
index 3a78be69d49..00000000000
--- a/man/mysqlshow.1
+++ /dev/null
@@ -1,93 +0,0 @@
-.TH mysqlshow 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-.BR mysqlshow
- \- Shows the structure of a mysql database (databases,tables and columns)
-.SH USAGE
-shell> mysqlshow [\fP\fIOPTIONS\fP] [\fP\fIdatabase [table [column]]\fP]
-.SH SYNOPSIS
-.B mysqlshow
-.RB [ \-# | \-\-debug=...]
-.RB [ \-? | \-\-help ]
-.RB [ \-c | \-\-character\-sets\-dir=...]
-.RB [ \-C | \-\-compress ]
-.RB [ \-h | \-\-host=... ]
-.RB [ \-i | \-\-status ]
-.RB [ \-k | \-\-keys ]
-.RB [ \-p | \-\-password\fP\fI[=...]\fP ]
-.RB [ \-P | \-\-port=... ]
-.RB [ \-S | \-\-socket=... ]
-.RB [ \-u | \-\-user=# ]
-.RB [ \-V | \-\-version ]
-.SH DESCRIPTION
-.TP
-.BR \-# | \-\-debug=...
-output debug log. Often this is 'd:t:o,filename`
-.TP
-.BR \-? | \-\-help
-display help and exit
-.TP
-.BR \-c | \-\-character\-sets\-dir=...
-Directory where character sets are
-.TP
-.BR \-C | \-\-compress
-Use compression in server/client protocol
-.TP
-.BR \-h | \-\-host=...
-connect to host
-.TP
-.BR \-i | \-\-status
-Shows a lot of extra information about each table
-.TP
-.BR \-k | \-\-keys
-show keys for table
-.TP
-.BR \-p | \-\-password \fP\fI[=...] \fP
-password to use when connecting to server
-If password is not given it's asked from the tty.
-.TP
-.BR \-P | \-\-port=...
-Port number to use for connection
-.TP
-.BR \-S | \-\-socket=...
-Socket file to use for connection
-.TP
-.BR \-u | \-\-user=#
-user for login if not current user
-.TP
-.BR \-V | \-\-version
-output version information and exit
-
-
-.SH NOTE
-If last argument contains a shell or SQL wildcard (*,?,% or _) then only
-what's matched by the wildcard is shown.
-If no database is given then all matching databases are shown.
-If no table is given then all matching tables in database are shown
-If no column is given then all matching columns and columntypes in table
-are shown
-
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-
-.\" end of man page
diff --git a/man/mysqlshow.1.in b/man/mysqlshow.1.in
new file mode 100644
index 00000000000..903d9620fd6
--- /dev/null
+++ b/man/mysqlshow.1.in
@@ -0,0 +1,98 @@
+.TH mysqlshow 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+.BR mysqlshow
+ \- Shows the structure of a mysql database (databases,tables and columns)
+.SH USAGE
+shell> mysqlshow [\fP\fIOPTIONS\fP] [\fP\fIdatabase [table [column]]\fP]
+.SH SYNOPSIS
+.B mysqlshow
+.RB [ \-# | \-\-debug=...]
+.RB [ \-? | \-\-help ]
+.RB [ \-c | \-\-character\-sets\-dir=...]
+.RB [ \-C | \-\-compress ]
+.RB [ \-h | \-\-host=... ]
+.RB [ \-i | \-\-status ]
+.RB [ \-k | \-\-keys ]
+.RB [ \-p | \-\-password\fP\fI[=...]\fP ]
+.RB [ \-P | \-\-port=... ]
+.RB [ \-S | \-\-socket=... ]
+.RB [ \-u | \-\-user=# ]
+.RB [ \-V | \-\-version ]
+.SH DESCRIPTION
+.TP
+.BR \-# | \-\-debug=...
+output debug log. Often this is 'd:t:o,filename`
+.TP
+.BR \-? | \-\-help
+display help and exit
+.TP
+.BR \-c | \-\-character\-sets\-dir=...
+Directory where character sets are
+.TP
+.BR \-C | \-\-compress
+Use compression in server/client protocol
+.TP
+.BR \-h | \-\-host=...
+connect to host
+.TP
+.BR \-i | \-\-status
+Shows a lot of extra information about each table
+.TP
+.BR \-k | \-\-keys
+show keys for table
+.TP
+.BR \-p | \-\-password \fP\fI[=...] \fP
+password to use when connecting to server
+If password is not given it's asked from the tty.
+.TP
+.BR \-P | \-\-port=...
+Port number to use for connection
+.TP
+.BR \-S | \-\-socket=...
+Socket file to use for connection
+.TP
+.BR \-u | \-\-user=#
+user for login if not current user
+.TP
+.BR \-V | \-\-version
+output version information and exit
+
+
+.SH NOTE
+If last argument contains a shell or SQL wildcard (*,?,% or _) then only
+what's matched by the wildcard is shown.
+If no database is given then all matching databases are shown.
+If no table is given then all matching tables in database are shown
+If no column is given then all matching columns and columntypes in table
+are shown
+
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysql_zap(1),
+perror(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+
+.\" end of man page
diff --git a/man/perror.1 b/man/perror.1
deleted file mode 100755
index eb6c9f39d56..00000000000
--- a/man/perror.1
+++ /dev/null
@@ -1,53 +0,0 @@
-.TH perror 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-perror \- describes a system or MySQL error code.
-.SH SYNOPSIS
-perror [OPTIONS] [ERRORCODE [ERRORCODE...]]
-.SH DESCRIPTION
-Can be used to display a description for a system error code, or an MyISAM/ISAM table handler error code.
-The error messages are mostly system dependent.
-.SH OPTIONS
-.TP
-.BR \-? | \-\-help
-Displays this help and exits.
-.TP
-.BR \-I | \-\-info
-Synonym for the above.
-.TP
-.BR \-s | \-\-silent
-Only print the error message
-.TP
-.BR \-v | \-\-verbose
-Print error code and message (default).
-.TP
-.BR \-V | \-\-version
-Displays version information and exits.
-.SH EXAMPLE
-shell> perror 64 79
-Error code 64: Machine is not on the network
-Error code 79: Can not access a needed shared library
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-
-.\" end of man page
diff --git a/man/perror.1.in b/man/perror.1.in
new file mode 100644
index 00000000000..f9efb48510b
--- /dev/null
+++ b/man/perror.1.in
@@ -0,0 +1,58 @@
+.TH perror 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+perror \- describes a system or MySQL error code.
+.SH SYNOPSIS
+perror [OPTIONS] [ERRORCODE [ERRORCODE...]]
+.SH DESCRIPTION
+Can be used to display a description for a system error code, or an MyISAM/ISAM table handler error code.
+The error messages are mostly system dependent.
+.SH OPTIONS
+.TP
+.BR \-? | \-\-help
+Displays this help and exits.
+.TP
+.BR \-I | \-\-info
+Synonym for the above.
+.TP
+.BR \-s | \-\-silent
+Only print the error message
+.TP
+.BR \-v | \-\-verbose
+Print error code and message (default).
+.TP
+.BR \-V | \-\-version
+Displays version information and exits.
+.SH EXAMPLE
+shell> perror 64 79
+Error code 64: Machine is not on the network
+Error code 79: Can not access a needed shared library
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+replace(1)
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+
+.\" end of man page
diff --git a/man/replace.1 b/man/replace.1
deleted file mode 100644
index 3c14989e392..00000000000
--- a/man/replace.1
+++ /dev/null
@@ -1,68 +0,0 @@
-.TH replace 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-.TP
-replace - A utility program that is used by msql2mysql, but that has more general applicability as well. replace changes strings in place in files or on the standard input. Uses a finite state machine to match longer strings first. Can be used to swap strings.
-.SH USAGE
-replace [-?svIV] from to from to ... -- [files]
-.TP
-or
-.TP
-replace [-?svIV] from to from to ... < fromfile > tofile
-.SH SYNOPSIS
-.B replace
-.RB [ -? | -I ]
-.RB [ -s ]
-.RB [ -v ]
-.SH DESCRIPTION
-.TP
-.BR replace
-.TP
-.BR -? | -I
-info
-.TP
-.BR -s
-silent
-.TP
-.BR -v
-verbose
-.SH EXTRA INFO
-.B Special characters in from string:
-.TP
-\\^
-Match start of line.
-.TP
-\\$
-Match end of line.
-.TP
-\\b
-Match space-character, start of line or end of line. For a end \\b the next replace starts locking at the end space-character. A \\b alone in a string matches only a space-character.
-.SH EXAMPLE
-this command swaps a and b in the given files:
-.TP
-shell> replace a b b a -- file1 file2 ...
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-.\" end of man page
-
-
diff --git a/man/replace.1.in b/man/replace.1.in
new file mode 100644
index 00000000000..395411f7e9f
--- /dev/null
+++ b/man/replace.1.in
@@ -0,0 +1,73 @@
+.TH replace 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database"
+.SH NAME
+.TP
+replace - A utility program that is used by msql2mysql, but that has more general applicability as well. replace changes strings in place in files or on the standard input. Uses a finite state machine to match longer strings first. Can be used to swap strings.
+.SH USAGE
+replace [-?svIV] from to from to ... -- [files]
+.TP
+or
+.TP
+replace [-?svIV] from to from to ... < fromfile > tofile
+.SH SYNOPSIS
+.B replace
+.RB [ -? | -I ]
+.RB [ -s ]
+.RB [ -v ]
+.SH DESCRIPTION
+.TP
+.BR replace
+.TP
+.BR -? | -I
+info
+.TP
+.BR -s
+silent
+.TP
+.BR -v
+verbose
+.SH EXTRA INFO
+.B Special characters in from string:
+.TP
+\\^
+Match start of line.
+.TP
+\\$
+Match end of line.
+.TP
+\\b
+Match space-character, start of line or end of line. For a end \\b the next replace starts locking at the end space-character. A \\b alone in a string matches only a space-character.
+.SH EXAMPLE
+this command swaps a and b in the given files:
+.TP
+shell> replace a b b a -- file1 file2 ...
+.SH "SEE ALSO"
+isamchk(1),
+isamlog(1),
+mysql(1),
+mysqlaccess(1),
+mysqladmin(1),
+mysqld(1),
+mysqld_multi(1),
+mysqld_safe(1),
+mysqldump(1),
+mysql_fix_privilege_tables(1),
+mysqlshow(1),
+mysql_zap(1),
+perror(1),
+.P
+For more information please refer to the MySQL reference
+manual, which may already be installed locally and which
+is also available online at http://www.mysql.com/doc/en/
+.SH BUGS
+Please refer to http://bugs.mysql.com/ to report bugs.
+.SH AUTHOR
+Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@
+Michael (Monty) Widenius (monty@mysql.com),
+MySQL AB (http://www.mysql.com/).
+This software comes with no warranty.
+Manual page by L. (Kill-9) Pedersen
+(kill-9@kill-9.dk), Mercurmedia Data Model Architect /
+system developer (http://www.mercurmedia.com)
+.\" end of man page
+
+
diff --git a/man/safe_mysqld.1 b/man/safe_mysqld.1
deleted file mode 100755
index 0505b973672..00000000000
--- a/man/safe_mysqld.1
+++ /dev/null
@@ -1,88 +0,0 @@
-.TH safe_mysqld 1 "19 December 2000" "MySQL 3.23" "MySQL database"
-.SH NAME
-safe_mysqld \- start the mysqld daemon on Unix.
-.SH SYNOPSIS
-.B safe_mysqld
-.RB [ \-\-basedir=\fP\fIpath\fP ]
-.RB [ \-\-core\-file\-size=# ]
-.RB [ \-\-defaults\-extra\-file=\fP\fIpath\fP ]
-.RB [ \-\-defaults\-file=\fP\fIpath\fP ]
-.RB [ \-\-open\-files=# ]
-.RB [ \-\-datadir=\fP\fIpath\fP ]
-.RB [ \-\-err\-log=\fP\fIpath \fP]
-.RB [ \-\-ledir=path ]
-.RB [ \-\-log=\fP\fIpath\fP ]
-.RB [ \-\-no\-defaults ]
-.RB [ \-\-open\-files=# ]
-.RB [ \-\-pid\-file=\fP\fIpath\fP ]
-.RB [ \-\-port=# ]
-.RB [ \-\-socket=\fP\fIpath\fP ]
-.RB [ \-\-timezone=# ]
-.RB [ \-\-user=# ]
-.SH DESCRIPTION
-safe_mysqld adds some safety features such as restarting the server when an
-error occurs and logging run-time information to a log file.
-.BR
-.TP
-.BR \-\-basedir=\fP\fIpath \fP
-.TP
-.BR \-\-core\-file\-size=#
-.TP
-.BR \-\-defaults\-extra\-file=\fP\fIpath \fP
-.TP
-.BR \-\-defaults\-file=\fP\fIpath \fP
-.TP
-.BR \-\-open\-files=#
-Size of the core file mysqld should be able to create. Passed to ulimit \-c.
-.TP
-.BR \-\-datadir=\fP\fIpath \fP
-.TP
-.BR \-\-err\-log=\fP\fIpath \fP
-.TP
-.BR \-\-ledir=\fP\fIpath \fP
-Path to mysqld
-.TP
-.BR \-\-log=\fP\fIpath \fP
-.TP
-.BR \-\-no\-defaults
-.TP
-.BR \-\-open\-files=#
-Number of files mysqld should be able to open. Passed to ulimit \-n.
-.TP
-.BR \-\-pid\-file=\fP\fIpath \fP
-.TP
-.BR \-\-port=#
-.TP
-.BR \-\-socket=\fP\fIpath \fP
-.TP
-.BR \-\-timezone=#
-Set the timezone (the TZ) variable to the value of this parameter.
-.TP
-.BR \-\-user=#
-.SH NOTE
-Note that all options on the command line to safe_mysqld are passed to mysqld. If you wants to use any options in safe_mysqld that mysqld doesn't support, you must specify these in the option file.
-.SH "SEE ALSO"
-isamchk (1),
-isamlog (1),
-mysqlaccess (1),
-mysqladmin (1),
-mysqlbug (1),
-mysqld (1),
-mysqldump (1),
-mysqlshow (1),
-msql2mysql (1),
-perror (1),
-replace (1),
-safe_mysqld (1),
-which1 (1),
-zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a
-Michael (Monty) Widenius (monty@tcx.se),
-TCX Datakonsult AB (http://www.tcx.se).
-This software comes with no warranty.
-Manual page by L. (Kill-9) Pedersen
-(kill-9@kill\-9.dk), Mercurmedia Data Model Architect /
-system developer (http://www.mercurmedia.com)
-
-.\" end of man page
diff --git a/man/which.2 b/man/which.2
index 599b68080a2..30d5557ed01 100644
--- a/man/which.2
+++ b/man/which.2
@@ -48,7 +48,7 @@ Ignore option
.BR --read-alias;
don\'t read stdin.
.SH "SEE ALSO"
-isamchk (1), isamlog (1), mysqlaccess (1), mysqladmin (1), mysqlbug (1), mysqld (1), mysqldump (1), mysqlshow (1), msql2mysql (1), perror (1), replace (1), safe_mysqld (1), which1 (1), zap (1),
+isamchk (1), isamlog (1), mysqlaccess (1), mysqladmin (1), mysqlbug (1), mysqld (1), mysqldump (1), mysqlshow (1), msql2mysql (1), perror (1), replace (1), mysqld_safe (1), which1 (1), zap (1),
.SH AUTHOR
Ver 1.0, distribution 3.23.29a Michael (Monty) Widenius (monty@tcx.se), TCX Datakonsult AB (http://www.tcx.se). This software comes with no warranty. Manual page by L. (Kill-9) Pedersen (kill-9@kill-9.dk), Mercurmedia Data Model Architect / system developer (http://www.mercurmedia.com)
.\" end of man page \ No newline at end of file
diff --git a/merge/Makefile.am b/merge/Makefile.am
index 240ff1593a9..78441e84fac 100644
--- a/merge/Makefile.am
+++ b/merge/Makefile.am
@@ -16,10 +16,10 @@
INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include
pkglib_LIBRARIES = libmerge.a
-noinst_HEADERS = mrgdef.h
-libmerge_a_SOURCES = open.c extra.c info.c _locking.c \
- rrnd.c update.c delete.c rsame.c panic.c \
- close.c create.c static.c
+noinst_HEADERS = mrg_def.h
+libmerge_a_SOURCES = mrg_open.c mrg_extra.c mrg_info.c mrg_locking.c \
+ mrg_rrnd.c mrg_update.c mrg_delete.c mrg_rsame.c \
+ mrg_panic.c mrg_close.c mrg_create.c mrg_static.c
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/merge/_locking.c b/merge/_locking.c
deleted file mode 100644
index 81582da1312..00000000000
--- a/merge/_locking.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Lock databases against read or write.
-*/
-
-#include "mrgdef.h"
-
-int mrg_lock_database(MRG_INFO *info,int lock_type)
-{
- int error,new_error;
- MRG_TABLE *file;
-
- error=0;
- for (file=info->open_tables ; file != info->end_table ; file++)
- if ((new_error=nisam_lock_database(file->table,lock_type)))
- error=new_error;
- return(error);
-}
diff --git a/merge/close.c b/merge/close.c
deleted file mode 100644
index 2b769ade8e9..00000000000
--- a/merge/close.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* close a isam-database */
-
-#include "mrgdef.h"
-
-int mrg_close(register MRG_INFO *info)
-{
- int error=0,new_error;
- MRG_TABLE *file;
- DBUG_ENTER("mrg_close");
-
- for (file=info->open_tables ; file != info->end_table ; file++)
- if ((new_error=nisam_close(file->table)))
- error=new_error;
- pthread_mutex_lock(&THR_LOCK_open);
- mrg_open_list=list_delete(mrg_open_list,&info->open_list);
- pthread_mutex_unlock(&THR_LOCK_open);
- my_free((gptr) info,MYF(0));
- if (error)
- {
- my_errno=error;
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
-}
diff --git a/merge/create.c b/merge/create.c
deleted file mode 100644
index fd2c16f9ea2..00000000000
--- a/merge/create.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Create a MERGE-file */
-
-#include "mrgdef.h"
-
- /* create file named 'name' and save filenames in it
- table_names should be NULL or a vector of string-pointers with
- a NULL-pointer last
- */
-
-int mrg_create(const char *name, const char**table_names)
-{
- int save_errno;
- uint errpos;
- File file;
- char buff[FN_REFLEN],*end;
- DBUG_ENTER("mrg_create");
-
- errpos=0;
- if ((file = my_create(fn_format(buff,name,"",MRG_NAME_EXT,4),0,
- O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
- goto err;
- errpos=1;
- if (table_names)
- for ( ; *table_names ; table_names++)
- {
- strmov(buff,*table_names);
- fn_same(buff,name,4);
- *(end=strend(buff))='\n';
- if (my_write(file,*table_names,(uint) (end-buff+1),
- MYF(MY_WME | MY_NABP)))
- goto err;
- }
- if (my_close(file,MYF(0)))
- goto err;
- DBUG_RETURN(0);
-
-err:
- save_errno=my_errno;
- switch (errpos) {
- case 1:
- VOID(my_close(file,MYF(0)));
- }
- my_errno=save_errno; /* Return right errocode */
- DBUG_RETURN(-1);
-} /* mrg_create */
diff --git a/merge/delete.c b/merge/delete.c
deleted file mode 100644
index a4ee46eedc2..00000000000
--- a/merge/delete.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Delete last read record */
-
-#include "mrgdef.h"
-
-int mrg_delete(MRG_INFO *info,const byte *record)
-{
- if (!info->current_table)
- {
- my_errno=HA_ERR_NO_ACTIVE_RECORD;
- return(-1);
- }
- return nisam_delete(info->current_table->table,record);
-}
diff --git a/merge/extra.c b/merge/extra.c
deleted file mode 100644
index c4f048a4385..00000000000
--- a/merge/extra.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Extra functions we want to do with a database
- - All flags, exept record-cache-flags, are set in all used databases
- record-cache-flags are set in mrg_rrnd when we are changing database.
-*/
-
-#include "mrgdef.h"
-
-int mrg_extra(
-MRG_INFO *info,
-enum ha_extra_function function)
-{
- MRG_TABLE *file;
-
- if (function == HA_EXTRA_CACHE)
- info->cache_in_use=1;
- else
- {
- if (function == HA_EXTRA_NO_CACHE || function == HA_EXTRA_RESET)
- info->cache_in_use=0;
- if (function == HA_EXTRA_RESET || function == HA_EXTRA_RESET_STATE)
- {
- info->current_table=0;
- info->last_used_table=info->open_tables;
- }
- for (file=info->open_tables ; file != info->end_table ; file++)
- nisam_extra(file->table,function);
- }
- return 0;
-}
diff --git a/merge/info.c b/merge/info.c
deleted file mode 100644
index d44ada8e6e6..00000000000
--- a/merge/info.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "mrgdef.h"
-
-ulong mrg_position(MRG_INFO *info)
-{
- MRG_TABLE *current_table;
-
- if (!(current_table = info->current_table) &&
- info->open_tables != info->end_table)
- current_table = info->open_tables;
- return (current_table ?
- (ulong) (current_table->table->lastpos +
- current_table->file_offset) :
- ~(ulong) 0);
-}
-
- /* If flag != 0 one only gets pos of last record */
-
-int mrg_info(MRG_INFO *info,register MERGE_INFO *x,int flag)
-{
- MRG_TABLE *current_table;
- DBUG_ENTER("mrg_info");
-
- if (!(current_table = info->current_table) &&
- info->open_tables != info->end_table)
- current_table = info->open_tables;
- x->recpos = info->current_table ?
- info->current_table->table->lastpos + info->current_table->file_offset :
- (ulong) -1L;
- if (flag != HA_STATUS_POS)
- {
- x->records = info->records;
- x->deleted = info->del;
- x->data_file_length = info->data_file_length;
- x->reclength = info->reclength;
- if (current_table)
- x->errkey = current_table->table->errkey;
- else
- { /* No tables in MRG */
- x->errkey=0;
- }
- x->options = info->options;
- }
- DBUG_RETURN(0);
-}
diff --git a/merge/mrg_close.c b/merge/mrg_close.c
new file mode 100644
index 00000000000..e835fd06e47
--- /dev/null
+++ b/merge/mrg_close.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* close a isam-database */
+
+#include "mrg_def.h"
+
+int mrg_close(register MRG_INFO *info)
+{
+ int error=0,new_error;
+ MRG_TABLE *file;
+ DBUG_ENTER("mrg_close");
+
+ for (file=info->open_tables ; file != info->end_table ; file++)
+ if ((new_error=nisam_close(file->table)))
+ error=new_error;
+ pthread_mutex_lock(&THR_LOCK_open);
+ mrg_open_list=list_delete(mrg_open_list,&info->open_list);
+ pthread_mutex_unlock(&THR_LOCK_open);
+ my_free((gptr) info,MYF(0));
+ if (error)
+ {
+ my_errno=error;
+ DBUG_RETURN(-1);
+ }
+ DBUG_RETURN(0);
+}
diff --git a/merge/mrg_create.c b/merge/mrg_create.c
new file mode 100644
index 00000000000..d55a1421647
--- /dev/null
+++ b/merge/mrg_create.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Create a MERGE-file */
+
+#include "mrg_def.h"
+
+ /* create file named 'name' and save filenames in it
+ table_names should be NULL or a vector of string-pointers with
+ a NULL-pointer last
+ */
+
+int mrg_create(const char *name, const char**table_names)
+{
+ int save_errno;
+ uint errpos;
+ File file;
+ char buff[FN_REFLEN],*end;
+ DBUG_ENTER("mrg_create");
+
+ errpos=0;
+ if ((file = my_create(fn_format(buff,name,"",MRG_NAME_EXT,4),0,
+ O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
+ goto err;
+ errpos=1;
+ if (table_names)
+ for ( ; *table_names ; table_names++)
+ {
+ strmov(buff,*table_names);
+ fn_same(buff,name,4);
+ *(end=strend(buff))='\n';
+ if (my_write(file,*table_names,(uint) (end-buff+1),
+ MYF(MY_WME | MY_NABP)))
+ goto err;
+ }
+ if (my_close(file,MYF(0)))
+ goto err;
+ DBUG_RETURN(0);
+
+err:
+ save_errno=my_errno;
+ switch (errpos) {
+ case 1:
+ VOID(my_close(file,MYF(0)));
+ }
+ my_errno=save_errno; /* Return right errocode */
+ DBUG_RETURN(-1);
+} /* mrg_create */
diff --git a/merge/mrg_def.h b/merge/mrg_def.h
new file mode 100644
index 00000000000..8b6be08c32d
--- /dev/null
+++ b/merge/mrg_def.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Denna fil includeras i alla merge-filer */
+
+#ifndef N_MAXKEY
+#include "../isam/isamdef.h"
+#endif
+
+#include "merge.h"
+
+extern LIST *mrg_open_list;
+
+#ifdef THREAD
+extern pthread_mutex_t THR_LOCK_open;
+#endif
diff --git a/merge/mrg_delete.c b/merge/mrg_delete.c
new file mode 100644
index 00000000000..920156be01e
--- /dev/null
+++ b/merge/mrg_delete.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Delete last read record */
+
+#include "mrg_def.h"
+
+int mrg_delete(MRG_INFO *info,const byte *record)
+{
+ if (!info->current_table)
+ {
+ my_errno=HA_ERR_NO_ACTIVE_RECORD;
+ return(-1);
+ }
+ return nisam_delete(info->current_table->table,record);
+}
diff --git a/merge/mrg_extra.c b/merge/mrg_extra.c
new file mode 100644
index 00000000000..d37b1aaa03c
--- /dev/null
+++ b/merge/mrg_extra.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Extra functions we want to do with a database
+ - All flags, exept record-cache-flags, are set in all used databases
+ record-cache-flags are set in mrg_rrnd when we are changing database.
+*/
+
+#include "mrg_def.h"
+
+int mrg_extra(
+MRG_INFO *info,
+enum ha_extra_function function)
+{
+ MRG_TABLE *file;
+
+ if (function == HA_EXTRA_CACHE)
+ info->cache_in_use=1;
+ else
+ {
+ if (function == HA_EXTRA_NO_CACHE || function == HA_EXTRA_RESET)
+ info->cache_in_use=0;
+ if (function == HA_EXTRA_RESET || function == HA_EXTRA_RESET_STATE)
+ {
+ info->current_table=0;
+ info->last_used_table=info->open_tables;
+ }
+ for (file=info->open_tables ; file != info->end_table ; file++)
+ nisam_extra(file->table,function);
+ }
+ return 0;
+}
diff --git a/merge/mrg_info.c b/merge/mrg_info.c
new file mode 100644
index 00000000000..57f22276487
--- /dev/null
+++ b/merge/mrg_info.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mrg_def.h"
+
+ulong mrg_position(MRG_INFO *info)
+{
+ MRG_TABLE *current_table;
+
+ if (!(current_table = info->current_table) &&
+ info->open_tables != info->end_table)
+ current_table = info->open_tables;
+ return (current_table ?
+ (ulong) (current_table->table->lastpos +
+ current_table->file_offset) :
+ ~(ulong) 0);
+}
+
+ /* If flag != 0 one only gets pos of last record */
+
+int mrg_info(MRG_INFO *info,register MERGE_INFO *x,int flag)
+{
+ MRG_TABLE *current_table;
+ DBUG_ENTER("mrg_info");
+
+ if (!(current_table = info->current_table) &&
+ info->open_tables != info->end_table)
+ current_table = info->open_tables;
+ x->recpos = info->current_table ?
+ info->current_table->table->lastpos + info->current_table->file_offset :
+ (ulong) -1L;
+ if (flag != HA_STATUS_POS)
+ {
+ x->records = info->records;
+ x->deleted = info->del;
+ x->data_file_length = info->data_file_length;
+ x->reclength = info->reclength;
+ if (current_table)
+ x->errkey = current_table->table->errkey;
+ else
+ { /* No tables in MRG */
+ x->errkey=0;
+ }
+ x->options = info->options;
+ }
+ DBUG_RETURN(0);
+}
diff --git a/merge/mrg_locking.c b/merge/mrg_locking.c
new file mode 100644
index 00000000000..bd33e047091
--- /dev/null
+++ b/merge/mrg_locking.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Lock databases against read or write.
+*/
+
+#include "mrg_def.h"
+
+int mrg_lock_database(MRG_INFO *info,int lock_type)
+{
+ int error,new_error;
+ MRG_TABLE *file;
+
+ error=0;
+ for (file=info->open_tables ; file != info->end_table ; file++)
+ if ((new_error=nisam_lock_database(file->table,lock_type)))
+ error=new_error;
+ return(error);
+}
diff --git a/merge/mrg_open.c b/merge/mrg_open.c
new file mode 100644
index 00000000000..83b776ea201
--- /dev/null
+++ b/merge/mrg_open.c
@@ -0,0 +1,150 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* open a MERGE-database */
+
+#include "mrg_def.h"
+#include <stddef.h>
+#include <errno.h>
+#ifdef VMS
+#include "static.c"
+#endif
+
+/* open a MERGE-database.
+
+ if handle_locking is 0 then exit with error if some database is locked
+ if handle_locking is 1 then wait if database is locked
+*/
+
+
+MRG_INFO *mrg_open(
+const char *name,
+int mode,
+int handle_locking)
+{
+ int save_errno,i,errpos;
+ uint files,dir_length,length, options;
+ ulonglong file_offset;
+ char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
+ MRG_INFO info,*m_info;
+ File fd;
+ IO_CACHE file;
+ N_INFO *isam,*last_isam;
+ DBUG_ENTER("mrg_open");
+
+ LINT_INIT(last_isam);
+ isam=0;
+ errpos=files=0;
+ bzero((gptr) &info,sizeof(info));
+ bzero((char*) &file,sizeof(file));
+ if ((fd=my_open(fn_format(name_buff,name,"",MRG_NAME_EXT,4),
+ O_RDONLY | O_SHARE,MYF(0))) < 0 ||
+ init_io_cache(&file, fd, IO_SIZE, READ_CACHE, 0, 0,
+ MYF(MY_WME | MY_NABP)))
+ goto err;
+ errpos=1;
+ dir_length=dirname_part(name_buff,name);
+ info.reclength=0;
+ while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
+ {
+ if ((end=buff+length)[-1] == '\n')
+ end[-1]='\0';
+ if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */
+ {
+ last_isam=isam;
+ if (!test_if_hard_path(buff))
+ {
+ VOID(strmake(name_buff+dir_length,buff,
+ sizeof(name_buff)-1-dir_length));
+ VOID(cleanup_dirname(buff,name_buff));
+ }
+ if (!(isam=nisam_open(buff,mode,test(handle_locking))))
+ goto err;
+ files++;
+ }
+ last_isam=isam;
+ if (info.reclength && info.reclength != isam->s->base.reclength)
+ {
+ my_errno=HA_ERR_WRONG_IN_RECORD;
+ goto err;
+ }
+ info.reclength=isam->s->base.reclength;
+ }
+ if (!(m_info= (MRG_INFO*) my_malloc(sizeof(MRG_INFO)+files*sizeof(MRG_TABLE),
+ MYF(MY_WME))))
+ goto err;
+ *m_info=info;
+ m_info->open_tables=(MRG_TABLE *) (m_info+1);
+ m_info->tables=files;
+
+ options= (uint) ~0;
+ for (i=files ; i-- > 0 ; )
+ {
+ m_info->open_tables[i].table=isam;
+ m_info->options|=isam->s->base.options;
+ options&=isam->s->base.options;
+ m_info->records+=isam->s->state.records;
+ m_info->del+=isam->s->state.del;
+ m_info->data_file_length=isam->s->state.data_file_length;
+ if (i)
+ isam=(N_INFO*) (isam->open_list.next->data);
+ }
+ /* Don't force readonly if not all tables are readonly */
+ if (! (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA)))
+ m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA);
+
+ /* Fix fileinfo for easyer debugging (actually set by rrnd) */
+ file_offset=0;
+ for (i=0 ; (uint) i < files ; i++)
+ {
+ m_info->open_tables[i].file_offset=(my_off_t) file_offset;
+ file_offset+=m_info->open_tables[i].table->s->state.data_file_length;
+ }
+ if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L)
+ {
+ my_errno=HA_ERR_RECORD_FILE_FULL;
+ my_free((char*) m_info,MYF(0));
+ goto err;
+ }
+
+ m_info->end_table=m_info->open_tables+files;
+ m_info->last_used_table=m_info->open_tables;
+
+ VOID(my_close(fd,MYF(0)));
+ end_io_cache(&file);
+ m_info->open_list.data=(void*) m_info;
+ pthread_mutex_lock(&THR_LOCK_open);
+ mrg_open_list=list_add(mrg_open_list,&m_info->open_list);
+ pthread_mutex_unlock(&THR_LOCK_open);
+ DBUG_RETURN(m_info);
+
+err:
+ save_errno=my_errno;
+ switch (errpos) {
+ case 1:
+ VOID(my_close(fd,MYF(0)));
+ end_io_cache(&file);
+ for (i=files ; i-- > 0 ; )
+ {
+ isam=last_isam;
+ if (i)
+ last_isam=(N_INFO*) (isam->open_list.next->data);
+ nisam_close(isam);
+ }
+ }
+ my_errno=save_errno;
+ DBUG_RETURN (NULL);
+}
diff --git a/merge/mrg_panic.c b/merge/mrg_panic.c
new file mode 100644
index 00000000000..e9ad1974d8f
--- /dev/null
+++ b/merge/mrg_panic.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mrg_def.h"
+
+ /* if flag == HA_PANIC_CLOSE then all misam files are closed */
+ /* if flag == HA_PANIC_WRITE then all misam files are unlocked and
+ all changed data in single user misam is written to file */
+ /* if flag == HA_PANIC_READ then all misam files that was locked when
+ nisam_panic(HA_PANIC_WRITE) was done is locked. A ni_readinfo() is
+ done for all single user files to get changes in database */
+
+
+int mrg_panic(
+enum ha_panic_function flag)
+{
+ int error=0;
+ LIST *list_element,*next_open;
+ MRG_INFO *info;
+ DBUG_ENTER("mrg_panic");
+
+ for (list_element=mrg_open_list ; list_element ; list_element=next_open)
+ {
+ next_open=list_element->next; /* Save if close */
+ info=(MRG_INFO*) list_element->data;
+ if (flag == HA_PANIC_CLOSE && mrg_close(info))
+ error=my_errno;
+ }
+ if (mrg_open_list && flag != HA_PANIC_CLOSE)
+ DBUG_RETURN(nisam_panic(flag));
+ if (!error) DBUG_RETURN(0);
+ my_errno=error;
+ DBUG_RETURN(-1);
+}
diff --git a/merge/mrg_rrnd.c b/merge/mrg_rrnd.c
new file mode 100644
index 00000000000..206427d74d4
--- /dev/null
+++ b/merge/mrg_rrnd.c
@@ -0,0 +1,110 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Read a record with random-access. The position to the record must
+ get by mrg_info(). The next record can be read with pos= -1 */
+
+
+#include "mrg_def.h"
+
+static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos);
+
+/*
+ If filepos == -1, read next
+ Returns same as nisam_rrnd:
+ 0 = Ok.
+ 1 = Record deleted.
+ -1 = EOF (or something, errno should be HA_ERR_END_OF_FILE)
+*/
+
+int mrg_rrnd(MRG_INFO *info,byte *buf,mrg_off_t filepos)
+{
+ int error;
+ N_INFO *isam_info;
+
+ if (filepos == ~(mrg_off_t) 0) /* Can't use HA_POS_ERROR */
+ {
+ if (!info->current_table)
+ {
+ if (info->open_tables == info->end_table)
+ { /* No tables */
+ my_errno=HA_ERR_END_OF_FILE;
+ return -1;
+ }
+ isam_info=(info->current_table=info->open_tables)->table;
+ if (info->cache_in_use)
+ nisam_extra(isam_info,HA_EXTRA_CACHE);
+ filepos=isam_info->s->pack.header_length;
+ isam_info->lastinx= (uint) -1; /* Can't forward or backward */
+ }
+ else
+ {
+ isam_info=info->current_table->table;
+ filepos= isam_info->nextpos;
+ }
+
+ for (;;)
+ {
+ isam_info->update&= HA_STATE_CHANGED;
+ if ((error=(*isam_info->s->read_rnd)(isam_info,(byte*) buf,
+ filepos,1)) >= 0 ||
+ my_errno != HA_ERR_END_OF_FILE)
+ return (error);
+ if (info->cache_in_use)
+ nisam_extra(info->current_table->table,HA_EXTRA_NO_CACHE);
+ if (info->current_table+1 == info->end_table)
+ return(-1);
+ info->current_table++;
+ info->last_used_table=info->current_table;
+ if (info->cache_in_use)
+ nisam_extra(info->current_table->table,HA_EXTRA_CACHE);
+ info->current_table->file_offset=
+ info->current_table[-1].file_offset+
+ info->current_table[-1].table->s->state.data_file_length;
+
+ isam_info=info->current_table->table;
+ filepos=isam_info->s->pack.header_length;
+ isam_info->lastinx= (uint) -1;
+ }
+ }
+ info->current_table=find_table(info->open_tables,
+ info->end_table-1,filepos);
+ isam_info=info->current_table->table;
+ isam_info->update&= HA_STATE_CHANGED;
+ return ((*isam_info->s->read_rnd)(isam_info,(byte*) buf,
+ (ulong) (filepos -
+ info->current_table->file_offset),
+ 0));
+}
+
+
+ /* Find which table to use according to file-pos */
+
+static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos)
+{
+ MRG_TABLE *mid;
+
+ while (start != end)
+ {
+ mid=start+((uint) (end-start)+1)/2;
+ if (mid->file_offset > pos)
+ end=mid-1;
+ else
+ start=mid;
+ }
+ return start;
+}
diff --git a/merge/mrg_rsame.c b/merge/mrg_rsame.c
new file mode 100644
index 00000000000..ee840bc3060
--- /dev/null
+++ b/merge/mrg_rsame.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mrg_def.h"
+
+
+int mrg_rsame(
+MRG_INFO *info,
+byte *record,
+int inx) /* not used, should be 0 */
+{
+ if (inx)
+ {
+ my_errno=HA_ERR_WRONG_INDEX;
+ return(-1);
+ }
+ if (!info->current_table)
+ {
+ my_errno=HA_ERR_NO_ACTIVE_RECORD;
+ return(-1);
+ }
+ return nisam_rsame(info->current_table->table,record,inx);
+}
diff --git a/merge/mrg_static.c b/merge/mrg_static.c
new file mode 100644
index 00000000000..1b7327c870f
--- /dev/null
+++ b/merge/mrg_static.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Static variables for pisam library. All definied here for easy making of
+ a shared library
+*/
+
+#ifndef stdin
+#include "mrg_def.h"
+#endif
+
+LIST *mrg_open_list=0;
diff --git a/merge/mrg_update.c b/merge/mrg_update.c
new file mode 100644
index 00000000000..a6650267f36
--- /dev/null
+++ b/merge/mrg_update.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Update last read record */
+
+#include "mrg_def.h"
+
+int mrg_update(
+register MRG_INFO *info,
+const byte *oldrec, const byte *newrec)
+{
+ if (!info->current_table)
+ {
+ my_errno=HA_ERR_NO_ACTIVE_RECORD;
+ return(-1);
+ }
+ return nisam_update(info->current_table->table,oldrec,newrec);
+}
diff --git a/merge/mrgdef.h b/merge/mrgdef.h
deleted file mode 100644
index 3f22c83589a..00000000000
--- a/merge/mrgdef.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Denna fil includeras i alla merge-filer */
-
-#ifndef N_MAXKEY
-#include "../isam/isamdef.h"
-#endif
-
-#include "merge.h"
-
-extern LIST *mrg_open_list;
-
-#ifdef THREAD
-extern pthread_mutex_t THR_LOCK_open;
-#endif
diff --git a/merge/open.c b/merge/open.c
deleted file mode 100644
index c1be98b7e18..00000000000
--- a/merge/open.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* open a MERGE-database */
-
-#include "mrgdef.h"
-#include <stddef.h>
-#include <errno.h>
-#ifdef VMS
-#include "static.c"
-#endif
-
-/* open a MERGE-database.
-
- if handle_locking is 0 then exit with error if some database is locked
- if handle_locking is 1 then wait if database is locked
-*/
-
-
-MRG_INFO *mrg_open(
-const char *name,
-int mode,
-int handle_locking)
-{
- int save_errno,i,errpos;
- uint files,dir_length,length;
- ulonglong file_offset;
- char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
- MRG_INFO info,*m_info;
- File fd;
- IO_CACHE file;
- N_INFO *isam,*last_isam;
- DBUG_ENTER("mrg_open");
-
- LINT_INIT(last_isam);
- isam=0;
- errpos=files=0;
- bzero((gptr) &info,sizeof(info));
- bzero((char*) &file,sizeof(file));
- if ((fd=my_open(fn_format(name_buff,name,"",MRG_NAME_EXT,4),
- O_RDONLY | O_SHARE,MYF(0))) < 0 ||
- init_io_cache(&file, fd, IO_SIZE, READ_CACHE, 0, 0,
- MYF(MY_WME | MY_NABP)))
- goto err;
- errpos=1;
- dir_length=dirname_part(name_buff,name);
- info.reclength=0;
- while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
- {
- if ((end=buff+length)[-1] == '\n')
- end[-1]='\0';
- if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */
- {
- last_isam=isam;
- if (!test_if_hard_path(buff))
- {
- VOID(strmake(name_buff+dir_length,buff,
- sizeof(name_buff)-1-dir_length));
- VOID(cleanup_dirname(buff,name_buff));
- }
- if (!(isam=nisam_open(buff,mode,test(handle_locking))))
- goto err;
- files++;
- }
- last_isam=isam;
- if (info.reclength && info.reclength != isam->s->base.reclength)
- {
- my_errno=HA_ERR_WRONG_IN_RECORD;
- goto err;
- }
- info.reclength=isam->s->base.reclength;
- }
- if (!(m_info= (MRG_INFO*) my_malloc(sizeof(MRG_INFO)+files*sizeof(MRG_TABLE),
- MYF(MY_WME))))
- goto err;
- *m_info=info;
- m_info->open_tables=(MRG_TABLE *) (m_info+1);
- m_info->tables=files;
-
- for (i=files ; i-- > 0 ; )
- {
- m_info->open_tables[i].table=isam;
- m_info->options|=isam->s->base.options;
- m_info->records+=isam->s->state.records;
- m_info->del+=isam->s->state.del;
- m_info->data_file_length=isam->s->state.data_file_length;
- if (i)
- isam=(N_INFO*) (isam->open_list.next->data);
- }
- /* Fix fileinfo for easyer debugging (actually set by rrnd) */
- file_offset=0;
- for (i=0 ; (uint) i < files ; i++)
- {
- m_info->open_tables[i].file_offset=(my_off_t) file_offset;
- file_offset+=m_info->open_tables[i].table->s->state.data_file_length;
- }
- if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L)
- {
- my_errno=HA_ERR_RECORD_FILE_FULL;
- my_free((char*) m_info,MYF(0));
- goto err;
- }
-
- m_info->end_table=m_info->open_tables+files;
- m_info->last_used_table=m_info->open_tables;
-
- VOID(my_close(fd,MYF(0)));
- end_io_cache(&file);
- m_info->open_list.data=(void*) m_info;
- pthread_mutex_lock(&THR_LOCK_open);
- mrg_open_list=list_add(mrg_open_list,&m_info->open_list);
- pthread_mutex_unlock(&THR_LOCK_open);
- DBUG_RETURN(m_info);
-
-err:
- save_errno=my_errno;
- switch (errpos) {
- case 1:
- VOID(my_close(fd,MYF(0)));
- end_io_cache(&file);
- for (i=files ; i-- > 0 ; )
- {
- isam=last_isam;
- if (i)
- last_isam=(N_INFO*) (isam->open_list.next->data);
- nisam_close(isam);
- }
- }
- my_errno=save_errno;
- DBUG_RETURN (NULL);
-}
diff --git a/merge/panic.c b/merge/panic.c
deleted file mode 100644
index cf333e3a9bf..00000000000
--- a/merge/panic.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "mrgdef.h"
-
- /* if flag == HA_PANIC_CLOSE then all misam files are closed */
- /* if flag == HA_PANIC_WRITE then all misam files are unlocked and
- all changed data in single user misam is written to file */
- /* if flag == HA_PANIC_READ then all misam files that was locked when
- nisam_panic(HA_PANIC_WRITE) was done is locked. A ni_readinfo() is
- done for all single user files to get changes in database */
-
-
-int mrg_panic(
-enum ha_panic_function flag)
-{
- int error=0;
- LIST *list_element,*next_open;
- MRG_INFO *info;
- DBUG_ENTER("mrg_panic");
-
- for (list_element=mrg_open_list ; list_element ; list_element=next_open)
- {
- next_open=list_element->next; /* Save if close */
- info=(MRG_INFO*) list_element->data;
- if (flag == HA_PANIC_CLOSE && mrg_close(info))
- error=my_errno;
- }
- if (mrg_open_list && flag != HA_PANIC_CLOSE)
- DBUG_RETURN(nisam_panic(flag));
- if (!error) DBUG_RETURN(0);
- my_errno=error;
- DBUG_RETURN(-1);
-}
diff --git a/merge/rrnd.c b/merge/rrnd.c
deleted file mode 100644
index e53982aca21..00000000000
--- a/merge/rrnd.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Read a record with random-access. The position to the record must
- get by mrg_info(). The next record can be read with pos= -1 */
-
-
-#include "mrgdef.h"
-
-static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos);
-
-/*
- If filepos == -1, read next
- Returns same as nisam_rrnd:
- 0 = Ok.
- 1 = Record deleted.
- -1 = EOF (or something, errno should be HA_ERR_END_OF_FILE)
-*/
-
-int mrg_rrnd(MRG_INFO *info,byte *buf,mrg_off_t filepos)
-{
- int error;
- N_INFO *isam_info;
-
- if (filepos == ~(mrg_off_t) 0) /* Can't use HA_POS_ERROR */
- {
- if (!info->current_table)
- {
- if (info->open_tables == info->end_table)
- { /* No tables */
- my_errno=HA_ERR_END_OF_FILE;
- return -1;
- }
- isam_info=(info->current_table=info->open_tables)->table;
- if (info->cache_in_use)
- nisam_extra(isam_info,HA_EXTRA_CACHE);
- filepos=isam_info->s->pack.header_length;
- isam_info->lastinx= (uint) -1; /* Can't forward or backward */
- }
- else
- {
- isam_info=info->current_table->table;
- filepos= isam_info->nextpos;
- }
-
- for (;;)
- {
- isam_info->update&= HA_STATE_CHANGED;
- if ((error=(*isam_info->s->read_rnd)(isam_info,(byte*) buf,
- filepos,1)) >= 0 ||
- my_errno != HA_ERR_END_OF_FILE)
- return (error);
- if (info->cache_in_use)
- nisam_extra(info->current_table->table,HA_EXTRA_NO_CACHE);
- if (info->current_table+1 == info->end_table)
- return(-1);
- info->current_table++;
- info->last_used_table=info->current_table;
- if (info->cache_in_use)
- nisam_extra(info->current_table->table,HA_EXTRA_CACHE);
- info->current_table->file_offset=
- info->current_table[-1].file_offset+
- info->current_table[-1].table->s->state.data_file_length;
-
- isam_info=info->current_table->table;
- filepos=isam_info->s->pack.header_length;
- isam_info->lastinx= (uint) -1;
- }
- }
- info->current_table=find_table(info->open_tables,
- info->end_table-1,filepos);
- isam_info=info->current_table->table;
- isam_info->update&= HA_STATE_CHANGED;
- return ((*isam_info->s->read_rnd)(isam_info,(byte*) buf,
- (ulong) (filepos -
- info->current_table->file_offset),
- 0));
-}
-
-
- /* Find which table to use according to file-pos */
-
-static MRG_TABLE *find_table(MRG_TABLE *start,MRG_TABLE *end,mrg_off_t pos)
-{
- MRG_TABLE *mid;
-
- while (start != end)
- {
- mid=start+((uint) (end-start)+1)/2;
- if (mid->file_offset > pos)
- end=mid-1;
- else
- start=mid;
- }
- return start;
-}
diff --git a/merge/rsame.c b/merge/rsame.c
deleted file mode 100644
index 4ebf25b21c1..00000000000
--- a/merge/rsame.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include "mrgdef.h"
-
-
-int mrg_rsame(
-MRG_INFO *info,
-byte *record,
-int inx) /* not used, should be 0 */
-{
- if (inx)
- {
- my_errno=HA_ERR_WRONG_INDEX;
- return(-1);
- }
- if (!info->current_table)
- {
- my_errno=HA_ERR_NO_ACTIVE_RECORD;
- return(-1);
- }
- return nisam_rsame(info->current_table->table,record,inx);
-}
diff --git a/merge/static.c b/merge/static.c
deleted file mode 100644
index e5f95ef195a..00000000000
--- a/merge/static.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- Static variables for pisam library. All definied here for easy making of
- a shared library
-*/
-
-#ifndef stdin
-#include "mrgdef.h"
-#endif
-
-LIST *mrg_open_list=0;
diff --git a/merge/update.c b/merge/update.c
deleted file mode 100644
index 9fcb82089e4..00000000000
--- a/merge/update.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Update last read record */
-
-#include "mrgdef.h"
-
-int mrg_update(
-register MRG_INFO *info,
-const byte *oldrec, const byte *newrec)
-{
- if (!info->current_table)
- {
- my_errno=HA_ERR_NO_ACTIVE_RECORD;
- return(-1);
- }
- return nisam_update(info->current_table->table,oldrec,newrec);
-}
diff --git a/mit-pthreads/.cvsignore b/mit-pthreads/.cvsignore
deleted file mode 100644
index 6b051949557..00000000000
--- a/mit-pthreads/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile
-config.cache
-config.h
-config.log
-config.status
-obj
diff --git a/mit-pthreads/COPYRIGHT b/mit-pthreads/COPYRIGHT
deleted file mode 100644
index 1b727cd8dac..00000000000
--- a/mit-pthreads/COPYRIGHT
+++ /dev/null
@@ -1,31 +0,0 @@
-Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors,
-proven@mit.edu All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by Chris Provenzano,
- the University of California, Berkeley, and contributors.
-4. Neither the name of Chris Provenzano, the University, nor the names of
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO, THE REGENTS OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/mit-pthreads/Changes-mysql b/mit-pthreads/Changes-mysql
deleted file mode 100644
index da30f66fdec..00000000000
--- a/mit-pthreads/Changes-mysql
+++ /dev/null
@@ -1,237 +0,0 @@
-Changes done to this distrubtion (pthreads-1_60_beta6) by Monty (monty@mysql.com)
-
-02.05.07
-- Hacked some files to get it to compile (not work) with glibc 2.2
- This is needed so that we can do 'make dist' in the MySQL distribution
-
-02.04.26
-- removed the following files because of copyright problems
-
-machdep/i386-sco-3.2v5/__signal.h
-machdep/i386-sco-3.2v5/__stdio.h
-machdep/i386-sco-3.2v5/__stdlib.h
-machdep/i386-sco-3.2v5/__string.h
-machdep/i386-sco-3.2v5/__time.h
-machdep/i386-sco-3.2v5/__unistd.h
-machdep/i386-sco-3.2v5/compat.h
-machdep/i386-sco-3.2v5/dirent.h
-machdep/i386-sco-3.2v5/posix/__signal.h
-machdep/i386-sco-3.2v5/socket.h
-machdep/i386-sco-3.2v5/syscall.h
-machdep/i386-sco-3.2v5/timers.h
-machdep/i386-sco-3.2v5/trash.can
-machdep/sco-3.2v5/__math.h
-machdep/sco-3.2v5/__signal.h
-machdep/sco-3.2v5/__stdio.h
-machdep/sco-3.2v5/__stdlib.h
-machdep/sco-3.2v5/__string.h
-machdep/sco-3.2v5/__time.h
-machdep/sco-3.2v5/__unistd.h
-machdep/sco-3.2v5/compat.h
-machdep/sco-3.2v5/dirent.h
-machdep/sco-3.2v5/posix/__signal.h
-machdep/sco-3.2v5/socket.h
-machdep/sco-3.2v5/syscall.h
-machdep/sco-3.2v5/timers.h
-machdep/sco-3.2v5/trash.can
-
-93.04.01
-- socket() didn't return NOTOK (-1) on error.
-- bind() didn't set error code on failure
-
-93.03.27
-- Added patch by D. Richard Hipp <drh@vnet.net> to make strtod and
- printf (of floats/doubles) thread safe. Patch provided by mevans@cti-ltd.com
-- Added patch I got from lucid@secret.org to fix lock in fork().
-
-93.03.26
-- Fixed some include files for BSD 2.0.
-- Changed the prototype of ioctl() for BSD.
-- Fixed new bug in fd_kernel.c; _fd_kern_read returned sometimes wrong errno.
-
-93.03.22
-- Change sys/cdefs.h to get it through Sun cc.
-- Added patches by Mark Evans
- 1. Crashes and hangs.
- 2. Missing functionality (namely flock())
- 3. Use of POSIX reentrant safe routines.
-
-93.03.21
-- Add patches by Larry V. Streepy to fix pthread_cancel.
- Fixed bug in Streepy's patch that checked return values of read,write..
- in fd.c (Already done in fd_sys.c)
-
-1. Added a declaration of &#34;signal&#34; to include/signal.h
-2. Modified PANIC macro to operate like assert and call a new function
- panic_kernel. Added new file pthreads/panic.c.
-3. Added support for fstatfs syscall for linux (mod to
- syscall-i386-linux-1.0.S).
-4. Added missing function declarations to machdep/linux-1.0/socket.h:
- getsockopt
- setsockopt
- getsockname
- getpeername
- send
- recv
- sendto
- recvfrom
- sendmsg
- recvmsg
- shutdown
-5. Added ifdef to avoid type conflict in machdep/linux-1.0/timers.h
-6. Fix bug in getprotoent (bogus semi-colon after if stmt).
-7. Change function name in proto_internal.c from _proto_init to
- _proto_buf.
-8. Fix bug in res_internal.c where buffer pointer was improperly
- maintained.
-9. Fix return value handling for POSIX function implementations.
-10. Fix bug in select handling where a thread could be incorrectly
- resumed with no sockets ready. Also added proper handling of
- selecting for exceptions (this was not implemented at all).
-11. Added deadlock detection to pthread_join (it can now return an
- EDEADLK error).
-12. Added support for pthread_cancel, changes to lots of files for this.
-13. Add new function __pthread_is_valid that searches the pthread list
- for a specified pthread_t value.
-
-93.03.22
-- Fixed some if the tests according to the below changes.
-
-93.03.21 by "Mati Sauks" <mati@psti.com>
-- Fixed bug if priority queue was empty or (*current)->next is empty.
-
-96.03.20 by Josip Gracin
-- Fixed gethostbyname to handle alias
-
-97.02.07
-- Removed CVS directories.
-- Commented make install in GNUmakefile.in.
-
-97.01.26 by David (david@detron.se)
-- Fixed a dist target in the GNUmakefile
-- Added #undef PTHREAD_STACK_MIN to avoid warning on solaris 2.5
-
-97.01.21 by Monty (monty@tcx.se)
-
-- Added file mysql-TODO and the patches directory.
-- Added patch p153 and p155 by Tim Hinderliter and Chris Colohan
- check the patches directory for more info.
-- Changed pthread_cond_timedwait to return ETIME instead of ETIMEDOUT
- (Required by Posix)
-- Changed the include file pthread.h to add prototypes for the following
- functions: pthread_sigmask, sigwait and sigsetwait
-- Added shutdown() and getpeername() prototypes to 'machdep/sunos-5.3/socket.h'
-- Changed __FD_NONBLOCK to (O_NONBLOCK | O_NDELAY) in
- ./machdep/engine-sparc-sunos-5.3.h
-- Added rint() prototype to math.h
-- Added new slot sighandled to 'struct pthread' for easy check if somebody
- interrupts a system call.
-- pthread_kill can now interrupt the following system calls:
- select(), read(), write(), send(), sendto(), sendmsg(), recv_timedwait(),
- recvfrom_timedwait(), readev(), writeev() and some socket functions.
-- Fixed bug in pthread_kill() which count up 'sigcount' wrongly.
- Two pthread_kill() in a row bugged the thread.
-- Merged fd_kern_wait and fd_kern_poll to 1 function and removed a
- a bug when polling select.
-- Implemented getpeername().
-- Some small optimizations.
-- Some re-indentation to make the code readable by me (Sorry about that).
-
-97.08.15 by Monty (monty@tcx.se)
-
-- Added patch by "Chris G. Demetriou" <cgd@pa.dec.com> for NetBSD/alpha.
-
-97.08.18 by Monty (monty@tcx.se)
-
-- Added new machdep definitions for HPUX-10.20,
- by JOERG_HENNE@Non-HP-Germany-om88.om.hp.com
-
-97.09.25 by Monty (monty@tcx.se)
-
-- Added some definitions for i386-SCO from the site:
- http://www.sco.com/skunkware/osr5/libraries/
-
-97.10.12 by Monty (monty@tcx.se)
-
-- Changed prototype macro __P to __P_ to avoid warnings on Solaris.
-- Fixed interruption of select() with pthread_kill() when signal handler
- used read or write.
-
-97.10.16 by Monty (monty@tcx.se)
-
-- Fixed that blocked signals doesn't interrupt threads.
-
-97.10.20 by Monty (monty@tcx.se)
-
-- Fixed broken ftruncate system call for FreeBSD 2.0
- The old one destroyed the orignal file by truncation too much.
-- Fixed prototypes for des_setkey,encrypt and setkey (according to Solaris 2.5)
-
-97.11.26 by Monty (monty@tcx.se)
-
-- Small patch to avoid compile errors on alpha-OSF1 3.2
-
-97.12.18 by Monty (monty@tcx.se)
-
-- Added fix for Irix 5.3 in __unistd.h
-
-98.01.13 by Monty (monty@tcx.se)
-- Added fd_check_entry to dup2 and table sizecheck to fd_check_entry()
- patch by Martin Fuchs <Martin@igdv.fh-darmstadt.de>
-
-98.01.18 by Monty (monty@tcx.se)
-- Added prototype for gettimeofday() for Solars 2.3
-- Added some small fixes for configure and Solaris 2.6
-
-98.01.23 by Monty (monty@tcx.se)
-- Ported to openbsd.
-- Renamed nanosleep() to pthread_nanosleep() to avoid name conflict on
- openbsd.
-- Fixed link problem with variable __sglue for Irix 5.3
- by Vladislav Malyshkin <malyshki@cs.wmich.edu>.
-
-98.03.02 by Monty (monty@tcx.se)
-- Applied patches from Curt Sampson <cjs@portal.ca>; NetBSD 1.3/i386 port.
-
-98.03.09 by Monty (monty@tcx.se)
-- Applied patches from Curt Sampson <cjs@portal.ca>; NetBSD 1.3/Alpha port.
-
-98.05.12
-- Added unixware to config.guess
-
-98.06.07
-- Added patch by Scott Dybiec <sdybiec@humanfactor.com>:
- Fixed select() returning incorrect number of active file descriptors.
-
-99.06.07 by Monty (monty@mysql.com)
-- Added patches from the NETBSD site. Should fix the following platforms:
- alpha-netbsd-1.3, sparc-netbsd-1.3, i386-netbsd, arm32-netbsd
-
-99.09.09 by Monty (monty@mysql.com)
-- Added patches from Christoph Badura <bad@oreilly.de> for NetBSD
-
-99.09.13 by Monty (monty@mysql.com)
-- Added patches from Dirk Froemberg <dirk@FreeBSD.org> for FreeBSD
-
-99.10.18 by Monty (monty@mysql.com)
-- Added patch for machdep_sys_lseek() for netbsd.
-
-99.12.30 by Monty (monty@mysql.com)
-- Added patch by Christoph Badura <bad@oreilly.de> to update mit-pthreads
- to the same version as in the NetBSD pkgsrc.
-
-00.02.24 by Monty (monty@mysql.com)
-- Added configure files to make mit-pthreads to compile and link during
- newer linux systems (needed because of the MySQL configure system).
- The resulting library has however not been verified under Linux.
-
-00.03.30 by Monty (monty@mysql.com)
-- Added chroot() and gethostname().
-
-00.10.18 by Monty (monty@mysql.com)
-- Added patch by Dave Huang <khym@bga.com> to fix problem with date/time
- on NETBSD/Alpha.
-
-01.01.11 by Monty (monty@mysql.com)
-- Added patch by Allen Briggs <briggs@ninthwonder.com> for
- Apple PowerMac 8500 w/ G3 upgrade running NetBSD/macppc
diff --git a/mit-pthreads/FAQ b/mit-pthreads/FAQ
deleted file mode 100644
index e4fd3cfc6d8..00000000000
--- a/mit-pthreads/FAQ
+++ /dev/null
@@ -1,122 +0,0 @@
-
- Answers to frequently asked questions
- for my implementation of POSIX threads
-
--------------------------------------------------------------------------------
-1. Pthreads
-
-(1.0) What is Pthreads?
-(1.1) Where can I get info on Pthreads?
-
-2. Getting, Building, Installing and Using proven's Pthreads
-
-(2.0) Where can I get the latest version of proven's Pthreads?
-(2.1) What platforms does proven's Pthreads run on?
-(2.2) What do I need to build proven's Pthreads?
-(2.3) How do I install proven's Pthreads?
-
-3. Known Problems
-
-(3.0) Tests
-(3.1) Installation
-(3.2) Missing functionality
-(3.3) Signals
-
--------------------------------------------------------------------------------
-1. Pthreads
-
-(1.0) What is Pthreads?
-
-Pthreads stands for POSIX threads and is based on the POSIX 1003.1c 1995
-thread standard. This standard passed international Standards Organization
-(ISO) Committee Document (CD) balloting in February 1995 and got the
-IEEE Standards Board approval in June 1995.
-
-
-(1.1) Where can I get info on Pthreads?
-
-You can call IEEE (908) 562-3800 which is the organization which POSIX
-belongs, and ask for POSIX 1003.1c (not 1003.4a) draft 10 (the standard
-won't be out until sometime in 1996). The draft costs $30.00 plus shipping
-which for me was $4.00. The IEEE doesn't make any of the standards available
-online.
-
-I have made documentation for some of the functions available online.
-To reference these use http://www.mit.edu:8001/people/proven/pthreads.html
-
--------------------------------------------------------------------------------
-2. Getting, Building, Installing and Using proven's Pthreads
-
-(2.0) Where can I get the latest version of proven's Pthreads?
-
-The latest version is pthreads-1_60_beta6 was release on November 16, 1996
-and is available from sipb.mit.edu:/pub/pthreads.
-
-
-(2.1) What platforms does proven's Pthreads run on?
-
-Lot's! It should run on the following platforms; the i386 processor
-running NetBSD-1.x, FreeBSD-2.x, BSDOS-2.0, Linux-1.2 and Linux-1.3;
-the r2000 (DECstation) running Ultrix-4.2; the Sparc running NetBSD-1.x,
-SunOS-4.1.3, Solaris-2.3, and Solaris-2.4; the alpha running OSF-2.3 and
-OSF-3.x; the SGI running IRIX-5.2; and the HPPA running HP/UX-9.x.
-
-Because it runs on so many platforms I don't get to compile and test every
-platform for every release. If you have a problem send mail to
-pthreads-bugs@mit.edu with the processor, OS, and version number along with
-a description of the bug.
-
-
-(2.2) What do I need to build proven's Pthreads?
-
-You will need gcc and gmake to build for all but NetBSD, FreeBSD and BSDOS.
-For those you may use either gmake or pmake (the native make).
-
-
-(2.3) How do I install proven's Pthreads?
-
-Installing pthreads is real easy. At the top level of pthreads do
-
-configure
-make
-make install
-
-It will be installed into the directory /usr/local/pthreads. If you don't
-like the location add a --prefix=<dir> option to configure. That's it.
-
-
--------------------------------------------------------------------------------
-3. Known problems.
-
-(3.0) Tests
-
-Under SunOS-4.1.x there is a bug in the kernel that prevents test_sock_1
-from passing. This bug has to do with a process tring to connect to itself.
-In respose I wrote test_sock_2 to test the socket code for SunOS which
-does work. You should have no problems using the socket code in SunOS
-so long as you don't write a program that need to connect to itself.
-
-
-(3.1) Installation
-
-The only know problem is on the SGI. You will need to use GNU tar instead
-of the native supplied one or edit the config.flags file and remove the -h
-option to tar. Aparently the -h option on IRIX 5.3 version of tar does the
-exact opposite of all the other versions of tar I've used and instead of
-following symbolic links and getting the file it archives the link.
-
-
-(3.2) Missing functionality
-
-The current release is missing cancelation, priority mutexes and others.
-I'm continuing to develope pthreads and I plan to put cancelation and
-priority mutexes and as much other stuff as I can into the 1_70 release
-
-
-(3.3) Signals
-
-Currently to intermix signals with pthreads you need to rename all calls
-to signal() and sigaction() to pthread_signal() and pthread_sigaction().
-I plan to write real wrapper routines for signal() and sigaction() for
-the 1_70 release.
-
diff --git a/mit-pthreads/GNUmakefile b/mit-pthreads/GNUmakefile
deleted file mode 100644
index e3fd53b48e5..00000000000
--- a/mit-pthreads/GNUmakefile
+++ /dev/null
@@ -1,129 +0,0 @@
-# === GNUmakefile =============================================================
-# Copyright (c) 1991, 1992, 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating libpthread.a
-#
-# 1.00 93/11/17 proven
-# -Put all the .o files into one file libpthread.a
-# -Initial cut for pthreads.
-#
-
-INSTALL_PATH = $(exec_prefix)
-
- BINDIR = $(INSTALL_PATH)/bin
- LIBDIR = $(INSTALL_PATH)/lib
- MANDIR = $(INSTALL_PATH)/man
- INCDIR = $(INSTALL_PATH)/include
- SUBINCDIR = $(INCDIR)/pthread
-
- AR = ar
- AS = gas
- CFLAGS = -I. -Iinclude -I$(srcdir)/include -DPTHREAD_KERNEL \
- -O3 -DDBUG_OFF -Werror
- CXXFLAGS = -I. -Iinclude -I$(srcdir)/include -DPTHREAD_KERNEL \
- -g -O2
- LD = gld
-
- CSRC =
-
- PTHREAD_DIR = pthreads stdlib stdio gen
- DIRS = $(PTHREAD_DIR)
-
- HEADERS =
-
- LIBRARIES = libpthread.a
-
- .CURDIR = .
-
-# force correct default target
-all:
-
-###############################################################################
-#
-# Read in any special flags that config knows about
-include config.flags
-
-# What the heck. Convert srcdir to absolute form so it looks prettier.
-srcdir := $(shell cd $(srcfoo) && pwd)
-
-################################################################################
-#
-# Here starts the nitty grity part of the Makefile.
-
-all-lib : libpthread.a
-
-include ${srcdir}/pthreads/GNUmakefile.inc
-include ${srcdir}/stdlib/GNUmakefile.inc
-include ${srcdir}/stdio/GNUmakefile.inc
-include ${srcdir}/string/GNUmakefile.inc
-include ${srcdir}/gen/GNUmakefile.inc
-include ${srcdir}/net/GNUmakefile.inc
-include ${srcdir}/scripts/GNUmakefile.inc
-
-REGULAR_OBJS= $(subst .cc,.o,$(SRCS))
-REGULAR_OBJS:= $(subst .c,.o,$(REGULAR_OBJS))
-REGULAR_OBJS:= $(subst .S,.o,$(REGULAR_OBJS))
-OBJS= $(REGULAR_OBJS) $(EXTRA_OBJS)
-REALOBJS = $(addprefix obj/, $(OBJS))
-
-$(REALOBJS) : $(config) $(types) $(paths)
-
-# Since we do not have a list of the relevant files we do a make clean
-# before copying everyting to the distribution directory.
-distdir:
- $(MAKE) clean
- cp -a . $(distdir)
- # Remove symlinks that the distribution should not have.
- rm -f $(distdir)/config.cache \
- $(distdir)/include/pthread/machdep.h \
- $(distdir)/include/pthread/posix.h \
- $(distdir)/include/sys \
- $(distdir)/machdep.c \
- $(distdir)/syscall.S \
- $(distdir)/syscall-template.S
-
-clean:
- rm -f a.out core maketmp makeout $(LIBRARIES) $(BINARIES) libpthread.*
- rm -rf obj
- cd tests && $(MAKE) clean && cd ..
-
-install-lib: $(LIBRARIES) install-dirs
- for x in $(LIBRARIES); \
- do install $$x $(DESTDIR)$(LIBDIR); \
- done
-
-# Removed make install since mysql uses this in place.
-# install-lib install-include install-bin
-install:
-
-libpthread.a: obj/libpthread.a
- rm -f libpthread.a
- ln -s obj/libpthread.a .
-
-obj/libpthread.a: ${REALOBJS}
- rm -f libpthread.a obj/new.a obj/libpthread.a
- cd obj && \
- ar r new.a ${OBJS} && \
- $(RANLIB) new.a && \
- mv -f new.a libpthread.a && \
- cd ..
-
-# For examining a combined symbol table, sizes, &c.
-libpthread.o: ${REALOBJS}
- cd obj && ld -r -o ../libpthread.o ${OBJS} && cd ..
-
-obj/x:
- if [ -d obj ]; then true; else mkdir obj; fi
- cp /dev/null obj/x
-
-GNUmakefile: config.status ${srcdir}/config/GNUmakefile.in
- $(SHELL) config.status
-
-obj/%.o: %.c obj/x
- $(CC) $(CFLAGS) -c $< -o $@
-
-obj/%.o: %.cc obj/x
- $(CXX) $(CXXFLAGS) $(CFLAGS) -c $< -o $@
-
-obj/%.o: %.S obj/x
- $(CC) $(CFLAGS) -c $< -o $@
diff --git a/mit-pthreads/NOTES b/mit-pthreads/NOTES
deleted file mode 100644
index cebdc6a396c..00000000000
--- a/mit-pthreads/NOTES
+++ /dev/null
@@ -1,59 +0,0 @@
-
-Here are some notes on the internals of the implementation.
-
-LIBC routines.
-
- Unfortuanately many of the libc routine return a pointer to static data.
-There are two methods to deal with this. One write a new routine where the
-arguments are different, and have one argument be a pointer to some space
-to store the data, or two use thread specific data and warn the user that
-data isn't valid if the calling thread is terminated.
-
-INTERNAL LOCKING
-To prevent deadlocks the following rules were used for locks.
-
-1. Local locks for mutex queues and other like things are only locked
- by running threads, at NO time will a local lock be held by
- a thread in a non running state.
-2. Only threads that are in a run state can attempt to lock another thread,
- this way, we can assume that the lock will be released shortly, and don't
- have to unlock the local lock.
-3. The only time a thread will have a pthread->lock and is not in a run
- state is when it is in the reschedule routine.
-4. The reschedule routine assumes all local locks have been released,
- there is a lock on the currently running thread (pthread_run),
- and that this thread is being rescheduled to a non running state.
- It is safe to unlock the currently running threads lock after it
- has been rescheduled.
-5. The reschedule routine locks the kernel, sets the state of the currently
- running thread, unlocks the currently running thread, calls the
- context switch routines.
-6 the kernel lock is used only ...
-
-
-7. The order of locking is ...
-
-1 local locks
-2 pthread->lock /* Assumes it will get it soon */
-3 pthread_run->lock /* Assumes it will get it soon, but must release 2 */
-4 kernel lock /* Currently assumes it will ALWAYS get it. */
-
-8. The kernel lock will be changed to a spin lock for systems that
-already support kernel threads, this way we can mutiplex threads onto
-kernel threads.
-9. There are points where the kernel is locked and it needs to get
-either a local lock or a pthread lock, if at these points the code
-fails to get the lock the kernel gives up and sets a flag which will
-be checked at a later point.
-10. Interrupts are dissabled while the kernel is locked, the interrupt
-mask must be checked afterwards or cleared in some way, after interrputs
-have been reenabled, this allows back to back interrupts, but should always
-avoid missing one.
-
-------------------------------------------------------------------------------
-Copyright (c) 1994 Chris Provenzano. All rights reserved.
-This product includes software developed by the Univeristy of California,
-Berkeley and its contributors.
-
-For further licencing and distribution restrictions see the file COPYRIGHT
-included in this directory.
diff --git a/mit-pthreads/NOTES_OSR5_BUILD_SKUNKWARE97 b/mit-pthreads/NOTES_OSR5_BUILD_SKUNKWARE97
deleted file mode 100644
index fd2e00c9860..00000000000
--- a/mit-pthreads/NOTES_OSR5_BUILD_SKUNKWARE97
+++ /dev/null
@@ -1,45 +0,0 @@
-This port to Osr5 was donated by
- ARTURO MONTES mitosys@colomsat.net.co
-Its a snapshot of the 1.60 Beta 5 version
-
-It passes all the tests except test_fork (this seems to be a problem
-with the MIT source)
-and I suspect there may also to be problems with
-the floating point initialisation and perhaps the netdb access as well
-
-
-Regarding the networking API's mind the following (ARTURO):
-
-- Always we are searching host address in /etc/hosts by default, if you
-want other behaviour let me to know.
-
-- If you haven't an entry in /etc/hosts, please create it and after test
-with DNS service.
-
-regarding floating point initialisation (ARTURO)
-
-...mit-pthreads/pthreads/tests> ./test_preemption_float
-test_preemption_float INDETERMINATE
-
-I inhibit the pthread float code, but they are a minor changes in machdep.c.
-
-> What did you do/needs to be done here ??
-
-Look into machdep.c machdep_save_float_state() and
-machdep_restore_float_state() routine. I think the initialization float
-code can have problems with pthread initialization code.
-
-----------------
-
-
-If you wish to rebuild from source you'll need the gnus devsys
-(gmake and gcc) and don't use configure to reconfigure the makefiles, etc
- ( I don't know why this is but it doesn't work)
-
-If Arturo keeps me updated with buildable snapshots I'll endeavour to keep
-the skunkware Website updated with them.
-
-
-Best of luck
-
-hops 01-Aug-97
diff --git a/mit-pthreads/README b/mit-pthreads/README
deleted file mode 100644
index 0a55bcd94bb..00000000000
--- a/mit-pthreads/README
+++ /dev/null
@@ -1,40 +0,0 @@
-This pthread package is/will be based on the POSIX1003.1c Draft 10 pthread
-standard, and Frank Muellers paper on signal handeling presented at the
-Winter 93 USENIX conference.
-
-It is currently being designed and written by me, Chris Provenzano.
-All bug, comments, and questions can be sent me at proven@mit.edu,
-or pthreads@mit.edu.
-
-PLEASE, don't send questions, bugs or patches to any of the *BSD*, Linux
-or GNU mailing lists.
-
-Thanks goes to Ken Raeburn for his help on the Sparc port, the configurator,
-and his many suggestions, Greg Hudson for the thread safe net routines and
-all the testing he's done.
-
-More thanks to Mark Eichin and all the others for the testing they have done.
-
-PORTING
-One of the goals of this user space implementation of pthreads is that it
-be portable. I have minimized the ammount of assembler code necessary,
-but some is.
-
-If you want to port it to another platform here are a few basic hints.
-
-You will need to create a machdep.h, machdep.c and syscall.S for the
-new architecture. The first two are necessary to get the context switch
-section of the pthread package running, the third is for all the syscalls.
-
-INCLUDE FILES AND PORTING
-In addition to the above three files you need to create a slew of .h files.
-Take a look at an existing port to determine what is in each, and then
-take a look at your system header files to determine what to put in them.
-
-------------------------------------------------------------------------------
-Copyright (c) 1993, 1994, 1995, 1996 Chris Provenzano. All rights reserved.
-This product includes software developed by the Univeristy of California,
-Berkeley and its contributors.
-
-For further licencing and distribution restrictions see the file COPYRIGHT
-included in this directory.
diff --git a/mit-pthreads/TODO-mysql b/mit-pthreads/TODO-mysql
deleted file mode 100644
index a19b1bd51d6..00000000000
--- a/mit-pthreads/TODO-mysql
+++ /dev/null
@@ -1,4 +0,0 @@
-This what should be done to get more functionally for mysqld.
-
-- open should be interruptable.
-- fcntl lock should be interruptable.
diff --git a/mit-pthreads/Whats_New b/mit-pthreads/Whats_New
deleted file mode 100644
index 556d9f63268..00000000000
--- a/mit-pthreads/Whats_New
+++ /dev/null
@@ -1,198 +0,0 @@
-For patches made to this release, check the file Changes-mysql
-
-For the 96/11/11 release version 1_60_beta6
-
- Ports
- Alpha running NetBSD-1.1 by Chris G Demetriou <cgd+@cs.cmu.edu>
- i386 running BSDi-2.1 by David J MacKenzie <djm@va.pubnix.com>
-
- Bug Fixes
- Test for struct timespec under linux and DTRT.
- include/unistd.h : #define SEEK_SET, SEEK_CUR, and SEEK_END.
- Bug reported by Stephen Tether <tether@MITLNS.MIT.EDU>
- stdlib/system.c : Uses the POSIX signal systemcalls.
- Bug reported by Matthew Newhook <matthew@thor.udc.neweast.ca>.
- net/gethostbyname.c: #include <string.h> and fix dereference problem.
- Bug reported by Chris G Demetriou <cgd+@cs.cmu.edu>
- pthreads/fd.c: Fix bug in close() reported by
- Bug reported by "William S. Lear" <rael@dejanews.com>
- tests/p_bench_pthread_create.c : Only try and create 10000 threads.
- include/pthread/sleep.h : No need to prototype machdep_gettimeofday()
- since it is declared here.
- Bug reported by Stewart Gebbie <stewart@global.co.za>
- stdio/fwrite.c: Fixed bug where if total bytes written = 0 then a divid
- by 0 occurs. Thanks to CTLarsen@lbl.gov for finding is and to
- Jin Guojun <jin@george.lbl.gov> for submitting a patch for it.
- stdio/refill.c (__swalk_lflush()): Second pass of flush should call
- flockfile() not ftrylockfile(). Just like in __swalk_sflush()
- net/res_internal.c (_res_parse_answer()): It looks like if
- iquery is true and type == T_PTR then the result->h_name
- will be over written because the bp isn't incrementd
- appropriately. Thanks to David Halls <David.Halls@cl.cam.ac.uk>
- for finding it.
- net/serv_internal.c (_serv_buf()) : Allocate more than four bytes
- of buffer space. Reported by drh@@tobit.vnet.net.
- pthreads/fd_kern.c: Make sure exception fds are included in
- machdep_sys_select() for support of select(). Thanks to
- Larry V. Streepy, Jr. <streepy@healthcare.com> for the patches.
- pthreads/fd_kern.c: Fix more I/O routines to report NOTOK on error
- instead of the old -error number. Hopefully this is the last of
- them. Thanks to Larry V. Streepy, Jr. <streepy@healthcare.com> for
- the patches.
- machdep/engine-i386-linux-1.0.c: Remove unneeded machdep_sys_readv()
- and machdep_sys_writev() routines. Reported by
- pthreads/process.c : Fix execl() and execle() to work on sparc systems.
- pthreads/fd_sysv.c : Fix accept() to work under Solaris 2.4
-
-
-For the 96/03/09 release version 1_60_beta5
-
- Ports
- Sparc running NetBSD-1.1
-
- Additions
- New reentrant netdb similar to Solaris API (ghudson)
-
- Bug Fixes
- Make default signal handlers work.
- Deadlock scheduling bug reported by Cathy Abbott <cabbot@cs.utk.edu>
- See pthreads-bugs transaction 31
- pthread/queue.c (pthread_queue_remove()): Don't set thread->queue and
- thread->next to NULL unless the thread is removed from the queue.
- pthreads/fd.c (setsockopt(), getsockopt(), getsockname(),
- getpeername()) : Call fd_lock() with appropriate paramaters.
- pthreads/fd_kern.c (sendmsg_timedwait()): Call fd_unlock() with
- FD_WRITE instead of FD_READ paramater.
- machdep/*/timers.h net/res_send.c, pthreads/cond.c, pthreads/select.c
- pthreads/sleep.c, tests/test_pthread_cond_timedwait.c:
- Change timespec to be POSIX compliant.
- include/unistd.h : Change u_int to unsigned [int] in prototypes.
- pthreads/fd.c : Use FD_SETSIZE instead of 1024 for a limit on fds.
-
-
-For the 95/09/xx release version 1_60_beta4
-
- Ports
- SGI running IRIX-5.3
-
- Additions
- Added pthread_sigprocmask().
- Added CV attributes
-
- strtok() and strtok_r() (Greg Hudson)
- getsockname() (Sean Levy)
-
- Bug Fixes
- stdio/fwalk.c, stdio/refill.c : Use flockfile() instead of
- ftrylockfile()/pthread_yield(), for traversing FILE list.
- pthreads/sig.c : Remove enum pthread_sig_flags and just use the vector.
- Added pthread_sigprocmask().
- pthreads/signal.c : Protect calls to pthread_sig_process().
- configure : Create the obj directory.
- tests/test_preemption_float.c : Rewritten to actually work.
- machdep/engine-i386-linux-1.0.c : Added __strtol_internal()
- tests/test_stdio_1.c : Don't use base_name or dir_name as variables.
- gen/getcwd.c : fstat => machdep_sys_fstat, since kernel fd's are
- used in the DIR data structure
- gen/isatty.c : Fixed call to fd_lock() to pass the right # args.
- pthreads/pthread_init.c : Fixed uninitialized members of
- pthread_initial.
-
-
-
-For the 95/06/xx release version 1_60_beta3
-
- Additions
- Add exec variants execl, execlp, execv, execvp (Ken Raeburn)
- pthreads/fd_sysv.c : Added routines setsockopt() and getsockname().
- Added include/endian.h : For machine dependent endian junk. (YUCK)
- Added socketpair()
- Added ttyname_r()
-
- Bug Fixes
- config/Makefile.in : Need $$ to reference shell variables in make.
- config/configure, config/configure.in : Redo freebsd2.* machine.
- machdep/sunos-4.1.3/__stdlib.h : typedef pthread_size_t size_t
- pthreads/fd.c : Fix bug with fd_free(), dup(), dup2(), and close()
- where a fd gets lost after a dup() then close().
- pthreads/fd_kern.c : The fd_table[fd]->flags of the fd that accept()
- returns should be the same as those of the fd passed to accept().
- stdio/fclose.c : Don't call funlockfile(fp) after fp->_file has been
- closed.
- pthreads/select.c : Move pthread_sched_prevent() inside the statement.
- if (machdep_sys_select(...) == OK)
- pthreads/machdep/linux-1.0/cdefs.h : moved the include_next outside
- of the ifdef so that it would eventually find the system cdefs.h
- pthreads/signal.c : Check sig_to_process before and after fd_kern_wait()
- . It is possible for sig_handler_fake() to registered one.
- pthreads/signal.c : Unset pthread_run temporarily around the call to
- sig_handler(0). places where this causes core dumps should check
- pthread_run.
- include/stdlib.h : Fix prototype for bsearch().
- machdep/syscall-i386-freebsd-2.0.S syscall-template-i386-freebsd2.0.S:
- Fix macro expansion problems for FreeBSD-2.0
- machdep/engine-sparc-sunos-5.3.c : Fix machdep_sys_select() to return
- machdep_sys_poll() errors and not the number of entries found.
- gen/getcwd.c : Use strlen(dp->d_name) not dp->d_namlen because there
- may be extra data associated with dp->d_namelen.
- machdep/freebsd-2.0/__unistd.h: Change #define _POSIX_VDISABLE to 0xff
- include/pthread.h : Added prototypes pthread_kill(), pthread_signal()
- machdep/linux-1.0/__signal.h : Added #define __sigmask() and
- #define sigmask, and fixed other SIG macros to use __sigmask.
- machdep/linux-1.0/dirent.h : #include <sys/types.h>
- machdep/linux-1.0/wait.h : Fix #define WIFSTOPPED(x) to use __WSTATUS(x)
- machdep/syscall-i386-linux-1.0.S : Added elf support. (NOT TESTED)
- pthreads/stat.c : Added to separate linux stat calls.
- (SGI will need this too)
- pthreads/signal.c : Whereever #ifdef (SA_RESETHAND) is used then
- #ifdef (SA_RESTART) also
- gen/isatty.c : isatty_basic() is called with the KFD not UFD.
- machdep/sunos-4.1.3/__stdlib.h : #include <sys/stdtypes.h>
- config/sun4os4.mk : Added pipe to SYSCALL_EXCEPTIONS
- machdep/syscall-sparc-sunos-4.1.3.S : Add machdep_sys_pipe().
- include/stdio.h : Remove __getc() and __putc(), because they really
- shouldn't be inlined.
- machdep/sunos-4.1.3/stat.h : Added __BEGIN_DECLS and __END_DECLS.
- machdep/alpha-osf1/cdefs.h, machdep/hpux-9.03/cdefs.h
- machdep/linux-1.0/cdefs.h, machdep/sunos-4.1.3/cdefs.h
- machdep/sunos-5.3/cdefs.h, machdep/ultrix-4.2/cdefs.h :
- #define __INLINE static inline and don't #define
- __CAN_DO_EXTERN_INLINE if __cplusplus and __GCC__ is defined.
- pthreads/fd_sysv.c : Fix so that only systems without socket systemcalls
- compile this file.
- machdep/engine-i386-linux-1.0.c : Fix linux machdep_sys_getdirentries()
- pthreads/gen : Nuke the signal-blocking code in pclose(). It doesn't do
- any good in a threaded program; some other thread would just get
- the signal.
-
-
-For the 94/11/xx release version 1_60
-
- Additions
- Added recvfrom_timedwait(), and similar calls
- Added thread safe time routines: ctime(), localtime(), ...
- Added thread safe rand routines: rand(), random(), ...
- Added priorities and releated routines: pthread_attr_getschedparam(),
- Added signals and releated routines:pthread_kill(), sigwait(), ...
- Added mutex attribues and releated routines: pthread_mutexattr_init(), .
- Added abort
-
- Added counting (recursive) mutexes.
- Added debugging mutexes.
- Added some more tests
-
- Redid entire thread kernel because of priorities, and signals.
- Test and set instructions no longer necessary for versions
- that don't support kernel threads.
-
- More debugging by Greg Hudson along with the network lookup routines
- An Alpha port from Ken Raeburn and Sean Levy
- A solaris port from me.
- select() implementations from Sean Levy and Peter Hofmann
- configure from Ken Raeburn
- pthread_init() no longer necessary for systems with G++ from Ken Raeburn
- net code from Greg Hudson including: gethostbyname(), ...
-
- Bug fixes:
- honor _POSIX_THREAD_DESTRUCTOR_ITERATIONS
- pthread_key_destroy() is really pthread_key_delete()
diff --git a/mit-pthreads/bin/.cvsignore b/mit-pthreads/bin/.cvsignore
deleted file mode 100644
index f3c7a7c5da6..00000000000
--- a/mit-pthreads/bin/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
diff --git a/mit-pthreads/bin/Makefile.in b/mit-pthreads/bin/Makefile.in
deleted file mode 100644
index 979ad2db2ea..00000000000
--- a/mit-pthreads/bin/Makefile.in
+++ /dev/null
@@ -1,48 +0,0 @@
-# === GNUmakefile ============================================================
-# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating the test programs for libpthread.a
-#
-# 1.00 93/08/03 proven
-# -Initial cut for pthreads.
-#
-
-CC = ../pgcc -notinstalled
-srctop = @srctop@
-srcdir = @srctop@/lib
-VPATH = @srctop@/lib
-CDEBUGFLAGS = @CFLAGS@
-
-CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(ADDL_CFLAGS) -DSRCDIR=\"$(srcdir)\"
-
-#
-DIRS = finger
-
-################################################################################
-#
-all:
- (for i in $(DIRS); do cd $$i; $(MAKE) all; cd ..; done)
-
-clean:
- (for i in $(DIRS); do cd $$i; $(MAKE) clean; cd ..; done)
- rm -f *.o $(TESTS) $(BENCHMARKS) a.out core maketmp makeout
-
-depend:
- (for i in $(DIRS); do cd $$i; $(MAKE) depend; cd ..; done)
- sed '/\#\#\# Dependencies/q' < Makefile > maketmp
- (for i in $(CSRC);do $(CPP) -M $$i;done) >> maketmp
- cp maketmp Makefile
-
-install:
- (for i in $(DIRS); do cd $$i; $(MAKE) install; cd ..; done)
-
-realclean: clean
- (for i in $(DIRS); do cd $$i; $(MAKE) realclean; cd ..; done)
- rm -f Makefile
-
-Makefile: Makefile.in
- (cd .. ; sh config.status)
-
-################################################################################
-### Do not remove the following line. It is for depend #########################
-### Dependencies:
diff --git a/mit-pthreads/bin/finger/.cvsignore b/mit-pthreads/bin/finger/.cvsignore
deleted file mode 100644
index f3c7a7c5da6..00000000000
--- a/mit-pthreads/bin/finger/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
diff --git a/mit-pthreads/bin/finger/Makefile.in b/mit-pthreads/bin/finger/Makefile.in
deleted file mode 100755
index ee20f47443d..00000000000
--- a/mit-pthreads/bin/finger/Makefile.in
+++ /dev/null
@@ -1,60 +0,0 @@
-# === makefile ============================================================
-# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating the test programs for libpthread.a
-#
-# 1.00 93/08/03 proven
-# -Initial cut for pthreads.
-#
-
-srctop = @srctop@
-srcdir = @srctop@/bin/finger
-VPATH = @srctop@/bin/finger
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-
-INSTALL_PATH = @exec_prefix@
- BINDIR = $(INSTALL_PATH)/bin
- LIBDIR = $(INSTALL_PATH)/lib
- MANDIR = $(INSTALL_PATH)/man
- INCDIR = $(INSTALL_PATH)/include
-
- CC = ../../pgcc -notinstalled
- CDEBUGFLAGS = @CFLAGS@
- INCLUDES = -I@srctop@/lib/libpthreadutil/ -L../../lib/libpthreadutil/
- CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(ADDL_CFLAGS) -DSRCDIR=\"$(srcdir)\"
- RANLIB = @RANLIB@
-
- OBJS = finger.o net.o
- BINARY = finger
-
-################################################################################
-#
-all : $(BINARY)
-
-clean:
- rm -f *.o $(TESTS) $(BENCHMARKS) a.out core maketmp makeout
-
-depend:
- sed '/\#\#\# Dependencies/q' < Makefile > maketmp
- (for i in $(CSRC);do $(CPP) -M $$i;done) >> maketmp
- cp maketmp Makefile
-
-install: $(BINARY)
- install $(BINARY) $(BINDIR)
-
-realclean: clean
- rm -f Makefile
-
-Makefile: Makefile.in
- (cd ../.. ; sh config.status)
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
-$(BINARY) : ${OBJS}
- $(CC) $(CFLAGS) -o $(BINARY) ${OBJS} -lpthreadutil
-
-################################################################################
-### Do not remove the following line. It is for depend #########################
-### Dependencies:
diff --git a/mit-pthreads/bin/finger/finger.c b/mit-pthreads/bin/finger/finger.c
deleted file mode 100755
index 33b3011e8bb..00000000000
--- a/mit-pthreads/bin/finger/finger.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* ==== finger.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano,
- * the University of California, Berkeley and its contributors.
- * 4. Neither the name of Chris Provenzano, the University nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO, THE REGENTS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * 1.00 93/08/26 proven
- * -Pthread redesign of this file.
- *
- * 1.10 95/02/11 proven
- * -Now that gethostbyname works ....
- */
-
-#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
- @(#) Copyright (c) 1993, 1995 Chris Provenzano.\n\
- @(#) Copyright (c) 1995 Greg Stark.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-#include <pthreadutil.h>
-#include <sys/param.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-void *netfinger();
-
-void usage(int eval)
-{
- fprintf(stderr,
- "usage: finger [-lps] [-c <net_count>] [-t|T <timeout>] [-f <filename>] [login ...]\n");
- exit(eval);
-}
-
-/*
- * These globals are set initialy and then are only read.
- * They do not need mutexes.
- */
-int thread_time = 0, program_timeout = 0, lflag = 0;
-pthread_tad_t parse_file_tad;
-pthread_tad_t netfinger_tad;
-
-void * timeout_thread(void * arg)
-{
- sleep(program_timeout);
- exit(0);
-}
-
-void * signal_thread(void * arg)
-{
- int sig;
- sigset_t program_signals;
- sigemptyset(&program_signals);
- sigaddset(&program_signals, SIGINT);
- sigwait(&program_signals, &sig);
- exit(0);
-}
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-void * parse_file(void * arg)
-{
- char hostname[MAXHOSTNAMELEN];
- char * filename = arg;
- pthread_atexit_t atexit_id;
- pthread_attr_t attr;
- pthread_t thread_id;
- char * thread_arg;
- FILE * fp;
- int len;
-
- netsetupwait();
-
- /* Parse the file and create a thread per connection */
- if ((fp = fopen(filename, "r")) == NULL) {
- fprintf(stderr, "Can't open file %s\n", filename);
- pthread_exit(NULL);
- }
- pthread_atexit_add(&atexit_id, fclose_nrv, fp);
-
- if (pthread_attr_init(&attr)) {
- fprintf(stderr, "Error: Can't initialize thread attributes\n");
- exit(2);
- }
- pthread_atexit_add(&atexit_id, pthread_attr_destroy_nrv, &attr);
-
- while (fgets(hostname, MAXHOSTNAMELEN, fp)) {
- if ((thread_arg = (char *)malloc(len = strlen(hostname))) == NULL) {
- fprintf(stderr, "Error: out of memory\n");
- exit(2);
- }
-
- hostname[len - 1] = '\0';
- strcpy(thread_arg, hostname);
- pthread_attr_setcleanup(&attr, free, thread_arg);
- if (pthread_tad_create(&netfinger_tad, &thread_id, NULL,
- netfinger, thread_arg)) {
- fprintf(stderr, "Error: pthread_tad_create() netfinger_tad.\n");
- exit(2);
- }
- }
- pthread_exit(NULL);
-}
-
-main(int argc, char **argv)
-{
- pthread_atexit_t atexit_id;
- pthread_t thread_id;
- int max_count = 0;
- char ch;
-
- /* getopt variables */
- extern char *optarg;
- extern int optind;
-
- /* Setup tad for parse_file() threads */
- if (pthread_tad_init(&parse_file_tad, max_count)) {
- fprintf(stderr,"Error: couldn't create parse_file() TAD.\n");
- exit(1);
- }
-
- while ((ch = getopt(argc, argv, "c:f:t:T:ls")) != (char)EOF)
- switch(ch) {
- case 't': /* Time to let each thread run */
- if ((thread_time = atoi(optarg)) <= 0) {
- usage(1);
- }
- break;
- case 'T': /* Time to let entire program run */
- if ((program_timeout = atoi(optarg)) <= 0) {
- usage(1);
- }
- break;
- case 'f': /* Parse file for list of places to finger */
- if (pthread_tad_create(&parse_file_tad, &thread_id, NULL,
- parse_file, optarg)) {
- fprintf(stderr,"Error: pthread_tad_create() parse_file_tad.\n");
- exit(1);
- }
- break;
- case 'c':
- max_count = atoi(optarg);
- break;
- case 'l': /* long format */
- lflag = 1;
- break;
- case 's': /* short format */
- lflag = 0;
- break;
- case '?':
- usage(0);
- default:
- usage(1);
- }
-
- /* The rest of the argumants are hosts */
- argc -= optind;
- argv += optind;
-
- /* Setup timeout thread, if there is one */
- if (program_timeout) {
- if (pthread_create(&thread_id, NULL, timeout_thread, NULL)) {
- fprintf(stderr,"Error: couldn't create program_timeout() thread\n");
- exit(1);
- }
- }
-
- /* Setup cleanup thread for signals */
- if (pthread_create(&thread_id, NULL, signal_thread, NULL)) {
- fprintf(stderr,"Error: couldn't create signal_timeout() thread\n");
- exit(1);
- }
-
- /* Setup tad for netfinger() threads */
- if (pthread_tad_init(&netfinger_tad, max_count)) {
- fprintf(stderr,"Error: couldn't create netfinger() TAD.\n");
- exit(1);
- }
-
- /* Setup the net and let everyone run */
- netsetup();
-
- while (*argv) {
- if (pthread_tad_create(&netfinger_tad, &thread_id, NULL,
- netfinger, *argv)) {
- fprintf(stderr, "Error: pthread_tad_create() netfinger_tad.\n");
- exit(2);
- }
- argv++;
- }
- pthread_tad_wait(&parse_file_tad, 0);
- pthread_tad_wait(&netfinger_tad, 0);
- exit(0);
-}
-
diff --git a/mit-pthreads/bin/finger/net.c b/mit-pthreads/bin/finger/net.c
deleted file mode 100755
index 77ccd92ee8c..00000000000
--- a/mit-pthreads/bin/finger/net.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/* ==== net.c ============================================================
- * Copyright (c) 1993, 1995 by Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * 1.00 93/08/26 proven
- * -Pthread redesign of this file.
- */
-
-#include <pthreadutil.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <string.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-/*
- * These globals are set initialy and then are only read.
- * They do not need mutexes.
- */
-extern int lflag;
-char myhostname[MAXHOSTNAMELEN];
-
-/*
- * These globals change and therefor do need mutexes
- */
-pthread_mutex_t spmutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t spcond = PTHREAD_COND_INITIALIZER;
-struct servent *sp = NULL;
-
-void netsetup(void)
-{
- pthread_mutex_lock(&spmutex);
- if (sp) {
- fprintf(stderr, "finger: service pointer already initialized.\n");
- exit(2);
- }
- if ((sp = (struct servent *)malloc(sizeof(struct servent) + 4096)) == NULL){
- fprintf(stderr, "finger: Couldn't allocate service pointer.\n");
- exit(2);
- }
- if (getservbyname_r("finger", "tcp", sp, (char *)sp + sizeof(struct servent), 4096) == NULL) {
- fprintf(stderr, "finger: tcp/finger: unknown service\n");
- exit(2);
- }
- if (gethostname(myhostname, MAXHOSTNAMELEN)) {
- fprintf(stderr, "finger: couldn't get my hostname.\n");
- exit(2);
- }
- pthread_cond_broadcast(&spcond);
- pthread_mutex_unlock(&spmutex);
-}
-
-void netsetupwait(void)
-{
- pthread_mutex_lock(&spmutex);
- while(sp == NULL) {
- pthread_cond_wait(&spcond, &spmutex);
- }
- pthread_mutex_unlock(&spmutex);
-}
-
-void *netfinger(char *name)
-{
- pthread_atexit_t atexit_id;
- register int c, lastc;
- struct in_addr defaddr;
- struct hostent *hp;
- struct sockaddr_in sin;
- int s, i, readbuflen;
- char readbuf[1024];
- char *host;
-
- netsetupwait();
- pthread_atexit_add(&atexit_id, fflush_nrv, NULL);
-
- if (!(host = strrchr(name, '@'))) {
- host = myhostname;
- } else {
- *host++ = '\0';
- }
- if (!(hp = gethostbyname(host))) {
- if ((defaddr.s_addr = inet_addr(host)) < 0) {
- fprintf(stderr, "[%s] gethostbyname: Unknown host\n", host);
- return;
- }
- }
- sin.sin_family = hp->h_addrtype;
- memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
- sin.sin_port = sp->s_port;
-
- if ((s = socket(sin.sin_family, SOCK_STREAM, 0)) < 0) {
- sprintf(readbuf, "[%s]: socket", hp->h_name);
- perror(readbuf);
- return;
- }
-
- /* have network connection; identify the host connected with */
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- sprintf(readbuf, "[%s]: connect", hp->h_name);
- perror(readbuf);
- close(s);
- return;
- }
-
- /* -l flag for remote fingerd */
- if (lflag)
- write(s, "/W ", 3);
- /* send the name followed by <CR><LF> */
- write(s, name, strlen(name));
- write(s, "\r\n", 2);
-
- /*
- * Read from the remote system; once we're connected, we assume some
- * data. If none arrives, we hang until the user interrupts, or
- * until the thread timeout expires.
- *
- * If we see a <CR> or a <CR> with the high bit set, treat it as
- * a newline; if followed by a newline character, only output one
- * newline.
- *
- * Otherwise, all high bits are stripped; if it isn't printable and
- * it isn't a space, we can simply set the 7th bit. Every ASCII
- * character with bit 7 set is printable.
- */
- for (readbuflen = read(s, readbuf, 1024), flockfile(stdout), lastc = '\n',
- printf("[%s]\n", hp->h_name); readbuflen > 0;
- readbuflen = read(s, readbuf, 1024)) {
- for (i = 0; i < readbuflen; i++) {
- c = readbuf[i] & 0x7f;
- if (c == 0x0d) {
- c = '\n';
- lastc = '\r';
- } else {
- if (!isprint(c) && !isspace(c))
- c |= 0x40;
- if (lastc != '\r' || c != '\n')
- lastc = c;
- else {
- lastc = '\n';
- continue;
- }
- }
- putchar_unlocked(c);
- }
- }
- if (lastc != '\n')
- putchar_unlocked('\n');
- funlockfile(stdout);
-}
diff --git a/mit-pthreads/config/COPYING.GNU b/mit-pthreads/config/COPYING.GNU
deleted file mode 100755
index a43ea2126fb..00000000000
--- a/mit-pthreads/config/COPYING.GNU
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- Appendix: How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/mit-pthreads/config/COPYRIGHT b/mit-pthreads/config/COPYRIGHT
deleted file mode 100755
index ba3ac43c589..00000000000
--- a/mit-pthreads/config/COPYRIGHT
+++ /dev/null
@@ -1,4 +0,0 @@
-The files config.guess and config.sub in this directory come from the GNU
-autoconf distribution, and are covered by the GNU Public License, which may
-be found in the file COPYING.GNU. They are the only files covered by the
-GPL.
diff --git a/mit-pthreads/config/GNUmakefile.in b/mit-pthreads/config/GNUmakefile.in
deleted file mode 100755
index 7c06ee367e6..00000000000
--- a/mit-pthreads/config/GNUmakefile.in
+++ /dev/null
@@ -1,129 +0,0 @@
-# === GNUmakefile =============================================================
-# Copyright (c) 1991, 1992, 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating libpthread.a
-#
-# 1.00 93/11/17 proven
-# -Put all the .o files into one file libpthread.a
-# -Initial cut for pthreads.
-#
-
-INSTALL_PATH = $(exec_prefix)
-
- BINDIR = $(INSTALL_PATH)/bin
- LIBDIR = $(INSTALL_PATH)/lib
- MANDIR = $(INSTALL_PATH)/man
- INCDIR = $(INSTALL_PATH)/include
- SUBINCDIR = $(INCDIR)/pthread
-
- AR = ar
- AS = gas
- CFLAGS = -I. -Iinclude -I$(srcdir)/include -DPTHREAD_KERNEL \
- @CFLAGS@
- CXXFLAGS = -I. -Iinclude -I$(srcdir)/include -DPTHREAD_KERNEL \
- @CXXFLAGS@
- LD = gld
-
- CSRC =
-
- PTHREAD_DIR = pthreads stdlib stdio gen
- DIRS = $(PTHREAD_DIR)
-
- HEADERS =
-
- LIBRARIES = libpthread.a
-
- .CURDIR = .
-
-# force correct default target
-all:
-
-###############################################################################
-#
-# Read in any special flags that config knows about
-include config.flags
-
-# What the heck. Convert srcdir to absolute form so it looks prettier.
-srcdir := $(shell cd $(srcfoo) && pwd)
-
-################################################################################
-#
-# Here starts the nitty grity part of the Makefile.
-
-all-lib : libpthread.a
-
-include ${srcdir}/pthreads/GNUmakefile.inc
-include ${srcdir}/stdlib/GNUmakefile.inc
-include ${srcdir}/stdio/GNUmakefile.inc
-include ${srcdir}/string/GNUmakefile.inc
-include ${srcdir}/gen/GNUmakefile.inc
-include ${srcdir}/net/GNUmakefile.inc
-include ${srcdir}/scripts/GNUmakefile.inc
-
-REGULAR_OBJS= $(subst .cc,.o,$(SRCS))
-REGULAR_OBJS:= $(subst .c,.o,$(REGULAR_OBJS))
-REGULAR_OBJS:= $(subst .S,.o,$(REGULAR_OBJS))
-OBJS= $(REGULAR_OBJS) $(EXTRA_OBJS)
-REALOBJS = $(addprefix obj/, $(OBJS))
-
-$(REALOBJS) : $(config) $(types) $(paths)
-
-# Since we do not have a list of the relevant files we do a make clean
-# before copying everyting to the distribution directory.
-distdir:
- $(MAKE) clean
- cp -a . $(distdir)
- # Remove symlinks that the distribution should not have.
- rm -f $(distdir)/config.cache \
- $(distdir)/include/pthread/machdep.h \
- $(distdir)/include/pthread/posix.h \
- $(distdir)/include/sys \
- $(distdir)/machdep.c \
- $(distdir)/syscall.S \
- $(distdir)/syscall-template.S
-
-clean:
- rm -f a.out core maketmp makeout $(LIBRARIES) $(BINARIES) libpthread.*
- rm -rf obj
- cd tests && $(MAKE) clean && cd ..
-
-install-lib: $(LIBRARIES) install-dirs
- for x in $(LIBRARIES); \
- do install $$x $(DESTDIR)$(LIBDIR); \
- done
-
-# Removed make install since mysql uses this in place.
-# install-lib install-include install-bin
-install:
-
-libpthread.a: obj/libpthread.a
- rm -f libpthread.a
- ln -s obj/libpthread.a .
-
-obj/libpthread.a: ${REALOBJS}
- rm -f libpthread.a obj/new.a obj/libpthread.a
- cd obj && \
- ar r new.a ${OBJS} && \
- $(RANLIB) new.a && \
- mv -f new.a libpthread.a && \
- cd ..
-
-# For examining a combined symbol table, sizes, &c.
-libpthread.o: ${REALOBJS}
- cd obj && ld -r -o ../libpthread.o ${OBJS} && cd ..
-
-obj/x:
- if [ -d obj ]; then true; else mkdir obj; fi
- cp /dev/null obj/x
-
-GNUmakefile: config.status ${srcdir}/config/GNUmakefile.in
- $(SHELL) config.status
-
-obj/%.o: %.c obj/x
- $(CC) $(CFLAGS) -c $< -o $@
-
-obj/%.o: %.cc obj/x
- $(CXX) $(CXXFLAGS) $(CFLAGS) -c $< -o $@
-
-obj/%.o: %.S obj/x
- $(CC) $(CFLAGS) -c $< -o $@
diff --git a/mit-pthreads/config/Makefile.in b/mit-pthreads/config/Makefile.in
deleted file mode 100644
index 3fa388d740b..00000000000
--- a/mit-pthreads/config/Makefile.in
+++ /dev/null
@@ -1,56 +0,0 @@
-# @(#)Makefile 5.2 (Berkeley) 3/5/91
-#
-
-LIB=pthread
-NOPIC=1
-NOPROFILE=1
-NOLINT=1
-MKPIC=no
-MKPROFILE=no
-MKLINT=no
-CPPFLAGS+= -I${.CURDIR} -I${.CURDIR}/include -I${srcdir}/include -DPTHREAD_KERNEL
-CDEBUGFLAGS= @CFLAGS@
-CFLAGS+= ${CDEBUGFLAGS}
-# CFLAGS+= ${CPPFLAGS} <- done by bsd.lib.mk
-CFLAGS+= ${CPPFLAGS}
-LIBDIR= $(exec_prefix)/lib
-BINDIR= $(exec_prefix)/bin
-INCDIR= $(exec_prefix)/include
-MANDIR= $(exec_prefix)/man
-
-.OBJDIR != if test -d ${.CURDIR}/obj ; then true ; else mkdir ${.CURDIR}/obj || exit 1 ; fi ; echo ${.CURDIR}/obj
-
-# Standard bsd install rules look for the "install" program, rather than
-# using some variable. So, hack things so that that install rule works.
-BINGRP != echo " " `groups` " " | sed 's/ [0-9][0-9]* / /g' | awk '{print $$1}'
-BINOWN != echo $${USER}
-LIBMODE = 644 # so ranlib can run!
-
-.include "config.flags"
-
-# %!$@ pmake seems to automagically cd into the obj directory, so relative
-# srcdir references are completely botched. Try to figure out an absolute
-# pathname for srcdir here, and live with it.
-srcdir = $(srctop)
-
-beforeinstall: install-dirs
-
-.include "${srcdir}/pthreads/Makefile.inc"
-.include "${srcdir}/stdlib/Makefile.inc"
-.include "${srcdir}/stdio/Makefile.inc"
-.include "${srcdir}/string/Makefile.inc"
-.include "${srcdir}/gen/Makefile.inc"
-.include "${srcdir}/net/Makefile.inc"
-.include "${srcdir}/scripts/Makefile.inc"
-
-$(OBJS) : $(config) $(types) $(paths)
-
-Makefile: ${srcdir}/config/Makefile.in
- cd ${.CURDIR} && sh config.status
-
-all-lib : libpthread.a
-# Removed make install since mysql uses this in place.
-#install : install-bin install-include
-install:
-
-.include <bsd.lib.mk>
diff --git a/mit-pthreads/config/acconfig.h b/mit-pthreads/config/acconfig.h
deleted file mode 100644
index 14552b0d851..00000000000
--- a/mit-pthreads/config/acconfig.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Does the OS already support struct timespec */
-#undef _OS_HAS_TIMESPEC
-
-/* For networking code: an integral type the size of an IP address (4
- octets). Determined by examining return values from certain
- functions. */
-#undef pthread_ipaddr_type
-
-/* For networking code: an integral type the size of an IP port number
- (2 octets). Determined by examining return values from certain
- functions. */
-#undef pthread_ipport_type
-
-/* type of clock_t, from system header files */
-#undef pthread_clock_t
-
-/* Specially named so grep processing will find it and put it into the
- generated ac-types.h. */
-#undef pthread_have_va_list_h
-
-/* type of size_t, from system header files */
-#undef pthread_size_t
-
-/* type of ssize_t, from system header files */
-#undef pthread_ssize_t
-
-/* type of time_t, from system header files */
-#undef pthread_time_t
-
-/* type of fpos_t, from system header files */
-#undef pthread_fpos_t
-
-/* type of off_t, from system header files */
-#undef pthread_off_t
-
-/* type of va_list, from system header files */
-#undef pthread_va_list
-
-/* type of sigset_t, from system header files */
-#undef pthread_sigset_t
-
-/* I don't know why the native compiler definitions aren't sufficient
- for this. */
-#undef sunos4
-
-/* define if the linker hauls in certain static data from libc even when
- you don't want it to. yes, this description is bogus, but chris added
- the need for this, without describing the problem. */
-#undef LD_LINKS_STATIC_DATA
-
-/* define if the system reissues the SIGCHLD if the handler reinstalls
- * itself before calling wait()
- */
-#undef BROKEN_SIGNALS
-
-/* where are terminal devices to be found? */
-#undef _PATH_PTY
-
-/* what directory holds the time zone info on this system? */
-#undef _PATH_TZDIR
-
-/* what file indicates the local time zone? */
-#undef _PATH_TZFILE
-
-/* Paths for various networking support files. */
-#undef _PATH_RESCONF
-#undef _PATH_HOSTS
-#undef _PATH_NETWORKS
-#undef _PATH_PROTOCOLS
-#undef _PATH_SERVICES
-
-/* Path for Bourne shell. */
-#undef _PATH_BSHELL
diff --git a/mit-pthreads/config/aclocal.m4 b/mit-pthreads/config/aclocal.m4
deleted file mode 100755
index 2a5cd3e9cbf..00000000000
--- a/mit-pthreads/config/aclocal.m4
+++ /dev/null
@@ -1,94 +0,0 @@
-dnl Autoconf extensions for pthreads package.
-dnl
-ifelse(regexp(AC_DEFINE(xxxxx),.*@@@.*),-1,,[define(IS_AUTOHEADER)])])dnl
-dnl
-dnl Now, the real stuff needed by the pthreads package.
-dnl
-AC_DEFUN([PTHREADS_CHECK_ONE_SYSCALL],
-[AC_MSG_CHECKING(for syscall $1)
-AC_CACHE_VAL(pthreads_cv_syscall_$1,
-AC_TRY_LINK([
-/* FIXME: This list should be generated from info in configure.in. */
-#ifdef HAVE_SYSCALL_H
-#include <syscall.h>
-#else
-#ifdef HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
-#else
-where is your syscall header file??
-#endif
-#endif
-],[
-int x;
-x = SYS_$1 ;
-],
-eval pthreads_cv_syscall_$1=yes,
-eval pthreads_cv_syscall_$1=no))
-if eval test \$pthreads_cv_syscall_$1 = yes ; then
- pthreads_syscall_present=yes
- available_syscalls="$available_syscalls $1"
-dnl Can't just do the obvious substitution here or autoheader gets
-dnl sorta confused. (Sigh.) Getting the requoting of the brackets right
-dnl would be a pain too.
- macroname=HAVE_SYSCALL_`echo $1 | tr '[[[a-z]]]' '[[[A-Z]]]'`
- AC_DEFINE_UNQUOTED($macroname)
-else
- pthreads_syscall_present=no
- missing_syscalls="$missing_syscalls $1"
-fi
-AC_MSG_RESULT($pthreads_syscall_present)
-])dnl
-dnl
-AC_DEFUN(PTHREADS_CHECK_SYSCALLS,dnl
-ifdef([IS_AUTOHEADER],[#
-dnl Need to fake out autoheader, since there's no way to add a new class
-dnl of features to generate config.h.in entries for.
-@@@syscalls="$1"@@@
-@@@funcs="$funcs syscall_`echo $syscalls | sed 's/ / syscall_/g'`"@@@
-],
-[pthreads_syscall_list="$1"
-for pthreads_syscallname in $pthreads_syscall_list ; do
- PTHREADS_CHECK_ONE_SYSCALL([$]pthreads_syscallname)
-done
-]))dnl
-dnl
-dnl Requote each argument.
-define([requote], [ifelse($#, 0, , $#, 1, "$1",
- "$1" [requote(builtin(shift,$@))])])dnl
-dnl
-dnl Determine proper typedef value for a typedef name, and define a
-dnl C macro to expand to that type. (A shell variable with that value
-dnl is also created.) If none of the specified types to try match, the
-dnl macro is left undefined, and the shell variable empty. If the
-dnl typedef name cannot be found in the specified header files, this
-dnl test errors out; perhaps it should be changed to simply leave the
-dnl macro undefined...
-dnl
-dnl PTHREADS_FIND_TYPE(typedefname,varname,includes,possible values...)
-dnl
-AC_DEFUN(PTHREADS_FIND_TYPE,
-ifdef([IS_AUTOHEADER],[#
-@@@syms="$syms $2"@@@
-],[dnl
-AC_MSG_CHECKING(type of $1)
-AC_CACHE_VAL(pthreads_cv_type_$1,
-[AC_TRY_COMPILE([$3],[ extern $1 foo; ],
-[ for try_type in [requote(builtin(shift,builtin(shift,builtin(shift,$@))))] ; do
- AC_TRY_COMPILE([$3],[ extern $1 foo; extern $try_type foo; ],
- [ pthreads_cv_type_$1="$try_type" ; break ])
- done],
- AC_MSG_ERROR(Can't find system typedef for $1.))])
-if test -n "$pthreads_cv_type_$1" ; then
- AC_DEFINE_UNQUOTED($2,$pthreads_cv_type_$1)
-fi
-$2=$pthreads_cv_type_$1
-AC_MSG_RESULT($pthreads_cv_type_$1)]))dnl
-dnl
-dnl
-dnl Like above, but the list of types to try is pre-specified.
-dnl
-AC_DEFUN(PTHREADS_FIND_INTEGRAL_TYPE,[
-PTHREADS_FIND_TYPE([$1], [$2], [$3],
- int, unsigned int, long, unsigned long,
- short, unsigned short, char, unsigned char,
- long long, unsigned long long)])dnl
diff --git a/mit-pthreads/config/config.flags.in b/mit-pthreads/config/config.flags.in
deleted file mode 100755
index 3d16423a045..00000000000
--- a/mit-pthreads/config/config.flags.in
+++ /dev/null
@@ -1,80 +0,0 @@
-# Since the real configure script runs from the config subdirectory,
-# compensate here...
-srctop= @srctop@
-srcfoo= $(srctop)
-
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-
-cpu = @target_cpu@
-os = @target_os@
-
-MISSING_SYSCALLS = @missing_syscalls@
-AVAILABLE_SYSCALLS = @available_syscalls@
-SYSCALL_EXCEPTIONS = @SYSCALL_EXCEPTIONS@
-HAVE_SYSCALL_TEMPLATE = @HAVE_SYSCALL_TEMPLATE@
-
-CC = @CC@
-CXX = @CXX@
-CPP = @CPP@
-SHELL = /bin/sh
-RANLIB = @RANLIB@
-# Should use autoconf to find these. Currently our makefiles are inconsistent.
-#AR = ar
-#AS = gas
-#LD = gld
-
-install-dirs:
- for d in $(INSTALL_PATH) $(BINDIR) $(LIBDIR) $(INCDIR) ; do \
- test -d $(DESTDIR)$$d || mkdir $(DESTDIR)$$d || exit 1 ; \
- done
-
-config.status: @srcdir@/configure
- cd ${.CURDIR} && $(SHELL) config.status --recheck
-config.flags: config.status @srcdir@/config.flags.in
- cd ${.CURDIR} && $(SHELL) config.status
-
-realclean: clean
- cd tests && $(MAKE) realclean && cd ..
- rm -f $(LINKS) config.status config.flags config.cache \
- Makefile GNUmakefile
-
-types=$(.CURDIR)/include/pthread/ac-types.h
-$(types) : config.h
- echo '#ifndef pthread_size_t' > $(types).new
- egrep '^#define pthread_' $(.CURDIR)/config.h >> $(types).new
- echo '#endif' >> $(types).new
- mv -f $(types).new $(types)
-
-config=$(.CURDIR)/include/pthread/config.h
-$(config) : config.h
- echo '#ifndef _SYS___CONFIG_H_' > $(config).new
- echo '#define _SYS___CONFIG_H_' >> $(config).new
- -egrep '^#define _OS_HAS' $(.CURDIR)/config.h >> $(config).new
- echo '#endif' >> $(config).new
- mv -f $(config).new $(config)
-
-paths=$(.CURDIR)/include/pthread/paths.h
-$(paths) : config.h
- echo '#ifndef _SYS___PATHS_H_' > $(paths).new
- echo '#define _SYS___PATHS_H_' >> $(paths).new
- egrep '^#define _PATH' $(.CURDIR)/config.h >> $(paths).new
- echo '#endif' >> $(paths).new
- mv -f $(paths).new $(paths)
-
-all-tests: all-lib
- cd ${.CURDIR}/tests && $(MAKE) all
-check: all-lib
- cd ${.CURDIR}/tests && $(MAKE) check
-all : all-lib all-bin
-
-install-bin: all-bin install-dirs
- for x in $(SCRIPTS) ; do \
- install $$x $(DESTDIR)$(BINDIR); \
- done
-
-install-include: install-dirs
- (cd ${srcdir}/include && tar chf - .)|(cd $(DESTDIR)$(INCDIR) && tar xf -)
- if [ -d config ]; then true; else \
- (cd ${.CURDIR}/include && tar chf - .)|(cd $(DESTDIR)$(INCDIR) && tar xf -); fi
- (cd $(DESTDIR)$(INCDIR) && find . \( -name CVS -o -name \*~ \) -print | xargs rm -rf)
diff --git a/mit-pthreads/config/config.guess b/mit-pthreads/config/config.guess
deleted file mode 100755
index 287ddc13c34..00000000000
--- a/mit-pthreads/config/config.guess
+++ /dev/null
@@ -1,505 +0,0 @@
-#!/bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
-#
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Written by Per Bothner <bothner@cygnus.com>.
-# The master version of this file is at the FSF in /home/gd/gnu/lib.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit system type (host/target name).
-#
-# Only a few systems have been added to this list; please add others
-# (but try to keep the structure clean).
-#
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 8/24/94.)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- alpha:OSF1:V*:*)
- # After 1.2, OSF1 uses "V1.3" for uname -r.
- echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'`
- exit 0 ;;
- alpha:OSF1:*:*)
- # 1.2 uses "1.2" for uname -r.
- echo alpha-dec-osf${UNAME_RELEASE}
- exit 0 ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit 0;;
- Pyramid*:OSx*:*:*)
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit 0 ;;
- sun4*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:*:*)
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit 0 ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit 0 ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- mips:*:5*:RISCos)
- echo mips-mips-riscos${UNAME_RELEASE}
- exit 0 ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit 0 ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit 0 ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit 0 ;;
- AViiON:dgux:*:*)
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
- -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- exit 0 ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit 0 ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit 0 ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit 0 ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit 0 ;;
- *:IRIX:*:*)
- echo mips-sgi-irix${UNAME_RELEASE}
- exit 0 ;;
- i[34]86:AIX:*:*)
- echo i386-ibm-aix
- exit 0 ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- sed 's/^ //' << EOF >dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
- echo rs6000-ibm-aix3.2.5
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit 0 ;;
- *:AIX:*:4)
- if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if grep bos410 /usr/include/stdio.h >/dev/null 2>&1; then
- IBM_REV=4.1
- elif grep bos411 /usr/include/stdio.h >/dev/null 2>&1; then
- IBM_REV=4.1.1
- else
- IBM_REV=4.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit 0 ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit 0 ;;
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit 0 ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit 0 ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit 0 ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit 0 ;;
- 9000/[3478]??:HP-UX:*:*)
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/7?? | 9000/8?7 ) HP_ARCH=hppa1.1 ;;
- 9000/8?? ) HP_ARCH=hppa1.0 ;;
- esac
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit 0 ;;
- 3050*:HI-UX:*:*)
- sed 's/^ //' << EOF >dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
- echo unknown-hitachi-hiuxwe2
- exit 0 ;;
- 9000/7??:4.3bsd:*:* | 9000/8?7:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit 0 ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit 0 ;;
- hp7??:OSF1:*:* | hp8?7:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit 0 ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit 0 ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit 0 ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit 0 ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit 0 ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit 0 ;;
- CRAY*X-MP:UNICOS:*:*)
- echo xmp-cray-unicos
- exit 0 ;;
- CRAY*Y-MP:UNICOS:*:*)
- echo ymp-cray-unicos
- exit 0 ;;
- CRAY-2:UNICOS:*:*)
- echo cray2-cray-unicos
- exit 0 ;;
- amiga:NetBSD:*:*)
- echo m68k-amiga-netbsd${UNAME_RELEASE}
- exit 0 ;;
- atari:NetBSD:*:*)
- echo m68k-atari-netbsd${UNAME_RELEASE}
- exit 0 ;;
- hp3[0-9][05]:NetBSD:*:*)
- echo m68k-hp-netbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:NetBSD:*:*)
- echo m68k-apple-netbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme68:NetBSD:*:*)
- echo m68k-motorola-netbsd${UNAME_RELEASE}
- exit 0 ;;
- next68k:NetBSD:*:*)
- echo m68k-next-netbsd${UNAME_RELEASE}
- exit 0 ;;
- news68k:NetBSD:*:*)
- echo m68k-sony-netbsd${UNAME_RELEASE}
- exit 0 ;;
- sun3:NetBSD:*:*)
- echo m68k-sun-netbsd${UNAME_RELEASE}
- exit 0 ;;
- x68k:NetBSD:*:*)
- echo m68k-sharp-netbsd${UNAME_RELEASE}
- exit 0 ;;
- i[34]86:BSD/386:*:* | *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
- *:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- *:NetBSD:*:*)
- UNAME_PROCESSOR=`uname -p 2>/dev/null` || UNAME_PROCESSOR=$UNAME_MACHINE
- echo ${UNAME_PROCESSOR}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- exit 0 ;;
- *:OpenBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- *:GNU:*:*)
- echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit 0 ;;
- *:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux
- exit 0 ;;
-# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
-# are messed up and put the nodename in both sysname and nodename.
- i[34]86:DYNIX/ptx:4*:*)
- echo i386-sequent-sysv4
- exit 0 ;;
- i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*)
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
- else
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}
- fi
- exit 0 ;;
- i[34]86:*:3.2:*)
- if /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
- (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
- echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
- elif test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL
- else
- echo ${UNAME_MACHINE}-unknown-sysv32
- fi
- exit 0 ;;
- i?86:*:5:7)
- UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
- (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE}
- exit 0 ;;
- Intel:Mach:3*:*)
- echo i386-unknown-mach3
- exit 0 ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit 0 ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit 0 ;;
- M680[234]0:*:R3V[567]*:*)
- test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
- uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4.3 && exit 0 ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4 && exit 0 ;;
- m680[234]0:LynxOS:2.2*:*)
- echo m68k-lynx-lynxos${UNAME_RELEASE}
- exit 0 ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit 0 ;;
- i[34]86:LynxOS:2.2*:*)
- echo i386-lynx-lynxos${UNAME_RELEASE}
- exit 0 ;;
- TSUNAMI:LynxOS:2.2*:*)
- echo sparc-lynx-lynxos${UNAME_RELEASE}
- exit 0 ;;
- rs6000:LynxOS:2.2*:*)
- echo rs6000-lynx-lynxos${UNAME_RELEASE}
- exit 0 ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit 0 ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit 0 ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-cat >dummy.c <<EOF
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
- printf ("m68k-sony-newsos\n"); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3");
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-unknown-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- printf ("i386-sequent-ptx\n"); exit (0);
-#endif
-
-#if defined (vax)
-#if !defined (ultrix)
- printf ("vax-dec-bsd\n"); exit (0);
-#else
- printf ("vax-dec-ultrix\n"); exit (0);
-#endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
-rm -f dummy.c dummy
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit 0 ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- c34*)
- echo c34-convex-bsd
- exit 0 ;;
- c38*)
- echo c38-convex-bsd
- exit 0 ;;
- c4*)
- echo c4-convex-bsd
- exit 0 ;;
- esac
-fi
-
-#echo '(Unable to guess system type)' 1>&2
-
-exit 1
diff --git a/mit-pthreads/config/config.h.in b/mit-pthreads/config/config.h.in
deleted file mode 100755
index b5e25404a67..00000000000
--- a/mit-pthreads/config/config.h.in
+++ /dev/null
@@ -1,324 +0,0 @@
-/* config.h.in. Generated automatically from configure.in by autoheader. */
-
-/* Define to `long' if <sys/types.h> doesn't define. */
-#undef off_t
-
-/* Define as the return type of signal handlers (int or void). */
-#undef RETSIGTYPE
-
-/* Define to `unsigned' if <sys/types.h> doesn't define. */
-#undef size_t
-
-/* Define if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Define if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
-/* Does the OS already support struct timespec */
-#undef _OS_HAS_TIMESPEC
-
-/* Does the OS need socklen_t for the socket syscalls? */
-#undef _OS_HAS_SOCKLEN_T
-
-/* For networking code: an integral type the size of an IP address (4
- octets). Determined by examining return values from certain
- functions. */
-#undef pthread_ipaddr_type
-
-/* For networking code: an integral type the size of an IP port number
- (2 octets). Determined by examining return values from certain
- functions. */
-#undef pthread_ipport_type
-
-/* type of clock_t, from system header files */
-#undef pthread_clock_t
-
-/* Specially named so grep processing will find it and put it into the
- generated ac-types.h. */
-#undef pthread_have_va_list_h
-
-/* type of size_t, from system header files */
-#undef pthread_size_t
-
-/* type of ssize_t, from system header files */
-#undef pthread_ssize_t
-
-/* type of time_t, from system header files */
-#undef pthread_time_t
-
-/* type of fpos_t, from system header files */
-#undef pthread_fpos_t
-
-/* type of off_t, from system header files */
-#undef pthread_off_t
-
-/* type of va_list, from system header files */
-#undef pthread_va_list
-
-/* I don't know why the native compiler definitions aren't sufficient
- for this. */
-#undef sunos4
-
-/* define if the linker hauls in certain static data from libc even when
- you don't want it to. yes, this description is bogus, but chris added
- the need for this, without describing the problem. */
-#undef LD_LINKS_STATIC_DATA
-
-/* define if the system reissues the SIGCHLD if the handler reinstalls
- * itself before calling wait()
- */
-#undef BROKEN_SIGNALS
-
-/* where are terminal devices to be found? */
-#undef _PATH_PTY
-
-/* what directory holds the time zone info on this system? */
-#undef _PATH_TZDIR
-
-/* what file indicates the local time zone? */
-#undef _PATH_TZFILE
-
-/* Paths for various networking support files. */
-#undef _PATH_RESCONF
-#undef _PATH_HOSTS
-#undef _PATH_NETWORKS
-#undef _PATH_PROTOCOLS
-#undef _PATH_SERVICES
-
-/* Path for Bourne shell. */
-#undef _PATH_BSHELL
-
-/* Define if you have the syscall_accept function. */
-#undef HAVE_SYSCALL_ACCEPT
-
-/* Define if you have the syscall_bind function. */
-#undef HAVE_SYSCALL_BIND
-
-/* Define if you have the syscall_chdir function. */
-#undef HAVE_SYSCALL_CHDIR
-
-/* Define if you have the syscall_chmod function. */
-#undef HAVE_SYSCALL_CHMOD
-
-/* Define if you have the syscall_chown function. */
-#undef HAVE_SYSCALL_CHOWN
-
-/* Define if you have the syscall_chroot function. */
-#undef HAVE_SYSCALL_CHROOT
-
-/* Define if you have the syscall_close function. */
-#undef HAVE_SYSCALL_CLOSE
-
-/* Define if you have the syscall_connect function. */
-#undef HAVE_SYSCALL_CONNECT
-
-/* Define if you have the syscall_creat function. */
-#undef HAVE_SYSCALL_CREAT
-
-/* Define if you have the syscall_dup function. */
-#undef HAVE_SYSCALL_DUP
-
-/* Define if you have the syscall_dup2 function. */
-#undef HAVE_SYSCALL_DUP2
-
-/* Define if you have the syscall_execve function. */
-#undef HAVE_SYSCALL_EXECVE
-
-/* Define if you have the syscall_exit function. */
-#undef HAVE_SYSCALL_EXIT
-
-/* Define if you have the syscall_fchmod function. */
-#undef HAVE_SYSCALL_FCHMOD
-
-/* Define if you have the syscall_fchown function. */
-#undef HAVE_SYSCALL_FCHOWN
-
-/* Define if you have the syscall_fcntl function. */
-#undef HAVE_SYSCALL_FCNTL
-
-/* Define if you have the syscall_flock function. */
-#undef HAVE_SYSCALL_FLOCK
-
-/* Define if you have the syscall_fork function. */
-#undef HAVE_SYSCALL_FORK
-
-/* Define if you have the syscall_fstat function. */
-#undef HAVE_SYSCALL_FSTAT
-
-/* Define if you have the syscall_fstatfs function. */
-#undef HAVE_SYSCALL_FSTATFS
-
-/* Define if you have the syscall_ftruncate function. */
-#undef HAVE_SYSCALL_FTRUNCATE
-
-/* Define if you have the syscall_getdents function. */
-#undef HAVE_SYSCALL_GETDENTS
-
-/* Define if you have the syscall_getdirentries function. */
-#undef HAVE_SYSCALL_GETDIRENTRIES
-
-/* Define if you have the syscall_getdtablesize function. */
-#undef HAVE_SYSCALL_GETDTABLESIZE
-
-/* Define if you have the syscall_getmsg function. */
-#undef HAVE_SYSCALL_GETMSG
-
-/* Define if you have the syscall_getpeername function. */
-#undef HAVE_SYSCALL_GETPEERNAME
-
-/* Define if you have the syscall_getpgrp function. */
-#undef HAVE_SYSCALL_GETPGRP
-
-/* Define if you have the syscall_getsockname function. */
-#undef HAVE_SYSCALL_GETSOCKNAME
-
-/* Define if you have the syscall_getsockopt function. */
-#undef HAVE_SYSCALL_GETSOCKOPT
-
-/* Define if you have the syscall_ioctl function. */
-#undef HAVE_SYSCALL_IOCTL
-
-/* Define if you have the syscall_ksigaction function. */
-#undef HAVE_SYSCALL_KSIGACTION
-
-/* Define if you have the syscall_link function. */
-#undef HAVE_SYSCALL_LINK
-
-/* Define if you have the syscall_listen function. */
-#undef HAVE_SYSCALL_LISTEN
-
-/* Define if you have the syscall_lseek function. */
-#undef HAVE_SYSCALL_LSEEK
-
-/* Define if you have the syscall_lstat function. */
-#undef HAVE_SYSCALL_LSTAT
-
-/* Define if you have the syscall_open function. */
-#undef HAVE_SYSCALL_OPEN
-
-/* Define if you have the syscall_pgrpsys function. */
-#undef HAVE_SYSCALL_PGRPSYS
-
-/* Define if you have the syscall_pipe function. */
-#undef HAVE_SYSCALL_PIPE
-
-/* Define if you have the syscall_poll function. */
-#undef HAVE_SYSCALL_POLL
-
-/* Define if you have the syscall_putmsg function. */
-#undef HAVE_SYSCALL_PUTMSG
-
-/* Define if you have the syscall_read function. */
-#undef HAVE_SYSCALL_READ
-
-/* Define if you have the syscall_readdir function. */
-#undef HAVE_SYSCALL_READDIR
-
-/* Define if you have the syscall_readv function. */
-#undef HAVE_SYSCALL_READV
-
-/* Define if you have the syscall_recv function. */
-#undef HAVE_SYSCALL_RECV
-
-/* Define if you have the syscall_recvfrom function. */
-#undef HAVE_SYSCALL_RECVFROM
-
-/* Define if you have the syscall_recvmsg function. */
-#undef HAVE_SYSCALL_RECVMSG
-
-/* Define if you have the syscall_rename function. */
-#undef HAVE_SYSCALL_RENAME
-
-/* Define if you have the syscall_select function. */
-#undef HAVE_SYSCALL_SELECT
-
-/* Define if you have the syscall_send function. */
-#undef HAVE_SYSCALL_SEND
-
-/* Define if you have the syscall_sendmsg function. */
-#undef HAVE_SYSCALL_SENDMSG
-
-/* Define if you have the syscall_sendto function. */
-#undef HAVE_SYSCALL_SENDTO
-
-/* Define if you have the syscall_setsockopt function. */
-#undef HAVE_SYSCALL_SETSOCKOPT
-
-/* Define if you have the syscall_shutdown function. */
-#undef HAVE_SYSCALL_SHUTDOWN
-
-/* Define if you have the syscall_sigaction function. */
-#undef HAVE_SYSCALL_SIGACTION
-
-/* Define if you have the syscall_sigpause function. */
-#undef HAVE_SYSCALL_SIGPAUSE
-
-/* Define if you have the syscall_sigprocmask function. */
-#undef HAVE_SYSCALL_SIGPROCMASK
-
-/* Define if you have the syscall_sigsuspend function. */
-#undef HAVE_SYSCALL_SIGSUSPEND
-
-/* Define if you have the syscall_socket function. */
-#undef HAVE_SYSCALL_SOCKET
-
-/* Define if you have the syscall_socketcall function. */
-#undef HAVE_SYSCALL_SOCKETCALL
-
-/* Define if you have the syscall_socketpair function. */
-#undef HAVE_SYSCALL_SOCKETPAIR
-
-/* Define if you have the syscall_stat function. */
-#undef HAVE_SYSCALL_STAT
-
-/* Define if you have the syscall_uname function. */
-#undef HAVE_SYSCALL_UNAME
-
-/* Define if you have the syscall_unlink function. */
-#undef HAVE_SYSCALL_UNLINK
-
-/* Define if you have the syscall_wait3 function. */
-#undef HAVE_SYSCALL_WAIT3
-
-/* Define if you have the syscall_wait4 function. */
-#undef HAVE_SYSCALL_WAIT4
-
-/* Define if you have the syscall_waitpid function. */
-#undef HAVE_SYSCALL_WAITPID
-
-/* Define if you have the syscall_waitsys function. */
-#undef HAVE_SYSCALL_WAITSYS
-
-/* Define if you have the syscall_write function. */
-#undef HAVE_SYSCALL_WRITE
-
-/* Define if you have the syscall_writev function. */
-#undef HAVE_SYSCALL_WRITEV
-
-/* Define if you have the vfork function. */
-#undef HAVE_VFORK
-
-/* Define if you have the <alloc.h> header file. */
-#undef HAVE_ALLOC_H
-
-/* Define if you have the <sys/filio.h> header file. */
-#undef HAVE_SYS_FILIO_H
-
-/* Define if you have the <sys/syscall.h> header file. */
-#undef HAVE_SYS_SYSCALL_H
-
-/* Define if you have the <sys/termio.h> header file. */
-#undef HAVE_SYS_TERMIO_H
-
-/* Define if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define if you have the <syscall.h> header file. */
-#undef HAVE_SYSCALL_H
-
-/* Define if you have the <termio.h> header file. */
-#undef HAVE_TERMIO_H
-
-/* Define if you have the <termios.h> header file. */
-#undef HAVE_TERMIOS_H
diff --git a/mit-pthreads/config/config.sub b/mit-pthreads/config/config.sub
deleted file mode 100755
index 7a0c7855a2a..00000000000
--- a/mit-pthreads/config/config.sub
+++ /dev/null
@@ -1,794 +0,0 @@
-#!/bin/sh
-# Configuration validation subroutine script, version 1.1.
-# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-# First pass through any local machine types.
-case $1 in
- *local*)
- echo $1
- exit 0
- ;;
- *)
- ;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS (if any).
-basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-if [ $basic_machine != $1 ]
-then os=`echo $1 | sed 's/.*-/-/'`
-else os=; fi
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp )
- os=
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
- ;;
- -lynx)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- tahoe | i[3456]86 | i860 | m68k | m68000 | m88k | ns32k | arm | arm32 | pyramid \
- | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
- | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
- | powerpc | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
- | pdp11 | mips64el | mips64orion | mips64orionel )
- basic_machine=$basic_machine-unknown
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
- | sparc-* | ns32k-* | fx80-* | arm-* | arm32-* | c[123]* \
- | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
- | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
- | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
- | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
- | pdp11-* | sh-* | powerpc-* | sparc64-* | mips64-* | mipsel-* \
- | mips64el-* | mips64orion-* | mips64orionel-* )
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-cbm
- ;;
- amigados)
- basic_machine=m68k-cbm
- os=-amigados
- ;;
- amigaunix | amix)
- basic_machine=m68k-cbm
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- cray2)
- basic_machine=cray2-cray
- os=-unicos
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- os=-mvs
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i[3456]86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
- os=-sysv32
- ;;
- i[3456]86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
- os=-sysv4
- ;;
- i[3456]86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
- os=-sysv
- ;;
- i[3456]86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
- os=-solaris2
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pentium-*)
- # We will change tis to say i586 once there has been
- # time for various packages to start to recognize that.
- basic_machine=i486-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- xmp)
- basic_machine=xmp-cray
- os=-unicos
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- mips)
- basic_machine=mips-mips
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sparc)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative must end in a *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[3456]* \
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigados* | -msdos* | -newsos* | -unicos* | -aos* \
- | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
- | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -freebsd* | -openbsd* \
- |-riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
- | -ptx* | -coff* | -winnt*)
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -xenix)
- os=-xenix
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- *-acorn)
- os=-riscix1.2
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-ibm)
- os=-aix
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigados
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-masscomp)
- os=-rtu
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -lynxos*)
- vendor=lynx
- ;;
- -aix*)
- vendor=ibm
- ;;
- -hpux*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
diff --git a/mit-pthreads/config/configure b/mit-pthreads/config/configure
deleted file mode 100755
index 4d99ac5c07e..00000000000
--- a/mit-pthreads/config/configure
+++ /dev/null
@@ -1,3336 +0,0 @@
-#! /bin/sh
-
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-
-# Defaults:
-ac_help=
-ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
---enable-dce-compat DCE compatibility"
-ac_default_prefix=/usr/local/pthreads
-
-# Initialize some variables set by options.
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
-exec_prefix=NONE
-host=NONE
-no_create=
-nonopt=NONE
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-target=NONE
-verbose=
-x_includes=NONE
-x_libraries=NONE
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
-
-ac_prev=
-for ac_option
-do
-
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
- ac_prev=
- continue
- fi
-
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case "$ac_option" in
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file="$ac_optarg" ;;
-
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
- datadir="$ac_optarg" ;;
-
- -disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
-
- -enable-* | --enable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "enable_${ac_feature}='$ac_optarg'" ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he)
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir="$ac_optarg" ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir="$ac_optarg" ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix="$ac_optarg" ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix="$ac_optarg" ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir="$ac_optarg" ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.13"
- exit 0 ;;
-
- -with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "with_${ac_package}='$ac_optarg'" ;;
-
- -without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes="$ac_optarg" ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries="$ac_optarg" ;;
-
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
- ;;
-
- *)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
-fi
-exec 5>./config.log
-
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
- esac
-done
-
-# NLS nuisances.
-# Only set these to C if already set. These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
-
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=config.flags.in
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then its parent.
- ac_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
- srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
- if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
- else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
- fi
-fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
- if test "x$prefix" != xNONE; then
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
-fi
-for ac_site_file in $CONFIG_SITE; do
- if test -r "$ac_site_file"; then
- echo "loading site script $ac_site_file"
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- echo "loading cache $cache_file"
- . $cache_file
-else
- echo "creating cache $cache_file"
- > $cache_file
-fi
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-ac_exeext=
-ac_objext=o
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
- ac_n= ac_c='
-' ac_t=' '
- else
- ac_n=-n ac_c= ac_t=
- fi
-else
- ac_n= ac_c='\c' ac_t=
-fi
-
-
-# Check whether --enable-dce-compat or --disable-dce-compat was given.
-if test "${enable_dce_compat+set}" = set; then
- enableval="$enable_dce_compat"
- { echo "configure: error: Actually, DCE compatibility doesn't work yet..." 1>&2; exit 1; }
-
-else
- true
-
-fi
-
-
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:542: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="gcc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:572: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_prog_rejected=no
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# -gt 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- set dummy "$ac_dir/$ac_word" "$@"
- shift
- ac_cv_prog_CC="$@"
- fi
-fi
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
- if test -z "$CC"; then
- case "`uname -s`" in
- *win32* | *WIN32*)
- # Extract the first word of "cl", so it can be a program name with args.
-set dummy cl; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:623: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="cl"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
- ;;
- esac
- fi
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:655: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 666 "configure"
-#include "confdefs.h"
-
-main(){return(0);}
-EOF
-if { (eval echo configure:671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- ac_cv_prog_cc_works=yes
- # If we can't run a trivial program, we are probably using a cross compiler.
- if (./conftest; exit) 2>/dev/null; then
- ac_cv_prog_cc_cross=no
- else
- ac_cv_prog_cc_cross=yes
- fi
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cc_works=no
-fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
-if test $ac_cv_prog_cc_works = no; then
- { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:697: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:702: checking whether we are using GNU C" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:711: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
-else
- ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
-else
- GCC=
-fi
-
-ac_test_CFLAGS="${CFLAGS+set}"
-ac_save_CFLAGS="$CFLAGS"
-CFLAGS=
-echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:730: checking whether ${CC-cc} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_cc_g=yes
-else
- ac_cv_prog_cc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS="$ac_save_CFLAGS"
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-
-for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:766: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CXX="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CXX="$ac_cv_prog_CXX"
-if test -n "$CXX"; then
- echo "$ac_t""$CXX" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-test -n "$CXX" && break
-done
-test -n "$CXX" || CXX="gcc"
-
-
-echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:798: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
-
-ac_ext=C
-# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cxx_cross
-
-cat > conftest.$ac_ext << EOF
-
-#line 809 "configure"
-#include "confdefs.h"
-
-int main(){return(0);}
-EOF
-if { (eval echo configure:814: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- ac_cv_prog_cxx_works=yes
- # If we can't run a trivial program, we are probably using a cross compiler.
- if (./conftest; exit) 2>/dev/null; then
- ac_cv_prog_cxx_cross=no
- else
- ac_cv_prog_cxx_cross=yes
- fi
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cxx_works=no
-fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
-if test $ac_cv_prog_cxx_works = no; then
- { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:840: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
-cross_compiling=$ac_cv_prog_cxx_cross
-
-echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-echo "configure:845: checking whether we are using GNU C++" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.C <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:854: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gxx=yes
-else
- ac_cv_prog_gxx=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gxx" 1>&6
-
-if test $ac_cv_prog_gxx = yes; then
- GXX=yes
-else
- GXX=
-fi
-
-ac_test_CXXFLAGS="${CXXFLAGS+set}"
-ac_save_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS=
-echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-echo "configure:873: checking whether ${CXX-g++} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.cc
-if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
- ac_cv_prog_cxx_g=yes
-else
- ac_cv_prog_cxx_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
-if test "$ac_test_CXXFLAGS" = set; then
- CXXFLAGS="$ac_save_CXXFLAGS"
-elif test $ac_cv_prog_cxx_g = yes; then
- if test "$GXX" = yes; then
- CXXFLAGS="-g -O2"
- else
- CXXFLAGS="-g"
- fi
-else
- if test "$GXX" = yes; then
- CXXFLAGS="-O2"
- else
- CXXFLAGS=
- fi
-fi
-
-echo $ac_n "checking compiler availability and simple error detection""... $ac_c" 1>&6
-echo "configure:905: checking compiler availability and simple error detection" >&5
-cat > conftest.$ac_ext <<EOF
-#line 907 "configure"
-#include "confdefs.h"
-
-int main() {
- exit(0);
-; return 0; }
-EOF
-if { (eval echo configure:914: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- cat > conftest.$ac_ext <<EOF
-#line 918 "configure"
-#include "confdefs.h"
-
-int main() {
- syntax errors galore!
-; return 0; }
-EOF
-if { (eval echo configure:925: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- { echo "configure: error: Can't detect syntax errors! Is CC set right?" 1>&2; exit 1; }
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- true
-fi
-rm -f conftest*
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't compile test program! Is CC set right?" 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-cat > conftest.$ac_ext <<EOF
-#line 944 "configure"
-#include "confdefs.h"
-
-int main() {
-
- typedef int Integer;
- extern int i;
- extern Integer i;
-
-; return 0; }
-EOF
-if { (eval echo configure:955: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- :
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't redeclare variables with this compiler??" 1>&2; exit 1; }
-fi
-rm -f conftest*
-cat > conftest.$ac_ext <<EOF
-#line 965 "configure"
-#include "confdefs.h"
-
-int main() {
-
- typedef long Long;
- extern int i;
- extern Long i;
-
-; return 0; }
-EOF
-if { (eval echo configure:976: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- { echo "configure: error: Compiler doesn't detect conflicting declarations." 1>&2; exit 1; }
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
-echo "$ac_t""ok" 1>&6
-
-if test $ac_cv_prog_gcc = yes ; then
- CFLAGS="$CFLAGS -Werror"
-fi
-
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:991: checking how to run the C preprocessor" >&5
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 1006 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1012: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 1023 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1029: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -nologo -E"
- cat > conftest.$ac_ext <<EOF
-#line 1040 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1046: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP=/lib/cpp
-fi
-rm -f conftest*
-fi
-rm -f conftest*
-fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
-fi
- CPP="$ac_cv_prog_CPP"
-else
- ac_cv_prog_CPP="$CPP"
-fi
-echo "$ac_t""$CPP" 1>&6
-
-
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1074: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_RANLIB="ranlib"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
- echo "$ac_t""$RANLIB" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-
-# Do some error checking and defaulting for the host and target type.
-# The inputs are:
-# configure --host=HOST --target=TARGET --build=BUILD NONOPT
-#
-# The rules are:
-# 1. You are not allowed to specify --host, --target, and nonopt at the
-# same time.
-# 2. Host defaults to nonopt.
-# 3. If nonopt is not specified, then host defaults to the current host,
-# as determined by config.guess.
-# 4. Target and build default to nonopt.
-# 5. If nonopt is not specified, then target and build default to host.
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-case $host---$target---$nonopt in
-NONE---*---* | *---NONE---* | *---*---NONE) ;;
-*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
-esac
-
-
-# Make sure we can run config.sub.
-if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:1151: checking host system type" >&5
-
-host_alias=$host
-case "$host_alias" in
-NONE)
- case $nonopt in
- NONE)
- if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
- else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
- fi ;;
- *) host_alias=$nonopt ;;
- esac ;;
-esac
-
-host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
-
-echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:1172: checking target system type" >&5
-
-target_alias=$target
-case "$target_alias" in
-NONE)
- case $nonopt in
- NONE) target_alias=$host_alias ;;
- *) target_alias=$nonopt ;;
- esac ;;
-esac
-
-target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
-target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$target" 1>&6
-
-echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1190: checking build system type" >&5
-
-build_alias=$build
-case "$build_alias" in
-NONE)
- case $nonopt in
- NONE) build_alias=$host_alias ;;
- *) build_alias=$nonopt ;;
- esac ;;
-esac
-
-build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
-build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$build" 1>&6
-
-test "$host_alias" != "$target_alias" &&
- test "$program_prefix$program_suffix$program_transform_name" = \
- NONENONEs,x,x, &&
- program_prefix=${target_alias}-
-
-
-syscall=NONE
-sysincludes=NONE
-extraincludes=NONE
-
-# Treat all x86 machines the same.
-# (Yet below, we pretend we can distinguish between the MIPS r2000 and r4000?)
-# (What about 680x0 machines?)
-case $host in
- i[456]86-*)
- host=`echo $host | sed 's/^i[456]86/i386/'`
- host_cpu=i386
- ;;
-esac
-
-# Here, you should set the following variables:
-# name
-# The "name" of this configuration. Used for "engine-*.c" file name,
-# default for syscall file names. Chris seems to have a thing for
-# putting "-" between OS and version number, but the configure script
-# will already have $host_cpu and $host_os available for you to use
-# in constructing a name.
-# sysincludes
-# Name of machdep directory with "sys" include file
-# replacements, if any. This directory is optional;
-# if you don't provide it, don't set this variable.
-# except
-# Names of any syscalls that shouldn't be generated
-# from the template, if any.
-# syscall
-# Base name of the syscall template files, if not the
-# same as <name>. If they're the same, omit this.
-#
-# Also, you may define random symbols and update CFLAGS if
-# necessary. However, for ease of porting to new machines,
-# it's best if you can create portable autoconf tests for
-# whatever you're trying to do, rather than hard-coding it
-# here based on the OS name. So please, try to keep this
-# section as minimal as possible.
-
-except=""
-name=$host_cpu-$host_os
-
-case $host in
- alpha-*-netbsd1.3[H-Z]|alpha-*-netbsd1.[45]*)
- name=alpha-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
- alpha-*-netbsd1.3*)
- name=alpha-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask fstat"
- ;;
- alpha-*-netbsd1.1* | alpha-*-netbsd1.2*)
- name=alpha-netbsd-1.1
- sysincludes=netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask"
- ;;
- alpha-*-osf*)
- name=alpha-osf1
- sysincludes=alpha-osf1
- except="fork sigsuspend"
- if test $ac_cv_prog_gcc = no ; then
- CFLAGS="$CFLAGS -std"
- fi
- ;;
- arm32-*-netbsd1.3[H-Z]|arm32-*-netbsd1.[45]*)
- name=arm32-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork pipe lseek ftruncate fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
- arm32-*-netbsd1.3*)
- name=arm32-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork pipe lseek ftruncate sigsuspend sigprocmask fstat"
- ;;
- hppa1.0-*-hpux10.20 | hppa1.1-*-hpux10.20)
- name=hppa-hpux-10.20
- sysincludes=hpux-10.20
- except="fork"
- ;;
- hppa1.1-*-hpux*9.*)
- name=hppa-hpux-9.03
- sysincludes=hpux-9.03
- # hpux-9.03.mk seems to be missing; what should this be?
- except="fork"
- ;;
- powerpc-*-netbsd1.*)
- name=powerpc-netbsd
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe fstat"
- available_syscalls="sigprocmask sigaction sigsuspend"
- ;;
- sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
- name=sparc-sunos-4.1.3
- sysincludes=sunos-4.1.3
- syscall=sparc-sunos4
- except="fork pipe getpgrp getdirentries"
- cat >> confdefs.h <<\EOF
-#define sunos4 1
-EOF
- # is this really needed??
- ;;
- sparc-*-solaris2.3* | sparc-*-solaris2.4*)
- name=sparc-sunos-5.3
- sysincludes=sunos-5.3
- except="fork sigaction"
- # Should really come up with a test for this...
- cat >> confdefs.h <<\EOF
-#define LD_LINKS_STATIC_DATA 1
-EOF
-
- cat >> confdefs.h <<\EOF
-#define BROKEN_SIGNALS 1
-EOF
-
- ;;
- sparc-*-solaris2*)
- name=sparc-sunos-5.3
- sysincludes=sunos-5.5
- except="fork sigaction"
- # Should really come up with a test for this...
- cat >> confdefs.h <<\EOF
-#define LD_LINKS_STATIC_DATA 1
-EOF
-
- cat >> confdefs.h <<\EOF
-#define BROKEN_SIGNALS 1
-EOF
-
- ;;
- sparc-*-netbsd1.3[H-Z]|sparc-*-netbsd1.[45]*)
- name=sparc-netbsd-1.3
- sysincludes=netbsd-1.1
- except="pipe fork lseek ftruncate fstat"
- available_syscalls="sigprocmask sigsuspend"
- ;;
- sparc-*-netbsd1.3*)
- name=sparc-netbsd-1.3
- sysincludes=netbsd-1.1
- except="pipe fork lseek ftruncate sigprocmask sigsuspend fstat"
- ;;
- sparc-*-netbsd1.0A | sparc-*-netbsd1.1* | sparc-*-netbsd1.2*)
- name=sparc-sunos-4.1.3
- sysincludes=netbsd-1.0
- syscall=sparc-netbsd-1.1
- except="pipe fork sigprocmask sigsuspend"
- ;;
- i386-*-openbsd2.*)
- name=i386-openbsd-2.0
- sysincludes=openbsd-2.0
- except="fork lseek ftruncate sigsuspend sigprocmask"
- ;;
- i386-*-linux*)
- #name=i386-linux-1.0
- #sysincludes=linux-1.0
- name=i386-linux-2.0
- sysincludes=linux-2.0
- extraincludes="bits"
- ;;
- i386-*-bsdi1.1)
- name=i386-bsdi-1.1
- sysincludes=bsdi-1.1
- ;;
- i386-*-bsdi2.0* | i386-*-bsdi2.1*)
- name=i386-bsdi-2.0
- sysincludes=bsdi-2.0
- syscall=i386-bsdi-2.0
- except="fork lseek ftruncate sigsuspend"
- ;;
- i386-*-netbsd1.3[H-Z]|i386-*-netbsd1.[45]*)
- name=i386-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
- i386-*-netbsd1.3*)
- name=i386-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe sigsuspend sigprocmask fstat"
- ;;
- i386-*-netbsd1.1* | i386-*-netbsd1.2*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.1
- syscall=i386-netbsd-1.1
- except="fork lseek ftruncate pipe sigsuspend sigprocmask"
- ;;
- i386-*-netbsd1.0*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.0
- except="fork lseek ftruncate sigsuspend"
- ;;
- i386-*-netbsd0.9*)
- name=i386-netbsd-0.9
- sysincludes=netbsd-0.9
- ;;
- m68*-*-netbsd*)
- name=m68000-netbsd
- sysincludes=netbsd-1.1
- except="lseek ftruncate pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
- i386-*-freebsd*)
- name=i386-freebsd-2.0
- sysincludes=freebsd-2.0
- except="fork lseek ftruncate sigsuspend sigprocmask"
- ;;
- romp-*-bsd*)
- name=romp-bsd
- ;;
- mips-dec-ultrix*)
- name=r2000-ultrix-4.2
- sysincludes=ultrix-4.2
- except="fork pipe"
- ;;
- mips-sgi-irix*)
- name=ip22-irix-5.2
- sysincludes=irix-5.2
- except="fstat stat"
- cat >> confdefs.h <<\EOF
-#define BROKEN_SIGNALS 1
-EOF
-
- ;;
- i386-*-sco3.2v5*)
- name=i386-sco3.2.5
- sysincludes=i386-sco3.2.5
- syscall=i386-sco3.2.5
- except="select socketcall accept bind connect getpeername getsockname getsockopt setsockopt listen recv recvfrom recvmsg send sendmsg sendto shutdown socket socketpair fork fcntl dup2 fstat fchmod fchown ftruncate pipe getdirentries sigaction sigpause wait3 waitpid getdtablesize"
- ;;
- *)
- { echo "configure: error: System type $host not recognized or not supported.
-See $srcdir/configure.in for supported systems." 1>&2; exit 1; }
- exit 1
- ;;
-esac
-
-SYSCALL_EXCEPTIONS=$except
-
-
-for ac_hdr in sys/termio.h termios.h termio.h alloc.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1453: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1458 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1463: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-ac_safe=`echo "va_list.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for va_list.h""... $ac_c" 1>&6
-echo "configure:1492: checking for va_list.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1497 "configure"
-#include "confdefs.h"
-#include <va_list.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1502: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define pthread_have_va_list_h 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-for ac_hdr in syscall.h sys/syscall.h sys/filio.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1531: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1536 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1541: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-pthreads_syscall_list="open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
- rename select getdtablesize ioctl ftruncate flock fstatfs chroot uname
- sigsuspend sigaction sigpause sigprocmask ksigaction
- getdents readdir getdirentries
- wait4 wait3 waitpid waitsys
- socket bind connect accept listen getsockopt setsockopt socketpair
- poll putmsg getmsg
- socketcall
-
- pgrpsys
-
- exit
- readv writev send sendto sendmsg recv recvfrom recvmsg
- getpeername getsockname
- shutdown
- getpgrp fork"
-for pthreads_syscallname in $pthreads_syscall_list ; do
- echo $ac_n "checking for syscall $pthreads_syscallname""... $ac_c" 1>&6
-echo "configure:1587: checking for syscall $pthreads_syscallname" >&5
-if eval "test \"`echo '$''{'pthreads_cv_syscall_$pthreads_syscallname'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1592 "configure"
-#include "confdefs.h"
-
-/* FIXME: This list should be generated from info in configure.in. */
-#ifdef HAVE_SYSCALL_H
-#include <syscall.h>
-#else
-#ifdef HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
-#else
-where is your syscall header file??
-#endif
-#endif
-
-int main() {
-
-int x;
-x = SYS_$pthreads_syscallname ;
-
-; return 0; }
-EOF
-if { (eval echo configure:1613: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval pthreads_cv_syscall_$pthreads_syscallname=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval pthreads_cv_syscall_$pthreads_syscallname=no
-fi
-rm -f conftest*
-fi
-
-if eval test \$pthreads_cv_syscall_$pthreads_syscallname = yes ; then
- pthreads_syscall_present=yes
- available_syscalls="$available_syscalls $pthreads_syscallname"
- macroname=HAVE_SYSCALL_`echo $pthreads_syscallname | tr '[a-z]' '[A-Z]'`
- cat >> confdefs.h <<EOF
-#define $macroname 1
-EOF
-
-else
- pthreads_syscall_present=no
- missing_syscalls="$missing_syscalls $pthreads_syscallname"
-fi
-echo "$ac_t""$pthreads_syscall_present" 1>&6
-
-done
-
-
-
-
-
-
-## Determine some typedef values from the system header files.
-echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1648: checking for ANSI C header files" >&5
-if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1653 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1661: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- ac_cv_header_stdc=yes
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1678 "configure"
-#include "confdefs.h"
-#include <string.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "memchr" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1696 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "free" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-if test "$cross_compiling" = yes; then
- :
-else
- cat > conftest.$ac_ext <<EOF
-#line 1717 "configure"
-#include "confdefs.h"
-#include <ctype.h>
-#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int main () { int i; for (i = 0; i < 256; i++)
-if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
-exit (0); }
-
-EOF
-if { (eval echo configure:1728: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
- :
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_header_stdc=no
-fi
-rm -fr conftest*
-fi
-
-fi
-fi
-
-echo "$ac_t""$ac_cv_header_stdc" 1>&6
-if test $ac_cv_header_stdc = yes; then
- cat >> confdefs.h <<\EOF
-#define STDC_HEADERS 1
-EOF
-
-fi
-
-echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:1752: checking for off_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1757 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_off_t=yes
-else
- rm -rf conftest*
- ac_cv_type_off_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_off_t" 1>&6
-if test $ac_cv_type_off_t = no; then
- cat >> confdefs.h <<\EOF
-#define off_t long
-EOF
-
-fi
-
-echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:1785: checking for size_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1790 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_size_t=yes
-else
- rm -rf conftest*
- ac_cv_type_size_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_size_t" 1>&6
-if test $ac_cv_type_size_t = no; then
- cat >> confdefs.h <<\EOF
-#define size_t unsigned
-EOF
-
-fi
-
-echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:1818: checking return type of signal handlers" >&5
-if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1823 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <signal.h>
-#ifdef signal
-#undef signal
-#endif
-#ifdef __cplusplus
-extern "C" void (*signal (int, void (*)(int)))(int);
-#else
-void (*signal ()) ();
-#endif
-
-int main() {
-int i;
-; return 0; }
-EOF
-if { (eval echo configure:1840: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_type_signal=void
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_type_signal=int
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_type_signal" 1>&6
-cat >> confdefs.h <<EOF
-#define RETSIGTYPE $ac_cv_type_signal
-EOF
-
-
-echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-echo "configure:1859: checking for ssize_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1864 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])ssize_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_ssize_t=yes
-else
- rm -rf conftest*
- ac_cv_type_ssize_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_ssize_t" 1>&6
-if test $ac_cv_type_ssize_t = no; then
- cat >> confdefs.h <<\EOF
-#define ssize_t int
-EOF
-
-fi
-
-echo $ac_n "checking for time_t""... $ac_c" 1>&6
-echo "configure:1892: checking for time_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_time_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1897 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])time_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_time_t=yes
-else
- rm -rf conftest*
- ac_cv_type_time_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_time_t" 1>&6
-if test $ac_cv_type_time_t = no; then
- cat >> confdefs.h <<\EOF
-#define time_t long
-EOF
-
-fi
-
-for ac_hdr in sys/time.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1928: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1933 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1938: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1965: checking whether time.h and sys/time.h may both be included" >&5
-if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1970 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-int main() {
-struct tm *tp;
-; return 0; }
-EOF
-if { (eval echo configure:1979: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_header_time=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_time=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_header_time" 1>&6
-if test $ac_cv_header_time = yes; then
- cat >> confdefs.h <<\EOF
-#define TIME_WITH_SYS_TIME 1
-EOF
-
-fi
-
-
-echo $ac_n "checking for struct timespec in sys/time.h""... $ac_c" 1>&6
-echo "configure:2001: checking for struct timespec in sys/time.h" >&5
-if eval "test \"`echo '$''{'pthreads_cv_timespec_in_time'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2006 "configure"
-#include "confdefs.h"
-#include <sys/time.h>
-int main() {
-struct timespec foo;
-; return 0; }
-EOF
-if { (eval echo configure:2013: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_timespec_in_time=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- pthreads_cv_timespec_in_time=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$pthreads_cv_timespec_in_time" 1>&6
-if test $pthreads_cv_timespec_in_time = yes ; then
- cat >> confdefs.h <<\EOF
-#define _OS_HAS_TIMESPEC 1
-EOF
-
-fi
-
-if eval "test \"`echo '$''{'pthreads_cv_socklen_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2037 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-int main() {
-socklen_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2045: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_socklen_t=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- pthreads_cv_socklen_t=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$pthreads_cv_socklen_t" 1>&6
-if test $pthreads_cv_socklen_t = yes ; then
- cat >> confdefs.h <<\EOF
-#define _OS_HAS_SOCKLEN_T 1
-EOF
-
-fi
-
-
-
-echo $ac_n "checking type of size_t""... $ac_c" 1>&6
-echo "configure:2068: checking type of size_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2073 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern size_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2086: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2090 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern size_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2103: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_size_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for size_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_size_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_size_t $pthreads_cv_type_size_t
-EOF
-
-fi
-pthread_size_t=$pthreads_cv_type_size_t
-echo "$ac_t""$pthreads_cv_type_size_t" 1>&6
-
-echo $ac_n "checking type of ssize_t""... $ac_c" 1>&6
-echo "configure:2131: checking type of ssize_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_ssize_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2136 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int main() {
- extern ssize_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2147: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2151 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int main() {
- extern ssize_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2162: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_ssize_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for ssize_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_ssize_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_ssize_t $pthreads_cv_type_ssize_t
-EOF
-
-fi
-pthread_ssize_t=$pthreads_cv_type_ssize_t
-echo "$ac_t""$pthreads_cv_type_ssize_t" 1>&6
-
-echo $ac_n "checking type of clock_t""... $ac_c" 1>&6
-echo "configure:2190: checking type of clock_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_clock_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2195 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() {
- extern clock_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2214: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2218 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() {
- extern clock_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2237: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_clock_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for clock_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_clock_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_clock_t $pthreads_cv_type_clock_t
-EOF
-
-fi
-pthread_clock_t=$pthreads_cv_type_clock_t
-echo "$ac_t""$pthreads_cv_type_clock_t" 1>&6
-
-echo $ac_n "checking type of time_t""... $ac_c" 1>&6
-echo "configure:2265: checking type of time_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_time_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2270 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() {
- extern time_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2289: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2293 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() {
- extern time_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2312: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_time_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for time_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_time_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_time_t $pthreads_cv_type_time_t
-EOF
-
-fi
-pthread_time_t=$pthreads_cv_type_time_t
-echo "$ac_t""$pthreads_cv_type_time_t" 1>&6
-echo $ac_n "checking for fpos_t in stdio.h""... $ac_c" 1>&6
-echo "configure:2339: checking for fpos_t in stdio.h" >&5
-if eval "test \"`echo '$''{'pthreads_cv_fpos_t_in_stdio'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2344 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-int main() {
-fpos_t position;
-; return 0; }
-EOF
-if { (eval echo configure:2351: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_fpos_t_in_stdio=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- pthreads_cv_fpos_t_in_stdio=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$pthreads_cv_fpos_t_in_stdio" 1>&6
-if test $pthreads_cv_fpos_t_in_stdio = yes ; then
-
-echo $ac_n "checking type of fpos_t""... $ac_c" 1>&6
-echo "configure:2367: checking type of fpos_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_fpos_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2372 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern fpos_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2385: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2389 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern fpos_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2402: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_fpos_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for fpos_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_fpos_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_fpos_t $pthreads_cv_type_fpos_t
-EOF
-
-fi
-pthread_fpos_t=$pthreads_cv_type_fpos_t
-echo "$ac_t""$pthreads_cv_type_fpos_t" 1>&6
-else
- cat >> confdefs.h <<\EOF
-#define fpos_t off_t
-EOF
-
- cat >> confdefs.h <<\EOF
-#define pthread_fpos_t pthread_off_t
-EOF
-
-fi
-
-echo $ac_n "checking type of off_t""... $ac_c" 1>&6
-echo "configure:2440: checking type of off_t" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_off_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2445 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern off_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2458: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2462 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() {
- extern off_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2475: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_off_t="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for off_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_off_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_off_t $pthreads_cv_type_off_t
-EOF
-
-fi
-pthread_off_t=$pthreads_cv_type_off_t
-echo "$ac_t""$pthreads_cv_type_off_t" 1>&6
-echo $ac_n "checking type of va_list""... $ac_c" 1>&6
-echo "configure:2502: checking type of va_list" >&5
-if eval "test \"`echo '$''{'pthreads_cv_type_va_list'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2507 "configure"
-#include "confdefs.h"
-#include <stdarg.h>
-int main() {
- extern va_list foo;
-; return 0; }
-EOF
-if { (eval echo configure:2514: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "char *" "char **" "void *" "void **" "int *" "long *" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2518 "configure"
-#include "confdefs.h"
-#include <stdarg.h>
-int main() {
- extern va_list foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2525: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_va_list="$try_type" ; break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for va_list." 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-if test -n "$pthreads_cv_type_va_list" ; then
- cat >> confdefs.h <<EOF
-#define pthread_va_list $pthreads_cv_type_va_list
-EOF
-
-fi
-pthread_va_list=$pthreads_cv_type_va_list
-echo "$ac_t""$pthreads_cv_type_va_list" 1>&6
-
-arpa_headers="#include <sys/types.h>
-#include <arpa/nameser.h>"
-
-echo $ac_n "checking IP address type""... $ac_c" 1>&6
-echo "configure:2556: checking IP address type" >&5
-if eval "test \"`echo '$''{'pthread_cv_type_ipaddr'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2561 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() {
- &_getlong;
-; return 0; }
-EOF
-if { (eval echo configure:2568: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- for type in "unsigned long" "unsigned int" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2573 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() {
-extern $type _getlong ();
-; return 0; }
-EOF
-if { (eval echo configure:2580: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- pthread_cv_type_ipaddr="$type"
- break
-
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- echo "configure: warning: Can't compile _getlong reference." 1>&2
-fi
-rm -f conftest*
- if test "$pthread_cv_type_ipaddr" = "" ; then
- echo "configure: warning: Can't determine _getlong return type." 1>&2
- echo "configure: warning: Defaulting to unsigned long." 1>&2
- pthread_cv_type_ipaddr="unsigned long"
- fi
-
-fi
-
-echo "$ac_t""$pthread_cv_type_ipaddr" 1>&6
-cat >> confdefs.h <<EOF
-#define pthread_ipaddr_type $pthread_cv_type_ipaddr
-EOF
-
-
-echo $ac_n "checking IP port type""... $ac_c" 1>&6
-echo "configure:2615: checking IP port type" >&5
-if eval "test \"`echo '$''{'pthread_cv_type_ipport'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2620 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() {
- &_getshort;
-; return 0; }
-EOF
-if { (eval echo configure:2627: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- for type in "unsigned short" "unsigned int" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2632 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() {
-extern $type _getshort ();
-; return 0; }
-EOF
-if { (eval echo configure:2639: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- pthread_cv_type_ipport="$type"
- break
-
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- done
-
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- echo "configure: warning: Can't compile _getshort reference." 1>&2
-fi
-rm -f conftest*
- if test "$pthread_cv_type_ipport" = "" ; then
- echo "configure: warning: Can't determine _getshort return type." 1>&2
- echo "configure: warning: Defaulting to unsigned short." 1>&2
- pthread_cv_type_ipport="unsigned short"
- fi
-
-fi
-
-echo "$ac_t""$pthread_cv_type_ipport" 1>&6
-cat >> confdefs.h <<EOF
-#define pthread_ipport_type $pthread_cv_type_ipport
-EOF
-
-
-echo $ac_n "checking pathname for terminal devices directory""... $ac_c" 1>&6
-echo "configure:2674: checking pathname for terminal devices directory" >&5
-if eval "test \"`echo '$''{'pthread_cv_pty_path'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -d /devices/pseudo ; then
- pty_path=/devices/pseudo/
- else
- pty_path=/dev/
- fi
- pthread_cv_pty_path=$pty_path
-
-fi
-
-cat >> confdefs.h <<EOF
-#define _PATH_PTY "$pthread_cv_pty_path"
-EOF
-
-echo "$ac_t""$pthread_cv_pty_path" 1>&6
-
-echo $ac_n "checking directory name for time zone info""... $ac_c" 1>&6
-echo "configure:2694: checking directory name for time zone info" >&5
-tzdir=NONE
-for f in /usr/lib/zoneinfo /usr/share/zoneinfo /usr/share/lib/zoneinfo /etc/zoneinfo /usr/local/lib/zoneinfo
-do
- if test -d $f ; then
- tzdir=$f
- break
- fi
-done
-case $tzdir in
-NONE)
- echo "configure: warning: Can't find zoneinfo directory." 1>&2
- echo "configure: warning: Defaulting zoneinfo directory to NULL." 1>&2
- tzdir=NULL
- ;;
-esac
-cat >> confdefs.h <<EOF
-#define _PATH_TZDIR "$tzdir"
-EOF
-
-echo "$ac_t""$tzdir" 1>&6
-
-echo $ac_n "checking filename for local time zone""... $ac_c" 1>&6
-echo "configure:2717: checking filename for local time zone" >&5
-tzfile=NONE
-for f in $tzdir/localtime /etc/localtime
-do
- if test -f $f ; then
- tzfile=$f
- break
- fi
-done
-case $tzfile in
-NONE) # Should this default to tzdir/localtime?
- echo "configure: warning: Can't find local time zone file." 1>&2
- if test tzdir = NULL ; then
- echo "configure: warning: Defaulting local time zone file to NULL" 1>&2
- tzfile=NULL
- else
- echo "configure: warning: Defaulting local time zone file to $tzdir/localtime." 1>&2
- tzfile=$tzdir/localtime
- fi
- ;;
-esac
-cat >> confdefs.h <<EOF
-#define _PATH_TZFILE "$tzfile"
-EOF
-
-echo "$ac_t""$tzfile" 1>&6
-
-cat >> confdefs.h <<\EOF
-#define _PATH_RESCONF "/etc/resolv.conf"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_HOSTS "/etc/hosts"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_NETWORKS "/etc/networks"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_PROTOCOLS "/etc/protocols"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_SERVICES "/etc/services"
-EOF
-
-
-cat >> confdefs.h <<\EOF
-#define _PATH_BSHELL "/bin/sh"
-EOF
-
-
-for ac_func in vfork
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2773: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2778 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:2801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-srctop=`cd ${srcdir}/..;pwd`
-
-
-# Now we deal with symlinks &c.
-
-test -d include || mkdir include || \
- { echo "configure: error: Can't create include directory." 1>&2; exit 1; }
-
-test -d include/pthread || mkdir include/pthread || \
- { echo "configure: error: Can't create include/pthread directory." 1>&2; exit 1; }
-
-test -d lib || mkdir lib || \
- { echo "configure: error: Can't create lib directory." 1>&2; exit 1; }
-
-test -d lib/libpthreadutil || mkdir lib/libpthreadutil || \
- { echo "configure: error: Can't create lib/libpthreadutil directory." 1>&2; exit 1; }
-
-test -d bin || mkdir bin || \
- { echo "configure: error: Can't create bin directory." 1>&2; exit 1; }
-
-test -d bin/finger || mkdir bin/finger || \
- { echo "configure: error: Can't create bin directory." 1>&2; exit 1; }
-
-test -d tests || mkdir tests || \
- { echo "configure: error: Can't create tests directory." 1>&2; exit 1; }
-
-if test x$syscall = xNONE ; then
- syscall=$name
-fi
-
-links="include/pthread/machdep.h include/pthread/posix.h \
- machdep.c syscall.S"
-targets="../machdep/engine-$name.h ../machdep/posix-$sysincludes.h \
- ../machdep/engine-$name.c ../machdep/syscall-$syscall.S"
-
-# Both these targets are optional. (Autoconf-generated configure scripts
-# will require the existence of link targets, so check before adding them
-# to the list.)
-if test x$sysincludes != xNONE ; then
- links="$links include/sys"
- targets="$targets ../machdep/$sysincludes"
-fi
-
-if test x$extraincludes != xNONE ; then
- for tmp in $extraincludes
- do
- links="$links include/$tmp"
- targets="$targets ../machdep/$sysincludes/extra/$tmp"
- done
-fi
-
-syscall_file=../machdep/syscall-template-$syscall.S
-if test -r $srcdir/$syscall_file ; then
- links="$links syscall-template.S"
- targets="$targets $syscall_file"
- HAVE_SYSCALL_TEMPLATE=yes
-else
- # This really isn't a fatal problem. In fact, it's expected, initially,
- # for some targets. This is just to persuade people to fix the targets
- # they deal with to provide some sort of template.
- #
- # Eventually this file probably will be required...
- echo "configure: warning: No syscall template file syscall-template-$syscall.S found." 1>&2
- HAVE_SYSCALL_TEMPLATE=no
-fi
-
-
-
-
-if test x$makefile_frag != x ; then
- makefile_frag=${srcdir}/$makefile_frag
-else
- makefile_frag=/dev/null
-fi
-
-
-
-
-
-trap '' 1 2 15
-cat > confcache <<\EOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs. It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
-#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already. You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
-#
-EOF
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
- case `(ac_space=' '; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote substitution
- # turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- -e "s/'/'\\\\''/g" \
- -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
- ;;
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
- ;;
- esac >> confcache
-if cmp -s $cache_file confcache; then
- :
-else
- if test -w $cache_file; then
- echo "updating cache $cache_file"
- cat confcache > $cache_file
- else
- echo "not updating unwritable cache $cache_file"
- fi
-fi
-rm -f confcache
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
-fi
-
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
-DEFS=-DHAVE_CONFIG_H
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
-# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
-# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
-
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
- case "\$ac_option" in
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
- -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.13"
- exit 0 ;;
- -help | --help | --hel | --he | --h)
- echo "\$ac_cs_usage"; exit 0 ;;
- *) echo "\$ac_cs_usage"; exit 1 ;;
- esac
-done
-
-ac_given_srcdir=$srcdir
-
-trap 'rm -fr `echo "config.flags GNUmakefile Makefile \
- lib/Makefile:../lib/Makefile.in \
- lib/libpthreadutil/Makefile:../lib/libpthreadutil/Makefile.in \
- bin/Makefile:../bin/Makefile.in \
- bin/finger/Makefile:../bin/finger/Makefile.in \
- tests/Makefile:../tests/Makefile.in config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@SHELL@%$SHELL%g
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@FFLAGS@%$FFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@CC@%$CC%g
-s%@CXX@%$CXX%g
-s%@CPP@%$CPP%g
-s%@RANLIB@%$RANLIB%g
-s%@host@%$host%g
-s%@host_alias@%$host_alias%g
-s%@host_cpu@%$host_cpu%g
-s%@host_vendor@%$host_vendor%g
-s%@host_os@%$host_os%g
-s%@target@%$target%g
-s%@target_alias@%$target_alias%g
-s%@target_cpu@%$target_cpu%g
-s%@target_vendor@%$target_vendor%g
-s%@target_os@%$target_os%g
-s%@build@%$build%g
-s%@build_alias@%$build_alias%g
-s%@build_cpu@%$build_cpu%g
-s%@build_vendor@%$build_vendor%g
-s%@build_os@%$build_os%g
-s%@SYSCALL_EXCEPTIONS@%$SYSCALL_EXCEPTIONS%g
-s%@available_syscalls@%$available_syscalls%g
-s%@missing_syscalls@%$missing_syscalls%g
-s%@srctop@%$srctop%g
-s%@HAVE_SYSCALL_TEMPLATE@%$HAVE_SYSCALL_TEMPLATE%g
-/@makefile_frag@/r $makefile_frag
-s%@makefile_frag@%%g
-
-CEOF
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-
-# Split the substitutions into bite-sized pieces for seds with
-# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
-ac_file=1 # Number of current file.
-ac_beg=1 # First line for current file.
-ac_end=$ac_max_sed_cmds # Line after last line for current file.
-ac_more_lines=:
-ac_sed_cmds=""
-while $ac_more_lines; do
- if test $ac_beg -gt 1; then
- sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
- else
- sed "${ac_end}q" conftest.subs > conftest.s$ac_file
- fi
- if test ! -s conftest.s$ac_file; then
- ac_more_lines=false
- rm -f conftest.s$ac_file
- else
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f conftest.s$ac_file"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
- fi
- ac_file=`expr $ac_file + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_cmds`
- fi
-done
-if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
-fi
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"config.flags GNUmakefile Makefile \
- lib/Makefile:../lib/Makefile.in \
- lib/libpthreadutil/Makefile:../lib/libpthreadutil/Makefile.in \
- bin/Makefile:../bin/Makefile.in \
- bin/finger/Makefile:../bin/finger/Makefile.in \
- tests/Makefile:../tests/Makefile.in"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
-
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dir_suffix= ac_dots=
- fi
-
- case "$ac_given_srcdir" in
- .) srcdir=.
- if test -z "$ac_dots"; then top_srcdir=.
- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
- *) # Relative path.
- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
- top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
-
-
- echo creating "$ac_file"
- rm -f "$ac_file"
- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
- case "$ac_file" in
- *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
- *) ac_comsub= ;;
- esac
-
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
-fi; done
-rm -f conftest.s*
-
-# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
-# NAME is the cpp macro being defined and VALUE is the value it is being given.
-#
-# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
-ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
-ac_dC='\3'
-ac_dD='%g'
-# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
-ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_uB='\([ ]\)%\1#\2define\3'
-ac_uC=' '
-ac_uD='\4%g'
-# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_eB='$%\1#\2define\3'
-ac_eC=' '
-ac_eD='%g'
-
-if test "${CONFIG_HEADERS+set}" != set; then
-EOF
-cat >> $CONFIG_STATUS <<EOF
- CONFIG_HEADERS="config.h"
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-fi
-for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- echo creating $ac_file
-
- rm -f conftest.frag conftest.in conftest.out
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- cat $ac_file_inputs > conftest.in
-
-EOF
-
-# Transform confdefs.h into a sed script conftest.vals that substitutes
-# the proper values into config.h.in to produce config.h. And first:
-# Protect against being on the right side of a sed subst in config.status.
-# Protect against being in an unquoted here document in config.status.
-rm -f conftest.vals
-cat > conftest.hdr <<\EOF
-s/[\\&%]/\\&/g
-s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
-s%ac_d%ac_u%gp
-s%ac_u%ac_e%gp
-EOF
-sed -n -f conftest.hdr confdefs.h > conftest.vals
-rm -f conftest.hdr
-
-# This sed command replaces #undef with comments. This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-cat >> conftest.vals <<\EOF
-s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
-EOF
-
-# Break up conftest.vals because some shells have a limit on
-# the size of here documents, and old seds have small limits too.
-
-rm -f conftest.tail
-while :
-do
- ac_lines=`grep -c . conftest.vals`
- # grep -c gives empty output for an empty file on some AIX systems.
- if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
- # Write a limited-size here document to conftest.frag.
- echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
- sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
- echo 'CEOF
- sed -f conftest.frag conftest.in > conftest.out
- rm -f conftest.in
- mv conftest.out conftest.in
-' >> $CONFIG_STATUS
- sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
- rm -f conftest.vals
- mv conftest.tail conftest.vals
-done
-rm -f conftest.vals
-
-cat >> $CONFIG_STATUS <<\EOF
- rm -f conftest.frag conftest.h
- echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
- cat conftest.in >> conftest.h
- rm -f conftest.in
- if cmp -s $ac_file conftest.h 2>/dev/null; then
- echo "$ac_file is unchanged"
- rm -f conftest.h
- else
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- fi
- rm -f $ac_file
- mv conftest.h $ac_file
- fi
-fi; done
-
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-ac_sources="$targets"
-ac_dests="$links"
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-srcdir=$ac_given_srcdir
-while test -n "$ac_sources"; do
- set $ac_dests; ac_dest=$1; shift; ac_dests=$*
- set $ac_sources; ac_source=$1; shift; ac_sources=$*
-
- echo "linking $srcdir/$ac_source to $ac_dest"
-
- if test ! -r $srcdir/$ac_source; then
- { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; }
- fi
- rm -f $ac_dest
-
- # Make relative symlinks.
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then
- # The dest file is in a subdirectory.
- test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir"
- ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dest_dir_suffix.
- ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dest_dir_suffix= ac_dots=
- fi
-
- case "$srcdir" in
- [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
- *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
- esac
-
- # Make a symlink if possible; otherwise try a hard link.
- if ln -s $ac_rel_source $ac_dest 2>/dev/null ||
- ln $srcdir/$ac_source $ac_dest; then :
- else
- { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
- fi
-done
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-
-exit 0
-EOF
-chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
diff --git a/mit-pthreads/config/configure.in b/mit-pthreads/config/configure.in
deleted file mode 100755
index 45cf0c74809..00000000000
--- a/mit-pthreads/config/configure.in
+++ /dev/null
@@ -1,745 +0,0 @@
-dnl Some reminders:
-dnl "dnl" is a "delete to newline" command for m4 - the remainder of the
-dnl line it's on, including the newline, will be discarded
-dnl "#" comments will usually be copied through
-dnl "[]" are quoting characters; use changequote around code that really
-dnl needs to use them, but try not to invoke autoconf macros
-dnl within such code
-dnl
-dnl When you change this file, re-run "autoreconf" -- that'll automatically
-dnl re-run both autoconf and autoheader.
-dnl
-dnl
-dnl To do:
-dnl CLOCKS_PER_SEC (default 100, Ultrix differs)
-dnl CLK_TCK (default 100, Ultrix differs)
-dnl clockid_t (not on all systems)
-dnl timer_t (not on all systems)
-dnl
-dnl
-dnl Now, the real stuff.
-dnl
-dnl This must be first.
-AC_INIT(config.flags.in)
-dnl
-dnl This file does require autoconf 2.0 or better...
-dnl
-AC_PREREQ(2.0)dnl
-dnl
-dnl Hook for the "--enable-dce-compat" option, when Chris actually
-dnl implements it.
-dnl
-AC_ARG_ENABLE(dce-compat,
- --enable-dce-compat DCE compatibility,
-[dnl "true" action
- AC_MSG_ERROR([Actually, DCE compatibility doesn't work yet...])
-],
-[dnl "false" action
- true
-])
-
-dnl What C compiler?
-AC_PROG_CC
-AC_PROG_CXX
-dnl Apparently autoconf doesn't test to see if the C compiler it locates
-dnl actually works... oops!
-AC_MSG_CHECKING(compiler availability and simple error detection)
-AC_TRY_COMPILE(,[ exit(0); ],[
- dnl true
- AC_TRY_COMPILE(,[ syntax errors galore! ],
- dnl true
- AC_MSG_ERROR(Can't detect syntax errors! Is CC set right?),
- dnl false
- true)],
- dnl false
- AC_MSG_ERROR(Can't compile test program! Is CC set right?))
-
-AC_TRY_COMPILE(,[
- typedef int Integer;
- extern int i;
- extern Integer i;
-], , AC_MSG_ERROR(Can't redeclare variables with this compiler??))
-AC_TRY_COMPILE(,[
- typedef long Long;
- extern int i;
- extern Long i;
-], AC_MSG_ERROR(Compiler doesn't detect conflicting declarations.))
-AC_MSG_RESULT(ok)
-
-if test $ac_cv_prog_gcc = yes ; then
- CFLAGS="$CFLAGS -Werror"
-fi
-
-AC_PROG_CPP
-
-AC_PROG_RANLIB
-
-dnl Default value of prefix should be /usr/local/pthreads, not /usr/local.
-AC_PREFIX_DEFAULT(/usr/local/pthreads)
-
-dnl Determine $host, by guessing if necessary.
-AC_CANONICAL_SYSTEM
-
-syscall=NONE
-sysincludes=NONE
-extraincludes=NONE
-
-# Treat all x86 machines the same.
-# (Yet below, we pretend we can distinguish between the MIPS r2000 and r4000?)
-# (What about 680x0 machines?)
-changequote(,)dnl
-case $host in
- i[456]86-*)
- host=`echo $host | sed 's/^i[456]86/i386/'`
- host_cpu=i386
- ;;
-esac
-changequote([,])dnl
-
-# Here, you should set the following variables:
-# name
-# The "name" of this configuration. Used for "engine-*.c" file name,
-# default for syscall file names. Chris seems to have a thing for
-# putting "-" between OS and version number, but the configure script
-# will already have $host_cpu and $host_os available for you to use
-# in constructing a name.
-# sysincludes
-# Name of machdep directory with "sys" include file
-# replacements, if any. This directory is optional;
-# if you don't provide it, don't set this variable.
-# except
-# Names of any syscalls that shouldn't be generated
-# from the template, if any.
-# syscall
-# Base name of the syscall template files, if not the
-# same as <name>. If they're the same, omit this.
-#
-# Also, you may define random symbols and update CFLAGS if
-# necessary. However, for ease of porting to new machines,
-# it's best if you can create portable autoconf tests for
-# whatever you're trying to do, rather than hard-coding it
-# here based on the OS name. So please, try to keep this
-# section as minimal as possible.
-
-except=""
-name=$host_cpu-$host_os
-
-case $host in
-changequote(,)dnl
- alpha-*-netbsd1.3[H-Z]|alpha-*-netbsd1.[45]*)
- name=alpha-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
-changequote([,])dnl
- alpha-*-netbsd1.3*)
- name=alpha-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask fstat"
- ;;
- alpha-*-netbsd1.1* | alpha-*-netbsd1.2*)
- name=alpha-netbsd-1.1
- sysincludes=netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask"
- ;;
- alpha-*-osf*)
- name=alpha-osf1
- sysincludes=alpha-osf1
- except="fork sigsuspend"
- if test $ac_cv_prog_gcc = no ; then
- CFLAGS="$CFLAGS -std"
- fi
- ;;
-changequote(,)dnl
- arm32-*-netbsd1.3[H-Z]|arm32-*-netbsd1.[45]*)
- name=arm32-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork pipe lseek ftruncate fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
-changequote([,])dnl
- arm32-*-netbsd1.3*)
- name=arm32-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork pipe lseek ftruncate sigsuspend sigprocmask fstat"
- ;;
- hppa1.0-*-hpux10.20 | hppa1.1-*-hpux10.20)
- name=hppa-hpux-10.20
- sysincludes=hpux-10.20
- except="fork"
- ;;
- hppa1.1-*-hpux*9.*)
- name=hppa-hpux-9.03
- sysincludes=hpux-9.03
- # hpux-9.03.mk seems to be missing; what should this be?
- except="fork"
- ;;
- powerpc-*-netbsd1.*)
- name=powerpc-netbsd
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe fstat"
- available_syscalls="sigprocmask sigaction sigsuspend"
- ;;
- sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
- name=sparc-sunos-4.1.3
- sysincludes=sunos-4.1.3
- syscall=sparc-sunos4
- except="fork pipe getpgrp getdirentries"
- AC_DEFINE(sunos4) # is this really needed??
- ;;
- sparc-*-solaris2.3* | sparc-*-solaris2.4*)
- name=sparc-sunos-5.3
- sysincludes=sunos-5.3
- except="fork sigaction"
- # Should really come up with a test for this...
- AC_DEFINE(LD_LINKS_STATIC_DATA)
- AC_DEFINE(BROKEN_SIGNALS)
- ;;
- sparc-*-solaris2*)
- name=sparc-sunos-5.3
- sysincludes=sunos-5.5
- except="fork sigaction"
- # Should really come up with a test for this...
- AC_DEFINE(LD_LINKS_STATIC_DATA)
- AC_DEFINE(BROKEN_SIGNALS)
- ;;
-changequote(,)dnl
- sparc-*-netbsd1.3[H-Z]|sparc-*-netbsd1.[45]*)
- name=sparc-netbsd-1.3
- sysincludes=netbsd-1.1
- except="pipe fork lseek ftruncate fstat"
- available_syscalls="sigprocmask sigsuspend"
- ;;
-changequote([,])dnl
- sparc-*-netbsd1.3*)
- name=sparc-netbsd-1.3
- sysincludes=netbsd-1.1
- except="pipe fork lseek ftruncate sigprocmask sigsuspend fstat"
- ;;
- sparc-*-netbsd1.0A | sparc-*-netbsd1.1* | sparc-*-netbsd1.2*)
- name=sparc-sunos-4.1.3
- sysincludes=netbsd-1.0
- syscall=sparc-netbsd-1.1
- except="pipe fork sigprocmask sigsuspend"
- ;;
- i386-*-openbsd2.*)
- name=i386-openbsd-2.0
- sysincludes=openbsd-2.0
- except="fork lseek ftruncate sigsuspend sigprocmask"
- ;;
- i386-*-linux*)
- #name=i386-linux-1.0
- #sysincludes=linux-1.0
- name=i386-linux-2.0
- sysincludes=linux-2.0
- extraincludes="bits"
- ;;
- i386-*-bsdi1.1)
- name=i386-bsdi-1.1
- sysincludes=bsdi-1.1
- ;;
- i386-*-bsdi2.0* | i386-*-bsdi2.1*)
- name=i386-bsdi-2.0
- sysincludes=bsdi-2.0
- syscall=i386-bsdi-2.0
- except="fork lseek ftruncate sigsuspend"
- ;;
-changequote(,)dnl
- i386-*-netbsd1.3[H-Z]|i386-*-netbsd1.[45]*)
- name=i386-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
-changequote([,])dnl
- i386-*-netbsd1.3*)
- name=i386-netbsd-1.3
- sysincludes=netbsd-1.1
- except="fork lseek ftruncate pipe sigsuspend sigprocmask fstat"
- ;;
- i386-*-netbsd1.1* | i386-*-netbsd1.2*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.1
- syscall=i386-netbsd-1.1
- except="fork lseek ftruncate pipe sigsuspend sigprocmask"
- ;;
- i386-*-netbsd1.0*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.0
- except="fork lseek ftruncate sigsuspend"
- ;;
- i386-*-netbsd0.9*)
- name=i386-netbsd-0.9
- sysincludes=netbsd-0.9
- ;;
- m68*-*-netbsd*)
- name=m68000-netbsd
- sysincludes=netbsd-1.1
- except="lseek ftruncate pipe fstat"
- available_syscalls="sigsuspend sigprocmask"
- ;;
- i386-*-freebsd*)
- name=i386-freebsd-2.0
- sysincludes=freebsd-2.0
- except="fork lseek ftruncate sigsuspend sigprocmask"
- ;;
- romp-*-bsd*)
- name=romp-bsd
- ;;
- mips-dec-ultrix*)
- name=r2000-ultrix-4.2
- sysincludes=ultrix-4.2
- except="fork pipe"
- ;;
- mips-sgi-irix*)
- name=ip22-irix-5.2
- sysincludes=irix-5.2
- except="fstat stat"
- AC_DEFINE(BROKEN_SIGNALS)
- ;;
- i386-*-sco3.2v5*)
- name=i386-sco3.2.5
- sysincludes=i386-sco3.2.5
- syscall=i386-sco3.2.5
- except="select socketcall accept bind connect getpeername getsockname getsockopt setsockopt listen recv recvfrom recvmsg send sendmsg sendto shutdown socket socketpair fork fcntl dup2 fstat fchmod fchown ftruncate pipe getdirentries sigaction sigpause wait3 waitpid getdtablesize"
- ;;
- *)
- AC_MSG_ERROR(System type $host not recognized or not supported.
-See $srcdir/configure.in for supported systems.)
- exit 1
- ;;
-esac
-
-SYSCALL_EXCEPTIONS=$except
-AC_SUBST(SYSCALL_EXCEPTIONS)
-
-AC_CHECK_HEADERS(sys/termio.h termios.h termio.h alloc.h)
-
-dnl Don't use AC_CHECK_HEADERS for this one, we want to define a special
-dnl symbol name starting with pthread_ if it's found.
-AC_CHECK_HEADER(va_list.h, AC_DEFINE(pthread_have_va_list_h))
-
-dnl Generate a list of system calls that we could generate. We later use
-dnl a syscall template .S file to produce a .o file for each syscall. This
-dnl is a bit better for porting and development purposes than having every
-dnl syscall listed for every target system; this way we only need the
-dnl template, and special hanlding for only those syscalls that can't be
-dnl handled by the templates.
-AC_CHECK_HEADERS(syscall.h sys/syscall.h sys/filio.h)
-
-PTHREADS_CHECK_SYSCALLS(open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
- rename select getdtablesize ioctl ftruncate flock fstatfs chroot uname
- dnl - signals
- sigsuspend sigaction sigpause sigprocmask ksigaction
- dnl - directory reading
- getdents readdir getdirentries
- dnl - variants of `wait' syscalls
- wait4 wait3 waitpid waitsys
- dnl - BSD socket calls
- socket bind connect accept listen getsockopt setsockopt socketpair
- dnl - SYSV stream calls
- poll putmsg getmsg
- dnl - Linux version uses one syscall
- socketcall
-
- dnl - Process info
- pgrpsys
-
- exit
- readv writev send sendto sendmsg recv recvfrom recvmsg
- getpeername getsockname
- shutdown
- getpgrp fork)
-
-AC_SUBST(available_syscalls)
-AC_SUBST(missing_syscalls)
-
-dnl Disabled for now -- generates warnings from autoconf.
-dnl ## Check some type sizes.
-dnl AC_CHECK_SIZEOF(int)
-dnl AC_CHECK_SIZEOF(long)
-dnl AC_CHECK_SIZEOF(char *)
-
-## Determine some typedef values from the system header files.
-dnl
-dnl Autoconf provides these automatically. They provide reasonable
-dnl fallbacks if the standard header files don't define the typedef names.
-dnl
-dnl AC_TYPE_MODE_T
-AC_TYPE_OFF_T
-dnl AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-dnl AC_TYPE_UID_T
-AC_TYPE_SIGNAL
-dnl
-dnl Default these types if their definitions can't be found.
-dnl
-AC_CHECK_TYPE(ssize_t,int)
-AC_CHECK_TYPE(time_t,long)
-dnl
-AC_CHECK_HEADERS(sys/time.h)
-AC_HEADER_TIME
-
-dnl
-dnl Check for the existence of these types
-dnl
-dnl struct timespec
-dnl
-AC_MSG_CHECKING(for struct timespec in sys/time.h)
-AC_CACHE_VAL(pthreads_cv_timespec_in_time,
- AC_TRY_COMPILE([#include <sys/time.h>], [struct timespec foo;],
- pthreads_cv_timespec_in_time=yes, pthreads_cv_timespec_in_time=no))
-AC_MSG_RESULT($pthreads_cv_timespec_in_time)
-if test $pthreads_cv_timespec_in_time = yes ; then
- AC_DEFINE(_OS_HAS_TIMESPEC)
-fi
-
-dnl socklen_t
-AC_CACHE_VAL(pthreads_cv_socklen_t,
- AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/socket.h>], [socklen_t foo;],
- pthreads_cv_socklen_t=yes, pthreads_cv_socklen_t=no))
-AC_MSG_RESULT($pthreads_cv_socklen_t)
-if test $pthreads_cv_socklen_t = yes ; then
- AC_DEFINE(_OS_HAS_SOCKLEN_T)
-fi
-
-
-dnl
-dnl Usage: PTHREADS_FIND_TYPE(system-typedef-name, new-macro-name,
-dnl list-of-includes-in-square-brackets,
-dnl comma-separated-list-of-types-to-try)
-dnl
-dnl PTHREADS_FIND_INTEGRAL_TYPE automatically provides a set of integral
-dnl types, and does not permit specification of additional types.
-dnl
-dnl The specified types must all be able to work as prefixes -- i.e., no
-dnl direct specification of array or function types. If you need such
-dnl types, add typedefs for them to include/pthread/xtypes.h, and include
-dnl that in the set of header files. For simple struct types, you can
-dnl try including the definition directly here, but it had better not
-dnl contain any commas or square brackets.
-dnl
-dnl If necessary, you can include other preprocessing commands and such
-dnl in the `includes' portion.
-dnl
-dnl Note: For now, each of these needs a corresponding entry
-dnl in acconfig.h.
-dnl
-dnl size_t
-dnl
-PTHREADS_FIND_INTEGRAL_TYPE(size_t, pthread_size_t, [
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-])
-dnl
-dnl ssize_t
-dnl
-PTHREADS_FIND_INTEGRAL_TYPE(ssize_t, pthread_ssize_t, [
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-])
-dnl
-dnl clock_t ---FIXME I don't know if this is the right set of header files. KR
-dnl
-PTHREADS_FIND_INTEGRAL_TYPE(clock_t, pthread_clock_t, [
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-])
-dnl
-dnl time_t
-dnl
-PTHREADS_FIND_INTEGRAL_TYPE(time_t, pthread_time_t, [
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-])
-dnl
-dnl fpos_t
-dnl
-dnl If fpos_t isn't defined in stdio.h, define it to be off_t. It
-dnl looks like AC_CHECK_TYPE won't work for this, because it doesn't
-dnl include stdio.h.
-dnl
-AC_MSG_CHECKING(for fpos_t in stdio.h)
-AC_CACHE_VAL(pthreads_cv_fpos_t_in_stdio,
- AC_TRY_COMPILE([#include <stdio.h>], [fpos_t position;],
- pthreads_cv_fpos_t_in_stdio=yes, pthreads_cv_fpos_t_in_stdio=no))
-AC_MSG_RESULT($pthreads_cv_fpos_t_in_stdio)
-if test $pthreads_cv_fpos_t_in_stdio = yes ; then
- PTHREADS_FIND_INTEGRAL_TYPE(fpos_t, pthread_fpos_t, [
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-])
-else
- AC_DEFINE(fpos_t,off_t)
- AC_DEFINE(pthread_fpos_t,pthread_off_t)
-fi
-dnl
-dnl off_t
-dnl
-PTHREADS_FIND_INTEGRAL_TYPE(off_t, pthread_off_t, [
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-])
-dnl
-dnl va_list -- This one could be tricky. Fortunately, on some systems,
-dnl we can just include the gcc stdarg.h header file if we can't determine
-dnl the type here. Won't work for non-gcc configurations though.
-dnl
-PTHREADS_FIND_TYPE(va_list, pthread_va_list, [#include <stdarg.h>],
- char *, char **, void *, void **, int *, long *)
-dnl
-dnl
-
-arpa_headers="#include <sys/types.h>
-#include <arpa/nameser.h>"
-
-dnl
-dnl Type for network (IP) addresses, 32 bits.
-dnl For now, I'm assuming that the return type from _getlong is it.
-dnl
-AC_MSG_CHECKING(IP address type)
-AC_CACHE_VAL(pthread_cv_type_ipaddr,
- AC_TRY_COMPILE($arpa_headers,[ &_getlong; ],[
- for type in "unsigned long" "unsigned int" ; do
- AC_TRY_COMPILE($arpa_headers, extern $type _getlong ();,[
- pthread_cv_type_ipaddr="$type"
- break
- ])
- done
- ],[ AC_MSG_WARN(Can't compile _getlong reference.) ])
- if test "$pthread_cv_type_ipaddr" = "" ; then
- AC_MSG_WARN(Can't determine _getlong return type.)
- AC_MSG_WARN(Defaulting to unsigned long.)
- pthread_cv_type_ipaddr="unsigned long"
- fi
-)
-AC_MSG_RESULT($pthread_cv_type_ipaddr)
-AC_DEFINE_UNQUOTED(pthread_ipaddr_type,$pthread_cv_type_ipaddr)
-
-dnl
-dnl Type for network (IP) ports, 16 bits.
-dnl For now, I'm assuming that the return type from _getshort is it.
-dnl
-AC_MSG_CHECKING(IP port type)
-AC_CACHE_VAL(pthread_cv_type_ipport,
- AC_TRY_COMPILE($arpa_headers,[ &_getshort; ],[
- for type in "unsigned short" "unsigned int" ; do
- AC_TRY_COMPILE($arpa_headers, extern $type _getshort ();,[
- pthread_cv_type_ipport="$type"
- break
- ])
- done
- ],[ AC_MSG_WARN(Can't compile _getshort reference.) ])
- if test "$pthread_cv_type_ipport" = "" ; then
- AC_MSG_WARN(Can't determine _getshort return type.)
- AC_MSG_WARN(Defaulting to unsigned short.)
- pthread_cv_type_ipport="unsigned short"
- fi
-)
-AC_MSG_RESULT($pthread_cv_type_ipport)
-AC_DEFINE_UNQUOTED(pthread_ipport_type,$pthread_cv_type_ipport)
-
-dnl
-dnl Guess where terminal devices are stored. This is for use in the
-dnl ttyname() implementation provided here.
-dnl
-AC_MSG_CHECKING(pathname for terminal devices directory)
-AC_CACHE_VAL(pthread_cv_pty_path,
- if test -d /devices/pseudo ; then
- pty_path=/devices/pseudo/
- else
- pty_path=/dev/
- fi
- pthread_cv_pty_path=$pty_path
-)
-AC_DEFINE_UNQUOTED(_PATH_PTY,"$pthread_cv_pty_path")
-AC_MSG_RESULT($pthread_cv_pty_path)
-
-dnl
-dnl Look for timezone info, for use in ctime.
-dnl
-AC_MSG_CHECKING(directory name for time zone info)
-tzdir=NONE
-for f in /usr/lib/zoneinfo /usr/share/zoneinfo /usr/share/lib/zoneinfo /etc/zoneinfo /usr/local/lib/zoneinfo
-do
- if test -d $f ; then
- tzdir=$f
- break
- fi
-done
-case $tzdir in
-NONE)
- AC_MSG_WARN(Can't find zoneinfo directory.)
- AC_MSG_WARN(Defaulting zoneinfo directory to NULL.)
- tzdir=NULL
- ;;
-esac
-AC_DEFINE_UNQUOTED(_PATH_TZDIR,"$tzdir")
-AC_MSG_RESULT($tzdir)
-
-AC_MSG_CHECKING(filename for local time zone)
-tzfile=NONE
-for f in $tzdir/localtime /etc/localtime
-do
- if test -f $f ; then
- tzfile=$f
- break
- fi
-done
-case $tzfile in
-NONE) # Should this default to tzdir/localtime?
- AC_MSG_WARN(Can't find local time zone file.)
- if test tzdir = NULL ; then
- AC_MSG_WARN(Defaulting local time zone file to NULL)
- tzfile=NULL
- else
- AC_MSG_WARN(Defaulting local time zone file to $tzdir/localtime.)
- tzfile=$tzdir/localtime
- fi
- ;;
-esac
-AC_DEFINE_UNQUOTED(_PATH_TZFILE,"$tzfile")
-AC_MSG_RESULT($tzfile)
-
-dnl
-dnl Network stuff. At the moment, I don't think there are any other
-dnl values we should expect. If we find a system that does store these
-dnl files elsewhere -- or doesn't have them all -- then run some tests.
-dnl
-AC_DEFINE(_PATH_RESCONF, "/etc/resolv.conf")
-AC_DEFINE(_PATH_HOSTS, "/etc/hosts")
-AC_DEFINE(_PATH_NETWORKS, "/etc/networks")
-AC_DEFINE(_PATH_PROTOCOLS, "/etc/protocols")
-AC_DEFINE(_PATH_SERVICES, "/etc/services")
-
-dnl
-dnl Other stuff
-dnl
-AC_DEFINE(_PATH_BSHELL, "/bin/sh")
-
-dnl If the system provides vfork, autoconf scripts will detect it.
-dnl So we should hide it.
-AC_CHECK_FUNCS(vfork)
-
-srctop=`cd ${srcdir}/..;pwd`
-AC_SUBST(srctop)
-
-# Now we deal with symlinks &c.
-
-test -d include || mkdir include || \
- AC_MSG_ERROR(Can't create include directory.)
-
-test -d include/pthread || mkdir include/pthread || \
- AC_MSG_ERROR(Can't create include/pthread directory.)
-
-test -d lib || mkdir lib || \
- AC_MSG_ERROR(Can't create lib directory.)
-
-test -d lib/libpthreadutil || mkdir lib/libpthreadutil || \
- AC_MSG_ERROR(Can't create lib/libpthreadutil directory.)
-
-test -d bin || mkdir bin || \
- AC_MSG_ERROR(Can't create bin directory.)
-
-test -d bin/finger || mkdir bin/finger || \
- AC_MSG_ERROR(Can't create bin directory.)
-
-test -d tests || mkdir tests || \
- AC_MSG_ERROR(Can't create tests directory.)
-
-if test x$syscall = xNONE ; then
- syscall=$name
-fi
-
-links="include/pthread/machdep.h include/pthread/posix.h \
- machdep.c syscall.S"
-targets="../machdep/engine-$name.h ../machdep/posix-$sysincludes.h \
- ../machdep/engine-$name.c ../machdep/syscall-$syscall.S"
-
-# Both these targets are optional. (Autoconf-generated configure scripts
-# will require the existence of link targets, so check before adding them
-# to the list.)
-if test x$sysincludes != xNONE ; then
- links="$links include/sys"
- targets="$targets ../machdep/$sysincludes"
-fi
-
-if test x$extraincludes != xNONE ; then
- for tmp in $extraincludes
- do
- links="$links include/$tmp"
- targets="$targets ../machdep/$sysincludes/extra/$tmp"
- done
-fi
-
-syscall_file=../machdep/syscall-template-$syscall.S
-if test -r $srcdir/$syscall_file ; then
- links="$links syscall-template.S"
- targets="$targets $syscall_file"
- HAVE_SYSCALL_TEMPLATE=yes
-else
- # This really isn't a fatal problem. In fact, it's expected, initially,
- # for some targets. This is just to persuade people to fix the targets
- # they deal with to provide some sort of template.
- #
- # Eventually this file probably will be required...
- AC_MSG_WARN(No syscall template file syscall-template-$syscall.S found.)
- HAVE_SYSCALL_TEMPLATE=no
-fi
-AC_SUBST(HAVE_SYSCALL_TEMPLATE)
-
-dnl Now tell it to make the links.
-dnl (The links are actually made by config.status.)
-AC_LINK_FILES($targets, $links)
-
-if test x$makefile_frag != x ; then
- makefile_frag=${srcdir}/$makefile_frag
-else
- makefile_frag=/dev/null
-fi
-dnl Drop in file indicated by $makefile_frag on *the line after* the
-dnl magic @makefile_frag@ sequence.
-AC_SUBST_FILE(makefile_frag)
-
-
-dnl Generate output files...
-AC_CONFIG_HEADER(config.h)
-
-dnl This must be last.
-AC_OUTPUT(config.flags GNUmakefile Makefile \
- lib/Makefile:../lib/Makefile.in \
- lib/libpthreadutil/Makefile:../lib/libpthreadutil/Makefile.in \
- bin/Makefile:../bin/Makefile.in \
- bin/finger/Makefile:../bin/finger/Makefile.in \
- tests/Makefile:../tests/Makefile.in)
diff --git a/mit-pthreads/config/configure.org b/mit-pthreads/config/configure.org
deleted file mode 100755
index f8526844a24..00000000000
--- a/mit-pthreads/config/configure.org
+++ /dev/null
@@ -1,2874 +0,0 @@
-#! /bin/sh
-
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.10
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-
-# Defaults:
-ac_help=
-ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
---enable-dce-compat DCE compatibility"
-ac_default_prefix=/usr/local/pthreads
-
-# Initialize some variables set by options.
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
-exec_prefix=NONE
-host=NONE
-no_create=
-nonopt=NONE
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-target=NONE
-verbose=
-x_includes=NONE
-x_libraries=NONE
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-
-ac_prev=
-for ac_option
-do
-
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
- ac_prev=
- continue
- fi
-
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case "$ac_option" in
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file="$ac_optarg" ;;
-
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
- datadir="$ac_optarg" ;;
-
- -disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
-
- -enable-* | --enable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "enable_${ac_feature}='$ac_optarg'" ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he)
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir="$ac_optarg" ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir="$ac_optarg" ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix="$ac_optarg" ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix="$ac_optarg" ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir="$ac_optarg" ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.10"
- exit 0 ;;
-
- -with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "with_${ac_package}='$ac_optarg'" ;;
-
- -without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes="$ac_optarg" ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries="$ac_optarg" ;;
-
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
- ;;
-
- *)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
-fi
-exec 5>./config.log
-
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
- esac
-done
-
-# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
-
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=config.flags.in
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then its parent.
- ac_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
- srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
- if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
- else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
- fi
-fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
- if test "x$prefix" != xNONE; then
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
-fi
-for ac_site_file in $CONFIG_SITE; do
- if test -r "$ac_site_file"; then
- echo "loading site script $ac_site_file"
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- echo "loading cache $cache_file"
- . $cache_file
-else
- echo "creating cache $cache_file"
- > $cache_file
-fi
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
- ac_n= ac_c='
-' ac_t=' '
- else
- ac_n=-n ac_c= ac_t=
- fi
-else
- ac_n= ac_c='\c' ac_t=
-fi
-
-
-# Check whether --enable-dce-compat or --disable-dce-compat was given.
-if test "${enable_dce_compat+set}" = set; then
- enableval="$enable_dce_compat"
- { echo "configure: error: Actually, DCE compatibility doesn't work yet..." 1>&2; exit 1; }
-
-else
- true
-
-fi
-
-
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="gcc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- ac_prog_rejected=no
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# -gt 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- set dummy "$ac_dir/$ac_word" "$@"
- shift
- ac_cv_prog_CC="$@"
- fi
-fi
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:616: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
-else
- ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
- if test "${CFLAGS+set}" != set; then
- echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_gcc_g=yes
-else
- ac_cv_prog_gcc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
- if test $ac_cv_prog_gcc_g = yes; then
- CFLAGS="-g -O"
- else
- CFLAGS="-O"
- fi
- fi
-else
- GCC=
- test "${CFLAGS+set}" = set || CFLAGS="-g"
-fi
-
-for ac_prog in $CCC c++ g++ gcc CC cxx
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CXX="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CXX="$ac_cv_prog_CXX"
-if test -n "$CXX"; then
- echo "$ac_t""$CXX" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-test -n "$CXX" && break
-done
-test -n "$CXX" || CXX="gcc"
-
-
-echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.C <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:696: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gxx=yes
-else
- ac_cv_prog_gxx=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gxx" 1>&6
-if test $ac_cv_prog_gxx = yes; then
- GXX=yes
- if test "${CXXFLAGS+set}" != set; then
- echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gxx_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.cc
-if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
- ac_cv_prog_gxx_g=yes
-else
- ac_cv_prog_gxx_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_gxx_g" 1>&6
- if test $ac_cv_prog_gxx_g = yes; then
- CXXFLAGS="-g -O"
- else
- CXXFLAGS="-O"
- fi
- fi
-else
- GXX=
- test "${CXXFLAGS+set}" = set || CXXFLAGS="-g"
-fi
-
-echo $ac_n "checking compiler availability and simple error detection""... $ac_c" 1>&6
-cat > conftest.$ac_ext <<EOF
-#line 735 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
- exit(0);
-; return 0; }
-EOF
-if { (eval echo configure:743: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- cat > conftest.$ac_ext <<EOF
-#line 747 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
- syntax errors galore!
-; return 0; }
-EOF
-if { (eval echo configure:755: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- { echo "configure: error: Can't detect syntax errors! Is CC set right?" 1>&2; exit 1; }
-else
- rm -rf conftest*
- true
-fi
-rm -f conftest*
-
-else
- rm -rf conftest*
- { echo "configure: error: Can't compile test program! Is CC set right?" 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-
-cat > conftest.$ac_ext <<EOF
-#line 772 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-
- typedef int Integer;
- extern int i;
- extern Integer i;
-
-; return 0; }
-EOF
-if { (eval echo configure:784: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- :
-else
- rm -rf conftest*
- { echo "configure: error: Can't redeclare variables with this compiler??" 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-cat > conftest.$ac_ext <<EOF
-#line 793 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-
- typedef long Long;
- extern int i;
- extern Long i;
-
-; return 0; }
-EOF
-if { (eval echo configure:805: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- { echo "configure: error: Compiler doesn't detect conflicting declarations." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-echo "$ac_t""ok" 1>&6
-
-if test $ac_cv_prog_gcc = yes ; then
- CFLAGS="$CFLAGS -Werror"
-fi
-
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 832 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:838: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 847 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:853: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- CPP=/lib/cpp
-fi
-rm -f conftest*
-fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
-fi
- CPP="$ac_cv_prog_CPP"
-else
- ac_cv_prog_CPP="$CPP"
-fi
-echo "$ac_t""$CPP" 1>&6
-
-
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_RANLIB="ranlib"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
- echo "$ac_t""$RANLIB" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-
-# Do some error checking and defaulting for the host and target type.
-# The inputs are:
-# configure --host=HOST --target=TARGET --build=BUILD NONOPT
-#
-# The rules are:
-# 1. You are not allowed to specify --host, --target, and nonopt at the
-# same time.
-# 2. Host defaults to nonopt.
-# 3. If nonopt is not specified, then host defaults to the current host,
-# as determined by config.guess.
-# 4. Target and build default to nonopt.
-# 5. If nonopt is not specified, then target and build default to host.
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-case $host---$target---$nonopt in
-NONE---*---* | *---NONE---* | *---*---NONE) ;;
-*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
-esac
-
-
-# Make sure we can run config.sub.
-if $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-
-host_alias=$host
-case "$host_alias" in
-NONE)
- case $nonopt in
- NONE)
- if host_alias=`$ac_config_guess`; then :
- else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
- fi ;;
- *) host_alias=$nonopt ;;
- esac ;;
-esac
-
-host=`$ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
-
-echo $ac_n "checking target system type""... $ac_c" 1>&6
-
-target_alias=$target
-case "$target_alias" in
-NONE)
- case $nonopt in
- NONE) target_alias=$host_alias ;;
- *) target_alias=$nonopt ;;
- esac ;;
-esac
-
-target=`$ac_config_sub $target_alias`
-target_cpu=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-target_vendor=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-target_os=`echo $target | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$target" 1>&6
-
-echo $ac_n "checking build system type""... $ac_c" 1>&6
-
-build_alias=$build
-case "$build_alias" in
-NONE)
- case $nonopt in
- NONE) build_alias=$host_alias ;;
- *) build_alias=$nonopt ;;
- esac ;;
-esac
-
-build=`$ac_config_sub $build_alias`
-build_cpu=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-build_vendor=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-build_os=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$build" 1>&6
-
-test "$host_alias" != "$target_alias" &&
- test "$program_prefix$program_suffix$program_transform_name" = \
- NONENONEs,x,x, &&
- program_prefix=${target_alias}-
-
-
-syscall=NONE
-sysincludes=NONE
-
-# Treat all x86 machines the same.
-# (Yet below, we pretend we can distinguish between the MIPS r2000 and r4000?)
-# (What about 680x0 machines?)
-case $host in
- i[456]86-*)
- host=`echo $host | sed 's/^i[456]86/i386/'`
- host_cpu=i386
- ;;
-esac
-
-# Here, you should set the following variables:
-# name
-# The "name" of this configuration. Used for "engine-*.c" file name,
-# default for syscall file names. Chris seems to have a thing for
-# putting "-" between OS and version number, but the configure script
-# will already have $host_cpu and $host_os available for you to use
-# in constructing a name.
-# sysincludes
-# Name of machdep directory with "sys" include file
-# replacements, if any. This directory is optional;
-# if you don't provide it, don't set this variable.
-# except
-# Names of any syscalls that shouldn't be generated
-# from the template, if any.
-# syscall
-# Base name of the syscall template files, if not the
-# same as <name>. If they're the same, omit this.
-#
-# Also, you may define random symbols and update CFLAGS if
-# necessary. However, for ease of porting to new machines,
-# it's best if you can create portable autoconf tests for
-# whatever you're trying to do, rather than hard-coding it
-# here based on the OS name. So please, try to keep this
-# section as minimal as possible.
-
-except=""
-name=$host_cpu-$host_os
-
-case $host in
- alpha-*-netbsd1.1* | alpha-*-netbsd1.2*)
- name=alpha-netbsd-1.1
- sysincludes=netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask"
- ;;
- alpha-*-osf*)
- name=alpha-osf1
- sysincludes=alpha-osf1
- except="fork sigsuspend"
- if test $ac_cv_prog_gcc = no ; then
- CFLAGS="$CFLAGS -std"
- fi
- ;;
- hppa1.1-*-hpux*)
- name=hppa-hpux-9.03
- sysincludes=hpux-9.03
- # hpux-9.03.mk seems to be missing; what should this be?
- except="fork"
- ;;
- sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
- name=sparc-sunos-4.1.3
- sysincludes=sunos-4.1.3
- syscall=sparc-sunos4
- except="fork pipe getpgrp getdirentries"
- cat >> confdefs.h <<\EOF
-#define sunos4 1
-EOF
- # is this really needed??
- ;;
- sparc-*-solaris2*)
- name=sparc-sunos-5.3
- sysincludes=sunos-5.3
- except="fork sigaction"
- # Should really come up with a test for this...
- cat >> confdefs.h <<\EOF
-#define LD_LINKS_STATIC_DATA 1
-EOF
-
- cat >> confdefs.h <<\EOF
-#define BROKEN_SIGNALS 1
-EOF
-
- ;;
- sparc-*-netbsd1.0A | sparc-*-netbsd1.1* | sparc-*-netbsd1.2*)
- name=sparc-sunos-4.1.3
- sysincludes=netbsd-1.0
- syscall=sparc-netbsd-1.1
- except="pipe fork sigprocmask sigsuspend"
- ;;
- i386-*-linux*)
- name=i386-linux-1.0
- sysincludes=linux-1.0
- ;;
- i386-*-bsdi1.1)
- name=i386-bsdi-1.1
- sysincludes=bsdi-1.1
- ;;
- i386-*-bsdi2.0* | i386-*-bsdi2.1*)
- name=i386-bsdi-2.0
- sysincludes=bsdi-2.0
- syscall=i386-bsdi-2.0
- except="fork lseek sigsuspend"
- ;;
- i386-*-netbsd1.1* | i386-*-netbsd1.2*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.1
- syscall=i386-netbsd-1.1
- except="fork lseek pipe sigsuspend sigprocmask"
- ;;
- i386-*-netbsd1.0*)
- name=i386-netbsd-1.0
- sysincludes=netbsd-1.0
- except="fork lseek sigsuspend"
- ;;
- i386-*-netbsd0.9*)
- name=i386-netbsd-0.9
- sysincludes=netbsd-0.9
- ;;
- m68*-*-netbsd*)
- name=m68000-netbsd
- ;;
- i386-*-freebsd2.*)
- name=i386-freebsd-2.0
- sysincludes=freebsd-2.0
- except="fork lseek sigsuspend sigprocmask"
- ;;
- romp-*-bsd*)
- name=romp-bsd
- ;;
- mips-dec-ultrix*)
- name=r2000-ultrix-4.2
- sysincludes=ultrix-4.2
- except="fork pipe"
- ;;
- mips-sgi-irix*)
- name=ip22-irix-5.2
- sysincludes=irix-5.2
- except="fstat stat"
- cat >> confdefs.h <<\EOF
-#define BROKEN_SIGNALS 1
-EOF
-
- ;;
- *)
- { echo "configure: error: System type $host not recognized or not supported.
-See $srcdir/configure.in for supported systems." 1>&2; exit 1; }
- exit 1
- ;;
-esac
-
-SYSCALL_EXCEPTIONS=$except
-
-
-for ac_hdr in sys/termio.h termios.h termio.h
-do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1174 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1179: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-ac_safe=`echo "va_list.h" | tr './\055' '___'`
-echo $ac_n "checking for va_list.h""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1210 "configure"
-#include "confdefs.h"
-#include <va_list.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1215: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define pthread_have_va_list_h 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-for ac_hdr in syscall.h sys/syscall.h
-do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1246 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1251: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-pthreads_syscall_list="open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
- rename select getdtablesize ioctl ftruncate
- sigsuspend sigaction sigpause sigprocmask ksigaction
- getdents readdir getdirentries
- wait4 wait3 waitpid waitsys
- socket bind connect accept listen getsockopt setsockopt socketpair
- poll putmsg getmsg
- socketcall
-
- pgrpsys
-
- exit
- readv writev send sendto sendmsg recv recvfrom recvmsg
- getpeername getsockname
- shutdown
- getpgrp fork"
-for pthreads_syscallname in $pthreads_syscall_list ; do
- echo $ac_n "checking for syscall $pthreads_syscallname""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_syscall_$pthreads_syscallname'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1299 "configure"
-#include "confdefs.h"
-
-/* FIXME: This list should be generated from info in configure.in. */
-#ifdef HAVE_SYSCALL_H
-#include <syscall.h>
-#else
-#ifdef HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
-#else
-where is your syscall header file??
-#endif
-#endif
-
-int main() { return 0; }
-int t() {
-
-int x;
-x = SYS_$pthreads_syscallname ;
-
-; return 0; }
-EOF
-if { (eval echo configure:1321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
- rm -rf conftest*
- eval pthreads_cv_syscall_$pthreads_syscallname=yes
-else
- rm -rf conftest*
- eval pthreads_cv_syscall_$pthreads_syscallname=no
-fi
-rm -f conftest*
-
-fi
-
-if eval test \$pthreads_cv_syscall_$pthreads_syscallname = yes ; then
- pthreads_syscall_present=yes
- available_syscalls="$available_syscalls $pthreads_syscallname"
- macroname=HAVE_SYSCALL_`echo $pthreads_syscallname | tr '[a-z]' '[A-Z]'`
- cat >> confdefs.h <<EOF
-#define $macroname 1
-EOF
-
-else
- pthreads_syscall_present=no
- missing_syscalls="$missing_syscalls $pthreads_syscallname"
-fi
-echo "$ac_t""$pthreads_syscall_present" 1>&6
-
-done
-
-
-
-
-
-
-## Determine some typedef values from the system header files.
-# If we cannot run a trivial program, we must be cross compiling.
-echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_c_cross=yes
-else
-cat > conftest.$ac_ext <<EOF
-#line 1363 "configure"
-#include "confdefs.h"
-main(){return(0);}
-EOF
-{ (eval echo configure:1367: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- ac_cv_c_cross=no
-else
- ac_cv_c_cross=yes
-fi
-fi
-rm -fr conftest*
-fi
-
-echo "$ac_t""$ac_cv_c_cross" 1>&6
-cross_compiling=$ac_cv_c_cross
-
-echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1385 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1393: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- ac_cv_header_stdc=yes
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1408 "configure"
-#include "confdefs.h"
-#include <string.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "memchr" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1426 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "free" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-if test "$cross_compiling" = yes; then
- :
-else
-cat > conftest.$ac_ext <<EOF
-#line 1447 "configure"
-#include "confdefs.h"
-#include <ctype.h>
-#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int main () { int i; for (i = 0; i < 256; i++)
-if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
-exit (0); }
-
-EOF
-{ (eval echo configure:1458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- :
-else
- ac_cv_header_stdc=no
-fi
-fi
-rm -fr conftest*
-fi
-fi
-
-echo "$ac_t""$ac_cv_header_stdc" 1>&6
-if test $ac_cv_header_stdc = yes; then
- cat >> confdefs.h <<\EOF
-#define STDC_HEADERS 1
-EOF
-
-fi
-
-echo $ac_n "checking for off_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1482 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "off_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_off_t=yes
-else
- rm -rf conftest*
- ac_cv_type_off_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_off_t" 1>&6
-if test $ac_cv_type_off_t = no; then
- cat >> confdefs.h <<\EOF
-#define off_t long
-EOF
-
-fi
-
-echo $ac_n "checking for size_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1513 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "size_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_size_t=yes
-else
- rm -rf conftest*
- ac_cv_type_size_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_size_t" 1>&6
-if test $ac_cv_type_size_t = no; then
- cat >> confdefs.h <<\EOF
-#define size_t unsigned
-EOF
-
-fi
-
-echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1544 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "ssize_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_ssize_t=yes
-else
- rm -rf conftest*
- ac_cv_type_ssize_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_ssize_t" 1>&6
-if test $ac_cv_type_ssize_t = no; then
- cat >> confdefs.h <<\EOF
-#define ssize_t int
-EOF
-
-fi
-
-echo $ac_n "checking for time_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_time_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1575 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "time_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_time_t=yes
-else
- rm -rf conftest*
- ac_cv_type_time_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_time_t" 1>&6
-if test $ac_cv_type_time_t = no; then
- cat >> confdefs.h <<\EOF
-#define time_t long
-EOF
-
-fi
-
-for ac_hdr in sys/time.h
-do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1609 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1614: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1643 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-int main() { return 0; }
-int t() {
-struct tm *tp;
-; return 0; }
-EOF
-if { (eval echo configure:1653: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_header_time=yes
-else
- rm -rf conftest*
- ac_cv_header_time=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_header_time" 1>&6
-if test $ac_cv_header_time = yes; then
- cat >> confdefs.h <<\EOF
-#define TIME_WITH_SYS_TIME 1
-EOF
-
-fi
-
-
-echo $ac_n "checking for struct timespec in sys/time.h""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_timespec_in_time'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1678 "configure"
-#include "confdefs.h"
-#include <sys/time.h>
-int main() { return 0; }
-int t() {
-struct timespec foo;
-; return 0; }
-EOF
-if { (eval echo configure:1686: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_timespec_in_time=yes
-else
- rm -rf conftest*
- pthreads_cv_timespec_in_time=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$pthreads_cv_timespec_in_time" 1>&6
-if test $pthreads_cv_timespec_in_time = yes ; then
- cat >> confdefs.h <<\EOF
-#define _OS_HAS_TIMESPEC 1
-EOF
-
-fi
-
-
-
-echo $ac_n "checking type of size_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1712 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern size_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:1726: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 1730 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern size_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:1744: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_size_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for size_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_size_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_size_t $pthreads_cv_type_size_t
-EOF
-
-fi
-pthread_size_t=$pthreads_cv_type_size_t
-echo "$ac_t""$pthreads_cv_type_size_t" 1>&6
-
-echo $ac_n "checking type of ssize_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_ssize_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1773 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int main() { return 0; }
-int t() {
- extern ssize_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:1785: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 1789 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int main() { return 0; }
-int t() {
- extern ssize_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:1801: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_ssize_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for ssize_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_ssize_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_ssize_t $pthreads_cv_type_ssize_t
-EOF
-
-fi
-pthread_ssize_t=$pthreads_cv_type_ssize_t
-echo "$ac_t""$pthreads_cv_type_ssize_t" 1>&6
-
-echo $ac_n "checking type of clock_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_clock_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1830 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() { return 0; }
-int t() {
- extern clock_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:1850: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 1854 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() { return 0; }
-int t() {
- extern clock_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:1874: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_clock_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for clock_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_clock_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_clock_t $pthreads_cv_type_clock_t
-EOF
-
-fi
-pthread_clock_t=$pthreads_cv_type_clock_t
-echo "$ac_t""$pthreads_cv_type_clock_t" 1>&6
-
-echo $ac_n "checking type of time_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_time_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1903 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() { return 0; }
-int t() {
- extern time_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:1923: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 1927 "configure"
-#include "confdefs.h"
-
-#include <stddef.h>
-#if TIME_WITH_SYS_TIME
-# include <time.h>
-# include <sys/time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int main() { return 0; }
-int t() {
- extern time_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:1947: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_time_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for time_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_time_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_time_t $pthreads_cv_type_time_t
-EOF
-
-fi
-pthread_time_t=$pthreads_cv_type_time_t
-echo "$ac_t""$pthreads_cv_type_time_t" 1>&6
-echo $ac_n "checking for fpos_t in stdio.h""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_fpos_t_in_stdio'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1975 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-int main() { return 0; }
-int t() {
-fpos_t position;
-; return 0; }
-EOF
-if { (eval echo configure:1983: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_fpos_t_in_stdio=yes
-else
- rm -rf conftest*
- pthreads_cv_fpos_t_in_stdio=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$pthreads_cv_fpos_t_in_stdio" 1>&6
-if test $pthreads_cv_fpos_t_in_stdio = yes ; then
-
-echo $ac_n "checking type of fpos_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_fpos_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2002 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern fpos_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2016: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2020 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern fpos_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2034: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_fpos_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for fpos_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_fpos_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_fpos_t $pthreads_cv_type_fpos_t
-EOF
-
-fi
-pthread_fpos_t=$pthreads_cv_type_fpos_t
-echo "$ac_t""$pthreads_cv_type_fpos_t" 1>&6
-else
- cat >> confdefs.h <<\EOF
-#define fpos_t off_t
-EOF
-
- cat >> confdefs.h <<\EOF
-#define pthread_fpos_t pthread_off_t
-EOF
-
-fi
-
-echo $ac_n "checking type of off_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_off_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2073 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern off_t foo;
-; return 0; }
-EOF
-if { (eval echo configure:2087: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "int" "unsigned int" "long" "unsigned long" "short" "unsigned short" "char" "unsigned char" "long long" "unsigned long long" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2091 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
-
-int main() { return 0; }
-int t() {
- extern off_t foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2105: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_off_t="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for off_t." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_off_t" ; then
- cat >> confdefs.h <<EOF
-#define pthread_off_t $pthreads_cv_type_off_t
-EOF
-
-fi
-pthread_off_t=$pthreads_cv_type_off_t
-echo "$ac_t""$pthreads_cv_type_off_t" 1>&6
-echo $ac_n "checking type of va_list""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthreads_cv_type_va_list'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2133 "configure"
-#include "confdefs.h"
-#include <stdarg.h>
-int main() { return 0; }
-int t() {
- extern va_list foo;
-; return 0; }
-EOF
-if { (eval echo configure:2141: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- for try_type in "char *" "char **" "void *" "void **" "int *" "long *" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2145 "configure"
-#include "confdefs.h"
-#include <stdarg.h>
-int main() { return 0; }
-int t() {
- extern va_list foo; extern $try_type foo;
-; return 0; }
-EOF
-if { (eval echo configure:2153: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- pthreads_cv_type_va_list="$try_type" ; break
-fi
-rm -f conftest*
-
- done
-else
- rm -rf conftest*
- { echo "configure: error: Can't find system typedef for va_list." 1>&2; exit 1; }
-fi
-rm -f conftest*
-
-fi
-
-if test -n "$pthreads_cv_type_va_list" ; then
- cat >> confdefs.h <<EOF
-#define pthread_va_list $pthreads_cv_type_va_list
-EOF
-
-fi
-pthread_va_list=$pthreads_cv_type_va_list
-echo "$ac_t""$pthreads_cv_type_va_list" 1>&6
-
-arpa_headers="#include <sys/types.h>
-#include <arpa/nameser.h>"
-
-echo $ac_n "checking IP address type""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthread_cv_type_ipaddr'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2185 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() { return 0; }
-int t() {
- &_getlong;
-; return 0; }
-EOF
-if { (eval echo configure:2193: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- for type in "unsigned long" "unsigned int" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2198 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() { return 0; }
-int t() {
-extern $type _getlong ();
-; return 0; }
-EOF
-if { (eval echo configure:2206: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- pthread_cv_type_ipaddr="$type"
- break
-
-fi
-rm -f conftest*
-
- done
-
-else
- rm -rf conftest*
- echo "configure: warning: Can't compile _getlong reference." 1>&2
-fi
-rm -f conftest*
-
- if test "$pthread_cv_type_ipaddr" = "" ; then
- echo "configure: warning: Can't determine _getlong return type." 1>&2
- echo "configure: warning: Defaulting to unsigned long." 1>&2
- pthread_cv_type_ipaddr="unsigned long"
- fi
-
-fi
-
-echo "$ac_t""$pthread_cv_type_ipaddr" 1>&6
-cat >> confdefs.h <<EOF
-#define pthread_ipaddr_type $pthread_cv_type_ipaddr
-EOF
-
-
-echo $ac_n "checking IP port type""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthread_cv_type_ipport'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2242 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() { return 0; }
-int t() {
- &_getshort;
-; return 0; }
-EOF
-if { (eval echo configure:2250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- for type in "unsigned short" "unsigned int" ; do
- cat > conftest.$ac_ext <<EOF
-#line 2255 "configure"
-#include "confdefs.h"
-$arpa_headers
-int main() { return 0; }
-int t() {
-extern $type _getshort ();
-; return 0; }
-EOF
-if { (eval echo configure:2263: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
-
- pthread_cv_type_ipport="$type"
- break
-
-fi
-rm -f conftest*
-
- done
-
-else
- rm -rf conftest*
- echo "configure: warning: Can't compile _getshort reference." 1>&2
-fi
-rm -f conftest*
-
- if test "$pthread_cv_type_ipport" = "" ; then
- echo "configure: warning: Can't determine _getshort return type." 1>&2
- echo "configure: warning: Defaulting to unsigned short." 1>&2
- pthread_cv_type_ipport="unsigned short"
- fi
-
-fi
-
-echo "$ac_t""$pthread_cv_type_ipport" 1>&6
-cat >> confdefs.h <<EOF
-#define pthread_ipport_type $pthread_cv_type_ipport
-EOF
-
-
-echo $ac_n "checking pathname for terminal devices directory""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'pthread_cv_pty_path'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -d /devices/pseudo ; then
- pty_path=/devices/pseudo/
- else
- pty_path=/dev/
- fi
- pthread_cv_pty_path=$pty_path
-
-fi
-
-cat >> confdefs.h <<EOF
-#define _PATH_PTY "$pthread_cv_pty_path"
-EOF
-
-echo "$ac_t""$pthread_cv_pty_path" 1>&6
-
-echo $ac_n "checking directory name for time zone info""... $ac_c" 1>&6
-tzdir=NONE
-for f in /usr/lib/zoneinfo /usr/share/zoneinfo /usr/share/lib/zoneinfo /etc/zoneinfo /usr/local/lib/zoneinfo
-do
- if test -d $f ; then
- tzdir=$f
- break
- fi
-done
-case $tzdir in
-NONE)
- echo "configure: warning: Can't find zoneinfo directory." 1>&2
- echo "configure: warning: Defaulting zoneinfo directory to NULL." 1>&2
- tzdir=NULL
- ;;
-esac
-cat >> confdefs.h <<EOF
-#define _PATH_TZDIR "$tzdir"
-EOF
-
-echo "$ac_t""$tzdir" 1>&6
-
-echo $ac_n "checking filename for local time zone""... $ac_c" 1>&6
-tzfile=NONE
-for f in $tzdir/localtime /etc/localtime
-do
- if test -f $f ; then
- tzfile=$f
- break
- fi
-done
-case $tzfile in
-NONE) # Should this default to tzdir/localtime?
- echo "configure: warning: Can't find local time zone file." 1>&2
- if test tzdir = NULL ; then
- echo "configure: warning: Defaulting local time zone file to NULL" 1>&2
- tzfile=NULL
- else
- echo "configure: warning: Defaulting local time zone file to $tzdir/localtime." 1>&2
- tzfile=$tzdir/localtime
- fi
- ;;
-esac
-cat >> confdefs.h <<EOF
-#define _PATH_TZFILE "$tzfile"
-EOF
-
-echo "$ac_t""$tzfile" 1>&6
-
-cat >> confdefs.h <<\EOF
-#define _PATH_RESCONF "/etc/resolv.conf"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_HOSTS "/etc/hosts"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_NETWORKS "/etc/networks"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_PROTOCOLS "/etc/protocols"
-EOF
-
-cat >> confdefs.h <<\EOF
-#define _PATH_SERVICES "/etc/services"
-EOF
-
-
-cat >> confdefs.h <<\EOF
-#define _PATH_BSHELL "/bin/sh"
-EOF
-
-
-for ac_func in vfork
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2395 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() { return 0; }
-int t() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:2419: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-
-fi
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-srctop=`cd ${srcdir}/..;pwd`
-
-
-# Now we deal with symlinks &c.
-
-test -d include || mkdir include || \
- { echo "configure: error: Can't create include directory." 1>&2; exit 1; }
-
-test -d include/pthread || mkdir include/pthread || \
- { echo "configure: error: Can't create include/pthread directory." 1>&2; exit 1; }
-
-test -d lib || mkdir lib || \
- { echo "configure: error: Can't create lib directory." 1>&2; exit 1; }
-
-test -d lib/libpthreadutil || mkdir lib/libpthreadutil || \
- { echo "configure: error: Can't create lib/libpthreadutil directory." 1>&2; exit 1; }
-
-test -d bin || mkdir bin || \
- { echo "configure: error: Can't create bin directory." 1>&2; exit 1; }
-
-test -d bin/finger || mkdir bin/finger || \
- { echo "configure: error: Can't create bin directory." 1>&2; exit 1; }
-
-test -d tests || mkdir tests || \
- { echo "configure: error: Can't create tests directory." 1>&2; exit 1; }
-
-if test x$syscall = xNONE ; then
- syscall=$name
-fi
-
-links="include/pthread/machdep.h include/pthread/posix.h \
- machdep.c syscall.S"
-targets="../machdep/engine-$name.h ../machdep/posix-$sysincludes.h \
- ../machdep/engine-$name.c ../machdep/syscall-$syscall.S"
-
-# Both these targets are optional. (Autoconf-generated configure scripts
-# will require the existence of link targets, so check before adding them
-# to the list.)
-if test x$sysincludes != xNONE ; then
- links="$links include/sys"
- targets="$targets ../machdep/$sysincludes"
-fi
-
-syscall_file=../machdep/syscall-template-$syscall.S
-if test -r $srcdir/$syscall_file ; then
- links="$links syscall-template.S"
- targets="$targets $syscall_file"
- HAVE_SYSCALL_TEMPLATE=yes
-else
- # This really isn't a fatal problem. In fact, it's expected, initially,
- # for some targets. This is just to persuade people to fix the targets
- # they deal with to provide some sort of template.
- #
- # Eventually this file probably will be required...
- echo "configure: warning: No syscall template file syscall-template-$syscall.S found." 1>&2
- HAVE_SYSCALL_TEMPLATE=no
-fi
-
-
-
-
-if test x$makefile_frag != x ; then
- makefile_frag=${srcdir}/$makefile_frag
-else
- makefile_frag=/dev/null
-fi
-
-
-
-
-
-trap '' 1 2 15
-cat > confcache <<\EOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs. It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
-#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already. You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
-#
-EOF
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
- sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
- >> confcache
-if cmp -s $cache_file confcache; then
- :
-else
- if test -w $cache_file; then
- echo "updating cache $cache_file"
- cat confcache > $cache_file
- else
- echo "not updating unwritable cache $cache_file"
- fi
-fi
-rm -f confcache
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
-fi
-
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
-DEFS=-DHAVE_CONFIG_H
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
-# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
-# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
-
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
- case "\$ac_option" in
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
- -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.10"
- exit 0 ;;
- -help | --help | --hel | --he | --h)
- echo "\$ac_cs_usage"; exit 0 ;;
- *) echo "\$ac_cs_usage"; exit 1 ;;
- esac
-done
-
-ac_given_srcdir=$srcdir
-
-trap 'rm -fr `echo "config.flags GNUmakefile Makefile \
- lib/Makefile:../lib/Makefile.in \
- lib/libpthreadutil/Makefile:../lib/libpthreadutil/Makefile.in \
- bin/Makefile:../bin/Makefile.in \
- bin/finger/Makefile:../bin/finger/Makefile.in \
- tests/Makefile:../tests/Makefile.in config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@CC@%$CC%g
-s%@CXX@%$CXX%g
-s%@CPP@%$CPP%g
-s%@RANLIB@%$RANLIB%g
-s%@host@%$host%g
-s%@host_alias@%$host_alias%g
-s%@host_cpu@%$host_cpu%g
-s%@host_vendor@%$host_vendor%g
-s%@host_os@%$host_os%g
-s%@target@%$target%g
-s%@target_alias@%$target_alias%g
-s%@target_cpu@%$target_cpu%g
-s%@target_vendor@%$target_vendor%g
-s%@target_os@%$target_os%g
-s%@build@%$build%g
-s%@build_alias@%$build_alias%g
-s%@build_cpu@%$build_cpu%g
-s%@build_vendor@%$build_vendor%g
-s%@build_os@%$build_os%g
-s%@SYSCALL_EXCEPTIONS@%$SYSCALL_EXCEPTIONS%g
-s%@available_syscalls@%$available_syscalls%g
-s%@missing_syscalls@%$missing_syscalls%g
-s%@srctop@%$srctop%g
-s%@HAVE_SYSCALL_TEMPLATE@%$HAVE_SYSCALL_TEMPLATE%g
-/@makefile_frag@/r $makefile_frag
-s%@makefile_frag@%%g
-
-CEOF
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"config.flags GNUmakefile Makefile \
- lib/Makefile:../lib/Makefile.in \
- lib/libpthreadutil/Makefile:../lib/libpthreadutil/Makefile.in \
- bin/Makefile:../bin/Makefile.in \
- bin/finger/Makefile:../bin/finger/Makefile.in \
- tests/Makefile:../tests/Makefile.in"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- # Adjust relative srcdir, etc. for subdirectories.
-
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dir_suffix= ac_dots=
- fi
-
- case "$ac_given_srcdir" in
- .) srcdir=.
- if test -z "$ac_dots"; then top_srcdir=.
- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
- *) # Relative path.
- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
- top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
-
- echo creating "$ac_file"
- rm -f "$ac_file"
- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
- case "$ac_file" in
- *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
- *) ac_comsub= ;;
- esac
- sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
-fi; done
-rm -f conftest.subs
-
-# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
-# NAME is the cpp macro being defined and VALUE is the value it is being given.
-#
-# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
-ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
-ac_dC='\3'
-ac_dD='%g'
-# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
-ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_uB='\([ ]\)%\1#\2define\3'
-ac_uC=' '
-ac_uD='\4%g'
-# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_eB='$%\1#\2define\3'
-ac_eC=' '
-ac_eD='%g'
-
-CONFIG_HEADERS=${CONFIG_HEADERS-"config.h"}
-for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- echo creating $ac_file
-
- rm -f conftest.frag conftest.in conftest.out
- cp $ac_given_srcdir/$ac_file_in conftest.in
-
-EOF
-
-# Transform confdefs.h into a sed script conftest.vals that substitutes
-# the proper values into config.h.in to produce config.h. And first:
-# Protect against being on the right side of a sed subst in config.status.
-# Protect against being in an unquoted here document in config.status.
-rm -f conftest.vals
-cat > conftest.hdr <<\EOF
-s/[\\&%]/\\&/g
-s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
-s%ac_d%ac_u%gp
-s%ac_u%ac_e%gp
-EOF
-sed -n -f conftest.hdr confdefs.h > conftest.vals
-rm -f conftest.hdr
-
-# This sed command replaces #undef with comments. This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-cat >> conftest.vals <<\EOF
-s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
-EOF
-
-# Break up conftest.vals because some shells have a limit on
-# the size of here documents, and old seds have small limits too.
-# Maximum number of lines to put in a single here document.
-ac_max_here_lines=12
-
-rm -f conftest.tail
-while :
-do
- ac_lines=`grep -c . conftest.vals`
- # grep -c gives empty output for an empty file on some AIX systems.
- if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
- # Write a limited-size here document to conftest.frag.
- echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
- sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
- echo 'CEOF
- sed -f conftest.frag conftest.in > conftest.out
- rm -f conftest.in
- mv conftest.out conftest.in
-' >> $CONFIG_STATUS
- sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
- rm -f conftest.vals
- mv conftest.tail conftest.vals
-done
-rm -f conftest.vals
-
-cat >> $CONFIG_STATUS <<\EOF
- rm -f conftest.frag conftest.h
- echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
- cat conftest.in >> conftest.h
- rm -f conftest.in
- if cmp -s $ac_file conftest.h 2>/dev/null; then
- echo "$ac_file is unchanged"
- rm -f conftest.h
- else
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- fi
- rm -f $ac_file
- mv conftest.h $ac_file
- fi
-fi; done
-
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-ac_sources="$targets"
-ac_dests="$links"
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-srcdir=$ac_given_srcdir
-while test -n "$ac_sources"; do
- set $ac_dests; ac_dest=$1; shift; ac_dests=$*
- set $ac_sources; ac_source=$1; shift; ac_sources=$*
-
- echo "linking $srcdir/$ac_source to $ac_dest"
-
- if test ! -r $srcdir/$ac_source; then
- { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; }
- fi
- rm -f $ac_dest
-
- # Make relative symlinks.
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then
- # The dest file is in a subdirectory.
- test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir"
- ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dest_dir_suffix.
- ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dest_dir_suffix= ac_dots=
- fi
-
- case "$srcdir" in
- [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
- *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
- esac
-
- # Make a symlink if possible; otherwise try a hard link.
- if ln -s $ac_rel_source $ac_dest 2>/dev/null ||
- ln $srcdir/$ac_source $ac_dest; then :
- else
- { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
- fi
-done
-
-
-exit 0
-EOF
-chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
diff --git a/mit-pthreads/config/install-sh b/mit-pthreads/config/install-sh
deleted file mode 100755
index ab74c882e92..00000000000
--- a/mit-pthreads/config/install-sh
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-#
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-tranformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-else
- true
-fi
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d $dst ]; then
- instcmd=:
- else
- instcmd=mkdir
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f $src -o -d $src ]
- then
- true
- else
- echo "install: $src does not exist"
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "install: no destination specified"
- exit 1
- else
- true
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d $dst ]
- then
- dst="$dst"/`basename $src`
- else
- true
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp="${pathcomp}${1}"
- shift
-
- if [ ! -d "${pathcomp}" ] ;
- then
- $mkdirprog "${pathcomp}"
- else
- true
- fi
-
- pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd $dst &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename $dst`
- else
- dstfile=`basename $dst $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename $dst`
- else
- true
- fi
-
-# Make a temp file name in the proper directory.
-
- dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd $src $dsttmp &&
-
- trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
- $doit $rmcmd -f $dstdir/$dstfile &&
- $doit $mvcmd $dsttmp $dstdir/$dstfile
-
-fi &&
-
-
-exit 0
diff --git a/mit-pthreads/configure b/mit-pthreads/configure
deleted file mode 100755
index ffad2bca3cd..00000000000
--- a/mit-pthreads/configure
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-
-# This silliness is because Chris wants the autoconf-related files
-# and makefiles not to appear in the top-level directory. Fine by
-# me, I don't much care. This script just needs to invoke the real
-# configure script...
-
-config=`echo $0 | sed -e 's,configure$,config/configure,'`
-
-if test ! -d obj ; then
- mkdir obj
-fi
-
-if test -n "$1" ; then
- sh $config "$@"
-else
- sh $config
-fi
diff --git a/mit-pthreads/gen/GNUmakefile.inc b/mit-pthreads/gen/GNUmakefile.inc
deleted file mode 100755
index a5025860b85..00000000000
--- a/mit-pthreads/gen/GNUmakefile.inc
+++ /dev/null
@@ -1,9 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# gen sources
-VPATH:= ${VPATH}:${srcdir}/gen
-
-SRCS:= ttyname.c directory.c popen.c time.c ctime.c difftime.c syslog.c \
- eprintf.c getpwent.c getpwnamuid.c pwd_internal.c \
- getcwd.c getwd.c isatty.c $(SRCS)
diff --git a/mit-pthreads/gen/Makefile.inc b/mit-pthreads/gen/Makefile.inc
deleted file mode 100644
index 6e2c3d44f43..00000000000
--- a/mit-pthreads/gen/Makefile.inc
+++ /dev/null
@@ -1,24 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# gen sources
-.PATH: ${srcdir}/gen
-
-SRCS+= ttyname.c isatty.c directory.c popen.c time.c ctime.c difftime.c \
- syslog.c eprintf.c getpwent.c getpwnamuid.c pwd_internal.c
-
-#SRCS+= alarm.c assert.c clock.c crypt.c ctermid.c ctype_.c \
-# disklabel.c err.c errlst.c exec.c fnmatch.c frexp.c \
-# fstab.c fts.c getcap.c getcwd.c getgrent.c getlogin.c getmntinfo.c \
-# getpass.c getpwent.c getsubopt.c getttyent.c getusershell.c glob.c \
-# infinity.c initgroups.c isatty.c isctype.c isinf.c mktemp.c nice.c \
-# nlist.c pause.c psignal.c raise.c \
-# scandir.c setjmperr.c \
-# setmode.c setrgid.c setruid.c siginterrupt.c \
-# siglist.c signal.c sigsetops.c syslog.c \
-# termios.c time.c times.c timezone.c ttyslot.c \
-# ualarm.c unvis.c utime.c valloc.c vis.c
-#
-# gen/regexp sources
-#SRCS+= regerror.c regexp.c regsub.c
-
diff --git a/mit-pthreads/gen/ctime.c b/mit-pthreads/gen/ctime.c
deleted file mode 100644
index 9b38d41e495..00000000000
--- a/mit-pthreads/gen/ctime.c
+++ /dev/null
@@ -1,1315 +0,0 @@
-/*
- * Copyright (c) 1987, 1989 Regents of the University of California.
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Arthur David Olson of the National Cancer Institute.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ctime.c 5.26 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
-
-/*
-** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu).
-** POSIX-style TZ environment variable handling from Guy Harris
-** (guy@auspex.com).
-*/
-
-/*LINTLIBRARY*/
-#include "config.h"
-#include <pthread.h>
-#include <sys/param.h>
-#include <fcntl.h>
-#include <time.h>
-#include <tzfile.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#ifndef WILDABBR
-/*
-** Someone might make incorrect use of a time zone abbreviation:
-** 1. They might reference tzname[0] before calling tzset (explicitly
-** or implicitly).
-** 2. They might reference tzname[1] before calling tzset (explicitly
-** or implicitly).
-** 3. They might reference tzname[1] after setting to a time zone
-** in which Daylight Saving Time is never observed.
-** 4. They might reference tzname[0] after setting to a time zone
-** in which Standard Time is never observed.
-** 5. They might reference tm.TM_ZONE after calling offtime.
-** What's best to do in the above cases is open to debate;
-** for now, we just set things up so that in any of the five cases
-** WILDABBR is used. Another possibility: initialize tzname[0] to the
-** string "tzname[0] used before set", and similarly for the other cases.
-** And another: initialize tzname[0] to "ERA", with an explanation in the
-** manual page of what this "time zone abbreviation" means (doing this so
-** that tzname[0] has the "normal" length of three characters).
-*/
-#define WILDABBR " "
-#endif /* !defined WILDABBR */
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif /* !defined TRUE */
-
-static const char GMT[] = "GMT";
-
-struct ttinfo { /* time type information */
- long tt_gmtoff; /* GMT offset in seconds */
- int tt_isdst; /* used to set tm_isdst */
- int tt_abbrind; /* abbreviation list index */
- int tt_ttisstd; /* TRUE if transition is std time */
-};
-
-struct lsinfo { /* leap second information */
- time_t ls_trans; /* transition time */
- long ls_corr; /* correction to apply */
-};
-
-struct state {
- int leapcnt;
- int timecnt;
- int typecnt;
- int charcnt;
- time_t ats[TZ_MAX_TIMES];
- unsigned char types[TZ_MAX_TIMES];
- struct ttinfo ttis[TZ_MAX_TYPES];
- char chars[(TZ_MAX_CHARS + 1 > sizeof GMT) ?
- TZ_MAX_CHARS + 1 : sizeof GMT];
- struct lsinfo lsis[TZ_MAX_LEAPS];
-};
-
-struct rule {
- int r_type; /* type of rule--see below */
- int r_day; /* day number of rule */
- int r_week; /* week number of rule */
- int r_mon; /* month number of rule */
- long r_time; /* transition time of rule */
-};
-
-#define JULIAN_DAY 0 /* Jn - Julian day */
-#define DAY_OF_YEAR 1 /* n - day of year */
-#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
-
-/*
-** Prototypes for static functions.
-*/
-
-static int detzcode __P_((const char *));
-static const char * getnum __P_((const char *, int *, int, int));
-static const char * getsecs __P_((const char *, long *));
-static const char * getoffset __P_((const char *, long *));
-static const char * getrule __P_((const char *, struct rule *));
-static const char * getzname __P_((const char *));
-static void gmtload __P_((struct state *));
-static void gmtsub __P_((const time_t *, long, struct tm *));
-static void localsub __P_((const time_t *, long, struct tm *));
-static void normalize __P_((int *, int *, int));
-static void settzname __P_((struct state *));
-static time_t time1 __P_((struct tm *, long));
-static time_t time2 __P_((struct tm *, long, int *));
-static void timesub __P_((const time_t *, long, const struct state *,
- struct tm *));
-static int tmcomp __P_((const struct tm *, const struct tm *));
-static time_t transtime __P_((time_t, int, const struct rule *, long));
-static int tzload __P_((const char *, struct state *));
-static int tzparse __P_((const char *, struct state *, int));
-static void tzset_basic __P_((void));
-static void tzsetwall_basic __P_((void));
-
-static pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER;
-static int lcl_is_set = FALSE;
-static int gmt_is_set = FALSE;
-static struct state lclmem;
-static struct state gmtmem;
-
-#define lclptr (&lclmem)
-#define gmtptr (&gmtmem)
-
-char * tzname[2] = {
- WILDABBR,
- WILDABBR
-};
-
-#ifdef USG_COMPAT
-time_t timezone = 0;
-int daylight = 0;
-#endif /* defined USG_COMPAT */
-
-#ifdef ALTZONE
-time_t altzone = 0;
-#endif /* defined ALTZONE */
-
-static int detzcode(const char * codep)
-{
- int result;
- int i;
-
- result = 0;
- for (i = 0; i < 4; ++i)
- result = (result << 8) | (codep[i] & 0xff);
- return result;
-}
-
-static void settzname(struct state * sp)
-{
- register int i;
-
- tzname[0] = WILDABBR;
- tzname[1] = WILDABBR;
-#ifdef USG_COMPAT
- daylight = 0;
- timezone = 0;
-#endif /* defined USG_COMPAT */
-#ifdef ALTZONE
- altzone = 0;
-#endif /* defined ALTZONE */
- for (i = 0; i < sp->typecnt; ++i) {
- register const struct ttinfo * const ttisp = &sp->ttis[i];
-
- tzname[ttisp->tt_isdst] =
- (char *) &sp->chars[ttisp->tt_abbrind];
-#ifdef USG_COMPAT
- if (ttisp->tt_isdst)
- daylight = 1;
- if (i == 0 || !ttisp->tt_isdst)
- timezone = -(ttisp->tt_gmtoff);
-#endif /* defined USG_COMPAT */
-#ifdef ALTZONE
- if (i == 0 || ttisp->tt_isdst)
- altzone = -(ttisp->tt_gmtoff);
-#endif /* defined ALTZONE */
- }
- /*
- ** And to get the latest zone names into tzname. . .
- */
- for (i = 0; i < sp->timecnt; ++i) {
- register const struct ttinfo * const ttisp =
- &sp->ttis[sp->types[i]];
-
- tzname[ttisp->tt_isdst] =
- (char *) &sp->chars[ttisp->tt_abbrind];
- }
-}
-
-static int tzload(const char * name, struct state * sp)
-{
- register const char * p;
- register int i;
- register int fid;
-
- if (name == NULL && (name = TZDEFAULT) == NULL)
- return -1;
- {
- char fullname[FILENAME_MAX + 1];
-
- if (name[0] == ':')
- ++name;
- if (name[0] != '/') {
- if ((p = TZDIR) == NULL)
- return -1;
- if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
- return -1;
- (void) strcpy(fullname, p);
- (void) strcat(fullname, "/");
- (void) strcat(fullname, name);
- name = fullname;
- }
- if ((fid = open(name, O_RDONLY)) == -1)
- return -1;
- }
- {
- register const struct tzhead * tzhp;
- char buf[sizeof *sp + sizeof *tzhp];
- int ttisstdcnt;
-
- i = read(fid, buf, sizeof buf);
- if (close(fid) != 0 || i < sizeof *tzhp)
- return -1;
- tzhp = (struct tzhead *) buf;
- ttisstdcnt = (int) detzcode(tzhp->tzh_ttisstdcnt);
- sp->leapcnt = (int) detzcode(tzhp->tzh_leapcnt);
- sp->timecnt = (int) detzcode(tzhp->tzh_timecnt);
- sp->typecnt = (int) detzcode(tzhp->tzh_typecnt);
- sp->charcnt = (int) detzcode(tzhp->tzh_charcnt);
- if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
- sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
- sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
- sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
- (ttisstdcnt != sp->typecnt && ttisstdcnt != 0))
- return -1;
- if (i < sizeof *tzhp +
- sp->timecnt * (4 + sizeof (char)) +
- sp->typecnt * (4 + 2 * sizeof (char)) +
- sp->charcnt * sizeof (char) +
- sp->leapcnt * 2 * 4 +
- ttisstdcnt * sizeof (char))
- return -1;
- p = buf + sizeof *tzhp;
- for (i = 0; i < sp->timecnt; ++i) {
- sp->ats[i] = detzcode(p);
- p += 4;
- }
- for (i = 0; i < sp->timecnt; ++i) {
- sp->types[i] = (unsigned char) *p++;
- if (sp->types[i] >= sp->typecnt)
- return -1;
- }
- for (i = 0; i < sp->typecnt; ++i) {
- register struct ttinfo * ttisp;
-
- ttisp = &sp->ttis[i];
- ttisp->tt_gmtoff = detzcode(p);
- p += 4;
- ttisp->tt_isdst = (unsigned char) *p++;
- if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
- return -1;
- ttisp->tt_abbrind = (unsigned char) *p++;
- if (ttisp->tt_abbrind < 0 ||
- ttisp->tt_abbrind > sp->charcnt)
- return -1;
- }
- for (i = 0; i < sp->charcnt; ++i)
- sp->chars[i] = *p++;
- sp->chars[i] = '\0'; /* ensure '\0' at end */
- for (i = 0; i < sp->leapcnt; ++i) {
- register struct lsinfo * lsisp;
-
- lsisp = &sp->lsis[i];
- lsisp->ls_trans = detzcode(p);
- p += 4;
- lsisp->ls_corr = detzcode(p);
- p += 4;
- }
- for (i = 0; i < sp->typecnt; ++i) {
- register struct ttinfo * ttisp;
-
- ttisp = &sp->ttis[i];
- if (ttisstdcnt == 0)
- ttisp->tt_ttisstd = FALSE;
- else {
- ttisp->tt_ttisstd = *p++;
- if (ttisp->tt_ttisstd != TRUE &&
- ttisp->tt_ttisstd != FALSE)
- return -1;
- }
- }
- }
- return 0;
-}
-
-static const int mon_lengths[2][MONSPERYEAR] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
- 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-static const int year_lengths[2] = {
- DAYSPERNYEAR, DAYSPERLYEAR
-};
-
-/*
-** Given a pointer into a time zone string, scan until a character that is not
-** a valid character in a zone name is found. Return a pointer to that
-** character.
-*/
-static const char * getzname(const char * strp)
-{
- register char c;
-
- while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' &&
- c != '+')
- ++strp;
- return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a number from that string.
-** Check that the number is within a specified range; if it is not, return
-** NULL.
-** Otherwise, return a pointer to the first character not part of the number.
-*/
-
-static const char *getnum(const char * strp, int * nump, int min, int max)
-{
- char c;
- int num;
-
- if (strp == NULL || !isdigit(*strp))
- return NULL;
- num = 0;
- while ((c = *strp) != '\0' && isdigit(c)) {
- num = num * 10 + (c - '0');
- if (num > max)
- return NULL; /* illegal value */
- ++strp;
- }
- if (num < min)
- return NULL; /* illegal value */
- *nump = num;
- return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a number of seconds,
-** in hh[:mm[:ss]] form, from the string.
-** If any error occurs, return NULL.
-** Otherwise, return a pointer to the first character not part of the number
-** of seconds.
-*/
-static const char * getsecs(const char * strp, long * secsp)
-{
- int num;
-
- strp = getnum(strp, &num, 0, HOURSPERDAY);
- if (strp == NULL)
- return NULL;
- *secsp = num * SECSPERHOUR;
- if (*strp == ':') {
- ++strp;
- strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
- if (strp == NULL)
- return NULL;
- *secsp += num * SECSPERMIN;
- if (*strp == ':') {
- ++strp;
- strp = getnum(strp, &num, 0, SECSPERMIN - 1);
- if (strp == NULL)
- return NULL;
- *secsp += num;
- }
- }
- return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract an offset, in
-** [+-]hh[:mm[:ss]] form, from the string.
-** If any error occurs, return NULL.
-** Otherwise, return a pointer to the first character not part of the time.
-*/
-static const char * getoffset(const char * strp, long * offsetp)
-{
- int neg;
-
- if (*strp == '-') {
- neg = 1;
- ++strp;
- } else if (isdigit(*strp) || *strp++ == '+')
- neg = 0;
- else return NULL; /* illegal offset */
- strp = getsecs(strp, offsetp);
- if (strp == NULL)
- return NULL; /* illegal time */
- if (neg)
- *offsetp = -*offsetp;
- return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a rule in the form
-** date[/time]. See POSIX section 8 for the format of "date" and "time".
-** If a valid rule is not found, return NULL.
-** Otherwise, return a pointer to the first character not part of the rule.
-*/
-static const char * getrule(const char * strp, struct rule * rulep)
-{
- if (*strp == 'J') {
- /*
- ** Julian day.
- */
- rulep->r_type = JULIAN_DAY;
- ++strp;
- strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
- } else if (*strp == 'M') {
- /*
- ** Month, week, day.
- */
- rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
- ++strp;
- strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
- if (strp == NULL)
- return NULL;
- if (*strp++ != '.')
- return NULL;
- strp = getnum(strp, &rulep->r_week, 1, 5);
- if (strp == NULL)
- return NULL;
- if (*strp++ != '.')
- return NULL;
- strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
- } else if (isdigit(*strp)) {
- /*
- ** Day of year.
- */
- rulep->r_type = DAY_OF_YEAR;
- strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
- } else return NULL; /* invalid format */
- if (strp == NULL)
- return NULL;
- if (*strp == '/') {
- /*
- ** Time specified.
- */
- ++strp;
- strp = getsecs(strp, &rulep->r_time);
- } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
- return strp;
-}
-
-/*
-** Given the Epoch-relative time of January 1, 00:00:00 GMT, in a year, the
-** year, a rule, and the offset from GMT at the time that rule takes effect,
-** calculate the Epoch-relative time that rule takes effect.
-*/
-static time_t transtime(time_t janfirst, int year,
- const struct rule * rulep, long offset)
-{
- register int leapyear;
- register time_t value;
- register int i;
- int d, m1, yy0, yy1, yy2, dow;
-
- leapyear = isleap(year);
- switch (rulep->r_type) {
-
- case JULIAN_DAY:
- /*
- ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
- ** years.
- ** In non-leap years, or if the day number is 59 or less, just
- ** add SECSPERDAY times the day number-1 to the time of
- ** January 1, midnight, to get the day.
- */
- value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
- if (leapyear && rulep->r_day >= 60)
- value += SECSPERDAY;
- break;
-
- case DAY_OF_YEAR:
- /*
- ** n - day of year.
- ** Just add SECSPERDAY times the day number to the time of
- ** January 1, midnight, to get the day.
- */
- value = janfirst + rulep->r_day * SECSPERDAY;
- break;
-
- case MONTH_NTH_DAY_OF_WEEK:
- /*
- ** Mm.n.d - nth "dth day" of month m.
- */
- value = janfirst;
- for (i = 0; i < rulep->r_mon - 1; ++i)
- value += mon_lengths[leapyear][i] * SECSPERDAY;
-
- /*
- ** Use Zeller's Congruence to get day-of-week of first day of
- ** month.
- */
- m1 = (rulep->r_mon + 9) % 12 + 1;
- yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
- yy1 = yy0 / 100;
- yy2 = yy0 % 100;
- dow = ((26 * m1 - 2) / 10 +
- 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
- if (dow < 0)
- dow += DAYSPERWEEK;
-
- /*
- ** "dow" is the day-of-week of the first day of the month. Get
- ** the day-of-month (zero-origin) of the first "dow" day of the
- ** month.
- */
- d = rulep->r_day - dow;
- if (d < 0)
- d += DAYSPERWEEK;
- for (i = 1; i < rulep->r_week; ++i) {
- if (d + DAYSPERWEEK >=
- mon_lengths[leapyear][rulep->r_mon - 1])
- break;
- d += DAYSPERWEEK;
- }
-
- /*
- ** "d" is the day-of-month (zero-origin) of the day we want.
- */
- value += d * SECSPERDAY;
- break;
- }
-
- /*
- ** "value" is the Epoch-relative time of 00:00:00 GMT on the day in
- ** question. To get the Epoch-relative time of the specified local
- ** time on that day, add the transition time and the current offset
- ** from GMT.
- */
- return value + rulep->r_time + offset;
-}
-
-/*
-** Given a POSIX section 8-style TZ string, fill in the rule tables as
-** appropriate.
-*/
-static int tzparse(const char * name, struct state * sp, int lastditch)
-{
- const char * stdname;
- const char * dstname;
- int stdlen;
- int dstlen;
- long stdoffset;
- long dstoffset;
- register time_t * atp;
- register unsigned char * typep;
- register char * cp;
- register int load_result;
-
- stdname = name;
- if (lastditch) {
- stdlen = strlen(name); /* length of standard zone name */
- name += stdlen;
- if (stdlen >= sizeof sp->chars)
- stdlen = (sizeof sp->chars) - 1;
- } else {
- name = getzname(name);
- stdlen = name - stdname;
- if (stdlen < 3)
- return -1;
- }
- if (*name == '\0')
- return -1;
- else {
- name = getoffset(name, &stdoffset);
- if (name == NULL)
- return -1;
- }
- load_result = tzload(TZDEFRULES, sp);
- if (load_result != 0)
- sp->leapcnt = 0; /* so, we're off a little */
- if (*name != '\0') {
- dstname = name;
- name = getzname(name);
- dstlen = name - dstname; /* length of DST zone name */
- if (dstlen < 3)
- return -1;
- if (*name != '\0' && *name != ',' && *name != ';') {
- name = getoffset(name, &dstoffset);
- if (name == NULL)
- return -1;
- } else dstoffset = stdoffset - SECSPERHOUR;
- if (*name == ',' || *name == ';') {
- struct rule start;
- struct rule end;
- register int year;
- register time_t janfirst;
- time_t starttime;
- time_t endtime;
-
- ++name;
- if ((name = getrule(name, &start)) == NULL)
- return -1;
- if (*name++ != ',')
- return -1;
- if ((name = getrule(name, &end)) == NULL)
- return -1;
- if (*name != '\0')
- return -1;
- sp->typecnt = 2; /* standard time and DST */
- /*
- ** Two transitions per year, from EPOCH_YEAR to 2037.
- */
- sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
- if (sp->timecnt > TZ_MAX_TIMES)
- return -1;
- sp->ttis[0].tt_gmtoff = -dstoffset;
- sp->ttis[0].tt_isdst = 1;
- sp->ttis[0].tt_abbrind = stdlen + 1;
- sp->ttis[1].tt_gmtoff = -stdoffset;
- sp->ttis[1].tt_isdst = 0;
- sp->ttis[1].tt_abbrind = 0;
- atp = sp->ats;
- typep = sp->types;
- janfirst = 0;
- for (year = EPOCH_YEAR; year <= 2037; ++year) {
- starttime = transtime(janfirst, year, &start,
- stdoffset);
- endtime = transtime(janfirst, year, &end,
- dstoffset);
- if (starttime > endtime) {
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- } else {
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
- }
- janfirst +=
- year_lengths[isleap(year)] * SECSPERDAY;
- }
- } else {
- int sawstd;
- int sawdst;
- long stdfix;
- long dstfix;
- long oldfix;
- int isdst;
- register int i;
-
- if (*name != '\0')
- return -1;
- if (load_result != 0)
- return -1;
- /*
- ** Compute the difference between the real and
- ** prototype standard and summer time offsets
- ** from GMT, and put the real standard and summer
- ** time offsets into the rules in place of the
- ** prototype offsets.
- */
- sawstd = FALSE;
- sawdst = FALSE;
- stdfix = 0;
- dstfix = 0;
- for (i = 0; i < sp->typecnt; ++i) {
- if (sp->ttis[i].tt_isdst) {
- oldfix = dstfix;
- dstfix =
- sp->ttis[i].tt_gmtoff + dstoffset;
- if (sawdst && (oldfix != dstfix))
- return -1;
- sp->ttis[i].tt_gmtoff = -dstoffset;
- sp->ttis[i].tt_abbrind = stdlen + 1;
- sawdst = TRUE;
- } else {
- oldfix = stdfix;
- stdfix =
- sp->ttis[i].tt_gmtoff + stdoffset;
- if (sawstd && (oldfix != stdfix))
- return -1;
- sp->ttis[i].tt_gmtoff = -stdoffset;
- sp->ttis[i].tt_abbrind = 0;
- sawstd = TRUE;
- }
- }
- /*
- ** Make sure we have both standard and summer time.
- */
- if (!sawdst || !sawstd)
- return -1;
- /*
- ** Now correct the transition times by shifting
- ** them by the difference between the real and
- ** prototype offsets. Note that this difference
- ** can be different in standard and summer time;
- ** the prototype probably has a 1-hour difference
- ** between standard and summer time, but a different
- ** difference can be specified in TZ.
- */
- isdst = FALSE; /* we start in standard time */
- for (i = 0; i < sp->timecnt; ++i) {
- register const struct ttinfo * ttisp;
-
- /*
- ** If summer time is in effect, and the
- ** transition time was not specified as
- ** standard time, add the summer time
- ** offset to the transition time;
- ** otherwise, add the standard time offset
- ** to the transition time.
- */
- ttisp = &sp->ttis[sp->types[i]];
- sp->ats[i] +=
- (isdst && !ttisp->tt_ttisstd) ?
- dstfix : stdfix;
- isdst = ttisp->tt_isdst;
- }
- }
- } else {
- dstlen = 0;
- sp->typecnt = 1; /* only standard time */
- sp->timecnt = 0;
- sp->ttis[0].tt_gmtoff = -stdoffset;
- sp->ttis[0].tt_isdst = 0;
- sp->ttis[0].tt_abbrind = 0;
- }
- sp->charcnt = stdlen + 1;
- if (dstlen != 0)
- sp->charcnt += dstlen + 1;
- if (sp->charcnt > sizeof sp->chars)
- return -1;
- cp = sp->chars;
- (void) strncpy(cp, stdname, stdlen);
- cp += stdlen;
- *cp++ = '\0';
- if (dstlen != 0) {
- (void) strncpy(cp, dstname, dstlen);
- *(cp + dstlen) = '\0';
- }
- return 0;
-}
-
-static void gmtload(struct state * sp)
-{
- if (tzload(GMT, sp) != 0)
- (void) tzparse(GMT, sp, TRUE);
-}
-
-static void tzset_basic()
-{
- const char * name;
- if ((name = getenv("TZ")) == NULL) {
- tzsetwall_basic();
- return;
- }
-
- if (*name == '\0') {
- /*
- ** User wants it fast rather than right.
- */
- lclptr->leapcnt = 0; /* so, we're off a little */
- lclptr->timecnt = 0;
- lclptr->ttis[0].tt_gmtoff = 0;
- lclptr->ttis[0].tt_abbrind = 0;
- (void) strcpy(lclptr->chars, GMT);
- } else {
- if (tzload(name, lclptr) != 0)
- if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
- (void) gmtload(lclptr);
- }
- lcl_is_set = TRUE;
- settzname(lclptr);
-}
-
-void tzset()
-{
- pthread_mutex_lock(&lcl_mutex);
- tzset_basic();
- pthread_mutex_unlock(&lcl_mutex);
-}
-
-static void tzsetwall_basic()
-{
- if (tzload((char *) NULL, lclptr) != 0)
- gmtload(lclptr);
- settzname(lclptr);
- lcl_is_set = TRUE;
-}
-
-void tzsetwall()
-{
- pthread_mutex_lock(&lcl_mutex);
- tzsetwall_basic();
- pthread_mutex_unlock(&lcl_mutex);
-}
-
-/*
-** The easy way to behave "as if no library function calls" localtime
-** is to not call it--so we drop its guts into "localsub", which can be
-** freely called. (And no, the PANS doesn't require the above behavior--
-** but it *is* desirable.)
-**
-** The unused offset argument is for the benefit of mktime variants.
-*/
-
-static void localsub(const time_t * timep, long offset, struct tm * tmp)
-{
- const struct ttinfo * ttisp;
- const time_t t = *timep;
- struct state * sp;
- int i;
-
- if (!lcl_is_set)
- tzset_basic();
- sp = lclptr;
- if (sp->timecnt == 0 || t < sp->ats[0]) {
- i = 0;
- while (sp->ttis[i].tt_isdst)
- if (++i >= sp->typecnt) {
- i = 0;
- break;
- }
- } else {
- for (i = 1; i < sp->timecnt; ++i)
- if (t < sp->ats[i])
- break;
- i = sp->types[i - 1];
- }
- ttisp = &sp->ttis[i];
- /*
- ** To get (wrong) behavior that's compatible with System V Release 2.0
- ** you'd replace the statement below with
- ** t += ttisp->tt_gmtoff;
- ** timesub(&t, 0L, sp, tmp);
- */
- timesub(&t, ttisp->tt_gmtoff, sp, tmp);
- tzname[tmp->tm_isdst] = (char *) &sp->chars[ttisp->tt_abbrind];
-#ifdef BSD_TM
- tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
-#endif
- tmp->tm_isdst = ttisp->tt_isdst;
-
- pthread_mutex_unlock(&lcl_mutex);
-}
-
-struct tm * localtime_r(const time_t * timep, struct tm * tm)
-{
- pthread_mutex_lock(&lcl_mutex);
- localsub(timep, 0L, tm);
- pthread_mutex_unlock(&lcl_mutex);
- return(tm);
-}
-
-struct tm * localtime(const time_t * timep)
-{
- static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t localtime_key = -1;
- struct tm * tm;
-
- pthread_mutex_lock(&localtime_mutex);
- if (localtime_key < 0) {
- if (pthread_key_create(&localtime_key, free) < 0) {
- pthread_mutex_unlock(&localtime_mutex);
- return(NULL);
- }
- }
- pthread_mutex_unlock(&localtime_mutex);
- if ((tm = pthread_getspecific(localtime_key)) == NULL) {
- if ((tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) {
- return(NULL);
- }
- pthread_setspecific(localtime_key, tm);
- }
-
- pthread_mutex_lock(&lcl_mutex);
- localsub(timep, 0L, tm);
- pthread_mutex_unlock(&lcl_mutex);
- return tm;
-}
-
-
-/*
- * gmtsub is to gmtime as localsub is to localtime.
- *
- * Once set there is no need to lock the gmt_mutex to view gmtptr
- */
-static void gmtsub(const time_t * timep, long offset, struct tm * tmp)
-{
- pthread_mutex_lock(&gmt_mutex);
- if (gmt_is_set == FALSE) {
- gmt_is_set = TRUE;
- gmtload(gmtptr);
- }
- pthread_mutex_unlock(&gmt_mutex);
-
- timesub(timep, offset, gmtptr, tmp);
- /*
- ** Could get fancy here and deliver something such as
- ** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero,
- ** but this is no time for a treasure hunt.
- */
-#ifdef BSD_TM
- if (offset != 0) {
- tmp->tm_zone = WILDABBR;
- } else {
- tmp->tm_zone = gmtptr->chars;
- }
-#endif
-}
-
-struct tm * gmtime_r(const time_t * timep, struct tm * tm)
-{
- gmtsub(timep, 0L, tm);
- return(tm);
-}
-
-struct tm * gmtime(const time_t * timep)
-{
- static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t gmtime_key = -1;
- struct tm * tm;
-
- pthread_mutex_lock(&gmtime_mutex);
- if (gmtime_key < 0) {
- if (pthread_key_create(&gmtime_key, free) < 0) {
- pthread_mutex_unlock(&gmtime_mutex);
- return(NULL);
- }
- }
- pthread_mutex_unlock(&gmtime_mutex);
- if ((tm = pthread_getspecific(gmtime_key)) == NULL) {
- if ((tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) {
- return(NULL);
- }
- pthread_setspecific(gmtime_key, tm);
- }
-
- gmtsub(timep, 0L, tm);
- return(tm);
-}
-
-static void timesub(const time_t * timep, long offset,
- const struct state * sp, struct tm * tmp)
-{
- register const struct lsinfo * lp;
- register long days;
- register long rem;
- register int y;
- register int yleap;
- register const int * ip;
- register long corr;
- register int hit;
- register int i;
-
- corr = 0;
- hit = FALSE;
- i = sp->leapcnt;
- while (--i >= 0) {
- lp = &sp->lsis[i];
- if (*timep >= lp->ls_trans) {
- if (*timep == lp->ls_trans)
- hit = ((i == 0 && lp->ls_corr > 0) ||
- lp->ls_corr > sp->lsis[i - 1].ls_corr);
- corr = lp->ls_corr;
- break;
- }
- }
- days = *timep / SECSPERDAY;
- rem = *timep % SECSPERDAY;
-#ifdef mc68k
- if (*timep == 0x80000000) {
- /*
- ** A 3B1 muffs the division on the most negative number.
- */
- days = -24855;
- rem = -11648;
- }
-#endif /* mc68k */
- rem += (offset - corr);
- while (rem < 0) {
- rem += SECSPERDAY;
- --days;
- }
- while (rem >= SECSPERDAY) {
- rem -= SECSPERDAY;
- ++days;
- }
- tmp->tm_hour = (int) (rem / SECSPERHOUR);
- rem = rem % SECSPERHOUR;
- tmp->tm_min = (int) (rem / SECSPERMIN);
- tmp->tm_sec = (int) (rem % SECSPERMIN);
- if (hit)
- /*
- ** A positive leap second requires a special
- ** representation. This uses "... ??:59:60".
- */
- ++(tmp->tm_sec);
- tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
- if (tmp->tm_wday < 0)
- tmp->tm_wday += DAYSPERWEEK;
- y = EPOCH_YEAR;
- if (days >= 0)
- for ( ; ; ) {
- yleap = isleap(y);
- if (days < (long) year_lengths[yleap])
- break;
- ++y;
- days = days - (long) year_lengths[yleap];
- }
- else do {
- --y;
- yleap = isleap(y);
- days = days + (long) year_lengths[yleap];
- } while (days < 0);
- tmp->tm_year = y - TM_YEAR_BASE;
- tmp->tm_yday = (int) days;
- ip = mon_lengths[yleap];
- for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
- days = days - (long) ip[tmp->tm_mon];
- tmp->tm_mday = (int) (days + 1);
- tmp->tm_isdst = 0;
-#ifdef BSD_TM
- tmp->tm_gmtoff = offset;
-#endif
-}
-
-/*
- * A la X3J11
- *
- * Made thread safe by using thread specific data
- */
-char * asctime_r(const struct tm * timeptr, char * result)
-{
- static const char wday_name[DAYSPERWEEK][3] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
- };
- static const char mon_name[MONSPERYEAR][3] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- (void) sprintf(result, "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n",
- wday_name[timeptr->tm_wday],
- mon_name[timeptr->tm_mon],
- timeptr->tm_mday, timeptr->tm_hour,
- timeptr->tm_min, timeptr->tm_sec,
- TM_YEAR_BASE + timeptr->tm_year);
- return(result);
-}
-
-char * asctime(const struct tm * timeptr)
-{
- static pthread_mutex_t asctime_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t asctime_key = -1;
- char * result;
-
- pthread_mutex_lock(&asctime_mutex);
- if (asctime_key < 0) {
- if (pthread_key_create(&asctime_key, free) < 0) {
- pthread_mutex_unlock(&asctime_mutex);
- return(NULL);
- }
- }
- pthread_mutex_unlock(&asctime_mutex);
- if ((result = pthread_getspecific(asctime_key)) == NULL) {
- if ((result = malloc(26)) == NULL) {
- return(NULL);
- }
- pthread_setspecific(asctime_key, result);
- }
-
- return(asctime_r(timeptr, result));
-}
-
-char * ctime_r(const time_t * timep, char * buf)
-{
- struct tm tm;
- return asctime_r(localtime_r(timep, &tm), buf);
-}
-
-char * ctime(const time_t * timep)
-{
- struct tm tm;
- return asctime(localtime_r(timep, &tm));
-}
-
-/*
-** Adapted from code provided by Robert Elz, who writes:
-** The "best" way to do mktime I think is based on an idea of Bob
-** Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
-** It does a binary search of the time_t space. Since time_t's are
-** just 32 bits, its a max of 32 iterations (even at 64 bits it
-** would still be very reasonable).
-*/
-static void normalize(int * tensptr,int * unitsptr, int base)
-{
- if (*unitsptr >= base) {
- *tensptr += *unitsptr / base;
- *unitsptr %= base;
- } else if (*unitsptr < 0) {
- --*tensptr;
- *unitsptr += base;
- if (*unitsptr < 0) {
- *tensptr -= 1 + (-*unitsptr) / base;
- *unitsptr = base - (-*unitsptr) % base;
- }
- }
-}
-
-static int tmcomp(const struct tm * atmp, const struct tm * btmp)
-{
- register int result;
-
- if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
- (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
- (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
- (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
- (result = (atmp->tm_min - btmp->tm_min)) == 0)
- result = atmp->tm_sec - btmp->tm_sec;
- return result;
-}
-
-static time_t time2(struct tm * tmp, long offset, int * okayp)
-{
- register const struct state * sp;
- register int dir;
- register int bits;
- register int i, j ;
- register int saved_seconds;
- time_t newt;
- time_t t;
- struct tm yourtm, mytm;
-
- *okayp = FALSE;
- yourtm = *tmp;
- if (yourtm.tm_sec >= SECSPERMIN + 2 || yourtm.tm_sec < 0)
- normalize(&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN);
- normalize(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR);
- normalize(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY);
- normalize(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR);
- while (yourtm.tm_mday <= 0) {
- --yourtm.tm_year;
- yourtm.tm_mday +=
- year_lengths[isleap(yourtm.tm_year + TM_YEAR_BASE)];
- }
- for ( ; ; ) {
- i = mon_lengths[isleap(yourtm.tm_year +
- TM_YEAR_BASE)][yourtm.tm_mon];
- if (yourtm.tm_mday <= i)
- break;
- yourtm.tm_mday -= i;
- if (++yourtm.tm_mon >= MONSPERYEAR) {
- yourtm.tm_mon = 0;
- ++yourtm.tm_year;
- }
- }
- saved_seconds = yourtm.tm_sec;
- yourtm.tm_sec = 0;
- /*
- ** Calculate the number of magnitude bits in a time_t
- ** (this works regardless of whether time_t is
- ** signed or unsigned, though lint complains if unsigned).
- */
- for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
- ;
- /*
- ** If time_t is signed, then 0 is the median value,
- ** if time_t is unsigned, then 1 << bits is median.
- */
- t = (t < 0) ? 0 : ((time_t) 1 << bits);
- for ( ; ; ) {
- localsub(&t, offset, &mytm);
- dir = tmcomp(&mytm, &yourtm);
- if (dir != 0) {
- if (bits-- < 0)
- return NOTOK;
- if (bits < 0)
- --t;
- else if (dir > 0)
- t -= (time_t) 1 << bits;
- else t += (time_t) 1 << bits;
- continue;
- }
- if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
- break;
- /*
- ** Right time, wrong type.
- ** Hunt for right time, right type.
- ** It's okay to guess wrong since the guess
- ** gets checked.
- */
- sp = lclptr;
- for (i = 0; i < sp->typecnt; ++i) {
- if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
- continue;
- for (j = 0; j < sp->typecnt; ++j) {
- if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
- continue;
- newt = t + sp->ttis[j].tt_gmtoff -
- sp->ttis[i].tt_gmtoff;
- localsub(&newt, offset, &mytm);
- if (tmcomp(&mytm, &yourtm) != 0)
- continue;
- if (mytm.tm_isdst != yourtm.tm_isdst)
- continue;
- /*
- ** We have a match.
- */
- t = newt;
- goto label;
- }
- }
- return NOTOK;
- }
-label:
- t += saved_seconds;
- localsub(&t, offset, tmp);
- *okayp = TRUE;
- return t;
-}
-
-static time_t time1(struct tm * tmp, long offset)
-{
- const struct state * sp;
- int samei, otheri, okay;
- time_t t;
-
- if (tmp->tm_isdst > 1)
- tmp->tm_isdst = 1;
- t = time2(tmp, offset, &okay);
- if (okay || tmp->tm_isdst < 0)
- return t;
- /*
- ** We're supposed to assume that somebody took a time of one type
- ** and did some math on it that yielded a "struct tm" that's bad.
- ** We try to divine the type they started from and adjust to the
- ** type they need.
- */
- sp = lclptr;
- for (samei = 0; samei < sp->typecnt; ++samei) {
- if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
- continue;
- for (otheri = 0; otheri < sp->typecnt; ++otheri) {
- if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
- continue;
- tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
- sp->ttis[samei].tt_gmtoff;
- tmp->tm_isdst = !tmp->tm_isdst;
- t = time2(tmp, offset, &okay);
- if (okay)
- return t;
- tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
- sp->ttis[samei].tt_gmtoff;
- tmp->tm_isdst = !tmp->tm_isdst;
- }
- }
- return NOTOK;
-}
-
-time_t mktime(struct tm * tmp)
-{
- time_t mktime_return_value;
-
- pthread_mutex_lock(&lcl_mutex);
- if (lcl_is_set == FALSE) {
- tzset_basic();
- }
- mktime_return_value = time1(tmp, 0L);
- pthread_mutex_unlock(&lcl_mutex);
- return(mktime_return_value);
-}
diff --git a/mit-pthreads/gen/difftime.c b/mit-pthreads/gen/difftime.c
deleted file mode 100644
index cddd896e04a..00000000000
--- a/mit-pthreads/gen/difftime.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)difftime.c 5.2 (Berkeley) 6/1/90";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-
-double
-difftime(time1, time0)
- time_t time1, time0;
-{
- return(time1 - time0);
-}
diff --git a/mit-pthreads/gen/directory.c b/mit-pthreads/gen/directory.c
deleted file mode 100644
index d189280fc1f..00000000000
--- a/mit-pthreads/gen/directory.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)closedir.c 5.9 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * One of these structures is malloced to describe the current directory
- * position each time telldir is called. It records the current magic
- * cookie returned by getdirentries and the offset within the buffer
- * associated with that return value.
- */
-struct ddloc {
- struct ddloc *loc_next;/* next structure in list */
- long loc_index; /* key associated with structure */
- long loc_seek; /* magic cookie returned by getdirentries */
- long loc_loc; /* offset of entry in buffer */
-};
-
-static long dd_loccnt = 0; /* Index of entry for sequential telldir's */
-
-#include <errno.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-
-
-/*
- * close a directory.
- */
-int closedir(DIR * dirp)
-{
- void *ptr, *nextptr;
- int fd;
-
- pthread_mutex_lock (dirp->dd_lock);
- fd = dirp->dd_fd;
- dirp->dd_fd = -1;
- dirp->dd_loc = 0;
- for (ptr = (void *)dirp->dd_ddloc; ptr; ptr = nextptr) {
- nextptr = (void *)(((struct ddloc *)ptr)->loc_next);
- free(ptr);
- }
- for (ptr = (void *)dirp->dd_dp; ptr; ptr = nextptr) {
- nextptr = (void *)(((struct __dirent *)ptr)->next);
- free(ptr);
- }
- free((void *)dirp->dd_buf);
- free (dirp->dd_lock);
- free((void *)dirp);
- return(machdep_sys_close(fd));
-}
-
-/*
- * open a directory.
- */
-DIR * opendir(const char * name)
-{
- DIR *dirp;
- int fd;
-
- if ((fd = machdep_sys_open(name, 0)) < 0)
- return NULL;
- if (machdep_sys_fcntl(fd, F_SETFD, 1) < 0 ||
- (dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
- machdep_sys_close (fd);
- return NULL;
- }
- dirp->dd_lock = (pthread_mutex_t*) malloc (sizeof (pthread_mutex_t));
- pthread_mutex_init (dirp->dd_lock, 0);
- /*
- * If CLSIZE is an exact multiple of DIRBLKSIZ, use a CLSIZE
- * buffer that it cluster boundary aligned.
- * Hopefully this can be a big win someday by allowing page trades
- * to user space to be done by getdirentries()
- */
-#ifndef CLSIZE
-#define CLSIZE 1
-#endif
- if ((CLSIZE % DIRBLKSIZ) == 0) {
- dirp->dd_buf = malloc(CLSIZE);
- dirp->dd_len = CLSIZE;
- } else {
- dirp->dd_buf = malloc(DIRBLKSIZ);
- dirp->dd_len = DIRBLKSIZ;
- }
- if (dirp->dd_buf == NULL) {
- machdep_sys_close (fd);
- free((void *)dirp);
- return NULL;
- }
-
- dirp->dd_ddloc = NULL;
- dirp->dd_dp = NULL;
- dirp->dd_seek = 0;
- dirp->dd_loc = 0;
- dirp->dd_fd = fd;
- return(dirp);
-}
-
-/*
- * The real work in gettint the next entry in a directory.
- * Return
- * NULL on End of directory
- * &ERR on Error
- * dp on valid directory;
- */
-static struct dirent ERR;
-static struct dirent * readdir_basic(DIR * dirp)
-{
- register struct dirent *dp;
-
- for (;;) {
- if (dirp->dd_loc == 0) {
- dirp->dd_size = machdep_sys_getdirentries(dirp->dd_fd,
- dirp->dd_buf, dirp->dd_len, &dirp->dd_seek);
- if (dirp->dd_size < 0)
- return(&ERR);
- if (dirp->dd_size == 0)
- return(NULL);
- }
- if (dirp->dd_loc >= dirp->dd_size) {
- dirp->dd_loc = 0;
- continue;
- }
- dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
- if ((long)dp & 03) /* bogus pointer check */
- return(&ERR);
- if (dp->d_reclen <= 0 ||
- dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc)
- return(&ERR);
- dirp->dd_loc += dp->d_reclen;
- if (dp->d_ino == 0)
- continue;
- return(dp);
- }
-}
-
-/*
- * POSIX.1 version of getting the next entry in a directory.
- */
-struct dirent * readdir(DIR * dirp)
-{
- register struct dirent * rp;
- struct __dirent * my__dp;
- pthread_t self;
-
- pthread_mutex_lock (dirp->dd_lock);
-
- self = pthread_self();
- /* Allocate space and return */
- for (my__dp = dirp->dd_dp; my__dp; my__dp = my__dp->next) {
- if (pthread_equal(my__dp->owner, self)) {
- break;
- }
- }
- if (my__dp == NULL) {
- if (my__dp = (struct __dirent *)(malloc(sizeof(struct __dirent)))) {
- my__dp->next = dirp->dd_dp;
- dirp->dd_dp = my__dp;
- my__dp->owner = self;
- } else {
- pthread_mutex_unlock (dirp->dd_lock);
- return(NULL);
- }
- }
- if (rp = readdir_basic(dirp)) {
- if (rp != &ERR) {
- memcpy(& (my__dp->data), rp, sizeof(struct dirent));
- rp = & (my__dp->data);
- } else {
- rp = NULL;
- }
- }
- pthread_mutex_unlock (dirp->dd_lock);
- return(rp);
-}
-
-/*
- * POSIX.4a version of getting the next entry in a directory.
- */
-int readdir_r(DIR * dirp, struct dirent * entry, struct dirent ** result)
-{
- register struct dirent * rp;
- int ret;
-
- pthread_mutex_lock (dirp->dd_lock);
- rp = readdir_basic(dirp);
- if (rp != &ERR) {
- if (rp) {
- memcpy(entry, rp, sizeof(struct dirent));
- *result = entry;
- ret = 0;
- } else {
- *result = NULL;
- ret = 0;
- }
- } else {
- /* Should get it from errno */
- ret = EBADF;
- }
- pthread_mutex_unlock (dirp->dd_lock);
- return(ret);
-}
-
-void rewinddir(DIR * dirp)
-{
- pthread_mutex_lock (dirp->dd_lock);
- (void)machdep_sys_lseek(dirp->dd_fd, 0, 0);
- dirp->dd_seek = 0;
- dirp->dd_loc = 0;
- pthread_mutex_unlock (dirp->dd_lock);
-}
-
-/*
- * Seek to an entry in a directory.
- * _seekdir is in telldir.c so that it can share opaque data structures.
- *
- * Use the POSIX reentrant safe readdir_r to simplify varifying POSIX
- * thread-safe compliance.
- */
-void seekdir(DIR * dirp, long loc)
-{
- register struct ddloc ** prevlp;
- register struct ddloc * lp;
- struct dirent * dp;
- struct dirent de;
-
- pthread_mutex_lock (dirp->dd_lock);
- prevlp = (struct ddloc **)&(dirp->dd_ddloc);
- lp = *prevlp;
- while (lp != NULL) {
- if (lp->loc_index == loc)
- break;
- prevlp = &lp->loc_next;
- lp = lp->loc_next;
- }
- if (lp) {
- if (lp->loc_seek != dirp->dd_seek) {
- if (machdep_sys_lseek(dirp->dd_fd, lp->loc_seek, 0) < 0) {
- *prevlp = lp->loc_next;
- pthread_mutex_unlock (dirp->dd_lock);
- return;
- }
- dirp->dd_seek = lp->loc_seek;
- dirp->dd_loc = 0;
- while (dirp->dd_loc < lp->loc_loc) {
- if (readdir_r(dirp, &de, &dp)) {
- *prevlp = lp->loc_next;
- break;
- }
- }
- }
- }
- pthread_mutex_unlock (dirp->dd_lock);
-}
-
-/*
- * return a pointer into a directory
- */
-long telldir(DIR *dirp)
-{
- struct ddloc *lp, **fakeout;
- int ret;
-
- pthread_mutex_lock (dirp->dd_lock);
- if (lp = (struct ddloc *)malloc(sizeof(struct ddloc))) {
- lp->loc_index = dd_loccnt++;
- lp->loc_seek = dirp->dd_seek;
- lp->loc_loc = dirp->dd_loc;
- lp->loc_next = dirp->dd_ddloc;
-
- /* Compiler won't let us change anything pointed to by db directly */
- /* So we fake to the left and do it anyway */
- /* Wonder if the compile optomizes it to the correct solution */
- fakeout = (struct ddloc **)&(dirp->dd_ddloc);
- *fakeout = lp;
-
- ret = lp->loc_index;
- } else {
- ret = -1;
- }
- pthread_mutex_unlock (dirp->dd_lock);
- return(ret);
-}
-
diff --git a/mit-pthreads/gen/eprintf.c b/mit-pthreads/gen/eprintf.c
deleted file mode 100644
index bcc65757bd4..00000000000
--- a/mit-pthreads/gen/eprintf.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This function is a replacement for the version in libgcc.a. This
- is needed because typically libgcc.a won't have been compiled
- against the threads library, so its references to "stderr" will
- come out wrong. */
-
-#include <stdio.h>
-
-void __eprintf (const char *fmt, const char *expr, int line, const char *file)
-{
- /* Considering the very special circumstances where this function
- would be called, perhaps we might want to disable the thread
- scheduler and break any existing locks on stderr? Well, maybe if
- we could be sure that stderr was in a useable state... */
- fprintf (stderr, fmt, expr, line, file);
- fflush (stderr);
-
- abort ();
-}
diff --git a/mit-pthreads/gen/getcwd.c b/mit-pthreads/gen/getcwd.c
deleted file mode 100644
index 9c1b089f26e..00000000000
--- a/mit-pthreads/gen/getcwd.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 1989, 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getcwd.c 5.11 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define ISDOT(dp) \
- (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
- dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
-
-
-/* Only use reentrant safe routines to simplify varifying POSIX thread-safe
- * compliance. (mevans).
- */
-
-char *
-getcwd(pt, size)
- char *pt;
- size_t size;
-{
- register DIR *dir;
- register dev_t dev;
- register ino_t ino;
- register int first;
- register char *bpt, *bup;
- struct stat s;
- struct dirent *dp;
- struct dirent de;
- dev_t root_dev;
- ino_t root_ino;
- size_t ptsize, upsize;
- int save_errno;
- char *ept, *eup, *up;
- int namelen;
-
- /*
- * If no buffer specified by the user, allocate one as necessary.
- * If a buffer is specified, the size has to be non-zero. The path
- * is built from the end of the buffer backwards.
- */
- if (pt) {
- ptsize = 0;
- if (!size) {
- errno = EINVAL;
- return((char *)NULL);
- }
- ept = pt + size;
- } else {
- if (!(pt = (char *)malloc(ptsize = 1024 - 4)))
- return((char *)NULL);
- ept = pt + ptsize;
- }
- bpt = ept - 1;
- *bpt = '\0';
-
- /*
- * Allocate bytes (1024 - malloc space) for the string of "../"'s.
- * Should always be enough (it's 340 levels). If it's not, allocate
- * as necessary. Special * case the first stat, it's ".", not "..".
- */
- if (!(up = (char *)malloc(upsize = 1024 - 4)))
- goto err;
- eup = up + MAXPATHLEN;
- bup = up;
- up[0] = '.';
- up[1] = '\0';
-
- /* Save root values, so know when to stop. */
- if (stat("/", &s))
- goto err;
- root_dev = s.st_dev;
- root_ino = s.st_ino;
-
- SET_ERRNO(0);
-
- for (first = 1;; first = 0) {
- /* Stat the current level. */
- if (lstat(up, &s))
- goto err;
-
- /* Save current node values. */
- ino = s.st_ino;
- dev = s.st_dev;
-
- /* Check for reaching root. */
- if (root_dev == dev && root_ino == ino) {
- *--bpt = '/';
- /*
- * It's unclear that it's a requirement to copy the
- * path to the beginning of the buffer, but it's always
- * been that way and stuff would probably break.
- */
- /* XXX was bcopy */
- (void)memcpy(pt, bpt, ept - bpt);
- free(up);
- return(pt);
- }
-
- /*
- * Build pointer to the parent directory, allocating memory
- * as necessary. Max length is 3 for "../", the largest
- * possible component name, plus a trailing NULL.
- */
- if (bup + 3 + MAXNAMLEN + 1 >= eup) {
- if (!(up = (char *)realloc(up, upsize *= 2)))
- goto err;
- eup = up + upsize;
- }
- *bup++ = '.';
- *bup++ = '.';
- *bup = '\0';
-
- /* Open and stat parent directory. */
- /* XXX opendir() returns kernel fd's instead of
- pthread fd's for some odd reason, so we must
- break the abstraction boundry here as well or
- fix everything in opendir et al. SNL */
- if (!(dir = opendir(up)) ||
- machdep_sys_fstat(dirfd(dir), &s))
- goto err;
-
- /* Add trailing slash for next directory. */
- *bup++ = '/';
-
- /*
- * If it's a mount point, have to stat each element because
- * the inode number in the directory is for the entry in the
- * parent directory, not the inode number of the mounted file.
- */
- save_errno = 0;
- if (s.st_dev == dev) {
- for (;;) {
- if (readdir_r(dir, &de, &dp))
- goto notfound;
- if (dp->d_fileno == ino)
- break;
- }
- } else
- for (;;) {
- if (readdir_r(dir, &de, &dp))
- goto notfound;
- if (ISDOT(dp))
- continue;
- memcpy(bup, dp->d_name, strlen(dp->d_name) + 1);
-
- /* Save the first error for later. */
- if (lstat(up, &s)) {
- if (!save_errno)
- save_errno = errno;
- SET_ERRNO(0);
- continue;
- }
- if (s.st_dev == dev && s.st_ino == ino)
- break;
- }
-
- /*
- * Check for length of the current name, preceding slash,
- * leading slash.
- */
- namelen = strlen(dp->d_name);
- if (bpt - pt <= namelen + (first ? 1 : 2)) {
- size_t len, off;
-
- if (!ptsize) {
- SET_ERRNO(ERANGE);
- goto err;
- }
- off = bpt - pt;
- len = ept - bpt;
- if (!(pt = (char *)realloc(pt, ptsize *= 2)))
- goto err;
- bpt = pt + off;
- ept = pt + ptsize;
- /* XXX was bcopy */
- (void)memcpy(ept - len, bpt, len);
- bpt = ept - len;
- }
- if (!first)
- *--bpt = '/';
- bpt -= namelen;
- memcpy(bpt, dp->d_name, namelen);
- (void)closedir(dir);
-
- /* Truncate any file name. */
- *bup = '\0';
- }
-
-notfound:
- /*
- * If readdir set errno, use it, not any saved error; otherwise,
- * didn't find the current directory in its parent directory, set
- * errno to ENOENT.
- */
- if (!errno) {
- if (!save_errno)
- save_errno = ENOENT;
- SET_ERRNO(save_errno);
- }
- /* FALLTHROUGH */
-err:
- if (ptsize)
- free(pt);
- free(up);
- return((char *)NULL);
-}
diff --git a/mit-pthreads/gen/getpwent.c b/mit-pthreads/gen/getpwent.c
deleted file mode 100644
index 7bcb2cbd610..00000000000
--- a/mit-pthreads/gen/getpwent.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 1984 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getpwent.c 5.2 (Berkeley) 3/9/86";
-#endif
-
-#include <pthread.h>
-#include <stdio.h>
-#include <pwd.h>
-#include "pwd_internal.h"
-
-void
-setpwent()
-{
- pwf_context_t *_data;
-
- _data = _pw_get_data();
-
- if (_data) {
- if (_data->pwf == NULL)
- _data->pwf = fopen(_data->pw_file, "r");
- else
- rewind(_data->pwf);
- }
-}
-
-void
-endpwent()
-{
- pwf_context_t *_data;
-
- _data = _pw_get_data();
-
- if (_data) {
- if (_data->pwf != NULL) {
- fclose(_data->pwf);
- _data->pwf = NULL;
- }
-#ifdef DBM_PWD_SUPPORT
- if (_data->pw_db != (DBM *)0) {
- dbm_close(_data->pw_db);
- _data->pw_db = (DBM *)0;
- _data->pw_stayopen = 0;
- }
-#endif /* DBM_PWD_SUPPORT */
- }
-}
-
-static char *
-pwskip(p)
- char *p;
-{
- while (*p && *p != ':' && *p != '\n')
- ++p;
- if (*p)
- *p++ = 0;
- return(p);
-}
-
-struct passwd *
-getpwent()
-{
- pwf_context_t *_data;
- char *p;
-
- _data = _pw_get_data();
- if (!_data)
- return 0;
-
- if (_data->pwf == NULL) {
- if ((_data->pwf = fopen(_data->pw_file, "r" )) == NULL)
- return(0);
- }
- p = fgets(_data->line, BUFSIZ, _data->pwf);
- if (p == NULL)
- return(0);
- _data->passwd.pw_name = p;
- p = pwskip(p);
- _data->passwd.pw_passwd = p;
- p = pwskip(p);
- _data->passwd.pw_uid = atoi(p);
- p = pwskip(p);
- _data->passwd.pw_gid = atoi(p);
- p = pwskip(p);
- _data->passwd.pw_gecos = p;
- p = pwskip(p);
- _data->passwd.pw_dir = p;
- p = pwskip(p);
- _data->passwd.pw_shell = p;
- while (*p && *p != '\n')
- p++;
- *p = '\0';
- return(&_data->passwd);
-}
-
-void
-setpwfile(file)
- char *file;
-{
- pwf_context_t *_data;
-
- _data = _pw_get_data();
- if (_data)
- _data->pw_file = file;
-}
diff --git a/mit-pthreads/gen/getpwnamuid.c b/mit-pthreads/gen/getpwnamuid.c
deleted file mode 100644
index 0e87081b7a9..00000000000
--- a/mit-pthreads/gen/getpwnamuid.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getpwnamuid.c 5.3 (Berkeley) 12/21/87";
-#endif
-
-#include <stdio.h>
-#include <pwd.h>
-#include <sys/file.h>
-#include "pwd_internal.h"
-
-/*
- * The following are shared with getpwent.c
- */
-
-#ifdef DBM_PWD_SUPPORT
-static struct passwd *
-fetchpw(key)
- datum key;
-{
- char *cp, *tp;
- pwf_context_t *_data;
-
- _data = _pw_get_data();
- if (!_data)
- return 0;
- if (key.dptr == 0)
- return ((struct passwd *)NULL);
- key = dbm_fetch(_data->pw_db, key);
- if (key.dptr == 0)
- return ((struct passwd *)NULL);
- cp = key.dptr;
- tp = _data->line;
-
-#define EXPAND(e) _data->passwd.e = tp; while (*tp++ = *cp++);
- EXPAND(pw_name);
- EXPAND(pw_passwd);
- memcpy((char *)&_data->passwd.pw_uid, cp, sizeof (int));
- cp += sizeof (int);
- memcpy((char *)&_data->passwd.pw_gid, cp, sizeof (int));
- cp += sizeof (int);
- EXPAND(pw_gecos);
- EXPAND(pw_dir);
- EXPAND(pw_shell);
- return (&_data->passwd);
-}
-#endif /* DBM_PWD_SUPPORT */
-
-struct passwd *
-getpwnam(nam)
- const char *nam;
-{
-#ifdef DBM_PWD_SUPPORT
- datum key;
-#endif
- struct passwd *pw, *getpwent();
- pwf_context_t *_data;
-
- _data = _pw_get_data();
- if (!_data)
- return 0;
-
-#ifdef DBM_PWD_SUPPORT
- if (_data->pw_db == (DBM *)0 &&
- (_data->pw_db = dbm_open(_data->pw_file, O_RDONLY)) == (DBM *)0) {
- oldcode:
-#endif
- setpwent();
- while ((pw = getpwent()) && strcmp(nam, pw->pw_name))
- ;
- if (!_data->pw_stayopen)
- endpwent();
- return (pw);
-#ifdef DBM_PWD_SUPPORT
- }
- if (flock(dbm_dirfno(_data->pw_db), LOCK_SH) < 0) {
- dbm_close(_data->pw_db);
- _data->pw_db = (DBM *)0;
- goto oldcode;
- }
- key.dptr = nam;
- key.dsize = strlen(nam);
- pw = fetchpw(key);
- (void) flock(dbm_dirfno(_data->pw_db), LOCK_UN);
- if (!_data->pw_stayopen) {
- dbm_close(_data->pw_db);
- _data->pw_db = (DBM *)0;
- }
- return (pw);
-#endif
-}
-
-struct passwd *
-getpwuid(uid)
- uid_t uid;
-{
-#ifdef DBM_PWD_SUPPORT
- datum key;
-#endif
- struct passwd *pw, *getpwent();
- pwf_context_t *_data;
-
- _data = _pw_get_data();
- if (!_data)
- return 0;
-#ifdef DBM_PWD_SUPPORT
- if (_data->pw_db == (DBM *)0 &&
- (_data->pw_db = dbm_open(_data->pw_file, O_RDONLY)) == (DBM *)0) {
- oldcode:
-#endif
- setpwent();
- while ((pw = getpwent()) && pw->pw_uid != uid)
- ;
- if (!_data->pw_stayopen)
- endpwent();
- return (pw);
-#ifdef DBM_PWD_SUPPORT
- }
- if (flock(dbm_dirfno(_data->pw_db), LOCK_SH) < 0) {
- dbm_close(_data->pw_db);
- _data->pw_db = (DBM *)0;
- goto oldcode;
- }
- key.dptr = (char *) &uid;
- key.dsize = sizeof uid;
- pw = fetchpw(key);
- (void) flock(dbm_dirfno(_data->pw_db), LOCK_UN);
- if (!_data->pw_stayopen) {
- dbm_close(_data->pw_db);
- _data->pw_db = (DBM *)0;
- }
- return (pw);
-#endif
-}
diff --git a/mit-pthreads/gen/getwd.c b/mit-pthreads/gen/getwd.c
deleted file mode 100644
index 7fdceda0f45..00000000000
--- a/mit-pthreads/gen/getwd.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getwd.c 5.1 (Berkeley) 2/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-char *
-getwd(buf)
- char *buf;
-{
- char *p;
- char *strerror();
-
- if (p = getcwd(buf, MAXPATHLEN))
- return(p);
- (void)strcpy(buf, strerror(errno));
- return((char *)NULL);
-}
diff --git a/mit-pthreads/gen/isatty.c b/mit-pthreads/gen/isatty.c
deleted file mode 100644
index a22f13015d9..00000000000
--- a/mit-pthreads/gen/isatty.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)isatty.c 5.6 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#ifdef sunos4
-#include <sys/termio.h>
-#else
-#include <termios.h>
-#endif
-#include <unistd.h>
-
-/*
- * If TIOCGETA is not defined try TCGETATTR
- * If TCGETATTR is not defined try TCGETA
- * If that doesn't work try getting it from termio.h
- */
-#ifndef TIOCGETA
-#ifdef TCGETATTR
-#define TIOCGETA TCGETATTR
-#else
-#ifndef TCGETA
-#include <termio.h>
-#endif
-#ifndef TIOCGETA
-#define TIOCGETA TCGETA
-#endif
-#endif
-#endif
-
-/* fd is the real fd to pass to the kernel */
-int isatty_basic(int fd)
-{
-#ifdef sunos4
- struct termio t;
-#else /* !sunos4 */
- struct termios t;
-#endif /* sunos4 */
- return (machdep_sys_ioctl(fd,
-#ifdef sunos4
- TCGETA,
-#else /* !sunos4 */
- TIOCGETA,
-#endif /* sunos4 */
- &t) ? 0 : 1);
-}
-
-int isatty(int fd)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- ret = isatty_basic(fd_table[fd]->fd.i);
- fd_unlock(fd, FD_READ);
- } else {
- /* Return 0 or 1 */
- ret = 0;
- }
- return(ret);
-}
-
diff --git a/mit-pthreads/gen/popen.c b/mit-pthreads/gen/popen.c
deleted file mode 100644
index c15fbdce1fe..00000000000
--- a/mit-pthreads/gen/popen.c
+++ /dev/null
@@ -1,117 +0,0 @@
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-static pid_t *pids = NULL;
-static int pids_size = 0;
-static int pids_top = 0;
-static pthread_mutex_t pids_lock = PTHREAD_MUTEX_INITIALIZER;
-
-FILE *popen(const char *cmd, const char *mode)
-{
- int fds[2], parent_fd, child_fd, child_target, new_size, i;
- pid_t pid, *new_pids;
-
- /* Verify the mode. */
- if ((*mode != 'r' && *mode != 'w') || mode[1] != 0)
- return NULL;
-
- /* Generate fds, and choose the parent and child fds. */
- if (pipe(fds) < 0)
- return NULL;
- parent_fd = (*mode == 'r') ? fds[0] : fds[1];
- child_fd = (*mode == 'r') ? fds[1] : fds[0];
-
- /* Ensure that there is space in the pid table. */
- pthread_mutex_lock(&pids_lock);
- if (pids_size <= parent_fd) {
- new_size = parent_fd + 1;
- if ((new_pids = malloc(new_size * sizeof(pid_t))) == NULL) {
- pthread_mutex_unlock(&pids_lock);
- close(parent_fd);
- close(child_fd);
- return NULL;
- }
- if (pids) {
- memcpy(new_pids, pids, pids_size * sizeof(pid_t));
- free(pids);
- }
- while (pids_size < new_size)
- new_pids[pids_size++] = -1;
- pids = new_pids;
- }
- pthread_mutex_unlock(&pids_lock);
-
- /* Fork off a child process. */
- switch (pid = fork()) {
- case -1: /* Failed to fork. */
- close(parent_fd);
- close(child_fd);
- return NULL;
- break;
- case 0: /* Child */
- /*
- * Set the child fd to stdout or stdin as appropriate,
- * and close the parent fd.
- */
- child_target = (*mode == 'r') ? STDOUT_FILENO : STDIN_FILENO;
- if (child_fd != child_target) {
- dup2(child_fd, child_target);
- close(child_fd);
- }
- close(parent_fd);
-
- /* Close all parent fds from previous popens(). */
- for (i = 0; i < pids_top; i++) {
- if (pids[i] != -1)
- close(i);
- }
-
- execl("/bin/sh", "sh", "-c", cmd, NULL);
- exit(1);
- default:
- break;
- }
-
- /* Record the parent fd in the pids table. */
- pthread_mutex_lock(&pids_lock);
- pids[parent_fd] = pid;
- if (pids_top < parent_fd + 1)
- pids_top = parent_fd + 1;
- pthread_mutex_unlock(&pids_lock);
-
- /* Close the child fd and return a stdio buffer for the parent fd. */
- close(child_fd);
- return fdopen(parent_fd, mode);
-}
-
-int pclose(fp)
- FILE *fp;
-{
- pid_t pid, result;
- int fd, pstat;
-
- fd = fileno(fp);
- pthread_mutex_lock(&pids_lock);
- /* Make sure this is a popened file. */
- if ((pids_top <= fd) || ((pid = pids[fd]) == -1)) {
- pthread_mutex_unlock(&pids_lock);
- return -1;
- }
- pids[fd] = -1;
- while (pids_top > 0 && pids[pids_top - 1] == -1)
- pids_top--;
- pthread_mutex_unlock(&pids_lock);
-
- fclose(fp);
-
- /* Wait for the subprocess to quit. */
- return (((result = waitpid(pid, &pstat, 0)) == -1) ? -1 : pstat);
-}
-
diff --git a/mit-pthreads/gen/pwd_internal.c b/mit-pthreads/gen/pwd_internal.c
deleted file mode 100644
index b0ebc27b5c6..00000000000
--- a/mit-pthreads/gen/pwd_internal.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ==== pwd_internal.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Thread-safe password hacking functions.
- *
- * 1.00 95/02/08 snl
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <pwd.h>
-#include <unistd.h>
-#include "pwd_internal.h"
-
-static pthread_once_t __pw_init = PTHREAD_ONCE_INIT;
-static pthread_key_t __pw_key;
-
-void
-_pw_null_cleanup(void *junkola)
-{
- pwf_context_t *x = (pwf_context_t *)junkola;
-
- if (x) {
- if (x->pwf) {
- fclose(x->pwf);
- x->pwf = 0;
- }
-#ifdef DBM_PWD_SUPPORT
- if (x->pw_db) {
- dbm_close(x->pw_db);
- x->pw_db = 0;
- }
-#endif /* DBM_PWD_SUPPORT */
- free((void *)x);
- }
-}
-
-void
-_pw_create_key()
-{
- if (pthread_key_create(&__pw_key, _pw_null_cleanup)) {
- PANIC();
- }
-}
-
-pwf_context_t *
-_pw_get_data()
-{
- pwf_context_t *_data;
-
- pthread_once(&__pw_init, _pw_create_key);
- _data = (pwf_context_t *)pthread_getspecific(__pw_key);
- if (!_data) {
- _data = (pwf_context_t *)malloc(sizeof(pwf_context_t));
- if (_data) {
- _data->pwf = 0;
- _data->line[0] = '\0';
- _data->pw_stayopen = 0;
- _data->pw_file = "/etc/passwd";
-#ifdef DBM_PWD_SUPPORT
- _data->pw_db = 0;
-#endif /* DBM_PWD_SUPPORT */
- pthread_setspecific(__pw_key, (void *)_data);
- }
- }
- return _data;
-}
diff --git a/mit-pthreads/gen/pwd_internal.h b/mit-pthreads/gen/pwd_internal.h
deleted file mode 100644
index 10fdab6cc4e..00000000000
--- a/mit-pthreads/gen/pwd_internal.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _PWD_INTERNAL_H_
-#define _PWD_INTERNAL_H_
-
-#if 0 /* Turn this off for now until we suck in ndbm or use gdbm -- SNL */
-#ifndef DBM_PWD_SUPPORT
-#if !defined(__alpha) && !defined(linux) && !defined(hpux)
-#define DBM_PWD_SUPPORT 1
-#endif /* !alpha && !linux && !hpux */
-#endif /* !DBM_PWD_SUPPORT */
-#endif
-
-#ifdef DBM_PWD_SUPPORT
-#include <ndbm.h>
-#endif /* DBM_PWD_SUPPORT */
-
-typedef struct pwf_context {
- FILE *pwf;
- char line[BUFSIZ+1];
- struct passwd passwd;
- int pw_stayopen;
- char *pw_file;
-#ifdef DBM_PWD_SUPPORT
- DBM *pw_db;
-#endif /* DBM_PWD_SUPPORT */
-} pwf_context_t;
-
-pwf_context_t *_pw_get_data __P_((void));
-
-#endif /* _PWD_INTERNAL_H_ */
diff --git a/mit-pthreads/gen/syslog.c b/mit-pthreads/gen/syslog.c
deleted file mode 100644
index e49795ecb69..00000000000
--- a/mit-pthreads/gen/syslog.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 1983, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of California at Berkeley. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)syslog.c 5.14 (Berkeley) 5/20/88";
-#endif /* LIBC_SCCS and not lint */
-
-
-/*
- * SYSLOG -- print message on log file
- *
- * This routine looks a lot like printf, except that it
- * outputs to the log file instead of the standard output.
- * Also:
- * adds a timestamp,
- * prints the module name in front of the message,
- * has some other formatting types (or will sometime),
- * adds a newline on the end of the message.
- *
- * The output of this routine is intended to be read by /etc/syslogd.
- *
- * Author: Eric Allman
- * Modified to use UNIX domain IPC by Ralph Campbell
- * Modified for pthreads and made more POSIX-compliant by Greg Hudson
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <errno.h>
-#include <syslog.h>
-
-int socket();
-char *strerror(int); /* For systems that don't prototype it */
-
-#define MAXLINE 1024 /* max message size */
-
-#define PRIFAC(p) (((p) & LOG_FACMASK) >> 3)
- /* XXX should be in <syslog.h> */
-#define IMPORTANT LOG_ERR
-
-static void basic_init(void);
-
-static char _log_name[] = "/dev/log";
-static char ctty[] = "/dev/console";
-
-static int LogFile = -1; /* fd for log */
-static int LogStat = 0; /* status bits, set by openlog() */
-static char *LogTag = "syslog"; /* string to tag the entry with */
-static int LogMask = 0xff; /* mask of priorities to be logged */
-static int LogFacility = LOG_USER; /* default facility code */
-
-static pthread_mutex_t basic_init_lock = PTHREAD_MUTEX_INITIALIZER;
-
-static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
-
-static void basic_init()
-{
- pthread_mutex_lock(&basic_init_lock);
- if (LogFile < 0)
- openlog(LogTag, LogStat | LOG_NDELAY, 0);
- pthread_mutex_unlock(&basic_init_lock);
-}
-
-void syslog(int pri, char *fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- vsyslog(pri, fmt, args);
- va_end(args);
-}
-
-void vsyslog(int pri, char *fmt, va_list args)
-{
- char buf[MAXLINE + 1], outline[MAXLINE + 1];
- register char *b, *f, *o;
- register int c;
- time_t now;
- int olderrno = errno, fd;
-
- /* Do a basic initialization if user didn't call openlog(). */
- if (LogFile < 0)
- basic_init();
-
- /* see if we should just throw out this message */
- if ((unsigned) PRIFAC(pri) >= LOG_NFACILITIES ||
- (LOG_MASK(pri & LOG_PRIMASK) & LogMask) == 0 ||
- (pri &~ (LOG_PRIMASK|LOG_FACMASK)) != 0)
- return;
-
- /* set default facility if none specified */
- if ((pri & LOG_FACMASK) == 0)
- pri |= LogFacility;
-
- /* build the message */
- o = outline;
- (void)sprintf(o, "<%d>", pri);
- o += strlen(o);
- time(&now);
- (void)sprintf(o, "%.15s ", ctime(&now) + 4);
- o += strlen(o);
- if (LogTag) {
- strcpy(o, LogTag);
- o += strlen(o);
- }
- if (LogStat & LOG_PID) {
- (void)sprintf(o, "[%d]", getpid());
- o += strlen(o);
- }
- if (LogTag) {
- strcpy(o, ": ");
- o += 2;
- }
-
- b = buf;
- f = fmt;
- while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
- char *strerror();
-
- if (c != '%') {
- *b++ = c;
- continue;
- }
- if ((c = *f++) != 'm') {
- *b++ = '%';
- *b++ = c;
- continue;
- }
- strcpy(b, strerror(olderrno));
- b += strlen(b);
- }
- *b++ = '\n';
- *b = '\0';
- vsprintf(o, buf, args);
- c = strlen(outline);
- if (c > MAXLINE)
- c = MAXLINE;
-
- /* output the message to the local logger */
- if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
- return;
- if (!(LogStat & LOG_CONS))
- return;
-
- /* output the message to the console */
- fd = open(ctty, O_WRONLY);
- alarm(0);
- strcat(o, "\r");
- o = strchr(outline, '>') + 1;
- write(fd, o, c + 1 - (o - outline));
- close(fd);
-}
-
-/*
- * OPENLOG -- open system log
- */
-
-void openlog(char *ident, int logstat, int logfac)
-{
- int flags;
-
- if (ident != NULL)
- LogTag = ident;
- LogStat = logstat;
- if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
- LogFacility = logfac;
- if (LogFile >= 0)
- return;
- SyslogAddr.sa_family = AF_UNIX;
- strncpy(SyslogAddr.sa_data, _log_name, sizeof SyslogAddr.sa_data);
- if (LogStat & LOG_NDELAY) {
- LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
- flags = fcntl(LogFile, F_GETFD);
- fcntl(LogFile, F_SETFD, flags & O_NONBLOCK);
- }
-}
-
-/*
- * CLOSELOG -- close the system log
- */
-
-void closelog()
-{
- (void) close(LogFile);
- LogFile = -1;
-}
-
-/*
- * SETLOGMASK -- set the log mask level
- */
-int setlogmask(int pmask)
-{
- int omask;
-
- omask = LogMask;
- if (pmask != 0)
- LogMask = pmask;
- return (omask);
-}
diff --git a/mit-pthreads/gen/time.c b/mit-pthreads/gen/time.c
deleted file mode 100644
index 82eec7edc1e..00000000000
--- a/mit-pthreads/gen/time.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)time.c 5.6 (Berkeley) 6/1/90";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/time.h>
-
-time_t time(time_t * t)
-{
- struct timeval tt;
-
- if (gettimeofday(&tt, (struct timezone *)0) < 0)
- return(-1);
- if (t)
- *t = tt.tv_sec;
- return(tt.tv_sec);
-}
diff --git a/mit-pthreads/gen/ttyname.c b/mit-pthreads/gen/ttyname.c
deleted file mode 100644
index b7a04485f79..00000000000
--- a/mit-pthreads/gen/ttyname.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ttyname.c 5.10 (Berkeley) 5/6/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include "config.h"
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-
-static pthread_mutex_t ttyname_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_key_t ttyname_key;
-static int ttyname_init = 0;
-extern void free();
-
-char * __ttyname_r_basic(int fd, char * buf, size_t len)
-{
- register struct dirent *dirp;
- register DIR *dp;
- struct stat dsb;
- struct stat sb;
- char * rval;
- int minlen;
-
- rval = NULL;
-
- /* Must be a terminal. */
- if (! isatty_basic(fd))
- return(rval);
- /* Must be a character device. */
- if (machdep_sys_fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
- return(rval);
- /* Must have enough room */
- if (len <= sizeof(_PATH_PTY))
- return(rval);
-
- if ((dp = opendir(_PATH_PTY)) != NULL) {
- memcpy(buf, _PATH_PTY, sizeof(_PATH_PTY));
- for (rval = NULL; dirp = readdir(dp);) {
- if (dirp->d_fileno != sb.st_ino)
- continue;
- minlen = (len - (sizeof(_PATH_PTY) - 1)) < (dirp->d_namlen + 1) ?
- (len - (sizeof(_PATH_PTY) - 1)) : (dirp->d_namlen + 1);
- memcpy (buf + sizeof(_PATH_PTY) - 1, dirp->d_name, minlen);
- if (stat(buf, &dsb) || sb.st_dev != dsb.st_dev ||
- sb.st_ino != dsb.st_ino)
- continue;
- rval = buf;
- break;
- }
- (void)closedir(dp);
- }
- return(rval);
-}
-
-char * __ttyname_basic(int fd)
-{
- char *buf;
-
- pthread_mutex_lock (&ttyname_lock);
- if (ttyname_init == 0) {
- if (pthread_key_create(&ttyname_key, free)) {
- pthread_mutex_unlock (&ttyname_lock);
- return(NULL);
- }
- ttyname_init = 1;
- }
- pthread_mutex_unlock (&ttyname_lock);
-
- /* Must have thread specific data field to put data */
- if ((buf = pthread_getspecific(ttyname_key)) == NULL) {
- if (buf = malloc(sizeof(_PATH_PTY) + MAXNAMLEN)) {
- if (pthread_setspecific(ttyname_key, buf) != OK) {
- free(buf);
- return(NULL);
- }
- } else {
- return(NULL);
- }
- }
- return(__ttyname_r_basic(fd, buf, sizeof(_PATH_PTY) + MAXNAMLEN));
-}
-
-char * ttyname_r(int fd, char * buf, size_t len)
-{
- char * ret;
-
- if (fd_lock(fd, FD_READ) == OK) {
- ret = __ttyname_r_basic(fd_table[fd]->fd.i, buf, len);
- fd_unlock(fd, FD_READ);
- } else {
- ret = NULL;
- }
- return(ret);
-}
-
-char * ttyname(int fd)
-{
- char * ret;
-
- if (fd_lock(fd, FD_READ) == OK) {
- ret = __ttyname_basic(fd_table[fd]->fd.i);
- fd_unlock(fd, FD_READ);
- } else {
- ret = NULL;
- }
- return(ret);
-}
-
-
diff --git a/mit-pthreads/include/Makefile.inc b/mit-pthreads/include/Makefile.inc
deleted file mode 100644
index b7fe59d5f0d..00000000000
--- a/mit-pthreads/include/Makefile.inc
+++ /dev/null
@@ -1,30 +0,0 @@
-# from: @(#)Makefile 5.45.1.1 (Berkeley) 5/6/91
-
-# Doing a make install builds /usr/include/pthread
-#
-# The ``rm -rf''s used below are safe because rm doesn't follow symbolic
-# links.
-
-
-FILES= cond.h copyright.h fd.h fd_pipe.h kernel.h mutex.h posix.h \
- pthread.h pthread_attr.h queue.h util.h
-
-# Machine dependent header file
-MFILE= ${.CURDIR}/arch/${MACHINE}/machdep.h
-
-realinstall:
- if [ ! -d ${DESTDIR}/usr/include/pthread ]; then \
- mkdir ${DESTDIR}/usr/include/pthread; \
- fi
- @echo installing ${FILES}
- @-for i in ${FILES}; do \
- cmp -s $$i ${DESTDIR}/usr/include/pthread/$$i || \
- install -c -m 644 $$i ${DESTDIR}/usr/include/$$i; \
- done
- cmp -s ${MFILE} ${DESTDIR}/usr/include/pthread/machdep.h || \
- install -c -m 644 ${MFILE} ${DESTDIR}/usr/include/pthread/machdep.h
- rm -rf ${DESTDIR}/usr/include/pthread.h
- ln -s /usr/include/pthread/pthread.h ${DESTDIR}/usr/include/pthread.h
- @chown -R ${BINOWN}:${BINGRP} ${DESTDIR}/usr/include/pthread
- @chmod -R a-w ${DESTDIR}/usr/include/pthread
-
diff --git a/mit-pthreads/include/arpa/inet.h b/mit-pthreads/include/arpa/inet.h
deleted file mode 100755
index d6ad76f4eb5..00000000000
--- a/mit-pthreads/include/arpa/inet.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 1983, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)inet.h 5.7 (Berkeley) 4/3/91
- * $Id$
- */
-
-#ifndef _INET_H_
-#define _INET_H_
-
-/* External definitions for functions in inet(3) */
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <pthread/types.h>
-
-__BEGIN_DECLS
-
-pthread_ipaddr_type inet_addr __P_((const char *));
-int inet_aton __P_((const char *, struct in_addr *));
-pthread_ipaddr_type inet_lnaof __P_((struct in_addr));
-struct in_addr inet_makeaddr __P_((pthread_ipaddr_type,
- pthread_ipaddr_type));
-pthread_ipaddr_type inet_netof __P_((struct in_addr));
-pthread_ipaddr_type inet_network __P_((const char *));
-char * inet_ntoa __P_((struct in_addr));
-char * inet_ntoa_r __P_((struct in_addr in, char *buf,
- int bufsize));
-
-__END_DECLS
-
-#endif /* !_INET_H_ */
diff --git a/mit-pthreads/include/arpa/nameser.h b/mit-pthreads/include/arpa/nameser.h
deleted file mode 100755
index 350d67538bd..00000000000
--- a/mit-pthreads/include/arpa/nameser.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (c) 1983, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)nameser.h 8.2 (Berkeley) 2/16/94
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#ifndef _NAMESER_H_
-#define _NAMESER_H_
-
-#include <endian.h>
-#include <sys/types.h>
-#include <pthread/types.h>
-
-/*
- * Define constants based on rfc883
- */
-#define PACKETSZ 512 /* maximum packet size */
-#define MAXDNAME 256 /* maximum domain name */
-#define MAXCDNAME 255 /* maximum compressed domain name */
-#define MAXLABEL 63 /* maximum length of domain label */
- /* Number of bytes of fixed size data in query structure */
-#define QFIXEDSZ 4
- /* number of bytes of fixed size data in resource record */
-#define RRFIXEDSZ 10
-
-/*
- * Internet nameserver port number
- */
-#define NAMESERVER_PORT 53
-
-/*
- * Currently defined opcodes
- */
-#define QUERY 0x0 /* standard query */
-#define IQUERY 0x1 /* inverse query */
-#define STATUS 0x2 /* nameserver status query */
-/*#define xxx 0x3*/ /* 0x3 reserved */
- /* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */
-#define UPDATEA 0x9 /* add resource record */
-#define UPDATED 0xa /* delete a specific resource record */
-#define UPDATEDA 0xb /* delete all named resource record */
-#define UPDATEM 0xc /* modify a specific resource record */
-#define UPDATEMA 0xd /* modify all named resource record */
-
-#define ZONEINIT 0xe /* initial zone transfer */
-#define ZONEREF 0xf /* incremental zone referesh */
-
-/*
- * Currently defined response codes
- */
-#define NOERROR 0 /* no error */
-#define FORMERR 1 /* format error */
-#define SERVFAIL 2 /* server failure */
-#define NXDOMAIN 3 /* non existent domain */
-#define NOTIMP 4 /* not implemented */
-#define REFUSED 5 /* query refused */
- /* non standard */
-#define NOCHANGE 0xf /* update failed to change db */
-
-/*
- * Type values for resources and queries
- */
-#define T_A 1 /* host address */
-#define T_NS 2 /* authoritative server */
-#define T_MD 3 /* mail destination */
-#define T_MF 4 /* mail forwarder */
-#define T_CNAME 5 /* connonical name */
-#define T_SOA 6 /* start of authority zone */
-#define T_MB 7 /* mailbox domain name */
-#define T_MG 8 /* mail group member */
-#define T_MR 9 /* mail rename name */
-#define T_NULL 10 /* null resource record */
-#define T_WKS 11 /* well known service */
-#define T_PTR 12 /* domain name pointer */
-#define T_HINFO 13 /* host information */
-#define T_MINFO 14 /* mailbox information */
-#define T_MX 15 /* mail routing information */
-#define T_TXT 16 /* text strings */
-#define T_RP 17 /* responsible person */
-#define T_AFSDB 18 /* AFS cell database */
-#define T_NSAP 22 /* NSAP address */
-#define T_NSAP_PTR 23 /* reverse lookup for NSAP */
- /* non standard */
-#define T_UINFO 100 /* user (finger) information */
-#define T_UID 101 /* user ID */
-#define T_GID 102 /* group ID */
-#define T_UNSPEC 103 /* Unspecified format (binary data) */
- /* Query type values which do not appear in resource records */
-#define T_AXFR 252 /* transfer zone of authority */
-#define T_MAILB 253 /* transfer mailbox records */
-#define T_MAILA 254 /* transfer mail agent records */
-#define T_ANY 255 /* wildcard match */
-
-/*
- * Values for class field
- */
-
-#define C_IN 1 /* the arpa internet */
-#define C_CHAOS 3 /* for chaos net (MIT) */
-#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */
- /* Query class values which do not appear in resource records */
-#define C_ANY 255 /* wildcard match */
-
-/*
- * Status return codes for T_UNSPEC conversion routines
- */
-#define CONV_SUCCESS 0
-#define CONV_OVERFLOW -1
-#define CONV_BADFMT -2
-#define CONV_BADCKSUM -3
-#define CONV_BADBUFLEN -4
-
-#if !defined(BYTE_ORDER) || (BYTE_ORDER != BIG_ENDIAN \
- && BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != PDP_ENDIAN)
- /* you must determine what the correct bit order is for
- * your compiler - the next line is an intentional error
- * which will force your compiles to bomb until you fix
- * the above macros.
- */
- #error "Undefined or invalid BYTE_ORDER";
-#endif
-
-/*
- * Structure for query header. The order of the fields is machine- and
- * compiler-dependent, depending on the byte/bit order and the layout
- * of bit fields. We use bit fields only in int variables, as this
- * is all ANSI requires. This requires a somewhat confusing rearrangement.
- */
-
-typedef struct {
- pthread_ipport_type id; /* query identification number */
-#if BYTE_ORDER == BIG_ENDIAN
- /* fields in third byte */
- u_int qr:1; /* response flag */
- u_int opcode:4; /* purpose of message */
- u_int aa:1; /* authoritive answer */
- u_int tc:1; /* truncated message */
- u_int rd:1; /* recursion desired */
- /* fields in fourth byte */
- u_int ra:1; /* recursion available */
- u_int pr:1; /* primary server required (non standard) */
- u_int unused:2; /* unused bits */
- u_int rcode:4; /* response code */
-#endif
-#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
- /* fields in third byte */
- u_int rd:1; /* recursion desired */
- u_int tc:1; /* truncated message */
- u_int aa:1; /* authoritive answer */
- u_int opcode:4; /* purpose of message */
- u_int qr:1; /* response flag */
- /* fields in fourth byte */
- u_int rcode:4; /* response code */
- u_int unused:2; /* unused bits */
- u_int pr:1; /* primary server required (non standard) */
- u_int ra:1; /* recursion available */
-#endif
- /* remaining bytes */
- pthread_ipport_type qdcount; /* number of question entries */
- pthread_ipport_type ancount; /* number of answer entries */
- pthread_ipport_type nscount; /* number of authority entries */
- pthread_ipport_type arcount; /* number of resource entries */
-} HEADER;
-
-/*
- * Defines for handling compressed domain names
- */
-#define INDIR_MASK 0xc0
-
-/*
- * Structure for passing resource records around.
- */
-struct rrec {
- pthread_ipport_type r_zone; /* zone number */
- pthread_ipport_type r_class; /* class number */
- pthread_ipport_type r_type; /* type number */
- pthread_ipaddr_type r_ttl; /* time to live */
- int r_size; /* size of data area */
- char * r_data; /* pointer to data */
-};
-
-extern pthread_ipport_type _getshort();
-extern pthread_ipaddr_type _getlong();
-
-/*
- * Inline versions of get/put short/long. Pointer is advanced.
- * We also assume that a "pthread_ipport_type" holds 2 "chars"
- * and that a "pthread_ipaddr_type" holds 4 "chars".
- *
- * These macros demonstrate the property of C whereby it can be
- * portable or it can be elegant but never both.
- */
-#define GETSHORT(s, cp) { \
- register u_char *t_cp = (u_char *)(cp); \
- (s) = ((pthread_ipport_type)t_cp[0] << 8) | (pthread_ipport_type)t_cp[1]; \
- (cp) += 2; \
-}
-
-#define GETLONG(l, cp) { \
- register u_char *t_cp = (u_char *)(cp); \
- (l) = (((pthread_ipaddr_type)t_cp[0]) << 24) \
- | (((pthread_ipaddr_type)t_cp[1]) << 16) \
- | (((pthread_ipaddr_type)t_cp[2]) << 8) \
- | (((pthread_ipaddr_type)t_cp[3])); \
- (cp) += 4; \
-}
-
-#define PUTSHORT(s, cp) { \
- register pthread_ipport_type t_s = (pthread_ipport_type)(s); \
- register u_char *t_cp = (u_char *)(cp); \
- *t_cp++ = t_s >> 8; \
- *t_cp = t_s; \
- (cp) += 2; \
-}
-
-/*
- * Warning: PUTLONG --no-longer-- destroys its first argument. if you
- * were depending on this "feature", you will lose.
- */
-#define PUTLONG(l, cp) { \
- register pthread_ipaddr_type t_l = (pthread_ipaddr_type)(l); \
- register u_char *t_cp = (u_char *)(cp); \
- *t_cp++ = t_l >> 24; \
- *t_cp++ = t_l >> 16; \
- *t_cp++ = t_l >> 8; \
- *t_cp = t_l; \
- (cp) += 4; \
-}
-
-#endif /* !_NAMESER_H_ */
diff --git a/mit-pthreads/include/dirent.h b/mit-pthreads/include/dirent.h
deleted file mode 100644
index c3e86cb9da1..00000000000
--- a/mit-pthreads/include/dirent.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _DIRENT_H_
-#define _DIRENT_H_
-
-#include <sys/dirent.h>
-#include <pthread.h>
-
-struct __dirent {
- struct __dirent * next;
- struct dirent data;
- pthread_t owner;
-};
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-/* structure describing an open directory. */
-typedef struct _dirdesc {
- struct __dirent * dd_dp; /* Linked list of struct __dirent pointer */
- int dd_fd; /* file descriptor associated with directory */
- long dd_loc; /* offset in current buffer */
- long dd_size; /* amount of data returned by getdirentries */
- char * dd_buf; /* data buffer */
- int dd_len; /* size of data buffer */
- long dd_seek; /* magic cookie returned by getdirentries */
- void * dd_ddloc; /* Linked list of ddloc structs for telldir/seekdir */
- pthread_mutex_t *dd_lock; /* Lock for open directory structure */
-} DIR;
-
-#define dirfd(dirp) ((dirp)->dd_fd)
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef KERNEL
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-DIR * opendir __P_((const char *));
-struct dirent * readdir __P_((DIR *));
-int readdir_r __P_((DIR *, struct dirent *, struct dirent **));
-void rewinddir __P_((DIR *));
-int closedir __P_((DIR *));
-#ifndef _POSIX_SOURCE
-long telldir __P_((DIR *));
-void seekdir __P_((DIR *, long));
-
-/*
-int scandir __P_((const char *, struct dirent ***,
- int (*)(struct dirent *),
- int (*)(const void *, const void *)));
-int alphasort __P_((const void *, const void *));
-int getdirentries __P_((int, char *, int, long *));
-*/
-#endif /* not POSIX */
-
-__END_DECLS
-
-#endif /* !KERNEL */
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/include/endian.h b/mit-pthreads/include/endian.h
deleted file mode 100644
index 8fb947dbd33..00000000000
--- a/mit-pthreads/include/endian.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 1983, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)nameser.h 8.2 (Berkeley) 2/16/94
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#ifndef _ENDIAN_H_
-#define _ENDIAN_H_
-
-#ifndef BYTE_ORDER
-#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */
-#define __LITTLE_ENDIAN 1234
-#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
-#define __BIG_ENDIAN 4321
-#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/
-#define __PDP_ENDIAN 3412
-
-#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
- defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
- defined(__alpha__) || defined(__alpha)
-#define BYTE_ORDER LITTLE_ENDIAN
-#define __BYTE_ORDER LITTLE_ENDIAN
-#endif
-
-#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
- defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
- defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || \
- defined(apollo) || defined(hp9000) || defined(hp9000s300) || \
- defined(hp9000s800) || \
- defined (BIT_ZERO_ON_LEFT)
-#define BYTE_ORDER BIG_ENDIAN
-#define __BYTE_ORDER BIG_ENDIAN
-#endif
-#endif /* BYTE_ORDER */
-
-#if !defined(BYTE_ORDER) || (BYTE_ORDER != BIG_ENDIAN \
- && BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != PDP_ENDIAN)
- /* you must determine what the correct bit order is for
- * your compiler - the next line is an intentional error
- * which will force your compiles to bomb until you fix
- * the above macros.
- */
- #error "Undefined or invalid BYTE_ORDER";
-#endif
-
-#endif /* !_ENDIAN_H */
diff --git a/mit-pthreads/include/errno.h b/mit-pthreads/include/errno.h
deleted file mode 100644
index 24b005e9369..00000000000
--- a/mit-pthreads/include/errno.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)errno.h 7.13 (Berkeley) 2/19/91
- * errno.h,v 1.3 1993/05/20 16:22:09 cgd Exp
- */
-
-#ifndef _ERRNO_H_
-#define _ERRNO_H_
-
-#include <sys/cdefs.h>
-#include <sys/errno.h>
-
-__BEGIN_DECLS
-
-extern int * __error();
-
-__END_DECLS
-
-#define errno (* __error())
-#define pthread_errno(x) pthread_run->error_p = x
-
-#endif /* _ERRNO_H_ */
diff --git a/mit-pthreads/include/math.h b/mit-pthreads/include/math.h
deleted file mode 100644
index d5963ce6023..00000000000
--- a/mit-pthreads/include/math.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef _MATH_H_
-#define _MATH_H_
-
-/* Needed for HUGE_VAL */
-#include <sys/__math.h>
-
-/* XOPEN/SVID */
-
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-#define M_E 2.7182818284590452354 /* e */
-#define M_LOG2E 1.4426950408889634074 /* log 2e */
-#define M_LOG10E 0.43429448190325182765 /* log 10e */
-#define M_LN2 0.69314718055994530942 /* log e2 */
-#define M_LN10 2.30258509299404568402 /* log e10 */
-#define M_PI 3.14159265358979323846 /* pi */
-#define M_PI_2 1.57079632679489661923 /* pi/2 */
-#define M_PI_4 0.78539816339744830962 /* pi/4 */
-#define M_1_PI 0.31830988618379067154 /* 1/pi */
-#define M_2_PI 0.63661977236758134308 /* 2/pi */
-#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
-#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
-#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
-
-#define MAXFLOAT ((float)3.40282346638528860e+38)
-
-#if !defined(_XOPEN_SOURCE)
-
-struct exception {
- int type;
- char *name;
- double arg1;
- double arg2;
- double retval;
-};
-
-#define HUGE MAXFLOAT
-
-#define DOMAIN 1
-#define SING 2
-#define OVERFLOW 3
-#define UNDERFLOW 4
-#define TLOSS 5
-#define PLOSS 6
-
-#endif /* !_XOPEN_SOURCE */
-#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
-
-#include <sys/cdefs.h>
-
-/* ANSI/POSIX */
-
-__BEGIN_DECLS
-
-double hypot __P_((double, double));
-double acos __P_((double));
-double asin __P_((double));
-double atan __P_((double));
-double atan2 __P_((double, double));
-double cos __P_((double));
-double sin __P_((double));
-double tan __P_((double));
-
-double cosh __P_((double));
-double sinh __P_((double));
-double tanh __P_((double));
-
-double exp __P_((double));
-double frexp __P_((double, int *));
-double ldexp __P_((double, int));
-double log __P_((double));
-double log10 __P_((double));
-double modf __P_((double, double *));
-
-double pow __P_((double, double));
-double sqrt __P_((double));
-
-double ceil __P_((double));
-double fabs __P_((double));
-double floor __P_((double));
-double fmod __P_((double, double));
-double rint __P_((double)); /* XOPEN; Added by Monty */
-int finite __P_((double dsrc)); /* math.h; added by Monty */
-__END_DECLS
-
-#endif /* _MATH_H_ */
diff --git a/mit-pthreads/include/netdb.h b/mit-pthreads/include/netdb.h
deleted file mode 100644
index 54d85e5a3ed..00000000000
--- a/mit-pthreads/include/netdb.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*-
- * Copyright (c) 1980, 1983, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)netdb.h 5.15 (Berkeley) 4/3/91
- * $Id$
- */
-
-#ifndef _NETDB_H_
-#define _NETDB_H_
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-
-#define _PATH_HEQUIV "/etc/hosts.equiv"
-#define _PATH_HOSTS "/etc/hosts"
-#define _PATH_NETWORKS "/etc/networks"
-#define _PATH_PROTOCOLS "/etc/protocols"
-#define _PATH_SERVICES "/etc/services"
-#define __NETDB_MAXALIASES 35
-#define __NETDB_MAXADDRS 35
-
-/*
- * Structures returned by network data base library. All addresses are
- * supplied in host order, and returned in network order (suitable for
- * use in system calls).
- */
-struct hostent {
- char *h_name; /* official name of host */
- char **h_aliases; /* alias list */
- int h_addrtype; /* host address type */
- int h_length; /* length of address */
- char **h_addr_list; /* list of addresses from name server */
-#define h_addr h_addr_list[0] /* address, for backward compatiblity */
-};
-
-/*
- * Assumption here is that a network number
- * fits in 32 bits -- probably a poor one.
- */
-struct netent {
- char *n_name; /* official name of net */
- char **n_aliases; /* alias list */
- int n_addrtype; /* net address type */
- unsigned long n_net; /* network # */
-};
-
-struct servent {
- char *s_name; /* official service name */
- char **s_aliases; /* alias list */
- int s_port; /* port # */
- char *s_proto; /* protocol to use */
-};
-
-struct protoent {
- char *p_name; /* official protocol name */
- char **p_aliases; /* alias list */
- int p_proto; /* protocol # */
-};
-
-/*
- * Error return codes from gethostbyname() and gethostbyaddr()
- * (left in extern int h_errno).
- */
-
-#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
-#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
-#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
-#define NO_DATA 4 /* Valid name, no data record of requested type */
-#define NO_ADDRESS NO_DATA /* no address, look for MX record */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-void endhostent __P_((void));
-void endnetent __P_((void));
-void endprotoent __P_((void));
-void endservent __P_((void));
-struct hostent *gethostbyaddr __P_((const char *, int, int));
-struct hostent *gethostbyname __P_((const char *));
-struct hostent *gethostent __P_((void));
-struct netent *getnetbyaddr __P_((long, int)); /* u_long? */
-struct netent *getnetbyname __P_((const char *));
-struct netent *getnetent __P_((void));
-struct protoent *getprotobyname __P_((const char *));
-struct protoent *getprotobynumber __P_((int));
-struct protoent *getprotoent __P_((void));
-struct servent *getservbyname __P_((const char *, const char *));
-struct servent *getservbyport __P_((int, const char *));
-struct servent *getservent __P_((void));
-void herror __P_((const char *));
-char *hstrerror __P_((int));
-void sethostent __P_((int));
-void setnetent __P_((int));
-void setprotoent __P_((int));
-void setservent __P_((int));
-struct hostent *gethostbyaddr_r __P_((const char *, int, int,
- struct hostent *, char *, int, int *));
-struct hostent *gethostbyname_r __P_((const char *, struct hostent *, char *,
- int, int *));
-struct hostent *gethostent_r __P_((struct hostent *, char *, int, int *));
-struct netent *getnetbyaddr_r __P_((long, int, struct netent *, char *, int));
-struct netent *getnetbyname_r __P_((const char *, struct netent *, char *,
- int));
-struct netent *getnetent_r __P_((struct netent *, char *, int));
-struct protoent *getprotobyname_r __P_((const char *, struct protoent *, char *,
- int));
-struct protoent *getprotobynumber_r __P_((int, struct protoent *, char *, int));
-struct protoent *getprotoent_r __P_((struct protoent *, char *, int));
-struct servent *getservbyname_r __P_((const char *, const char *,
- struct servent *, char *, int));
-struct servent *getservbyport_r __P_((int, const char *, struct servent *,
- char *, int));
-struct servent *getservent_r __P_((struct servent *, char *, int));
-__END_DECLS
-
-#endif /* !_NETDB_H_ */
diff --git a/mit-pthreads/include/pthread.h b/mit-pthreads/include/pthread.h
deleted file mode 100644
index e8a44050215..00000000000
--- a/mit-pthreads/include/pthread.h
+++ /dev/null
@@ -1,371 +0,0 @@
-/* ==== pthread.h ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic pthread header.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- *
- * 93/9/28 streepy - Added support for pthread cancel
- *
- */
-
-#ifndef _PTHREAD_H_
-#define _PTHREAD_H_
-
-#include <pthread/types.h>
-
-#include <pthread/version.h>
-#include <pthread/machdep.h>
-#include <pthread/cleanup.h>
-#include <pthread/kernel.h>
-#include <pthread/prio_queue.h>
-#include <pthread/queue.h>
-#include <pthread/sleep.h>
-#include <pthread/mutex.h>
-#include <pthread/cond.h>
-#include <pthread/fd.h>
-#include <pthread/debug_out.h>
-
-/* Requires mutex.h */
-#include <pthread/specific.h>
-
-#include <pthread/util.h>
-
-/* More includes */
-#include <pthread/pthread_once.h>
-
-/* More includes, that need size_t */
-#include <pthread/pthread_attr.h>
-
-#include <signal.h> /* for sigset_t */ /* Moved by monty */
-
-/* Constants for use with pthread_setcancelstate and pthread_setcanceltype */
-#define PTHREAD_CANCEL_DISABLE 0
-#define PTHREAD_CANCEL_ENABLE 1
-#define PTHREAD_CANCEL_DEFERRED 0
-#define PTHREAD_CANCEL_ASYNCHRONOUS 1
-
-#define PTHREAD_CANCELLED (void *)1 /* Exit status of a cancelled thread */
-
-
-#ifdef PTHREAD_KERNEL
-
-enum pthread_state {
-#define __pthread_defstate(S,NAME) S,
-#include "pthread/state.def"
-#undef __pthread_defstate
-
- /* enum lists aren't supposed to end with a comma, sigh */
- PS_STATE_MAX
-};
-
-/* Put PANIC inside an expression that evaluates to non-void type, to
- make it easier to combine it in expressions. */
-#define DO_PANIC() (PANIC (), 0)
-#define PANICIF(x) ((x) ? DO_PANIC () : 0)
-
-/* In the thread flag field, we use a series of bit flags. Flags can
- * organized into "groups" of mutually exclusive flags. Other flags
- * are unrelated and can be set and cleared with a single bit operation.
- */
-
-#define PF_WAIT_EVENT 0x01
-#define PF_DONE_EVENT 0x02
-#define PF_EVENT_GROUP 0x03 /* All event bits */
-
-#define PF_CANCEL_STATE 0x04 /* cancellability state */
-#define PF_CANCEL_TYPE 0x08 /* cancellability type */
-#define PF_THREAD_CANCELLED 0x10 /* thread has been cancelled */
-#define PF_RUNNING_TO_CANCEL 0x20 /* Thread is running so it can cancel*/
-#define PF_AT_CANCEL_POINT 0x40 /* Thread is at a cancel point */
-
-/* Flag operations */
-
-#define SET_PF_FLAG(x,f) ( (x)->flags |= (f) )
-#define TEST_PF_FLAG(x,f) ( (x)->flags & (f) )
-#define CLEAR_PF_FLAG(x,f) ( (x)->flags &= ~(f) )
-#define CLEAR_PF_GROUP(x,g) ( (x)->flags &= ~(g) )
-#define SET_PF_FLAG_IN_GROUP(x,g,f) ( CLEAR_PF_GROUP(x,g),SET_PF_FLAG(x,f))
-#define TEST_PF_GROUP(x,g) ( (x)->flags & (g) )
-
-#define SET_PF_DONE_EVENT(x) \
-( !TEST_PF_FLAG(x,PF_DONE_EVENT) \
- ? ( TEST_PF_FLAG(x,PF_WAIT_EVENT) \
- ? (SET_PF_FLAG_IN_GROUP(x,PF_EVENT_GROUP,PF_DONE_EVENT), OK) \
- : DO_PANIC ()) \
- : NOTOK )
-
-#define SET_PF_WAIT_EVENT(x) \
-( PANICIF (TEST_PF_GROUP(x,PF_EVENT_GROUP) ), \
- SET_PF_FLAG_IN_GROUP(x,PF_EVENT_GROUP,PF_WAIT_EVENT), 0)
-
-#define CLEAR_PF_DONE_EVENT(x) \
-( PANICIF (!TEST_PF_FLAG(x,PF_DONE_EVENT)), \
- CLEAR_PF_GROUP(x,PF_EVENT_GROUP) )
-
-#define SET_PF_CANCELLED(x) ( SET_PF_FLAG(x,PF_THREAD_CANCELLED) )
-#define TEST_PF_CANCELLED(x) ( TEST_PF_FLAG(x,PF_THREAD_CANCELLED) )
-
-#define SET_PF_RUNNING_TO_CANCEL(x) ( SET_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-#define CLEAR_PF_RUNNING_TO_CANCEL(x)( CLEAR_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-#define TEST_PF_RUNNING_TO_CANCEL(x)( TEST_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-
-#define SET_PF_AT_CANCEL_POINT(x) ( SET_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-#define CLEAR_PF_AT_CANCEL_POINT(x) ( CLEAR_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-#define TEST_PF_AT_CANCEL_POINT(x) ( TEST_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-
-#define SET_PF_CANCEL_STATE(x,f) \
- ( (f) ? SET_PF_FLAG(x,PF_CANCEL_STATE) : CLEAR_PF_FLAG(x,PF_CANCEL_STATE) )
-#define TEST_PF_CANCEL_STATE(x) \
- ( (TEST_PF_FLAG(x,PF_CANCEL_STATE)) ? PTHREAD_CANCEL_ENABLE \
- : PTHREAD_CANCEL_DISABLE )
-
-#define SET_PF_CANCEL_TYPE(x,f) \
- ( (f) ? SET_PF_FLAG(x,PF_CANCEL_TYPE) : CLEAR_PF_FLAG(x,PF_CANCEL_TYPE) )
-#define TEST_PF_CANCEL_TYPE(x) \
- ( (TEST_PF_FLAG(x,PF_CANCEL_TYPE)) ? PTHREAD_CANCEL_ASYNCHRONOUS \
- : PTHREAD_CANCEL_DEFERRED )
-
-/* See if a thread is in a state that it can be cancelled */
-#define TEST_PTHREAD_IS_CANCELLABLE(x) \
-( (TEST_PF_CANCEL_STATE(x) == PTHREAD_CANCEL_ENABLE && TEST_PF_CANCELLED(x)) \
- ? ((TEST_PF_CANCEL_TYPE(x) == PTHREAD_CANCEL_ASYNCHRONOUS) \
- ? 1 \
- : TEST_PF_AT_CANCEL_POINT(x)) \
- : 0 )
-
-
-struct pthread_select_data {
- int nfds;
- fd_set readfds;
- fd_set writefds;
- fd_set exceptfds;
-};
-
-union pthread_wait_data {
- pthread_mutex_t * mutex;
- pthread_cond_t * cond;
- const sigset_t * sigwait; /* Waiting on a signal in sigwait */
- struct {
- short fd; /* Used when thread waiting on fd */
- short branch; /* line number, for debugging */
- } fd;
- struct pthread_select_data * select_data;
-};
-
-#define PTT_USER_THREAD 0x0001
-
-struct pthread {
- int thread_type;
- struct machdep_pthread machdep_data;
- pthread_attr_t attr;
-
- /* Signal interface */
- sigset_t sigmask;
- sigset_t sigpending;
- int sigcount; /* Number of signals pending */
- int sighandled; /* Set when signal has been handled */
- /* Timeout time */
- struct timespec wakeup_time;
-
- /* Join queue for waiting threads */
- struct pthread_queue join_queue;
-
- /*
- * Thread implementations are just multiple queue type implemenations,
- * Below are the various link lists currently necessary
- * It is possible for a thread to be on multiple, or even all the
- * queues at once, much care must be taken during queue manipulation.
- *
- * The pthread structure must be locked before you can even look at
- * the link lists.
- */
-
- /*
- * ALL threads, in any state.
- * Must lock kernel lock before manipulating.
- */
- struct pthread * pll;
-
- /*
- * Standard link list for running threads, mutexes, etc ...
- * It can't be on both a running link list and a wait queue.
- * Must lock kernel lock before manipulating.
- */
- struct pthread * next;
- union pthread_wait_data data;
-
- /*
- * Actual queue state and priority of thread.
- * (Note: "priority" is a reserved word in Concurrent C, please
- * don't use it. --KR)
- */
- struct pthread_queue * queue;
- enum pthread_state state;
- enum pthread_state old_state; /* Used when cancelled */
- char flags;
- char pthread_priority;
-
- /*
- * Sleep queue, this is different from the standard link list
- * because it is possible to be on both (pthread_cond_timedwait();
- * Must lock sleep mutex before manipulating
- */
- struct pthread *sll; /* For sleeping threads */
-
- /*
- * Data that doesn't need to be locked
- * Mostly because only the thread owning the data can manipulate it
- */
- void * ret;
- int error;
- int * error_p;
- const void ** specific_data;
- int specific_data_count;
-
- /* Cleanup handlers Link List */
- struct pthread_cleanup *cleanup;
-};
-
-#else /* not PTHREAD_KERNEL */
-
-struct pthread;
-
-#endif
-
-typedef struct pthread *pthread_t;
-
-/*
- * Globals
- */
-#ifdef PTHREAD_KERNEL
-
-extern struct pthread * pthread_run;
-extern struct pthread * pthread_initial;
-extern struct pthread * pthread_link_list;
-extern struct pthread_queue pthread_dead_queue;
-extern struct pthread_queue pthread_alloc_queue;
-
-extern pthread_attr_t pthread_attr_default;
-extern volatile int fork_lock;
-extern pthread_size_t pthread_pagesize;
-
-extern sigset_t * uthread_sigmask;
-
-/* Kernel global functions */
-extern void pthread_sched_prevent(void);
-extern void pthread_sched_resume(void);
-extern int __pthread_is_valid( pthread_t );
-extern void pthread_cancel_internal( int freelocks );
-
-#endif
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(DCE_COMPAT)
-
-typedef void * (*pthread_startroutine_t)(void *);
-typedef void * pthread_addr_t;
-
-int pthread_create __P_((pthread_t *, pthread_attr_t,
- pthread_startroutine_t,
- pthread_addr_t));
-void pthread_exit __P_((pthread_addr_t));
-int pthread_join __P_((pthread_t, pthread_addr_t *));
-
-#else
-
-void pthread_init __P_((void));
-int pthread_create __P_((pthread_t *,
- const pthread_attr_t *,
- void * (*start_routine)(void *),
- void *));
-void pthread_exit __P_((void *));
-pthread_t pthread_self __P_((void));
-int pthread_equal __P_((pthread_t, pthread_t));
-int pthread_join __P_((pthread_t, void **));
-int pthread_detach __P_((pthread_t));
-void pthread_yield __P_((void));
-int pthread_setschedparam __P_((pthread_t pthread, int policy,
- struct sched_param * param));
-int pthread_getschedparam __P_((pthread_t pthread, int * policy,
- struct sched_param * param));
-int pthread_kill __P_((struct pthread *, int));
-void (*pthread_signal __P_((int, void (*)(int))))();
-int pthread_cancel __P_(( pthread_t pthread ));
-int pthread_setcancelstate __P_(( int state, int *oldstate ));
-int pthread_setcanceltype __P_(( int type, int *oldtype ));
-void pthread_testcancel __P_(( void ));
-
-int pthread_sigmask __P_((int how, const sigset_t *set,
- sigset_t * oset)); /* added by Monty */
-int sigwait __P_((const sigset_t * set, int * sig));
-int sigsetwait __P_((const sigset_t * set, int * sig));
-#endif
-
-#if defined(PTHREAD_KERNEL)
-
-/* Not valid, but I can't spell so this will be caught at compile time */
-#define pthread_yeild(notvalid)
-
-#endif
-
-__END_DECLS
-
-/*
- * Static constructors
- */
-#ifdef __cplusplus
-
-extern struct pthread * pthread_initial;
-
-class __pthread_init_t {
-/* struct __pthread_init_t { */
- public:
- __pthread_init_t() {
- if (pthread_initial == NULL) {
- pthread_init();
- }
- }
-};
-
-static __pthread_init_t __pthread_init_this_file;
-
-#endif /* __cplusplus */
-
-#endif
diff --git a/mit-pthreads/include/pthread/ac-types.h b/mit-pthreads/include/pthread/ac-types.h
deleted file mode 100644
index 7fa4568817f..00000000000
--- a/mit-pthreads/include/pthread/ac-types.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef pthread_size_t
-#define pthread_ipaddr_type unsigned long
-#define pthread_ipport_type unsigned short
-#define pthread_clock_t long
-#define pthread_size_t unsigned int
-#define pthread_ssize_t int
-#define pthread_time_t long
-#define pthread_off_t long
-#define pthread_va_list void *
-#endif
diff --git a/mit-pthreads/include/pthread/cleanup.h b/mit-pthreads/include/pthread/cleanup.h
deleted file mode 100755
index cd995ceddcf..00000000000
--- a/mit-pthreads/include/pthread/cleanup.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==== cleanup.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : cleanup header.
- *
- * 1.20 94/02/13 proven
- * -Started coding this file.
- */
-
-/*
- * New cleanup structures
- */
-struct pthread_cleanup {
- struct pthread_cleanup *next;
- void (*routine)();
- void *routine_arg;
-};
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-int pthread_cleanup_push __P_((void (*routine)(void *), void *routine_arg));
-void pthread_cleanup_pop __P_((int execute));
-
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/cond.h b/mit-pthreads/include/pthread/cond.h
deleted file mode 100755
index ec9f7cf0016..00000000000
--- a/mit-pthreads/include/pthread/cond.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* ==== cond.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Condition variable header.
- *
- * 1.00 93/10/30 proven
- * -Started coding this file.
- */
-
-#include <timers.h>
-
-/*
- * New cond structures
- */
-enum pthread_condtype {
- COND_TYPE_FAST,
- COND_TYPE_STATIC_FAST,
- COND_TYPE_COUNTING_FAST, /* Used with MUTEX_TYPE_COUNTING_FAST */
- COND_TYPE_METERED,
- COND_TYPE_DEBUG, /* Debug conds will have lots of options */
- COND_TYPE_MAX
-};
-
-#define PTHREAD_CONDTYPE_FAST 1
-#define PTHREAD_CONDTYPE_DEBUG 4
-#define PTHREAD_CONDTYPE_RECURSIVE 2
-
-typedef struct pthread_cond {
- enum pthread_condtype c_type;
- struct pthread_queue c_queue;
- semaphore c_lock;
- void * c_data;
- long c_flags;
-} pthread_cond_t;
-
-typedef struct pthread_condattr {
- enum pthread_condtype c_type;
- long c_flags;
-} pthread_condattr_t;
-
-/*
- * Flags for conds.
- */
-#define COND_FLAGS_PRIVATE 0x01
-#define COND_FLAGS_INITED 0x02
-#define COND_FLAGS_BUSY 0x04
-
-/*
- * Static cond initialization values.
- */
-#define PTHREAD_COND_INITIALIZER \
-{ COND_TYPE_STATIC_FAST, PTHREAD_QUEUE_INITIALIZER, \
- SEMAPHORE_CLEAR, NULL, COND_FLAGS_INITED }
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-struct timespec;
-
-int pthread_cond_init __P_((pthread_cond_t *, const pthread_condattr_t *));
-int pthread_cond_timedwait __P_((pthread_cond_t *, pthread_mutex_t *,
- const struct timespec * abstime));
-int pthread_cond_wait __P_((pthread_cond_t *, pthread_mutex_t *));
-int pthread_cond_signal __P_((pthread_cond_t *));
-int pthread_cond_broadcast __P_((pthread_cond_t *));
-int pthread_cond_destroy __P_((pthread_cond_t *));
-
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/config.h b/mit-pthreads/include/pthread/config.h
deleted file mode 100644
index 251948c3874..00000000000
--- a/mit-pthreads/include/pthread/config.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifndef _SYS___CONFIG_H_
-#define _SYS___CONFIG_H_
-#define _OS_HAS_TIMESPEC 1
-#define _OS_HAS_SOCKLEN_T 1
-#endif
diff --git a/mit-pthreads/include/pthread/debug_out.h b/mit-pthreads/include/pthread/debug_out.h
deleted file mode 100755
index 6968c5ea90e..00000000000
--- a/mit-pthreads/include/pthread/debug_out.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* debug_out.h - macros to use for debugging prints in places where calls
- to printf() and gang are ill-advised. */
-
-#ifdef PTHREAD_DEBUGGING
-#define PTHREAD_DEBUG_WriteStr(S) (void)machdep_sys_write(2,S,strlen(S))
-#define PTHREAD_DEBUG_WriteInt32Hex(X) \
- { char _xbuf[8]; int _temp = (int)(X), _temp2; \
- _temp2 = ((_temp>>28)&0xf); \
- _xbuf[0] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>24)&0xf); \
- _xbuf[1] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>20)&0xf); \
- _xbuf[2] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>16)&0xf); \
- _xbuf[3] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>12)&0xf); \
- _xbuf[4] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>8)&0xf); \
- _xbuf[5] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = ((_temp>>4)&0xf); \
- _xbuf[6] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- _temp2 = (_temp&0xf); \
- _xbuf[7] = (_temp2<10)? (_temp2+'0'): ((_temp2-10)+'a'); \
- (void)machdep_sys_write(2,_xbuf,8); \
- }
-#ifdef __alpha
-#define PTHREAD_DEBUG_WriteInt64Hex(X) \
- { long _tempX = (long)(X),_tempY; \
- _tempY=((_tempX>>32)&0xffffffff); \
- PTHREAD_DEBUG_WriteInt32Hex(_tempY); \
- _tempY=(_tempX&0xffffffff); \
- PTHREAD_DEBUG_WriteInt32Hex(_tempY); \
- }
-#define PTHREAD_DEBUG_WritePointer(X) PTHREAD_DEBUG_WriteInt64Hex(X)
-#else
-#define PTHREAD_DEBUG_WriteInt64Hex(X) PTHREAD_DEBUG_WriteInt32Hex(X)
-#define PTHREAD_DEBUG_WritePointer(X) PTHREAD_DEBUG_WriteInt32Hex(X)
-#endif /* __alpha */
-#else /* ! PTHREAD_DEBUGGING */
-#define PTHREAD_DEBUG_WriteStr(S)
-#define PTHREAD_DEBUG_WriteInt32Hex(X)
-#define PTHREAD_DEBUG_WriteInt64HeX(X)
-#define PTHREAD_DEBUG_WritePointer(X)
-#endif /* PTHREAD_DEBUGGING */
diff --git a/mit-pthreads/include/pthread/fd.h b/mit-pthreads/include/pthread/fd.h
deleted file mode 100755
index d27a5066936..00000000000
--- a/mit-pthreads/include/pthread/fd.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* ==== fd.h ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic fd header.
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added
- */
-
-/*
- * New pthread types.
- */
-enum fd_type {
- FD_NT, /* Not tested */
- FD_NIU, /* Known to be not in use */
- FD_HALF_DUPLEX, /* Files, and seeking devices */
- FD_FULL_DUPLEX, /* pipes, sockets, drivers, ... */
- FD_TEST_HALF_DUPLEX, /* Redo machdep_sys_fcntl */
- FD_TEST_FULL_DUPLEX /* Redo machdep_sys_fcntl */
-};
-
-
-#define FD_READ 0x1
-#define FD_WRITE 0x2
-#define FD_RDWR (FD_READ | FD_WRITE)
-
-union fd_data {
- void *ptr;
- int i;
-};
-
-struct timespec;
-struct iovec;
-struct fd_ops {
- pthread_ssize_t (*write) __P_((union fd_data, int, const void *,
- size_t, struct timespec *));
- pthread_ssize_t (*read) __P_((union fd_data, int, void *, size_t,
- struct timespec *));
- int (*close)();
- int (*fcntl)();
- int (*writev) __P_((union fd_data, int,
- const struct iovec *,
- int, struct timespec *));
- int (*readv) __P_((union fd_data, int,
- const struct iovec *,
- int, struct timespec *));
- off_t (*seek)();
- int use_kfds;
-};
-
-struct fd_table_entry {
- struct pthread_queue r_queue;
- struct pthread_queue w_queue;
- struct pthread *r_owner;
- struct pthread *w_owner;
- pthread_mutex_t mutex;
- struct fd_table_entry *next;
- struct fd_ops *ops;
- enum fd_type type;
- int r_lockcount; /* Count for FILE read locks */
- int w_lockcount; /* Count for FILE write locks */
- int count;
-
- /* data that needs to be passed to the type dependent fd */
- int flags;
- union fd_data fd;
-};
-
-/*
- * Globals
- */
-#if defined(PTHREAD_KERNEL)
-
-extern struct fd_table_entry **fd_table;
-extern int dtablesize;
-
-#endif
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/include/pthread/fd_pipe.h b/mit-pthreads/include/pthread/fd_pipe.h
deleted file mode 100755
index cc5670dbb7d..00000000000
--- a/mit-pthreads/include/pthread/fd_pipe.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ==== fd_pipe.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : The new fast ITC pipe header.
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- */
-
-struct __pipe {
- semaphore lock;
- char * buf;
- int size;
- int flags;
- int count;
- int offset;
- struct pthread * wait;
- char * wait_buf;
- size_t wait_size;
-};
-
-#define RD_CLOSED 0x01
-#define WR_CLOSED 0x02
-
diff --git a/mit-pthreads/include/pthread/kernel.h b/mit-pthreads/include/pthread/kernel.h
deleted file mode 100755
index c474d789681..00000000000
--- a/mit-pthreads/include/pthread/kernel.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* ==== kernel.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : mutex header.
- *
- * 1.00 93/07/22 proven
- * -Started coding this file.
- */
-
-/*
- * Defines only for the pthread user kernel.
- */
-#if defined(PTHREAD_KERNEL)
-
-#ifdef __GNUC__
-#include <assert.h>
-#endif
-#ifdef __ASSERT_FUNCTION
-#define PANIC() panic_kernel( __FILE__, __LINE__, __ASSERT_FUNCTION )
-#else
-#define PANIC() panic_kernel( __FILE__, __LINE__, (const char *)0 )
-#endif
-
-
-/* Time each rr thread gets */
-#define PTHREAD_RR_TIMEOUT 100000000
-
-/* Set the errno value */
-#define SET_ERRNO(x) \
-{ \
- if (!pthread_run->error_p) { \
- pthread_run->error_p = &pthread_run->error; \
- } \
- (*(pthread_run->error_p)) = x; \
-}
-
-/* Globals only the internals should see */
-extern struct pthread_prio_queue * pthread_current_prio_queue;
-extern volatile int pthread_kernel_lock;
-
-#endif
diff --git a/mit-pthreads/include/pthread/kthread.h b/mit-pthreads/include/pthread/kthread.h
deleted file mode 100755
index a2e73361d8c..00000000000
--- a/mit-pthreads/include/pthread/kthread.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ==== kthread.h ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic pthread header.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- *
- * 1.32 94/05/25 proven
- * -Started adding kernel thread support
- */
-
-#ifndef _KTHREAD_H_
-#define _KTHREAD_H_
-
-enum kthread_state {
- KS_RUNNING,
- KS_DEAD,
-};
-
-struct kthread {
- enum kthread_state state;
-
- struct pthread_queue pthread_current_queue;
- struct pthread * pthread_link_list;
- struct pthread * pthread_run;
-
- semaphore lock;
-
-};
-
-/*
- * Globals
- */
-extern struct kthread * kthread_link_list;
-
-#endif
diff --git a/mit-pthreads/include/pthread/mutex.h b/mit-pthreads/include/pthread/mutex.h
deleted file mode 100755
index e6f1fe58c0f..00000000000
--- a/mit-pthreads/include/pthread/mutex.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* ==== mutex.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : mutex header.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-/*
- * New mutex structures
- */
-enum pthread_mutextype {
- MUTEX_TYPE_STATIC_FAST = 0,
- MUTEX_TYPE_FAST = 1,
- MUTEX_TYPE_COUNTING_FAST = 2, /* Recursive */
- MUTEX_TYPE_METERED = 3,
- MUTEX_TYPE_DEBUG = 4, /* This will have lots of options */
- MUTEX_TYPE_MAX
-};
-
-#define PTHREAD_MUTEXTYPE_FAST 1
-#define PTHREAD_MUTEXTYPE_DEBUG 4
-#define PTHREAD_MUTEXTYPE_RECURSIVE 2
-
-union pthread_mutex_data {
- void * m_ptr;
- int m_count;
-};
-
-typedef struct pthread_mutex {
- enum pthread_mutextype m_type;
- struct pthread_queue m_queue;
- struct pthread * m_owner;
- semaphore m_lock;
- union pthread_mutex_data m_data;
- long m_flags;
-} pthread_mutex_t;
-
-typedef struct pthread_mutexattr {
- enum pthread_mutextype m_type;
- long m_flags;
-} pthread_mutexattr_t;
-
-/*
- * Flags for mutexes.
- */
-#define MUTEX_FLAGS_PRIVATE 0x01
-#define MUTEX_FLAGS_INITED 0x02
-#define MUTEX_FLAGS_BUSY 0x04
-
-/*
- * Static mutex initialization values.
- */
-#define PTHREAD_MUTEX_INITIALIZER \
-{ MUTEX_TYPE_STATIC_FAST, PTHREAD_QUEUE_INITIALIZER, \
- NULL, SEMAPHORE_CLEAR, { NULL }, MUTEX_FLAGS_INITED }
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-int pthread_mutex_init __P_((pthread_mutex_t *, const pthread_mutexattr_t *));
-int pthread_mutex_lock __P_((pthread_mutex_t *));
-int pthread_mutex_unlock __P_((pthread_mutex_t *));
-int pthread_mutex_trylock __P_((pthread_mutex_t *));
-int pthread_mutex_destroy __P_((pthread_mutex_t *));
-
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/paths.h b/mit-pthreads/include/pthread/paths.h
deleted file mode 100644
index bf2bf9d01a2..00000000000
--- a/mit-pthreads/include/pthread/paths.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _SYS___PATHS_H_
-#define _SYS___PATHS_H_
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/lib/zoneinfo"
-#define _PATH_TZFILE "/usr/lib/zoneinfo/localtime"
-#define _PATH_RESCONF "/etc/resolv.conf"
-#define _PATH_HOSTS "/etc/hosts"
-#define _PATH_NETWORKS "/etc/networks"
-#define _PATH_PROTOCOLS "/etc/protocols"
-#define _PATH_SERVICES "/etc/services"
-#define _PATH_BSHELL "/bin/sh"
-#endif
diff --git a/mit-pthreads/include/pthread/prio_queue.h b/mit-pthreads/include/pthread/prio_queue.h
deleted file mode 100755
index e29a0170548..00000000000
--- a/mit-pthreads/include/pthread/prio_queue.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ==== priority.h ==========================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Priority functions.
- *
- * 1.00 94/09/19 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_PRIO_QUEUE_H_
-#define _PTHREAD_PRIO_QUEUE_H_
-
-/*
- * Static queue initialization values.
- */
-#define PTHREAD_DEFAULT_PRIORITY 64
-#define PTHREAD_MAX_PRIORITY 126
-#define PTHREAD_MIN_PRIORITY 0
-
-/*
- * New prio_queue structures
- */
-struct pthread_prio_level {
- struct pthread * first;
- struct pthread * last;
-};
-
-struct pthread_prio_queue {
- void * data;
- struct pthread * next;
- struct pthread_prio_level level[PTHREAD_MAX_PRIORITY + 1];
-};
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-void pthread_prio_queue_init __P_((struct pthread_prio_queue *));
-void pthread_prio_queue_enq __P_((struct pthread_prio_queue *,
- struct pthread *));
-struct pthread *pthread_prio_queue_deq
- __P_((struct pthread_prio_queue *));
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/include/pthread/pthread_attr.h b/mit-pthreads/include/pthread/pthread_attr.h
deleted file mode 100755
index 8cad262bad2..00000000000
--- a/mit-pthreads/include/pthread/pthread_attr.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* ==== pthread_attr.h ========================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic pthread attributes header.
- *
- * 1.00 93/11/03 proven
- * -Started coding this file.
- */
-
-#define _POSIX_THREAD_ATTR_STACKSIZE
-
-#define PTHREAD_STACK_DEFAULT 65536
-
-/* flags */
-#define PTHREAD_DETACHED 0x1
-#define PTHREAD_SCOPE_SYSTEM 0x2
-#define PTHREAD_INHERIT_SCHED 0x4
-#define PTHREAD_NOFLOAT 0x8
-
-#define PTHREAD_CREATE_DETACHED PTHREAD_DETACHED
-#define PTHREAD_CREATE_JOINABLE 0
-#define PTHREAD_SCOPE_PROCESS 0
-#define PTHREAD_EXPLICIT_SCHED 0
-
-/*
- * New pthread attribute types.
- */
-enum schedparam_policy {
- SCHED_RR,
- SCHED_IO,
- SCHED_FIFO,
- SCHED_OTHER
-};
-
-struct pthread_attr {
- enum schedparam_policy schedparam_policy;
- int sched_priority;
-
- int flags;
- void * arg_attr;
- void (*cleanup_attr)();
- void * stackaddr_attr;
- size_t stacksize_attr;
-};
-
-struct sched_param {
- int sched_priority;
- void * no_data;
-};
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(DCE_COMPAT)
-
-typedef struct pthread_attr * pthread_attr_t;
-
-int pthread_attr_create __P_((pthread_attr_t *));
-int pthread_attr_delete __P_((pthread_attr_t *));
-
-#else
-
-typedef struct pthread_attr pthread_attr_t;
-
-int pthread_attr_init __P_((pthread_attr_t *));
-int pthread_attr_destroy __P_((pthread_attr_t *));
-int pthread_attr_setstacksize __P_((pthread_attr_t *, size_t));
-int pthread_attr_getstacksize __P_((pthread_attr_t *, size_t *));
-int pthread_attr_setstackaddr __P_((pthread_attr_t *, void *));
-int pthread_attr_getstackaddr __P_((pthread_attr_t *, void **));
-int pthread_attr_setdetachstate __P_((pthread_attr_t *, int ));
-int pthread_attr_getdetachstate __P_((pthread_attr_t *, int *));
-int pthread_attr_setscope __P_((pthread_attr_t *, int ));
-int pthread_attr_getscope __P_((pthread_attr_t *, int *));
-int pthread_attr_setinheritsched __P_((pthread_attr_t *, int ));
-int pthread_attr_getinheritsched __P_((pthread_attr_t *, int *));
-int pthread_attr_setschedpolicy __P_((pthread_attr_t *, int ));
-int pthread_attr_getschedpolicy __P_((pthread_attr_t *, int *));
-int pthread_attr_setschedparam __P_((pthread_attr_t *, struct sched_param *));
-int pthread_attr_getschedparam __P_((pthread_attr_t *, struct sched_param *));
-
-int pthread_attr_setfloatstate __P_((pthread_attr_t *, int ));
-int pthread_attr_getfloatstate __P_((pthread_attr_t *, int *));
-int pthread_attr_setcleanup __P_((pthread_attr_t *, void (*routine)(void *),
- void *));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/include/pthread/pthread_once.h b/mit-pthreads/include/pthread/pthread_once.h
deleted file mode 100755
index ac53d5f9b2c..00000000000
--- a/mit-pthreads/include/pthread/pthread_once.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ==== pthread_once.h ========================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : mutex header.
- *
- * 1.00 93/12/12 proven
- * -Started coding this file.
- */
-
-/* New pthread_once structures */
-typedef struct pthread_once {
- int state;
- pthread_mutex_t mutex;
-} pthread_once_t;
-
-/* Static pthread_once_t initialization value. */
-#define PTHREAD_NEEDS_INIT 0
-#define PTHREAD_DONE_INIT 1
-#define PTHREAD_ONCE_INIT { PTHREAD_NEEDS_INIT, PTHREAD_MUTEX_INITIALIZER }
-
-/* New functions */
-
-__BEGIN_DECLS
-
-int pthread_once __P_((pthread_once_t *, void (*init_routine)(void)));
-
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/queue.h b/mit-pthreads/include/pthread/queue.h
deleted file mode 100755
index eca7699e95a..00000000000
--- a/mit-pthreads/include/pthread/queue.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ==== queue.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : mutex header.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-/*
- * New queue structures
- */
-struct pthread_queue {
- struct pthread *q_next;
- struct pthread *q_last;
- void *q_data;
-};
-
-/*
- * Static queue initialization values.
- */
-#define PTHREAD_QUEUE_INITIALIZER { NULL, NULL, NULL }
-
-/*
- * New functions
- * Should make pthread_queue_get a macro
- */
-
-__BEGIN_DECLS
-
-void pthread_queue_init __P_((struct pthread_queue *));
-void pthread_queue_enq __P_((struct pthread_queue *, struct pthread *));
-int pthread_queue_remove __P_((struct pthread_queue *, struct pthread *));
-struct pthread *pthread_queue_get __P_((struct pthread_queue *));
-struct pthread *pthread_queue_deq __P_((struct pthread_queue *));
-
-__END_DECLS
diff --git a/mit-pthreads/include/pthread/sleep.h b/mit-pthreads/include/pthread/sleep.h
deleted file mode 100755
index 8bf471a24aa..00000000000
--- a/mit-pthreads/include/pthread/sleep.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* ==== sleep.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : sleep header.
- *
- * 1.00 94/06/04 proven
- * -Started coding this file.
- */
-
-#if defined(PTHREAD_KERNEL)
-
-#include <timers.h>
-
-/*
- * New functions
- */
-static inline int machdep_gettimeofday(struct timespec * current_time)
-{
- struct timeval current_real_time;
- int ret;
-
- ret = gettimeofday(&current_real_time, NULL);
- TIMEVAL_TO_TIMESPEC((&current_real_time), current_time);
- return(ret);
-}
-
-__BEGIN_DECLS
-
-void sleep_schedule __P_((struct timespec *, struct timespec *));
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/include/pthread/specific.h b/mit-pthreads/include/pthread/specific.h
deleted file mode 100755
index 9c66a695556..00000000000
--- a/mit-pthreads/include/pthread/specific.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* ==== specific.h ========================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Thread specific data management header.
- *
- * 1.20 94/03/30 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_DATAKEYS_MAX 256
-#define _POSIX_THREAD_DESTRUTOR_ITERATIONS 4
-
-/*
- * New thread specific key type.
- */
-struct pthread_key {
- pthread_mutex_t mutex;
- long count;
- void (*destructor)();
-};
-
-typedef int pthread_key_t;
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-int pthread_key_create __P_((pthread_key_t *, void (*routine)(void *)));
-int pthread_setspecific __P_((pthread_key_t, const void *));
-void *pthread_getspecific __P_((pthread_key_t));
-int pthread_key_delete __P_((pthread_key_t));
-
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/state.def b/mit-pthreads/include/pthread/state.def
deleted file mode 100755
index c62d102a9f0..00000000000
--- a/mit-pthreads/include/pthread/state.def
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This file defines the states that a given thread can be in.
-
- The funky macro use here is so that this one header file can also
- define the corresponding state names, so that the two lists can't
- get inconsistent within a given source tree. */
-
-/* The thread is runnable. */
-__pthread_defstate (PS_RUNNING, "running")
-
-/*
- * The rest of the states are where the thread is waiting on some event.
- * Someday maybe the "data" field will point to the object being waited for.
- */
-
-/* Waiting for a mutex (pthread_mutex_lock()). */
-__pthread_defstate (PS_MUTEX_WAIT, "mutex")
-
-/* Waiting on a condition variable
- (pthread_cond_wait(), or pthread_cond_timedwait()). */
-__pthread_defstate (PS_COND_WAIT, "cond")
-
-/*
- * File descriptor stuff.
- *
- * File descriptors have a special lock. If it is a FULL_DUPLEX fd such as
- * a socket or fifo then it has two mutexes, one for reads and one for writes.
- * Some routines will even try to get both. It will always try to get the
- * read lock first before tring to get the write. All other fds only have
- * one mutex which all calls will get. It is displayed as if it is a read lock.
- */
-/* Waiting on a fd read lock (fd_lock()) */
-__pthread_defstate (PS_FDLR_WAIT, "fdlr")
-
-/* Waiting on a fd write lock (fd_lock()) */
-__pthread_defstate (PS_FDLW_WAIT, "fdlw")
-
-/* Waiting for the kernel fd to have data to read,
- (read(), readv(), recv(), recvfrom(), and recvmsg()). */
-__pthread_defstate (PS_FDR_WAIT, "fdr") /* Waiting on a kernel read */
-
-/* Waiting for the kernel fd to allow a write
- (write(), writev(), send(), sendto(), sendmsg()) */
-__pthread_defstate (PS_FDW_WAIT, "fdw")
-
-/* Waiting for several fds in a select() */
-__pthread_defstate (PS_SELECT_WAIT, "select")
-
-/* Waiting on a sleep (sleep(), usleep() or nanosleep()). */
-__pthread_defstate (PS_SLEEP_WAIT, "sleep")
-
-/* Waiting for a child to die (wait(), waitpid(), wait3(), or wait4()). */
-__pthread_defstate (PS_WAIT_WAIT, "wait")
-
-/* Waiting on some set of signals (sigwait()) */
-__pthread_defstate (PS_SIGWAIT, "sig")
-
-/* Waiting for a thread to die (pthread_join()) */
-__pthread_defstate (PS_JOIN, "join")
-
-/* Waiting for some thread to join with me or detach me */
-__pthread_defstate (PS_DEAD, "dead")
-
-/* Waiting for some thread to create me */
-__pthread_defstate (PS_UNALLOCED, "unallocated")
diff --git a/mit-pthreads/include/pthread/types.h b/mit-pthreads/include/pthread/types.h
deleted file mode 100755
index 7fdf001a0bc..00000000000
--- a/mit-pthreads/include/pthread/types.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef pthread_types_h
-#define pthread_types_h
-
-#include <pthread/xtypes.h>
-#include <pthread/ac-types.h>
-
-#if !defined (pthread_va_list) && defined (__NetBSD__)
-#include <stdarg.h>
-#define pthread_va_list _BSD_VA_LIST_
-#endif
-
-#if !defined (pthread_va_list) && defined (__GNUC__)
-#define __need_va_list
-#include <stdarg.h>
-#define pthread_va_list __gnuc_va_list
-#endif /* pthread_va_list, __GNUC__ */
-
-/* OSF/1 does it this way. */
-#if !defined (pthread_va_list) && defined (pthread_have_va_list_h)
-#ifndef _VA_LIST
-#define _HIDDEN_VA_LIST
-#include <va_list.h>
-#define pthread_va_list __va_list
-#else
-/* va_list has already been defined */
-#define pthread_va_list va_list
-#endif
-#endif
-
-/* If all else fails... */
-#ifndef pthread_va_list
-#include <stdarg.h>
-#define pthread_va_list va_list
-#endif
-
-#if defined(__STDC__) || defined(__GNUC__)
-#ifndef __P_
-#define __P_(protos) protos
-#endif
-#else
-#ifndef __P_
-#define __P_(protos)
-#endif
-#endif
-
-#endif /* pthread_types_h */
diff --git a/mit-pthreads/include/pthread/unistd.h b/mit-pthreads/include/pthread/unistd.h
deleted file mode 100755
index 3cb07533114..00000000000
--- a/mit-pthreads/include/pthread/unistd.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)unistd.h 5.13 (Berkeley) 6/17/91
- */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-void _exit __P_((int));
-int access __P_((const char *, int));
-int chdir __P_((const char *));
-int chown __P_((const char *, uid_t, gid_t));
-int close __P_((int));
-int dup __P_((int));
-int dup2 __P_((int, int));
-int execve __P_((const char *, char * const *, char * const *));
-pid_t fork __P_((void));
-int isatty __P_((int));
-int link __P_((const char *, const char *));
-off_t lseek __P_((int, off_t, int));
-int pipe __P_((int *));
-ssize_t read __P_((int, void *, size_t));
-u_int sleep __P_((u_int));
-char *ttyname __P_((int));
-int unlink __P_((const char *));
-ssize_t write __P_((int, const void *, size_t));
-
-/* Not implemented for threads yet */
-u_int alarm __P_((u_int));
-char *cuserid __P_((char *));
-int execl __P_((const char *, const char *, ...));
-int execle __P_((const char *, const char *, ...));
-int execlp __P_((const char *, const char *, ...));
-int execv __P_((const char *, char * const *));
-int execvp __P_((const char *, char * const *));
-long fpathconf __P_((int, int)); /* not yet */
-char *getcwd __P_((char *, size_t));
-gid_t getegid __P_((void));
-uid_t geteuid __P_((void));
-gid_t getgid __P_((void));
-int getgroups __P_((int, int *)); /* XXX (gid_t *) */
-char *getlogin __P_((void));
-pid_t getpgrp __P_((void));
-pid_t getpid __P_((void));
-pid_t getppid __P_((void));
-uid_t getuid __P_((void));
-long pathconf __P_((const char *, int)); /* not yet */
-int pause __P_((void));
-int rmdir __P_((const char *));
-int setgid __P_((gid_t));
-int setpgid __P_((pid_t, pid_t));
-pid_t setsid __P_((void));
-int setuid __P_((uid_t));
-long sysconf __P_((int)); /* not yet */
-pid_t tcgetpgrp __P_((int));
-int tcsetpgrp __P_((int, pid_t));
-
-#ifndef _POSIX_SOURCE
-
-int acct __P_((const char *));
-int async_daemon __P_((void));
-char *brk __P_((const char *));
-int chflags __P_((const char *, long));
-int chroot __P_((const char *));
-char *crypt __P_((const char *, const char *));
-int des_cipher __P_((const char *, char *, long, int));
-int des_setkey __P_((const char *key));
-int encrypt __P_((char *, int));
-void endusershell __P_((void));
-int exect __P_((const char *, char * const *, char * const *));
-int fchdir __P_((int));
-int fchflags __P_((int, long));
-int fchown __P_((int, uid_t, gid_t));
-int fsync __P_((int));
-int ftruncate __P_((int, off_t));
-int getdtablesize __P_((void));
-long gethostid __P_((void));
-int gethostname __P_((char *, int));
-mode_t getmode __P_((const void *, mode_t));
-int getpagesize __P_((void));
-char *getpass __P_((const char *));
-char *getusershell __P_((void));
-char *getwd __P_((char *)); /* obsoleted by getcwd() */
-int initgroups __P_((const char *, int));
-int mknod __P_((const char *, mode_t, dev_t));
-int mkstemp __P_((char *));
-char *mktemp __P_((char *));
-int nfssvc __P_((int));
-int nice __P_((int));
-void psignal __P_((u_int, const char *));
-extern char *sys_siglist[];
-int profil __P_((char *, int, int, int));
-int rcmd __P_((char **, int, const char *,
- const char *, const char *, int *));
-char *re_comp __P_((const char *));
-int re_exec __P_((const char *));
-int readlink __P_((const char *, char *, int));
-int reboot __P_((int));
-int revoke __P_((const char *));
-int rresvport __P_((int *));
-int ruserok __P_((const char *, int, const char *, const char *));
-char *sbrk __P_((int));
-int setegid __P_((gid_t));
-int seteuid __P_((uid_t));
-int setgroups __P_((int, const int *));
-void sethostid __P_((long));
-int sethostname __P_((const char *, int));
-int setkey __P_((const char *));
-int setlogin __P_((const char *));
-void *setmode __P_((const char *));
-int setpgrp __P_((pid_t pid, pid_t pgrp)); /* obsoleted by setpgid() */
-int setregid __P_((int, int));
-int setreuid __P_((int, int));
-int setrgid __P_((gid_t));
-int setruid __P_((uid_t));
-void setusershell __P_((void));
-int swapon __P_((const char *));
-int symlink __P_((const char *, const char *));
-void sync __P_((void));
-int syscall __P_((int, ...));
-int truncate __P_((const char *, off_t));
-int ttyslot __P_((void));
-u_int ualarm __P_((u_int, u_int));
-void usleep __P_((u_int));
-int vfork __P_((void));
-
-#endif /* !_POSIX_SOURCE */
-__END_DECLS
-
diff --git a/mit-pthreads/include/pthread/util.h b/mit-pthreads/include/pthread/util.h
deleted file mode 100755
index aaa33a6318d..00000000000
--- a/mit-pthreads/include/pthread/util.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* ==== util.h ============================================================
- * Copyright (c) 1991, 1992, 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Header file for generic utility functions.
- *
- * 91/08/31 proven - Added exchange.
- * Exchange any two objects of any size in any table.
- *
- * 91/10/06 proven - Cleaned out all the old junk.
- *
- * 91/03/06 proven - Added getint.
- */
-
-#ifndef _PTHREAD_UTIL_H
-#define _PTHREAD_UTIL_H
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* Stuff only pthread internals really uses */
-#if defined(PTHREAD_KERNEL)
-
-#undef FALSE
-#undef TRUE
-
-typedef enum Boolean {
- FALSE,
- TRUE
-} Boolean;
-
-#define OK 0
-#define NUL '\0'
-#define NOTOK -1
-
-#if ! defined(min)
-#define min(a,b) (((a)<(b))?(a):(b))
-#define max(a,b) (((a)>(b))?(a):(b))
-#endif
-
-/* Alingn the size to the next multiple of 4 bytes */
-#define ALIGN4(size) ((size + 3) & ~3)
-#define ALIGN8(size) ((size + 7) & ~7)
-
-#ifdef DEBUG
-#define DEBUG0(s) printf(s)
-#define DEBUG1(s,a) printf(s,a)
-#define DEBUG2(s,a,b) printf(s,a,b)
-#define DEBUG3(s,a,b,c) printf(s,a,b,c)
-#else
-#define DEBUG0(s)
-#define DEBUG1(s)
-#define DEBUG2(s)
-#define DEBUG3(s)
-#endif
-
-#endif
-
-#endif
diff --git a/mit-pthreads/include/pthread/version.h b/mit-pthreads/include/pthread/version.h
deleted file mode 100755
index fda3af284d0..00000000000
--- a/mit-pthreads/include/pthread/version.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== version.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Header file for programs that what to KNOW the version.
- *
- * 94/08/24 proven - Added this file for pthreads.
- */
-
-#ifndef _PTHREAD_VERSION_H
-#define _PTHREAD_VERSION_H 1
-#define _PTHREAD_VERSION_M 60
-#define _PTHREAD_VERSION_P 0
-#endif
diff --git a/mit-pthreads/include/pthread/xtypes.h b/mit-pthreads/include/pthread/xtypes.h
deleted file mode 100755
index 4dcc4f04f8c..00000000000
--- a/mit-pthreads/include/pthread/xtypes.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* If you need any special typedefs for function pointers &c to try
- testing for in configure.in, define them here. */
-
-/* According to ANSI, two struct types in the same module are not
- compatible types. So there's no way to define a type for
- pthread_sigset_t that's compatible with sigset_t when they're
- structure types, if we assume we can't pull in a __sigset_t or
- something by itself from system header files.
-
- Since that was my main reason for creating this file, there isn't
- anything here now. If after working on this code a bit longer we
- don't find anything else to put here, this file should just go
- away. */
diff --git a/mit-pthreads/include/pwd.h b/mit-pthreads/include/pwd.h
deleted file mode 100644
index af945a2b8db..00000000000
--- a/mit-pthreads/include/pwd.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)pwd.h 8.2 (Berkeley) 1/21/94
- * $Id$
- */
-
-#ifndef _PWD_H_
-#define _PWD_H_
-
-#include <sys/types.h>
-
-#ifndef _POSIX_SOURCE
-#define _PATH_PASSWD "/etc/passwd"
-#define _PATH_MASTERPASSWD "/etc/master.passwd"
-
-#define _PATH_MP_DB "/etc/pwd.db"
-#define _PATH_SMP_DB "/etc/spwd.db"
-
-#define _PATH_PWD_MKDB "/usr/sbin/pwd_mkdb"
-
-#define _PW_KEYBYNAME '1' /* stored by name */
-#define _PW_KEYBYNUM '2' /* stored by entry in the "file" */
-#define _PW_KEYBYUID '3' /* stored by uid */
-
-#define _PASSWORD_EFMT1 '_' /* extended encryption format */
-
-#define _PASSWORD_LEN 128 /* max length, not counting NULL */
-#endif
-
-struct passwd {
- char *pw_name; /* user name */
- char *pw_passwd; /* encrypted password */
- int pw_uid; /* user uid */
- int pw_gid; /* user gid */
- time_t pw_change; /* password change time */
- char *pw_class; /* user access class */
- char *pw_gecos; /* Honeywell login info */
- char *pw_dir; /* home directory */
- char *pw_shell; /* default shell */
- time_t pw_expire; /* account expiration */
-};
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct passwd *getpwuid __P_((uid_t));
-struct passwd *getpwnam __P_((const char *));
-#ifndef _POSIX_SOURCE
-struct passwd *getpwent __P_((void));
-#ifndef _XOPEN_SOURCE
-int setpassent __P_((int));
-#endif
-void setpwent __P_((void));
-void endpwent __P_((void));
-#endif
-__END_DECLS
-
-#endif /* !_PWD_H_ */
diff --git a/mit-pthreads/include/resolv.h b/mit-pthreads/include/resolv.h
deleted file mode 100644
index f6313a7229e..00000000000
--- a/mit-pthreads/include/resolv.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 1983, 1987, 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)resolv.h 5.15 (Berkeley) 4/3/91
- * $Id$
- */
-
-#ifndef _RESOLV_H_
-#define _RESOLV_H_
-
-#include <netinet/in.h>
-/*
- * This is specificly for Solaris which defines NOERROR in the streams
- * header files and defines it differently than in arpa/nameser.h
- */
-#ifdef NOERROR
-#undef NOERROR
-#endif
-#include <arpa/nameser.h>
-
-/*
- * revision information. this is the release date in YYYYMMDD format.
- * it can change every day so the right thing to do with it is use it
- * in preprocessor commands such as "#if (__RES > 19931104)". do not
- * compare for equality; rather, use it to determine whether your resolver
- * is new enough to contain a certain feature.
- */
-
-#define __RES 19940703
-
-/*
- * Resolver configuration file.
- * Normally not present, but may contain the address of the
- * inital name server(s) to query and the domain search list.
- */
-
-#ifndef _PATH_RESCONF
-#define _PATH_RESCONF "/etc/resolv.conf"
-#endif
-
-/*
- * Global defines and variables for resolver stub.
- */
-#define MAXNS 3 /* max # name servers we'll track */
-#define MAXDFLSRCH 3 /* # default domain levels to try */
-#define MAXDNSRCH 6 /* max # domains in search path */
-#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
-#define MAXDNSLUS 4 /* max # of host lookup types */
-
-#define RES_TIMEOUT 5 /* min. seconds between retries */
-#define MAXRESOLVSORT 10 /* number of net to sort on */
-#define RES_MAXNDOTS 15 /* should reflect bit field size */
-
-struct __res_state {
- int retrans; /* retransmition time interval */
- int retry; /* number of times to retransmit */
- long options; /* option flags - see below. */
- int nscount; /* number of name servers */
- struct sockaddr_in nsaddr_list[MAXNS]; /* address of name server */
-#define nsaddr nsaddr_list[0] /* for backward compatibility */
- u_short id; /* current packet id */
- char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
- char defdname[MAXDNAME]; /* default domain */
- long pfcode; /* RES_PRF_ flags - see below. */
- u_char ndots:4; /* threshold for initial abs. query */
- u_char nsort:4; /* number of elements in sort_list[] */
- char unused[3];
- struct {
- struct in_addr addr;
- u_long mask;
- } sort_list[MAXRESOLVSORT];
- char lookups[MAXDNSLUS];
-};
-
-/*
- * Resolver options
- */
-#define RES_INIT 0x0001 /* address initialized */
-#define RES_DEBUG 0x0002 /* print debug messages */
-#define RES_AAONLY 0x0004 /* authoritative answers only */
-#define RES_USEVC 0x0008 /* use virtual circuit */
-#define RES_PRIMARY 0x0010 /* query primary server only */
-#define RES_IGNTC 0x0020 /* ignore trucation errors */
-#define RES_RECURSE 0x0040 /* recursion desired */
-#define RES_DEFNAMES 0x0080 /* use default domain name */
-#define RES_STAYOPEN 0x0100 /* Keep TCP socket open */
-#define RES_DNSRCH 0x0200 /* search up local domain tree */
-
-#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
-
-/*
- * Resolver "pfcode" values. Used by dig.
- */
-#define RES_PRF_STATS 0x0001
-/* 0x0002 */
-#define RES_PRF_CLASS 0x0004
-#define RES_PRF_CMD 0x0008
-#define RES_PRF_QUES 0x0010
-#define RES_PRF_ANS 0x0020
-#define RES_PRF_AUTH 0x0040
-#define RES_PRF_ADD 0x0080
-#define RES_PRF_HEAD1 0x0100
-#define RES_PRF_HEAD2 0x0200
-#define RES_PRF_TTLID 0x0400
-#define RES_PRF_HEADX 0x0800
-#define RES_PRF_QUERY 0x1000
-#define RES_PRF_REPLY 0x2000
-#define RES_PRF_INIT 0x4000
-/* 0x8000 */
-
-#define _res (*_res_status())
-#define h_errno (_res_get_error())
-
-#include <sys/cdefs.h>
-#include <stdio.h>
-
-/* Private routines shared between libc/net, named, nslookup and others. */
-#define dn_skipname __dn_skipname
-#define fp_query __fp_query
-#define hostalias __hostalias
-#define putlong __putlong
-#define putshort __putshort
-#define p_class __p_class
-#define p_time __p_time
-#define p_type __p_type
-__BEGIN_DECLS
-struct __res_state *_res_status __P_((void));
-int _res_get_error __P_((void));
-
-int __dn_skipname __P_((const u_char *, const u_char *));
-void __fp_query __P_((char *, FILE *));
-char *__hostalias __P_((const char *));
-void __putlong __P_((pthread_ipaddr_type, unsigned char *));
-void __putshort __P_((pthread_ipport_type, unsigned char *));
-char *__p_class __P_((int));
-char *__p_time __P_((unsigned long));
-char *__p_type __P_((int));
-
-int dn_comp __P_((const unsigned char *, unsigned char *, int,
- unsigned char **, unsigned char **));
-int dn_expand __P_((const unsigned char *, const unsigned char *,
- const unsigned char *, unsigned char *, int));
-int res_init __P_((void));
-int res_mkquery __P_((int, const char *, int, int, const char *, int,
- const char *, char *, int));
-int res_send __P_((const char *, int, char *, int));
-__END_DECLS
-
-#endif /* !_RESOLV_H_ */
-
diff --git a/mit-pthreads/include/sched.h b/mit-pthreads/include/sched.h
deleted file mode 100644
index dcd9d4e3600..00000000000
--- a/mit-pthreads/include/sched.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ==== pthread.h ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic pthread header.
- *
- * 1.00 93/08/29 proven
- * -Started coding this file.
- */
-
-#ifndef _SCHED_H_
-#define _SCHED_H_
-
-#include <pthread/prio_queue.h>
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-int sched_yield __P_((void));
-int sched_get_priority_max __P_((int));
-int sched_get_priority_min __P_((int));
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/include/signal.h b/mit-pthreads/include/signal.h
deleted file mode 100644
index 9fb1ec6e2c8..00000000000
--- a/mit-pthreads/include/signal.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)signal.h 8.3 (Berkeley) 3/30/94
- */
-
-#ifndef _SIGNAL_H
-#define _SIGNAL_H
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <sys/__signal.h>
-
-__BEGIN_DECLS
-
-int raise __P_((int));
-/* RETSIGTYPE signal __P_((int __sig, RETSIGTYPE)); */
-
-#ifndef _ANSI_SOURCE
-
-int sigfillset __P_((sigset_t *));
-int sigemptyset __P_((sigset_t *));
-int sigaddset __P_((sigset_t *, int));
-int sigdelset __P_((sigset_t *, int));
-int sigismember __P_((const sigset_t *, int));
-int sigsuspend __P_((const sigset_t *));
-int sigprocmask __P_((int, const sigset_t *, sigset_t *));
-
-/* Still need work */
-int kill __P_((pid_t, int));
-int sigaction __P_((int, const struct sigaction *, struct sigaction *));
-int sigpending __P_((sigset_t *));
-
-#ifndef _POSIX_SOURCE
-
-int killpg __P_((pid_t, int));
-int siginterrupt __P_((int, int));
-void psignal __P_((unsigned int, const char *));
-
-/* int sigpause __P_((int)); */
-/* int sigsetmask __P_((int)); */
-/* int sigblock __P_((int)); */
-/* int sigreturn __P_((struct sigcontext *)); */
-/* int sigvec __P_((int, struct sigvec *, struct sigvec *)); */
-/* int sigstack __P_((const struct sigstack *, struct sigstack *)); */
-
-#endif /* !_POSIX_SOURCE */
-#endif /* !_ANSI_SOURCE */
-
-__END_DECLS
-
-#endif /* !_USER_SIGNAL_H */
diff --git a/mit-pthreads/include/stdio.h b/mit-pthreads/include/stdio.h
deleted file mode 100644
index 538d4685f3f..00000000000
--- a/mit-pthreads/include/stdio.h
+++ /dev/null
@@ -1,371 +0,0 @@
-/* ==== stdio.h ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdio.h 5.17 (Berkeley) 6/3/91
- * $Id$
- */
-
-#ifndef _STDIO_H_
-#define _STDIO_H_
-
-#include <sys/cdefs.h>
-#include <pthread/types.h>
-#include <pthread/posix.h>
-#include <sys/__stdio.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define _FSTDIO /* Define for new stdio with functions. */
-
-/*
- * NB: to fit things in six character monocase externals, the stdio
- * code uses the prefix `__s' for stdio objects, typically followed
- * by a three-character attempt at a mnemonic.
- */
-
-/* stdio buffers */
-struct __sbuf {
- unsigned char *_base;
- int _size;
-};
-
-/*
- * stdio state variables.
- *
- * The following always hold:
- *
- * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
- * _lbfsize is -_bf._size, else _lbfsize is 0
- * if _flags&__SRD, _w is 0
- * if _flags&__SWR, _r is 0
- *
- * This ensures that the getc and putc macros (or inline functions) never
- * try to write or read from a file that is in `read' or `write' mode.
- * (Moreover, they can, and do, automatically switch from read mode to
- * write mode, and back, on "r+" and "w+" files.)
- *
- * _lbfsize is used only to make the inline line-buffered output stream
- * code as compact as possible.
- *
- * _ub, _up, and _ur are used when ungetc() pushes back more characters
- * than fit in the current _bf, or when ungetc() pushes back a character
- * that does not match the previous one in _bf. When this happens,
- * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
- * _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
- */
-typedef struct __sFILE {
- unsigned char *_p; /* current position in (some) buffer */
- int _r; /* read space left for getc() */
- int _w; /* write space left for putc() */
- short _flags; /* flags, below; this FILE is free if 0 */
- short _file; /* fileno, if Unix descriptor, else -1 */
- struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
- int _lbfsize; /* 0 or -_bf._size, for inline putc */
-
- /* separate buffer for long sequences of ungetc() */
- struct __sbuf _ub; /* ungetc buffer */
- unsigned char *_up; /* saved _p when _p is doing ungetc data */
- int _ur; /* saved _r when _r is counting ungetc data */
-
- /* tricks to meet minimum requirements even when malloc() fails */
- unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
- unsigned char _nbuf[1]; /* guarantee a getc() buffer */
-
- /* separate buffer for fgetline() when line crosses buffer boundary */
- struct __sbuf _lb; /* buffer for fgetline() */
-
- /* Unix stdio files get aligned to block boundaries on fseek() */
- int _blksize; /* stat.st_blksize (may be != _bf._size) */
- int _offset; /* current lseek offset */
-} FILE;
-
-__BEGIN_DECLS
-extern FILE __sF[];
-__END_DECLS
-
-#define __SLBF 0x0001 /* line buffered */
-#define __SNBF 0x0002 /* unbuffered */
-#define __SRD 0x0004 /* OK to read */
-#define __SWR 0x0008 /* OK to write */
- /* RD and WR are never simultaneously asserted */
-#define __SRW 0x0010 /* open for reading & writing */
-#define __SEOF 0x0020 /* found EOF */
-#define __SERR 0x0040 /* found error */
-#define __SMBF 0x0080 /* _buf is from malloc */
-#define __SAPP 0x0100 /* fdopen()ed in append mode */
-#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
-#define __SOPT 0x0400 /* do fseek() optimisation */
-#define __SNPT 0x0800 /* do not do fseek() optimisation */
-#define __SOFF 0x1000 /* set iff _offset is in fact correct */
-#define __SMOD 0x2000 /* true => fgetline modified _p text */
-
-/*
- * The following three definitions are for ANSI C, which took them
- * from System V, which brilliantly took internal interface macros and
- * made them official arguments to setvbuf(), without renaming them.
- * Hence, these ugly _IOxxx names are *supposed* to appear in user code.
- *
- * Although numbered as their counterparts above, the implementation
- * does not rely on this.
- */
-#define _IOFBF 0 /* setvbuf should set fully buffered */
-#define _IOLBF 1 /* setvbuf should set line buffered */
-#define _IONBF 2 /* setvbuf should set unbuffered */
-
-#define BUFSIZ 1024 /* size of buffer used by setbuf */
-#define EOF (-1)
-
-/*
- * FOPEN_MAX is a minimum maximum, and should be the number of descriptors
- * that the kernel can provide without allocation of a resource that can
- * fail without the process sleeping. Do not use this for anything.
- */
-#define FOPEN_MAX 20 /* must be <= OPEN_MAX <sys/syslimits.h> */
-#define FILENAME_MAX 1024 /* must be <= PATH_MAX <sys/syslimits.h> */
-
-/* System V/ANSI C; this is the wrong way to do this, do *not* use these. */
-#ifndef _ANSI_SOURCE
-#define P_tmpdir "/var/tmp/"
-#endif
-#define L_tmpnam 1024 /* XXX must be == PATH_MAX */
-#ifndef TMP_MAX
-#define TMP_MAX 308915776
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0 /* set file offset to offset */
-#endif
-#ifndef SEEK_CUR
-#define SEEK_CUR 1 /* set file offset to current plus offset */
-#endif
-#ifndef SEEK_END
-#define SEEK_END 2 /* set file offset to EOF plus offset */
-#endif
-
-#define stdin (&__sF[0])
-#define stdout (&__sF[1])
-#define stderr (&__sF[2])
-
-/*
- * Functions defined in ANSI C standard.
- */
-__BEGIN_DECLS
-void clearerr __P_((FILE *));
-int fclose __P_((FILE *));
-int feof __P_((FILE *));
-int ferror __P_((FILE *));
-int fflush __P_((FILE *));
-int fgetc __P_((FILE *));
-int fgetpos __P_((FILE *, fpos_t *));
-char * fgets __P_((char *, size_t, FILE *));
-FILE * fopen __P_((const char *, const char *));
-int fprintf __P_((FILE *, const char *, ...));
-int fputc __P_((int, FILE *));
-int fputs __P_((const char *, FILE *));
-size_t fread __P_((void *, size_t, size_t, FILE *));
-FILE * freopen __P_((const char *, const char *, FILE *));
-int fscanf __P_((FILE *, const char *, ...));
-int fseek __P_((FILE *, long, int));
-int fsetpos __P_((FILE *, const fpos_t *));
-long ftell __P_((const FILE *));
-size_t fwrite __P_((const void *, size_t, size_t, FILE *));
-int getc __P_((FILE *));
-int getchar __P_((void));
-char * gets __P_((char *));
-
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-extern int sys_nerr; /* perror(3) external variables */
-/* Under NetBSD and BSD 4.4, at least, this is expected to be a const
- array of pointers to const. If you take `const' back out of this
- declaration, please make it conditional on __NetBSD__ and bsd4_4. */
-#ifdef HAVE_SYS_ERRLIST_WITHOUT_CONST
-extern char *sys_errlist[];
-#else
-extern const char *const sys_errlist[];
-#endif
-#endif
-
-void perror __P_((const char *));
-int printf __P_((const char *, ...));
-int putc __P_((int, FILE *));
-int putchar __P_((int));
-int puts __P_((const char *));
-int remove __P_((const char *));
-int rename __P_((const char *, const char *));
-void rewind __P_((FILE *));
-int scanf __P_((const char *, ...));
-void setbuf __P_((FILE *, char *));
-int setvbuf __P_((FILE *, char *, int, size_t));
-int sprintf __P_((char *, const char *, ...));
-int sscanf __P_((const char *, const char *, ...));
-FILE * tmpfile __P_((void));
-char * tmpnam __P_((char *));
-int ungetc __P_((int, FILE *));
-int vfprintf __P_((FILE *, const char *, pthread_va_list));
-int vprintf __P_((const char *, pthread_va_list));
-int vsprintf __P_((char *, const char *, pthread_va_list));
-char *mprintf __P_((const char *, ...));
-char *vmprintf __P_((const char *, pthread_va_list));
-__END_DECLS
-
-/*
- * Functions defined in POSIX 1003.1.
- */
-#ifndef _ANSI_SOURCE
-#define L_ctermid 1024 /* size for ctermid(); PATH_MAX */
-#define L_cuserid 9 /* size for cuserid(); UT_NAMESIZE + 1 */
-
-__BEGIN_DECLS
-char * ctermid __P_((char *));
-char * cuserid __P_((char *));
-FILE * fdopen __P_((int, const char *));
-int fileno __P_((FILE *));
-__END_DECLS
-#endif /* not ANSI */
-
-/*
- * Functions defined in POSIX 1003.4a. (1c)
- */
-#ifndef _ANSI_SOURCE
-__BEGIN_DECLS
-void flockfile __P_((FILE *));
-void funlockfile __P_((FILE *));
-int ftrylockfile __P_((FILE *));
-__END_DECLS
-#endif /* not ANSI */
-
-/*
- * Routines that are purely local.
- */
-#if !defined (_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-char *fgetline __P_((FILE *, size_t *));
-int fpurge __P_((FILE *));
-int getw __P_((FILE *));
-int pclose __P_((FILE *));
-FILE *popen __P_((const char *, const char *));
-int putw __P_((int, FILE *));
-void setbuffer __P_((FILE *, char *, int));
-int setlinebuf __P_((FILE *));
-char *tempnam __P_((const char *, const char *));
-int snprintf __P_((char *, size_t, const char *, ...));
-int vsnprintf __P_((char *, size_t, const char *, pthread_va_list));
-int vscanf __P_((const char *, pthread_va_list));
-int vsscanf __P_((const char *, const char *, pthread_va_list));
-__END_DECLS
-
-/*
- * This is a #define because the function is used internally and
- * (unlike vfscanf) the name __svfscanf is guaranteed not to collide
- * with a user function when _ANSI_SOURCE or _POSIX_SOURCE is defined.
- */
-#define vfscanf __svfscanf
-
-/*
- * Stdio function-access interface.
- */
-__BEGIN_DECLS
-FILE *funopen __P_((const void *,
- int (*)(void *, char *, int),
- int (*)(void *, const char *, int),
- fpos_t (*)(void *, fpos_t, int),
- int (*)(void *)));
-__END_DECLS
-#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
-#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
-#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
-
-/*
- * Functions internal to the implementation.
- */
-__BEGIN_DECLS
-int __srget __P_((FILE *));
-int __svfscanf __P_((FILE *, const char *, pthread_va_list));
-int __swbuf __P_((int, FILE *));
-__END_DECLS
-
-/*
- * The __sfoo macros are here so that we can
- * define function versions in the C library.
- */
-#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
-
-__BEGIN_DECLS
-int __getc __P_((FILE *));
-__END_DECLS
-
-#define getc(fp) __getc(fp)
-#define getchar() getc(stdin)
-#define getc_unlocked(fp) __sgetc(fp)
-#define getchar_unlocked() getc_unlocked(stdin)
-
-#ifdef __CAN_DO_EXTERN_INLINE
-__INLINE int __sputc(int _c, FILE *_p)
-{
- if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
- return (*_p->_p++ = _c);
- else
- return (__swbuf(_c, _p));
-}
-#else
-__BEGIN_DECLS
-int __sputc __P_((int, FILE *));
-__END_DECLS
-#endif
-
-__BEGIN_DECLS
-int __putc __P_((int, FILE *));
-__END_DECLS
-
-#define putc(x, fp) __putc(x, fp)
-#define putchar(x) putc(x, stdout)
-#define putc_unlocked(x, fp) __sputc(x, fp)
-#define putchar_unlocked(x) putc_unlocked(x, stdout)
-
-#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
-#define __sferror(p) (((p)->_flags & __SERR) != 0)
-#define __sfileno(p) ((p)->_file)
-
-#define feof(p) __sfeof(p)
-#define ferror(p) __sferror(p)
-
-#ifndef _ANSI_SOURCE
-#define fileno(p) __sfileno(p)
-#endif
-
-#endif
diff --git a/mit-pthreads/include/stdlib.h b/mit-pthreads/include/stdlib.h
deleted file mode 100644
index 77f84ffa0bb..00000000000
--- a/mit-pthreads/include/stdlib.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _STDLIB_H_
-#define _STDLIB_H_
-
-#include <sys/__stdlib.h>
-
-/* Returned by `div'. */
-typedef struct
- {
- int quot; /* Quotient. */
- int rem; /* Remainder. */
- } div_t;
-
-/* Returned by `ldiv'. */
-typedef struct
- {
- long quot; /* Quotient. */
- long rem; /* Remainder. */
- } ldiv_t;
-
-#ifndef RAND_MAX
-#define RAND_MAX 2147483647
-#endif
-
-#define EXIT_FAILURE 1 /* Failing exit status. */
-#define EXIT_SUCCESS 0 /* Successful exit status. */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-double atof __P_((const char *));
-int atoi __P_((const char *));
-long atol __P_((const char *));
-double strtod __P_((const char *, char **));
-long strtol __P_((const char *, char **, int));
-unsigned long strtoul __P_((const char *, char **, int));
-
-int rand __P_((void));
-void srand __P_((unsigned int));
-
-long random __P_((void));
-void srandom __P_((unsigned int));
-char * initstate __P_((unsigned int, char *, int));
-char * setstate __P_((char *));
-
-void * malloc __P_((size_t));
-void * realloc __P_((void *, size_t));
-void * calloc __P_((size_t, size_t));
-void free __P_((void *));
-
-__NORETURN void abort __P_((void));
-int atexit __P_((void (* __func)() ));
-__NORETURN void exit __P_((int));
-int system __P_((const char *));
-
-extern char ** environ;
-
-char * getenv __P_((const char *));
-int putenv __P_((const char *));
-int setenv __P_((const char *, const char *, int));
-void unsetenv __P_((const char *));
-
-void * bsearch __P_((const void *, const void *, size_t, size_t,
- int (* __func)__P_((const void *, const void *)) ));
-void qsort __P_((void *, size_t, size_t,
- int (* __func)__P_((const void *, const void *)) ));
-
-int abs __P_((int));
-long labs __P_((long));
-div_t div __P_((int, int));
-ldiv_t ldiv __P_((long, long));
-
-void * memchr __P_((const void *, int, size_t));
-
-/* Stuff to do */
-int mblen __P_((const char *, size_t));
-int mbtowc __P_((wchar_t *, const char *, size_t));
-int wctomb __P_((char *, wchar_t));
-size_t mbstowcs __P_((wchar_t *, const char *, size_t));
-size_t wcstombs __P_((char *, const wchar_t *, size_t));
-
-
-__END_DECLS
-
-#endif /* !_STDLIB_H_ */
diff --git a/mit-pthreads/include/string.h b/mit-pthreads/include/string.h
deleted file mode 100644
index 4143a1cfec7..00000000000
--- a/mit-pthreads/include/string.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* $NetBSD: string.h,v 1.6 1994/10/26 00:56:30 cgd Exp $ */
-
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)string.h 5.10 (Berkeley) 3/9/91
- */
-
-#ifndef _STRING_H_
-#define _STRING_H_
-#include <sys/cdefs.h>
-#include <pthread/types.h>
-#include <pthread/posix.h>
-#include <sys/__string.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-__BEGIN_DECLS
-void *memchr __P_((const void *, int, size_t));
-int memcmp __P_((const void *, const void *, size_t));
-void *memcpy __P_((void *, const void *, size_t));
-void *memmove __P_((void *, const void *, size_t));
-void *memset __P_((void *, int, size_t));
-char *strcat __P_((char *, const char *));
-char *strchr __P_((const char *, int));
-int strcmp __P_((const char *, const char *));
-int strcoll __P_((const char *, const char *));
-char *strcpy __P_((char *, const char *));
-size_t strcspn __P_((const char *, const char *));
-char *strerror __P_((int));
-size_t strlen __P_((const char *));
-char *strncat __P_((char *, const char *, size_t));
-int strncmp __P_((const char *, const char *, size_t));
-char *strncpy __P_((char *, const char *, size_t));
-char *strpbrk __P_((const char *, const char *));
-char *strrchr __P_((const char *, int));
-size_t strspn __P_((const char *, const char *));
-char *strstr __P_((const char *, const char *));
-char *strtok __P_((char *, const char *));
-char *strtok_r __P_((char *, const char *, char **));
-size_t strxfrm __P_((char *, const char *, size_t));
-
-/* Nonstandard routines common to all pthreads supported platforms */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-int ffs __P_((int));
-void *memccpy __P_((void *, const void *, int, size_t));
-int strcasecmp __P_((const char *, const char *));
-int strncasecmp __P_((const char *, const char *, size_t));
-char *strsignal __P_((int));
-void swab __P_((const void *, void *, size_t));
-#endif
-__END_DECLS
-
-#endif /* _STRING_H_ */
diff --git a/mit-pthreads/include/syslog.h b/mit-pthreads/include/syslog.h
deleted file mode 100644
index 31b42285fc1..00000000000
--- a/mit-pthreads/include/syslog.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- *
- * @(#)syslog.h 7.8 (Berkeley) 5/26/88
- */
-
-#ifndef SYSLOG_H
-#define SYSLOG_H
-
-/* Added __[BEGIN/END]_DECLS so this file would work with C++. (mevans) */
-#include <sys/cdefs.h>
-#include <stdarg.h>
-
-/* Discipline: openlog(), closelog(), and setlogmask() are not thread-safe
- * and should only be called when other threads will not be calling syslog
- * functions. syslog() and vsyslog() are thread-safe and may be called
- * asynchronously, even if openlog() has not been called. */
-
-/*
- * Facility codes
- */
-
-#define LOG_KERN (0<<3) /* kernel messages */
-#define LOG_USER (1<<3) /* random user-level messages */
-#define LOG_MAIL (2<<3) /* mail system */
-#define LOG_DAEMON (3<<3) /* system daemons */
-#define LOG_AUTH (4<<3) /* security/authorization messages */
-#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
-#define LOG_LPR (6<<3) /* line printer subsystem */
-#define LOG_NEWS (7<<3) /* network news subsystem */
-#define LOG_UUCP (8<<3) /* UUCP subsystem */
- /* other codes through 15 reserved for system use */
-#define LOG_LOCAL0 (16<<3) /* reserved for local use */
-#define LOG_LOCAL1 (17<<3) /* reserved for local use */
-#define LOG_LOCAL2 (18<<3) /* reserved for local use */
-#define LOG_LOCAL3 (19<<3) /* reserved for local use */
-#define LOG_LOCAL4 (20<<3) /* reserved for local use */
-#define LOG_LOCAL5 (21<<3) /* reserved for local use */
-#define LOG_LOCAL6 (22<<3) /* reserved for local use */
-#define LOG_LOCAL7 (23<<3) /* reserved for local use */
-
-#define LOG_NFACILITIES 24 /* maximum number of facilities */
-#define LOG_FACMASK 0x03f8 /* mask to extract facility part */
-
-#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3) /* facility of pri */
-
-/*
- * Priorities (these are ordered)
- */
-
-#define LOG_EMERG 0 /* system is unusable */
-#define LOG_ALERT 1 /* action must be taken immediately */
-#define LOG_CRIT 2 /* critical conditions */
-#define LOG_ERR 3 /* error conditions */
-#define LOG_WARNING 4 /* warning conditions */
-#define LOG_NOTICE 5 /* normal but signification condition */
-#define LOG_INFO 6 /* informational */
-#define LOG_DEBUG 7 /* debug-level messages */
-
-#define LOG_PRIMASK 0x0007 /* mask to extract priority part (internal) */
-#define LOG_PRI(p) ((p) & LOG_PRIMASK) /* extract priority */
-
-#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
-
-#ifdef KERNEL
-#define LOG_PRINTF -1 /* pseudo-priority to indicate use of printf */
-#endif
-
-/*
- * arguments to setlogmask.
- */
-#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
-#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */
-
-/*
- * Option flags for openlog.
- *
- * LOG_ODELAY no longer does anything; LOG_NDELAY is the
- * inverse of what it used to be.
- */
-#define LOG_PID 0x01 /* log the pid with each message */
-#define LOG_CONS 0x02 /* log on the console if errors in sending */
-#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */
-#define LOG_NDELAY 0x08 /* don't delay open */
-#define LOG_NOWAIT 0x10 /* if forking to log on console, don't wait() */
-
-__BEGIN_DECLS
-
-/* Syslogging functions. */
-void syslog(int pri, char *fmt, ...);
-void vsyslog(int pri, char *fmt, va_list args);
-void openlog(char *ident, int logstat, int logfac);
-void closelog(void);
-int setlogmask(int pmask);
-
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/include/time.h b/mit-pthreads/include/time.h
deleted file mode 100644
index 614bbeb2a59..00000000000
--- a/mit-pthreads/include/time.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _TIME_H_
-#define _TIME_H_
-
-#include <sys/__time.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef __hpux__
-struct tm {
- int tm_sec; /* seconds after the minute [0-60] */
- int tm_min; /* minutes after the hour [0-59] */
- int tm_hour; /* hours since midnight [0-23] */
- int tm_mday; /* day of the month [1-31] */
- int tm_mon; /* months since January [0-11] */
- int tm_year; /* years since 1900 */
- int tm_wday; /* days since Sunday [0-6] */
- int tm_yday; /* days since January 1 [0-365] */
- int tm_isdst; /* Daylight Savings Time flag */
- long tm_gmtoff; /* offset from CUT in seconds */
- char *tm_zone; /* timezone abbreviation */
-};
-#endif /* __hpux__ */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-/* clock_t clock __P_((void)); */
-
-char * asctime __P_((const struct tm *));
-double difftime __P_((time_t, time_t));
-char * ctime __P_((const time_t *));
-struct tm * gmtime __P_((const time_t *));
-struct tm * localtime __P_((const time_t *));
-
-char * asctime_r __P_((const struct tm *, char *));
-char * ctime_r __P_((const time_t *, char *));
-struct tm * gmtime_r __P_((const time_t *, struct tm *));
-struct tm * localtime_r __P_((const time_t *, struct tm *));
-
-time_t mktime __P_((struct tm *));
-
-/* size_t strftime __P_((char *, size_t, const char *, const struct tm *)); */
-time_t time __P_((time_t *));
-
-#if !defined(_ANSI_SOURCE)
-/* #define CLK_TCK 100 */
-extern char *tzname[2];
-void tzset __P_((void));
-#endif /* not ANSI */
-
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-/* char *timezone __P_((int, int)); */
-void tzsetwall __P_((void));
-#endif /* neither ANSI nor POSIX */
-
-__END_DECLS
-
-#endif /* !_TIME_H_ */
diff --git a/mit-pthreads/include/timers.h b/mit-pthreads/include/timers.h
deleted file mode 100644
index 9a0196a3631..00000000000
--- a/mit-pthreads/include/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _TIMERS_H_
-#define _TIMERS_H_
-
-#include <sys/timers.h>
-
-#endif
diff --git a/mit-pthreads/include/tzfile.h b/mit-pthreads/include/tzfile.h
deleted file mode 100644
index 7a486302e10..00000000000
--- a/mit-pthreads/include/tzfile.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Arthur David Olson of the National Cancer Institute.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)tzfile.h 5.10 (Berkeley) 4/3/91
- * $Id$
- */
-
-#ifndef _TZFILE_H_
-#define _TZFILE_H_
-
-#include <pthread/paths.h>
-
-/*
- * Information about time zone files.
- */
-#define TZDIR _PATH_TZDIR
-#define TZDEFAULT _PATH_TZFILE
-#define TZDEFRULES "posixrules"
-
-/*
-** Each file begins with. . .
-*/
-
-struct tzhead {
- char tzh_reserved[24]; /* reserved for future use */
- char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
- char tzh_leapcnt[4]; /* coded number of leap seconds */
- char tzh_timecnt[4]; /* coded number of transition times */
- char tzh_typecnt[4]; /* coded number of local time types */
- char tzh_charcnt[4]; /* coded number of abbr. chars */
-};
-
-/*
-** . . .followed by. . .
-**
-** tzh_timecnt (char [4])s coded transition times a la time(2)
-** tzh_timecnt (unsigned char)s types of local time starting at above
-** tzh_typecnt repetitions of
-** one (char [4]) coded GMT offset in seconds
-** one (unsigned char) used to set tm_isdst
-** one (unsigned char) that's an abbreviation list index
-** tzh_charcnt (char)s '\0'-terminated zone abbreviations
-** tzh_leapcnt repetitions of
-** one (char [4]) coded leap second transition times
-** one (char [4]) total correction after above
-** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition
-** time is standard time, if FALSE,
-** transition time is wall clock time
-** if absent, transition times are
-** assumed to be wall clock time
-*/
-
-/*
-** In the current implementation, "tzset()" refuses to deal with files that
-** exceed any of the limits below.
-*/
-
-/*
-** The TZ_MAX_TIMES value below is enough to handle a bit more than a
-** year's worth of solar time (corrected daily to the nearest second) or
-** 138 years of Pacific Presidential Election time
-** (where there are three time zone transitions every fourth year).
-*/
-#define TZ_MAX_TIMES 370
-
-#define NOSOLAR /* 4BSD doesn't currently handle solar time */
-
-#ifndef NOSOLAR
-#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
-#else
-#define TZ_MAX_TYPES 10 /* Maximum number of local time types */
-#endif
-
-#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
-
-#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
-
-#define SECSPERMIN 60
-#define MINSPERHOUR 60
-#define HOURSPERDAY 24
-#define DAYSPERWEEK 7
-#define DAYSPERNYEAR 365
-#define DAYSPERLYEAR 366
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR 12
-
-#define TM_SUNDAY 0
-#define TM_MONDAY 1
-#define TM_TUESDAY 2
-#define TM_WEDNESDAY 3
-#define TM_THURSDAY 4
-#define TM_FRIDAY 5
-#define TM_SATURDAY 6
-
-#define TM_JANUARY 0
-#define TM_FEBRUARY 1
-#define TM_MARCH 2
-#define TM_APRIL 3
-#define TM_MAY 4
-#define TM_JUNE 5
-#define TM_JULY 6
-#define TM_AUGUST 7
-#define TM_SEPTEMBER 8
-#define TM_OCTOBER 9
-#define TM_NOVEMBER 10
-#define TM_DECEMBER 11
-
-#define TM_YEAR_BASE 1900
-
-#define EPOCH_YEAR 1970
-#define EPOCH_WDAY TM_THURSDAY
-
-/*
-** Accurate only for the past couple of centuries;
-** that will probably do.
-*/
-
-#define isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0)
-
-#endif /* !_TZFILE_H_ */
-
diff --git a/mit-pthreads/include/unistd.h b/mit-pthreads/include/unistd.h
deleted file mode 100644
index 213aa983172..00000000000
--- a/mit-pthreads/include/unistd.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)unistd.h 5.13 (Berkeley) 6/17/91
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <sys/cdefs.h>
-#include <sys/__unistd.h>
-
-#define R_OK 4
-#define W_OK 2
-#define X_OK 1
-#define F_OK 0
-
-#ifndef SEEK_SET
-#define SEEK_SET 0 /* set file offset to offset */
-#endif
-#ifndef SEEK_CUR
-#define SEEK_CUR 1 /* set file offset to current plus offset */
-#endif
-#ifndef SEEK_END
-#define SEEK_END 2 /* set file offset to EOF plus offset */
-#endif
-
-#define STDIN_FILENO 0 /* standard input file descriptor */
-#define STDOUT_FILENO 1 /* standard output file descriptor */
-#define STDERR_FILENO 2 /* standard error file descriptor */
-
-__BEGIN_DECLS
-void _exit __P_((int));
-int access __P_((const char *, int));
-int chdir __P_((const char *));
-int chown __P_((const char *, uid_t, gid_t));
-int close __P_((int));
-int dup __P_((int));
-int dup2 __P_((int, int));
-int execve __P_((const char *, char * const *, char * const *));
-pid_t fork __P_((void));
-int isatty __P_((int));
-int link __P_((const char *, const char *));
-off_t lseek __P_((int, off_t, int));
-int pipe __P_((int *));
-ssize_t read __P_((int, void *, size_t));
-unsigned sleep __P_((unsigned));
-char *ttyname __P_((int));
-int unlink __P_((const char *));
-ssize_t write __P_((int, const void *, size_t));
-
-/* Not implemented for threads yet */
-unsigned alarm __P_((unsigned));
-char *cuserid __P_((char *));
-int execl __P_((const char *, const char *, ...));
-int execle __P_((const char *, const char *, ...));
-int execlp __P_((const char *, const char *, ...));
-int execv __P_((const char *, char * const *));
-int execvp __P_((const char *, char * const *));
-long fpathconf __P_((int, int)); /* not yet */
-char *getcwd __P_((char *, size_t));
-gid_t getegid __P_((void));
-uid_t geteuid __P_((void));
-gid_t getgid __P_((void));
-int getgroups __P_((int, gid_t *)); /* XXX (gid_t *) */
-char *getlogin __P_((void));
-pid_t getpgrp __P_((void));
-pid_t getpid __P_((void));
-pid_t getppid __P_((void));
-uid_t getuid __P_((void));
-long pathconf __P_((const char *, int)); /* not yet */
-int pause __P_((void));
-int rmdir __P_((const char *));
-int setgid __P_((gid_t));
-int setpgid __P_((pid_t, pid_t));
-pid_t setsid __P_((void));
-int setuid __P_((uid_t));
-long sysconf __P_((int)); /* not yet */
-pid_t tcgetpgrp __P_((int));
-int tcsetpgrp __P_((int, pid_t));
-
-#ifndef _POSIX_SOURCE
-
-int acct __P_((const char *));
-int async_daemon __P_((void));
-char *brk __P_((const char *));
-/* int chflags __P_((const char *, long)); */
-int chroot __P_((const char *));
-char *crypt __P_((const char *, const char *));
-int des_cipher __P_((const char *, char *, long, int));
-void des_setkey __P_((const char *key));
-void encrypt __P_((char *, int));
-void endusershell __P_((void));
-int exect __P_((const char *, char * const *, char * const *));
-int fchdir __P_((int));
-/* int fchflags __P_((int, long)); */
-int fchown __P_((int, uid_t, gid_t));
-int fsync __P_((int));
-int ftruncate __P_((int, off_t));
-int getdtablesize __P_((void));
-long gethostid __P_((void));
-int gethostname __P_((char *, int));
-mode_t getmode __P_((const void *, mode_t));
-int getpagesize __P_((void));
-char *getpass __P_((const char *));
-char *getusershell __P_((void));
-char *getwd __P_((char *)); /* obsoleted by getcwd() */
-int initgroups __P_((const char *, gid_t));
-int mknod __P_((const char *, mode_t, dev_t));
-int mkstemp __P_((char *));
-char *mktemp __P_((char *));
-int nfssvc __P_((int));
-int nice __P_((int));
-void psignal __P_((unsigned, const char *));
-/* extern char *sys_siglist[]; */
-int profil __P_((char *, int, int, int));
-int rcmd __P_((char **, int, const char *,
- const char *, const char *, int *));
-char *re_comp __P_((const char *));
-int re_exec __P_((const char *));
-int readlink __P_((const char *, char *, int));
-int reboot __P_((int));
-int revoke __P_((const char *));
-int rresvport __P_((int *));
-int ruserok __P_((const char *, int, const char *, const char *));
-char *sbrk __P_((int));
-int setegid __P_((gid_t));
-int seteuid __P_((uid_t));
-int setgroups __P_((int, const gid_t *));
-void sethostid __P_((long));
-int sethostname __P_((const char *, int));
-void setkey __P_((const char *));
-int setlogin __P_((const char *));
-void *setmode __P_((const char *));
-int setpgrp __P_((pid_t pid, pid_t pgrp)); /* obsoleted by setpgid() */
-int setregid __P_((int, int));
-int setreuid __P_((int, int));
-int setrgid __P_((gid_t));
-int setruid __P_((uid_t));
-void setusershell __P_((void));
-int swapon __P_((const char *));
-int symlink __P_((const char *, const char *));
-void sync __P_((void));
-int syscall __P_((int, ...));
-int truncate __P_((const char *, off_t));
-int ttyslot __P_((void));
-unsigned ualarm __P_((unsigned, unsigned));
-void usleep __P_((unsigned));
-int vfork __P_((void));
-
-#endif /* !_POSIX_SOURCE */
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/lib/.cvsignore b/mit-pthreads/lib/.cvsignore
deleted file mode 100644
index f3c7a7c5da6..00000000000
--- a/mit-pthreads/lib/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
diff --git a/mit-pthreads/lib/Makefile.in b/mit-pthreads/lib/Makefile.in
deleted file mode 100644
index 821d293d896..00000000000
--- a/mit-pthreads/lib/Makefile.in
+++ /dev/null
@@ -1,48 +0,0 @@
-# === GNUmakefile ============================================================
-# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating the test programs for libpthread.a
-#
-# 1.00 93/08/03 proven
-# -Initial cut for pthreads.
-#
-
-CC = ../pgcc -notinstalled
-srctop = @srctop@
-srcdir = @srctop@/lib
-VPATH = @srctop@/lib
-CDEBUGFLAGS = @CFLAGS@
-
-CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(ADDL_CFLAGS) -DSRCDIR=\"$(srcdir)\"
-
-#
-DIRS = libpthreadutil
-
-################################################################################
-#
-all:
- (for i in $(DIRS); do cd $$i; $(MAKE) all; cd ..; done)
-
-clean:
- (for i in $(DIRS); do cd $$i; $(MAKE) clean; cd ..; done)
- rm -f *.o $(TESTS) $(BENCHMARKS) a.out core maketmp makeout
-
-depend:
- (for i in $(DIRS); do cd $$i; $(MAKE) depend; cd ..; done)
- sed '/\#\#\# Dependencies/q' < Makefile > maketmp
- (for i in $(CSRC);do $(CPP) -M $$i;done) >> maketmp
- cp maketmp Makefile
-
-install:
- (for i in $(DIRS); do cd $$i; $(MAKE) install; cd ..; done)
-
-realclean: clean
- (for i in $(DIRS); do cd $$i; $(MAKE) realclean; cd ..; done)
- rm -f Makefile
-
-Makefile: Makefile.in
- (cd .. ; sh config.status)
-
-################################################################################
-### Do not remove the following line. It is for depend #########################
-### Dependencies:
diff --git a/mit-pthreads/lib/libpthreadutil/.cvsignore b/mit-pthreads/lib/libpthreadutil/.cvsignore
deleted file mode 100644
index f3c7a7c5da6..00000000000
--- a/mit-pthreads/lib/libpthreadutil/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
diff --git a/mit-pthreads/lib/libpthreadutil/Makefile.in b/mit-pthreads/lib/libpthreadutil/Makefile.in
deleted file mode 100755
index 94034f426b3..00000000000
--- a/mit-pthreads/lib/libpthreadutil/Makefile.in
+++ /dev/null
@@ -1,65 +0,0 @@
-# === makefile ============================================================
-# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating the test programs for libpthread.a
-#
-# 1.00 93/08/03 proven
-# -Initial cut for pthreads.
-#
-
-srctop = @srctop@
-srcdir = @srctop@/lib/libpthreadutil
-VPATH = @srctop@/lib/libpthreadutil
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-
-INSTALL_PATH = @exec_prefix@
- BINDIR = $(INSTALL_PATH)/bin
- LIBDIR = $(INSTALL_PATH)/lib
- MANDIR = $(INSTALL_PATH)/man
- INCDIR = $(INSTALL_PATH)/include
-
- CC = ../../pgcc -notinstalled
- CDEBUGFLAGS = @CFLAGS@
- CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(ADDL_CFLAGS) -DSRCDIR=\"$(srcdir)\"
- RANLIB = @RANLIB@
-
- OBJS = pthread_tad.o pthread_atexit.o
- LIBRARY = libpthreadutil.a
- HEADERS = pthreadutil.h
-
-################################################################################
-#
-all : $(LIBRARY)
-
-clean:
- rm -f *.o $(TESTS) $(BENCHMARKS) a.out core maketmp makeout
-
-depend:
- sed '/\#\#\# Dependencies/q' < Makefile > maketmp
- (for i in $(CSRC);do $(CPP) -M $$i;done) >> maketmp
- cp maketmp Makefile
-
-install: $(LIBRARY)
- install $(LIBRARY) $(LIBDIR)
- for x in $(HEADERS); \
- do cp $(srcdir)/$$x $(INCDIR); \
- done
-
-realclean: clean
- rm -f Makefile
-
-Makefile: Makefile.in
- (cd ../.. ; sh config.status)
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
-$(LIBRARY) : ${OBJS}
- ar r new.a ${OBJS} && \
- $(RANLIB) new.a && \
- mv -f new.a $(LIBRARY)
-
-################################################################################
-### Do not remove the following line. It is for depend #########################
-### Dependencies:
diff --git a/mit-pthreads/lib/libpthreadutil/pthread_atexit.c b/mit-pthreads/lib/libpthreadutil/pthread_atexit.c
deleted file mode 100755
index f244fbfb0c8..00000000000
--- a/mit-pthreads/lib/libpthreadutil/pthread_atexit.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* ==== pthread_atexit.c =====================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread attribute functions.
- *
- * 1.20 94/02/13 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#define PTHREAD_KERNEL
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "pthreadutil.h"
-
-static int pthread_atexit_inited = 0;
-static pthread_key_t pthread_atexit_key;
-static pthread_mutex_t pthread_atexit_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/* ==========================================================================
- * pthread_atexit_done()
- */
-static void pthread_atexit_done(void * arg)
-{
- pthread_atexit_t id, id_next;
-
- for (id = arg; id; id = id_next) {
- id_next = id->next;
- id->rtn(id->arg);
- free(id);
- }
-}
-
-/* ==========================================================================
- * pthread_atexit_add()
- */
-int pthread_atexit_add(pthread_atexit_t *id, void (*rtn)(void *), void * arg)
-{
- int ret;
-
- if (ret = pthread_mutex_lock(&pthread_atexit_mutex)) {
- return(ret);
- }
- if (!pthread_atexit_inited) {
- if (ret = pthread_key_create(&pthread_atexit_key, pthread_atexit_done)){
- pthread_mutex_unlock(&pthread_atexit_mutex);
- return(ret);
- }
- pthread_atexit_inited++;
- }
- pthread_mutex_unlock(&pthread_atexit_mutex);
-
- if ((*id) = (pthread_atexit_t)malloc(sizeof(struct pthread_atexit))) {
- if ((*id)->next = pthread_getspecific(pthread_atexit_key)) {
- (*id)->next->prev = (*id);
- }
- pthread_setspecific(pthread_atexit_key, (void *)*id);
- (*id)->prev = NULL;
- (*id)->rtn = rtn;
- (*id)->arg = arg;
- return(OK);
- }
- return(ENOMEM);
-}
-
-/* ==========================================================================
- * pthread_atexit_remove()
- */
-int pthread_atexit_remove(pthread_atexit_t * id, int execute)
-{
- pthread_atexit_t old;
-
- if (old = pthread_getspecific(pthread_atexit_key)) {
- if (old == *id) {
- old = old->next;
- old->prev = NULL;
- pthread_setspecific(pthread_atexit_key, old);
- } else {
- if ((*id)->next) {
- (*id)->next->prev = (*id)->prev;
- }
- (*id)->prev->next = (*id)->next;
- }
- if (execute) {
- (*id)->rtn((*id)->arg);
- }
- free((*id));
- return(OK);
- }
- return(EINVAL);
-}
-
-/* ==========================================================================
- * A few non void functions that are often used as void functions
- */
-void fflush_nrv(void * fp) { fflush((FILE *)fp); }
-void fclose_nrv(void * fp) { fclose((FILE *)fp); }
-
-void pthread_attr_destroy_nrv(void * attr)
-{
- pthread_attr_destroy((pthread_attr_t *)attr);
-}
diff --git a/mit-pthreads/lib/libpthreadutil/pthread_tad.c b/mit-pthreads/lib/libpthreadutil/pthread_tad.c
deleted file mode 100755
index a59fd9b87bf..00000000000
--- a/mit-pthreads/lib/libpthreadutil/pthread_tad.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* ==== pthread_tad.c =========================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@athena.mit.edu
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano,
- * and its contributors.
- * 4. Neither the name of Chris Provenzano, nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO, AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef lint
-static char copyright[] =
- "@(#) Copyright (c) 1995 Chris Provenzano.\nAll rights reserved.\n";
-#endif /* not lint */
-
-/* tad = thread allocation domain */
-#define PTHREAD_KERNEL
-
-#include "pthreadutil.h"
-#include <stdio.h>
-#include <errno.h>
-
-int pthread_tad_count(pthread_tad_t * tad)
-{
- int ret;
-
- pthread_mutex_lock(&tad->mutex);
- ret = tad->count_current;
- pthread_mutex_unlock(&tad->mutex);
- return(ret);
-}
-
-static void pthread_tad_done(void * arg)
-{
- pthread_tad_t * tad = arg;
- pthread_mutex_lock(&tad->mutex);
- --tad->count_current;
-/* if (--tad->count_current < tad->count_max) */
- pthread_cond_broadcast(&tad->cond);
- pthread_mutex_unlock(&tad->mutex);
-}
-
-#ifndef PTHREAD_KERNEL
-struct tad_start {
- pthread_tad_t * tad;
- void * (*routine)();
- void * arg;
-};
-
-static void * pthread_tad_start(struct tad_start * tad_start)
-{
- void * (*routine)() = tad_start->routine;
- void * arg = tad_start->arg;
-
- pthread_mutex_lock(&tad_start->tad->mutex);
- pthread_cleanup_push(pthread_tad_done, tad_start->tad);
- pthread_mutex_unlock(&tad_start->tad->mutex);
- free(tad_start);
- return(routine(arg));
-}
-#else
-static void * pthread_tad_start(void * tad_start_arg)
-{
- pthread_tad_t * tad = tad_start_arg;
- void * (*routine)() = tad->routine;
- void * arg = tad->arg;
-
- tad->count_current++;
- pthread_cleanup_push(pthread_tad_done, tad);
- pthread_mutex_unlock(&tad->mutex);
- return(routine(arg));
-}
-#endif
-
-int pthread_tad_create(pthread_tad_t * tad, pthread_t *thread_id,
- pthread_attr_t *attr, void * (*routine)(), void * arg)
-{
-#ifndef PTHREAD_KERNEL
- struct tad_start tad;
-#endif
- int ret;
-
- pthread_mutex_lock(&tad->mutex);
- while (tad->count_max && (tad->count_current > tad->count_max))
- pthread_cond_wait(&tad->cond, &tad->mutex);
-
-#ifndef PTHREAD_KERNEL
- if ((tad_start = malloc(sizeof(struct tad_start))) == NULL) {
- pthread_mutex_unlock(&tad->mutex);
- return(ENOMEM);
- }
- tad_start->routine = routine;
- tad_start->arg = arg;
- tad_start->tad = tad;
- if ((ret = pthread_create(thread_id, attr,
- pthread_tad_start, tad_start)) == OK)
- tad->count_current++;
- pthread_mutex_unlock(&tad->mutex);
-#else
- tad->routine = routine;
- tad->arg = arg;
- if (ret = pthread_create(thread_id, attr, pthread_tad_start, tad))
- pthread_mutex_unlock(&tad->mutex);
-#endif
- return(ret);
-}
-
-int pthread_tad_wait(pthread_tad_t * tad, unsigned int count)
-{
- if ((tad->count_max) && (tad->count_max < count)) {
- return(EINVAL);
- }
- pthread_mutex_lock(&tad->mutex);
- while (tad->count_current > count)
- pthread_cond_wait(&tad->cond, &tad->mutex);
- pthread_mutex_unlock(&tad->mutex);
- return(OK);
-}
-
-int pthread_tad_init(pthread_tad_t * tad, unsigned int max_count)
-{
- int ret;
-
- if ((ret = pthread_mutex_init(&tad->mutex, NULL)) == OK) {
- if (ret = pthread_cond_init(&tad->cond, NULL)) {
- pthread_mutex_destroy(&tad->mutex);
- } else {
- tad->count_max = max_count;
- tad->count_current = 0;
- }
- }
- return(ret);
-}
-
-/* User is responsible to make sure their are no threads running */
-int pthread_tad_destroy(pthread_tad_t * tad)
-{
- int ret;
-
- if ((ret = pthread_mutex_destroy(&tad->mutex)) == OK) {
- ret = pthread_cond_destroy(&tad->cond);
- } else {
- pthread_cond_destroy(&tad->cond);
- }
- tad->count_max = NOTOK;
- return(ret);
-}
diff --git a/mit-pthreads/lib/libpthreadutil/pthreadutil.h b/mit-pthreads/lib/libpthreadutil/pthreadutil.h
deleted file mode 100755
index 0d8e6a6ef5f..00000000000
--- a/mit-pthreads/lib/libpthreadutil/pthreadutil.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* ==== pthread_tad.h ========================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@athena.mit.edu
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano,
- * and its contributors.
- * 4. Neither the name of Chris Provenzano, nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO, AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <pthread.h>
-#include <sys/cdefs.h>
-
-typedef struct pthread_tad_t {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- unsigned int count_current;
- unsigned int count_max;
- void * arg;
- void * (*routine)();
-} pthread_tad_t;
-
-typedef struct pthread_atexit {
- struct pthread_atexit * next;
- struct pthread_atexit * prev;
- void (*rtn)(void *);
- void * arg;
-} * pthread_atexit_t;
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-int pthread_tad_count __P_((pthread_tad_t *));
-int pthread_tad_create __P_((pthread_tad_t *, pthread_t *, pthread_attr_t *,
- void *(*routine)(), void *));
-int pthread_tad_wait __P_((pthread_tad_t *, unsigned int));
-int pthread_tad_init __P_((pthread_tad_t *, unsigned int));
-int pthread_tad_destroy __P_((pthread_tad_t *));
-
-int pthread_atexit_add __P_((pthread_atexit_t *, void (*)(void *), void *));
-int pthread_atexit_remove __P_((pthread_atexit_t *, int));
-
-
-void fclose_nrv __P_((void *));
-void fflush_nrv __P_((void *));
-void pthread_attr_destroy_nrv __P_((void *));
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/alpha-osf1/__math.h b/mit-pthreads/machdep/alpha-osf1/__math.h
deleted file mode 100755
index 12fdc85678c..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__math.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * ANSI required entries in math.h
- *
- */
-#ifdef _ANSI_C_SOURCE
-
-#if defined(_IEEE_FP)
-# define HUGE_VAL 1.8e308
-#else
-# define HUGE_VAL 1.797693134862315708e308
-#endif
-
-#endif /*_ANSI_C_SOURCE */
-
-
-
diff --git a/mit-pthreads/machdep/alpha-osf1/__signal.h b/mit-pthreads/machdep/alpha-osf1/__signal.h
deleted file mode 100755
index 2bb13380314..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__signal.h
+++ /dev/null
@@ -1,106 +0,0 @@
-#include <standards.h>
-
-typedef int sig_atomic_t; /* accessable as an atomic entity (ANSI) */
-
-/*
- * valid signal values: all undefined values are reserved for future use
- * note: POSIX requires a value of 0 to be used as the null signal in kill()
- */
-#define SIGHUP 1 /* hangup, generated when terminal disconnects */
-#define SIGINT 2 /* interrupt, generated from terminal special char */
-#define SIGQUIT 3 /* (*) quit, generated from terminal special char */
-#define SIGILL 4 /* (*) illegal instruction (not reset when caught)*/
-#define SIGTRAP 5 /* (*) trace trap (not reset when caught) */
-#define SIGABRT 6 /* (*) abort process */
-#define SIGEMT 7 /* EMT instruction */
-#define SIGFPE 8 /* (*) floating point exception */
-#define SIGKILL 9 /* kill (cannot be caught or ignored) */
-#define SIGBUS 10 /* (*) bus error (specification exception) */
-#define SIGSEGV 11 /* (*) segmentation violation */
-#define SIGSYS 12 /* (*) bad argument to system call */
-#define SIGPIPE 13 /* write on a pipe with no one to read it */
-#define SIGALRM 14 /* alarm clock timeout */
-#define SIGTERM 15 /* software termination signal */
-#define SIGURG 16 /* (+) urgent contition on I/O channel */
-#define SIGSTOP 17 /* (@) stop (cannot be caught or ignored) */
-#define SIGTSTP 18 /* (@) interactive stop */
-#define SIGCONT 19 /* (!) continue (cannot be caught or ignored) */
-#define SIGCHLD 20 /* (+) sent to parent on child stop or exit */
-#define SIGTTIN 21 /* (@) background read attempted from control terminal*/
-#define SIGTTOU 22 /* (@) background write attempted to control terminal */
-#define SIGIO 23 /* (+) I/O possible, or completed */
-#define SIGXCPU 24 /* cpu time limit exceeded (see setrlimit()) */
-#define SIGXFSZ 25 /* file size limit exceeded (see setrlimit()) */
-#define SIGVTALRM 26 /* virtual time alarm (see setitimer) */
-#define SIGPROF 27 /* profiling time alarm (see setitimer) */
-#define SIGWINCH 28 /* (+) window size changed */
-#define SIGINFO 29 /* information request */
-#define SIGUSR1 30 /* user defined signal 1 */
-#define SIGUSR2 31 /* user defined signal 2 */
-#define SIGMAX 31
-#define NSIG 31
-
-/*
- * additional signal names supplied for compatibility, only
- */
-#define SIGIOINT SIGURG /* printer to backend error signal */
-#define SIGAIO SIGIO /* base lan i/o */
-#define SIGPTY SIGIO /* pty i/o */
-#define SIGPOLL SIGIO /* STREAMS version of this signal */
-#define SIGIOT SIGABRT /* abort (terminate) process */
-#define SIGLOST SIGIOT /* old BSD signal ?? */
-#define SIGPWR SIGINFO /* Power Fail/Restart -- SVID3/SVR4 */
-#define SIGCLD SIGCHLD
-
-/*
- * valid signal action values; other values => pointer to handler function
- */
-#define SIG_DFL (void (*)())0
-#define SIG_IGN (void (*)())1
-
-/*
- * values of "how" argument to sigprocmask() call
- */
-#define SIG_BLOCK 1
-#define SIG_UNBLOCK 2
-#define SIG_SETMASK 3
-
-/*
- * sigaction structure used in sigaction() system call
- * The order of the fields in this structure must match those in
- * the sigvec structure (below).
- */
-struct sigaction {
- void (*sa_handler)(); /* signal handler, or action value */
- sigset_t sa_mask; /* signals to block while in handler */
- int sa_flags; /* signal action flags */
-};
-
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) ( *(s) |= 1L << ((n) - 1), 0)
-#define __SIGDELSET(s, n) ( *(s) &= ~(1L << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ( (*(s) & (1L << ((n) - 1))) != (sigset_t)0)
-
-
-#define SIGSTKSZ (16384)
-#define MINSIGSTKSZ (4096)
-
-/*
- * valid flags define for sa_flag field of sigaction structure
- */
-#define SA_ONSTACK 0x00000001 /* run on special signal stack */
-#define SA_RESTART 0x00000002 /* restart system calls on sigs */
-#define SA_NOCLDSTOP 0x00000004 /* do not set SIGCHLD for child stops*/
-#define SA_NODEFER 0x00000008 /* don't block while handling */
-#define SA_RESETHAND 0x00000010 /* old sys5 style behavior */
-#define SA_NOCLDWAIT 0x00000020 /* no zombies */
-#define SA_SIGINFO 0x00000040 /* deliver siginfo to handler */
-
-/* This is for sys/time.h */
-/* Removed for OSF1 V3.2
-typedef union sigval {
- int sival_int;
- void *sival_ptr;
-} sigval_t;
-*/
diff --git a/mit-pthreads/machdep/alpha-osf1/__stdio.h b/mit-pthreads/machdep/alpha-osf1/__stdio.h
deleted file mode 100755
index 39801b125c8..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__stdio.h
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#ifndef _FPOS_T
-#define _FPOS_T
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-#define HAVE_SYS_ERRLIST_WITHOUT_CONST
-
diff --git a/mit-pthreads/machdep/alpha-osf1/__stdlib.h b/mit-pthreads/machdep/alpha-osf1/__stdlib.h
deleted file mode 100755
index 79ca737e0c8..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__stdlib.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* bleah */
-
-#include <stddef.h>
diff --git a/mit-pthreads/machdep/alpha-osf1/__string.h b/mit-pthreads/machdep/alpha-osf1/__string.h
deleted file mode 100755
index 6558102a282..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__string.h
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-__BEGIN_DECLS
-
-/*
-void * memchr __P_((const void *, int , size_t ));
-void * memcpy __P_((void *, const void *, size_t ));
-void * memset __P_((void *, int , size_t ));
-size_t strcspn __P_((const char *, const char *));
-size_t strlen __P_((const char *));
-size_t strspn __P_((const char *, const char *));
-*/
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/alpha-osf1/__time.h b/mit-pthreads/machdep/alpha-osf1/__time.h
deleted file mode 100755
index b4ce1ead2bf..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__time.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <pthread/types.h>
-#include <machine/machtime.h> /* CLOCKS_PER_SEC is defined here */
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef pthread_clock_t clock_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef pthread_time_t time_t;
-#endif
-
-#ifndef CLK_TCK
-#define CLK_TCK 60
-#endif
diff --git a/mit-pthreads/machdep/alpha-osf1/__unistd.h b/mit-pthreads/machdep/alpha-osf1/__unistd.h
deleted file mode 100755
index 2a7fbe9389b..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/__unistd.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <sys/types.h>
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef long ssize_t; /* Added by monty */
-#endif
diff --git a/mit-pthreads/machdep/alpha-osf1/cdefs.h b/mit-pthreads/machdep/alpha-osf1/cdefs.h
deleted file mode 100755
index c9b54f033ec..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/cdefs.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define __INLINE static
-#define inline
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/alpha-osf1/compat.h b/mit-pthreads/machdep/alpha-osf1/compat.h
deleted file mode 100755
index 4c2801e05de..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/compat.h
+++ /dev/null
@@ -1 +0,0 @@
-#define omsghdr msghdr
diff --git a/mit-pthreads/machdep/alpha-osf1/dirent.h b/mit-pthreads/machdep/alpha-osf1/dirent.h
deleted file mode 100755
index 697ef7b8a8c..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/dirent.h
+++ /dev/null
@@ -1,7 +0,0 @@
-struct dirent {
- ino_t d_ino;
- ushort_t d_reclen, d_namlen;
- char d_name[256];
-};
-#define d_fileno d_ino
-#define MAXNAMLEN 256
diff --git a/mit-pthreads/machdep/alpha-osf1/signal.h b/mit-pthreads/machdep/alpha-osf1/signal.h
deleted file mode 100755
index c387f9f31ad..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/signal.h
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-#include <signal.h>
diff --git a/mit-pthreads/machdep/alpha-osf1/socket.h b/mit-pthreads/machdep/alpha-osf1/socket.h
deleted file mode 100755
index 28e17ca463d..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/socket.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 1982,1985,1986,1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)socket.h 7.13 (Berkeley) 4/20/91
- */
-
-#ifndef _SOCKET_H_
-#define _SOCKET_H_
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-/*
- * Types
- */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 4 /* raw-protocol interface */
-#define SOCK_RDM 5 /* reliably-delivered message */
-#define SOCK_SEQPACKET 6 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_PROTOTYPE 0x1009 /* get/set protocol type */
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
- int l_onoff; /* option on/off */
- int l_linger; /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_NBS 7 /* nbs protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* DEC Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_NIT 17 /* Network Interface Tap */
-#define AF_802 18 /* IEEE 802.2, also ISO 8802 */
-#define AF_ISO 19 /* ISO protocols */
-#define AF_OSI AF_ISO
-#define AF_X25 20 /* CCITT X.25 in particular */
-#define AF_OSINET 21
-#define AF_GOSIP 22
-#define AF_MAX 22
-
-/* Not supported by solaris */
-/* #define AF_ROUTE 17 /* Internal Routing Protocol */
-/* #define AF_LINK 18 /* Link layer interface */
-/* #define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
-
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- u_short sa_family; /* address family */
- char sa_data[14]; /* actually longer; address value */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- u_short sp_family; /* address family */
- u_short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_NBS AF_NBS
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NIT AF_NIT
-#define PF_802 AF_802
-#define PF_ISO AF_ISO
-#define PF_OSI AF_ISO
-#define PF_X25 AF_X25
-#define PF_OSINET AF_OSINET
-#define PF_GOSIP AF_GOSIP
-#define PF_MAX AF_MAX
-
-/* #define PF_ROUTE AF_ROUTE */
-/* #define PF_LINK AF_LINK */
-/* #define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- * Used value-result for recvmsg, value only for sendmsg.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- u_int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- u_int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_MAXIOVLEN 16
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-
-/* #define MSG_EOR 0x8 data completes record */
-/* #define MSG_TRUNC 0x10 data discarded before delivery */
-/* #define MSG_CTRUNC 0x20 control data lost before delivery */
-/* #define MSG_WAITALL 0x40 wait for full request or error */
-
-/*
- * Header for ancillary data objects in msg_control buffer.
- * Used for additional information with/about a datagram
- * not expressible by flags. The format is a sequence
- * of message elements headed by cmsghdr structures.
- */
-struct cmsghdr {
- u_int cmsg_len; /* data byte count, including hdr */
- int cmsg_level; /* originating protocol */
- int cmsg_type; /* protocol-specific type */
-/* followed by u_char cmsg_data[]; */
-};
-
-/* given pointer to struct adatahdr, return pointer to data */
-#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
-
-/* given pointer to struct adatahdr, return pointer to next adatahdr */
-#define CMSG_NXTHDR(mhdr, cmsg) \
- (((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
- (mhdr)->msg_control + (mhdr)->msg_controllen) ? \
- (struct cmsghdr *)NULL : \
- (struct cmsghdr *)((caddr_t)(cmsg) + ALIGN((cmsg)->cmsg_len)))
-
-#define CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
-
-/* "Socket"-level control message types: */
-#define SCM_RIGHTS 0x01 /* access rights (array of int) */
-
-/*
- * 4.3 compat sockaddr, move to compat file later
- */
-struct osockaddr {
- u_short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-#define SYS_socketcall 83
-
-#define SO_ACCEPT 1
-#define SO_BIND 2
-#define SO_CONNECT 3
-#define SO_GETPEERNAME 4
-#define SO_GETSOCKNAME 5
-#define SO_GETSOCKOPT 6
-#define SO_LISTEN 7
-#define SO_RECV 8
-#define SO_RECVFROM 9
-#define SO_SEND 10
-#define SO_SENDTO 11
-#define SO_SETSOCKOPT 12
-#define SO_SHUTDOWN 13
-#define SO_SOCKET 14
-#define SO_SOCKPOLL 15
-#define SO_GETIPDOMAIN 16
-#define SO_SETIPDOMAIN 17
-#define SO_ADJTIME 18
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-int getsockname __P_((int, struct sockaddr *, int *));
-int getsockopt __P_((int, int, int, void *, int *));
-int listen __P_((int, int));
-/* original definitions
-int recv __P_((int, void *, int, int));
-int recvfrom __P_((int, void *, int, int,
- struct sockaddr *, int *));
-int recvmsg __P_((int, struct msghdr *, int));
-int send __P_((int, const void *, int, int));
-int sendto __P_((int, const void *, int, int, const struct sockaddr *, int));
-int sendmsg __P_((int, const struct msghdr *, int));
-*/
-ssize_t recv __P_((int, void *, size_t, int));
-ssize_t recvfrom __P_((int, void *, size_t, int,
- struct sockaddr *, int *));
-ssize_t recvmsg __P_((int, struct msghdr *, int));
-ssize_t send __P_((int, const void *, size_t, int));
-ssize_t sendto __P_((int, const void *, size_t, int,
- const struct sockaddr *, int));
-ssize_t sendmsg __P_((int, const struct msghdr *, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int shutdown __P_((int, int));
-int socket __P_((int, int, int));
-int socketpair __P_((int, int, int, int *));
-__END_DECLS
-
-#endif /* !_SOCKET_H_ */
diff --git a/mit-pthreads/machdep/alpha-osf1/timers.h b/mit-pthreads/machdep/alpha-osf1/timers.h
deleted file mode 100755
index 36317d083f0..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/timers.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-#endif
diff --git a/mit-pthreads/machdep/alpha-osf1/uio.h b/mit-pthreads/machdep/alpha-osf1/uio.h
deleted file mode 100755
index 8d494672ee4..00000000000
--- a/mit-pthreads/machdep/alpha-osf1/uio.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* N.B.: The Alpha, under OSF/1, does *not* use size_t for the length,
- or for the returned values from readv and writev. */
-
-struct iovec {
- void *iov_base;
- int iov_len;
-};
-
-/* I'm assuming the iovec structures are const. I haven't verified
- it. */
-extern ssize_t readv (int, const struct iovec *, int);
-extern ssize_t writev (int, const struct iovec *, int);
diff --git a/mit-pthreads/machdep/bsdi-1.1/compat.h b/mit-pthreads/machdep/bsdi-1.1/compat.h
deleted file mode 100755
index e6f60c372c7..00000000000
--- a/mit-pthreads/machdep/bsdi-1.1/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/bsdi-1.1/dirent.h b/mit-pthreads/machdep/bsdi-1.1/dirent.h
deleted file mode 100755
index d0272a4ee38..00000000000
--- a/mit-pthreads/machdep/bsdi-1.1/dirent.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* BSDI $Id$ */
-
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- unsigned long
- d_fileno; /* file number of entry */
- unsigned short
- d_reclen; /* length of this record */
- unsigned short
- d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-/*
- * There should probably be no need for this. In the BSDI sources,
- * it is excluded if _POSIX_SOURCE is defined, and pthreads are supposed
- * to be posix. Sources that use d_ino should really be using d_fileno.
- * mbd
- */
-#define d_ino d_fileno /* backward compatibility */
-
-#endif /* !_SYS_DIRENT_H_ */
-
diff --git a/mit-pthreads/machdep/bsdi-1.1/errno.h b/mit-pthreads/machdep/bsdi-1.1/errno.h
deleted file mode 100755
index 3da61d692a3..00000000000
--- a/mit-pthreads/machdep/bsdi-1.1/errno.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $NetBSD: errno.h,v 1.8 1994/06/29 06:44:02 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#endif
diff --git a/mit-pthreads/machdep/bsdi-1.1/socket.h b/mit-pthreads/machdep/bsdi-1.1/socket.h
deleted file mode 100755
index 39d7c1cce26..00000000000
--- a/mit-pthreads/machdep/bsdi-1.1/socket.h
+++ /dev/null
@@ -1,277 +0,0 @@
-/* BSDI $Id$ */
-
-/*
- * Copyright (c) 1982,1985,1986,1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)socket.h 7.13 (Berkeley) 4/20/91
- */
-
-#ifndef _SOCKET_H_
-#define _SOCKET_H_
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-/*
- * Types
- */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 3 /* raw-protocol interface */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
- int l_onoff; /* option on/off */
- int l_linger; /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_ISO 7 /* ISO protocols */
-#define AF_OSI AF_ISO
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* DEC Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_ROUTE 17 /* Internal Routing Protocol */
-#define AF_LINK 18 /* Link layer interface */
-#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
-
-#define AF_MAX 20
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- u_char sa_len; /* total length */
- u_char sa_family; /* address family */
- char sa_data[14]; /* actually longer; address value */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- u_short sp_family; /* address family */
- u_short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_ISO AF_ISO
-#define PF_OSI AF_ISO
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_ROUTE AF_ROUTE
-#define PF_LINK AF_LINK
-#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
-
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- * Used value-result for recvmsg, value only for sendmsg.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- u_int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- u_int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_control; /* ancillary data, see below */
- u_int msg_controllen; /* ancillary data buffer len */
- int msg_flags; /* flags on received message */
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-#define MSG_EOR 0x8 /* data completes record */
-#define MSG_TRUNC 0x10 /* data discarded before delivery */
-#define MSG_CTRUNC 0x20 /* control data lost before delivery */
-#define MSG_WAITALL 0x40 /* wait for full request or error */
-
-/*
- * Header for ancillary data objects in msg_control buffer.
- * Used for additional information with/about a datagram
- * not expressible by flags. The format is a sequence
- * of message elements headed by cmsghdr structures.
- */
-struct cmsghdr {
- u_int cmsg_len; /* data byte count, including hdr */
- int cmsg_level; /* originating protocol */
- int cmsg_type; /* protocol-specific type */
-/* followed by u_char cmsg_data[]; */
-};
-
-/* given pointer to struct adatahdr, return pointer to data */
-#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
-
-/* given pointer to struct adatahdr, return pointer to next adatahdr */
-#define CMSG_NXTHDR(mhdr, cmsg) \
- (((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
- (mhdr)->msg_control + (mhdr)->msg_controllen) ? \
- (struct cmsghdr *)NULL : \
- (struct cmsghdr *)((caddr_t)(cmsg) + ALIGN((cmsg)->cmsg_len)))
-
-#define CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
-
-/* "Socket"-level control message types: */
-#define SCM_RIGHTS 0x01 /* access rights (array of int) */
-
-/*
- * 4.3 compat sockaddr, move to compat file later
- */
-struct osockaddr {
- u_short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * 4.3-compat message header (move to compat file later).
- */
-struct omsghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#ifndef KERNEL
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-int getsockname __P_((int, struct sockaddr *, int *));
-int getsockopt __P_((int, int, int, void *, int *));
-int listen __P_((int, int));
-/* original definitions
-int recv __P_((int, void *, int, int));
-int recvfrom __P_((int, void *, int, int,
- struct sockaddr *, int *));
-int recvmsg __P_((int, struct msghdr *, int));
-int send __P_((int, const void *, int, int));
-int sendto __P_((int, const void *, int, int, const struct sockaddr *, int));
-int sendmsg __P_((int, const struct msghdr *, int));
-*/
-ssize_t recv __P_((int, void *, size_t, int));
-ssize_t recvfrom __P_((int, void *, size_t, int,
- struct sockaddr *, int *));
-ssize_t recvmsg __P_((int, struct msghdr *, int));
-ssize_t send __P_((int, const void *, size_t, int));
-ssize_t sendto __P_((int, const void *, size_t, int,
- const struct sockaddr *, int));
-ssize_t sendmsg __P_((int, const struct msghdr *, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int shutdown __P_((int, int));
-int socket __P_((int, int, int));
-int socketpair __P_((int, int, int, int *));
-__END_DECLS
-
-#endif /* !KERNEL */
-
-#endif /* !_SOCKET_H_ */
diff --git a/mit-pthreads/machdep/bsdi-1.1/timers.h b/mit-pthreads/machdep/bsdi-1.1/timers.h
deleted file mode 100755
index 7101ab99106..00000000000
--- a/mit-pthreads/machdep/bsdi-1.1/timers.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-#endif
diff --git a/mit-pthreads/machdep/bsdi-2.0/__math.h b/mit-pthreads/machdep/bsdi-2.0/__math.h
deleted file mode 100755
index 2c919472f33..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__math.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * ANSI/POSIX
- */
-/* Generate an overflow to create +Inf; the multiply shuts up gcc 1 */
-#define HUGE_VAL (1e250*1e250) /* IEEE: positive infinity */
-
diff --git a/mit-pthreads/machdep/bsdi-2.0/__path.h b/mit-pthreads/machdep/bsdi-2.0/__path.h
deleted file mode 100755
index 9c347016f5f..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__path.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * __path.h,v 1.1 1995/01/03 12:53:32 proven Exp
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "/etc/localtime"
-
-#endif /* !_SYS__PATH_H_ */
diff --git a/mit-pthreads/machdep/bsdi-2.0/__signal.h b/mit-pthreads/machdep/bsdi-2.0/__signal.h
deleted file mode 100755
index d3deecf15e2..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__signal.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <sys/signal.h>
-
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) (*(s) |= 1 << ((n) - 1), 0)
-#define __SIGDELSET(s, n) (*(s) &= ~(1 << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ((*(s) & (1 << ((n) - 1))) != 0)
diff --git a/mit-pthreads/machdep/bsdi-2.0/__stdio.h b/mit-pthreads/machdep/bsdi-2.0/__stdio.h
deleted file mode 100755
index d4d37c2017c..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__stdio.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
diff --git a/mit-pthreads/machdep/bsdi-2.0/__stdlib.h b/mit-pthreads/machdep/bsdi-2.0/__stdlib.h
deleted file mode 100755
index 189bb5e8799..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__stdlib.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * __stdlib.h,v 1.1 1995/01/03 12:53:34 proven Exp
- */
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#ifdef _BSD_WCHAR_T_
-typedef _BSD_WCHAR_T_ wchar_t;
-#undef _BSD_WCHAR_T_
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* _STDLIB_H_ */
diff --git a/mit-pthreads/machdep/bsdi-2.0/__string.h b/mit-pthreads/machdep/bsdi-2.0/__string.h
deleted file mode 100755
index 275032946ea..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__string.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-void strmode __P_((int, char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/bsdi-2.0/__time.h b/mit-pthreads/machdep/bsdi-2.0/__time.h
deleted file mode 100755
index bc4d956486d..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__time.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * __time.h,v 1.1 1994/12/13 07:18:55 proven Exp
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_CLOCK_T_
-typedef _BSD_CLOCK_T_ clock_t;
-#undef _BSD_CLOCK_T_
-#endif
-
-#ifdef _BSD_TIME_T_
-typedef _BSD_TIME_T_ time_t;
-#undef _BSD_TIME_T_
-#endif
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/bsdi-2.0/__unistd.h b/mit-pthreads/machdep/bsdi-2.0/__unistd.h
deleted file mode 100755
index 4a5ee6a245e..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/__unistd.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * __unistd.h,v 1.1 1995/01/03 12:53:35 proven Exp
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define ioctl_request_type unsigned long /* For fd.c */
-
-/* compile-time symbolic constants */
-#define _POSIX_JOB_CONTROL /* implementation supports job control */
-
-#ifdef _NOT_AVAILABLE
-#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */
-#endif
-
-#define _POSIX_VERSION 198808L
-#define _POSIX2_VERSION 199212L
-
-/* execution-time symbolic constants */
- /* chown requires appropriate privileges */
-#define _POSIX_CHOWN_RESTRICTED 1
- /* too-long path components generate errors */
-#define _POSIX_NO_TRUNC 1
- /* may disable terminal special characters */
-#define _POSIX_VDISABLE ((unsigned char)'\377')
-
-/* configurable pathname variables */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_CHOWN_RESTRICTED 7
-#define _PC_NO_TRUNC 8
-#define _PC_VDISABLE 9
-
-/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-
-/* configurable system strings */
-#define _CS_PATH 1
-
-#endif
diff --git a/mit-pthreads/machdep/bsdi-2.0/compat.h b/mit-pthreads/machdep/bsdi-2.0/compat.h
deleted file mode 100755
index 0dfdc27f9e8..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/compat.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
-
diff --git a/mit-pthreads/machdep/bsdi-2.0/dirent.h b/mit-pthreads/machdep/bsdi-2.0/dirent.h
deleted file mode 100755
index 0dfdc27f9e8..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/dirent.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
-
diff --git a/mit-pthreads/machdep/bsdi-2.0/errno.h b/mit-pthreads/machdep/bsdi-2.0/errno.h
deleted file mode 100755
index 1a3c37d0147..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/errno.h
+++ /dev/null
@@ -1,162 +0,0 @@
-
-/* $NetBSD: errno.h,v 1.8 1994/06/29 06:44:02 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#endif
-
diff --git a/mit-pthreads/machdep/bsdi-2.0/time.h b/mit-pthreads/machdep/bsdi-2.0/time.h
deleted file mode 100755
index a8bf0ff8f82..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/time.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef ts_sec
-#define ts_sec tv_sec
-#define ts_nsec tv_nsec
-#endif
-#include "/usr/include/sys/time.h"
-
diff --git a/mit-pthreads/machdep/bsdi-2.0/timers.h b/mit-pthreads/machdep/bsdi-2.0/timers.h
deleted file mode 100755
index b603b78e6b2..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * timers.h,v 1.50 1994/08/08 03:44:09 proven Exp
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-#endif
diff --git a/mit-pthreads/machdep/bsdi-2.0/wait.h b/mit-pthreads/machdep/bsdi-2.0/wait.h
deleted file mode 100755
index 5f7635a73a7..00000000000
--- a/mit-pthreads/machdep/bsdi-2.0/wait.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* $NetBSD: wait.h,v 1.7 1994/06/29 06:46:23 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- */
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#include <machine/endian.h>
-
-/*
- * Deprecated:
- * Structure of the information in the status word returned by wait4.
- * If w_stopval==WSTOPPED, then the second structure describes
- * the information returned, else the first.
- */
-union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-};
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#ifndef KERNEL
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
-#endif
-
diff --git a/mit-pthreads/machdep/engine-alpha-netbsd-1.1.c b/mit-pthreads/machdep/engine-alpha-netbsd-1.1.c
deleted file mode 100644
index c1ff04db16d..00000000000
--- a/mit-pthreads/machdep/engine-alpha-netbsd-1.1.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for NetBSD/Alpha 1.1(+)
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * 95/04/22 cgd
- * -Modified to make it go with NetBSD/Alpha
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-alpha-osf1.c,v 1.4.4.1 1995/12/13 05:41:37 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return __machdep_save_int_state(pthread_run->machdep_data.machdep_istate);
-}
-
-void machdep_restore_state(void)
-{
- __machdep_restore_int_state(pthread_run->machdep_data.machdep_istate);
-}
-
-void machdep_save_float_state (void)
-{
- __machdep_save_fp_state(pthread_run->machdep_data.machdep_fstate);
-}
-
-void machdep_restore_float_state (void)
-{
- __machdep_restore_fp_state(pthread_run->machdep_data.machdep_fstate);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Set up new stack frame so that it looks like it returned from a
- longjmp() to the beginning of machdep_pthread_start(). */
- machdep_pthread->machdep_istate[8/*ISTATE_RA*/] = 0;
- machdep_pthread->machdep_istate[0/*ISTATE_PC*/] = (long)machdep_pthread_start;
- machdep_pthread->machdep_istate[10/*ISTATE_PV*/] = (long)machdep_pthread_start;
-
- /* Alpha stack starts high and builds down. */
- {
- long stk_addr = (long) machdep_pthread->machdep_stack;
- stk_addr += stack_size - 1024;
- stk_addr &= ~15;
- machdep_pthread->machdep_istate[9/*ISTATE_SP*/] = stk_addr;
- }
-}
-
-int safe_store (loc, new)
- int *loc;
- int new;
-{
- int locked, old;
- asm ("mb" : : : "memory");
- do {
- asm ("ldl_l %0,%1" : "=r" (old) : "m" (*loc));
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*loc) : "0" (new));
- } while (!locked);
- asm ("mb" : : : "memory");
- return old;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-off_t machdep_sys_lseek(int fd, off_t offset, int whence)
-{
- extern off_t __syscall();
-
- return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
-}
diff --git a/mit-pthreads/machdep/engine-alpha-netbsd-1.1.h b/mit-pthreads/machdep/engine-alpha-netbsd-1.1.h
deleted file mode 100644
index 50c872da7b6..00000000000
--- a/mit-pthreads/machdep/engine-alpha-netbsd-1.1.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano (proven@athena.mit.edu) and
- * Ken Raeburn (raeburn@mit.edu).
- *
- * engine-alpha-osf1.h,v 1.4.4.1 1995/12/13 05:41:42 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-/* The first machine dependent functions are the SEMAPHORES needing
- the test and set instruction.
-
- On the Alpha, the actual values here are irrelevant; they just have
- to be different. */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#if 0
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ int *_sem_lock = (lock), locked, old; \
- asm ("mb" : : : "memory"); \
- do { asm ("ldl_l %0,%1" : "=r" (old) : "m" (*_sem_lock)); \
- /* ?? if (old != SEMAPHORE_CLEAR) break; */ \
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*_sem_lock) \
- : "0" (SEMAPHORE_SET)); \
- } while (!locked); \
- asm ("mb" : : : "memory"); \
- old == SEMAPHORE_CLEAR; })
-
-#define SEMAPHORE_RESET(lock) \
-({ int *_sem_lock = (lock); \
- *_sem_lock = SEMAPHORE_CLEAR; \
- asm ("mb" : : : "memory"); })
-#endif
-
-/*
- * New types
- */
-typedef int semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- unsigned long machdep_istate[11];
- unsigned long machdep_fstate[9];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
- { NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 2048
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-int __machdep_save_int_state __P_((unsigned long *));
-void __machdep_restore_int_state __P_((unsigned long *));
-void __machdep_save_fp_state __P_((unsigned long *));
-void __machdep_restore_fp_state __P_((unsigned long *));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-alpha-netbsd-1.3.c b/mit-pthreads/machdep/engine-alpha-netbsd-1.3.c
deleted file mode 100644
index 0932c421ea2..00000000000
--- a/mit-pthreads/machdep/engine-alpha-netbsd-1.3.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for NetBSD/Alpha 1.1(+)
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * 95/04/22 cgd
- * -Modified to make it go with NetBSD/Alpha
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-alpha-osf1.c,v 1.4.4.1 1995/12/13 05:41:37 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return __machdep_save_int_state(pthread_run->machdep_data.machdep_istate);
-}
-
-void machdep_restore_state(void)
-{
- __machdep_restore_int_state(pthread_run->machdep_data.machdep_istate);
-}
-
-void machdep_save_float_state (void)
-{
- __machdep_save_fp_state(pthread_run->machdep_data.machdep_fstate);
-}
-
-void machdep_restore_float_state (void)
-{
- __machdep_restore_fp_state(pthread_run->machdep_data.machdep_fstate);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Set up new stack frame so that it looks like it returned from a
- longjmp() to the beginning of machdep_pthread_start(). */
- machdep_pthread->machdep_istate[8/*ISTATE_RA*/] = 0;
- machdep_pthread->machdep_istate[0/*ISTATE_PC*/] = (long)machdep_pthread_start;
- machdep_pthread->machdep_istate[10/*ISTATE_PV*/] = (long)machdep_pthread_start;
-
- /* Alpha stack starts high and builds down. */
- {
- long stk_addr = (long) machdep_pthread->machdep_stack;
- stk_addr += stack_size - 1024;
- stk_addr &= ~15;
- machdep_pthread->machdep_istate[9/*ISTATE_SP*/] = stk_addr;
- }
-}
-
-int safe_store (loc, new)
- int *loc;
- int new;
-{
- int locked, old;
- asm ("mb" : : : "memory");
- do {
- asm ("ldl_l %0,%1" : "=r" (old) : "m" (*loc));
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*loc) : "0" (new));
- } while (!locked);
- asm ("mb" : : : "memory");
- return old;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-off_t machdep_sys_lseek(int fd, off_t offset, int whence)
-{
- extern off_t __syscall();
-
- return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
diff --git a/mit-pthreads/machdep/engine-alpha-netbsd-1.3.h b/mit-pthreads/machdep/engine-alpha-netbsd-1.3.h
deleted file mode 100644
index bc4178d3c41..00000000000
--- a/mit-pthreads/machdep/engine-alpha-netbsd-1.3.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano (proven@athena.mit.edu) and
- * Ken Raeburn (raeburn@mit.edu).
- *
- * engine-alpha-osf1.h,v 1.4.4.1 1995/12/13 05:41:42 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-#include <sys/signal.h> /* for _NSIG */
-
-/* The first machine dependent functions are the SEMAPHORES needing
- the test and set instruction.
-
- On the Alpha, the actual values here are irrelevant; they just have
- to be different. */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#if 0
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ int *_sem_lock = (lock), locked, old; \
- asm ("mb" : : : "memory"); \
- do { asm ("ldl_l %0,%1" : "=r" (old) : "m" (*_sem_lock)); \
- /* ?? if (old != SEMAPHORE_CLEAR) break; */ \
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*_sem_lock) \
- : "0" (SEMAPHORE_SET)); \
- } while (!locked); \
- asm ("mb" : : : "memory"); \
- old == SEMAPHORE_CLEAR; })
-
-#define SEMAPHORE_RESET(lock) \
-({ int *_sem_lock = (lock); \
- *_sem_lock = SEMAPHORE_CLEAR; \
- asm ("mb" : : : "memory"); })
-#endif
-
-/*
- * New types
- */
-typedef int semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX (_NSIG-1)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- unsigned long machdep_istate[11];
- unsigned long machdep_fstate[9];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
- { NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 2048
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-int __machdep_save_int_state __P_((unsigned long *));
-void __machdep_restore_int_state __P_((unsigned long *));
-void __machdep_save_fp_state __P_((unsigned long *));
-void __machdep_restore_fp_state __P_((unsigned long *));
-
-extern off_t machdep_sys_lseek(int, off_t, int);
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-alpha-osf1.c b/mit-pthreads/machdep/engine-alpha-osf1.c
deleted file mode 100644
index 9b563a56c28..00000000000
--- a/mit-pthreads/machdep/engine-alpha-osf1.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for SunOS-4.1.3 on sparc
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdlib.h>
-
-/* These would be defined in setjmp.h, if _POSIX_SOURCE and _XOPEN_SOURCE
- were both undefined. But we've already included it, and lost the
- opportunity. */
-#define JB_PC 2
-#define JB_RA 30
-#define JB_PV 31
-#define JB_SP 34
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return setjmp (pthread_run->machdep_data.machdep_state);
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-extern void machdep_restore_from_setjmp (jmp_buf, long);
-void machdep_restore_state(void)
-{
- machdep_restore_from_setjmp (pthread_run->machdep_data.machdep_state, 1);
-}
-
-void machdep_save_float_state (void) { }
-void machdep_restore_float_state (void) { }
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
-
- /* Set up new stack frame so that it looks like it returned from a
- longjmp() to the beginning of machdep_pthread_start(). */
- machdep_pthread->machdep_state[JB_RA] = 0;
- machdep_pthread->machdep_state[JB_PC] = (long)machdep_pthread_start;
- machdep_pthread->machdep_state[JB_PV] = (long)machdep_pthread_start;
-
- /* Alpha stack starts high and builds down. */
- {
- long stk_addr = (long) machdep_pthread->machdep_stack;
- stk_addr += stack_size - 1024;
- stk_addr &= ~15;
- machdep_pthread->machdep_state[JB_SP] = stk_addr;
- }
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int pid, int * statusp, int options)
-{
- return machdep_sys_wait4 (pid, statusp, options, NULL);
-}
-
-/* These are found in flsbuf.o in the Alpha libc. I don't know what
- they're for, precisely. */
-static xxx;
-_bufsync (p)
- char *p;
-{
- long a1 = *(long *)(p+48);
- long t0 = *(long *)(p+8);
- long v0 = a1 - t0;
- long t1, t2;
-
- abort ();
-
- v0 += xxx;
- if (v0 < 0)
- {
- *(char**)(p + 8) = p;
- return v0;
- }
- t1 = *(int*)p;
- t2 = v0 - t1;
- if (t2 < 0)
- *(int*)p = (int) v0;
- return v0;
-}
-
-_findbuf () { abort (); }
-_wrtchk () { abort (); }
-_xflsbuf () { abort (); }
-_flsbuf () { abort (); }
-
-void __xxx_never_called () {
- /* Force other stuff to get dragged in. */
- _cleanup ();
- fflush (NULL);
- fclose (NULL);
-}
-
-int safe_store (loc, new)
- int *loc;
- int new;
-{
- int locked, old;
- asm ("mb" : : : "memory");
- do {
- asm ("ldl_l %0,%1" : "=r" (old) : "m" (*loc));
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*loc) : "0" (new));
- } while (!locked);
- asm ("mb" : : : "memory");
- return old;
-}
diff --git a/mit-pthreads/machdep/engine-alpha-osf1.h b/mit-pthreads/machdep/engine-alpha-osf1.h
deleted file mode 100644
index fdf374ccc44..00000000000
--- a/mit-pthreads/machdep/engine-alpha-osf1.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano (proven@athena.mit.edu) and
- * Ken Raeburn (raeburn@mit.edu).
- *
- * $Id$
- *
- */
-
-#ifndef sigwait
-#define sigwait __bogus_osf1_sigwait
-#endif
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-#undef sigwait
-
-/* The first machine dependent functions are the SEMAPHORES needing
- the test and set instruction.
-
- On the Alpha, the actual values here are irrelevant; they just have
- to be different. */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#if 0
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ int *_sem_lock = (lock), locked, old; \
- asm ("mb" : : : "memory"); \
- do { asm ("ldl_l %0,%1" : "=r" (old) : "m" (*_sem_lock)); \
- /* ?? if (old != SEMAPHORE_CLEAR) break; */ \
- asm ("stl_c %0,%1" : "=r" (locked), "=m" (*_sem_lock) \
- : "0" (SEMAPHORE_SET)); \
- } while (!locked); \
- asm ("mb" : : : "memory"); \
- old == SEMAPHORE_CLEAR; })
-
-#define SEMAPHORE_RESET(lock) \
-({ int *_sem_lock = (lock); \
- *_sem_lock = SEMAPHORE_CLEAR; \
- asm ("mb" : : : "memory"); })
-#endif
-
-/*
- * New types
- */
-typedef int semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
- { NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 2048
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-arm32-netbsd-1.3.c b/mit-pthreads/machdep/engine-arm32-netbsd-1.3.c
deleted file mode 100644
index 510b35fdb0e..00000000000
--- a/mit-pthreads/machdep/engine-arm32-netbsd-1.3.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for NetBSD on arm32
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * 98/10/22 bad
- * -adapt from i386 version
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-#if defined(_JB_REG_R13)
-#define REG_LR _JB_REG_R14
-#define REG_SP _JB_REG_R13
-#else
-#define REG_LR JMPBUF_REG_R14
-#define REG_SP JMPBUF_REG_R13
-#endif
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[REG_LR] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[REG_SP] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
diff --git a/mit-pthreads/machdep/engine-arm32-netbsd-1.3.h b/mit-pthreads/machdep/engine-arm32-netbsd-1.3.h
deleted file mode 100644
index c8a4e79386a..00000000000
--- a/mit-pthreads/machdep/engine-arm32-netbsd-1.3.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * Id: engine-i386-netbsd-1.3.h,v 1.1 1998/02/28 04:53:15 cjs Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/signal.h> /* for _NSIG */
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#if 0
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-#endif
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX (_NSIG-1)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-#if 0
- char machdep_float_state[108];
-#endif
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-hppa-hpux-10.20.c b/mit-pthreads/machdep/engine-hppa-hpux-10.20.c
deleted file mode 100644
index f6f0b2e0f1d..00000000000
--- a/mit-pthreads/machdep/engine-hppa-hpux-10.20.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for HP-UX 9.03 on hppa
- *
- * 1.00 93/12/14 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-volatile int setupStack = 0;
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_save_float_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state()
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(jmp_buf j)
-{
- setjmp(j);
- if( setupStack )
- return;
-
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- jmp_buf tmp_jmp_buf;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /*
- * Set up new stack frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- setjmp(machdep_pthread->machdep_state);
-
- /* get the stack frame from the real machdep_pthread_start */
- setupStack = 1;
-/* machdep_pthread_start(machdep_pthread->machdep_state); */
- machdep_pthread_start(tmp_jmp_buf);
- setupStack = 0;
-
- /* copy over the interesting part of the frame */
- ((int *)machdep_pthread->machdep_state)[44] = ((int *)tmp_jmp_buf)[44];
-
- /* Stack starts low and builds up, but needs two start frames */
- ((int *)machdep_pthread->machdep_state)[1] =
- (int)machdep_pthread->machdep_stack + (64 * 2);
-}
-
-int machdep_sys_getdtablesize()
-{
- return sysconf(_SC_OPEN_MAX);
-}
-
-void sig_check_and_resume()
-{
- return;
-}
-
-void ___exit(int status)
-{
- exit(status);
- PANIC();
-}
diff --git a/mit-pthreads/machdep/engine-hppa-hpux-10.20.h b/mit-pthreads/machdep/engine-hppa-hpux-10.20.h
deleted file mode 100644
index 9cbe3349a3d..00000000000
--- a/mit-pthreads/machdep/engine-hppa-hpux-10.20.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * Stuff for compiling
- */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const
-#endif
-#define inline
-#define signed
-#define volatile
-#endif
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- *
- * Note: The set and clear defines are backwards.
- */
-#define SEMAPHORE_CLEAR { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
-#define SEMAPHORE_SET 0
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long real_addr; \
-long temp; \
- \
-real_addr = ((long)((*lock) + 15) & ~15); \
- \
-__asm__ volatile("ldcwx %%r0(%2),%0" \
- :"=r" (temp) \
- :"0" (temp),"r" (real_addr)); \
-temp ? 0 : 1; \
-})
-
-#define SEMAPHORE_RESET(lock) \
-({ \
-char *real_addr; \
- \
-real_addr = (char*)((long)((*lock) + 15) & ~15); \
-*real_addr = 0xff; \
-})
-
-/*
- * New types
- * The semaphore is really 16 bytes but must be aligened on a 16 byte
- * boundary. By specifing 31 bytes the macros can frob it correctly.
- */
-typedef char semaphore[31];
-
-/*
- * Macros for sigset_t
- */
-#define SIGMAX 30
-/* see hpux-9.03/__signal.h for SIG_ANY */
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- /* long machdep_state[_JBLEN]; */
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 4096
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * page size
- */
-#define getpagesize() 4096
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-hppa-hpux-9.03.c b/mit-pthreads/machdep/engine-hppa-hpux-9.03.c
deleted file mode 100644
index 3770a2e106a..00000000000
--- a/mit-pthreads/machdep/engine-hppa-hpux-9.03.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for HP-UX 9.03 on hppa
- *
- * 1.00 93/12/14 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_save_float_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state()
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- ((int *)machdep_pthread->machdep_state)[0] = (int)machdep_pthread_start;
-
- /* Stack starts low and builds up, but needs two start frames */
- ((int *)machdep_pthread->machdep_state)[1] =
- (int)machdep_pthread->machdep_stack + (64 * 2);
-}
-
-int machdep_sys_getdtablesize()
-{
- return sysconf(_SC_OPEN_MAX);
-}
-
-void sig_check_and_resume()
-{
- return;
-}
-
-void ___exit(int status)
-{
- exit(status);
- PANIC();
-}
diff --git a/mit-pthreads/machdep/engine-hppa-hpux-9.03.h b/mit-pthreads/machdep/engine-hppa-hpux-9.03.h
deleted file mode 100644
index 7c599400e3e..00000000000
--- a/mit-pthreads/machdep/engine-hppa-hpux-9.03.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * Stuff for compiling
- */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define const
-#define inline
-#define signed
-#define volatile
-#endif
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- *
- * Note: The set and clear defines are backwards.
- */
-#define SEMAPHORE_CLEAR { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
-#define SEMAPHORE_SET 0
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long real_addr; \
-long temp; \
- \
-real_addr = ((long)((*lock) + 15) & ~15); \
- \
-__asm__ volatile("ldcwx %%r0(%2),%0" \
- :"=r" (temp) \
- :"0" (temp),"r" (real_addr)); \
-temp ? 0 : 1; \
-})
-
-#define SEMAPHORE_RESET(lock) \
-({ \
-char *real_addr; \
- \
-real_addr = (char*)((long)((*lock) + 15) & ~15); \
-*real_addr = 0xff; \
-})
-
-/*
- * New types
- * The semaphore is really 16 bytes but must be aligened on a 16 byte
- * boundary. By specifing 31 bytes the macros can frob it correctly.
- */
-typedef char semaphore[31];
-
-/*
- * Macros for sigset_t
- */
-#define SIGMAX 30
-/* see hpux-9.03/__signal.h for SIG_ANY */
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- /* long machdep_state[_JBLEN]; */
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 4096
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * page size
- */
-#define getpagesize() 4096
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-bsdi-1.1.c b/mit-pthreads/machdep/engine-i386-bsdi-1.1.c
deleted file mode 100644
index da78bef393e..00000000000
--- a/mit-pthreads/machdep/engine-i386-bsdi-1.1.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- sig_check_and_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * machdep_pthread_create()
- */
-void machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument, long stack_size,
- void *stack_start, long nsec)
-{
- machdep_pthread->machdep_stack = stack_start;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-machdep_sys_send(int s, const void *buf, int len, int flags)
-{
- return(machdep_sys_sendto(s, buf, len, flags, (struct sockaddr*)NULL, 0));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-machdep_sys_recv(int s, void *buf, int len, int flags)
-{
- return(machdep_sys_recvfrom(s, buf, len, flags, (struct sockaddr*)NULL, 0));
-}
diff --git a/mit-pthreads/machdep/engine-i386-bsdi-1.1.h b/mit-pthreads/machdep/engine-i386-bsdi-1.1.h
deleted file mode 100644
index 7f7b8a62d06..00000000000
--- a/mit-pthreads/machdep/engine-i386-bsdi-1.1.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/engine-i386-bsdi-2.0.c b/mit-pthreads/machdep/engine-i386-bsdi-2.0.c
deleted file mode 100644
index 63a6de1b092..00000000000
--- a/mit-pthreads/machdep/engine-i386-bsdi-2.0.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
diff --git a/mit-pthreads/machdep/engine-i386-bsdi-2.0.h b/mit-pthreads/machdep/engine-i386-bsdi-2.0.h
deleted file mode 100644
index 3be254b4090..00000000000
--- a/mit-pthreads/machdep/engine-i386-bsdi-2.0.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * engine-i386-netbsd-1.0.h,v 1.53 1994/12/13 07:17:23 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK (O_NONBLOCK|O_NDELAY)
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/engine-i386-freebsd-1.1.c b/mit-pthreads/machdep/engine-i386-freebsd-1.1.c
deleted file mode 100644
index 422193e77e3..00000000000
--- a/mit-pthreads/machdep/engine-i386-freebsd-1.1.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- sig_check_and_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * machdep_pthread_create()
- */
-void machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument, long stack_size,
- void *stack_start, long nsec)
-{
- machdep_pthread->machdep_stack = stack_start;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-machdep_sys_send(int s, const void *buf, int len, int flags)
-{
- return(machdep_sys_sendto(s, buf, len, flags, NULL, 0));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-machdep_sys_recv(int s, void *buf, int len, int flags)
-{
- return(machdep_sys_recvfrom(s, buf, len, flags, NULL, 0));
-}
diff --git a/mit-pthreads/machdep/engine-i386-freebsd-1.1.h b/mit-pthreads/machdep/engine-i386-freebsd-1.1.h
deleted file mode 100644
index 0e8e93bdbfb..00000000000
--- a/mit-pthreads/machdep/engine-i386-freebsd-1.1.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-freebsd-2.0.c b/mit-pthreads/machdep/engine-i386-freebsd-2.0.c
deleted file mode 100644
index 3b6b8f31ae0..00000000000
--- a/mit-pthreads/machdep/engine-i386-freebsd-2.0.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-i386-freebsd-2.0.c,v 1.1 1995/03/01 01:21:20 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(machdep_sys_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- machdep_sys_longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- machdep_sys_setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state->_jb[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state->_jb[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
diff --git a/mit-pthreads/machdep/engine-i386-freebsd-2.0.h b/mit-pthreads/machdep/engine-i386-freebsd-2.0.h
deleted file mode 100644
index 87ef21389ce..00000000000
--- a/mit-pthreads/machdep/engine-i386-freebsd-2.0.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-linux-1.0.c b/mit-pthreads/machdep/engine-i386-linux-1.0.c
deleted file mode 100644
index fac044fe47c..00000000000
--- a/mit-pthreads/machdep/engine-i386-linux-1.0.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for Linux-1.0 on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/uio.h>
-#include <sys/types.h>
-#include <sys/param.h> /* for OPEN_MAX */
-#include <sys/socket.h>
-#include <sys/socketcall.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_save_float_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flag)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state->__pc = (char *)machdep_pthread_start;
- machdep_pthread->machdep_state->__bp = (char *)0;/* So the backtrace
- * is sensible (mevans) *
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state->__sp =
- (char *)machdep_pthread->machdep_stack + stack_size;
-}
-
-
-/* ==========================================================================
- * Linux Socket calls are a bit different
- * ==========================================================================
- * machdep_sys_socket()
- */
-int machdep_sys_socket(int a, int b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_SOCKET, array));
-}
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-int machdep_sys_accept(int a, struct sockaddr * b, int * c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_ACCEPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-int machdep_sys_bind(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_BIND, array));
-}
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-int machdep_sys_connect(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_CONNECT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-int machdep_sys_listen(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_LISTEN, array));
-}
-
-/* ==========================================================================
- * machdep_sys_shutdown()
- */
-int machdep_sys_shutdown(int a, int b)
-{
- int array[2];
-
- array[0] = (int)a;
- array[1] = (int)b;
-
- return(machdep_sys_socketcall(SYS_SHUTDOWN, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-int machdep_sys_getsockopt(int a, int b, int c, char *d, int *e)
-{
- int array[5];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
-
- return(machdep_sys_socketcall(SYS_GETSOCKOPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_setsockopt()
- */
-int machdep_sys_setsockopt(int a, int b, int c, char *d, int e)
-{
- int array[5];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
-
- return(machdep_sys_socketcall(SYS_SETSOCKOPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-int machdep_sys_getpeername(int a, struct sockaddr *b, int *c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_GETPEERNAME, array));
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-int machdep_sys_send(int a, char *b, int c, int d)
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_SEND, array));
-}
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-int machdep_sys_sendto(int a, char *b, int c, int d,
- struct sockaddr *e, int f)
-{
- int array[6];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
- array[5] = (int)f;
-
- return(machdep_sys_socketcall(SYS_SENDTO, array));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-int machdep_sys_recv(int a, char *b, int c, int d)
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_RECV, array));
-}
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-int machdep_sys_recvfrom(int a, char *b, int c, int d,
- struct sockaddr *e, int *f)
-{
- int array[6];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
- array[5] = (int)f;
-
- return(machdep_sys_socketcall(SYS_RECVFROM, array));
-}
-
-/* ==========================================================================
- * machdep_sys_socketpair()
- */
-int machdep_sys_socketpair(int a, int b, int c, int d[2])
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_SOCKETPAIR, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-int machdep_sys_getsockname(int a, char * b, int * c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_GETSOCKNAME, array));
-}
-
-/* ==========================================================================
- * machdep_sys_sendmsg()
- */
-int machdep_sys_sendmsg(int a, char * b, int c)
-{
-#ifdef SYS_SENDMSG
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_SENDMSG, array));
-#else
- return(-ENOSYS);
-#endif
-}
-
-/* ==========================================================================
- * machdep_sys_recvmsg()
- */
-int machdep_sys_recvmsg(int a, char * b, int c)
-{
-#ifdef SYS_RECVMSG
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_RECVMSG, array));
-#else
- return(-ENOSYS);
-#endif
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- int ret;
-
- if ((ret = machdep_sys_readdir(fd, buf, 1)) > 0) {
- return(1);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* getdtablesize */
-machdep_sys_getdtablesize ()
-{
- return OPEN_MAX;
-}
-
-struct stat;
-
-/* ==========================================================================
- * _fxstat()
- */
-int _fxstat(int __ver, int fd, struct stat *buf)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- ret = machdep_sys_fstat(fd_table[fd]->fd.i, buf);
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * _lxstat()
- */
-int _lxstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_lstat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * _xstat()
- */
-int _xstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_stat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * strtol()
- */
-__strtol_internal(char * a, char ** b, int c)
-{
- return(strtol(a, b, c));
-}
-
-
diff --git a/mit-pthreads/machdep/engine-i386-linux-1.0.h b/mit-pthreads/machdep/engine-i386-linux-1.0.h
deleted file mode 100644
index 721618a6f19..00000000000
--- a/mit-pthreads/machdep/engine-i386-linux-1.0.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- */
-
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-volatile long temp = SEMAPHORE_SET; \
- \
-__asm__("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-linux-2.0.c b/mit-pthreads/machdep/engine-i386-linux-2.0.c
deleted file mode 100644
index 72c757fe08a..00000000000
--- a/mit-pthreads/machdep/engine-i386-linux-2.0.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for Linux-1.0 on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/uio.h>
-#include <sys/types.h>
-#include <sys/param.h> /* for OPEN_MAX */
-#include <sys/socket.h>
-#include <sys/socketcall.h>
-#include <linux/net.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_save_float_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flag)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state->__jmpbuf[JB_PC]= (int) (char *)machdep_pthread_start;
- /* Fix so that the backtrace * is sensible (mevans) */
- machdep_pthread->machdep_state->__jmpbuf[JB_BP] = (int) (char *) 0;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state->__jmpbuf[JB_SP]=
- (int) (char *) machdep_pthread->machdep_stack + stack_size;
-}
-
-
-/* ==========================================================================
- * Linux Socket calls are a bit different
- * ==========================================================================
- * machdep_sys_socket()
- */
-int machdep_sys_socket(int a, int b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_SOCKET, array));
-}
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-int machdep_sys_accept(int a, struct sockaddr * b, int * c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_ACCEPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-int machdep_sys_bind(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_BIND, array));
-}
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-int machdep_sys_connect(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_CONNECT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-int machdep_sys_listen(int a, const struct sockaddr * b, int c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_LISTEN, array));
-}
-
-/* ==========================================================================
- * machdep_sys_shutdown()
- */
-int machdep_sys_shutdown(int a, int b)
-{
- int array[2];
-
- array[0] = (int)a;
- array[1] = (int)b;
-
- return(machdep_sys_socketcall(SYS_SHUTDOWN, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-int machdep_sys_getsockopt(int a, int b, int c, char *d, int *e)
-{
- int array[5];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
-
- return(machdep_sys_socketcall(SYS_GETSOCKOPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_setsockopt()
- */
-int machdep_sys_setsockopt(int a, int b, int c, char *d, int e)
-{
- int array[5];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
-
- return(machdep_sys_socketcall(SYS_SETSOCKOPT, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-int machdep_sys_getpeername(int a, struct sockaddr *b, int *c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_GETPEERNAME, array));
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-int machdep_sys_send(int a, char *b, int c, int d)
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_SEND, array));
-}
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-int machdep_sys_sendto(int a, char *b, int c, int d,
- struct sockaddr *e, int f)
-{
- int array[6];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
- array[5] = (int)f;
-
- return(machdep_sys_socketcall(SYS_SENDTO, array));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-int machdep_sys_recv(int a, char *b, int c, int d)
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_RECV, array));
-}
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-int machdep_sys_recvfrom(int a, char *b, int c, int d,
- struct sockaddr *e, int *f)
-{
- int array[6];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
- array[4] = (int)e;
- array[5] = (int)f;
-
- return(machdep_sys_socketcall(SYS_RECVFROM, array));
-}
-
-/* ==========================================================================
- * machdep_sys_socketpair()
- */
-int machdep_sys_socketpair(int a, int b, int c, int d[2])
-{
- int array[4];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
- array[3] = (int)d;
-
- return(machdep_sys_socketcall(SYS_SOCKETPAIR, array));
-}
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-int machdep_sys_getsockname(int a, char * b, int * c)
-{
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_GETSOCKNAME, array));
-}
-
-/* ==========================================================================
- * machdep_sys_sendmsg()
- */
-int machdep_sys_sendmsg(int a, char * b, int c)
-{
-#ifdef SYS_SENDMSG
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_SENDMSG, array));
-#else
- return(-ENOSYS);
-#endif
-}
-
-/* ==========================================================================
- * machdep_sys_recvmsg()
- */
-int machdep_sys_recvmsg(int a, char * b, int c)
-{
-#ifdef SYS_RECVMSG
- int array[3];
-
- array[0] = (int)a;
- array[1] = (int)b;
- array[2] = (int)c;
-
- return(machdep_sys_socketcall(SYS_RECVMSG, array));
-#else
- return(-ENOSYS);
-#endif
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- int ret;
-
- if ((ret = machdep_sys_readdir(fd, buf, 1)) > 0) {
- return(1);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* getdtablesize */
-machdep_sys_getdtablesize ()
-{
- return OPEN_MAX;
-}
-
-struct stat;
-
-/* ==========================================================================
- * _fxstat()
- */
-int _fxstat(int __ver, int fd, struct stat *buf)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- ret = machdep_sys_fstat(fd_table[fd]->fd.i, buf);
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * _lxstat()
- */
-int _lxstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_lstat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * _xstat()
- */
-int _xstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_stat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * strtol()
- */
-__strtol_internal(char * a, char ** b, int c)
-{
- return(strtol(a, b, c));
-}
-
-
diff --git a/mit-pthreads/machdep/engine-i386-linux-2.0.h b/mit-pthreads/machdep/engine-i386-linux-2.0.h
deleted file mode 100644
index f4f75621226..00000000000
--- a/mit-pthreads/machdep/engine-i386-linux-2.0.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- */
-
-/* Avoid problem with including bits/pthreadtypes.h with libc 2.2 */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-volatile long temp = SEMAPHORE_SET; \
- \
-__asm__("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-0.9.c b/mit-pthreads/machdep/engine-i386-netbsd-0.9.c
deleted file mode 100644
index c42363fdeda..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-0.9.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- sig_check_and_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * machdep_pthread_create()
- */
-void machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument, long stack_size,
- void *stack_start, long nsec)
-{
- machdep_pthread->machdep_stack = stack_start;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-machdep_sys_send(int s, const void *buf, int len, int flags)
-{
- return(machdep_sys_sendto(s, buf, len, flags, (struct sockaddr*)NULL, 0));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-machdep_sys_recv(int s, void *buf, int len, int flags)
-{
- return(machdep_sys_recvfrom(s, buf, len, flags, (struct sockaddr*)NULL, 0));
-}
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-0.9.h b/mit-pthreads/machdep/engine-i386-netbsd-0.9.h
deleted file mode 100644
index 0e8e93bdbfb..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-0.9.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-1.0.c b/mit-pthreads/machdep/engine-i386-netbsd-1.0.c
deleted file mode 100644
index 7f31cb0305d..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-1.0.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-1.0.h b/mit-pthreads/machdep/engine-i386-netbsd-1.0.h
deleted file mode 100644
index 80e17fef368..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-1.0.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-1.3.c b/mit-pthreads/machdep/engine-i386-netbsd-1.3.c
deleted file mode 100644
index f86a9e5ba56..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-1.3.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
diff --git a/mit-pthreads/machdep/engine-i386-netbsd-1.3.h b/mit-pthreads/machdep/engine-i386-netbsd-1.3.h
deleted file mode 100644
index f399c4b34b6..00000000000
--- a/mit-pthreads/machdep/engine-i386-netbsd-1.3.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/signal.h> /* for _NSIG */
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX (_NSIG-1)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-openbsd-2.0.c b/mit-pthreads/machdep/engine-i386-openbsd-2.0.c
deleted file mode 100644
index 09ff0072fdc..00000000000
--- a/mit-pthreads/machdep/engine-i386-openbsd-2.0.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-i386-freebsd-2.0.c,v 1.1 1995/03/01 01:21:20 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(machdep_sys_setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
-
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- machdep_sys_longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
-
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- machdep_sys_setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
diff --git a/mit-pthreads/machdep/engine-i386-openbsd-2.0.h b/mit-pthreads/machdep/engine-i386-openbsd-2.0.h
deleted file mode 100644
index 87ef21389ce..00000000000
--- a/mit-pthreads/machdep/engine-i386-openbsd-2.0.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-i386-sco-3.2v5.c b/mit-pthreads/machdep/engine-i386-sco-3.2v5.c
deleted file mode 100755
index 95f0d757585..00000000000
--- a/mit-pthreads/machdep/engine-i386-sco-3.2v5.c
+++ /dev/null
@@ -1,1072 +0,0 @@
-
-/* ==== machdep.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for SCO3.2v5 on i386
- *
- * 1.00 96/11/21 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-i386-freebsd-2.0.c,v 1.1 1995/03/01 01:21:20 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/timeb.h>
-#include <sys/stat.h>
-#include <stropts.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/unistd.h>
-#include <sys/utsname.h>
-#include <sys/sysi86.h>
-
-void machdep_sys_abort(char*fname,int lineno)
-
-{
- char buf[128];
-
- sprintf(buf,"panic: %s => %d\n", fname, lineno);
- machdep_sys_write(1, buf, strlen(buf));
- abort();
-}
-
-#if 0
-int setitimer(int which, struct itimerval* value, struct itimerval* ovalue)
-
-{
- register int ret;
- if ((ret = machdep_sys_setitimer(which,value,ovalue))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-#endif
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = (char *)pthread->machdep_data.machdep_float_state;
- __asm__ ("fsave %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-int machdep_restore_float_state(void)
-{
- char * fdata = (char *)pthread_run->machdep_data.machdep_float_state;
- __asm__ ("frstor %0"::"m" (*fdata));
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (machdep_sys_setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
- int ret;
-
- if (machdep_pthread) {
- ret = machdep_sys_setitimer(ITIMER_VIRTUAL, &zeroval,
- &(machdep_pthread->machdep_timer));
- } else {
- ret = machdep_sys_setitimer(ITIMER_VIRTUAL, &zeroval, NULL);
- }
-
- if (ret) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[JB_PC] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[JB_SP] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
-#if 0
- return(machdep_sys_wait4(0, b, c, d));
-#else
- return -ENOSYS;
-#endif
-}
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-machdep_sys_fstat(int f, struct stat* b)
-{
- return machdep_sys_fxstat(0x33, f, b);
-}
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-machdep_sys_dup2(int a, int b)
-{
- machdep_sys_close(b);
- return machdep_sys_fcntl(a, F_DUPFD, b);
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-
-{
- register int ret;
- if ((ret = machdep_sys_sysconf(_SC_OPEN_MAX))<0)
- PANIC();
- return ret;
-}
-
-/* ==========================================================================
- * machdep_sys_fchown()
- */
-machdep_sys_fchown(int fd,uid_t owner,gid_t group)
-
-{
- return -ENOSYS;
-}
-
-/* ==========================================================================
- * machdep_sys_fchmod()
- */
-machdep_sys_fchmod(int fd,mode_t mode)
-
-{
- return -ENOSYS;
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
-
-/* ==========================================================================
- * SCO Socket calls are a bit different
- * ==========================================================================
- * machdep_sys_socket()
- */
-int machdep_sys_socket(int domain, int type, int protocol)
-{
- register int s, fd, ret;
- struct socksysreq req;
-
- if ((s = machdep_sys_open("/dev/socksys", 0))<0)
- return s;
-
- req.args[0] = SO_SOCKET;
- req.args[1] = (int)domain;
- req.args[2] = (int)type;
- req.args[3] = (int)protocol;
- if ((fd = machdep_sys_ioctl(s, SIOCSOCKSYS, &req))<0) {
- machdep_sys_close(s);
- return fd;
- }
-
- if ((ret=machdep_sys_dup2(fd, s))<0) {
- machdep_sys_close(fd);
- return ret;
- }
-
- machdep_sys_close(fd);
- return s;
-
-}
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-int machdep_sys_accept(int s, struct sockaddr * b, int * c)
-{
- struct socksysreq req;
-
- req.args[0] = SO_ACCEPT;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-int machdep_sys_bind(int s, const struct sockaddr * b, int c)
-{
- struct socksysreq req;
-
- req.args[0] = SO_BIND;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-int machdep_sys_connect(int s, const struct sockaddr * b, int c)
-{
- struct socksysreq req;
-
- req.args[0] = SO_CONNECT;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-int machdep_sys_listen(int s, int backlog)
-{
- struct socksysreq req;
-
- req.args[0] = SO_LISTEN;
- req.args[1] = (int)s;
- req.args[2] = (int)backlog;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_shutdown()
- */
-int machdep_sys_shutdown(int s, int b)
-{
- struct socksysreq req;
-
- req.args[0] = SO_SHUTDOWN;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-int machdep_sys_getsockopt(int s, int b, int c, char *d, int *e)
-{
- struct socksysreq req;
-
- req.args[0] = SO_GETSOCKOPT;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
- req.args[4] = (int)d;
- req.args[5] = (int)e;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_setsockopt()
- */
-int machdep_sys_setsockopt(int s, int b, int c, char *d, int e)
-{
- struct socksysreq req;
-
- req.args[0] = SO_SETSOCKOPT;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
- req.args[4] = (int)d;
- req.args[5] = (int)e;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-int machdep_sys_getpeername(int s, struct sockaddr *b, int *c)
-{
- struct socksysreq req;
-
- req.args[0] = SO_GETPEERNAME;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_send()
- */
-int machdep_sys_send(int s, char *b, int c, int d)
-{
- struct socksysreq req;
-
- req.args[0] = SO_SEND;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
- req.args[4] = (int)d;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-int machdep_sys_sendto(int s, char *b, int c, int d,
- struct sockaddr *e, int f)
-{
- struct socksysreq req;
-
- req.args[0] = SO_SENDTO;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
- req.args[4] = (int)d;
- req.args[5] = (int)e;
- req.args[6] = (int)f;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_recv()
- */
-int machdep_sys_recv(int s, char *b, int c, int d)
-{
- struct socksysreq req;
-
- req.args[0] = SO_RECV;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
- req.args[4] = (int)d;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-int machdep_sys_recvfrom(int s, char *buf, int len, int flags,
- struct sockaddr *from, int *fromlen)
-{
- struct socksysreq req;
-
- req.args[0] = SO_RECVFROM;
- req.args[1] = (int)s;
- req.args[2] = (int)buf;
- req.args[3] = (int)len;
- req.args[4] = (int)flags;
- req.args[5] = (int)from;
- req.args[6] = (int)fromlen;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-/* ==========================================================================
- * machdep_sys_socketpair()
- */
-int machdep_sys_socketpair(int d, int type, int protocol, int sv[2])
-
-{
- register int s1, s2;
- register int ret;
- struct socksysreq req;
-
- if (d != AF_UNIX)
- return -EPROTONOSUPPORT;
- if ((s1=machdep_sys_socket(d,type,protocol))<0) {
- return s1;
- }
- if ((s2=machdep_sys_socket(d,type,protocol))<0) {
- machdep_sys_close(s1);
- return s2;
- }
- req.args[0] = SO_SOCKPAIR;
- req.args[1] = s1;
- req.args[2] = s2;
- if ((ret=machdep_sys_ioctl(s1,SIOCSOCKSYS,&req))<0) {
- machdep_sys_close(s1);
- machdep_sys_close(s2);
- return ret;
- }
- sv[0] = s1;
- sv[1] = s2;
- return 0;
-}
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-int machdep_sys_getsockname(int s, char * b, int * c)
-{
- struct socksysreq req;
-
- req.args[0] = SO_GETSOCKNAME;
- req.args[1] = (int)s;
- req.args[2] = (int)b;
- req.args[3] = (int)c;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-int machdep_sys_sendmsg(int s, const struct msghdr *msg, int flags)
-
-{
- struct socksysreq req;
-
- req.args[0] = SO_SENDMSG;
- req.args[1] = (int)s;
- req.args[2] = (int)msg;
- req.args[3] = (int)flags;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-int machdep_sys_recvmsg(int s, struct msghdr *msg, int flags)
-
-{
- struct socksysreq req;
-
- req.args[0] = SO_RECVMSG;
- req.args[1] = (int)s;
- req.args[2] = (int)msg;
- req.args[3] = (int)flags;
-
- return(machdep_sys_ioctl(s, SIOCSOCKSYS, &req));
-}
-
-u_short ntohs(u_short n)
-
-{
- union {
- unsigned char u_nc[4];
- u_short u_ns;
- } ns;
- register unsigned char* p = &ns.u_nc[0];
-
- ns.u_ns = n;
- return (p[0]<<8)|p[1];
-}
-
-u_short htons(u_short h)
-
-{
- union {
- unsigned char u_nc[2];
- u_short u_ns;
- } ns;
- register unsigned char* p = &ns.u_nc[0];
- p[0] = (h>>8)&0xFF;
- p[1] = (h&0xFF);
- return ns.u_ns;
-}
-
-
-u_long ntohl(u_long n)
-
-{
- union {
- unsigned char u_nc[4];
- u_long u_nl;
- } nl;
- register unsigned char* p = &nl.u_nc[0];
-
- nl.u_nl = n;
- return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
-}
-
-u_long htonl(u_long h)
-
-{
- union {
- unsigned char u_nc[4];
- u_long u_nl;
- } nl;
- register unsigned char* p = &nl.u_nc[0];
- p[0] = (h>>24)&0xFF;
- p[1] = (h>>16)&0xFF;
- p[2] = (h>>8)&0xFF;
- p[3] = (h&0xFF);
- return nl.u_nl;
-}
-
-int getdomainname(char* domain,int len)
-
-{
- /* edi = len */
- struct socksysreq req;
- register int ret, fd;
- if (len>MAXHOSTNAMELEN)
- len = MAXHOSTNAMELEN;
-
- if ((fd = machdep_sys_open("/dev/socksys", 0)) < 0)
- return fd;
-
- req.args[0] = SO_GETIPDOMAIN;
- req.args[1] = (int)domain;
- req.args[2] = (int)len;
- if((ret=machdep_sys_ioctl(fd, SIOCSOCKSYS, &req))<0) {
- machdep_sys_close(fd);
- return ret;
- }
-
- machdep_sys_close(fd);
- domain[len-1] = '\0';
- return 0;
-}
-
-int gethostname(char* name, int namelen)
-
-{
- struct utsname uts;
- register int ret, len;
- char domain[MAXHOSTNAMELEN+1];
-
- if (name==NULL)
- return -EFAULT;
- if ((ret=machdep_sys_uname(&uts))<0)
- return ret;
- if (namelen<(len=strlen(uts.nodename)))
- return -EFAULT;
- strncpy(name,uts.nodename,len);
- if (namelen>len)
- name[len] = '\0';
- if ((ret=getdomainname(domain, namelen - len))<0)
- return ret;
- if (domain[0]=='\0')
- return 0;
- if (len + strlen(domain) + 2 > namelen)
- return -EFAULT;
- strcat(name, ".");
- strcat(name, domain);
- return 0;
-}
-
-int gettimeofday(struct timeval* tp, struct timezone* tz)
-
-{
- register int ret;
- if ((ret = machdep_sys_gettimeofday(tp, NULL))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-
-int kill(pid_t pid, int signo)
-
-{
- register int ret;
- if ((ret = machdep_sys_kill(pid,signo))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-
-typedef void (*signal_t(int signo, void (*func)(int)))(int);
-
-signal_t* _libc_signal = NULL;
-
-void (*signal(int signo, void (*func)(int)))(int)
-
-{
- int ret;
- void (*oldfunc)(int);
- extern void (*machdep_sys_signal(int signo, void (*func)(int),int* r))(int);
- if (_libc_signal!=NULL)
- return (*_libc_signal)(signo, func);
-
- oldfunc = machdep_sys_signal(signo, func, &ret);
- if (ret!=0) {
- errno = ret;
- return SIG_ERR;
- }
- else {
- return oldfunc;
- }
-}
-
-int (*_libc_sigaction)(int ,const struct sigaction *, struct sigaction *) = NULL;
-int sigaction(int sig,const struct sigaction *act, struct sigaction *oact)
-
-{
- register int ret;
- if (_libc_sigaction!=NULL)
- return (*_libc_sigaction)(sig,act,oact);
- if ((ret = machdep_sys_sigaction(sig,act,oact))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-
-int (*_libc_sigprocmask)(int, const sigset_t *, sigset_t *) = NULL;
-
-int sigprocmask(int how, const sigset_t *set, sigset_t * oset)
-
-{
- register int ret;
- if (_libc_sigprocmask!=NULL)
- return (*_libc_sigprocmask)(how,set,oset);
- if ((ret = machdep_sys_sigprocmask(how,set,oset))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-
-int (*_libc_sigsuspend)(const sigset_t *) = NULL;
-
-int sigsuspend(const sigset_t *set)
-{
- register int ret;
- if (_libc_sigsuspend!=NULL)
- return (*_libc_sigsuspend)(set);
- if ((ret = machdep_sys_sigsuspend(set))<0) {
- errno = -ret;
- return -1;
- }
- else {
- return 0;
- }
-}
-
-int _sigrelse(sig)
-int sig;
-
-{
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, sig);
- return sigprocmask(SIG_UNBLOCK,&mask,NULL);
-}
-
-int _sighold(sig)
-int sig;
-
-{
- sigset_t mask;
- sigemptyset(&mask);
- sigaddset(&mask, sig);
- return sigprocmask(SIG_BLOCK,&mask,NULL);
-}
-
-void (*sigset(int sig, void (*func)(int)))(int)
-{
- return signal(sig, func);
-}
-
-
-int (*_libc_getmsg)(int , struct strbuf *, struct strbuf *, int *) = NULL;
-
-int getmsg(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
- int * flags)
-{
- register int ret;
- if (_libc_getmsg != NULL)
- return (*_libc_getmsg)(fd,ctlptr,dataptr,flags);
- else if ((ret=machdep_sys_getmsg(fd,ctlptr,dataptr,flags))<0) {
- errno = -ret;
- return -1;
- }
- else
- return ret;
-}
-
-int (*_libc_putmsg)(int , const struct strbuf *, const struct strbuf *, int) = NULL;
-
-int putmsg(int fd, const struct strbuf * ctlptr, const struct strbuf * dataptr,
- int flags)
-{
- register int ret;
- if (_libc_putmsg != NULL)
- return (*_libc_putmsg)(fd,ctlptr,dataptr,flags);
- else if ((ret=machdep_sys_putmsg(fd,ctlptr,dataptr,flags))<0) {
- errno = -ret;
- return -1;
- }
- else
- return ret;
-}
-
-int ftime(struct timeb* tp)
-
-{
- register int ret;
- if ((ret=machdep_sys_ftime(tp))<0) {
- errno = -ret;
- return NOTOK;
- }
- return 0;
-}
-
-int getpagesize()
-
-{
- register int ret;
-#if 0
- if ((ret = machdep_sys_sysconf(_SC_PAGE_SIZE))<0) {
- PANIC();
- SET_ERRNO(-ret);
- return -1;
- }
- else {
- return 0;
- }
-#else
- return PAGESIZE;
-#endif
-}
-
-static pthread_mutex_t machdep_mutex =
-{ MUTEX_TYPE_COUNTING_FAST, PTHREAD_QUEUE_INITIALIZER, \
- NULL, SEMAPHORE_CLEAR, { NULL }, MUTEX_FLAGS_INITED };
-
-static pthread_mutex_t malloc_mutex =
-{ MUTEX_TYPE_COUNTING_FAST, PTHREAD_QUEUE_INITIALIZER, \
- NULL, SEMAPHORE_CLEAR, { NULL }, MUTEX_FLAGS_INITED };
-
-struct stdlock {
- volatile long init;
- pthread_mutex_t* mutex;
-};
-
-static void machdep_stdinitlock(struct stdlock* lock)
-
-{
- if (lock==0) PANIC();
- pthread_mutex_lock(&machdep_mutex);
- if (!lock->init) {
- register pthread_mutex_t* mutex;
- pthread_mutexattr_t attr;
-
- lock->init = 1;
- lock->mutex = &machdep_mutex;
- mutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
- pthread_mutexattr_init (&attr);
- pthread_mutexattr_settype (&attr, MUTEX_TYPE_COUNTING_FAST);
- pthread_mutex_init(mutex, &attr);
- lock->mutex = mutex;
- }
- pthread_mutex_unlock(&machdep_mutex);
-}
-
-void machdep_stdlock(struct stdlock* lock)
-
-{
- if (lock==0) PANIC();
- if (!lock->init)
- machdep_stdinitlock(lock);
- pthread_mutex_lock(lock->mutex);
-}
-
-void machdep_stdunlock(struct stdlock* lock)
-
-{
- if (lock==0) PANIC();
- if (!lock->init)
- machdep_stdinitlock(lock);
- pthread_mutex_unlock(lock->mutex);
-}
-
-int machdep_stdtrylock(struct stdlock* lock)
-
-{
- if (lock==0) PANIC();
- if (!lock->init)
- machdep_stdinitlock(lock);
- return pthread_mutex_trylock(lock->mutex);
-}
-
-int machdep_stdtryunlock(struct stdlock* lock)
-
-{
- if (lock==0) PANIC();
- if (!lock->init)
- machdep_stdinitlock(lock);
- if (pthread_mutex_trylock(lock->mutex))
- return pthread_mutex_unlock(lock->mutex);
- return 0;
-}
-
-extern void (*_libc_stdlock)(struct stdlock* lock);
-extern void (*_libc_stdunlock)(struct stdlock* lock);
-extern int (*_libc_stdtrylock)(struct stdlock* lock);
-extern int (*_libc_stdtryunlock)(struct stdlock* lock);
-
-int machdep_sys_init()
-
-{
- typedef void (*voidfunc_t)();
- extern voidfunc_t _libc_read;
- extern voidfunc_t _libc_write;
- extern voidfunc_t _libc_readv;
- extern voidfunc_t _libc_writev;
- extern voidfunc_t _libc_open;
- extern voidfunc_t _libc_close;
- extern voidfunc_t _libc_fork;
- extern voidfunc_t _libc_fcntl;
- extern voidfunc_t _libc_dup;
- extern voidfunc_t _libc_pipe;
- extern voidfunc_t _libc_select;
- extern voidfunc_t _libc_malloc;
- extern voidfunc_t _libc_realloc;
- extern voidfunc_t _libc_free;
- extern ssize_t pthread_read (int , char*, int );
- extern ssize_t pthread_write (int , char*, int );
- extern int pthread_close (int);
- extern int pthread_dup (int);
- extern int pthread_fork ();
- extern int pthread_pipe (int*);
- extern int pthread_fcntl(int, int, ...);
- extern int pthread_open(const char *, int, ...);
- extern ssize_t pthread_readv (int , const struct iovec *, int );
- extern ssize_t pthread_writev (int , const struct iovec *, int );
- extern int pthread_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
- extern int pthread_getmsg(int , struct strbuf *, struct strbuf *,int*);
- extern int pthread_putmsg(int , const struct strbuf *, const struct strbuf *,int);
- extern void (*pthread_signal(int , void (*)(int)))(int);
- extern int pthread_sigaction(int,const struct sigaction *, struct sigaction *);
- extern int pthread_sigprocmask(int, const sigset_t *, sigset_t *);
- extern int pthread_sigsuspend(const sigset_t *);
-
-
- static struct {
- voidfunc_t *p;
- voidfunc_t f;
- } maptable[] = {
- {(voidfunc_t*)&_libc_read, (voidfunc_t) pthread_read},
- {(voidfunc_t*)&_libc_write, (voidfunc_t) pthread_write},
- {(voidfunc_t*)&_libc_readv, (voidfunc_t) pthread_readv},
- {(voidfunc_t*)&_libc_writev, (voidfunc_t) pthread_writev},
- {(voidfunc_t*)&_libc_open, (voidfunc_t) pthread_open},
- {(voidfunc_t*)&_libc_close, (voidfunc_t) pthread_close},
- {(voidfunc_t*)&_libc_fork, (voidfunc_t) pthread_fork},
- {(voidfunc_t*)&_libc_fcntl, (voidfunc_t) pthread_fcntl},
- {(voidfunc_t*)&_libc_dup, (voidfunc_t) pthread_dup},
- {(voidfunc_t*)&_libc_pipe, (voidfunc_t) pthread_pipe},
- {(voidfunc_t*)&_libc_select, (voidfunc_t) pthread_select},
- {(voidfunc_t*)&_libc_getmsg, (voidfunc_t) pthread_getmsg},
- {(voidfunc_t*)&_libc_putmsg, (voidfunc_t) pthread_putmsg},
- {(voidfunc_t*)&_libc_signal, (voidfunc_t) pthread_signal},
- {(voidfunc_t*)&_libc_sigaction, (voidfunc_t) pthread_sigaction},
- {(voidfunc_t*)&_libc_sigprocmask, (voidfunc_t) pthread_sigprocmask},
- {(voidfunc_t*)&_libc_sigsuspend, (voidfunc_t) pthread_sigsuspend},
- {(voidfunc_t*) 0, (voidfunc_t) 0}
- };
- register int i;
-
- for (i=0; maptable[i].p; i++)
- *maptable[i].p = maptable[i].f;
-
- _libc_stdlock = machdep_stdlock;
- _libc_stdunlock = machdep_stdunlock;
- _libc_stdtrylock = machdep_stdtrylock;
- _libc_stdtryunlock = machdep_stdtryunlock;
- return 0;
-}
-
-#if 0
-extern end;
-char* nd = (char*) &end;
-char* brk(const char* endds)
-
-{
- register int ret;
-
- if ((ret = machdep_sys_brk((char*)endds))<0) {
- SET_ERRNO(-ret);
- return (char*) -1;
- }
- else {
- nd = (char*) endds;
- return 0;
- }
-}
-
-char *sbrk(int incr)
-
-{
- register char* ret;
- if (incr!=0 && (ret=brk(nd + incr))!=0)
- return ret;
- else
- return nd - incr;
-}
-#endif
-
-sigset_t sigmask(int sig)
-
-{
- sigset_t oset;
- sigemptyset(&oset);
- sigaddset(&oset, sig);
- return oset;
-}
-
-sigset_t sigsetmask(sigset_t set)
-
-{
- sigset_t oset;
- sigprocmask(SIG_SETMASK,&set,&oset);
- return oset;
-}
-
-sigset_t sigblock(sigset_t set)
-
-{
- sigset_t oset;
- sigprocmask(SIG_BLOCK,&set,&oset);
- return oset;
-}
diff --git a/mit-pthreads/machdep/engine-i386-sco-3.2v5.h b/mit-pthreads/machdep/engine-i386-sco-3.2v5.h
deleted file mode 100644
index 8b2aa362f06..00000000000
--- a/mit-pthreads/machdep/engine-i386-sco-3.2v5.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * engine-i386-freebsd-2.0.h,v 1.1.4.1 1995/12/13 05:41:52 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-long temp = SEMAPHORE_SET; \
- \
-__asm__ volatile ("xchgl %0,(%2)" \
- :"=r" (temp) \
- :"0" (temp),"r" (lock)); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-#define JB_BP 3
-#define JB_SP 4
-#define JB_PC 5
- char machdep_float_state[108];
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 2048
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-ip22-irix-5.2.c b/mit-pthreads/machdep/engine-ip22-irix-5.2.c
deleted file mode 100644
index d205d05f316..00000000000
--- a/mit-pthreads/machdep/engine-ip22-irix-5.2.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1995 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for IRIX-5.2 on the IP22
- *
- * 1.00 95/04/26 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- int i;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- if (setjmp(machdep_pthread->machdep_state)) {
- machdep_pthread_start();
- }
-
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
-
- /* IP22 stack starts high and builds down. */
- machdep_pthread->machdep_state[JB_SP] =
- (int)machdep_pthread->machdep_stack + stack_size - 1024;
- machdep_pthread->machdep_state[JB_SP] &= ~7;
-
- memcpy((void *)machdep_pthread->machdep_state[JB_SP],
- (char *)(((int)&i) - 24), 32);
-
-}
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-machdep_sys_dup2(int a, int b)
-{
- machdep_sys_close(b);
- machdep_sys_fcntl(a, F_DUPFD, b);
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_waitsys(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_waitsys(a, b, c, NULL));
-}
-
-struct stat;
-
-/* ==========================================================================
- * _fxstat()
- */
-int _fxstat(int __ver, int fd, struct stat *buf)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_fstat(fd_table[fd]->fd.i, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * _lxstat()
- */
-int _lxstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_lstat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * _xstat()
- */
-int _xstat(int __ver, const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_stat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- int i;
-
- i = machdep_sys_getdents(fd, buf, len);
- return i;
-}
diff --git a/mit-pthreads/machdep/engine-ip22-irix-5.2.h b/mit-pthreads/machdep/engine-ip22-irix-5.2.h
deleted file mode 100644
index 94dd386608e..00000000000
--- a/mit-pthreads/machdep/engine-ip22-irix-5.2.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0xff
-
-/*
- * More machine dependent macros
- */
-#ifdef PTHREAD_KERNEL
-
-#define machdep_save_float_state(x)
-#define machdep_restore_float_state()
-
-#endif
-
-/*
- * New types
- */
-typedef char semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIGMAX 32
-#define SIG_ANY(sig) \
-({ \
- sigset_t *sig_addr = (sigset_t *)&sig; \
- int ret = 0; \
- int i; \
- \
- for (i = 1; i <= SIGMAX; i++) { \
- if (sigismember(sig_addr, i)) { \
- ret = 1; \
- break; \
- } \
- } \
- ret; \
-})
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-m68000-netbsd.c b/mit-pthreads/machdep/engine-m68000-netbsd.c
deleted file mode 100644
index 6346c36ca7c..00000000000
--- a/mit-pthreads/machdep/engine-m68000-netbsd.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * m68k work from David Leonard <david.leonard@it.uq.edu.au>.
- * updated and NetBSD/m68k work from Andy Finnell <andyf@vei.net>.
- *
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "pthread.h"
-#include <sys/syscall.h>
-#include <sys/stat.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return( _setjmp(pthread_run->machdep_data.machdep_state) );
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- char * fdata = pthread->machdep_data.machdep_fstate;
-
- __asm__ ( "fmovem fp0-fp7,%0"::"m" (*fdata) );
- __asm__ ( "fmovem fpcr/fpsr/fpi,%0"::"m" (fdata[80]) );
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state(void)
-{
- char * fdata = pthread_run->machdep_data.machdep_fstate;
-
- __asm__ ( "fmovem %0,fp0-fp7"::"m" (*fdata) );
- __asm__ ( "fmovem %0,fpcr/fpsr/fpi"::"m" (fdata[80]) );
-
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0 } };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return((void*)malloc(size));
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current thread's start routine with argument */
- pthread_exit(
- pthread_run->machdep_data.start_routine(
- pthread_run->machdep_data.start_argument
- )
- );
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stack frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- *
- * state is the set_jmp structure, which for m68k is:
- * long onstack_flag; // [0]
- * long sigmask; // [1]
- * long sp; // [2]
- * long fp; // [3]
- * long ap; // [4]
- * long pc; // [5]
- * long ps; // [6]
- * long regs[10]; // non scratch registers
- */
- machdep_pthread->machdep_state[5] = (long)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size;
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-off_t machdep_sys_lseek(int fd, off_t offset, int whence)
-{
- extern off_t __syscall();
-
- return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
-}
-
-int machdep_sys_ftruncate( int fd, off_t length)
-{
- quad_t q;
- int rv;
-
- q = __syscall((quad_t)SYS_ftruncate, fd,0, length);
- if( /* LINTED constant */ sizeof( quad_t ) == sizeof( register_t ) ||
- /* LINTED constant */ BYTE_ORDER == LITTLE_ENDIAN )
- rv = (int)q;
- else
- rv = (int)((u_quad_t)q >> 32);
-
- return rv;
-}
-
-int machdep_sys_fstat( int f, struct stat* st )
-{
- return __fstat13(f,st);
-}
diff --git a/mit-pthreads/machdep/engine-m68000-netbsd.h b/mit-pthreads/machdep/engine-m68000-netbsd.h
deleted file mode 100644
index ec3c6a01bce..00000000000
--- a/mit-pthreads/machdep/engine-m68000-netbsd.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * m68k work by Andy Finnell <andyf@vei.net> based off work by
- * David Leonard and Chris Provenzano.
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0x80;
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
- volatile long temp = SEMAPHORE_CLEAR; \
- __asm__ volatile( \
- "tas %2; bpl 0f; movl #1,%0; 0:" \
- :"=r" (temp) \
- :"0" (temp),"m" (*lock)); \
- temp; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef char semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
- char machdep_fstate[92];
-};
-
-/*
- * Min pthread stacksize
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-
-#ifndef __machdep_stack_get
-#define __machdep_stack_get(x) (x)->machdep_stack
-#endif
-#ifndef __machdep_stack_set
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#endif
-#ifndef __machdep_stack_repl
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-#endif
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-powerpc-netbsd.c b/mit-pthreads/machdep/engine-powerpc-netbsd.c
deleted file mode 100644
index fc17e3de5d0..00000000000
--- a/mit-pthreads/machdep/engine-powerpc-netbsd.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for NetBSD/PowerPC (1.5+)
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * 2001/01/10 briggs
- * -Modified to make it go with NetBSD/PowerPC
- */
-
-#ifndef lint
-static const char rcsid[] = "engine-alpha-osf1.c,v 1.4.4.1 1995/12/13 05:41:37 proven Exp";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* XXXMLG
- * This is EXTREMELY bogus, but it seems that this function is called
- * with the pthread kernel locked. If this happens, __errno() will
- * return the wrong address until after the first context switch.
- *
- * Clearly there is a leak of pthread_kernel somewhere, but until
- * it is found, we force a context switch here, just before calling
- * the thread start routine. When we return from pthread_yield
- * the kernel will be unlocked.
- */
- pthread_yield();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(void *), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Set up new stack frame so that it looks like it returned from a
- longjmp() to the beginning of machdep_pthread_start(). */
- /* state is sigmask, then r8-r31 where r11 is the LR
- * So, istate[3] is r10, which is the SP
- * So, istate[4] is r11, which is the LR
- * So, istate[5] is r12, which is the CR
- */
- machdep_pthread->machdep_istate[4] = (long)machdep_pthread_start;
- machdep_pthread->machdep_istate[5] = 0;
-
- /* PowerPC stack starts high and builds down, and needs to be 16-byte
- aligned. */
- machdep_pthread->machdep_istate[3] =
- ((long) machdep_pthread->machdep_stack + stack_size) & ~0xf;
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return( _setjmp(pthread_run->machdep_data.machdep_istate) );
-}
-
-void machdep_restore_state(void)
-{
- _longjmp(pthread_run->machdep_data.machdep_istate, 1);
-}
-
-void machdep_save_float_state (struct pthread *pthread)
-{
- __machdep_save_fp_state(pthread->machdep_data.machdep_fstate);
-}
-
-void machdep_restore_float_state (void)
-{
- __machdep_restore_fp_state(pthread_run->machdep_data.machdep_fstate);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread);
-void machdep_pthread_start(void);
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void
-__machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void *
-__machdep_stack_alloc(size_t size)
-{
- return(malloc(size));
-}
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-int
-machdep_sys_creat(char * path, int mode)
-{
- return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-int
-machdep_sys_wait3(int * b, int c, int *d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-int
-machdep_sys_waitpid(int a, int * b, int c)
-{
- return(machdep_sys_wait4(a, b, c, NULL));
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-int
-machdep_sys_getdtablesize(void)
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-off_t
-machdep_sys_lseek(int fd, off_t offset, int whence)
-{
- return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
-}
-
-int
-machdep_sys_ftruncate( int fd, off_t length)
-{
- quad_t q;
- int rv;
-
- q = __syscall((quad_t)SYS_ftruncate, fd,0, length);
- if( /* LINTED constant */ sizeof( quad_t ) == sizeof( register_t ) ||
- /* LINTED constant */ BYTE_ORDER == LITTLE_ENDIAN )
- rv = (int)q;
- else
- rv = (int)((u_quad_t)q >> 32);
-
- return rv;
-}
-
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int
-machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
diff --git a/mit-pthreads/machdep/engine-powerpc-netbsd.h b/mit-pthreads/machdep/engine-powerpc-netbsd.h
deleted file mode 100644
index 530b7ca81e2..00000000000
--- a/mit-pthreads/machdep/engine-powerpc-netbsd.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano (proven@athena.mit.edu) and
- * Ken Raeburn (raeburn@mit.edu).
- *
- * engine-alpha-osf1.h,v 1.4.4.1 1995/12/13 05:41:42 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-#include <sys/signal.h> /* for _NSIG */
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0xffff
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
- volatile long t1, temp = SEMAPHORE_SET; \
- __asm__ volatile( \
- "1: lwarx %0,0,%1; \
- cmpwi %0, 0; \
- bne 2f; \
- stwcx. %2,0,%1; \
- bne- 1b; \
- 2: " \
- :"=r" (t1) \
- :"m" (lock), "r" (temp)); \
- t1; \
-})
-
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef int semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX (_NSIG-1)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_istate;
- unsigned long machdep_fstate[66];
- /* 64-bit fp regs 0-31 + fpscr */
- /* We pretend the fpscr is 64 bits */
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
- { NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, { 0 }, { 0 } }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 2048
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if ((stack = __machdep_stack_get(x))) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-int machdep_save_state(void);
-
-void __machdep_save_fp_state(unsigned long *);
-void __machdep_restore_fp_state(unsigned long *);
-void *__machdep_stack_alloc(size_t);
-void __machdep_stack_free(void *);
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-r2000-ultrix-4.2.c b/mit-pthreads/machdep/engine-r2000-ultrix-4.2.c
deleted file mode 100644
index 45c8cc73f24..00000000000
--- a/mit-pthreads/machdep/engine-r2000-ultrix-4.2.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for decstation with r2000/r3000
- *
- * 1.00 93/07/21 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/*
- * The r2000/r3000 processors do not have a test and set instruction, so
- * the semaphore TEST_AND_SET macro is linked very closely to the interrupt
- * handelling of the pthreads package.
- */
-
-/* ==========================================================================
- * semaphore_test_and_set()
- *
- * SEMAPHORE_TEST_AND_SET prevents interrupts, tests the lock and then
- * turns interrupts back on, checking to see if any interrupts have occured
- * between the prevent and resume.
- */
-int semaphore_test_and_set(semaphore *lock)
-{
- int rval;
-
-/* None of this should be necessary
- sig_prevent();
- if (!(rval = (*lock))) {
- *lock = SEMAPHORE_SET;
- }
- sig_check_and_resume();
- return(rval);
-*/
-}
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_save_float_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * fake_longjmp()
- */
-void fake_longjmp(jmp_buf env)
-{
- asm("li $5,1; sw $5, 20($4); li $2,103; syscall");
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- *
- * When I redo machdep_save_state, I'll put the asm in machdep_save_state()
- * and machdep_restore_state() and I won't have to do an additional function
- * call.
- */
-void machdep_restore_state(void)
-{
- fake_longjmp(pthread_run->machdep_data.machdep_state);
- /* longjmp(pthread_run->machdep_data.machdep_state, 1); */
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state(void)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[JB_RA] = (int)machdep_pthread_start;
- machdep_pthread->machdep_state[JB_PC] = (int)machdep_pthread_start;
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state[JB_SP] =
- (int)machdep_pthread->machdep_stack + stack_size;
-
- /* This is the real global pointer */
- /* machdep_pthread->machdep_state[JB_GP] = 0; */
-}
-
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- * This isn't a real implementation; we can make the assumption that the
- * pthreads library is not using oset, and that it is always blocking or
- * unblocking all signals at once.
- */
-int machdep_sys_sigprocmask(int how, const sigset_t *set, sigset_t *oset)
-{
- switch(how) {
- case SIG_BLOCK:
- sigblock(*set);
- break;
- case SIG_UNBLOCK:
- sigsetmask(~*set);
- break;
- case SIG_SETMASK:
- sigsetmask(*set);
- break;
- default:
- return -EINVAL;
- }
- return(OK);
-}
-
diff --git a/mit-pthreads/machdep/engine-r2000-ultrix-4.2.h b/mit-pthreads/machdep/engine-r2000-ultrix-4.2.h
deleted file mode 100644
index 8e2d70f8feb..00000000000
--- a/mit-pthreads/machdep/engine-r2000-ultrix-4.2.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Machine dependent header for decstation with r2000/r3000
- * running Ultrix-4.2
- *
- * 1.00 93/07/21 proven
- * -Started coding this file.
- */
-
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 1
-
-#define SEMAPHORE_TEST_AND_SET(lock) semaphore_test_and_set(lock)
-#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
-
-/*
- * New types
- */
-typedef long semaphore;
-
-#if !defined(_POSIX_SOURCE)
-
-/* typedef int ssize_t; */
-
-#if !defined(__GNUC__)
-
-/*
- * sigset_t macros
- */
-typedef int sigset_t;
-#define sigaddset(set, num) ((*set) |= (1 << (num - 1)))
-#define sigemptyset(set) (*set = 0)
-
-#endif
-#endif
-
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Structures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-
-/*
- * Min stacksize, arch dependent
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK (O_NONBLOCK | O_NDELAY)
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int semaphore_test_and_set __P_((semaphore *));
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-romp-bsd.c b/mit-pthreads/machdep/engine-romp-bsd.c
deleted file mode 100644
index dd1a1096ece..00000000000
--- a/mit-pthreads/machdep/engine-romp-bsd.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for NetBSD on i386
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- return(_pthread_save(pthread_run->machdep_data.machdep_state, 0, 0));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- _pthread_restore(pthread_run->machdep_data.machdep_state);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- sig_check_and_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * machdep_pthread_create()
- */
-void machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument, long stack_size,
- void *stack_start, long nsec)
-{
- machdep_pthread->machdep_stack = stack_start;
-
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- _pthread_save(machdep_pthread->machdep_state,
- (void *)((int)machdep_pthread->machdep_stack + stack_size),
- machdep_pthread_start);
-}
-
diff --git a/mit-pthreads/machdep/engine-romp-bsd.h b/mit-pthreads/machdep/engine-romp-bsd.h
deleted file mode 100644
index 28c59d35e70..00000000000
--- a/mit-pthreads/machdep/engine-romp-bsd.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1993 John F. Carr, jfc@athena.mit.edu
- *
- * Description : Machine dependent header for IBM/RT
- *
- * 1.00 93/09/xx jfc
- * -Coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-/*
- * Stuff for compiling
- */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define const
-#define inline
-#define signed
-#define volatile
-#endif
-
-#define SEMAPHORE_CLEAR 0x0000
-#define SEMAPHORE_SET 0xff00
-#define SEMAPHORE_TEST_AND_SET(lock) _tsh(lock)
-#define SEMAPHORE_RESET(lock) *(lock) = SEMAPHORE_CLEAR
-extern unsigned short _tsh(volatile unsigned short *);
-
-typedef unsigned short semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Min pthread stacksize
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK O_NONBLOCK
-
-#if defined(PTHREAD_KERNEL)
-
-int machdep_save_state __P_((void));
-
-/* save(jmp_buf, stack pointer, restart proc) */
-extern int _pthread_save(jmp_buf, void *, void (*)());
-extern void _pthread_restore(jmp_buf);
-
-typedef int ssize_t;
-typedef unsigned int sigset_t;
-#define sigemptyset(sp) *(sp) = 0
-#define sigprocmask(op, nssp, ossp) if (ossp) *(int *)ossp = sigsetmask(*nssp); else sigsetmask(*nssp)
-#define sigdelset(sp, i) *(sp) &= ~(1 << (i))
-#define sigaddset(sp, i) *(sp) |= (1 << (i))
-#define sigismember(sp, i) (*(sp) & (1 << (i)))
-#endif
diff --git a/mit-pthreads/machdep/engine-sparc-netbsd-1.3.c b/mit-pthreads/machdep/engine-sparc-netbsd-1.3.c
deleted file mode 100644
index 8e0520cfba5..00000000000
--- a/mit-pthreads/machdep/engine-sparc-netbsd-1.3.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for SunOS-4.1.3 on sparc
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- *
- * 98/10/22 bad
- * -update for fat sigset_t in NetBSD 1.3H
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-/* ==========================================================================
- * machdep_save_float_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state(void)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[3] = (int)machdep_pthread_start;
- machdep_pthread->machdep_state[4] = (int)machdep_pthread_start;
-
- /* Sparc stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size - 1024;
- machdep_pthread->machdep_state[2] &= ~7;
-
-}
-
-#if defined(HAVE_SYSCALL_GETDENTS)
-/* ==========================================================================
- * machdep_sys_getdirentries()
- *
- * Always use getdents in place of getdirentries if possible --proven
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
-#endif
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int pid, int * statusp, int options)
-{
- if (pid == -1)
- pid = 0;
- else if (pid == 0)
- pid = - getpgrp ();
- return machdep_sys_wait4 (pid, statusp, options, NULL);
-}
-
-#if !defined(HAVE_SYSCALL_SIGPROCMASK)
-#if 0
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- * This isn't a real implementation; we can make the assumption that the
- * pthreads library is not using oset, and that it is always blocking or
- * unblocking all signals at once.
- */
-int machdep_sys_sigprocmask(int how, const sigset_t *set, sigset_t *oset)
-{
- switch(how) {
- case SIG_BLOCK:
- sigblock(*set);
- break;
- case SIG_UNBLOCK:
- sigsetmask(~*set);
- break;
- case SIG_SETMASK:
- sigsetmask(*set);
- break;
- default:
- return -EINVAL;
- }
- return(OK);
-}
-
-/* ==========================================================================
- * sigaction()
- *
- * Temporary until I do machdep_sys_sigaction()
- */
-int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact)
-{
- return(sigvec(sig, (struct sigvec *)act, (struct sigvec *)oldact));
-}
-#endif
-#endif
-
-#if !defined(HAVE_SYSCALL_GETDTABLESIZE)
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-#endif
diff --git a/mit-pthreads/machdep/engine-sparc-netbsd-1.3.h b/mit-pthreads/machdep/engine-sparc-netbsd-1.3.h
deleted file mode 100644
index a187d3dace8..00000000000
--- a/mit-pthreads/machdep/engine-sparc-netbsd-1.3.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * engine-sparc-sunos-4.1.3.h,v 1.52.4.1 1995/12/13 05:42:33 proven Exp
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-#include <sys/signal.h> /* for _NSIG */
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0xff
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-char *p = lock; \
-long temp; \
- \
-__asm__ volatile("ldstub %1,%0" \
- :"=r" (temp) \
- :"m" (*p) \
- :"memory"); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) \
-{ \
-__asm__ volatile("stb %1, %0" \
- :"=m" (*lock) \
- :"r" (SEMAPHORE_CLEAR) \
- :"memory"); \
-}
-
-/*
- * New types
- */
-typedef char semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX (_NSIG-1)
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK (O_NONBLOCK | O_NDELAY)
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.c b/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.c
deleted file mode 100644
index 6916c3610cd..00000000000
--- a/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for SunOS-4.1.3 on sparc
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-/* ==========================================================================
- * machdep_save_float_state()
- */
-void machdep_save_float_state(struct pthread * pthread)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_restore_float_state()
- */
-void machdep_restore_float_state(void)
-{
- return;
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume ();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * __machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- setjmp(machdep_pthread->machdep_state);
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state[3] = (int)machdep_pthread_start;
- machdep_pthread->machdep_state[4] = (int)machdep_pthread_start;
-
- /* Sparc stack starts high and builds down. */
- machdep_pthread->machdep_state[2] =
- (int)machdep_pthread->machdep_stack + stack_size - 1024;
- machdep_pthread->machdep_state[2] &= ~7;
-
-}
-
-#if defined(HAVE_SYSCALL_GETDENTS)
-/* ==========================================================================
- * machdep_sys_getdirentries()
- *
- * Always use getdents in place of getdirentries if possible --proven
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
-#endif
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(machdep_sys_wait4(0, b, c, d));
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int pid, int * statusp, int options)
-{
- if (pid == -1)
- pid = 0;
- else if (pid == 0)
- pid = - getpgrp ();
- return machdep_sys_wait4 (pid, statusp, options, NULL);
-}
-
-#if !defined(HAVE_SYSCALL_SIGPROCMASK)
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- * This isn't a real implementation; we can make the assumption that the
- * pthreads library is not using oset, and that it is always blocking or
- * unblocking all signals at once.
- */
-int machdep_sys_sigprocmask(int how, const sigset_t *set, sigset_t *oset)
-{
- switch(how) {
- case SIG_BLOCK:
- sigblock(*set);
- break;
- case SIG_UNBLOCK:
- sigsetmask(~*set);
- break;
- case SIG_SETMASK:
- sigsetmask(*set);
- break;
- default:
- return -EINVAL;
- }
- return(OK);
-}
-
-/* ==========================================================================
- * sigaction()
- *
- * Temporary until I do machdep_sys_sigaction()
- */
-int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact)
-{
- return(sigvec(sig, (struct sigvec *)act, (struct sigvec *)oldact));
-}
-#endif
-
-#if !defined(HAVE_SYSCALL_GETDTABLESIZE)
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-#endif
diff --git a/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.h b/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.h
deleted file mode 100644
index 1a4a8768ad0..00000000000
--- a/mit-pthreads/machdep/engine-sparc-sunos-4.1.3.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0xff
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-char *p = lock; \
-long temp; \
- \
-__asm__ volatile("ldstub %1,%0" \
- :"=r" (temp) \
- :"m" (*p) \
- :"memory"); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) \
-{ \
-__asm__ volatile("stb %1, %0" \
- :"=m" (*lock) \
- :"r" (SEMAPHORE_CLEAR) \
- :"memory"); \
-}
-
-/*
- * New types
- */
-typedef char semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIG_ANY(sig) (sig)
-#define SIGMAX 31
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK (O_NONBLOCK | O_NDELAY)
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/engine-sparc-sunos-5.3.c b/mit-pthreads/machdep/engine-sparc-sunos-5.3.c
deleted file mode 100644
index a228a408da3..00000000000
--- a/mit-pthreads/machdep/engine-sparc-sunos-5.3.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/* ==== machdep.c ============================================================
- * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Machine dependent functions for SunOS-4.1.3 on sparc
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/procset.h>
-#include <sys/systeminfo.h>
-#include <poll.h>
-
-/* ==========================================================================
- * machdep_save_state()
- */
-int machdep_save_state(void)
-{
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- return(setjmp(pthread_run->machdep_data.machdep_state));
-}
-
-/* ==========================================================================
- * machdep_restore_state()
- */
-void machdep_restore_state(void)
-{
- longjmp(pthread_run->machdep_data.machdep_state, 1);
-}
-
-/* ==========================================================================
- * machdep_set_thread_timer()
- */
-void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_unset_thread_timer()
- */
-void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
-{
- struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
-
- if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
- PANIC();
- }
-}
-
-/* ==========================================================================
- * machdep_pthread_cleanup()
- */
-void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
-{
- return(machdep_pthread->machdep_stack);
-}
-
-/* ==========================================================================
- * machdep_pthread_start()
- */
-void machdep_pthread_start(void)
-{
- context_switch_done();
- pthread_sched_resume();
-
- /* Run current threads start routine with argument */
- pthread_exit(pthread_run->machdep_data.start_routine
- (pthread_run->machdep_data.start_argument));
-
- /* should never reach here */
- PANIC();
-}
-
-/* ==========================================================================
- * __machdep_stack_free()
- */
-void __machdep_stack_free(void * stack)
-{
- free(stack);
-}
-
-/* ==========================================================================
- * __machdep_stack_alloc()
- */
-void * __machdep_stack_alloc(size_t size)
-{
- void * stack;
-
- return(malloc(size));
-}
-
-/* ==========================================================================
- * machdep_pthread_create()
- */
-void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
- void *(* start_routine)(), void *start_argument,
- long stack_size, long nsec, long flags)
-{
- machdep_pthread->start_routine = start_routine;
- machdep_pthread->start_argument = start_argument;
-
- machdep_pthread->machdep_timer.it_value.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
- machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
- machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
-
- /* Save register windows onto stackframe */
- __asm__ ("ta 3");
-
- if (setjmp(machdep_pthread->machdep_state)) {
- machdep_pthread_start();
- }
-
- /*
- * Set up new stact frame so that it looks like it
- * returned from a longjmp() to the beginning of
- * machdep_pthread_start().
- */
-
- /* Sparc stack starts high and builds down. */
- machdep_pthread->machdep_state[1] =
- (int)machdep_pthread->machdep_stack + stack_size - 1024;
- machdep_pthread->machdep_state[1] &= ~7;
-
-}
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-int machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
-{
- return(machdep_sys_getdents(fd, buf, len));
-}
-
-/* ==========================================================================
- * machdep_sys_wait3()
- */
-machdep_sys_wait3(int * b, int c, int * d)
-{
- return(-ENOSYS);
- /* return(machdep_sys_wait4(0, b, c, d)); */
-}
-
-/* ==========================================================================
- * machdep_sys_waitpid()
- */
-machdep_sys_waitpid(int a, int * b, int c)
-{
- idtype_t id;
-
- switch (a) {
- case -1:
- id = P_ALL;
- break;
- case 0:
- a = machdep_sys_pgrpsys(0);
- id = P_PGID;
- break;
- default:
- if (a < 0) {
- id = P_PGID;
- a = -a;
- } else {
- id = P_PID;
- }
- break;
- }
-
- return(machdep_sys_waitsys(id, a, b, c));
-}
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-machdep_sys_dup2(int a, int b)
-{
- machdep_sys_close(b);
- machdep_sys_fcntl(a, F_DUPFD, b);
-}
-
-/* ==========================================================================
- * machdep_sys_ftruncate()
- */
-machdep_sys_ftruncate(int a, off_t b)
-{
- flock_t c;
-
- c.l_len = 0;
- c.l_start = b;
- c.l_whence = 0;
- return(machdep_sys_fcntl(a, F_FREESP, c));
-}
-
-/* ==========================================================================
- * machdep_sys_select()
- * Recoded to be quicker by Monty
- */
-static fd_set bogus_fds; /* Always zero, never changed */
-
-machdep_sys_select(int nfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
-{
- struct pollfd fds[64],*ptr;
- int i, fds_count, time_out, found;
-
- /* Make sure each arg has a valid pointer */
- if ((readfds == NULL) || (writefds == NULL) || (exceptfds == NULL)) {
- if (exceptfds == NULL) {
- exceptfds = &bogus_fds;
- }
- if (writefds == NULL) {
- writefds = &bogus_fds;
- }
- if (readfds == NULL) {
- readfds = &bogus_fds;
- }
- }
-
- ptr=fds;
- for (i = 0 ; i < nfds; i++)
- {
- if (FD_ISSET(i, readfds))
- {
- if (FD_ISSET(i, writefds))
- ptr->events= POLLIN | POLLOUT;
- else
- ptr->events= POLLIN;
- (ptr++)->fd=i;
- }
- else if (FD_ISSET(i, writefds))
- {
- ptr->events=POLLOUT;
- (ptr++)->fd=i;
- }
- }
- FD_ZERO(readfds);
- FD_ZERO(writefds);
- FD_ZERO(exceptfds);
- time_out = timeout->tv_usec / 1000 + timeout->tv_sec * 1000;
- fds_count=(int) (ptr-fds);
- while ((found = machdep_sys_poll(fds, fds_count, time_out)) <= 0)
- {
- if (found != -ERESTART) /* Try again if restartable */
- return(found); /* Usually 0 ; Cant read or write */
- }
-
- while (ptr-- != fds)
- {
- if (ptr->revents & POLLIN)
- FD_SET(ptr->fd, readfds);
- if (ptr->revents & POLLOUT)
- FD_SET(ptr->fd,writefds);
- }
- return(found);
-}
-
-/* ==========================================================================
- * machdep_sys_getdtablesize()
- */
-machdep_sys_getdtablesize()
-{
- return(sysconf(_SC_OPEN_MAX));
-}
-
-/* ==========================================================================
- * getpagesize()
- */
-getpagesize()
-{
- return(sysconf(_SC_PAGESIZE));
-}
-
-/* ==========================================================================
- * gethostname()
- */
-int gethostname(char * name, int namelen)
-{
- if (sysinfo(SI_HOSTNAME, name, namelen) == NOTOK) {
- return(NOTOK);
- } else {
- return(OK);
- }
-}
-
-/* ==========================================================================
- * machdep_sys_sigaction()
- *
- * This is VERY temporary.
- */
-int machdep_sys_sigaction(int a, void * b, void * c)
-{
- return(sigaction(a, b, c));
-}
diff --git a/mit-pthreads/machdep/engine-sparc-sunos-5.3.h b/mit-pthreads/machdep/engine-sparc-sunos-5.3.h
deleted file mode 100644
index 365ecd799eb..00000000000
--- a/mit-pthreads/machdep/engine-sparc-sunos-5.3.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* ==== machdep.h ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- */
-
-#include <unistd.h>
-#include <setjmp.h>
-#include <sys/time.h>
-#include <sys/cdefs.h>
-
-/*
- * The first machine dependent functions are the SEMAPHORES
- * needing the test and set instruction.
- */
-#define SEMAPHORE_CLEAR 0
-#define SEMAPHORE_SET 0xff
-
-#define SEMAPHORE_TEST_AND_SET(lock) \
-({ \
-char *p = lock; \
-long temp; \
- \
-__asm__ volatile("ldstub %1,%0" \
- :"=r" (temp) \
- :"m" (*p) \
- :"memory"); \
-temp; \
-})
-
-#define SEMAPHORE_RESET(lock) \
-{ \
-__asm__ volatile("stb %1, %0" \
- :"=m" (*lock) \
- :"r" (SEMAPHORE_CLEAR) \
- :"memory"); \
-}
-
-/*
- * More machine dependent macros
- */
-#ifdef PTHREAD_KERNEL
-
-#define machdep_save_float_state(x)
-#define machdep_restore_float_state()
-
-#endif
-
-/*
- * New types
- */
-typedef char semaphore;
-
-/*
- * sigset_t macros
- */
-#define SIGMAX 31
-#define SIG_ANY(sig) \
-({ \
- sigset_t *sig_addr = (sigset_t *)&sig; \
- int ret = 0; \
- int i; \
- \
- for (i = 1; i <= SIGMAX; i++) { \
- if (sigismember(sig_addr, i)) { \
- ret = 1; \
- break; \
- } \
- } \
- ret; \
-})
-
-/*
- * New Strutures
- */
-struct machdep_pthread {
- void *(*start_routine)(void *);
- void *start_argument;
- void *machdep_stack;
- struct itimerval machdep_timer;
- jmp_buf machdep_state;
-};
-
-/*
- * Static machdep_pthread initialization values.
- * For initial thread only.
- */
-#define MACHDEP_PTHREAD_INIT \
-{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, 0 }
-
-/*
- * Minimum stack size
- */
-#undef PTHREAD_STACK_MIN /* Defined in limits.h */
-#define PTHREAD_STACK_MIN 1024
-
-/*
- * Some fd flag defines that are necessary to distinguish between posix
- * behavior and bsd4.3 behavior.
- */
-#define __FD_NONBLOCK (O_NONBLOCK | O_NDELAY)
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-#if defined(PTHREAD_KERNEL)
-
-#define __machdep_stack_get(x) (x)->machdep_stack
-#define __machdep_stack_set(x, y) (x)->machdep_stack = y
-#define __machdep_stack_repl(x, y) \
-{ \
- if (stack = __machdep_stack_get(x)) { \
- __machdep_stack_free(stack); \
- } \
- __machdep_stack_set(x, y); \
-}
-
-void * __machdep_stack_alloc __P_((size_t));
-void __machdep_stack_free __P_((void *));
-
-int machdep_save_state __P_((void));
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/freebsd-1.1/compat.h b/mit-pthreads/machdep/freebsd-1.1/compat.h
deleted file mode 100755
index e7de318aa88..00000000000
--- a/mit-pthreads/machdep/freebsd-1.1/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-1.1/dirent.h b/mit-pthreads/machdep/freebsd-1.1/dirent.h
deleted file mode 100755
index 5226443f86b..00000000000
--- a/mit-pthreads/machdep/freebsd-1.1/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/freebsd-1.1/socket.h b/mit-pthreads/machdep/freebsd-1.1/socket.h
deleted file mode 100755
index f13d01e7fe5..00000000000
--- a/mit-pthreads/machdep/freebsd-1.1/socket.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (c) 1982,1985,1986,1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)socket.h 7.13 (Berkeley) 4/20/91
- * $Id$
- */
-
-#ifndef _SYS_SOCKET_H_
-#define _SYS_SOCKET_H_ 1
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-/*
- * Types
- */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 3 /* raw-protocol interface */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
- int l_onoff; /* option on/off */
- int l_linger; /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_ISO 7 /* ISO protocols */
-#define AF_OSI AF_ISO
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* DEC Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_ROUTE 17 /* Internal Routing Protocol */
-#define AF_LINK 18 /* Link layer interface */
-#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
-#define AF_RMP 20 /* HP's Remote Maint Protocol */
-#define AF_MAX 21
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- u_char sa_len; /* total length */
- u_char sa_family; /* address family */
- char sa_data[14]; /* actually longer; address value */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- u_short sp_family; /* address family */
- u_short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_ISO AF_ISO
-#define PF_OSI AF_ISO
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_ROUTE AF_ROUTE
-#define PF_LINK AF_LINK
-#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
-#define PF_RMP AF_RMP
-
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- * Used value-result for recvmsg, value only for sendmsg.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- u_int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- u_int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_control; /* ancillary data, see below */
- u_int msg_controllen; /* ancillary data buffer len */
- int msg_flags; /* flags on received message */
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-#define MSG_EOR 0x8 /* data completes record */
-#define MSG_TRUNC 0x10 /* data discarded before delivery */
-#define MSG_CTRUNC 0x20 /* control data lost before delivery */
-#define MSG_WAITALL 0x40 /* wait for full request or error */
-
-/*
- * Header for ancillary data objects in msg_control buffer.
- * Used for additional information with/about a datagram
- * not expressible by flags. The format is a sequence
- * of message elements headed by cmsghdr structures.
- */
-struct cmsghdr {
- u_int cmsg_len; /* data byte count, including hdr */
- int cmsg_level; /* originating protocol */
- int cmsg_type; /* protocol-specific type */
-/* followed by u_char cmsg_data[]; */
-};
-
-/* given pointer to struct adatahdr, return pointer to data */
-#define CMSG_DATA(cmsg) ((u_char *)((cmsg) + 1))
-
-/* given pointer to struct adatahdr, return pointer to next adatahdr */
-#define CMSG_NXTHDR(mhdr, cmsg) \
- (((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
- (mhdr)->msg_control + (mhdr)->msg_controllen) ? \
- (struct cmsghdr *)NULL : \
- (struct cmsghdr *)((caddr_t)(cmsg) + ALIGN((cmsg)->cmsg_len)))
-
-#define CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control)
-
-/* "Socket"-level control message types: */
-#define SCM_RIGHTS 0x01 /* access rights (array of int) */
-
-/*
- * 4.3 compat sockaddr, move to compat file later
- */
-struct osockaddr {
- u_short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * 4.3-compat message header (move to compat file later).
- */
-struct omsghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#ifndef KERNEL
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-int getsockname __P_((int, struct sockaddr *, int *));
-int getsockopt __P_((int, int, int, void *, int *));
-int listen __P_((int, int));
-ssize_t recv __P_((int, void *, size_t, int));
-ssize_t recvfrom __P_((int, void *, size_t, int,
- struct sockaddr *, int *));
-int recvmsg __P_((int, struct msghdr *, int));
-ssize_t send __P_((int, const void *, size_t, int));
-ssize_t sendto __P_((int, const void *, size_t, int,
- const struct sockaddr *, int));
-int sendmsg __P_((int, const struct msghdr *, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int shutdown __P_((int, int));
-int socket __P_((int, int, int));
-int socketpair __P_((int, int, int, int *));
-__END_DECLS
-
-#endif /* !KERNEL */
-#endif /* _SYS_SOCKET_H_ */
diff --git a/mit-pthreads/machdep/freebsd-1.1/timers.h b/mit-pthreads/machdep/freebsd-1.1/timers.h
deleted file mode 100755
index 3c4d057976a..00000000000
--- a/mit-pthreads/machdep/freebsd-1.1/timers.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-2.0/__math.h b/mit-pthreads/machdep/freebsd-2.0/__math.h
deleted file mode 100755
index 27ed0f2575d..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__math.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * ANSI/POSIX
- */
-extern char __infinity[];
-#define HUGE_VAL (*(double *) __infinity)
-
diff --git a/mit-pthreads/machdep/freebsd-2.0/__path.h b/mit-pthreads/machdep/freebsd-2.0/__path.h
deleted file mode 100755
index 432494daafa..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "/etc/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/freebsd-2.0/__signal.h b/mit-pthreads/machdep/freebsd-2.0/__signal.h
deleted file mode 100755
index 918955c9948..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__signal.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <sys/signal.h>
-
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) (*(s) |= 1 << ((n) - 1), 0)
-#define __SIGDELSET(s, n) (*(s) &= ~(1 << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ((*(s) & (1 << ((n) - 1))) != 0)
-
diff --git a/mit-pthreads/machdep/freebsd-2.0/__stdio.h b/mit-pthreads/machdep/freebsd-2.0/__stdio.h
deleted file mode 100755
index d60b9df7a54..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__stdio.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
diff --git a/mit-pthreads/machdep/freebsd-2.0/__stdlib.h b/mit-pthreads/machdep/freebsd-2.0/__stdlib.h
deleted file mode 100755
index 5ee2b8ed3d9..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__stdlib.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#ifdef _BSD_WCHAR_T_
-typedef _BSD_WCHAR_T_ wchar_t;
-#ifdef _BSD_RUNE_T_
-typedef _BSD_RUNE_T_ rune_t;
-#undef _BSD_RUNE_T_
-#else
-typedef _BSD_WCHAR_T_ rune_t;
-#endif
-#undef _BSD_WCHAR_T_
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* _STDLIB_H_ */
diff --git a/mit-pthreads/machdep/freebsd-2.0/__string.h b/mit-pthreads/machdep/freebsd-2.0/__string.h
deleted file mode 100755
index 93d4fcf9dd2..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__string.h
+++ /dev/null
@@ -1,21 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-void strmode __P_((int, char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
-
diff --git a/mit-pthreads/machdep/freebsd-2.0/__time.h b/mit-pthreads/machdep/freebsd-2.0/__time.h
deleted file mode 100755
index 5c4b722bc3c..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__time.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <machine/ansi.h>
-#include <machine/limits.h>
-
-#ifdef _BSD_CLOCK_T_
-typedef _BSD_CLOCK_T_ clock_t;
-#undef _BSD_CLOCK_T_
-#endif
-
-#ifdef _BSD_TIME_T_
-typedef _BSD_TIME_T_ time_t;
-#undef _BSD_TIME_T_
-#endif
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#define CLOCKS_PER_SEC 100
-
-#if !defined(CLK_TCK)
-#define CLK_TCK 100
-#endif /* not CLK_TCK */
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/freebsd-2.0/__unistd.h b/mit-pthreads/machdep/freebsd-2.0/__unistd.h
deleted file mode 100755
index ed5b0657727..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/__unistd.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define ioctl_request_type unsigned long /* For fd.c */
-
-/* compile-time symbolic constants */
-#define _POSIX_JOB_CONTROL /* implementation supports job control */
-
-#ifdef _NOT_AVAILABLE
-#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */
-#endif
-
-#ifndef _POSIX_VERSION
-#define _POSIX_VERSION 198808L
-#endif
-#ifndef _POSIX2_VERSION
-#define _POSIX2_VERSION 199212L
-#endif
-
-/* execution-time symbolic constants */
- /* chown requires appropriate privileges */
-#define _POSIX_CHOWN_RESTRICTED 1
- /* too-long path components generate errors */
-#define _POSIX_NO_TRUNC 1
- /* may disable terminal special characters */
-#define _POSIX_VDISABLE 0xff
-
-/* configurable pathname variables */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_CHOWN_RESTRICTED 7
-#define _PC_NO_TRUNC 8
-#define _PC_VDISABLE 9
-
-/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-
-/* configurable system strings */
-#define _CS_PATH 1
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-2.0/compat.h b/mit-pthreads/machdep/freebsd-2.0/compat.h
deleted file mode 100755
index e7de318aa88..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-2.0/dirent.h b/mit-pthreads/machdep/freebsd-2.0/dirent.h
deleted file mode 100755
index 5226443f86b..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/freebsd-2.0/errno.h b/mit-pthreads/machdep/freebsd-2.0/errno.h
deleted file mode 100755
index 3da61d692a3..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/errno.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $NetBSD: errno.h,v 1.8 1994/06/29 06:44:02 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-2.0/timers.h b/mit-pthreads/machdep/freebsd-2.0/timers.h
deleted file mode 100755
index f9768c68c8f..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-#endif
diff --git a/mit-pthreads/machdep/freebsd-2.0/wait.h b/mit-pthreads/machdep/freebsd-2.0/wait.h
deleted file mode 100755
index 7861e3fa180..00000000000
--- a/mit-pthreads/machdep/freebsd-2.0/wait.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- * $Id$
- */
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#include <machine/endian.h>
-
-/*
- * Deprecated:
- * Structure of the information in the status word returned by wait4.
- * If w_stopval==WSTOPPED, then the second structure describes
- * the information returned, else the first.
- */
-union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-};
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#ifndef KERNEL
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/__math.h b/mit-pthreads/machdep/hpux-10.20/__math.h
deleted file mode 100755
index 8066bd60713..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__math.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#define HUGE_VAL 1.7976931348623157e+308
-
-
diff --git a/mit-pthreads/machdep/hpux-10.20/__signal.h b/mit-pthreads/machdep/hpux-10.20/__signal.h
deleted file mode 100755
index fbb1d6ce2b1..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__signal.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <sys/signal.h>
-
-#ifndef SIGCLD
-#define SIGCLD SIGCHLD
-#endif
-
-/* #define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1))) */
-#define sigword(n) (((unsigned int)((n) - 1))>>5)
-
-#define __SIGEMPTYSET { 0, 0, 0, 0, 0, 0, 0, 0 }
-#define __SIGFILLSET { 0xffffffff,0xffffffff,0xffffffff,0xffffffff,\
- 0xffffffff,0xffffffff,0xffffffff,0xffffffff}
-#define __SIGADDSET(s, n) ((s)->sigset[sigword(n)] |= sigmask(n))
-#define __SIGDELSET(s, n) ((s)->sigset[sigword(n)] &= ~sigmask(n))
-#define __SIGISMEMBER(s, n) ((s)->sigset[sigword(n)] & sigmask(n))
-
-#define SIGSET_SIZE sizeof(sigset_t)/sizeof(long)
-
-#define SIG_ANY(sig) sig_any(&sig)
-
-static inline int sig_any(sigset_t *sig) {
- int i;
- for (i=0; i < SIGSET_SIZE; i++)
- if (sig->sigset[i] != 0)
- return 1;
- return 0;
-}
-
diff --git a/mit-pthreads/machdep/hpux-10.20/__stdio.h b/mit-pthreads/machdep/hpux-10.20/__stdio.h
deleted file mode 100755
index b8f1a07d9d6..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__stdio.h
+++ /dev/null
@@ -1,11 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-#include <sys/types.h>
-/*
-typedef pthread_fpos_t fpos_t;
-*/
-
diff --git a/mit-pthreads/machdep/hpux-10.20/__stdlib.h b/mit-pthreads/machdep/hpux-10.20/__stdlib.h
deleted file mode 100755
index 37a14a960d5..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__stdlib.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* $Id$ */
-
-#ifndef __sys_stdtypes_h
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef unsigned int wchar_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/__string.h b/mit-pthreads/machdep/hpux-10.20/__string.h
deleted file mode 100755
index 1badf6d660c..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__string.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#ifndef _SYS_STDSYMS_INCLUDED
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard SunOS 4.x string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/__time.h b/mit-pthreads/machdep/hpux-10.20/__time.h
deleted file mode 100755
index ae958dcc3cf..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__time.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $Id$ */
-
-#ifndef __sys_stdtypes_h
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#define CLOCKS_PER_SEC 1000000
-
-#if !defined(_ANSI_SOURCE) && !defined(CLK_TCK)
-#define CLK_TCK 60
-#endif /* not ANSI */
-
-#endif
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/hpux-10.20/__unistd.h b/mit-pthreads/machdep/hpux-10.20/__unistd.h
deleted file mode 100755
index 218e13d14ec..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/__unistd.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* /afs/sipb.mit.edu/project/pthreads/src/CVS/pthreads/machdep/hpux-9.03/__unist
-d.h,v 1.2 1995/03/10 03:59:53 snl Exp */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/stdsyms.h>
-#include <sys/types.h>
-#include <utime.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef _GID_T
-#define _GID_T
-typedef long gid_t;
-#endif
-
-#ifndef _UID_T
-#define _UID_T
-typedef long uid_t;
-#endif
-
-#ifndef _PID_T
-#define _PID_T
-typedef long pid_t;
-#endif
-
-#ifndef _OFF_T
-#define _OFF_T
-typedef long off_t;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef int ssize_t;
-#endif
-
-#define ioctl_request_type int /* For fd.c */
-
-/* Symbolic constants for sysconf() variables defined by POSIX.1-1988: 0-7 */
-
-#define _SC_ARG_MAX 0 /* ARG_MAX: Max length of argument to exec()
- including environment data */
-#define _SC_CHILD_MAX 1 /* CHILD_MAX: Max of processes per userid */
-#define _SC_CLK_TCK 2 /* Number of clock ticks per second */
-#define _SC_NGROUPS_MAX 3 /* NGROUPS_MAX: Max of simultaneous
- supplementary group IDs per process */
-#define _SC_OPEN_MAX 4 /* OPEN_MAX: Max of files that one process
- can have open at any one time */
-#define _SC_JOB_CONTROL 5 /* _POSIX_JOB_CONTROL: 1 iff supported */
-#define _SC_SAVED_IDS 6 /* _POSIX_SAVED_IDS: 1 iff supported */
-#define _SC_1_VERSION_88 7 /* _POSIX_VERSION: Date of POSIX.1-1988 */
-
-/* Symbolic constants for sysconf() variables added by POSIX.1-1990: 100-199 */
-
-#define _SC_STREAM_MAX 100 /* STREAM_MAX: Max of open stdio FILEs */
-#define _SC_TZNAME_MAX 101 /* TZNAME_MAX: Max length of timezone name */
-#define _SC_1_VERSION_90 102 /* _POSIX_VERSION: Date of POSIX.1-1990 */
-
-#endif /* _SYS___UNISTD_H_ */
-
diff --git a/mit-pthreads/machdep/hpux-10.20/cdefs.h b/mit-pthreads/machdep/hpux-10.20/cdefs.h
deleted file mode 100755
index 643089e6df6..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/cdefs.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-#include <sys/_inttypes.h>
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __INLINE static
-#define __BEGIN_DECLS
-#define __END_DECLS
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-/*
-typedef int int32_t;
-*/
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-/*
-typedef short int16_t;
-*/
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/compat.h b/mit-pthreads/machdep/hpux-10.20/compat.h
deleted file mode 100755
index 5a59434417c..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Compatibility header for networking code.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/dirent.h b/mit-pthreads/machdep/hpux-10.20/dirent.h
deleted file mode 100755
index 5f17af345db..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/dirent.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/hpux-10.20/socket.h b/mit-pthreads/machdep/hpux-10.20/socket.h
deleted file mode 100755
index c7a37706940..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/socket.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 1982, 1985, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)socket.h 7.3 (Berkeley) 6/27/88
- */
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-#include <sys/stdsyms.h>
-#include <pthread/posix.h>
-#include <sys/cdefs.h>
-
-/*
- * Types of sockets
- */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 3 /* raw-protocol interface */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_SND_COPYAVOID 0x1009 /* avoid copy on send*/
-#define SO_RCV_COPYAVOID 0x100a /* avoid copy on rcv */
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_NBS 7 /* nbs protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_OTS 17 /* Used for OSI in the ifnets */
-#define AF_NIT 18 /* NIT */
-
-#define AF_MAX 19
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- unsigned short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- unsigned short sp_family; /* address family */
- unsigned short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_NBS AF_NBS
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 20
-
-/*
- * Message header for recvmsg and sendmsg calls.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-
-#define MSG_MAXIOVLEN 16
-
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/hpux-10.20/stdtypes.h b/mit-pthreads/machdep/hpux-10.20/stdtypes.h
deleted file mode 100755
index 2b22abbf818..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/stdtypes.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* @(#)stdtypes.h 1.6 90/01/04 SMI */
-
-/*
- * Suppose you have an ANSI C or POSIX thingy that needs a typedef
- * for thingy_t. Put it here and include this file wherever you
- * define the thingy. This is used so that we don't have size_t in
- * N (N > 1) different places and so that we don't have to have
- * types.h included all the time and so that we can include this in
- * the lint libs instead of termios.h which conflicts with ioctl.h.
- */
-#ifndef __sys_stdtypes_h
-#define __sys_stdtypes_h
-
-#ifndef _SIGSET_T_
-#define _SIGSET_T_
-typedef int sigset_t; /* signal mask - may change */
-#endif
-
-#ifndef _SPEED_T_
-#define _SPEED_T_
-typedef unsigned int speed_t; /* tty speeds */
-#endif
-
-#ifndef _TCFLAG_T_
-#define _TCFLAG_T_
-typedef unsigned long tcflag_t; /* tty line disc modes */
-#endif
-
-#ifndef _CC_T_
-#define _CC_T_
-typedef unsigned char cc_t; /* tty control char */
-#endif
-
-#ifndef _PID_T_
-#define _PID_T_
-typedef int pid_t; /* process id */
-#endif
-
-#ifndef _MODE_T_
-#define _MODE_T_
-typedef unsigned short mode_t; /* file mode bits */
-#endif
-
-#ifndef _NLINK_T_
-#define _NLINK_T_
-typedef short nlink_t; /* links to a file */
-#endif
-
-#ifndef _CLOCK_T_
-#define _CLOCK_T_
-typedef long clock_t; /* units=ticks (typically 60/sec) */
-#endif
-
-#ifndef _TIME_T_
-#define _TIME_T_
-typedef long time_t; /* value = secs since epoch */
-#endif
-
-#ifndef _SIZE_T_
-#define _SIZE_T_
-typedef int size_t; /* ??? */
-#endif
-
-#ifndef _PTRDIFF_T_
-#define _PTRDIFF_T_
-typedef int ptrdiff_t; /* result of subtracting two pointers */
-#endif
-
-#ifndef _WCHAR_T_
-#define _WCHAR_T_
-typedef unsigned short wchar_t; /* big enough for biggest char set */
-#endif
-
-#endif /* !__sys_stdtypes_h */
diff --git a/mit-pthreads/machdep/hpux-10.20/time.h b/mit-pthreads/machdep/hpux-10.20/time.h
deleted file mode 100755
index 544905b0749..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/time.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/* $Header$ */
-
-#ifndef _SYS_TIME_INCLUDED
-#define _SYS_TIME_INCLUDED
-
-/* time.h: Definitions for time handling functions */
-
-#ifdef _KERNEL_BUILD
-#include "../h/stdsyms.h"
-#else /* ! _KERNEL_BUILD */
-#include <sys/stdsyms.h>
-#endif /* _KERNEL_BUILD */
-
-#include <sys/types.h>
-
-/* ANSI C time constants, types, and structures */
-
-#ifdef _INCLUDE__STDC__
-# define CLOCKS_PER_SEC 1000000
-
-# ifndef NULL
-# define NULL 0
-# endif
-
-# ifndef _CLOCK_T
-# define _CLOCK_T
- typedef unsigned long clock_t;
-# endif /* _CLOCK_T */
-
-# ifndef _TIME_T
-# define _TIME_T
- typedef long time_t;
-# endif /* _TIME_T */
-
-# ifndef _SIZE_T
-# define _SIZE_T
- typedef unsigned int size_t;
-# endif /* _SIZE_T */
-
- /* Structure used with gmtime(), localtime(), mktime(), strftime(). */
- struct tm {
- int tm_sec; /* second (0-61, allows for leap seconds) */
- int tm_min; /* minute (0-59) */
- int tm_hour; /* hour (0-23) */
- int tm_mday; /* day of the month (1-31) */
- int tm_mon; /* month (0-11) */
- int tm_year; /* years since 1900 */
- int tm_wday; /* day of the week (0-6) */
- int tm_yday; /* day of the year (0-365) */
- int tm_isdst; /* non-0 if daylight savings time is in effect */
- };
-#endif /* _INCLUDE__STDC__ */
-
-
-/* Additional types needed for HP-UX */
-
-#ifdef _INCLUDE_HPUX_SOURCE
-# ifndef _STRUCT_TIMEVAL
-# define _STRUCT_TIMEVAL
- /* Structure returned by gettimeofday(2) system call and others */
- struct timeval {
- unsigned long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
- };
-# endif /* _STRUCT_TIMEVAL */
-
- /* Structure used to represent timezones for gettimeofday(2) and others */
- struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
- };
-
- /* Structure defining a timer setting. */
- struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
- };
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-
-/* Function prototypes and external variable declarations */
-
-#ifndef _KERNEL
-#ifdef __cplusplus
- extern "C" {
-#endif /* __cplusplus */
-
-#ifdef _INCLUDE__STDC__
-# ifdef _PROTOTYPES
- extern double difftime(time_t, time_t);
- extern time_t mktime(struct tm *);
- extern time_t time(time_t *);
- extern char *ctime(const time_t *);
- extern struct tm *gmtime(const time_t *);
- extern struct tm *localtime(const time_t *);
- extern size_t strftime(char *, size_t, const char *, const struct tm *);
-# else /* not _PROTOTYPES */
- extern double difftime();
- extern time_t mktime();
- extern time_t time();
- extern char *ctime();
- extern struct tm *gmtime();
- extern struct tm *localtime();
- extern size_t strftime();
-# endif /* not _PROTOTYPES */
-
-# ifdef _CLASSIC_ANSI_TYPES
- extern long clock();
-# else /* not _CLASSIC_ANSI_TYPES */
-# ifdef _PROTOTYPES
- extern clock_t clock(void);
-# else /* not _PROTOTYPES */
- extern clock_t clock();
-# endif /* not _PROTOTYPES */
-# endif /* not _CLASSIC_ANSI_TYPES */
-#endif /* _INCLUDE__STDC__ */
-
-#ifdef _INCLUDE_POSIX_SOURCE
-# ifdef _PROTOTYPES
- extern void tzset(void);
-# else /* not _PROTOTYPES */
- extern void tzset();
-# endif /* not _PROTOTYPES */
-
- extern char *tzname[2];
-#endif /* _INCLUDE_POSIX_SOURCE */
-
-
-#ifdef _INCLUDE_XOPEN_SOURCE
-# ifdef _PROTOTYPES
- extern char *strptime(const char *, const char *, struct tm *);
-# else /* not _PROTOTYPES */
- extern char *strptime();
-# endif /* not _PROTOTYPES */
-
- extern long timezone;
- extern int daylight;
-#endif /* _INCLUDE_XOPEN_SOURCE */
-
-
-#ifdef _INCLUDE_HPUX_SOURCE
-# ifdef _PROTOTYPES
- extern struct tm *getdate(const char *);
- extern char *nl_asctime(struct tm *, char *, int);
- extern char *nl_ctime(long *, char *, int);
- extern char *nl_ascxtime(struct tm *, char *);
- extern char *nl_cxtime(long *, char *);
- extern int getitimer(int, struct itimerval *);
- extern int setitimer(int, const struct itimerval *, struct itimerval *);
- extern int gettimeofday(struct timeval *, struct timezone *);
- extern int settimeofday(const struct timeval *, const struct timezone *);
- extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
- extern int stime(const time_t *);
-# else /* not _PROTOTYPES */
- extern struct tm *getdate();
- extern char *nl_asctime();
- extern char *nl_ctime();
- extern char *nl_ascxtime();
- extern char *nl_cxtime();
- extern int getitimer();
- extern int setitimer();
- extern int gettimeofday();
- extern int settimeofday();
- extern int select();
- extern int stime();
-# endif /* not _PROTOTYPES */
- extern int getdate_err;
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-#ifdef __cplusplus
- }
-#endif /* __cplusplus */
-#endif /* not _KERNEL */
-
-
-/*
- * CLK_TCK is needed by the kernel, and also in the POSIX namespace.
- */
-
-#ifdef _INCLUDE_POSIX_SOURCE
-# ifndef CLK_TCK
-# ifdef __hp9000s300
-# define CLK_TCK 50
-# endif /* __hp9000s300 */
-# ifdef __hp9000s800
-# define CLK_TCK 100
-# endif /* __hp9000s800 */
-# endif /* CLK_TCK */
-#endif
-
-
-/* Additional HP-UX structures, macros, and constants */
-
-#ifdef _INCLUDE_HPUX_SOURCE
-
- /* Kernel instrumentation time value */
- struct ki_timeval {
- long tv_sec; /* seconds */
- long tv_nunit; /* and native units */
- };
-
- /* Kinds of daylight savings time */
-# define DST_NONE 0 /* not on dst */
-# define DST_USA 1 /* USA style dst */
-# define DST_AUST 2 /* Australian style dst */
-# define DST_WET 3 /* Western European dst */
-# define DST_MET 4 /* Middle European dst */
-# define DST_EET 5 /* Eastern European dst */
-
- /*
- * Operations on timevals.
- *
- * NB: timercmp does not work for >= or <=.
- */
-# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-# define timercmp(tvp, uvp, cmp) \
- ((tvp)->tv_sec cmp (uvp)->tv_sec || \
- (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
-# define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
-
- /* Names of the interval timers */
-# define ITIMER_REAL 0
-# define ITIMER_VIRTUAL 1
-# define ITIMER_PROF 2
-
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-#endif /* _SYS_TIME_INCLUDED */
diff --git a/mit-pthreads/machdep/hpux-10.20/timers.h b/mit-pthreads/machdep/hpux-10.20/timers.h
deleted file mode 100755
index 5a76a295400..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/timers.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/signal.h>
-#include <sys/types.h>
-#include <time.h>
-
-/*
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-*/
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-10.20/uio.h b/mit-pthreads/machdep/hpux-10.20/uio.h
deleted file mode 100755
index d1ec4c94f22..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/uio.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct HP-UX header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-#include <sys/cdefs.h>
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-__BEGIN_DECLS
-
-int readv __P_((int, const struct iovec *, int));
-int writev __P_((int, const struct iovec *, int));
-
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/machdep/hpux-10.20/wait.h b/mit-pthreads/machdep/hpux-10.20/wait.h
deleted file mode 100755
index bca70d9f1ec..00000000000
--- a/mit-pthreads/machdep/hpux-10.20/wait.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)wait.h 8.1 (Berkeley) 6/2/93
- * $Id$
- */
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#define _W_INT(i) (i)
-#define WCOREFLAG 0200
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-#endif
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/__math.h b/mit-pthreads/machdep/hpux-9.03/__math.h
deleted file mode 100755
index 8066bd60713..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__math.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#define HUGE_VAL 1.7976931348623157e+308
-
-
diff --git a/mit-pthreads/machdep/hpux-9.03/__signal.h b/mit-pthreads/machdep/hpux-9.03/__signal.h
deleted file mode 100755
index fbb1d6ce2b1..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__signal.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <sys/signal.h>
-
-#ifndef SIGCLD
-#define SIGCLD SIGCHLD
-#endif
-
-/* #define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1))) */
-#define sigword(n) (((unsigned int)((n) - 1))>>5)
-
-#define __SIGEMPTYSET { 0, 0, 0, 0, 0, 0, 0, 0 }
-#define __SIGFILLSET { 0xffffffff,0xffffffff,0xffffffff,0xffffffff,\
- 0xffffffff,0xffffffff,0xffffffff,0xffffffff}
-#define __SIGADDSET(s, n) ((s)->sigset[sigword(n)] |= sigmask(n))
-#define __SIGDELSET(s, n) ((s)->sigset[sigword(n)] &= ~sigmask(n))
-#define __SIGISMEMBER(s, n) ((s)->sigset[sigword(n)] & sigmask(n))
-
-#define SIGSET_SIZE sizeof(sigset_t)/sizeof(long)
-
-#define SIG_ANY(sig) sig_any(&sig)
-
-static inline int sig_any(sigset_t *sig) {
- int i;
- for (i=0; i < SIGSET_SIZE; i++)
- if (sig->sigset[i] != 0)
- return 1;
- return 0;
-}
-
diff --git a/mit-pthreads/machdep/hpux-9.03/__stdio.h b/mit-pthreads/machdep/hpux-9.03/__stdio.h
deleted file mode 100755
index 091b065a2e9..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__stdio.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-typedef pthread_fpos_t fpos_t;
-
diff --git a/mit-pthreads/machdep/hpux-9.03/__stdlib.h b/mit-pthreads/machdep/hpux-9.03/__stdlib.h
deleted file mode 100755
index 37a14a960d5..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__stdlib.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* $Id$ */
-
-#ifndef __sys_stdtypes_h
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef unsigned int wchar_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/__string.h b/mit-pthreads/machdep/hpux-9.03/__string.h
deleted file mode 100755
index 1badf6d660c..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__string.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#ifndef _SYS_STDSYMS_INCLUDED
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard SunOS 4.x string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/__time.h b/mit-pthreads/machdep/hpux-9.03/__time.h
deleted file mode 100755
index ae958dcc3cf..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__time.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $Id$ */
-
-#ifndef __sys_stdtypes_h
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#define CLOCKS_PER_SEC 1000000
-
-#if !defined(_ANSI_SOURCE) && !defined(CLK_TCK)
-#define CLK_TCK 60
-#endif /* not ANSI */
-
-#endif
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/hpux-9.03/__unistd.h b/mit-pthreads/machdep/hpux-9.03/__unistd.h
deleted file mode 100755
index 0e8515b1f96..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/__unistd.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* /afs/sipb.mit.edu/project/pthreads/src/CVS/pthreads/machdep/hpux-9.03/__unist
-d.h,v 1.2 1995/03/10 03:59:53 snl Exp */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/stdsyms.h>
-#include <sys/types.h>
-#include <utime.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef _GID_T
-#define _GID_T
-typedef long gid_t;
-#endif
-
-#ifndef _UID_T
-#define _UID_T
-typedef long uid_t;
-#endif
-
-#ifndef _PID_T
-#define _PID_T
-typedef long pid_t;
-#endif
-
-#ifndef _OFF_T
-#define _OFF_T
-typedef long off_t;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef int ssize_t;
-#endif
-
-/* Symbolic constants for sysconf() variables defined by POSIX.1-1988: 0-7 */
-
-#define _SC_ARG_MAX 0 /* ARG_MAX: Max length of argument to exec()
- including environment data */
-#define _SC_CHILD_MAX 1 /* CHILD_MAX: Max of processes per userid */
-#define _SC_CLK_TCK 2 /* Number of clock ticks per second */
-#define _SC_NGROUPS_MAX 3 /* NGROUPS_MAX: Max of simultaneous
- supplementary group IDs per process */
-#define _SC_OPEN_MAX 4 /* OPEN_MAX: Max of files that one process
- can have open at any one time */
-#define _SC_JOB_CONTROL 5 /* _POSIX_JOB_CONTROL: 1 iff supported */
-#define _SC_SAVED_IDS 6 /* _POSIX_SAVED_IDS: 1 iff supported */
-#define _SC_1_VERSION_88 7 /* _POSIX_VERSION: Date of POSIX.1-1988 */
-
-/* Symbolic constants for sysconf() variables added by POSIX.1-1990: 100-199 */
-
-#define _SC_STREAM_MAX 100 /* STREAM_MAX: Max of open stdio FILEs */
-#define _SC_TZNAME_MAX 101 /* TZNAME_MAX: Max length of timezone name */
-#define _SC_1_VERSION_90 102 /* _POSIX_VERSION: Date of POSIX.1-1990 */
-
-#endif /* _SYS___UNISTD_H_ */
-
diff --git a/mit-pthreads/machdep/hpux-9.03/cdefs.h b/mit-pthreads/machdep/hpux-9.03/cdefs.h
deleted file mode 100755
index 041300cbe02..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/cdefs.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __INLINE static
-#define __BEGIN_DECLS
-#define __END_DECLS
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/compat.h b/mit-pthreads/machdep/hpux-9.03/compat.h
deleted file mode 100755
index 5a59434417c..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Compatibility header for networking code.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/dirent.h b/mit-pthreads/machdep/hpux-9.03/dirent.h
deleted file mode 100755
index 5f17af345db..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/dirent.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/hpux-9.03/socket.h b/mit-pthreads/machdep/hpux-9.03/socket.h
deleted file mode 100755
index c7a37706940..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/socket.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 1982, 1985, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)socket.h 7.3 (Berkeley) 6/27/88
- */
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-#include <sys/stdsyms.h>
-#include <pthread/posix.h>
-#include <sys/cdefs.h>
-
-/*
- * Types of sockets
- */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 3 /* raw-protocol interface */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_SND_COPYAVOID 0x1009 /* avoid copy on send*/
-#define SO_RCV_COPYAVOID 0x100a /* avoid copy on rcv */
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_NBS 7 /* nbs protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_OTS 17 /* Used for OSI in the ifnets */
-#define AF_NIT 18 /* NIT */
-
-#define AF_MAX 19
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- unsigned short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- unsigned short sp_family; /* address family */
- unsigned short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_NBS AF_NBS
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 20
-
-/*
- * Message header for recvmsg and sendmsg calls.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-
-#define MSG_MAXIOVLEN 16
-
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-
-__END_DECLS
-
diff --git a/mit-pthreads/machdep/hpux-9.03/stdtypes.h b/mit-pthreads/machdep/hpux-9.03/stdtypes.h
deleted file mode 100755
index 2b22abbf818..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/stdtypes.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* @(#)stdtypes.h 1.6 90/01/04 SMI */
-
-/*
- * Suppose you have an ANSI C or POSIX thingy that needs a typedef
- * for thingy_t. Put it here and include this file wherever you
- * define the thingy. This is used so that we don't have size_t in
- * N (N > 1) different places and so that we don't have to have
- * types.h included all the time and so that we can include this in
- * the lint libs instead of termios.h which conflicts with ioctl.h.
- */
-#ifndef __sys_stdtypes_h
-#define __sys_stdtypes_h
-
-#ifndef _SIGSET_T_
-#define _SIGSET_T_
-typedef int sigset_t; /* signal mask - may change */
-#endif
-
-#ifndef _SPEED_T_
-#define _SPEED_T_
-typedef unsigned int speed_t; /* tty speeds */
-#endif
-
-#ifndef _TCFLAG_T_
-#define _TCFLAG_T_
-typedef unsigned long tcflag_t; /* tty line disc modes */
-#endif
-
-#ifndef _CC_T_
-#define _CC_T_
-typedef unsigned char cc_t; /* tty control char */
-#endif
-
-#ifndef _PID_T_
-#define _PID_T_
-typedef int pid_t; /* process id */
-#endif
-
-#ifndef _MODE_T_
-#define _MODE_T_
-typedef unsigned short mode_t; /* file mode bits */
-#endif
-
-#ifndef _NLINK_T_
-#define _NLINK_T_
-typedef short nlink_t; /* links to a file */
-#endif
-
-#ifndef _CLOCK_T_
-#define _CLOCK_T_
-typedef long clock_t; /* units=ticks (typically 60/sec) */
-#endif
-
-#ifndef _TIME_T_
-#define _TIME_T_
-typedef long time_t; /* value = secs since epoch */
-#endif
-
-#ifndef _SIZE_T_
-#define _SIZE_T_
-typedef int size_t; /* ??? */
-#endif
-
-#ifndef _PTRDIFF_T_
-#define _PTRDIFF_T_
-typedef int ptrdiff_t; /* result of subtracting two pointers */
-#endif
-
-#ifndef _WCHAR_T_
-#define _WCHAR_T_
-typedef unsigned short wchar_t; /* big enough for biggest char set */
-#endif
-
-#endif /* !__sys_stdtypes_h */
diff --git a/mit-pthreads/machdep/hpux-9.03/time.h b/mit-pthreads/machdep/hpux-9.03/time.h
deleted file mode 100755
index 544905b0749..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/time.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/* $Header$ */
-
-#ifndef _SYS_TIME_INCLUDED
-#define _SYS_TIME_INCLUDED
-
-/* time.h: Definitions for time handling functions */
-
-#ifdef _KERNEL_BUILD
-#include "../h/stdsyms.h"
-#else /* ! _KERNEL_BUILD */
-#include <sys/stdsyms.h>
-#endif /* _KERNEL_BUILD */
-
-#include <sys/types.h>
-
-/* ANSI C time constants, types, and structures */
-
-#ifdef _INCLUDE__STDC__
-# define CLOCKS_PER_SEC 1000000
-
-# ifndef NULL
-# define NULL 0
-# endif
-
-# ifndef _CLOCK_T
-# define _CLOCK_T
- typedef unsigned long clock_t;
-# endif /* _CLOCK_T */
-
-# ifndef _TIME_T
-# define _TIME_T
- typedef long time_t;
-# endif /* _TIME_T */
-
-# ifndef _SIZE_T
-# define _SIZE_T
- typedef unsigned int size_t;
-# endif /* _SIZE_T */
-
- /* Structure used with gmtime(), localtime(), mktime(), strftime(). */
- struct tm {
- int tm_sec; /* second (0-61, allows for leap seconds) */
- int tm_min; /* minute (0-59) */
- int tm_hour; /* hour (0-23) */
- int tm_mday; /* day of the month (1-31) */
- int tm_mon; /* month (0-11) */
- int tm_year; /* years since 1900 */
- int tm_wday; /* day of the week (0-6) */
- int tm_yday; /* day of the year (0-365) */
- int tm_isdst; /* non-0 if daylight savings time is in effect */
- };
-#endif /* _INCLUDE__STDC__ */
-
-
-/* Additional types needed for HP-UX */
-
-#ifdef _INCLUDE_HPUX_SOURCE
-# ifndef _STRUCT_TIMEVAL
-# define _STRUCT_TIMEVAL
- /* Structure returned by gettimeofday(2) system call and others */
- struct timeval {
- unsigned long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
- };
-# endif /* _STRUCT_TIMEVAL */
-
- /* Structure used to represent timezones for gettimeofday(2) and others */
- struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
- };
-
- /* Structure defining a timer setting. */
- struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
- };
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-
-/* Function prototypes and external variable declarations */
-
-#ifndef _KERNEL
-#ifdef __cplusplus
- extern "C" {
-#endif /* __cplusplus */
-
-#ifdef _INCLUDE__STDC__
-# ifdef _PROTOTYPES
- extern double difftime(time_t, time_t);
- extern time_t mktime(struct tm *);
- extern time_t time(time_t *);
- extern char *ctime(const time_t *);
- extern struct tm *gmtime(const time_t *);
- extern struct tm *localtime(const time_t *);
- extern size_t strftime(char *, size_t, const char *, const struct tm *);
-# else /* not _PROTOTYPES */
- extern double difftime();
- extern time_t mktime();
- extern time_t time();
- extern char *ctime();
- extern struct tm *gmtime();
- extern struct tm *localtime();
- extern size_t strftime();
-# endif /* not _PROTOTYPES */
-
-# ifdef _CLASSIC_ANSI_TYPES
- extern long clock();
-# else /* not _CLASSIC_ANSI_TYPES */
-# ifdef _PROTOTYPES
- extern clock_t clock(void);
-# else /* not _PROTOTYPES */
- extern clock_t clock();
-# endif /* not _PROTOTYPES */
-# endif /* not _CLASSIC_ANSI_TYPES */
-#endif /* _INCLUDE__STDC__ */
-
-#ifdef _INCLUDE_POSIX_SOURCE
-# ifdef _PROTOTYPES
- extern void tzset(void);
-# else /* not _PROTOTYPES */
- extern void tzset();
-# endif /* not _PROTOTYPES */
-
- extern char *tzname[2];
-#endif /* _INCLUDE_POSIX_SOURCE */
-
-
-#ifdef _INCLUDE_XOPEN_SOURCE
-# ifdef _PROTOTYPES
- extern char *strptime(const char *, const char *, struct tm *);
-# else /* not _PROTOTYPES */
- extern char *strptime();
-# endif /* not _PROTOTYPES */
-
- extern long timezone;
- extern int daylight;
-#endif /* _INCLUDE_XOPEN_SOURCE */
-
-
-#ifdef _INCLUDE_HPUX_SOURCE
-# ifdef _PROTOTYPES
- extern struct tm *getdate(const char *);
- extern char *nl_asctime(struct tm *, char *, int);
- extern char *nl_ctime(long *, char *, int);
- extern char *nl_ascxtime(struct tm *, char *);
- extern char *nl_cxtime(long *, char *);
- extern int getitimer(int, struct itimerval *);
- extern int setitimer(int, const struct itimerval *, struct itimerval *);
- extern int gettimeofday(struct timeval *, struct timezone *);
- extern int settimeofday(const struct timeval *, const struct timezone *);
- extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
- extern int stime(const time_t *);
-# else /* not _PROTOTYPES */
- extern struct tm *getdate();
- extern char *nl_asctime();
- extern char *nl_ctime();
- extern char *nl_ascxtime();
- extern char *nl_cxtime();
- extern int getitimer();
- extern int setitimer();
- extern int gettimeofday();
- extern int settimeofday();
- extern int select();
- extern int stime();
-# endif /* not _PROTOTYPES */
- extern int getdate_err;
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-#ifdef __cplusplus
- }
-#endif /* __cplusplus */
-#endif /* not _KERNEL */
-
-
-/*
- * CLK_TCK is needed by the kernel, and also in the POSIX namespace.
- */
-
-#ifdef _INCLUDE_POSIX_SOURCE
-# ifndef CLK_TCK
-# ifdef __hp9000s300
-# define CLK_TCK 50
-# endif /* __hp9000s300 */
-# ifdef __hp9000s800
-# define CLK_TCK 100
-# endif /* __hp9000s800 */
-# endif /* CLK_TCK */
-#endif
-
-
-/* Additional HP-UX structures, macros, and constants */
-
-#ifdef _INCLUDE_HPUX_SOURCE
-
- /* Kernel instrumentation time value */
- struct ki_timeval {
- long tv_sec; /* seconds */
- long tv_nunit; /* and native units */
- };
-
- /* Kinds of daylight savings time */
-# define DST_NONE 0 /* not on dst */
-# define DST_USA 1 /* USA style dst */
-# define DST_AUST 2 /* Australian style dst */
-# define DST_WET 3 /* Western European dst */
-# define DST_MET 4 /* Middle European dst */
-# define DST_EET 5 /* Eastern European dst */
-
- /*
- * Operations on timevals.
- *
- * NB: timercmp does not work for >= or <=.
- */
-# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-# define timercmp(tvp, uvp, cmp) \
- ((tvp)->tv_sec cmp (uvp)->tv_sec || \
- (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
-# define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
-
- /* Names of the interval timers */
-# define ITIMER_REAL 0
-# define ITIMER_VIRTUAL 1
-# define ITIMER_PROF 2
-
-#endif /* _INCLUDE_HPUX_SOURCE */
-
-#endif /* _SYS_TIME_INCLUDED */
diff --git a/mit-pthreads/machdep/hpux-9.03/timers.h b/mit-pthreads/machdep/hpux-9.03/timers.h
deleted file mode 100755
index 3c4d057976a..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/timers.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/hpux-9.03/uio.h b/mit-pthreads/machdep/hpux-9.03/uio.h
deleted file mode 100755
index d1ec4c94f22..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/uio.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct HP-UX header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-#include <sys/cdefs.h>
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-__BEGIN_DECLS
-
-int readv __P_((int, const struct iovec *, int));
-int writev __P_((int, const struct iovec *, int));
-
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/machdep/hpux-9.03/wait.h b/mit-pthreads/machdep/hpux-9.03/wait.h
deleted file mode 100755
index bca70d9f1ec..00000000000
--- a/mit-pthreads/machdep/hpux-9.03/wait.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)wait.h 8.1 (Berkeley) 6/2/93
- * $Id$
- */
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#define _W_INT(i) (i)
-#define WCOREFLAG 0200
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-#endif
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/irix-5.2/__math.h b/mit-pthreads/machdep/irix-5.2/__math.h
deleted file mode 100755
index 229d5121524..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__math.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-extern char __infinity[];
-#define HUGE_VAL (*(double *) __infinity)
-
diff --git a/mit-pthreads/machdep/irix-5.2/__signal.h b/mit-pthreads/machdep/irix-5.2/__signal.h
deleted file mode 100755
index 87797da3198..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__signal.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <sys/signal.h>
-
-typedef int sig_atomic_t;
-
-#ifndef sigmask
-#define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1)))
-#endif
-#define sigword(n) (((unsigned int)((n) - 1))>>5)
-
-#define __SIGEMPTYSET { 0, 0, 0, 0 };
-#define __SIGFILLSET { 0xffffffff,0xffffffff,0xffffffff,0xffffffff };
-#define __SIGADDSET(s, n) ((s)->sigbits[sigword(n)] |= sigmask(n))
-#define __SIGDELSET(s, n) ((s)->sigbits[sigword(n)] &= ~sigmask(n))
-#define __SIGISMEMBER(s, n) (sigmask(n) & (s)->sigbits[sigword(n)])
-
diff --git a/mit-pthreads/machdep/irix-5.2/__stdio.h b/mit-pthreads/machdep/irix-5.2/__stdio.h
deleted file mode 100755
index bb4c14b32c6..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__stdio.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#if !defined(_SIZE_T) && !defined(_SIZE_T_)
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-typedef pthread_fpos_t fpos_t;
diff --git a/mit-pthreads/machdep/irix-5.2/__stdlib.h b/mit-pthreads/machdep/irix-5.2/__stdlib.h
deleted file mode 100755
index 2bec122c5f1..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__stdlib.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <sgidefs.h>
-
-#if !defined(_SIZE_T) && !defined(_SIZE_T_)
-#define _SIZE_T
-#if (_MIPS_SZLONG == 32)
-typedef unsigned int size_t;
-#endif
-#if (_MIPS_SZLONG == 64)
-typedef unsigned long size_t;
-#endif
-#endif
-
-#ifndef _WCHAR_T
-#define _WCHAR_T
-#if (_MIPS_SZLONG == 32)
-typedef long wchar_t;
-#endif
-#if (_MIPS_SZLONG == 64)
-typedef __int32_t wchar_t;
-#endif
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
diff --git a/mit-pthreads/machdep/irix-5.2/__string.h b/mit-pthreads/machdep/irix-5.2/__string.h
deleted file mode 100755
index 50261e73cfc..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__string.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#if !defined(_SIZE_T) && !defined(_SIZE_T_)
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
diff --git a/mit-pthreads/machdep/irix-5.2/__time.h b/mit-pthreads/machdep/irix-5.2/__time.h
deleted file mode 100755
index 51fb993b38d..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__time.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#if !defined(_SIZE_T) && !defined(_SIZE_T_)
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef pthread_clock_t clock_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef pthread_time_t time_t;
-#endif /* !_TIME_T */
-
-#define CLOCKS_PER_SEC 1000000
-
-#ifndef CLK_TCK
-#define CLK_TCK sysconf(3) /* clock ticks per second */
- /* 3 is _SC_CLK_TCK */
-#endif
diff --git a/mit-pthreads/machdep/irix-5.2/__unistd.h b/mit-pthreads/machdep/irix-5.2/__unistd.h
deleted file mode 100755
index 0d71d631a5b..00000000000
--- a/mit-pthreads/machdep/irix-5.2/__unistd.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <sys/types.h>
-#include <sys/unistd.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define ioctl_request_type int /* For fd.c */
diff --git a/mit-pthreads/machdep/irix-5.2/compat.h b/mit-pthreads/machdep/irix-5.2/compat.h
deleted file mode 100755
index 8fd504e504f..00000000000
--- a/mit-pthreads/machdep/irix-5.2/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description :
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/irix-5.2/dirent.h b/mit-pthreads/machdep/irix-5.2/dirent.h
deleted file mode 100755
index 79fe486951d..00000000000
--- a/mit-pthreads/machdep/irix-5.2/dirent.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _SYS_DIRENT_H
-#define _SYS_DIRENT_H
-
-#if !defined(_POSIX_SOURCE)
-#define MAXNAMLEN 255 /* maximum filename length */
-#define DIRBUF 4096 /* buffer size for fs-indep. dirs */
-#endif /* !defined(_POSIX_SOURCE) */
-
-#include <sys/types.h>
-
-struct dirent { /* data from readdir() */
- ino_t d_ino; /* inode number of entry */
- off_t d_off; /* offset of disk direntory entry */
- unsigned short d_reclen; /* length of this record */
- char d_name[MAXNAMLEN+1];/* name of file */
-};
-
-#define d_namlen d_reclen
-#define d_fileno d_ino
-
-#endif /* _SYS_DIRENT_H */
diff --git a/mit-pthreads/machdep/irix-5.2/socket.h b/mit-pthreads/machdep/irix-5.2/socket.h
deleted file mode 100755
index b08d3939802..00000000000
--- a/mit-pthreads/machdep/irix-5.2/socket.h
+++ /dev/null
@@ -1,304 +0,0 @@
-#ifndef __SYS_TPI_SOCKET_H__
-#ifndef __SYS_SOCKET_H__
-#define __SYS_SOCKET_H__
-/*
- * Copyright (c) 1982,1985, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- *
- * @(#)socket.h 7.1 (Berkeley) 6/4/86
- */
-#include <sys/cdefs.h>
-#include <sys/bsd_types.h>
-
-/*
- * Definitions related to sockets: types, address families, options.
- */
-
-/*
- * Types
- */
-#ifdef _STYPES_LATER /* old ABI */
-#define SOCK_STREAM 1 /* stream socket */
-#define SOCK_DGRAM 2 /* datagram socket */
-#define SOCK_RAW 3 /* raw-protocol interface */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequenced packet stream */
-#else /* !_STYPES_LATER, new ABI */
-
-#ifndef NC_TPI_CLTS
-#define NC_TPI_CLTS 1 /* must agree with netconfig.h */
-#define NC_TPI_COTS 2 /* must agree with netconfig.h */
-#define NC_TPI_COTS_ORD 3 /* must agree with netconfig.h */
-#define NC_TPI_RAW 4 /* must agree with netconfig.h */
-#endif /* !NC_TPI_CLTS */
-
-#define SOCK_DGRAM NC_TPI_CLTS /* datagram socket */
-#define SOCK_STREAM NC_TPI_COTS /* stream socket */
-#define SOCK_RAW NC_TPI_RAW /* raw-protocol interface */
-#define SOCK_RDM 5 /* reliably-delivered message */
-#define SOCK_SEQPACKET 6 /* sequenced packet stream */
-
-#ifdef _KERNEL
-#define IRIX4_SOCK_STREAM 1 /* stream socket */
-#define IRIX4_SOCK_DGRAM 2 /* datagram socket */
-#define IRIX4_SOCK_RAW 3 /* raw-protocol interface */
-#define IRIX4_SOCK_RDM 4 /* reliably-delivered message */
-#define IRIX4_SOCK_SEQPACKET 5 /* sequenced packet stream */
-#endif /* _KERNEL */
-#endif /* _STYPES_LATER */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-#define SO_REUSEPORT 0x0200 /* allow local address,port reuse */
-#define SO_ORDREL 0x0200 /* MIPS ABI - unimplemented */
-#define SO_IMASOCKET 0x0400 /* use libsocket (not TLI) semantics */
-#define SO_CHAMELEON 0x1000 /* (cipso) set label to 1st req rcvd */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_PROTOTYPE 0x1009 /* get protocol type (libsocket) */
-
-/*
- * Structure used for manipulating linger option.
- */
-struct linger {
- int l_onoff; /* option on/off */
- int l_linger; /* linger time */
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- * XTP really is not an address family, but is included here to take
- * up space, because other AF_ entries are numerically equal to their
- * PF_ counterparts.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_ISO 7 /* ISO protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* DEC Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_ROUTE 17 /* Internal Routing Protocol */
-#ifdef __sgi
-#define AF_RAW 18 /* Raw link layer interface */
-#else
-#define AF_LINK 18 /* Link layer interface */
-#endif
-#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
-
-/* MIPS ABI VALUES - unimplemented */
-#define AF_NIT 17 /* Network Interface Tap */
-#define AF_802 18 /* IEEE 802.2, also ISO 8802 */
-#define AF_OSI 19 /* umbrella for all families used */
-#define AF_X25 20 /* CCITT X.25 in particular */
-#define AF_OSINET 21 /* AFI = 47, IDI = 4 */
-#define AF_GOSIP 22 /* U.S. Government OSI */
-
-
-#define AF_SDL 23 /* SGI Data Link for DLPI */
-
-#define AF_MAX (AF_SDL+1)
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- u_short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- u_short sp_family; /* address family */
- u_short sp_protocol; /* protocol */
-};
-
-/*
- * An option specification consists of an opthdr, followed by the value of
- * the option. An options buffer contains one or more options. The len
- * field of opthdr specifies the length of the option value in bytes. This
- * length must be a multiple of sizeof(long) (use OPTLEN macro).
- */
-
-struct opthdr {
- long level; /* protocol level affected */
- long name; /* option to modify */
- long len; /* length of option value */
-};
-
-#define OPTLEN(x) ((((x) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))
-#define OPTVAL(opt) ((char *)(opt + 1))
-
-/*
- * the optdefault structure is used for internal tables of option default
- * values.
- */
-struct optdefault {
- int optname; /* the option */
- char *val; /* ptr to default value */
- int len; /* length of value */
-};
-
-struct tpisocket;
-struct T_optmgmt_req;
-struct msgb;
-
-/*
- * the opproc structure is used to build tables of options processing
- * functions for dooptions().
- */
-struct opproc {
- int level; /* options level this function handles */
- int (*func)(struct tpisocket *, struct T_optmgmt_req *,
- struct opthdr *, struct msgb *);
- /* the function */
-};
-
-/*
- * This structure is used to encode pseudo system calls
- */
-struct socksysreq {
- int args[7];
-};
-
-/*
- * This structure is used for adding new protocols to the list supported by
- * sockets.
- */
-
-struct socknewproto {
- int family; /* address family (AF_INET, etc.) */
- int type; /* protocol type (SOCK_STREAM, etc.) */
- int proto; /* per family proto number */
- dev_t dev; /* major/minor to use (must be a clone) */
- int flags; /* protosw flags */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_ISO AF_ISO
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_ROUTE AF_ROUTE
-#define PF_LINK AF_LINK
-#define PF_XTP pseudo_AF_XTP /* really just proto family, no AF */
-#ifdef __sgi
-#define PF_RAW AF_RAW
-#endif
-
-/* MIPS ABI VALUES - unimplemented */
-#define PF_NIT AF_NIT /* Network Interface Tap */
-#define PF_802 AF_802 /* IEEE 802.2, also ISO 8802 */
-#define PF_OSI AF_OSI /* umbrella for all families used */
-#define PF_X25 AF_X25 /* CCITT X.25 in particular */
-#define PF_OSINET AF_OSINET /* AFI = 47, IDI = 4 */
-#define PF_GOSIP AF_GOSIP /* U.S. Government OSI */
-
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-#define MSG_EOR 0x8 /* data completes record (OSI only) */
-#ifdef XTP
-#define MSG_BTAG 0x40 /* XTP packet with BTAG field */
-#define MSG_ETAG 0x80 /* XTP packet with ETAG field */
-#endif
-
-#define MSG_MAXIOVLEN 16
-
-__BEGIN_DECLS
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-int getsockname __P_((int, struct sockaddr *, int *));
-int getsockopt __P_((int, int, int, void *, int *));
-int listen __P_((int, int));
-ssize_t recv __P_((int, void *, size_t, int));
-ssize_t recvfrom __P_((int, void *, size_t, int, struct sockaddr *, int *));
-int recvmsg __P_((int, struct msghdr *, int));
-ssize_t send __P_((int, const void *, size_t, int));
-ssize_t sendto __P_((int, const void *, size_t, int,
- const struct sockaddr *, int));
-int sendmsg __P_((int, const struct msghdr *, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int shutdown __P_((int, int));
-int socket __P_((int, int, int));
-int socketpair __P_((int, int, int, int *));
-__END_DECLS
-
-#endif /* !__SYS_SOCKET_H__ */
-#endif /* !__SYS_TPI_SOCKET_H__ */
diff --git a/mit-pthreads/machdep/irix-5.2/timers.h b/mit-pthreads/machdep/irix-5.2/timers.h
deleted file mode 100755
index ffa24dc9a15..00000000000
--- a/mit-pthreads/machdep/irix-5.2/timers.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __SYS_TIMERS_H__
-#define __SYS_TIMERS_H__
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-#endif /* !__SYS_TIMERS_H__ */
diff --git a/mit-pthreads/machdep/irix-5.2/wait.h b/mit-pthreads/machdep/irix-5.2/wait.h
deleted file mode 100755
index c0a7e7113d8..00000000000
--- a/mit-pthreads/machdep/irix-5.2/wait.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- *
- * @(#)wait.h 7.4 (Berkeley) 1/27/88
- */
-#ifndef __SYS_WAIT_H__
-#define __SYS_WAIT_H__
-
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define WSTOPFLG 0177
-#define WIFSTOPPED(stat) ((_W_INT(stat)&0377)==_WSTOPPED&&((_W_INT(stat)>>8)&0377)!=0)
-#define WSTOPSIG(stat) ((_W_INT(stat)>>8)&0377)
-#define WIFSIGNALED(stat) ((_W_INT(stat)&0377)>0&&((_W_INT(stat)>>8)&0377)==0)
-#define WTERMSIG(stat) (_W_INT(stat)&0177)
-#define WIFEXITED(stat) ((_W_INT(stat)&0377)==0)
-#define WEXITSTATUS(stat) ((_W_INT(stat)>>8)&0377)
-#define WCOREDUMP(stat) (_W_INT(stat) & WCOREFLAG)
-
-/*
- * Option bits for the second argument of wait3. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 0100
-#define WUNTRACED 0004 /* for POSIX */
-
-#if !defined(_POSIX_SOURCE)
-
-/*
- * Structure of the information in the first word returned by both
- * wait and wait3. If w_stopval==_WSTOPPED, then the second structure
- * describes the information returned, else the first. See WUNTRACED below.
- */
-typedef union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#ifdef _MIPSEL
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#ifdef _MIPSEB
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#ifdef _MIPSEL
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#ifdef _MIPSEB
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-} wait_t;
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-
-
-#define WSTOPPED 0004 /* wait for processes stopped by signals */
-#endif /* !defined(_POSIX_SOURCE) */
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-__BEGIN_DECLS
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-
-#endif /* __SYS_WAIT_H__ */
diff --git a/mit-pthreads/machdep/linux-1.0/__math.h b/mit-pthreads/machdep/linux-1.0/__math.h
deleted file mode 100755
index 05c65d58321..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__math.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef HUGE_VAL
-#define HUGE_VAL DBL_MAX
-#endif
-
diff --git a/mit-pthreads/machdep/linux-1.0/__path.h b/mit-pthreads/machdep/linux-1.0/__path.h
deleted file mode 100755
index 9caeb7d3016..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/lib/zoneinfo"
-#define _PATH_TZFILE "/usr/lib/zoneinfo/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/linux-1.0/__signal.h b/mit-pthreads/machdep/linux-1.0/__signal.h
deleted file mode 100755
index 4cd671f155c..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__signal.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <features.h>
-#include <linux/signal.h>
-
-#ifndef SIGCLD
-#define SIGCLD SIGCHLD
-#endif
-
-typedef int sig_atomic_t;
-
-typedef __sighandler_t SignalHandler;
-
-#define SignalBad ((SignalHandler)-1)
-#define SignalDefault ((SignalHandler)0)
-#define SignalIgnore ((SignalHandler)1)
-
-#define __sigmask(sig) (1 << ((sig) - 1))
-#define sigmask __sigmask
-
-#define __SIGFILLSET 0xffffffff
-#define __SIGEMPTYSET 0
-#define __SIGADDSET(s,n) ((*s) |= (__sigmask(n)))
-#define __SIGDELSET(s,n) ((*s) &= ~(__sigmask(n)))
-#define __SIGISMEMBER(s,n) ((*s) & (__sigmask(n)))
-
diff --git a/mit-pthreads/machdep/linux-1.0/__stdio.h b/mit-pthreads/machdep/linux-1.0/__stdio.h
deleted file mode 100755
index eb7e904c34d..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__stdio.h
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-typedef pthread_fpos_t fpos_t;
diff --git a/mit-pthreads/machdep/linux-1.0/__stdlib.h b/mit-pthreads/machdep/linux-1.0/__stdlib.h
deleted file mode 100755
index eaa0bb988ee..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__stdlib.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <features.h>
-
-/* Get size_t, wchar_t and NULL from <stddef.h>. */
-#define __need_size_t
-#define __need_wchar_t
-#define __need_NULL
-#include <stddef.h>
-
-#define __need_Emath
-#include <errno.h>
-
-/* Get HUGE_VAL (returned by strtod on overflow) from <float.h>. */
-#define __need_HUGE_VAL
-#include <float.h>
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/__string.h b/mit-pthreads/machdep/linux-1.0/__string.h
deleted file mode 100755
index 8a5e09608e0..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__string.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard Linux string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/__time.h b/mit-pthreads/machdep/linux-1.0/__time.h
deleted file mode 100755
index a088268286e..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__time.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ==== __time.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : System specific time header.
- *
- * 1.00 94/11/07 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS___TIME_H_
-#define _SYS___TIME_H_
-
-#include <features.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *) 0)
-#endif
-#endif
-#endif
-
-#define CLOCKS_PER_SEC 100
-#define CLK_TCK 100
-
-extern long int timezone;
-extern int daylight;
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/__unistd.h b/mit-pthreads/machdep/linux-1.0/__unistd.h
deleted file mode 100755
index 0f15b7c4883..00000000000
--- a/mit-pthreads/machdep/linux-1.0/__unistd.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <features.h>
-
-/* POSIX Standard approved as IEEE Std 1003.1 as of August, 1988. */
-#define _POSIX_VERSION 199009L
-#define _POSIX2_C_BIND 1
-#define _POSIX2_C_DEV 1
-#define _POSIX2_SW_DEV 1
-
-#define __need_size_t
-#define ioctl_request_type int /* For fd.c */
-
-#include <posix_opt.h>
-#include <sys/types.h>
-#include <stddef.h>
-
-#endif
-
diff --git a/mit-pthreads/machdep/linux-1.0/cdefs.h b/mit-pthreads/machdep/linux-1.0/cdefs.h
deleted file mode 100755
index f9d5668cfe6..00000000000
--- a/mit-pthreads/machdep/linux-1.0/cdefs.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This is intended to eventually find /usr/include/sys/cdefs.h
- * if it's inside the ifdef then it won't work if this file is
- * found in the include files path more than once.
- *
- * include_next is a GNU C extension, we might eventually want
- * to have our own cdefs in here simply to avoid GNU C dependencies
- * (though there are already enough in the asm stuff anyways)
- * [gsstark:19950419.0307EST]
- */
-#include_next <sys/cdefs.h>
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#if !defined(__cplusplus)
-#define __CAN_DO_EXTERN_INLINE
-#endif
-
-#endif /* _PTHREAD_SYS_CDEFS_H_ */
diff --git a/mit-pthreads/machdep/linux-1.0/compat.h b/mit-pthreads/machdep/linux-1.0/compat.h
deleted file mode 100755
index 6edb992ac3d..00000000000
--- a/mit-pthreads/machdep/linux-1.0/compat.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#include <sys/types.h>
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/dirent.h b/mit-pthreads/machdep/linux-1.0/dirent.h
deleted file mode 100755
index 7f783a198e0..00000000000
--- a/mit-pthreads/machdep/linux-1.0/dirent.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#ifndef _SYS_DIRENT_H
-#define _SYS_DIRENT_H
-
-#include <sys/types.h>
-#include <linux/limits.h>
-
-struct dirent {
- long d_ino;
- off_t d_off;
- unsigned short d_reclen;
- char d_name[NAME_MAX+1];
-};
-
-#ifndef d_fileno
-#define d_fileno d_ino
-#endif
-
-#ifndef d_namlen
-#define d_namlen d_reclen
-#endif
-
-#ifndef MAXNAMLEN
-#define MAXNAMLEN NAME_MAX
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/errno.h b/mit-pthreads/machdep/linux-1.0/errno.h
deleted file mode 100755
index a94a56b0437..00000000000
--- a/mit-pthreads/machdep/linux-1.0/errno.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* ==== errno.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Errno is already broken up into data/prototyes.
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#include <linux/errno.h>
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/socket.h b/mit-pthreads/machdep/linux-1.0/socket.h
deleted file mode 100755
index cc4c0fd262e..00000000000
--- a/mit-pthreads/machdep/linux-1.0/socket.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* ==== socket.h.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Linux header file.
- */
-
-#ifndef _PTHREAD_SOCKET_H_
-#define _PTHREAD_SOCKET_H_
-
-/* #include <linux/socket.h> */
-#ifndef _LINUX_SOCKET_H
-#define _LINUX_SOCKET_H
-
-/* IP options */
-#define IP_TOS 1
-#define IPTOS_LOWDELAY 0x10
-#define IPTOS_THROUGHPUT 0x08
-#define IPTOS_RELIABILITY 0x04
-#define IP_TTL 2
-#ifndef IP_HDRINCL
-#define IP_HDRINCL 3
-#endif
-#ifdef V1_3_WILL_DO_THIS_FUNKY_STUFF
-#define IP_OPTIONS 4
-#endif
-
-#endif
-
-/* #include <asm/socket.h> arch-dependent defines */
-#include <linux/sockios.h> /* the SIOCxxx I/O controls */
-#include <pthread/posix.h>
-
-struct sockaddr {
- unsigned short sa_family; /* address family, AF_xxx */
- char sa_data[14]; /* 14 bytes of protocol address */
-};
-
-struct linger {
- int l_onoff; /* Linger active */
- int l_linger; /* How long to linger for */
-};
-
-struct msghdr
-{
- void * msg_name; /* Socket name */
- int msg_namelen; /* Length of name */
- struct iovec * msg_iov; /* Data blocks */
- int msg_iovlen; /* Number of blocks */
- void * msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */
- int msg_accrightslen;/* Length of rights list */
-};
-
-/* Socket types. */
-#define SOCK_STREAM 1 /* stream (connection) socket */
-#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
-#define SOCK_RAW 3 /* raw socket */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequential packet socket */
-#define SOCK_PACKET 10 /* linux specific way of */
- /* getting packets at the dev */
- /* level. For writing rarp and */
- /* other similar things on the */
- /* user level. */
-
-/* Supported address families. */
-#define AF_UNSPEC 0
-#define AF_UNIX 1 /* Unix domain sockets */
-#define AF_INET 2 /* Internet IP Protocol */
-#define AF_AX25 3 /* Amateur Radio AX.25 */
-#define AF_IPX 4 /* Novell IPX */
-#define AF_APPLETALK 5 /* Appletalk DDP */
-#define AF_NETROM 6 /* Amateur radio NetROM */
-#define AF_BRIDGE 7 /* Multiprotocol bridge */
-#define AF_AAL5 8 /* Reserved for Werner's ATM */
-#define AF_X25 9 /* Reserved for X.25 project */
-#define AF_INET6 10 /* IP version 6 */
-#define AF_MAX 12 /* For now.. */
-
-/* Protocol families, same as address families. */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_AX25 AF_AX25
-#define PF_IPX AF_IPX
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NETROM AF_NETROM
-#define PF_BRIDGE AF_BRIDGE
-#define PF_AAL5 AF_AAL5
-#define PF_X25 AF_X25
-#define PF_INET6 AF_INET6
-
-#define PF_MAX AF_MAX
-
-/* Maximum queue length specificable by listen. */
-#define SOMAXCONN 128
-
-/* Flags we can use with send/ and recv. */
-#define MSG_OOB 1
-#define MSG_PEEK 2
-#define MSG_DONTROUTE 4
-
-/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
-#define SOL_SOCKET 1
-#define SOL_IP 0
-#define SOL_IPX 256
-#define SOL_AX25 257
-#define SOL_ATALK 258
-#define SOL_NETROM 259
-#define SOL_TCP 6
-#define SOL_UDP 17
-
-/* For setsockoptions(2) */
-#define SO_DEBUG 1
-#define SO_REUSEADDR 2
-#define SO_TYPE 3
-#define SO_ERROR 4
-#define SO_DONTROUTE 5
-#define SO_BROADCAST 6
-#define SO_SNDBUF 7
-#define SO_RCVBUF 8
-#define SO_KEEPALIVE 9
-#define SO_OOBINLINE 10
-#define SO_NO_CHECK 11
-#define SO_PRIORITY 12
-#define SO_LINGER 13
-/* To add :#define SO_REUSEPORT 14 */
-
-
-#define IP_MULTICAST_IF 32
-#define IP_MULTICAST_TTL 33
-#define IP_MULTICAST_LOOP 34
-#define IP_ADD_MEMBERSHIP 35
-#define IP_DROP_MEMBERSHIP 36
-
-
-/* These need to appear somewhere around here */
-#define IP_DEFAULT_MULTICAST_TTL 1
-#define IP_DEFAULT_MULTICAST_LOOP 1
-#define IP_MAX_MEMBERSHIPS 20
-
-/* IPX options */
-#define IPX_TYPE 1
-
-/* TCP options - this way around because someone left a set in the c library includes */
-#define TCP_NODELAY 1
-#define TCP_MAXSEG 2
-
-/* The various priorities. */
-#define SOPRI_INTERACTIVE 0
-#define SOPRI_NORMAL 1
-#define SOPRI_BACKGROUND 2
-
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-
-int getsockopt __P_((int __s, int __level, int __optname,
- void *__optval, int *__optlen));
-int setsockopt __P_((int __s, int __level, int __optname,
- __const void *__optval, int optlen));
-int getsockname __P_((int __sockfd, struct sockaddr *__addr,
- int *__paddrlen));
-int getpeername __P_((int __sockfd, struct sockaddr *__peer,
- int *__paddrlen));
-ssize_t send __P_((int __sockfd, __const void *__buff, size_t __len, int __flags));
-ssize_t recv __P_((int __sockfd, void *__buff, size_t __len, int __flags));
-ssize_t sendto __P_((int __sockfd, __const void *__buff, size_t __len,
- int __flags, __const struct sockaddr *__to,
- int __tolen));
-ssize_t recvfrom __P_((int __sockfd, void *__buff, size_t __len,
- int __flags, struct sockaddr *__from,
- int *__fromlen));
-extern ssize_t sendmsg __P_((int __fd, __const struct msghdr *__message,
- int __flags));
-extern ssize_t recvmsg __P_((int __fd, struct msghdr *__message,
- int __flags));
-int shutdown __P_((int __sockfd, int __how));
-
-__END_DECLS
-
-#endif
-
-
-
-
diff --git a/mit-pthreads/machdep/linux-1.0/timers.h b/mit-pthreads/machdep/linux-1.0/timers.h
deleted file mode 100755
index 110cb27378c..00000000000
--- a/mit-pthreads/machdep/linux-1.0/timers.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <pthread/config.h>
-#include <sys/types.h>
-#include <time.h>
-
-#ifndef _OS_HAS_TIMESPEC
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-#endif
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/uio.h b/mit-pthreads/machdep/linux-1.0/uio.h
deleted file mode 100755
index 67af5bf76e0..00000000000
--- a/mit-pthreads/machdep/linux-1.0/uio.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Linux header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-#endif
diff --git a/mit-pthreads/machdep/linux-1.0/wait.h b/mit-pthreads/machdep/linux-1.0/wait.h
deleted file mode 100755
index bcc28c5ef58..00000000000
--- a/mit-pthreads/machdep/linux-1.0/wait.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $NetBSD: wait.h,v 1.7 1994/06/29 06:46:23 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- */
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait and extract the
- * relevant values. Union wait is no supported with pthreads.
- */
-#define __W_INT(i) (i)
-#define __WSTATUS(x) (__W_INT(x) & 0177)
-#define __WSTOPPED 0177 /* __WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (__WSTATUS(x) == __WSTOPPED)
-#define WSTOPSIG(x) (__W_INT(x) >> 8)
-#define WIFSIGNALED(x) (__WSTATUS(x) != __WSTOPPED && __WSTATUS(x) != 0)
-#define WTERMSIG(x) (__WSTATUS(x))
-#define WIFEXITED(x) (__WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (__W_INT(x) >> 8)
-
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (__W_INT(x) & WCOREFLAG)
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | __WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-
-/* Tokens for special values of the "pid" parameter to wait4. */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#define WSTOPPED __WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-__BEGIN_DECLS
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
diff --git a/mit-pthreads/machdep/linux-2.0/__math.h b/mit-pthreads/machdep/linux-2.0/__math.h
deleted file mode 100755
index 05c65d58321..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__math.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef HUGE_VAL
-#define HUGE_VAL DBL_MAX
-#endif
-
diff --git a/mit-pthreads/machdep/linux-2.0/__path.h b/mit-pthreads/machdep/linux-2.0/__path.h
deleted file mode 100755
index 9caeb7d3016..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/lib/zoneinfo"
-#define _PATH_TZFILE "/usr/lib/zoneinfo/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/linux-2.0/__signal.h b/mit-pthreads/machdep/linux-2.0/__signal.h
deleted file mode 100755
index 81136b8c14d..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__signal.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#include <features.h>
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-#define _NSIG 64 /* Biggest signal number + 1
- (including real-time signals). */
-# define NSIG _NSIG
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX (_NSIG-1)
-
-#ifndef SIGCLD
-#define SIGCLD SIGCHLD
-#endif
-
-
-/* Type of a signal handler. */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL ((__sighandler_t)0) /* default signal handling */
-#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
-#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
-
-typedef int sig_atomic_t;
-
-#define SignalBad ((SignalHandler)-1)
-#define SignalDefault ((SignalHandler)0)
-#define SignalIgnore ((SignalHandler)1)
-
-#include "bits/sigset.h"
-
-#define __SIGFILLSET {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
-#define __SIGEMPTYSET { 0,0,0,0,0,0,0,0 }
-#define __SIGADDSET(s,n) __sigaddset((s),(n))
-#define __SIGDELSET(s,n) __sigdelset((s),(n))
-#define __SIGISMEMBER(s,n) __sigismember((s),(n))
-
-
-struct sigaction {
- __sighandler_t sa_handler;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
- sigset_t sa_mask; /* mask last for extensibility */
-};
-
-/* Values for the HOW argument to `sigprocmask'. */
-#define SIG_BLOCK 0 /* Block signals. */
-#define SIG_UNBLOCK 1 /* Unblock signals. */
-#define SIG_SETMASK 2 /* Set the set of blocked signals. */
diff --git a/mit-pthreads/machdep/linux-2.0/__stdio.h b/mit-pthreads/machdep/linux-2.0/__stdio.h
deleted file mode 100755
index 38deb337038..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__stdio.h
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Hack for configuration with libgcc 2.2 */
-#ifndef pthread_fpos_t
-#define pthread_fpos_t long
-#endif
-
-typedef pthread_fpos_t fpos_t;
diff --git a/mit-pthreads/machdep/linux-2.0/__stdlib.h b/mit-pthreads/machdep/linux-2.0/__stdlib.h
deleted file mode 100755
index eaa0bb988ee..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__stdlib.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <features.h>
-
-/* Get size_t, wchar_t and NULL from <stddef.h>. */
-#define __need_size_t
-#define __need_wchar_t
-#define __need_NULL
-#include <stddef.h>
-
-#define __need_Emath
-#include <errno.h>
-
-/* Get HUGE_VAL (returned by strtod on overflow) from <float.h>. */
-#define __need_HUGE_VAL
-#include <float.h>
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/__string.h b/mit-pthreads/machdep/linux-2.0/__string.h
deleted file mode 100755
index 8a5e09608e0..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__string.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard Linux string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/__time.h b/mit-pthreads/machdep/linux-2.0/__time.h
deleted file mode 100755
index b86c153543a..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__time.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ==== __time.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : System specific time header.
- *
- * 1.00 94/11/07 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS___TIME_H_
-#define _SYS___TIME_H_
-
-#include <features.h>
-
-struct timespec
- {
- long int tv_sec; /* Seconds. */
- long int tv_nsec; /* Nanoseconds. */
- };
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *) 0)
-#endif
-#endif
-#endif
-
-#define CLOCKS_PER_SEC 100
-#define CLK_TCK 100
-
-extern long int timezone;
-extern int daylight;
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/__unistd.h b/mit-pthreads/machdep/linux-2.0/__unistd.h
deleted file mode 100755
index 444f070659a..00000000000
--- a/mit-pthreads/machdep/linux-2.0/__unistd.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <features.h>
-
-/* POSIX Standard approved as IEEE Std 1003.1 as of August, 1988. */
-#define _POSIX_VERSION 199009L
-#define _POSIX2_C_BIND 1
-#define _POSIX2_C_DEV 1
-#define _POSIX2_SW_DEV 1
-
-#define __need_size_t
-
-#include <sys/types.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-int chroot(const char *);
-int gethostname(char *, int);
-#ifdef __cplusplus
-}
-#endif
-#endif
-
diff --git a/mit-pthreads/machdep/linux-2.0/cdefs.h b/mit-pthreads/machdep/linux-2.0/cdefs.h
deleted file mode 100755
index 04f93a138c9..00000000000
--- a/mit-pthreads/machdep/linux-2.0/cdefs.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This is intended to eventually find /usr/include/sys/cdefs.h
- * if it's inside the ifdef then it won't work if this file is
- * found in the include files path more than once.
- *
- * include_next is a GNU C extension, we might eventually want
- * to have our own cdefs in here simply to avoid GNU C dependencies
- * (though there are already enough in the asm stuff anyways)
- * [gsstark:19950419.0307EST]
- */
-
-/* We are almost always included from features.h. */
-
-#ifndef _FEATURES_H
-#include <features.h>
-#endif
-
-#ifndef __BITS_SOCKET_H
-#define __BITS_SOCKET_H
-#endif
-
-#define __need_timespec
-
-#include_next <sys/cdefs.h>
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#if !defined(__cplusplus)
-#define __CAN_DO_EXTERN_INLINE
-#endif
-
-#endif /* _PTHREAD_SYS_CDEFS_H_ */
diff --git a/mit-pthreads/machdep/linux-2.0/compat.h b/mit-pthreads/machdep/linux-2.0/compat.h
deleted file mode 100755
index 6edb992ac3d..00000000000
--- a/mit-pthreads/machdep/linux-2.0/compat.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#include <sys/types.h>
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/dirent.h b/mit-pthreads/machdep/linux-2.0/dirent.h
deleted file mode 100755
index 7f783a198e0..00000000000
--- a/mit-pthreads/machdep/linux-2.0/dirent.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#ifndef _SYS_DIRENT_H
-#define _SYS_DIRENT_H
-
-#include <sys/types.h>
-#include <linux/limits.h>
-
-struct dirent {
- long d_ino;
- off_t d_off;
- unsigned short d_reclen;
- char d_name[NAME_MAX+1];
-};
-
-#ifndef d_fileno
-#define d_fileno d_ino
-#endif
-
-#ifndef d_namlen
-#define d_namlen d_reclen
-#endif
-
-#ifndef MAXNAMLEN
-#define MAXNAMLEN NAME_MAX
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/errno.h b/mit-pthreads/machdep/linux-2.0/errno.h
deleted file mode 100755
index a94a56b0437..00000000000
--- a/mit-pthreads/machdep/linux-2.0/errno.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* ==== errno.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Errno is already broken up into data/prototyes.
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#include <linux/errno.h>
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/extra/bits/local_lim.h b/mit-pthreads/machdep/linux-2.0/extra/bits/local_lim.h
deleted file mode 100644
index 1a319ccdfd4..00000000000
--- a/mit-pthreads/machdep/linux-2.0/extra/bits/local_lim.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Minimum guaranteed maximum values for system limits. Linux version.
-
-/* The kernel header pollutes the namespace with the NR_OPEN symbol.
- Remove this after including the header if necessary. */
-
-#ifndef NR_OPEN
-# define __undef_NR_OPEN
-#endif
-
-#include <linux/limits.h>
-
-#ifdef __undef_NR_OPEN
-# undef NR_OPEN
-# undef __undef_NR_OPEN
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/extra/bits/socket.h b/mit-pthreads/machdep/linux-2.0/extra/bits/socket.h
deleted file mode 100755
index 1814e189b64..00000000000
--- a/mit-pthreads/machdep/linux-2.0/extra/bits/socket.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/* ==== socket.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Linux header file.
- */
-
-#ifndef _PTHREAD_BITS_SOCKET_H_
-#define _PTHREAD_BITS_SOCKET_H_
-
-/* #include <linux/socket.h> */
-#ifndef _LINUX_SOCKET_H
-#define _LINUX_SOCKET_H
-
-/* IP options */
-#define IP_TOS 1
-#define IPTOS_LOWDELAY 0x10
-#define IPTOS_THROUGHPUT 0x08
-#define IPTOS_RELIABILITY 0x04
-#define IP_TTL 2
-#ifndef IP_HDRINCL
-#define IP_HDRINCL 3
-#endif
-#ifdef V1_3_WILL_DO_THIS_FUNKY_STUFF
-#define IP_OPTIONS 4
-#endif
-
-#endif
-
-/* Fixes to be able to configure with glibc 2.2 */
-typedef unsigned short int sa_family_t;
-#define __SOCKADDR_COMMON(sa_prefix) \
- sa_family_t sa_prefix##family
-#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))
-
-/* Type for length arguments in socket calls. */
-typedef unsigned int socklen_t;
-
-/* #include <asm/socket.h> arch-dependent defines */
-#include <linux/sockios.h> /* the SIOCxxx I/O controls */
-#include <pthread/posix.h>
-
-struct sockaddr {
- unsigned short sa_family; /* address family, AF_xxx */
- char sa_data[14]; /* 14 bytes of protocol address */
-};
-
-struct linger {
- int l_onoff; /* Linger active */
- int l_linger; /* How long to linger for */
-};
-
-struct msghdr
-{
- void * msg_name; /* Socket name */
- int msg_namelen; /* Length of name */
- struct iovec * msg_iov; /* Data blocks */
- int msg_iovlen; /* Number of blocks */
- void * msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */
- int msg_accrightslen;/* Length of rights list */
-};
-
-/* Socket types. */
-#define SOCK_STREAM 1 /* stream (connection) socket */
-#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
-#define SOCK_RAW 3 /* raw socket */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequential packet socket */
-#define SOCK_PACKET 10 /* linux specific way of */
- /* getting packets at the dev */
- /* level. For writing rarp and */
- /* other similar things on the */
- /* user level. */
-
-/* Supported address families. */
-#define AF_UNSPEC 0
-#define AF_UNIX 1 /* Unix domain sockets */
-#define AF_INET 2 /* Internet IP Protocol */
-#define AF_AX25 3 /* Amateur Radio AX.25 */
-#define AF_IPX 4 /* Novell IPX */
-#define AF_APPLETALK 5 /* Appletalk DDP */
-#define AF_NETROM 6 /* Amateur radio NetROM */
-#define AF_BRIDGE 7 /* Multiprotocol bridge */
-#define AF_AAL5 8 /* Reserved for Werner's ATM */
-#define AF_X25 9 /* Reserved for X.25 project */
-#define AF_INET6 10 /* IP version 6 */
-#define AF_MAX 12 /* For now.. */
-
-/* Protocol families, same as address families. */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_AX25 AF_AX25
-#define PF_IPX AF_IPX
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NETROM AF_NETROM
-#define PF_BRIDGE AF_BRIDGE
-#define PF_AAL5 AF_AAL5
-#define PF_X25 AF_X25
-#define PF_INET6 AF_INET6
-
-#define PF_MAX AF_MAX
-
-/* Maximum queue length specificable by listen. */
-#define SOMAXCONN 128
-
-/* Flags we can use with send/ and recv. */
-#define MSG_OOB 1
-#define MSG_PEEK 2
-#define MSG_DONTROUTE 4
-
-/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
-#define SOL_SOCKET 1
-#define SOL_IP 0
-#define SOL_IPX 256
-#define SOL_AX25 257
-#define SOL_ATALK 258
-#define SOL_NETROM 259
-#define SOL_TCP 6
-#define SOL_UDP 17
-
-/* For setsockoptions(2) */
-#define SO_DEBUG 1
-#define SO_REUSEADDR 2
-#define SO_TYPE 3
-#define SO_ERROR 4
-#define SO_DONTROUTE 5
-#define SO_BROADCAST 6
-#define SO_SNDBUF 7
-#define SO_RCVBUF 8
-#define SO_KEEPALIVE 9
-#define SO_OOBINLINE 10
-#define SO_NO_CHECK 11
-#define SO_PRIORITY 12
-#define SO_LINGER 13
-/* To add :#define SO_REUSEPORT 14 */
-
-
-#define IP_MULTICAST_IF 32
-#define IP_MULTICAST_TTL 33
-#define IP_MULTICAST_LOOP 34
-#define IP_ADD_MEMBERSHIP 35
-#define IP_DROP_MEMBERSHIP 36
-
-
-/* These need to appear somewhere around here */
-#define IP_DEFAULT_MULTICAST_TTL 1
-#define IP_DEFAULT_MULTICAST_LOOP 1
-#define IP_MAX_MEMBERSHIPS 20
-
-/* IPX options */
-#define IPX_TYPE 1
-
-/* TCP options - this way around because someone left a set in the c library includes */
-#define TCP_NODELAY 1
-#define TCP_MAXSEG 2
-
-/* The various priorities. */
-#define SOPRI_INTERACTIVE 0
-#define SOPRI_NORMAL 1
-#define SOPRI_BACKGROUND 2
-
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, socklen_t *));
-int bind __P_((int, const struct sockaddr *, socklen_t));
-int connect __P_((int, const struct sockaddr *, socklen_t));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-
-int getsockopt __P_((int __s, int __level, int __optname,
- void *__optval, socklen_t *__optlen));
-int setsockopt __P_((int __s, int __level, int __optname,
- __const void *__optval, socklen_t optlen));
-int getsockname __P_((int __sockfd, struct sockaddr *__addr,
- socklen_t *__paddrlen));
-int getpeername __P_((int __sockfd, struct sockaddr *__peer,
- socklen_t *__paddrlen));
-ssize_t send __P_((int __sockfd, __const void *__buff, size_t __len, int __flags));
-ssize_t recv __P_((int __sockfd, void *__buff, size_t __len, int __flags));
-ssize_t sendto __P_((int __sockfd, __const void *__buff, size_t __len,
- int __flags, __const struct sockaddr *__to,
- socklen_t __tolen));
-ssize_t recvfrom __P_((int __sockfd, void *__buff, size_t __len,
- int __flags, struct sockaddr *__from,
- socklen_t *__fromlen));
-extern ssize_t sendmsg __P_((int __fd, __const struct msghdr *__message,
- int __flags));
-extern ssize_t recvmsg __P_((int __fd, struct msghdr *__message,
- int __flags));
-int shutdown __P_((int __sockfd, int __how));
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/socket.h b/mit-pthreads/machdep/linux-2.0/socket.h
deleted file mode 100755
index 2a8a04f1903..00000000000
--- a/mit-pthreads/machdep/linux-2.0/socket.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* ==== socket.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Linux header file.
- */
-
-#ifndef _PTHREAD_SOCKET_H_
-#define _PTHREAD_SOCKET_H_
-
-#include "bits/socket.h"
-
-#endif
-
diff --git a/mit-pthreads/machdep/linux-2.0/timers.h b/mit-pthreads/machdep/linux-2.0/timers.h
deleted file mode 100755
index 110cb27378c..00000000000
--- a/mit-pthreads/machdep/linux-2.0/timers.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <pthread/config.h>
-#include <sys/types.h>
-#include <time.h>
-
-#ifndef _OS_HAS_TIMESPEC
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-#endif
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/uio.h b/mit-pthreads/machdep/linux-2.0/uio.h
deleted file mode 100755
index 67af5bf76e0..00000000000
--- a/mit-pthreads/machdep/linux-2.0/uio.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Linux header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-#endif
diff --git a/mit-pthreads/machdep/linux-2.0/wait.h b/mit-pthreads/machdep/linux-2.0/wait.h
deleted file mode 100755
index bcc28c5ef58..00000000000
--- a/mit-pthreads/machdep/linux-2.0/wait.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $NetBSD: wait.h,v 1.7 1994/06/29 06:46:23 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- */
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait and extract the
- * relevant values. Union wait is no supported with pthreads.
- */
-#define __W_INT(i) (i)
-#define __WSTATUS(x) (__W_INT(x) & 0177)
-#define __WSTOPPED 0177 /* __WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (__WSTATUS(x) == __WSTOPPED)
-#define WSTOPSIG(x) (__W_INT(x) >> 8)
-#define WIFSIGNALED(x) (__WSTATUS(x) != __WSTOPPED && __WSTATUS(x) != 0)
-#define WTERMSIG(x) (__WSTATUS(x))
-#define WIFEXITED(x) (__WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (__W_INT(x) >> 8)
-
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (__W_INT(x) & WCOREFLAG)
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | __WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-
-/* Tokens for special values of the "pid" parameter to wait4. */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#define WSTOPPED __WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-__BEGIN_DECLS
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
diff --git a/mit-pthreads/machdep/netbsd-0.9/dirent.h b/mit-pthreads/machdep/netbsd-0.9/dirent.h
deleted file mode 100755
index 5226443f86b..00000000000
--- a/mit-pthreads/machdep/netbsd-0.9/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.0/__math.h b/mit-pthreads/machdep/netbsd-1.0/__math.h
deleted file mode 100755
index dc009d822f4..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__math.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * ANSI/POSIX
- */
-extern char __infinity[];
-#define HUGE_VAL (*(double *) __infinity)
-
diff --git a/mit-pthreads/machdep/netbsd-1.0/__path.h b/mit-pthreads/machdep/netbsd-1.0/__path.h
deleted file mode 100755
index 432494daafa..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "/etc/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/netbsd-1.0/__signal.h b/mit-pthreads/machdep/netbsd-1.0/__signal.h
deleted file mode 100755
index 918955c9948..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__signal.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <sys/signal.h>
-
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) (*(s) |= 1 << ((n) - 1), 0)
-#define __SIGDELSET(s, n) (*(s) &= ~(1 << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ((*(s) & (1 << ((n) - 1))) != 0)
-
diff --git a/mit-pthreads/machdep/netbsd-1.0/__stdio.h b/mit-pthreads/machdep/netbsd-1.0/__stdio.h
deleted file mode 100755
index d60b9df7a54..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__stdio.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
diff --git a/mit-pthreads/machdep/netbsd-1.0/__stdlib.h b/mit-pthreads/machdep/netbsd-1.0/__stdlib.h
deleted file mode 100755
index 7b24491b892..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__stdlib.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#ifdef _BSD_WCHAR_T_
-typedef _BSD_WCHAR_T_ wchar_t;
-#undef _BSD_WCHAR_T_
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* _STDLIB_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.0/__string.h b/mit-pthreads/machdep/netbsd-1.0/__string.h
deleted file mode 100755
index 1ebee28e708..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__string.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-void strmode __P_((int, char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.0/__time.h b/mit-pthreads/machdep/netbsd-1.0/__time.h
deleted file mode 100755
index 16ea9d1f0dd..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_CLOCK_T_
-typedef _BSD_CLOCK_T_ clock_t;
-#undef _BSD_CLOCK_T_
-#endif
-
-#ifdef _BSD_TIME_T_
-typedef _BSD_TIME_T_ time_t;
-#undef _BSD_TIME_T_
-#endif
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#define CLOCKS_PER_SEC 100
-
-#if !defined(_ANSI_SOURCE)
-#define CLK_TCK 100
-#endif /* not ANSI */
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.0/__unistd.h b/mit-pthreads/machdep/netbsd-1.0/__unistd.h
deleted file mode 100755
index b4741ba6725..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/__unistd.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* compile-time symbolic constants */
-#define _POSIX_JOB_CONTROL /* implementation supports job control */
-
-#ifdef _NOT_AVAILABLE
-#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */
-#endif
-
-#define _POSIX_VERSION 198808L
-#define _POSIX2_VERSION 199212L
-
-/* execution-time symbolic constants */
- /* chown requires appropriate privileges */
-#define _POSIX_CHOWN_RESTRICTED 1
- /* too-long path components generate errors */
-#define _POSIX_NO_TRUNC 1
- /* may disable terminal special characters */
-#define _POSIX_VDISABLE ((unsigned char)'\377')
-
-/* configurable pathname variables */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_CHOWN_RESTRICTED 7
-#define _PC_NO_TRUNC 8
-#define _PC_VDISABLE 9
-
-/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-
-/* configurable system strings */
-#define _CS_PATH 1
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.0/compat.h b/mit-pthreads/machdep/netbsd-1.0/compat.h
deleted file mode 100755
index e7de318aa88..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.0/dirent.h b/mit-pthreads/machdep/netbsd-1.0/dirent.h
deleted file mode 100755
index 5226443f86b..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.0/errno.h b/mit-pthreads/machdep/netbsd-1.0/errno.h
deleted file mode 100755
index 3da61d692a3..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/errno.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $NetBSD: errno.h,v 1.8 1994/06/29 06:44:02 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.0/time.h b/mit-pthreads/machdep/netbsd-1.0/time.h
deleted file mode 100755
index f2cc61f8d75..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/time.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* $NetBSD: time.h,v 1.8 1994/06/29 06:45:44 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)time.h 8.1 (Berkeley) 6/2/93
- */
-
-#ifndef _SYS_TIME_H_
-#define _SYS_TIME_H_
-
-/*
- * Structure returned by gettimeofday(2) system call,
- * and used in other calls.
- */
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
-};
-
-/*
- * Structure defined by POSIX.4 to be like a timeval.
- */
-struct timespec {
- long tv_sec; /* seconds */
- long tv_nsec; /* and nanoseconds */
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-#define DST_NONE 0 /* not on dst */
-#define DST_USA 1 /* USA style dst */
-#define DST_AUST 2 /* Australian style dst */
-#define DST_WET 3 /* Western European dst */
-#define DST_MET 4 /* Middle European dst */
-#define DST_EET 5 /* Eastern European dst */
-#define DST_CAN 6 /* Canada */
-
-/* Operations on timevals. */
-#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
-#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-#define timercmp(tvp, uvp, cmp) \
- (((tvp)->tv_sec == (uvp)->tv_sec) ? \
- ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
- ((tvp)->tv_sec cmp (uvp)->tv_sec))
-
-/*
- * Names of the interval timers, and structure
- * defining a timer setting.
- */
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-
-/*
- * Getkerninfo clock information structure
- */
-struct clockinfo {
- int hz; /* clock frequency */
- int tick; /* micro-seconds per hz tick */
- int stathz; /* statistics clock frequency */
- int profhz; /* profiling clock frequency */
-};
-
-#include <time.h>
-
-#ifndef _POSIX_SOURCE
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int adjtime __P_((const struct timeval *, struct timeval *));
-int getitimer __P_((int, struct itimerval *));
-int gettimeofday __P_((struct timeval *, struct timezone *));
-int setitimer __P_((int, const struct itimerval *, struct itimerval *));
-int settimeofday __P_((const struct timeval *, const struct timezone *));
-int utimes __P_((const char *, const struct timeval *));
-__END_DECLS
-#endif /* !POSIX */
-
-#endif /* !_SYS_TIME_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.0/timers.h b/mit-pthreads/machdep/netbsd-1.0/timers.h
deleted file mode 100755
index f9768c68c8f..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.0/wait.h b/mit-pthreads/machdep/netbsd-1.0/wait.h
deleted file mode 100755
index c1cd876d052..00000000000
--- a/mit-pthreads/machdep/netbsd-1.0/wait.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* $NetBSD: wait.h,v 1.7 1994/06/29 06:46:23 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- */
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#include <machine/endian.h>
-
-/*
- * Deprecated:
- * Structure of the information in the status word returned by wait4.
- * If w_stopval==WSTOPPED, then the second structure describes
- * the information returned, else the first.
- */
-union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-};
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#ifndef KERNEL
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/__math.h b/mit-pthreads/machdep/netbsd-1.1/__math.h
deleted file mode 100755
index dc009d822f4..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__math.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * ANSI/POSIX
- */
-extern char __infinity[];
-#define HUGE_VAL (*(double *) __infinity)
-
diff --git a/mit-pthreads/machdep/netbsd-1.1/__path.h b/mit-pthreads/machdep/netbsd-1.1/__path.h
deleted file mode 100755
index be7f9f6c658..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * __path.h,v 1.1 1995/01/03 12:53:32 proven Exp
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "/etc/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/netbsd-1.1/__signal.h b/mit-pthreads/machdep/netbsd-1.1/__signal.h
deleted file mode 100755
index ea2979f2b4e..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__signal.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <sys/signal.h>
-
-__BEGIN_DECLS
-
-#if NSIG <= 32
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) (*(s) |= 1 << ((n) - 1), 0)
-#define __SIGDELSET(s, n) (*(s) &= ~(1 << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ((*(s) & (1 << ((n) - 1))) != 0)
-
-#else /* XXX Netbsd >= 1.3H */
-
-int sigaction __P_((int, const struct sigaction *, struct sigaction *)) __RENAME(__sigaction14);
-
-#define __SIGEMPTYSET { 0, 0, 0, 0}
-#define __SIGFILLSET { 0xffffffff, 0xffffffff, \
- 0xffffffff, 0xffffffff }
-#define __SIGMASK(n) (1 << (((n) - 1) & 31))
-#define __SIGWORD(n) (((n) - 1) >> 5)
-#define __SIGADDSET(s, n) ((s)->__bits[__SIGWORD(n)] |= __SIGMASK(n))
-#define __SIGDELSET(s, n) ((s)->__bits[__SIGWORD(n)] &= ~__SIGMASK(n))
-#define __SIGISMEMBER(s, n) (((s)->__bits[__SIGWORD(n)] & __SIGMASK(n)) != 0)
-
-#endif
-
-__END_DECLS
diff --git a/mit-pthreads/machdep/netbsd-1.1/__stdio.h b/mit-pthreads/machdep/netbsd-1.1/__stdio.h
deleted file mode 100755
index d60b9df7a54..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__stdio.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
diff --git a/mit-pthreads/machdep/netbsd-1.1/__stdlib.h b/mit-pthreads/machdep/netbsd-1.1/__stdlib.h
deleted file mode 100755
index 189bb5e8799..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__stdlib.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * __stdlib.h,v 1.1 1995/01/03 12:53:34 proven Exp
- */
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#ifdef _BSD_WCHAR_T_
-typedef _BSD_WCHAR_T_ wchar_t;
-#undef _BSD_WCHAR_T_
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* _STDLIB_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.1/__string.h b/mit-pthreads/machdep/netbsd-1.1/__string.h
deleted file mode 100755
index 1ebee28e708..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__string.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-void strmode __P_((int, char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/__time.h b/mit-pthreads/machdep/netbsd-1.1/__time.h
deleted file mode 100755
index 27ceb815852..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * __time.h,v 1.1 1994/12/13 07:18:55 proven Exp
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_CLOCK_T_
-typedef _BSD_CLOCK_T_ clock_t;
-#undef _BSD_CLOCK_T_
-#endif
-
-#ifdef _BSD_TIME_T_
-typedef _BSD_TIME_T_ time_t;
-#undef _BSD_TIME_T_
-#endif
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#define CLOCKS_PER_SEC 100
-
-#if !defined(_ANSI_SOURCE)
-#define CLK_TCK 100
-#endif /* not ANSI */
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.1/__unistd.h b/mit-pthreads/machdep/netbsd-1.1/__unistd.h
deleted file mode 100755
index cea3165c229..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/__unistd.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * __unistd.h,v 1.1 1995/01/03 12:53:35 proven Exp
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* compile-time symbolic constants */
-#define _POSIX_JOB_CONTROL /* implementation supports job control */
-
-#ifdef _NOT_AVAILABLE
-#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */
-#endif
-
-#define _POSIX_VERSION 198808L
-#define _POSIX2_VERSION 199212L
-
-/* execution-time symbolic constants */
- /* chown requires appropriate privileges */
-#define _POSIX_CHOWN_RESTRICTED 1
- /* too-long path components generate errors */
-#define _POSIX_NO_TRUNC 1
- /* may disable terminal special characters */
-#define _POSIX_VDISABLE ((unsigned char)'\377')
-
-/* configurable pathname variables */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_CHOWN_RESTRICTED 7
-#define _PC_NO_TRUNC 8
-#define _PC_VDISABLE 9
-
-/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-
-/* configurable system strings */
-#define _CS_PATH 1
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/compat.h b/mit-pthreads/machdep/netbsd-1.1/compat.h
deleted file mode 100755
index f843795cc0a..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * compat.h,v 1.50 1994/08/08 03:44:05 proven Exp
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/dirent.h b/mit-pthreads/machdep/netbsd-1.1/dirent.h
deleted file mode 100755
index cf004a274d6..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/dirent.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* $NetBSD: dirent.h,v 1.12 1996/04/09 20:55:25 cgd Exp $ */
-
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 8.3 (Berkeley) 8/10/94
- */
-
-/*
- * The dirent structure defines the format of directory entries returned by
- * the getdirentries(2) system call.
- *
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_int32_t d_fileno; /* file number of entry */
- u_int16_t d_reclen; /* length of this record */
- u_int8_t d_type; /* file type, see below */
- u_int8_t d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#ifdef PTHREAD_KERNEL
-#define d_ino d_fileno
-#endif
-
-/*
- * File types
- */
-#define DT_UNKNOWN 0
-#define DT_FIFO 1
-#define DT_CHR 2
-#define DT_DIR 4
-#define DT_BLK 6
-#define DT_REG 8
-#define DT_LNK 10
-#define DT_SOCK 12
-#define DT_WHT 14
-
-/*
- * Convert between stat structure types and directory types.
- */
-#define IFTODT(mode) (((mode) & 0170000) >> 12)
-#define DTTOIF(dirtype) ((dirtype) << 12)
-
-#if defined(_KERNEL)
-/*
- * The DIRENT_SIZE macro gives the minimum record length which will hold
- * the directory entry. This requires the amount of space in struct dirent
- * without the d_name field, plus enough space for the name with a terminating
- * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
- */
-#define DIRENT_SIZE(dp) \
- ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
-
-#endif /* !_KERNEL */
diff --git a/mit-pthreads/machdep/netbsd-1.1/errno.h b/mit-pthreads/machdep/netbsd-1.1/errno.h
deleted file mode 100755
index c313b578c5a..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/errno.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* $NetBSD: errno.h,v 1.10 1996/01/20 01:33:53 jtc Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _KERNEL
-extern int errno; /* global error number */
-
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-extern int sys_nerr;
-extern const char *const sys_errlist[];
-#endif
-#endif
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#ifdef _KERNEL
-/* pseudo-errors returned inside kernel to modify return to process */
-#define ERESTART -1 /* restart syscall */
-#define EJUSTRETURN -2 /* don't modify regs, just return */
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/time.h b/mit-pthreads/machdep/netbsd-1.1/time.h
deleted file mode 100755
index a701db9c62e..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/time.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* $NetBSD: time.h,v 1.17 1996/02/01 00:10:36 jtc Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)time.h 8.2 (Berkeley) 7/10/94
- */
-
-#ifndef _SYS_TIME_H_
-#define _SYS_TIME_H_
-
-#include <sys/types.h>
-
-/*
- * Structure returned by gettimeofday(2) system call,
- * and used in other calls.
- */
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
-};
-
-/*
- * Structure defined by POSIX.1b to be like a timeval.
- */
-struct timespec {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* and nanoseconds */
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-#define DST_NONE 0 /* not on dst */
-#define DST_USA 1 /* USA style dst */
-#define DST_AUST 2 /* Australian style dst */
-#define DST_WET 3 /* Western European dst */
-#define DST_MET 4 /* Middle European dst */
-#define DST_EET 5 /* Eastern European dst */
-#define DST_CAN 6 /* Canada */
-
-/* Operations on timevals. */
-#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
-#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-#define timercmp(tvp, uvp, cmp) \
- (((tvp)->tv_sec == (uvp)->tv_sec) ? \
- ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
- ((tvp)->tv_sec cmp (uvp)->tv_sec))
-#define timeradd(tvp, uvp, vvp) \
- do { \
- (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
- (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
- if ((vvp)->tv_usec >= 1000000) { \
- (vvp)->tv_sec++; \
- (vvp)->tv_usec -= 1000000; \
- } \
- } while (0)
-#define timersub(tvp, uvp, vvp) \
- do { \
- (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
- (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
- if ((vvp)->tv_usec < 0) { \
- (vvp)->tv_sec--; \
- (vvp)->tv_usec += 1000000; \
- } \
- } while (0)
-
-/*
- * Names of the interval timers, and structure
- * defining a timer setting.
- */
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-
-/*
- * Getkerninfo clock information structure
- */
-struct clockinfo {
- int hz; /* clock frequency */
- int tick; /* micro-seconds per hz tick */
- int tickadj; /* clock skew rate for adjtime() */
- int stathz; /* statistics clock frequency */
- int profhz; /* profiling clock frequency */
-};
-
-#ifdef _KERNEL
-int itimerfix __P_((struct timeval *tv));
-int itimerdecr __P_((struct itimerval *itp, int usec));
-void microtime __P_((struct timeval *tv));
-#else /* !_KERNEL */
-#include <time.h>
-
-#ifndef _POSIX_SOURCE
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int adjtime __P_((const struct timeval *, struct timeval *));
-int getitimer __P_((int, struct itimerval *));
-int gettimeofday __P_((struct timeval *, struct timezone *));
-int setitimer __P_((int, const struct itimerval *, struct itimerval *));
-int settimeofday __P_((const struct timeval *, const struct timezone *));
-int utimes __P_((const char *, const struct timeval *));
-__END_DECLS
-#endif /* !POSIX */
-
-#endif /* !_KERNEL */
-
-#endif /* !_SYS_TIME_H_ */
diff --git a/mit-pthreads/machdep/netbsd-1.1/timers.h b/mit-pthreads/machdep/netbsd-1.1/timers.h
deleted file mode 100755
index b603b78e6b2..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * timers.h,v 1.50 1994/08/08 03:44:09 proven Exp
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-#endif
diff --git a/mit-pthreads/machdep/netbsd-1.1/wait.h b/mit-pthreads/machdep/netbsd-1.1/wait.h
deleted file mode 100755
index 0a1e9285e56..00000000000
--- a/mit-pthreads/machdep/netbsd-1.1/wait.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* $NetBSD: wait.h,v 1.11 1996/04/09 20:55:51 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.2 (Berkeley) 7/10/94
- */
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* don't hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#include <machine/endian.h>
-
-/*
- * Deprecated:
- * Structure of the information in the status word returned by wait4.
- * If w_stopval==WSTOPPED, then the second structure describes
- * the information returned, else the first.
- */
-union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-};
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#ifndef _KERNEL
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
-#endif
-
-#endif /* !_SYS_WAIT_H_ */
diff --git a/mit-pthreads/machdep/openbsd-2.0/__math.h b/mit-pthreads/machdep/openbsd-2.0/__math.h
deleted file mode 100755
index 27ed0f2575d..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__math.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * ANSI/POSIX
- */
-extern char __infinity[];
-#define HUGE_VAL (*(double *) __infinity)
-
diff --git a/mit-pthreads/machdep/openbsd-2.0/__path.h b/mit-pthreads/machdep/openbsd-2.0/__path.h
deleted file mode 100755
index 432494daafa..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__path.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "/etc/localtime"
-
-#endif /* !_SYS__PATH_H_ */
-
diff --git a/mit-pthreads/machdep/openbsd-2.0/__signal.h b/mit-pthreads/machdep/openbsd-2.0/__signal.h
deleted file mode 100755
index 918955c9948..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__signal.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <sys/signal.h>
-
-#define __SIGEMPTYSET 0
-#define __SIGFILLSET 0xffffffff
-#define __SIGADDSET(s, n) (*(s) |= 1 << ((n) - 1), 0)
-#define __SIGDELSET(s, n) (*(s) &= ~(1 << ((n) - 1)), 0)
-#define __SIGISMEMBER(s, n) ((*(s) & (1 << ((n) - 1))) != 0)
-
diff --git a/mit-pthreads/machdep/openbsd-2.0/__stdio.h b/mit-pthreads/machdep/openbsd-2.0/__stdio.h
deleted file mode 100755
index d60b9df7a54..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__stdio.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-typedef pthread_fpos_t fpos_t; /* Must match off_t <sys/types.h> */
diff --git a/mit-pthreads/machdep/openbsd-2.0/__stdlib.h b/mit-pthreads/machdep/openbsd-2.0/__stdlib.h
deleted file mode 100755
index 5ee2b8ed3d9..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__stdlib.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <machine/ansi.h>
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#ifdef _BSD_WCHAR_T_
-typedef _BSD_WCHAR_T_ wchar_t;
-#ifdef _BSD_RUNE_T_
-typedef _BSD_RUNE_T_ rune_t;
-#undef _BSD_RUNE_T_
-#else
-typedef _BSD_WCHAR_T_ rune_t;
-#endif
-#undef _BSD_WCHAR_T_
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* _STDLIB_H_ */
diff --git a/mit-pthreads/machdep/openbsd-2.0/__string.h b/mit-pthreads/machdep/openbsd-2.0/__string.h
deleted file mode 100755
index 93d4fcf9dd2..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__string.h
+++ /dev/null
@@ -1,21 +0,0 @@
-
-#include <machine/ansi.h>
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-void strmode __P_((int, char *));
-char *strsep __P_((char **, const char *));
-__END_DECLS
-#endif
-
diff --git a/mit-pthreads/machdep/openbsd-2.0/__time.h b/mit-pthreads/machdep/openbsd-2.0/__time.h
deleted file mode 100755
index 5c4b722bc3c..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__time.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <machine/ansi.h>
-#include <machine/limits.h>
-
-#ifdef _BSD_CLOCK_T_
-typedef _BSD_CLOCK_T_ clock_t;
-#undef _BSD_CLOCK_T_
-#endif
-
-#ifdef _BSD_TIME_T_
-typedef _BSD_TIME_T_ time_t;
-#undef _BSD_TIME_T_
-#endif
-
-#ifdef _BSD_SIZE_T_
-typedef _BSD_SIZE_T_ size_t;
-#undef _BSD_SIZE_T_
-#endif
-
-#define CLOCKS_PER_SEC 100
-
-#if !defined(CLK_TCK)
-#define CLK_TCK 100
-#endif /* not CLK_TCK */
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/openbsd-2.0/__unistd.h b/mit-pthreads/machdep/openbsd-2.0/__unistd.h
deleted file mode 100755
index 41244522461..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/__unistd.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define ioctl_request_type unsigned long /* For fd.c */
-
-/* compile-time symbolic constants */
-#define _POSIX_JOB_CONTROL /* implementation supports job control */
-
-#ifdef _NOT_AVAILABLE
-#define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */
-#endif
-
-#define _POSIX_VERSION 198808L
-#define _POSIX2_VERSION 199212L
-
-/* execution-time symbolic constants */
- /* chown requires appropriate privileges */
-#define _POSIX_CHOWN_RESTRICTED 1
- /* too-long path components generate errors */
-#define _POSIX_NO_TRUNC 1
- /* may disable terminal special characters */
-/* #define _POSIX_VDISABLE 0xff */
-
-/* configurable pathname variables */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_CHOWN_RESTRICTED 7
-#define _PC_NO_TRUNC 8
-#define _PC_VDISABLE 9
-
-/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-
-/* configurable system strings */
-#define _CS_PATH 1
-
-#endif
diff --git a/mit-pthreads/machdep/openbsd-2.0/compat.h b/mit-pthreads/machdep/openbsd-2.0/compat.h
deleted file mode 100755
index e7de318aa88..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/compat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : COmpat header to make socket code compile.
- *
- * 1.00 94/08/01 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#endif
diff --git a/mit-pthreads/machdep/openbsd-2.0/dirent.h b/mit-pthreads/machdep/openbsd-2.0/dirent.h
deleted file mode 100755
index 5226443f86b..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno /* backward compatibility */
-
-/* definitions for library routines operating on directories. */
-#define DIRBLKSIZ 1024
-
-#endif /* !_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/openbsd-2.0/errno.h b/mit-pthreads/machdep/openbsd-2.0/errno.h
deleted file mode 100755
index 3da61d692a3..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/errno.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $NetBSD: errno.h,v 1.8 1994/06/29 06:44:02 cgd Exp $ */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)errno.h 8.5 (Berkeley) 1/21/94
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#endif
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
-#define ETXTBSY 26 /* Text file busy */
-#endif
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-
-/* non-blocking and interrupt i/o */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Operation timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
-#define ENAMETOOLONG 63 /* File name too long */
-
-/* should be rearranged */
-#ifndef _POSIX_SOURCE
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
-#define ENOTEMPTY 66 /* Directory not empty */
-
-/* quotas & mush */
-#ifndef _POSIX_SOURCE
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
-
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define EFTYPE 79 /* Inappropriate file type or format */
-#define EAUTH 80 /* Authentication error */
-#define ENEEDAUTH 81 /* Need authenticator */
-#define ELAST 81 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
-
-#endif
diff --git a/mit-pthreads/machdep/openbsd-2.0/timers.h b/mit-pthreads/machdep/openbsd-2.0/timers.h
deleted file mode 100755
index f9768c68c8f..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/timers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/time.h>
-
-#endif
diff --git a/mit-pthreads/machdep/openbsd-2.0/wait.h b/mit-pthreads/machdep/openbsd-2.0/wait.h
deleted file mode 100755
index 7861e3fa180..00000000000
--- a/mit-pthreads/machdep/openbsd-2.0/wait.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)wait.h 8.1 (Berkeley) 6/2/93
- * $Id$
- */
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-/*
- * This file holds definitions relevent to the wait4 system call
- * and the alternate interfaces that use it (wait, wait3, waitpid).
- */
-
-/*
- * Macros to test the exit status returned by wait
- * and extract the relevant values.
- */
-#ifdef _POSIX_SOURCE
-#define _W_INT(i) (i)
-#else
-#define _W_INT(w) (*(int *)&(w)) /* convert union wait to int */
-#define WCOREFLAG 0200
-#endif
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-#ifndef _POSIX_SOURCE
-#define WCOREDUMP(x) (_W_INT(x) & WCOREFLAG)
-
-#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
-#define W_STOPCODE(sig) ((sig) << 8 | _WSTOPPED)
-#endif
-
-/*
- * Option bits for the third argument of wait4. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-#ifndef _POSIX_SOURCE
-/* POSIX extensions and 4.2/4.3 compatability: */
-
-/*
- * Tokens for special values of the "pid" parameter to wait4.
- */
-#define WAIT_ANY (-1) /* any process */
-#define WAIT_MYPGRP 0 /* any process in my process group */
-
-#include <machine/endian.h>
-
-/*
- * Deprecated:
- * Structure of the information in the status word returned by wait4.
- * If w_stopval==WSTOPPED, then the second structure describes
- * the information returned, else the first.
- */
-union wait {
- int w_status; /* used in syscall */
- /*
- * Terminated process status.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Termsig:7, /* termination signal */
- w_Coredump:1, /* core dump indicator */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Retcode:8, /* exit code if w_termsig==0 */
- w_Coredump:1, /* core dump indicator */
- w_Termsig:7; /* termination signal */
-#endif
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#if BYTE_ORDER == LITTLE_ENDIAN
- unsigned int w_Stopval:8, /* == W_STOPPED if stopped */
- w_Stopsig:8, /* signal that stopped us */
- w_Filler:16; /* upper bits filler */
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- unsigned int w_Filler:16, /* upper bits filler */
- w_Stopsig:8, /* signal that stopped us */
- w_Stopval:8; /* == W_STOPPED if stopped */
-#endif
- } w_S;
-};
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-
-#define WSTOPPED _WSTOPPED
-#endif /* _POSIX_SOURCE */
-
-#ifndef KERNEL
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-struct rusage; /* forward declaration */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-#ifndef _POSIX_SOURCE
-pid_t wait3 __P_((int *, int, void *));
-pid_t wait4 __P_((pid_t, int *, int, void *));
-#endif
-__END_DECLS
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-alpha-osf1.h b/mit-pthreads/machdep/posix-alpha-osf1.h
deleted file mode 100644
index 1d8bb6c5c4b..00000000000
--- a/mit-pthreads/machdep/posix-alpha-osf1.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#define __WAIT_STATUS int *
-#include <pthread/types.h>
-
-#endif
diff --git a/mit-pthreads/machdep/posix-bsdi-1.1.h b/mit-pthreads/machdep/posix-bsdi-1.1.h
deleted file mode 100644
index 4c56ea93a3b..00000000000
--- a/mit-pthreads/machdep/posix-bsdi-1.1.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __NORETURN
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
-
diff --git a/mit-pthreads/machdep/posix-bsdi-2.0.h b/mit-pthreads/machdep/posix-bsdi-2.0.h
deleted file mode 100644
index 4c56ea93a3b..00000000000
--- a/mit-pthreads/machdep/posix-bsdi-2.0.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __NORETURN
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
-
diff --git a/mit-pthreads/machdep/posix-freebsd-1.1.h b/mit-pthreads/machdep/posix-freebsd-1.1.h
deleted file mode 100644
index e1a00e9efd1..00000000000
--- a/mit-pthreads/machdep/posix-freebsd-1.1.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __NORETURN
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-freebsd-2.0.h b/mit-pthreads/machdep/posix-freebsd-2.0.h
deleted file mode 100644
index 7bad77aba02..00000000000
--- a/mit-pthreads/machdep/posix-freebsd-2.0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-hpux-10.20.h b/mit-pthreads/machdep/posix-hpux-10.20.h
deleted file mode 100644
index c7ecb429e79..00000000000
--- a/mit-pthreads/machdep/posix-hpux-10.20.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
-
diff --git a/mit-pthreads/machdep/posix-hpux-9.03.h b/mit-pthreads/machdep/posix-hpux-9.03.h
deleted file mode 100644
index c7ecb429e79..00000000000
--- a/mit-pthreads/machdep/posix-hpux-9.03.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
-
diff --git a/mit-pthreads/machdep/posix-i386-sco-3.2v5.h b/mit-pthreads/machdep/posix-i386-sco-3.2v5.h
deleted file mode 100644
index ab91311612d..00000000000
--- a/mit-pthreads/machdep/posix-i386-sco-3.2v5.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * posix-freebsd-2.0.h,v 1.1 1995/03/01 01:21:30 proven Exp
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-irix-5.2.h b/mit-pthreads/machdep/posix-irix-5.2.h
deleted file mode 100644
index d387bbbbf69..00000000000
--- a/mit-pthreads/machdep/posix-irix-5.2.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an IRIX-5.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 95/06/01 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-linux-1.0.h b/mit-pthreads/machdep/posix-linux-1.0.h
deleted file mode 100644
index 7f665d6b44a..00000000000
--- a/mit-pthreads/machdep/posix-linux-1.0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Convert a Linux-1.0 system to a more or less POSIX system.
- * Mostly POSIX already
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __INLINE extern inline
-/*
- * OK now do stuff to make the code compile.
- * Every OS has its own prototypes for each function
- */
-#ifdef malloc
-#undef malloc
-#endif
-
-#ifdef free
-#undef free
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-linux-2.0.h b/mit-pthreads/machdep/posix-linux-2.0.h
deleted file mode 100644
index 7f665d6b44a..00000000000
--- a/mit-pthreads/machdep/posix-linux-2.0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Convert a Linux-1.0 system to a more or less POSIX system.
- * Mostly POSIX already
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __INLINE extern inline
-/*
- * OK now do stuff to make the code compile.
- * Every OS has its own prototypes for each function
- */
-#ifdef malloc
-#undef malloc
-#endif
-
-#ifdef free
-#undef free
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-netbsd-0.9.h b/mit-pthreads/machdep/posix-netbsd-0.9.h
deleted file mode 100644
index 00ff2efa327..00000000000
--- a/mit-pthreads/machdep/posix-netbsd-0.9.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#define __NORETURN
-
-#endif
diff --git a/mit-pthreads/machdep/posix-netbsd-1.0.h b/mit-pthreads/machdep/posix-netbsd-1.0.h
deleted file mode 100644
index 7bad77aba02..00000000000
--- a/mit-pthreads/machdep/posix-netbsd-1.0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-netbsd-1.1.h b/mit-pthreads/machdep/posix-netbsd-1.1.h
deleted file mode 100644
index f4ff1dfae05..00000000000
--- a/mit-pthreads/machdep/posix-netbsd-1.1.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * posix-netbsd-1.0.h,v 1.53 1995/02/17 03:41:34 proven Exp
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-openbsd-2.0.h b/mit-pthreads/machdep/posix-openbsd-2.0.h
deleted file mode 100644
index 7bad77aba02..00000000000
--- a/mit-pthreads/machdep/posix-openbsd-2.0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * $Id$
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-romp-bsd.h b/mit-pthreads/machdep/posix-romp-bsd.h
deleted file mode 100644
index 7825622b064..00000000000
--- a/mit-pthreads/machdep/posix-romp-bsd.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert a system to a more or less POSIX system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#ifndef O_NONBLOCK
-#ifdef FNDELAY
-#define O_NONBLOCK FNDELAY
-#endif
-#endif
-
-#ifndef O_ACCMODE
-#define O_ACCMODE (O_RDONLY|O_RDWR|O_WRONLY)
-#endif
-
-#ifndef S_ISREG
-#define S_ISREG(x) ((x & S_IFMT) == S_IFREG)
-#endif
-
-#ifndef ENOSYS
-#define ENOSYS EINVAL
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
diff --git a/mit-pthreads/machdep/posix-sco-3.2v5.h b/mit-pthreads/machdep/posix-sco-3.2v5.h
deleted file mode 100644
index ab91311612d..00000000000
--- a/mit-pthreads/machdep/posix-sco-3.2v5.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * posix-freebsd-2.0.h,v 1.1 1995/03/01 01:21:30 proven Exp
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* More stuff for compiling */
-#if defined(__GNUC__)
-#define __INLINE extern inline
-#else
-#define __INLINE static
-#endif
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-sunos-4.1.3.h b/mit-pthreads/machdep/posix-sunos-4.1.3.h
deleted file mode 100644
index 719386bc558..00000000000
--- a/mit-pthreads/machdep/posix-sunos-4.1.3.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Do the right thing for a sunos 4.1.3 system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-extern long strtol();
-extern unsigned long strtoul();
-
-#endif
diff --git a/mit-pthreads/machdep/posix-sunos-5.3.h b/mit-pthreads/machdep/posix-sunos-5.3.h
deleted file mode 100644
index 9fb765d60c3..00000000000
--- a/mit-pthreads/machdep/posix-sunos-5.3.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Do the right thing for a sunos 4.1.3 system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-sunos-5.5.h b/mit-pthreads/machdep/posix-sunos-5.5.h
deleted file mode 100644
index 9fb765d60c3..00000000000
--- a/mit-pthreads/machdep/posix-sunos-5.5.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Do the right thing for a sunos 4.1.3 system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/posix-ultrix-4.2.h b/mit-pthreads/machdep/posix-ultrix-4.2.h
deleted file mode 100644
index f21aec23ea3..00000000000
--- a/mit-pthreads/machdep/posix-ultrix-4.2.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* ==== posix.h ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * $Id$
- *
- * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_POSIX_H_
-#define _PTHREAD_POSIX_H_
-
-#include <sys/cdefs.h>
-
-/* Make sure we have size_t defined */
-#include <pthread/types.h>
-
-#ifndef __WAIT_STATUS
-#define __WAIT_STATUS int *
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__math.h b/mit-pthreads/machdep/sunos-4.1.3/__math.h
deleted file mode 100755
index 9de1dc6d4bd..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__math.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * Posix (actually ansi C) section
- */
-#define HUGE_VAL (__infinity()) /* Produces IEEE Infinity. */
-
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__path.h b/mit-pthreads/machdep/sunos-4.1.3/__path.h
deleted file mode 100755
index 2665b5a0e8a..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__path.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * $Id$
- */
-
-#ifndef _SYS__PATH_H_
-#define _SYS__PATH_H_
-
-#define _PATH_PTY "/dev/"
-#define _PATH_TZDIR "/usr/share/zoneinfo"
-#define _PATH_TZFILE "localtime"
-
-#endif /* !_SYS__PATH_H_ */
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__signal.h b/mit-pthreads/machdep/sunos-4.1.3/__signal.h
deleted file mode 100755
index f8b4fb8b6de..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__signal.h
+++ /dev/null
@@ -1,11 +0,0 @@
-
-#include <sys/signal.h>
-#include <sys/stdtypes.h>
-
-typedef int sig_atomic_t;
-
-#define __SIGFILLSET 0xffffffff
-#define __SIGEMPTYSET 0
-#define __SIGADDSET(s,n) ((*s) |= (1 << ((n) - 1)))
-#define __SIGDELSET(s,n) ((*s) &= ~(1 << ((n) - 1)))
-#define __SIGISMEMBER(s,n) ((*s) & (1 << ((n) - 1)))
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__stdio.h b/mit-pthreads/machdep/sunos-4.1.3/__stdio.h
deleted file mode 100755
index 6ca5e57396d..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__stdio.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-typedef pthread_fpos_t fpos_t;
-
-#include <sys/stdtypes.h>
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__stdlib.h b/mit-pthreads/machdep/sunos-4.1.3/__stdlib.h
deleted file mode 100755
index 7bb9093c51c..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__stdlib.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* $Id$ */
-
-#ifndef __sys_stdtypes_h
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <sys/stdtypes.h> /* to get size_t */
-
-#if (! defined _SIZE_T_ ) && (! defined(_GCC_SIZE_T))
-#define _SIZE_T_
-#define _GCC_SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-#if (! defined _WCHAR_T_ ) && (! defined(_GCC_WCHAR_T))
-#define _WCHAR_T_
-#define _GCC_WCHAR_T
-typedef unsigned int wchar_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__string.h b/mit-pthreads/machdep/sunos-4.1.3/__string.h
deleted file mode 100755
index 0859a80cf24..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__string.h
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#include <sys/stdtypes.h>
-
-/* Non-standard SunOS 4.x string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-char *strdup __P_((const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__time.h b/mit-pthreads/machdep/sunos-4.1.3/__time.h
deleted file mode 100755
index 1ffa0e47d3f..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__time.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-#include <sys/stdtypes.h>
diff --git a/mit-pthreads/machdep/sunos-4.1.3/__unistd.h b/mit-pthreads/machdep/sunos-4.1.3/__unistd.h
deleted file mode 100755
index 3b86527252c..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/__unistd.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#define _SC_ARG_MAX 1 /* space for argv & envp */
-#define _SC_CHILD_MAX 2 /* maximum children per process??? */
-#define _SC_CLK_TCK 3 /* clock ticks/sec */
-#define _SC_NGROUPS_MAX 4 /* number of groups if multple supp. */
-#define _SC_OPEN_MAX 5 /* max open files per process */
-#define _SC_JOB_CONTROL 6 /* do we have job control */
-#define _SC_SAVED_IDS 7 /* do we have saved uid/gids */
-#define _SC_VERSION 8 /* POSIX version supported */
-
-#define _POSIX_JOB_CONTROL 1
-#define _POSIX_SAVED_IDS 1
-#define _POSIX_VERSION 198808
-
-#define _PC_LINK_MAX 1 /* max links to file/dir */
-#define _PC_MAX_CANON 2 /* max line length */
-#define _PC_MAX_INPUT 3 /* max "packet" to a tty device */
-#define _PC_NAME_MAX 4 /* max pathname component length */
-#define _PC_PATH_MAX 5 /* max pathname length */
-#define _PC_PIPE_BUF 6 /* size of a pipe */
-#define _PC_CHOWN_RESTRICTED 7 /* can we give away files */
-#define _PC_NO_TRUNC 8 /* trunc or error on >NAME_MAX */
-#define _PC_VDISABLE 9 /* best char to shut off tty c_cc */
-#define _PC_LAST 9 /* highest value of any _PC_* */
-
-#ifndef NULL
-#define NULL 0 /* null pointer constant */
-#endif
-
-typedef int ssize_t;
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/cdefs.h b/mit-pthreads/machdep/sunos-4.1.3/cdefs.h
deleted file mode 100755
index a059fa3d3fc..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/cdefs.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define __INLINE static
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/compat.h b/mit-pthreads/machdep/sunos-4.1.3/compat.h
deleted file mode 100755
index b2a846d00ee..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/dirent.h b/mit-pthreads/machdep/sunos-4.1.3/dirent.h
deleted file mode 100755
index c2048b1741c..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- off_t d_off; /* offset of next disk dir entry */
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
-
-
diff --git a/mit-pthreads/machdep/sunos-4.1.3/fcntlcom.h b/mit-pthreads/machdep/sunos-4.1.3/fcntlcom.h
deleted file mode 100755
index 2b7acce7696..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/fcntlcom.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* @(#)fcntlcom.h 1.13 91/06/18 SMI; from UCB fcntl.h 5.2 1/8/86 */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#ifndef __sys_fcntlcom_h
-#define __sys_fcntlcom_h
-
-#include <sys/cdefs.h>
-
-/*
- * Rewack the FXXXXX values as _FXXXX so that _POSIX_SOURCE works.
- */
-#define _FOPEN (-1) /* from sys/file.h, kernel use only */
-#define _FREAD 0x0001 /* read enabled */
-#define _FWRITE 0x0002 /* write enabled */
-#define _FNDELAY 0x0004 /* non blocking I/O (4.2 style) */
-#define _FAPPEND 0x0008 /* append (writes guaranteed at the end) */
-#define _FSETBLK 0x0010 /* use block offsets */
-#define _FASYNC 0x0040 /* signal pgrp when data ready */
-#define _FSHLOCK 0x0080 /* BSD flock() shared lock present */
-#define _FEXLOCK 0x0100 /* BSD flock() exclusive lock present */
-#define _FCREAT 0x0200 /* open with file create */
-#define _FTRUNC 0x0400 /* open with truncation */
-#define _FEXCL 0x0800 /* error on open if file exists */
-#define _FNBIO 0x1000 /* non blocking I/O (sys5 style) */
-#define _FSYNC 0x2000 /* do all writes synchronously */
-#define _FNONBLOCK 0x4000 /* non blocking I/O (POSIX style) */
-#define _FNOCTTY 0x8000 /* don't assign a ctty on this open */
-#define _FMARK 0x10000 /* internal; mark during gc() */
-#define _FDEFER 0x20000 /* internal; defer for next gc pass */
-
-#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
-
-/*
- * Flag values for open(2) and fcntl(2)
- * The kernel adds 1 to the open modes to turn it into some
- * combination of FREAD and FWRITE.
- */
-#define O_RDONLY 0 /* +1 == FREAD */
-#define O_WRONLY 1 /* +1 == FWRITE */
-#define O_RDWR 2 /* +1 == FREAD|FWRITE */
-#define O_APPEND _FAPPEND
-#define O_CREAT _FCREAT
-#define O_TRUNC _FTRUNC
-#define O_EXCL _FEXCL
-/* O_SYNC _FSYNC not posix, defined below */
-/* O_NDELAY _FNDELAY set in include/fcntl.h */
-/* O_NDELAY _FNBIO set in 5include/fcntl.h */
-#define O_NONBLOCK _FNONBLOCK
-#define O_NOCTTY _FNOCTTY
-
-#ifndef _POSIX_SOURCE
-
-#define O_SYNC _FSYNC
-
-/*
- * Flags that work for fcntl(fd, F_SETFL, FXXXX)
- */
-#define FAPPEND _FAPPEND
-#define FSYNC _FSYNC
-#define FASYNC _FASYNC
-#define FNBIO _FNBIO
-#define FNONBIO _FNONBLOCK /* XXX fix to be NONBLOCK everywhere */
-#define FNDELAY _FNDELAY
-
-/*
- * Flags that are disallowed for fcntl's (FCNTLCANT);
- * used for opens, internal state, or locking.
- */
-#define FREAD _FREAD
-#define FWRITE _FWRITE
-#define FMARK _FMARK
-#define FDEFER _FDEFER
-#define FSETBLK _FSETBLK
-#define FSHLOCK _FSHLOCK
-#define FEXLOCK _FEXLOCK
-
-/*
- * The rest of the flags, used only for opens
- */
-#define FOPEN _FOPEN
-#define FCREAT _FCREAT
-#define FTRUNC _FTRUNC
-#define FEXCL _FEXCL
-#define FNOCTTY _FNOCTTY
-
-#endif !_POSIX_SOURCE
-
-/* XXX close on exec request; must match UF_EXCLOSE in user.h */
-#define FD_CLOEXEC 1 /* posix */
-
-/* fcntl(2) requests */
-#define F_DUPFD 0 /* Duplicate fildes */
-#define F_GETFD 1 /* Get fildes flags (close on exec) */
-#define F_SETFD 2 /* Set fildes flags (close on exec) */
-#define F_GETFL 3 /* Get file flags */
-#define F_SETFL 4 /* Set file flags */
-#ifndef _POSIX_SOURCE
-#define F_GETOWN 5 /* Get owner - for ASYNC */
-#define F_SETOWN 6 /* Set owner - for ASYNC */
-#endif /* !_POSIX_SOURCE */
-#define F_GETLK 7 /* Get record-locking information */
-#define F_SETLK 8 /* Set or Clear a record-lock (Non-Blocking) */
-#define F_SETLKW 9 /* Set or Clear a record-lock (Blocking) */
-#ifndef _POSIX_SOURCE
-#define F_RGETLK 10 /* Test a remote lock to see if it is blocked */
-#define F_RSETLK 11 /* Set or unlock a remote lock */
-#define F_CNVT 12 /* Convert a fhandle to an open fd */
-#define F_RSETLKW 13 /* Set or Clear remote record-lock(Blocking) */
-#endif /* !_POSIX_SOURCE */
-
-/* fcntl(2) flags (l_type field of flock structure) */
-#define F_RDLCK 1 /* read lock */
-#define F_WRLCK 2 /* write lock */
-#define F_UNLCK 3 /* remove lock(s) */
-#ifndef _POSIX_SOURCE
-#define F_UNLKSYS 4 /* remove remote locks for a given system */
-#endif /* !_POSIX_SOURCE */
-
-#include <sys/stdtypes.h>
-
-/* file segment locking set data type - information passed to system by user */
-struct flock {
- short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */
- short l_whence; /* flag to choose starting offset */
- long l_start; /* relative offset, in bytes */
- long l_len; /* length, in bytes; 0 means lock to EOF */
- short l_pid; /* returned with F_GETLK */
- short l_xxx; /* reserved for future use */
-};
-
-#ifndef _POSIX_SOURCE
-/* extended file segment locking set data type */
-struct eflock {
- short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */
- short l_whence; /* flag to choose starting offset */
- long l_start; /* relative offset, in bytes */
- long l_len; /* length, in bytes; 0 means lock to EOF */
- short l_pid; /* returned with F_GETLK */
- short l_xxx; /* reserved for future use */
- long l_rpid; /* Remote process id wanting this lock */
- long l_rsys; /* Remote system id wanting this lock */
-};
-#endif /* !_POSIX_SOURCE */
-
-#ifndef KERNEL
-#include <sys/stat.h> /* sigh. for the mode bits for open/creat */
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-int open __P_((const char *path, int flags, ...));
-int creat __P_((const char *path, mode_t modes));
-int fcntl __P_((int fd, int cmd, ...));
-
-__END_DECLS
-
-#endif /* !KERNEL */
-#endif /* !__sys_fcntlcom_h */
diff --git a/mit-pthreads/machdep/sunos-4.1.3/signal.h b/mit-pthreads/machdep/sunos-4.1.3/signal.h
deleted file mode 100755
index 02a19860922..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/signal.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef __sys_signal_h
-#define __sys_signal_h
-
-#define NSIG 32
-
-/*
- * If any signal defines (SIG*) are added, deleted, or changed, the same
- * changes must be made in /usr/include/signal.h as well.
- */
-#define SIGHUP 1 /* hangup */
-#define SIGINT 2 /* interrupt */
-#define SIGQUIT 3 /* quit */
-#define SIGILL 4 /* illegal instruction (not reset when caught) */
-#define SIGTRAP 5 /* trace trap (not reset when caught) */
-#define SIGIOT 6 /* IOT instruction */
-#define SIGABRT 6 /* used by abort, replace SIGIOT in the future */
-#define SIGEMT 7 /* EMT instruction */
-#define SIGFPE 8 /* floating point exception */
-#define SIGKILL 9 /* kill (cannot be caught or ignored) */
-#define SIGBUS 10 /* bus error */
-#define SIGSEGV 11 /* segmentation violation */
-#define SIGSYS 12 /* bad argument to system call */
-#define SIGPIPE 13 /* write on a pipe with no one to read it */
-#define SIGALRM 14 /* alarm clock */
-#define SIGTERM 15 /* software termination signal from kill */
-#define SIGURG 16 /* urgent condition on IO channel */
-#define SIGSTOP 17 /* sendable stop signal not from tty */
-#define SIGTSTP 18 /* stop signal from tty */
-#define SIGCONT 19 /* continue a stopped process */
-#define SIGCHLD 20 /* to parent on child stop or exit */
-#define SIGCLD 20 /* System V name for SIGCHLD */
-#define SIGTTIN 21 /* to readers pgrp upon background tty read */
-#define SIGTTOU 22 /* like TTIN for output if (tp->t_local&LTOSTOP) */
-#define SIGIO 23 /* input/output possible signal */
-#define SIGPOLL SIGIO /* System V name for SIGIO */
-#define SIGXCPU 24 /* exceeded CPU time limit */
-#define SIGXFSZ 25 /* exceeded file size limit */
-#define SIGVTALRM 26 /* virtual time alarm */
-#define SIGPROF 27 /* profiling time alarm */
-#define SIGWINCH 28 /* window changed */
-#define SIGLOST 29 /* resource lost (eg, record-lock lost) */
-#define SIGUSR1 30 /* user defined signal 1 */
-#define SIGUSR2 31 /* user defined signal 2 */
-
-struct sigvec {
- void (*sv_handler)(); /* signal handler */
- int sv_mask; /* signal mask to apply */
- int sv_flags; /* see signal options below */
-};
-#define SV_ONSTACK 0x0001 /* take signal on signal stack */
-#define SV_INTERRUPT 0x0002 /* do not restart system on signal return */
-#define SV_RESETHAND 0x0004 /* reset signal handler to SIG_DFL when signal taken */
-/*
- * If any SA_NOCLDSTOP or SV_NOCLDSTOP is change, the same
- * changes must be made in /usr/include/signal.h as well.
- */
-#define SV_NOCLDSTOP 0x0008 /* don't send a SIGCHLD on child stop */
-#define SA_ONSTACK SV_ONSTACK
-#define SA_INTERRUPT SV_INTERRUPT
-#define SA_RESETHAND SV_RESETHAND
-
-#define SA_NOCLDSTOP SV_NOCLDSTOP
-#define sv_onstack sv_flags /* isn't compatibility wonderful! */
-
-/*
- * If SIG_ERR, SIG_DFL, SIG_IGN, or SIG_HOLD are changed, the same changes
- * must be made in /usr/include/signal.h as well.
- */
-#define SIG_ERR (void (*)())-1
-#define SIG_DFL (void (*)())0
-#define SIG_IGN (void (*)())1
-
-/*
- * Macro for converting signal number to a mask suitable for sigblock().
- */
-#define sigmask(m) (1 << ((m)-1))
-
-/*
- * If SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK are changed, the same changes
- * must be made in /usr/include/signal.h as well.
- */
-#define SIG_BLOCK 0x0001
-#define SIG_UNBLOCK 0x0002
-#define SIG_SETMASK 0x0004
-
-/*
- * If changes are made to sigset_t or struct sigaction, the same changes
- * must be made in /usr/include/signal.h as well.
- */
-#include <sys/stdtypes.h>
-
-struct sigaction {
- void (*sa_handler)();
- sigset_t sa_mask;
- int sa_flags;
-};
-
-#endif /* !__sys_signal_h */
diff --git a/mit-pthreads/machdep/sunos-4.1.3/stat.h b/mit-pthreads/machdep/sunos-4.1.3/stat.h
deleted file mode 100755
index 35e7f760204..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/stat.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* @(#)stat.h 2.19 90/01/24 SMI; from UCB 4.7 83/05/21 */
-
-/*
- * NOTE: changes to this file should also be made to xpg2include/sys/stat.h
- */
-
-#ifndef __sys_stat_h
-#define __sys_stat_h
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-struct stat {
- dev_t st_dev;
- ino_t st_ino;
- mode_t st_mode;
- short st_nlink;
- uid_t st_uid;
- gid_t st_gid;
- dev_t st_rdev;
- off_t st_size;
- time_t st_atime;
- int st_spare1;
- time_t st_mtime;
- int st_spare2;
- time_t st_ctime;
- int st_spare3;
- long st_blksize;
- long st_blocks;
- long st_spare4[2];
-};
-
-#define _IFMT 0170000 /* type of file */
-#define _IFDIR 0040000 /* directory */
-#define _IFCHR 0020000 /* character special */
-#define _IFBLK 0060000 /* block special */
-#define _IFREG 0100000 /* regular */
-#define _IFLNK 0120000 /* symbolic link */
-#define _IFSOCK 0140000 /* socket */
-#define _IFIFO 0010000 /* fifo */
-
-#define S_ISUID 0004000 /* set user id on execution */
-#define S_ISGID 0002000 /* set group id on execution */
-#ifndef _POSIX_SOURCE
-#define S_ISVTX 0001000 /* save swapped text even after use */
-#define S_IREAD 0000400 /* read permission, owner */
-#define S_IWRITE 0000200 /* write permission, owner */
-#define S_IEXEC 0000100 /* execute/search permission, owner */
-
-#define S_ENFMT 0002000 /* enforcement-mode locking */
-
-#define S_IFMT _IFMT
-#define S_IFDIR _IFDIR
-#define S_IFCHR _IFCHR
-#define S_IFBLK _IFBLK
-#define S_IFREG _IFREG
-#define S_IFLNK _IFLNK
-#define S_IFSOCK _IFSOCK
-#define S_IFIFO _IFIFO
-#endif !_POSIX_SOURCE
-
-#define S_IRWXU 0000700 /* rwx, owner */
-#define S_IRUSR 0000400 /* read permission, owner */
-#define S_IWUSR 0000200 /* write permission, owner */
-#define S_IXUSR 0000100 /* execute/search permission, owner */
-#define S_IRWXG 0000070 /* rwx, group */
-#define S_IRGRP 0000040 /* read permission, group */
-#define S_IWGRP 0000020 /* write permission, grougroup */
-#define S_IXGRP 0000010 /* execute/search permission, group */
-#define S_IRWXO 0000007 /* rwx, other */
-#define S_IROTH 0000004 /* read permission, other */
-#define S_IWOTH 0000002 /* write permission, other */
-#define S_IXOTH 0000001 /* execute/search permission, other */
-
-#define S_ISBLK(m) (((m)&_IFMT) == _IFBLK)
-#define S_ISCHR(m) (((m)&_IFMT) == _IFCHR)
-#define S_ISDIR(m) (((m)&_IFMT) == _IFDIR)
-#define S_ISFIFO(m) (((m)&_IFMT) == _IFIFO)
-#define S_ISREG(m) (((m)&_IFMT) == _IFREG)
-#ifndef _POSIX_SOURCE
-#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK)
-#define S_ISSOCK(m) (((m)&_IFMT) == _IFSOCK)
-#endif
-
-__BEGIN_DECLS
-int chmod __P_((const char *path, mode_t mode));
-int fstat __P_((int fd, struct stat *sbuf));
-int mkdir __P_((char *path, mode_t mode));
-int mkfifo __P_((char *path, mode_t mode));
-int stat __P_((const char *path, struct stat *sbuf));
-mode_t umask __P_((mode_t mask));
-__END_DECLS
-
-#endif /* !__sys_stat_h */
diff --git a/mit-pthreads/machdep/sunos-4.1.3/time.h b/mit-pthreads/machdep/sunos-4.1.3/time.h
deleted file mode 100755
index 20bb085e4d8..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* @(#)time.h 2.12 91/05/22 SMI; from UCB 7.1 6/4/86 */
-
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#ifndef _SYS_TIME_H_
-#define _SYS_TIME_H_
-
-#include <sys/cdefs.h>
-/*
- * Structure returned by gettimeofday(2) system call,
- * and used in other calls.
- */
-
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
-};
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-
-#define DST_NONE 0 /* not on dst */
-#define DST_USA 1 /* USA style dst */
-#define DST_AUST 2 /* Australian style dst */
-#define DST_WET 3 /* Western European dst */
-#define DST_MET 4 /* Middle European dst */
-#define DST_EET 5 /* Eastern European dst */
-#define DST_CAN 6 /* Canada */
-#define DST_GB 7 /* Great Britain and Eire */
-#define DST_RUM 8 /* Rumania */
-#define DST_TUR 9 /* Turkey */
-#define DST_AUSTALT 10 /* Australian style with shift in 1986 */
-
-/*
- * Operations on timevals.
- *
- * NB: timercmp does not work for >= or <=.
- */
-#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-#define timercmp(tvp, uvp, cmp) \
- ((tvp)->tv_sec cmp (uvp)->tv_sec || \
- (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
-#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
-
-/*
- * Names of the interval timers, and structure
- * defining a timer setting.
- */
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-
-__BEGIN_DECLS
-int gettimeofday __P_((struct timeval *, struct timezone *));
-__END_DECLS
-
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/timers.h b/mit-pthreads/machdep/sunos-4.1.3/timers.h
deleted file mode 100755
index 3c4d057976a..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/timers.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-4.1.3/wait.h b/mit-pthreads/machdep/sunos-4.1.3/wait.h
deleted file mode 100755
index 97f5fb261f7..00000000000
--- a/mit-pthreads/machdep/sunos-4.1.3/wait.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-
-#define _W_INT(i) (i)
-#define WCOREFLAG 0200
-
-#define _WSTATUS(x) (_W_INT(x) & 0177)
-#define _WSTOPPED 0177 /* _WSTATUS if process is stopped */
-#define WIFSTOPPED(x) (_WSTATUS(x) == _WSTOPPED)
-#define WSTOPSIG(x) (_W_INT(x) >> 8)
-#define WIFSIGNALED(x) (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0)
-#define WTERMSIG(x) (_WSTATUS(x))
-#define WIFEXITED(x) (_WSTATUS(x) == 0)
-#define WEXITSTATUS(x) (_W_INT(x) >> 8)
-
-#endif /* _SYS_WAIT_H_ */
diff --git a/mit-pthreads/machdep/sunos-5.3/__math.h b/mit-pthreads/machdep/sunos-5.3/__math.h
deleted file mode 100755
index 5404b52c661..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__math.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * ANSI/POSIX
- */
-typedef union _h_val {
- unsigned long _i[2];
- double _d;
-} _h_val;
-
-#ifdef __STDC__
-extern const _h_val __huge_val;
-#else
-extern _h_val __huge_val;
-#endif
-
-#define HUGE_VAL __huge_val._d
-
diff --git a/mit-pthreads/machdep/sunos-5.3/__signal.h b/mit-pthreads/machdep/sunos-5.3/__signal.h
deleted file mode 100755
index 638c1ca7331..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__signal.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <sys/feature_tests.h>
-#include <sys/signal.h>
-
-/*
-typedef struct {
- unsigned long __sigbits[4];
-} sigset_t;
-*/
-
-typedef int sig_atomic_t;
-
-#define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1)))
-#define sigword(n) (((unsigned int)((n) - 1))>>5)
-
-#define __SIGEMPTYSET { 0, 0, 0, 0 };
-#define __SIGFILLSET { 0xffffffff,0xffffffff,0xffffffff,0xffffffff };
-#define __SIGADDSET(s, n) ((s)->__sigbits[sigword(n)] |= sigmask(n))
-#define __SIGDELSET(s, n) ((s)->__sigbits[sigword(n)] &= ~sigmask(n))
-#define __SIGISMEMBER(s, n) (sigmask(n) & (s)->__sigbits[sigword(n)])
diff --git a/mit-pthreads/machdep/sunos-5.3/__stdio.h b/mit-pthreads/machdep/sunos-5.3/__stdio.h
deleted file mode 100755
index 4dd4becdbe9..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__stdio.h
+++ /dev/null
@@ -1,6 +0,0 @@
-typedef pthread_fpos_t fpos_t;
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/__stdlib.h b/mit-pthreads/machdep/sunos-5.3/__stdlib.h
deleted file mode 100755
index a0717ce3c2b..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__stdlib.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <sys/feature_tests.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _UID_T
-#define _UID_T
-typedef long uid_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef long wchar_t;
-#endif
-
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/__string.h b/mit-pthreads/machdep/sunos-5.3/__string.h
deleted file mode 100755
index 9cb12a07bb7..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__string.h
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-char *strdup __P_((const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/__time.h b/mit-pthreads/machdep/sunos-5.3/__time.h
deleted file mode 100755
index 231e997acfa..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : System specific time header.
- *
- * 1.00 94/11/07 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS___TIME_H_
-#define _SYS___TIME_H_
-
-#include <sys/feature_tests.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned size_t;
-#endif
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-#ifndef _CLOCKID_T
-#define _CLOCKID_T
-typedef int clockid_t;
-#endif
-#ifndef _TIMER_T
-#define _TIMER_T
-typedef int timer_t;
-#endif
-
-#include <sys/time.h>
-#include <sys/siginfo.h>
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/__unistd.h b/mit-pthreads/machdep/sunos-5.3/__unistd.h
deleted file mode 100755
index 4e83a863735..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/__unistd.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-#include <sys/unistd.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/cdefs.h b/mit-pthreads/machdep/sunos-5.3/cdefs.h
deleted file mode 100755
index f95f7b36958..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/cdefs.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define __INLINE static
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/compat.h b/mit-pthreads/machdep/sunos-5.3/compat.h
deleted file mode 100755
index b2a846d00ee..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/dirent.h b/mit-pthreads/machdep/sunos-5.3/dirent.h
deleted file mode 100755
index 303d3d7df2b..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- off_t d_off; /* offset of next disk dir entry */
- u_short d_reclen; /* length of this record */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_namlen d_reclen
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
-
-
diff --git a/mit-pthreads/machdep/sunos-5.3/socket.h b/mit-pthreads/machdep/sunos-5.3/socket.h
deleted file mode 100755
index 0b075622fed..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/socket.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1982, 1985, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)socket.h 7.3 (Berkeley) 6/27/88
- */
-
-#ifndef _SYS_SOCKET_H
-#define _SYS_SOCKET_H
-
-/*
- * Types of sockets
- */
-#define SOCK_STREAM 2 /* stream socket */
-#define SOCK_DGRAM 1 /* datagram socket */
-#define SOCK_RAW 4 /* raw-protocol interface */
-#define SOCK_RDM 5 /* reliably-delivered message */
-#define SOCK_SEQPACKET 6 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_PROTOTYPE 0x1009 /* get/set protocol type */
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_NBS 7 /* nbs protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_NIT 17 /* NIT */
-#define AF_802 18 /* IEEE 802.2, also ISO 8802 */
-#define AF_ISO 19 /* ISO protocols */
-#define AF_OSI AF_ISO
-#define AF_X25 20 /* CCITT X.25 in particular */
-#define AF_OSINET 21
-#define AF_GOSIP 22
-#define AF_MAX 22
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- unsigned short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- unsigned short sp_family; /* address family */
- unsigned short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_NBS AF_NBS
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NIT AF_NIT
-#define PF_802 AF_802
-#define PF_ISO AF_ISO
-#define PF_OSI AF_ISO
-#define PF_X25 AF_X25
-#define PF_OSINET AF_OSINET
-#define PF_GOSIP AF_GOSIP
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-
-#define MSG_MAXIOVLEN 16
-
-#include <sys/cdefs.h>
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int getsockname __P_((int, struct sockaddr *, int *));
-int shutdown __P_((int, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-__END_DECLS
-
-#endif /* _SYS_SOCKET_H */
diff --git a/mit-pthreads/machdep/sunos-5.3/timers.h b/mit-pthreads/machdep/sunos-5.3/timers.h
deleted file mode 100755
index 3ee2c78f088..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/timers.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-#define tv_sec tv_sec
-#define tv_nsec tv_nsec
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-#ifndef NOT_USED
-/* for sleep.h */
-/* int gettimeofday __P_((struct timeval *,struct timezone *)); */
-int gettimeofday __P_((struct timeval *,void *));
-#endif
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.3/uio.h b/mit-pthreads/machdep/sunos-5.3/uio.h
deleted file mode 100755
index 7786142dd87..00000000000
--- a/mit-pthreads/machdep/sunos-5.3/uio.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Solaris header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-#include <sys/cdefs.h>
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-typedef struct iovec iovec_t;
-
-struct uio {
- iovec_t *uio_iov; /* pointer to array of iovecs */
- int uio_iovcnt; /* number of iovecs */
- /* These are all bogus */
- int _uio_offset; /* file offset */
- int uio_segflg; /* address space (kernel or user) */
- short uio_fmode; /* file mode flags */
- int _uio_limit; /* u-limit (maximum "block" offset) */
- int uio_resid; /* residual count */
-};
-
-typedef struct uio uio_t;
-
-__BEGIN_DECLS
-
-int readv __P_((int, const struct iovec *, int));
-int writev __P_((int, const struct iovec *, int));
-
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/machdep/sunos-5.5/__math.h b/mit-pthreads/machdep/sunos-5.5/__math.h
deleted file mode 100755
index 5404b52c661..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__math.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * ANSI/POSIX
- */
-typedef union _h_val {
- unsigned long _i[2];
- double _d;
-} _h_val;
-
-#ifdef __STDC__
-extern const _h_val __huge_val;
-#else
-extern _h_val __huge_val;
-#endif
-
-#define HUGE_VAL __huge_val._d
-
diff --git a/mit-pthreads/machdep/sunos-5.5/__signal.h b/mit-pthreads/machdep/sunos-5.5/__signal.h
deleted file mode 100755
index 638c1ca7331..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__signal.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <sys/feature_tests.h>
-#include <sys/signal.h>
-
-/*
-typedef struct {
- unsigned long __sigbits[4];
-} sigset_t;
-*/
-
-typedef int sig_atomic_t;
-
-#define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1)))
-#define sigword(n) (((unsigned int)((n) - 1))>>5)
-
-#define __SIGEMPTYSET { 0, 0, 0, 0 };
-#define __SIGFILLSET { 0xffffffff,0xffffffff,0xffffffff,0xffffffff };
-#define __SIGADDSET(s, n) ((s)->__sigbits[sigword(n)] |= sigmask(n))
-#define __SIGDELSET(s, n) ((s)->__sigbits[sigword(n)] &= ~sigmask(n))
-#define __SIGISMEMBER(s, n) (sigmask(n) & (s)->__sigbits[sigword(n)])
diff --git a/mit-pthreads/machdep/sunos-5.5/__stdio.h b/mit-pthreads/machdep/sunos-5.5/__stdio.h
deleted file mode 100755
index 4dd4becdbe9..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__stdio.h
+++ /dev/null
@@ -1,6 +0,0 @@
-typedef pthread_fpos_t fpos_t;
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/__stdlib.h b/mit-pthreads/machdep/sunos-5.5/__stdlib.h
deleted file mode 100755
index a0717ce3c2b..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__stdlib.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <sys/feature_tests.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _UID_T
-#define _UID_T
-typedef long uid_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef long wchar_t;
-#endif
-
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/__string.h b/mit-pthreads/machdep/sunos-5.5/__string.h
deleted file mode 100755
index 9cb12a07bb7..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__string.h
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard NetBSD string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-char *strdup __P_((const char *));
-__END_DECLS
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/__time.h b/mit-pthreads/machdep/sunos-5.5/__time.h
deleted file mode 100755
index 231e997acfa..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : System specific time header.
- *
- * 1.00 94/11/07 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS___TIME_H_
-#define _SYS___TIME_H_
-
-#include <sys/feature_tests.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned size_t;
-#endif
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-#ifndef _CLOCKID_T
-#define _CLOCKID_T
-typedef int clockid_t;
-#endif
-#ifndef _TIMER_T
-#define _TIMER_T
-typedef int timer_t;
-#endif
-
-#include <sys/time.h>
-#include <sys/siginfo.h>
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/__unistd.h b/mit-pthreads/machdep/sunos-5.5/__unistd.h
deleted file mode 100755
index 4e83a863735..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/__unistd.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-#include <sys/unistd.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/cdefs.h b/mit-pthreads/machdep/sunos-5.5/cdefs.h
deleted file mode 100755
index f95f7b36958..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/cdefs.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#else /* !__GNUC__ */
-#define __BEGIN_DECLS
-#define __END_DECLS
-#define __INLINE static
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/compat.h b/mit-pthreads/machdep/sunos-5.5/compat.h
deleted file mode 100755
index b2a846d00ee..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/dirent.h b/mit-pthreads/machdep/sunos-5.5/dirent.h
deleted file mode 100755
index 303d3d7df2b..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/dirent.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- off_t d_off; /* offset of next disk dir entry */
- u_short d_reclen; /* length of this record */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_namlen d_reclen
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
-
-
diff --git a/mit-pthreads/machdep/sunos-5.5/socket.h b/mit-pthreads/machdep/sunos-5.5/socket.h
deleted file mode 100755
index 0b075622fed..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/socket.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1982, 1985, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#)socket.h 7.3 (Berkeley) 6/27/88
- */
-
-#ifndef _SYS_SOCKET_H
-#define _SYS_SOCKET_H
-
-/*
- * Types of sockets
- */
-#define SOCK_STREAM 2 /* stream socket */
-#define SOCK_DGRAM 1 /* datagram socket */
-#define SOCK_RAW 4 /* raw-protocol interface */
-#define SOCK_RDM 5 /* reliably-delivered message */
-#define SOCK_SEQPACKET 6 /* sequenced packet stream */
-
-/*
- * Option flags per-socket.
- */
-#define SO_DEBUG 0x0001 /* turn on debugging info recording */
-#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-#define SO_REUSEADDR 0x0004 /* allow local address reuse */
-#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-#define SO_DONTROUTE 0x0010 /* just use interface addresses */
-#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
-#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
-#define SO_LINGER 0x0080 /* linger on close if data present */
-#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
-
-/*
- * Additional options, not kept in so_options.
- */
-#define SO_SNDBUF 0x1001 /* send buffer size */
-#define SO_RCVBUF 0x1002 /* receive buffer size */
-#define SO_SNDLOWAT 0x1003 /* send low-water mark */
-#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
-#define SO_SNDTIMEO 0x1005 /* send timeout */
-#define SO_RCVTIMEO 0x1006 /* receive timeout */
-#define SO_ERROR 0x1007 /* get error status and clear */
-#define SO_TYPE 0x1008 /* get socket type */
-#define SO_PROTOTYPE 0x1009 /* get/set protocol type */
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET 0xffff /* options for socket level */
-
-/*
- * Address families.
- */
-#define AF_UNSPEC 0 /* unspecified */
-#define AF_UNIX 1 /* local to host (pipes, portals) */
-#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK 3 /* arpanet imp addresses */
-#define AF_PUP 4 /* pup protocols: e.g. BSP */
-#define AF_CHAOS 5 /* mit CHAOS protocols */
-#define AF_NS 6 /* XEROX NS protocols */
-#define AF_NBS 7 /* nbs protocols */
-#define AF_ECMA 8 /* european computer manufacturers */
-#define AF_DATAKIT 9 /* datakit protocols */
-#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
-#define AF_SNA 11 /* IBM SNA */
-#define AF_DECnet 12 /* DECnet */
-#define AF_DLI 13 /* Direct data link interface */
-#define AF_LAT 14 /* LAT */
-#define AF_HYLINK 15 /* NSC Hyperchannel */
-#define AF_APPLETALK 16 /* Apple Talk */
-#define AF_NIT 17 /* NIT */
-#define AF_802 18 /* IEEE 802.2, also ISO 8802 */
-#define AF_ISO 19 /* ISO protocols */
-#define AF_OSI AF_ISO
-#define AF_X25 20 /* CCITT X.25 in particular */
-#define AF_OSINET 21
-#define AF_GOSIP 22
-#define AF_MAX 22
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
- unsigned short sa_family; /* address family */
- char sa_data[14]; /* up to 14 bytes of direct address */
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
- unsigned short sp_family; /* address family */
- unsigned short sp_protocol; /* protocol */
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_IMPLINK AF_IMPLINK
-#define PF_PUP AF_PUP
-#define PF_CHAOS AF_CHAOS
-#define PF_NS AF_NS
-#define PF_NBS AF_NBS
-#define PF_ECMA AF_ECMA
-#define PF_DATAKIT AF_DATAKIT
-#define PF_CCITT AF_CCITT
-#define PF_SNA AF_SNA
-#define PF_DECnet AF_DECnet
-#define PF_DLI AF_DLI
-#define PF_LAT AF_LAT
-#define PF_HYLINK AF_HYLINK
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NIT AF_NIT
-#define PF_802 AF_802
-#define PF_ISO AF_ISO
-#define PF_OSI AF_ISO
-#define PF_X25 AF_X25
-#define PF_OSINET AF_OSINET
-#define PF_GOSIP AF_GOSIP
-#define PF_MAX AF_MAX
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN 5
-
-/*
- * Message header for recvmsg and sendmsg calls.
- */
-struct msghdr {
- caddr_t msg_name; /* optional address */
- int msg_namelen; /* size of address */
- struct iovec *msg_iov; /* scatter/gather array */
- int msg_iovlen; /* # elements in msg_iov */
- caddr_t msg_accrights; /* access rights sent/received */
- int msg_accrightslen;
-};
-
-#define MSG_OOB 0x1 /* process out-of-band data */
-#define MSG_PEEK 0x2 /* peek at incoming message */
-#define MSG_DONTROUTE 0x4 /* send without using routing tables */
-
-#define MSG_MAXIOVLEN 16
-
-#include <sys/cdefs.h>
-/*
- * Functions
- */
-
-__BEGIN_DECLS
-
-int accept __P_((int, struct sockaddr *, int *));
-int bind __P_((int, const struct sockaddr *, int));
-int connect __P_((int, const struct sockaddr *, int));
-int listen __P_((int, int));
-int socket __P_((int, int, int));
-int setsockopt __P_((int, int, int, const void *, int));
-int getsockname __P_((int, struct sockaddr *, int *));
-int shutdown __P_((int, int));
-int getpeername __P_((int, struct sockaddr *, int *));
-__END_DECLS
-
-#endif /* _SYS_SOCKET_H */
diff --git a/mit-pthreads/machdep/sunos-5.5/timers.h b/mit-pthreads/machdep/sunos-5.5/timers.h
deleted file mode 100755
index 3aad5f80065..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/timers.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-#define tv_sec tv_sec
-#define tv_nsec tv_nsec
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-#ifdef NOT_USED
-int gettimeofday __P_((struct timeval *,struct timezone *)); /* for sleep.h */
-#endif
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/sunos-5.5/uio.h b/mit-pthreads/machdep/sunos-5.5/uio.h
deleted file mode 100755
index 7786142dd87..00000000000
--- a/mit-pthreads/machdep/sunos-5.5/uio.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* ==== uio.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Correct Solaris header file.
- */
-
-#ifndef _PTHREAD_UIO_H_
-#define _PTHREAD_UIO_H_
-
-#include <sys/cdefs.h>
-
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-
-typedef struct iovec iovec_t;
-
-struct uio {
- iovec_t *uio_iov; /* pointer to array of iovecs */
- int uio_iovcnt; /* number of iovecs */
- /* These are all bogus */
- int _uio_offset; /* file offset */
- int uio_segflg; /* address space (kernel or user) */
- short uio_fmode; /* file mode flags */
- int _uio_limit; /* u-limit (maximum "block" offset) */
- int uio_resid; /* residual count */
-};
-
-typedef struct uio uio_t;
-
-__BEGIN_DECLS
-
-int readv __P_((int, const struct iovec *, int));
-int writev __P_((int, const struct iovec *, int));
-
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/machdep/syscall-alpha-netbsd-1.1.S b/mit-pthreads/machdep/syscall-alpha-netbsd-1.1.S
deleted file mode 100644
index 5b7dd017426..00000000000
--- a/mit-pthreads/machdep/syscall-alpha-netbsd-1.1.S
+++ /dev/null
@@ -1,206 +0,0 @@
-#include <machine/asm.h>
-#define CHMK() call_pal 0x83
-#define COMPAT_43
-#include <sys/syscall.h>
-#ifndef __CONCAT
-#include <sys/cdefs.h>
-#endif
-#define CONCAT __CONCAT
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl CONCAT(machdep_sys_,x) ;\
- .ent CONCAT(machdep_sys_,x), 0 ;\
-CONCAT(machdep_sys_,x): ;\
- .frame sp,0,ra ;\
- ldiq v0, CONCAT(SYS_,x) ;\
- CHMK() ;\
- beq a3, CONCAT(Lsys_noerr_,x) ;\
- br gp, CONCAT(Lsys_err_,x) ;\
-CONCAT(Lsys_err_,x): ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-CONCAT(Lsys_noerr_,x):
-
-#define XSYSCALL(x) SYSCALL(x) ; RET ; .end CONCAT(machdep_sys_,x)
-
- .globl machdep_cerror
-machdep_cerror:
- br t0, Lmachdep_cerror_setgp
-Lmachdep_cerror_setgp:
- ldgp gp, 0(t0)
- stl v0, errno
-#if 0
- ldiq v0, -1
-#else
- subq zero, v0, v0
-#endif
- RET
-
-/* The fork system call is special... */
-SYSCALL(fork)
- cmovne a4, 0, v0
- RET
- .end machdep_sys_fork
-
-/* The pipe system call is special... */
-SYSCALL(pipe)
- stl v0, 0(a0)
- stl a4, 4(a0)
- mov zero, v0
- RET
- .end machdep_sys_pipe
-
-/* The sigsuspend system call is special... */
- .align 4
- .globl machdep_sys_sigsuspend
- .ent machdep_sys_sigsuspend, 0
-machdep_sys_sigsuspend:
- ldl a0, 0(a0) /* pass *mask instead of mask */
- ldiq v0, SYS_sigsuspend
- CHMK()
- mov zero, v0 /* shouldn't need; just in case... */
- RET
- .end machdep_sys_sigsuspend
-
-/* The sigprocmask system call is special... */
- .align 4
- .globl machdep_sys_sigprocmask
- .ent machdep_sys_sigprocmask, 0
-machdep_sys_sigprocmask:
- mov a2, a5 /* safe */
- cmoveq a1, 1, a0 /* if set == NULL, how = SIG_BLOCK */
- beq a1, Ldoit /* and set = 0, and do it. */
- ldl a1, 0(a1) /* load the set from *set */
-Ldoit: ldiq v0, SYS_sigprocmask
- CHMK()
- beq a5, Lret /* if they don't want old mask, done */
- stl v0, 0(a5) /* otherwise, give it to them. */
-Lret: mov zero, v0
- RET
- .end machdep_sys_sigprocmask
-
-/* More stuff ... */
- .align 4
- .global __machdep_save_int_state
- .ent __machdep_save_int_state, 0
-__machdep_save_int_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* save integer registers */
- stq ra, ( 0 * 8)(a0) /* return address */
- stq s0, ( 1 * 8)(a0) /* callee-saved registers */
- stq s1, ( 2 * 8)(a0)
- stq s2, ( 3 * 8)(a0)
- stq s3, ( 4 * 8)(a0)
- stq s4, ( 5 * 8)(a0)
- stq s5, ( 6 * 8)(a0)
- stq s6, ( 7 * 8)(a0)
- stq sp, ( 9 * 8)(a0)
- stq ra, ( 8 * 8)(a0) /* RA on return */
- stq pv, (10 * 8)(a0) /* and PV; we restore it */
-
- mov zero, v0
- lda sp, 16(sp)
- RET
- .end __machdep_save_int_state
-
- .align 4
- .global __machdep_restore_int_state
- .ent __machdep_restore_int_state, 0
-__machdep_restore_int_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* restore integer registers */
- ldq t0, ( 0 * 8)(a0) /* return address */
- ldq s0, ( 1 * 8)(a0) /* callee-saved registers */
- ldq s1, ( 2 * 8)(a0)
- ldq s2, ( 3 * 8)(a0)
- ldq s3, ( 4 * 8)(a0)
- ldq s4, ( 5 * 8)(a0)
- ldq s5, ( 6 * 8)(a0)
- ldq s6, ( 7 * 8)(a0)
- ldq ra, ( 8 * 8)(a0) /* RA after return */
- ldq sp, ( 9 * 8)(a0)
- ldq pv, (10 * 8)(a0) /* and PV; we restore it */
-
- ldiq v0, 1
- ret zero,(t0),1
- .end __machdep_restore_int_state
-
- .align 4
- .global __machdep_save_fp_state
- .ent __machdep_save_fp_state, 0
-__machdep_save_fp_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* save FP registers */
- stt fs0, (0 * 8)(a0) /* callee-saved registers */
- stt fs1, (1 * 8)(a0)
- stt fs2, (2 * 8)(a0)
- stt fs3, (3 * 8)(a0)
- stt fs4, (4 * 8)(a0)
- stt fs5, (5 * 8)(a0)
- stt fs6, (6 * 8)(a0)
- stt fs7, (7 * 8)(a0)
- mf_fpcr ft0 /* and FP control reg */
- stt ft0, (8 * 8)(a0)
-
- lda sp, 16(sp)
- RET
- .end __machdep_save_fp_state
-
- .align 4
- .global __machdep_restore_fp_state
- .ent __machdep_restore_fp_state, 0
-__machdep_restore_fp_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* restore FP registers */
- ldt fs0, (0 * 8)(a0) /* callee-saved registers */
- ldt fs1, (1 * 8)(a0)
- ldt fs2, (2 * 8)(a0)
- ldt fs3, (3 * 8)(a0)
- ldt fs4, (4 * 8)(a0)
- ldt fs5, (5 * 8)(a0)
- ldt fs6, (6 * 8)(a0)
- ldt fs7, (7 * 8)(a0)
- ldt ft0, (8 * 8)(a0)
- mt_fpcr ft0 /* and FP control reg */
-
- lda sp, 16(sp)
- RET
- .end __machdep_restore_fp_state
diff --git a/mit-pthreads/machdep/syscall-alpha-netbsd-1.3.S b/mit-pthreads/machdep/syscall-alpha-netbsd-1.3.S
deleted file mode 100644
index 61435a729d7..00000000000
--- a/mit-pthreads/machdep/syscall-alpha-netbsd-1.3.S
+++ /dev/null
@@ -1,228 +0,0 @@
-#include <machine/asm.h>
-#define CHMK() call_pal 0x83
-#define COMPAT_43
-#include <sys/syscall.h>
-#ifndef __CONCAT
-#include <sys/cdefs.h>
-#endif
-#define CONCAT __CONCAT
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl CONCAT(machdep_sys_,x) ;\
- .ent CONCAT(machdep_sys_,x), 0 ;\
-CONCAT(machdep_sys_,x): ;\
- .frame sp,0,ra ;\
- ldiq v0, CONCAT(SYS_,x) ;\
- CHMK() ;\
- beq a3, CONCAT(Lsys_noerr_,x) ;\
- br gp, CONCAT(Lsys_err_,x) ;\
-CONCAT(Lsys_err_,x): ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-CONCAT(Lsys_noerr_,x):
-
-#define XSYSCALL(x) SYSCALL(x) ; RET ; .end CONCAT(machdep_sys_,x)
-
- .globl machdep_cerror
-machdep_cerror:
- br t0, Lmachdep_cerror_setgp
-Lmachdep_cerror_setgp:
- ldgp gp, 0(t0)
- stl v0, errno
-#if 0
- ldiq v0, -1
-#else
- subq zero, v0, v0
-#endif
- RET
-
-/* The fork system call is special... */
-SYSCALL(fork)
- cmovne a4, 0, v0
- RET
- .end machdep_sys_fork
-
-/* The pipe system call is special... */
-SYSCALL(pipe)
- stl v0, 0(a0)
- stl a4, 4(a0)
- mov zero, v0
- RET
- .end machdep_sys_pipe
-
-#ifndef SYS___sigsuspend14
-/* The sigsuspend system call is special... */
- .align 4
- .globl machdep_sys_sigsuspend
- .ent machdep_sys_sigsuspend, 0
-machdep_sys_sigsuspend:
- ldl a0, 0(a0) /* pass *mask instead of mask */
- ldiq v0, SYS_sigsuspend
- CHMK()
- mov zero, v0 /* shouldn't need; just in case... */
- RET
- .end machdep_sys_sigsuspend
-#endif /* SYS_sigsuspend14 */
-
-#ifndef SYS___sigprocmask14
-/* The sigprocmask system call is special... */
- .align 4
- .globl machdep_sys_sigprocmask
- .ent machdep_sys_sigprocmask, 0
-machdep_sys_sigprocmask:
- mov a2, a5 /* safe */
- cmoveq a1, 1, a0 /* if set == NULL, how = SIG_BLOCK */
- beq a1, Ldoit /* and set = 0, and do it. */
- ldl a1, 0(a1) /* load the set from *set */
-Ldoit: ldiq v0, SYS_sigprocmask
- CHMK()
- beq a5, Lret /* if they don't want old mask, done */
- stl v0, 0(a5) /* otherwise, give it to them. */
-Lret: mov zero, v0
- RET
- .end machdep_sys_sigprocmask
-#endif /* SYS_sigprocmask14 */
-
-/* More stuff ... */
- .align 4
- .global __machdep_save_int_state
- .ent __machdep_save_int_state, 0
-__machdep_save_int_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* save integer registers */
- stq ra, ( 0 * 8)(a0) /* return address */
- stq s0, ( 1 * 8)(a0) /* callee-saved registers */
- stq s1, ( 2 * 8)(a0)
- stq s2, ( 3 * 8)(a0)
- stq s3, ( 4 * 8)(a0)
- stq s4, ( 5 * 8)(a0)
- stq s5, ( 6 * 8)(a0)
- stq s6, ( 7 * 8)(a0)
- stq sp, ( 9 * 8)(a0)
- stq ra, ( 8 * 8)(a0) /* RA on return */
- stq pv, (10 * 8)(a0) /* and PV; we restore it */
-
- mov zero, v0
- lda sp, 16(sp)
- RET
- .end __machdep_save_int_state
-
- .align 4
- .global __machdep_restore_int_state
- .ent __machdep_restore_int_state, 0
-__machdep_restore_int_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* restore integer registers */
- ldq t0, ( 0 * 8)(a0) /* return address */
- ldq s0, ( 1 * 8)(a0) /* callee-saved registers */
- ldq s1, ( 2 * 8)(a0)
- ldq s2, ( 3 * 8)(a0)
- ldq s3, ( 4 * 8)(a0)
- ldq s4, ( 5 * 8)(a0)
- ldq s5, ( 6 * 8)(a0)
- ldq s6, ( 7 * 8)(a0)
- ldq ra, ( 8 * 8)(a0) /* RA after return */
- ldq sp, ( 9 * 8)(a0)
- ldq pv, (10 * 8)(a0) /* and PV; we restore it */
-
- ldiq v0, 1
- ret zero,(t0),1
- .end __machdep_restore_int_state
-
- .align 4
- .global __machdep_save_fp_state
- .ent __machdep_save_fp_state, 0
-__machdep_save_fp_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* save FP registers */
- stt fs0, (0 * 8)(a0) /* callee-saved registers */
- stt fs1, (1 * 8)(a0)
- stt fs2, (2 * 8)(a0)
- stt fs3, (3 * 8)(a0)
- stt fs4, (4 * 8)(a0)
- stt fs5, (5 * 8)(a0)
- stt fs6, (6 * 8)(a0)
- stt fs7, (7 * 8)(a0)
- mf_fpcr ft0 /* and FP control reg */
- stt ft0, (8 * 8)(a0)
-
- lda sp, 16(sp)
- RET
- .end __machdep_save_fp_state
-
- .align 4
- .global __machdep_restore_fp_state
- .ent __machdep_restore_fp_state, 0
-__machdep_restore_fp_state:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
-
- /* restore FP registers */
- ldt fs0, (0 * 8)(a0) /* callee-saved registers */
- ldt fs1, (1 * 8)(a0)
- ldt fs2, (2 * 8)(a0)
- ldt fs3, (3 * 8)(a0)
- ldt fs4, (4 * 8)(a0)
- ldt fs5, (5 * 8)(a0)
- ldt fs6, (6 * 8)(a0)
- ldt fs7, (7 * 8)(a0)
- ldt ft0, (8 * 8)(a0)
- mt_fpcr ft0 /* and FP control reg */
-
- lda sp, 16(sp)
- RET
- .end __machdep_restore_fp_state
-
-/* For fstat() we actually syscall fstat13. */
- .align 4
- .globl machdep_sys_fstat
- .ent machdep_sys_fstat, 0
-machdep_sys_fstat:
- .frame sp,0,ra
- ldiq v0, SYS___fstat13
- CHMK()
- beq a3, Lsys_noerr_fstat
- br gp, Lsys_err_fstat
-Lsys_err_fstat:
- /* Load gp so we can find cerror to jump to. */
- ldgp gp, 0(gp)
- jmp zero, machdep_cerror
-Lsys_noerr_fstat:
- RET
- .end machdep_sys_fstat
diff --git a/mit-pthreads/machdep/syscall-alpha-osf1.S b/mit-pthreads/machdep/syscall-alpha-osf1.S
deleted file mode 100644
index fad823a7352..00000000000
--- a/mit-pthreads/machdep/syscall-alpha-osf1.S
+++ /dev/null
@@ -1,97 +0,0 @@
-#include <asm.h>
-#include <regdef.h>
-#define COMPAT_43
-#include <syscall.h>
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl machdep_sys_##x ;\
- .ent machdep_sys_##x, 0 ;\
-machdep_sys_##x: ;\
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
- beq a3, 2f ;\
- br gp, 1f ;\
-1: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-2:
-
-#define XSYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
- .globl machdep_cerror
-machdep_cerror:
- br t0, 1f
-1:
- ldgp gp, 0(t0)
- stl v0, errno
-#if 0
- ldiq v0, -1
-#else
- subq zero, v0, v0
-#endif
- ret
-
-/* The fork system call is special... */
-SYSCALL(fork)
- cmovne a4, 0, v0
- ret
- .end machdep_sys_fork
-
-/* So is the sigsuspend system call */
- .align 4
- .globl machdep_sys_sigsuspend
- .ent machdep_sys_sigsuspend, 0
-machdep_sys_sigsuspend:
- .frame sp,0,ra
-
- bis a0, a0, a1
- ldq a0, 0(a1)
- ldiq v0, SYS_sigsuspend
- CHMK()
- ret
- .end machdep_sys_sigsuspend
-
-/* More stuff ... */
- .align 4
- .globl machdep_restore_from_setjmp
- .ent machdep_restore_from_setjmp, 0
-machdep_restore_from_setjmp:
- .frame sp, 16, ra
- ldgp gp, 0(t12)
- lda sp, -16(sp)
- stq ra, 0(sp)
- ldq v0, 280(a0)
- subq v0, 0x00000000acedbade, t0
- bne t0, botch
- cmoveq a1, 0x1, a1
- stq a1, 32(a0)
- ldiq v0, 0x67
- call_pal 0x83
-botch:
- /* This should cause the program to crash. Eventually, fix it
- up to print a message first. */
- jsr abort
- .end machdep_restore_from_setjmp
diff --git a/mit-pthreads/machdep/syscall-arm32-netbsd-1.3.S b/mit-pthreads/machdep/syscall-arm32-netbsd-1.3.S
deleted file mode 100644
index 5914674b508..00000000000
--- a/mit-pthreads/machdep/syscall-arm32-netbsd-1.3.S
+++ /dev/null
@@ -1,193 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 0
-
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _C_LABEL(machdep_sys_fork);
-
-_C_LABEL(machdep_sys_fork):;
-
- swi SYS_fork
- bcs 1f
- sub r1, r1, #0x00000001
- and r0, r0, r1
- mov r15, r14
-
-
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
- .globl _C_LABEL(machdep_sys_fstat);
-
-_C_LABEL(machdep_sys_fstat):;
-
- swi SYS___fstat13
- bcs 1f
- mov r15, r14
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- swi SYS___syscall
- bcs 1f
- mov r15, r14
-
-
-#ifndef SYS___sigsuspend14
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _C_LABEL(machdep_sys_sigsuspend);
-
-_C_LABEL(machdep_sys_sigsuspend):;
-
- ldr r0, [r0]
- swi SYS_sigsuspend
- bcs 1f
- mov r0, #0x00000000
- mov r15, r14
-
-#endif
-
-#ifndef SYS___sigprocmask14
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _C_LABEL(machdep_sys_sigprocmask);
-
-_C_LABEL(machdep_sys_sigprocmask):;
-
- teq r1, #0x00000000
- moveq r0, #0x00000001
- moveq r1, #0x00000000
- ldrne r1, [r1]
- swi SYS_sigprocmask
- bcs 1f
- teq r2, #0x00000000
- strne r0, [r2]
- mov r0, #0x00000000
- mov r15, r14
-#endif
-
-/* ==========================================================================
- * machdep_sys_ftruncate()
- */
- .global _C_LABEL(machdep_sys_ftruncate)
-_C_LABEL(machdep_sys_ftruncate):
- mov r12, r13
- stmfd r13!, {r11, r12, r14, r15}
- sub r13, r13, #8
- stmia r13, {r1-r2}
- mov r3, #0
- sub r11, r12, #4
- mov r2, r0
- mov r1, #0
- mov r0, #201
- bl _machdep_sys___syscall
- ldmea r11, {r11, r13, r15}
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .global _C_LABEL(machdep_sys_lseek)
-
-_C_LABEL(machdep_sys_lseek):
- mov r12, r13
- stmfd r13!, {r11, r12, r14, r15}
- str r3, [r13, #-4]!
- sub r13, r13, #8
- stmia r13, {r1-r2}
- sub r11, r12, #4
- mov r3, #0
- mov r2, r0
- mov r1, #0
- mov r0, #SYS_lseek
- bl _machdep_sys___syscall
- ldmea r11, {r11, r13, r15}
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _C_LABEL(machdep_sys_pipe);
-
-_C_LABEL(machdep_sys_pipe):;
-
- mov r2, r0
- swi SYS_pipe
- bcs 1f
- str r0, [r2, #0x0000]
- str r1, [r2, #0x0004]
- mov r0, #0x00000000
- mov r15, r14
-
-
-1:
- rsb r0, r0, #0x00000000
- mvn r1, #0x00000000
- mov r15, r14
diff --git a/mit-pthreads/machdep/syscall-hppa-hpux-10.20.S b/mit-pthreads/machdep/syscall-hppa-hpux-10.20.S
deleted file mode 100644
index c63d845bae5..00000000000
--- a/mit-pthreads/machdep/syscall-hppa-hpux-10.20.S
+++ /dev/null
@@ -1,23 +0,0 @@
- .CODE
-
-machdep_error
- sub %r0,%r28,%r28
- bv,n %r0(%r2)
-
-machdep_sys_fork
-
- .PROC
- .CALLINFO NO_CALLS,FRAME=0
-
- ldil -0x80000,%r1
- ble 4(%sr7,%r1)
- ldi 2 ,%r22
- or,= %r0,%r22,%r0
- b,n machdep_error
- or,= %r29,%r0,%r0
- copy %r0,%r28
- bv,n %r0(%r2)
-
- .PROCEND
- .EXPORT machdep_sys_fork,ENTRY
-
diff --git a/mit-pthreads/machdep/syscall-hppa-hpux-9.03.S b/mit-pthreads/machdep/syscall-hppa-hpux-9.03.S
deleted file mode 100644
index c63d845bae5..00000000000
--- a/mit-pthreads/machdep/syscall-hppa-hpux-9.03.S
+++ /dev/null
@@ -1,23 +0,0 @@
- .CODE
-
-machdep_error
- sub %r0,%r28,%r28
- bv,n %r0(%r2)
-
-machdep_sys_fork
-
- .PROC
- .CALLINFO NO_CALLS,FRAME=0
-
- ldil -0x80000,%r1
- ble 4(%sr7,%r1)
- ldi 2 ,%r22
- or,= %r0,%r22,%r0
- b,n machdep_error
- or,= %r29,%r0,%r0
- copy %r0,%r28
- bv,n %r0(%r2)
-
- .PROCEND
- .EXPORT machdep_sys_fork,ENTRY
-
diff --git a/mit-pthreads/machdep/syscall-i386-bsdi-1.1.S b/mit-pthreads/machdep/syscall-i386-bsdi-1.1.S
deleted file mode 100644
index e54cd0d0773..00000000000
--- a/mit-pthreads/machdep/syscall-i386-bsdi-1.1.S
+++ /dev/null
@@ -1,288 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_write()
- */
-SYSCALL(write)
-
-/* ==========================================================================
- * machdep_sys_read()
- */
-SYSCALL(read)
-
-/* ==========================================================================
- * machdep_sys_open()
- */
-SYSCALL(open)
-
-/* ==========================================================================
- * machdep_sys_close()
- */
-SYSCALL(close)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
-SYSCALL(fcntl)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-SYSCALL(lseek)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
-SYSCALL(pipe)
-
-/* ==========================================================================
- * machdep_sys_dup()
- */
-SYSCALL(dup)
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-SYSCALL(dup2)
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys_execve()
- */
-SYSCALL(execve)
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-SYSCALL(fstat)
-
-/* ==========================================================================
- * machdep_sys_fchown()
- */
-SYSCALL(fchown)
-
-/* ==========================================================================
- * machdep_sys_fchmod()
- */
-SYSCALL(fchmod)
-
-/* ==========================================================================
- * machdep_sys_chown()
- */
-SYSCALL(chown)
-
-/* ==========================================================================
- * machdep_sys_chmod()
- */
-SYSCALL(chmod)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(chdir)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(link)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(unlink)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(rename)
-
-/* ==========================================================================
- * Nonstandard calls used to make the system work
- *
- * ==========================================================================
- * machdep_sys_select()
- */
-SYSCALL(select)
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-SYSCALL(getdirentries)
-
-/* ==========================================================================
- * machdep_sys_wait4()
- */
-SYSCALL(wait4)
-
-/* ==========================================================================
- * Berkeley socket stuff
- *
- * ==========================================================================
- * machdep_sys_socket()
- */
-SYSCALL(socket)
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-SYSCALL(bind)
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-SYSCALL(connect)
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-SYSCALL(accept)
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-SYSCALL(listen)
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-SYSCALL(getsockopt)
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-SYSCALL(readv)
-
-/* ==========================================================================
- * machdep_sys_writev()
- */
-SYSCALL(writev)
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-SYSCALL(getpeername)
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-SYSCALL(getsockname)
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-SYSCALL(sendto)
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-SYSCALL(recvfrom)
-
-/* ==========================================================================
- * machdep_sys_sendmsg()
- */
-SYSCALL(sendmsg)
-
-/* ==========================================================================
- * machdep_sys_recvmsg()
- */
-SYSCALL(recvmsg)
-
-/* ==========================================================================
- * machdep_sys_shutdown() - Is this correct?
- */
-SYSCALL(shutdown)
-
diff --git a/mit-pthreads/machdep/syscall-i386-bsdi-2.0.S b/mit-pthreads/machdep/syscall-i386-bsdi-2.0.S
deleted file mode 100644
index 8a56717da31..00000000000
--- a/mit-pthreads/machdep/syscall-i386-bsdi-2.0.S
+++ /dev/null
@@ -1,294 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "syscall-i386-netbsd-1.0.S,v 1.56 1995/09/26 21:04:05 raeburn Exp";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _machdep_sys_sigsuspend;
-
-_machdep_sys_sigsuspend:;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-3:
-
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl _machdep_sys_lseek;
-
-_machdep_sys_lseek:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl _machdep_sys_ftruncate;
-
-_machdep_sys_ftruncate:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
-
-
-/* BSDI DEFS.h,v 2.1 1995/02/03 06:28:24 polk Exp */
-
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)DEFS.h 8.1 (Berkeley) 6/4/93
- */
-
-#ifdef PROF
-#define ENTRY(x) .globl _/**/x; .align 2; _/**/x: \
- .data; 1:; .long 0; .text; \
- pushl %ebp; movl %esp,%ebp; \
- leal 1b,%eax; call mcount; leave
-#define ASENTRY(x) .globl x; .align 2; x: \
- .data; 1:; .long 0; .text; \
- pushl %ebp; movl %esp,%ebp; \
- leal 1b,%eax; call mcount; leave
-#else
-#define ENTRY(x) .globl _/**/x; .align 2; _/**/x:
-#define ASENTRY(x) .globl x; .align 2; x:
-#endif
-
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
- .asciz "@(#)_setjmp.s 8.1 (Berkeley) 6/4/93"
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * C library -- _setjmp, _longjmp
- *
- * _longjmp(a,v)
- * will generate a "return(v)" from the last call to
- * _setjmp(a)
- * by restoring registers from the stack.
- * The previous signal state is NOT restored.
- */
-
-
-.globl __setjmp; /* Patch by Jan Legenhausen (monty) */
-.align 2;
-__setjmp:
- movl 4(%esp),%eax
- movl 0(%esp),%edx
- movl %edx, 0(%eax) /* rta */
- movl %ebx, 4(%eax)
- movl %esp, 8(%eax)
- movl %ebp,12(%eax)
- movl %esi,16(%eax)
- movl %edi,20(%eax)
- movl $0,%eax
- ret
-
-.globl __longjmp; /* Patch by Jan Legenhausen ? (monty) */
-.align 2;
-__longjmp:
- movl 4(%esp),%edx
- movl 8(%esp),%eax
- movl 0(%edx),%ecx
- movl 4(%edx),%ebx
- movl 8(%edx),%esp
- movl 12(%edx),%ebp
- movl 16(%edx),%esi
- movl 20(%edx),%edi
- cmpl $0,%eax
- jne 1f
- movl $1,%eax
-1: movl %ecx,0(%esp)
- ret
diff --git a/mit-pthreads/machdep/syscall-i386-freebsd-1.1.S b/mit-pthreads/machdep/syscall-i386-freebsd-1.1.S
deleted file mode 100644
index 5777cc5e06d..00000000000
--- a/mit-pthreads/machdep/syscall-i386-freebsd-1.1.S
+++ /dev/null
@@ -1,293 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_write()
- */
-SYSCALL(write)
-
-/* ==========================================================================
- * machdep_sys_read()
- */
-SYSCALL(read)
-
-/* ==========================================================================
- * machdep_sys_open()
- */
-SYSCALL(open)
-
-/* ==========================================================================
- * machdep_sys_close()
- */
-SYSCALL(close)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
-SYSCALL(fcntl)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-SYSCALL(lseek)
-
-/* ==========================================================================
- * machdep_sys_stat()
- */
-SYSCALL(stat)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
-SYSCALL(pipe)
-
-/* ==========================================================================
- * machdep_sys_dup()
- */
-SYSCALL(dup)
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-SYSCALL(dup2)
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys_execve()
- */
-SYSCALL(execve)
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-SYSCALL(fstat)
-
-/* ==========================================================================
- * machdep_sys_fchown()
- */
-SYSCALL(fchown)
-
-/* ==========================================================================
- * machdep_sys_fchmod()
- */
-SYSCALL(fchmod)
-
-/* ==========================================================================
- * machdep_sys_chown()
- */
-SYSCALL(chown)
-
-/* ==========================================================================
- * machdep_sys_chmod()
- */
-SYSCALL(chmod)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(chdir)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(link)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(unlink)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL(rename)
-
-/* ==========================================================================
- * Nonstandard calls used to make the system work
- *
- * ==========================================================================
- * machdep_sys_select()
- */
-SYSCALL(select)
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-SYSCALL(getdirentries)
-
-/* ==========================================================================
- * machdep_sys_wait4()
- */
-SYSCALL(wait4)
-
-/* ==========================================================================
- * Berkeley socket stuff
- *
- * ==========================================================================
- * machdep_sys_socket()
- */
-SYSCALL(socket)
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-SYSCALL(bind)
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-SYSCALL(connect)
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-SYSCALL(accept)
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-SYSCALL(listen)
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-SYSCALL(getsockopt)
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-SYSCALL(readv)
-
-/* ==========================================================================
- * machdep_sys_writev()
- */
-SYSCALL(writev)
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-SYSCALL(getpeername)
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-SYSCALL(getsockname)
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-SYSCALL(sendto)
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-SYSCALL(recvfrom)
-
-/* ==========================================================================
- * machdep_sys_sendmsg()
- */
-SYSCALL(sendmsg)
-
-/* ==========================================================================
- * machdep_sys_recvmsg()
- */
-SYSCALL(recvmsg)
-
-/* ==========================================================================
- * machdep_sys_shutdown()
- */
-SYSCALL(shutdown)
-
diff --git a/mit-pthreads/machdep/syscall-i386-freebsd-2.0.S b/mit-pthreads/machdep/syscall-i386-freebsd-2.0.S
deleted file mode 100644
index b713bcac344..00000000000
--- a/mit-pthreads/machdep/syscall-i386-freebsd-2.0.S
+++ /dev/null
@@ -1,240 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1995 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- */
-
-#ifndef lint
- .text
- .asciz "syscall-i386-freebsd-2.0.S,v 1.2 1995/05/26 07:44:29 proven Exp";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#ifdef __ELF__
-#define NAME(X) machdep_sys_##X
-#else
-#define NAME(X) _machdep_sys_##X
-#endif
-
-#else
-
-#ifdef __ELF__
-#define NAME(X) machdep_sys_/**/X
-#else
-#define NAME(X) _machdep_sys_/**/X
-#endif
-
-#endif
-
-#ifdef __ELF__
-#define END(X) 5: ; .type NAME(X),@function ; .size NAME(X),5b - NAME(X)
-#define KERNCALL int $0x80
-#else
-#define END(X)
-#define KERNCALL .byte 0x9a; .long 0; .word 7;
-#endif
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl NAME(fork);
-
-NAME(fork):;
-
- movl $(SYS_fork), %eax;
- KERNCALL;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
- END(fork)
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- KERNCALL;
- jb 3f;
- ret
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl NAME(sigsuspend);
-
-NAME(sigsuspend):;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- KERNCALL;
- jb 3f;
- ret
-3:
- neg %eax
- movl $0xffffffff,%edx
- ret
- END(sigsuspend)
-
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl NAME(sigprocmask);
-
-NAME(sigprocmask):;
-
- movl 8(%esp),%ecx
- movl (%ecx),%ecx
- movl %ecx,8(%esp)
- movl $ SYS_sigprocmask , %eax
- KERNCALL;
- jb 4f;
- ret
-4:
- neg %eax
- movl $0xffffffff,%edx
- ret
- END(sigprocmask)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl NAME(lseek);
-
-NAME(lseek):;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
- END(lseek)
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl NAME(ftruncate);
-
-NAME(ftruncate):;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
- END(ftruncate)
-
-/* ==========================================================================
- * machdep_sys_setjmp()
- */
- .globl NAME(setjmp);
-
-NAME(setjmp):;
- movl 4(%esp),%eax
- movl 0(%esp),%edx
- movl %edx, 0(%eax) /* rta */
- movl %ebx, 4(%eax)
- movl %esp, 8(%eax)
- movl %ebp,12(%eax)
- movl %esi,16(%eax)
- movl %edi,20(%eax)
- xorl %eax,%eax
- ret
- END(setjmp)
-
-/* ==========================================================================
- * machdep_sys_longjmp()
- */
- .globl NAME(longjmp);
-
-NAME(longjmp):;
- movl 4(%esp),%edx
- movl 8(%esp),%eax
- movl 0(%edx),%ecx
- movl 4(%edx),%ebx
- movl 8(%edx),%esp
- movl 12(%edx),%ebp
- movl 16(%edx),%esi
- movl 20(%edx),%edi
- testl %eax,%eax
- jnz 1f
- incl %eax
-1:
- movl %ecx,0(%esp)
- ret
- END(longjmp)
diff --git a/mit-pthreads/machdep/syscall-i386-linux-1.0.S b/mit-pthreads/machdep/syscall-i386-linux-1.0.S
deleted file mode 100644
index 1399c812e2f..00000000000
--- a/mit-pthreads/machdep/syscall-i386-linux-1.0.S
+++ /dev/null
@@ -1,406 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- *
- * 1.16 94/01/30 proven
- * -This file now requires gas version 2.0 or greater.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <sys/syscall.h>
-#include <config.h>
-
-#ifdef __ELF__
-
-#define NAME(X) machdep_sys_##X
-#define END(X) 1: ; .type NAME(X),@function ; .size NAME(X),1b - NAME(X)
-
-#else
-
-#define NAME(X) _machdep_sys_##X
-#define END(X)
-
-#endif
-
-#define SYSCALL0(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define SYSCALL1(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define SYSCALL2(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- mov 12(%esp), %ecx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define STATCALL2(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- mov 12(%esp), %ecx; \
- lea SYS_prev_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- END(x)
-
-#define SYSCALL3(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- mov 12(%esp), %ecx; \
- mov 16(%esp), %edx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- END(x)
-
-
-#define SYSCALL4(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- push %esi; \
- mov 12(%esp), %ebx; \
- mov 16(%esp), %ecx; \
- mov 20(%esp), %edx; \
- mov 24(%esp), %esi; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %esi; \
- pop %ebx; \
- ret; \
- END(x)
-
-#define SYSCALL5(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- push %esi; \
- push %edi; \
- mov 16(%esp), %ebx; \
- mov 20(%esp), %ecx; \
- mov 24(%esp), %edx; \
- mov 28(%esp), %esi; \
- mov 32(%esp), %edi; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %edi; \
- pop %esi; \
- pop %ebx; \
- ret; \
- END(x)
-
-/* =========================================================================
- * exit 1 select 82
- * fork 2 fstatfs 100
- * read 3 socketcall 102
- * write 4 flock 143
- * open 5 readv 145
- * creat 8 writev 146
- * link 9
- * unlink 10
- * execve 11
- * chdir 12
- * chmod 15
- * chown 16
- * lseek 19
- * rename 38
- * dup 41
- * pipe 42
- * ioctl 54
- * fcntl 55
- * dup2 63
- * readdir 89
- * ftruncate 93
- * fchmod 94
- * fchown 95
- */
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * machdep_sys_read()
- */
-SYSCALL3(read)
-
-/* ==========================================================================
- * machdep_sys_write()
- */
-SYSCALL3(write)
-
-/* ==========================================================================
- * machdep_sys_open()
- */
-SYSCALL3(open)
-
-/* ==========================================================================
- * machdep_sys_close()
- */
-SYSCALL1(close)
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-SYSCALL2(creat)
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-SYSCALL2(dup2)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
-SYSCALL3(fcntl)
-
-/* ==========================================================================
- * machdep_sys_fchown()
- */
-SYSCALL3(fchown)
-
-/* ==========================================================================
- * machdep_sys_fchmod()
- */
-SYSCALL2(fchmod)
-
-/* ==========================================================================
- * machdep_sys_ioctl()
- */
-SYSCALL3(ioctl)
-
-/* ==========================================================================
- * machdep_sys_chown()
- */
-SYSCALL3(chown)
-
-/* ==========================================================================
- * machdep_sys_chmod()
- */
-SYSCALL2(chmod)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL1(chdir)
-
-/* ==========================================================================
- * machdep_sys_unlink()
- */
-SYSCALL1(unlink)
-
-/* ==========================================================================
- * machdep_sys_link()
- */
-SYSCALL2(link)
-
-/* ==========================================================================
- * machdep_sys_rename()
- */
-SYSCALL2(rename)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-SYSCALL3(lseek)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
-SYSCALL1(pipe)
-
-/* ==========================================================================
- * machdep_sys_dup()
- */
-SYSCALL1(dup)
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
-SYSCALL0(fork)
-
-/* ==========================================================================
- * machdep_sys_execve()
- */
-SYSCALL3(execve)
-
-/* ==========================================================================
- * machdep_sys_stat()
- */
-#ifdef __ELF__
-STATCALL2(stat)
-#else
-SYSCALL2(stat)
-#endif
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-#ifdef __ELF__
-STATCALL2(fstat)
-#else
-SYSCALL2(fstat)
-#endif
-
-/* ==========================================================================
- * machdep_sys_lstat()
- */
-#ifdef __ELF__
-STATCALL2(lstat)
-#else
-SYSCALL2(lstat)
-#endif
-
-/* ==========================================================================
- * machdep_sys_fstatfs()
- */
-SYSCALL2(fstatfs)
-
-
-/* ==========================================================================
- * machdep_sys_ftruncate()
- */
-SYSCALL2(ftruncate)
-
-/* ==========================================================================
- * Nonstandard calls used to make the system work
- *
- * ==========================================================================
- * machdep_sys_select()
- */
-
- .globl NAME(select)
-
-NAME(select):
-
- push %ebx
- lea 8(%esp), %ebx
- lea SYS_select, %eax
- int $0x80
- pop %ebx
- ret
- END(select)
-
-/* ==========================================================================
- * machdep_sys_wait4()
- */
-SYSCALL4(wait4)
-
-/* ==========================================================================
- * machdep_sys_readdir()
- */
-SYSCALL3(readdir)
-
-/* ==========================================================================
- * machdep_sys_socketcall()
- */
-SYSCALL2(socketcall)
-
-
-SYSCALL1(exit)
-SYSCALL3(sigprocmask)
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
-
- .globl NAME(sigsuspend)
-
-NAME(sigsuspend):
-
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- push %ebx
- mov 8(%ebp), %edx
- mov (%edx), %edx
- lea SYS_sigsuspend, %eax
- int $0x80
- pop %ebx
- pop %esi
- pop %edi
- mov %ebp,%esp
- pop %ebp
- ret
- END(sigsuspend)
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-#ifdef HAVE_SYSCALL_READV
-SYSCALL3(readv)
-#endif
-
-/* ==========================================================================
- * machdep_sys_writev()
- */
-#ifdef HAVE_SYSCALL_WRITEV
-SYSCALL3(writev)
-#endif
-
-/* ==========================================================================
- * machdep_sys_flock()
- */
-#ifdef HAVE_SYSCALL_FLOCK
-SYSCALL2(flock)
-#endif
diff --git a/mit-pthreads/machdep/syscall-i386-linux-2.0.S b/mit-pthreads/machdep/syscall-i386-linux-2.0.S
deleted file mode 100644
index d5807b2d9b4..00000000000
--- a/mit-pthreads/machdep/syscall-i386-linux-2.0.S
+++ /dev/null
@@ -1,389 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- *
- * 1.16 94/01/30 proven
- * -This file now requires gas version 2.0 or greater.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <sys/syscall.h>
-#include <config.h>
-
-#ifdef __ELF__
-
-#define NAME(X) machdep_sys_##X
-#define END(X) 1: ; .type NAME(X),@function ; .size NAME(X),1b - NAME(X)
-
-#else
-
-#define NAME(X) _machdep_sys_##X
-#define END(X)
-
-#endif
-
-#define SYSCALL0(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define SYSCALL1(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define SYSCALL2(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- mov 12(%esp), %ecx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- \
- END(x)
-
-#define SYSCALL3(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- mov 8(%esp), %ebx; \
- mov 12(%esp), %ecx; \
- mov 16(%esp), %edx; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %ebx; \
- ret; \
- END(x)
-
-
-#define SYSCALL4(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- push %esi; \
- mov 12(%esp), %ebx; \
- mov 16(%esp), %ecx; \
- mov 20(%esp), %edx; \
- mov 24(%esp), %esi; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %esi; \
- pop %ebx; \
- ret; \
- END(x)
-
-#define SYSCALL5(x) \
- .globl NAME(x) ; \
- \
-NAME(x): \
- \
- push %ebx; \
- push %esi; \
- push %edi; \
- mov 16(%esp), %ebx; \
- mov 20(%esp), %ecx; \
- mov 24(%esp), %edx; \
- mov 28(%esp), %esi; \
- mov 32(%esp), %edi; \
- lea SYS_##x, %eax; \
- int $0x80; \
- pop %edi; \
- pop %esi; \
- pop %ebx; \
- ret; \
- END(x)
-
-/* =========================================================================
- * exit 1 select 82
- * fork 2 fstatfs 100
- * read 3 socketcall 102
- * write 4 flock 143
- * open 5 readv 145
- * creat 8 writev 146
- * link 9
- * unlink 10
- * execve 11
- * chdir 12
- * chmod 15
- * chown 16
- * lseek 19
- * rename 38
- * dup 41
- * pipe 42
- * ioctl 54
- * fcntl 55
- * dup2 63
- * readdir 89
- * ftruncate 93
- * fchmod 94
- * fchown 95
- */
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * machdep_sys_read()
- */
-SYSCALL3(read)
-
-/* ==========================================================================
- * machdep_sys_write()
- */
-SYSCALL3(write)
-
-/* ==========================================================================
- * machdep_sys_open()
- */
-SYSCALL3(open)
-
-/* ==========================================================================
- * machdep_sys_close()
- */
-SYSCALL1(close)
-
-/* ==========================================================================
- * machdep_sys_creat()
- */
-SYSCALL2(creat)
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-SYSCALL2(dup2)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
-SYSCALL3(fcntl)
-
-/* ==========================================================================
- * machdep_sys_fchown()
- */
-SYSCALL3(fchown)
-
-/* ==========================================================================
- * machdep_sys_fchmod()
- */
-SYSCALL2(fchmod)
-
-/* ==========================================================================
- * machdep_sys_ioctl()
- */
-SYSCALL3(ioctl)
-
-/* ==========================================================================
- * machdep_sys_chown()
- */
-SYSCALL3(chown)
-
-/* ==========================================================================
- * machdep_sys_chmod()
- */
-SYSCALL2(chmod)
-
-/* ==========================================================================
- * machdep_sys_chdir()
- */
-SYSCALL1(chdir)
-
-/* ==========================================================================
- * machdep_sys_unlink()
- */
-SYSCALL1(unlink)
-
-/* ==========================================================================
- * machdep_sys_link()
- */
-SYSCALL2(link)
-
-/* ==========================================================================
- * machdep_sys_rename()
- */
-SYSCALL2(rename)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-SYSCALL3(lseek)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
-SYSCALL1(pipe)
-
-/* ==========================================================================
- * machdep_sys_dup()
- */
-SYSCALL1(dup)
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
-SYSCALL0(fork)
-
-/* ==========================================================================
- * machdep_sys_execve()
- */
-SYSCALL3(execve)
-
-/* ==========================================================================
- * machdep_sys_stat()
- */
-SYSCALL2(stat)
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-SYSCALL2(fstat)
-
-/* ==========================================================================
- * machdep_sys_lstat()
- */
-SYSCALL2(lstat)
-
-/* ==========================================================================
- * machdep_sys_fstatfs()
- */
-SYSCALL2(fstatfs)
-
-/* ==========================================================================
- * machdep_sys_ftruncate()
- */
-SYSCALL2(ftruncate)
-
-/* ==========================================================================
- * machdep_sys_chroot()
- */
-SYSCALL1(chroot)
-
-/* ==========================================================================
- * machdep_sys_uname()
- */
-SYSCALL1(uname)
-
-/* ==========================================================================
- * Nonstandard calls used to make the system work
- *
- * ==========================================================================
- * machdep_sys_select()
- */
-
- .globl NAME(select)
-
-NAME(select):
-
- push %ebx
- lea 8(%esp), %ebx
- lea SYS_select, %eax
- int $0x80
- pop %ebx
- ret
- END(select)
-
-/* ==========================================================================
- * machdep_sys_wait4()
- */
-SYSCALL4(wait4)
-
-/* ==========================================================================
- * machdep_sys_readdir()
- */
-SYSCALL3(readdir)
-
-/* ==========================================================================
- * machdep_sys_socketcall()
- */
-SYSCALL2(socketcall)
-
-
-SYSCALL1(exit)
-SYSCALL3(sigprocmask)
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
-
- .globl NAME(sigsuspend)
-
-NAME(sigsuspend):
-
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- push %ebx
- mov 8(%ebp), %edx
- mov (%edx), %edx
- lea SYS_sigsuspend, %eax
- int $0x80
- pop %ebx
- pop %esi
- pop %edi
- mov %ebp,%esp
- pop %ebp
- ret
- END(sigsuspend)
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-#ifdef HAVE_SYSCALL_READV
-SYSCALL3(readv)
-#endif
-
-/* ==========================================================================
- * machdep_sys_writev()
- */
-#ifdef HAVE_SYSCALL_WRITEV
-SYSCALL3(writev)
-#endif
-
-/* ==========================================================================
- * machdep_sys_flock()
- */
-#ifdef HAVE_SYSCALL_FLOCK
-SYSCALL2(flock)
-#endif
diff --git a/mit-pthreads/machdep/syscall-i386-netbsd-0.9.S b/mit-pthreads/machdep/syscall-i386-netbsd-0.9.S
deleted file mode 100644
index 8d768a673d3..00000000000
--- a/mit-pthreads/machdep/syscall-i386-netbsd-0.9.S
+++ /dev/null
@@ -1,229 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_write()
- */
-SYSCALL(write)
-
-/* ==========================================================================
- * machdep_sys_read()
- */
-SYSCALL(read)
-
-/* ==========================================================================
- * machdep_sys_open()
- */
-SYSCALL(open)
-
-/* ==========================================================================
- * machdep_sys_close()
- */
-SYSCALL(close)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
-SYSCALL(fcntl)
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
-SYSCALL(lseek)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
-SYSCALL(pipe)
-
-/* ==========================================================================
- * machdep_sys_dup()
- */
-SYSCALL(dup)
-
-/* ==========================================================================
- * machdep_sys_dup2()
- */
-SYSCALL(dup2)
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys_execve()
- */
-SYSCALL(execve)
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
-SYSCALL(fstat)
-
-/* ==========================================================================
- * Nonstandard calls used to make the system work
- *
- * ==========================================================================
- * machdep_sys_select()
- */
-SYSCALL(select)
-
-/* ==========================================================================
- * machdep_sys_getdirentries()
- */
-SYSCALL(getdirentries)
-
-/* ==========================================================================
- * Berkeley socket stuff
- *
- * ==========================================================================
- * machdep_sys_socket()
- */
-SYSCALL(socket)
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
-SYSCALL(bind)
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
-SYSCALL(connect)
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
-SYSCALL(accept)
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
-SYSCALL(listen)
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
-SYSCALL(getsockopt)
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-SYSCALL(readv)
-
-/* ==========================================================================
- * machdep_sys_writev()
- */
-SYSCALL(writev)
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
-SYSCALL(getpeername)
-
-/* ==========================================================================
- * machdep_sys_getsockname()
- */
-SYSCALL(getsockname)
-
-/* ==========================================================================
- * machdep_sys_sendto()
- */
-SYSCALL(sendto)
-
-/* ==========================================================================
- * machdep_sys_recvfrom()
- */
-SYSCALL(recvfrom)
-
diff --git a/mit-pthreads/machdep/syscall-i386-netbsd-1.0.S b/mit-pthreads/machdep/syscall-i386-netbsd-1.0.S
deleted file mode 100644
index da535dd2f80..00000000000
--- a/mit-pthreads/machdep/syscall-i386-netbsd-1.0.S
+++ /dev/null
@@ -1,158 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _machdep_sys_sigsuspend;
-
-_machdep_sys_sigsuspend:;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-3:
-
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl _machdep_sys_lseek;
-
-_machdep_sys_lseek:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl _machdep_sys_ftruncate;
-
-_machdep_sys_ftruncate:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
diff --git a/mit-pthreads/machdep/syscall-i386-netbsd-1.1.S b/mit-pthreads/machdep/syscall-i386-netbsd-1.1.S
deleted file mode 100644
index a74d2ac1af6..00000000000
--- a/mit-pthreads/machdep/syscall-i386-netbsd-1.1.S
+++ /dev/null
@@ -1,181 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- int $0x80;
- jb 3f;
- ret
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _machdep_sys_sigsuspend;
-
-_machdep_sys_sigsuspend:;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- int $0x80;
- jb 3f;
- ret
-
-3:
-
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl _machdep_sys_lseek;
-
-_machdep_sys_lseek:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl _machdep_sys_ftruncate;
-
-_machdep_sys_ftruncate:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _machdep_sys_sigprocmask;
-
-_machdep_sys_sigprocmask:;
-
- movl 8(%esp),%ecx
- movl (%ecx),%ecx
- movl %ecx,8(%esp)
- movl $(SYS_sigprocmask), %eax;
- int $0x80;
- jb 3b;
- ret
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _machdep_sys_pipe;
-
-_machdep_sys_pipe:;
-
- movl $(SYS_pipe), %eax;
- int $0x80;
- jb 3b;
- movl 4(%esp),%ecx
- movl %eax,(%ecx)
- movl %edx,4(%ecx)
- xorl %eax,%eax
- ret
-
diff --git a/mit-pthreads/machdep/syscall-i386-netbsd-1.3.S b/mit-pthreads/machdep/syscall-i386-netbsd-1.3.S
deleted file mode 100644
index 85dc6b3e5bc..00000000000
--- a/mit-pthreads/machdep/syscall-i386-netbsd-1.3.S
+++ /dev/null
@@ -1,200 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- * 1.00 93/08/26 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _C_LABEL(machdep_sys_fork);
-
-_C_LABEL(machdep_sys_fork):;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- int $0x80;
- jb 3f;
- ret
-
-#ifndef SYS___sigsuspend14
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _C_LABEL(machdep_sys_sigsuspend);
-
-_C_LABEL(machdep_sys_sigsuspend):;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- int $0x80;
- jb 3f;
- ret
-#endif
-
-3:
-
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl _C_LABEL(machdep_sys_lseek);
-
-_C_LABEL(machdep_sys_lseek):;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl _C_LABEL(machdep_sys_ftruncate);
-
-_C_LABEL(machdep_sys_ftruncate):;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
-
-#ifndef SYS___sigprocmask14
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _C_LABEL(machdep_sys_sigprocmask);
-
-_C_LABEL(machdep_sys_sigprocmask):;
-
- movl 8(%esp),%ecx
- movl (%ecx),%ecx
- movl %ecx,8(%esp)
- movl $(SYS_sigprocmask), %eax;
- int $0x80;
- jb 3b;
- ret
-#endif
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _C_LABEL(machdep_sys_pipe);
-
-_C_LABEL(machdep_sys_pipe):;
-
- movl $(SYS_pipe), %eax;
- int $0x80;
- jb 3b;
- movl 4(%esp),%ecx
- movl %eax,(%ecx)
- movl %edx,4(%ecx)
- xorl %eax,%eax
- ret
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
- .globl _C_LABEL(machdep_sys_fstat);
-
-_C_LABEL(machdep_sys_fstat):;
- movl $(SYS___fstat13), %eax;
- int $0x80;
- jb 4f;
- ret
-4:
- neg %eax
- movl $0xffffffff,%edx
- ret
-
diff --git a/mit-pthreads/machdep/syscall-i386-openbsd-2.0.S b/mit-pthreads/machdep/syscall-i386-openbsd-2.0.S
deleted file mode 100644
index cfdbbc77f73..00000000000
--- a/mit-pthreads/machdep/syscall-i386-openbsd-2.0.S
+++ /dev/null
@@ -1,237 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1995 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- */
-
-#ifndef lint
- .text
- .asciz "syscall-i386-freebsd-2.0.S,v 1.2 1995/05/26 07:44:29 proven Exp";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x##; \
- \
-_machdep_sys_##x##:; \
- \
- movl $(SYS_##x##), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- movl $(SYS_fork), %eax;
- .byte 0x9a; .long 0; .word 7;
- cmpl $0, %edx
- je 2f
- movl $0, %eax
-2:
- ret;
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-
-_machdep_sys___syscall:;
-
- movl $(SYS___syscall), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _machdep_sys_sigsuspend;
-
-_machdep_sys_sigsuspend:;
-
- movl 4(%esp),%eax # fetch mask arg
- movl (%eax),%eax # indirect to mask arg
- movl %eax,4(%esp)
- movl $(SYS_sigsuspend), %eax;
- .byte 0x9a; .long 0; .word 7;
- jb 3f;
- ret
-
-3:
-
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _machdep_sys_sigprocmask;
-
-_machdep_sys_sigprocmask:;
-
- movl 8(%esp),%ecx
- movl (%ecx),%ecx
- movl %ecx,8(%esp)
- movl $ SYS_sigprocmask , %eax
- .byte 0x9a; .long 0; .word 7;
- jb 4f;
- ret
-
-4:
- neg %eax
- movl $0xffffffff,%edx
- ret
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .globl _machdep_sys_lseek;
-
-_machdep_sys_lseek:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x14(%ebp);
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0;
- pushl 0x8(%ebp);
- pushl $0x0;
- pushl $(SYS_lseek);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_ftruncate() ; Added by Monty
- */
- .globl _machdep_sys_ftruncate;
-
-_machdep_sys_ftruncate:;
-
- pushl %ebp;
- movl %esp,%ebp;
- pushl 0x10(%ebp);
- pushl 0xc(%ebp);
- pushl $0x0; # Why this?
- pushl 0x8(%ebp);
- pushl $0x0; # And this?
- pushl $(SYS_ftruncate);
- call _machdep_sys___syscall;
- leave
- ret
-
-/* ==========================================================================
- * machdep_sys_setjmp()
- */
- .globl _machdep_sys_setjmp;
-
-_machdep_sys_setjmp:;
- movl 4(%esp),%eax
- movl 0(%esp),%edx
- movl %edx, 0(%eax) /* rta */
- movl %ebx, 4(%eax)
- movl %esp, 8(%eax)
- movl %ebp,12(%eax)
- movl %esi,16(%eax)
- movl %edi,20(%eax)
- xorl %eax,%eax
- ret
-
-/* ==========================================================================
- * machdep_sys_longjmp()
- */
- .globl _machdep_sys_longjmp;
-
-_machdep_sys_longjmp:;
- movl 4(%esp),%edx
- movl 8(%esp),%eax
- movl 0(%edx),%ecx
- movl 4(%edx),%ebx
- movl 8(%edx),%esp
- movl 12(%edx),%ebp
- movl 16(%edx),%esi
- movl 20(%edx),%edi
- testl %eax,%eax
- jnz 1f
- incl %eax
-1: movl %ecx,0(%esp)
- ret
-
diff --git a/mit-pthreads/machdep/syscall-i386-sco-3.2v5.S b/mit-pthreads/machdep/syscall-i386-sco-3.2v5.S
deleted file mode 100644
index 0a60dcdd866..00000000000
--- a/mit-pthreads/machdep/syscall-i386-sco-3.2v5.S
+++ /dev/null
@@ -1,442 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1995 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for i386/i486/i586
- *
- */
-
-#ifndef lint
- .text
- .asciz "syscall-i386-sco-3.2v5.S,v 1.2 1995/05/26 07:44:29 proven Exp";
-#endif
-
-#if defined(SYSLIBC_SCCS) && !defined(lint)
- .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
-#endif /* SYSLIBC_SCCS and not lint */
-
-#include <sys/errno.h>
-#include <sys/syscall.h>
-
-#ifdef _SCO_ELF
-
-#define NAME(X) machdep_sys_##X
-#define GETADDR(X) \
- call 1f; \
-1: \
- popl %ebx; \
- addl $NAME(X)+[.-1b], %ebx
-
-#define END(X) 1: ; .type NAME(X),@function ; .size NAME(X),1b - NAME(X)
-
-#else
-
-#define NAME(X) _machdep_sys_##X
-#define END(X)
-
-#endif
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl NAME(x); \
- \
-NAME(x): \
- movl $(SYS_##x##), %eax; \
- lcall $7, $0; \
- jae 1f; \
- cmp $(ERESTART), %eax; \
- je NAME(x); \
- neg %eax; \
-1: \
- ret; \
-\
- END(x)
-
-
-#else
-
-#define SYSCALL(x) \
- .globl NAME(x); \
- \
-NAME(x): \
- \
- movl $(SYS_/**/x), %eax; \
- lcall $7, $0; \
- jb 1b; \
- ret; \
- END(x)
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl NAME(fork);
-
-NAME(fork):;
- movl $(SYS_fork), %eax
- lcall $7, $0
- jae 1f
- neg %eax
- ret
-1:
- test %edx, %edx
- je 2f
- xor %eax, %eax
-2:
- ret;
- END(fork)
-
-/* ==========================================================================
- * NAME(getdents)
- */
- .globl NAME(getdents);
-
-NAME(getdents):
- movl $(SYS_getdents), %eax;
- lcall $7, $0
- jae 1f
- neg %eax
-1:
- ret;
- END(getdents)
-
-/* ==========================================================================
- * NAME(fxstat)
- */
- .globl NAME(fxstat);
-
-NAME(fxstat):;
- movl $(SYS_fxstat), %eax;
- lcall $7, $0
- jae 1f
- neg %eax;
- ret;
-1:
- xor %eax, %eax;
- ret;
- END(fxstat)
-
-/* ==========================================================================
- * NAME(signal)
- */
- .globl NAME(signal);
-
-NAME(signal):;
- movl 4(%esp), %ecx
- movl $(SYS_signal),%eax
-#if 0
- call .L1
-.L1:
- popl %edx
- addl $(NAME(sigreturn)+[.-.L1]), %edx
-#else
- movl $NAME(sigreturn), %edx
-#endif
- lcall $7,$0
- jae 1f
-# movl %eax, 12(%esp)
- neg %eax
- ret
-1:
-# xor %eax, %eax
-# movl %eax, 12(%esp)
- ret
- END(signal)
-
-/* ==========================================================================
- * NAME(sigaction)
- */
- .globl NAME(sigaction);
-
-NAME(sigaction):
- movl $(SYS_sigaction),%eax
-#if 0
- call .L2
-.L2:
- popl %edx
- addl $(NAME(sigreturn)+[.-.L2]), %edx
-#else
- movl $NAME(sigreturn), %edx
-#endif
- lcall $7, $0
- jb 1f
- xor %eax, %eax
- ret
-1:
- neg %eax
- ret
- END(sigaction)
-
- .globl NAME(sigreturn)
-NAME(sigreturn):
- addl $4,%esp
- lcall $0xf, $0
- nop
- nop
- END(sigreturn)
-
-/* ==========================================================================
- * NAME(waitpid)
- */
- .globl NAME(waitpid);
-
-NAME(waitpid):
- .byte 0x9c
- popl %eax
- orl $0x8c4, %eax
- pushl %eax
- .byte 0x9d
- movl $(SYS_wait), %eax
- lcall $7, $0
- jae 2f
- cmpl $(ERESTART), %al
- je NAME(waitpid)
- neg %eax
-3:
- ret
-2:
- movl 8(%esp), %ecx
- test %ecx,%ecx
- je 3b
- mov %edx, (%ecx)
- ret
- END(waitpid)
-
-/* ==========================================================================
- * NAME(uname)
- */
- .globl NAME(uname);
-
-NAME(uname):
- pushl $0
- pushl $0
- pushl 12(%esp)
- subl $4, %esp
- movl $(SYS_utssys), %eax
- .byte 0x9a; .long 0; .word 7;
- jb 1f
- addl $16, %esp
- ret
-1:
- addl $16, %esp
- neg %eax
- ret
- END(uname)
-
-
-/* ==========================================================================
- * machdep_sys_ftruncate
- */
-
-SYSCALL(ftruncate)
-
-/* ==========================================================================
- * machdep_sys_ftime
- */
-
-SYSCALL(ftime)
-
-/* ==========================================================================
- * machdep_sys_gettimeofday()
- */
-
-SYSCALL(gettimeofday)
-
-/* ==========================================================================
- * machdep_sys_kill()
- */
-
-SYSCALL(kill)
-
-/* ==========================================================================
- * pthread_sys_setitimer
- */
- .globl NAME(setitimer);
-
-NAME(setitimer):;
- movl $(SYS_setitimer), %eax;
- lcall $7, $0
- jae 1f
- neg %eax
- ret
-1:
- xor %eax, %eax
- ret;
- END(setitimer)
-
-/* ==========================================================================
- * pthread_sys_sysconf
- */
- .globl NAME(sysconf);
-
-NAME(sysconf):;
- movl $(SYS_sysconf), %eax;
- lcall $7, $0
- jae 1f
- neg %eax
-1:
- ret;
- END(sysconf)
-
-/* ==========================================================================
- * pthread_sys_sysi86()
- */
- .globl NAME(sysi86);
-
-NAME(sysi86):;
- movl $(SYS_sysi86), %eax
- lcall $7, $0
- jae 1f
- neg %eax
-1:
- ret;
- END(sysi86)
-
-
-/* ==========================================================================
- * machdep_sys_brk()
- */
- .globl NAME(brk);
-
-NAME(brk):;
- movl $(SYS_break), %eax
- lcall $7, $0
- jae 1f
- neg %eax
- ret
-1:
- xor %eax, %eax
- ret;
- END(brk)
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl NAME(pipe);
-
-NAME(pipe):;
- movl $(SYS_pipe), %eax;
- lcall $7, $0
- jae 1f
- neg %eax
- ret
-1:
- movl 4(%esp), %ecx
- movl %eax, (%ecx)
- movl %edx, 4(%ecx)
- xor %eax, %eax
- ret;
- END(brk)
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
- .globl NAME(fcntl);
-
-NAME(fcntl):;
- movl $(SYS_fcntl), %eax
- lcall $7, $0
- jae 1f
- neg %eax
-1:
- ret
- END(fcntl)
-
-
-/* ==========================================================================
- * machdep_sys_select()
- */
- .globl NAME(select);
-
-NAME(select):;
- movl $(SYS_select), %eax
- lcall $7, $0
- jae 1f
- cmp $(ERESTART), %eax
- jne 2f
- movl $(EINTR), %eax
-2:
- neg %eax
-1:
- ret
- END(select)
-
-
-/* ==========================================================================
- * setjmp()
- */
- .globl setjmp;
-
-setjmp:
- movl 4(%esp),%eax
- movl %ebx,(%eax)
- movl %esi,4(%eax)
- movl %edi,8(%eax)
- movl %ebp,12(%eax)
- popl %edx
- movl %esp,16(%eax)
- movl %edx,20(%eax)
- subl %eax,%eax
- jmp *%edx
-1: ; .type setjmp,@function ; .size setjmp,1b - setjmp
-
-/* ==========================================================================
- * longjmp()
- */
- .globl longjmp;
-
-longjmp:
- movl 4(%esp),%edx
- movl 8(%esp),%eax
- movl 0(%edx),%ebx
- movl 4(%edx),%esi
- movl 8(%edx),%edi
- movl 12(%edx),%ebp
- movl 16(%edx),%esp
- test %eax,%eax
- jne 1f
- inc %eax
-1:
- jmp *20(%edx)
-1: ; .type longjmp,@function ; .size longjmp,1b - longjmp
diff --git a/mit-pthreads/machdep/syscall-ip22-irix-5.2.S b/mit-pthreads/machdep/syscall-ip22-irix-5.2.S
deleted file mode 100644
index ded0fc55e38..00000000000
--- a/mit-pthreads/machdep/syscall-ip22-irix-5.2.S
+++ /dev/null
@@ -1,106 +0,0 @@
-#include <sys.s>
-#include <sys/regdef.h>
-
-/*
- Kernel syscall interface:
- Input:
- v0 syscall number
- Output:
-
- This macro is similar to SYSCALL in sys/syscall.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- Compile with -DPIC for pic code.
-*/
-
-#ifdef PIC
-#define PICOPT .option pic2
-#else
-#define PICOPT
-#endif
-
-
-#define YSYSCALL(x) \
- PICOPT; \
- .globl machdep_sys_##x; \
- .ent machdep_sys_##x, 0; \
-machdep_sys_##x:; \
- .frame sp,0,ra; \
- .set noreorder; \
- li v0, SYS_##x; \
- syscall; \
- bne a3, zero, 1b; \
- nop; \
- j ra; \
- nop; \
- .end machdep_sys_##x
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- subu v0,zero,v0;
- j ra;
-
-/* ==========================================================================
- * lstat
- */
- PICOPT;
- .globl machdep_sys_lstat;
- .ent machdep_sys_lstat, 0;
-machdep_sys_lstat:;
- .frame sp,0,ra;
- .set noreorder;
- move a2, a1
- move a1, a0
- li a0, 2
- li v0, SYS_lxstat;
- syscall;
- bne a3, zero, 1b;
- nop;
- j ra;
- nop;
- .end machdep_sys_lstat
-
-/* ==========================================================================
- * fstat
- */
- PICOPT;
- .globl machdep_sys_fstat;
- .ent machdep_sys_fstat, 0;
-machdep_sys_fstat:;
- .frame sp,0,ra;
- .set noreorder;
- move a2, a1
- move a1, a0
- li a0, 2
- li v0, SYS_fxstat;
- syscall;
- bne a3, zero, 1b;
- nop;
- j ra;
- nop;
- .end machdep_sys_fstat
-
-/* ==========================================================================
- * stat
- */
- PICOPT;
- .globl machdep_sys_stat;
- .ent machdep_sys_stat, 0;
-machdep_sys_stat:;
- .frame sp,0,ra;
- .set noreorder;
- move a2, a1
- move a1, a0
- li a0, 2
- li v0, SYS_xstat;
- syscall;
- bne a3, zero, 1b;
- nop;
- j ra;
- nop;
- .end machdep_sys_stat
diff --git a/mit-pthreads/machdep/syscall-m68000-netbsd.S b/mit-pthreads/machdep/syscall-m68000-netbsd.S
deleted file mode 100644
index f36286770a2..00000000000
--- a/mit-pthreads/machdep/syscall-m68000-netbsd.S
+++ /dev/null
@@ -1,83 +0,0 @@
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-#define IMM #
-#define SYSCALL(x) .even; ENTRY(machdep_sys_ ## x); \
- movl IMM SYS_ ## x,d0; trap IMM 0; jcs err; rts
-#else /* !__STDC__ */
-#define SYSCALL(x) .even; ENTRY(machdep_sys_/**/x); \
- movl #SYS_/**/x,d0; trap #0; jcs err; rts
-#endif /* !__STDC__ */
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .even
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-err:
- negl d0
- rts
-
-/* ==========================================================================
- * machdep_sys_pipe
- */
- .even
-ENTRY(machdep_sys_pipe);
- movl #SYS_pipe,d0
- trap #0
- jcs err
- movl sp@(4),a0
- movl d0,a0@+
- movl d1,a0@
- clrl d0
- rts
-
-#ifndef SYS___sigsuspend14
- .even
-ENTRY(machdep_sys_sigsuspend)
- movl sp@(4),a0
- movl a0@,sp@(4)
- movl #SYS_compat_13_sigsuspend13,d0
- trap #0
- jcs err
- clrl d0
- rts
-#endif
-
-#ifndef SYS___sigprocmask14
- .even
-ENTRY(machdep_sys_sigprocmask)
- tstl sp@(8)
- jne gotptr
-/* movl #0,sp@(8) /* null mask pointer; block empty set */
- movl #1,sp@(4)
- jra doit
-gotptr:
- movl sp@(8),a0
- movl a0@,sp@(8)
-doit:
- movl #SYS_compat_13_sigprocmask13,d0
- trap #0
- jcs err
- tstl sp@(12)
- jeq out
- movl sp@(12),a0
- movl d0,a0@
-out:
- clrl d0
- rts
-#endif
diff --git a/mit-pthreads/machdep/syscall-powerpc-netbsd.S b/mit-pthreads/machdep/syscall-powerpc-netbsd.S
deleted file mode 100644
index bdda457f116..00000000000
--- a/mit-pthreads/machdep/syscall-powerpc-netbsd.S
+++ /dev/null
@@ -1,185 +0,0 @@
-#include <machine/asm.h>
-#define COMPAT_43
-#include <sys/syscall.h>
-#ifndef __CONCAT
-#include <sys/cdefs.h>
-#endif
-#define CONCAT __CONCAT
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- 0 - system call number
- 3-8 - arguments, as in C
- Output:
- so - (summary overflow) clear iff successful
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-ENTRY(machdep_cerror)
- mflr 0 # Save LR in 0
- stwu 1,-16(1) # allocate new stack frame
- stw 0,20(1) # Stash 0 in stack
- stw 31,8(1) # Stash 31 in stack (since it's callee-saved
- mr 31,3 # and we stash return there)
- bl PIC_PLT(_C_LABEL(__errno))
- stw 31,0(3) # *errno() = err
- lwz 0,20(1) # Restore LR from stack to 0
- neg 3,31 # return -errno to 3
- lwz 31,8(1) # Restore 31 from stack
- mtlr 0
- la 1,16(1) # Restore stack frame
- li 4,-1 # Put -1 in r4 for those syscalls that return
- blr # two values
-
-/* The fork system call is special... */
-ENTRY(machdep_sys_fork)
- li 0, SYS_fork
- sc
- bso PIC_PLT(_C_LABEL(machdep_cerror))
- addi 4,4,-1
- blr
-
-/* The pipe system call is special... */
-ENTRY(machdep_sys_pipe)
- mr 5,3
- li 0,SYS_pipe
- sc
- bso PIC_PLT(_C_LABEL(machdep_cerror))
- stw 3,0(5) # Success, store fds
- stw 4,4(5)
- li 3,0
- blr # And return 0
-
-#ifndef SYS___sigsuspend14
-/* The sigsuspend system call is special... */
-ENTRY(machdep_sys_sigsuspend)
- lwz 3,0(3)
- li 0,SYS_compat_13_sigsuspend13
- sc
- b PIC_PLT(_C_LABEL(machdep_cerror))
-#endif /* SYS_sigsuspend14 */
-
-#ifndef SYS___sigprocmask14
-/* The sigprocmask system call is special... */
-ENTRY(machdep_sys_sigprocmask)
- or. 4,4,4 # Set == NULL ?
- li 6,1 # how = SIG_BLOCK
- beq Ldoit
- lwz 4,0(4) # if not, replace it in r4 with #set
- mr 6,3
-Ldoit: mr 3,6 # ... using sigprocmask(SIG_BLOCK)
- li 0,SYS_compat_13_sigprocmask13
- sc
- bso PIC_PLT(_C_LABEL(machdep_cerror))
- or. 5,5,5 # Check to see if oset requested
- beq Ldone # if oset != NULL
- stw 3,0(5) # *oset = oldmask
-Ldone:
- li 3,0 # return 0
- blr
-#endif /* SYS_sigprocmask14 */
-
-/* More stuff ... */
-
-/* For fstat() we actually syscall fstat13. */
-ENTRY(machdep_sys_fstat)
- li 0, SYS___fstat13
- sc
- bnslr
- b PIC_PLT(_C_LABEL(machdep_cerror))
-
-/* Do we need to save the entire floating point state? I think so... */
-ENTRY(__machdep_save_fp_state)
- stwu 1,-8(1)
- stw 3,4(1)
- stfd 0,0(3)
- stfdu 1,8(3)
- stfdu 2,8(3)
- stfdu 3,8(3)
- stfdu 4,8(3)
- stfdu 5,8(3)
- stfdu 6,8(3)
- stfdu 7,8(3)
- stfdu 8,8(3)
- stfdu 9,8(3)
- stfdu 10,8(3)
- stfdu 11,8(3)
- stfdu 12,8(3)
- stfdu 13,8(3)
- stfdu 14,8(3)
- stfdu 15,8(3)
- stfdu 16,8(3)
- stfdu 17,8(3)
- stfdu 18,8(3)
- stfdu 19,8(3)
- stfdu 20,8(3)
- stfdu 21,8(3)
- stfdu 22,8(3)
- stfdu 23,8(3)
- stfdu 24,8(3)
- stfdu 25,8(3)
- stfdu 26,8(3)
- stfdu 27,8(3)
- stfdu 28,8(3)
- stfdu 29,8(3)
- stfdu 30,8(3)
- stfdu 31,8(3)
- mffs 0
- stfdu 0,8(3)
- lwz 3,4(1)
- lwz 1,0(1)
- blr
-
-ENTRY(__machdep_restore_fp_state)
- stwu 1,-12(1)
- stw 3,4(1)
- stw 4,8(1)
- mr 4,3
- lfdu 1,8(3)
- lfdu 2,8(3)
- lfdu 3,8(3)
- lfdu 4,8(3)
- lfdu 5,8(3)
- lfdu 6,8(3)
- lfdu 7,8(3)
- lfdu 8,8(3)
- lfdu 9,8(3)
- lfdu 10,8(3)
- lfdu 11,8(3)
- lfdu 12,8(3)
- lfdu 13,8(3)
- lfdu 14,8(3)
- lfdu 15,8(3)
- lfdu 16,8(3)
- lfdu 17,8(3)
- lfdu 18,8(3)
- lfdu 19,8(3)
- lfdu 20,8(3)
- lfdu 21,8(3)
- lfdu 22,8(3)
- lfdu 23,8(3)
- lfdu 24,8(3)
- lfdu 25,8(3)
- lfdu 26,8(3)
- lfdu 27,8(3)
- lfdu 28,8(3)
- lfdu 29,8(3)
- lfdu 30,8(3)
- lfdu 31,8(3)
- lfdu 0,8(3)
- mtfsf 127,0
- lfd 0,0(4)
- lwz 3,4(1)
- lwz 4,8(1)
- lwz 1,0(1)
- blr
diff --git a/mit-pthreads/machdep/syscall-r2000-ultrix-4.2.S b/mit-pthreads/machdep/syscall-r2000-ultrix-4.2.S
deleted file mode 100644
index dc891dc37bd..00000000000
--- a/mit-pthreads/machdep/syscall-r2000-ultrix-4.2.S
+++ /dev/null
@@ -1,166 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for decstation with r2000/r3000
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- */
-
- .text
- .ascii "$Id$";
-
-#include <syscall.h>
-#include <machine/regdef.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value. Eventually I want to load the errno value directly
- * into pthread_run->error but until then ...
- */
-machdep_error:
- negu v0, v0 /* Return negative of errno value. */
- j ra
-
-/* ==========================================================================
- * Syscalls already done,
- * Standard Other important BSD sockets
- * fork = 2 select = 93 socket = 97
- * read = 3 readv = 120 connect = 98
- * write = 4 writev = 121 accept = 99
- * open = 5 getdirentries = send = 101
- * close = 6 recv = 102
- * creat = 8 bind = 104
- * link = 9 listen = 106
- * unlink = 10 recvmsg = 113
- * chdir = 12 sendmsg = 114
- * chmod = 15 getsockopt = 118
- * chown = 16 recvfrom = 125
- * lseek = 19 sendto = 133
- * stat = 38 shutdown = 134
- * dup = 41 getpeername = 141
- * pipe = 42
- * execve = 59
- * fstat = 62
- * wait3 = 84
- * dup2 = 90
- * fcntl = 92
- * fchown = 123
- * fchmod = 124
- * rename = 128
- * waitpid = 189
- * ======================================================================= */
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl machdep_sys_fork
- .ent machdep_sys_fork
-
-machdep_sys_fork:
-
- .frame sp,0,ra /* No frame, return address in ra */
-
- li v0,SYS_fork /* Load fork syscall # into v0 */
- syscall
- bne a3,zero,machdep_error /* Error if a3 != 0 */
- beqz v1,__fork_parent /* Second return value = 0, if parent */
- li v0,0
-__fork_parent:
- j ra
-
- .end machdep_sys_fork
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl machdep_sys_pipe
- .ent machdep_sys_pipe
-
-machdep_sys_pipe:
-
- .frame sp,0,ra /* No frame, return address in ra */
-
- li v0,SYS_pipe /* Load pipe syscall # into v0 */
- syscall
- bne a3,zero,machdep_error /* Error if a3 != 0 */
- sw v0, 0(a0)
- sw v1, 4(a0)
- li v0, 0
- j ra
-
- .end machdep_sys_pipe
-
-/* ==========================================================================
- * Other important asm routines.
- * ======================================================================= */
-/* ==========================================================================
- * fake_setjmp()
- */
- .globl fake_setjmp
- .ent fake_setjmp
-
-fake_setjmp:
-
- .frame sp,0,ra /* No frame, return address in ra */
-
- /* Save all the important registers */
- sw ra,8(a0)
- sw gp,124(a0)
- sw sp,128(a0)
- sw s0,76(a0)
- /* More registers needed. */
- j ra
-
- .end fake_longjmp
-
-/* ==========================================================================
- * machdep_sys_longjmp()
- */
- .globl machdep_sys_longjmp
- .ent machdep_sys_longjmp
-
-machdep_sys_longjmp:
-
- .frame sp,0,ra /* No frame, return address in ra */
- li a1,1 /* Load 1 into reg a1 */
- sw a1, 20(a0); /* Load a1 into address a0 + 20 */
- li v0,SYS_sigreturn /* Load sigreturn syscall # into v0 */
- syscall /* Do syscall to do longjmp */
- j ra
-
- .end machdep_sys_longjmp
diff --git a/mit-pthreads/machdep/syscall-romp-bsd.S b/mit-pthreads/machdep/syscall-romp-bsd.S
deleted file mode 100644
index 233f0b9430b..00000000000
--- a/mit-pthreads/machdep/syscall-romp-bsd.S
+++ /dev/null
@@ -1,327 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1993 by John F. Carr, jfc@mit.edu
- *
- * 1.00 93/09/xx proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-/* DO NOT USE COLONS IN THIS FILE, GCC CAN'T HANDLE THEM */
-/* #include <copyright.h> */
-
- .globl .oVncs
- .text
- .align 2
-
-/* ==========================================================================
- * machdep_sys_write()
- */
- .globl _machdep_sys_write
- .globl _.machdep_sys_write
-
- .text 2
-_machdep_sys_write:
- .long _.machdep_sys_write
-
- .text
-_.machdep_sys_write:
- lcs r0,0(r3)
- svc 4(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_read()
- */
- .globl _machdep_sys_read
- .globl _.machdep_sys_read
-
- .text 2
-_machdep_sys_read:
- .long _.machdep_sys_read
-
- .text
-_.machdep_sys_read:
- lcs r0,0(r3)
- svc 3(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_open()
- */
- .globl _machdep_sys_open
- .globl _.machdep_sys_open
-
- .text 2
-_machdep_sys_open:
- .long _.machdep_sys_open
-
- .text
-_.machdep_sys_open:
- lcs r0,0(r2)
- svc 5(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_bind()
- */
- .globl _machdep_sys_bind
- .globl _.machdep_sys_bind
-
- .text 2
-_machdep_sys_bind:
- .long _.machdep_sys_bind
-
- .text
-_.machdep_sys_bind:
- ls r0,0(r3)
- svc 104(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_socket()
- */
- .globl _machdep_sys_socket
- .globl _.machdep_sys_socket
-
- .text 2
-_machdep_sys_socket:
- .long _.machdep_sys_socket
-
- .text
- .align 2
-_.machdep_sys_socket:
- svc 97(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_close()
- */
- .globl _machdep_sys_close
- .globl _.machdep_sys_close
-
- .text 2
-_machdep_sys_close:
- .long _.machdep_sys_close
-
- .text
- .align 2
-_.machdep_sys_close:
- svc 6(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-
-/* ==========================================================================
- * machdep_sys_connect()
- */
- .globl _machdep_sys_connect
- .globl _.machdep_sys_connect
-
- .text 2
-_machdep_sys_connect:
- .long _.machdep_sys_connect
-
- .text
-_.machdep_sys_connect:
- lcs r0,0(r3)
- svc 98(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-/* ==========================================================================
- * machdep_sys_accept()
- */
- .globl _machdep_sys_accept
- .globl _.machdep_sys_accept
-
- .text 2
-_machdep_sys_accept:
- .long _.machdep_sys_accept
-
- .text
-_.machdep_sys_accept:
- lcs r0,0(r3)
- svc 99(r0)
- bntbr r15
- store r2,_errno,r5
- cal r2,-1(r0)
-
-/* ==========================================================================
- * machdep_sys_listen()
- */
- .globl _machdep_sys_listen
- .globl _.machdep_sys_listen
-
- .text 2
- .align 2
-_machdep_sys_listen:
- .long _.machdep_sys_listen
-
- .text
- .align 2
-_.machdep_sys_listen:
- svc 106(r0)
- bntbr r15
- brx r15
- twoc r2,r2
-
-/* ==========================================================================
- * machdep_sys_fcntl()
- */
- .globl _.machdep_sys_fcntl
- .globl _machdep_sys_fcntl
-
- .text 2
-_machdep_sys_fcntl:
- .long _.machdep_sys_fcntl
- .text
-_.machdep_sys_fcntl:
- lcs r0,0(sp)
- svc 92(r0)
- bntbr r15
- store r2,_errno,r5
- brx r15
- cal r2,-1(r0)
-
-/* ==========================================================================
- * machdep_sys_getpeername()
- */
- .globl _machdep_sys_getpeername
- .globl _.machdep_sys_getpeername
-
- .text 2
-_machdep_sys_getpeername:
- .long _.machdep_sys_getpeername
-
- .text
-_.machdep_sys_getpeername:
- ls r0,0(sp)
- svc 141(r0)
- bntbr r15
- brx r15
- twoc r2,r2
-
-
-/* ==========================================================================
- * machdep_sys_getsockopt()
- */
- .globl _machdep_sys_getsockopt
- .globl _.machdep_sys_getsockopt
-
- .text 2
-_machdep_sys_getsockopt:
- .long _.machdep_sys_getsockopt
-
- .text
-_.machdep_sys_getsockopt:
- ls r0,0(sp)
- svc 118(r0)
- bntbr r15
- brx r15
- twoc r2,r2
-
-
-/* ==========================================================================
- * machdep_sys_select()
- */
-
- .globl _.machdep_sys_select
- .globl _machdep_sys_select
-
- .text 2
-_machdep_sys_select:
- .long _.machdep_sys_select
- .text
-_.machdep_sys_select:
- svc 93(r0)
- bntbr r15
- brx r15
- twoc r2,r2
-
-/* ==========================================================================
- * __tsh()
- */
- .globl _._tsh
- .globl __tsh
- .text 2
-__tsh: .long _._tsh
- .text
- .align 2
-_._tsh:
- brx r15
- tsh r2,0(r2)
-
-
-/* ==========================================================================
- * __pthread_save()
- */
- .globl __pthread_save
- .globl _._pthread_save
- .text 2
-__pthread_save:
- .long _._pthread_save
- .text
- .align 2
-_._pthread_save:
- ail r5,r4,0
- jne 1f
- mr r4,sp
- lis r5,0
- stm r4,0(r2)
- brx r15
- lis r2,0
-1:
- mr r0,r15 # save old return address
- ls r15,0(r4) # new return address
- mr r5,r4 # r0 to restore
- mr r4,r3 # sp to restore
- stm r4,0(r2)
- brx r0
- lis r2,0
-
-
-/* ==========================================================================
- * __pthread_restore()
- */
- .globl __pthread_restore
- .globl _._pthread_restore
- .text 2
-__pthread_restore:
- .long _._pthread_restore
- .text
- .align 2
-_._pthread_restore:
- lm r4,0(r2)
- mr r0,r5
- lis r2,1
- brx r15
- mr sp,r4
-
-
diff --git a/mit-pthreads/machdep/syscall-sparc-netbsd-1.1.S b/mit-pthreads/machdep/syscall-sparc-netbsd-1.1.S
deleted file mode 100644
index 9c4da4b1325..00000000000
--- a/mit-pthreads/machdep/syscall-sparc-netbsd-1.1.S
+++ /dev/null
@@ -1,102 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _machdep_sys_pipe
-
-_machdep_sys_pipe:
- mov %o0, %o2
- mov SYS_pipe, %g1
- ta 0
- bcs 1b
- nop
- st %o0, [ %o2 ]
- st %o1, [ %o2 + 4 ]
- retl
- mov %g0, %o0
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- mov SYS_fork, %g1;
- ta 0;
- bcs 1b;
- nop;
- dec %o1;
- retl;
- and %o0, %o1, %o0; ! return 0 in child, pid in parent
-
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _machdep_sys_sigprocmask;
-
-_machdep_sys_sigprocmask:;
-
- ld [%o1], %o1;
- mov SYS_sigprocmask, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _machdep_sys_sigsuspend;
-
-_machdep_sys_sigsuspend:;
-
- ld [%o0], %o0;
- mov SYS_sigsuspend, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
diff --git a/mit-pthreads/machdep/syscall-sparc-netbsd-1.3.S b/mit-pthreads/machdep/syscall-sparc-netbsd-1.3.S
deleted file mode 100644
index 74a51e756b7..00000000000
--- a/mit-pthreads/machdep/syscall-sparc-netbsd-1.3.S
+++ /dev/null
@@ -1,172 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _C_LABEL(machdep_sys_##x); \
- \
-_C_LABEL(machdep_sys_##x):; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _C_LABEL(machdep_sys_pipe)
-
-_C_LABEL(machdep_sys_pipe):
- mov %o0, %o2
- mov SYS_pipe, %g1
- ta 0
- bcs 1b
- nop
- st %o0, [ %o2 ]
- st %o1, [ %o2 + 4 ]
- retl
- mov %g0, %o0
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _C_LABEL(machdep_sys_fork);
-
-_C_LABEL(machdep_sys_fork):;
-
- mov SYS_fork, %g1;
- ta 0;
- bcs 1b;
- nop;
- dec %o1;
- retl;
- and %o0, %o1, %o0; ! return 0 in child, pid in parent
-
-#ifndef SYS___sigprocmask14
-/* ==========================================================================
- * machdep_sys_sigprocmask()
- */
- .globl _C_LABEL(machdep_sys_sigprocmask);
-
-_C_LABEL(machdep_sys_sigprocmask):;
-
- ld [%o1], %o1;
- mov SYS_sigprocmask, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
-#endif
-
-#ifndef SYS___sigsuspend14
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
- .globl _C_LABEL(machdep_sys_sigsuspend);
-
-_C_LABEL(machdep_sys_sigsuspend):;
-
- ld [%o0], %o0;
- mov SYS_sigsuspend, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
-#endif
-
-/* ==========================================================================
- * machdep_sys_fstat()
- */
- .globl _C_LABEL(machdep_sys_fstat);
-
-_C_LABEL(machdep_sys_fstat):;
-
- mov SYS___fstat13, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys___syscall()
- */
-_machdep_sys___syscall:;
-
- mov SYS___syscall, %g1;
- ta 0;
- bcs 1b;
- nop;
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_lseek()
- */
- .global _C_LABEL(machdep_sys_lseek)
-
-_C_LABEL(machdep_sys_lseek):
- save %sp,-112,%sp
- mov %i1,%o4
- mov %i2,%o5
- st %i3,[%sp+92]
- mov 0,%o0
- mov SYS_lseek,%o1
- mov %i0,%o2
- call _machdep_sys___syscall,0
- mov 0,%o3
- mov %o0,%i0
- mov %o1,%i1
- ret
- restore
-
-/* ==========================================================================
- * machdep_sys_ftruncate()
- */
- .global _C_LABEL(machdep_sys_ftruncate)
-
-_C_LABEL(machdep_sys_ftruncate):
- save %sp,-104,%sp
- mov %i1,%o4
- mov %i2,%o5
- mov 0,%o0
- mov SYS_ftruncate,%o1
- mov %i0,%o2
- call _machdep_sys___syscall,0
- mov 0,%o3
- mov %o0,%o1
- sra %o0,31,%o0
- ret
- restore %g0,%o1,%o0
diff --git a/mit-pthreads/machdep/syscall-sparc-sunos-4.1.3.S b/mit-pthreads/machdep/syscall-sparc-sunos-4.1.3.S
deleted file mode 100644
index ec293b0ca3f..00000000000
--- a/mit-pthreads/machdep/syscall-sparc-sunos-4.1.3.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _machdep_sys_pipe
-
-_machdep_sys_pipe:
- mov %o0, %o2
- mov SYS_pipe, %g1
- ta 0
- bcs 1b
- nop
- st %o0, [ %o2 ]
- st %o1, [ %o2 + 4 ]
- retl
- mov %g0, %o0
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- mov SYS_fork, %g1;
- ta 0;
- bcs 1b;
- nop;
- tst %o1
- bne,a __fork_parent
- mov %g0, %o0
-__fork_parent:;
- retl
-
-/* POSIX-compliant getpgrp() takes no arguments. The SunOS syscall wants
- one, and gives the POSIXy result if that argument is zero. */
- .globl _getpgrp
-_getpgrp:
- mov SYS_getpgrp, %g1
- mov 0, %i0
- ta 0
- bcs 1b
- nop
- retl
- nop
-
-#if 0
-/* I think this bit of magic will do the right thing for other syscalls.
- We get here with the new `errno' code in %o0. It should get stored in
- *__error(), and -1 returned to the caller. */
- .globl cerror
-cerror:
- save %sp,-104,%sp
- /* Now value is in %i0. Store it in *__error(). */
- call ___error
- nop
- st %i0,[%o0]
-
- /* Now also store a copy in global variable errno, for routines
- like isatty that want to examine it and which haven't been
- converted yet. */
- sethi %hi(_errno), %o0
- st %i0,[%o0+%lo(_errno)]
-
-#if 0 /* use this if you want -errno returned */
- sub %r0,%i0,%i0
-#else /* return -1 */
- mov -1,%i0
-#endif
- retl
- restore
-#endif
diff --git a/mit-pthreads/machdep/syscall-sparc-sunos-5.3.S b/mit-pthreads/machdep/syscall-sparc-sunos-5.3.S
deleted file mode 100644
index 822055ad04e..00000000000
--- a/mit-pthreads/machdep/syscall-sparc-sunos-5.3.S
+++ /dev/null
@@ -1,65 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#define _ASM
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl machdep_sys_fork;
-
-machdep_sys_fork:;
-
- mov SYS_fork, %g1;
- ta 0;
- bcs 1b;
- nop;
- tst %o1
- bne,a __fork_parent
- mov %g0, %o0
-__fork_parent:;
- retl
- nop; /* Added by monty to keep sparc assembler happy */
-
-/* ==========================================================================
- * Berkeley socket stuff
- *
- * ==========================================================================
- * machdep_sys_socketcall()
- */
- .globl machdep_sys_socketcall;
-
-machdep_sys_socketcall:;
-
- mov 83, %g1;
- ta 0;
- bcs,a 2b;
- sub %r0,%o0,%o0;
- retl
- nop; /* Added by monty to keep sparc assembler happy */
diff --git a/mit-pthreads/machdep/syscall-sparc-sunos4.S b/mit-pthreads/machdep/syscall-sparc-sunos4.S
deleted file mode 100644
index ec293b0ca3f..00000000000
--- a/mit-pthreads/machdep/syscall-sparc-sunos4.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-/* ==========================================================================
- * machdep_sys_pipe()
- */
- .globl _machdep_sys_pipe
-
-_machdep_sys_pipe:
- mov %o0, %o2
- mov SYS_pipe, %g1
- ta 0
- bcs 1b
- nop
- st %o0, [ %o2 ]
- st %o1, [ %o2 + 4 ]
- retl
- mov %g0, %o0
-
-/* ==========================================================================
- * machdep_sys_fork()
- */
- .globl _machdep_sys_fork;
-
-_machdep_sys_fork:;
-
- mov SYS_fork, %g1;
- ta 0;
- bcs 1b;
- nop;
- tst %o1
- bne,a __fork_parent
- mov %g0, %o0
-__fork_parent:;
- retl
-
-/* POSIX-compliant getpgrp() takes no arguments. The SunOS syscall wants
- one, and gives the POSIXy result if that argument is zero. */
- .globl _getpgrp
-_getpgrp:
- mov SYS_getpgrp, %g1
- mov 0, %i0
- ta 0
- bcs 1b
- nop
- retl
- nop
-
-#if 0
-/* I think this bit of magic will do the right thing for other syscalls.
- We get here with the new `errno' code in %o0. It should get stored in
- *__error(), and -1 returned to the caller. */
- .globl cerror
-cerror:
- save %sp,-104,%sp
- /* Now value is in %i0. Store it in *__error(). */
- call ___error
- nop
- st %i0,[%o0]
-
- /* Now also store a copy in global variable errno, for routines
- like isatty that want to examine it and which haven't been
- converted yet. */
- sethi %hi(_errno), %o0
- st %i0,[%o0+%lo(_errno)]
-
-#if 0 /* use this if you want -errno returned */
- sub %r0,%i0,%i0
-#else /* return -1 */
- mov -1,%i0
-#endif
- retl
- restore
-#endif
diff --git a/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.1.S b/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.1.S
deleted file mode 100644
index a2941ece7c9..00000000000
--- a/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.1.S
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <machine/asm.h>
-#define COMPAT_43
-#include <sys/syscall.h>
-#define CHMK() call_pal 0x83
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl machdep_sys_##x ;\
- .ent machdep_sys_##x, 0 ;\
-machdep_sys_##x: ;\
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
- beq a3, Lsys_noerr_##x ;\
- br gp, Lsys_err_##x ;\
-Lsys_err_##x: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-Lsys_noerr_##x:
-
-#define SIMPLE_SYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
-#define XSYSCALL(x) SIMPLE_SYSCALL(x)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.3.S b/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.3.S
deleted file mode 100644
index 12595feabc1..00000000000
--- a/mit-pthreads/machdep/syscall-template-alpha-netbsd-1.3.S
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <machine/asm.h>
-#define COMPAT_43
-#include <sys/syscall.h>
-#define CHMK() call_pal 0x83
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl machdep_sys_##x ;\
- .ent machdep_sys_##x, 0 ;\
-machdep_sys_##x: ;\
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
- beq a3, Lsys_noerr_##x ;\
- br gp, Lsys_err_##x ;\
-Lsys_err_##x: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-Lsys_noerr_##x:
-
-#define SIMPLE_SYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
-#define XSYSCALL(x) SIMPLE_SYSCALL(x)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-alpha-osf1.S b/mit-pthreads/machdep/syscall-template-alpha-osf1.S
deleted file mode 100644
index bc4653b5f9e..00000000000
--- a/mit-pthreads/machdep/syscall-template-alpha-osf1.S
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <asm.h>
-#include <regdef.h>
-#define COMPAT_43
-#include <syscall.h>
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- v0 - system call number
- a* - arguments, as in C
- Output:
- a3 - zero iff successful
- v0 - errno value on failure, else result
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- .align 4 ;\
- .globl machdep_sys_##x ;\
- .ent machdep_sys_##x, 0 ;\
-machdep_sys_##x: ;\
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
- beq a3, 2f ;\
- br gp, 1f ;\
-1: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
- jmp zero, machdep_cerror ;\
-2:
-
-#define SIMPLE_SYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
-#define XSYSCALL(x) SIMPLE_SYSCALL(x)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-arm32-netbsd-1.3.S b/mit-pthreads/machdep/syscall-template-arm32-netbsd-1.3.S
deleted file mode 100644
index 923d2c03a75..00000000000
--- a/mit-pthreads/machdep/syscall-template-arm32-netbsd-1.3.S
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _C_LABEL(machdep_sys_##x); \
- \
-_C_LABEL(machdep_sys_##x):; \
- \
- swi SYS_##x; \
- bcs 1b; \
- mov r15, r14;
-
-#else
-
-#define SYSCALL(x) \
- .globl _C_LABEL(_machdep_sys_/**/x); \
- \
-_C_LABEL(machdep_sys_/**/x):; \
- \
- swi SYS_/**/x; \
- bcs 1b; \
- mov r15, r14;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 0
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- rsb r0, r0, #0x00000000
- mvn r1, #0x00000000
- mov r15, r14
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-hppa-hpux-10.20.S b/mit-pthreads/machdep/syscall-template-hppa-hpux-10.20.S
deleted file mode 100644
index 0123b1deee7..00000000000
--- a/mit-pthreads/machdep/syscall-template-hppa-hpux-10.20.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ==== syscall.S ============================================================
- * Written 1996 by Stefan Grefen, grefen@convex.com
- */
-
-#include <sys/syscall.h>
-
-#define _CAT(a,b)a##b
-#define CAT(a,b)_CAT(a,b)
-
-#define MKNAME(a)CAT(a,SYSCALL_NAME)
-
- .CODE
-machdep_error
- sub %r0,%r28,%r28
- bv,n %r0(%r2)
-
- .label MKNAME(machdep_sys_)
- .PROC
- .CALLINFO NO_CALLS,FRAME=0
- ldil -0x80000,%r1
- ble 4(%sr7,%r1)
- ldi MKNAME(SYS_),%r22
- or,= %r0,%r22,%r0
- b,n machdep_error
- bv,n %r0(%r2)
- .PROCEND
- .EXPORT MKNAME(machdep_sys_)
diff --git a/mit-pthreads/machdep/syscall-template-hppa-hpux-9.03.S b/mit-pthreads/machdep/syscall-template-hppa-hpux-9.03.S
deleted file mode 100644
index 0123b1deee7..00000000000
--- a/mit-pthreads/machdep/syscall-template-hppa-hpux-9.03.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ==== syscall.S ============================================================
- * Written 1996 by Stefan Grefen, grefen@convex.com
- */
-
-#include <sys/syscall.h>
-
-#define _CAT(a,b)a##b
-#define CAT(a,b)_CAT(a,b)
-
-#define MKNAME(a)CAT(a,SYSCALL_NAME)
-
- .CODE
-machdep_error
- sub %r0,%r28,%r28
- bv,n %r0(%r2)
-
- .label MKNAME(machdep_sys_)
- .PROC
- .CALLINFO NO_CALLS,FRAME=0
- ldil -0x80000,%r1
- ble 4(%sr7,%r1)
- ldi MKNAME(SYS_),%r22
- or,= %r0,%r22,%r0
- b,n machdep_error
- bv,n %r0(%r2)
- .PROCEND
- .EXPORT MKNAME(machdep_sys_)
diff --git a/mit-pthreads/machdep/syscall-template-i386-bsdi-2.0.S b/mit-pthreads/machdep/syscall-template-i386-bsdi-2.0.S
deleted file mode 100644
index 3299f49195f..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-bsdi-2.0.S
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x##; \
- \
-_machdep_sys_##x##:; \
- \
- movl $(SYS_##x##), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x/**/; \
- \
-_machdep_sys_/**/x/**/:; \
- \
- movl $(SYS_/**/x/**/), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-freebsd-2.0.S b/mit-pthreads/machdep/syscall-template-i386-freebsd-2.0.S
deleted file mode 100644
index 1906a949c8b..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-freebsd-2.0.S
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYS(X) SYS_##X
-#ifdef __ELF__
-#define NAME(X) machdep_sys_##X
-#else
-#define NAME(X) _machdep_sys_##X
-#endif
-
-#else
-
-#define SYS(X) SYS_/**/X
-#ifdef __ELF__
-#define NAME(X) machdep_sys_/**/X
-#else
-#define NAME(X) _machdep_sys_/**/X
-#endif
-
-#endif
-
-#ifdef __ELF__
-#define END(X) 5: ; .type NAME(X),@function ; .size NAME(X),5b - NAME(X)
-#define KERNCALL int $0x80
-#else
-#define END(X)
-#define KERNCALL .byte 0x9a; .long 0; .word 7;
-#endif
-
-#define SYSCALL(x) \
- .globl NAME(x); \
- \
-NAME(x):; \
- movl $(SYS(x)), %eax; \
- KERNCALL; \
- jb 1b; \
- ret; \
- END(x)
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-netbsd-1.1.S b/mit-pthreads/machdep/syscall-template-i386-netbsd-1.1.S
deleted file mode 100644
index c5e76bb4538..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-netbsd-1.1.S
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- movl $(SYS_##x), %eax; \
- int $0x80; \
- jb 1b; \
- ret;
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- int $0x80; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-netbsd-1.3.S b/mit-pthreads/machdep/syscall-template-i386-netbsd-1.3.S
deleted file mode 100644
index d6dffc35132..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-netbsd-1.3.S
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _C_LABEL(machdep_sys_##x); \
- \
-_C_LABEL(machdep_sys_##x):; \
- \
- movl $(SYS_##x), %eax; \
- int $0x80; \
- jb 1b; \
- ret;
-
-#else
-
-#define _SYSCALL(x) \
- .globl _C_LABEL(machdep_sys_/**/x); \
- \
-_C_LABEL(machdep_sys_/**/x):; \
- \
- movl $(SYS_/**/x), %eax; \
- int $0x80; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-netbsd1.0.S b/mit-pthreads/machdep/syscall-template-i386-netbsd1.0.S
deleted file mode 100644
index 83a2405ed51..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-netbsd1.0.S
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- movl $(SYS_##x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-openbsd-2.0.S b/mit-pthreads/machdep/syscall-template-i386-openbsd-2.0.S
deleted file mode 100644
index 34fb5caaa43..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-openbsd-2.0.S
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <sys/syscall.h>
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x##; \
- \
-_machdep_sys_##x:##; \
- \
- movl $(SYS_##x##), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-_machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jb 1b; \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- neg %eax
- ret
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-i386-sco-3.2v5.S b/mit-pthreads/machdep/syscall-template-i386-sco-3.2v5.S
deleted file mode 100644
index 753475b5c3d..00000000000
--- a/mit-pthreads/machdep/syscall-template-i386-sco-3.2v5.S
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <sys/errno.h>
-#include <sys/syscall.h>
-
-#ifdef _SCO_ELF
-
-#define NAME(X) machdep_sys_##X
-#define END(X) 1: ; .type NAME(X),@function ; .size NAME(X),1b - NAME(X)
-#define GETBX(X) \
- push %ebx; \
- call 1f; \
-1: \
- popl %ebx;
-#else
-
-#define NAME(X) _machdep_sys_##X
-#define END(X)
-
-#endif
-
-#ifdef __STDC__
-
-#define SYSCALL(x) \
- .globl NAME(x); \
- \
-NAME(x):; \
- movl $(SYS_##x##), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jae 1f; \
- cmp $(ERESTART), %eax; \
- je NAME(x); \
- neg %eax; \
-1: \
- ret; \
- END(x)
-
-#else
-
-#define SYSCALL(x) \
- .globl _machdep_sys_/**/x; \
- \
-machdep_sys_/**/x:; \
- \
- movl $(SYS_/**/x), %eax; \
- .byte 0x9a; .long 0; .word 7; \
- jae 1f; \
- neg %eax;
-1: \
- ret;
-
-#endif
-
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-ip22-irix-5.2.S b/mit-pthreads/machdep/syscall-template-ip22-irix-5.2.S
deleted file mode 100644
index 722b001671b..00000000000
--- a/mit-pthreads/machdep/syscall-template-ip22-irix-5.2.S
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <sys.s>
-#include <sys/regdef.h>
-/* #include <sys/asm.h> */
-
-/*
- Kernel syscall interface:
- Input:
- v0 syscall number
- Output:
-
- This macro is similar to SYSCALL in sys/syscall.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- Compile with -DPIC for pic code.
-*/
-
-#ifdef PIC
-#define PICOPT .option pic2
-#else
-#define PICOPT
-#endif
-
-
-#define YSYSCALL(x) \
- PICOPT; \
- .globl machdep_sys_##x; \
- .ent machdep_sys_##x, 0; \
-machdep_sys_##x:; \
- .frame sp,0,ra; \
- .set noreorder; \
- li v0, SYS_##x; \
- syscall; \
- bne a3, zero, 1b; \
- nop; \
- j ra; \
- nop; \
- .end machdep_sys_##x
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- subu v0,zero,v0;
- j ra;
-
-#define XSYSCALL(x) YSYSCALL(x)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-m68000-netbsd.S b/mit-pthreads/machdep/syscall-template-m68000-netbsd.S
deleted file mode 100644
index ce16bb5523c..00000000000
--- a/mit-pthreads/machdep/syscall-template-m68000-netbsd.S
+++ /dev/null
@@ -1,43 +0,0 @@
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-
-#ifdef __STDC__
-#define IMM #
-#define SYSCALL(x) .even; \
- ENTRY(machdep_sys_ ## x); \
- movl IMM SYS_ ## x,d0; \
- trap IMM 0; \
- jcs err; \
- rts
-#else /* !__STDC__ */
-#define SYSCALL(x) .even; ENTRY(machdep_sys_/**/x); \
- movl #SYS_/**/x,d0; trap #0; jcs err; rts
-#endif /* !__STDC__ */
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .even
-
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-err:
- negl d0
- rts
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-powerpc-netbsd.S b/mit-pthreads/machdep/syscall-template-powerpc-netbsd.S
deleted file mode 100644
index 1755c1ab2e8..00000000000
--- a/mit-pthreads/machdep/syscall-template-powerpc-netbsd.S
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <machine/asm.h>
-#define COMPAT_43
-#include <sys/syscall.h>
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-
-#ifdef SYS___sigaction14
-#define SYS_sigaction SYS___sigaction14
-#endif
-
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-#undef SYSCALL
-
-/* Kernel syscall interface:
- Input:
- 0 - system call number
- 3-8 - arguments, as in C
- Output:
- so - (summary overflow) clear iff successful
-
- This macro is similar to SYSCALL in asm.h, but not completely.
- There's room for optimization, if we assume this will continue to
- be assembled as one file.
-
- This macro expansions does not include the return instruction.
- If there's no other work to be done, use something like:
- SYSCALL(foo) ; ret
- If there is other work to do (in fork, maybe?), do it after the
- SYSCALL invocation. */
-
-#define SYSCALL(x) \
- ENTRY(machdep_sys_ ## x) \
- li 0, SYS_ ## x ; \
- sc ; \
- bnslr ; \
- b PIC_PLT(_C_LABEL(machdep_cerror))
-
-#define XSYSCALL(x) SYSCALL(x) ; blr
-
- XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-r2000-ultrix-4.2.S b/mit-pthreads/machdep/syscall-template-r2000-ultrix-4.2.S
deleted file mode 100644
index 575fe3c3d74..00000000000
--- a/mit-pthreads/machdep/syscall-template-r2000-ultrix-4.2.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Machine dependent syscalls for decstation with r2000/r3000
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- */
-
- .text
- .ascii "$Id$";
-
-#include <syscall.h>
-#include <machine/regdef.h>
-
-#define SYSCALL(x) \
- \
- .globl machdep_sys_##x; \
- .ent machdep_sys_##x; \
- \
-machdep_sys_##x:; \
- \
- .frame sp,0,ra; /* No frame, return address in ra */ \
- \
- li v0,SYS_##x; /* Load syscall # into v0 */ \
- syscall; \
- bne a3,zero,machdep_error; /* Error if a3 != 0 */ \
- j ra; \
- \
- .end machdep_sys_##x
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 2
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value. Eventually I want to load the errno value directly
- * into pthread_run->error but until then ...
- */
-machdep_error:
- negu v0, v0 /* Return negative of errno value. */
- j ra
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.1.S b/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.1.S
deleted file mode 100644
index 2d07892a315..00000000000
--- a/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.1.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl; \
- nop
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.3.S b/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.3.S
deleted file mode 100644
index 2caad5c3437..00000000000
--- a/mit-pthreads/machdep/syscall-template-sparc-netbsd-1.3.S
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#include <machine/asm.h>
-#include <sys/syscall.h>
-
-#ifdef SYS___sigsuspend14
-#define SYS_sigsuspend SYS___sigsuspend14
-#endif
-#ifdef SYS___sigprocmask14
-#define SYS_sigprocmask SYS___sigprocmask14
-#endif
-
-#define SYSCALL(x) \
- .globl _C_LABEL(machdep_sys_##x); \
- \
-_C_LABEL(machdep_sys_##x):; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl; \
- nop
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/syscall-template-sparc-sunos-5.3.S b/mit-pthreads/machdep/syscall-template-sparc-sunos-5.3.S
deleted file mode 100644
index 65a796a057d..00000000000
--- a/mit-pthreads/machdep/syscall-template-sparc-sunos-5.3.S
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#ifndef lint
- .text
- .asciz "$Id$";
-#endif
-
-#define _ASM
-#include <sys/syscall.h>
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-#define concat2(a,b) a ## b
-#define concat(a,b) concat2(a,b)
-#define SYSval concat(SYS_,SYSCALL_NAME)
-#define procname concat(machdep_sys_,SYSCALL_NAME)
-
- .globl procname
-
-procname:
- mov SYSval, %g1
- ta 0
- bcs,a 2b
- sub %r0,%o0,%o0
- retl
- nop
diff --git a/mit-pthreads/machdep/syscall-template-sparc-sunos4.S b/mit-pthreads/machdep/syscall-template-sparc-sunos4.S
deleted file mode 100644
index 2d07892a315..00000000000
--- a/mit-pthreads/machdep/syscall-template-sparc-sunos4.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/* ==== syscall.S ============================================================
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- */
-
-#include <sys/syscall.h>
-
-#define SYSCALL(x) \
- .globl _machdep_sys_##x; \
- \
-_machdep_sys_##x:; \
- \
- mov SYS_##x, %g1; \
- ta 0; \
- bcs,a 2b; \
- sub %r0,%o0,%o0; \
- retl; \
- nop
-
-/*
- * Initial asm stuff for all functions.
- */
- .text
- .align 4
-
-/* ==========================================================================
- * error code for all syscalls. The error value is returned as the negative
- * of the errno value.
- */
-
-1:
- sub %r0, %o0, %o0
-2:
- retl
- nop
-
-#define XSYSCALL(NAME) SYSCALL(NAME)
-
-XSYSCALL(SYSCALL_NAME)
diff --git a/mit-pthreads/machdep/ultrix-4.2/__math.h b/mit-pthreads/machdep/ultrix-4.2/__math.h
deleted file mode 100755
index 6249d720039..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__math.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#define HUGE_VAL 1.8e+308
-
diff --git a/mit-pthreads/machdep/ultrix-4.2/__signal.h b/mit-pthreads/machdep/ultrix-4.2/__signal.h
deleted file mode 100755
index 68364772a6a..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__signal.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#include <ansi_compat.h>
-
-#define NSIG 32
-
-#define SIGHUP 1 /* hangup */
-#define SIGINT 2 /* interrupt */
-#define SIGQUIT 3 /* quit */
-#define SIGILL 4 /* illegal instruction (not reset when caught) */
-#define SIGTRAP 5 /* trace trap (not reset when caught) */
-#define SIGIOT 6 /* IOT instruction */
-#define SIGEMT 7 /* EMT instruction */
-#define SIGFPE 8 /* floating point exception */
-#define SIGKILL 9 /* kill (cannot be caught or ignored) */
-#define SIGBUS 10 /* bus error */
-#define SIGSEGV 11 /* segmentation violation */
-#define SIGSYS 12 /* bad argument to system call */
-#define SIGPIPE 13 /* write on a pipe with no one to read it */
-#define SIGALRM 14 /* alarm clock */
-#define SIGTERM 15 /* software termination signal from kill */
-#define SIGURG 16 /* urgent condition on IO channel */
-#define SIGSTOP 17 /* sendable stop signal not from tty */
-#define SIGTSTP 18 /* stop signal from tty */
-#define SIGCONT 19 /* continue a stopped process */
-#define SIGCHLD 20 /* to parent on child stop or exit */
-#define SIGTTIN 21 /* to readers pgrp upon background tty read */
-#define SIGTTOU 22 /* like TTIN for output if (tp->t_local&LTOSTOP) */
-#define SIGIO 23 /* input/output possible signal */
-#define SIGXCPU 24 /* exceeded CPU time limit */
-#define SIGXFSZ 25 /* exceeded file size limit */
-#define SIGVTALRM 26 /* virtual time alarm */
-#define SIGPROF 27 /* profiling time alarm */
-#define SIGWINCH 28 /* window size changes */
-#define SIGLOST 29 /* Sys-V rec lock: notify user upon server crash */
-#define SIGUSR1 30 /* User signal 1 (from SysV) */
-#define SIGUSR2 31 /* User signal 2 (from SysV) */
-
-/* Add System V signal definitions (DLB001) */
-#define SIGCLD SIGCHLD /* System V name for SIGCHLD */
-#define SIGABRT SIGIOT
-
-typedef long sig_atomic_t;
-typedef unsigned int sigset_t;
-
-struct sigaction {
- void (*sa_handler)(); /* signal handler */
- sigset_t sa_mask; /* signal mask to apply */
- int sa_flags; /* see signal options below */
-};
-
-/* Defines for sigprocmask() call. POSIX.
- */
-#define SIG_BLOCK 1 /* Add these signals to block mask */
-#define SIG_UNBLOCK 2 /* Remove these signals from block mask */
-#define SIG_SETMASK 3 /* Set block mask to this mask */
-
-#define SIG_ERR ((void (*)())(-1))
-#define SIG_DFL ((void (*)())( 0))
-#define SIG_IGN ((void (*)())( 1))
-
-
-#define __SIGFILLSET 0xffffffff
-#define __SIGEMPTYSET 0
-#define __SIGADDSET(s,n) ((*s) |= (1 << ((n) - 1)))
-#define __SIGDELSET(s,n) ((*s) &= ~(1 << ((n) - 1)))
-#define __SIGISMEMBER(s,n) ((*s) & (1 << ((n) - 1)))
-
diff --git a/mit-pthreads/machdep/ultrix-4.2/__stdio.h b/mit-pthreads/machdep/ultrix-4.2/__stdio.h
deleted file mode 100755
index 3f6aee47de3..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__stdio.h
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#if ! defined(_SIZE_T_)
-#define _SIZE_T_
-typedef pthread_size_t size_t;
-#endif
-
-typedef pthread_fpos_t fpos_t;
diff --git a/mit-pthreads/machdep/ultrix-4.2/__stdlib.h b/mit-pthreads/machdep/ultrix-4.2/__stdlib.h
deleted file mode 100755
index e2e52cc41c9..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__stdlib.h
+++ /dev/null
@@ -1,21 +0,0 @@
-
-#ifndef _SYS___STDLIB_H_
-#define _SYS___STDLIB_H_
-
-#include <ansi_compat.h>
-
-#ifndef _SIZE_T_
-#define _SIZE_T_
-typedef unsigned int size_t;
-#endif
-
-#ifndef _WCHAR_T_
-#define _WCHAR_T_
-typedef unsigned int wchar_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/__string.h b/mit-pthreads/machdep/ultrix-4.2/__string.h
deleted file mode 100755
index 03039b5cf73..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__string.h
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#if ! defined(_SIZE_T_)
-#define _SIZE_T_
-typedef pthread_size_t size_t;
-#endif
-
-/* Non-standard Ultrix string routines. */
-#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-int bcmp __P_((const void *, const void *, size_t));
-void bcopy __P_((const void *, void *, size_t));
-void bzero __P_((void *, size_t));
-char *index __P_((const char *, int));
-char *rindex __P_((const char *, int));
-__END_DECLS
-#endif
-
diff --git a/mit-pthreads/machdep/ultrix-4.2/__time.h b/mit-pthreads/machdep/ultrix-4.2/__time.h
deleted file mode 100755
index dddc54430bc..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__time.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS__TIME_H_
-#define _SYS__TIME_H_
-
-#include <ansi_compat.h>
-
-#ifndef _CLOCK_T_
-#define _CLOCK_T_
-typedef int clock_t;
-#endif
-
-#ifndef _TIME_T_
-#define _TIME_T_
-typedef int time_t;
-#endif
-
-#ifndef _SIZE_T_
-#define _SIZE_T_
-typedef unsigned int size_t;
-#endif
-
-#define CLOCKS_PER_SEC 1000000
-
-#if !defined(_ANSI_SOURCE)
-#define CLK_TCK 60
-#endif /* not ANSI */
-
-#endif /* !_SYS__TIME_H_ */
diff --git a/mit-pthreads/machdep/ultrix-4.2/__unistd.h b/mit-pthreads/machdep/ultrix-4.2/__unistd.h
deleted file mode 100755
index f570242ef0d..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/__unistd.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)stdlib.h 5.13 (Berkeley) 6/4/91
- * $Id$
- */
-
-#ifndef _SYS___UNISTD_H_
-#define _SYS___UNISTD_H_
-
-#include <sys/types.h>
-
-#ifndef _SSIZE_T_
-#define _SSIZE_T_
-typedef int ssize_t;
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/cdefs.h b/mit-pthreads/machdep/ultrix-4.2/cdefs.h
deleted file mode 100755
index 4e1dc1c280d..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/cdefs.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* ==== cdefs.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Similar to the BSD cdefs.h file.
- *
- * 1.00 94/01/26 proven
- * -Started coding this file.
- */
-
-#ifndef _PTHREAD_SYS_CDEFS_H_
-#define _PTHREAD_SYS_CDEFS_H_
-
-/* Stuff for compiling */
-#if defined(__GNUC__)
-#if defined(__cplusplus)
-#define __INLINE static inline
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __INLINE extern inline
-#define __CAN_DO_EXTERN_INLINE
-#define __BEGIN_DECLS
-#define __END_DECLS
-#if !defined(__STDC__)
-#define const __const
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-#endif
-#endif
-#else /* !__GNUC__ */
-#define __INLINE static
-#define __BEGIN_DECLS
-#define __END_DECLS
-#endif
-
-#ifndef __NORETURN
-#define __NORETURN
-#endif /* __NORETURN not defined. */
-
-#ifndef _U_INT32_T_
-#define _U_INT32_T_
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _U_INT16_T_
-#define _U_INT16_T_
-typedef unsigned short u_int16_t;
-#endif
-
-#ifndef _INT32_T_
-#define _INT32_T_
-typedef int int32_t;
-#endif
-
-#ifndef _INT16_T_
-#define _INT16_T_
-typedef short int16_t;
-#endif
-
-#ifndef _SSIZE_T_
-#define _SSIZE_T_
-typedef int ssize_t;
-#endif
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/compat.h b/mit-pthreads/machdep/ultrix-4.2/compat.h
deleted file mode 100755
index b2a846d00ee..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/compat.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ==== compat.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_COMPAT_H_
-#define _SYS_COMPAT_H_
-
-#define omsghdr msghdr
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/dirent.h b/mit-pthreads/machdep/ultrix-4.2/dirent.h
deleted file mode 100755
index 5f17af345db..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/dirent.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*-
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)dirent.h 5.18 (Berkeley) 2/23/91
- */
-
-#ifndef _SYS_DIRENT_H_
-#define _SYS_DIRENT_H_
-
-/*
- * A directory entry has a struct dirent at the front of it, containing its
- * inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
- * byte boundary with null bytes. All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- */
-
-struct dirent {
- u_long d_fileno; /* file number of entry */
- u_short d_reclen; /* length of this record */
- u_short d_namlen; /* length of string in d_name */
-#ifdef _POSIX_SOURCE
- char d_name[255 + 1]; /* name must be no longer than this */
-#else
-#define MAXNAMLEN 255
- char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-#endif
-};
-
-#define d_ino d_fileno
-
-#endif /* !_SYS_DIRENT_H_ */
diff --git a/mit-pthreads/machdep/ultrix-4.2/errno.h b/mit-pthreads/machdep/ultrix-4.2/errno.h
deleted file mode 100755
index b47633a9456..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/errno.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)errno.h 7.13 (Berkeley) 2/19/91
- * errno.h,v 1.3 1993/05/20 16:22:09 cgd Exp
- */
-
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EAGAIN 11 /* No more processes */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-/* 15 Non POSIX */
-/* 16 Non POSIX */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-/* 26 Non POSIX */
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-
-/* math software */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-/* 35 Non POSIX */
-/* 36 Non POSIX */
-/* 37 Non POSIX */
-/* 38 Non POSIX */
-/* 39 Non POSIX */
-/* 40 Non POSIX */
-/* 41 Non POSIX */
-/* 42 Non POSIX */
-/* 43 Non POSIX */
-/* 44 Non POSIX */
-/* 45 Non POSIX */
-/* 46 Non POSIX */
-/* 47 Non POSIX */
-/* 48 Non POSIX */
-/* 49 Non POSIX */
-/* 50 Non POSIX */
-/* 51 Non POSIX */
-/* 52 Non POSIX */
-/* 53 Non POSIX */
-/* 54 Non POSIX */
-/* 55 Non POSIX */
-/* 56 Non POSIX */
-/* 57 Non POSIX */
-/* 58 Non POSIX */
-/* 59 Non POSIX */
-/* 60 Non POSIX */
-/* 61 Non POSIX */
-/* 62 Non POSIX */
-#define ENAMETOOLONG 63 /* File name too long */
-/* 64 Non POSIX */
-/* 65 Non POSIX */
-#define ENOTEMPTY 66 /* Directory not empty */
-/* 67 Non POSIX */
-/* 68 Non POSIX */
-/* 69 Non POSIX */
-/* 70 Non POSIX */
-/* 71 Non POSIX */
-/* 72 Non POSIX */
-/* 73 Non POSIX */
-/* 74 Non POSIX */
-#define ENOLCK 75 /* No locks available */
-#define ENOSYS 76 /* Function not implemented */
-
-#ifndef _POSIX_SOURCE
-#define ENOTBLK 15 /* Block device required */
-#define EBUSY 16 /* Device busy */
-#define ETXTBSY 26 /* Text file busy */
-
-/* non-blocking and interrupt i/o */
-#define EWOULDBLOCK 35 /* Operation would block */
-#define EDEADLK EWOULDBLOCK /* Resource deadlock avoided */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-
-/* ipc/network software -- argument errors */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported on socket */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-
-/* ipc/network software -- operational errors */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Connection timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-
-#define ELOOP 62 /* Too many levels of symbolic links */
-
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-
-/* quotas & mush */
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-
-/* Network File System */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-
-/* IPC errors */
-#define ENOMSG 72 /* RPC struct is bad */
-#define EIDRM 73 /* RPC version wrong */
-
-/* Alignment error of some type (i.e., cluster, page, block ...) */
-#define EALIGN 74 /* RPC prog. not avail */
-#endif /* _POSIX_SOURCE */
-
-#endif /* _SYS_ERRNO_H_ */
diff --git a/mit-pthreads/machdep/ultrix-4.2/time.h b/mit-pthreads/machdep/ultrix-4.2/time.h
deleted file mode 100755
index 1dbb32b67a4..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/time.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)time.h 5.12 (Berkeley) 3/9/91
- * $Id$
- */
-
-#ifndef _SYS_TIME_H_
-#define _SYS_TIME_H_
-
-#include <time.h>
-#include <sys/cdefs.h>
-
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* microseconds */
-};
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* dst correction */
-};
-#define DST_NONE 0 /* not on dst */
-#define DST_USA 1 /* USA style dst */
-#define DST_AUST 2 /* Australian style dst */
-#define DST_WET 3 /* Western European dst */
-#define DST_MET 4 /* Middle European dst */
-#define DST_EET 5 /* Eastern European dst */
-
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-/*
- * Functions
- */
-__BEGIN_DECLS
-
-int gettimeofday __P_((struct timeval *, struct timezone *));
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/timers.h b/mit-pthreads/machdep/ultrix-4.2/timers.h
deleted file mode 100755
index 3c4d057976a..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/timers.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* ==== timers.h ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Basic timers header.
- *
- * 1.00 94/06/13 proven
- * -Started coding this file.
- */
-
-#ifndef _SYS_TIMERS_H_
-#define _SYS_TIMERS_H_
-
-#include <sys/types.h>
-#include <time.h>
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-}
-#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
-}
-
-/*
- * New functions
- */
-
-__BEGIN_DECLS
-
-__END_DECLS
-
-#endif
diff --git a/mit-pthreads/machdep/ultrix-4.2/wait.h b/mit-pthreads/machdep/ultrix-4.2/wait.h
deleted file mode 100755
index 8114f7e461d..00000000000
--- a/mit-pthreads/machdep/ultrix-4.2/wait.h
+++ /dev/null
@@ -1,121 +0,0 @@
-
-#ifndef _SYS_WAIT_H_
-#define _SYS_WAIT_H_
-
-#include <ansi_compat.h>
-#include <sys/cdefs.h>
-
-#if !defined(_POSIX_SOURCE)
-union wait {
-#else
-union __wait {
-#endif /* !defined(_POSIX_SOURCE) */
-#ifdef __vax
- int w_status; /* used in syscall */
-#endif /* __vax */
-#ifdef __mips__
- unsigned int w_status; /* used in syscall */
-#endif /* __mips */
- /*
- * Terminated process status.
- */
- struct {
-#ifdef __vax
- unsigned short w_Termsig:7; /* termination signal */
- unsigned short w_Coredump:1; /* core dump indicator */
- unsigned short w_Retcode:8; /* exit code if w_termsig==0 */
-#endif /* __vax */
-#ifdef __mips__
-#ifdef __MIPSEL__
- unsigned int w_Termsig:7; /* termination signal */
- unsigned int w_Coredump:1; /* core dump indicator */
- unsigned int w_Retcode:8; /* exit code if w_termsig==0 */
- unsigned int w_Filler:16; /* pad to word boundary */
-#endif /* __MIPSEL */
-#ifdef __MIPSEB__
- unsigned int w_Filler:16; /* pad to word boundary */
- unsigned int w_Retcode:8; /* exit code if w_termsig==0 */
- unsigned int w_Coredump:1; /* core dump indicator */
- unsigned int w_Termsig:7; /* termination signal */
-#endif /* __MIPSEB */
-#endif /* __mips */
- } w_T;
- /*
- * Stopped process status. Returned
- * only for traced children unless requested
- * with the WUNTRACED option bit.
- */
- struct {
-#ifdef __vax
- unsigned short w_Stopval:8; /* == W_STOPPED if stopped */
- unsigned short w_Stopsig:8; /* signal that stopped us */
-#endif /* __vax */
-#ifdef __mips__
-#ifdef __MIPSEL__
- unsigned int w_Stopval:8; /* == W_STOPPED if stopped */
- unsigned int w_Stopsig:8; /* signal that stopped us */
- unsigned int w_Filler:16; /* pad to word boundary */
-#endif /* __MIPSEL */
-#ifdef __MIPSEB__
- unsigned int w_Filler:16; /* pad to word boundary */
- unsigned int w_Stopsig:8; /* signal that stopped us */
- unsigned int w_Stopval:8; /* == W_STOPPED if stopped */
-#endif /* __MIPSEB */
-#endif /* __mips */
- } w_S;
-};
-
-#if !defined(_POSIX_SOURCE)
-#define w_termsig w_T.w_Termsig
-#define w_coredump w_T.w_Coredump
-#define w_retcode w_T.w_Retcode
-#define w_stopval w_S.w_Stopval
-#define w_stopsig w_S.w_Stopsig
-#define WSTOPPED 0177 /* value of s.stopval if process is stopped */
-#endif /* !defined(_POSIX_SOURCE) */
-
-#ifdef WSTOPPED
-#define _WSTOPPED WSTOPPED
-#else
-#define _WSTOPPED 0177
-#endif
-
-/*
- * Option bits for the second argument of wait3. WNOHANG causes the
- * wait to not hang if there are no stopped or terminated processes, rather
- * returning an error indication in this case (pid==0). WUNTRACED
- * indicates that the caller should receive status about untraced children
- * which stop due to signals. If children are stopped and a wait without
- * this option is done, it is as though they were still running... nothing
- * about them is returned.
- */
-#define WNOHANG 1 /* dont hang in wait */
-#define WUNTRACED 2 /* tell about stopped, untraced children */
-
-/*
- * Must cast as union wait * because POSIX defines the input to these macros
- * as int.
- */
-
-#ifdef _POSIX_SOURCE
-#define WIFSTOPPED(x) (((union __wait *)&(x))->w_S.w_Stopval == _WSTOPPED)
-#define WIFSIGNALED(x) (((union __wait *)&(x))->w_S.w_Stopval != _WSTOPPED && ((union __wait *)&(x))->w_T.w_Termsig != 0)
-#define WIFEXITED(x) (((union __wait *)&(x))->w_S.w_Stopval != _WSTOPPED && ((union __wait *)&(x))->w_T.w_Termsig == 0)
-#define WEXITSTATUS(x) (((union __wait *)&(x))->w_T.w_Retcode)
-#define WTERMSIG(x) (((union __wait *)&(x))->w_T.w_Termsig)
-#define WSTOPSIG(x) (((union __wait *)&(x))->w_S.w_Stopsig)
-#endif /* _POSIX_SOURCE */
-
-#if !defined(_POSIX_SOURCE)
-#define WIFSTOPPED(x) (((union wait *)&(x))->w_stopval == WSTOPPED)
-#define WIFSIGNALED(x) (((union wait *)&(x))->w_stopval != WSTOPPED && ((union wait *)&(x))->w_termsig != 0)
-#define WIFEXITED(x) (((union wait *)&(x))->w_stopval != WSTOPPED && ((union wait *)&(x))->w_termsig == 0)
-#define WEXITSTATUS(x) (((union wait *)&(x))->w_retcode)
-#define WTERMSIG(x) (((union wait *)&(x))->w_termsig)
-#define WSTOPSIG(x) (((union wait *)&(x))->w_stopsig)
-#endif /* !defined(_POSIX_SOURCE) */
-
-pid_t wait __P_((int *));
-pid_t waitpid __P_((pid_t, int *, int));
-
-#endif /* _SYS_WAIT_H_ */
diff --git a/mit-pthreads/machdep/unistd-i386-freebsd-1.1.h b/mit-pthreads/machdep/unistd-i386-freebsd-1.1.h
deleted file mode 100644
index 033e70de5e5..00000000000
--- a/mit-pthreads/machdep/unistd-i386-freebsd-1.1.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)unistd.h 5.13 (Berkeley) 6/17/91
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <sys/unistd.h>
-
-#define STDIN_FILENO 0 /* standard input file descriptor */
-#define STDOUT_FILENO 1 /* standard output file descriptor */
-#define STDERR_FILENO 2 /* standard error file descriptor */
-
-#ifndef NULL
-#define NULL 0 /* null pointer constant */
-#endif
-
-typedef int ssize_t; /* count of bytes or error indication */
-
-__BEGIN_DECLS
-void _exit __P_((int));
-int access __P_((const char *, int));
-u_int alarm __P_((u_int));
-int chdir __P_((const char *));
-int chown __P_((const char *, uid_t, gid_t));
-int close __P_((int));
-char *cuserid __P_((char *));
-int dup __P_((int));
-int dup2 __P_((int, int));
-int execl __P_((const char *, const char *, ...));
-int execle __P_((const char *, const char *, ...));
-int execlp __P_((const char *, const char *, ...));
-int execv __P_((const char *, char * const *));
-int execve __P_((const char *, char * const *, char * const *));
-int execvp __P_((const char *, char * const *));
-pid_t fork __P_((void));
-long fpathconf __P_((int, int)); /* not yet */
-char *getcwd __P_((char *, size_t));
-gid_t getegid __P_((void));
-uid_t geteuid __P_((void));
-gid_t getgid __P_((void));
-int getgroups __P_((int, int *)); /* XXX (gid_t *) */
-char *getlogin __P_((void));
-pid_t getpgrp __P_((void));
-pid_t getpid __P_((void));
-pid_t getppid __P_((void));
-uid_t getuid __P_((void));
-int isatty __P_((int));
-int link __P_((const char *, const char *));
-off_t lseek __P_((int, off_t, int));
-long pathconf __P_((const char *, int)); /* not yet */
-int pause __P_((void));
-int pipe __P_((int *));
-ssize_t read __P_((int, void *, size_t));
-int rmdir __P_((const char *));
-int setgid __P_((gid_t));
-int setpgid __P_((pid_t, pid_t));
-pid_t setsid __P_((void));
-int setuid __P_((uid_t));
-u_int sleep __P_((u_int));
-long sysconf __P_((int)); /* not yet */
-pid_t tcgetpgrp __P_((int));
-int tcsetpgrp __P_((int, pid_t));
-char *ttyname __P_((int));
-int unlink __P_((const char *));
-ssize_t write __P_((int, const void *, size_t));
-
-#ifndef _POSIX_SOURCE
-
-/* structure timeval required for select() */
-#include <sys/time.h>
-
-int acct __P_((const char *));
-int async_daemon __P_((void));
-char *brk __P_((const char *));
-int chflags __P_((const char *, long));
-int chroot __P_((const char *));
-char *crypt __P_((const char *, const char *));
-int des_cipher __P_((const char *, char *, long, int));
-int des_setkey __P_((const char *key));
-int encrypt __P_((char *, int));
-void endusershell __P_((void));
-int exect __P_((const char *, char * const *, char * const *));
-int fchdir __P_((int));
-int fchflags __P_((int, long));
-int fchown __P_((int, uid_t, gid_t));
-int fsync __P_((int));
-int ftruncate __P_((int, off_t));
-int getdtablesize __P_((void));
-long gethostid __P_((void));
-int gethostname __P_((char *, int));
-mode_t getmode __P_((const void *, mode_t));
-int getpagesize __P_((void));
-char *getpass __P_((const char *));
-char *getusershell __P_((void));
-char *getwd __P_((char *)); /* obsoleted by getcwd() */
-int initgroups __P_((const char *, int));
-int mknod __P_((const char *, mode_t, dev_t));
-int mkstemp __P_((char *));
-char *mktemp __P_((char *));
-int nfssvc __P_((int));
-int nice __P_((int));
-void psignal __P_((u_int, const char *));
-extern char *sys_siglist[];
-int profil __P_((char *, int, int, int));
-int rcmd __P_((char **, int, const char *,
- const char *, const char *, int *));
-char *re_comp __P_((const char *));
-int re_exec __P_((const char *));
-int readlink __P_((const char *, char *, int));
-int reboot __P_((int));
-int revoke __P_((const char *));
-int rresvport __P_((int *));
-int ruserok __P_((const char *, int, const char *, const char *));
-char *sbrk __P_((int));
-int select __P_((int, fd_set *, fd_set *, fd_set *, struct timeval *));
-int setegid __P_((gid_t));
-int seteuid __P_((uid_t));
-int setgroups __P_((int, const int *));
-void sethostid __P_((long));
-int sethostname __P_((const char *, int));
-int setkey __P_((const char *));
-int setlogin __P_((const char *));
-void *setmode __P_((const char *));
-int setpgrp __P_((pid_t pid, pid_t pgrp)); /* obsoleted by setpgid() */
-int setregid __P_((int, int));
-int setreuid __P_((int, int));
-int setrgid __P_((gid_t));
-int setruid __P_((uid_t));
-void setusershell __P_((void));
-int swapon __P_((const char *));
-int symlink __P_((const char *, const char *));
-void sync __P_((void));
-int syscall __P_((int, ...));
-int truncate __P_((const char *, off_t));
-int ttyslot __P_((void));
-u_int ualarm __P_((u_int, u_int));
-void usleep __P_((u_int));
-void *valloc __P_((size_t)); /* obsoleted by malloc() */
-int vfork __P_((void));
-
-#endif /* !_POSIX_SOURCE */
-__END_DECLS
-
-#endif /* !_UNISTD_H_ */
diff --git a/mit-pthreads/machdep/unistd-i386-linux-1.0.h b/mit-pthreads/machdep/unistd-i386-linux-1.0.h
deleted file mode 100644
index e7a3c5de1e4..00000000000
--- a/mit-pthreads/machdep/unistd-i386-linux-1.0.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)unistd.h 5.13 (Berkeley) 6/17/91
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <features.h>
-
-/* POSIX Standard approved as IEEE Std 1003.1 as of August, 1988. */
-#define _POSIX_VERSION 199009L
-#define _POSIX2_C_BIND 1
-#define _POSIX2_C_DEV 1
-#define _POSIX2_SW_DEV 1
-
-#define __need_size_t
-
-#include <posix_opt.h>
-#include <sys/types.h>
-#include <stddef.h>
-
-#define STDIN_FILENO 0 /* standard input file descriptor */
-#define STDOUT_FILENO 1 /* standard output file descriptor */
-#define STDERR_FILENO 2 /* standard error file descriptor */
-
-#include <pthread/unistd.h>
-
-#endif /* !_UNISTD_H_ */
diff --git a/mit-pthreads/machdep/unistd-i386-linux-2.0.h b/mit-pthreads/machdep/unistd-i386-linux-2.0.h
deleted file mode 100644
index e7a3c5de1e4..00000000000
--- a/mit-pthreads/machdep/unistd-i386-linux-2.0.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)unistd.h 5.13 (Berkeley) 6/17/91
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <features.h>
-
-/* POSIX Standard approved as IEEE Std 1003.1 as of August, 1988. */
-#define _POSIX_VERSION 199009L
-#define _POSIX2_C_BIND 1
-#define _POSIX2_C_DEV 1
-#define _POSIX2_SW_DEV 1
-
-#define __need_size_t
-
-#include <posix_opt.h>
-#include <sys/types.h>
-#include <stddef.h>
-
-#define STDIN_FILENO 0 /* standard input file descriptor */
-#define STDOUT_FILENO 1 /* standard output file descriptor */
-#define STDERR_FILENO 2 /* standard error file descriptor */
-
-#include <pthread/unistd.h>
-
-#endif /* !_UNISTD_H_ */
diff --git a/mit-pthreads/machdep/unistd-sparc-sunos-4.1.3.h b/mit-pthreads/machdep/unistd-sparc-sunos-4.1.3.h
deleted file mode 100644
index 4d2161b628f..00000000000
--- a/mit-pthreads/machdep/unistd-sparc-sunos-4.1.3.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)unistd.h 5.13 (Berkeley) 6/17/91
- * $Id$
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#define _NO_STDIO_SIZE_T
-
-#define _SC_ARG_MAX 1 /* space for argv & envp */
-#define _SC_CHILD_MAX 2 /* maximum children per process??? */
-#define _SC_CLK_TCK 3 /* clock ticks/sec */
-#define _SC_NGROUPS_MAX 4 /* number of groups if multple supp. */
-#define _SC_OPEN_MAX 5 /* max open files per process */
-#define _SC_JOB_CONTROL 6 /* do we have job control */
-#define _SC_SAVED_IDS 7 /* do we have saved uid/gids */
-#define _SC_VERSION 8 /* POSIX version supported */
-
-#define _POSIX_JOB_CONTROL 1
-#define _POSIX_SAVED_IDS 1
-#define _POSIX_VERSION 198808
-
-#define _PC_LINK_MAX 1 /* max links to file/dir */
-#define _PC_MAX_CANON 2 /* max line length */
-#define _PC_MAX_INPUT 3 /* max "packet" to a tty device */
-#define _PC_NAME_MAX 4 /* max pathname component length */
-#define _PC_PATH_MAX 5 /* max pathname length */
-#define _PC_PIPE_BUF 6 /* size of a pipe */
-#define _PC_CHOWN_RESTRICTED 7 /* can we give away files */
-#define _PC_NO_TRUNC 8 /* trunc or error on >NAME_MAX */
-#define _PC_VDISABLE 9 /* best char to shut off tty c_cc */
-#define _PC_LAST 9 /* highest value of any _PC_* */
-
-
-#define STDIN_FILENO 0 /* standard input file descriptor */
-#define STDOUT_FILENO 1 /* standard output file descriptor */
-#define STDERR_FILENO 2 /* standard error file descriptor */
-
-#ifndef NULL
-#define NULL 0 /* null pointer constant */
-#endif
-
-typedef int ssize_t;
-
-__BEGIN_DECLS
-void _exit __P_((int));
-int access __P_((const char *, int));
-unsigned alarm __P_((unsigned));
-int chdir __P_((const char *));
-int chown __P_((const char *, uid_t, gid_t));
-int close __P_((int));
-size_t confstr __P_((int, char *, size_t));
-char *cuserid __P_((char *));
-int dup __P_((int));
-int dup2 __P_((int, int));
-int execl __P_((const char *, const char *, ...));
-int execle __P_((const char *, const char *, ...));
-int execlp __P_((const char *, const char *, ...));
-int execv __P_((const char *, char * const *));
-int execve __P_((const char *, char * const *, char * const *));
-int execvp __P_((const char *, char * const *));
-pid_t fork __P_((void));
-long fpathconf __P_((int, int)); /* not yet */
-char *getcwd __P_((char *, size_t));
-gid_t getegid __P_((void));
-uid_t geteuid __P_((void));
-gid_t getgid __P_((void));
-int getgroups __P_((int, int *)); /* XXX (gid_t *) */
-char *getlogin __P_((void));
-pid_t getpgrp __P_((void));
-pid_t getpid __P_((void));
-pid_t getppid __P_((void));
-uid_t getuid __P_((void));
-int isatty __P_((int));
-int link __P_((const char *, const char *));
-off_t lseek __P_((int, off_t, int));
-long pathconf __P_((const char *, int)); /* not yet */
-int pause __P_((void));
-int pipe __P_((int *));
-ssize_t read __P_((int, void *, size_t));
-int rmdir __P_((const char *));
-int setgid __P_((gid_t));
-int setpgid __P_((pid_t, pid_t));
-pid_t setsid __P_((void));
-int setuid __P_((uid_t));
-unsigned sleep __P_((unsigned));
-long sysconf __P_((int)); /* not yet */
-pid_t tcgetpgrp __P_((int));
-int tcsetpgrp __P_((int, pid_t));
-char *ttyname __P_((int));
-int unlink __P_((const char *));
-ssize_t write __P_((int, const void *, size_t));
-
-#ifndef _POSIX_SOURCE
-
-/* structure timeval required for select() */
-#include <sys/time.h>
-
-int acct __P_((const char *));
-int async_daemon __P_((void));
-char *brk __P_((const char *));
-int chflags __P_((const char *, long));
-int chroot __P_((const char *));
-char *crypt __P_((const char *, const char *));
-int des_cipher __P_((const char *, char *, long, int));
-int des_setkey __P_((const char *key));
-int encrypt __P_((char *, int));
-void endusershell __P_((void));
-int exect __P_((const char *, char * const *, char * const *));
-int fchdir __P_((int));
-int fchflags __P_((int, long));
-int fchown __P_((int, uid_t, gid_t));
-int fsync __P_((int));
-int ftruncate __P_((int, off_t));
-int getdomainname __P_((char *, int));
-int getdtablesize __P_((void));
-long gethostid __P_((void));
-int gethostname __P_((char *, int));
-mode_t getmode __P_((const void *, mode_t));
-int getpagesize __P_((void));
-char *getpass __P_((const char *));
-char *getusershell __P_((void));
-char *getwd __P_((char *)); /* obsoleted by getcwd() */
-int initgroups __P_((const char *, int));
-int mknod __P_((const char *, mode_t, dev_t));
-int mkstemp __P_((char *));
-char *mktemp __P_((char *));
-int nfssvc __P_((int));
-int nice __P_((int));
-void psignal __P_((u_int, const char *));
-extern const char *const sys_siglist[];
-int profil __P_((char *, int, int, int));
-int rcmd __P_((char **, int, const char *,
- const char *, const char *, int *));
-char *re_comp __P_((const char *));
-int re_exec __P_((const char *));
-int readlink __P_((const char *, char *, int));
-int reboot __P_((int));
-int revoke __P_((const char *));
-int rresvport __P_((int *));
-int ruserok __P_((const char *, int, const char *, const char *));
-char *sbrk __P_((int));
-int select __P_((int, fd_set *, fd_set *, fd_set *, struct timeval *));
-int setdomainname __P_((const char *, int));
-int setegid __P_((gid_t));
-int seteuid __P_((uid_t));
-int setgroups __P_((int, const int *));
-void sethostid __P_((long));
-int sethostname __P_((const char *, int));
-int setkey __P_((const char *));
-int setlogin __P_((const char *));
-void *setmode __P_((const char *));
-int setpgrp __P_((pid_t pid, pid_t pgrp)); /* obsoleted by setpgid() */
-int setregid __P_((int, int));
-int setreuid __P_((int, int));
-int setrgid __P_((gid_t));
-int setruid __P_((uid_t));
-void setusershell __P_((void));
-int swapon __P_((const char *));
-int symlink __P_((const char *, const char *));
-void sync __P_((void));
-int syscall __P_((int, ...));
-int truncate __P_((const char *, off_t));
-int ttyslot __P_((void));
-u_int ualarm __P_((u_int, u_int));
-void usleep __P_((u_int));
-void *valloc __P_((size_t)); /* obsoleted by malloc() */
-pid_t vfork __P_((void));
-
-int getopt __P_((int, char * const *, const char *));
-extern char *optarg; /* getopt(3) external variables */
-extern int opterr;
-extern int optind;
-extern int optopt;
-int getsubopt __P_((char **, char * const *, char **));
-extern char *suboptarg; /* getsubopt(3) external variable */
-#endif /* !_POSIX_SOURCE */
-__END_DECLS
-
-#endif /* !_UNISTD_H_ */
diff --git a/mit-pthreads/net/GNUmakefile.inc b/mit-pthreads/net/GNUmakefile.inc
deleted file mode 100644
index 6b89617f63b..00000000000
--- a/mit-pthreads/net/GNUmakefile.inc
+++ /dev/null
@@ -1,14 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# gen sources
-VPATH:= ${VPATH}:${srcdir}/net
-
-SRCS:= gethostbyaddr.c gethostbyname.c gethostent.c getnetbyaddr.c \
- getnetbyname.c getnetent.c getproto.c getprotoent.c getprotoname.c \
- getservbyname.c getservbyport.c getservent.c herror.c inet_addr.c \
- inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \
- net_internal.c proto_internal.c res_comp.c res_init.c res_internal.c \
- res_mkquery.c res_query.c res_querydomain.c res_search.c res_send.c \
- res_debug.c serv_internal.c $(SRCS)
-
diff --git a/mit-pthreads/net/Makefile.inc b/mit-pthreads/net/Makefile.inc
deleted file mode 100644
index 08be88c808f..00000000000
--- a/mit-pthreads/net/Makefile.inc
+++ /dev/null
@@ -1,13 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# gen sources
-.PATH: ${srcdir}/net
-
-SRCS+= gethostbyaddr.c gethostbyname.c gethostent.c getnetbyaddr.c \
- getnetbyname.c getnetent.c getproto.c getprotoent.c getprotoname.c \
- getservbyname.c getservbyport.c getservent.c herror.c inet_addr.c \
- inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \
- net_internal.c proto_internal.c res_comp.c res_init.c res_internal.c \
- res_mkquery.c res_query.c res_querydomain.c res_search.c res_send.c \
- serv_internal.c gethostname.c
diff --git a/mit-pthreads/net/gethostbyaddr.c b/mit-pthreads/net/gethostbyaddr.c
deleted file mode 100644
index f80e47ffd99..00000000000
--- a/mit-pthreads/net/gethostbyaddr.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)gethostbyaddr.c 6.45 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <resolv.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include "res_internal.h"
-
-static struct hostent *file_find_addr(const char *addr, int len, int type,
- struct hostent *result, char *buf,
- int bufsize, int *errval);
-
-struct hostent *gethostbyaddr(const char *addr, int len, int type)
-{
- struct res_data *data = _res_init();
-
- if (!data)
- return NULL;
- if (!data->buf) {
- data->buf = malloc(sizeof(struct hostent) + HOST_BUFSIZE);
- if (!data->buf) {
- errno = 0;
- data->errval = NO_RECOVERY;
- return NULL;
- }
- }
- return gethostbyaddr_r(addr, len, type, (struct hostent *) data->buf,
- data->buf + sizeof(struct hostent), HOST_BUFSIZE,
- &data->errval);
-}
-
-struct hostent *gethostbyaddr_r(const char *addr, int len, int type,
- struct hostent *result, char *buf, int bufsize,
- int *errval)
-{
- struct res_data *data;
- querybuf qbuf;
- char lookups[MAXDNSLUS], addrbuf[MAXDNAME], *abuf;
- struct hostent *hp;
- int n, i;
-
- /* Default failure condition is not a range error and not recoverable. */
- errno = 0;
- *errval = NO_RECOVERY;
-
- data = _res_init();
- if (!data)
- return NULL;
-
- if (type != AF_INET)
- return NULL;
- sprintf(addrbuf, "%u.%u.%u.%u.in-addr.arpa",
- (unsigned)addr[3] & 0xff, (unsigned)addr[2] & 0xff,
- (unsigned)addr[1] & 0xff, (unsigned)addr[0] & 0xff);
-
- memcpy(lookups, data->state.lookups, sizeof(lookups));
- if (*lookups == 0)
- strncpy(lookups, "bf", sizeof(lookups));
-
- hp = NULL;
- for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
- switch (lookups[i]) {
- case 'b':
-
- /* Allocate space for a one-item list of addresses. */
- abuf = SP(SP(buf, char *, 2), struct in_addr, 1);
- if (abuf > buf + bufsize) {
- errno = ERANGE;
- return NULL;
- }
-
- /* Perform and parse the query. */
- n = res_query(addrbuf, C_IN, T_PTR, (char *)&qbuf, sizeof(qbuf));
- if (n < 0)
- break;
- hp = _res_parse_answer(&qbuf, n, 1, result, abuf,
- bufsize - (abuf - buf), errval);
- if (hp == NULL)
- break;
-
- /* Fill in our own address list. */
- result->h_addrtype = type;
- result->h_length = len;
- result->h_addr_list = (char **) ALIGN(buf, char *);
- result->h_addr_list[0] = ALIGN(&result->h_addr_list[2],
- struct in_addr);
- result->h_addr_list[1] = NULL;
- break;
-
- case 'f':
- hp = file_find_addr(addr, len, type, result, buf, bufsize, errval);
- break;
- }
- }
-
- return hp;
-}
-
-static struct hostent *file_find_addr(const char *addr, int len, int type,
- struct hostent *result, char *buf,
- int bufsize, int *errval)
-{
- FILE *fp = NULL;
-
- pthread_mutex_lock(&host_iterate_lock);
- sethostent(0);
- while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) {
- /* Check the entry against the given address. */
- if (result->h_addrtype == type &&
- memcmp(result->h_addr, addr, len) == 0)
- break;
- }
- pthread_mutex_unlock(&host_iterate_lock);
- if (!result && errno != ERANGE)
- *errval = HOST_NOT_FOUND;
- return result;
-}
-
diff --git a/mit-pthreads/net/gethostbyname.c b/mit-pthreads/net/gethostbyname.c
deleted file mode 100644
index aaaaf79b31b..00000000000
--- a/mit-pthreads/net/gethostbyname.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)gethostbyname.c 6.45 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <resolv.h>
-#include "res_internal.h"
-
-static struct hostent *fake_hostent(const char *hostname, struct in_addr addr,
- struct hostent *result, char *buf,
- int bufsize, int *errval);
-static struct hostent *file_find_name(const char *name, struct hostent *result,
- char *buf, int bufsize, int *errval);
-
-struct hostent *gethostbyname(const char *hostname)
-{
- struct res_data *data = _res_init();
-
- if (!data)
- return NULL;
- if (!data->buf) {
- data->buf = malloc(sizeof(struct hostent) + HOST_BUFSIZE);
- if (!data->buf) {
- errno = 0;
- data->errval = NO_RECOVERY;
- return NULL;
- }
- }
- return gethostbyname_r(hostname, (struct hostent *) data->buf,
- data->buf + sizeof(struct hostent), HOST_BUFSIZE,
- &data->errval);
-}
-
-struct hostent *gethostbyname_r(const char *hostname, struct hostent *result,
- char *buf, int bufsize, int *errval)
-{
- struct in_addr addr;
- querybuf qbuf;
- const char *p;
- int n;
-
- /* Default failure condition is not a range error and not recoverable. */
- errno = 0;
- *errval = NO_RECOVERY;
-
- /* Check for all-numeric hostname with no trailing dot. */
- if (isdigit(hostname[0])) {
- p = hostname;
- while (*p && (isdigit(*p) || *p == '.'))
- p++;
- if (!*p && p[-1] != '.') {
- /* Looks like an IP address; convert it. */
- if (inet_aton(hostname, &addr) == -1) {
- *errval = HOST_NOT_FOUND;
- return NULL;
- }
- return fake_hostent(hostname, addr, result, buf, bufsize, errval);
- }
- }
-
- /* Do the search. */
- n = res_search(hostname, C_IN, T_A, qbuf.buf, sizeof(qbuf));
- if (n >= 0)
- return _res_parse_answer(&qbuf, n, 0, result, buf, bufsize, errval);
- else if (errno == ECONNREFUSED)
- return file_find_name(hostname, result, buf, bufsize, errval);
- else
- return NULL;
-}
-
-static struct hostent *fake_hostent(const char *hostname, struct in_addr addr,
- struct hostent *result, char *buf,
- int bufsize, int *errval)
-{
- int len = strlen(hostname);
- char *name, *addr_ptr;
-
- if (SP(SP(SP(buf, char, len + 1), addr, 1), char *, 3) > buf + bufsize) {
- errno = ERANGE;
- return NULL;
- }
-
- /* Copy faked name and address into buffer. */
- strcpy(buf, hostname);
- name = buf;
- buf = ALIGN(buf + len + 1, addr);
- *((struct in_addr *) buf) = addr;
- addr_ptr = buf;
- buf = ALIGN(buf + sizeof(addr), char *);
- ((char **) buf)[0] = addr_ptr;
- ((char **) buf)[1] = NULL;
- ((char **) buf)[2] = NULL;
-
- result->h_name = name;
- result->h_aliases = ((char **) buf) + 2;
- result->h_addrtype = AF_INET;
- result->h_length = sizeof(addr);
- result->h_addr_list = (char **) buf;
-
- return result;
-}
-
-static struct hostent *file_find_name(const char *name, struct hostent *result,
- char *buf, int bufsize, int *errval)
-{
- char **alias;
- FILE *fp = NULL;
-
- pthread_mutex_lock(&host_iterate_lock);
- sethostent(0);
- while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcasecmp(result->h_name, name) == 0)
- break;
- for (alias = result->h_aliases; *alias; alias++) {
- if (strcasecmp(*alias, name) == 0)
- goto end; /* Josip Gracin */
- }
- }
-end:
- pthread_mutex_unlock(&host_iterate_lock);
- if (!result && errno != ERANGE)
- *errval = HOST_NOT_FOUND;
- return result;
-}
-
diff --git a/mit-pthreads/net/gethostent.c b/mit-pthreads/net/gethostent.c
deleted file mode 100644
index d6feb7aa164..00000000000
--- a/mit-pthreads/net/gethostent.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)gethostent.c 5.8 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include "res_internal.h"
-
-static pthread_mutex_t res_file_lock = PTHREAD_MUTEX_INITIALIZER;
-static int res_file_stayopen;
-static FILE *res_file;
-
-void sethostent(int stayopen)
-{
- pthread_mutex_lock(&res_file_lock);
- res_file_stayopen |= stayopen;
- if (res_file)
- rewind(res_file);
- else
- res_file = fopen(_PATH_HOSTS, "r");
- pthread_mutex_unlock(&res_file_lock);
-}
-
-void endhostent()
-{
- pthread_mutex_lock(&res_file_lock);
- if (res_file)
- fclose(res_file);
- pthread_mutex_unlock(&res_file_lock);
-}
-
-struct hostent *gethostent()
-{
- struct res_data *data = _res_init();
-
- if (!data)
- return NULL;
- if (!data->buf) {
- data->buf = malloc(sizeof(struct hostent) + HOST_BUFSIZE);
- if (!data->buf) {
- data->errval = NO_RECOVERY;
- return NULL;
- }
- }
- return gethostent_r((struct hostent *) data->buf,
- data->buf + sizeof(struct hostent), HOST_BUFSIZE,
- &data->errval);
-}
-
-struct hostent *gethostent_r(struct hostent *result, char *buf, int bufsize,
- int *errval)
-{
- char *p, **alias;
- struct in_addr *addr;
- int l;
-
- errno = 0;
- pthread_mutex_lock(&res_file_lock);
- if (res_file == NULL && (res_file = fopen(_PATH_HOSTS, "r")) == NULL) {
- pthread_mutex_unlock(&res_file_lock);
- return NULL;
- }
- while (fgets(buf, bufsize, res_file)) {
- if (*buf == '#')
- continue;
- p = strpbrk(buf, "#\n");
- if (p == NULL)
- continue;
- l = strlen(buf) + 1;
- *p = '\0';
- p = strpbrk(buf, " \t");
- if (p == NULL)
- continue;
- *p++ = '\0';
-
- /* THIS STUFF IS INTERNET SPECIFIC */
- if (SP(SP(SP(buf, char, l), *addr, 1), char *, 3) > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- addr = (struct in_addr *) ALIGN(buf + l, struct in_addr);
- if (inet_aton(buf, addr) == 0)
- continue;
- result->h_length = sizeof(*addr);
- result->h_addrtype = AF_INET;
- result->h_addr_list = (char **) ALIGN(addr + sizeof(*addr), char *);
- result->h_addr_list[0] = (char *) addr;
- result->h_addr_list[1] = NULL;
- result->h_aliases = result->h_addr_list + 2;
- while (*p == ' ' || *p == '\t')
- p++;
- result->h_name = p;
- alias = result->h_aliases;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- while (p && *p) {
- if (*p == ' ' || *p == '\t') {
- p++;
- continue;
- }
- if ((char *) &alias[2] > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- *alias++ = p;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- }
- if (p && *p)
- break;
- *alias = NULL;
- pthread_mutex_unlock(&res_file_lock);
- return result;
- }
-
- pthread_mutex_unlock(&res_file_lock);
- *errval = (errno == ERANGE) ? NO_RECOVERY : 0;
- return NULL;
-}
-
diff --git a/mit-pthreads/net/gethostname.c b/mit-pthreads/net/gethostname.c
deleted file mode 100644
index 8bec0793296..00000000000
--- a/mit-pthreads/net/gethostname.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright Abandoned 2000 TCX DataKonsult AB & Monty Program KB & Detron HB
- This file is public domain and comes with NO WARRANTY of any kind */
-
-#include "config.h"
-#include <pthread.h>
-#include <sys/utsname.h>
-
-#ifdef HAVE_SYSCALL_UNAME
-int gethostname(char *name, int len)
-{
- int ret;
- struct utsname buf;
-
- if ((ret = machdep_sys_chroot(&buf)) < OK)
- {
- SET_ERRNO(-ret);
- }
- else
- strncpy(name,uname->sysname, len);
- return(ret);
-}
-#endif
diff --git a/mit-pthreads/net/getnetbyaddr.c b/mit-pthreads/net/getnetbyaddr.c
deleted file mode 100644
index 6fba661c92e..00000000000
--- a/mit-pthreads/net/getnetbyaddr.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getnetbyaddr.c 5.7 (Berkeley) 6/1/90";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <netdb.h>
-#include "net_internal.h"
-
-struct netent *getnetbyaddr(long net, int type)
-{
- char *buf = _net_buf();
-
- if (!buf)
- return NULL;
- return getnetbyaddr_r(net, type, (struct netent *) buf,
- buf + sizeof(struct netent), NET_BUFSIZE);
-}
-
-struct netent *getnetbyaddr_r(long net, int type, struct netent *result,
- char *buf, int bufsize)
-{
- pthread_mutex_lock(&net_iterate_lock);
- setnetent(0);
- while ((result = getnetent_r(result, buf, bufsize)) != NULL) {
- if (result->n_addrtype == type && result->n_net == net)
- break;
- }
- pthread_mutex_unlock(&net_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getnetbyname.c b/mit-pthreads/net/getnetbyname.c
deleted file mode 100644
index 5b044ceb7a7..00000000000
--- a/mit-pthreads/net/getnetbyname.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getnetbyname.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <netdb.h>
-#include <string.h>
-#include "net_internal.h"
-
-struct netent *getnetbyname(const char *name)
-{
- char *buf = _net_buf();
-
- if (!buf)
- return NULL;
- return getnetbyname_r(name, (struct netent *) buf,
- buf + sizeof(struct netent), NET_BUFSIZE);
-}
-
-struct netent *getnetbyname_r(const char *name, struct netent *result,
- char *buf, int bufsize)
-{
- char **alias;
-
- pthread_mutex_lock(&net_iterate_lock);
- setnetent(0);
- while ((result = getnetent_r(result, buf, bufsize)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcmp(result->n_name, name) == 0)
- break;
- for (alias = result->n_aliases; *alias != 0; alias++) {
- if (strcmp(*alias, name) == 0)
- break;
- }
- }
- pthread_mutex_unlock(&net_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getnetent.c b/mit-pthreads/net/getnetent.c
deleted file mode 100644
index 05af0b09159..00000000000
--- a/mit-pthreads/net/getnetent.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getnetent.c 5.8 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include "net_internal.h"
-
-static pthread_mutex_t net_file_lock = PTHREAD_MUTEX_INITIALIZER;
-static int net_file_stayopen;
-static FILE *net_file;
-
-void setnetent(int stayopen)
-{
- pthread_mutex_lock(&net_file_lock);
- net_file_stayopen |= stayopen;
- if (net_file)
- rewind(net_file);
- else
- net_file = fopen(_PATH_NETWORKS, "r");
- pthread_mutex_unlock(&net_file_lock);
-}
-
-void endnetent()
-{
- pthread_mutex_lock(&net_file_lock);
- if (net_file)
- fclose(net_file);
- pthread_mutex_unlock(&net_file_lock);
-}
-
-struct netent *getnetent()
-{
- char *buf = _net_buf();
-
- return getnetent_r((struct netent *) buf, buf + sizeof(struct netent),
- NET_BUFSIZE);
-}
-
-struct netent *getnetent_r(struct netent *result, char *buf, int bufsize)
-{
- char *p, *q, **alias;
- int l;
-
- errno = 0;
- pthread_mutex_lock(&net_file_lock);
- if (net_file == NULL && (net_file = fopen(_PATH_NETWORKS, "r")) == NULL) {
- pthread_mutex_unlock(&net_file_lock);
- return NULL;
- }
- while (fgets(buf, bufsize, net_file)) {
- if (*buf == '#')
- continue;
- p = strpbrk(buf, "#\n");
- if (p == NULL)
- continue;
- *p = '\0';
- l = strlen(buf) + 1;
- result->n_name = buf;
- p = strpbrk(buf, " \t");
- if (p == NULL)
- continue;
- *p++ = '\0';
- while (*p == ' ' || *p == '\t')
- p++;
- q = strpbrk(p, " \t");
- if (q != NULL)
- *q++ = '\0';
- if (SP(SP(buf, char, l), char *, 1) > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- result->n_net = inet_network(p);
- result->n_addrtype = AF_INET;
- result->n_aliases = (char **) ALIGN(buf + l, char *);
- alias = result->n_aliases;
- if (q != NULL) {
- p = q;
- while (p && *p) {
- if (*p == ' ' || *p == '\t') {
- p++;
- continue;
- }
- if ((char *) &alias[2] > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- *alias++ = p;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- }
- if (p && *p)
- break;
- }
- *alias = NULL;
- pthread_mutex_unlock(&net_file_lock);
- return result;
- }
-
- pthread_mutex_unlock(&net_file_lock);
- return NULL;
-}
-
diff --git a/mit-pthreads/net/getproto.c b/mit-pthreads/net/getproto.c
deleted file mode 100644
index f6313bf1510..00000000000
--- a/mit-pthreads/net/getproto.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getproto.c 5.6 (Berkeley) 6/1/90";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <netdb.h>
-#include "proto_internal.h"
-
-struct protoent *getprotobynumber(int proto)
-{
- char *buf = _proto_buf();
-
- if (!buf)
- return NULL;
- return getprotobynumber_r(proto, (struct protoent *) buf,
- buf + sizeof(struct protoent), PROTO_BUFSIZE);
-}
-
-struct protoent *getprotobynumber_r(int proto, struct protoent *result,
- char *buf, int bufsize)
-{
- pthread_mutex_lock(&proto_iterate_lock);
- setprotoent(0);
- while ((result = getprotoent_r(result, buf, bufsize)) != NULL) {
- if (result->p_proto == proto)
- break;
- }
- pthread_mutex_unlock(&proto_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getprotoent.c b/mit-pthreads/net/getprotoent.c
deleted file mode 100644
index 8bd8d95ec14..00000000000
--- a/mit-pthreads/net/getprotoent.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getprotoent.c 5.8 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include "proto_internal.h"
-
-static pthread_mutex_t proto_file_lock = PTHREAD_MUTEX_INITIALIZER;
-static int proto_file_stayopen;
-static FILE *proto_file;
-
-void setprotoent(int stayopen)
-{
- pthread_mutex_lock(&proto_file_lock);
- proto_file_stayopen |= stayopen;
- if (proto_file)
- rewind(proto_file);
- else
- proto_file = fopen(_PATH_PROTOCOLS, "r");
- pthread_mutex_unlock(&proto_file_lock);
-}
-
-void endprotoent()
-{
- pthread_mutex_lock(&proto_file_lock);
- if (proto_file)
- fclose(proto_file);
- pthread_mutex_unlock(&proto_file_lock);
-}
-
-struct protoent *getprotoent()
-{
- char *buf = _proto_buf();
-
- return getprotoent_r((struct protoent *) buf,
- buf + sizeof(struct protoent), PROTO_BUFSIZE);
-}
-
-struct protoent *getprotoent_r(struct protoent *result, char *buf, int bufsize)
-{
- char *p, *q, **alias;
- int l;
-
- errno = 0;
- pthread_mutex_lock(&proto_file_lock);
- if (proto_file == NULL && !(proto_file = fopen(_PATH_PROTOCOLS, "r"))) {
- pthread_mutex_unlock(&proto_file_lock);
- return NULL;
- }
- while (fgets(buf, bufsize, proto_file)) {
- if (*buf == '#')
- continue;
- p = strpbrk(buf, "#\n");
- if (p == NULL)
- continue;
- *p = '\0';
- l = strlen(buf) + 1;
- result->p_name = buf;
- p = strpbrk(buf, " \t");
- if (p == NULL)
- continue;
- *p++ = '\0';
- while (*p == ' ' || *p == '\t')
- p++;
- q = strpbrk(p, " \t");
- if (q != NULL)
- *q++ = '\0';
- if (SP(SP(buf, char, l), char *, 1) > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- result->p_proto = atoi(p);
- result->p_aliases = (char **) ALIGN(buf + l, char *);
- alias = result->p_aliases;
- if (q != NULL) {
- p = q;
- while (p && *p) {
- if (*p == ' ' || *p == '\t') {
- p++;
- continue;
- }
- if ((char *) &alias[2] > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- *alias++ = p;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- }
- if (p && *p)
- break;
- }
- *alias = NULL;
- pthread_mutex_unlock(&proto_file_lock);
- return result;
- }
-
- pthread_mutex_unlock(&proto_file_lock);
- return NULL;
-}
-
diff --git a/mit-pthreads/net/getprotoname.c b/mit-pthreads/net/getprotoname.c
deleted file mode 100644
index 7bd7b925091..00000000000
--- a/mit-pthreads/net/getprotoname.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getprotoname.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <netdb.h>
-#include <string.h>
-#include "proto_internal.h"
-
-struct protoent *getprotobyname(const char *name)
-{
- char *buf = _proto_buf();
-
- if (!buf)
- return NULL;
- return getprotobyname_r(name, (struct protoent *) buf,
- buf + sizeof(struct protoent), PROTO_BUFSIZE);
-}
-
-struct protoent *getprotobyname_r(const char *name, struct protoent *result,
- char *buf, int bufsize)
-{
- char **alias;
-
- pthread_mutex_lock(&proto_iterate_lock);
- setprotoent(0);
- while ((result = getprotoent_r(result, buf, bufsize)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcmp(result->p_name, name) == 0)
- break;
- for (alias = result->p_aliases; *alias != 0; alias++) {
- if (strcmp(*alias, name) == 0)
- break;
- }
- }
- pthread_mutex_unlock(&proto_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getservbyname.c b/mit-pthreads/net/getservbyname.c
deleted file mode 100644
index f482b544fd0..00000000000
--- a/mit-pthreads/net/getservbyname.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getservbyname.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <netdb.h>
-#include <string.h>
-#include "serv_internal.h"
-
-struct servent *getservbyname(const char *name, const char *proto)
-{
- char *buf = _serv_buf();
-
- if (!buf)
- return NULL;
- return getservbyname_r(name, proto, (struct servent *) buf,
- buf + sizeof(struct servent), SERV_BUFSIZE);
-}
-
-struct servent *getservbyname_r(const char *name, const char *proto,
- struct servent *result, char *buf, int bufsize)
-{
- char **alias;
-
- pthread_mutex_lock(&serv_iterate_lock);
- setservent(0);
- while ((result = getservent_r(result, buf, bufsize)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcmp(result->s_name, name) != 0) {
- for (alias = result->s_aliases; *alias != NULL; alias++) {
- if (strcmp(*alias, name) == 0)
- break;
- }
- if (*alias == NULL)
- continue;
- }
- if (proto == NULL || strcmp(result->s_proto, proto) == 0)
- break;
- }
- pthread_mutex_unlock(&serv_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getservbyport.c b/mit-pthreads/net/getservbyport.c
deleted file mode 100644
index e3418212c0b..00000000000
--- a/mit-pthreads/net/getservbyport.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getservbyport.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include "serv_internal.h"
-
-struct servent *getservbyport(int port, const char *proto)
-{
- char *buf = _serv_buf();
-
- if (!buf)
- return NULL;
- return getservbyport_r(port, proto, (struct servent *) buf,
- buf + sizeof(struct servent), SERV_BUFSIZE);
-}
-
-struct servent *getservbyport_r(int port, const char *proto,
- struct servent *result, char *buf, int bufsize)
-{
- pthread_mutex_lock(&serv_iterate_lock);
- setservent(0);
- while ((result = getservent_r(result, buf, bufsize)) != NULL) {
- if (result->s_port != port)
- continue;
- if (proto == NULL || strcmp(result->s_proto, proto) == 0)
- break;
- }
- pthread_mutex_unlock(&serv_iterate_lock);
- return result;
-}
-
diff --git a/mit-pthreads/net/getservent.c b/mit-pthreads/net/getservent.c
deleted file mode 100644
index b0a7e039f69..00000000000
--- a/mit-pthreads/net/getservent.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getservent.c 5.9 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include "serv_internal.h"
-
-static pthread_mutex_t serv_file_lock = PTHREAD_MUTEX_INITIALIZER;
-static int serv_file_stayopen=0;
-static FILE *serv_file=NULL;
-
-void setservent(int stayopen)
-{
- pthread_mutex_lock(&serv_file_lock);
- serv_file_stayopen |= stayopen;
- if (serv_file)
- rewind(serv_file);
- else
- serv_file = fopen(_PATH_SERVICES, "r");
- pthread_mutex_unlock(&serv_file_lock);
-}
-
-void endservent()
-{
- pthread_mutex_lock(&serv_file_lock);
- if (serv_file)
- {
- fclose(serv_file);
- serv_file=NULL;
- }
- pthread_mutex_unlock(&serv_file_lock);
-}
-
-struct servent *getservent()
-{
- char *buf = _serv_buf();
-
- return getservent_r((struct servent *) buf, buf + sizeof(struct servent),
- SERV_BUFSIZE);
-}
-
-struct servent *getservent_r(struct servent *result, char *buf, int bufsize)
-{
- char *p, *q, **alias;
- int l;
-
- errno = 0;
- pthread_mutex_lock(&serv_file_lock);
- if (serv_file == NULL && !(serv_file = fopen(_PATH_SERVICES, "r"))) {
- pthread_mutex_unlock(&serv_file_lock);
- return NULL;
- }
- while (fgets(buf, bufsize, serv_file)) {
- if (*buf == '#')
- continue;
- p = strpbrk(buf, "#\n");
- if (p == NULL)
- continue;
- *p = '\0';
- l = strlen(buf) + 1;
- result->s_name = buf;
- q = strpbrk(buf, " \t");
- if (q == NULL)
- continue;
- *q++ = '\0';
- while (*q == ' ' || *q == '\t')
- q++;
- p = strpbrk(q, ",/");
- if (p == NULL)
- continue;
- *p++ = '\0';
- if (SP(SP(buf, char, l), char *, 1) > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- result->s_port = htons((u_short)atoi(q));
- result->s_proto = p;
- result->s_aliases = (char **) ALIGN(buf + l, char *);
- alias = result->s_aliases;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- while (p && *p) {
- if (*p == ' ' || *p == '\t') {
- p++;
- continue;
- }
- if ((char *) &alias[2] > buf + bufsize) {
- errno = ERANGE;
- break;
- }
- *alias++ = p;
- p = strpbrk(p, " \t");
- if (p != NULL)
- *p++ = '\0';
- }
- *alias = NULL;
- pthread_mutex_unlock(&serv_file_lock);
- return result;
- }
-
- pthread_mutex_unlock(&serv_file_lock);
- return NULL;
-}
-
diff --git a/mit-pthreads/net/herror.c b/mit-pthreads/net/herror.c
deleted file mode 100644
index 935c8e7ea38..00000000000
--- a/mit-pthreads/net/herror.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)herror.c 6.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <string.h>
-#include <resolv.h>
-
-char *h_errlist[] = {
- "Error 0",
- "Unknown host", /* 1 HOST_NOT_FOUND */
- "Host name lookup failure", /* 2 TRY_AGAIN */
- "Unknown server error", /* 3 NO_RECOVERY */
- "No address associated with name", /* 4 NO_ADDRESS */
-};
-int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) };
-
-/*
- * herror --
- * print the error indicated by the h_errno value.
- */
-void
-herror(s)
- const char *s;
-{
- struct iovec iov[4];
- register struct iovec *v = iov;
- int error = h_errno;
-
- if (s && *s) {
- v->iov_base = (char *)s;
- v->iov_len = strlen(s);
- v++;
- v->iov_base = ": ";
- v->iov_len = 2;
- v++;
- }
- v->iov_base = ((unsigned int)(error) < h_nerr) ?
- h_errlist[error] : "Unknown error";
- v->iov_len = strlen(v->iov_base);
- v++;
- v->iov_base = "\n";
- v->iov_len = 1;
- writev(STDERR_FILENO, iov, (v - iov) + 1);
-}
-
-char *
-hstrerror(err)
- int err;
-{
- return ((unsigned int)(err) < h_nerr) ? h_errlist[err]
- : "Unknown resolver error";
-}
-
diff --git a/mit-pthreads/net/inet_addr.c b/mit-pthreads/net/inet_addr.c
deleted file mode 100644
index 75ca154d4c2..00000000000
--- a/mit-pthreads/net/inet_addr.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 1983, 1990 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_addr.c 5.10 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-/*
- * Ascii internet address interpretation routine.
- * The value returned is in network order.
- */
-pthread_ipaddr_type
-inet_addr(cp)
- register const char *cp;
-{
- struct in_addr val;
-
- if (inet_aton(cp, &val))
- return (val.s_addr);
- return (INADDR_NONE);
-}
-
-/*
- * Check whether "cp" is a valid ascii representation
- * of an Internet address and convert to a binary address.
- * Returns 1 if the address is valid, 0 if not.
- * This replaces inet_addr, the return value from which
- * cannot distinguish between failure and a local broadcast address.
- */
-
-inet_aton(cp, addr)
- const register char *cp;
- struct in_addr *addr;
-{
- pthread_ipaddr_type parts[4], *pp = parts;
- pthread_ipaddr_type val, base, n;
- register char c;
-
- for (;;) {
- /*
- * Collect number up to ``.''.
- * Values are specified as for C:
- * 0x=hex, 0=octal, other=decimal.
- */
- val = 0; base = 10;
- if (*cp == '0') {
- if (*++cp == 'x' || *cp == 'X')
- base = 16, cp++;
- else
- base = 8;
- }
- while ((c = *cp) != '\0') {
- if (isascii(c) && isdigit(c)) {
- val = (val * base) + (c - '0');
- cp++;
- continue;
- }
- if (base == 16 && isascii(c) && isxdigit(c)) {
- val = (val << 4) +
- (c + 10 - (islower(c) ? 'a' : 'A'));
- cp++;
- continue;
- }
- break;
- }
- if (*cp == '.') {
- /*
- * Internet format:
- * a.b.c.d
- * a.b.c (with c treated as 16-bits)
- * a.b (with b treated as 24 bits)
- */
- if (pp >= parts + 3 || val > 0xff)
- return (0);
- *pp++ = val, cp++;
- } else
- break;
- }
- /*
- * Check for trailing characters.
- */
- if (*cp && (!isascii(*cp) || !isspace(*cp)))
- return (0);
- /*
- * Concoct the address according to
- * the number of parts specified.
- */
- n = pp - parts + 1;
- switch (n) {
-
- case 1: /* a -- 32 bits */
- break;
-
- case 2: /* a.b -- 8.24 bits */
- if (val > 0xffffff)
- return (0);
- val |= parts[0] << 24;
- break;
-
- case 3: /* a.b.c -- 8.8.16 bits */
- if (val > 0xffff)
- return (0);
- val |= (parts[0] << 24) | (parts[1] << 16);
- break;
-
- case 4: /* a.b.c.d -- 8.8.8.8 bits */
- if (val > 0xff)
- return (0);
- val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
- break;
- }
- if (addr)
- addr->s_addr = htonl(val);
- return (1);
-}
-
diff --git a/mit-pthreads/net/inet_lnaof.c b/mit-pthreads/net/inet_lnaof.c
deleted file mode 100644
index 752a5f03f79..00000000000
--- a/mit-pthreads/net/inet_lnaof.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_lnaof.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/*
- * Return the local network address portion of an
- * internet address; handles class a/b/c network
- * number formats.
- */
-pthread_ipaddr_type
-inet_lnaof(in)
- struct in_addr in;
-{
- register pthread_ipaddr_type i = ntohl(in.s_addr);
-
- if (IN_CLASSA(i))
- return ((i)&IN_CLASSA_HOST);
- else if (IN_CLASSB(i))
- return ((i)&IN_CLASSB_HOST);
- else
- return ((i)&IN_CLASSC_HOST);
-}
diff --git a/mit-pthreads/net/inet_makeaddr.c b/mit-pthreads/net/inet_makeaddr.c
deleted file mode 100644
index a4995e2b4c4..00000000000
--- a/mit-pthreads/net/inet_makeaddr.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_makeaddr.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/*
- * Formulate an Internet address from network + host. Used in
- * building addresses stored in the ifnet structure.
- */
-struct in_addr
-inet_makeaddr(net, host)
- pthread_ipaddr_type net, host;
-{
- pthread_ipaddr_type addr;
-
- if (net < 128)
- addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
- else if (net < 65536)
- addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
- else if (net < 16777216L)
- addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
- else
- addr = net | host;
- addr = htonl(addr);
- return (*(struct in_addr *)&addr);
-}
diff --git a/mit-pthreads/net/inet_netof.c b/mit-pthreads/net/inet_netof.c
deleted file mode 100644
index 40d3f4c3385..00000000000
--- a/mit-pthreads/net/inet_netof.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_netof.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/*
- * Return the network number from an internet
- * address; handles class a/b/c network #'s.
- */
-pthread_ipaddr_type
-inet_netof(in)
- struct in_addr in;
-{
- register pthread_ipaddr_type i = ntohl(in.s_addr);
-
- if (IN_CLASSA(i))
- return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
- else if (IN_CLASSB(i))
- return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
- else
- return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
-}
diff --git a/mit-pthreads/net/inet_network.c b/mit-pthreads/net/inet_network.c
deleted file mode 100644
index cc0f1b4e603..00000000000
--- a/mit-pthreads/net/inet_network.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_network.c 5.8 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-/*
- * Internet network address interpretation routine.
- * The library routines call this routine to interpret
- * network numbers.
- */
-pthread_ipaddr_type
-inet_network(cp)
- register const char *cp;
-{
- pthread_ipaddr_type parts[4], *pp = parts;
- pthread_ipaddr_type val, base, n;
- register char c;
- register int i;
-
-again:
- val = 0; base = 10;
- if (*cp == '0')
- base = 8, cp++;
- if (*cp == 'x' || *cp == 'X')
- base = 16, cp++;
- while (c = *cp) {
- if (isdigit(c)) {
- val = (val * base) + (c - '0');
- cp++;
- continue;
- }
- if (base == 16 && isxdigit(c)) {
- val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
- cp++;
- continue;
- }
- break;
- }
- if (*cp == '.') {
- if (pp >= parts + 4)
- return (INADDR_NONE);
- *pp++ = val, cp++;
- goto again;
- }
- if (*cp && !isspace(*cp))
- return (INADDR_NONE);
- *pp++ = val;
- n = pp - parts;
- if (n > 4)
- return (INADDR_NONE);
- for (val = 0, i = 0; i < n; i++) {
- val <<= 8;
- val |= parts[i] & 0xff;
- }
- return (val);
-}
diff --git a/mit-pthreads/net/inet_ntoa.c b/mit-pthreads/net/inet_ntoa.c
deleted file mode 100644
index cd206afcf2a..00000000000
--- a/mit-pthreads/net/inet_ntoa.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)inet_ntoa.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * Convert network-format internet address
- * to base 256 d.d.d.d representation.
- */
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-char *inet_ntoa(struct in_addr in)
-{
- static pthread_mutex_t inet_ntoa_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t inet_ntoa_key = -1;
- char *buf, *inet_ntoa_r();
-
- if (inet_ntoa_key < 0) {
- pthread_mutex_lock(&inet_ntoa_mutex);
- if (inet_ntoa_key < 0) {
- if (pthread_key_create(&inet_ntoa_key, free) < 0) {
- pthread_mutex_unlock(&inet_ntoa_mutex);
- return(NULL);
- }
- }
- pthread_mutex_unlock(&inet_ntoa_mutex);
- }
- if ((buf = pthread_getspecific(inet_ntoa_key)) == NULL) {
- if ((buf = (char *) malloc(18)) == NULL) {
- return(NULL);
- }
- pthread_setspecific(inet_ntoa_key, buf);
- }
- return inet_ntoa_r(in, buf, 18);
-}
-
-char *inet_ntoa_r(struct in_addr in, char *buf, int bufsize)
-{
- register char *p;
-
- p = (char *)&in;
-#define UC(b) (((int)b)&0xff)
- (void)snprintf(buf, bufsize,
- "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
- return (buf);
-}
-
diff --git a/mit-pthreads/net/net_internal.c b/mit-pthreads/net/net_internal.c
deleted file mode 100644
index 2c25ff76693..00000000000
--- a/mit-pthreads/net/net_internal.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)net_internal.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "net_internal.h"
-
-static void _net_init_global(void);
-
-pthread_mutex_t net_iterate_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-static pthread_key_t key;
-static int init_status;
-
-/* Performs global initialization. */
-char *_net_buf()
-{
- char *buf;
-
- /* Make sure the global initializations have been done. */
- pthread_once(&init_once, _net_init_global);
-
- /* Initialize thread-specific data for this thread if it hasn't
- * been done already. */
- buf = (char *) pthread_getspecific(key);
- if (!buf) {
- buf = (char *) malloc(NET_BUFSIZE);
- if (buf == NULL)
- return NULL;
- if (pthread_setspecific(key, buf) < 0) {
- free(buf);
- return NULL;
- }
- }
- return buf;
-}
-
-static void _net_init_global()
-{
- init_status = pthread_key_create(&key, free);
-}
-
diff --git a/mit-pthreads/net/net_internal.h b/mit-pthreads/net/net_internal.h
deleted file mode 100644
index 0dc5c866e5d..00000000000
--- a/mit-pthreads/net/net_internal.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)net_internal.h 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#ifndef _NET_INTERNAL_H
-#define _NET_INTERNAL_H
-
-#include <pthread.h>
-#include <netdb.h>
-#include <resolv.h>
-
-#define NET_BUFSIZE 4096
-#undef ALIGN
-#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t)))
-#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t))
-
-extern pthread_mutex_t net_iterate_lock;
-
-__BEGIN_DECLS
-char *_net_buf(void);
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/net/proto_internal.c b/mit-pthreads/net/proto_internal.c
deleted file mode 100644
index db3ab04ec77..00000000000
--- a/mit-pthreads/net/proto_internal.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)proto_internal.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "proto_internal.h"
-
-static void _proto_init_global(void);
-
-pthread_mutex_t proto_iterate_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-static pthread_key_t key;
-static int init_status;
-
-/* Performs global initialization. */
-char *_proto_buf()
-{
- char *buf;
-
- /* Make sure the global initializations have been done. */
- pthread_once(&init_once, _proto_init_global);
-
- /* Initialize thread-specific data for this thread if it hasn't
- * been done already. */
- buf = (char *) pthread_getspecific(key);
- if (!buf) {
- buf = (char *) malloc(PROTO_BUFSIZE);
- if (buf == NULL)
- return NULL;
- if (pthread_setspecific(key, buf) < 0) {
- free(buf);
- return NULL;
- }
- }
- return buf;
-}
-
-static void _proto_init_global()
-{
- init_status = pthread_key_create(&key, free);
-}
-
diff --git a/mit-pthreads/net/proto_internal.h b/mit-pthreads/net/proto_internal.h
deleted file mode 100644
index 4ed06883f25..00000000000
--- a/mit-pthreads/net/proto_internal.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)proto_internal.h 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#ifndef _PROTO_INTERNAL_H
-#define _PROTO_INTERNAL_H
-
-#include <pthread.h>
-#include <netdb.h>
-#include <resolv.h>
-
-#define PROTO_BUFSIZE 4096
-#undef ALIGN
-#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t)))
-#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t))
-
-extern pthread_mutex_t proto_iterate_lock;
-
-__BEGIN_DECLS
-char *_proto_buf(void);
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/net/res_comp.c b/mit-pthreads/net/res_comp.c
deleted file mode 100644
index 45a4bcafed2..00000000000
--- a/mit-pthreads/net/res_comp.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_comp.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <sys/cdefs.h>
-#include <netinet/in.h>
-#include <resolv.h>
-#include <stdio.h>
-
-static dn_find();
-
-/*
- * Expand compressed domain name 'comp_dn' to full domain name.
- * 'msg' is a pointer to the begining of the message,
- * 'eomorig' points to the first location after the message,
- * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
- * Return size of compressed name or -1 if there was an error.
- */
-dn_expand(msg, eomorig, comp_dn, exp_dn, length)
- const u_char *msg, *eomorig, *comp_dn;
- u_char *exp_dn;
- int length;
-{
- register u_char *cp, *dn;
- register int n, c;
- u_char *eom;
- int len = -1, checked = 0;
-
- dn = exp_dn;
- cp = (u_char *)comp_dn;
- eom = exp_dn + length;
- /*
- * fetch next label in domain name
- */
- while (n = *cp++) {
- /*
- * Check for indirection
- */
- switch (n & INDIR_MASK) {
- case 0:
- if (dn != exp_dn) {
- if (dn >= eom)
- return (-1);
- *dn++ = '.';
- }
- if (dn+n >= eom)
- return (-1);
- checked += n + 1;
- while (--n >= 0) {
- if ((c = *cp++) == '.') {
- if (dn + n + 2 >= eom)
- return (-1);
- *dn++ = '\\';
- }
- *dn++ = c;
- if (cp >= eomorig) /* out of range */
- return(-1);
- }
- break;
-
- case INDIR_MASK:
- if (len < 0)
- len = cp - comp_dn + 1;
- cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff));
- if (cp < msg || cp >= eomorig) /* out of range */
- return(-1);
- checked += 2;
- /*
- * Check for loops in the compressed name;
- * if we've looked at the whole message,
- * there must be a loop.
- */
- if (checked >= eomorig - msg)
- return (-1);
- break;
-
- default:
- return (-1); /* flag error */
- }
- }
- *dn = '\0';
- if (len < 0)
- len = cp - comp_dn;
- return (len);
-}
-
-/*
- * Compress domain name 'exp_dn' into 'comp_dn'.
- * Return the size of the compressed name or -1.
- * 'length' is the size of the array pointed to by 'comp_dn'.
- * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
- * is a pointer to the beginning of the message. The list ends with NULL.
- * 'lastdnptr' is a pointer to the end of the arrary pointed to
- * by 'dnptrs'. Side effect is to update the list of pointers for
- * labels inserted into the message as we compress the name.
- * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
- * is NULL, we don't update the list.
- */
-dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
- const u_char *exp_dn;
- u_char *comp_dn, **dnptrs, **lastdnptr;
- int length;
-{
- register u_char *cp, *dn;
- register int c, l;
- u_char **cpp, **lpp, *sp, *eob;
- u_char *msg;
-
- dn = (u_char *)exp_dn;
- cp = comp_dn;
- eob = cp + length;
- if (dnptrs != NULL) {
- if ((msg = *dnptrs++) != NULL) {
- for (cpp = dnptrs; *cpp != NULL; cpp++)
- ;
- lpp = cpp; /* end of list to search */
- }
- } else
- msg = NULL;
- for (c = *dn++; c != '\0'; ) {
- /* look to see if we can use pointers */
- if (msg != NULL) {
- if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
- if (cp+1 >= eob)
- return (-1);
- *cp++ = (l >> 8) | INDIR_MASK;
- *cp++ = l % 256;
- return (cp - comp_dn);
- }
- /* not found, save it */
- if (lastdnptr != NULL && cpp < lastdnptr-1) {
- *cpp++ = cp;
- *cpp = NULL;
- }
- }
- sp = cp++; /* save ptr to length byte */
- do {
- if (c == '.') {
- c = *dn++;
- break;
- }
- if (c == '\\') {
- if ((c = *dn++) == '\0')
- break;
- }
- if (cp >= eob) {
- if (msg != NULL)
- *lpp = NULL;
- return (-1);
- }
- *cp++ = c;
- } while ((c = *dn++) != '\0');
- /* catch trailing '.'s but not '..' */
- if ((l = cp - sp - 1) == 0 && c == '\0') {
- cp--;
- break;
- }
- if (l <= 0 || l > MAXLABEL) {
- if (msg != NULL)
- *lpp = NULL;
- return (-1);
- }
- *sp = l;
- }
- if (cp >= eob) {
- if (msg != NULL)
- *lpp = NULL;
- return (-1);
- }
- *cp++ = '\0';
- return (cp - comp_dn);
-}
-
-/*
- * Skip over a compressed domain name. Return the size or -1.
- */
-__dn_skipname(comp_dn, eom)
- const u_char *comp_dn, *eom;
-{
- register u_char *cp;
- register int n;
-
- cp = (u_char *)comp_dn;
- while (cp < eom && (n = *cp++)) {
- /*
- * check for indirection
- */
- switch (n & INDIR_MASK) {
- case 0: /* normal case, n == len */
- cp += n;
- continue;
- case INDIR_MASK: /* indirection */
- cp++;
- break;
- default: /* illegal type */
- return (-1);
- }
- break;
- }
- if (cp > eom)
- return -1;
- return (cp - comp_dn);
-}
-
-/*
- * Search for expanded name from a list of previously compressed names.
- * Return the offset from msg if found or -1.
- * dnptrs is the pointer to the first name on the list,
- * not the pointer to the start of the message.
- */
-static int
-dn_find(exp_dn, msg, dnptrs, lastdnptr)
- u_char *exp_dn, *msg;
- u_char **dnptrs, **lastdnptr;
-{
- register u_char *dn, *cp, **cpp;
- register int n;
- u_char *sp;
-
- for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
- dn = exp_dn;
- sp = cp = *cpp;
- while (n = *cp++) {
- /*
- * check for indirection
- */
- switch (n & INDIR_MASK) {
- case 0: /* normal case, n == len */
- while (--n >= 0) {
- if (*dn == '.')
- goto next;
- if (*dn == '\\')
- dn++;
- if (*dn++ != *cp++)
- goto next;
- }
- if ((n = *dn++) == '\0' && *cp == '\0')
- return (sp - msg);
- if (n == '.')
- continue;
- goto next;
-
- default: /* illegal type */
- return (-1);
-
- case INDIR_MASK: /* indirection */
- cp = msg + (((n & 0x3f) << 8) | *cp);
- }
- }
- if (*dn == '\0')
- return (sp - msg);
- next: ;
- }
- return (-1);
-}
-
-/*
- * Routines to insert/extract short/long's. Must account for byte
- * order and non-alignment problems. This code at least has the
- * advantage of being portable.
- *
- * used by sendmail.
- */
-
-u_short
-_getshort(msgp)
- register const u_char *msgp;
-{
- register u_short u;
-
- GETSHORT(u, msgp);
- return (u);
-}
-
-pthread_ipaddr_type
-_getlong(msgp)
- const u_char *msgp;
-{
- pthread_ipaddr_type u;
-
- GETLONG(u, msgp);
- return (u);
-}
-
-void
-#ifdef __STDC__
-__putshort(register u_short s, register u_char *msgp)
-#else
- __putshort(s, msgp)
- register u_short s;
- register u_char *msgp;
-#endif
-{
- PUTSHORT(s, msgp);
-}
-
-void
-__putlong(l, msgp)
- register pthread_ipaddr_type l;
- register u_char *msgp;
-{
- PUTLONG(l, msgp);
-}
-
diff --git a/mit-pthreads/net/res_debug.c b/mit-pthreads/net/res_debug.c
deleted file mode 100644
index 3e2084fccf8..00000000000
--- a/mit-pthreads/net/res_debug.c
+++ /dev/null
@@ -1,749 +0,0 @@
-/*
- * Copyright (c) 1985, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <stdio.h>
-#include <string.h>
-#include <resolv.h>
-#include <arpa/inet.h>
-
-void __fp_query();
-char *__p_class(), *__p_time(), *__p_type();
-char *p_cdname(), *p_fqname(), *p_rr();
-static char *p_option __P_((u_long));
-
-char *_res_opcodes[] = {
- "QUERY",
- "IQUERY",
- "CQUERYM",
- "CQUERYU",
- "4",
- "5",
- "6",
- "7",
- "8",
- "UPDATEA",
- "UPDATED",
- "UPDATEDA",
- "UPDATEM",
- "UPDATEMA",
- "ZONEINIT",
- "ZONEREF",
-};
-
-char *_res_resultcodes[] = {
- "NOERROR",
- "FORMERR",
- "SERVFAIL",
- "NXDOMAIN",
- "NOTIMP",
- "REFUSED",
- "6",
- "7",
- "8",
- "9",
- "10",
- "11",
- "12",
- "13",
- "14",
- "NOCHANGE",
-};
-
-static char retbuf[16];
-
-static char *
-dewks(wks)
- int wks;
-{
- switch (wks) {
- case 5: return("rje");
- case 7: return("echo");
- case 9: return("discard");
- case 11: return("systat");
- case 13: return("daytime");
- case 15: return("netstat");
- case 17: return("qotd");
- case 19: return("chargen");
- case 20: return("ftp-data");
- case 21: return("ftp");
- case 23: return("telnet");
- case 25: return("smtp");
- case 37: return("time");
- case 39: return("rlp");
- case 42: return("name");
- case 43: return("whois");
- case 53: return("domain");
- case 57: return("apts");
- case 59: return("apfs");
- case 67: return("bootps");
- case 68: return("bootpc");
- case 69: return("tftp");
- case 77: return("rje");
- case 79: return("finger");
- case 87: return("link");
- case 95: return("supdup");
- case 100: return("newacct");
- case 101: return("hostnames");
- case 102: return("iso-tsap");
- case 103: return("x400");
- case 104: return("x400-snd");
- case 105: return("csnet-ns");
- case 109: return("pop-2");
- case 111: return("sunrpc");
- case 113: return("auth");
- case 115: return("sftp");
- case 117: return("uucp-path");
- case 119: return("nntp");
- case 121: return("erpc");
- case 123: return("ntp");
- case 133: return("statsrv");
- case 136: return("profile");
- case 144: return("NeWS");
- case 161: return("snmp");
- case 162: return("snmp-trap");
- case 170: return("print-srv");
- default: (void) sprintf(retbuf, "%d", wks); return(retbuf);
- }
-}
-
-static char *
-deproto(protonum)
- int protonum;
-{
- switch (protonum) {
- case 1: return("icmp");
- case 2: return("igmp");
- case 3: return("ggp");
- case 5: return("st");
- case 6: return("tcp");
- case 7: return("ucl");
- case 8: return("egp");
- case 9: return("igp");
- case 11: return("nvp-II");
- case 12: return("pup");
- case 16: return("chaos");
- case 17: return("udp");
- default: (void) sprintf(retbuf, "%d", protonum); return(retbuf);
- }
-}
-
-static char *
-do_rrset(msg, cp, cnt, pflag, file, hs)
- int cnt, pflag;
- char *cp,*msg, *hs;
- FILE *file;
-{
- int n;
- int sflag;
- /*
- * Print answer records
- */
- sflag = (_res.pfcode & pflag);
- if (n = ntohs(cnt)) {
- if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
- fprintf(file, hs);
- while (--n >= 0) {
- cp = p_rr(cp, msg, file);
- if ((cp-msg) > PACKETSZ)
- return (NULL);
- }
- if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
- putc('\n', file);
- }
- return(cp);
-}
-
-__p_query(msg)
- char *msg;
-{
- __fp_query(msg, stdout);
-}
-
-/*
- * Print the current options.
- * This is intended to be primarily a debugging routine.
- */
-void
-__fp_resstat(statp, file)
- struct __res_state *statp;
- FILE *file;
-{
- int bit;
-
- fprintf(file, ";; res options:");
- if (!statp)
- statp = &_res;
- for (bit = 0; bit < 32; bit++) { /* XXX 32 - bad assumption! */
- if (statp->options & (1<<bit))
- fprintf(file, " %s", p_option(1<<bit));
- }
- putc('\n', file);
-}
-
-/*
- * Print the contents of a query.
- * This is intended to be primarily a debugging routine.
- */
-void
-__fp_query(msg,file)
- char *msg;
- FILE *file;
-{
- register char *cp;
- register HEADER *hp;
- register int n;
-
- /*
- * Print header fields.
- */
- hp = (HEADER *)msg;
- cp = msg + sizeof(HEADER);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
- fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
- _res_opcodes[hp->opcode],
- _res_resultcodes[hp->rcode],
- ntohs(hp->id));
- putc('\n', file);
- }
- putc(';', file);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
- fprintf(file,"; flags:");
- if (hp->qr)
- fprintf(file," qr");
- if (hp->aa)
- fprintf(file," aa");
- if (hp->tc)
- fprintf(file," tc");
- if (hp->rd)
- fprintf(file," rd");
- if (hp->ra)
- fprintf(file," ra");
- if (hp->pr)
- fprintf(file," pr");
- }
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
- fprintf(file,"; Ques: %d", ntohs(hp->qdcount));
- fprintf(file,", Ans: %d", ntohs(hp->ancount));
- fprintf(file,", Auth: %d", ntohs(hp->nscount));
- fprintf(file,", Addit: %d", ntohs(hp->arcount));
- }
-#if 1
- if ((!_res.pfcode) || (_res.pfcode &
- (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
- putc('\n',file);
- }
-#endif
- /*
- * Print question records.
- */
- if (n = ntohs(hp->qdcount)) {
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file,";; QUESTIONS:\n");
- while (--n >= 0) {
- fprintf(file,";;\t");
- cp = p_cdname(cp, msg, file);
- if (cp == NULL)
- return;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ", type = %s",
- __p_type(_getshort(cp)));
- cp += sizeof(u_short);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ", class = %s\n",
- __p_class(_getshort(cp)));
- cp += sizeof(u_short);
- putc('\n', file);
- }
- }
- /*
- * Print authoritative answer records
- */
- cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file,
- ";; ANSWERS:\n");
- if (cp == NULL)
- return;
-
- /*
- * print name server records
- */
- cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file,
- ";; AUTHORITY RECORDS:\n");
- if (!cp)
- return;
-
- /*
- * print additional records
- */
- cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file,
- ";; ADDITIONAL RECORDS:\n");
- if (!cp)
- return;
-}
-
-char *
-p_cdname(cp, msg, file)
- char *cp, *msg;
- FILE *file;
-{
- char name[MAXDNAME];
- int n;
-
- if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME,
- (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
- return (NULL);
- if (name[0] == '\0')
- putc('.', file);
- else
- fputs(name, file);
- return (cp + n);
-}
-
-char *
-p_fqname(cp, msg, file)
- char *cp, *msg;
- FILE *file;
-{
- char name[MAXDNAME];
- int n, len;
-
- if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME,
- (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
- return (NULL);
- if (name[0] == '\0') {
- putc('.', file);
- } else {
- fputs(name, file);
- if (name[strlen(name) - 1] != '.')
- putc('.', file);
- }
- return (cp + n);
-}
-
-/*
- * Print resource record fields in human readable form.
- *
- * Removed calls to non-reentrant routines to simplify varifying
- * POSIX thread-safe implementations. (mevans).
- */
-char *
-p_rr(cp, msg, file)
- char *cp, *msg;
- FILE *file;
-{
- int type, class, dlen, n, c;
- struct in_addr inaddr;
- char *cp1, *cp2;
- u_long tmpttl, t;
- int lcnt;
- char buf[32];
-
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL); /* compression error */
- type = _getshort(cp);
- cp += sizeof(u_short);
- class = _getshort(cp);
- cp += sizeof(u_short);
- tmpttl = _getlong(cp);
- cp += sizeof(u_long);
- dlen = _getshort(cp);
- cp += sizeof(u_short);
- cp1 = cp;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
- fprintf(file, "\t%lu", tmpttl);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
- fprintf(file, "\t%s", __p_class(class));
- fprintf(file, "\t%s", __p_type(type));
- /*
- * Print type specific data, if appropriate
- */
- switch (type) {
- case T_A:
- switch (class) {
- case C_IN:
- case C_HS:
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- if (dlen == 4) {
- fprintf(file,"\t%s",
- inet_ntoa_r(inaddr, buf, sizeof(buf)));
- cp += dlen;
- } else if (dlen == 7) {
- char *address;
- u_char protocol;
- u_short port;
-
- address = inet_ntoa_r(inaddr,
- buf, sizeof(buf));
- cp += sizeof(inaddr);
- protocol = *(u_char*)cp;
- cp += sizeof(u_char);
- port = _getshort(cp);
- cp += sizeof(u_short);
- fprintf(file, "\t%s\t; proto %d, port %d",
- address, protocol, port);
- }
- break;
- default:
- cp += dlen;
- }
- break;
- case T_CNAME:
- case T_MB:
- case T_MG:
- case T_MR:
- case T_NS:
- case T_PTR:
- putc('\t', file);
- cp = p_fqname(cp, msg, file);
- break;
-
- case T_HINFO:
- if (n = *cp++) {
- fprintf(file,"\t%.*s", n, cp);
- cp += n;
- }
- if (n = *cp++) {
- fprintf(file,"\t%.*s", n, cp);
- cp += n;
- }
- break;
-
- case T_SOA:
- putc('\t', file);
- cp = p_fqname(cp, msg, file); /* origin */
- putc(' ', file);
- cp = p_fqname(cp, msg, file); /* mail addr */
- fputs(" (\n", file);
- t = _getlong(cp); cp += sizeof(u_long);
- fprintf(file,"\t\t\t%lu\t; serial\n", t);
- t = _getlong(cp); cp += sizeof(u_long);
- fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t));
- t = _getlong(cp); cp += sizeof(u_long);
- fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t));
- t = _getlong(cp); cp += sizeof(u_long);
- fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t));
- t = _getlong(cp); cp += sizeof(u_long);
- fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t));
- break;
-
- case T_MX:
- case T_AFSDB:
- fprintf(file,"\t%d ", _getshort(cp));
- cp += sizeof(u_short);
- cp = p_fqname(cp, msg, file);
- break;
-
- case T_TXT:
- (void) fputs("\t\"", file);
- cp2 = cp1 + dlen;
- while (cp < cp2) {
- if (n = (unsigned char) *cp++) {
- for (c = n; c > 0 && cp < cp2; c--)
- if (*cp == '\n') {
- (void) putc('\\', file);
- (void) putc(*cp++, file);
- } else
- (void) putc(*cp++, file);
- }
- }
- putc('"', file);
- break;
-
- case T_MINFO:
- case T_RP:
- putc('\t', file);
- cp = p_fqname(cp, msg, file);
- putc(' ', file);
- cp = p_fqname(cp, msg, file);
- break;
-
- case T_UINFO:
- putc('\t', file);
- fputs(cp, file);
- cp += dlen;
- break;
-
- case T_UID:
- case T_GID:
- if (dlen == 4) {
- fprintf(file,"\t%u", _getlong(cp));
- cp += sizeof(long);
- }
- break;
-
- case T_WKS:
- if (dlen < sizeof(u_long) + 1)
- break;
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- cp += sizeof(u_long);
- fprintf(file, "\t%s %s ( ",
- inet_ntoa_r(inaddr, buf, sizeof(buf)),
- deproto((int) *cp));
- cp += sizeof(u_char);
- n = 0;
- lcnt = 0;
- while (cp < cp1 + dlen) {
- c = *cp++;
- do {
- if (c & 0200) {
- if (lcnt == 0) {
- fputs("\n\t\t\t", file);
- lcnt = 5;
- }
- fputs(dewks(n), file);
- putc(' ', file);
- lcnt--;
- }
- c <<= 1;
- } while (++n & 07);
- }
- putc(')', file);
- break;
-
-#ifdef ALLOW_T_UNSPEC
- case T_UNSPEC:
- {
- int NumBytes = 8;
- char *DataPtr;
- int i;
-
- if (dlen < NumBytes) NumBytes = dlen;
- fprintf(file, "\tFirst %d bytes of hex data:",
- NumBytes);
- for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
- fprintf(file, " %x", *DataPtr);
- cp += dlen;
- }
- break;
-#endif /* ALLOW_T_UNSPEC */
-
- default:
- fprintf(file,"\t?%d?", type);
- cp += dlen;
- }
-#if 0
- fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
-#else
- putc('\n', file);
-#endif
- if (cp - cp1 != dlen) {
- fprintf(file,";; packet size error (found %d, dlen was %d)\n",
- cp - cp1, dlen);
- cp = NULL;
- }
- return (cp);
-}
-
-static char nbuf[40];
-
-/*
- * Return a string for the type
- */
-char *
-__p_type(type)
- int type;
-{
- switch (type) {
- case T_A:
- return("A");
- case T_NS: /* authoritative server */
- return("NS");
- case T_CNAME: /* canonical name */
- return("CNAME");
- case T_SOA: /* start of authority zone */
- return("SOA");
- case T_MB: /* mailbox domain name */
- return("MB");
- case T_MG: /* mail group member */
- return("MG");
- case T_MR: /* mail rename name */
- return("MR");
- case T_NULL: /* null resource record */
- return("NULL");
- case T_WKS: /* well known service */
- return("WKS");
- case T_PTR: /* domain name pointer */
- return("PTR");
- case T_HINFO: /* host information */
- return("HINFO");
- case T_MINFO: /* mailbox information */
- return("MINFO");
- case T_MX: /* mail routing info */
- return("MX");
- case T_TXT: /* text */
- return("TXT");
- case T_RP: /* responsible person */
- return("RP");
- case T_AFSDB: /* AFS cell database */
- return("AFSDB");
- case T_AXFR: /* zone transfer */
- return("AXFR");
- case T_MAILB: /* mail box */
- return("MAILB");
- case T_MAILA: /* mail address */
- return("MAILA");
- case T_ANY: /* matches any type */
- return("ANY");
- case T_UINFO:
- return("UINFO");
- case T_UID:
- return("UID");
- case T_GID:
- return("GID");
-#ifdef ALLOW_T_UNSPEC
- case T_UNSPEC:
- return("UNSPEC");
-#endif /* ALLOW_T_UNSPEC */
-
- default:
- (void)sprintf(nbuf, "%d", type);
- return(nbuf);
- }
-}
-
-/*
- * Return a mnemonic for class
- */
-char *
-__p_class(class)
- int class;
-{
-
- switch (class) {
- case C_IN: /* internet class */
- return("IN");
- case C_HS: /* hesiod class */
- return("HS");
- case C_ANY: /* matches any class */
- return("ANY");
- default:
- (void)sprintf(nbuf, "%d", class);
- return(nbuf);
- }
-}
-
-/*
- * Return a mnemonic for an option
- */
-static char *
-p_option(option)
- u_long option;
-{
- switch (option) {
- case RES_INIT: return "init";
- case RES_DEBUG: return "debug";
- case RES_AAONLY: return "aaonly";
- case RES_USEVC: return "usevc";
- case RES_PRIMARY: return "primry";
- case RES_IGNTC: return "igntc";
- case RES_RECURSE: return "recurs";
- case RES_DEFNAMES: return "defnam";
- case RES_STAYOPEN: return "styopn";
- case RES_DNSRCH: return "dnsrch";
- default: sprintf(nbuf, "?0x%x?", option); return nbuf;
- }
-}
-
-/*
- * Return a mnemonic for a time to live
- */
-char *
-__p_time(value)
- u_long value;
-{
- int secs, mins, hours, days;
- register char *p;
-
- if (value == 0) {
- strcpy(nbuf, "0 secs");
- return(nbuf);
- }
-
- secs = value % 60;
- value /= 60;
- mins = value % 60;
- value /= 60;
- hours = value % 24;
- value /= 24;
- days = value;
- value = 0;
-
-#define PLURALIZE(x) x, (x == 1) ? "" : "s"
- p = nbuf;
- if (days) {
- (void)sprintf(p, "%d day%s", PLURALIZE(days));
- while (*++p);
- }
- if (hours) {
- if (days)
- *p++ = ' ';
- (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
- while (*++p);
- }
- if (mins) {
- if (days || hours)
- *p++ = ' ';
- (void)sprintf(p, "%d min%s", PLURALIZE(mins));
- while (*++p);
- }
- if (secs || ! (days || hours || mins)) {
- if (days || hours || mins)
- *p++ = ' ';
- (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
- }
- return(nbuf);
-}
diff --git a/mit-pthreads/net/res_init.c b/mit-pthreads/net/res_init.c
deleted file mode 100644
index 0a5c944c974..00000000000
--- a/mit-pthreads/net/res_init.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_init.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <resolv.h>
-#include <netdb.h>
-#include "res_internal.h"
-
-int res_init()
-{
- if (_res_init()) {
- return 0;
- } else {
- /* Due to clever tricks in _res_init(), a check for h_errno will
- * return NO_RECOVERY even if the next try at initialization
- * succeeds, so it's okay that we can't set an error value here. */
- return -1;
- }
-}
-
diff --git a/mit-pthreads/net/res_internal.c b/mit-pthreads/net/res_internal.c
deleted file mode 100644
index 4eab65bf5aa..00000000000
--- a/mit-pthreads/net/res_internal.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_internal.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <resolv.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <errno.h>
-#include "res_internal.h"
-
-#define DEFAULT_RETRIES 4
-
-pthread_mutex_t host_iterate_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-static pthread_key_t key;
-static int init_status;
-
-static void _res_init_global(void);
-static void set_options(const char *options, const char *source);
-static pthread_ipaddr_type net_mask(struct in_addr in);
-static int qcomp(const void *arg1, const void *arg2);
-
-static struct __res_state start;
-/* We want to define _res for partial binary compatibility with libraries. */
-#undef _res
-struct __res_state _res = {
- RES_TIMEOUT, /* retransmition time interval */
- 4, /* number of times to retransmit */
- RES_DEFAULT, /* options flags */
- 1, /* number of name servers */
-};
-
-struct hostent *_res_parse_answer(querybuf *answer, int anslen, int iquery,
- struct hostent *result, char *buf,
- int bufsize, int *errval)
-{
- struct res_data *data = _res_init();
- register HEADER *hp;
- register u_char *cp;
- register int n;
- u_char *eom;
- char *aliases[__NETDB_MAXALIASES], *addrs[__NETDB_MAXADDRS];
- char *bp = buf, **ap = aliases, **hap = addrs;
- int type, class, ancount, qdcount, getclass = C_ANY, iquery_done = 0;
-
- eom = answer->buf + anslen;
- /*
- * find first satisfactory answer
- */
- hp = &answer->hdr;
- ancount = ntohs(hp->ancount);
- qdcount = ntohs(hp->qdcount);
- bp = buf;
- cp = answer->buf + sizeof(HEADER);
-
- /* Read in the hostname if this is an address lookup. */
- if (qdcount) {
- if (iquery) {
- if ((n = dn_expand((u_char *) answer->buf,
- (u_char *) eom, (u_char *) cp, (u_char *) bp,
- bufsize - (bp - buf))) < 0) {
- *errval = NO_RECOVERY;
- return ((struct hostent *) NULL);
- }
- cp += n + QFIXEDSZ;
- result->h_name = bp;
- bp += strlen(bp) + 1;
- } else {
- cp += __dn_skipname(cp, eom) + QFIXEDSZ;
- }
- while (--qdcount > 0)
- cp += __dn_skipname(cp, eom) + QFIXEDSZ;
- } else if (iquery) {
- *errval = (hp->aa) ? HOST_NOT_FOUND : TRY_AGAIN;
- return ((struct hostent *) NULL);
- }
-
- /* Read in the answers. */
- *ap = NULL;
- *hap = NULL;
- while (--ancount >= 0 && cp < eom) {
- if ((n = dn_expand((u_char *) answer->buf, (u_char *) eom,
- (u_char *) cp, (u_char *) bp,
- bufsize - (bp - buf))) < 0)
- break;
- cp += n;
- type = _getshort(cp);
- cp += sizeof(u_short);
- class = _getshort(cp);
- cp += sizeof(u_short) + sizeof(pthread_ipaddr_type);
- n = _getshort(cp);
- cp += sizeof(u_short);
- if (type == T_CNAME) {
- cp += n;
- if (ap >= aliases + __NETDB_MAXALIASES - 1)
- continue;
- *ap++ = bp;
- bp += strlen(bp) + 1;
- continue;
- }
- if (iquery && type == T_PTR) {
- if ((n = dn_expand((u_char *) answer->buf, (u_char *) eom,
- (u_char *) cp, (u_char *) bp,
- bufsize - (bp - buf))) < 0)
- break;
- cp += n;
- result->h_name = bp;
- bp += strlen(bp) + 1;
- iquery_done = 1;
- break;
- }
- if (iquery || type != T_A) {
-#ifdef DEBUG_RESOLVER
- if (data->state.options & RES_DEBUG)
- printf("unexpected answer type %d, size %d\n",
- type, n);
-#endif
- cp += n;
- continue;
- }
- if (hap > addrs) {
- if (n != result->h_length) {
- cp += n;
- continue;
- }
- if (class != getclass) {
- cp += n;
- continue;
- }
- } else {
- result->h_length = n;
- getclass = class;
- result->h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
- if (!iquery) {
- result->h_name = bp;
- bp += strlen(bp) + 1;
- }
- }
- bp = ALIGN(bp, pthread_ipaddr_type);
- if (bp + n >= buf + bufsize) {
- errno = ERANGE;
- return NULL;
- }
- memcpy(bp, cp, n);
- cp += n;
- if (hap >= addrs + __NETDB_MAXADDRS - 1)
- continue;
- *hap++ = bp;
- bp += n;
- cp += n;
- }
-
- if (hap > addrs || iquery_done) {
- *ap++ = NULL;
- *hap++ = NULL;
- if (data->state.nsort)
- qsort(addrs, hap - addrs, sizeof(struct in_addr), qcomp);
- if (SP(bp, char *, (hap - addrs) + (ap - aliases)) > buf + bufsize) {
- errno = ERANGE;
- return NULL;
- }
- result->h_addr_list = (char **) ALIGN(bp, char *);
- memcpy(result->h_addr_list, addrs, (hap - addrs) * sizeof(char *));
- result->h_aliases = result->h_addr_list + (hap - addrs);
- memcpy(result->h_aliases, aliases, (ap - aliases) * sizeof(char *));
- return result;
- } else {
- *errval = TRY_AGAIN;
- return NULL;
- }
-}
-
-/* Performs global initialization. */
-struct res_data *_res_init()
-{
- struct res_data *data;
-
- /* Make sure the global initializations have been done. */
- pthread_once(&init_once, _res_init_global);
- if (init_status < 0)
- return NULL;
-
- /* Initialize thread-specific data for this thread if it hasn't
- * been done already. */
- data = (struct res_data *) pthread_getspecific(key);
- if (!data) {
- data = (struct res_data *) malloc(sizeof(struct res_data));
- if (data == NULL)
- return NULL;
- if (pthread_setspecific(key, data) < 0) {
- free(data);
- return NULL;
- }
- data->buf = NULL;
- data->state = start;
- data->errval = NO_RECOVERY;
- data->sock = -1;
- }
- return data;
-}
-
-static void _res_init_global()
-{
- int result;
- char line[BUFSIZ], buf[BUFSIZ], *domain, *p, *net;
- int i, localdomain_set = 0, num_servers = 0, num_sorts = 0;
- FILE *fp;
- struct in_addr addr;
-
- /* Assume an error state until we finish. */
- init_status = -1;
-
- /* Initialize the key for thread-specific data. */
- result = pthread_key_create(&key, free);
- if (result < 0)
- return;
-
- /* Initialize starting state. */
- start.retrans = RES_TIMEOUT;
- start.retry = DEFAULT_RETRIES;
- start.options = RES_DEFAULT;
- start.id = 0;
- start.nscount = 1;
- start.nsaddr.sin_addr.s_addr = INADDR_ANY;
- start.nsaddr.sin_family = AF_INET;
- start.nsaddr.sin_port = htons(NAMESERVER_PORT);
- start.nscount = 1;
- start.ndots = 1;
- start.pfcode = 0;
- strncpy(start.lookups, "f", sizeof(start.lookups));
-
- /* Look for a LOCALDOMAIN definition. */
- domain = getenv("LOCALDOMAIN");
- if (domain != NULL) {
- strncpy(start.defdname, domain, sizeof(start.defdname));
- domain = start.defdname;
- localdomain_set = 1;
-
- /* Construct a search path from the LOCALDOMAIN value, which is
- * a space-separated list of strings. For backwards-compatibility,
- * a newline terminates the list. */
- i = 0;
- while (*domain && i < MAXDNSRCH) {
- start.dnsrch[i] = domain;
- while (*domain && !isspace(*domain))
- domain++;
- if (!*domain || *domain == '\n') {
- *domain = 0;
- break;
- }
- *domain++ = 0;
- while (isspace(*domain))
- domain++;
- i++;
- }
- }
-
- /* Look for a config file and read it in. */
- fp = fopen(_PATH_RESCONF, "r");
- if (fp != NULL) {
- strncpy(start.lookups, "bf", sizeof(start.lookups));
-
- /* Read in the configuration file. */
- while (fgets(line, sizeof(line), fp)) {
-
- /* Ignore blank lines and comments. */
- if (*line == ';' || *line == '#' || !*line)
- continue;
-
- if (strncmp(line, "domain", 6) == 0) {
-
- /* Read in the default domain, and initialize a one-
- * element search path. Skip the domain line if we
- * already got one from the LOCALDOMAIN environment
- * variable. */
- if (localdomain_set)
- continue;
-
- /* Look for the next word in the line. */
- p = line + 6;
- while (*p == ' ' || *p == '\t')
- p++;
- if (!*p || *p == '\n')
- continue;
-
- /* Copy in the domain, and null-terminate it at the
- * first tab or newline. */
- strncpy(start.defdname, p, sizeof(start.defdname) - 1);
- p = strpbrk(start.defdname, "\t\n");
- if (p)
- *p = 0;
-
- start.dnsrch[0] = start.defdname;
- start.dnsrch[1] = NULL;
-
- } else if (strncmp(line, "lookup", 6) == 0) {
-
- /* Get a list of lookup types. */
- memset(start.lookups, 0, sizeof(start.lookups));
-
- /* Find the next word in the line. */
- p = line + 6;
- while (isspace(*p))
- p++;
-
- i = 0;
- while (*p && i < MAXDNSLUS) {
- /* Add a lookup type. */
- if (*p == 'y' || *p == 'b' || *p == 'f')
- start.lookups[i++] = *p;
-
- /* Find the next word. */
- while (*p && !isspace(*p))
- p++;
- while (isspace(*p))
- p++;
- }
-
- } else if (strncmp(line, "search", 6) == 0) {
-
- /* Read in a space-separated list of domains to search
- * when a name is not fully-qualified. Skip this line
- * if the LOCALDOMAIN environment variable was set. */
- if (localdomain_set)
- continue;
-
- /* Look for the next word on the line. */
- p = line + 6;
- while (*p == ' ' || *p == '\t')
- p++;
- if (!*p || *p == '\n')
- continue;
-
- /* Copy the rest of the line into start.defdname. */
- strncpy(start.defdname, p, sizeof(start.defdname) - 1);
- domain = start.defdname;
- p = strchr(domain, '\n');
- if (*p)
- *p = 0;
-
- /* Construct a search path from the line, which is a
- * space-separated list of strings. */
- i = 0;
- while (*domain && i < MAXDNSRCH) {
- start.dnsrch[i] = domain;
- while (*domain && !isspace(*domain))
- domain++;
- if (!*domain || *domain == '\n') {
- *domain = 0;
- break;
- }
- *domain++ = 0;
- while (isspace(*domain))
- domain++;
- i++;
- }
-
- } else if (strncmp(line, "nameserver", 10) == 0) {
-
- /* Add an address to the list of name servers we can
- * connect to. */
-
- /* Look for the next word in the line. */
- p = line + 10;
- while (*p == ' ' || *p == '\t')
- p++;
- if (*p && *p != '\n' && inet_aton(p, &addr)) {
- start.nsaddr_list[num_servers].sin_addr = addr;
- start.nsaddr_list[num_servers].sin_family = AF_INET;
- start.nsaddr_list[num_servers].sin_port =
- htons(NAMESERVER_PORT);
- if (++num_servers >= MAXNS)
- break;
- }
-
- } else if (strncmp(line, "sortlist", 8) == 0) {
-
- p = line + 8;
- while (num_sorts < MAXRESOLVSORT) {
-
- /* Find the next word in the line. */
- p = line + 8;
- while (*p == ' ' || *p == '\t')
- p++;
-
- /* Read in an IP address and netmask. */
- if (sscanf(p, "%[0-9./]s", buf) != 1)
- break;
- net = strchr(buf, '/');
- if (net)
- *net = 0;
-
- /* Translate the address into an IP address
- * and netmask. */
- if (inet_aton(buf, &addr)) {
- start.sort_list[num_sorts].addr = addr;
- if (net && inet_aton(net + 1, &addr)) {
- start.sort_list[num_sorts].mask = addr.s_addr;
- } else {
- start.sort_list[num_sorts].mask =
- net_mask(start.sort_list[num_sorts].addr);
- }
- num_sorts++;
- }
-
- /* Skip past this word. */
- if (net)
- *net = '/';
- p += strlen(buf);
- }
-
- }
- }
- fclose(fp);
- }
-
- /* If we don't have a default domain, strip off the first
- * component of this machine's domain name, and make a one-
- * element search path consisting of the default domain. */
- if (*start.defdname == 0) {
- if (gethostname(buf, sizeof(start.defdname) - 1) == 0) {
- p = strchr(buf, '.');
- if (p)
- strcpy(start.defdname, p + 1);
- }
- start.dnsrch[0] = start.defdname;
- start.dnsrch[1] = NULL;
- }
-
- p = getenv("RES_OPTIONS");
- if (p)
- set_options(p, "env");
-
- start.options |= RES_INIT;
- _res = start;
- init_status = 0;
-}
-
-static void set_options(const char *options, const char *source)
-{
- const char *p = options;
- int i;
-
- while (*p) {
-
- /* Skip leading and inner runs of spaces. */
- while (*p == ' ' || *p == '\t')
- p++;
-
- /* Search for and process individual options. */
- if (strncmp(p, "ndots:", 6) == 0) {
- i = atoi(p + 6);
- start.ndots = (i <= RES_MAXNDOTS) ? i : RES_MAXNDOTS;
- } else if (!strncmp(p, "debug", 5))
- start.options |= RES_DEBUG;
- else if (!strncmp(p, "usevc", 5))
- start.options |= RES_USEVC;
- else if (!strncmp(p, "stayopen", 8))
- start.options |= RES_STAYOPEN;
-
- /* Skip to next run of spaces */
- while (*p && *p != ' ' && *p != '\t')
- p++;
- }
-}
-
-static pthread_ipaddr_type net_mask(struct in_addr in)
-{
- pthread_ipaddr_type i = ntohl(in.s_addr);
-
- if (IN_CLASSA(i))
- return htonl(IN_CLASSA_NET);
- if (IN_CLASSB(i))
- return htonl(IN_CLASSB_NET);
- return htonl(IN_CLASSC_NET);
-}
-
-/* Get the error value for this thread, or NO_RECOVERY if none has been
- * successfully set. The screw case to worry about here is if
- * __res_init() fails for a resolver routine because it can't allocate
- * or set the thread-specific data, and then __res_init() succeeds here.
- * Because __res_init() sets errval to NO_RECOVERY after a successful
- * initialization, we return NO_RECOVERY in that case, which is correct. */
-int _res_get_error()
-{
- struct res_data *data;
-
- data = _res_init();
- return (data) ? data->errval : NO_RECOVERY;
-}
-
-struct __res_state *_res_status()
-{
- struct res_data *data;
-
- data = _res_init();
- return (data) ? &data->state : NULL;
-}
-
-static int qcomp(const void *arg1, const void *arg2)
-{
- const struct in_addr **a1 = (const struct in_addr **) arg1;
- const struct in_addr **a2 = (const struct in_addr **) arg2;
- struct __res_state *state = _res_status();
-
- int pos1, pos2;
-
- for (pos1 = 0; pos1 < state->nsort; pos1++) {
- if (state->sort_list[pos1].addr.s_addr ==
- ((*a1)->s_addr & state->sort_list[pos1].mask))
- break;
- }
- for (pos2 = 0; pos2 < state->nsort; pos2++) {
- if (state->sort_list[pos2].addr.s_addr ==
- ((*a2)->s_addr & state->sort_list[pos2].mask))
- break;
- }
- return pos1 - pos2;
-}
-
-/*
- * This routine is for closing the socket if a virtual circuit is used and
- * the program wants to close it. We don't use this routine, but libc
- * might reference it.
- *
- * This routine is not expected to be user visible.
- */
-void _res_close()
-{
- struct res_data *data;
-
- data = _res_init();
- if (data && data->sock != -1) {
- (void) close(data->sock);
- data->sock = -1;
- }
-}
diff --git a/mit-pthreads/net/res_internal.h b/mit-pthreads/net/res_internal.h
deleted file mode 100644
index 24e70278644..00000000000
--- a/mit-pthreads/net/res_internal.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_internal.h 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#ifndef _RES_INTERNAL_H
-#define _RES_INTERNAL_H
-
-#include <pthread.h>
-#include <netdb.h>
-#include <resolv.h>
-
-#define HOST_BUFSIZE 4096
-#undef ALIGN
-#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t)))
-#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t))
-
-struct res_data {
- char *buf;
- struct __res_state state;
- int errval;
- int sock;
-};
-
-#if PACKETSZ > 1024
-#define MAXPACKET PACKETSZ
-#else
-#define MAXPACKET 1024
-#endif
-
-typedef union {
- HEADER hdr;
- unsigned char buf[MAXPACKET];
-} querybuf;
-
-typedef union {
- long al;
- char ac;
-} align;
-
-extern pthread_mutex_t host_iterate_lock;
-
-__BEGIN_DECLS
-struct hostent *_res_parse_answer(querybuf *answer, int anslen, int iquery,
- struct hostent *result, char *buf,
- int buflen, int *errval);
-void _res_set_error(int val);
-struct res_data *_res_init(void);
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/net/res_mkquery.c b/mit-pthreads/net/res_mkquery.c
deleted file mode 100644
index 42f27318368..00000000000
--- a/mit-pthreads/net/res_mkquery.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_mkquery.c 6.16 (Berkeley) 3/6/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/param.h>
-#include <sys/cdefs.h>
-#include <netinet/in.h>
-#include <resolv.h>
-#include <stdio.h>
-#include <string.h>
-
-/*
- * Form all types of queries.
- * Returns the size of the result or -1.
- */
-res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
- int op; /* opcode of query */
- const char *dname; /* domain name */
- int class, type; /* class and type of query */
- const char *data; /* resource record data */
- int datalen; /* length of data */
- const char *newrr_in; /* new rr for modify or append */
- char *buf; /* buffer to put query */
- int buflen; /* size of buffer */
-{
- register HEADER *hp;
- register char *cp;
- register int n;
- struct rrec *newrr = (struct rrec *) newrr_in;
- char *dnptrs[10], **dpp, **lastdnptr;
- struct __res_state *_rs;
-
- /*
- * Initialize header fields.
- */
-
- _rs = _res_status();
- if (!_rs)
- return -1;
- if ((buf == NULL) || (buflen < sizeof(HEADER)))
- return(-1);
- memset(buf, 0, sizeof(HEADER));
- hp = (HEADER *) buf;
- hp->id = htons(++_rs->id);
- hp->opcode = op;
- hp->pr = (_rs->options & RES_PRIMARY) != 0;
- hp->rd = (_rs->options & RES_RECURSE) != 0;
- hp->rcode = NOERROR;
- cp = buf + sizeof(HEADER);
- buflen -= sizeof(HEADER);
- dpp = dnptrs;
- *dpp++ = buf;
- *dpp++ = NULL;
- lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
- /*
- * perform opcode specific processing
- */
- switch (op) {
- case QUERY:
- if ((buflen -= QFIXEDSZ) < 0)
- return(-1);
- if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen,
- (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
- return (-1);
- cp += n;
- buflen -= n;
- __putshort(type, (u_char *)cp);
- cp += sizeof(u_short);
- __putshort(class, (u_char *)cp);
- cp += sizeof(u_short);
- hp->qdcount = htons(1);
- if (op == QUERY || data == NULL)
- break;
- /*
- * Make an additional record for completion domain.
- */
- buflen -= RRFIXEDSZ;
- if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen,
- (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
- return (-1);
- cp += n;
- buflen -= n;
- __putshort(T_NULL, (u_char *)cp);
- cp += sizeof(u_short);
- __putshort(class, (u_char *)cp);
- cp += sizeof(u_short);
- __putlong(0, (u_char *)cp);
- cp += sizeof(pthread_ipaddr_type);
- __putshort(0, (u_char *)cp);
- cp += sizeof(u_short);
- hp->arcount = htons(1);
- break;
-
- case IQUERY:
- /*
- * Initialize answer section
- */
- if (buflen < 1 + RRFIXEDSZ + datalen)
- return (-1);
- *cp++ = '\0'; /* no domain name */
- __putshort(type, (u_char *)cp);
- cp += sizeof(u_short);
- __putshort(class, (u_char *)cp);
- cp += sizeof(u_short);
- __putlong(0, (u_char *)cp);
- cp += sizeof(pthread_ipaddr_type);
- __putshort(datalen, (u_char *)cp);
- cp += sizeof(u_short);
- if (datalen) {
- memcpy(cp, data, datalen);
- cp += datalen;
- }
- hp->ancount = htons(1);
- break;
-
-#ifdef ALLOW_UPDATES
- /*
- * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
- * (Record to be modified is followed by its replacement in msg.)
- */
- case UPDATEM:
- case UPDATEMA:
-
- case UPDATED:
- /*
- * The res code for UPDATED and UPDATEDA is the same; user
- * calls them differently: specifies data for UPDATED; server
- * ignores data if specified for UPDATEDA.
- */
- case UPDATEDA:
- buflen -= RRFIXEDSZ + datalen;
- if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
- return (-1);
- cp += n;
- __putshort(type, cp);
- cp += sizeof(u_short);
- __putshort(class, cp);
- cp += sizeof(u_short);
- __putlong(0, cp);
- cp += sizeof(pthread_ipaddr_type);
- __putshort(datalen, cp);
- cp += sizeof(u_short);
- if (datalen) {
- memcpy(cp, data, datalen);
- cp += datalen;
- }
- if ( (op == UPDATED) || (op == UPDATEDA) ) {
- hp->ancount = htons(0);
- break;
- }
- /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
-
- case UPDATEA: /* Add new resource record */
- buflen -= RRFIXEDSZ + datalen;
- if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
- return (-1);
- cp += n;
- __putshort(newrr->r_type, cp);
- cp += sizeof(u_short);
- __putshort(newrr->r_class, cp);
- cp += sizeof(u_short);
- __putlong(0, cp);
- cp += sizeof(pthread_ipaddr_type);
- __putshort(newrr->r_size, cp);
- cp += sizeof(u_short);
- if (newrr->r_size) {
- memcpy(cp, newrr->r_data, newrr->r_size);
- cp += newrr->r_size;
- }
- hp->ancount = htons(0);
- break;
-
-#endif /* ALLOW_UPDATES */
- }
- return (cp - buf);
-}
-
diff --git a/mit-pthreads/net/res_query.c b/mit-pthreads/net/res_query.c
deleted file mode 100644
index 1727e6d1179..00000000000
--- a/mit-pthreads/net/res_query.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_query.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <resolv.h>
-#include <netdb.h>
-#include "res_internal.h"
-
-#if PACKETSZ > 1024
-#define MAXPACKET PACKETSZ
-#else
-#define MAXPACKET 1024
-#endif
-
-int res_query(char *name, int class, int type, unsigned char *answer,
- int anslen)
-{
- struct res_data *data;
- char buf[MAXPACKET];
- int result;
- HEADER *hp;
-
- data = _res_init();
- if (!data)
- return -1;
-
- /* Make the query. */
- result = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, buf,
- sizeof(buf));
- if (result <= 0) {
- data->errval = NO_RECOVERY;
- return result;
- }
-
- result = res_send(buf, result, (char *) answer, anslen);
- if (result < 0) {
- data->errval = TRY_AGAIN;
- return result;
- }
-
- hp = (HEADER *) answer;
- if (hp->rcode == NOERROR && ntohs(hp->ancount) != 0)
- return result;
-
- /* Translate the error code and return. */
- switch(hp->rcode) {
- case NOERROR:
- data->errval = NO_DATA;
- break;
- case SERVFAIL:
- data->errval = TRY_AGAIN;
- break;
- case NXDOMAIN:
- data->errval = HOST_NOT_FOUND;
- break;
- default:
- data->errval = NO_RECOVERY;
- break;
- }
- return -1;
-}
-
diff --git a/mit-pthreads/net/res_querydomain.c b/mit-pthreads/net/res_querydomain.c
deleted file mode 100644
index 31beeb7a62c..00000000000
--- a/mit-pthreads/net/res_querydomain.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_querydomain.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <resolv.h>
-#include <string.h>
-
-/* For backwards compatibility. */
-int res_querydomain(char *name, char *domain, int class, int type,
- unsigned char *answer, int anslen)
-{
- char buf[2 * MAXDNAME + 2];
- char *longname = buf;
- int len;
-
- if (domain == NULL) {
- /* Check for trailing '.'; copy without '.' if present. */
- len = strlen(name);
- if (len > 0 && name[len - 1] == '.' && len < sizeof(buf)) {
- memcpy(buf, name, len - 1);
- buf[len - 1] = '\0';
- } else {
- longname = name;
- }
- } else {
- sprintf(buf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
- }
-
- return (res_query(longname, class, type, answer, anslen));
-}
-
diff --git a/mit-pthreads/net/res_search.c b/mit-pthreads/net/res_search.c
deleted file mode 100644
index 2c84f0d68f3..00000000000
--- a/mit-pthreads/net/res_search.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_search.c 6.45 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <resolv.h>
-#include <netdb.h>
-#include "res_internal.h"
-
-static char *search_aliases(const char *name, char *buf, int bufsize);
-
-int res_search(const char *name, int class, int type, unsigned char *answer,
- int anslen)
-{
- struct res_data *data;
- const char *p;
- int num_dots, len, result, no_data = 0, error;
- char buf[2 * MAXDNAME + 2], *domain, **dptr, *alias;
-
- data = _res_init();
- if (!data)
- return -1;
-
- /* Count the dots in name, and get a pointer to the end of name. */
- num_dots = 0;
- for (p = name; *p; p++) {
- if (*p == '.')
- num_dots++;
- }
- len = p - name;
-
- /* If there aren't any dots, check to see if name is an alias for
- * another host. If so, try the resolved alias as a fully-qualified
- * name. */
- alias = search_aliases(name, buf, sizeof(buf));
- if (alias != NULL)
- return res_query(alias, class, type, answer, anslen);
-
- /* If there's a trailing dot, try to strip it off and query the name. */
- if (len > 0 && p[-1] == '.') {
- if (len > sizeof(buf)) {
- /* It's too long; just query the original name. */
- return res_query(name, class, type, answer, anslen);
- } else {
- /* Copy the name without the trailing dot and query. */
- memcpy(buf, name, len - 1);
- buf[len] = 0;
- return res_query(buf, class, type, answer, anslen);
- }
- }
-
- if (data->state.options & RES_DNSRCH) {
- /* If RES_DNSRCH is set, query all the domains until we get a
- * definitive answer. */
- for (dptr = data->state.dnsrch; *dptr; dptr++) {
- domain = *dptr;
- sprintf(buf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
- result = res_query(buf, class, type, answer, anslen);
- if (result > 0)
- return result;
- if (data->errval == NO_DATA)
- no_data = 1;
- else if (data->errval != HOST_NOT_FOUND)
- break;
- }
- } else if (num_dots == 0 && data->state.options & RES_DEFNAMES) {
- /* If RES_DEFNAMES is set and there is no dot, query the default
- * domain. */
- domain = data->state.defdname;
- sprintf(buf, "%.*s.%.%s", MAXDNAME, name, MAXDNAME, domain);
- result = res_query(buf, class, type, answer, anslen);
- if (result > 0)
- return result;
- if (data->errval == NO_DATA)
- no_data = 1;
- }
-
- /* If all the domain queries failed, try the name as fully-qualified.
- * Only do this if there is at least one dot in the name. */
- if (num_dots > 0) {
- result = res_query(name, class, type, answer, anslen);
- if (result > 0)
- return result;
- }
-
- if (no_data)
- data->errval = NO_DATA;
-
- return -1;
-}
-
-static char *search_aliases(const char *name, char *buf, int bufsize)
-{
- FILE *fp;
- char *filename, *p;
- int len;
-
- filename = getenv("HOSTALIASES");
- if (filename == NULL)
- return NULL;
-
- fp = fopen(filename, "r");
- if (fp == NULL)
- return NULL;
-
- len = strlen(name);
- while (fgets(buf, bufsize, fp)) {
-
- /* Get the first word from the buffer. */
- p = buf;
- while (*p && !isspace(*p))
- p++;
- if (!*p)
- break;
-
- /* Null-terminate the first word and compare it with the name. */
- *p = 0;
- if (strcasecmp(buf, name) != 0)
- continue;
-
- p++;
- while (isspace(*p))
- p++;
- fclose(fp);
- return (*p) ? p : NULL;
- }
-
- fclose(fp);
- return NULL;
-}
-
diff --git a/mit-pthreads/net/res_send.c b/mit-pthreads/net/res_send.c
deleted file mode 100644
index 84162e8e387..00000000000
--- a/mit-pthreads/net/res_send.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)res_send.c 6.45 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-#include <resolv.h>
-#include <netdb.h>
-#include <time.h>
-#include <sys/timers.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include "res_internal.h"
-
-enum { SEND_GIVE_UP = -1, SEND_TRY_NEXT = -2, SEND_TRY_SAME = -3,
- SEND_TIMEOUT = -4, SEND_TRUNCATED = -5 };
-
-static int send_datagram(int server, int sock, const char *buf, int buflen,
- char *answer, int anslen, int try,
- struct res_data *data);
-static int send_circuit(int server, const char *buf, int buflen, char *answer,
- int anslen, struct res_data *data);
-static int close_save_errno(int sock);
-
-int res_send(const char *buf, int buflen, char *answer, int anslen)
-{
- struct res_data *data;
- struct sockaddr_in local;
- int use_virtual_circuit, result, udp_sock, have_seen_same, terrno = 0;
- int try, server;
-
- data = _res_init();
- if (!data)
- return -1;
-
- try = 0;
- server = 0;
-
- /* Try doing connectionless queries if appropriate. */
- if (!(data->state.options & RES_USEVC) && buflen <= PACKETSZ) {
- /* Create and bind a local UDP socket. */
- udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (udp_sock < 0)
- return -1;
- local.sin_family = AF_INET;
- local.sin_addr.s_addr = htonl(INADDR_ANY);
- local.sin_port = htons(0);
- if (bind(udp_sock, (struct sockaddr *) &local, sizeof(local)) < 0) {
- close(udp_sock);
- return -1;
- }
-
- /* Cycle through the retries and servers, sending off queries and
- * waiting for responses. */
- for (; try < data->state.retry; try++) {
- for (; server < data->state.nscount; server++) {
- result = send_datagram(server, udp_sock, buf, buflen, answer,
- anslen, try, data);
- if (result == SEND_TIMEOUT)
- terrno = ETIMEDOUT;
- else if (result != SEND_TRY_NEXT)
- break;
- }
- if (server < data->state.nscount)
- break;
- }
-
- close(udp_sock);
- if (result < 0)
- errno = (terrno == ETIMEDOUT) ? ETIMEDOUT : ECONNREFUSED;
- else
- errno = 0;
- if (result != SEND_TRUNCATED)
- return (result >= 0) ? result : -1;
- }
-
- /* Either we have to use the virtual circuit, or the server couldn't
- * fit its response in a UDP packet. Cycle through the retries and
- * servers, sending off queries and waiting for responses. Allow a
- * response of SEND_TRY_SAME to cause an extra retry once. */
- for (; try < data->state.retry; try++) {
- for (; server < data->state.nscount; server++) {
- result = send_circuit(server, buf, buflen, answer, anslen, data);
- terrno = errno;
- if (result == SEND_TRY_SAME) {
- if (!have_seen_same)
- server--;
- have_seen_same = 1;
- } else if (result != SEND_TRY_NEXT) {
- break;
- }
- }
- }
-
- errno = terrno;
- return (result >= 0) ? result : -1;
-}
-
-static int send_datagram(int server, int sock, const char *buf, int buflen,
- char *answer, int anslen, int try,
- struct res_data *data)
-{
- int count, interval;
- struct sockaddr_in local_addr;
- HEADER *request = (HEADER *) buf, *response = (HEADER *) answer;
- struct timespec timeout;
- struct timeval current;
- struct timezone zone;
-
-#ifdef DEBUG_RESOLVER
- if (_res.options & RES_DEBUG) {
- printf("res_send: request:\n");
- __p_query(buf);
- }
-#endif /* DEBUG_RESOLVER */
- /* Send a packet to the server. */
- count = sendto(sock, buf, buflen, 0,
- (struct sockaddr *) &data->state.nsaddr_list[server],
- sizeof(struct sockaddr_in));
-
- if (count != buflen) {
-#ifdef DEBUG_RESOLVER
- if (count < 0){
- if (_res.options & RES_DEBUG)
- perror("send_datagram:sendto");
- }
-#endif /* DEBUG_RESOLVER */
- return SEND_TRY_NEXT;
- }
-
- /* Await a reply with the correct ID. */
- while (1) {
- struct sockaddr_in from;
- int from_len;
-
- from_len = sizeof(from);
- interval = data->state.retrans << try;
- if (try > 0)
- interval /= data->state.nscount;
- gettimeofday(&current, &zone);
- current.tv_sec += interval;
- TIMEVAL_TO_TIMESPEC(&current, &timeout);
- count = recvfrom_timedwait(sock, answer, anslen, 0,
- &from, &from_len, &timeout);
- if (count < 0)
- return SEND_TRY_NEXT;
- /* If the ID is wrong, it's from an old query; ignore it. */
- if (response->id == request->id)
- break;
-#ifdef DEBUG_RESOLVER
- if (_res.options & RES_DEBUG) {
- printf("res_sendto: count=%d, response:\n", count);
- __p_query(answer);
- }
-#endif /* DEBUG_RESOLVER */
- }
-
- /* Report a truncated response unless RES_IGNTC is set. This will
- * cause the res_send() loop to fall back to TCP. */
- if (response->tc && !(data->state.options & RES_IGNTC))
- return SEND_TRUNCATED;
-
- return count;
-}
-
-static int send_circuit(int server, const char *buf, int buflen, char *answer,
- int anslen, struct res_data *data)
-{
- HEADER *response = (HEADER *) answer;
- int sock = -1, result, n, response_len, count;
- unsigned short len;
- struct iovec iov[2];
- char *p, junk[512];
-
- /* If data->sock is valid, then it's an open connection to the
- * first server. Grab it if it's appropriate; close it if not. */
- if (data->sock) {
- if (server == 0)
- sock = data->sock;
- else
- close(data->sock);
- data->sock = -1;
- }
-
- /* Initialize our socket if we didn't grab it from data. */
- if (sock == -1) {
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock < 0)
- return SEND_GIVE_UP;
- result = connect(sock,
- (struct sockaddr *) &data->state.nsaddr_list[server],
- sizeof(struct sockaddr_in));
- if (result < 0) {
- close_save_errno(sock);
- return SEND_TRY_NEXT;
- }
- }
-
- /* Send length and message. */
- len = htons((unsigned short) buflen);
- iov[0].iov_base = (caddr_t) &len;
- iov[0].iov_len = sizeof(len);
- iov[1].iov_base = (char *) buf;
- iov[1].iov_len = buflen;
- if (writev(sock, iov, 2) != sizeof(len) + buflen) {
- close_save_errno(sock);
- return SEND_TRY_NEXT;
- }
-
- /* Receive length. */
- p = (char *) &len;
- n = sizeof(len);
- while (n) {
- count = read(sock, p, n);
- if (count <= 0) {
- /* If we got ECONNRESET, the remote server may have restarted,
- * and we report SEND_TRY_SAME. (The main loop will only
- * allow one of these, so we don't have to worry about looping
- * indefinitely.) */
- close_save_errno(sock);
- return (errno == ECONNRESET) ? SEND_TRY_SAME : SEND_TRY_NEXT;
- }
- p += count;
- n -= count;
- }
- len = ntohs(len);
- response_len = (len > anslen) ? anslen : len;
- len -= response_len;
-
- /* Receive message. */
- p = answer;
- n = response_len;
- while (n) {
- count = read(sock, p, n);
- if (count <= 0) {
- close_save_errno(sock);
- return SEND_TRY_NEXT;
- }
- p += count;
- n -= count;
- }
-
- /* If the reply is longer than our answer buffer, set the truncated
- * bit and flush the rest of the reply, to keep the connection in
- * sync. */
- if (len) {
- response->tc = 1;
- while (len) {
- n = (len > sizeof(junk)) ? sizeof(junk) : len;
- count = read(sock, junk, n);
- if (count <= 0) {
- close_save_errno(sock);
- return response_len;
- }
- len -= count;
- }
- }
-
- /* If this is the first server, and RES_USEVC and RES_STAYOPEN are
- * both set, save the connection. Otherwise, close it. */
- if (server == 0 && (data->state.options & RES_USEVC &&
- data->state.options & RES_STAYOPEN))
- data->sock = sock;
- else
- close_save_errno(sock);
-
- return response_len;
-}
-
-static int close_save_errno(int sock)
-{
- int terrno;
-
- terrno = errno;
- close(sock);
- errno = terrno;
-}
diff --git a/mit-pthreads/net/serv_internal.c b/mit-pthreads/net/serv_internal.c
deleted file mode 100644
index f4acc8697ae..00000000000
--- a/mit-pthreads/net/serv_internal.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)serv_internal.c 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "serv_internal.h"
-
-#define DEFAULT_RETRIES 4
-
-static void _serv_init_global();
-
-pthread_mutex_t serv_iterate_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_once_t init_once = PTHREAD_ONCE_INIT;
-static pthread_key_t key;
-static int init_status;
-
-/* Performs global initialization. */
-char *_serv_buf()
-{
- char *buf;
-
- /* Make sure the global initializations have been done. */
- pthread_once(&init_once, _serv_init_global);
-
- /* Initialize thread-specific data for this thread if it hasn't
- * been done already. */
- buf = (char *) pthread_getspecific(key);
- if (!buf) {
- buf = (char *) malloc(sizeof(struct servent) + SERV_BUFSIZE);
- if (buf == NULL)
- return NULL;
- if (pthread_setspecific(key, buf) < 0) {
- free(buf);
- return NULL;
- }
- }
- return buf;
-}
-
-static void _serv_init_global()
-{
- init_status = pthread_key_create(&key, free);
-}
-
diff --git a/mit-pthreads/net/serv_internal.h b/mit-pthreads/net/serv_internal.h
deleted file mode 100644
index 60a7c02c2ea..00000000000
--- a/mit-pthreads/net/serv_internal.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)serv_internal.h 6.22 (Berkeley) 3/19/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#ifndef _SERV_INTERNAL_H
-#define _SERV_INTERNAL_H
-
-#include <pthread.h>
-#include <netdb.h>
-#include <resolv.h>
-
-#define SERV_BUFSIZE 4096
-#undef ALIGN
-#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t)))
-#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t))
-
-extern pthread_mutex_t serv_iterate_lock;
-
-__BEGIN_DECLS
-char *_serv_buf(void);
-__END_DECLS
-
-#endif
-
diff --git a/mit-pthreads/patches/Streepy.html b/mit-pthreads/patches/Streepy.html
deleted file mode 100755
index a3b4faa815f..00000000000
--- a/mit-pthreads/patches/Streepy.html
+++ /dev/null
@@ -1,2873 +0,0 @@
-diff -c -r1.1.1.1 pthread.h
-*** pthread.h 1996/03/13 04:30:57 1.1.1.1
---- pthread.h 1996/10/02 17:52:47
-***************
-*** 35,40 ****
---- 35,43 ----
- *
- * 1.00 93/07/20 proven
- * -Started coding this file.
-+ *
-+ * 93/9/28 streepy - Added support for pthread cancel
-+ *
- */
-
- #ifndef _PTHREAD_H_
-***************
-*** 65,70 ****
---- 68,82 ----
- /* More includes, that need size_t */
- #include <pthread/pthread_attr.h>
-
-+ /* Constants for use with pthread_setcancelstate and pthread_setcanceltype */
-+ #define PTHREAD_CANCEL_DISABLE 0
-+ #define PTHREAD_CANCEL_ENABLE 1
-+ #define PTHREAD_CANCEL_DEFERRED 0
-+ #define PTHREAD_CANCEL_ASYNCHRONOUS 1
-+
-+ #define PTHREAD_CANCELLED (void *)1 /* Exit status of a cancelled thread */
-+
-+
- #ifdef PTHREAD_KERNEL
-
- #include <signal.h> /* for sigset_t */
-***************
-*** 78,120 ****
- PS_STATE_MAX
- };
-
-- #define PF_WAIT_EVENT 0x01
-- #define PF_DONE_EVENT 0x02
--
- /* Put PANIC inside an expression that evaluates to non-void type, to
- make it easier to combine it in expressions. */
-! #define DO_PANIC() (PANIC (), 0)
-! #define PANICIF(x) ((x) ? DO_PANIC () : 0)
-
-! #define SET_PF_DONE_EVENT(x) \
-! ( !(x->flags & PF_DONE_EVENT) \
-! ? ( (x->flags & PF_WAIT_EVENT) \
-! ? (x->flags = PF_DONE_EVENT, OK) \
-! : DO_PANIC ()) \
- : NOTOK )
-
-! #define SET_PF_WAIT_EVENT(x) \
-! ( PANICIF (x->flags & (PF_WAIT_EVENT | PF_DONE_EVENT)), \
-! (x->flags = PF_WAIT_EVENT), 0)
-!
-! #define CLEAR_PF_DONE_EVENT(x) \
-! ( PANICIF (!(x->flags & PF_DONE_EVENT)), \
-! x->flags = 0 )
-
- struct pthread_select_data {
-! int nfds;
-! fd_set readfds;
-! fd_set writefds;
-! fd_set exceptfds;
- };
-
- union pthread_wait_data {
-! pthread_mutex_t * mutex;
-! pthread_cond_t * cond;
-! const sigset_t * sigwait; /* Waiting on a signal in sigwait */
- struct {
-! short fd; /* Used when thread waiting on fd */
-! short branch; /* line number, for debugging */
- } fd;
- struct pthread_select_data * select_data;
- };
---- 90,185 ----
- PS_STATE_MAX
- };
-
- /* Put PANIC inside an expression that evaluates to non-void type, to
- make it easier to combine it in expressions. */
-! #define DO_PANIC() (PANIC (), 0)
-! #define PANICIF(x) ((x) ? DO_PANIC () : 0)
-!
-! /* In the thread flag field, we use a series of bit flags. Flags can
-! * organized into "groups" of mutually exclusive flags. Other flags
-! * are unrelated and can be set and cleared with a single bit operation.
-! */
-
-! #define PF_WAIT_EVENT 0x01
-! #define PF_DONE_EVENT 0x02
-! #define PF_EVENT_GROUP 0x03 /* All event bits */
-!
-! #define PF_CANCEL_STATE 0x04 /* cancellability state */
-! #define PF_CANCEL_TYPE 0x08 /* cancellability type */
-! #define PF_THREAD_CANCELLED 0x10 /* thread has been cancelled */
-! #define PF_RUNNING_TO_CANCEL 0x20 /* Thread is running so it can cancel*/
-! #define PF_AT_CANCEL_POINT 0x40 /* Thread is at a cancel point */
-!
-! /* Flag operations */
-!
-! #define SET_PF_FLAG(x,f) ( (x)->flags |= (f) )
-! #define TEST_PF_FLAG(x,f) ( (x)->flags & (f) )
-! #define CLEAR_PF_FLAG(x,f) ( (x)->flags &= ~(f) )
-! #define CLEAR_PF_GROUP(x,g) ( (x)->flags &= ~(g) )
-! #define SET_PF_FLAG_IN_GROUP(x,g,f) ( CLEAR_PF_GROUP(x,g),SET_PF_FLAG(x,f))
-! #define TEST_PF_GROUP(x,g) ( (x)->flags & (g) )
-!
-! #define SET_PF_DONE_EVENT(x) \
-! ( !TEST_PF_FLAG(x,PF_DONE_EVENT) \
-! ? ( TEST_PF_FLAG(x,PF_WAIT_EVENT) \
-! ? (SET_PF_FLAG_IN_GROUP(x,PF_EVENT_GROUP,PF_DONE_EVENT), OK) \
-! : DO_PANIC ()) \
- : NOTOK )
-
-! #define SET_PF_WAIT_EVENT(x) \
-! ( PANICIF (TEST_PF_GROUP(x,PF_EVENT_GROUP) ), \
-! SET_PF_FLAG_IN_GROUP(x,PF_EVENT_GROUP,PF_WAIT_EVENT), 0)
-!
-! #define CLEAR_PF_DONE_EVENT(x) \
-! ( PANICIF (!TEST_PF_FLAG(x,PF_DONE_EVENT)), \
-! CLEAR_PF_GROUP(x,PF_EVENT_GROUP) )
-!
-! #define SET_PF_CANCELLED(x) ( SET_PF_FLAG(x,PF_THREAD_CANCELLED) )
-! #define TEST_PF_CANCELLED(x) ( TEST_PF_FLAG(x,PF_THREAD_CANCELLED) )
-!
-! #define SET_PF_RUNNING_TO_CANCEL(x) ( SET_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-! #define CLEAR_PF_RUNNING_TO_CANCEL(x)( CLEAR_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-! #define TEST_PF_RUNNING_TO_CANCEL(x)( TEST_PF_FLAG(x,PF_RUNNING_TO_CANCEL) )
-!
-! #define SET_PF_AT_CANCEL_POINT(x) ( SET_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-! #define CLEAR_PF_AT_CANCEL_POINT(x) ( CLEAR_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-! #define TEST_PF_AT_CANCEL_POINT(x) ( TEST_PF_FLAG(x,PF_AT_CANCEL_POINT) )
-!
-! #define SET_PF_CANCEL_STATE(x,f) \
-! ( (f) ? SET_PF_FLAG(x,PF_CANCEL_STATE) : CLEAR_PF_FLAG(x,PF_CANCEL_STATE) )
-! #define TEST_PF_CANCEL_STATE(x) \
-! ( (TEST_PF_FLAG(x,PF_CANCEL_STATE)) ? PTHREAD_CANCEL_ENABLE \
-! : PTHREAD_CANCEL_DISABLE )
-!
-! #define SET_PF_CANCEL_TYPE(x,f) \
-! ( (f) ? SET_PF_FLAG(x,PF_CANCEL_TYPE) : CLEAR_PF_FLAG(x,PF_CANCEL_TYPE) )
-! #define TEST_PF_CANCEL_TYPE(x) \
-! ( (TEST_PF_FLAG(x,PF_CANCEL_TYPE)) ? PTHREAD_CANCEL_ASYNCHRONOUS \
-! : PTHREAD_CANCEL_DEFERRED )
-!
-! /* See if a thread is in a state that it can be cancelled */
-! #define TEST_PTHREAD_IS_CANCELLABLE(x) \
-! ( (TEST_PF_CANCEL_STATE(x) == PTHREAD_CANCEL_ENABLE && TEST_PF_CANCELLED(x)) \
-! ? ((TEST_PF_CANCEL_TYPE(x) == PTHREAD_CANCEL_ASYNCHRONOUS) \
-! ? 1 \
-! : TEST_PF_AT_CANCEL_POINT(x)) \
-! : 0 )
-!
-
- struct pthread_select_data {
-! int nfds;
-! fd_set readfds;
-! fd_set writefds;
-! fd_set exceptfds;
- };
-
- union pthread_wait_data {
-! pthread_mutex_t * mutex;
-! pthread_cond_t * cond;
-! const sigset_t * sigwait; /* Waiting on a signal in sigwait */
- struct {
-! short fd; /* Used when thread waiting on fd */
-! short branch; /* line number, for debugging */
- } fd;
- struct pthread_select_data * select_data;
- };
-***************
-*** 122,143 ****
- #define PTT_USER_THREAD 0x0001
-
- struct pthread {
-! int thread_type;
- struct machdep_pthread machdep_data;
-! pthread_attr_t attr;
-
- /* Signal interface */
-! sigset_t sigmask;
-! sigset_t sigpending;
-! int sigcount; /* Number of signals pending */
-
- /* Timeout time */
-! struct timespec wakeup_time;
-
- /* Join queue for waiting threads */
- struct pthread_queue join_queue;
-
--
- /*
- * Thread implementations are just multiple queue type implemenations,
- * Below are the various link lists currently necessary
---- 187,207 ----
- #define PTT_USER_THREAD 0x0001
-
- struct pthread {
-! int thread_type;
- struct machdep_pthread machdep_data;
-! pthread_attr_t attr;
-
- /* Signal interface */
-! sigset_t sigmask;
-! sigset_t sigpending;
-! int sigcount; /* Number of signals pending */
-
- /* Timeout time */
-! struct timespec wakeup_time;
-
- /* Join queue for waiting threads */
- struct pthread_queue join_queue;
-
- /*
- * Thread implementations are just multiple queue type implemenations,
- * Below are the various link lists currently necessary
-***************
-*** 152,165 ****
- * ALL threads, in any state.
- * Must lock kernel lock before manipulating.
- */
-! struct pthread * pll;
-
- /*
- * Standard link list for running threads, mutexes, etc ...
- * It can't be on both a running link list and a wait queue.
- * Must lock kernel lock before manipulating.
- */
-! struct pthread * next;
- union pthread_wait_data data;
-
- /*
---- 216,229 ----
- * ALL threads, in any state.
- * Must lock kernel lock before manipulating.
- */
-! struct pthread * pll;
-
- /*
- * Standard link list for running threads, mutexes, etc ...
- * It can't be on both a running link list and a wait queue.
- * Must lock kernel lock before manipulating.
- */
-! struct pthread * next;
- union pthread_wait_data data;
-
- /*
-***************
-*** 167,197 ****
- * (Note: "priority" is a reserved word in Concurrent C, please
- * don't use it. --KR)
- */
-! struct pthread_queue * queue;
-! enum pthread_state state;
-! char flags;
-! char pthread_priority;
-
- /*
- * Sleep queue, this is different from the standard link list
- * because it is possible to be on both (pthread_cond_timedwait();
- * Must lock sleep mutex before manipulating
- */
-! struct pthread *sll; /* For sleeping threads */
-
- /*
- * Data that doesn't need to be locked
-! * Mostly it's because only the thread owning the data can manipulate it
- */
-! void * ret;
-! int error;
-! int * error_p;
-! const void ** specific_data;
-! int specific_data_count;
-
- /* Cleanup handlers Link List */
- struct pthread_cleanup *cleanup;
--
- };
-
- #else /* not PTHREAD_KERNEL */
---- 231,261 ----
- * (Note: "priority" is a reserved word in Concurrent C, please
- * don't use it. --KR)
- */
-! struct pthread_queue * queue;
-! enum pthread_state state;
-! enum pthread_state old_state; /* Used when cancelled */
-! char flags;
-! char pthread_priority;
-
- /*
- * Sleep queue, this is different from the standard link list
- * because it is possible to be on both (pthread_cond_timedwait();
- * Must lock sleep mutex before manipulating
- */
-! struct pthread *sll; /* For sleeping threads */
-
- /*
- * Data that doesn't need to be locked
-! * Mostly because only the thread owning the data can manipulate it
- */
-! void * ret;
-! int error;
-! int * error_p;
-! const void ** specific_data;
-! int specific_data_count;
-
- /* Cleanup handlers Link List */
- struct pthread_cleanup *cleanup;
- };
-
- #else /* not PTHREAD_KERNEL */
-***************
-*** 200,223 ****
-
- #endif
-
-! typedef struct pthread * pthread_t;
-
- /*
- * Globals
- */
- #ifdef PTHREAD_KERNEL
-
-! extern struct pthread * pthread_run;
-! extern struct pthread * pthread_initial;
-! extern struct pthread * pthread_link_list;
- extern struct pthread_queue pthread_dead_queue;
- extern struct pthread_queue pthread_alloc_queue;
-
-! extern pthread_attr_t pthread_attr_default;
-! extern volatile int fork_lock;
-! extern pthread_size_t pthread_pagesize;
-!
-! extern sigset_t * uthread_sigmask;
-
- #endif
-
---- 264,293 ----
-
- #endif
-
-! typedef struct pthread *pthread_t;
-
- /*
- * Globals
- */
- #ifdef PTHREAD_KERNEL
-
-! extern struct pthread * pthread_run;
-! extern struct pthread * pthread_initial;
-! extern struct pthread * pthread_link_list;
- extern struct pthread_queue pthread_dead_queue;
- extern struct pthread_queue pthread_alloc_queue;
-
-! extern pthread_attr_t pthread_attr_default;
-! extern volatile int fork_lock;
-! extern pthread_size_t pthread_pagesize;
-!
-! extern sigset_t * uthread_sigmask;
-!
-! /* Kernel global functions */
-! extern void pthread_sched_prevent(void);
-! extern void pthread_sched_resume(void);
-! extern int __pthread_is_valid( pthread_t );
-! extern void pthread_cancel_internal( int freelocks );
-
- #endif
-
-***************
-*** 229,271 ****
-
- #if defined(DCE_COMPAT)
-
-! typedef void * (*pthread_startroutine_t)(void *)
-! typedef void * pthread_addr_t
-
-! int pthread_create __P((pthread_t *, pthread_attr_t,
-! pthread_startroutine_t,
-! pthread_addr_t));
-! void pthread_exit __P((pthread_addr_t));
-! int pthread_join __P((pthread_t, pthread_addr_t *));
-
- #else
-
-! void pthread_init __P((void));
-! int pthread_create __P((pthread_t *,
-! const pthread_attr_t *,
-! void * (*start_routine)(void *),
-! void *));
-! void pthread_exit __P((void *));
-! pthread_t pthread_self __P((void));
-! int pthread_equal __P((pthread_t, pthread_t));
-! int pthread_join __P((pthread_t, void **));
-! int pthread_detach __P((pthread_t));
-! void pthread_yield __P((void));
-!
-! int pthread_setschedparam __P((pthread_t pthread, int policy,
-! struct sched_param * param));
-! int pthread_getschedparam __P((pthread_t pthread, int * policy,
-! struct sched_param * param));
-!
-! int pthread_kill __P((struct pthread *, int));
-! int pthread_signal __P((int, void (*)(int)));
-
- #endif
-
- #if defined(PTHREAD_KERNEL)
-
- /* Not valid, but I can't spell so this will be caught at compile time */
-! #define pthread_yeild(notvalid)
-
- #endif
-
---- 299,343 ----
-
- #if defined(DCE_COMPAT)
-
-! typedef void * (*pthread_startroutine_t)(void *);
-! typedef void * pthread_addr_t;
-
-! int pthread_create __P((pthread_t *, pthread_attr_t,
-! pthread_startroutine_t, pthread_addr_t));
-! void pthread_exit __P((pthread_addr_t));
-! int pthread_join __P((pthread_t, pthread_addr_t *));
-
- #else
-
-! void pthread_init __P((void));
-! int pthread_create __P((pthread_t *, const pthread_attr_t *,
-! void * (*start_routine)(void *), void *));
-! void pthread_exit __P((void *));
-! pthread_t pthread_self __P((void));
-! int pthread_equal __P((pthread_t, pthread_t));
-! int pthread_join __P((pthread_t, void **));
-! int pthread_detach __P((pthread_t));
-! void pthread_yield __P((void));
-!
-! int pthread_setschedparam __P((pthread_t pthread, int policy,
-! struct sched_param * param));
-! int pthread_getschedparam __P((pthread_t pthread, int * policy,
-! struct sched_param * param));
-!
-! int pthread_kill __P((struct pthread *, int));
-! int pthread_signal __P((int, void (*)(int)));
-!
-! int pthread_cancel __P(( pthread_t pthread ));
-! int pthread_setcancelstate __P(( int state, int *oldstate ));
-! int pthread_setcanceltype __P(( int type, int *oldtype ));
-! void pthread_testcancel __P(( void ));
-
- #endif
-
- #if defined(PTHREAD_KERNEL)
-
- /* Not valid, but I can't spell so this will be caught at compile time */
-! #define pthread_yeild(notvalid)
-
- #endif
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/include/signal.h,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 signal.h
-*** signal.h 1995/12/25 03:03:09 1.1.1.1
---- signal.h 1996/09/26 21:46:04
-***************
-*** 43,48 ****
---- 43,49 ----
- __BEGIN_DECLS
-
- int raise __P((int));
-+ __sighandler_t signal __P((int __sig, __sighandler_t));
-
- #ifndef _ANSI_SOURCE
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/include/pthread/kernel.h,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 kernel.h
-*** kernel.h 1994/12/13 07:09:01 1.1.1.1
---- kernel.h 1996/10/02 19:08:41
-***************
-*** 42,48 ****
- */
- #if defined(PTHREAD_KERNEL)
-
-! #define PANIC() abort()
-
- /* Time each rr thread gets */
- #define PTHREAD_RR_TIMEOUT 100000000
---- 42,54 ----
- */
- #if defined(PTHREAD_KERNEL)
-
-! #ifdef __GNUC__
-! #include <assert.h>
-! #define PANIC() panic_kernel( __FILE__, __LINE__, __ASSERT_FUNCTION )
-! #else
-! #define PANIC() panic_kernel( __FILE__, __LINE__, (const char *)0 )
-! #endif
-!
-
- /* Time each rr thread gets */
- #define PTHREAD_RR_TIMEOUT 100000000
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/machdep/syscall-i386-linux-1.0.S,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 syscall-i386-linux-1.0.S
-*** syscall-i386-linux-1.0.S 1995/09/27 04:38:55 1.1.1.1
---- syscall-i386-linux-1.0.S 1996/06/04 19:20:17
-***************
-*** 147,154 ****
-
- /* =========================================================================
- * exit 1 select 82
-! * fork 2 socketcall 102
-! * read 3
- * write 4
- * open 5
- * creat 8
---- 147,154 ----
-
- /* =========================================================================
- * exit 1 select 82
-! * fork 2 fstatfs 100
-! * read 3 socketcall 102
- * write 4
- * open 5
- * creat 8
-***************
-*** 160,166 ****
- * chown 16
- * lseek 19
- * rename 38
-! * dup 41
- * pipe 42
- * ioctl 54
- * fcntl 55
---- 160,166 ----
- * chown 16
- * lseek 19
- * rename 38
-! * dup 41
- * pipe 42
- * ioctl 54
- * fcntl 55
-***************
-*** 302,314 ****
- #endif
-
- /* ==========================================================================
-! * machdep_sys_fstat()
- */
- #ifdef __ELF__
- STATCALL2(lstat)
- #else
- SYSCALL2(lstat)
- #endif
-
- /* ==========================================================================
- * machdep_sys_ftruncate()
---- 302,320 ----
- #endif
-
- /* ==========================================================================
-! * machdep_sys_lstat()
- */
- #ifdef __ELF__
- STATCALL2(lstat)
- #else
- SYSCALL2(lstat)
- #endif
-+
-+ /* ==========================================================================
-+ * machdep_sys_fstatfs()
-+ */
-+ SYSCALL2(fstatfs)
-+
-
- /* ==========================================================================
- * machdep_sys_ftruncate()
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/machdep/linux-1.0/socket.h,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 socket.h
-*** socket.h 1995/12/26 02:28:03 1.1.1.1
---- socket.h 1996/09/27 18:12:45
-***************
-*** 26,32 ****
-
- #endif
-
-! /* #include <asm/socket.h> /* arch-dependent defines */
- #include <linux/sockios.h> /* the SIOCxxx I/O controls */
- #include <pthread/posix.h>
-
---- 26,32 ----
-
- #endif
-
-! /* #include <asm/socket.h> arch-dependent defines */
- #include <linux/sockios.h> /* the SIOCxxx I/O controls */
- #include <pthread/posix.h>
-
-***************
-*** 161,166 ****
---- 161,188 ----
- int connect __P((int, const struct sockaddr *, int));
- int listen __P((int, int));
- int socket __P((int, int, int));
-+
-+ int getsockopt __P ((int __s, int __level, int __optname,
-+ void *__optval, int *__optlen));
-+ int setsockopt __P ((int __s, int __level, int __optname,
-+ __const void *__optval, int optlen));
-+ int getsockname __P ((int __sockfd, struct sockaddr *__addr,
-+ int *__paddrlen));
-+ int getpeername __P ((int __sockfd, struct sockaddr *__peer,
-+ int *__paddrlen));
-+ ssize_t send __P ((int __sockfd, __const void *__buff, size_t __len, int __flags));
-+ ssize_t recv __P ((int __sockfd, void *__buff, size_t __len, int __flags));
-+ ssize_t sendto __P ((int __sockfd, __const void *__buff, size_t __len,
-+ int __flags, __const struct sockaddr *__to,
-+ int __tolen));
-+ ssize_t recvfrom __P ((int __sockfd, void *__buff, size_t __len,
-+ int __flags, struct sockaddr *__from,
-+ int *__fromlen));
-+ extern ssize_t sendmsg __P ((int __fd, __const struct msghdr *__message,
-+ int __flags));
-+ extern ssize_t recvmsg __P ((int __fd, struct msghdr *__message,
-+ int __flags));
-+ int shutdown __P ((int __sockfd, int __how));
-
- __END_DECLS
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/machdep/linux-1.0/timers.h,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 timers.h
-*** timers.h 1996/03/05 08:28:36 1.1.1.1
---- timers.h 1996/05/25 21:30:08
-***************
-*** 43,52 ****
---- 43,54 ----
- #include <sys/types.h>
- #include <time.h>
-
-+ #ifndef _LINUX_TIME_H
- struct timespec {
- time_t tv_sec;
- long tv_nsec;
- };
-+ #endif /* _LINUX_TIME_H */
-
- #define TIMEVAL_TO_TIMESPEC(tv, ts) { \
- (ts)->tv_sec = (tv)->tv_sec; \
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/net/getprotoent.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 getprotoent.c
-*** getprotoent.c 1996/02/09 05:39:41 1.1.1.1
---- getprotoent.c 1996/05/27 01:11:27
-***************
-*** 128,135 ****
- if (p != NULL)
- *p++ = '\0';
- }
-! if (p && *p);
-! break;
- }
- *alias = NULL;
- pthread_mutex_unlock(&proto_file_lock);
---- 128,135 ----
- if (p != NULL)
- *p++ = '\0';
- }
-! if (p && *p)
-! break;
- }
- *alias = NULL;
- pthread_mutex_unlock(&proto_file_lock);
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/net/proto_internal.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 proto_internal.c
-*** proto_internal.c 1996/02/09 05:39:49 1.1.1.1
---- proto_internal.c 1996/06/04 16:25:57
-***************
-*** 49,55 ****
- static int init_status;
-
- /* Performs global initialization. */
-! char *_proto_init()
- {
- char *buf;
-
---- 49,55 ----
- static int init_status;
-
- /* Performs global initialization. */
-! char *_proto_buf()
- {
- char *buf;
-
-***************
-*** 75,78 ****
- {
- init_status = pthread_key_create(&key, free);
- }
--
---- 75,77 ----
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/net/res_internal.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 res_internal.c
-*** res_internal.c 1996/02/09 05:39:53 1.1.1.1
---- res_internal.c 1996/09/25 23:31:11
-***************
-*** 144,149 ****
---- 144,150 ----
- break;
- cp += n;
- result->h_name = bp;
-+ bp += strlen(bp) + 1;
- iquery_done = 1;
- break;
- }
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/GNUmakefile.inc,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 GNUmakefile.inc
-*** GNUmakefile.inc 1995/08/30 22:27:04 1.1.1.1
---- GNUmakefile.inc 1996/10/02 19:04:29
-***************
-*** 8,14 ****
- syscall.S pthread_join.c pthread_detach.c pthread_once.c sleep.c \
- specific.c process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
-! dump_state.c pthread_kill.c stat.c readv.c writev.c condattr.c $(SRCS)
-
- ifeq ($(HAVE_SYSCALL_TEMPLATE),yes)
- SYSCALL_FILTER_RULE= for s in $(AVAILABLE_SYSCALLS) ; do \
---- 8,15 ----
- syscall.S pthread_join.c pthread_detach.c pthread_once.c sleep.c \
- specific.c process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
-! dump_state.c pthread_kill.c stat.c readv.c writev.c condattr.c \
-! pthread_cancel.c panic.c $(SRCS)
-
- ifeq ($(HAVE_SYSCALL_TEMPLATE),yes)
- SYSCALL_FILTER_RULE= for s in $(AVAILABLE_SYSCALLS) ; do \
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/Makefile.inc,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 Makefile.inc
-*** Makefile.inc 1995/08/22 22:09:07 1.1.1.1
---- Makefile.inc 1996/10/02 19:04:38
-***************
-*** 8,14 ****
- pthread_join.c pthread_detach.c pthread_once.c sleep.c specific.c \
- process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
-! dump_state.c pthread_kill.c condattr.c
-
- .if $(HAVE_SYSCALL_TEMPLATE) == yes
- OBJS+= syscalls.o
---- 8,14 ----
- pthread_join.c pthread_detach.c pthread_once.c sleep.c specific.c \
- process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
-! dump_state.c pthread_kill.c condattr.c pthread_cancel.c panic.c
-
- .if $(HAVE_SYSCALL_TEMPLATE) == yes
- OBJS+= syscalls.o
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/cond.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 cond.c
-*** cond.c 1996/03/05 08:29:12 1.1.1.1
---- cond.c 1996/10/03 18:19:04
-***************
-*** 188,197 ****
---- 188,204 ----
- pthread_queue_enq(&cond->c_queue, pthread_run);
- pthread_mutex_unlock(mutex);
-
-+ pthread_run->data.mutex = mutex;
-+
- SET_PF_WAIT_EVENT(pthread_run);
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-+
-+ pthread_run->data.mutex = NULL;
-+
- rval = pthread_mutex_lock(mutex);
- return(rval);
- break;
-***************
-*** 203,212 ****
---- 210,226 ----
- pthread_mutex_unlock(mutex);
- mutex->m_data.m_count = 1;
-
-+ pthread_run->data.mutex = mutex;
-+
- SET_PF_WAIT_EVENT(pthread_run);
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-+
-+ pthread_run->data.mutex = NULL;
-+
- rval = pthread_mutex_lock(mutex);
- mutex->m_data.m_count = count;
- return(rval);
-***************
-*** 258,265 ****
---- 272,285 ----
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
-+ pthread_run->data.mutex = mutex;
-+
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-+
-+ pthread_run->data.mutex = NULL;
-
- /* Remove ourselves from sleep queue. If we fail then we timedout */
- if (sleep_cancel(pthread_run) == NOTOK) {
-***************
-*** 285,292 ****
---- 305,318 ----
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
-+ pthread_run->data.mutex = mutex;
-+
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-+
-+ pthread_run->data.mutex = NULL;
-
- /* Remove ourselves from sleep queue. If we fail then we timedout */
- if (sleep_cancel(pthread_run) == NOTOK) {
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/fd.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 fd.c
-*** fd.c 1996/02/09 02:54:19 1.1.1.1
---- fd.c 1996/10/03 01:33:03
-***************
-*** 48,54 ****
---- 48,59 ----
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/uio.h>
-+ #include <sys/ioctl.h>
-+ #if __STDC__
- #include <stdarg.h>
-+ #else
-+ #include <varargs.h>
-+ #endif
- #include <fcntl.h>
- #include <errno.h>
- #include <pthread/posix.h>
-***************
-*** 62,67 ****
---- 67,74 ----
- static const int dtablecount = 4096/sizeof(struct fd_table_entry);
- int dtablesize;
-
-+ static int fd_get_pthread_fd_from_kernel_fd( int );
-+
- /* ==========================================================================
- * Allocate dtablecount entries at once and populate the fd_table.
- *
-***************
-*** 199,204 ****
---- 206,244 ----
- return(NOTOK);
- }
-
-+ /*----------------------------------------------------------------------
-+ * Function: fd_get_pthread_fd_from_kernel_fd
-+ * Purpose: get the fd_table index of a kernel fd
-+ * Args: fd = kernel fd to convert
-+ * Returns: fd_table index, -1 if not found
-+ * Notes:
-+ *----------------------------------------------------------------------*/
-+ static int
-+ fd_get_pthread_fd_from_kernel_fd( int kfd )
-+ {
-+ int j;
-+
-+ /* This is *SICK*, but unless there is a faster way to
-+ * turn a kernel fd into an fd_table index, this has to do.
-+ */
-+ for( j=0; j < dtablesize; j++ ) {
-+ if( fd_table[j] &&
-+ fd_table[j]->type != FD_NT &&
-+ fd_table[j]->type != FD_NIU &&
-+ fd_table[j]->fd.i == kfd ) {
-+ return j;
-+ }
-+ }
-+
-+ /* Not listed byfd, Check for kernel fd == pthread fd */
-+ if( fd_table[kfd] == NULL || fd_table[kfd]->type == FD_NT ) {
-+ /* Assume that the kernel fd is the same */
-+ return kfd;
-+ }
-+
-+ return NOTOK; /* Not found */
-+ }
-+
- /* ==========================================================================
- * fd_basic_basic_unlock()
- *
-***************
-*** 288,293 ****
---- 328,334 ----
- switch (fd_table[fd]->type) {
- case FD_NIU:
- /* If not in use return EBADF error */
-+ SET_ERRNO(EBADF);
- return(NOTOK);
- break;
- case FD_NT:
-***************
-*** 297,302 ****
---- 338,344 ----
- */
- fd_kern_init(fd);
- if (fd_table[fd]->type == FD_NIU) {
-+ SET_ERRNO(EBADF);
- return(NOTOK);
- }
- break;
-***************
-*** 409,414 ****
---- 451,545 ----
- return(OK);
- }
-
-+ /*----------------------------------------------------------------------
-+ * Function: fd_unlock_for_cancel
-+ * Purpose: Unlock all fd locks held prior to being cancelled
-+ * Args: void
-+ * Returns:
-+ * OK or NOTOK
-+ * Notes:
-+ * Assumes the kernel is locked on entry
-+ *----------------------------------------------------------------------*/
-+ int
-+ fd_unlock_for_cancel( void )
-+ {
-+ int i, fd;
-+ struct pthread_select_data *data;
-+ int rdlk, wrlk, lktype;
-+ int found;
-+
-+ /* What we do depends on the previous state of the thread */
-+ switch( pthread_run->old_state ) {
-+ case PS_RUNNING:
-+ case PS_JOIN:
-+ case PS_SLEEP_WAIT:
-+ case PS_WAIT_WAIT:
-+ case PS_SIGWAIT:
-+ case PS_FDLR_WAIT:
-+ case PS_FDLW_WAIT:
-+ case PS_DEAD:
-+ case PS_UNALLOCED:
-+ break; /* Nothing to do */
-+
-+ case PS_COND_WAIT:
-+ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP );
-+ /* Must reaquire the mutex according to the standard */
-+ if( pthread_run->data.mutex == NULL ) {
-+ PANIC();
-+ }
-+ pthread_mutex_lock( pthread_run->data.mutex );
-+ break;
-+
-+ case PS_FDR_WAIT:
-+ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
-+ /* Free the lock on the fd being used */
-+ fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd );
-+ if( fd == NOTOK ) {
-+ PANIC(); /* Can't find fd */
-+ }
-+ fd_unlock( fd, FD_READ );
-+ break;
-+
-+ case PS_FDW_WAIT: /* Waiting on i/o */
-+ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
-+ /* Free the lock on the fd being used */
-+ fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd );
-+ if( fd == NOTOK ) {
-+ PANIC(); /* Can't find fd */
-+ }
-+ fd_unlock( fd, FD_WRITE );
-+ break;
-+
-+ case PS_SELECT_WAIT:
-+ data = pthread_run->data.select_data;
-+
-+ CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
-+
-+ for( i = 0; i < data->nfds; i++) {
-+ rdlk =(FD_ISSET(i,&data->readfds)
-+ || FD_ISSET(i,&data->exceptfds));
-+ wrlk = FD_ISSET(i, &data->writefds);
-+ lktype = rdlk ? (wrlk ? FD_RDWR : FD_READ) : FD_WRITE;
-+
-+ if( ! (rdlk || wrlk) )
-+ continue; /* No locks, no unlock */
-+
-+ if( (fd = fd_get_pthread_fd_from_kernel_fd( i )) == NOTOK ) {
-+ PANIC(); /* Can't find fd */
-+ }
-+
-+ fd_unlock( fd, lktype );
-+ }
-+ break;
-+
-+ case PS_MUTEX_WAIT:
-+ PANIC(); /* Should never cancel a mutex wait */
-+
-+ default:
-+ PANIC(); /* Unknown thread status */
-+ }
-+ }
-+
- /* ==========================================================================
- * fd_lock()
- */
-***************
-*** 476,481 ****
---- 607,616 ----
- ret = fd_table[fd]->ops->read(fd_table[fd]->fd,
- fd_table[fd]->flags, buf, nbytes, timeout);
- fd_unlock(fd, FD_READ);
-+ if( ret < 0 ) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
- }
- return(ret);
- }
-***************
-*** 500,505 ****
---- 635,644 ----
- ret = fd_table[fd]->ops->readv(fd_table[fd]->fd,
- fd_table[fd]->flags, iov, iovcnt, timeout);
- fd_unlock(fd, FD_READ);
-+ if( ret < 0 ) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
- }
- return(ret);
- }
-***************
-*** 524,529 ****
---- 663,672 ----
- ret = fd_table[fd]->ops->write(fd_table[fd]->fd,
- fd_table[fd]->flags, buf, nbytes, timeout);
- fd_unlock(fd, FD_WRITE);
-+ if( ret < 0 ) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
- }
- return(ret);
- }
-***************
-*** 548,553 ****
---- 691,700 ----
- ret = fd_table[fd]->ops->writev(fd_table[fd]->fd,
- fd_table[fd]->flags, iov, iovcnt, timeout);
- fd_unlock(fd, FD_WRITE);
-+ if( ret < 0 ) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
- }
- return(ret);
- }
-***************
-*** 599,677 ****
- union fd_data realfd;
- int ret, flags;
-
- /* Need to lock the newfd by hand */
-! if (fd < dtablesize) {
-! pthread_mutex_lock(&fd_table_mutex);
-! if (fd_table[fd]) {
-! pthread_mutex_unlock(&fd_table_mutex);
-! mutex = &(fd_table[fd]->mutex);
-! pthread_mutex_lock(mutex);
-
-! /*
-! * XXX Gross hack ... because of fork(), any fd closed by the
-! * parent should not change the fd of the child, unless it owns it.
- */
-! switch(fd_table[fd]->type) {
-! case FD_NIU:
-! pthread_mutex_unlock(mutex);
-! ret = -EINVAL;
-! break;
-! case FD_NT:
-! /*
-! * If it's not tested then the only valid possibility is it's
-! * kernel fd.
-! */
-! ret = machdep_sys_close(fd);
-! fd_table[fd]->type = FD_NIU;
-! pthread_mutex_unlock(mutex);
-! break;
-! case FD_TEST_FULL_DUPLEX:
-! case FD_TEST_HALF_DUPLEX:
- realfd = fd_table[fd]->fd;
- flags = fd_table[fd]->flags;
- if ((entry = fd_free(fd)) == NULL) {
-! ret = fd_table[fd]->ops->close(realfd, flags);
- } else {
-! /* There can't be any others waiting for fd. */
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
-- mutex = &(fd_table[fd]->mutex);
- }
- pthread_mutex_unlock(mutex);
-- break;
-- default:
-- ret = fd_basic_lock(fd, FD_RDWR, mutex, NULL);
-- if (ret == OK) {
-- realfd = fd_table[fd]->fd;
-- flags = fd_table[fd]->flags;
-- pthread_mutex_unlock(mutex);
-- if ((entry = fd_free(fd)) == NULL) {
-- ret = fd_table[fd]->ops->close(realfd, flags);
-- } else {
-- fd_basic_basic_unlock(entry, FD_RDWR);
-- pthread_mutex_unlock(&entry->mutex);
-- /* Note: entry->mutex = mutex */
-- }
-- fd_unlock(fd, FD_RDWR);
-- } else {
-- pthread_mutex_unlock(mutex);
-- }
-- break;
- }
-! } else {
-! /* Don't bother creating a table entry */
-! pthread_mutex_unlock(&fd_table_mutex);
-! ret = machdep_sys_close(fd);
- }
-! return(ret);
- }
-! return(-EINVAL);
- }
-
- /* ==========================================================================
- * fd_basic_dup()
- *
- * Might need to do more than just what's below.
- */
- static inline void fd_basic_dup(int fd, int newfd)
- {
---- 746,836 ----
- union fd_data realfd;
- int ret, flags;
-
-+ if( fd < 0 || fd >= dtablesize ) {
-+ SET_ERRNO(EBADF);
-+ return -1;
-+ }
-+
- /* Need to lock the newfd by hand */
-! pthread_mutex_lock(&fd_table_mutex);
-! if (fd_table[fd]) {
-! pthread_mutex_unlock(&fd_table_mutex);
-! mutex = &(fd_table[fd]->mutex);
-! pthread_mutex_lock(mutex);
-
-! /*
-! * XXX Gross hack ... because of fork(), any fd closed by the
-! * parent should not change the fd of the child, unless it owns it.
-! */
-! switch(fd_table[fd]->type) {
-! case FD_NIU:
-! pthread_mutex_unlock(mutex);
-! ret = -EBADF;
-! break;
-! case FD_NT:
-! /*
-! * If it's not tested then the only valid possibility is it's
-! * kernel fd.
- */
-! ret = machdep_sys_close(fd);
-! fd_table[fd]->type = FD_NIU;
-! pthread_mutex_unlock(mutex);
-! break;
-! case FD_TEST_FULL_DUPLEX:
-! case FD_TEST_HALF_DUPLEX:
-! realfd = fd_table[fd]->fd;
-! flags = fd_table[fd]->flags;
-! if ((entry = fd_free(fd)) == NULL) {
-! ret = fd_table[fd]->ops->close(realfd, flags);
-! } else {
-! /* There can't be any others waiting for fd. */
-! pthread_mutex_unlock(&entry->mutex);
-! /* Note: entry->mutex = mutex */
-! mutex = &(fd_table[fd]->mutex);
-! }
-! pthread_mutex_unlock(mutex);
-! break;
-! default:
-! ret = fd_basic_lock(fd, FD_RDWR, mutex, NULL);
-! if (ret == OK) {
- realfd = fd_table[fd]->fd;
- flags = fd_table[fd]->flags;
-+ pthread_mutex_unlock(mutex);
- if ((entry = fd_free(fd)) == NULL) {
-! ret = fd_table[fd]->ops->close(realfd, flags);
- } else {
-! fd_basic_basic_unlock(entry, FD_RDWR);
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
- }
-+ fd_unlock(fd, FD_RDWR);
-+ } else {
- pthread_mutex_unlock(mutex);
- }
-! break;
- }
-! } else {
-! /* Don't bother creating a table entry */
-! pthread_mutex_unlock(&fd_table_mutex);
-! ret = machdep_sys_close(fd);
-! }
-!
-! if( ret < 0 ) {
-! SET_ERRNO(-ret);
-! ret = -1;
- }
-!
-! return ret;
- }
-
- /* ==========================================================================
- * fd_basic_dup()
- *
- * Might need to do more than just what's below.
-+ *
-+ * This is a MAJOR guess!! I don't know if the mutext unlock is valid
-+ * in the BIG picture. But it seems to be needed to avoid deadlocking
-+ * with ourselves when we try to close the duped file descriptor.
- */
- static inline void fd_basic_dup(int fd, int newfd)
- {
-***************
-*** 679,684 ****
---- 838,845 ----
- fd_table[fd]->next = fd_table[newfd];
- fd_table[newfd] = fd_table[fd];
- fd_table[fd]->count++;
-+ pthread_mutex_unlock(&fd_table[newfd]->next->mutex);
-+
- }
-
- /* ==========================================================================
-***************
-*** 896,904 ****
- * ala select()... --SNL
- */
- int
-! ioctl(int fd, unsigned long request, caddr_t arg)
- {
- int ret;
-
- if (fd < 0 || fd >= dtablesize)
- ret = NOTOK;
---- 1057,1071 ----
- * ala select()... --SNL
- */
- int
-! ioctl(int fd, int request, ...)
- {
- int ret;
-+ pthread_va_list ap;
-+ caddr_t arg;
-+
-+ va_start( ap, request ); /* Get the arg */
-+ arg = va_arg(ap,caddr_t);
-+ va_end( ap );
-
- if (fd < 0 || fd >= dtablesize)
- ret = NOTOK;
-***************
-*** 906,911 ****
---- 1073,1086 ----
- ret = machdep_sys_ioctl(fd, request, arg);
- else if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- ret = machdep_sys_ioctl(fd_table[fd]->fd.i, request, arg);
-+ if( ret == 0 && request == FIONBIO ) {
-+ /* Properly set NONBLOCK flag */
-+ int v = *(int *)arg;
-+ if( v )
-+ fd_table[fd]->flags |= __FD_NONBLOCK;
-+ else
-+ fd_table[fd]->flags &= ~__FD_NONBLOCK;
-+ }
- fd_unlock(fd, FD_RDWR);
- }
- return ret;
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/fd_kern.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 fd_kern.c
-*** fd_kern.c 1996/02/12 00:58:30 1.1.1.1
---- fd_kern.c 1996/10/03 01:54:15
-***************
-*** 128,134 ****
-
-
- if ((count = machdep_sys_select(dtablesize, &fd_set_read,
-! &fd_set_write, NULL, &__fd_kern_poll_timeout)) < OK) {
- if (count == -EINTR) {
- return;
- }
---- 128,134 ----
-
-
- if ((count = machdep_sys_select(dtablesize, &fd_set_read,
-! &fd_set_write, &fd_set_except, &__fd_kern_poll_timeout)) < OK) {
- if (count == -EINTR) {
- return;
- }
-***************
-*** 167,200 ****
-
- for (pthread = fd_wait_select.q_next; count && pthread; ) {
- int found_one = 0;
-
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- int count_dec = 0;
-
-! if ((FD_ISSET(i, &pthread->data.select_data->exceptfds) &&
-! ! FD_ISSET(i, &fd_set_except))) {
-! FD_CLR(i, &pthread->data.select_data->exceptfds);
-! } else {
-! count_dec++;
- }
-! if ((FD_ISSET(i, &pthread->data.select_data->writefds) &&
-! ! FD_ISSET(i, &fd_set_write))) {
-! FD_CLR(i, &pthread->data.select_data->writefds);
-! } else {
-! count_dec++;
- }
-! if ((FD_ISSET(i, &pthread->data.select_data->readfds) &&
-! ! FD_ISSET(i, &fd_set_read))) {
-! FD_CLR(i, &pthread->data.select_data->readfds);
-! } else {
-! count_dec++;
- }
- if (count_dec) {
- found_one++;
- count--;
- }
- }
- if (found_one) {
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_select, deq);
---- 167,223 ----
-
- for (pthread = fd_wait_select.q_next; count && pthread; ) {
- int found_one = 0;
-+ fd_set tmp_readfds, tmp_writefds, tmp_exceptfds;
-+
-+ memcpy(&tmp_readfds, &pthread->data.select_data->readfds,
-+ sizeof(fd_set));
-+ memcpy(&tmp_writefds, &pthread->data.select_data->writefds,
-+ sizeof(fd_set));
-+ memcpy(&tmp_exceptfds, &pthread->data.select_data->exceptfds,
-+ sizeof(fd_set));
-
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- int count_dec = 0;
-
-! if( (FD_ISSET(i, &tmp_exceptfds)) ) {
-! if( FD_ISSET(i, &fd_set_except) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_exceptfds);
-! }
- }
-!
-! if( (FD_ISSET(i, &tmp_writefds)) ) {
-! if( FD_ISSET(i, &fd_set_write) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_writefds);
-! }
- }
-!
-! if( (FD_ISSET(i, &tmp_readfds)) ) {
-! if( FD_ISSET(i, &fd_set_read) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_readfds);
-! }
- }
-+
- if (count_dec) {
- found_one++;
- count--;
- }
- }
-+
- if (found_one) {
-+ /* Update the threads saved select data fd sets */
-+ memcpy(&pthread->data.select_data->readfds, &tmp_readfds,
-+ sizeof(fd_set));
-+ memcpy(&pthread->data.select_data->writefds, &tmp_writefds,
-+ sizeof(fd_set));
-+ memcpy(&pthread->data.select_data->exceptfds, &tmp_exceptfds,
-+ sizeof(fd_set));
-+
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_select, deq);
-***************
-*** 266,272 ****
- */
-
- while ((count = machdep_sys_select(dtablesize, &fd_set_read,
-! &fd_set_write, NULL, &__fd_kern_wait_timeout)) < OK) {
- if (count == -EINTR) {
- return;
- }
---- 289,295 ----
- */
-
- while ((count = machdep_sys_select(dtablesize, &fd_set_read,
-! &fd_set_write, &fd_set_except, &__fd_kern_wait_timeout)) < OK) {
- if (count == -EINTR) {
- return;
- }
-***************
-*** 305,338 ****
-
- for (pthread = fd_wait_select.q_next; count && pthread; ) {
- int found_one = 0;
-
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- int count_dec = 0;
-
-! if ((FD_ISSET(i, &pthread->data.select_data->exceptfds) &&
-! ! FD_ISSET(i, &fd_set_except))) {
-! FD_CLR(i, &pthread->data.select_data->exceptfds);
-! } else {
-! count_dec++;
- }
-! if ((FD_ISSET(i, &pthread->data.select_data->writefds) &&
-! ! FD_ISSET(i, &fd_set_write))) {
-! FD_CLR(i, &pthread->data.select_data->writefds);
-! } else {
-! count_dec++;
- }
-! if ((FD_ISSET(i, &pthread->data.select_data->readfds) &&
-! ! FD_ISSET(i, &fd_set_read))) {
-! FD_CLR(i, &pthread->data.select_data->readfds);
-! } else {
-! count_dec++;
- }
- if (count_dec) {
- found_one++;
- count--;
- }
- }
- if (found_one) {
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_select, deq);
---- 328,383 ----
-
- for (pthread = fd_wait_select.q_next; count && pthread; ) {
- int found_one = 0;
-+ fd_set tmp_readfds, tmp_writefds, tmp_exceptfds;
-+
-+ memcpy(&tmp_readfds, &pthread->data.select_data->readfds,
-+ sizeof(fd_set));
-+ memcpy(&tmp_writefds, &pthread->data.select_data->writefds,
-+ sizeof(fd_set));
-+ memcpy(&tmp_exceptfds, &pthread->data.select_data->exceptfds,
-+ sizeof(fd_set));
-
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- int count_dec = 0;
-
-! if( (FD_ISSET(i, &tmp_exceptfds)) ) {
-! if( FD_ISSET(i, &fd_set_except) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_exceptfds);
-! }
- }
-!
-! if( (FD_ISSET(i, &tmp_writefds)) ) {
-! if( FD_ISSET(i, &fd_set_write) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_writefds);
-! }
- }
-!
-! if( (FD_ISSET(i, &tmp_readfds)) ) {
-! if( FD_ISSET(i, &fd_set_read) ) {
-! count_dec++; /* got a hit */
-! } else {
-! FD_CLR(i, &tmp_readfds);
-! }
- }
-+
- if (count_dec) {
- found_one++;
- count--;
- }
- }
- if (found_one) {
-+ /* Update the threads saved select data fd sets */
-+ memcpy(&pthread->data.select_data->readfds, &tmp_readfds,
-+ sizeof(fd_set));
-+ memcpy(&pthread->data.select_data->writefds, &tmp_writefds,
-+ sizeof(fd_set));
-+ memcpy(&pthread->data.select_data->exceptfds, &tmp_exceptfds,
-+ sizeof(fd_set));
-+
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_select, deq);
-***************
-*** 380,404 ****
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
-- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
-- SET_ERRNO(-ret);
-- ret = NOTOK;
- break;
- }
- }
---- 425,450 ----
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
-+ SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDR_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
-+ SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDR_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- break;
- }
- }
-***************
-*** 437,443 ****
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
-- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
---- 483,488 ----
-***************
-*** 447,454 ****
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
-- SET_ERRNO(-ret);
-- ret = NOTOK;
- break;
- }
- }
---- 492,497 ----
-***************
-*** 480,504 ****
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
-- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
-- SET_ERRNO(-ret);
-- ret = NOTOK;
- break;
- }
- }
---- 523,548 ----
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
-+ SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDW_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
-+ SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDW_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- break;
- }
- }
-***************
-*** 537,543 ****
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
-- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
---- 581,586 ----
-***************
-*** 547,554 ****
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
-- SET_ERRNO(-ret);
-- ret = NOTOK;
- break;
- }
- }
---- 590,595 ----
-***************
-*** 662,668 ****
- */
- int create(const char *path, mode_t mode)
- {
-! return creat (path, mode);
- }
-
- /* ==========================================================================
---- 703,709 ----
- */
- int create(const char *path, mode_t mode)
- {
-! return creat (path, mode);
- }
-
- /* ==========================================================================
-***************
-*** 672,678 ****
-
- int creat(const char *path, mode_t mode)
- {
-! return open (path, O_CREAT | O_TRUNC | O_WRONLY, mode);
- }
-
- /* ==========================================================================
---- 713,719 ----
-
- int creat(const char *path, mode_t mode)
- {
-! return open (path, O_CREAT | O_TRUNC | O_WRONLY, mode);
- }
-
- /* ==========================================================================
-***************
-*** 1079,1090 ****
- int bind(int fd, const struct sockaddr *name, int namelen)
- {
- /* Not much to do in bind */
-- semaphore *plock;
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_bind(fd_table[fd]->fd.i, name, namelen)) < OK) {
- SET_ERRNO(-ret);
- }
- fd_unlock(fd, FD_RDWR);
- }
---- 1120,1131 ----
- int bind(int fd, const struct sockaddr *name, int namelen)
- {
- /* Not much to do in bind */
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_bind(fd_table[fd]->fd.i, name, namelen)) < OK) {
- SET_ERRNO(-ret);
-+ ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
-***************
-*** 1100,1113 ****
- */
- int connect(int fd, const struct sockaddr *name, int namelen)
- {
-! struct sockaddr tmpname;
-! int ret, tmpnamelen;
-
-! if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_connect(fd_table[fd]->fd.i, name, namelen)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
-! ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) ||
-! (ret == -EALREADY) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
---- 1141,1154 ----
- */
- int connect(int fd, const struct sockaddr *name, int namelen)
- {
-! struct sockaddr tmpname;
-! int ret, tmpnamelen;
-
-! if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_connect(fd_table[fd]->fd.i, name, namelen)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
-! ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) ||
-! (ret == -EALREADY) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
-***************
-*** 1121,1131 ****
- tmpnamelen = sizeof(tmpname);
- /* OK now lets see if it really worked */
- if (((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
-! &tmpname, &tmpnamelen)) < OK) && (ret == -ENOTCONN)) {
-
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
-! SO_ERROR, &pthread_run->error, &tmpnamelen);
- }
- } else {
- SET_ERRNO(-ret);
---- 1162,1180 ----
- tmpnamelen = sizeof(tmpname);
- /* OK now lets see if it really worked */
- if (((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
-! &tmpname, &tmpnamelen)) < OK)
-! && (ret == -ENOTCONN)) {
-
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
-! SO_ERROR, &ret, &tmpnamelen);
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! } else {
-! if( ret < 0 ) {
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! }
- }
- } else {
- SET_ERRNO(-ret);
-***************
-*** 1133,1140 ****
- }
- }
- fd_unlock(fd, FD_RDWR);
-! }
-! return(ret);
- }
-
- #endif
---- 1182,1189 ----
- }
- }
- fd_unlock(fd, FD_RDWR);
-! }
-! return(ret);
- }
-
- #endif
-***************
-*** 1164,1170 ****
- } else {
- fd_unlock(fd, FD_RDWR);
- SET_ERRNO(-fd_kern);
-! return(fd_kern);
- }
- }
- fd_unlock(fd, FD_RDWR);
---- 1213,1219 ----
- } else {
- fd_unlock(fd, FD_RDWR);
- SET_ERRNO(-fd_kern);
-! return(NOTOK);
- }
- }
- fd_unlock(fd, FD_RDWR);
-***************
-*** 1198,1205 ****
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
-! ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog);
-! if ((ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
---- 1247,1253 ----
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
-! if ((ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
-***************
-*** 1246,1252 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1294,1300 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1311,1317 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1359,1365 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1405,1411 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1453,1459 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1471,1477 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1519,1525 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1536,1542 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1584,1590 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1603,1609 ****
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
---- 1651,1657 ----
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
-! ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-***************
-*** 1734,1744 ****
- */
- int getsockopt(int fd, int level, int optname, void * optval, int * optlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_getsockopt(fd_table[fd]->fd.i, level,
-! optname, optval, optlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
---- 1782,1792 ----
- */
- int getsockopt(int fd, int level, int optname, void * optval, int * optlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_getsockopt(fd_table[fd]->fd.i, level,
-! optname, optval, optlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
-***************
-*** 1756,1772 ****
- */
- int getsockname(int fd, struct sockaddr * name, int * naddrlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
-! if ((ret = machdep_sys_getsockname(fd_table[fd]->fd.i,
-! name, naddrlen)) < OK) {
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! }
-! fd_unlock(fd, FD_RDWR);
-! }
-! return ret;
- }
-
- #endif
---- 1804,1820 ----
- */
- int getsockname(int fd, struct sockaddr * name, int * naddrlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
-! if ((ret = machdep_sys_getsockname(fd_table[fd]->fd.i,
-! name, naddrlen)) < OK) {
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! }
-! fd_unlock(fd, FD_RDWR);
-! }
-! return ret;
- }
-
- #endif
-***************
-*** 1778,1793 ****
- */
- int getpeername(int fd, struct sockaddr * peer, int * paddrlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
-! if ((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
-! peer, paddrlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
-! }
-! fd_unlock(fd, FD_READ);
-! }
- return ret;
- }
-
---- 1826,1841 ----
- */
- int getpeername(int fd, struct sockaddr * peer, int * paddrlen)
- {
-! int ret;
-
-! if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
-! if ((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
-! peer, paddrlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
-! }
-! fd_unlock(fd, FD_READ);
-! }
- return ret;
- }
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 pthread.c
-*** pthread.c 1995/12/13 05:53:01 1.1.1.1
---- pthread.c 1996/10/01 21:42:01
-***************
-*** 129,134 ****
---- 129,160 ----
-
- }
-
-+ /*----------------------------------------------------------------------
-+ * Function: __pthread_is_valid
-+ * Purpose: Scan the list of threads to see if a specified thread exists
-+ * Args:
-+ * pthread = The thread to scan for
-+ * Returns:
-+ * int = 1 if found, 0 if not
-+ * Notes:
-+ * The kernel is assumed to be locked
-+ *----------------------------------------------------------------------*/
-+ int
-+ __pthread_is_valid( pthread_t pthread )
-+ {
-+ int rtn = 0; /* Assume not found */
-+ pthread_t t;
-+
-+ for( t = pthread_link_list; t; t = t->pll ) {
-+ if( t == pthread ) {
-+ rtn = 1; /* Found it */
-+ break;
-+ }
-+ }
-+
-+ return rtn;
-+ }
-+
- /* ==========================================================================
- * __pthread_free()
- */
-***************
-*** 242,247 ****
---- 268,277 ----
- new_thread->next = NULL;
- new_thread->flags = 0;
-
-+ /* PTHREADS spec says we start with cancellability on and deferred */
-+ SET_PF_CANCEL_STATE(new_thread, PTHREAD_CANCEL_ENABLE);
-+ SET_PF_CANCEL_TYPE(new_thread, PTHREAD_CANCEL_DEFERRED);
-+
- new_thread->error_p = NULL;
- new_thread->sll = NULL;
-
-***************
-*** 261,269 ****
- }
- return(retval);
- }
--
-- /* ==========================================================================
-- * pthread_cancel()
-- *
-- * This routine will also require a sig_prevent/sig_check_and_resume()
-- */
---- 291,293 ----
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread_init.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 pthread_init.c
-*** pthread_init.c 1996/03/13 04:33:10 1.1.1.1
---- pthread_init.c 1996/10/01 21:43:59
-***************
-*** 92,99 ****
- pthread_initial->next = NULL;
- pthread_initial->flags = 0;
- pthread_initial->pll = NULL;
-- pthread_initial->flags = 0;
- pthread_initial->sll = NULL;
-
- /* Ugly errno hack */
- pthread_initial->error_p = &errno;
---- 92,103 ----
- pthread_initial->next = NULL;
- pthread_initial->flags = 0;
- pthread_initial->pll = NULL;
- pthread_initial->sll = NULL;
-+
-+ /* PTHREADS spec says we start with cancellability on and deferred */
-+ SET_PF_CANCEL_STATE(pthread_initial, PTHREAD_CANCEL_ENABLE);
-+ SET_PF_CANCEL_TYPE(pthread_initial, PTHREAD_CANCEL_DEFERRED);
-+
-
- /* Ugly errno hack */
- pthread_initial->error_p = &errno;
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread_join.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 pthread_join.c
-*** pthread_join.c 1995/12/13 05:53:07 1.1.1.1
---- pthread_join.c 1996/10/02 16:54:36
-***************
-*** 42,47 ****
---- 42,49 ----
- #include <pthread.h>
- #include <errno.h>
-
-+ static int testDeadlock( struct pthread_queue *queue, pthread_t target );
-+
- /* ==========================================================================
- * pthread_join()
- */
-***************
-*** 51,56 ****
---- 53,64 ----
-
- pthread_sched_prevent();
-
-+ /* Ensure they gave us a legal pthread pointer */
-+ if( ! __pthread_is_valid( pthread ) ) {
-+ pthread_sched_resume();
-+ return(EINVAL);
-+ }
-+
- /* Check that thread isn't detached already */
- if (pthread->attr.flags & PTHREAD_DETACHED) {
- pthread_sched_resume();
-***************
-*** 62,81 ****
- * Note: This must happen after checking detached state.
- */
- if (pthread_queue_remove(&pthread_dead_queue, pthread) != OK) {
-! pthread_queue_enq(&(pthread->join_queue), pthread_run);
-! pthread_resched_resume(PS_JOIN);
-! pthread_sched_prevent();
-!
-! if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
-! pthread_queue_enq(&pthread_alloc_queue, pthread);
-! pthread->attr.flags |= PTHREAD_DETACHED;
-! pthread->state = PS_UNALLOCED;
-! if (thread_return) {
-! *thread_return = pthread->ret;
-! }
-! ret = OK;
- } else {
-! ret = ESRCH;
- }
- } else {
- /* Just get the return value and detach the thread */
---- 70,98 ----
- * Note: This must happen after checking detached state.
- */
- if (pthread_queue_remove(&pthread_dead_queue, pthread) != OK) {
-!
-! /* Before we pend on the join, ensure there is no dead lock */
-!
-! if( testDeadlock( &pthread_run->join_queue, pthread ) == NOTOK ) {
-! ret = EDEADLK;
- } else {
-! pthread_queue_enq(&(pthread->join_queue), pthread_run);
-! SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
-! pthread_resched_resume(PS_JOIN);
-! CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-! pthread_sched_prevent();
-!
-! if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
-! pthread_queue_enq(&pthread_alloc_queue, pthread);
-! pthread->attr.flags |= PTHREAD_DETACHED;
-! pthread->state = PS_UNALLOCED;
-! if (thread_return) {
-! *thread_return = pthread->ret;
-! }
-! ret = OK;
-! } else {
-! ret = ESRCH;
-! }
- }
- } else {
- /* Just get the return value and detach the thread */
-***************
-*** 89,92 ****
---- 106,139 ----
- }
- pthread_sched_resume();
- return(ret);
-+ }
-+
-+ /*----------------------------------------------------------------------
-+ * Function: testDeadlock
-+ * Purpose: recursive queue walk to check for deadlocks
-+ * Args:
-+ * queue = the queue to walk
-+ * pthread = target to scan for
-+ * Returns:
-+ * OK = no deadlock, NOTOK = deadlock
-+ * Notes:
-+ *----------------------------------------------------------------------*/
-+ static int
-+ testDeadlock( struct pthread_queue *queue, pthread_t target )
-+ {
-+ pthread_t t;
-+
-+ if( queue == NULL )
-+ return OK; /* Empty queue, obviously ok */
-+
-+ for( t = queue->q_next; t; t = t->next ) {
-+ if( t == target )
-+ return NOTOK; /* bang, your dead */
-+
-+ if( testDeadlock( &t->join_queue, target ) == NOTOK ) {
-+ return NOTOK;
-+ }
-+ }
-+
-+ return OK; /* No deadlock */
- }
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/select.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 select.c
-*** select.c 1996/03/05 08:29:14 1.1.1.1
---- select.c 1996/10/02 16:56:27
-***************
-*** 56,220 ****
- int select(int numfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
- {
-! fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */
-! fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p;
-! fd_set read_locks, write_locks, rdwr_locks;
-! struct timespec timeout_time, current_time;
-! struct timeval zero_timeout = { 0, 0 };
-! int i, j, ret = 0, got_all_locks = 1;
-! struct pthread_select_data data;
-!
-! if (numfds > dtablesize) {
-! numfds = dtablesize;
-! }
-!
-! data.nfds = 0;
-! FD_ZERO(&data.readfds);
-! FD_ZERO(&data.writefds);
-! FD_ZERO(&data.exceptfds);
-
-! /* Do this first */
-! if (timeout) {
- machdep_gettimeofday(&current_time);
-! timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
-! if ((timeout_time.tv_nsec = current_time.tv_nsec +
-! (timeout->tv_usec * 1000)) > 1000000000) {
-! timeout_time.tv_nsec -= 1000000000;
-! timeout_time.tv_sec++;
-! }
-! }
-!
-! FD_ZERO(&read_locks);
-! FD_ZERO(&write_locks);
-! FD_ZERO(&rdwr_locks);
-! FD_ZERO(&real_readfds);
-! FD_ZERO(&real_writefds);
-! FD_ZERO(&real_exceptfds);
-!
-! /* lock readfds */
-! if (readfds || writefds || exceptfds) {
-! for (i = 0; i < numfds; i++) {
-! if ((readfds && (FD_ISSET(i, readfds))) ||
-! (exceptfds && FD_ISSET(i, exceptfds))) {
-! if (writefds && FD_ISSET(i ,writefds)) {
-! if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &rdwr_locks);
-! FD_SET(fd_table[i]->fd.i,&real_writefds);
-! } else {
-! if ((ret = fd_lock(i, FD_READ, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &read_locks);
-! }
-! if (readfds && FD_ISSET(i,readfds)) {
-! FD_SET(fd_table[i]->fd.i, &real_readfds);
-! }
-! if (exceptfds && FD_ISSET(i,exceptfds)) {
-! FD_SET(fd_table[i]->fd.i, &real_exceptfds);
-! }
-! if (fd_table[i]->fd.i >= data.nfds) {
-! data.nfds = fd_table[i]->fd.i + 1;
-! }
-! } else {
-! if (writefds && FD_ISSET(i, writefds)) {
-! if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &write_locks);
-! FD_SET(fd_table[i]->fd.i,&real_writefds);
-! }
-! if (fd_table[i]->fd.i >= data.nfds) {
-! data.nfds = fd_table[i]->fd.i + 1;
-! }
-! }
-! }
-! }
-!
-! if (got_all_locks) {
-!
-! memcpy(&data.readfds,&real_readfds,sizeof(fd_set));
-! memcpy(&data.writefds,&real_writefds,sizeof(fd_set));
-! memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set));
-!
-! real_readfds_p = (readfds == NULL) ? NULL : &real_readfds;
-! real_writefds_p = (writefds == NULL) ? NULL : &real_writefds;
-! real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds;
-!
-! if ((ret = machdep_sys_select(data.nfds, real_readfds_p,
-! real_writefds_p, real_exceptfds_p, &zero_timeout)) == OK) {
-!
-! pthread_sched_prevent();
-!
-! real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds;
-! real_writefds_p = (writefds == NULL) ? NULL : &data.writefds;
-! real_readfds_p = (readfds == NULL) ? NULL : &data.readfds;
-!
-! pthread_queue_enq(&fd_wait_select, pthread_run);
-! pthread_run->data.select_data = &data;
-! SET_PF_WAIT_EVENT(pthread_run);
-!
-! if (timeout) {
-! machdep_gettimeofday(&current_time);
-! sleep_schedule(&current_time, &timeout_time);
-!
-! pthread_resched_resume(PS_SELECT_WAIT);
-!
-! /* We're awake */
-! CLEAR_PF_DONE_EVENT(pthread_run);
-! if (sleep_cancel(pthread_run) == NOTOK) {
-! ret = OK;
-! } else {
-! ret = data.nfds;
-! }
-! } else {
-! pthread_resched_resume(PS_SELECT_WAIT);
-! CLEAR_PF_DONE_EVENT(pthread_run);
-! ret = data.nfds; /* XXX ??? snl */
-! }
-! } else if (ret < 0) {
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! }
-! }
-!
-! /* clean up the locks */
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ);
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR);
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE);
-!
-! if (ret > 0) {
-! if (readfds != NULL) {
-! for (i = 0; i < numfds; i++) {
-! if (! (FD_ISSET(i,readfds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_readfds_p)))
-! FD_CLR(i,readfds);
-! }
-! }
-! if (writefds != NULL) {
-! for (i = 0; i < numfds; i++)
-! if (! (FD_ISSET(i,writefds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_writefds_p)))
-! FD_CLR(i,writefds);
-! }
-! if (exceptfds != NULL) {
-! for (i = 0; i < numfds; i++)
-! if (! (FD_ISSET(i,exceptfds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p)))
-! FD_CLR(i,exceptfds);
-! }
-! } else {
-! if (exceptfds != NULL) FD_ZERO(exceptfds);
-! if (writefds != NULL) FD_ZERO(writefds);
-! if (readfds != NULL) FD_ZERO(readfds);
- }
-
-! return(ret);
- }
---- 56,223 ----
- int select(int numfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
- {
-! fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */
-! fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p;
-! fd_set read_locks, write_locks, rdwr_locks;
-! struct timespec timeout_time, current_time;
-! struct timeval zero_timeout = { 0, 0 };
-! int i, j, ret = 0, got_all_locks = 1;
-! struct pthread_select_data data;
-!
-! if (numfds > dtablesize) {
-! numfds = dtablesize;
-! }
-!
-! data.nfds = 0;
-! FD_ZERO(&data.readfds);
-! FD_ZERO(&data.writefds);
-! FD_ZERO(&data.exceptfds);
-!
-! /* Do this first */
-! if (timeout) {
-! machdep_gettimeofday(&current_time);
-! timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
-! if ((timeout_time.tv_nsec = current_time.tv_nsec +
-! (timeout->tv_usec * 1000)) > 1000000000) {
-! timeout_time.tv_nsec -= 1000000000;
-! timeout_time.tv_sec++;
-! }
-! }
-!
-! FD_ZERO(&read_locks);
-! FD_ZERO(&write_locks);
-! FD_ZERO(&rdwr_locks);
-! FD_ZERO(&real_readfds);
-! FD_ZERO(&real_writefds);
-! FD_ZERO(&real_exceptfds);
-!
-! /* lock readfds */
-! if (readfds || writefds || exceptfds) {
-! for (i = 0; i < numfds; i++) {
-! if ((readfds && (FD_ISSET(i, readfds))) ||
-! (exceptfds && FD_ISSET(i, exceptfds))) {
-! if (writefds && FD_ISSET(i ,writefds)) {
-! if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &rdwr_locks);
-! FD_SET(fd_table[i]->fd.i,&real_writefds);
-! } else {
-! if ((ret = fd_lock(i, FD_READ, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &read_locks);
-! }
-! if (readfds && FD_ISSET(i,readfds)) {
-! FD_SET(fd_table[i]->fd.i, &real_readfds);
-! }
-! if (exceptfds && FD_ISSET(i,exceptfds)) {
-! FD_SET(fd_table[i]->fd.i, &real_exceptfds);
-! }
-! if (fd_table[i]->fd.i >= data.nfds) {
-! data.nfds = fd_table[i]->fd.i + 1;
-! }
-! } else {
-! if (writefds && FD_ISSET(i, writefds)) {
-! if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) {
-! got_all_locks = 0;
-! break;
-! }
-! FD_SET(i, &write_locks);
-! FD_SET(fd_table[i]->fd.i,&real_writefds);
-! if (fd_table[i]->fd.i >= data.nfds) {
-! data.nfds = fd_table[i]->fd.i + 1;
-! }
-! }
-! }
-! }
-! }
-!
-! if (got_all_locks) {
-! memcpy(&data.readfds,&real_readfds,sizeof(fd_set));
-! memcpy(&data.writefds,&real_writefds,sizeof(fd_set));
-! memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set));
-!
-! real_readfds_p = (readfds == NULL) ? NULL : &real_readfds;
-! real_writefds_p = (writefds == NULL) ? NULL : &real_writefds;
-! real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds;
-!
-! if ((ret = machdep_sys_select(data.nfds, real_readfds_p,
-! real_writefds_p, real_exceptfds_p,
-! &zero_timeout)) == OK) {
-! pthread_sched_prevent();
-!
-! real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds;
-! real_writefds_p = (writefds == NULL) ? NULL : &data.writefds;
-! real_readfds_p = (readfds == NULL) ? NULL : &data.readfds;
-!
-! pthread_queue_enq(&fd_wait_select, pthread_run);
-! pthread_run->data.select_data = &data;
-! SET_PF_WAIT_EVENT(pthread_run);
-
-! if (timeout) {
- machdep_gettimeofday(&current_time);
-! sleep_schedule(&current_time, &timeout_time);
-!
-! SET_PF_AT_CANCEL_POINT(pthread_run);
-! pthread_resched_resume(PS_SELECT_WAIT);
-! CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-!
-! /* We're awake */
-! CLEAR_PF_DONE_EVENT(pthread_run);
-! if (sleep_cancel(pthread_run) == NOTOK) {
-! ret = OK;
-! } else {
-! ret = data.nfds;
-! }
-! } else {
-! SET_PF_AT_CANCEL_POINT(pthread_run);
-! pthread_resched_resume(PS_SELECT_WAIT);
-! CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-! CLEAR_PF_DONE_EVENT(pthread_run);
-! ret = data.nfds; /* XXX ??? snl */
-! }
-! } else if (ret < 0) {
-! SET_ERRNO(-ret);
-! ret = NOTOK;
-! }
-! }
-!
-! /* clean up the locks */
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ);
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR);
-! for (i = 0; i < numfds; i++)
-! if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE);
-!
-! if (ret > 0) {
-! if (readfds != NULL) {
-! for (i = 0; i < numfds; i++) {
-! if (! (FD_ISSET(i,readfds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_readfds_p)))
-! FD_CLR(i,readfds);
-! }
-! }
-! if (writefds != NULL) {
-! for (i = 0; i < numfds; i++)
-! if (! (FD_ISSET(i,writefds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_writefds_p)))
-! FD_CLR(i,writefds);
-! }
-! if (exceptfds != NULL) {
-! for (i = 0; i < numfds; i++)
-! if (! (FD_ISSET(i,exceptfds) &&
-! FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p)))
-! FD_CLR(i,exceptfds);
- }
-+ } else {
-+ if (exceptfds != NULL) FD_ZERO(exceptfds);
-+ if (writefds != NULL) FD_ZERO(writefds);
-+ if (readfds != NULL) FD_ZERO(readfds);
-+ }
-
-! return(ret);
- }
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/sig.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 sig.c
-*** sig.c 1996/03/13 04:33:13 1.1.1.1
---- sig.c 1996/10/03 01:07:54
-***************
-*** 301,307 ****
---- 301,310 ----
- pthread_run->data.sigwait = set;
- pthread_run->ret = sig;
-
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_SIGWAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-+
- return(OK);
- }
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/signal.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 signal.c
-*** signal.c 1996/03/13 04:33:17 1.1.1.1
---- signal.c 1996/10/03 17:30:16
-***************
-*** 72,77 ****
---- 72,78 ----
-
- static void sig_handler(int signal);
- static void set_thread_timer();
-+ static void __cleanup_after_resume( void );
- void sig_prevent(void);
- void sig_resume(void);
-
-***************
-*** 482,502 ****
- }
- }
-
-! /* Only bother if we are truly unlocking the kernel */
-! while (!(--pthread_kernel_lock)) {
-! if (sig_to_process) {
-! /* if (SIG_ANY(sig_to_process)) { */
-! pthread_kernel_lock++;
-! sig_handler(0);
-! continue;
-! }
-! if (pthread_run && pthread_run->sigcount) {
-! pthread_kernel_lock++;
-! pthread_sig_process();
-! continue;
-! }
-! break;
-! }
- }
-
- /* ==========================================================================
---- 483,489 ----
- }
- }
-
-! __cleanup_after_resume();
- }
-
- /* ==========================================================================
-***************
-*** 508,530 ****
- void pthread_resched_resume(enum pthread_state state)
- {
- pthread_run->state = state;
-- sig_handler(SIGVTALRM);
-
-! /* Only bother if we are truely unlocking the kernel */
-! while (!(--pthread_kernel_lock)) {
-! if (sig_to_process) {
-! /* if (SIG_ANY(sig_to_process)) { */
-! pthread_kernel_lock++;
-! sig_handler(0);
-! continue;
-! }
-! if (pthread_run && pthread_run->sigcount) {
-! pthread_kernel_lock++;
-! pthread_sig_process();
-! continue;
-! }
-! break;
- }
- }
-
- /* ==========================================================================
---- 495,523 ----
- void pthread_resched_resume(enum pthread_state state)
- {
- pthread_run->state = state;
-
-! /* Since we are about to block this thread, lets see if we are
-! * at a cancel point and if we've been cancelled.
-! * Avoid cancelling dead or unalloced threads.
-! */
-! if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) &&
-! TEST_PTHREAD_IS_CANCELLABLE(pthread_run) &&
-! state != PS_DEAD && state != PS_UNALLOCED ) {
-!
-! /* Set this flag to avoid recursively calling pthread_exit */
-! /* We have to set this flag here because we will unlock the
-! * kernel prior to calling pthread_cancel_internal.
-! */
-! SET_PF_RUNNING_TO_CANCEL(pthread_run);
-!
-! pthread_run->old_state = state; /* unlock needs this data */
-! pthread_sched_resume(); /* Unlock kernel before cancel */
-! pthread_cancel_internal( 1 ); /* free locks and exit */
- }
-+
-+ sig_handler(SIGVTALRM);
-+
-+ __cleanup_after_resume();
- }
-
- /* ==========================================================================
-***************
-*** 532,537 ****
---- 525,543 ----
- */
- void pthread_sched_resume()
- {
-+ __cleanup_after_resume();
-+ }
-+
-+ /*----------------------------------------------------------------------
-+ * Function: __cleanup_after_resume
-+ * Purpose: cleanup kernel locks after a resume
-+ * Args: void
-+ * Returns: void
-+ * Notes:
-+ *----------------------------------------------------------------------*/
-+ static void
-+ __cleanup_after_resume( void )
-+ {
- /* Only bother if we are truely unlocking the kernel */
- while (!(--pthread_kernel_lock)) {
- /* if (SIG_ANY(sig_to_process)) { */
-***************
-*** 546,551 ****
---- 552,568 ----
- continue;
- }
- break;
-+ }
-+
-+ if( pthread_run == NULL )
-+ return; /* Must be during init processing */
-+
-+ /* Test for cancel that should be handled now */
-+
-+ if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) &&
-+ TEST_PTHREAD_IS_CANCELLABLE(pthread_run) ) {
-+ /* Kernel is already unlocked */
-+ pthread_cancel_internal( 1 ); /* free locks and exit */
- }
- }
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/sleep.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 sleep.c
-*** sleep.c 1996/03/11 08:33:32 1.1.1.1
---- sleep.c 1996/10/03 01:14:58
-***************
-*** 249,255 ****
---- 249,257 ----
-
- /* Reschedule thread */
- SET_PF_WAIT_EVENT(pthread_run);
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_SLEEP_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-
- /* Return actual time slept */
-***************
-*** 332,338 ****
- current_time.tv_sec++;
- }
- machdep_start_timer(&(current_time),
-! &(pthread_sleep->wakeup_time));
- }
- } else {
- for (pthread_last = pthread_sleep; pthread_last;
---- 334,340 ----
- current_time.tv_sec++;
- }
- machdep_start_timer(&(current_time),
-! &(pthread_sleep->wakeup_time));
- }
- } else {
- for (pthread_last = pthread_sleep; pthread_last;
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/stat.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 stat.c
-*** stat.c 1995/09/21 02:36:05 1.1.1.1
---- stat.c 1996/06/04 19:17:33
-***************
-*** 43,48 ****
---- 43,49 ----
- #include <errno.h>
-
- struct stat;
-+ struct statfs;
-
- /* ==========================================================================
- * fstat()
-***************
-*** 91,95 ****
---- 92,115 ----
- }
- return(ret);
-
-+ }
-+
-+ /* ==========================================================================
-+ * fstatfs()
-+ *
-+ * Might want to indirect this.
-+ */
-+ int fstatfs(int fd, struct statfs *buf)
-+ {
-+ int ret;
-+
-+ if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
-+ if ((ret = machdep_sys_fstatfs(fd_table[fd]->fd.i, buf)) < OK) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
-+ fd_unlock(fd, FD_READ);
-+ }
-+ return(ret);
- }
-
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/wait.c,v retrieving revision 1.1.1.1
-diff -c -r1.1.1.1 wait.c
-*** wait.c 1995/02/21 08:07:24 1.1.1.1
---- wait.c 1996/10/03 01:20:02
-***************
-*** 103,109 ****
---- 103,111 ----
- pthread_queue_enq(&wait_queue, pthread_run);
-
- /* reschedule unlocks scheduler */
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_WAIT_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_sched_prevent();
- }
-***************
-*** 126,132 ****
---- 128,136 ----
- pthread_queue_enq(&wait_queue, pthread_run);
-
- /* reschedule unlocks scheduler */
-+ SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_WAIT_WAIT);
-+ CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_sched_prevent();
- }
-<pre><font size=-1>
diff --git a/mit-pthreads/patches/Streepy2.html b/mit-pthreads/patches/Streepy2.html
deleted file mode 100755
index 80d44d6440c..00000000000
--- a/mit-pthreads/patches/Streepy2.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<html>
-<head>
- <title>Diffs on diffs :-) by Larry V. Streepy, Jr.</title>
- <base target=_top>
- <meta name="GENERATOR" content="FindMail Communications">
- <meta name="Date" content="Monday, October 07, 1996 02:03 PM PST">
- <meta name="Author" content="Larry V. Streepy, Jr.">
-</head>
-<body background="/gifs/betafm.gif" bgcolor="#ffffff" text="#000000" link="#0000ee" vlink="#ff0000" alink="#000099">
-<h3>Diffs on diffs :-)</h3>
-Larry V. Streepy, Jr. (<a href="mailto.html?mid=2079859748&num=398" target="_top">@healthcare.com</a>)<br>Monday, October 07, 1996 02:03 PM PST<br>
-<p>
-This is a multi-part message in MIME format.<p>
---------------65BE18E23639BCDD7BE55F7F <br>
-Content-Type: text/plain; charset=us-ascii <br>
-Content-Transfer-Encoding: 7bit<p>
-Unfortunately, there are a couple of bugs in my pthread_cancel support (no, say it isn't so :-)<p>
-Oh well, I cam across a couple of cases that I missed in my testing last week. Here are the bugs:<p>
-1. If a thread calls pthread_testcancel during it's cleanup processing after being cancelled, the pthread kernel would hang.<p>
-2. I didn't realize that threads in PS_SLEEP_WAIT state are *NOT* on any queue, they are handled using a linked list. So, when cancelling a thread that was sleeping, a PANIC() I put in possiblymakeRunnable would go off.<p>
-Both of these are fixed. The diffs are attached.<br>
--- <br>
-Larry V. Streepy, Jr. <br>
-Chief Technical Officer, Healthcare Communications, Inc. mailto:<a href="mailto.html?mid=2079859748&num=398" target="_top">@healthcare.com</a> <br>
-(214) 851-7033 (Dallas Main #) <br>
-(970) 626-5028 (My office #) (970) 626-4425 (Fax)<p>
---------------65BE18E23639BCDD7BE55F7F <br>
-Content-Type: text/plain; charset=us-ascii; name=&#34;cancel.diffs&#34; Content-Transfer-Encoding: 7bit <br>
-Content-Disposition: inline; filename=&#34;cancel.diffs&#34;<p>
-Index: pthread_cancel.c<br>
-=================================================================== RCS file: /usr/cvssrc/pthreads-1_60_beta5/pthreads/pthread_cancel.c,v retrieving revision 1.1 <br>
-diff -c -r1.1 pthread_cancel.c<br>
-*** pthread_cancel.c 1996/10/06 00:31:27 1.1<br>
---- pthread_cancel.c 1996/10/07 18:33:27<br>
-***************<br>
-*** 187,192 ****<br>
---- 187,197 ----<br>
- return; /* Can't be cancelled */<br>
- }<br>
- <br>
-+ /* Ensure that we aren't in the process of exiting already */<br>
-+ if( TEST_PF_RUNNING_TO_CANCEL(pthread_run) ) {<br>
-+ return;<br>
-+ }<br>
-+ <br>
- /* See if we have been cancelled */<br>
- if( TEST_PF_CANCELLED(pthread_run) ) {<br>
- /* Set this flag to avoid recursively calling pthread_exit */<br>
-***************<br>
-*** 266,277 ****<br>
- if( pthread-&gt;state == PS_RUNNING )<br>
- return; /* will happen at context switch */<br>
- <br>
-! /* Otherwise, we need to take it off the queue and make it runnable */<br>
-! if( pthread-&gt;queue == NULL ) {<br>
-! PANIC(); /* Must be on a queue */<br>
-! }<br>
- <br>
-- pthread_queue_remove(pthread-&gt;queue, pthread);<br>
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);<br>
- pthread-&gt;old_state = pthread-&gt;state;<br>
- pthread-&gt;state = PS_RUNNING;<br>
---- 271,291 ----<br>
- if( pthread-&gt;state == PS_RUNNING )<br>
- return; /* will happen at context switch */<br>
- <br>
-! /* If the thread is sleeping, the it isn't on a queue. */<br>
-! if( pthread-&gt;state == PS_SLEEP_WAIT ) {<br>
-! sleep_cancel( pthread ); /* Remove from sleep list */<br>
-! } else {<br>
-! /* Otherwise, we need to take it off the queue and make it runnable */<br>
-! <br>
-! if( pthread-&gt;queue == NULL ) {<br>
-! PANIC(); /* Must be on a queue */<br>
-! }<br>
-! <br>
-! pthread_queue_remove(pthread-&gt;queue, pthread);<br>
-! }<br>
-! <br>
-! /* And make it runnable */<br>
- <br>
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);<br>
- pthread-&gt;old_state = pthread-&gt;state;<br>
- pthread-&gt;state = PS_RUNNING;<p>
-<pre><font size=-1>
---------------65BE18E23639BCDD7BE55F7F--
-
-</pre><p></pre>
-<hr>
-<a href="http://www.findmail.com/" target="_top"><font size=-1>Powered by FindMail Communications</font><br></a>
-<br>Please email comments and suggestions to:<a href="/cgi-bin/comments.py" target="_top">comments@findmail.com</a>
-<br><font size=-3 color="#ffffff">xmlarchive</font>
-</body></html> \ No newline at end of file
diff --git a/mit-pthreads/patches/bill_lear b/mit-pthreads/patches/bill_lear
deleted file mode 100755
index f49b79c4272..00000000000
--- a/mit-pthreads/patches/bill_lear
+++ /dev/null
@@ -1,70 +0,0 @@
-From rael@dejanews.com Wed Jan 29 06:06:14 1997
-X-VM-v5-Data: ([nil nil nil t nil nil nil nil nil]
- ["1497" "Tue" "28" "January" "1997" "21:52:57" "-0600" "William S. Lear" "rael@dejanews.com" "<199701290352.VAA08678@homer.dejanews.com>" "53" "Patches for linux2.0" "^From:" nil nil "1" "1997012903:52:57" "Patches for linux2.0" nil nil]
- nil)
-Received: from MIT.EDU (PACIFIC-CARRIER-ANNEX.MIT.EDU [18.69.0.28])
- by analytik.analytikerna.se (8.8.4/8.8.4) with SMTP
- id GAA23245 for <monty@analytikerna.se>; Wed, 29 Jan 1997 06:06:12 +0100 (MET)
-Received: from host-205-238-143-2.dejanews.com by MIT.EDU with SMTP
- id AA25254; Tue, 28 Jan 97 22:53:08 EST
-Received: (from rael@localhost) by homer.dejanews.com (8.7.6/8.6.12) id VAA08678 for pthreads@mit.edu; Tue, 28 Jan 1997 21:52:57 -0600 (CST)
-Message-Id: <199701290352.VAA08678@homer.dejanews.com>
-Content-Length: 1496
-From: "William S. Lear" <rael@dejanews.com>
-To: pthreads@MIT.EDU
-Subject: Patches for linux2.0
-Date: Tue, 28 Jan 1997 21:52:57 -0600 (CST)
-
-
-The following are some patches I found necessary to run smoothly
-under linux2.0. The PTEST directory below refers to the original
-pthreads 1.60 beta 6 release. Of course, the '-O2' "fix" is not strictly
-needed.
-
-#============================================================
-# < pthreads-1_60beta6/config/configure
-# > PTEST/pthreads-1_60beta6/config/configure
-#------------------------------------------------------------
-642c642
-< CFLAGS="-g -O2"
----
-> CFLAGS="-g -O"
-1104,1106d1103
-< cat >> confdefs.h <<EOF
-< #define BSD_TM 1
-< EOF
-
-# Diff for:
-#============================================================
-# < pthreads-1_60beta6/config/config.h.in
-# > PTEST/pthreads-1_60beta6/config/config.h.in
-#------------------------------------------------------------
-3,8d2
-< /* Does the OS have tm needing bsd'ish initialization? */
-< #undef BSD_TM
-<
-< /* Does the OS already support struct timespec */
-< #undef _OS_HAS_TIMESPEC
-<
-
-# Diff for:
-#============================================================
-# < pthreads-1_60beta6/gen/ctime.c
-# > PTEST/pthreads-1_60beta6/gen/ctime.c
-#------------------------------------------------------------
-49c49
-< #include "config.h"
----
->
-
-# Diff for:
-#============================================================
-# < pthreads-1_60beta6/include/math.h
-# > PTEST/pthreads-1_60beta6/include/math.h
-#------------------------------------------------------------
-54d53
-< double hypot __P((double, double));
-
-
-Bill Lear (rael@dejanews.com)
-
diff --git a/mit-pthreads/patches/chris_demetriou b/mit-pthreads/patches/chris_demetriou
deleted file mode 100755
index 283d6c1999c..00000000000
--- a/mit-pthreads/patches/chris_demetriou
+++ /dev/null
@@ -1,149 +0,0 @@
-From cgd@pa.dec.com Fri Aug 15 04:22:21 1997
-X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
- ["3982" "Thu" "14" "August" "1997" "18:57:55" "-0700" "Chris G. Demetriou" "cgd@pa.dec.com" "<15218.871610275@dnaunix.pa.dec.com>" "126" "patches to get 1.60 beta6 to build on ELF NetBSD/alpha systems" "^From:" nil nil "8" "1997081501:57:55" "patches to get 1.60 beta6 to build on ELF NetBSD/alpha systems" nil nil]
- nil)
-Received: from MIT.EDU (PACIFIC-CARRIER-ANNEX.MIT.EDU [18.69.0.28])
- by analytik.analytikerna.se (8.8.4/8.8.4) with SMTP
- id EAA10207 for <monty@analytikerna.se>; Fri, 15 Aug 1997 04:22:19 +0200 (MET DST)
-Received: from mail2.digital.com by MIT.EDU with SMTP
- id AA13470; Thu, 14 Aug 97 22:01:37 EDT
-Received: from dnaunix.pa.dec.com (dnaunix.pa.dec.com [16.4.208.21])
- by mail2.digital.com (8.7.5/UNX 1.5/1.0/WV) with SMTP id SAA15366;
- Thu, 14 Aug 1997 18:58:16 -0700 (PDT)
-Received: by dnaunix.pa.dec.com; id AA15044; Thu, 14 Aug 1997 18:57:56 -0700
-Message-Id: <15218.871610275@dnaunix.pa.dec.com>
-X-Mts: smtp
-Content-Length: 3981
-From: "Chris G. Demetriou" <cgd@pa.dec.com>
-Sender: cgd@pa.dec.com
-To: pthreads-bugs@MIT.EDU
-Cc: "Chris G. Demetriou" <cgd@pa.dec.com>, pthreads@MIT.EDU
-Subject: patches to get 1.60 beta6 to build on ELF NetBSD/alpha systems
-Date: Thu, 14 Aug 97 18:57:55 -0700
-
-Enclosed below are patches to pthreads 1.60 beta6 to build on
-current NetBSD/alpha systems (which use ELF). With these patches,
-pthreads passes 'make check.'
-
-As an aside, the test_switch test generates _340k_ of output ("a"
-for a while, then "ab" for a while) when run one the machine I was
-testing on. In my opinion, that's a ... bit excessive, especially
-since 'make check' has to be run interactively!
-
-
-
-chris
-============================================================================
-diff -rc pthreads-1_60_beta6.orig/config/Makefile.in pthreads-1_60_beta6/config/Makefile.in
-*** pthreads-1_60_beta6.orig/config/Makefile.in Thu Mar 21 20:29:54 1996
---- pthreads-1_60_beta6/config/Makefile.in Thu Aug 14 17:56:55 1997
-***************
-*** 29,35 ****
- # pathname for srcdir here, and live with it.
- srcdir = $(srctop)
-
-! beforeinstall:: install-dirs
-
- .include "${srcdir}/pthreads/Makefile.inc"
- .include "${srcdir}/stdlib/Makefile.inc"
---- 29,35 ----
- # pathname for srcdir here, and live with it.
- srcdir = $(srctop)
-
-! beforeinstall: install-dirs
-
- .include "${srcdir}/pthreads/Makefile.inc"
- .include "${srcdir}/stdlib/Makefile.inc"
-diff -rc pthreads-1_60_beta6.orig/machdep/syscall-alpha-netbsd-1.1.S pthreads-1_60_beta6/machdep/syscall-alpha-netbsd-1.1.S
-*** pthreads-1_60_beta6.orig/machdep/syscall-alpha-netbsd-1.1.S Wed Nov 13 13:03:28 1996
---- pthreads-1_60_beta6/machdep/syscall-alpha-netbsd-1.1.S Thu Aug 14 18:03:27 1997
-***************
-*** 35,54 ****
- .frame sp,0,ra ;\
- ldiq v0, CONCAT(SYS_,x) ;\
- CHMK() ;\
-! beq a3, 2f ;\
-! br gp, 1f ;\
-! 1: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
-! jmp zero, machdep_cerror ;\
-! 2:
-
- #define XSYSCALL(x) SYSCALL(x) ; RET ; .end CONCAT(machdep_sys_,x)
-
- .globl machdep_cerror
- machdep_cerror:
-! br t0, 1f
-! 1:
- ldgp gp, 0(t0)
- stl v0, errno
- #if 0
---- 35,54 ----
- .frame sp,0,ra ;\
- ldiq v0, CONCAT(SYS_,x) ;\
- CHMK() ;\
-! beq a3, CONCAT(Lsys_noerr_,x) ;\
-! br gp, CONCAT(Lsys_err_,x) ;\
-! CONCAT(Lsys_err_,x): ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
-! jmp zero, machdep_cerror ;\
-! CONCAT(Lsys_noerr_,x):
-
- #define XSYSCALL(x) SYSCALL(x) ; RET ; .end CONCAT(machdep_sys_,x)
-
- .globl machdep_cerror
- machdep_cerror:
-! br t0, Lmachdep_cerror_setgp
-! Lmachdep_cerror_setgp:
- ldgp gp, 0(t0)
- stl v0, errno
- #if 0
-diff -rc pthreads-1_60_beta6.orig/machdep/syscall-template-alpha-netbsd-1.1.S pthreads-1_60_beta6/machdep/syscall-template-alpha-netbsd-1.1.S
-*** pthreads-1_60_beta6.orig/machdep/syscall-template-alpha-netbsd-1.1.S Mon Apr 22 23:15:42 1996
---- pthreads-1_60_beta6/machdep/syscall-template-alpha-netbsd-1.1.S Thu Aug 14 17:58:14 1997
-***************
-*** 31,43 ****
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
-! beq a3, 2f ;\
-! br gp, 1f ;\
-! 1: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
-! jmp zero, machdep_cerror ;\
-! 2:
-
- #define SIMPLE_SYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
---- 31,43 ----
- .frame sp,0,ra ;\
- ldiq v0, SYS_##x ;\
- CHMK() ;\
-! beq a3, Lsys_noerr_##x ;\
-! br gp, Lsys_err_##x ;\
-! Lsys_err_##x: ;\
- /* Load gp so we can find cerror to jump to. */;\
- ldgp gp, 0(gp) ;\
-! jmp zero, machdep_cerror ;\
-! Lsys_noerr_##x:
-
- #define SIMPLE_SYSCALL(x) SYSCALL(x) ; ret ; .end machdep_sys_##x
-
-diff -rc pthreads-1_60_beta6.orig/pthreads/process.c pthreads-1_60_beta6/pthreads/process.c
-*** pthreads-1_60_beta6.orig/pthreads/process.c Tue Nov 12 05:45:16 1996
---- pthreads-1_60_beta6/pthreads/process.c Thu Aug 14 18:12:49 1997
-***************
-*** 40,45 ****
---- 40,47 ----
- #include <stdarg.h>
- #include <unistd.h>
-
-+ extern void *alloca();
-+
- #ifndef lint
- static const char rcsid[] = "$Id$";
- #endif
-
diff --git a/mit-pthreads/patches/mevans b/mit-pthreads/patches/mevans
deleted file mode 100755
index d5ff2f27610..00000000000
--- a/mit-pthreads/patches/mevans
+++ /dev/null
@@ -1,642 +0,0 @@
-=A0
-Attached are several patches for pthreads-1_60_beta6. The patches fall
-into 3 catagories:
-
- 1. Crashes and hangs.
- 2. Missing functionality (namely flock())
- 3. Use of POSIX reentrant safe routines.
-
-Most of the patches contain a comment as to why the change was made.
-The one major exception is to fd_kern.c at line 257 (unpatched). The
-change to that line is to fix a "hang" that prevents threads for
-scheduling for an hour if there is no external I/O event.
-
-I also include patches that modify several functions to use POSIX
-reentrant safe routines. I know that MIT pthreads implements routine
-like gethostbyname in a thread safe manner, but we're pretty, um, anal
-about trying to keep our code as portable as possible. By excluding
-using routines that are not reentrant safe according to the PTHREAD
-safe, it's easy for us to stub out the unsafe routines and catch
-non-compliant code. I almost left these patches out, but I'm hoping
-they'll be adopted. :-)
-
-WARNING: None of the MIT pthreads routines that convert floats/doubles
-between their native forms and strings are thread safe! (i.e printf,
-sprintf, fprintf, atod, strtod, etc) I have replacements, but I need to
-check with the author of the replacements and my employer.
-
-Mark Evans
-
-------------69CDAAF52A3566916F8ED01A0
-Content-Disposition: inline; filename="pthreads-1_60_beta6.patch"
-Content-Type: text/plain; charset=us-ascii; name="pthreads-1_60_beta6.patch"
-Content-Transfer-Encoding: 7bit
-
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/config/config.h.in pthreads-1_60_beta6+/config/config.h.in
-*** pthreads-1_60_beta6/config/config.h.in Thu Mar 21 21:30:04 1996
---- pthreads-1_60_beta6+/config/config.h.in Sat Mar 15 14:08:55 1997
-***************
-*** 137,142 ****
---- 137,145 ----
- /* Define if you have the syscall_ftruncate function. */
- #undef HAVE_SYSCALL_FTRUNCATE
-
-+ /* Define if you have the syscall_flock function. */
-+ #undef HAVE_SYSCALL_FLOCK
-+
- /* Define if you have the syscall_getdents function. */
- #undef HAVE_SYSCALL_GETDENTS
-
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/config/configure.in pthreads-1_60_beta6+/config/configure.in
-*** pthreads-1_60_beta6/config/configure.in Wed Nov 13 14:03:08 1996
---- pthreads-1_60_beta6+/config/configure.in Sat Mar 15 14:08:55 1997
-***************
-*** 241,247 ****
-
- PTHREADS_CHECK_SYSCALLS(open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
-! rename select getdtablesize ioctl ftruncate
- dnl - signals
- sigsuspend sigaction sigpause sigprocmask ksigaction
- dnl - directory reading
---- 241,247 ----
-
- PTHREADS_CHECK_SYSCALLS(open write read creat close fcntl lseek dup2 dup pipe
- fchmod fchown execve fstat lstat link unlink chdir chown chmod stat
-! rename select getdtablesize ioctl ftruncate flock
- dnl - signals
- sigsuspend sigaction sigpause sigprocmask ksigaction
- dnl - directory reading
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/gen/directory.c pthreads-1_60_beta6+/gen/directory.c
-*** pthreads-1_60_beta6/gen/directory.c Sat May 20 10:55:34 1995
---- pthreads-1_60_beta6+/gen/directory.c Sat Mar 15 14:08:55 1997
-***************
-*** 251,262 ****
---- 251,266 ----
- /*
- * Seek to an entry in a directory.
- * _seekdir is in telldir.c so that it can share opaque data structures.
-+ *
-+ * Use the POSIX reentrant safe readdir_r to simplify varifying POSIX
-+ * thread-safe compliance.
- */
- void seekdir(DIR * dirp, long loc)
- {
- register struct ddloc ** prevlp;
- register struct ddloc * lp;
- struct dirent * dp;
-+ struct dirent de;
-
- pthread_mutex_lock (dirp->dd_lock);
- prevlp = (struct ddloc **)&(dirp->dd_ddloc);
-***************
-*** 277,283 ****
- dirp->dd_seek = lp->loc_seek;
- dirp->dd_loc = 0;
- while (dirp->dd_loc < lp->loc_loc) {
-! if (!(dp = readdir(dirp))) {
- *prevlp = lp->loc_next;
- break;
- }
---- 281,287 ----
- dirp->dd_seek = lp->loc_seek;
- dirp->dd_loc = 0;
- while (dirp->dd_loc < lp->loc_loc) {
-! if (readdir_r(dirp, &de, &dp)) {
- *prevlp = lp->loc_next;
- break;
- }
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/gen/getcwd.c pthreads-1_60_beta6+/gen/getcwd.c
-*** pthreads-1_60_beta6/gen/getcwd.c Sat Sep 2 17:39:30 1995
---- pthreads-1_60_beta6+/gen/getcwd.c Sat Mar 15 14:08:55 1997
-***************
-*** 50,67 ****
- (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
- dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
-
- char *
- getcwd(pt, size)
- char *pt;
- size_t size;
- {
-- register struct dirent *dp;
- register DIR *dir;
- register dev_t dev;
- register ino_t ino;
- register int first;
- register char *bpt, *bup;
- struct stat s;
- dev_t root_dev;
- ino_t root_ino;
- size_t ptsize, upsize;
---- 50,71 ----
- (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
- dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
-
-+ /* Only use reentrant safe routines to simplify varifying POSIX thread-safe
-+ * compliance. (mevans).
-+ */
- char *
- getcwd(pt, size)
- char *pt;
- size_t size;
- {
- register DIR *dir;
- register dev_t dev;
- register ino_t ino;
- register int first;
- register char *bpt, *bup;
- struct stat s;
-+ struct dirent *dp;
-+ struct dirent de;
- dev_t root_dev;
- ino_t root_ino;
- size_t ptsize, upsize;
-***************
-*** 166,179 ****
- save_errno = 0;
- if (s.st_dev == dev) {
- for (;;) {
-! if (!(dp = readdir(dir)))
- goto notfound;
- if (dp->d_fileno == ino)
- break;
- }
- } else
- for (;;) {
-! if (!(dp = readdir(dir)))
- goto notfound;
- if (ISDOT(dp))
- continue;
---- 170,183 ----
- save_errno = 0;
- if (s.st_dev == dev) {
- for (;;) {
-! if (readdir_r(dir, &de, &dp))
- goto notfound;
- if (dp->d_fileno == ino)
- break;
- }
- } else
- for (;;) {
-! if (readdir_r(dir, &de, &dp))
- goto notfound;
- if (ISDOT(dp))
- continue;
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/include/syslog.h pthreads-1_60_beta6+/include/syslog.h
-*** pthreads-1_60_beta6/include/syslog.h Mon Sep 26 21:26:29 1994
---- pthreads-1_60_beta6+/include/syslog.h Sat Mar 15 14:08:56 1997
-***************
-*** 9,14 ****
---- 9,16 ----
- #ifndef SYSLOG_H
- #define SYSLOG_H
-
-+ /* Added __[BEGIN/END]_DECLS so this file would work with C++. (mevans) */
-+ #include <sys/cdefs.h>
- #include <stdarg.h>
-
- /* Discipline: openlog(), closelog(), and setlogmask() are not thread-safe
-***************
-*** 84,95 ****
---- 86,101 ----
- #define LOG_NDELAY 0x08 /* don't delay open */
- #define LOG_NOWAIT 0x10 /* if forking to log on console, don't wait() */
-
-+ __BEGIN_DECLS
-+
- /* Syslogging functions. */
- void syslog(int pri, char *fmt, ...);
- void vsyslog(int pri, char *fmt, va_list args);
- void openlog(char *ident, int logstat, int logfac);
- void closelog(void);
- int setlogmask(int pmask);
-+
-+ __END_DECLS
-
- #endif
-
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/machdep/engine-i386-linux-1.0.c pthreads-1_60_beta6+/machdep/engine-i386-linux-1.0.c
-*** pthreads-1_60_beta6/machdep/engine-i386-linux-1.0.c Mon Oct 21 20:39:13 1996
---- pthreads-1_60_beta6+/machdep/engine-i386-linux-1.0.c Sat Mar 15 14:08:56 1997
-***************
-*** 142,147 ****
---- 142,149 ----
- * machdep_pthread_start().
- */
- machdep_pthread->machdep_state->__pc = (char *)machdep_pthread_start;
-+ machdep_pthread->machdep_state->__bp = (char *)0;/* So the backtrace
-+ * is sensible (mevans) */
-
- /* Stack starts high and builds down. */
- machdep_pthread->machdep_state->__sp =
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/machdep/syscall-i386-linux-1.0.S pthreads-1_60_beta6+/machdep/syscall-i386-linux-1.0.S
-*** pthreads-1_60_beta6/machdep/syscall-i386-linux-1.0.S Mon Oct 21 22:17:32 1996
---- pthreads-1_60_beta6+/machdep/syscall-i386-linux-1.0.S Sat Mar 15 14:08:56 1997
-***************
-*** 148,156 ****
- /* =========================================================================
- * exit 1 select 82
- * fork 2 socketcall 102
-! * read 3 readv 145
-! * write 4 writev 146
-! * open 5
- * creat 8
- * link 9
- * unlink 10
---- 148,156 ----
- /* =========================================================================
- * exit 1 select 82
- * fork 2 socketcall 102
-! * read 3 flock 143
-! * write 4 readv 145
-! * open 5 writev 146
- * creat 8
- * link 9
- * unlink 10
-***************
-*** 390,394 ****
---- 390,401 ----
- */
- #ifdef HAVE_SYSCALL_WRITEV
- SYSCALL3(writev)
-+ #endif
-+
-+ /* ==========================================================================
-+ * machdep_sys_flock()
-+ */
-+ #ifdef HAVE_SYSCALL_FLOCK
-+ SYSCALL2(flock)
- #endif
-
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/net/gethostbyname.c pthreads-1_60_beta6+/net/gethostbyname.c
-*** pthreads-1_60_beta6/net/gethostbyname.c Mon Apr 22 22:41:21 1996
---- pthreads-1_60_beta6+/net/gethostbyname.c Sat Mar 15 14:08:58 1997
-***************
-*** 146,161 ****
- {
- char **alias;
- FILE *fp = NULL;
-
- pthread_mutex_lock(&host_iterate_lock);
- sethostent(0);
-! while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcasecmp(result->h_name, name) == 0)
- break;
- for (alias = result->h_aliases; *alias; alias++) {
-! if (strcasecmp(*alias, name) == 0)
- break;
- }
- }
- pthread_mutex_unlock(&host_iterate_lock);
---- 146,166 ----
- {
- char **alias;
- FILE *fp = NULL;
-+ int fFound = FALSE;
-
- pthread_mutex_lock(&host_iterate_lock);
- sethostent(0);
-! while (!fFound && (result = gethostent_r(result, buf, bufsize, errval))
-! != NULL) {
- /* Check the entry's name and aliases against the given name. */
- if (strcasecmp(result->h_name, name) == 0)
- break;
- for (alias = result->h_aliases; *alias; alias++) {
-! if (strcasecmp(*alias, name) == 0) {
-! /* fFound will exit while loop. (mevans). */
-! fFound = TRUE;
- break;
-+ }
- }
- }
- pthread_mutex_unlock(&host_iterate_lock);
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/net/res_debug.c pthreads-1_60_beta6+/net/res_debug.c
-*** pthreads-1_60_beta6/net/res_debug.c Thu Feb 23 22:42:35 1995
---- pthreads-1_60_beta6+/net/res_debug.c Sat Mar 15 14:08:58 1997
-***************
-*** 375,380 ****
---- 375,383 ----
-
- /*
- * Print resource record fields in human readable form.
-+ *
-+ * Removed calls to non-reentrant routines to simplify varifying
-+ * POSIX thread-safe implementations. (mevans).
- */
- char *
- p_rr(cp, msg, file)
-***************
-*** 386,391 ****
---- 389,395 ----
- char *cp1, *cp2;
- u_long tmpttl, t;
- int lcnt;
-+ char buf[32];
-
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL); /* compression error */
-***************
-*** 413,426 ****
- case C_HS:
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- if (dlen == 4) {
-! fprintf(file,"\t%s", inet_ntoa(inaddr));
- cp += dlen;
- } else if (dlen == 7) {
- char *address;
- u_char protocol;
- u_short port;
-
-! address = inet_ntoa(inaddr);
- cp += sizeof(inaddr);
- protocol = *(u_char*)cp;
- cp += sizeof(u_char);
---- 417,432 ----
- case C_HS:
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- if (dlen == 4) {
-! fprintf(file,"\t%s",
-! inet_ntoa_r(inaddr, buf, sizeof(buf)));
- cp += dlen;
- } else if (dlen == 7) {
- char *address;
- u_char protocol;
- u_short port;
-
-! address = inet_ntoa_r(inaddr,
-! buf, sizeof(buf));
- cp += sizeof(inaddr);
- protocol = *(u_char*)cp;
- cp += sizeof(u_char);
-***************
-*** 524,530 ****
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- cp += sizeof(u_long);
- fprintf(file, "\t%s %s ( ",
-! inet_ntoa(inaddr),
- deproto((int) *cp));
- cp += sizeof(u_char);
- n = 0;
---- 530,536 ----
- bcopy(cp, (char *)&inaddr, sizeof(inaddr));
- cp += sizeof(u_long);
- fprintf(file, "\t%s %s ( ",
-! inet_ntoa_r(inaddr, buf, sizeof(buf)),
- deproto((int) *cp));
- cp += sizeof(u_char);
- n = 0;
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/fd_kern.c pthreads-1_60_beta6+/pthreads/fd_kern.c
-*** pthreads-1_60_beta6/pthreads/fd_kern.c Tue Oct 1 12:26:48 1996
---- pthreads-1_60_beta6+/pthreads/fd_kern.c Sat Mar 15 14:09:00 1997
-***************
-*** 215,221 ****
- * Called when there is no active thread to run.
- */
- extern struct timeval __fd_kern_wait_timeout;
-!
- void fd_kern_wait()
- {
- fd_set fd_set_read, fd_set_write, fd_set_except;
---- 215,221 ----
- * Called when there is no active thread to run.
- */
- extern struct timeval __fd_kern_wait_timeout;
-! extern volatile sig_atomic_t sig_to_process;
- void fd_kern_wait()
- {
- fd_set fd_set_read, fd_set_write, fd_set_except;
-***************
-*** 254,260 ****
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
-! __fd_kern_wait_timeout.tv_sec = 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
-
---- 254,260 ----
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
-! __fd_kern_wait_timeout.tv_sec = (sig_to_process) ? 0 : 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
-
-***************
-*** 726,731 ****
---- 726,753 ----
- return(ret);
- }
-
-+ #if defined (HAVE_SYSCALL_FLOCK)
-+ /* ==========================================================================
-+ * flock()
-+ *
-+ * Added (mevans)
-+ */
-+ int flock(int fd, int operation)
-+ {
-+ int ret;
-+
-+ if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
-+ if ((ret = machdep_sys_flock(fd_table[fd]->fd.i,
-+ operation)) < OK) {
-+ SET_ERRNO(-ret);
-+ ret = NOTOK;
-+ }
-+ fd_unlock(fd, FD_RDWR);
-+ }
-+ return(ret);
-+ }
-+ #endif
-+
- /* ==========================================================================
- * pipe()
- */
-***************
-*** 1126,1132 ****
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
- SO_ERROR, &ret, &tmpnamelen);
-! SET_ERRNO(-ret);
- ret = NOTOK;
- }
- } else {
---- 1148,1155 ----
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
- SO_ERROR, &ret, &tmpnamelen);
-! /* ret is already positive (mevans) */
-! SET_ERRNO(ret);
- ret = NOTOK;
- }
- } else {
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/malloc.c pthreads-1_60_beta6+/pthreads/malloc.c
-*** pthreads-1_60_beta6/pthreads/malloc.c Thu Mar 9 21:06:43 1995
---- pthreads-1_60_beta6+/pthreads/malloc.c Sat Mar 15 14:09:00 1997
-***************
-*** 196,204 ****
- else
- n = n - x;
- if (n) {
-! if (sbrk(n) == (char *)-1)
- return (NULL);
- }
- bucket = 0;
- amt = 8;
- while (pagesz > amt) {
---- 196,207 ----
- else
- n = n - x;
- if (n) {
-! if (sbrk(n) == (char *)-1) {
-! /* Unlock before returning (mevans) */
-! pthread_mutex_unlock(mutex);
- return (NULL);
- }
-+ }
- bucket = 0;
- amt = 8;
- while (pagesz > amt) {
-***************
-*** 363,366 ****
---- 366,382 ----
- free(cp);
-
- return (res);
-+ }
-+ /* ==========================================================================
-+ * calloc()
-+ *
-+ * Added to ensure pthread's allocation is used (mevans).
-+ */
-+ void *calloc(size_t nmemb, size_t size)
-+ {
-+ void *p;
-+ size *= nmemb;
-+ p = malloc(size);
-+ if (p) memset(p, 0, size);
-+ return (p);
- }
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/select.c pthreads-1_60_beta6+/pthreads/select.c
-*** pthreads-1_60_beta6/pthreads/select.c Sat Jul 6 21:58:55 1996
---- pthreads-1_60_beta6+/pthreads/select.c Sat Mar 15 14:09:00 1997
-***************
-*** 165,176 ****
- pthread_resched_resume(PS_SELECT_WAIT);
-
- /* We're awake */
-- CLEAR_PF_DONE_EVENT(pthread_run);
- if (sleep_cancel(pthread_run) == NOTOK) {
- ret = OK;
- } else {
- ret = data.nfds;
- }
- } else {
- pthread_resched_resume(PS_SELECT_WAIT);
- CLEAR_PF_DONE_EVENT(pthread_run);
---- 165,180 ----
- pthread_resched_resume(PS_SELECT_WAIT);
-
- /* We're awake */
- if (sleep_cancel(pthread_run) == NOTOK) {
- ret = OK;
- } else {
- ret = data.nfds;
- }
-+ /* Moving this after the sleep_cancel() seemed
-+ * to fix intermittent crashes during heavy
-+ * socket use. (mevans)
-+ */
-+ CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- pthread_resched_resume(PS_SELECT_WAIT);
- CLEAR_PF_DONE_EVENT(pthread_run);
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/signal.c pthreads-1_60_beta6+/pthreads/signal.c
-*** pthreads-1_60_beta6/pthreads/signal.c Tue Mar 12 21:33:17 1996
---- pthreads-1_60_beta6+/pthreads/signal.c Sat Mar 15 14:09:00 1997
-***************
-*** 65,71 ****
- */
-
- static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
-! static sig_atomic_t sig_to_process = 0;
-
- /* static volatile sigset_t sig_to_process; */
- static volatile int sig_count = 0;
---- 65,71 ----
- */
-
- static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
-! volatile sig_atomic_t sig_to_process = 0;
-
- /* static volatile sigset_t sig_to_process; */
- static volatile int sig_count = 0;
-***************
-*** 303,309 ****
- break;
- case NOTOK:
- /* Do the registered action, no threads were sleeping */
-! sigdefault(sig);
- break;
- }
- break;
---- 303,317 ----
- break;
- case NOTOK:
- /* Do the registered action, no threads were sleeping */
-! /* There is a timing window that gets
-! * here when no threads are on the
-! * sleep queue. This is a quick fix.
-! * The real problem is possibly related
-! * to heavy use of condition variables
-! * with time outs.
-! * (mevans)
-! *sigdefault(sig);
-! */
- break;
- }
- break;
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/stdio/setvbuf.c pthreads-1_60_beta6+/stdio/setvbuf.c
-*** pthreads-1_60_beta6/stdio/setvbuf.c Sat Sep 3 20:58:36 1994
---- pthreads-1_60_beta6+/stdio/setvbuf.c Sat Mar 15 14:09:00 1997
-***************
-*** 142,148 ****
- flags |= __SLBF;
- if (flags & __SRW)
- flags &= ~(__SRD | __SWR);
-! fp->_w = 0;
- fp->_flags = flags;
- fp->_bf._base = fp->_p = (unsigned char *)buf;
- fp->_bf._size = size;
---- 142,148 ----
- flags |= __SLBF;
- if (flags & __SRW)
- flags &= ~(__SRD | __SWR);
-! fp->_w = size; /* Was 0 (mevans) */
- fp->_flags = flags;
- fp->_bf._base = fp->_p = (unsigned char *)buf;
- fp->_bf._size = size;
-diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/stdlib/system.c pthreads-1_60_beta6+/stdlib/system.c
-*** pthreads-1_60_beta6/stdlib/system.c Wed Apr 24 21:18:56 1996
---- pthreads-1_60_beta6+/stdlib/system.c Sat Mar 15 14:09:01 1997
-***************
-*** 62,68 ****
- argp[2] = (char *) command;
- sigemptyset(&tmp_mask);
- sigaddset(&tmp_mask, SIGCHLD);
-! pthread_sigmask(SIG_BLOCK, tmp_mask, &old_mask);
- switch(pid = fork()) {
- case -1: /* error */
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
---- 62,69 ----
- argp[2] = (char *) command;
- sigemptyset(&tmp_mask);
- sigaddset(&tmp_mask, SIGCHLD);
-! /* Pass the address of tmp_mask to avoid a sigfault. (mevans). */
-! pthread_sigmask(SIG_BLOCK, &tmp_mask, &old_mask);
- switch(pid = fork()) {
- case -1: /* error */
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
diff --git a/mit-pthreads/patches/p153 b/mit-pthreads/patches/p153
deleted file mode 100755
index 4e374e29a10..00000000000
--- a/mit-pthreads/patches/p153
+++ /dev/null
@@ -1,90 +0,0 @@
-<HEAD><TITLE>discuss@charon.mit.edu: [153] in "Pthreads Bugs"</TITLE>
-<H1>[153] in Pthreads Bugs</H1></HEAD>
-<A HREF="/"><IMG SRC="/i-d.gif" ALT="root"></A>
-<A HREF="?153"><IMG SRC="/i-back.gif" ALT="meeting"></A>
-<A HREF="/help.html"><IMG SRC="/i-help.gif" ALT="help"></A>
-<A HREF="1"><IMG SRC="/i-first.gif" ALT="first"></A>
-<A HREF="151"><IMG SRC="/i-fref.gif" ALT="first in chain"></A>
-<A HREF="152"><IMG SRC="/i-pref.gif" ALT="previous in chain"></A>
-<A HREF="152"><IMG SRC="/i-prev.gif" ALT="previous"></A>
-<A HREF="154"><IMG SRC="/i-next.gif" ALT="next"></A>
-<IMG SRC="/n-nref.gif" ALT="">
-<IMG SRC="/n-lref.gif" ALT="">
-<A HREF="161"><IMG SRC="/i-last.gif" ALT="last"></A>
-<HR><H2>Re: sleep / SIGALRM problem in 1_60_beta6</H2>
-<H3>daemon@ATHENA.MIT.EDU (Mon Dec 9 19:32:22 1996
-)</H3>
-<PRE>
-Date: Mon, 09 Dec 1996 17:22:50 -0700
-From: "Mark M. Evans" &lt;mevans@cti-ltd.com&gt;
-To: Tim Hinderliter &lt;kyd@internap.com&gt;
-Cc: pthreads-bugs@MIT.EDU
-
-I think I found what caused fd_kern_wait() to block for the entire
-hour (instead of waking up due to the SIGALRM). Basically, the
-SIGALRM that would move the sleeping thread to the run queue occurs
-while pthread_kernel_lock is set, but *before* the critical section in
-fd_kern_wait() that sets __fd_kern_wait_timeout.tv_sec to 3600. So,
-sig_handler_real() clears __fd_kern_wait_timeout.tv_sec "too soon."
-
-I've worked around this by checking sig_to_process in the critical
-section to determine if we are truly idle. To do this I had to make
-sig_to_process publicly available.
-
-Here are the diffs (relative to the pthreads/pthreads directory):
-
-diff -c -r1.2 -r1.3
-*** signal.c 1996/11/20 05:09:50 1.2
---- signal.c 1996/12/09 23:14:52 1.3
-***************
-*** 65,71 ****
- */
-
- static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
-! static sig_atomic_t sig_to_process = 0;
-
- /* static volatile sigset_t sig_to_process; */
- static volatile int sig_count = 0;
---- 65,71 ----
- */
-
- static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
-! sig_atomic_t sig_to_process = 0;
-
- /* static volatile sigset_t sig_to_process; */
- static volatile int sig_count = 0;
-*** fd_kern.c 1996/12/03 04:14:59 1.6
---- fd_kern.c 1996/12/09 23:14:51 1.7
-***************
-*** 215,221 ****
- * Called when there is no active thread to run.
- */
- extern struct timeval __fd_kern_wait_timeout;
-!
- void fd_kern_wait()
- {
- fd_set fd_set_read, fd_set_write, fd_set_except;
---- 215,221 ----
- * Called when there is no active thread to run.
- */
- extern struct timeval __fd_kern_wait_timeout;
-! extern volatile sig_atomic_t sig_to_process;
- void fd_kern_wait()
- {
- fd_set fd_set_read, fd_set_write, fd_set_except;
-***************
-*** 254,260 ****
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
-! __fd_kern_wait_timeout.tv_sec = 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &amp;sig_to_block, &amp;oset);
-
---- 254,260 ----
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
-! __fd_kern_wait_timeout.tv_sec = (sig_to_process) ? 0 : 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &amp;sig_to_block, &amp;oset);
diff --git a/mit-pthreads/patches/p155 b/mit-pthreads/patches/p155
deleted file mode 100755
index dbdfa7de899..00000000000
--- a/mit-pthreads/patches/p155
+++ /dev/null
@@ -1,96 +0,0 @@
-<HEAD><TITLE>discuss@charon.mit.edu: [155] in "Pthreads Bugs"</TITLE>
-<H1>[155] in Pthreads Bugs</H1></HEAD>
-<A HREF="/"><IMG SRC="/i-d.gif" ALT="root"></A>
-<A HREF="?155"><IMG SRC="/i-back.gif" ALT="meeting"></A>
-<A HREF="/help.html"><IMG SRC="/i-help.gif" ALT="help"></A>
-<A HREF="1"><IMG SRC="/i-first.gif" ALT="first"></A>
-<IMG SRC="/n-fref.gif" ALT="">
-<IMG SRC="/n-pref.gif" ALT="">
-<A HREF="154"><IMG SRC="/i-prev.gif" ALT="previous"></A>
-<A HREF="156"><IMG SRC="/i-next.gif" ALT="next"></A>
-<IMG SRC="/n-nref.gif" ALT="">
-<IMG SRC="/n-lref.gif" ALT="">
-<A HREF="161"><IMG SRC="/i-last.gif" ALT="last"></A>
-<HR><H2>pthread_kill() Bug</H2>
-<H3>daemon@ATHENA.MIT.EDU (Thu Dec 26 20:34:45 1996
-)</H3>
-<PRE>
-From: Chris Colohan &lt;colohan@eecg.toronto.edu&gt;
-To: pthreads-bugs@MIT.EDU, proven@MIT.EDU
-Date: Thu, 26 Dec 1996 20:33:48 -0500
-
-pthread_kill() has a problem in PThreads 1.60beta6. It checks to see
-if the target thread is in the state PS_SIGWAIT, and if it is it
-reschedules it. But it does not check if there is more than one
-thread in the PS_SIGWAIT state, and hence mangles the pthread_sigwait
-linked list, potentially resulting in threads getting blocked forever,
-and signals never being delivered. I have a *very* contrived test
-case that demonstrates this problem if you would like it. Please let
-me know...
-
-Chris
-===
-
-Diffs created with diff -c:
-
-*** /home/colohan/thesis/t/pthreads-1_60_beta6/pthreads/pthread_kill.c Tue Feb 21 03:07:18 1995
---- pthread_kill.c Thu Dec 26 19:50:22 1996
-***************
-*** 41,51 ****
---- 41,58 ----
-
- #include &lt;pthread.h&gt;
-
-+ /* Defined in sig.c, a linked list of threads currently
-+ * blocked in sigwait(): */
-+ extern struct pthread * pthread_sigwait;
-+
-+
- /* ==========================================================================
- * pthread_kill()
- */
- int pthread_kill(struct pthread * pthread, int sig)
- {
-+ struct pthread ** pthread_ptr;
-+
- pthread_sched_prevent();
-
- /* Check who is the current owner of pthread */
-***************
-*** 53,62 ****
- if (0) {
- } else {
- if (pthread-&gt;state == PS_SIGWAIT) {
-! if (sigismember(pthread-&gt;data.sigwait, sig)) {
-! *(int *)(pthread-&gt;ret) = sig;
-! pthread_sched_other_resume(pthread);
-! return(OK);
- }
- }
- sigaddset(&amp;(pthread-&gt;sigpending), sig);
---- 60,84 ----
- if (0) {
- } else {
- if (pthread-&gt;state == PS_SIGWAIT) {
-! if(sigismember(pthread-&gt;data.sigwait, sig)) {
-! for (pthread_ptr = &amp;pthread_sigwait;
-! (*pthread_ptr);
-! pthread_ptr = &amp;((*pthread_ptr)-&gt;next)) {
-! if ((*pthread_ptr) == pthread) {
-!
-! /* Take the thread out of the
-! * pthread_sigwait linked list: */
-! *pthread_ptr=(*pthread_ptr)-&gt;next;
-!
-! *(int *)(pthread-&gt;ret) = sig;
-! pthread_sched_other_resume(pthread);
-! return(OK);
-! }
-! }
-! /* A thread should not be in the state PS_SIGWAIT
-! * without being in the pthread_sigwait linked
-! * list: */
-! PANIC();
- }
- }
- sigaddset(&amp;(pthread-&gt;sigpending), sig);
diff --git a/mit-pthreads/pthreads/GNUmakefile.inc b/mit-pthreads/pthreads/GNUmakefile.inc
deleted file mode 100644
index c8621495bac..00000000000
--- a/mit-pthreads/pthreads/GNUmakefile.inc
+++ /dev/null
@@ -1,46 +0,0 @@
-# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91
-
-# pthread sources
-VPATH := $(VPATH):${srcdir}/pthreads
-
-SRCS:= cleanup.c cond.c fd.c fd_kern.c fd_pipe.c fd_sysv.c file.c globals.c \
- malloc.c mutex.c pthread.c pthread_attr.c queue.c signal.c machdep.c \
- syscall.S pthread_join.c pthread_detach.c pthread_once.c sleep.c \
- specific.c process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
- dump_state.c pthread_kill.c stat.c readv.c writev.c condattr.c \
- pthread_cancel.c panic.c $(SRCS)
-
-ifeq ($(HAVE_SYSCALL_TEMPLATE),yes)
-SYSCALL_FILTER_RULE= for s in $(AVAILABLE_SYSCALLS) ; do \
- case " $(SYSCALL_EXCEPTIONS) " in \
- *" "$$s" "*) ;; \
- *) echo $$s ;; \
- esac ; \
- done
-STD_SYSCALLS:=$(shell $(SYSCALL_FILTER_RULE))
-STD_SYSCALL_FILES:= $(addprefix S,$(addsuffix .o,$(STD_SYSCALLS)))
-EXTRA_OBJS := $(EXTRA_OBJS) syscalls.o
-# EXTRA_OBJS := $(EXTRA_OBJS) $(STD_SYSCALL_FILES)
-
-ifndef SYSCALL_PIC_COMPILE
-SYSCALL_PIC_COMPILE=true
-endif
-
-obj/syscalls.o: syscall-template.S
- -rm -rf obj/syscalls
- mkdir obj/syscalls
- for syscall in $(STD_SYSCALLS) ; do \
- echo $$syscall ; \
- $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -c syscall-template.S -o obj/syscalls/S$$syscall.o ; \
- $(SYSCALL_PIC_COMPILE) ; \
- done
- x=`pwd` && cd obj/syscalls && ld -r -o ../syscalls.o S*.o && cd $$x
- rm -r obj/syscalls
-endif
-
-syscall.o: ${.CURDIR}/pthreads/syscall.S
- cpp ${CPPFLAGS} ${.CURDIR}/pthreads/syscall.S > syscall.i
- as syscall.i
- rm syscall.i
- mv a.out syscall.o
diff --git a/mit-pthreads/pthreads/Makefile.inc b/mit-pthreads/pthreads/Makefile.inc
deleted file mode 100644
index 3939d57de6e..00000000000
--- a/mit-pthreads/pthreads/Makefile.inc
+++ /dev/null
@@ -1,75 +0,0 @@
-# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91
-
-# pthread sources
-.PATH: ${srcdir}/pthreads
-
-SRCS+= cleanup.c cond.c fd.c fd_kern.c fd_pipe.c file.c globals.c malloc.c \
- mutex.c pthread.c pthread_attr.c queue.c signal.c machdep.c syscall.S \
- pthread_join.c pthread_detach.c pthread_once.c sleep.c specific.c \
- process.c wait.c errno.c schedparam.c _exit.c prio_queue.c \
- pthread_init.c init.cc sig.c info.c mutexattr.c select.c wrapper.c \
- dump_state.c pthread_kill.c condattr.c pthread_cancel.c panic.c
-
-.if $(HAVE_SYSCALL_TEMPLATE) == yes
-OBJS+= syscalls.o
-.if !defined(NOPIC)
-SOBJS+= syscalls.so
-SYSCALL_PIC_COMPILE= $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -DPIC -c ${.CURDIR}/syscall-template.S -o ${.OBJDIR}/syscalls/S$$syscall.so
-.else
-SYSCALL_PIC_COMPILE= true
-.endif
-.if !defined(NOPROFILE)
-POBJS+= syscalls.po
-SYSCALL_PROF_COMPILE= $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -pg -c ${.CURDIR}/syscall-template.S -o ${.OBJDIR}/syscalls/S$$syscall.po
-.else
-SYSCALL_PROF_COMPILE= true
-.endif
-
-OPSYS!= uname -s
-
-syscalls.o syscalls.so syscalls.po : syscall-template.S
- -rm -rf ${.OBJDIR}/syscalls
- mkdir ${.OBJDIR}/syscalls
- for syscall in $(AVAILABLE_SYSCALLS) ; do \
- case " $(SYSCALL_EXCEPTIONS) " in \
- *" "$$syscall" "*) ;; \
- *) echo $$syscall ; \
- $(CC) $(CFLAGS) -DSYSCALL_NAME=$$syscall -c ${.CURDIR}/syscall-template.S -o ${.OBJDIR}/syscalls/S$$syscall.o ; \
- $(SYSCALL_PIC_COMPILE) ; \
- $(SYSCALL_PROF_COMPILE) ;; \
- esac ; \
- done
- x=`pwd` && cd ${.OBJDIR}/syscalls && ld -r -o ../syscalls.o *.o && cd $$x
-.if !defined(NOPIC)
- x=`pwd` && cd ${.OBJDIR}/syscalls && ld -r -o ../syscalls.so *.so && cd $$x
-.endif
-.if !defined(NOPROFILE)
- x=`pwd` && cd ${.OBJDIR}/syscalls && ld -r -o ../syscalls.po *.po && cd $$x
-.endif
- rm -r ${.OBJDIR}/syscalls
-.endif
-
-syscall.o: syscall.S
-.if (${OPSYS} == "FreeBSD")
- $(CC) -c -x assembler-with-cpp -o syscall.o ${.CURDIR}/syscall.S
-.else
- cpp ${CPPFLAGS} ${.CURDIR}/syscall.S > syscall.i
- as syscall.i
- rm syscall.i
- mv a.out syscall.o
-.endif
-
-syscall.po: syscall.S
-.if (${OPSYS} == "FreeBSD")
- $(CC) -c -x assembler-with-cpp -o syscall.po ${.CURDIR}/syscall.S
-.else
- cpp ${CPPFLAGS} ${.CURDIR}/syscall.S > syscall.i
- as syscall.i
- rm syscall.i
- mv a.out syscall.po
-.endif
-
-MAN2+=
-
-MAN3+=
-
diff --git a/mit-pthreads/pthreads/_exit.c b/mit-pthreads/pthreads/_exit.c
deleted file mode 100644
index fde795011ce..00000000000
--- a/mit-pthreads/pthreads/_exit.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* ==== _exit.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : The locking functions for stdio.
- *
- * 1.00 94/09/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <fcntl.h>
-
-/* ==========================================================================
- * _exit()
- *
- * Change all file descriptors back to their original state,
- * before exiting for good.
- */
-void _exit(int status)
-{
- int fd;
-
- pthread_sched_prevent();
-
- for (fd = 0; fd < dtablesize; fd++) {
- if (fd_table[fd] == NULL) {
- continue;
- }
- /* Is it a kernel fd ? */
- if ((!fd_table[fd]->ops) || (fd_table[fd]->ops->use_kfds != 1)) {
- continue;
- }
- switch (fd_table[fd]->type) {
- case FD_HALF_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags);
- fd_table[fd]->type = FD_TEST_HALF_DUPLEX;
- break;
- case FD_FULL_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags);
- fd_table[fd]->type = FD_TEST_FULL_DUPLEX;
- break;
- default:
- break;
- }
- }
- machdep_sys_exit(status);
-}
-
diff --git a/mit-pthreads/pthreads/cleanup.c b/mit-pthreads/pthreads/cleanup.c
deleted file mode 100644
index 3eb096b8337..00000000000
--- a/mit-pthreads/pthreads/cleanup.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ==== cleanup.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread attribute functions.
- *
- * 1.20 94/02/13 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* ==========================================================================
- * pthread_cleanup_push()
- */
-int pthread_cleanup_push(void (*routine)(void *), void *routine_arg)
-{
- struct pthread_cleanup *new;
- int ret;
-
- if ((new = (struct pthread_cleanup*)malloc(sizeof(struct pthread_cleanup))))
- {
- new->routine = routine;
- new->routine_arg = routine_arg;
- new->next = pthread_run->cleanup;
-
- pthread_run->cleanup = new;
- ret = OK;
- } else {
- ret = ENOMEM;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_cleanup_pop()
- */
-void pthread_cleanup_pop(int execute)
-{
- struct pthread_cleanup *old;
-
- if ((old = pthread_run->cleanup))
- {
- pthread_run->cleanup = old->next;
- if (execute) {
- old->routine(old->routine_arg);
- }
- free(old);
- }
-}
-
diff --git a/mit-pthreads/pthreads/cond.c b/mit-pthreads/pthreads/cond.c
deleted file mode 100644
index 8dacd0397ce..00000000000
--- a/mit-pthreads/pthreads/cond.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/* ==== cond.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Condition variable functions.
- *
- * 1.00 93/10/28 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <timers.h>
-#include <errno.h>
-
-#ifndef ETIME
-#define ETIME ETIMEDOUT
-#endif
-
-/* ==========================================================================
- * pthread_cond_is_debug()
- *
- * Check that cond is a debug cond and if so returns entry number into
- * array of debug condes.
- */
-static int pthread_cond_debug_count = 0;
-static pthread_cond_t ** pthread_cond_debug_ptrs = NULL;
-static pthread_mutex_t pthread_cond_debug_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static inline int pthread_cond_is_debug(pthread_cond_t * cond)
-{
- int i;
-
- for (i = 0; i < pthread_cond_debug_count; i++) {
- if (pthread_cond_debug_ptrs[i] == cond) {
- return(i);
- }
- }
- return(NOTOK);
-}
-/* ==========================================================================
- * pthread_cond_init()
- *
- * In this implementation I don't need to allocate memory.
- * ENOMEM, EAGAIN should never be returned. Arch that have
- * weird constraints may need special coding.
- */
-int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr)
-{
- enum pthread_condtype type;
-
- /* Only check if attr specifies some mutex type other than fast */
- if ((cond_attr) && (cond_attr->c_type != COND_TYPE_FAST)) {
- if (cond_attr->c_type >= COND_TYPE_MAX) {
- return(EINVAL);
- }
- type = cond_attr->c_type;
- } else {
- type = COND_TYPE_FAST;
- }
-
- switch (type) {
- case COND_TYPE_FAST:
- case COND_TYPE_COUNTING_FAST:
- break;
- case COND_TYPE_DEBUG:
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if (pthread_cond_is_debug(cond) == NOTOK) {
- pthread_cond_t ** new;
-
- if ((new = (pthread_cond_t **)realloc(pthread_cond_debug_ptrs,
- (pthread_cond_debug_count + 1) * (sizeof(void *)))) == NULL) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- return(ENOMEM);
- }
- pthread_cond_debug_ptrs = new;
- pthread_cond_debug_ptrs[pthread_cond_debug_count++] = cond;
- } else {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- return(EBUSY);
- }
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- break;
- case COND_TYPE_STATIC_FAST:
- defualt:
- return(EINVAL);
- break;
- }
-
- /* Set all other paramaters */
- pthread_queue_init(&cond->c_queue);
- cond->c_flags |= COND_FLAGS_INITED;
- cond->c_type = type;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_cond_destroy()
- */
-int pthread_cond_destroy(pthread_cond_t *cond)
-{
- int i;
-
- /* Only check if cond is of type other than fast */
- switch(cond->c_type) {
- case COND_TYPE_FAST:
- case COND_TYPE_COUNTING_FAST:
- break;
- case COND_TYPE_DEBUG:
- if (pthread_queue_get(&(cond->c_queue))) {
- return(EBUSY);
- }
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if ((i = pthread_cond_is_debug(cond)) == NOTOK) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- return(EINVAL);
- }
-
- /* Remove the cond from the list of debug condition variables */
- pthread_cond_debug_ptrs[i] =
- pthread_cond_debug_ptrs[--pthread_cond_debug_count];
- pthread_cond_debug_ptrs[pthread_cond_debug_count] = NULL;
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- break;
- case COND_TYPE_STATIC_FAST:
- default:
- return(EINVAL);
- break;
- }
-
- /* Cleanup cond, others might want to use it. */
- pthread_queue_init(&cond->c_queue);
- cond->c_flags = 0;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_cond_wait()
- */
-int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
-{
- int rval;
-
- pthread_sched_prevent();
- switch (cond->c_type) {
- case COND_TYPE_DEBUG:
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if (pthread_cond_is_debug(cond) == NOTOK) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- pthread_sched_resume();
- return(EINVAL);
- }
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
-
- /*
- * Fast condition variables do not check for any error conditions.
- */
- case COND_TYPE_FAST:
- case COND_TYPE_STATIC_FAST:
- pthread_queue_enq(&cond->c_queue, pthread_run);
- pthread_mutex_unlock(mutex);
-
- pthread_run->data.mutex = mutex;
-
- SET_PF_WAIT_EVENT(pthread_run);
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-
- pthread_run->data.mutex = NULL;
-
- rval = pthread_mutex_lock(mutex);
- return(rval);
- break;
- case COND_TYPE_COUNTING_FAST:
- {
- int count = mutex->m_data.m_count;
-
- pthread_queue_enq(&cond->c_queue, pthread_run);
- pthread_mutex_unlock(mutex);
- mutex->m_data.m_count = 1;
-
- pthread_run->data.mutex = mutex;
-
- SET_PF_WAIT_EVENT(pthread_run);
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-
- pthread_run->data.mutex = NULL;
-
- rval = pthread_mutex_lock(mutex);
- mutex->m_data.m_count = count;
- return(rval);
- break;
- }
- default:
- rval = EINVAL;
- break;
- }
- pthread_sched_resume();
- return(rval);
-}
-
-/* ==========================================================================
- * pthread_cond_timedwait()
- */
-int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
- const struct timespec * abstime)
-{
- struct timespec current_time, new_time;
- int rval = OK;
-
- pthread_sched_prevent();
- machdep_gettimeofday(& current_time);
-
- switch (cond->c_type) {
- case COND_TYPE_DEBUG:
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if (pthread_cond_is_debug(cond) == NOTOK) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- pthread_sched_resume();
- return(EINVAL);
- }
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
-
- /*
- * Fast condition variables do not check for any error conditions.
- */
- case COND_TYPE_FAST:
- case COND_TYPE_STATIC_FAST:
-
- /* Set pthread wakeup time*/
- pthread_run->wakeup_time = *abstime;
-
- /* Install us on the sleep queue */
- sleep_schedule (&current_time, &(pthread_run->wakeup_time));
-
- pthread_queue_enq(&cond->c_queue, pthread_run);
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
- pthread_run->data.mutex = mutex;
-
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_run->data.mutex = NULL;
-
- /* Remove ourselves from sleep queue. If we fail then we timedout */
- if (sleep_cancel(pthread_run) == NOTOK) {
- SET_ERRNO(ETIME);
- rval = ETIME;
- }
-
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_mutex_lock(mutex);
- return(rval);
- break;
- case COND_TYPE_COUNTING_FAST:
- {
- int count = mutex->m_data.m_count;
-
- /* Set pthread wakeup time*/
- pthread_run->wakeup_time = *abstime;
-
- /* Install us on the sleep queue */
- sleep_schedule (&current_time, &(pthread_run->wakeup_time));
-
- pthread_queue_enq(&cond->c_queue, pthread_run);
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
- pthread_run->data.mutex = mutex;
-
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_COND_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_run->data.mutex = NULL;
-
- /* Remove ourselves from sleep queue. If we fail then we timedout */
- if (sleep_cancel(pthread_run) == NOTOK) {
- SET_ERRNO(ETIME);
- rval = ETIME;
- }
-
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_mutex_lock(mutex);
- mutex->m_data.m_count = count;
- return(rval);
- break;
- }
- default:
- rval = EINVAL;
- break;
- }
- pthread_sched_resume();
- return(rval);
-}
-
-/* ==========================================================================
- * pthread_cond_signal()
- */
-int pthread_cond_signal(pthread_cond_t *cond)
-{
- struct pthread *pthread;
- int rval;
-
- pthread_sched_prevent();
- switch (cond->c_type) {
- case COND_TYPE_DEBUG:
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if (pthread_cond_is_debug(cond) == NOTOK) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- pthread_sched_resume();
- return(EINVAL);
- }
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
-
- case COND_TYPE_FAST:
- case COND_TYPE_STATIC_FAST:
- if (pthread = pthread_queue_deq(&cond->c_queue)) {
- if ((SET_PF_DONE_EVENT(pthread)) == OK) {
- pthread_sched_other_resume(pthread);
- } else {
- pthread_sched_resume();
- }
- return(OK);
- }
- rval = OK;
- break;
- default:
- rval = EINVAL;
- break;
- }
- pthread_sched_resume();
- return(rval);
-}
-
-/* ==========================================================================
- * pthread_cond_broadcast()
- *
- * Not much different then the above routine.
- */
-int pthread_cond_broadcast(pthread_cond_t *cond)
-{
- struct pthread * pthread, * high_pthread, * low_pthread;
- int rval;
-
- pthread_sched_prevent();
- switch (cond->c_type) {
- case COND_TYPE_DEBUG:
- pthread_mutex_lock(&pthread_cond_debug_mutex);
- if (pthread_cond_is_debug(cond) == NOTOK) {
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
- pthread_sched_resume();
- return(EINVAL);
- }
- pthread_mutex_unlock(&pthread_cond_debug_mutex);
-
- case COND_TYPE_FAST:
- case COND_TYPE_STATIC_FAST:
- if (pthread = pthread_queue_deq(&cond->c_queue)) {
- pthread->state = PS_RUNNING;
- high_pthread = pthread;
-
- while (pthread = pthread_queue_deq(&cond->c_queue)) {
- if (pthread->pthread_priority >
- high_pthread->pthread_priority) {
- low_pthread = high_pthread;
- high_pthread = pthread;
- } else {
- low_pthread = pthread;
- }
- if ((SET_PF_DONE_EVENT(low_pthread)) == OK) {
- pthread_prio_queue_enq(pthread_current_prio_queue,
- low_pthread);
- low_pthread->state = PS_RUNNING;
- }
- }
- if ((SET_PF_DONE_EVENT(high_pthread)) == OK) {
- pthread_sched_other_resume(high_pthread);
- } else {
- pthread_sched_resume();
- }
- return(OK);
- }
- rval = OK;
- break;
- default:
- rval = EINVAL;
- break;
- }
- pthread_sched_resume();
- return(rval);
-}
-
diff --git a/mit-pthreads/pthreads/condattr.c b/mit-pthreads/pthreads/condattr.c
deleted file mode 100644
index ac010bdf4b1..00000000000
--- a/mit-pthreads/pthreads/condattr.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* ==== condattr.c ===========================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Mutex functions.
- *
- * 1.00 95/08/22 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-
-/* ==========================================================================
- * pthread_condattr_init()
- */
-int pthread_condattr_init(pthread_condattr_t *attr)
-{
- attr->c_type = COND_TYPE_FAST;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_condattr_destroy()
- */
-int pthread_condattr_destroy(pthread_condattr_t *attr)
-{
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_condattr_settype()
- */
-int pthread_condattr_settype(pthread_condattr_t *attr, unsigned int type)
-{
- switch(type) {
- case PTHREAD_CONDTYPE_FAST:
- attr->c_type = COND_TYPE_FAST;
- break;
- case PTHREAD_CONDTYPE_RECURSIVE:
- attr->c_type = COND_TYPE_COUNTING_FAST;
- break;
- case PTHREAD_CONDTYPE_DEBUG:
- attr->c_type = COND_TYPE_DEBUG;
- break;
- default:
- return(EINVAL);
- }
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_condattr_gettype()
- */
-int pthread_condattr_gettype(pthread_condattr_t *attr, unsigned int * type)
-{
- *type = (unsigned int)attr->c_type;
- return(OK);
-}
diff --git a/mit-pthreads/pthreads/dump_state.c b/mit-pthreads/pthreads/dump_state.c
deleted file mode 100644
index 3d9840bad64..00000000000
--- a/mit-pthreads/pthreads/dump_state.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* ==== dump_state.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- *
- * Description : Bogus debugging output routines.
- *
- * 1.00 95/02/08 snl
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * pthread_dump_state()
- *
- * Totally, totally bogus routine to dump the state of pthreads.
- */
-
-void
-pthread_dump_state()
-{
- pthread_t thread;
-
- for (thread = pthread_link_list; thread; thread = thread->pll) {
- printf("Thread %lx", thread);
- if (thread == pthread_initial)
- printf("*");
- if (thread == pthread_run)
- printf("^");
- printf(" ");
- switch (thread->state) {
- case PS_RUNNING: printf("RUNNING "); break;
- case PS_MUTEX_WAIT: printf("MUTEX_WAIT "); break;
- case PS_COND_WAIT: printf("COND_WAIT "); break;
- case PS_FDLR_WAIT: printf("FDLR_WAIT "); break;
- case PS_FDLW_WAIT: printf("FDLW_WAIT "); break;
- case PS_FDR_WAIT: printf("FDR_WAIT "); break;
- case PS_FDW_WAIT: printf("FDW_WAIT "); break;
- case PS_SELECT_WAIT: printf("SELECT "); break;
- case PS_SLEEP_WAIT: printf("SLEEP_WAIT "); break;
- case PS_WAIT_WAIT: printf("WAIT_WAIT "); break;
- case PS_SIGWAIT: printf("SIGWAIT "); break;
- case PS_JOIN: printf("JOIN "); break;
- case PS_DEAD: printf("DEAD "); break;
- default: printf("*UNKNOWN %d* ", thread->state);
- break;
- }
- switch (thread->attr.schedparam_policy) {
- case SCHED_RR: printf("RR "); break;
- case SCHED_IO: printf("IO "); break;
- case SCHED_FIFO: printf("FIFO "); break;
- case SCHED_OTHER: printf("OTHER "); break;
- default: printf("*UNKNOWN %d* ",
- thread->attr.schedparam_policy);
- break;
- }
- }
-}
diff --git a/mit-pthreads/pthreads/errno.c b/mit-pthreads/pthreads/errno.c
deleted file mode 100644
index bc680235424..00000000000
--- a/mit-pthreads/pthreads/errno.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ==== errno.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Return the pointer to the threads errno address.
- *
- * 1.32 94/05/25 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/* ==========================================================================
- * __error()
- */
-int * __error()
-{
- if (!pthread_run->error_p) {
- pthread_run->error_p = &pthread_run->error;
- }
- return(pthread_run->error_p);
-}
diff --git a/mit-pthreads/pthreads/fd.c b/mit-pthreads/pthreads/fd.c
deleted file mode 100644
index 3eb59c11bd1..00000000000
--- a/mit-pthreads/pthreads/fd.c
+++ /dev/null
@@ -1,1083 +0,0 @@
-/* ==== fd.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : All the syscalls dealing with fds.
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <sys/ioctl.h>
-#ifdef HAVE_SYS_FILIO_H
-#include <sys/filio.h> /* For ioctl */
-#endif
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread/posix.h>
-
-/*
- * These first functions really should not be called by the user.
- *
- * I really should dynamically figure out what the table size is.
- */
-static pthread_mutex_t fd_table_mutex = PTHREAD_MUTEX_INITIALIZER;
-static const int dtablecount = 4096/sizeof(struct fd_table_entry);
-int dtablesize;
-
-static int fd_get_pthread_fd_from_kernel_fd( int );
-
-/* ==========================================================================
- * Allocate dtablecount entries at once and populate the fd_table.
- *
- * fd_init_entry()
- */
-int fd_init_entry(int entry)
-{
- struct fd_table_entry *fd_entry;
- int i, round;
-
- if (fd_table[entry] == NULL) {
- round = entry - entry % dtablecount;
-
- if ((fd_entry = (struct fd_table_entry *)malloc(
- sizeof(struct fd_table_entry) * dtablecount)) == NULL) {
- return(NOTOK);
- }
-
- for (i = 0; i < dtablecount && round+i < dtablesize; i++) {
- fd_table[round + i] = &fd_entry[i];
-
- fd_table[round + i]->ops = NULL;
- fd_table[round + i]->type = FD_NT;
- fd_table[round + i]->fd.i = NOTOK;
- fd_table[round + i]->flags = 0;
- fd_table[round + i]->count = 0;
-
- pthread_mutex_init(&(fd_table[round + i]->mutex), NULL);
- pthread_queue_init(&(fd_table[round + i]->r_queue));
- pthread_queue_init(&(fd_table[round + i]->w_queue));
- fd_table[round + i]->r_owner = NULL;
- fd_table[round + i]->w_owner = NULL;
- fd_table[round + i]->r_lockcount= 0;
- fd_table[round + i]->w_lockcount= 0;
-
- fd_table[round + i]->next = NULL;
- }
- }
- return(OK);
-}
-
-/* ==========================================================================
- * fd_check_entry()
- */
-int fd_check_entry(unsigned int entry)
-{
- int ret = OK;
-
- pthread_mutex_lock(&fd_table_mutex);
-
- if (entry < dtablesize) {
- if (fd_table[entry] == NULL) {
- if (fd_init_entry(entry)) {
- SET_ERRNO(EBADF);
- ret = -EBADF;
- }
- }
- } else {
- SET_ERRNO(EBADF);
- ret = -EBADF;
- }
-
- pthread_mutex_unlock(&fd_table_mutex);
- return(ret);
-}
-
-/* ==========================================================================
- * fd_init()
- */
-void fd_init(void)
-{
- int i;
-
- if ((dtablesize = machdep_sys_getdtablesize()) < 0) {
- /* Can't figure out the table size. */
- PANIC();
- }
-
- /* select() can only handle FD_SETSIZE descriptors, so our inner loop will
- * break if dtablesize is higher than that. This should be removed if and
- * when the inner loop is rewritten to use poll(). */
- if (dtablesize > FD_SETSIZE) {
- dtablesize = FD_SETSIZE;
- }
-
- if (fd_table = (struct fd_table_entry **)malloc(
- sizeof(struct fd_table_entry) * dtablesize)) {
- memset(fd_table, 0, sizeof(struct fd_table_entry) * dtablesize);
- if (fd_check_entry(0) == OK) {
- return;
- }
- }
-
- /*
- * There isn't enough memory to allocate a fd table at init time.
- * This is a problem.
- */
- PANIC();
-
-}
-
-/* ==========================================================================
- * fd_allocate()
- */
-int fd_allocate()
-{
- pthread_mutex_t * mutex;
- int i;
-
- for (i = 0; i < dtablesize; i++) {
- if (fd_check_entry(i) == OK) {
- mutex = &(fd_table[i]->mutex);
- if (pthread_mutex_trylock(mutex)) {
- continue;
- }
- if (fd_table[i]->count || fd_table[i]->r_owner
- || fd_table[i]->w_owner) {
- pthread_mutex_unlock(mutex);
- continue;
- }
- if (fd_table[i]->type == FD_NT) {
- /* Test to see if the kernel version is in use */
- if ((machdep_sys_fcntl(i, F_GETFL, NULL)) >= OK) {
- /* If so continue; */
- pthread_mutex_unlock(mutex);
- continue;
- }
- }
- fd_table[i]->count++;
- pthread_mutex_unlock(mutex);
- return(i);
- }
- }
- SET_ERRNO(ENFILE);
- return(NOTOK);
-}
-
-/*----------------------------------------------------------------------
- * Function: fd_get_pthread_fd_from_kernel_fd
- * Purpose: get the fd_table index of a kernel fd
- * Args: fd = kernel fd to convert
- * Returns: fd_table index, -1 if not found
- * Notes:
- *----------------------------------------------------------------------*/
-static int
-fd_get_pthread_fd_from_kernel_fd( int kfd )
-{
- int j;
-
- /* This is *SICK*, but unless there is a faster way to
- * turn a kernel fd into an fd_table index, this has to do.
- */
- for( j=0; j < dtablesize; j++ ) {
- if( fd_table[j] &&
- fd_table[j]->type != FD_NT &&
- fd_table[j]->type != FD_NIU &&
- fd_table[j]->fd.i == kfd ) {
- return j;
- }
- }
-
- /* Not listed byfd, Check for kernel fd == pthread fd */
- if( fd_table[kfd] == NULL || fd_table[kfd]->type == FD_NT ) {
- /* Assume that the kernel fd is the same */
- return kfd;
- }
-
- return NOTOK; /* Not found */
-}
-
-/* ==========================================================================
- * fd_basic_basic_unlock()
- *
- * The real work of unlock without the locking of fd_table[fd].lock.
- */
-void fd_basic_basic_unlock(struct fd_table_entry * entry, int lock_type)
-{
- struct pthread *pthread;
-
- if (entry->r_owner == pthread_run) {
- if ((entry->type == FD_HALF_DUPLEX) ||
- (entry->type == FD_TEST_HALF_DUPLEX) ||
- (lock_type == FD_READ) || (lock_type == FD_RDWR)) {
- if (entry->r_lockcount == 0) {
- if (pthread = pthread_queue_deq(&entry->r_queue)) {
- pthread_sched_prevent();
- entry->r_owner = pthread;
- if ((SET_PF_DONE_EVENT(pthread)) == OK) {
- pthread_sched_other_resume(pthread);
- } else {
- pthread_sched_resume();
- }
- } else {
- entry->r_owner = NULL;
- }
- } else {
- entry->r_lockcount--;
- }
- }
- }
-
- if (entry->w_owner == pthread_run) {
- if ((entry->type != FD_HALF_DUPLEX) &&
- (entry->type != FD_TEST_HALF_DUPLEX) &&
- ((lock_type == FD_WRITE) || (lock_type == FD_RDWR))) {
- if (entry->w_lockcount == 0) {
- if (pthread = pthread_queue_deq(&entry->w_queue)) {
- pthread_sched_prevent();
- entry->w_owner = pthread;
- if ((SET_PF_DONE_EVENT(pthread)) == OK) {
- pthread_sched_other_resume(pthread);
- } else {
- pthread_sched_resume();
- }
- } else {
- entry->w_owner = NULL;
- }
- } else {
- entry->w_lockcount--;
- }
- }
- }
-}
-
-/* ==========================================================================
- * fd_basic_unlock()
- */
-void fd_basic_unlock(int fd, int lock_type)
-{
- fd_basic_basic_unlock(fd_table[fd], lock_type);
-}
-
-/* ==========================================================================
- * fd_unlock()
- */
-void fd_unlock(int fd, int lock_type)
-{
- pthread_mutex_t *mutex;
-
- mutex = &(fd_table[fd]->mutex);
- pthread_mutex_lock(mutex);
- fd_basic_basic_unlock(fd_table[fd], lock_type);
- pthread_mutex_unlock(mutex);
-}
-
-/* ==========================================================================
- * fd_basic_lock()
- *
- * The real work of lock without the locking of fd_table[fd].lock.
- * Be sure to leave the lock the same way you found it. i.e. locked.
- */
-int fd_basic_lock(unsigned int fd, int lock_type, pthread_mutex_t * mutex,
- struct timespec * timeout)
-{
- semaphore *plock;
-
- switch (fd_table[fd]->type) {
- case FD_NIU:
- /* If not in use return EBADF error */
- SET_ERRNO(EBADF);
- return(NOTOK);
- break;
- case FD_NT:
- /*
- * If not tested, test it and see if it is valid
- * If not ok return EBADF error
- */
- fd_kern_init(fd);
- if (fd_table[fd]->type == FD_NIU) {
- SET_ERRNO(EBADF);
- return(NOTOK);
- }
- break;
- case FD_TEST_HALF_DUPLEX:
- case FD_TEST_FULL_DUPLEX:
- /* If a parent process reset the fd to its proper state */
- if (!fork_lock) {
- /* It had better be a kernel fd */
- fd_kern_reset(fd);
- }
- break;
- default:
- break;
- }
-
- if ((fd_table[fd]->type == FD_HALF_DUPLEX) ||
- (fd_table[fd]->type == FD_TEST_HALF_DUPLEX) ||
- (lock_type == FD_READ) || (lock_type == FD_RDWR)) {
- if (fd_table[fd]->r_owner) {
- if (fd_table[fd]->r_owner != pthread_run) {
- pthread_sched_prevent();
- pthread_queue_enq(&fd_table[fd]->r_queue, pthread_run);
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- /* Reschedule will unlock pthread_run */
- pthread_run->data.fd.fd = fd;
- pthread_run->data.fd.branch = __LINE__;
- pthread_resched_resume(PS_FDLR_WAIT);
- pthread_mutex_lock(mutex);
-
- /* If we're the owner then we have to cancel the sleep */
- if (fd_table[fd]->r_owner != pthread_run) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- SET_ERRNO(ETIMEDOUT);
- return(NOTOK);
- }
- sleep_cancel(pthread_run);
- } else {
- /* Reschedule will unlock pthread_run */
- pthread_run->data.fd.fd = fd;
- pthread_run->data.fd.branch = __LINE__;
- pthread_resched_resume(PS_FDLR_WAIT);
- pthread_mutex_lock(mutex);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- fd_table[fd]->r_lockcount++;
- }
- }
- fd_table[fd]->r_owner = pthread_run;
- }
- if ((fd_table[fd]->type != FD_HALF_DUPLEX) &&
- (fd_table[fd]->type != FD_TEST_HALF_DUPLEX) &&
- ((lock_type == FD_WRITE) || (lock_type == FD_RDWR))) {
- if (fd_table[fd]->w_owner) {
- if (fd_table[fd]->w_owner != pthread_run) {
- pthread_sched_prevent();
- pthread_queue_enq(&fd_table[fd]->w_queue, pthread_run);
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_mutex_unlock(mutex);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- /* Reschedule will unlock pthread_run */
- pthread_run->data.fd.fd = fd;
- pthread_run->data.fd.branch = __LINE__;
- pthread_resched_resume(PS_FDLR_WAIT);
- pthread_mutex_lock(mutex);
-
- /* If we're the owner then we have to cancel the sleep */
- if (fd_table[fd]->w_owner != pthread_run) {
- if (lock_type == FD_RDWR) {
- /* Unlock current thread */
- fd_basic_unlock(fd, FD_READ);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- SET_ERRNO(ETIMEDOUT);
- return(NOTOK);
- }
- sleep_cancel(pthread_run);
- } else {
- /* Reschedule will unlock pthread_run */
- pthread_run->data.fd.fd = fd;
- pthread_run->data.fd.branch = __LINE__;
- pthread_resched_resume(PS_FDLR_WAIT);
- pthread_mutex_lock(mutex);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- fd_table[fd]->w_lockcount++;
- }
- }
- fd_table[fd]->w_owner = pthread_run;
- }
- if (!fd_table[fd]->count) {
- fd_basic_unlock(fd, lock_type);
- return(NOTOK);
- }
- return(OK);
-}
-
-/*----------------------------------------------------------------------
- * Function: fd_unlock_for_cancel
- * Purpose: Unlock all fd locks held prior to being cancelled
- * Args: void
- * Returns:
- * OK or NOTOK
- * Notes:
- * Assumes the kernel is locked on entry
- *----------------------------------------------------------------------*/
-int
-fd_unlock_for_cancel( void )
-{
- int i, fd;
- struct pthread_select_data *data;
- int rdlk, wrlk, lktype;
- int found;
-
- /* What we do depends on the previous state of the thread */
- switch( pthread_run->old_state ) {
- case PS_RUNNING:
- case PS_JOIN:
- case PS_SLEEP_WAIT:
- case PS_WAIT_WAIT:
- case PS_SIGWAIT:
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_DEAD:
- case PS_UNALLOCED:
- break; /* Nothing to do */
-
- case PS_COND_WAIT:
- CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP );
- /* Must reaquire the mutex according to the standard */
- if( pthread_run->data.mutex == NULL ) {
- PANIC();
- }
- pthread_mutex_lock( pthread_run->data.mutex );
- break;
-
- case PS_FDR_WAIT:
- CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
- /* Free the lock on the fd being used */
- fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd );
- if( fd == NOTOK ) {
- PANIC(); /* Can't find fd */
- }
- fd_unlock( fd, FD_READ );
- break;
-
- case PS_FDW_WAIT: /* Waiting on i/o */
- CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
- /* Free the lock on the fd being used */
- fd = fd_get_pthread_fd_from_kernel_fd( pthread_run->data.fd.fd );
- if( fd == NOTOK ) {
- PANIC(); /* Can't find fd */
- }
- fd_unlock( fd, FD_WRITE );
- break;
-
- case PS_SELECT_WAIT:
- data = pthread_run->data.select_data;
-
- CLEAR_PF_GROUP( pthread_run, PF_EVENT_GROUP);
-
- for( i = 0; i < data->nfds; i++) {
- rdlk =(FD_ISSET(i,&data->readfds)
- || FD_ISSET(i,&data->exceptfds));
- wrlk = FD_ISSET(i, &data->writefds);
- lktype = rdlk ? (wrlk ? FD_RDWR : FD_READ) : FD_WRITE;
-
- if( ! (rdlk || wrlk) )
- continue; /* No locks, no unlock */
-
- if( (fd = fd_get_pthread_fd_from_kernel_fd( i )) == NOTOK ) {
- PANIC(); /* Can't find fd */
- }
-
- fd_unlock( fd, lktype );
- }
- break;
-
- case PS_MUTEX_WAIT:
- PANIC(); /* Should never cancel a mutex wait */
-
- default:
- PANIC(); /* Unknown thread status */
- }
-}
-
-/* ==========================================================================
- * fd_lock()
- */
-#define pthread_mutex_lock_timedwait(a, b) pthread_mutex_lock(a)
-
-int fd_lock(unsigned int fd, int lock_type, struct timespec * timeout)
-{
- struct timespec current_time;
- pthread_mutex_t *mutex;
- int error;
-
- if ((error = fd_check_entry(fd)) == OK) {
- mutex = &(fd_table[fd]->mutex);
- if (pthread_mutex_lock_timedwait(mutex, timeout)) {
- SET_ERRNO(ETIMEDOUT);
- return(-ETIMEDOUT);
- }
- error = fd_basic_lock(fd, lock_type, mutex, timeout);
- pthread_mutex_unlock(mutex);
- }
- return(error);
-}
-
-/* ==========================================================================
- * fd_free()
- *
- * Assumes fd is locked and owner by pthread_run
- * Don't clear the queues, fd_unlock will do that.
- */
-struct fd_table_entry * fd_free(int fd)
-{
- struct fd_table_entry *fd_valid;
-
- fd_valid = NULL;
- fd_table[fd]->r_lockcount = 0;
- fd_table[fd]->w_lockcount = 0;
- if (--fd_table[fd]->count) {
- fd_valid = fd_table[fd];
- fd_table[fd] = fd_table[fd]->next;
- fd_valid->next = fd_table[fd]->next;
- /* Don't touch queues of fd_valid */
- }
-
- fd_table[fd]->type = FD_NIU;
- fd_table[fd]->fd.i = NOTOK;
- fd_table[fd]->next = NULL;
- fd_table[fd]->flags = 0;
- fd_table[fd]->count = 0;
- return(fd_valid);
-}
-
-
-/* ==========================================================================
- * ======================================================================= */
-
-/* ==========================================================================
- * read_timedwait()
- */
-ssize_t read_timedwait(int fd, void *buf, size_t nbytes,
- struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- ret = fd_table[fd]->ops->read(fd_table[fd]->fd,
- fd_table[fd]->flags, buf, nbytes, timeout);
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * read()
- */
-ssize_t read(int fd, void *buf, size_t nbytes)
-{
- return(read_timedwait(fd, buf, nbytes, NULL));
-}
-
-/* ==========================================================================
- * readv_timedwait()
- */
-int readv_timedwait(int fd, const struct iovec *iov, int iovcnt,
- struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- ret = fd_table[fd]->ops->readv(fd_table[fd]->fd,
- fd_table[fd]->flags, iov, iovcnt, timeout);
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * readv()
- */
-ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
-{
- return(readv_timedwait(fd, iov, iovcnt, NULL));
-}
-
-/* ==========================================================================
- * write()
- */
-ssize_t write_timedwait(int fd, const void *buf, size_t nbytes,
- struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK)
- {
- ret = fd_table[fd]->ops->write(fd_table[fd]->fd,
- fd_table[fd]->flags, buf, nbytes,
- timeout);
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * write()
- */
-ssize_t write(int fd, const void * buf, size_t nbytes)
-{
- return(write_timedwait(fd, buf, nbytes, NULL));
-}
-
-/* ==========================================================================
- * writev_timedwait()
- */
-int writev_timedwait(int fd, const struct iovec *iov, int iovcnt,
- struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) {
- ret = fd_table[fd]->ops->writev(fd_table[fd]->fd,
- fd_table[fd]->flags, iov, iovcnt, timeout);
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * writev()
- */
-ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
-{
- return(writev_timedwait(fd, iov, iovcnt, NULL));
-}
-
-/* ==========================================================================
- * lseek()
- */
-off_t lseek(int fd, off_t offset, int whence)
-{
- off_t ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- ret = fd_table[fd]->ops->seek(fd_table[fd]->fd,
- fd_table[fd]->flags, offset, whence);
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * close()
- *
- * The whole close procedure is a bit odd and needs a bit of a rethink.
- * For now close() locks the fd, calls fd_free() which checks to see if
- * there are any other fd values poinging to the same real fd. If so
- * It breaks the wait queue into two sections those that are waiting on fd
- * and those waiting on other fd's. Those that are waiting on fd are connected
- * to the fd_table[fd] queue, and the count is set to zero, (BUT THE LOCK IS NOT
- * RELEASED). close() then calls fd_unlock which give the fd to the next queued
- * element which determins that the fd is closed and then calls fd_unlock etc...
- *
- * XXX close() is even uglier now. You may assume that the kernel fd is the
- * same as fd if fd_table[fd] == NULL or if fd_table[fd]->type == FD_NT.
- * This is true because before any fd_table[fd] is allocated the corresponding
- * kernel fd must be checks to see if it's valid.
- */
-int close(int fd)
-{
- struct fd_table_entry * entry;
- pthread_mutex_t *mutex;
- union fd_data realfd;
- int ret, flags;
-
- if(fd < 0 || fd >= dtablesize)
- {
- SET_ERRNO(EBADF);
- return -1;
- }
- /* Need to lock the newfd by hand */
- pthread_mutex_lock(&fd_table_mutex);
- if (fd_table[fd]) {
- pthread_mutex_unlock(&fd_table_mutex);
- mutex = &(fd_table[fd]->mutex);
- pthread_mutex_lock(mutex);
-
- /*
- * XXX Gross hack ... because of fork(), any fd closed by the
- * parent should not change the fd of the child, unless it owns it.
- */
- switch(fd_table[fd]->type) {
- case FD_NIU:
- pthread_mutex_unlock(mutex);
- ret = -EBADF;
- break;
- case FD_NT:
- /*
- * If it's not tested then the only valid possibility is it's
- * kernel fd.
- */
- ret = machdep_sys_close(fd);
- fd_table[fd]->type = FD_NIU;
- pthread_mutex_unlock(mutex);
- break;
- case FD_TEST_FULL_DUPLEX:
- case FD_TEST_HALF_DUPLEX:
- realfd = fd_table[fd]->fd;
- flags = fd_table[fd]->flags;
- if ((entry = fd_free(fd)) == NULL) {
- ret = fd_table[fd]->ops->close(realfd, flags);
- } else {
- /* There can't be any others waiting for fd. */
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
- mutex = &(fd_table[fd]->mutex);
- }
- pthread_mutex_unlock(mutex);
- break;
- default:
- ret = fd_basic_lock(fd, FD_RDWR, mutex, NULL);
- if (ret == OK) {
- realfd = fd_table[fd]->fd;
- flags = fd_table[fd]->flags;
- pthread_mutex_unlock(mutex);
- if ((entry = fd_free(fd)) == NULL) {
- ret = fd_table[fd]->ops->close(realfd, flags);
- } else {
- fd_basic_basic_unlock(entry, FD_RDWR);
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
- }
- fd_unlock(fd, FD_RDWR);
- } else {
- pthread_mutex_unlock(mutex);
- }
- break;
- }
- } else {
- /* Don't bother creating a table entry */
- pthread_mutex_unlock(&fd_table_mutex);
- ret = machdep_sys_close(fd);
- }
- if( ret < 0) {
- SET_ERRNO(-ret);
- ret = -1;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * fd_basic_dup()
- *
- *
- * This is a MAJOR guess!! I don't know if the mutext unlock is valid
- * in the BIG picture. But it seems to be needed to avoid deadlocking
- * with ourselves when we try to close the duped file descriptor.
- */
-static inline void fd_basic_dup(int fd, int newfd)
-{
- fd_table[newfd]->next = fd_table[fd]->next;
- fd_table[fd]->next = fd_table[newfd];
- fd_table[newfd] = fd_table[fd];
- fd_table[fd]->count++;
- pthread_mutex_unlock(&fd_table[newfd]->next->mutex);
-
-}
-
-/* ==========================================================================
- * dup2()
- *
- * Note: Always lock the lower number fd first to avoid deadlocks.
- * Note: Leave the newfd locked. It will be unlocked at close() time.
- * Note: newfd must be locked by hand so it can be closed if it is open,
- * or it won't be opened while dup is in progress.
- */
-int dup2(fd, newfd)
-{
- struct fd_table_entry * entry;
- pthread_mutex_t *mutex;
- union fd_data realfd;
- int ret, flags;
-
- if ((ret = fd_check_entry(newfd)) != OK)
- return ret;
-
- if (newfd < dtablesize) {
- if (fd < newfd) {
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- /* Need to lock the newfd by hand */
- mutex = &(fd_table[newfd]->mutex);
- pthread_mutex_lock(mutex);
-
- /* Is it inuse */
- if (fd_basic_lock(newfd, FD_RDWR, mutex, NULL) == OK) {
- realfd = fd_table[newfd]->fd;
- flags = fd_table[newfd]->flags;
- /* free it and check close status */
- if ((entry = fd_free(newfd)) == NULL) {
- entry = fd_table[newfd];
- entry->ops->close(realfd, flags);
- if (entry->r_queue.q_next) {
- if (fd_table[fd]->next) {
- fd_table[fd]->r_queue.q_last->next =
- entry->r_queue.q_next;
- } else {
- fd_table[fd]->r_queue.q_next =
- entry->r_queue.q_next;
- }
- fd_table[fd]->r_queue.q_last =
- entry->r_queue.q_last;
- }
- if (entry->w_queue.q_next) {
- if (fd_table[fd]->next) {
- fd_table[fd]->w_queue.q_last->next =
- entry->w_queue.q_next;
- } else {
- fd_table[fd]->w_queue.q_next =
- entry->w_queue.q_next;
- }
- fd_table[fd]->w_queue.q_last =
- entry->w_queue.q_last;
- }
- entry->r_queue.q_next = NULL;
- entry->w_queue.q_next = NULL;
- entry->r_queue.q_last = NULL;
- entry->w_queue.q_last = NULL;
- entry->r_owner = NULL;
- entry->w_owner = NULL;
- ret = OK;
- } else {
- fd_basic_basic_unlock(entry, FD_RDWR);
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
- }
- }
- fd_basic_dup(fd, newfd);
- }
- fd_unlock(fd, FD_RDWR);
- } else {
- /* Need to lock the newfd by hand */
- mutex = &(fd_table[newfd]->mutex);
- pthread_mutex_lock(mutex);
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- /* Is newfd inuse */
- if ((ret = fd_basic_lock(newfd, FD_RDWR, mutex, NULL)) == OK) {
- realfd = fd_table[newfd]->fd;
- flags = fd_table[newfd]->flags;
- /* free it and check close status */
- if ((entry = fd_free(newfd)) == NULL) {
- entry = fd_table[newfd];
- entry->ops->close(realfd, flags);
- if (entry->r_queue.q_next) {
- if (fd_table[fd]->next) {
- fd_table[fd]->r_queue.q_last->next =
- entry->r_queue.q_next;
- } else {
- fd_table[fd]->r_queue.q_next =
- entry->r_queue.q_next;
- }
- fd_table[fd]->r_queue.q_last =
- entry->r_queue.q_last;
- }
- if (entry->w_queue.q_next) {
- if (fd_table[fd]->next) {
- fd_table[fd]->w_queue.q_last->next =
- entry->w_queue.q_next;
- } else {
- fd_table[fd]->w_queue.q_next =
- entry->w_queue.q_next;
- }
- fd_table[fd]->w_queue.q_last =
- entry->w_queue.q_last;
- }
- entry->r_queue.q_next = NULL;
- entry->w_queue.q_next = NULL;
- entry->r_queue.q_last = NULL;
- entry->w_queue.q_last = NULL;
- entry->r_owner = NULL;
- entry->w_owner = NULL;
- ret = OK;
- } else {
- fd_basic_basic_unlock(entry, FD_RDWR);
- pthread_mutex_unlock(&entry->mutex);
- /* Note: entry->mutex = mutex */
- }
- fd_basic_dup(fd, newfd);
- }
- fd_unlock(fd, FD_RDWR);
- }
- }
- } else {
- ret = NOTOK;
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * dup()
- */
-int dup(int fd)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- ret = fd_allocate();
- fd_basic_dup(fd, ret);
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * fcntl()
- */
-int fcntl(int fd, int cmd, ...)
-{
- int ret, realfd, flags;
- struct flock *flock;
- semaphore *plock;
- va_list ap;
-
- flags = 0;
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- va_start(ap, cmd);
- switch(cmd) {
- case F_DUPFD:
- ret = fd_allocate();
- fd_basic_dup(va_arg(ap, int), ret);
- break;
- case F_SETFD:
- break;
- case F_GETFD:
- break;
- case F_GETFL:
- ret = fd_table[fd]->flags;
- break;
- case F_SETFL:
- flags = va_arg(ap, int);
- if ((ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd,
- fd_table[fd]->flags, cmd, flags | __FD_NONBLOCK)) == OK) {
- fd_table[fd]->flags = flags;
- }
- break;
-/* case F_SETLKW: */
- /*
- * Do the same as SETLK but if it fails with EACCES or EAGAIN
- * block the thread and try again later, not implemented yet
- */
-/* case F_SETLK: */
-/* case F_GETLK:
- flock = va_arg(ap, struct flock*);
- ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd,
- fd_table[fd]->flags, cmd, flock);
- break; */
- default:
- /* Might want to make va_arg use a union */
- ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd,
- fd_table[fd]->flags, cmd, va_arg(ap, void*));
- break;
- }
- va_end(ap);
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * getdtablesize()
- */
-int getdtablesize()
-{
- return dtablesize;
-}
-
-/* ==========================================================================
- * ioctl()
- *
- * Really want to do a real implementation of this that parses the args ala
- * fcntl(), above, but it will have to be a totally platform-specific,
- * nightmare-on-elm-st-style sort of thing. Might even deserve its own file
- * ala select()... --SNL
- */
-#ifndef ioctl_request_type
-#define ioctl_request_type unsigned long /* Dummy patch by Monty */
-#endif
-
-int
-ioctl(int fd, ioctl_request_type request, ...)
-{
- int ret;
- pthread_va_list ap;
- caddr_t arg;
-
- va_start( ap, request ); /* Get the arg */
- arg = va_arg(ap,caddr_t);
- va_end( ap );
-
- if (fd < 0 || fd >= dtablesize)
- ret = NOTOK;
- else if (fd_table[fd]->fd.i == NOTOK)
- ret = machdep_sys_ioctl(fd, request, arg);
- else if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- ret = machdep_sys_ioctl(fd_table[fd]->fd.i, request, arg);
- if( ret == 0 && request == FIONBIO ) {
- /* Properly set NONBLOCK flag */
- int v = *(int *)arg;
- if( v )
- fd_table[fd]->flags |= __FD_NONBLOCK;
- else
- fd_table[fd]->flags &= ~__FD_NONBLOCK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return ret;
-}
-
diff --git a/mit-pthreads/pthreads/fd_kern.c b/mit-pthreads/pthreads/fd_kern.c
deleted file mode 100644
index f4ada4e4fd4..00000000000
--- a/mit-pthreads/pthreads/fd_kern.c
+++ /dev/null
@@ -1,1950 +0,0 @@
-/* ==== fd_kern.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Deals with the valid kernel fds.
- *
- * 1.00 93/09/27 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-#include <pthread.h>
-#include <unistd.h>
-#include <sys/compat.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread/posix.h>
-#include <string.h>
-
-#if defined (HAVE_SYSCALL_SENDTO) && !defined (HAVE_SYSCALL_SEND)
-
-pthread_ssize_t machdep_sys_send (int fd, const void *msg, size_t len,
- int flags)
-{
- return machdep_sys_sendto (fd, msg, len, flags,
- (const struct sockaddr *) 0, 0);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_RECVFROM) && !defined (HAVE_SYSCALL_RECV)
-
-pthread_ssize_t machdep_sys_recv (int fd, void *buf, size_t len, int flags)
-{
- return machdep_sys_recvfrom (fd, buf, len, flags,
- (struct sockaddr *) 0, (int *) 0);
-}
-
-#endif
-
-/* ==========================================================================
- * Check if there is any signal with must be handled. Added by Monty
- * This could be somewhat system dependent but it should work.
- */
-
-static int fd_check_if_pending_signal(struct pthread *pthread)
-{
- int i;
- unsigned long *pending,*mask;
- if (!pthread->sigcount)
- return 0;
- pending= (unsigned long*) &pthread->sigpending;
- mask= (unsigned long*) &pthread->sigmask;
-
- for (i=0 ; i < sizeof(pthread->sigpending)/sizeof(unsigned long); i++)
- {
- if (*pending && (*mask ^ (unsigned) ~0L))
- return 1;
- pending++;
- mask++;
- }
- return 0;
-}
-
-/* ==========================================================================
- * Variables used by both fd_kern_poll and fd_kern_wait
- */
-struct pthread_queue fd_wait_read = PTHREAD_QUEUE_INITIALIZER;
-struct pthread_queue fd_wait_write = PTHREAD_QUEUE_INITIALIZER;
-struct pthread_queue fd_wait_select = PTHREAD_QUEUE_INITIALIZER;
-
-static struct timeval __fd_kern_poll_timeout = { 0, 0 }; /* Moved by monty */
-extern struct timeval __fd_kern_wait_timeout;
-extern volatile sig_atomic_t sig_to_process;
-
-/*
- * ==========================================================================
- * Do a select if there is someting to wait for.
- * This is to a combination of the old fd_kern_poll() and fd_kern_wait()
- * Return 1 if nothing to do.
- */
-
-static int fd_kern_select(struct timeval *timeout)
-{
- fd_set fd_set_read, fd_set_write, fd_set_except;
- struct pthread *pthread, *deq;
- int count, i;
-
- if (!fd_wait_read.q_next && !fd_wait_write.q_next && !fd_wait_select.q_next)
- return 1; /* Nothing to do */
-
- FD_ZERO(&fd_set_read);
- FD_ZERO(&fd_set_write);
- FD_ZERO(&fd_set_except);
- for (pthread = fd_wait_read.q_next; pthread; pthread = pthread->next)
- FD_SET(pthread->data.fd.fd, &fd_set_read);
- for (pthread = fd_wait_write.q_next; pthread; pthread = pthread->next)
- FD_SET(pthread->data.fd.fd, &fd_set_write);
- for (pthread = fd_wait_select.q_next; pthread; pthread = pthread->next)
- {
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- if (FD_ISSET(i, &pthread->data.select_data->exceptfds))
- FD_SET(i, &fd_set_except);
- if (FD_ISSET(i, &pthread->data.select_data->writefds))
- FD_SET(i, &fd_set_write);
- if (FD_ISSET(i, &pthread->data.select_data->readfds))
- FD_SET(i, &fd_set_read);
- }
- }
-
- /* Turn off interrupts for real while we set the timer. */
-
- if (timeout == &__fd_kern_wait_timeout)
- { /* from fd_kern_wait() */
- sigset_t sig_to_block, oset;
- sigfillset(&sig_to_block);
- machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset);
-
- machdep_unset_thread_timer(NULL);
- __fd_kern_wait_timeout.tv_usec = 0;
- __fd_kern_wait_timeout.tv_sec = (sig_to_process) ? 0 : 3600;
-
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
- }
- /*
- * There is a small but finite chance that an interrupt will
- * occure between the unblock and the select. Because of this
- * sig_handler_real() sets the value of __fd_kern_wait_timeout
- * to zero causing the select to do a poll instead of a wait.
- */
-
- while ((count = machdep_sys_select(dtablesize, &fd_set_read,
- &fd_set_write, &fd_set_except,
- timeout)) < OK)
- {
- if (count == -EINTR)
- return 0;
- PANIC();
- }
-
- for (pthread = fd_wait_read.q_next; pthread; ) {
- if (count && FD_ISSET(pthread->data.fd.fd, &fd_set_read) ||
- fd_check_if_pending_signal(pthread))
- {
- if (FD_ISSET(pthread->data.fd.fd, &fd_set_read))
- count--;
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_read, deq);
- if (SET_PF_DONE_EVENT(deq) == OK) {
- pthread_prio_queue_enq(pthread_current_prio_queue, deq);
- deq->state = PS_RUNNING;
- }
- continue;
- }
- pthread = pthread->next;
- }
-
- for (pthread = fd_wait_write.q_next; pthread; ) {
- if (count && FD_ISSET(pthread->data.fd.fd, &fd_set_write) ||
- fd_check_if_pending_signal(pthread))
- {
- if (FD_ISSET(pthread->data.fd.fd, &fd_set_read))
- count--;
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_write, deq);
- if (SET_PF_DONE_EVENT(deq) == OK) {
- pthread_prio_queue_enq(pthread_current_prio_queue, deq);
- deq->state = PS_RUNNING;
- }
- continue;
- }
- pthread = pthread->next;
- }
-
- for (pthread = fd_wait_select.q_next; pthread; )
- {
- int found_one=0; /* Loop fixed by monty */
- if (count)
- {
- fd_set tmp_readfds, tmp_writefds, tmp_exceptfds;
- memcpy(&tmp_readfds, &pthread->data.select_data->readfds,
- sizeof(fd_set));
- memcpy(&tmp_writefds, &pthread->data.select_data->writefds,
- sizeof(fd_set));
- memcpy(&tmp_exceptfds, &pthread->data.select_data->exceptfds,
- sizeof(fd_set));
-
- for (i = 0; i < pthread->data.select_data->nfds; i++) {
- if (FD_ISSET(i, &tmp_exceptfds))
- {
- if (! FD_ISSET(i, &fd_set_except))
- FD_CLR(i, &tmp_exceptfds);
- else
- found_one=1;
- }
- if (FD_ISSET(i, &tmp_writefds))
- {
- if (! FD_ISSET(i, &fd_set_write))
- FD_CLR(i, &tmp_writefds);
- else
- found_one=1;
- }
- if (FD_ISSET(i, &tmp_readfds))
- {
- if (! FD_ISSET(i, &fd_set_read))
- FD_CLR(i, &tmp_readfds);
- else
- found_one=1;
- }
- }
- if (found_one)
- {
- memcpy(&pthread->data.select_data->readfds, &tmp_readfds,
- sizeof(fd_set));
- memcpy(&pthread->data.select_data->writefds, &tmp_writefds,
- sizeof(fd_set));
- memcpy(&pthread->data.select_data->exceptfds, &tmp_exceptfds,
- sizeof(fd_set));
- }
- }
- if (found_one || fd_check_if_pending_signal(pthread))
- {
- deq = pthread;
- pthread = pthread->next;
- pthread_queue_remove(&fd_wait_select, deq);
- if (SET_PF_DONE_EVENT(deq) == OK) {
- pthread_prio_queue_enq(pthread_current_prio_queue, deq);
- deq->state = PS_RUNNING;
- }
- } else {
- pthread = pthread->next;
- }
- }
- return 0;
-}
-
-
-/* ==========================================================================
- * fd_kern_poll()
- *
- * Called only from context_switch(). The kernel must be locked.
- *
- * This function uses a linked list of waiting pthreads, NOT a queue.
- */
-
-void fd_kern_poll()
-{
- fd_kern_select(&__fd_kern_poll_timeout);
-}
-
-
-/* ==========================================================================
- * fd_kern_wait()
- *
- * Called when there is no active thread to run.
- */
-
-void fd_kern_wait()
-{
- if (fd_kern_select(&__fd_kern_wait_timeout))
- /* No threads, waiting on I/O, do a sigsuspend */
- sig_handler_pause();
-}
-
-
-/* ==========================================================================
- * Special Note: All operations return the errno as a negative of the errno
- * listed in errno.h
- * ======================================================================= */
-
-/* ==========================================================================
- * read()
- */
-pthread_ssize_t __fd_kern_read(union fd_data fd_data, int flags, void *buf,
- size_t nbytes, struct timespec * timeout)
-{
- int fd = fd_data.i;
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_read(fd, buf, nbytes)) < OK) {
- if (!(flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDR_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret= NOTOK;
- break;
- }
- pthread_sched_resume();
- } else {
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDR_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
- } else {
- SET_ERRNO(-ret);
- ret = NOTOK;
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * readv()
- */
-int __fd_kern_readv(union fd_data fd_data, int flags, const struct iovec *iov,
- int iovcnt, struct timespec * timeout)
-{
- int fd = fd_data.i;
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_readv(fd, iov, iovcnt)) < OK) {
- if (!(flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- pthread_run->data.fd.fd = fd;
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDW_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = NOTOK;
- break;
- }
- pthread_sched_resume();
- } else {
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_FDW_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
- } else {
- SET_ERRNO(-ret);
- ret = NOTOK;
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * write()
- */
-pthread_ssize_t __fd_kern_write(union fd_data fd_data, int flags,
- const void *buf, size_t nbytes, struct timespec * timeout)
-{
- int fd = fd_data.i;
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_write(fd, buf, nbytes)) < OK) {
- if (!(flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- pthread_run->data.fd.fd = fd;
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = NOTOK;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
- } else {
- SET_ERRNO(-ret);
- ret = NOTOK;
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * writev()
- */
-int __fd_kern_writev(union fd_data fd_data, int flags, const struct iovec *iov,
- int iovcnt, struct timespec * timeout)
-{
- int fd = fd_data.i;
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_writev(fd, iov, iovcnt)) < OK) {
- if (!(flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- pthread_run->data.fd.fd = fd;
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = NOTOK;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
- } else {
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * For blocking version we really should set an interrupt
- * fcntl()
- */
-int __fd_kern_fcntl(union fd_data fd_data, int flags, int cmd, int arg)
-{
- int fd = fd_data.i;
-
- return(machdep_sys_fcntl(fd, cmd, arg));
-}
-
-/* ==========================================================================
- * close()
- */
-int __fd_kern_close(union fd_data fd_data, int flags)
-{
- int fd = fd_data.i;
-
- return(machdep_sys_close(fd));
-}
-
-/* ==========================================================================
- * lseek()
- * Assume that error number is in the range 0- 255 to get bigger
- * range of seek. ; Monty
- */
-off_t __fd_kern_lseek(union fd_data fd_data, int f, off_t offset, int whence)
-{
- int fd = fd_data.i;
- extern off_t machdep_sys_lseek(int, off_t, int);
- off_t ret=machdep_sys_lseek(fd, offset, whence);
- if ((long) ret < 0L && (long) ret >= -255L)
- {
- SET_ERRNO(ret);
- ret= NOTOK;
- }
- return ret;
-}
-
-/*
- * File descriptor operations
- */
-extern machdep_sys_close();
-
-/* Normal file operations */
-static struct fd_ops __fd_kern_ops = {
- __fd_kern_write, __fd_kern_read, __fd_kern_close, __fd_kern_fcntl,
- __fd_kern_writev, __fd_kern_readv, __fd_kern_lseek, 1
-};
-
-/* NFS file opperations */
-
-/* FIFO file opperations */
-
-/* Device operations */
-
-/* ==========================================================================
- * open()
- *
- * Because open could potentially block opening a file from a remote
- * system, we want to make sure the call will timeout. We then try and open
- * the file, and stat the file to determine what operations we should
- * associate with the fd.
- *
- * This is not done yet
- *
- * A regular file on the local system needs no special treatment.
- */
-int open(const char *path, int flags, ...)
-{
- int fd, mode, fd_kern;
- struct stat stat_buf;
- va_list ap;
-
- /* If pthread scheduling == FIFO set a virtual timer */
- if (flags & O_CREAT) {
- va_start(ap, flags);
- mode = va_arg(ap, int);
- va_end(ap);
- } else {
- mode = 0;
- }
-
- if (!((fd = fd_allocate()) < OK)) {
- fd_table[fd]->flags = flags;
- flags |= __FD_NONBLOCK;
-
- if (!((fd_kern = machdep_sys_open(path, flags, mode)) < OK)) {
-
- /* fstat the file to determine what type it is */
- if (machdep_sys_fstat(fd_kern, &stat_buf)) {
- PANIC();
- }
- if (S_ISREG(stat_buf.st_mode)) {
- fd_table[fd]->ops = &(__fd_kern_ops);
- fd_table[fd]->type = FD_HALF_DUPLEX;
- } else {
- fd_table[fd]->ops = &(__fd_kern_ops);
- fd_table[fd]->type = FD_FULL_DUPLEX;
- }
- fd_table[fd]->fd.i = fd_kern;
- return(fd);
- }
-
- fd_table[fd]->count = 0;
- SET_ERRNO(-fd_kern);
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * create()
- */
-int create(const char *path, mode_t mode)
-{
- return creat (path, mode);
-}
-
-/* ==========================================================================
- * creat()
- */
-#undef creat
-
-int creat(const char *path, mode_t mode)
-{
- return open (path, O_CREAT | O_TRUNC | O_WRONLY, mode);
-}
-
-/* ==========================================================================
- * fchown()
- */
-int fchown(int fd, uid_t owner, gid_t group)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) {
- if ((ret = machdep_sys_fchown(fd_table[fd]->fd.i, owner, group)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * fchmod()
- */
-int fchmod(int fd, mode_t mode)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) {
- if ((ret = machdep_sys_fchmod(fd_table[fd]->fd.i, mode)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * ftruncate()
- */
-int ftruncate(int fd, off_t length)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) {
- if ((ret = machdep_sys_ftruncate(fd_table[fd]->fd.i, length)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-#if defined (HAVE_SYSCALL_FLOCK)
-/* ==========================================================================
- * flock()
- *
- * Added (mevans)
- */
-int flock(int fd, int operation)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_flock(fd_table[fd]->fd.i,
- operation)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-#endif
-
-/* ==========================================================================
- * pipe()
- */
-int pipe(int fds[2])
-{
- int kfds[2];
- int ret;
-
- if ((fds[0] = fd_allocate()) >= OK) {
- if ((fds[1] = fd_allocate()) >= OK) {
- if ((ret = machdep_sys_pipe(kfds)) >= OK) {
- fd_table[fds[0]]->flags = machdep_sys_fcntl(kfds[0], F_GETFL, NULL);
- machdep_sys_fcntl(kfds[0], F_SETFL, fd_table[fds[0]]->flags | __FD_NONBLOCK);
- fd_table[fds[1]]->flags = machdep_sys_fcntl(kfds[1], F_GETFL, NULL);
- machdep_sys_fcntl(kfds[1], F_SETFL, fd_table[fds[1]]->flags | __FD_NONBLOCK);
-
- fd_table[fds[0]]->ops = &(__fd_kern_ops);
- fd_table[fds[1]]->ops = &(__fd_kern_ops);
-
- /* Not really full duplex but ... */
- fd_table[fds[0]]->type = FD_FULL_DUPLEX;
- fd_table[fds[1]]->type = FD_FULL_DUPLEX;
-
- fd_table[fds[0]]->fd.i = kfds[0];
- fd_table[fds[1]]->fd.i = kfds[1];
-
- return(OK);
- } else {
- SET_ERRNO(-ret);
- }
- fd_table[fds[1]]->count = 0;
- }
- fd_table[fds[0]]->count = 0;
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * fd_kern_reset()
- * Change the fcntl blocking flag back to NONBLOCKING. This should only
- * be called after a fork.
- */
-void fd_kern_reset(int fd)
-{
- switch (fd_table[fd]->type) {
- case FD_TEST_HALF_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL,
- fd_table[fd]->flags | __FD_NONBLOCK);
- fd_table[fd]->type = FD_HALF_DUPLEX;
- break;
- case FD_TEST_FULL_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL,
- fd_table[fd]->flags | __FD_NONBLOCK);
- fd_table[fd]->type = FD_FULL_DUPLEX;
- break;
- default:
- break;
- }
-}
-
-/* ==========================================================================
- * fd_kern_init()
- *
- * Assume the entry is locked before routine is invoked
- *
- * This may change. The problem is setting the fd to nonblocking changes
- * the parents fd too, which may not be the desired result.
- *
- * New added feature: If the fd in question is a tty then we open it again
- * and close the original, this way we don't have to worry about the
- * fd being NONBLOCKING to the outside world.
- */
-void fd_kern_init(int fd)
-{
- if ((fd_table[fd]->flags = machdep_sys_fcntl(fd, F_GETFL, NULL)) >= OK) {
- if (isatty_basic(fd)) {
- int new_fd;
-
- if ((new_fd = machdep_sys_open(__ttyname_basic(fd), O_RDWR)) >= OK){
- if (machdep_sys_dup2(new_fd, fd) == OK) {
- /* Should print a warning */
-
- /* Should also set the flags to that of opened outside of
- process */
- }
- machdep_sys_close(new_fd);
- }
- }
- /* We do these things regaurdless of the above results */
- machdep_sys_fcntl(fd, F_SETFL, fd_table[fd]->flags | __FD_NONBLOCK);
- fd_table[fd]->ops = &(__fd_kern_ops);
- fd_table[fd]->type = FD_HALF_DUPLEX;
- fd_table[fd]->fd.i = fd;
- fd_table[fd]->count = 1;
-
- }
-}
-
-/* ==========================================================================
- * fd_kern_gettableentry()
- *
- * Remember only return a a file descriptor that I will modify later.
- * Don't return file descriptors that aren't owned by the child, or don't
- * have kernel operations.
- */
-static int fd_kern_gettableentry(const int child, int fd)
-{
- int i;
-
- for (i = 0; i < dtablesize; i++) {
- if (fd_table[i]) {
- if (fd_table[i]->fd.i == fd) {
- if (child) {
- if ((fd_table[i]->type != FD_TEST_HALF_DUPLEX) &&
- (fd_table[i]->type != FD_TEST_FULL_DUPLEX)) {
- continue;
- }
- } else {
- if ((fd_table[i]->type == FD_NT) ||
- (fd_table[i]->type == FD_NIU)) {
- continue;
- }
- }
- /* Is it a kernel fd ? */
- if ((!fd_table[i]->ops) ||
- (fd_table[i]->ops->use_kfds != 1)) {
- continue;
- }
- return(i);
- }
- }
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * fd_kern_exec()
- *
- * Fixup the fd_table such that (fd == fd_table[fd]->fd.i) this way
- * the new immage will be OK.
- *
- * Only touch those that won't be used by the parent if we're in a child
- * otherwise fixup all.
- *
- * Returns:
- * 0 no fixup necessary
- * 1 fixup without problems
- * 2 failed fixup on some descriptors, and clobbered them.
- */
-int fd_kern_exec(const int child)
-{
- int ret = 0;
- int fd, i;
-
- for (fd = 0; fd < dtablesize; fd++) {
- if (fd_table[fd] == NULL) {
- continue;
- }
- /* Is the fd already in use ? */
- if (child) {
- if ((fd_table[fd]->type != FD_TEST_HALF_DUPLEX) &&
- (fd_table[fd]->type != FD_TEST_FULL_DUPLEX)) {
- continue;
- }
- } else {
- if ((fd_table[fd]->type == FD_NT) ||
- (fd_table[fd]->type == FD_NIU)) {
- continue;
- }
- }
- /* Is it a kernel fd ? */
- if ((!fd_table[fd]->ops) ||
- (fd_table[fd]->ops->use_kfds != 1)) {
- continue;
- }
- /* Does it match ? */
- if (fd_table[fd]->fd.i == fd) {
- continue;
- }
- /* OK, fixup entry: Read comments before changing. This isn't obvious */
-
- /* i is the real file descriptor fd currently represents */
- if (((i = fd_table[fd]->fd.i) >= dtablesize) || (i < 0)) {
- /* This should never happen */
- PANIC();
- }
-
- /*
- * if the real file descriptor with the same number as the fake file
- * descriptor number fd is actually in use by the program, we have
- * to move it out of the way
- */
- if ((machdep_sys_fcntl(fd, F_GETFL, NULL)) >= OK) {
- /* fd is busy */
- int j;
-
- /*
- * j is the fake file descriptor that represents the real file
- * descriptor that we want to move. This way the fake file
- * descriptor fd can move its real file descriptor i such that
- * fd == i.
- */
- if ((j = fd_kern_gettableentry(child, fd)) >= OK) {
-
- /*
- * Since j represents a fake file descriptor and fd represents
- * a fake file descriptor. If j < fd then a previous pass
- * should have set fd_table[j]->fd.i == j.
- */
- if (fd < j) {
- if ((fd_table[j]->fd.i = machdep_sys_dup(fd)) < OK) {
- /* Close j, there is nothing else we can do */
- fd_table[j]->type = FD_NIU;
- ret = 2;
- }
- } else {
- /* This implies fd_table[j]->fd.i != j */
- PANIC();
- }
- }
- }
-
- /*
- * Here the real file descriptor i is set to equel the fake file
- * descriptor fd
- */
- machdep_sys_dup2(i, fd);
-
- /*
- * Now comes the really complicated part: UNDERSTAND before changing
- *
- * Here are the things this routine wants to do ...
- *
- * Case 1. The real file descriptor has only one fake file descriptor
- * representing it.
- * fd -> i, fd != i ===> fd -> fd, close(i)
- * Example fd = 4, i = 2: then close(2), set fd -> i = 4
- *
- * Case 2. The real file descriptor has more than one fake file
- * descriptor representing it, and this is the first fake file
- * descriptor representing the real file descriptor
- * fd -> i, fd' -> i, fd != i ===> fd -> fd, fd' -> fd, close(i)
- *
- * The problem is achiving the above is very messy and difficult,
- * but I should be able to take a short cut. If fd > i then there
- * will be no need to ever move i, this is because the fake file
- * descriptor foo that we would have wanted to represent the real
- * file descriptor i has already been processed. If fd < i then by
- * moving i to fd all subsequent fake file descriptors fd' should fall
- * into the previous case and won't need aditional adjusting.
- *
- * Does this break the above fd < j check .... It shouldn't because j
- * is a fake file descriptor and if j < fd then j has already moved
- * its real file descriptor foo such that foo <= j therefore foo < fd
- * and not foo == fd therefor j cannot represent the real
- * filedescriptor that fd want to move to and be less than fd
- */
- if (fd < i) {
- fd_table[fd]->fd.i = fd;
- machdep_sys_close(i);
- }
- if (ret < 1) {
- ret = 1;
- }
- }
-}
-
-/* ==========================================================================
- * fd_kern_fork()
- */
-void fd_kern_fork()
-{
- pthread_mutex_t *mutex;
- int fd;
-
- for (fd = 0; fd < dtablesize; fd++) {
- if (fd_table[fd] == NULL) {
- continue;
- }
- mutex = & (fd_table[fd]->mutex);
- if (pthread_mutex_trylock(mutex)) {
- continue;
- }
- if ((fd_table[fd]->r_owner) || (fd_table[fd]->w_owner)) {
- pthread_mutex_unlock(mutex);
- continue;
- }
- /* Is it a kernel fd ? */
- if ((!fd_table[fd]->ops) || (fd_table[fd]->ops->use_kfds != 1)) {
- pthread_mutex_unlock(mutex);
- continue;
- }
- switch (fd_table[fd]->type) {
- case FD_HALF_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags);
- fd_table[fd]->type = FD_TEST_HALF_DUPLEX;
- break;
- case FD_FULL_DUPLEX:
- machdep_sys_fcntl(fd_table[fd]->fd.i, F_SETFL, fd_table[fd]->flags);
- fd_table[fd]->type = FD_TEST_FULL_DUPLEX;
- break;
- default:
- break;
- }
- pthread_mutex_unlock(mutex);
- }
-}
-
-/* ==========================================================================
- * Here are the berkeley socket functions. These are not POSIX.
- * ======================================================================= */
-
-#if defined (HAVE_SYSCALL_SOCKET) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * socket()
- */
-int socket(int af, int type, int protocol)
-{
- int fd, fd_kern;
-
- if (!((fd = fd_allocate()) < OK)) {
-
- if (!((fd_kern = machdep_sys_socket(af, type, protocol)) < OK)) {
- int tmp_flags;
-
- tmp_flags = machdep_sys_fcntl(fd_kern, F_GETFL, 0);
- machdep_sys_fcntl(fd_kern, F_SETFL, tmp_flags | __FD_NONBLOCK);
-
- /* Should fstat the file to determine what type it is */
- fd_table[fd]->ops = & __fd_kern_ops;
- fd_table[fd]->type = FD_FULL_DUPLEX;
- fd_table[fd]->fd.i = fd_kern;
- fd_table[fd]->flags = tmp_flags;
- return(fd);
- }
-
- fd_table[fd]->count = 0;
- SET_ERRNO(-fd_kern);
- }
- return(NOTOK);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_BIND) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * bind()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int bind(int fd, const struct sockaddr *name, socklen_t namelen)
-#else
-int bind(int fd, const struct sockaddr *name, int namelen)
-#endif
-{
- /* Not much to do in bind */
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_bind(fd_table[fd]->fd.i, name, namelen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_CONNECT) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * connect()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int connect(int fd, const struct sockaddr *name, socklen_t namelen)
-#else
-int connect(int fd, const struct sockaddr *name, int namelen)
-#endif
-{
- struct sockaddr tmpname;
- int ret, tmpnamelen;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_connect(fd_table[fd]->fd.i, name, namelen)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) ||
- (ret == -EALREADY) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- pthread_resched_resume(PS_FDW_WAIT);
- CLEAR_PF_DONE_EVENT(pthread_run);
-
- tmpnamelen = sizeof(tmpname);
- /* OK now lets see if it really worked */
- if (((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
- &tmpname, &tmpnamelen)) < OK) &&
- (ret == -ENOTCONN))
- {
- /* Get the error, this function should not fail */
- machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET,
- SO_ERROR, &ret, &tmpnamelen);
- SET_ERRNO(ret); /* ret is already positive (mevans) */
- ret = NOTOK;
- }
- } else {
- if (ret < 0)
- {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- }
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_ACCEPT) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * accept()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int accept(int fd, struct sockaddr *name, socklen_t *namelen)
-#else
-int accept(int fd, struct sockaddr *name, int *namelen)
-#endif
-{
- int ret, fd_kern;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- while ((fd_kern = machdep_sys_accept(fd_table[fd]->fd.i, name, namelen)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((fd_kern == -EWOULDBLOCK) || (fd_kern == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- pthread_resched_resume(PS_FDR_WAIT);
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- fd_unlock(fd, FD_RDWR);
- SET_ERRNO(-fd_kern);
- return(NOTOK);
- }
- }
- fd_unlock(fd, FD_RDWR);
-
- if (!((ret = fd_allocate()) < OK)) {
-
- /* This may be unnecessary */
- machdep_sys_fcntl(fd_kern, F_SETFL, __FD_NONBLOCK);
-
- /* Should fstat the file to determine what type it is */
- fd_table[ret]->ops = & __fd_kern_ops;
- fd_table[ret]->type = FD_FULL_DUPLEX;
- fd_table[ret]->fd.i = fd_kern;
-
- /* XXX Flags should be the same as those on the listening fd */
- fd_table[ret]->flags = fd_table[fd]->flags;
- }
- }
- return(ret);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_LISTEN) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * listen()
- */
-int listen(int fd, int backlog)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_listen(fd_table[fd]->fd.i, backlog)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SEND) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * send_timedwait()
- */
-ssize_t send_timedwait(int fd, const void * msg, size_t len, int flags,
- struct timespec * timeout)
-{
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) {
- while ((ret = machdep_sys_send(fd_table[fd]->fd.i,
- msg, len, flags)) < OK)
- {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN)))
- {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- ret= -EINTR;
- break;
- }
- } else {
- break;
- }
- }
- fd_unlock(fd, FD_WRITE);
- }
- if (ret < 0)
- {
- SET_ERRNO(-ret);
- return(NOTOK);
- }
- return ret;
-}
-
-/* ==========================================================================
- * send()
- */
-ssize_t send(int fd, const void * msg, size_t len, int flags)
-{
- return(send_timedwait(fd, msg, len, flags, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SENDTO) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * sendto_timedwait()
- */
-ssize_t sendto_timedwait(int fd, const void * msg, size_t len,
- int flags, const struct sockaddr *to, int to_len,
- struct timespec * timeout)
-{
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) {
- while ((ret = machdep_sys_sendto(fd_table[fd]->fd.i,
- msg, len, flags, to, to_len)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret= -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- ret= -EINTR;
- break;
- }
- }
- else
- break; /* ret contains the errorcode */
- }
- fd_unlock(fd, FD_WRITE);
- }
- if (ret < 0)
- {
- SET_ERRNO(-ret);
- return(NOTOK);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * sendto()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-ssize_t sendto(int fd, const void * msg, size_t len, int flags,
- const struct sockaddr *to, socklen_t to_len)
-#else
-ssize_t sendto(int fd, const void * msg, size_t len, int flags,
- const struct sockaddr *to, int to_len)
-#endif
-{
- return(sendto_timedwait(fd, msg, len, flags, to, to_len, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SENDMSG) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * sendmsg_timedwait()
- */
-ssize_t sendmsg_timedwait(int fd, const struct msghdr *msg, int flags,
- struct timespec * timeout)
-{
- int passed_fd, ret, i;
-
- /* Handle getting the real file descriptor */
- for(i = 0; i < (((struct omsghdr *)msg)->msg_accrightslen/sizeof(i)); i++) {
- passed_fd = *(((int *)((struct omsghdr *)msg)->msg_accrights) + i);
- if ((ret = fd_lock(passed_fd, FD_RDWR, NULL)) == OK) {
- *(((int *)((struct omsghdr *)msg)->msg_accrights) + i)
- = fd_table[passed_fd]->fd.i;
- machdep_sys_fcntl(fd_table[passed_fd]->fd.i, F_SETFL,
- fd_table[passed_fd]->flags);
- switch(fd_table[passed_fd]->type) {
- case FD_TEST_FULL_DUPLEX:
- case FD_TEST_HALF_DUPLEX:
- break;
- case FD_FULL_DUPLEX:
- fd_table[passed_fd]->type = FD_TEST_FULL_DUPLEX;
- break;
- case FD_HALF_DUPLEX:
- fd_table[passed_fd]->type = FD_TEST_HALF_DUPLEX;
- break;
- default:
- PANIC();
- }
- } else {
- fd_unlock(fd, FD_RDWR);
- SET_ERRNO(EBADF);
- return(NOTOK);
- }
- fd_unlock(fd, FD_RDWR);
- }
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) {
- while((ret = machdep_sys_sendmsg(fd_table[fd]->fd.i, msg, flags)) < OK){
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
-
- } else {
- SET_ERRNO(-ret);
- ret = NOTOK;
- break;
- }
- }
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * sendmsg()
- */
-ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
-{
- return(sendmsg_timedwait(fd, msg, flags, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_RECV) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * recv_timedwait()
- */
-ssize_t recv_timedwait(int fd, void * buf, size_t len, int flags,
- struct timespec * timeout)
-{
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) {
- while ((ret = machdep_sys_recv(fd_table[fd]->fd.i,
- buf, len, flags)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- ret= -EINTR;
- break;
- }
-
- } else {
- break;
- }
- }
- fd_unlock(fd, FD_READ);
- }
- if (ret < 0)
- {
- SET_ERRNO(-ret);
- return(NOTOK);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * recv()
- */
-ssize_t recv(int fd, void * buf, size_t len, int flags)
-{
- return(recv_timedwait(fd, buf, len, flags, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_RECVFROM) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * recvfrom_timedwait()
- */
-ssize_t recvfrom_timedwait(int fd, void * buf, size_t len, int flags,
- struct sockaddr * from, int * from_len,
- struct timespec * timeout)
-{
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) {
- while ((ret = machdep_sys_recvfrom(fd_table[fd]->fd.i,
- buf, len, flags, from, from_len)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- ret= -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
-
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- ret= -EINTR;
- break;
- }
- } else {
- break;
- }
- }
- fd_unlock(fd, FD_READ);
- }
- if (ret < 0)
- {
- SET_ERRNO(-ret);
- return(NOTOK);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * recvfrom()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-ssize_t recvfrom(int fd, void * buf, size_t len, int flags,
- struct sockaddr * from, socklen_t * from_len)
-#else
-ssize_t recvfrom(int fd, void * buf, size_t len, int flags,
- struct sockaddr * from, int * from_len)
-#endif
-{
- return(recvfrom_timedwait(fd, buf, len, flags, from, from_len, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_RECVMSG) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * recvmsg_timedwait()
- */
-ssize_t recvmsg_timedwait(int fd, struct msghdr *msg, int flags,
- struct timespec * timeout)
-{
- struct stat stat_buf;
- int passed_fd, ret, i;
-
- pthread_run->sighandled=0; /* Added by monty */
- if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) {
- while ((ret = machdep_sys_recvmsg(fd_table[fd]->fd.i, msg, flags)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = NOTOK;
- break;
- }
- pthread_sched_resume();
-
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= NOTOK;
- break;
- }
- } else {
- SET_ERRNO(-ret);
- ret = NOTOK;
- break;
- }
- }
- fd_unlock(fd, FD_READ);
-
- /* Handle getting the real file descriptor */
- for (i = 0; i < (((struct omsghdr *)msg)->msg_accrightslen / sizeof(i));
- i++) {
- passed_fd = *(((int *)((struct omsghdr *)msg)->msg_accrights) + i);
- if (!((fd = fd_allocate()) < OK)) {
- fd_table[fd]->flags = machdep_sys_fcntl(passed_fd, F_GETFL);
-
- if (!( fd_table[fd]->flags & __FD_NONBLOCK)) {
- machdep_sys_fcntl(passed_fd, F_SETFL,
- fd_table[fd]->flags | __FD_NONBLOCK);
- }
-
- /* fstat the file to determine what type it is */
- machdep_sys_fstat(passed_fd, &stat_buf);
- if (S_ISREG(stat_buf.st_mode)) {
- fd_table[fd]->type = FD_HALF_DUPLEX;
- } else {
- fd_table[fd]->type = FD_FULL_DUPLEX;
- }
- *(((int *)((struct omsghdr *)msg)->msg_accrights) + i) = fd;
- fd_table[fd]->ops = &(__fd_kern_ops);
- fd_table[fd]->fd.i = passed_fd;
- } else {
- SET_ERRNO(EBADF);
- return(NOTOK);
- break;
- }
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * recvmsg()
- */
-ssize_t recvmsg(int fd, struct msghdr *msg, int flags)
-{
- return(recvmsg_timedwait(fd, msg, flags, NULL));
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SHUTDOWN) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * shutdown()
- */
-int shutdown(int fd, int how)
-{
- int ret;
-
- switch(how) {
- case 0: /* Read */
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_shutdown(fd_table[fd]->fd.i, how)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_READ);
- }
- case 1: /* Write */
- if ((ret = fd_lock(fd, FD_WRITE, NULL)) == OK) {
- if ((ret = machdep_sys_shutdown(fd_table[fd]->fd.i, how)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_WRITE);
- }
- case 2: /* Read-Write */
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_shutdown(fd_table[fd]->fd.i, how)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- default:
- SET_ERRNO(EBADF);
- ret = NOTOK;
- break;
- }
- return(ret);
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SETSOCKOPT) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * setsockopt()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int setsockopt(int fd, int level, int optname, const void * optval, socklen_t optlen)
-#else
-int setsockopt(int fd, int level, int optname, const void * optval, int optlen)
-#endif
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) {
- if ((ret = machdep_sys_setsockopt(fd_table[fd]->fd.i, level,
- optname, optval, optlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return ret;
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_GETSOCKOPT) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * getsockopt()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int getsockopt(int fd, int level, int optname, void * optval, socklen_t * optlen)
-#else
-int getsockopt(int fd, int level, int optname, void * optval, int * optlen)
-#endif
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_getsockopt(fd_table[fd]->fd.i, level,
- optname, optval, optlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return ret;
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_GETSOCKOPT) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * getsockname()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int getsockname(int fd, struct sockaddr * name, socklen_t * naddrlen)
-#else
-int getsockname(int fd, struct sockaddr * name, int * naddrlen)
-#endif
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_getsockname(fd_table[fd]->fd.i,
- name, naddrlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return ret;
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_GETPEERNAME) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * getpeername()
- */
-#ifdef _OS_HAS_SOCKLEN_T
-int getpeername(int fd, struct sockaddr * peer, socklen_t * paddrlen)
-#else
-int getpeername(int fd, struct sockaddr * peer, int * paddrlen)
-#endif
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_getpeername(fd_table[fd]->fd.i,
- peer, paddrlen)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_READ);
- }
- return ret;
-}
-
-#endif
-
-#if defined (HAVE_SYSCALL_SOCKETPAIR) || defined (HAVE_SYSCALL_SOCKETCALL)
-
-/* ==========================================================================
- * socketpair()
- */
-int socketpair(int af, int type, int protocol, int pair[2])
-{
- int ret, fd[2];
-
- if (!((pair[0] = fd_allocate()) < OK)) {
- if (!((pair[1] = fd_allocate()) < OK)) {
- if (!((ret = machdep_sys_socketpair(af, type, protocol, fd)) < OK)){
- int tmp_flags;
-
- tmp_flags = machdep_sys_fcntl(fd[0], F_GETFL, 0);
- machdep_sys_fcntl(fd[0], F_SETFL, tmp_flags | __FD_NONBLOCK);
- fd_table[pair[0]]->ops = & __fd_kern_ops;
- fd_table[pair[0]]->type = FD_FULL_DUPLEX;
- fd_table[pair[0]]->flags = tmp_flags;
- fd_table[pair[0]]->fd.i = fd[0];
-
- tmp_flags = machdep_sys_fcntl(fd[1], F_GETFL, 0);
- machdep_sys_fcntl(fd[1], F_SETFL, tmp_flags | __FD_NONBLOCK);
- fd_table[pair[1]]->ops = & __fd_kern_ops;
- fd_table[pair[1]]->type = FD_FULL_DUPLEX;
- fd_table[pair[1]]->flags = tmp_flags;
- fd_table[pair[1]]->fd.i = fd[1];
-
- return(ret);
- }
- fd_table[pair[1]]->count = 0;
- }
- fd_table[pair[0]]->count = 0;
- SET_ERRNO(-ret);
- }
- return(NOTOK);
-}
-
-#endif
diff --git a/mit-pthreads/pthreads/fd_pipe.c b/mit-pthreads/pthreads/fd_pipe.c
deleted file mode 100644
index e8bc20857ed..00000000000
--- a/mit-pthreads/pthreads/fd_pipe.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/* ==== fd_pipe.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : The new fast ITC pipe routines.
- *
- * 1.00 93/08/14 proven
- * -Started coding this file.
- *
- * 1.01 93/11/13 proven
- * -The functions readv() and writev() added.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <pthread/fd_pipe.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread/posix.h>
-#include <string.h>
-#include <stdlib.h>
-
-#ifndef MIN
-#define MIN(a,b) ((a)<(b)?(a):(b))
-#endif
-
-/* ==========================================================================
- * The pipe lock is never unlocked until all pthreads waiting are done with it
- * read()
- */
-pthread_ssize_t __pipe_read(union fd_data fd_data, int flags, void *buf,
- size_t nbytes, struct timespec * timeout)
-{
- struct __pipe *fd = (struct __pipe *)fd_data.ptr;
- struct pthread * pthread;
- int ret = 0;
-
- if (flags & O_ACCMODE) { return(NOTOK); }
-
- /* If there is nothing to read, go to sleep */
- if (fd->count == 0) {
- if (flags == WR_CLOSED) {
- return(0);
- }
-
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- pthread_run->next = NULL;
- fd->wait = pthread_run;
-
- pthread_resched_resume(PS_FDR_WAIT);
- ret = fd->size;
- } else {
- ret = MIN(nbytes, fd->count);
- memcpy(buf, fd->buf + fd->offset, ret);
- if (!(fd->count -= ret)) {
- fd->offset = 0;
- }
-
- if (pthread = fd->wait) {
- fd->wait = NULL;
- pthread_sched_prevent();
- pthread_sched_other_resume(pthread);
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * __pipe_write()
- *
- * First check to see if the read side is still open, then
- * check to see if there is a thread in a read wait for this pipe, if so
- * copy as much data as possible directly into the read waiting threads
- * buffer. The write thread(whether or not there was a read thread)
- * copies as much data as it can into the pipe buffer and it there
- * is still data it goes to sleep.
- */
-pthread_ssize_t __pipe_write(union fd_data fd_data, int flags, const void *buf,
- size_t nbytes, struct timespec * timeout) {
- struct __pipe *fd = (struct __pipe *)fd_data.ptr;
- struct pthread * pthread;
- int ret, count;
-
- if (!(flags & O_ACCMODE)) { return(NOTOK); }
-
- while (fd->flags != RD_CLOSED) {
- if (pthread = fd->wait) {
-
- pthread_sched_prevent();
-
- /* Copy data directly into waiting pthreads buf */
- fd->wait_size = MIN(nbytes, fd->wait_size);
- memcpy(fd->wait_buf, buf, fd->wait_size);
- buf = (const char *)buf + fd->wait_size;
- nbytes -= fd->wait_size;
- ret = fd->wait_size;
- fd->wait = NULL;
-
- /* Wake up waiting pthread */
- pthread_sched_other_resume(pthread);
- }
-
- if (count = MIN(nbytes, fd->size - (fd->offset + fd->count))) {
- memcpy(fd->buf + (fd->offset + fd->count), buf, count);
- buf = (const char *)buf + count;
- nbytes -= count;
- ret += count;
- }
- if (nbytes) {
- pthread_sched_prevent();
- fd->wait = pthread_run;
- pthread_resched_resume(PS_FDW_WAIT);
- } else {
- return(ret);
- }
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * __pipe_close()
- *
- * The whole close procedure is a bit odd and needs a bit of a rethink.
- * For now close() locks the fd, calls fd_free() which checks to see if
- * there are any other fd values poinging to the same real fd. If so
- * It breaks the wait queue into two sections those that are waiting on fd
- * and those waiting on other fd's. Those that are waiting on fd are connected
- * to the fd_table[fd] queue, and the count is set to zero, (BUT THE LOCK IS NOT
- * RELEASED). close() then calls fd_unlock which give the fd to the next queued
- * element which determins that the fd is closed and then calls fd_unlock etc...
- */
-int __pipe_close(struct __pipe *fd, int flags)
-{
- struct pthread * pthread;
-
- if (!(fd->flags)) {
- if (pthread = fd->wait) {
- if (flags & O_ACCMODE) {
- fd->count = 0;
- fd->wait = NULL;
- fd->flags |= WR_CLOSED;
- pthread_sched_prevent();
- pthread_resched_resume(pthread);
- } else {
- /* Should send a signal */
- fd->flags |= RD_CLOSED;
- }
- }
- } else {
- free(fd);
- return(OK);
- }
-}
-
-/* ==========================================================================
- * For fcntl() which isn't implemented yet
- * __pipe_enosys()
- */
-static int __pipe_enosys()
-{
- SET_ERRNO(ENOSYS);
- return(NOTOK);
-}
-
-/* ==========================================================================
- * For writev() and readv() which aren't implemented yet
- * __pipe_enosys_v()
- */
-static int __pipe_enosys_v(union fd_data fd, int flags,
- const struct iovec *vec, int nvec,
- struct timespec *timeout)
-{
- SET_ERRNO(ENOSYS);
- return(NOTOK);
-}
-
-/* ==========================================================================
- * For lseek() which isn't implemented yet
- * __pipe_enosys_o()
- */
-static off_t __pipe_enosys_o()
-{
- SET_ERRNO(ENOSYS);
- return(NOTOK);
-}
-
-/*
- * File descriptor operations
- */
-struct fd_ops fd_ops[] = {
-{ __pipe_write, __pipe_read, __pipe_close, __pipe_enosys,
- __pipe_enosys_v, __pipe_enosys_v, __pipe_enosys_o, 0 },
-};
-
-/* ==========================================================================
- * open()
- */
-/* int __pipe_open(const char *path, int flags, ...) */
-int newpipe(int fd[2])
-{
- struct __pipe *fd_data;
-
- if ((!((fd[0] = fd_allocate()) < OK)) && (!((fd[1] = fd_allocate()) < OK))) {
- fd_data = malloc(sizeof(struct __pipe));
- fd_data->buf = malloc(4096);
- fd_data->size = 4096;
- fd_data->count = 0;
- fd_data->offset = 0;
-
- fd_data->wait = NULL;
- fd_data->flags = 0;
-
- fd_table[fd[0]]->fd.ptr = fd_data;
- fd_table[fd[0]]->flags = O_RDONLY;
- fd_table[fd[1]]->fd.ptr = fd_data;
- fd_table[fd[1]]->flags = O_WRONLY;
-
- return(OK);
- }
- return(NOTOK);
-}
-
diff --git a/mit-pthreads/pthreads/fd_sysv.c b/mit-pthreads/pthreads/fd_sysv.c
deleted file mode 100644
index 6dc01a49aa4..00000000000
--- a/mit-pthreads/pthreads/fd_sysv.c
+++ /dev/null
@@ -1,897 +0,0 @@
-/* ==== fd_sysv.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Transforms BSD socket calls to SYSV streams.
- *
- * 1.00 94/11/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <config.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#if defined (HAVE_SYSCALL_PUTMSG) && defined (HAVE_SYSCALL_GETMSG) && !defined(HAVE_SYSCALL_SOCKETCALL) && !defined(HAVE_SYSCALL_SOCKET)
-#define HAVE_STREAMS 1
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#include <tiuser.h>
-#include <sys/tihdr.h>
-#include <netinet/in.h>
-#include <sys/timod.h>
-
-#define STREAM_BUF_SIZE sizeof(union T_primitives) + sizeof(struct sockaddr)
-
-extern struct pthread_queue fd_wait_read, fd_wait_write;
-
-/* ==========================================================================
- * putmsg_timedwait_basic()
- */
-static int putmsg_timedwait_basic(int fd, struct strbuf * ctlptr,
- struct strbuf * dataptr, int flags, struct timespec * timeout)
-{
-
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_putmsg(fd_table[fd]->fd.i,
- ctlptr, dataptr, flags)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDW_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_write, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(& current_time, timeout);
-
- pthread_resched_resume(PS_FDW_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDW_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= -EINTR;
- break;
- }
- } else {
- SET_ERRNO(-ret);
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * putmsg_timedwait()
- */
-int putmsg_timedwait(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
- int flags, struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) {
- ret = putmsg_timedwait_basic(fd, ctlptr, dataptr, flags, timeout);
- fd_unlock(fd, FD_WRITE);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * putmsg()
- */
-int putmsg(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
- int flags)
-{
- return(putmsg_timedwait(fd, ctlptr, dataptr, flags, NULL));
-}
-
-/* ==========================================================================
- * getmsg_timedwait_basic()
- */
-int getmsg_timedwait_basic(int fd, struct strbuf * ctlptr,
- struct strbuf * dataptr, int * flags, struct timespec * timeout)
-{
- int ret;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_getmsg(fd_table[fd]->fd.i,
- ctlptr, dataptr, flags)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_run->data.fd.fd = fd_table[fd]->fd.i;
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(& current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- ret= -EINTR;
- break;
- }
-
- } else {
- SET_ERRNO(-ret);
- break;
- }
- }
- return(ret);
-}
-
-/* ==========================================================================
- * getmsg_timedwait()
- */
-int getmsg_timedwait(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
- int * flags, struct timespec * timeout)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) {
- ret = getmsg_timedwait_basic(fd, ctlptr, dataptr, flags, timeout);
- fd_unlock(fd, FD_READ);
- }
- return (ret);
-}
-
-/* ==========================================================================
- * getmsg()
- */
-int getmsg(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
- int * flags)
-{
- return(getmsg_timedwait(fd, ctlptr, dataptr, flags, NULL));
-}
-
-#endif
-
-/* ==========================================================================
- * Here are the berkeley socket functions implemented with stream calls.
- * These are not POSIX.
- * ======================================================================= */
-
-#if (!defined (HAVE_SYSCALL_BIND)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * bind()
- */
-int bind(int fd, const struct sockaddr *name, int namelen)
-{
- char buf[STREAM_BUF_SIZE];
- union T_primitives * res;
- struct T_bind_req * req;
- struct T_bind_ack * ack;
- struct strbuf strbuf;
- int flags, ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK)
- {
- req = (struct T_bind_req *)buf;
- req->PRIM_type = T_BIND_REQ;
- req->ADDR_length = namelen;
- req->ADDR_offset = sizeof(struct T_bind_req);
- req->CONIND_number = 4;
- memcpy(buf + sizeof(struct T_bind_req), name, namelen);
-
- strbuf.len = sizeof(struct T_bind_req) + namelen;
- strbuf.maxlen = STREAM_BUF_SIZE;
- strbuf.buf = buf;
-
- if ((ret=putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL)) == OK)
- {
- memset(buf, 0, STREAM_BUF_SIZE);
-
- strbuf.len = sizeof(struct T_bind_ack) + namelen;
- strbuf.maxlen = STREAM_BUF_SIZE;
- strbuf.buf = buf;
- flags = 0;
-
- if ((ret = getmsg_timedwait_basic(fd, &strbuf, NULL,
- &flags, NULL)) >= OK)
- {
- res = (union T_primitives *)buf;
-
- switch(res->type) {
- case T_BIND_ACK:
- ret = OK;
- break;
- default:
- SET_ERRNO(EPROTO); /* What should this be? */
- ret = NOTOK;
- break;
- }
- }
- else
- {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- }
- else
- {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_CONNECT)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * connect()
- */
-int connect(int fd, const struct sockaddr *name, int namelen)
-{
- char buf[STREAM_BUF_SIZE];
- union T_primitives * res;
- struct T_conn_req * req;
- struct T_conn_con * con;
- struct T_ok_ack * ok;
- struct strbuf strbuf;
- int flags, ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK)
- {
- req = (struct T_conn_req *)buf;
- req->PRIM_type = T_CONN_REQ;
- req->DEST_length = namelen;
- req->DEST_offset = sizeof(struct T_conn_req);
- req->OPT_length = 0;
- req->OPT_offset = 0;
- memcpy(buf + sizeof(struct T_conn_req), name, namelen);
-
- strbuf.len = sizeof(struct T_conn_req) + namelen;
- strbuf.maxlen = STREAM_BUF_SIZE;
- strbuf.buf = buf;
-
- if ((ret=putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL)) != OK)
- goto err;
-
- memset(buf, 0, STREAM_BUF_SIZE);
- ok = (struct T_ok_ack *)buf;
-
- strbuf.maxlen = STREAM_BUF_SIZE;
- strbuf.len = STREAM_BUF_SIZE;
- strbuf.buf = buf;
- flags = 0;
-
- if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL)) < OK)
- goto err; /* Fixed by monty */
- if (ok->PRIM_type != T_OK_ACK)
- {
- ret= -EPROTO; /* What should this be? */
- goto err;
- }
-
- memset(buf, 0, STREAM_BUF_SIZE);
- strbuf.maxlen = STREAM_BUF_SIZE;
- strbuf.len = STREAM_BUF_SIZE;
- strbuf.buf = buf;
- flags = 0;
-
- if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL) < OK))
- goto err;
-
- res = (union T_primitives *) buf;
- switch(res->type) {
- case T_CONN_CON:
- ret = OK;
- break;
- case T_DISCON_IND:
- ret= -ECONNREFUSED;
- goto err;
- default:
- ret= -EPROTO; /* What should this be? */
- goto err;
- }
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-
- err:
- fd_unlock(fd, FD_RDWR);
- SET_ERRNO(-ret); /* Proably not needed... */
- return NOTOK;
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_LISTEN)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * listen()
- */
-int listen(int fd, int backlog)
-{
- return(OK);
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_SOCKET)) && defined(HAVE_STREAMS)
-
-extern ssize_t __fd_kern_write();
-static pthread_ssize_t __fd_sysv_read();
-extern int __fd_kern_close();
-extern int __fd_kern_fcntl();
-extern int __fd_kern_writev();
-extern int __fd_kern_readv();
-extern off_t __fd_kern_lseek();
-
-/* Normal file operations */
-static struct fd_ops __fd_sysv_ops = {
- __fd_kern_write, __fd_sysv_read, __fd_kern_close, __fd_kern_fcntl,
- __fd_kern_writev, __fd_kern_readv, __fd_kern_lseek, 1
-};
-
-/* ==========================================================================
- * read()
- */
-static pthread_ssize_t __fd_sysv_read(union fd_data fd_data, int flags,
- void *buf, size_t nbytes, struct timespec * timeout)
-{
- struct strbuf dataptr;
- int fd = fd_data.i;
- int getmsg_flags;
- int ret;
-
- getmsg_flags = 0;
- dataptr.len = 0;
- dataptr.buf = buf;
- dataptr.maxlen = nbytes;
-
- pthread_run->sighandled=0; /* Added by monty */
- while ((ret = machdep_sys_getmsg(fd, NULL, &dataptr, &getmsg_flags)) < OK) {
- if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
- ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
- pthread_sched_prevent();
-
- /* queue pthread for a FDR_WAIT */
- pthread_run->data.fd.fd = fd;
- SET_PF_WAIT_EVENT(pthread_run);
- pthread_queue_enq(&fd_wait_read, pthread_run);
-
- if (timeout) {
- /* get current time */
- struct timespec current_time;
- machdep_gettimeofday(&current_time);
- sleep_schedule(& current_time, timeout);
-
- pthread_resched_resume(PS_FDR_WAIT);
-
- /* We're awake */
- pthread_sched_prevent();
- if (sleep_cancel(pthread_run) == NOTOK) {
- CLEAR_PF_DONE_EVENT(pthread_run);
- pthread_sched_resume();
- SET_ERRNO(ETIMEDOUT);
- ret = -ETIMEDOUT;
- break;
- }
- pthread_sched_resume();
- } else {
- pthread_resched_resume(PS_FDR_WAIT);
- }
- CLEAR_PF_DONE_EVENT(pthread_run);
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- SET_ERRNO(EINTR);
- return(NOTOK);
- }
- } else {
- SET_ERRNO(-ret);
- return(NOTOK);
- break;
- }
- }
- return(dataptr.len);
-}
-
-/* ==========================================================================
- * socket_tcp()
- */
-static int socket_tcp(int fd)
-{
- int ret;
-
- if ((ret = machdep_sys_open("/dev/tcp", O_RDWR | O_NONBLOCK, 0)) >= OK) {
- /* Should fstat the file to determine what type it is */
- fd_table[fd]->ops = & __fd_sysv_ops;
- fd_table[fd]->type = FD_FULL_DUPLEX;
- fd_table[fd]->fd.i = ret;
- fd_table[fd]->flags = 0;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * socket()
- */
-int socket(int af, int type, int protocol)
-{
- int fd, fd_kern;
-
- if ((fd = fd_allocate()) < OK)
- return (fd);
-
- switch(af) {
- case AF_INET:
- switch(type) {
- case SOCK_STREAM:
- if ((fd_kern = socket_tcp(fd)) >= OK)
- return(fd);
- SET_ERRNO(-fd_kern);
- break;
- case SOCK_DGRAM:
- if ((fd_kern = machdep_sys_open("/dev/udp",
- O_RDWR | O_NONBLOCK, 0)) >= OK) {
- /* Should fstat the file to determine what type it is */
- fd_table[fd]->ops = & __fd_sysv_ops;
- fd_table[fd]->type = FD_FULL_DUPLEX;
- fd_table[fd]->fd.i = fd_kern;
- fd_table[fd]->flags = 0;
- return(fd);
- }
- SET_ERRNO(-fd_kern);
- break;
- default:
- SET_ERRNO(EPROTONOSUPPORT);
- break;
- }
- break;
- case AF_UNIX:
- case AF_ISO:
- case AF_NS:
- default:
- SET_ERRNO(EPROTONOSUPPORT);
- break;
- }
- fd_table[fd]->count = 0;
- return(NOTOK); /* Fixed by monty */
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_ACCEPT)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * accept_fd()
- */
-static int accept_fd(int fd, struct sockaddr *name, int *namelen, char * buf,
- int SEQ_number)
-{
- struct T_conn_res * res;
- struct strbuf strbuf;
- int fd_new, fd_kern;
-
- /* Get a new table entry */
- if ((fd_new = fd_allocate()) < OK)
- return(NOTOK);
-
- /* Get the new kernel entry */
- if (!((fd_kern = socket_tcp(fd_new)) < OK)) {
- res = (struct T_conn_res *)buf;
- res->PRIM_type = T_CONN_RES;
- /* res->QUEUE_ptr = (queue_t *)&fd_kern; */
- res->OPT_length = 0;
- res->OPT_offset = 0;
- res->SEQ_number = SEQ_number;
-
- strbuf.maxlen = sizeof(union T_primitives) +sizeof(struct sockaddr);
- strbuf.len = sizeof(struct T_conn_ind) + (*namelen);
- strbuf.buf = buf;
-
- {
- struct strfdinsert insert;
-
- insert.ctlbuf.maxlen = (sizeof(union T_primitives) +
- sizeof(struct sockaddr));
- insert.ctlbuf.len = sizeof(struct T_conn_ind);
- insert.ctlbuf.buf = buf;
- insert.databuf.maxlen = 0;
- insert.databuf.len = 0;
- insert.databuf.buf = NULL;
- insert.flags = 0;
- insert.fildes = fd_kern;
- insert.offset = 4;
- /* Should the following be checked ? */
- machdep_sys_ioctl(fd_table[fd]->fd.i, I_FDINSERT, &insert);
- }
-
- /* if (putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL) == OK) {
- /* return(fd_new); */
- {
- int flags = 0;
- int ret;
-
- /* Should the following be checked ? */
- ret = getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL);
- return(fd_new);
-
- }
- machdep_sys_close(fd_kern);
- }
- fd_table[fd_new]->count = 0;
- return(NOTOK);
-}
-
-
-/* ==========================================================================
- * accept()
- */
-int accept(int fd, struct sockaddr *name, int *namelen)
-{
- char buf[sizeof(union T_primitives) + sizeof(struct sockaddr)];
- struct T_conn_ind * ind;
- struct strbuf strbuf;
- int flags, ret;
-
- if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK)
- {
- ind = (struct T_conn_ind *)buf;
- ind->PRIM_type = T_CONN_IND;
- ind->SRC_length = (*namelen);
- ind->SRC_offset = sizeof(struct T_conn_ind);
- ind->OPT_length = 0;
- ind->OPT_offset = 0;
- ind->SEQ_number = 0;
-
- strbuf.maxlen = sizeof(union T_primitives) + sizeof(struct sockaddr);
- strbuf.len = sizeof(struct T_conn_ind) + (*namelen);
- strbuf.buf = buf;
- flags = 0;
-
- if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL)) < OK)
- {
- SET_ERRNO(-ret);
- ret= NOTOK;
- }
- else
- ret = accept_fd(fd, name, namelen, buf, ind->SEQ_number);
- fd_unlock(fd, FD_RDWR);
- }
- return(ret);
-}
-
-#endif /* HAVE_SYSCALL_ACCEPT */
-
-#if (!defined (HAVE_SYSCALL_SENDTO)) && defined (HAVE_STREAMS)
-
-/* ==========================================================================
- * sendto_timedwait()
- */
-ssize_t sendto_timedwait(int fd, const void * msg, size_t len, int flags,
- const struct sockaddr *name, int namelen, struct timespec * timeout)
-{
- char buf[STREAM_BUF_SIZE];
- struct T_unitdata_req * req;
- struct strbuf dataptr;
- struct strbuf ctlptr;
- ssize_t ret, prio;
-
- req = (struct T_unitdata_req *)buf;
- req->PRIM_type = T_UNITDATA_REQ;
- req->DEST_length = namelen;
- req->DEST_offset = sizeof(struct T_unitdata_req);
- req->OPT_length = 0;
- req->OPT_offset = 0;
- memcpy(buf + sizeof(struct T_unitdata_req), name, namelen);
-
- ctlptr.len = sizeof(struct T_unitdata_req) + namelen;
- ctlptr.maxlen = STREAM_BUF_SIZE;
- ctlptr.buf = buf;
-
- dataptr.len = len;
- dataptr.maxlen = len;
- dataptr.buf = (void *)msg;
-
- if ((ret = putmsg_timedwait(fd, &ctlptr, &dataptr, 0, timeout)) == OK) {
- ret = len;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * sendto()
- */
-ssize_t sendto(int fd, const void * msg, size_t len, int flags,
- const struct sockaddr *to, int to_len)
-{
- return(sendto_timedwait(fd, msg, len, flags, to, to_len, NULL));
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_SEND)) && defined (HAVE_STREAMS)
-
-/* ==========================================================================
- * send_timedwait()
- */
-ssize_t send_timedwait(int fd, const void * msg, size_t len, int flags,
- struct timespec * timeout)
-{
- char buf[STREAM_BUF_SIZE];
- struct T_unitdata_req * req;
- struct strbuf dataptr;
- struct strbuf ctlptr;
- ssize_t ret, prio;
-
- req = (struct T_unitdata_req *)buf;
- req->PRIM_type = T_UNITDATA_REQ;
- req->DEST_length = 0;
- req->DEST_offset = 0;
- req->OPT_length = 0;
- req->OPT_offset = 0;
-
- ctlptr.len = sizeof(struct T_unitdata_req);
- ctlptr.maxlen = STREAM_BUF_SIZE;
- ctlptr.buf = buf;
-
- dataptr.len = len;
- dataptr.maxlen = len;
- dataptr.buf = (void *)msg;
-
- if ((ret = putmsg_timedwait(fd, &ctlptr, &dataptr, 0, timeout)) == OK) {
- ret = len;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * send()
- */
-ssize_t send(int fd, const void * msg, size_t len, int flags)
-{
- return(send_timedwait(fd, msg, len, flags, NULL));
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_RECVFROM)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * recvfrom_timedwait()
- */
-ssize_t recvfrom_timedwait(int fd, void * msg, size_t len, int flags,
- struct sockaddr * name, int * namelen, struct timespec * timeout)
-{
- char buf[STREAM_BUF_SIZE];
- struct T_unitdata_ind * ind;
- struct strbuf dataptr;
- struct strbuf ctlptr;
- int ret, prio;
-
- ctlptr.len = 0;
- ctlptr.maxlen = STREAM_BUF_SIZE;
- ctlptr.buf = buf;
-
- dataptr.maxlen = len;
- dataptr.len = 0;
- dataptr.buf = msg;
-
- prio = 0;
-
- ret = getmsg_timedwait(fd, &ctlptr, &dataptr, &prio, timeout);
- if (ret >= OK) {
- if (name != NULL) {
- ind = (struct T_unitdata_ind *)buf;
-
- if (*namelen > ind->SRC_length)
- *namelen = ind->SRC_length;
- memcpy(name, buf + ind->SRC_offset, *namelen);
- }
- ret = dataptr.len;
- }
-
- return(ret);
-}
-
-/* ==========================================================================
- * recvfrom()
- */
-ssize_t recvfrom(int fd, void * buf, size_t len, int flags,
- struct sockaddr * from, int * from_len)
-{
- return(recvfrom_timedwait(fd, buf, len, flags, from, from_len, NULL));
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_RECV)) && defined(HAVE_STREAMS)
-
-/* ==========================================================================
- * recv_timedwait()
- */
-ssize_t recv_timedwait(int fd, void * msg, size_t len, int flags,
- struct timespec * timeout)
-{
- char buf[STREAM_BUF_SIZE];
- struct T_unitdata_ind * ind;
- struct strbuf dataptr;
- struct strbuf ctlptr;
- int ret, prio;
-
- ctlptr.len = 0;
- ctlptr.maxlen = STREAM_BUF_SIZE;
- ctlptr.buf = buf;
-
- dataptr.maxlen = len;
- dataptr.len = 0;
- dataptr.buf = msg;
-
- prio = 0;
-
- ret = getmsg_timedwait(fd, &ctlptr, &dataptr, &prio, timeout);
- if (ret >= OK)
- ret = dataptr.len;
-
- return(ret);
-}
-
-/* ==========================================================================
- * recv()
- */
-ssize_t recv(int fd, void * buf, size_t len, int flags,
- struct sockaddr * from, int * from_len)
-{
- return(recv_timedwait(fd, buf, len, flags, NULL));
-}
-
-#endif
-
-#if (!defined (HAVE_SYSCALL_SETSOCKOPT)) && defined(HAVE_STREAMS)
-/* ==========================================================================
- * setsockopt()
- */
-int setsockopt(int s, int level, int optname, const void *optval, int optlen)
-{
- return(0);
-}
-#endif
-
-struct foo { /* Used by getsockname and getpeername */
- long a;
- int b;
- struct sockaddr *name;
-};
-
-#if (!defined (HAVE_SYSCALL_GETSOCKNAME)) && defined(HAVE_STREAMS)
-/* ==========================================================================
- * getsockname()
- */
-
-
-int getsockname(int s, struct sockaddr *name, int *namelen)
-{
- struct foo foo;
- int i;
- if (*namelen < sizeof(struct sockaddr)) {
- SET_ERRNO(ENOMEM);
- return(-1);
- }
- foo.a = 0x84;
- foo.b = 0;
- foo.name = name;
- i = ioctl(s, TI_GETMYNAME, &foo);
- *namelen = foo.b;
- return(i);
-}
-#endif
-
-#if (!defined (HAVE_SYSCALL_GETPEERNAME)) && defined(HAVE_STREAMS)
-/* ==========================================================================
- * getpeername() ; Added by Monty
- */
-
-int getpeername(int s, struct sockaddr *name, int *namelen)
-{
- struct foo foo;
- int i;
- if (*namelen < sizeof(struct sockaddr)) {
- SET_ERRNO(ENOMEM);
- return(-1);
- }
- foo.a = 0x84; /* Max length ? */
- foo.b = 0; /* Return length */
- foo.name = name; /* Return buffer */
- i = ioctl(s, TI_GETPEERNAME, &foo);
- *namelen = foo.b;
- return(i);
-}
-#endif
-
-
-#if (!defined (HAVE_SYSCALL_SHUTDOWN)) && defined(HAVE_STREAMS)
-/* ==========================================================================
- * shutdown()
- */
-
-int shutdown(int s, int how)
-{
- return(0);
-}
-#endif
diff --git a/mit-pthreads/pthreads/file.c b/mit-pthreads/pthreads/file.c
deleted file mode 100644
index 4b8a8aad6db..00000000000
--- a/mit-pthreads/pthreads/file.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* ==== file.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : The locking functions for stdio.
- *
- * 1.00 93/09/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdio.h>
-
-/* ==========================================================================
- * flockfile()
- */
-void flockfile(FILE *fp)
-{
- pthread_mutex_t *mutex;
- int fd, flags;
-
- if ((fd = fileno(fp)) >= 0) {
- pthread_mutex_lock(mutex = &(fd_table[fd]->mutex));
-
- if (fp->_flags & __SRW) {
- flags = FD_READ | FD_WRITE;
- } else {
- if (fp->_flags & __SWR) {
- flags = FD_WRITE;
- } else {
- flags = FD_READ;
- }
- }
-
- /* This might fail but POSIX doesn't give a damn. */
- fd_basic_lock(fd, flags, mutex, NULL);
- pthread_mutex_unlock(mutex);
- }
-}
-
-/* ==========================================================================
- * ftrylockfile()
- */
-int ftrylockfile(FILE *fp)
-{
- pthread_mutex_t *mutex;
- int fd, flags;
-
- if ((fd = fileno(fp)) >= 0) {
- pthread_mutex_lock(mutex = &(fd_table[fd]->mutex));
-
- if (fp->_flags & __SRW) {
- flags = FD_READ | FD_WRITE;
- } else {
- if (fp->_flags & __SWR) {
- flags = FD_WRITE;
- } else {
- flags = FD_READ;
- }
- }
- if (!(fd_table[fd]->r_owner && fd_table[fd]->w_owner)) {
- fd_basic_lock(fd, flags, mutex, NULL);
- fd = OK;
- } else {
- fd = NOTOK;
- }
- pthread_mutex_unlock(mutex);
- } else {
- fd = OK;
- }
- return(fd);
-}
-
-/* ==========================================================================
- * funlockfile()
- */
-void funlockfile(FILE *fp)
-{
- pthread_mutex_t *mutex;
- int fd, flags;
-
- if ((fd = fileno(fp)) >= 0) {
- pthread_mutex_lock(mutex = &(fd_table[fd]->mutex));
-
- if (fp->_flags & __SRW) {
- flags = FD_READ | FD_WRITE;
- } else {
- if (fp->_flags & __SWR) {
- flags = FD_WRITE;
- } else {
- flags = FD_READ;
- }
- }
- fd_basic_unlock(fd, flags);
- pthread_mutex_unlock(mutex);
- }
-}
-
diff --git a/mit-pthreads/pthreads/globals.c b/mit-pthreads/pthreads/globals.c
deleted file mode 100644
index 921588fb220..00000000000
--- a/mit-pthreads/pthreads/globals.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* ==== globals.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Global variables.
- *
- * 1.00 93/07/26 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/*
- * Initial thread, running thread, and top of link list of all threads.
- */
-struct pthread *pthread_run=NULL;
-struct pthread *pthread_initial=NULL;
-struct pthread *pthread_link_list=NULL;
-
-sigset_t * uthread_sigmask; /* Current process signal mask */
-
-/*
- * Dead thread queue, and threads elligible to be alloced queue.
- */
-struct pthread_queue pthread_dead_queue;
-struct pthread_queue pthread_alloc_queue;
-
-/*
- * Queue for all threads elidgeable to run this scheduling round.
- */
-struct pthread_prio_queue * pthread_current_prio_queue=NULL;
-
-/*
- * default thread attributes
- */
-pthread_attr_t pthread_attr_default = { SCHED_RR, PTHREAD_DEFAULT_PRIORITY,
- PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, PTHREAD_STACK_DEFAULT };
-
-/*
- * File table information
- */
-struct fd_table_entry **fd_table=NULL;
-
-/*
- * A we a fork()ed process
- */
-volatile int fork_lock = 0;
-volatile int pthread_kernel_lock=0;
-
-/*
- * The page size, as returned by getpagesize()
- */
-size_t pthread_pagesize=0;
-
diff --git a/mit-pthreads/pthreads/info.c b/mit-pthreads/pthreads/info.c
deleted file mode 100644
index 2b9722ba291..00000000000
--- a/mit-pthreads/pthreads/info.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* hello */
-
-#include <stdio.h>
-#include <pthread.h>
-#include <signal.h>
-
-static const char *const state_names[] = {
-#define __pthread_defstate(S,NAME) NAME,
-#include "pthread/state.def"
-#undef __pthread_defstate
- 0
-};
-
-void (*dump_thread_info_fn) (struct pthread *, FILE *);
-
-static void
-dump_thread_info (thread, file)
- struct pthread *thread;
- FILE *file;
-{
- /* machdep */
- /* attr */
- /* signals */
- /* wakeup_time */
- /* join */
- fprintf (file, " thread @%p prio %3d %s", thread,
- thread->pthread_priority, state_names[(int) thread->state]);
- switch (thread->state) {
- case PS_FDLR_WAIT:
- fprintf (file, " fd %d[%d]", thread->data.fd.fd,
- thread->data.fd.branch);
- fprintf (file, " owner %pr/%pw",
- fd_table[thread->data.fd.fd]->r_owner,
- fd_table[thread->data.fd.fd]->w_owner);
- break;
- }
- /* show where the signal handler gets run */
- if (thread == pthread_run)
- fprintf (file, "\t\t[ME!]");
- fprintf (file, "\n");
- if (dump_thread_info_fn)
- (*dump_thread_info_fn) (thread, file);
-}
-
-static void
-pthread_dump_info_to_file (file)
- FILE *file;
-{
- pthread_t t;
- for (t = pthread_link_list; t; t = t->pll)
- dump_thread_info (t, file);
-}
-
-void
-pthread_dump_info ()
-{
- if (ftrylockfile (stderr) != 0)
- return;
- fprintf (stderr, "process id %ld:\n", (long) getpid ());
- pthread_dump_info_to_file (stderr);
- funlockfile (stderr);
-}
-
-#ifdef SIGINFO
-static void
-sig_handler (sig)
- int sig;
-{
- pthread_dump_info ();
-}
-
-void
-pthread_setup_siginfo ()
-{
- (void) signal (SIGINFO, sig_handler);
-}
-#endif
diff --git a/mit-pthreads/pthreads/init.cc b/mit-pthreads/pthreads/init.cc
deleted file mode 100644
index 24a131a60a5..00000000000
--- a/mit-pthreads/pthreads/init.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-
-/*
- * DO not delete this file. The hack here ensures that pthread_init() gets
- * called before main does. This doesn't fix everything. It is still
- * possible for a c++ module to reley on constructors that need pthreads.
- */
-#include <pthread.h>
-
-char __pthread_init_hack = 42;
diff --git a/mit-pthreads/pthreads/malloc.c b/mit-pthreads/pthreads/malloc.c
deleted file mode 100644
index 76fe03824ac..00000000000
--- a/mit-pthreads/pthreads/malloc.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/* ==== malloc.c ============================================================
- * Copyright (c) 1983 Regents of the University of California.
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Malloc functions.
- * This is a very fast storage allocator. It allocates blocks of a small
- * number of different sizes, and keeps free lists of each size. Blocks that
- * don't exactly fit are passed up to the next larger size. In this
- * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
- * This is designed for use in a virtual memory environment.
- *
- * 0.00 82/02/21 Chris Kingsley kingsley@cit-20
- *
- * 1.00 93/11/06 proven
- * -Modified BSD libc malloc to be threadsafe.
- *
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <string.h>
-#include <pthread/posix.h>
-
-/*
- * The overhead on a block is at least 4 bytes. When free, this space
- * contains a pointer to the next free block, and the bottom two bits must
- * be zero. When in use, the first byte is set to MAGIC, and the second
- * byte is the size index. The remaining bytes are for alignment.
- * If range checking is enabled then a second word holds the size of the
- * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
- * The order of elements is critical: ov_magic must overlay the low order
- * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
- */
-#ifdef __alpha
-#define _MOST_RESTRICTIVE_ALIGNMENT_TYPE char*
-#else
-#define _MOST_RESTRICTIVE_ALIGNMENT_TYPE double
-#endif /* __alpha */
-union overhead {
- _MOST_RESTRICTIVE_ALIGNMENT_TYPE __alignment_pad0;
- union overhead *ov_next; /* when free */
- struct {
- u_char ovu_magic; /* magic number */
- u_char ovu_index; /* bucket # */
-#ifdef RCHECK
- u_short ovu_rmagic; /* range magic number */
- size_t ovu_size; /* actual block size */
-#endif
- } ovu;
-#define ov_magic ovu.ovu_magic
-#define ov_index ovu.ovu_index
-#define ov_rmagic ovu.ovu_rmagic
-#define ov_size ovu.ovu_size
-};
-
-#define MAGIC 0xef /* magic # on accounting info */
-#define RMAGIC 0x5555 /* magic # on range info */
-
-#ifdef RCHECK
-#define RSLOP sizeof (u_short)
-#else
-#define RSLOP 0
-#endif
-
-/*
- * nextf[i] is the pointer to the next free block of size 2^(i+3). The
- * smallest allocatable block is 8 bytes. The overhead information
- * precedes the data area returned to the user.
- */
-#define NBUCKETS 30
-static union overhead *nextf[NBUCKETS];
-#ifndef hpux
-extern char *sbrk();
-#endif
-
-static size_t pagesz; /* page size */
-static int pagebucket; /* page size bucket */
-static pthread_mutex_t malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-#if defined(DEBUG) || defined(RCHECK)
-#define ASSERT(p) if (!(p)) botch("p")
-#include <stdio.h>
-static
-botch(s)
- char *s;
-{
- fprintf(stderr, "\r\nassertion botched: %s\r\n", s);
- (void) fflush(stderr); /* just in case user buffered it */
- abort();
-}
-#else
-#define ASSERT(p)
-#endif
-
-/* ==========================================================================
- * morecore()
- *
- * Allocate more memory to the indicated bucket
- */
-static inline void morecore(int bucket)
-{
- register union overhead *op;
- register size_t sz; /* size of desired block */
- size_t amt; /* amount to allocate */
- size_t nblks; /* how many blocks we get */
-
- /*
- * sbrk_size <= 0 only for big, FLUFFY, requests (about
- * 2^30 bytes on a VAX, I think) or for a negative arg.
- */
- sz = 1L << (bucket + 3);
-#ifdef DEBUG
- ASSERT(sz > 0);
-#else
- if (sz <= 0)
- return;
-#endif
- if (sz < pagesz) {
- amt = pagesz;
- nblks = amt / sz;
- } else {
- amt = sz + pagesz;
- nblks = 1;
- }
- op = (union overhead *)sbrk(amt);
- /* no more room! */
- if (op == (union overhead *) -1)
- return;
- /*
- * Add new memory allocated to that on
- * free list for this hash bucket.
- */
- nextf[bucket] = op;
- while (--nblks > 0) {
- op->ov_next = (union overhead *)((caddr_t)op + sz);
- op = (union overhead *)((caddr_t)op + sz);
- }
-}
-
-/* ==========================================================================
- * malloc()
- */
-void *malloc(size_t nbytes)
-{
- pthread_mutex_t *mutex;
- union overhead *op;
- size_t amt;
- size_t bucket, n;
-
- mutex = &malloc_mutex;
- pthread_mutex_lock(mutex);
- /*
- * First time malloc is called, setup page size and
- * align break pointer so all data will be page aligned.
- */
- if (pagesz == 0) {
- size_t x;
- pagesz = n = getpagesize();
- op = (union overhead *)sbrk(0);
- x = sizeof (*op) - ((long)op & (n - 1));
- if (n < x)
- n = n + pagesz - x;
- else
- n = n - x;
- if (n) {
- if (sbrk(n) == (char *)-1) {
- /* Unlock before returning (mevans) */
- pthread_mutex_unlock(mutex);
- return (NULL);
- }
- }
- bucket = 0;
- amt = 8;
- while (pagesz > amt) {
- amt <<= 1;
- bucket++;
- }
- pagebucket = bucket;
- }
- /*
- * Convert amount of memory requested into closest block size
- * stored in hash buckets which satisfies request.
- * Account for space used per block for accounting.
- */
- if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) {
-#ifndef RCHECK
- amt = 8; /* size of first bucket */
- bucket = 0;
-#else
- amt = 16; /* size of first bucket */
- bucket = 1;
-#endif
- n = -(sizeof (*op) + RSLOP);
- } else {
- amt = pagesz;
- bucket = pagebucket;
- }
- while (nbytes > amt + n) {
- amt <<= 1;
- if (amt == 0) {
- pthread_mutex_unlock(mutex);
- return (NULL);
- }
- bucket++;
- }
- ASSERT (bucket < NBUCKETS);
- /*
- * If nothing in hash bucket right now,
- * request more memory from the system.
- */
- if ((op = nextf[bucket]) == NULL) {
- morecore(bucket);
- if ((op = nextf[bucket]) == NULL) {
- pthread_mutex_unlock(mutex);
- return (NULL);
- }
- }
- /* remove from linked list */
- nextf[bucket] = op->ov_next;
- op->ov_magic = MAGIC;
- op->ov_index = bucket;
-#ifdef RCHECK
- /*
- * Record allocated size of block and
- * bound space with magic numbers.
- */
- op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
- op->ov_rmagic = RMAGIC;
- *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
-#endif
- pthread_mutex_unlock(mutex);
- return ((char *)(op + 1));
-}
-
-/* ==========================================================================
- * free()
- */
-void free(void *cp)
-{
- pthread_mutex_t *mutex;
- union overhead *op;
- int size;
-
- mutex = &malloc_mutex;
- pthread_mutex_lock(mutex);
- if (cp == NULL) {
- pthread_mutex_unlock(mutex);
- return;
- }
- op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
-#ifdef DEBUG
- ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */
-#else
- if (op->ov_magic != MAGIC) {
- pthread_mutex_unlock(mutex);
- return; /* sanity */
- }
-#endif
-#ifdef RCHECK
- ASSERT(op->ov_rmagic == RMAGIC);
- ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
-#endif
- size = op->ov_index;
- ASSERT(size < NBUCKETS);
- op->ov_next = nextf[size]; /* also clobbers ov_magic */
- nextf[size] = op;
-
- pthread_mutex_unlock(mutex);
-}
-
-/* ==========================================================================
- * realloc()
- *
- * Storage compaction is no longer supported, fix program and try again.
- */
-void *realloc(void *cp, size_t nbytes)
-{
- pthread_mutex_t *mutex;
- size_t onb;
- size_t i;
- union overhead *op;
- char *res;
-
- if (cp == NULL)
- return (malloc(nbytes));
- op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
-
- if (op->ov_magic == MAGIC) {
- i = op->ov_index;
- } else {
- /*
- * This will cause old programs using storage compaction feature of
- * realloc to break in a pseudo resonable way that is easy to debug.
- * Returning a malloced buffer without the copy may cause
- * indeterministic behavior.
- */
- return(NULL);
- }
-
- mutex = &malloc_mutex;
- pthread_mutex_lock(mutex);
- onb = 1L << (i + 3);
- if (onb < pagesz)
- onb -= sizeof (*op) + RSLOP;
- else
- onb += pagesz - sizeof (*op) - RSLOP;
-
- /* avoid the copy if same size block */
- if (i) {
- i = 1L << (i + 2);
- if (i < pagesz)
- i -= sizeof (*op) + RSLOP;
- else
- i += pagesz - sizeof (*op) - RSLOP;
- }
-
- if (nbytes <= onb && nbytes > i) {
-#ifdef RCHECK
- op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
- *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
-#endif
- pthread_mutex_unlock(mutex);
- return(cp);
- }
- pthread_mutex_unlock(mutex);
-
- if ((res = malloc(nbytes)) == NULL) {
- free(cp);
- return (NULL);
- }
-
- memcpy(res, cp, (nbytes < onb) ? nbytes : onb);
- free(cp);
-
- return (res);
-}
-
-/* ==========================================================================
- * calloc()
- *
- * Added to ensure pthread's allocation is used (mevans).
- */
-void *calloc(size_t nmemb, size_t size)
-{
- void *p;
- size *= nmemb;
- p = malloc(size);
- if (p) memset(p, 0, size);
- return (p);
-}
diff --git a/mit-pthreads/pthreads/mutex.c b/mit-pthreads/pthreads/mutex.c
deleted file mode 100644
index 1a2ca6fa1c1..00000000000
--- a/mit-pthreads/pthreads/mutex.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* ==== mutex.c ==============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Mutex functions.
- *
- * 1.00 93/07/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* ==========================================================================
- * pthread_mutex_is_debug()
- *
- * Check that mutex is a debug mutex and if so returns entry number into
- * array of debug mutexes.
- */
-static int pthread_mutex_debug_count = 0;
-static pthread_mutex_t ** pthread_mutex_debug_ptrs = NULL;
-
-static inline int pthread_mutex_is_debug(pthread_mutex_t * mutex)
-{
- int i;
-
- for (i = 0; i < pthread_mutex_debug_count; i++) {
- if (pthread_mutex_debug_ptrs[i] == mutex) {
- return(i);
- }
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * pthread_mutex_init()
- *
- * In this implementation I don't need to allocate memory.
- * ENOMEM, EAGAIN should never be returned. Arch that have
- * weird constraints may need special coding.
- */
-int pthread_mutex_init(pthread_mutex_t *mutex,
- const pthread_mutexattr_t *mutex_attr)
-{
- enum pthread_mutextype type;
-
- /* Only check if attr specifies some mutex type other than fast */
- if ((mutex_attr) && (mutex_attr->m_type != MUTEX_TYPE_FAST)) {
- if (mutex_attr->m_type >= MUTEX_TYPE_MAX) {
- return(EINVAL);
- }
- type = mutex_attr->m_type;
- } else {
- type = MUTEX_TYPE_FAST;
- }
- mutex->m_flags = 0;
-
- pthread_sched_prevent();
-
- switch(type) {
- case MUTEX_TYPE_FAST:
- break;
- case MUTEX_TYPE_STATIC_FAST:
- pthread_sched_resume();
- return(EINVAL);
- break;
- case MUTEX_TYPE_COUNTING_FAST:
- mutex->m_data.m_count = 0;
- break;
- case MUTEX_TYPE_DEBUG:
- if (pthread_mutex_is_debug(mutex) == NOTOK) {
- pthread_mutex_t ** new;
-
- if ((new = (pthread_mutex_t **)realloc(pthread_mutex_debug_ptrs,
- (pthread_mutex_debug_count + 1) * (sizeof(void *)))) == NULL) {
- pthread_sched_resume();
- return(ENOMEM);
- }
- pthread_mutex_debug_ptrs = new;
- pthread_mutex_debug_ptrs[pthread_mutex_debug_count++] = mutex;
- } else {
- pthread_sched_resume();
- return(EBUSY);
- }
- break;
- default:
- pthread_sched_resume();
- return(EINVAL);
- break;
- }
- /* Set all other paramaters */
- pthread_queue_init(&mutex->m_queue);
- mutex->m_flags |= MUTEX_FLAGS_INITED;
- mutex->m_owner = NULL;
- mutex->m_type = type;
-
- pthread_sched_resume();
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_mutex_destroy()
- */
-int pthread_mutex_destroy(pthread_mutex_t *mutex)
-{
- int i;
-
- pthread_sched_prevent();
-
- /* Only check if mutex is of type other than fast */
- switch(mutex->m_type) {
- case MUTEX_TYPE_FAST:
- break;
- case MUTEX_TYPE_STATIC_FAST:
- pthread_sched_resume();
- return(EINVAL);
- break;
- case MUTEX_TYPE_COUNTING_FAST:
- mutex->m_data.m_count = 0;
- break;
- case MUTEX_TYPE_DEBUG:
- if ((i = pthread_mutex_is_debug(mutex)) == NOTOK) {
- pthread_sched_resume();
- return(EINVAL);
- }
- if (mutex->m_owner) {
- pthread_sched_resume();
- return(EBUSY);
- }
-
- /* Remove the mutex from the list of debug mutexes */
- pthread_mutex_debug_ptrs[i] =
- pthread_mutex_debug_ptrs[--pthread_mutex_debug_count];
- pthread_mutex_debug_ptrs[pthread_mutex_debug_count] = NULL;
- break;
- default:
- pthread_sched_resume();
- return(EINVAL);
- break;
- }
-
- /* Cleanup mutex, others might want to use it. */
- pthread_queue_init(&mutex->m_queue);
- mutex->m_owner = NULL;
- mutex->m_flags = 0;
-
- pthread_sched_resume();
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_mutex_trylock()
- */
-int pthread_mutex_trylock(pthread_mutex_t *mutex)
-{
- int rval;
-
- pthread_sched_prevent();
- switch (mutex->m_type) {
- /*
- * Fast mutexes do not check for any error conditions.
- */
- case MUTEX_TYPE_FAST:
- case MUTEX_TYPE_STATIC_FAST:
- if (!mutex->m_owner) {
- mutex->m_owner = pthread_run;
- rval = OK;
- } else {
- rval = EBUSY;
- }
- break;
- case MUTEX_TYPE_COUNTING_FAST:
- if (mutex->m_owner) {
- if (mutex->m_owner == pthread_run) {
- mutex->m_data.m_count++;
- rval = OK;
- } else {
- rval = EBUSY;
- }
- } else {
- mutex->m_owner = pthread_run;
- rval = OK;
- }
- break;
- case MUTEX_TYPE_DEBUG:
- if (pthread_mutex_is_debug(mutex) != NOTOK) {
- if (!mutex->m_owner) {
- mutex->m_owner = pthread_run;
- rval = OK;
- } else {
- rval = EBUSY;
- }
- } else {
- rval = EINVAL;
- }
- break;
- default:
- rval = EINVAL;
- break;
- }
-
- pthread_sched_resume();
- return(rval);
-}
-
-/* ==========================================================================
- * pthread_mutex_lock()
- */
-int pthread_mutex_lock(pthread_mutex_t *mutex)
-{
- int rval;
-
- pthread_sched_prevent();
- switch (mutex->m_type) {
- /*
- * Fast mutexes do not check for any error conditions.
- */
- case MUTEX_TYPE_FAST:
- case MUTEX_TYPE_STATIC_FAST:
- if (mutex->m_owner) {
- pthread_queue_enq(&mutex->m_queue, pthread_run);
-
- /* Reschedule will unlock scheduler */
- pthread_resched_resume(PS_MUTEX_WAIT);
- return(OK);
- }
- mutex->m_owner = pthread_run;
- rval = OK;
- break;
- case MUTEX_TYPE_COUNTING_FAST:
- if (mutex->m_owner) {
- if (mutex->m_owner != pthread_run) {
- pthread_queue_enq(&mutex->m_queue, pthread_run);
-
- /* Reschedule will unlock scheduler */
- pthread_resched_resume(PS_MUTEX_WAIT);
- return(OK);
- } else {
- mutex->m_data.m_count++;
- }
- } else {
- mutex->m_owner = pthread_run;
- }
- rval = OK;
- break;
- case MUTEX_TYPE_DEBUG:
- if (pthread_mutex_is_debug(mutex) != NOTOK) {
- if (mutex->m_owner) {
- if (mutex->m_owner != pthread_run) {
- pthread_queue_enq(&mutex->m_queue, pthread_run);
-
- /* Reschedule will unlock pthread_run */
- pthread_resched_resume(PS_MUTEX_WAIT);
-
- if (mutex->m_owner != pthread_run) {
- PANIC();
- }
- return(OK);
- }
- rval = EDEADLK;
- break;
- }
- mutex->m_owner = pthread_run;
- rval = OK;
- break;
- }
- rval = EINVAL;
- break;
- default:
- rval = EINVAL;
- break;
- }
-
- pthread_sched_resume();
- return(rval);
-}
-
-/* ==========================================================================
- * pthread_mutex_unlock()
- */
-int pthread_mutex_unlock(pthread_mutex_t *mutex)
-{
- struct pthread *pthread;
- int rval;
-
- pthread_sched_prevent();
-
- switch (mutex->m_type) {
- /*
- * Fast mutexes do not check for any error conditions.
- */
- case MUTEX_TYPE_FAST:
- case MUTEX_TYPE_STATIC_FAST:
- if (mutex->m_owner = pthread_queue_deq(&mutex->m_queue)) {
-
- /* Reschedule will unlock scheduler */
- pthread_sched_other_resume(mutex->m_owner);
- return(OK);
- }
- rval = OK;
- break;
- case MUTEX_TYPE_COUNTING_FAST:
- if (mutex->m_data.m_count) {
- mutex->m_data.m_count--;
- rval = OK;
- break;
- }
- if (mutex->m_owner = pthread_queue_deq(&mutex->m_queue)) {
-
- /* Reschedule will unlock scheduler */
- pthread_sched_other_resume(mutex->m_owner);
- return(OK);
- }
- rval = OK;
- break;
- case MUTEX_TYPE_DEBUG:
- if (pthread_mutex_is_debug(mutex) != NOTOK) {
- if (mutex->m_owner == pthread_run) {
- if (mutex->m_owner = pthread_queue_deq(&mutex->m_queue)) {
-
- /* Reschedule will unlock scheduler */
- pthread_sched_other_resume(mutex->m_owner);
- return(OK);
- }
- rval = OK;
- } else {
- rval = EPERM;
- }
- } else {
- rval = EINVAL;
- }
- break;
- default:
- rval = EINVAL;
- break;
- }
- pthread_sched_resume();
- return(rval);
-}
diff --git a/mit-pthreads/pthreads/mutexattr.c b/mit-pthreads/pthreads/mutexattr.c
deleted file mode 100644
index d045b5041a0..00000000000
--- a/mit-pthreads/pthreads/mutexattr.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* ==== mutexattr.c ===========================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Mutex functions.
- *
- * 1.00 93/07/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-
-/* ==========================================================================
- * pthread_mutexattr_init()
- */
-int pthread_mutexattr_init(pthread_mutexattr_t *attr)
-{
- attr->m_type = MUTEX_TYPE_FAST;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_mutexattr_destroy()
- */
-int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
-{
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_mutexattr_settype()
- */
-int pthread_mutexattr_settype(pthread_mutexattr_t *attr, unsigned int type)
-{
- switch(type) {
- case PTHREAD_MUTEXTYPE_FAST:
- attr->m_type = MUTEX_TYPE_FAST;
- break;
- case PTHREAD_MUTEXTYPE_RECURSIVE:
- attr->m_type = MUTEX_TYPE_COUNTING_FAST;
- break;
- case PTHREAD_MUTEXTYPE_DEBUG:
- attr->m_type = MUTEX_TYPE_DEBUG;
- break;
- default:
- return(EINVAL);
- }
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_mutexattr_gettype()
- */
-int pthread_mutexattr_gettype(pthread_mutexattr_t *attr, unsigned int * type)
-{
- *type = (unsigned int)attr->m_type;
- return(OK);
-}
diff --git a/mit-pthreads/pthreads/panic.c b/mit-pthreads/pthreads/panic.c
deleted file mode 100644
index 6b963acd651..00000000000
--- a/mit-pthreads/pthreads/panic.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ==== panic.c =======================================================
- * Copyright (c) 1996 by Larry V. Streepy, Jr.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Larry V. Streepy, Jr.
- * 4. The name of Larry V. Streepy, Jr. may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Larry V. Streepy, Jr. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Larry V. Streepy, Jr. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread kernel panic
- *
- * 02 Oct 1996 - Larry V. Streepy, Jr.
- * - Initial coding
- */
-
-#include <pthread.h>
-#include <stdio.h>
-/*----------------------------------------------------------------------
- * Function: panic_kernel
- * Purpose: print a message and panic the pthreads kernel
- * Args: file name, line number, and function
- * Returns: doesn't
- * Notes:
- *----------------------------------------------------------------------*/ void
-panic_kernel( const char *file, unsigned int line, const char *func )
-{
-#ifdef __GNUC__
- (void) fprintf( stderr, "%s:%u: %s%sPhtreads kernel panic.\n",
- file, line, func ? func : "", func ? ": " : "" );
- (void) fflush (stderr);
-#else
- (void) fprintf( stderr, "%s:%u: Phtreads kernel panic.\n", file, line );
- (void) fflush (stderr);
-#endif
- abort();
-}
diff --git a/mit-pthreads/pthreads/prio_queue.c b/mit-pthreads/pthreads/prio_queue.c
deleted file mode 100644
index d976f9cd68f..00000000000
--- a/mit-pthreads/pthreads/prio_queue.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* ==== prio_queue.c ==========================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Priority Queue functions.
- *
- * 1.00 94/09/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/* A thread when it becomes eligeble to run is placed on the run queue.
- This requires locking the kernel lock
-*/
-
-/* ==========================================================================
- * pthread_prio_queue_init()
- */
-void pthread_prio_queue_init(struct pthread_prio_queue * queue)
-{
- int i;
-
- for (i = 0; i <= PTHREAD_MAX_PRIORITY; i++) {
- queue->level[i].first = NULL;
- queue->level[i].last = NULL;
- }
- queue->next = NULL;
- queue->data = NULL;
-}
-
-/* ==========================================================================
- * pthread_priority_enq()
- */
-void pthread_prio_queue_enq(struct pthread_prio_queue * queue,
- struct pthread * pthread)
-{
- int priority = pthread->pthread_priority;
-
- if (queue->next) {
- if (queue->level[priority].first) {
- pthread->next = (queue->level[priority].last)->next;
- (queue->level[priority].last)->next = pthread;
- queue->level[priority].last = pthread;
- return;
- }
- if (priority != PTHREAD_MAX_PRIORITY) {
- int prev_priority;
- /* Find first higher priority thread queued on queue */
- for (prev_priority = priority + 1; prev_priority <=
- PTHREAD_MAX_PRIORITY; prev_priority++) {
- if (queue->level[prev_priority].first) {
- pthread->next = (queue->level[prev_priority].last)->next;
- (queue->level[prev_priority].last)->next = pthread;
- queue->level[priority].first = pthread;
- queue->level[priority].last = pthread;
- return;
- }
- }
- }
- }
- queue->level[priority].first = pthread;
- queue->level[priority].last = pthread;
- pthread->next = queue->next;
- queue->next = pthread;
-}
-
-/* ==========================================================================
- * pthread_prio_queue_deq()
- */
-struct pthread * pthread_prio_queue_deq(struct pthread_prio_queue * queue)
-{
- struct pthread * pthread;
- int priority;
-
- if (pthread = queue->next) {
- priority = queue->next->pthread_priority;
- if (queue->level[priority].first == queue->level[priority].last) {
- queue->level[priority].first = NULL;
- queue->level[priority].last = NULL;
- } else {
- queue->level[priority].first = pthread->next;
- }
- queue->next = pthread->next;
- pthread->next = NULL;
- }
- return(pthread);
-}
-
-/* ==========================================================================
- * pthread_prio_queue_remove()
- */
-int pthread_prio_queue_remove(struct pthread_prio_queue *queue,
- struct pthread *thread)
-{
- /* XXX This is slow, should start with thread priority */
- int priority = thread->pthread_priority;
- struct pthread **current = &(queue->level[priority].first);
- struct pthread *prev = NULL;
-
- if (thread==*current) {
- int current_priority=priority+1;
-
- if (*current == queue->next){
- pthread_prio_queue_deq(queue);
- thread->next = NULL;
- return(OK);
- }
- for (current_priority; current_priority <= PTHREAD_MAX_PRIORITY;
- current_priority++) {
- if (queue->level[current_priority].last) {
- queue->level[current_priority].last->next = (*current)->next;
- if ((*current)->next &&
- (*current)->next->pthread_priority == priority)
- queue->level[priority].first = (*current)->next;
- else {
- queue->level[priority].first = NULL;
- queue->level[priority].last = NULL;
- }
- thread->next = NULL;
- return(OK);
- }
- }
- }
-
- if (*current == NULL) /* Mati Sauks */
- {
- return (NOTOK);
- }
- for (prev=*current,current=&((*current)->next);
- *current && ((*current)->pthread_priority == priority);
- prev=*current,current=&((*current)->next)) {
- if (*current == thread) {
- if (*current == queue->level[priority].last) {
- queue->level[priority].last = prev;
- }
-
- *current = (*current)->next;
- thread->next=NULL;
- return(OK);
- }
- }
- return(NOTOK);
-}
-
diff --git a/mit-pthreads/pthreads/process.c b/mit-pthreads/pthreads/process.c
deleted file mode 100644
index 9b3abb3384b..00000000000
--- a/mit-pthreads/pthreads/process.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ==== process.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Process functions (fork, exec, ...).
- *
- * 1.23 94/04/18 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <unistd.h>
-#ifdef HAVE_ALLOC_H
-#include <alloc.h>
-#endif
-
-extern void *alloca();
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-/* ==========================================================================
- * fork()
- *
- * This function requires a sig_prevent()/sig_check_and_resume() for the
- * parent. The child never unlocks.
- */
-pid_t fork()
-{
- pid_t ret;
-
- pthread_sched_prevent();
-
- fd_kern_fork();
- if (ret = machdep_sys_fork()) { /* Parent or error */
- pthread_sched_resume();
- } else { /* Child */
- machdep_unset_thread_timer(NULL);
- machdep_stop_timer(NULL);
- fork_lock++;
- pthread_kernel_lock--;
- }
- return(ret);
-}
-
-#ifdef HAVE_VFORK
-/* The semantics of vfork probably won't mix well with the pthread
- library code. Don't even try. */
-pid_t vfork ()
-{
- return fork ();
-}
-#endif
-
-/* ==========================================================================
- * execve()
- *
- * This function requires a sig_prevent()/sig_check_and_resume() if one
- * hasn't been done in the fork routine. Normally machdep_sys_execve()
- * should never return.
- */
-int execve(const char *name, char * const *argv, char * const *envp)
-{
- int ret;
-
- if (!fork_lock) {
- pthread_sched_prevent();
- fd_kern_exec(0);
- ret = machdep_sys_execve(name, argv, envp);
- pthread_sched_resume();
- } else {
- fd_kern_exec(1);
- ret = machdep_sys_execve(name, argv, envp);
- }
- return(ret);
-}
-
-/* Variants of execve. Define them here so that the system versions
- don't get used and drag in the system version of execve. */
-#include <sys/stat.h>
-#include <string.h>
-#include <sys/param.h>
-extern char **environ;
-
-static const char *find (const char *name, char *buf)
-{
- char *p1, *p2;
- extern char *getenv ();
- struct stat sb;
-
- if (strchr (name, '/'))
- return name;
- p1 = getenv ("PATH");
- if (p1 == 0)
- p1 = "/bin:/usr/bin:";
- while (*p1) {
- memset (buf, 0, MAXPATHLEN);
- p2 = strchr (p1, ':');
- if (p2 == 0)
- p2 = p1 + strlen (p1);
- strncpy (buf, p1, p2 - p1);
- buf[p2 - p1] = 0;
- strcat (buf, "/");
- strcat (buf, name);
- if (lstat (buf, &sb) == 0)
- return buf;
-
- if (*p2 == ':')
- p2++;
- p1 = p2;
- }
- return name;
-}
-
-int execl (const char *path, const char *arg, ...)
-{
-#ifdef SCO_3_5
- return execve (path, (char *const *) &arg, environ);
-#else
- char ** argv;
- va_list ap;
- int i;
-
- va_start(ap, arg);
- for (i = 1; va_arg(ap, char *) != NULL; i++);
- va_end(ap);
-
- argv = alloca (i * sizeof (char *));
-
- va_start(ap, arg);
- argv[0] = (char *) arg;
- for (i = 1; (argv[i] = (char *) va_arg(ap, char *)) != NULL; i++);
- va_end(ap);
-
- return execve (path, argv, environ);
-#endif
-}
-
-int execlp (const char *name, const char *arg, ...)
-{
-#ifdef SCO_3_5
- char buf[MAXPATHLEN];
- return execve (find (name, buf), (char *const *) &arg, environ);
-#else
- char buf[MAXPATHLEN];
- char ** argv;
- va_list ap;
- int i;
-
- va_start(ap, arg);
- for (i = 1; va_arg(ap, char *) != NULL; i++);
- va_end(ap);
-
- argv = alloca (i * sizeof (char *));
-
- va_start(ap, arg);
- argv[0] = (char *) arg;
- for (i = 1; (argv[i] = (char *) va_arg(ap, char *)) != NULL; i++);
- va_end(ap);
-
- return execve (find (name, buf), argv, environ);
-#endif
-}
-
-int execle (const char *name, const char *arg, ... /* , char *const envp[] */);
-
-/* This one turns on ptrace-style tracing? */
-int exect (const char *path, char *const argv[], char *const envp[]);
-
-int execv (const char *path, char *const argv[]) {
- return execve (path, argv, environ);
-}
-
-int execvp (const char *name, char *const argv[]) {
- char buf[MAXPATHLEN];
- return execve (find (name, buf), argv, environ);
-}
diff --git a/mit-pthreads/pthreads/pthread.c b/mit-pthreads/pthreads/pthread.c
deleted file mode 100644
index 6f7e2d53980..00000000000
--- a/mit-pthreads/pthreads/pthread.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/* ==== pthread.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread functions.
- *
- * 1.00 93/07/26 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sched.h>
-
-/* ==========================================================================
- * sched_yield()
- */
-int sched_yield()
-{
- sig_handler_fake(SIGVTALRM);
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_yield()
- */
-void pthread_yield()
-{
- sig_handler_fake(SIGVTALRM);
-}
-
-/* ==========================================================================
- * pthread_self()
- */
-pthread_t pthread_self()
-{
- return(pthread_run);
-}
-
-/* ==========================================================================
- * pthread_equal()
- */
-int pthread_equal(pthread_t t1, pthread_t t2)
-{
- return(t1 == t2);
-}
-
-/* ==========================================================================
- * pthread_exit()
- */
-extern void pthread_cleanupspecific(void);
-
-void pthread_exit(void *status)
-{
- pthread_t pthread;
-
- /* Save return value */
- pthread_run->ret = status;
-
- /* First execute all cleanup handlers */
- while (pthread_run->cleanup) {
- pthread_cleanup_pop(1);
- }
-
- /* Don't forget the cleanup attr */
- if (pthread_run->attr.cleanup_attr) {
- pthread_run->attr.cleanup_attr(pthread_run->attr.arg_attr);
- }
-
- /* Next run thread-specific data desctructors */
- if (pthread_run->specific_data) {
- pthread_cleanupspecific();
- }
-
- pthread_sched_prevent();
-
- if (!(pthread_run->attr.flags & PTHREAD_DETACHED)) {
- /*
- * Are there any threads joined to this one,
- * if so wake them and let them detach this thread.
- */
- while (pthread = pthread_queue_deq(&(pthread_run->join_queue))) {
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
- pthread->state = PS_RUNNING;
- }
- pthread_queue_enq(&pthread_dead_queue, pthread_run);
- pthread_resched_resume(PS_DEAD);
- } else {
- pthread_queue_enq(&pthread_alloc_queue, pthread_run);
- pthread_resched_resume(PS_UNALLOCED);
- }
-
- /* This thread will never run again */
- PANIC();
-
-}
-
-/*----------------------------------------------------------------------
- * Function: __pthread_is_valid
- * Purpose: Scan the list of threads to see if a specified thread exists
- * Args:
- * pthread = The thread to scan for
- * Returns:
- * int = 1 if found, 0 if not
- * Notes:
- * The kernel is assumed to be locked
- *----------------------------------------------------------------------*/
-int
-__pthread_is_valid( pthread_t pthread )
-{
- int rtn = 0; /* Assume not found */
- pthread_t t;
-
- for( t = pthread_link_list; t; t = t->pll ) {
- if( t == pthread ) {
- rtn = 1; /* Found it */
- break;
- }
- }
-
- return rtn;
-}
-
-/* ==========================================================================
- * __pthread_free()
- */
-static inline void __pthread_free(pthread_t new_thread)
-{
- pthread_sched_prevent();
- new_thread->state = PS_UNALLOCED;
- new_thread->attr.stacksize_attr = 0;
- new_thread->attr.stackaddr_attr = NULL;
- pthread_queue_enq(&pthread_alloc_queue, new_thread);
- pthread_sched_resume();
-}
-/* ==========================================================================
- * __pthread_alloc()
- */
-/* static inline pthread_t __pthread_alloc(const pthread_attr_t *attr) */
-static pthread_t __pthread_alloc(const pthread_attr_t *attr)
-{
- pthread_t thread;
- void * stack;
- void * old;
-
- pthread_sched_prevent();
- thread = pthread_queue_deq(&pthread_alloc_queue);
- pthread_sched_resume();
-
- if (thread) {
- if (stack = attr->stackaddr_attr) {
- __machdep_stack_repl(&(thread->machdep_data), stack);
- } else {
- if ((__machdep_stack_get(&(thread->machdep_data)) == NULL)
- || (attr->stacksize_attr > thread->attr.stacksize_attr)) {
- if (stack = __machdep_stack_alloc(attr->stacksize_attr)) {
- __machdep_stack_repl(&(thread->machdep_data), stack);
- } else {
- __pthread_free(thread);
- thread = NULL;
- }
- }
- }
- } else {
- /* We should probable allocate several for efficiency */
- if (thread = (pthread_t)malloc(sizeof(struct pthread))) {
- /* Link new thread into list of all threads */
-
- pthread_sched_prevent();
- thread->state = PS_UNALLOCED;
- thread->pll = pthread_link_list;
- pthread_link_list = thread;
- pthread_sched_resume();
-
- if ((stack = attr->stackaddr_attr) ||
- (stack = __machdep_stack_alloc(attr->stacksize_attr))) {
- __machdep_stack_set(&(thread->machdep_data), stack);
- } else {
- __machdep_stack_set(&(thread->machdep_data), NULL);
- __pthread_free(thread);
- thread = NULL;
- }
- }
- }
- return(thread);
-}
-
-/* ==========================================================================
- * pthread_create()
- *
- * After the new thread structure is allocated and set up, it is added to
- * pthread_run_next_queue, which requires a sig_prevent(),
- * sig_check_and_resume()
- */
-int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
- void * (*start_routine)(void *), void *arg)
-{
- pthread_t new_thread;
- int nsec = 100000000;
- int retval = OK;
-
- if (! attr)
- attr = &pthread_attr_default;
-
- if (new_thread = __pthread_alloc(attr)) {
-
- __machdep_pthread_create(&(new_thread->machdep_data),
- start_routine, arg, attr->stacksize_attr, nsec, 0);
-
- memcpy(&new_thread->attr, attr, sizeof(pthread_attr_t));
- if (new_thread->attr.flags & PTHREAD_INHERIT_SCHED) {
- new_thread->pthread_priority = pthread_run->pthread_priority;
- new_thread->attr.sched_priority = pthread_run->pthread_priority;
- new_thread->attr.schedparam_policy =
- pthread_run->attr.schedparam_policy;
- } else {
- new_thread->pthread_priority = new_thread->attr.sched_priority;
- }
-
- if (!(new_thread->attr.flags & PTHREAD_NOFLOAT)) {
- machdep_save_float_state(new_thread);
- }
-
- /* Initialize signalmask */
- new_thread->sigmask = pthread_run->sigmask;
- sigemptyset(&(new_thread->sigpending));
- new_thread->sigcount = 0;
-
- pthread_queue_init(&(new_thread->join_queue));
- new_thread->specific_data = NULL;
- new_thread->specific_data_count = 0;
- new_thread->cleanup = NULL;
- new_thread->queue = NULL;
- new_thread->next = NULL;
- new_thread->flags = 0;
-
- /* PTHREADS spec says we start with cancellability on and deferred */
- SET_PF_CANCEL_STATE(new_thread, PTHREAD_CANCEL_ENABLE);
- SET_PF_CANCEL_TYPE(new_thread, PTHREAD_CANCEL_DEFERRED);
-
- new_thread->error_p = NULL;
- new_thread->sll = NULL;
-
- pthread_sched_prevent();
-
-
- pthread_sched_other_resume(new_thread);
- /*
- * Assignment must be outside of the locked pthread kernel incase
- * thread is a bogus address resulting in a seg-fault. We want the
- * original thread to be capable of handling the resulting signal.
- * --proven
- */
- (*thread) = new_thread;
- } else {
- retval = EAGAIN;
- }
- return(retval);
-}
diff --git a/mit-pthreads/pthreads/pthread_attr.c b/mit-pthreads/pthreads/pthread_attr.c
deleted file mode 100644
index 5e1c0302227..00000000000
--- a/mit-pthreads/pthreads/pthread_attr.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* ==== pthread_attr.c =======================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread attribute functions.
- *
- * 1.00 93/11/04 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-#include <string.h>
-
-/* Currently we do no locking, should we just to be safe? CAP */
-/* ==========================================================================
- * pthread_attr_init()
- */
-int pthread_attr_init(pthread_attr_t *attr)
-{
- memcpy(attr, &pthread_attr_default, sizeof(pthread_attr_t));
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_destroy()
- */
-int pthread_attr_destroy(pthread_attr_t *attr)
-{
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_getstacksize()
- */
-int pthread_attr_getstacksize(pthread_attr_t *attr, size_t * stacksize)
-{
- *stacksize = attr->stacksize_attr;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setstacksize()
- */
-int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
-{
- if (stacksize >= PTHREAD_STACK_MIN) {
- attr->stacksize_attr = stacksize;
- return(OK);
- }
- return(EINVAL);
-}
-
-/* ==========================================================================
- * pthread_attr_getstackaddr()
- */
-int pthread_attr_getstackaddr(pthread_attr_t *attr, void ** stackaddr)
-{
- *stackaddr = attr->stackaddr_attr;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setstackaddr()
- */
-int pthread_attr_setstackaddr(pthread_attr_t *attr, void * stackaddr)
-{
- attr->stackaddr_attr = stackaddr;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setcleanup()
- */
-int pthread_attr_setcleanup(pthread_attr_t *attr, void (*routine)(void *),
- void * arg)
-{
- attr->cleanup_attr = routine;
- attr->arg_attr = arg;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_getdetachstate()
- */
-int pthread_attr_getdetachstate(pthread_attr_t *attr, int * detachstate)
-{
- *detachstate = attr->flags & PTHREAD_DETACHED;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setdetachstate()
- */
-int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
-{
- attr->flags = (attr->flags & ~(PTHREAD_DETACHED)) |
- (detachstate & PTHREAD_DETACHED);
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_getfloatstate()
- */
-int pthread_attr_getfloatstate(pthread_attr_t *attr, int * floatstate)
-{
- *floatstate = attr->flags & PTHREAD_NOFLOAT;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setfloatstate()
- */
-int pthread_attr_setfloatstate(pthread_attr_t *attr, int floatstate)
-{
- attr->flags = (attr->flags & ~(PTHREAD_NOFLOAT)) |
- (floatstate & PTHREAD_NOFLOAT);
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_getscope()
- */
-int pthread_attr_getscope(pthread_attr_t *attr, int * contentionscope)
-{
- *contentionscope = attr->flags & PTHREAD_SCOPE_SYSTEM;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setscope()
- */
-int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
-{
- int ret;
-
- switch (contentionscope) {
- case PTHREAD_SCOPE_PROCESS:
- attr->flags = (attr->flags & ~(PTHREAD_SCOPE_PROCESS))
- | PTHREAD_SCOPE_PROCESS;
- ret = OK;
- break;
- case PTHREAD_SCOPE_SYSTEM:
- ret = ENOSYS;
- break;
- default:
- ret = EINVAL;
- break;
- }
-
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_attr_getinheritsched()
- */
-int pthread_attr_getinheritsched(pthread_attr_t *attr, int * inheritsched)
-{
- *inheritsched = attr->flags & PTHREAD_INHERIT_SCHED;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setinheritsched()
- */
-int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
-{
- attr->flags = (attr->flags & ~(PTHREAD_INHERIT_SCHED)) |
- (inheritsched & PTHREAD_INHERIT_SCHED);
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_getschedpolicy()
- */
-int pthread_attr_getschedpolicy(pthread_attr_t *attr, int * schedpolicy)
-{
- *schedpolicy = (int)attr->schedparam_policy;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setschedpolicy()
- */
-int pthread_attr_setschedpolicy(pthread_attr_t *attr, int schedpolicy)
-{
- int ret;
-
- switch(schedpolicy) {
- case SCHED_FIFO:
- case SCHED_IO:
- case SCHED_RR:
- attr->schedparam_policy = schedpolicy;
- ret = OK;
- break;
- default:
- ret = EINVAL;
- break;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_attr_getschedparam()
- */
-int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param * param)
-{
- param->sched_priority = attr->sched_priority;
- return(OK);
-}
-
-/* ==========================================================================
- * pthread_attr_setschedparam()
- */
-int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param * param)
-{
- if ((param->sched_priority >= PTHREAD_MIN_PRIORITY) &&
- (param->sched_priority <= PTHREAD_MAX_PRIORITY)) {
- attr->sched_priority = param->sched_priority;
- return(OK);
- }
- return(EINVAL);
-}
-
diff --git a/mit-pthreads/pthreads/pthread_cancel.c b/mit-pthreads/pthreads/pthread_cancel.c
deleted file mode 100644
index 4191a269027..00000000000
--- a/mit-pthreads/pthreads/pthread_cancel.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/* ==== pthread_cancel.c ====================================================
- * Copyright (c) 1996 by Larry V. Streepy, Jr.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Larry V. Streepy, Jr.
- * 4. The name of Larry V. Streepy, Jr. may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Larry V. Streepy, Jr. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Larry V. Streepy, Jr. BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread_cancel operations
- *
- * 27 Sep 1996 - Larry V. Streepy, Jr.
- * - Initial coding
- */
-#ifndef lint
-static const char rcsid[] = "$Id:";
-#endif
-#include <pthread.h>
-#include <errno.h>
-static void possiblyMakeRunnable( pthread_t pthread );
-
-/*----------------------------------------------------------------------
- * Function: pthread_cancel
- * Purpose: Allows a thread to request that it or another thread
- * terminate execution
- * Args:
- * thread = thread to mark as cancelled
- * Returns:
- * int 0 = ok, -1 = some error (see errno)
- * Notes:
- * The thread is simply marked as CANCELLED, it is up to the cancelled
- * thread to decide how to handle it.
- *----------------------------------------------------------------------*/ int
-pthread_cancel( pthread_t pthread )
-{
- int rtn = 0; /* Assume all ok */
- pthread_sched_prevent();
- /* Ensure they gave us a legal pthread pointer */
- if( ! __pthread_is_valid( pthread ) ) {
- rtn = ESRCH; /* No such thread */
- } else if( pthread->state == PS_UNALLOCED || pthread->state == PS_DEAD ) {
- /* The standard doesn't call these out as errors, so return 0 */
- rtn = 0;
- } else {
- SET_PF_CANCELLED(pthread); /* Set the flag */
- /* If the thread is in the right state, then stick it on the
- * run queue so it will get a chance to process the cancel.
- */
- if( pthread != pthread_run ) {
- possiblyMakeRunnable( pthread );
- }
- }
- pthread_sched_resume();
- if( rtn == 0 )
- pthread_testcancel(); /* See if we cancelled ourself */
- return rtn;
-}
-
-/*----------------------------------------------------------------------
- * Function: pthread_setcancelstate
- * Purpose: Set the current thread's cancellability state
- * Args:
- * state = PTHREAD_CANCEL_DISABLE or PTHREAD_CANCEL_ENABLE
- * oldstate= pointer to holder for old state or NULL (*MODIFIED*)
- * Returns:
- * int 0 = ok
- * EINVAL = state is neither of the legal states
- * Notes:
- * This has to be async-cancel safe, so we prevent scheduling in
- * here
- *----------------------------------------------------------------------*/
-
-int
-pthread_setcancelstate( int newstate, int *oldstate )
-{
- int ostate = TEST_PF_CANCEL_STATE(pthread_run);
- int rtn = 0;
- pthread_sched_prevent();
- if( newstate == PTHREAD_CANCEL_ENABLE ||
- newstate == PTHREAD_CANCEL_DISABLE ) {
- SET_PF_CANCEL_STATE(pthread_run, newstate);
- if( oldstate != NULL )
- *oldstate = ostate;
- } else { /* Invalid new state */
- rtn = EINVAL;
- }
- pthread_sched_resume();
- if( rtn == 0 ) {
- /* Test to see if we have a pending cancel to handle */
- pthread_testcancel();
- }
- return rtn;
-}
-
-/*----------------------------------------------------------------------
- * Function: pthread_setcanceltype
- * Purpose: Set the current thread's cancellability type
- * Args:
- * type = PTHREAD_CANCEL_DEFERRED or PTHREAD_CANCEL_ASYNCHRONOUS
- * oldtype = pointer to holder for old type or NULL (*MODIFIED*)
- * Returns:
- * int 0 = ok
- * EINVAL = type is neither of the legal states
- * Notes:
- * This has to be async-cancel safe, so we prevent scheduling in
- * here
- *----------------------------------------------------------------------*/
-
-int
-pthread_setcanceltype( int newtype, int *oldtype )
-{
- int otype = TEST_PF_CANCEL_TYPE(pthread_run);
- int rtn = 0;
- pthread_sched_prevent();
- if( newtype == PTHREAD_CANCEL_DEFERRED ||
- newtype == PTHREAD_CANCEL_ASYNCHRONOUS) {
- SET_PF_CANCEL_TYPE(pthread_run, newtype);
- if( oldtype != NULL )
- *oldtype = otype;
- } else { /* Invalid new type */
- rtn = EINVAL;
- }
- pthread_sched_resume();
- if( rtn == 0 ) {
- /* Test to see if we have a pending cancel to handle */
- pthread_testcancel();
- }
- return rtn;
-}
-
-/*----------------------------------------------------------------------
- * Function: pthread_testcancel
- * Purpose: Requests delivery of a pending cancel to the current thread
- * Args: void
- * Returns: void
- * Notes:
- * If the current thread has been cancelled, this function will not
- * return and the threads exit processing will be initiated.
- *----------------------------------------------------------------------*/
-
-void
-pthread_testcancel( void )
-{
- if( TEST_PF_CANCEL_STATE(pthread_run) == PTHREAD_CANCEL_DISABLE ) {
- return; /* Can't be cancelled */
- }
- /* Ensure that we aren't in the process of exiting already */
- if( TEST_PF_RUNNING_TO_CANCEL(pthread_run) )
- return;
-
- /* See if we have been cancelled */
- if( TEST_PF_CANCELLED(pthread_run) ) {
- /* Set this flag to avoid recursively calling pthread_exit */
- SET_PF_RUNNING_TO_CANCEL(pthread_run);
- pthread_exit( PTHREAD_CANCELLED ); /* Easy - just call pthread_exit */
- }
- return; /* Not cancelled */
-}
-
-/*----------------------------------------------------------------------
- * Function: pthread_cancel_internal
- * Purpose: An internal routine to begin the cancel processing
- * Args: freelocks = do we need to free locks before exiting
- * Returns: void
- * Notes:
- * This routine is called from pthread_resched_resume
- * prior to a context switch, and after a thread has resumed.
- *
- * The kernel must *NOT* be locked on entry here
- *----------------------------------------------------------------------*/
-
-void
-pthread_cancel_internal( int freelocks )
-{
- pthread_sched_prevent(); /* gotta stay focused */
- /* Since we can be called from pthread_resched_resume(), our
- * state is currently not PS_RUNNING. Since we side stepped
- * the actually blocking, we need to be removed from the queue
- * and marked as running.
- */
- if( pthread_run->state != PS_RUNNING ) {
- if( pthread_run->queue == NULL ) {
- PANIC(); /* Must be on a queue */
- }
- /* We MUST NOT put the thread on the prio_queue here. It
- * is already running (although it's state has changed) and if we
- * put it on the run queue, it will get resumed after it is dead
- * and we end up with a nice panic.
- */
- pthread_queue_remove(pthread_run->queue, pthread_run);
- pthread_run->state = PS_RUNNING; /* we are running */
- }
- /* Set this flag to avoid recursively calling pthread_exit */
- SET_PF_RUNNING_TO_CANCEL(pthread_run);
- /* Free up any locks we hold if told to. */
- if( freelocks ) {
- fd_unlock_for_cancel();
- }
- pthread_sched_resume();
- pthread_exit( PTHREAD_CANCELLED ); /* Easy - just call pthread_exit */
-}
-
-/*----------------------------------------------------------------------
- * Function: possiblyMakeRunnable
- * Purpose: Make a thread runnable so it can be cancelled if state allows
- * Args:
- * pthread = thread to process
- * Returns:
- * Notes:
- *----------------------------------------------------------------------*/
-
-static void
-possiblyMakeRunnable( pthread_t pthread )
-{
- if( ! TEST_PTHREAD_IS_CANCELLABLE(pthread) )
- return; /* Not currently cancellable */
- /* If the thread is currently runnable, then we just let things
- * take their course when it is next resumed.
- */
- if( pthread->state == PS_RUNNING )
- return; /* will happen at context switch */
- /* If the thread is sleeping, the it isn't on a queue. */
- if( pthread->state == PS_SLEEP_WAIT ) {
- sleep_cancel( pthread ); /* Remove from sleep list */
- } else {
- /* Otherwise, we need to take it off the queue and make it runnable */
- if( pthread->queue == NULL ) {
- PANIC(); /* Must be on a queue */
- }
- pthread_queue_remove(pthread->queue, pthread);
- }
- /* And make it runnable */
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
- pthread->old_state = pthread->state;
- pthread->state = PS_RUNNING;
-}
diff --git a/mit-pthreads/pthreads/pthread_detach.c b/mit-pthreads/pthreads/pthread_detach.c
deleted file mode 100644
index d3ae8c03bb3..00000000000
--- a/mit-pthreads/pthreads/pthread_detach.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ==== pthread_detach.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread_join function.
- *
- * 1.00 94/01/15 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <errno.h>
-#include <pthread.h>
-
-/* ==========================================================================
- * pthread_detach()
- */
-int pthread_detach(pthread_t pthread)
-{
- struct pthread * next_thread, * high_thread, * low_thread;
- int ret;
-
- pthread_sched_prevent();
-
- /* Check that thread isn't detached already */
- if (!(pthread->attr.flags & PTHREAD_DETACHED)) {
-
- pthread->attr.flags |= PTHREAD_DETACHED;
-
- /* Wakeup all threads waiting on a join */
- if (next_thread = pthread_queue_deq(&(pthread->join_queue))) {
- high_thread = next_thread;
-
- while (next_thread = pthread_queue_deq(&(pthread->join_queue))) {
- if (high_thread->pthread_priority < next_thread->pthread_priority) {
- low_thread = high_thread;
- high_thread = next_thread;
- } else {
- low_thread = next_thread;
- }
- pthread_prio_queue_enq(pthread_current_prio_queue, low_thread);
- low_thread->state = PS_RUNNING;
- }
- /* If the thread is dead then move it to the alloc queue */
- if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
- pthread_queue_enq(&pthread_alloc_queue, pthread);
- }
- pthread_sched_other_resume(high_thread);
- return(OK);
- }
- /* If the thread is dead then move it to the alloc queue */
- if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
- pthread_queue_enq(&pthread_alloc_queue, pthread);
- pthread->state = PS_UNALLOCED;
- }
- ret = OK;
- } else {
- ret = ESRCH;
- }
- pthread_sched_resume();
- return(ret);
-}
diff --git a/mit-pthreads/pthreads/pthread_init.c b/mit-pthreads/pthreads/pthread_init.c
deleted file mode 100644
index 83e19fe0229..00000000000
--- a/mit-pthreads/pthreads/pthread_init.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* ==== pthread_init.c ========================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread_init routine.
- *
- * 1.00 94/09/20 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * errno is declared here to prevent the linker from pulling in errno
- * from the C library (and whatever else is in that file). I also use
- * errno as the default location for error numbers for the initial thread
- * giving some backwards compatibility.
- */
-#ifdef errno
-#undef errno
-#endif
-
-#if !defined(M_UNIX)
-int errno;
-#else
-extern int errno;
-#endif
-
-/* ==========================================================================
- * pthread_init()
- *
- * We use features of the C++ linker to make sure this function is called
- * before anything else is done in the program. See init.cc.
- */
-void pthread_init(void)
-{
- struct machdep_pthread machdep_data = MACHDEP_PTHREAD_INIT;
-
- /* Only call this once */
- if (pthread_initial) {
- return;
- }
-
- pthread_pagesize = getpagesize();
-
- /* Initialize the first thread */
- if ((pthread_initial = (pthread_t)malloc(sizeof(struct pthread))) &&
- (pthread_current_prio_queue = (struct pthread_prio_queue *)
- malloc(sizeof(struct pthread_prio_queue)))) {
- memcpy(&(pthread_initial->machdep_data), &machdep_data,
- sizeof(machdep_data));
- memcpy(&pthread_initial->attr, &pthread_attr_default,
- sizeof(pthread_attr_t));
-
- pthread_initial->pthread_priority = PTHREAD_DEFAULT_PRIORITY;
- pthread_initial->state = PS_RUNNING;
-
- pthread_queue_init(&(pthread_initial->join_queue));
- pthread_initial->specific_data = NULL;
- pthread_initial->specific_data_count = 0;
- pthread_initial->cleanup = NULL;
- pthread_initial->queue = NULL;
- pthread_initial->next = NULL;
- pthread_initial->flags = 0;
- pthread_initial->pll = NULL;
- pthread_initial->sll = NULL;
-
- /* PTHREADS spec says we start with cancellability on and deferred */
- SET_PF_CANCEL_STATE(pthread_initial, PTHREAD_CANCEL_ENABLE);
- SET_PF_CANCEL_TYPE(pthread_initial, PTHREAD_CANCEL_DEFERRED);
-
-
- /* Ugly errno hack */
- pthread_initial->error_p = &errno;
- pthread_initial->error = 0;
-
- pthread_prio_queue_init(pthread_current_prio_queue);
- pthread_link_list = pthread_initial;
- pthread_run = pthread_initial;
-
- uthread_sigmask = &(pthread_run->sigmask);
-
- /* XXX can I assume the mask and pending siganl sets are empty. */
- sigemptyset(&(pthread_initial->sigpending));
- sigemptyset(&(pthread_initial->sigmask));
- pthread_initial->sigcount = 0;
-
- /* Initialize the signal handler. */
- sig_init();
-
- /* Initialize the fd table. */
- fd_init();
-
- /* Start the scheduler */
- machdep_set_thread_timer(&(pthread_run->machdep_data));
-#ifdef M_UNIX
- machdep_sys_init();
-#endif
- return;
- }
- PANIC();
-}
diff --git a/mit-pthreads/pthreads/pthread_join.c b/mit-pthreads/pthreads/pthread_join.c
deleted file mode 100644
index 879250020a1..00000000000
--- a/mit-pthreads/pthreads/pthread_join.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* ==== pthread_join.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread_join function.
- *
- * 1.00 94/01/15 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-
-static int testDeadlock( struct pthread_queue *queue, pthread_t target );
-
-/* ==========================================================================
- * pthread_join()
- */
-int pthread_join(pthread_t pthread, void **thread_return)
-{
- int ret;
-
- pthread_sched_prevent();
-
- /* Ensure they gave us a legal pthread pointer */
- if( ! __pthread_is_valid( pthread ) ) {
- pthread_sched_resume();
- return(EINVAL);
- }
-
- /* Check that thread isn't detached already */
- if (pthread->attr.flags & PTHREAD_DETACHED) {
- pthread_sched_resume();
- return(ESRCH);
- }
-
- /*
- * Now check if other thread has exited
- * Note: This must happen after checking detached state.
- */
- if (pthread_queue_remove(&pthread_dead_queue, pthread) != OK) {
-
- /* Before we pend on the join, ensure there is no dead lock */
-
- if( testDeadlock( &pthread_run->join_queue, pthread ) == NOTOK ) {
- ret = EDEADLK;
- } else {
- pthread_queue_enq(&(pthread->join_queue), pthread_run);
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_JOIN);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- pthread_sched_prevent();
-
- if (pthread_queue_remove(&pthread_dead_queue, pthread) == OK) {
- pthread_queue_enq(&pthread_alloc_queue, pthread);
- pthread->attr.flags |= PTHREAD_DETACHED;
- pthread->state = PS_UNALLOCED;
- if (thread_return) {
- *thread_return = pthread->ret;
- }
- ret = OK;
- } else {
- ret = ESRCH;
- }
- }
- } else {
- /* Just get the return value and detach the thread */
- pthread_queue_enq(&pthread_alloc_queue, pthread);
- pthread->attr.flags |= PTHREAD_DETACHED;
- pthread->state = PS_UNALLOCED;
- if (thread_return) {
- *thread_return = pthread->ret;
- }
- ret = OK;
- }
- pthread_sched_resume();
- return(ret);
-}
-
-/*----------------------------------------------------------------------
- * Function: testDeadlock
- * Purpose: recursive queue walk to check for deadlocks
- * Args:
- * queue = the queue to walk
- * pthread = target to scan for
- * Returns:
- * OK = no deadlock, NOTOK = deadlock
- * Notes:
- *----------------------------------------------------------------------*/
-static int
-testDeadlock( struct pthread_queue *queue, pthread_t target )
-{
- pthread_t t;
-
- if( queue == NULL )
- return OK; /* Empty queue, obviously ok */
-
- for( t = queue->q_next; t; t = t->next ) {
- if( t == target )
- return NOTOK; /* bang, your dead */
-
- if( testDeadlock( &t->join_queue, target ) == NOTOK ) {
- return NOTOK;
- }
- }
-
- return OK; /* No deadlock */
-}
diff --git a/mit-pthreads/pthreads/pthread_kill.c b/mit-pthreads/pthreads/pthread_kill.c
deleted file mode 100644
index 9e3e61488a3..00000000000
--- a/mit-pthreads/pthreads/pthread_kill.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* ==== pthread_kill.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread_kill function.
- *
- * 1.32 94/06/12 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/* Defined in sig.c, a linked list of threads currently
- * blocked in sigwait(): */
-extern struct pthread * pthread_sigwait;
-
-
-/* ==========================================================================
- * pthread_kill()
- */
-int pthread_kill(struct pthread * pthread, int sig)
-{
- struct pthread ** pthread_ptr;
-
- pthread_sched_prevent();
-
- /* Check who is the current owner of pthread */
-/* if (pthread->kthread != pthread_run->kthread) { */
- if (0) {
- } else {
- if (pthread->state == PS_SIGWAIT) {
- if(sigismember(pthread->data.sigwait, sig)) {
- for (pthread_ptr = &pthread_sigwait;
- (*pthread_ptr);
- pthread_ptr = &((*pthread_ptr)->next)) {
- if ((*pthread_ptr) == pthread) {
-
- /* Take the thread out of the
- * pthread_sigwait linked list: */
- *pthread_ptr=(*pthread_ptr)->next;
-
- *(int *)(pthread->ret) = sig;
- pthread_sched_other_resume(pthread);
- return(OK);
- }
- }
- /* A thread should not be in the state PS_SIGWAIT
- * without being in the pthread_sigwait linked
- * list: */
- PANIC();
- }
- }
- if (!sigismember(&pthread->sigpending,sig)) /* Added by monty */
- {
- sigaddset(&(pthread->sigpending), sig);
- pthread->sigcount++;
- }
- }
-
- pthread_sched_resume();
- return(OK);
-}
diff --git a/mit-pthreads/pthreads/pthread_once.c b/mit-pthreads/pthreads/pthread_once.c
deleted file mode 100644
index 0a3dcd23fae..00000000000
--- a/mit-pthreads/pthreads/pthread_once.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==== pthread_once.c =======================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : pthread_once function.
- *
- * 1.00 93/12/12 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/* ==========================================================================
- * pthread_once()
- */
-int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
-{
- /* Check first for speed */
- if (once_control->state == PTHREAD_NEEDS_INIT) {
- pthread_mutex_lock(&(once_control->mutex));
- if (once_control->state == PTHREAD_NEEDS_INIT) {
- init_routine();
- once_control->state = PTHREAD_DONE_INIT;
- }
- pthread_mutex_unlock(&(once_control->mutex));
- }
- return(OK);
-}
diff --git a/mit-pthreads/pthreads/queue.c b/mit-pthreads/pthreads/queue.c
deleted file mode 100644
index c33774bf4dd..00000000000
--- a/mit-pthreads/pthreads/queue.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* ==== queue.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Queue functions.
- *
- * 1.00 93/07/15 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-
-/*
- * All routines in this file assume that the queue has been appropriatly
- * locked.
- */
-
-/* ==========================================================================
- * pthread_queue_init()
- */
-void pthread_queue_init(struct pthread_queue *queue)
-{
- queue->q_next = NULL;
- queue->q_last = NULL;
- queue->q_data = NULL;
-}
-
-/* ==========================================================================
- * pthread_queue_enq()
- */
-void pthread_queue_enq(struct pthread_queue *queue, struct pthread *thread)
-{
- if (queue->q_last) {
- queue->q_last->next = thread;
- } else {
- queue->q_next = thread;
- }
- queue->q_last = thread;
- thread->queue = queue;
- thread->next = NULL;
-
-}
-
-/* ==========================================================================
- * pthread_queue_get()
- */
-struct pthread *pthread_queue_get(struct pthread_queue *queue)
-{
- return(queue->q_next);
-}
-
-/* ==========================================================================
- * pthread_queue_deq()
- */
-struct pthread *pthread_queue_deq(struct pthread_queue *queue)
-{
- struct pthread *thread = NULL;
-
- if (queue->q_next) {
- thread = queue->q_next;
- if (!(queue->q_next = queue->q_next->next)) {
- queue->q_last = NULL;
- }
- thread->queue = NULL;
- thread->next = NULL;
- }
- return(thread);
-}
-
-/* ==========================================================================
- * pthread_queue_remove()
- */
-int pthread_queue_remove(struct pthread_queue *queue, struct pthread *thread)
-{
- struct pthread **current = &(queue->q_next);
- struct pthread *prev = NULL;
- int ret = NOTOK;
-
- while (*current) {
- if (*current == thread) {
- if ((*current)->next) {
- *current = (*current)->next;
- } else {
- queue->q_last = prev;
- *current = NULL;
- }
- thread->queue = NULL;
- thread->next = NULL;
- ret = OK;
- break;
- }
- prev = *current;
- current = &((*current)->next);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_llist_remove()
- */
-int pthread_llist_remove(struct pthread **llist, struct pthread *thread)
-{
- while (*llist) {
- if (*llist == thread) {
- *llist = thread->next;
- return(OK);
- }
- llist = &(*llist)->next;
- }
- return(NOTOK);
-}
-
diff --git a/mit-pthreads/pthreads/readv.c b/mit-pthreads/pthreads/readv.c
deleted file mode 100644
index fd63d31cf94..00000000000
--- a/mit-pthreads/pthreads/readv.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* ==== readv.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Implementation of readv().
- *
- * 1.00 95/06/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-
-#ifndef HAVE_SYSCALL_READV
-
-#include <errno.h>
-#include <unistd.h>
-#include <sys/uio.h>
-#include <sys/types.h>
-
-/* ==========================================================================
- * machdep_sys_readv()
- */
-int machdep_sys_readv(int fd, struct iovec * vector, int count)
-{
- size_t bytes, i;
- char *buffer;
- int ret = 0;
-
- /* Find the total number of bytes to be read. */
- for (bytes = 0, i = 0; i < count; ++i)
- bytes += vector[i].iov_len;
-
- if (bytes) {
- /*
- * Allocate a temporary buffer to hold the data.
- * Don't use alloca because threads tend to have smaller stacks.
- */
- if ((buffer = (char *)malloc(bytes)) == NULL) {
- return(-ENOMEM);
- }
- ret = (int)machdep_sys_read(fd, buffer, bytes);
-
- /* Copy the data from memory specified by VECTOR to BUFFER */
- for (i = 0, bytes = 0; ret > 0; ret -= vector[i].iov_len) {
- memcpy(vector[i].iov_base, buffer + bytes,
- ret > vector[i].iov_len ? vector[i].iov_len : ret);
- bytes += vector[i].iov_len;
- }
- free(buffer);
- }
- return(ret);
-}
-
-#endif
diff --git a/mit-pthreads/pthreads/schedparam.c b/mit-pthreads/pthreads/schedparam.c
deleted file mode 100644
index b4b28577022..00000000000
--- a/mit-pthreads/pthreads/schedparam.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* ==== schedparam.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread schedparam functions.
- *
- * 1.38 94/06/15 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <sched.h>
-#include <errno.h>
-
-/* ==========================================================================
- * sched_get_priority_max
- */
-int sched_get_priority_max(int policy)
-{
- return PTHREAD_MAX_PRIORITY;
-}
-
-/* ==========================================================================
- * sched_get_priority_min
- */
-int sched_get_priority_min(int policy)
-{
- return PTHREAD_MIN_PRIORITY;
-}
-
-/* Currently only policy is supported */
-/* ==========================================================================
- * pthread_setschedparam()
- */
-int pthread_setschedparam(pthread_t pthread, int policy,
- struct sched_param * param)
-{
- enum schedparam_policy new_policy, old_policy;
- int ret = OK;
- int prio;
-
- new_policy = policy;
- pthread_sched_prevent();
- old_policy = pthread->attr.schedparam_policy;
-
- if (param) {
- if ((param->sched_priority < PTHREAD_MIN_PRIORITY) ||
- (param->sched_priority > PTHREAD_MAX_PRIORITY)) {
- pthread_sched_resume();
- return(EINVAL);
- }
- prio = param->sched_priority;
- } else {
- prio = pthread->pthread_priority;
- }
-
- if (pthread == pthread_run) {
- switch(new_policy) {
- case SCHED_RR:
- pthread->attr.schedparam_policy = new_policy;
- switch (old_policy) {
- case SCHED_FIFO:
- machdep_unset_thread_timer(NULL);
- default:
- pthread->pthread_priority = prio;
- break;
- }
- break;
- case SCHED_FIFO:
- pthread->attr.schedparam_policy = new_policy;
- switch (old_policy) {
- case SCHED_IO:
- case SCHED_RR:
- if (pthread->pthread_priority < prio) {
- pthread->pthread_priority = prio;
- pthread_sched_resume();
- pthread_yield();
- return(OK);
- }
- default:
- pthread->pthread_priority = prio;
- break;
- }
- break;
- case SCHED_IO:
- pthread->attr.schedparam_policy = new_policy;
- switch (old_policy) {
- case SCHED_FIFO:
- machdep_unset_thread_timer(NULL);
- default:
- pthread->pthread_priority = prio;
- break;
- }
- break;
- default:
- SET_ERRNO(EINVAL);
- ret = EINVAL;
- break;
- }
- } else {
- switch(new_policy) {
- case SCHED_FIFO:
- case SCHED_IO:
- case SCHED_RR:
- if(pthread_prio_queue_remove(pthread_current_prio_queue,pthread) == OK) {
- pthread->attr.schedparam_policy = new_policy;
- pthread->pthread_priority = prio;
- pthread_sched_other_resume(pthread);
- } else {
- pthread->attr.schedparam_policy = new_policy;
- pthread->pthread_priority = prio;
- pthread_sched_resume();
- }
- return(OK);
- break;
- default:
- SET_ERRNO(EINVAL);
- ret = EINVAL;
- break;
- }
- }
-
- pthread_sched_resume();
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_getschedparam()
- */
-int pthread_getschedparam(pthread_t pthread, int * policy,
- struct sched_param * param)
-{
- *policy = pthread->attr.schedparam_policy;
- if (param) {
- param->sched_priority = pthread->pthread_priority;
- }
- return(OK);
-}
-
diff --git a/mit-pthreads/pthreads/select.c b/mit-pthreads/pthreads/select.c
deleted file mode 100644
index eaafce31f19..00000000000
--- a/mit-pthreads/pthreads/select.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* ==== select.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This code based on code contributed by
- * Peter Hofmann <peterh@prz.tu-berlin.d400.de>
- *
- * Description : Select.
- *
- * 1.23 94/04/26 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <string.h>
-#include <errno.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/time.h>
-
-extern struct pthread_queue fd_wait_select;
-static struct timeval zero_timeout = { 0, 0 }; /* Moved by monty */
-
-/* ==========================================================================
- * select()
- */
-int select(int numfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
-{
- fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */
- fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p;
- fd_set read_locks, write_locks, rdwr_locks;
- struct timespec timeout_time, current_time;
- int i, j, ret = 0, got_all_locks = 1;
- struct pthread_select_data data;
-
- if (numfds > dtablesize) {
- numfds = dtablesize;
- }
-
- data.nfds = 0;
- FD_ZERO(&data.readfds);
- FD_ZERO(&data.writefds);
- FD_ZERO(&data.exceptfds);
-
- /* Do this first */
- if (timeout) {
- machdep_gettimeofday(&current_time);
- timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec;
- if ((timeout_time.tv_nsec = current_time.tv_nsec +
- (timeout->tv_usec * 1000)) > 1000000000) {
- timeout_time.tv_nsec -= 1000000000;
- timeout_time.tv_sec++;
- }
- }
-
- FD_ZERO(&read_locks);
- FD_ZERO(&write_locks);
- FD_ZERO(&rdwr_locks);
- FD_ZERO(&real_readfds);
- FD_ZERO(&real_writefds);
- FD_ZERO(&real_exceptfds);
-
- /* lock readfds */
- if (readfds || writefds || exceptfds) {
- for (i = 0; i < numfds; i++) {
- if ((readfds && (FD_ISSET(i, readfds))) ||
- (exceptfds && FD_ISSET(i, exceptfds))) {
- if (writefds && FD_ISSET(i ,writefds)) {
- if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) {
- got_all_locks = 0;
- break;
- }
- FD_SET(i, &rdwr_locks);
- FD_SET(fd_table[i]->fd.i,&real_writefds);
- } else {
- if ((ret = fd_lock(i, FD_READ, NULL)) != OK) {
- got_all_locks = 0;
- break;
- }
- FD_SET(i, &read_locks);
- }
- if (readfds && FD_ISSET(i,readfds)) {
- FD_SET(fd_table[i]->fd.i, &real_readfds);
- }
- if (exceptfds && FD_ISSET(i,exceptfds)) {
- FD_SET(fd_table[i]->fd.i, &real_exceptfds);
- }
- if (fd_table[i]->fd.i >= data.nfds) {
- data.nfds = fd_table[i]->fd.i + 1;
- }
- } else {
- if (writefds && FD_ISSET(i, writefds)) {
- if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) {
- got_all_locks = 0;
- break;
- }
- FD_SET(i, &write_locks);
- FD_SET(fd_table[i]->fd.i,&real_writefds);
- if (fd_table[i]->fd.i >= data.nfds) {
- data.nfds = fd_table[i]->fd.i + 1;
- }
- }
- }
- }
- }
-
- if (got_all_locks)
- {
- memcpy(&data.readfds,&real_readfds,sizeof(fd_set));
- memcpy(&data.writefds,&real_writefds,sizeof(fd_set));
- memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set));
-
- real_readfds_p = (readfds == NULL) ? NULL : &real_readfds;
- real_writefds_p = (writefds == NULL) ? NULL : &real_writefds;
- real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds;
-
- pthread_run->sighandled=0;
- if ((ret = machdep_sys_select(data.nfds, real_readfds_p,
- real_writefds_p, real_exceptfds_p,
- &zero_timeout)) == OK) {
- pthread_sched_prevent();
-
- real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds;
- real_writefds_p = (writefds == NULL) ? NULL : &data.writefds;
- real_readfds_p = (readfds == NULL) ? NULL : &data.readfds;
-
- pthread_queue_enq(&fd_wait_select, pthread_run);
- pthread_run->data.select_data = &data;
- SET_PF_WAIT_EVENT(pthread_run);
-
- if (timeout) {
- machdep_gettimeofday(&current_time);
- sleep_schedule(&current_time, &timeout_time);
-
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_SELECT_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
-
- /* We're awake */
- if (sleep_cancel(pthread_run) == NOTOK) {
- ret = OK;
- }
- else
- {
- int count = 0;
- for (i = 0; i < numfds; i++)
- {
- if (real_readfds_p && (FD_ISSET(i, real_readfds_p)))
- count++;
- if (real_writefds_p && (FD_ISSET(i, real_writefds_p)))
- count++;
- if (real_exceptfds_p && (FD_ISSET(i, real_exceptfds_p)))
- count++;
- }
- ret = count;
- }
- /* Moving this after the sleep_cancel() seemed
- * to fix intermittent crashes during heavy
- * socket use. (mevans)
- */
- CLEAR_PF_DONE_EVENT(pthread_run);
- } else {
- int count = 0;
- SET_PF_AT_CANCEL_POINT(pthread_run);
- pthread_resched_resume(PS_SELECT_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run);
- CLEAR_PF_DONE_EVENT(pthread_run);
- for (i = 0; i < numfds; i++)
- {
- if (real_readfds_p && (FD_ISSET(i, real_readfds_p)))
- count++;
- if (real_writefds_p && (FD_ISSET(i, real_writefds_p)))
- count++;
- if (real_exceptfds_p && (FD_ISSET(i, real_exceptfds_p)))
- count++;
- }
- ret = count;
- }
- if (pthread_run->sighandled) /* Added by monty */
- { /* We where aborted */
- ret= NOTOK;
- SET_ERRNO(EINTR);
- }
- } else if (ret < 0) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- }
-
- /* clean up the locks */
- for (i = 0; i < numfds; i++)
- { /* Changed by monty */
- if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ);
- if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR);
- if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE);
- }
- if (ret > 0) {
- if (readfds != NULL) {
- for (i = 0; i < numfds; i++) {
- if (! (FD_ISSET(i,readfds) &&
- FD_ISSET(fd_table[i]->fd.i,real_readfds_p)))
- FD_CLR(i,readfds);
- }
- }
- if (writefds != NULL) {
- for (i = 0; i < numfds; i++)
- if (! (FD_ISSET(i,writefds) &&
- FD_ISSET(fd_table[i]->fd.i,real_writefds_p)))
- FD_CLR(i,writefds);
- }
- if (exceptfds != NULL) {
- for (i = 0; i < numfds; i++)
- if (! (FD_ISSET(i,exceptfds) &&
- FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p)))
- FD_CLR(i,exceptfds);
- }
- } else {
- if (exceptfds != NULL) FD_ZERO(exceptfds);
- if (writefds != NULL) FD_ZERO(writefds);
- if (readfds != NULL) FD_ZERO(readfds);
- }
-
- return(ret);
-}
diff --git a/mit-pthreads/pthreads/sig.c b/mit-pthreads/pthreads/sig.c
deleted file mode 100644
index 85d4465bf1c..00000000000
--- a/mit-pthreads/pthreads/sig.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/* ==== sig.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : All the thread signal functions.
- *
- * 1.32 94/06/12 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-
-#if defined(M_UNIX)
-#define signal(A,B) machdep_sys_signal((A),(B))
-#endif
-
-extern void sig_handler_real();
-
-struct pthread * pthread_sigwait;
-static sigset_t pending_signals;
-
-struct pthread_sigvec {
- void (*vector)();
- sigset_t mask;
- int flags;
-} pthread_sigvec[SIGMAX];
-
-/* ==========================================================================
- * pthread_sig_register()
- *
- * Assumes the kernel is locked.
- */
-int pthread_sig_register(int sig)
-{
- struct pthread ** pthread_ptr, * pthread;
- int ret;
-
- /*
- * If we have a siginfo structure and the signal is synchronous then
- * only deliver the signal to the current thread.
- */
-
- /* Check waiting threads for delivery */
- for (pthread_ptr = &pthread_sigwait; (*pthread_ptr);
- pthread_ptr = &((*pthread_ptr)->next)) {
- if (sigismember((*pthread_ptr)->data.sigwait, sig)) {
- pthread=*pthread_ptr;
- *pthread_ptr=(*pthread_ptr)->next;
-
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
- ret = pthread->pthread_priority;
- *(int *)(pthread->ret) = sig;
- pthread->state = PS_RUNNING;
-
- return(ret);
- }
- }
-
- /* Check current running thread */
- if (pthread_run) {
- if (!sigismember(&pthread_run->sigmask, sig)) {
- sigaddset(&pthread_run->sigpending, sig);
- pthread_run->sigcount++;
- return(0);
- }
- }
-
- /* Check any running thread */
- for (pthread = pthread_current_prio_queue->next;
- pthread; pthread = pthread->next) {
- if (!sigismember(&pthread->sigmask, sig)) {
- sigaddset(&pthread->sigpending, sig);
- pthread->sigcount++;
- return(0);
- }
- }
-
- /* Check any thread */
- for (pthread = pthread_link_list; pthread; pthread = pthread->pll) {
- if (!sigismember(&pthread->sigmask, sig)) {
- sigaddset(&pthread->sigpending, sig);
- pthread->sigcount++;
- return(0);
- }
- }
-
- sigaddset(&pending_signals, sig);
- return(0);
-}
-
-/* ==========================================================================
- * pthread_sig_default()
- */
-void pthread_sig_default(int sig)
-{
- sigset_t mask, omask;
-
- if (pthread_sigvec[sig].vector == SIG_DFL) {
- /* Set the signal handler to default before issueing the kill */
- signal(sig, SIG_DFL);
- kill(getpid(), sig);
- sigemptyset(&mask);
- sigaddset(&mask, sig);
- machdep_sys_sigprocmask(SIG_UNBLOCK, &mask, &omask);
- signal(sig, sig_handler_real);
- }
-}
-
-/* ==========================================================================
- * pthread_sig_process()
- *
- * Assumes the kernel is locked.
- */
-void pthread_sig_process()
-{
- void (*vector)();
- int i, j;
-
- for (i = 1; i < SIGMAX; i++) {
- if (sigismember(&(pthread_run->sigpending), i)) {
- if (! sigismember(&(pthread_run->sigmask), i)) {
- sigdelset(&(pthread_run->sigpending), i);
- pthread_run->sigcount--;
-
- if (pthread_sigvec[i].vector == SIG_IGN) {
- continue;
- }
- if (pthread_sigvec[i].vector == SIG_DFL) {
- pthread_sig_default(i);
- continue;
- }
-
- {
- sigset_t omask;
-
- sigemptyset(&omask);
- /* Save old mask */
- for (j = 1; j < SIGMAX; j++) {
- if (sigismember(&(pthread_run->sigmask), j)) {
- if (sigismember(&(pthread_sigvec[i].mask), j))
- sigaddset(&(pthread_run->sigmask), j);
- sigaddset(&omask, j);
- }
- }
- /* The signal is masked while handling the signal */
- sigaddset(&(pthread_run->sigmask), i);
-
- /*
- * Allow interrupts during a signal,
- * but not a change in the vector
- */
- vector = pthread_sigvec[i].vector;
- if (--pthread_kernel_lock) {
- PANIC();
- }
- vector(i);
- pthread_run->sighandled=1; /* Mark for select; Monty */
- pthread_kernel_lock++;
-
- memcpy(&(pthread_run->sigmask), &omask, sizeof(omask));
- }
- }
- }
- }
-}
-
-/* ==========================================================================
- * pthread_sigmask()
- *
- * It is unclear wheather this call should be implemented as an atomic
- * operation. The resulting mask could be wrong if in the signal
- * handler the thread calls sigprocmask for any signal other than the
- * signal the handler is dealing with.
- */
-int pthread_sigmask(int how, const sigset_t *set, sigset_t * oset)
-{
- int i;
-
- if (oset) {
- sigemptyset(oset);
- for (i = 1; i < SIGMAX; i++) {
- if (sigismember(&(pthread_run->sigmask), i)) {
- sigaddset(oset, i);
- }
- }
- }
-
- if (set) {
- switch(how) {
- case SIG_BLOCK:
- for (i = 1; i < SIGMAX; i++) {
- if (sigismember(set, i)) {
- sigaddset(&(pthread_run->sigmask), i);
- }
- }
- break;
- case SIG_UNBLOCK:
- pthread_sched_prevent();
- for (i = 1; i < SIGMAX; i++) {
- if (sigismember(set, i)) {
- sigdelset(&(pthread_run->sigmask), i);
- if (sigismember(&pending_signals, i)) {
- sigaddset(&(pthread_run->sigpending), i);
- sigdelset(&pending_signals, i);
- pthread_run->sigcount++;
- }
- }
- }
- pthread_sched_resume();
- break;
- case SIG_SETMASK:
- sigfillset(&(pthread_run->sigmask));
- pthread_sched_prevent();
- for (i = 1; i < SIGMAX; i++) {
- if (! sigismember(set, i)) {
- sigdelset(&(pthread_run->sigmask), i);
- if (sigismember(&pending_signals, i)) {
- sigaddset(&(pthread_run->sigpending), i);
- sigdelset(&pending_signals, i);
- pthread_run->sigcount++;
- }
- }
- }
- pthread_sched_resume();
- break;
- default:
- SET_ERRNO(EINVAL);
- return(NOTOK);
- }
- }
- return(OK);
-}
-
-int sigprocmask(int how, const sigset_t *set, sigset_t * oset)
-{
- return(pthread_sigmask(how, set, oset));
-}
-
-/* ==========================================================================
- * sigwait()
- */
-int sigwait(const sigset_t * set, int * sig)
-{
- int i;
-
- /* Check that sig is valid */
- *sig = 0;
-
- pthread_sched_prevent();
- for (i = 1; i < SIGMAX; i++) {
- if (sigismember(set, i)) {
- /* Check personal signals */
- if (sigismember(&(pthread_run->sigpending), i)) {
- sigdelset(&(pthread_run->sigpending), i);
- pthread_sched_resume();
- *sig = i;
- return(OK);
- }
- /* Check kernel signals */
- if (sigismember(&pending_signals, i)) {
- sigdelset(&pending_signals, i);
- pthread_sched_resume();
- *sig = i;
- return(OK);
- }
- }
- }
-
- /* No pending signals, wait for one */
- pthread_run->next = pthread_sigwait;
- pthread_sigwait = pthread_run;
- pthread_run->data.sigwait = set;
- pthread_run->ret = sig;
-
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_SIGWAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- return(OK);
-}
-
-/* ==========================================================================
- * raise()
- */
-int raise(int sig)
-{
- return(pthread_kill(pthread_self(), sig));
-}
-
-/* ==========================================================================
- * sigsuspend()
- */
-int sigsuspend(const sigset_t * mask)
-{
- int ret_sig, ret;
- sigset_t nm, om;
-
- sigfillset(&nm);
- for(ret_sig = 1; ret_sig < SIGMAX; ret_sig++) {
- if (sigismember(mask, ret_sig)) {
- sigdelset(&nm, ret_sig);
- }
- }
- pthread_sigmask(SIG_BLOCK, &nm, &om);
- if ((ret = sigwait(&nm, &ret_sig)) == OK) {
- sigemptyset(&nm);
- sigaddset(&nm, ret_sig);
- pthread_kill(pthread_self(), ret_sig);
- pthread_sigmask(SIG_UNBLOCK, &nm, NULL);
- /* There is a race condition here, it's not worth worring about */
- pthread_sigmask(SIG_BLOCK, &nm, NULL);
- SET_ERRNO(EINTR);
- ret = NOTOK;
- }
- pthread_sigmask(SIG_SETMASK, &om, NULL);
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_signal()
- */
-void (*pthread_signal(int sig, void (*dispatch)(int)))()
-{
- void (*odispatch)(int);
-
- odispatch = pthread_sigvec[sig].vector;
- if ((sig > 0) && (sig < SIGMAX)) {
- pthread_sigvec[sig].vector = dispatch;
- sigemptyset(&(pthread_sigvec[sig].mask));
- pthread_sigvec[sig].flags = 0;
- }
- return(odispatch);
-}
-
-/* ==========================================================================
- * pthread_sigprocmask()
- */
-int pthread_sigaction(int sig, const struct sigaction * act,
- struct sigaction * oact)
-{
- if ((sig > 0) && (sig < SIGMAX)) {
- if (oact) {
- memcpy(&(oact->sa_mask), &(pthread_sigvec[sig].mask),
- sizeof(sigset_t));
- oact->sa_handler = pthread_sigvec[sig].vector;
- oact->sa_flags = pthread_sigvec[sig].flags;
- }
- if (act) {
- memcpy(&(pthread_sigvec[sig].mask), &(act->sa_mask),
- sizeof(sigset_t));
- pthread_sigvec[sig].vector = act->sa_handler;
- pthread_sigvec[sig].flags = act->sa_flags;
- }
- return(OK);
- }
- SET_ERRNO(EINVAL);
- return(NOTOK);
-}
-
-/*
- * The following here are stolen from BSD because I get mutiply defined
- * symbols between sig.o and posix_sig.o in Sun's libc.a under Sunos 4.1.3.
- * The problem is that sigprocmask() is defined in posix_sig.o, in the same
- * module that a lot of other sigset-primitives are defined, and we have
- * our definition of sigprocmask() here, but use those other primitives.
- */
-
-#undef sigemptyset
-#undef sigfillset
-#undef sigaddset
-#undef sigdelset
-#undef sigismember
-
-static const sigset_t __sigemptyset = __SIGEMPTYSET;
-int sigemptyset(sigset_t *set)
-{
- *set = __sigemptyset;
- return (0);
-}
-
-static const sigset_t __sigfillset = __SIGFILLSET;
-int sigfillset(sigset_t * set)
-{
- *set = __sigfillset;
- return (0);
-}
-
-#define _MAXIMUM_SIG NSIG
-
-int sigaddset(sigset_t *set, int signo)
-{
- if (signo <= 0 || signo >= _MAXIMUM_SIG) {
- errno = EINVAL;
- return -1;
- }
- __SIGADDSET(set, signo);
- return (0);
-}
-
-int sigdelset(sigset_t *set, int signo)
-{
- if (signo <= 0 || signo >= _MAXIMUM_SIG) {
- errno = EINVAL;
- return -1;
- }
- __SIGDELSET(set, signo);
- return (0);
-}
-
-int sigismember(const sigset_t *set, int signo)
-{
- if (signo <= 0 || signo >= _MAXIMUM_SIG) {
- errno = EINVAL;
- return -1;
- }
- return(__SIGISMEMBER(set, signo));
-}
-
diff --git a/mit-pthreads/pthreads/signal.c b/mit-pthreads/pthreads/signal.c
deleted file mode 100644
index 7da4183c1cb..00000000000
--- a/mit-pthreads/pthreads/signal.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/* ==== signal.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Queue functions.
- *
- * 1.00 93/07/21 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <config.h>
-#include <pthread.h>
-#include <signal.h>
-
-/* This will force init.o to get dragged in; if you've got support for
- C++ initialization, that'll cause pthread_init to be called at
- program startup automatically, so the application won't need to
- call it explicitly. */
-
-extern char __pthread_init_hack;
-char *__pthread_init_hack_2 = &__pthread_init_hack;
-
-/*
- * Time which select in fd_kern_wait() will sleep.
- * If there are no threads to run we sleep for an hour or until
- * we get an interrupt or an fd thats awakens. To make sure we
- * don't miss an interrupt this variable gets reset too zero in
- * sig_handler_real().
- */
-struct timeval __fd_kern_wait_timeout = { 0, 0 };
-
-/*
- * Global for user-kernel lock, and blocked signals
- */
-
-static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
-volatile sig_atomic_t sig_to_process = 0;
-
-/* static volatile sigset_t sig_to_process; */
-static volatile int sig_count = 0;
-
-static void sig_handler(int signal);
-static void set_thread_timer();
-static void __cleanup_after_resume( void );
-void sig_prevent(void);
-void sig_resume(void);
-
-/* ==========================================================================
- * context_switch()
- *
- * This routine saves the current state of the running thread gets
- * the next thread to run and restores it's state. To allow different
- * processors to work with this routine, I allow the machdep_restore_state()
- * to either return or have it return from machdep_save_state with a value
- * other than 0, this is for implementations which use setjmp/longjmp.
- */
-static void context_switch()
-{
- struct pthread **current, *next, *last, **dead;
-
- if (pthread_run->state == PS_RUNNING) {
- /* Put current thread back on the queue */
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread_run);
- }
-
- /* save floating point registers if necessary */
- if (!(pthread_run->attr.flags & PTHREAD_NOFLOAT)) {
- machdep_save_float_state(pthread_run);
- }
- /* save state of current thread */
- if (machdep_save_state()) {
- return;
- }
-
- last = pthread_run;
-
- /* Poll all fds */
- fd_kern_poll();
-
-context_switch_reschedule:;
- /* Are there any threads to run */
- if (pthread_run = pthread_prio_queue_deq(pthread_current_prio_queue)) {
- /* restore floating point registers if necessary */
- if (!(pthread_run->attr.flags & PTHREAD_NOFLOAT)) {
- machdep_restore_float_state();
- }
- uthread_sigmask = &(pthread_run->sigmask);
- /* restore state of new current thread */
- machdep_restore_state();
- return;
- }
-
- /* Are there any threads at all */
- for (next = pthread_link_list; next; next = next->pll) {
- if ((next->state != PS_UNALLOCED) && (next->state != PS_DEAD)) {
- sigset_t sig_to_block, oset;
-
- sigfillset(&sig_to_block);
-
- /*
- * Check sig_to_process before calling fd_kern_wait, to handle
- * things like zero timeouts to select() which would register
- * a signal with the sig_handler_fake() call.
- *
- * This case should ignore SIGVTALRM
- */
- machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset);
- signum_to_process[SIGVTALRM] = 0;
- if (sig_to_process) {
- /* Process interrupts */
- /*
- * XXX pthread_run should not be set!
- * Places where it dumps core should be fixed to
- * check for the existance of pthread_run --proven
- */
- sig_handler(0);
- } else {
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
- /*
- * Do a wait, timeout is set to a hour unless we get an
- * intr. before the select in wich case it polls.
- */
- fd_kern_wait();
- machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset);
- /* Check for interrupts, but ignore SIGVTALR */
- signum_to_process[SIGVTALRM] = 0;
- if (sig_to_process) {
- /* Process interrupts */
- sig_handler(0);
- }
- }
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
- goto context_switch_reschedule;
- }
- }
-
- /* There are no threads alive. */
- pthread_run = last;
- exit(0);
-}
-
-#if !defined(HAVE_SYSCALL_SIGSUSPEND) && defined(HAVE_SYSCALL_SIGPAUSE)
-
-/* ==========================================================================
- * machdep_sys_sigsuspend()
- */
-int machdep_sys_sigsuspend(sigset_t * set)
-{
- return(machdep_sys_sigpause(* set));
-}
-
-#endif
-
-/* ==========================================================================
- * sig_handler_pause()
- *
- * Wait until a signal is sent to the process.
- */
-void sig_handler_pause()
-{
- sigset_t sig_to_block, sig_to_pause, oset;
-
- sigfillset(&sig_to_block);
- sigemptyset(&sig_to_pause);
- machdep_sys_sigprocmask(SIG_BLOCK, &sig_to_block, &oset);
-/* if (!(SIG_ANY(sig_to_process))) { */
- if (!sig_to_process) {
- machdep_sys_sigsuspend(&sig_to_pause);
- }
- machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
-}
-
-/* ==========================================================================
- * context_switch_done()
- *
- * This routine does all the things that are necessary after a context_switch()
- * calls the machdep_restore_state(). DO NOT put this in the context_switch()
- * routine because sometimes the machdep_restore_state() doesn't return
- * to context_switch() but instead ends up in machdep_thread_start() or
- * some such routine, which will need to call this routine and
- * sig_check_and_resume().
- */
-void context_switch_done()
-{
- /* sigdelset((sigset_t *)&sig_to_process, SIGVTALRM); */
- signum_to_process[SIGVTALRM] = 0;
- set_thread_timer();
-}
-
-/* ==========================================================================
- * set_thread_timer()
- *
- * Assums kernel is locked.
- */
-static void set_thread_timer()
-{
- static int last_sched_attr = SCHED_RR;
-
- switch (pthread_run->attr.schedparam_policy) {
- case SCHED_RR:
- machdep_set_thread_timer(&(pthread_run->machdep_data));
- break;
- case SCHED_FIFO:
- if (last_sched_attr != SCHED_FIFO) {
- machdep_unset_thread_timer(NULL);
- }
- break;
- case SCHED_IO:
- if ((last_sched_attr != SCHED_IO) && (!sig_count)) {
- machdep_set_thread_timer(&(pthread_run->machdep_data));
- }
- break;
- default:
- machdep_set_thread_timer(&(pthread_run->machdep_data));
- break;
- }
- last_sched_attr = pthread_run->attr.schedparam_policy;
-}
-
-/* ==========================================================================
- * sigvtalrm()
- */
-static inline void sigvtalrm()
-{
- if (sig_count) {
- sigset_t sigall, oset;
-
- sig_count = 0;
-
- /* Unblock all signals */
- sigemptyset(&sigall);
- machdep_sys_sigprocmask(SIG_SETMASK, &sigall, &oset);
- }
- context_switch();
- context_switch_done();
-}
-
-/* ==========================================================================
- * sigdefault()
- */
-static inline void sigdefault(int sig)
-{
- int ret;
-
- ret = pthread_sig_register(sig);
- if (pthread_run && (ret > pthread_run->pthread_priority)) {
- sigvtalrm();
- }
-}
-
-/* ==========================================================================
- * sig_handler_switch()
- */
-static inline void sig_handler_switch(int sig)
-{
- int ret;
-
- switch(sig) {
- case 0:
- break;
- case SIGVTALRM:
- sigvtalrm();
- break;
- case SIGALRM:
-/* sigdelset((sigset_t *)&sig_to_process, SIGALRM); */
- signum_to_process[SIGALRM] = 0;
- switch (ret = sleep_wakeup()) {
- default:
- if (pthread_run && (ret > pthread_run->pthread_priority)) {
- sigvtalrm();
- }
- case 0:
- break;
- case NOTOK:
- /* Do the registered action, no threads were sleeping */
- /* There is a timing window that gets
- * here when no threads are on the
- * sleep queue. This is a quick fix.
- * The real problem is possibly related
- * to heavy use of condition variables
- * with time outs.
- * (mevans)
- *sigdefault(sig);
- */
- break;
- }
- break;
- case SIGCHLD:
-/* sigdelset((sigset_t *)&sig_to_process, SIGCHLD); */
- signum_to_process[SIGCHLD] = 0;
- switch (ret = wait_wakeup()) {
- default:
- if (pthread_run && (ret > pthread_run->pthread_priority)) {
- sigvtalrm();
- }
- case 0:
- break;
- case NOTOK:
- /* Do the registered action, no threads were waiting */
- sigdefault(sig);
- break;
- }
- break;
-
-#ifdef SIGINFO
- case SIGINFO:
- pthread_dump_info ();
- /* Then fall through, invoking the application's
- signal handler after printing our info out.
-
- I'm not convinced that this is right, but I'm not
- 100% convinced that it is wrong, and this is how
- Chris wants it done... */
-#endif
-
- default:
- /* Do the registered action */
- if (!sigismember(uthread_sigmask, sig)) {
- /*
- * If the signal isn't masked by the last running thread and
- * the signal behavior is default or ignore then we can
- * execute it immediatly. --proven
- */
- pthread_sig_default(sig);
- }
- signum_to_process[sig] = 0;
- sigdefault(sig);
- break;
- }
-
-}
-
-/* ==========================================================================
- * sig_handler()
- *
- * Process signal that just came in, plus any pending on the signal mask.
- * All of these must be resolved.
- *
- * Assumes the kernel is locked.
- */
-static void sig_handler(int sig)
-{
- if (pthread_kernel_lock != 1) {
- PANIC();
- }
-
- if (sig) {
- sig_handler_switch(sig);
- }
-
- while (sig_to_process) {
- for (sig_to_process = 0, sig = 1; sig <= SIGMAX; sig++) {
- if (signum_to_process[sig]) {
- sig_handler_switch(sig);
- }
- }
- }
-
-
-/*
- if (SIG_ANY(sig_to_process)) {
- for (sig = 1; sig <= SIGMAX; sig++) {
- if (sigismember((sigset_t *)&sig_to_process, sig)) {
- goto sig_handler_top;
- }
- }
- }
-*/
-}
-
-/* ==========================================================================
- * sig_handler_real()
- *
- * On a multi-processor this would need to use the test and set instruction
- * otherwise the following will work.
- */
-void sig_handler_real(int sig)
-{
- /*
- * Get around systems with BROKEN signal handlers.
- *
- * Some systems will reissue SIGCHLD if the handler explicitly
- * clear the signal pending by either doing a wait() or
- * ignoring the signal.
- */
-#if defined BROKEN_SIGNALS
- if (sig == SIGCHLD) {
- sigignore(SIGCHLD);
- signal(SIGCHLD, sig_handler_real);
- }
-#endif
-
- if (pthread_kernel_lock) {
- /* sigaddset((sigset_t *)&sig_to_process, sig); */
- __fd_kern_wait_timeout.tv_sec = 0;
- signum_to_process[sig] = 1;
- sig_to_process = 1;
- return;
- }
- pthread_kernel_lock++;
-
- sig_count++;
- sig_handler(sig);
-
- /* Handle any signals the current thread might have just gotten */
- if (pthread_run && pthread_run->sigcount) {
- pthread_sig_process();
- }
- pthread_kernel_lock--;
-}
-
-/* ==========================================================================
- * sig_handler_fake()
- */
-void sig_handler_fake(int sig)
-{
- if (pthread_kernel_lock) {
- /* sigaddset((sigset_t *)&sig_to_process, sig); */
- signum_to_process[sig] = 1;
- sig_to_process = 1;
- return;
- }
- pthread_kernel_lock++;
- sig_handler(sig);
- while (!(--pthread_kernel_lock)) {
- if (sig_to_process) {
- /* if (SIG_ANY(sig_to_process)) { */
- pthread_kernel_lock++;
- sig_handler(0);
- } else {
- break;
- }
- }
-}
-
-/* ==========================================================================
- * __pthread_signal_delete(int sig)
- *
- * Assumes the kernel is locked.
- */
-void __pthread_signal_delete(int sig)
-{
- signum_to_process[sig] = 0;
-}
-
-/* ==========================================================================
- * pthread_sched_other_resume()
- *
- * Check if thread to be resumed is of higher priority and if so
- * stop current thread and start new thread.
- */
-pthread_sched_other_resume(struct pthread * pthread)
-{
- pthread->state = PS_RUNNING;
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
-
- if (pthread->pthread_priority > pthread_run->pthread_priority) {
- if (pthread_kernel_lock == 1) {
- sig_handler(SIGVTALRM);
- }
- }
-
- __cleanup_after_resume();
-}
-
-/* ==========================================================================
- * pthread_resched_resume()
- *
- * This routine assumes that the caller is the current pthread, pthread_run
- * and that it has a lock the kernel thread and it wants to reschedule itself.
- */
-void pthread_resched_resume(enum pthread_state state)
-{
- pthread_run->state = state;
-
- /* Since we are about to block this thread, lets see if we are
- * at a cancel point and if we've been cancelled.
- * Avoid cancelling dead or unalloced threads.
- */
- if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) &&
- TEST_PTHREAD_IS_CANCELLABLE(pthread_run) &&
- state != PS_DEAD && state != PS_UNALLOCED ) {
-
- /* Set this flag to avoid recursively calling pthread_exit */
- /* We have to set this flag here because we will unlock the
- * kernel prior to calling pthread_cancel_internal.
- */
- SET_PF_RUNNING_TO_CANCEL(pthread_run);
-
- pthread_run->old_state = state; /* unlock needs this data */
- pthread_sched_resume(); /* Unlock kernel before cancel */
- pthread_cancel_internal( 1 ); /* free locks and exit */
- }
-
- sig_handler(SIGVTALRM);
-
- __cleanup_after_resume();
-}
-
-/* ==========================================================================
- * pthread_sched_resume()
- */
-void pthread_sched_resume()
-{
- __cleanup_after_resume();
-}
-
-/*----------------------------------------------------------------------
- * Function: __cleanup_after_resume
- * Purpose: cleanup kernel locks after a resume
- * Args: void
- * Returns: void
- * Notes:
- *----------------------------------------------------------------------*/
-static void
-__cleanup_after_resume( void )
-{
- /* Only bother if we are truely unlocking the kernel */
- while (!(--pthread_kernel_lock)) {
- /* if (SIG_ANY(sig_to_process)) { */
- if (sig_to_process) {
- pthread_kernel_lock++;
- sig_handler(0);
- continue;
- }
- if (pthread_run && pthread_run->sigcount) {
- pthread_kernel_lock++;
- pthread_sig_process();
- continue;
- }
- break;
- }
-
- if( pthread_run == NULL )
- return; /* Must be during init processing */
-
- /* Test for cancel that should be handled now */
-
- if( ! TEST_PF_RUNNING_TO_CANCEL(pthread_run) &&
- TEST_PTHREAD_IS_CANCELLABLE(pthread_run) ) {
- /* Kernel is already unlocked */
- pthread_cancel_internal( 1 ); /* free locks and exit */
- }
-}
-
-/* ==========================================================================
- * pthread_sched_prevent()
- */
-void pthread_sched_prevent(void)
-{
- pthread_kernel_lock++;
-}
-
-/* ==========================================================================
- * sig_init()
- *
- * SIGVTALRM (NOT POSIX) needed for thread timeslice timeouts.
- * Since it's not POSIX I will replace it with a
- * virtual timer for threads.
- * SIGALRM (IS POSIX) so some special handling will be
- * necessary to fake SIGALRM signals
- */
-#ifndef SIGINFO
-#define SIGINFO 0
-#endif
-void sig_init(void)
-{
- static const int signum_to_initialize[] =
- { SIGCHLD, SIGALRM, SIGVTALRM, SIGINFO, 0 };
- static const int signum_to_ignore[] = { SIGKILL, SIGSTOP, 0 };
- int i, j;
-
-#if defined(HAVE_SYSCALL_SIGACTION) || defined(HAVE_SYSCALL_KSIGACTION)
- struct sigaction act;
-
- act.sa_handler = sig_handler_real;
- sigemptyset(&(act.sa_mask));
- act.sa_flags = 0;
-#endif
-
- /* Initialize the important signals */
- for (i = 0; signum_to_initialize[i]; i++) {
-
-#if defined(HAVE_SYSCALL_SIGACTION) || defined(HAVE_SYSCALL_KSIGACTION)
- if (sigaction(signum_to_initialize[i], &act, NULL)) {
-#else
- if (signal(signum_to_initialize[i], sig_handler_real)) {
-#endif
- PANIC();
- }
- }
-
- /* Initialize the rest of the signals */
- for (j = 1; j < SIGMAX; j++) {
- for (i = 0; signum_to_initialize[i]; i++) {
- if (signum_to_initialize[i] == j) {
- goto sig_next;
- }
- }
- /* Because Solaris 2.4 can't deal -- proven */
- for (i = 0; signum_to_ignore[i]; i++) {
- if (signum_to_ignore[i] == j) {
- goto sig_next;
- }
- }
- pthread_signal(j, SIG_DFL);
-
-#if defined(HAVE_SYSCALL_SIGACTION) || defined(HAVE_SYSCALL_KSIGACTION)
- sigaction(j, &act, NULL);
-#else
- signal(j, sig_handler_real);
-#endif
-
- sig_next:;
- }
-
-#if defined BROKEN_SIGNALS
- signal(SIGCHLD, sig_handler_real);
-#endif
-
-}
-
diff --git a/mit-pthreads/pthreads/sleep.c b/mit-pthreads/pthreads/sleep.c
deleted file mode 100644
index 1c13dd2eb1d..00000000000
--- a/mit-pthreads/pthreads/sleep.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/* ==== sleep.c ============================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : All the appropriate sleep routines.
- *
- * 1.00 93/12/28 proven
- * -Started coding this file.
- *
- * 1.36 94/06/04 proven
- * -Use new timer structure pthread_timer, that uses seconds
- * -nano seconds. Rewrite all routines completely.
- *
- * 1.38 94/06/13 proven
- * -switch pthread_timer to timespec
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <unistd.h>
-#include <sys/compat.h>
-
-struct pthread * pthread_sleep = NULL;
-
-/* ==========================================================================
- * sleep_compare_time()
- */
-/* static inline int sleep_compare_time(struct timespec * time1,
- struct timespec * time2) */
-static int sleep_compare_time(struct timespec * time1, struct timespec * time2)
-{
- if ((time1->tv_sec < time2->tv_sec) ||
- ((time1->tv_sec == time2->tv_sec) && (time1->tv_nsec < time2->tv_nsec))) {
- return(-1);
- }
- if ((time1->tv_sec == time2->tv_sec) && (time1->tv_nsec == time2->tv_nsec)){
- return(0);
- }
- return(1);
-}
-
-/* ==========================================================================
- * machdep_stop_timer()
- *
- * Returns the time left on the timer.
- */
-static struct itimerval timestop = { { 0, 0 }, { 0, 0 } };
-
-void machdep_stop_timer(struct timespec *current)
-{
- struct itimerval timenow;
-
- setitimer(ITIMER_REAL, & timestop, & timenow);
- __pthread_signal_delete(SIGALRM);
- if (current) {
- current->tv_nsec = timenow.it_value.tv_usec * 1000;
- current->tv_sec = timenow.it_value.tv_sec;
- }
-}
-
-/* ==========================================================================
- * machdep_start_timer()
- */
-int machdep_start_timer(struct timespec *current, struct timespec *wakeup)
-{
- struct itimerval timeout;
-
- timeout.it_value.tv_usec = (wakeup->tv_nsec - current->tv_nsec) / 1000;
- timeout.it_value.tv_sec = wakeup->tv_sec - current->tv_sec;
- timeout.it_interval.tv_usec = 0;
- timeout.it_interval.tv_sec = 0;
- if (timeout.it_value.tv_usec < 0) {
- timeout.it_value.tv_usec += 1000000;
- timeout.it_value.tv_sec--;
- }
-
- if (((long) timeout.it_value.tv_sec >= 0) &&
- ((timeout.it_value.tv_usec) || (timeout.it_value.tv_sec))) {
- if (setitimer(ITIMER_REAL, & timeout, NULL) < 0)
- {
- fprintf(stderr,"Got error %d from setitimer with:\n\
- wakeup: tv_sec: %ld tv_nsec: %ld\n\
- current: tv_sec: %ld tv_nsec: %ld\n\
- argument: tv_sec: %ld tv_usec: %ld\n",
- errno,
- wakeup->tv_sec, wakeup->tv_nsec,
- current->tv_sec, current->tv_nsec,
- timeout.it_value.tv_sec, timeout.it_value.tv_usec);
- PANIC();
- }
- } else {
- /*
- * There is no time on the timer.
- * This shouldn't happen,
- * but isn't fatal.
- */
- sig_handler_fake(SIGALRM);
- }
- return(OK);
-}
-
-/* ==========================================================================
- * sleep_schedule()
- *
- * Assumes that the current thread is the thread to be scheduled
- * and that the kthread is already locked.
- */
-void sleep_schedule(struct timespec *current_time, struct timespec *new_time)
-{
- struct pthread * pthread_sleep_current, * pthread_sleep_prev;
-
- /* Record the new time as the current thread's wakeup time. */
- pthread_run->wakeup_time = *new_time;
-
- /* any threads? */
- if (pthread_sleep_current = pthread_sleep) {
- if (sleep_compare_time(&(pthread_sleep_current->wakeup_time),
- new_time) <= 0) {
- /* Don't need to restart timer */
- while (pthread_sleep_current->sll) {
-
- pthread_sleep_prev = pthread_sleep_current;
- pthread_sleep_current = pthread_sleep_current->sll;
-
- if (sleep_compare_time(&(pthread_sleep_current->wakeup_time),
- new_time) > 0) {
- pthread_run->sll = pthread_sleep_current;
- pthread_sleep_prev->sll = pthread_run;
- return;
- }
- }
-
- /* No more threads in queue, attach pthread_run to end of list */
- pthread_sleep_current->sll = pthread_run;
- pthread_run->sll = NULL;
-
- } else {
- /* Start timer and enqueue thread */
- machdep_start_timer(current_time, new_time);
- pthread_run->sll = pthread_sleep_current;
- pthread_sleep = pthread_run;
- }
- } else {
- /* Start timer and enqueue thread */
- machdep_start_timer(current_time, new_time);
- pthread_sleep = pthread_run;
- pthread_run->sll = NULL;
- }
-}
-
-/* ==========================================================================
- * sleep_wakeup()
- *
- * This routine is called by the interrupt handler, which has already
- * locked the current kthread. Since all threads on this list are owned
- * by the current kthread, rescheduling won't be a problem.
- */
-int sleep_spurious_wakeup = 0;
-int sleep_wakeup()
-{
- struct pthread *pthread_sleep_next;
- struct timespec current_time;
- int ret = 0;
-
- if (pthread_sleep == NULL) {
- return(NOTOK);
- }
-
- machdep_gettimeofday(&current_time);
- if (sleep_compare_time(&(pthread_sleep->wakeup_time), &current_time) > 0) {
- machdep_start_timer(&current_time, &(pthread_sleep->wakeup_time));
- sleep_spurious_wakeup++;
- return(OK);
- }
-
- do {
- if (pthread_sleep->pthread_priority > ret) {
- ret = pthread_sleep->pthread_priority;
- }
-
- /*
- * Clean up removed thread and start it running again.
- *
- * Note: It is VERY important to remove the thread form the
- * current queue before putting it on the run queue.
- * Both queues use pthread_sleep->next, and the thread that points
- * to pthread_sleep should point to pthread_sleep->next then
- * pthread_sleep should be put on the run queue.
- */
- if ((SET_PF_DONE_EVENT(pthread_sleep)) == OK) {
- if (pthread_sleep->queue)
- pthread_queue_remove(pthread_sleep->queue, pthread_sleep);
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread_sleep);
- pthread_sleep->state = PS_RUNNING;
- }
-
- pthread_sleep_next = pthread_sleep->sll;
- pthread_sleep->sll = NULL;
-
- if ((pthread_sleep = pthread_sleep_next) == NULL) {
- /* No more threads on sleep queue */
- return(ret);
- }
- } while (sleep_compare_time(&(pthread_sleep->wakeup_time), &(current_time)) <= 0);
-
- /* Start timer for next time interval */
- machdep_start_timer(&current_time, &(pthread_sleep->wakeup_time));
- return(ret);
-}
-
-
-/* ==========================================================================
- * __sleep()
- */
-void __sleep(struct timespec * time_to_sleep)
-{
- struct pthread *pthread_sleep_prev;
- struct timespec current_time, wakeup_time;
-
- pthread_sched_prevent();
-
- /* Get real time */
- machdep_gettimeofday(&current_time);
- wakeup_time.tv_sec = current_time.tv_sec + time_to_sleep->tv_sec;
- wakeup_time.tv_nsec = current_time.tv_nsec + time_to_sleep->tv_nsec;
-
- sleep_schedule(&current_time, &wakeup_time);
-
- /* Reschedule thread */
- SET_PF_WAIT_EVENT(pthread_run);
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_SLEEP_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
- CLEAR_PF_DONE_EVENT(pthread_run);
-
- /* Return actual time slept */
- time_to_sleep->tv_sec = pthread_run->wakeup_time.tv_sec;
- time_to_sleep->tv_nsec = pthread_run->wakeup_time.tv_nsec;
-}
-
-/* ==========================================================================
- * pthread_nanosleep()
- */
-unsigned int pthread_nanosleep(unsigned int nseconds)
-{
- struct timespec time_to_sleep;
-
- if (nseconds) {
- time_to_sleep.tv_nsec = nseconds;
- time_to_sleep.tv_sec = 0;
- __sleep(&time_to_sleep);
- nseconds = time_to_sleep.tv_nsec;
- }
- return(nseconds);
-}
-
-/* ==========================================================================
- * usleep()
- */
-void usleep(unsigned int useconds)
-{
- struct timespec time_to_sleep;
-
- if (useconds) {
- time_to_sleep.tv_nsec = (useconds % 1000000) * 1000;
- time_to_sleep.tv_sec = useconds / 1000000;
- __sleep(&time_to_sleep);
- }
-}
-
-/* ==========================================================================
- * sleep()
- */
-unsigned int sleep(unsigned int seconds)
-{
- struct timespec time_to_sleep;
-
- if (seconds) {
- time_to_sleep.tv_sec = seconds;
- time_to_sleep.tv_nsec = 0;
- __sleep(&time_to_sleep);
- seconds = time_to_sleep.tv_sec;
- }
- return(seconds);
-}
-
-/* ==========================================================================
- * sleep_cancel()
- *
- * Cannot be called while kernel is locked.
- * Does not wake sleeping thread up, just remove it from the sleep queue.
- */
-int sleep_cancel(struct pthread * pthread)
-{
- struct timespec current_time, delta_time;
- struct pthread * pthread_last;
- int rval = NOTOK;
-
- /* Lock sleep queue, Note this may be on a different kthread queue */
- pthread_sched_prevent();
-
- if (pthread_sleep) {
- if (pthread == pthread_sleep) {
- rval = OK;
- machdep_stop_timer(&delta_time);
- if (pthread_sleep = pthread_sleep->sll) {
- current_time.tv_sec = delta_time.tv_sec;
- current_time.tv_nsec = delta_time.tv_nsec;
- current_time.tv_sec += pthread_sleep->wakeup_time.tv_sec;
- current_time.tv_nsec += pthread_sleep->wakeup_time.tv_nsec;
- while (current_time.tv_nsec > 1000000000) {
- current_time.tv_nsec -= 1000000000;
- current_time.tv_sec++;
- }
- machdep_start_timer(&(current_time),
- &(pthread_sleep->wakeup_time));
- }
- } else {
- for (pthread_last = pthread_sleep; pthread_last;
- pthread_last = pthread_last->sll) {
- if (pthread_last->sll == pthread) {
- pthread_last->sll = pthread->sll;
- rval = OK;
- break;
- }
- }
- }
- }
-
- pthread_sched_resume();
- pthread->sll = NULL;
- return(rval);
-}
diff --git a/mit-pthreads/pthreads/specific.c b/mit-pthreads/pthreads/specific.c
deleted file mode 100644
index 898f9b0cd1b..00000000000
--- a/mit-pthreads/pthreads/specific.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* ==== specific.c =======================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Pthread thread specific data management.
- *
- * 1.20 94/03/30 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-
-static struct pthread_key key_table[PTHREAD_DATAKEYS_MAX];
-static pthread_mutex_t key_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/* ==========================================================================
- * pthread_key_create()
- */
-int pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
-{
- pthread_mutex_lock(&key_mutex);
- for ((*key) = 0; (*key) < PTHREAD_DATAKEYS_MAX; (*key)++) {
- if (key_table[(*key)].count == 0) {
- key_table[(*key)].count++;
- key_table[(*key)].destructor = destructor;
- pthread_mutex_init(&(key_table[(*key)].mutex), NULL);
- pthread_mutex_unlock(&key_mutex);
- return(OK);
- }
- }
- pthread_mutex_unlock(&key_mutex);
- return(EAGAIN);
-}
-
-/* ==========================================================================
- * pthread_key_delete()
- */
-int pthread_key_delete(pthread_key_t key)
-{
- int ret;
-
- if (key < PTHREAD_DATAKEYS_MAX) {
- pthread_mutex_lock(&(key_table[key].mutex));
- switch (key_table[key].count) {
- case 1:
- pthread_mutex_destroy(&(key_table[key].mutex));
- key_table[key].destructor = NULL;
- key_table[key].count = 0;
- case 0:
- ret = OK;
- break;
- default:
- ret = EBUSY;
- }
- pthread_mutex_unlock(&(key_table[key].mutex));
- } else {
- ret = EINVAL;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_cleanupspecific()
- */
-void pthread_cleanupspecific(void)
-{
- void * data;
- int key;
- int itr;
-
- pthread_mutex_lock(&key_mutex);
- for (itr = 0; itr < _POSIX_THREAD_DESTRUTOR_ITERATIONS; itr++) {
- for (key = 0; key < PTHREAD_DATAKEYS_MAX; key++) {
- if (pthread_run->specific_data_count) {
- if (pthread_run->specific_data[key]) {
- data = (void *)pthread_run->specific_data[key];
- pthread_run->specific_data[key] = NULL;
- pthread_run->specific_data_count--;
- if (key_table[key].destructor) {
- pthread_mutex_unlock(&key_mutex);
- key_table[key].destructor(data);
- pthread_mutex_lock(&key_mutex);
- }
- key_table[key].count--;
- }
- } else {
- free(pthread_run->specific_data);
- pthread_mutex_unlock(&key_mutex);
- return;
- }
- }
- }
- free(pthread_run->specific_data);
- pthread_mutex_unlock(&key_mutex);
-}
-
-static inline const void ** pthread_key_allocate_data(void)
-{
- const void ** new_data;
- if(new_data = (const void**)malloc(sizeof(void *) * PTHREAD_DATAKEYS_MAX)) {
- memset((void *)new_data, 0, sizeof(void *) * PTHREAD_DATAKEYS_MAX);
- }
- return(new_data);
-}
-
-/* ==========================================================================
- * pthread_setspecific()
- */
-int pthread_setspecific(pthread_key_t key, const void * value)
-{
- int ret;
-
- if ((pthread_run->specific_data) ||
- (pthread_run->specific_data = pthread_key_allocate_data())) {
- if ((key < PTHREAD_DATAKEYS_MAX) && (key_table)) {
- pthread_mutex_lock(&(key_table[key].mutex));
- if (key_table[key].count) {
- if (pthread_run->specific_data[key] == NULL) {
- if (value != NULL) {
- pthread_run->specific_data_count++;
- key_table[key].count++;
- }
- } else {
- if (value == NULL) {
- pthread_run->specific_data_count--;
- key_table[key].count--;
- }
- }
- pthread_run->specific_data[key] = value;
- ret = OK;
- } else {
- ret = EINVAL;
- }
- pthread_mutex_unlock(&(key_table[key].mutex));
- } else {
- ret = EINVAL;
- }
- } else {
- ret = ENOMEM;
- }
- return(ret);
-}
-
-/* ==========================================================================
- * pthread_getspecific()
- */
-void * pthread_getspecific(pthread_key_t key)
-{
- void *ret;
-
- if ((pthread_run->specific_data) && (key < PTHREAD_DATAKEYS_MAX)
- && (key_table)) {
- pthread_mutex_lock(&(key_table[key].mutex));
- if (key_table[key].count) {
- ret = (void *)pthread_run->specific_data[key];
- } else {
- ret = NULL;
- }
- pthread_mutex_unlock(&(key_table[key].mutex));
- } else {
- ret = NULL;
- }
- return(ret);
-}
diff --git a/mit-pthreads/pthreads/stat.c b/mit-pthreads/pthreads/stat.c
deleted file mode 100644
index f18b7c6bd24..00000000000
--- a/mit-pthreads/pthreads/stat.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* ==== stat.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : All the syscalls dealing with fds.
- *
- * 1.00 93/05/27 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <errno.h>
-
-struct stat;
-struct statfs;
-
-/* ==========================================================================
- * fstat()
- *
- * Might want to indirect this.
- */
-int fstat(int fd, struct stat *buf)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_fstat(fd_table[fd]->fd.i, buf)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-
-/* ==========================================================================
- * stat()
- */
-int stat(const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_stat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * lstat()
- */
-int lstat(const char * path, struct stat * buf)
-{
- int ret;
-
- if ((ret = machdep_sys_lstat(path, buf)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- return(ret);
-
-}
-
-#ifdef HAVE_SYSCALL_FSTATFS
-/* ==========================================================================
- * fstatfs()
- *
- * Might want to indirect this.
- */
-int fstatfs(int fd, struct statfs *buf)
-{
- int ret;
-
- if ((ret = fd_lock(fd, FD_READ, NULL)) == OK) {
- if ((ret = machdep_sys_fstatfs(fd_table[fd]->fd.i, buf)) < OK) {
- SET_ERRNO(-ret);
- ret = NOTOK;
- }
- fd_unlock(fd, FD_READ);
- }
- return(ret);
-}
-#endif
diff --git a/mit-pthreads/pthreads/wait.c b/mit-pthreads/pthreads/wait.c
deleted file mode 100644
index 9f0418ca8a1..00000000000
--- a/mit-pthreads/pthreads/wait.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* ==== wait.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : All the appropriate wait routines.
- *
- * 1.38 94/06/13 proven
- * -Started coding this file.
- *
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include <pthread.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <pthread/posix.h>
-#include <sys/compat.h>
-#include <sys/wait.h>
-
-/* This is an UGLY hack to get wait to compile, something better is needed. */
-/* #define _POSIX_SOURCE
-#undef _POSIX_SOURCE
-*/
-
-struct pthread_queue wait_queue = { NULL, NULL, NULL };
-extern void sig_handler_real();
-
-/* ==========================================================================
- * wait_wakeup()
- *
- * This routine is called by the interrupt handler which has locked
- * the current kthread semaphore. Since only threads owned by the
- * current kthread can be queue here, no additional locks are necessary.
- */
-int wait_wakeup()
-{
- struct pthread *pthread;
- int ret = 0;
-
- if (pthread = pthread_queue_deq(& wait_queue)) {
- /* Wakeup all threads, and enqueue them on the run queue */
- do {
- pthread->state = PS_RUNNING;
- if (pthread->pthread_priority > ret) {
- ret = pthread->pthread_priority;
- }
- pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
- } while (pthread = pthread_queue_deq(&wait_queue));
- return(ret);
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * For the wait calls, it is important that the current kthread is locked
- * before the apropriate wait syscall is preformed. This way we ensure
- * that there is never a case where a thread is waiting for a child but
- * missed the interrupt for that child.
- * Patched by William S. Lear 1997-02-02
- */
-
-/* ==========================================================================
- * waitpid()
- */
-pid_t waitpid(pid_t pid, int *status, int options)
-{
- pid_t ret;
-
- pthread_sched_prevent();
- ret = machdep_sys_waitpid(pid, status, options | WNOHANG);
- /* If we are not doing nohang, try again, else return immediately */
- if (!(options & WNOHANG)) {
- while (ret == OK) {
- /* Enqueue thread on wait queue */
- pthread_queue_enq(&wait_queue, pthread_run);
-
- /* reschedule unlocks scheduler */
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_WAIT_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_sched_prevent();
-
- ret = machdep_sys_waitpid(pid, status, options | WNOHANG);
- }
- }
- pthread_sched_resume();
- return(ret);
-}
-
-/* ==========================================================================
- * wait3()
- * Patched by Monty 1997-02-02
- */
-pid_t wait3(__WAIT_STATUS status, int options, void * rusage)
-{
- semaphore * lock;
- pid_t ret;
-
- pthread_sched_prevent();
- ret = machdep_sys_wait3(status, options | WNOHANG, rusage);
- /* If we are not doing nohang, try again, else return immediately */
- if (!(options & WNOHANG)) {
- while (ret == OK) {
- /* Enqueue thread on wait queue */
- pthread_queue_enq(&wait_queue, pthread_run);
-
- /* reschedule unlocks scheduler */
- SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
- pthread_resched_resume(PS_WAIT_WAIT);
- CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
-
- pthread_sched_prevent();
-
- machdep_sys_wait3(status, options | WNOHANG, rusage);
- }
- }
- pthread_sched_resume();
- return(ret);
-}
-
-/* ==========================================================================
- * wait()
- */
-pid_t wait(__WAIT_STATUS status)
-{
- return(waitpid((pid_t)-1, (int *)status, 0));
-}
diff --git a/mit-pthreads/pthreads/wrapper.c b/mit-pthreads/pthreads/wrapper.c
deleted file mode 100644
index 6e3f4478fcf..00000000000
--- a/mit-pthreads/pthreads/wrapper.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* ==== wrapper.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Wrapper functions for syscalls that only need errno redirected
- *
- * 1.4x 94/07/23 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-#include <pthread.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pthread/posix.h>
-
-/* ==========================================================================
- * link()
- */
-int link(const char * name1, const char * name2)
-{
- int ret;
-
- if ((ret = machdep_sys_link(name1, name2)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * unlink()
- */
-int unlink(const char * path)
-{
- int ret;
-
- if ((ret = machdep_sys_unlink(path)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * chdir()
- */
-int chdir(const char * path)
-{
- int ret;
-
- if ((ret = machdep_sys_chdir(path)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * chmod()
- */
-int chmod(const char * path, mode_t mode)
-{
- int ret;
-
- if ((ret = machdep_sys_chmod(path, mode)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * chown()
- */
-int chown(const char * path, uid_t owner, gid_t group)
-{
- int ret;
-
- if ((ret = machdep_sys_chown(path, owner, group)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-/* ==========================================================================
- * rename()
- */
-int rename(const char * name1, const char * name2)
-{
- int ret;
-
- if ((ret = machdep_sys_rename(name1, name2)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-
-
-/* ==========================================================================
- * chroot()
- */
-
-#ifdef HAVE_SYSCALL_CHROOT
-int chroot(const char * name)
-{
- int ret;
-
- if ((ret = machdep_sys_chroot(name)) < OK) {
- SET_ERRNO(-ret);
- }
- return(ret);
-
-}
-#endif
diff --git a/mit-pthreads/pthreads/writev.c b/mit-pthreads/pthreads/writev.c
deleted file mode 100644
index 9823d5ad201..00000000000
--- a/mit-pthreads/pthreads/writev.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* ==== writev.c ============================================================
- * Copyright (c) 1995 by Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Chris Provenzano.
- * 4. The name of Chris Provenzano may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Description : Implementation of writev().
- *
- * 1.00 95/06/19 proven
- * -Started coding this file.
- */
-
-#ifndef lint
-static const char rcsid[] = "$Id$";
-#endif
-
-#include "config.h"
-
-#ifndef HAVE_SYSCALL_WRITEV
-
-#include <errno.h>
-#include <unistd.h>
-#include <sys/uio.h>
-#include <sys/types.h>
-
-/* ==========================================================================
- * machdep_sys_writev()
- *
- * modified from the GNU C Library posix/writev.c
- */
-int machdep_sys_writev(int fd, struct iovec * vector, int count)
-{
- size_t bytes, i;
- char *buffer;
- int ret;
-
- /* Find the total number of bytes to be written. */
- for (bytes = 0, i = 0; i < count; ++i)
- bytes += vector[i].iov_len;
-
- if (bytes) {
- /*
- * Allocate a temporary buffer to hold the data.
- * Don't use alloca because threads tend to have smaller stacks.
- */
- if ((buffer = (char *)malloc(bytes)) == NULL) {
- return(-ENOMEM);
- }
- /* Copy the data from memory specified by VECTOR to BUFFER */
- for (ret = 0, i = 0; i < count; ++i) {
- memcpy(buffer + ret, vector[i].iov_base, vector[i].iov_len);
- ret += vector[i].iov_len;
- }
- } else {
- buffer = NULL;
- }
-
- ret = (int)machdep_sys_write(fd, buffer, bytes);
- if (buffer)
- free(buffer);
- return(ret);
-}
-
-#endif
diff --git a/mit-pthreads/scripts/GNUmakefile.inc b/mit-pthreads/scripts/GNUmakefile.inc
deleted file mode 100755
index 6309f28ca55..00000000000
--- a/mit-pthreads/scripts/GNUmakefile.inc
+++ /dev/null
@@ -1,24 +0,0 @@
-VPATH := $(VPATH):${srcdir}/scripts
-SCRIPTS= pgcc pg++
-
-abspath := $(shell pwd)
-
-all-bin: $(SCRIPTS)
-
-pgcc: pgcc.sh
- sed -e 's!EXEC_PREFIX!$(exec_prefix)!g' \
- -e 's!BUILD_PREFIX!$(abspath)!g' \
- -e 's!SRC_PREFIX!$(srcdir)!g' \
- -e 's!COMPILER!gcc!g' \
- < $(srcdir)/scripts/pgcc.sh > pgcc.new
- chmod a+x pgcc.new
- mv -f pgcc.new pgcc
-
-pg++: pgcc.sh
- sed -e 's!EXEC_PREFIX!$(exec_prefix)!g' \
- -e 's!BUILD_PREFIX!$(abspath)!g' \
- -e 's!SRC_PREFIX!$(srcdir)!g' \
- -e 's!COMPILER!g++!g' \
- < $(srcdir)/scripts/pgcc.sh > pg++.new
- chmod a+x pg++.new
- mv -f pg++.new pg++
diff --git a/mit-pthreads/scripts/Makefile.inc b/mit-pthreads/scripts/Makefile.inc
deleted file mode 100644
index 441f6b51d29..00000000000
--- a/mit-pthreads/scripts/Makefile.inc
+++ /dev/null
@@ -1,30 +0,0 @@
-.PATH : ${srcdir}/scripts
-SCRIPTS= pgcc pg++
-
-abspath != pwd
-
-all-bin: $(SCRIPTS)
-
-#
-# Objects go in the obj directory for both BSD and GNU make but these
-# scripts get put in the obj dir for BSD and the root dir for GNU.
-#
-pgcc: pgcc.sh
- sed -e 's!EXEC_PREFIX!$(exec_prefix)!g' \
- -e 's!BUILD_PREFIX!$(.CURDIR)!g' \
- -e 's!SRC_PREFIX!$(srcdir)!g' \
- -e 's!COMPILER!gcc!g' \
- < $(srcdir)/scripts/pgcc.sh > pgcc.new
- chmod a+x pgcc.new
- mv -f pgcc.new pgcc
- ln -fs obj/pgcc ../pgcc
-
-pg++: pgcc.sh
- sed -e 's!EXEC_PREFIX!$(exec_prefix)!g' \
- -e 's!BUILD_PREFIX!$(.CURDIR)!g' \
- -e 's!SRC_PREFIX!$(srcdir)!g' \
- -e 's!COMPILER!g++!g' \
- < $(srcdir)/scripts/pgcc.sh > pg++.new
- chmod a+x pg++.new
- mv -f pg++.new pg++
- ln -fs obj/pg++ ../pg++
diff --git a/mit-pthreads/scripts/pgcc.sh b/mit-pthreads/scripts/pgcc.sh
deleted file mode 100755
index 6bd6cbeccdb..00000000000
--- a/mit-pthreads/scripts/pgcc.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-
-pthreads_root=EXEC_PREFIX
-build_root=BUILD_PREFIX
-src_root=SRC_PREFIX
-
-include_dir='-I$pthreads_root/include'
-lib_dir='-L$pthreads_root/lib'
-libs='-lpthread -lm -lgcc -lpthread'
-
-# Might be a good idea to also provide a way to override pthreads_root
-# so that we can use this script in the build tree, before installation.
-if arg="$1" ; then
- case $arg in
- -notinstalled)
- include_dir='-I$build_root/include -I$src_root/include'
- lib_dir='-L$build_root/obj'
- shift
- ;;
- esac
-fi
-
-for arg in "$@" ; do
- case $arg in
- -nostdinc) include_dir= ;;
- -nostdlib | -c) libs= ;;
- esac
-done
-
-# Include the -L option in any case, just in case the user provided the
-# names of some libraries we've built threaded versions of.
-eval exec COMPILER '"$@"' $include_dir $lib_dir $libs
diff --git a/mit-pthreads/stdio/GNUmakefile.inc b/mit-pthreads/stdio/GNUmakefile.inc
deleted file mode 100755
index 7cb1371661d..00000000000
--- a/mit-pthreads/stdio/GNUmakefile.inc
+++ /dev/null
@@ -1,26 +0,0 @@
-
-# from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91
-# $Id$
-
-# Thread safe stdio sources
-VPATH:= ${VPATH}:${srcdir}/stdio
-
-SRCS:= clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
- fgetline.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \
- fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
- fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \
- getc.c getchar.c gets.c getw.c makebuf.c perror.c putc.c \
- putchar.c puts.c putw.c refill.c remove.c rewind.c rget.c scanf.c \
- setbuf.c setbuffer.c setvbuf.c sscanf.c \
- stdio.c ungetc.c \
- vfscanf.c vscanf.c vsscanf.c \
- wsetup.c putc_unlocked.c putchar_unlocked.c getc_unlocked.c \
- getchar_unlocked.c strerror.c wbuf.c xprintf.c $(SRCS)
-
-# tempnam.c tmpnam.c tmpfile.c
-#
-# SRCS:= sys_errlist.c $(SRCS)
-# sys_errlist.c: make_errlist
-# (FOO=`pwd`; cd ${srcdir}/stdio/make_errlist; \
-# $(MAKE) CC=$(CC) srcdir=${srcdir} objdir=$${FOO})
-# `pwd`/make_errlist;
diff --git a/mit-pthreads/stdio/Makefile.inc b/mit-pthreads/stdio/Makefile.inc
deleted file mode 100644
index 10c598c328f..00000000000
--- a/mit-pthreads/stdio/Makefile.inc
+++ /dev/null
@@ -1,20 +0,0 @@
-
-# from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91
-# $Id$
-
-# Thread safe stdio sources
-.PATH: ${srcdir}/stdio
-
-# SRCS+= tempnam.c tmpfile.c tmpnam.c
-
-SRCS+= clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
- fgetline.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \
- fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
- fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \
- getc.c getchar.c gets.c getw.c makebuf.c perror.c putc.c \
- putchar.c puts.c putw.c refill.c remove.c rewind.c rget.c scanf.c \
- setbuf.c setbuffer.c setvbuf.c sscanf.c \
- stdio.c ungetc.c \
- vfscanf.c vscanf.c vsscanf.c \
- wsetup.c putc_unlocked.c putchar_unlocked.c getc_unlocked.c \
- getchar_unlocked.c strerror.c wbuf.c xprintf.c
diff --git a/mit-pthreads/stdio/README b/mit-pthreads/stdio/README
deleted file mode 100755
index 8e4c07909e9..00000000000
--- a/mit-pthreads/stdio/README
+++ /dev/null
@@ -1,41 +0,0 @@
-Copyright (c) 1993, 1994 Chris Provenzano. All rights reserved.
-
-This is a threadsafe stdio based on the BSD stdio written by Chris Torek.
-This product includes software developed by the Univeristy of California,
-Berkeley and its contributors.
-
-INCLUDE FILES AND PORTING
-To continue to make this package portable, some basic rules on includes
-files must be followed.
-
-pthread.h should be included first (if it is to be included).
-stdio.h should be included.
-
-INTERNAL LOCKING
-1. All functions that can be called by the user must have flockfile() at the
- begining and a funlockfile() at the end. The routine flockfile() is a
- counting mutex, The thread that owns the lock can call flockfile() as
- many times as it wants, but must call an equal number of funlockfile()
- before the lock will be released.
-2. All functions starting with __ shouldn't need addtional locking.
-3. Anything that writes the variable __sglue should lock __sfp_mutex,
- check __sfp_state, and do a condion wait if it is set.
-4. Anything that checks fp->_flag for valididity should also lock
- __sfp_mutex.
-5. Anything that reads the variable __sglue should lock __sfp_mutex, increment
- __sfp_state, and then unlock the mutex. At function return it should
- lock the mutex again decrement __sfp_state and check if zero. If so
- do a cond_signal, and unlock the mutex.
-6. The functions fopen, fdopen, and freopen are the only functions that
- will change a fp->_file
-7. fdopen and fopen both allocate the next fp by locking __sfp_mutex
- checking fp->_flags and then setting it if free.
-8. freopen tries to preserve fp->_file. It sets __sfp_mutex, then it
- tries to lock fp->_file and close it.
-9. __sinit is done with a pthread_once routine.
-
-
-
-Things to do.
-
-Fix printf so it uses the ininf function.
diff --git a/mit-pthreads/stdio/clrerr.c b/mit-pthreads/stdio/clrerr.c
deleted file mode 100644
index e809cfb8efd..00000000000
--- a/mit-pthreads/stdio/clrerr.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)clrerr.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-void clearerr(FILE *fp)
-{
- flockfile(fp);
- fp->_flags &= ~(__SERR|__SEOF);
- funlockfile(fp);
-}
diff --git a/mit-pthreads/stdio/fclose.c b/mit-pthreads/stdio/fclose.c
deleted file mode 100644
index c5db0808f6a..00000000000
--- a/mit-pthreads/stdio/fclose.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fclose.c 5.2 (Berkeley) 2/1/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-/* Do not reset the fd */
-fclose(fp)
- register FILE *fp;
-{
- register int r;
-
- if (fp->_flags) {
- flockfile(fp);
- r = fp->_flags & __SWR ? __sflush(fp) : 0;
- if (fp->_flags & __SMBF)
- free((char *)fp->_bf._base);
- if (HASUB(fp))
- FREEUB(fp);
- if (HASLB(fp))
- FREELB(fp);
- if (__sclose(fp) < 0)
- r = EOF;
-/* funlockfile(fp); Don't unlock. The close() already has. */
- fp->_file = -1;
- fp->_flags = 0; /* release this FILE for reuse, DO THIS LAST */
- return(r);
- }
- errno = EBADF;
- return(EOF);
-}
diff --git a/mit-pthreads/stdio/fdopen.c b/mit-pthreads/stdio/fdopen.c
deleted file mode 100644
index 4c006f24c7c..00000000000
--- a/mit-pthreads/stdio/fdopen.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fdopen.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include "local.h"
-
-extern pthread_mutex_t __sfp_mutex;
-extern pthread_cond_t __sfp_cond;
-extern int __sfp_state;
-
-FILE *fdopen(int fd, const char *mode)
-{
- register FILE *fp;
- int flags, oflags, fdflags, tmp;
-
- if ((flags = __sflags(mode, &oflags)) == 0)
- return (NULL);
-
- /* Make sure the mode the user wants is a subset of the actual mode. */
- if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
- return (NULL);
- tmp = fdflags & O_ACCMODE;
- if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
- errno = EINVAL;
- return (NULL);
- }
-
- __sinit ();
- pthread_mutex_lock(&__sfp_mutex);
- while (__sfp_state) {
- pthread_cond_wait(&__sfp_cond, &__sfp_mutex);
- }
-
- if (fp = __sfp()) {
- fp->_flags = flags;
-
- /*
- * If opened for appending, but underlying descriptor does not have
- * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
- * end before each write.
- */
- if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
- fp->_flags |= __SAPP;
- fp->_file = fd;
-
- }
- pthread_mutex_unlock(&__sfp_mutex);
- return (fp);
-}
diff --git a/mit-pthreads/stdio/feof.c b/mit-pthreads/stdio/feof.c
deleted file mode 100644
index 10946fee581..00000000000
--- a/mit-pthreads/stdio/feof.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)feof.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro feof.
- */
-#undef feof
-
-feof(fp)
- FILE *fp;
-{
- return (__sfeof(fp));
-}
diff --git a/mit-pthreads/stdio/ferror.c b/mit-pthreads/stdio/ferror.c
deleted file mode 100644
index b80ddab037e..00000000000
--- a/mit-pthreads/stdio/ferror.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)ferror.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro ferror.
- */
-#undef ferror
-
-ferror(fp)
- FILE *fp;
-{
- return (__sferror(fp));
-}
diff --git a/mit-pthreads/stdio/fflush.c b/mit-pthreads/stdio/fflush.c
deleted file mode 100644
index 766691045b5..00000000000
--- a/mit-pthreads/stdio/fflush.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fflush.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include "local.h"
-
-/* Flush a single file, or (if fp is NULL) all files. */
-fflush(fp)
- register FILE *fp;
-{
- int retval;
-
- if (fp == NULL)
- return (__swalk_sflush());
- flockfile(fp);
-
- if ((fp->_flags & (__SWR | __SRW)) == 0) {
- errno = EBADF;
- retval = EOF;
- } else {
- retval = __sflush(fp);
- }
- funlockfile(fp);
- return(retval);
-}
-
-__sflush(fp)
- register FILE *fp;
-{
- register unsigned char *p;
- register int n, t;
-
- t = fp->_flags;
- if ((t & __SWR) == 0)
- return (0);
-
- if ((p = fp->_bf._base) == NULL)
- return (0);
-
- n = fp->_p - p; /* write this much */
-
- /*
- * Set these immediately to avoid problems with longjmp and to allow
- * exchange buffering (via setvbuf) in user write function.
- */
- fp->_p = p;
- fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
-
- for (; n > 0; n -= t, p += t) {
- t = __swrite(fp, (char *)p, n);
- if (t <= 0) {
- fp->_flags |= __SERR;
- return (EOF);
- }
- }
- return (0);
-}
diff --git a/mit-pthreads/stdio/fgetc.c b/mit-pthreads/stdio/fgetc.c
deleted file mode 100644
index c5eb2ee5986..00000000000
--- a/mit-pthreads/stdio/fgetc.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fgetc.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-fgetc(fp)
- FILE *fp;
-{
- int ret;
-
- flockfile(fp);
- ret = __sgetc(fp);
- funlockfile(fp);
- return(ret);
-}
-
-int __getc(FILE *_p)
-{
- int ret;
- flockfile(_p);
- ret = __sgetc(_p);
- funlockfile(_p);
- return(ret);
-}
-
diff --git a/mit-pthreads/stdio/fgetline.c b/mit-pthreads/stdio/fgetline.c
deleted file mode 100644
index 219660612f1..00000000000
--- a/mit-pthreads/stdio/fgetline.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fgetline.c 5.2 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "local.h"
-
-/*
- * Expand the line buffer. Return -1 on error.
- * The `new size' does not account for a terminating '\0',
- * so we add 1 here.
- */
-__slbexpand(fp, newsize)
- FILE *fp;
- size_t newsize;
-{
- void *p;
-
- if (fp->_lb._size >= ++newsize)
- return (0);
- if ((p = realloc(fp->_lb._base, newsize)) == NULL)
- return (-1);
- fp->_lb._base = p;
- fp->_lb._size = newsize;
- return (0);
-}
-
-/*
- * Get an input line. The returned pointer often (but not always)
- * points into a stdio buffer. Fgetline smashes the newline (if any)
- * in the stdio buffer; callers must not use it on streams that
- * have `magic' setvbuf() games happening.
- */
-char *
-fgetline(fp, lenp)
- register FILE *fp;
- size_t *lenp;
-{
- register unsigned char *p;
- register size_t len;
- size_t off;
-
- flockfile(fp);
-
- /* make sure there is input */
- if (fp->_r <= 0 && __srefill(fp)) {
- if (lenp != NULL)
- *lenp = 0;
- funlockfile(fp);
- return (NULL);
- }
-
- /* look for a newline in the input */
- if ((p = memchr((void *)fp->_p, '\n', fp->_r)) != NULL) {
- register char *ret;
-
- /*
- * Found one. Flag buffer as modified to keep
- * fseek from `optimising' a backward seek, since
- * the newline is about to be trashed. (We should
- * be able to get away with doing this only if
- * p is not pointing into an ungetc buffer, since
- * fseek discards ungetc data, but this is the
- * usual case anyway.)
- */
- ret = (char *)fp->_p;
- len = p - fp->_p;
- fp->_flags |= __SMOD;
- *p = 0;
- fp->_r -= len + 1;
- fp->_p = p + 1;
- if (lenp != NULL)
- *lenp = len;
- funlockfile(fp);
- return (ret);
- }
-
- /*
- * We have to copy the current buffered data to the line buffer.
- *
- * OPTIMISTIC is length that we (optimistically)
- * expect will accomodate the `rest' of the string,
- * on each trip through the loop below.
- */
-#define OPTIMISTIC 80
-
- for (len = fp->_r, off = 0;; len += fp->_r) {
- register size_t diff;
-
- /*
- * Make sure there is room for more bytes.
- * Copy data from file buffer to line buffer,
- * refill file and look for newline. The
- * loop stops only when we find a newline.
- */
- if (__slbexpand(fp, len + OPTIMISTIC))
- goto error;
- (void) memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
- len - off);
- off = len;
- if (__srefill(fp))
- break; /* EOF or error: return partial line */
- if ((p = memchr((void *)fp->_p, '\n', fp->_r)) == NULL)
- continue;
-
- /* got it: finish up the line (like code above) */
- fp->_flags |= __SMOD; /* soon */
- diff = p - fp->_p;
- len += diff;
- if (__slbexpand(fp, len))
- goto error;
- (void) memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, diff);
- fp->_r -= diff + 1;
- fp->_p = p + 1;
- break;
- }
- if (lenp != NULL)
- *lenp = len;
- fp->_lb._base[len] = 0;
-
- funlockfile(fp);
- return ((char *)fp->_lb._base);
-
-error:
- if (lenp != NULL)
- *lenp = 0; /* ??? */
- funlockfile(fp);
- return (NULL); /* ??? */
-}
diff --git a/mit-pthreads/stdio/fgetpos.c b/mit-pthreads/stdio/fgetpos.c
deleted file mode 100644
index c81b48e3cc8..00000000000
--- a/mit-pthreads/stdio/fgetpos.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fgetpos.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
-#include "local.h"
-
-fgetpos(fp, pos)
- FILE *fp;
- fpos_t *pos;
-{
- flockfile(fp);
-
- /*
- * Find offset of underlying I/O object, then
- * adjust for buffered bytes.
- */
- if (fp->_flags & __SOFF) {
- *pos = fp->_offset;
- } else {
- *pos = __sseek(fp, (off_t)0, SEEK_CUR);
- }
-
- if (*pos != (fpos_t)-1) {
- if (fp->_flags & __SRD) {
- /*
- * Reading. Any unread characters (including
- * those from ungetc) cause the position to be
- * smaller than that in the underlying object.
- */
- *pos -= fp->_r;
- if (HASUB(fp))
- *pos -= fp->_ur;
- } else if (fp->_flags & __SWR && fp->_p != NULL) {
- /*
- * Writing. Any buffered characters cause the
- * position to be greater than that in the
- * underlying object.
- */
- *pos += fp->_p - fp->_bf._base;
- }
- }
- funlockfile(fp);
- return ((*pos) == (fpos_t)-1);
-}
diff --git a/mit-pthreads/stdio/fgets.c b/mit-pthreads/stdio/fgets.c
deleted file mode 100644
index 5ee5c4d6608..00000000000
--- a/mit-pthreads/stdio/fgets.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fgets.c 5.4 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * Read at most n-1 characters from the given file.
- * Stop when a newline has been read, or the count runs out.
- * Return first argument, or NULL if no characters were read.
- */
-char *
-fgets(buf, n, fp)
- char *buf;
- register size_t n;
- register FILE *fp;
-{
- register size_t len;
- register char *s;
- register unsigned char *p, *t;
-
- if (n < 2) /* sanity check */
- return (NULL);
-
- flockfile(fp);
- s = buf;
- n--; /* leave space for NUL */
- do {
- /*
- * If the buffer is empty, refill it.
- */
- if ((len = fp->_r) <= 0) {
- if (__srefill(fp)) {
- /* EOF/error: stop with partial or no line */
- if (s == buf)
- buf = NULL;
- break;
- }
- len = fp->_r;
- }
- p = fp->_p;
-
- /*
- * Scan through at most n bytes of the current buffer,
- * looking for '\n'. If found, copy up to and including
- * newline, and stop. Otherwise, copy entire chunk
- * and loop.
- */
- if (len > n)
- len = n;
- t = memchr((void *)p, '\n', len);
- if (t != NULL) {
- len = ++t - p;
- fp->_r -= len;
- fp->_p = t;
- (void) memcpy((void *)s, (void *)p, len);
- s += len;
- break;
- }
- fp->_r -= len;
- fp->_p += len;
- (void) memcpy((void *)s, (void *)p, len);
- s += len;
- } while ((n -= len) != 0);
-
- *s = 0;
- funlockfile(fp);
- return (buf);
-}
diff --git a/mit-pthreads/stdio/fileno.c b/mit-pthreads/stdio/fileno.c
deleted file mode 100644
index 475bd509993..00000000000
--- a/mit-pthreads/stdio/fileno.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fileno.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro fileno.
- */
-#undef fileno
-
-fileno(fp)
- FILE *fp;
-{
- return (__sfileno(fp));
-}
diff --git a/mit-pthreads/stdio/findfp.c b/mit-pthreads/stdio/findfp.c
deleted file mode 100644
index 35817eb6a5f..00000000000
--- a/mit-pthreads/stdio/findfp.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)findfp.c 5.10 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include "local.h"
-#include "glue.h"
-
-
-#define NSTATIC 20 /* stdin + stdout + stderr + the usual */
-#define NDYNAMIC 10 /* add ten more whenever necessary */
-
-#define std(flags, file) \
- {0,0,0,flags,file,{0},0 }
-/* p r w flags file _bf z */
-
-static FILE usual[NSTATIC - 3]; /* the usual */
-static struct glue uglue = { 0, NSTATIC - 3, usual };
-
-FILE __sF[3] = {
- std(__SRD, 0), /* stdin */
- std(__SWR, 1), /* stdout */
- std(__SWR|__SNBF, 2) /* stderr */
-};
-struct glue __sglue = { &uglue, 3, __sF };
-FILE *__iob = __sF;
-FILE *_iob = __sF;
-
-pthread_mutex_t __sfp_mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t __sfp_cond = PTHREAD_COND_INITIALIZER;
-/*
- * __sfp_state = 0, when free, > 0 when in _fwalk
- * This allows multiple readers in _fwalk, but only one writer __sfp,
- * or freopen() at a time.
- */
-int __sfp_state = 0;
-
-static struct glue *moreglue(register int n)
-{
- register struct glue *g;
- register FILE *p;
- static FILE empty;
-
- g = (struct glue *)malloc(sizeof(struct glue) + n * sizeof(FILE));
- if (g == NULL)
- return (NULL);
- p = (FILE *)(g + 1);
- g->next = NULL;
- g->niobs = n;
- g->iobs = p;
- while (--n >= 0)
- *p++ = empty;
- return (g);
-}
-
-/*
- * Find a free FILE for fopen et al.
- */
-FILE *__sfp()
-{
- register FILE *fp;
- register int n;
- register struct glue *g;
-
- for (g = &__sglue;; g = g->next) {
- for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
- if (fp->_flags == 0) {
- fp->_flags = 1; /* reserve this slot; caller sets real flags */
- fp->_p = NULL; /* no current pointer */
- fp->_w = 0; /* nothing to read or write */
- fp->_r = 0;
- fp->_bf._base = NULL; /* no buffer */
- fp->_bf._size = 0;
- fp->_lbfsize = 0; /* not line buffered */
- fp->_file = -1; /* no file */
- fp->_ub._base = NULL; /* no ungetc buffer */
- fp->_ub._size = 0;
- fp->_lb._base = NULL; /* no line buffer */
- fp->_lb._size = 0;
- goto __sfp_done;
- }
- if (g->next == NULL && (g->next = moreglue(NDYNAMIC)) == NULL) {
- fp = NULL;
- break;
- }
- }
-__sfp_done:;
- return (fp);
-}
-
-/*
- * exit() calls _cleanup() through *__cleanup, set whenever we
- * open or buffer a file. This chicanery is done so that programs
- * that do not use stdio need not link it all in.
- *
- * The name `_cleanup' is, alas, fairly well known outside stdio.
- */
-void _cleanup()
-{
- (void) __swalk_sflush();
-}
-
-/*
- * __sinit() is called whenever stdio's internal variables must be set up.
- * Do the pthread_once stuff here to keep pthread_once_t out of the
- * header files. No reason sprintf.c &c should need to include pthread.h...
- */
-static void __s_real_init ()
-{
- /* make sure we clean up on exit */
- __cleanup = _cleanup;
-}
-
-static pthread_once_t sdidinit = PTHREAD_ONCE_INIT;
-
-void __sinit ()
-{
- pthread_once (&sdidinit, __s_real_init);
-}
diff --git a/mit-pthreads/stdio/flags.c b/mit-pthreads/stdio/flags.c
deleted file mode 100644
index c0971003312..00000000000
--- a/mit-pthreads/stdio/flags.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)flags.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-
-/*
- * Return the (stdio) flags for a given mode. Store the flags
- * to be passed to an open() syscall through *optr.
- * Return 0 on error.
- */
-__sflags(mode, optr)
- register char *mode;
- int *optr;
-{
- register int ret, m, o;
-
- switch (*mode++) {
-
- case 'r': /* open for reading */
- ret = __SRD;
- m = O_RDONLY;
- o = 0;
- break;
-
- case 'w': /* open for writing */
- ret = __SWR;
- m = O_WRONLY;
- o = O_CREAT | O_TRUNC;
- break;
-
- case 'a': /* open for appending */
- ret = __SWR;
- m = O_WRONLY;
- o = O_CREAT | O_APPEND;
- break;
-
- default: /* illegal mode */
- errno = EINVAL;
- return (0);
- }
-
- /* [rwa]\+ or [rwa]b\+ means read and write */
- if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) {
- ret = __SRW;
- m = O_RDWR;
- }
- *optr = m | o;
- return (ret);
-}
diff --git a/mit-pthreads/stdio/floatio.h b/mit-pthreads/stdio/floatio.h
deleted file mode 100644
index cf3821488ae..00000000000
--- a/mit-pthreads/stdio/floatio.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)floatio.h 5.1 (Berkeley) 1/20/91
- * $Id$
- */
-
-/*
- * Floating point scanf/printf (input/output) definitions.
- */
-
-/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
-#define MAXEXP 308
-/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
-#define MAXFRACT 39
diff --git a/mit-pthreads/stdio/fopen.c b/mit-pthreads/stdio/fopen.c
deleted file mode 100644
index d44c17b633f..00000000000
--- a/mit-pthreads/stdio/fopen.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fopen.c 5.5 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <errno.h>
-#include "local.h"
-
-extern pthread_mutex_t __sfp_mutex;
-extern pthread_cond_t __sfp_cond;
-extern int __sfp_state;
-
-FILE *fopen(const char *file, const char *mode)
-{
- register FILE *fp;
- register int f;
- int flags, oflags;
-
- if ((flags = __sflags(mode, &oflags)) == 0)
- return (NULL);
- if ((f = open(file, oflags, 0666)) < 0) {
- return (NULL);
- }
-
- __sinit ();
- pthread_mutex_lock(&__sfp_mutex);
- while (__sfp_state) {
- pthread_cond_wait(&__sfp_cond, &__sfp_mutex);
- }
-
- if (fp = __sfp()) {
- fp->_file = f;
- fp->_flags = flags;
-
- /*
- * When opening in append mode, even though we use O_APPEND,
- * we need to seek to the end so that ftell() gets the right
- * answer. If the user then alters the seek pointer, or
- * the file extends, this will fail, but there is not much
- * we can do about this. (We could set __SAPP and check in
- * fseek and ftell.)
- */
- if (oflags & O_APPEND)
- (void) __sseek((void *)fp, (off_t)0, SEEK_END);
- }
- pthread_mutex_unlock(&__sfp_mutex);
- return (fp);
-}
diff --git a/mit-pthreads/stdio/fprintf.c b/mit-pthreads/stdio/fprintf.c
deleted file mode 100644
index bdeb49c054d..00000000000
--- a/mit-pthreads/stdio/fprintf.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fprintf.c 5.6 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#if __STDC__
-fprintf(FILE *fp, const char *fmt, ...)
-#else
-fprintf(fp, fmt, va_alist)
- FILE *fp;
- char *fmt;
- va_dcl
-#endif
-{
- int ret;
- va_list ap;
-
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- ret = vfprintf(fp, fmt, ap);
- va_end(ap);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/fpurge.c b/mit-pthreads/stdio/fpurge.c
deleted file mode 100644
index 7edbb0b30cd..00000000000
--- a/mit-pthreads/stdio/fpurge.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fpurge.c 5.2 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-/*
- * fpurge: like fflush, but without writing anything: leave the
- * given FILE's buffer empty.
- */
-int
-fpurge(fp)
- register FILE *fp;
-{
- int ret;
-
- flockfile(fp);
- if (fp->_flags) {
- if (HASUB(fp))
- FREEUB(fp);
- fp->_p = fp->_bf._base;
- fp->_r = 0;
- fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
- ret = 0;
- } else {
- errno = EBADF;
- ret = EOF;
- }
- funlockfile(fp);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/fputc.c b/mit-pthreads/stdio/fputc.c
deleted file mode 100644
index e6dd752f81b..00000000000
--- a/mit-pthreads/stdio/fputc.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fputc.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-fputc(c, fp)
- int c;
- register FILE *fp;
-{
- int ret;
- flockfile(fp);
- ret = __sputc(c, fp);
- funlockfile(fp);
- return(ret);
-}
-
-int __putc(int _c, FILE *_p)
-{
- int ret;
- flockfile(_p);
- ret = __sputc(_c, _p);
- funlockfile(_p);
- return(ret);
-}
-
-int __sputc(int _c, FILE *_p)
-{
- if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
- return (*_p->_p++ = _c);
- else
- return (__swbuf(_c, _p));
-}
-
diff --git a/mit-pthreads/stdio/fputs.c b/mit-pthreads/stdio/fputs.c
deleted file mode 100644
index 882b828409e..00000000000
--- a/mit-pthreads/stdio/fputs.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fputs.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-#include "fvwrite.h"
-
-/*
- * Write the given string to the given file.
- */
-fputs(s, fp)
- const char *s;
- FILE *fp;
-{
- struct __suio uio;
- struct __siov iov;
- int ret;
-
- iov.iov_base = (void *)s;
- iov.iov_len = uio.uio_resid = strlen(s);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- flockfile(fp);
- ret = __sfvwrite(fp, &uio);
- funlockfile(fp);
- return(ret);
-}
diff --git a/mit-pthreads/stdio/fread.c b/mit-pthreads/stdio/fread.c
deleted file mode 100644
index 0d8ec6186c7..00000000000
--- a/mit-pthreads/stdio/fread.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fread.c 5.4 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-
-size_t
-fread(buf, size, count, fp)
- void *buf;
- size_t size, count;
- register FILE *fp;
-{
- register size_t resid;
- register char *p;
- register int r;
- size_t total;
-
- if ((resid = count * size) == 0)
- return (count);
-
- flockfile(fp);
- if (fp->_r < 0)
- fp->_r = 0;
- total = resid;
- p = buf;
- while (resid > (r = fp->_r)) {
- (void) memcpy((void *)p, (void *)fp->_p, (size_t)r);
- fp->_p += r;
- /* fp->_r = 0 ... done in __srefill */
- p += r;
- resid -= r;
- if (__srefill(fp)) {
- /* no more input: return partial result */
- count = (total - resid) / size;
- goto done_fread;
- }
- }
- (void) memcpy((void *)p, (void *)fp->_p, resid);
- fp->_r -= resid;
- fp->_p += resid;
-done_fread:;
- funlockfile(fp);
- return (count);
-}
diff --git a/mit-pthreads/stdio/freopen.c b/mit-pthreads/stdio/freopen.c
deleted file mode 100644
index f45571c8ea0..00000000000
--- a/mit-pthreads/stdio/freopen.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)freopen.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-extern pthread_mutex_t __sfp_mutex;
-extern pthread_cond_t __sfp_cond;
-extern int __sfp_state;
-
-/*
- * Re-direct an existing, open (probably) file to some other file.
- * ANSI is written such that the original file gets closed if at
- * all possible, no matter what.
- */
-FILE *
-freopen(file, mode, fp)
- const char *file, *mode;
- register FILE *fp;
-{
- int f, flags, oflags;
- FILE *ret;
-
- if ((flags = __sflags(mode, &oflags)) == 0) {
- (void) fclose(fp);
- return (NULL);
- }
-
- __sinit ();
-
- /*
- * There are actually programs that depend on being able to "freopen"
- * descriptors that weren't originally open. Keep this from breaking.
- * Remember whether the stream was open to begin with, and which file
- * descriptor (if any) was associated with it. If it was attached to
- * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
- * should work. This is unnecessary if it was not a Unix file.
- */
- /* while lock __sfp_mutex, to block out fopen, and other freopen calls */
- while (pthread_mutex_lock(&__sfp_mutex) == OK) {
- if (ftrylockfile(fp) == OK) {
- if (fp->_flags) {
- /* flush the stream; ANSI doesn't require this. */
- if (fp->_flags & __SWR)
- (void) __sflush(fp);
- __sclose(fp);
- /*
- * Finish closing fp. We cannot keep fp->_base:
- * it may be the wrong size. This loses the effect
- * of any setbuffer calls, but stdio has always done
- * this before.
- * NOTE: We do this even if __ftrylockfilr failed with
- * an error to avoid memory leaks.
- */
- if (fp->_flags & __SMBF)
- free((char *)fp->_bf._base);
- fp->_w = 0;
- fp->_r = 0;
- fp->_p = NULL;
- fp->_bf._base = NULL;
- fp->_bf._size = 0;
- fp->_lbfsize = 0;
- if (HASUB(fp))
- FREEUB(fp);
- fp->_ub._size = 0;
- if (HASLB(fp))
- FREELB(fp);
- fp->_lb._size = 0;
- }
- /* Get a new descriptor to refer to the new file. */
- if ((f = open(file, oflags, 0666)) < OK)
- ret = NULL;
- /*
- * If reopening something that was open before on a real file, try
- * to maintain the descriptor. Various C library routines (perror)
- * assume stderr is always fd STDERR_FILENO, even if being
- * freopen'd.
- */
- /* Testing f == fp->_file may no longer be necessary */
- if (fp->_file >= 0 && f != fp->_file) {
- if (dup2(f, fp->_file) >= OK) {
- (void)close(f);
- f = fp->_file;
- }
- }
- fp->_flags = flags;
- fp->_file = f;
- ret = fp;
- } else {
- /* unlock __sfp_mutex, and try again later */
- pthread_mutex_unlock(&__sfp_mutex);
- pthread_yield();
- continue;
- }
- /* @@ Yo, Chris! Between the "break" and "continue" statements
- above, the program will never get here. What gives? */
- pthread_mutex_unlock(&__sfp_mutex);
- funlockfile(fp);
- return(ret);
- }
- (void)fclose(fp);
- return(NULL);
-}
diff --git a/mit-pthreads/stdio/fscanf.c b/mit-pthreads/stdio/fscanf.c
deleted file mode 100644
index 8fbbac5d102..00000000000
--- a/mit-pthreads/stdio/fscanf.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fscanf.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#if __STDC__
-fscanf(FILE *fp, char const *fmt, ...) {
- int r;
- va_list ap;
-
- va_start(ap, fmt);
-#else
-fscanf(fp, fmt, va_alist)
- FILE *fp;
- char *fmt;
- va_dcl
-{
- int r;
- va_list ap;
-
- va_start(ap);
-#endif
- flockfile(fp);
- r = __svfscanf(fp, fmt, ap);
- funlockfile(fp);
- va_end(ap);
- return(r);
-}
diff --git a/mit-pthreads/stdio/fseek.c b/mit-pthreads/stdio/fseek.c
deleted file mode 100644
index 5c7feda638f..00000000000
--- a/mit-pthreads/stdio/fseek.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fseek.c 5.7 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include "local.h"
-
-#define POS_ERR (-(fpos_t)1)
-
-/*
- * Seek the given file to the given offset.
- * `Whence' must be one of the three SEEK_* macros.
- */
-fseek(fp, offset, whence)
- register FILE *fp;
- long offset;
- int whence;
-{
-#if __STDC__
- register fpos_t (*seekfn)(void *, fpos_t, int);
-#else
- register fpos_t (*seekfn)();
-#endif
- fpos_t target, curoff;
- size_t n;
- struct stat st;
- int havepos;
-
- /* make sure stdio is set up */
- __sinit ();
-
- flockfile(fp);
-
- /*
- * Change any SEEK_CUR to SEEK_SET, and check `whence' argument.
- * After this, whence is either SEEK_SET or SEEK_END.
- */
- switch (whence) {
- case SEEK_CUR:
- /*
- * In order to seek relative to the current stream offset,
- * we have to first find the current stream offset a la
- * ftell (see ftell for details).
- */
- if (fp->_flags & __SOFF)
- curoff = fp->_offset;
- else {
- curoff = __sseek(fp, (off_t)0, SEEK_CUR);
- if (curoff == -1L) {
- funlockfile(fp);
- return (EOF);
- }
- }
- if (fp->_flags & __SRD) {
- curoff -= fp->_r;
- if (HASUB(fp))
- curoff -= fp->_ur;
- } else if (fp->_flags & __SWR && fp->_p != NULL)
- curoff += fp->_p - fp->_bf._base;
-
- offset += curoff;
- whence = SEEK_SET;
- havepos = 1;
- break;
-
- case SEEK_SET:
- case SEEK_END:
- curoff = 0; /* XXX just to keep gcc quiet */
- havepos = 0;
- break;
-
- default:
- errno = EINVAL;
- funlockfile(fp);
- return (EOF);
- }
-
- /*
- * Can only optimise if:
- * reading (and not reading-and-writing);
- * not unbuffered; and
- * this is a `regular' Unix file (and hence seekfn==__sseek).
- * We must check __NBF first, because it is possible to have __NBF
- * and __SOPT both set.
- */
- if (fp->_bf._base == NULL)
- __smakebuf(fp);
- if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
- goto dumb;
- if ((fp->_flags & __SOPT) == 0) {
- if (fp->_file < 0 || fstat(fp->_file, &st) ||
- (st.st_mode & S_IFMT) != S_IFREG) {
- fp->_flags |= __SNPT;
- goto dumb;
- }
- fp->_blksize = st.st_blksize;
- fp->_flags |= __SOPT;
- }
-
- /*
- * We are reading; we can try to optimise.
- * Figure out where we are going and where we are now.
- */
- if (whence == SEEK_SET)
- target = offset;
- else {
- if (fstat(fp->_file, &st))
- goto dumb;
- target = st.st_size + offset;
- }
-
- if (!havepos) {
- if (fp->_flags & __SOFF)
- curoff = fp->_offset;
- else {
- curoff = __sseek(fp, (off_t)0, SEEK_CUR);
- if (curoff == POS_ERR)
- goto dumb;
- }
- curoff -= fp->_r;
- if (HASUB(fp))
- curoff -= fp->_ur;
- }
-
- /*
- * Compute the number of bytes in the input buffer (pretending
- * that any ungetc() input has been discarded). Adjust current
- * offset backwards by this count so that it represents the
- * file offset for the first byte in the current input buffer.
- */
- if (HASUB(fp)) {
- n = fp->_up - fp->_bf._base;
- curoff -= n;
- n += fp->_ur;
- } else {
- n = fp->_p - fp->_bf._base;
- curoff -= n;
- n += fp->_r;
- }
-
- /*
- * If the target offset is within the current buffer,
- * simply adjust the pointers, clear EOF, undo ungetc(),
- * and return. (If the buffer was modified, we have to
- * skip this; see fgetline.c.)
- */
- if ((fp->_flags & __SMOD) == 0 &&
- target >= curoff && target < curoff + n) {
- register int o = target - curoff;
-
- fp->_p = fp->_bf._base + o;
- fp->_r = n - o;
- if (HASUB(fp))
- FREEUB(fp);
- fp->_flags &= ~__SEOF;
- funlockfile(fp);
- return (0);
- }
-
- /*
- * The place we want to get to is not within the current buffer,
- * but we can still be kind to the kernel copyout mechanism.
- * By aligning the file offset to a block boundary, we can let
- * the kernel use the VM hardware to map pages instead of
- * copying bytes laboriously. Using a block boundary also
- * ensures that we only read one block, rather than two.
- */
- curoff = target & ~(fp->_blksize - 1);
- if (__sseek(fp, (off_t)curoff, SEEK_SET) != POS_ERR) {
- fp->_r = 0;
- fp->_p = fp->_bf._base;
- if (HASUB(fp))
- FREEUB(fp);
- fp->_flags &= ~__SEOF;
- n = target - curoff;
- if (n) {
- if (__srefill(fp) || fp->_r < n)
- goto dumb;
- fp->_p += n;
- fp->_r -= n;
- }
- funlockfile(fp);
- return (0);
- }
-
- /*
- * We get here if we cannot optimise the seek ... just
- * do it. Allow the seek function to change fp->_bf._base.
- */
-dumb:
- if (__sflush(fp) || __sseek(fp, (off_t)offset, whence) == POS_ERR) {
- funlockfile(fp);
- return (EOF);
- }
- /* success: clear EOF indicator and discard ungetc() data */
- if (HASUB(fp))
- FREEUB(fp);
- fp->_p = fp->_bf._base;
- fp->_r = 0;
- /* fp->_w = 0; */ /* unnecessary (I think...) */
- fp->_flags &= ~__SEOF;
- funlockfile(fp);
- return (0);
-}
diff --git a/mit-pthreads/stdio/fsetpos.c b/mit-pthreads/stdio/fsetpos.c
deleted file mode 100644
index a421d405f51..00000000000
--- a/mit-pthreads/stdio/fsetpos.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fsetpos.c 5.2 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-/*
- * fsetpos: like fseek.
- * Don't bother locking, fseek does it.
- */
-fsetpos(iop, pos)
- FILE *iop;
- const fpos_t *pos;
-{
- return (fseek(iop, (long)*pos, SEEK_SET));
-}
diff --git a/mit-pthreads/stdio/ftell.c b/mit-pthreads/stdio/ftell.c
deleted file mode 100644
index e5961fa50b6..00000000000
--- a/mit-pthreads/stdio/ftell.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)ftell.c 5.4 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-#include "local.h"
-
-/*
- * ftell: return current offset.
- */
-long
-ftell(fp)
- register const FILE *fp;
-{
- long pos;
-
- flockfile((FILE *)fp);
-
- /*
- * Find offset of underlying I/O object, then
- * adjust for buffered bytes.
- */
- if (fp->_flags & __SOFF) {
- pos = fp->_offset;
- } else {
- pos = (long)__sseek((FILE *)fp, (off_t)0, SEEK_CUR);
- }
-
- if (pos != -1L) {
- if (fp->_flags & __SRD) {
- /*
- * Reading. Any unread characters (including
- * those from ungetc) cause the position to be
- * smaller than that in the underlying object.
- */
- pos -= fp->_r;
- if (HASUB(fp))
- pos -= fp->_ur;
- } else if (fp->_flags & __SWR && fp->_p != NULL) {
- /*
- * Writing. Any buffered characters cause the
- * position to be greater than that in the
- * underlying object.
- */
- pos += fp->_p - fp->_bf._base;
- }
- }
- funlockfile((FILE *)fp);
- return (pos);
-}
diff --git a/mit-pthreads/stdio/funopen.c b/mit-pthreads/stdio/funopen.c
deleted file mode 100644
index f8b37ed0ae4..00000000000
--- a/mit-pthreads/stdio/funopen.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)funopen.c 5.2 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <errno.h>
-#include "local.h"
-
-FILE *
-funopen(cookie, readfn, writefn, seekfn, closefn)
- const void *cookie;
- int (*readfn)(), (*writefn)();
-#if __STDC__
- fpos_t (*seekfn)(void *cookie, fpos_t off, int whence);
-#else
- fpos_t (*seekfn)();
-#endif
- int (*closefn)();
-{
- struct fd_ops *fd_ops;
- char *flags;
- FILE *fp;
- int fd;
-
- if (readfn == NULL) {
- if (writefn == NULL) { /* illegal */
- errno = EINVAL;
- return (NULL);
- } else
- flags = "w"; /* write only */
- } else {
- if (writefn == NULL)
- flags = "r"; /* read only */
- else
- flags = "r+"; /* read-write */
- }
-
- if (fd_ops = (struct fd_ops*)malloc(sizeof(struct fd_ops))) {
- if ((fd = fd_allocate()) >= OK) {
-
- /* Set functions */
- fd_ops->seek = (off_t(*)())seekfn;
- fd_ops->read = (pthread_ssize_t(*)())readfn;
- fd_ops->write = (pthread_ssize_t(*)())writefn;
- fd_ops->close = closefn;
- fd_ops->use_kfds = 2;
-
- /* Alloc space for funtion pointer table */
- fd_table[fd]->type = FD_HALF_DUPLEX;
- fd_table[fd]->ops = fd_ops;
- fd_table[fd]->flags = O_RDWR;
-
- /* Save the cookie, it's important */
- fd_table[fd]->fd.ptr = (void *)cookie;
-
- if (fp = fdopen(fd, flags))
- return(fp);
-
- fd_free(fd);
- }
- free(fd_ops);
- }
- return(NULL);
-}
diff --git a/mit-pthreads/stdio/fvwrite.c b/mit-pthreads/stdio/fvwrite.c
deleted file mode 100644
index 5ed25b4e7b4..00000000000
--- a/mit-pthreads/stdio/fvwrite.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fvwrite.c 5.3 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "local.h"
-#include "fvwrite.h"
-
-/*
- * Write some memory regions. Return zero on success, EOF on error.
- *
- * This routine is large and unsightly, but most of the ugliness due
- * to the three different kinds of output buffering is handled here.
- */
-__sfvwrite(fp, uio)
- register FILE *fp;
- register struct __suio *uio;
-{
- register size_t len;
- register char *p;
- register struct __siov *iov;
- register int w, s;
- char *nl;
- int nlknown, nldist;
-
- if ((len = uio->uio_resid) == 0)
- return (0);
- /* make sure we can write */
- if (cantwrite(fp))
- return (EOF);
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define COPY(n) (void) memcpy((void *)fp->_p, (void *)p, (size_t)(n));
-
- iov = uio->uio_iov;
- p = iov->iov_base;
- len = iov->iov_len;
- iov++;
-#define GETIOV(extra_work) \
- while (len == 0) { \
- extra_work; \
- p = iov->iov_base; \
- len = iov->iov_len; \
- iov++; \
- }
- if (fp->_flags & __SNBF) {
- /*
- * Unbuffered: write up to BUFSIZ bytes at a time.
- */
- do {
- GETIOV(;);
- w = __swrite(fp, p, MIN(len, BUFSIZ));
- if (w <= 0)
- goto err;
- p += w;
- len -= w;
- } while ((uio->uio_resid -= w) != 0);
- } else if ((fp->_flags & __SLBF) == 0) {
- /*
- * Fully buffered: fill partially full buffer, if any,
- * and then flush. If there is no partial buffer, write
- * one _bf._size byte chunk directly (without copying).
- *
- * String output is a special case: write as many bytes
- * as fit, but pretend we wrote everything. This makes
- * snprintf() return the number of bytes needed, rather
- * than the number used, and avoids its write function
- * (so that the write function can be invalid).
- */
- do {
- GETIOV(;);
- w = fp->_w;
- if (fp->_flags & __SSTR) {
- if (len < w)
- w = len;
- COPY(w); /* copy MIN(fp->_w,len), */
- fp->_w -= w;
- fp->_p += w;
- w = len; /* but pretend copied all */
- } else if (fp->_p > fp->_bf._base && len > w) {
- /* fill and flush */
- COPY(w);
- /* fp->_w -= w; */ /* unneeded */
- fp->_p += w;
- if (fflush(fp))
- goto err;
- } else if (len >= (w = fp->_bf._size)) {
- if ((w = __swrite(fp, p, w)) <= 0)
- goto err;
- } else {
- /* fill and done */
- w = len;
- COPY(w);
- fp->_w -= w;
- fp->_p += w;
- }
- p += w;
- len -= w;
- } while ((uio->uio_resid -= w) != 0);
- } else {
- /*
- * Line buffered: like fully buffered, but we
- * must check for newlines. Compute the distance
- * to the first newline (including the newline),
- * or `infinity' if there is none, then pretend
- * that the amount to write is MIN(len,nldist).
- */
- nlknown = 0;
- nldist = 0; /* XXX just to keep gcc happy */
- do {
- GETIOV(nlknown = 0);
- if (!nlknown) {
- nl = memchr((void *)p, '\n', len);
- nldist = nl ? nl + 1 - p : len + 1;
- nlknown = 1;
- }
- s = MIN(len, nldist);
- w = fp->_w + fp->_bf._size;
- if (fp->_p > fp->_bf._base && s > w) {
- COPY(w);
- /* fp->_w -= w; */
- fp->_p += w;
- if (fflush(fp))
- goto err;
- } else if (s >= (w = fp->_bf._size)) {
- if ((w = __swrite(fp, p, w)) <= 0)
- goto err;
- } else {
- w = s;
- COPY(w);
- fp->_w -= w;
- fp->_p += w;
- }
- if ((nldist -= w) == 0) {
- /* copied the newline: flush and forget */
- if (fflush(fp))
- goto err;
- nlknown = 0;
- }
- p += w;
- len -= w;
- } while ((uio->uio_resid -= w) != 0);
- }
- return (0);
-
-err:
- fp->_flags |= __SERR;
- return (EOF);
-}
diff --git a/mit-pthreads/stdio/fvwrite.h b/mit-pthreads/stdio/fvwrite.h
deleted file mode 100644
index b3474563a4e..00000000000
--- a/mit-pthreads/stdio/fvwrite.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)fvwrite.h 5.1 (Berkeley) 1/20/91
- * $Id$
- */
-
-/*
- * I/O descriptors for __sfvwrite().
- */
-struct __siov {
- void *iov_base;
- size_t iov_len;
-};
-
-struct __suio {
- struct __siov *uio_iov;
- int uio_iovcnt;
- int uio_resid;
-};
-
-extern int __sfvwrite __P_(( FILE *, struct __suio *));
diff --git a/mit-pthreads/stdio/fwalk.c b/mit-pthreads/stdio/fwalk.c
deleted file mode 100644
index 58a199e0707..00000000000
--- a/mit-pthreads/stdio/fwalk.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fwalk.c 5.2 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include "local.h"
-#include "glue.h"
-
-extern pthread_mutex_t __sfp_mutex;
-extern pthread_cond_t __sfp_cond;
-extern int __sfp_state;
-
-/*
- * fwalk now can only be used for flushing the buffers.
- * This is all it was originally used for.
- * The function has also become much more complicated.
- * The first time through we flush everything we can.
- * If this fails to flush everything because we couldn't get a lock
- * we wait on the locksfor the second pass. Why this works ...
- *
- * This function must allow for multiple threads to flush everything.
- * This function cannot flush buffers locked by another thread.
- * So we flush everything we can the first pass. This includes all
- * buffers locked by this thread, and wait on buffers that are locked.
- * Eventually other threads willl unlock there buffers or flush them themselves
- * at which point this thread will notice that it's empty or be able to
- * flush the buffer. This is fine so long as no other thread tries to flush
- * all buffers. Here is the possible deadlock condition, but since this thread
- * has flushed all buffers it can, there are NO buffers locked by this thread
- * that need flushing so any other thread flushing won't block waiting on this
- * thread thereby eliminating the deadlock condition.
- */
-
-int __swalk_sflush()
-{
- register FILE *fp, *savefp;
- register int n, ret, saven;
- register struct glue *g, *saveg;
-
- /* Only allow other threads to read __sglue */
- pthread_mutex_lock(&__sfp_mutex);
- __sfp_state++;
- pthread_mutex_unlock(&__sfp_mutex);
-
- ret = 0;
- saven = 0;
- saveg = NULL;
- savefp = NULL;
- for (g = &__sglue; g != NULL; g = g->next) {
- for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) {
- if (fp->_flags != 0) {
- /* Is there anything to flush? */
- if (fp->_bf._base && (fp->_bf._base - fp->_p)) {
- if (ftrylockfile(fp)) { /* Can we flush it */
- if (!saven) { /* No, save first fp we can't flush */
- saven = n;
- saveg = g;
- savefp = fp;
- continue;
- }
- } else {
- ret |= __sflush(fp);
- funlockfile(fp);
- }
- }
- }
- }
- }
- if (savefp) {
- for (g = saveg; g != NULL; g = g->next) {
- for (fp = savefp, n = saven + 1; --n >= 0; fp++) {
- if (fp->_flags != 0) {
- /* Anything to flush */
- while (fp->_bf._base && (fp->_bf._base - fp->_p)) {
- flockfile(fp);
- ret |= __sflush(fp);
- funlockfile(fp);
- }
- }
- }
- }
- }
-
- /* If no other readers wakeup a thread waiting to do __sfp */
- pthread_mutex_lock(&__sfp_mutex);
- if (! (--__sfp_state)) {
- pthread_cond_signal(&__sfp_cond);
- }
- pthread_mutex_unlock(&__sfp_mutex);
- return (ret);
-}
-
diff --git a/mit-pthreads/stdio/fwrite.c b/mit-pthreads/stdio/fwrite.c
deleted file mode 100644
index 5eada4ee84b..00000000000
--- a/mit-pthreads/stdio/fwrite.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)fwrite.c 5.5 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include "local.h"
-#include "fvwrite.h"
-
-/*
- * Write `count' objects (each size `size') from memory to the given file.
- * Return the number of whole objects written.
- */
-size_t
-fwrite(buf, size, count, fp)
- const void *buf;
- size_t size, count;
- FILE *fp;
-{
- struct __suio uio;
- struct __siov iov;
- size_t n;
-
- iov.iov_base = (void *)buf;
- uio.uio_resid = iov.iov_len = n = count * size;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- if (! n)
- return(0);
-
- flockfile(fp);
-
- /*
- * The usual case is success (__sfvwrite returns 0);
- * skip the divide if this happens, since divides are
- * generally slow and since this occurs whenever size==0.
- */
- if (__sfvwrite(fp, &uio) == 0)
- count = (n - uio.uio_resid) / size;
- funlockfile(fp);
- return(count);
-}
diff --git a/mit-pthreads/stdio/getc.c b/mit-pthreads/stdio/getc.c
deleted file mode 100644
index 6896e78bc7e..00000000000
--- a/mit-pthreads/stdio/getc.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getc.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro getc.
- */
-#undef getc
-
-getc(fp)
- register FILE *fp;
-{
- int ret;
- flockfile(fp);
- ret = __sgetc(fp);
- funlockfile(fp);
- return(ret);
-}
diff --git a/mit-pthreads/stdio/getc_unlocked.c b/mit-pthreads/stdio/getc_unlocked.c
deleted file mode 100644
index 01db3bcea2a..00000000000
--- a/mit-pthreads/stdio/getc_unlocked.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getc.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro getc.
- */
-#undef getc_unlocked
-
-getc_unlocked(fp)
- register FILE *fp;
-{
- return (__sgetc(fp));
-}
diff --git a/mit-pthreads/stdio/getchar.c b/mit-pthreads/stdio/getchar.c
deleted file mode 100644
index 6e631c6c1b1..00000000000
--- a/mit-pthreads/stdio/getchar.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getchar.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * A subroutine version of the macro getchar.
- */
-#include <pthread.h>
-#include <stdio.h>
-
-#undef getchar
-
-getchar()
-{
- int ret;
- flockfile(stdin);
- ret = getc(stdin);
- funlockfile(stdin);
- return(ret);
-}
diff --git a/mit-pthreads/stdio/getchar_unlocked.c b/mit-pthreads/stdio/getchar_unlocked.c
deleted file mode 100644
index 40945c5dd57..00000000000
--- a/mit-pthreads/stdio/getchar_unlocked.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getchar.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * A subroutine version of the macro getchar.
- */
-#include <pthread.h>
-#include <stdio.h>
-
-#undef getchar_unlocked
-
-getchar_unlocked()
-{
- return (getc(stdin));
-}
diff --git a/mit-pthreads/stdio/gets.c b/mit-pthreads/stdio/gets.c
deleted file mode 100644
index 0e7967ae3fe..00000000000
--- a/mit-pthreads/stdio/gets.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)gets.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
-
-char *
-gets(buf)
- char *buf;
-{
- register int c;
- register char *s;
- static int warned;
- static char w[] =
- "warning: this program uses gets(), which is unsafe.\r\n";
-
- if (!warned) {
- (void) write(STDERR_FILENO, w, sizeof(w) - 1);
- warned = 1;
- }
- for (s = buf; (c = getchar()) != '\n';)
- if (c == EOF)
- if (s == buf)
- return (NULL);
- else
- break;
- else
- *s++ = c;
- *s = 0;
- return (buf);
-}
diff --git a/mit-pthreads/stdio/getw.c b/mit-pthreads/stdio/getw.c
deleted file mode 100644
index 623ba6258a1..00000000000
--- a/mit-pthreads/stdio/getw.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)getw.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-getw(fp)
- FILE *fp;
-{
- int x;
-
- return (fread((void *)&x, sizeof(x), 1, fp) == 1 ? x : EOF);
-}
diff --git a/mit-pthreads/stdio/glue.h b/mit-pthreads/stdio/glue.h
deleted file mode 100644
index e5103bbb0b3..00000000000
--- a/mit-pthreads/stdio/glue.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)glue.h 5.1 (Berkeley) 1/20/91
- * $Id$
- */
-
-/*
- * The first few FILEs are statically allocated; others are dynamically
- * allocated and linked in via this glue structure.
- */
-typedef struct glue {
- struct glue *next;
- int niobs;
- FILE *iobs;
-} __sglue_type;
-extern struct glue __sglue;
diff --git a/mit-pthreads/stdio/local.h b/mit-pthreads/stdio/local.h
deleted file mode 100644
index 068754fad38..00000000000
--- a/mit-pthreads/stdio/local.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)local.h 5.3 (Berkeley) 5/6/93
- * $Id$
- */
-
-/*
- * Information local to this implementation of stdio,
- * in particular, macros and private variables.
- */
-
-#include <sys/types.h>
-#include <stddef.h>
-
-extern FILE *__sfp __P_((void));
-extern int __sflush __P_((FILE *));
-extern int __srefill __P_((FILE *));
-extern int __swrite __P_((FILE *, const char *, int));
-extern int __sread __P_((FILE *, char *, int));
-extern fpos_t __sseek __P_((FILE *, off_t, int));
-extern int __sclose __P_((FILE *));
-extern void __sinit __P_((void));
-extern void _cleanup __P_((void));
-extern void __smakebuf __P_((FILE *));
-extern int __swhatbuf __P_((FILE *, size_t *, int *));
-extern int __swalk_sflush __P_(());
-extern int __swsetup __P_((FILE *));
-extern int __sflags __P_((const char *, int *));
-
-extern void (*__cleanup) __P_((void));
-
-/*
- * Return true iff the given FILE cannot be written now.
- */
-#define cantwrite(fp) \
- ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
- __swsetup(fp))
-
-/*
- * Test whether the given stdio file has an active ungetc buffer;
- * release such a buffer, without restoring ordinary unread data.
- */
-#define HASUB(fp) ((fp)->_ub._base != NULL)
-#define FREEUB(fp) { \
- if ((fp)->_ub._base != (fp)->_ubuf) \
- free((char *)(fp)->_ub._base); \
- (fp)->_ub._base = NULL; \
-}
-
-/*
- * test for an fgetline() buffer.
- */
-#define HASLB(fp) ((fp)->_lb._base != NULL)
-#define FREELB(fp) { \
- free((char *)(fp)->_lb._base); \
- (fp)->_lb._base = NULL; \
-}
diff --git a/mit-pthreads/stdio/makebuf.c b/mit-pthreads/stdio/makebuf.c
deleted file mode 100644
index 316abe054b6..00000000000
--- a/mit-pthreads/stdio/makebuf.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)makebuf.c 5.3 (Berkeley) 5/6/93";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-void (*__cleanup) __P_((void));
-
-/*
- * Allocate a file buffer, or switch to unbuffered I/O.
- * Per the ANSI C standard, ALL tty devices default to line buffered.
- *
- * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
- * optimisation) right after the fstat() that finds the buffer size.
- */
-void
-__smakebuf(fp)
- register FILE *fp;
-{
- register void *p;
- register int flags;
- size_t size;
- int couldbetty;
-
- if (fp->_flags & __SNBF) {
- fp->_bf._base = fp->_p = fp->_nbuf;
- fp->_bf._size = 1;
- return;
- }
- flags = __swhatbuf(fp, &size, &couldbetty);
- if ((p = malloc(size)) == NULL) {
- fp->_flags |= __SNBF;
- fp->_bf._base = fp->_p = fp->_nbuf;
- fp->_bf._size = 1;
- return;
- }
- __cleanup = _cleanup;
- flags |= __SMBF;
- fp->_bf._base = fp->_p = p;
- fp->_bf._size = size;
- if (couldbetty && isatty(fp->_file))
- flags |= __SLBF;
- fp->_flags |= flags;
-}
-
-/*
- * Internal routine to determine `proper' buffering for a file.
- */
-int
-__swhatbuf(fp, bufsize, couldbetty)
- register FILE *fp;
- size_t *bufsize;
- int *couldbetty;
-{
- struct stat st;
-
- if (fp->_file < 0 || fstat(fp->_file, &st) < 0) {
- *couldbetty = 0;
- *bufsize = BUFSIZ;
- return (__SNPT);
- }
-
- /* could be a tty iff it is a character device */
- *couldbetty = (st.st_mode & S_IFMT) == S_IFCHR;
- if (st.st_blksize <= 0) {
- *bufsize = BUFSIZ;
- return (__SNPT);
- }
-
- /*
- * Optimise fseek() only if it is a regular file. (The test for
- * __sseek is mainly paranoia.) It is safe to set _blksize
- * unconditionally; it will only be used if __SOPT is also set.
- */
- *bufsize = st.st_blksize;
- fp->_blksize = st.st_blksize;
- return ((st.st_mode & S_IFMT) == S_IFREG ? __SOPT : __SNPT);
-}
diff --git a/mit-pthreads/stdio/mktemp.c b/mit-pthreads/stdio/mktemp.c
deleted file mode 100644
index 7fdc631ad0b..00000000000
--- a/mit-pthreads/stdio/mktemp.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)mktemp.c 5.10 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-
-static int _gettemp();
-
-mkstemp(path)
- char *path;
-{
- int fd;
-
- return (_gettemp(path, &fd) ? fd : -1);
-}
-
-char *
-mktemp(path)
- char *path;
-{
- return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
-}
-
-static
-_gettemp(path, doopen)
- char *path;
- register int *doopen;
-{
- extern int errno;
- register char *start, *trv;
- struct stat sbuf;
- u_int pid;
-
- pid = getpid();
- for (trv = path; *trv; ++trv); /* extra X's get set to 0's */
- while (*--trv == 'X') {
- *trv = (pid % 10) + '0';
- pid /= 10;
- }
-
- /*
- * check the target directory; if you have six X's and it
- * doesn't exist this runs for a *very* long time.
- */
- for (start = trv + 1;; --trv) {
- if (trv <= path)
- break;
- if (*trv == '/') {
- *trv = '\0';
- if (stat(path, &sbuf))
- return(0);
- if (!S_ISDIR(sbuf.st_mode)) {
- errno = ENOTDIR;
- return(0);
- }
- *trv = '/';
- break;
- }
- }
-
- for (;;) {
- if (doopen) {
- if ((*doopen =
- open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
- return(1);
- if (errno != EEXIST)
- return(0);
- }
- else if (stat(path, &sbuf))
- return(errno == ENOENT ? 1 : 0);
-
- /* tricky little algorithm for backward compatibility */
- for (trv = start;;) {
- if (!*trv)
- return(0);
- if (*trv == 'z')
- *trv++ = 'a';
- else {
- if (isdigit(*trv))
- *trv = 'a';
- else
- ++*trv;
- break;
- }
- }
- }
- /*NOTREACHED*/
-}
diff --git a/mit-pthreads/stdio/perror.c b/mit-pthreads/stdio/perror.c
deleted file mode 100644
index 19fe52f5010..00000000000
--- a/mit-pthreads/stdio/perror.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)perror.c 5.11 (Berkeley) 2/24/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-char *strerror(int); /* For systems that don't prototype it in string.h */
-
-void
-perror(s)
- const char *s;
-{
- char * e;
-
- if (fd_lock(STDERR_FILENO, FD_WRITE, NULL) == OK) {
- if (s && *s) {
- fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd,
- fd_table[STDERR_FILENO]->flags, s, strlen(s), NULL);
- fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd,
- fd_table[STDERR_FILENO]->flags, ": ", 2, NULL);
- }
- e = strerror(errno);
- fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd,
- fd_table[STDERR_FILENO]->flags, e, strlen(e), NULL);
- fd_table[STDERR_FILENO]->ops->write(fd_table[STDERR_FILENO]->fd,
- fd_table[STDERR_FILENO]->flags, "\n", 1, NULL);
- fd_unlock(STDERR_FILENO, FD_WRITE);
- }
-}
diff --git a/mit-pthreads/stdio/printf.c b/mit-pthreads/stdio/printf.c
deleted file mode 100644
index a298509d341..00000000000
--- a/mit-pthreads/stdio/printf.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)printf.c 5.6 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <pthread.h>
-#include <stdio.h>
-
-printf(char const *fmt, ...)
-{
- int ret;
- va_list ap;
-
- va_start(ap, fmt);
- ret = vfprintf(stdout, fmt, ap);
- va_end(ap);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/putc.c b/mit-pthreads/stdio/putc.c
deleted file mode 100644
index ac71e35ff25..00000000000
--- a/mit-pthreads/stdio/putc.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)putc.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro putc.
- */
-#undef putc
-
-putc(c, fp)
- int c;
- register FILE *fp;
-{
- int ret;
- flockfile(fp);
- ret = __sputc(c, fp);
- funlockfile(fp);
- return(ret);
-}
diff --git a/mit-pthreads/stdio/putc_unlocked.c b/mit-pthreads/stdio/putc_unlocked.c
deleted file mode 100644
index 7c9c78ff1e8..00000000000
--- a/mit-pthreads/stdio/putc_unlocked.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)putc.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro putc.
- */
-#undef putc_unlocked
-
-putc_unlocked(c, fp)
- int c;
- register FILE *fp;
-{
- return (__sputc(c, fp));
-}
diff --git a/mit-pthreads/stdio/putchar.c b/mit-pthreads/stdio/putchar.c
deleted file mode 100644
index c22a11ea25d..00000000000
--- a/mit-pthreads/stdio/putchar.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)putchar.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-#undef putchar
-
-/*
- * A subroutine version of the macro putchar
- */
-putchar(c)
- int c;
-{
- register FILE *so = stdout;
- int ret;
-
- flockfile(so);
- ret = __sputc(c, so);
- funlockfile(so);
- return(ret);
-}
diff --git a/mit-pthreads/stdio/putchar_unlocked.c b/mit-pthreads/stdio/putchar_unlocked.c
deleted file mode 100644
index df27a501211..00000000000
--- a/mit-pthreads/stdio/putchar_unlocked.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)putchar.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-
-#undef putchar_unlocked
-/*
- * A subroutine version of the macro putchar
- */
-putchar_unlocked(c)
- int c;
-{
- register FILE *so = stdout;
-
- return (__sputc(c, so));
-}
diff --git a/mit-pthreads/stdio/puts.c b/mit-pthreads/stdio/puts.c
deleted file mode 100644
index 97f8b3599f2..00000000000
--- a/mit-pthreads/stdio/puts.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)puts.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-#include "fvwrite.h"
-
-/*
- * Write the given string to stdout, appending a newline.
- */
-puts(s)
- char const *s;
-{
- size_t c = strlen(s);
- struct __suio uio;
- struct __siov iov[2];
- int r;
-
- iov[0].iov_base = (void *)s;
- iov[0].iov_len = c;
- iov[1].iov_base = "\n";
- iov[1].iov_len = 1;
- uio.uio_resid = c + 1;
- uio.uio_iov = &iov[0];
- uio.uio_iovcnt = 2;
-
- flockfile(stdout);
- r = (__sfvwrite(stdout, &uio) ? EOF : '\n');
- funlockfile(stdout);
- return(r);
-}
diff --git a/mit-pthreads/stdio/putw.c b/mit-pthreads/stdio/putw.c
deleted file mode 100644
index 79473f0e243..00000000000
--- a/mit-pthreads/stdio/putw.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)putw.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include "fvwrite.h"
-
-putw(w, fp)
- int w;
- FILE *fp;
-{
- struct __suio uio;
- struct __siov iov;
- int r;
-
- iov.iov_base = &w;
- iov.iov_len = uio.uio_resid = sizeof(w);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
-
- flockfile(fp);
- r = (__sfvwrite(fp, &uio));
- funlockfile(fp);
- return(r);
-}
diff --git a/mit-pthreads/stdio/refill.c b/mit-pthreads/stdio/refill.c
deleted file mode 100644
index 396895e56ff..00000000000
--- a/mit-pthreads/stdio/refill.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)refill.c 5.3 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-#include "glue.h"
-
-extern pthread_mutex_t __sfp_mutex;
-extern pthread_cond_t __sfp_cond;
-extern struct glue __sglue;
-extern int __sfp_state;
-
-/* This function is very similar to __swalk_sflush */
-static void __swalk_lflush()
-{
- register FILE *fp, *savefp;
- register int n, saven;
- register struct glue *g, *saveg;
-
- /* Only allow other threads to read __sglue */
- pthread_mutex_lock(&__sfp_mutex);
- __sfp_state++;
- pthread_mutex_unlock(&__sfp_mutex);
-
- saven = 0;
- saveg = NULL;
- savefp = NULL;
- for (g = &__sglue; g != NULL; g = g->next) {
- for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) {
- if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) {
- /* Is there anything to flush? */
- if (fp->_bf._base && (fp->_bf._base - fp->_p)) {
- if (ftrylockfile(fp)) { /* Can we flush it */
- if (!saven) { /* No, save first fp we can't flush */
- saven = n;
- saveg = g;
- savefp = fp;
- continue;
- }
- } else {
- (void) __sflush(fp);
- funlockfile(fp);
- }
- }
- }
- }
- }
- if (savefp) {
- for (g = saveg; g != NULL; g = g->next) {
- for (fp = savefp, n = saven + 1; --n >= 0; fp++) {
- if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) {
- /* Anything to flush */
- while (fp->_bf._base && (fp->_bf._base - fp->_p)) {
- flockfile(fp);
- (void) __sflush(fp);
- funlockfile(fp);
- }
- }
- }
- }
- }
-
- /* If no other readers wakeup a thread waiting to do __sfp */
- pthread_mutex_lock(&__sfp_mutex);
- if (! (--__sfp_state)) {
- pthread_cond_signal(&__sfp_cond);
- }
- pthread_mutex_unlock(&__sfp_mutex);
-}
-
-/*
- * Refill a stdio buffer.
- * Return EOF on eof or error, 0 otherwise.
- */
-__srefill(fp)
- register FILE *fp;
-{
-
- /* make sure stdio is set up */
- __sinit ();
-
- fp->_r = 0; /* largely a convenience for callers */
-
- /* SysV does not make this test; take it out for compatibility */
- if (fp->_flags & __SEOF)
- return (EOF);
-
- /* if not already reading, have to be reading and writing */
- if ((fp->_flags & __SRD) == 0) {
- if ((fp->_flags & __SRW) == 0) {
- errno = EBADF;
- return (EOF);
- }
- /* switch to reading */
- if (fp->_flags & __SWR) {
- if (__sflush(fp))
- return (EOF);
- fp->_flags &= ~__SWR;
- fp->_w = 0;
- fp->_lbfsize = 0;
- }
- fp->_flags |= __SRD;
- } else {
- /*
- * We were reading. If there is an ungetc buffer,
- * we must have been reading from that. Drop it,
- * restoring the previous buffer (if any). If there
- * is anything in that buffer, return.
- */
- if (HASUB(fp)) {
- FREEUB(fp);
- if ((fp->_r = fp->_ur) != 0) {
- fp->_p = fp->_up;
- return (0);
- }
- }
- }
-
- if (fp->_file == -1) {
- fp->_flags |= __SEOF;
- return(EOF);
- }
-
- if (fp->_bf._base == NULL)
- __smakebuf(fp);
-
- /*
- * Before reading from a line buffered or unbuffered file,
- * flush all line buffered output files, per the ANSI C
- * standard.
- */
- if (fp->_flags & (__SLBF|__SNBF))
- __swalk_lflush();
- fp->_p = fp->_bf._base;
- fp->_r = __sread(fp, (char *)fp->_p, fp->_bf._size);
- fp->_flags &= ~__SMOD; /* buffer contents are again pristine */
- if (fp->_r <= 0) {
- if (fp->_r == 0)
- fp->_flags |= __SEOF;
- else {
- fp->_r = 0;
- fp->_flags |= __SERR;
- }
- return (EOF);
- }
- return (0);
-}
diff --git a/mit-pthreads/stdio/remove.c b/mit-pthreads/stdio/remove.c
deleted file mode 100644
index 116537e3a0f..00000000000
--- a/mit-pthreads/stdio/remove.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)remove.c 5.3 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <unistd.h>
-
-remove(file)
- const char *file;
-{
- return (unlink(file));
-}
diff --git a/mit-pthreads/stdio/rewind.c b/mit-pthreads/stdio/rewind.c
deleted file mode 100644
index 17d4418db39..00000000000
--- a/mit-pthreads/stdio/rewind.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)rewind.c 5.6 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <errno.h>
-#include <stdio.h>
-
-void
-rewind(fp)
- register FILE *fp;
-{
- flockfile(fp);
- (void) fseek(fp, 0L, SEEK_SET);
- fp->_flags &= ~(__SERR|__SEOF); /* clearerr */
- funlockfile(fp);
- errno = 0; /* not required, but seems reasonable */
-}
diff --git a/mit-pthreads/stdio/rget.c b/mit-pthreads/stdio/rget.c
deleted file mode 100644
index a2b19afb130..00000000000
--- a/mit-pthreads/stdio/rget.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)rget.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-/*
- * Handle getc() when the buffer ran out:
- * Refill, then return the first character
- * in the newly-filled buffer.
- */
-__srget(fp)
- register FILE *fp;
-{
- if (__srefill(fp) == 0) {
- fp->_r--;
- return (*fp->_p++);
- }
- return (EOF);
-}
diff --git a/mit-pthreads/stdio/scanf.c b/mit-pthreads/stdio/scanf.c
deleted file mode 100644
index 9f9f5a6665e..00000000000
--- a/mit-pthreads/stdio/scanf.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)scanf.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#if __STDC__
-scanf(char const *fmt, ...)
-#else
-scanf(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- int ret;
- va_list ap;
-
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- flockfile(stdin);
- ret = __svfscanf(stdin, fmt, ap);
- funlockfile(stdin);
- va_end(ap);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/setbuf.c b/mit-pthreads/stdio/setbuf.c
deleted file mode 100644
index af8d088089d..00000000000
--- a/mit-pthreads/stdio/setbuf.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)setbuf.c 5.3 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include "local.h"
-
-void
-setbuf(fp, buf)
- FILE *fp;
- char *buf;
-{
- (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
-}
diff --git a/mit-pthreads/stdio/setbuffer.c b/mit-pthreads/stdio/setbuffer.c
deleted file mode 100644
index 0c79e55fd93..00000000000
--- a/mit-pthreads/stdio/setbuffer.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)setbuffer.c 5.5 (Berkeley) 3/18/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-
-void
-setbuffer(fp, buf, size)
- register FILE *fp;
- char *buf;
- int size;
-{
-
- (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, size);
-}
-
-/*
- * set line buffering
- */
-setlinebuf(fp)
- FILE *fp;
-{
-
- (void) setvbuf(fp, (char *)NULL, _IOLBF, (size_t)0);
- return (0); /* ??? */
-}
diff --git a/mit-pthreads/stdio/setvbuf.c b/mit-pthreads/stdio/setvbuf.c
deleted file mode 100644
index 288d8c32db0..00000000000
--- a/mit-pthreads/stdio/setvbuf.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)setvbuf.c 5.5 (Berkeley) 5/6/93";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-/*
- * Set one of the three kinds of buffering, optionally including
- * a buffer.
- */
-setvbuf(fp, buf, mode, size)
- register FILE *fp;
- char *buf;
- register int mode;
- register size_t size;
-{
- register int ret, flags;
- size_t iosize;
- int ttyflag;
-
- /*
- * Verify arguments. The `int' limit on `size' is due to this
- * particular implementation. Note, buf and size are ignored
- * when setting _IONBF.
- */
- if (mode != _IONBF)
- if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0)
- return (EOF);
-
- flockfile(fp);
- /*
- * Write current buffer, if any. Discard unread input, cancel
- * line buffering, and free old buffer if malloc()ed.
- */
- ret = 0;
- (void)__sflush(fp);
- fp->_r = fp->_lbfsize = 0;
- flags = fp->_flags;
- if (flags & __SMBF)
- free((void *)fp->_bf._base);
- flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT);
-
- /* If setting unbuffered mode, skip all the hard work. */
- if (mode == _IONBF)
- goto nbf;
-
- /*
- * Find optimal I/O size for seek optimization. This also returns
- * a `tty flag' to suggest that we check isatty(fd), but we do not
- * care since our caller told us how to buffer.
- */
- flags |= __swhatbuf(fp, &iosize, &ttyflag);
- if (size == 0) {
- buf = NULL; /* force local allocation */
- size = iosize;
- }
-
- /* Allocate buffer if needed. */
- if (buf == NULL) {
- if ((buf = malloc(size)) == NULL) {
- /*
- * Unable to honor user's request. We will return
- * failure, but try again with file system size.
- */
- ret = EOF;
- if (size != iosize) {
- size = iosize;
- buf = malloc(size);
- }
- }
- if (buf == NULL) {
- /* No luck; switch to unbuffered I/O. */
-nbf:
- fp->_flags = flags | __SNBF;
- fp->_w = 0;
- fp->_bf._base = fp->_p = fp->_nbuf;
- fp->_bf._size = 1;
- funlockfile(fp);
- return (ret);
- }
- flags |= __SMBF;
- }
-
- /*
- * Kill any seek optimization if the buffer is not the
- * right size.
- *
- * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)?
- */
- if (size != iosize)
- flags |= __SNPT;
-
- /*
- * Fix up the FILE fields, and set __cleanup for output flush on
- * exit (since we are buffered in some way). If in r/w mode, go
- * to the intermediate state, so that everyone has to call
- * __srefill or __swsetup on the first operation -- it is more
- * trouble than it is worth to set things up correctly here.
- */
- if (mode == _IOLBF)
- flags |= __SLBF;
- if (flags & __SRW)
- flags &= ~(__SRD | __SWR);
- fp->_w = size; /* Was 0 (mevans) */
- fp->_flags = flags;
- fp->_bf._base = fp->_p = (unsigned char *)buf;
- fp->_bf._size = size;
- fp->_lbfsize = 0;
- __cleanup = _cleanup;
-
- funlockfile(fp);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/snprintf.c b/mit-pthreads/stdio/snprintf.c
deleted file mode 100644
index dd9bca24f73..00000000000
--- a/mit-pthreads/stdio/snprintf.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)snprintf.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#if __STDC__
-snprintf(char *str, size_t n, char const *fmt, ...)
-#else
-snprintf(str, n, fmt, va_alist)
- char *str;
- size_t n;
- char *fmt;
- va_dcl
-#endif
-{
- int ret;
- va_list ap;
- FILE f;
-
- if ((int)n < 1)
- return (EOF);
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- f._file = -1;
- f._flags = __SWR | __SSTR;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = n - 1;
- ret = vfprintf(&f, fmt, ap);
- *f._p = 0;
- va_end(ap);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/sprintf.c b/mit-pthreads/stdio/sprintf.c
deleted file mode 100644
index a500e8d4afa..00000000000
--- a/mit-pthreads/stdio/sprintf.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)sprintf.c 5.7 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <limits.h>
-#include <stdio.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include "local.h"
-
-#if __STDC__
-sprintf(char *str, char const *fmt, ...)
-#else
-sprintf(str, fmt, va_alist)
- char *str;
- char *fmt;
- va_dcl
-#endif
-{
- int ret;
- va_list ap;
- FILE f;
-
- f._file = -1;
- f._flags = __SWR | __SSTR;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = INT_MAX;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- ret = vfprintf(&f, fmt, ap);
- va_end(ap);
- *f._p = 0;
- return (ret);
-}
diff --git a/mit-pthreads/stdio/sscanf.c b/mit-pthreads/stdio/sscanf.c
deleted file mode 100644
index 50148192b9c..00000000000
--- a/mit-pthreads/stdio/sscanf.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)sscanf.c 5.1 (Berkeley) 1/20/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <string.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include "local.h"
-
-#if __STDC__
-sscanf(const char *str, char const *fmt, ...)
-#else
-sscanf(str, fmt, va_alist)
- const char *str;
- char *fmt;
- va_dcl
-#endif
-{
- int ret;
- va_list ap;
- FILE f;
-
- f._flags = __SRD;
- f._file = -1;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._r = strlen(str);
- f._ub._base = NULL;
- f._lb._base = NULL;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- ret = __svfscanf(&f, fmt, ap);
- va_end(ap);
- return (ret);
-}
diff --git a/mit-pthreads/stdio/stdio.c b/mit-pthreads/stdio/stdio.c
deleted file mode 100644
index 0b676eeb09b..00000000000
--- a/mit-pthreads/stdio/stdio.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)stdio.c 5.3 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include "local.h"
-
-/*
- * Small standard I/O/seek/close functions.
- * These maintain the `known seek offset' for seek optimisation.
- */
-int __sread(FILE *fp, char *buf, int n)
-{
- register int ret;
-
- /* if the read succeeded, update the current offset */
- if (fd_table[fp->_file]->ops->use_kfds < 2) {
- ret = fd_table[fp->_file]->ops->read(fd_table[fp->_file]->fd,
- fd_table[fp->_file]->flags, buf, n, NULL);
- } else {
- pthread_ssize_t (*readfn)() = fd_table[fp->_file]->ops->read;
- ret = readfn(fd_table[fp->_file]->fd, buf, n);
- }
- if (ret >= 0) {
- fp->_offset += ret;
- } else {
- fp->_flags &= ~__SOFF; /* paranoia */
- }
- return (ret);
-}
-
-int __swrite(FILE *fp, const char *buf, int n)
-{
- if (fp->_flags & __SAPP)
- (void) lseek(fp->_file, (off_t)0, SEEK_END);
- fp->_flags &= ~__SOFF; /* in case FAPPEND mode is set */
- if (fd_table[fp->_file]->ops->use_kfds < 2) {
- return(fd_table[fp->_file]->ops->write(fd_table[fp->_file]->fd,
- fd_table[fp->_file]->flags, buf, n, NULL));
- } else {
- pthread_ssize_t (*writefn)() = fd_table[fp->_file]->ops->write;
- return(writefn(fd_table[fp->_file]->fd,buf,n));
- }
-}
-
-fpos_t __sseek(FILE *fp, off_t offset, int whence)
-{
- register fpos_t ret;
-
- ret = (fpos_t)lseek(fp->_file, offset, whence);
- if (ret == -1L)
- fp->_flags &= ~__SOFF;
- else {
- fp->_flags |= __SOFF;
- fp->_offset = ret;
- }
- return (ret);
-}
-
-int __sclose(FILE *fp)
-{
- return (close(fp->_file));
-}
diff --git a/mit-pthreads/stdio/strerror.c b/mit-pthreads/stdio/strerror.c
deleted file mode 100644
index d35235e63b0..00000000000
--- a/mit-pthreads/stdio/strerror.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strerror.c 5.6 (Berkeley) 5/4/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <string.h>
-#if defined(__NetBSD__)
-#include <errno.h>
-#endif
-
-char *
-strerror(num)
- int num;
-{
-#if !defined(__NetBSD__)
- extern int sys_nerr;
- extern char *sys_errlist[];
-#endif
-#define UPREFIX "Unknown error: "
- static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
- register unsigned int errnum;
- register char *p, *t;
- char tmp[40];
-
- errnum = num; /* convert to unsigned */
- if (errnum < sys_nerr)
- return((char *)sys_errlist[errnum]);
-
- /* Do this by hand, so we don't include stdio(3). */
- t = tmp;
- do {
- *t++ = "0123456789"[errnum % 10];
- } while (errnum /= 10);
- for (p = ebuf + sizeof(UPREFIX) - 1;;) {
- *p++ = *--t;
- if (t <= tmp)
- break;
- }
- return(ebuf);
-}
diff --git a/mit-pthreads/stdio/tempnam.c b/mit-pthreads/stdio/tempnam.c
deleted file mode 100644
index 88150a18019..00000000000
--- a/mit-pthreads/stdio/tempnam.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)tempnam.c 5.1 (Berkeley) 2/22/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/param.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-/* #include <paths.h> */
-
-char *
-tempnam(dir, pfx)
- const char *dir, *pfx;
-{
- int sverrno;
- char *f, *name;
-
- if (!(name = malloc(MAXPATHLEN)))
- return(NULL);
-
- if (!pfx)
- pfx = "tmp.";
-
- if (f = getenv("TMPDIR")) {
- (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
- *(f + strlen(f) - 1) == '/'? "": "/", pfx);
- if (f = mktemp(name))
- return(f);
- }
-
- if (f = (char *)dir) {
- (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
- *(f + strlen(f) - 1) == '/'? "": "/", pfx);
- if (f = mktemp(name))
- return(f);
- }
-
- f = P_tmpdir;
- (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
- if (f = mktemp(name))
- return(f);
-
- f = _PATH_TMP;
- (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
- if (f = mktemp(name))
- return(f);
-
- sverrno = errno;
- free(name);
- errno = sverrno;
- return(NULL);
-}
diff --git a/mit-pthreads/stdio/tmpfile.c b/mit-pthreads/stdio/tmpfile.c
deleted file mode 100644
index 471bed33716..00000000000
--- a/mit-pthreads/stdio/tmpfile.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)tmpfile.c 5.4 (Berkeley) 5/27/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <signal.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <paths.h>
-
-FILE *
-tmpfile()
-{
- sigset_t set, oset;
- FILE *fp;
- int fd, sverrno;
-#define TRAILER "tmp.XXXXXX"
- char buf[sizeof(_PATH_TMP) + sizeof(TRAILER)];
-
- memcpy(buf, _PATH_TMP, sizeof(_PATH_TMP) - 1);
- memcpy( buf + sizeof(_PATH_TMP) - 1, TRAILER, sizeof(TRAILER));
-
- sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
-
- fd = mkstemp(buf);
- if (fd != -1)
- (void)unlink(buf);
-
- (void)sigprocmask(SIG_SETMASK, &oset, NULL);
-
- if (fd == -1)
- return (NULL);
-
- if (!(fp = fdopen(fd, "w+"))) {
- sverrno = errno;
- (void)close(fd);
- errno = sverrno;
- return (NULL);
- }
- return (fp);
-}
diff --git a/mit-pthreads/stdio/tmpnam.c b/mit-pthreads/stdio/tmpnam.c
deleted file mode 100644
index 8d65b21b037..00000000000
--- a/mit-pthreads/stdio/tmpnam.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)tmpnam.c 5.3 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <unistd.h>
-#include <stdio.h>
-
-char *
-tmpnam(s)
- char *s;
-{
- static char buf[L_tmpnam];
-
- if (s == NULL)
- s = buf;
- (void)snprintf(s, L_tmpnam, "%stmp.XXXXXX", P_tmpdir);
- return(mktemp(s));
-}
diff --git a/mit-pthreads/stdio/ungetc.c b/mit-pthreads/stdio/ungetc.c
deleted file mode 100644
index e035f93d5f2..00000000000
--- a/mit-pthreads/stdio/ungetc.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)ungetc.c 5.6 (Berkeley) 5/4/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "local.h"
-
-/*
- * Expand the ungetc buffer `in place'. That is, adjust fp->_p when
- * the buffer moves, so that it points the same distance from the end,
- * and move the bytes in the buffer around as necessary so that they
- * are all at the end (stack-style).
- */
-static
-__submore(fp)
- register FILE *fp;
-{
- register int i;
- register unsigned char *p;
-
- if (fp->_ub._base == fp->_ubuf) {
- /*
- * Get a new buffer (rather than expanding the old one).
- */
- if ((p = malloc((size_t)BUFSIZ)) == NULL)
- return (EOF);
- fp->_ub._base = p;
- fp->_ub._size = BUFSIZ;
- p += BUFSIZ - sizeof(fp->_ubuf);
- for (i = sizeof(fp->_ubuf); --i >= 0;)
- p[i] = fp->_ubuf[i];
- fp->_p = p;
- return (0);
- }
- i = fp->_ub._size;
- p = realloc(fp->_ub._base, i << 1);
- if (p == NULL)
- return (EOF);
- (void) memcpy((void *)(p + i), (void *)p, (size_t)i);
- fp->_p = p + i;
- fp->_ub._base = p;
- fp->_ub._size = i << 1;
- return (0);
-}
-
-ungetc(c, fp)
- int c;
- register FILE *fp;
-{
- if (c == EOF)
- return (EOF);
- __sinit ();
-
- flockfile(fp);
- if ((fp->_flags & __SRD) == 0) {
- /*
- * Not already reading: no good unless reading-and-writing.
- * Otherwise, flush any current write stuff.
- */
- if ((fp->_flags & __SRW) == 0)
- c = EOF;
- goto ungetc_end;
- if (fp->_flags & __SWR) {
- if (__sflush(fp))
- c = EOF;
- goto ungetc_end;
- fp->_flags &= ~__SWR;
- fp->_w = 0;
- fp->_lbfsize = 0;
- }
- fp->_flags |= __SRD;
- }
- c = (unsigned char)c;
-
- /*
- * If we are in the middle of ungetc'ing, just continue.
- * This may require expanding the current ungetc buffer.
- */
- if (HASUB(fp)) {
- if (fp->_r >= fp->_ub._size && __submore(fp))
- return (EOF);
- *--fp->_p = c;
- fp->_r++;
- goto ungetc_end;
- }
-
- /*
- * If we can handle this by simply backing up, do so,
- * but never replace the original character.
- * (This makes sscanf() work when scanning `const' data.)
- */
- if (fp->_bf._base != NULL && fp->_p > fp->_bf._base &&
- fp->_p[-1] == c) {
- fp->_p--;
- fp->_r++;
- goto ungetc_end;
- }
-
- /*
- * Create an ungetc buffer.
- * Initially, we will use the `reserve' buffer.
- */
- fp->_ur = fp->_r;
- fp->_up = fp->_p;
- fp->_ub._base = fp->_ubuf;
- fp->_ub._size = sizeof(fp->_ubuf);
- fp->_ubuf[sizeof(fp->_ubuf) - 1] = c;
- fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1];
- fp->_r = 1;
-
-ungetc_end:;
- funlockfile(fp);
- return (c);
-}
diff --git a/mit-pthreads/stdio/vfprintf.c b/mit-pthreads/stdio/vfprintf.c
deleted file mode 100644
index fd990bb1889..00000000000
--- a/mit-pthreads/stdio/vfprintf.c
+++ /dev/null
@@ -1,788 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * Actual printf innards.
- *
- * This code is large and complicated...
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "local.h"
-#include "fvwrite.h"
-
-/* Define FLOATING_POINT to get floating point. */
-#define FLOATING_POINT
-
-/*
- * Flush out all the vectors defined by the given uio,
- * then reset it so that it can be reused.
- */
-static int
-__sprint(fp, uio)
- register FILE* fp;
- register struct __suio *uio;
-{
- register int err;
-
- if (uio->uio_resid == 0) {
- uio->uio_iovcnt = 0;
- return (0);
- }
- err = __sfvwrite(fp, uio);
- uio->uio_resid = 0;
- uio->uio_iovcnt = 0;
- return (err);
-}
-
-/*
- * Helper function for `fprintf to unbuffered unix file': creates a
- * temporary buffer. We only work on write-only files; this avoids
- * worries about ungetc buffers and so forth.
- */
-static int
-__sbprintf(fp, fmt, ap)
- FILE *fp;
- const char *fmt;
- pthread_va_list ap;
-{
- unsigned char buf[BUFSIZ];
- FILE fake;
- int ret;
-
- /* copy the important variables */
- fake._flags = fp->_flags & ~__SNBF;
- fake._file = fp->_file;
-
- /* set up the buffer */
- fake._bf._base = fake._p = buf;
- fake._bf._size = fake._w = sizeof(buf);
- fake._lbfsize = 0; /* not actually used, but Just In Case */
-
- /* do the work, then copy any error status */
- ret = vfprintf(&fake, fmt, ap);
- if (ret >= 0 && fflush(&fake))
- ret = EOF;
- if (fake._flags & __SERR)
- fp->_flags |= __SERR;
- return (ret);
-}
-
-
-#ifdef FLOATING_POINT
-#include <locale.h>
-#include <math.h>
-#include "floatio.h"
-
-#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
-#define DEFPREC 6
-
-static char *cvt __P_((double, int, int, char *, int *, int, int *));
-static int exponent __P_((char *, int, int));
-
-#else /* no FLOATING_POINT */
-
-#define BUF 40
-
-#endif /* FLOATING_POINT */
-
-
-/*
- * Macros for converting digits to letters and vice versa
- */
-#define to_digit(c) ((c) - '0')
-#define is_digit(c) ((unsigned)to_digit(c) <= 9)
-#define to_char(n) ((n) + '0')
-
-/*
- * Flags used during conversion.
- */
-#define ALT 0x001 /* alternate form */
-#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
-#define LADJUST 0x004 /* left adjustment */
-#define LONGDBL 0x008 /* long double; unimplemented */
-#define LONGINT 0x010 /* long integer */
-#define QUADINT 0x020 /* quad integer */
-#define SHORTINT 0x040 /* short integer */
-#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
-#define FPT 0x100 /* Floating point number */
-int
-vfprintf(fp, fmt0, ap)
- FILE *fp;
- const char *fmt0;
- pthread_va_list ap;
-{
- register char *fmt; /* format string */
- register int ch; /* character from fmt */
- register int n; /* handy integer (short term usage) */
- register char *cp; /* handy char pointer (short term usage) */
- register struct __siov *iovp;/* for PRINT macro */
- register int flags; /* flags as above */
- int ret; /* return value accumulator */
- int width; /* width from format (%8d), or 0 */
- int prec; /* precision from format (%.3d), or -1 */
- char sign; /* sign prefix (' ', '+', '-', or \0) */
-#ifdef FLOATING_POINT
- char softsign; /* temporary negative sign for floats */
- double _double; /* double precision arguments %[eEfgG] */
- int expt; /* integer value of exponent */
- int expsize; /* character count for expstr */
- int ndig; /* actual number of digits returned by cvt */
- char expstr[7]; /* buffer for exponent string */
-#endif
-
-#if defined (__alpha) && !defined(_GNUC_)
-#define quad_t long
-#define u_quad_t unsigned long
-#else /* gcc has builtin quad type (long long) SOS */
-#define quad_t long long
-#define u_quad_t unsigned long long
-#endif
-
- u_quad_t _uquad; /* integer arguments %[diouxX] */
- enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
- int dprec; /* a copy of prec if [diouxX], 0 otherwise */
- int fieldsz; /* field size expanded by sign, etc */
- int realsz; /* field size expanded by dprec */
- int size; /* size of converted field or string */
- char *xdigs; /* digits for [xX] conversion */
-#define NIOV 8
- struct __suio uio; /* output information: summary */
- struct __siov iov[NIOV];/* ... and individual io vectors */
- char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
- char ox[2]; /* space for 0x hex-prefix */
-
- /*
- * Choose PADSIZE to trade efficiency vs. size. If larger printf
- * fields occur frequently, increase PADSIZE and make the initialisers
- * below longer.
- */
-#define PADSIZE 16 /* pad chunk size */
- static char blanks[PADSIZE] =
- {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
- static char zeroes[PADSIZE] =
- {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
-
- /*
- * BEWARE, these `goto error' on error, and PAD uses `n'.
- */
-#define PRINT(ptr, len) { \
- iovp->iov_base = (ptr); \
- iovp->iov_len = (len); \
- uio.uio_resid += (len); \
- iovp++; \
- if (++uio.uio_iovcnt >= NIOV) { \
- if (__sprint(fp, &uio)) \
- goto error; \
- iovp = iov; \
- } \
-}
-#define PAD(howmany, with) { \
- if ((n = (howmany)) > 0) { \
- while (n > PADSIZE) { \
- PRINT(with, PADSIZE); \
- n -= PADSIZE; \
- } \
- PRINT(with, n); \
- } \
-}
-#define FLUSH() { \
- if (uio.uio_resid && __sprint(fp, &uio)) \
- goto error; \
- uio.uio_iovcnt = 0; \
- iovp = iov; \
-}
-
- /*
- * To extend shorts properly, we need both signed and unsigned
- * argument extraction methods.
- */
-#define SARG() \
- (flags&QUADINT ? va_arg(ap, quad_t) : \
- flags&LONGINT ? va_arg(ap, long) : \
- flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
- (long)va_arg(ap, int))
-#define UARG() \
- (flags&QUADINT ? va_arg(ap, u_quad_t) : \
- flags&LONGINT ? va_arg(ap, u_long) : \
- flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
- (u_long)va_arg(ap, u_int))
-
- flockfile(fp);
-
- /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
- if (cantwrite(fp))
- return (EOF);
-
- /* optimise fprintf(stderr) (and other unbuffered Unix files) */
- if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
- fp->_file >= 0) {
- ret = (__sbprintf(fp, fmt0, ap));
- funlockfile(fp);
- return(ret);
- }
-
- fmt = (char *)fmt0;
- uio.uio_iov = iovp = iov;
- uio.uio_resid = 0;
- uio.uio_iovcnt = 0;
- ret = 0;
-
- /*
- * Scan the format for conversions (`%' character).
- */
- for (;;) {
- for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
- /* void */;
- if ((n = fmt - cp) != 0) {
- PRINT(cp, n);
- ret += n;
- }
- if (ch == '\0')
- goto done;
- fmt++; /* skip over '%' */
-
- flags = 0;
- dprec = 0;
- width = 0;
- prec = -1;
- sign = '\0';
-
-rflag: ch = *fmt++;
-reswitch: switch (ch) {
- case ' ':
- /*
- * ``If the space and + flags both appear, the space
- * flag will be ignored.''
- * -- ANSI X3J11
- */
- if (!sign)
- sign = ' ';
- goto rflag;
- case '#':
- flags |= ALT;
- goto rflag;
- case '*':
- /*
- * ``A negative field width argument is taken as a
- * - flag followed by a positive field width.''
- * -- ANSI X3J11
- * They don't exclude field widths read from args.
- */
- if ((width = va_arg(ap, int)) >= 0)
- goto rflag;
- width = -width;
- /* FALLTHROUGH */
- case '-':
- flags |= LADJUST;
- goto rflag;
- case '+':
- sign = '+';
- goto rflag;
- case '.':
- if ((ch = *fmt++) == '*') {
- n = va_arg(ap, int);
- prec = n < 0 ? -1 : n;
- goto rflag;
- }
- n = 0;
- while (is_digit(ch)) {
- n = 10 * n + to_digit(ch);
- ch = *fmt++;
- }
- prec = n < 0 ? -1 : n;
- goto reswitch;
- case '0':
- /*
- * ``Note that 0 is taken as a flag, not as the
- * beginning of a field width.''
- * -- ANSI X3J11
- */
- flags |= ZEROPAD;
- goto rflag;
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- n = 0;
- do {
- n = 10 * n + to_digit(ch);
- ch = *fmt++;
- } while (is_digit(ch));
- width = n;
- goto reswitch;
-#ifdef FLOATING_POINT
- case 'L':
- flags |= LONGDBL;
- goto rflag;
-#endif
- case 'h':
- flags |= SHORTINT;
- goto rflag;
- case 'l':
- flags |= LONGINT;
- goto rflag;
- case 'q':
- flags |= QUADINT;
- goto rflag;
- case 'c':
- *(cp = buf) = va_arg(ap, int);
- size = 1;
- sign = '\0';
- break;
- case 'D':
- flags |= LONGINT;
- /*FALLTHROUGH*/
- case 'd':
- case 'i':
- _uquad = SARG();
- if ((quad_t)_uquad < 0) {
- _uquad = -_uquad;
- sign = '-';
- }
- base = DEC;
- goto number;
-#ifdef FLOATING_POINT
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- case 'G':
- if (prec == -1) {
- prec = DEFPREC;
- } else if ((ch == 'g' || ch == 'G') && prec == 0) {
- prec = 1;
- }
-
- if (flags & LONGDBL) {
- _double = (double) va_arg(ap, long double);
- } else {
- _double = va_arg(ap, double);
- }
-
- /* do this before tricky precision changes */
- /* if (isinf(_double)) {
- if (_double < 0)
- sign = '-';
- cp = "Inf";
- size = 3;
- break;
- } */
-/* if (isnan(_double)) {
- cp = "NaN";
- size = 3;
- break;
- } */
-
- flags |= FPT;
- cp = cvt(_double, prec, flags, &softsign,
- &expt, ch, &ndig);
- if (ch == 'g' || ch == 'G') {
- if (expt <= -4 || expt > prec)
- ch = (ch == 'g') ? 'e' : 'E';
- else
- ch = 'g';
- }
- if (ch <= 'e') { /* 'e' or 'E' fmt */
- --expt;
- expsize = exponent(expstr, expt, ch);
- size = expsize + ndig;
- if (ndig > 1 || flags & ALT)
- ++size;
- } else if (ch == 'f') { /* f fmt */
- if (expt > 0) {
- size = expt;
- if (prec || flags & ALT)
- size += prec + 1;
- } else /* "0.X" */
- size = prec + 2;
- } else if (expt >= ndig) { /* fixed g fmt */
- size = expt;
- if (flags & ALT)
- ++size;
- } else
- size = ndig + (expt > 0 ?
- 1 : 2 - expt);
-
- if (softsign)
- sign = '-';
- break;
-#endif /* FLOATING_POINT */
- case 'n':
- if (flags & QUADINT)
- *va_arg(ap, quad_t *) = ret;
- else if (flags & LONGINT)
- *va_arg(ap, long *) = ret;
- else if (flags & SHORTINT)
- *va_arg(ap, short *) = ret;
- else
- *va_arg(ap, int *) = ret;
- continue; /* no output */
- case 'O':
- flags |= LONGINT;
- /*FALLTHROUGH*/
- case 'o':
- _uquad = UARG();
- base = OCT;
- goto nosign;
- case 'p':
- /*
- * ``The argument shall be a pointer to void. The
- * value of the pointer is converted to a sequence
- * of printable characters, in an implementation-
- * defined manner.''
- * -- ANSI X3J11
- */
- /* NOSTRICT */
- _uquad = (u_quad_t)(size_t)va_arg(ap, void *);
- base = HEX;
- xdigs = "0123456789abcdef";
- flags |= HEXPREFIX;
- ch = 'x';
- goto nosign;
- case 's':
- if ((cp = va_arg(ap, char *)) == NULL)
- cp = "(null)";
- if (prec >= 0) {
- /*
- * can't use strlen; can only look for the
- * NUL in the first `prec' characters, and
- * strlen() will go further.
- */
- char *p = memchr(cp, 0, prec);
-
- if (p != NULL) {
- size = p - cp;
- if (size > prec)
- size = prec;
- } else
- size = prec;
- } else
- size = strlen(cp);
- sign = '\0';
- break;
- case 'U':
- flags |= LONGINT;
- /*FALLTHROUGH*/
- case 'u':
- _uquad = UARG();
- base = DEC;
- goto nosign;
- case 'X':
- xdigs = "0123456789ABCDEF";
- goto hex;
- case 'x':
- xdigs = "0123456789abcdef";
-hex: _uquad = UARG();
- base = HEX;
- /* leading 0x/X only if non-zero */
- if (flags & ALT && _uquad != 0)
- flags |= HEXPREFIX;
-
- /* unsigned conversions */
-nosign: sign = '\0';
- /*
- * ``... diouXx conversions ... if a precision is
- * specified, the 0 flag will be ignored.''
- * -- ANSI X3J11
- */
-number: if ((dprec = prec) >= 0)
- flags &= ~ZEROPAD;
-
- /*
- * ``The result of converting a zero value with an
- * explicit precision of zero is no characters.''
- * -- ANSI X3J11
- */
- cp = buf + BUF;
- if (_uquad != 0 || prec != 0) {
- /*
- * Unsigned mod is hard, and unsigned mod
- * by a constant is easier than that by
- * a variable; hence this switch.
- */
- switch (base) {
- case OCT:
- do {
- *--cp = to_char(_uquad & 7);
- _uquad >>= 3;
- } while (_uquad);
- /* handle octal leading 0 */
- if (flags & ALT && *cp != '0')
- *--cp = '0';
- break;
-
- case DEC:
- /* many numbers are 1 digit */
- while (_uquad >= 10) {
- *--cp = to_char(_uquad % 10);
- _uquad /= 10;
- }
- *--cp = to_char(_uquad);
- break;
-
- case HEX:
- do {
- *--cp = xdigs[_uquad & 15];
- _uquad >>= 4;
- } while (_uquad);
- break;
-
- default:
- cp = "bug in vfprintf: bad base";
- size = strlen(cp);
- goto skipsize;
- }
- }
- size = buf + BUF - cp;
- skipsize:
- break;
- default: /* "%?" prints ?, unless ? is NUL */
- if (ch == '\0')
- goto done;
- /* pretend it was %c with argument ch */
- cp = buf;
- *cp = ch;
- size = 1;
- sign = '\0';
- break;
- }
-
- /*
- * All reasonable formats wind up here. At this point, `cp'
- * points to a string which (if not flags&LADJUST) should be
- * padded out to `width' places. If flags&ZEROPAD, it should
- * first be prefixed by any sign or other prefix; otherwise,
- * it should be blank padded before the prefix is emitted.
- * After any left-hand padding and prefixing, emit zeroes
- * required by a decimal [diouxX] precision, then print the
- * string proper, then emit zeroes required by any leftover
- * floating precision; finally, if LADJUST, pad with blanks.
- *
- * Compute actual size, so we know how much to pad.
- * fieldsz excludes decimal prec; realsz includes it.
- */
- fieldsz = size;
- if (sign)
- fieldsz++;
- else if (flags & HEXPREFIX)
- fieldsz += 2;
- realsz = dprec > fieldsz ? dprec : fieldsz;
-
- /* right-adjusting blank padding */
- if ((flags & (LADJUST|ZEROPAD)) == 0)
- PAD(width - realsz, blanks);
-
- /* prefix */
- if (sign) {
- PRINT(&sign, 1);
- } else if (flags & HEXPREFIX) {
- ox[0] = '0';
- ox[1] = ch;
- PRINT(ox, 2);
- }
-
- /* right-adjusting zero padding */
- if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
- PAD(width - realsz, zeroes);
-
- /* leading zeroes from decimal precision */
- PAD(dprec - fieldsz, zeroes);
-
- /* the string or number proper */
-#ifdef FLOATING_POINT
- if ((flags & FPT) == 0) {
- PRINT(cp, size);
- } else { /* glue together f_p fragments */
- if (ch >= 'f') { /* 'f' or 'g' */
- if (_double == 0) {
- /* kludge for __dtoa irregularity */
- if (expt >= ndig && (flags & ALT) == 0) {
- PRINT("0", 1);
- } else {
- PRINT("0.", 2);
- PAD(ndig - 1, zeroes);
- }
- } else if (expt <= 0) {
- PRINT("0.", 2);
- PAD(-expt, zeroes);
- PRINT(cp, ndig);
- } else if (expt >= ndig) {
- PRINT(cp, ndig);
- PAD(expt - ndig, zeroes);
- if (flags & ALT)
- PRINT(".", 1);
- } else {
- PRINT(cp, expt);
- cp += expt;
- PRINT(".", 1);
- PRINT(cp, ndig-expt);
- }
- } else { /* 'e' or 'E' */
- if (ndig > 1 || flags & ALT) {
- ox[0] = *cp++;
- ox[1] = '.';
- PRINT(ox, 2);
- if (_double || flags & ALT == 0) {
- PRINT(cp, ndig-1);
- } else /* 0.[0..] */
- /* __dtoa irregularity */
- PAD(ndig - 1, zeroes);
- } else /* XeYYY */
- PRINT(cp, 1);
- PRINT(expstr, expsize);
- }
- }
-#else
- PRINT(cp, size);
-#endif
- /* left-adjusting padding (always blank) */
- if (flags & LADJUST)
- PAD(width - realsz, blanks);
-
- /* finally, adjust ret */
- ret += width > realsz ? width : realsz;
-
- FLUSH(); /* copy out the I/O vectors */
- }
-done:
- FLUSH();
-error:
- if (__sferror(fp))
- ret = EOF;
- funlockfile(fp);
- return (ret);
-}
-
-#ifdef FLOATING_POINT
-
-extern char *__dtoa __P_((double, int, int, int *, int *, char **));
-
-static char *
-cvt(value, ndigits, flags, sign, decpt, ch, length)
- double value;
- int ndigits, flags, *decpt, ch, *length;
- char *sign;
-{
- int mode, dsgn;
- char *digits, *bp, *rve;
-
- if (ch == 'f') {
- mode = 3; /* ndigits after the decimal point */
- } else {
- /* To obtain ndigits after the decimal point for the 'e'
- * and 'E' formats, round to ndigits + 1 significant
- * figures.
- */
- if (ch == 'e' || ch == 'E') {
- ndigits++;
- }
- mode = 2; /* ndigits significant digits */
- }
-
- if (value < 0) {
- value = -value;
- *sign = '-';
- } else
- *sign = '\000';
-/* #if !defined(__alpha__) && !defined(hpux) */
-#ifndef THIS_IS_NEVER_DEFINED
- digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
-#else
- { char *ecvt(double,int,int*,int*);
-
- digits = ecvt(value, ndigits, decpt, &dsgn);
- rve = (digits + (int)strlen(digits));
- }
-#endif
- if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */
- bp = digits + ndigits;
- if (ch == 'f') {
- if (*digits == '0' && value)
- *decpt = -ndigits + 1;
- bp += *decpt;
- }
- if (value == 0) /* kludge for __dtoa irregularity */
- rve = bp;
- while (rve < bp)
- *rve++ = '0';
- }
- *length = rve - digits;
- return (digits);
-}
-
-static int
-exponent(p0, exp, fmtch)
- char *p0;
- int exp, fmtch;
-{
- register char *p, *t;
- char expbuf[MAXEXP];
-
- p = p0;
- *p++ = fmtch;
- if (exp < 0) {
- exp = -exp;
- *p++ = '-';
- }
- else
- *p++ = '+';
- t = expbuf + MAXEXP;
- if (exp > 9) {
- do {
- *--t = to_char(exp % 10);
- } while ((exp /= 10) > 9);
- *--t = to_char(exp);
- for (; t < expbuf + MAXEXP; *p++ = *t++);
- }
- else {
- *p++ = '0';
- *p++ = to_char(exp);
- }
- return (p - p0);
-}
-#endif /* FLOATING_POINT */
diff --git a/mit-pthreads/stdio/vfscanf.c b/mit-pthreads/stdio/vfscanf.c
deleted file mode 100644
index f6d0a40aa51..00000000000
--- a/mit-pthreads/stdio/vfscanf.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vfscanf.c 5.7 (Berkeley) 12/14/92";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include "local.h"
-
-#define FLOATING_POINT
-
-#include "floatio.h"
-#define BUF 513 /* Maximum length of numeric string. */
-
-/*
- * Flags used during conversion.
- */
-#define LONG 0x01 /* l: long or double */
-#define LONGDBL 0x02 /* L: long double; unimplemented */
-#define SHORT 0x04 /* h: short */
-#define SUPPRESS 0x08 /* suppress assignment */
-#define POINTER 0x10 /* weird %p pointer (`fake hex') */
-#define NOSKIP 0x20 /* do not skip blanks */
-
-/*
- * The following are used in numeric conversions only:
- * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
- * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
- */
-#define SIGNOK 0x40 /* +/- is (still) legal */
-#define NDIGITS 0x80 /* no digits detected */
-
-#define DPTOK 0x100 /* (float) decimal point is still legal */
-#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
-
-#define PFXOK 0x100 /* 0x prefix is (still) legal */
-#define NZDIGITS 0x200 /* no zero digits detected */
-
-/*
- * Conversion types.
- */
-#define CT_CHAR 0 /* %c conversion */
-#define CT_CCL 1 /* %[...] conversion */
-#define CT_STRING 2 /* %s conversion */
-#define CT_INT 3 /* integer, i.e., strtol or strtoul */
-#define CT_FLOAT 4 /* floating, i.e., strtod */
-
-#define u_char unsigned char
-#define u_long unsigned long
-
-static u_char *__sccl();
-
-/*
- * vfscanf
- */
-__svfscanf(fp, fmt0, ap)
- register FILE *fp;
- char const *fmt0;
- pthread_va_list ap;
-{
- register u_char *fmt = (u_char *)fmt0;
- register int c; /* character from format, or conversion */
- register size_t width; /* field width, or 0 */
- register char *p; /* points into all kinds of strings */
- register int n; /* handy integer */
- register int flags; /* flags as defined above */
- register char *p0; /* saves original value of p when necessary */
- int nassigned; /* number of fields assigned */
- int nread; /* number of characters consumed from fp */
- int base; /* base argument to strtol/strtoul */
- u_long (*ccfn)(); /* conversion function (strtol/strtoul) */
- char ccltab[256]; /* character class table for %[...] */
- char buf[BUF]; /* buffer for numeric conversions */
-
- /* `basefix' is used to avoid `if' tests in the integer scanner */
- static short basefix[17] =
- { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
-
- nassigned = 0;
- nread = 0;
- base = 0; /* XXX just to keep gcc happy */
- ccfn = NULL; /* XXX just to keep gcc happy */
- for (;;) {
- c = *fmt++;
- if (c == 0)
- return (nassigned);
- if (isspace(c)) {
- for (;;) {
- if (fp->_r <= 0 && __srefill(fp))
- return (nassigned);
- if (!isspace(*fp->_p))
- break;
- nread++, fp->_r--, fp->_p++;
- }
- continue;
- }
- if (c != '%')
- goto literal;
- width = 0;
- flags = 0;
- /*
- * switch on the format. continue if done;
- * break once format type is derived.
- */
-again: c = *fmt++;
- switch (c) {
- case '%':
-literal:
- if (fp->_r <= 0 && __srefill(fp))
- goto input_failure;
- if (*fp->_p != c)
- goto match_failure;
- fp->_r--, fp->_p++;
- nread++;
- continue;
-
- case '*':
- flags |= SUPPRESS;
- goto again;
- case 'l':
- flags |= LONG;
- goto again;
- case 'L':
- flags |= LONGDBL;
- goto again;
- case 'h':
- flags |= SHORT;
- goto again;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- width = width * 10 + c - '0';
- goto again;
-
- /*
- * Conversions.
- * Those marked `compat' are for 4.[123]BSD compatibility.
- *
- * (According to ANSI, E and X formats are supposed
- * to the same as e and x. Sorry about that.)
- */
- case 'D': /* compat */
- flags |= LONG;
- /* FALLTHROUGH */
- case 'd':
- c = CT_INT;
- ccfn = (u_long (*)())strtol;
- base = 10;
- break;
-
- case 'i':
- c = CT_INT;
- ccfn = (u_long (*)())strtol;
- base = 0;
- break;
-
- case 'O': /* compat */
- flags |= LONG;
- /* FALLTHROUGH */
- case 'o':
- c = CT_INT;
- ccfn = strtoul;
- base = 8;
- break;
-
- case 'u':
- c = CT_INT;
- ccfn = strtoul;
- base = 10;
- break;
-
- case 'X': /* compat XXX */
- flags |= LONG;
- /* FALLTHROUGH */
- case 'x':
- flags |= PFXOK; /* enable 0x prefixing */
- c = CT_INT;
- ccfn = strtoul;
- base = 16;
- break;
-
-#ifdef FLOATING_POINT
- case 'E': /* compat XXX */
- case 'F': /* compat */
- flags |= LONG;
- /* FALLTHROUGH */
- case 'e': case 'f': case 'g':
- c = CT_FLOAT;
- break;
-#endif
-
- case 's':
- c = CT_STRING;
- break;
-
- case '[':
- fmt = __sccl(ccltab, fmt);
- flags |= NOSKIP;
- c = CT_CCL;
- break;
-
- case 'c':
- flags |= NOSKIP;
- c = CT_CHAR;
- break;
-
- case 'p': /* pointer format is like hex */
- flags |= POINTER | PFXOK;
- c = CT_INT;
- ccfn = strtoul;
- base = 16;
- break;
-
- case 'n':
- if (flags & SUPPRESS) /* ??? */
- continue;
- if (flags & SHORT)
- *va_arg(ap, short *) = nread;
- else if (flags & LONG)
- *va_arg(ap, long *) = nread;
- else
- *va_arg(ap, int *) = nread;
- continue;
-
- /*
- * Disgusting backwards compatibility hacks. XXX
- */
- case '\0': /* compat */
- return (EOF);
-
- default: /* compat */
- if (isupper(c))
- flags |= LONG;
- c = CT_INT;
- ccfn = (u_long (*)())strtol;
- base = 10;
- break;
- }
-
- /*
- * We have a conversion that requires input.
- */
- if (fp->_r <= 0 && __srefill(fp))
- goto input_failure;
-
- /*
- * Consume leading white space, except for formats
- * that suppress this.
- */
- if ((flags & NOSKIP) == 0) {
- while (isspace(*fp->_p)) {
- nread++;
- if (--fp->_r > 0)
- fp->_p++;
- else if (__srefill(fp))
- goto input_failure;
- }
- /*
- * Note that there is at least one character in
- * the buffer, so conversions that do not set NOSKIP
- * ca no longer result in an input failure.
- */
- }
-
- /*
- * Do the conversion.
- */
- switch (c) {
-
- case CT_CHAR:
- /* scan arbitrary characters (sets NOSKIP) */
- if (width == 0)
- width = 1;
- if (flags & SUPPRESS) {
- size_t sum = 0;
- for (;;) {
- if ((n = fp->_r) < width) {
- sum += n;
- width -= n;
- fp->_p += n;
- if (__srefill(fp)) {
- if (sum == 0)
- goto input_failure;
- break;
- }
- } else {
- sum += width;
- fp->_r -= width;
- fp->_p += width;
- break;
- }
- }
- nread += sum;
- } else {
- size_t r = fread((void *)va_arg(ap, char *), 1,
- width, fp);
-
- if (r == 0)
- goto input_failure;
- nread += r;
- nassigned++;
- }
- break;
-
- case CT_CCL:
- /* scan a (nonempty) character class (sets NOSKIP) */
- if (width == 0)
- width = ~0; /* `infinity' */
- /* take only those things in the class */
- if (flags & SUPPRESS) {
- n = 0;
- while (ccltab[*fp->_p]) {
- n++, fp->_r--, fp->_p++;
- if (--width == 0)
- break;
- if (fp->_r <= 0 && __srefill(fp)) {
- if (n == 0)
- goto input_failure;
- break;
- }
- }
- if (n == 0)
- goto match_failure;
- } else {
- p0 = p = va_arg(ap, char *);
- while (ccltab[*fp->_p]) {
- fp->_r--;
- *p++ = *fp->_p++;
- if (--width == 0)
- break;
- if (fp->_r <= 0 && __srefill(fp)) {
- if (p == p0)
- goto input_failure;
- break;
- }
- }
- n = p - p0;
- if (n == 0)
- goto match_failure;
- *p = 0;
- nassigned++;
- }
- nread += n;
- break;
-
- case CT_STRING:
- /* like CCL, but zero-length string OK, & no NOSKIP */
- if (width == 0)
- width = ~0;
- if (flags & SUPPRESS) {
- n = 0;
- while (!isspace(*fp->_p)) {
- n++, fp->_r--, fp->_p++;
- if (--width == 0)
- break;
- if (fp->_r <= 0 && __srefill(fp))
- break;
- }
- nread += n;
- } else {
- p0 = p = va_arg(ap, char *);
- while (!isspace(*fp->_p)) {
- fp->_r--;
- *p++ = *fp->_p++;
- if (--width == 0)
- break;
- if (fp->_r <= 0 && __srefill(fp))
- break;
- }
- *p = 0;
- nread += p - p0;
- nassigned++;
- }
- continue;
-
- case CT_INT:
- /* scan an integer as if by strtol/strtoul */
-#ifdef hardway
- if (width == 0 || width > sizeof(buf) - 1)
- width = sizeof(buf) - 1;
-#else
- /* size_t is unsigned, hence this optimisation */
- if (--width > sizeof(buf) - 2)
- width = sizeof(buf) - 2;
- width++;
-#endif
- flags |= SIGNOK | NDIGITS | NZDIGITS;
- for (p = buf; width; width--) {
- c = *fp->_p;
- /*
- * Switch on the character; `goto ok'
- * if we accept it as a part of number.
- */
- switch (c) {
-
- /*
- * The digit 0 is always legal, but is
- * special. For %i conversions, if no
- * digits (zero or nonzero) have been
- * scanned (only signs), we will have
- * base==0. In that case, we should set
- * it to 8 and enable 0x prefixing.
- * Also, if we have not scanned zero digits
- * before this, do not turn off prefixing
- * (someone else will turn it off if we
- * have scanned any nonzero digits).
- */
- case '0':
- if (base == 0) {
- base = 8;
- flags |= PFXOK;
- }
- if (flags & NZDIGITS)
- flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
- else
- flags &= ~(SIGNOK|PFXOK|NDIGITS);
- goto ok;
-
- /* 1 through 7 always legal */
- case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- base = basefix[base];
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
-
- /* digits 8 and 9 ok iff decimal or hex */
- case '8': case '9':
- base = basefix[base];
- if (base <= 8)
- break; /* not legal here */
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
-
- /* letters ok iff hex */
- case 'A': case 'B': case 'C':
- case 'D': case 'E': case 'F':
- case 'a': case 'b': case 'c':
- case 'd': case 'e': case 'f':
- /* no need to fix base here */
- if (base <= 10)
- break; /* not legal here */
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
-
- /* sign ok only as first character */
- case '+': case '-':
- if (flags & SIGNOK) {
- flags &= ~SIGNOK;
- goto ok;
- }
- break;
-
- /* x ok iff flag still set & 2nd char */
- case 'x': case 'X':
- if (flags & PFXOK && p == buf + 1) {
- base = 16; /* if %i */
- flags &= ~PFXOK;
- goto ok;
- }
- break;
- }
-
- /*
- * If we got here, c is not a legal character
- * for a number. Stop accumulating digits.
- */
- break;
- ok:
- /*
- * c is legal: store it and look at the next.
- */
- *p++ = c;
- if (--fp->_r > 0)
- fp->_p++;
- else if (__srefill(fp))
- break; /* EOF */
- }
- /*
- * If we had only a sign, it is no good; push
- * back the sign. If the number ends in `x',
- * it was [sign] '0' 'x', so push back the x
- * and treat it as [sign] '0'.
- */
- if (flags & NDIGITS) {
- if (p > buf)
- (void) ungetc(*(u_char *)--p, fp);
- goto match_failure;
- }
- c = ((u_char *)p)[-1];
- if (c == 'x' || c == 'X') {
- --p;
- (void) ungetc(c, fp);
- }
- if ((flags & SUPPRESS) == 0) {
- u_long res;
-
- *p = 0;
- res = (*ccfn)(buf, (char **)NULL, base);
- if (flags & POINTER)
- *va_arg(ap, void **) = (void *)res;
- else if (flags & SHORT)
- *va_arg(ap, short *) = res;
- else if (flags & LONG)
- *va_arg(ap, long *) = res;
- else
- *va_arg(ap, int *) = res;
- nassigned++;
- }
- nread += p - buf;
- break;
-
-#ifdef FLOATING_POINT
- case CT_FLOAT:
- /* scan a floating point number as if by strtod */
-#ifdef hardway
- if (width == 0 || width > sizeof(buf) - 1)
- width = sizeof(buf) - 1;
-#else
- /* size_t is unsigned, hence this optimisation */
- if (--width > sizeof(buf) - 2)
- width = sizeof(buf) - 2;
- width++;
-#endif
- flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
- for (p = buf; width; width--) {
- c = *fp->_p;
- /*
- * This code mimicks the integer conversion
- * code, but is much simpler.
- */
- switch (c) {
-
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- case '8': case '9':
- flags &= ~(SIGNOK | NDIGITS);
- goto fok;
-
- case '+': case '-':
- if (flags & SIGNOK) {
- flags &= ~SIGNOK;
- goto fok;
- }
- break;
- case '.':
- if (flags & DPTOK) {
- flags &= ~(SIGNOK | DPTOK);
- goto fok;
- }
- break;
- case 'e': case 'E':
- /* no exponent without some digits */
- if ((flags&(NDIGITS|EXPOK)) == EXPOK) {
- flags =
- (flags & ~(EXPOK|DPTOK)) |
- SIGNOK | NDIGITS;
- goto fok;
- }
- break;
- }
- break;
- fok:
- *p++ = c;
- if (--fp->_r > 0)
- fp->_p++;
- else if (__srefill(fp))
- break; /* EOF */
- }
- /*
- * If no digits, might be missing exponent digits
- * (just give back the exponent) or might be missing
- * regular digits, but had sign and/or decimal point.
- */
- if (flags & NDIGITS) {
- if (flags & EXPOK) {
- /* no digits at all */
- while (p > buf)
- ungetc(*(u_char *)--p, fp);
- goto match_failure;
- }
- /* just a bad exponent (e and maybe sign) */
- c = *(u_char *)--p;
- if (c != 'e' && c != 'E') {
- (void) ungetc(c, fp);/* sign */
- c = *(u_char *)--p;
- }
- (void) ungetc(c, fp);
- }
- if ((flags & SUPPRESS) == 0) {
- double res;
-
- *p = 0;
- res = strtod(buf, (char **) NULL);
- if (flags & LONG)
- *va_arg(ap, double *) = res;
- else
- *va_arg(ap, float *) = res;
- nassigned++;
- }
- nread += p - buf;
- break;
-#endif /* FLOATING_POINT */
- }
- }
-input_failure:
- return (nassigned ? nassigned : -1);
-match_failure:
- return (nassigned);
-}
-
-/*
- * Fill in the given table from the scanset at the given format
- * (just after `['). Return a pointer to the character past the
- * closing `]'. The table has a 1 wherever characters should be
- * considered part of the scanset.
- */
-static u_char *
-__sccl(tab, fmt)
- register char *tab;
- register u_char *fmt;
-{
- register int c, n, v;
-
- /* first `clear' the whole table */
- c = *fmt++; /* first char hat => negated scanset */
- if (c == '^') {
- v = 1; /* default => accept */
- c = *fmt++; /* get new first char */
- } else
- v = 0; /* default => reject */
- /* should probably use memset here */
- for (n = 0; n < 256; n++)
- tab[n] = v;
- if (c == 0)
- return (fmt - 1);/* format ended before closing ] */
-
- /*
- * Now set the entries corresponding to the actual scanset
- * to the opposite of the above.
- *
- * The first character may be ']' (or '-') without being special;
- * the last character may be '-'.
- */
- v = 1 - v;
- for (;;) {
- tab[c] = v; /* take character c */
-doswitch:
- n = *fmt++; /* and examine the next */
- switch (n) {
-
- case 0: /* format ended too soon */
- return (fmt - 1);
-
- case '-':
- /*
- * A scanset of the form
- * [01+-]
- * is defined as `the digit 0, the digit 1,
- * the character +, the character -', but
- * the effect of a scanset such as
- * [a-zA-Z0-9]
- * is implementation defined. The V7 Unix
- * scanf treats `a-z' as `the letters a through
- * z', but treats `a-a' as `the letter a, the
- * character -, and the letter a'.
- *
- * For compatibility, the `-' is not considerd
- * to define a range if the character following
- * it is either a close bracket (required by ANSI)
- * or is not numerically greater than the character
- * we just stored in the table (c).
- */
- n = *fmt;
- if (n == ']' || n < c) {
- c = '-';
- break; /* resume the for(;;) */
- }
- fmt++;
- do { /* fill in the range */
- tab[++c] = v;
- } while (c < n);
-#if 1 /* XXX another disgusting compatibility hack */
- /*
- * Alas, the V7 Unix scanf also treats formats
- * such as [a-c-e] as `the letters a through e'.
- * This too is permitted by the standard....
- */
- goto doswitch;
-#else
- c = *fmt++;
- if (c == 0)
- return (fmt - 1);
- if (c == ']')
- return (fmt);
-#endif
- break;
-
- case ']': /* end of scanset */
- return (fmt);
-
- default: /* just another character */
- c = n;
- break;
- }
- }
- /* NOTREACHED */
-}
diff --git a/mit-pthreads/stdio/vprintf.c b/mit-pthreads/stdio/vprintf.c
deleted file mode 100644
index 4999c4fb239..00000000000
--- a/mit-pthreads/stdio/vprintf.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vprintf.c 5.6 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <stdio.h>
-
-vprintf(fmt, ap)
- char const *fmt;
- pthread_va_list ap;
-{
- return (vfprintf(stdout, fmt, ap));
-}
diff --git a/mit-pthreads/stdio/vscanf.c b/mit-pthreads/stdio/vscanf.c
deleted file mode 100644
index 5a562f89528..00000000000
--- a/mit-pthreads/stdio/vscanf.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Donn Seeley at UUNET Technologies, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vscanf.c 5.1 (Berkeley) 4/15/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <stdio.h>
-
-vscanf(fmt, ap)
- const char *fmt;
- pthread_va_list ap;
-{
- int r;
- flockfile(stdin);
- r = __svfscanf(stdin, fmt, ap);
- funlockfile(stdin);
- return(r);
-}
diff --git a/mit-pthreads/stdio/vsnprintf.c b/mit-pthreads/stdio/vsnprintf.c
deleted file mode 100644
index 8fd1e6d8613..00000000000
--- a/mit-pthreads/stdio/vsnprintf.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vsnprintf.c 5.2 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-
-vsnprintf(str, n, fmt, ap)
- char *str;
- size_t n;
- const char *fmt;
- pthread_va_list ap;
-{
- int ret;
- FILE f;
-
- if ((int)n < 1)
- return (EOF);
- f._file = -1;
- f._flags = __SWR | __SSTR;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = n - 1;
- ret = vfprintf(&f, fmt, ap);
- *f._p = 0;
- return (ret);
-}
diff --git a/mit-pthreads/stdio/vsprintf.c b/mit-pthreads/stdio/vsprintf.c
deleted file mode 100644
index c6cdb708be3..00000000000
--- a/mit-pthreads/stdio/vsprintf.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vsprintf.c 5.5 (Berkeley) 2/5/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <limits.h>
-#include <stdio.h>
-
-vsprintf(str, fmt, ap)
- char *str;
- const char *fmt;
- pthread_va_list ap;
-{
- int ret;
- FILE f;
-
- f._file = -1;
- f._flags = __SWR | __SSTR;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = INT_MAX;
- ret = vfprintf(&f, fmt, ap);
- *f._p = 0;
- return (ret);
-}
diff --git a/mit-pthreads/stdio/vsscanf.c b/mit-pthreads/stdio/vsscanf.c
deleted file mode 100644
index 9d9cdcffeeb..00000000000
--- a/mit-pthreads/stdio/vsscanf.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Donn Seeley at UUNET Technologies, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)vsscanf.c 5.1 (Berkeley) 4/15/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-vsscanf(str, fmt, ap)
- const char *str;
- const char *fmt;
- pthread_va_list ap;
-{
- int ret;
- FILE f;
-
- f._flags = __SRD;
- f._file = -1; /* This will do the right thing */
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._r = strlen(str);
- f._ub._base = NULL;
- f._lb._base = NULL;
- return (__svfscanf(&f, fmt, ap));
-}
diff --git a/mit-pthreads/stdio/wbuf.c b/mit-pthreads/stdio/wbuf.c
deleted file mode 100644
index 58cb9ad058e..00000000000
--- a/mit-pthreads/stdio/wbuf.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)wbuf.c 5.6 (Berkeley) 1/20/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include "local.h"
-
-/*
- * Write the given character into the (probably full) buffer for
- * the given file. Flush the buffer out if it is or becomes full,
- * or if c=='\n' and the file is line buffered.
- */
-__swbuf(c, fp)
- register int c;
- register FILE *fp;
-{
- register int n;
-
- /*
- * In case we cannot write, or longjmp takes us out early,
- * make sure _w is 0 (if fully- or un-buffered) or -_bf._size
- * (if line buffered) so that we will get called again.
- * If we did not do this, a sufficient number of putc()
- * calls might wrap _w from negative to positive.
- */
- fp->_w = fp->_lbfsize;
- if (cantwrite(fp))
- return (EOF);
- c = (unsigned char)c;
-
- /*
- * If it is completely full, flush it out. Then, in any case,
- * stuff c into the buffer. If this causes the buffer to fill
- * completely, or if c is '\n' and the file is line buffered,
- * flush it (perhaps a second time). The second flush will always
- * happen on unbuffered streams, where _bf._size==1; fflush()
- * guarantees that putc() will always call wbuf() by setting _w
- * to 0, so we need not do anything else.
- */
- n = fp->_p - fp->_bf._base;
- if (n >= fp->_bf._size) {
- if (fflush(fp))
- return (EOF);
- n = 0;
- }
- fp->_w--;
- *fp->_p++ = c;
- if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n'))
- if (fflush(fp))
- return (EOF);
- return (c);
-}
diff --git a/mit-pthreads/stdio/wsetup.c b/mit-pthreads/stdio/wsetup.c
deleted file mode 100644
index 1c86f45a973..00000000000
--- a/mit-pthreads/stdio/wsetup.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1993, 1994 Chris Provenzano.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)wsetup.c 5.2 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "local.h"
-
-/*
- * Various output routines call wsetup to be sure it is safe to write,
- * because either _flags does not include __SWR, or _buf is NULL.
- * _wsetup returns 0 if OK to write, nonzero otherwise.
- */
-__swsetup(fp)
- register FILE *fp;
-{
- /* make sure stdio is set up */
- __sinit ();
-
- /*
- * If we are not writing, we had better be reading and writing.
- */
- if ((fp->_flags & __SWR) == 0) {
- if ((fp->_flags & __SRW) == 0)
- return (EOF);
- if (fp->_flags & __SRD) {
- /* clobber any ungetc data */
- if (HASUB(fp))
- FREEUB(fp);
- fp->_flags &= ~(__SRD|__SEOF);
- fp->_r = 0;
- fp->_p = fp->_bf._base;
- }
- fp->_flags |= __SWR;
- }
-
- /*
- * Make a buffer if necessary, then set _w.
- */
- if (fp->_bf._base == NULL)
- __smakebuf(fp);
- if (fp->_flags & __SLBF) {
- /*
- * It is line buffered, so make _lbfsize be -_bufsize
- * for the putc() macro. We will change _lbfsize back
- * to 0 whenever we turn off __SWR.
- */
- fp->_w = 0;
- fp->_lbfsize = -fp->_bf._size;
- } else
- fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size;
- return (0);
-}
diff --git a/mit-pthreads/stdio/xprintf.c b/mit-pthreads/stdio/xprintf.c
deleted file mode 100644
index 668e8bc0605..00000000000
--- a/mit-pthreads/stdio/xprintf.c
+++ /dev/null
@@ -1,883 +0,0 @@
-/*
-** It turns out that the printf functions in the stock MIT pthread library
-** is busted. It isn't thread safe. If two threads try to do a printf
-** of a floating point value at the same time, a core-dump might result.
-** So this code is substituted.
-*/
-/*
-** NAME: $Source$
-** VERSION: $Revision$
-** DATE: $Date$
-**
-** ONELINER: A replacement for formatted printing programs.
-**
-** COPYRIGHT:
-** Copyright (c) 1990 by D. Richard Hipp. This code is an original
-** work and has been prepared without reference to any prior
-** implementations of similar functions. No part of this code is
-** subject to licensing restrictions of any telephone company or
-** university.
-**
-** This copyright was released and the code placed in the public domain
-** by the author, D. Richard Hipp, on October 3, 1996.
-**
-** DESCRIPTION:
-** This program is an enhanced replacement for the "printf" programs
-** found in the standard library. The following enhancements are
-** supported:
-**
-** + Additional functions. The standard set of "printf" functions
-** includes printf, fprintf, sprintf, vprintf, vfprintf, and
-** vsprintf. This module adds the following:
-**
-** * snprintf -- Works like sprintf, but has an extra argument
-** which is the size of the buffer written to.
-**
-** * mprintf -- Similar to sprintf. Writes output to memory
-** obtained from mem_alloc.
-**
-** * xprintf -- Calls a function to dispose of output.
-**
-** * nprintf -- No output, but returns the number of characters
-** that would have been output by printf.
-**
-** * A v- version (ex: vsnprintf) of every function is also
-** supplied.
-**
-** + A few extensions to the formatting notation are supported:
-**
-** * The "=" flag (similar to "-") causes the output to be
-** be centered in the appropriately sized field.
-**
-** * The %b field outputs an integer in binary notation.
-**
-** * The %c field now accepts a precision. The character output
-** is repeated by the number of times the precision specifies.
-**
-** * The %' field works like %c, but takes as its character the
-** next character of the format string, instead of the next
-** argument. For example, printf("%.78'-") prints 78 minus
-** signs, the same as printf("%.78c",'-').
-**
-** + When compiled using GCC on a SPARC, this version of printf is
-** faster than the library printf for SUN OS 4.1.
-**
-** + All functions are fully reentrant.
-**
-*/
-/*
-** Undefine COMPATIBILITY to make some slight changes in the way things
-** work. I think the changes are an improvement, but they are not
-** backwards compatible.
-*/
-/* #define COMPATIBILITY / * Compatible with SUN OS 4.1 */
-#include <stdio.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-/*
-** The maximum number of digits of accuracy in a floating-point conversion.
-*/
-#define MAXDIG 20
-
-/*
-** Conversion types fall into various categories as defined by the
-** following enumeration.
-*/
-enum e_type { /* The type of the format field */
- RADIX, /* Integer types. %d, %x, %o, and so forth */
- FLOAT, /* Floating point. %f */
- EXP, /* Exponentional notation. %e and %E */
- GENERIC, /* Floating or exponential, depending on exponent. %g */
- SIZE, /* Return number of characters processed so far. %n */
- STRING, /* Strings. %s */
- PERCENT, /* Percent symbol. %% */
- CHAR, /* Characters. %c */
- ERROR, /* Used to indicate no such conversion type */
-/* The rest are extensions, not normally found in printf() */
- CHARLIT, /* Literal characters. %' */
- SEEIT, /* Strings with visible control characters. %S */
- MEM_STRING, /* A string which should be deleted after use. %z */
- ORDINAL, /* 1st, 2nd, 3rd and so forth */
-};
-
-/*
-** Each builtin conversion character (ex: the 'd' in "%d") is described
-** by an instance of the following structure
-*/
-typedef struct s_info { /* Information about each format field */
- int fmttype; /* The format field code letter */
- int base; /* The base for radix conversion */
- char *charset; /* The character set for conversion */
- int flag_signed; /* Is the quantity signed? */
- char *prefix; /* Prefix on non-zero values in alt format */
- enum e_type type; /* Conversion paradigm */
-} info;
-
-/*
-** The following table is searched linearly, so it is good to put the
-** most frequently used conversion types first.
-*/
-static info fmtinfo[] = {
- { 'd', 10, "0123456789", 1, 0, RADIX, },
- { 's', 0, 0, 0, 0, STRING, },
- { 'S', 0, 0, 0, 0, SEEIT, },
- { 'z', 0, 0, 0, 0, MEM_STRING, },
- { 'c', 0, 0, 0, 0, CHAR, },
- { 'o', 8, "01234567", 0, "0", RADIX, },
- { 'u', 10, "0123456789", 0, 0, RADIX, },
- { 'x', 16, "0123456789abcdef", 0, "x0", RADIX, },
- { 'X', 16, "0123456789ABCDEF", 0, "X0", RADIX, },
- { 'r', 10, "0123456789", 0, 0, ORDINAL, },
- { 'f', 0, 0, 1, 0, FLOAT, },
- { 'e', 0, "e", 1, 0, EXP, },
- { 'E', 0, "E", 1, 0, EXP, },
- { 'g', 0, "e", 1, 0, GENERIC, },
- { 'G', 0, "E", 1, 0, GENERIC, },
- { 'i', 10, "0123456789", 1, 0, RADIX, },
- { 'n', 0, 0, 0, 0, SIZE, },
- { 'S', 0, 0, 0, 0, SEEIT, },
- { '%', 0, 0, 0, 0, PERCENT, },
- { 'b', 2, "01", 0, "b0", RADIX, }, /* Binary notation */
- { 'p', 10, "0123456789", 0, 0, RADIX, }, /* Pointers */
- { '\'', 0, 0, 0, 0, CHARLIT, }, /* Literal char */
-};
-#define NINFO (sizeof(fmtinfo)/sizeof(info)) /* Size of the fmtinfo table */
-
-/*
-** If NOFLOATINGPOINT is defined, then none of the floating point
-** conversions will work.
-*/
-#ifndef NOFLOATINGPOINT
-/*
-** "*val" is a double such that 0.1 <= *val < 10.0
-** Return the ascii code for the leading digit of *val, then
-** multiply "*val" by 10.0 to renormalize.
-**
-** Example:
-** input: *val = 3.14159
-** output: *val = 1.4159 function return = '3'
-**
-** The counter *cnt is incremented each time. After counter exceeds
-** 16 (the number of significant digits in a 64-bit float) '0' is
-** always returned.
-*/
-static int getdigit(long double *val, int *cnt){
- int digit;
- long double d;
- if( (*cnt)++ >= MAXDIG ) return '0';
- digit = (int)*val;
- d = digit;
- digit += '0';
- *val = (*val - d)*10.0;
- return digit;
-}
-#endif
-
-/*
-** Setting the size of the BUFFER involves trade-offs. No %d or %f
-** conversion can have more than BUFSIZE characters. If the field
-** width is larger than BUFSIZE, it is silently shortened. On the
-** other hand, this routine consumes more stack space with larger
-** BUFSIZEs. If you have some threads for which you want to minimize
-** stack space, you should keep BUFSIZE small.
-*/
-#define BUFSIZE 100 /* Size of the output buffer */
-
-/*
-** The root program. All variations call this core.
-**
-** INPUTS:
-** func This is a pointer to a function taking three arguments
-** 1. A pointer to the list of characters to be output
-** (Note, this list is NOT null terminated.)
-** 2. An integer number of characters to be output.
-** (Note: This number might be zero.)
-** 3. A pointer to anything. Same as the "arg" parameter.
-**
-** arg This is the pointer to anything which will be passed as the
-** third argument to "func". Use it for whatever you like.
-**
-** fmt This is the format string, as in the usual print.
-**
-** ap This is a pointer to a list of arguments. Same as in
-** vfprint.
-**
-** OUTPUTS:
-** The return value is the total number of characters sent to
-** the function "func". Returns -1 on a error.
-**
-** Note that the order in which automatic variables are declared below
-** seems to make a big difference in determining how fast this beast
-** will run.
-*/
-static int vxprintf(func,arg,format,ap)
- void (*func)(char*,int,void*);
- void *arg;
- const char *format;
- va_list ap;
-{
- register const char *fmt; /* The format string. */
- register int c; /* Next character in the format string */
- register char *bufpt; /* Pointer to the conversion buffer */
- register int precision; /* Precision of the current field */
- register int length; /* Length of the field */
- register int idx; /* A general purpose loop counter */
- int count; /* Total number of characters output */
- int width; /* Width of the current field */
- int flag_leftjustify; /* True if "-" flag is present */
- int flag_plussign; /* True if "+" flag is present */
- int flag_blanksign; /* True if " " flag is present */
- int flag_alternateform; /* True if "#" flag is present */
- int flag_zeropad; /* True if field width constant starts with zero */
- int flag_long; /* True if "l" flag is present */
- int flag_center; /* True if "=" flag is present */
- unsigned long longvalue; /* Value for integer types */
- long double realvalue; /* Value for real types */
- info *infop; /* Pointer to the appropriate info structure */
- char buf[BUFSIZE]; /* Conversion buffer */
- char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
- int errorflag = 0; /* True if an error is encountered */
- enum e_type xtype; /* Conversion paradigm */
- char *zMem; /* String to be freed */
- static char spaces[] =
- " ";
-#define SPACESIZE (sizeof(spaces)-1)
-#ifndef NOFLOATINGPOINT
- int exp; /* exponent of real numbers */
- long double rounder; /* Used for rounding floating point values */
- int flag_dp; /* True if decimal point should be shown */
- int flag_rtz; /* True if trailing zeros should be removed */
- int flag_exp; /* True to force display of the exponent */
- int nsd; /* Number of significant digits returned */
-#endif
-
- fmt = format; /* Put in a register for speed */
- count = length = 0;
- bufpt = 0;
- for(; (c=(*fmt))!=0; ++fmt){
- if( c!='%' ){
- register int amt;
- bufpt = (char *)fmt;
- amt = 1;
- while( (c=(*++fmt))!='%' && c!=0 ) amt++;
- (*func)(bufpt,amt,arg);
- count += amt;
- if( c==0 ) break;
- }
- if( (c=(*++fmt))==0 ){
- errorflag = 1;
- (*func)("%",1,arg);
- count++;
- break;
- }
- /* Find out what flags are present */
- flag_leftjustify = flag_plussign = flag_blanksign =
- flag_alternateform = flag_zeropad = flag_center = 0;
- do{
- switch( c ){
- case '-': flag_leftjustify = 1; c = 0; break;
- case '+': flag_plussign = 1; c = 0; break;
- case ' ': flag_blanksign = 1; c = 0; break;
- case '#': flag_alternateform = 1; c = 0; break;
- case '0': flag_zeropad = 1; c = 0; break;
- case '=': flag_center = 1; c = 0; break;
- default: break;
- }
- }while( c==0 && (c=(*++fmt))!=0 );
- if( flag_center ) flag_leftjustify = 0;
- /* Get the field width */
- width = 0;
- if( c=='*' ){
- width = va_arg(ap,int);
- if( width<0 ){
- flag_leftjustify = 1;
- width = -width;
- }
- c = *++fmt;
- }else{
- while( isdigit(c) ){
- width = width*10 + c - '0';
- c = *++fmt;
- }
- }
- if( width > BUFSIZE-10 ){
- width = BUFSIZE-10;
- }
- /* Get the precision */
- if( c=='.' ){
- precision = 0;
- c = *++fmt;
- if( c=='*' ){
- precision = va_arg(ap,int);
-#ifndef COMPATIBILITY
- /* This is sensible, but SUN OS 4.1 doesn't do it. */
- if( precision<0 ) precision = -precision;
-#endif
- c = *++fmt;
- }else{
- while( isdigit(c) ){
- precision = precision*10 + c - '0';
- c = *++fmt;
- }
- }
- /* Limit the precision to prevent overflowing buf[] during conversion */
- if( precision>BUFSIZE-40 ) precision = BUFSIZE-40;
- }else{
- precision = -1;
- }
- /* Get the conversion type modifier */
- if( c=='l' ){
- flag_long = 1;
- c = *++fmt;
- }else{
- flag_long = 0;
- }
- /* Fetch the info entry for the field */
- infop = 0;
- for(idx=0; idx<NINFO; idx++){
- if( c==fmtinfo[idx].fmttype ){
- infop = &fmtinfo[idx];
- break;
- }
- }
- /* No info entry found. It must be an error. */
- if( infop==0 ){
- xtype = ERROR;
- }else{
- xtype = infop->type;
- }
-
- /*
- ** At this point, variables are initialized as follows:
- **
- ** flag_alternateform TRUE if a '#' is present.
- ** flag_plussign TRUE if a '+' is present.
- ** flag_leftjustify TRUE if a '-' is present or if the
- ** field width was negative.
- ** flag_zeropad TRUE if the width began with 0.
- ** flag_long TRUE if the letter 'l' (ell) prefixed
- ** the conversion character.
- ** flag_blanksign TRUE if a ' ' is present.
- ** width The specified field width. This is
- ** always non-negative. Zero is the default.
- ** precision The specified precision. The default
- ** is -1.
- ** xtype The class of the conversion.
- ** infop Pointer to the appropriate info struct.
- */
- switch( xtype ){
- case ORDINAL:
- case RADIX:
- if( flag_long ) longvalue = va_arg(ap,long);
- else longvalue = va_arg(ap,int);
-#ifdef COMPATIBILITY
- /* For the format %#x, the value zero is printed "0" not "0x0".
- ** I think this is stupid. */
- if( longvalue==0 ) flag_alternateform = 0;
-#else
- /* More sensible: turn off the prefix for octal (to prevent "00"),
- ** but leave the prefix for hex. */
- if( longvalue==0 && infop->base==8 ) flag_alternateform = 0;
-#endif
- if( infop->flag_signed ){
- if( *(long*)&longvalue<0 ){
- longvalue = -*(long*)&longvalue;
- prefix = '-';
- }else if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
- }else prefix = 0;
- if( flag_zeropad && precision<width-(prefix!=0) ){
- precision = width-(prefix!=0);
- }
- bufpt = &buf[BUFSIZE];
- if( xtype==ORDINAL ){
- long a,b;
- a = longvalue%10;
- b = longvalue%100;
- bufpt -= 2;
- if( a==0 || a>3 || (b>10 && b<14) ){
- bufpt[0] = 't';
- bufpt[1] = 'h';
- }else if( a==1 ){
- bufpt[0] = 's';
- bufpt[1] = 't';
- }else if( a==2 ){
- bufpt[0] = 'n';
- bufpt[1] = 'd';
- }else if( a==3 ){
- bufpt[0] = 'r';
- bufpt[1] = 'd';
- }
- }
- {
- register char *cset; /* Use registers for speed */
- register int base;
- cset = infop->charset;
- base = infop->base;
- do{ /* Convert to ascii */
- *(--bufpt) = cset[longvalue%base];
- longvalue = longvalue/base;
- }while( longvalue>0 );
- }
- length = (int)(&buf[BUFSIZE]-bufpt);
- for(idx=precision-length; idx>0; idx--){
- *(--bufpt) = '0'; /* Zero pad */
- }
- if( prefix ) *(--bufpt) = prefix; /* Add sign */
- if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
- char *pre, x;
- pre = infop->prefix;
- if( *bufpt!=pre[0] ){
- for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x;
- }
- }
- length = (int)(&buf[BUFSIZE]-bufpt);
- break;
- case FLOAT:
- case EXP:
- case GENERIC:
- realvalue = va_arg(ap,double);
-#ifndef NOFLOATINGPOINT
- if( precision<0 ) precision = 6; /* Set default precision */
- if( precision>BUFSIZE-10 ) precision = BUFSIZE-10;
- if( realvalue<0.0 ){
- realvalue = -realvalue;
- prefix = '-';
- }else{
- if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
- }
- if( infop->type==GENERIC && precision>0 ) precision--;
- rounder = 0.0;
-#ifdef COMPATIBILITY
- /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */
- for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
-#else
- /* It makes more sense to use 0.5 */
- if( precision>MAXDIG-1 ) idx = MAXDIG-1;
- else idx = precision;
- for(rounder=0.5; idx>0; idx--, rounder*=0.1);
-#endif
- if( infop->type==FLOAT ) realvalue += rounder;
- /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
- exp = 0;
- if( realvalue>0.0 ){
- int k = 0;
- while( realvalue>=1e8 && k++<100 ){ realvalue *= 1e-8; exp+=8; }
- while( realvalue>=10.0 && k++<100 ){ realvalue *= 0.1; exp++; }
- while( realvalue<1e-8 && k++<100 ){ realvalue *= 1e8; exp-=8; }
- while( realvalue<1.0 && k++<100 ){ realvalue *= 10.0; exp--; }
- if( k>=100 ){
- bufpt = "NaN";
- length = 3;
- break;
- }
- }
- bufpt = buf;
- /*
- ** If the field type is GENERIC, then convert to either EXP
- ** or FLOAT, as appropriate.
- */
- flag_exp = xtype==EXP;
- if( xtype!=FLOAT ){
- realvalue += rounder;
- if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
- }
- if( xtype==GENERIC ){
- flag_rtz = !flag_alternateform;
- if( exp<-4 || exp>precision ){
- xtype = EXP;
- }else{
- precision = precision - exp;
- xtype = FLOAT;
- }
- }else{
- flag_rtz = 0;
- }
- /*
- ** The "exp+precision" test causes output to be of type EXP if
- ** the precision is too large to fit in buf[].
- */
- nsd = 0;
- if( xtype==FLOAT && exp+precision<BUFSIZE-30 ){
- flag_dp = (precision>0 || flag_alternateform);
- if( prefix ) *(bufpt++) = prefix; /* Sign */
- if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */
- else for(; exp>=0; exp--) *(bufpt++) = getdigit(&realvalue,&nsd);
- if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */
- for(exp++; exp<0 && precision>0; precision--, exp++){
- *(bufpt++) = '0';
- }
- while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue,&nsd);
- *(bufpt--) = 0; /* Null terminate */
- if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */
- while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
- if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
- }
- bufpt++; /* point to next free slot */
- }else{ /* EXP or GENERIC */
- flag_dp = (precision>0 || flag_alternateform);
- if( prefix ) *(bufpt++) = prefix; /* Sign */
- *(bufpt++) = getdigit(&realvalue,&nsd); /* First digit */
- if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */
- while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue,&nsd);
- bufpt--; /* point to last digit */
- if( flag_rtz && flag_dp ){ /* Remove tail zeros */
- while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
- if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
- }
- bufpt++; /* point to next free slot */
- if( exp || flag_exp ){
- *(bufpt++) = infop->charset[0];
- if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */
- else { *(bufpt++) = '+'; }
- if( exp>=100 ){
- *(bufpt++) = (exp/100)+'0'; /* 100's digit */
- exp %= 100;
- }
- *(bufpt++) = exp/10+'0'; /* 10's digit */
- *(bufpt++) = exp%10+'0'; /* 1's digit */
- }
- }
- /* The converted number is in buf[] and zero terminated. Output it.
- ** Note that the number is in the usual order, not reversed as with
- ** integer conversions. */
- length = (int)(bufpt-buf);
- bufpt = buf;
-
- /* Special case: Add leading zeros if the flag_zeropad flag is
- ** set and we are not left justified */
- if( flag_zeropad && !flag_leftjustify && length < width){
- int i;
- int nPad = width - length;
- for(i=width; i>=nPad; i--){
- bufpt[i] = bufpt[i-nPad];
- }
- i = prefix!=0;
- while( nPad-- ) bufpt[i++] = '0';
- length = width;
- }
-#endif
- break;
- case SIZE:
- *(va_arg(ap,int*)) = count;
- length = width = 0;
- break;
- case PERCENT:
- buf[0] = '%';
- bufpt = buf;
- length = 1;
- break;
- case CHARLIT:
- case CHAR:
- c = buf[0] = (xtype==CHAR ? va_arg(ap,int) : *++fmt);
- if( precision>=0 ){
- for(idx=1; idx<precision; idx++) buf[idx] = c;
- length = precision;
- }else{
- length =1;
- }
- bufpt = buf;
- break;
- case STRING:
- case MEM_STRING:
- zMem = bufpt = va_arg(ap,char*);
- if( bufpt==0 ) bufpt = "(null)";
- length = strlen(bufpt);
- if( precision>=0 && precision<length ) length = precision;
- break;
- case SEEIT:
- {
- int i;
- int c;
- char *arg = va_arg(ap,char*);
- for(i=0; i<BUFSIZE-1 && (c = *arg++)!=0; i++){
- if( c<0x20 || c>=0x7f ){
- buf[i++] = '^';
- buf[i] = (c&0x1f)+0x40;
- }else{
- buf[i] = c;
- }
- }
- bufpt = buf;
- length = i;
- if( precision>=0 && precision<length ) length = precision;
- }
- break;
- case ERROR:
- buf[0] = '%';
- buf[1] = c;
- errorflag = 0;
- idx = 1+(c!=0);
- (*func)("%",idx,arg);
- count += idx;
- if( c==0 ) fmt--;
- break;
- }/* End switch over the format type */
- /*
- ** The text of the conversion is pointed to by "bufpt" and is
- ** "length" characters long. The field width is "width". Do
- ** the output.
- */
- if( !flag_leftjustify ){
- register int nspace;
- nspace = width-length;
- if( nspace>0 ){
- if( flag_center ){
- nspace = nspace/2;
- width -= nspace;
- flag_leftjustify = 1;
- }
- count += nspace;
- while( nspace>=SPACESIZE ){
- (*func)(spaces,SPACESIZE,arg);
- nspace -= SPACESIZE;
- }
- if( nspace>0 ) (*func)(spaces,nspace,arg);
- }
- }
- if( length>0 ){
- (*func)(bufpt,length,arg);
- count += length;
- }
- if( xtype==MEM_STRING && zMem ){
- free(zMem);
- }
- if( flag_leftjustify ){
- register int nspace;
- nspace = width-length;
- if( nspace>0 ){
- count += nspace;
- while( nspace>=SPACESIZE ){
- (*func)(spaces,SPACESIZE,arg);
- nspace -= SPACESIZE;
- }
- if( nspace>0 ) (*func)(spaces,nspace,arg);
- }
- }
- }/* End for loop over the format string */
- return errorflag ? -1 : count;
-} /* End of function */
-
-/*
-** This non-standard function is still occasionally useful....
-*/
-int xprintf(
- void (*func)(char*,int,void*),
- void *arg,
- const char *format,
- ...
-){
- va_list ap;
- va_start(ap,format);
- return vxprintf(func,arg,format,ap);
-}
-
-/*
-** Now for string-print, also as found in any standard library.
-** Add to this the snprint function which stops added characters
-** to the string at a given length.
-**
-** Note that snprint returns the length of the string as it would
-** be if there were no limit on the output.
-*/
-struct s_strargument { /* Describes the string being written to */
- char *next; /* Next free slot in the string */
- char *last; /* Last available slot in the string */
-};
-
-static void sout(txt,amt,arg)
- char *txt;
- int amt;
- void *arg;
-{
- register char *head;
- register const char *t;
- register int a;
- register char *tail;
- a = amt;
- t = txt;
- head = ((struct s_strargument*)arg)->next;
- tail = ((struct s_strargument*)arg)->last;
- if( tail ){
- while( a-- >0 && head<tail ) *(head++) = *(t++);
- }else{
- while( a-- >0 ) *(head++) = *(t++);
- }
- *head = 0;
- ((struct s_strargument*)arg)->next = head;
-}
-
-int sprintf(char *buf, const char *fmt, ...){
- int rc;
- va_list ap;
- struct s_strargument arg;
-
- va_start(ap,fmt);
- arg.next = buf;
- arg.last = 0;
- *arg.next = 0;
- rc = vxprintf(sout,&arg,fmt,ap);
- va_end(ap);
-}
-int vsprintf(char *buf,const char *fmt,va_list ap){
- struct s_strargument arg;
- arg.next = buf;
- arg.last = 0;
- *buf = 0;
- return vxprintf(sout,&arg,fmt,ap);
-}
-int snprintf(char *buf, size_t n, const char *fmt, ...){
- int rc;
- va_list ap;
- struct s_strargument arg;
-
- va_start(ap,fmt);
- arg.next = buf;
- arg.last = &arg.next[n-1];
- *arg.next = 0;
- rc = vxprintf(sout,&arg,fmt,ap);
- va_end(ap);
-}
-int vsnprintf(char *buf, size_t n, const char *fmt, va_list ap){
- struct s_strargument arg;
- arg.next = buf;
- arg.last = &buf[n-1];
- *buf = 0;
- return vxprintf(sout,&arg,fmt,ap);
-}
-
-/*
-** The following section of code handles the mprintf routine, that
-** writes to memory obtained from malloc().
-*/
-
-/* This structure is used to store state information about the
-** write in progress
-*/
-struct sgMprintf {
- char *zBase; /* A base allocation */
- char *zText; /* The string collected so far */
- int nChar; /* Length of the string so far */
- int nAlloc; /* Amount of space allocated in zText */
-};
-
-/* The xprintf callback function. */
-static void mout(zNewText,nNewChar,arg)
- char *zNewText;
- int nNewChar;
- void *arg;
-{
- struct sgMprintf *pM = (struct sgMprintf*)arg;
- if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
- pM->nAlloc = pM->nChar + nNewChar*2 + 1;
- if( pM->zText==pM->zBase ){
- pM->zText = malloc(pM->nAlloc);
- if( pM->zText && pM->nChar ) memcpy(pM->zText,pM->zBase,pM->nChar);
- }else{
- pM->zText = realloc(pM->zText, pM->nAlloc);
- }
- }
- if( pM->zText ){
- memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
- pM->nChar += nNewChar;
- pM->zText[pM->nChar] = 0;
- }
-}
-
-/*
-** mprintf() works like printf(), but allocations memory to hold the
-** resulting string and returns a pointer to the allocated memory.
-**
-** We changed the name to TclMPrint() to conform with the Tcl private
-** routine naming conventions.
-*/
-char *mprintf(const char *zFormat, ...){
- va_list ap;
- struct sgMprintf sMprintf;
- char *zNew;
- char zBuf[200];
-
- va_start(ap,zFormat);
- sMprintf.nChar = 0;
- sMprintf.nAlloc = sizeof(zBuf);
- sMprintf.zText = zBuf;
- sMprintf.zBase = zBuf;
- vxprintf(mout,&sMprintf,zFormat,ap);
- va_end(ap);
- if( sMprintf.zText==sMprintf.zBase ){
- zNew = malloc( sMprintf.nChar+1 );
- if( zNew ) strcpy(zNew,zBuf);
- }else{
- zNew = realloc(sMprintf.zText,sMprintf.nChar+1);
- }
-
- return zNew;
-}
-
-/* This is the varargs version of mprintf.
-**
-** The name is changed to TclVMPrintf() to conform with Tcl naming
-** conventions.
-*/
-char *vmprintf(const char *zFormat,va_list ap){
- struct sgMprintf sMprintf;
- char zBuf[200];
- sMprintf.nChar = 0;
- sMprintf.zText = zBuf;
- sMprintf.nAlloc = sizeof(zBuf);
- sMprintf.zBase = zBuf;
- vxprintf(mout,&sMprintf,zFormat,ap);
- if( sMprintf.zText==sMprintf.zBase ){
- sMprintf.zText = malloc( strlen(zBuf)+1 );
- if( sMprintf.zText ) strcpy(sMprintf.zText,zBuf);
- }else{
- sMprintf.zText = realloc(sMprintf.zText,sMprintf.nChar+1);
- }
- return sMprintf.zText;
-}
-
-/*
-** The following section of code handles the standard fprintf routines
-** for pthreads.
-*/
-
-/* The xprintf callback function. */
-static void fout(zNewText,nNewChar,arg)
- char *zNewText;
- int nNewChar;
- void *arg;
-{
- fwrite(zNewText,1,nNewChar,(FILE*)arg);
-}
-
-/* The public interface routines */
-int fprintf(FILE *pOut, const char *zFormat, ...){
- va_list ap;
- int retc;
-
- va_start(ap,zFormat);
- retc = vxprintf(fout,pOut,zFormat,ap);
- va_end(ap);
- return retc;
-}
-int vfprintf(FILE *pOut, const char *zFormat, va_list ap){
- return vxprintf(fout,pOut,zFormat,ap);
-}
-int printf(const char *zFormat, ...){
- va_list ap;
- int retc;
-
- va_start(ap,zFormat);
- retc = vxprintf(fout,stdout,zFormat,ap);
- va_end(ap);
- return retc;
-}
-int vprintf(const char *zFormat, va_list ap){
- return vxprintf(fout,stdout,zFormat,ap);
-}
diff --git a/mit-pthreads/stdlib/GNUmakefile.inc b/mit-pthreads/stdlib/GNUmakefile.inc
deleted file mode 100755
index 2f55ce8b217..00000000000
--- a/mit-pthreads/stdlib/GNUmakefile.inc
+++ /dev/null
@@ -1,7 +0,0 @@
-# @(#)Makefile.inc 5.6 (Berkeley) 6/4/91
-
-# stdlib sources
-VPATH:= ${VPATH}:${srcdir}/stdlib
-
-SRCS:= abort.c exit.c strtod.c getopt.c rand.c random.c strtol.c strtoul.c \
- system.c $(SRCS)
diff --git a/mit-pthreads/stdlib/Makefile.inc b/mit-pthreads/stdlib/Makefile.inc
deleted file mode 100644
index cc323d1d0e1..00000000000
--- a/mit-pthreads/stdlib/Makefile.inc
+++ /dev/null
@@ -1,10 +0,0 @@
-# @(#)Makefile.inc 5.6 (Berkeley) 6/4/91
-
-# stdlib sources
-.PATH: ${srcdir}/${MACHINE}/stdlib ${srcdir}/stdlib
-
-SRCS+= exit.c strtod.c getopt.c rand.c random.c strtol.c strtoul.c
-
-# SRCS+=abort.c atexit.c atoi.c atof.c atol.c bsearch.c calloc.c div.c \
-# getenv.c heapsort.c labs.c ldiv.c malloc.c multibyte.c \
-# putenv.c qsort.c radixsort.c setenv.c system.c
diff --git a/mit-pthreads/stdlib/abort.c b/mit-pthreads/stdlib/abort.c
deleted file mode 100644
index 474c35f6107..00000000000
--- a/mit-pthreads/stdlib/abort.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)abort.c 5.11 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-
-void
-abort()
-{
- sigset_t mask;
-
- sigfillset(&mask);
- /*
- * don't block SIGABRT to give any handler a chance; we ignore
- * any errors -- X3J11 doesn't allow abort to return anyway.
- */
- sigdelset(&mask, SIGABRT);
- pthread_sigmask(SIG_SETMASK, &mask, NULL);
- kill(getpid(), SIGABRT);
-
- /*
- * if SIGABRT ignored, or caught and the handler returns, do
- * it again, only harder.
- */
- pthread_signal(SIGABRT, SIG_DFL);
- pthread_sigmask(SIG_SETMASK, &mask, NULL);
- kill(getpid(), SIGABRT);
- exit(1);
-}
diff --git a/mit-pthreads/stdlib/atexit.h b/mit-pthreads/stdlib/atexit.h
deleted file mode 100644
index d13dc588781..00000000000
--- a/mit-pthreads/stdlib/atexit.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)atexit.h 5.1 (Berkeley) 5/15/90
- * $Id$
- */
-
-/* must be at least 32 to guarantee ANSI conformance */
-#define ATEXIT_SIZE 32
-
-struct atexit {
- struct atexit *next; /* next in list */
- int ind; /* next index in this table */
- void (*fns[ATEXIT_SIZE])(); /* the table itself */
-};
-
-struct atexit *__atexit; /* points to head of LIFO stack */
diff --git a/mit-pthreads/stdlib/exit.c b/mit-pthreads/stdlib/exit.c
deleted file mode 100644
index 159a066d797..00000000000
--- a/mit-pthreads/stdlib/exit.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)exit.c 5.4 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/cdefs.h>
-#include <pthread/posix.h>
-#include "atexit.h"
-
-void (*__cleanup)();
-
-/*
- * Exit, flushing stdio buffers if necessary.
- */
-void __NORETURN exit(int status)
-{
- register struct atexit *p;
- register int n;
-
- for (p = __atexit; p; p = p->next)
- for (n = p->ind; --n >= 0;)
- (*p->fns[n])();
- if (__cleanup)
- (*__cleanup)();
- _exit(status);
-
- /* This is to shut up gcc, which complains about this function
- * returning even if _exit() is declared noreturn. */
- while (1);
-}
-
-
-/*
- * Register a function to be performed at exit.
- */
-int atexit(void (*fn)())
-{
- static struct atexit __atexit0; /* one guaranteed table */
- register struct atexit *p;
-
- if ((p = __atexit) == NULL)
- __atexit = p = &__atexit0;
- else if (p->ind >= ATEXIT_SIZE) {
- if ((p = malloc(sizeof(*p))) == NULL)
- return (-1);
- p->ind = 0;
- p->next = __atexit;
- __atexit = p;
- }
- p->fns[p->ind++] = fn;
- return (0);
-}
diff --git a/mit-pthreads/stdlib/getopt.c b/mit-pthreads/stdlib/getopt.c
deleted file mode 100644
index 71fafd49490..00000000000
--- a/mit-pthreads/stdlib/getopt.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <config.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * get option letter from argument vector
- */
-
-#ifndef LD_LINKS_STATIC_DATA
-/*
- * Under the Solaris ld, some data sections are linked in regaurdless of
- * whether or not the name has been resolved.
- */
-int opterr = 1, /* if error message should be printed */
- optind = 1, /* index into parent argv vector */
- optopt = 0; /* character checked for validity */
-char * optarg = NULL; /* argument associated with option */
-
-#else
-
-extern int opterr, optind, optopt;
-extern char *optarg;
-
-#endif
-
-#define BADCH (int)'?'
-#define EMSG ""
-
-int
-getopt(nargc, nargv, ostr)
- int nargc;
- char * const *nargv;
- const char *ostr;
-{
- static char *place = EMSG; /* option letter processing */
- register char *oli; /* option letter list index */
- char *p;
-
- if (!*place) { /* update scanning pointer */
- if (optind >= nargc || *(place = nargv[optind]) != '-') {
- place = EMSG;
- return(EOF);
- }
- if (place[1] && *++place == '-') { /* found "--" */
- ++optind;
- place = EMSG;
- return(EOF);
- }
- } /* option letter okay? */
- if ((optopt = (int)*place++) == (int)':' ||
- !(oli = strchr(ostr, optopt))) {
- /*
- * if the user didn't specify '-' as an option,
- * assume it means EOF.
- */
- if (optopt == (int)'-')
- return(EOF);
- if (!*place)
- ++optind;
- if (opterr) {
- if (!(p = strrchr(*nargv, '/')))
- p = *nargv;
- else
- ++p;
- (void)fprintf(stderr, "%s: illegal option -- %c\n",
- p, optopt);
- }
- return(BADCH);
- }
- if (*++oli != ':') { /* don't need argument */
- optarg = NULL;
- if (!*place)
- ++optind;
- }
- else { /* need an argument */
- if (*place) /* no white space */
- optarg = place;
- else if (nargc <= ++optind) { /* no arg */
- place = EMSG;
- if (!(p = strrchr(*nargv, '/')))
- p = *nargv;
- else
- ++p;
- if (opterr)
- (void)fprintf(stderr,
- "%s: option requires an argument -- %c\n",
- p, optopt);
- return(BADCH);
- }
- else /* white space */
- optarg = nargv[optind];
- place = EMSG;
- ++optind;
- }
- return(optopt); /* dump back option letter */
-}
diff --git a/mit-pthreads/stdlib/rand.c b/mit-pthreads/stdlib/rand.c
deleted file mode 100644
index 9367dceed25..00000000000
--- a/mit-pthreads/stdlib/rand.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rand.c 5.6 (Berkeley) 6/24/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <stdlib.h>
-
-static u_long next = 1;
-
-int rand_r(u_int * next_r)
-{
- int ret;
-
- (*next_r) = (*next_r) * 1103515245 + 12345;
- ret = (*next_r) & RAND_MAX;
- return(ret);
-}
-
-#undef rand
-int rand(void)
-{
- return ((next = next * 1103515245 + 12345) & RAND_MAX);
-}
-
-#undef srand
-void srand(unsigned int seed)
-{
- next = seed;
-}
diff --git a/mit-pthreads/stdlib/random.c b/mit-pthreads/stdlib/random.c
deleted file mode 100644
index 8cba96e7534..00000000000
--- a/mit-pthreads/stdlib/random.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * Copyright (c) 1994 Chris Provenzano, proven@mit.edu
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)random.c 5.9 (Berkeley) 2/23/91";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/*
- * random.c:
- *
- * An improved random number generation package. In addition to the standard
- * rand()/srand() like interface, this package also has a special state info
- * interface. The initstate() routine is called with a seed, an array of
- * bytes, and a count of how many bytes are being passed in; this array is
- * then initialized to contain information for random number generation with
- * that much state information. Good sizes for the amount of state
- * information are 32, 64, 128, and 256 bytes. The state can be switched by
- * calling the setstate() routine with the same array as was initiallized
- * with initstate(). By default, the package runs with 128 bytes of state
- * information and generates far better random numbers than a linear
- * congruential generator. If the amount of state information is less than
- * 32 bytes, a simple linear congruential R.N.G. is used.
- *
- * Internally, the state information is treated as an array of longs; the
- * zeroeth element of the array is the type of R.N.G. being used (small
- * integer); the remainder of the array is the state information for the
- * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
- * state information, which will allow a degree seven polynomial. (Note:
- * the zeroeth word of state information also has some other information
- * stored in it -- see setstate() for details).
- *
- * The random number generation technique is a linear feedback shift register
- * approach, employing trinomials (since there are fewer terms to sum up that
- * way). In this approach, the least significant bit of all the numbers in
- * the state table will act as a linear feedback shift register, and will
- * have period 2^deg - 1 (where deg is the degree of the polynomial being
- * used, assuming that the polynomial is irreducible and primitive). The
- * higher order bits will have longer periods, since their values are also
- * influenced by pseudo-random carries out of the lower bits. The total
- * period of the generator is approximately deg*(2**deg - 1); thus doubling
- * the amount of state information has a vast influence on the period of the
- * generator. Note: the deg*(2**deg - 1) is an approximation only good for
- * large deg, when the period of the shift register is the dominant factor.
- * With deg equal to seven, the period is actually much longer than the
- * 7*(2**7 - 1) predicted by this formula.
- */
-
-/*
- * For each of the currently supported random number generators, we have a
- * break value on the amount of state information (you need at least this
- * many bytes of state info to support this random number generator), a degree
- * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
- * the separation between the two lower order coefficients of the trinomial.
- */
-#define TYPE_0 0 /* linear congruential */
-#define BREAK_0 8
-#define DEG_0 0
-#define SEP_0 0
-
-#define TYPE_1 1 /* x**7 + x**3 + 1 */
-#define BREAK_1 32
-#define DEG_1 7
-#define SEP_1 3
-
-#define TYPE_2 2 /* x**15 + x + 1 */
-#define BREAK_2 64
-#define DEG_2 15
-#define SEP_2 1
-
-#define TYPE_3 3 /* x**31 + x**3 + 1 */
-#define BREAK_3 128
-#define DEG_3 31
-#define SEP_3 3
-
-#define TYPE_4 4 /* x**63 + x + 1 */
-#define BREAK_4 256
-#define DEG_4 63
-#define SEP_4 1
-
-/*
- * Array versions of the above information to make code run faster --
- * relies on fact that TYPE_i == i.
- */
-#define MAX_TYPES 5 /* max number of types above */
-
-static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
-static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
-
-/*
- * Initially, everything is set up as if from:
- *
- * initstate(1, &randtbl, 128);
- *
- * Note that this initialization takes advantage of the fact that srandom()
- * advances the front and rear pointers 10*rand_deg times, and hence the
- * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
- * element of the state information, which contains info about the current
- * position of the rear pointer is just
- *
- * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
- */
-
-static long randtbl[DEG_3 + 1] = {
- TYPE_3,
- 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
- 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
- 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88,
- 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
- 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
- 0x27fb47b9,
-};
-
-/*
- * fptr and rptr are two pointers into the state info, a front and a rear
- * pointer. These two pointers are always rand_sep places aparts, as they
- * cycle cyclically through the state information. (Yes, this does mean we
- * could get away with just one pointer, but the code for random() is more
- * efficient this way). The pointers are left positioned as they would be
- * from the call
- *
- * initstate(1, randtbl, 128);
- *
- * (The position of the rear pointer, rptr, is really 0 (as explained above
- * in the initialization of randtbl) because the state table pointer is set
- * to point to randtbl[1] (as explained below).
- */
-static long *fptr = &randtbl[SEP_3 + 1];
-static long *rptr = &randtbl[1];
-
-/*
- * The following things are the pointer to the state information table, the
- * type of the current generator, the degree of the current polynomial being
- * used, and the separation between the two pointers. Note that for efficiency
- * of random(), we remember the first location of the state information, not
- * the zeroeth. Hence it is valid to access state[-1], which is used to
- * store the type of the R.N.G. Also, we remember the last location, since
- * this is more efficient than indexing every time to find the address of
- * the last element to see if the front and rear pointers have wrapped.
- */
-static long *state = &randtbl[1];
-static int rand_type = TYPE_3;
-static int rand_deg = DEG_3;
-static int rand_sep = SEP_3;
-static long *end_ptr = &randtbl[DEG_3 + 1];
-
-/*
- * State info won't be corrupted by multiple simultaneous calls,
- * but srandom(), initstate(), and setstate() affect all threads
- */
-static pthread_mutex_t random_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/*
- * random:
- *
- * If we are using the trivial TYPE_0 R.N.G., just do the old linear
- * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
- * the same in all the other cases due to all the global variables that have
- * been set up. The basic operation is to add the number at the rear pointer
- * into the one at the front pointer. Then both pointers are advanced to
- * the next location cyclically in the table. The value returned is the sum
- * generated, reduced to 31 bits by throwing away the "least random" low bit.
- *
- * Note: the code takes advantage of the fact that both the front and
- * rear pointers can't wrap on the same call by not testing the rear
- * pointer if the front one has wrapped.
- *
- * Returns a 31-bit random number.
- */
-static long random_basic()
-{
- long i;
-
- if (rand_type == TYPE_0)
- i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
- else {
- *fptr += *rptr;
- i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */
- if (++fptr >= end_ptr) {
- fptr = state;
- ++rptr;
- } else if (++rptr >= end_ptr)
- rptr = state;
- }
- return(i);
-}
-
-long random()
-{
- long ret;
-
- pthread_mutex_lock(&random_mutex);
- ret = random_basic();
- pthread_mutex_unlock(&random_mutex);
- return(ret);
-}
-/*
- * srandom:
- *
- * Initialize the random number generator based on the given seed. If the
- * type is the trivial no-state-information type, just remember the seed.
- * Otherwise, initializes state[] based on the given "seed" via a linear
- * congruential generator. Then, the pointers are set to known locations
- * that are exactly rand_sep places apart. Lastly, it cycles the state
- * information a given number of times to get rid of any initial dependencies
- * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
- * for default usage relies on values produced by this routine.
- */
-static void srandom_basic(u_int x)
-{
- int i;
-
- state[0] = x;
- for (i = 1; i < rand_deg; i++)
- state[i] = 1103515245 * state[i - 1] + 12345;
- fptr = &state[rand_sep];
- rptr = &state[0];
-
- for (i = 0; i < 10 * rand_deg; i++)
- (void)random_basic();
-}
-
-void srandom(u_int x)
-{
- pthread_mutex_lock(&random_mutex);
- srandom_basic(x);
- pthread_mutex_unlock(&random_mutex);
-}
-
-/*
- * initstate:
- *
- * Initialize the state information in the given array of n bytes for future
- * random number generation. Based on the number of bytes we are given, and
- * the break values for the different R.N.G.'s, we choose the best (largest)
- * one we can and set things up for it. srandom() is then called to
- * initialize the state information.
- *
- * Note that on return from srandom(), we set state[-1] to be the type
- * multiplexed with the current value of the rear pointer; this is so
- * successive calls to initstate() won't lose this information and will be
- * able to restart with setstate().
- *
- * Note: the first thing we do is save the current state, if any, just like
- * setstate() so that it doesn't matter when initstate is called.
- *
- * Returns a pointer to the old state.
- */
-#ifdef initstate
-#undef initstate
-#endif
-char * initstate(u_int seed, char * arg_state, int n)
-{
- register char *ostate = (char *)(&state[-1]);
-
- pthread_mutex_lock(&random_mutex);
-
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES * (rptr - state) + rand_type;
- if (n < BREAK_0) {
- (void)fprintf(stderr,
- "random: not enough state (%d bytes); ignored.\n", n);
- pthread_mutex_unlock(&random_mutex);
- return(0);
- }
- if (n < BREAK_1) {
- rand_type = TYPE_0;
- rand_deg = DEG_0;
- rand_sep = SEP_0;
- } else if (n < BREAK_2) {
- rand_type = TYPE_1;
- rand_deg = DEG_1;
- rand_sep = SEP_1;
- } else if (n < BREAK_3) {
- rand_type = TYPE_2;
- rand_deg = DEG_2;
- rand_sep = SEP_2;
- } else if (n < BREAK_4) {
- rand_type = TYPE_3;
- rand_deg = DEG_3;
- rand_sep = SEP_3;
- } else {
- rand_type = TYPE_4;
- rand_deg = DEG_4;
- rand_sep = SEP_4;
- }
- state = &(((long *)arg_state)[1]); /* first location */
- end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
- srandom_basic(seed);
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES*(rptr - state) + rand_type;
- pthread_mutex_unlock(&random_mutex);
- return(ostate);
-}
-
-/*
- * setstate:
- *
- * Restore the state from the given state array.
- *
- * Note: it is important that we also remember the locations of the pointers
- * in the current state information, and restore the locations of the pointers
- * from the old state information. This is done by multiplexing the pointer
- * location into the zeroeth word of the state information.
- *
- * Note that due to the order in which things are done, it is OK to call
- * setstate() with the same state as the current state.
- *
- * Returns a pointer to the old state information.
- */
-#ifdef setstate
-#undef setstate
-#endif
-char * setstate(char * arg_state)
-{
- register long *new_state = (long *)arg_state;
- register int type = new_state[0] % MAX_TYPES;
- register int rear = new_state[0] / MAX_TYPES;
- char *ostate = (char *)(&state[-1]);
-
- pthread_mutex_lock(&random_mutex);
-
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES * (rptr - state) + rand_type;
- switch(type) {
- case TYPE_0:
- case TYPE_1:
- case TYPE_2:
- case TYPE_3:
- case TYPE_4:
- rand_type = type;
- rand_deg = degrees[type];
- rand_sep = seps[type];
- break;
- default:
- (void)fprintf(stderr,
- "random: state info corrupted; not changed.\n");
- }
- state = &new_state[1];
- if (rand_type != TYPE_0) {
- rptr = &state[rear];
- fptr = &state[(rear + rand_sep) % rand_deg];
- }
- end_ptr = &state[rand_deg]; /* set end_ptr too */
-
- pthread_mutex_unlock(&random_mutex);
- return(ostate);
-}
-
diff --git a/mit-pthreads/stdlib/strtod.c b/mit-pthreads/stdlib/strtod.c
deleted file mode 100644
index 173ca1e4bdf..00000000000
--- a/mit-pthreads/stdlib/strtod.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
-** An alternative implemtation of "strtod()" that is both
-** simplier, and thread-safe.
-*/
-#include <pthread.h>
-#include <ctype.h>
-#include <math.h>
-
-#ifdef TEST
-# define strtod NewStrtod
-#include <stdio.h>
-#endif
-
-static double scaler10[] = {
- 1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
-};
-static double scaler1[] = {
- 1.0, 10.0, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9
-};
-static double pastpoint[] = {
- 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
- 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16, 1e-17, 1e-18, 1e-19,
- 1e-20, 1e-21, 1e-22, 1e-23, 1e-24, 1e-25, 1e-26, 1e-27, 1e-28, 1e-29,
- 1e-30, 1e-31, 1e-32, 1e-33, 1e-34, 1e-35, 1e-36, 1e-37, 1e-38, 1e-39,
- 1e-40, 1e-41, 1e-42, 1e-43, 1e-44, 1e-45, 1e-46, 1e-47, 1e-48, 1e-49,
- 1e-50, 1e-51, 1e-52, 1e-53, 1e-54, 1e-55, 1e-56, 1e-57, 1e-58, 1e-59,
-};
-
-#ifndef DBL_MAX
-#define DBL_MAX 1.7976931348623157e+308
-#endif
-
-double strtod(const char *zNum, char **pzEnd){
- double rResult = 0.0;
- int isNegative = 0;
-
- while( isspace(*zNum) ){
- zNum++;
- }
- if( *zNum=='-' ){
- zNum++;
- isNegative = 1;
- }else if( *zNum=='+' ){
- zNum++;
- }
- while( isdigit(*zNum) ){
- rResult = rResult*10.0 + (*zNum - '0');
- zNum++;
- }
- if( *zNum=='.' ){
- int n = 0;
- zNum++;
- while( isdigit(*zNum) ){
- if( n<sizeof(pastpoint)/sizeof(pastpoint[0]) ){
- rResult += pastpoint[n] * (*zNum - '0');
- n++;
- }
- zNum++;
- }
- }
- if( *zNum=='e' || *zNum=='E' ){
- int expVal = 0;
- int isNegExp = 0;
- const char *zExpStart = zNum;
- zNum++;
- if( *zNum=='-' ){
- isNegExp = 1;
- zNum++;
- }else if( *zNum=='+' ){
- zNum++;
- }
- if( !isdigit(*zNum) ){
- zNum = zExpStart;
- }else{
- double scaler = 1.0;
- while( isdigit(*zNum) ){
- expVal = expVal*10 + *zNum - '0';
- zNum++;
- }
- if( expVal >= 1000 ){
- if( isNegExp ){
- rResult = 0.0;
- }else{
- rResult = DBL_MAX;
- }
- goto done;
- }
- while( expVal >= 100 ){
- scaler *= 1.0e100;
- expVal -= 100;
- }
- scaler *= scaler10[expVal/10]*scaler1[expVal%10];
- if( isNegExp ){
- scaler = 1.0/scaler;
- }
- rResult *= scaler;
- }
-
- }
-
-done:
- if( pzEnd ){
- *pzEnd = (char *)zNum;
- }
- if( isNegative && rResult!=0.0 ){
- rResult = -rResult;
- }
- return rResult;
-}
-
-double atof(const char *nptr)
-{
- return (strtod(nptr, 0));
-}
-
-#ifdef TEST
-#undef strtod
-
-double strtod(const char*,char**);
-double NewStrtod(const char*,char**);
-
-int main(int argc, char **argv){
- int nTest = 0;
- int nFail = 0;
- int nBigFail = 0;
- char zBuf[1000];
-
- while( fgets(zBuf,sizeof(zBuf),stdin) ){
- double old, new;
- char *zTailOld, *zTailNew;
- int i;
-
- for(i=0; zBuf[i] && zBuf[i]!='\n'; i++){}
- zBuf[i] = 0;
-
-#if TEST==1
- printf("Input line: [%s]\n",zBuf);
- old = strtod(zBuf,&zTailOld);
- printf("value=%g\n",old);
- printf("Old: 0x%08x%08x tail=[%s]\n",
- ((int*)&old)[1], ((int*)&old)[0], zTailOld);
- new = NewStrtod(zBuf,&zTailNew);
- printf("value=%g\n",new);
- printf("New: 0x%08x%08x tail=[%s]\n\n",
- ((int*)&new)[1], ((int*)&new)[0], zTailNew);
-#else
- old = strtod(zBuf,&zTailOld);
- new = NewStrtod(zBuf,&zTailNew);
- nTest++;
- if( strcmp(zTailOld,zTailNew)
- || ((int*)&old)[0]!=((int*)&new)[0]
- || ((int*)&old)[1]!=((int*)&new)[1]
- ){
- int olda, oldb, newa, newb;
-
- nFail++;
- olda = ((int*)&old)[1];
- oldb = ((int*)&old)[0];
- newa = ((int*)&new)[1];
- newb = ((int*)&new)[0];
-
- if( olda!=newa || abs(oldb-newb)>2 ){
- nBigFail++;
- printf("******* Big failure \n");
- }
- printf("Input = [%s]\n",zBuf);
- printf("old: val=%g 0x%08x%08x tail=[%s]\n",
- old, olda, oldb, zTailOld);
- printf("new: val=%g 0x%08x%08x tail=[%s]\n\n",
- new, newa, newb, zTailNew);
- }
-#endif
- }
-
- printf("Out of %d tests, %d failures and %d big failurs\n",
- nTest,nFail, nBigFail);
-}
-#endif
diff --git a/mit-pthreads/stdlib/strtol.c b/mit-pthreads/stdlib/strtol.c
deleted file mode 100644
index 91be90cc94c..00000000000
--- a/mit-pthreads/stdlib/strtol.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <limits.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-
-
-/*
- * Convert a string to a long integer.
- *
- * Ignores `locale' stuff. Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
- */
-long
-strtol(nptr, endptr, base)
- const char *nptr;
- char **endptr;
- register int base;
-{
- register const char *s = nptr;
- register unsigned long acc;
- register int c;
- register unsigned long cutoff;
- register int neg = 0, any, cutlim;
-
- /*
- * Skip white space and pick up leading +/- sign if any.
- * If base is 0, allow 0x for hex and 0 for octal, else
- * assume decimal; if base is already 16, allow 0x.
- */
- do {
- c = *s++;
- } while (isspace(c));
- if (c == '-') {
- neg = 1;
- c = *s++;
- } else if (c == '+')
- c = *s++;
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
- c = s[1];
- s += 2;
- base = 16;
- }
- if (base == 0)
- base = c == '0' ? 8 : 10;
-
- /*
- * Compute the cutoff value between legal numbers and illegal
- * numbers. That is the largest legal value, divided by the
- * base. An input number that is greater than this value, if
- * followed by a legal input character, is too big. One that
- * is equal to this value may be valid or not; the limit
- * between valid and invalid numbers is then based on the last
- * digit. For instance, if the range for longs is
- * [-2147483648..2147483647] and the input base is 10,
- * cutoff will be set to 214748364 and cutlim to either
- * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
- * a value > 214748364, or equal but the next digit is > 7 (or 8),
- * the number is too big, and we will return a range error.
- *
- * Set any if any `digits' consumed; make it negative to indicate
- * overflow.
- */
- cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
- cutlim = cutoff % (unsigned long)base;
- cutoff /= (unsigned long)base;
- for (acc = 0, any = 0;; c = *s++) {
- if (isdigit(c))
- c -= '0';
- else if (isalpha(c))
- c -= isupper(c) ? 'A' - 10 : 'a' - 10;
- else
- break;
- if (c >= base)
- break;
- if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
- any = -1;
- else {
- any = 1;
- acc *= base;
- acc += c;
- }
- }
- if (any < 0) {
- acc = neg ? LONG_MIN : LONG_MAX;
- errno = ERANGE;
- } else if (neg)
- acc = -acc;
- if (endptr != 0)
- *endptr = (char *) (any ? s - 1 : nptr);
- return (acc);
-}
diff --git a/mit-pthreads/stdlib/strtoul.c b/mit-pthreads/stdlib/strtoul.c
deleted file mode 100644
index c6b6b01a0f2..00000000000
--- a/mit-pthreads/stdlib/strtoul.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 1990 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <limits.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/*
- * Convert a string to an unsigned long integer.
- *
- * Ignores `locale' stuff. Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
- */
-unsigned long
-strtoul(nptr, endptr, base)
- const char *nptr;
- char **endptr;
- register int base;
-{
- register const char *s = nptr;
- register unsigned long acc;
- register int c;
- register unsigned long cutoff;
- register int neg = 0, any, cutlim;
-
- /*
- * See strtol for comments as to the logic used.
- */
- do {
- c = *s++;
- } while (isspace(c));
- if (c == '-') {
- neg = 1;
- c = *s++;
- } else if (c == '+')
- c = *s++;
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
- c = s[1];
- s += 2;
- base = 16;
- }
- if (base == 0)
- base = c == '0' ? 8 : 10;
- cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
- cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
- for (acc = 0, any = 0;; c = *s++) {
- if (isdigit(c))
- c -= '0';
- else if (isalpha(c))
- c -= isupper(c) ? 'A' - 10 : 'a' - 10;
- else
- break;
- if (c >= base)
- break;
- if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
- any = -1;
- else {
- any = 1;
- acc *= base;
- acc += c;
- }
- }
- if (any < 0) {
- acc = ULONG_MAX;
- errno = ERANGE;
- } else if (neg)
- acc = -acc;
- if (endptr != 0)
- *endptr = (char *) (any ? s - 1 : nptr);
- return (acc);
-}
diff --git a/mit-pthreads/stdlib/system.c b/mit-pthreads/stdlib/system.c
deleted file mode 100644
index e7cc164fbc7..00000000000
--- a/mit-pthreads/stdlib/system.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)system.c 5.10 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <pthread/paths.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-
-extern char **environ;
-
-system(command)
- const char *command;
-{
- char *argp[] = {"sh", "-c", "*to be filled in*", NULL};
- void (*intsave)(), (*quitsave)(), (*signal())();
- sigset_t tmp_mask, old_mask;
- int pstat;
- pid_t pid;
-
- if (!command) /* just checking... */
- return(1);
-
- argp[2] = (char *) command;
- sigemptyset(&tmp_mask);
- sigaddset(&tmp_mask, SIGCHLD);
- pthread_sigmask(SIG_BLOCK, &tmp_mask, &old_mask);
- switch(pid = fork()) {
- case -1: /* error */
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
- return(-1);
- case 0: /* child */
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
- execve(_PATH_BSHELL, argp, environ);
- _exit(127);
- }
-
- intsave = pthread_signal(SIGINT, SIG_IGN);
- quitsave = pthread_signal(SIGQUIT, SIG_IGN);
- pid = waitpid(pid, (int *)&pstat, 0);
- (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL);
- (void)pthread_signal(SIGQUIT, quitsave);
- (void)pthread_signal(SIGINT, intsave);
- return(pid == -1 ? -1 : pstat);
-}
diff --git a/mit-pthreads/string/GNUmakefile.inc b/mit-pthreads/string/GNUmakefile.inc
deleted file mode 100755
index f3994d31479..00000000000
--- a/mit-pthreads/string/GNUmakefile.inc
+++ /dev/null
@@ -1,7 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# gen sources
-VPATH:= ${VPATH}:${srcdir}/string
-
-SRCS:= strtok.c $(SRCS)
diff --git a/mit-pthreads/string/Makefile.inc b/mit-pthreads/string/Makefile.inc
deleted file mode 100644
index 4a5536bac4a..00000000000
--- a/mit-pthreads/string/Makefile.inc
+++ /dev/null
@@ -1,8 +0,0 @@
-# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
-# $Id$
-
-# string sources
-.PATH: ${srcdir}/string
-
-SRCS+= strtok.c
-
diff --git a/mit-pthreads/string/strtok.c b/mit-pthreads/string/strtok.c
deleted file mode 100644
index 4c08dcc4d37..00000000000
--- a/mit-pthreads/string/strtok.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/*static char *sccsid = "from: @(#)strtok.c 5.8 (Berkeley) 2/24/91";*/
-static char *rcsid = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
-#include <pthread.h>
-#include <string.h>
-#include <stdlib.h>
-
-char *
-strtok(s, delim)
- register char *s;
- register const char *delim;
-{
- static pthread_mutex_t strtok_mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t strtok_key = -1;
- char **lasts;
-
- pthread_mutex_lock(&strtok_mutex);
- if (strtok_key < 0) {
- if (pthread_key_create(&strtok_key, free) < 0) {
- pthread_mutex_unlock(&strtok_mutex);
- return(NULL);
- }
- }
- pthread_mutex_unlock(&strtok_mutex);
- if ((lasts = pthread_getspecific(strtok_key)) == NULL) {
- if ((lasts = (char **)malloc(sizeof(char *))) == NULL) {
- return(NULL);
- }
- pthread_setspecific(strtok_key, lasts);
- }
-
- return(strtok_r(s, delim, lasts));
-}
-
-char *
-strtok_r(s, delim, lasts)
- register char *s;
- register const char *delim;
- register char **lasts;
-{
- register char *spanp;
- register int c, sc;
- char *tok;
-
-
- if (s == NULL && (s = *lasts) == NULL)
- return (NULL);
-
- /*
- * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
- */
-cont:
- c = *s++;
- for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
- if (c == sc)
- goto cont;
- }
-
- if (c == 0) { /* no non-delimiter characters */
- *lasts = NULL;
- return (NULL);
- }
- tok = s - 1;
-
- /*
- * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
- * Note that delim must have one NUL; we stop if we see that, too.
- */
- for (;;) {
- c = *s++;
- spanp = (char *)delim;
- do {
- if ((sc = *spanp++) == c) {
- if (c == 0)
- s = NULL;
- else
- s[-1] = 0;
- *lasts = s;
- return (tok);
- }
- } while (sc != 0);
- }
- /* NOTREACHED */
-}
diff --git a/mit-pthreads/tests/.cvsignore b/mit-pthreads/tests/.cvsignore
deleted file mode 100644
index f3c7a7c5da6..00000000000
--- a/mit-pthreads/tests/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
diff --git a/mit-pthreads/tests/Makefile.in b/mit-pthreads/tests/Makefile.in
deleted file mode 100644
index 6e01b6bffc3..00000000000
--- a/mit-pthreads/tests/Makefile.in
+++ /dev/null
@@ -1,164 +0,0 @@
-# === GNUmakefile ============================================================
-# Copyright (c) 1993 Chris Provenzano, proven@athena.mit.edu
-#
-# Description: This file is for creating the test programs for libpthread.a
-#
-# 1.00 93/08/03 proven
-# -Initial cut for pthreads.
-#
-
-CC = ../pgcc -notinstalled
-CPP = @CPP@
-srctop = @srctop@
-srcdir = @srctop@/tests
-VPATH = @srctop@/tests
-CDEBUGFLAGS = @CFLAGS@
-
-INCLUDES= -I../include -I.. -I$(srctop)/include
-CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(ADDL_CFLAGS) -DSRCDIR=\"$(srcdir)\"
-LIBS = -lm -lgcc -L../obj/ -lpthread
-#LIBS = -static
-
-# This list used to include test_select, but that test doesn't terminate.
-TESTS = test_create test_pthread_join test_switch test_sleep test_readdir \
- test_fork test_execve test_preemption test_preemption_float \
- test_sock_1 test_sock_2 test_stdio_1 test_pthread_mutex \
- test_pthread_cond_timedwait test_netdb test_pw test_cwd
-# This list used to include p_bench_semaphore, but the semaphore support isn't
-# defined for all targets (or used for any).
-BENCHMARKS = p_bench_read p_bench_mutex p_bench_yield \
- p_bench_getpid p_bench_pthread_create
-
-all : $(TESTS) $(BENCHMARKS)
-
-check : $(TESTS)
- set -e ; \
- for i in $(TESTS) ; do \
- echo Running test $$i ... ; \
- ./$$i ; \
- done
-
-# More flags
-ADDITIONALFLAGS = -DPTHREAD_INITIAL_PORT
-################################################################################
-#
-
-clean:
- rm -f *.o $(TESTS) $(BENCHMARKS) a.out core maketmp makeout
-
-depend:
- sed '/\#\#\# Dependencies/q' < Makefile > maketmp
- (for i in $(CSRC);do $(CPP) -M $$i;done) >> maketmp
- cp maketmp Makefile
-
-install:
-
-realclean: clean
- rm -f Makefile
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
-Makefile: Makefile.in
- (cd .. ; sh config.status)
-
-test_create : test_create.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_create test_create.o $(LIBS)
-
-test_pthread_join : test_pthread_join.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_pthread_join test_pthread_join.o $(LIBS)
-
-test_switch : test_switch.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_switch test_switch.o $(LIBS)
-
-test_sleep : test_sleep.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_sleep test_sleep.o $(LIBS)
-
-test_readdir : test_readdir.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_readdir test_readdir.o $(LIBS)
-
-test_fork : test_fork.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_fork test_fork.o $(LIBS)
-
-test_execve : test_execve.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_execve test_execve.o $(LIBS)
-
-test_preemption : test_preemption.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_preemption test_preemption.o $(LIBS)
-
-test_preemption_float : test_preemption_float.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_preemption_float test_preemption_float.o $(LIBS)
-
-test_stdio_1 : test_stdio_1.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_stdio_1 test_stdio_1.o $(LIBS)
-
-test_sock_1 : test_sock_1.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_sock_1 test_sock_1.o $(LIBS)
-
-test_sock_2 : test_sock_2a test_sock_2.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_sock_2 test_sock_2.o $(LIBS)
-
-test_sock_2a : test_sock_2a.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_sock_2a test_sock_2a.o $(LIBS)
-
-test_pthread_mutex : test_pthread_mutex.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_pthread_mutex test_pthread_mutex.o $(LIBS)
-
-test_pthread_cond_timedwait : test_pthread_cond_timedwait.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_pthread_cond_timedwait test_pthread_cond_timedwait.o $(LIBS)
-
-test_netdb : test_netdb.o ../libpthread.a
- $(CC) $(CFLAGS) -o test_netdb test_netdb.o $(LIBS)
-
-test_select : test_select.o ../obj/libpthread.a
- $(CC) $(CFLAGS) -o test_select test_select.o $(LIBS)
-
-test_pw : test_pw.o ../obj/libpthread.a
- $(CC) $(CFLAGS) -o test_pw test_pw.o $(LIBS)
-
-test_cwd : test_cwd.o ../obj/libpthread.a
- $(CC) $(CFLAGS) -o test_cwd test_cwd.o $(LIBS)
-
-p_bench_read : p_bench_read.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_read p_bench_read.o $(LIBS)
-
-p_bench_semaphore : p_bench_semaphore.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_semaphore p_bench_semaphore.o $(LIBS)
-
-p_bench_mutex : p_bench_mutex.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_mutex p_bench_mutex.o $(LIBS)
-
-p_bench_yield : p_bench_yield.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_yield p_bench_yield.o $(LIBS)
-
-p_bench_getpid : p_bench_getpid.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_getpid p_bench_getpid.o $(LIBS)
-
-p_bench_pthread_create : p_bench_pthread_create.o ../libpthread.a
- $(CC) $(CFLAGS) -o p_bench_pthread_create p_bench_pthread_create.o $(LIBS)
-
-test_create.o : test_create.c
-test_pthread_join.o : test_pthread_join.c
-test_switch.o : test_switch.c
-test_sleep.o : test_sleep.c
-test_readdir.o : test_readdir.c
-test_fork.o : test_fork.c
-test_execve.o : test_execve.c
-test_preemption.o : test_preemption.c
-test_preemption_float.o : test_preemption_float.c
-test_sock_1.o : test_sock_1.c
-test_sock_2.o : test_sock_2.c
-test_sock_3.o : test_sock_3.c
-test_stdio_1.o : test_stdio_1.c
-test_pthread_mutex.o : test_pthread_mutex.c
-test_pthread_cond_timedwait.o : test_pthread_cond_timedwait.c
-p_bench_read.o : p_bench_read.c
-p_bench_semaphore.o : p_bench_semaphore.c
-p_bench_mutex.o : p_bench_mutex.c
-p_bench_yield.o : p_bench_yield.c
-p_bench_getpid.o : p_bench_getpid.c
-p_bench_pthread_create.o : p_bench_pthread_create.c
-
-################################################################################
-### Do not remove the following line. It is for depend #########################
-### Dependencies:
diff --git a/mit-pthreads/tests/README b/mit-pthreads/tests/README
deleted file mode 100755
index bb4a3e7ce01..00000000000
--- a/mit-pthreads/tests/README
+++ /dev/null
@@ -1,26 +0,0 @@
-This directory contains a few test and benchmark programs that I've
-developed to help me test the consistancy of the libpthread.a.
-
-TEST
-----------------------
-test_create Tests the pthread_create() routine. The stack addresses
- should be very different (ie the upper values of the
- address should be different) and the arg should be
- 0xdeadbeaf.
-
-test_switch A nondeterministic test. It should show context switching,
- by displaying different letters.
-
-test_sleep Timing this test should result in a time of about 20 seconds.
- It should sleep for 10 seconds and then print ba 10 times
- at the rate of about once a second.
-
-p_bench_* Benchmarks for various routines.
-
-------------------------------------------------------------------------------
-Copyright (c) 1994 Chris Provenzano. All rights reserved.
-This product includes software developed by the Univeristy of California,
-Berkeley and its contributors.
-
-For further licencing and distribution restrictions see the file COPYRIGHT
-included in the parent directory.
diff --git a/mit-pthreads/tests/bench_fcntl.c b/mit-pthreads/tests/bench_fcntl.c
deleted file mode 100644
index 046046adda4..00000000000
--- a/mit-pthreads/tests/bench_fcntl.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* ==== bench_read.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark reads of /dev/null. Gives a good aprox. of
- * syscall times.
- *
- * 1.00 93/08/01 proven
- * -Started coding this file.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define OK 0
-#define NOTOK -1
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("getopt [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- int count = 1000000;
- int debug = 0;
- int flags;
- int fd;
- int i;
-
- char word[8192];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- if ((fd = open("/dev/zero", O_RDONLY)) < OK) {
- printf("Error: open\n");
- exit(0);
- }
-
- if (gettimeofday(&starttime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
- for (i = 0; i < count; i++) {
- if ((flags = fcntl(0, F_GETFL)) < 0) {
- perror("fcntl 1st GETFL");
- }
- }
- if (gettimeofday(&endtime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
-
- printf("%d fcntls of /dev/null took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-}
diff --git a/mit-pthreads/tests/bench_pipe.c b/mit-pthreads/tests/bench_pipe.c
deleted file mode 100644
index 8555cf37f67..00000000000
--- a/mit-pthreads/tests/bench_pipe.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* ==== bench_pipe.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark reads of /dev/null. Gives a good aprox. of
- * syscall times.
- *
- * 1.00 93/08/01 proven
- * -Started coding this file.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("bench_pipe [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- char buf[1];
- int count = 1000;
- int debug = 0;
- int fd0[2];
- int fd1[2];
- int i;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- if ((pipe(fd0) < OK) || (pipe(fd1) < OK)) {
- printf("Error: pipe\n");
- exit(0);
- }
-
- switch (fork()) {
- case NOTOK:
- printf("Error: fork\n");
- exit(0);
- case OK: /* Child */
- for (i = 0; i < count; i++) {
- if (read(fd1[0], buf, 1) < OK) {
- printf("Error: child read\n");
- exit(0);
- }
- if (write(fd0[1], buf, 1) < OK) {
- printf("Error: child write\n");
- exit(0);
- }
- }
- exit(0);
- break;
- default:
- break;
- }
-
- if (gettimeofday(&starttime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
- count --;
- if (write(fd1[1], buf, 1) < OK) {
- perror("first parent write");
- exit(0);
- }
- for (i = 0; i < count; i++) {
- if (read(fd0[0], buf, 1) < OK) {
- printf("Error: parent read\n");
- exit(0);
- }
- if (write(fd1[1], buf, 1) < OK) {
- printf("Error: parent write\n");
- exit(0);
- }
- }
- if (gettimeofday(&endtime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
-
- printf("%d ping pong tests took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-}
diff --git a/mit-pthreads/tests/bench_read.c b/mit-pthreads/tests/bench_read.c
deleted file mode 100644
index 28c8469e270..00000000000
--- a/mit-pthreads/tests/bench_read.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* ==== bench_read.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark reads of /dev/null. Gives a good aprox. of
- * syscall times.
- *
- * 1.00 93/08/01 proven
- * -Started coding this file.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define OK 0
-#define NOTOK -1
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("getopt [-d?] [-c count] [-s size]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- int count = 1000000;
- int debug = 0;
- int size = 1;
- int fd;
- int i;
-
- char word[8192];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- while ((word[0] = getopt(argc, argv, "s:c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case 's':
- if ((size = atoi(optarg)) > 8192) {
- size = 8192;
- }
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- if ((fd = open("/netbsd", O_RDONLY)) < OK) {
- printf("Error: open\n");
- exit(0);
- }
-
- if (gettimeofday(&starttime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
- for (i = 0; i < count; i++) {
- if (read(fd, word, size) < OK) {
- printf("Error: read\n");
- exit(0);
- }
- }
- if (gettimeofday(&endtime, NULL)) {
- printf("Error: gettimeofday\n");
- exit(0);
- }
-
- printf("%d reads of /netbsd took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-}
diff --git a/mit-pthreads/tests/p_bench_getpid.c b/mit-pthreads/tests/p_bench_getpid.c
deleted file mode 100644
index d972d075c1d..00000000000
--- a/mit-pthreads/tests/p_bench_getpid.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ==== p_bench_getpid.c =================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark mutex lock and unlock times
- *
- * 1.00 93/11/08 proven
- * -Started coding this file.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("p_bench_getpid [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- pthread_mutex_t lock;
- pid_t process_id;
- int count = 1000000;
- int debug = 0;
- int i;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
- for (i = 0; i < count; i++) {
- process_id = getpid();
- }
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d getpid calls took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/p_bench_mutex.c b/mit-pthreads/tests/p_bench_mutex.c
deleted file mode 100644
index e3179f08072..00000000000
--- a/mit-pthreads/tests/p_bench_mutex.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ==== p_bench_mutex.c =================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark mutex lock and unlock times
- *
- * 1.00 93/11/08 proven
- * -Started coding this file.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("getopt [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- pthread_mutex_t lock;
- int count = 1000000;
- int debug = 0;
- int i;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- pthread_mutex_init(&lock, NULL);
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
- for (i = 0; i < count; i++) {
- pthread_mutex_lock(&lock);
- pthread_mutex_unlock(&lock);
- }
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d mutex locks/unlocks no contention took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/p_bench_pthread_create.c b/mit-pthreads/tests/p_bench_pthread_create.c
deleted file mode 100644
index b31b680c665..00000000000
--- a/mit-pthreads/tests/p_bench_pthread_create.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ==== p_bench_pthread_create.c =============================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark mutex lock and unlock times
- *
- * 1.00 93/11/08 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-
-extern pthread_attr_t pthread_attr_default;
-
-/* ==========================================================================
- * new_thread();
- */
-void * new_thread(void * arg)
-{
- PANIC();
-}
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("p_bench_getpid [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- pthread_mutex_t lock;
- pthread_t thread_id;
- int count = 10000;
- int debug = 0;
- int i;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
- /* Shut timer off */
- machdep_unset_thread_timer(NULL);
- pthread_attr_default.stackaddr_attr = &word;
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
- for (i = 0; i < count; i++) {
- if (pthread_create(&thread_id, & pthread_attr_default, new_thread, NULL)) {
- printf("Bad pthread create routine\n");
- exit(1);
- }
- }
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d getpid calls took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/p_bench_read.c b/mit-pthreads/tests/p_bench_read.c
deleted file mode 100644
index 52a6aca7706..00000000000
--- a/mit-pthreads/tests/p_bench_read.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* ==== p_bench_read.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark reads of /dev/null. Gives a good aprox. of
- * syscall times.
- *
- * 1.00 93/08/01 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("p_bench_read [-d?] [-c count] [-s size] [-f file]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- char *infile = "/dev/null";
- int count = 1000000;
- int debug = 0;
- int size = 1;
- int fd;
- int i;
-
- char word[16384], *word_ptr;
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
-
- while ((word[0] = getopt(argc, argv, "c:df:s:?")) != (char)EOF) {
- switch (word[0]) {
- case 'c':
- count = atoi(optarg);
- break;
- case 'd':
- debug++;
- break;
- case 'f':
- infile = optarg;
- break;
- case 's':
- if ((size = atoi(optarg)) > 8192) {
- size = 8192;
- }
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- /* Align buffer boundary to a page boundary */
- word_ptr = (char *)(((size_t) word + 4095) & ~4095);
-
- if ((fd = open(infile, O_RDONLY)) < OK) {
- perror ("open");
- return 1;
- }
-
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- for (i = 0; i < count; i++) {
- if (read(fd, word_ptr, size) < OK) {
- printf("Error: read\n");
- exit(0);
- }
- }
-
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d reads of %s took %d usecs.\n", count, infile,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/p_bench_semaphore.c b/mit-pthreads/tests/p_bench_semaphore.c
deleted file mode 100644
index b3bce340b95..00000000000
--- a/mit-pthreads/tests/p_bench_semaphore.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* ==== p_bench_semaphore.c =================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark semaphore Test and Set/ CLear times
- *
- * 1.00 93/11/08 proven
- * -Started coding this file.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("getopt [-d?] [-c count]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- semaphore lock = SEMAPHORE_CLEAR;
- semaphore *lock_addr;
- int count = 1000000;
- int debug = 0;
- int i;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
-
- while ((word[0] = getopt(argc, argv, "c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- lock_addr = &lock;
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
- for (i = 0; i < count; i++) {
- if (SEMAPHORE_TEST_AND_SET(lock_addr)) {
- printf("Semaphore already locked error\n");
- return 1;
- }
- SEMAPHORE_RESET(lock_addr);
- }
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d locks/unlocks of a semaphore took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/p_bench_yield.c b/mit-pthreads/tests/p_bench_yield.c
deleted file mode 100644
index bb6d86be09e..00000000000
--- a/mit-pthreads/tests/p_bench_yield.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* ==== p_bench_mutex.c =================================================
- * Copyright (c) 1993-1995 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Benchmark mutex lock and unlock times
- *
- * 1.00 93/11/08 proven
- * -Started coding this file.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-
-#define OK 0
-#define NOTOK -1
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("p_bench_yield [-d?] \\\n");
- printf("\t[-c count] \\\n");
- printf("\t[-C thread count] \\\n");
- printf("\t[-O optimization level]\n");
- errno = 0;
-}
-
-void *yield(void * arg)
-{
- int i, * count;
-
- count = (int *)arg;
- for (i = 0; i < *count; i++) {
- pthread_yield();
- }
- return(NULL);
-}
-
-main(int argc, char **argv)
-{
- struct timeval starttime, endtime;
- pthread_mutex_t lock;
- pthread_attr_t attr;
- pthread_t thread_id;
- int thread_count = 1;
- int optimization = 0;
- int count = 1000000;
- int i, debug = 0;
-
- char word[256];
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- pthread_init();
-
- while ((word[0] = getopt(argc, argv, "C:O:c:d?")) != (char)EOF) {
- switch (word[0]) {
- case 'C':
- thread_count = atoi(optarg);
- break;
- case 'O':
- optimization = atoi(optarg);
- break;
- case 'c':
- count = atoi(optarg);
- break;
- case 'd':
- debug++;
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- pthread_attr_init(&attr);
- if (optimization > 0) {
- pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
- }
- if (optimization > 1) {
- pthread_attr_setfloatstate(&attr, PTHREAD_NOFLOAT);
- }
-
- pthread_mutex_init(&lock, NULL);
- if (gettimeofday(&starttime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
- for (i = 1; i < thread_count; i++) {
- if (pthread_create(&thread_id, &attr, yield, &count)) {
- perror ("pthread_create");
- return 1;
- }
- if (pthread_detach(thread_id)) {
- perror ("pthread_detach");
- return 1;
- }
- }
- if (pthread_create(&thread_id, &attr, yield, &count)) {
- perror ("pthread_create");
- return 1;
- }
- if (pthread_join(thread_id, NULL)) {
- perror ("pthread_join");
- return 1;
- }
- if (gettimeofday(&endtime, NULL)) {
- perror ("gettimeofday");
- return 1;
- }
-
- printf("%d pthread_yields took %d usecs.\n", count,
- (endtime.tv_sec - starttime.tv_sec) * 1000000 +
- (endtime.tv_usec - starttime.tv_usec));
-
- return 0;
-}
diff --git a/mit-pthreads/tests/test_create.c b/mit-pthreads/tests/test_create.c
deleted file mode 100644
index 2d82db07c5f..00000000000
--- a/mit-pthreads/tests/test_create.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ==== test_create.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_create() and pthread_exit() calls.
- *
- * 1.00 93/08/03 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL
-#include <pthread.h>
-#include <stdio.h>
-
-void* new_thread(void* arg)
-{
- int i;
-
- printf("New thread was passed arg address %x\n", arg);
- printf("New thread stack at %x\n", &i);
- return(NULL);
- PANIC();
-}
-
-main()
-{
- pthread_t thread;
- int i;
-
- printf("Original thread stack at %x\n", &i);
- if (pthread_create(&thread, NULL, new_thread, (void *)0xdeadbeef)) {
- printf("Error: creating new thread\n");
- }
- pthread_exit(NULL);
- PANIC();
-}
diff --git a/mit-pthreads/tests/test_cwd.c b/mit-pthreads/tests/test_cwd.c
deleted file mode 100644
index 979c173d5fc..00000000000
--- a/mit-pthreads/tests/test_cwd.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <stdio.h>
-
-main(int argc, char **argv)
-{
- char wd[1024], *getcwd(), *getwd();
-
- pthread_init();
- printf("getcwd => %s\n", getcwd(wd, 1024));
- printf("getwd => %s\n", getwd(wd));
- exit(0);
-}
diff --git a/mit-pthreads/tests/test_execve.c b/mit-pthreads/tests/test_execve.c
deleted file mode 100644
index f7988457df9..00000000000
--- a/mit-pthreads/tests/test_execve.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ==== test_execve.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test execve() and dup2() calls.
- *
- * 1.00 94/04/29 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL
-#include <pthread.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-extern char **environ;
-char *argv[] = {
- "/bin/echo",
- "This message should be displayed after the execve system call",
- NULL
-};
-
-char * should_succeed = "This line should be displayed\n";
-char * should_fail = "Error: This line should NOT be displayed\n";
-
-main()
-{
- pthread_t thread;
- int fd;
-
- pthread_init();
-
- printf("This is the first message\n");
- if (isatty(1)) {
- if ((fd = open(ttyname(1), O_RDWR)) < OK) {
- printf("Error: opening tty\n");
- exit(1);
- }
- } else {
- printf("Error: stdout not a tty\n");
- exit(1);
- }
-
- printf("This output is necessary to set the stdout fd to NONBLOCKING\n");
-
- /* do a dup2 */
- dup2(fd, 1);
- write(1, should_succeed, (size_t)strlen(should_succeed));
- machdep_sys_write(1, should_fail, strlen(should_fail));
-
- if (execve(argv[0], argv, environ) < OK) {
- printf("Error: execve\n");
- exit(1);
- }
- PANIC();
-}
diff --git a/mit-pthreads/tests/test_fcntl.c b/mit-pthreads/tests/test_fcntl.c
deleted file mode 100644
index 60bc77ce464..00000000000
--- a/mit-pthreads/tests/test_fcntl.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <stdio.h>
-#include <fcntl.h>
-
-main()
-{
- int flags, child;
-
- if ((flags = fcntl(0, F_GETFL)) < 0) {
- perror("fcntl 1st GETFL");
- }
- printf ("flags = %x\n", flags);
-
- switch(child = fork()) {
- case -1:
- printf("error during fork\n");
- break;
- case 0: /* child */
- execlp("test_create", "test_create", NULL);
- break;
- default: /* parent */
- wait(NULL);
- break;
- }
-
- while(1){
- if ((flags = fcntl(0, F_GETFL)) < 0) {
- perror("fcntl parent GETFL");
- }
- printf ("parent %d flags = %x\n", child, flags);
- sleep(1);
- }
-}
diff --git a/mit-pthreads/tests/test_fork.c b/mit-pthreads/tests/test_fork.c
deleted file mode 100644
index 4c2125e678a..00000000000
--- a/mit-pthreads/tests/test_fork.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/* ==== test_fork.c ============================================================
- * Copyright (c) 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test fork() and dup2() calls.
- *
- * 1.00 94/04/29 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL
-#include <pthread.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-main()
-{
- pthread_t thread;
- int flags, pid;
-
- pthread_init();
-
- if (((flags = machdep_sys_fcntl(1, F_GETFL, NULL)) >= OK) &&
- (flags & __FD_NONBLOCK | O_NDELAY)) {
- machdep_sys_fcntl(1, F_SETFL, flags & (~__FD_NONBLOCK | O_NDELAY));
- }
- printf("parent process %d\n", getpid());
-
- switch(pid = fork()) {
- case OK:
- exit(OK);
- break;
- case NOTOK:
- printf("fork() FAILED\n");
- exit(2);
- break;
- default:
- if ((flags = machdep_sys_fcntl(1, F_GETFL, NULL)) >= OK) {
- if (flags & (__FD_NONBLOCK | O_NDELAY)) {
- printf("fd flags not set to BLOCKING ERROR\n");
- printf("test_fork FAILED\n");
- exit(1);
- break;
- }
- printf("The stdout fd was set to BLOCKING\n");
- printf("child process %d\n", pid);
- flags = machdep_sys_fcntl(1, F_GETFL, NULL);
- if (flags & (__FD_NONBLOCK | O_NDELAY)) {
- printf("The stdout fd was reset to O_NDELAY\n");
- } else {
- printf("Error: the stdout fd was not reset\n");
- printf("test_fork FAILED\n");
- exit(1);
- }
- }
- break;
- }
-
- printf("test_fork PASSED\n");
- pthread_exit(NULL);
-}
diff --git a/mit-pthreads/tests/test_netdb.c b/mit-pthreads/tests/test_netdb.c
deleted file mode 100644
index a944579237f..00000000000
--- a/mit-pthreads/tests/test_netdb.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* ==== test_netdb.c =========================================================
- * Copyright (c) 1995 by Greg Hudson, ghudson@.mit.edu
- *
- * Description : Test netdb calls.
- *
- * 1.00 95/01/05 ghudson
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL /* Needed for OK and NOTOK defines */
-#include <pthread.h>
-#include <string.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <errno.h>
-
-int debug = 0;
-
-static int test_serv()
-{
- struct servent *serv;
- char answer[1024];
-
- if (serv = getservbyname("telnet", "tcp"))
- printf("getservbyname -> port %d\n", ntohs(serv->s_port));
- else
- printf("getservbyname -> NULL (bad)\n");
-
- if (serv = getservbyname_r("telnet", "tcp", serv, answer, 1024))
- printf("getservbyname_r -> port %d\n", ntohs(serv->s_port));
- else
- printf("getservbyname_r -> NULL (bad)\n");
- return(OK);
-}
-
-static int test_host()
-{
- struct hostent *host;
- struct in_addr addr;
- char answer[1024];
- int error;
-
- if (host = gethostbyname("maze.mit.edu")) {
- memcpy(&addr, host->h_addr, sizeof(addr));
- printf("gethostbyname -> %s\n", inet_ntoa(addr));
- } else {
- printf("gethostbyname -> NULL (bad)\n");
- host = (struct hostent *)answer;
- }
-
- if (host = gethostbyname_r("maze.mit.edu", host, answer, 1024, &error)) {
- memcpy(&addr, host->h_addr, sizeof(addr));
- printf("gethostbyname_r -> %s\n", inet_ntoa(addr));
- } else {
- printf("gethostbyname_r -> NULL (bad)\n");
- }
- return(OK);
-}
-
-static int test_localhost()
-{
- struct hostent *host;
-
- if (host = gethostbyname("127.0.0.1")) {
- return(OK);
- }
- return(NOTOK);
-}
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("test_netdb [-d?]\n");
- errno = 0;
-}
-
-main(int argc, char **argv)
-{
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
- char ch;
-
- while ((ch = getopt(argc, argv, "d?")) != (char)EOF) {
- switch (ch) {
- case 'd':
- debug++;
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
- }
-
- printf("test_netdb START\n");
-
- if (test_serv() || test_localhost() || test_host()) {
- printf("test_netdb FAILED\n");
- exit(1);
- }
-
- printf("test_netdb PASSED\n");
- exit(0);
-}
diff --git a/mit-pthreads/tests/test_pause.c b/mit-pthreads/tests/test_pause.c
deleted file mode 100644
index 46c5080e43e..00000000000
--- a/mit-pthreads/tests/test_pause.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <stdio.h>
-#include <signal.h>
-
-foo(int sig)
-{
- return;
-}
-
-main()
-{
- sigset_t all;
-
- signal (1, foo);
- sigfillset(&all);
- sigprocmask(SIG_BLOCK, &all, NULL);
- printf("Begin pause\n");
- pause();
- printf("Done pause\n");
-}
diff --git a/mit-pthreads/tests/test_preemption.c b/mit-pthreads/tests/test_preemption.c
deleted file mode 100644
index 9181c127fe4..00000000000
--- a/mit-pthreads/tests/test_preemption.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* ==== test_pthread_cond.c =========================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_cond(). Run this after test_create()
- *
- * 1.23 94/05/04 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdio.h>
-
-void* new_thread(void * new_buf)
-{
- int i;
-
- for (i = 0; i < 10; i++) {
- pthread_yield();
- }
- printf("test_preemption PASSED\n");
- exit(0);
-}
-
-main()
-{
- pthread_t thread;
- int error;
-
- printf("test_preemption START\n");
-
- if (pthread_create(&thread, NULL, new_thread, NULL)) {
- printf("pthread_create failed\n");
- exit(2);
- }
-
- while(1);
- exit(1);
-}
diff --git a/mit-pthreads/tests/test_preemption_float.c b/mit-pthreads/tests/test_preemption_float.c
deleted file mode 100644
index e12192044c6..00000000000
--- a/mit-pthreads/tests/test_preemption_float.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Test to see if floating point state is being properly maintained
- for each thread. Different threads doing floating point operations
- simultaneously should not interfere with one another. This
- includes operations that might change some FPU flags, such as
- rounding modes, at least implicitly. */
-
-#include <pthread.h>
-#include <math.h>
-#include <stdio.h>
-
-int limit = 2;
-int float_passed = 0;
-int float_failed = 1;
-
-void *log_loop (void *x) {
- int i;
- double d, d1, d2;
- /* sleep (1); */
- for (i = 0; i < limit; i++) {
- d = 42.0;
- d = log (exp (d));
- d = (d + 39.0) / d;
- if (i == 0)
- d1 = d;
- else {
- d2 = d;
- d = sin(d);
- /* if (d2 != d1) { */
- if (memcmp (&d2, &d1, 8)) {
- pthread_exit(&float_failed);
- }
- }
- }
- pthread_exit(&float_passed);
-}
-
-void *trig_loop (void *x) {
- int i;
- double d, d1, d2;
- /* sleep (1); */
- for (i = 0; i < limit; i++) {
- d = 35.0;
- d *= M_PI;
- d /= M_LN2;
- d = sin (d);
- d = cos (1 / d);
- if (i == 0)
- d1 = d;
- else {
- d2 = d;
- d = sin(d);
- /* if (d2 != d1) { */
- if (memcmp (&d2, &d1, 8)) {
- pthread_exit(&float_failed);
- }
- }
- }
- pthread_exit(&float_passed);
-}
-
-#define N 10
-int main () {
- int i;
- pthread_t thread[2];
- pthread_attr_t attr;
- int *x, *y;
-
- pthread_init ();
- pthread_attr_init(&attr);
- pthread_attr_setfloatstate(&attr, PTHREAD_NOFLOAT);
-
- while(limit < 100000) {
- pthread_create (&thread[0], &attr, trig_loop, 0);
- pthread_create (&thread[1], &attr, log_loop, 0);
- pthread_join(thread[0], (void **) &x);
- pthread_join(thread[1], (void **) &y);
- if ((*x == float_failed) || (*y == float_failed)) {
- limit *= 4;
- break;
- }
- limit *= 4;
- }
- if ((*x == float_passed) && (*y == float_passed)) {
- printf("test_preemption_float INDETERMINATE\n");
- return(0);
- }
- pthread_create (&thread[0], NULL, trig_loop, 0);
- pthread_create (&thread[1], NULL, log_loop, 0);
- pthread_join(thread[0], (void **) &x);
- pthread_join(thread[1], (void **) &y);
-
- if ((*x == float_failed) || (*y == float_failed)) {
- printf("test_preemption_float FAILED\n");
- return(1);
- }
- printf("test_preemption_float PASSED\n");
- return(0);
-}
diff --git a/mit-pthreads/tests/test_pthread_cond_timedwait.c b/mit-pthreads/tests/test_pthread_cond_timedwait.c
deleted file mode 100644
index fe21408f11e..00000000000
--- a/mit-pthreads/tests/test_pthread_cond_timedwait.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* ==== test_pthread_cond.c =========================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_cond(). Run this after test_create()
- *
- * 1.23 94/05/04 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-
-#ifndef ETIME
-#define ETIME ETIMEDOUT
-#endif
-
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-
-void* thread_1(void * new_buf)
-{
- pthread_mutex_lock(&mutex);
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- pthread_exit(NULL);
-}
-
-void* thread_2(void * new_buf)
-{
- sleep(1);
- pthread_mutex_lock(&mutex);
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- pthread_exit(NULL);
-}
-
-main()
-{
- struct timespec abstime = { 0, 0 };
- struct timeval curtime;
- pthread_t thread;
- int error;
-
- pthread_init();
- printf("pthread_cond_timedwait START\n");
-
- pthread_mutex_lock(&mutex);
- gettimeofday(&curtime, NULL);
- abstime.tv_sec = curtime.tv_sec + 5;
-
- /* Test a condition timeout */
- if (pthread_cond_timedwait(&cond, &mutex, &abstime) != ETIME) {
- printf("pthread_cond_timedwait failed to timeout\n");
- printf("pthread_cond_timedwait FAILED\n");
- pthread_mutex_unlock(&mutex);
- exit(1);
- }
- printf("Got first timeout ok\n"); /* Added by monty */
- /* Test a normal condition signal */
- if (pthread_create(&thread, NULL, thread_1, NULL)) {
- printf("pthread_create failed\n");
- exit(2);
- }
-
- abstime.tv_sec = curtime.tv_sec + 10;
- if (pthread_cond_timedwait(&cond, &mutex, &abstime)) {
- printf("pthread_cond_timedwait #1 timedout\n");
- printf("pthread_cond_timedwait FAILED\n");
- pthread_mutex_unlock(&mutex);
- exit(1);
- }
-
- /* Test a normal condition signal after a sleep */
- if (pthread_create(&thread, NULL, thread_2, NULL)) {
- printf("pthread_create failed\n");
- exit(2);
- }
-
- pthread_yield();
-
- abstime.tv_sec = curtime.tv_sec + 10;
- if (pthread_cond_timedwait(&cond, &mutex, &abstime)) {
- printf("pthread_cond_timedwait #2 timedout\n");
- printf("pthread_cond_timedwait FAILED\n");
- pthread_mutex_unlock(&mutex);
- exit(1);
- }
-
- printf("pthread_cond_timedwait PASSED\n");
- pthread_mutex_unlock(&mutex);
- exit(0);
-}
diff --git a/mit-pthreads/tests/test_pthread_join.c b/mit-pthreads/tests/test_pthread_join.c
deleted file mode 100644
index fd2ec6a78b2..00000000000
--- a/mit-pthreads/tests/test_pthread_join.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ==== test_pthread_join.c =================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_join(). Run this after test_create()
- *
- * 1.23 94/05/04 proven
- * -Started coding this file.
- */
-
-#define PTHREAD_KERNEL
-#include <pthread.h>
-#include <stdio.h>
-
-/* This thread yields so the creator has a live thread to wait on */
-void* new_thread_1(void * new_buf)
-{
- int i;
-
- sprintf((char *)new_buf, "New thread %%d stack at %x\n", &i);
- pthread_yield();
- return(new_buf);
- PANIC();
-}
-
-/* This thread doesn't yield so the creator has a dead thread to wait on */
-void* new_thread_2(void * new_buf)
-{
- int i;
-
- sprintf((char *)new_buf, "New thread %%d stack at %x\n", &i);
- return(new_buf);
- PANIC();
-}
-
-main()
-{
- char buf[256], *status;
- pthread_t thread;
- int debug = 1;
- int i = 0;
-
- pthread_init();
-
- printf("Original thread stack at %x\n", &i);
- if (pthread_create(&thread, NULL, new_thread_1, (void *)buf) == OK) {
- if (pthread_join(thread, (void **)(&status)) == OK) {
- if (debug) { printf(status, ++i); }
- } else {
- printf("ERROR: Joining with new thread #1.\n");
- printf("FAILED: test_pthread_join\n");
- exit(1);
- }
- } else {
- printf("ERROR: Creating new thread #1\n");
- printf("FAILED: test_pthread_join\n");
- exit(2);
- }
-
-
- /* Now have the created thread finishing before the join. */
- if (pthread_create(&thread, NULL, new_thread_2, (void *)buf) == OK){
- pthread_yield();
- if (pthread_join(thread, (void **)(&status)) == OK) {
- if (debug) { printf(status, ++i); }
- } else {
- printf("ERROR: Joining with new thread #2.\n");
- printf("FAILED: test_pthread_join\n");
- exit(1);
- }
- } else {
- printf("ERROR: Creating new thread #2\n");
- printf("FAILED: test_pthread_join\n");
- exit(2);
- }
- printf("test_pthread_join PASSED\n");
- pthread_exit(NULL);
-}
-
diff --git a/mit-pthreads/tests/test_pthread_mutex.c b/mit-pthreads/tests/test_pthread_mutex.c
deleted file mode 100644
index 2fb0574f5cb..00000000000
--- a/mit-pthreads/tests/test_pthread_mutex.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/* ==== test_pthread_cond.c =========================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_cond(). Run this after test_create()
- *
- * 1.23 94/05/04 proven
- * -Started coding this file.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-
-#define OK 0
-#define NOTOK -1
-
-int contention_variable;
-
-void * thread_contention(void * arg)
-{
- pthread_mutex_t * mutex = arg;
-
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- pthread_exit(NULL);
- }
-
- if (contention_variable != 1) {
- printf("contention_variable != 1 ERROR\n");
- pthread_exit(NULL);
- }
- contention_variable = 2;
-
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- pthread_exit(NULL);
- }
- pthread_exit(NULL);
-}
-
-int test_contention_lock(pthread_mutex_t * mutex)
-{
- pthread_t thread;
-
- printf("test_contention_lock()\n");
-
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- return(NOTOK);
- }
- contention_variable = 0;
-
- if (pthread_create(&thread, NULL, thread_contention, mutex)) {
- printf("pthread_create() FAILED\n");
- exit(2);
- }
-
- pthread_yield();
-
- contention_variable = 1;
-
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
-
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- return(NOTOK);
- }
-
- if (contention_variable != 2) {
- printf("contention_variable != 2 ERROR\n");
- return(NOTOK);
- }
-
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
-
- return(OK);
-}
-
-int test_nocontention_lock(pthread_mutex_t * mutex)
-{
- printf("test_nocontention_lock()\n");
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_debug_double_lock(pthread_mutex_t * mutex)
-{
- printf("test_debug_double_lock()\n");
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_lock(mutex) != EDEADLK) {
- printf("double lock error not detected ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_debug_double_unlock(pthread_mutex_t * mutex)
-{
- printf("test_debug_double_unlock()\n");
- if (pthread_mutex_lock(mutex)) {
- printf("pthread_mutex_lock() ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_unlock(mutex) != EPERM) {
- printf("double unlock error not detected ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_nocontention_trylock(pthread_mutex_t * mutex)
-{
- printf("test_nocontention_trylock()\n");
- if (pthread_mutex_trylock(mutex)) {
- printf("pthread_mutex_trylock() ERROR\n");
- return(NOTOK);
- }
- if (pthread_mutex_unlock(mutex)) {
- printf("pthread_mutex_unlock() ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_mutex_static(void)
-{
- pthread_mutex_t mutex_static = PTHREAD_MUTEX_INITIALIZER;
-
- printf("test_mutex_static()\n");
- if (test_nocontention_lock(&mutex_static) ||
- test_contention_lock(&mutex_static)) {
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_mutex_fast(void)
-{
- pthread_mutex_t mutex_fast;
-
- printf("test_mutex_fast()\n");
- if (pthread_mutex_init(&mutex_fast, NULL)) {
- printf("pthread_mutex_init() ERROR\n");
- return(NOTOK);
- }
- if (test_nocontention_lock(&mutex_fast) ||
- test_contention_lock(&mutex_fast)) {
- return(NOTOK);
- }
- if (pthread_mutex_destroy(&mutex_fast)) {
- printf("pthread_mutex_destroy() ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-int test_mutex_debug()
-{
- pthread_mutexattr_t mutex_debug_attr;
- pthread_mutex_t mutex_debug;
-
- printf("test_mutex_debug()\n");
- pthread_mutexattr_init(&mutex_debug_attr);
- pthread_mutexattr_settype(&mutex_debug_attr, PTHREAD_MUTEXTYPE_DEBUG);
-
- if (pthread_mutex_init(&mutex_debug, &mutex_debug_attr)) {
- printf("pthread_mutex_init() ERROR\n");
- return(NOTOK);
- }
- if (test_nocontention_lock(&mutex_debug) ||
- test_contention_lock(&mutex_debug) ||
- test_debug_double_lock(&mutex_debug) ||
- test_debug_double_unlock(&mutex_debug)) {
- return(NOTOK);
- }
- if (pthread_mutex_destroy(&mutex_debug)) {
- printf("pthread_mutex_destroy() ERROR\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-main()
-{
- pthread_init();
-
- printf("test_pthread_mutex START\n");
-
- if (test_mutex_static() || test_mutex_fast() || test_mutex_debug()) {
- printf("test_pthread_mutex FAILED\n");
- exit(1);
- }
-
- printf("test_pthread_mutex PASSED\n");
- exit(0);
-}
-
diff --git a/mit-pthreads/tests/test_pw.c b/mit-pthreads/tests/test_pw.c
deleted file mode 100644
index 0ef6d428180..00000000000
--- a/mit-pthreads/tests/test_pw.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <pwd.h>
-
-main()
-{
- struct passwd *pw;
-
- pthread_init();
- pw = getpwuid(getuid());
- if (!pw) {
- printf("getpwuid(%d) died!\n", getuid());
- exit(1);
- }
- printf("getpwuid(%d) => %lx\n", getuid(), pw);
- printf(" you are: %s\n uid: %d\n gid: %d\n class: %s\n gecos: %s\n dir: %s\n shell: %s\n",
- pw->pw_name, pw->pw_uid, pw->pw_gid, pw->pw_class, pw->pw_gecos, pw->pw_dir,
- pw->pw_shell);
- exit(0);
-}
diff --git a/mit-pthreads/tests/test_readdir.c b/mit-pthreads/tests/test_readdir.c
deleted file mode 100644
index 6de1841bdbc..00000000000
--- a/mit-pthreads/tests/test_readdir.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* ==== test_readdir.c ========================================================
- * Copyright (c) 1993, 1994 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_create() and pthread_exit() calls.
- *
- * 1.00 94/05/19 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <stdio.h>
-
-main()
-{
- struct dirent * file;
- DIR * dot_dir;
- int i, found = 0;
-
- pthread_init();
-
- if (dot_dir = opendir(".")) {
- while (file = readdir(dot_dir)) {
- if (!strcmp("test_readdir", file->d_name)) {
- found = 1;
- }
- }
- closedir(dot_dir);
- if (found) {
- printf("test_readdir PASSED\n");
- exit(0);
- } else {
- printf("Couldn't find file test_readdir ERROR\n");
- }
- } else {
- printf("opendir() ERROR\n");
- }
- printf("test_readdir FAILED\n");
- exit(1);
-}
-
diff --git a/mit-pthreads/tests/test_select.c b/mit-pthreads/tests/test_select.c
deleted file mode 100644
index 0401d77a666..00000000000
--- a/mit-pthreads/tests/test_select.c
+++ /dev/null
@@ -1,115 +0,0 @@
-#include <pthread.h>
-#include <stdio.h>
-#ifndef ultrix
-#include <sys/fcntl.h>
-#else /* ultrix */
-#include <fcntl.h>
-#endif /* !ultrix */
-#include <sys/types.h>
-#include <sys/time.h>
-#ifdef hpux
-#include <sys/file.h>
-#endif /* hpux */
-#include <errno.h>
-#define NLOOPS 1000
-
-int ntouts = 0;
-
-void *
-bg_routine(void *arg)
-{
- write(1,"bg routine running\n",19);
- /*pthread_dump_state();*/
- while (1) {
- int n;
- char dot;
-
- dot = '.';
- pthread_yield();
- write(1,&dot,1);
- pthread_yield();
- n = NLOOPS;
- while (n-- > 0)
- pthread_yield();
- }
-}
-
-void *
-fg_routine(void *arg)
-{
- int flags, stat, nonblock_flag;
- static struct timeval tout = { 0, 500000 };
-
-#if 0
-#if defined(hpux) || defined(__alpha)
- nonblock_flag = O_NONBLOCK;
-#else
- nonblock_flag = FNDELAY;
-#endif
- printf("fg_routine running\n");
- flags = fcntl(0, F_GETFL, 0);
- printf("stdin flags b4 anything = %x\n", flags);
- stat = fcntl(0, F_SETFL, flags | nonblock_flag);
- if (stat < 0) {
- printf("fcntl(%x) => %d\n", nonblock_flag, errno);
- printf("could not set nonblocking i/o on stdin [oldf %x, stat %d]\n",
- flags, stat);
- exit(1);
- }
- printf("stdin flags = 0x%x after turning on %x\n", flags, nonblock_flag);
-#endif
- while (1) {
- int n;
- fd_set r;
-
- FD_ZERO(&r);
- FD_SET(0,&r);
- printf("select>");
- n = select(1, &r, (fd_set*)0, (fd_set*)0, (struct timeval *)0);
- if (n < 0) {
- perror ("select");
- exit(1);
- } else if (n > 0) {
- int nb;
- char buf[128];
-
- printf("=> select returned: %d\n", n);
- while ((nb = read(0, buf, sizeof(buf)-1)) >= 0) {
- buf[nb] = '\0';
- printf("read %d: |%s|\n", nb, buf);
- }
- printf("=> out of read loop: %d / %d\n", nb, errno);
- if (nb < 0) {
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- perror ("read");
- exit(1);
- }
- }
- } else
- ntouts++;
- }
-}
-
-main(int argc, char **argv)
-{
- pthread_t bg_thread, fg_thread;
- int junk;
-
- pthread_init();
- setbuf(stdout,NULL);
- setbuf(stderr,NULL);
- if (argc > 1) {
- if (pthread_create(&bg_thread, NULL, bg_routine, 0) < 0) {
- printf("error: could not create bg thread\n");
- exit(1);
- }
- }
- if (pthread_create(&fg_thread, NULL, fg_routine, 0) < 0) {
- printf("error: could not create fg thread\n");
- exit(1);
- }
- printf("threads forked: bg=%lx fg=%lx\n", bg_thread, fg_thread);
- /*pthread_dump_state();*/
- printf("initial thread %lx joining fg...\n", pthread_self());
- pthread_join(fg_thread, (void **)&junk);
-}
diff --git a/mit-pthreads/tests/test_setjmp.c b/mit-pthreads/tests/test_setjmp.c
deleted file mode 100644
index ea24ecd63bc..00000000000
--- a/mit-pthreads/tests/test_setjmp.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <setjmp.h>
-
-main()
-{
-jmp_buf foo;
-
-if (setjmp(foo)) {
- exit(0);
-}
-printf("Hi mom\n");
-longjmp(foo, 1);
-printf("Should never reach here\n");
-}
diff --git a/mit-pthreads/tests/test_sleep.c b/mit-pthreads/tests/test_sleep.c
deleted file mode 100644
index f228d08a2ca..00000000000
--- a/mit-pthreads/tests/test_sleep.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* ==== test_switch.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test context switch functionality.
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdio.h>
-
-const char buf[] = "abcdefghijklimnopqrstuvwxyz";
-int fd = 1;
-
-void* new_thread(void* arg)
-{
- int i;
-
- for (i = 0; i < 10; i++) {
- write(fd, buf + (long) arg, 1);
- sleep(1);
- }
-}
-
-main()
-{
- pthread_t thread;
- int count = 2;
- long i;
-
- pthread_init();
-
- printf("Going to sleep\n");
- sleep(10);
- printf("Done sleeping\n");
-
- for(i = 0; i < count; i++) {
- if (pthread_create(&thread, NULL, new_thread, (void *) i)) {
- printf("error creating new thread %d\n", i);
- }
- }
- pthread_exit(NULL);
- fprintf(stderr, "pthread_exit returned\n");
- exit(1);
-}
diff --git a/mit-pthreads/tests/test_sock_1.c b/mit-pthreads/tests/test_sock_1.c
deleted file mode 100644
index e23755a67dc..00000000000
--- a/mit-pthreads/tests/test_sock_1.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* ==== test_sock_1.c =========================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_create() and pthread_exit() calls.
- *
- * 1.00 93/08/03 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-struct sockaddr_in a_sout;
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_attr_t attr;
-
-#define MESSAGE5 "This should be message #5"
-#define MESSAGE6 "This should be message #6"
-
-void * sock_connect(void* arg)
-{
- char buf[1024];
- int fd, tmp;
-
- /* Ensure sock_read runs first */
- if (pthread_mutex_lock(&mutex)) {
- printf("Error: sock_connect:pthread_mutex_lock()\n");
- exit(1);
- }
-
- a_sout.sin_addr.s_addr = htonl(0x7f000001); /* loopback */
-
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_connect:socket()\n");
- exit(1);
- }
-
- printf("This should be message #2\n");
- if (connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- printf("Error: sock_connect:connect()\n");
- exit(1);
- }
- close(fd);
-
- if (pthread_mutex_unlock(&mutex)) {
- printf("Error: sock_connect:pthread_mutex_lock()\n");
- exit(1);
- }
-
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_connect:socket()\n");
- exit(1);
- }
-
- printf("This should be message #3\n");
-
- if (connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- printf("Error: sock_connect:connect()\n");
- exit(1);
- }
-
- /* Ensure sock_read runs again */
- pthread_yield();
- pthread_yield();
- pthread_yield();
- pthread_yield();
- if (pthread_mutex_lock(&mutex)) {
- printf("Error: sock_connect:pthread_mutex_lock()\n");
- exit(1);
- }
-
- if ((tmp = read(fd, buf, 1024)) <= 0) {
- printf("Error: sock_connect:read() == %d\n", tmp);
- exit(1);
- }
- write(fd, MESSAGE6, sizeof(MESSAGE6));
- printf("%s\n", buf);
- close(fd);
-}
-
-extern struct fd_table_entry ** fd_table;
-void * sock_write(void* arg)
-{
- int fd = *(int *)arg;
-
- write(fd, MESSAGE5, sizeof(MESSAGE5));
- return(NULL);
-}
-
-void * sock_accept(void* arg)
-{
- pthread_t thread;
- struct sockaddr a_sin;
- int a_sin_size, a_fd, fd, tmp;
- short port;
- char buf[1024];
-
- if (pthread_mutex_unlock(&mutex)) {
- printf("Error: sock_accept:pthread_mutex_lock()\n");
- exit(1);
- }
-
- port = 3276;
- a_sout.sin_family = AF_INET;
- a_sout.sin_port = htons(port);
- a_sout.sin_addr.s_addr = INADDR_ANY;
-
- if ((a_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_accept:socket()\n");
- exit(1);
- }
-
- while (bind(a_fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- if (errno == EADDRINUSE) {
- a_sout.sin_port = htons((++port));
- continue;
- }
- printf("Error: sock_accept:bind()\n");
- exit(1);
- }
-
- if (listen(a_fd, 2)) {
- printf("Error: sock_accept:listen()\n");
- exit(1);
- }
-
- a_sin_size = sizeof(a_sin);
- printf("This should be message #1\n");
- if ((fd = accept(a_fd, &a_sin, &a_sin_size)) < 0) {
- printf("Error: sock_accept:accept()\n");
- exit(1);
- }
-
- if (pthread_mutex_lock(&mutex)) {
- printf("Error: sock_accept:pthread_mutex_lock()\n");
- exit(1);
- }
- close(fd);
-
- a_sin_size = sizeof(a_sin);
- printf("This should be message #4\n");
- if ((fd = accept(a_fd, &a_sin, &a_sin_size)) < 0) {
- printf("Error: sock_accept:accept()\n");
- exit(1);
- }
-
- if (pthread_mutex_unlock(&mutex)) {
- printf("Error: sock_accept:pthread_mutex_lock()\n");
- exit(1);
- }
-
- /* Setup a write thread */
- if (pthread_create(&thread, &attr, sock_write, &fd)) {
- printf("Error: sock_accept:pthread_create(sock_write)\n");
- exit(1);
- }
- if ((tmp = read(fd, buf, 1024)) <= 0) {
- printf("Error: sock_accept:read() == %d\n", tmp);
- exit(1);
- }
- printf("%s\n", buf);
- close(fd);
-}
-
-main()
-{
- pthread_t thread;
- int i;
-
- pthread_init();
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
-
- /* Ensure sock_read runs first */
- if (pthread_mutex_lock(&mutex)) {
- printf("Error: main:pthread_mutex_lock()\n");
- exit(1);
- }
-
- if (pthread_attr_init(&attr)) {
- printf("Error: main:pthread_attr_init()\n");
- exit(1);
- }
- if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
- printf("Error: main:pthread_attr_setschedpolicy()\n");
- exit(1);
- }
- if (pthread_create(&thread, &attr, sock_accept, (void *)0xdeadbeaf)) {
- printf("Error: main:pthread_create(sock_accept)\n");
- exit(1);
- }
- if (pthread_create(&thread, &attr, sock_connect, (void *)0xdeadbeaf)) {
- printf("Error: main:pthread_create(sock_connect)\n");
- exit(1);
- }
- printf("initial thread %lx going to sleep\n", pthread_self());
- sleep(10);
- printf("done sleeping\n");
- return 0;
-}
diff --git a/mit-pthreads/tests/test_sock_2.c b/mit-pthreads/tests/test_sock_2.c
deleted file mode 100644
index 5ec82fd7499..00000000000
--- a/mit-pthreads/tests/test_sock_2.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* ==== test_sock_1.c =========================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_create() and pthread_exit() calls.
- *
- * 1.00 93/08/03 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-struct sockaddr_in a_sout;
-
-#define MESSAGE5 "This should be message #5"
-#define MESSAGE6 "This should be message #6"
-
-void * sock_write(void* arg)
-{
- int fd = *(int *)arg;
-
- write(fd, MESSAGE5, sizeof(MESSAGE5));
- return(NULL);
-}
-
-void * sock_accept(void* arg)
-{
- pthread_t thread;
- struct sockaddr a_sin;
- int a_sin_size, a_fd, fd, tmp;
- short port;
- char buf[1024];
-
- port = 3276;
- a_sout.sin_family = AF_INET;
- a_sout.sin_port = htons(port);
- a_sout.sin_addr.s_addr = INADDR_ANY;
-
- if ((a_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_accept:socket()\n");
- exit(1);
- }
-
- while (bind(a_fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- if (errno == EADDRINUSE) {
- a_sout.sin_port = htons((++port));
- continue;
- }
- printf("Error: sock_accept:bind()\n");
- exit(1);
- }
-
- if (listen(a_fd, 2)) {
- printf("Error: sock_accept:listen()\n");
- exit(1);
- }
-
- a_sin_size = sizeof(a_sin);
- printf("This should be message #1\n");
- if ((fd = accept(a_fd, &a_sin, &a_sin_size)) < 0) {
- printf("Error: sock_accept:accept()\n");
- exit(1);
- }
- close(fd);
- sleep(1);
-
- a_sin_size = sizeof(a_sin);
- memset(&a_sin, 0, sizeof(a_sin));
- printf("This should be message #4\n");
- if ((fd = accept(a_fd, &a_sin, &a_sin_size)) < 0) {
- printf("Error: sock_accept:accept()\n");
- exit(1);
- }
-
- /* Setup a write thread */
- if (pthread_create(&thread, NULL, sock_write, &fd)) {
- printf("Error: sock_accept:pthread_create(sock_write)\n");
- exit(1);
- }
- if ((tmp = read(fd, buf, 1024)) <= 0) {
- tmp = read(fd, buf, 1024);
- printf("Error: sock_accept:read() == %d\n", tmp);
- exit(1);
- }
- printf("%s\n", buf);
- close(fd);
-}
-
-main()
-{
- pthread_t thread;
- int i;
-
- switch(fork()) {
- case -1:
- printf("Error: main:fork()\n");
- break;
- case 0:
- execl("test_sock_2a", "test_sock_2a", "fork okay", NULL);
- default:
- break;
- }
-
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
-
- if (pthread_create(&thread, NULL, sock_accept, (void *)0xdeadbeaf)) {
- printf("Error: main:pthread_create(sock_accept)\n");
- exit(1);
- }
- pthread_exit(NULL);
-}
diff --git a/mit-pthreads/tests/test_sock_2a.c b/mit-pthreads/tests/test_sock_2a.c
deleted file mode 100644
index 9f767b7c675..00000000000
--- a/mit-pthreads/tests/test_sock_2a.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* ==== test_sock_1.c =========================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test pthread_create() and pthread_exit() calls.
- *
- * 1.00 93/08/03 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-struct sockaddr_in a_sout;
-
-#define MESSAGE5 "This should be message #5"
-#define MESSAGE6 "This should be message #6"
-
-void * sock_connect(void* arg)
-{
- char buf[1024];
- int fd, tmp;
- short port;
-
- port = 3276;
- a_sout.sin_family = AF_INET;
- a_sout.sin_port = htons(port);
- a_sout.sin_addr.s_addr = htonl(0x7f000001); /* loopback */
-
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_connect:socket()\n");
- exit(1);
- }
-
- printf("This should be message #2\n");
- if (connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- printf("Error: sock_connect:connect()\n");
- exit(1);
- }
- close(fd);
-
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- printf("Error: sock_connect:socket()\n");
- exit(1);
- }
-
- printf("This should be message #3\n");
-
- if (connect(fd, (struct sockaddr *) &a_sout, sizeof(a_sout)) < 0) {
- printf("Error: sock_connect:connect()\n");
- exit(1);
- }
-
- /* Ensure sock_read runs again */
-
- if ((tmp = read(fd, buf, 1024)) <= 0) {
- printf("Error: sock_connect:read() == %d\n", tmp);
- exit(1);
- }
- write(fd, MESSAGE6, sizeof(MESSAGE6));
- printf("%s\n", buf);
- close(fd);
-}
-
-main(int argc, char **argv)
-{
- pthread_t thread;
- int i;
-
- if (argv[1] && (!strcmp(argv[1], "fork okay"))) {
- sleep(1);
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
-
- if (pthread_create(&thread, NULL, sock_connect, (void *)0xdeadbeaf)) {
- printf("Error: main:pthread_create(sock_connect)\n");
- exit(1);
- }
- pthread_exit(NULL);
- }
- printf("test_sock_2a needs to be execed from test_sock_2.\n");
- printf("It is not a stand alone test.\n");
- exit(1);
-}
diff --git a/mit-pthreads/tests/test_stdio_1.c b/mit-pthreads/tests/test_stdio_1.c
deleted file mode 100644
index 648343a2c9d..00000000000
--- a/mit-pthreads/tests/test_stdio_1.c
+++ /dev/null
@@ -1,124 +0,0 @@
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-char * base_name = "test_stdio_1.c";
-char * dir_name = SRCDIR;
-char * fullname;
-
-#define OK 0
-#define NOTOK -1
-
-/* Test fopen()/ftell()/getc() */
-int test_1(void)
-{
- struct stat statbuf;
- FILE * fp;
- int i;
-
- if (stat(fullname, &statbuf) < OK) {
- printf("ERROR: Couldn't stat %s\n", fullname);
- return(NOTOK);
- }
-
- if ((fp = fopen(fullname, "r")) == NULL) {
- printf("ERROR: Couldn't open %s\n", fullname);
- return(NOTOK);
- }
-
- /* Get the entire file */
- while ((i = getc(fp)) != EOF);
-
- if (ftell(fp) != statbuf.st_size) {
- printf("ERROR: ftell() and stat() don't agree.");
- return(NOTOK);
- }
-
- if (fclose(fp) < OK) {
- printf("ERROR: fclose() failed.");
- return(NOTOK);
- }
- return(OK);
-}
-
-/* Test fopen()/fclose() */
-int test_2(void)
-{
- FILE *fp1, *fp2;
-
- if ((fp1 = fopen(fullname, "r")) == NULL) {
- printf("ERROR: Couldn't fopen %s\n", fullname);
- return(NOTOK);
- }
-
- if (fclose(fp1) < OK) {
- printf("ERROR: fclose() failed.");
- return(NOTOK);
- }
-
- if ((fp2 = fopen(fullname, "r")) == NULL) {
- printf("ERROR: Couldn't fopen %s\n", fullname);
- return(NOTOK);
- }
-
- if (fclose(fp2) < OK) {
- printf("ERROR: fclose() failed.");
- return(NOTOK);
- }
-
- if (fp1 != fp2) {
- printf("ERROR: FILE table leak.\n");
- return(NOTOK);
- }
-
- return(OK);
-}
-
-/* Test sscanf()/sprintf() */
-int test_3(void)
-{
- char * str = "10 4.53";
- char buf[64];
- double d;
- int i;
-
- if (sscanf(str, "%d %lf", &i, &d) != 2) {
- printf("ERROR: sscanf didn't parse input string correctly\n");
- return(NOTOK);
- }
-
- /* Should have a check */
- sprintf(buf, "%d %2.2lf", i, d);
-
- if (strcmp(buf, str)) {
- printf("ERROR: sscanf()/sprintf() didn't parse unparse correctly\n");
- return(NOTOK);
- }
- return(OK);
-}
-
-main()
-{
-
- printf("test_stdio_1 START\n");
-
- if (fullname = malloc (strlen (dir_name) + strlen (base_name) + 2)) {
- sprintf (fullname, "%s/%s", dir_name, base_name);
- } else {
- perror ("malloc");
- exit(1);
- }
-
- if (test_1() || test_2() || test_3()) {
- printf("test_stdio_1 FAILED\n");
- exit(1);
- }
-
- printf("test_stdio_1 PASSED\n");
- exit(0);
-}
-
-
diff --git a/mit-pthreads/tests/test_switch.c b/mit-pthreads/tests/test_switch.c
deleted file mode 100644
index 4c184158fb8..00000000000
--- a/mit-pthreads/tests/test_switch.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ==== test_switch.c ============================================================
- * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
- *
- * Description : Test context switch functionality.
- *
- * 1.00 93/08/04 proven
- * -Started coding this file.
- */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <errno.h>
-
-#define OK 0
-#define NOTOK -1
-
-const char buf[] = "abcdefghijklmnopqrstuvwxyz";
-char x[sizeof(buf)];
-int fd = 1;
-
-/* ==========================================================================
- * usage();
- */
-void usage(void)
-{
- printf("test_switch [-d?] [-c count]\n");
- printf("count must be between 2 and 26\n");
- errno = 0;
-}
-
-void* new_thread(void* arg)
-{
- while(1) {
- write (fd, (char *) arg, 1);
- x[(char *)arg - buf] = 1;
- }
- fprintf(stderr, "Compiler error\n");
- exit(1);
-}
-
-main(int argc, char **argv)
-{
- pthread_t thread;
- int count = 2;
- int debug = 0;
- int eof = 0;
- long i;
-
- /* Getopt variables. */
- extern int optind, opterr;
- extern char *optarg;
-
- while (!eof)
- switch (getopt (argc, argv, "c:d?"))
- {
- case EOF:
- eof = 1;
- break;
- case 'd':
- debug++;
- break;
- case 'c':
- count = atoi(optarg);
- if ((count > 26) || (count < 2)) {
- count = 2;
- }
- break;
- case '?':
- usage();
- return(OK);
- default:
- usage();
- return(NOTOK);
- }
-
- for (i = 0; i < count; i++) {
- if (pthread_create(&thread, NULL, new_thread, (void*)(buf+i))) {
- fprintf (stderr, "error creating new thread %d\n", i);
- exit (1);
- }
- }
-#if 0 /* This would cause the program to loop forever, and "make
- check" would never complete. */
- pthread_exit (NULL);
- fprintf(stderr, "pthread_exit returned\n");
- exit(1);
-#else
- sleep (10);
- for (i = 0; i < count; i++)
- if (x[i] == 0) {
- fprintf (stderr, "thread %d never ran\n", i);
- return 1;
- }
- printf ("\n%s PASSED\n", argv[0]);
- return 0;
-#endif
-}
diff --git a/myisam/Makefile.am b/myisam/Makefile.am
index b68126d5d69..97456edee8d 100644
--- a/myisam/Makefile.am
+++ b/myisam/Makefile.am
@@ -1,15 +1,15 @@
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-#
+#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -17,21 +17,22 @@
EXTRA_DIST = mi_test_all.sh mi_test_all.res
pkgdata_DATA = mi_test_all mi_test_all.res
-INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include
+INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include
LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a ../mysys/libmysys.a \
../dbug/libdbug.a ../strings/libmystrings.a
pkglib_LIBRARIES = libmyisam.a
-bin_PROGRAMS = myisamchk myisamlog myisampack
+bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump
myisamchk_DEPENDENCIES= $(LIBRARIES)
myisamlog_DEPENDENCIES= $(LIBRARIES)
myisampack_DEPENDENCIES=$(LIBRARIES)
-noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 ft_test1 ft_eval
+noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 #ft_test1 ft_eval
noinst_HEADERS = myisamdef.h fulltext.h ftdefs.h ft_test1.h ft_eval.h
mi_test1_DEPENDENCIES= $(LIBRARIES)
mi_test2_DEPENDENCIES= $(LIBRARIES)
mi_test3_DEPENDENCIES= $(LIBRARIES)
-ft_test1_DEPENDENCIES= $(LIBRARIES)
-ft_eval_DEPENDENCIES= $(LIBRARIES)
+#ft_test1_DEPENDENCIES= $(LIBRARIES)
+#ft_eval_DEPENDENCIES= $(LIBRARIES)
+myisam_ftdump_DEPENDENCIES= $(LIBRARIES)
libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
mi_rnext.c mi_rnext_same.c \
mi_search.c mi_page.c mi_key.c mi_locking.c \
@@ -44,8 +45,8 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
mi_range.c mi_dbug.c mi_checksum.c mi_log.c \
mi_changed.c mi_static.c mi_delete_all.c \
mi_delete_table.c mi_rename.c mi_check.c \
- ft_parser.c ft_search.c ft_stopwords.c ft_static.c \
- ft_update.c sort.c
+ ft_parser.c ft_stopwords.c ft_static.c \
+ ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c
CLEANFILES = test?.MY? FT?.MY? isam.log mi_test_all
DEFS = -DMAP_TO_USE_RAID
diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c
new file mode 100644
index 00000000000..c7128464228
--- /dev/null
+++ b/myisam/ft_boolean_search.c
@@ -0,0 +1,655 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
+
+/* TODO: add caching - pre-read several index entries at once */
+
+#define FT_CORE
+#include "ftdefs.h"
+#include <queues.h>
+
+/* search with boolean queries */
+
+static double _wghts[11]=
+{
+ 0.131687242798354,
+ 0.197530864197531,
+ 0.296296296296296,
+ 0.444444444444444,
+ 0.666666666666667,
+ 1.000000000000000,
+ 1.500000000000000,
+ 2.250000000000000,
+ 3.375000000000000,
+ 5.062500000000000,
+ 7.593750000000000};
+static double *wghts=_wghts+5; /* wghts[i] = 1.5**i */
+
+static double _nwghts[11]=
+{
+ -0.065843621399177,
+ -0.098765432098766,
+ -0.148148148148148,
+ -0.222222222222222,
+ -0.333333333333334,
+ -0.500000000000000,
+ -0.750000000000000,
+ -1.125000000000000,
+ -1.687500000000000,
+ -2.531250000000000,
+ -3.796875000000000};
+static double *nwghts=_nwghts+5; /* nwghts[i] = -0.5*1.5**i */
+
+#define FTB_FLAG_TRUNC 1 /* MUST be 1 */
+#define FTB_FLAG_YES 2 /* These two - YES and NO */
+#define FTB_FLAG_NO 4 /* should NEVER be set both */
+
+typedef struct st_ftb_expr FTB_EXPR;
+struct st_ftb_expr
+{
+ FTB_EXPR *up;
+ float weight;
+ uint flags;
+ my_off_t docid[2];
+/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */
+ float cur_weight;
+ byte *quot, *qend;
+ int yesses; /* number of "yes" words matched */
+ int nos; /* number of "no" words matched */
+ int ythresh; /* number of "yes" words in expr */
+ int yweaks; /* number of "yes" words for scan only */
+};
+
+typedef struct st_ftb_word
+{
+ FTB_EXPR *up;
+ float weight;
+ uint flags;
+ my_off_t docid[2];
+/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */
+ uint ndepth;
+ int len;
+ /* ... docid cache can be added here. SerG */
+ byte word[1];
+} FTB_WORD;
+
+typedef struct st_ft_info
+{
+ struct _ft_vft *please;
+ MI_INFO *info;
+ uint keynr;
+ CHARSET_INFO *charset;
+ enum { UNINITIALIZED, READY, INDEX_SEARCH, INDEX_DONE /*, SCAN*/ } state;
+ uint with_scan;
+ my_off_t lastpos;
+ FTB_EXPR *root;
+ QUEUE queue;
+ TREE no_dupes;
+ FTB_WORD **list;
+ MEM_ROOT mem_root;
+} FTB;
+
+static int FTB_WORD_cmp(my_off_t *v, FTB_WORD *a, FTB_WORD *b)
+{
+ int i;
+
+ /* if a==curdoc, take it as a < b */
+ if (v && a->docid[0] == *v)
+ return -1;
+
+ /* ORDER BY docid, ndepth DESC */
+ i=CMP_NUM(a->docid[0], b->docid[0]);
+ if (!i)
+ i=CMP_NUM(b->ndepth,a->ndepth);
+ return i;
+}
+
+static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b)
+{
+ /* ORDER BY word DESC, ndepth DESC */
+ int i=_mi_compare_text(cs, (uchar*) (*b)->word+1,(*b)->len-1,
+ (uchar*) (*a)->word+1,(*a)->len-1,0);
+ if (!i)
+ i=CMP_NUM((*b)->ndepth,(*a)->ndepth);
+ return i;
+}
+
+static void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
+ FTB_EXPR *up, uint depth)
+{
+ byte res;
+ FTB_PARAM param;
+ FT_WORD w;
+ FTB_WORD *ftbw;
+ FTB_EXPR *ftbe;
+ uint extra=HA_FT_WLEN+ftb->info->s->rec_reflength; /* just a shortcut */
+
+ if (ftb->state != UNINITIALIZED)
+ return;
+
+ param.prev=' ';
+ param.quot=up->quot;
+ while ((res=ft_get_word(start,end,&w,&param)))
+ {
+ int r=param.plusminus;
+ float weight= (float) (param.pmsign ? nwghts : wghts)[(r>5)?5:((r<-5)?-5:r)];
+ switch (res) {
+ case 1: /* word found */
+ ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root,
+ sizeof(FTB_WORD) +
+ (param.trunc ? MI_MAX_KEY_BUFF :
+ w.len+extra));
+ ftbw->len=w.len+1;
+ ftbw->flags=0;
+ if (param.yesno>0) ftbw->flags|=FTB_FLAG_YES;
+ if (param.yesno<0) ftbw->flags|=FTB_FLAG_NO;
+ if (param.trunc) ftbw->flags|=FTB_FLAG_TRUNC;
+ ftbw->weight=weight;
+ ftbw->up=up;
+ ftbw->docid[0]=ftbw->docid[1]=HA_POS_ERROR;
+ ftbw->ndepth= (param.yesno<0) + depth;
+ memcpy(ftbw->word+1, w.pos, w.len);
+ ftbw->word[0]=w.len;
+ if (param.yesno > 0) up->ythresh++;
+ queue_insert(& ftb->queue, (byte *)ftbw);
+ ftb->with_scan|=(param.trunc & FTB_FLAG_TRUNC);
+ break;
+ case 2: /* left bracket */
+ ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR));
+ ftbe->flags=0;
+ if (param.yesno>0) ftbe->flags|=FTB_FLAG_YES;
+ if (param.yesno<0) ftbe->flags|=FTB_FLAG_NO;
+ ftbe->weight=weight;
+ ftbe->up=up;
+ ftbe->ythresh=ftbe->yweaks=0;
+ ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR;
+ if ((ftbe->quot=param.quot)) ftb->with_scan|=2;
+ if (param.yesno > 0) up->ythresh++;
+ _ftb_parse_query(ftb, start, end, ftbe, depth+1);
+ param.quot=0;
+ break;
+ case 3: /* right bracket */
+ if (up->quot) up->qend=param.quot;
+ return;
+ }
+ }
+ return;
+}
+
+static int _ftb_no_dupes_cmp(void* not_used __attribute__((unused)),
+ const void *a,const void *b)
+{
+ return CMP_NUM((*((my_off_t*)a)), (*((my_off_t*)b)));
+}
+
+static void _ftb_init_index_search(FT_INFO *ftb)
+{
+ int i, r;
+ FTB_WORD *ftbw;
+ MI_INFO *info=ftb->info;
+ MI_KEYDEF *keyinfo;
+ my_off_t keyroot;
+
+ if ((ftb->state != READY && ftb->state !=INDEX_DONE) ||
+ ftb->keynr == NO_SUCH_KEY)
+ return;
+ ftb->state=INDEX_SEARCH;
+
+ keyinfo=info->s->keyinfo+ftb->keynr;
+ keyroot=info->s->state.key_root[ftb->keynr];
+
+ for (i=ftb->queue.elements; i; i--)
+ {
+ ftbw=(FTB_WORD *)(ftb->queue.root[i]);
+
+ if (ftbw->flags & FTB_FLAG_TRUNC)
+ {
+ /*
+ special treatment for truncation operator
+ 1. there are some (besides this) +words
+ | no need to search in the index, it can never ADD new rows
+ | to the result, and to remove half-matched rows we do scan anyway
+ 2. -trunc*
+ | same as 1.
+ 3. in 1 and 2, +/- need not be on the same expr. level,
+ but can be on any upper level, as in +word +(trunc1* trunc2*)
+ 4. otherwise
+ | We have to index-search for this prefix.
+ | It may cause duplicates, as in the index (sorted by <word,docid>)
+ | <aaaa,row1>
+ | <aabb,row2>
+ | <aacc,row1>
+ | Searching for "aa*" will find row1 twice...
+ */
+ FTB_EXPR *ftbe;
+ for (ftbe=(FTB_EXPR*)ftbw;
+ ftbe->up && !(ftbe->up->flags & FTB_FLAG_TRUNC);
+ ftbe->up->flags|= FTB_FLAG_TRUNC, ftbe=ftbe->up)
+ {
+ if (ftbe->flags & FTB_FLAG_NO || /* 2 */
+ ftbe->up->ythresh - ftbe->up->yweaks >1) /* 1 */
+ {
+ FTB_EXPR *top_ftbe=ftbe->up->up;
+ ftbw->docid[0]=HA_POS_ERROR;
+ for (ftbe=ftbw->up; ftbe != top_ftbe; ftbe=ftbe->up)
+ if (ftbe->flags & FTB_FLAG_YES)
+ ftbe->yweaks++;
+ ftbe=0;
+ break;
+ }
+ }
+ if (!ftbe)
+ continue;
+ /* 3 */
+ if (!is_tree_inited(& ftb->no_dupes))
+ init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t),
+ _ftb_no_dupes_cmp,0,0,0);
+ else
+ reset_tree(& ftb->no_dupes);
+ }
+ r=_mi_search(info, keyinfo, (uchar*) ftbw->word, ftbw->len,
+ SEARCH_FIND | SEARCH_BIGGER, keyroot);
+ if (!r)
+ {
+ r=_mi_compare_text(ftb->charset,
+ info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC),
+ ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
+ (uchar*) ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC),
+ ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
+ 0);
+ }
+ if (r) /* not found */
+ {
+ if (ftbw->flags&FTB_FLAG_YES && ftbw->up->up==0)
+ {
+ /*
+ This word MUST BE present in every document returned,
+ so we can abort the search right now
+ */
+ ftb->state=INDEX_DONE;
+ return;
+ }
+ }
+ else
+ {
+ memcpy(ftbw->word, info->lastkey, info->lastkey_length);
+ ftbw->docid[0]=info->lastpos;
+ }
+ }
+ queue_fix(& ftb->queue);
+}
+
+
+FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
+ uint query_len,
+ my_bool presort __attribute__((unused)))
+{
+ FTB *ftb;
+ FTB_EXPR *ftbe;
+ uint res;
+
+ if (!(ftb=(FTB *)my_malloc(sizeof(FTB), MYF(MY_WME))))
+ return 0;
+ ftb->please= (struct _ft_vft *) & _ft_vft_boolean;
+ ftb->state=UNINITIALIZED;
+ ftb->info=info;
+ ftb->keynr=keynr;
+ ftb->charset= ((keynr==NO_SUCH_KEY) ?
+ default_charset_info :
+ info->s->keyinfo[keynr].seg->charset);
+ ftb->with_scan=0;
+ ftb->lastpos=HA_POS_ERROR;
+ bzero(& ftb->no_dupes, sizeof(TREE));
+
+ init_alloc_root(&ftb->mem_root, 1024, 1024);
+
+ /*
+ Hack: instead of init_queue, we'll use reinit queue to be able
+ to alloc queue with alloc_root()
+ */
+ res=ftb->queue.max_elements=1+query_len/(min(ft_min_word_len,2)+1);
+ if (!(ftb->queue.root=
+ (byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*))))
+ goto err;
+ reinit_queue(& ftb->queue, res, 0, 0,
+ (int (*)(void*,byte*,byte*))FTB_WORD_cmp, 0);
+ if (!(ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR))))
+ goto err;
+ ftbe->weight=1;
+ ftbe->flags=FTB_FLAG_YES;
+ ftbe->nos=1;
+ ftbe->quot=0;
+ ftbe->up=0;
+ ftbe->ythresh=ftbe->yweaks=0;
+ ftbe->docid[0]=ftbe->docid[1]=HA_POS_ERROR;
+ ftb->root=ftbe;
+ _ftb_parse_query(ftb, &query, query+query_len, ftbe, 0);
+ ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root,
+ sizeof(FTB_WORD *)*ftb->queue.elements);
+ memcpy(ftb->list, ftb->queue.root+1, sizeof(FTB_WORD *)*ftb->queue.elements);
+ qsort2(ftb->list, ftb->queue.elements, sizeof(FTB_WORD *),
+ (qsort2_cmp)FTB_WORD_cmp_list, ftb->charset);
+ if (ftb->queue.elements<2) ftb->with_scan &= ~FTB_FLAG_TRUNC;
+ ftb->state=READY;
+ return ftb;
+err:
+ free_root(& ftb->mem_root, MYF(0));
+ my_free((gptr)ftb,MYF(0));
+ return 0;
+}
+
+
+/* returns 1 if str0 contain str1 */
+static int _ftb_strstr(const byte *s0, const byte *e0,
+ const byte *s1, const byte *e1,
+ CHARSET_INFO *cs)
+{
+ const byte *p;
+
+ while (s0 < e0)
+ {
+ while (s0 < e0 && cs->to_upper[(uint) (uchar) *s0++] !=
+ cs->to_upper[(uint) (uchar) *s1])
+ /* no-op */;
+ if (s0 >= e0)
+ return 0;
+ p=s1+1;
+ while (s0 < e0 && p < e1 && cs->to_upper[(uint) (uchar) *s0] ==
+ cs->to_upper[(uint) (uchar) *p])
+ s0++, p++;
+ if (p >= e1)
+ return 1;
+ }
+ return 0;
+}
+
+
+static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig)
+{
+ FT_SEG_ITERATOR ftsi;
+ FTB_EXPR *ftbe;
+ float weight=ftbw->weight;
+ int yn=ftbw->flags, ythresh, mode=(ftsi_orig != 0);
+ my_off_t curdoc=ftbw->docid[mode];
+
+ for (ftbe=ftbw->up; ftbe; ftbe=ftbe->up)
+ {
+ ythresh = ftbe->ythresh - (mode ? 0 : ftbe->yweaks);
+ if (ftbe->docid[mode] != curdoc)
+ {
+ ftbe->cur_weight=0;
+ ftbe->yesses=ftbe->nos=0;
+ ftbe->docid[mode]=curdoc;
+ }
+ if (ftbe->nos)
+ break;
+ if (yn & FTB_FLAG_YES)
+ {
+ weight /= ftbe->ythresh;
+ ftbe->cur_weight += weight;
+ if (++ftbe->yesses == ythresh)
+ {
+ yn=ftbe->flags;
+ weight=ftbe->cur_weight*ftbe->weight;
+ if (mode && ftbe->quot)
+ {
+ int not_found=1;
+
+ memcpy(&ftsi, ftsi_orig, sizeof(ftsi));
+ while (_mi_ft_segiterator(&ftsi) && not_found)
+ {
+ if (!ftsi.pos)
+ continue;
+ not_found = ! _ftb_strstr(ftsi.pos, ftsi.pos+ftsi.len,
+ ftbe->quot, ftbe->qend, ftb->charset);
+ }
+ if (not_found) break;
+ } /* ftbe->quot */
+ }
+ else
+ break;
+ }
+ else
+ if (yn & FTB_FLAG_NO)
+ {
+ /*
+ NOTE: special sort function of queue assures that all
+ (yn & FTB_FLAG_NO) != 0
+ events for every particular subexpression will
+ "auto-magically" happen BEFORE all the
+ (yn & FTB_FLAG_YES) != 0 events. So no
+ already matched expression can become not-matched again.
+ */
+ ++ftbe->nos;
+ break;
+ }
+ else
+ {
+ if (ftbe->ythresh)
+ weight/=3;
+ ftbe->cur_weight += weight;
+ if (ftbe->yesses < ythresh)
+ break;
+ yn= (ftbe->yesses++ == ythresh) ? ftbe->flags : 0 ;
+ weight*= ftbe->weight;
+ }
+ }
+}
+
+
+int ft_boolean_read_next(FT_INFO *ftb, char *record)
+{
+ FTB_EXPR *ftbe;
+ FTB_WORD *ftbw;
+ MI_INFO *info=ftb->info;
+ MI_KEYDEF *keyinfo=info->s->keyinfo+ftb->keynr;
+ my_off_t keyroot=info->s->state.key_root[ftb->keynr];
+ my_off_t curdoc;
+ int r;
+
+ if (ftb->state != INDEX_SEARCH && ftb->state != INDEX_DONE)
+ return -1;
+
+ /* black magic ON */
+ if ((int) _mi_check_index(info, ftb->keynr) < 0)
+ return my_errno;
+ if (_mi_readinfo(info, F_RDLCK, 1))
+ return my_errno;
+ /* black magic OFF */
+
+ if (!ftb->queue.elements)
+ return my_errno=HA_ERR_END_OF_FILE;
+
+ /* Attention!!! Address of a local variable is used here! See err: label */
+ ftb->queue.first_cmp_arg=(void *)&curdoc;
+
+ while (ftb->state == INDEX_SEARCH &&
+ (curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid[0]) !=
+ HA_POS_ERROR)
+ {
+ while (curdoc==(ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0])
+ {
+ _ftb_climb_the_tree(ftb, ftbw, 0);
+
+ /* update queue */
+ r=_mi_search(info, keyinfo, (uchar*) ftbw->word, USE_WHOLE_KEY,
+ SEARCH_BIGGER , keyroot);
+ if (!r)
+ {
+ r=_mi_compare_text(ftb->charset,
+ info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC),
+ ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
+ (uchar*) ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC),
+ ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC),
+ 0);
+ }
+ if (r) /* not found */
+ {
+ ftbw->docid[0]=HA_POS_ERROR;
+ if (ftbw->flags&FTB_FLAG_YES && ftbw->up->up==0)
+ {
+ /*
+ This word MUST BE present in every document returned,
+ so we can stop the search right now
+ */
+ ftb->state=INDEX_DONE;
+ }
+ }
+ else
+ {
+ memcpy(ftbw->word, info->lastkey, info->lastkey_length);
+ ftbw->docid[0]=info->lastpos;
+ }
+ queue_replaced(& ftb->queue);
+ }
+
+ ftbe=ftb->root;
+ if (ftbe->docid[0]==curdoc && ftbe->cur_weight>0 &&
+ ftbe->yesses>=(ftbe->ythresh-ftbe->yweaks) && !ftbe->nos)
+ {
+ /* curdoc matched ! */
+ if (is_tree_inited(& ftb->no_dupes) &&
+ tree_insert(& ftb->no_dupes, &curdoc, 0)->count >1)
+ /* but it managed to get past this line once */
+ continue;
+
+ info->lastpos=curdoc;
+ info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
+
+ if (!(*info->read_record)(info,curdoc,record))
+ {
+ info->update|= HA_STATE_AKTIV; /* Record is read */
+ if (ftb->with_scan && ft_boolean_find_relevance(ftb,record,0)==0)
+ continue; /* no match */
+ my_errno=0;
+ goto err;
+ }
+ goto err;
+ }
+ }
+ ftb->state=INDEX_DONE;
+ my_errno=HA_ERR_END_OF_FILE;
+err:
+ ftb->queue.first_cmp_arg=(void *)0;
+ return my_errno;
+}
+
+
+float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
+{
+ FT_WORD word;
+ FTB_WORD *ftbw;
+ FTB_EXPR *ftbe;
+ FT_SEG_ITERATOR ftsi, ftsi2;
+ const byte *end;
+ my_off_t docid=ftb->info->lastpos;
+
+ if (docid == HA_POS_ERROR)
+ return -2.0;
+ if (!ftb->queue.elements)
+ return 0;
+
+ if (ftb->state != INDEX_SEARCH && docid <= ftb->lastpos)
+ {
+ FTB_EXPR *x;
+ uint i;
+
+ for (i=0; i < ftb->queue.elements; i++)
+ {
+ ftb->list[i]->docid[1]=HA_POS_ERROR;
+ for (x=ftb->list[i]->up; x; x=x->up)
+ x->docid[1]=HA_POS_ERROR;
+ }
+ }
+
+ ftb->lastpos=docid;
+
+ if (ftb->keynr==NO_SUCH_KEY)
+ _mi_ft_segiterator_dummy_init(record, length, &ftsi);
+ else
+ _mi_ft_segiterator_init(ftb->info, ftb->keynr, record, &ftsi);
+ memcpy(&ftsi2, &ftsi, sizeof(ftsi));
+
+ while (_mi_ft_segiterator(&ftsi))
+ {
+ if (!ftsi.pos)
+ continue;
+
+ end=ftsi.pos+ftsi.len;
+ while (ft_simple_get_word((byte **) &ftsi.pos,(byte *) end, &word))
+ {
+ int a, b, c;
+ for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2)
+ {
+ ftbw=ftb->list[c];
+ if (_mi_compare_text(ftb->charset, (uchar*) word.pos, word.len,
+ (uchar*) ftbw->word+1, ftbw->len-1,
+ (my_bool) (ftbw->flags&FTB_FLAG_TRUNC)) >0)
+ b=c;
+ else
+ a=c;
+ }
+ for (; c>=0; c--)
+ {
+ ftbw=ftb->list[c];
+ if (_mi_compare_text(ftb->charset, (uchar*) word.pos, word.len,
+ (uchar*) ftbw->word+1,ftbw->len-1,
+ (my_bool) (ftbw->flags&FTB_FLAG_TRUNC)))
+ break;
+ if (ftbw->docid[1] == docid)
+ continue;
+ ftbw->docid[1]=docid;
+ _ftb_climb_the_tree(ftb, ftbw, &ftsi2);
+ }
+ }
+ }
+
+ ftbe=ftb->root;
+ if (ftbe->docid[1]==docid && ftbe->cur_weight>0 &&
+ ftbe->yesses>=ftbe->ythresh && !ftbe->nos)
+ { /* row matched ! */
+ return ftbe->cur_weight;
+ }
+ else
+ { /* match failed ! */
+ return 0.0;
+ }
+}
+
+
+void ft_boolean_close_search(FT_INFO *ftb)
+{
+ if (is_tree_inited(& ftb->no_dupes))
+ {
+ delete_tree(& ftb->no_dupes);
+ }
+ free_root(& ftb->mem_root, MYF(0));
+ my_free((gptr)ftb,MYF(0));
+}
+
+
+float ft_boolean_get_relevance(FT_INFO *ftb)
+{
+ return ftb->root->cur_weight;
+}
+
+
+void ft_boolean_reinit_search(FT_INFO *ftb)
+{
+ _ftb_init_index_search(ftb);
+}
+
diff --git a/myisam/ft_eval.c b/myisam/ft_eval.c
index 9466104100a..34248c69f20 100644
--- a/myisam/ft_eval.c
+++ b/myisam/ft_eval.c
@@ -11,18 +11,32 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
+/* Written by Sergei A. Golubchik, who has a shared copyright to this code
+ added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */
#include "ftdefs.h"
#include "ft_eval.h"
#include <stdarg.h>
-#include <getopt.h>
+#include <my_getopt.h>
static void print_error(int exit_code, const char *fmt,...);
static void get_options(int argc, char *argv[]);
static int create_record(char *pos, FILE *file);
+static void usage();
-int main(int argc,char *argv[])
+static struct my_option my_long_options[] =
+{
+ {"", 's', "", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'q', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'S', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", '#', "", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'V', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", '?', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'h', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
{
MI_INFO *file;
int i,j;
@@ -32,7 +46,7 @@ int main(int argc,char *argv[])
bzero((char*)recinfo,sizeof(recinfo));
/* First define 2 columns */
- recinfo[0].type=FIELD_SKIPP_ENDSPACE;
+ recinfo[0].type=FIELD_SKIP_ENDSPACE;
recinfo[0].length=docid_length;
recinfo[1].type=FIELD_BLOB;
recinfo[1].length= 4+mi_portable_sizeof_char_ptr;
@@ -65,7 +79,7 @@ int main(int argc,char *argv[])
my_errno=0;
i=0;
- while(create_record(record,df))
+ while (create_record(record,df))
{
error=mi_write(file,record);
if (error)
@@ -80,102 +94,125 @@ int main(int argc,char *argv[])
if (!(file=mi_open(filename,2,0))) goto err;
if (!silent)
printf("- Reading rows with key\n");
- for(i=1;create_record(record,qf);i++) {
- FT_DOCLIST *result; double w; int t,err;
+ for (i=1;create_record(record,qf);i++)
+ {
+ FT_DOCLIST *result;
+ double w;
+ int t, err;
- result=ft_init_search(file,0,blob_record,(uint) strlen(blob_record),1);
- if(!result) {
+ result=ft_nlq_init_search(file,0,blob_record,(uint) strlen(blob_record),1);
+ if (!result)
+ {
printf("Query %d failed with errno %3d\n",i,my_errno);
goto err;
}
if (!silent)
printf("Query %d. Found: %d.\n",i,result->ndocs);
- for(j=0;(err=ft_read_next(result, read_record))==0;j++) {
+ for (j=0;(err=ft_nlq_read_next(result, read_record))==0;j++)
+ {
t=uint2korr(read_record);
- w=ft_get_relevance(result);
+ w=ft_nlq_get_relevance(result);
printf("%d %.*s %f\n",i,t,read_record+2,w);
}
- if(err != HA_ERR_END_OF_FILE) {
+ if (err != HA_ERR_END_OF_FILE)
+ {
printf("ft_read_next %d failed with errno %3d\n",j,my_errno);
goto err;
}
- ft_close_search(result);
+ ft_nlq_close_search(result);
}
if (mi_close(file)) goto err;
my_end(MY_CHECK_ERROR);
return (0);
-err:
+
+ err:
printf("got error: %3d when using myisam-database\n",my_errno);
- return 1; /* skipp warning */
+ return 1; /* skip warning */
}
-static void get_options(int argc,char *argv[])
-{
- int c;
- char *options=(char*) "Vh#:qSs:";
- while ((c=getopt(argc,argv,options)) != -1)
- {
- switch(c) {
- case 's':
- if(stopwordlist && stopwordlist!=ft_precompiled_stopwords) break;
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case 's':
+ if (stopwordlist && stopwordlist != ft_precompiled_stopwords)
+ break;
+ {
+ FILE *f; char s[HA_FT_MAXLEN]; int i=0,n=SWL_INIT;
+
+ if (!(stopwordlist=(const char**) malloc(n*sizeof(char *))))
+ print_error(1,"malloc(%d)",n*sizeof(char *));
+ if (!(f=fopen(argument,"r")))
+ print_error(1,"fopen(%s)",argument);
+ while (!feof(f))
{
- FILE *f; char s[HA_FT_MAXLEN]; int i=0,n=SWL_INIT;
-
- if(!(stopwordlist=(const char**) malloc(n*sizeof(char *))))
- print_error(1,"malloc(%d)",n*sizeof(char *));
- if(!(f=fopen(optarg,"r")))
- print_error(1,"fopen(%s)",optarg);
- while(!feof(f)) {
- if(!(fgets(s,HA_FT_MAXLEN,f)))
- print_error(1,"fgets(s,%d,%s)",HA_FT_MAXLEN,optarg);
- if(!(stopwordlist[i++]=strdup(s)))
- print_error(1,"strdup(%s)",s);
- if(i>=n) {
- n+=SWL_PLUS;
- if(!(stopwordlist=(const char**) realloc((char*) stopwordlist,n*sizeof(char *))))
- print_error(1,"realloc(%d)",n*sizeof(char *));
- }
+ if (!(fgets(s,HA_FT_MAXLEN,f)))
+ print_error(1,"fgets(s,%d,%s)",HA_FT_MAXLEN,argument);
+ if (!(stopwordlist[i++]=strdup(s)))
+ print_error(1,"strdup(%s)",s);
+ if (i >= n)
+ {
+ n+=SWL_PLUS;
+ if (!(stopwordlist=(const char**) realloc((char*) stopwordlist,
+ n*sizeof(char *))))
+ print_error(1,"realloc(%d)",n*sizeof(char *));
}
- fclose(f);
- stopwordlist[i]=NULL;
- break;
}
- case 'q': silent=1; break;
- case 'S': if(stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break;
- case '#':
- DEBUGGER_ON;
- DBUG_PUSH (optarg);
+ fclose(f);
+ stopwordlist[i]=NULL;
break;
- case 'V':
- case '?':
- case 'h':
- default:
- printf("%s -[%s] <d_file> <q_file>\n", argv[0], options);
- exit(0);
}
+ case 'q': silent=1; break;
+ case 'S': if (stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break;
+ case '#':
+ DEBUGGER_ON;
+ DBUG_PUSH (argument);
+ break;
+ case 'V':
+ case '?':
+ case 'h':
+ usage();
+ exit(1);
}
- if(!(d_file=argv[optind])) print_error(1,"No d_file");
- if(!(df=fopen(d_file,"r")))
+ return 0;
+}
+
+
+static void get_options(int argc, char *argv[])
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ if (!(d_file=argv[optind])) print_error(1,"No d_file");
+ if (!(df=fopen(d_file,"r")))
print_error(1,"fopen(%s)",d_file);
- if(!(q_file=argv[optind+1])) print_error(1,"No q_file");
- if(!(qf=fopen(q_file,"r")))
+ if (!(q_file=argv[optind+1])) print_error(1,"No q_file");
+ if (!(qf=fopen(q_file,"r")))
print_error(1,"fopen(%s)",q_file);
return;
} /* get options */
+
static int create_record(char *pos, FILE *file)
-{ uint tmp; char *ptr;
+{
+ uint tmp; char *ptr;
bzero((char *)pos,MAX_REC_LENGTH);
/* column 1 - VARCHAR */
- if(!(fgets(pos+2,MAX_REC_LENGTH-32,file)))
+ if (!(fgets(pos+2,MAX_REC_LENGTH-32,file)))
{
- if(feof(file)) return 0; else print_error(1,"fgets(docid) - 1");
+ if (feof(file))
+ return 0;
+ else
+ print_error(1,"fgets(docid) - 1");
}
tmp=(uint) strlen(pos+2)-1;
int2store(pos,tmp);
@@ -183,7 +220,7 @@ static int create_record(char *pos, FILE *file)
/* column 2 - BLOB */
- if(!(fgets(blob_record,MAX_BLOB_LENGTH,file)))
+ if (!(fgets(blob_record,MAX_BLOB_LENGTH,file)))
print_error(1,"fgets(docid) - 2");
tmp=(uint) strlen(blob_record);
int4store(pos,tmp);
@@ -206,3 +243,11 @@ static void print_error(int exit_code, const char *fmt,...)
va_end(args);
exit(exit_code);
}
+
+
+static void usage()
+{
+ printf("%s [options]\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
diff --git a/myisam/ft_eval.h b/myisam/ft_eval.h
index d87b6be9c7c..68be3a39f33 100644
--- a/myisam/ft_eval.h
+++ b/myisam/ft_eval.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & Sergei A. Golubchik
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -40,4 +40,3 @@ MI_KEYSEG keyseg[10];
#define MAX_LINE_LENGTH 128
char line[MAX_LINE_LENGTH];
-
diff --git a/myisam/ft_nlq_search.c b/myisam/ft_nlq_search.c
new file mode 100644
index 00000000000..f426b88d77d
--- /dev/null
+++ b/myisam/ft_nlq_search.c
@@ -0,0 +1,291 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
+
+#define FT_CORE
+#include "ftdefs.h"
+
+/* search with natural language queries */
+
+typedef struct ft_doc_rec
+{
+ my_off_t dpos;
+ double weight;
+} FT_DOC;
+
+struct st_ft_info
+{
+ struct _ft_vft *please;
+ MI_INFO *info;
+ int ndocs;
+ int curdoc;
+ FT_DOC doc[1];
+};
+
+typedef struct st_all_in_one
+{
+ MI_INFO *info;
+ uint keynr;
+ CHARSET_INFO *charset;
+ uchar *keybuff;
+ MI_KEYDEF *keyinfo;
+ my_off_t key_root;
+ TREE dtree;
+} ALL_IN_ONE;
+
+typedef struct st_ft_superdoc
+{
+ FT_DOC doc;
+ FT_WORD *word_ptr;
+ double tmp_weight;
+} FT_SUPERDOC;
+
+static int FT_SUPERDOC_cmp(void* cmp_arg __attribute__((unused)),
+ FT_SUPERDOC *p1, FT_SUPERDOC *p2)
+{
+ if (p1->doc.dpos < p2->doc.dpos)
+ return -1;
+ if (p1->doc.dpos == p2->doc.dpos)
+ return 0;
+ return 1;
+}
+
+static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
+{
+ uint keylen, r, doc_cnt;
+ FT_SUPERDOC sdoc, *sptr;
+ TREE_ELEMENT *selem;
+ double gweight=1;
+#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
+ float tmp_weight;
+#else
+#error
+#endif
+
+ DBUG_ENTER("walk_and_match");
+
+ word->weight=LWS_FOR_QUERY;
+
+ keylen=_ft_make_key(aio->info,aio->keynr,(char*) aio->keybuff,word,0);
+ keylen-=HA_FT_WLEN;
+
+ doc_cnt=0;
+
+ r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
+ SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
+ aio->info->update|= HA_STATE_AKTIV; /* for _mi_test_if_changed() */
+
+ while (!r && gweight)
+ {
+ if (_mi_compare_text(aio->charset,
+ aio->info->lastkey,keylen,
+ aio->keybuff,keylen,0)) break;
+
+#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
+ mi_float4get(tmp_weight,aio->info->lastkey+keylen);
+#else
+#error
+#endif
+ if(tmp_weight==0) DBUG_RETURN(doc_cnt); /* stopword, doc_cnt should be 0 */
+
+ sdoc.doc.dpos=aio->info->lastpos;
+
+ /* saving document matched into dtree */
+ if (!(selem=tree_insert(&aio->dtree, &sdoc, 0)))
+ DBUG_RETURN(1);
+
+ sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
+
+ if (selem->count==1) /* document's first match */
+ sptr->doc.weight=0;
+ else
+ sptr->doc.weight+=sptr->tmp_weight*sptr->word_ptr->weight;
+
+ sptr->word_ptr=word;
+ sptr->tmp_weight=tmp_weight;
+
+ doc_cnt++;
+
+ gweight=word->weight*GWS_IN_USE;
+ if (gweight < 0 || doc_cnt > 2000000)
+ gweight=0;
+
+ if (_mi_test_if_changed(aio->info) == 0)
+ r=_mi_search_next(aio->info, aio->keyinfo, aio->info->lastkey,
+ aio->info->lastkey_length, SEARCH_BIGGER,
+ aio->key_root);
+ else
+ r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
+ aio->info->lastkey_length, SEARCH_BIGGER,
+ aio->key_root);
+ }
+
+ word->weight=gweight;
+
+ DBUG_RETURN(0);
+}
+
+
+static int walk_and_copy(FT_SUPERDOC *from,
+ uint32 count __attribute__((unused)), FT_DOC **to)
+{
+ DBUG_ENTER("walk_and_copy");
+ from->doc.weight+=from->tmp_weight*from->word_ptr->weight;
+ (*to)->dpos=from->doc.dpos;
+ (*to)->weight=from->doc.weight;
+ (*to)++;
+ DBUG_RETURN(0);
+}
+
+
+static int FT_DOC_cmp(FT_DOC *a, FT_DOC *b)
+{
+ return sgn(b->weight - a->weight);
+}
+
+
+FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query,
+ uint query_len, my_bool presort)
+{
+ TREE allocated_wtree, *wtree=&allocated_wtree;
+ ALL_IN_ONE aio;
+ FT_DOC *dptr;
+ FT_INFO *dlist=NULL;
+ my_off_t saved_lastpos=info->lastpos;
+ DBUG_ENTER("ft_init_nlq_search");
+
+/* black magic ON */
+ if ((int) (keynr = _mi_check_index(info,keynr)) < 0)
+ DBUG_RETURN(NULL);
+ if (_mi_readinfo(info,F_RDLCK,1))
+ DBUG_RETURN(NULL);
+/* black magic OFF */
+
+ aio.info=info;
+ aio.keynr=keynr;
+ aio.keyinfo=info->s->keyinfo+keynr;
+ aio.charset=aio.keyinfo->seg->charset;
+ aio.keybuff=info->lastkey+info->s->base.max_key_length;
+ aio.key_root=info->s->state.key_root[keynr];
+
+ bzero(&allocated_wtree,sizeof(allocated_wtree));
+
+ init_tree(&aio.dtree,0,0,sizeof(FT_SUPERDOC),(qsort_cmp2)&FT_SUPERDOC_cmp,0,
+ NULL, NULL);
+
+ ft_parse_init(&allocated_wtree, aio.charset);
+ if (ft_parse(&allocated_wtree,query,query_len))
+ goto err;
+
+ if (tree_walk(wtree, (tree_walk_action)&walk_and_match, &aio,
+ left_root_right))
+ goto err2;
+
+ dlist=(FT_INFO *)my_malloc(sizeof(FT_INFO)+
+ sizeof(FT_DOC)*(aio.dtree.elements_in_tree-1),
+ MYF(0));
+ if(!dlist)
+ goto err2;
+
+ dlist->please= (struct _ft_vft *) & _ft_vft_nlq;
+ dlist->ndocs=aio.dtree.elements_in_tree;
+ dlist->curdoc=-1;
+ dlist->info=aio.info;
+ dptr=dlist->doc;
+
+ tree_walk(&aio.dtree, (tree_walk_action) &walk_and_copy,
+ &dptr, left_root_right);
+
+ if (presort)
+ qsort(dlist->doc, dlist->ndocs, sizeof(FT_DOC), (qsort_cmp)&FT_DOC_cmp);
+
+err2:
+ delete_tree(wtree);
+ delete_tree(&aio.dtree);
+
+err:
+ info->lastpos=saved_lastpos;
+ DBUG_RETURN(dlist);
+}
+
+
+int ft_nlq_read_next(FT_INFO *handler, char *record)
+{
+ MI_INFO *info= (MI_INFO *) handler->info;
+
+ if (++handler->curdoc >= handler->ndocs)
+ {
+ --handler->curdoc;
+ return HA_ERR_END_OF_FILE;
+ }
+
+ info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
+
+ info->lastpos=handler->doc[handler->curdoc].dpos;
+ if (!(*info->read_record)(info,info->lastpos,record))
+ {
+ info->update|= HA_STATE_AKTIV; /* Record is read */
+ return 0;
+ }
+ return my_errno;
+}
+
+
+float ft_nlq_find_relevance(FT_INFO *handler,
+ byte *record __attribute__((unused)),
+ uint length __attribute__((unused)))
+{
+ int a,b,c;
+ FT_DOC *docs=handler->doc;
+ my_off_t docid=handler->info->lastpos;
+
+ if (docid == HA_POS_ERROR)
+ return -5.0;
+
+ /* Assuming docs[] is sorted by dpos... */
+
+ for (a=0, b=handler->ndocs, c=(a+b)/2; b-a>1; c=(a+b)/2)
+ {
+ if (docs[c].dpos > docid)
+ b=c;
+ else
+ a=c;
+ }
+ if (docs[a].dpos == docid)
+ return (float) docs[a].weight;
+ else
+ return 0.0;
+}
+
+
+void ft_nlq_close_search(FT_INFO *handler)
+{
+ my_free((gptr)handler,MYF(0));
+}
+
+
+float ft_nlq_get_relevance(FT_INFO *handler)
+{
+ return (float) handler->doc[handler->curdoc].weight;
+}
+
+
+void ft_nlq_reinit_search(FT_INFO *handler)
+{
+ handler->curdoc=-1;
+}
+
diff --git a/myisam/ft_parser.c b/myisam/ft_parser.c
index 7ea2e240c36..c25ed6022a0 100644
--- a/myisam/ft_parser.c
+++ b/myisam/ft_parser.c
@@ -33,16 +33,12 @@ typedef struct st_ft_docstat {
double max, nsum, nsum2;
#endif /* EVAL_RUN */
- MI_INFO *info;
- uint keynr;
- byte *keybuf;
} FT_DOCSTAT;
-static int FT_WORD_cmp(FT_WORD *w1, FT_WORD *w2)
+static int FT_WORD_cmp(CHARSET_INFO* cs, FT_WORD *w1, FT_WORD *w2)
{
- return _mi_compare_text(default_charset_info,
- (uchar*) w1->pos,w1->len,
- (uchar*) w2->pos, w2->len,0);
+ return _mi_compare_text(cs, (uchar*) w1->pos, w1->len,
+ (uchar*) w2->pos, w2->len, 0);
}
static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat)
@@ -63,17 +59,15 @@ static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat)
/* transforms tree of words into the array, applying normalization */
-FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree)
+FT_WORD * ft_linearize(TREE *wtree)
{
FT_WORD *wlist,*p;
FT_DOCSTAT docstat;
+ DBUG_ENTER("ft_linearize");
if ((wlist=(FT_WORD *) my_malloc(sizeof(FT_WORD)*
(1+wtree->elements_in_tree),MYF(0))))
{
- docstat.info=info;
- docstat.keynr=keynr;
- docstat.keybuf=keybuf;
docstat.list=wlist;
docstat.uniq=wtree->elements_in_tree;
#ifdef EVAL_RUN
@@ -83,13 +77,12 @@ FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree)
tree_walk(wtree,(tree_walk_action)&walk_and_copy,&docstat,left_root_right);
}
delete_tree(wtree);
- my_free((char*) wtree,MYF(0));
if (!wlist)
- return NULL;
+ DBUG_RETURN(NULL);
docstat.list->pos=NULL;
- for(p=wlist;p->pos;p++)
+ for (p=wlist;p->pos;p++)
{
p->weight=PRENORM_IN_USE;
#ifdef EVAL_RUN
@@ -104,48 +97,146 @@ FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree)
#endif
#endif /* EVAL_RUN */
- for(p=wlist;p->pos;p++)
+ for (p=wlist;p->pos;p++)
{
p->weight/=NORM_IN_USE;
}
- return wlist;
+ DBUG_RETURN(wlist);
}
+#define true_word_char(X) (isalnum(X) || (X)=='_')
#ifdef HYPHEN_IS_DELIM
-#define word_char(X) (isalnum(X) || (X)=='_' || (X)=='\'')
+#define misc_word_char(X) ((X)=='\'')
#else
-#define word_char(X) (isalnum(X) || (X)=='_' || (X)=='\'' || (X)=='-')
+#define misc_word_char(X) ((X)=='\'' || (X)=='-')
#endif
+#define word_char(X) (true_word_char(X) || misc_word_char(X))
-/* this is rather dumb first version of the parser */
-TREE * ft_parse(TREE *wtree, byte *doc, int doclen)
+
+/* returns:
+ * 0 - eof
+ * 1 - word found
+ * 2 - left bracket
+ * 3 - right bracket
+ */
+byte ft_get_word(byte **start, byte *end, FT_WORD *word, FTB_PARAM *param)
{
- byte *end=doc+doclen;
- FT_WORD w;
+ byte *doc=*start;
+ int mwc;
+
+ param->yesno=(FTB_YES==' ') ? 1 : (param->quot != 0);
+ param->plusminus=param->pmsign=0;
- if (!wtree)
+ while (doc<end)
{
- if (!(wtree=(TREE *)my_malloc(sizeof(TREE),MYF(0)))) return NULL;
- init_tree(wtree,0,sizeof(FT_WORD),(qsort_cmp)&FT_WORD_cmp,0,NULL);
+ for (;doc<end;doc++)
+ {
+ if (true_word_char(*doc)) break;
+ if (*doc == FTB_RQUOT && param->quot) {
+ param->quot=doc;
+ *start=doc+1;
+ return 3; /* FTB_RBR */
+ }
+ if ((*doc == FTB_LBR || *doc == FTB_RBR || *doc == FTB_LQUOT)
+ && !param->quot)
+ {
+ /* param->prev=' '; */
+ *start=doc+1;
+ if (*doc == FTB_LQUOT) param->quot=*start;
+ return (*doc == FTB_RBR)+2;
+ }
+ if (param->prev == ' ' && !param->quot)
+ {
+ if (*doc == FTB_YES ) { param->yesno=+1; continue; } else
+ if (*doc == FTB_EGAL) { param->yesno= 0; continue; } else
+ if (*doc == FTB_NO ) { param->yesno=-1; continue; } else
+ if (*doc == FTB_INC ) { param->plusminus++; continue; } else
+ if (*doc == FTB_DEC ) { param->plusminus--; continue; } else
+ if (*doc == FTB_NEG ) { param->pmsign=!param->pmsign; continue; }
+ }
+ param->prev=*doc;
+ param->yesno=(FTB_YES==' ') ? 1 : (param->quot != 0);
+ param->plusminus=param->pmsign=0;
+ }
+
+ mwc=0;
+ for (word->pos=doc; doc<end; doc++)
+ if (true_word_char(*doc))
+ mwc=0;
+ else if (!misc_word_char(*doc) || mwc++)
+ break;
+
+ param->prev='A'; /* be sure *prev is true_word_char */
+ word->len= (uint)(doc-word->pos) - mwc;
+ if ((param->trunc=(doc<end && *doc == FTB_TRUNC)))
+ doc++;
+
+ if (((word->len >= ft_min_word_len && !is_stopword(word->pos, word->len))
+ || param->trunc) && word->len < ft_max_word_len)
+ {
+ *start=doc;
+ return 1;
+ }
}
+ return 0;
+}
+
+byte ft_simple_get_word(byte **start, byte *end, FT_WORD *word)
+{
+ byte *doc=*start;
+ int mwc;
+ DBUG_ENTER("ft_simple_get_word");
- w.weight=0;
while (doc<end)
{
for (;doc<end;doc++)
- if (word_char(*doc)) break;
- for (w.pos=doc; doc<end; doc++)
- if (!word_char(*doc)) break;
- if ((w.len= (uint) (doc-w.pos)) < MIN_WORD_LEN) continue;
- if (w.len >= HA_FT_MAXLEN) continue;
- if (is_stopword(w.pos, w.len)) continue;
- if (!tree_insert(wtree, &w, 0))
{
- delete_tree(wtree);
- my_free((char*) wtree,MYF(0));
- return NULL;
+ if (true_word_char(*doc)) break;
+ }
+
+ mwc=0;
+ for(word->pos=doc; doc<end; doc++)
+ if (true_word_char(*doc))
+ mwc=0;
+ else if (!misc_word_char(*doc) || mwc++)
+ break;
+
+ word->len= (uint)(doc-word->pos) - mwc;
+
+ if (word->len >= ft_min_word_len && word->len < ft_max_word_len &&
+ !is_stopword(word->pos, word->len))
+ {
+ *start=doc;
+ DBUG_RETURN(1);
}
}
- return wtree;
+ DBUG_RETURN(0);
}
+
+void ft_parse_init(TREE *wtree, CHARSET_INFO *cs)
+{
+ DBUG_ENTER("ft_parse_init");
+ if (!is_tree_inited(wtree))
+ init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0,NULL, cs);
+ DBUG_VOID_RETURN;
+}
+
+int ft_parse(TREE *wtree, byte *doc, int doclen)
+{
+ byte *end=doc+doclen;
+ FT_WORD w;
+ DBUG_ENTER("ft_parse");
+
+ while (ft_simple_get_word(&doc,end,&w))
+ {
+ if (!tree_insert(wtree, &w, 0))
+ goto err;
+ }
+ DBUG_RETURN(0);
+
+err:
+ delete_tree(wtree);
+ DBUG_RETURN(1);
+}
+
diff --git a/myisam/ft_search.c b/myisam/ft_search.c
deleted file mode 100644
index 9a728a4c211..00000000000
--- a/myisam/ft_search.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
-
-#include "ftdefs.h"
-
-/* queries isam and returns list of documents matched */
-
-typedef struct st_all_in_one {
- MI_INFO *info;
- uint keynr;
- uchar *keybuff;
- MI_KEYDEF *keyinfo;
- my_off_t key_root;
- TREE dtree;
-} ALL_IN_ONE;
-
-typedef struct st_ft_superdoc {
- FT_DOC doc;
- FT_WORD *word_ptr;
- double tmp_weight;
-} FT_SUPERDOC;
-
-static int FT_SUPERDOC_cmp(FT_SUPERDOC *p1, FT_SUPERDOC *p2)
-{
- if (p1->doc.dpos < p2->doc.dpos)
- return -1;
- if (p1->doc.dpos == p2->doc.dpos)
- return 0;
- return 1;
-}
-
-static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
-{
- uint keylen, r, doc_cnt;
-#ifdef EVAL_RUN
- uint cnt;
- double sum, sum2, suml;
-#endif /* EVAL_RUN */
- FT_SUPERDOC sdoc, *sptr;
- TREE_ELEMENT *selem;
-#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
- float tmp_weight;
-#else
-#error
-#endif
-
- word->weight=LWS_FOR_QUERY;
-
- keylen=_ft_make_key(aio->info,aio->keynr,(char*) aio->keybuff,word,0);
-#ifdef EVAL_RUN
- keylen-=1+HA_FT_WLEN;
-#else /* EVAL_RUN */
- keylen-=HA_FT_WLEN;
-#endif /* EVAL_RUN */
-
-#ifdef EVAL_RUN
- sum=sum2=suml=
-#endif /* EVAL_RUN */
- doc_cnt=0;
-
- r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
- SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
-
- while(!r)
- {
- if (_mi_compare_text(default_charset_info,
- aio->info->lastkey,keylen,
- aio->keybuff,keylen,0)) break;
-
-#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
-#ifdef EVAL_RUN
- mi_float4get(tmp_weight,aio->info->lastkey+keylen+1);
-#else /* EVAL_RUN */
- mi_float4get(tmp_weight,aio->info->lastkey+keylen);
-#endif /* EVAL_RUN */
-#else
-#error
-#endif
- if(tmp_weight==0) return doc_cnt; /* stopword, doc_cnt should be 0 */
-
-#ifdef EVAL_RUN
- cnt=*(byte *)(aio->info->lastkey+keylen);
-#endif /* EVAL_RUN */
-
- sdoc.doc.dpos=aio->info->lastpos;
-
- /* saving document matched into dtree */
- if(!(selem=tree_insert(&aio->dtree, &sdoc, 0))) return 1;
-
- sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
-
- if(selem->count==1) /* document's first match */
- sptr->doc.weight=0;
- else
- sptr->doc.weight+=sptr->tmp_weight*sptr->word_ptr->weight;
-
- sptr->word_ptr=word;
- sptr->tmp_weight=tmp_weight;
-
- doc_cnt++;
-#ifdef EVAL_RUN
- sum +=cnt;
- sum2+=cnt*cnt;
- suml+=cnt*log(cnt);
-#endif /* EVAL_RUN */
-
- if (_mi_test_if_changed(aio->info) == 0)
- r=_mi_search_next(aio->info, aio->keyinfo, aio->info->lastkey,
- aio->info->lastkey_length, SEARCH_BIGGER,
- aio->key_root);
- else
- r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
- aio->info->lastkey_length, SEARCH_BIGGER,
- aio->key_root);
- }
- if(doc_cnt) {
- word->weight*=GWS_IN_USE;
- if(word->weight < 0) word->weight=0;
- }
-
- return 0;
-}
-
-static int walk_and_copy(FT_SUPERDOC *from,
- uint32 count __attribute__((unused)), FT_DOC **to)
-{
- from->doc.weight+=from->tmp_weight*from->word_ptr->weight;
- (*to)->dpos=from->doc.dpos;
- (*to)->weight=from->doc.weight;
- (*to)++;
- return 0;
-}
-
-static int FT_DOC_cmp(FT_DOC *a, FT_DOC *b)
-{
- return sgn(b->weight - a->weight);
-}
-
-FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key,
- uint key_len, my_bool presort)
-{
- TREE *wtree;
- ALL_IN_ONE aio;
- FT_DOCLIST *dlist;
- FT_DOC *dptr;
- my_off_t saved_lastpos=((MI_INFO *)info)->lastpos;
-
-/* black magic ON */
- if ((int) (keynr = _mi_check_index((MI_INFO *)info,keynr)) < 0)
- return NULL;
- if (_mi_readinfo((MI_INFO *)info,F_RDLCK,1))
- return NULL;
-/* black magic OFF */
-
- dlist=NULL;
- aio.info=(MI_INFO *)info;
- aio.keynr=keynr;
- aio.keybuff=aio.info->lastkey+aio.info->s->base.max_key_length;
- aio.keyinfo=aio.info->s->keyinfo+keynr;
- aio.key_root=aio.info->s->state.key_root[keynr];
-
- if (!(wtree=ft_parse(NULL,key,key_len))) return NULL;
-
- init_tree(&aio.dtree,0,sizeof(FT_SUPERDOC),(qsort_cmp)&FT_SUPERDOC_cmp,0,
- NULL);
-
- if (tree_walk(wtree, (tree_walk_action)&walk_and_match, &aio,
- left_root_right))
- goto err;
-
- dlist=(FT_DOCLIST *) my_malloc(sizeof(FT_DOCLIST)+sizeof(FT_DOC)*
- (aio.dtree.elements_in_tree-1),MYF(0));
- if (!dlist)
- goto err;
-
- dlist->ndocs=aio.dtree.elements_in_tree;
- dlist->curdoc=-1;
- dlist->info=aio.info;
- dptr=dlist->doc;
-
- tree_walk(&aio.dtree, (tree_walk_action)&walk_and_copy, &dptr,
- left_root_right);
-
- if (presort)
- {
- qsort(dlist->doc, dlist->ndocs, sizeof(FT_DOC), (qsort_cmp)&FT_DOC_cmp);
- }
-
-err:
- delete_tree(&aio.dtree);
- delete_tree(wtree);
- my_free((char*) wtree,MYF(0));
- ((MI_INFO *)info)->lastpos=saved_lastpos;
- return dlist;
-}
-
-int ft_read_next(FT_DOCLIST *handler, char *record)
-{
- MI_INFO *info= (MI_INFO *) handler->info;
-
- if (++handler->curdoc >= handler->ndocs)
- {
- --handler->curdoc;
- return HA_ERR_END_OF_FILE;
- }
-
- info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
-
- info->lastpos=handler->doc[handler->curdoc].dpos;
- if (!(*info->read_record)(info,info->lastpos,record))
- {
- info->update|= HA_STATE_AKTIV; /* Record is read */
- return 0;
- }
- return my_errno;
-}
diff --git a/myisam/ft_static.c b/myisam/ft_static.c
index 00d9d4ed19a..7f78a11bb2f 100644
--- a/myisam/ft_static.c
+++ b/myisam/ft_static.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,6 +18,11 @@
#include "ftdefs.h"
+ulong ft_min_word_len=4;
+ulong ft_max_word_len=HA_FT_MAXLEN;
+ulong ft_max_word_len_for_sort=20;
+const char *ft_boolean_syntax="+ -><()~*:\"\"&|";
+
const MI_KEYSEG ft_keysegs[FT_SEGS]={
{
HA_KEYTYPE_VARTEXT, /* type */
@@ -39,10 +44,30 @@ const MI_KEYSEG ft_keysegs[FT_SEGS]={
},
#endif /* EVAL_RUN */
{
- HA_FT_WTYPE, 7, 0, 0, 0, 0, HA_FT_WLEN, 0, 0, NULL
+ HA_FT_WTYPE, 7, 0, 0, 0, HA_NO_SORT, HA_FT_WLEN, 0, 0, NULL
}
};
+const struct _ft_vft _ft_vft_nlq = {
+ ft_nlq_read_next, ft_nlq_find_relevance, ft_nlq_close_search,
+ ft_nlq_get_relevance, ft_nlq_reinit_search
+};
+const struct _ft_vft _ft_vft_boolean = {
+ ft_boolean_read_next, ft_boolean_find_relevance, ft_boolean_close_search,
+ ft_boolean_get_relevance, ft_boolean_reinit_search
+};
+
+FT_INFO *(*_ft_init_vft[2])(MI_INFO *, uint, byte *, uint, my_bool) =
+{ ft_init_nlq_search, ft_init_boolean_search };
+
+FT_INFO *ft_init_search(uint mode, void *info, uint keynr,
+ byte *query, uint query_len, my_bool presort)
+{
+ return (*_ft_init_vft[mode])((MI_INFO *)info, keynr,
+ query, query_len, presort);
+}
+
+const char *ft_stopword_file = 0;
const char *ft_precompiled_stopwords[] = {
#ifdef COMPILE_STOPWORDS_IN
@@ -52,7 +77,6 @@ const char *ft_precompiled_stopwords[] = {
it was slightly modified to my taste, though
*/
- "a",
"a's",
"able",
"about",
@@ -106,7 +130,6 @@ const char *ft_precompiled_stopwords[] = {
"available",
"away",
"awfully",
- "b",
"be",
"became",
"because",
@@ -130,7 +153,6 @@ const char *ft_precompiled_stopwords[] = {
"brief",
"but",
"by",
- "c",
"c'mon",
"c's",
"came",
@@ -160,7 +182,6 @@ const char *ft_precompiled_stopwords[] = {
"couldn't",
"course",
"currently",
- "d",
"definitely",
"described",
"despite",
@@ -176,7 +197,6 @@ const char *ft_precompiled_stopwords[] = {
"down",
"downwards",
"during",
- "e",
"each",
"edu",
"eg",
@@ -200,7 +220,6 @@ const char *ft_precompiled_stopwords[] = {
"exactly",
"example",
"except",
- "f",
"far",
"few",
"fifth",
@@ -217,7 +236,6 @@ const char *ft_precompiled_stopwords[] = {
"from",
"further",
"furthermore",
- "g",
"get",
"gets",
"getting",
@@ -230,7 +248,6 @@ const char *ft_precompiled_stopwords[] = {
"got",
"gotten",
"greetings",
- "h",
"had",
"hadn't",
"happens",
@@ -263,7 +280,6 @@ const char *ft_precompiled_stopwords[] = {
"how",
"howbeit",
"however",
- "i",
"i'd",
"i'll",
"i'm",
@@ -292,16 +308,13 @@ const char *ft_precompiled_stopwords[] = {
"it's",
"its",
"itself",
- "j",
"just",
- "k",
"keep",
"keeps",
"kept",
"know",
"knows",
"known",
- "l",
"last",
"lately",
"later",
@@ -320,7 +333,6 @@ const char *ft_precompiled_stopwords[] = {
"looking",
"looks",
"ltd",
- "m",
"mainly",
"many",
"may",
@@ -338,7 +350,6 @@ const char *ft_precompiled_stopwords[] = {
"must",
"my",
"myself",
- "n",
"name",
"namely",
"nd",
@@ -365,7 +376,6 @@ const char *ft_precompiled_stopwords[] = {
"novel",
"now",
"nowhere",
- "o",
"obviously",
"of",
"off",
@@ -393,7 +403,6 @@ const char *ft_precompiled_stopwords[] = {
"over",
"overall",
"own",
- "p",
"particular",
"particularly",
"per",
@@ -405,11 +414,9 @@ const char *ft_precompiled_stopwords[] = {
"presumably",
"probably",
"provides",
- "q",
"que",
"quite",
"qv",
- "r",
"rather",
"rd",
"re",
@@ -421,7 +428,6 @@ const char *ft_precompiled_stopwords[] = {
"relatively",
"respectively",
"right",
- "s",
"said",
"same",
"saw",
@@ -471,7 +477,6 @@ const char *ft_precompiled_stopwords[] = {
"such",
"sup",
"sure",
- "t",
"t's",
"take",
"taken",
@@ -531,7 +536,6 @@ const char *ft_precompiled_stopwords[] = {
"trying",
"twice",
"two",
- "u",
"un",
"under",
"unfortunately",
@@ -548,14 +552,12 @@ const char *ft_precompiled_stopwords[] = {
"uses",
"using",
"usually",
- "v",
"value",
"various",
"very",
"via",
"viz",
"vs",
- "w",
"want",
"wants",
"was",
@@ -607,8 +609,6 @@ const char *ft_precompiled_stopwords[] = {
"would",
"would",
"wouldn't",
- "x",
- "y",
"yes",
"yet",
"you",
@@ -620,7 +620,6 @@ const char *ft_precompiled_stopwords[] = {
"yours",
"yourself",
"yourselves",
- "z",
"zero",
#endif
diff --git a/myisam/ft_stem.c b/myisam/ft_stem.c
index bdfc73b774b..846d5d2247f 100644
--- a/myisam/ft_stem.c
+++ b/myisam/ft_stem.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -17,4 +17,3 @@
/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
/* mulitingual stem */
-
diff --git a/myisam/ft_stopwords.c b/myisam/ft_stopwords.c
index d796b87ed71..298df9a54cf 100644
--- a/myisam/ft_stopwords.c
+++ b/myisam/ft_stopwords.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -25,35 +25,83 @@ typedef struct st_ft_stopwords {
static TREE *stopwords3=NULL;
-static int FT_STOPWORD_cmp(FT_STOPWORD *w1, FT_STOPWORD *w2)
+static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)),
+ FT_STOPWORD *w1, FT_STOPWORD *w2)
{
return _mi_compare_text(default_charset_info,
(uchar *)w1->pos,w1->len,
(uchar *)w2->pos,w2->len,0);
}
-int ft_init_stopwords(const char **sws)
+static void FT_STOPWORD_free(FT_STOPWORD *w, TREE_FREE action,
+ void *arg __attribute__((unused)))
{
- FT_STOPWORD sw;
+ if (action == free_free)
+ my_free((gptr) w->pos, MYF(0));
+}
+static int ft_add_stopword(const char *w)
+{
+ FT_STOPWORD sw;
+ return !w ||
+ (((sw.len= (uint) strlen(sw.pos=w)) >= ft_min_word_len) &&
+ (tree_insert(stopwords3, &sw, 0)==NULL));
+}
- if(!stopwords3)
+int ft_init_stopwords()
+{
+ if (!stopwords3)
{
- if(!(stopwords3=(TREE *)my_malloc(sizeof(TREE),MYF(0)))) return -1;
- init_tree(stopwords3,0,sizeof(FT_STOPWORD),(qsort_cmp)&FT_STOPWORD_cmp,0,
- NULL);
+ if (!(stopwords3=(TREE *)my_malloc(sizeof(TREE),MYF(0))))
+ return -1;
+ init_tree(stopwords3,0,0,sizeof(FT_STOPWORD),(qsort_cmp2)&FT_STOPWORD_cmp,
+ 0,
+ (ft_stopword_file ? (tree_element_free)&FT_STOPWORD_free : 0),
+ NULL);
}
- if(!sws) return 0;
+ if (ft_stopword_file)
+ {
+ File fd;
+ uint len;
+ byte *buffer, *start, *end;
+ FT_WORD w;
+ int error=-1;
+
+ if (!*ft_stopword_file)
+ return 0;
- for(;*sws;sws++)
+ if ((fd=my_open(ft_stopword_file, O_RDONLY, MYF(MY_WME))) == -1)
+ return -1;
+ len=(uint)my_seek(fd, 0L, MY_SEEK_END, MYF(0));
+ my_seek(fd, 0L, MY_SEEK_SET, MYF(0));
+ if (!(start=buffer=my_malloc(len+1, MYF(MY_WME))))
+ goto err0;
+ len=my_read(fd, buffer, len, MYF(MY_WME));
+ end=start+len;
+ while (ft_simple_get_word(&start, end, &w))
+ {
+ if (ft_add_stopword(my_strdup_with_length(w.pos, w.len, MYF(0))))
+ goto err1;
+ }
+ error=0;
+err1:
+ my_free(buffer, MYF(0));
+err0:
+ my_close(fd, MYF(MY_WME));
+ return error;
+ }
+ else
{
- if( (sw.len= (uint) strlen(sw.pos=*sws)) < MIN_WORD_LEN) continue;
- if(!tree_insert(stopwords3, &sw, 0))
+ /* compatibility mode: to be removed */
+ char **sws=(char **)ft_precompiled_stopwords;
+
+ for (;*sws;sws++)
{
- delete_tree(stopwords3); /* purecov: inspected */
- return -1; /* purecov: inspected */
+ if (ft_add_stopword(*sws))
+ return -1;
}
+ ft_stopword_file="(built-in)"; /* for SHOW VARIABLES */
}
return 0;
}
@@ -71,7 +119,7 @@ void ft_free_stopwords()
{
if (stopwords3)
{
- delete_tree(stopwords3); /* purecov: inspected */
+ delete_tree(stopwords3); /* purecov: inspected */
my_free((char*) stopwords3,MYF(0));
stopwords3=0;
}
diff --git a/myisam/ft_test1.c b/myisam/ft_test1.c
index 5093b591fb2..cb0b6054f0a 100644
--- a/myisam/ft_test1.c
+++ b/myisam/ft_test1.c
@@ -14,13 +14,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
+/* Written by Sergei A. Golubchik, who has a shared copyright to this code
+ added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */
#include "ftdefs.h"
#include "ft_test1.h"
-#include <getopt.h>
+#include <my_getopt.h>
-static int key_field=FIELD_VARCHAR,extra_field=FIELD_SKIPP_ENDSPACE;
+static int key_field=FIELD_VARCHAR,extra_field=FIELD_SKIP_ENDSPACE;
static uint key_length=200,extra_length=50;
static int key_type=HA_KEYTYPE_TEXT;
static int verbose=0,silent=0,skip_update=0,
@@ -33,8 +34,26 @@ static char record[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH];
static int run_test(const char *filename);
static void get_options(int argc, char *argv[]);
static void create_record(char *, int);
+static void usage();
-int main(int argc,char *argv[])
+static struct my_option my_long_options[] =
+{
+ {"", 'v', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", '?', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'h', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'V', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'v', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 's', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'N', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'S', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'K', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'F', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", 'U', "", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"", '#', "", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
{
MY_INIT(argv[0]);
@@ -137,7 +156,7 @@ static int run_test(const char *filename)
printf("- Reading rows with key\n");
for (i=0 ; i < NQUERIES ; i++)
{ FT_DOCLIST *result;
- result=ft_init_search(file,0,(char*) query[i],strlen(query[i]),1);
+ result=ft_nlq_init_search(file,0,(char*) query[i],strlen(query[i]),1);
if(!result) {
printf("Query %d: `%s' failed with errno %3d\n",i,query[i],my_errno);
continue;
@@ -145,7 +164,7 @@ static int run_test(const char *filename)
printf("Query %d: `%s'. Found: %d. Top five documents:\n",
i,query[i],result->ndocs);
for(j=0;j<5;j++) { double w; int err;
- err=ft_read_next(result, read_record);
+ err=ft_nlq_read_next(result, read_record);
if(err==HA_ERR_END_OF_FILE) {
printf("No more matches!\n");
break;
@@ -153,7 +172,7 @@ static int run_test(const char *filename)
printf("ft_read_next %d failed with errno %3d\n",j,my_errno);
break;
}
- w=ft_get_relevance(result);
+ w=ft_nlq_get_relevance(result);
if(key_field == FIELD_VARCHAR) {
uint l;
char *p;
@@ -164,7 +183,7 @@ static int run_test(const char *filename)
printf("%10.7f: %.*s\n",w,recinfo[1].length,
recinfo[0].length+read_record);
}
- ft_close_search(result);
+ ft_nlq_close_search(result);
}
if (mi_close(file)) goto err;
@@ -173,7 +192,7 @@ static int run_test(const char *filename)
return (0);
err:
printf("got error: %3d when using myisam-database\n",my_errno);
- return 1; /* skipp warning */
+ return 1; /* skip warning */
}
static char blob_key[MAX_REC_LENGTH];
@@ -186,7 +205,7 @@ void create_record(char *pos, int n)
{
uint tmp;
char *ptr;
- strncpy(blob_key,data[n].f0,keyinfo[0].seg[0].length);
+ strnmov(blob_key,data[n].f0,keyinfo[0].seg[0].length);
tmp=strlen(blob_key);
int4store(pos,tmp);
ptr=blob_key;
@@ -196,21 +215,21 @@ void create_record(char *pos, int n)
else if (recinfo[0].type == FIELD_VARCHAR)
{
uint tmp;
- strncpy(pos+2,data[n].f0,keyinfo[0].seg[0].length);
+ strnmov(pos+2,data[n].f0,keyinfo[0].seg[0].length);
tmp=strlen(pos+2);
int2store(pos,tmp);
pos+=recinfo[0].length;
}
else
{
- strncpy(pos,data[n].f0,keyinfo[0].seg[0].length);
+ strnmov(pos,data[n].f0,keyinfo[0].seg[0].length);
pos+=recinfo[0].length;
}
if (recinfo[1].type == FIELD_BLOB)
{
uint tmp;
char *ptr;
- strncpy(blob_key,data[n].f2,keyinfo[0].seg[0].length);
+ strnmov(blob_key,data[n].f2,keyinfo[0].seg[0].length);
tmp=strlen(blob_key);
int4store(pos,tmp);
ptr=blob_key;
@@ -220,46 +239,59 @@ void create_record(char *pos, int n)
else if (recinfo[1].type == FIELD_VARCHAR)
{
uint tmp;
- strncpy(pos+2,data[n].f2,keyinfo[0].seg[0].length);
+ strnmov(pos+2,data[n].f2,keyinfo[0].seg[0].length);
tmp=strlen(pos+2);
int2store(pos,tmp);
pos+=recinfo[1].length;
}
else
{
- strncpy(pos,data[n].f2,keyinfo[0].seg[0].length);
+ strnmov(pos,data[n].f2,keyinfo[0].seg[0].length);
pos+=recinfo[1].length;
}
}
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case 'v': verbose=1; break;
+ case 's': silent=1; break;
+ case 'F': no_fulltext=1; no_search=1;
+ case 'U': skip_update=1; break;
+ case 'K': no_keys=no_search=1; break;
+ case 'N': no_search=1; break;
+ case 'S': no_stopwords=1; break;
+ case '#':
+ DEBUGGER_ON;
+ DBUG_PUSH (argument);
+ break;
+ case 'V':
+ case '?':
+ case 'h':
+ usage();
+ exit(1);
+ }
+ return 0;
+}
+
/* Read options */
static void get_options(int argc,char *argv[])
{
- int c;
- const char *options="hVvsNSKFU#:";
+ int ho_error;
- while ((c=getopt(argc,argv,options)) != -1)
- {
- switch(c) {
- case 'v': verbose=1; break;
- case 's': silent=1; break;
- case 'F': no_fulltext=1; no_search=1;
- case 'U': skip_update=1; break;
- case 'K': no_keys=no_search=1; break;
- case 'N': no_search=1; break;
- case 'S': no_stopwords=1; break;
- case '#':
- DEBUGGER_ON;
- DBUG_PUSH (optarg);
- break;
- case 'V':
- case '?':
- case 'h':
- default:
- printf("%s -[%s]\n", argv[0], options);
- exit(0);
- }
- }
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
return;
} /* get options */
+
+
+static void usage()
+{
+ printf("%s [options]\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
diff --git a/myisam/ft_test1.h b/myisam/ft_test1.h
index 17b0cae66b7..e360244057b 100644
--- a/myisam/ft_test1.h
+++ b/myisam/ft_test1.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -419,4 +419,3 @@ const char *query[NQUERIES]={
"against about after more right the with/without", /* stopwords test */
"mysql license and copyright"
};
-
diff --git a/myisam/ft_update.c b/myisam/ft_update.c
index 753c4dc4029..a68cc2a4cf4 100644
--- a/myisam/ft_update.c
+++ b/myisam/ft_update.c
@@ -19,6 +19,7 @@
/* functions to work with full-text indices */
#include "ftdefs.h"
+#include <math.h>
/**************************************************************
This is to make ft-code to ignore keyseg.length at all *
@@ -27,46 +28,92 @@
#define set_if_smaller(A,B) /* no op */
/**************************************************************/
+void _mi_ft_segiterator_init(MI_INFO *info, uint keynr, const byte *record,
+ FT_SEG_ITERATOR *ftsi)
+{
+ ftsi->num=info->s->keyinfo[keynr].keysegs-FT_SEGS;
+ ftsi->seg=info->s->keyinfo[keynr].seg;
+ ftsi->rec=record;
+}
+
+void _mi_ft_segiterator_dummy_init(const byte *record, uint len,
+ FT_SEG_ITERATOR *ftsi)
+{
+ ftsi->num=1;
+ ftsi->seg=0;
+ ftsi->pos=record;
+ ftsi->len=len;
+}
+
+/*
+ This function breaks convention "return 0 in success"
+ but it's easier to use like this
+
+ while(_mi_ft_segiterator())
+
+ so "1" means "OK", "0" means "EOF"
+*/
-/* parses a document i.e. calls _mi_ft_parse for every keyseg */
-static FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, byte *keybuf,
- const byte *record)
+uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi)
{
- TREE *parsed=NULL;
- MI_KEYSEG *keyseg;
- byte *pos;
- uint i;
+ if (!ftsi->num) return 0; else ftsi->num--;
+ if (!ftsi->seg) return 1; else ftsi->seg--;
- keyseg=info->s->keyinfo[keynr].seg;
- for (i=info->s->keyinfo[keynr].keysegs-FT_SEGS ; i-- ; )
+ if (ftsi->seg->null_bit &&
+ (ftsi->rec[ftsi->seg->null_pos] & ftsi->seg->null_bit))
{
- uint len;
+ ftsi->pos=0;
+ return 1;
+ }
+ ftsi->pos= ftsi->rec+ftsi->seg->start;
+ if (ftsi->seg->flag & HA_VAR_LENGTH)
+ {
+ ftsi->len=uint2korr(ftsi->pos);
+ ftsi->pos+=2; /* Skip VARCHAR length */
+ set_if_smaller(ftsi->len,ftsi->seg->length);
+ return 1;
+ }
+ if (ftsi->seg->flag & HA_BLOB_PART)
+ {
+ ftsi->len=_mi_calc_blob_length(ftsi->seg->bit_start,ftsi->pos);
+ memcpy_fixed((char*) &ftsi->pos, ftsi->pos+ftsi->seg->bit_start,
+ sizeof(char*));
+ set_if_smaller(ftsi->len,ftsi->seg->length);
+ return 1;
+ }
+ ftsi->len=ftsi->seg->length;
+ return 1;
+}
- keyseg--;
- if (keyseg->null_bit && (record[keyseg->null_pos] & keyseg->null_bit))
- continue; /* NULL field */
- pos= (byte *)record+keyseg->start;
- if (keyseg->flag & HA_VAR_LENGTH)
- {
- len=uint2korr(pos);
- pos+=2; /* Skip VARCHAR length */
- set_if_smaller(len,keyseg->length);
- }
- else if (keyseg->flag & HA_BLOB_PART)
- {
- len=_mi_calc_blob_length(keyseg->bit_start,pos);
- memcpy_fixed(&pos,pos+keyseg->bit_start,sizeof(char*));
- set_if_smaller(len,keyseg->length);
- }
- else
- len=keyseg->length;
- if (!(parsed=ft_parse(parsed, pos, len)))
- return NULL;
+
+/* parses a document i.e. calls ft_parse for every keyseg */
+
+uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record)
+{
+ FT_SEG_ITERATOR ftsi;
+ _mi_ft_segiterator_init(info, keynr, record, &ftsi);
+
+ ft_parse_init(parsed, info->s->keyinfo[keynr].seg->charset);
+ while (_mi_ft_segiterator(&ftsi))
+ {
+ if (ftsi.pos)
+ if (ft_parse(parsed, (byte *)ftsi.pos, ftsi.len))
+ return 1;
}
- /* Handle the case where all columns are NULL */
- if (!parsed && !(parsed=ft_parse(0, (byte*) "", 0)))
+ return 0;
+}
+
+FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr,
+ byte *keybuf __attribute__((unused)),
+ const byte *record)
+{
+ TREE ptree;
+
+ bzero((char*) &ptree, sizeof(ptree));
+ if (_mi_ft_parse(&ptree, info, keynr, record))
return NULL;
- return ft_linearize(info, keynr, keybuf, parsed);
+
+ return ft_linearize(/*info, keynr, keybuf, */ &ptree);
}
static int _mi_ft_store(MI_INFO *info, uint keynr, byte *keybuf,
@@ -74,88 +121,110 @@ static int _mi_ft_store(MI_INFO *info, uint keynr, byte *keybuf,
{
uint key_length;
- while(wlist->pos)
+ for (; wlist->pos; wlist++)
{
key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos);
if (_mi_ck_write(info,keynr,(uchar*) keybuf,key_length))
return 1;
- wlist++;
}
return 0;
}
-static int _mi_ft_erase(MI_INFO *info, uint keynr, byte *keybuf, FT_WORD *wlist, my_off_t filepos)
+static int _mi_ft_erase(MI_INFO *info, uint keynr, byte *keybuf,
+ FT_WORD *wlist, my_off_t filepos)
{
uint key_length, err=0;
- while(wlist->pos)
+ for (; wlist->pos; wlist++)
{
key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos);
if (_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length))
err=1;
- wlist++;
}
return err;
}
-/* compares an appropriate parts of two WORD_KEY keys directly out of records */
-/* returns 1 if they are different */
+/*
+ Compares an appropriate parts of two WORD_KEY keys directly out of records
+ returns 1 if they are different
+*/
#define THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT 1
#define GEE_THEY_ARE_ABSOLUTELY_IDENTICAL 0
int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2)
{
- MI_KEYSEG *keyseg;
- byte *pos1, *pos2;
- uint i;
+ FT_SEG_ITERATOR ftsi1, ftsi2;
+ CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset;
+ _mi_ft_segiterator_init(info, keynr, rec1, &ftsi1);
+ _mi_ft_segiterator_init(info, keynr, rec2, &ftsi2);
- i=info->s->keyinfo[keynr].keysegs-FT_SEGS;
- keyseg=info->s->keyinfo[keynr].seg;
- while(i--)
+ while (_mi_ft_segiterator(&ftsi1) && _mi_ft_segiterator(&ftsi2))
{
- uint len1, len2;
- LINT_INIT(len1); LINT_INIT(len2);
- keyseg--;
- if (keyseg->null_bit)
- {
- if ( (rec1[keyseg->null_pos] ^ rec2[keyseg->null_pos])
- & keyseg->null_bit )
- return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT;
- if (rec1[keyseg->null_pos] & keyseg->null_bit )
- continue; /* NULL field */
- }
- pos1= (byte *)rec1+keyseg->start;
- pos2= (byte *)rec2+keyseg->start;
- if (keyseg->flag & HA_VAR_LENGTH)
- {
- len1=uint2korr(pos1);
- pos1+=2; /* Skip VARCHAR length */
- set_if_smaller(len1,keyseg->length);
- len2=uint2korr(pos2);
- pos2+=2; /* Skip VARCHAR length */
- set_if_smaller(len2,keyseg->length);
- }
- else if (keyseg->flag & HA_BLOB_PART)
+ if ((ftsi1.pos != ftsi2.pos) &&
+ (!ftsi1.pos || !ftsi2.pos ||
+ _mi_compare_text(cs, (uchar*) ftsi1.pos,ftsi1.len,
+ (uchar*) ftsi2.pos,ftsi2.len,0)))
+ return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT;
+ }
+ return GEE_THEY_ARE_ABSOLUTELY_IDENTICAL;
+}
+
+
+/* update a document entry */
+
+int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
+ const byte *oldrec, const byte *newrec, my_off_t pos)
+{
+ int error= -1;
+ FT_WORD *oldlist,*newlist, *old_word, *new_word;
+ CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset;
+ uint key_length;
+ int cmp, cmp2;
+
+ if (!(old_word=oldlist=_mi_ft_parserecord(info, keynr, keybuf, oldrec)))
+ goto err0;
+ if (!(new_word=newlist=_mi_ft_parserecord(info, keynr, keybuf, newrec)))
+ goto err1;
+
+ error=0;
+ while(old_word->pos && new_word->pos)
+ {
+ cmp=_mi_compare_text(cs, (uchar*) old_word->pos,old_word->len,
+ (uchar*) new_word->pos,new_word->len,0);
+ cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5);
+
+ if (cmp < 0 || cmp2)
{
- len1=_mi_calc_blob_length(keyseg->bit_start,pos1);
- memcpy_fixed(&pos1,pos1+keyseg->bit_start,sizeof(char*));
- set_if_smaller(len1,keyseg->length);
- len2=_mi_calc_blob_length(keyseg->bit_start,pos2);
- memcpy_fixed(&pos2,pos2+keyseg->bit_start,sizeof(char*));
- set_if_smaller(len2,keyseg->length);
+ key_length=_ft_make_key(info,keynr,keybuf,old_word,pos);
+ if ((error=_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length)))
+ goto err2;
}
- else /* fixed length key */
+ if (cmp > 0 || cmp2)
{
- len1=len2=keyseg->length;
+ key_length=_ft_make_key(info,keynr,keybuf,new_word,pos);
+ if ((error=_mi_ck_write(info,keynr,(uchar*) keybuf,key_length)))
+ goto err2;
}
- if ((len1 != len2) || memcmp(pos1, pos2, len1))
- return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT;
- }
- return GEE_THEY_ARE_ABSOLUTELY_IDENTICAL;
+ if (cmp<=0) old_word++;
+ if (cmp>=0) new_word++;
+ }
+ if (old_word->pos)
+ error=_mi_ft_erase(info,keynr,keybuf,old_word,pos);
+ else if (new_word->pos)
+ error=_mi_ft_store(info,keynr,keybuf,new_word,pos);
+
+err2:
+ my_free((char*) newlist,MYF(0));
+err1:
+ my_free((char*) oldlist,MYF(0));
+err0:
+ return error;
}
+
/* adds a document to the collection */
+
int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record,
my_off_t pos)
{
@@ -170,7 +239,9 @@ int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record,
return error;
}
+
/* removes a document from the collection */
+
int _mi_ft_del(MI_INFO *info, uint keynr, byte *keybuf, const byte *record,
my_off_t pos)
{
diff --git a/myisam/ftdefs.h b/myisam/ftdefs.h
index d9b4ff6b44d..62fa4362e19 100644
--- a/myisam/ftdefs.h
+++ b/myisam/ftdefs.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -22,15 +22,18 @@
#include <m_ctype.h>
#include <my_tree.h>
-#define MIN_WORD_LEN 4
-
#define HYPHEN_IS_DELIM
#define HYPHEN_IS_CONCAT /* not used for now */
#define COMPILE_STOPWORDS_IN
-/* Most of the formulae were shamelessly stolen from SMART distribution
- ftp://ftp.cs.cornell.edu/pub/smart/smart.11.0.tar.Z
+/* Interested readers may consult SMART
+ (ftp://ftp.cs.cornell.edu/pub/smart/smart.11.0.tar.Z)
+ for an excellent implementation of vector space model we use.
+ It also demonstrate the usage of different weghting techniques.
+ This code, though, is completely original and is not based on the
+ SMART code but was in some cases inspired by it.
+
NORM_PIVOT was taken from the article
A.Singhal, C.Buckley, M.Mitra, "Pivoted Document Length Normalization",
ACM SIGIR'96, 21-29, 1996
@@ -75,13 +78,26 @@ extern ulong collstat;
/* Mysterious, but w/o (double) GWS_IDF performs better :-o */
#define GWS_IDF log(aio->info->state->records/doc_cnt)
#define GWS_IDF1 log((double)aio->info->state->records/doc_cnt)
-#define GWS_PROB log(((double)(aio->info->state->records-doc_cnt))/doc_cnt)
+#define GWS_PROB ((aio->info->state->records > doc_cnt) ? log(((double)(aio->info->state->records-doc_cnt))/doc_cnt) : 0 )
#define GWS_FREQ (1.0/doc_cnt)
#define GWS_SQUARED pow(log((double)aio->info->state->records/doc_cnt),2)
#define GWS_CUBIC pow(log((double)aio->info->state->records/doc_cnt),3)
#define GWS_ENTROPY (1-(suml/sum-log(sum))/log(aio->info->state->records))
/*=================================================================*/
+/* Boolean search operators */
+#define FTB_YES (ft_boolean_syntax[0])
+#define FTB_EGAL (ft_boolean_syntax[1])
+#define FTB_NO (ft_boolean_syntax[2])
+#define FTB_INC (ft_boolean_syntax[3])
+#define FTB_DEC (ft_boolean_syntax[4])
+#define FTB_LBR (ft_boolean_syntax[5])
+#define FTB_RBR (ft_boolean_syntax[6])
+#define FTB_NEG (ft_boolean_syntax[7])
+#define FTB_TRUNC (ft_boolean_syntax[8])
+#define FTB_LQUOT (ft_boolean_syntax[10])
+#define FTB_RQUOT (ft_boolean_syntax[11])
+
typedef struct st_ft_word {
byte * pos;
uint len;
@@ -91,9 +107,52 @@ typedef struct st_ft_word {
#endif /* EVAL_RUN */
} FT_WORD;
+typedef struct st_ftb_param {
+ byte prev;
+ int yesno;
+ int plusminus;
+ bool pmsign;
+ bool trunc;
+ byte *quot;
+} FTB_PARAM;
+
int is_stopword(char *word, uint len);
uint _ft_make_key(MI_INFO *, uint , byte *, FT_WORD *, my_off_t);
-TREE * ft_parse(TREE *, byte *, int);
-FT_WORD * ft_linearize(MI_INFO *, uint, byte *, TREE *);
+byte ft_get_word(byte **, byte *, FT_WORD *, FTB_PARAM *);
+byte ft_simple_get_word(byte **, byte *, FT_WORD *);
+
+typedef struct _st_ft_seg_iterator {
+ uint num, len;
+ MI_KEYSEG *seg;
+ const byte *rec, *pos;
+} FT_SEG_ITERATOR;
+
+void _mi_ft_segiterator_init(MI_INFO *, uint, const byte *, FT_SEG_ITERATOR *);
+void _mi_ft_segiterator_dummy_init(const byte *, uint, FT_SEG_ITERATOR *);
+uint _mi_ft_segiterator(FT_SEG_ITERATOR *);
+
+void ft_parse_init(TREE *, CHARSET_INFO *);
+int ft_parse(TREE *, byte *, int);
+FT_WORD * ft_linearize(TREE *);
+FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, byte *, const byte *);
+uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record);
+
+extern const struct _ft_vft _ft_vft_nlq;
+FT_INFO *ft_init_nlq_search(MI_INFO *, uint, byte *, uint, my_bool);
+int ft_nlq_read_next(FT_INFO *, char *);
+float ft_nlq_find_relevance(FT_INFO *, byte *, uint);
+void ft_nlq_close_search(FT_INFO *);
+float ft_nlq_get_relevance(FT_INFO *);
+my_off_t ft_nlq_get_docid(FT_INFO *);
+void ft_nlq_reinit_search(FT_INFO *);
+
+extern const struct _ft_vft _ft_vft_boolean;
+FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint, my_bool);
+int ft_boolean_read_next(FT_INFO *, char *);
+float ft_boolean_find_relevance(FT_INFO *, byte *, uint);
+void ft_boolean_close_search(FT_INFO *);
+float ft_boolean_get_relevance(FT_INFO *);
+my_off_t ft_boolean_get_docid(FT_INFO *);
+void ft_boolean_reinit_search(FT_INFO *);
diff --git a/myisam/fulltext.h b/myisam/fulltext.h
index 8fcac8172b1..f787c9bcfe8 100644
--- a/myisam/fulltext.h
+++ b/myisam/fulltext.h
@@ -24,7 +24,6 @@
/* shoudn't be def'ed when linking with mysql */
#undef EVAL_RUN
-#define HA_FT_MAXLEN 254
#define HA_FT_WTYPE HA_KEYTYPE_FLOAT
#define HA_FT_WLEN 4
#ifdef EVAL_RUN
diff --git a/myisam/mi_cache.c b/myisam/mi_cache.c
index f88725ff04b..8dee068c50e 100644
--- a/myisam/mi_cache.c
+++ b/myisam/mi_cache.c
@@ -1,27 +1,40 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Functions for read record cacheing with myisam */
-/* Used instead of my_b_read() to allow for no-cacheed seeks */
+/*
+ Functions for read record cacheing with myisam
+ Used for reading dynamic/compressed records from datafile.
-#include "myisamdef.h"
+ Can fetch data directly from file (outside cache),
+ if reading a small chunk straight before the cached part (with possible
+ overlap).
+
+ Can be explicitly asked not to use cache (by not setting READING_NEXT in
+ flag) - useful for occasional out-of-cache reads, when the next read is
+ expected to hit the cache again.
- /* Copy block from cache if it`s in it. If re_read_if_possibly is */
- /* set read to cache (if after current file-position) else read to */
- /* buff */
+ Allows "partial read" errors in the record header (when READING_HEADER flag
+ is set) - unread part is bzero'ed
+
+ Note: out-of-cache reads are enabled for shared IO_CACHE's too,
+ as these reads will be cached by OS cache (and my_pread is always atomic)
+*/
+
+
+#include "myisamdef.h"
int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length,
int flag)
@@ -44,12 +57,13 @@ int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length,
pos+=read_length;
buff+=read_length;
}
- if ((offset= (my_off_t) (pos - info->pos_in_file)) <
- (my_off_t) (info->rc_end - info->rc_request_pos))
+ if (pos >= info->pos_in_file &&
+ (offset= (my_off_t) (pos - info->pos_in_file)) <
+ (my_off_t) (info->read_end - info->request_pos))
{
- in_buff_pos=info->rc_request_pos+(uint) offset;
- in_buff_length= min(length,(uint) (info->rc_end-in_buff_pos));
- memcpy(buff,info->rc_request_pos+(uint) offset,(size_t) in_buff_length);
+ in_buff_pos=info->request_pos+(uint) offset;
+ in_buff_length= min(length,(uint) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
if (!(length-=in_buff_length))
DBUG_RETURN(0);
pos+=in_buff_length;
@@ -60,38 +74,35 @@ int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length,
if (flag & READING_NEXT)
{
if (pos != (info->pos_in_file +
- (uint) (info->rc_end - info->rc_request_pos)))
+ (uint) (info->read_end - info->request_pos)))
{
info->pos_in_file=pos; /* Force start here */
- info->rc_pos=info->rc_end=info->rc_request_pos; /* Everything used */
+ info->read_pos=info->read_end=info->request_pos; /* Everything used */
info->seek_not_done=1;
}
else
- info->rc_pos=info->rc_end; /* All block used */
+ info->read_pos=info->read_end; /* All block used */
if (!(*info->read_function)(info,buff,length))
DBUG_RETURN(0);
- if (!(flag & READING_HEADER) || info->error == -1 ||
- (uint) info->error+in_buff_length < 3)
- {
- if (!my_errno || my_errno == -1)
- my_errno=HA_ERR_WRONG_IN_RECORD;
- DBUG_RETURN(1);
- }
- bzero(buff+info->error,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length -
- (uint) info->error);
- DBUG_RETURN(0);
+ read_length=info->error;
+ }
+ else
+ {
+ info->seek_not_done=1;
+ if ((read_length=my_pread(info->file,buff,length,pos,MYF(0))) == length)
+ DBUG_RETURN(0);
}
- info->seek_not_done=1;
- if ((read_length=my_pread(info->file,buff,length,pos,MYF(0))) == length)
- DBUG_RETURN(0);
if (!(flag & READING_HEADER) || (int) read_length == -1 ||
read_length+in_buff_length < 3)
{
+ DBUG_PRINT("error",
+ ("Error %d reading next-multi-part block (Got %d bytes)",
+ my_errno, (int) read_length));
if (!my_errno || my_errno == -1)
my_errno=HA_ERR_WRONG_IN_RECORD;
DBUG_RETURN(1);
}
bzero(buff+read_length,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length -
- read_length);
+ read_length);
DBUG_RETURN(0);
} /* _mi_read_cache */
diff --git a/myisam/mi_changed.c b/myisam/mi_changed.c
index bd6b14b0c6c..c2ab5568eba 100644
--- a/myisam/mi_changed.c
+++ b/myisam/mi_changed.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -24,7 +24,7 @@ int mi_is_changed(MI_INFO *info)
{
int result;
DBUG_ENTER("mi_is_changed");
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(-1);
VOID(_mi_writeinfo(info,0));
result=(int) info->data_changed;
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 89fcfe74cea..8581f79c99d 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -14,14 +14,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Descript, check and repair of ISAM tables */
+/* Describe, check and repair of MyISAM tables */
-#include "fulltext.h"
+#include "ftdefs.h"
#include <m_ctype.h>
#include <stdarg.h>
-#include <getopt.h>
+#include <my_getopt.h>
#include <assert.h>
-#ifdef HAVE_SYS_VADVICE_H
+#ifdef HAVE_SYS_VADVISE_H
#include <sys/vadvise.h>
#endif
#ifdef HAVE_SYS_MMAN_H
@@ -36,7 +36,7 @@
/* Functions defined in this file */
static int check_k_link(MI_CHECK *param, MI_INFO *info,uint nr);
-static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
+static int chk_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
my_off_t page, uchar *buff, ha_rows *keys,
ha_checksum *key_checksum, uint level);
static uint isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo);
@@ -45,25 +45,22 @@ static int writekeys(MI_CHECK *param, MI_INFO *info,byte *buff,
my_off_t filepos);
static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
my_off_t pagepos, File new_file);
-static int sort_key_read(SORT_INFO *sort_info,void *key);
-static int sort_get_next_record(SORT_INFO *sort_info);
-static int sort_key_cmp(SORT_INFO *sort_info, const void *a,const void *b);
-static int sort_key_write(SORT_INFO *sort_info, const void *a);
+static int sort_key_read(MI_SORT_PARAM *sort_param,void *key);
+static int sort_ft_key_read(MI_SORT_PARAM *sort_param,void *key);
+static int sort_get_next_record(MI_SORT_PARAM *sort_param);
+static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,const void *b);
+static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a);
static my_off_t get_record_for_key(MI_INFO *info,MI_KEYDEF *keyinfo,
uchar *key);
-static int sort_insert_key(MI_CHECK *param, reg1 SORT_KEY_BLOCKS *key_block,
+static int sort_insert_key(MI_SORT_PARAM *sort_param,
+ reg1 SORT_KEY_BLOCKS *key_block,
uchar *key, my_off_t prev_block);
-static int sort_delete_record(MI_CHECK *param);
-static int flush_pending_blocks(MI_CHECK *param);
+static int sort_delete_record(MI_SORT_PARAM *sort_param);
+/*static int flush_pending_blocks(MI_CHECK *param);*/
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks,
uint buffer_length);
-static void update_key_parts(MI_KEYDEF *keyinfo,
- ulong *rec_per_key_part,
- ulonglong *unique,
- ulonglong records);
static ha_checksum mi_byte_checksum(const byte *buf, uint length);
-static void set_data_file_type(MI_CHECK *param, SORT_INFO *info,
- MYISAM_SHARE *share);
+static void set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share);
#ifdef __WIN__
static double ulonglong2double(ulonglong value)
@@ -79,7 +76,7 @@ static double ulonglong2double(ulonglong value)
#else
#define my_off_t2double(A) ((double) (A))
#endif /* SIZEOF_OFF_T > 4 */
-#endif
+#endif /* __WIN__ */
void myisamchk_init(MI_CHECK *param)
{
@@ -95,7 +92,6 @@ void myisamchk_init(MI_CHECK *param)
param->sort_key_blocks=BUFFERS_WHEN_SORTING;
param->tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL;
param->myf_rw=MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL);
- param->sort_info.param=param;
param->start_check_pos=0;
}
@@ -104,6 +100,7 @@ void myisamchk_init(MI_CHECK *param)
int chk_status(MI_CHECK *param, register MI_INFO *info)
{
MYISAM_SHARE *share=info->s;
+
if (mi_is_crashed_on_repair(info))
mi_check_print_warning(param,
"Table is marked as crashed and last repair failed");
@@ -129,20 +126,13 @@ int chk_status(MI_CHECK *param, register MI_INFO *info)
int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag)
{
reg2 ha_rows i;
- uint j,delete_link_length;
+ uint delete_link_length;
my_off_t empty,next_link,old_link;
char buff[22],buff2[22];
DBUG_ENTER("chk_del");
- if (!(test_flag & T_SILENT))
- puts("- check key delete-chain");
-
LINT_INIT(old_link);
param->record_checksum=0;
- param->key_file_blocks=info->s->base.keystart;
- for (j=0 ; j < info->s->state.header.max_block_size ; j++)
- if (check_k_link(param,info,j))
- goto wrong;
delete_link_length=((info->s->options & HA_OPTION_PACK_RECORD) ? 20 :
info->s->rec_reflength+1);
@@ -203,23 +193,35 @@ int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag)
empty+=info->s->base.pack_reclength;
}
}
+ if (test_flag & T_VERBOSE)
+ puts("\n");
if (empty != info->state->empty)
{
- if (test_flag & T_VERBOSE) puts("");
mi_check_print_warning(param,
- "Not used space is supposed to be: %s but is: %s",
- llstr(info->state->empty,buff),
- llstr(empty,buff2));
- info->state->empty=empty;
+ "Found %s deleted space in delete link chain. Should be %s",
+ llstr(empty,buff2),
+ llstr(info->state->empty,buff));
+ }
+ if (next_link != HA_OFFSET_ERROR)
+ {
+ mi_check_print_error(param,
+ "Found more than the expected %s deleted rows in delete link chain",
+ llstr(info->state->del, buff));
+ goto wrong;
}
- if (i != 0 || next_link != HA_OFFSET_ERROR)
+ if (i != 0)
+ {
+ mi_check_print_error(param,
+ "Found %s deleted rows in delete link chain. Should be %s",
+ llstr(info->state->del - i, buff2),
+ llstr(info->state->del, buff));
goto wrong;
-
- if (test_flag & T_VERBOSE) puts("\n");
+ }
}
DBUG_RETURN(0);
+
wrong:
- param->retry_without_quick=1; /* Don't use quick repair */
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
if (test_flag & T_VERBOSE) puts("");
mi_check_print_error(param,"record delete-link-chain corrupted");
DBUG_RETURN(1);
@@ -231,7 +233,7 @@ wrong:
static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
{
my_off_t next_link;
- uint block_size=(nr+1)*MI_KEY_BLOCK_LENGTH;
+ uint block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH;
ha_rows records;
char llbuff[21],*buff;
DBUG_ENTER("check_k_link");
@@ -319,7 +321,7 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
error=1;
mi_check_print_error(param,"Size of datafile is: %-9s Should be: %s",
llstr(size,buff), llstr(skr,buff2));
- param->retry_without_quick=1; /* Don't use quick repair */
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
}
else
{
@@ -353,6 +355,18 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
char buff[22],buff2[22];
DBUG_ENTER("chk_key");
+ if (!(param->testflag & T_SILENT))
+ puts("- check key delete-chain");
+
+ param->key_file_blocks=info->s->base.keystart;
+ for (key=0 ; key < info->s->state.header.max_block_size ; key++)
+ if (check_k_link(param,info,key))
+ {
+ if (param->testflag & T_VERBOSE) puts("");
+ mi_check_print_error(param,"key delete-link-chain corrupted");
+ DBUG_RETURN(-1);
+ }
+
if (!(param->testflag & T_SILENT)) puts("- check index reference");
all_keydata=all_totaldata=key_totlength=0;
@@ -371,8 +385,8 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
{
/* Remember old statistics for key */
memcpy((char*) rec_per_key_part,
- (char*) share->state.rec_per_key_part+
- (uint) (rec_per_key_part - param->rec_per_key_part),
+ (char*) (share->state.rec_per_key_part +
+ (uint) (rec_per_key_part - param->rec_per_key_part)),
keyinfo->keysegs*sizeof(*rec_per_key_part));
continue;
}
@@ -458,7 +472,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
info->s->state.auto_increment=save_auto_value;
/* Check that there isn't a row with auto_increment = 0 in the table */
- mi_extra(info,HA_EXTRA_KEYREAD);
+ mi_extra(info,HA_EXTRA_KEYREAD,0);
bzero(info->lastkey,keyinfo->seg->length);
if (!mi_rkey(info, info->rec_buff, key, (const byte*) info->lastkey,
keyinfo->seg->length, HA_READ_KEY_EXACT))
@@ -469,7 +483,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
"Found row where the auto_increment column has the value 0");
param->warning_printed=save;
}
- mi_extra(info,HA_EXTRA_NO_KEYREAD);
+ mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
}
length=(my_off_t) isam_key_length(info,keyinfo)*keys + param->key_blocks*2;
@@ -604,7 +618,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
if (*keys != 1L) /* not first_key */
{
uint diff;
- _mi_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,SEARCH_FIND,
+ _mi_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
+ SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
&diff);
param->unique_count[diff-1]++;
}
@@ -843,7 +858,8 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
}
if (info->s->base.blobs)
{
- if (!(to=mi_fix_rec_buff_for_blob(info,block_info.rec_len)))
+ if (!(to= mi_alloc_rec_buff(info, block_info.rec_len,
+ &info->rec_buff)))
{
mi_check_print_error(param,"Not enough memory for blob at %s",
llstr(start_recpos,llbuff));
@@ -874,15 +890,19 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
{
if (b_type & BLOCK_LAST)
{
- mi_check_print_error(param,"Record link to short for record at %s",
- llstr(start_recpos,llbuff));
+ mi_check_print_error(param,
+ "Wrong record length %s of %s at %s",
+ llstr(block_info.rec_len-left_length,llbuff),
+ llstr(block_info.rec_len, llbuff2),
+ llstr(start_recpos,llbuff3));
got_error=1;
break;
}
if (info->state->data_file_length < block_info.next_filepos)
{
- mi_check_print_error(param,"Found next-recordlink that points outside datafile at %s",
- llstr(block_info.filepos,llbuff));
+ mi_check_print_error(param,
+ "Found next-recordlink that points outside datafile at %s",
+ llstr(block_info.filepos,llbuff));
got_error=1;
break;
}
@@ -893,7 +913,8 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
if (_mi_rec_unpack(info,record,info->rec_buff,block_info.rec_len) ==
MY_FILE_ERROR)
{
- mi_check_print_error(param,"Found wrong record at %s", llstr(start_recpos,llbuff));
+ mi_check_print_error(param,"Found wrong record at %s",
+ llstr(start_recpos,llbuff));
got_error=1;
}
else
@@ -901,7 +922,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
info->checksum=mi_checksum(info,record);
if (param->testflag & (T_EXTEND | T_MEDIUM | T_VERBOSE))
{
- if (_mi_rec_check(info,record))
+ if (_mi_rec_check(info,record, info->rec_buff,block_info.rec_len))
{
mi_check_print_error(param,"Found wrong packed record at %s",
llstr(start_recpos,llbuff));
@@ -921,7 +942,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
goto err;
start_recpos=pos;
splits++;
- VOID(_mi_pack_get_block_info(info,&block_info, -1, start_recpos, NullS));
+ VOID(_mi_pack_get_block_info(info,&block_info, -1, start_recpos));
pos=block_info.filepos+block_info.rec_len;
if (block_info.rec_len < (uint) info->s->min_pack_length ||
block_info.rec_len > (uint) info->s->max_pack_length)
@@ -1036,6 +1057,13 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
}
}
+ if (del_length != info->state->empty)
+ {
+ mi_check_print_warning(param,
+ "Found %s deleted space. Should be %s",
+ llstr(del_length,llbuff2),
+ llstr(info->state->empty,llbuff));
+ }
if (used+empty+del_length != info->state->data_file_length)
{
mi_check_print_warning(param,
@@ -1068,7 +1096,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
if (used != 0 && ! param->error_printed)
{
printf("Records:%18s M.recordlength:%9lu Packed:%14.0f%%\n",
- llstr(records,llbuff), (long)((used-link_used)/records),
+ llstr(records,llbuff), (long)((used-link_used)/records),
(info->s->base.blobs ? 0.0 :
(ulonglong2double((ulonglong) info->s->base.reclength*records)-
my_off_t2double(used))/
@@ -1092,7 +1120,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
mi_check_print_error(param,"got error: %d when reading datafile at record: %s",my_errno, llstr(records,llbuff));
err2:
my_free((gptr) record,MYF(0));
- param->retry_without_quick=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(1);
} /* chk_data_link */
@@ -1110,38 +1138,48 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
File new_file;
MYISAM_SHARE *share=info->s;
char llbuff[22],llbuff2[22];
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO sort_info;
+ MI_SORT_PARAM sort_param;
DBUG_ENTER("mi_repair");
- sort_info->buff=sort_info->record=0;
+ bzero((char *)&sort_info, sizeof(sort_info));
+ bzero((char *)&sort_param, sizeof(sort_param));
start_records=info->state->records;
new_header_length=(param->testflag & T_UNPACK) ? 0L :
share->pack.header_length;
got_error=1;
new_file= -1;
+ sort_param.sort_info=&sort_info;
+
if (!(param->testflag & T_SILENT))
{
printf("- recovering (with keycache) MyISAM-table '%s'\n",name);
printf("Data records: %s\n", llstr(info->state->records,llbuff));
}
+ param->testflag|=T_REP; /* for easy checking */
+
+ if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
+ param->testflag|=T_CALC_CHECKSUM;
if (!param->using_global_keycache)
- VOID(init_key_cache(param->use_buffers,NEAD_MEM));
+ VOID(init_key_cache(param->use_buffers));
if (init_io_cache(&param->read_cache,info->dfile,
(uint) param->read_buffer_length,
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)))
+ {
+ bzero(&info->rec_cache,sizeof(info->rec_cache));
goto err;
+ }
if (!rep_quick)
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
WRITE_CACHE, new_header_length, 1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
goto err;
info->opt_flag|=WRITE_CACHE_USED;
- sort_info->start_recpos=0;
- sort_info->buff=0; sort_info->buff_length=0;
- if (!(sort_info->record=(byte*) my_malloc((uint) share->base.pack_reclength,
- MYF(0))))
+ if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
+ MYF(0))) ||
+ !mi_alloc_rec_buff(info, -1, &sort_param.rec_buff))
{
mi_check_print_error(param,"Not enough memory for extra record");
goto err;
@@ -1149,9 +1187,10 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
if (!rep_quick)
{
- if ((new_file=my_raid_create(fn_format(param->temp_filename,name,"",
- DATA_TMP_EXT,
- 2+4),
+ /* Get real path for data file */
+ if ((new_file=my_raid_create(fn_format(param->temp_filename,
+ share->data_file_name, "",
+ DATA_TMP_EXT, 2+4),
0,param->tmpfile_createflag,
share->base.raid_type,
share->base.raid_chunks,
@@ -1173,16 +1212,19 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
mi_int2store(share->state.header.options,share->options);
}
}
- sort_info->info=info;
- sort_info->pos=sort_info->max_pos=share->pack.header_length;
- sort_info->filepos=new_header_length;
- param->read_cache.end_of_file=sort_info->filelength=
+ sort_info.info=info;
+ sort_info.param = param;
+ sort_param.read_cache=param->read_cache;
+ sort_param.pos=sort_param.max_pos=share->pack.header_length;
+ sort_param.filepos=new_header_length;
+ param->read_cache.end_of_file=sort_info.filelength=
my_seek(info->dfile,0L,MY_SEEK_END,MYF(0));
- sort_info->dupp=0;
- sort_info->fix_datafile= (my_bool) (! rep_quick);
- sort_info->max_records= ~(ha_rows) 0;
+ sort_info.dupp=0;
+ sort_param.fix_datafile= (my_bool) (! rep_quick);
+ sort_param.master=1;
+ sort_info.max_records= ~(ha_rows) 0;
- set_data_file_type(param, sort_info, share);
+ set_data_file_type(&sort_info, share);
del=info->state->del;
info->state->records=info->state->del=share->state.split=0;
info->state->empty=0;
@@ -1196,10 +1238,11 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
for (i=0 ; i < share->state.header.max_block_size ; i++)
share->state.key_del[i]= HA_OFFSET_ERROR;
- /* I think mi_repair and mi_repair_by_sort should do the same
- (according, e.g. to ha_myisam::repair), but as mi_repair doesn't
- touch key_map it cannot be used to T_CREATE_MISSING_KEYS.
- That is the next line for... (serg)
+ /*
+ I think mi_repair and mi_repair_by_sort should do the same
+ (according, e.g. to ha_myisam::repair), but as mi_repair doesn't
+ touch key_map it cannot be used to T_CREATE_MISSING_KEYS.
+ That is what the next line is for... (serg)
*/
share->state.key_map= ((((ulonglong) 1L << share->base.keys)-1) &
@@ -1208,36 +1251,37 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
info->state->key_file_length=share->base.keystart;
lock_memory(param); /* Everything is alloced */
- while (!(error=sort_get_next_record(sort_info)))
+ while (!(error=sort_get_next_record(&sort_param)))
{
- if (writekeys(param, info,(byte*) sort_info->record,sort_info->filepos))
+ if (writekeys(param,info,(byte*)sort_param.record,sort_param.filepos))
{
if (my_errno != HA_ERR_FOUND_DUPP_KEY)
goto err;
- DBUG_DUMP("record",(byte*) sort_info->record,share->base.pack_reclength);
+ DBUG_DUMP("record",(byte*) sort_param.record,share->base.pack_reclength);
mi_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s",
info->errkey+1,
- llstr(sort_info->start_recpos,llbuff),
+ llstr(sort_param.start_recpos,llbuff),
llstr(info->dupp_key_pos,llbuff2));
if (param->testflag & T_VERBOSE)
{
VOID(_mi_make_key(info,(uint) info->errkey,info->lastkey,
- sort_info->record,0L));
+ sort_param.record,0L));
_mi_print_key(stdout,share->keyinfo[info->errkey].seg,info->lastkey,
USE_WHOLE_KEY);
}
- sort_info->dupp++;
- if (rep_quick == 1)
+ sort_info.dupp++;
+ if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK)
{
- param->error_printed=param->retry_without_quick=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
+ param->error_printed=1;
goto err;
}
continue;
}
- if (sort_write_record(sort_info))
+ if (sort_write_record(&sort_param))
goto err;
}
- if (error > 0 || write_data_suffix(param,info) ||
+ if (error > 0 || write_data_suffix(&sort_info, (my_bool)!rep_quick) ||
flush_io_cache(&info->rec_cache) || param->read_cache.error < 0)
goto err;
@@ -1245,7 +1289,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
{
VOID(fputs(" \r",stdout)); VOID(fflush(stdout));
}
- if (my_chsize(share->kfile,info->state->key_file_length,MYF(0)))
+ if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0)))
{
mi_check_print_warning(param,
"Can't change size of indexfile, error: %d",
@@ -1253,12 +1297,13 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
goto err;
}
- if (rep_quick && del+sort_info->dupp != info->state->del)
+ if (rep_quick && del+sort_info.dupp != info->state->del)
{
mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
mi_check_print_error(param,"Run recovery again without -q");
got_error=1;
- param->retry_repair=param->retry_without_quick=1;
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
goto err;
}
if (param->testflag & T_SAFE_REPAIR)
@@ -1276,14 +1321,12 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
{
my_close(info->dfile,MYF(0));
info->dfile=new_file;
- info->state->data_file_length=sort_info->filepos;
- /* Only whole records */
- share->state.split=info->state->records+info->state->del;
+ info->state->data_file_length=sort_param.filepos;
share->state.version=(ulong) time((time_t*) 0); /* Force reopen */
}
else
{
- info->state->data_file_length=sort_info->max_pos;
+ info->state->data_file_length=sort_param.max_pos;
}
if (param->testflag & T_CALC_CHECKSUM)
share->state.checksum=param->glob_crc;
@@ -1292,10 +1335,10 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
{
if (start_records != info->state->records)
printf("Data records: %s\n", llstr(info->state->records,llbuff));
- if (sort_info->dupp)
+ if (sort_info.dupp)
mi_check_print_warning(param,
"%s records have been removed",
- llstr(sort_info->dupp,llbuff));
+ llstr(sort_info.dupp,llbuff));
}
got_error=0;
@@ -1311,11 +1354,11 @@ err:
{
my_close(new_file,MYF(0));
info->dfile=new_file= -1;
- if (change_to_newfile(share->filename,MI_NAME_DEXT,
+ if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
- mi_open_datafile(info,share))
+ mi_open_datafile(info,share,-1))
got_error=1;
}
}
@@ -1323,17 +1366,20 @@ err:
{
if (! param->error_printed)
mi_check_print_error(param,"%d for record at pos %s",my_errno,
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param.start_recpos,llbuff));
if (new_file >= 0)
{
VOID(my_close(new_file,MYF(0)));
VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks,
MYF(MY_WME)));
+ info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */
}
mi_mark_crashed_on_repair(info);
}
- my_free(sort_info->record,MYF(MY_ALLOW_ZERO_PTR));
- my_free(sort_info->buff,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff),
+ MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
VOID(end_io_cache(&info->rec_cache));
@@ -1342,7 +1388,7 @@ err:
{
share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
share->pack.header_length=0;
- share->data_file_type=sort_info->new_data_file_type;
+ share->data_file_type=sort_info.new_data_file_type;
}
share->state.changed|= (STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES |
STATE_NOT_ANALYZED);
@@ -1494,6 +1540,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
File new_file;
my_off_t index_pos[MI_MAX_POSSIBLE_KEY];
uint r_locks,w_locks;
+ int old_lock;
MYISAM_SHARE *share=info->s;
MI_STATE_INFO old_state;
DBUG_ENTER("sort_index");
@@ -1501,8 +1548,10 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
if (!(param->testflag & T_SILENT))
printf("- Sorting index for MyISAM-table '%s'\n",name);
- if ((new_file=my_create(fn_format(param->temp_filename,name,"",
- INDEX_TMP_EXT,2+4),
+ /* Get real path for index file */
+ fn_format(param->temp_filename,name,"", MI_NAME_IEXT,2+4+32);
+ if ((new_file=my_create(fn_format(param->temp_filename,param->temp_filename,
+ "", INDEX_TMP_EXT,2+4),
0,param->tmpfile_createflag,MYF(0))) <= 0)
{
mi_check_print_error(param,"Can't create new tempfile: '%s'",
@@ -1522,7 +1571,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
if (share->state.key_root[key] != HA_OFFSET_ERROR)
{
- index_pos[key]=param->new_file_pos; /* Write first block here */
+ index_pos[key]=param->new_file_pos; /* Write first block here */
if (sort_one_index(param,info,keyinfo,share->state.key_root[key],
new_file))
goto err;
@@ -1535,23 +1584,28 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
share->state.version=(ulong) time((time_t*) 0);
- old_state=share->state; /* save state if not stored */
- r_locks=share->r_locks; w_locks=share->w_locks;
+ old_state= share->state; /* save state if not stored */
+ r_locks= share->r_locks;
+ w_locks= share->w_locks;
+ old_lock= info->lock_type;
+
/* Put same locks as old file */
- share->r_locks=share->w_locks=0;
+ share->r_locks= share->w_locks= share->tot_locks= 0;
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
VOID(my_close(share->kfile,MYF(MY_WME)));
share->kfile = -1;
VOID(my_close(new_file,MYF(MY_WME)));
- if (change_to_newfile(share->filename,MI_NAME_IEXT,INDEX_TMP_EXT,0,
+ if (change_to_newfile(share->index_file_name,MI_NAME_IEXT,INDEX_TMP_EXT,0,
MYF(0)) ||
mi_open_keyfile(share))
goto err2;
- info->lock_type=F_UNLCK; /* Force mi_readinfo to lock */
+ info->lock_type= F_UNLCK; /* Force mi_readinfo to lock */
_mi_readinfo(info,F_WRLCK,0); /* Will lock the table */
- info->lock_type=F_WRLCK;
- share->r_locks=r_locks; share->w_locks=w_locks;
- share->state=old_state; /* Restore old state */
+ info->lock_type= old_lock;
+ share->r_locks= r_locks;
+ share->w_locks= w_locks;
+ share->tot_locks= r_locks+w_locks;
+ share->state= old_state; /* Restore old state */
info->state->key_file_length=param->new_file_pos;
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
@@ -1643,9 +1697,14 @@ err:
} /* sort_one_index */
- /* Change to use new file */
- /* Copy stats from old file to new file, deletes orginal and */
- /* changes new file name to old file name */
+ /*
+ Let temporary file replace old file.
+ This assumes that the new file was created in the same
+ directory as given by realpath(filename).
+ This will ensure that any symlinks that are used will still work.
+ Copy stats from old file to new file, deletes orignal and
+ changes new file name to old file name
+ */
int change_to_newfile(const char * filename, const char * old_ext,
const char * new_ext,
@@ -1660,8 +1719,10 @@ int change_to_newfile(const char * filename, const char * old_ext,
raid_chunks,
MYF(MY_WME | MY_LINK_WARNING | MyFlags));
#endif
- return my_redel(fn_format(old_filename,filename,"",old_ext,2+4),
- fn_format(new_filename,filename,"",new_ext,2+4),
+ /* Get real path to filename */
+ (void) fn_format(old_filename,filename,"",old_ext,2+4+32);
+ return my_redel(old_filename,
+ fn_format(new_filename,old_filename,"",new_ext,2+4),
MYF(MY_WME | MY_LINK_WARNING | MyFlags));
} /* change_to_newfile */
@@ -1721,8 +1782,21 @@ err:
DBUG_RETURN(1);
}
- /* Fix table or given index using sorting */
- /* saves new table in temp_filename */
+
+/*
+ Repair table or given index using sorting
+
+ SYNOPSIS
+ mi_repair_by_sort()
+ param Repair parameters
+ info MyISAM handler to repair
+ name Name of table (for warnings)
+ rep_quick set to <> 0 if we should not change data file
+
+ RESULT
+ 0 ok
+ <>0 Error
+*/
int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
const char * name, int rep_quick)
@@ -1735,9 +1809,10 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
File new_file;
MI_SORT_PARAM sort_param;
MYISAM_SHARE *share=info->s;
+ MI_KEYSEG *keyseg;
ulong *rec_per_key_part;
char llbuff[22];
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO sort_info;
ulonglong key_map=share->state.key_map;
DBUG_ENTER("mi_repair_by_sort");
@@ -1751,25 +1826,14 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
printf("- recovering (with sort) MyISAM-table '%s'\n",name);
printf("Data records: %s\n", llstr(start_records,llbuff));
}
+ param->testflag|=T_REP; /* for easy checking */
- /* Hmm, repair_by_sort uses find_all_keys, and find_all_keys strictly
- implies "one row - one key per keynr", while for ft_key one row/keynr
- can produce as many keys as the number of unique words in the text
- that's why I disabled repair_by_sort for ft-keys. (serg)
- */
- for (i=0 ; i < share->base.keys ; i++)
- {
- if ((((ulonglong) 1 << i) & key_map) &&
- (share->keyinfo[i].flag & HA_FULLTEXT))
- {
- mi_check_print_error(param,
- "Can`t use repair_by_sort with FULLTEXT key");
- DBUG_RETURN(1);
- }
- }
+ if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
+ param->testflag|=T_CALC_CHECKSUM;
- bzero((char*) sort_info,sizeof(*sort_info));
- if (!(sort_info->key_block=
+ bzero((char*)&sort_info,sizeof(sort_info));
+ bzero((char *)&sort_param, sizeof(sort_param));
+ if (!(sort_info.key_block=
alloc_key_blocks(param,
(uint) param->sort_key_blocks,
share->base.max_key_block_length))
@@ -1782,21 +1846,23 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
WRITE_CACHE,new_header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw)))
goto err;
- sort_info->key_block_end=sort_info->key_block+param->sort_key_blocks;
+ sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
info->opt_flag|=WRITE_CACHE_USED;
info->rec_cache.file=info->dfile; /* for sort_delete_record */
- if (!(sort_info->record=(byte*) my_malloc((uint) share->base.pack_reclength,
- MYF(0))))
+ if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
+ MYF(0))) ||
+ !mi_alloc_rec_buff(info, -1, &sort_param.rec_buff))
{
mi_check_print_error(param,"Not enough memory for extra record");
goto err;
}
if (!rep_quick)
{
- if ((new_file=my_raid_create(fn_format(param->temp_filename,name,"",
- DATA_TMP_EXT,
- 2+4),
+ /* Get real path for data file */
+ if ((new_file=my_raid_create(fn_format(param->temp_filename,
+ share->data_file_name, "",
+ DATA_TMP_EXT, 2+4),
0,param->tmpfile_createflag,
share->base.raid_type,
share->base.raid_chunks,
@@ -1841,32 +1907,34 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
key_map= ~key_map; /* Create the missing keys */
}
- sort_info->info=info;
- sort_info->param = param;
+ sort_info.info=info;
+ sort_info.param = param;
- set_data_file_type(param, sort_info, share);
- sort_info->filepos=new_header_length;
- sort_info->dupp=0;
- sort_info->buff=0;
- param->read_cache.end_of_file=sort_info->filelength=
+ set_data_file_type(&sort_info, share);
+ sort_param.filepos=new_header_length;
+ sort_info.dupp=0;
+ sort_info.buff=0;
+ param->read_cache.end_of_file=sort_info.filelength=
my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+ sort_param.wordlist=NULL;
+
if (share->data_file_type == DYNAMIC_RECORD)
length=max(share->base.min_pack_length+1,share->base.min_block_length);
else if (share->data_file_type == COMPRESSED_RECORD)
length=share->base.min_block_length;
else
length=share->base.pack_reclength;
- sort_param.max_records=sort_info->max_records=
- ((param->testflag & T_TRUST_HEADER) ? info->state->records :
- (ha_rows) (sort_info->filelength/length+1));
+ sort_info.max_records=
+ ((param->testflag & T_CREATE_MISSING_KEYS) ? info->state->records :
+ (ha_rows) (sort_info.filelength/length+1));
sort_param.key_cmp=sort_key_cmp;
sort_param.key_write=sort_key_write;
- sort_param.key_read=sort_key_read;
sort_param.lock_in_memory=lock_memory;
sort_param.tmpdir=param->tmpdir;
- sort_param.myf_rw=param->myf_rw;
- sort_param.sort_info=sort_info;
+ sort_param.sort_info=&sort_info;
+ sort_param.fix_datafile= (my_bool) (! rep_quick);
+ sort_param.master =1;
del=info->state->del;
param->glob_crc=0;
@@ -1874,40 +1942,51 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
param->calc_checksum=1;
rec_per_key_part= param->rec_per_key_part;
- for (sort_info->key=0 ; sort_info->key < share->base.keys ;
- rec_per_key_part+=sort_info->keyinfo->keysegs, sort_info->key++)
+ for (sort_param.key=0 ; sort_param.key < share->base.keys ;
+ rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++)
{
- sort_info->keyinfo=share->keyinfo+sort_info->key;
- if (!(((ulonglong) 1 << sort_info->key) & key_map))
+ sort_param.read_cache=param->read_cache;
+ sort_param.keyinfo=share->keyinfo+sort_param.key;
+ if (!(((ulonglong) 1 << sort_param.key) & key_map))
{
/* Remember old statistics for key */
memcpy((char*) rec_per_key_part,
- (char*) share->state.rec_per_key_part+
- (uint) (rec_per_key_part - param->rec_per_key_part),
- sort_info->keyinfo->keysegs*sizeof(*rec_per_key_part));
+ (char*) (share->state.rec_per_key_part +
+ (uint) (rec_per_key_part - param->rec_per_key_part)),
+ sort_param.keyinfo->keysegs*sizeof(*rec_per_key_part));
continue;
}
if ((!(param->testflag & T_SILENT)))
- printf ("- Fixing index %d\n",sort_info->key+1);
- sort_info->max_pos=sort_info->pos=share->pack.header_length;
- sort_info->keyseg=sort_info->keyinfo->seg;
- sort_info->fix_datafile= (my_bool) (sort_info->key == 0 && ! rep_quick);
- bzero((char*) sort_info->unique,sizeof(sort_info->unique));
+ printf ("- Fixing index %d\n",sort_param.key+1);
+ sort_param.max_pos=sort_param.pos=share->pack.header_length;
+ keyseg=sort_param.keyinfo->seg;
+ bzero((char*) sort_param.unique,sizeof(sort_param.unique));
sort_param.key_length=share->rec_reflength;
- for (i=0 ; sort_info->keyseg[i].type != HA_KEYTYPE_END; i++)
- {
- sort_param.key_length+=sort_info->keyseg[i].length;
- if (sort_info->keyseg[i].flag & HA_SPACE_PACK)
- sort_param.key_length+=get_pack_length(sort_info->keyseg[i].length);
- if (sort_info->keyseg[i].flag & (HA_BLOB_PART | HA_VAR_LENGTH))
- sort_param.key_length+=2 + test(sort_info->keyseg[i].length >= 127);
- if (sort_info->keyseg[i].flag & HA_NULL_PART)
+ for (i=0 ; keyseg[i].type != HA_KEYTYPE_END; i++)
+ {
+ sort_param.key_length+=keyseg[i].length;
+ if (keyseg[i].flag & HA_SPACE_PACK)
+ sort_param.key_length+=get_pack_length(keyseg[i].length);
+ if (keyseg[i].flag & (HA_BLOB_PART | HA_VAR_LENGTH))
+ sort_param.key_length+=2 + test(keyseg[i].length >= 127);
+ if (keyseg[i].flag & HA_NULL_PART)
sort_param.key_length++;
}
info->state->records=info->state->del=share->state.split=0;
info->state->empty=0;
+ if (sort_param.keyinfo->flag & HA_FULLTEXT)
+ {
+ sort_info.max_records=
+ (ha_rows) (sort_info.filelength/ft_max_word_len_for_sort+1);
+
+ sort_param.key_read=sort_ft_key_read;
+ sort_param.key_length+=ft_max_word_len_for_sort-HA_FT_MAXLEN;
+ }
+ else
+ sort_param.key_read=sort_key_read;
+
if (_create_index_by_sort(&sort_param,
(my_bool) (!(param->testflag & T_VERBOSE)),
(uint) param->sort_buffer_length))
@@ -1918,18 +1997,17 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
param->calc_checksum=0; /* No need to calc glob_crc */
/* Set for next loop */
- sort_param.max_records=sort_info->max_records=
- (ha_rows) info->state->records;
+ sort_info.max_records= (ha_rows) info->state->records;
if (param->testflag & T_STATISTICS)
- update_key_parts(sort_info->keyinfo, rec_per_key_part, sort_info->unique,
+ update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique,
(ulonglong) info->state->records);
- share->state.key_map|=(ulonglong) 1 << sort_info->key;
+ share->state.key_map|=(ulonglong) 1 << sort_param.key;
- if (sort_info->fix_datafile)
+ if (sort_param.fix_datafile)
{
- param->read_cache.end_of_file=sort_info->filepos;
- if (write_data_suffix(param,info) || end_io_cache(&info->rec_cache))
+ param->read_cache.end_of_file=sort_param.filepos;
+ if (write_data_suffix(&sort_info,1) || end_io_cache(&info->rec_cache))
goto err;
if (param->testflag & T_SAFE_REPAIR)
{
@@ -1940,25 +2018,25 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
goto err;
}
}
- share->state.state.data_file_length = info->state->data_file_length
- = sort_info->filepos;
+ share->state.state.data_file_length = info->state->data_file_length=
+ sort_param.filepos;
/* Only whole records */
- share->state.split=info->state->records+info->state->del;
share->state.version=(ulong) time((time_t*) 0);
my_close(info->dfile,MYF(0));
info->dfile=new_file;
- share->data_file_type=sort_info->new_data_file_type;
+ share->data_file_type=sort_info.new_data_file_type;
share->pack.header_length=(ulong) new_header_length;
+ sort_param.fix_datafile=0;
}
else
- info->state->data_file_length=sort_info->max_pos;
+ info->state->data_file_length=sort_param.max_pos;
- if (flush_pending_blocks(param))
- goto err;
+ /*if (flush_pending_blocks(param))
+ goto err;*/
param->read_cache.file=info->dfile; /* re-init read cache */
- reinit_io_cache(&param->read_cache,READ_CACHE,share->pack.header_length,1,
- 1);
+ reinit_io_cache(&param->read_cache,READ_CACHE,share->pack.header_length,
+ 1,1);
}
if (param->testflag & T_WRITE_LOOP)
@@ -1966,16 +2044,17 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
VOID(fputs(" \r",stdout)); VOID(fflush(stdout));
}
- if (rep_quick && del+sort_info->dupp != info->state->del)
+ if (rep_quick && del+sort_info.dupp != info->state->del)
{
mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
mi_check_print_error(param,"Run recovery again without -q");
got_error=1;
- param->retry_repair=param->retry_without_quick=1;
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
goto err;
}
- if (rep_quick != 1)
+ if (rep_quick & T_FORCE_UNIQUENESS)
{
my_off_t skr=info->state->data_file_length+
(share->options & HA_OPTION_COMPRESS_RECORD ?
@@ -1985,8 +2064,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
skr < share->base.reloc*share->base.min_pack_length)
skr=share->base.reloc*share->base.min_pack_length;
#endif
- if (skr != sort_info->filelength && !info->s->base.raid_type)
- if (my_chsize(info->dfile,skr,MYF(0)))
+ if (skr != sort_info.filelength && !info->s->base.raid_type)
+ if (my_chsize(info->dfile,skr,0,MYF(0)))
mi_check_print_warning(param,
"Can't change size of datafile, error: %d",
my_errno);
@@ -1994,7 +2073,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
if (param->testflag & T_CALC_CHECKSUM)
share->state.checksum=param->glob_crc;
- if (my_chsize(share->kfile,info->state->key_file_length,MYF(0)))
+ if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0)))
mi_check_print_warning(param,
"Can't change size of indexfile, error: %d",
my_errno);
@@ -2003,10 +2082,10 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
{
if (start_records != info->state->records)
printf("Data records: %s\n", llstr(info->state->records,llbuff));
- if (sort_info->dupp)
+ if (sort_info.dupp)
mi_check_print_warning(param,
"%s records have been removed",
- llstr(sort_info->dupp,llbuff));
+ llstr(sort_info.dupp,llbuff));
}
got_error=0;
@@ -2023,11 +2102,11 @@ err:
{
my_close(new_file,MYF(0));
info->dfile=new_file= -1;
- if (change_to_newfile(share->filename,MI_NAME_DEXT,
+ if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
- mi_open_datafile(info,share))
+ mi_open_datafile(info,share,-1))
got_error=1;
}
}
@@ -2049,9 +2128,11 @@ err:
share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
share->state.changed|=STATE_NOT_SORTED_PAGES;
- my_free((gptr) sort_info->key_block,MYF(MY_ALLOW_ZERO_PTR));
- my_free(sort_info->record,MYF(MY_ALLOW_ZERO_PTR));
- my_free(sort_info->buff,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mi_get_rec_buff_ptr(info, sort_param.rec_buff),
+ MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((gptr) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
if (!got_error && (param->testflag & T_UNPACK))
@@ -2062,74 +2143,540 @@ err:
DBUG_RETURN(got_error);
}
+/*
+ Threaded repair of table using sorting
+
+ SYNOPSIS
+ mi_repair_parallel()
+ param Repair parameters
+ info MyISAM handler to repair
+ name Name of table (for warnings)
+ rep_quick set to <> 0 if we should not change data file
+
+ DESCRIPTION
+ Same as mi_repair_by_sort but do it multithreaded
+ Each key is handled by a separate thread.
+ TODO: make a number of threads a parameter
+
+ RESULT
+ 0 ok
+ <>0 Error
+*/
+
+int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
+ const char * name, int rep_quick)
+{
+#ifndef THREAD
+ return mi_repair_by_sort(param, info, name, rep_quick);
+#else
+ int got_error;
+ uint i,key, total_key_length, istep;
+ ulong rec_length;
+ ha_rows start_records;
+ my_off_t new_header_length,del;
+ File new_file;
+ MI_SORT_PARAM *sort_param=0;
+ MYISAM_SHARE *share=info->s;
+ ulong *rec_per_key_part;
+ MI_KEYSEG *keyseg;
+ char llbuff[22];
+ IO_CACHE_SHARE io_share;
+ SORT_INFO sort_info;
+ ulonglong key_map=share->state.key_map;
+ pthread_attr_t thr_attr;
+ DBUG_ENTER("mi_repair_parallel");
+
+ start_records=info->state->records;
+ got_error=1;
+ new_file= -1;
+ new_header_length=(param->testflag & T_UNPACK) ? 0 :
+ share->pack.header_length;
+ if (!(param->testflag & T_SILENT))
+ {
+ printf("- parallel recovering (with sort) MyISAM-table '%s'\n",name);
+ printf("Data records: %s\n", llstr(start_records,llbuff));
+ }
+ param->testflag|=T_REP; /* for easy checking */
+
+ if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
+ param->testflag|=T_CALC_CHECKSUM;
+
+ bzero((char*)&sort_info,sizeof(sort_info));
+ if (!(sort_info.key_block=
+ alloc_key_blocks(param,
+ (uint) param->sort_key_blocks,
+ share->base.max_key_block_length))
+ || init_io_cache(&param->read_cache,info->dfile,
+ (uint) param->read_buffer_length,
+ READ_CACHE,share->pack.header_length,1,MYF(MY_WME)) ||
+ (! rep_quick &&
+ init_io_cache(&info->rec_cache,info->dfile,
+ (uint) param->write_buffer_length,
+ WRITE_CACHE,new_header_length,1,
+ MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw)))
+ goto err;
+ sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
+ info->opt_flag|=WRITE_CACHE_USED;
+ info->rec_cache.file=info->dfile; /* for sort_delete_record */
+
+ if (!rep_quick)
+ {
+ /* Get real path for data file */
+ if ((new_file=my_raid_create(fn_format(param->temp_filename,
+ share->data_file_name, "",
+ DATA_TMP_EXT,
+ 2+4),
+ 0,param->tmpfile_createflag,
+ share->base.raid_type,
+ share->base.raid_chunks,
+ share->base.raid_chunksize,
+ MYF(0))) < 0)
+ {
+ mi_check_print_error(param,"Can't create new tempfile: '%s'",
+ param->temp_filename);
+ goto err;
+ }
+ if (filecopy(param, new_file,info->dfile,0L,new_header_length,
+ "datafile-header"))
+ goto err;
+ if (param->testflag & T_UNPACK)
+ {
+ share->options&= ~HA_OPTION_COMPRESS_RECORD;
+ mi_int2store(share->state.header.options,share->options);
+ }
+ share->state.dellink= HA_OFFSET_ERROR;
+ info->rec_cache.file=new_file;
+ }
+
+ info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
+ if (!(param->testflag & T_CREATE_MISSING_KEYS))
+ {
+ /*
+ Flush key cache for this file if we are calling this outside
+ myisamchk
+ */
+ flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
+ /* Clear the pointers to the given rows */
+ for (i=0 ; i < share->base.keys ; i++)
+ share->state.key_root[i]= HA_OFFSET_ERROR;
+ for (i=0 ; i < share->state.header.max_block_size ; i++)
+ share->state.key_del[i]= HA_OFFSET_ERROR;
+ info->state->key_file_length=share->base.keystart;
+ }
+ else
+ {
+ if (flush_key_blocks(share->kfile, FLUSH_FORCE_WRITE))
+ goto err;
+ key_map= ~key_map; /* Create the missing keys */
+ }
+
+ sort_info.info=info;
+ sort_info.param = param;
+
+ set_data_file_type(&sort_info, share);
+ sort_info.dupp=0;
+ sort_info.buff=0;
+ param->read_cache.end_of_file=sort_info.filelength=
+ my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+ rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ rec_length=share->base.min_block_length;
+ else
+ rec_length=share->base.pack_reclength;
+ sort_info.max_records=
+ /* +1 below is required hack for parallel repair mode.
+ The info->state->records value, that is compared later
+ to sort_info.max_records and cannot exceed it, is
+ increased in sort_key_write. In mi_repair_by_sort, sort_key_write
+ is called after sort_key_read, where the comparison is performed,
+ but in parallel mode master thread can call sort_key_write
+ before some other repair thread calls sort_key_read.
+ Furthermore I'm not even sure +1 would be enough.
+ May be sort_info.max_records shold be always set to max value in
+ parallel mode. */
+ ((param->testflag & T_CREATE_MISSING_KEYS) ? info->state->records + 1:
+ (ha_rows) (sort_info.filelength/rec_length+1));
+
+ del=info->state->del;
+ param->glob_crc=0;
+ if (param->testflag & T_CALC_CHECKSUM)
+ param->calc_checksum=1;
+
+ if (!(sort_param=(MI_SORT_PARAM *)
+ my_malloc((uint) share->base.keys *
+ (sizeof(MI_SORT_PARAM) + share->base.pack_reclength),
+ MYF(MY_ZEROFILL))))
+ {
+ mi_check_print_error(param,"Not enough memory!");
+ goto err;
+ }
+ total_key_length=0;
+ rec_per_key_part= param->rec_per_key_part;
+ info->state->records=info->state->del=share->state.split=0;
+ info->state->empty=0;
+
+ for (i=key=0, istep=1 ; key < share->base.keys ;
+ rec_per_key_part+=sort_param[i].keyinfo->keysegs, i+=istep, key++)
+ {
+ sort_param[i].key=key;
+ sort_param[i].keyinfo=share->keyinfo+key;
+ if (!(((ulonglong) 1 << key) & key_map))
+ {
+ /* Remember old statistics for key */
+ memcpy((char*) rec_per_key_part,
+ (char*) (share->state.rec_per_key_part+
+ (uint) (rec_per_key_part - param->rec_per_key_part)),
+ sort_param[i].keyinfo->keysegs*sizeof(*rec_per_key_part));
+ istep=0;
+ continue;
+ }
+ istep=1;
+ if ((!(param->testflag & T_SILENT)))
+ printf ("- Fixing index %d\n",key+1);
+ sort_param[i].key_read= ((sort_param[i].keyinfo->flag & HA_FULLTEXT) ?
+ sort_ft_key_read : sort_key_read);
+ sort_param[i].key_cmp=sort_key_cmp;
+ sort_param[i].key_write=sort_key_write;
+ sort_param[i].lock_in_memory=lock_memory;
+ sort_param[i].tmpdir=param->tmpdir;
+ sort_param[i].sort_info=&sort_info;
+ sort_param[i].master=0;
+ sort_param[i].fix_datafile=0;
+
+ sort_param[i].filepos=new_header_length;
+ sort_param[i].max_pos=sort_param[i].pos=share->pack.header_length;
+
+ sort_param[i].record= (((char *)(sort_param+share->base.keys))+
+ (share->base.pack_reclength * i));
+ if (!mi_alloc_rec_buff(info, -1, &sort_param[i].rec_buff))
+ {
+ mi_check_print_error(param,"Not enough memory!");
+ goto err;
+ }
+
+ sort_param[i].key_length=share->rec_reflength;
+ for (keyseg=sort_param[i].keyinfo->seg; keyseg->type != HA_KEYTYPE_END;
+ keyseg++)
+ {
+ sort_param[i].key_length+=keyseg->length;
+ if (keyseg->flag & HA_SPACE_PACK)
+ sort_param[i].key_length+=get_pack_length(keyseg->length);
+ if (keyseg->flag & (HA_BLOB_PART | HA_VAR_LENGTH))
+ sort_param[i].key_length+=2 + test(keyseg->length >= 127);
+ if (keyseg->flag & HA_NULL_PART)
+ sort_param[i].key_length++;
+ }
+ total_key_length+=sort_param[i].key_length;
+
+ if (sort_param[i].keyinfo->flag & HA_FULLTEXT)
+ sort_param[i].key_length+=ft_max_word_len_for_sort-ft_max_word_len;
+ }
+ sort_info.total_keys=i;
+ sort_param[0].master= 1;
+ sort_param[0].fix_datafile= (my_bool)(! rep_quick);
+
+ sort_info.got_error=0;
+ pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&sort_info.cond, 0);
+ pthread_mutex_lock(&sort_info.mutex);
+
+ init_io_cache_share(&param->read_cache, &io_share, i);
+ (void) pthread_attr_init(&thr_attr);
+ (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
+
+ for (i=0 ; i < sort_info.total_keys ; i++)
+ {
+ sort_param[i].read_cache=param->read_cache;
+ /*
+ two approaches: the same amount of memory for each thread
+ or the memory for the same number of keys for each thread...
+ In the second one all the threads will fill their sort_buffers
+ (and call write_keys) at the same time, putting more stress on i/o.
+ */
+ sort_param[i].sortbuff_size=
+#ifndef USING_SECOND_APPROACH
+ param->sort_buffer_length/sort_info.total_keys;
+#else
+ param->sort_buffer_length*sort_param[i].key_length/total_key_length;
+#endif
+ if (pthread_create(&sort_param[i].thr, &thr_attr,
+ thr_find_all_keys,
+ (void *) (sort_param+i)))
+ {
+ mi_check_print_error(param,"Cannot start a repair thread");
+ remove_io_thread(&param->read_cache);
+ sort_info.got_error=1;
+ }
+ else
+ sort_info.threads_running++;
+ }
+ (void) pthread_attr_destroy(&thr_attr);
+
+ /* waiting for all threads to finish */
+ while (sort_info.threads_running)
+ pthread_cond_wait(&sort_info.cond, &sort_info.mutex);
+ pthread_mutex_unlock(&sort_info.mutex);
+
+ if ((got_error= thr_write_keys(sort_param)))
+ {
+ param->retry_repair=1;
+ goto err;
+ }
+ got_error=1; /* Assume the following may go wrong */
+
+ if (sort_param[0].fix_datafile)
+ {
+ if (write_data_suffix(&sort_info,1) || end_io_cache(&info->rec_cache))
+ goto err;
+ if (param->testflag & T_SAFE_REPAIR)
+ {
+ /* Don't repair if we loosed more than one row */
+ if (info->state->records+1 < start_records)
+ {
+ info->state->records=start_records;
+ goto err;
+ }
+ }
+ share->state.state.data_file_length= info->state->data_file_length=
+ sort_param->filepos;
+ /* Only whole records */
+ share->state.version=(ulong) time((time_t*) 0);
+ my_close(info->dfile,MYF(0));
+ info->dfile=new_file;
+ share->data_file_type=sort_info.new_data_file_type;
+ share->pack.header_length=(ulong) new_header_length;
+ }
+ else
+ info->state->data_file_length=sort_param->max_pos;
+
+ if (rep_quick && del+sort_info.dupp != info->state->del)
+ {
+ mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
+ mi_check_print_error(param,"Run recovery again without -q");
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
+ goto err;
+ }
+
+ if (rep_quick & T_FORCE_UNIQUENESS)
+ {
+ my_off_t skr=info->state->data_file_length+
+ (share->options & HA_OPTION_COMPRESS_RECORD ?
+ MEMMAP_EXTRA_MARGIN : 0);
+#ifdef USE_RELOC
+ if (share->data_file_type == STATIC_RECORD &&
+ skr < share->base.reloc*share->base.min_pack_length)
+ skr=share->base.reloc*share->base.min_pack_length;
+#endif
+ if (skr != sort_info.filelength && !info->s->base.raid_type)
+ if (my_chsize(info->dfile,skr,0,MYF(0)))
+ mi_check_print_warning(param,
+ "Can't change size of datafile, error: %d",
+ my_errno);
+ }
+ if (param->testflag & T_CALC_CHECKSUM)
+ share->state.checksum=param->glob_crc;
+
+ if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0)))
+ mi_check_print_warning(param,
+ "Can't change size of indexfile, error: %d", my_errno);
+
+ if (!(param->testflag & T_SILENT))
+ {
+ if (start_records != info->state->records)
+ printf("Data records: %s\n", llstr(info->state->records,llbuff));
+ if (sort_info.dupp)
+ mi_check_print_warning(param,
+ "%s records have been removed",
+ llstr(sort_info.dupp,llbuff));
+ }
+ got_error=0;
+
+ if (&share->state.state != info->state)
+ memcpy(&share->state.state, info->state, sizeof(*info->state));
+
+err:
+ got_error|= flush_blocks(param,share->kfile);
+ VOID(end_io_cache(&info->rec_cache));
+ if (!got_error)
+ {
+ /* Replace the actual file with the temporary file */
+ if (new_file >= 0)
+ {
+ my_close(new_file,MYF(0));
+ info->dfile=new_file= -1;
+ if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
+ DATA_TMP_EXT, share->base.raid_chunks,
+ (param->testflag & T_BACKUP_DATA ?
+ MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
+ mi_open_datafile(info,share,-1))
+ got_error=1;
+ }
+ }
+ if (got_error)
+ {
+ if (! param->error_printed)
+ mi_check_print_error(param,"%d when fixing table",my_errno);
+ if (new_file >= 0)
+ {
+ VOID(my_close(new_file,MYF(0)));
+ VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
+ MYF(MY_WME)));
+ if (info->dfile == new_file)
+ info->dfile= -1;
+ }
+ mi_mark_crashed_on_repair(info);
+ }
+ else if (key_map == share->state.key_map)
+ share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
+ share->state.changed|=STATE_NOT_SORTED_PAGES;
+
+ pthread_cond_destroy (&sort_info.cond);
+ pthread_mutex_destroy(&sort_info.mutex);
+
+ my_free((gptr) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((gptr) sort_param,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
+ VOID(end_io_cache(&param->read_cache));
+ info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
+ if (!got_error && (param->testflag & T_UNPACK))
+ {
+ share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
+ share->pack.header_length=0;
+ }
+ DBUG_RETURN(got_error);
+#endif /* THREAD */
+}
/* Read next record and return next key */
-static int sort_key_read(SORT_INFO *sort_info, void *key)
+static int sort_key_read(MI_SORT_PARAM *sort_param, void *key)
{
int error;
- MI_INFO *info;
+ SORT_INFO *sort_info=sort_param->sort_info;
+ MI_INFO *info=sort_info->info;
DBUG_ENTER("sort_key_read");
- info=sort_info->info;
-
- if ((error=sort_get_next_record(sort_info)))
+ if ((error=sort_get_next_record(sort_param)))
DBUG_RETURN(error);
if (info->state->records == sort_info->max_records)
{
mi_check_print_error(sort_info->param,
- "Found too many records; Can`t continue");
+ "Key %d - Found too many records; Can't continue",
+ sort_param->key+1);
DBUG_RETURN(1);
}
- (void) _mi_make_key(info,sort_info->key,(uchar*)key,sort_info->record,
- sort_info->filepos);
- DBUG_RETURN(sort_write_record(sort_info));
+ sort_param->real_key_length=
+ (info->s->rec_reflength+
+ _mi_make_key(info, sort_param->key, (uchar*) key,
+ sort_param->record, sort_param->filepos));
+#ifdef HAVE_purify
+ bzero(key+sort_param->real_key_length,
+ (sort_param->key_length-sort_param->real_key_length));
+#endif
+ DBUG_RETURN(sort_write_record(sort_param));
} /* sort_key_read */
+static int sort_ft_key_read(MI_SORT_PARAM *sort_param, void *key)
+{
+ int error;
+ SORT_INFO *sort_info=sort_param->sort_info;
+ MI_INFO *info=sort_info->info;
+ FT_WORD *wptr=0;
+ DBUG_ENTER("sort_ft_key_read");
+
+ if (!sort_param->wordlist)
+ {
+ for (;;)
+ {
+ my_free((char*) wptr, MYF(MY_ALLOW_ZERO_PTR));
+ if ((error=sort_get_next_record(sort_param)))
+ DBUG_RETURN(error);
+ if (!(wptr=_mi_ft_parserecord(info,sort_param->key,
+ key,sort_param->record)))
+ DBUG_RETURN(1);
+ if (wptr->pos)
+ break;
+ error=sort_write_record(sort_param);
+ }
+ sort_param->wordptr=sort_param->wordlist=wptr;
+ }
+ else
+ {
+ error=0;
+ wptr=(FT_WORD*)(sort_param->wordptr);
+ }
+
+ sort_param->real_key_length=(info->s->rec_reflength+
+ _ft_make_key(info, sort_param->key,
+ key, wptr++, sort_param->filepos));
+#ifdef HAVE_purify
+ if (sort_param->key_length > sort_param->real_key_length)
+ bzero(key+sort_param->real_key_length,
+ (sort_param->key_length-sort_param->real_key_length));
+#endif
+ if (!wptr->pos)
+ {
+ my_free((char*) sort_param->wordlist, MYF(0));
+ sort_param->wordlist=0;
+ error=sort_write_record(sort_param);
+ }
+ else
+ sort_param->wordptr=(void*)wptr;
+
+ DBUG_RETURN(error);
+} /* sort_ft_key_read */
+
+
/* Read next record from file using parameters in sort_info */
/* Return -1 if end of file, 0 if ok and > 0 if error */
-static int sort_get_next_record(SORT_INFO *sort_info)
+static int sort_get_next_record(MI_SORT_PARAM *sort_param)
{
int searching;
uint found_record,b_type,left_length;
my_off_t pos;
byte *to;
MI_BLOCK_INFO block_info;
- MI_INFO *info;
- MYISAM_SHARE *share;
+ SORT_INFO *sort_info=sort_param->sort_info;
MI_CHECK *param=sort_info->param;
+ MI_INFO *info=sort_info->info;
+ MYISAM_SHARE *share=info->s;
char llbuff[22],llbuff2[22];
DBUG_ENTER("sort_get_next_record");
- info=sort_info->info;
- share=info->s;
switch (share->data_file_type) {
case STATIC_RECORD:
for (;;)
{
- if (my_b_read(&param->read_cache,sort_info->record,
+ if (my_b_read(&sort_param->read_cache,sort_param->record,
share->base.pack_reclength))
{
- if (param->read_cache.error)
+ if (sort_param->read_cache.error)
param->out_flag |= O_DATA_LOST;
- param->retry_repair=param->retry_without_quick=1;
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(-1);
}
- sort_info->start_recpos=sort_info->pos;
- if (!sort_info->fix_datafile)
- sort_info->filepos=sort_info->pos;
- sort_info->max_pos=(sort_info->pos+=share->base.pack_reclength);
- share->state.split++;
- if (*sort_info->record)
+ sort_param->start_recpos=sort_param->pos;
+ if (!sort_param->fix_datafile)
+ {
+ sort_param->filepos=sort_param->pos;
+ if (sort_param->master)
+ share->state.split++;
+ }
+ sort_param->max_pos=(sort_param->pos+=share->base.pack_reclength);
+ if (*sort_param->record)
{
if (param->calc_checksum)
param->glob_crc+= (info->checksum=
- mi_static_checksum(info,sort_info->record));
+ mi_static_checksum(info,sort_param->record));
DBUG_RETURN(0);
}
- if (!sort_info->fix_datafile)
+ if (!sort_param->fix_datafile && sort_param->master)
{
info->state->del++;
info->state->empty+=share->base.pack_reclength;
@@ -2137,8 +2684,8 @@ static int sort_get_next_record(SORT_INFO *sort_info)
}
case DYNAMIC_RECORD:
LINT_INIT(to);
- pos=sort_info->pos;
- searching=(sort_info->fix_datafile && (param->testflag & T_EXTEND));
+ pos=sort_param->pos;
+ searching=(sort_param->fix_datafile && (param->testflag & T_EXTEND));
for (;;)
{
found_record=block_info.second_read= 0;
@@ -2146,13 +2693,13 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (searching)
{
pos=MY_ALIGN(pos,MI_DYN_ALIGN_SIZE);
- param->retry_without_quick=1;
- sort_info->start_recpos=pos;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
+ sort_param->start_recpos=pos;
}
do
{
- if (pos > sort_info->max_pos)
- sort_info->max_pos=pos;
+ if (pos > sort_param->max_pos)
+ sort_param->max_pos=pos;
if (pos & (MI_DYN_ALIGN_SIZE-1))
{
if ((param->testflag & T_VERBOSE) || searching == 0)
@@ -2164,8 +2711,9 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (found_record && pos == param->search_after_block)
mi_check_print_info(param,"Block: %s used by record at %s",
llstr(param->search_after_block,llbuff),
- llstr(sort_info->start_recpos,llbuff2));
- if (_mi_read_cache(&param->read_cache,(byte*) block_info.header,pos,
+ llstr(sort_param->start_recpos,llbuff2));
+ if (_mi_read_cache(&sort_param->read_cache,
+ (byte*) block_info.header,pos,
MI_BLOCK_INFO_HEADER_LENGTH,
(! found_record ? READING_NEXT : 0) |
READING_HEADER))
@@ -2174,20 +2722,21 @@ static int sort_get_next_record(SORT_INFO *sort_info)
{
mi_check_print_info(param,
"Can't read whole record at %s (errno: %d)",
- llstr(sort_info->start_recpos,llbuff),errno);
+ llstr(sort_param->start_recpos,llbuff),errno);
goto try_next;
}
DBUG_RETURN(-1);
}
- if (searching && ! sort_info->fix_datafile)
+ if (searching && ! sort_param->fix_datafile)
{
param->error_printed=1;
- param->retry_repair=param->retry_without_quick=1;
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(1); /* Something wrong with data */
}
- if (((b_type=_mi_get_block_info(&block_info,-1,pos)) &
- (BLOCK_ERROR | BLOCK_FATAL_ERROR)) ||
- ((b_type & BLOCK_FIRST) &&
+ b_type=_mi_get_block_info(&block_info,-1,pos);
+ if ((b_type & (BLOCK_ERROR | BLOCK_FATAL_ERROR)) ||
+ ((b_type & BLOCK_FIRST) &&
(block_info.rec_len < (uint) share->base.min_pack_length ||
block_info.rec_len > (uint) share->base.max_pack_length)))
{
@@ -2209,7 +2758,7 @@ static int sort_get_next_record(SORT_INFO *sort_info)
block_info.header[i] <= MI_MAX_DYN_HEADER_BYTE)
break;
pos+=(ulong) i;
- sort_info->start_recpos=pos;
+ sort_param->start_recpos=pos;
continue;
}
if (b_type & BLOCK_DELETED)
@@ -2245,7 +2794,7 @@ static int sort_get_next_record(SORT_INFO *sort_info)
goto try_next;
searching=1;
pos+= MI_DYN_ALIGN_SIZE;
- sort_info->start_recpos=pos;
+ sort_param->start_recpos=pos;
block_info.second_read=0;
continue;
}
@@ -2266,14 +2815,15 @@ static int sort_get_next_record(SORT_INFO *sort_info)
goto try_next;
searching=1;
pos+= MI_DYN_ALIGN_SIZE;
- sort_info->start_recpos=pos;
+ sort_param->start_recpos=pos;
block_info.second_read=0;
continue;
}
}
if (b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR))
{
- if (!sort_info->fix_datafile && (b_type & BLOCK_DELETED))
+ if (!sort_param->fix_datafile && sort_param->master &&
+ (b_type & BLOCK_DELETED))
{
info->state->empty+=block_info.block_len;
info->state->del++;
@@ -2284,7 +2834,7 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (searching)
{
pos+=MI_DYN_ALIGN_SIZE;
- sort_info->start_recpos=pos;
+ sort_param->start_recpos=pos;
}
else
pos=block_info.filepos+block_info.block_len;
@@ -2292,43 +2842,45 @@ static int sort_get_next_record(SORT_INFO *sort_info)
continue;
}
- share->state.split++;
+ if (!sort_param->fix_datafile && sort_param->master)
+ share->state.split++;
if (! found_record++)
{
- sort_info->find_length=left_length=block_info.rec_len;
- sort_info->start_recpos=pos;
- if (!sort_info->fix_datafile)
- sort_info->filepos=sort_info->start_recpos;
- if (sort_info->fix_datafile && (param->testflag & T_EXTEND))
- sort_info->pos=block_info.filepos+1;
+ sort_param->find_length=left_length=block_info.rec_len;
+ sort_param->start_recpos=pos;
+ if (!sort_param->fix_datafile)
+ sort_param->filepos=sort_param->start_recpos;
+ if (sort_param->fix_datafile && (param->testflag & T_EXTEND))
+ sort_param->pos=block_info.filepos+1;
else
- sort_info->pos=block_info.filepos+block_info.block_len;
+ sort_param->pos=block_info.filepos+block_info.block_len;
if (share->base.blobs)
{
- if (!(to=mi_fix_rec_buff_for_blob(info,block_info.rec_len)))
+ if (!(to=mi_alloc_rec_buff(info,block_info.rec_len,
+ &(sort_param->rec_buff))))
{
- mi_check_print_error(param,"Not enough memory for blob at %s",
- llstr(sort_info->start_recpos,llbuff));
+ mi_check_print_error(param,"Not enough memory for blob at %s (need %lu)",
+ llstr(sort_param->start_recpos,llbuff), block_info.rec_len);
DBUG_RETURN(1);
}
}
else
- to= info->rec_buff;
+ to= sort_param->rec_buff;
}
if (left_length < block_info.data_len || ! block_info.data_len)
{
mi_check_print_info(param,"Found block with too small length at %s; Skipped",
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
if (block_info.filepos + block_info.data_len >
- param->read_cache.end_of_file)
+ sort_param->read_cache.end_of_file)
{
mi_check_print_info(param,"Found block that points outside data file at %s",
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
- if (_mi_read_cache(&param->read_cache,to,block_info.filepos,
+ if (_mi_read_cache(&sort_param->read_cache,to,block_info.filepos,
block_info.data_len,
(found_record == 1 ? READING_NEXT : 0)))
{
@@ -2343,31 +2895,32 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (pos == HA_OFFSET_ERROR && left_length)
{
mi_check_print_info(param,"Wrong block with wrong total length starting at %s",
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
- if (pos + MI_BLOCK_INFO_HEADER_LENGTH > param->read_cache.end_of_file)
+ if (pos + MI_BLOCK_INFO_HEADER_LENGTH > sort_param->read_cache.end_of_file)
{
mi_check_print_info(param,"Found link that points at %s (outside data file) at %s",
llstr(pos,llbuff2),
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
} while (left_length);
- if (_mi_rec_unpack(info,sort_info->record,info->rec_buff,
- sort_info->find_length) != MY_FILE_ERROR)
+ if (_mi_rec_unpack(info,sort_param->record,sort_param->rec_buff,
+ sort_param->find_length) != MY_FILE_ERROR)
{
- if (param->read_cache.error < 0)
+ if (sort_param->read_cache.error < 0)
DBUG_RETURN(1);
if (info->s->calc_checksum)
- info->checksum=mi_checksum(info,sort_info->record);
+ info->checksum=mi_checksum(info,sort_param->record);
if ((param->testflag & (T_EXTEND | T_REP)) || searching)
{
- if (_mi_rec_check(info, sort_info->record))
+ if (_mi_rec_check(info, sort_param->record, sort_param->rec_buff,
+ sort_param->find_length))
{
mi_check_print_info(param,"Found wrong packed record at %s",
- llstr(sort_info->start_recpos,llbuff));
+ llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
}
@@ -2376,31 +2929,33 @@ static int sort_get_next_record(SORT_INFO *sort_info)
DBUG_RETURN(0);
}
if (!searching)
- mi_check_print_info(param,"Found wrong stored record at %s",
- llstr(sort_info->start_recpos,llbuff));
+ mi_check_print_info(param,"Key %d - Found wrong stored record at %s",
+ sort_param->key+1,
+ llstr(sort_param->start_recpos,llbuff));
try_next:
- pos=(sort_info->start_recpos+=MI_DYN_ALIGN_SIZE);
+ pos=(sort_param->start_recpos+=MI_DYN_ALIGN_SIZE);
searching=1;
}
case COMPRESSED_RECORD:
- for (searching=0 ;; searching=1, sort_info->pos++)
+ for (searching=0 ;; searching=1, sort_param->pos++)
{
- if (_mi_read_cache(&param->read_cache,(byte*) block_info.header,
- sort_info->pos,
+ if (_mi_read_cache(&sort_param->read_cache,(byte*) block_info.header,
+ sort_param->pos,
share->pack.ref_length,READING_NEXT))
DBUG_RETURN(-1);
- if (searching && ! sort_info->fix_datafile)
+ if (searching && ! sort_param->fix_datafile)
{
param->error_printed=1;
- param->retry_repair=param->retry_without_quick=1;
+ param->retry_repair=1;
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(1); /* Something wrong with data */
}
- sort_info->start_recpos=sort_info->pos;
- if (_mi_pack_get_block_info(info,&block_info,-1,sort_info->pos, NullS))
+ sort_param->start_recpos=sort_param->pos;
+ if (_mi_pack_get_block_info(info,&block_info,-1,sort_param->pos))
DBUG_RETURN(-1);
if (!block_info.rec_len &&
- sort_info->pos + MEMMAP_EXTRA_MARGIN ==
- param->read_cache.end_of_file)
+ sort_param->pos + MEMMAP_EXTRA_MARGIN ==
+ sort_param->read_cache.end_of_file)
DBUG_RETURN(-1);
if (block_info.rec_len < (uint) share->min_pack_length ||
block_info.rec_len > (uint) share->max_pack_length)
@@ -2408,32 +2963,35 @@ static int sort_get_next_record(SORT_INFO *sort_info)
if (! searching)
mi_check_print_info(param,"Found block with wrong recordlength: %d at %s\n",
block_info.rec_len,
- llstr(sort_info->pos,llbuff));
+ llstr(sort_param->pos,llbuff));
continue;
}
- if (_mi_read_cache(&param->read_cache,(byte*) info->rec_buff,
+ if (_mi_read_cache(&sort_param->read_cache,(byte*) sort_param->rec_buff,
block_info.filepos, block_info.rec_len,
READING_NEXT))
{
if (! searching)
mi_check_print_info(param,"Couldn't read whole record from %s",
- llstr(sort_info->pos,llbuff));
+ llstr(sort_param->pos,llbuff));
continue;
}
- if (_mi_pack_rec_unpack(info,sort_info->record,info->rec_buff,
+ if (_mi_pack_rec_unpack(info,sort_param->record,sort_param->rec_buff,
block_info.rec_len))
{
if (! searching)
mi_check_print_info(param,"Found wrong record at %s",
- llstr(sort_info->pos,llbuff));
+ llstr(sort_param->pos,llbuff));
continue;
}
- info->checksum=mi_checksum(info,sort_info->record);
- if (!sort_info->fix_datafile)
- sort_info->filepos=sort_info->pos;
- sort_info->max_pos=(sort_info->pos=block_info.filepos+
+ info->checksum=mi_checksum(info,sort_param->record);
+ if (!sort_param->fix_datafile)
+ {
+ sort_param->filepos=sort_param->pos;
+ if (sort_param->master)
+ share->state.split++;
+ }
+ sort_param->max_pos=(sort_param->pos=block_info.filepos+
block_info.rec_len);
- share->state.split++;
info->packed_length=block_info.rec_len;
if (param->calc_checksum)
param->glob_crc+= info->checksum;
@@ -2446,41 +3004,41 @@ static int sort_get_next_record(SORT_INFO *sort_info)
/* Write record to new file */
-int sort_write_record(SORT_INFO *sort_info)
+int sort_write_record(MI_SORT_PARAM *sort_param)
{
int flag;
uint length;
ulong block_length,reclength;
byte *from;
byte block_buff[8];
- MI_INFO *info;
- MYISAM_SHARE *share;
+ SORT_INFO *sort_info=sort_param->sort_info;
MI_CHECK *param=sort_info->param;
+ MI_INFO *info=sort_info->info;
+ MYISAM_SHARE *share=info->s;
DBUG_ENTER("sort_write_record");
- info=sort_info->info;
- share=info->s;
- if (sort_info->fix_datafile)
+ if (sort_param->fix_datafile)
{
switch (sort_info->new_data_file_type) {
case STATIC_RECORD:
- if (my_b_write(&info->rec_cache,sort_info->record,
+ if (my_b_write(&info->rec_cache,sort_param->record,
share->base.pack_reclength))
{
mi_check_print_error(param,"%d when writing to datafile",my_errno);
DBUG_RETURN(1);
}
- sort_info->filepos+=share->base.pack_reclength;
- /* sort_info->param->glob_crc+=mi_static_checksum(info, sort_info->record); */
+ sort_param->filepos+=share->base.pack_reclength;
+ info->s->state.split++;
+ /* sort_info->param->glob_crc+=mi_static_checksum(info, sort_param->record); */
break;
case DYNAMIC_RECORD:
if (! info->blobs)
- from=info->rec_buff;
+ from=sort_param->rec_buff;
else
{
/* must be sure that local buffer is big enough */
reclength=info->s->base.pack_reclength+
- _my_calc_total_blob_length(info,sort_info->record)+
+ _my_calc_total_blob_length(info,sort_param->record)+
ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
MI_DYN_DELETE_BLOCK_HEADER;
if (sort_info->buff_length < reclength)
@@ -2493,22 +3051,30 @@ int sort_write_record(SORT_INFO *sort_info)
}
from=sort_info->buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER);
}
- info->checksum=mi_checksum(info,sort_info->record);
- reclength=_mi_rec_pack(info,from,sort_info->record);
- /* sort_info->param->glob_crc+=info->checksum; */
- block_length=reclength+ 3 + test(reclength >= (65520-3));
- if (block_length < share->base.min_block_length)
- block_length=share->base.min_block_length;
+ info->checksum=mi_checksum(info,sort_param->record);
+ reclength=_mi_rec_pack(info,from,sort_param->record);
flag=0;
- info->update|=HA_STATE_WRITE_AT_END;
- block_length=MY_ALIGN(block_length,MI_DYN_ALIGN_SIZE);
- if (_mi_write_part_record(info,0L,block_length,HA_OFFSET_ERROR,
- &from,&reclength,&flag))
+ /* sort_info->param->glob_crc+=info->checksum; */
+
+ do
{
- mi_check_print_error(param,"%d when writing to datafile",my_errno);
- DBUG_RETURN(1);
- }
- sort_info->filepos+=block_length;
+ block_length=reclength+ 3 + test(reclength >= (65520-3));
+ if (block_length < share->base.min_block_length)
+ block_length=share->base.min_block_length;
+ info->update|=HA_STATE_WRITE_AT_END;
+ block_length=MY_ALIGN(block_length,MI_DYN_ALIGN_SIZE);
+ if (block_length > MI_MAX_BLOCK_LENGTH)
+ block_length=MI_MAX_BLOCK_LENGTH;
+ if (_mi_write_part_record(info,0L,block_length,
+ sort_param->filepos+block_length,
+ &from,&reclength,&flag))
+ {
+ mi_check_print_error(param,"%d when writing to datafile",my_errno);
+ DBUG_RETURN(1);
+ }
+ sort_param->filepos+=block_length;
+ info->s->state.split++;
+ } while (reclength);
/* sort_info->param->glob_crc+=info->checksum; */
break;
case COMPRESSED_RECORD:
@@ -2517,22 +3083,26 @@ int sort_write_record(SORT_INFO *sort_info)
if (info->s->base.blobs)
length+=save_pack_length(block_buff+length,info->blob_length);
if (my_b_write(&info->rec_cache,block_buff,length) ||
- my_b_write(&info->rec_cache,(byte*) info->rec_buff,reclength))
+ my_b_write(&info->rec_cache,(byte*) sort_param->rec_buff,reclength))
{
mi_check_print_error(param,"%d when writing to datafile",my_errno);
DBUG_RETURN(1);
}
/* sort_info->param->glob_crc+=info->checksum; */
- sort_info->filepos+=reclength+length;
+ sort_param->filepos+=reclength+length;
+ info->s->state.split++;
break;
}
}
- info->state->records++;
- if ((param->testflag & T_WRITE_LOOP) &&
- (info->state->records % WRITE_COUNT) == 0)
+ if (sort_param->master)
{
- char llbuff[22];
- printf("%s\r", llstr(info->state->records,llbuff)); VOID(fflush(stdout));
+ info->state->records++;
+ if ((param->testflag & T_WRITE_LOOP) &&
+ (info->state->records % WRITE_COUNT) == 0)
+ {
+ char llbuff[22];
+ printf("%s\r", llstr(info->state->records,llbuff)); VOID(fflush(stdout));
+ }
}
DBUG_RETURN(0);
} /* sort_write_record */
@@ -2540,49 +3110,49 @@ int sort_write_record(SORT_INFO *sort_info)
/* Compare two keys from _create_index_by_sort */
-static int sort_key_cmp(SORT_INFO *sort_info, const void *a, const void *b)
+static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a,
+ const void *b)
{
uint not_used;
- return (_mi_key_cmp(sort_info->keyseg,*((uchar**) a),*((uchar**) b),
+ return (_mi_key_cmp(sort_param->keyinfo->seg,*((uchar**) a),*((uchar**) b),
USE_WHOLE_KEY, SEARCH_SAME,&not_used));
} /* sort_key_cmp */
-static int sort_key_write(SORT_INFO *sort_info, const void *a)
+static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
{
uint diff_pos;
char llbuff[22],llbuff2[22];
+ SORT_INFO *sort_info=sort_param->sort_info;
MI_CHECK *param= sort_info->param;
int cmp;
if (sort_info->key_block->inited)
{
- cmp=_mi_key_cmp(sort_info->keyseg,sort_info->key_block->lastkey,(uchar*) a,
- USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE ,&diff_pos);
- sort_info->unique[diff_pos-1]++;
+ cmp=_mi_key_cmp(sort_param->keyinfo->seg, sort_info->key_block->lastkey,
+ (uchar*) a, USE_WHOLE_KEY, SEARCH_FIND | SEARCH_UPDATE,
+ &diff_pos);
+ sort_param->unique[diff_pos-1]++;
}
else
{
cmp= -1;
}
- if ((sort_info->keyinfo->flag & HA_NOSAME) && cmp == 0)
+ if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0)
{
sort_info->dupp++;
sort_info->info->lastpos=get_record_for_key(sort_info->info,
- sort_info->keyinfo,
+ sort_param->keyinfo,
(uchar*) a);
mi_check_print_warning(param,
- "Duplicate key for record at %10s against record at %10s",
- llstr(sort_info->info->lastpos,llbuff),
- llstr(get_record_for_key(sort_info->info,
- sort_info->keyinfo,
- sort_info->key_block->
- lastkey),
- llbuff2));
- param->retry_without_quick=1;
+ "Duplicate key for record at %10s against record at %10s",
+ llstr(sort_info->info->lastpos,llbuff),
+ llstr(get_record_for_key(sort_info->info, sort_param->keyinfo,
+ sort_info->key_block->lastkey), llbuff2));
+ param->testflag|=T_RETRY_WITHOUT_QUICK;
if (sort_info->param->testflag & T_VERBOSE)
- _mi_print_key(stdout,sort_info->keyseg,(uchar*) a, USE_WHOLE_KEY);
- return (sort_delete_record(param));
+ _mi_print_key(stdout,sort_param->keyinfo->seg,(uchar*) a, USE_WHOLE_KEY);
+ return (sort_delete_record(sort_param));
}
#ifndef DBUG_OFF
if (cmp > 0)
@@ -2592,8 +3162,8 @@ static int sort_key_write(SORT_INFO *sort_info, const void *a)
return(1);
}
#endif
- return (sort_insert_key(param,sort_info->key_block,(uchar*) a,
- HA_OFFSET_ERROR));
+ return (sort_insert_key(sort_param,sort_info->key_block,
+ (uchar*) a, HA_OFFSET_ERROR));
} /* sort_key_write */
@@ -2608,7 +3178,7 @@ static my_off_t get_record_for_key(MI_INFO *info, MI_KEYDEF *keyinfo,
/* Insert a key in sort-key-blocks */
-static int sort_insert_key(MI_CHECK *param,
+static int sort_insert_key(MI_SORT_PARAM *sort_param,
register SORT_KEY_BLOCKS *key_block, uchar *key,
my_off_t prev_block)
{
@@ -2617,14 +3187,16 @@ static int sort_insert_key(MI_CHECK *param,
uchar *anc_buff,*lastkey;
MI_KEY_PARAM s_temp;
MI_INFO *info;
- SORT_INFO *sort_info= &param->sort_info;
+ MI_KEYDEF *keyinfo=sort_param->keyinfo;
+ SORT_INFO *sort_info= sort_param->sort_info;
+ MI_CHECK *param=sort_info->param;
DBUG_ENTER("sort_insert_key");
anc_buff=key_block->buff;
info=sort_info->info;
lastkey=key_block->lastkey;
nod_flag= (key_block == sort_info->key_block ? 0 :
- sort_info->info->s->base.key_reflength);
+ info->s->base.key_reflength);
if (!key_block->inited)
{
@@ -2645,17 +3217,16 @@ static int sort_insert_key(MI_CHECK *param,
if (nod_flag)
_mi_kpointer(info,key_block->end_pos,prev_block);
- t_length=(*sort_info->keyinfo->pack_key)(sort_info->keyinfo,nod_flag,
- (uchar*) 0,lastkey,lastkey,key,
- &s_temp);
- (*sort_info->keyinfo->store_key)(sort_info->keyinfo,
- key_block->end_pos+nod_flag,&s_temp);
+ t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
+ (uchar*) 0,lastkey,lastkey,key,
+ &s_temp);
+ (*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
a_length+=t_length;
mi_putint(anc_buff,a_length,nod_flag);
key_block->end_pos+=t_length;
- if (a_length <= sort_info->keyinfo->block_length)
+ if (a_length <= keyinfo->block_length)
{
- VOID(_mi_move_key(sort_info->keyinfo,key_block->lastkey,key));
+ VOID(_mi_move_key(keyinfo,key_block->lastkey,key));
key_block->last_length=a_length-t_length;
DBUG_RETURN(0);
}
@@ -2663,52 +3234,50 @@ static int sort_insert_key(MI_CHECK *param,
/* Fill block with end-zero and write filled block */
mi_putint(anc_buff,key_block->last_length,nod_flag);
bzero((byte*) anc_buff+key_block->last_length,
- sort_info->keyinfo->block_length- key_block->last_length);
+ keyinfo->block_length- key_block->last_length);
key_file_length=info->state->key_file_length;
- if ((filepos=_mi_new(info,sort_info->keyinfo)) == HA_OFFSET_ERROR)
+ if ((filepos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
DBUG_RETURN(1);
/* If we read the page from the key cache, we have to write it back to it */
if (key_file_length == info->state->key_file_length)
{
- if (_mi_write_keypage(info, sort_info->keyinfo, filepos,
- anc_buff))
+ if (_mi_write_keypage(info, keyinfo, filepos, anc_buff))
DBUG_RETURN(1);
}
else if (my_pwrite(info->s->kfile,(byte*) anc_buff,
- (uint) sort_info->keyinfo->block_length,filepos,
- param->myf_rw))
+ (uint) keyinfo->block_length,filepos, param->myf_rw))
DBUG_RETURN(1);
DBUG_DUMP("buff",(byte*) anc_buff,mi_getint(anc_buff));
/* Write separator-key to block in next level */
- if (sort_insert_key(param,key_block+1,key_block->lastkey,filepos))
+ if (sort_insert_key(sort_param,key_block+1,key_block->lastkey,filepos))
DBUG_RETURN(1);
/* clear old block and write new key in it */
key_block->inited=0;
- DBUG_RETURN(sort_insert_key(param, key_block,key,prev_block));
+ DBUG_RETURN(sort_insert_key(sort_param, key_block,key,prev_block));
} /* sort_insert_key */
/* Delete record when we found a duplicated key */
-static int sort_delete_record(MI_CHECK *param)
+static int sort_delete_record(MI_SORT_PARAM *sort_param)
{
uint i;
int old_file,error;
uchar *key;
- MI_INFO *info;
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO *sort_info=sort_param->sort_info;
+ MI_CHECK *param=sort_info->param;
+ MI_INFO *info=sort_info->info;
DBUG_ENTER("sort_delete_record");
- if (param->opt_rep_quick == 1)
+ if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK)
{
mi_check_print_error(param,
- "Quick-recover aborted; Run recovery without switch 'q' or with switch -qq");
+ "Quick-recover aborted; Run recovery without switch -q or with switch -qq");
DBUG_RETURN(1);
}
- info=sort_info->info;
if (info->s->options & HA_OPTION_COMPRESS_RECORD)
{
mi_check_print_error(param,
@@ -2718,10 +3287,10 @@ static int sort_delete_record(MI_CHECK *param)
old_file=info->dfile;
info->dfile=info->rec_cache.file;
- if (sort_info->key)
+ if (sort_info->current_key)
{
key=info->lastkey+info->s->base.max_key_length;
- if ((error=(*info->s->read_rnd)(info,sort_info->record,info->lastpos,0)) &&
+ if ((error=(*info->s->read_rnd)(info,sort_param->record,info->lastpos,0)) &&
error != HA_ERR_RECORD_DELETED)
{
mi_check_print_error(param,"Can't read record to be removed");
@@ -2729,9 +3298,9 @@ static int sort_delete_record(MI_CHECK *param)
DBUG_RETURN(1);
}
- for (i=0 ; i < sort_info->key ; i++)
+ for (i=0 ; i < sort_info->current_key ; i++)
{
- uint key_length=_mi_make_key(info,i,key,sort_info->record,info->lastpos);
+ uint key_length=_mi_make_key(info,i,key,sort_param->record,info->lastpos);
if (_mi_ck_delete(info,i,key,key_length))
{
mi_check_print_error(param,"Can't delete key %d from record to be removed",i+1);
@@ -2740,8 +3309,7 @@ static int sort_delete_record(MI_CHECK *param)
}
}
if (param->calc_checksum)
- param->glob_crc-=(*info->s->calc_checksum)(info,
- sort_info->record);
+ param->glob_crc-=(*info->s->calc_checksum)(info, sort_param->record);
}
error=flush_io_cache(&info->rec_cache) || (*info->s->delete_record)(info);
info->dfile=old_file; /* restore actual value */
@@ -2749,20 +3317,20 @@ static int sort_delete_record(MI_CHECK *param)
DBUG_RETURN(error);
} /* sort_delete_record */
-
/* Fix all pending blocks and flush everything to disk */
-static int flush_pending_blocks(MI_CHECK *param)
+int flush_pending_blocks(MI_SORT_PARAM *sort_param)
{
uint nod_flag,length;
my_off_t filepos,key_file_length;
- MI_INFO *info;
SORT_KEY_BLOCKS *key_block;
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO *sort_info= sort_param->sort_info;
+ MI_CHECK *param=sort_info->param;
+ MI_INFO *info=sort_info->info;
+ MI_KEYDEF *keyinfo=sort_param->keyinfo;
DBUG_ENTER("flush_pending_blocks");
filepos= HA_OFFSET_ERROR; /* if empty file */
- info=sort_info->info;
nod_flag=0;
for (key_block=sort_info->key_block ; key_block->inited ; key_block++)
{
@@ -2771,30 +3339,26 @@ static int flush_pending_blocks(MI_CHECK *param)
if (nod_flag)
_mi_kpointer(info,key_block->end_pos,filepos);
key_file_length=info->state->key_file_length;
- bzero((byte*) key_block->buff+length,
- sort_info->keyinfo->block_length-length);
- if ((filepos=_mi_new(info,sort_info->keyinfo)) == HA_OFFSET_ERROR)
+ bzero((byte*) key_block->buff+length, keyinfo->block_length-length);
+ if ((filepos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
DBUG_RETURN(1);
/* If we read the page from the key cache, we have to write it back */
if (key_file_length == info->state->key_file_length)
{
- if (_mi_write_keypage(info, sort_info->keyinfo, filepos,
- key_block->buff))
+ if (_mi_write_keypage(info, keyinfo, filepos, key_block->buff))
DBUG_RETURN(1);
}
else if (my_pwrite(info->s->kfile,(byte*) key_block->buff,
- (uint) sort_info->keyinfo->block_length,filepos,
- param->myf_rw))
+ (uint) keyinfo->block_length,filepos, param->myf_rw))
DBUG_RETURN(1);
DBUG_DUMP("buff",(byte*) key_block->buff,length);
nod_flag=1;
}
- info->s->state.key_root[sort_info->key]=filepos; /* Last is root for tree */
+ info->s->state.key_root[sort_param->key]=filepos; /* Last is root for tree */
DBUG_RETURN(0);
} /* flush_pending_blocks */
-
/* alloc space and pointers for key_blocks */
static SORT_KEY_BLOCKS *alloc_key_blocks(MI_CHECK *param, uint blocks,
@@ -2846,7 +3410,6 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
MI_STATUS_INFO status_info;
uint unpack,key_parts;
ha_rows max_records;
- char name[FN_REFLEN];
ulonglong file_length,tmp_length;
MI_CREATE_INFO create_info;
@@ -2955,8 +3518,9 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
create_info.language = (param->language ? param->language :
share.state.header.language);
- if (mi_create(fn_format(name,filename,"",MI_NAME_IEXT,
- 4+ (param->opt_follow_links ? 16 : 0)),
+ /* We don't have to handle symlinks here because we are using
+ HA_DONT_TOUCH_DATA */
+ if (mi_create(filename,
share.base.keys - share.state.header.uniques,
keyinfo, share.base.fields, recdef,
share.state.header.uniques, uniquedef,
@@ -2966,7 +3530,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
mi_check_print_error(param,"Got error %d when trying to recreate indexfile",my_errno);
goto end;
}
- *org_info=mi_open(name,O_RDWR,
+ *org_info=mi_open(filename,O_RDWR,
(param->testflag & T_WAIT_FOREVER) ? HA_OPEN_WAIT_IF_LOCKED :
(param->testflag & T_DESCRIPT) ? HA_OPEN_IGNORE_IF_LOCKED :
HA_OPEN_ABORT_IF_LOCKED);
@@ -3004,24 +3568,25 @@ end:
/* write suffix to data file if neaded */
-int write_data_suffix(MI_CHECK *param, MI_INFO *info)
+int write_data_suffix(SORT_INFO *sort_info, my_bool fix_datafile)
{
- if (info->s->options & HA_OPTION_COMPRESS_RECORD &&
- param->sort_info.fix_datafile)
+ MI_INFO *info=sort_info->info;
+
+ if (info->s->options & HA_OPTION_COMPRESS_RECORD && fix_datafile)
{
char buff[MEMMAP_EXTRA_MARGIN];
bzero(buff,sizeof(buff));
if (my_b_write(&info->rec_cache,buff,sizeof(buff)))
{
- mi_check_print_error(param,"%d when writing to datafile",my_errno);
+ mi_check_print_error(sort_info->param,
+ "%d when writing to datafile",my_errno);
return 1;
}
- param->read_cache.end_of_file+=sizeof(buff);
+ sort_info->param->read_cache.end_of_file+=sizeof(buff);
}
return 0;
}
-
/* Update state and myisamchk_time of indexfile */
int update_state_info(MI_CHECK *param, MI_INFO *info,uint update)
@@ -3035,12 +3600,17 @@ int update_state_info(MI_CHECK *param, MI_INFO *info,uint update)
}
if (update & UPDATE_STAT)
{
- uint key_parts= mi_uint2korr(share->state.header.key_parts);
+ uint i, key_parts= mi_uint2korr(share->state.header.key_parts);
share->state.rec_per_key_rows=info->state->records;
- memcpy((char*) share->state.rec_per_key_part,
- (char*) param->rec_per_key_part,
- sizeof(*param->rec_per_key_part)*key_parts);
share->state.changed&= ~STATE_NOT_ANALYZED;
+ if (info->state->records)
+ {
+ for (i=0; i<key_parts; i++)
+ {
+ if (!(share->state.rec_per_key_part[i]=param->rec_per_key_part[i]))
+ share->state.changed|= STATE_NOT_ANALYZED;
+ }
+ }
}
if (update & (UPDATE_STAT | UPDATE_SORT | UPDATE_TIME | UPDATE_AUTO_INC))
{
@@ -3057,9 +3627,11 @@ int update_state_info(MI_CHECK *param, MI_INFO *info,uint update)
{ /* Force update of status */
int error;
uint r_locks=share->r_locks,w_locks=share->w_locks;
- share->r_locks=share->w_locks=0;
+ share->r_locks= share->w_locks= share->tot_locks= 0;
error=_mi_writeinfo(info,WRITEINFO_NO_UNLOCK);
- share->r_locks=r_locks; share->w_locks=w_locks;
+ share->r_locks=r_locks;
+ share->w_locks=w_locks;
+ share->tot_locks=r_locks+w_locks;
if (!error)
return 0;
}
@@ -3084,6 +3656,7 @@ err:
void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
my_bool repair_only)
{
+ byte *record;
if (!info->s->base.auto_key ||
!(((ulonglong) 1 << (info->s->base.auto_key-1)
& info->s->state.key_map)))
@@ -3095,15 +3668,26 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
return;
}
if (!(param->testflag & T_SILENT) &&
- !(param->testflag & (T_REP | T_REP_BY_SORT)))
+ !(param->testflag & T_REP))
printf("Updating MyISAM file: %s\n", param->isam_file_name);
- /* We have to use keyread here as a normal read uses info->rec_buff */
- mi_extra(info,HA_EXTRA_KEYREAD);
- if (mi_rlast(info,info->rec_buff, info->s->base.auto_key-1))
+ /*
+ We have to use an allocated buffer instead of info->rec_buff as
+ _mi_put_key_in_record() may use info->rec_buff
+ */
+ if (!(record= (byte*) my_malloc((uint) info->s->base.pack_reclength,
+ MYF(0))))
+ {
+ mi_check_print_error(param,"Not enough memory for extra record");
+ return;
+ }
+
+ mi_extra(info,HA_EXTRA_KEYREAD,0);
+ if (mi_rlast(info, record, info->s->base.auto_key-1))
{
if (my_errno != HA_ERR_END_OF_FILE)
{
- mi_extra(info,HA_EXTRA_NO_KEYREAD);
+ mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
+ my_free((char*) record, MYF(0));
mi_check_print_error(param,"%d when reading last record",my_errno);
return;
}
@@ -3115,20 +3699,19 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
ulonglong auto_increment= (repair_only ? info->s->state.auto_increment :
param->auto_increment_value);
info->s->state.auto_increment=0;
- update_auto_increment(info,info->rec_buff);
+ update_auto_increment(info, record);
set_if_bigger(info->s->state.auto_increment,auto_increment);
}
- mi_extra(info,HA_EXTRA_NO_KEYREAD);
+ mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
+ my_free((char*) record, MYF(0));
update_state_info(param, info, UPDATE_AUTO_INC);
return;
}
/* calculate unique keys for each part key */
-static void update_key_parts(MI_KEYDEF *keyinfo,
- ulong *rec_per_key_part,
- ulonglong *unique,
- ulonglong records)
+void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part,
+ ulonglong *unique, ulonglong records)
{
ulonglong count=0,tmp;
uint parts;
@@ -3139,6 +3722,9 @@ static void update_key_parts(MI_KEYDEF *keyinfo,
tmp=records;
else
tmp= (records + (count+1)/2) / (count+1);
+ /* for some weird keys (e.g. FULLTEXT) tmp can be <1 here.
+ let's ensure it is not */
+ set_if_bigger(tmp,1);
if (tmp >= (ulonglong) ~(ulong) 0)
tmp=(ulonglong) ~(ulong) 0;
*rec_per_key_part=(ulong) tmp;
@@ -3147,7 +3733,7 @@ static void update_key_parts(MI_KEYDEF *keyinfo,
}
-ha_checksum mi_byte_checksum(const byte *buf, uint length)
+static ha_checksum mi_byte_checksum(const byte *buf, uint length)
{
ha_checksum crc;
const byte *end=buf+length;
@@ -3168,12 +3754,15 @@ ha_checksum mi_byte_checksum(const byte *buf, uint length)
static my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
{
+ uint key_maxlength=key->maxlength;
+ if (key->flag & HA_FULLTEXT)
+ key_maxlength+=ft_max_word_len_for_sort-HA_FT_MAXLEN;
return (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY | HA_FULLTEXT) &&
- ((ulonglong) rows * key->maxlength >
+ ((ulonglong) rows * key_maxlength >
(ulonglong) myisam_max_temp_length ||
- (ulonglong) rows * (key->maxlength - key->minlength) / 2 >
+ (ulonglong) rows * (key_maxlength - key->minlength) / 2 >
myisam_max_extra_temp_length ||
- (rows == 0 && (key->maxlength / key->minlength) > 2)));
+ (rows == 0 && (key_maxlength / key->minlength) > 2)));
}
@@ -3186,8 +3775,8 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows)
MI_KEYDEF *key=share->keyinfo;
for (i=0 ; i < share->base.keys ; i++,key++)
{
- if (!(key->flag & HA_NOSAME) && ! mi_too_big_key_for_sort(key,rows) &&
- info->s->base.auto_key != i+1)
+ if (!(key->flag & (HA_NOSAME|HA_AUTO_KEY)) &&
+ ! mi_too_big_key_for_sort(key,rows))
{
share->state.key_map&= ~ ((ulonglong) 1 << i);
info->update|= HA_STATE_CHANGED;
@@ -3203,31 +3792,22 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows)
even if the temporary file would be quite big!
*/
-my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
- ulonglong key_map,
- my_bool force)
+my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
+ ulonglong key_map, my_bool force)
{
MYISAM_SHARE *share=info->s;
MI_KEYDEF *key=share->keyinfo;
uint i;
/*
- repair_by_sort only works if we have at least one key. If we don't
+ mi_repair_by_sort only works if we have at least one key. If we don't
have any keys, we should use the normal repair.
*/
if (!key_map)
return FALSE; /* Can't use sort */
for (i=0 ; i < share->base.keys ; i++,key++)
{
-/* It's to disable repair_by_sort for ft-keys.
- Another solution would be to make ft-keys just too_big_key_for_sort,
- but then they won't be disabled by dectivate_non_unique_index
- and so they will be created at the first stage. As ft-key creation
- is very time-consuming process, it's better to leave it to repair stage
- but this repair shouldn't be repair_by_sort (serg)
- */
- if ((!force && mi_too_big_key_for_sort(key,rows)) ||
- (key->flag & HA_FULLTEXT))
+ if (!force && mi_too_big_key_for_sort(key,rows))
return FALSE;
}
return TRUE;
@@ -3235,10 +3815,10 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
static void
-set_data_file_type(MI_CHECK *param, SORT_INFO *sort_info, MYISAM_SHARE *share)
+set_data_file_type(SORT_INFO *sort_info, MYISAM_SHARE *share)
{
if ((sort_info->new_data_file_type=share->data_file_type) ==
- COMPRESSED_RECORD && param->testflag & T_UNPACK)
+ COMPRESSED_RECORD && sort_info->param->testflag & T_UNPACK)
{
MYISAM_SHARE tmp;
diff --git a/myisam/mi_checksum.c b/myisam/mi_checksum.c
index 9dabe55e239..a760b03a032 100644
--- a/myisam/mi_checksum.c
+++ b/myisam/mi_checksum.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_close.c b/myisam/mi_close.c
index f30119144bc..dbaaebb1143 100644
--- a/myisam/mi_close.c
+++ b/myisam/mi_close.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -29,8 +29,7 @@ int mi_close(register MI_INFO *info)
MYISAM_SHARE *share=info->s;
DBUG_ENTER("mi_close");
DBUG_PRINT("enter",("base: %lx reopen: %u locks: %u",
- info,(uint) share->reopen,
- (uint) (share->w_locks+share->r_locks)));
+ info,(uint) share->reopen, (uint) share->tot_locks));
pthread_mutex_lock(&THR_LOCK_myisam);
if (info->lock_type == F_EXTRA_LCK)
@@ -47,7 +46,10 @@ int mi_close(register MI_INFO *info)
pthread_mutex_lock(&share->intern_lock);
if (share->options & HA_OPTION_READ_ONLY_DATA)
+ {
share->r_locks--;
+ share->tot_locks--;
+ }
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
{
if (end_io_cache(&info->rec_cache))
@@ -58,6 +60,7 @@ int mi_close(register MI_INFO *info)
myisam_open_list=list_delete(myisam_open_list,&info->open_list);
pthread_mutex_unlock(&share->intern_lock);
+ my_free(mi_get_rec_buff_ptr(info, info->rec_buff), MYF(MY_ALLOW_ZERO_PTR));
if (flag)
{
if (share->kfile >= 0 &&
@@ -99,7 +102,6 @@ int mi_close(register MI_INFO *info)
error = my_errno;
myisam_log_command(MI_LOG_CLOSE,info,NULL,0,error);
- my_free((gptr) info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr) info,MYF(0));
if (error)
diff --git a/myisam/mi_create.c b/myisam/mi_create.c
index d0ba37a77c6..9f39c6f522e 100644
--- a/myisam/mi_create.c
+++ b/myisam/mi_create.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -38,12 +38,13 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
register uint i,j;
File dfile,file;
int errpos,save_errno;
+ myf create_flag;
uint fields,length,max_key_length,packed,pointer,
key_length,info_length,key_segs,options,min_key_length_skipp,
base_pos,varchar_count,long_varchar_count,varchar_length,
max_key_block_length,unique_key_parts,offset;
ulong reclength, real_reclength,min_pack_length;
- char buff[FN_REFLEN];
+ char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
ulong pack_reclength;
ulonglong tot_length,max_rows;
enum en_fieldtype type;
@@ -118,8 +119,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
pack_reclength+=(1 << ((rec->length-mi_portable_sizeof_char_ptr)*8)); /* Max blob length */
}
}
- else if (type == FIELD_SKIPP_PRESPACE ||
- type == FIELD_SKIPP_ENDSPACE)
+ else if (type == FIELD_SKIP_PRESPACE ||
+ type == FIELD_SKIP_ENDSPACE)
{
if (pack_reclength != INT_MAX32)
pack_reclength+= rec->length > 255 ? 2 : 1;
@@ -137,7 +138,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
pack_reclength+=2;
}
}
- else if (type != FIELD_SKIPP_ZERO)
+ else if (type != FIELD_SKIP_ZERO)
{
min_pack_length+=rec->length;
packed--; /* Not a pack record type */
@@ -151,7 +152,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
while (rec != recinfo)
{
rec--;
- if (rec->type == (int) FIELD_SKIPP_ZERO && rec->length == 1)
+ if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1)
{
rec->type=(int) FIELD_NORMAL;
packed--;
@@ -163,6 +164,9 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (packed || (flags & HA_PACK_RECORD))
options|=HA_OPTION_PACK_RECORD; /* Must use packed records */
+ /* We can't use checksum with static length rows */
+ if (!(options & HA_OPTION_PACK_RECORD))
+ options&= ~HA_OPTION_CHECKSUM;
if (options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))
min_pack_length+=varchar_count; /* Min length to pack */
else
@@ -223,8 +227,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.state.key_del=key_del;
if (uniques)
{
- max_key_block_length= MI_KEY_BLOCK_LENGTH;
- max_key_length= MI_UNIQUE_HASH_LENGTH + pointer;
+ max_key_block_length= myisam_block_size;
+ max_key_length= MI_UNIQUE_HASH_LENGTH + pointer;
}
for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
@@ -282,7 +286,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
keydef->seg[0].type == (int) HA_KEYTYPE_NUM)
keydef->seg[0].flag&= ~HA_SPACE_PACK;
- /* Only use HA_PACK_KEY if the first segment is a variable length key */
+ /* Only use HA_PACK_KEY when first segment is a variable length key */
if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
HA_VAR_LENGTH)))
{
@@ -300,7 +304,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (keydef->flag & HA_BINARY_PACK_KEY)
options|=HA_OPTION_PACK_KEYS; /* Using packed keys */
- if (keydef->flag & HA_AUTO_KEY)
+ if (keydef->flag & HA_AUTO_KEY && ci->with_auto_increment)
share.base.auto_key=i+1;
for (j=0, keyseg=keydef->seg ; j < keydef->keysegs ; j++, keyseg++)
{
@@ -366,7 +370,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.state.rec_per_key_part[key_segs-1]=1L;
length+=key_length;
keydef->block_length= MI_BLOCK_SIZE(length,pointer,MI_MAX_KEYPTR_SIZE);
- if (keydef->block_length/MI_KEY_BLOCK_LENGTH > MI_MAX_KEY_BLOCK_SIZE)
+ if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
+ length >= MI_MAX_KEY_BUFF)
{
my_errno=HA_WRONG_CREATE_OPTION;
goto err;
@@ -382,7 +387,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
(length*2)))*
(ulong) keydef->block_length;
}
- for (i=max_key_block_length/MI_KEY_BLOCK_LENGTH ; i-- ; )
+ for (i=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
key_del[i]=HA_OFFSET_ERROR;
unique_key_parts=0;
@@ -400,7 +405,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
key_segs+=uniques; /* Each unique has 1 key seg */
base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE +
- max_key_block_length/MI_KEY_BLOCK_LENGTH*MI_STATE_KEYBLOCK_SIZE+
+ max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH*
+ MI_STATE_KEYBLOCK_SIZE+
key_segs*MI_STATE_KEYSEG_SIZE);
info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+
keys * MI_KEYDEF_SIZE+
@@ -419,7 +425,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
mi_int2store(share.state.header.base_pos,base_pos);
share.state.header.language= (ci->language ?
ci->language : MY_CHARSET_CURRENT);
- share.state.header.max_block_size=max_key_block_length/MI_KEY_BLOCK_LENGTH;
+ share.state.header.max_block_size=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
share.state.dellink = HA_OFFSET_ERROR;
share.state.process= (ulong) getpid();
@@ -432,7 +438,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.base.rec_reflength=pointer;
share.base.key_reflength=
mi_get_pointer_length((tot_length + max_key_block_length * keys *
- MI_INDEX_BLOCK_MARGIN) / MI_KEY_BLOCK_LENGTH,
+ MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH,
3);
share.base.keys= share.state.header.keys = keys;
share.state.header.uniques= uniques;
@@ -471,17 +477,40 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (! (flags & HA_DONT_TOUCH_DATA))
share.state.create_time= (long) time((time_t*) 0);
- if ((file = my_create(fn_format(buff,name,"",MI_NAME_IEXT,4),0,
- O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
+ if (ci->index_file_name)
+ {
+ fn_format(filename, ci->index_file_name,"",MI_NAME_IEXT,4);
+ fn_format(linkname,name, "",MI_NAME_IEXT,4);
+ linkname_ptr=linkname;
+ /*
+ Don't create the table if the link or file exists to ensure that one
+ doesn't accidently destroy another table.
+ */
+ create_flag=0;
+ }
+ else
+ {
+ fn_format(filename,name,"",MI_NAME_IEXT,(4+ (flags & HA_DONT_TOUCH_DATA) ?
+ 32 : 0));
+ linkname_ptr=0;
+ /* Replace the current file */
+ create_flag=MY_DELETE_OLD;
+ }
+
+ if ((file= my_create_with_symlink(linkname_ptr,
+ filename,
+ 0, O_RDWR | O_TRUNC,
+ MYF(MY_WME | create_flag))) < 0)
goto err;
errpos=1;
- VOID(fn_format(buff,name,"",MI_NAME_DEXT,2+4));
+
if (!(flags & HA_DONT_TOUCH_DATA))
{
#ifdef USE_RAID
if (share.base.raid_type)
{
- if ((dfile=my_raid_create(buff,0,O_RDWR | O_TRUNC,
+ (void) fn_format(filename,name,"",MI_NAME_DEXT,2+4);
+ if ((dfile=my_raid_create(filename,0,O_RDWR | O_TRUNC,
share.base.raid_type,
share.base.raid_chunks,
share.base.raid_chunksize,
@@ -490,9 +519,26 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
}
else
#endif
- if ((dfile = my_create(buff,0,O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
- goto err;
-
+ {
+ if (ci->data_file_name)
+ {
+ fn_format(filename, ci->data_file_name,"",MI_NAME_DEXT,4);
+ fn_format(linkname, name, "",MI_NAME_DEXT,4);
+ linkname_ptr=linkname;
+ create_flag=0;
+ }
+ else
+ {
+ fn_format(filename,name,"",MI_NAME_DEXT,4);
+ linkname_ptr=0;
+ create_flag=MY_DELETE_OLD;
+ }
+ if ((dfile=
+ my_create_with_symlink(linkname_ptr, filename,
+ 0,O_RDWR | O_TRUNC,
+ MYF(MY_WME | create_flag))) < 0)
+ goto err;
+ }
errpos=3;
}
@@ -511,14 +557,14 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
/* Write key and keyseg definitions */
for (i=0 ; i < share.base.keys - uniques; i++)
{
- uint ft_segs=(keydefs[i].flag & HA_FULLTEXT) ? FT_SEGS : 0; /* SerG */
+ uint ft_segs=(keydefs[i].flag & HA_FULLTEXT) ? FT_SEGS : 0;
if (mi_keydef_write(file, &keydefs[i]))
goto err;
for (j=0 ; j < keydefs[i].keysegs-ft_segs ; j++)
if (mi_keyseg_write(file, &keydefs[i].seg[j]))
goto err;
- for (j=0 ; j < ft_segs ; j++) /* SerG */
+ for (j=0 ; j < ft_segs ; j++)
{
MI_KEYSEG seg=ft_keysegs[j];
seg.language= keydefs[i].seg[0].language;
@@ -534,11 +580,11 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
{
tmp_keydef.keysegs=1;
tmp_keydef.flag= HA_UNIQUE_CHECK;
- tmp_keydef.block_length= MI_KEY_BLOCK_LENGTH;
+ tmp_keydef.block_length= myisam_block_size;
tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer;
tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;
- tmp_keyseg.type= MI_UNIQUE_HASH_TYPE;
- tmp_keyseg.length= MI_UNIQUE_HASH_LENGTH;
+ tmp_keyseg.type= MI_UNIQUE_HASH_TYPE;
+ tmp_keyseg.length= MI_UNIQUE_HASH_LENGTH;
tmp_keyseg.start= offset;
offset+= MI_UNIQUE_HASH_LENGTH;
if (mi_keydef_write(file,&tmp_keydef) ||
@@ -571,13 +617,13 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
#endif
/* Enlarge files */
- if (my_chsize(file,(ulong) share.base.keystart,MYF(0)))
+ if (my_chsize(file,(ulong) share.base.keystart,0,MYF(0)))
goto err;
if (! (flags & HA_DONT_TOUCH_DATA))
{
#ifdef USE_RELOC
- if (my_chsize(dfile,share.base.min_pack_length*ci->reloc_rows,MYF(0)))
+ if (my_chsize(dfile,share.base.min_pack_length*ci->reloc_rows,0,MYF(0)))
goto err;
#endif
errpos=2;
@@ -599,20 +645,16 @@ err:
VOID(my_close(dfile,MYF(0)));
/* fall through */
case 2:
- if (! (flags & HA_DONT_TOUCH_DATA))
- {
/* QQ: Tõnu should add a call to my_raid_delete() here */
- VOID(fn_format(buff,name,"",MI_NAME_DEXT,2+4));
- my_delete(buff,MYF(0));
- }
+ if (! (flags & HA_DONT_TOUCH_DATA))
+ my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,2+4),
+ MYF(0));
/* fall through */
case 1:
VOID(my_close(file,MYF(0)));
if (! (flags & HA_DONT_TOUCH_DATA))
- {
- VOID(fn_format(buff,name,"",MI_NAME_IEXT,2+4));
- my_delete(buff,MYF(0));
- }
+ my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,2+4),
+ MYF(0));
}
my_free((char*) rec_per_key_part, MYF(0));
DBUG_RETURN(my_errno=save_errno); /* return the fatal errno */
diff --git a/myisam/mi_dbug.c b/myisam/mi_dbug.c
index eda1aafecc8..fe5b36fd304 100644
--- a/myisam/mi_dbug.c
+++ b/myisam/mi_dbug.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -137,6 +137,10 @@ void _mi_print_key(FILE *stream, register MI_KEYSEG *keyseg,
{
uint tmp_length;
get_key_length(tmp_length,key);
+ /*
+ The following command sometimes gives a warning from valgrind.
+ Not yet sure if the bug is in valgrind, glibc or mysqld
+ */
VOID(fprintf(stream,"%.*s",(int) tmp_length,key));
key+=tmp_length;
break;
@@ -162,7 +166,7 @@ my_bool check_table_is_closed(const char *name, const char *where)
{
MI_INFO *info=(MI_INFO*) pos->data;
MYISAM_SHARE *share=info->s;
- if (!strcmp(share->filename,filename))
+ if (!strcmp(share->unique_file_name,filename))
{
if (share->last_version)
{
diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c
index 445e745b07d..6f94e3c4256 100644
--- a/myisam/mi_delete.c
+++ b/myisam/mi_delete.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -97,6 +97,12 @@ int mi_delete(MI_INFO *info,const byte *record)
myisam_log_command(MI_LOG_DELETE,info,(byte*) lastpos,sizeof(lastpos),0);
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
allow_break(); /* Allow SIGHUP & SIGINT */
+ if (info->invalidator != 0)
+ {
+ DBUG_PRINT("info", ("invalidator... '%s' (delete)", info->filename));
+ (*info->invalidator)(info->filename);
+ info->invalidator=0;
+ }
DBUG_RETURN(0);
err:
@@ -196,7 +202,8 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_ENTER("d_search");
DBUG_DUMP("page",(byte*) anc_buff,mi_getint(anc_buff));
- flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key,key_length,SEARCH_SAME,
+ flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, USE_WHOLE_KEY,
+ SEARCH_SAME,
&keypos, lastkey, &last_key);
if (flag == MI_FOUND_WRONG_KEY)
{
diff --git a/myisam/mi_delete_all.c b/myisam/mi_delete_all.c
index c3ed9455e12..45e56626d59 100644
--- a/myisam/mi_delete_all.c
+++ b/myisam/mi_delete_all.c
@@ -1,21 +1,21 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Remove all rows from a MyISAM table */
-/* This only clears the status information; The files are not truncated */
+/* This clears the status information and truncates files */
#include "myisamdef.h"
@@ -43,12 +43,20 @@ int mi_delete_all_rows(MI_INFO *info)
info->state->empty=info->state->key_empty=0;
state->checksum=0;
- for (i=share->base.max_key_block_length/MI_KEY_BLOCK_LENGTH ; i-- ; )
+ for (i=share->base.max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
state->key_del[i]= HA_OFFSET_ERROR;
for (i=0 ; i < share->base.keys ; i++)
state->key_root[i]= HA_OFFSET_ERROR;
myisam_log_command(MI_LOG_DELETE_ALL,info,(byte*) 0,0,0);
+ /*
+ If we are using delayed keys or if the user has done changes to the tables
+ since it was locked then there may be key blocks in the key cache
+ */
+ flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
+ if (my_chsize(info->dfile, 0, 0, MYF(MY_WME)) ||
+ my_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)) )
+ goto err;
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(0);
@@ -62,4 +70,3 @@ err:
DBUG_RETURN(my_errno=save_errno);
}
} /* mi_delete */
-
diff --git a/myisam/mi_delete_table.c b/myisam/mi_delete_table.c
index 995106160ef..6d842d7e6a4 100644
--- a/myisam/mi_delete_table.c
+++ b/myisam/mi_delete_table.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -50,12 +50,12 @@ int mi_delete_table(const char *name)
#endif /* USE_RAID */
fn_format(from,name,"",MI_NAME_IEXT,4);
- if (my_delete(from, MYF(MY_WME)))
+ if (my_delete_with_symlink(from, MYF(MY_WME)))
DBUG_RETURN(my_errno);
fn_format(from,name,"",MI_NAME_DEXT,4);
#ifdef USE_RAID
if (raid_type)
DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME)) ? my_errno : 0);
#endif
- DBUG_RETURN(my_delete(from, MYF(MY_WME)) ? my_errno : 0);
+ DBUG_RETURN(my_delete_with_symlink(from, MYF(MY_WME)) ? my_errno : 0);
}
diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c
index c08723d7a2c..2a3f4aec0a8 100644
--- a/myisam/mi_dynrec.c
+++ b/myisam/mi_dynrec.c
@@ -1,22 +1,31 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
- /* Functions to handle space-packed-records and blobs */
+/*
+ Functions to handle space-packed-records and blobs
+
+ A row may be stored in one or more linked blocks.
+ The block size is between MI_MIN_BLOCK_LENGTH and MI_MAX_BLOCK_LENGTH.
+ Each block is aligned on MI_DYN_ALIGN_SIZE.
+ The reson for the max block size is to not have too many different types
+ of blocks. For the differnet block types, look at _mi_get_block_info()
+*/
#include "myisamdef.h"
+#include <assert.h>
/* Enough for comparing if number is zero */
static char zero_string[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -58,26 +67,31 @@ int _mi_write_blob_record(MI_INFO *info, const byte *record)
{
byte *rec_buff;
int error;
- ulong reclength,extra;
+ ulong reclength,reclength2,extra;
- extra=ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
- MI_DYN_DELETE_BLOCK_HEADER+1;
- reclength= (info->s->base.pack_reclength+
+ extra= (ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
+ MI_DYN_DELETE_BLOCK_HEADER+1);
+ reclength= (info->s->base.pack_reclength +
_my_calc_total_blob_length(info,record)+ extra);
+#ifdef NOT_USED /* We now support big rows */
if (reclength > MI_DYN_MAX_ROW_LENGTH)
{
my_errno=HA_ERR_TO_BIG_ROW;
return -1;
}
+#endif
if (!(rec_buff=(byte*) my_alloca(reclength)))
{
my_errno=ENOMEM;
return(-1);
}
- reclength=_mi_rec_pack(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
- record);
+ reclength2= _mi_rec_pack(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
+ record);
+ DBUG_PRINT("info",("reclength: %lu reclength2: %lu",
+ reclength, reclength2));
+ DBUG_ASSERT(reclength2 <= reclength);
error=write_dynamic_record(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
- reclength);
+ reclength2);
my_afree(rec_buff);
return(error);
}
@@ -89,15 +103,17 @@ int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const byte *record)
int error;
ulong reclength,extra;
- extra=ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
- MI_DYN_DELETE_BLOCK_HEADER;
- reclength=info->s->base.pack_reclength+
- _my_calc_total_blob_length(info,record)+ extra;
+ extra= (ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
+ MI_DYN_DELETE_BLOCK_HEADER);
+ reclength= (info->s->base.pack_reclength+
+ _my_calc_total_blob_length(info,record)+ extra);
+#ifdef NOT_USED /* We now support big rows */
if (reclength > MI_DYN_MAX_ROW_LENGTH)
{
my_errno=HA_ERR_TO_BIG_ROW;
return -1;
}
+#endif
if (!(rec_buff=(byte*) my_alloca(reclength)))
{
my_errno=ENOMEM;
@@ -130,17 +146,17 @@ static int write_dynamic_record(MI_INFO *info, const byte *record,
DBUG_ENTER("write_dynamic_record");
flag=0;
- while (reclength)
+ do
{
if (_mi_find_writepos(info,reclength,&filepos,&length))
goto err;
if (_mi_write_part_record(info,filepos,length,info->s->state.dellink,
(byte**) &record,&reclength,&flag))
goto err;
- }
+ } while (reclength);
DBUG_RETURN(0);
- err:
+err:
DBUG_RETURN(1);
}
@@ -153,12 +169,12 @@ static int _mi_find_writepos(MI_INFO *info,
ulong *length) /* length of block at filepos */
{
MI_BLOCK_INFO block_info;
+ ulong tmp;
DBUG_ENTER("_mi_find_writepos");
if (info->s->state.dellink != HA_OFFSET_ERROR)
{
/* Deleted blocks exists; Get last used block */
-
*filepos=info->s->state.dellink;
block_info.second_read=0;
info->rec_cache.seek_not_done=1;
@@ -178,19 +194,22 @@ static int _mi_find_writepos(MI_INFO *info,
{
/* No deleted blocks; Allocate a new block */
*filepos=info->state->data_file_length;
- if ((*length=reclength+3 + test(reclength >= (65520-3))) <
+ if ((tmp=reclength+3 + test(reclength >= (65520-3))) <
info->s->base.min_block_length)
- *length=info->s->base.min_block_length;
+ tmp= info->s->base.min_block_length;
else
- *length= ((*length+MI_DYN_ALIGN_SIZE-1) &
- (~ (ulong) (MI_DYN_ALIGN_SIZE-1)));
+ tmp= ((tmp+MI_DYN_ALIGN_SIZE-1) &
+ (~ (ulong) (MI_DYN_ALIGN_SIZE-1)));
if (info->state->data_file_length >
- (info->s->base.max_data_file_length- *length))
+ (info->s->base.max_data_file_length - tmp))
{
my_errno=HA_ERR_RECORD_FILE_FULL;
DBUG_RETURN(-1);
}
- info->state->data_file_length+= *length;
+ if (tmp > MI_MAX_BLOCK_LENGTH)
+ tmp=MI_MAX_BLOCK_LENGTH;
+ *length= tmp;
+ info->state->data_file_length+= tmp;
info->s->state.split++;
info->update|=HA_STATE_WRITE_AT_END;
}
@@ -199,7 +218,11 @@ static int _mi_find_writepos(MI_INFO *info,
-/* Remove a deleted block from the deleted list */
+/*
+ Unlink a deleted block from the deleted list.
+ This block will be combined with the preceding or next block to form
+ a big block.
+*/
static bool unlink_deleted_block(MI_INFO *info, MI_BLOCK_INFO *block_info)
{
@@ -213,6 +236,7 @@ static bool unlink_deleted_block(MI_INFO *info, MI_BLOCK_INFO *block_info)
{
MI_BLOCK_INFO tmp;
tmp.second_read=0;
+ /* Unlink block from the previous block */
if (!(_mi_get_block_info(&tmp,info->dfile,block_info->prev_filepos)
& BLOCK_DELETED))
DBUG_RETURN(1); /* Something is wrong */
@@ -220,6 +244,7 @@ static bool unlink_deleted_block(MI_INFO *info, MI_BLOCK_INFO *block_info)
if (my_pwrite(info->dfile,(char*) tmp.header+4,8,
block_info->prev_filepos+4, MYF(MY_NABP)))
DBUG_RETURN(1);
+ /* Unlink block from next block */
if (block_info->next_filepos != HA_OFFSET_ERROR)
{
if (!(_mi_get_block_info(&tmp,info->dfile,block_info->next_filepos)
@@ -232,47 +257,77 @@ static bool unlink_deleted_block(MI_INFO *info, MI_BLOCK_INFO *block_info)
DBUG_RETURN(1);
}
}
+ /* We now have one less deleted block */
info->state->del--;
info->state->empty-= block_info->block_len;
info->s->state.split--;
- /* Removing block that we are using through mi_rrnd */
+ /*
+ If this was a block that we where accessing through table scan
+ (mi_rrnd() or mi_scan(), then ensure that we skip over this block
+ when doing next mi_rrnd() or mi_scan().
+ */
if (info->nextpos == block_info->filepos)
info->nextpos+=block_info->block_len;
DBUG_RETURN(0);
}
- /* Delete datarecord from database */
- /* info->rec_cache.seek_not_done is updated in cmp_record */
-static int delete_dynamic_record(MI_INFO *info, my_off_t filepos,
- uint second_read)
+/*
+ Add a backward link to delete block
+
+ SYNOPSIS
+ update_backward_delete_link()
+ info MyISAM handler
+ delete_block Position to delete block to update.
+ If this is 'HA_OFFSET_ERROR', nothing will be done
+ filepos Position to block that 'delete_block' should point to
+
+ RETURN
+ 0 ok
+ 1 error. In this case my_error is set.
+*/
+
+static int update_backward_delete_link(MI_INFO *info, my_off_t delete_block,
+ my_off_t filepos)
{
- uint length,b_type;
- MI_BLOCK_INFO block_info,del_block;
- int error=0;
- my_bool remove_next_block;
- DBUG_ENTER("delete_dynamic_record");
+ MI_BLOCK_INFO block_info;
+ DBUG_ENTER("update_backward_delete_link");
- /* First add a link from the last block to the new one */
- if (info->s->state.dellink != HA_OFFSET_ERROR)
+ if (delete_block != HA_OFFSET_ERROR)
{
block_info.second_read=0;
- if (_mi_get_block_info(&block_info,info->dfile,info->s->state.dellink)
+ if (_mi_get_block_info(&block_info,info->dfile,delete_block)
& BLOCK_DELETED)
{
char buff[8];
mi_sizestore(buff,filepos);
- if (my_pwrite(info->dfile,buff,8,info->s->state.dellink+12,
- MYF(MY_NABP)))
- error=1; /* Error on write */
+ if (my_pwrite(info->dfile,buff, 8, delete_block+12, MYF(MY_NABP)))
+ DBUG_RETURN(1); /* Error on write */
}
else
{
- error=1; /* Wrong delete link */
my_errno=HA_ERR_WRONG_IN_RECORD;
+ DBUG_RETURN(1); /* Wrong delete link */
}
}
+ return 0;
+}
+
+ /* Delete datarecord from database */
+ /* info->rec_cache.seek_not_done is updated in cmp_record */
+
+static int delete_dynamic_record(MI_INFO *info, my_off_t filepos,
+ uint second_read)
+{
+ uint length,b_type;
+ MI_BLOCK_INFO block_info,del_block;
+ int error;
+ my_bool remove_next_block;
+ DBUG_ENTER("delete_dynamic_record");
+
+ /* First add a link from the last block to the new one */
+ error= update_backward_delete_link(info, info->s->state.dellink, filepos);
block_info.second_read=second_read;
do
@@ -313,7 +368,7 @@ static int delete_dynamic_record(MI_INFO *info, my_off_t filepos,
info->state->empty+=length;
filepos=block_info.next_filepos;
- /* Now it's safe to unlink the block */
+ /* Now it's safe to unlink the deleted block directly after this one */
if (remove_next_block && unlink_deleted_block(info,&del_block))
error=1;
} while (!(b_type & BLOCK_LAST));
@@ -370,19 +425,30 @@ int _mi_write_part_record(MI_INFO *info,
info->s->state.dellink : info->state->data_file_length;
if (*flag == 0) /* First block */
{
- head_length=5+8+long_block*2;
- temp[0]=5+(uchar) long_block;
- if (long_block)
+ if (*reclength > MI_MAX_BLOCK_LENGTH)
{
- mi_int3store(temp+1,*reclength);
- mi_int3store(temp+4,length-head_length);
- mi_sizestore((byte*) temp+7,next_filepos);
+ head_length= 16;
+ temp[0]=13;
+ mi_int4store(temp+1,*reclength);
+ mi_int3store(temp+5,length-head_length);
+ mi_sizestore((byte*) temp+8,next_filepos);
}
else
{
- mi_int2store(temp+1,*reclength);
- mi_int2store(temp+3,length-head_length);
- mi_sizestore((byte*) temp+5,next_filepos);
+ head_length=5+8+long_block*2;
+ temp[0]=5+(uchar) long_block;
+ if (long_block)
+ {
+ mi_int3store(temp+1,*reclength);
+ mi_int3store(temp+4,length-head_length);
+ mi_sizestore((byte*) temp+7,next_filepos);
+ }
+ else
+ {
+ mi_int2store(temp+1,*reclength);
+ mi_int2store(temp+3,length-head_length);
+ mi_sizestore((byte*) temp+5,next_filepos);
+ }
}
}
else
@@ -466,7 +532,7 @@ int _mi_write_part_record(MI_INFO *info,
{
info->update&= ~HA_STATE_EXTEND_BLOCK;
if (my_block_write(&info->rec_cache,(byte*) *record-head_length,
- length+extra_length+del_length,filepos))
+ length+extra_length+del_length,filepos))
goto err;
}
else if (my_b_write(&info->rec_cache,(byte*) *record-head_length,
@@ -485,21 +551,11 @@ int _mi_write_part_record(MI_INFO *info,
*reclength-=(length-head_length);
*flag=6;
- if (del_length && next_delete_block != HA_OFFSET_ERROR)
+ if (del_length)
{
/* link the next delete block to this */
- MI_BLOCK_INFO del_block;
- del_block.second_read=0;
- if (!(_mi_get_block_info(&del_block,info->dfile,next_delete_block)
- & BLOCK_DELETED))
- {
- my_errno=HA_ERR_WRONG_IN_RECORD;
- goto err;
- }
- mi_sizestore(del_block.header+12,info->s->state.dellink);
- if (my_pwrite(info->dfile,(char*) del_block.header+12,8,
- next_delete_block+12,
- MYF(MY_NABP)))
+ if (update_backward_delete_link(info, next_delete_block,
+ info->s->state.dellink))
goto err;
}
@@ -541,6 +597,8 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, byte *record,
{
uint tmp=MY_ALIGN(reclength - length + 3 +
test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
+ tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
/* Check if we can extend this block */
if (block_info.filepos + block_info.block_len ==
info->state->data_file_length &&
@@ -555,9 +613,15 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, byte *record,
info->update|= HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK;
length+=tmp;
}
- else
+ else if (length < MI_MAX_BLOCK_LENGTH - MI_MIN_BLOCK_LENGTH)
{
- /* Check if next block is a deleted block */
+ /*
+ Check if next block is a deleted block
+ Above we have MI_MIN_BLOCK_LENGTH to avoid the problem where
+ the next block is so small it can't be splited which could
+ casue problems
+ */
+
MI_BLOCK_INFO del_block;
del_block.second_read=0;
if (_mi_get_block_info(&del_block,info->dfile,
@@ -568,7 +632,35 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, byte *record,
DBUG_PRINT("info",("Extending current block"));
if (unlink_deleted_block(info,&del_block))
goto err;
- length+=del_block.block_len;
+ if ((length+=del_block.block_len) > MI_MAX_BLOCK_LENGTH)
+ {
+ /*
+ New block was too big, link overflow part back to
+ delete list
+ */
+ my_off_t next_pos;
+ ulong rest_length= length-MI_MAX_BLOCK_LENGTH;
+ set_if_bigger(rest_length, MI_MIN_BLOCK_LENGTH);
+ next_pos= del_block.filepos+ del_block.block_len - rest_length;
+
+ if (update_backward_delete_link(info, info->s->state.dellink,
+ next_pos))
+ DBUG_RETURN(1);
+
+ /* create delete link for data that didn't fit into the page */
+ del_block.header[0]=0;
+ mi_int3store(del_block.header+1, rest_length);
+ mi_sizestore(del_block.header+4,info->s->state.dellink);
+ bfill(del_block.header+12,8,255);
+ if (my_pwrite(info->dfile,(byte*) del_block.header,20, next_pos,
+ MYF(MY_NABP)))
+ DBUG_RETURN(1);
+ info->s->state.dellink= next_pos;
+ info->s->state.split++;
+ info->state->del++;
+ info->state->empty+= rest_length;
+ length-= rest_length;
+ }
}
}
}
@@ -582,7 +674,10 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, byte *record,
&record,&reclength,&flag))
goto err;
if ((filepos=block_info.next_filepos) == HA_OFFSET_ERROR)
+ {
+ /* Start writing data on deleted blocks */
filepos=info->s->state.dellink;
+ }
}
if (block_info.next_filepos != HA_OFFSET_ERROR)
@@ -629,7 +724,7 @@ uint _mi_rec_pack(MI_INFO *info, register byte *to, register const byte *from)
}
blob++;
}
- else if (type == FIELD_SKIPP_ZERO)
+ else if (type == FIELD_SKIP_ZERO)
{
if (memcmp((byte*) from,zero_string,length) == 0)
flag|=bit;
@@ -638,11 +733,11 @@ uint _mi_rec_pack(MI_INFO *info, register byte *to, register const byte *from)
memcpy((byte*) to,from,(size_t) length); to+=length;
}
}
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
pos= (byte*) from; end= (byte*) from + length;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{ /* Pack trailing spaces */
while (end > from && *(end-1) == ' ')
end--;
@@ -707,11 +802,12 @@ uint _mi_rec_pack(MI_INFO *info, register byte *to, register const byte *from)
/*
-** Check if a record was correctly packed. Used only by isamchk
-** Returns 0 if record is ok.
+ Check if a record was correctly packed. Used only by myisamchk
+ Returns 0 if record is ok.
*/
-my_bool _mi_rec_check(MI_INFO *info,const char *record)
+my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *rec_buff,
+ ulong packed_length)
{
uint length,new_length,flag,bit,i;
char *pos,*end,*packpos,*to;
@@ -719,7 +815,7 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record)
reg3 MI_COLUMNDEF *rec;
DBUG_ENTER("_mi_rec_check");
- packpos=info->rec_buff; to= info->rec_buff+info->s->base.pack_bits;
+ packpos=rec_buff; to= rec_buff+info->s->base.pack_bits;
rec=info->s->rec;
flag= *packpos; bit=1;
@@ -737,7 +833,7 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record)
if (blob_length)
to+=length - mi_portable_sizeof_char_ptr+ blob_length;
}
- else if (type == FIELD_SKIPP_ZERO)
+ else if (type == FIELD_SKIP_ZERO)
{
if (memcmp((byte*) record,zero_string,length) == 0)
{
@@ -747,11 +843,11 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record)
else
to+=length;
}
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
pos= (byte*) record; end= (byte*) record + length;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{ /* Pack trailing spaces */
while (end > record && *(end-1) == ' ')
end--;
@@ -803,8 +899,7 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record)
to+=length;
}
}
- if (info->packed_length != (uint) (to - info->rec_buff)
- + test(info->s->calc_checksum) ||
+ if (packed_length != (uint) (to - rec_buff) + test(info->s->calc_checksum) ||
(bit != 1 && (flag & ~(bit - 1))))
goto err;
if (info->s->calc_checksum)
@@ -817,7 +912,7 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record)
}
DBUG_RETURN(0);
- err:
+err:
DBUG_RETURN(1);
}
@@ -863,10 +958,10 @@ ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
}
if (flag & bit)
{
- if (type == FIELD_BLOB || type == FIELD_SKIPP_ZERO)
+ if (type == FIELD_BLOB || type == FIELD_SKIP_ZERO)
bzero((byte*) to,rec_length);
- else if (type == FIELD_SKIPP_ENDSPACE ||
- type == FIELD_SKIPP_PRESPACE)
+ else if (type == FIELD_SKIP_ENDSPACE ||
+ type == FIELD_SKIP_PRESPACE)
{
if (rec->length > 255 && *from & 128)
{
@@ -884,7 +979,7 @@ ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
if (length >= rec_length ||
min_pack_length + length > (uint) (from_end - from))
goto err;
- if (type == FIELD_SKIPP_ENDSPACE)
+ if (type == FIELD_SKIP_ENDSPACE)
{
memcpy(to,(byte*) from,(size_t) length);
bfill((byte*) to+length,rec_length-length,' ');
@@ -911,7 +1006,7 @@ ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
}
else
{
- if (type == FIELD_SKIPP_ENDSPACE || type == FIELD_SKIPP_PRESPACE)
+ if (type == FIELD_SKIP_ENDSPACE || type == FIELD_SKIP_PRESPACE)
min_pack_length--;
if (min_pack_length + rec_length > (uint) (from_end - from))
goto err;
@@ -933,8 +1028,8 @@ ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
if (info->s->calc_checksum)
from++;
if (to == to_end && from == from_end && (bit == 1 || !(flag & ~(bit-1))))
- DBUG_RETURN((info->packed_length=found_length));
- err:
+ DBUG_RETURN(found_length);
+err:
my_errno=HA_ERR_RECORD_DELETED;
DBUG_PRINT("error",("to_end: %lx -> %lx from_end: %lx -> %lx",
to,to_end,from,from_end));
@@ -1042,7 +1137,8 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
goto panic;
if (info->s->base.blobs)
{
- if (!(to=mi_fix_rec_buff_for_blob(info,block_info.rec_len)))
+ if (!(to=mi_alloc_rec_buff(info, block_info.rec_len,
+ &info->rec_buff)))
goto err;
}
else
@@ -1059,11 +1155,11 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
} while (left_length);
info->update|= HA_STATE_AKTIV; /* We have a aktive record */
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
DBUG_RETURN(_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
MY_FILE_ERROR ? 0 : -1);
}
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
DBUG_RETURN(-1); /* Wrong data to read */
panic:
@@ -1073,33 +1169,12 @@ err:
DBUG_RETURN(-1);
}
-
-byte *mi_fix_rec_buff_for_blob(MI_INFO *info, ulong length)
-{
- uint extra;
- if (! info->rec_buff || length > info->alloced_rec_buff_length)
- {
- byte *newptr;
- extra=ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
- MI_DYN_DELETE_BLOCK_HEADER;
- if (!(newptr=(byte*) my_realloc((gptr) info->rec_alloc,length+extra,
- MYF(MY_ALLOW_ZERO_PTR))))
- return newptr;
- info->rec_alloc=newptr;
- info->rec_buff=newptr+ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER);
- info->alloced_rec_buff_length=length;
- }
- return info->rec_buff;
-}
-
-
/* compare unique constraint between stored rows */
int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def,
const byte *record, my_off_t pos)
{
- byte *rec_buff,*rec_alloc,*old_record;
- uint alloced_rec_buff_length;
+ byte *rec_buff,*old_record;
int error;
DBUG_ENTER("_mi_cmp_dynamic_unique");
@@ -1108,23 +1183,15 @@ int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def,
/* Don't let the compare destroy blobs that may be in use */
rec_buff=info->rec_buff;
- rec_alloc=info->rec_alloc;
- alloced_rec_buff_length=info->alloced_rec_buff_length;
if (info->s->base.blobs)
- {
info->rec_buff=0;
- info->rec_alloc=0;
- info->alloced_rec_buff_length=0;
- }
error=_mi_read_dynamic_record(info,pos,old_record);
if (!error)
error=mi_unique_comp(def, record, old_record, def->null_are_equal);
if (info->s->base.blobs)
{
- my_free(info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mi_get_rec_buff_ptr(info, info->rec_buff), MYF(MY_ALLOW_ZERO_PTR));
info->rec_buff=rec_buff;
- info->rec_alloc=rec_alloc;
- info->alloced_rec_buff_length=alloced_rec_buff_length;
}
my_afree(old_record);
DBUG_RETURN(error);
@@ -1205,7 +1272,7 @@ int _mi_cmp_dynamic_record(register MI_INFO *info, register const byte *record)
}
}
my_errno=0;
- err:
+err:
if (buffer != info->rec_buff)
my_afree((gptr) buffer);
DBUG_RETURN(my_errno);
@@ -1258,7 +1325,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
if (info->lock_type == F_UNLCK)
{
#ifndef UNSAFE_LOCKING
- if (share->r_locks == 0 && share->w_locks == 0)
+ if (share->tot_locks == 0)
{
if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
MYF(MY_SEEK_NOT_DONE) | info->lock_wait))
@@ -1334,7 +1401,8 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
info->lastpos=filepos;
if (share->base.blobs)
{
- if (!(to=mi_fix_rec_buff_for_blob(info,block_info.rec_len)))
+ if (!(to= mi_alloc_rec_buff(info, block_info.rec_len,
+ &info->rec_buff)))
goto err;
}
else
@@ -1393,8 +1461,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
} while (left_len);
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
- if (share->r_locks == 0 && share->w_locks == 0)
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
if (_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
MY_FILE_ERROR)
DBUG_RETURN(0);
@@ -1421,33 +1488,27 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0)));
if (my_read(file,(char*) header,sizeof(info->header),MYF(0)) !=
sizeof(info->header))
- {
- my_errno=HA_ERR_WRONG_IN_RECORD;
- return BLOCK_FATAL_ERROR;
- }
+ goto err;
}
DBUG_DUMP("header",(byte*) header,MI_BLOCK_INFO_HEADER_LENGTH);
if (info->second_read)
{
- if (info->header[0] <= 6)
+ if (info->header[0] <= 6 || info->header[0] == 13)
return_val=BLOCK_SYNC_ERROR;
}
else
{
- if (info->header[0] > 6)
+ if (info->header[0] > 6 && info->header[0] != 13)
return_val=BLOCK_SYNC_ERROR;
}
- info->next_filepos= HA_OFFSET_ERROR; /* Dummy ifall no next block */
+ info->next_filepos= HA_OFFSET_ERROR; /* Dummy if no next block */
switch (info->header[0]) {
case 0:
if ((info->block_len=(uint) mi_uint3korr(header+1)) <
MI_MIN_BLOCK_LENGTH ||
(info->block_len & (MI_DYN_ALIGN_SIZE -1)))
- {
- my_errno=HA_ERR_WRONG_IN_RECORD;
- return BLOCK_ERROR;
- }
+ goto err;
info->filepos=filepos;
info->next_filepos=mi_sizekorr(header+4);
info->prev_filepos=mi_sizekorr(header+12);
@@ -1458,7 +1519,7 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
(mi_uint4korr(header+12) != 0 &&
(mi_uint4korr(header+12) != (ulong) ~0 ||
info->prev_filepos != (ulong) ~0)))
- return BLOCK_FATAL_ERROR;
+ goto err;
#endif
return return_val | BLOCK_DELETED; /* Deleted block */
@@ -1471,6 +1532,14 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
info->filepos=filepos+4;
return return_val | BLOCK_FIRST | BLOCK_LAST;
+ case 13:
+ info->rec_len=mi_uint4korr(header+1);
+ info->block_len=info->data_len=mi_uint3korr(header+5);
+ info->next_filepos=mi_sizekorr(header+8);
+ info->second_read=1;
+ info->filepos=filepos+16;
+ return return_val | BLOCK_FIRST;
+
case 3:
info->rec_len=info->data_len=mi_uint2korr(header+1);
info->block_len=info->rec_len+ (uint) header[3];
@@ -1530,8 +1599,9 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
info->second_read=1;
info->filepos=filepos+12;
return return_val;
- default:
- my_errno=HA_ERR_WRONG_IN_RECORD; /* Garbage */
- return BLOCK_ERROR;
}
+
+err:
+ my_errno=HA_ERR_WRONG_IN_RECORD; /* Garbage */
+ return BLOCK_ERROR;
}
diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c
index cf075512ac4..1d45fd300e7 100644
--- a/myisam/mi_extra.c
+++ b/myisam/mi_extra.c
@@ -1,24 +1,19 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Extra functions we want to do with a database */
-/* - Set flags for quicker databasehandler */
-/* - Set databasehandler to normal */
-/* - Reset recordpointers as after open database */
-
#include "myisamdef.h"
#ifdef HAVE_MMAP
#include <sys/mman.h>
@@ -27,30 +22,55 @@
#include <errno.h>
#endif
- /* set extra flags for database */
+/*
+ Set options and buffers to optimize table handling
+
+ SYNOPSIS
+ mi_extra()
+ info open table
+ function operation
+ extra_arg Pointer to extra argument (normally pointer to ulong)
+ Used when function is one of:
+ HA_EXTRA_WRITE_CACHE
+ HA_EXTRA_CACHE
+ HA_EXTRA_BULK_INSERT_BEGIN
+ If extra_arg is 0, then the default cache size is used.
+ HA_EXTRA_BULK_INSERT_FLUSH
+ extra_arg is a a pointer to which index to flush (uint*)
+ RETURN VALUES
+ 0 ok
+*/
+
-int mi_extra(MI_INFO *info, enum ha_extra_function function)
+int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
{
int error=0;
+ ulong cache_size;
MYISAM_SHARE *share=info->s;
DBUG_ENTER("mi_extra");
+ DBUG_PRINT("enter",("function: %d",(int) function));
switch (function) {
case HA_EXTRA_RESET:
/*
Free buffers and reset the following flags:
EXTRA_CACHE, EXTRA_WRITE_CACHE, EXTRA_KEYREAD, EXTRA_QUICK
+
+ If the row buffer cache is large (for dynamic tables), reduce it
+ to save memory.
*/
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
{
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
error=end_io_cache(&info->rec_cache);
}
+ if (share->base.blobs)
+ mi_alloc_rec_buff(info, -1, &info->rec_buff);
#if defined(HAVE_MMAP) && defined(HAVE_MADVICE)
if (info->opt_flag & MEMMAP_USED)
madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM);
#endif
- info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
+ info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
info->quick_mode=0;
/* Fall through */
@@ -102,11 +122,13 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
if (!(info->opt_flag &
(READ_CACHE_USED | WRITE_CACHE_USED | MEMMAP_USED)))
{
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
if (!(init_io_cache(&info->rec_cache,info->dfile,
(uint) min(info->state->data_file_length+1,
- my_default_record_cache_size),
- READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
- MYF(share->write_flag & MY_WAIT_IF_FULL))))
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
{
info->opt_flag|=READ_CACHE_USED;
info->update&= ~HA_STATE_ROW_CHANGED;
@@ -132,10 +154,12 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
error=1; /* Not possibly if not locked */
break;
}
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
if (!(info->opt_flag &
(READ_CACHE_USED | WRITE_CACHE_USED | OPT_NO_ROWS)) &&
!share->state.header.uniques)
- if (!(init_io_cache(&info->rec_cache,info->dfile,0,
+ if (!(init_io_cache(&info->rec_cache,info->dfile, cache_size,
WRITE_CACHE,info->state->data_file_length,
(pbool) (info->lock_type != F_UNLCK),
MYF(share->write_flag & MY_WAIT_IF_FULL))))
@@ -146,6 +170,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
HA_STATE_EXTEND_BLOCK);
}
break;
+ case HA_EXTRA_PREPARE_FOR_UPDATE:
+ if (info->s->data_file_type != DYNAMIC_RECORD)
+ break;
+ /* Remove read/write cache if dynamic rows */
case HA_EXTRA_NO_CACHE:
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
{
@@ -219,9 +247,17 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
}
if (share->state.key_map)
{
- share->state.key_map=0;
- info->state->key_file_length=share->state.state.key_file_length=
- share->base.keystart;
+ MI_KEYDEF *key=share->keyinfo;
+ uint i;
+ for (i=0 ; i < share->base.keys ; i++,key++)
+ {
+ if (!(key->flag & HA_NOSAME) && info->s->base.auto_key != i+1)
+ {
+ share->state.key_map&= ~ ((ulonglong) 1 << i);
+ info->update|= HA_STATE_CHANGED;
+ }
+ }
+
if (!share->changed)
{
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
@@ -239,10 +275,17 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
case HA_EXTRA_FORCE_REOPEN:
pthread_mutex_lock(&THR_LOCK_myisam);
share->last_version= 0L; /* Impossible version */
+ pthread_mutex_unlock(&THR_LOCK_myisam);
+ break;
+ case HA_EXTRA_PREPARE_FOR_DELETE:
+ pthread_mutex_lock(&THR_LOCK_myisam);
+ share->last_version= 0L; /* Impossible version */
#ifdef __WIN__
/* Close the isam and data files as Win32 can't drop an open table */
pthread_mutex_lock(&share->intern_lock);
- if (flush_key_blocks(share->kfile,FLUSH_RELEASE))
+ if (flush_key_blocks(share->kfile,
+ (function == HA_EXTRA_FORCE_REOPEN ?
+ FLUSH_RELEASE : FLUSH_IGNORE_CHANGED)))
{
error=my_errno;
share->changed=1;
@@ -293,22 +336,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
if (share->not_flushed)
{
share->not_flushed=0;
-#if defined(__WIN__)
- if (_commit(share->kfile))
- error=errno;
- if (_commit(info->dfile))
- error=errno;
-#elif defined(HAVE_FDATASYNC)
- if (fdatasync(share->kfile))
- error=errno;
- if (fdatasync(share->dfile))
- error=errno;
-#elif defined(HAVE_FSYNC)
- if ( fsync(share->kfile))
- error=errno;
- if (fsync(share->dfile))
- error=errno;
-#endif
+ if (my_sync(share->kfile, MYF(0)))
+ error= my_errno;
+ if (my_sync(info->dfile, MYF(0)))
+ error= my_errno;
if (error)
{
share->changed=1;
@@ -316,11 +347,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
}
}
if (share->base.blobs)
- {
- my_free(info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR));
- info->rec_alloc=info->rec_buff=0;
- mi_fix_rec_buff_for_blob(info,info->s->base.pack_reclength);
- }
+ mi_alloc_rec_buff(info, -1, &info->rec_buff);
break;
case HA_EXTRA_NORMAL: /* Theese isn't in use */
info->quick_mode=0;
diff --git a/myisam/mi_info.c b/myisam/mi_info.c
index 6e7abfc0914..f4eace198f9 100644
--- a/myisam/mi_info.c
+++ b/myisam/mi_info.c
@@ -1,20 +1,20 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Ger tillbaka en struct med information om isam-filen */
+/* Return useful base information for an open table */
#include "myisamdef.h"
#ifdef __WIN__
@@ -45,7 +45,7 @@ int mi_status(MI_INFO *info, register MI_ISAMINFO *x, uint flag)
{
pthread_mutex_lock(&share->intern_lock);
VOID(_mi_readinfo(info,F_RDLCK,0));
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
pthread_mutex_unlock(&share->intern_lock);
}
if (flag & HA_STATUS_VARIABLE)
@@ -80,13 +80,17 @@ int mi_status(MI_INFO *info, register MI_ISAMINFO *x, uint flag)
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
0L : share->base.pack_reclength);
x->sortkey= -1; /* No clustering */
- /* The following should be included even if we are not compiling with
- USE_RAID as the client must be able to request it! */
x->rec_per_key = share->state.rec_per_key_part;
+ x->key_map = share->state.key_map;
+ x->data_file_name = share->data_file_name;
+ x->index_file_name = share->index_file_name;
+ /*
+ The following should be included even if we are not compiling with
+ USE_RAID as the client must be able to request it!
+ */
x->raid_type= share->base.raid_type;
x->raid_chunks= share->base.raid_chunks;
x->raid_chunksize= share->base.raid_chunksize;
- x->key_map = share->state.key_map;
}
if ((flag & HA_STATUS_TIME) && !my_fstat(info->dfile,&state,MYF(0)))
x->update_time=state.st_mtime;
diff --git a/myisam/mi_key.c b/myisam/mi_key.c
index 9f4e2cb1524..766ecf334b6 100644
--- a/myisam/mi_key.c
+++ b/myisam/mi_key.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,6 +18,10 @@
#include "myisamdef.h"
#include "m_ctype.h"
+#include <assert.h>
+#ifdef HAVE_IEEEFP_H
+#include <ieeefp.h>
+#endif
#define CHECK_KEYS
@@ -88,25 +92,28 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
}
else if (keyseg->flag & HA_SWAP_KEY)
{ /* Numerical column */
-#ifdef NAN_TEST
- float float_nr;
- double dbl_nr;
+#ifdef HAVE_ISNAN
if (type == HA_KEYTYPE_FLOAT)
{
- float_nr=float4get(pos);
- if (float_nr == (float) FLT_MAX)
+ float nr;
+ float4get(nr,pos);
+ if (isnan(nr))
{
- float_nr= (float) FLT_MAX;
- pos= (byte*) &float_nr;
+ /* Replace NAN with zero */
+ bzero(key,length);
+ key+=length;
+ continue;
}
}
else if (type == HA_KEYTYPE_DOUBLE)
{
- dbl_nr=float8get(key);
- if (dbl_nr == DBL_MAX)
+ double nr;
+ float8get(nr,pos);
+ if (isnan(nr))
{
- dbl_nr=DBL_MAX;
- pos=(byte*) &dbl_nr;
+ bzero(key,length);
+ key+=length;
+ continue;
}
}
#endif
@@ -130,11 +137,26 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
} /* _mi_make_key */
- /* Pack a key to intern format from given format (c_rkey) */
- /* returns length of packed key */
+/*
+ Pack a key to intern format from given format (c_rkey)
+
+ SYNOPSIS
+ _mi_pack_key()
+ info MyISAM handler
+ uint keynr key number
+ key Store packed key here
+ old Not packed key
+ k_length Length of 'old' to use
+ last_used_keyseg out parameter. May be NULL
+
+ RETURN
+ length of packed key
+
+ last_use_keyseg Store pointer to the keyseg after the last used one
+*/
uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
- uint k_length)
+ uint k_length, MI_KEYSEG **last_used_keyseg)
{
uint length;
uchar *pos,*end,*start_key=key;
@@ -205,6 +227,8 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
key+= length;
k_length-=length;
}
+ if (last_used_keyseg)
+ *last_used_keyseg= keyseg;
#ifdef NOT_USED
if (keyseg->type)
@@ -241,10 +265,11 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
byte *blob_ptr;
DBUG_ENTER("_mi_put_key_in_record");
- if (info->blobs && info->s->keyinfo[keynr].flag & HA_VAR_LENGTH_KEY)
+ if (info->s->base.blobs && info->s->keyinfo[keynr].flag & HA_VAR_LENGTH_KEY)
{
if (!(blob_ptr=
- mi_fix_rec_buff_for_blob(info, info->s->keyinfo[keynr].keylength)))
+ mi_alloc_rec_buff(info, info->s->keyinfo[keynr].keylength,
+ &info->rec_buff)))
goto err;
}
key=(byte*) info->lastkey;
@@ -346,7 +371,7 @@ err:
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf)
{
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
if (filepos != HA_OFFSET_ERROR)
{
if (info->lastinx >= 0)
@@ -364,53 +389,86 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf)
return(-1); /* Wrong data to read */
}
+
+/*
+ Update auto_increment info
- /* Update auto_increment info */
+ SYNOPSIS
+ update_auto_increment()
+ info MyISAM handler
+ record Row to update
+
+ IMPLEMENTATION
+ Only replace the auto_increment value if it is higher than the previous
+ one. For signed columns we don't update the auto increment value if it's
+ less than zero.
+*/
void update_auto_increment(MI_INFO *info,const byte *record)
{
- ulonglong value;
- MI_KEYSEG *keyseg=info->s->keyinfo[info->s->base.auto_key-1].seg;
- const uchar *key=(uchar*) record+keyseg->start;
+ ulonglong value= 0; /* Store unsigned values here */
+ longlong s_value= 0; /* Store signed values here */
+ MI_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg;
+ const uchar *key= (uchar*) record + keyseg->start;
switch (keyseg->type) {
case HA_KEYTYPE_INT8:
+ s_value= (longlong) *(char*)key;
+ break;
case HA_KEYTYPE_BINARY:
value=(ulonglong) *(uchar*) key;
break;
case HA_KEYTYPE_SHORT_INT:
+ s_value= (longlong) sint2korr(key);
+ break;
case HA_KEYTYPE_USHORT_INT:
value=(ulonglong) uint2korr(key);
break;
case HA_KEYTYPE_LONG_INT:
+ s_value= (longlong) sint4korr(key);
+ break;
case HA_KEYTYPE_ULONG_INT:
value=(ulonglong) uint4korr(key);
break;
case HA_KEYTYPE_INT24:
+ s_value= (longlong) sint3korr(key);
+ break;
case HA_KEYTYPE_UINT24:
value=(ulonglong) uint3korr(key);
break;
- case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
+ case HA_KEYTYPE_FLOAT: /* This shouldn't be used */
{
float f_1;
float4get(f_1,key);
- value = (ulonglong) f_1;
+ /* Ignore negative values */
+ value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1;
break;
}
- case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
+ case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */
{
double f_1;
float8get(f_1,key);
- value = (ulonglong) f_1;
+ /* Ignore negative values */
+ value = (f_1 < 0.0) ? 0 : (ulonglong) f_1;
break;
}
case HA_KEYTYPE_LONGLONG:
+ s_value= sint8korr(key);
+ break;
case HA_KEYTYPE_ULONGLONG:
value= uint8korr(key);
break;
default:
- value=0; /* Error */
+ DBUG_ASSERT(0);
+ value=0; /* Error */
break;
}
- set_if_bigger(info->s->state.auto_increment,value);
+
+ /*
+ The following code works becasue if s_value < 0 then value is 0
+ and if s_value == 0 then value will contain either s_value or the
+ correct value.
+ */
+ set_if_bigger(info->s->state.auto_increment,
+ (s_value > 0) ? (ulonglong) s_value : value);
}
diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c
index de5f0d0c2cf..f3bfa8deb90 100644
--- a/myisam/mi_locking.c
+++ b/myisam/mi_locking.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -35,21 +35,31 @@ int mi_lock_database(MI_INFO *info, int lock_type)
MYISAM_SHARE *share=info->s;
uint flag;
DBUG_ENTER("mi_lock_database");
+ DBUG_PRINT("info",("lock_type: %d", lock_type));
if (share->options & HA_OPTION_READ_ONLY_DATA ||
info->lock_type == lock_type)
DBUG_RETURN(0);
+ if (lock_type == F_EXTRA_LCK)
+ {
+ ++share->w_locks;
+ ++share->tot_locks;
+ info->lock_type= lock_type;
+ DBUG_RETURN(0);
+ }
+
flag=error=0;
pthread_mutex_lock(&share->intern_lock);
if (share->kfile >= 0) /* May only be false on windows */
{
- switch (lock_type)
- {
+ switch (lock_type) {
case F_UNLCK:
+ DBUG_PRINT("info", ("old lock: %d", info->lock_type));
if (info->lock_type == F_RDLCK)
count= --share->r_locks;
else
count= --share->w_locks;
+ --share->tot_locks;
if (info->lock_type == F_WRLCK && !share->w_locks &&
!share->delay_key_write && flush_key_blocks(share->kfile,FLUSH_KEEP))
{
@@ -66,6 +76,8 @@ int mi_lock_database(MI_INFO *info, int lock_type)
}
if (!count)
{
+ DBUG_PRINT("info",("changed: %u w_locks: %u",
+ (uint) share->changed, share->w_locks));
if (share->changed && !share->w_locks)
{
share->state.process= share->last_process=share->this_process;
@@ -76,41 +88,32 @@ int mi_lock_database(MI_INFO *info, int lock_type)
share->changed=0;
if (myisam_flush)
{
-#if defined(__WIN__)
- if (_commit(share->kfile))
- error=errno;
- if (_commit(info->dfile))
- error=errno;
-#elif defined(HAVE_FDATASYNC)
- if (fdatasync(share->kfile))
- error=errno;
- if (fdatasync(share->dfile))
- error=errno;
-#elif defined(HAVE_FSYNC)
- if (fsync(share->kfile))
- error=errno;
- if (fsync(share->dfile))
- error=errno;
-#endif
+ if (my_sync(share->kfile, MYF(0)))
+ error= my_errno;
+ if (my_sync(info->dfile, MYF(0)))
+ error= my_errno;
}
else
share->not_flushed=1;
if (error)
mi_mark_crashed(info);
}
- if (share->r_locks)
- { /* Only read locks left */
- flag=1;
- if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
- MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
- error=my_errno;
- }
- else if (!share->w_locks)
- { /* No more locks */
- flag=1;
- if (my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
- MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
- error=my_errno;
+ if (info->lock_type != F_EXTRA_LCK)
+ {
+ if (share->r_locks)
+ { /* Only read locks left */
+ flag=1;
+ if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
+ MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
+ error=my_errno;
+ }
+ else if (!share->w_locks)
+ { /* No more locks */
+ flag=1;
+ if (my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
+ MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
+ error=my_errno;
+ }
}
}
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
@@ -153,6 +156,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
}
VOID(_mi_test_if_changed(info));
share->r_locks++;
+ share->tot_locks++;
info->lock_type=lock_type;
break;
case F_WRLCK:
@@ -199,7 +203,9 @@ int mi_lock_database(MI_INFO *info, int lock_type)
}
VOID(_mi_test_if_changed(info));
info->lock_type=lock_type;
+ info->invalidator=info->s->invalidator;
share->w_locks++;
+ share->tot_locks++;
break;
default:
break; /* Impossible */
@@ -216,7 +222,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
/****************************************************************************
-** The following functions are called by thr_lock() in threaded applications
+ The following functions are called by thr_lock() in threaded applications
****************************************************************************/
void mi_get_status(void* param)
@@ -295,13 +301,12 @@ my_bool mi_check_status(void* param)
int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer)
{
- MYISAM_SHARE *share;
DBUG_ENTER("_mi_readinfo");
- share=info->s;
if (info->lock_type == F_UNLCK)
{
- if (!share->r_locks && !share->w_locks)
+ MYISAM_SHARE *share=info->s;
+ if (!share->tot_locks)
{
if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
info->lock_wait | MY_SEEK_NOT_DONE))
@@ -317,6 +322,7 @@ int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer)
}
if (check_keybuffer)
VOID(_mi_test_if_changed(info));
+ info->invalidator=info->s->invalidator;
}
else if (lock_type == F_WRLCK && info->lock_type == F_RDLCK)
{
@@ -336,9 +342,11 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
int error,olderror;
MYISAM_SHARE *share=info->s;
DBUG_ENTER("_mi_writeinfo");
+ DBUG_PRINT("info",("operation: %u tot_locks: %u", operation,
+ share->tot_locks));
error=0;
- if (share->r_locks == 0 && share->w_locks == 0)
+ if (share->tot_locks == 0)
{
olderror=my_errno; /* Remember last error */
if (operation)
@@ -363,9 +371,7 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
my_errno=olderror;
}
else if (operation)
- {
share->changed= 1; /* Mark keyfile changed */
- }
DBUG_RETURN(error);
} /* _mi_writeinfo */
@@ -411,11 +417,14 @@ int _mi_mark_file_changed(MI_INFO *info)
share->global_changed=1;
share->state.open_count++;
}
- mi_int2store(buff,share->state.open_count);
- buff[2]=1; /* Mark that it's changed */
- return (my_pwrite(share->kfile,buff,sizeof(buff),
- sizeof(share->state.header),
- MYF(MY_NABP)));
+ if (!share->temporary)
+ {
+ mi_int2store(buff,share->state.open_count);
+ buff[2]=1; /* Mark that it's changed */
+ return (my_pwrite(share->kfile,buff,sizeof(buff),
+ sizeof(share->state.header),
+ MYF(MY_NABP)));
+ }
}
return 0;
}
diff --git a/myisam/mi_log.c b/myisam/mi_log.c
index 5c64c130212..1dcfd5250d2 100644
--- a/myisam/mi_log.c
+++ b/myisam/mi_log.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index 048fdf1ce15..944a8af01e9 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -56,7 +56,7 @@ static MI_INFO *test_if_reopen(char *filename)
{
MI_INFO *info=(MI_INFO*) pos->data;
MYISAM_SHARE *share=info->s;
- if (!strcmp(share->filename,filename) && share->last_version)
+ if (!strcmp(share->unique_file_name,filename) && share->last_version)
return info;
}
return 0;
@@ -74,9 +74,11 @@ static MI_INFO *test_if_reopen(char *filename)
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{
int lock_error,kfile,open_mode,save_errno;
- uint i,j,len,errpos,head_length,base_pos,offset,info_length,extra,keys,
+ uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
key_parts,unique_key_parts,tmp_length,uniques;
- char name_buff[FN_REFLEN],*disk_cache,*disk_pos, *end_pos;
+ char name_buff[FN_REFLEN], org_name [FN_REFLEN], index_name[FN_REFLEN],
+ data_name[FN_REFLEN];
+ char *disk_cache, *disk_pos, *end_pos;
MI_INFO info,*m_info,*old_info;
MYISAM_SHARE share_buff,*share;
ulong rec_per_key_part[MI_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
@@ -91,7 +93,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
head_length=sizeof(share_buff.state.header);
bzero((byte*) &info,sizeof(info));
- VOID(fn_format(name_buff,name,"",MI_NAME_IEXT,4+16+32));
+ my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0));
pthread_mutex_lock(&THR_LOCK_myisam);
if (!(old_info=test_if_reopen(name_buff)))
{
@@ -112,15 +114,17 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
errpos=1;
if (my_read(kfile,(char*) share->state.header.file_version,head_length,
MYF(MY_NABP)))
+ {
+ my_errno= HA_ERR_NOT_A_TABLE;
goto err;
-
+ }
if (memcmp((byte*) share->state.header.file_version,
(byte*) myisam_file_magic, 4))
{
DBUG_PRINT("error",("Wrong header in %s",name_buff));
DBUG_DUMP("error_dump",(char*) share->state.header.file_version,
head_length);
- my_errno=HA_ERR_CRASHED;
+ my_errno=HA_ERR_NOT_A_TABLE;
goto err;
}
share->options= mi_uint2korr(share->state.header.options);
@@ -135,6 +139,13 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
my_errno=HA_ERR_OLD_FILE;
goto err;
}
+ /* Don't call realpath() if the name can't be a link */
+ if (strcmp(name_buff, org_name))
+ (void) my_readlink(index_name, org_name, MYF(0));
+ else
+ (void) strmov(index_name, org_name);
+ (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,2+4+16);
+
info_length=mi_uint2korr(share->state.header.header_length);
base_pos=mi_uint2korr(share->state.header.base_pos);
if (!(disk_cache=(char*) my_alloca(info_length+128)))
@@ -156,7 +167,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
}
errpos=3;
if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
+ {
+ my_errno=HA_ERR_CRASHED;
goto err;
+ }
len=mi_uint2korr(share->state.header.state_info_length);
keys= (uint) share->state.header.keys;
uniques= (uint) share->state.header.uniques;
@@ -173,6 +187,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
}
share->state_diff_length=len-MI_STATE_INFO_SIZE;
+ if (share->state.header.fulltext_keys)
+ fprintf(stderr, "Warning: table file %s was created in MySQL 4.1+, use REPAIR TABLE ... USE_FRM to recreate it as a valid MySQL 4.0 table\n", name_buff);
+
mi_state_info_read(disk_cache, &share->state);
len= mi_uint2korr(share->state.header.base_info_length);
if (len != MI_BASE_INFO_SIZE)
@@ -216,7 +233,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
(mi_safe_mul(share->base.pack_reclength,
(ulonglong) 1 << (share->base.rec_reflength*8))-1);
max_key_file_length=
- mi_safe_mul(MI_KEY_BLOCK_LENGTH,
+ mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
((ulonglong) 1 << (share->base.key_reflength*8))-1);
#if SIZEOF_OFF_T == 4
set_if_smaller(max_data_file_length, INT_MAX32);
@@ -258,7 +275,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
&share->rec,
(share->base.fields+1)*sizeof(MI_COLUMNDEF),
&share->blobs,sizeof(MI_BLOB)*share->base.blobs,
- &share->filename,strlen(name_buff)+1,
+ &share->unique_file_name,strlen(name_buff)+1,
+ &share->index_file_name,strlen(index_name)+1,
+ &share->data_file_name,strlen(data_name)+1,
&share->state.key_root,keys*sizeof(my_off_t),
&share->state.key_del,
(share->state.header.max_block_size*sizeof(my_off_t)),
@@ -276,7 +295,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
memcpy((char*) share->state.key_del,
(char*) key_del, (sizeof(my_off_t) *
share->state.header.max_block_size));
- strmov(share->filename,name_buff);
+ strmov(share->unique_file_name, name_buff);
+ strmov(share->index_file_name, index_name);
+ strmov(share->data_file_name, data_name);
share->blocksize=min(IO_SIZE,myisam_block_size);
{
@@ -368,7 +389,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
lock_error=1; /* Database unlocked */
}
- if (mi_open_datafile(&info, share))
+ if (mi_open_datafile(&info, share, -1))
goto err;
errpos=5;
@@ -441,7 +462,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
my_errno=EACCES; /* Can't open in write mode */
goto err;
}
- if (mi_open_datafile(&info, share))
+ if (mi_open_datafile(&info, share, old_info->dfile))
goto err;
errpos=5;
}
@@ -453,12 +474,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
&info.buff,(share->base.max_key_block_length*2+
share->base.max_key_length),
&info.lastkey,share->base.max_key_length*3+1,
- &info.filename,strlen(name)+1,
+ &info.filename,strlen(org_name)+1,
NullS))
goto err;
errpos=6;
- strmov(info.filename,name);
+ strmov(info.filename,org_name);
memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
info.lastkey2=info.lastkey+share->base.max_key_length;
@@ -476,6 +497,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->options|=HA_OPTION_READ_ONLY_DATA;
info.lock_type=F_UNLCK;
info.quick_mode=0;
+ info.bulk_insert=0;
info.errkey= -1;
info.page_changed=1;
pthread_mutex_lock(&share->intern_lock);
@@ -486,6 +508,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{
info.lock_type=F_RDLCK;
share->r_locks++;
+ share->tot_locks++;
}
if ((open_flags & HA_OPEN_TMP_TABLE) ||
(share->options & HA_OPTION_TMP_TABLE))
@@ -493,6 +516,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->temporary=share->delay_key_write=1;
share->write_flag=MYF(MY_NABP);
share->w_locks++; /* We don't have to update status */
+ share->tot_locks++;
info.lock_type=F_WRLCK;
}
if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
@@ -504,21 +528,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
/* Allocate buffer for one record */
- extra=0;
- if (share->options & HA_OPTION_PACK_RECORD)
- extra=ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
- MI_DYN_DELETE_BLOCK_HEADER;
-
- tmp_length=max(share->base.pack_reclength+share->base.pack_bits,
- share->base.max_key_length);
- info.alloced_rec_buff_length=tmp_length;
- if (!(info.rec_alloc=(byte*) my_malloc(tmp_length+extra+8,
- MYF(MY_WME | MY_ZEROFILL))))
+ /* prerequisites: bzero(info) && info->s=share; are met. */
+ if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
goto err;
- if (extra)
- info.rec_buff=info.rec_alloc+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER);
- else
- info.rec_buff=info.rec_alloc;
+ bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
*m_info=info;
#ifdef THREAD
@@ -530,7 +543,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
pthread_mutex_unlock(&THR_LOCK_myisam);
if (myisam_log_file >= 0)
{
- intern_filename(name_buff,share->filename);
+ intern_filename(name_buff,share->index_file_name);
_myisam_log(MI_LOG_OPEN,m_info,name_buff,(uint) strlen(name_buff));
}
DBUG_RETURN(m_info);
@@ -569,6 +582,41 @@ err:
} /* mi_open */
+byte *mi_alloc_rec_buff(MI_INFO *info, ulong length, byte **buf)
+{
+ uint extra;
+ uint32 old_length;
+ LINT_INIT(old_length);
+
+ if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
+ {
+ byte *newptr = *buf;
+
+ /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
+ if (length == (ulong) -1)
+ {
+ length= max(info->s->base.pack_reclength,
+ info->s->base.max_key_length);
+ /* Avoid unnecessary realloc */
+ if (newptr && length == old_length)
+ return newptr;
+ }
+
+ extra= ((info->s->options & HA_OPTION_PACK_RECORD) ?
+ ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
+ MI_REC_BUFF_OFFSET : 0);
+ if (extra && newptr)
+ newptr-= MI_REC_BUFF_OFFSET;
+ if (!(newptr=(byte*) my_realloc((gptr)newptr, length+extra+8,
+ MYF(MY_ALLOW_ZERO_PTR))))
+ return newptr;
+ *((uint32 *) newptr)= (uint32) length;
+ *buf= newptr+(extra ? MI_REC_BUFF_OFFSET : 0);
+ }
+ return *buf;
+}
+
+
ulonglong mi_safe_mul(ulonglong a, ulonglong b)
{
ulonglong max_val= ~ (ulonglong) 0; /* my_off_t is unsigned */
@@ -643,15 +691,20 @@ static void setup_key_functions(register MI_KEYDEF *keyinfo)
}
else if (keyinfo->flag & HA_VAR_LENGTH_KEY)
{
- keyinfo->bin_search=_mi_seq_search;
keyinfo->get_key= _mi_get_pack_key;
if (keyinfo->seg[0].flag & HA_PACK_KEY)
{ /* Prefix compression */
+ if (!keyinfo->seg->charset || use_strcoll(keyinfo->seg->charset) ||
+ (keyinfo->seg->flag & HA_NULL_PART))
+ keyinfo->bin_search=_mi_seq_search;
+ else
+ keyinfo->bin_search=_mi_prefix_search;
keyinfo->pack_key=_mi_calc_var_pack_key_length;
keyinfo->store_key=_mi_store_var_pack_key;
}
else
{
+ keyinfo->bin_search=_mi_seq_search;
keyinfo->pack_key=_mi_calc_var_key_length; /* Variable length key */
keyinfo->store_key=_mi_store_static_key;
}
@@ -677,6 +730,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
uchar *ptr=buff;
uint i, keys= (uint) state->header.keys,
key_blocks=state->header.max_block_size;
+ DBUG_ENTER("mi_state_info_write");
memcpy_fixed(ptr,&state->header,sizeof(state->header));
ptr+=sizeof(state->header);
@@ -727,10 +781,10 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
}
if (pWrite & 1)
- return my_pwrite(file,(char*) buff, (uint) (ptr-buff), 0L,
- MYF(MY_NABP | MY_THREADSAFE));
- else
- return my_write(file, (char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
+ DBUG_RETURN(my_pwrite(file,(char*) buff, (uint) (ptr-buff), 0L,
+ MYF(MY_NABP | MY_THREADSAFE)));
+ DBUG_RETURN(my_write(file, (char*) buff, (uint) (ptr-buff),
+ MYF(MY_NABP)));
}
@@ -761,6 +815,8 @@ char *mi_state_info_read(char *ptr, MI_STATE_INFO *state)
state->status = mi_uint4korr(ptr); ptr +=4;
state->update_count=mi_uint4korr(ptr); ptr +=4;
+ ptr+= state->state_diff_length;
+
for (i=0; i < keys; i++)
{
state->key_root[i]= mi_sizekorr(ptr); ptr +=8;
@@ -769,7 +825,6 @@ char *mi_state_info_read(char *ptr, MI_STATE_INFO *state)
{
state->key_del[i] = mi_sizekorr(ptr); ptr +=8;
}
- ptr+= state->state_diff_length;
state->sec_index_changed = mi_uint4korr(ptr); ptr +=4;
state->sec_index_used = mi_uint4korr(ptr); ptr +=4;
state->version = mi_uint4korr(ptr); ptr +=4;
@@ -790,14 +845,17 @@ uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
{
char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
- if (pRead)
+ if (!myisam_single_user)
{
- if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
+ if (pRead)
+ {
+ if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
+ return (MY_FILE_ERROR);
+ }
+ else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
return (MY_FILE_ERROR);
+ mi_state_info_read(buff, state);
}
- else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
- return (MY_FILE_ERROR);
- mi_state_info_read(buff, state);
return 0;
}
@@ -909,7 +967,7 @@ char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef)
keydef->keylength = mi_uint2korr(ptr); ptr +=2;
keydef->minlength = mi_uint2korr(ptr); ptr +=2;
keydef->maxlength = mi_uint2korr(ptr); ptr +=2;
- keydef->block_size = keydef->block_length/MI_KEY_BLOCK_LENGTH-1;
+ keydef->block_size = keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
keydef->underflow_block_length=keydef->block_length/3;
keydef->version = 0; /* Not saved */
return ptr;
@@ -1005,37 +1063,37 @@ char *mi_recinfo_read(char *ptr, MI_COLUMNDEF *recinfo)
}
/**************************************************************************
- ** Help functions for recover
- *************************************************************************/
+Open data file with or without RAID
+We can't use dup() here as the data file descriptors need to have different
+active seek-positions.
-int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share)
-{
- char name_buff[FN_REFLEN];
- (void) fn_format(name_buff, share->filename,"",MI_NAME_DEXT, 2+4);
+The argument file_to_dup is here for the future if there would on some OS
+exist a dup()-like call that would give us two different file descriptors.
+*************************************************************************/
+int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup __attribute__((unused)))
+{
#ifdef USE_RAID
if (share->base.raid_type)
{
- if ((info->dfile=my_raid_open(name_buff,
- share->mode | O_SHARE,
- share->base.raid_type,
- share->base.raid_chunks,
- share->base.raid_chunksize,
- MYF(MY_WME | MY_RAID))) < 0)
- return 1;
+ info->dfile=my_raid_open(share->data_file_name,
+ share->mode | O_SHARE,
+ share->base.raid_type,
+ share->base.raid_chunks,
+ share->base.raid_chunksize,
+ MYF(MY_WME | MY_RAID));
}
else
#endif
- if ((info->dfile=my_open(name_buff, share->mode | O_SHARE,
- MYF(MY_WME))) < 0)
- return 1;
- return 0;
+ info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
+ MYF(MY_WME));
+ return info->dfile >= 0 ? 0 : 1;
}
int mi_open_keyfile(MYISAM_SHARE *share)
{
- if ((share->kfile=my_open(share->filename, share->mode | O_SHARE,
+ if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
MYF(MY_WME))) < 0)
return 1;
return 0;
diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c
index 242883a2c4a..b21bf0b2163 100644
--- a/myisam/mi_packrec.c
+++ b/myisam/mi_packrec.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -165,7 +165,9 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
diff_length=(int) rec_reflength - (int) share->base.rec_reflength;
if (fix_keys)
share->rec_reflength=rec_reflength;
- share->base.min_block_length=share->min_pack_length+share->pack.ref_length;
+ share->base.min_block_length=share->min_pack_length+1;
+ if (share->min_pack_length > 254)
+ share->base.min_block_length+=2;
if (!(share->decode_trees=(MI_DECODE_TREE*)
my_malloc((uint) (trees*sizeof(MI_DECODE_TREE)+
@@ -416,8 +418,7 @@ int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, byte *buf)
DBUG_RETURN(-1); /* _search() didn't find record */
file=info->dfile;
- if (_mi_pack_get_block_info(info, &block_info, file, filepos,
- info->rec_buff))
+ if (_mi_pack_get_block_info(info, &block_info, file, filepos))
goto err;
if (my_read(file,(byte*) info->rec_buff + block_info.offset ,
block_info.rec_len - block_info.offset, MYF(MY_NABP)))
@@ -465,7 +466,7 @@ static void (*get_unpack_function(MI_COLUMNDEF *rec))
(MI_COLUMNDEF *, MI_BIT_BUFF *, uchar *, uchar *)
{
switch (rec->base_type) {
- case FIELD_SKIPP_ZERO:
+ case FIELD_SKIP_ZERO:
if (rec->pack_type & PACK_TYPE_ZERO_FILL)
return &uf_zerofill_skipp_zero;
return &uf_skipp_zero;
@@ -475,7 +476,7 @@ static void (*get_unpack_function(MI_COLUMNDEF *rec))
if (rec->pack_type & PACK_TYPE_ZERO_FILL)
return &uf_zerofill_normal;
return &decode_bytes;
- case FIELD_SKIPP_ENDSPACE:
+ case FIELD_SKIP_ENDSPACE:
if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
{
if (rec->pack_type & PACK_TYPE_SELECTED)
@@ -485,7 +486,7 @@ static void (*get_unpack_function(MI_COLUMNDEF *rec))
if (rec->pack_type & PACK_TYPE_SELECTED)
return &uf_endspace_selected;
return &uf_endspace;
- case FIELD_SKIPP_PRESPACE:
+ case FIELD_SKIP_PRESPACE:
if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
{
if (rec->pack_type & PACK_TYPE_SELECTED)
@@ -742,6 +743,12 @@ static void uf_blob(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
{
ulong length=get_bits(bit_buff,rec->space_length_bits);
uint pack_length=(uint) (end-to)-mi_portable_sizeof_char_ptr;
+ if (bit_buff->blob_pos+length > bit_buff->blob_end)
+ {
+ bit_buff->error=1;
+ bzero((byte*) to,(end-to));
+ return;
+ }
decode_bytes(rec,bit_buff,bit_buff->blob_pos,bit_buff->blob_pos+length);
_my_store_blob_length((byte*) to,pack_length,length);
memcpy_fixed((char*) to+pack_length,(char*) &bit_buff->blob_pos,
@@ -963,11 +970,10 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf,
if (_mi_read_cache(&info->rec_cache,(byte*) block_info.header,filepos,
share->pack.ref_length, skip_deleted_blocks))
goto err;
- b_type=_mi_pack_get_block_info(info,&block_info,-1, filepos, NullS);
+ b_type=_mi_pack_get_block_info(info,&block_info,-1, filepos);
}
else
- b_type=_mi_pack_get_block_info(info,&block_info,info->dfile,filepos,
- info->rec_buff);
+ b_type=_mi_pack_get_block_info(info,&block_info,info->dfile,filepos);
if (b_type)
goto err; /* Error code is already set */
#ifndef DBUG_OFF
@@ -1007,7 +1013,7 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf,
/* Read and process header from a huff-record-file */
uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file,
- my_off_t filepos, char *rec_buff)
+ my_off_t filepos)
{
uchar *header=info->header;
uint head_length,ref_length;
@@ -1057,16 +1063,18 @@ uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file,
info->blob_len=uint3korr(header+head_length+1);
head_length+=4;
}
- if (!(mi_fix_rec_buff_for_blob(myisam,info->rec_len + info->blob_len)))
+ if (!(mi_alloc_rec_buff(myisam,info->rec_len + info->blob_len,
+ &myisam->rec_buff)))
return BLOCK_FATAL_ERROR; /* not enough memory */
myisam->bit_buff.blob_pos=(uchar*) myisam->rec_buff+info->rec_len;
+ myisam->bit_buff.blob_end= myisam->bit_buff.blob_pos+info->blob_len;
myisam->blob_length=info->blob_len;
}
info->filepos=filepos+head_length;
if (file > 0)
{
info->offset=min(info->rec_len, ref_length - head_length);
- memcpy(rec_buff, header+head_length, info->offset);
+ memcpy(myisam->rec_buff, header+head_length, info->offset);
}
return 0;
}
@@ -1231,10 +1239,12 @@ static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info,
info->blob_len=uint3korr(header+1);
header+=4;
}
- /* mi_fix_rec_buff_for_blob sets my_errno on error */
- if (!(mi_fix_rec_buff_for_blob(myisam,info->blob_len)))
+ /* mi_alloc_rec_buff sets my_errno on error */
+ if (!(mi_alloc_rec_buff(myisam, info->blob_len,
+ &myisam->rec_buff)))
return 0; /* not enough memory */
myisam->bit_buff.blob_pos=(uchar*) myisam->rec_buff;
+ myisam->bit_buff.blob_end= (uchar*) myisam->rec_buff + info->blob_len;
}
return header;
}
diff --git a/myisam/mi_page.c b/myisam/mi_page.c
index f8e2a977754..1d40980e309 100644
--- a/myisam/mi_page.c
+++ b/myisam/mi_page.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -64,9 +64,11 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
#ifndef FAST /* Safety check */
if (page < info->s->base.keystart ||
page+keyinfo->block_length > info->state->key_file_length ||
- page & (myisam_block_size-1))
+ (page & (MI_MIN_KEY_BLOCK_LENGTH-1)))
{
- DBUG_PRINT("error",("Trying to write outside key region: %lu",
+ DBUG_PRINT("error",("Trying to write inside key status region: key_start: %lu length: %lu page: %lu",
+ (long) info->s->base.keystart,
+ (long) info->state->key_file_length,
(long) page));
my_errno=EINVAL;
return(-1);
diff --git a/myisam/mi_panic.c b/myisam/mi_panic.c
index 92fc6f3695c..bd0b07b097e 100644
--- a/myisam/mi_panic.c
+++ b/myisam/mi_panic.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_range.c b/myisam/mi_range.c
index 038f9abc3a6..8e85afc5f80 100644
--- a/myisam/mi_range.c
+++ b/myisam/mi_range.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -45,7 +45,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
if ((inx = _mi_check_index(info,inx)) < 0)
DBUG_RETURN(HA_POS_ERROR);
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(HA_POS_ERROR);
info->update&= (HA_STATE_CHANGED+HA_STATE_ROW_CHANGED);
if (info->s->concurrent_insert)
@@ -58,7 +58,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
info->state->records+ (ha_rows) 1);
if (info->s->concurrent_insert)
rw_unlock(&info->s->key_root_lock[inx]);
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
DBUG_RETURN(HA_POS_ERROR);
DBUG_PRINT("info",("records: %ld",(ulong) (end_pos-start_pos)));
@@ -72,7 +72,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len,
enum ha_rkey_function search_flag)
{
- uint inx=(uint) info->lastinx;
+ uint inx=(uint) info->lastinx, nextflag;
MI_KEYDEF *keyinfo=info->s->keyinfo+inx;
uchar *key_buff;
double pos;
@@ -83,11 +83,16 @@ static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len,
if (key_len == 0)
key_len=USE_WHOLE_KEY;
key_buff=info->lastkey+info->s->base.max_key_length;
- key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len);
+ key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len,
+ (MI_KEYSEG**) 0);
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,
(uchar*) key_buff,key_len););
+ nextflag=myisam_read_vec[search_flag];
+ if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
+ key_len=USE_WHOLE_KEY;
+
pos=_mi_search_pos(info,keyinfo,key_buff,key_len,
- myisam_read_vec[search_flag] | SEARCH_SAVE_BUFF,
+ nextflag | SEARCH_SAVE_BUFF,
info->s->state.key_root[inx]);
if (pos >= 0.0)
{
@@ -145,9 +150,9 @@ static double _mi_search_pos(register MI_INFO *info,
** Matches keynr+1
*/
offset=1.0; /* Matches keynr+1 */
- if (nextflag & SEARCH_FIND &&
+ if ((nextflag & SEARCH_FIND) && nod_flag &&
((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
- key_len) && nod_flag)
+ key_len != USE_WHOLE_KEY))
{
/*
** There may be identical keys in the tree. Try to match on of those.
diff --git a/myisam/mi_rename.c b/myisam/mi_rename.c
index 5c92db3f7ce..db44b8fe28f 100644
--- a/myisam/mi_rename.c
+++ b/myisam/mi_rename.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -51,7 +51,7 @@ int mi_rename(const char *old_name, const char *new_name)
fn_format(from,old_name,"",MI_NAME_IEXT,4);
fn_format(to,new_name,"",MI_NAME_IEXT,4);
- if (my_rename(from, to, MYF(MY_WME)))
+ if (my_rename_with_symlink(from, to, MYF(MY_WME)))
DBUG_RETURN(my_errno);
fn_format(from,old_name,"",MI_NAME_DEXT,4);
fn_format(to,new_name,"",MI_NAME_DEXT,4);
@@ -60,5 +60,5 @@ int mi_rename(const char *old_name, const char *new_name)
DBUG_RETURN(my_raid_rename(from, to, raid_chunks, MYF(MY_WME)) ? my_errno :
0);
#endif
- DBUG_RETURN(my_rename(from, to,MYF(MY_WME)) ? my_errno : 0);
+ DBUG_RETURN(my_rename_with_symlink(from, to,MYF(MY_WME)) ? my_errno : 0);
}
diff --git a/myisam/mi_rfirst.c b/myisam/mi_rfirst.c
index 8928c6332c5..e30f61801a0 100644
--- a/myisam/mi_rfirst.c
+++ b/myisam/mi_rfirst.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_rkey.c b/myisam/mi_rkey.c
index 0df390412b9..1bb478efd3d 100644
--- a/myisam/mi_rkey.c
+++ b/myisam/mi_rkey.c
@@ -23,11 +23,13 @@
/* Ordinary search_flag is 0 ; Give error if no record with key */
int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
- enum ha_rkey_function search_flag)
+ enum ha_rkey_function search_flag)
{
uchar *key_buff;
MYISAM_SHARE *share=info->s;
- uint pack_key_length;
+ MI_KEYDEF *keyinfo;
+ MI_KEYSEG *last_used_keyseg;
+ uint pack_key_length, use_key_length, nextflag;
DBUG_ENTER("mi_rkey");
DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d",
info,inx,search_flag));
@@ -36,31 +38,41 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
DBUG_RETURN(my_errno);
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
+ keyinfo= share->keyinfo + inx;
if (!info->use_packed_key)
{
if (key_len == 0)
key_len=USE_WHOLE_KEY;
key_buff=info->lastkey+info->s->base.max_key_length;
- pack_key_length=_mi_pack_key(info,(uint) inx,key_buff,(uchar*) key,key_len);
- info->last_rkey_length=pack_key_length;
- DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,share->keyinfo[inx].seg,
- key_buff,pack_key_length););
+ pack_key_length=_mi_pack_key(info, (uint) inx, key_buff, (uchar*) key,
+ key_len, &last_used_keyseg);
+ DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,
+ key_buff, pack_key_length););
}
else
{
- /* key is already packed! */
+ /*
+ key is already packed!; This happens when we are using a MERGE TABLE
+ */
key_buff=info->lastkey+info->s->base.max_key_length;
- info->last_rkey_length=pack_key_length=key_len;
+ pack_key_length= key_len;
bmove(key_buff,key,key_len);
+ last_used_keyseg= 0;
}
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
goto err;
if (share->concurrent_insert)
rw_rdlock(&share->key_root_lock[inx]);
- if (!_mi_search(info,info->s->keyinfo+inx,key_buff,pack_key_length,
- myisam_read_vec[search_flag],info->s->state.key_root[inx]))
+
+ nextflag=myisam_read_vec[search_flag];
+ use_key_length=pack_key_length;
+ if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
+ use_key_length=USE_WHOLE_KEY;
+
+ if (!_mi_search(info,keyinfo, key_buff, use_key_length,
+ myisam_read_vec[search_flag], info->s->state.key_root[inx]))
{
while (info->lastpos >= info->state->data_file_length)
{
@@ -70,7 +82,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
exact key, because the keys are sorted according to position
*/
- if (_mi_search_next(info,info->s->keyinfo+inx,info->lastkey,
+ if (_mi_search_next(info, keyinfo, info->lastkey,
info->lastkey_length,
myisam_readnext_vec[search_flag],
info->s->state.key_root[inx]))
@@ -80,8 +92,17 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
if (share->concurrent_insert)
rw_unlock(&share->key_root_lock[inx]);
+ /* Calculate length of the found key; Used by mi_rnext_same */
+ if ((keyinfo->flag & HA_VAR_LENGTH_KEY) && last_used_keyseg &&
+ info->lastpos != HA_OFFSET_ERROR)
+ info->last_rkey_length= _mi_keylength_part(keyinfo, info->lastkey,
+ last_used_keyseg);
+ else
+ info->last_rkey_length= pack_key_length;
+
+ /* Check if we don't want to have record back, only error message */
if (!buf)
- DBUG_RETURN(info->lastpos==HA_OFFSET_ERROR ? my_errno : 0);
+ DBUG_RETURN(info->lastpos == HA_OFFSET_ERROR ? my_errno : 0);
if (!(*info->read_record)(info,info->lastpos,buf))
{
@@ -91,8 +112,9 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
info->lastpos = HA_OFFSET_ERROR; /* Didn't find key */
- /* Store key for read next */
+ /* Store last used key as a base for read next */
memcpy(info->lastkey,key_buff,pack_key_length);
+ info->last_rkey_length= pack_key_length;
bzero((char*) info->lastkey+pack_key_length,info->s->base.rec_reflength);
info->lastkey_length=pack_key_length+info->s->base.rec_reflength;
diff --git a/myisam/mi_rlast.c b/myisam/mi_rlast.c
index c08174e9117..61c3ff58fd5 100644
--- a/myisam/mi_rlast.c
+++ b/myisam/mi_rlast.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_rnext.c b/myisam/mi_rnext.c
index f297740af60..6d135462f96 100644
--- a/myisam/mi_rnext.c
+++ b/myisam/mi_rnext.c
@@ -35,7 +35,7 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_PREV_FOUND)
flag=0; /* Read first */
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
if (info->s->concurrent_insert)
rw_rdlock(&info->s->key_root_lock[inx]);
@@ -51,7 +51,7 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
info->s->state.key_root[inx]);
else
error=_mi_search(info,info->s->keyinfo+inx,info->lastkey,
- info->lastkey_length,flag, info->s->state.key_root[inx]);
+ USE_WHOLE_KEY,flag, info->s->state.key_root[inx]);
if (!error)
{
diff --git a/myisam/mi_rnext_same.c b/myisam/mi_rnext_same.c
index 0e172894cdf..a9d1953323c 100644
--- a/myisam/mi_rnext_same.c
+++ b/myisam/mi_rnext_same.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -27,15 +27,14 @@
int mi_rnext_same(MI_INFO *info, byte *buf)
{
int error;
- uint inx,flag,not_used;
+ uint inx,not_used;
MI_KEYDEF *keyinfo;
DBUG_ENTER("mi_rnext_same");
if ((int) (inx=info->lastinx) < 0 || info->lastpos == HA_OFFSET_ERROR)
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
keyinfo=info->s->keyinfo+inx;
- flag=SEARCH_BIGGER; /* Read next */
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
memcpy(info->lastkey2,info->lastkey,info->last_rkey_length);
@@ -44,7 +43,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf)
for (;;)
{
if ((error=_mi_search_next(info,keyinfo,info->lastkey,
- info->lastkey_length,flag,
+ info->lastkey_length,SEARCH_BIGGER,
info->s->state.key_root[inx])))
break;
if (_mi_key_cmp(keyinfo->seg,info->lastkey2,info->lastkey,
diff --git a/myisam/mi_rprev.c b/myisam/mi_rprev.c
index fff2d2257b6..4807e636252 100644
--- a/myisam/mi_rprev.c
+++ b/myisam/mi_rprev.c
@@ -36,7 +36,7 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx)
if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_NEXT_FOUND)
flag=0; /* Read last */
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
changed=_mi_test_if_changed(info);
if (share->concurrent_insert)
@@ -50,7 +50,7 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx)
share->state.key_root[inx]);
else
error=_mi_search(info,share->keyinfo+inx,info->lastkey,
- info->lastkey_length, flag, share->state.key_root[inx]);
+ USE_WHOLE_KEY, flag, share->state.key_root[inx]);
if (!error)
{
diff --git a/myisam/mi_rrnd.c b/myisam/mi_rrnd.c
index 11fa2af59bd..f8009441cff 100644
--- a/myisam/mi_rrnd.c
+++ b/myisam/mi_rrnd.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_rsame.c b/myisam/mi_rsame.c
index a4092b53c0b..56c8d1226ca 100644
--- a/myisam/mi_rsame.c
+++ b/myisam/mi_rsame.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -41,7 +41,7 @@ int mi_rsame(MI_INFO *info, byte *record, int inx)
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
/* Read row from data file */
- if (_mi_readinfo(info,F_RDLCK,1))
+ if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
if (inx >= 0)
@@ -51,7 +51,8 @@ int mi_rsame(MI_INFO *info, byte *record, int inx)
info->lastpos);
if (info->s->concurrent_insert)
rw_rdlock(&info->s->key_root_lock[inx]);
- VOID(_mi_search(info,info->s->keyinfo+inx,info->lastkey,0,SEARCH_SAME,
+ VOID(_mi_search(info,info->s->keyinfo+inx,info->lastkey, USE_WHOLE_KEY,
+ SEARCH_SAME,
info->s->state.key_root[inx]));
if (info->s->concurrent_insert)
rw_unlock(&info->s->key_root_lock[inx]);
diff --git a/myisam/mi_rsamepos.c b/myisam/mi_rsamepos.c
index 28a5b6783b2..a1d96fb7104 100644
--- a/myisam/mi_rsamepos.c
+++ b/myisam/mi_rsamepos.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_scan.c b/myisam/mi_scan.c
index c06f092ab17..90bc3430ba7 100644
--- a/myisam/mi_scan.c
+++ b/myisam/mi_scan.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/myisam/mi_search.c b/myisam/mi_search.c
index 938062d977d..b98ee351195 100644
--- a/myisam/mi_search.c
+++ b/myisam/mi_search.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -19,29 +19,27 @@
#include "fulltext.h"
#include "m_ctype.h"
-#define CMP(a,b) (a<b ? -1 : a == b ? 0 : 1)
-
static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
- uchar *key, uchar *keypos,
- uint *return_key_length);
+ uchar *key, uchar *keypos,
+ uint *return_key_length);
- /* Check index */
+ /* Check index */
int _mi_check_index(MI_INFO *info, int inx)
{
- if (inx == -1) /* Use last index */
+ if (inx == -1) /* Use last index */
inx=info->lastinx;
if (inx < 0 || ! (((ulonglong) 1 << inx) & info->s->state.key_map))
{
my_errno=HA_ERR_WRONG_INDEX;
return -1;
}
- if (info->lastinx != inx) /* Index changed */
+ if (info->lastinx != inx) /* Index changed */
{
info->lastinx = inx;
info->page_changed=1;
info->update= ((info->update & (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED)) |
- HA_STATE_NEXT_FOUND | HA_STATE_PREV_FOUND);
+ HA_STATE_NEXT_FOUND | HA_STATE_PREV_FOUND);
}
if (info->opt_flag & WRITE_CACHE_USED && flush_io_cache(&info->rec_cache))
return(-1);
@@ -49,15 +47,15 @@ int _mi_check_index(MI_INFO *info, int inx)
} /* mi_check_index */
- /*
- ** Search after row by a key
- ** Position to row is stored in info->lastpos
- ** Return: -1 if not found
- ** 1 if one should continue search on higher level
- */
+ /*
+ ** Search after row by a key
+ ** Position to row is stored in info->lastpos
+ ** Return: -1 if not found
+ ** 1 if one should continue search on higher level
+ */
int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
- uchar *key, uint key_len, uint nextflag, register my_off_t pos)
+ uchar *key, uint key_len, uint nextflag, register my_off_t pos)
{
my_bool last_key;
int error,flag;
@@ -66,25 +64,25 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
uchar lastkey[MI_MAX_KEY_BUFF],*buff;
DBUG_ENTER("_mi_search");
DBUG_PRINT("enter",("pos: %ld nextflag: %d lastpos: %ld",
- pos,nextflag,info->lastpos));
+ pos,nextflag,info->lastpos));
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_len););
if (pos == HA_OFFSET_ERROR)
{
- my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
+ my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
info->lastpos= HA_OFFSET_ERROR;
if (!(nextflag & (SEARCH_SMALLER | SEARCH_BIGGER | SEARCH_LAST)))
- DBUG_RETURN(-1); /* Not found ; return error */
- DBUG_RETURN(1); /* Search at upper levels */
+ DBUG_RETURN(-1); /* Not found ; return error */
+ DBUG_RETURN(1); /* Search at upper levels */
}
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,
- test(!(nextflag & SEARCH_SAVE_BUFF)))))
+ test(!(nextflag & SEARCH_SAVE_BUFF)))))
goto err;
DBUG_DUMP("page",(byte*) buff,mi_getint(buff));
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
- &keypos,lastkey, &last_key);
+ &keypos,lastkey, &last_key);
if (flag == MI_FOUND_WRONG_KEY)
DBUG_RETURN(-1);
nod_flag=mi_test_if_nod(buff);
@@ -93,36 +91,36 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (flag)
{
if ((error=_mi_search(info,keyinfo,key,key_len,nextflag,
- _mi_kpos(nod_flag,keypos))) <= 0)
+ _mi_kpos(nod_flag,keypos))) <= 0)
DBUG_RETURN(error);
if (flag >0)
{
if (nextflag & (SEARCH_SMALLER | SEARCH_LAST) &&
- keypos == buff+2+nod_flag)
- DBUG_RETURN(1); /* Bigger than key */
+ keypos == buff+2+nod_flag)
+ DBUG_RETURN(1); /* Bigger than key */
}
else if (nextflag & SEARCH_BIGGER && keypos >= maxpos)
- DBUG_RETURN(1); /* Smaller than key */
+ DBUG_RETURN(1); /* Smaller than key */
}
else
{
if ((nextflag & SEARCH_FIND) && nod_flag &&
((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
- key_len))
+ key_len != USE_WHOLE_KEY))
{
if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND,
- _mi_kpos(nod_flag,keypos))) >= 0 ||
- my_errno != HA_ERR_KEY_NOT_FOUND)
- DBUG_RETURN(error);
- info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in memory */
+ _mi_kpos(nod_flag,keypos))) >= 0 ||
+ my_errno != HA_ERR_KEY_NOT_FOUND)
+ DBUG_RETURN(error);
+ info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in mem */
}
}
if (pos != info->last_keypage)
{
uchar *old_buff=buff;
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,
- test(!(nextflag & SEARCH_SAVE_BUFF)))))
+ test(!(nextflag & SEARCH_SAVE_BUFF)))))
goto err;
keypos=buff+(keypos-old_buff);
maxpos=buff+(maxpos-old_buff);
@@ -132,13 +130,13 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
{
uint not_used;
if (_mi_get_prev_key(info,keyinfo, buff, info->lastkey, keypos,
- &info->lastkey_length))
+ &info->lastkey_length))
goto err;
if ((nextflag & SEARCH_LAST) &&
- _mi_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
- &not_used))
+ _mi_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
+ &not_used))
{
- my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
+ my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
goto err;
}
}
@@ -157,7 +155,7 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
info->int_keytree_version=keyinfo->version;
info->last_search_keypage=info->last_keypage;
info->page_changed=0;
- info->buff_used= (info->buff != buff); /* If we have to reread buff */
+ info->buff_used= (info->buff != buff); /* If we have to reread buff */
DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
DBUG_RETURN(0);
@@ -169,14 +167,14 @@ err:
} /* _mi_search */
- /* Search after key in page-block */
- /* If packed key puts smaller or identical key in buff */
- /* ret_pos point to where find or bigger key starts */
- /* ARGSUSED */
+ /* Search after key in page-block */
+ /* If packed key puts smaller or identical key in buff */
+ /* ret_pos point to where find or bigger key starts */
+ /* ARGSUSED */
int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
- uchar *buff __attribute__((unused)), my_bool *last_key)
+ uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
+ uchar *buff __attribute__((unused)), my_bool *last_key)
{
reg4 int start,mid,end,save_end;
int flag;
@@ -194,17 +192,17 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
{
mid= (start+end)/2;
if ((flag=_mi_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len,
- comp_flag,&not_used))
- >= 0)
+ comp_flag,&not_used))
+ >= 0)
end=mid;
else
start=mid+1;
}
if (mid != start)
flag=_mi_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len,
- comp_flag,&not_used);
+ comp_flag,&not_used);
if (flag < 0)
- start++; /* point at next, bigger key */
+ start++; /* point at next, bigger key */
*ret_pos=page+(uint) start*totlength;
*last_key= end == save_end;
DBUG_PRINT("exit",("flag: %d keypos: %d",flag,start));
@@ -212,13 +210,13 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
} /* _mi_bin_search */
- /* Used instead of _mi_bin_search() when key is packed */
- /* Puts smaller or identical key in buff */
- /* Key is searched sequentially */
+ /* Used instead of _mi_bin_search() when key is packed */
+ /* Puts smaller or identical key in buff */
+ /* Key is searched sequentially */
int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
- uchar *buff, my_bool *last_key)
+ uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
+ uchar *buff, my_bool *last_key)
{
int flag;
uint nod_flag,length,not_used;
@@ -230,7 +228,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
nod_flag=mi_test_if_nod(page);
page+=2+nod_flag;
*ret_pos=page;
- t_buff[0]=0; /* Avoid bugs */
+ t_buff[0]=0; /* Avoid bugs */
while (page < end)
{
length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,t_buff);
@@ -238,11 +236,11 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
{
my_errno=HA_ERR_CRASHED;
DBUG_PRINT("error",("Found wrong key: length: %d page: %lx end: %lx",
- length,page,end));
+ length,page,end));
DBUG_RETURN(MI_FOUND_WRONG_KEY);
}
if ((flag=_mi_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
- &not_used)) >= 0)
+ &not_used)) >= 0)
break;
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("page: %lx key: '%s' flag: %d",page,t_buff,flag));
@@ -251,14 +249,226 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
*ret_pos=page;
}
if (flag == 0)
- memcpy(buff,t_buff,length); /* Result is first key */
+ memcpy(buff,t_buff,length); /* Result is first key */
*last_key= page == end;
DBUG_PRINT("exit",("flag: %d ret_pos: %lx",flag,*ret_pos));
DBUG_RETURN(flag);
} /* _mi_seq_search */
- /* Get pos to a key_block */
+int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
+ uchar *key, uint key_len, uint nextflag, uchar **ret_pos,
+ uchar *buff, my_bool *last_key)
+{
+ /*
+ my_flag is raw comparison result to be changed according to
+ SEARCH_NO_FIND,SEARCH_LAST and HA_REVERSE_SORT flags.
+ flag is the value returned by _mi_key_cmp and as treated as final
+ */
+ int flag=0, my_flag=-1;
+ uint nod_flag, length, len, matched, cmplen, kseg_len;
+ uint prefix_len,suffix_len;
+ int key_len_skip, seg_len_pack, key_len_left;
+ uchar *end, *kseg, *vseg;
+ uchar *sort_order=keyinfo->seg->charset->sort_order;
+ uchar tt_buff[MI_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
+ uchar *saved_from, *saved_to, *saved_vseg;
+ uint saved_length=0, saved_prefix_len=0;
+ DBUG_ENTER("_mi_prefix_search");
+
+ LINT_INIT(length);
+ LINT_INIT(prefix_len);
+ LINT_INIT(seg_len_pack);
+ LINT_INIT(saved_from);
+ LINT_INIT(saved_to);
+ LINT_INIT(saved_vseg);
+
+ t_buff[0]=0; /* Avoid bugs */
+ end= page+mi_getint(page);
+ nod_flag=mi_test_if_nod(page);
+ page+=2+nod_flag;
+ *ret_pos=page;
+ kseg=key;
+ {
+ uint lenght_pack;
+ get_key_pack_length(kseg_len,lenght_pack,kseg);
+ key_len_skip=lenght_pack+kseg_len;
+ key_len_left=(int) key_len- (int) key_len_skip;
+ cmplen=(key_len_left>=0) ? kseg_len : key_len-lenght_pack;
+ DBUG_PRINT("info",("key: '%.*s'",kseg_len,kseg));
+ }
+
+/*
+ Keys are compressed the following way:
+
+ If the max length of first key segment <= 127 characters the prefix is
+ 1 byte else it's 2 byte
+
+ prefix The high bit is set if this is a prefix for the prev key
+ length Packed length if the previous was a prefix byte
+ [length] Length character of data
+ next-key-seg Next key segments
+*/
+
+ matched=0; /* how many char's from prefix were alredy matched */
+ len=0; /* length of previous key unpacked */
+
+ while (page < end)
+ {
+ uint packed= *page & 128;
+
+ vseg=page;
+ if (keyinfo->seg->length >= 127)
+ {
+ suffix_len=mi_uint2korr(vseg) & 32767;
+ vseg+=2;
+ }
+ else
+ suffix_len= *vseg++ & 127;
+
+ if (packed)
+ {
+ if (suffix_len == 0) /* Same key */
+ prefix_len=len;
+ else
+ {
+ prefix_len=suffix_len;
+ get_key_length(suffix_len,vseg);
+ }
+ }
+ else
+ prefix_len=0;
+
+ len=prefix_len+suffix_len;
+ seg_len_pack=get_pack_length(len);
+ t_buff=tt_buff+3-seg_len_pack;
+ store_key_length(t_buff,len);
+
+ if (prefix_len > saved_prefix_len)
+ memcpy(t_buff+seg_len_pack+saved_prefix_len,saved_vseg,
+ prefix_len-saved_prefix_len);
+ saved_vseg=vseg;
+ saved_prefix_len=prefix_len;
+
+ DBUG_PRINT("loop",("page: '%.*s%.*s'",prefix_len,t_buff+seg_len_pack,suffix_len,vseg));
+ {
+ uchar *from=vseg+suffix_len;
+ MI_KEYSEG *keyseg;
+ uint l;
+
+ for (keyseg=keyinfo->seg+1 ; keyseg->type ; keyseg++ )
+ {
+
+ if (keyseg->flag & HA_NULL_PART)
+ {
+ if (!(*from++))
+ continue;
+ }
+ if (keyseg->flag & (HA_VAR_LENGTH | HA_BLOB_PART | HA_SPACE_PACK))
+ {
+ get_key_length(l,from);
+ }
+ else
+ l=keyseg->length;
+
+ from+=l;
+ }
+ from+=keyseg->length;
+ page=from+nod_flag;
+ length=from-vseg;
+ }
+
+ if (page > end)
+ {
+ my_errno=HA_ERR_CRASHED;
+ DBUG_PRINT("error",("Found wrong key: length: %d page: %lx end: %lx",
+ length,page,end));
+ DBUG_RETURN(MI_FOUND_WRONG_KEY);
+ }
+
+ if (matched >= prefix_len)
+ {
+ /* We have to compare. But we can still skip part of the key */
+ uint left;
+ uchar *k=kseg+prefix_len;
+
+ left=(len>cmplen) ? cmplen-prefix_len : suffix_len;
+
+ matched=prefix_len+left;
+
+ for(my_flag=0;left;left--)
+ if ((my_flag= (int) sort_order[*vseg++] - (int) sort_order[*k++]))
+ break;
+
+ if (my_flag>0) /* mismatch */
+ break;
+ else if (my_flag==0) /* match */
+ { /*
+ ** len cmplen seg_left_len more_segs
+ ** < matched=len; continue search
+ ** > = prefix ? found : (matched=len; continue search)
+ ** > < - ok, found
+ ** = < - ok, found
+ ** = = - ok, found
+ ** = = + next seg
+ */
+ if (len < cmplen)
+ {
+ my_flag= -1;
+ }
+ else if (len > cmplen)
+ {
+ if ((my_flag= (!(nextflag & SEARCH_PREFIX) || key_len_left>0)))
+ break;
+ goto fix_flag;
+ }
+ else if (key_len_left>0)
+ {
+ uint not_used;
+ if ((flag = _mi_key_cmp(keyinfo->seg+1,vseg,
+ k,key_len_left,nextflag,&not_used)) >= 0)
+ break;
+ }
+ else
+ {
+ /* at this line flag==-1 if the following lines were already
+ visited and 0 otherwise, i.e. flag <=0 here always !!! */
+ fix_flag:
+ if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST))
+ flag=(nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
+ if (flag>=0) break;
+ }
+ }
+ matched-=left;
+ }
+ /* else (matched < prefix_len) ---> do nothing. */
+
+ memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
+ saved_to=buff+saved_length;
+ saved_from=saved_vseg;
+ saved_length=length;
+ *ret_pos=page;
+ }
+ if (my_flag)
+ flag=(keyinfo->seg->flag & HA_REVERSE_SORT) ? -my_flag : my_flag;
+ if (flag == 0)
+ {
+ memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
+ saved_to=buff+saved_length;
+ saved_from=saved_vseg;
+ saved_length=length;
+ }
+ if (saved_length)
+ memcpy(saved_to,saved_from,saved_length);
+
+ *last_key= page == end;
+
+ DBUG_PRINT("exit",("flag: %d ret_pos: %lx",flag,*ret_pos));
+ DBUG_RETURN(flag);
+} /* _mi_prefix_search */
+
+
+ /* Get pos to a key_block */
my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
{
@@ -266,11 +476,11 @@ my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
switch (nod_flag) {
#if SIZEOF_OFF_T > 4
case 7:
- return mi_uint7korr(after_key)*MI_KEY_BLOCK_LENGTH;
+ return mi_uint7korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
case 6:
- return mi_uint6korr(after_key)*MI_KEY_BLOCK_LENGTH;
+ return mi_uint6korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
case 5:
- return mi_uint5korr(after_key)*MI_KEY_BLOCK_LENGTH;
+ return mi_uint5korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
#else
case 7:
after_key++;
@@ -280,25 +490,25 @@ my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
after_key++;
#endif
case 4:
- return ((my_off_t) mi_uint4korr(after_key))*MI_KEY_BLOCK_LENGTH;
+ return ((my_off_t) mi_uint4korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
case 3:
- return ((my_off_t) mi_uint3korr(after_key))*MI_KEY_BLOCK_LENGTH;
+ return ((my_off_t) mi_uint3korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
case 2:
- return (my_off_t) (mi_uint2korr(after_key)*MI_KEY_BLOCK_LENGTH);
+ return (my_off_t) (mi_uint2korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH);
case 1:
- return (uint) (*after_key)*MI_KEY_BLOCK_LENGTH;
- case 0: /* At leaf page */
- default: /* Impossible */
+ return (uint) (*after_key)*MI_MIN_KEY_BLOCK_LENGTH;
+ case 0: /* At leaf page */
+ default: /* Impossible */
return(HA_OFFSET_ERROR);
}
} /* _kpos */
- /* Save pos to a key_block */
+ /* Save pos to a key_block */
void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos)
{
- pos/=MI_KEY_BLOCK_LENGTH;
+ pos/=MI_MIN_KEY_BLOCK_LENGTH;
switch (info->s->base.key_reflength) {
#if SIZEOF_OFF_T > 4
case 7: mi_int7store(buff,pos); break;
@@ -316,12 +526,12 @@ void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos)
case 3: mi_int3store(buff,pos); break;
case 2: mi_int2store(buff,(uint) pos); break;
case 1: buff[0]= (uchar) pos; break;
- default: abort(); /* impossible */
+ default: abort(); /* impossible */
}
} /* _mi_kpointer */
- /* Calc pos to a data-record from a key */
+ /* Calc pos to a data-record from a key */
my_off_t _mi_dpos(MI_INFO *info, uint nod_flag, uchar *after_key)
@@ -336,19 +546,19 @@ my_off_t _mi_dpos(MI_INFO *info, uint nod_flag, uchar *after_key)
case 5: pos= (my_off_t) mi_uint5korr(after_key); break;
#else
case 8: pos= (my_off_t) mi_uint4korr(after_key+4); break;
- case 7: pos= (my_off_t) mi_uint4korr(after_key+3); break;
- case 6: pos= (my_off_t) mi_uint4korr(after_key+2); break;
- case 5: pos= (my_off_t) mi_uint4korr(after_key+1); break;
+ case 7: pos= (my_off_t) mi_uint4korr(after_key+3); break;
+ case 6: pos= (my_off_t) mi_uint4korr(after_key+2); break;
+ case 5: pos= (my_off_t) mi_uint4korr(after_key+1); break;
#endif
case 4: pos= (my_off_t) mi_uint4korr(after_key); break;
case 3: pos= (my_off_t) mi_uint3korr(after_key); break;
case 2: pos= (my_off_t) mi_uint2korr(after_key); break;
default:
- pos=0L; /* Shut compiler up */
+ pos=0L; /* Shut compiler up */
}
return (info->s->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
- pos*info->s->base.pack_reclength;
+ (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
+ pos*info->s->base.pack_reclength;
}
@@ -362,22 +572,22 @@ my_off_t _mi_rec_pos(MYISAM_SHARE *s, uchar *ptr)
case 8:
pos= (my_off_t) mi_uint8korr(ptr);
if (pos == HA_OFFSET_ERROR)
- return HA_OFFSET_ERROR; /* end of list */
+ return HA_OFFSET_ERROR; /* end of list */
break;
case 7:
pos= (my_off_t) mi_uint7korr(ptr);
if (pos == (((my_off_t) 1) << 56) -1)
- return HA_OFFSET_ERROR; /* end of list */
+ return HA_OFFSET_ERROR; /* end of list */
break;
case 6:
pos= (my_off_t) mi_uint6korr(ptr);
if (pos == (((my_off_t) 1) << 48) -1)
- return HA_OFFSET_ERROR; /* end of list */
+ return HA_OFFSET_ERROR; /* end of list */
break;
case 5:
pos= (my_off_t) mi_uint5korr(ptr);
if (pos == (((my_off_t) 1) << 40) -1)
- return HA_OFFSET_ERROR; /* end of list */
+ return HA_OFFSET_ERROR; /* end of list */
break;
#else
case 8:
@@ -402,20 +612,20 @@ my_off_t _mi_rec_pos(MYISAM_SHARE *s, uchar *ptr)
if (pos == (my_off_t) (1 << 16) -1)
return HA_OFFSET_ERROR;
break;
- default: abort(); /* Impossible */
+ default: abort(); /* Impossible */
}
return ((s->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
- pos*s->base.pack_reclength);
+ (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
+ pos*s->base.pack_reclength);
}
- /* save position to record */
+ /* save position to record */
void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos)
{
if (!(info->s->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) &&
+ (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) &&
pos != HA_OFFSET_ERROR)
pos/=info->s->base.pack_reclength;
@@ -438,27 +648,28 @@ void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos)
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
case 2: mi_int2store(buff,(uint) pos); break;
- default: abort(); /* Impossible */
+ default: abort(); /* Impossible */
}
} /* _mi_dpointer */
int _mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
- uchar *b, uint b_length, my_bool part_key)
+ uchar *b, uint b_length, my_bool part_key)
{
- uint length= min(a_length,b_length);
- uchar *end= a+ length;
int flag;
#ifdef USE_STRCOLL
if (use_strcoll(charset_info))
{
- if ((flag = my_strnncoll(charset_info, a, a_length, b, b_length)))
- return flag;
+ if (part_key && b_length < a_length)
+ a_length=b_length;
+ return my_strnncoll(charset_info, a, a_length, b, b_length);
}
else
#endif
{
+ uint length= min(a_length,b_length);
+ uchar *end= a+ length;
uchar *sort_order=charset_info->sort_order;
while (a < end)
if ((flag= (int) sort_order[*a++] - (int) sort_order[*b++]))
@@ -471,7 +682,7 @@ int _mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
- my_bool part_key)
+ my_bool part_key)
{
uint length= min(a_length,b_length);
uchar *end= a+ length;
@@ -486,19 +697,35 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
}
- /*
- ** Compare two keys with is bigger
- ** Returns <0, 0, >0 acording to with is bigger
- ** Key_length specifies length of key to use. Number-keys can't
- ** be splited
- ** If flag <> SEARCH_FIND compare also position
- */
+/*
+ Compare two keys
+
+ SYNOPSIS
+ _mi_key_cmp()
+ keyseg Key segments of key to compare
+ a First key to compare, in format from _mi_pack_key()
+ This is normally key specified by user
+ b Second key to compare. This is always from a row
+ key_length Length of key to compare. This can be shorter than
+ a to just compare sub keys
+ next_flag How keys should be compared
+ If bit SEARCH_FIND is not set the keys includes the row
+ position and this should also be compared
+
+ NOTES
+ Number-keys can't be splited
+
+ RETURN VALUES
+ <0 If a < b
+ 0 If a == b
+ >0 If a > b
+*/
#define FCMP(A,B) ((int) (A) - (int) (B))
int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
- register uchar *b, uint key_length, uint nextflag,
- uint *diff_pos)
+ register uchar *b, uint key_length, uint nextflag,
+ uint *diff_pos)
{
int flag;
int16 s_1,s_2;
@@ -508,129 +735,158 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
double d_1,d_2;
uint next_key_length;
- if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
- key_length=USE_WHOLE_KEY;
*diff_pos=0;
-
for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
{
uchar *end;
+ uint piks=! (keyseg->flag & HA_NO_SORT);
(*diff_pos)++;
/* Handle NULL part */
if (keyseg->null_bit)
{
key_length--;
- if (*a != *b)
+ if (*a != *b && piks)
{
- flag = (int) *a - (int) *b;
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ flag = (int) *a - (int) *b;
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
}
b++;
- if (!*a++) /* If key was NULL */
+ if (!*a++) /* If key was NULL */
{
- if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
- nextflag=SEARCH_SAME; /* Allow duplicate keys */
- next_key_length=key_length;
- continue; /* To next key part */
+ if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
+ nextflag=SEARCH_SAME; /* Allow duplicate keys */
+ else if (nextflag & SEARCH_NULL_ARE_NOT_EQUAL)
+ {
+ /*
+ This is only used from mi_check() to calculate cardinality.
+ It can't be used when searching for a key as this would cause
+ compare of (a,b) and (b,a) to return the same value.
+ */
+ return -1;
+ }
+ next_key_length=key_length;
+ continue; /* To next key part */
}
}
end= a+ min(keyseg->length,key_length);
next_key_length=key_length-keyseg->length;
switch ((enum ha_base_keytype) keyseg->type) {
- case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
+ case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
if (keyseg->flag & HA_SPACE_PACK)
{
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
+ int a_length,b_length,pack_length;
+ get_key_length(a_length,a);
+ get_key_pack_length(b_length,pack_length,b);
+ next_key_length=key_length-b_length-pack_length;
- if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
+ if (piks &&
+ (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
(my_bool) ((nextflag & SEARCH_PREFIX) &&
next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- break;
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a+=a_length;
+ b+=b_length;
+ break;
}
else
{
- uint length=(uint) (end-a);
- if ((flag=_mi_compare_text(keyseg->charset,a,length,b,length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a=end;
- b+=length;
+ uint length=(uint) (end-a), a_length=length, b_length=length;
+ if (!(nextflag & SEARCH_PREFIX))
+ {
+ while (a_length && a[a_length-1] == ' ')
+ a_length--;
+ while (b_length && b[b_length-1] == ' ')
+ b_length--;
+ }
+ if (piks &&
+ (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
+ (my_bool) ((nextflag & SEARCH_PREFIX)
+ && next_key_length <= 0))))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a=end;
+ b+=length;
}
break;
case HA_KEYTYPE_BINARY:
if (keyseg->flag & HA_SPACE_PACK)
{
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
+ int a_length,b_length,pack_length;
+ get_key_length(a_length,a);
+ get_key_pack_length(b_length,pack_length,b);
+ next_key_length=key_length-b_length-pack_length;
- if ((flag=compare_bin(a,a_length,b,b_length,
+ if (piks &&
+ (flag=compare_bin(a,a_length,b,b_length,
(my_bool) ((nextflag & SEARCH_PREFIX) &&
next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- break;
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a+=a_length;
+ b+=b_length;
+ break;
}
else
{
- uint length=keyseg->length;
- if ((flag=compare_bin(a,length,b,length,
+ uint length=keyseg->length;
+ if (piks &&
+ (flag=compare_bin(a,length,b,length,
(my_bool) ((nextflag & SEARCH_PREFIX) &&
next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=length;
- b+=length;
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a+=length;
+ b+=length;
}
break;
case HA_KEYTYPE_VARTEXT:
{
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
-
- if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
+ int a_length,full_a_length,b_length,full_b_length,pack_length;
+ get_key_length(a_length,a);
+ get_key_pack_length(b_length,pack_length,b);
+ full_a_length=a_length;
+ full_b_length=b_length;
+ next_key_length=key_length-b_length-pack_length;
+
+ if ((nextflag & (SEARCH_FIND | SEARCH_UPDATE)) == SEARCH_FIND)
+ {
+ while (a_length && a[a_length-1] == ' ')
+ a_length--;
+ while (b_length && b[b_length-1] == ' ')
+ b_length--;
+ }
+ if (piks &&
+ (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length,
(my_bool) ((nextflag & SEARCH_PREFIX) &&
next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- break;
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a+=full_a_length;
+ b+=full_b_length;
+ break;
}
break;
case HA_KEYTYPE_VARBINARY:
{
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
+ int a_length,b_length,pack_length;
+ get_key_length(a_length,a);
+ get_key_pack_length(b_length,pack_length,b);
+ next_key_length=key_length-b_length-pack_length;
- if ((flag=compare_bin(a,a_length,b,b_length,
+ if (piks &&
+ (flag=compare_bin(a,a_length,b,b_length,
(my_bool) ((nextflag & SEARCH_PREFIX) &&
next_key_length <= 0))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- break;
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a+=a_length;
+ b+=b_length;
+ break;
}
break;
case HA_KEYTYPE_INT8:
{
int i_1= (int) *((signed char*) a);
int i_2= (int) *((signed char*) b);
- if ((flag = CMP(i_1,i_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(i_1,i_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b++;
break;
@@ -638,125 +894,132 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
case HA_KEYTYPE_SHORT_INT:
s_1= mi_sint2korr(a);
s_2= mi_sint2korr(b);
- if ((flag = CMP(s_1,s_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(s_1,s_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 2; /* sizeof(short int); */
break;
case HA_KEYTYPE_USHORT_INT:
{
- uint16 us_1,us_2;
- us_1= mi_sint2korr(a);
- us_2= mi_sint2korr(b);
- if ((flag = CMP(us_1,us_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+=2; /* sizeof(short int); */
- break;
+ uint16 us_1,us_2;
+ us_1= mi_sint2korr(a);
+ us_2= mi_sint2korr(b);
+ if (piks && (flag = CMP_NUM(us_1,us_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ a= end;
+ b+=2; /* sizeof(short int); */
+ break;
}
case HA_KEYTYPE_LONG_INT:
l_1= mi_sint4korr(a);
l_2= mi_sint4korr(b);
- if ((flag = CMP(l_1,l_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(l_1,l_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 4; /* sizeof(long int); */
break;
case HA_KEYTYPE_ULONG_INT:
u_1= mi_sint4korr(a);
u_2= mi_sint4korr(b);
- if ((flag = CMP(u_1,u_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(u_1,u_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 4; /* sizeof(long int); */
break;
case HA_KEYTYPE_INT24:
l_1=mi_sint3korr(a);
l_2=mi_sint3korr(b);
- if ((flag = CMP(l_1,l_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(l_1,l_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 3;
break;
case HA_KEYTYPE_UINT24:
l_1=mi_uint3korr(a);
l_2=mi_uint3korr(b);
- if ((flag = CMP(l_1,l_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(l_1,l_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 3;
break;
case HA_KEYTYPE_FLOAT:
mi_float4get(f_1,a);
mi_float4get(f_2,b);
- if ((flag = CMP(f_1,f_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(f_1,f_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 4; /* sizeof(float); */
break;
case HA_KEYTYPE_DOUBLE:
mi_float8get(d_1,a);
mi_float8get(d_2,b);
- if ((flag = CMP(d_1,d_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(d_1,d_2)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 8; /* sizeof(double); */
break;
- case HA_KEYTYPE_NUM: /* Numeric key */
+ case HA_KEYTYPE_NUM: /* Numeric key */
{
int swap_flag= 0;
int alength,blength;
-
+
if (keyseg->flag & HA_REVERSE_SORT)
{
- swap(uchar*,a,b);
- swap_flag=1; /* Remember swap of a & b */
+ swap(uchar*,a,b);
+ swap_flag=1; /* Remember swap of a & b */
end= a+ (int) (end-b);
}
if (keyseg->flag & HA_SPACE_PACK)
{
- alength= *a++; blength= *b++;
- end=a+alength;
- next_key_length=key_length-blength-1;
+ alength= *a++; blength= *b++;
+ end=a+alength;
+ next_key_length=key_length-blength-1;
}
else
{
- alength= (int) (end-a);
- blength=keyseg->length;
- /* remove pre space from keys */
- for ( ; alength && *a == ' ' ; a++, alength--) ;
- for ( ; blength && *b == ' ' ; b++, blength--) ;
- }
-
- if (*a == '-')
- {
- if (*b != '-')
- return -1;
- a++; b++;
- swap(uchar*,a,b);
- swap(int,alength,blength);
- swap_flag=1-swap_flag;
- alength--; blength--;
- end=a+alength;
+ alength= (int) (end-a);
+ blength=keyseg->length;
+ /* remove pre space from keys */
+ for ( ; alength && *a == ' ' ; a++, alength--) ;
+ for ( ; blength && *b == ' ' ; b++, blength--) ;
}
- else if (*b == '-')
- return 1;
- while (alength && (*a == '+' || *a == '0'))
+ if (piks)
{
- a++; alength--;
+ if (*a == '-')
+ {
+ if (*b != '-')
+ return -1;
+ a++; b++;
+ swap(uchar*,a,b);
+ swap(int,alength,blength);
+ swap_flag=1-swap_flag;
+ alength--; blength--;
+ end=a+alength;
+ }
+ else if (*b == '-')
+ return 1;
+ while (alength && (*a == '+' || *a == '0'))
+ {
+ a++; alength--;
+ }
+ while (blength && (*b == '+' || *b == '0'))
+ {
+ b++; blength--;
+ }
+ if (alength != blength)
+ return (alength < blength) ? -1 : 1;
+ while (a < end)
+ if (*a++ != *b++)
+ return ((int) a[-1] - (int) b[-1]);
}
- while (blength && (*b == '+' || *b == '0'))
+ else
{
- b++; blength--;
+ b+=(end-a);
+ a=end;
}
- if (alength != blength)
- return (alength < blength) ? -1 : 1;
- while (a < end)
- if (*a++ != *b++)
- return ((int) a[-1] - (int) b[-1]);
-
- if (swap_flag) /* Restore pointers */
- swap(uchar*,a,b);
+
+ if (swap_flag) /* Restore pointers */
+ swap(uchar*,a,b);
break;
}
#ifdef HAVE_LONG_LONG
@@ -765,8 +1028,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
longlong ll_a,ll_b;
ll_a= mi_sint8korr(a);
ll_b= mi_sint8korr(b);
- if ((flag = CMP(ll_a,ll_b)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(ll_a,ll_b)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 8;
break;
@@ -776,15 +1039,15 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
ulonglong ll_a,ll_b;
ll_a= mi_uint8korr(a);
ll_b= mi_uint8korr(b);
- if ((flag = CMP(ll_a,ll_b)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
+ if (piks && (flag = CMP_NUM(ll_a,ll_b)))
+ return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a= end;
b+= 8;
break;
}
#endif
- case HA_KEYTYPE_END: /* Ready */
- goto end; /* diff_pos is incremented */
+ case HA_KEYTYPE_END: /* Ready */
+ goto end; /* diff_pos is incremented */
}
}
(*diff_pos)++;
@@ -799,33 +1062,33 @@ end:
{
if (*a++ != *b++)
{
- flag= FCMP(a[-1],b[-1]);
- break;
+ flag= FCMP(a[-1],b[-1]);
+ break;
}
}
if (nextflag & SEARCH_SAME)
- return (flag); /* read same */
+ return (flag); /* read same */
if (nextflag & SEARCH_BIGGER)
- return (flag <= 0 ? -1 : 1); /* read next */
- return (flag < 0 ? -1 : 1); /* read previous */
+ return (flag <= 0 ? -1 : 1); /* read next */
+ return (flag < 0 ? -1 : 1); /* read previous */
}
return 0;
} /* _mi_key_cmp */
- /* Get key from key-block */
- /* page points at previous key; its advanced to point at next key */
- /* key should contain previous key */
- /* Returns length of found key + pointers */
- /* nod_flag is a flag if we are on nod */
+ /* Get key from key-block */
+ /* page points at previous key; its advanced to point at next key */
+ /* key should contain previous key */
+ /* Returns length of found key + pointers */
+ /* nod_flag is a flag if we are on nod */
- /* same as _mi_get_key but used with fixed length keys */
+ /* same as _mi_get_key but used with fixed length keys */
uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag,
- register uchar **page, register uchar *key)
+ register uchar **page, register uchar *key)
{
memcpy((byte*) key,(byte*) *page,
- (size_t) (keyinfo->keylength+nod_flag));
+ (size_t) (keyinfo->keylength+nod_flag));
*page+=keyinfo->keylength+nod_flag;
return(keyinfo->keylength);
} /* _mi_get_static_key */
@@ -834,7 +1097,7 @@ uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag,
/* Key with is packed against previous key or key with a NULL column */
uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
- register uchar **page_pos, register uchar *key)
+ register uchar **page_pos, register uchar *key)
{
reg1 MI_KEYSEG *keyseg;
uchar *start_key,*page=*page_pos;
@@ -850,11 +1113,11 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
uint packed= *page & 128,tot_length,rest_length;
if (keyseg->length >= 127)
{
- length=mi_uint2korr(page) & 32767;
- page+=2;
+ length=mi_uint2korr(page) & 32767;
+ page+=2;
}
else
- length= *page++ & 127;
+ length= *page++ & 127;
if (packed)
{
@@ -915,23 +1178,23 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
}
else
{
- if (keyseg->flag & HA_NULL_PART)
- {
- if (!length--) /* Null part */
- {
- *key++=0;
- continue;
- }
- *key++=1; /* Not null */
- }
+ if (keyseg->flag & HA_NULL_PART)
+ {
+ if (!length--) /* Null part */
+ {
+ *key++=0;
+ continue;
+ }
+ *key++=1; /* Not null */
+ }
}
if (length > (uint) keyseg->length)
{
- DBUG_PRINT("error",("Found too long packed key: %d of %d at %lx",
- length, keyseg->length, *page_pos));
- DBUG_DUMP("key",(char*) *page_pos,16);
- my_errno=HA_ERR_CRASHED;
- return 0; /* Error */
+ DBUG_PRINT("error",("Found too long packed key: %d of %d at %lx",
+ length, keyseg->length, *page_pos));
+ DBUG_DUMP("key",(char*) *page_pos,16);
+ my_errno=HA_ERR_CRASHED;
+ return 0; /* Error */
}
store_key_length_inc(key,length);
}
@@ -939,18 +1202,18 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
{
if (keyseg->flag & HA_NULL_PART)
{
- if (!(*key++ = *page++))
- continue;
+ if (!(*key++ = *page++))
+ continue;
}
if (keyseg->flag &
- (HA_VAR_LENGTH | HA_BLOB_PART | HA_SPACE_PACK))
+ (HA_VAR_LENGTH | HA_BLOB_PART | HA_SPACE_PACK))
{
- uchar *tmp=page;
- get_key_length(length,tmp);
- length+=(uint) (tmp-page);
+ uchar *tmp=page;
+ get_key_length(length,tmp);
+ length+=(uint) (tmp-page);
}
else
- length=keyseg->length;
+ length=keyseg->length;
}
memcpy((byte*) key,(byte*) page,(size_t) length);
key+=length;
@@ -967,12 +1230,13 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
/* key that is packed relatively to previous */
uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
- register uchar **page_pos, register uchar *key)
+ register uchar **page_pos, register uchar *key)
{
reg1 MI_KEYSEG *keyseg;
- uchar *start_key,*page=*page_pos,*page_end,*from,*from_end;
+ uchar *start_key,*page,*page_end,*from,*from_end;
uint length,tmp;
+ page= *page_pos;
page_end=page+MI_MAX_KEY_BUFF+1;
start_key=key;
@@ -982,16 +1246,16 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
if (length > keyinfo->maxlength)
{
DBUG_PRINT("error",("Found too long binary packed key: %d of %d at %lx",
- length, keyinfo->maxlength, *page_pos));
+ length, keyinfo->maxlength, *page_pos));
DBUG_DUMP("key",(char*) *page_pos,16);
my_errno=HA_ERR_CRASHED;
- return 0; /* Wrong key */
+ return 0; /* Wrong key */
}
from=key; from_end=key+length;
}
else
{
- from=page; from_end=page_end; /* Not packed key */
+ from=page; from_end=page_end; /* Not packed key */
}
/*
@@ -1005,7 +1269,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
{
if (from == from_end) { from=page; from_end=page_end; }
if (!(*key++ = *from++))
- continue; /* Null part */
+ continue; /* Null part */
}
if (keyseg->flag & (HA_VAR_LENGTH | HA_BLOB_PART | HA_SPACE_PACK))
{
@@ -1013,10 +1277,10 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
if (from == from_end) { from=page; from_end=page_end; }
if ((length= (*key++ = *from++)) == 255)
{
- if (from == from_end) { from=page; from_end=page_end; }
- length= (uint) ((*key++ = *from++)) << 8;
- if (from == from_end) { from=page; from_end=page_end; }
- length+= (uint) ((*key++ = *from++));
+ if (from == from_end) { from=page; from_end=page_end; }
+ length= (uint) ((*key++ = *from++)) << 8;
+ if (from == from_end) { from=page; from_end=page_end; }
+ length+= (uint) ((*key++ = *from++));
}
}
else
@@ -1024,18 +1288,20 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
if ((tmp=(uint) (from_end-from)) <= length)
{
- key+=tmp; /* Use old key */
+ key+=tmp; /* Use old key */
length-=tmp;
from=page; from_end=page_end;
}
- memcpy((byte*) key,(byte*) from,(size_t) length);
+ DBUG_PRINT("info",("key: %lx from: %lx length: %u",
+ key, from, length));
+ memcpy_overlap((byte*) key, (byte*) from, (size_t) length);
key+=length;
from+=length;
}
length=keyseg->length+nod_flag;
if ((tmp=(uint) (from_end-from)) <= length)
{
- memcpy(key+tmp,page,length-tmp); /* Get last part of key */
+ memcpy(key+tmp,page,length-tmp); /* Get last part of key */
*page_pos= page+length-tmp;
}
else
@@ -1044,7 +1310,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
{
DBUG_PRINT("error",("Error when unpacking key"));
my_errno=HA_ERR_CRASHED;
- return 0; /* Error */
+ return 0; /* Error */
}
memcpy((byte*) key,(byte*) from,(size_t) length);
*page_pos= from+length;
@@ -1053,11 +1319,11 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
}
- /* Get key at position without knowledge of previous key */
- /* Returns pointer to next key */
+ /* Get key at position without knowledge of previous key */
+ /* Returns pointer to next key */
uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
- uchar *key, uchar *keypos, uint *return_key_length)
+ uchar *key, uchar *keypos, uint *return_key_length)
{
uint nod_flag;
DBUG_ENTER("_mi_get_key");
@@ -1071,14 +1337,14 @@ uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
else
{
page+=2+nod_flag;
- key[0]=0; /* safety */
+ key[0]=0; /* safety */
while (page <= keypos)
{
*return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key);
if (*return_key_length == 0)
{
- my_errno=HA_ERR_CRASHED;
- DBUG_RETURN(0);
+ my_errno=HA_ERR_CRASHED;
+ DBUG_RETURN(0);
}
}
}
@@ -1087,12 +1353,12 @@ uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
} /* _mi_get_key */
- /* Get key at position without knowledge of previous key */
- /* Returns 0 if ok */
+ /* Get key at position without knowledge of previous key */
+ /* Returns 0 if ok */
static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
- uchar *key, uchar *keypos,
- uint *return_key_length)
+ uchar *key, uchar *keypos,
+ uint *return_key_length)
{
uint nod_flag;
DBUG_ENTER("_mi_get_prev_key");
@@ -1102,20 +1368,20 @@ static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
{
*return_key_length=keyinfo->keylength;
bmove((byte*) key,(byte*) keypos- *return_key_length-nod_flag,
- *return_key_length);
+ *return_key_length);
DBUG_RETURN(0);
}
else
{
page+=2+nod_flag;
- key[0]=0; /* safety */
+ key[0]=0; /* safety */
while (page < keypos)
{
*return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key);
if (*return_key_length == 0)
{
- my_errno=HA_ERR_CRASHED;
- DBUG_RETURN(1);
+ my_errno=HA_ERR_CRASHED;
+ DBUG_RETURN(1);
}
}
}
@@ -1124,11 +1390,11 @@ static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
- /* Get last key from key-page */
- /* Return pointer to where key starts */
+ /* Get last key from key-page */
+ /* Return pointer to where key starts */
uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
- uchar *lastkey, uchar *endpos, uint *return_key_length)
+ uchar *lastkey, uchar *endpos, uint *return_key_length)
{
uint nod_flag;
uchar *lastpos;
@@ -1153,9 +1419,9 @@ uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
*return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,lastkey);
if (*return_key_length == 0)
{
- DBUG_PRINT("error",("Couldn't find last key: page: %lx",page));
- my_errno=HA_ERR_CRASHED;
- DBUG_RETURN(0);
+ DBUG_PRINT("error",("Couldn't find last key: page: %lx",page));
+ my_errno=HA_ERR_CRASHED;
+ DBUG_RETURN(0);
}
}
}
@@ -1164,7 +1430,7 @@ uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
} /* _mi_get_last_key */
- /* Calculate length of key */
+ /* Calculate length of key */
uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
{
@@ -1179,7 +1445,7 @@ uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
{
if (keyseg->flag & HA_NULL_PART)
if (!*key++)
- continue;
+ continue;
if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH))
{
uint length;
@@ -1193,28 +1459,59 @@ uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
} /* _mi_keylength */
- /* Move a key */
+/*
+ Calculate length of part key.
+
+ Used in mi_rkey() to find the key found for the key-part that was used.
+ This is needed in case of multi-byte character sets where we may search
+ after '0xDF' but find 'ss'
+*/
+
+uint _mi_keylength_part(MI_KEYDEF *keyinfo, register uchar *key,
+ MI_KEYSEG *end)
+{
+ reg1 MI_KEYSEG *keyseg;
+ uchar *start= key;
+
+ for (keyseg=keyinfo->seg ; keyseg != end ; keyseg++)
+ {
+ if (keyseg->flag & HA_NULL_PART)
+ if (!*key++)
+ continue;
+ if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH))
+ {
+ uint length;
+ get_key_length(length,key);
+ key+=length;
+ }
+ else
+ key+= keyseg->length;
+ }
+ return (uint) (key-start);
+}
+
+ /* Move a key */
uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, uchar *from)
{
reg1 uint length;
memcpy((byte*) to, (byte*) from,
- (size_t) (length=_mi_keylength(keyinfo,from)));
+ (size_t) (length=_mi_keylength(keyinfo,from)));
return to+length;
}
- /* Find next/previous record with same key */
- /* This can't be used when database is touched after last read */
+ /* Find next/previous record with same key */
+ /* This can't be used when database is touched after last read */
int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
- uchar *key, uint key_length, uint nextflag, my_off_t pos)
+ uchar *key, uint key_length, uint nextflag, my_off_t pos)
{
int error;
uint nod_flag;
uchar lastkey[MI_MAX_KEY_BUFF];
DBUG_ENTER("_mi_search_next");
DBUG_PRINT("enter",("nextflag: %d lastpos: %ld int_keypos: %lx",
- nextflag,(long) info->lastpos,info->int_keypos));
+ nextflag,(long) info->lastpos,info->int_keypos));
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
/* Force full read if we are at last key or if we are not on a leaf
@@ -1228,51 +1525,53 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
info->page_changed ||
(info->int_keytree_version != keyinfo->version &&
(info->int_nod_flag || info->buff_used)))
- DBUG_RETURN(_mi_search(info,keyinfo,key,key_length,
- nextflag | SEARCH_SAVE_BUFF, pos));
+ DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
+ nextflag | SEARCH_SAVE_BUFF, pos));
if (info->buff_used)
{
if (!_mi_fetch_keypage(info,keyinfo,info->last_search_keypage,
- info->buff,0))
+ info->buff,0))
DBUG_RETURN(-1);
info->buff_used=0;
}
/* Last used buffer is in info->buff */
nod_flag=mi_test_if_nod(info->buff);
- memcpy(lastkey,key,key_length);
- if (nextflag & SEARCH_BIGGER) /* Next key */
+ if (nextflag & SEARCH_BIGGER) /* Next key */
{
my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos);
if (tmp_pos != HA_OFFSET_ERROR)
{
- if ((error=_mi_search(info,keyinfo,key,key_length,
- nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
- DBUG_RETURN(error);
+ if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
+ nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
+ DBUG_RETURN(error);
}
+ memcpy(lastkey,key,key_length);
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,
- &info->int_keypos,lastkey)))
+ &info->int_keypos,lastkey)))
DBUG_RETURN(-1);
}
- else /* Previous key */
+ else /* Previous key */
{
uint length;
/* Find start of previous key */
info->int_keypos=_mi_get_last_key(info,keyinfo,info->buff,lastkey,
- info->int_keypos, &length);
+ info->int_keypos, &length);
if (!info->int_keypos)
DBUG_RETURN(-1);
if (info->int_keypos == info->buff+2)
- DBUG_RETURN(_mi_search(info,keyinfo,key,key_length,
- nextflag | SEARCH_SAVE_BUFF, pos));
- if ((error=_mi_search(info,keyinfo,key,0,nextflag | SEARCH_SAVE_BUFF,
- _mi_kpos(nod_flag,info->int_keypos))) <= 0)
+ DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
+ nextflag | SEARCH_SAVE_BUFF, pos));
+ if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
+ nextflag | SEARCH_SAVE_BUFF,
+ _mi_kpos(nod_flag,info->int_keypos))) <= 0)
DBUG_RETURN(error);
+ /* QQ: We should be able to optimize away the following call */
if (! _mi_get_last_key(info,keyinfo,info->buff,lastkey,
- info->int_keypos,&info->lastkey_length))
+ info->int_keypos,&info->lastkey_length))
DBUG_RETURN(-1);
}
memcpy(info->lastkey,lastkey,info->lastkey_length);
@@ -1282,11 +1581,11 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
} /* _mi_search_next */
- /* Search after position for the first row in an index */
- /* This is stored in info->lastpos */
+ /* Search after position for the first row in an index */
+ /* This is stored in info->lastpos */
int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
- register my_off_t pos)
+ register my_off_t pos)
{
uint nod_flag;
uchar *page;
@@ -1311,7 +1610,7 @@ int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
} while ((pos=_mi_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
- info->lastkey);
+ info->lastkey);
info->int_keypos=page; info->int_maxpos=info->buff+mi_getint(info->buff)-1;
info->int_nod_flag=nod_flag;
info->int_keytree_version=keyinfo->version;
@@ -1324,11 +1623,11 @@ int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
} /* _mi_search_first */
- /* Search after position for the last row in an index */
- /* This is stored in info->lastpos */
+ /* Search after position for the last row in an index */
+ /* This is stored in info->lastpos */
int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
- register my_off_t pos)
+ register my_off_t pos)
{
uint nod_flag;
uchar *buff,*page;
@@ -1336,7 +1635,7 @@ int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (pos == HA_OFFSET_ERROR)
{
- my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
+ my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
info->lastpos= HA_OFFSET_ERROR;
DBUG_RETURN(-1);
}
@@ -1354,7 +1653,7 @@ int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
} while ((pos=_mi_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
if (!_mi_get_last_key(info,keyinfo,buff,info->lastkey,page,
- &info->lastkey_length))
+ &info->lastkey_length))
DBUG_RETURN(-1);
info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
info->int_keypos=info->int_maxpos=page;
@@ -1374,22 +1673,22 @@ int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
** Functions to store and pack a key in a page
**
** mi_calc_xx_key_length takes the following arguments:
-** nod_flag If nod: Length of nod-pointer
-** next_key Position to pos after the new key in buffer
-** org_key Key that was before the next key in buffer
-** prev_key Last key before current key
-** key Key that will be stored
-** s_temp Information how next key will be packed
+** nod_flag If nod: Length of nod-pointer
+** next_key Position to pos after the new key in buffer
+** org_key Key that was before the next key in buffer
+** prev_key Last key before current key
+** key Key that will be stored
+** s_temp Information how next key will be packed
****************************************************************************/
/* Static length key */
int
_mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
- uchar *next_pos __attribute__((unused)),
- uchar *org_key __attribute__((unused)),
- uchar *prev_key __attribute__((unused)),
- uchar *key, MI_KEY_PARAM *s_temp)
+ uchar *next_pos __attribute__((unused)),
+ uchar *org_key __attribute__((unused)),
+ uchar *prev_key __attribute__((unused)),
+ uchar *key, MI_KEY_PARAM *s_temp)
{
s_temp->key=key;
return (int) (s_temp->totlength=keyinfo->keylength+nod_flag);
@@ -1399,10 +1698,10 @@ _mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
int
_mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
- uchar *next_pos __attribute__((unused)),
- uchar *org_key __attribute__((unused)),
- uchar *prev_key __attribute__((unused)),
- uchar *key, MI_KEY_PARAM *s_temp)
+ uchar *next_pos __attribute__((unused)),
+ uchar *org_key __attribute__((unused)),
+ uchar *prev_key __attribute__((unused)),
+ uchar *key, MI_KEY_PARAM *s_temp)
{
s_temp->key=key;
return (int) (s_temp->totlength=_mi_keylength(keyinfo,key)+nod_flag);
@@ -1417,10 +1716,10 @@ _mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
If the max length of first key segment <= 127 characters the prefix is
1 byte else it's 2 byte
- prefix byte The high bit is set if this is a prefix for the prev key
- length Packed length if the previous was a prefix byte
- [length] Length character of data
- next-key-seg Next key segments
+ prefix byte The high bit is set if this is a prefix for the prev key
+ length Packed length if the previous was a prefix byte
+ [length] Length character of data
+ next-key-seg Next key segments
If the first segment can have NULL:
The length is 0 for NULLS and 1+length for not null columns.
@@ -1429,8 +1728,8 @@ _mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
int
_mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
- uchar *org_key, uchar *prev_key, uchar *key,
- MI_KEY_PARAM *s_temp)
+ uchar *org_key, uchar *prev_key, uchar *key,
+ MI_KEY_PARAM *s_temp)
{
reg1 MI_KEYSEG *keyseg;
int length;
@@ -1471,15 +1770,15 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
s_temp->key=key;
s_temp->ref_length=s_temp->key_length=0;
s_temp->totlength=key_length-1+diff_flag;
- s_temp->next_key_pos=0; /* No next key */
+ s_temp->next_key_pos=0; /* No next key */
return (s_temp->totlength);
}
s_temp->store_not_null=1;
- key_length--; /* We don't store NULL */
+ key_length--; /* We don't store NULL */
if (prev_key && !*prev_key++)
- org_key=prev_key=0; /* Can't pack against prev */
+ org_key=prev_key=0; /* Can't pack against prev */
else if (org_key)
- org_key++; /* Skipp NULL */
+ org_key++; /* Skipp NULL */
}
else
s_temp->store_not_null=0;
@@ -1495,14 +1794,14 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
if (prev_key)
{
get_key_length(org_key_length,prev_key);
- s_temp->prev_key=prev_key; /* Pointer at data */
+ s_temp->prev_key=prev_key; /* Pointer at data */
/* Don't use key-pack if length == 0 */
if (new_key_length && new_key_length == org_key_length)
same_length=1;
else if (new_key_length > org_key_length)
end=key + org_key_length;
- if (sort_order) /* SerG */
+ if (sort_order) /* SerG */
{
while (key < end && sort_order[*key] == sort_order[*prev_key])
{
@@ -1513,7 +1812,7 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
{
while (key < end && *key == *prev_key)
{
- key++; prev_key++;
+ key++; prev_key++;
}
}
}
@@ -1528,15 +1827,15 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
length=(int) key_length-(int) (key_end-start)-length_pack;
length+= diff_flag;
if (next_key)
- { /* Can't combine with next */
- s_temp->n_length= *next_key; /* Needed by _mi_store_key */
+ { /* Can't combine with next */
+ s_temp->n_length= *next_key; /* Needed by _mi_store_key */
next_key=0;
}
}
else
{
if (start != key)
- { /* Starts as prev key */
+ { /* Starts as prev key */
ref_length= (uint) (key-start);
s_temp->ref_length= ref_length + pack_marker;
length= (int) (key_length - ref_length);
@@ -1547,16 +1846,16 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
}
else
{
- s_temp->key_length+=s_temp->store_not_null; /* If null */
+ s_temp->key_length+=s_temp->store_not_null; /* If null */
length= key_length - length_pack+ diff_flag;
}
}
s_temp->totlength=(uint) length;
s_temp->prev_length=0;
DBUG_PRINT("test",("tot_length: %d length: %d uniq_key_length: %d",
- key_length,length,s_temp->key_length));
+ key_length,length,s_temp->key_length));
- /* If something after that hasn't length=0, test if we can combine */
+ /* If something after that hasn't length=0, test if we can combine */
if ((s_temp->next_key_pos=next_key))
{
uint packed,n_length;
@@ -1572,134 +1871,134 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
if (!packed)
n_length-= s_temp->store_not_null;
- if (n_length || packed) /* Don't pack 0 length keys */
+ if (n_length || packed) /* Don't pack 0 length keys */
{
uint next_length_pack, new_ref_length=s_temp->ref_length;
if (packed)
{
- /* If first key and next key is packed (only on delete) */
- if (!prev_key && org_key)
- {
- get_key_length(org_key_length,org_key);
- key=start;
- if (sort_order) /* SerG */
- {
- while (key < end && sort_order[*key] == sort_order[*org_key])
- {
- key++; org_key++;
- }
- }
- else
- {
- while (key < end && *key == *org_key)
- {
- key++; org_key++;
- }
- }
- if ((new_ref_length= (uint) (key - start)))
- new_ref_length+=pack_marker;
- }
-
- if (!n_length)
- {
- /*
- We put a different key between two identical variable length keys
- Extend next key to have same prefix as this key
- */
- if (new_ref_length) /* prefix of previus key */
- { /* make next key longer */
- s_temp->part_of_prev_key= new_ref_length;
- s_temp->prev_length= org_key_length -
- (new_ref_length-pack_marker);
- s_temp->n_ref_length= s_temp->n_length= s_temp->prev_length;
- n_length= get_pack_length(s_temp->prev_length);
- s_temp->prev_key+= (new_ref_length - pack_marker);
- length+= s_temp->prev_length + n_length;
- }
- else
- { /* Can't use prev key */
- s_temp->part_of_prev_key=0;
- s_temp->prev_length= org_key_length;
- s_temp->n_ref_length=s_temp->n_length= org_key_length;
- length+= org_key_length;
- /* +get_pack_length(org_key_length); */
- }
- return (int) length;
- }
-
- ref_length=n_length;
- get_key_pack_length(n_length,next_length_pack,next_key);
-
- /* Test if new keys has fewer characters that match the previous key */
- if (!new_ref_length)
- { /* Can't use prev key */
- s_temp->part_of_prev_key= 0;
- s_temp->prev_length= ref_length;
- s_temp->n_ref_length= s_temp->n_length= n_length+ref_length;
- /* s_temp->prev_key+= get_pack_length(org_key_length); */
- return (int) length+ref_length-next_length_pack;
- }
- if (ref_length+pack_marker > new_ref_length)
- {
- uint new_pack_length=new_ref_length-pack_marker;
- /* We must copy characters from the original key to the next key */
- s_temp->part_of_prev_key= new_ref_length;
- s_temp->prev_length= ref_length - new_pack_length;
- s_temp->n_ref_length=s_temp->n_length=n_length + s_temp->prev_length;
- s_temp->prev_key+= new_pack_length;
-/* +get_pack_length(org_key_length); */
- length= length-get_pack_length(ref_length)+
- get_pack_length(new_pack_length);
- return (int) length + s_temp->prev_length;
- }
+ /* If first key and next key is packed (only on delete) */
+ if (!prev_key && org_key)
+ {
+ get_key_length(org_key_length,org_key);
+ key=start;
+ if (sort_order) /* SerG */
+ {
+ while (key < end && sort_order[*key] == sort_order[*org_key])
+ {
+ key++; org_key++;
+ }
+ }
+ else
+ {
+ while (key < end && *key == *org_key)
+ {
+ key++; org_key++;
+ }
+ }
+ if ((new_ref_length= (uint) (key - start)))
+ new_ref_length+=pack_marker;
+ }
+
+ if (!n_length)
+ {
+ /*
+ We put a different key between two identical variable length keys
+ Extend next key to have same prefix as this key
+ */
+ if (new_ref_length) /* prefix of previus key */
+ { /* make next key longer */
+ s_temp->part_of_prev_key= new_ref_length;
+ s_temp->prev_length= org_key_length -
+ (new_ref_length-pack_marker);
+ s_temp->n_ref_length= s_temp->n_length= s_temp->prev_length;
+ n_length= get_pack_length(s_temp->prev_length);
+ s_temp->prev_key+= (new_ref_length - pack_marker);
+ length+= s_temp->prev_length + n_length;
+ }
+ else
+ { /* Can't use prev key */
+ s_temp->part_of_prev_key=0;
+ s_temp->prev_length= org_key_length;
+ s_temp->n_ref_length=s_temp->n_length= org_key_length;
+ length+= org_key_length;
+ /* +get_pack_length(org_key_length); */
+ }
+ return (int) length;
+ }
+
+ ref_length=n_length;
+ get_key_pack_length(n_length,next_length_pack,next_key);
+
+ /* Test if new keys has fewer characters that match the previous key */
+ if (!new_ref_length)
+ { /* Can't use prev key */
+ s_temp->part_of_prev_key= 0;
+ s_temp->prev_length= ref_length;
+ s_temp->n_ref_length= s_temp->n_length= n_length+ref_length;
+ /* s_temp->prev_key+= get_pack_length(org_key_length); */
+ return (int) length+ref_length-next_length_pack;
+ }
+ if (ref_length+pack_marker > new_ref_length)
+ {
+ uint new_pack_length=new_ref_length-pack_marker;
+ /* We must copy characters from the original key to the next key */
+ s_temp->part_of_prev_key= new_ref_length;
+ s_temp->prev_length= ref_length - new_pack_length;
+ s_temp->n_ref_length=s_temp->n_length=n_length + s_temp->prev_length;
+ s_temp->prev_key+= new_pack_length;
+/* +get_pack_length(org_key_length); */
+ length= length-get_pack_length(ref_length)+
+ get_pack_length(new_pack_length);
+ return (int) length + s_temp->prev_length;
+ }
}
else
{
- /* Next key wasn't a prefix of previous key */
- ref_length=0;
- next_length_pack=0;
+ /* Next key wasn't a prefix of previous key */
+ ref_length=0;
+ next_length_pack=0;
}
DBUG_PRINT("test",("length: %d next_key: %lx",length,next_key));
{
- uint tmp_length;
- key=(start+=ref_length);
- if (key+n_length < key_end) /* Normalize length based */
- key_end=key+n_length;
- if (sort_order) /* SerG */
- {
+ uint tmp_length;
+ key=(start+=ref_length);
+ if (key+n_length < key_end) /* Normalize length based */
+ key_end=key+n_length;
+ if (sort_order) /* SerG */
+ {
while (key < key_end && sort_order[*key] ==
- sort_order[*next_key])
- {
- key++; next_key++;
- }
- }
- else
- {
- while (key < key_end && *key == *next_key)
- {
- key++; next_key++;
- }
- }
- if (!(tmp_length=(uint) (key-start)))
- { /* Key can't be re-packed */
- s_temp->next_key_pos=0;
- return length;
- }
- ref_length+=tmp_length;
- n_length-=tmp_length;
- length-=tmp_length+next_length_pack; /* We gained these chars */
+ sort_order[*next_key])
+ {
+ key++; next_key++;
+ }
+ }
+ else
+ {
+ while (key < key_end && *key == *next_key)
+ {
+ key++; next_key++;
+ }
+ }
+ if (!(tmp_length=(uint) (key-start)))
+ { /* Key can't be re-packed */
+ s_temp->next_key_pos=0;
+ return length;
+ }
+ ref_length+=tmp_length;
+ n_length-=tmp_length;
+ length-=tmp_length+next_length_pack; /* We gained these chars */
}
if (n_length == 0)
{
- s_temp->n_ref_length=pack_marker; /* Same as prev key */
+ s_temp->n_ref_length=pack_marker; /* Same as prev key */
}
else
{
- s_temp->n_ref_length=ref_length | pack_marker;
- length+= get_pack_length(n_length);
- s_temp->n_length=n_length;
+ s_temp->n_ref_length=ref_length | pack_marker;
+ length+= get_pack_length(n_length);
+ s_temp->n_length=n_length;
}
}
}
@@ -1711,15 +2010,18 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
int
_mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
- uchar *org_key, uchar *prev_key, uchar *key,
- MI_KEY_PARAM *s_temp)
+ uchar *org_key, uchar *prev_key, uchar *key,
+ MI_KEY_PARAM *s_temp)
{
uint length,key_length,ref_length;
s_temp->totlength=key_length=_mi_keylength(keyinfo,key)+nod_flag;
+#ifdef HAVE_purify
+ s_temp->n_length= s_temp->n_ref_length=0; /* For valgrind */
+#endif
s_temp->key=key;
s_temp->prev_key=org_key;
- if (prev_key) /* If not first key in block */
+ if (prev_key) /* If not first key in block */
{
/* pack key against previous key */
/*
@@ -1738,7 +2040,7 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
s_temp->ref_length=ref_length=0;
length=key_length+1;
}
- if ((s_temp->next_key_pos=next_key)) /* If another key after */
+ if ((s_temp->next_key_pos=next_key)) /* If another key after */
{
/* pack key against next key */
uint next_length,next_length_pack;
@@ -1749,21 +2051,21 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
{
uchar *end;
for (key= s_temp->key, end=key+next_length ;
- *key == *org_key && key < end;
- key++,org_key++) ;
+ *key == *org_key && key < end;
+ key++,org_key++) ;
ref_length= (uint) (key - s_temp->key);
}
if (next_length > ref_length)
{
/* We put a key with different case between two keys with the same prefix
- Extend next key to have same prefix as
- this key */
+ Extend next key to have same prefix as
+ this key */
s_temp->n_ref_length= ref_length;
s_temp->prev_length= next_length-ref_length;
s_temp->prev_key+= ref_length;
return (int) (length+ s_temp->prev_length - next_length_pack +
- get_pack_length(ref_length));
+ get_pack_length(ref_length));
}
/* Check how many characters are identical to next key */
key= s_temp->key+next_length;
@@ -1771,12 +2073,12 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
if ((ref_length= (uint) (key - s_temp->key)-1) == next_length)
{
s_temp->next_key_pos=0;
- return length; /* can't pack next key */
+ return length; /* can't pack next key */
}
s_temp->prev_length=0;
s_temp->n_ref_length=ref_length;
return (int) (length-(ref_length - next_length) - next_length_pack +
- get_pack_length(ref_length));
+ get_pack_length(ref_length));
}
return (int) length;
}
@@ -1789,8 +2091,8 @@ _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
/* store key without compression */
void _mi_store_static_key(MI_KEYDEF *keyinfo __attribute__((unused)),
- register uchar *key_pos,
- register MI_KEY_PARAM *s_temp)
+ register uchar *key_pos,
+ register MI_KEY_PARAM *s_temp)
{
memcpy((byte*) key_pos,(byte*) s_temp->key,(size_t) s_temp->totlength);
}
@@ -1804,8 +2106,8 @@ void _mi_store_static_key(MI_KEYDEF *keyinfo __attribute__((unused)),
void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
- register uchar *key_pos,
- register MI_KEY_PARAM *s_temp)
+ register uchar *key_pos,
+ register MI_KEY_PARAM *s_temp)
{
uint length;
uchar *start;
@@ -1826,9 +2128,9 @@ void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->key_length);
}
bmove((byte*) key_pos,(byte*) s_temp->key,
- (length=s_temp->totlength-(uint) (key_pos-start)));
+ (length=s_temp->totlength-(uint) (key_pos-start)));
- if (!s_temp->next_key_pos) /* No following key */
+ if (!s_temp->next_key_pos) /* No following key */
return;
key_pos+=length;
@@ -1838,14 +2140,14 @@ void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
if (s_temp->part_of_prev_key)
{
store_pack_length(s_temp->pack_marker == 128,key_pos,
- s_temp->part_of_prev_key);
+ s_temp->part_of_prev_key);
store_key_length_inc(key_pos,s_temp->n_length);
}
else
{
s_temp->n_length+= s_temp->store_not_null;
store_pack_length(s_temp->pack_marker == 128,key_pos,
- s_temp->n_length);
+ s_temp->n_length);
}
memcpy(key_pos, s_temp->prev_key, s_temp->prev_length);
}
@@ -1853,7 +2155,7 @@ void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
{
store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->n_ref_length);
if (s_temp->n_ref_length == s_temp->pack_marker)
- return; /* Identical key */
+ return; /* Identical key */
store_key_length(key_pos,s_temp->n_length);
}
else
@@ -1867,18 +2169,18 @@ void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
/* variable length key with prefix compression */
void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
- register uchar *key_pos,
- register MI_KEY_PARAM *s_temp)
+ register uchar *key_pos,
+ register MI_KEY_PARAM *s_temp)
{
store_key_length_inc(key_pos,s_temp->ref_length);
memcpy((char*) key_pos,(char*) s_temp->key+s_temp->ref_length,
- (size_t) s_temp->totlength-s_temp->ref_length);
+ (size_t) s_temp->totlength-s_temp->ref_length);
if (s_temp->next_key_pos)
{
key_pos+=(uint) (s_temp->totlength-s_temp->ref_length);
store_key_length_inc(key_pos,s_temp->n_ref_length);
- if (s_temp->prev_length) /* If we must extend key */
+ if (s_temp->prev_length) /* If we must extend key */
{
memcpy(key_pos,s_temp->prev_key,s_temp->prev_length);
}
diff --git a/myisam/mi_static.c b/myisam/mi_static.c
index f790f90ca78..37b9ac04b7a 100644
--- a/myisam/mi_static.c
+++ b/myisam/mi_static.c
@@ -1,21 +1,21 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
- Static variables for pisam library. All definied here for easy making of
+ Static variables for MyISAM library. All definied here for easy making of
a shared library
*/
@@ -32,7 +32,7 @@ my_string myisam_log_filename=(char*) "myisam.log";
File myisam_log_file= -1;
uint myisam_quick_table_bits=9;
uint myisam_block_size=MI_KEY_BLOCK_LENGTH; /* Best by test */
-my_bool myisam_flush=0,myisam_delay_key_write=0;
+my_bool myisam_flush=0, myisam_delay_key_write=0, myisam_single_user=0;
#if defined(THREAD) && !defined(DONT_USE_RW_LOCKS)
my_bool myisam_concurrent_insert=1;
#else
@@ -40,10 +40,12 @@ my_bool myisam_concurrent_insert=0;
#endif
my_off_t myisam_max_extra_temp_length= MI_MAX_TEMP_LENGTH;
my_off_t myisam_max_temp_length= MAX_FILE_SIZE;
+ulong myisam_bulk_insert_tree_size=8192*1024;
-
-/* read_vec[] is used for converting between P_READ_KEY.. and SEARCH_ */
-/* Position is , == , >= , <= , > , < */
+/*
+ read_vec[] is used for converting between P_READ_KEY.. and SEARCH_
+ Position is , == , >= , <= , > , <
+*/
uint NEAR myisam_read_vec[]=
{
diff --git a/myisam/mi_statrec.c b/myisam/mi_statrec.c
index 05ff40d8921..9afebce2ae6 100644
--- a/myisam/mi_statrec.c
+++ b/myisam/mi_statrec.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -27,17 +27,16 @@ int _mi_write_static_record(MI_INFO *info, const byte *record)
{
my_off_t filepos=info->s->state.dellink;
info->rec_cache.seek_not_done=1; /* We have done a seek */
- VOID(my_seek(info->dfile,info->s->state.dellink+1,MY_SEEK_SET,MYF(0)));
-
- if (my_read(info->dfile,(char*) &temp[0],info->s->base.rec_reflength,
- MYF(MY_NABP)))
+ if (my_pread(info->dfile,(char*) &temp[0],info->s->base.rec_reflength,
+ info->s->state.dellink+1,
+ MYF(MY_NABP)))
goto err;
info->s->state.dellink= _mi_rec_pos(info->s,temp);
info->state->del--;
info->state->empty-=info->s->base.pack_reclength;
- VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0)));
- if (my_write(info->dfile, (char*) record, info->s->base.reclength,
- MYF(MY_NABP)))
+ if (my_pwrite(info->dfile, (char*) record, info->s->base.reclength,
+ filepos,
+ MYF(MY_NABP)))
goto err;
}
else
@@ -64,16 +63,18 @@ int _mi_write_static_record(MI_INFO *info, const byte *record)
else
{
info->rec_cache.seek_not_done=1; /* We have done a seek */
- VOID(my_seek(info->dfile,info->state->data_file_length,
- MY_SEEK_SET,MYF(0)));
- if (my_write(info->dfile,(char*) record,info->s->base.reclength,
- info->s->write_flag))
+ if (my_pwrite(info->dfile,(char*) record,info->s->base.reclength,
+ info->state->data_file_length,
+ info->s->write_flag))
goto err;
if (info->s->base.pack_reclength != info->s->base.reclength)
{
uint length=info->s->base.pack_reclength - info->s->base.reclength;
bzero((char*) temp,length);
- if (my_write(info->dfile, (byte*) temp,length, info->s->write_flag))
+ if (my_pwrite(info->dfile, (byte*) temp,length,
+ info->state->data_file_length+
+ info->s->base.reclength,
+ info->s->write_flag))
goto err;
}
}
@@ -88,9 +89,10 @@ int _mi_write_static_record(MI_INFO *info, const byte *record)
int _mi_update_static_record(MI_INFO *info, my_off_t pos, const byte *record)
{
info->rec_cache.seek_not_done=1; /* We have done a seek */
- VOID(my_seek(info->dfile,pos,MY_SEEK_SET,MYF(0)));
- return (my_write(info->dfile,(char*) record,info->s->base.reclength,
- MYF(MY_NABP)) != 0);
+ return (my_pwrite(info->dfile,
+ (char*) record,info->s->base.reclength,
+ pos,
+ MYF(MY_NABP)) != 0);
}
@@ -104,9 +106,8 @@ int _mi_delete_static_record(MI_INFO *info)
_mi_dpointer(info,temp+1,info->s->state.dellink);
info->s->state.dellink = info->lastpos;
info->rec_cache.seek_not_done=1;
- VOID(my_seek(info->dfile,info->lastpos,MY_SEEK_SET,MYF(0)));
- return (my_write(info->dfile,(byte*) temp, 1+info->s->rec_reflength,
- MYF(MY_NABP)) != 0);
+ return (my_pwrite(info->dfile,(byte*) temp, 1+info->s->rec_reflength,
+ info->lastpos, MYF(MY_NABP)) != 0);
}
@@ -129,9 +130,9 @@ int _mi_cmp_static_record(register MI_INFO *info, register const byte *old)
if ((info->opt_flag & READ_CHECK_USED))
{ /* If check isn't disabled */
info->rec_cache.seek_not_done=1; /* We have done a seek */
- VOID(my_seek(info->dfile,info->lastpos,MY_SEEK_SET,MYF(0)));
- if (my_read(info->dfile, (char*) info->rec_buff, info->s->base.reclength,
- MYF(MY_NABP)))
+ if (my_pread(info->dfile, (char*) info->rec_buff, info->s->base.reclength,
+ info->lastpos,
+ MYF(MY_NABP)))
DBUG_RETURN(-1);
if (memcmp((byte*) info->rec_buff, (byte*) old,
(uint) info->s->base.reclength))
@@ -152,9 +153,8 @@ int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def,
DBUG_ENTER("_mi_cmp_static_unique");
info->rec_cache.seek_not_done=1; /* We have done a seek */
- VOID(my_seek(info->dfile,pos,MY_SEEK_SET,MYF(0)));
- if (my_read(info->dfile, (char*) info->rec_buff, info->s->base.reclength,
- MYF(MY_NABP)))
+ if (my_pread(info->dfile, (char*) info->rec_buff, info->s->base.reclength,
+ pos, MYF(MY_NABP)))
DBUG_RETURN(-1);
DBUG_RETURN(mi_unique_comp(def, record, info->rec_buff,
def->null_are_equal));
@@ -181,8 +181,7 @@ int _mi_read_static_record(register MI_INFO *info, register my_off_t pos,
error=my_pread(info->dfile,(char*) record,info->s->base.reclength,
pos,MYF(MY_NABP)) != 0;
- if (info->s->r_locks == 0 && info->s->w_locks == 0)
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
if (! error)
{
if (!*record)
@@ -195,7 +194,7 @@ int _mi_read_static_record(register MI_INFO *info, register my_off_t pos,
}
return(-1); /* Error on read */
}
- VOID(_mi_writeinfo(info,0)); /* No such record */
+ fast_mi_writeinfo(info); /* No such record */
return(-1);
}
@@ -222,7 +221,7 @@ int _mi_read_rnd_static_record(MI_INFO *info, byte *buf,
(skipp_deleted_blocks || !filepos))
{
cache_read=1; /* Read record using cache */
- cache_length=(uint) (info->rec_cache.rc_end - info->rec_cache.rc_pos);
+ cache_length=(uint) (info->rec_cache.read_end - info->rec_cache.read_pos);
}
else
info->rec_cache.seek_not_done=1; /* Filepos is changed */
@@ -240,7 +239,7 @@ int _mi_read_rnd_static_record(MI_INFO *info, byte *buf,
{ /* We don't nead new info */
#ifndef UNSAFE_LOCKING
if ((! cache_read || share->base.reclength > cache_length) &&
- share->r_locks == 0 && share->w_locks == 0)
+ share->tot_locks == 0)
{ /* record not in cache */
if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
MYF(MY_SEEK_NOT_DONE) | info->lock_wait))
@@ -257,7 +256,7 @@ int _mi_read_rnd_static_record(MI_INFO *info, byte *buf,
DBUG_PRINT("test",("filepos: %ld (%ld) records: %ld del: %ld",
filepos/share->base.reclength,filepos,
info->state->records, info->state->del));
- VOID(_mi_writeinfo(info,0));
+ fast_mi_writeinfo(info);
DBUG_RETURN(my_errno=HA_ERR_END_OF_FILE);
}
info->lastpos= filepos;
diff --git a/myisam/mi_test1.c b/myisam/mi_test1.c
index ae09bd4142e..8ea97c8e489 100644
--- a/myisam/mi_test1.c
+++ b/myisam/mi_test1.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -17,20 +17,23 @@
/* Testing of the basic functions of a MyISAM table */
#include "myisam.h"
-#include <getopt.h>
+#include <my_getopt.h>
#include <m_string.h>
#define MAX_REC_LENGTH 1024
-static int rec_pointer_size=0,verbose=0,flags[50];
-static int key_field=FIELD_SKIPP_PRESPACE,extra_field=FIELD_SKIPP_ENDSPACE;
+static void usage();
+
+static int rec_pointer_size=0, flags[50];
+static int key_field=FIELD_SKIP_PRESPACE,extra_field=FIELD_SKIP_ENDSPACE;
static int key_type=HA_KEYTYPE_NUM;
static int create_flag=0;
-static uint insert_count= 1000,update_count=1000,remove_count=1000;
-static uint pack_keys=0,pack_seg=0,null_fields=0,key_length=6,skip_update=0;
-static uint unique_key=HA_NOSAME,key_cacheing=0,opt_unique=0;
-static uint silent;
+static uint insert_count, update_count, remove_count;
+static uint pack_keys=0, pack_seg=0, key_length;
+static uint unique_key=HA_NOSAME;
+static my_bool key_cacheing, null_fields, silent, skip_update, opt_unique,
+ verbose;
static MI_COLUMNDEF recinfo[4];
static MI_KEYDEF keyinfo[10];
static MI_KEYSEG keyseg[10];
@@ -47,14 +50,14 @@ int main(int argc,char *argv[])
MY_INIT(argv[0]);
my_init();
if (key_cacheing)
- init_key_cache(IO_SIZE*16,(uint) IO_SIZE*4*10);
+ init_key_cache(IO_SIZE*16);
get_options(argc,argv);
exit(run_test("test1"));
}
-int run_test(const char *filename)
+static int run_test(const char *filename)
{
MI_INFO *file;
int i,j,error,deleted,rec_length,uniques=0;
@@ -501,139 +504,155 @@ static void update_record(char *record)
}
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"checksum", no_argument, 0, 'c'},
+ {"checksum", 'c', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", required_argument, 0, '#'},
+ {"debug", '#', "Undocumented",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"delete_rows", required_argument, 0, 'd'},
- {"help", no_argument, 0, '?'},
- {"insert_rows", required_argument, 0, 'i'},
- {"key_alpha", no_argument, 0, 'a'},
- {"key_binary_pack", no_argument, 0, 'B'},
- {"key_blob", required_argument, 0, 'b'},
- {"key_cache", no_argument, 0, 'K'},
- {"key_length", required_argument, 0, 'k'},
- {"key_multiple", no_argument, 0, 'm'},
- {"key_prefix_pack", no_argument, 0, 'P'},
- {"key_space_pack", no_argument, 0, 'p'},
- {"key_varchar", no_argument, 0, 'w'},
- {"null_fields", no_argument, 0, 'N'},
- {"row_fixed_size", no_argument, 0, 'S'},
- {"row_pointer_size", required_argument, 0, 'R'},
- {"silent", no_argument, 0, 's'},
- {"skip_update", no_argument, 0, 'U'},
- {"unique", no_argument, 0, 'C'},
- {"update_rows", required_argument, 0, 'u'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
+ {"delete_rows", 'd', "Undocumented", (gptr*) &remove_count,
+ (gptr*) &remove_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
+ {"help", '?', "Display help and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"insert_rows", 'i', "Undocumented", (gptr*) &insert_count,
+ (gptr*) &insert_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
+ {"key_alpha", 'a', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_binary_pack", 'B', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_blob", 'b', "Undocumented",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_cache", 'K', "Undocumented", (gptr*) &key_cacheing,
+ (gptr*) &key_cacheing, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_length", 'k', "Undocumented", (gptr*) &key_length, (gptr*) &key_length,
+ 0, GET_UINT, REQUIRED_ARG, 6, 0, 0, 0, 0, 0},
+ {"key_multiple", 'm', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_prefix_pack", 'P', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_space_pack", 'p', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"key_varchar", 'w', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"null_fields", 'N', "Undocumented",
+ (gptr*) &null_fields, (gptr*) &null_fields, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"row_fixed_size", 'S', "Undocumented",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"row_pointer_size", 'R', "Undocumented", (gptr*) &rec_pointer_size,
+ (gptr*) &rec_pointer_size, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Undocumented",
+ (gptr*) &silent, (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip_update", 'U', "Undocumented", (gptr*) &skip_update,
+ (gptr*) &skip_update, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"unique", 'C', "Undocumented", (gptr*) &opt_unique, (gptr*) &opt_unique, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"update_rows", 'u', "Undocumented", (gptr*) &update_count,
+ (gptr*) &update_count, 0, GET_UINT, REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Be more verbose", (gptr*) &verbose, (gptr*) &verbose, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Print version number and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case 'a':
+ key_type= HA_KEYTYPE_TEXT;
+ break;
+ case 'c':
+ create_flag|= HA_CREATE_CHECKSUM;
+ break;
+ case 'R': /* Length of record pointer */
+ if (rec_pointer_size > 3)
+ rec_pointer_size=0;
+ break;
+ case 'P':
+ pack_keys= HA_PACK_KEY; /* Use prefix compression */
+ break;
+ case 'B':
+ pack_keys= HA_BINARY_PACK_KEY; /* Use binary compression */
+ break;
+ case 'S':
+ if (key_field == FIELD_VARCHAR)
+ {
+ create_flag=0; /* Static sized varchar */
+ }
+ else if (key_field != FIELD_BLOB)
+ {
+ key_field=FIELD_NORMAL; /* static-size record */
+ extra_field=FIELD_NORMAL;
+ }
+ break;
+ case 'p':
+ pack_keys=HA_PACK_KEY; /* Use prefix + space packing */
+ pack_seg=HA_SPACE_PACK;
+ key_type=HA_KEYTYPE_TEXT;
+ break;
+ case 'm':
+ unique_key=0;
+ break;
+ case 'b':
+ key_field=FIELD_BLOB; /* blob key */
+ extra_field= FIELD_BLOB;
+ pack_seg|= HA_BLOB_PART;
+ key_type= HA_KEYTYPE_VARTEXT;
+ break;
+ case 'k':
+ if (key_length < 4 || key_length > MI_MAX_KEY_LENGTH)
+ {
+ fprintf(stderr,"Wrong key length\n");
+ exit(1);
+ }
+ break;
+ case 'w':
+ key_field=FIELD_VARCHAR; /* varchar keys */
+ extra_field= FIELD_VARCHAR;
+ key_type= HA_KEYTYPE_VARTEXT;
+ pack_seg|= HA_VAR_LENGTH;
+ create_flag|= HA_PACK_RECORD;
+ break;
+ case 'K': /* Use key cacheing */
+ key_cacheing=1;
+ break;
+ case 'V':
+ printf("test1 Ver 1.2 \n");
+ exit(0);
+ case '#':
+ DEBUGGER_ON;
+ DBUG_PUSH (argument);
+ break;
+ case '?':
+ usage();
+ exit(1);
+ }
+ return 0;
+}
+
+
/* Read options */
-static void get_options(int argc,char *argv[])
+static void get_options(int argc, char *argv[])
{
- int c,option_index=0;
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
- while ((c=getopt_long(argc,argv,"abBcCd:i:k:KmPR:SspNu:UvVw#:",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'a':
- key_type= HA_KEYTYPE_TEXT;
- break;
- case 'c':
- create_flag|= HA_CREATE_CHECKSUM;
- break;
- case 'C':
- opt_unique=1;
- break;
- case 'R': /* Length of record pointer */
- rec_pointer_size=atoi(optarg);
- if (rec_pointer_size > 3)
- rec_pointer_size=0;
- break;
- case 'P':
- pack_keys= HA_PACK_KEY; /* Use prefix compression */
- break;
- case 'B':
- pack_keys= HA_BINARY_PACK_KEY; /* Use binary compression */
- break;
- case 'S':
- if (key_field == FIELD_VARCHAR)
- {
- create_flag=0; /* Static sized varchar */
- }
- else if (key_field != FIELD_BLOB)
- {
- key_field=FIELD_NORMAL; /* static-size record */
- extra_field=FIELD_NORMAL;
- }
- break;
- case 'p':
- pack_keys=HA_PACK_KEY; /* Use prefix + space packing */
- pack_seg=HA_SPACE_PACK;
- key_type=HA_KEYTYPE_TEXT;
- break;
- case 'N':
- null_fields=1; /* First key part may be null */
- break;
- case 'v': /* verbose */
- verbose=1;
- break;
- case 'd':
- remove_count=atoi(optarg);
- break;
- case 'i':
- insert_count=atoi(optarg);
- break;
- case 'u':
- update_count=atoi(optarg);
- break;
- case 'U':
- skip_update=1;
- break;
- case 'm':
- unique_key=0;
- break;
- case 'b':
- key_field=FIELD_BLOB; /* blob key */
- extra_field= FIELD_BLOB;
- pack_seg|= HA_BLOB_PART;
- key_type= HA_KEYTYPE_VARTEXT;
- break;
- case 'k':
- key_length=atoi(optarg);
- if (key_length < 4 || key_length > MI_MAX_KEY_LENGTH)
- {
- fprintf(stderr,"Wrong key length\n");
- exit(1);
- }
- break;
- case 's':
- silent=1;
- break;
- case 'w':
- key_field=FIELD_VARCHAR; /* varchar keys */
- extra_field= FIELD_VARCHAR;
- key_type= HA_KEYTYPE_VARTEXT;
- pack_seg|= HA_VAR_LENGTH;
- create_flag|= HA_PACK_RECORD;
- break;
- case 'K': /* Use key cacheing */
- key_cacheing=1;
- break;
- case 'V':
- printf("test1 Ver 1.0 \n");
- exit(0);
- case '#':
- DEBUGGER_ON;
- DBUG_PUSH (optarg);
- break;
- }
- }
return;
} /* get options */
+
+
+static void usage()
+{
+ printf("Usage: %s [options]\n\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
diff --git a/myisam/mi_test2.c b/myisam/mi_test2.c
index b66b02afdf9..11253f1fdee 100644
--- a/myisam/mi_test2.c
+++ b/myisam/mi_test2.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -148,15 +148,15 @@ int main(int argc, char *argv[])
keyinfo[5].keysegs=1;
keyinfo[5].flag = pack_type;
- recinfo[0].type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[0].length=7;
recinfo[0].null_bit=0;
recinfo[0].null_pos=0;
- recinfo[1].type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[1].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[1].length=5;
recinfo[1].null_bit=0;
recinfo[1].null_pos=0;
- recinfo[2].type=pack_fields ? FIELD_SKIPP_PRESPACE : 0;
+ recinfo[2].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[2].length=9;
recinfo[2].null_bit=0;
recinfo[2].null_pos=0;
@@ -164,11 +164,11 @@ int main(int argc, char *argv[])
recinfo[3].length=STANDARD_LENGTH-7-5-9-4;
recinfo[3].null_bit=0;
recinfo[3].null_pos=0;
- recinfo[4].type=pack_fields ? FIELD_SKIPP_ZERO : 0;
+ recinfo[4].type=pack_fields ? FIELD_SKIP_ZERO : 0;
recinfo[4].length=4;
recinfo[4].null_bit=0;
recinfo[4].null_pos=0;
- recinfo[5].type=pack_fields ? FIELD_SKIPP_ENDSPACE : 0;
+ recinfo[5].type=pack_fields ? FIELD_SKIP_ENDSPACE : 0;
recinfo[5].length=60;
recinfo[5].null_bit=0;
recinfo[5].null_pos=0;
@@ -208,13 +208,13 @@ int main(int argc, char *argv[])
if (!silent)
printf("- Writing key:s\n");
if (key_cacheing)
- init_key_cache(key_cache_size,(uint) IO_SIZE*4*10); /* Use a small cache */
+ init_key_cache(key_cache_size); /* Use a small cache */
if (locking)
mi_lock_database(file,F_WRLCK);
if (write_cacheing)
- mi_extra(file,HA_EXTRA_WRITE_CACHE);
+ mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
if (opt_quick_mode)
- mi_extra(file,HA_EXTRA_QUICK);
+ mi_extra(file,HA_EXTRA_QUICK,0);
for (i=0 ; i < recant ; i++)
{
@@ -261,11 +261,15 @@ int main(int argc, char *argv[])
if (testflag==1) goto end;
if (write_cacheing)
- if (mi_extra(file,HA_EXTRA_NO_CACHE))
+ {
+ if (mi_extra(file,HA_EXTRA_NO_CACHE,0))
{
puts("got error from mi_extra(HA_EXTRA_NO_CACHE)");
goto end;
}
+ }
+ if (key_cacheing)
+ resize_key_cache(key_cache_size*2);
if (!silent)
printf("- Delete\n");
@@ -325,12 +329,12 @@ int main(int argc, char *argv[])
{
if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
{
- printf("error: %d; can't uppdate:\nFrom: \"%s\"\nTo: \"%s\"\n",
+ printf("error: %d; can't update:\nFrom: \"%s\"\nTo: \"%s\"\n",
my_errno,read_record,record2);
goto err;
}
if (verbose)
- printf("Double key when tryed to uppdate:\nFrom: \"%s\"\nTo: \"%s\"\n",record,record2);
+ printf("Double key when tried to update:\nFrom: \"%s\"\nTo: \"%s\"\n",record,record2);
}
else
{
@@ -341,70 +345,81 @@ int main(int argc, char *argv[])
}
}
}
- if (testflag==3) goto end;
+ if (testflag == 3)
+ goto end;
- if (!silent)
- printf("- Same key: first - next -> last - prev -> first\n");
- DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
for (i=999, dupp_keys=j=0 ; i>0 ; i--)
{
- if (key1[i] >dupp_keys) { dupp_keys=key1[i]; j=i; }
+ if (key1[i] > dupp_keys)
+ {
+ dupp_keys=key1[i]; j=i;
+ }
}
sprintf(key,"%6d",j);
- if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys);
- if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) goto err;
- if (mi_rsame(file,read_record2,-1)) goto err;
- if (memcmp(read_record,read_record2,reclength) != 0)
- {
- printf("mi_rsame didn't find same record\n");
- goto end;
- }
- info.recpos=mi_position(file);
- if (mi_rfirst(file,read_record2,0) ||
- mi_rsame_with_pos(file,read_record2,0,info.recpos) ||
- memcmp(read_record,read_record2,reclength) != 0)
+ start=keyinfo[0].seg[0].start;
+ length=keyinfo[0].seg[0].length;
+ if (dupp_keys)
{
- printf("mi_rsame_with_pos didn't find same record\n");
- goto end;
- }
- {
- int skr=mi_rnext(file,read_record2,0);
- if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
- mi_rprev(file,read_record2,-1) ||
+ if (!silent)
+ printf("- Same key: first - next -> last - prev -> first\n");
+ DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
+ if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys);
+
+ if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
+ goto err;
+ if (mi_rsame(file,read_record2,-1))
+ goto err;
+ if (memcmp(read_record,read_record2,reclength) != 0)
+ {
+ printf("mi_rsame didn't find same record\n");
+ goto end;
+ }
+ info.recpos=mi_position(file);
+ if (mi_rfirst(file,read_record2,0) ||
+ mi_rsame_with_pos(file,read_record2,0,info.recpos) ||
memcmp(read_record,read_record2,reclength) != 0)
{
- printf("mi_rsame_with_pos lost position\n");
+ printf("mi_rsame_with_pos didn't find same record\n");
+ goto end;
+ }
+ {
+ int skr=mi_rnext(file,read_record2,0);
+ if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
+ mi_rprev(file,read_record2,-1) ||
+ memcmp(read_record,read_record2,reclength) != 0)
+ {
+ printf("mi_rsame_with_pos lost position\n");
+ goto end;
+ }
+ }
+ ant=1;
+ while (mi_rnext(file,read_record2,0) == 0 &&
+ memcmp(read_record2+start,key,length) == 0) ant++;
+ if (ant != dupp_keys)
+ {
+ printf("next: Found: %d keys of %d\n",ant,dupp_keys);
+ goto end;
+ }
+ ant=0;
+ while (mi_rprev(file,read_record3,0) == 0 &&
+ bcmp(read_record3+start,key,length) == 0) ant++;
+ if (ant != dupp_keys)
+ {
+ printf("prev: Found: %d records of %d\n",ant,dupp_keys);
goto end;
}
- }
- ant=1;
- start=keyinfo[0].seg[0].start; length=keyinfo[0].seg[0].length;
- while (mi_rnext(file,read_record2,0) == 0 &&
- memcmp(read_record2+start,key,length) == 0) ant++;
- if (ant != dupp_keys)
- {
- printf("next: Found: %d keys of %d\n",ant,dupp_keys);
- goto end;
- }
- ant=0;
- while (mi_rprev(file,read_record3,0) == 0 &&
- bcmp(read_record3+start,key,length) == 0) ant++;
- if (ant != dupp_keys)
- {
- printf("prev: Found: %d records of %d\n",ant,dupp_keys);
- goto end;
- }
- /* Check of mi_rnext_same */
- if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
- goto err;
- ant=1;
- while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10)
- ant++;
- if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE)
- {
- printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys);
- goto end;
+ /* Check of mi_rnext_same */
+ if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
+ goto err;
+ ant=1;
+ while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10)
+ ant++;
+ if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE)
+ {
+ printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys);
+ goto end;
+ }
}
if (!silent)
@@ -624,14 +639,14 @@ int main(int argc, char *argv[])
if ((long) range_records < (long) records*7/10-2 ||
(long) range_records > (long) records*14/10+2)
{
- printf("mi_records_range for key: %d returned %ld; Should be about %ld\n",
- i, range_records, records);
+ printf("mi_records_range for key: %d returned %lu; Should be about %lu\n",
+ i, (ulong) range_records, (ulong) records);
goto end;
}
if (verbose && records)
{
- printf("mi_records_range returned %ld; Exact is %ld (diff: %4.2g %%)\n",
- range_records,records,
+ printf("mi_records_range returned %lu; Exact is %lu (diff: %4.2g %%)\n",
+ (ulong) range_records, (ulong) records,
labs((long) range_records-(long) records)*100.0/records);
}
@@ -645,8 +660,8 @@ int main(int argc, char *argv[])
|| info.keys != keys)
{
puts("Wrong info from mi_info");
- printf("Got: records: %ld delete: %ld i_keys: %d\n",
- info.records,info.deleted,info.keys);
+ printf("Got: records: %lu delete: %lu i_keys: %d\n",
+ (ulong) info.records, (ulong) info.deleted, info.keys);
}
if (verbose)
{
@@ -666,7 +681,7 @@ int main(int argc, char *argv[])
if (!silent)
printf("- mi_extra(CACHE) + mi_rrnd.... + mi_extra(NO_CACHE)\n");
- if (mi_extra(file,HA_EXTRA_RESET) || mi_extra(file,HA_EXTRA_CACHE))
+ if (mi_extra(file,HA_EXTRA_RESET,0) || mi_extra(file,HA_EXTRA_CACHE,0))
{
if (locking || (!use_blob && !pack_fields))
{
@@ -684,7 +699,7 @@ int main(int argc, char *argv[])
ant,write_count-opt_delete);
goto end;
}
- if (mi_extra(file,HA_EXTRA_NO_CACHE))
+ if (mi_extra(file,HA_EXTRA_NO_CACHE,0))
{
puts("got error from mi_extra(HA_EXTRA_NO_CACHE)");
goto end;
@@ -709,7 +724,7 @@ int main(int argc, char *argv[])
DBUG_PRINT("progpos",("Removing keys"));
lastpos = HA_OFFSET_ERROR;
/* DBUG_POP(); */
- mi_extra(file,HA_EXTRA_RESET);
+ mi_extra(file,HA_EXTRA_RESET,0);
found_parts=0;
while ((error=mi_rrnd(file,read_record,HA_OFFSET_ERROR)) !=
HA_ERR_END_OF_FILE)
@@ -776,9 +791,15 @@ end:
printf("\nFollowing test have been made:\n");
printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete);
if (rec_pointer_size)
- printf("Record pointer size: %d\n",rec_pointer_size);
+ printf("Record pointer size: %d\n",rec_pointer_size);
+ printf("myisam_block_size: %u\n", myisam_block_size);
if (key_cacheing)
- puts("Key cacheing used");
+ {
+ puts("Key cache used");
+ printf("key_cache_block_size: %u\n", key_cache_block_size);
+ if (write_cacheing)
+ puts("Key cache resized");
+ }
if (write_cacheing)
puts("Write cacheing used");
if (write_cacheing)
@@ -801,7 +822,7 @@ reads: %10lu\n",
end_key_cache();
if (blob_buffer)
my_free(blob_buffer,MYF(0));
- my_end(MY_CHECK_ERROR | MY_GIVE_INFO);
+ my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO);
return(0);
err:
printf("got error: %d when using MyISAM-database\n",my_errno);
@@ -861,7 +882,29 @@ static void get_options(int argc, char **argv)
verbose=1;
break;
case 'm': /* records */
- recant=atoi(++pos);
+ if ((recant=atoi(++pos)) < 10)
+ {
+ fprintf(stderr,"record count must be >= 10\n");
+ exit(1);
+ }
+ break;
+ case 'e': /* myisam_block_length */
+ if ((myisam_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
+ myisam_block_size > MI_MAX_KEY_BLOCK_LENGTH)
+ {
+ fprintf(stderr,"Wrong myisam_block_length\n");
+ exit(1);
+ }
+ myisam_block_size=1 << my_bit_log2(myisam_block_size);
+ break;
+ case 'E': /* myisam_block_length */
+ if ((key_cache_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
+ key_cache_block_size > MI_MAX_KEY_BLOCK_LENGTH)
+ {
+ fprintf(stderr,"Wrong key_cache_block_size\n");
+ exit(1);
+ }
+ key_cache_block_size=1 << my_bit_log2(key_cache_block_size);
break;
case 'f':
if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS)
@@ -904,7 +947,7 @@ static void get_options(int argc, char **argv)
case 'V':
printf("%s Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
puts("By Monty, for your professional use\n");
- printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-t#]\n",
+ printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-e#] [-E#] [-t#]\n",
progname);
exit(0);
case '#':
diff --git a/myisam/mi_test3.c b/myisam/mi_test3.c
index 48325b2dcac..6111167b38f 100644
--- a/myisam/mi_test3.c
+++ b/myisam/mi_test3.c
@@ -1,21 +1,23 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Test av locking */
+#ifndef __NETWARE__
+
#include "myisam.h"
#include <sys/types.h>
#ifdef HAVE_SYS_WAIT_H
@@ -173,7 +175,7 @@ void start_test(int id)
exit(1);
}
if (key_cacheing && rnd(2) == 0)
- init_key_cache(65536L,(uint) IO_SIZE*4*10);
+ init_key_cache(65536L);
printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)
@@ -302,7 +304,7 @@ int test_rrnd(MI_INFO *file,int id)
return 1;
}
if (rnd(2) == 0)
- mi_extra(file,HA_EXTRA_CACHE);
+ mi_extra(file,HA_EXTRA_CACHE,0);
}
count=0;
@@ -323,7 +325,7 @@ int test_rrnd(MI_INFO *file,int id)
end:
if (lock)
{
- mi_extra(file,HA_EXTRA_NO_CACHE);
+ mi_extra(file,HA_EXTRA_NO_CACHE,0);
if (mi_lock_database(file,F_UNLCK))
{
fprintf(stderr,"%2d: Can't unlock table\n",id);
@@ -355,7 +357,7 @@ int test_write(MI_INFO *file,int id,int lock_type)
return 1;
}
if (rnd(2) == 0)
- mi_extra(file,HA_EXTRA_WRITE_CACHE);
+ mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
}
sprintf(record.id,"%7d",getpid());
@@ -380,7 +382,7 @@ int test_write(MI_INFO *file,int id,int lock_type)
}
if (lock)
{
- mi_extra(file,HA_EXTRA_NO_CACHE);
+ mi_extra(file,HA_EXTRA_NO_CACHE,0);
if (mi_lock_database(file,F_UNLCK))
{
fprintf(stderr,"%2d: Can't unlock table\n",id);
@@ -483,3 +485,15 @@ int test_update(MI_INFO *file,int id,int lock_type)
printf("%2d: update: %5d\n",id,update); fflush(stdout);
return 0;
}
+
+#else /* __NETWARE__ */
+
+#include <stdio.h>
+
+main()
+{
+ fprintf(stderr,"this test has not been ported to NetWare\n");
+ return 0;
+}
+
+#endif /* __NETWARE__ */
diff --git a/myisam/mi_test_all.res b/myisam/mi_test_all.res
index d6b4703d702..94355bf1aa2 100644
--- a/myisam/mi_test_all.res
+++ b/myisam/mi_test_all.res
@@ -1,48 +1,50 @@
-Maximum memory usage: 545477 bytes (533k)
-Maximum memory usage: 545477 bytes (533k)
-Maximum memory usage: 545369 bytes (533k)
-mi_test2-i686 -s -L -K -R1 -m2000 ; Should give error 135
+mi_test2 -s -L -K -R1 -m2000 ; Should give error 135
Error: 135 in write at record: 1105
got error: 135 when using MyISAM-database
-Maximum memory usage: 29439 bytes (29k)
-Maximum memory usage: 66541 bytes (65k)
-Maximum memory usage: 5101 bytes (5k)
-Maximum memory usage: 545488 bytes (533k)
+myisamchk: MyISAM file test2
+myisamchk: warning: Datafile is almost full, 65532 of 65534 used
+MyISAM-table 'test2' is usable but should be fixed
Commands Used count Errors Recover errors
-open 1 0 0
-write 50 0 0
-update 5 0 0
-delete 50 0 0
-close 1 0 0
-extra 6 0 0
-Total 113 0 0
-Maximum memory usage: 545744 bytes (533k)
+open 17 0 0
+write 850 0 0
+update 85 0 0
+delete 850 0 0
+close 17 0 0
+extra 102 0 0
+Total 1921 0 0
Commands Used count Errors Recover errors
-open 2 0 0
-write 100 0 0
-update 10 0 0
-delete 100 0 0
-close 2 0 0
-extra 12 0 0
-Total 226 0 0
-Maximum memory usage: 5101 bytes (5k)
-1.12user 0.52system 0:01.71elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (214major+25minor)pagefaults 0swaps
-Maximum memory usage: 21189 bytes (21k)
-1.29user 0.55system 0:01.82elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (215major+29minor)pagefaults 0swaps
-Maximum memory usage: 66541 bytes (65k)
-1.10user 0.51system 0:01.66elapsed 96%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (216major+40minor)pagefaults 0swaps
-Maximum memory usage: 82629 bytes (81k)
-1.33user 0.24system 0:01.54elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (216major+44minor)pagefaults 0swaps
-Maximum memory usage: 545477 bytes (533k)
-1.31user 0.24system 0:01.55elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (216major+173minor)pagefaults 0swaps
-Maximum memory usage: 545389 bytes (533k)
-1.37user 0.18system 0:01.57elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (218major+180minor)pagefaults 0swaps
-Maximum memory usage: 109165 bytes (107k)
-1.42user 0.38system 0:01.78elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k
-0inputs+0outputs (218major+51minor)pagefaults 0swaps
+open 18 0 0
+write 900 0 0
+update 90 0 0
+delete 900 0 0
+close 18 0 0
+extra 108 0 0
+Total 2034 0 0
+
+real 0m1.054s
+user 0m0.410s
+sys 0m0.640s
+
+real 0m1.077s
+user 0m0.550s
+sys 0m0.530s
+
+real 0m1.100s
+user 0m0.420s
+sys 0m0.680s
+
+real 0m0.783s
+user 0m0.590s
+sys 0m0.200s
+
+real 0m0.764s
+user 0m0.560s
+sys 0m0.210s
+
+real 0m0.699s
+user 0m0.570s
+sys 0m0.130s
+
+real 0m0.991s
+user 0m0.630s
+sys 0m0.350s
diff --git a/myisam/mi_test_all.sh b/myisam/mi_test_all.sh
index ccc9c39c64e..07e71d65675 100755
--- a/myisam/mi_test_all.sh
+++ b/myisam/mi_test_all.sh
@@ -3,7 +3,9 @@
# Execute some simple basic test on MyISAM libary to check if things
# works at all.
+valgrind="valgrind --alignment=8 --leak-check=yes"
silent="-s"
+
if test -f mi_test1$MACH ; then suffix=$MACH else suffix=""; fi
mi_test1$suffix $silent
myisamchk$suffix -se test1
@@ -66,6 +68,14 @@ myisamchk$suffix -rs test1
myisamchk$suffix -se test1
myisamchk$suffix -rqs test1
myisamchk$suffix -se test1
+myisamchk$suffix -rs --correct-checksum test1
+myisamchk$suffix -se test1
+myisamchk$suffix -rqs --correct-checksum test1
+myisamchk$suffix -se test1
+myisamchk$suffix -ros --correct-checksum test1
+myisamchk$suffix -se test1
+myisamchk$suffix -rqos --correct-checksum test1
+myisamchk$suffix -se test1
# check of myisampack / myisamchk
myisampack$suffix --force -s test1
@@ -105,13 +115,25 @@ mi_test1$suffix $silent --key_multiple -P -S
myisamchk$suffix -sm test1
mi_test2$suffix $silent -L -K -W -P
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -W -P -A
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -W -P -S -R1 -m500
echo "mi_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135"
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -R1 -m2000
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -P -S -R3 -m50 -b1000000
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -B
+myisamchk$suffix -sm test2
mi_test2$suffix $silent -D -B -c
+myisamchk$suffix -sm test2
+mi_test2$suffix $silent -m10000 -e8192 -K
+myisamchk$suffix -sm test2
+mi_test2$suffix $silent -m10000 -e16384 -E16384 -K -L
+myisamchk$suffix -sm test2
+
mi_test2$suffix $silent -L -K -W -P -m50 -l
myisamlog$suffix
mi_test2$suffix $silent -L -K -W -P -m50 -l -b100
diff --git a/myisam/mi_unique.c b/myisam/mi_unique.c
index 7f1e6b83a12..ddba40214e7 100644
--- a/myisam/mi_unique.c
+++ b/myisam/mi_unique.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -179,19 +179,19 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
memcpy_fixed((byte*) &pos_a,pos_a+keyseg->bit_start,sizeof(char*));
memcpy_fixed((byte*) &pos_b,pos_b+keyseg->bit_start,sizeof(char*));
}
- end= pos_a+length;
if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT)
{
- uchar *sort_order=keyseg->charset->sort_order;
- while (pos_a != end)
- if (sort_order[*(uchar*) pos_a++] !=
- sort_order[*(uchar*) pos_b++])
+ if (_mi_compare_text(keyseg->charset, (uchar *)pos_a, length,
+ (uchar *)pos_b, length, 0))
return 1;
}
else
+ {
+ end= pos_a+length;
while (pos_a != end)
if (*pos_a++ != *pos_b++)
return 1;
+ }
}
return 0;
}
diff --git a/myisam/mi_update.c b/myisam/mi_update.c
index 185624f3878..f9ed969d8b5 100644
--- a/myisam/mi_update.c
+++ b/myisam/mi_update.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -83,8 +83,6 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
/* Check which keys changed from the original row */
new_key=info->lastkey2;
- key_changed=HA_STATE_KEY_CHANGED; /* We changed current database */
- /* Remove key that didn't change */
changed=0;
for (i=0 ; i < share->base.keys ; i++)
{
@@ -93,14 +91,19 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
/* The following code block is for text searching by SerG */
if (share->keyinfo[i].flag & HA_FULLTEXT )
{
- if(_mi_ft_cmp(info,i,oldrec, newrec))
+ if (_mi_ft_cmp(info,i,oldrec, newrec))
{
if ((int) i == info->lastinx)
+ {
+ /*
+ We are changeing the index we are reading on. Mark that
+ the index data has changed and we need to do a full search
+ when doing read-next
+ */
key_changed|=HA_STATE_WRITTEN;
+ }
changed|=((ulonglong) 1 << i);
- if (_mi_ft_del(info,i,(char*) old_key,oldrec,pos))
- goto err;
- if (_mi_ft_add(info,i,(char*) new_key,newrec,pos))
+ if (_mi_ft_update(info,i,(char*) old_key,oldrec,newrec,pos))
goto err;
}
}
@@ -123,11 +126,39 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
}
}
}
+ /*
+ If we are running with external locking, we must update the index file
+ that something has changed.
+ */
+ if (changed || !my_disable_locking)
+ key_changed|= HA_STATE_CHANGED;
if (share->calc_checksum)
+ {
info->checksum=(*share->calc_checksum)(info,newrec);
- if ((*share->update_record)(info,pos,newrec))
- goto err;
+ /* Store new checksum in index file header */
+ key_changed|= HA_STATE_CHANGED;
+ }
+ {
+ /*
+ Don't update index file if data file is not extended and no status
+ information changed
+ */
+ MI_STATUS_INFO state;
+ ha_rows org_split;
+ my_off_t org_delete_link;
+
+ memcpy((char*) &state, (char*) info->state, sizeof(state));
+ org_split= share->state.split;
+ org_delete_link= share->state.dellink;
+ if ((*share->update_record)(info,pos,newrec))
+ goto err;
+ if (!key_changed &&
+ (memcmp((char*) &state, (char*) info->state, sizeof(state)) ||
+ org_split != share->state.split ||
+ org_delete_link != share->state.dellink))
+ key_changed|= HA_STATE_CHANGED; /* Must update index file */
+ }
if (auto_key_changed)
update_auto_increment(info,newrec);
if (share->calc_checksum)
@@ -138,11 +169,19 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,0);
VOID(_mi_writeinfo(info,key_changed ? WRITEINFO_UPDATE_KEYFILE : 0));
allow_break(); /* Allow SIGHUP & SIGINT */
+ if (info->invalidator != 0)
+ {
+ DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename));
+ (*info->invalidator)(info->filename);
+ info->invalidator=0;
+ }
DBUG_RETURN(0);
err:
DBUG_PRINT("error",("key: %d errno: %d",i,my_errno));
save_errno=my_errno;
+ if (changed)
+ key_changed|= HA_STATE_CHANGED;
if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL)
{
info->errkey= (int) i;
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index 7b468395166..40e2f301fce 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -25,7 +25,8 @@
/* Functions declared in this file */
-static int w_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
+static int w_search(MI_INFO *info,MI_KEYDEF *keyinfo,
+ uint comp_flag, uchar *key,
uint key_length, my_off_t pos, uchar *father_buff,
uchar *father_keypos, my_off_t father_page,
my_bool insert_last);
@@ -35,17 +36,21 @@ static int _mi_balance_page(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
uchar *key, uint *return_key_length,
uchar **after_key);
-
+int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key,
+ uint key_length);
+int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key,
+ uint key_length);
/* Write new record to database */
int mi_write(MI_INFO *info, byte *record)
{
+ MYISAM_SHARE *share=info->s;
uint i;
int save_errno;
my_off_t filepos;
uchar *buff;
- MYISAM_SHARE *share=info->s;
+ my_bool lock_tree= share->concurrent_insert;
DBUG_ENTER("mi_write");
DBUG_PRINT("enter",("isam: %d data: %d",info->s->kfile,info->dfile));
@@ -96,33 +101,36 @@ int mi_write(MI_INFO *info, byte *record)
{
if (((ulonglong) 1 << i) & share->state.key_map)
{
- if (share->concurrent_insert)
+ bool local_lock_tree= (lock_tree &&
+ !(info->bulk_insert &&
+ is_tree_inited(&info->bulk_insert[i])));
+ if (local_lock_tree)
{
rw_wrlock(&share->key_root_lock[i]);
share->keyinfo[i].version++;
}
- if (share->keyinfo[i].flag & HA_FULLTEXT ) /* SerG */
- { /* SerG */
- if (_mi_ft_add(info,i,(char*) buff,record,filepos)) /* SerG */
- { /* SerG */
- if (share->concurrent_insert)
+ if (share->keyinfo[i].flag & HA_FULLTEXT )
+ {
+ if (_mi_ft_add(info,i,(char*) buff,record,filepos))
+ {
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
- DBUG_PRINT("error",("Got error: %d on write",my_errno)); /* SerG */
- goto err; /* SerG */
- } /* SerG */
- } /* SerG */
- else /* SerG */
+ DBUG_PRINT("error",("Got error: %d on write",my_errno));
+ goto err;
+ }
+ }
+ else
{
uint key_length=_mi_make_key(info,i,buff,record,filepos);
if (_mi_ck_write(info,i,buff,key_length))
{
- if (share->concurrent_insert)
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
DBUG_PRINT("error",("Got error: %d on write",my_errno));
goto err;
}
}
- if (share->concurrent_insert)
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
}
}
@@ -142,6 +150,12 @@ int mi_write(MI_INFO *info, byte *record)
info->lastpos=filepos;
myisam_log_record(MI_LOG_WRITE,info,record,filepos,0);
VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE));
+ if (info->invalidator != 0)
+ {
+ DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename));
+ (*info->invalidator)(info->filename);
+ info->invalidator=0;
+ }
allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(0);
@@ -149,19 +163,32 @@ err:
save_errno=my_errno;
if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL)
{
+ if (info->bulk_insert)
+ {
+ uint j;
+ for (j=0 ; j < share->base.keys ; j++)
+ {
+ if (is_tree_inited(&info->bulk_insert[j]))
+ {
+ reset_tree(&info->bulk_insert[j]);
+ }
+ }
+ }
info->errkey= (int) i;
while ( i-- > 0)
{
if (((ulonglong) 1 << i) & share->state.key_map)
{
- if (share->concurrent_insert)
+ bool local_lock_tree= (lock_tree &&
+ !(info->bulk_insert &&
+ is_tree_inited(&info->bulk_insert[i])));
+ if (local_lock_tree)
rw_wrlock(&share->key_root_lock[i]);
- /* The following code block is for text searching by SerG */
if (share->keyinfo[i].flag & HA_FULLTEXT)
{
if (_mi_ft_del(info,i,(char*) buff,record,filepos))
{
- if (share->concurrent_insert)
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
break;
}
@@ -171,12 +198,12 @@ err:
uint key_length=_mi_make_key(info,i,buff,record,filepos);
if (_mi_ck_delete(info,i,buff,key_length))
{
- if (share->concurrent_insert)
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
break;
}
}
- if (share->concurrent_insert)
+ if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
}
}
@@ -196,19 +223,51 @@ err2:
/* Write one key to btree */
-int _mi_ck_write(register MI_INFO *info, uint keynr, uchar *key,
- uint key_length)
+int _mi_ck_write(MI_INFO *info, uint keynr, uchar *key, uint key_length)
{
- int error;
DBUG_ENTER("_mi_ck_write");
+ if (info->bulk_insert && is_tree_inited(&info->bulk_insert[keynr]))
+ {
+ DBUG_RETURN(_mi_ck_write_tree(info, keynr, key, key_length));
+ }
+ else
+ {
+ DBUG_RETURN(_mi_ck_write_btree(info, keynr, key, key_length));
+ }
+} /* _mi_ck_write */
+
+
+/**********************************************************************
+ * Normal insert code *
+ **********************************************************************/
+
+int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key,
+ uint key_length)
+{
+ int error;
+ uint comp_flag;
+ MI_KEYDEF *keyinfo=info->s->keyinfo+keynr;
+ DBUG_ENTER("_mi_ck_write_btree");
+
+ if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
+ comp_flag=SEARCH_BIGGER; /* Put after same key */
+ else if (keyinfo->flag & HA_NOSAME)
+ {
+ comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* No dupplicates */
+ if (keyinfo->flag & HA_NULL_ARE_EQUAL)
+ comp_flag|= SEARCH_NULL_ARE_EQUAL;
+ }
+ else
+ comp_flag=SEARCH_SAME; /* Keys in rec-pos order */
+
if (info->s->state.key_root[keynr] == HA_OFFSET_ERROR ||
- (error=w_search(info,info->s->keyinfo+keynr,key, key_length,
+ (error=w_search(info, keyinfo, comp_flag, key, key_length,
info->s->state.key_root[keynr], (uchar *) 0, (uchar*) 0,
(my_off_t) 0, 1)) > 0)
error=_mi_enlarge_root(info,keynr,key);
DBUG_RETURN(error);
-} /* _mi_ck_write */
+} /* _mi_ck_write_btree */
/* Make a new root with key as only pointer */
@@ -246,13 +305,12 @@ int _mi_enlarge_root(register MI_INFO *info, uint keynr, uchar *key)
*/
static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
- uchar *key, uint key_length, my_off_t page,
- uchar *father_buff,
- uchar *father_keypos, my_off_t father_page,
- my_bool insert_last)
+ uint comp_flag, uchar *key, uint key_length, my_off_t page,
+ uchar *father_buff, uchar *father_keypos,
+ my_off_t father_page, my_bool insert_last)
{
int error,flag;
- uint comp_flag,nod_flag;
+ uint nod_flag, search_key_length;
uchar *temp_buff,*keypos;
uchar keybuff[MI_MAX_KEY_BUFF];
my_bool was_last_key;
@@ -260,25 +318,15 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_ENTER("w_search");
DBUG_PRINT("enter",("page: %ld",page));
- if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
- comp_flag=SEARCH_BIGGER; /* Put after same key */
- else if (keyinfo->flag & HA_NOSAME)
- {
- comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* No dupplicates */
- if (keyinfo->flag & HA_NULL_ARE_EQUAL)
- comp_flag|= SEARCH_NULL_ARE_EQUAL;
- }
- else
- comp_flag=SEARCH_SAME; /* Keys in rec-pos order */
-
+ search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
MI_MAX_KEY_BUFF*2)))
DBUG_RETURN(-1);
if (!_mi_fetch_keypage(info,keyinfo,page,temp_buff,0))
goto err;
- flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,key_length,comp_flag,
- &keypos, keybuff, &was_last_key);
+ flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length,
+ comp_flag, &keypos, keybuff, &was_last_key);
nod_flag=mi_test_if_nod(temp_buff);
if (flag == 0)
{
@@ -299,7 +347,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
insert_last=0;
next_page=_mi_kpos(nod_flag,keypos);
if (next_page == HA_OFFSET_ERROR ||
- (error=w_search(info,keyinfo,key,key_length,next_page,
+ (error=w_search(info, keyinfo, comp_flag, key, key_length, next_page,
temp_buff, keypos, page, insert_last)) >0)
{
error=_mi_insert(info,keyinfo,key,temp_buff,keypos,keybuff,father_buff,
@@ -349,7 +397,7 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
{
DBUG_PRINT("test",("t_length: %d ref_len: %d",
t_length,s_temp.ref_length));
- DBUG_PRINT("test",("n_ref_len: %d n_length: %d key: %lx",
+ DBUG_PRINT("test",("n_ref_len: %d n_length: %d key_pos: %lx",
s_temp.n_ref_length,s_temp.n_length,s_temp.key));
}
#endif
@@ -686,3 +734,156 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
err:
DBUG_RETURN(-1);
} /* _mi_balance_page */
+
+/**********************************************************************
+ * Bulk insert code *
+ **********************************************************************/
+
+typedef struct {
+ MI_INFO *info;
+ uint keynr;
+} bulk_insert_param;
+
+int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key,
+ uint key_length)
+{
+ int error;
+ DBUG_ENTER("_mi_ck_write_tree");
+
+ error= tree_insert(&info->bulk_insert[keynr], key,
+ key_length + info->s->rec_reflength) ? 0 : HA_ERR_OUT_OF_MEM ;
+
+ DBUG_RETURN(error);
+} /* _mi_ck_write_tree */
+
+
+/* typeof(_mi_keys_compare)=qsort_cmp2 */
+
+static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2)
+{
+ uint not_used;
+ return _mi_key_cmp(param->info->s->keyinfo[param->keynr].seg,
+ key1, key2, USE_WHOLE_KEY, SEARCH_SAME,
+ &not_used);
+}
+
+
+static int keys_free(uchar *key, TREE_FREE mode, bulk_insert_param *param)
+{
+ /*
+ Probably I can use info->lastkey here, but I'm not sure,
+ and to be safe I'd better use local lastkey.
+ */
+ uchar lastkey[MI_MAX_KEY_BUFF];
+ uint keylen;
+ MI_KEYDEF *keyinfo;
+
+ switch (mode) {
+ case free_init:
+ if (param->info->s->concurrent_insert)
+ {
+ rw_wrlock(&param->info->s->key_root_lock[param->keynr]);
+ param->info->s->keyinfo[param->keynr].version++;
+ }
+ return 0;
+ case free_free:
+ keyinfo=param->info->s->keyinfo+param->keynr;
+ keylen=_mi_keylength(keyinfo, key);
+ memcpy(lastkey, key, keylen);
+ return _mi_ck_write_btree(param->info,param->keynr,lastkey,
+ keylen - param->info->s->rec_reflength);
+ case free_end:
+ if (param->info->s->concurrent_insert)
+ rw_unlock(&param->info->s->key_root_lock[param->keynr]);
+ return 0;
+ }
+ return -1;
+}
+
+
+int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows)
+{
+ MYISAM_SHARE *share=info->s;
+ MI_KEYDEF *key=share->keyinfo;
+ bulk_insert_param *params;
+ uint i, num_keys, total_keylength;
+ ulonglong key_map=0;
+ DBUG_ENTER("_mi_init_bulk_insert");
+ DBUG_PRINT("enter",("cache_size: %lu", cache_size));
+
+ if (info->bulk_insert || (rows && rows < MI_MIN_ROWS_TO_USE_BULK_INSERT))
+ DBUG_RETURN(0);
+
+ for (i=total_keylength=num_keys=0 ; i < share->base.keys ; i++)
+ {
+ if (!(key[i].flag & HA_NOSAME) && share->base.auto_key != i+1
+ && test(share->state.key_map & ((ulonglong) 1 << i)))
+ {
+ num_keys++;
+ key_map |=((ulonglong) 1 << i);
+ total_keylength+=key[i].maxlength+TREE_ELEMENT_EXTRA_SIZE;
+ }
+ }
+
+ if (num_keys==0 ||
+ num_keys * MI_MIN_SIZE_BULK_INSERT_TREE > cache_size)
+ DBUG_RETURN(0);
+
+ if (rows && rows*total_keylength < cache_size)
+ cache_size=rows;
+ else
+ cache_size/=total_keylength*16;
+
+ info->bulk_insert=(TREE *)
+ my_malloc((sizeof(TREE)*share->base.keys+
+ sizeof(bulk_insert_param)*num_keys),MYF(0));
+
+ if (!info->bulk_insert)
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+
+ params=(bulk_insert_param *)(info->bulk_insert+share->base.keys);
+ for (i=0 ; i < share->base.keys ; i++)
+ {
+ if (test(key_map & ((ulonglong) 1 << i)))
+ {
+ params->info=info;
+ params->keynr=i;
+ /* Only allocate a 16'th of the buffer at a time */
+ init_tree(&info->bulk_insert[i],
+ cache_size * key[i].maxlength,
+ cache_size * key[i].maxlength, 0,
+ (qsort_cmp2)keys_compare, 0,
+ (tree_element_free) keys_free, (void *)params++);
+ }
+ else
+ info->bulk_insert[i].root=0;
+ }
+
+ DBUG_RETURN(0);
+}
+
+void mi_flush_bulk_insert(MI_INFO *info, uint inx)
+{
+ if (info->bulk_insert)
+ {
+ if (is_tree_inited(&info->bulk_insert[inx]))
+ reset_tree(&info->bulk_insert[inx]);
+ }
+}
+
+void mi_end_bulk_insert(MI_INFO *info)
+{
+ if (info->bulk_insert)
+ {
+ uint i;
+ for (i=0 ; i < info->s->base.keys ; i++)
+ {
+ if (is_tree_inited(& info->bulk_insert[i]))
+ {
+ delete_tree(& info->bulk_insert[i]);
+ }
+ }
+ my_free((void *)info->bulk_insert, MYF(0));
+ info->bulk_insert=0;
+ }
+}
diff --git a/myisam/myisam_ftdump.c b/myisam/myisam_ftdump.c
new file mode 100644
index 00000000000..69fef529fa9
--- /dev/null
+++ b/myisam/myisam_ftdump.c
@@ -0,0 +1,274 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Written by Sergei A. Golubchik, who has a shared copyright to this code
+ added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */
+
+#include "ftdefs.h"
+#include <my_getopt.h>
+
+static void get_options(int *argc,char **argv[]);
+static void usage();
+static void complain(int val);
+
+static int count=0, stats=0, dump=0, lstats=0;
+static my_bool verbose;
+static char *query=NULL;
+static uint lengths[256];
+
+#define MAX_LEN (HA_FT_MAXLEN+10)
+#define HOW_OFTEN_TO_WRITE 10000
+
+static struct my_option my_long_options[] =
+{
+ {"dump", 'd', "Dump index (incl. data offsets and word weights)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"stats", 's', "Report global stats",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Be verbose",
+ (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"count", 'c', "Calculate per-word stats (counts and global weights)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"length", 'l', "Report length distribution",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"execute", 'e', "Execute given query", (gptr*) &query, (gptr*) &query, 0,
+ GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", 'h', "Display help and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?', "Synonym for -h",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+
+int main(int argc,char *argv[])
+{
+ int error=0;
+ uint keylen, keylen2=0, inx, doc_cnt=0;
+ float weight;
+ double gws, min_gws=0, avg_gws=0;
+ MI_INFO *info;
+ char buf[MAX_LEN], buf2[MAX_LEN], buf_maxlen[MAX_LEN], buf_min_gws[MAX_LEN];
+ ulong total=0, maxlen=0, uniq=0, max_doc_cnt=0;
+ struct { MI_INFO *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */
+
+ MY_INIT(argv[0]);
+ get_options(&argc, &argv);
+ if (count || dump)
+ verbose=0;
+ if (!count && !dump && !lstats && !query)
+ stats=1;
+
+ if (verbose)
+ setbuf(stdout,NULL);
+
+ if (argc < 2)
+ usage();
+
+ if (!(info=mi_open(argv[0],2,HA_OPEN_ABORT_IF_LOCKED)))
+ goto err;
+
+ inx=atoi(argv[1]);
+ *buf2=0;
+ aio->info=info;
+
+ if ((inx >= info->s->base.keys) ||
+ !(info->s->keyinfo[inx].flag & HA_FULLTEXT))
+ {
+ printf("Key %d in table %s is not a FULLTEXT key\n", inx, info->filename);
+ goto err;
+ }
+
+ if (query)
+ {
+#if 0
+ FT_DOCLIST *result;
+ int i;
+
+ ft_init_stopwords(ft_precompiled_stopwords);
+
+ result=ft_nlq_init_search(info,inx,query,strlen(query),1);
+ if(!result)
+ goto err;
+
+ if (verbose)
+ printf("%d rows matched\n",result->ndocs);
+
+ for(i=0 ; i<result->ndocs ; i++)
+ printf("%9qx %20.7f\n",result->doc[i].dpos,result->doc[i].weight);
+
+ ft_nlq_close_search(result);
+#else
+ printf("-e option is disabled\n");
+#endif
+ }
+ else
+ {
+ info->lastpos= HA_OFFSET_ERROR;
+ info->update|= HA_STATE_PREV_FOUND;
+
+ while (!(error=mi_rnext(info,NULL,inx)))
+ {
+ keylen=*(info->lastkey);
+
+#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
+ mi_float4get(weight,info->lastkey+keylen+1);
+#else
+#error
+#endif
+
+#ifdef HAVE_SNPRINTF
+ snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey+1);
+#else
+ sprintf(buf,"%.*s",(int) keylen,info->lastkey+1);
+#endif
+ casedn_str(buf);
+ total++;
+ lengths[keylen]++;
+
+ if (count || stats)
+ {
+ doc_cnt++;
+ if (strcmp(buf, buf2))
+ {
+ if (*buf2)
+ {
+ uniq++;
+ avg_gws+=gws=GWS_IN_USE;
+ if (count)
+ printf("%9u %20.7f %s\n",doc_cnt,gws,buf2);
+ if (maxlen<keylen2)
+ {
+ maxlen=keylen2;
+ strmov(buf_maxlen, buf2);
+ }
+ if (max_doc_cnt < doc_cnt)
+ {
+ max_doc_cnt=doc_cnt;
+ strmov(buf_min_gws, buf2);
+ min_gws=gws;
+ }
+ }
+ strmov(buf2, buf);
+ keylen2=keylen;
+ doc_cnt=0;
+ }
+ }
+ if (dump)
+ printf("%9qx %20.7f %s\n",info->lastpos,weight,buf);
+
+ if(verbose && (total%HOW_OFTEN_TO_WRITE)==0)
+ printf("%10ld\r",total);
+ }
+
+ if (stats)
+ {
+ count=0;
+ for (inx=0;inx<256;inx++)
+ {
+ count+=lengths[inx];
+ if ((ulong) count >= total/2)
+ break;
+ }
+ printf("Total rows: %qu\nTotal words: %lu\n"
+ "Unique words: %lu\nLongest word: %lu chars (%s)\n"
+ "Median length: %u\n"
+ "Average global weight: %f\n"
+ "Most common word: %lu times, weight: %f (%s)\n",
+ (ulonglong)info->state->records, total, uniq, maxlen, buf_maxlen,
+ inx, avg_gws/uniq, max_doc_cnt, min_gws, buf_min_gws);
+ }
+ if (lstats)
+ {
+ count=0;
+ for (inx=0; inx<256; inx++)
+ {
+ count+=lengths[inx];
+ if (count && lengths[inx])
+ printf("%3u: %10lu %5.2f%% %20lu %4.1f%%\n", inx,
+ (ulong) lengths[inx],100.0*lengths[inx]/total,(ulong) count,
+ 100.0*count/total);
+ }
+ }
+ }
+
+err:
+ if (error && error != HA_ERR_END_OF_FILE)
+ printf("got error %d\n",my_errno);
+ if (info)
+ mi_close(info);
+ return 0;
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch(optid) {
+ case 'd':
+ dump=1;
+ complain(count || query);
+ break;
+ case 's':
+ stats=1;
+ complain(query!=0);
+ break;
+ case 'c':
+ count= 1;
+ complain(dump || query);
+ break;
+ case 'l':
+ lstats=1;
+ complain(query!=0);
+ break;
+ case 'e':
+ complain(dump || count || stats);
+ break;
+ case '?':
+ case 'h':
+ usage();
+ }
+ return 0;
+}
+
+
+static void get_options(int *argc, char **argv[])
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+} /* get options */
+
+
+static void usage()
+{
+ printf("Use: ft_dump <table_name> <index_no>\n");
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+ exit(1);
+}
+
+
+static void complain(int val) /* Kinda assert :-) */
+{
+ if (val)
+ {
+ printf("You cannot use these options together!\n");
+ exit(1);
+ }
+}
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index cb321f8fda3..f1deda41f8b 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -1,27 +1,26 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Descript, check and repair of ISAM tables */
+/* Describe, check and repair of MyISAM tables */
#include "fulltext.h"
#include <m_ctype.h>
#include <stdarg.h>
-#include <getopt.h>
-#include <assert.h>
+#include <my_getopt.h>
#ifdef HAVE_SYS_VADVICE_H
#include <sys/vadvise.h>
#endif
@@ -44,6 +43,9 @@ static char **default_argv;
static const char *load_default_groups[]= { "myisamchk", 0 };
static const char *set_charset_name;
static CHARSET_INFO *set_charset;
+static long opt_myisam_block_size;
+static const char *my_progname_short;
+static int stopwords_inited= 0;
static const char *type_names[]=
{ "?","char","binary", "short", "long", "float",
@@ -69,12 +71,11 @@ static void print_version(void);
static void usage(void);
static int myisamchk(MI_CHECK *param, char *filename);
static void descript(MI_CHECK *param, register MI_INFO *info, my_string name);
-static int mi_sort_records(MI_CHECK *param,
- register MI_INFO *info, my_string name,
- uint sort_key,
- my_bool write_info,
- my_bool update_index);
-static int sort_record_index(MI_CHECK *param,MI_INFO *info,MI_KEYDEF *keyinfo,
+static int mi_sort_records(MI_CHECK *param, register MI_INFO *info,
+ my_string name, uint sort_key,
+ my_bool write_info, my_bool update_index);
+static int sort_record_index(MI_SORT_PARAM *sort_param, MI_INFO *info,
+ MI_KEYDEF *keyinfo,
my_off_t page,uchar *buff,uint sortkey,
File new_file, my_bool update_index);
@@ -86,6 +87,7 @@ int main(int argc, char **argv)
{
int error;
MY_INIT(argv[0]);
+ my_progname_short= my_progname+dirname_length(my_progname);
#ifdef __EMX__
_wildcard (&argc, &argv);
@@ -100,12 +102,13 @@ int main(int argc, char **argv)
while (--argc >= 0)
{
int new_error=myisamchk(&check_param, *(argv++));
+ if ((check_param.testflag & T_REP_ANY) != T_REP)
+ check_param.testflag&= ~T_REP;
VOID(fflush(stdout));
VOID(fflush(stderr));
if ((check_param.error_printed | check_param.warning_printed) &&
(check_param.testflag & T_FORCE_CREATE) &&
- (!(check_param.testflag & (T_REP | T_REP_BY_SORT | T_SORT_RECORDS |
- T_SORT_INDEX))))
+ (!(check_param.testflag & (T_REP | T_SORT_RECORDS | T_SORT_INDEX))))
{
uint old_testflag=check_param.testflag;
if (!(check_param.testflag & T_REP))
@@ -129,7 +132,7 @@ int main(int argc, char **argv)
char buff[22],buff2[22];
if (!(check_param.testflag & T_SILENT) || check_param.testflag & T_INFO)
puts("\n---------\n");
- printf("\nTotal of all %d ISAM-files:\nData records: %9s Deleted blocks: %9s\n",check_param.total_files,llstr(check_param.total_records,buff),
+ printf("\nTotal of all %d MyISAM-files:\nData records: %9s Deleted blocks: %9s\n",check_param.total_files,llstr(check_param.total_records,buff),
llstr(check_param.total_deleted,buff2));
}
free_defaults(default_argv);
@@ -141,112 +144,237 @@ int main(int argc, char **argv)
#endif
} /* main */
+enum options_mc {
+ OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS,
+ OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE,
+ OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
+ OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
+ OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT
+};
-static CHANGEABLE_VAR changeable_vars[] = {
- { "key_buffer_size",(long*) &check_param.use_buffers,(long) USE_BUFFER_INIT,
- (long) MALLOC_OVERHEAD, (long) ~0L,(long) MALLOC_OVERHEAD,(long) IO_SIZE },
- { "read_buffer_size", (long*) &check_param.read_buffer_length,(long) READ_BUFFER_INIT,
- (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L },
- { "write_buffer_size", (long*) &check_param.write_buffer_length,(long) READ_BUFFER_INIT,
- (long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L },
- { "sort_buffer_size",(long*) &check_param.sort_buffer_length,(long) SORT_BUFFER_INIT,
- (long) (MIN_SORT_BUFFER+MALLOC_OVERHEAD),(long) ~0L,
- (long) MALLOC_OVERHEAD,(long) 1L },
- { "sort_key_blocks",(long*) &check_param.sort_key_blocks,BUFFERS_WHEN_SORTING,4L,100L,0L,
- 1L },
- { "decode_bits",(long*) &decode_bits,9L,4L,17L,0L,1L },
- { NullS,(long*) 0,0L,0L,0L,0L,0L,} };
-
-enum options {OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS};
-
-
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"analyze", no_argument, 0, 'a'},
- {"block-search", required_argument,0, 'b'},
- {"backup", no_argument, 0, 'B'},
- {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
- {"check", no_argument, 0, 'c'},
- {"check-only-changed",no_argument, 0, 'C'},
+ {"analyze", 'a',
+ "Analyze distribution of keys. Will make some joins in MySQL faster. You can check the calculated distribution.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"block-search", 'b',
+ "No help available.",
+ 0, 0, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"backup", 'B',
+ "Make a backup of the .MYD file as 'filename-time.BAK'",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are.",
+ (gptr*) &set_charset_name, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"check", 'c',
+ "Check table for errors.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"check-only-changed", 'C',
+ "Check only tables that have changed since last check.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"correct-checksum", OPT_CORRECT_CHECKSUM,
+ "Correct checksum information for table.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", optional_argument, 0, '#'},
+ {"debug", '#',
+ "Output debug log. Often this is 'd:t:o,filename'.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"description", no_argument, 0, 'd'},
- {"data-file-length", required_argument, 0, 'D'},
- {"extend-check", no_argument, 0, 'e'},
- {"fast", no_argument, 0, 'F'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, '?'},
- {"information", no_argument, 0, 'i'},
- {"keys-used", required_argument, 0, 'k'},
- {"medium-check", no_argument, 0, 'm'},
- {"no-symlinks", no_argument, 0, 'l'},
- {"quick", no_argument, 0, 'q'},
- {"read-only", no_argument, 0, 'T'},
- {"recover", no_argument, 0, 'r'},
- {"safe-recover", no_argument, 0, 'o'},
- {"start-check-pos", required_argument, 0, OPT_START_CHECK_POS},
- {"set-auto-increment",optional_argument, 0, 'A'},
- {"set-character-set",required_argument,0,OPT_SET_CHARSET},
- {"set-variable", required_argument, 0, 'O'},
- {"silent", no_argument, 0, 's'},
- {"sort-index", no_argument, 0, 'S'},
- {"sort-records", required_argument, 0, 'R'},
- {"sort-recover", no_argument, 0, 'n'},
- {"tmpdir", required_argument, 0, 't'},
- {"update-state", no_argument, 0, 'U'},
- {"unpack", no_argument, 0, 'u'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"wait", no_argument, 0, 'w'},
- {0, 0, 0, 0}
+ {"description", 'd',
+ "Prints some information about table.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"data-file-length", 'D',
+ "Max length of data file (when recreating data-file when it's full).",
+ (gptr*) &check_param.max_data_file_length,
+ (gptr*) &check_param.max_data_file_length,
+ 0, GET_LL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"extend-check", 'e',
+ "If used when checking a table, ensure that the table is 100 percent consistent, which will take a long time. If used when repairing a table, try to recover every possible row from the data file. Normally this will also find a lot of garbage rows; Don't use this option with repair if you are not totally desperate.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"fast", 'F',
+ "Check only tables that haven't been closed properly.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"force", 'f',
+ "Restart with -r if there are any errors in the table. States will be updated as with --update-state.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"HELP", 'H',
+ "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"help", '?',
+ "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"information", 'i',
+ "Print statistics information about table that is checked.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"keys-used", 'k',
+ "Tell MyISAM to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts!",
+ (gptr*) &check_param.keys_in_use,
+ (gptr*) &check_param.keys_in_use,
+ 0, GET_ULL, REQUIRED_ARG, -1, 0, 0, 0, 0, 0},
+ {"medium-check", 'm',
+ "Faster than extend-check, but only finds 99.99% of all errors. Should be good enough for most cases.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"quick", 'q', "Faster repair by not modifying the data file.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"read-only", 'T',
+ "Don't mark table as checked.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"recover", 'r',
+ "Can fix almost anything except unique keys that aren't unique.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"parallel-recover", 'p',
+ "Same as '-r' but creates all the keys in parallel",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"safe-recover", 'o',
+ "Uses old recovery method; Slower than '-r' but can handle a couple of cases where '-r' reports that it can't fix the data file.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sort-recover", 'n',
+ "Force recovering with sorting even if the temporary file was very big.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef DEBUG
+ {"start-check-pos", OPT_START_CHECK_POS,
+ "No help available.",
+ 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"set-auto-increment", 'A',
+ "Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.",
+ (gptr*) &check_param.auto_increment_value,
+ (gptr*) &check_param.auto_increment_value,
+ 0, GET_ULL, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-character-set", OPT_SET_CHARSET,
+ "Change the character set used by the index",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's',
+ "Only print errors. One can use two -s to make myisamchk very silent.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sort-index", 'S',
+ "Sort index blocks. This speeds up 'read-next' in applications.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sort-records", 'R',
+ "Sort records according to an index. This makes your data much more localized and may speed up things. (It may be VERY slow to do a sort the first time!)",
+ (gptr*) &check_param.opt_sort_key,
+ (gptr*) &check_param.opt_sort_key,
+ 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"tmpdir", 't',
+ "Path for temporary files.",
+ (gptr*) &check_param.tmpdir,
+ 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"update-state", 'U',
+ "Mark tables as crashed if any errors were found.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"unpack", 'u',
+ "Unpack file packed with myisampack.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v',
+ "Print more information. This can be used with --description and --check. Use many -v for more verbosity!",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V',
+ "Print version and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"wait", 'w',
+ "Wait if table is locked.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { "key_buffer_size", OPT_KEY_BUFFER_SIZE, "",
+ (gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0,
+ GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD,
+ (long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0},
+ { "myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "",
+ (gptr*) &opt_myisam_block_size, (gptr*) &opt_myisam_block_size, 0,
+ GET_LONG, REQUIRED_ARG, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH,
+ MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0},
+ { "read_buffer_size", OPT_READ_BUFFER_SIZE, "",
+ (gptr*) &check_param.read_buffer_length,
+ (gptr*) &check_param.read_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
+ (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
+ (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ { "write_buffer_size", OPT_WRITE_BUFFER_SIZE, "",
+ (gptr*) &check_param.write_buffer_length,
+ (gptr*) &check_param.write_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
+ (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
+ (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ { "sort_buffer_size", OPT_SORT_BUFFER_SIZE, "",
+ (gptr*) &check_param.sort_buffer_length,
+ (gptr*) &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
+ (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD),
+ (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ { "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "",
+ (gptr*) &check_param.sort_key_blocks,
+ (gptr*) &check_param.sort_key_blocks, 0, GET_ULONG, REQUIRED_ARG,
+ BUFFERS_WHEN_SORTING, 4L, 100L, 0L, 1L, 0},
+ { "decode_bits", OPT_DECODE_BITS, "", (gptr*) &decode_bits,
+ (gptr*) &decode_bits, 0, GET_UINT, REQUIRED_ARG, 9L, 4L, 17L, 0L, 1L, 0},
+ { "ft_min_word_len", OPT_FT_MIN_WORD_LEN, "", (gptr*) &ft_min_word_len,
+ (gptr*) &ft_min_word_len, 0, GET_ULONG, REQUIRED_ARG, 4, 1, HA_FT_MAXLEN,
+ 0, 1, 0},
+ { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, "", (gptr*) &ft_max_word_len,
+ (gptr*) &ft_max_word_len, 0, GET_ULONG, REQUIRED_ARG, HA_FT_MAXLEN, 10,
+ HA_FT_MAXLEN, 0, 1, 0},
+ { "ft_max_word_len_for_sort", OPT_FT_MAX_WORD_LEN_FOR_SORT, "",
+ (gptr*) &ft_max_word_len_for_sort, (gptr*) &ft_max_word_len_for_sort, 0,
+ GET_ULONG, REQUIRED_ARG, 20, 4, HA_FT_MAXLEN, 0, 1, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
+
static void print_version(void)
{
- printf("%s Ver 1.53 for %s at %s\n",my_progname,SYSTEM_TYPE,
+ printf("%s Ver 2.6 for %s at %s\n", my_progname, SYSTEM_TYPE,
MACHINE_TYPE);
}
+
static void usage(void)
{
- uint i;
print_version();
puts("By Monty, for your professional use");
puts("This software comes with NO WARRANTY: see the PUBLIC for details.\n");
- puts("Description, check and repair of ISAM tables.");
+ puts("Description, check and repair of MyISAM tables.");
puts("Used without options all tables on the command will be checked for errors");
- printf("Usage: %s [OPTIONS] tables[.MYI]\n", my_progname);
+ printf("Usage: %s [OPTIONS] tables[.MYI]\n", my_progname_short);
puts("\nGlobal options:\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename`\n\
+ -#, --debug=... Output debug log. Often this is 'd:t:o,filename'\n\
-?, --help Display this help and exit.\n\
-O, --set-variable var=option\n\
- Change the value of a variable.\n\
+ Change the value of a variable. Please note that\n\
+ this option is deprecated; you can set variables\n\
+ directly with '--variable-name=value'.\n\
+ -t, --tmpdir=path Path for temporary files\n\
-s, --silent Only print errors. One can use two -s to make\n\
myisamchk very silent\n\
-v, --verbose Print more information. This can be used with\n\
- --describe and --check. Use many -v for more verbosity!\n\
+ --description and --check. Use many -v for more verbosity!\n\
-V, --version Print version and exit.\n\
-w, --wait Wait if table is locked.\n");
+#ifdef DEBUG
+ puts(" --start-check-pos=# Start reading file at given offset.\n");
+#endif
puts("Check options (check is the default action for myisamchk):\n\
-c, --check Check table for errors\n\
-e, --extend-check Check the table VERY throughly. Only use this in\n\
extreme cases as myisamchk should normally be able to\n\
find out if the table is ok even without this switch\n\
- -F, --fast Check only tables that hasn't been closed properly\n\
+ -F, --fast Check only tables that haven't been closed properly.\n\
+ It also applies to other requested actions (e.g. --analyze\n\
+ will be ignored if the table is already analyzed).\n\
+ -f, --force Restart with '-r' if there are any errors in the table.\n\
+ States will be updated as with '--update-state'\n\
-C, --check-only-changed\n\
- Check only tables that has changed since last check\n\
- -f, --force Restart with -r if there are any errors in the table.\n\
- States will be updated as with --update-state\n\
+ Check only tables that have changed since last check.\n\
+ It also applies to other requested actions (e.g. --analyze\n\
+ will be ignored if the table is already analyzed).\n\
-i, --information Print statistics information about table that is checked\n\
- -m, --medium-check Faster than extended-check, but only finds 99.99% of\n\
+ -m, --medium-check Faster than extend-check, but only finds 99.99% of\n\
all errors. Should be good enough for most cases\n\
-U --update-state Mark tables as crashed if you find any errors\n\
-T, --read-only Don't mark table as checked\n");
- puts("Repair options (When using -r or -o) \n\
+ puts("Repair options (When using '-r' or '-o') \n\
-B, --backup Make a backup of the .MYD file as 'filename-time.BAK'\n\
+ --correct-checksum Correct checksum information for table.\n\
-D, --data-file-length=# Max length of data file (when recreating data\n\
file when it's full)\n\
-e, --extend-check Try to recover every possible row from the data file\n\
@@ -256,12 +384,14 @@ static void usage(void)
-k, --keys-used=# Tell MyISAM to update only some specific keys. # is a\n\
bit mask of which keys to use. This can be used to\n\
get faster inserts!\n\
- -l, --no-symlinks Do not follow symbolic links. Normally\n\
- myisamchk repairs the table a symlink points at.\n\
-r, --recover Can fix almost anything except unique keys that aren't\n\
unique.\n\
- -n, --sort-recover Force recovering with sorting even if the temporary\n\
+ -n, --sort-recover Forces recovering with sorting even if the temporary\n\
file would be very big.\n\
+ -p, --parallel-recover\n\
+ Uses the same technique as '-r' and '-n', but creates\n\
+ all the keys in parallel, in different threads.\n\
+ THIS IS ALPHA CODE. USE AT YOUR OWN RISK!\n\
-o, --safe-recover Uses old recovery method; Slower than '-r' but can\n\
handle a couple of cases where '-r' reports that it\n\
can't fix the data file.\n\
@@ -269,17 +399,18 @@ static void usage(void)
Directory where character sets are\n\
--set-character-set=name\n\
Change the character set used by the index\n\
- -t, --tmpdir=path Path for temporary files\n\
-q, --quick Faster repair by not modifying the data file.\n\
One can give a second '-q' to force myisamchk to\n\
- modify the original datafile in case of duplicate keys\n\
+ modify the original datafile in case of duplicate keys.\n\
+ NOTE: Tables where the data file is currupted can't be\n\
+ fixed with this option.\n\
-u, --unpack Unpack file packed with myisampack.\n\
");
puts("Other actions:\n\
-a, --analyze Analyze distribution of keys. Will make some joins in\n\
MySQL faster. You can check the calculated distribution\n\
- by using '--describe --verbose table_name'.\n\
+ by using '--description --verbose table_name'.\n\
-d, --description Prints some information about table.\n\
-A, --set-auto-increment[=value]\n\
Force auto_increment to start at this or higher value\n\
@@ -290,126 +421,183 @@ static void usage(void)
-R, --sort-records=#\n\
Sort records according to an index. This makes your\n\
data much more localized and may speed up things\n\
- (It may be VERY slow to do a sort the first time!)");
-
- print_defaults("my",load_default_groups);
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (i=0; changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- changeable_vars[i].name,
- *changeable_vars[i].varptr);
+ (It may be VERY slow to do a sort the first time!)\n\
+ -b, --block-search=#\n\
+ Find a record, a block at given offset belongs to.");
+
+ print_defaults("my", load_default_groups);
+ my_print_variables(my_long_options);
}
/* Read options */
-static void get_options(register int *argc,register char ***argv)
+static my_bool
+get_one_option(int optid,
+ const struct my_option *opt __attribute__((unused)),
+ char *argument)
{
- int c,option_index=0;
- uint old_testflag;
-
- load_defaults("my",load_default_groups,argc,argv);
- default_argv= *argv;
- set_all_changeable_vars(changeable_vars);
- if (isatty(fileno(stdout)))
- check_param.testflag|=T_WRITE_LOOP;
- while ((c=getopt_long(*argc,*argv,
- "aBcCdeifF?lqrmnosSTuUvVw#:b:D:k:O:R:A::t:",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'a':
+ switch (optid) {
+ case 'a':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_STATISTICS;
+ else
check_param.testflag|= T_STATISTICS;
- break;
- case 'A':
- if (optarg)
- check_param.auto_increment_value=strtoull(optarg,NULL,0);
- else
- check_param.auto_increment_value=0; /* Set to max used value */
- check_param.testflag|= T_AUTO_INC;
- break;
- case 'b':
- check_param.search_after_block=strtoul(optarg,NULL,10);
- break;
- case 'B':
+ break;
+ case 'A':
+ if (argument)
+ check_param.auto_increment_value= strtoull(argument, NULL, 0);
+ else
+ check_param.auto_increment_value= 0; /* Set to max used value */
+ check_param.testflag|= T_AUTO_INC;
+ break;
+ case 'b':
+ check_param.search_after_block= strtoul(argument, NULL, 10);
+ break;
+ case 'B':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_BACKUP_DATA;
+ else
check_param.testflag|= T_BACKUP_DATA;
- break;
- case 'c':
+ break;
+ case 'c':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_CHECK;
+ else
check_param.testflag|= T_CHECK;
- break;
- case 'C':
+ break;
+ case 'C':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~(T_CHECK | T_CHECK_ONLY_CHANGED);
+ else
check_param.testflag|= T_CHECK | T_CHECK_ONLY_CHANGED;
- break;
- case 'D':
- check_param.max_data_file_length=strtoll(optarg,NULL,10);
- break;
- case 's': /* silent */
+ break;
+ case 'D':
+ check_param.max_data_file_length=strtoll(argument, NULL, 10);
+ break;
+ case 's': /* silent */
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~(T_SILENT | T_VERY_SILENT);
+ else
+ {
if (check_param.testflag & T_SILENT)
- check_param.testflag|=T_VERY_SILENT;
+ check_param.testflag|= T_VERY_SILENT;
check_param.testflag|= T_SILENT;
check_param.testflag&= ~T_WRITE_LOOP;
- break;
- case 'w':
+ }
+ break;
+ case 'w':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_WAIT_FOREVER;
+ else
check_param.testflag|= T_WAIT_FOREVER;
- break;
- case 'd': /* description if isam-file */
+ break;
+ case 'd': /* description if isam-file */
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_DESCRIPT;
+ else
check_param.testflag|= T_DESCRIPT;
- break;
- case 'e': /* extend check */
+ break;
+ case 'e': /* extend check */
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_EXTEND;
+ else
check_param.testflag|= T_EXTEND;
- break;
- case 'i':
+ break;
+ case 'i':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_INFO;
+ else
check_param.testflag|= T_INFO;
- break;
- case 'f':
+ break;
+ case 'f':
+ if (argument == disabled_my_option)
+ {
+ check_param.tmpfile_createflag= O_RDWR | O_TRUNC | O_EXCL;
+ check_param.testflag&= ~(T_FORCE_CREATE | T_UPDATE_STATE);
+ }
+ else
+ {
check_param.tmpfile_createflag= O_RDWR | O_TRUNC;
check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE;
- break;
- case 'F':
- check_param.testflag|=T_FAST;
- break;
- case 'k':
- check_param.keys_in_use= (ulonglong) strtoll(optarg,NULL,10);
- break;
- case 'l':
- check_param.opt_follow_links=0;
- break;
- case 'm':
+ }
+ break;
+ case 'F':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_FAST;
+ else
+ check_param.testflag|= T_FAST;
+ break;
+ case 'k':
+ check_param.keys_in_use= (ulonglong) strtoll(argument, NULL, 10);
+ break;
+ case 'm':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_MEDIUM;
+ else
check_param.testflag|= T_MEDIUM; /* Medium check */
- break;
- case 'r': /* Repair table */
- check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
- break;
- case 'o':
- check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP;
- check_param.force_sort=0;
- my_disable_async_io=1; /* More safety */
- break;
- case 'n':
- check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
- check_param.force_sort=1;
- break;
- case 'q':
- check_param.opt_rep_quick++;
- break;
- case 'u':
+ break;
+ case 'r': /* Repair table */
+ check_param.testflag&= ~T_REP_ANY;
+ if (argument != disabled_my_option)
+ check_param.testflag|= T_REP_BY_SORT;
+ break;
+ case 'p':
+ check_param.testflag&= ~T_REP_ANY;
+ if (argument != disabled_my_option)
+ check_param.testflag|= T_REP_PARALLEL;
+ break;
+ case 'o':
+ check_param.testflag&= ~T_REP_ANY;
+ check_param.force_sort= 0;
+ if (argument != disabled_my_option)
+ {
+ check_param.testflag|= T_REP;
+ my_disable_async_io= 1; /* More safety */
+ }
+ break;
+ case 'n':
+ check_param.testflag&= ~T_REP_ANY;
+ if (argument == disabled_my_option)
+ check_param.force_sort= 0;
+ else
+ {
+ check_param.testflag|= T_REP_BY_SORT;
+ check_param.force_sort= 1;
+ }
+ break;
+ case 'q':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~(T_QUICK | T_FORCE_UNIQUENESS);
+ else
+ check_param.testflag|=
+ (check_param.testflag & T_QUICK) ? T_FORCE_UNIQUENESS : T_QUICK;
+ break;
+ case 'u':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~(T_UNPACK | T_REP_BY_SORT);
+ else
check_param.testflag|= T_UNPACK | T_REP_BY_SORT;
- break;
- case 'v': /* Verbose */
+ break;
+ case 'v': /* Verbose */
+ if (argument == disabled_my_option)
+ {
+ check_param.testflag&= ~T_VERBOSE;
+ check_param.verbose=0;
+ }
+ else
+ {
check_param.testflag|= T_VERBOSE;
check_param.verbose++;
- break;
- case 'O':
- if (set_changeable_var(optarg, changeable_vars))
- {
- usage();
- exit(1);
- }
- break;
- case 'R': /* Sort records */
- old_testflag=check_param.testflag;
+ }
+ break;
+ case 'R': /* Sort records */
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_SORT_RECORDS;
+ else
+ {
check_param.testflag|= T_SORT_RECORDS;
- check_param.opt_sort_key=(uint) atoi(optarg)-1;
+ check_param.opt_sort_key= (uint) atoi(argument) - 1;
if (check_param.opt_sort_key >= MI_MAX_KEY)
{
fprintf(stderr,
@@ -417,65 +605,100 @@ static void get_options(register int *argc,register char ***argv)
MI_MAX_KEY);
exit(1);
}
- break;
- case 'S': /* Sort index */
- old_testflag=check_param.testflag;
+ }
+ break;
+ case 'S': /* Sort index */
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_SORT_INDEX;
+ else
check_param.testflag|= T_SORT_INDEX;
- break;
- case 't':
- check_param.tmpdir=optarg;
- break;
- case 'T':
+ break;
+ case 'T':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_READONLY;
+ else
check_param.testflag|= T_READONLY;
- break;
- case 'U':
+ break;
+ case 'U':
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_UPDATE_STATE;
+ else
check_param.testflag|= T_UPDATE_STATE;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o,/tmp/myisamchk.trace");
- break;
- case 'V':
- print_version();
- exit(0);
- case OPT_CHARSETS_DIR:
- charsets_dir = optarg;
- break;
- case OPT_SET_CHARSET:
- set_charset_name=optarg;
- break;
+ break;
+ case '#':
+ if (argument == disabled_my_option)
+ {
+ DBUG_POP();
+ }
+ else
+ {
+ DBUG_PUSH(argument ? argument : "d:t:o,/tmp/myisamchk.trace");
+ }
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case OPT_CORRECT_CHECKSUM:
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~T_CALC_CHECKSUM;
+ else
+ check_param.testflag|= T_CALC_CHECKSUM;
+ break;
#ifdef DEBUG /* Only useful if debugging */
- case OPT_START_CHECK_POS:
- check_param.start_check_pos=strtoull(optarg,NULL,0);
- break;
+ case OPT_START_CHECK_POS:
+ check_param.start_check_pos= strtoull(argument, NULL, 0);
+ break;
#endif
- case '?':
- usage();
- exit(0);
- }
+ case 'H':
+ my_print_help(my_long_options);
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
}
- (*argc)-=optind;
- (*argv)+=optind;
+ return 0;
+}
+
+
+static void get_options(register int *argc,register char ***argv)
+{
+ int ho_error;
+
+ load_defaults("my", load_default_groups, argc, argv);
+ default_argv= *argv;
+ if (isatty(fileno(stdout)))
+ check_param.testflag|=T_WRITE_LOOP;
+
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ /* If using repair, then update checksum if one uses --update-state */
+ if ((check_param.testflag & T_UPDATE_STATE) &&
+ (check_param.testflag & T_REP_ANY))
+ check_param.testflag|= T_CALC_CHECKSUM;
+
if (*argc == 0)
{
usage();
exit(-1);
}
+
if ((check_param.testflag & T_UNPACK) &&
- (check_param.opt_rep_quick || (check_param.testflag & T_SORT_RECORDS)))
+ (check_param.testflag & (T_QUICK | T_SORT_RECORDS)))
{
VOID(fprintf(stderr,
"%s: --unpack can't be used with --quick or --sort-records\n",
- my_progname));
+ my_progname_short));
exit(1);
}
if ((check_param.testflag & T_READONLY) &&
(check_param.testflag &
- (T_REP_BY_SORT | T_REP | T_STATISTICS | T_AUTO_INC |
+ (T_REP_ANY | T_STATISTICS | T_AUTO_INC |
T_SORT_RECORDS | T_SORT_INDEX | T_FORCE_CREATE)))
{
VOID(fprintf(stderr,
"%s: Can't use --readonly when repairing or sorting\n",
- my_progname));
+ my_progname_short));
exit(1);
}
@@ -483,6 +706,7 @@ static void get_options(register int *argc,register char ***argv)
if (!(set_charset=get_charset_by_name(set_charset_name, MYF(MY_WME))))
exit(1);
+ myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
return;
} /* get options */
@@ -492,11 +716,10 @@ static void get_options(register int *argc,register char ***argv)
static int myisamchk(MI_CHECK *param, my_string filename)
{
int error,lock_type,recreate;
- int rep_quick= param->opt_rep_quick;
+ int rep_quick= param->testflag & (T_QUICK | T_FORCE_UNIQUENESS);
uint raid_chunks;
MI_INFO *info;
File datafile;
- char fixed_name[FN_REFLEN];
char llbuff[22],llbuff2[22];
my_bool state_updated=0;
MYISAM_SHARE *share;
@@ -521,7 +744,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
case HA_ERR_CRASHED:
mi_check_print_error(param,"'%s' doesn't have a correct index definition. You need to recreate it before you can do a repair",filename);
break;
- case HA_ERR_WRONG_TABLE_DEF:
+ case HA_ERR_NOT_A_TABLE:
mi_check_print_error(param,"'%s' is not a MyISAM-table",filename);
break;
case HA_ERR_CRASHED_ON_USAGE:
@@ -554,11 +777,12 @@ static int myisamchk(MI_CHECK *param, my_string filename)
}
share=info->s;
share->options&= ~HA_OPTION_READ_ONLY_DATA; /* We are modifing it */
+ share->tot_locks-= share->r_locks;
share->r_locks=0;
raid_chunks=share->base.raid_chunks;
/*
- Skipp the checking of the file if:
+ Skip the checking of the file if:
We are using --fast and the table is closed properly
We are using --check-only-changed-tables and the table hasn't changed
*/
@@ -566,21 +790,24 @@ static int myisamchk(MI_CHECK *param, my_string filename)
{
my_bool need_to_check= mi_is_crashed(info) || share->state.open_count != 0;
- if ((param->testflag & (T_REP_BY_SORT | T_REP | T_SORT_RECORDS)) &&
+ if ((param->testflag & (T_REP_ANY | T_SORT_RECORDS)) &&
((share->state.changed & (STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR) ||
!(param->testflag & T_CHECK_ONLY_CHANGED))))
need_to_check=1;
- if ((param->testflag & T_STATISTICS) &&
- (share->state.changed & STATE_NOT_ANALYZED))
- need_to_check=1;
- if ((param->testflag & T_SORT_INDEX) &&
- (share->state.changed & STATE_NOT_SORTED_PAGES))
- need_to_check=1;
- if ((param->testflag & T_REP_BY_SORT) &&
- (share->state.changed & STATE_NOT_OPTIMIZED_KEYS))
- need_to_check=1;
+ if (info->s->base.keys && info->state->records)
+ {
+ if ((param->testflag & T_STATISTICS) &&
+ (share->state.changed & STATE_NOT_ANALYZED))
+ need_to_check=1;
+ if ((param->testflag & T_SORT_INDEX) &&
+ (share->state.changed & STATE_NOT_SORTED_PAGES))
+ need_to_check=1;
+ if ((param->testflag & T_REP_BY_SORT) &&
+ (share->state.changed & STATE_NOT_OPTIMIZED_KEYS))
+ need_to_check=1;
+ }
if ((param->testflag & T_CHECK_ONLY_CHANGED) &&
(share->state.changed & (STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR)))
@@ -598,7 +825,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
DBUG_RETURN(0);
}
}
- if ((param->testflag & (T_REP_BY_SORT | T_REP | T_STATISTICS |
+ if ((param->testflag & (T_REP_ANY | T_STATISTICS |
T_SORT_RECORDS | T_SORT_INDEX)) &&
(((param->testflag & T_UNPACK) &&
share->data_file_type == COMPRESSED_RECORD) ||
@@ -610,11 +837,12 @@ static int myisamchk(MI_CHECK *param, my_string filename)
(((ulonglong) 1L << share->base.keys)-1)) ||
test_if_almost_full(info) ||
info->s->state.header.file_version[3] != myisam_file_magic[3] ||
- (set_charset && set_charset->number != share->state.header.language)))
+ (set_charset && set_charset->number != share->state.header.language) ||
+ myisam_block_size != MI_KEY_BLOCK_LENGTH))
{
if (set_charset)
- check_param.language=set_charset->number;
- if (recreate_table(&check_param, &info,filename))
+ param->language=set_charset->number;
+ if (recreate_table(param, &info,filename))
{
VOID(fprintf(stderr,
"MyISAM-table '%s' is not fixed because of errors\n",
@@ -622,15 +850,15 @@ static int myisamchk(MI_CHECK *param, my_string filename)
return(-1);
}
recreate=1;
- if (!(param->testflag & (T_REP | T_REP_BY_SORT)))
+ if (!(param->testflag & T_REP_ANY))
{
param->testflag|=T_REP_BY_SORT; /* if only STATISTICS */
if (!(param->testflag & T_SILENT))
printf("- '%s' has old table-format. Recreating index\n",filename);
- if (!rep_quick)
- rep_quick=1;
+ rep_quick|=T_QUICK;
}
share=info->s;
+ share->tot_locks-= share->r_locks;
share->r_locks=0;
}
@@ -639,12 +867,12 @@ static int myisamchk(MI_CHECK *param, my_string filename)
param->total_files++;
param->total_records+=info->state->records;
param->total_deleted+=info->state->del;
- descript(&check_param, info, filename);
+ descript(param, info, filename);
}
else
{
- if (share->fulltext_index)
- ft_init_stopwords(ft_precompiled_stopwords); /* SerG */
+ if (share->fulltext_index && !stopwords_inited++)
+ ft_init_stopwords();
if (!(param->testflag & T_READONLY))
lock_type = F_WRLCK; /* table is changed */
@@ -659,14 +887,17 @@ static int myisamchk(MI_CHECK *param, my_string filename)
param->error_printed=0;
goto end2;
}
- share->w_locks++; /* Mark for writeinfo */
- info->lock_type= F_EXTRA_LCK; /* Simulate as locked */
- info->tmp_lock_type=lock_type;
+ /*
+ _mi_readinfo() has locked the table.
+ We mark the table as locked (without doing file locks) to be able to
+ use functions that only works on locked tables (like row caching).
+ */
+ mi_lock_database(info, F_EXTRA_LCK);
datafile=info->dfile;
- if (param->testflag & (T_REP+T_REP_BY_SORT+T_SORT_RECORDS+T_SORT_INDEX))
+ if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX))
{
- if (param->testflag & (T_REP+T_REP_BY_SORT))
+ if (param->testflag & T_REP_ANY)
{
ulonglong tmp=share->state.key_map;
share->state.key_map= (((ulonglong) 1 << share->base.keys)-1)
@@ -674,11 +905,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (tmp != share->state.key_map)
info->update|=HA_STATE_CHANGED;
}
- VOID(fn_format(fixed_name,filename,"",MI_NAME_IEXT,
- 4+ (param->opt_follow_links ? 16 : 0)));
-
- if (rep_quick && chk_del(&check_param, info,
- param->testflag & ~T_VERBOSE))
+ if (rep_quick && chk_del(param, info, param->testflag & ~T_VERBOSE))
{
if (param->testflag & T_FORCE_CREATE)
{
@@ -694,18 +921,21 @@ static int myisamchk(MI_CHECK *param, my_string filename)
}
if (!error)
{
- if ((param->testflag & T_REP_BY_SORT) &&
+ if ((param->testflag & (T_REP_BY_SORT | T_REP_PARALLEL)) &&
(share->state.key_map ||
(rep_quick && !param->keys_in_use && !recreate)) &&
mi_test_if_sort_rep(info, info->state->records,
info->s->state.key_map,
- check_param.force_sort))
+ param->force_sort))
{
- error=mi_repair_by_sort(&check_param,info,fixed_name,rep_quick);
+ if (param->testflag & T_REP_BY_SORT)
+ error=mi_repair_by_sort(param,info,filename,rep_quick);
+ else
+ error=mi_repair_parallel(param,info,filename,rep_quick);
state_updated=1;
}
- else if (param->testflag & (T_REP | T_REP_BY_SORT))
- error=mi_repair(&check_param, info,fixed_name,rep_quick);
+ else if (param->testflag & T_REP_ANY)
+ error=mi_repair(param, info,filename,rep_quick);
}
if (!error && param->testflag & T_SORT_RECORDS)
{
@@ -717,10 +947,10 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (param->out_flag & O_NEW_DATA)
{ /* Change temp file to org file */
VOID(my_close(info->dfile,MYF(MY_WME))); /* Close new file */
- error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT,
+ error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks,
MYF(0));
- if (mi_open_datafile(info,info->s))
+ if (mi_open_datafile(info,info->s, -1))
error=1;
param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */
param->read_cache.file=info->dfile;
@@ -731,27 +961,28 @@ static int myisamchk(MI_CHECK *param, my_string filename)
uint key;
/*
We can't update the index in mi_sort_records if we have a
- prefix compressed index
+ prefix compressed or fulltext index
*/
my_bool update_index=1;
for (key=0 ; key < share->base.keys; key++)
- if (share->keyinfo[key].flag & HA_BINARY_PACK_KEY)
+ if (share->keyinfo[key].flag & (HA_BINARY_PACK_KEY|HA_FULLTEXT))
update_index=0;
- error=mi_sort_records(param,info,fixed_name,param->opt_sort_key,
+ error=mi_sort_records(param,info,filename,param->opt_sort_key,
+ /* what is the following parameter for ? */
(my_bool) !(param->testflag & T_REP),
update_index);
datafile=info->dfile; /* This is now locked */
if (!error && !update_index)
{
- if (check_param.verbose)
+ if (param->verbose)
puts("Table had a compressed index; We must now recreate the index");
- error=mi_repair_by_sort(&check_param,info,fixed_name,1);
+ error=mi_repair_by_sort(param,info,filename,1);
}
}
}
if (!error && param->testflag & T_SORT_INDEX)
- error=mi_sort_index(param,info,fixed_name);
+ error=mi_sort_index(param,info,filename);
if (!error)
share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR);
@@ -786,7 +1017,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
!(param->testflag & (T_FAST | T_FORCE_CREATE)))
{
if (param->testflag & (T_EXTEND | T_MEDIUM))
- VOID(init_key_cache(param->use_buffers,(uint) NEAD_MEM));
+ VOID(init_key_cache(param->use_buffers));
VOID(init_io_cache(&param->read_cache,datafile,
(uint) param->read_buffer_length,
READ_CACHE,
@@ -820,8 +1051,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
}
}
if ((param->testflag & T_AUTO_INC) ||
- ((param->testflag & (T_REP | T_REP_BY_SORT)) &&
- info->s->base.auto_key))
+ ((param->testflag & T_REP_ANY) && info->s->base.auto_key))
update_auto_increment_key(param, info,
(my_bool) !test(param->testflag & T_AUTO_INC));
@@ -830,7 +1060,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if (info->update & HA_STATE_CHANGED && ! (param->testflag & T_READONLY))
error|=update_state_info(param, info,
UPDATE_OPEN_COUNT |
- (((param->testflag & (T_REP | T_REP_BY_SORT)) ?
+ (((param->testflag & T_REP_ANY) ?
UPDATE_TIME : 0) |
(state_updated ? UPDATE_STAT : 0) |
((param->testflag & T_SORT_RECORDS) ?
@@ -838,7 +1068,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
VOID(lock_file(param, share->kfile,0L,F_UNLCK,"indexfile",filename));
info->update&= ~HA_STATE_CHANGED;
}
- share->w_locks--;
+ mi_lock_database(info, F_UNLCK);
end2:
if (mi_close(info))
{
@@ -848,25 +1078,25 @@ end2:
if (error == 0)
{
if (param->out_flag & O_NEW_DATA)
- error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT,
+ error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks,
((param->testflag & T_BACKUP_DATA) ?
MYF(MY_REDEL_MAKE_BACKUP) : MYF(0)));
if (param->out_flag & O_NEW_INDEX)
- error|=change_to_newfile(fixed_name,MI_NAME_IEXT,INDEX_TMP_EXT,0,
+ error|=change_to_newfile(filename,MI_NAME_IEXT,INDEX_TMP_EXT,0,
MYF(0));
}
VOID(fflush(stdout)); VOID(fflush(stderr));
if (param->error_printed)
{
- if (param->testflag & (T_REP+T_REP_BY_SORT+T_SORT_RECORDS+T_SORT_INDEX))
+ if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX))
{
VOID(fprintf(stderr,
"MyISAM-table '%s' is not fixed because of errors\n",
filename));
- if (check_param.testflag & (T_REP_BY_SORT | T_REP))
+ if (param->testflag & T_REP_ANY)
VOID(fprintf(stderr,
- "Try fixing it by using the --safe-recover (-o) or the --force (-f) option\n"));
+ "Try fixing it by using the --safe-recover (-o), the --force (-f) option or by not using the --quick (-q) flag\n"));
}
else if (!(param->error_printed & 2) &&
!(param->testflag & T_FORCE_CREATE))
@@ -875,7 +1105,7 @@ end2:
filename));
}
else if (param->warning_printed &&
- ! (param->testflag & (T_REP+T_REP_BY_SORT+T_SORT_RECORDS+T_SORT_INDEX+
+ ! (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX |
T_FORCE_CREATE)))
VOID(fprintf(stderr, "MyISAM-table '%s' is usable but should be fixed\n",
filename));
@@ -1155,7 +1385,7 @@ static int mi_sort_records(MI_CHECK *param,
register MI_INFO *info, my_string name,
uint sort_key,
my_bool write_info,
- my_bool update_index)
+ my_bool update_index)
{
int got_error;
uint key;
@@ -1165,11 +1395,14 @@ static int mi_sort_records(MI_CHECK *param,
ha_rows old_record_count;
MYISAM_SHARE *share=info->s;
char llbuff[22],llbuff2[22];
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO sort_info;
+ MI_SORT_PARAM sort_param;
DBUG_ENTER("sort_records");
- bzero((char*) sort_info,sizeof(*sort_info));
- sort_info->param=param;
+ bzero((char*)&sort_info,sizeof(sort_info));
+ bzero((char*)&sort_param,sizeof(sort_param));
+ sort_param.sort_info=&sort_info;
+ sort_info.param=param;
keyinfo= &share->keyinfo[sort_key];
got_error=1;
temp_buff=0;
@@ -1177,10 +1410,24 @@ static int mi_sort_records(MI_CHECK *param,
if (!(((ulonglong) 1 << sort_key) & share->state.key_map))
{
- mi_check_print_error(param,"Can't sort table '%s' on key %d; No such key",
+ mi_check_print_warning(param,
+ "Can't sort table '%s' on key %d; No such key",
name,sort_key+1);
param->error_printed=0;
- DBUG_RETURN(-1);
+ DBUG_RETURN(0); /* Nothing to do */
+ }
+ if (keyinfo->flag & HA_FULLTEXT)
+ {
+ mi_check_print_warning(param,"Can't sort table '%s' on FULLTEXT key %d",
+ name,sort_key+1);
+ param->error_printed=0;
+ DBUG_RETURN(0); /* Nothing to do */
+ }
+ if (share->data_file_type == COMPRESSED_RECORD)
+ {
+ mi_check_print_warning(param,"Can't sort read-only table '%s'", name);
+ param->error_printed=0;
+ DBUG_RETURN(0); /* Nothing to do */
}
if (!(param->testflag & T_SILENT))
{
@@ -1193,7 +1440,7 @@ static int mi_sort_records(MI_CHECK *param,
if (share->state.key_root[sort_key] == HA_OFFSET_ERROR)
DBUG_RETURN(0); /* Nothing to do */
- init_key_cache(param->use_buffers,NEAD_MEM);
+ init_key_cache(param->use_buffers);
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
WRITE_CACHE,share->pack.header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
@@ -1205,13 +1452,15 @@ static int mi_sort_records(MI_CHECK *param,
mi_check_print_error(param,"Not enough memory for key block");
goto err;
}
- if (!(sort_info->record=(byte*) my_malloc((uint) share->base.pack_reclength,
+ if (!(sort_param.record=(byte*) my_malloc((uint) share->base.pack_reclength,
MYF(0))))
{
mi_check_print_error(param,"Not enough memory for record");
goto err;
}
- new_file=my_raid_create(fn_format(param->temp_filename,name,"",
+ fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32);
+ new_file=my_raid_create(fn_format(param->temp_filename,
+ param->temp_filename,"",
DATA_TMP_EXT,2+4),
0,param->tmpfile_createflag,
share->base.raid_type,
@@ -1245,18 +1494,19 @@ static int mi_sort_records(MI_CHECK *param,
}
/* Setup param for sort_write_record */
- sort_info->info=info;
- sort_info->new_data_file_type=share->data_file_type;
- sort_info->fix_datafile=1;
- sort_info->filepos=share->pack.header_length;
+ sort_info.info=info;
+ sort_info.new_data_file_type=share->data_file_type;
+ sort_param.fix_datafile=1;
+ sort_param.master=1;
+ sort_param.filepos=share->pack.header_length;
old_record_count=info->state->records;
info->state->records=0;
- if (sort_info->new_data_file_type != COMPRESSED_RECORD)
+ if (sort_info.new_data_file_type != COMPRESSED_RECORD)
share->state.checksum=0;
- if (sort_record_index(param, info,keyinfo,share->state.key_root[sort_key],
+ if (sort_record_index(&sort_param,info,keyinfo,share->state.key_root[sort_key],
temp_buff, sort_key,new_file,update_index) ||
- write_data_suffix(param, info) ||
+ write_data_suffix(&sort_info,1) ||
flush_io_cache(&info->rec_cache))
goto err;
@@ -1274,7 +1524,7 @@ static int mi_sort_records(MI_CHECK *param,
info->state->del=0;
info->state->empty=0;
share->state.dellink= HA_OFFSET_ERROR;
- info->state->data_file_length=sort_info->filepos;
+ info->state->data_file_length=sort_param.filepos;
share->state.split=info->state->records; /* Only hole records */
share->state.version=(ulong) time((time_t*) 0);
@@ -1298,11 +1548,11 @@ err:
{
my_afree((gptr) temp_buff);
}
- my_free(sort_info->record,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
VOID(end_io_cache(&info->rec_cache));
- my_free(sort_info->buff,MYF(MY_ALLOW_ZERO_PTR));
- sort_info->buff=0;
+ my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
+ sort_info.buff=0;
share->state.sortkey=sort_key;
DBUG_RETURN(flush_blocks(param, share->kfile) | got_error);
} /* sort_records */
@@ -1310,7 +1560,8 @@ err:
/* Sort records recursive using one index */
-static int sort_record_index(MI_CHECK *param,MI_INFO *info, MI_KEYDEF *keyinfo,
+static int sort_record_index(MI_SORT_PARAM *sort_param,MI_INFO *info,
+ MI_KEYDEF *keyinfo,
my_off_t page, uchar *buff, uint sort_key,
File new_file,my_bool update_index)
{
@@ -1319,7 +1570,8 @@ static int sort_record_index(MI_CHECK *param,MI_INFO *info, MI_KEYDEF *keyinfo,
my_off_t next_page,rec_pos;
uchar lastkey[MI_MAX_KEY_BUFF];
char llbuff[22];
- SORT_INFO *sort_info= &param->sort_info;
+ SORT_INFO *sort_info= sort_param->sort_info;
+ MI_CHECK *param=sort_info->param;
DBUG_ENTER("sort_record_index");
nod_flag=mi_test_if_nod(buff);
@@ -1350,7 +1602,7 @@ static int sort_record_index(MI_CHECK *param,MI_INFO *info, MI_KEYDEF *keyinfo,
llstr(next_page,llbuff));
goto err;
}
- if (sort_record_index(param, info,keyinfo,next_page,temp_buff,sort_key,
+ if (sort_record_index(sort_param, info,keyinfo,next_page,temp_buff,sort_key,
new_file, update_index))
goto err;
}
@@ -1361,23 +1613,23 @@ static int sort_record_index(MI_CHECK *param,MI_INFO *info, MI_KEYDEF *keyinfo,
break;
rec_pos= _mi_dpos(info,0,lastkey+key_length);
- if ((*info->s->read_rnd)(info,sort_info->record,rec_pos,0))
+ if ((*info->s->read_rnd)(info,sort_param->record,rec_pos,0))
{
mi_check_print_error(param,"%d when reading datafile",my_errno);
goto err;
}
- if (rec_pos != sort_info->filepos && update_index)
+ if (rec_pos != sort_param->filepos && update_index)
{
_mi_dpointer(info,keypos-nod_flag-info->s->rec_reflength,
- sort_info->filepos);
- if (movepoint(info,sort_info->record,rec_pos,sort_info->filepos,
+ sort_param->filepos);
+ if (movepoint(info,sort_param->record,rec_pos,sort_param->filepos,
sort_key))
{
mi_check_print_error(param,"%d when updating key-pointers",my_errno);
goto err;
}
}
- if (sort_write_record(sort_info))
+ if (sort_write_record(sort_param))
goto err;
}
/* Clear end of block to get better compression if the table is backuped */
@@ -1423,13 +1675,13 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
if (!param->warning_printed && !param->error_printed)
{
if (param->testflag & T_SILENT)
- fprintf(stderr,"%s: MyISAM file %s\n",my_progname,
+ fprintf(stderr,"%s: MyISAM file %s\n",my_progname_short,
param->isam_file_name);
param->out_flag|= O_DATA_LOST;
}
param->warning_printed=1;
va_start(args,fmt);
- fprintf(stderr,"%s: warning: ",my_progname);
+ fprintf(stderr,"%s: warning: ",my_progname_short);
VOID(vfprintf(stderr, fmt, args));
VOID(fputc('\n',stderr));
fflush(stderr);
@@ -1449,12 +1701,12 @@ void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
if (!param->warning_printed && !param->error_printed)
{
if (param->testflag & T_SILENT)
- fprintf(stderr,"%s: ISAM file %s\n",my_progname,param->isam_file_name);
+ fprintf(stderr,"%s: MyISAM file %s\n",my_progname_short,param->isam_file_name);
param->out_flag|= O_DATA_LOST;
}
param->error_printed|=1;
va_start(args,fmt);
- fprintf(stderr,"%s: error: ",my_progname);
+ fprintf(stderr,"%s: error: ",my_progname_short);
VOID(vfprintf(stderr, fmt, args));
VOID(fputc('\n',stderr));
fflush(stderr);
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index 260e9665b31..51a2dd3a2b3 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,6 +18,7 @@
#include "myisam.h" /* Structs & some defines */
#include "myisampack.h" /* packing of keys */
+#include <my_tree.h>
#ifdef THREAD
#include <my_pthread.h>
#include <thr_lock.h>
@@ -37,7 +38,7 @@ typedef struct st_mi_status_info
my_off_t key_empty; /* lost space in indexfile */
my_off_t key_file_length;
my_off_t data_file_length;
-} MI_STATUS_INFO;
+} MI_STATUS_INFO;
typedef struct st_mi_state_info
{
@@ -54,7 +55,8 @@ typedef struct st_mi_state_info
uchar uniques; /* number of UNIQUE definitions */
uchar language; /* Language for indexes */
uchar max_block_size; /* max keyblock size */
- uchar not_used[2]; /* To align to 8 */
+ uchar fulltext_keys; /* reserved for 4.1 */
+ uchar not_used; /* To align to 8 */
} header;
MI_STATUS_INFO state;
@@ -65,8 +67,10 @@ typedef struct st_mi_state_info
ulong unique; /* Unique number for this process */
ulong update_count; /* Updated for each write lock */
ulong status;
+ ulong *rec_per_key_part;
my_off_t *key_root; /* Start of key trees */
my_off_t *key_del; /* delete links for trees */
+ my_off_t rec_per_key_rows; /* Rows when calculating rec_per_key */
ulong sec_index_changed; /* Updated when new sec_index */
ulong sec_index_used; /* which extra index are in use */
@@ -79,8 +83,6 @@ typedef struct st_mi_state_info
uint sortkey; /* sorted by this key (not used) */
uint open_count;
uint8 changed; /* Changed since myisamchk */
- my_off_t rec_per_key_rows; /* Rows when calculating rec_per_key */
- ulong *rec_per_key_part;
/* the following isn't saved on disk */
uint state_diff_length; /* Should be 0 */
@@ -159,42 +161,45 @@ typedef struct st_mi_isam_share { /* Shared between opens */
MI_COLUMNDEF *rec; /* Pointer to field information */
MI_PACK pack; /* Data about packed records */
MI_BLOB *blobs; /* Pointer to blobs */
- char *filename; /* Name of indexfile */
+ char *unique_file_name; /* realpath() of index file */
+ char *data_file_name, /* Resolved path names from symlinks */
+ *index_file_name;
byte *file_map; /* mem-map of file if possible */
+ MI_DECODE_TREE *decode_trees;
+ uint16 *decode_tables;
+ int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
+ int (*write_record)(struct st_myisam_info*, const byte*);
+ int (*update_record)(struct st_myisam_info*, my_off_t, const byte*);
+ int (*delete_record)(struct st_myisam_info*);
+ int (*read_rnd)(struct st_myisam_info*, byte*, my_off_t, my_bool);
+ int (*compare_record)(struct st_myisam_info*, const byte *);
+ ha_checksum (*calc_checksum)(struct st_myisam_info*, const byte *);
+ int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *,
+ const byte *record, my_off_t pos);
+ invalidator_by_filename invalidator; /* query cache invalidator */
ulong this_process; /* processid */
ulong last_process; /* For table-change-check */
ulong last_version; /* Version on start */
ulong options; /* Options used */
+ ulong min_pack_length; /* Theese are used by packed data */
+ ulong max_pack_length;
+ ulong state_diff_length;
uint rec_reflength; /* rec_reflength in use now */
- int kfile; /* Shared keyfile */
- int data_file; /* Shared data file */
+ File kfile; /* Shared keyfile */
+ File data_file; /* Shared data file */
int mode; /* mode of file on open */
uint reopen; /* How many times reopened */
- uint w_locks,r_locks; /* Number of read/write locks */
+ uint w_locks,r_locks,tot_locks; /* Number of read/write locks */
uint blocksize; /* blocksize of keyfile */
- ulong min_pack_length; /* Theese are used by packed data */
- ulong max_pack_length;
- ulong state_diff_length;
+ myf write_flag;
+ int rnd; /* rnd-counter */
+ enum data_file_type data_file_type;
my_bool changed, /* If changed since lock */
global_changed, /* If changed since open */
not_flushed,
temporary,delay_key_write,
concurrent_insert,
fulltext_index;
- myf write_flag;
- int rnd; /* rnd-counter */
- MI_DECODE_TREE *decode_trees;
- uint16 *decode_tables;
- enum data_file_type data_file_type;
- int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
- int (*write_record)(struct st_myisam_info*, const byte*);
- int (*update_record)(struct st_myisam_info*, my_off_t, const byte*);
- int (*delete_record)(struct st_myisam_info*);
- int (*read_rnd)(struct st_myisam_info*, byte*, my_off_t, my_bool);
- int (*compare_record)(struct st_myisam_info*, const byte *);
- ha_checksum (*calc_checksum)(struct st_myisam_info*, const byte *);
- int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *,
- const byte *record, my_off_t pos);
#ifdef THREAD
THR_LOCK lock;
pthread_mutex_t intern_lock; /* Locking for use with _locking */
@@ -208,20 +213,25 @@ typedef uint mi_bit_type;
typedef struct st_mi_bit_buff { /* Used for packing of record */
mi_bit_type current_byte;
uint bits;
- uchar *pos,*end,*blob_pos;
+ uchar *pos,*end,*blob_pos,*blob_end;
uint error;
} MI_BIT_BUFF;
-
struct st_myisam_info {
MYISAM_SHARE *s; /* Shared between open:s */
MI_STATUS_INFO *state,save_state;
MI_BLOB *blobs; /* Pointer to blobs */
- int dfile; /* The datafile */
- MI_BIT_BUFF bit_buff;
- uint opt_flag; /* Optim. for space/speed */
- uint update; /* If file changed since open */
+ MI_BIT_BUFF bit_buff;
+ /* accumulate indexfile changes between write's */
+ TREE *bulk_insert;
char *filename; /* parameter to open filename */
+ uchar *buff, /* Temp area for key */
+ *lastkey,*lastkey2; /* Last used search key */
+ byte *rec_buff; /* Tempbuff for recordpack */
+ uchar *int_keypos, /* Save position for next/previous */
+ *int_maxpos; /* -""- */
+ int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
+ invalidator_by_filename invalidator; /* query cache invalidator */
ulong this_unique; /* uniq filenumber or thread */
ulong last_unique; /* last unique number */
ulong this_loop; /* counter for this open */
@@ -230,20 +240,17 @@ struct st_myisam_info {
nextpos; /* Position to next record */
my_off_t save_lastpos;
my_off_t pos; /* Intern variable */
- ha_checksum checksum;
- ulong packed_length,blob_length; /* Length of found, packed record */
- uint alloced_rec_buff_length; /* Max recordlength malloced */
- uchar *buff, /* Temp area for key */
- *lastkey,*lastkey2; /* Last used search key */
- byte *rec_buff, /* Tempbuff for recordpack */
- *rec_alloc; /* Malloced area for record */
- uchar *int_keypos, /* Save position for next/previous */
- *int_maxpos; /* -""- */
- uint32 int_keytree_version; /* -""- */
- uint int_nod_flag; /* -""- */
my_off_t last_keypage; /* Last key page read */
my_off_t last_search_keypage; /* Last keypage when searching */
my_off_t dupp_key_pos;
+ ha_checksum checksum;
+ /* QQ: the folloing two xxx_length fields should be removed,
+ as they are not compatible with parallel repair */
+ ulong packed_length,blob_length; /* Length of found, packed record */
+ int dfile; /* The datafile */
+ uint opt_flag; /* Optim. for space/speed */
+ uint update; /* If file changed since open */
+ uint int_nod_flag; /* -""- */
int lastinx; /* Last used index */
uint lastkey_length; /* Length of key in lastkey */
uint last_rkey_length; /* Last length in mi_rkey() */
@@ -254,15 +261,15 @@ struct st_myisam_info {
uint data_changed; /* Somebody has changed data */
uint save_update; /* When using KEY_READ */
int save_lastinx;
+ uint32 int_keytree_version; /* -""- */
+ LIST open_list;
+ IO_CACHE rec_cache; /* When cacheing records */
+ myf lock_wait; /* is 0 or MY_DONT_WAIT */
my_bool was_locked; /* Was locked in panic */
my_bool quick_mode;
my_bool page_changed; /* If info->buff can't be used for rnext */
my_bool buff_used; /* If info->buff has to be reread for rnext */
my_bool use_packed_key; /* For MYISAMMRG */
- myf lock_wait; /* is 0 or MY_DONT_WAIT */
- int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
- LIST open_list;
- IO_CACHE rec_cache; /* When cacheing records */
#ifdef THREAD
THR_LOCK_DATA lock;
#endif
@@ -285,7 +292,7 @@ struct st_myisam_info {
#define STATE_CHANGED 1
#define STATE_CRASHED 2
-#define STATE_CRASHED_ON_REPAIR 4
+#define STATE_CRASHED_ON_REPAIR 4
#define STATE_NOT_ANALYZED 8
#define STATE_NOT_OPTIMIZED_KEYS 16
#define STATE_NOT_SORTED_PAGES 32
@@ -352,7 +359,9 @@ struct st_myisam_info {
#define MI_DYN_MAX_BLOCK_LENGTH ((1L << 24)-4L)
#define MI_DYN_MAX_ROW_LENGTH (MI_DYN_MAX_BLOCK_LENGTH - MI_SPLIT_LENGTH)
#define MI_DYN_ALIGN_SIZE 4 /* Align blocks on this */
-#define MI_MAX_DYN_HEADER_BYTE 12 /* max header byte for dynamic rows */
+#define MI_MAX_DYN_HEADER_BYTE 13 /* max header byte for dynamic rows */
+#define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1)))
+#define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint32))
#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */
@@ -361,12 +370,13 @@ struct st_myisam_info {
#define PACK_TYPE_ZERO_FILL 4
#define MI_FOUND_WRONG_KEY 32738 /* Impossible value from _mi_key_cmp */
-#define MI_KEY_BLOCK_LENGTH 1024 /* Min key block length */
-#define MI_MAX_KEY_BLOCK_LENGTH 8192
-#define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_KEY_BLOCK_LENGTH)
-#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) ((((key_length+data_pointer+key_pointer)*4+key_pointer+2)/MI_KEY_BLOCK_LENGTH+1)*MI_KEY_BLOCK_LENGTH)
-#define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */
-#define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */
+#define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH)
+#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) ((((key_length+data_pointer+key_pointer)*4+key_pointer+2)/myisam_block_size+1)*myisam_block_size)
+#define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */
+#define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */
+
+#define MI_MIN_SIZE_BULK_INSERT_TREE 16384 /* this is per key */
+#define MI_MIN_ROWS_TO_USE_BULK_INSERT 100
/* The UNIQUE check is done with a hashed long key */
@@ -473,6 +483,9 @@ extern int _mi_bin_search(struct st_myisam_info *info,MI_KEYDEF *keyinfo,
extern int _mi_seq_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page,
uchar *key,uint key_len,uint comp_flag,
uchar **ret_pos,uchar *buff, my_bool *was_last_key);
+extern int _mi_prefix_search(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page,
+ uchar *key,uint key_len,uint comp_flag,
+ uchar **ret_pos,uchar *buff, my_bool *was_last_key);
extern int _mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint ,
my_bool);
extern my_off_t _mi_kpos(uint nod_flag,uchar *after_key);
@@ -494,6 +507,8 @@ extern uchar *_mi_get_last_key(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *keypos,
extern uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
uchar *key, uchar *keypos, uint *return_key_length);
extern uint _mi_keylength(MI_KEYDEF *keyinfo,uchar *key);
+extern uint _mi_keylength_part(MI_KEYDEF *keyinfo, register uchar *key,
+ MI_KEYSEG *end);
extern uchar *_mi_move_key(MI_KEYDEF *keyinfo,uchar *to,uchar *from);
extern int _mi_search_next(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
uint key_length,uint nextflag,my_off_t pos);
@@ -508,15 +523,23 @@ extern my_off_t _mi_new(MI_INFO *info,MI_KEYDEF *keyinfo);
extern uint _mi_make_key(MI_INFO *info,uint keynr,uchar *key,
const byte *record,my_off_t filepos);
extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old,
- uint key_length);
+ uint key_length, MI_KEYSEG **last_used_keyseg);
extern int _mi_read_key_record(MI_INFO *info,my_off_t filepos,byte *buf);
extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos,
uint length,int re_read_if_possibly);
extern void update_auto_increment(MI_INFO *info,const byte *record);
-extern byte *mi_fix_rec_buff_for_blob(MI_INFO *info,ulong blob_length);
+
+extern byte *mi_alloc_rec_buff(MI_INFO *,ulong, byte**);
+#define mi_get_rec_buff_ptr(info,buf) \
+ ((((info)->s->options & HA_OPTION_PACK_RECORD) && (buf)) ? \
+ (buf) - MI_REC_BUFF_OFFSET : (buf))
+#define mi_get_rec_buff_len(info,buf) \
+ (*((uint32 *)(mi_get_rec_buff_ptr(info,buf))))
+
extern ulong _mi_rec_unpack(MI_INFO *info,byte *to,byte *from,
ulong reclength);
-extern my_bool _mi_rec_check(MI_INFO *info,const char *from);
+extern my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *packpos,
+ ulong reclength);
extern int _mi_write_part_record(MI_INFO *info,my_off_t filepos,ulong length,
my_off_t next_filepos,byte **record,
ulong *reclength,int *flag);
@@ -528,6 +551,8 @@ extern int _mi_read_rnd_pack_record(MI_INFO*, byte *,my_off_t, my_bool);
extern int _mi_pack_rec_unpack(MI_INFO *info,byte *to,byte *from,
ulong reclength);
extern ulonglong mi_safe_mul(ulonglong a,ulonglong b);
+extern int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
+ const byte *oldrec, const byte *newrec, my_off_t pos);
struct st_sort_info;
@@ -554,7 +579,7 @@ typedef struct st_mi_block_info { /* Parameter to _mi_get_block_info */
#define BLOCK_SYNC_ERROR 16 /* Right data at wrong place */
#define BLOCK_FATAL_ERROR 32 /* hardware-error */
-#define NEAD_MEM ((uint) 10*4*(IO_SIZE+32)+32) /* Nead for recursion */
+#define NEED_MEM ((uint) 10*4*(IO_SIZE+32)+32) /* Nead for recursion */
#define MAXERR 20
#define BUFFERS_WHEN_SORTING 16 /* Alloc for sort-key-tree */
#define WRITE_COUNT MY_HOW_OFTEN_TO_WRITE
@@ -580,14 +605,16 @@ enum myisam_log_commands {
#define myisam_log_command(a,b,c,d,e) if (myisam_log_file >= 0) _myisam_log_command(a,b,c,d,e)
#define myisam_log_record(a,b,c,d,e) if (myisam_log_file >= 0) _myisam_log_record(a,b,c,d,e)
+#define fast_mi_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _mi_writeinfo((INFO),0)
+#define fast_mi_readinfo(INFO) ((INFO)->lock_type == F_UNLCK) && _mi_readinfo((INFO),F_RDLCK,1)
+
#ifdef __cplusplus
extern "C" {
#endif
extern uint _mi_get_block_info(MI_BLOCK_INFO *,File, my_off_t);
extern uint _mi_rec_pack(MI_INFO *info,byte *to,const byte *from);
-extern uint _mi_pack_get_block_info(MI_INFO *mysql, MI_BLOCK_INFO *, File,
- my_off_t, char *rec_buf);
+extern uint _mi_pack_get_block_info(MI_INFO *, MI_BLOCK_INFO *, File, my_off_t);
extern void _my_store_blob_length(byte *pos,uint pack_length,uint length);
extern void _myisam_log(enum myisam_log_commands command,MI_INFO *info,
const byte *buffert,uint length);
@@ -633,14 +660,19 @@ my_bool mi_check_status(void* param);
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
my_bool check_table_is_closed(const char *name, const char *where);
-int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share);
+int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
int mi_open_keyfile(MYISAM_SHARE *share);
void mi_setup_functions(register MYISAM_SHARE *share);
-/* Functions needed by mi_check */
+ /* Functions needed by mi_check */
void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...));
void mi_check_print_warning _VARARGS((MI_CHECK *param, const char *fmt,...));
void mi_check_print_info _VARARGS((MI_CHECK *param, const char *fmt,...));
+int flush_pending_blocks(MI_SORT_PARAM *param);
+int thr_write_keys(MI_SORT_PARAM *sort_param);
+#ifdef THREAD
+pthread_handler_decl(thr_find_all_keys,arg);
+#endif
#ifdef __cplusplus
}
diff --git a/myisam/myisamlog.c b/myisam/myisamlog.c
index ddfafb91430..091f9ad1d7e 100644
--- a/myisam/myisamlog.c
+++ b/myisam/myisamlog.c
@@ -56,7 +56,7 @@ extern int main(int argc,char * *argv);
static void get_options(int *argc,char ***argv);
static int examine_log(my_string file_name,char **table_names);
static int read_string(IO_CACHE *file,gptr *to,uint length);
-static int file_info_compare(void *a,void *b);
+static int file_info_compare(void *cmp_arg, void *a,void *b);
static int test_if_open(struct file_info *key,element_count count,
struct test_if_open_param *param);
static void fix_blob_pointers(MI_INFO *isam,byte *record);
@@ -331,9 +331,9 @@ static int examine_log(my_string file_name, char **table_names)
init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0));
bzero((gptr) com_count,sizeof(com_count));
- init_tree(&tree,0,sizeof(file_info),(qsort_cmp) file_info_compare,1,
- (void(*)(void*)) file_info_free);
- VOID(init_key_cache(KEY_CACHE_SIZE,(uint) (10*4*(IO_SIZE+MALLOC_OVERHEAD))));
+ init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
+ (tree_element_free) file_info_free, NULL);
+ VOID(init_key_cache(KEY_CACHE_SIZE));
files_open=0; access_time=0;
while (access_time++ != number_of_commands &&
@@ -404,11 +404,7 @@ static int examine_log(my_string file_name, char **table_names)
}
to=isam_file_name;
if (filepath)
- {
- strmov(isam_file_name,filepath);
- convert_dirname(isam_file_name);
- to=strend(isam_file_name);
- }
+ to=convert_dirname(isam_file_name,filepath,NullS);
strmov(to,pos);
fn_ext(isam_file_name)[0]=0; /* Remove extension */
}
@@ -417,8 +413,16 @@ static int examine_log(my_string file_name, char **table_names)
VOID(tree_walk(&tree,(tree_walk_action) test_if_open,(void*) &open_param,
left_root_right));
file_info.id=open_param.max_id+1;
+ /*
+ * In the line below +10 is added to accomodate '<' and '>' chars
+ * plus '\0' at the end, so that there is place for 7 digits.
+ * It is improbable that same table can have that many entries in
+ * the table cache.
+ * The additional space is needed for the sprintf commands two lines
+ * below.
+ */
file_info.show_name=my_memdup(isam_file_name,
- (uint) strlen(isam_file_name)+6,
+ (uint) strlen(isam_file_name)+10,
MYF(MY_WME));
if (file_info.id > 1)
sprintf(strend(file_info.show_name),"<%d>",file_info.id);
@@ -488,7 +492,7 @@ static int examine_log(my_string file_name, char **table_names)
command_name[command], (int) extra_command,result);
if (update && curr_file_info && !curr_file_info->closed)
{
- if (mi_extra(curr_file_info->isam, extra_command) != (int) result)
+ if (mi_extra(curr_file_info->isam, extra_command, 0) != (int) result)
{
fflush(stdout);
VOID(fprintf(stderr,
@@ -695,7 +699,8 @@ static int read_string(IO_CACHE *file, register gptr *to, register uint length)
} /* read_string */
-static int file_info_compare(void *a, void *b)
+static int file_info_compare(void* cmp_arg __attribute__((unused)),
+ void *a, void *b)
{
long lint;
diff --git a/myisam/myisampack.c b/myisam/myisampack.c
index cd18cebbda0..800203a30e2 100644
--- a/myisam/myisampack.c
+++ b/myisam/myisampack.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -30,7 +30,7 @@
#ifndef __GNU_LIBRARY__
#define __GNU_LIBRARY__ /* Skip warnings in getopt.h */
#endif
-#include <getopt.h>
+#include <my_getopt.h>
#if INT_MAX > 32767
#define BITS_SAVED 32
@@ -124,7 +124,8 @@ static void free_counts_and_tree_and_queue(HUFF_TREE *huff_trees,
uint trees,
HUFF_COUNTS *huff_counts,
uint fields);
-static int compare_tree(const uchar *s,const uchar *t);
+static int compare_tree(void* cmp_arg __attribute__((unused)),
+ const uchar *s,const uchar *t);
static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts);
static void check_counts(HUFF_COUNTS *huff_counts,uint trees,
my_off_t records);
@@ -168,9 +169,10 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf);
static void mrg_reset(PACK_MRG_INFO *mrg);
-static int backup=0,error_on_write=0,test_only=0,verbose=0,silent=0,
- write_loop=0,force_pack=0,opt_wait=0,isamchk_neaded=0;
+static int error_on_write=0,test_only=0,verbose=0,silent=0,
+ write_loop=0,force_pack=0, isamchk_neaded=0;
static int tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL;
+static my_bool backup, opt_wait;
static uint tree_buff_length=8196-MALLOC_OVERHEAD;
static char tmp_dir[FN_REFLEN]={0},*join_table;
static my_off_t intervall_length;
@@ -231,57 +233,106 @@ int main(int argc, char **argv)
enum options_mp {OPT_CHARSETS_DIR_MP=256};
-static struct option long_options[] =
+static struct my_option my_long_options[] =
{
- {"backup", no_argument, 0, 'b'},
- {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR_MP},
- {"debug", optional_argument, 0, '#'},
- {"force", no_argument, 0, 'f'},
- {"join", required_argument, 0, 'j'},
- {"help", no_argument, 0, '?'},
- {"silent", no_argument, 0, 's'},
- {"tmpdir", required_argument, 0, 'T'},
- {"test", no_argument, 0, 't'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"wait", no_argument, 0, 'w'},
- {0, 0, 0, 0}
+ {"backup", 'b', "Make a backup of the table as table_name.OLD",
+ (gptr*) &backup, (gptr*) &backup, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR_MP,
+ "Directory where character sets are.", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"force", 'f',
+ "Force packing of table even if it gets bigger or if tempfile exists.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"join", 'j',
+ "Join all given tables into 'new_table_name'. All tables MUST have identical layouts.",
+ (gptr*) &join_table, (gptr*) &join_table, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"silent", 's', "Be more silent.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"tmpdir", 'T', "Use temporary directory to store temporary table.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"test", 't', "Don't pack table, only test packing it.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Write info about progress and packing result.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"wait", 'w', "Wait and retry if table is in use.", (gptr*) &opt_wait,
+ (gptr*) &opt_wait, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
static void print_version(void)
{
- printf("%s Ver 1.13 for %s on %s\n",my_progname,SYSTEM_TYPE,MACHINE_TYPE);
+ printf("%s Ver 1.22 for %s on %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
}
static void usage(void)
{
print_version();
- puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB");
+ puts("Copyright (C) 2002 MySQL AB");
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,");
puts("and you are welcome to modify and redistribute it under the GPL license\n");
puts("Pack a MyISAM-table to take much less space.");
puts("Keys are not updated, you must run myisamchk -rq on the datafile");
puts("afterwards to update the keys.");
- puts("You should give the .MSI file as the filename argument.");
+ puts("You should give the .MYI file as the filename argument.");
printf("\nUsage: %s [OPTIONS] filename...\n", my_progname);
- puts("\n\
- -b, --backup Make a backup of the table as table_name.OLD\n\
- -f, --force Force packing of table even if it gets bigger or if\n\
- tempfile exists.\n\
- -j, --join='new_table_name'\n\
- Join all given tables into 'new_table_name'.\n\
- All tables MUST have identical layouts.\n\
- -s, --silent Be more silent.\n\
- -t, --test Don't pack table, only test packing it.\n\
- -v, --verbose Write info about progress and packing result.\n\
- -w, --wait Wait and retry if table is in use.\n\
- -T, --tmpdir=... Use temporary directory to store temporary table.\n\
- -#, --debug=... Output debug log. Often this is 'd:t:o,filename`\n\
- -?, --help Display this help and exit.\n\
- -V, --version Output version information and exit.");
- print_defaults("my",load_default_groups);
+ my_print_help(my_long_options);
+ print_defaults("my", load_default_groups);
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ uint length;
+
+ switch(optid) {
+ case 'f':
+ force_pack= 1;
+ tmpfile_createflag= O_RDWR | O_TRUNC;
+ break;
+ case 's':
+ write_loop= verbose= 0;
+ silent= 1;
+ break;
+ case 't':
+ test_only= verbose= 1;
+ break;
+ case 'T':
+ length= (uint) (strmov(tmp_dir, argument) - tmp_dir);
+ if (length != dirname_length(tmp_dir))
+ {
+ tmp_dir[length]=FN_LIBCHAR;
+ tmp_dir[length+1]=0;
+ }
+ break;
+ case 'v':
+ verbose= 1;
+ silent= 0;
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:o");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
}
/* reads options */
@@ -289,66 +340,15 @@ static void usage(void)
static void get_options(int *argc,char ***argv)
{
- int c,option_index=0;
- uint length;
+ int ho_error;
my_progname= argv[0][0];
if (isatty(fileno(stdout)))
write_loop=1;
- while ((c=getopt_long(*argc,*argv,"bfj:stvwT:#::?V",long_options,
- &option_index)) != EOF)
- {
- switch(c) {
- case 'b':
- backup=1;
- break;
- case 'f':
- force_pack=1;
- tmpfile_createflag=O_RDWR | O_TRUNC;
- break;
- case 'j':
- join_table=optarg;
- break;
- case 's':
- write_loop=verbose=0; silent=1;
- break;
- case 't':
- test_only=verbose=1;
- break;
- case 'T':
- length=(uint) (strmov(tmp_dir,optarg)-tmp_dir);
- if (length != dirname_length(tmp_dir))
- {
- tmp_dir[length]=FN_LIBCHAR;
- tmp_dir[length+1]=0;
- }
- break;
- case 'v':
- verbose=1; silent=0;
- break;
- case 'w':
- opt_wait=1;
- break;
- case '#':
- DBUG_PUSH(optarg ? optarg : "d:t:o");
- break;
- case OPT_CHARSETS_DIR_MP:
- charsets_dir = optarg;
- break;
- case 'V': print_version(); exit(0);
- case 'I':
- case '?':
- usage();
- exit(0);
- default:
- fprintf(stderr,"%s: Illegal option: -%c\n",my_progname,opterr);
- usage();
- exit(1);
- }
- }
- (*argc)-=optind;
- (*argv)+=optind;
+ if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
if (!*argc)
{
usage();
@@ -663,9 +663,9 @@ static HUFF_COUNTS *init_huff_count(MI_INFO *info,my_off_t records)
type = FIELD_NORMAL;
if (count[i].field_length <= 8 &&
(type == FIELD_NORMAL ||
- type == FIELD_SKIPP_ZERO))
+ type == FIELD_SKIP_ZERO))
count[i].max_zero_fill= count[i].field_length;
- init_tree(&count[i].int_tree,0,-1,(qsort_cmp) compare_tree,0,NULL);
+ init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0,NULL,NULL);
if (records && type != FIELD_BLOB && type != FIELD_VARCHAR)
count[i].tree_pos=count[i].tree_buff =
my_malloc(count[i].field_length > 1 ? tree_buff_length : 2,
@@ -787,7 +787,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
/* Save character counters and space-counts and zero-field-counts */
if (count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_ENDSPACE)
+ count->field_type == FIELD_SKIP_ENDSPACE)
{
for ( ; end_pos > pos ; end_pos--)
if (end_pos[-1] != ' ')
@@ -806,7 +806,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
count->max_end_space = length;
}
if (count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_PRESPACE)
+ count->field_type == FIELD_SKIP_PRESPACE)
{
for (pos=start_pos; pos < end_pos ; pos++)
if (pos[0] != ' ')
@@ -842,7 +842,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
}
if (count->field_length <= 8 &&
(count->field_type == FIELD_NORMAL ||
- count->field_type == FIELD_SKIPP_ZERO))
+ count->field_type == FIELD_SKIP_ZERO))
{
uint i;
if (!memcmp((byte*) start_pos,zero_string,count->field_length))
@@ -947,7 +947,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
new_length=calc_packed_length(huff_counts,0);
if (old_length < new_length && huff_counts->field_length > 1)
{
- huff_counts->field_type=FIELD_SKIPP_ZERO;
+ huff_counts->field_type=FIELD_SKIP_ZERO;
huff_counts->counts[0]-=length;
huff_counts->bytes_packed=old_length- records/8;
goto found_pack;
@@ -991,7 +991,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
huff_counts->counts[' ']+=huff_counts->tot_pre_space;
if (test_space_compress(huff_counts,records,huff_counts->max_end_space,
huff_counts->end_space,
- huff_counts->tot_end_space,FIELD_SKIPP_ENDSPACE))
+ huff_counts->tot_end_space,FIELD_SKIP_ENDSPACE))
goto found_pack;
huff_counts->counts[' ']-=huff_counts->tot_pre_space;
}
@@ -999,7 +999,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
{
if (test_space_compress(huff_counts,records,huff_counts->max_pre_space,
huff_counts->pre_space,
- huff_counts->tot_pre_space,FIELD_SKIPP_PRESPACE))
+ huff_counts->tot_pre_space,FIELD_SKIP_PRESPACE))
goto found_pack;
}
@@ -1009,10 +1009,10 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
if (huff_counts->max_zero_fill &&
(huff_counts->field_type == FIELD_NORMAL ||
- huff_counts->field_type == FIELD_SKIPP_ZERO))
+ huff_counts->field_type == FIELD_SKIP_ZERO))
{
huff_counts->counts[0]-=huff_counts->max_zero_fill*
- (huff_counts->field_type == FIELD_SKIPP_ZERO ?
+ (huff_counts->field_type == FIELD_SKIP_ZERO ?
records - huff_counts->zero_fields : records);
huff_counts->pack_type|=PACK_TYPE_ZERO_FILL;
huff_counts->bytes_packed=calc_packed_length(huff_counts,0);
@@ -1052,9 +1052,9 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
if (verbose)
printf("\nnormal: %3d empty-space: %3d empty-zero: %3d empty-fill: %3d\npre-space: %3d end-space: %3d intervall-fields: %3d zero: %3d\n",
field_count[FIELD_NORMAL],space_fields,
- field_count[FIELD_SKIPP_ZERO],fill_zero_fields,
- field_count[FIELD_SKIPP_PRESPACE],
- field_count[FIELD_SKIPP_ENDSPACE],
+ field_count[FIELD_SKIP_ZERO],fill_zero_fields,
+ field_count[FIELD_SKIP_PRESPACE],
+ field_count[FIELD_SKIP_ENDSPACE],
field_count[FIELD_INTERVALL],
field_count[FIELD_ZERO]);
DBUG_VOID_RETURN;
@@ -1282,7 +1282,8 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
return 0;
}
-static int compare_tree(register const uchar *s, register const uchar *t)
+static int compare_tree(void* cmp_arg __attribute__((unused)),
+ register const uchar *s, register const uchar *t)
{
uint length;
for (length=global_count->field_length; length-- ;)
@@ -1719,7 +1720,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
field_length-=count->max_zero_fill;
switch(count->field_type) {
- case FIELD_SKIPP_ZERO:
+ case FIELD_SKIP_ZERO:
if (!memcmp((byte*) start_pos,zero_string,field_length))
{
write_bits(1,1);
@@ -1733,7 +1734,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
write_bits(tree->code[(uchar) *start_pos],
(uint) tree->code_len[(uchar) *start_pos]);
break;
- case FIELD_SKIPP_ENDSPACE:
+ case FIELD_SKIP_ENDSPACE:
for (pos=end_pos ; pos > start_pos && pos[-1] == ' ' ; pos--) ;
length=(uint) (end_pos-pos);
if (count->pack_type & PACK_TYPE_SELECTED)
@@ -1756,7 +1757,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
(uint) tree->code_len[(uchar) *start_pos]);
start_pos=end_pos;
break;
- case FIELD_SKIPP_PRESPACE:
+ case FIELD_SKIP_PRESPACE:
for (pos=start_pos ; pos < end_pos && pos[0] == ' ' ; pos++) ;
length=(uint) (pos-start_pos);
if (count->pack_type & PACK_TYPE_SELECTED)
@@ -2045,7 +2046,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
share->changed=1; /* Force write of header */
share->state.open_count=0;
share->global_changed=0;
- VOID(my_chsize(share->kfile,share->state.state.key_file_length,
+ VOID(my_chsize(share->kfile, share->state.state.key_file_length, 0,
MYF(0)));
if (share->base.keys)
isamchk_neaded=1;
@@ -2087,7 +2088,7 @@ static void mrg_reset(PACK_MRG_INFO *mrg)
{
if (mrg->current)
{
- mi_extra(*mrg->current,HA_EXTRA_NO_CACHE);
+ mi_extra(*mrg->current, HA_EXTRA_NO_CACHE, 0);
mrg->current=0;
}
}
@@ -2102,8 +2103,8 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf)
{
isam_info= *(info->current=info->file);
info->end=info->current+info->count;
- mi_extra(isam_info,HA_EXTRA_RESET);
- mi_extra(isam_info,HA_EXTRA_CACHE);
+ mi_extra(isam_info, HA_EXTRA_RESET, 0);
+ mi_extra(isam_info, HA_EXTRA_CACHE, 0);
filepos=isam_info->s->pack.header_length;
}
else
@@ -2119,14 +2120,14 @@ static int mrg_rrnd(PACK_MRG_INFO *info,byte *buf)
filepos, 1)) ||
error != HA_ERR_END_OF_FILE)
return (error);
- mi_extra(isam_info,HA_EXTRA_NO_CACHE);
+ mi_extra(isam_info,HA_EXTRA_NO_CACHE, 0);
if (info->current+1 == info->end)
return(HA_ERR_END_OF_FILE);
info->current++;
isam_info= *info->current;
filepos=isam_info->s->pack.header_length;
- mi_extra(isam_info,HA_EXTRA_RESET);
- mi_extra(isam_info,HA_EXTRA_CACHE);
+ mi_extra(isam_info,HA_EXTRA_RESET, 0);
+ mi_extra(isam_info,HA_EXTRA_CACHE, 0);
}
}
diff --git a/myisam/sort.c b/myisam/sort.c
index 161a5f92bf5..95ede6ddaa1 100644
--- a/myisam/sort.c
+++ b/myisam/sort.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -19,7 +19,7 @@
them in sorted order through SORT_INFO functions.
*/
-#include "myisamdef.h"
+#include "fulltext.h"
#if defined(MSDOS) || defined(__WIN__)
#include <fcntl.h>
#else
@@ -27,7 +27,8 @@
#endif
#include <queues.h>
- /* static variabels */
+/* static variables */
+
#undef MIN_SORT_MEMORY
#undef MYF_RW
#undef DISK_BUFFER_SIZE
@@ -35,64 +36,80 @@
#define MERGEBUFF 15
#define MERGEBUFF2 31
#define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD)
-#define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL)
+#define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL)
#define DISK_BUFFER_SIZE (IO_SIZE*16)
typedef struct st_buffpek {
- my_off_t file_pos; /* Where we are in the sort file */
- uchar *base,*key; /* Key pointers */
- ha_rows count; /* Number of rows in table */
- ulong mem_count; /* numbers of keys in memory */
- ulong max_keys; /* Max keys in buffert */
+ my_off_t file_pos; /* Where we are in the sort file */
+ uchar *base,*key; /* Key pointers */
+ ha_rows count; /* Number of rows in table */
+ ulong mem_count; /* numbers of keys in memory */
+ ulong max_keys; /* Max keys in buffert */
} BUFFPEK;
extern void print_error _VARARGS((const char *fmt,...));
- /* functions defined in this file */
+/* Functions defined in this file */
static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info,uint keys,
- uchar **sort_keys,
- BUFFPEK *buffpek,int *maxbuffer,
- IO_CACHE *tempfile);
+ uchar **sort_keys,
+ DYNAMIC_ARRAY *buffpek,int *maxbuffer,
+ IO_CACHE *tempfile,
+ IO_CACHE *tempfile_for_exceptions);
static int NEAR_F write_keys(MI_SORT_PARAM *info,uchar * *sort_keys,
- uint count, BUFFPEK *buffpek,IO_CACHE *tempfile);
+ uint count, BUFFPEK *buffpek,IO_CACHE *tempfile);
+static int NEAR_F write_key(MI_SORT_PARAM *info, uchar *key,
+ IO_CACHE *tempfile);
static int NEAR_F write_index(MI_SORT_PARAM *info,uchar * *sort_keys,
- uint count);
+ uint count);
static int NEAR_F merge_many_buff(MI_SORT_PARAM *info,uint keys,
- uchar * *sort_keys,
- BUFFPEK *buffpek,int *maxbuffer,
- IO_CACHE *t_file);
+ uchar * *sort_keys,
+ BUFFPEK *buffpek,int *maxbuffer,
+ IO_CACHE *t_file);
static uint NEAR_F read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
- uint sort_length);
+ uint sort_length);
static int NEAR_F merge_buffers(MI_SORT_PARAM *info,uint keys,
- IO_CACHE *from_file, IO_CACHE *to_file,
- uchar * *sort_keys, BUFFPEK *lastbuff,
- BUFFPEK *Fb, BUFFPEK *Tb);
+ IO_CACHE *from_file, IO_CACHE *to_file,
+ uchar * *sort_keys, BUFFPEK *lastbuff,
+ BUFFPEK *Fb, BUFFPEK *Tb);
static int NEAR_F merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int,
- IO_CACHE *);
-static char **make_char_array(uint fields,uint length,myf my_flag);
+ IO_CACHE *);
+
- /* Creates a index of sorted keys */
- /* Returns 0 if everything went ok */
+/*
+ Creates a index of sorted keys
+
+ SYNOPSIS
+ _create_index_by_sort()
+ info Sort parameters
+ no_messages Set to 1 if no output
+ sortbuff_size Size if sortbuffer to allocate
+
+ RESULT
+ 0 ok
+ <> 0 Error
+*/
int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
ulong sortbuff_size)
{
int error,maxbuffer,skr;
uint memavl,old_memavl,keys,sort_length;
- BUFFPEK *buffpek;
+ DYNAMIC_ARRAY buffpek;
ha_rows records;
uchar **sort_keys;
- IO_CACHE tempfile;
+ IO_CACHE tempfile, tempfile_for_exceptions;
DBUG_ENTER("_create_index_by_sort");
DBUG_PRINT("enter",("sort_length: %d", info->key_length));
my_b_clear(&tempfile);
- buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1;
+ my_b_clear(&tempfile_for_exceptions);
+ bzero((char*) &buffpek,sizeof(buffpek));
+ sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1;
memavl=max(sortbuff_size,MIN_SORT_MEMORY);
- records= info->max_records;
+ records= info->sort_info->max_records;
sort_length= info->key_length;
LINT_INIT(keys);
@@ -116,14 +133,14 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
}
while ((maxbuffer= (int) (records/(keys-1)+1)) != skr);
- if ((sort_keys= (uchar **) make_char_array(keys,sort_length,MYF(0))))
+ if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+
+ HA_FT_MAXLEN, MYF(0))))
{
- if ((buffpek = (BUFFPEK*) my_malloc((uint) (sizeof(BUFFPEK)*
- (uint) maxbuffer),
- MYF(0))))
- break;
- else
+ if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer,
+ maxbuffer/2))
my_free((gptr) sort_keys,MYF(0));
+ else
+ break;
}
old_memavl=memavl;
if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
@@ -139,14 +156,15 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
if (!no_messages)
printf(" - Searching for keys, allocating buffer for %d keys\n",keys);
- if ((records=find_all_keys(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile))
+ if ((records=find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer,
+ &tempfile,&tempfile_for_exceptions))
== HA_POS_ERROR)
goto err; /* purecov: tested */
if (maxbuffer == 0)
{
if (!no_messages)
- printf(" - Dumping %lu keys\n",records);
- if (write_index(info,sort_keys,(uint) records))
+ printf(" - Dumping %lu keys\n", (ulong) records);
+ if (write_index(info,sort_keys, (uint) records))
goto err; /* purecov: inspected */
}
else
@@ -155,112 +173,449 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
if (maxbuffer >= MERGEBUFF2)
{
if (!no_messages)
- printf(" - Merging %lu keys\n",records); /* purecov: tested */
- if (merge_many_buff(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile))
- goto err; /* purecov: inspected */
+ printf(" - Merging %lu keys\n", (ulong) records); /* purecov: tested */
+ if (merge_many_buff(info,keys,sort_keys,
+ dynamic_element(&buffpek,0,BUFFPEK *),&maxbuffer,&tempfile))
+ goto err; /* purecov: inspected */
}
if (flush_io_cache(&tempfile) ||
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
- goto err; /* purecov: inspected */
+ goto err; /* purecov: inspected */
if (!no_messages)
- puts(" - Last merge and dumping keys"); /* purecov: tested */
- if (merge_index(info,keys,sort_keys,buffpek,maxbuffer,&tempfile))
- goto err; /* purecov: inspected */
+ puts(" - Last merge and dumping keys\n"); /* purecov: tested */
+ if (merge_index(info,keys,sort_keys,dynamic_element(&buffpek,0,BUFFPEK *),
+ maxbuffer,&tempfile))
+ goto err; /* purecov: inspected */
}
+
+ if (flush_pending_blocks(info))
+ goto err;
+
+ if (my_b_inited(&tempfile_for_exceptions))
+ {
+ MI_INFO *index=info->sort_info->info;
+ uint keyno=info->key;
+ uint key_length, ref_length=index->s->rec_reflength;
+
+ if (flush_io_cache(&tempfile_for_exceptions) ||
+ reinit_io_cache(&tempfile_for_exceptions,READ_CACHE,0L,0,0))
+ goto err;
+
+ while (!my_b_read(&tempfile_for_exceptions,(byte*)&key_length,
+ sizeof(key_length))
+ && !my_b_read(&tempfile_for_exceptions,(byte*)sort_keys,
+ (uint) key_length))
+ {
+ if (_mi_ck_write(index,keyno,(uchar*) sort_keys,key_length-ref_length))
+ goto err;
+ }
+ }
+
error =0;
err:
if (sort_keys)
my_free((gptr) sort_keys,MYF(0));
- if (buffpek)
- my_free((gptr) buffpek,MYF(0));
+ delete_dynamic(&buffpek);
close_cached_file(&tempfile);
+ close_cached_file(&tempfile_for_exceptions);
DBUG_RETURN(error ? -1 : 0);
} /* _create_index_by_sort */
- /* Search after all keys and place them in a temp. file */
+/* Search after all keys and place them in a temp. file */
static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys,
- uchar **sort_keys, BUFFPEK *buffpek,
- int *maxbuffer, IO_CACHE *tempfile)
+ uchar **sort_keys, DYNAMIC_ARRAY *buffpek,
+ int *maxbuffer, IO_CACHE *tempfile,
+ IO_CACHE *tempfile_for_exceptions)
{
int error;
- uint idx,indexpos;
+ uint idx;
DBUG_ENTER("find_all_keys");
- idx=indexpos=error=0;
+ idx=error=0;
+ sort_keys[0]=(uchar*) (sort_keys+keys);
- while (!(error=(*info->key_read)(info->sort_info,sort_keys[idx])))
+ while (!(error=(*info->key_read)(info,sort_keys[idx])))
{
- if ((uint) ++idx == keys)
+ if (info->real_key_length > info->key_length)
{
- if (indexpos >= (uint) *maxbuffer ||
- write_keys(info,sort_keys,idx-1,buffpek+indexpos,tempfile))
- DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
+ if (write_key(info,sort_keys[idx],tempfile_for_exceptions))
+ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
+ continue;
+ }
+
+ if (++idx == keys)
+ {
+ if (write_keys(info,sort_keys,idx-1,(BUFFPEK *)alloc_dynamic(buffpek),
+ tempfile))
+ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
+
+ sort_keys[0]=(uchar*) (sort_keys+keys);
memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length);
- idx=1; indexpos++;
+ idx=1;
}
+ sort_keys[idx]=sort_keys[idx-1]+info->key_length;
}
if (error > 0)
DBUG_RETURN(HA_POS_ERROR); /* Aborted by get_key */ /* purecov: inspected */
- if (indexpos)
- if (indexpos >= (uint) *maxbuffer ||
- write_keys(info,sort_keys,idx,buffpek+indexpos,tempfile))
- DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
- *maxbuffer=(int) indexpos;
- DBUG_RETURN(indexpos*(keys-1)+idx);
+ if (buffpek->elements)
+ {
+ if (write_keys(info,sort_keys,idx,(BUFFPEK *)alloc_dynamic(buffpek),
+ tempfile))
+ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
+ *maxbuffer=buffpek->elements-1;
+ }
+ else
+ *maxbuffer=0;
+
+ DBUG_RETURN((*maxbuffer)*(keys-1)+idx);
} /* find_all_keys */
- /* Write all keys in memory to file for later merge */
+#ifdef THREAD
+/* Search after all keys and place them in a temp. file */
+
+pthread_handler_decl(thr_find_all_keys,arg)
+{
+ MI_SORT_PARAM *info= (MI_SORT_PARAM*) arg;
+ int error;
+ uint memavl,old_memavl,keys,sort_length;
+ uint idx, maxbuffer;
+ uchar **sort_keys=0;
+
+ LINT_INIT(keys);
+
+ error=1;
+
+ if (my_thread_init())
+ goto err;
+ if (info->sort_info->got_error)
+ goto err;
+
+ my_b_clear(&info->tempfile);
+ my_b_clear(&info->tempfile_for_exceptions);
+ bzero((char*) &info->buffpek,sizeof(info->buffpek));
+ bzero((char*) &info->unique, sizeof(info->unique));
+ sort_keys= (uchar **) NULL;
+
+ memavl=max(info->sortbuff_size, MIN_SORT_MEMORY);
+ idx= info->sort_info->max_records;
+ sort_length= info->key_length;
+ maxbuffer= 1;
+
+ while (memavl >= MIN_SORT_MEMORY)
+ {
+ if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
+ (my_off_t) memavl)
+ keys= idx+1;
+ else
+ {
+ uint skr;
+ do
+ {
+ skr=maxbuffer;
+ if (memavl < sizeof(BUFFPEK)*maxbuffer ||
+ (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
+ (sort_length+sizeof(char*))) <= 1)
+ {
+ mi_check_print_error(info->sort_info->param,
+ "sort_buffer_size is to small");
+ goto err;
+ }
+ }
+ while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
+ }
+ if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+
+ ((info->keyinfo->flag & HA_FULLTEXT) ?
+ HA_FT_MAXLEN : 0), MYF(0))))
+ {
+ if (my_init_dynamic_array(&info->buffpek, sizeof(BUFFPEK),
+ maxbuffer, maxbuffer/2))
+ my_free((gptr) sort_keys,MYF(0));
+ else
+ break;
+ }
+ old_memavl=memavl;
+ if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
+ memavl=MIN_SORT_MEMORY;
+ }
+ if (memavl < MIN_SORT_MEMORY)
+ {
+ mi_check_print_error(info->sort_info->param,"Sort buffer to small"); /* purecov: tested */
+ goto err; /* purecov: tested */
+ }
+
+ if (info->sort_info->param->testflag & T_VERBOSE)
+ printf("Key %d - Allocating buffer for %d keys\n",info->key+1,keys);
+ info->sort_keys=sort_keys;
+
+ idx=error=0;
+ sort_keys[0]=(uchar*) (sort_keys+keys);
+
+ while (!(error=info->sort_info->got_error) &&
+ !(error=(*info->key_read)(info,sort_keys[idx])))
+ {
+ if (info->real_key_length > info->key_length)
+ {
+ if (write_key(info,sort_keys[idx], &info->tempfile_for_exceptions))
+ goto err;
+ continue;
+ }
+
+ if (++idx == keys)
+ {
+ if (write_keys(info,sort_keys,idx-1,
+ (BUFFPEK *)alloc_dynamic(&info->buffpek),
+ &info->tempfile))
+ goto err;
+ sort_keys[0]=(uchar*) (sort_keys+keys);
+ memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length);
+ idx=1;
+ }
+ sort_keys[idx]=sort_keys[idx-1]+info->key_length;
+ }
+ if (error > 0)
+ goto err;
+ if (info->buffpek.elements)
+ {
+ if (write_keys(info,sort_keys, idx,
+ (BUFFPEK *) alloc_dynamic(&info->buffpek), &info->tempfile))
+ goto err;
+ info->keys=(info->buffpek.elements-1)*(keys-1)+idx;
+ }
+ else
+ info->keys=idx;
+
+ info->sort_keys_length=keys;
+ goto ok;
+
+err:
+ info->sort_info->got_error=1; /* no need to protect this with a mutex */
+ if (sort_keys)
+ my_free((gptr) sort_keys,MYF(0));
+ info->sort_keys=0;
+ delete_dynamic(& info->buffpek);
+ close_cached_file(&info->tempfile);
+ close_cached_file(&info->tempfile_for_exceptions);
+
+ok:
+ remove_io_thread(&info->read_cache);
+ pthread_mutex_lock(&info->sort_info->mutex);
+ info->sort_info->threads_running--;
+ pthread_cond_signal(&info->sort_info->cond);
+ pthread_mutex_unlock(&info->sort_info->mutex);
+ my_thread_end();
+ return NULL;
+}
+
+
+int thr_write_keys(MI_SORT_PARAM *sort_param)
+{
+ SORT_INFO *sort_info=sort_param->sort_info;
+ MI_CHECK *param=sort_info->param;
+ ulong length, keys;
+ ulong *rec_per_key_part=param->rec_per_key_part;
+ int got_error=sort_info->got_error;
+ uint i;
+ MI_INFO *info=sort_info->info;
+ MYISAM_SHARE *share=info->s;
+ MI_SORT_PARAM *sinfo;
+ byte *mergebuf=0;
+ LINT_INIT(length);
+
+ for (i= 0, sinfo= sort_param ;
+ i < sort_info->total_keys ;
+ i++, rec_per_key_part+=sinfo->keyinfo->keysegs, sinfo++)
+ {
+ if (!sinfo->sort_keys)
+ {
+ got_error=1;
+ continue;
+ }
+ if (!got_error)
+ {
+ share->state.key_map|=(ulonglong) 1 << sinfo->key;
+ if (param->testflag & T_STATISTICS)
+ update_key_parts(sinfo->keyinfo, rec_per_key_part,
+ sinfo->unique, (ulonglong) info->state->records);
+ if (!sinfo->buffpek.elements)
+ {
+ if (param->testflag & T_VERBOSE)
+ {
+ printf("Key %d - Dumping %u keys\n",sinfo->key+1, sinfo->keys);
+ fflush(stdout);
+ }
+ if (write_index(sinfo, sinfo->sort_keys, sinfo->keys) ||
+ flush_pending_blocks(sinfo))
+ got_error=1;
+ }
+ }
+ my_free((gptr) sinfo->sort_keys,MYF(0));
+ my_free(mi_get_rec_buff_ptr(info, sinfo->rec_buff),
+ MYF(MY_ALLOW_ZERO_PTR));
+ sinfo->sort_keys=0;
+ }
+
+ for (i= 0, sinfo= sort_param ;
+ i < sort_info->total_keys ;
+ i++,
+ delete_dynamic(&sinfo->buffpek),
+ close_cached_file(&sinfo->tempfile),
+ close_cached_file(&sinfo->tempfile_for_exceptions),
+ sinfo++)
+ {
+ if (got_error)
+ continue;
+ if (sinfo->buffpek.elements)
+ {
+ uint maxbuffer=sinfo->buffpek.elements-1;
+ if (!mergebuf)
+ {
+ length=param->sort_buffer_length;
+ while (length >= MIN_SORT_MEMORY && !mergebuf)
+ {
+ mergebuf=my_malloc(length, MYF(0));
+ length=length*3/4;
+ }
+ if (!mergebuf)
+ {
+ got_error=1;
+ continue;
+ }
+ }
+ keys=length/sinfo->key_length;
+ if (maxbuffer >= MERGEBUFF2)
+ {
+ if (param->testflag & T_VERBOSE)
+ printf("Key %d - Merging %u keys\n",sinfo->key+1, sinfo->keys);
+ if (merge_many_buff(sinfo, keys, (uchar **)mergebuf,
+ dynamic_element(&sinfo->buffpek, 0, BUFFPEK *),
+ (int*) &maxbuffer, &sinfo->tempfile))
+ {
+ got_error=1;
+ continue;
+ }
+ }
+ if (flush_io_cache(&sinfo->tempfile) ||
+ reinit_io_cache(&sinfo->tempfile,READ_CACHE,0L,0,0))
+ {
+ got_error=1;
+ continue;
+ }
+ if (param->testflag & T_VERBOSE)
+ printf("Key %d - Last merge and dumping keys\n", sinfo->key+1);
+ if (merge_index(sinfo, keys, (uchar **)mergebuf,
+ dynamic_element(&sinfo->buffpek,0,BUFFPEK *),
+ maxbuffer,&sinfo->tempfile) ||
+ flush_pending_blocks(sinfo))
+ {
+ got_error=1;
+ continue;
+ }
+ }
+ if (my_b_inited(&sinfo->tempfile_for_exceptions))
+ {
+ uint key_length;
+
+ if (param->testflag & T_VERBOSE)
+ printf("Key %d - Dumping 'long' keys\n", sinfo->key+1);
+
+ if (flush_io_cache(&sinfo->tempfile_for_exceptions) ||
+ reinit_io_cache(&sinfo->tempfile_for_exceptions,READ_CACHE,0L,0,0))
+ {
+ got_error=1;
+ continue;
+ }
+
+ while (!got_error &&
+ !my_b_read(&sinfo->tempfile_for_exceptions,(byte*)&key_length,
+ sizeof(key_length)) &&
+ !my_b_read(&sinfo->tempfile_for_exceptions,(byte*)mergebuf,
+ (uint) key_length))
+ {
+ if (_mi_ck_write(info,sinfo->key,(uchar*) mergebuf,
+ key_length - info->s->rec_reflength))
+ got_error=1;
+ }
+ }
+ }
+ my_free((gptr) mergebuf,MYF(MY_ALLOW_ZERO_PTR));
+ return got_error;
+}
+#endif /* THREAD */
+
+ /* Write all keys in memory to file for later merge */
static int NEAR_F write_keys(MI_SORT_PARAM *info, register uchar **sort_keys,
- uint count, BUFFPEK *buffpek,
- IO_CACHE *tempfile)
+ uint count, BUFFPEK *buffpek, IO_CACHE *tempfile)
{
uchar **end;
uint sort_length=info->key_length;
DBUG_ENTER("write_keys");
qsort2((byte*) sort_keys,count,sizeof(byte*),(qsort2_cmp) info->key_cmp,
- info->sort_info);
+ info);
if (!my_b_inited(tempfile) &&
open_cached_file(tempfile, info->tmpdir, "ST", DISK_BUFFER_SIZE,
- info->myf_rw))
+ info->sort_info->param->myf_rw))
DBUG_RETURN(1); /* purecov: inspected */
+
buffpek->file_pos=my_b_tell(tempfile);
buffpek->count=count;
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
+ {
if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length))
DBUG_RETURN(1); /* purecov: inspected */
+ }
DBUG_RETURN(0);
} /* write_keys */
- /* Write index */
+static int NEAR_F write_key(MI_SORT_PARAM *info, uchar *key,
+ IO_CACHE *tempfile)
+{
+ uint key_length=info->real_key_length;
+ DBUG_ENTER("write_key");
+
+ if (!my_b_inited(tempfile) &&
+ open_cached_file(tempfile, info->tmpdir, "ST", DISK_BUFFER_SIZE,
+ info->sort_info->param->myf_rw))
+ DBUG_RETURN(1);
+
+ if (my_b_write(tempfile,(byte*)&key_length,sizeof(key_length)) ||
+ my_b_write(tempfile,(byte*)key,(uint) key_length))
+ DBUG_RETURN(1);
+ DBUG_RETURN(0);
+} /* write_key */
+
+
+/* Write index */
static int NEAR_F write_index(MI_SORT_PARAM *info, register uchar **sort_keys,
- register uint count)
+ register uint count)
{
DBUG_ENTER("write_index");
qsort2((gptr) sort_keys,(size_t) count,sizeof(byte*),
- (qsort2_cmp) info->key_cmp,info->sort_info);
+ (qsort2_cmp) info->key_cmp,info);
while (count--)
- if ((*info->key_write)(info->sort_info,*sort_keys++))
+ {
+ if ((*info->key_write)(info,*sort_keys++))
DBUG_RETURN(-1); /* purecov: inspected */
+ }
DBUG_RETURN(0);
} /* write_index */
- /* Merge buffers to make < MERGEBUFF2 buffers */
+ /* Merge buffers to make < MERGEBUFF2 buffers */
static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
- uchar **sort_keys, BUFFPEK *buffpek,
- int *maxbuffer, IO_CACHE *t_file)
+ uchar **sort_keys, BUFFPEK *buffpek,
+ int *maxbuffer, IO_CACHE *t_file)
{
register int i;
IO_CACHE t_file2, *from_file, *to_file, *temp;
@@ -268,11 +623,11 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
DBUG_ENTER("merge_many_buff");
if (*maxbuffer < MERGEBUFF2)
- DBUG_RETURN(0); /* purecov: inspected */
+ DBUG_RETURN(0); /* purecov: inspected */
if (flush_io_cache(t_file) ||
open_cached_file(&t_file2,info->tmpdir,"ST",DISK_BUFFER_SIZE,
- info->myf_rw))
- DBUG_RETURN(1); /* purecov: inspected */
+ info->sort_info->param->myf_rw))
+ DBUG_RETURN(1); /* purecov: inspected */
from_file= t_file ; to_file= &t_file2;
while (*maxbuffer >= MERGEBUFF2)
@@ -283,30 +638,40 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
{
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
- buffpek+i,buffpek+i+MERGEBUFF-1))
- break; /* purecov: inspected */
+ buffpek+i,buffpek+i+MERGEBUFF-1))
+ break; /* purecov: inspected */
}
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
- buffpek+i,buffpek+ *maxbuffer))
+ buffpek+i,buffpek+ *maxbuffer))
break; /* purecov: inspected */
if (flush_io_cache(to_file))
- break; /* purecov: inspected */
+ break; /* purecov: inspected */
temp=from_file; from_file=to_file; to_file=temp;
*maxbuffer= (int) (lastbuff-buffpek)-1;
}
- close_cached_file(to_file); /* This holds old result */
+ close_cached_file(to_file); /* This holds old result */
if (to_file == t_file)
- *t_file=t_file2; /* Copy result file */
+ *t_file=t_file2; /* Copy result file */
- DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */
+ DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */
} /* merge_many_buff */
- /* Read data to buffer */
- /* This returns (uint) -1 if something goes wrong */
+/*
+ Read data to buffer
+
+ SYNOPSIS
+ read_to_buffer()
+ fromfile File to read from
+ buffpek Where to read from
+ sort_length max length to read
+ RESULT
+ > 0 Ammount of bytes read
+ -1 Error
+*/
static uint NEAR_F read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
- uint sort_length)
+ uint sort_length)
{
register uint count;
uint length;
@@ -314,24 +679,26 @@ static uint NEAR_F read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
{
if (my_pread(fromfile->file,(byte*) buffpek->base,
- (length= sort_length*count),buffpek->file_pos,MYF_RW))
- return((uint) -1); /* purecov: inspected */
+ (length= sort_length*count),buffpek->file_pos,MYF_RW))
+ return((uint) -1); /* purecov: inspected */
buffpek->key=buffpek->base;
- buffpek->file_pos+= length; /* New filepos */
- buffpek->count-= count;
+ buffpek->file_pos+= length; /* New filepos */
+ buffpek->count-= count;
buffpek->mem_count= count;
}
return (count*sort_length);
} /* read_to_buffer */
- /* Merge buffers to one buffer */
- /* If to_file == 0 then use info->key_write */
+/*
+ Merge buffers to one buffer
+ If to_file == 0 then use info->key_write
+*/
static int NEAR_F
-merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
- IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff,
- BUFFPEK *Fb, BUFFPEK *Tb)
+merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
+ IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff,
+ BUFFPEK *Fb, BUFFPEK *Tb)
{
int error;
uint sort_length,maxcount;
@@ -351,8 +718,8 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
sort_length=info->key_length;
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
- (int (*)(void*, byte *,byte*)) info->key_cmp,
- (void*) info->sort_info))
+ (int (*)(void*, byte *,byte*)) info->key_cmp,
+ (void*) info))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
@@ -361,7 +728,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
buffpek->base= strpos;
buffpek->max_keys=maxcount;
strpos+= (uint) (error=(int) read_to_buffer(from_file,buffpek,
- sort_length));
+ sort_length));
if (error == -1)
goto err; /* purecov: inspected */
queue_insert(&queue,(char*) buffpek);
@@ -374,52 +741,52 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
buffpek=(BUFFPEK*) queue_top(&queue);
if (to_file)
{
- if (my_b_write(to_file,(byte*) buffpek->key,(uint) sort_length))
- {
- error=1; goto err; /* purecov: inspected */
- }
+ if (my_b_write(to_file,(byte*) buffpek->key,(uint) sort_length))
+ {
+ error=1; goto err; /* purecov: inspected */
+ }
}
else
{
- if ((*info->key_write)(info->sort_info,(void*) buffpek->key))
- {
- error=1; goto err; /* purecov: inspected */
- }
+ if ((*info->key_write)(info,(void*) buffpek->key))
+ {
+ error=1; goto err; /* purecov: inspected */
+ }
}
buffpek->key+=sort_length;
if (! --buffpek->mem_count)
{
- if (!(error=(int) read_to_buffer(from_file,buffpek,sort_length)))
- {
- uchar *base=buffpek->base;
- uint max_keys=buffpek->max_keys;
-
- VOID(queue_remove(&queue,0));
-
- /* Put room used by buffer to use in other buffer */
- for (refpek= (BUFFPEK**) &queue_top(&queue);
- refpek <= (BUFFPEK**) &queue_end(&queue);
- refpek++)
- {
- buffpek= *refpek;
- if (buffpek->base+buffpek->max_keys*sort_length == base)
- {
- buffpek->max_keys+=max_keys;
- break;
- }
- else if (base+max_keys*sort_length == buffpek->base)
- {
- buffpek->base=base;
- buffpek->max_keys+=max_keys;
- break;
- }
- }
- break; /* One buffer have been removed */
- }
+ if (!(error=(int) read_to_buffer(from_file,buffpek,sort_length)))
+ {
+ uchar *base=buffpek->base;
+ uint max_keys=buffpek->max_keys;
+
+ VOID(queue_remove(&queue,0));
+
+ /* Put room used by buffer to use in other buffer */
+ for (refpek= (BUFFPEK**) &queue_top(&queue);
+ refpek <= (BUFFPEK**) &queue_end(&queue);
+ refpek++)
+ {
+ buffpek= *refpek;
+ if (buffpek->base+buffpek->max_keys*sort_length == base)
+ {
+ buffpek->max_keys+=max_keys;
+ break;
+ }
+ else if (base+max_keys*sort_length == buffpek->base)
+ {
+ buffpek->base=base;
+ buffpek->max_keys+=max_keys;
+ break;
+ }
+ }
+ break; /* One buffer have been removed */
+ }
}
else if (error == -1)
- goto err; /* purecov: inspected */
- queue_replaced(&queue); /* Top element has been replaced */
+ goto err; /* purecov: inspected */
+ queue_replaced(&queue); /* Top element has been replaced */
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
@@ -430,9 +797,9 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
if (to_file)
{
if (my_b_write(to_file,(byte*) buffpek->key,
- (sort_length*buffpek->mem_count)))
+ (sort_length*buffpek->mem_count)))
{
- error=1; goto err; /* purecov: inspected */
+ error=1; goto err; /* purecov: inspected */
}
}
else
@@ -440,18 +807,18 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
register uchar *end;
strpos= buffpek->key;
for (end=strpos+buffpek->mem_count*sort_length;
- strpos != end ;
- strpos+=sort_length)
+ strpos != end ;
+ strpos+=sort_length)
{
- if ((*info->key_write)(info->sort_info,(void*) strpos))
- {
- error=1; goto err; /* purecov: inspected */
- }
+ if ((*info->key_write)(info,(void*) strpos))
+ {
+ error=1; goto err; /* purecov: inspected */
+ }
}
}
}
while ((error=(int) read_to_buffer(from_file,buffpek,sort_length)) != -1 &&
- error != 0);
+ error != 0);
lastbuff->count=count;
if (to_file)
@@ -462,34 +829,16 @@ err:
} /* merge_buffers */
- /* Do a merge to output-file (save only positions) */
+ /* Do a merge to output-file (save only positions) */
static int NEAR_F
merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys,
- BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile)
+ BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile)
{
DBUG_ENTER("merge_index");
if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek,
- buffpek+maxbuffer))
+ buffpek+maxbuffer))
DBUG_RETURN(1); /* purecov: inspected */
DBUG_RETURN(0);
} /* merge_index */
-
- /* Make a pointer of arrays to keys */
-
-static char **make_char_array(register uint fields, uint length, myf my_flag)
-{
- register char **pos;
- char **old_pos,*char_pos;
- DBUG_ENTER("make_char_array");
-
- if ((old_pos= (char**) my_malloc( fields*(length+sizeof(char*)), my_flag)))
- {
- pos=old_pos; char_pos=((char*) (pos+fields)) -length;
- while (fields--)
- *(pos++) = (char_pos+= length);
- }
-
- DBUG_RETURN(old_pos);
-} /* make_char_array */
diff --git a/myisammrg/Makefile.am b/myisammrg/Makefile.am
index 04fa1c9ec13..6a6824affba 100644
--- a/myisammrg/Makefile.am
+++ b/myisammrg/Makefile.am
@@ -16,12 +16,12 @@
INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include
pkglib_LIBRARIES = libmyisammrg.a
-noinst_HEADERS = mymrgdef.h
+noinst_HEADERS = myrg_def.h
libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
myrg_rrnd.c myrg_update.c myrg_delete.c myrg_rsame.c \
myrg_panic.c myrg_close.c myrg_create.c myrg_static.c \
myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \
- myrg_rprev.c myrg_queue.c
+ myrg_rprev.c myrg_queue.c myrg_write.c myrg_range.c
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/myisammrg/mymrgdef.h b/myisammrg/mymrgdef.h
deleted file mode 100644
index aae1d07cd64..00000000000
--- a/myisammrg/mymrgdef.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* This file is included by all myisam-merge files */
-
-#ifndef N_MAXKEY
-#include "../myisam/myisamdef.h"
-#endif
-
-#include "myisammrg.h"
-
-extern LIST *myrg_open_list;
-
-#ifdef THREAD
-extern pthread_mutex_t THR_LOCK_open;
-#endif
-
-int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag);
diff --git a/myisammrg/myrg_close.c b/myisammrg/myrg_close.c
index 7ab73c5ded4..897020c6865 100644
--- a/myisammrg/myrg_close.c
+++ b/myisammrg/myrg_close.c
@@ -1,22 +1,22 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* close a isam-database */
-#include "mymrgdef.h"
+#include "myrg_def.h"
int myrg_close(MYRG_INFO *info)
{
diff --git a/myisammrg/myrg_create.c b/myisammrg/myrg_create.c
index 113831b9d7f..5fc3c60ff32 100644
--- a/myisammrg/myrg_create.c
+++ b/myisammrg/myrg_create.c
@@ -1,29 +1,30 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Create a MYMERGE_-file */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/* create file named 'name' and save filenames in it
table_names should be NULL or a vector of string-pointers with
a NULL-pointer last
*/
-int myrg_create(const char *name, const char **table_names, my_bool fix_names)
+int myrg_create(const char *name, const char **table_names,
+ uint insert_method, my_bool fix_names)
{
int save_errno;
uint errpos;
@@ -50,6 +51,13 @@ int myrg_create(const char *name, const char **table_names, my_bool fix_names)
goto err;
}
}
+ if (insert_method != MERGE_INSERT_DISABLED)
+ {
+ end=strxmov(buff,"#INSERT_METHOD=",
+ get_type(&merge_insert_method,insert_method-1),"\n",NullS);
+ if (my_write(file,buff,(uint) (end-buff),MYF(MY_WME | MY_NABP)))
+ goto err;
+ }
if (my_close(file,MYF(0)))
goto err;
DBUG_RETURN(0);
diff --git a/myisammrg/myrg_def.h b/myisammrg/myrg_def.h
new file mode 100644
index 00000000000..00e7950bccf
--- /dev/null
+++ b/myisammrg/myrg_def.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* This file is included by all myisam-merge files */
+
+#ifndef N_MAXKEY
+#include "../myisam/myisamdef.h"
+#endif
+
+#include "myisammrg.h"
+
+extern LIST *myrg_open_list;
+
+#ifdef THREAD
+extern pthread_mutex_t THR_LOCK_open;
+#endif
+
+int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag);
+int _myrg_mi_read_record(MI_INFO *info, byte *buf);
+
diff --git a/myisammrg/myrg_delete.c b/myisammrg/myrg_delete.c
index 9ac32655172..8b89ed62ac1 100644
--- a/myisammrg/myrg_delete.c
+++ b/myisammrg/myrg_delete.c
@@ -1,30 +1,27 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Delete last read record */
-#include "mymrgdef.h"
+#include "myrg_def.h"
-int myrg_delete(
-MYRG_INFO *info,
-const byte *record)
+int myrg_delete(MYRG_INFO *info, const byte *record)
{
if (!info->current_table)
- {
- return(my_errno=HA_ERR_NO_ACTIVE_RECORD);
- }
+ return (my_errno= HA_ERR_NO_ACTIVE_RECORD);
+
return mi_delete(info->current_table->table,record);
}
diff --git a/myisammrg/myrg_extra.c b/myisammrg/myrg_extra.c
index c8a634e748f..62cf5f01aba 100644
--- a/myisammrg/myrg_extra.c
+++ b/myisammrg/myrg_extra.c
@@ -20,9 +20,10 @@
record-cache-flags are set in myrg_rrnd when we are changing database.
*/
-#include "mymrgdef.h"
+#include "myrg_def.h"
-int myrg_extra(MYRG_INFO *info,enum ha_extra_function function)
+int myrg_extra(MYRG_INFO *info,enum ha_extra_function function,
+ void *extra_arg)
{
int error,save_error=0;
MYRG_TABLE *file;
@@ -30,10 +31,15 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function)
DBUG_PRINT("info",("function: %d",(ulong) function));
if (function == HA_EXTRA_CACHE)
+ {
info->cache_in_use=1;
+ info->cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
+ }
else
{
- if (function == HA_EXTRA_NO_CACHE || function == HA_EXTRA_RESET)
+ if (function == HA_EXTRA_NO_CACHE || function == HA_EXTRA_RESET ||
+ function == HA_EXTRA_PREPARE_FOR_UPDATE)
info->cache_in_use=0;
if (function == HA_EXTRA_RESET || function == HA_EXTRA_RESET_STATE)
{
@@ -41,8 +47,22 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function)
info->last_used_table=info->open_tables;
}
for (file=info->open_tables ; file != info->end_table ; file++)
- if ((error=mi_extra(file->table,function)))
+ {
+ if ((error=mi_extra(file->table, function, extra_arg)))
save_error=error;
+ }
}
DBUG_RETURN(save_error);
}
+
+
+void myrg_extrafunc(MYRG_INFO *info, invalidator_by_filename inv)
+{
+ MYRG_TABLE *file;
+ DBUG_ENTER("myrg_extrafunc");
+
+ for (file=info->open_tables ; file != info->end_table ; file++)
+ file->table->s->invalidator = inv;
+
+ DBUG_VOID_RETURN;
+}
diff --git a/myisammrg/myrg_info.c b/myisammrg/myrg_info.c
index 8ca830339b9..ba840ac444b 100644
--- a/myisammrg/myrg_info.c
+++ b/myisammrg/myrg_info.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
ulonglong myrg_position(MYRG_INFO *info)
{
@@ -28,8 +28,6 @@ ulonglong myrg_position(MYRG_INFO *info)
~(ulonglong) 0;
}
- /* If flag != 0 one only gets pos of last record */
-
int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag)
{
MYRG_TABLE *current_table;
@@ -55,15 +53,16 @@ int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag)
DBUG_PRINT("info2",("table: %s, offset: %lu",
file->table->filename,(ulong) file->file_offset));
}
- x->records = info->records;
- x->deleted = info->del;
- x->data_file_length = info->data_file_length;
- x->reclength = info->reclength;
- x->options = info->options;
+ x->records= info->records;
+ x->deleted= info->del;
+ x->data_file_length= info->data_file_length;
+ x->reclength= info->reclength;
+ x->options= info->options;
if (current_table)
- x->errkey = current_table->table->errkey;
+ x->errkey= current_table->table->errkey;
else
- x->errkey=0;
+ x->errkey= 0;
+ x->rec_per_key = info->rec_per_key_part;
}
DBUG_RETURN(0);
}
diff --git a/myisammrg/myrg_locking.c b/myisammrg/myrg_locking.c
index c89acca3918..e5a8d3f3d9d 100644
--- a/myisammrg/myrg_locking.c
+++ b/myisammrg/myrg_locking.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,11 +18,9 @@
Lock databases against read or write.
*/
-#include "mymrgdef.h"
+#include "myrg_def.h"
-int myrg_lock_database(
-MYRG_INFO *info,
-int lock_type)
+int myrg_lock_database(MYRG_INFO *info, int lock_type)
{
int error,new_error;
MYRG_TABLE *file;
diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c
index df94fb680cb..5188669cad1 100644
--- a/myisammrg/myrg_open.c
+++ b/myisammrg/myrg_open.c
@@ -14,29 +14,26 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* open a MYMERGE_-database */
+/* open a MyISAM MERGE table */
-#include "mymrgdef.h"
+#include "myrg_def.h"
#include <stddef.h>
#include <errno.h>
#ifdef VMS
#include "mrg_static.c"
#endif
-/* open a MYMERGE_-database.
-
- if handle_locking is 0 then exit with error if some database is locked
- if handle_locking is 1 then wait if database is locked
+/*
+ open a MyISAM MERGE table
+ if handle_locking is 0 then exit with error if some table is locked
+ if handle_locking is 1 then wait if table is locked
*/
-MYRG_INFO *myrg_open(
-const char *name,
-int mode,
-int handle_locking)
+MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{
int save_errno,i,errpos;
- uint files,dir_length,length;
+ uint files,dir_length,length,key_parts;
ulonglong file_offset;
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
MYRG_INFO info,*m_info;
@@ -63,45 +60,72 @@ int handle_locking)
{
if ((end=buff+length)[-1] == '\n')
end[-1]='\0';
- if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */
+ if (!buff[0])
+ continue; /* Skip empty lines */
+ if (buff[0] == '#')
{
- if (!test_if_hard_path(buff))
- {
- VOID(strmake(name_buff+dir_length,buff,
- sizeof(name_buff)-1-dir_length));
- VOID(cleanup_dirname(buff,name_buff));
+ if( !strncmp(buff+1,"INSERT_METHOD=",14))
+ { /* Lookup insert method */
+ int tmp=find_type(buff+15,&merge_insert_method,2);
+ info.merge_insert_method = (uint) (tmp >= 0 ? tmp : 0);
}
- if (!(isam=mi_open(buff,mode,test(handle_locking))))
- goto err;
- files++;
- last_isam=isam;
- if (info.reclength && info.reclength != isam->s->base.reclength)
- {
- my_errno=HA_ERR_WRONG_IN_RECORD;
+ continue; /* Skip comments */
+ }
+
+ if (!test_if_hard_path(buff))
+ {
+ VOID(strmake(name_buff+dir_length,buff,
+ sizeof(name_buff)-1-dir_length));
+ VOID(cleanup_dirname(buff,name_buff));
+ }
+ if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0))))
goto err;
- }
- info.reclength=isam->s->base.reclength;
+ files++;
+ last_isam=isam;
+ if (info.reclength && info.reclength != isam->s->base.reclength)
+ {
+ my_errno=HA_ERR_WRONG_MRG_TABLE_DEF;
+ goto err;
}
+ info.reclength=isam->s->base.reclength;
}
+ key_parts=(isam ? isam->s->base.key_parts : 0);
if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO)+
- files*sizeof(MYRG_TABLE),
+ files*sizeof(MYRG_TABLE)+
+ sizeof(long)*key_parts,
MYF(MY_WME))))
goto err;
*m_info=info;
- m_info->open_tables=(files) ? (MYRG_TABLE *) (m_info+1) : 0;
m_info->tables=files;
+ if (files)
+ {
+ m_info->open_tables=(MYRG_TABLE *) (m_info+1);
+ m_info->rec_per_key_part=(ulong *) (m_info->open_tables+files);
+ bzero((char*) m_info->rec_per_key_part,sizeof(long)*key_parts);
+ }
+ else
+ {
+ m_info->open_tables=0;
+ m_info->rec_per_key_part=0;
+ }
errpos=2;
for (i=files ; i-- > 0 ; )
{
+ uint j;
m_info->open_tables[i].table=isam;
m_info->options|=isam->s->options;
m_info->records+=isam->state->records;
m_info->del+=isam->state->del;
m_info->data_file_length+=isam->state->data_file_length;
+ for (j=0; j < key_parts; j++)
+ m_info->rec_per_key_part[j]+=isam->s->state.rec_per_key_part[j] / files;
if (i)
isam=(MI_INFO*) (isam->open_list.next->data);
}
+ /* Don't mark table readonly, for ALTER TABLE ... UNION=(...) to work */
+ m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA);
+
/* Fix fileinfo for easyer debugging (actually set by rrnd) */
file_offset=0;
for (i=0 ; (uint) i < files ; i++)
diff --git a/myisammrg/myrg_panic.c b/myisammrg/myrg_panic.c
index 99a1f6828d1..ab08b8082c3 100644
--- a/myisammrg/myrg_panic.c
+++ b/myisammrg/myrg_panic.c
@@ -1,20 +1,20 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/* if flag == HA_PANIC_CLOSE then all misam files are closed */
/* if flag == HA_PANIC_WRITE then all misam files are unlocked and
diff --git a/myisammrg/myrg_queue.c b/myisammrg/myrg_queue.c
index d6f831db48c..5ec382feb91 100644
--- a/myisammrg/myrg_queue.c
+++ b/myisammrg/myrg_queue.c
@@ -14,9 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Read record based on a key */
-
-#include "mymrgdef.h"
+#include "myrg_def.h"
static int queue_key_cmp(void *keyseg, byte *a, byte *b)
{
@@ -55,3 +53,13 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
}
return error;
}
+
+int _myrg_mi_read_record(MI_INFO *info, byte *buf)
+{
+ if (!(*info->read_record)(info,info->lastpos,buf))
+ {
+ info->update|= HA_STATE_AKTIV; /* Record is read */
+ return 0;
+ }
+ return my_errno;
+}
diff --git a/myisammrg/myrg_range.c b/myisammrg/myrg_range.c
new file mode 100644
index 00000000000..7644ae40c7b
--- /dev/null
+++ b/myisammrg/myrg_range.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "myrg_def.h"
+
+ha_rows myrg_records_in_range(MYRG_INFO *info, int inx, const byte *start_key,
+ uint start_key_len,
+ enum ha_rkey_function start_search_flag,
+ const byte *end_key, uint end_key_len,
+ enum ha_rkey_function end_search_flag)
+{
+ ha_rows records=0, res;
+ MYRG_TABLE *table;
+
+ for (table=info->open_tables ; table != info->end_table ; table++)
+ {
+ res=mi_records_in_range(table->table, inx,
+ start_key, start_key_len, start_search_flag,
+ end_key, end_key_len, end_search_flag);
+ if (res == HA_POS_ERROR)
+ return HA_POS_ERROR;
+ if (records > HA_POS_ERROR - res)
+ return HA_POS_ERROR-1;
+ records+=res;
+ }
+ return records;
+}
+
diff --git a/myisammrg/myrg_rfirst.c b/myisammrg/myrg_rfirst.c
index 0625e848660..9ba07686c47 100644
--- a/myisammrg/myrg_rfirst.c
+++ b/myisammrg/myrg_rfirst.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/* Read first row according to specific key */
@@ -45,5 +45,5 @@ int myrg_rfirst(MYRG_INFO *info, byte *buf, int inx)
return HA_ERR_END_OF_FILE;
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
- return mi_rrnd(mi,buf,mi->lastpos);
+ return _myrg_mi_read_record(mi,buf);
}
diff --git a/myisammrg/myrg_rkey.c b/myisammrg/myrg_rkey.c
index cd2c73c8ec2..fbfa7f24921 100644
--- a/myisammrg/myrg_rkey.c
+++ b/myisammrg/myrg_rkey.c
@@ -27,7 +27,7 @@
*/
-#include "mymrgdef.h"
+#include "myrg_def.h"
/* todo: we could store some additional info to speedup lookups:
column (key, keyseg) can be constant per table
@@ -36,7 +36,7 @@
SerG
*/
-int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key,
+int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
uint key_len, enum ha_rkey_function search_flag)
{
byte *key_buff;
@@ -83,5 +83,5 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key,
return HA_ERR_KEY_NOT_FOUND;
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
- return mi_rrnd(mi,record,mi->lastpos);
+ return _myrg_mi_read_record(mi,buf);
}
diff --git a/myisammrg/myrg_rlast.c b/myisammrg/myrg_rlast.c
index f41844dfd5c..96bb798bd4f 100644
--- a/myisammrg/myrg_rlast.c
+++ b/myisammrg/myrg_rlast.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/* Read last row with the same key as the previous read. */
@@ -45,6 +45,6 @@ int myrg_rlast(MYRG_INFO *info, byte *buf, int inx)
return HA_ERR_END_OF_FILE;
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
- return mi_rrnd(mi,buf,mi->lastpos);
+ return _myrg_mi_read_record(mi,buf);
}
diff --git a/myisammrg/myrg_rnext.c b/myisammrg/myrg_rnext.c
index 703ca29632b..0929c63fc1d 100644
--- a/myisammrg/myrg_rnext.c
+++ b/myisammrg/myrg_rnext.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/*
Read next row with the same key as previous read
@@ -49,5 +49,5 @@ int myrg_rnext(MYRG_INFO *info, byte *buf, int inx)
/* now, mymerge's read_next is as simple as one queue_top */
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
- return mi_rrnd(mi,buf,mi->lastpos);
+ return _myrg_mi_read_record(mi,buf);
}
diff --git a/myisammrg/myrg_rprev.c b/myisammrg/myrg_rprev.c
index 8c43b40035a..797993e903d 100644
--- a/myisammrg/myrg_rprev.c
+++ b/myisammrg/myrg_rprev.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
/*
Read previous row with the same key as previous read
@@ -49,5 +49,5 @@ int myrg_rprev(MYRG_INFO *info, byte *buf, int inx)
/* now, mymerge's read_prev is as simple as one queue_top */
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
- return mi_rrnd(mi,buf,mi->lastpos);
+ return _myrg_mi_read_record(mi,buf);
}
diff --git a/myisammrg/myrg_rrnd.c b/myisammrg/myrg_rrnd.c
index de731e58d5b..d623ea8ea9c 100644
--- a/myisammrg/myrg_rrnd.c
+++ b/myisammrg/myrg_rrnd.c
@@ -19,12 +19,12 @@
get by myrg_info(). The next record can be read with pos= -1 */
-#include "mymrgdef.h"
+#include "myrg_def.h"
static MYRG_TABLE *find_table(MYRG_TABLE *start,MYRG_TABLE *end,ulonglong pos);
/*
- If filepos == HA_OFFSET_ERROR, read next
+ If filepos == HA_OFFSET_ERROR, read next
Returns same as mi_rrnd:
0 = Ok.
HA_ERR_RECORD_DELETED = Record is deleted.
@@ -48,7 +48,7 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos)
}
isam_info=(info->current_table=info->open_tables)->table;
if (info->cache_in_use)
- mi_extra(isam_info,HA_EXTRA_CACHE);
+ mi_extra(isam_info,HA_EXTRA_CACHE,(byte*) &info->cache_size);
filepos=isam_info->s->pack.header_length;
isam_info->lastinx= (uint) -1; /* Can't forward or backward */
}
@@ -66,13 +66,15 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos)
HA_ERR_END_OF_FILE)
DBUG_RETURN(error);
if (info->cache_in_use)
- mi_extra(info->current_table->table,HA_EXTRA_NO_CACHE);
+ mi_extra(info->current_table->table, HA_EXTRA_NO_CACHE,
+ (byte*) &info->cache_size);
if (info->current_table+1 == info->end_table)
DBUG_RETURN(HA_ERR_END_OF_FILE);
info->current_table++;
info->last_used_table=info->current_table;
if (info->cache_in_use)
- mi_extra(info->current_table->table,HA_EXTRA_CACHE);
+ mi_extra(info->current_table->table, HA_EXTRA_CACHE,
+ (byte*) &info->cache_size);
info->current_table->file_offset=
info->current_table[-1].file_offset+
info->current_table[-1].table->state->data_file_length;
diff --git a/myisammrg/myrg_rsame.c b/myisammrg/myrg_rsame.c
index 301b96e667b..f6b2164dc21 100644
--- a/myisammrg/myrg_rsame.c
+++ b/myisammrg/myrg_rsame.c
@@ -1,30 +1,28 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mymrgdef.h"
+#include "myrg_def.h"
int myrg_rsame(MYRG_INFO *info,byte *record,int inx)
{
if (inx) /* not yet used, should be 0 */
- {
- return(my_errno=HA_ERR_WRONG_INDEX);
- }
+ return (my_errno=HA_ERR_WRONG_INDEX);
+
if (!info->current_table)
- {
- return(my_errno=HA_ERR_NO_ACTIVE_RECORD);
- }
+ return (my_errno=HA_ERR_NO_ACTIVE_RECORD);
+
return mi_rsame(info->current_table->table,record,inx);
}
diff --git a/myisammrg/myrg_static.c b/myisammrg/myrg_static.c
index 88eb095382b..b21b834ac24 100644
--- a/myisammrg/myrg_static.c
+++ b/myisammrg/myrg_static.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,7 +20,11 @@
*/
#ifndef stdin
-#include "mymrgdef.h"
+#include "myrg_def.h"
#endif
LIST *myrg_open_list=0;
+static const char *merge_insert_methods[] =
+{ "FIRST", "LAST", NullS };
+TYPELIB merge_insert_method= { array_elements(merge_insert_methods)-1,"",
+ merge_insert_methods};
diff --git a/myisammrg/myrg_update.c b/myisammrg/myrg_update.c
index b75c6ea6f9b..7b9f614b965 100644
--- a/myisammrg/myrg_update.c
+++ b/myisammrg/myrg_update.c
@@ -1,26 +1,27 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Update last read record */
-#include "mymrgdef.h"
+#include "myrg_def.h"
int myrg_update(register MYRG_INFO *info,const byte *oldrec, byte *newrec)
{
if (!info->current_table)
- return(my_errno=HA_ERR_NO_ACTIVE_RECORD);
+ return (my_errno=HA_ERR_NO_ACTIVE_RECORD);
+
return mi_update(info->current_table->table,oldrec,newrec);
}
diff --git a/myisammrg/myrg_write.c b/myisammrg/myrg_write.c
new file mode 100644
index 00000000000..0f191edc23c
--- /dev/null
+++ b/myisammrg/myrg_write.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2001 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Write a row to a MyISAM MERGE table */
+
+#include "myrg_def.h"
+
+int myrg_write(register MYRG_INFO *info, byte *rec)
+{
+ /* [phi] MERGE_WRITE_DISABLED is handled by the else case */
+ if (info->merge_insert_method == MERGE_INSERT_TO_FIRST)
+ return mi_write(info->open_tables[0].table,rec);
+ else if (info->merge_insert_method == MERGE_INSERT_TO_LAST)
+ return mi_write(info->end_table[-1].table,rec);
+ else /* unsupported insertion method */
+ return (my_errno= HA_ERR_WRONG_COMMAND);
+}
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index d897bdecb59..66f931133e3 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -31,6 +31,7 @@ dist-hook:
$(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include
$(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r
$(INSTALL_DATA) $(srcdir)/std_data/*.dat $(srcdir)/std_data/*.001 $(distdir)/std_data
+ $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data
install-data-local:
$(mkinstalldirs) \
@@ -47,6 +48,7 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/r/*.require $(DESTDIR)$(testdir)/r
$(INSTALL_DATA) $(srcdir)/include/*.inc $(DESTDIR)$(testdir)/include
$(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data
+ $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(DESTDIR)$(testdir)/std_data
SUFFIXES = .sh
@@ -62,6 +64,8 @@ SUFFIXES = .sh
-e 's!@''libexecdir''@!$(libexecdir)!g' \
-e 's!@''PERL''@!@PERL@!' \
-e 's!@''VERSION''@!@VERSION@!' \
+ -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \
+ -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \
-e 's!@''MYSQL_SERVER_SUFFIX''@!@MYSQL_SERVER_SUFFIX@!' \
$< > $@-t
@CHMOD@ +x $@-t
diff --git a/mysql-test/create-test-result b/mysql-test/create-test-result
index 24c3d175303..bfd64f32fc5 100755
--- a/mysql-test/create-test-result
+++ b/mysql-test/create-test-result
@@ -5,7 +5,7 @@
# If you have a spare moment feel free to improve it - the right way is
# to start mysqld yourself and run mysqltest -r
-RESULT_DIR=r/3.23
+RESULT_DIR=r
if [ -z $EDITOR] ; then
EDITOR=vi
fi
@@ -32,7 +32,7 @@ result_file=$RESULT_DIR/$test_name.result
touch $result_file
echo "Running the test case against empty file, will fail, but don't worry"
-./mysql-test-run $test_name
+./mysql-test-run --do-test=$test_name
reject_file=$result_file.reject
diff --git a/mysql-test/fix-result b/mysql-test/fix-result
new file mode 100755
index 00000000000..bd380332ff5
--- /dev/null
+++ b/mysql-test/fix-result
@@ -0,0 +1,22 @@
+#! /bin/sh
+
+# Sasha's hack to fix results generated with mysql-test-run --record
+# to be version and test port independent. In some cases, further minor
+# manual edititing may be required, but most of the time it should not
+# happen
+
+#It is assumed we are running the script in mysql-test directory
+
+VERSION=4.0.1-alpha-debug-log
+TEST_CASE=$1
+
+if [ -z "$TEST_CASE" ] ;
+then
+ echo "usage: $0 test_case_name"
+ exit 1
+fi
+
+../extra/replace $VERSION '$VERSION' 9306 '$MASTER_MYPORT' 9307 \
+'$SLAVE_MYPORT' \\ \\\\ -- r/$TEST_CASE.result
+
+
diff --git a/mysql-test/include/check_var_limit.inc b/mysql-test/include/check_var_limit.inc
new file mode 100644
index 00000000000..f955aeb345e
--- /dev/null
+++ b/mysql-test/include/check_var_limit.inc
@@ -0,0 +1,9 @@
+#
+# Check that second part of $LIMIT is between $MIN_LIMIT and $MAX_LIMIT
+# This is useful to check that a variable from SHOW_VARIABLES is within
+# certain limits. Check query_cache_merge.test for an example of using this.
+#
+-- require r/check_var_limit.require
+disable_query_log;
+eval select SUBSTRING_INDEX("$LIMIT", "\\t", -1) BETWEEN $MIN_LIMIT AND $MAX_LIMIT as "limit";
+enable_query_log;
diff --git a/mysql-test/include/have_bdb.inc b/mysql-test/include/have_bdb.inc
index 0126e30210f..3f7377e7515 100644
--- a/mysql-test/include/have_bdb.inc
+++ b/mysql-test/include/have_bdb.inc
@@ -1,2 +1,4 @@
-- require r/have_bdb.require
+disable_query_log;
show variables like "have_bdb";
+enable_query_log;
diff --git a/mysql-test/include/have_crypt.inc b/mysql-test/include/have_crypt.inc
new file mode 100644
index 00000000000..fe1f974bffd
--- /dev/null
+++ b/mysql-test/include/have_crypt.inc
@@ -0,0 +1,4 @@
+-- require r/have_crypt.require
+disable_query_log;
+show variables like "have_crypt";
+enable_query_log;
diff --git a/mysql-test/include/have_gemini.inc b/mysql-test/include/have_gemini.inc
deleted file mode 100644
index 78a84ac6f3e..00000000000
--- a/mysql-test/include/have_gemini.inc
+++ /dev/null
@@ -1,2 +0,0 @@
--- require r/have_gemini.require
-show variables like "have_gemini";
diff --git a/mysql-test/include/have_innodb.inc b/mysql-test/include/have_innodb.inc
index 7dcaef44878..4f83d378cbc 100644
--- a/mysql-test/include/have_innodb.inc
+++ b/mysql-test/include/have_innodb.inc
@@ -1,2 +1,4 @@
-- require r/have_innodb.require
+disable_query_log;
show variables like "have_innodb";
+enable_query_log;
diff --git a/mysql-test/include/have_isam.inc b/mysql-test/include/have_isam.inc
index d83328f70f4..830170c921f 100644
--- a/mysql-test/include/have_isam.inc
+++ b/mysql-test/include/have_isam.inc
@@ -1,2 +1,4 @@
-- require r/have_isam.require
+disable_query_log;
show variables like "have_isam";
+enable_query_log;
diff --git a/mysql-test/include/have_openssl.inc b/mysql-test/include/have_openssl.inc
new file mode 100644
index 00000000000..54c5b04b3e4
--- /dev/null
+++ b/mysql-test/include/have_openssl.inc
@@ -0,0 +1,4 @@
+-- require r/have_openssl.require
+disable_query_log;
+show variables like "have_openssl";
+enable_query_log;
diff --git a/mysql-test/include/have_openssl_1.inc b/mysql-test/include/have_openssl_1.inc
new file mode 100644
index 00000000000..887309c7e23
--- /dev/null
+++ b/mysql-test/include/have_openssl_1.inc
@@ -0,0 +1,4 @@
+-- require r/have_openssl_1.require
+disable_query_log;
+SHOW STATUS LIKE 'Ssl_cipher';
+enable_query_log;
diff --git a/mysql-test/include/have_query_cache.inc b/mysql-test/include/have_query_cache.inc
new file mode 100644
index 00000000000..e5e6052c9a7
--- /dev/null
+++ b/mysql-test/include/have_query_cache.inc
@@ -0,0 +1,4 @@
+-- require r/have_query_cache.require
+disable_query_log;
+show variables like "have_query_cache";
+enable_query_log;
diff --git a/mysql-test/include/master-slave.inc b/mysql-test/include/master-slave.inc
index 61077f898f6..474b1357e9e 100644
--- a/mysql-test/include/master-slave.inc
+++ b/mysql-test/include/master-slave.inc
@@ -1,11 +1,13 @@
-connect (master,localhost,root,,test,0,mysql-master.sock);
-connect (master1,localhost,root,,test,0,mysql-master.sock);
-connect (slave,localhost,root,,test,0,mysql-slave.sock);
-connect (slave1,localhost,root,,test,0,mysql-slave.sock);
+connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connect (master1,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
+connect (slave1,127.0.0.1,root,,test,$SLAVE_MYPORT,);
connection slave;
+--error 0,1199
!slave stop;
@r/slave-stopped.result show status like 'Slave_running';
connection master;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
connection slave;
reset slave;
@@ -13,3 +15,6 @@ reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
slave start;
@r/slave-running.result show status like 'Slave_running';
+
+# Set the default connection to 'master'
+connection master;
diff --git a/mysql-test/include/not_embedded.inc b/mysql-test/include/not_embedded.inc
new file mode 100644
index 00000000000..52ae026ece3
--- /dev/null
+++ b/mysql-test/include/not_embedded.inc
@@ -0,0 +1,5 @@
+-- require r/not_embedded.require
+disable_query_log;
+select version() like "%embedded%" as "have_embedded";
+enable_query_log;
+
diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh
index 6fe736644d3..8f90301d2d8 100644
--- a/mysql-test/install_test_db.sh
+++ b/mysql-test/install_test_db.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 1997, 1998, 1999 TCX DataKonsult AB & Monty Program KB & Detron HB
+# Copyright (C) 1997-2002 MySQL AB
# For a more info consult the file COPYRIGHT distributed with this file
# This scripts creates the privilege tables db, host, user, tables_priv,
@@ -30,7 +30,7 @@ else
fi
mdata=$data/mysql
-
+EXTRA_ARG=""
if test ! -x $execdir/mysqld
then
@@ -57,9 +57,7 @@ if [ x$BINARY_DIST = x1 ] ; then
basedir=..
else
basedir=.
-rm -rf share
-mkdir share
-ln -f -s ../../sql/share share/mysql
+EXTRA_ARG="--language=../sql/share/english/"
fi
# Initialize variables
@@ -87,13 +85,15 @@ then
c_d="$c_d References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_d="$c_d Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_d="$c_d Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_d="$c_d PRIMARY KEY Host (Host,Db,User),"
c_d="$c_d KEY User (User)"
c_d="$c_d )"
c_d="$c_d comment='Database privileges';"
- i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y');
- INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y');"
+ i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
+ INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');"
fi
if test ! -f $mdata/host.frm
@@ -111,6 +111,8 @@ then
c_h="$c_h References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_h="$c_h Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_h="$c_h Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_h="$c_h PRIMARY KEY Host (Host,Db)"
c_h="$c_h )"
c_h="$c_h comment='Host privileges; Merged with database privileges';"
@@ -119,9 +121,9 @@ fi
if test ! -f $mdata/user.frm
then
c_u="$c_u CREATE TABLE user ("
- c_u="$c_u Host char(60) DEFAULT '' NOT NULL,"
- c_u="$c_u User char(16) DEFAULT '' NOT NULL,"
- c_u="$c_u Password char(16) DEFAULT '' NOT NULL,"
+ c_u="$c_u Host char(60) binary DEFAULT '' NOT NULL,"
+ c_u="$c_u User char(16) binary DEFAULT '' NOT NULL,"
+ c_u="$c_u Password char(16) binary DEFAULT '' NOT NULL,"
c_u="$c_u Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
@@ -136,16 +138,29 @@ then
c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Super_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL,"
+ c_u="$c_u ssl_cipher BLOB NOT NULL,"
+ c_u="$c_u x509_issuer BLOB NOT NULL,"
+ c_u="$c_u x509_subject BLOB NOT NULL,"
+ c_u="$c_u max_questions int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_updates int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_connections int(11) unsigned DEFAULT 0 NOT NULL,"
c_u="$c_u PRIMARY KEY Host (Host,User)"
c_u="$c_u )"
c_u="$c_u comment='Users and global privileges';"
- i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
- INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
- REPLACE INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
-
- INSERT INTO user VALUES ('localhost','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');
- INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');"
+ i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ REPLACE INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user (host,user) values ('localhost','');
+ INSERT INTO user (host,user) values ('$hostname','');"
fi
if test ! -f $mdata/func.frm
@@ -192,8 +207,11 @@ then
c_c="$c_c comment='Column privileges';"
fi
-if $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \
- --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb --skip-gemini << END_OF_DATA
+mysqld_boot=" $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \
+ --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $EXTRA_ARG"
+echo "running $mysqld_boot"
+
+if $mysqld_boot << END_OF_DATA
use mysql;
$c_d
$i_d
@@ -213,5 +231,6 @@ END_OF_DATA
then
exit 0
else
+ echo "Error executing mysqld --bootstrap"
exit 1
fi
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index f134ca7c519..5b39b167d7d 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -12,13 +12,21 @@
DB=test
DBPASSWD=
VERBOSE=""
-TZ=GMT-3; export TZ # for UNIX_TIMESTAMP tests to work
+USE_MANAGER=0
+MY_TZ=GMT-3
+TZ=$MY_TZ; export TZ # for UNIX_TIMESTAMP tests to work
+
+# For query_cache test
+ulimit -n 1024
#++
# Program Definitions
#--
-PATH=/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/bin/X11
+LC_COLLATE=C
+export LC_COLLATE
+PATH=/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin:/usr/bin/X11:$PATH
+MASTER_40_ARGS="--rpl-recovery-rank=1 --init-rpl-role=master"
# Standard functions
@@ -35,31 +43,84 @@ which ()
continue 2
fi
done
- echo "which: no $file in ($PATH)"
+ echo "Fatal error: Cannot find program $file in $PATH" 1>&2
exit 1
done
IFS="$save_ifs"
+ exit 0
+}
+
+
+sleep_until_file_deleted ()
+{
+ pid=$1;
+ file=$2
+ loop=$SLEEP_TIME_FOR_DELETE
+ while (test $loop -gt 0)
+ do
+ if [ ! -r $file ]
+ then
+ if test $pid != "0"
+ then
+ wait_for_pid $pid
+ fi
+ return
+ fi
+ sleep 1
+ loop=`expr $loop - 1`
+ done
+}
+
+sleep_until_file_created ()
+{
+ file=$1
+ loop=$2
+ org_time=$2
+ while (test $loop -gt 0)
+ do
+ if [ -r $file ]
+ then
+ return 0
+ fi
+ sleep 1
+ loop=`expr $loop - 1`
+ done
+ echo "ERROR: $file was not created in $org_time seconds; Aborting"
+ exit 1;
}
+# For the future
+
+wait_for_pid()
+{
+ pid=$1
+ #$WAIT_PID pid $SLEEP_TIME_FOR_DELETE
+}
# No paths below as we can't be sure where the program is!
SED=sed
-BASENAME=`which basename | $SED q`
+BASENAME=`which basename`
+if test $? != 0; then exit 1; fi
DIFF=`which diff | $SED q`
+if test $? != 0; then exit 1; fi
CAT=cat
CUT=cut
+HEAD=head
TAIL=tail
ECHO=echo # use internal echo if possible
EXPR=expr # use internal if possible
FIND=find
-GCOV=`which gcov | $SED q`
+GREP=grep
+if test $? != 0; then exit 1; fi
PRINTF=printf
RM=rm
-TIME=time
+if test $? != 0; then exit 1; fi
TR=tr
-XARGS=`which xargs | $SED q`
+XARGS=`which xargs`
+if test $? != 0; then exit 1; fi
+SORT=sort
# Are we using a source or a binary distribution?
@@ -90,7 +151,7 @@ else
BINARY_DIST=1
fi
-#BASEDIR is always one above mysql-test directory
+#BASEDIR is always one above mysql-test directory
CWD=`pwd`
cd ..
BASEDIR=`pwd`
@@ -99,7 +160,8 @@ MYSQL_TEST_DIR=$BASEDIR/mysql-test
export MYSQL_TEST_DIR
STD_DATA=$MYSQL_TEST_DIR/std_data
hostname=`hostname` # Installed in the mysql privilege table
-
+
+MANAGER_QUIET_OPT="-q"
TESTDIR="$MYSQL_TEST_DIR/t"
TESTSUFFIX=test
TOT_SKIP=0
@@ -109,21 +171,28 @@ TOT_TEST=0
USERT=0
SYST=0
REALT=0
+FAST_START=""
MYSQL_TMP_DIR=$MYSQL_TEST_DIR/var/tmp
SLAVE_LOAD_TMPDIR=../../var/tmp #needs to be same length to test logging
RES_SPACE=" "
MYSQLD_SRC_DIRS="strings mysys include extra regex isam merge myisam \
myisammrg heap sql"
+MY_LOG_DIR="$MYSQL_TEST_DIR/var/log"
#
# Set LD_LIBRARY_PATH if we are using shared libraries
#
-LD_LIBRARY_PATH="$BASEDIR/lib:$LD_LIBRARY_PATH"
-export LD_LIBRARY_PATH
+LD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$LD_LIBRARY_PATH"
+DYLD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$DYLD_LIBRARY_PATH"
+export LD_LIBRARY_PATH DYLD_LIBRARY_PATH
MASTER_RUNNING=0
MASTER_MYPORT=9306
SLAVE_RUNNING=0
SLAVE_MYPORT=9307
+MYSQL_MANAGER_PORT=9305 # needs to be out of the way of slaves
+MYSQL_MANAGER_PW_FILE=$MYSQL_TEST_DIR/var/tmp/manager.pwd
+MYSQL_MANAGER_LOG=$MYSQL_TEST_DIR/var/log/manager.log
+MYSQL_MANAGER_USER=root
NO_SLAVE=0
USER_TEST=
@@ -132,19 +201,42 @@ EXTRA_MYSQL_TEST_OPT=""
USE_RUNNING_SERVER=1
DO_GCOV=""
DO_GDB=""
+MANUAL_GDB=""
DO_DDD=""
DO_CLIENT_GDB=""
-SLEEP_TIME=2
+SLEEP_TIME_AFTER_RESTART=1
+SLEEP_TIME_FOR_DELETE=10
+SLEEP_TIME_FOR_FIRST_MASTER=400 # Enough time to create innodb tables
+SLEEP_TIME_FOR_SECOND_MASTER=30
+SLEEP_TIME_FOR_FIRST_SLAVE=400
+SLEEP_TIME_FOR_SECOND_SLAVE=30
+CHARACTER_SET=latin1
DBUSER=""
+START_WAIT_TIMEOUT=10
+STOP_WAIT_TIMEOUT=10
+MYSQL_TEST_SSL_OPTS=""
while test $# -gt 0; do
case "$1" in
--user=*) DBUSER=`$ECHO "$1" | $SED -e "s;--user=;;"` ;;
--force) FORCE=1 ;;
+ --verbose-manager) MANAGER_QUIET_OPT="" ;;
+ --old-master) MASTER_40_ARGS="";;
+ --master-binary=*)
+ MASTER_MYSQLD=`$ECHO "$1" | $SED -e "s;--master-binary=;;"` ;;
+ --slave-binary=*)
+ SLAVE_MYSQLD=`$ECHO "$1" | $SED -e "s;--slave-binary=;;"` ;;
--local) USE_RUNNING_SERVER="" ;;
+ --extern) USE_RUNNING_SERVER="1" ;;
--tmpdir=*) MYSQL_TMP_DIR=`$ECHO "$1" | $SED -e "s;--tmpdir=;;"` ;;
+ --local-master)
+ MASTER_MYPORT=3306;
+ EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT --host=127.0.0.1 \
+ --port=$MYSQL_MYPORT"
+ LOCAL_MASTER=1 ;;
--master_port=*) MASTER_MYPORT=`$ECHO "$1" | $SED -e "s;--master_port=;;"` ;;
--slave_port=*) SLAVE_MYPORT=`$ECHO "$1" | $SED -e "s;--slave_port=;;"` ;;
+ --manager-port=*) MYSQL_MANAGER_PORT=`$ECHO "$1" | $SED -e "s;--manager_port=;;"` ;;
--with-openssl)
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT \
--ssl-ca=$BASEDIR/SSL/cacert.pem \
@@ -153,28 +245,42 @@ while test $# -gt 0; do
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT \
--ssl-ca=$BASEDIR/SSL/cacert.pem \
--ssl-cert=$BASEDIR/SSL/server-cert.pem \
- --ssl-key=$BASEDIR/SSL/server-key.pem" ;;
- --skip-innobase)
- EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-innobase"
- EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-innobase" ;;
- --skip-bdb)
- EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-bdb"
- EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-bdb" ;;
+ --ssl-key=$BASEDIR/SSL/server-key.pem"
+ MYSQL_TEST_SSL_OPTS="--ssl-ca=$BASEDIR/SSL/cacert.pem \
+ --ssl-cert=$BASEDIR/SSL/client-cert.pem \
+ --ssl-key=$BASEDIR/SSL/client-key.pem" ;;
+ --no-manager | --skip-manager) USE_MANAGER=0 ;;
+ --manager)
+ USE_MANAGER=1
+ USE_RUNNING_SERVER=
+ ;;
+ --start-and-exit)
+ START_AND_EXIT=1
+ ;;
--skip-rpl) NO_SLAVE=1 ;;
--skip-test=*) SKIP_TEST=`$ECHO "$1" | $SED -e "s;--skip-test=;;"`;;
--do-test=*) DO_TEST=`$ECHO "$1" | $SED -e "s;--do-test=;;"`;;
+ --warnings | --log-warnings)
+ EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --log-warnings"
+ EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --log-warnings"
+ ;;
+ --wait-timeout=*)
+ START_WAIT_TIMEOUT=`$ECHO "$1" | $SED -e "s;--wait-timeout=;;"`
+ STOP_WAIT_TIMEOUT=$START_WAIT_TIMEOUT;;
--record)
RECORD=1;
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1" ;;
--bench)
DO_BENCH=1
NO_SLAVE=1
- ;;
+ ;;
--big*) # Actually --big-test
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1" ;;
+ --compress)
+ EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1" ;;
--sleep=*)
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1"
- SLEEP_TIME=`$ECHO "$1" | $SED -e "s;--sleep=;;"`
+ SLEEP_TIME_AFTER_RESTART=`$ECHO "$1" | $SED -e "s;--sleep=;;"`
;;
--user-test=*)
USER_TEST=`$ECHO "$1" | $SED -e "s;--user-test=;;"`
@@ -190,15 +296,20 @@ while test $# -gt 0; do
exit 1
fi
DO_GCOV=1
+ GCOV=`which gcov`
;;
--gprof )
DO_GPROF=1
- ;;
+ ;;
--gdb )
+ START_WAIT_TIMEOUT=300
+ STOP_WAIT_TIMEOUT=300
if [ x$BINARY_DIST = x1 ] ; then
$ECHO "Note: you will get more meaningful output on a source distribution compiled with debugging option when running tests with --gdb option"
fi
DO_GDB=1
+ # This needs to be checked properly
+ # USE_MANAGER=1
USE_RUNNING_SERVER=""
;;
--client-gdb )
@@ -206,6 +317,15 @@ while test $# -gt 0; do
$ECHO "Note: you will get more meaningful output on a source distribution compiled with debugging option when running tests with --client-gdb option"
fi
DO_CLIENT_GDB=1
+ EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --gdb"
+ EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb"
+ ;;
+ --manual-gdb )
+ DO_GDB=1
+ MANUAL_GDB=1
+ USE_RUNNING_SERVER=""
+ EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --gdb"
+ EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb"
;;
--ddd )
if [ x$BINARY_DIST = x1 ] ; then
@@ -213,17 +333,47 @@ while test $# -gt 0; do
fi
DO_DDD=1
USE_RUNNING_SERVER=""
+ EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --gdb"
+ EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb"
+ ;;
+ --valgrind)
+ VALGRIND=`which valgrind` # this will print an error if not found
+ # Give good warning to the user and stop
+ if [ -z "$VALGRIND" ] ; then
+ $ECHO "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://developer.kde.org/~sewardj ."
+ exit 1
+ fi
+ VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16"
+ EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb"
+ EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb"
+ SLEEP_TIME_AFTER_RESTART=10
+ SLEEP_TIME_FOR_DELETE=120
+ USE_RUNNING_SERVER=""
+ ;;
+ --valgrind-options=*)
+ TMP=`$ECHO "$1" | $SED -e "s;--valgrind-options=;;"`
+ VALGRIND="$VALGRIND $TMP"
+ ;;
+ --valgrind-all)
+ VALGRIND="$VALGRIND -v --show-reachable=yes"
;;
--skip-*)
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT $1"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT $1"
;;
+ --strace-client )
+ STRACE_CLIENT=1
+ ;;
--debug)
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT \
--debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/master.trace"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT \
--debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/slave.trace"
- EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT --debug"
+ EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT \
+ --debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqltest.trace"
+ ;;
+ --fast)
+ FAST_START=1
;;
-- ) shift; break ;;
--* ) $ECHO "Unrecognized option: $1"; exit 1 ;;
@@ -237,19 +387,21 @@ done
#--
MYRUN_DIR=$MYSQL_TEST_DIR/var/run
+MANAGER_PID_FILE="$MYRUN_DIR/manager.pid"
+
MASTER_MYDDIR="$MYSQL_TEST_DIR/var/master-data"
-MASTER_MYSOCK="$MYSQL_TMP_DIR/mysql-master.sock"
-MASTER_MYPID="$MYRUN_DIR/mysqld.pid"
-MASTER_MYLOG="$MYSQL_TEST_DIR/var/log/mysqld.log"
-MASTER_MYERR="$MYSQL_TEST_DIR/var/log/mysqld.err"
+MASTER_MYSOCK="$MYSQL_TMP_DIR/master.sock"
+MASTER_MYPID="$MYRUN_DIR/master.pid"
+MASTER_MYLOG="$MYSQL_TEST_DIR/var/log/master.log"
+MASTER_MYERR="$MYSQL_TEST_DIR/var/log/master.err"
SLAVE_MYDDIR="$MYSQL_TEST_DIR/var/slave-data"
-SLAVE_MYSOCK="$MYSQL_TMP_DIR/mysql-slave.sock"
-SLAVE_MYPID="$MYRUN_DIR/mysqld-slave.pid"
-SLAVE_MYLOG="$MYSQL_TEST_DIR/var/log/mysqld-slave.log"
-SLAVE_MYERR="$MYSQL_TEST_DIR/var/log/mysqld-slave.err"
+SLAVE_MYSOCK="$MYSQL_TMP_DIR/slave.sock"
+SLAVE_MYPID="$MYRUN_DIR/slave.pid"
+SLAVE_MYLOG="$MYSQL_TEST_DIR/var/log/slave.log"
+SLAVE_MYERR="$MYSQL_TEST_DIR/var/log/slave.err"
-CLIENT_MYLOG="$MYSQL_TEST_DIR/var/log/client.log"
+CURRENT_TEST="$MYSQL_TEST_DIR/var/log/current_test"
SMALL_SERVER="-O key_buffer_size=1M -O sort_buffer=256K -O max_heap_table_size=1M"
export MASTER_MYPORT
@@ -259,7 +411,7 @@ if [ x$SOURCE_DIST = x1 ] ; then
MY_BASEDIR=$MYSQL_TEST_DIR
else
MY_BASEDIR=$BASEDIR
-fi
+fi
# Create the directories
@@ -269,32 +421,64 @@ fi
[ -d $MYSQL_TEST_DIR/var ] || mkdir $MYSQL_TEST_DIR/var
[ -d $MYSQL_TEST_DIR/var/tmp ] || mkdir $MYSQL_TEST_DIR/var/tmp
[ -d $MYSQL_TEST_DIR/var/run ] || mkdir $MYSQL_TEST_DIR/var/run
+[ -d $MYSQL_TEST_DIR/var/log ] || mkdir $MYSQL_TEST_DIR/var/log
-[ -z "$COLUMNS" ] && COLUMNS=80
+if test ${COLUMNS:-0} -lt 80 ; then COLUMNS=80 ; fi
E=`$EXPR $COLUMNS - 8`
-DASH72=`$ECHO '------------------------------------------------------------------------'|$CUT -c 1-$E`
+DASH72=`$ECHO '------------------------------------------'|$CUT -c 1-$E`
# on source dist, we pick up freshly build executables
# on binary, use what is installed
if [ x$SOURCE_DIST = x1 ] ; then
- MYSQLD="$BASEDIR/sql/mysqld"
+ MYSQLD="$VALGRIND $BASEDIR/sql/mysqld"
if [ -f "$BASEDIR/client/.libs/lt-mysqltest" ] ; then
MYSQL_TEST="$BASEDIR/client/.libs/lt-mysqltest"
+ elif [ -f "$BASEDIR/client/.libs/mysqltest" ] ; then
+ MYSQL_TEST="$BASEDIR/client/.libs/mysqltest"
else
MYSQL_TEST="$BASEDIR/client/mysqltest"
fi
+ if [ -f "$BASEDIR/client/.libs/mysqldump" ] ; then
+ MYSQL_DUMP="$BASEDIR/client/.libs/mysqldump"
+ else
+ MYSQL_DUMP="$BASEDIR/client/mysqldump"
+ fi
+ if [ -f "$BASEDIR/client/.libs/mysqlbinlog" ] ; then
+ MYSQL_BINLOG="$BASEDIR/client/.libs/mysqlbinlog"
+ else
+ MYSQL_BINLOG="$BASEDIR/client/mysqlbinlog"
+ fi
+ if [ -n "$STRACE_CLIENT" ]; then
+ MYSQL_TEST="strace -o $MYSQL_TEST_DIR/var/log/mysqltest.strace $MYSQL_TEST"
+ fi
+
MYSQLADMIN="$BASEDIR/client/mysqladmin"
+ WAIT_PID="$BASEDIR/extra/mysql_waitpid"
+ MYSQL_MANAGER_CLIENT="$BASEDIR/client/mysqlmanagerc"
+ MYSQL_MANAGER="$BASEDIR/tools/mysqlmanager"
+ MYSQL_MANAGER_PWGEN="$BASEDIR/client/mysqlmanager-pwgen"
MYSQL="$BASEDIR/client/mysql"
LANGUAGE="$BASEDIR/sql/share/english/"
CHARSETSDIR="$BASEDIR/sql/share/charsets"
INSTALL_DB="./install_test_db"
else
- MYSQLD="$BASEDIR/bin/mysqld"
+ if test -x "$BASEDIR/libexec/mysqld"
+ then
+ MYSQLD="$VALGRIND $BASEDIR/libexec/mysqld"
+ else
+ MYSQLD="$VALGRIND $BASEDIR/bin/mysqld"
+ fi
MYSQL_TEST="$BASEDIR/bin/mysqltest"
+ MYSQL_DUMP="$BASEDIR/bin/mysqldump"
+ MYSQL_BINLOG="$BASEDIR/bin/mysqlbinlog"
MYSQLADMIN="$BASEDIR/bin/mysqladmin"
+ WAIT_PID="$BASEDIR/bin/mysql_waitpid"
+ MYSQL_MANAGER="$BASEDIR/bin/mysqlmanager"
+ MYSQL_MANAGER_CLIENT="$BASEDIR/bin/mysqlmanagerc"
+ MYSQL_MANAGER_PWGEN="$BASEDIR/bin/mysqlmanager-pwgen"
MYSQL="$BASEDIR/bin/mysql"
INSTALL_DB="./install_test_db -bin"
- if test -d "$BASEDIR/share/mysql/english"
+ if test -d "$BASEDIR/share/mysql/english"
then
LANGUAGE="$BASEDIR/share/mysql/english/"
CHARSETSDIR="$BASEDIR/share/mysql/charsets"
@@ -304,6 +488,21 @@ else
fi
fi
+MYSQL_DUMP="$MYSQL_DUMP --no-defaults -uroot --socket=$MASTER_MYSOCK"
+MYSQL_BINLOG="$MYSQL_BINLOG --no-defaults --local-load=$MYSQL_TMP_DIR"
+export MYSQL_DUMP
+export MYSQL_BINLOG
+
+if [ -z "$MASTER_MYSQLD" ]
+then
+MASTER_MYSQLD=$MYSQLD
+fi
+
+if [ -z "$SLAVE_MYSQLD" ]
+then
+SLAVE_MYSQLD=$MYSQLD
+fi
+
# If we should run all tests cases, we will use a local server for that
if [ -z "$1" ]
@@ -326,7 +525,9 @@ then
fi
-MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB --user=$DBUSER --password=$DBPASSWD --silent -v --tmpdir=$MYSQL_TMP_DIR"
+MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB \
+ --user=$DBUSER --password=$DBPASSWD --silent -v --skip-safemalloc \
+ --tmpdir=$MYSQL_TMP_DIR --port=$MASTER_MYPORT $MYSQL_TEST_SSL_OPTS"
MYSQL_TEST_BIN=$MYSQL_TEST
MYSQL_TEST="$MYSQL_TEST $MYSQL_TEST_ARGS"
GDB_CLIENT_INIT=$MYSQL_TMP_DIR/gdbinit.client
@@ -337,20 +538,14 @@ GCOV_ERR=$MYSQL_TMP_DIR/mysqld-gcov.err
GPROF_DIR=$MYSQL_TMP_DIR/gprof
GPROF_MASTER=$GPROF_DIR/master.gprof
GPROF_SLAVE=$GPROF_DIR/slave.gprof
-TIMEFILE="$MYSQL_TMP_DIR/mysqltest-time"
-SLAVE_MYSQLD=$MYSQLD #this can be changed later if we are doing gcov
+TIMEFILE="$MYSQL_TEST_DIR/var/log/mysqltest-time"
+if [ -n "$DO_CLIENT_GDB" -o -n "$DO_GDB" ] ; then
+ XTERM=`which xterm`
+fi
#++
# Function Definitions
#--
-wait_for_server_start ()
-{
- $MYSQLADMIN --no-defaults -u $DBUSER --silent -O connect_timeout=10 -w3 --host=$hostname --port=$1 ping >> $CLIENT_MYLOG 2>&1
- exit_code=$?
- if [ $exit_code != 0 ]; then
- echo "Error: Could not start $2, exit code $exit_code";
- fi
-}
prompt_user ()
{
@@ -365,12 +560,12 @@ show_failed_diff ()
reject_file=r/$1.reject
result_file=r/$1.result
eval_file=r/$1.eval
-
+
if [ -f $eval_file ]
then
result_file=$eval_file
fi
-
+
if [ -x "$DIFF" ] && [ -f $reject_file ]
then
echo "Below are the diffs between actual and expected results:"
@@ -380,7 +575,7 @@ show_failed_diff ()
echo "Please follow the instructions outlined at"
echo "http://www.mysql.com/doc/R/e/Reporting_mysqltest_bugs.html"
echo "to find the reason to this problem and how to report this."
- fi
+ fi
}
do_gdb_test ()
@@ -389,7 +584,7 @@ do_gdb_test ()
$ECHO "set args $mysql_test_args < $2" > $GDB_CLIENT_INIT
echo "Set breakpoints ( if needed) and type 'run' in gdb window"
#this xterm should not be backgrounded
- xterm -title "Client" -e gdb -x $GDB_CLIENT_INIT $MYSQL_TEST_BIN
+ $XTERM -title "Client" -e gdb -x $GDB_CLIENT_INIT $MYSQL_TEST_BIN
}
error () {
@@ -398,7 +593,9 @@ error () {
}
error_is () {
- $TR "\n" " " < $TIMEFILE | $SED -e 's/.* At line \(.*\)\: \(.*\)Command .*$/ \>\> Error at line \1: \2<\</'
+ $ECHO "Errors are (from $TIMEFILE) :"
+ $CAT < $TIMEFILE
+ $ECHO "(the last line(s) may be the ones that caused the die() in mysqltest)"
}
prefix_to_8() {
@@ -421,29 +618,66 @@ total_inc () {
TOT_TEST=`$EXPR $TOT_TEST + 1`
}
+
+skip_test() {
+ USERT=" ...."
+ SYST=" ...."
+ REALT=" ...."
+ pname=`$ECHO "$1 "|$CUT -c 1-24`
+ RES="$pname"
+ skip_inc
+ $ECHO "$RES$RES_SPACE [ skipped ]"
+}
+
report_stats () {
if [ $TOT_FAIL = 0 ]; then
$ECHO "All $TOT_TEST tests were successful."
else
- xten=`$EXPR $TOT_PASS \* 10000`
- raw=`$EXPR $xten / $TOT_TEST`
- raw=`$PRINTF %.4d $raw`
- whole=`$PRINTF %.2s $raw`
- xwhole=`$EXPR $whole \* 100`
- deci=`$EXPR $raw - $xwhole`
+ xten=`$EXPR $TOT_PASS \* 10000`
+ raw=`$EXPR $xten / $TOT_TEST`
+ raw=`$PRINTF %.4d $raw`
+ whole=`$PRINTF %.2s $raw`
+ xwhole=`$EXPR $whole \* 100`
+ deci=`$EXPR $raw - $xwhole`
$ECHO "Failed ${TOT_FAIL}/${TOT_TEST} tests, ${whole}.${deci}% successful."
$ECHO ""
- $ECHO "The log files in $MYSQL_TEST_DIR/var/log may give you some hint"
+ $ECHO "The log files in $MY_LOG_DIR may give you some hint"
$ECHO "of what when wrong."
$ECHO "If you want to report this error, please read first the documentation at"
$ECHO "http://www.mysql.com/doc/M/y/MySQL_test_suite.html"
fi
+
+ if test -z "$USE_RUNNING_SERVER"
+ then
+
+ # Report if there was any fatal warnings/errors in the log files
+ #
+ $RM -f $MY_LOG_DIR/warnings $MY_LOG_DIR/warnings.tmp
+ # Remove some non fatal warnings from the log files
+ $SED -e 's!Warning: Table:.* on delete!!g' \
+ $MY_LOG_DIR/*.err > $MY_LOG_DIR/warnings.tmp
+
+ found_error=0
+ # Find errors
+ for i in "^Warning:" "^Error:" "^==.* at 0x"
+ do
+ if `$GREP "$i" $MY_LOG_DIR/warnings.tmp >> $MY_LOG_DIR/warnings`
+ then
+ found_error=1
+ fi
+ done
+ $RM -f $MY_LOG_DIR/warnings.tmp
+ if [ $found_error = "1" ]
+ then
+ echo "WARNING: Got errors/warnings while running tests. Please examine"
+ echo "$MY_LOG_DIR/warnings for details."
+ fi
+ fi
}
mysql_install_db () {
$ECHO "Removing Stale Files"
- $RM -rf $MASTER_MYDDIR $SLAVE_MYDDIR $SLAVE_MYLOG $MASTER_MYLOG \
- $SLAVE_MYERR $MASTER_MYERR
+ $RM -rf $MASTER_MYDDIR $SLAVE_MYDDIR $MY_LOG_DIR/*
$ECHO "Installing Master Databases"
$INSTALL_DB
if [ $? != 0 ]; then
@@ -456,25 +690,31 @@ mysql_install_db () {
error "Could not install slave test DBs"
exit 1
fi
- # Give mysqld some time to die.
- sleep $SLEEP_TIME
+
+ for slave_num in 1 2 ;
+ do
+ $RM -rf var/slave$slave_num-data
+ mkdir -p var/slave$slave_num-data/mysql
+ mkdir -p var/slave$slave_num-data/test
+ cp var/slave-data/mysql/* var/slave$slave_num-data/mysql
+ done
return 0
}
gprof_prepare ()
{
- rm -rf $GPROF_DIR
- mkdir -p $GPROF_DIR
+ $RM -rf $GPROF_DIR
+ mkdir -p $GPROF_DIR
}
gprof_collect ()
{
if [ -f $MASTER_MYDDIR/gmon.out ]; then
- gprof $MYSQLD $MASTER_MYDDIR/gmon.out > $GPROF_MASTER
+ gprof $MASTER_MYSQLD $MASTER_MYDDIR/gmon.out > $GPROF_MASTER
echo "Master execution profile has been saved in $GPROF_MASTER"
fi
if [ -f $SLAVE_MYDDIR/gmon.out ]; then
- gprof $MYSQLD $SLAVE_MYDDIR/gmon.out > $GPROF_SLAVE
+ gprof $SLAVE_MYSQLD $SLAVE_MYDDIR/gmon.out > $GPROF_SLAVE
echo "Slave execution profile has been saved in $GPROF_SLAVE"
fi
}
@@ -499,173 +739,393 @@ gcov_collect () {
$ECHO "gcov info in $GCOV_MSG, errors in $GCOV_ERR"
}
+abort_if_failed()
+{
+ if [ ! $? = 0 ] ; then
+ echo $1
+ exit 1
+ fi
+}
-start_master()
+start_manager()
{
- [ x$MASTER_RUNNING = 1 ] && return
- #run master initialization shell script if one exists
- if [ -f "$master_init_script" ] ;
- then
- /bin/sh $master_init_script
+ if [ $USE_MANAGER = 0 ] ; then
+ echo "Manager disabled, skipping manager start."
+ $RM -f $MYSQL_MANAGER_LOG
+ return
+ fi
+ $ECHO "Starting MySQL Manager"
+ if [ -f "$MANAGER_PID_FILE" ] ; then
+ kill `cat $MANAGER_PID_FILE`
+ sleep 1
+ if [ -f "$MANAGER_PID_FILE" ] ; then
+ kill -9 `cat $MANAGER_PID_FILE`
+ sleep 1
fi
- cd $BASEDIR # for gcov
- # Remove old berkeley db log files that can confuse the server
- $RM -f $MASTER_MYDDIR/log.*
- #start master
- if [ -z "$DO_BENCH" ]
- then
- master_args="--no-defaults --log-bin=master-bin \
- --server-id=1 \
- --basedir=$MY_BASEDIR \
- --port=$MASTER_MYPORT \
- --exit-info=256 \
- --core \
- --datadir=$MASTER_MYDDIR \
- --pid-file=$MASTER_MYPID \
- --socket=$MASTER_MYSOCK \
- --log=$MASTER_MYLOG \
- --character-sets-dir=$CHARSETSDIR \
- --tmpdir=$MYSQL_TMP_DIR \
- --language=$LANGUAGE \
- --innodb_data_file_path=ibdata1:50M \
- $SMALL_SERVER \
- $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
- else
- master_args="--no-defaults --log-bin=master-bin --server-id=1 \
- --basedir=$MY_BASEDIR \
- --port=$MASTER_MYPORT \
- --datadir=$MASTER_MYDDIR \
- --pid-file=$MASTER_MYPID \
- --socket=$MASTER_MYSOCK \
- --default-character-set=$CHARACTER_SET \
- --core \
- --tmpdir=$MYSQL_TMP_DIR \
- --language=$LANGUAGE \
- --innodb_data_file_path=ibdata1:50M \
- $SMALL_SERVER \
- $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
- fi
- if [ x$DO_DDD = x1 ]
+ fi
+
+ $RM -f $MANAGER_PID_FILE
+ MYSQL_MANAGER_PW=`$MYSQL_MANAGER_PWGEN -u $MYSQL_MANAGER_USER \
+ -o $MYSQL_MANAGER_PW_FILE`
+ $MYSQL_MANAGER --log=$MYSQL_MANAGER_LOG --port=$MYSQL_MANAGER_PORT \
+ --password-file=$MYSQL_MANAGER_PW_FILE --pid-file=$MANAGER_PID_FILE
+ abort_if_failed "Could not start MySQL manager"
+ mysqltest_manager_args="--manager-host=localhost \
+ --manager-user=$MYSQL_MANAGER_USER \
+ --manager-password=$MYSQL_MANAGER_PW \
+ --manager-port=$MYSQL_MANAGER_PORT \
+ --manager-wait-timeout=$START_WAIT_TIMEOUT"
+ MYSQL_TEST="$MYSQL_TEST $mysqltest_manager_args"
+ MYSQL_TEST_ARGS="$MYSQL_TEST_ARGS $mysqltest_manager_args"
+ while [ ! -f $MANAGER_PID_FILE ] ; do
+ sleep 1
+ done
+ echo "Manager started"
+}
+
+stop_manager()
+{
+ if [ $USE_MANAGER = 0 ] ; then
+ return
+ fi
+ $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT -u$MYSQL_MANAGER_USER \
+ -p$MYSQL_MANAGER_PW -P $MYSQL_MANAGER_PORT <<EOF
+shutdown
+EOF
+ echo "Manager terminated"
+
+}
+
+manager_launch()
+{
+ ident=$1
+ shift
+ if [ $USE_MANAGER = 0 ] ; then
+ $@ >> $CUR_MYERR 2>&1 &
+ sleep 2 #hack
+ return
+ fi
+ $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \
+ --password=$MYSQL_MANAGER_PW --port=$MYSQL_MANAGER_PORT <<EOF
+def_exec $ident $@
+set_exec_stdout $ident $CUR_MYERR
+set_exec_stderr $ident $CUR_MYERR
+set_exec_con $ident root localhost $CUR_MYSOCK
+start_exec $ident $START_WAIT_TIMEOUT
+EOF
+ abort_if_failed "Could not execute manager command"
+}
+
+manager_term()
+{
+ pid=$1
+ ident=$2
+ if [ $USE_MANAGER = 0 ] ; then
+ # Shutdown time must be high as slave may be in reconnect
+ $MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock --connect_timeout=5 --shutdown_timeout=70 shutdown >> $MYSQL_MANAGER_LOG 2>&1
+ res=$?
+ # Some systems require an extra connect
+ $MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock --connect_timeout=1 ping >> $MYSQL_MANAGER_LOG 2>&1
+ if test $res = 0
then
- $ECHO "set args $master_args" > $GDB_MASTER_INIT
- ddd --debugger "gdb -x $GDB_MASTER_INIT" $MYSQLD &
- prompt_user "Hit enter to continue after you've started the master"
- elif [ x$DO_GDB = x1 ]
+ wait_for_pid $pid
+ fi
+ return $res
+ fi
+ $MYSQL_MANAGER_CLIENT $MANAGER_QUIET_OPT --user=$MYSQL_MANAGER_USER \
+ --password=$MYSQL_MANAGER_PW --port=$MYSQL_MANAGER_PORT <<EOF
+stop_exec $ident $STOP_WAIT_TIMEOUT
+EOF
+ abort_if_failed "Could not execute manager command"
+}
+
+
+start_master()
+{
+ if [ x$MASTER_RUNNING = x1 ] || [ x$LOCAL_MASTER = x1 ] ; then
+ return
+ fi
+ # Remove old berkeley db log files that can confuse the server
+ $RM -f $MASTER_MYDDIR/log.*
+ # Remove stale binary logs
+ $RM -f $MYSQL_TEST_DIR/var/log/master-bin.*
+ # Remove old master.info and relay-log.info files
+ $RM -f $MYSQL_TEST_DIR/var/master-data/master.info $MYSQL_TEST_DIR/var/master-data/relay-log.info
+
+ #run master initialization shell script if one exists
+
+ if [ -f "$master_init_script" ] ;
+ then
+ /bin/sh $master_init_script
+ fi
+ cd $BASEDIR # for gcov
+ if [ -z "$DO_BENCH" ]
+ then
+ master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin \
+ --server-id=1 \
+ --basedir=$MY_BASEDIR \
+ --port=$MASTER_MYPORT \
+ --local-infile \
+ --exit-info=256 \
+ --core \
+ --datadir=$MASTER_MYDDIR \
+ --pid-file=$MASTER_MYPID \
+ --socket=$MASTER_MYSOCK \
+ --log=$MASTER_MYLOG \
+ --character-sets-dir=$CHARSETSDIR \
+ --default-character-set=$CHARACTER_SET \
+ --tmpdir=$MYSQL_TMP_DIR \
+ --language=$LANGUAGE \
+ --innodb_data_file_path=ibdata1:50M \
+ --open-files-limit=1024 \
+ $MASTER_40_ARGS \
+ $SMALL_SERVER \
+ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
+ else
+ master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin \
+ --server-id=1 --rpl-recovery-rank=1 \
+ --basedir=$MY_BASEDIR --init-rpl-role=master \
+ --port=$MASTER_MYPORT \
+ --local-infile \
+ --datadir=$MASTER_MYDDIR \
+ --pid-file=$MASTER_MYPID \
+ --socket=$MASTER_MYSOCK \
+ --character-sets-dir=$CHARSETSDIR \
+ --default-character-set=$CHARACTER_SET \
+ --core \
+ --tmpdir=$MYSQL_TMP_DIR \
+ --language=$LANGUAGE \
+ --innodb_data_file_path=ibdata1:50M \
+ $MASTER_40_ARGS \
+ $SMALL_SERVER \
+ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
+ fi
+
+ CUR_MYERR=$MASTER_MYERR
+ CUR_MYSOCK=$MASTER_MYSOCK
+
+ if [ x$DO_DDD = x1 ]
+ then
+ $ECHO "set args $master_args" > $GDB_MASTER_INIT
+ manager_launch master ddd -display $DISPLAY --debugger \
+ "gdb -x $GDB_MASTER_INIT" $MASTER_MYSQLD
+ elif [ x$DO_GDB = x1 ]
+ then
+ if [ x$MANUAL_GDB = x1 ]
then
$ECHO "set args $master_args" > $GDB_MASTER_INIT
- xterm -title "Master" -e gdb -x $GDB_MASTER_INIT $MYSQLD &
- prompt_user "Hit enter to continue after you've started the master"
- else
- $MYSQLD $master_args >> $MASTER_MYERR 2>&1 &
- fi
- wait_for_server_start $MASTER_MYPORT master
+ $ECHO "To start gdb for the master , type in another window:"
+ $ECHO "cd $CWD ; gdb -x $GDB_MASTER_INIT $MASTER_MYSQLD"
+ wait_for_master=1500
+ else
+ ( $ECHO set args $master_args;
+ if [ $USE_MANAGER = 0 ] ; then
+ cat <<EOF
+b mysql_parse
+commands 1
+disa 1
+end
+r
+EOF
+ fi ) > $GDB_MASTER_INIT
+ manager_launch master $XTERM -display $DISPLAY \
+ -title "Master" -e gdb -x $GDB_MASTER_INIT $MASTER_MYSQLD
+ fi
+ else
+ manager_launch master $MASTER_MYSQLD $master_args
+ fi
+ sleep_until_file_created $MASTER_MYPID $wait_for_master
+ wait_for_master=$SLEEP_TIME_FOR_SECOND_MASTER
MASTER_RUNNING=1
}
start_slave()
{
- [ x$SKIP_SLAVE = x1 ] && return
- [ x$SLAVE_RUNNING = 1 ] && return
-
- #run slave initialization shell script if one exists
- if [ -f "$slave_init_script" ] ;
- then
- /bin/sh $slave_init_script
- fi
-
- if [ -z "$SLAVE_MASTER_INFO" ] ; then
- master_info="--master-user=root \
- --master-connect-retry=1 \
- --master-host=127.0.0.1 \
- --master-password= \
- --master-port=$MASTER_MYPORT \
- --server-id=2"
- else
- master_info=$SLAVE_MASTER_INFO
- fi
-
- $RM -f $SLAVE_MYDDIR/log.*
- slave_args="--no-defaults $master_info \
- --exit-info=256 \
- --log-bin=slave-bin --log-slave-updates \
- --log=$SLAVE_MYLOG \
- --basedir=$MY_BASEDIR \
- --datadir=$SLAVE_MYDDIR \
- --pid-file=$SLAVE_MYPID \
- --port=$SLAVE_MYPORT \
- --socket=$SLAVE_MYSOCK \
- --character-sets-dir=$CHARSETSDIR \
- --core \
- --tmpdir=$MYSQL_TMP_DIR \
- --language=$LANGUAGE \
- --skip-innodb --skip-slave-start \
- --master-retry-count=5 \
- $SMALL_SERVER \
- $EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT"
- if [ x$DO_DDD = x1 ]
- then
- $ECHO "set args $slave_args" > $GDB_SLAVE_INIT
- ddd --debugger "gdb -x $GDB_SLAVE_INIT" $SLAVE_MYSQLD &
- prompt_user "Hit enter to continue after you've started the slave"
- elif [ x$DO_GDB = x1 ]
+ [ x$SKIP_SLAVE = x1 ] && return
+ eval "this_slave_running=\$SLAVE$1_RUNNING"
+ [ x$this_slave_running = 1 ] && return
+ # When testing fail-safe replication, we will have more than one slave
+ # in this case, we start secondary slaves with an argument
+ slave_ident="slave$1"
+ if [ -n "$1" ] ;
+ then
+ slave_server_id=`$EXPR 2 + $1`
+ slave_rpl_rank=$slave_server_id
+ slave_port=`expr $SLAVE_MYPORT + $1`
+ slave_log="$SLAVE_MYLOG.$1"
+ slave_err="$SLAVE_MYERR.$1"
+ slave_datadir="$SLAVE_MYDDIR/../$slave_ident-data/"
+ slave_pid="$MYRUN_DIR/mysqld-$slave_ident.pid"
+ slave_sock="$SLAVE_MYSOCK-$1"
+ else
+ slave_server_id=2
+ slave_rpl_rank=2
+ slave_port=$SLAVE_MYPORT
+ slave_log=$SLAVE_MYLOG
+ slave_err=$SLAVE_MYERR
+ slave_datadir=$SLAVE_MYDDIR
+ slave_pid=$SLAVE_MYPID
+ slave_sock="$SLAVE_MYSOCK"
+ fi
+ # Remove stale binary logs and old master.info files
+ $RM -f $MYSQL_TEST_DIR/var/log/$slave_ident-*bin.*
+ $RM -f $slave_datadir/master.info $slave_datadir/relay-log.info
+
+ #run slave initialization shell script if one exists
+ if [ -f "$slave_init_script" ] ;
+ then
+ /bin/sh $slave_init_script
+ fi
+
+ if [ -z "$SLAVE_MASTER_INFO" ] ; then
+ master_info="--master-user=root \
+ --master-connect-retry=1 \
+ --master-host=127.0.0.1 \
+ --master-password="" \
+ --master-port=$MASTER_MYPORT \
+ --server-id=$slave_server_id --rpl-recovery-rank=$slave_rpl_rank"
+ else
+ master_info=$SLAVE_MASTER_INFO
+ fi
+
+ $RM -f $slave_datadir/log.*
+ slave_args="--no-defaults $master_info \
+ --exit-info=256 \
+ --log-bin=$MYSQL_TEST_DIR/var/log/$slave_ident-bin \
+ --relay-log=$MYSQL_TEST_DIR/var/log/$slave_ident-relay-bin \
+ --log-slave-updates \
+ --log=$slave_log \
+ --basedir=$MY_BASEDIR \
+ --datadir=$slave_datadir \
+ --pid-file=$slave_pid \
+ --port=$slave_port \
+ --socket=$slave_sock \
+ --character-sets-dir=$CHARSETSDIR \
+ --default-character-set=$CHARACTER_SET \
+ --core --init-rpl-role=slave \
+ --tmpdir=$MYSQL_TMP_DIR \
+ --language=$LANGUAGE \
+ --skip-innodb --skip-slave-start \
+ --slave-load-tmpdir=$SLAVE_LOAD_TMPDIR \
+ --report-host=127.0.0.1 --report-user=root \
+ --report-port=$slave_port \
+ --master-retry-count=10 \
+ -O slave_net_timeout=10 \
+ $SMALL_SERVER \
+ $EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT"
+ CUR_MYERR=$slave_err
+ CUR_MYSOCK=$slave_sock
+
+ if [ x$DO_DDD = x1 ]
+ then
+ $ECHO "set args $master_args" > $GDB_SLAVE_INIT
+ manager_launch $slave_ident ddd -display $DISPLAY --debugger \
+ "gdb -x $GDB_SLAVE_INIT" $SLAVE_MYSQLD
+ elif [ x$DO_GDB = x1 ]
+ then
+ if [ x$MANUAL_GDB = x1 ]
then
$ECHO "set args $slave_args" > $GDB_SLAVE_INIT
- xterm -title "Slave" -e gdb -x $GDB_SLAVE_INIT $SLAVE_MYSQLD &
- prompt_user "Hit enter to continue after you've started the slave"
+ echo "To start gdb for the slave, type in another window:"
+ echo "cd $CWD ; gdb -x $GDB_SLAVE_INIT $SLAVE_MYSQLD"
+ wait_for_slave=1500
else
- $SLAVE_MYSQLD $slave_args >> $SLAVE_MYERR 2>&1 &
+ ( $ECHO set args $slave_args;
+ if [ $USE_MANAGER = 0 ] ; then
+ cat <<EOF
+b mysql_parse
+commands 1
+disa 1
+end
+r
+EOF
+ fi ) > $GDB_SLAVE_INIT
+ manager_launch $slave_ident $XTERM -display $DISPLAY -title "Slave" -e \
+ gdb -x $GDB_SLAVE_INIT $SLAVE_MYSQLD
fi
- wait_for_server_start $SLAVE_MYPORT slave
- SLAVE_RUNNING=1
+ else
+ manager_launch $slave_ident $SLAVE_MYSQLD $slave_args
+ fi
+ eval "SLAVE$1_RUNNING=1"
+ sleep_until_file_created $slave_pid $wait_for_slave
+ wait_for_slave=$SLEEP_TIME_FOR_SECOND_SLAVE
}
-mysql_start () {
- $ECHO "Starting MySQL daemon"
- start_master
- start_slave
- cd $MYSQL_TEST_DIR
- return 1
+mysql_start ()
+{
+# We should not start the daemon here as we don't know the arguments
+# for the test. Better to let the test start the daemon
+
+# $ECHO "Starting MySQL daemon"
+# start_master
+# start_slave
+ cd $MYSQL_TEST_DIR
+ return 1
}
stop_slave ()
{
- if [ x$SLAVE_RUNNING = x1 ]
+ eval "this_slave_running=\$SLAVE$1_RUNNING"
+ slave_ident="slave$1"
+ if [ -n "$1" ] ;
then
- $MYSQLADMIN --no-defaults --socket=$SLAVE_MYSOCK -u root -O shutdown_timeout=20 shutdown
- if [ $? != 0 ] && [ -f $SLAVE_MYPID ]
+ slave_pid="$MYRUN_DIR/mysqld-$slave_ident.pid"
+ else
+ slave_pid=$SLAVE_MYPID
+ fi
+ if [ x$this_slave_running = x1 ]
+ then
+ pid=`$CAT $slave_pid`
+ manager_term $pid $slave_ident
+ if [ $? != 0 ] && [ -f $slave_pid ]
then # try harder!
- $ECHO "slave not cooperating with mysqladmin, will try manual kill"
- kill `$CAT $SLAVE_MYPID`
- sleep $SLEEP_TIME
- if [ -f $SLAVE_MYPID ] ; then
- $ECHO "slave refused to die. Sending SIGKILL"
- kill -9 `$CAT $SLAVE_MYPID`
- $RM -f $SLAVE_MYPID
- else
- $ECHO "slave responded to SIGTERM "
- fi
+ $ECHO "slave not cooperating with mysqladmin, will try manual kill"
+ kill $pid
+ sleep_until_file_deleted $pid $slave_pid
+ if [ -f $slave_pid ] ; then
+ $ECHO "slave refused to die. Sending SIGKILL"
+ kill -9 `$CAT $slave_pid`
+ $RM -f $slave_pid
+ else
+ $ECHO "slave responded to SIGTERM "
+ fi
+ else
+ sleep $SLEEP_TIME_AFTER_RESTART
fi
- SLAVE_RUNNING=0
- fi
+ eval "SLAVE$1_RUNNING=0"
+ fi
+}
+
+stop_slave_threads ()
+{
+ eval "this_slave_running=\$SLAVE$1_RUNNING"
+ slave_ident="slave$1"
+ if [ x$this_slave_running = x1 ]
+ then
+ $MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$slave_ident.sock stop-slave > /dev/null 2>&1
+ fi
}
stop_master ()
{
if [ x$MASTER_RUNNING = x1 ]
then
- $MYSQLADMIN --no-defaults --socket=$MASTER_MYSOCK -u root -O shutdown_timeout=20 shutdown
+ pid=`$CAT $MASTER_MYPID`
+ manager_term $pid master
if [ $? != 0 ] && [ -f $MASTER_MYPID ]
then # try harder!
- $ECHO "master not cooperating with mysqladmin, will try manual kill"
- kill `$CAT $MASTER_MYPID`
- sleep $SLEEP_TIME
- if [ -f $MASTER_MYPID ] ; then
- $ECHO "master refused to die. Sending SIGKILL"
- kill -9 `$CAT $MASTER_MYPID`
- $RM -f $MASTER_MYPID
- else
- $ECHO "master responded to SIGTERM "
- fi
+ $ECHO "master not cooperating with mysqladmin, will try manual kill"
+ kill $pid
+ sleep_until_file_deleted $pid $MASTER_MYPID
+ if [ -f $MASTER_MYPID ] ; then
+ $ECHO "master refused to die. Sending SIGKILL"
+ kill -9 `$CAT $MASTER_MYPID`
+ $RM -f $MASTER_MYPID
+ else
+ $ECHO "master responded to SIGTERM "
+ fi
+ else
+ sleep $SLEEP_TIME_AFTER_RESTART
fi
MASTER_RUNNING=0
fi
@@ -679,22 +1139,23 @@ mysql_stop ()
stop_master
$ECHO "Master shutdown finished"
stop_slave
+ stop_slave 1
+ stop_slave 2
$ECHO "Slave shutdown finished"
-
+
return 1
}
-mysql_restart () {
-
- mysql_stop
- mysql_start
-
- return 1
+mysql_restart ()
+{
+ mysql_stop
+ mysql_start
+ return 1
}
mysql_loadstd () {
-
- # cp $STD_DATA/*.frm $STD_DATA/*.MRG $MASTER_MYDDIR/test
+
+ # cp $STD_DATA/*.frm $STD_DATA/*.MRG $MASTER_MYDDIR/test
return 1
}
@@ -707,64 +1168,83 @@ run_testcase ()
master_init_script=$TESTDIR/$tname-master.sh
slave_init_script=$TESTDIR/$tname-slave.sh
slave_master_info_file=$TESTDIR/$tname.slave-mi
+ echo $tname > $CURRENT_TEST
SKIP_SLAVE=`$EXPR \( $tname : rpl \) = 0`
- if [ -n "$SKIP_TEST" ] ; then
+ if [ $USE_MANAGER = 1 ] ; then
+ many_slaves=`$EXPR \( \( $tname : rpl_failsafe \) != 0 \) \| \( \( $tname : rpl_chain_temp_table \) != 0 \)`
+ fi
+
+ if [ -n "$SKIP_TEST" ] ; then
SKIP_THIS_TEST=`$EXPR \( $tname : "$SKIP_TEST" \) != 0`
if [ x$SKIP_THIS_TEST = x1 ] ;
then
- return;
+ skip_test $tname;
+ return;
fi
fi
- if [ -n "$DO_TEST" ] ; then
+ if [ -n "$DO_TEST" ] ; then
DO_THIS_TEST=`$EXPR \( $tname : "$DO_TEST" \) != 0`
if [ x$DO_THIS_TEST = x0 ] ;
then
- return;
+ skip_test $tname;
+ return;
fi
fi
if [ x${NO_SLAVE}x$SKIP_SLAVE = x1x0 ] ;
then
- USERT=" ...."
- SYST=" ...."
- REALT=" ...."
- timestr="$USERT $SYST $REALT"
- pname=`$ECHO "$tname "|$CUT -c 1-24`
- RES="$pname $timestr"
- skip_inc
- $ECHO "$RES$RES_SPACE [ skipped ]"
+ skip_test $tname;
return
fi
+ # Stop all slave threads, so that we don't have useless reconnection attempts
+ # and error messages in case the slave and master servers restart.
+ stop_slave_threads
+ stop_slave_threads 1
+ stop_slave_threads 2
+
if [ -z "$USE_RUNNING_SERVER" ] ;
then
if [ -f $master_opt_file ] ;
then
- EXTRA_MASTER_OPT=`$CAT $master_opt_file`
+ EXTRA_MASTER_OPT=`$CAT $master_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"`
+ case "$EXTRA_MASTER_OPT" in
+ --timezone=*)
+ TZ=`$ECHO "$EXTRA_MASTER_OPT" | $SED -e "s;--timezone=;;"`
+ export TZ
+ # Note that this must be set to space, not "" for test-reset to work
+ EXTRA_MASTER_OPT=" "
+ ;;
+ esac
stop_master
+ echo "CURRENT_TEST: $tname" >> $MASTER_MYERR
start_master
+ TZ=$MY_TZ; export TZ
else
if [ ! -z "$EXTRA_MASTER_OPT" ] || [ x$MASTER_RUNNING != x1 ] || [ -f $master_init_script ]
then
EXTRA_MASTER_OPT=""
stop_master
+ echo "CURRENT_TEST: $tname" >> $MASTER_MYERR
start_master
- fi
+ else
+ echo "CURRENT_TEST: $tname" >> $MASTER_MYERR
+ fi
fi
+
do_slave_restart=0
-
if [ -f $slave_opt_file ] ;
then
- EXTRA_SLAVE_OPT=`$CAT $slave_opt_file`
+ EXTRA_SLAVE_OPT=`$CAT $slave_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"`
do_slave_restart=1
else
if [ ! -z "$EXTRA_SLAVE_OPT" ] || [ x$SLAVE_RUNNING != x1 ] ;
then
EXTRA_SLAVE_OPT=""
- do_slave_restart=1
- fi
+ do_slave_restart=1
+ fi
fi
if [ -f $slave_master_info_file ] ; then
@@ -774,46 +1254,42 @@ run_testcase ()
if [ ! -z "$SLAVE_MASTER_INFO" ] || [ x$SLAVE_RUNNING != x1 ] ;
then
SLAVE_MASTER_INFO=""
- do_slave_restart=1
- fi
+ do_slave_restart=1
+ fi
fi
if [ x$do_slave_restart = x1 ] ; then
stop_slave
+ echo "CURRENT_TEST: $tname" >> $SLAVE_MYERR
start_slave
+ else
+ echo "CURRENT_TEST: $tname" >> $SLAVE_MYERR
+ fi
+ if [ x$many_slaves = x1 ]; then
+ start_slave 1
+ start_slave 2
fi
fi
cd $MYSQL_TEST_DIR
-
+
if [ -f $tf ] ; then
$RM -f r/$tname.*reject
mysql_test_args="-R r/$tname.result $EXTRA_MYSQL_TEST_OPT"
- if [ -z "$DO_CLIENT_GDB" ] ; then
- mytime=`$TIME -p $MYSQL_TEST $mysql_test_args < $tf 2> $TIMEFILE`
+ if [ -z "$DO_CLIENT_GDB" ] ; then
+ `$MYSQL_TEST $mysql_test_args < $tf 2> $TIMEFILE`;
else
- do_gdb_test "$mysql_test_args" "$tf"
+ do_gdb_test "$mysql_test_args" "$tf"
fi
-
- res=$?
- if [ $res = 0 ]; then
- mytime=`$CAT $TIMEFILE | $TAIL -3 | $TR '\n' ':'`
-
- USERT=`$ECHO $mytime | $CUT -d : -f 2 | $CUT -d ' ' -f 2`
- USERT=`prefix_to_8 $USERT`
- SYST=`$ECHO $mytime | $CUT -d : -f 3 | $CUT -d ' ' -f 2`
- SYST=`prefix_to_8 $SYST`
- REALT=`$ECHO $mytime | $CUT -d : -f 1 | $CUT -d ' ' -f 2`
- REALT=`prefix_to_8 $REALT`
- else
- USERT=" ...."
- SYST=" ...."
- REALT=" ...."
- fi
+ res=$?
- timestr="$USERT $SYST $REALT"
pname=`$ECHO "$tname "|$CUT -c 1-24`
- RES="$pname $timestr"
+ RES="$pname"
+
+ if [ x$many_slaves = x1 ] ; then
+ stop_slave 1
+ stop_slave 2
+ fi
if [ $res = 0 ]; then
total_inc
@@ -838,10 +1314,11 @@ run_testcase ()
if [ -z "$DO_GDB" ] && [ -z "$USE_RUNNING_SERVER" ] && [ -z "$DO_DDD" ]
then
mysql_stop
+ stop_manager
fi
exit 1
fi
-
+
if [ -z "$DO_GDB" ] && [ -z "$USE_RUNNING_SERVER" ] && [ -z "$DO_DDD" ]
then
mysql_restart
@@ -853,26 +1330,54 @@ run_testcase ()
fi
}
-
######################################################################
# Main script starts here
######################################################################
[ "$DO_GCOV" -a ! -x "$GCOV" ] && error "No gcov found"
-[ "$DO_GCOV" ] && gcov_prepare
-[ "$DO_GPROF" ] && gprof_prepare
+[ "$DO_GCOV" ] && gcov_prepare
+[ "$DO_GPROF" ] && gprof_prepare
-# Ensure that no old mysqld test servers are running
if [ -z "$USE_RUNNING_SERVER" ]
then
- $MYSQLADMIN --no-defaults --socket=$MASTER_MYSOCK -u root -O connect_timeout=5 shutdown > /dev/null 2>&1
- $MYSQLADMIN --no-defaults --socket=$SLAVE_MYSOCK -u root -O connect_timeout=5 shutdown > /dev/null 2>&1
+ if [ -z "$FAST_START" ]
+ then
+ # Ensure that no old mysqld test servers are running
+ $MYSQLADMIN --no-defaults --socket=$MASTER_MYSOCK -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
+ $MYSQLADMIN --no-defaults --socket=$SLAVE_MYSOCK -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
+ $MYSQLADMIN --no-defaults --host=$hostname --port=$MASTER_MYPORT -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
+ $MYSQLADMIN --no-defaults --host=$hostname --port=$SLAVE_MYPORT -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
+ $MYSQLADMIN --no-defaults --host=$hostname --port=`expr $SLAVE_MYPORT + 1` -u root -O connect_timeout=5 -O shutdown_timeout=20 shutdown > /dev/null 2>&1
+ sleep_until_file_deleted 0 $MASTER_MYPID
+ sleep_until_file_deleted 0 $SLAVE_MYPID
+ else
+ rm $MASTER_MYPID $SLAVE_MYPID
+ fi
+
+ # Kill any running managers
+ if [ -f "$MANAGER_PID_FILE" ]
+ then
+ kill `cat $MANAGER_PID_FILE`
+ sleep 1
+ if [ -f "$MANAGER_PID_FILE" ]
+ then
+ kill -9 `cat $MANAGER_PID_FILE`
+ sleep 1
+ fi
+ fi
+
+ # Remove files that can cause problems
+ $RM -f $MYSQL_TEST_DIR/var/run/* $MYSQL_TEST_DIR/var/tmp/*
+
+ wait_for_master=$SLEEP_TIME_FOR_FIRST_MASTER
+ wait_for_slave=$SLEEP_TIME_FOR_FIRST_SLAVE
$ECHO "Installing Test Databases"
mysql_install_db
+ start_manager
-#do not automagically start deamons if we are in gdb or running only one test
-#case
+# Do not automagically start daemons if we are in gdb or running only one test
+# case
if [ -z "$DO_GDB" ] && [ -z "$DO_DDD" ]
then
mysql_start
@@ -881,33 +1386,40 @@ then
mysql_loadstd
fi
+if [ "x$START_AND_EXIT" = "x1" ] ; then
+ echo "Servers started, exiting"
+ exit
+fi
$ECHO "Starting Tests"
+#
+# This can probably be deleted
+#
if [ "$DO_BENCH" = 1 ]
then
- BENCHDIR=$BASEDIR/sql-bench/
- savedir=`pwd`
- cd $BENCHDIR
- if [ -z "$1" ]
- then
- ./run-all-tests --socket=$MASTER_MYSOCK --user=root
- else
- if [ -x "./$1" ]
+ BENCHDIR=$BASEDIR/sql-bench/
+ savedir=`pwd`
+ cd $BENCHDIR
+ if [ -z "$1" ]
then
- ./$1 --socket=$MASTER_MYSOCK --user=root
+ ./run-all-tests --socket=$MASTER_MYSOCK --user=root
else
- echo "benchmark $1 not found"
+ if [ -x "./$1" ]
+ then
+ ./$1 --socket=$MASTER_MYSOCK --user=root
+ else
+ echo "benchmark $1 not found"
+ fi
fi
- fi
- cd $savedir
- mysql_stop
- exit
+ cd $savedir
+ mysql_stop
+ stop_manager
+ exit
fi
-
$ECHO
-$ECHO " TEST USER SYSTEM ELAPSED RESULT"
+$ECHO " TEST RESULT"
$ECHO $DASH72
if [ -z "$1" ] ;
@@ -915,25 +1427,23 @@ then
if [ x$RECORD = x1 ]; then
$ECHO "Will not run in record mode without a specific test case."
else
- if [ -z "$USER_TEST" ]
- then
- for tf in $TESTDIR/*.$TESTSUFFIX
- do
- run_testcase $tf
- done
- $RM -f $TIMEFILE # Remove for full test
- else
- $USER_TEST
- fi
- fi
-else
-tname=`$BASENAME $1 .test`
- tf=$TESTDIR/$tname.$TESTSUFFIX
- if [ -f $tf ] ; then
- run_testcase $tf
- else
- $ECHO "Test case $tf does not exist."
+ for tf in `ls -1 $TESTDIR/*.$TESTSUFFIX | $SORT`
+ do
+ run_testcase $tf
+ done
+ $RM -f $TIMEFILE # Remove for full test
fi
+else
+ while [ ! -z "$1" ]; do
+ tname=`$BASENAME $1 .test`
+ tf=$TESTDIR/$tname.$TESTSUFFIX
+ if [ -f $tf ] ; then
+ run_testcase $tf
+ else
+ $ECHO "Test case $tf does not exist."
+ fi
+ shift
+ done
fi
$ECHO $DASH72
@@ -944,6 +1454,7 @@ then
mysql_stop
fi
+stop_manager
report_stats
$ECHO
diff --git a/mysql-test/r/alias.result b/mysql-test/r/alias.result
index 61a65f68007..5ed10b58929 100644
--- a/mysql-test/r/alias.result
+++ b/mysql-test/r/alias.result
@@ -1,2 +1,73 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+cont_nr int(11) NOT NULL auto_increment,
+ver_nr int(11) NOT NULL default '0',
+aufnr int(11) NOT NULL default '0',
+username varchar(50) NOT NULL default '',
+hdl_nr int(11) NOT NULL default '0',
+eintrag date NOT NULL default '0000-00-00',
+st_klasse varchar(40) NOT NULL default '',
+st_wert varchar(40) NOT NULL default '',
+st_zusatz varchar(40) NOT NULL default '',
+st_bemerkung varchar(255) NOT NULL default '',
+kunden_art varchar(40) NOT NULL default '',
+mcbs_knr int(11) default NULL,
+mcbs_aufnr int(11) NOT NULL default '0',
+schufa_status char(1) default '?',
+bemerkung text,
+wirknetz text,
+wf_igz int(11) NOT NULL default '0',
+tarifcode varchar(80) default NULL,
+recycle char(1) default NULL,
+sim varchar(30) default NULL,
+mcbs_tpl varchar(30) default NULL,
+emp_nr int(11) NOT NULL default '0',
+laufzeit int(11) default NULL,
+hdl_name varchar(30) default NULL,
+prov_hdl_nr int(11) NOT NULL default '0',
+auto_wirknetz varchar(50) default NULL,
+auto_billing varchar(50) default NULL,
+touch timestamp(14) NOT NULL,
+kategorie varchar(50) default NULL,
+kundentyp varchar(20) NOT NULL default '',
+sammel_rech_msisdn varchar(30) NOT NULL default '',
+p_nr varchar(9) NOT NULL default '',
+suffix char(3) NOT NULL default '',
+PRIMARY KEY (cont_nr),
+KEY idx_aufnr(aufnr),
+KEY idx_hdl_nr(hdl_nr),
+KEY idx_st_klasse(st_klasse),
+KEY ver_nr(ver_nr),
+KEY eintrag_idx(eintrag),
+KEY emp_nr_idx(emp_nr),
+KEY wf_igz(wf_igz),
+KEY touch(touch),
+KEY hdl_tag(eintrag,hdl_nr),
+KEY prov_hdl_nr(prov_hdl_nr),
+KEY mcbs_aufnr(mcbs_aufnr),
+KEY kundentyp(kundentyp),
+KEY p_nr(p_nr,suffix)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (3359356,405,3359356,'Mustermann Musterfrau',52500,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1485525,2122316,'+','','N',1909160,'MobilComSuper92000D2',NULL,NULL,'MS9ND2',3,24,'MobilCom Shop Koeln',52500,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359357,468,3359357,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1503580,2139699,'+','','P',1909171,'MobilComSuper9D1T10SFreisprech(Akquise)',NULL,NULL,'MS9NS1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359358,407,3359358,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1501358,2137473,'N','','N',1909159,'MobilComSuper92000D2',NULL,NULL,'MS9ND2',325,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359359,468,3359359,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1507831,2143894,'+','','P',1909162,'MobilComSuper9D1T10SFreisprech(Akquise)',NULL,NULL,'MS9NS1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359360,0,0,'Mustermann Musterfrau',29674907,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1900169997,2414578,'+',NULL,'N',1909148,'',NULL,NULL,'RV99066_2',20,NULL,'POS',29674907,NULL,NULL,20010202105916,'Mobilfunk','','','97317481','007');
+INSERT INTO t1 VALUES (3359361,406,3359361,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag storniert','','(7001-84):Storno, Kd. möchte nicht mehr','privat',NULL,0,'+','','P',1909150,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',325,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359362,406,3359362,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1509984,2145874,'+','','P',1909154,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+SELECT ELT(FIELD(kundentyp,'PP','PPA','PG','PGA','FK','FKA','FP','FPA','K','KA','V','VA',''), 'Privat (Private Nutzung)','Privat (Private Nutzung) Sitz im Ausland','Privat (geschaeftliche Nutzung)','Privat (geschaeftliche Nutzung) Sitz im Ausland','Firma (Kapitalgesellschaft)','Firma (Kapitalgesellschaft) Sitz im Ausland','Firma (Personengesellschaft)','Firma (Personengesellschaft) Sitz im Ausland','oeff. rechtl. Koerperschaft','oeff. rechtl. Koerperschaft Sitz im Ausland','Eingetragener Verein','Eingetragener Verein Sitz im Ausland','Typ unbekannt') AS Kundentyp ,kategorie FROM t1 WHERE hdl_nr < 2000000 AND kategorie IN ('Prepaid','Mobilfunk') AND st_klasse = 'Workflow' GROUP BY kundentyp ORDER BY kategorie;
Kundentyp kategorie
Privat (Private Nutzung) Mobilfunk
+drop table t1;
+CREATE TABLE t1 (
+AUFNR varchar(12) NOT NULL default '',
+PLNFL varchar(6) NOT NULL default '',
+VORNR varchar(4) NOT NULL default '',
+xstatus_vor smallint(5) unsigned NOT NULL default '0',
+);
+INSERT INTO t1 VALUES ('40004712','000001','0010',9);
+INSERT INTO t1 VALUES ('40004712','000001','0020',0);
+UPDATE t1 SET t1.xstatus_vor = Greatest(t1.xstatus_vor,1) WHERE t1.aufnr =
+"40004712" AND t1.plnfl = "000001" AND t1.vornr > "0010" ORDER BY t1.vornr
+ASC LIMIT 1;
+drop table t1;
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index 8b104225b9c..b32e100df55 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -1,3 +1,26 @@
+drop table if exists t1,t2;
+create table t1 (
+col1 int not null auto_increment primary key,
+col2 varchar(30) not null,
+col3 varchar (20) not null,
+col4 varchar(4) not null,
+col5 enum('PENDING', 'ACTIVE', 'DISABLED') not null,
+col6 int not null, to_be_deleted int);
+insert into t1 values (2,4,3,5,"PENDING",1,7);
+alter table t1
+add column col4_5 varchar(20) not null after col4,
+add column col7 varchar(30) not null after col5,
+add column col8 datetime not null, drop column to_be_deleted,
+change column col2 fourth varchar(30) not null after col3,
+modify column col6 int not null first;
+select * from t1;
+col6 col1 col3 fourth col4 col4_5 col5 col7 col8
+1 2 3 4 5 PENDING 0000-00-00 00:00:00
+drop table t1;
+create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
+insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12);
+alter table t1 add column new_col int, order by payoutid,bandid;
+select * from t1;
bandID payoutID new_col
6 1 NULL
3 4 NULL
@@ -7,6 +30,8 @@ bandID payoutID new_col
5 10 NULL
7 12 NULL
8 12 NULL
+alter table t1 order by bandid,payoutid;
+select * from t1;
bandID payoutID new_col
1 6 NULL
2 6 NULL
@@ -16,22 +41,315 @@ bandID payoutID new_col
6 1 NULL
7 12 NULL
8 12 NULL
+drop table t1;
+CREATE TABLE t1 (
+GROUP_ID int(10) unsigned DEFAULT '0' NOT NULL,
+LANG_ID smallint(5) unsigned DEFAULT '0' NOT NULL,
+NAME varchar(80) DEFAULT '' NOT NULL,
+PRIMARY KEY (GROUP_ID,LANG_ID),
+KEY NAME (NAME));
+ALTER TABLE t1 CHANGE NAME NAME CHAR(80) not null;
+SHOW FULL COLUMNS FROM t1;
Field Type Null Key Default Extra Privileges
GROUP_ID int(10) unsigned PRI 0 select,insert,update,references
LANG_ID smallint(5) unsigned PRI 0 select,insert,update,references
NAME char(80) MUL select,insert,update,references
+DROP TABLE t1;
+create table t1 (n int);
+insert into t1 values(9),(3),(12),(10);
+alter table t1 order by n;
+select * from t1;
n
3
9
10
12
+drop table t1;
+CREATE TABLE t1 (
+id int(11) unsigned NOT NULL default '0',
+category_id tinyint(4) unsigned NOT NULL default '0',
+type_id tinyint(4) unsigned NOT NULL default '0',
+body text NOT NULL,
+user_id int(11) unsigned NOT NULL default '0',
+status enum('new','old') NOT NULL default 'new',
+PRIMARY KEY (id)
+) TYPE=MyISAM;
+ALTER TABLE t1 ORDER BY t1.id, t1.status, t1.type_id, t1.user_id, t1.body;
+DROP TABLE t1;
+CREATE TABLE t1 (AnamneseId int(10) unsigned NOT NULL auto_increment,B BLOB,PRIMARY KEY (AnamneseId)) type=myisam;
+insert into t1 values (null,"hello");
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1 ADD Column new_col int not null;
+UNLOCK TABLES;
+OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
+DROP TABLE t1;
+create table t1 (n1 int not null, n2 int, n3 int, n4 float,
+unique(n1),
+key (n1, n2, n3, n4),
+key (n2, n3, n4, n1),
+key (n3, n4, n1, n2),
+key (n4, n1, n2, n3) );
+alter table t1 disable keys;
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 n1 1 n1 A 0 NULL NULL BTREE
+t1 1 n1_2 1 n1 A NULL NULL NULL BTREE disabled
+t1 1 n1_2 2 n2 A NULL NULL NULL YES BTREE disabled
+t1 1 n1_2 3 n3 A NULL NULL NULL YES BTREE disabled
+t1 1 n1_2 4 n4 A NULL NULL NULL YES BTREE disabled
+t1 1 n2 1 n2 A NULL NULL NULL YES BTREE disabled
+t1 1 n2 2 n3 A NULL NULL NULL YES BTREE disabled
+t1 1 n2 3 n4 A NULL NULL NULL YES BTREE disabled
+t1 1 n2 4 n1 A NULL NULL NULL BTREE disabled
+t1 1 n3 1 n3 A NULL NULL NULL YES BTREE disabled
+t1 1 n3 2 n4 A NULL NULL NULL YES BTREE disabled
+t1 1 n3 3 n1 A NULL NULL NULL BTREE disabled
+t1 1 n3 4 n2 A NULL NULL NULL YES BTREE disabled
+t1 1 n4 1 n4 A NULL NULL NULL YES BTREE disabled
+t1 1 n4 2 n1 A NULL NULL NULL BTREE disabled
+t1 1 n4 3 n2 A NULL NULL NULL YES BTREE disabled
+t1 1 n4 4 n3 A NULL NULL NULL YES BTREE disabled
+insert into t1 values(10,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(9,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(8,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(7,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(6,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(5,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(4,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(3,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(2,RAND()*1000,RAND()*1000,RAND());
+insert into t1 values(1,RAND()*1000,RAND()*1000,RAND());
+alter table t1 enable keys;
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 n1 1 n1 A 10 NULL NULL BTREE
+t1 1 n1_2 1 n1 A 10 NULL NULL BTREE
+t1 1 n1_2 2 n2 A 10 NULL NULL YES BTREE
+t1 1 n1_2 3 n3 A 10 NULL NULL YES BTREE
+t1 1 n1_2 4 n4 A 10 NULL NULL YES BTREE
+t1 1 n2 1 n2 A 10 NULL NULL YES BTREE
+t1 1 n2 2 n3 A 10 NULL NULL YES BTREE
+t1 1 n2 3 n4 A 10 NULL NULL YES BTREE
+t1 1 n2 4 n1 A 10 NULL NULL BTREE
+t1 1 n3 1 n3 A 10 NULL NULL YES BTREE
+t1 1 n3 2 n4 A 10 NULL NULL YES BTREE
+t1 1 n3 3 n1 A 10 NULL NULL BTREE
+t1 1 n3 4 n2 A 10 NULL NULL YES BTREE
+t1 1 n4 1 n4 A 10 NULL NULL YES BTREE
+t1 1 n4 2 n1 A 10 NULL NULL BTREE
+t1 1 n4 3 n2 A 10 NULL NULL YES BTREE
+t1 1 n4 4 n3 A 10 NULL NULL YES BTREE
+drop table t1;
+create table t1 (i int unsigned not null auto_increment primary key);
+insert into t1 values (null),(null),(null),(null);
+alter table t1 drop i,add i int unsigned not null auto_increment, drop primary key, add primary key (i);
+select * from t1;
i
1
2
3
4
+drop table t1;
+create table t1 (i int unsigned not null auto_increment primary key);
+alter table t1 rename t2;
+alter table t2 rename t1, add c char(10) comment "no comment";
+show columns from t1;
+Field Type Null Key Default Extra
+i int(10) unsigned PRI NULL auto_increment
+c char(10) YES NULL
+drop table t1;
+create table t1 (a int, b int);
+insert into t1 values(1,100), (2,100), (3, 100);
+insert into t1 values(1,99), (2,99), (3, 99);
+insert into t1 values(1,98), (2,98), (3, 98);
+insert into t1 values(1,97), (2,97), (3, 97);
+insert into t1 values(1,96), (2,96), (3, 96);
+insert into t1 values(1,95), (2,95), (3, 95);
+insert into t1 values(1,94), (2,94), (3, 94);
+insert into t1 values(1,93), (2,93), (3, 93);
+insert into t1 values(1,92), (2,92), (3, 92);
+insert into t1 values(1,91), (2,91), (3, 91);
+insert into t1 values(1,90), (2,90), (3, 90);
+insert into t1 values(1,89), (2,89), (3, 89);
+insert into t1 values(1,88), (2,88), (3, 88);
+insert into t1 values(1,87), (2,87), (3, 87);
+insert into t1 values(1,86), (2,86), (3, 86);
+insert into t1 values(1,85), (2,85), (3, 85);
+insert into t1 values(1,84), (2,84), (3, 84);
+insert into t1 values(1,83), (2,83), (3, 83);
+insert into t1 values(1,82), (2,82), (3, 82);
+insert into t1 values(1,81), (2,81), (3, 81);
+insert into t1 values(1,80), (2,80), (3, 80);
+insert into t1 values(1,79), (2,79), (3, 79);
+insert into t1 values(1,78), (2,78), (3, 78);
+insert into t1 values(1,77), (2,77), (3, 77);
+insert into t1 values(1,76), (2,76), (3, 76);
+insert into t1 values(1,75), (2,75), (3, 75);
+insert into t1 values(1,74), (2,74), (3, 74);
+insert into t1 values(1,73), (2,73), (3, 73);
+insert into t1 values(1,72), (2,72), (3, 72);
+insert into t1 values(1,71), (2,71), (3, 71);
+insert into t1 values(1,70), (2,70), (3, 70);
+insert into t1 values(1,69), (2,69), (3, 69);
+insert into t1 values(1,68), (2,68), (3, 68);
+insert into t1 values(1,67), (2,67), (3, 67);
+insert into t1 values(1,66), (2,66), (3, 66);
+insert into t1 values(1,65), (2,65), (3, 65);
+insert into t1 values(1,64), (2,64), (3, 64);
+insert into t1 values(1,63), (2,63), (3, 63);
+insert into t1 values(1,62), (2,62), (3, 62);
+insert into t1 values(1,61), (2,61), (3, 61);
+insert into t1 values(1,60), (2,60), (3, 60);
+insert into t1 values(1,59), (2,59), (3, 59);
+insert into t1 values(1,58), (2,58), (3, 58);
+insert into t1 values(1,57), (2,57), (3, 57);
+insert into t1 values(1,56), (2,56), (3, 56);
+insert into t1 values(1,55), (2,55), (3, 55);
+insert into t1 values(1,54), (2,54), (3, 54);
+insert into t1 values(1,53), (2,53), (3, 53);
+insert into t1 values(1,52), (2,52), (3, 52);
+insert into t1 values(1,51), (2,51), (3, 51);
+insert into t1 values(1,50), (2,50), (3, 50);
+insert into t1 values(1,49), (2,49), (3, 49);
+insert into t1 values(1,48), (2,48), (3, 48);
+insert into t1 values(1,47), (2,47), (3, 47);
+insert into t1 values(1,46), (2,46), (3, 46);
+insert into t1 values(1,45), (2,45), (3, 45);
+insert into t1 values(1,44), (2,44), (3, 44);
+insert into t1 values(1,43), (2,43), (3, 43);
+insert into t1 values(1,42), (2,42), (3, 42);
+insert into t1 values(1,41), (2,41), (3, 41);
+insert into t1 values(1,40), (2,40), (3, 40);
+insert into t1 values(1,39), (2,39), (3, 39);
+insert into t1 values(1,38), (2,38), (3, 38);
+insert into t1 values(1,37), (2,37), (3, 37);
+insert into t1 values(1,36), (2,36), (3, 36);
+insert into t1 values(1,35), (2,35), (3, 35);
+insert into t1 values(1,34), (2,34), (3, 34);
+insert into t1 values(1,33), (2,33), (3, 33);
+insert into t1 values(1,32), (2,32), (3, 32);
+insert into t1 values(1,31), (2,31), (3, 31);
+insert into t1 values(1,30), (2,30), (3, 30);
+insert into t1 values(1,29), (2,29), (3, 29);
+insert into t1 values(1,28), (2,28), (3, 28);
+insert into t1 values(1,27), (2,27), (3, 27);
+insert into t1 values(1,26), (2,26), (3, 26);
+insert into t1 values(1,25), (2,25), (3, 25);
+insert into t1 values(1,24), (2,24), (3, 24);
+insert into t1 values(1,23), (2,23), (3, 23);
+insert into t1 values(1,22), (2,22), (3, 22);
+insert into t1 values(1,21), (2,21), (3, 21);
+insert into t1 values(1,20), (2,20), (3, 20);
+insert into t1 values(1,19), (2,19), (3, 19);
+insert into t1 values(1,18), (2,18), (3, 18);
+insert into t1 values(1,17), (2,17), (3, 17);
+insert into t1 values(1,16), (2,16), (3, 16);
+insert into t1 values(1,15), (2,15), (3, 15);
+insert into t1 values(1,14), (2,14), (3, 14);
+insert into t1 values(1,13), (2,13), (3, 13);
+insert into t1 values(1,12), (2,12), (3, 12);
+insert into t1 values(1,11), (2,11), (3, 11);
+insert into t1 values(1,10), (2,10), (3, 10);
+insert into t1 values(1,9), (2,9), (3, 9);
+insert into t1 values(1,8), (2,8), (3, 8);
+insert into t1 values(1,7), (2,7), (3, 7);
+insert into t1 values(1,6), (2,6), (3, 6);
+insert into t1 values(1,5), (2,5), (3, 5);
+insert into t1 values(1,4), (2,4), (3, 4);
+insert into t1 values(1,3), (2,3), (3, 3);
+insert into t1 values(1,2), (2,2), (3, 2);
+insert into t1 values(1,1), (2,1), (3, 1);
+alter table t1 add unique (a,b), add key (b);
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 a 1 a A NULL NULL NULL YES BTREE
+t1 0 a 2 b A NULL NULL NULL YES BTREE
+t1 1 b 1 b A 100 NULL NULL YES BTREE
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 a 1 a A 3 NULL NULL YES BTREE
+t1 0 a 2 b A 300 NULL NULL YES BTREE
+t1 1 b 1 b A 100 NULL NULL YES BTREE
+drop table t1;
+CREATE TABLE t1 (i int(10), index(i) );
+ALTER TABLE t1 DISABLE KEYS;
+INSERT DELAYED INTO t1 VALUES(1),(2),(3);
+ALTER TABLE t1 ENABLE KEYS;
+drop table t1;
+CREATE TABLE t1 (
+Host varchar(16) binary NOT NULL default '',
+User varchar(16) binary NOT NULL default '',
+PRIMARY KEY (Host,User)
+) TYPE=MyISAM;
+ALTER TABLE t1 DISABLE KEYS;
+LOCK TABLES t1 WRITE;
+INSERT INTO t1 VALUES ('localhost','root'),('localhost',''),('games','monty');
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 User A 3 NULL NULL BTREE
+ALTER TABLE t1 ENABLE KEYS;
+UNLOCK TABLES;
+CHECK TABLES t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
+CREATE TABLE t1 (
+Host varchar(16) binary NOT NULL default '',
+User varchar(16) binary NOT NULL default '',
+PRIMARY KEY (Host,User),
+KEY (Host)
+) TYPE=MyISAM;
+ALTER TABLE t1 DISABLE KEYS;
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 User A 0 NULL NULL BTREE
+t1 1 Host 1 Host A NULL NULL NULL BTREE disabled
+LOCK TABLES t1 WRITE;
+INSERT INTO t1 VALUES ('localhost','root'),('localhost','');
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 User A 2 NULL NULL BTREE
+t1 1 Host 1 Host A NULL NULL NULL BTREE disabled
+ALTER TABLE t1 ENABLE KEYS;
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 User A 2 NULL NULL BTREE
+t1 1 Host 1 Host A 1 NULL NULL BTREE
+UNLOCK TABLES;
+CHECK TABLES t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1 RENAME t2;
+UNLOCK TABLES;
+select * from t2;
+Host User
+localhost
+localhost root
+DROP TABLE t2;
+CREATE TABLE t1 (
+Host varchar(16) binary NOT NULL default '',
+User varchar(16) binary NOT NULL default '',
+PRIMARY KEY (Host,User),
+KEY (Host)
+) TYPE=MyISAM;
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1 DISABLE KEYS;
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 User A 0 NULL NULL BTREE
+t1 1 Host 1 Host A NULL NULL NULL BTREE disabled
+DROP TABLE t1;
name
current
name
diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result
index e69a7e99992..5e859bb0b7a 100644
--- a/mysql-test/r/analyse.result
+++ b/mysql-test/r/analyse.result
@@ -1,18 +1,26 @@
+drop table if exists t1,t2;
+create table t1 (i int, j int, empty_string char(10), bool char(1), d date);
+insert into t1 values (1,2,"","Y","2002-03-03"), (3,4,"","N","2002-03-04"), (5,6,"","Y","2002-03-04"), (7,8,"","N","2002-03-05");
+select * from t1 procedure analyse();
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
t1.i 1 7 1 1 0 0 4.0000 2.2361 ENUM('1','3','5','7') NOT NULL
t1.j 2 8 1 1 0 0 5.0000 2.2361 ENUM('2','4','6','8') NOT NULL
-t1.empty_string 0 0 4 0 0.0000 NULL ENUM('') NOT NULL
+t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL
t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL
-t1.d 2002-03-04 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
+t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
+select * from t1 procedure analyse(2);
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
t1.i 1 7 1 1 0 0 4.0000 2.2361 TINYINT(1) UNSIGNED NOT NULL
t1.j 2 8 1 1 0 0 5.0000 2.2361 TINYINT(1) UNSIGNED NOT NULL
t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL
t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL
-t1.d 2002-03-04 10 10 0 0 10.0000 NULL DATE NOT NULL
+t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
+create table t2 select * from t1 procedure analyse();
+select * from t2;
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
t1.i 1 7 1 1 0 0 4.0000 2.2361 ENUM('1','3','5','7') NOT NULL
t1.j 2 8 1 1 0 0 5.0000 2.2361 ENUM('2','4','6','8') NOT NULL
-t1.empty_string 0 0 4 0 0.0000 NULL ENUM('') NOT NULL
+t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL
t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL
-t1.d 2002-03-04 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
+t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
+drop table t1,t2;
diff --git a/mysql-test/r/ansi.result b/mysql-test/r/ansi.result
new file mode 100644
index 00000000000..f9f96310b73
--- /dev/null
+++ b/mysql-test/r/ansi.result
@@ -0,0 +1,10 @@
+drop table if exists t1;
+SELECT 'A' || 'B';
+'A' || 'B'
+AB
+CREATE TABLE t1 (id INT, id2 int);
+SELECT id,NULL,1,1.1,'a' FROM t1 GROUP BY id;
+id NULL 1 1.1 a
+SELECT id FROM t1 GROUP BY id2;
+'t1.id' isn't in GROUP BY
+drop table t1;
diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result
index bf6265e5b64..2d6b058d9c5 100644
--- a/mysql-test/r/auto_increment.result
+++ b/mysql-test/r/auto_increment.result
@@ -1,32 +1,52 @@
+drop table if exists t1;
+create table t1 (a int not null auto_increment,b int, primary key (a)) type=myisam auto_increment=3;
+insert into t1 values (1,1),(NULL,3),(NULL,4);
+delete from t1 where a=4;
+insert into t1 values (NULL,5),(NULL,6);
+select * from t1;
a b
1 1
3 3
5 5
6 6
+delete from t1 where a=6;
+replace t1 values (3,1);
+ALTER TABLE t1 add c int;
+replace t1 values (3,3,3);
+insert into t1 values (NULL,7,7);
+update t1 set a=8,b=b+1,c=c+1 where a=7;
+insert into t1 values (NULL,9,9);
+select * from t1;
a b c
1 1 NULL
3 3 3
5 5 NULL
8 8 8
9 9 9
-a b
-1 1
-5 5
-3 3
-4 4
-6 6
-a b c
-1 1 NULL
-5 5 NULL
-3 3 NULL
-4 4 NULL
-6 6 6
+drop table t1;
+create table t1 (
+skey tinyint unsigned NOT NULL auto_increment PRIMARY KEY,
+sval char(20)
+);
+insert into t1 values (NULL, "hello");
+insert into t1 values (NULL, "hey");
+select * from t1;
skey sval
1 hello
2 hey
+select _rowid,t1._rowid,skey,sval from t1;
_rowid _rowid skey sval
1 1 1 hello
2 2 2 hey
+drop table t1;
+create table t1 (a char(10) not null, b int not null auto_increment, primary key(a,b));
+insert into t1 values ("a",1),("b",2),("a",2),("c",1);
+insert into t1 values ("a",NULL),("b",NULL),("c",NULL),("e",NULL);
+insert into t1 (a) values ("a"),("b"),("c"),("d");
+insert into t1 (a) values ('k'),('d');
+insert into t1 (a) values ("a");
+insert into t1 values ("d",last_insert_id());
+select * from t1;
a b
a 1
a 2
@@ -44,9 +64,17 @@ d 2
d 5
e 1
k 1
+drop table t1;
+create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ordid), index(ord,ordid));
+insert into t1 (ordid,ord) values (NULL,'sdj'),(NULL,'sdj');
+select * from t1;
ordid ord
1 sdj
2 sdj
+drop table t1;
+create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid));
+insert into t1 values (NULL,'sdj'),(NULL,'sdj'),(NULL,"abc"),(NULL,'abc'),(NULL,'zzz'),(NULL,'sdj'),(NULL,'abc');
+select * from t1;
ordid ord
1 abc
2 abc
@@ -55,8 +83,51 @@ ordid ord
2 sdj
3 sdj
1 zzz
+drop table t1;
+create table t1 (sid char(5), id int(2) NOT NULL auto_increment, key(sid, id));
+create table t2 (sid char(20), id int(2));
+insert into t2 values ('skr',NULL),('skr',NULL),('test',NULL);
+insert into t1 select * from t2;
+select * from t1;
+sid id
+skr 1
+skr 2
+test 1
+drop table t1,t2;
+create table t1 (a int not null primary key auto_increment);
+insert into t1 values (0);
+update t1 set a=0;
+select * from t1;
a
0
+check table t1;
Table Op Msg_type Msg_text
test.t1 check warning Found row where the auto_increment column has the value 0
test.t1 check status OK
+drop table t1;
+create table t1 (a int not null auto_increment primary key);
+insert into t1 values (NULL);
+insert into t1 values (-1);
+select last_insert_id();
+last_insert_id()
+1
+insert into t1 values (NULL);
+select * from t1;
+a
+-1
+1
+2
+drop table t1;
+create table t1 (a int not null auto_increment primary key) /*!40102 type=heap */;
+insert into t1 values (NULL);
+insert into t1 values (-1);
+select last_insert_id();
+last_insert_id()
+1
+insert into t1 values (NULL);
+select * from t1;
+a
+-1
+1
+2
+drop table t1;
diff --git a/mysql-test/r/backup.result b/mysql-test/r/backup.result
index 0d34cd7eae8..0e0a87172f2 100644
--- a/mysql-test/r/backup.result
+++ b/mysql-test/r/backup.result
@@ -1,45 +1,77 @@
+set SQL_LOG_BIN=0;
+create table t4(n int);
+backup table t4 to '../bogus';
Table Op Msg_type Msg_text
test.t4 backup error Failed copying .frm file (errno: X)
test.t4 backup status Operation failed
+backup table t4 to '../tmp';
Table Op Msg_type Msg_text
test.t4 backup status OK
+backup table t4 to '../tmp';
Table Op Msg_type Msg_text
test.t4 backup error Failed copying .frm file (errno: X)
test.t4 backup status Operation failed
+drop table t4;
+restore table t4 from '../tmp';
Table Op Msg_type Msg_text
test.t4 restore status OK
+select count(*) from t4;
count(*)
0
+create table t1(n int);
+insert into t1 values (23),(45),(67);
+backup table t1 to '../tmp';
Table Op Msg_type Msg_text
test.t1 backup status OK
+drop table t1;
+restore table t1 from '../bogus';
Table Op Msg_type Msg_text
t1 restore error Failed copying .frm file
+restore table t1 from '../tmp';
Table Op Msg_type Msg_text
test.t1 restore status OK
+select n from t1;
n
23
45
67
+create table t2(m int not null primary key);
+create table t3(k int not null primary key);
+insert into t2 values (123),(145),(167);
+insert into t3 values (223),(245),(267);
+backup table t2,t3 to '../tmp';
Table Op Msg_type Msg_text
test.t2 backup status OK
test.t3 backup status OK
+drop table t1,t2,t3;
+restore table t1,t2,t3 from '../tmp';
Table Op Msg_type Msg_text
test.t1 restore status OK
test.t2 restore status OK
test.t3 restore status OK
+select n from t1;
n
23
45
67
+select m from t2;
m
123
145
167
+select k from t3;
k
223
245
267
+drop table t1,t2,t3,t4;
+restore table t1 from '../tmp';
Table Op Msg_type Msg_text
test.t1 restore status OK
+rename table t1 to t5;
+lock tables t5 write;
+backup table t5 to '../tmp';
+unlock tables;
Table Op Msg_type Msg_text
test.t5 backup status OK
+drop table t5;
diff --git a/mysql-test/r/bdb-alter-table-1.result b/mysql-test/r/bdb-alter-table-1.result
index 3742f45eb7a..095d89355ad 100644
--- a/mysql-test/r/bdb-alter-table-1.result
+++ b/mysql-test/r/bdb-alter-table-1.result
@@ -1,4 +1,11 @@
+drop table if exists t1;
+create table t1(objid BIGINT not null, tablename varchar(64), oid BIGINT not null, test BIGINT, PRIMARY KEY (objid), UNIQUE(tablename)) type=BDB;
+insert into t1 values(1, 't1',4,9);
+insert into t1 values(2, 'metatable',1,9);
+insert into t1 values(3, 'metaindex',1,9 );
+select * from t1;
objid tablename oid test
1 t1 4 9
2 metatable 1 9
3 metaindex 1 9
+alter table t1 drop column test;
diff --git a/mysql-test/r/bdb-alter-table-2.result b/mysql-test/r/bdb-alter-table-2.result
index 19c6d5e1ff9..c23b5ba0031 100644
--- a/mysql-test/r/bdb-alter-table-2.result
+++ b/mysql-test/r/bdb-alter-table-2.result
@@ -1,4 +1,6 @@
+select * from t1;
objid tablename oid
1 t1 4
2 metatable 1
3 metaindex 1
+drop table t1;
diff --git a/mysql-test/r/bdb-crash.result b/mysql-test/r/bdb-crash.result
index 8fa8378640b..5079368ea21 100644
--- a/mysql-test/r/bdb-crash.result
+++ b/mysql-test/r/bdb-crash.result
@@ -1,3 +1,32 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+ChargeID int(10) unsigned NOT NULL auto_increment,
+ServiceID int(10) unsigned DEFAULT '0' NOT NULL,
+ChargeDate date DEFAULT '0000-00-00' NOT NULL,
+ChargeAmount decimal(20,2) DEFAULT '0.00' NOT NULL,
+FedTaxes decimal(20,2) DEFAULT '0.00' NOT NULL,
+ProvTaxes decimal(20,2) DEFAULT '0.00' NOT NULL,
+ChargeStatus enum('New','Auth','Unauth','Sale','Denied','Refund')
+DEFAULT 'New' NOT NULL,
+ChargeAuthorizationMessage text,
+ChargeComment text,
+ChargeTimeStamp varchar(20),
+PRIMARY KEY (ChargeID),
+KEY ServiceID (ServiceID),
+KEY ChargeDate (ChargeDate)
+) type=BDB;
+BEGIN;
+INSERT INTO t1
+VALUES(NULL,1,'2001-03-01',1,1,1,'New',NULL,NULL,'now');
+COMMIT;
+BEGIN;
+UPDATE t1 SET ChargeAuthorizationMessage = 'blablabla' WHERE
+ChargeID = 1;
+COMMIT;
+INSERT INTO t1
+VALUES(NULL,1,'2001-03-01',1,1,1,'New',NULL,NULL,'now');
+select * from t1;
ChargeID ServiceID ChargeDate ChargeAmount FedTaxes ProvTaxes ChargeStatus ChargeAuthorizationMessage ChargeComment ChargeTimeStamp
1 1 2001-03-01 1.00 1.00 1.00 New blablabla NULL now
2 1 2001-03-01 1.00 1.00 1.00 New NULL NULL now
+drop table t1;
diff --git a/mysql-test/r/bdb-deadlock.result b/mysql-test/r/bdb-deadlock.result
index 89077d16980..55b3d3ea2a5 100644
--- a/mysql-test/r/bdb-deadlock.result
+++ b/mysql-test/r/bdb-deadlock.result
@@ -1,10 +1,31 @@
+drop table if exists t1,t2;
+create table t1 (id integer, x integer) type=BDB;
+create table t2 (id integer, x integer) type=BDB;
+insert into t1 values(0, 0);
+insert into t2 values(0, 0);
+set autocommit=0;
+update t1 set x = 1 where id = 0;
+set autocommit=0;
+update t2 set x = 1 where id = 0;
+select x from t1 where id = 0;
+select x from t2 where id = 0;
+Deadlock found when trying to get lock; Try restarting transaction
+commit;
x
1
+commit;
+select * from t1;
id x
0 1
+select * from t2;
id x
0 1
+commit;
+select * from t1;
id x
0 1
+select * from t2;
id x
0 1
+commit;
+drop table t1,t2;
diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result
index 4d26304db4c..2ccb5148d58 100644
--- a/mysql-test/r/bdb.result
+++ b/mysql-test/r/bdb.result
@@ -1,3 +1,7 @@
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
+create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=bdb;
+insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
+select id, code, name from t1 order by id;
id code name
1 1 Tim
2 1 Monty
@@ -6,6 +10,8 @@ id code name
5 3 Sasha
6 3 Jeremy
7 4 Matt
+update ignore t1 set id = 8, name = 'Sinisa' where id < 3;
+select id, code, name from t1 order by id;
id code name
2 1 Monty
3 2 David
@@ -14,6 +20,8 @@ id code name
6 3 Jeremy
7 4 Matt
8 1 Sinisa
+update ignore t1 set id = id + 10, name = 'Ralph' where id < 4;
+select id, code, name from t1 order by id;
id code name
3 2 David
4 2 Erik
@@ -22,10 +30,26 @@ id code name
7 4 Matt
8 1 Sinisa
12 1 Ralph
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) type=bdb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
id parent_id level
8 102 2
9 102 2
15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+Duplicate entry '1024' for key 1
+select * from t1;
id parent_id level
1001 100 0
1002 101 1
@@ -66,6 +90,8 @@ id parent_id level
1193 105 2
1202 107 2
1203 107 2
+update ignore t1 set id=id+1;
+select * from t1;
id parent_id level
1001 100 0
1002 101 1
@@ -106,16 +132,22 @@ id parent_id level
1194 105 2
1202 107 2
1204 107 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102 order by parent_id,id;
id parent_id level
1008 102 2
-1015 102 2
1010 102 2
+1015 102 2
+explain select level from t1 where level=1;
table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 1 where used; Using index
+t1 ref level level 1 const 1 Using where; Using index
+explain select level,id from t1 where level=1;
table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 1 where used; Using index
+t1 ref level level 1 const 1 Using where; Using index
+explain select level,id,parent_id from t1 where level=1;
table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 1 where used
+t1 ref level level 1 const 1 Using where
+select level,id from t1 where level=1;
level id
1 1002
1 1003
@@ -123,6 +155,7 @@ level id
1 1005
1 1006
1 1007
+select level,id,parent_id from t1 where level=1;
level id parent_id
1 1002 101
1 1003 101
@@ -130,31 +163,77 @@ level id parent_id
1 1005 101
1 1006 101
1 1007 101
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 id A 39 NULL NULL
-t1 1 parent_id 1 parent_id A 9 NULL NULL
-t1 1 level 1 level A 3 NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 id A 39 NULL NULL BTREE
+t1 1 parent_id 1 parent_id A 9 NULL NULL BTREE
+t1 1 level 1 level A 3 NULL NULL BTREE
+drop table t1;
+CREATE TABLE t1 (
+gesuchnr int(11) DEFAULT '0' NOT NULL,
+benutzer_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (gesuchnr,benutzer_id)
+) type=BDB;
+replace into t1 (gesuchnr,benutzer_id) values (2,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+select * from t1;
gesuchnr benutzer_id
1 1
2 1
+drop table t1;
+create table t1 (id int not null primary key, x int not null, key (x)) type=bdb;
+insert into t1 (id, x) values (1, 1);
+replace into t1 (id, x) values (1, 2);
+select * from t1;
id x
1 2
+drop table t1;
+create table t1 (a int) type=bdb;
+insert into t1 values (1), (2);
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
+delete from t1 where a = 1;
+select * from t1;
a
2
+check table t1;
Table Op Msg_type Msg_text
-test.t1 check error The handler for the table doesn't support check/repair
+test.t1 check error The handler for the table doesn't support check
+drop table t1;
+create table t1 (a int,b varchar(20)) type=bdb;
+insert into t1 values (1,""), (2,"testing");
+delete from t1 where a = 1;
+select * from t1;
a b
2 testing
+create index skr on t1 (a);
+insert into t1 values (3,""), (4,"testing");
+analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 1 skr 1 a A 3 NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 skr 1 a A 3 NULL NULL YES BTREE
+drop table t1;
+create table t1 (a int,b varchar(20),key(a)) type=bdb;
+insert into t1 values (1,""), (2,"testing");
+select * from t1 where a = 1;
a b
1
+drop table t1;
+create table t1 (a char(10) not null, b int not null auto_increment, primary key(a,b)) type=BDB;
+insert into t1 values ("a",1),("b",2),("a",2),("c",1);
+insert into t1 values ("a",NULL),("b",NULL),("c",NULL),("e",NULL);
+insert into t1 (a) values ("a"),("b"),("c"),("d");
+insert into t1 (a) values ('k'),('d');
+insert into t1 (a) values ("a");
+insert into t1 values ("d",last_insert_id());
+select * from t1;
a b
a 1
a 2
@@ -172,121 +251,290 @@ d 2
d 5
e 1
k 1
+flush tables;
+select count(*) from t1;
count(*)
16
+drop table t1;
+create table t1 (n int not null primary key) type=bdb;
+set autocommit=0;
+insert into t1 values (4);
+rollback;
+select n, "after rollback" from t1;
n after rollback
+insert into t1 values (4);
+commit;
+select n, "after commit" from t1;
n after commit
4 after commit
+commit;
+insert into t1 values (5);
+insert into t1 values (4);
+Duplicate entry '4' for key 1
+commit;
+select n, "after commit" from t1;
n after commit
4 after commit
5 after commit
+set autocommit=1;
+insert into t1 values (6);
+insert into t1 values (4);
+Duplicate entry '4' for key 1
+select n from t1;
n
4
5
6
+rollback;
+drop table t1;
+create table t1 ( id int NOT NULL PRIMARY KEY, nom varchar(64)) type=BDB;
+begin;
+insert into t1 values(1,'hamdouni');
+select id as afterbegin_id,nom as afterbegin_nom from t1;
afterbegin_id afterbegin_nom
1 hamdouni
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
afterrollback_id afterrollback_nom
+set autocommit=0;
+insert into t1 values(2,'mysql');
+select id as afterautocommit0_id,nom as afterautocommit0_nom from t1;
afterautocommit0_id afterautocommit0_nom
2 mysql
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
afterrollback_id afterrollback_nom
+set autocommit=1;
+drop table t1;
+CREATE TABLE t1 (id char(8) not null primary key, val int not null) type=bdb;
+insert into t1 values ('pippo', 12);
+insert into t1 values ('pippo', 12);
+Duplicate entry 'pippo' for key 1
+delete from t1;
+delete from t1 where id = 'pippo';
+select * from t1;
id val
+insert into t1 values ('pippo', 12);
+set autocommit=0;
+delete from t1;
+rollback;
+select * from t1;
id val
pippo 12
+delete from t1;
+commit;
+select * from t1;
id val
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR(64)) TYPE=BDB;
+INSERT INTO t1 VALUES (1, 'Jochen');
+select * from t1;
ID NAME
1 Jochen
+drop table t1;
+CREATE TABLE t1 ( _userid VARCHAR(60) NOT NULL PRIMARY KEY) TYPE=BDB;
+set autocommit=0;
+INSERT INTO t1 SET _userid='marc@anyware.co.uk';
+COMMIT;
+SELECT * FROM t1;
_userid
marc@anyware.co.uk
+SELECT _userid FROM t1 WHERE _userid='marc@anyware.co.uk';
_userid
marc@anyware.co.uk
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (
+user_id int(10) DEFAULT '0' NOT NULL,
+name varchar(100),
+phone varchar(100),
+ref_email varchar(100) DEFAULT '' NOT NULL,
+detail varchar(200),
+PRIMARY KEY (user_id,ref_email)
+)type=bdb;
+INSERT INTO t1 VALUES (10292,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10292,'shirish','2333604','shirish@yahoo.com','ddsds'),(10292,'sonali','323232','sonali@bolly.com','filmstar');
+select * from t1 where user_id=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
+INSERT INTO t1 VALUES (10291,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10293,'shirish','2333604','shirish@yahoo.com','ddsds');
+select * from t1 where user_id=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
+select * from t1 where user_id>=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id>10292;
user_id name phone ref_email detail
10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id<10292;
user_id name phone ref_email detail
10291 sanjeev 29153373 sansh777@hotmail.com xxx
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A NULL NULL NULL
-t1 0 PRIMARY 2 b A 0 NULL NULL
-t1 0 b 1 b A 0 NULL NULL
-t1 0 c 1 c A 0 NULL NULL
-t1 1 a 1 a A NULL NULL NULL
-t1 1 a_2 1 a A NULL NULL NULL
+drop table t1;
+CREATE TABLE t1 (a int not null, b int not null,c int not null,
+key(a),primary key(a,b), unique(c),key(a),unique(b));
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 b A 0 NULL NULL BTREE
+t1 0 c 1 c A 0 NULL NULL BTREE
+t1 0 b 1 b A 0 NULL NULL BTREE
+t1 1 a 1 a A NULL NULL NULL BTREE
+t1 1 a_2 1 a A NULL NULL NULL BTREE
+drop table t1;
+create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
+alter table t1 type=BDB;
+insert into t1 values ('1','1'),('5','2'),('2','3'),('3','4'),('4','4');
+select * from t1;
col1 col2
1 1
2 3
3 4
4 4
5 2
+update t1 set col2='7' where col1='4';
+select * from t1;
col1 col2
1 1
2 3
3 4
4 7
5 2
+alter table t1 add co3 int not null;
+select * from t1;
col1 col2 co3
1 1 0
2 3 0
3 4 0
4 7 0
5 2 0
+update t1 set col2='9' where col1='2';
+select * from t1;
col1 col2 co3
1 1 0
2 9 0
3 4 0
4 7 0
5 2 0
+drop table t1;
+create table t1 (a int not null , b int, primary key (a)) type = BDB;
+create table t2 (a int not null , b int, primary key (a)) type = myisam;
+insert into t1 VALUES (1,3) , (2,3), (3,3);
+select * from t1;
a b
1 3
2 3
3 3
+insert into t2 select * from t1;
+select * from t2;
a b
1 3
2 3
3 3
+delete from t1 where b = 3;
+select * from t1;
a b
+insert into t1 select * from t2;
+select * from t1;
a b
1 3
2 3
3 3
+select * from t2;
a b
1 3
2 3
3 3
+drop table t1,t2;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+ggid varchar(32) binary DEFAULT '' NOT NULL,
+email varchar(64) DEFAULT '' NOT NULL,
+passwd varchar(32) binary DEFAULT '' NOT NULL,
+PRIMARY KEY (id),
+UNIQUE ggid (ggid)
+) TYPE=BDB;
+insert into t1 (ggid,passwd) values ('test1','xxx');
+insert into t1 (ggid,passwd) values ('test2','yyy');
+insert into t1 (ggid,passwd) values ('test2','this will fail');
+Duplicate entry 'test2' for key 2
+insert into t1 (ggid,id) values ('this will fail',1);
+Duplicate entry '1' for key 1
+select * from t1 where ggid='test1';
id ggid email passwd
1 test1 xxx
+select * from t1 where passwd='xxx';
id ggid email passwd
1 test1 xxx
+select * from t1 where id=2;
id ggid email passwd
2 test2 yyy
+replace into t1 (ggid,id) values ('this will work',1);
+replace into t1 (ggid,passwd) values ('test2','this will work');
+update t1 set id=100,ggid='test2' where id=1;
+Duplicate entry 'test2' for key 2
+select * from t1;
id ggid email passwd
1 this will work
3 test2 this will work
+select * from t1 where id=1;
id ggid email passwd
1 this will work
+select * from t1 where id=999;
id ggid email passwd
+drop table t1;
+CREATE TABLE t1 (
+user_name varchar(12),
+password text,
+subscribed char(1),
+user_id int(11) DEFAULT '0' NOT NULL,
+quota bigint(20),
+weight double,
+access_date date,
+access_time time,
+approved datetime,
+dummy_primary_key int(11) NOT NULL auto_increment,
+PRIMARY KEY (dummy_primary_key)
+) TYPE=BDB;
+INSERT INTO t1 VALUES ('user_0','somepassword','N',0,0,0,'2000-09-07','23:06:59','2000-09-07 23:06:59',1);
+INSERT INTO t1 VALUES ('user_1','somepassword','Y',1,1,1,'2000-09-07','23:06:59','2000-09-07 23:06:59',2);
+INSERT INTO t1 VALUES ('user_2','somepassword','N',2,2,1.4142135623731,'2000-09-07','23:06:59','2000-09-07 23:06:59',3);
+INSERT INTO t1 VALUES ('user_3','somepassword','Y',3,3,1.7320508075689,'2000-09-07','23:06:59','2000-09-07 23:06:59',4);
+INSERT INTO t1 VALUES ('user_4','somepassword','N',4,4,2,'2000-09-07','23:06:59','2000-09-07 23:06:59',5);
+select user_name, password , subscribed, user_id, quota, weight, access_date, access_time, approved, dummy_primary_key from t1 order by user_name;
user_name password subscribed user_id quota weight access_date access_time approved dummy_primary_key
user_0 somepassword N 0 0 0 2000-09-07 23:06:59 2000-09-07 23:06:59 1
user_1 somepassword Y 1 1 1 2000-09-07 23:06:59 2000-09-07 23:06:59 2
user_2 somepassword N 2 2 1.4142135623731 2000-09-07 23:06:59 2000-09-07 23:06:59 3
user_3 somepassword Y 3 3 1.7320508075689 2000-09-07 23:06:59 2000-09-07 23:06:59 4
user_4 somepassword N 4 4 2 2000-09-07 23:06:59 2000-09-07 23:06:59 5
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) type=bdb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1);
+INSERT INTO t1 values (179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
id parent_id level
8 102 2
9 102 2
15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+select * from t1;
id parent_id level
1001 100 0
1003 101 1
@@ -327,6 +575,8 @@ id parent_id level
1019 103 2
1005 101 1
1179 105 2
+update ignore t1 set id=id+1;
+select * from t1;
id parent_id level
1002 100 0
1004 101 1
@@ -367,12 +617,16 @@ id parent_id level
1020 103 2
1006 101 1
1180 105 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
id parent_id level
1009 102 2
1025 102 2
1016 102 2
+explain select level from t1 where level=1;
table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 1 where used; Using index
+t1 ref level level 1 const 1 Using where; Using index
+select level,id from t1 where level=1;
level id
1 1004
1 1005
@@ -380,6 +634,7 @@ level id
1 1007
1 1008
1 1006
+select level,id,parent_id from t1 where level=1;
level id parent_id
1 1004 101
1 1005 101
@@ -387,6 +642,7 @@ level id parent_id
1 1007 101
1 1008 101
1 1006 101
+select level,id from t1 where level=1 order by id;
level id
1 1003
1 1004
@@ -394,6 +650,8 @@ level id
1 1006
1 1007
1 1008
+delete from t1 where level=1;
+select * from t1;
id parent_id level
1002 100 0
1009 102 2
@@ -428,43 +686,86 @@ id parent_id level
1022 104 2
1020 103 2
1180 105 2
+drop table t1;
+CREATE TABLE t1 (
+sca_code char(6) NOT NULL,
+cat_code char(6) NOT NULL,
+sca_desc varchar(50),
+lan_code char(2) NOT NULL,
+sca_pic varchar(100),
+sca_sdesc varchar(50),
+sca_sch_desc varchar(16),
+PRIMARY KEY (sca_code, cat_code, lan_code),
+INDEX sca_pic (sca_pic)
+) type = bdb ;
+INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING'),( 'QQ', 'N', 'RING', 'EN', 'not null', NULL, 'RING');
+select count(*) from t1 where sca_code = 'PD';
count(*)
1
+select count(*) from t1 where sca_code <= 'PD';
count(*)
1
+select count(*) from t1 where sca_pic is null;
count(*)
2
+alter table t1 drop index sca_pic, add index sca_pic (cat_code, sca_pic);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
count(*)
1
+select count(*) from t1 where cat_code='E';
count(*)
0
+alter table t1 drop index sca_pic, add index (sca_pic, cat_code);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
count(*)
1
+select count(*) from t1 where sca_pic >= 'n';
count(*)
1
+select sca_pic from t1 where sca_pic is null;
sca_pic
NULL
NULL
+update t1 set sca_pic="test" where sca_pic is null;
+delete from t1 where sca_code='pd';
+drop table t1;
+set @a:=now();
+CREATE TABLE t1 (a int not null, b timestamp not null, primary key (a)) type=bdb;
+insert into t1 (a) values(1),(2),(3);
+select t1.a from t1 natural join t1 as t2 where t1.b >= @a order by t1.a;
a
1
2
3
+update t1 set a=5 where a=1;
+select a from t1;
a
2
3
5
+drop table t1;
+flush logs;
+create table t1 (b blob, i int, key (b(100)), key (i), key (i, b(20))) type=bdb;
+insert into t1 values ('this is a blob', 1), (null, -1), (null, null),("",1),("",2),("",3);
+select b from t1 where b = 'this is a blob';
b
this is a blob
+select * from t1 where b like 't%';
b i
this is a blob 1
+select b, i from t1 where b is not null;
b i
this is a blob 1
1
2
3
+select * from t1 where b is null and i > 0;
b i
+select * from t1 where i is NULL;
b i
NULL NULL
+update t1 set b='updated' where i=1;
+select * from t1;
b i
updated 1
NULL -1
@@ -472,63 +773,420 @@ NULL NULL
updated 1
2
3
+drop table t1;
+create table t1 (a varchar(100) not null, primary key(a), b int not null) type=bdb;
+insert into t1 values("hello",1),("world",2);
+select * from t1 order by b desc;
a b
world 2
hello 1
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 2 NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 2 NULL NULL BTREE
+drop table t1;
+create table t1 (i int, j int )TYPE=BDB;
+insert into t1 values (1,2);
+select * from t1 where i=1 and j=2;
i j
1 2
+create index ax1 on t1 (i,j);
+select * from t1 where i=1 and j=2;
i j
1 2
+drop table t1;
+drop table if exists t1, t2, t3, t4, t5, t6, t7;
+create table t1
+(
+branch_id int auto_increment primary key,
+branch_name varchar(255) not null,
+branch_active int not null default 1,
+unique branch_name(branch_name),
+index branch_active(branch_active)
+) type=bdb;
+drop table if exists t2 ;
+create table t2
+(
+target_id int auto_increment primary key,
+target_name varchar(255) not null,
+target_active int not null default 1,
+unique target_name(target_name),
+index target_active(target_active)
+) type=bdb;
+drop table if exists t3 ;
+create table t3
+(
+platform_id int auto_increment primary key,
+platform_name varchar(255) not null,
+platform_active int not null default 1,
+unique platform_name(platform_name),
+index platform_active(platform_active)
+) type=bdb;
+drop table if exists t4 ;
+create table t4
+(
+product_id int auto_increment primary key,
+product_name varchar(255) not null,
+version_file varchar(255) not null,
+product_active int not null default 1,
+unique product_name(product_name),
+index product_active(product_active)
+) type=bdb;
+drop table if exists t5 ;
+create table t5
+(
+product_file_id int auto_increment primary key,
+product_id int not null,
+file_name varchar(255) not null,
+/* cvs module used to find the file version */
+module_name varchar(255) not null,
+/* flag whether the file is still included in the product */
+file_included int not null default 1,
+unique product_file(product_id,file_name),
+index file_included(file_included)
+) type=bdb;
+drop table if exists t6 ;
+create table t6
+(
+file_platform_id int auto_increment primary key,
+product_file_id int not null,
+platform_id int not null,
+branch_id int not null,
+/* filename in the build system */
+build_filename varchar(255) not null,
+/* default filename in the build archive */
+archive_filename varchar(255) not null,
+unique file_platform(product_file_id,platform_id,branch_id)
+) type=bdb;
+drop table if exists t8 ;
+create table t8
+(
+archive_id int auto_increment primary key,
+branch_id int not null,
+target_id int not null,
+platform_id int not null,
+product_id int not null,
+status_id int not null default 1,
+unique archive(branch_id,target_id,platform_id,product_id),
+index status_id(status_id)
+) type=bdb;
+drop table if exists t7 ;
+create table t7
+(
+build_id int auto_increment primary key,
+branch_id int not null,
+target_id int not null,
+build_number int not null,
+build_date date not null,
+/* build system tag, e.g. 'rmanight-022301-1779' */
+build_tag varchar(255) not null,
+/* path relative to the build archive root, e.g. 'current' */
+build_path text not null,
+unique build(branch_id,target_id,build_number)
+) type=bdb;
+insert into t1 (branch_name)
+values ('RealMedia');
+insert into t1 (branch_name)
+values ('RP8REV');
+insert into t1 (branch_name)
+values ('SERVER_8_0_GOLD');
+insert into t2 (target_name)
+values ('rmanight');
+insert into t2 (target_name)
+values ('playerall');
+insert into t2 (target_name)
+values ('servproxyall');
+insert into t3 (platform_name)
+values ('linux-2.0-libc6-i386');
+insert into t3 (platform_name)
+values ('win32-i386');
+insert into t4 (product_name, version_file)
+values ('realserver', 'servinst');
+insert into t4 (product_name, version_file)
+values ('realproxy', 'prxyinst');
+insert into t4 (product_name, version_file)
+values ('realplayer', 'playinst');
+insert into t4 (product_name, version_file)
+values ('plusplayer', 'plusinst');
+create temporary table tmp1
+select branch_id, target_id, platform_id, product_id
+from t1, t2, t3, t4 ;
+create temporary table tmp2
+select tmp1.branch_id, tmp1.target_id, tmp1.platform_id, tmp1.product_id
+from tmp1 left join t8
+using (branch_id,target_id,platform_id,product_id)
+where t8.archive_id is null ;
+insert into t8
+(branch_id, target_id, platform_id, product_id, status_id)
+select branch_id, target_id, platform_id, product_id, 1
+from tmp2 ;
+drop table tmp1 ;
+drop table tmp2 ;
+insert into t5 (product_id, file_name, module_name)
+values (1, 'servinst', 'server');
+insert into t5 (product_id, file_name, module_name)
+values (2, 'prxyinst', 'server');
+insert into t5 (product_id, file_name, module_name)
+values (3, 'playinst', 'rpapp');
+insert into t5 (product_id, file_name, module_name)
+values (4, 'plusinst', 'rpapp');
+insert into t6
+(product_file_id,platform_id,branch_id,build_filename,archive_filename)
+values (1, 2, 3, 'servinst.exe', 'win32-servinst.exe');
+insert into t6
+(product_file_id,platform_id,branch_id,build_filename,archive_filename)
+values (1, 1, 3, 'v80_linux-2.0-libc6-i386_servinst.bin', 'linux2-servinst.exe');
+insert into t6
+(product_file_id,platform_id,branch_id,build_filename,archive_filename)
+values (3, 2, 2, 'playinst.exe', 'win32-playinst.exe');
+insert into t6
+(product_file_id,platform_id,branch_id,build_filename,archive_filename)
+values (4, 2, 2, 'playinst.exe', 'win32-playinst.exe');
+insert into t7
+(branch_id,target_id,build_number,build_tag,build_date,build_path)
+values (2, 2, 1071, 'playerall-022101-1071', '2001-02-21', 'current');
+insert into t7
+(branch_id,target_id,build_number,build_tag,build_date,build_path)
+values (2, 2, 1072, 'playerall-022201-1072', '2001-02-22', 'current');
+insert into t7
+(branch_id,target_id,build_number,build_tag,build_date,build_path)
+values (3, 3, 388, 'servproxyall-022201-388', '2001-02-22', 'current');
+insert into t7
+(branch_id,target_id,build_number,build_tag,build_date,build_path)
+values (3, 3, 389, 'servproxyall-022301-389', '2001-02-23', 'current');
+insert into t7
+(branch_id,target_id,build_number,build_tag,build_date,build_path)
+values (4, 4, 100, 'foo target-010101-100', '2001-01-01', 'current');
+update t8
+set status_id=2
+where branch_id=2 and target_id=2 and platform_id=2 and product_id=1;
+select t7.build_path
+from
+t1,
+t7,
+t2,
+t3,
+t4,
+t5,
+t6
+where
+t7.branch_id = t1.branch_id and
+t7.target_id = t2.target_id and
+t5.product_id = t4.product_id and
+t6.product_file_id = t5.product_file_id and
+t6.platform_id = t3.platform_id and
+t6.branch_id = t6.branch_id and
+t7.build_id = 1 and
+t4.product_id = 3 and
+t5.file_name = 'playinst' and
+t3.platform_id = 2;
build_path
current
+drop table t1, t2, t3, t4, t5, t6, t7, t8;
+CREATE TABLE t1 (
+a tinytext NOT NULL,
+b tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (a(32),b)
+) TYPE=BDB;
+INSERT INTO t1 VALUES ('a',1),('a',2);
+SELECT * FROM t1 WHERE a='a' AND b=2;
a b
a 2
+SELECT * FROM t1 WHERE a='a' AND b in (2);
a b
a 2
+SELECT * FROM t1 WHERE a='a' AND b in (1,2);
a b
a 1
a 2
+drop table t1;
+CREATE TABLE t1 (
+a int3 unsigned NOT NULL,
+b int1 unsigned NOT NULL,
+UNIQUE (a, b)
+) TYPE = BDB;
+INSERT INTO t1 VALUES (1, 1);
+SELECT MIN(B),MAX(b) FROM t1 WHERE t1.a = 1;
MIN(B) MAX(b)
1 1
+drop table t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=bdb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+Duplicate entry '1-1' for key 1
+select id from t1;
id
0
1
2
+select id from t1;
id
0
1
2
+UNLOCK TABLES;
+DROP TABLE t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=bdb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+begin;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+Duplicate entry '1-1' for key 1
+select id from t1;
id
0
1
2
+insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D');
+commit;
+select id,id3 from t1;
id id3
0 0
1 1
2 2
100 2
+UNLOCK TABLES;
+DROP TABLE t1;
+CREATE TABLE t1 (SYAIN_NO char(5) NOT NULL default '', KINMU_DATE char(6) NOT NULL default '', PRIMARY KEY (SYAIN_NO,KINMU_DATE)) TYPE=BerkeleyDB;
+CREATE TABLE t2 ( SYAIN_NO char(5) NOT NULL default '',STR_DATE char(8) NOT NULL default '',PRIMARY KEY (SYAIN_NO,STR_DATE) ) TYPE=BerkeleyDB;
+select T1.KINMU_DATE from t1 T1 ,t2 T2 where T1.SYAIN_NO = '12345' and T1.KINMU_DATE = '200106' and T2.SYAIN_NO = T1.SYAIN_NO;
KINMU_DATE
+select T1.KINMU_DATE from t1 T1 ,t2 T2 where T1.SYAIN_NO = '12345' and T1.KINMU_DATE = '200106' and T2.SYAIN_NO = T1.SYAIN_NO;
KINMU_DATE
+DROP TABLE t1,t2;
+drop table if exists t1;
+create table t1 (a int(11) not null, b int(11) not null, unique (a,b)) type=bdb;
+insert into t1 values (1,1), (1,2);
+select * from t1 where a = 1;
a b
1 1
1 2
+select t1.*, t2.* from t1, t1 t2 where t1.a = t2.a and t2.a = 1;
a b a b
1 1 1 1
1 1 1 2
1 2 1 1
1 2 1 2
+select * from t1 where a = 1;
a b
1 1
1 2
+drop table t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=bdb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ');
+create table t2 (id int NOT NULL,primary key (id)) type=bdb;
+LOCK TABLES t1 WRITE, t2 WRITE;
+insert into t2 values(1);
+SELECT t1.* FROM t1 WHERE id IN (1);
id id2 id3 dummy1
+SELECT t1.* FROM t2 left outer join t1 on (t1.id=t2.id);
id id2 id3 dummy1
NULL NULL NULL NULL
+delete from t1 where id3 >= 0 and id3 <= 0;
+drop table t1,t2;
+CREATE TABLE t1 (i varchar(48) NOT NULL default '', p varchar(255) default NULL,s varchar(48) NOT NULL default '', PRIMARY KEY (i), UNIQUE(p,s)) TYPE=BDB;
+INSERT INTO t1 VALUES ('00000000-e6c4ddeaa6-003b8-83458387','programs/xxxxxxxx.wmv','00000000-e6c4ddeb32-003bc-83458387');
+SELECT * FROM t1 WHERE p='programs/xxxxxxxx.wmv';
i p s
00000000-e6c4ddeaa6-003b8-83458387 programs/xxxxxxxx.wmv 00000000-e6c4ddeb32-003bc-83458387
+drop table t1;
+CREATE TABLE t1 ( STR_DATE varchar(8) NOT NULL default '',INFO_NOTE varchar(200) default NULL,PRIMARY KEY (STR_DATE) ) TYPE=BerkeleyDB;
+select INFO_NOTE from t1 where STR_DATE = '20010610';
INFO_NOTE
+select INFO_NOTE from t1 where STR_DATE < '20010610';
INFO_NOTE
+select INFO_NOTE from t1 where STR_DATE > '20010610';
INFO_NOTE
+drop table t1;
+create table t1 (a int not null, b int, primary key (a)) type =bdb;
+create table t2 (a int not null, b int, primary key (a)) type =bdb;
+insert into t1 values (2, 3),(1, 7),(10, 7);
+insert into t2 values (2, 3),(1, 7),(10, 7);
+select * from t1;
+a b
+1 7
+2 3
+10 7
+select * from t2;
+a b
+1 7
+2 3
+10 7
+delete t1, t2 from t1, t2 where t1.a = t2.a;
+select * from t1;
+a b
+select * from t2;
+a b
+select * from t2;
+a b
+drop table t1,t2;
+create table t1 (x int not null, index(x)) type=bdb;
+insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+select * from t1 where x <= 10 and x >= 7;
+x
+7
+8
+9
+10
+select * from t1 where x <= 10 and x >= 7 order by x;
+x
+7
+8
+9
+10
+select * from t1 where x <= 10 and x >= 7 order by x desc;
+x
+10
+9
+8
+7
+select * from t1 where x <= 8 and x >= 5 order by x desc;
+x
+8
+7
+6
+5
+select * from t1 where x < 8 and x > 5 order by x desc;
+x
+7
+6
+drop table t1;
+create table t1 ( c char(8) not null ) type=bdb;
+insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9');
+insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F');
+alter table t1 add b char(8) not null;
+alter table t1 add a char(8) not null;
+alter table t1 add primary key (a,b,c);
+update t1 set a=c, b=c;
+create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=bdb;
+insert into t2 select * from t1;
+delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
+drop table t1,t2;
+create table t1 (a char(10), key(a), b int not null, key(b)) engine=bdb;
+insert into t1 values ('a',1),('A',2);
+explain select a from t1;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 2
+select a from t1;
+a
+a
+A
+explain select b from t1;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL b 4 NULL 2 Using index
+select b from t1;
+b
+1
+2
+alter table t1 modify a char(10) binary;
+explain select a from t1;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL a 11 NULL 2 Using index
+select a from t1;
+a
+A
+a
+drop table t1;
diff --git a/mysql-test/r/bdb_cache.result b/mysql-test/r/bdb_cache.result
new file mode 100644
index 00000000000..e5c6923162a
--- /dev/null
+++ b/mysql-test/r/bdb_cache.result
@@ -0,0 +1,100 @@
+drop table if exists t1, t2, t3;
+flush status;
+set autocommit=0;
+create table t1 (a int not null) type=bdb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+commit;
+set autocommit=1;
+begin;
+create table t1 (a int not null) type=bdb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+commit;
+create table t1 (a int not null) type=bdb;
+create table t2 (a int not null) type=bdb;
+create table t3 (a int not null) type=bdb;
+insert into t1 values (1),(2);
+insert into t2 values (1),(2);
+insert into t3 values (1),(2);
+select * from t1;
+a
+1
+2
+select * from t2;
+a
+1
+2
+select * from t3;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+begin;
+select * from t1;
+a
+1
+2
+select * from t2;
+a
+1
+2
+select * from t3;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+insert into t1 values (3);
+insert into t2 values (3);
+insert into t1 values (4);
+select * from t1;
+a
+1
+2
+3
+4
+select * from t2;
+a
+1
+2
+3
+select * from t3;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+commit;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
diff --git a/mysql-test/r/bench_count_distinct.result b/mysql-test/r/bench_count_distinct.result
index 20f23c0abbe..d414e8e466e 100644
--- a/mysql-test/r/bench_count_distinct.result
+++ b/mysql-test/r/bench_count_distinct.result
@@ -1,2 +1,6 @@
+drop table if exists t1;
+create table t1(n int not null, key(n)) delay_key_write = 1;
+select count(distinct n) from t1;
count(distinct n)
100
+drop table t1;
diff --git a/mysql-test/r/big_test.require b/mysql-test/r/big_test.require
new file mode 100644
index 00000000000..001b903496b
--- /dev/null
+++ b/mysql-test/r/big_test.require
@@ -0,0 +1,2 @@
+using_big_test
+1
diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result
index 46ce0fda2c1..308adc881f2 100644
--- a/mysql-test/r/bigint.result
+++ b/mysql-test/r/bigint.result
@@ -1,15 +1,83 @@
+select 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296;
0 256 00000000000000065536 2147483647 -2147483648 2147483648 +4294967296
0 256 65536 2147483647 -2147483648 2147483648 4294967296
+select 9223372036854775807,-009223372036854775808;
9223372036854775807 -009223372036854775808
9223372036854775807 -9223372036854775808
+select +9999999999999999999,-9999999999999999999;
+9999999999999999999 -9999999999999999999
-10000000000000000000 -10000000000000000000
+9999999999999999999 -10000000000000000000
+select cast(9223372036854775808 as unsigned)+1;
+cast(9223372036854775808 as unsigned)+1
+9223372036854775809
+select 9223372036854775808+1;
+9223372036854775808+1
+9223372036854775809
+drop table if exists t1;
+create table t1 (a bigint unsigned not null, primary key(a));
+insert into t1 values (18446744073709551615), (0xFFFFFFFFFFFFFFFE), (18446744073709551613), (18446744073709551612);
+select * from t1;
a
+18446744073709551612
+18446744073709551613
18446744073709551614
18446744073709551615
+select * from t1 where a=18446744073709551615;
a
18446744073709551615
+delete from t1 where a=18446744073709551615;
+select * from t1;
a
-18446744073709551615
-a
+18446744073709551612
+18446744073709551613
18446744073709551614
+drop table t1;
+create table t1 ( a int not null default 1, big bigint );
+insert into t1 (big) values (-1),(12345678901234567),(9223372036854775807),(18446744073709551615);
+select min(big),max(big),max(big)-1 from t1;
+min(big) max(big) max(big)-1
+-1 9223372036854775807 9223372036854775806
+select min(big),max(big),max(big)-1 from t1 group by a;
+min(big) max(big) max(big)-1
+-1 9223372036854775807 9223372036854775806
+alter table t1 modify big bigint unsigned not null;
+select min(big),max(big),max(big)-1 from t1;
+min(big) max(big) max(big)-1
+12345678901234567 18446744073709551615 18446744073709551614
+select min(big),max(big),max(big)-1 from t1 group by a;
+min(big) max(big) max(big)-1
+12345678901234567 18446744073709551615 18446744073709551614
+alter table t1 add key (big);
+select min(big),max(big),max(big)-1 from t1;
+min(big) max(big) max(big)-1
+12345678901234567 18446744073709551615 18446744073709551614
+select min(big),max(big),max(big)-1 from t1 group by a;
+min(big) max(big) max(big)-1
+12345678901234567 18446744073709551615 18446744073709551614
+alter table t1 modify big bigint not null;
+select min(big),max(big),max(big)-1 from t1;
+min(big) max(big) max(big)-1
+-1 9223372036854775807 9223372036854775806
+select min(big),max(big),max(big)-1 from t1 group by a;
+min(big) max(big) max(big)-1
+-1 9223372036854775807 9223372036854775806
+drop table t1;
+create table t1 (id bigint auto_increment primary key, a int) auto_increment=9999999999;
+insert into t1 values (null,1);
+select * from t1;
+id a
+9999999999 1
+select * from t1 limit 9999999999;
+id a
+9999999999 1
+drop table t1;
+CREATE TABLE t1 ( quantity decimal(60,0));
+insert into t1 values (10000000000000000000);
+insert into t1 values (10000000000000000000.0);
+insert into t1 values ('10000000000000000000');
+select * from t1;
+quantity
+-8446744073709551616
+10000000000000000000
+10000000000000000000
+drop table t1;
diff --git a/mysql-test/r/binary.result b/mysql-test/r/binary.result
index cbd95e03232..2de8b01bc3a 100644
--- a/mysql-test/r/binary.result
+++ b/mysql-test/r/binary.result
@@ -1,37 +1,82 @@
+drop table if exists t1,t2;
+create table t1 (name char(20) not null, primary key (name));
+create table t2 (name char(20) binary not null, primary key (name));
+insert into t1 values ("å");
+insert into t1 values ("ä");
+insert into t1 values ("ö");
+insert into t2 select * from t1;
+select * from t1 order by name;
name
å
ä
ö
+select concat("*",name,"*") from t1 order by 1;
concat("*",name,"*")
*å*
*ä*
*ö*
+select min(name),min(concat("*",name,"*")),max(name),max(concat("*",name,"*")) from t1;
min(name) min(concat("*",name,"*")) max(name) max(concat("*",name,"*"))
å *å* ö *ö*
+select * from t2 order by name;
name
ä
å
ö
+select concat("*",name,"*") from t2 order by 1;
concat("*",name,"*")
*ä*
*å*
*ö*
+select min(name),min(concat("*",name,"*")),max(name),max(concat("*",name,"*")) from t2;
min(name) min(concat("*",name,"*")) max(name) max(concat("*",name,"*"))
ä *ä* ö *ö*
+select name from t1 where name between 'Ä' and 'Ö';
name
ä
ö
+select name from t2 where name between 'ä' and 'ö';
name
ä
å
ö
+select name from t2 where name between 'Ä' and 'Ö';
name
+drop table t1,t2;
+create table t1 (a char(10) not null, b char(10) binary not null,key (a), key(b));
+insert into t1 values ("hello ","hello "),("hello2 ","hello2 ");
+select * from t1 where a="hello";
a b
hello hello
+select * from t1 where a="hello ";
a b
+hello hello
+select * from t1 ignore index (a) where a="hello ";
+a b
+hello hello
+select * from t1 where b="hello";
+a b
+hello hello
+select * from t1 where b="hello ";
+a b
+hello hello
+select * from t1 ignore index (b) where b="hello ";
+a b
+alter table t1 modify b tinytext not null, drop key b, add key (b(100));
+select * from t1 where b="hello ";
+a b
+hello hello
+select * from t1 ignore index (b) where b="hello ";
a b
hello hello
+drop table t1;
+create table t1 (b char(8));
+insert into t1 values(NULL);
+select b from t1 where binary b like '';
b
+select b from t1 group by binary b like '';
b
NULL
+select b from t1 having binary b like '';
b
+drop table t1;
diff --git a/mysql-test/r/bool.result b/mysql-test/r/bool.result
new file mode 100644
index 00000000000..cb82c6baa0f
--- /dev/null
+++ b/mysql-test/r/bool.result
@@ -0,0 +1,74 @@
+DROP TABLE IF EXISTS t1;
+SELECT IF(NULL AND 1, 1, 2), IF(1 AND NULL, 1, 2);
+IF(NULL AND 1, 1, 2) IF(1 AND NULL, 1, 2)
+2 2
+SELECT NULL AND 1, 1 AND NULL, 0 AND NULL, NULL and 0;
+NULL AND 1 1 AND NULL 0 AND NULL NULL and 0
+NULL NULL 0 0
+create table t1 (a int);
+insert into t1 values (0),(1),(NULL);
+SELECT * FROM t1 WHERE IF(a AND 1, 0, 1);
+a
+0
+NULL
+SELECT * FROM t1 WHERE IF(1 AND a, 0, 1);
+a
+0
+NULL
+SELECT * FROM t1 where NOT(a AND 1);
+a
+0
+SELECT * FROM t1 where NOT(1 AND a);
+a
+0
+SELECT * FROM t1 where (a AND 1)=0;
+a
+0
+SELECT * FROM t1 where (1 AND a)=0;
+a
+0
+SELECT * FROM t1 where (1 AND a)=1;
+a
+1
+SELECT * FROM t1 where (1 AND a) IS NULL;
+a
+NULL
+SET @a=0, @b=0;
+SELECT * FROM t1 WHERE NULL AND (@a:=@a+1);
+a
+SELECT * FROM t1 WHERE NOT(a>=0 AND NULL AND (@b:=@b+1));
+a
+SELECT * FROM t1 WHERE a=2 OR (NULL AND (@a:=@a+1));
+a
+SELECT * FROM t1 WHERE NOT(a=2 OR (NULL AND (@b:=@b+1)));
+a
+SELECT @a, @b;
+@a @b
+0 6
+DROP TABLE t1;
+drop table if exists t;
+create table t(a int, b int);
+insert into t values(null, null), (0, null), (1, null), (null, 0), (null, 1), (0, 0), (0, 1), (1, 0), (1, 1);
+select ifnull(A, 'N') as A, ifnull(B, 'N') as B, ifnull(not A, 'N') as nA, ifnull(not B, 'N') as nB, ifnull(A and B, 'N') as AB, ifnull(not (A and B), 'N') as `n(AB)`, ifnull((not A or not B), 'N') as nAonB, ifnull(A or B, 'N') as AoB, ifnull(not(A or B), 'N') as `n(AoB)`, ifnull(not A and not B, 'N') as nAnB from t;
+A B nA nB AB n(AB) nAonB AoB n(AoB) nAnB
+N N N N N N N N N N
+0 N 1 N 0 1 1 N N N
+1 N 0 N N N N 1 0 0
+N 0 N 1 0 1 1 N N N
+N 1 N 0 N N N 1 0 0
+0 0 1 1 0 1 1 0 1 1
+0 1 1 0 0 1 1 1 0 0
+1 0 0 1 0 1 1 1 0 0
+1 1 0 0 1 0 0 1 0 0
+select ifnull(A=1, 'N') as A, ifnull(B=1, 'N') as B, ifnull(not (A=1), 'N') as nA, ifnull(not (B=1), 'N') as nB, ifnull((A=1) and (B=1), 'N') as AB, ifnull(not ((A=1) and (B=1)), 'N') as `n(AB)`, ifnull((not (A=1) or not (B=1)), 'N') as nAonB, ifnull((A=1) or (B=1), 'N') as AoB, ifnull(not((A=1) or (B=1)), 'N') as `n(AoB)`, ifnull(not (A=1) and not (B=1), 'N') as nAnB from t;
+A B nA nB AB n(AB) nAonB AoB n(AoB) nAnB
+N N N N N N N N N N
+0 N 1 N 0 1 1 N N N
+1 N 0 N N N N 1 0 0
+N 0 N 1 0 1 1 N N N
+N 1 N 0 N N N 1 0 0
+0 0 1 1 0 1 1 0 1 1
+0 1 1 0 0 1 1 1 0 0
+1 0 0 1 0 1 1 1 0 0
+1 1 0 0 1 0 0 1 0 0
+drop table t;
diff --git a/mysql-test/r/bulk_replace.result b/mysql-test/r/bulk_replace.result
new file mode 100644
index 00000000000..0a079965b82
--- /dev/null
+++ b/mysql-test/r/bulk_replace.result
@@ -0,0 +1,11 @@
+drop table if exists t1;
+CREATE TABLE t1 (a int, unique (a), b int not null, unique(b), c int not null, index(c));
+replace into t1 values (1,1,1),(2,2,2),(3,1,3);
+select * from t1;
+a b c
+3 1 3
+2 2 2
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index 9ba33daaa4d..4c16b375400 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -1,46 +1,73 @@
+drop table if exists t1;
+select CASE "b" when "a" then 1 when "b" then 2 END;
CASE "b" when "a" then 1 when "b" then 2 END
2
+select CASE "c" when "a" then 1 when "b" then 2 END;
CASE "c" when "a" then 1 when "b" then 2 END
NULL
+select CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END;
CASE "c" when "a" then 1 when "b" then 2 ELSE 3 END
3
+select CASE BINARY "b" when "a" then 1 when "B" then 2 WHEN "b" then "ok" END;
CASE BINARY "b" when "a" then 1 when "B" then 2 WHEN "b" then "ok" END
ok
+select CASE "b" when "a" then 1 when binary "B" then 2 WHEN "b" then "ok" END;
CASE "b" when "a" then 1 when binary "B" then 2 WHEN "b" then "ok" END
ok
+select CASE concat("a","b") when concat("ab","") then "a" when "b" then "b" end;
CASE concat("a","b") when concat("ab","") then "a" when "b" then "b" end
a
+select CASE when 1=0 then "true" else "false" END;
CASE when 1=0 then "true" else "false" END
false
+select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END;
CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END
one
+select CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END;
CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END
two
+select (CASE "two" when "one" then "1" WHEN "two" then "2" END) | 0;
(CASE "two" when "one" then "1" WHEN "two" then "2" END) | 0
2
+select (CASE "two" when "one" then 1.00 WHEN "two" then 2.00 END) +0.0;
(CASE "two" when "one" then 1.00 WHEN "two" then 2.00 END) +0.0
2.00
+select case 1/0 when "a" then "true" else "false" END;
case 1/0 when "a" then "true" else "false" END
false
+select case 1/0 when "a" then "true" END;
case 1/0 when "a" then "true" END
NULL
+select (case 1/0 when "a" then "true" END) | 0;
(case 1/0 when "a" then "true" END) | 0
NULL
+select (case 1/0 when "a" then "true" END) + 0.0;
(case 1/0 when "a" then "true" END) + 0.0
NULL
+select case when 1>0 then "TRUE" else "FALSE" END;
case when 1>0 then "TRUE" else "FALSE" END
TRUE
+select case when 1<0 then "TRUE" else "FALSE" END;
case when 1<0 then "TRUE" else "FALSE" END
FALSE
+create table t1 (a int);
+insert into t1 values(1),(2),(3),(4);
+select case a when 1 then 2 when 2 then 3 else 0 end as fcase, count(*) from t1 group by fcase;
fcase count(*)
0 2
2 1
3 1
+select case a when 1 then "one" when 2 then "two" else "nothing" end as fcase, count(*) from t1 group by fcase;
fcase count(*)
nothing 2
one 1
two 1
+drop table t1;
+create table t1 (row int not null, col int not null, val varchar(255) not null);
+insert into t1 values (1,1,'orange'),(1,2,'large'),(2,1,'yellow'),(2,2,'medium'),(3,1,'green'),(3,2,'small');
+select max(case col when 1 then val else null end) as color from t1 group by row;
color
orange
yellow
green
+drop table t1;
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
new file mode 100644
index 00000000000..572b32c171c
--- /dev/null
+++ b/mysql-test/r/cast.result
@@ -0,0 +1,39 @@
+select CAST(1-2 AS UNSIGNED);
+CAST(1-2 AS UNSIGNED)
+18446744073709551615
+select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
+CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
+-1
+select CONVERT('-1',UNSIGNED);
+CONVERT('-1',UNSIGNED)
+18446744073709551615
+select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
+cast(-5 as unsigned) | 1 cast(-5 as unsigned) & -1
+18446744073709551611 18446744073709551611
+select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
+cast(-5 as unsigned) -1 cast(-5 as unsigned) + 1
+18446744073709551610 18446744073709551612
+select ~5, cast(~5 as signed);
+~5 cast(~5 as signed)
+18446744073709551610 -6
+select cast(5 as unsigned) -6.0;
+cast(5 as unsigned) -6.0
+-1.0
+select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A";
+cast("A" as binary) = "a" cast(BINARY "a" as CHAR) = "A"
+0 1
+select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME);
+cast("2001-1-1" as DATE) cast("2001-1-1" as DATETIME)
+2001-1-1 2001-1-1
+select cast("1:2:3" as TIME);
+cast("1:2:3" as TIME)
+1:2:3
+select cast("2001-1-1" as date) = "2001-01-01";
+cast("2001-1-1" as date) = "2001-01-01"
+0
+select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
+cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"
+0
+select cast("1:2:3" as TIME) = "1:02:03";
+cast("1:2:3" as TIME) = "1:02:03"
+0
diff --git a/mysql-test/r/check.result b/mysql-test/r/check.result
index 694d7429a14..ecaa13642bd 100644
--- a/mysql-test/r/check.result
+++ b/mysql-test/r/check.result
@@ -1,2 +1,7 @@
+drop table if exists t1;
+create table t1(n int not null, key(n), key(n), key(n), key(n));
+ check table t1 extended;
+insert into t1 values (200000);
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
diff --git a/mysql-test/r/check_var_limit.require b/mysql-test/r/check_var_limit.require
new file mode 100644
index 00000000000..01a59782180
--- /dev/null
+++ b/mysql-test/r/check_var_limit.require
@@ -0,0 +1,2 @@
+limit
+1
diff --git a/mysql-test/r/comments.result b/mysql-test/r/comments.result
index 7044667e4af..8092f789954 100644
--- a/mysql-test/r/comments.result
+++ b/mysql-test/r/comments.result
@@ -1,15 +1,28 @@
+select 1+2/*hello*/+3;
1+2/*hello*/+3
6
+select 1 /* long
+multi line comment */;
1
1
+;
+Query was empty
+select 1 /*!32301 +1 */;
1 /*!32301 +1
2
+select 1 /*!52301 +1 */;
1
1
+select 1--1;
1--1
2
+select 1 --2
++1;
1 --2
+1
4
+select 1 # The rest of the row will be ignored
+;
1
1
+/* line with only comment */;
diff --git a/mysql-test/r/compare.result b/mysql-test/r/compare.result
index 6af85c16dff..afd2a1a086b 100644
--- a/mysql-test/r/compare.result
+++ b/mysql-test/r/compare.result
@@ -1,6 +1,14 @@
+drop table if exists t1;
+CREATE TABLE t1 (id CHAR(12) not null, PRIMARY KEY (id));
+insert into t1 values ('000000000001'),('000000000002');
+explain select * from t1 where id=000000000001;
table type possible_keys key key_len ref rows Extra
-t1 index PRIMARY PRIMARY 12 NULL 2 where used; Using index
+t1 index PRIMARY PRIMARY 12 NULL 2 Using where; Using index
+select * from t1 where id=000000000001;
id
000000000001
+delete from t1 where id=000000000002;
+select * from t1;
id
000000000001
+drop table t1;
diff --git a/mysql-test/r/constraints.result b/mysql-test/r/constraints.result
new file mode 100644
index 00000000000..3b41e291e0f
--- /dev/null
+++ b/mysql-test/r/constraints.result
@@ -0,0 +1,16 @@
+drop table if exists t1;
+create table t1 (a int check (a>0));
+insert into t1 values (1);
+insert into t1 values (0);
+drop table t1;
+create table t1 (a int ,b int, check a>b);
+insert into t1 values (1,0);
+insert into t1 values (0,1);
+drop table t1;
+create table t1 (a int ,b int, constraint abc check (a>b));
+insert into t1 values (1,0);
+insert into t1 values (0,1);
+drop table t1;
+create table t1 (a int null);
+insert into t1 values (1),(NULL);
+drop table t1;
diff --git a/mysql-test/r/convert.result b/mysql-test/r/convert.result
new file mode 100644
index 00000000000..f8dad8c69ba
--- /dev/null
+++ b/mysql-test/r/convert.result
@@ -0,0 +1,17 @@
+select @@convert_character_set;
+@@convert_character_set
+
+select @@global.convert_character_set;
+@@global.convert_character_set
+
+show variables like "%convert_character_set%";
+Variable_name Value
+convert_character_set
+SET CHARACTER SET cp1251_koi8;
+select @@convert_character_set;
+@@convert_character_set
+cp1251_koi8
+SET CHARACTER SET DEFAULT;
+select @@convert_character_set;
+@@convert_character_set
+
diff --git a/mysql-test/r/count_distinct.result b/mysql-test/r/count_distinct.result
index 97d7b57f249..16460580d6c 100644
--- a/mysql-test/r/count_distinct.result
+++ b/mysql-test/r/count_distinct.result
@@ -1,11 +1,55 @@
+drop table if exists t1,t2,t3;
+create table t1 (libname varchar(21) not null, city text, primary key (libname));
+create table t2 (isbn varchar(21) not null, author text, title text, primary key (isbn));
+create table t3 (isbn varchar(21) not null, libname varchar(21) not null, quantity int ,primary key (isbn,libname));
+insert into t2 values ('001','Daffy','A duck''s life');
+insert into t2 values ('002','Bugs','A rabbit\'s life');
+insert into t2 values ('003','Cowboy','Life on the range');
+insert into t2 values ('000','Anonymous','Wanna buy this book?');
+insert into t2 values ('004','Best Seller','One Heckuva book');
+insert into t2 values ('005','EveryoneBuys','This very book');
+insert into t2 values ('006','San Fran','It is a san fran lifestyle');
+insert into t2 values ('007','BerkAuthor','Cool.Berkley.the.book');
+insert into t3 values('000','New York Public Libra','1');
+insert into t3 values('001','New York Public Libra','2');
+insert into t3 values('002','New York Public Libra','3');
+insert into t3 values('003','New York Public Libra','4');
+insert into t3 values('004','New York Public Libra','5');
+insert into t3 values('005','New York Public Libra','6');
+insert into t3 values('006','San Fransisco Public','5');
+insert into t3 values('007','Berkeley Public1','3');
+insert into t3 values('007','Berkeley Public2','3');
+insert into t3 values('001','NYC Lib','8');
+insert into t1 values ('New York Public Libra','New York');
+insert into t1 values ('San Fransisco Public','San Fran');
+insert into t1 values ('Berkeley Public1','Berkeley');
+insert into t1 values ('Berkeley Public2','Berkeley');
+insert into t1 values ('NYC Lib','New York');
+select t2.isbn,city,t1.libname,count(t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city,t1.libname;
isbn city libname a
007 Berkeley Berkeley Public1 1
007 Berkeley Berkeley Public2 1
000 New York New York Public Libra 6
001 New York NYC Lib 1
006 San Fran San Fransisco Public 1
+select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct t1.libname) > 1;
isbn city libname a
007 Berkeley Berkeley Public1 2
000 New York New York Public Libra 2
+select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct concat(t1.libname,'a')) > 1;
+isbn city libname a
+007 Berkeley Berkeley Public1 2
+000 New York New York Public Libra 2
+drop table t1, t2, t3;
+create table t1 (f1 int);
+insert into t1 values (1);
+create table t2 (f1 int,f2 int);
+select t1.f1,count(distinct t2.f2),count(distinct 1,NULL) from t1 left join t2 on t1.f1=t2.f1 group by t1.f1;
f1 count(distinct t2.f2) count(distinct 1,NULL)
1 0 0
+drop table t1,t2;
+create table t1 (f int);
+select count(distinct f) from t1;
+count(distinct f)
+0
+drop table t1;
diff --git a/mysql-test/r/count_distinct2.result b/mysql-test/r/count_distinct2.result
new file mode 100644
index 00000000000..131e3b325ec
--- /dev/null
+++ b/mysql-test/r/count_distinct2.result
@@ -0,0 +1,129 @@
+drop table if exists t1;
+create table t1(n1 int, n2 int, s char(20), vs varchar(20), t text);
+insert into t1 values (1,11, 'one','eleven', 'eleven'),
+(1,11, 'one','eleven', 'eleven'),
+(2,11, 'two','eleven', 'eleven'),
+(2,12, 'two','twevle', 'twelve'),
+(2,13, 'two','thirteen', 'foo'),
+(2,13, 'two','thirteen', 'foo'),
+(2,13, 'two','thirteen', 'bar'),
+(NULL,13, 'two','thirteen', 'bar'),
+(2,NULL, 'two','thirteen', 'bar'),
+(2,13, NULL,'thirteen', 'bar'),
+(2,13, 'two',NULL, 'bar'),
+(2,13, 'two','thirteen', NULL);
+select distinct n1 from t1;
+n1
+1
+2
+NULL
+select count(distinct n1) from t1;
+count(distinct n1)
+2
+select distinct n2 from t1;
+n2
+11
+12
+13
+NULL
+select count(distinct n2) from t1;
+count(distinct n2)
+3
+select distinct s from t1;
+s
+one
+two
+NULL
+select count(distinct s) from t1;
+count(distinct s)
+2
+select distinct vs from t1;
+vs
+eleven
+twevle
+thirteen
+NULL
+select count(distinct vs) from t1;
+count(distinct vs)
+3
+select distinct t from t1;
+t
+eleven
+twelve
+foo
+bar
+NULL
+select count(distinct t) from t1;
+count(distinct t)
+4
+select distinct n1,n2 from t1;
+n1 n2
+1 11
+2 11
+2 12
+2 13
+NULL 13
+2 NULL
+select count(distinct n1,n2) from t1;
+count(distinct n1,n2)
+4
+select distinct n1,s from t1;
+n1 s
+1 one
+2 two
+NULL two
+2 NULL
+select count(distinct n1,s) from t1;
+count(distinct n1,s)
+2
+select distinct s,n1,vs from t1;
+s n1 vs
+one 1 eleven
+two 2 eleven
+two 2 twevle
+two 2 thirteen
+two NULL thirteen
+NULL 2 thirteen
+two 2 NULL
+select count(distinct s,n1,vs) from t1;
+count(distinct s,n1,vs)
+4
+select distinct s,t from t1;
+s t
+one eleven
+two eleven
+two twelve
+two foo
+two bar
+NULL bar
+two NULL
+select count(distinct s,t) from t1;
+count(distinct s,t)
+5
+select count(distinct n1), count(distinct n2) from t1;
+count(distinct n1) count(distinct n2)
+2 3
+select count(distinct n2), n1 from t1 group by n1;
+count(distinct n2) n1
+1 NULL
+1 1
+3 2
+drop table t1;
+create table t1 (n int default NULL);
+flush status;
+select count(distinct n) from t1;
+count(distinct n)
+5000
+show status like 'Created_tmp_disk_tables';
+Variable_name Value
+Created_tmp_disk_tables 1
+drop table t1;
+create table t1 (s text);
+flush status;
+select count(distinct s) from t1;
+count(distinct s)
+5000
+show status like 'Created_tmp_disk_tables';
+Variable_name Value
+Created_tmp_disk_tables 1
+drop table t1;
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 88d597bd3d7..627913939fb 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1,17 +1,104 @@
+drop table if exists t1,t2;
+create table t1 (b char(0));
+insert into t1 values (""),(null);
+select * from t1;
b
NULL
+drop table if exists t1;
+create table t1 (b char(0) not null);
+create table if not exists t1 (b char(0) not null);
+insert into t1 values (""),(null);
+select * from t1;
b
+drop table if exists t1;
+create table t2 type=heap select * from t1;
+Table 'test.t1' doesn't exist
+create table t2 select auto+1 from t1;
+Table 'test.t1' doesn't exist
+drop table if exists t1,t2;
+create table t1 (b char(0) not null, index(b));
+The used table handler can't index column 'b'
+create table t1 (a int not null auto_increment,primary key (a)) type=heap;
+The used table type doesn't support AUTO_INCREMENT columns
+create table t1 (a int not null,b text) type=heap;
+The used table type doesn't support BLOB/TEXT columns
+drop table if exists t1;
+create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap;
+The used table type doesn't support AUTO_INCREMENT columns
+create table not_existing_database.test (a int);
+Got one of the listed errors
+create table `a/a` (a int);
+Incorrect table name 'a/a'
+create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int);
+Incorrect table name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
+Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
+create table 1ea10 (1a20 int,1e int);
+insert into 1ea10 values(1,1);
+select 1ea10.1a20,1e+ 1e+10 from 1ea10;
1a20 1e+ 1e+10
1 10000000001
+drop table 1ea10;
+create table t1 (t1.index int);
+drop table t1;
+drop database if exists test_$1;
+create database test_$1;
+create table test_$1.$test1 (a$1 int, $b int, c$ int);
+insert into test_$1.$test1 values (1,2,3);
+select a$1, $b, c$ from test_$1.$test1;
a$1 $b c$
1 2 3
+create table test_$1.test2$ (a int);
+drop table test_$1.test2$;
+drop database test_$1;
+create table `` (a int);
+Incorrect table name ''
+drop table if exists ``;
+Incorrect table name ''
+create table t1 (`` int);
+Incorrect column name ''
+drop table if exists t1;
+create table t1 (a int auto_increment not null primary key, B CHAR(20));
+insert into t1 (b) values ("hello"),("my"),("world");
+create table t2 (key (b)) select * from t1;
+explain select * from t2 where b="world";
table type possible_keys key key_len ref rows Extra
-t2 ref B B 21 const 1 where used
+t2 ref B B 21 const 1 Using where
+select * from t2 where b="world";
a B
3 world
+drop table t1,t2;
+create table t1(x varchar(50) );
+create table t2 select x from t1 where 1=2;
+describe t1;
+Field Type Null Key Default Extra
+x varchar(50) YES NULL
+describe t2;
+Field Type Null Key Default Extra
+x varchar(50) YES NULL
+drop table t2;
+create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f;
+describe t2;
+Field Type Null Key Default Extra
+a datetime 0000-00-00 00:00:00
+b time 00:00:00
+c date 0000-00-00
+d bigint(17) 0
+e double(18,1) 0.0
+f bigint(17) 0
+drop table t2;
+create table t2 select CAST("2001-12-29" AS DATE) as d, CAST("20:45:11" AS TIME) as t, CAST("2001-12-29 20:45:11" AS DATETIME) as dt;
+describe t2;
+Field Type Null Key Default Extra
+d date 0000-00-00
+t time 00:00:00
+dt datetime 0000-00-00 00:00:00
+drop table t1,t2;
+create table t1 (a int not null, b int, primary key(a), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b));
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0',
@@ -49,3 +136,83 @@ t1 CREATE TABLE `t1` (
KEY `b_30` (`b`),
KEY `b_31` (`b`)
) TYPE=MyISAM
+drop table t1;
+create table t1 select if(1,'1','0'), month("2002-08-02");
+drop table t1;
+create table t1 select if('2002'='2002','Y','N');
+select * from t1;
+if('2002'='2002','Y','N')
+Y
+drop table if exists t1;
+SET SESSION table_type="heap";
+SELECT @@table_type;
+@@table_type
+HEAP
+CREATE TABLE t1 (a int not null);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0'
+) TYPE=HEAP
+drop table t1;
+SET SESSION table_type="gemini";
+SELECT @@table_type;
+@@table_type
+GEMINI
+CREATE TABLE t1 (a int not null);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0'
+) TYPE=MyISAM
+SET SESSION table_type=default;
+drop table t1;
+create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2));
+insert into t1 values ("a", 1), ("b", 2);
+insert into t1 values ("c", NULL);
+Column 'k2' cannot be null
+insert into t1 values (NULL, 3);
+Column 'k1' cannot be null
+insert into t1 values (NULL, NULL);
+Column 'k1' cannot be null
+drop table t1;
+create table t1 select x'4132';
+drop table t1;
+create table t1 select 1,2,3;
+create table if not exists t1 select 1,2;
+create table if not exists t1 select 1,2,3,4;
+Column count doesn't match value count at row 1
+create table if not exists t1 select 1;
+select * from t1;
+1 2 3
+1 2 3
+0 1 2
+0 0 1
+drop table t1;
+create table t1 select 1,2,3;
+create table if not exists t1 select 1,2;
+create table if not exists t1 select 1,2,3,4;
+Column count doesn't match value count at row 1
+create table if not exists t1 select 1;
+select * from t1;
+1 2 3
+1 2 3
+0 1 2
+0 0 1
+drop table t1;
+create table t1 (a int not null, b int, primary key (a));
+insert into t1 values (1,1);
+create table if not exists t1 select 2;
+select * from t1;
+a b
+1 1
+0 2
+create table if not exists t1 select 3 as 'a',4 as 'b';
+create table if not exists t1 select 3 as 'a',3 as 'b';
+Duplicate entry '3' for key 1
+select * from t1;
+a b
+1 1
+0 2
+3 4
+drop table t1;
diff --git a/mysql-test/r/ctype_cp1251.result b/mysql-test/r/ctype_cp1251.result
new file mode 100644
index 00000000000..a1f860e1f83
--- /dev/null
+++ b/mysql-test/r/ctype_cp1251.result
@@ -0,0 +1,24 @@
+drop table if exists t1;
+create table t1 (a varchar(10) not null);
+insert into t1 values ("a"),("ab"),("abc");
+select * from t1;
+a
+a
+ab
+abc
+select a, left(a,1) as b from t1;
+a b
+a a
+ab a
+abc a
+select a, left(a,1) as b from t1 group by a;
+a b
+a a
+ab a
+abc a
+SELECT DISTINCT RIGHT(a,1) from t1;
+RIGHT(a,1)
+a
+b
+c
+drop table t1;
diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result
new file mode 100644
index 00000000000..28394d9533a
--- /dev/null
+++ b/mysql-test/r/ctype_latin1_de.result
@@ -0,0 +1,269 @@
+drop table if exists t1;
+create table t1 (a char (20) not null, b int not null auto_increment, index (a,b));
+insert into t1 (a) values ('ä'),('ac'),('ae'),('ad'),('Äc'),('aeb');
+insert into t1 (a) values ('üc'),('uc'),('ue'),('ud'),('Ü'),('ueb'),('uf');
+insert into t1 (a) values ('ö'),('oc'),('Öa'),('oe'),('od'),('Öc'),('oeb');
+insert into t1 (a) values ('s'),('ss'),('ß'),('ßb'),('ssa'),('ssc'),('ßa');
+insert into t1 (a) values ('eä'),('uü'),('öo'),('ää'),('ääa'),('aeae');
+insert into t1 (a) values ('q'),('a'),('u'),('o'),('é'),('É'),('a');
+select a,b from t1 order by a,b;
+a b
+a 1
+a 2
+ac 1
+ad 1
+ä 1
+ae 2
+ää 1
+aeae 2
+ääa 1
+aeb 1
+Äc 1
+é 1
+É 2
+eä 1
+o 1
+oc 1
+od 1
+ö 1
+oe 2
+Öa 1
+oeb 1
+Öc 1
+öo 1
+q 1
+s 1
+ss 1
+ß 2
+ssa 1
+ßa 2
+ßb 1
+ssc 1
+u 1
+uc 1
+ud 1
+ue 1
+Ü 2
+ueb 1
+üc 1
+uf 1
+uü 1
+select a,b from t1 order by upper(a),b;
+a b
+a 1
+a 2
+ac 1
+ad 1
+ä 1
+ae 2
+ää 1
+aeae 2
+ääa 1
+aeb 1
+Äc 1
+é 1
+É 2
+eä 1
+o 1
+oc 1
+od 1
+ö 1
+oe 2
+Öa 1
+oeb 1
+Öc 1
+öo 1
+q 1
+s 1
+ss 1
+ß 2
+ssa 1
+ßa 2
+ßb 1
+ssc 1
+u 1
+uc 1
+ud 1
+ue 1
+Ü 2
+ueb 1
+üc 1
+uf 1
+uü 1
+select a from t1 order by a desc;
+a
+uü
+uf
+üc
+ueb
+ue
+ud
+uc
+u
+ssc
+ßb
+ßa
+ssa
+ss
+s
+q
+öo
+Öc
+oeb
+Öa
+oe
+od
+oc
+o
+eä
+Äc
+aeb
+ääa
+aeae
+ää
+ae
+ad
+ac
+a
+a
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+select * from t1 where a like "ö%";
+a b
+ö 1
+Öa 1
+Öc 1
+öo 1
+select * from t1 where a like binary "%É%";
+a b
+É 2
+select * from t1 where a like "%Á%";
+a b
+a 1
+a 2
+ac 1
+ad 1
+ae 2
+aeae 2
+ääa 1
+aeb 1
+Öa 1
+ssa 1
+ßa 2
+select * from t1 where a like "%U%";
+a b
+u 1
+uc 1
+ud 1
+ue 1
+ueb 1
+uf 1
+uü 1
+select * from t1 where a like "%ss%";
+a b
+ss 1
+ssa 1
+ssc 1
+drop table t1;
+select strcmp('ä','ae'),strcmp('ae','ä'),strcmp('aeq','äq'),strcmp('äq','aeq');
+strcmp('ä','ae') strcmp('ae','ä') strcmp('aeq','äq') strcmp('äq','aeq')
+0 0 0 0
+select strcmp('ss','ß'),strcmp('ß','ss'),strcmp('ßs','sss'),strcmp('ßq','ssq');
+strcmp('ss','ß') strcmp('ß','ss') strcmp('ßs','sss') strcmp('ßq','ssq')
+0 0 0 0
+select strcmp('ä','af'),strcmp('a','ä'),strcmp('ää','aeq'),strcmp('ää','aeaeq');
+strcmp('ä','af') strcmp('a','ä') strcmp('ää','aeq') strcmp('ää','aeaeq')
+-1 -1 -1 -1
+select strcmp('ss','ßa'),strcmp('ß','ssa'),strcmp('sßa','sssb'),strcmp('s','ß');
+strcmp('ss','ßa') strcmp('ß','ssa') strcmp('sßa','sssb') strcmp('s','ß')
+-1 -1 -1 -1
+select strcmp('ö','oö'),strcmp('Ü','uü'),strcmp('ö','oeb');
+strcmp('ö','oö') strcmp('Ü','uü') strcmp('ö','oeb')
+-1 -1 -1
+select strcmp('af','ä'),strcmp('ä','a'),strcmp('aeq','ää'),strcmp('aeaeq','ää');
+strcmp('af','ä') strcmp('ä','a') strcmp('aeq','ää') strcmp('aeaeq','ää')
+1 1 1 1
+select strcmp('ßa','ss'),strcmp('ssa','ß'),strcmp('sssb','sßa'),strcmp('ß','s');
+strcmp('ßa','ss') strcmp('ssa','ß') strcmp('sssb','sßa') strcmp('ß','s')
+1 1 1 1
+select strcmp('u','öa'),strcmp('u','ö');
+strcmp('u','öa') strcmp('u','ö')
+1 1
+select strcmp('sä', 'ßa'), strcmp('aä', 'äx');
+strcmp('sä', 'ßa') strcmp('aä', 'äx')
+-1 -1
+create table t1 (a varchar(10), key(a), fulltext (a));
+insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
+select * from t1 where a like "abc%";
+a
+abc
+abcd
+select * from t1 where a like "test%";
+a
+test
+select * from t1 where a like "te_t";
+a
+test
+select * from t1 where match a against ("te*" in boolean mode)+0;
+a
+test
+drop table t1;
+create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word));
+insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae');
+update t1 set word2=word;
+select word, word=0xdf as t from t1 having t > 0;
+word t
+ß 1
+select word, word=cast(0xdf AS CHAR) as t from t1 having t > 0;
+word t
+ss 1
+ß 1
+select * from t1 where word=0xDF;
+word word2
+ß ß
+select * from t1 where word=CAST(0xDF as CHAR);
+word word2
+ss ss
+ß ß
+select * from t1 where word2=0xDF;
+word word2
+ß ß
+select * from t1 where word2=CAST(0xDF as CHAR);
+word word2
+ss ss
+ß ß
+select * from t1 where word='ae';
+word word2
+ä ä
+ae ae
+select * from t1 where word= 0xe4 or word=CAST(0xe4 as CHAR);
+word word2
+ä ä
+ae ae
+select * from t1 where word between 0xDF and 0xDF;
+word word2
+ß ß
+select * from t1 where word between CAST(0xDF AS CHAR) and CAST(0xDF AS CHAR);
+word word2
+ss ss
+ß ß
+select * from t1 where word like 'ae';
+word word2
+ae ae
+select * from t1 where word like 'AE';
+word word2
+ae ae
+select * from t1 where word like 0xDF;
+word word2
+ß ß
+select * from t1 where word like CAST(0xDF as CHAR);
+word word2
+ß ß
+drop table t1;
diff --git a/mysql-test/r/ctype_tis620.result b/mysql-test/r/ctype_tis620.result
new file mode 100644
index 00000000000..811609d4ba9
--- /dev/null
+++ b/mysql-test/r/ctype_tis620.result
@@ -0,0 +1,18 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+recid int(11) NOT NULL auto_increment,
+dyninfo text,
+PRIMARY KEY (recid)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,'color=\"STB,NPG\"\r\nengine=\"J30A13\"\r\nframe=\"MRHCG1640YP4\"\r\ngrade=\"V6\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CG164YEN\"\r\ntype=\"VT6\"\r\n');
+INSERT INTO t1 VALUES (2,'color=\"HTM,NPG,DEG,RGS\"\r\nengine=\"F23A5YP1\"\r\nframe=\"MRHCF8640YP3\"\r\ngrade=\"EXi AT\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CF864YE\"\r\ntype=\"EXA\"\r\n');
+SELECT DISTINCT
+(IF( LOCATE( 'year=\"', dyninfo ) = 1,
+SUBSTRING( dyninfo, 6+1, LOCATE('\"\r',dyninfo) - 6 -1),
+IF( LOCATE( '\nyear=\"', dyninfo ),
+SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) + 7,
+LOCATE( '\"\r', SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) +7 )) - 1), '' ))) AS year
+FROM t1
+HAVING year != '' ORDER BY year;
+year
+DROP TABLE t1;
diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result
new file mode 100644
index 00000000000..223a18f19e9
--- /dev/null
+++ b/mysql-test/r/ctype_ujis.result
@@ -0,0 +1,8 @@
+drop table if exists t1;
+create table t1 (c text);
+insert into t1 values (0xa4a2),(0xa4a3);
+select hex(left(c,1)) from t1 group by c;
+hex(left(c,1))
+A4A2
+A4A3
+drop table t1;
diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result
index d1914341a8d..9e375203e49 100644
--- a/mysql-test/r/delayed.result
+++ b/mysql-test/r/delayed.result
@@ -1,10 +1,31 @@
+drop table if exists t1;
+create table t1 (a char(10), tmsp timestamp);
+insert into t1 set a = 1;
+insert delayed into t1 set a = 2;
+insert into t1 set a = 3, tmsp=NULL;
+insert delayed into t1 set a = 4;
+insert delayed into t1 set a = 5, tmsp = 19711006010203;
+insert delayed into t1 (a, tmsp) values (6, 19711006010203);
+insert delayed into t1 (a, tmsp) values (7, NULL);
+insert into t1 set a = 8,tmsp=19711006010203;
+select * from t1 where tmsp=0;
a tmsp
+select * from t1 where tmsp=19711006010203;
a tmsp
5 19711006010203
6 19711006010203
8 19711006010203
+drop table t1;
+create table t1 (a int not null auto_increment primary key, b char(10));
+insert delayed into t1 values (1,"b");
+insert delayed into t1 values (null,"c");
+insert delayed into t1 values (3,"d"),(null,"e");
+insert delayed into t1 values (3,"this will give an","error");
+Column count doesn't match value count at row 1
+select * from t1;
a b
1 b
2 c
3 d
4 e
+drop table t1;
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index 169232b72d8..abc8245e69f 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -1,4 +1,52 @@
+drop table if exists t1;
+CREATE TABLE t1 (a tinyint(3), b tinyint(5));
+INSERT INTO t1 VALUES (1,1);
+INSERT LOW_PRIORITY INTO t1 VALUES (1,2);
+INSERT INTO t1 VALUES (1,3);
+DELETE from t1 where a=1 limit 1;
+DELETE LOW_PRIORITY from t1 where a=1;
+INSERT INTO t1 VALUES (1,1);
+DELETE from t1;
+LOCK TABLE t1 write;
+INSERT INTO t1 VALUES (1,2);
+DELETE from t1;
+UNLOCK TABLES;
+INSERT INTO t1 VALUES (1,2);
+SET AUTOCOMMIT=0;
+DELETE from t1;
+SET AUTOCOMMIT=1;
+drop table t1;
+create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
+insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23);
+delete from t1 where a=26;
+drop table t1;
+create table t1 (a bigint not null, primary key (a,a,a,a,a,a,a,a,a,a));
+insert into t1 values (2),(4),(6),(8),(10),(12),(14),(16),(18),(20),(22),(24),(26),(23),(27);
+delete from t1 where a=27;
+drop table t1;
+CREATE TABLE t1 (
+bool char(0) default NULL,
+not_null varchar(20) binary NOT NULL default '',
+misc integer not null,
+PRIMARY KEY (not_null)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (NULL,'a',4), (NULL,'b',5), (NULL,'c',6), (NULL,'d',7);
+select * from t1 where misc > 5 and bool is null;
bool not_null misc
NULL c 6
NULL d 7
+delete from t1 where misc > 5 and bool is null;
+select * from t1 where misc > 5 and bool is null;
bool not_null misc
+select count(*) from t1;
+count(*)
+2
+delete from t1 where 1 > 2;
+select count(*) from t1;
+count(*)
+2
+delete from t1 where 3 > 2;
+select count(*) from t1;
+count(*)
+0
+drop table t1;
diff --git a/mysql-test/r/dirty-close.result b/mysql-test/r/dirty-close.result
deleted file mode 100644
index f85b057eefa..00000000000
--- a/mysql-test/r/dirty-close.result
+++ /dev/null
@@ -1,4 +0,0 @@
-n
-1
-2
-3
diff --git a/mysql-test/r/dirty_close.result b/mysql-test/r/dirty_close.result
new file mode 100644
index 00000000000..c4fc19a35f8
--- /dev/null
+++ b/mysql-test/r/dirty_close.result
@@ -0,0 +1,9 @@
+drop table if exists t1;
+create table t1 (n int);
+insert into t1 values (1),(2),(3);
+select * from t1;
+n
+1
+2
+3
+drop table t1;
diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result
index 0d2f6c6c59c..a0343f13394 100644
--- a/mysql-test/r/distinct.result
+++ b/mysql-test/r/distinct.result
@@ -1,3 +1,21 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (id int,facility char(20));
+CREATE TABLE t2 (facility char(20));
+INSERT INTO t1 VALUES (NULL,NULL);
+INSERT INTO t1 VALUES (-1,'');
+INSERT INTO t1 VALUES (0,'');
+INSERT INTO t1 VALUES (1,'/L');
+INSERT INTO t1 VALUES (2,'A01');
+INSERT INTO t1 VALUES (3,'ANC');
+INSERT INTO t1 VALUES (4,'F01');
+INSERT INTO t1 VALUES (5,'FBX');
+INSERT INTO t1 VALUES (6,'MT');
+INSERT INTO t1 VALUES (7,'P');
+INSERT INTO t1 VALUES (8,'RV');
+INSERT INTO t1 VALUES (9,'SRV');
+INSERT INTO t1 VALUES (10,'VMT');
+INSERT INTO t2 SELECT DISTINCT FACILITY FROM t1;
+select id from t1 group by id;
id
NULL
-1
@@ -12,6 +30,7 @@ NULL
8
9
10
+select * from t1 order by id;
id facility
NULL NULL
-1
@@ -26,6 +45,7 @@ NULL NULL
8 RV
9 SRV
10 VMT
+select id-5,facility from t1 order by "id-5";
id-5 facility
NULL NULL
-6
@@ -40,6 +60,7 @@ NULL NULL
3 RV
4 SRV
5 VMT
+select id,concat(facility) from t1 group by id ;
id concat(facility)
NULL NULL
-1
@@ -54,6 +75,7 @@ NULL NULL
8 RV
9 SRV
10 VMT
+select id+0 as a,max(id),concat(facility) as b from t1 group by a order by b desc,a;
a max(id) b
10 10 VMT
9 9 SRV
@@ -68,10 +90,12 @@ a max(id) b
-1 -1
0 0
NULL NULL NULL
+select id >= 0 and id <= 5 as grp,count(*) from t1 group by grp;
grp count(*)
NULL 1
0 6
1 6
+SELECT DISTINCT FACILITY FROM t1;
FACILITY
NULL
@@ -85,6 +109,7 @@ P
RV
SRV
VMT
+SELECT FACILITY FROM t2;
FACILITY
NULL
@@ -98,79 +123,308 @@ P
RV
SRV
VMT
+SELECT count(*) from t1,t2 where t1.facility=t2.facility;
count(*)
12
+select count(facility) from t1;
count(facility)
12
+select count(*) from t1;
count(*)
13
+select count(*) from t1 where facility IS NULL;
count(*)
1
+select count(*) from t1 where facility = NULL;
count(*)
0
+select count(*) from t1 where facility IS NOT NULL;
count(*)
12
+select count(*) from t1 where id IS NULL;
count(*)
1
+select count(*) from t1 where id IS NOT NULL;
count(*)
12
+drop table t1,t2;
+CREATE TABLE t1 (UserId int(11) DEFAULT '0' NOT NULL);
+INSERT INTO t1 VALUES (20);
+INSERT INTO t1 VALUES (27);
+SELECT UserId FROM t1 WHERE Userid=22;
UserId
+SELECT UserId FROM t1 WHERE UserId=22 group by Userid;
UserId
+SELECT DISTINCT UserId FROM t1 WHERE UserId=22 group by Userid;
UserId
+SELECT DISTINCT UserId FROM t1 WHERE UserId=22;
UserId
+drop table t1;
+CREATE TABLE t1 (a int(10) unsigned not null primary key,b int(10) unsigned);
+INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1);
+CREATE TABLE t2 (a int(10) unsigned not null, key (A));
+INSERT INTO t2 VALUES (1),(2);
+CREATE TABLE t3 (a int(10) unsigned, key(A), b text);
+INSERT INTO t3 VALUES (1,'1'),(2,'2');
+SELECT DISTINCT t3.b FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
b
1
+INSERT INTO t2 values (1),(2),(3);
+INSERT INTO t3 VALUES (1,'1'),(2,'2'),(1,'1'),(2,'2');
+explain SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
table type possible_keys key key_len ref rows Extra
t3 index a a 5 NULL 6 Using index; Using temporary
t2 index a a 4 NULL 5 Using index; Distinct
-t1 eq_ref PRIMARY PRIMARY 4 t2.a 1 where used; Distinct
+t1 eq_ref PRIMARY PRIMARY 4 t2.a 1 Using where; Distinct
+SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a;
a
1
+create temporary table t4 select * from t3;
+insert into t3 select * from t4;
+insert into t4 select * from t3;
+insert into t3 select * from t4;
+insert into t4 select * from t3;
+insert into t3 select * from t4;
+insert into t4 select * from t3;
+insert into t3 select * from t4;
+explain select distinct t1.a from t1,t3 where t1.a=t3.a;
table type possible_keys key key_len ref rows Extra
-t1 index PRIMARY PRIMARY 4 NULL 2 Using index; Using temporary
-t3 ref a a 5 t1.a 10 where used; Using index; Distinct
+t1 index PRIMARY PRIMARY 4 NULL 4 Using index; Using temporary
+t3 ref a a 5 t1.a 10 Using where; Using index; Distinct
+select distinct t1.a from t1,t3 where t1.a=t3.a;
a
1
2
+select distinct 1 from t1,t3 where t1.a=t3.a;
1
1
+explain SELECT distinct t1.a from t1;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL PRIMARY 4 NULL 4 Using index
+explain SELECT distinct t1.a from t1 order by a desc;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL PRIMARY 4 NULL 4 Using index
+explain SELECT t1.a from t1 group by a order by a desc;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL PRIMARY 4 NULL 4 Using index
+explain SELECT distinct t1.a from t1 order by a desc limit 1;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL PRIMARY 4 NULL 4 Using index
+explain SELECT distinct a from t3 order by a desc limit 2;
+table type possible_keys key key_len ref rows Extra
+t3 index NULL a 5 NULL 204 Using index
+explain SELECT distinct a,b from t3 order by a+1;
+table type possible_keys key key_len ref rows Extra
+t3 ALL NULL NULL NULL NULL 204 Using temporary; Using filesort
+explain SELECT distinct a,b from t3 order by a limit 10;
+table type possible_keys key key_len ref rows Extra
+t3 index NULL a 5 NULL 204 Using temporary
+explain SELECT a,b from t3 group by a,b order by a+1;
+table type possible_keys key key_len ref rows Extra
+t3 ALL NULL NULL NULL NULL 204 Using temporary; Using filesort
+drop table t1,t2,t3,t4;
+CREATE TABLE t1 (name varchar(255));
+INSERT INTO t1 VALUES ('aa'),('ab'),('ac'),('ad'),('ae');
+SELECT DISTINCT * FROM t1 LIMIT 2;
name
aa
ab
+SELECT DISTINCT name FROM t1 LIMIT 2;
name
aa
ab
+SELECT DISTINCT 1 FROM t1 LIMIT 2;
1
1
+drop table t1;
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+NAME varchar(75) DEFAULT '' NOT NULL,
+LINK_ID int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (ID),
+KEY NAME (NAME),
+KEY LINK_ID (LINK_ID)
+);
+INSERT INTO t1 (ID, NAME, LINK_ID) VALUES (1,'Mike',0),(2,'Jack',0),(3,'Bill',0);
+CREATE TABLE t2 (
+ID int(11) NOT NULL auto_increment,
+NAME varchar(150) DEFAULT '' NOT NULL,
+PRIMARY KEY (ID),
+KEY NAME (NAME)
+);
+SELECT DISTINCT
+t2.id AS key_link_id,
+t2.name AS link
+FROM t1
+LEFT JOIN t2 ON t1.link_id=t2.id
+GROUP BY t1.id
+ORDER BY link;
key_link_id link
NULL NULL
+drop table t1,t2;
+create table t1 (
+id int not null,
+name tinytext not null,
+unique (id)
+);
+create table t2 (
+id int not null,
+idx int not null,
+unique (id, idx)
+);
+create table t3 (
+id int not null,
+idx int not null,
+unique (id, idx)
+);
+insert into t1 values (1,'yes'), (2,'no');
+insert into t2 values (1,1);
+insert into t3 values (1,1);
+EXPLAIN
+SELECT DISTINCT
+t1.id
+from
+t1
+straight_join
+t2
+straight_join
+t3
+straight_join
+t1 as j_lj_t2 left join t2 as t2_lj
+on j_lj_t2.id=t2_lj.id
+straight_join
+t1 as j_lj_t3 left join t3 as t3_lj
+on j_lj_t3.id=t3_lj.id
+WHERE
+((t1.id=j_lj_t2.id AND t2_lj.id IS NULL) OR (t1.id=t2.id AND t2.idx=2))
+AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
table type possible_keys key key_len ref rows Extra
t1 index id id 4 NULL 2 Using index; Using temporary
t2 index id id 8 NULL 1 Using index; Distinct
t3 index id id 8 NULL 1 Using index; Distinct
-j_lj_t2 index id id 4 NULL 2 where used; Using index; Distinct
-t2_lj index id id 8 NULL 1 where used; Using index; Distinct
-j_lj_t3 index id id 4 NULL 2 where used; Using index; Distinct
-t3_lj index id id 8 NULL 1 where used; Using index; Distinct
+j_lj_t2 index id id 4 NULL 2 Using where; Using index; Distinct
+t2_lj ref id id 4 j_lj_t2.id 1 Using where; Using index; Distinct
+j_lj_t3 index id id 4 NULL 2 Using where; Using index; Distinct
+t3_lj ref id id 4 j_lj_t3.id 1 Using where; Using index; Distinct
+SELECT DISTINCT
+t1.id
+from
+t1
+straight_join
+t2
+straight_join
+t3
+straight_join
+t1 as j_lj_t2 left join t2 as t2_lj
+on j_lj_t2.id=t2_lj.id
+straight_join
+t1 as j_lj_t3 left join t3 as t3_lj
+on j_lj_t3.id=t3_lj.id
+WHERE
+((t1.id=j_lj_t2.id AND t2_lj.id IS NULL) OR (t1.id=t2.id AND t2.idx=2))
+AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
id
2
+drop table t1,t2,t3;
+drop table if exists t1;
+create table t1 (a int not null, b int not null, t time);
+insert into t1 values (1,1,"00:06:15"),(1,2,"00:06:15"),(1,2,"00:30:15"),(1,3,"00:06:15"),(1,3,"00:30:15");
+select a,sec_to_time(sum(time_to_sec(t))) from t1 group by a,b;
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
1 00:36:30
+select distinct a,sec_to_time(sum(time_to_sec(t))) from t1 group by a,b;
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
+create table t2 (a int not null primary key, b int);
+insert into t2 values (1,1),(2,2),(3,3);
+select t1.a,sec_to_time(sum(time_to_sec(t))) from t1 left join t2 on (t1.b=t2.a) group by t1.a,t2.b;
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
1 00:36:30
+select distinct t1.a,sec_to_time(sum(time_to_sec(t))) from t1 left join t2 on (t1.b=t2.a) group by t1.a,t2.b;
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
+drop table t1,t2;
+create table t1 (a int not null,b char(5), c text);
+insert into t1 (a) values (1),(2),(3),(4),(1),(2),(3),(4);
+select distinct a from t1 group by b,a having a > 2 order by a desc;
a
4
3
+select distinct a,c from t1 group by b,c,a having a > 2 order by a desc;
a c
4 NULL
3 NULL
+drop table t1;
+create table t1 (a char(1), key(a)) type=myisam;
+insert into t1 values('1'),('1');
+select * from t1 where a >= '1';
+a
+1
+1
+select distinct a from t1 order by a desc;
+a
+1
+select distinct a from t1 where a >= '1' order by a desc;
+a
+1
+drop table t1;
+CREATE TABLE t1 (email varchar(50), infoID BIGINT, dateentered DATETIME);
+CREATE TABLE t2 (infoID BIGINT, shipcode varchar(10));
+INSERT INTO t1 (email, infoID, dateentered) VALUES
+('test1@testdomain.com', 1, '2002-07-30 22:56:38'),
+('test1@testdomain.com', 1, '2002-07-27 22:58:16'),
+('test2@testdomain.com', 1, '2002-06-19 15:22:19'),
+('test2@testdomain.com', 2, '2002-06-18 14:23:47'),
+('test3@testdomain.com', 1, '2002-05-19 22:17:32');
+INSERT INTO t2(infoID, shipcode) VALUES
+(1, 'Z001'),
+(2, 'R002');
+SELECT DISTINCTROW email, shipcode FROM t1, t2 WHERE t1.infoID=t2.infoID;
+email shipcode
+test1@testdomain.com Z001
+test2@testdomain.com Z001
+test3@testdomain.com Z001
+test2@testdomain.com R002
+SELECT DISTINCTROW email FROM t1 ORDER BY dateentered DESC;
+email
+test1@testdomain.com
+test2@testdomain.com
+test3@testdomain.com
+SELECT DISTINCTROW email, shipcode FROM t1, t2 WHERE t1.infoID=t2.infoID ORDER BY dateentered DESC;
+email shipcode
+test1@testdomain.com Z001
+test2@testdomain.com Z001
+test2@testdomain.com R002
+test3@testdomain.com Z001
+drop table t1,t2;
+CREATE TABLE t1 (privatemessageid int(10) unsigned NOT NULL auto_increment, folderid smallint(6) NOT NULL default '0', userid int(10) unsigned NOT NULL default '0', touserid int(10) unsigned NOT NULL default '0', fromuserid int(10) unsigned NOT NULL default '0', title varchar(250) NOT NULL default '', message mediumtext NOT NULL, dateline int(10) unsigned NOT NULL default '0', showsignature smallint(6) NOT NULL default '0', iconid smallint(5) unsigned NOT NULL default '0', messageread smallint(6) NOT NULL default '0', readtime int(10) unsigned NOT NULL default '0', receipt smallint(6) unsigned NOT NULL default '0', deleteprompt smallint(6) unsigned NOT NULL default '0', multiplerecipients smallint(6) unsigned NOT NULL default '0', PRIMARY KEY (privatemessageid), KEY userid (userid)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (128,0,33,33,8,':D','',996121863,1,0,2,996122850,2,0,0);
+CREATE TABLE t2 (userid int(10) unsigned NOT NULL auto_increment, usergroupid smallint(5) unsigned NOT NULL default '0', username varchar(50) NOT NULL default '', password varchar(50) NOT NULL default '', email varchar(50) NOT NULL default '', styleid smallint(5) unsigned NOT NULL default '0', parentemail varchar(50) NOT NULL default '', coppauser smallint(6) NOT NULL default '0', homepage varchar(100) NOT NULL default '', icq varchar(20) NOT NULL default '', aim varchar(20) NOT NULL default '', yahoo varchar(20) NOT NULL default '', signature mediumtext NOT NULL, adminemail smallint(6) NOT NULL default '0', showemail smallint(6) NOT NULL default '0', invisible smallint(6) NOT NULL default '0', usertitle varchar(250) NOT NULL default '', customtitle smallint(6) NOT NULL default '0', joindate int(10) unsigned NOT NULL default '0', cookieuser smallint(6) NOT NULL default '0', daysprune smallint(6) NOT NULL default '0', lastvisit int(10) unsigned NOT NULL default '0', lastactivity int(10) unsigned NOT NULL default '0', lastpost int(10) unsigned NOT NULL default '0', posts smallint(5) unsigned NOT NULL default '0', timezoneoffset varchar(4) NOT NULL default '', emailnotification smallint(6) NOT NULL default '0', buddylist mediumtext NOT NULL, ignorelist mediumtext NOT NULL, pmfolders mediumtext NOT NULL, receivepm smallint(6) NOT NULL default '0', emailonpm smallint(6) NOT NULL default '0', pmpopup smallint(6) NOT NULL default '0', avatarid smallint(6) NOT NULL default '0', avatarrevision int(6) unsigned NOT NULL default '0', options smallint(6) NOT NULL default '15', birthday date NOT NULL default '0000-00-00', maxposts smallint(6) NOT NULL default '-1', startofweek smallint(6) NOT NULL default '1', ipaddress varchar(20) NOT NULL default '', referrerid int(10) unsigned NOT NULL default '0', nosessionhash smallint(6) NOT NULL default '0', autorefresh smallint(6) NOT NULL default '-1', messagepopup tinyint(2) NOT NULL default '0', inforum smallint(5) unsigned NOT NULL default '0', ratenum smallint(5) unsigned NOT NULL default '0', ratetotal smallint(5) unsigned NOT NULL default '0', allowrate smallint(5) unsigned NOT NULL default '1', PRIMARY KEY (userid), KEY usergroupid (usergroupid), KEY username (username), KEY inforum (inforum)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (33,6,'Kevin','0','kevin@stileproject.com',1,'',0,'http://www.stileproject.com','','','','',1,1,0,'Administrator',0,996120694,1,-1,1030996168,1031027028,1030599436,36,'-6',0,'','','',1,0,1,0,0,15,'0000-00-00',-1,1,'64.0.0.0',0,1,-1,0,0,4,19,1);
+SELECT DISTINCT t1.*, t2.* FROM t1 LEFT JOIN t2 ON (t2.userid = t1.touserid);
+privatemessageid folderid userid touserid fromuserid title message dateline showsignature iconid messageread readtime receipt deleteprompt multiplerecipients userid usergroupid username password email styleid parentemail coppauser homepage icq aim yahoo signature adminemail showemail invisible usertitle customtitle joindate cookieuser daysprune lastvisit lastactivity lastpost posts timezoneoffset emailnotification buddylist ignorelist pmfolders receivepm emailonpm pmpopup avatarid avatarrevision options birthday maxposts startofweek ipaddress referrerid nosessionhash autorefresh messagepopup inforum ratenum ratetotal allowrate
+128 0 33 33 8 :D 996121863 1 0 2 996122850 2 0 0 33 6 Kevin 0 kevin@stileproject.com 1 0 http://www.stileproject.com 1 1 0 Administrator 0 996120694 1 -1 1030996168 1031027028 1030599436 36 -6 0 1 0 1 0 0 15 0000-00-00 -1 1 64.0.0.0 0 1 -1 0 0 4 19 1
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a int primary key, b int, c int);
+INSERT t1 VALUES (1,2,3);
+CREATE TABLE t2 (a int primary key, b int, c int);
+INSERT t2 VALUES (3,4,5);
+SELECT DISTINCT t1.a, t2.b FROM t1, t2 WHERE t1.a=1 ORDER BY t2.c;
+a b
+1 4
+DROP TABLE IF EXISTS t1,t2;
+CREATE table t1 ( `id` int(11) NOT NULL auto_increment, `name` varchar(50) NOT NULL default '', PRIMARY KEY (`id`)) TYPE=MyISAM AUTO_INCREMENT=3 ;
+INSERT INTO t1 VALUES (1, 'aaaaa');
+INSERT INTO t1 VALUES (3, 'aaaaa');
+INSERT INTO t1 VALUES (2, 'eeeeeee');
+select distinct left(name,1) as name from t1;
+name
+a
+e
+drop table t1;
diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result
index 741fc6bba85..5c732aebbcc 100644
--- a/mysql-test/r/drop.result
+++ b/mysql-test/r/drop.result
@@ -1,11 +1,46 @@
+drop table if exists t1;
+drop table t1;
+Unknown table 't1'
+create table t1(n int);
+insert into t1 values(1);
+create temporary table t1( n int);
+insert into t1 values(2);
+create table t1(n int);
+Table 't1' already exists
+drop table t1;
+select * from t1;
n
1
+drop database if exists mysqltest;
+create database mysqltest;
+drop database if exists mysqltest;
+create database mysqltest;
+create table mysqltest.mysqltest (n int);
+insert into mysqltest.mysqltest values (4);
+select * from mysqltest.mysqltest;
n
4
+drop database if exists mysqltest;
+create database mysqltest;
+drop database mysqltest;
+flush tables with read lock;
+create database mysqltest;
+Got one of the listed errors
+unlock tables;
+create database mysqltest;
+show databases;
Database
-foo
mysql
+mysqltest
test
+flush tables with read lock;
+drop database mysqltest;
+Got one of the listed errors
+unlock tables;
+drop database mysqltest;
+show databases;
Database
mysql
test
+drop database mysqltest;
+Can't drop database 'mysqltest'. Database doesn't exist
diff --git a/mysql-test/r/drop_temp_table.result b/mysql-test/r/drop_temp_table.result
new file mode 100644
index 00000000000..6b18b54335d
--- /dev/null
+++ b/mysql-test/r/drop_temp_table.result
@@ -0,0 +1,18 @@
+reset master;
+create database `drop-temp+table-test`;
+use `drop-temp+table-test`;
+create temporary table `table:name` (a int);
+select get_lock("a",10);
+get_lock("a",10)
+1
+select get_lock("a",10);
+get_lock("a",10)
+1
+show binlog events;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
+master-bin.001 79 Query 1 79 use `test`; create database `drop-temp+table-test`
+master-bin.001 152 Query 1 152 use `drop-temp+table-test`; create temporary table `table:name` (a int)
+master-bin.001 246 Query 1 246 use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE `drop-temp+table-test`.`table:name`
+master-bin.001 365 Query 1 365 use `drop-temp+table-test`; DO RELEASE_LOCK("a")
+drop database `drop-temp+table-test`;
diff --git a/mysql-test/r/empty_table.result b/mysql-test/r/empty_table.result
index 284ed65ee3b..cea787f4abd 100644
--- a/mysql-test/r/empty_table.result
+++ b/mysql-test/r/empty_table.result
@@ -1,4 +1,10 @@
+drop table if exists t1;
+create table t1 (nr int(5) not null auto_increment,b blob,str char(10), primary key (nr));
+select count(*) from t1;
count(*)
0
+select * from t1;
nr b str
+select * from t1 limit 0;
nr b str
+drop table t1;
diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result
new file mode 100644
index 00000000000..5afecc6d600
--- /dev/null
+++ b/mysql-test/r/errors.result
@@ -0,0 +1,25 @@
+drop table if exists t1;
+insert into t1 values(1);
+Table 'test.t1' doesn't exist
+delete from t1;
+Table 'test.t1' doesn't exist
+update t1 set a=1;
+Table 'test.t1' doesn't exist
+create table t1 (a int);
+select count(test.t1.b) from t1;
+Unknown column 'test.t1.b' in 'field list'
+select count(not_existing_database.t1) from t1;
+Unknown table 'not_existing_database' in field list
+select count(not_existing_database.t1.a) from t1;
+Unknown table 'not_existing_database.t1' in field list
+select count(not_existing_database.t1.a) from not_existing_database.t1;
+Got one of the listed errors
+select 1 from t1 order by 2;
+Unknown column '2' in 'order clause'
+select 1 from t1 group by 2;
+Unknown column '2' in 'group statement'
+select 1 from t1 order by t1.b;
+Unknown column 't1.b' in 'order clause'
+select count(*),b from t1;
+Unknown column 'b' in 'field list'
+drop table t1;
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index 558feb10f84..d433078a251 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -1,15 +1,46 @@
+drop table if exists t1;
+create table t1 (id int not null, str char(10), unique(str));
+explain select * from t1;
+table type possible_keys key key_len ref rows Extra
+t1 system NULL NULL NULL NULL 0 const row not found
+insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar");
+select * from t1 where str is null;
id str
1 NULL
2 NULL
+select * from t1 where str="foo";
id str
3 foo
+explain select * from t1 where str is null;
table type possible_keys key key_len ref rows Extra
-t1 ref str str 11 const 1 where used
+t1 ref str str 11 const 1 Using where
+explain select * from t1 where str="foo";
table type possible_keys key key_len ref rows Extra
t1 const str str 11 const 1
+explain select * from t1 ignore key (str) where str="foo";
table type possible_keys key key_len ref rows Extra
-t1 ALL str NULL NULL NULL 4 where used
+t1 ALL NULL NULL NULL NULL 4 Using where
+explain select * from t1 use key (str,str) where str="foo";
table type possible_keys key key_len ref rows Extra
t1 const str str 11 const 1
+explain select * from t1 use key (str,str,foo) where str="foo";
+Key column 'foo' doesn't exist in table
+explain select * from t1 ignore key (str,str,foo) where str="foo";
+Key column 'foo' doesn't exist in table
+drop table t1;
+explain select 1;
Comment
No tables used
+create table t1 (a int not null);
+explain select count(*) from t1;
+Comment
+Select tables optimized away
+insert into t1 values(1);
+explain select count(*) from t1;
+Comment
+Select tables optimized away
+insert into t1 values(1);
+explain select count(*) from t1;
+Comment
+Select tables optimized away
+drop table t1;
diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result
index fca84de710c..8dc73e446c7 100644
--- a/mysql-test/r/flush.result
+++ b/mysql-test/r/flush.result
@@ -1,6 +1,30 @@
+drop table if exists t1;
+drop database if exists mysqltest;
+create temporary table t1(n int not null primary key);
+drop table if exists t2;
+create table t2(n int);
+insert into t2 values(3);
+select * from t1;
n
3
+flush tables with read lock;
+drop table t2;
+Table 't2' was locked with a READ lock and can't be updated
+ drop table t2;
+unlock tables;
+create database mysqltest;
+create table mysqltest.t1(n int);
+insert into mysqltest.t1 values (23);
+flush tables with read lock;
+ drop database mysqltest;
+select * from mysqltest.t1;
n
23
+unlock tables;
+create table t1 (n int);
+flush tables with read lock;
+insert into t1 values (345);
+select * from t1;
n
345
+drop table t1;
diff --git a/mysql-test/r/foreign_key.result b/mysql-test/r/foreign_key.result
new file mode 100644
index 00000000000..ece53db2e9a
--- /dev/null
+++ b/mysql-test/r/foreign_key.result
@@ -0,0 +1,15 @@
+drop table if exists t1;
+create table t1 (
+a int not null references t2,
+b int not null references t2 (c),
+primary key (a,b),
+foreign key (a) references t3 match full,
+foreign key (a) references t3 match partial,
+foreign key (a,b) references t3 (c,d) on delete no action
+on update no action,
+foreign key (a,b) references t3 (c,d) on update cascade,
+foreign key (a,b) references t3 (c,d) on delete set default,
+foreign key (a,b) references t3 (c,d) on update set null);
+create index a on t1 (a);
+create unique index b on t1 (a,b);
+drop table t1;
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index c39210107ae..651baad266e 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -1,22 +1,194 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (a VARCHAR(200), b TEXT, FULLTEXT (a,b));
+INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),
+('Full-text indexes', 'are called collections'),
+('Only MyISAM tables','support collections'),
+('Function MATCH ... AGAINST()','is used to do a search'),
+('Full-text search in MySQL', 'implements vector space model');
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 a 1 a A NULL NULL NULL YES FULLTEXT
+t1 1 a 2 b A NULL NULL NULL YES FULLTEXT
+select * from t1 where MATCH(a,b) AGAINST ("collections");
a b
Only MyISAM tables support collections
Full-text indexes are called collections
+select * from t1 where MATCH(a,b) AGAINST ("indexes");
a b
Full-text indexes are called collections
+select * from t1 where MATCH(a,b) AGAINST ("indexes collections");
a b
Full-text indexes are called collections
Only MyISAM tables support collections
+explain select * from t1 where MATCH(a,b) AGAINST ("collections");
+table type possible_keys key key_len ref rows Extra
+t1 fulltext a a 0 1 Using where
+explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0;
+table type possible_keys key key_len ref rows Extra
+t1 fulltext a a 0 1 Using where
+explain select * from t1 where MATCH(a,b) AGAINST ("collections")>1;
+table type possible_keys key key_len ref rows Extra
+t1 fulltext a a 0 1 Using where
+explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=0;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 5 Using where
+explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=1;
+table type possible_keys key key_len ref rows Extra
+t1 fulltext a a 0 1 Using where
+explain select * from t1 where 0<MATCH(a,b) AGAINST ("collections");
+table type possible_keys key key_len ref rows Extra
+t1 fulltext a a 0 1 Using where
+explain select * from t1 where 1<MATCH(a,b) AGAINST ("collections");
+table type possible_keys key key_len ref rows Extra
+t1 fulltext a a 0 1 Using where
+explain select * from t1 where 0<=MATCH(a,b) AGAINST ("collections");
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 5 Using where
+explain select * from t1 where 1<=MATCH(a,b) AGAINST ("collections");
+table type possible_keys key key_len ref rows Extra
+t1 fulltext a a 0 1 Using where
+explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0 and a like '%ll%';
+table type possible_keys key key_len ref rows Extra
+t1 fulltext a a 0 1 Using where
+select * from t1 where MATCH(a,b) AGAINST("support -collections" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+select * from t1 where MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Full-text indexes are called collections
+Only MyISAM tables support collections
+select * from t1 where MATCH(a,b) AGAINST("support +collections" IN BOOLEAN MODE);
+a b
+Full-text indexes are called collections
+Only MyISAM tables support collections
+select * from t1 where MATCH(a,b) AGAINST("sear*" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Function MATCH ... AGAINST() is used to do a search
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE);
+a b
+Only MyISAM tables support collections
+select * from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Function MATCH ... AGAINST() is used to do a search
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE);
+a b
+Function MATCH ... AGAINST() is used to do a search
+select *, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1;
+a b x
+MySQL has now support for full-text search 1
+Full-text indexes are called collections 1
+Only MyISAM tables support collections 2
+Function MATCH ... AGAINST() is used to do a search 0
+Full-text search in MySQL implements vector space model 0
+select *, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1;
+a b x
+MySQL has now support for full-text search 1
+Full-text indexes are called collections 1
+Only MyISAM tables support collections 2
+Function MATCH ... AGAINST() is used to do a search 0
+Full-text search in MySQL implements vector space model 0
+select * from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE);
+a b
+Full-text indexes are called collections
+select * from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE);
+a b
+select * from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+select * from t1 where MATCH a,b AGAINST ('"text search" "now support"' IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH a,b AGAINST ('"text search" -"now support"' IN BOOLEAN MODE);
+a b
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH a,b AGAINST ('"text search" +"now support"' IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+select * from t1 where MATCH a,b AGAINST ('"text i"' IN BOOLEAN MODE);
+a b
+Full-text indexes are called collections
+select * from t1 where MATCH a AGAINST ("search" IN BOOLEAN MODE);
+a b
+Full-text search in MySQL implements vector space model
+select * from t1 where MATCH b AGAINST ("sear*" IN BOOLEAN MODE);
+a b
+MySQL has now support for full-text search
+Function MATCH ... AGAINST() is used to do a search
+select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes");
+a b
+Only MyISAM tables support collections
+Full-text indexes are called collections
+Full-text indexes are called collections
+delete from t1 where a like "MySQL%";
+update t1 set a='some test foobar' where MATCH a,b AGAINST ('model');
+delete from t1 where MATCH(a,b) AGAINST ("indexes");
+select * from t1;
a b
Only MyISAM tables support collections
Function MATCH ... AGAINST() is used to do a search
some test foobar implements vector space model
+drop table t1;
+create table t1 (a varchar(200) not null, fulltext (a));
+insert t1 values ("aaa10 bbb20"), ("aaa20 bbb15"), ("aaa30 bbb10");
+select * from t1 where match a against ("+aaa* +bbb*" in boolean mode);
+a
+aaa10 bbb20
+aaa20 bbb15
+aaa30 bbb10
+select * from t1 where match a against ("+aaa* +bbb1*" in boolean mode);
+a
+aaa20 bbb15
+aaa30 bbb10
+select * from t1 where match a against ("+aaa* +ccc*" in boolean mode);
+a
+select * from t1 where match a against ("+aaa10 +(bbb*)" in boolean mode);
+a
+aaa10 bbb20
+drop table t1;
+CREATE TABLE t1 (
+id int(11),
+ticket int(11),
+KEY ti (id),
+KEY tit (ticket)
+);
+INSERT INTO t1 VALUES (2,3),(1,2);
+CREATE TABLE t2 (
+ticket int(11),
+inhalt text,
+KEY tig (ticket),
+fulltext index tix (inhalt)
+);
+INSERT INTO t2 VALUES (1,'foo'),(2,'bar'),(3,'foobar');
+select t1.id FROM t2 as ttxt,t1,t1 as ticket2
+WHERE ticket2.id = ttxt.ticket AND t1.id = ticket2.ticket and
+match(ttxt.inhalt) against ('foobar');
id
+select t1.id FROM t2 as ttxt,t1 INNER JOIN t1 as ticket2 ON
+ticket2.id = ttxt.ticket
+WHERE t1.id = ticket2.ticket and match(ttxt.inhalt) against ('foobar');
id
+INSERT INTO t1 VALUES (3,3);
+select t1.id FROM t2 as ttxt,t1
+INNER JOIN t1 as ticket2 ON ticket2.id = ttxt.ticket
+WHERE t1.id = ticket2.ticket and
+match(ttxt.inhalt) against ('foobar');
id
3
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t2 1 tig 1 ticket A NULL NULL NULL
-t2 1 tix 1 inhalt A NULL 1 NULL FULLTEXT
+show keys from t2;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t2 1 tig 1 ticket A NULL NULL NULL YES BTREE
+t2 1 tix 1 inhalt A NULL NULL NULL YES FULLTEXT
+show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`ticket` int(11) default NULL,
@@ -24,8 +196,97 @@ t2 CREATE TABLE `t2` (
KEY `tig` (`ticket`),
FULLTEXT KEY `tix` (`inhalt`)
) TYPE=MyISAM
+select * from t2 where MATCH inhalt AGAINST (NULL);
ticket inhalt
+select * from t2 where MATCH inhalt AGAINST ('foobar');
ticket inhalt
3 foobar
+select * from t2 having MATCH inhalt AGAINST ('foobar');
ticket inhalt
3 foobar
+CREATE TABLE t3 (
+ticket int(11),
+inhalt text,
+KEY tig (ticket),
+fulltext index tix (inhalt)
+);
+select * from t2 where MATCH inhalt AGAINST (t2.inhalt);
+Wrong arguments to AGAINST
+select * from t2 where MATCH ticket AGAINST ('foobar');
+Can't find FULLTEXT index matching the column list
+select * from t2,t3 where MATCH (t2.inhalt,t3.inhalt) AGAINST ('foobar');
+Wrong arguments to MATCH
+drop table t1,t2,t3;
+CREATE TABLE t1 (
+id int(11) auto_increment,
+title varchar(100) default '',
+PRIMARY KEY (id),
+KEY ind5 (title),
+FULLTEXT KEY FT1 (title)
+) TYPE=MyISAM;
+insert into t1 (title) values ('this is a test');
+select * from t1 where match title against ('test' in boolean mode);
+id title
+1 this is a test
+update t1 set title='this is A test' where id=1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+update t1 set title='this test once revealed a bug' where id=1;
+select * from t1;
+id title
+1 this test once revealed a bug
+update t1 set title=NULL where id=1;
+drop table t1;
+CREATE TABLE t1 (a int(11), b text, FULLTEXT KEY (b)) TYPE=MyISAM;
+insert into t1 values (1,"I wonder why the fulltext index doesnt work?");
+SELECT * from t1 where MATCH (b) AGAINST ('apples');
+a b
+insert into t1 values (2,"fullaaa fullzzz");
+select * from t1 where match b against ('full*' in boolean mode);
+a b
+2 fullaaa fullzzz
+1 I wonder why the fulltext index doesnt work?
+drop table t1;
+CREATE TABLE t1 ( id int(11) NOT NULL auto_increment primary key, mytext text NOT NULL, FULLTEXT KEY mytext (mytext)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'my small mouse'),(2,'la-la-la'),(3,'It is so funny'),(4,'MySQL Tutorial');
+select 8 from t1;
+8
+8
+8
+8
+8
+drop table t1;
+drop table if exists t1;
+create table t1 (a text, fulltext key (a));
+insert into t1 values ('aaaa');
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+select * from t1 where match (a) against ('aaaa');
+a
+drop table t1;
+drop table if exists t1;
+create table t1 ( ref_mag text not null, fulltext (ref_mag));
+insert into t1 values ('test');
+select ref_mag from t1 where match ref_mag against ('+test' in boolean mode);
+ref_mag
+test
+alter table t1 change ref_mag ref_mag char (255) not null;
+select ref_mag from t1 where match ref_mag against ('+test' in boolean mode);
+ref_mag
+test
+drop table t1;
+create table t1 (t1_id int(11) primary key, name varchar(32));
+insert into t1 values (1, 'data1');
+insert into t1 values (2, 'data2');
+create table t2 (t2_id int(11) primary key, t1_id int(11), name varchar(32));
+insert into t2 values (1, 1, 'xxfoo');
+insert into t2 values (2, 1, 'xxbar');
+insert into t2 values (3, 1, 'xxbuz');
+select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode);
+t1_id name t2_id t1_id name
+1 data1 1 1 xxfoo
+select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
+t2_id t1_id name
+drop table t1,t2;
diff --git a/mysql-test/r/fulltext_cache.result b/mysql-test/r/fulltext_cache.result
index a580437b0ce..c489bdefeb8 100644
--- a/mysql-test/r/fulltext_cache.result
+++ b/mysql-test/r/fulltext_cache.result
@@ -1,5 +1,30 @@
+drop table if exists t1, t2;
+CREATE TABLE t1 (
+id int(10) unsigned NOT NULL auto_increment,
+q varchar(255) default NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (1,'aaaaaaaaa dsaass de');
+INSERT INTO t1 VALUES (2,'ssde df s fsda sad er');
+CREATE TABLE t2 (
+id int(10) unsigned NOT NULL auto_increment,
+id2 int(10) unsigned default NULL,
+item varchar(255) default NULL,
+PRIMARY KEY (id),
+FULLTEXT KEY item(item)
+);
+INSERT INTO t2 VALUES (1,1,'sushi');
+INSERT INTO t2 VALUES (2,1,'Bolo de Chocolate');
+INSERT INTO t2 VALUES (3,1,'Feijoada');
+INSERT INTO t2 VALUES (4,1,'Mousse de Chocolate');
+INSERT INTO t2 VALUES (5,2,'um copo de Vodka');
+INSERT INTO t2 VALUES (6,2,'um chocolate Snickers');
+INSERT INTO t2 VALUES (7,1,'Bife');
+INSERT INTO t2 VALUES (8,1,'Pizza de Salmao');
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
+as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
q item id x
-aaaaaaaaa dsaass de sushi 1 1.92378665219675
+aaaaaaaaa dsaass de sushi 1 1.92378664016724
aaaaaaaaa dsaass de Bolo de Chocolate 2 0
aaaaaaaaa dsaass de Feijoada 3 0
aaaaaaaaa dsaass de Mousse de Chocolate 4 0
@@ -7,8 +32,10 @@ ssde df s fsda sad er um copo de Vodka 5 0
ssde df s fsda sad er um chocolate Snickers 6 0
aaaaaaaaa dsaass de Bife 7 0
aaaaaaaaa dsaass de Pizza de Salmao 8 0
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
+as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
q item id x
-aaaaaaaaa dsaass de sushi 1 1.92378665219675
+aaaaaaaaa dsaass de sushi 1 1
aaaaaaaaa dsaass de Bolo de Chocolate 2 0
aaaaaaaaa dsaass de Feijoada 3 0
aaaaaaaaa dsaass de Mousse de Chocolate 4 0
@@ -16,3 +43,26 @@ ssde df s fsda sad er um copo de Vodka 5 0
ssde df s fsda sad er um chocolate Snickers 6 0
aaaaaaaaa dsaass de Bife 7 0
aaaaaaaaa dsaass de Pizza de Salmao 8 0
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
+as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+q item id x
+aaaaaaaaa dsaass de sushi 1 1.92378664016724
+aaaaaaaaa dsaass de Bolo de Chocolate 2 0
+aaaaaaaaa dsaass de Feijoada 3 0
+aaaaaaaaa dsaass de Mousse de Chocolate 4 0
+ssde df s fsda sad er um copo de Vodka 5 0
+ssde df s fsda sad er um chocolate Snickers 6 0
+aaaaaaaaa dsaass de Bife 7 0
+aaaaaaaaa dsaass de Pizza de Salmao 8 0
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
+as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+q item id x
+aaaaaaaaa dsaass de sushi 1 1
+aaaaaaaaa dsaass de Bolo de Chocolate 2 0
+aaaaaaaaa dsaass de Feijoada 3 0
+aaaaaaaaa dsaass de Mousse de Chocolate 4 0
+ssde df s fsda sad er um copo de Vodka 5 0
+ssde df s fsda sad er um chocolate Snickers 6 0
+aaaaaaaaa dsaass de Bife 7 0
+aaaaaaaaa dsaass de Pizza de Salmao 8 0
+drop table t1, t2;
diff --git a/mysql-test/r/fulltext_distinct.result b/mysql-test/r/fulltext_distinct.result
new file mode 100644
index 00000000000..abb4929d0ec
--- /dev/null
+++ b/mysql-test/r/fulltext_distinct.result
@@ -0,0 +1,43 @@
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+id mediumint unsigned NOT NULL auto_increment,
+tag char(6) NOT NULL default '',
+value text NOT NULL default '',
+PRIMARY KEY (id),
+KEY kt(tag),
+KEY kv(value(15)),
+FULLTEXT KEY kvf(value)
+) TYPE=MyISAM;
+CREATE TABLE t2 (
+id_t2 mediumint unsigned NOT NULL default '0',
+id_t1 mediumint unsigned NOT NULL default '0',
+field_number tinyint unsigned NOT NULL default '0',
+PRIMARY KEY (id_t2,id_t1,field_number),
+KEY id_t1(id_t1)
+) TYPE=MyISAM;
+INSERT INTO t1 (tag,value) VALUES ('foo123','bar111');
+INSERT INTO t1 (tag,value) VALUES ('foo123','bar222');
+INSERT INTO t1 (tag,value) VALUES ('bar345','baz333 ar');
+INSERT INTO t2 VALUES (2231626,64280,0);
+INSERT INTO t2 VALUES (2231626,64281,0);
+INSERT INTO t2 VALUES (12346, 3, 1);
+SELECT * FROM t1;
+id tag value
+1 foo123 bar111
+2 foo123 bar222
+3 bar345 baz333 ar
+SELECT * FROM t2;
+id_t2 id_t1 field_number
+12346 3 1
+2231626 64280 0
+2231626 64281 0
+SELECT DISTINCT t2.id_t2 FROM t2, t1
+WHERE MATCH (t1.value) AGAINST ('baz333') AND t1.id = t2.id_t1;
+id_t2
+12346
+SELECT DISTINCT t2.id_t2 FROM t2, t1
+WHERE MATCH (t1.value) AGAINST ('baz333' IN BOOLEAN MODE)
+AND t1.id = t2.id_t1;
+id_t2
+12346
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/fulltext_left_join.result b/mysql-test/r/fulltext_left_join.result
index 04244e309e5..d215ea0cea8 100644
--- a/mysql-test/r/fulltext_left_join.result
+++ b/mysql-test/r/fulltext_left_join.result
@@ -1,5 +1,52 @@
+drop table if exists t1, t2;
+CREATE TABLE t1 (
+id VARCHAR(255) NOT NULL PRIMARY KEY,
+sujet VARCHAR(255),
+motsclefs TEXT,
+texte MEDIUMTEXT,
+FULLTEXT(sujet, motsclefs, texte)
+);
+INSERT INTO t1 VALUES('123','toto','essai','test');
+INSERT INTO t1 VALUES('456','droit','penal','lawyer');
+INSERT INTO t1 VALUES('789','aaaaa','bbbbb','cccccc');
+CREATE TABLE t2 (
+id VARCHAR(255) NOT NULL,
+author VARCHAR(255) NOT NULL
+);
+INSERT INTO t2 VALUES('123', 'moi');
+INSERT INTO t2 VALUES('123', 'lui');
+INSERT INTO t2 VALUES('456', 'lui');
+select match(t1.texte,t1.sujet,t1.motsclefs) against('droit')
+from t1 left join t2 on t2.id=t1.id;
match(t1.texte,t1.sujet,t1.motsclefs) against('droit')
0
0
-0.67003110026735
+0.67003107070923
0
+select match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE)
+from t1 left join t2 on t2.id=t1.id;
+match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE)
+0
+0
+1
+0
+drop table t1, t2;
+create table t1 (venue_id int(11) default null, venue_text varchar(255) default null, dt datetime default null) type=myisam;
+insert into t1 (venue_id, venue_text, dt) values (1, 'a1', '2003-05-23 19:30:00'),(null, 'a2', '2003-05-23 19:30:00');
+create table t2 (name varchar(255) not null default '', entity_id int(11) not null auto_increment, primary key (entity_id), fulltext key name (name)) type=myisam;
+insert into t2 (name, entity_id) values ('aberdeen town hall', 1), ('glasgow royal concert hall', 2), ('queen\'s hall, edinburgh', 3);
+select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen' in boolean mode) and dt = '2003-05-23 19:30:00';
+venue_id venue_text dt name entity_id
+1 a1 2003-05-23 19:30:00 aberdeen town hall 1
+select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen') and dt = '2003-05-23 19:30:00';
+venue_id venue_text dt name entity_id
+1 a1 2003-05-23 19:30:00 aberdeen town hall 1
+select * from t1 left join t2 on (venue_id = entity_id and match(name) against('aberdeen' in boolean mode)) where dt = '2003-05-23 19:30:00';
+venue_id venue_text dt name entity_id
+1 a1 2003-05-23 19:30:00 aberdeen town hall 1
+NULL a2 2003-05-23 19:30:00 NULL NULL
+select * from t1 left join t2 on (venue_id = entity_id and match(name) against('aberdeen')) where dt = '2003-05-23 19:30:00';
+venue_id venue_text dt name entity_id
+1 a1 2003-05-23 19:30:00 aberdeen town hall 1
+NULL a2 2003-05-23 19:30:00 NULL NULL
+drop table t1,t2;
diff --git a/mysql-test/r/fulltext_multi.result b/mysql-test/r/fulltext_multi.result
index d78d88172b5..968b00020e2 100644
--- a/mysql-test/r/fulltext_multi.result
+++ b/mysql-test/r/fulltext_multi.result
@@ -1,12 +1,29 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a int(11) NOT NULL auto_increment,
+b text,
+c varchar(254) default NULL,
+PRIMARY KEY (a),
+FULLTEXT KEY bb(b),
+FULLTEXT KEY cc(c),
+FULLTEXT KEY a(b,c)
+);
+INSERT INTO t1 VALUES (1,'lala lolo lili','oooo aaaa pppp');
+INSERT INTO t1 VALUES (2,'asdf fdsa','lkjh fghj');
+INSERT INTO t1 VALUES (3,'qpwoei','zmxnvb');
+SELECT a, MATCH b AGAINST ('lala lkjh') FROM t1;
a MATCH b AGAINST ('lala lkjh')
-1 0.67003110026735
+1 0.67003107070923
2 0
3 0
+SELECT a, MATCH c AGAINST ('lala lkjh') FROM t1;
a MATCH c AGAINST ('lala lkjh')
1 0
-2 0.67756324121582
+2 0.67756325006485
3 0
+SELECT a, MATCH b,c AGAINST ('lala lkjh') FROM t1;
a MATCH b,c AGAINST ('lala lkjh')
-1 0.64840710366884
-2 0.66266459031789
+1 0.64840710163116
+2 0.66266459226608
3 0
+drop table t1;
diff --git a/mysql-test/r/fulltext_order_by.result b/mysql-test/r/fulltext_order_by.result
index 3ac5285151b..bfee9eba280 100644
--- a/mysql-test/r/fulltext_order_by.result
+++ b/mysql-test/r/fulltext_order_by.result
@@ -1,19 +1,80 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a INT AUTO_INCREMENT PRIMARY KEY,
+message CHAR(20),
+FULLTEXT(message)
+) comment = 'original testcase by sroussey@network54.com';
+INSERT INTO t1 (message) VALUES ("Testing"),("table"),("testbug"),
+("steve"),("is"),("cool"),("steve is cool");
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve');
a MATCH (message) AGAINST ('steve')
-4 0.90587321329654
-7 0.89568988462614
+4 0.90587323904037
+7 0.89568990468979
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve');
+a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
+4 1
+7 1
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
a MATCH (message) AGAINST ('steve')
-4 0.90587321329654
-7 0.89568988462614
+4 0.90587323904037
+7 0.89568990468979
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
+a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
+4 1
+7 1
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve') ORDER BY a;
a MATCH (message) AGAINST ('steve')
-7 0.89568988462614
-4 0.90587321329654
+4 0.90587323904037
+7 0.89568990468979
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a;
+a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
+4 1
+7 1
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve') ORDER BY a DESC;
a MATCH (message) AGAINST ('steve')
-7 0.89568988462614
+7 0.89568990468979
+4 0.90587323904037
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a DESC;
+a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
+7 1
+4 1
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve') ORDER BY 1;
+a MATCH (message) AGAINST ('steve')
+7 0.89568990468979
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY 1;
+a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
+7 1
+SELECT a, MATCH (message) AGAINST ('steve') as rel FROM t1 ORDER BY rel;
a rel
1 0
2 0
3 0
5 0
6 0
-7 0.89568988462614
-4 0.90587321329654
+7 0.89568990468979
+4 0.90587323904037
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
+a rel
+1 0
+2 0
+3 0
+5 0
+6 0
+4 1
+7 1
+drop table t1;
+CREATE TABLE t1 (
+a INT AUTO_INCREMENT PRIMARY KEY,
+message CHAR(20),
+FULLTEXT(message)
+);
+INSERT INTO t1 (message) VALUES ("testbug"),("testbug foobar");
+SELECT a, MATCH (message) AGAINST ('t* f*' IN BOOLEAN MODE) as rel FROM t1;
+a rel
+1 1
+2 2
+SELECT a, MATCH (message) AGAINST ('t* f*' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel,a;
+a rel
+1 1
+2 2
+drop table t1;
diff --git a/mysql-test/r/fulltext_update.result b/mysql-test/r/fulltext_update.result
index 77ee76ad30d..5d3f95b318c 100644
--- a/mysql-test/r/fulltext_update.result
+++ b/mysql-test/r/fulltext_update.result
@@ -1,2 +1,22 @@
+drop table if exists test;
+CREATE TABLE test (
+gnr INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+url VARCHAR(80) DEFAULT '' NOT NULL,
+shortdesc VARCHAR(200) DEFAULT '' NOT NULL,
+longdesc text DEFAULT '' NOT NULL,
+description VARCHAR(80) DEFAULT '' NOT NULL,
+name VARCHAR(80) DEFAULT '' NOT NULL,
+FULLTEXT(url,description,shortdesc,longdesc),
+PRIMARY KEY(gnr)
+);
+insert into test (url,shortdesc,longdesc,description,name) VALUES
+("http:/test.at", "kurz", "lang","desc", "name");
+insert into test (url,shortdesc,longdesc,description,name) VALUES
+("http:/test.at", "kurz", "","desc", "name");
+update test set url='test', description='ddd', name='nam' where gnr=2;
+update test set url='test', shortdesc='ggg', longdesc='mmm',
+description='ddd', name='nam' where gnr=2;
+check table test;
Table Op Msg_type Msg_text
test.test check status OK
+drop table test;
diff --git a/mysql-test/r/fulltext_var.result b/mysql-test/r/fulltext_var.result
new file mode 100644
index 00000000000..dda8e332fba
--- /dev/null
+++ b/mysql-test/r/fulltext_var.result
@@ -0,0 +1,7 @@
+show variables like "ft\_%";
+Variable_name Value
+ft_boolean_syntax + -><()~*:""&|
+ft_min_word_len 4
+ft_max_word_len 254
+ft_max_word_len_for_sort 20
+ft_stopword_file (built-in)
diff --git a/mysql-test/r/func_concat.result b/mysql-test/r/func_concat.result
index 75ee8f2bf79..17afd49b54c 100644
--- a/mysql-test/r/func_concat.result
+++ b/mysql-test/r/func_concat.result
@@ -1,13 +1,28 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 ( number INT NOT NULL, alpha CHAR(6) NOT NULL );
+INSERT INTO t1 VALUES (1413006,'idlfmv'),
+(1413065,'smpsfz'),(1413127,'sljrhx'),(1413304,'qerfnd');
+SELECT number, alpha, CONCAT_WS('<---->',number,alpha) AS new
+FROM t1 GROUP BY number;
number alpha new
1413006 idlfmv 1413006<---->idlfmv
1413065 smpsfz 1413065<---->smpsfz
1413127 sljrhx 1413127<---->sljrhx
1413304 qerfnd 1413304<---->qerfnd
+SELECT CONCAT_WS('<---->',number,alpha) AS new
+FROM t1 GROUP BY new LIMIT 1;
new
1413006<---->idlfmv
+SELECT number, alpha, CONCAT_WS('<->',number,alpha) AS new
+FROM t1 GROUP BY new LIMIT 1;
number alpha new
1413006 idlfmv 1413006<->idlfmv
+SELECT number, alpha, CONCAT_WS('-',number,alpha,alpha,alpha,alpha,alpha,alpha,alpha) AS new
+FROM t1 GROUP BY new LIMIT 1;
number alpha new
1413006 idlfmv 1413006-idlfmv-idlfmv-idlfmv-idlfmv-idlfmv-idlfmv-idlfmv
+SELECT number, alpha, CONCAT_WS('<------------------>',number,alpha) AS new
+FROM t1 GROUP BY new LIMIT 1;
number alpha new
1413006 idlfmv 1413006<------------------>idlfmv
+drop table t1;
diff --git a/mysql-test/r/func_crypt.result b/mysql-test/r/func_crypt.result
index 021989add8d..96bbaa6cae7 100644
--- a/mysql-test/r/func_crypt.result
+++ b/mysql-test/r/func_crypt.result
@@ -1,2 +1,19 @@
+select length(encrypt('foo', 'ff')) <> 0;
length(encrypt('foo', 'ff')) <> 0
1
+select old_password('test'), password('test');
+old_password('test') password('test')
+378b243e220ca493 378b243e220ca493
+select length(encrypt('test')), encrypt('test','aa');
+length(encrypt('test')) encrypt('test','aa')
+13 aaqPiZY5xR5l.
+drop table if exists t1;
+create table t1 (name varchar(50), pw varchar(16));
+insert into t1 values ('tom', password('my_pass'));
+set @pass='my_pass';
+select name from t1 where name='tom' and pw=password(@pass);
+name
+tom
+select name from t1 where name='tom' and pw=password(@undefined);
+name
+drop table t1;
diff --git a/mysql-test/r/func_date_add.result b/mysql-test/r/func_date_add.result
index 3bc0fb1aff3..acdf2c5d7be 100644
--- a/mysql-test/r/func_date_add.result
+++ b/mysql-test/r/func_date_add.result
@@ -1,12 +1,47 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+visitor_id int(10) unsigned DEFAULT '0' NOT NULL,
+group_id int(10) unsigned DEFAULT '0' NOT NULL,
+hits int(10) unsigned DEFAULT '0' NOT NULL,
+sessions int(10) unsigned DEFAULT '0' NOT NULL,
+ts timestamp(14),
+PRIMARY KEY (visitor_id,group_id)
+)/*! type=MyISAM */;
+INSERT INTO t1 VALUES (465931136,7,2,2,20000318160952);
+INSERT INTO t1 VALUES (173865424,2,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,8,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,39,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,7,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,3,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,6,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,60,2,2,20000318233615);
+INSERT INTO t1 VALUES (173865424,1502,2,2,20000318233615);
+INSERT INTO t1 VALUES (48985536,2,2,2,20000319013932);
+INSERT INTO t1 VALUES (48985536,8,2,2,20000319013932);
+INSERT INTO t1 VALUES (48985536,39,2,2,20000319013932);
+INSERT INTO t1 VALUES (48985536,7,2,2,20000319013932);
+INSERT INTO t1 VALUES (465931136,3,2,2,20000318160951);
+INSERT INTO t1 VALUES (465931136,119,1,1,20000318160953);
+INSERT INTO t1 VALUES (465931136,2,1,1,20000318160950);
+INSERT INTO t1 VALUES (465931136,8,1,1,20000318160950);
+INSERT INTO t1 VALUES (465931136,39,1,1,20000318160950);
+INSERT INTO t1 VALUES (1092858576,14,1,1,20000319013445);
+INSERT INTO t1 VALUES (357917728,3,2,2,20000319145026);
+INSERT INTO t1 VALUES (357917728,7,2,2,20000319145027);
+select visitor_id,max(ts) as mts from t1 group by visitor_id
+having mts < DATE_SUB(NOW(),INTERVAL 3 MONTH);
visitor_id mts
48985536 20000319013932
173865424 20000318233615
357917728 20000319145027
465931136 20000318160953
1092858576 20000319013445
+select visitor_id,max(ts) as mts from t1 group by visitor_id
+having DATE_ADD(mts,INTERVAL 3 MONTH) < NOW();
visitor_id mts
48985536 20000319013932
173865424 20000318233615
357917728 20000319145027
465931136 20000318160953
1092858576 20000319013445
+drop table t1;
diff --git a/mysql-test/r/func_encrypt.result b/mysql-test/r/func_encrypt.result
new file mode 100644
index 00000000000..39c734999b2
--- /dev/null
+++ b/mysql-test/r/func_encrypt.result
@@ -0,0 +1,136 @@
+drop table if exists t1;
+create table t1 (x blob);
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('a','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','a'));
+insert into t1 values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab'));
+insert into t1 values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc'));
+insert into t1 values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd'));
+insert into t1 values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde'));
+insert into t1 values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef'));
+insert into t1 values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg'));
+insert into t1 values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh'));
+insert into t1 values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi'));
+insert into t1 values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij'));
+insert into t1 values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('brown dog','sabakala'));
+insert into t1 values (des_encrypt('dog','sabakala'));
+insert into t1 values (des_encrypt('dog!','sabakala'));
+insert into t1 values (des_encrypt('dog!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!!!','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+select hex(x), hex(des_decrypt(x,'sabakala')) from t1;
+hex(x) hex(des_decrypt(x,'sabakala'))
+FFA185A4656D113445E31D7A5B31BB57671A4CA9E21E63FE5D9C801E0CC7AA6190C13E269C2AE8D8060D3FB3FEA94FEC7FB006B9DCAC3E3E41 NULL
+FFC620C3B84E926A54 NULL
+FFA4F77D4220A16C980AF7CB576F8DC0A864F357825C16F329F24F66EBA775765B7C1538B90970740F853B556AEBD35AC31B962EA9B12B5AD4 NULL
+FFACFF5921BB876A90 NULL
+FFA6F18760E7CC5A4C325244B8486F692AAA11D229AF9ED4E4C9D56D7C0278C0DDA58F73E15E2B5F6C1DDD19B22B8071C454C930585449AAEB NULL
+FF3736DFEDC4B765F4 NULL
+FF598681EA5F03CD6D6AEA2B118DF4885DD78BECDFB012BBB05386E436DC403D3CB9DE3BE8D5D3BB7FD90A1F9F9A3E055BB3B4FD3F6A869473 NULL
+FF15B8B5952D630CAE NULL
+FF11EE3A400685226B76D5EC567681FA90247CE3C9DBE43341311C22F74562B1199957D80E300737791F6345BBC61AE03F28F52E5A6DCC78B2 NULL
+FF0A832AE10DC85483 NULL
+FF6F5C0BF4C5F899B4E7C091D9B1F1E92A7623B651B150CA3E7F420B4DD316D2C1BF76FCF9F9A046C000A9E21C106591E8C1930201B1750269 NULL
+FFA08D5FB849A9FC90 NULL
+FFF7331312FE153A39B1EC0D65BC1D3A0B6FCD49DA8C95D6161F53B11D297BAE142BCA6B9492DAE9A02AF455F16CA2C1CF4E1AD17297E947E2 NULL
+FFDEE60A938478E059 NULL
+FF95A729E73D5D87416A53055029E8CAA95B4F7B49F3D2D821A95D1FCE70F4B7A3226077176723F3DCC0A44D3B2EE9EFBC4D31AA87C948916C NULL
+FF1C78557F542A1FDC91943761B2EED14F NULL
+FF1E35B0775EEE512544A75BDAF58EA1655F5C899D3C5191A47263E2D11C3E688F662AB79F66D3B1DF9C75BD869EB8E04FDAE85719CB573A43 NULL
+FF1C78557F542A1FDCDC4182B5314185E5 NULL
+FF783123DCB36F98A51C39A560C92E129F1DDEEAB170825406A61260FBFBBFB0F2E48DB3282588A975C9C71E0EACA71A2B642A8C9C2E921A9F NULL
+FF1C78557F542A1FDCAC4B1B6B47206306 NULL
+FF6D9B450837017D06CA1F1C9A0E700D03DEF06A4F954527A961CA805F70320E9F3F0007636B80768A253A5F7ADABC18B78F1A2FA560CC0B21 NULL
+FF1C78557F542A1FDCE9038BD99DD43F2E NULL
+FF23FD03BA7548DD0957EBA7A8FBF7A18589762F3913E9A935BDA72F6F28202DC64572E0D633A54EA55BFD2C749E408C8632CCE36A7AE00619 NULL
+FFD8DD3C4ABCB02FCDFE1383ECC0F61E7D02CD3BA72BBAEA26384D14835796501B3DC9A2F7EC2FC1633BDA6D56464536FE12010049C53A1991 54686520717569636B2072656420666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67
+FFACC5C5479575CBCA518B05778139B1BFC10F07299C98D04F580BC2F816828722D65A89C1831BD29DA626D319813BD374 717569636B2072656420666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67
+FF128D5517241DEEC631ABD2A47FA66E57930001417F18204328B0B2CB13F7AD2F50B8336EFAE7DE21 72656420666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67
+FF7CF971283B4DC2D050B3DB22684737B74B5B1CF12CF2FAC5A5995A298505F56D82BBFB9FC3E70059 666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67
+FF8333F3DD21E4488F967E03DD12394813A49F72848BB49473D3CB1C8A1AACF220 6A756D706564206F76657220746865206C617A792062726F776E20646F67
+FFE8CB7FD80E6262C5FEB042A2DCC73B699CEEDCA6DC4458A0 6F76657220746865206C617A792062726F776E20646F67
+FFA29334D7CDB1B403DF3EB992067DD524C7D568E8D98EBFE5 746865206C617A792062726F776E20646F67
+FF4F0C5858FE2358D400E38831D5577C85 6C617A792062726F776E20646F67
+FFB370CD6BAFD1CB95974D21DCCA2DD9D7 62726F776E20646F67
+FF8F7777B28C7A459A 646F67
+FF75213A4D7D01D715 646F6721
+FF2DCAF574B173FB4D 646F672121
+FFFA775787BE776B15 646F67212121
+FF3FC2E42D7C840905 646F6721212121
+FF9723312D26D9E6DA01D01A784A64DB9D 646F672121212121
+FF8333F3DD21E4488F967E03DD12394813A49F72848BB49473D3CB1C8A1AACF220 6A756D706564206F76657220746865206C617A792062726F776E20646F67
+FF8333F3DD21E4488F967E03DD12394813A49F72848BB49473D3CB1C8A1AACF220 6A756D706564206F76657220746865206C617A792062726F776E20646F67
+select des_decrypt(x,'sabakala') as s from t1 having s like '%dog%';
+s
+The quick red fox jumped over the lazy brown dog
+quick red fox jumped over the lazy brown dog
+red fox jumped over the lazy brown dog
+fox jumped over the lazy brown dog
+jumped over the lazy brown dog
+over the lazy brown dog
+the lazy brown dog
+lazy brown dog
+brown dog
+dog
+dog!
+dog!!
+dog!!!
+dog!!!!
+dog!!!!!
+jumped over the lazy brown dog
+jumped over the lazy brown dog
+drop table t1;
+select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello"));
+hex(des_encrypt("hello")) des_decrypt(des_encrypt("hello"))
+85D6DC8859F9759BBB hello
+select des_decrypt(des_encrypt("hello",4));
+des_decrypt(des_encrypt("hello",4))
+hello
+select des_decrypt(des_encrypt("hello",'test'),'test');
+des_decrypt(des_encrypt("hello",'test'),'test')
+hello
+select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password'));
+hex(des_encrypt("hello")) hex(des_encrypt("hello",5)) hex(des_encrypt("hello",'default_password'))
+85D6DC8859F9759BBB 85D6DC8859F9759BBB FFD6DC8859F9759BBB
+select des_decrypt(des_encrypt("hello"),'default_password');
+des_decrypt(des_encrypt("hello"),'default_password')
+hello
+select des_decrypt(des_encrypt("hello",4),'password4');
+des_decrypt(des_encrypt("hello",4),'password4')
+hello
+SET @a=des_decrypt(des_encrypt("hello"));
+flush des_key_file;
+select @a = des_decrypt(des_encrypt("hello"));
+@a = des_decrypt(des_encrypt("hello"))
+1
+select hex("hello");
+hex("hello")
+68656C6C6F
+select hex(des_decrypt(des_encrypt("hello",4),'password2'));
+hex(des_decrypt(des_encrypt("hello",4),'password2'))
+NULL
+select hex(des_decrypt(des_encrypt("hello","hidden")));
+hex(des_decrypt(des_encrypt("hello","hidden")))
+NULL
diff --git a/mysql-test/r/func_equal.result b/mysql-test/r/func_equal.result
index 6e2933641aa..32a911eedf8 100644
--- a/mysql-test/r/func_equal.result
+++ b/mysql-test/r/func_equal.result
@@ -1,15 +1,29 @@
+select 0<=>0,0.0<=>0.0,"A"<=>"A",NULL<=>NULL;
0<=>0 0.0<=>0.0 "A"<=>"A" NULL<=>NULL
1 1 1 1
+select 1<=>0,0<=>NULL,NULL<=>0;
1<=>0 0<=>NULL NULL<=>0
0 0 0
+select 1.0<=>0.0,0.0<=>NULL,NULL<=>0.0;
1.0<=>0.0 0.0<=>NULL NULL<=>0.0
0 0 0
+select "A"<=>"B","A"<=>NULL,NULL<=>"A";
"A"<=>"B" "A"<=>NULL NULL<=>"A"
0 0 0
+drop table if exists t1,t2;
+create table t1 (id int, value int);
+create table t2 (id int, value int);
+insert into t1 values (1,null);
+insert into t2 values (1,null);
+select t1.*, t2.*, t1.value<=>t2.value from t1, t2 where t1.id=t2.id and t1.id=1;
id value id value t1.value<=>t2.value
1 NULL 1 NULL 1
+select * from t1 where id <=>id;
id value
1 NULL
+select * from t1 where value <=> value;
id value
1 NULL
+select * from t1 where id <=> value or value<=>id;
id value
+drop table t1,t2;
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index ea9a06123ae..99c42bb83cf 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -1,3 +1,12 @@
+drop table if exists t1,t2;
+create table t1 (grp int, a bigint unsigned, c char(10) not null);
+insert into t1 values (1,1,"a");
+insert into t1 values (2,2,"b");
+insert into t1 values (2,3,"c");
+insert into t1 values (3,4,"E");
+insert into t1 values (3,5,"C");
+insert into t1 values (3,6,"D");
+select a,c,sum(a) from t1 group by a;
a c sum(a)
1 a 1
2 b 2
@@ -5,82 +14,245 @@ a c sum(a)
4 E 4
5 C 5
6 D 6
+select a,c,sum(a) from t1 where a > 10 group by a;
a c sum(a)
+select sum(a) from t1 where a > 10;
sum(a)
NULL
+select a from t1 order by rand(10);
a
+2
+6
1
3
-6
5
-2
4
+select distinct a from t1 order by rand(10);
a
+2
+6
1
3
-6
5
-2
4
+select count(distinct a),count(distinct grp) from t1;
count(distinct a) count(distinct grp)
6 3
+insert into t1 values (null,null,'');
+select count(distinct a),count(distinct grp) from t1;
count(distinct a) count(distinct grp)
6 3
-sum(a) count(a) avg(a) std(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c)
+select sum(all a),count(all a),avg(all a),std(all a),bit_or(all a),bit_and(all a),min(all a),max(all a),min(all c),max(all c) from t1;
+sum(all a) count(all a) avg(all a) std(all a) bit_or(all a) bit_and(all a) min(all a) max(all a) min(all c) max(all c)
21 6 3.5000 1.7078 7 0 1 6 E
+select grp, sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp;
grp sum(a) count(a) avg(a) std(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c)
-NULL 0 0 NULL NULL 0 0 NULL NULL
+NULL NULL 0 NULL NULL 0 18446744073709551615 NULL NULL
1 1 1 1.0000 0.0000 1 1 1 1 a a
2 5 2 2.5000 0.5000 3 2 2 3 b c
3 15 3 5.0000 0.8165 7 4 4 6 C E
+select grp, sum(a)+count(a)+avg(a)+std(a)+bit_or(a)+bit_and(a)+min(a)+max(a)+min(c)+max(c) as sum from t1 group by grp;
grp sum
NULL NULL
1 7
2 20
3 44.816496580928
+create table t2 (grp int, a bigint unsigned, c char(10));
+insert into t2 select grp,max(a)+max(grp),max(c) from t1 group by grp;
+replace into t2 select grp, a, c from t1 limit 2,1;
+select * from t2;
grp a c
NULL NULL
1 2 a
2 5 c
3 9 E
2 3 c
+drop table t1,t2;
+CREATE TABLE t1 (id int(11),value1 float(10,2));
+INSERT INTO t1 VALUES (1,0.00),(1,1.00), (1,2.00), (2,10.00), (2,11.00), (2,12.00);
+CREATE TABLE t2 (id int(11),name char(20));
+INSERT INTO t2 VALUES (1,'Set One'),(2,'Set Two');
+select id, avg(value1), std(value1) from t1 group by id;
id avg(value1) std(value1)
1 1.000000 0.816497
2 11.000000 0.816497
+select name, avg(value1), std(value1) from t1, t2 where t1.id = t2.id group by t1.id;
name avg(value1) std(value1)
Set One 1.000000 0.816497
Set Two 11.000000 0.816497
+drop table t1,t2;
+create table t1 (id int not null);
+create table t2 (id int not null,rating int null);
+insert into t1 values(1),(2),(3);
+insert into t2 values(1, 3),(2, NULL),(2, NULL),(3, 2),(3, NULL);
+select t1.id, avg(rating) from t1 left join t2 on ( t1.id = t2.id ) group by t1.id;
id avg(rating)
1 3.0000
2 NULL
3 2.0000
+drop table t1,t2;
+create table t1 (a smallint(6) primary key, c char(10), b text);
+INSERT INTO t1 VALUES (1,'1','1');
+INSERT INTO t1 VALUES (2,'2','2');
+INSERT INTO t1 VALUES (4,'4','4');
+select count(*) from t1;
count(*)
3
+select count(*) from t1 where a = 1;
count(*)
1
+select count(*) from t1 where a = 100;
count(*)
0
+select count(*) from t1 where a >= 10;
count(*)
0
+select count(a) from t1 where a = 1;
count(a)
1
+select count(a) from t1 where a = 100;
count(a)
0
+select count(a) from t1 where a >= 10;
count(a)
0
+select count(b) from t1 where b >= 2;
count(b)
2
+select count(b) from t1 where b >= 10;
count(b)
0
+select count(c) from t1 where c = 10;
count(c)
0
+drop table t1;
+CREATE TABLE t1 (d DATETIME, i INT);
+INSERT INTO t1 VALUES (NOW(), 1);
+SELECT COUNT(i), i, COUNT(i)*i FROM t1 GROUP BY i;
COUNT(i) i COUNT(i)*i
1 1 1
+SELECT COUNT(i), (i+0), COUNT(i)*(i+0) FROM t1 GROUP BY i;
COUNT(i) (i+0) COUNT(i)*(i+0)
1 1 1
+DROP TABLE t1;
+create table t1 (
+num float(5,2),
+user char(20)
+);
+insert into t1 values (10.3,'nem'),(20.53,'monty'),(30.23,'sinisa');
+insert into t1 values (30.13,'nem'),(20.98,'monty'),(10.45,'sinisa');
+insert into t1 values (5.2,'nem'),(8.64,'monty'),(11.12,'sinisa');
+select sum(num) from t1;
sum(num)
147.58
+select sum(num) from t1 group by user;
sum(num)
50.15
45.63
51.80
+drop table t1;
+create table t1 (a1 int, a2 char(3), key k1(a1), key k2(a2));
+insert into t1 values(10,'aaa'), (10,null), (10,'bbb'), (20,'zzz');
+create table t2(a1 char(3), a2 int, a3 real, key k1(a1), key k2(a2, a1));
+select * from t1;
+a1 a2
+10 aaa
+10 NULL
+10 bbb
+20 zzz
+select min(a2) from t1;
+min(a2)
+aaa
+select max(t1.a1), max(t2.a2) from t1, t2;
+max(t1.a1) max(t2.a2)
+NULL NULL
+select max(t1.a1) from t1, t2;
+max(t1.a1)
+NULL
+select max(t2.a2), max(t1.a1) from t1, t2;
+max(t2.a2) max(t1.a1)
+NULL NULL
+explain select min(a2) from t1;
+Comment
+Select tables optimized away
+explain select max(t1.a1), max(t2.a2) from t1, t2;
+Comment
+No matching min/max row
+insert into t2 values('AAA', 10, 0.5);
+select max(t1.a1), max(t2.a1) from t1, t2 where t2.a2=9;
+max(t1.a1) max(t2.a1)
+NULL NULL
+select max(t2.a1), max(t1.a1) from t1, t2 where t2.a2=9;
+max(t2.a1) max(t1.a1)
+NULL NULL
+select t1.a1, t1.a2, t2.a1, t2.a2 from t1 left outer join t2 on t1.a1=10;
+a1 a2 a1 a2
+10 aaa AAA 10
+10 NULL AAA 10
+10 bbb AAA 10
+20 zzz NULL NULL
+select max(t1.a2) from t1 left outer join t2 on t1.a1=10;
+max(t1.a2)
+zzz
+select max(t1.a2) from t1 left outer join t2 on t1.a1=10 where t1.a1=20;
+max(t1.a2)
+zzz
+select max(t1.a2) from t1 left outer join t2 on t1.a1=10 where t1.a1=10;
+max(t1.a2)
+bbb
+select max(t2.a1) from t1 left outer join t2 on t1.a2=t2.a1 and 1=0 where t2.a1='AAA';
+max(t2.a1)
+NULL
+drop table t1,t2;
+CREATE TABLE t1 (a int, b int);
+select count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1;
+count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
+0 NULL NULL NULL NULL NULL 18446744073709551615 0
+select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
+insert into t1 values (1,null);
+select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
+1 0 NULL NULL NULL NULL NULL 18446744073709551615 0
+insert into t1 values (1,null);
+insert into t1 values (2,null);
+select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
+1 0 NULL NULL NULL NULL NULL 18446744073709551615 0
+2 0 NULL NULL NULL NULL NULL 18446744073709551615 0
+select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
+1 0 NULL NULL NULL NULL NULL 18446744073709551615 0
+2 0 NULL NULL NULL NULL NULL 18446744073709551615 0
+insert into t1 values (2,1);
+select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
+1 0 NULL NULL NULL NULL NULL 18446744073709551615 0
+2 1 1 1.0000 0.0000 1 1 1 1
+select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
+1 0 NULL NULL NULL NULL NULL 18446744073709551615 0
+2 1 1 1.0000 0.0000 1 1 1 1
+insert into t1 values (3,1);
+select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
+1 0 NULL NULL NULL NULL NULL 18446744073709551615 0
+2 1 1 1.0000 0.0000 1 1 1 1
+3 1 1 1.0000 0.0000 1 1 1 1
+select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b)
+1 0 NULL NULL NULL NULL NULL 18446744073709551615 0
+2 1 1 1.0000 0.0000 1 1 1 1
+3 1 1 1.0000 0.0000 1 1 1 1
+drop table t1;
+create table t1 (col int);
+insert into t1 values (-1), (-2), (-3);
+select bit_and(col), bit_or(col) from t1;
+bit_and(col) bit_or(col)
+18446744073709551612 18446744073709551615
+select SQL_BIG_RESULT bit_and(col), bit_or(col) from t1 group by col;
+bit_and(col) bit_or(col)
+18446744073709551613 18446744073709551613
+18446744073709551614 18446744073709551614
+18446744073709551615 18446744073709551615
+drop table t1;
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result
index 8b5d51a4ba2..0ab41258091 100644
--- a/mysql-test/r/func_if.result
+++ b/mysql-test/r/func_if.result
@@ -1,5 +1,10 @@
+drop table if exists t1;
+select IF(0,"ERROR","this"),IF(1,"is","ERROR"),IF(NULL,"ERROR","a"),IF(1,2,3)|0,IF(1,2.0,3.0)+0 ;
IF(0,"ERROR","this") IF(1,"is","ERROR") IF(NULL,"ERROR","a") IF(1,2,3)|0 IF(1,2.0,3.0)+0
this is a 2 2.0
+CREATE TABLE t1 (st varchar(255) NOT NULL, u int(11) NOT NULL) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('a',1),('A',1),('aa',1),('AA',1),('a',1),('aaa',0),('BBB',0);
+select if(1,st,st) s from t1 order by s;
s
a
A
@@ -8,6 +13,7 @@ aa
AA
aaa
BBB
+select if(u=1,st,st) s from t1 order by s;
s
a
A
@@ -16,6 +22,7 @@ aa
AA
aaa
BBB
+select if(u=1,binary st,st) s from t1 order by s;
s
A
AA
@@ -24,6 +31,7 @@ a
a
aa
aaa
+select if(u=1,st,binary st) s from t1 where st like "%a%" order by s;
s
A
AA
@@ -31,7 +39,16 @@ a
a
aa
aaa
+drop table t1;
+create table t1 (num double(12,2));
+insert into t1 values (144.54);
+select sum(if(num is null,0.00,num)) from t1;
sum(if(num is null,0.00,num))
144.54
+drop table t1;
+create table t1 (x int, y int);
+insert into t1 values (0,6),(10,16),(20,26),(30,10),(40,46),(50,56);
+select min(if(y -x > 5,y,NULL)), max(if(y - x > 5,y,NULL)) from t1;
min(if(y -x > 5,y,NULL)) max(if(y - x > 5,y,NULL))
-16 6
+6 56
+drop table t1;
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index f201d371876..ba33ee0831d 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -1,14 +1,28 @@
+drop table if exists t1;
+CREATE TABLE t1 (field char(1));
+INSERT INTO t1 VALUES ('A'),(NULL);
+SELECT * from t1 WHERE field IN (NULL);
field
+SELECT * from t1 WHERE field NOT IN (NULL);
field
A
+SELECT * from t1 where field = field;
field
A
+SELECT * from t1 where field <=> field;
field
A
NULL
+DELETE FROM t1 WHERE field NOT IN (NULL);
+SELECT * FROM t1;
field
NULL
+drop table t1;
+create table t1 (id int(10) primary key);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
+select * from t1 where id in (2,5,9);
id
2
5
9
+drop table t1;
diff --git a/mysql-test/r/func_isnull.result b/mysql-test/r/func_isnull.result
index deaeaaf71c9..20ddc87ee78 100644
--- a/mysql-test/r/func_isnull.result
+++ b/mysql-test/r/func_isnull.result
@@ -1 +1,7 @@
+drop table if exists t1;
+create table t1 (id int auto_increment primary key not null, mydate date not null);
+insert into t1 values (0,"2002-05-01"),(0,"2002-05-01"),(0,"2002-05-01");
+flush tables;
+select * from t1 where isnull(to_days(mydate));
id mydate
+drop table t1;
diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result
index 78bede19762..b196b50f53b 100644
--- a/mysql-test/r/func_like.result
+++ b/mysql-test/r/func_like.result
@@ -1,7 +1,48 @@
+drop table if exists t1;
+create table t1 (a varchar(10), key(a));
+insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
+explain select * from t1 where a like 'abc%';
+table type possible_keys key key_len ref rows Extra
+t1 range a a 11 NULL 1 Using where; Using index
+explain select * from t1 where a like concat('abc','%');
+table type possible_keys key key_len ref rows Extra
+t1 range a a 11 NULL 1 Using where; Using index
+select * from t1 where a like "abc%";
a
abc
abcd
+select * from t1 where a like concat("abc","%");
+a
+abc
+abcd
+select * from t1 where a like "ABC%";
+a
+abc
+abcd
+select * from t1 where a like "test%";
a
test
+select * from t1 where a like "te_t";
a
test
+select * from t1 where a like "%a%";
+a
+a
+abc
+abcd
+select * from t1 where a like "%abcd%";
+a
+abcd
+select * from t1 where a like "%abc\d%";
+a
+abcd
+drop table t1;
+create table t1 (a varchar(10), key(a));
+insert into t1 values ('a'), ('a\\b');
+select * from t1 where a like 'a\\%' escape '#';
+a
+a\b
+select * from t1 where a like 'a\\%' escape '#' and a like 'a\\\\b';
+a
+a\b
+drop table t1;
diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
index 5e774fe9886..e37862d0176 100644
--- a/mysql-test/r/func_math.result
+++ b/mysql-test/r/func_math.result
@@ -1,23 +1,44 @@
+select floor(5.5),floor(-5.5);
floor(5.5) floor(-5.5)
5 -6
+select ceiling(5.5),ceiling(-5.5);
ceiling(5.5) ceiling(-5.5)
6 -5
+select truncate(52.64,1),truncate(52.64,2),truncate(52.64,-1),truncate(52.64,-2), truncate(-52.64,1),truncate(-52.64,-1);
truncate(52.64,1) truncate(52.64,2) truncate(52.64,-1) truncate(52.64,-2) truncate(-52.64,1) truncate(-52.64,-1)
52.6 52.64 50 0 -52.6 -50
+select round(5.5),round(-5.5);
round(5.5) round(-5.5)
6 -6
+select round(5.64,1),round(5.64,2),round(5.64,-1),round(5.64,-2);
round(5.64,1) round(5.64,2) round(5.64,-1) round(5.64,-2)
5.6 5.64 10 0
+select abs(-10), sign(-5), sign(5), sign(0);
abs(-10) sign(-5) sign(5) sign(0)
10 -1 1 0
-log(exp(10)) exp(log(sqrt(10))*2)
-10.000000 10.000000
+select log(exp(10)),exp(log(sqrt(10))*2),log(-1),log(NULL),log(1,1),log(3,9),log(-1,2),log(NULL,2);
+log(exp(10)) exp(log(sqrt(10))*2) log(-1) log(NULL) log(1,1) log(3,9) log(-1,2) log(NULL,2)
+10.000000 10.000000 NULL NULL NULL 2.000000 NULL NULL
+select ln(exp(10)),exp(ln(sqrt(10))*2),ln(-1),ln(0),ln(NULL);
+ln(exp(10)) exp(ln(sqrt(10))*2) ln(-1) ln(0) ln(NULL)
+10.000000 10.000000 NULL NULL NULL
+select log2(8),log2(15),log2(-2),log2(0),log2(NULL);
+log2(8) log2(15) log2(-2) log2(0) log2(NULL)
+3.000000 3.906891 NULL NULL NULL
+select log10(100),log10(18),log10(-4),log10(0),log10(NULL);
+log10(100) log10(18) log10(-4) log10(0) log10(NULL)
+2.000000 1.255273 NULL NULL NULL
+select pow(10,log10(10)),power(2,4);
pow(10,log10(10)) power(2,4)
10.000000 16.000000
+set @@rand_seed1=10000000,@@rand_seed2=1000000;
+select rand(999999),rand();
rand(999999) rand()
-0.18435012473199 0.76373626176616
-PI() sin(pi()/2) cos(pi()/2) abs(tan(pi())) cot(1) asin(1) acos(0) atan(1)
+0.014231365187309 0.028870999839968
+select pi(),sin(pi()/2),cos(pi()/2),abs(tan(pi())),cot(1),asin(1),acos(0),atan(1);
+pi() sin(pi()/2) cos(pi()/2) abs(tan(pi())) cot(1) asin(1) acos(0) atan(1)
3.141593 1.000000 0.000000 0.000000 0.64209262 1.570796 1.570796 0.785398
+select degrees(pi()),radians(360);
degrees(pi()) radians(360)
180 6.2831853071796
ACOS(1.0)
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 5448127548b..d51bea020ed 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -1,8 +1,18 @@
+select format(1.5555,0),format(123.5555,1),format(1234.5555,2),format(12345.5555,3),format(123456.5555,4),format(1234567.5555,5),format("12345.2399",2);
format(1.5555,0) format(123.5555,1) format(1234.5555,2) format(12345.5555,3) format(123456.5555,4) format(1234567.5555,5) format("12345.2399",2)
2 123.6 1,234.56 12,345.556 123,456.5555 1,234,567.55550 12,345.24
+select inet_ntoa(inet_aton("255.255.255.255.255.255.255.255"));
inet_ntoa(inet_aton("255.255.255.255.255.255.255.255"))
-255.255.255.255.255.255.255.255
+NULL
+select inet_aton("255.255.255.255.255"),inet_aton("255.255.1.255"),inet_aton("0.1.255");
inet_aton("255.255.255.255.255") inet_aton("255.255.1.255") inet_aton("0.1.255")
1099511627775 4294902271 511
+select inet_ntoa(1099511627775),inet_ntoa(4294902271),inet_ntoa(511);
inet_ntoa(1099511627775) inet_ntoa(4294902271) inet_ntoa(511)
-255.255.255.255.255 255.255.1.255 0.0.1.255
+NULL 255.255.1.255 0.0.1.255
+select length(format('nan', 2)) > 0;
+length(format('nan', 2)) > 0
+1
+select concat("$",format(2500,2));
+concat("$",format(2500,2))
+$2,500.00
diff --git a/mysql-test/r/func_op.result b/mysql-test/r/func_op.result
index b14f575c998..d009a66353e 100644
--- a/mysql-test/r/func_op.result
+++ b/mysql-test/r/func_op.result
@@ -1,6 +1,27 @@
+select 1+1,1-1,1+1*2,8/5,8%5,mod(8,5),mod(8,5)|0,-(1+1)*-2;
1+1 1-1 1+1*2 8/5 8%5 mod(8,5) mod(8,5)|0 -(1+1)*-2
2 0 3 1.60 3 3 3 4
+select 1 | (1+1),5 & 3,bit_count(7) ;
1 | (1+1) 5 & 3 bit_count(7)
3 1 3
+select 1 << 32,1 << 63, 1 << 64, 4 >> 2, 4 >> 63, 1<< 63 >> 60;
1 << 32 1 << 63 1 << 64 4 >> 2 4 >> 63 1<< 63 >> 60
-4294967296 -9223372036854775808 0 1 0 8
+4294967296 9223372036854775808 0 1 0 8
+select -1 | 0, -1 ^ 0, -1 & 0;
+-1 | 0 -1 ^ 0 -1 & 0
+18446744073709551615 18446744073709551615 0
+select -1 | 1, -1 ^ 1, -1 & 1;
+-1 | 1 -1 ^ 1 -1 & 1
+18446744073709551615 18446744073709551614 1
+select 1 | -1, 1 ^ -1, 1 & -1;
+1 | -1 1 ^ -1 1 & -1
+18446744073709551615 18446744073709551614 1
+select 0 | -1, 0 ^ -1, 0 & -1;
+0 | -1 0 ^ -1 0 & -1
+18446744073709551615 18446744073709551615 0
+select -1 >> 0, -1 << 0;
+-1 >> 0 -1 << 0
+18446744073709551615 18446744073709551615
+select -1 >> 1, -1 << 1;
+-1 >> 1 -1 << 1
+9223372036854775807 18446744073709551614
diff --git a/mysql-test/r/func_regexp.result b/mysql-test/r/func_regexp.result
index 5927dba0974..8d22994ef2b 100644
--- a/mysql-test/r/func_regexp.result
+++ b/mysql-test/r/func_regexp.result
@@ -1,3 +1,20 @@
+drop table if exists t1;
+create table t1 (s1 char(64),s2 char(64));
+insert into t1 values('aaa','aaa');
+insert into t1 values('aaa|qqq','qqq');
+insert into t1 values('gheis','^[^a-dXYZ]+$');
+insert into t1 values('aab','^aa?b');
+insert into t1 values('Baaan','^Ba*n');
+insert into t1 values('aaa','qqq|aaa');
+insert into t1 values('qqq','qqq|aaa');
+insert into t1 values('bbb','qqq|aaa');
+insert into t1 values('bbb','qqq');
+insert into t1 values('aaa','aba');
+insert into t1 values(null,'abc');
+insert into t1 values('def',null);
+insert into t1 values(null,null);
+insert into t1 values('ghi','ghi[');
+select HIGH_PRIORITY s1 regexp s2 from t1;
s1 regexp s2
1
1
@@ -13,13 +30,25 @@ NULL
NULL
NULL
NULL
+drop table t1;
+create table t1 (xxx char(128));
+insert into t1 (xxx) values('this is a test of some long text to see what happens');
+select * from t1 where xxx regexp('is a test of some long text to');
xxx
this is a test of some long text to see what happens
+select * from t1 where xxx regexp('is a test of some long text to ');
xxx
this is a test of some long text to see what happens
+select * from t1 where xxx regexp('is a test of some long text to s');
xxx
this is a test of some long text to see what happens
+select * from t1 where xxx regexp('is a test of some long text to se');
xxx
this is a test of some long text to see what happens
+drop table t1;
+create table t1 (xxx char(128));
+insert into t1 (xxx) values('this is some text: to test - out.reg exp (22/45)');
+select * from t1 where xxx REGEXP '^this is some text: to test - out\\.reg exp [[(][0-9]+[/\\][0-9]+[])][ ]*$';
xxx
this is some text: to test - out.reg exp (22/45)
+drop table t1;
diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result
index b82fffc3dbd..eeeb216d142 100644
--- a/mysql-test/r/func_set.result
+++ b/mysql-test/r/func_set.result
@@ -1,18 +1,30 @@
+select interval(55,10,20,30,40,50,60,70,80,90,100),interval(3,1,1+1,1+1+1+1),field("IBM","NCA","ICL","SUN","IBM","DIGITAL"),field("A","B","C"),elt(2,"ONE","TWO","THREE"),interval(0,1,2,3,4),elt(1,1,2,3)|0,elt(1,1.1,1.2,1.3)+0;
interval(55,10,20,30,40,50,60,70,80,90,100) interval(3,1,1+1,1+1+1+1) field("IBM","NCA","ICL","SUN","IBM","DIGITAL") field("A","B","C") elt(2,"ONE","TWO","THREE") interval(0,1,2,3,4) elt(1,1,2,3)|0 elt(1,1.1,1.2,1.3)+0
5 2 4 0 TWO 0 1 1.1
+select find_in_set("b","a,b,c"),find_in_set("c","a,b,c"),find_in_set("dd","a,bbb,dd"),find_in_set("bbb","a,bbb,dd");
find_in_set("b","a,b,c") find_in_set("c","a,b,c") find_in_set("dd","a,bbb,dd") find_in_set("bbb","a,bbb,dd")
2 3 3 2
+select find_in_set("d","a,b,c"),find_in_set("dd","a,bbb,d"),find_in_set("bb","a,bbb,dd");
find_in_set("d","a,b,c") find_in_set("dd","a,bbb,d") find_in_set("bb","a,bbb,dd")
0 0 0
+select make_set(0,'a','b','c'),make_set(-1,'a','b','c'),make_set(1,'a','b','c'),make_set(2,'a','b','c'),make_set(1+2,concat('a','b'),'c');
make_set(0,'a','b','c') make_set(-1,'a','b','c') make_set(1,'a','b','c') make_set(2,'a','b','c') make_set(1+2,concat('a','b'),'c')
a,b,c a b ab,c
+select make_set(NULL,'a','b','c'),make_set(1|4,'a',NULL,'c'),make_set(1+2,'a',NULL,'c');
make_set(NULL,'a','b','c') make_set(1|4,'a',NULL,'c') make_set(1+2,'a',NULL,'c')
NULL a,c a
+select export_set(9,"Y","N","-",5),export_set(9,"Y","N"),export_set(9,"Y","N","");
export_set(9,"Y","N","-",5) export_set(9,"Y","N") export_set(9,"Y","N","")
Y-N-N-Y-N Y,N,N,Y,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N YNNYNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+select elt(2,1),field(NULL,"a","b","c");
elt(2,1) field(NULL,"a","b","c")
NULL 0
+select find_in_set("","a,b,c"),find_in_set("","a,b,c,"),find_in_set("",",a,b,c");
find_in_set("","a,b,c") find_in_set("","a,b,c,") find_in_set("",",a,b,c")
0 4 1
+select find_in_set("abc","abc"),find_in_set("ab","abc"),find_in_set("abcd","abc");
find_in_set("abc","abc") find_in_set("ab","abc") find_in_set("abcd","abc")
1 0 0
+select interval(null, 1, 10, 100);
+interval(null, 1, 10, 100)
+-1
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index ec421e9f31b..7d2668c8cf6 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -1,112 +1,275 @@
+drop table if exists t1;
+select 'hello',"'hello'",'""hello""','''h''e''l''l''o''',"hel""lo",'hel\'lo';
hello 'hello' ""hello"" 'h'e'l'l'o' hel"lo hel'lo
hello 'hello' ""hello"" 'h'e'l'l'o' hel"lo hel'lo
+select 'hello' 'monty';
hello
hellomonty
+select length('\n\t\r\b\0\_\%\\');
length('\n\t\r\b\0\_\%\\')
10
+select bit_length('\n\t\r\b\0\_\%\\');
+bit_length('\n\t\r\b\0\_\%\\')
+80
+select concat('monty',' was here ','again'),length('hello'),char(ascii('h'));
concat('monty',' was here ','again') length('hello') char(ascii('h'))
monty was here again 5 h
+select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
locate('he','hello') locate('he','hello',2) locate('lo','hello',2)
1 0 4
-instr('hello','he')
-1
-position('ll' in 'hello') position('a' in 'hello')
+select instr('hello','HE'), instr('hello',binary 'HE'), instr(binary 'hello','HE');
+instr('hello','HE') instr('hello',binary 'HE') instr(binary 'hello','HE')
+1 0 0
+select position(binary 'll' in 'hello'),position('a' in binary 'hello');
+position(binary 'll' in 'hello') position('a' in binary 'hello')
3 0
+select left('hello',2),right('hello',2),substring('hello',2,2),mid('hello',1,5) ;
left('hello',2) right('hello',2) substring('hello',2,2) mid('hello',1,5)
he lo el hello
+select concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',substring('monty',5,1)) ;
concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',substring('monty',5,1))
happy
+select substring_index('www.tcx.se','.',-2),substring_index('www.tcx.se','.',1);
substring_index('www.tcx.se','.',-2) substring_index('www.tcx.se','.',1)
tcx.se www
+select substring_index('www.tcx.se','tcx',1),substring_index('www.tcx.se','tcx',-1);
substring_index('www.tcx.se','tcx',1) substring_index('www.tcx.se','tcx',-1)
www. .se
+select substring_index('.tcx.se','.',-2),substring_index('.tcx.se','.tcx',-1);
substring_index('.tcx.se','.',-2) substring_index('.tcx.se','.tcx',-1)
tcx.se .se
+select concat(':',ltrim(' left '),':',rtrim(' right '),':');
concat(':',ltrim(' left '),':',rtrim(' right '),':')
:left : right:
+select concat(':',trim(LEADING FROM ' left'),':',trim(TRAILING FROM ' right '),':');
concat(':',trim(LEADING FROM ' left'),':',trim(TRAILING FROM ' right '),':')
:left: right:
+select concat(':',trim(' m '),':',trim(BOTH FROM ' y '),':',trim('*' FROM '*s*'),':');
concat(':',trim(' m '),':',trim(BOTH FROM ' y '),':',trim('*' FROM '*s*'),':')
:m:y:s:
+select concat(':',trim(BOTH 'ab' FROM 'ababmyabab'),':',trim(BOTH '*' FROM '***sql'),':');
concat(':',trim(BOTH 'ab' FROM 'ababmyabab'),':',trim(BOTH '*' FROM '***sql'),':')
:my:sql:
+select concat(':',trim(LEADING '.*' FROM '.*my'),':',trim(TRAILING '.*' FROM 'sql.*.*'),':');
concat(':',trim(LEADING '.*' FROM '.*my'),':',trim(TRAILING '.*' FROM 'sql.*.*'),':')
:my:sql:
+select TRIM("foo" FROM "foo"), TRIM("foo" FROM "foook"), TRIM("foo" FROM "okfoo");
TRIM("foo" FROM "foo") TRIM("foo" FROM "foook") TRIM("foo" FROM "okfoo")
ok ok
+select concat_ws(', ','monty','was here','again');
concat_ws(', ','monty','was here','again')
monty, was here, again
+select concat_ws(NULL,'a'),concat_ws(',',NULL,'');
concat_ws(NULL,'a') concat_ws(',',NULL,'')
NULL
+select concat_ws(',','',NULL,'a');
concat_ws(',','',NULL,'a')
-a
+,a
+SELECT CONCAT('"',CONCAT_WS('";"',repeat('a',60),repeat('b',60),repeat('c',60),repeat('d',100)), '"');
CONCAT('"',CONCAT_WS('";"',repeat('a',60),repeat('b',60),repeat('c',60),repeat('d',100)), '"')
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es');
insert('txs',2,1,'hi') insert('is ',4,0,'a') insert('txxxxt',2,4,'es')
this is a test
+select replace('aaaa','a','b'),replace('aaaa','aa','b'),replace('aaaa','a','bb'),replace('aaaa','','b'),replace('bbbb','a','c');
replace('aaaa','a','b') replace('aaaa','aa','b') replace('aaaa','a','bb') replace('aaaa','','b') replace('bbbb','a','c')
bbbb bb bbbbbbbb aaaa bbbb
+select replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL') ;
replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL')
this is a REAL test
+select soundex(''),soundex('he'),soundex('hello all folks');
soundex('') soundex('he') soundex('hello all folks')
H000 H4142
-password('test') length(encrypt('test')) encrypt('test','aa')
-378b243e220ca493 13 aaqPiZY5xR5l.
+select md5('hello');
md5('hello')
5d41402abc4b2a76b9719d911017c592
+select sha('abc');
+sha('abc')
+a9993e364706816aba3e25717850c26c9cd0d89d
+select sha1('abc');
+sha1('abc')
+a9993e364706816aba3e25717850c26c9cd0d89d
+select aes_decrypt(aes_encrypt('abc','1'),'1');
+aes_decrypt(aes_encrypt('abc','1'),'1')
+abc
+select aes_decrypt(aes_encrypt('abc','1'),1);
+aes_decrypt(aes_encrypt('abc','1'),1)
+abc
+select aes_encrypt(NULL,"a");
+aes_encrypt(NULL,"a")
+NULL
+select aes_encrypt("a",NULL);
+aes_encrypt("a",NULL)
+NULL
+select aes_decrypt(NULL,"a");
+aes_decrypt(NULL,"a")
+NULL
+select aes_decrypt("a",NULL);
+aes_decrypt("a",NULL)
+NULL
+select aes_decrypt("a","a");
+aes_decrypt("a","a")
+NULL
+select aes_decrypt(aes_encrypt("","a"),"a");
+aes_decrypt(aes_encrypt("","a"),"a")
+
+select repeat('monty',5),concat('*',space(5),'*');
repeat('monty',5) concat('*',space(5),'*')
montymontymontymontymonty * *
+select reverse('abc'),reverse('abcd');
reverse('abc') reverse('abcd')
cba dcba
-rpad('a',4,'1') rpad('a',4,'12') rpad('abcd',3,'12')
-a111 a121 abc
-lpad('a',4,'1') lpad('a',4,'12') lpad('abcd',3,'12')
-111a 121a abc
+select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12'), rpad(11, 10 , 22), rpad("ab", 10, 22);
+rpad('a',4,'1') rpad('a',4,'12') rpad('abcd',3,'12') rpad(11, 10 , 22) rpad("ab", 10, 22)
+a111 a121 abc 1122222222 ab22222222
+select lpad('a',4,'1'),lpad('a',4,'12'),lpad('abcd',3,'12'), lpad(11, 10 , 22);
+lpad('a',4,'1') lpad('a',4,'12') lpad('abcd',3,'12') lpad(11, 10 , 22)
+111a 121a abc 2222222211
+select rpad(741653838,17,'0'),lpad(741653838,17,'0');
rpad(741653838,17,'0') lpad(741653838,17,'0')
74165383800000000 00000000741653838
+select rpad('abcd',7,'ab'),lpad('abcd',7,'ab');
rpad('abcd',7,'ab') lpad('abcd',7,'ab')
abcdaba abaabcd
+select rpad('abcd',1,'ab'),lpad('abcd',1,'ab');
rpad('abcd',1,'ab') lpad('abcd',1,'ab')
a a
+select rpad('STRING', 20, CONCAT('p','a','d') );
+rpad('STRING', 20, CONCAT('p','a','d') )
+STRINGpadpadpadpadpa
+select lpad('STRING', 20, CONCAT('p','a','d') );
+lpad('STRING', 20, CONCAT('p','a','d') )
+padpadpadpadpaSTRING
+select LEAST(NULL,'HARRY','HARRIOT',NULL,'HAROLD'),GREATEST(NULL,'HARRY','HARRIOT',NULL,'HAROLD');
LEAST(NULL,'HARRY','HARRIOT',NULL,'HAROLD') GREATEST(NULL,'HARRY','HARRIOT',NULL,'HAROLD')
HAROLD HARRY
+select least(1,2,3) | greatest(16,32,8), least(5,4)*1,greatest(-1.0,1.0)*1,least(3,2,1)*1.0,greatest(1,1.1,1.0),least("10",9),greatest("A","B","0");
least(1,2,3) | greatest(16,32,8) least(5,4)*1 greatest(-1.0,1.0)*1 least(3,2,1)*1.0 greatest(1,1.1,1.0) least("10",9) greatest("A","B","0")
33 4 1.0 1.0 1.1 9 B
+select decode(encode(repeat("a",100000),"monty"),"monty")=repeat("a",100000);
decode(encode(repeat("a",100000),"monty"),"monty")=repeat("a",100000)
1
+select decode(encode("abcdef","monty"),"monty")="abcdef";
decode(encode("abcdef","monty"),"monty")="abcdef"
1
+select quote('\'\"\\test');
+quote('\'\"\\test')
+'\'"\\test'
+select quote(concat('abc\'', '\\cba'));
+quote(concat('abc\'', '\\cba'))
+'abc\'\\cba'
+select quote(1/0), quote('\0\Z');
+quote(1/0) quote('\0\Z')
+NULL '\0\Z'
+select length(quote(concat(char(0),"test")));
+length(quote(concat(char(0),"test")))
+8
+select hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235))));
+hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235))))
+27E0E3E6E7E8EAEB27
+select reverse("");
reverse("")
+select insert("aa",100,1,"b"),insert("aa",1,3,"b"),left("aa",-1),substring("a",1,2);
insert("aa",100,1,"b") insert("aa",1,3,"b") left("aa",-1) substring("a",1,2)
aa b a
+select elt(2,1),field(NULL,"a","b","c"),reverse("");
elt(2,1) field(NULL,"a","b","c") reverse("")
NULL 0
+select locate("a","b",2),locate("","a",1);
locate("a","b",2) locate("","a",1)
0 1
+select ltrim("a"),rtrim("a"),trim(BOTH "" from "a"),trim(BOTH " " from "a");
ltrim("a") rtrim("a") trim(BOTH "" from "a") trim(BOTH " " from "a")
a a a a
+select concat("1","2")|0,concat("1",".5")+0.0;
concat("1","2")|0 concat("1",".5")+0.0
12 1.5
+select substring_index("www.tcx.se","",3);
substring_index("www.tcx.se","",3)
+select length(repeat("a",100000000)),length(repeat("a",1000*64));
length(repeat("a",100000000)) length(repeat("a",1000*64))
NULL 64000
+select position("0" in "baaa" in (1)),position("0" in "1" in (1,2,3)),position("sql" in ("mysql"));
position("0" in "baaa" in (1)) position("0" in "1" in (1,2,3)) position("sql" in ("mysql"))
1 0 3
+select position(("1" in (1,2,3)) in "01");
position(("1" in (1,2,3)) in "01")
2
+select length(repeat("a",65500)),length(concat(repeat("a",32000),repeat("a",32000))),length(replace("aaaaa","a",concat(repeat("a",10000)))),length(insert(repeat("a",40000),1,30000,repeat("b",50000)));
length(repeat("a",65500)) length(concat(repeat("a",32000),repeat("a",32000))) length(replace("aaaaa","a",concat(repeat("a",10000)))) length(insert(repeat("a",40000),1,30000,repeat("b",50000)))
65500 64000 50000 60000
+select length(repeat("a",1000000)),length(concat(repeat("a",32000),repeat("a",32000),repeat("a",32000))),length(replace("aaaaa","a",concat(repeat("a",32000)))),length(insert(repeat("a",48000),1,1000,repeat("a",48000)));
length(repeat("a",1000000)) length(concat(repeat("a",32000),repeat("a",32000),repeat("a",32000))) length(replace("aaaaa","a",concat(repeat("a",32000)))) length(insert(repeat("a",48000),1,1000,repeat("a",48000)))
1000000 96000 160000 95000
+create table t1 ( domain char(50) );
+insert into t1 VALUES ("hello.de" ), ("test.de" );
+select domain from t1 where concat('@', trim(leading '.' from concat('.', domain))) = '@hello.de';
domain
hello.de
+select domain from t1 where concat('@', trim(leading '.' from concat('.', domain))) = '@test.de';
domain
test.de
+drop table t1;
+CREATE TABLE t1 (
+id int(10) unsigned NOT NULL,
+title varchar(255) default NULL,
+prio int(10) unsigned default NULL,
+category int(10) unsigned default NULL,
+program int(10) unsigned default NULL,
+bugdesc text,
+created datetime default NULL,
+modified timestamp(14) NOT NULL,
+bugstatus int(10) unsigned default NULL,
+submitter int(10) unsigned default NULL
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'Link',1,1,1,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa','2001-02-28 08:40:16',20010228084016,0,4);
+SELECT CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter), '"') FROM t1;
CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter), '"')
"Link";"1";"1";"1";"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";"2001-02-28 08:40:16";"20010228084016";"0";"4"
+SELECT CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugstatus,submitter), '"') FROM t1;
CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugstatus,submitter), '"')
"Link";"1";"1";"1";"0";"4"
+SELECT CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter) FROM t1;
CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter)
Link";"1";"1";"1";"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";"2001-02-28 08:40:16";"20010228084016";"0";"4
+SELECT bugdesc, REPLACE(bugdesc, 'xxxxxxxxxxxxxxxxxxxx', 'bbbbbbbbbbbbbbbbbbbb') from t1 group by bugdesc;
+bugdesc REPLACE(bugdesc, 'xxxxxxxxxxxxxxxxxxxx', 'bbbbbbbbbbbbbbbbbbbb')
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+drop table t1;
+CREATE TABLE t1 (id int(11) NOT NULL auto_increment, tmp text NOT NULL, KEY id (id)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
+SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
+1
+DROP TABLE t1;
+CREATE TABLE t1 (
+wid int(10) unsigned NOT NULL auto_increment,
+data_podp date default NULL,
+status_wnio enum('nowy','podp','real','arch') NOT NULL default 'nowy',
+PRIMARY KEY(wid),
+);
+INSERT INTO t1 VALUES (8,NULL,'real');
+INSERT INTO t1 VALUES (9,NULL,'nowy');
+SELECT elt(status_wnio,data_podp) FROM t1 GROUP BY wid;
+elt(status_wnio,data_podp)
+NULL
+NULL
+DROP TABLE t1;
+CREATE TABLE t1 (
+title text
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('Congress reconvenes in September to debate welfare and adult education');
+INSERT INTO t1 VALUES ('House passes the CAREERS bill');
+SELECT CONCAT("</a>",RPAD("",(55 - LENGTH(title)),".")) from t1;
+CONCAT("</a>",RPAD("",(55 - LENGTH(title)),"."))
+NULL
+</a>..........................
+DROP TABLE t1;
+CREATE TABLE t1 (i int, j int);
+INSERT INTO t1 VALUES (1,1),(2,2);
+SELECT DISTINCT i, ELT(j, '345', '34') FROM t1;
+i ELT(j, '345', '34')
+1 345
+2 34
+DROP TABLE t1;
diff --git a/mysql-test/r/func_system.result b/mysql-test/r/func_system.result
index c6ec28bfd34..5ea4ed5e4e0 100644
--- a/mysql-test/r/func_system.result
+++ b/mysql-test/r/func_system.result
@@ -1,4 +1,6 @@
-database() user()
-test root@localhost
+select database(),user() like "%@%";
+database() user() like "%@%"
+test 1
+select version()>="3.23.29";
version()>="3.23.29"
1
diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index 586e345ea10..e11eaa0d246 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -1,34 +1,71 @@
+select 0=0,1>0,1>=1,1<0,1<=0,1!=0,strcmp("abc","abcd"),strcmp("b","a"),strcmp("a","a") ;
0=0 1>0 1>=1 1<0 1<=0 1!=0 strcmp("abc","abcd") strcmp("b","a") strcmp("a","a")
1 1 1 0 0 1 -1 1 0
+select "a"<"b","a"<="b","b">="a","b">"a","a"="A","a"<>"b";
"a"<"b" "a"<="b" "b">="a" "b">"a" "a"="A" "a"<>"b"
1 1 1 1 1 1
+select "a "="A", "A "="a", "a " <= "A b";
"a "="A" "A "="a" "a " <= "A b"
1 1 1
+select "abc" like "a%", "abc" not like "%d%", "a%" like "a\%","abc%" like "a%\%","abcd" like "a%b_%d", "a" like "%%a","abcde" like "a%_e","abc" like "abc%";
"abc" like "a%" "abc" not like "%d%" "a%" like "a\%" "abc%" like "a%\%" "abcd" like "a%b_%d" "a" like "%%a" "abcde" like "a%_e" "abc" like "abc%"
1 1 1 1 1 1 1 1
+select "a" like "%%b","a" like "%%ab","ab" like "a\%", "ab" like "_", "ab" like "ab_", "abc" like "%_d", "abc" like "abc%d";
"a" like "%%b" "a" like "%%ab" "ab" like "a\%" "ab" like "_" "ab" like "ab_" "abc" like "%_d" "abc" like "abc%d"
0 0 0 0 0 0 0
+select '?' like '|%', '?' like '|%' ESCAPE '|', '%' like '|%', '%' like '|%' ESCAPE '|', '%' like '%';
'?' like '|%' '?' like '|%' ESCAPE '|' '%' like '|%' '%' like '|%' ESCAPE '|' '%' like '%'
0 0 0 1 1
+select 'abc' like '%c','abcabc' like '%c', "ab" like "", "ab" like "a", "ab" like "ab";
'abc' like '%c' 'abcabc' like '%c' "ab" like "" "ab" like "a" "ab" like "ab"
1 1 0 0 1
+select "Det här är svenska" regexp "h[[:alpha:]]+r", "aba" regexp "^(a|b)*$";
"Det här är svenska" regexp "h[[:alpha:]]+r" "aba" regexp "^(a|b)*$"
1 1
+select "aba" regexp concat("^","a");
"aba" regexp concat("^","a")
1
+select !0,NOT 0=1,!(0=0),1 AND 1,1 && 0,0 OR 1,1 || NULL, 1=1 or 1=1 and 1=0;
!0 NOT 0=1 !(0=0) 1 AND 1 1 && 0 0 OR 1 1 || NULL 1=1 or 1=1 and 1=0
1 1 0 1 0 1 1 1
+select 2 between 1 and 3, "monty" between "max" and "my",2=2 and "monty" between "max" and "my" and 3=3;
2 between 1 and 3 "monty" between "max" and "my" 2=2 and "monty" between "max" and "my" and 3=3
1 1 1
+select 'b' between 'a' and 'c', 'B' between 'a' and 'c';
'b' between 'a' and 'c' 'B' between 'a' and 'c'
1 1
+select 2 in (3,2,5,9,5,1),"monty" in ("david","monty","allan"), 1.2 in (1.4,1.2,1.0);
2 in (3,2,5,9,5,1) "monty" in ("david","monty","allan") 1.2 in (1.4,1.2,1.0)
1 1 1
+select -1.49 or -1.49,0.6 or 0.6;
-1.49 or -1.49 0.6 or 0.6
1 1
+select 3 ^ 11, 1 ^ 1, 1 ^ 0, 1 ^ NULL, NULL ^ 1;
+3 ^ 11 1 ^ 1 1 ^ 0 1 ^ NULL NULL ^ 1
+8 0 1 NULL NULL
+select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL;
+1 XOR 1 1 XOR 0 0 XOR 1 0 XOR 0 NULL XOR 1 1 XOR NULL 0 XOR NULL
+0 1 1 0 NULL NULL NULL
+create table t1 (a int);
+insert t1 values (1);
+select * from t1 where 1 xor 1;
+a
+drop table t1;
+select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1;
5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1
0 1
+select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1;
1 and 2 between 2 and 10 2 between 2 and 10 and 1
1 1
+select 1 and 0 or 2, 2 or 1 and 0;
1 and 0 or 2 2 or 1 and 0
1 1
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 ( faq_group_id int(11) NOT NULL default '0', faq_id int(11) NOT NULL default '0', title varchar(240) default NULL, keywords text, description longblob, solution longblob, status tinyint(4) NOT NULL default '0', access_id smallint(6) default NULL, lang_id smallint(6) NOT NULL default '0', created datetime NOT NULL default '0000-00-00 00:00:00', updated datetime default NULL, last_access datetime default NULL, last_notify datetime default NULL, solved_count int(11) NOT NULL default '0', static_solved int(11) default NULL, solved_1 int(11) default NULL, solved_2 int(11) default NULL, solved_3 int(11) default NULL, solved_4 int(11) default NULL, solved_5 int(11) default NULL, expires datetime default NULL, notes text, assigned_to smallint(6) default NULL, assigned_group smallint(6) default NULL, last_edited_by smallint(6) default NULL, orig_ref_no varchar(15) binary default NULL, c$fundstate smallint(6) default NULL, c$contributor smallint(6) default NULL, UNIQUE KEY t1$faq_id (faq_id), KEY t1$group_id$faq_id (faq_group_id,faq_id), KEY t1$c$fundstate (c$fundstate) ) TYPE=MyISAM;
+INSERT INTO t1 VALUES (82,82,'How to use the DynaVox Usage Counts Feature','usages count, number, corner, white, box, button','<as-html>\r\n<table width=\"100%\" border=\"0\">\r\n <tr>\r\n <td width=\"3%\"> </td>\r\n <td width=\"97%\">\r\n <h3><font face=\"Verdana, Arial, Helvetica, sans-serif\" color=\"#000000\">How \r\n To</font><!-- #BeginEditable \"CS_troubleshoot_question\" --><font face=\"Verdana, Arial, Helvetica, sans-serif\" color=\"#000099\"><font color=\"#000000\">: \r\n Display or Hide the Usage Counts to find out how many times each button is being selected. </font></font><!-- #EndEditable --></h3>\r\n </td>\r\n </tr>\r\n</table>','<as-html>\r\n <table width=\"100%\" border=\"0\">\r\n <tr>\r\n <td width=\"3%\"> </td>\r\n \r\n<td width=\"97%\"><!-- #BeginEditable \"CS_troubleshoot_answer\" --> \r\n \r\n<p><font color=\"#000000\" face=\"Verdana, Arial, Helvetica, sans-serif\">1. Select \r\n the <i>On/Setup</i> button to access the DynaVox Setup Menu.<br>\r\n 2. Select <b>Button Features.</b><br>\r\n 3. Below the <b>OK</b> button is the <b>Usage Counts</b> button.<br>\r\n a. If it says \"Hidden\" then the Usage Counts will not be displayed.<br>\r\n b. If it says \"Displayed\" then the Usage Counts will be shown.<br>\r\n c. Select the <b>Usage Counts</b> Option Ring once and it will toggle \r\n to the alternative option.<br>\r\n 4. Once the correct setting has been chosen, select <b>OK</b> to leave the <i>Button \r\n Features</i> menu.<br>\r\n 5. Select <b>OK</b> out of the <i>Setup</i> menu and return to the communication \r\n page.</font></p>\r\n <p><font color=\"#000000\" face=\"Verdana, Arial, Helvetica, sans-serif\">For \r\n further information on <i>Usage Counts,</i> see the <i>Button Features \r\n Menu Entry</i> in the DynaVox/DynaMyte Reference Manual.</font></p>\r\n<!-- #EndEditable --></td>\r\n </tr>\r\n</table>',4,1,1,'2001-11-16 16:43:34','2002-11-25 12:09:43','2003-07-24 01:04:48',NULL,11,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,11,NULL,NULL,NULL);
+CREATE TABLE t2 ( access_id smallint(6) NOT NULL default '0', name varchar(20) binary default NULL, rank smallint(6) NOT NULL default '0', KEY t2$access_id (access_id) ) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,'Everyone',2),(2,'Help',3),(3,'Customer Support',1);
+SELECT f_acc.rank, a1.rank, a2.rank FROM t1 LEFT JOIN t1 f1 ON (f1.access_id=1 AND f1.faq_group_id = t1.faq_group_id) LEFT JOIN t2 a1 ON (a1.access_id = f1.access_id) LEFT JOIN t1 f2 ON (f2.access_id=3 AND f2.faq_group_id = t1.faq_group_id) LEFT JOIN t2 a2 ON (a2.access_id = f2.access_id), t2 f_acc WHERE LEAST(a1.rank,a2.rank) = f_acc.rank;
+rank rank rank
+2 2 NULL
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index a77d9b2cdff..4715227425e 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -1,227 +1,442 @@
+drop table if exists t1,t2,t3;
+select from_days(to_days("960101")),to_days(960201)-to_days("19960101"),to_days(date_add(curdate(), interval 1 day))-to_days(curdate()),weekday("1997-11-29");
from_days(to_days("960101")) to_days(960201)-to_days("19960101") to_days(date_add(curdate(), interval 1 day))-to_days(curdate()) weekday("1997-11-29")
1996-01-01 31 1 5
+select period_add("9602",-12),period_diff(199505,"9404") ;
period_add("9602",-12) period_diff(199505,"9404")
199502 13
+select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_timestamp(now());
now()-now() weekday(curdate())-weekday(now()) unix_timestamp()-unix_timestamp(now())
0 0 0
+select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0;
from_unixtime(unix_timestamp("1994-03-02 10:11:12")) from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s") from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0
1994-03-02 10:11:12 1994-03-02 10:11:12 19940302101112
+select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
+sec_to_time(time_to_sec("0:30:47")/6.21);
sec_to_time(9001) sec_to_time(9001)+0 time_to_sec("15:12:22") sec_to_time(time_to_sec("0:30:47")/6.21)
02:30:01 23001 54742 00:04:57
+select sec_to_time(time_to_sec('-838:59:59'));
sec_to_time(time_to_sec('-838:59:59'))
-838:59:59
+select now()-curdate()*1000000-curtime();
now()-curdate()*1000000-curtime()
0
+select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
strcmp(current_timestamp(),concat(current_date()," ",current_time()))
0
+select strcmp(localtime(),concat(current_date()," ",current_time()));
+strcmp(localtime(),concat(current_date()," ",current_time()))
+0
+select strcmp(localtimestamp(),concat(current_date()," ",current_time()));
+strcmp(localtimestamp(),concat(current_date()," ",current_time()))
+0
+select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w");
date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")
January Thursday 2nd 1997 97 01 02 03 04 05 4
+select date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w"));
date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w"))
January Thursday 2nd 1997 97 01 02 12 00 00 4
+select dayofmonth("1997-01-02"),dayofmonth(19970323);
dayofmonth("1997-01-02") dayofmonth(19970323)
2 23
+select month("1997-01-02"),year("98-02-03"),dayofyear("1997-12-31");
month("1997-01-02") year("98-02-03") dayofyear("1997-12-31")
1 1998 365
+select month("2001-02-00"),year("2001-00-00");
month("2001-02-00") year("2001-00-00")
2 2001
+select DAYOFYEAR("1997-03-03"), WEEK("1998-03-03"), QUARTER(980303);
DAYOFYEAR("1997-03-03") WEEK("1998-03-03") QUARTER(980303)
62 9 1
+select HOUR("1997-03-03 23:03:22"), MINUTE("23:03:22"), SECOND(230322);
HOUR("1997-03-03 23:03:22") MINUTE("23:03:22") SECOND(230322)
23 3 22
+select week(19980101),week(19970101),week(19980101,1),week(19970101,1);
week(19980101) week(19970101) week(19980101,1) week(19970101,1)
-0 1 1 1
+0 0 1 1
+select week(19981231),week(19971231),week(19981231,1),week(19971231,1);
week(19981231) week(19971231) week(19981231,1) week(19971231,1)
-52 53 53 53
+52 52 53 53
+select week(19950101),week(19950101,1);
week(19950101) week(19950101,1)
1 0
+select yearweek('1981-12-31',1),yearweek('1982-01-01',1),yearweek('1982-12-31',1),yearweek('1983-01-01',1);
yearweek('1981-12-31',1) yearweek('1982-01-01',1) yearweek('1982-12-31',1) yearweek('1983-01-01',1)
198153 198153 198252 198252
+select yearweek('1987-01-01',1),yearweek('1987-01-01');
+yearweek('1987-01-01',1) yearweek('1987-01-01')
+198701 198652
+select week("2000-01-01",0) as '2000', week("2001-01-01",0) as '2001', week("2002-01-01",0) as '2002',week("2003-01-01",0) as '2003', week("2004-01-01",0) as '2004', week("2005-01-01",0) as '2005', week("2006-01-01",0) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+0 0 0 0 0 0 1
+select week("2000-01-06",0) as '2000', week("2001-01-06",0) as '2001', week("2002-01-06",0) as '2002',week("2003-01-06",0) as '2003', week("2004-01-06",0) as '2004', week("2005-01-06",0) as '2005', week("2006-01-06",0) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+1 0 1 1 1 1 1
+select week("2000-01-01",1) as '2000', week("2001-01-01",1) as '2001', week("2002-01-01",1) as '2002',week("2003-01-01",1) as '2003', week("2004-01-01",1) as '2004', week("2005-01-01",1) as '2005', week("2006-01-01",1) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+0 1 1 1 1 0 0
+select week("2000-01-06",1) as '2000', week("2001-01-06",1) as '2001', week("2002-01-06",1) as '2002',week("2003-01-06",1) as '2003', week("2004-01-06",1) as '2004', week("2005-01-06",1) as '2005', week("2006-01-06",1) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+1 1 1 2 2 1 1
+select yearweek("2000-01-01",0) as '2000', yearweek("2001-01-01",0) as '2001', yearweek("2002-01-01",0) as '2002',yearweek("2003-01-01",0) as '2003', yearweek("2004-01-01",0) as '2004', yearweek("2005-01-01",0) as '2005', yearweek("2006-01-01",0) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+199952 200053 200152 200252 200352 200452 200601
+select yearweek("2000-01-06",0) as '2000', yearweek("2001-01-06",0) as '2001', yearweek("2002-01-06",0) as '2002',yearweek("2003-01-06",0) as '2003', yearweek("2004-01-06",0) as '2004', yearweek("2005-01-06",0) as '2005', yearweek("2006-01-06",0) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+200001 200053 200201 200301 200401 200501 200601
+select yearweek("2000-01-01",1) as '2000', yearweek("2001-01-01",1) as '2001', yearweek("2002-01-01",1) as '2002',yearweek("2003-01-01",1) as '2003', yearweek("2004-01-01",1) as '2004', yearweek("2005-01-01",1) as '2005', yearweek("2006-01-01",1) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+199952 200101 200201 200301 200401 200453 200552
+select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', yearweek("2002-01-06",1) as '2002',yearweek("2003-01-06",1) as '2003', yearweek("2004-01-06",1) as '2004', yearweek("2005-01-06",1) as '2005', yearweek("2006-01-06",1) as '2006';
+2000 2001 2002 2003 2004 2005 2006
+200001 200101 200201 200302 200402 200501 200601
+select week(19981231,2), week(19981231,3), week(20000101,2), week(20000101,3);
+week(19981231,2) week(19981231,3) week(20000101,2) week(20000101,3)
+52 53 52 52
+select week(20001231,2),week(20001231,3);
+week(20001231,2) week(20001231,3)
+53 52
+select week(19981231,0) as '0', week(19981231,1) as '1', week(19981231,2) as '2', week(19981231,3) as '3', week(19981231,4) as '4', week(19981231,5) as '5', week(19981231,6) as '6', week(19981231,7) as '7';
+0 1 2 3 4 5 6 7
+52 53 52 53 52 52 52 52
+select week(20000101,0) as '0', week(20000101,1) as '1', week(20000101,2) as '2', week(20000101,3) as '3', week(20000101,4) as '4', week(20000101,5) as '5', week(20000101,6) as '6', week(20000101,7) as '7';
+0 1 2 3 4 5 6 7
+0 0 52 52 0 0 52 52
+select week(20000106,0) as '0', week(20000106,1) as '1', week(20000106,2) as '2', week(20000106,3) as '3', week(20000106,4) as '4', week(20000106,5) as '5', week(20000106,6) as '6', week(20000106,7) as '7';
+0 1 2 3 4 5 6 7
+1 1 1 1 1 1 1 1
+select week(20001231,0) as '0', week(20001231,1) as '1', week(20001231,2) as '2', week(20001231,3) as '3', week(20001231,4) as '4', week(20001231,5) as '5', week(20001231,6) as '6', week(20001231,7) as '7';
+0 1 2 3 4 5 6 7
+53 52 53 52 53 52 1 52
+select week(20010101,0) as '0', week(20010101,1) as '1', week(20010101,2) as '2', week(20010101,3) as '3', week(20010101,4) as '4', week(20010101,5) as '5', week(20010101,6) as '6', week(20010101,7) as '7';
+0 1 2 3 4 5 6 7
+0 1 53 1 1 1 1 1
+select yearweek(20001231,0), yearweek(20001231,1), yearweek(20001231,2), yearweek(20001231,3), yearweek(20001231,4), yearweek(20001231,5), yearweek(20001231,6), yearweek(20001231,7);
+yearweek(20001231,0) yearweek(20001231,1) yearweek(20001231,2) yearweek(20001231,3) yearweek(20001231,4) yearweek(20001231,5) yearweek(20001231,6) yearweek(20001231,7)
+200053 200052 200053 200052 200101 200052 200101 200052
+set default_week_format = 6;
+select week(20001231), week(20001231,6);
+week(20001231) week(20001231,6)
+1 1
+set default_week_format = 0;
+set default_week_format = 2;
+select week(20001231),week(20001231,2),week(20001231,0);
+week(20001231) week(20001231,2) week(20001231,0)
+53 53 53
+set default_week_format = 0;
+select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v');
date_format('1998-12-31','%x-%v') date_format('1999-01-01','%x-%v')
1998-53 1998-53
+select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v');
date_format('1999-12-31','%x-%v') date_format('2000-01-01','%x-%v')
1999-52 1999-52
-yearweek('1987-01-01',1) yearweek('1987-01-01')
-198701 198653
+select dayname("1962-03-03"),dayname("1962-03-03")+0;
dayname("1962-03-03") dayname("1962-03-03")+0
Saturday 5
+select monthname("1972-03-04"),monthname("1972-03-04")+0;
monthname("1972-03-04") monthname("1972-03-04")+0
March 3
+select time_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
00|12|0|12|00|AM|12:00:00 AM|00|00:00:00
+select time_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
01|01|1|1|02|AM|01:02:03 AM|03|01:02:03
+select time_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
13|01|13|1|14|PM|01:14:15 PM|15|13:14:15
+select time_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T');
time_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T')
01|01|1|1|00|AM|01:00:15 AM|15|01:00:15
+select date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w');
date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w')
13|01|13|1|14|PM|01:14:15 PM|15|13:14:15| January|Saturday|31st|1998|98|Sat|Jan|031|01|31|01|15|6
+select date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w');
date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w')
NULL
+select date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND);
date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)
1998-01-01 00:00:00
+select date_add("1997-12-31 23:59:59",INTERVAL 1 MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL 1 MINUTE)
1998-01-01 00:00:59
+select date_add("1997-12-31 23:59:59",INTERVAL 1 HOUR);
date_add("1997-12-31 23:59:59",INTERVAL 1 HOUR)
1998-01-01 00:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL 1 DAY);
date_add("1997-12-31 23:59:59",INTERVAL 1 DAY)
1998-01-01 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL 1 MONTH);
date_add("1997-12-31 23:59:59",INTERVAL 1 MONTH)
1998-01-31 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL 1 YEAR);
date_add("1997-12-31 23:59:59",INTERVAL 1 YEAR)
1998-12-31 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL "1:1" MINUTE_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "1:1" MINUTE_SECOND)
1998-01-01 00:01:00
+select date_add("1997-12-31 23:59:59",INTERVAL "1:1" HOUR_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL "1:1" HOUR_MINUTE)
1998-01-01 01:00:59
+select date_add("1997-12-31 23:59:59",INTERVAL "1:1" DAY_HOUR);
date_add("1997-12-31 23:59:59",INTERVAL "1:1" DAY_HOUR)
1998-01-02 00:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL "1 1" YEAR_MONTH);
date_add("1997-12-31 23:59:59",INTERVAL "1 1" YEAR_MONTH)
1999-01-31 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL "1:1:1" HOUR_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "1:1:1" HOUR_SECOND)
1998-01-01 01:01:00
+select date_add("1997-12-31 23:59:59",INTERVAL "1 1:1" DAY_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL "1 1:1" DAY_MINUTE)
1998-01-02 01:00:59
+select date_add("1997-12-31 23:59:59",INTERVAL "1 1:1:1" DAY_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "1 1:1:1" DAY_SECOND)
1998-01-02 01:01:00
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL 1 SECOND)
1997-12-31 23:59:59
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 MINUTE);
date_sub("1998-01-01 00:00:00",INTERVAL 1 MINUTE)
1997-12-31 23:59:00
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 HOUR);
date_sub("1998-01-01 00:00:00",INTERVAL 1 HOUR)
1997-12-31 23:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 DAY);
date_sub("1998-01-01 00:00:00",INTERVAL 1 DAY)
1997-12-31 00:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 MONTH);
date_sub("1998-01-01 00:00:00",INTERVAL 1 MONTH)
1997-12-01 00:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL 1 YEAR);
date_sub("1998-01-01 00:00:00",INTERVAL 1 YEAR)
1997-01-01 00:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL "1:1" MINUTE_SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1" MINUTE_SECOND)
1997-12-31 23:58:59
+select date_sub("1998-01-01 00:00:00",INTERVAL "1:1" HOUR_MINUTE);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1" HOUR_MINUTE)
1997-12-31 22:59:00
+select date_sub("1998-01-01 00:00:00",INTERVAL "1:1" DAY_HOUR);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1" DAY_HOUR)
1997-12-30 23:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL "1 1" YEAR_MONTH);
date_sub("1998-01-01 00:00:00",INTERVAL "1 1" YEAR_MONTH)
1996-12-01 00:00:00
+select date_sub("1998-01-01 00:00:00",INTERVAL "1:1:1" HOUR_SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL "1:1:1" HOUR_SECOND)
1997-12-31 22:58:59
+select date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1" DAY_MINUTE);
date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1" DAY_MINUTE)
1997-12-30 22:59:00
+select date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1:1" DAY_SECOND);
date_sub("1998-01-01 00:00:00",INTERVAL "1 1:1:1" DAY_SECOND)
1997-12-30 22:58:59
+select date_add("1997-12-31 23:59:59",INTERVAL 100000 SECOND);
date_add("1997-12-31 23:59:59",INTERVAL 100000 SECOND)
1998-01-02 03:46:39
+select date_add("1997-12-31 23:59:59",INTERVAL -100000 MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL -100000 MINUTE)
1997-10-23 13:19:59
+select date_add("1997-12-31 23:59:59",INTERVAL 100000 HOUR);
date_add("1997-12-31 23:59:59",INTERVAL 100000 HOUR)
2009-05-29 15:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL -100000 DAY);
date_add("1997-12-31 23:59:59",INTERVAL -100000 DAY)
1724-03-17 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL 100000 MONTH);
date_add("1997-12-31 23:59:59",INTERVAL 100000 MONTH)
NULL
+select date_add("1997-12-31 23:59:59",INTERVAL -100000 YEAR);
date_add("1997-12-31 23:59:59",INTERVAL -100000 YEAR)
NULL
+select date_add("1997-12-31 23:59:59",INTERVAL "10000:1" MINUTE_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "10000:1" MINUTE_SECOND)
1998-01-07 22:40:00
+select date_add("1997-12-31 23:59:59",INTERVAL "-10000:1" HOUR_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL "-10000:1" HOUR_MINUTE)
1996-11-10 07:58:59
+select date_add("1997-12-31 23:59:59",INTERVAL "10000:1" DAY_HOUR);
date_add("1997-12-31 23:59:59",INTERVAL "10000:1" DAY_HOUR)
2025-05-19 00:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL "-100 1" YEAR_MONTH);
date_add("1997-12-31 23:59:59",INTERVAL "-100 1" YEAR_MONTH)
1897-11-30 23:59:59
+select date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "10000:99:99" HOUR_SECOND)
1999-02-21 17:40:38
+select date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE);
date_add("1997-12-31 23:59:59",INTERVAL " -10000 99:99" DAY_MINUTE)
1970-08-11 19:20:59
+select date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL "10000 99:99:99" DAY_SECOND)
2025-05-23 04:40:38
+select "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
"1997-12-31 23:59:59" + INTERVAL 1 SECOND
1998-01-01 00:00:00
+select INTERVAL 1 DAY + "1997-12-31";
INTERVAL 1 DAY + "1997-12-31"
1998-01-01
+select "1998-01-01 00:00:00" - INTERVAL 1 SECOND;
"1998-01-01 00:00:00" - INTERVAL 1 SECOND
1997-12-31 23:59:59
+select date_sub("1998-01-02",INTERVAL 31 DAY);
date_sub("1998-01-02",INTERVAL 31 DAY)
1997-12-02
+select date_add("1997-12-31",INTERVAL 1 SECOND);
date_add("1997-12-31",INTERVAL 1 SECOND)
1997-12-31 00:00:01
+select date_add("1997-12-31",INTERVAL 1 DAY);
date_add("1997-12-31",INTERVAL 1 DAY)
1998-01-01
+select date_add(NULL,INTERVAL 100000 SECOND);
date_add(NULL,INTERVAL 100000 SECOND)
NULL
+select date_add("1997-12-31 23:59:59",INTERVAL NULL SECOND);
date_add("1997-12-31 23:59:59",INTERVAL NULL SECOND)
NULL
+select date_add("1997-12-31 23:59:59",INTERVAL NULL MINUTE_SECOND);
date_add("1997-12-31 23:59:59",INTERVAL NULL MINUTE_SECOND)
NULL
+select date_add("9999-12-31 23:59:59",INTERVAL 1 SECOND);
date_add("9999-12-31 23:59:59",INTERVAL 1 SECOND)
NULL
+select date_sub("0000-00-00 00:00:00",INTERVAL 1 SECOND);
date_sub("0000-00-00 00:00:00",INTERVAL 1 SECOND)
NULL
+select date_add('1998-01-30',Interval 1 month);
date_add('1998-01-30',Interval 1 month)
1998-02-28
+select date_add('1998-01-30',Interval '2:1' year_month);
date_add('1998-01-30',Interval '2:1' year_month)
2000-02-29
+select date_add('1996-02-29',Interval '1' year);
date_add('1996-02-29',Interval '1' year)
1997-02-28
+select extract(YEAR FROM "1999-01-02 10:11:12");
extract(YEAR FROM "1999-01-02 10:11:12")
1999
+select extract(YEAR_MONTH FROM "1999-01-02");
extract(YEAR_MONTH FROM "1999-01-02")
199901
+select extract(DAY FROM "1999-01-02");
extract(DAY FROM "1999-01-02")
2
+select extract(DAY_HOUR FROM "1999-01-02 10:11:12");
extract(DAY_HOUR FROM "1999-01-02 10:11:12")
210
+select extract(DAY_MINUTE FROM "02 10:11:12");
extract(DAY_MINUTE FROM "02 10:11:12")
21011
+select extract(DAY_SECOND FROM "225 10:11:12");
extract(DAY_SECOND FROM "225 10:11:12")
225101112
+select extract(HOUR FROM "1999-01-02 10:11:12");
extract(HOUR FROM "1999-01-02 10:11:12")
10
+select extract(HOUR_MINUTE FROM "10:11:12");
extract(HOUR_MINUTE FROM "10:11:12")
1011
+select extract(HOUR_SECOND FROM "10:11:12");
extract(HOUR_SECOND FROM "10:11:12")
101112
+select extract(MINUTE FROM "10:11:12");
extract(MINUTE FROM "10:11:12")
11
+select extract(MINUTE_SECOND FROM "10:11:12");
extract(MINUTE_SECOND FROM "10:11:12")
1112
+select extract(SECOND FROM "1999-01-02 10:11:12");
extract(SECOND FROM "1999-01-02 10:11:12")
12
+select extract(MONTH FROM "2001-02-00");
extract(MONTH FROM "2001-02-00")
2
+create table t1 (ctime varchar(20));
+insert into t1 values ('2001-01-12 12:23:40');
+select ctime, hour(ctime) from t1;
ctime hour(ctime)
2001-01-12 12:23:40 12
+select ctime from t1 where extract(MONTH FROM ctime) = 1 AND extract(YEAR FROM ctime) = 2001;
+ctime
+2001-01-12 12:23:40
+drop table t1;
+create table t1 (id int);
+create table t2 (id int, date date);
+insert into t1 values (1);
+insert into t2 values (1, "0000-00-00");
+insert into t1 values (2);
+insert into t2 values (2, "2000-01-01");
+select monthname(date) from t1 inner join t2 on t1.id = t2.id;
monthname(date)
NULL
January
+select monthname(date) from t1 inner join t2 on t1.id = t2.id order by t1.id;
monthname(date)
NULL
January
+drop table t1,t2;
+CREATE TABLE t1 (updated text) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('');
+SELECT month(updated) from t1;
month(updated)
NULL
+SELECT year(updated) from t1;
year(updated)
NULL
+drop table t1;
+create table t1 (d date, dt datetime, t timestamp, c char(10));
+insert into t1 values ("0000-00-00", "0000-00-00", "0000-00-00", "0000-00-00");
+select dayofyear("0000-00-00"),dayofyear(d),dayofyear(dt),dayofyear(t),dayofyear(c) from t1;
dayofyear("0000-00-00") dayofyear(d) dayofyear(dt) dayofyear(t) dayofyear(c)
NULL NULL NULL NULL NULL
+select dayofmonth("0000-00-00"),dayofmonth(d),dayofmonth(dt),dayofmonth(t),dayofmonth(c) from t1;
dayofmonth("0000-00-00") dayofmonth(d) dayofmonth(dt) dayofmonth(t) dayofmonth(c)
0 0 0 0 0
+select month("0000-00-00"),month(d),month(dt),month(t),month(c) from t1;
month("0000-00-00") month(d) month(dt) month(t) month(c)
0 0 0 0 0
+select quarter("0000-00-00"),quarter(d),quarter(dt),quarter(t),quarter(c) from t1;
quarter("0000-00-00") quarter(d) quarter(dt) quarter(t) quarter(c)
0 0 0 0 0
+select week("0000-00-00"),week(d),week(dt),week(t),week(c) from t1;
week("0000-00-00") week(d) week(dt) week(t) week(c)
NULL NULL NULL NULL NULL
+select year("0000-00-00"),year(d),year(dt),year(t),year(c) from t1;
year("0000-00-00") year(d) year(dt) year(t) year(c)
0 0 0 0 0
+select yearweek("0000-00-00"),yearweek(d),yearweek(dt),yearweek(t),yearweek(c) from t1;
yearweek("0000-00-00") yearweek(d) yearweek(dt) yearweek(t) yearweek(c)
NULL NULL NULL NULL NULL
+select to_days("0000-00-00"),to_days(d),to_days(dt),to_days(t),to_days(c) from t1;
to_days("0000-00-00") to_days(d) to_days(dt) to_days(t) to_days(c)
NULL NULL NULL NULL NULL
+select extract(MONTH FROM "0000-00-00"),extract(MONTH FROM d),extract(MONTH FROM dt),extract(MONTH FROM t),extract(MONTH FROM c) from t1;
extract(MONTH FROM "0000-00-00") extract(MONTH FROM d) extract(MONTH FROM dt) extract(MONTH FROM t) extract(MONTH FROM c)
0 0 0 0 0
+drop table t1;
+CREATE TABLE t1 ( start datetime default NULL);
+INSERT INTO t1 VALUES ('2002-10-21 00:00:00'),('2002-10-28 00:00:00'),('2002-11-04 00:00:00');
+CREATE TABLE t2 ( ctime1 timestamp(14) NOT NULL, ctime2 timestamp(14) NOT NULL);
+INSERT INTO t2 VALUES (20021029165106,20021105164731);
+CREATE TABLE t3 (ctime1 char(19) NOT NULL, ctime2 char(19) NOT NULL);
+INSERT INTO t3 VALUES ("2002-10-29 16:51:06","2002-11-05 16:47:31");
+select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2;
start ctime1 ctime2
+2002-11-04 00:00:00 20021029165106 20021105164731
+select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2;
start ctime1 ctime2
2002-11-04 00:00:00 20021029165106 20021105164731
+select * from t1, t3 where t1.start between t3.ctime1 and t3.ctime2;
start ctime1 ctime2
2002-11-04 00:00:00 2002-10-29 16:51:06 2002-11-05 16:47:31
+drop table t1,t2,t3;
+select @a:=FROM_UNIXTIME(1);
+@a:=FROM_UNIXTIME(1)
+1970-01-01 03:00:01
+select unix_timestamp(@a);
+unix_timestamp(@a)
+1
+select unix_timestamp('1969-12-01 19:00:01');
+unix_timestamp('1969-12-01 19:00:01')
+0
diff --git a/mysql-test/r/func_timestamp.result b/mysql-test/r/func_timestamp.result
index 4d4a5b541ac..d9912f08b72 100644
--- a/mysql-test/r/func_timestamp.result
+++ b/mysql-test/r/func_timestamp.result
@@ -1,3 +1,11 @@
+drop table if exists t1;
+create table t1 (Zeit time, Tag tinyint not null, Monat tinyint not null,
+Jahr smallint not null, index(Tag), index(Monat), index(Jahr) );
+insert into t1 values ("09:26:00",16,9,1998),("09:26:00",16,9,1998);
+SELECT CONCAT(Jahr,'-',Monat,'-',Tag,' ',Zeit) AS Date,
+UNIX_TIMESTAMP(CONCAT(Jahr,'-',Monat,'-',Tag,' ',Zeit)) AS Unix
+FROM t1;
Date Unix
1998-9-16 09:26:00 905927160
1998-9-16 09:26:00 905927160
+drop table t1;
diff --git a/mysql-test/r/gcc296.result b/mysql-test/r/gcc296.result
index 7184bfb9cdc..8f78f70cc1f 100644
--- a/mysql-test/r/gcc296.result
+++ b/mysql-test/r/gcc296.result
@@ -1,5 +1,20 @@
+drop table if exists obory;
+CREATE TABLE obory (
+kodoboru varchar(10) default NULL,
+obor tinytext,
+aobor tinytext,
+UNIQUE INDEX kodoboru (kodoboru),
+FULLTEXT KEY obor (obor),
+FULLTEXT KEY aobor (aobor)
+);
+INSERT INTO obory VALUES ('0101000000','aaa','AAA');
+INSERT INTO obory VALUES ('0102000000','bbb','BBB');
+INSERT INTO obory VALUES ('0103000000','ccc','CCC');
+INSERT INTO obory VALUES ('0104000000','xxx','XXX');
+select * from obory;
kodoboru obor aobor
0101000000 aaa AAA
0102000000 bbb BBB
0103000000 ccc CCC
0104000000 xxx XXX
+drop table obory;
diff --git a/mysql-test/r/gemini.result b/mysql-test/r/gemini.result
deleted file mode 100644
index 0b43b4f5192..00000000000
--- a/mysql-test/r/gemini.result
+++ /dev/null
@@ -1,370 +0,0 @@
-id code name
-1 1 Tim
-2 1 Monty
-3 2 David
-4 2 Erik
-5 3 Sasha
-6 3 Jeremy
-7 4 Matt
-id code name
-2 1 Monty
-3 2 David
-4 2 Erik
-5 3 Sasha
-6 3 Jeremy
-7 4 Matt
-8 1 Sinisa
-id code name
-3 2 David
-4 2 Erik
-5 3 Sasha
-6 3 Jeremy
-7 4 Matt
-8 1 Sinisa
-12 1 Ralph
-id parent_id level
-8 102 2
-9 102 2
-15 102 2
-id parent_id level
-1001 100 0
-1003 101 1
-1004 101 1
-1008 102 2
-1009 102 2
-1017 103 2
-1022 104 2
-1024 104 2
-1028 105 2
-1029 105 2
-1030 105 2
-1031 106 2
-1032 106 2
-1033 106 2
-1203 107 2
-1202 107 2
-1020 103 2
-1157 100 0
-1193 105 2
-1040 107 2
-1002 101 1
-1015 102 2
-1006 101 1
-1034 106 2
-1035 106 2
-1016 103 2
-1007 101 1
-1036 107 2
-1018 103 2
-1026 105 2
-1027 105 2
-1183 104 2
-1038 107 2
-1025 105 2
-1037 107 2
-1021 104 2
-1019 103 2
-1005 101 1
-1179 105 2
-id parent_id level
-1001 100 0
-1003 101 1
-1004 101 1
-1008 102 2
-1010 102 2
-1017 103 2
-1023 104 2
-1024 104 2
-1028 105 2
-1029 105 2
-1030 105 2
-1031 106 2
-1032 106 2
-1033 106 2
-1204 107 2
-1203 107 2
-1020 103 2
-1158 100 0
-1194 105 2
-1041 107 2
-1002 101 1
-1015 102 2
-1006 101 1
-1034 106 2
-1035 106 2
-1016 103 2
-1007 101 1
-1036 107 2
-1018 103 2
-1026 105 2
-1027 105 2
-1184 104 2
-1039 107 2
-1025 105 2
-1038 107 2
-1022 104 2
-1019 103 2
-1005 101 1
-1180 105 2
-id parent_id level
-1008 102 2
-1010 102 2
-1015 102 2
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 6 where used; Using index
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 6 where used
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 6 where used
-level id
-1 1003
-1 1004
-1 1002
-1 1006
-1 1007
-1 1005
-level id parent_id
-1 1003 101
-1 1004 101
-1 1002 101
-1 1006 101
-1 1007 101
-1 1005 101
-gesuchnr benutzer_id
-1 1
-2 1
-a
-2
-user_id name phone ref_email detail
-10292 sanjeev 29153373 sansh777@hotmail.com xxx
-10292 shirish 2333604 shirish@yahoo.com ddsds
-10292 sonali 323232 sonali@bolly.com filmstar
-user_id name phone ref_email detail
-10292 sanjeev 29153373 sansh777@hotmail.com xxx
-10292 shirish 2333604 shirish@yahoo.com ddsds
-10292 sonali 323232 sonali@bolly.com filmstar
-user_id name phone ref_email detail
-10292 sanjeev 29153373 sansh777@hotmail.com xxx
-10292 shirish 2333604 shirish@yahoo.com ddsds
-10292 sonali 323232 sonali@bolly.com filmstar
-10293 shirish 2333604 shirish@yahoo.com ddsds
-user_id name phone ref_email detail
-10293 shirish 2333604 shirish@yahoo.com ddsds
-user_id name phone ref_email detail
-10291 sanjeev 29153373 sansh777@hotmail.com xxx
-a b
-1 3
-2 3
-3 3
-a b
-1 3
-2 3
-3 3
-a b
-a b
-1 3
-2 3
-3 3
-a b
-1 3
-2 3
-3 3
-id ggid email passwd
-1 test1 xxx
-id ggid email passwd
-1 test1 xxx
-id ggid email passwd
-2 test2 yyy
-id parent_id level
-8 102 2
-9 102 2
-15 102 2
-id parent_id level
-1001 100 0
-1003 101 1
-1004 101 1
-1008 102 2
-1024 102 2
-1017 103 2
-1022 104 2
-1024 104 2
-1028 105 2
-1029 105 2
-1030 105 2
-1031 106 2
-1032 106 2
-1033 106 2
-1203 107 2
-1202 107 2
-1020 103 2
-1157 100 0
-1193 105 2
-1040 107 2
-1002 101 1
-1015 102 2
-1006 101 1
-1034 106 2
-1035 106 2
-1016 103 2
-1007 101 1
-1036 107 2
-1018 103 2
-1026 105 2
-1027 105 2
-1183 104 2
-1038 107 2
-1025 105 2
-1037 107 2
-1021 104 2
-1019 103 2
-1005 101 1
-1179 105 2
-id parent_id level
-1002 100 0
-1004 101 1
-1005 101 1
-1009 102 2
-1025 102 2
-1018 103 2
-1023 104 2
-1025 104 2
-1029 105 2
-1030 105 2
-1031 105 2
-1032 106 2
-1033 106 2
-1034 106 2
-1204 107 2
-1203 107 2
-1021 103 2
-1158 100 0
-1194 105 2
-1041 107 2
-1003 101 1
-1016 102 2
-1007 101 1
-1035 106 2
-1036 106 2
-1017 103 2
-1008 101 1
-1037 107 2
-1019 103 2
-1027 105 2
-1028 105 2
-1184 104 2
-1039 107 2
-1026 105 2
-1038 107 2
-1022 104 2
-1020 103 2
-1006 101 1
-1180 105 2
-id parent_id level
-1009 102 2
-1025 102 2
-1016 102 2
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 6 where used; Using index
-level id
-1 1004
-1 1005
-1 1003
-1 1007
-1 1008
-1 1006
-level id parent_id
-1 1004 101
-1 1005 101
-1 1003 101
-1 1007 101
-1 1008 101
-1 1006 101
-level id
-1 1003
-1 1004
-1 1005
-1 1006
-1 1007
-1 1008
-id parent_id level
-1002 100 0
-1009 102 2
-1025 102 2
-1018 103 2
-1023 104 2
-1025 104 2
-1029 105 2
-1030 105 2
-1031 105 2
-1032 106 2
-1033 106 2
-1034 106 2
-1204 107 2
-1203 107 2
-1021 103 2
-1158 100 0
-1194 105 2
-1041 107 2
-1016 102 2
-1035 106 2
-1036 106 2
-1017 103 2
-1037 107 2
-1019 103 2
-1027 105 2
-1028 105 2
-1184 104 2
-1039 107 2
-1026 105 2
-1038 107 2
-1022 104 2
-1020 103 2
-1180 105 2
-count(*)
-1
-a
-1
-2
-3
-test for rollback
-test for rollback
-n after rollback
-4 after rollback
-n after commit
-4 after commit
-5 after commit
-n after commit
-4 after commit
-5 after commit
-6 after commit
-n
-4
-5
-6
-7
-afterbegin_id afterbegin_nom
-1 first
-2 hamdouni
-afterrollback_id afterrollback_nom
-1 first
-afterautocommit0_id afterautocommit0_nom
-1 first
-3 mysql
-afterrollback_id afterrollback_nom
-1 first
-id val
-id val
-pippo 12
-id val
-ID NAME
-1 Jochen
-_userid
-marc@anyware.co.uk
-_userid
-marc@anyware.co.uk
-f1
-65
-379
-468
-469
-508
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
new file mode 100644
index 00000000000..1a968fa4f2f
--- /dev/null
+++ b/mysql-test/r/grant.result
@@ -0,0 +1,133 @@
+drop table if exists t1;
+delete from mysql.user where user='mysqltest_1';
+delete from mysql.db where user='mysqltest_1';
+flush privileges;
+grant select on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA";
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
+GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+grant delete on mysqltest.* to mysqltest_1@localhost;
+select * from mysql.user where user="mysqltest_1";
+Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections
+localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
+GRANT SELECT, DELETE ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+revoke delete on mysqltest.* from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
+GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+grant select on mysqltest.* to mysqltest_1@localhost require NONE;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "MySQL AB";
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
+GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+revoke all privileges on mysqltest.* from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
+delete from mysql.user where user='mysqltest_1';
+flush privileges;
+grant CREATE TEMPORARY TABLES, LOCK TABLES on mysqltest.* to mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT CREATE TEMPORARY TABLES, LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+flush privileges;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT CREATE TEMPORARY TABLES, LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+revoke CREATE TEMPORARY TABLES on mysqltest.* from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
+grant ALL PRIVILEGES on mysqltest.* to mysqltest_1@localhost with GRANT OPTION;
+flush privileges;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
+revoke LOCK TABLES, ALTER on mysqltest.* from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
+revoke all privileges on mysqltest.* from mysqltest_1@localhost;
+delete from mysql.user where user='mysqltest_1';
+flush privileges;
+grant usage on test.* to mysqltest_1@localhost with grant option;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT USAGE ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
+GRANT USAGE ON `test`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
+delete from mysql.user where user='mysqltest_1';
+delete from mysql.db where user='mysqltest_1';
+delete from mysql.tables_priv where user='mysqltest_1';
+delete from mysql.columns_priv where user='mysqltest_1';
+flush privileges;
+create table t1 (a int);
+GRANT select,update,insert on t1 to mysqltest_1@localhost;
+GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT SELECT, SELECT (a), INSERT, INSERT (a), UPDATE, UPDATE (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
+select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
+table_priv column_priv
+Select,Insert,Update Select,Insert,Update,References
+REVOKE select (a), update on t1 from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT SELECT, INSERT, INSERT (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
+REVOKE select,update,insert,insert (a) on t1 from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
+GRANT REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
+GRANT select,references on t1 to mysqltest_1@localhost;
+select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
+table_priv column_priv
+Select,References References
+grant all on test.* to mysqltest_3@localhost with grant option;
+revoke all on test.* from mysqltest_3@localhost;
+show grants for mysqltest_3@localhost;
+Grants for mysqltest_3@localhost
+GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost'
+GRANT USAGE ON `test`.* TO 'mysqltest_3'@'localhost' WITH GRANT OPTION
+revoke grant option on test.* from mysqltest_3@localhost;
+show grants for mysqltest_3@localhost;
+Grants for mysqltest_3@localhost
+GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost'
+grant all on test.t1 to mysqltest_2@localhost with grant option;
+revoke all on test.t1 from mysqltest_2@localhost;
+show grants for mysqltest_2@localhost;
+Grants for mysqltest_2@localhost
+GRANT USAGE ON *.* TO 'mysqltest_2'@'localhost'
+GRANT USAGE ON `test`.`t1` TO 'mysqltest_2'@'localhost' WITH GRANT OPTION
+revoke grant option on test.t1 from mysqltest_2@localhost;
+show grants for mysqltest_2@localhost;
+Grants for mysqltest_2@localhost
+GRANT USAGE ON *.* TO 'mysqltest_2'@'localhost'
+delete from mysql.user where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.db where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.tables_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.columns_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+flush privileges;
+drop table t1;
+GRANT FILE on mysqltest.* to mysqltest_1@localhost;
+Wrong usage of DB GRANT and GLOBAL PRIVILEGES
+select 1;
+1
+1
diff --git a/mysql-test/r/grant_cache.result b/mysql-test/r/grant_cache.result
new file mode 100644
index 00000000000..fca6864cc63
--- /dev/null
+++ b/mysql-test/r/grant_cache.result
@@ -0,0 +1,154 @@
+drop table if exists test.t1,mysqltest.t1,mysqltest.t2;
+drop database if exists mysqltest;
+reset query cache;
+flush status;
+create database if not exists mysqltest;
+create table mysqltest.t1 (a int,b int,c int);
+create table mysqltest.t2 (a int,b int,c int);
+insert into mysqltest.t1 values (1,1,1),(2,2,2);
+insert into mysqltest.t2 values (3,3,3);
+create table test.t1 (a char (10));
+insert into test.t1 values ("test.t1");
+select * from t1;
+a
+test.t1
+select * from t1;
+a b c
+1 1 1
+2 2 2
+select a from t1;
+a
+1
+2
+select c from t1;
+c
+1
+2
+select * from t2;
+a b c
+3 3 3
+select * from mysqltest.t1,test.t1;
+a b c a
+1 1 1 test.t1
+2 2 2 test.t1
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 6
+show status like "Qcache_hits%";
+Variable_name Value
+Qcache_hits 0
+grant SELECT on mysqltest.* to mysqltest_1@localhost;
+grant SELECT on mysqltest.t1 to mysqltest_2@localhost;
+grant SELECT on test.t1 to mysqltest_2@localhost;
+grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost;
+select "user1";
+user1
+user1
+select * from t1;
+a b c
+1 1 1
+2 2 2
+select a from t1 ;
+a
+1
+2
+select c from t1;
+c
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 6
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 3
+show status like "Qcache_not_cached";
+Variable_name Value
+Qcache_not_cached 1
+select "user2";
+user2
+user2
+select * from t1;
+a b c
+1 1 1
+2 2 2
+select a from t1;
+a
+1
+2
+select c from t1;
+c
+1
+2
+select * from mysqltest.t1,test.t1;
+a b c a
+1 1 1 test.t1
+2 2 2 test.t1
+select * from t2;
+select command denied to user: 'mysqltest_2@localhost' for table 't2'
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 6
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 7
+show status like "Qcache_not_cached";
+Variable_name Value
+Qcache_not_cached 3
+select "user3";
+user3
+user3
+select * from t1;
+select command denied to user: 'mysqltest_3@localhost' for column 'b' in table 't1'
+select a from t1;
+a
+1
+2
+select c from t1;
+SELECT command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
+select * from t2;
+select command denied to user: 'mysqltest_3@localhost' for table 't2'
+select mysqltest.t1.c from test.t1,mysqltest.t1;
+SELECT command denied to user: 'mysqltest_3@localhost' for column 'c' in table 't1'
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 6
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 7
+show status like "Qcache_not_cached";
+Variable_name Value
+Qcache_not_cached 8
+select "user4";
+user4
+user4
+select a from t1;
+No Database Selected
+select * from mysqltest.t1,test.t1;
+a b c a
+1 1 1 test.t1
+2 2 2 test.t1
+select a from mysqltest.t1;
+a
+1
+2
+select a from mysqltest.t1;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 8
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 8
+show status like "Qcache_not_cached";
+Variable_name Value
+Qcache_not_cached 9
+delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.tables_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.columns_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+flush privileges;
+drop table test.t1,mysqltest.t1,mysqltest.t2;
+drop database mysqltest;
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 0073827056d..dba95614052 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -1,15 +1,206 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (
+spID int(10) unsigned,
+userID int(10) unsigned,
+score smallint(5) unsigned,
+lsg char(40),
+date date
+);
+INSERT INTO t1 VALUES (1,1,1,'','0000-00-00');
+INSERT INTO t1 VALUES (2,2,2,'','0000-00-00');
+INSERT INTO t1 VALUES (2,1,1,'','0000-00-00');
+INSERT INTO t1 VALUES (3,3,3,'','0000-00-00');
+CREATE TABLE t2 (
+userID int(10) unsigned NOT NULL auto_increment,
+niName char(15),
+passwd char(8),
+mail char(50),
+isAukt enum('N','Y') DEFAULT 'N',
+vName char(30),
+nName char(40),
+adr char(60),
+plz char(5),
+ort char(35),
+land char(20),
+PRIMARY KEY (userID)
+);
+INSERT INTO t2 VALUES (1,'name','pass','mail','Y','v','n','adr','1','1','1');
+INSERT INTO t2 VALUES (2,'name','pass','mail','Y','v','n','adr','1','1','1');
+INSERT INTO t2 VALUES (3,'name','pass','mail','Y','v','n','adr','1','1','1');
+INSERT INTO t2 VALUES (4,'name','pass','mail','Y','v','n','adr','1','1','1');
+INSERT INTO t2 VALUES (5,'name','pass','mail','Y','v','n','adr','1','1','1');
+SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID GROUP BY t2.userid;
userid MIN(t1.score)
1 1
2 2
3 3
+SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID GROUP BY t2.userid ORDER BY NULL;
userid MIN(t1.score)
1 1
2 2
+3 3
+SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid;
+userid MIN(t1.score)
+1 1
+2 2
+SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid;
userid MIN(t1.score+0.0)
1 1.0
2 2.0
+SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid ORDER BY NULL;
+userid MIN(t1.score+0.0)
+2 2.0
+1 1.0
+EXPLAIN SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid ORDER BY NULL;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 4 Using where; Using temporary
+t2 eq_ref PRIMARY PRIMARY 4 t1.userID 1 Using index
+drop table test.t1,test.t2;
+CREATE TABLE t1 (
+PID int(10) unsigned NOT NULL auto_increment,
+payDate date DEFAULT '0000-00-00' NOT NULL,
+recDate datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+URID int(10) unsigned DEFAULT '0' NOT NULL,
+CRID int(10) unsigned DEFAULT '0' NOT NULL,
+amount int(10) unsigned DEFAULT '0' NOT NULL,
+operator int(10) unsigned,
+method enum('unknown','cash','dealer','check','card','lazy','delayed','test') DEFAULT 'unknown' NOT NULL,
+DIID int(10) unsigned,
+reason char(1) binary DEFAULT '' NOT NULL,
+code_id int(10) unsigned,
+qty mediumint(8) unsigned DEFAULT '0' NOT NULL,
+PRIMARY KEY (PID),
+KEY URID (URID),
+KEY reason (reason),
+KEY method (method),
+KEY payDate (payDate)
+);
+INSERT INTO t1 VALUES (1,'1970-01-01','1997-10-17 00:00:00',2529,1,21000,11886,'check',0,'F',16200,6);
+SELECT COUNT(P.URID),SUM(P.amount),P.method, MIN(PP.recdate+0) > 19980501000000 AS IsNew FROM t1 AS P JOIN t1 as PP WHERE P.URID = PP.URID GROUP BY method,IsNew;
+Can't group on 'IsNew'
+drop table t1;
+CREATE TABLE t1 (
+cid mediumint(9) NOT NULL auto_increment,
+firstname varchar(32) DEFAULT '' NOT NULL,
+surname varchar(32) DEFAULT '' NOT NULL,
+PRIMARY KEY (cid)
+);
+INSERT INTO t1 VALUES (1,'That','Guy');
+INSERT INTO t1 VALUES (2,'Another','Gent');
+CREATE TABLE t2 (
+call_id mediumint(8) NOT NULL auto_increment,
+contact_id mediumint(8) DEFAULT '0' NOT NULL,
+PRIMARY KEY (call_id),
+KEY contact_id (contact_id)
+);
+lock tables t1 read,t2 write;
+INSERT INTO t2 VALUES (10,2);
+INSERT INTO t2 VALUES (18,2);
+INSERT INTO t2 VALUES (62,2);
+INSERT INTO t2 VALUES (91,2);
+INSERT INTO t2 VALUES (92,2);
+SELECT cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid;
+cid CONCAT(firstname, ' ', surname) COUNT(call_id)
+SELECT cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid ORDER BY NULL;
cid CONCAT(firstname, ' ', surname) COUNT(call_id)
+SELECT HIGH_PRIORITY cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid ORDER BY surname, firstname;
cid CONCAT(firstname, ' ', surname) COUNT(call_id)
+drop table t1,t2;
+unlock tables;
+CREATE TABLE t1 (
+bug_id mediumint(9) NOT NULL auto_increment,
+groupset bigint(20) DEFAULT '0' NOT NULL,
+assigned_to mediumint(9) DEFAULT '0' NOT NULL,
+bug_file_loc text,
+bug_severity enum('blocker','critical','major','normal','minor','trivial','enhancement') DEFAULT 'blocker' NOT NULL,
+bug_status enum('NEW','ASSIGNED','REOPENED','RESOLVED','VERIFIED','CLOSED') DEFAULT 'NEW' NOT NULL,
+creation_ts datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+delta_ts timestamp(14),
+short_desc mediumtext,
+long_desc mediumtext,
+op_sys enum('All','Windows 3.1','Windows 95','Windows 98','Windows NT','Windows 2000','Linux','other') DEFAULT 'All' NOT NULL,
+priority enum('P1','P2','P3','P4','P5') DEFAULT 'P1' NOT NULL,
+product varchar(64) DEFAULT '' NOT NULL,
+rep_platform enum('All','PC','VTD-8','Other'),
+reporter mediumint(9) DEFAULT '0' NOT NULL,
+version varchar(16) DEFAULT '' NOT NULL,
+component varchar(50) DEFAULT '' NOT NULL,
+resolution enum('','FIXED','INVALID','WONTFIX','LATER','REMIND','DUPLICATE','WORKSFORME') DEFAULT '' NOT NULL,
+target_milestone varchar(20) DEFAULT '' NOT NULL,
+qa_contact mediumint(9) DEFAULT '0' NOT NULL,
+status_whiteboard mediumtext NOT NULL,
+votes mediumint(9) DEFAULT '0' NOT NULL,
+PRIMARY KEY (bug_id),
+KEY assigned_to (assigned_to),
+KEY creation_ts (creation_ts),
+KEY delta_ts (delta_ts),
+KEY bug_severity (bug_severity),
+KEY bug_status (bug_status),
+KEY op_sys (op_sys),
+KEY priority (priority),
+KEY product (product),
+KEY reporter (reporter),
+KEY version (version),
+KEY component (component),
+KEY resolution (resolution),
+KEY target_milestone (target_milestone),
+KEY qa_contact (qa_contact),
+KEY votes (votes)
+);
+INSERT INTO t1 VALUES (1,0,0,'','normal','','2000-02-10 09:25:12',20000321114747,'','','Linux','P1','TestProduct','PC',3,'other','TestComponent','','M1',0,'',0);
+INSERT INTO t1 VALUES (9,0,0,'','enhancement','','2000-03-10 11:49:36',20000321114747,'','','All','P5','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - conversion','','',0,'',0);
+INSERT INTO t1 VALUES (10,0,0,'','enhancement','','2000-03-10 18:10:16',20000321114747,'','','All','P4','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - conversion','','',0,'',0);
+INSERT INTO t1 VALUES (7,0,0,'','critical','','2000-03-09 10:50:21',20000321114747,'','','All','P1','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - generic','','',0,'',0);
+INSERT INTO t1 VALUES (6,0,0,'','normal','','2000-03-09 10:42:44',20000321114747,'','','All','P2','AAAAA','PC',3,'2.00 CD - Pre','kkkkkkkkkkk lllllllllll','','',0,'',0);
+INSERT INTO t1 VALUES (8,0,0,'','major','','2000-03-09 11:32:14',20000321114747,'','','All','P3','AAAAA','PC',3,'2.00 CD - Pre','kkkkkkkkkkk lllllllllll','','',0,'',0);
+INSERT INTO t1 VALUES (5,0,0,'','enhancement','','2000-03-09 10:38:59',20000321114747,'','','All','P5','CCC/CCCCCC','PC',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (4,0,0,'','normal','','2000-03-08 18:32:14',20000321114747,'','','other','P2','TestProduct','Other',3,'other','TestComponent2','','',0,'',0);
+INSERT INTO t1 VALUES (3,0,0,'','normal','','2000-03-08 18:30:52',20000321114747,'','','other','P2','TestProduct','Other',3,'other','TestComponent','','',0,'',0);
+INSERT INTO t1 VALUES (2,0,0,'','enhancement','','2000-03-08 18:24:51',20000321114747,'','','All','P2','TestProduct','Other',4,'other','TestComponent2','','',0,'',0);
+INSERT INTO t1 VALUES (11,0,0,'','blocker','','2000-03-13 09:43:41',20000321114747,'','','All','P2','CCC/CCCCCC','PC',5,'7.00','DDDDDDDDD','','',0,'',0);
+INSERT INTO t1 VALUES (12,0,0,'','normal','','2000-03-13 16:14:31',20000321114747,'','','All','P2','AAAAA','PC',3,'2.00 CD - Pre','kkkkkkkkkkk lllllllllll','','',0,'',0);
+INSERT INTO t1 VALUES (13,0,0,'','normal','','2000-03-15 16:20:44',20000321114747,'','','other','P2','TestProduct','Other',3,'other','TestComponent','','',0,'',0);
+INSERT INTO t1 VALUES (14,0,0,'','blocker','','2000-03-15 18:13:47',20000321114747,'','','All','P1','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - generic','','',0,'',0);
+INSERT INTO t1 VALUES (15,0,0,'','minor','','2000-03-16 18:03:28',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','DDDDDDDDD','','',0,'',0);
+INSERT INTO t1 VALUES (16,0,0,'','normal','','2000-03-16 18:33:41',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (17,0,0,'','normal','','2000-03-16 18:34:18',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (18,0,0,'','normal','','2000-03-16 18:34:56',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (19,0,0,'','enhancement','','2000-03-16 18:35:34',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (20,0,0,'','enhancement','','2000-03-16 18:36:23',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (21,0,0,'','enhancement','','2000-03-16 18:37:23',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (22,0,0,'','enhancement','','2000-03-16 18:38:16',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0);
+INSERT INTO t1 VALUES (23,0,0,'','normal','','2000-03-16 18:58:12',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','DDDDDDDDD','','',0,'',0);
+INSERT INTO t1 VALUES (24,0,0,'','normal','','2000-03-17 11:08:10',20000321114747,'','','All','P2','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0);
+INSERT INTO t1 VALUES (25,0,0,'','normal','','2000-03-17 11:10:45',20000321114747,'','','All','P2','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0);
+INSERT INTO t1 VALUES (26,0,0,'','normal','','2000-03-17 11:15:47',20000321114747,'','','All','P2','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0);
+INSERT INTO t1 VALUES (27,0,0,'','normal','','2000-03-17 17:45:41',20000321114747,'','','All','P2','CCC/CCCCCC','PC',5,'7.00','DDDDDDDDD','','',0,'',0);
+INSERT INTO t1 VALUES (28,0,0,'','normal','','2000-03-20 09:51:45',20000321114747,'','','Windows NT','P2','TestProduct','PC',8,'other','TestComponent','','',0,'',0);
+INSERT INTO t1 VALUES (29,0,0,'','normal','','2000-03-20 11:15:09',20000321114747,'','','All','P5','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0);
+CREATE TABLE t2 (
+value tinytext,
+program varchar(64),
+initialowner tinytext NOT NULL,
+initialqacontact tinytext NOT NULL,
+description mediumtext NOT NULL
+);
+INSERT INTO t2 VALUES ('TestComponent','TestProduct','id0001','','');
+INSERT INTO t2 VALUES ('BBBBBBBBBBBBB - conversion','AAAAA','id0001','','');
+INSERT INTO t2 VALUES ('BBBBBBBBBBBBB - generic','AAAAA','id0001','','');
+INSERT INTO t2 VALUES ('TestComponent2','TestProduct','id0001','','');
+INSERT INTO t2 VALUES ('BBBBBBBBBBBBB - eeeeeeeee','AAAAA','id0001','','');
+INSERT INTO t2 VALUES ('kkkkkkkkkkk lllllllllll','AAAAA','id0001','','');
+INSERT INTO t2 VALUES ('Test Procedures','AAAAA','id0001','','');
+INSERT INTO t2 VALUES ('Documentation','AAAAA','id0003','','');
+INSERT INTO t2 VALUES ('DDDDDDDDD','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Eeeeeeee Lite','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Eeeeeeee Full','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Administration','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Distribution','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Setup','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Unspecified','CCC/CCCCCC','id0002','','');
+INSERT INTO t2 VALUES ('Web Interface','AAAAAAAA-AAA','id0001','','');
+INSERT INTO t2 VALUES ('Host communication','AAAAA','id0001','','');
+select value,description,bug_id from t2 left join t1 on t2.program=t1.product and t2.value=t1.component where program="AAAAA";
value description bug_id
BBBBBBBBBBBBB - conversion 9
BBBBBBBBBBBBB - conversion 10
@@ -22,6 +213,7 @@ kkkkkkkkkkk lllllllllll 12
Test Procedures NULL
Documentation NULL
Host communication NULL
+select value,description,COUNT(bug_id) from t2 left join t1 on t2.program=t1.product and t2.value=t1.component where program="AAAAA" group by value;
value description COUNT(bug_id)
BBBBBBBBBBBBB - conversion 2
BBBBBBBBBBBBB - eeeeeeeee 0
@@ -30,6 +222,7 @@ Documentation 0
Host communication 0
kkkkkkkkkkk lllllllllll 3
Test Procedures 0
+select value,description,COUNT(bug_id) from t2 left join t1 on t2.program=t1.product and t2.value=t1.component where program="AAAAA" group by value having COUNT(bug_id) IN (0,2);
value description COUNT(bug_id)
BBBBBBBBBBBBB - conversion 2
BBBBBBBBBBBBB - eeeeeeeee 0
@@ -37,49 +230,224 @@ BBBBBBBBBBBBB - generic 2
Documentation 0
Host communication 0
Test Procedures 0
+drop table t1,t2;
+create table t1 (foo int);
+insert into t1 values (1);
+select 1+1, "a",count(*) from t1 where foo in (2);
1+1 a count(*)
2 a 0
+insert into t1 values (1);
+select 1+1,"a",count(*) from t1 where foo in (2);
1+1 a count(*)
2 a 0
+drop table t1;
+CREATE TABLE t1 (
+spID int(10) unsigned,
+userID int(10) unsigned,
+score smallint(5) unsigned,
+key (spid),
+key (score)
+);
+INSERT INTO t1 VALUES (1,1,1),(2,2,2),(2,1,1),(3,3,3),(4,3,3),(5,3,3),(6,3,3),(7,3,3);
+explain select userid,count(*) from t1 group by userid desc;
table type possible_keys key key_len ref rows Extra
-t1 ALL NULL NULL NULL NULL 6 Using temporary
+t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort
+explain select userid,count(*) from t1 group by userid desc order by null;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 8 Using temporary
+select userid,count(*) from t1 group by userid desc;
userid count(*)
-3 3
+3 5
2 1
1 2
+select userid,count(*) from t1 group by userid desc having (count(*)+1) IN (4,3);
userid count(*)
-3 3
1 2
+select userid,count(*) from t1 group by userid desc having 3 IN (1,COUNT(*));
userid count(*)
-3 3
+explain select spid,count(*) from t1 where spid between 1 and 2 group by spid desc;
+table type possible_keys key key_len ref rows Extra
+t1 range spID spID 5 NULL 3 Using where; Using index
+explain select spid,count(*) from t1 where spid between 1 and 2 group by spid;
table type possible_keys key key_len ref rows Extra
-t1 range spID spID 5 NULL 2 where used; Using index; Using temporary
+t1 range spID spID 5 NULL 3 Using where; Using index
+explain select spid,count(*) from t1 where spid between 1 and 2 group by spid order by null;
table type possible_keys key key_len ref rows Extra
-t1 range spID spID 5 NULL 2 where used; Using index
+t1 range spID spID 5 NULL 3 Using where; Using index
+select spid,count(*) from t1 where spid between 1 and 2 group by spid;
spid count(*)
1 1
2 2
+select spid,count(*) from t1 where spid between 1 and 2 group by spid desc;
spid count(*)
2 2
1 1
+explain select sql_big_result spid,sum(userid) from t1 group by spid desc;
table type possible_keys key key_len ref rows Extra
-t1 ALL NULL NULL NULL NULL 6 Using filesort
+t1 ALL NULL NULL NULL NULL 8 Using filesort
+explain select sql_big_result spid,sum(userid) from t1 group by spid desc order by null;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 8 Using filesort
+select sql_big_result spid,sum(userid) from t1 group by spid desc;
spid sum(userid)
+7 3
+6 3
5 3
4 3
3 3
2 3
1 1
+explain select sql_big_result score,count(*) from t1 group by score desc;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL score 3 NULL 8 Using index
+explain select sql_big_result score,count(*) from t1 group by score desc order by null;
table type possible_keys key key_len ref rows Extra
-t1 index NULL score 3 NULL 6 Using index
+t1 index NULL score 3 NULL 8 Using index
+select sql_big_result score,count(*) from t1 group by score desc;
score count(*)
-3 3
+3 5
2 1
1 2
+drop table t1;
+create table t1 (a date default null, b date default null);
+insert t1 values ('1999-10-01','2000-01-10'), ('1997-01-01','1998-10-01');
+select a,min(b) c,count(distinct rand()) from t1 group by a having c<a + interval 1 day;
+a c count(distinct rand())
+drop table t1;
+CREATE TABLE t1 (a char(1));
+INSERT INTO t1 VALUES ('A'),('B'),('A'),('B'),('A'),('B'),(NULL),('a'),('b'),(NULL),('A'),('B'),(NULL);
+SELECT a FROM t1 GROUP BY a;
+a
+NULL
+A
+B
+SELECT a,count(*) FROM t1 GROUP BY a;
+a count(*)
+NULL 3
+A 5
+B 5
+SELECT a FROM t1 GROUP BY binary a;
+a
+NULL
+A
+B
+a
+b
+SELECT a,count(*) FROM t1 GROUP BY binary a;
+a count(*)
+NULL 3
+A 4
+B 4
+a 1
+b 1
+SELECT binary a FROM t1 GROUP BY 1;
+binary a
+NULL
+A
+B
+a
+b
+SELECT binary a,count(*) FROM t1 GROUP BY 1;
+binary a count(*)
+NULL 3
+A 4
+B 4
+a 1
+b 1
+SET SQL_BIG_TABLES=1;
+SELECT a FROM t1 GROUP BY a;
+a
+NULL
+A
+B
+SELECT a,count(*) FROM t1 GROUP BY a;
+a count(*)
+NULL 3
+A 5
+B 5
+SELECT a FROM t1 GROUP BY binary a;
+a
+NULL
+A
+B
+a
+b
+SELECT a,count(*) FROM t1 GROUP BY binary a;
+a count(*)
+NULL 3
+A 4
+B 4
+a 1
+b 1
+SELECT binary a FROM t1 GROUP BY 1;
+binary a
+NULL
+A
+B
+a
+b
+SELECT binary a,count(*) FROM t1 GROUP BY 1;
+binary a count(*)
+NULL 3
+A 4
+B 4
+a 1
+b 1
+SET SQL_BIG_TABLES=0;
+drop table t1;
+CREATE TABLE t1 (
+`a` char(193) default NULL,
+`b` char(63) default NULL
+);
+INSERT INTO t1 VALUES ('abc','def'),('hij','klm');
+SELECT CONCAT(a, b) FROM t1 GROUP BY 1;
+CONCAT(a, b)
+abcdef
+hijklm
+SELECT CONCAT(a, b),count(*) FROM t1 GROUP BY 1;
+CONCAT(a, b) count(*)
+abcdef 1
+hijklm 1
+SELECT CONCAT(a, b),count(distinct a) FROM t1 GROUP BY 1;
+CONCAT(a, b) count(distinct a)
+abcdef 1
+hijklm 1
+SELECT 1 FROM t1 GROUP BY CONCAT(a, b);
+1
+1
+1
+INSERT INTO t1 values ('hij','klm');
+SELECT CONCAT(a, b),count(*) FROM t1 GROUP BY 1;
+CONCAT(a, b) count(*)
+abcdef 1
+hijklm 2
+DROP TABLE t1;
+drop table if exists t1;
+create table t1 (One int unsigned, Two int unsigned, Three int unsigned, Four int unsigned);
+insert into t1 values (1,2,1,4),(1,2,2,4),(1,2,3,4),(1,2,4,4),(1,1,1,4),(1,1,2,4),(1,1,3,4),(1,1,4,4),(1,3,1,4),(1,3,2,4),(1,3,3,4),(1,3,4,4);
+select One, Two, sum(Four) from t1 group by One,Two;
One Two sum(Four)
1 1 16
1 2 16
1 3 16
+drop table t1;
+create table t1 (id integer primary key not null auto_increment, gender char(1));
+insert into t1 values (NULL, 'M'), (NULL, 'F'),(NULL, 'F'),(NULL, 'F'),(NULL, 'M');
+create table t2 (user_id integer not null, date date);
+insert into t2 values (1, '2002-06-09'),(2, '2002-06-09'),(1, '2002-06-09'),(3, '2002-06-09'),(4, '2002-06-09'),(4, '2002-06-09');
+select u.gender as gender, count(distinct u.id) as dist_count, (count(distinct u.id)/5*100) as percentage from t1 u, t2 l where l.user_id = u.id group by u.gender;
+gender dist_count percentage
+F 3 60.00
+M 1 20.00
+select u.gender as gender, count(distinct u.id) as dist_count, (count(distinct u.id)/5*100) as percentage from t1 u, t2 l where l.user_id = u.id group by u.gender order by percentage;
+gender dist_count percentage
+M 1 20.00
+F 3 60.00
+drop table t1,t2;
+CREATE TABLE t1 (ID1 int, ID2 int, ID int NOT NULL AUTO_INCREMENT,PRIMARY KEY(ID
+));
+insert into t1 values (1,244,NULL),(2,243,NULL),(134,223,NULL),(185,186,NULL);
+select S.ID as xID, S.ID1 as xID1 from t1 as S left join t1 as yS on S.ID1 between yS.ID1 and yS.ID2;
xID xID1
1 1
2 2
@@ -91,41 +459,170 @@ xID xID1
4 185
4 185
4 185
+select S.ID as xID, S.ID1 as xID1, repeat('*',count(distinct yS.ID)) as Level from t1 as S left join t1 as yS on S.ID1 between yS.ID1 and yS.ID2 group by xID order by xID1;
xID xID1 Level
1 1 *
2 2 **
3 134 ***
4 185 ****
+drop table t1;
+CREATE TABLE t1 (
+pid int(11) unsigned NOT NULL default '0',
+c1id int(11) unsigned default NULL,
+c2id int(11) unsigned default NULL,
+value int(11) unsigned NOT NULL default '0',
+UNIQUE KEY pid2 (pid,c1id,c2id),
+UNIQUE KEY pid (pid,value)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1, 1, NULL, 1),(1, 2, NULL, 2),(1, NULL, 3, 3),(1, 4, NULL, 4),(1, 5, NULL, 5);
+CREATE TABLE t2 (
+id int(11) unsigned NOT NULL default '0',
+active enum('Yes','No') NOT NULL default 'Yes',
+PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1, 'Yes'),(2, 'No'),(4, 'Yes'),(5, 'No');
+CREATE TABLE t3 (
+id int(11) unsigned NOT NULL default '0',
+active enum('Yes','No') NOT NULL default 'Yes',
+PRIMARY KEY (id)
+);
+INSERT INTO t3 VALUES (3, 'Yes');
+select * from t1 AS m LEFT JOIN t2 AS c1 ON m.c1id =
+c1.id AND c1.active = 'Yes' LEFT JOIN t3 AS c2 ON m.c2id = c2.id AND
+c2.active = 'Yes' WHERE m.pid=1 AND (c1.id IS NOT NULL OR c2.id IS NOT NULL);
pid c1id c2id value id active id active
1 1 NULL 1 1 Yes NULL NULL
1 NULL 3 3 NULL NULL 3 Yes
1 4 NULL 4 4 Yes NULL NULL
+select max(value) from t1 AS m LEFT JOIN t2 AS c1 ON
+m.c1id = c1.id AND c1.active = 'Yes' LEFT JOIN t3 AS c2 ON m.c2id =
+c2.id AND c2.active = 'Yes' WHERE m.pid=1 AND (c1.id IS NOT NULL OR c2.id IS
+NOT NULL);
max(value)
4
+drop table t1,t2,t3;
+create table t1 (a blob null);
+insert into t1 values (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(""),(""),(""),("b");
+select a,count(*) from t1 group by a;
a count(*)
NULL 9
3
b 1
+set option sql_big_tables=1;
+select a,count(*) from t1 group by a;
a count(*)
NULL 9
3
b 1
+drop table t1;
+create table t1 (a int not null, b int not null);
+insert into t1 values (1,1),(1,2),(3,1),(3,2),(2,2),(2,1);
+create table t2 (a int not null, b int not null, key(a));
+insert into t2 values (1,3),(3,1),(2,2),(1,1);
+select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b;
+a b
+1 1
+1 3
+2 2
+3 1
+select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b ORDER BY NULL;
+a b
+1 3
+3 1
+2 2
+1 1
+explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
+t2 ALL a NULL NULL NULL 3 Using where
+explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b ORDER BY NULL;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 6 Using temporary
+t2 ALL a NULL NULL NULL 3 Using where
+drop table t1,t2;
+create table t1 (a int, b int);
+insert into t1 values (1, 4),(10, 40),(1, 4),(10, 43),(1, 4),(10, 41),(1, 4),(10, 43),(1, 4);
+select a, MAX(b), INTERVAL (MAX(b), 1,3,10,30,39,40,50,60,100,1000) from t1 group by a;
a MAX(b) INTERVAL (MAX(b), 1,3,10,30,39,40,50,60,100,1000)
1 4 2
10 43 6
+select a, MAX(b), CASE MAX(b) when 4 then 4 when 43 then 43 else 0 end from t1 group by a;
a MAX(b) CASE MAX(b) when 4 then 4 when 43 then 43 else 0 end
1 4 4
10 43 43
+select a, MAX(b), FIELD(MAX(b), '43', '4', '5') from t1 group by a;
a MAX(b) FIELD(MAX(b), '43', '4', '5')
1 4 2
10 43 1
+select a, MAX(b), CONCAT_WS(MAX(b), '43', '4', '5') from t1 group by a;
a MAX(b) CONCAT_WS(MAX(b), '43', '4', '5')
1 4 434445
10 43 43434435
+select a, MAX(b), ELT(MAX(b), 'a', 'b', 'c', 'd', 'e', 'f') from t1 group by a;
a MAX(b) ELT(MAX(b), 'a', 'b', 'c', 'd', 'e', 'f')
1 4 d
10 43 NULL
+select a, MAX(b), MAKE_SET(MAX(b), 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h') from t1 group by a;
a MAX(b) MAKE_SET(MAX(b), 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h')
1 4 c
10 43 a,b,d,f
-a c count(distinct rand())
+drop table t1;
+create table t1 (id int not null, qty int not null);
+insert into t1 values (1,2),(1,3),(2,4),(2,5);
+select id, sum(qty) as sqty, count(qty) as cqty from t1 group by id having sum(qty)>2 and cqty>1;
+id sqty cqty
+1 5 2
+2 9 2
+select id, sum(qty) as sqty from t1 group by id having sqty>2 and count(qty)>1;
+id sqty
+1 5
+2 9
+select id, sum(qty) as sqty, count(qty) as cqty from t1 group by id having sqty>2 and cqty>1;
+id sqty cqty
+1 5 2
+2 9 2
+select id, sum(qty) as sqty, count(qty) as cqty from t1 group by id having sum(qty)>2 and count(qty)>1;
+id sqty cqty
+1 5 2
+2 9 2
+select count(*), case interval(qty,2,3,4,5,6,7,8) when -1 then NULL when 0 then "zero" when 1 then "one" when 2 then "two" end as category from t1 group by category;
+count(*) category
+2 NULL
+1 one
+1 two
+select count(*), interval(qty,2,3,4,5,6,7,8) as category from t1 group by category;
+count(*) category
+1 1
+1 2
+1 3
+1 4
+drop table t1;
+CREATE TABLE t1 (
+userid int(10) unsigned,
+score smallint(5) unsigned,
+key (score)
+);
+INSERT INTO t1 VALUES (1,1),(2,2),(1,1),(3,3),(3,3),(3,3),(3,3),(3,3);
+SELECT userid,count(*) FROM t1 GROUP BY userid DESC;
+userid count(*)
+3 5
+2 1
+1 2
+EXPLAIN SELECT userid,count(*) FROM t1 GROUP BY userid DESC;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort
+DROP TABLE t1;
+CREATE TABLE t1 (
+i int(11) default NULL,
+j int(11) default NULL
+);
+INSERT INTO t1 VALUES (1,2),(2,3),(4,5),(3,5),(1,5),(23,5);
+SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL;
+i COUNT(DISTINCT(i))
+1 1
+2 1
+4 4
+explain SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 6 Using filesort
+DROP TABLE t1;
diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result
new file mode 100644
index 00000000000..1cfc3a9de8b
--- /dev/null
+++ b/mysql-test/r/handler.result
@@ -0,0 +1,193 @@
+drop table if exists t1;
+create table t1 (a int, b char(10), key a(a), key b(a,b));
+insert into t1 values
+(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
+(14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"),
+(20,"ggg"),(21,"hhh"),(22,"iii");
+handler t1 open as t2;
+handler t2 read a first;
+a b
+14 aaa
+handler t2 read a next;
+a b
+15 bbb
+handler t2 read a next;
+a b
+16 ccc
+handler t2 read a prev;
+a b
+15 bbb
+handler t2 read a last;
+a b
+22 iii
+handler t2 read a prev;
+a b
+21 hhh
+handler t2 read a prev;
+a b
+20 ggg
+handler t2 read a first;
+a b
+14 aaa
+handler t2 read a prev;
+a b
+handler t2 read a last;
+a b
+22 iii
+handler t2 read a prev;
+a b
+21 hhh
+handler t2 read a next;
+a b
+22 iii
+handler t2 read a next;
+a b
+handler t2 read a=(15);
+a b
+15 bbb
+handler t2 read a=(16);
+a b
+16 ccc
+handler t2 read a=(19,"fff");
+Too many key parts specified. Max 1 parts allowed
+handler t2 read b=(19,"fff");
+a b
+19 fff
+handler t2 read b=(19,"yyy");
+a b
+19 yyy
+handler t2 read b=(19);
+a b
+19 fff
+handler t1 read a last;
+Unknown table 't1' in HANDLER
+handler t2 read a=(11);
+a b
+handler t2 read a>=(11);
+a b
+14 aaa
+handler t2 read a=(18);
+a b
+18 eee
+handler t2 read a>=(18);
+a b
+18 eee
+handler t2 read a>(18);
+a b
+19 fff
+handler t2 read a<=(18);
+a b
+18 eee
+handler t2 read a<(18);
+a b
+17 ddd
+handler t2 read a first limit 5;
+a b
+14 aaa
+15 bbb
+16 ccc
+16 xxx
+17 ddd
+handler t2 read a next limit 3;
+a b
+18 eee
+19 fff
+19 yyy
+handler t2 read a prev limit 10;
+a b
+19 fff
+18 eee
+17 ddd
+16 xxx
+16 ccc
+15 bbb
+14 aaa
+handler t2 read a>=(16) limit 4;
+a b
+16 ccc
+16 xxx
+17 ddd
+18 eee
+handler t2 read a>=(16) limit 2,2;
+a b
+17 ddd
+18 eee
+handler t2 read a last limit 3;
+a b
+22 iii
+21 hhh
+20 ggg
+handler t2 read a=(19);
+a b
+19 fff
+handler t2 read a=(19) where b="yyy";
+a b
+19 yyy
+handler t2 read first;
+a b
+17 ddd
+handler t2 read next;
+a b
+18 eee
+handler t2 read next;
+a b
+19 fff
+handler t2 read last;
+You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
+handler t2 close;
+handler t1 open as t2;
+drop table t1;
+create table t1 (a int);
+insert into t1 values (17);
+handler t2 read first;
+Unknown table 't2' in HANDLER
+handler t1 open as t2;
+alter table t1 engine=MyISAM;
+handler t2 read first;
+Unknown table 't2' in HANDLER
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3),(4),(5),(6);
+delete from t1 limit 2;
+handler t1 open;
+handler t1 read first;
+a
+3
+handler t1 read first limit 1,1;
+a
+4
+handler t1 read first limit 2,2;
+a
+5
+6
+delete from t1 limit 3;
+handler t1 read first;
+a
+6
+drop table t1;
+create table t1(a int, index(a));
+insert into t1 values (1), (2), (3);
+handler t1 open;
+handler t1 read a=(W);
+Unknown column 'W' in 'field list'
+handler t1 read a=(a);
+Wrong arguments to HANDLER ... READ
+drop table t1;
+create table t1 (a char(5));
+insert into t1 values ("Ok");
+handler t1 open as t;
+handler t read first;
+a
+Ok
+use mysql;
+handler t read first;
+a
+Ok
+handler t close;
+handler test.t1 open as t;
+handler t read first;
+a
+Ok
+handler t close;
+use test;
+drop table t1;
diff --git a/mysql-test/r/have_crypt.require b/mysql-test/r/have_crypt.require
new file mode 100644
index 00000000000..739fbb738f0
--- /dev/null
+++ b/mysql-test/r/have_crypt.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_crypt YES
diff --git a/mysql-test/r/have_gemini.require b/mysql-test/r/have_gemini.require
deleted file mode 100644
index 0ffe0e40d3b..00000000000
--- a/mysql-test/r/have_gemini.require
+++ /dev/null
@@ -1,2 +0,0 @@
-Variable_name Value
-have_gemini YES
diff --git a/mysql-test/r/have_met_timezone.require b/mysql-test/r/have_met_timezone.require
new file mode 100644
index 00000000000..b3fde075ebd
--- /dev/null
+++ b/mysql-test/r/have_met_timezone.require
@@ -0,0 +1,2 @@
+FROM_UNIXTIME(24*3600)
+1970-01-02 01:00:00
diff --git a/mysql-test/r/have_openssl.require b/mysql-test/r/have_openssl.require
new file mode 100644
index 00000000000..dae48a472b5
--- /dev/null
+++ b/mysql-test/r/have_openssl.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_openssl YES
diff --git a/mysql-test/r/have_openssl_1.require b/mysql-test/r/have_openssl_1.require
new file mode 100644
index 00000000000..032b60d544a
--- /dev/null
+++ b/mysql-test/r/have_openssl_1.require
@@ -0,0 +1,2 @@
+Variable_name Value
+Ssl_cipher EDH-RSA-DES-CBC3-SHA
diff --git a/mysql-test/r/have_query_cache.require b/mysql-test/r/have_query_cache.require
new file mode 100644
index 00000000000..312d837fed3
--- /dev/null
+++ b/mysql-test/r/have_query_cache.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_query_cache YES
diff --git a/mysql-test/r/have_symlink.require b/mysql-test/r/have_symlink.require
new file mode 100644
index 00000000000..55ad9437034
--- /dev/null
+++ b/mysql-test/r/have_symlink.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_symlink YES
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index 69943c505f0..d643070f7f9 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -1,6 +1,80 @@
+drop table if exists t1,t2;
+create table t1 (a int);
+select count(a) as b from t1 where a=0 having b > 0;
b
+insert into t1 values (null);
+select count(a) as b from t1 where a=0 having b > 0;
b
+select count(a) as b from t1 where a=0 having b >=0;
b
0
+drop table t1;
+CREATE TABLE t1 (
+raw_id int(10) NOT NULL default '0',
+chr_start int(10) NOT NULL default '0',
+chr_end int(10) NOT NULL default '0',
+raw_start int(10) NOT NULL default '0',
+raw_end int(10) NOT NULL default '0',
+raw_ori int(2) NOT NULL default '0'
+);
+INSERT INTO t1 VALUES (469713,1,164123,1,164123,1),(317330,164124,317193,101,153170,1),(469434,317194,375620,101,58527,1),(591816,375621,484273,1,108653,1),(591807,484274,534671,91,50488,1),(318885,534672,649362,101,114791,1),(318728,649363,775520,102,126259,1),(336829,775521,813997,101,38577,1),(317740,813998,953227,101,139330,1),(1,813998,953227,101,139330,1);
+CREATE TABLE t2 (
+id int(10) unsigned NOT NULL default '0',
+contig_id int(10) unsigned NOT NULL default '0',
+seq_start int(10) NOT NULL default '0',
+seq_end int(10) NOT NULL default '0',
+strand tinyint(2) NOT NULL default '0',
+KEY id (id)
+);
+INSERT INTO t2 VALUES (133195,469713,61327,61384,1),(133196,469713,64113,64387,1),(133197,1,1,1,0),(133197,1,1,1,-2);
+SELECT e.id,
+MIN( IF(sgp.raw_ori=1,
+(e.seq_start+sgp.chr_start-sgp.raw_start),
+(sgp.chr_start+sgp.raw_end-e.seq_end))) as start,
+MAX( IF(sgp.raw_ori=1,
+(e.seq_end+sgp.chr_start-sgp.raw_start),
+(sgp.chr_start+sgp.raw_end-e.seq_start))) as end,
+AVG(IF (sgp.raw_ori=1,e.strand,(-e.strand))) as chr_strand
+FROM t1 sgp,
+t2 e
+WHERE sgp.raw_id=e.contig_id
+GROUP BY e.id
+HAVING chr_strand= -1 and end >= 0
+AND start <= 999660;
id start end chr_strand
133197 813898 813898 -1.0000
+drop table t1,t2;
+CREATE TABLE t1 (Fld1 int(11) default NULL,Fld2 int(11) default NULL);
+INSERT INTO t1 VALUES (1,10),(1,20),(2,NULL),(2,NULL),(3,50);
+select Fld1, max(Fld2) as q from t1 group by Fld1 having q is not null;
+Fld1 q
+1 20
+3 50
+select Fld1, max(Fld2) from t1 group by Fld1 having max(Fld2) is not null;
+Fld1 max(Fld2)
+1 20
+3 50
+select Fld1, max(Fld2) from t1 group by Fld1 having avg(Fld2) is not null;
+Fld1 max(Fld2)
+1 20
+3 50
+select Fld1, max(Fld2) from t1 group by Fld1 having std(Fld2) is not null;
+Fld1 max(Fld2)
+1 20
+3 50
+drop table t1;
+create table t1 (id int not null, qty int not null);
+insert into t1 values (1,2),(1,3),(2,4),(2,5);
+select id, sum(qty) as sqty from t1 group by id having sqty>2;
+id sqty
+1 5
+2 9
+select sum(qty) as sqty from t1 group by id having count(id) > 0;
+sqty
+5
+9
+select sum(qty) as sqty from t1 group by id having count(distinct id) > 0;
+sqty
+5
+9
+drop table t1;
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index d3d16128ebd..bdf7dc225f3 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -1,41 +1,81 @@
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a NULL NULL NULL NULL
+drop table if exists t1;
+create table t1 (a int not null,b int not null, primary key (a)) type=heap comment="testing heaps" avg_row_length=100 min_rows=1 max_rows=100;
+insert into t1 values(1,1),(2,2),(3,3),(4,4);
+delete from t1 where a=1 or a=0;
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a NULL NULL NULL NULL HASH
+select * from t1;
a b
2 2
3 3
4 4
+select * from t1 where a=4;
a b
4 4
+update t1 set b=5 where a=4;
+update t1 set b=b+1 where a>=3;
+replace t1 values (3,3);
+select * from t1;
a b
2 2
3 3
4 6
+alter table t1 add c int not null, add key (c,a);
+drop table t1;
+create table t1 (a int not null,b int not null, primary key (a)) type=memory comment="testing heaps";
+insert into t1 values(1,1),(2,2),(3,3),(4,4);
+delete from t1 where a > 0;
+select * from t1;
+a b
+drop table t1;
+create table t1 (a int not null,b int not null, primary key (a)) type=heap comment="testing heaps";
+insert into t1 values(1,1),(2,2),(3,3),(4,4);
+alter table t1 modify a int not null auto_increment, type=myisam, comment="new myisam table";
+select * from t1;
a b
1 1
2 2
3 3
4 4
+drop table t1;
+create table t1 (a int not null) type=heap;
+insert into t1 values (869751),(736494),(226312),(802616);
+select * from t1 where a > 736494;
a
869751
802616
+alter table t1 add unique uniq_id(a);
+select * from t1 where a > 736494;
a
869751
802616
+select * from t1 where a = 736494;
a
736494
+select * from t1 where a=869751 or a=736494;
a
736494
869751
+select * from t1 where a in (869751,736494,226312,802616);
a
226312
736494
802616
869751
+alter table t1 type=myisam;
+explain select * from t1 where a in (869751,736494,226312,802616);
table type possible_keys key key_len ref rows Extra
-t1 range uniq_id uniq_id 4 NULL 4 where used; Using index
+t1 range uniq_id uniq_id 4 NULL 4 Using where; Using index
+drop table t1;
+create table t1 (x int not null, y int not null, key x(x), unique y(y))
+type=heap;
+insert into t1 values (1,1),(2,2),(1,3),(2,4),(2,5),(2,6);
+select * from t1 where x=1;
x y
1 3
1 1
+select * from t1,t1 as t2 where t1.x=t2.y;
x y x y
1 1 1 1
2 2 2 2
@@ -43,11 +83,20 @@ x y x y
2 4 2 2
2 5 2 2
2 6 2 2
+explain select * from t1,t1 as t2 where t1.x=t2.y;
table type possible_keys key key_len ref rows Extra
t1 ALL x NULL NULL NULL 6
t2 eq_ref y y 4 t1.x 1
+drop table t1;
+create table t1 (a int) type=heap;
+insert into t1 values(1);
+select max(a) from t1;
max(a)
1
+drop table t1;
+CREATE TABLE t1 ( a int not null default 0, b int not null default 0, key(a), key(b) ) TYPE=HEAP;
+insert into t1 values(1,1),(1,2),(2,3),(1,3),(1,4),(1,5),(1,6);
+select * from t1 where a=1;
a b
1 6
1 5
@@ -55,6 +104,8 @@ a b
1 3
1 2
1 1
+insert into t1 values(1,1),(1,2),(2,3),(1,3),(1,4),(1,5),(1,6);
+select * from t1 where a=1;
a b
1 6
1 5
@@ -68,20 +119,101 @@ a b
1 3
1 2
1 1
+drop table t1;
+create table t1 (id int unsigned not null, primary key (id)) type=HEAP;
+insert into t1 values(1);
+select max(id) from t1;
max(id)
1
+insert into t1 values(2);
+select max(id) from t1;
max(id)
2
+replace into t1 values(1);
+drop table t1;
+create table t1 (n int) type=heap;
+drop table t1;
+create table t1 (n int) type=heap;
+drop table if exists t1;
+CREATE table t1(f1 int not null,f2 char(20) not
+null,index(f2)) type=heap;
+INSERT into t1 set f1=12,f2="bill";
+INSERT into t1 set f1=13,f2="bill";
+INSERT into t1 set f1=14,f2="bill";
+INSERT into t1 set f1=15,f2="bill";
+INSERT into t1 set f1=16,f2="ted";
+INSERT into t1 set f1=12,f2="ted";
+INSERT into t1 set f1=12,f2="ted";
+INSERT into t1 set f1=12,f2="ted";
+INSERT into t1 set f1=12,f2="ted";
+delete from t1 where f2="bill";
+select * from t1;
f1 f2
16 ted
12 ted
12 ted
12 ted
12 ted
+drop table t1;
+create table t1 (btn char(10) not null, key(btn)) type=heap;
+insert into t1 values ("hello"),("hello"),("hello"),("hello"),("hello"),("a"),("b"),("c"),("d"),("e"),("f"),("g"),("h"),("i");
+explain select * from t1 where btn like "q%";
table type possible_keys key key_len ref rows Extra
-t1 ALL btn NULL NULL NULL 14 where used
+t1 ALL btn NULL NULL NULL 14 Using where
+select * from t1 where btn like "q%";
btn
+alter table t1 add column new_col char(1) not null, add key (btn,new_col), drop key btn;
+update t1 set new_col=btn;
+explain select * from t1 where btn="a";
+table type possible_keys key key_len ref rows Extra
+t1 ALL btn NULL NULL NULL 11 Using where
+explain select * from t1 where btn="a" and new_col="a";
+table type possible_keys key key_len ref rows Extra
+t1 ref btn btn 11 const,const 10 Using where
+drop table t1;
+CREATE TABLE t1 (
+a int default NULL,
+b int default NULL,
+KEY a (a),
+UNIQUE b (b)
+) type=heap;
+INSERT INTO t1 VALUES (NULL,99),(99,NULL),(1,1),(2,2),(1,3);
+SELECT * FROM t1 WHERE a=NULL;
+a b
+explain SELECT * FROM t1 WHERE a IS NULL;
+table type possible_keys key key_len ref rows Extra
+t1 ref a a 5 const 10 Using where
+SELECT * FROM t1 WHERE a<=>NULL;
+a b
+NULL 99
+SELECT * FROM t1 WHERE b=NULL;
+a b
+explain SELECT * FROM t1 WHERE b IS NULL;
table type possible_keys key key_len ref rows Extra
-t1 ALL btn NULL NULL NULL 14 where used
+t1 ref b b 5 const 1 Using where
+SELECT * FROM t1 WHERE b<=>NULL;
+a b
+99 NULL
+INSERT INTO t1 VALUES (1,3);
+Duplicate entry '3' for key 1
+DROP TABLE t1;
+CREATE TABLE t1 (
+a int default NULL,
+key a (a)
+) TYPE=HEAP;
+INSERT INTO t1 VALUES (10), (10), (10);
+EXPLAIN SELECT * FROM t1 WHERE a=10;
table type possible_keys key key_len ref rows Extra
-t1 ref btn btn 11 const,const 10 where used
+t1 ref a a 5 const 10 Using where
+SELECT * FROM t1 WHERE a=10;
+a
+10
+10
+10
+DROP TABLE t1;
+CREATE TABLE t1 (a int not null, primary key(a)) type=heap;
+INSERT into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11);
+DELETE from t1 where a < 100;
+SELECT * from t1;
+a
+DROP TABLE t1;
diff --git a/mysql-test/r/innodb-deadlock.result b/mysql-test/r/innodb-deadlock.result
new file mode 100644
index 00000000000..121bfa8c6cb
--- /dev/null
+++ b/mysql-test/r/innodb-deadlock.result
@@ -0,0 +1,20 @@
+drop table if exists t1;
+create table t1 (id integer, x integer) type=INNODB;
+insert into t1 values(0, 0);
+set autocommit=0;
+SELECT * from t1 where id = 0 FOR UPDATE;
+id x
+0 0
+set autocommit=0;
+update t1 set x=2 where id = 0;
+update t1 set x=1 where id = 0;
+select * from t1;
+id x
+0 1
+commit;
+commit;
+select * from t1;
+id x
+0 2
+commit;
+drop table t1;
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 06663e36007..416c583a8d7 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1,3 +1,8 @@
+drop table if exists t1,t2,t3;
+drop database if exists mysqltest;
+create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=innodb;
+insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
+select id, code, name from t1 order by id;
id code name
1 1 Tim
2 1 Monty
@@ -6,6 +11,8 @@ id code name
5 3 Sasha
6 3 Jeremy
7 4 Matt
+update ignore t1 set id = 8, name = 'Sinisa' where id < 3;
+select id, code, name from t1 order by id;
id code name
2 1 Monty
3 2 David
@@ -14,6 +21,8 @@ id code name
6 3 Jeremy
7 4 Matt
8 1 Sinisa
+update ignore t1 set id = id + 10, name = 'Ralph' where id < 4;
+select id, code, name from t1 order by id;
id code name
3 2 David
4 2 Erik
@@ -22,10 +31,26 @@ id code name
7 4 Matt
8 1 Sinisa
12 1 Ralph
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) type=innodb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
id parent_id level
8 102 2
9 102 2
15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+Got one of the listed errors
+select * from t1;
id parent_id level
1001 100 0
1002 101 1
@@ -66,6 +91,8 @@ id parent_id level
1193 105 2
1202 107 2
1203 107 2
+update ignore t1 set id=id+1;
+select * from t1;
id parent_id level
1001 100 0
1002 101 1
@@ -106,16 +133,13 @@ id parent_id level
1194 105 2
1202 107 2
1204 107 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
id parent_id level
1008 102 2
1010 102 2
1015 102 2
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 12 where used; Using index
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 12 where used; Using index
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 12 where used
+select level,id from t1 where level=1;
level id
1 1002
1 1003
@@ -123,6 +147,7 @@ level id
1 1005
1 1006
1 1007
+select level,id,parent_id from t1 where level=1;
level id parent_id
1 1002 101
1 1003 101
@@ -130,142 +155,334 @@ level id parent_id
1 1005 101
1 1006 101
1 1007 101
+optimize table t1;
Table Op Msg_type Msg_text
-test.t1 optimize error The handler for the table doesn't support check/repair
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 id A 87 NULL NULL
-t1 1 parent_id 1 parent_id A 43 NULL NULL
-t1 1 level 1 level A 6 NULL NULL
+test.t1 optimize status OK
+drop table t1;
+CREATE TABLE t1 (
+gesuchnr int(11) DEFAULT '0' NOT NULL,
+benutzer_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (gesuchnr,benutzer_id)
+) type=innodb;
+replace into t1 (gesuchnr,benutzer_id) values (2,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+select * from t1;
gesuchnr benutzer_id
1 1
2 1
+drop table t1;
+create table t1 (a int) type=innodb;
+insert into t1 values (1), (2);
+optimize table t1;
Table Op Msg_type Msg_text
-test.t1 optimize error The handler for the table doesn't support check/repair
+test.t1 optimize status OK
+delete from t1 where a = 1;
+select * from t1;
a
2
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+create table t1 (a int,b varchar(20)) type=innodb;
+insert into t1 values (1,""), (2,"testing");
+delete from t1 where a = 1;
+select * from t1;
a b
2 testing
+create index skr on t1 (a);
+insert into t1 values (3,""), (4,"testing");
+analyze table t1;
Table Op Msg_type Msg_text
-test.t1 analyze error The handler for the table doesn't support check/repair
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 1 skr 1 a A 3 NULL NULL
+test.t1 analyze status OK
+drop table t1;
+create table t1 (a int,b varchar(20),key(a)) type=innodb;
+insert into t1 values (1,""), (2,"testing");
+select * from t1 where a = 1;
a b
1
+drop table t1;
+create table t1 (n int not null primary key) type=innodb;
+set autocommit=0;
+insert into t1 values (4);
+rollback;
+select n, "after rollback" from t1;
n after rollback
+insert into t1 values (4);
+commit;
+select n, "after commit" from t1;
n after commit
4 after commit
+commit;
+insert into t1 values (5);
+insert into t1 values (4);
+Duplicate entry '4' for key 1
+commit;
+select n, "after commit" from t1;
n after commit
4 after commit
5 after commit
+set autocommit=1;
+insert into t1 values (6);
+insert into t1 values (4);
+Duplicate entry '4' for key 1
+select n from t1;
n
4
5
6
+rollback;
+drop table t1;
+create table t1 ( id int NOT NULL PRIMARY KEY, nom varchar(64)) type=innodb;
+begin;
+insert into t1 values(1,'hamdouni');
+select id as afterbegin_id,nom as afterbegin_nom from t1;
afterbegin_id afterbegin_nom
1 hamdouni
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
afterrollback_id afterrollback_nom
+set autocommit=0;
+insert into t1 values(2,'mysql');
+select id as afterautocommit0_id,nom as afterautocommit0_nom from t1;
afterautocommit0_id afterautocommit0_nom
2 mysql
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
afterrollback_id afterrollback_nom
+set autocommit=1;
+drop table t1;
+CREATE TABLE t1 (id char(8) not null primary key, val int not null) type=innodb;
+insert into t1 values ('pippo', 12);
+insert into t1 values ('pippo', 12);
+Duplicate entry 'pippo' for key 1
+delete from t1;
+delete from t1 where id = 'pippo';
+select * from t1;
id val
+insert into t1 values ('pippo', 12);
+set autocommit=0;
+delete from t1;
+rollback;
+select * from t1;
id val
pippo 12
+delete from t1;
+commit;
+select * from t1;
id val
+drop table t1;
+create table t1 (a integer) type=innodb;
+start transaction;
+rename table t1 to t2;
+create table t1 (b integer) type=innodb;
+insert into t1 values (1);
+rollback;
+drop table t1;
+rename table t2 to t1;
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR(64)) TYPE=innodb;
+INSERT INTO t1 VALUES (1, 'Jochen');
+select * from t1;
ID NAME
1 Jochen
+drop table t1;
+CREATE TABLE t1 ( _userid VARCHAR(60) NOT NULL PRIMARY KEY) TYPE=innodb;
+set autocommit=0;
+INSERT INTO t1 SET _userid='marc@anyware.co.uk';
+COMMIT;
+SELECT * FROM t1;
_userid
marc@anyware.co.uk
+SELECT _userid FROM t1 WHERE _userid='marc@anyware.co.uk';
_userid
marc@anyware.co.uk
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (
+user_id int(10) DEFAULT '0' NOT NULL,
+name varchar(100),
+phone varchar(100),
+ref_email varchar(100) DEFAULT '' NOT NULL,
+detail varchar(200),
+PRIMARY KEY (user_id,ref_email)
+)type=innodb;
+INSERT INTO t1 VALUES (10292,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10292,'shirish','2333604','shirish@yahoo.com','ddsds'),(10292,'sonali','323232','sonali@bolly.com','filmstar');
+select * from t1 where user_id=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
+INSERT INTO t1 VALUES (10291,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10293,'shirish','2333604','shirish@yahoo.com','ddsds');
+select * from t1 where user_id=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
+select * from t1 where user_id>=10292;
user_id name phone ref_email detail
10292 sanjeev 29153373 sansh777@hotmail.com xxx
10292 shirish 2333604 shirish@yahoo.com ddsds
10292 sonali 323232 sonali@bolly.com filmstar
10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id>10292;
user_id name phone ref_email detail
10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id<10292;
user_id name phone ref_email detail
10291 sanjeev 29153373 sansh777@hotmail.com xxx
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A NULL NULL NULL
-t1 0 PRIMARY 2 b A 0 NULL NULL
-t1 0 b 1 b A 0 NULL NULL
-t1 0 c 1 c A 0 NULL NULL
-t1 1 a 1 a A NULL NULL NULL
-t1 1 a_2 1 a A NULL NULL NULL
+drop table t1;
+CREATE TABLE t1 (a int not null, b int not null,c int not null,
+key(a),primary key(a,b), unique(c),key(a),unique(b));
+drop table t1;
+create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
+alter table t1 type=innodb;
+insert into t1 values ('1','1'),('5','2'),('2','3'),('3','4'),('4','4');
+select * from t1;
col1 col2
1 1
2 3
3 4
4 4
5 2
+update t1 set col2='7' where col1='4';
+select * from t1;
col1 col2
1 1
2 3
3 4
4 7
5 2
+alter table t1 add co3 int not null;
+select * from t1;
col1 col2 co3
1 1 0
2 3 0
3 4 0
4 7 0
5 2 0
+update t1 set col2='9' where col1='2';
+select * from t1;
col1 col2 co3
1 1 0
2 9 0
3 4 0
4 7 0
5 2 0
+drop table t1;
+create table t1 (a int not null , b int, primary key (a)) type = innodb;
+create table t2 (a int not null , b int, primary key (a)) type = myisam;
+insert into t1 VALUES (1,3) , (2,3), (3,3);
+select * from t1;
a b
1 3
2 3
3 3
+insert into t2 select * from t1;
+select * from t2;
a b
1 3
2 3
3 3
+delete from t1 where b = 3;
+select * from t1;
a b
+insert into t1 select * from t2;
+select * from t1;
a b
1 3
2 3
3 3
+select * from t2;
a b
1 3
2 3
3 3
+drop table t1,t2;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+ggid varchar(32) binary DEFAULT '' NOT NULL,
+email varchar(64) DEFAULT '' NOT NULL,
+passwd varchar(32) binary DEFAULT '' NOT NULL,
+PRIMARY KEY (id),
+UNIQUE ggid (ggid)
+) TYPE=innodb;
+insert into t1 (ggid,passwd) values ('test1','xxx');
+insert into t1 (ggid,passwd) values ('test2','yyy');
+insert into t1 (ggid,passwd) values ('test2','this will fail');
+Duplicate entry 'test2' for key 2
+insert into t1 (ggid,id) values ('this will fail',1);
+Duplicate entry '1' for key 1
+select * from t1 where ggid='test1';
id ggid email passwd
1 test1 xxx
+select * from t1 where passwd='xxx';
id ggid email passwd
1 test1 xxx
+select * from t1 where id=2;
id ggid email passwd
2 test2 yyy
+replace into t1 (ggid,id) values ('this will work',1);
+replace into t1 (ggid,passwd) values ('test2','this will work');
+update t1 set id=100,ggid='test2' where id=1;
+Duplicate entry 'test2' for key 2
+select * from t1;
id ggid email passwd
1 this will work
-4 test2 this will work
+3 test2 this will work
+select * from t1 where id=1;
id ggid email passwd
1 this will work
+select * from t1 where id=999;
id ggid email passwd
+drop table t1;
+CREATE TABLE t1 (
+user_name varchar(12),
+password text,
+subscribed char(1),
+user_id int(11) DEFAULT '0' NOT NULL,
+quota bigint(20),
+weight double,
+access_date date,
+access_time time,
+approved datetime,
+dummy_primary_key int(11) NOT NULL auto_increment,
+PRIMARY KEY (dummy_primary_key)
+) TYPE=innodb;
+INSERT INTO t1 VALUES ('user_0','somepassword','N',0,0,0,'2000-09-07','23:06:59','2000-09-07 23:06:59',1);
+INSERT INTO t1 VALUES ('user_1','somepassword','Y',1,1,1,'2000-09-07','23:06:59','2000-09-07 23:06:59',2);
+INSERT INTO t1 VALUES ('user_2','somepassword','N',2,2,1.4142135623731,'2000-09-07','23:06:59','2000-09-07 23:06:59',3);
+INSERT INTO t1 VALUES ('user_3','somepassword','Y',3,3,1.7320508075689,'2000-09-07','23:06:59','2000-09-07 23:06:59',4);
+INSERT INTO t1 VALUES ('user_4','somepassword','N',4,4,2,'2000-09-07','23:06:59','2000-09-07 23:06:59',5);
+select user_name, password , subscribed, user_id, quota, weight, access_date, access_time, approved, dummy_primary_key from t1 order by user_name;
user_name password subscribed user_id quota weight access_date access_time approved dummy_primary_key
user_0 somepassword N 0 0 0 2000-09-07 23:06:59 2000-09-07 23:06:59 1
user_1 somepassword Y 1 1 1 2000-09-07 23:06:59 2000-09-07 23:06:59 2
user_2 somepassword N 2 2 1.4142135623731 2000-09-07 23:06:59 2000-09-07 23:06:59 3
user_3 somepassword Y 3 3 1.7320508075689 2000-09-07 23:06:59 2000-09-07 23:06:59 4
user_4 somepassword N 4 4 2 2000-09-07 23:06:59 2000-09-07 23:06:59 5
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) type=innodb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1);
+INSERT INTO t1 values (179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
id parent_id level
8 102 2
9 102 2
15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+select * from t1;
id parent_id level
1001 100 0
1003 101 1
@@ -306,6 +523,8 @@ id parent_id level
1019 103 2
1005 101 1
1179 105 2
+update ignore t1 set id=id+1;
+select * from t1;
id parent_id level
1002 100 0
1004 101 1
@@ -346,12 +565,13 @@ id parent_id level
1020 103 2
1006 101 1
1180 105 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
id parent_id level
1009 102 2
1025 102 2
1016 102 2
-table type possible_keys key key_len ref rows Extra
-t1 ref level level 1 const 6 where used; Using index
+select level,id from t1 where level=1;
level id
1 1004
1 1005
@@ -359,6 +579,7 @@ level id
1 1007
1 1008
1 1006
+select level,id,parent_id from t1 where level=1;
level id parent_id
1 1004 101
1 1005 101
@@ -366,6 +587,7 @@ level id parent_id
1 1007 101
1 1008 101
1 1006 101
+select level,id from t1 where level=1 order by id;
level id
1 1003
1 1004
@@ -373,6 +595,8 @@ level id
1 1006
1 1007
1 1008
+delete from t1 where level=1;
+select * from t1;
id parent_id level
1002 100 0
1009 102 2
@@ -407,100 +631,432 @@ id parent_id level
1022 104 2
1020 103 2
1180 105 2
+drop table t1;
+CREATE TABLE t1 (
+sca_code char(6) NOT NULL,
+cat_code char(6) NOT NULL,
+sca_desc varchar(50),
+lan_code char(2) NOT NULL,
+sca_pic varchar(100),
+sca_sdesc varchar(50),
+sca_sch_desc varchar(16),
+PRIMARY KEY (sca_code, cat_code, lan_code),
+INDEX sca_pic (sca_pic)
+) type = innodb ;
+INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING'),( 'QQ', 'N', 'RING', 'EN', 'not null', NULL, 'RING');
+select count(*) from t1 where sca_code = 'PD';
count(*)
1
+select count(*) from t1 where sca_code <= 'PD';
count(*)
1
+select count(*) from t1 where sca_pic is null;
count(*)
2
+alter table t1 drop index sca_pic, add index sca_pic (cat_code, sca_pic);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
count(*)
1
+select count(*) from t1 where cat_code='E';
count(*)
0
+alter table t1 drop index sca_pic, add index (sca_pic, cat_code);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
count(*)
1
+select count(*) from t1 where sca_pic >= 'n';
count(*)
1
+select sca_pic from t1 where sca_pic is null;
sca_pic
NULL
NULL
+update t1 set sca_pic="test" where sca_pic is null;
+delete from t1 where sca_code='pd';
+drop table t1;
+set @a:=now();
+CREATE TABLE t1 (a int not null, b timestamp not null, primary key (a)) type=innodb;
+insert into t1 (a) values(1),(2),(3);
+select t1.a from t1 natural join t1 as t2 where t1.b >= @a order by t1.a;
a
1
2
3
+update t1 set a=5 where a=1;
+select a from t1;
a
2
3
5
+drop table t1;
+create table t1 (a varchar(100) not null, primary key(a), b int not null) type=innodb;
+insert into t1 values("hello",1),("world",2);
+select * from t1 order by b desc;
a b
world 2
hello 1
+optimize table t1;
Table Op Msg_type Msg_text
-test.t1 optimize error The handler for the table doesn't support check/repair
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 2 NULL NULL
+test.t1 optimize status OK
+drop table t1;
+create table t1 (i int, j int ) TYPE=innodb;
+insert into t1 values (1,2);
+select * from t1 where i=1 and j=2;
i j
1 2
+create index ax1 on t1 (i,j);
+select * from t1 where i=1 and j=2;
i j
1 2
+drop table t1;
+CREATE TABLE t1 (
+a int3 unsigned NOT NULL,
+b int1 unsigned NOT NULL,
+UNIQUE (a, b)
+) TYPE = innodb;
+INSERT INTO t1 VALUES (1, 1);
+SELECT MIN(B),MAX(b) FROM t1 WHERE t1.a = 1;
MIN(B) MAX(b)
1 1
+drop table t1;
+CREATE TABLE t1 (a int unsigned NOT NULL) type=innodb;
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
a
1
-table type possible_keys key key_len ref rows Extra
-t1 range PRIMARY PRIMARY 4 NULL 1 where used
+DROP TABLE t1;
+create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h int, i int, j int, k int, l int, m int, n int, o int, p int, q int, r int, s int, t int, u int, v int, w int, x int, y int, z int, a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, b1 int, b2 int, b3 int, b4 int, b5 int, b6 int) type = innodb;
+insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
+drop table t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=innodb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+Duplicate entry '1-1' for key 1
+select id from t1;
id
0
1
2
+select id from t1;
id
0
1
2
+UNLOCK TABLES;
+DROP TABLE t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=innodb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+begin;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+Duplicate entry '1-1' for key 1
+select id from t1;
id
0
1
2
+insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D');
+commit;
+select id,id3 from t1;
id id3
0 0
1 1
2 2
100 2
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` char(20) default NULL,
- KEY `a` (`a`)
-) TYPE=InnoDB
+UNLOCK TABLES;
+DROP TABLE t1;
+create temporary table t1 (a int not null auto_increment, primary key(a)) type=innodb;
+insert into t1 values (NULL),(NULL),(NULL);
+delete from t1 where a=3;
+insert into t1 values (NULL);
+select * from t1;
a
1
2
4
+alter table t1 add b int;
+select * from t1;
a b
1 NULL
2 NULL
4 NULL
+drop table t1;
+create table t1
+(
+id int auto_increment primary key,
+name varchar(32) not null,
+value text not null,
+uid int not null,
+unique key(name,uid)
+) type=innodb;
+insert into t1 values (1,'one','one value',101),
+(2,'two','two value',102),(3,'three','three value',103);
+set insert_id=5;
+replace into t1 (value,name,uid) values ('other value','two',102);
+delete from t1 where uid=102;
+set insert_id=5;
+replace into t1 (value,name,uid) values ('other value','two',102);
+set insert_id=6;
+replace into t1 (value,name,uid) values ('other value','two',102);
+select * from t1;
id name value uid
1 one one value 101
3 three three value 103
6 two other value 102
-table type possible_keys key key_len ref rows Extra
-t1 index NULL PRIMARY 4 NULL 4
-table type possible_keys key key_len ref rows Extra
-t1 index NULL b 4 NULL 4
-table type possible_keys key key_len ref rows Extra
-t1 ALL NULL NULL NULL NULL 4 Using filesort
-table type possible_keys key key_len ref rows Extra
-t1 index NULL PRIMARY 4 NULL 4 Using index
-table type possible_keys key key_len ref rows Extra
-t1 index NULL b 4 NULL 4 Using index
-table type possible_keys key key_len ref rows Extra
-t1 index NULL b 4 NULL 4 Using index
-table type possible_keys key key_len ref rows Extra
-t1 index NULL b 4 NULL 4 Using index
-table type possible_keys key key_len ref rows Extra
-t1 ALL NULL NULL NULL NULL 4
+drop table t1;
+create database mysqltest;
+create table mysqltest.t1 (a int not null) type= innodb;
+insert into mysqltest.t1 values(1);
+create table mysqltest.t2 (a int not null) type= myisam;
+insert into mysqltest.t2 values(1);
+create table mysqltest.t3 (a int not null) type= heap;
+insert into mysqltest.t3 values(1);
+commit;
+drop database mysqltest;
+set autocommit=0;
+create table t1 (a int not null) type= innodb;
+insert into t1 values(1),(2);
+truncate table t1;
+Can't execute the given command because you have active locked tables or an active transaction
+commit;
+truncate table t1;
+select * from t1;
+a
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+a
+commit;
+drop table t1;
+set autocommit=1;
+create table t1 (a int not null) type= innodb;
+insert into t1 values(1),(2);
+truncate table t1;
+insert into t1 values(1),(2);
+select * from t1;
+a
+1
+2
+truncate table t1;
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+a
+drop table t1;
+create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) type=innodb;
+insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4);
+drop table t1;
+create table t1 (t int not null default 1, key (t)) type=innodb;
+desc t1;
Field Type Null Key Default Extra
-testint int(11) 1
+t int(11) MUL 1
+drop table t1;
+CREATE TABLE t1 (
+number bigint(20) NOT NULL default '0',
+cname char(15) NOT NULL default '',
+carrier_id smallint(6) NOT NULL default '0',
+privacy tinyint(4) NOT NULL default '0',
+last_mod_date timestamp(14) NOT NULL,
+last_mod_id smallint(6) NOT NULL default '0',
+last_app_date timestamp(14) NOT NULL,
+last_app_id smallint(6) default '-1',
+version smallint(6) NOT NULL default '0',
+assigned_scps int(11) default '0',
+status tinyint(4) default '0'
+) TYPE=InnoDB;
+INSERT INTO t1 VALUES (4077711111,'SeanWheeler',90,2,20020111112846,500,00000000000000,-1,2,3,1);
+INSERT INTO t1 VALUES (9197722223,'berry',90,3,20020111112809,500,20020102114532,501,4,10,0);
+INSERT INTO t1 VALUES (650,'San Francisco',0,0,20011227111336,342,00000000000000,-1,1,24,1);
+INSERT INTO t1 VALUES (302467,'Sue\'s Subshop',90,3,20020109113241,500,20020102115111,501,7,24,0);
+INSERT INTO t1 VALUES (6014911113,'SudzCarwash',520,1,20020102115234,500,20020102115259,501,33,32768,0);
+INSERT INTO t1 VALUES (333,'tubs',99,2,20020109113440,501,20020109113440,500,3,10,0);
+CREATE TABLE t2 (
+number bigint(20) NOT NULL default '0',
+cname char(15) NOT NULL default '',
+carrier_id smallint(6) NOT NULL default '0',
+privacy tinyint(4) NOT NULL default '0',
+last_mod_date timestamp(14) NOT NULL,
+last_mod_id smallint(6) NOT NULL default '0',
+last_app_date timestamp(14) NOT NULL,
+last_app_id smallint(6) default '-1',
+version smallint(6) NOT NULL default '0',
+assigned_scps int(11) default '0',
+status tinyint(4) default '0'
+) TYPE=InnoDB;
+INSERT INTO t2 VALUES (4077711111,'SeanWheeler',0,2,20020111112853,500,00000000000000,-1,2,3,1);
+INSERT INTO t2 VALUES (9197722223,'berry',90,3,20020111112818,500,20020102114532,501,4,10,0);
+INSERT INTO t2 VALUES (650,'San Francisco',90,0,20020109113158,342,00000000000000,-1,1,24,1);
+INSERT INTO t2 VALUES (333,'tubs',99,2,20020109113453,501,20020109113453,500,3,10,0);
+select * from t1;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+4077711111 SeanWheeler 90 2 20020111112846 500 00000000000000 -1 2 3 1
+9197722223 berry 90 3 20020111112809 500 20020102114532 501 4 10 0
+650 San Francisco 0 0 20011227111336 342 00000000000000 -1 1 24 1
+302467 Sue's Subshop 90 3 20020109113241 500 20020102115111 501 7 24 0
+6014911113 SudzCarwash 520 1 20020102115234 500 20020102115259 501 33 32768 0
+333 tubs 99 2 20020109113440 501 20020109113440 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+4077711111 SeanWheeler 0 2 20020111112853 500 00000000000000 -1 2 3 1
+9197722223 berry 90 3 20020111112818 500 20020102114532 501 4 10 0
+650 San Francisco 90 0 20020109113158 342 00000000000000 -1 1 24 1
+333 tubs 99 2 20020109113453 501 20020109113453 500 3 10 0
+delete t1, t2 from t1 left join t2 on t1.number=t2.number where (t1.carrier_id=90 and t1.number=t2.number) or (t2.carrier_id=90 and t1.number=t2.number) or (t1.carrier_id=90 and t2.number is null);
+select * from t1;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+6014911113 SudzCarwash 520 1 20020102115234 500 20020102115259 501 33 32768 0
+333 tubs 99 2 20020109113440 501 20020109113440 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+333 tubs 99 2 20020109113453 501 20020109113453 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+333 tubs 99 2 20020109113453 501 20020109113453 500 3 10 0
+drop table t1,t2;
+create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=innodb;
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+SELECT @@tx_isolation,@@global.tx_isolation;
+@@tx_isolation @@global.tx_isolation
+SERIALIZABLE REPEATABLE-READ
+insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+COMMIT;
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+insert into t1 (code, name) values (2, 'Erik'), (3, 'Sasha');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+4 2 Erik
+5 3 Sasha
+COMMIT;
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+insert into t1 (code, name) values (3, 'Jeremy'), (4, 'Matt');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+4 2 Erik
+5 3 Sasha
+6 3 Jeremy
+7 4 Matt
+COMMIT;
+DROP TABLE t1;
+drop table if exists t1,t2;
+create table t1 (n int(10), d int(10)) type=innodb;
+create table t2 (n int(10), d int(10)) type=innodb;
+insert into t1 values(1,1),(1,2);
+insert into t2 values(1,10),(2,20);
+UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+select * from t1;
+n d
+1 10
+1 10
+select * from t2;
+n d
+1 30
+2 20
+drop table t1,t2;
+create table t1 (a int, b int) type=innodb;
+insert into t1 values(20,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a;
+b ifnull(t2.b,"this is null")
+NULL this is null
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+b ifnull(t2.b,"this is null")
+NULL this is null
+insert into t1 values(10,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+b ifnull(t2.b,"this is null")
+NULL this is null
+NULL this is null
+drop table t1;
+create table t1 (a varchar(10) not null) type=myisam;
+create table t2 (b varchar(10) not null unique) type=innodb;
+select t1.a from t1,t2 where t1.a=t2.b;
+a
+drop table t1,t2;
+create table t1 (a int not null, b int, primary key (a)) type = innodb;
+create table t2 (a int not null, b int, primary key (a)) type = innodb;
+insert into t1 values (10, 20);
+insert into t2 values (10, 20);
+update t1, t2 set t1.b = 150, t2.b = t1.b where t2.a = t1.a and t1.a = 10;
+drop table t1,t2;
+CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
+CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE ) TYPE=INNODB;
+insert into t1 set id=1;
+insert into t2 set id=1, t1_id=1;
+delete t1,t2 from t1,t2 where t1.id=t2.t1_id;
+select * from t1;
+id
+select * from t2;
+id t1_id
+drop table t2,t1;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1(id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
+CREATE TABLE t2(id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id) ) TYPE=INNODB;
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1, 1);
+SELECT * from t1;
+id
+1
+UPDATE t1,t2 SET t1.id=t1.id+1, t2.t1_id=t1.id+1;
+SELECT * from t1;
+id
+2
+UPDATE t1,t2 SET t1.id=t1.id+1 where t1.id!=t2.id;
+SELECT * from t1;
+id
+3
+DROP TABLE t1,t2;
+set autocommit=0;
+CREATE TABLE t1 (id CHAR(15) NOT NULL, value CHAR(40) NOT NULL, PRIMARY KEY(id)) TYPE=InnoDB;
+CREATE TABLE t2 (id CHAR(15) NOT NULL, value CHAR(40) NOT NULL, PRIMARY KEY(id)) TYPE=InnoDB;
+CREATE TABLE t3 (id1 CHAR(15) NOT NULL, id2 CHAR(15) NOT NULL, PRIMARY KEY(id1, id2)) TYPE=InnoDB;
+INSERT INTO t3 VALUES("my-test-1", "my-test-2");
+COMMIT;
+INSERT INTO t1 VALUES("this-key", "will disappear");
+INSERT INTO t2 VALUES("this-key", "will also disappear");
+DELETE FROM t3 WHERE id1="my-test-1";
+SELECT * FROM t1;
+id value
+this-key will disappear
+SELECT * FROM t2;
+id value
+this-key will also disappear
+SELECT * FROM t3;
+id1 id2
+ROLLBACK;
+SELECT * FROM t1;
+id value
+SELECT * FROM t2;
+id value
+SELECT * FROM t3;
+id1 id2
+my-test-1 my-test-2
+SELECT * FROM t3 WHERE id1="my-test-1" LOCK IN SHARE MODE;
+id1 id2
+my-test-1 my-test-2
+COMMIT;
+set autocommit=1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int not null primary key, b int not null, unique (b)) type=innodb;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+UPDATE t1 set a=a+100 where b between 2 and 3 and a < 1000;
+SELECT * from t1;
a b
1 1
102 2
@@ -511,3 +1067,182 @@ a b
7 7
8 8
9 9
+drop table t1;
+CREATE TABLE t1 (a int not null primary key, b int not null, key (b)) type=innodb;
+CREATE TABLE t2 (a int not null primary key, b int not null, key (b)) type=innodb;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10),(11,11),(12,12);
+INSERT INTO t2 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+update t1,t2 set t1.a=t1.a+100;
+select * from t1;
+a b
+101 1
+102 2
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+110 10
+111 11
+112 12
+update t1,t2 set t1.a=t1.a+100 where t1.a=101;
+select * from t1;
+a b
+201 1
+102 2
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+110 10
+111 11
+112 12
+update t1,t2 set t1.b=t1.b+10 where t1.b=2;
+select * from t1;
+a b
+201 1
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+110 10
+111 11
+102 12
+112 12
+update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t1.a=t2.a+100;
+select * from t1;
+a b
+201 1
+103 5
+104 6
+106 6
+105 7
+107 7
+108 8
+109 9
+110 10
+111 11
+102 12
+112 12
+select * from t2;
+a b
+1 1
+2 2
+6 6
+7 7
+8 8
+9 9
+3 13
+4 14
+5 15
+drop table t1,t2;
+CREATE TABLE t2 ( NEXT_T BIGINT NOT NULL PRIMARY KEY) TYPE=MyISAM;
+CREATE TABLE t1 ( B_ID INTEGER NOT NULL PRIMARY KEY) TYPE=InnoDB;
+SET AUTOCOMMIT=0;
+INSERT INTO t1 ( B_ID ) VALUES ( 1 );
+INSERT INTO t2 ( NEXT_T ) VALUES ( 1 );
+ROLLBACK;
+Warning: Some non-transactional changed tables couldn't be rolled back
+SELECT * FROM t1;
+B_ID
+drop table t1,t2;
+create table t1 ( pk int primary key, parent int not null, child int not null, index (parent) ) type = innodb;
+insert into t1 values (1,0,4), (2,1,3), (3,2,1), (4,1,2);
+select distinct parent,child from t1 order by parent;
+parent child
+0 4
+1 2
+1 3
+2 1
+drop table t1;
+create table t1 (a int not null auto_increment primary key, b int, c int, key(c)) type=innodb;
+create table t2 (a int not null auto_increment primary key, b int);
+insert into t1 (b) values (null),(null),(null),(null),(null),(null),(null);
+insert into t2 (a) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+select count(*) from t1;
+count(*)
+29267
+update t1 set c=a;
+drop table t1,t2;
+create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) type=innodb;
+insert into t1 (id) values (null),(null),(null),(null),(null);
+update t1 set fk=69 where fk is null order by id limit 1;
+SELECT * from t1;
+id fk
+2 NULL
+3 NULL
+4 NULL
+5 NULL
+1 69
+drop table t1;
+create table t1 (a int not null, b int not null, key (a));
+insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3);
+SET @tmp=0;
+update t1 set b=(@tmp:=@tmp+1) order by a;
+update t1 set b=99 where a=1 order by b asc limit 1;
+update t1 set b=100 where a=1 order by b desc limit 2;
+update t1 set a=a+10+b where a=1 order by b;
+select * from t1 order by a,b;
+a b
+2 4
+2 5
+2 6
+3 7
+3 8
+3 9
+3 10
+3 11
+3 12
+13 2
+111 100
+111 100
+drop table t1;
+create table t1 ( c char(8) not null ) type=innodb;
+insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9');
+insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F');
+alter table t1 add b char(8) not null;
+alter table t1 add a char(8) not null;
+alter table t1 add primary key (a,b,c);
+update t1 set a=c, b=c;
+create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=innodb;
+insert into t2 select * from t1;
+delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
+drop table t1,t2;
+SET AUTOCOMMIT=1;
+create table t1 (a integer auto_increment primary key) type=innodb;
+insert into t1 (a) values (NULL),(NULL);
+truncate table t1;
+insert into t1 (a) values (NULL),(NULL);
+SELECT * from t1;
+a
+3
+4
+drop table t1;
+CREATE TABLE t1 (`id 1` INT NOT NULL, PRIMARY KEY (`id 1`)) TYPE=INNODB;
+CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (`t1_id`) REFERENCES `t1`(`id 1`) ON DELETE CASCADE ) TYPE=INNODB;
+drop table t2,t1;
diff --git a/mysql-test/r/innodb_cache.result b/mysql-test/r/innodb_cache.result
new file mode 100644
index 00000000000..47abcb45fe5
--- /dev/null
+++ b/mysql-test/r/innodb_cache.result
@@ -0,0 +1,110 @@
+drop table if exists t1, t2, t3;
+flush status;
+set autocommit=0;
+create table t1 (a int not null) type=innodb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+commit;
+set autocommit=1;
+begin;
+create table t1 (a int not null) type=innodb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+commit;
+create table t1 (a int not null) type=innodb;
+create table t2 (a int not null) type=innodb;
+create table t3 (a int not null) type=innodb;
+insert into t1 values (1),(2);
+insert into t2 values (1),(2);
+insert into t3 values (1),(2);
+select * from t1;
+a
+1
+2
+select * from t2;
+a
+1
+2
+select * from t3;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+begin;
+select * from t1;
+a
+1
+2
+select * from t2;
+a
+1
+2
+select * from t3;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+insert into t1 values (3);
+insert into t2 values (3);
+insert into t1 values (4);
+select * from t1;
+a
+1
+2
+3
+4
+select * from t2;
+a
+1
+2
+3
+select * from t3;
+a
+1
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+commit;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+drop table if exists t1;
+CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) TYPE=InnoDB;
+select count(*) from t1;
+count(*)
+0
+insert into t1 (id) values (0);
+select count(*) from t1;
+count(*)
+1
+drop table t1;
diff --git a/mysql-test/r/innodb_handler.result b/mysql-test/r/innodb_handler.result
new file mode 100644
index 00000000000..8aa5309308f
--- /dev/null
+++ b/mysql-test/r/innodb_handler.result
@@ -0,0 +1,151 @@
+drop table if exists t1;
+create table t1 (a int, b char(10), key a(a), key b(a,b)) type=innodb;
+insert into t1 values
+(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
+(14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"),
+(20,"ggg"),(21,"hhh"),(22,"iii");
+handler t1 open as t2;
+handler t2 read a first;
+a b
+14 aaa
+handler t2 read a next;
+a b
+15 bbb
+handler t2 read a next;
+a b
+16 ccc
+handler t2 read a prev;
+a b
+15 bbb
+handler t2 read a last;
+a b
+22 iii
+handler t2 read a prev;
+a b
+21 hhh
+handler t2 read a prev;
+a b
+20 ggg
+handler t2 read a first;
+a b
+14 aaa
+handler t2 read a prev;
+a b
+handler t2 read a last;
+a b
+22 iii
+handler t2 read a prev;
+a b
+21 hhh
+handler t2 read a next;
+a b
+22 iii
+handler t2 read a next;
+a b
+handler t2 read a=(15);
+a b
+15 bbb
+handler t2 read a=(16);
+a b
+16 ccc
+handler t2 read a=(19,"fff");
+Too many key parts specified. Max 1 parts allowed
+handler t2 read b=(19,"fff");
+a b
+19 fff
+handler t2 read b=(19,"yyy");
+a b
+19 yyy
+handler t2 read b=(19);
+a b
+19 fff
+handler t1 read a last;
+Unknown table 't1' in HANDLER
+handler t2 read a=(11);
+a b
+handler t2 read a>=(11);
+a b
+14 aaa
+handler t2 read a=(18);
+a b
+18 eee
+handler t2 read a>=(18);
+a b
+18 eee
+handler t2 read a>(18);
+a b
+19 fff
+handler t2 read a<=(18);
+a b
+18 eee
+handler t2 read a<(18);
+a b
+17 ddd
+handler t2 read a first limit 5;
+a b
+14 aaa
+15 bbb
+16 ccc
+16 xxx
+17 ddd
+handler t2 read a next limit 3;
+a b
+18 eee
+19 fff
+19 yyy
+handler t2 read a prev limit 10;
+a b
+19 fff
+18 eee
+17 ddd
+16 xxx
+16 ccc
+15 bbb
+14 aaa
+handler t2 read a>=(16) limit 4;
+a b
+16 ccc
+16 xxx
+17 ddd
+18 eee
+handler t2 read a>=(16) limit 2,2;
+a b
+17 ddd
+18 eee
+handler t2 read a last limit 3;
+a b
+22 iii
+21 hhh
+20 ggg
+handler t2 read a=(19);
+a b
+19 fff
+handler t2 read a=(19) where b="yyy";
+a b
+19 yyy
+handler t2 read first;
+a b
+17 ddd
+handler t2 read next;
+a b
+18 eee
+handler t2 read last;
+You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
+handler t2 close;
+handler t1 open as t2;
+handler t2 read first;
+a b
+17 ddd
+alter table t1 type=innodb;
+handler t2 read first;
+Unknown table 't2' in HANDLER
+drop table t1;
+CREATE TABLE t1 ( no1 smallint(5) NOT NULL default '0', no2 int(10) NOT NULL default '0', PRIMARY KEY (no1,no2)) TYPE=InnoDB;
+INSERT INTO t1 VALUES (1,274),(1,275),(2,6),(2,8),(4,1),(4,2);
+HANDLER t1 OPEN;
+HANDLER t1 READ `primary` = (1, 1000);
+no1 no2
+HANDLER t1 READ `primary` PREV;
+no1 no2
+1 275
+DROP TABLE t1;
diff --git a/mysql-test/r/ins000001.result b/mysql-test/r/ins000001.result
deleted file mode 100644
index 283f31ffb43..00000000000
--- a/mysql-test/r/ins000001.result
+++ /dev/null
@@ -1,4 +0,0 @@
-id t2
-1 mysql.com
-2 hotmail.com
-3 aol.com
diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result
index 145ec8a5cf4..7520fd7e6cc 100644
--- a/mysql-test/r/insert.result
+++ b/mysql-test/r/insert.result
@@ -1,6 +1,86 @@
+drop table if exists t1,t2;
+create table t1 (a int not null);
+insert into t1 values (1);
+insert into t1 values (a+2);
+insert into t1 values (a+3);
+insert into t1 values (4),(a+5);
+select * from t1;
a
1
2
3
4
5
+drop table t1;
+create table t1 (id int not null auto_increment primary key, username varchar(32) not null, unique (username));
+insert into t1 values (0,"mysql");
+insert into t1 values (0,"mysql ab");
+insert into t1 values (0,"mysql a");
+insert into t1 values (0,"r1manic");
+insert into t1 values (0,"r1man");
+drop table t1;
+create table t1 (a int not null auto_increment, primary key (a), t timestamp, c char(10) default "hello", i int);
+insert into t1 values (default,default,default,default), (default,default,default,default), (4,0,"a",5),(default,default,default,default);
+select a,t>0,c,i from t1;
+a t>0 c i
+1 1 hello NULL
+2 1 hello NULL
+4 0 a 5
+5 1 hello NULL
+truncate table t1;
+insert into t1 set a=default,t=default,c=default;
+insert into t1 set a=default,t=default,c=default,i=default;
+insert into t1 set a=4,t=0,c="a",i=5;
+insert into t1 set a=5,t=0,c="a",i=null;
+insert into t1 set a=default,t=default,c=default,i=default;
+select a,t>0,c,i from t1;
+a t>0 c i
+1 1 hello NULL
+2 1 hello NULL
+4 0 a 5
+5 0 a NULL
+6 1 hello NULL
+drop table t1;
+create table t1 (sid char(20), id int(2) NOT NULL auto_increment, key(sid, id));
+insert into t1 values ('skr',NULL),('skr',NULL),('test',NULL);
+select * from t1;
+sid id
+skr 1
+skr 2
+test 1
+insert into t1 values ('rts',NULL),('rts',NULL),('test',NULL);
+select * from t1;
+sid id
+rts 1
+rts 2
+skr 1
+skr 2
+test 1
+test 2
+drop table t1;
+create table t1 (id int NOT NULL DEFAULT 8);
+insert into t1 values(NULL);
+Column 'id' cannot be null
+insert into t1 values (1), (NULL), (2);
+select * from t1;
+id
+1
+0
+2
+drop table t1;
+create table t1 (email varchar(50));
+insert into t1 values ('sasha@mysql.com'),('monty@mysql.com'),('foo@hotmail.com'),('foo@aol.com'),('bar@aol.com');
+create table t2(id int not null auto_increment primary key, t2 varchar(50), unique(t2));
+insert delayed into t2 (t2) select distinct substring(email, locate('@', email)+1) from t1;
+select * from t2;
+id t2
+1 mysql.com
+2 hotmail.com
+3 aol.com
+drop table t1,t2;
+drop database if exists mysqltest;
+create database mysqltest;
+use mysqltest;
+create table t1 (c int);
+insert into mysqltest.t1 set mysqltest.t1.c = '1';
+drop database mysqltest;
diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result
index 2435e28d7fe..c5b98976fd6 100644
--- a/mysql-test/r/insert_select.result
+++ b/mysql-test/r/insert_select.result
@@ -1,3 +1,12 @@
+drop table if exists t1,t2;
+create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
+insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12);
+create table t2 (payoutID SMALLINT UNSIGNED NOT NULL PRIMARY KEY);
+insert into t2 (payoutID) SELECT DISTINCT payoutID FROM t1;
+insert into t2 (payoutID) SELECT payoutID+10 FROM t1;
+Duplicate entry '16' for key 1
+insert ignore into t2 (payoutID) SELECT payoutID+10 FROM t1;
+select * from t2;
payoutID
1
4
@@ -11,6 +20,578 @@ payoutID
19
20
22
+drop table t1,t2;
+CREATE TABLE `t1` (
+`numeropost` bigint(20) unsigned NOT NULL default '0',
+`icone` tinyint(4) unsigned NOT NULL default '0',
+`numreponse` bigint(20) unsigned NOT NULL auto_increment,
+`contenu` text NOT NULL,
+`pseudo` varchar(50) NOT NULL default '',
+`date` datetime NOT NULL default '0000-00-00 00:00:00',
+`ip` bigint(11) NOT NULL default '0',
+`signature` tinyint(1) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`,`numreponse`)
+,KEY `ip` (`ip`),
+KEY `date` (`date`),
+KEY `pseudo` (`pseudo`),
+KEY `numreponse` (`numreponse`)
+) TYPE=MyISAM;
+CREATE TABLE `t2` (
+`numeropost` bigint(20) unsigned NOT NULL default '0',
+`icone` tinyint(4) unsigned NOT NULL default '0',
+`numreponse` bigint(20) unsigned NOT NULL auto_increment,
+`contenu` text NOT NULL,
+`pseudo` varchar(50) NOT NULL default '',
+`date` datetime NOT NULL default '0000-00-00 00:00:00',
+`ip` bigint(11) NOT NULL default '0',
+`signature` tinyint(1) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`,`numreponse`),
+KEY `ip` (`ip`),
+KEY `date` (`date`),
+KEY `pseudo` (`pseudo`),
+KEY `numreponse` (`numreponse`)
+) TYPE=MyISAM;
+INSERT INTO t2
+(numeropost,icone,numreponse,contenu,pseudo,date,ip,signature) VALUES
+(9,1,56,'test','joce','2001-07-25 13:50:53'
+,3649052399,0);
+INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip)
+SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM t2
+WHERE numeropost=9 ORDER BY numreponse ASC;
+show variables like '%bulk%';
+Variable_name Value
+bulk_insert_buffer_size 8388608
+INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip)
+SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM t2
+WHERE numeropost=9 ORDER BY numreponse ASC;
+DROP TABLE t1,t2;
+create table t1(a int, unique(a));
+insert into t1 values(2);
+create table t2(a int);
+insert into t2 values(1),(2);
+reset master;
+insert into t1 select * from t2;
+Duplicate entry '2' for key 1
+show binlog events;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
+master-bin.001 79 Query 1 79 use `test`; insert into t1 select * from t2
+drop table t1, t2;
+drop table if exists t1, t2;
+create table t1 (a int not null);
+create table t2 (a int not null);
+insert into t1 values (1);
+insert into t1 values (a+2);
+insert into t1 values (a+3);
+insert into t1 values (4),(a+5);
+insert into t1 select * from t1;
+select * from t1;
+a
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+insert into t1 select * from t1 as t2;
+select * from t1;
+a
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+insert into t2 select * from t1 as t2;
+select * from t1;
+a
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+insert into t1 select t2.a from t1,t2;
+select * from t1;
+a
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+2
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+3
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+4
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+5
+insert into t1 select * from t1,t1;
+Not unique table/alias: 't1'
+drop table t1,t2;
+create table t1 (a int not null primary key, b char(10));
+create table t2 (a int not null, b char(10));
+insert into t1 values (1,"t1:1"),(3,"t1:3");
+insert into t2 values (2,"t2:2"), (3,"t2:3");
+insert into t1 select * from t2;
+Duplicate entry '3' for key 1
+select * from t1;
+a b
+1 t1:1
+3 t1:3
+2 t2:2
+replace into t1 select * from t2;
+select * from t1;
+a b
+1 t1:1
+3 t2:3
+2 t2:2
+drop table t1,t2;
+CREATE TABLE t1 ( USID INTEGER UNSIGNED, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User CHAR(32) NOT NULL DEFAULT '<UNKNOWN>', NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL);
+CREATE TABLE t2 ( USID INTEGER UNSIGNED AUTO_INCREMENT, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User TEXT NOT NULL, NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL, INDEX(USID,ServerID,NASAddr,SessionID), INDEX(AssignedAddr));
+INSERT INTO t1 VALUES (39,42,'Access-Granted','46','491721000045',2130706433,17690,NULL,NULL,'Localnet','491721000045','49172200000',754974766,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2003-07-18 00:11:21',NULL,NULL,20030718001121);
+INSERT INTO t2 SELECT USID, ServerID, State, SessionID, User, NASAddr, NASPort, NASPortType, ConnectSpeed, CarrierType, CallingStationID, CalledStationID, AssignedAddr, SessionTime, PacketsIn, OctetsIn, PacketsOut, OctetsOut, TerminateCause, UnauthTime, AccessRequestTime, AcctStartTime, AcctLastTime, LastModification from t1 LIMIT 1;
+drop table t1,t2;
Month Type Field Count
2003-09-01 1 1 100
2003-09-01 1 2 100
diff --git a/mysql-test/r/isam.result b/mysql-test/r/isam.result
index d5c15527f3e..680d1d6d322 100644
--- a/mysql-test/r/isam.result
+++ b/mysql-test/r/isam.result
@@ -1,12 +1,249 @@
+drop table if exists t1,t2;
+create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a)) type=isam;
+delete from t1 where (a & 1);
+select sum(length(b)) from t1;
+sum(length(b))
+3274494
+drop table t1;
+create table t1 (a int not null auto_increment,b int, primary key (a)) type=isam;
+insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4);
+delete from t1 where a=4 or a=2;
+insert into t1 values (NULL,4),(NULL,5),(6,6);
+select * from t1;
+a b
+1 1
+5 5
+3 3
+4 4
+6 6
+delete from t1 where a=6;
+replace t1 values (3,1);
+replace t1 values (3,3);
+ALTER TABLE t1 add c int;
+insert into t1 values (NULL,6,6);
+select * from t1;
+a b c
+1 1 NULL
+5 5 NULL
+3 3 NULL
+4 4 NULL
+6 6 6
+drop table t1;
+create table t1 (a int,b text, index(a)) type=isam;
+Column 'a' is used with UNIQUE or INDEX but is not defined as NOT NULL
+create table t1 (a int,b text, index(b)) type=isam;
+BLOB column 'b' can't be used in key specification with the used table type
+create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=isam;
+Incorrect table definition; There can only be one auto column and it must be defined as a key
+create table t1 (ordid int(8), unique (ordid)) type=isam;
+Column 'ordid' is used with UNIQUE or INDEX but is not defined as NOT NULL
+drop table if exists t1;
+create table t1 (a int not null primary key, b int not null,c int not null, key(b,c));
+insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4);
+create table t2 type=isam select * from t1;
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+check table t1,t2;
Table Op Msg_type Msg_text
test.t1 check status OK
+test.t2 check error The handler for the table doesn't support check
+repair table t1,t2;
Table Op Msg_type Msg_text
test.t1 repair status OK
+test.t2 repair error The handler for the table doesn't support repair
+check table t2,t1;
Table Op Msg_type Msg_text
+test.t2 check error The handler for the table doesn't support check
test.t1 check status OK
+lock tables t1 write;
+check table t2,t1;
Table Op Msg_type Msg_text
-test.t1 repair status OK
-Table Op Msg_type Msg_text
+test.t2 check error Table 't2' was not locked with LOCK TABLES
test.t1 check status OK
+show columns from t1;
+Field Type Null Key Default Extra
+a int(11) PRI 0
+b int(11) MUL 0
+c int(11) 0
+show full columns from t1;
+Field Type Null Key Default Extra Privileges
+a int(11) PRI 0 select,insert,update,references
+b int(11) MUL 0 select,insert,update,references
+c int(11) 0 select,insert,update,references
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 4 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
+t1 1 b 2 c A 4 NULL NULL BTREE
+drop table t1,t2;
+create table t1 (i1 int, i2 int, i3 int, i4 int, i5 int, i6 int, i7 int, i8
+int, i9 int, i10 int, i11 int, i12 int, i13 int, i14 int, i15 int, i16 int, i17
+int, i18 int, i19 int, i20 int, i21 int, i22 int, i23 int, i24 int, i25 int,
+i26 int, i27 int, i28 int, i29 int, i30 int, i31 int, i32 int, i33 int, i34
+int, i35 int, i36 int, i37 int, i38 int, i39 int, i40 int, i41 int, i42 int,
+i43 int, i44 int, i45 int, i46 int, i47 int, i48 int, i49 int, i50 int, i51
+int, i52 int, i53 int, i54 int, i55 int, i56 int, i57 int, i58 int, i59 int,
+i60 int, i61 int, i62 int, i63 int, i64 int, i65 int, i66 int, i67 int, i68
+int, i69 int, i70 int, i71 int, i72 int, i73 int, i74 int, i75 int, i76 int,
+i77 int, i78 int, i79 int, i80 int, i81 int, i82 int, i83 int, i84 int, i85
+int, i86 int, i87 int, i88 int, i89 int, i90 int, i91 int, i92 int, i93 int,
+i94 int, i95 int, i96 int, i97 int, i98 int, i99 int, i100 int, i101 int, i102
+int, i103 int, i104 int, i105 int, i106 int, i107 int, i108 int, i109 int, i110
+int, i111 int, i112 int, i113 int, i114 int, i115 int, i116 int, i117 int, i118
+int, i119 int, i120 int, i121 int, i122 int, i123 int, i124 int, i125 int, i126
+int, i127 int, i128 int, i129 int, i130 int, i131 int, i132 int, i133 int, i134
+int, i135 int, i136 int, i137 int, i138 int, i139 int, i140 int, i141 int, i142
+int, i143 int, i144 int, i145 int, i146 int, i147 int, i148 int, i149 int, i150
+int, i151 int, i152 int, i153 int, i154 int, i155 int, i156 int, i157 int, i158
+int, i159 int, i160 int, i161 int, i162 int, i163 int, i164 int, i165 int, i166
+int, i167 int, i168 int, i169 int, i170 int, i171 int, i172 int, i173 int, i174
+int, i175 int, i176 int, i177 int, i178 int, i179 int, i180 int, i181 int, i182
+int, i183 int, i184 int, i185 int, i186 int, i187 int, i188 int, i189 int, i190
+int, i191 int, i192 int, i193 int, i194 int, i195 int, i196 int, i197 int, i198
+int, i199 int, i200 int, i201 int, i202 int, i203 int, i204 int, i205 int, i206
+int, i207 int, i208 int, i209 int, i210 int, i211 int, i212 int, i213 int, i214
+int, i215 int, i216 int, i217 int, i218 int, i219 int, i220 int, i221 int, i222
+int, i223 int, i224 int, i225 int, i226 int, i227 int, i228 int, i229 int, i230
+int, i231 int, i232 int, i233 int, i234 int, i235 int, i236 int, i237 int, i238
+int, i239 int, i240 int, i241 int, i242 int, i243 int, i244 int, i245 int, i246
+int, i247 int, i248 int, i249 int, i250 int, i251 int, i252 int, i253 int, i254
+int, i255 int, i256 int, i257 int, i258 int, i259 int, i260 int, i261 int, i262
+int, i263 int, i264 int, i265 int, i266 int, i267 int, i268 int, i269 int, i270
+int, i271 int, i272 int, i273 int, i274 int, i275 int, i276 int, i277 int, i278
+int, i279 int, i280 int, i281 int, i282 int, i283 int, i284 int, i285 int, i286
+int, i287 int, i288 int, i289 int, i290 int, i291 int, i292 int, i293 int, i294
+int, i295 int, i296 int, i297 int, i298 int, i299 int, i300 int, i301 int, i302
+int, i303 int, i304 int, i305 int, i306 int, i307 int, i308 int, i309 int, i310
+int, i311 int, i312 int, i313 int, i314 int, i315 int, i316 int, i317 int, i318
+int, i319 int, i320 int, i321 int, i322 int, i323 int, i324 int, i325 int, i326
+int, i327 int, i328 int, i329 int, i330 int, i331 int, i332 int, i333 int, i334
+int, i335 int, i336 int, i337 int, i338 int, i339 int, i340 int, i341 int, i342
+int, i343 int, i344 int, i345 int, i346 int, i347 int, i348 int, i349 int, i350
+int, i351 int, i352 int, i353 int, i354 int, i355 int, i356 int, i357 int, i358
+int, i359 int, i360 int, i361 int, i362 int, i363 int, i364 int, i365 int, i366
+int, i367 int, i368 int, i369 int, i370 int, i371 int, i372 int, i373 int, i374
+int, i375 int, i376 int, i377 int, i378 int, i379 int, i380 int, i381 int, i382
+int, i383 int, i384 int, i385 int, i386 int, i387 int, i388 int, i389 int, i390
+int, i391 int, i392 int, i393 int, i394 int, i395 int, i396 int, i397 int, i398
+int, i399 int, i400 int, i401 int, i402 int, i403 int, i404 int, i405 int, i406
+int, i407 int, i408 int, i409 int, i410 int, i411 int, i412 int, i413 int, i414
+int, i415 int, i416 int, i417 int, i418 int, i419 int, i420 int, i421 int, i422
+int, i423 int, i424 int, i425 int, i426 int, i427 int, i428 int, i429 int, i430
+int, i431 int, i432 int, i433 int, i434 int, i435 int, i436 int, i437 int, i438
+int, i439 int, i440 int, i441 int, i442 int, i443 int, i444 int, i445 int, i446
+int, i447 int, i448 int, i449 int, i450 int, i451 int, i452 int, i453 int, i454
+int, i455 int, i456 int, i457 int, i458 int, i459 int, i460 int, i461 int, i462
+int, i463 int, i464 int, i465 int, i466 int, i467 int, i468 int, i469 int, i470
+int, i471 int, i472 int, i473 int, i474 int, i475 int, i476 int, i477 int, i478
+int, i479 int, i480 int, i481 int, i482 int, i483 int, i484 int, i485 int, i486
+int, i487 int, i488 int, i489 int, i490 int, i491 int, i492 int, i493 int, i494
+int, i495 int, i496 int, i497 int, i498 int, i499 int, i500 int, i501 int, i502
+int, i503 int, i504 int, i505 int, i506 int, i507 int, i508 int, i509 int, i510
+int, i511 int, i512 int, i513 int, i514 int, i515 int, i516 int, i517 int, i518
+int, i519 int, i520 int, i521 int, i522 int, i523 int, i524 int, i525 int, i526
+int, i527 int, i528 int, i529 int, i530 int, i531 int, i532 int, i533 int, i534
+int, i535 int, i536 int, i537 int, i538 int, i539 int, i540 int, i541 int, i542
+int, i543 int, i544 int, i545 int, i546 int, i547 int, i548 int, i549 int, i550
+int, i551 int, i552 int, i553 int, i554 int, i555 int, i556 int, i557 int, i558
+int, i559 int, i560 int, i561 int, i562 int, i563 int, i564 int, i565 int, i566
+int, i567 int, i568 int, i569 int, i570 int, i571 int, i572 int, i573 int, i574
+int, i575 int, i576 int, i577 int, i578 int, i579 int, i580 int, i581 int, i582
+int, i583 int, i584 int, i585 int, i586 int, i587 int, i588 int, i589 int, i590
+int, i591 int, i592 int, i593 int, i594 int, i595 int, i596 int, i597 int, i598
+int, i599 int, i600 int, i601 int, i602 int, i603 int, i604 int, i605 int, i606
+int, i607 int, i608 int, i609 int, i610 int, i611 int, i612 int, i613 int, i614
+int, i615 int, i616 int, i617 int, i618 int, i619 int, i620 int, i621 int, i622
+int, i623 int, i624 int, i625 int, i626 int, i627 int, i628 int, i629 int, i630
+int, i631 int, i632 int, i633 int, i634 int, i635 int, i636 int, i637 int, i638
+int, i639 int, i640 int, i641 int, i642 int, i643 int, i644 int, i645 int, i646
+int, i647 int, i648 int, i649 int, i650 int, i651 int, i652 int, i653 int, i654
+int, i655 int, i656 int, i657 int, i658 int, i659 int, i660 int, i661 int, i662
+int, i663 int, i664 int, i665 int, i666 int, i667 int, i668 int, i669 int, i670
+int, i671 int, i672 int, i673 int, i674 int, i675 int, i676 int, i677 int, i678
+int, i679 int, i680 int, i681 int, i682 int, i683 int, i684 int, i685 int, i686
+int, i687 int, i688 int, i689 int, i690 int, i691 int, i692 int, i693 int, i694
+int, i695 int, i696 int, i697 int, i698 int, i699 int, i700 int, i701 int, i702
+int, i703 int, i704 int, i705 int, i706 int, i707 int, i708 int, i709 int, i710
+int, i711 int, i712 int, i713 int, i714 int, i715 int, i716 int, i717 int, i718
+int, i719 int, i720 int, i721 int, i722 int, i723 int, i724 int, i725 int, i726
+int, i727 int, i728 int, i729 int, i730 int, i731 int, i732 int, i733 int, i734
+int, i735 int, i736 int, i737 int, i738 int, i739 int, i740 int, i741 int, i742
+int, i743 int, i744 int, i745 int, i746 int, i747 int, i748 int, i749 int, i750
+int, i751 int, i752 int, i753 int, i754 int, i755 int, i756 int, i757 int, i758
+int, i759 int, i760 int, i761 int, i762 int, i763 int, i764 int, i765 int, i766
+int, i767 int, i768 int, i769 int, i770 int, i771 int, i772 int, i773 int, i774
+int, i775 int, i776 int, i777 int, i778 int, i779 int, i780 int, i781 int, i782
+int, i783 int, i784 int, i785 int, i786 int, i787 int, i788 int, i789 int, i790
+int, i791 int, i792 int, i793 int, i794 int, i795 int, i796 int, i797 int, i798
+int, i799 int, i800 int, i801 int, i802 int, i803 int, i804 int, i805 int, i806
+int, i807 int, i808 int, i809 int, i810 int, i811 int, i812 int, i813 int, i814
+int, i815 int, i816 int, i817 int, i818 int, i819 int, i820 int, i821 int, i822
+int, i823 int, i824 int, i825 int, i826 int, i827 int, i828 int, i829 int, i830
+int, i831 int, i832 int, i833 int, i834 int, i835 int, i836 int, i837 int, i838
+int, i839 int, i840 int, i841 int, i842 int, i843 int, i844 int, i845 int, i846
+int, i847 int, i848 int, i849 int, i850 int, i851 int, i852 int, i853 int, i854
+int, i855 int, i856 int, i857 int, i858 int, i859 int, i860 int, i861 int, i862
+int, i863 int, i864 int, i865 int, i866 int, i867 int, i868 int, i869 int, i870
+int, i871 int, i872 int, i873 int, i874 int, i875 int, i876 int, i877 int, i878
+int, i879 int, i880 int, i881 int, i882 int, i883 int, i884 int, i885 int, i886
+int, i887 int, i888 int, i889 int, i890 int, i891 int, i892 int, i893 int, i894
+int, i895 int, i896 int, i897 int, i898 int, i899 int, i900 int, i901 int, i902
+int, i903 int, i904 int, i905 int, i906 int, i907 int, i908 int, i909 int, i910
+int, i911 int, i912 int, i913 int, i914 int, i915 int, i916 int, i917 int, i918
+int, i919 int, i920 int, i921 int, i922 int, i923 int, i924 int, i925 int, i926
+int, i927 int, i928 int, i929 int, i930 int, i931 int, i932 int, i933 int, i934
+int, i935 int, i936 int, i937 int, i938 int, i939 int, i940 int, i941 int, i942
+int, i943 int, i944 int, i945 int, i946 int, i947 int, i948 int, i949 int, i950
+int, i951 int, i952 int, i953 int, i954 int, i955 int, i956 int, i957 int, i958
+int, i959 int, i960 int, i961 int, i962 int, i963 int, i964 int, i965 int, i966
+int, i967 int, i968 int, i969 int, i970 int, i971 int, i972 int, i973 int, i974
+int, i975 int, i976 int, i977 int, i978 int, i979 int, i980 int, i981 int, i982
+int, i983 int, i984 int, i985 int, i986 int, i987 int, i988 int, i989 int, i990
+int, i991 int, i992 int, i993 int, i994 int, i995 int, i996 int, i997 int, i998
+int, i999 int, i1000 int, b blob) row_format=dynamic;
+insert into t1 values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Sergei");
+update t1 set b=repeat('a',256);
+update t1 set i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
diff --git a/mysql-test/r/isolation.result b/mysql-test/r/isolation.result
deleted file mode 100644
index 60b71e217bb..00000000000
--- a/mysql-test/r/isolation.result
+++ /dev/null
@@ -1,61 +0,0 @@
-f1
-test1
-bar
-f1
-test2
-bar
-f1
-test3
-bar
-f1
-f1
-test4
-bar
-f1
-test5
-bar
-f1
-test6
-bar
-f1
-test7
-bar
-f1
-test8
-bar
-f1
-test9
-bar
-f1
-test10
-bar
-f1
-test11
-bar
-f1
-test12
-bar
-f1
-test13
-bar
-f1
-test14
-bar
-f1
-test15
-bar
-f1
-test16
-bar
-f1
-test17
-bar
-f1
-test18
-bar
-f1
-test19
-bar
-f1
-test20
-bar
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index 713d7736585..039b6e1cba3 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1,46 +1,372 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (S1 INT);
+CREATE TABLE t2 (S1 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t1 JOIN t2;
+S1 S1
+1 2
+SELECT * FROM t1 INNER JOIN t2;
+S1 S1
+1 2
+SELECT * from t1 JOIN t2 USING (S1);
+S1 S1
+SELECT * FROM t1 INNER JOIN t2 USING (S1);
+S1 S1
+SELECT * from t1 CROSS JOIN t2;
+S1 S1
+1 2
+SELECT * from t1 LEFT JOIN t2 USING(S1);
+S1 S1
+1 NULL
+SELECT * from t1 LEFT JOIN t2 ON(t2.S1=2);
+S1 S1
+1 2
+SELECT * from t1 RIGHT JOIN t2 USING(S1);
+S1 S1
+NULL 2
+SELECT * from t1 RIGHT JOIN t2 ON(t1.S1=1);
+S1 S1
+1 2
+drop table t1,t2;
+create table t1 (id int primary key);
+create table t2 (id int);
+insert into t1 values (75);
+insert into t1 values (79);
+insert into t1 values (78);
+insert into t1 values (77);
+replace into t1 values (76);
+replace into t1 values (76);
+insert into t1 values (104);
+insert into t1 values (103);
+insert into t1 values (102);
+insert into t1 values (101);
+insert into t1 values (105);
+insert into t1 values (106);
+insert into t1 values (107);
+insert into t2 values (107),(75),(1000);
+select t1.id, t2.id from t1, t2 where t2.id = t1.id;
id id
107 107
75 75
+select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id;
id count(t2.id)
75 1
107 1
+select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id;
id count(t2.id)
75 1
107 1
+select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
+id id
+NULL 75
+explain select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
+table type possible_keys key key_len ref rows Extra
+t1 const PRIMARY NULL NULL NULL 1 Impossible ON condition
+t2 ALL NULL NULL NULL NULL 3 Using where
+explain select t1.id, t2.id from t1, t2 where t2.id = t1.id and t1.id <0 and t1.id > 0;
+Comment
+Impossible WHERE noticed after reading const tables
+drop table t1,t2;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+token varchar(100) DEFAULT '' NOT NULL,
+count int(11) DEFAULT '0' NOT NULL,
+qty int(11),
+phone char(1) DEFAULT '' NOT NULL,
+timestamp datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+PRIMARY KEY (id),
+KEY token (token(15)),
+KEY timestamp (timestamp),
+UNIQUE token_2 (token(75),count,phone)
+);
+INSERT INTO t1 VALUES (21,'e45703b64de71482360de8fec94c3ade',3,7800,'n','1999-12-23 17:22:21');
+INSERT INTO t1 VALUES (22,'e45703b64de71482360de8fec94c3ade',4,5000,'y','1999-12-23 17:22:21');
+INSERT INTO t1 VALUES (18,'346d1cb63c89285b2351f0ca4de40eda',3,13200,'b','1999-12-23 11:58:04');
+INSERT INTO t1 VALUES (17,'ca6ddeb689e1b48a04146b1b5b6f936a',4,15000,'b','1999-12-23 11:36:53');
+INSERT INTO t1 VALUES (16,'ca6ddeb689e1b48a04146b1b5b6f936a',3,13200,'b','1999-12-23 11:36:53');
+INSERT INTO t1 VALUES (26,'a71250b7ed780f6ef3185bfffe027983',5,1500,'b','1999-12-27 09:44:24');
+INSERT INTO t1 VALUES (24,'4d75906f3c37ecff478a1eb56637aa09',3,5400,'y','1999-12-23 17:29:12');
+INSERT INTO t1 VALUES (25,'4d75906f3c37ecff478a1eb56637aa09',4,6500,'y','1999-12-23 17:29:12');
+INSERT INTO t1 VALUES (27,'a71250b7ed780f6ef3185bfffe027983',3,6200,'b','1999-12-27 09:44:24');
+INSERT INTO t1 VALUES (28,'a71250b7ed780f6ef3185bfffe027983',3,5400,'y','1999-12-27 09:44:36');
+INSERT INTO t1 VALUES (29,'a71250b7ed780f6ef3185bfffe027983',4,17700,'b','1999-12-27 09:45:05');
+CREATE TABLE t2 (
+id int(11) NOT NULL auto_increment,
+category int(11) DEFAULT '0' NOT NULL,
+county int(11) DEFAULT '0' NOT NULL,
+state int(11) DEFAULT '0' NOT NULL,
+phones int(11) DEFAULT '0' NOT NULL,
+nophones int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY category (category,county,state)
+);
+INSERT INTO t2 VALUES (3,2,11,12,5400,7800);
+INSERT INTO t2 VALUES (4,2,25,12,6500,11200);
+INSERT INTO t2 VALUES (5,1,37,6,10000,12000);
+select a.id, b.category as catid, b.state as stateid, b.county as countyid from t1 a, t2 b ignore index (primary) where (a.token ='a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id);
id catid stateid countyid
27 2 12 11
28 2 12 11
29 2 12 25
26 1 6 37
+select a.id, b.category as catid, b.state as stateid, b.county as
+countyid from t1 a, t2 b where (a.token =
+'a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id) order by a.id;
id catid stateid countyid
26 1 6 37
27 2 12 11
28 2 12 11
29 2 12 25
+drop table t1, t2;
+create table t1 (a int primary key);
+insert into t1 values(1),(2);
+select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a);
a
1
2
+select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a) left join t1 as t32 using (a) left join t1 as t33 using (a) left join t1 as t34 using (a) left join t1 as t35 using (a) left join t1 as t36 using (a) left join t1 as t37 using (a) left join t1 as t38 using (a) left join t1 as t39 using (a) left join t1 as t40 using (a) left join t1 as t41 using (a) left join t1 as t42 using (a) left join t1 as t43 using (a) left join t1 as t44 using (a) left join t1 as t45 using (a) left join t1 as t46 using (a) left join t1 as t47 using (a) left join t1 as t48 using (a) left join t1 as t49 using (a) left join t1 as t50 using (a) left join t1 as t51 using (a) left join t1 as t52 using (a) left join t1 as t53 using (a) left join t1 as t54 using (a) left join t1 as t55 using (a) left join t1 as t56 using (a) left join t1 as t57 using (a) left join t1 as t58 using (a) left join t1 as t59 using (a) left join t1 as t60 using (a) left join t1 as t61 using (a) left join t1 as t62 using (a) left join t1 as t63 using (a) left join t1 as t64 using (a) left join t1 as t65 using (a);
+Too many tables. MySQL can only use XX tables in a join
+drop table t1;
+CREATE TABLE t1 (
+a int(11) NOT NULL,
+b int(11) NOT NULL,
+PRIMARY KEY (a,b)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(2,3);
+CREATE TABLE t2 (
+a int(11) default NULL
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (2),(3);
+SELECT t1.a,t2.a,b FROM t1,t2 WHERE t1.a=t2.a AND (t1.a=1 OR t1.a=2) AND b>=1 AND b<=3;
a a b
2 2 3
+DROP TABLE t1, t2;
+CREATE TABLE t1 (d DATE NOT NULL);
+CREATE TABLE t2 (d DATE NOT NULL);
+INSERT INTO t1 (d) VALUES ('2001-08-01'),('0000-00-00');
+SELECT * FROM t1 LEFT JOIN t2 USING (d) WHERE t2.d IS NULL;
d d
2001-08-01 NULL
0000-00-00 NULL
+SELECT * from t1 WHERE t1.d IS NULL;
d
0000-00-00
+SELECT * FROM t1 WHERE 1/0 IS NULL;
d
2001-08-01
0000-00-00
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+Document_ID varchar(50) NOT NULL default '',
+Contractor_ID varchar(6) NOT NULL default '',
+Language_ID char(3) NOT NULL default '',
+Expiration_Date datetime default NULL,
+Publishing_Date datetime default NULL,
+Title text,
+Column_ID varchar(50) NOT NULL default '',
+PRIMARY KEY (Language_ID,Document_ID,Contractor_ID)
+);
+INSERT INTO t1 VALUES ('xep80','1','ger','2001-12-31 20:00:00','2001-11-12 10:58:00','Kartenbestellung - jetzt auch online','anle'),('','999998','',NULL,NULL,NULL,'');
+CREATE TABLE t2 (
+Contractor_ID char(6) NOT NULL default '',
+Language_ID char(3) NOT NULL default '',
+Document_ID char(50) NOT NULL default '',
+CanRead char(1) default NULL,
+Customer_ID int(11) NOT NULL default '0',
+PRIMARY KEY (Contractor_ID,Language_ID,Document_ID,Customer_ID)
+);
+INSERT INTO t2 VALUES ('5','ger','xep80','1',999999),('1','ger','xep80','1',999999);
+CREATE TABLE t3 (
+Language_ID char(3) NOT NULL default '',
+Column_ID char(50) NOT NULL default '',
+Contractor_ID char(6) NOT NULL default '',
+CanRead char(1) default NULL,
+Active char(1) default NULL,
+PRIMARY KEY (Language_ID,Column_ID,Contractor_ID)
+);
+INSERT INTO t3 VALUES ('ger','home','1','1','1'),('ger','Test','1','0','0'),('ger','derclu','1','0','0'),('ger','clubne','1','0','0'),('ger','philos','1','0','0'),('ger','clubko','1','0','0'),('ger','clubim','1','1','1'),('ger','progra','1','0','0'),('ger','progvo','1','0','0'),('ger','progsp','1','0','0'),('ger','progau','1','0','0'),('ger','progku','1','0','0'),('ger','progss','1','0','0'),('ger','nachl','1','0','0'),('ger','mitgli','1','0','0'),('ger','mitsu','1','0','0'),('ger','mitbus','1','0','0'),('ger','ergmar','1','1','1'),('ger','home','4','1','1'),('ger','derclu','4','1','1'),('ger','clubne','4','0','0'),('ger','philos','4','1','1'),('ger','clubko','4','1','1'),('ger','clubim','4','1','1'),('ger','progra','4','1','1'),('ger','progvo','4','1','1'),('ger','progsp','4','1','1'),('ger','progau','4','0','0'),('ger','progku','4','1','1'),('ger','progss','4','1','1'),('ger','nachl','4','1','1'),('ger','mitgli','4','0','0'),('ger','mitsu','4','0','0'),('ger','mitbus','4','0','0'),('ger','ergmar','4','1','1'),('ger','progra2','1','0','0'),('ger','archiv','4','1','1'),('ger','anmeld','4','1','1'),('ger','thema','4','1','1'),('ger','edito','4','1','1'),('ger','madis','4','1','1'),('ger','enma','4','1','1'),('ger','madis','1','1','1'),('ger','enma','1','1','1'),('ger','vorsch','4','0','0'),('ger','veranst','4','0','0'),('ger','anle','4','1','1'),('ger','redak','4','1','1'),('ger','nele','4','1','1'),('ger','aukt','4','1','1'),('ger','callcenter','4','1','1'),('ger','anle','1','0','0');
+delete from t1 where Contractor_ID='999998';
+insert into t1 (Contractor_ID) Values ('999998');
+SELECT DISTINCT COUNT(t1.Title) FROM t1,
+t2, t3 WHERE
+t1.Document_ID='xep80' AND t1.Contractor_ID='1' AND
+t1.Language_ID='ger' AND '2001-12-21 23:14:24' >=
+Publishing_Date AND '2001-12-21 23:14:24' <= Expiration_Date AND
+t1.Document_ID = t2.Document_ID AND
+t1.Language_ID = t2.Language_ID AND
+t1.Contractor_ID = t2.Contractor_ID AND (
+t2.Customer_ID = '4' OR
+t2.Customer_ID = '999999' OR
+t2.Customer_ID = '1' )AND t2.CanRead
+= '1' AND t1.Column_ID=t3.Column_ID AND
+t1.Language_ID=t3.Language_ID AND (
+t3.Contractor_ID = '4' OR
+t3.Contractor_ID = '999999' OR
+t3.Contractor_ID = '1') AND
+t3.CanRead='1' AND t3.Active='1';
COUNT(t1.Title)
1
+SELECT DISTINCT COUNT(t1.Title) FROM t1,
+t2, t3 WHERE
+t1.Document_ID='xep80' AND t1.Contractor_ID='1' AND
+t1.Language_ID='ger' AND '2001-12-21 23:14:24' >=
+Publishing_Date AND '2001-12-21 23:14:24' <= Expiration_Date AND
+t1.Document_ID = t2.Document_ID AND
+t1.Language_ID = t2.Language_ID AND
+t1.Contractor_ID = t2.Contractor_ID AND (
+t2.Customer_ID = '4' OR
+t2.Customer_ID = '999999' OR
+t2.Customer_ID = '1' )AND t2.CanRead
+= '1' AND t1.Column_ID=t3.Column_ID AND
+t1.Language_ID=t3.Language_ID AND (
+t3.Contractor_ID = '4' OR
+t3.Contractor_ID = '999999' OR
+t3.Contractor_ID = '1') AND
+t3.CanRead='1' AND t3.Active='1';
COUNT(t1.Title)
1
+drop table t1,t2,t3;
+CREATE TABLE t1 (
+t1_id int(11) default NULL,
+t2_id int(11) default NULL,
+type enum('Cost','Percent') default NULL,
+cost_unit enum('Cost','Unit') default NULL,
+min_value double default NULL,
+max_value double default NULL,
+t3_id int(11) default NULL,
+item_id int(11) default NULL
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (12,5,'Percent','Cost',-1,0,-1,-1),(14,4,'Percent','Cost',-1,0,-1,-1),(18,5,'Percent','Cost',-1,0,-1,-1),(19,4,'Percent','Cost',-1,0,-1,-1),(20,5,'Percent','Cost',100,-1,22,291),(21,5,'Percent','Cost',100,-1,18,291),(22,1,'Percent','Cost',100,-1,6,291),(23,1,'Percent','Cost',100,-1,21,291),(24,1,'Percent','Cost',100,-1,9,291),(25,1,'Percent','Cost',100,-1,4,291),(26,1,'Percent','Cost',100,-1,20,291),(27,4,'Percent','Cost',100,-1,7,202),(28,1,'Percent','Cost',50,-1,-1,137),(29,2,'Percent','Cost',100,-1,4,354),(30,2,'Percent','Cost',100,-1,9,137),(93,2,'Cost','Cost',-1,10000000,-1,-1);
+CREATE TABLE t2 (
+id int(10) unsigned NOT NULL auto_increment,
+name varchar(255) default NULL,
+PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,'s1'),(2,'s2'),(3,'s3'),(4,'s4'),(5,'s5');
+select t1.*, t2.* from t1, t2 where t2.id=t1.t2_id limit 2;
t1_id t2_id type cost_unit min_value max_value t3_id item_id id name
22 1 Percent Cost 100 -1 6 291 1 s1
23 1 Percent Cost 100 -1 21 291 1 s1
+drop table t1,t2;
+CREATE TABLE t1 (
+siteid varchar(25) NOT NULL default '',
+emp_id varchar(30) NOT NULL default '',
+rate_code varchar(10) default NULL,
+UNIQUE KEY site_emp (siteid,emp_id),
+KEY siteid (siteid)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('rivercats','psmith','cust'), ('rivercats','KWalker','cust');
+CREATE TABLE t2 (
+siteid varchar(25) NOT NULL default '',
+rate_code varchar(10) NOT NULL default '',
+base_rate float NOT NULL default '0',
+PRIMARY KEY (siteid,rate_code),
+FULLTEXT KEY rate_code (rate_code)
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES ('rivercats','cust',20);
+SELECT emp.rate_code, lr.base_rate FROM t1 AS emp LEFT JOIN t2 AS lr USING (siteid, rate_code) WHERE emp.emp_id = 'psmith' AND lr.siteid = 'rivercats';
rate_code base_rate
cust 20
+SELECT emp.rate_code, lr.base_rate FROM t1 AS emp LEFT JOIN t2 AS lr USING (siteid, rate_code) WHERE lr.siteid = 'rivercats' AND emp.emp_id = 'psmith';
rate_code base_rate
cust 20
+drop table t1,t2;
+CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, Value1 VARCHAR(255));
+CREATE TABLE t2 (ID INTEGER NOT NULL PRIMARY KEY, Value2 VARCHAR(255));
+INSERT INTO t1 VALUES (1, 'A');
+INSERT INTO t2 VALUES (1, 'B');
+SELECT * FROM t1 NATURAL JOIN t2 WHERE 1 AND (Value1 = 'A' AND Value2 <> 'B');
ID Value1 ID Value2
+SELECT * FROM t1 NATURAL JOIN t2 WHERE 1 AND Value1 = 'A' AND Value2 <> 'B';
ID Value1 ID Value2
+SELECT * FROM t1 NATURAL JOIN t2 WHERE (Value1 = 'A' AND Value2 <> 'B') AND 1;
ID Value1 ID Value2
+drop table t1,t2;
+create table t1 (i int);
+create table t2 (i int);
+create table t3 (i int);
+insert into t1 values(1),(2);
+insert into t2 values(2),(3);
+insert into t3 values (2),(4);
+select * from t1 natural left join t2;
+i i
+1 NULL
+2 2
+select * from t1 left join t2 on (t1.i=t2.i);
+i i
+1 NULL
+2 2
+select * from t1 natural left join t2 natural left join t3;
+i i i
+1 NULL NULL
+2 2 2
+select * from t1 left join t2 on (t1.i=t2.i) left join t3 on (t2.i=t3.i);
+i i i
+1 NULL NULL
+2 2 2
+select * from t3 natural right join t2;
+i i
+2 2
+NULL 3
+select * from t3 right join t2 on (t3.i=t2.i);
+i i
+2 2
+NULL 3
+select * from t3 natural right join t2 natural right join t1;
+i i i
+NULL NULL 1
+2 2 2
+select * from t3 right join t2 on (t3.i=t2.i) right join t1 on (t2.i=t1.i);
+i i i
+NULL NULL 1
+2 2 2
+select * from t1,t2 natural left join t3 order by t1.i,t2.i,t3.i;
+i i i
+1 2 2
+1 3 NULL
+2 2 2
+2 3 NULL
+select * from t1,t2 left join t3 on (t2.i=t3.i) order by t1.i,t2.i,t3.i;
+i i i
+1 2 2
+1 3 NULL
+2 2 2
+2 3 NULL
+select t1.i,t2.i,t3.i from t2 natural left join t3,t1 order by t1.i,t2.i,t3.i;
+i i i
+1 2 2
+1 3 NULL
+2 2 2
+2 3 NULL
+select t1.i,t2.i,t3.i from t2 left join t3 on (t2.i=t3.i),t1 order by t1.i,t2.i,t3.i;
+i i i
+1 2 2
+1 3 NULL
+2 2 2
+2 3 NULL
+select * from t1,t2 natural right join t3 order by t1.i,t2.i,t3.i;
+i i i
+1 NULL 4
+1 2 2
+2 NULL 4
+2 2 2
+select * from t1,t2 right join t3 on (t2.i=t3.i) order by t1.i,t2.i,t3.i;
+i i i
+1 NULL 4
+1 2 2
+2 NULL 4
+2 2 2
+select t1.i,t2.i,t3.i from t2 natural right join t3,t1 order by t1.i,t2.i,t3.i;
+i i i
+1 NULL 4
+1 2 2
+2 NULL 4
+2 2 2
+select t1.i,t2.i,t3.i from t2 right join t3 on (t2.i=t3.i),t1 order by t1.i,t2.i,t3.i;
+i i i
+1 NULL 4
+1 2 2
+2 NULL 4
+2 2 2
+drop table t1,t2,t3;
diff --git a/mysql-test/r/join_crash.result b/mysql-test/r/join_crash.result
index f7bef8af8ec..c7bca9f7497 100644
--- a/mysql-test/r/join_crash.result
+++ b/mysql-test/r/join_crash.result
@@ -1 +1,110 @@
+DROP TABLE IF EXISTS t1,t2,t3,t4;
+CREATE TABLE t1 (
+project_id int(11) NOT NULL auto_increment,
+project_row_lock int(11) NOT NULL default '0',
+project_name varchar(80) NOT NULL default '',
+client_ptr int(11) NOT NULL default '0',
+project_contact_ptr int(11) default NULL,
+client_contact_ptr int(11) default NULL,
+billing_contact_ptr int(11) default NULL,
+comments mediumtext,
+PRIMARY KEY (project_id),
+UNIQUE KEY project (client_ptr,project_name)
+) TYPE=MyISAM PACK_KEYS=1;
+INSERT INTO t1 VALUES (1,0,'Rejected Time',1,NULL,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (209,0,'MDGRAD Proposal/Investigation',97,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (208,0,'Font 9 Design',84,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (207,0,'Web Based Order Processing',95,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (205,0,'Mac Screen Saver',95,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (206,0,'Web Site',96,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (204,0,'Magnafire Glue',94,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (203,0,'Print Bid',93,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (202,0,'EPOC Port',92,NULL,NULL,NULL,'');
+INSERT INTO t1 VALUES (201,0,'TravelMate',88,NULL,NULL,NULL,'');
+CREATE TABLE t2 (
+period_id int(11) NOT NULL auto_increment,
+period_type enum('user_table','client_table','role_table','member_table','project_table') default NULL,
+period_key int(11) default NULL,
+start_date datetime default NULL,
+end_date datetime default NULL,
+work_load int(11) default NULL,
+PRIMARY KEY (period_id),
+KEY period_index (period_type,period_key),
+KEY date_index (start_date,end_date)
+) TYPE=MyISAM PACK_KEYS=1;
+INSERT INTO t2 VALUES (1,'user_table',98,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (2,'user_table',99,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (3,'user_table',100,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (49,'project_table',148,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (50,'client_table',68,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (51,'project_table',149,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (52,'project_table',150,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (53,'client_table',69,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (54,'project_table',151,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (55,'client_table',70,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (155,'role_table',1,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (156,'role_table',2,'2000-01-01 00:00:00',NULL,NULL);
+INSERT INTO t2 VALUES (160,'member_table',1,'2000-01-01 00:00:00',NULL,1);
+INSERT INTO t2 VALUES (161,'member_table',2,'2000-01-01 00:00:00',NULL,1);
+INSERT INTO t2 VALUES (162,'member_table',3,'2000-01-01 00:00:00',NULL,1);
+CREATE TABLE t3 (
+budget_id int(11) NOT NULL auto_increment,
+project_ptr int(11) NOT NULL default '0',
+po_number varchar(20) NOT NULL default '',
+status enum('open','closed') default NULL,
+date_received datetime default NULL,
+amount_received float(10,2) default NULL,
+adjustment float(10,2) default NULL,
+PRIMARY KEY (budget_id),
+UNIQUE KEY po (project_ptr,po_number)
+) TYPE=MyISAM PACK_KEYS=1;
+CREATE TABLE t4 (
+client_id int(11) NOT NULL auto_increment,
+client_row_lock int(11) NOT NULL default '0',
+client_name varchar(80) NOT NULL default '',
+contact_ptr int(11) default NULL,
+comments mediumtext,
+PRIMARY KEY (client_id),
+UNIQUE KEY client_name (client_name)
+) TYPE=MyISAM PACK_KEYS=1;
+INSERT INTO t4 VALUES (1,0,'CPS',NULL,NULL);
+select distinct
+t1.project_id as project_id,
+t1.project_name as project_name,
+t1.client_ptr as client_ptr,
+t1.comments as comments,
+sum( t3.amount_received ) + sum( t3.adjustment ) as total_budget
+from
+t1 ,
+t2 as client_period ,
+t2 as project_period
+left join
+t3
+on
+t3.project_ptr = t1.project_id
+and t3.date_received <= '2001-03-22 14:15:09'
+ left join
+t4
+on
+t4.client_id = t1.client_ptr
+where
+1
+and ( client_period.period_type = 'client_table'
+ and client_period.period_key = t4.client_id
+and ( client_period.start_date <= '2001-03-22 14:15:09' or isnull( client_period.start_date ))
+and ( client_period.end_date > '2001-03-21 14:15:09' or isnull( client_period.end_date ))
+)
+and ( project_period.period_type = 'project_table'
+ and project_period.period_key = t1.project_id
+and ( project_period.start_date <= '2001-03-22 14:15:09' or isnull( project_period.start_date ))
+and ( project_period.end_date > '2001-03-21 14:15:09' or isnull( project_period.end_date )) )
+group by
+client_id,
+project_id ,
+client_period.period_id ,
+project_period.period_id
+order by
+client_name asc,
+project_name asc;
project_id project_name client_ptr comments total_budget
+DROP TABLE t1,t2,t3,t4;
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index f5e643a9bbf..ae4d99e6241 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1,8 +1,19 @@
+drop table if exists t1,t2,t3,t4,t5;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a bigint(20) unsigned default NULL,
+c char(10) NOT NULL default ''
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,1,'a'),(2,2,'b'),(2,3,'c'),(3,4,'E'),(3,5,'C'),(3,6,'D'),(NULL,NULL,'');
+create table t2 (id int, a bigint unsigned not null, c char(10), d int, primary key (a));
+insert into t2 values (1,1,"a",1),(3,4,"A",4),(3,5,"B",5),(3,6,"C",6),(4,7,"D",7);
+select t1.*,t2.* from t1 JOIN t2 where t1.a=t2.a;
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) order by t1.grp,t1.a,t2.c;
grp a c id a c d
NULL NULL NULL NULL NULL NULL
1 1 a 1 1 a 1
@@ -11,18 +22,21 @@ NULL NULL NULL NULL NULL NULL
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from { oj t2 left outer join t1 on (t1.a=t2.a) };
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
NULL NULL NULL 4 7 D 7
+select t1.*,t2.* from t1 as t0,{ oj t2 left outer join t1 on (t1.a=t2.a) } WHERE t0.a=2;
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
NULL NULL NULL 4 7 D 7
+select t1.*,t2.* from t1 left join t2 using (a);
grp a c id a c d
1 1 a 1 1 a 1
2 2 b NULL NULL NULL NULL
@@ -31,11 +45,13 @@ grp a c id a c d
3 5 C 3 5 B 5
3 6 D 3 6 C 6
NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 left join t2 using (a) where t1.a=t2.a;
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from t1 left join t2 using (a,c);
grp a c id a c d
1 1 a 1 1 a 1
2 2 b NULL NULL NULL NULL
@@ -44,6 +60,7 @@ grp a c id a c d
3 5 C NULL NULL NULL NULL
3 6 D NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 left join t2 using (c);
grp a c id a c d
1 1 a 1 1 a 1
1 1 a 3 4 A 4
@@ -53,6 +70,7 @@ grp a c id a c d
3 5 C 3 6 C 6
3 6 D 4 7 D 7
NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 natural left outer join t2;
grp a c id a c d
1 1 a 1 1 a 1
2 2 b NULL NULL NULL NULL
@@ -61,19 +79,24 @@ grp a c id a c d
3 5 C NULL NULL NULL NULL
3 6 D NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL
+select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) where t2.id=3;
grp a c id a c d
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) where t2.id is null;
grp a c id a c d
2 2 b NULL NULL NULL NULL
2 3 c NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL
+explain select t1.*,t2.* from t1,t2 where t1.a=t2.a and isnull(t2.a)=1;
Comment
Impossible WHERE noticed after reading const tables
+explain select t1.*,t2.* from t1 left join t2 on t1.a=t2.a where isnull(t2.a)=1;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 7
-t2 eq_ref PRIMARY PRIMARY 8 t1.a 1 where used
+t2 eq_ref PRIMARY PRIMARY 8 t1.a 1 Using where
+select t1.*,t2.*,t3.a from t1 left join t2 on (t1.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
grp a c id a c d a
1 1 a 1 1 a 1 1
2 2 b NULL NULL NULL NULL NULL
@@ -82,28 +105,161 @@ grp a c id a c d a
3 5 C 3 5 B 5 5
3 6 D 3 6 C 6 6
NULL NULL NULL NULL NULL NULL NULL
+explain select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
+Cross dependency found in OUTER JOIN. Examine your ON conditions
+select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a);
+Cross dependency found in OUTER JOIN. Examine your ON conditions
+select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t2.a=t3.a);
+Cross dependency found in OUTER JOIN. Examine your ON conditions
+select t1.*,t2.* from t1 inner join t2 using (a);
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from t1 inner join t2 on (t1.a=t2.a);
grp a c id a c d
1 1 a 1 1 a 1
3 4 E 3 4 A 4
3 5 C 3 5 B 5
3 6 D 3 6 C 6
+select t1.*,t2.* from t1 natural join t2;
grp a c id a c d
1 1 a 1 1 a 1
+drop table t1,t2;
+CREATE TABLE t1 (
+usr_id INT unsigned NOT NULL,
+uniq_id INT unsigned NOT NULL AUTO_INCREMENT,
+start_num INT unsigned NOT NULL DEFAULT 1,
+increment INT unsigned NOT NULL DEFAULT 1,
+PRIMARY KEY (uniq_id),
+INDEX usr_uniq_idx (usr_id, uniq_id),
+INDEX uniq_usr_idx (uniq_id, usr_id)
+);
+CREATE TABLE t2 (
+id INT unsigned NOT NULL DEFAULT 0,
+usr2_id INT unsigned NOT NULL DEFAULT 0,
+max INT unsigned NOT NULL DEFAULT 0,
+c_amount INT unsigned NOT NULL DEFAULT 0,
+d_max INT unsigned NOT NULL DEFAULT 0,
+d_num INT unsigned NOT NULL DEFAULT 0,
+orig_time INT unsigned NOT NULL DEFAULT 0,
+c_time INT unsigned NOT NULL DEFAULT 0,
+active ENUM ("no","yes") NOT NULL,
+PRIMARY KEY (id,usr2_id),
+INDEX id_idx (id),
+INDEX usr2_idx (usr2_id)
+);
+INSERT INTO t1 VALUES (3,NULL,0,50),(3,NULL,0,200),(3,NULL,0,25),(3,NULL,0,84676),(3,NULL,0,235),(3,NULL,0,10),(3,NULL,0,3098),(3,NULL,0,2947),(3,NULL,0,8987),(3,NULL,0,8347654),(3,NULL,0,20398),(3,NULL,0,8976),(3,NULL,0,500),(3,NULL,0,198);
+SELECT t1.usr_id,t1.uniq_id,t1.increment,
+t2.usr2_id,t2.c_amount,t2.max
+FROM t1
+LEFT JOIN t2 ON t2.id = t1.uniq_id
+WHERE t1.uniq_id = 4
+ORDER BY t2.c_amount;
usr_id uniq_id increment usr2_id c_amount max
3 4 84676 NULL NULL NULL
+SELECT t1.usr_id,t1.uniq_id,t1.increment,
+t2.usr2_id,t2.c_amount,t2.max
+FROM t2
+RIGHT JOIN t1 ON t2.id = t1.uniq_id
+WHERE t1.uniq_id = 4
+ORDER BY t2.c_amount;
usr_id uniq_id increment usr2_id c_amount max
3 4 84676 NULL NULL NULL
+INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
+INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes');
+Duplicate entry '2-3' for key 1
+INSERT INTO t2 VALUES (7,3,1000,2000,0,0,746294,937484,'yes');
+SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4 ORDER BY t2.c_amount;
usr_id uniq_id increment usr2_id c_amount max
3 4 84676 NULL NULL NULL
+SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4 GROUP BY t2.c_amount;
usr_id uniq_id increment usr2_id c_amount max
3 4 84676 NULL NULL NULL
+SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4;
usr_id uniq_id increment usr2_id c_amount max
3 4 84676 NULL NULL NULL
+drop table t1,t2;
+drop table if exists t1,t2,t3,t4;
+CREATE TABLE t1 (
+cod_asig int(11) DEFAULT '0' NOT NULL,
+desc_larga_cat varchar(80) DEFAULT '' NOT NULL,
+desc_larga_cas varchar(80) DEFAULT '' NOT NULL,
+desc_corta_cat varchar(40) DEFAULT '' NOT NULL,
+desc_corta_cas varchar(40) DEFAULT '' NOT NULL,
+cred_total double(3,1) DEFAULT '0.0' NOT NULL,
+pre_requisit int(11),
+co_requisit int(11),
+preco_requisit int(11),
+PRIMARY KEY (cod_asig)
+);
+INSERT INTO t1 VALUES (10360,'asdfggfg','Introduccion a los Ordenadores I','asdfggfg','Introduccio Ordinadors I',6.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (10361,'Components i Circuits Electronics I','Componentes y Circuitos Electronicos I','Components i Circuits Electronics I','Comp. i Circ. Electr. I',6.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (10362,'Laboratori d`Ordinadors','Laboratorio de Ordenadores','Laboratori d`Ordinadors','Laboratori Ordinadors',4.5,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (10363,'Tecniques de Comunicacio Oral i Escrita','Tecnicas de Comunicacion Oral y Escrita','Tecniques de Comunicacio Oral i Escrita','Tec. Com. Oral i Escrita',4.5,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11403,'Projecte Fi de Carrera','Proyecto Fin de Carrera','Projecte Fi de Carrera','PFC',9.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11404,'+lgebra lineal','Algebra lineal','+lgebra lineal','+lgebra lineal',15.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11405,'+lgebra lineal','Algebra lineal','+lgebra lineal','+lgebra lineal',18.0,NULL,NULL,NULL);
+INSERT INTO t1 VALUES (11406,'Calcul Infinitesimal','Cßlculo Infinitesimal','Calcul Infinitesimal','Calcul Infinitesimal',15.0,NULL,NULL,NULL);
+CREATE TABLE t2 (
+idAssignatura int(11) DEFAULT '0' NOT NULL,
+Grup int(11) DEFAULT '0' NOT NULL,
+Places smallint(6) DEFAULT '0' NOT NULL,
+PlacesOcupades int(11) DEFAULT '0',
+PRIMARY KEY (idAssignatura,Grup)
+);
+INSERT INTO t2 VALUES (10360,12,333,0);
+INSERT INTO t2 VALUES (10361,30,2,0);
+INSERT INTO t2 VALUES (10361,40,3,0);
+INSERT INTO t2 VALUES (10360,45,10,0);
+INSERT INTO t2 VALUES (10362,10,12,0);
+INSERT INTO t2 VALUES (10360,55,2,0);
+INSERT INTO t2 VALUES (10360,70,0,0);
+INSERT INTO t2 VALUES (10360,565656,0,0);
+INSERT INTO t2 VALUES (10360,32767,7,0);
+INSERT INTO t2 VALUES (10360,33,8,0);
+INSERT INTO t2 VALUES (10360,7887,85,0);
+INSERT INTO t2 VALUES (11405,88,8,0);
+INSERT INTO t2 VALUES (10360,0,55,0);
+INSERT INTO t2 VALUES (10360,99,0,0);
+INSERT INTO t2 VALUES (11411,30,10,0);
+INSERT INTO t2 VALUES (11404,0,0,0);
+INSERT INTO t2 VALUES (10362,11,111,0);
+INSERT INTO t2 VALUES (10363,33,333,0);
+INSERT INTO t2 VALUES (11412,55,0,0);
+INSERT INTO t2 VALUES (50003,66,6,0);
+INSERT INTO t2 VALUES (11403,5,0,0);
+INSERT INTO t2 VALUES (11406,11,11,0);
+INSERT INTO t2 VALUES (11410,11410,131,0);
+INSERT INTO t2 VALUES (11416,11416,32767,0);
+INSERT INTO t2 VALUES (11409,0,0,0);
+CREATE TABLE t3 (
+id int(11) NOT NULL auto_increment,
+dni_pasaporte char(16) DEFAULT '' NOT NULL,
+idPla int(11) DEFAULT '0' NOT NULL,
+cod_asig int(11) DEFAULT '0' NOT NULL,
+any smallint(6) DEFAULT '0' NOT NULL,
+quatrimestre smallint(6) DEFAULT '0' NOT NULL,
+estat char(1) DEFAULT 'M' NOT NULL,
+PRIMARY KEY (id),
+UNIQUE dni_pasaporte (dni_pasaporte,idPla),
+UNIQUE dni_pasaporte_2 (dni_pasaporte,idPla,cod_asig,any,quatrimestre)
+);
+INSERT INTO t3 VALUES (1,'11111111',1,10362,98,1,'M');
+CREATE TABLE t4 (
+id int(11) NOT NULL auto_increment,
+papa int(11) DEFAULT '0' NOT NULL,
+fill int(11) DEFAULT '0' NOT NULL,
+idPla int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY papa (idPla,papa),
+UNIQUE papa_2 (idPla,papa,fill)
+);
+INSERT INTO t4 VALUES (1,-1,10360,1);
+INSERT INTO t4 VALUES (2,-1,10361,1);
+INSERT INTO t4 VALUES (3,-1,10362,1);
+SELECT DISTINCT fill,desc_larga_cat,cred_total,Grup,Places,PlacesOcupades FROM t4 LEFT JOIN t3 ON t3.cod_asig=fill AND estat='S' AND dni_pasaporte='11111111' AND t3.idPla=1 , t2,t1 WHERE fill=t1.cod_asig AND Places>PlacesOcupades AND fill=idAssignatura AND t4.idPla=1 AND papa=-1;
fill desc_larga_cat cred_total Grup Places PlacesOcupades
10360 asdfggfg 6.0 0 55 0
10360 asdfggfg 6.0 12 333 0
@@ -116,59 +272,88 @@ fill desc_larga_cat cred_total Grup Places PlacesOcupades
10361 Components i Circuits Electronics I 6.0 40 3 0
10362 Laboratori d`Ordinadors 4.5 10 12 0
10362 Laboratori d`Ordinadors 4.5 11 111 0
+SELECT DISTINCT fill,t3.idPla FROM t4 LEFT JOIN t3 ON t3.cod_asig=t4.fill AND t3.estat='S' AND t3.dni_pasaporte='1234' AND t3.idPla=1 ;
fill idPla
10360 NULL
10361 NULL
10362 NULL
+INSERT INTO t3 VALUES (3,'1234',1,10360,98,1,'S');
+SELECT DISTINCT fill,t3.idPla FROM t4 LEFT JOIN t3 ON t3.cod_asig=t4.fill AND t3.estat='S' AND t3.dni_pasaporte='1234' AND t3.idPla=1 ;
fill idPla
10360 1
10361 NULL
10362 NULL
+drop table t1,t2,t3,test.t4;
+CREATE TABLE t1 (
+id smallint(5) unsigned NOT NULL auto_increment,
+name char(60) DEFAULT '' NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (1,'Antonio Paz');
+INSERT INTO t1 VALUES (2,'Lilliana Angelovska');
+INSERT INTO t1 VALUES (3,'Thimble Smith');
+CREATE TABLE t2 (
+id smallint(5) unsigned NOT NULL auto_increment,
+owner smallint(5) unsigned DEFAULT '0' NOT NULL,
+name char(60),
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES (1,1,'El Gato');
+INSERT INTO t2 VALUES (2,1,'Perrito');
+INSERT INTO t2 VALUES (3,3,'Happy');
+select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner);
name name id
Antonio Paz El Gato 1
Antonio Paz Perrito 2
Lilliana Angelovska NULL NULL
Thimble Smith Happy 3
+select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.id is null;
name name id
Lilliana Angelovska NULL NULL
+explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.id is null;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 3
-t2 ALL NULL NULL NULL NULL 3 where used; Not exists
+t2 ALL NULL NULL NULL NULL 3 Using where; Not exists
+explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.name is null;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 3
-t2 ALL NULL NULL NULL NULL 3 where used
+t2 ALL NULL NULL NULL NULL 3 Using where
+select count(*) from t1 left join t2 on (t1.id = t2.owner);
count(*)
4
+select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner);
name name id
Antonio Paz El Gato 1
Antonio Paz Perrito 2
Lilliana Angelovska NULL NULL
Thimble Smith Happy 3
+select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.id is null;
name name id
Lilliana Angelovska NULL NULL
+explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.id is null;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 3
-t2 ALL NULL NULL NULL NULL 3 where used; Not exists
+t2 ALL NULL NULL NULL NULL 3 Using where; Not exists
+explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.name is null;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 3
-t2 ALL NULL NULL NULL NULL 3 where used
+t2 ALL NULL NULL NULL NULL 3 Using where
+select count(*) from t2 right join t1 on (t1.id = t2.owner);
count(*)
4
+select t1.name, t2.name, t2.id,t3.id from t2 right join t1 on (t1.id = t2.owner) left join t1 as t3 on t3.id=t2.owner;
name name id id
Antonio Paz El Gato 1 1
Antonio Paz Perrito 2 1
Lilliana Angelovska NULL NULL NULL
Thimble Smith Happy 3 3
+select t1.name, t2.name, t2.id,t3.id from t1 right join t2 on (t1.id = t2.owner) right join t1 as t3 on t3.id=t2.owner;
name name id id
Antonio Paz El Gato 1 1
Antonio Paz Perrito 2 1
-NULL Happy 3 1
-NULL El Gato 1 2
-NULL Perrito 2 2
-NULL Happy 3 2
-NULL El Gato 1 3
-NULL Perrito 2 3
+NULL NULL NULL 2
Thimble Smith Happy 3 3
+select t1.name, t2.name, t2.id, t2.owner, t3.id from t1 left join t2 on (t1.id = t2.owner) right join t1 as t3 on t3.id=t2.owner;
name name id owner id
Antonio Paz El Gato 1 1 1
Antonio Paz Perrito 2 1 1
@@ -180,49 +365,136 @@ Thimble Smith NULL NULL NULL 2
Antonio Paz NULL NULL NULL 3
Lilliana Angelovska NULL NULL NULL 3
Thimble Smith Happy 3 3 3
+drop table t1,t2;
+create table t1 (id int not null, str char(10), index(str));
+insert into t1 values (1, null), (2, null), (3, "foo"), (4, "bar");
+select * from t1 where str is not null order by id;
id str
-4 bar
3 foo
+4 bar
+select * from t1 where str is null;
id str
1 NULL
2 NULL
+drop table t1;
+CREATE TABLE t1 (
+t1_id bigint(21) NOT NULL auto_increment,
+PRIMARY KEY (t1_id)
+);
+CREATE TABLE t2 (
+t2_id bigint(21) NOT NULL auto_increment,
+PRIMARY KEY (t2_id)
+);
+CREATE TABLE t3 (
+t3_id bigint(21) NOT NULL auto_increment,
+PRIMARY KEY (t3_id)
+);
+CREATE TABLE t4 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+KEY seq_0_id (seq_0_id),
+KEY seq_1_id (seq_1_id)
+);
+CREATE TABLE t5 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+KEY seq_1_id (seq_1_id),
+KEY seq_0_id (seq_0_id)
+);
+insert into t1 values (1);
+insert into t2 values (1);
+insert into t3 values (1);
+insert into t4 values (1,1);
+insert into t5 values (1,1);
+explain select * from t3 left join t4 on t4.seq_1_id = t2.t2_id left join t1 on t1.t1_id = t4.seq_0_id left join t5 on t5.seq_0_id = t1.t1_id left join t2 on t2.t2_id = t5.seq_1_id where t3.t3_id = 23;
+Cross dependency found in OUTER JOIN. Examine your ON conditions
+drop table t1,t2,t3,t4,t5;
+create table t1 (n int, m int, o int, key(n));
+create table t2 (n int not null, m int, o int, primary key(n));
+insert into t1 values (1, 2, 11), (1, 2, 7), (2, 2, 8), (1,2,9),(1,3,9);
+insert into t2 values (1, 2, 3),(2, 2, 8), (4,3,9),(3,2,10);
+select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and
+t1.m = t2.m where t1.n = 1;
n m o n m o
1 2 11 1 2 3
1 2 7 1 2 3
1 2 9 1 2 3
1 3 9 NULL NULL NULL
+select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and
+t1.m = t2.m where t1.n = 1 order by t1.o;
n m o n m o
1 2 7 1 2 3
1 2 9 1 2 3
1 3 9 NULL NULL NULL
1 2 11 1 2 3
+drop table t1,t2;
+CREATE TABLE t1 (id1 INT NOT NULL PRIMARY KEY, dat1 CHAR(1), id2 INT);
+INSERT INTO t1 VALUES (1,'a',1);
+INSERT INTO t1 VALUES (2,'b',1);
+INSERT INTO t1 VALUES (3,'c',2);
+CREATE TABLE t2 (id2 INT NOT NULL PRIMARY KEY, dat2 CHAR(1));
+INSERT INTO t2 VALUES (1,'x');
+INSERT INTO t2 VALUES (2,'y');
+INSERT INTO t2 VALUES (3,'z');
+SELECT t2.id2 FROM t2 LEFT OUTER JOIN t1 ON t1.id2 = t2.id2 WHERE id1 IS NULL;
id2
3
+SELECT t2.id2 FROM t2 NATURAL LEFT OUTER JOIN t1 WHERE id1 IS NULL;
id2
3
+drop table t1,t2;
+create table t1 ( color varchar(20), name varchar(20) );
+insert into t1 values ( 'red', 'apple' );
+insert into t1 values ( 'yellow', 'banana' );
+insert into t1 values ( 'green', 'lime' );
+insert into t1 values ( 'black', 'grape' );
+insert into t1 values ( 'blue', 'blueberry' );
+create table t2 ( count int, color varchar(20) );
+insert into t2 values (10, 'green');
+insert into t2 values (5, 'black');
+insert into t2 values (15, 'white');
+insert into t2 values (7, 'green');
+select * from t1;
color name
red apple
yellow banana
green lime
black grape
blue blueberry
+select * from t2;
count color
10 green
5 black
15 white
7 green
+select * from t2 natural join t1;
count color color name
10 green green lime
7 green green lime
5 black black grape
+select t2.count, t1.name from t2 natural join t1;
count name
10 lime
7 lime
5 grape
+select t2.count, t1.name from t2 inner join t1 using (color);
count name
10 lime
7 lime
5 grape
+drop table t1;
+drop table t2;
+CREATE TABLE t1 (
+pcode varchar(8) DEFAULT '' NOT NULL
+);
+INSERT INTO t1 VALUES ('kvw2000'),('kvw2001'),('kvw3000'),('kvw3001'),('kvw3002'),('kvw3500'),('kvw3501'),('kvw3502'),('kvw3800'),('kvw3801'),('kvw3802'),('kvw3900'),('kvw3901'),('kvw3902'),('kvw4000'),('kvw4001'),('kvw4002'),('kvw4200'),('kvw4500'),('kvw5000'),('kvw5001'),('kvw5500'),('kvw5510'),('kvw5600'),('kvw5601'),('kvw6000'),('klw1000'),('klw1020'),('klw1500'),('klw2000'),('klw2001'),('klw2002'),('kld2000'),('klw2500'),('kmw1000'),('kmw1500'),('kmw2000'),('kmw2001'),('kmw2100'),('kmw3000'),('kmw3200');
+CREATE TABLE t2 (
+pcode varchar(8) DEFAULT '' NOT NULL,
+KEY pcode (pcode)
+);
+INSERT INTO t2 VALUES ('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw6000'),('kvw6000'),('kld2000');
+SELECT t1.pcode, IF(ISNULL(t2.pcode), 0, COUNT(*)) AS count FROM t1
+LEFT JOIN t2 ON t1.pcode = t2.pcode GROUP BY t1.pcode;
pcode count
kld2000 1
klw1000 0
@@ -265,6 +537,7 @@ kvw5510 0
kvw5600 0
kvw5601 0
kvw6000 2
+SELECT SQL_BIG_RESULT t1.pcode, IF(ISNULL(t2.pcode), 0, COUNT(*)) AS count FROM t1 LEFT JOIN t2 ON t1.pcode = t2.pcode GROUP BY t1.pcode;
pcode count
kld2000 1
klw1000 0
@@ -307,27 +580,107 @@ kvw5510 0
kvw5600 0
kvw5601 0
kvw6000 2
+drop table t1,t2;
+CREATE TABLE t1 (
+id int(11),
+pid int(11),
+rep_del tinyint(4),
+KEY id (id),
+KEY pid (pid)
+);
+INSERT INTO t1 VALUES (1,NULL,NULL);
+INSERT INTO t1 VALUES (2,1,NULL);
+select * from t1 LEFT JOIN t1 t2 ON (t1.id=t2.pid) AND t2.rep_del IS NULL;
id pid rep_del id pid rep_del
1 NULL NULL 2 1 NULL
2 1 NULL NULL NULL NULL
+create index rep_del ON t1(rep_del);
+select * from t1 LEFT JOIN t1 t2 ON (t1.id=t2.pid) AND t2.rep_del IS NULL;
id pid rep_del id pid rep_del
1 NULL NULL 2 1 NULL
2 1 NULL NULL NULL NULL
+drop table t1;
+CREATE TABLE t1 (
+id int(11) DEFAULT '0' NOT NULL,
+name tinytext DEFAULT '' NOT NULL,
+UNIQUE id (id)
+);
+INSERT INTO t1 VALUES (1,'yes'),(2,'no');
+CREATE TABLE t2 (
+id int(11) DEFAULT '0' NOT NULL,
+idx int(11) DEFAULT '0' NOT NULL,
+UNIQUE id (id,idx)
+);
+INSERT INTO t2 VALUES (1,1);
+explain SELECT * from t1 left join t2 on t1.id=t2.id where t2.id IS NULL;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 2
-t2 index id id 8 NULL 1 where used; Using index; Not exists
+t2 ref id id 4 t1.id 1 Using where; Using index; Not exists
+SELECT * from t1 left join t2 on t1.id=t2.id where t2.id IS NULL;
id name id idx
2 no NULL NULL
+drop table t1,t2;
+create table t1 (bug_id mediumint, reporter mediumint);
+create table t2 (bug_id mediumint, who mediumint, index(who));
+insert into t2 values (1,1),(1,2);
+insert into t1 values (1,1),(2,1);
+SELECT * FROM t1 LEFT JOIN t2 ON (t1.bug_id = t2.bug_id AND t2.who = 2) WHERE (t1.reporter = 2 OR t2.who = 2);
bug_id reporter bug_id who
1 1 1 2
+drop table t1,t2;
+create table t1 (fooID smallint unsigned auto_increment, primary key (fooID));
+create table t2 (fooID smallint unsigned not null, barID smallint unsigned not null, primary key (fooID,barID));
+insert into t1 (fooID) values (10),(20),(30);
+insert into t2 values (10,1),(20,2),(30,3);
+explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
table type possible_keys key key_len ref rows Extra
t2 index NULL PRIMARY 4 NULL 3 Using index
-t1 eq_ref PRIMARY PRIMARY 2 const 1 where used; Using index
+t1 eq_ref PRIMARY PRIMARY 2 const 1 Using where; Using index
+select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
fooID barID fooID
10 1 NULL
20 2 NULL
30 3 30
+select * from t2 left join t1 ignore index(primary) on t1.fooID = t2.fooID and t1.fooID = 30;
fooID barID fooID
10 1 NULL
20 2 NULL
30 3 30
+drop table t1,t2;
+drop table if exists t3;
+create table t1 (i int);
+create table t2 (i int);
+create table t3 (i int);
+insert into t1 values(1),(2);
+insert into t2 values(2),(3);
+insert into t3 values(2),(4);
+select * from t1 natural left join t2 natural left join t3;
+i i i
+1 NULL NULL
+2 2 2
+drop table t1,t2,t3;
+create table t1 (f1 integer,f2 integer,f3 integer);
+create table t2 (f2 integer,f4 integer);
+create table t3 (f3 integer,f5 integer);
+select * from t1
+left outer join t2 using (f2)
+left outer join t3 using (f3);
+Unknown column 'test.t2.f3' in 'on clause'
+drop table t1,t2,t3;
+create table t1 (a1 int, a2 int);
+create table t2 (b1 int not null, b2 int);
+create table t3 (c1 int, c2 int);
+insert into t1 values (1,2), (2,2), (3,2);
+insert into t2 values (1,3), (2,3);
+insert into t3 values (2,4), (3,4);
+select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
+a1 a2 b1 b2 c1 c2
+1 2 1 3 NULL NULL
+2 2 2 3 NULL NULL
+3 2 NULL NULL 3 4
+explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 3
+t2 ALL NULL NULL NULL NULL 2
+t3 ALL NULL NULL NULL NULL 2
+drop table t1, t2, t3;
diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result
index dbdec824d3b..31d35a681aa 100644
--- a/mysql-test/r/key.result
+++ b/mysql-test/r/key.result
@@ -1,19 +1,179 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (
+ID CHAR(32) NOT NULL,
+name CHAR(32) NOT NULL,
+value CHAR(255),
+INDEX indexIDname (ID(8),name(8))
+) ;
+INSERT INTO t1 VALUES
+('keyword','indexdir','/export/home/local/www/database/indexes/keyword');
+INSERT INTO t1 VALUES ('keyword','urlprefix','text/ /text');
+INSERT INTO t1 VALUES ('keyword','urlmap','/text/ /');
+INSERT INTO t1 VALUES ('keyword','attr','personal employee company');
+INSERT INTO t1 VALUES
+('emailgids','indexdir','/export/home/local/www/database/indexes/emailgids');
+INSERT INTO t1 VALUES ('emailgids','urlprefix','text/ /text');
+INSERT INTO t1 VALUES ('emailgids','urlmap','/text/ /');
+INSERT INTO t1 VALUES ('emailgids','attr','personal employee company');
+SELECT value FROM t1 WHERE ID='emailgids' AND name='attr';
value
personal employee company
+drop table t1;
+CREATE TABLE t1 (
+price int(5) DEFAULT '0' NOT NULL,
+area varchar(40) DEFAULT '' NOT NULL,
+type varchar(40) DEFAULT '' NOT NULL,
+transityes enum('Y','N') DEFAULT 'Y' NOT NULL,
+shopsyes enum('Y','N') DEFAULT 'Y' NOT NULL,
+schoolsyes enum('Y','N') DEFAULT 'Y' NOT NULL,
+petsyes enum('Y','N') DEFAULT 'Y' NOT NULL,
+KEY price (price,area,type,transityes,shopsyes,schoolsyes,petsyes)
+);
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','N','N','N','N');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','N','N','N','N');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','','','','');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
+INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
+SELECT * FROM t1 WHERE area='Vancouver' and transityes='y' and schoolsyes='y' and ( ((type='1 Bedroom' or type='Studio/Bach') and (price<=500)) or ((type='2 Bedroom') and (price<=550)) or ((type='Shared/Roomate') and (price<=300)) or ((type='Room and Board') and (price<=500)) ) and price <= 400;
price area type transityes shopsyes schoolsyes petsyes
+drop table t1;
+CREATE TABLE t1 (program enum('signup','unique','sliding') not null, type enum('basic','sliding','signup'), sites set('mt'), PRIMARY KEY (program));
+ALTER TABLE t1 modify program enum('signup','unique','sliding');
+drop table t1;
+CREATE TABLE t1 (
+name varchar(50) DEFAULT '' NOT NULL,
+author varchar(50) DEFAULT '' NOT NULL,
+category decimal(10,0) DEFAULT '0' NOT NULL,
+email varchar(50),
+password varchar(50),
+proxy varchar(50),
+bitmap varchar(20),
+msg varchar(255),
+urlscol varchar(127),
+urlhttp varchar(127),
+timeout decimal(10,0),
+nbcnx decimal(10,0),
+creation decimal(10,0),
+livinguntil decimal(10,0),
+lang decimal(10,0),
+type decimal(10,0),
+subcat decimal(10,0),
+subtype decimal(10,0),
+reg char(1),
+scs varchar(255),
+capacity decimal(10,0),
+userISP varchar(50),
+CCident varchar(50) DEFAULT '' NOT NULL,
+PRIMARY KEY (name,author,category)
+);
+INSERT INTO t1 VALUES
+('patnom','patauteur',0,'p.favre@cryo-networks.fr',NULL,NULL,'#p2sndnq6ae5g1u6t','essai\nsalut','scol://195.242.78.119:patauteur.patnom',NULL,NULL,NULL,950036174,-882087474,NULL,3,0,3,'1','Pub/patnom/futur_divers.scs',NULL,'pat','CC1');
+INSERT INTO t1 VALUES
+('LeNomDeMonSite','Marc',0,'m.barilley@cryo-networks.fr',NULL,NULL,NULL,NULL,'scol://195.242.78.119:Marc.LeNomDeMonSite',NULL,NULL,NULL,950560434,-881563214,NULL,3,0,3,'1','Pub/LeNomDeMonSite/domus_hibere.scs',NULL,'Marq','CC1');
+select * from t1 where name='patnom' and author='patauteur' and category=0;
name author category email password proxy bitmap msg urlscol urlhttp timeout nbcnx creation livinguntil lang type subcat subtype reg scs capacity userISP CCident
patnom patauteur 0 p.favre@cryo-networks.fr NULL NULL #p2sndnq6ae5g1u6t essai
salut scol://195.242.78.119:patauteur.patnom NULL NULL NULL 950036174 -882087474 NULL 3 0 3 1 Pub/patnom/futur_divers.scs NULL pat CC1
+drop table t1;
+create table t1
+(
+name_id int not null auto_increment,
+name blob,
+INDEX name_idx (name(5)),
+primary key (name_id)
+);
+INSERT t1 VALUES(NULL,'/');
+INSERT t1 VALUES(NULL,'[T,U]_axpby');
+SELECT * FROM t1 WHERE name='[T,U]_axpy';
name_id name
+SELECT * FROM t1 WHERE name='[T,U]_axpby';
name_id name
2 [T,U]_axpby
+create table t2
+(
+name_id int not null auto_increment,
+name char(255) binary,
+INDEX name_idx (name(5)),
+primary key (name_id)
+);
+INSERT t2 select * from t1;
+SELECT * FROM t2 WHERE name='[T,U]_axpy';
name_id name
+SELECT * FROM t2 WHERE name='[T,U]_axpby';
name_id name
2 [T,U]_axpby
+drop table t1,t2;
+create table t1
+(
+SEQNO numeric(12 ) not null,
+MOTYPEID numeric(12 ) not null,
+MOINSTANCEID numeric(12 ) not null,
+ATTRID numeric(12 ) not null,
+VALUE varchar(120) not null,
+primary key (SEQNO, MOTYPEID, MOINSTANCEID, ATTRID, VALUE )
+);
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'b');
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
+Duplicate entry '1-1-1-1-a' for key 1
+drop table t1;
+CREATE TABLE t1 (
+a tinytext NOT NULL,
+b tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (a(32),b)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('a',1),('a',2);
+SELECT * FROM t1 WHERE a='a' AND b=2;
a b
a 2
+SELECT * FROM t1 WHERE a='a' AND b in (2);
a b
a 2
+SELECT * FROM t1 WHERE a='a' AND b in (1,2);
a b
a 1
a 2
+drop table t1;
+create table t1 (a int not null unique, b int unique, c int, d int not null primary key, key(c), e int not null unique);
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 d A 0 NULL NULL BTREE
+t1 0 a 1 a A 0 NULL NULL BTREE
+t1 0 e 1 e A 0 NULL NULL BTREE
+t1 0 b 1 b A NULL NULL NULL YES BTREE
+t1 1 c 1 c A NULL NULL NULL YES BTREE
+drop table t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NOT NULL,i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+c i
+ 1
+ 2
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+c i
+ 1
+ 2
+a 1
+a 2
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NULL, i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+c i
+NULL 1
+NULL 2
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+c i
+NULL 1
+NULL 2
+a 1
+a 2
+drop table t1;
diff --git a/mysql-test/r/key_diff.result b/mysql-test/r/key_diff.result
index ab5b9bcc0e7..2d4bc19474f 100644
--- a/mysql-test/r/key_diff.result
+++ b/mysql-test/r/key_diff.result
@@ -1,3 +1,12 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+a char(5) NOT NULL,
+b char(4) NOT NULL,
+KEY (a),
+KEY (b)
+);
+INSERT INTO t1 VALUES ('A','B'),('b','A'),('C','c'),('D','E'),('a','a');
+select * from t1,t1 as t2;
a b a b
A B A B
b A A B
@@ -24,9 +33,11 @@ b A a a
C c a a
D E a a
a a a a
+explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B;
table type possible_keys key key_len ref rows Extra
t1 ALL a NULL NULL NULL 5
-t2 ALL b NULL NULL NULL 5 where used
+t2 ALL b NULL NULL NULL 4 Using where
+select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a;
a b a b
A B a a
A B b A
@@ -34,6 +45,8 @@ C c C c
a a a a
a a b A
b A A B
+select * from t1 where a='a';
a b
A B
a a
+drop table t1;
diff --git a/mysql-test/r/key_primary.result b/mysql-test/r/key_primary.result
index ee0c1c957dc..87289f1cf54 100644
--- a/mysql-test/r/key_primary.result
+++ b/mysql-test/r/key_primary.result
@@ -1,9 +1,20 @@
+drop table if exists t1;
+create table t1 (t1 char(3) primary key);
+insert into t1 values("ABC");
+insert into t1 values("ABA");
+insert into t1 values("AB%");
+select * from t1 where t1="ABC";
t1
ABC
+select * from t1 where t1="ABCD";
t1
+select * from t1 where t1 like "a_\%";
t1
AB%
+describe select * from t1 where t1="ABC";
table type possible_keys key key_len ref rows Extra
t1 const PRIMARY PRIMARY 3 const 1
+describe select * from t1 where t1="ABCD";
Comment
Impossible WHERE noticed after reading const tables
+drop table t1;
diff --git a/mysql-test/r/keywords.result b/mysql-test/r/keywords.result
index f49681ad93b..2ca36425841 100644
--- a/mysql-test/r/keywords.result
+++ b/mysql-test/r/keywords.result
@@ -1,4 +1,16 @@
+drop table if exists t1;
+create table t1 (time time, date date, timestamp timestamp);
+insert into t1 values ("12:22:22","97:02:03","1997-01-02");
+select * from t1;
time date timestamp
12:22:22 1997-02-03 19970102000000
+select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time) from t1;
t1.time+0 t1.date+0 t1.timestamp+0 concat(date," ",time)
122222 19970203 19970102000000 1997-02-03 12:22:22
+drop table t1;
+create table events(binlog int);
+insert into events values(1);
+select events.binlog from events;
+binlog
+1
+drop table events;
diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result
index 628c6d21094..788fab8d31a 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -1,4 +1,11 @@
+drop table if exists t1;
+create table t1 (kill_id int);
+insert into t1 values(connection_id());
+select ((@id := kill_id) - kill_id) from t1;
((@id := kill_id) - kill_id)
0
+kill @id;
+select 4;
4
4
+drop table t1;
diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result
index 6c3a1ed17e4..c82105e6a49 100644
--- a/mysql-test/r/limit.result
+++ b/mysql-test/r/limit.result
@@ -1,25 +1,69 @@
+drop table if exists t1;
+create table t1 (a int primary key, b int not null);
+insert into t1 () values ();
+insert into t1 values (1,1),(2,1),(3,1);
+update t1 set a=4 where b=1 limit 1;
+select * from t1;
a b
0 0
4 1
2 1
3 1
+update t1 set b=2 where b=1 limit 2;
+select * from t1;
a b
0 0
4 2
2 2
3 1
+update t1 set b=4 where b=1;
+select * from t1;
a b
0 0
4 2
2 2
3 4
+delete from t1 where b=2 limit 1;
+select * from t1;
a b
0 0
2 2
3 4
+delete from t1 limit 1;
+select * from t1;
a b
2 2
3 4
+drop table t1;
+create table t1 (i int);
+insert into t1 (i) values(1),(1),(1);
+delete from t1 limit 1;
+update t1 set i=2 limit 1;
+delete from t1 limit 0;
+update t1 set i=3 limit 0;
+select * from t1;
i
2
1
+drop table t1;
+select 0 limit 0;
+0
+CREATE TABLE t1(id int auto_increment primary key, id2 int, index(id2));
+INSERT INTO t1 (id2) values (0),(0),(0);
+DELETE FROM t1 WHERE id=1;
+INSERT INTO t1 SET id2=0;
+SELECT * FROM t1;
+id id2
+4 0
+2 0
+3 0
+DELETE FROM t1 WHERE id2 = 0 ORDER BY id LIMIT 1;
+SELECT * FROM t1;
+id id2
+4 0
+3 0
+DELETE FROM t1 WHERE id2 = 0 ORDER BY id desc LIMIT 1;
+SELECT * FROM t1;
+id id2
+3 0
+DROP TABLE t1;
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
new file mode 100644
index 00000000000..1730d7b5c25
--- /dev/null
+++ b/mysql-test/r/loaddata.result
@@ -0,0 +1,46 @@
+drop table if exists t1;
+create table t1 (a date, b date, c date not null, d date);
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',';
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' IGNORE 2 LINES;
+SELECT * from t1;
+a b c d
+0000-00-00 NULL 0000-00-00 0000-00-00
+0000-00-00 0000-00-00 0000-00-00 0000-00-00
+2003-03-03 2003-03-03 2003-03-03 NULL
+2003-03-03 2003-03-03 2003-03-03 NULL
+truncate table t1;
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' LINES STARTING BY ',' (b,c,d);
+SELECT * from t1;
+a b c d
+NULL NULL 0000-00-00 0000-00-00
+NULL 0000-00-00 0000-00-00 0000-00-00
+NULL 2003-03-03 2003-03-03 NULL
+drop table t1;
+create table t1 (a text, b text);
+load data infile '../../std_data/loaddata2.dat' into table t1 fields terminated by ',' enclosed by '''';
+select concat('|',a,'|'), concat('|',b,'|') from t1;
+concat('|',a,'|') concat('|',b,'|')
+|Field A| |Field B|
+|Field 1| |Field 2'
+Field 3,'Field 4|
+|Field 5' ,'Field 6| NULL
+|Field 6| | 'Field 7'|
+drop table t1;
+create table t1 (a int, b char(10));
+load data infile '../../std_data/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines;
+select * from t1;
+a b
+1 row 1
+2 row 2
+0 1234567890
+3 row 3
+0 1234567890
+truncate table t1;
+load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines;
+select * from t1;
+a b
+1 row 1
+2 row 2
+3 row 3
+0
+drop table t1;
diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result
index ccd3c02558d..31a18fe6cec 100644
--- a/mysql-test/r/lock.result
+++ b/mysql-test/r/lock.result
@@ -1,10 +1,49 @@
+drop table if exists t1,t2;
+CREATE TABLE t1 ( `id` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0', `id3` int(11) NOT NULL default '0', `dummy1` char(30) default NULL, PRIMARY KEY (`id`,`id2`), KEY `index_id3` (`id3`)) TYPE=MyISAM;
+insert into t1 (id,id2) values (1,1),(1,2),(1,3);
+LOCK TABLE t1 WRITE;
+select dummy1,count(distinct id) from t1 group by dummy1;
dummy1 count(distinct id)
NULL 1
+update t1 set id=-1 where id=1;
+LOCK TABLE t1 READ;
+update t1 set id=1 where id=1;
+Table 't1' was locked with a READ lock and can't be updated
+create table t2 SELECT * from t1;
+Table 't2' was not locked with LOCK TABLES
+create temporary table t2 SELECT * from t1;
+drop table if exists t2;
+unlock tables;
+create table t2 SELECT * from t1;
+LOCK TABLE t1 WRITE,t2 write;
+insert into t2 SELECT * from t1;
+update t1 set id=1 where id=-1;
+drop table t1,t2;
+CREATE TABLE t1 (
+index1 smallint(6) default NULL,
+nr smallint(6) default NULL,
+KEY index1(index1)
+) TYPE=MyISAM;
+CREATE TABLE t2 (
+nr smallint(6) default NULL,
+name varchar(20) default NULL
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,'item1');
+INSERT INTO t2 VALUES (2,'item2');
+lock tables t1 write, t2 read;
+insert into t1 select 1,nr from t2 where name='item1';
+insert into t1 select 2,nr from t2 where name='item2';
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write;
+check table t2;
Table Op Msg_type Msg_text
test.t2 check error Table 't2' was not locked with LOCK TABLES
-n
-4
-n
-1
+insert into t1 select nr from t1;
+Table 't1' was not locked with LOCK TABLES
+unlock tables;
+lock tables t1 write, t1 as t1_alias read;
+insert into t1 select index1,nr from t1 as t1_alias;
+drop table t1,t2;
diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result
new file mode 100644
index 00000000000..b808fca0acf
--- /dev/null
+++ b/mysql-test/r/lock_multi.result
@@ -0,0 +1,26 @@
+drop table if exists t1,t2;
+create table t1(n int);
+insert into t1 values (1);
+lock tables t1 write;
+ update low_priority t1 set n = 4;
+ select n from t1;
+unlock tables;
+n
+4
+drop table t1;
+create table t1(n int);
+insert into t1 values (1);
+lock tables t1 read;
+ update low_priority t1 set n = 4;
+ select n from t1;
+unlock tables;
+n
+1
+drop table t1;
+create table t1 (a int);
+create table t2 (a int);
+lock table t1 write, t2 write;
+ insert t1 select * from t2;
+drop table t2;
+Table 'test.t2' doesn't exist
+drop table t1;
diff --git a/mysql-test/r/lock_tables_lost_commit.result b/mysql-test/r/lock_tables_lost_commit.result
new file mode 100644
index 00000000000..ccf56793f45
--- /dev/null
+++ b/mysql-test/r/lock_tables_lost_commit.result
@@ -0,0 +1,8 @@
+drop table if exists t1;
+create table t1(a int) type=innodb;
+lock tables t1 write;
+insert into t1 values(10);
+select * from t1;
+a
+10
+drop table t1;
diff --git a/mysql-test/r/lowercase2.require b/mysql-test/r/lowercase2.require
new file mode 100644
index 00000000000..522eac63e81
--- /dev/null
+++ b/mysql-test/r/lowercase2.require
@@ -0,0 +1,2 @@
+Variable_name Value
+lower_case_table_names 2
diff --git a/mysql-test/r/lowercase_table.result b/mysql-test/r/lowercase_table.result
new file mode 100644
index 00000000000..16bc92cb711
--- /dev/null
+++ b/mysql-test/r/lowercase_table.result
@@ -0,0 +1,41 @@
+drop table if exists t1,t2,t3,t4,T1;
+create table T1 (id int primary key, Word varchar(40) not null, Index(Word));
+create table t4 (id int primary key, Word varchar(40) not null);
+INSERT INTO T1 VALUES (1, 'a'), (2, 'b'), (3, 'c');
+INSERT INTO T4 VALUES(1,'match');
+SELECT * FROM t1;
+id Word
+1 a
+2 b
+3 c
+SELECT T1.id from T1 LIMIT 1;
+id
+1
+SELECT T2.id from t1 as T2 LIMIT 1;
+id
+1
+SELECT * from t1 left join t4 on (test.t1.id= TEST.t4.id) where TEST.t1.id >= test.t4.id;
+id Word id Word
+1 a 1 match
+SELECT T2.id from t1 as t2 LIMIT 1;
+Unknown table 'T2' in field list
+RENAME TABLE T1 TO T2;
+ALTER TABLE T2 ADD new_col int not null;
+ALTER TABLE T2 RENAME T3;
+show tables like 't_';
+Tables_in_test (t_)
+t3
+t4
+drop table t3,t4;
+create table t1 (a int);
+select count(*) from T1;
+count(*)
+0
+select count(*) from t1;
+count(*)
+0
+select count(T1.a) from t1;
+Unknown table 'T1' in field list
+select count(bags.a) from t1 as Bags;
+Unknown table 'bags' in field list
+drop table t1;
diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result
new file mode 100644
index 00000000000..e582978c126
--- /dev/null
+++ b/mysql-test/r/lowercase_table2.result
@@ -0,0 +1,108 @@
+DROP TABLE IF EXISTS t1,t2,T1,T2,t3,T3;
+DROP DATABASE IF EXISTS `TEST_$1`;
+DROP DATABASE IF EXISTS `test_$1`;
+CREATE TABLE T1 (a int);
+INSERT INTO T1 VALUES (1);
+SHOW TABLES LIKE "T1";
+Tables_in_test (T1)
+T1
+SHOW TABLES LIKE "t1";
+Tables_in_test (t1)
+T1
+SHOW CREATE TABLE T1;
+Table Create Table
+T1 CREATE TABLE `T1` (
+ `a` int(11) default NULL
+) TYPE=MyISAM
+RENAME TABLE T1 TO T2;
+SHOW TABLES LIKE "T2";
+Tables_in_test (T2)
+T2
+SELECT * FROM t2;
+a
+1
+RENAME TABLE T2 TO t3;
+SHOW TABLES LIKE "T3";
+Tables_in_test (T3)
+t3
+RENAME TABLE T3 TO T1;
+SHOW TABLES LIKE "T1";
+Tables_in_test (T1)
+T1
+ALTER TABLE T1 add b int;
+SHOW TABLES LIKE "T1";
+Tables_in_test (T1)
+t1
+ALTER TABLE T1 RENAME T2;
+SHOW TABLES LIKE "T2";
+Tables_in_test (T2)
+T2
+LOCK TABLE T2 WRITE;
+ALTER TABLE T2 drop b;
+SHOW TABLES LIKE "T2";
+Tables_in_test (T2)
+t2
+UNLOCK TABLES;
+RENAME TABLE T2 TO T1;
+SHOW TABLES LIKE "T1";
+Tables_in_test (T1)
+T1
+SELECT * from T1;
+a
+1
+DROP TABLE T1;
+CREATE DATABASE `TEST_$1`;
+SHOW DATABASES LIKE "TEST%";
+Database (TEST%)
+TEST_$1
+DROP DATABASE `test_$1`;
+CREATE TABLE T1 (a int) engine=innodb;
+INSERT INTO T1 VALUES (1);
+SHOW TABLES LIKE "T1";
+Tables_in_test (T1)
+T1
+SHOW TABLES LIKE "t1";
+Tables_in_test (t1)
+T1
+SHOW CREATE TABLE T1;
+Table Create Table
+T1 CREATE TABLE `T1` (
+ `a` int(11) default NULL
+) TYPE=InnoDB
+RENAME TABLE T1 TO T2;
+SHOW TABLES LIKE "T2";
+Tables_in_test (T2)
+t2
+SELECT * FROM t2;
+a
+1
+RENAME TABLE T2 TO t3;
+SHOW TABLES LIKE "T3";
+Tables_in_test (T3)
+t3
+RENAME TABLE T3 TO T1;
+SHOW TABLES LIKE "T1";
+Tables_in_test (T1)
+t1
+ALTER TABLE T1 add b int;
+SHOW TABLES LIKE "T1";
+Tables_in_test (T1)
+t1
+ALTER TABLE T1 RENAME T2;
+SHOW TABLES LIKE "T2";
+Tables_in_test (T2)
+t2
+LOCK TABLE T2 WRITE;
+ALTER TABLE T2 drop b;
+SHOW TABLES LIKE "T2";
+Tables_in_test (T2)
+t2
+UNLOCK TABLES;
+RENAME TABLE T2 TO T1;
+SHOW TABLES LIKE "T1";
+Tables_in_test (T1)
+t1
+SELECT * from T1;
+a
+1
+DROP TABLE T1;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index bdde202b335..650fdb1c77b 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -1,3 +1,10 @@
+drop table if exists t1,t2,t3,t4,t5,t6;
+create table t1 (a int not null primary key auto_increment, message char(20));
+create table t2 (a int not null primary key auto_increment, message char(20));
+INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1");
+INSERT INTO t2 (message) VALUES ("Testing"),("table"),("t2");
+create table t3 (a int not null, b char(20), key(a)) type=MERGE UNION=(t1,t2);
+select * from t3;
a b
1 Testing
2 table
@@ -5,6 +12,7 @@ a b
1 Testing
2 table
3 t2
+select * from t3 order by a desc;
a b
3 t1
3 t2
@@ -12,13 +20,30 @@ a b
2 table
1 Testing
1 Testing
+drop table t3;
+insert into t1 select NULL,message from t2;
+insert into t2 select NULL,message from t1;
+insert into t1 select NULL,message from t2;
+insert into t2 select NULL,message from t1;
+insert into t1 select NULL,message from t2;
+insert into t2 select NULL,message from t1;
+insert into t1 select NULL,message from t2;
+insert into t2 select NULL,message from t1;
+insert into t1 select NULL,message from t2;
+insert into t2 select NULL,message from t1;
+insert into t1 select NULL,message from t2;
+create table t3 (a int not null, b char(20), key(a)) type=MERGE UNION=(test.t1,test.t2);
+explain select * from t3 where a < 10;
table type possible_keys key key_len ref rows Extra
-t3 range a a 4 NULL 10 where used
+t3 range a a 4 NULL 18 Using where
+explain select * from t3 where a > 10 and a < 20;
table type possible_keys key key_len ref rows Extra
-t3 range a a 4 NULL 10 where used
+t3 range a a 4 NULL 16 Using where
+select * from t3 where a = 10;
a b
10 Testing
10 Testing
+select * from t3 where a < 10;
a b
1 Testing
1 Testing
@@ -38,6 +63,7 @@ a b
8 table
9 t2
9 t2
+select * from t3 where a > 10 and a < 20;
a b
11 table
11 table
@@ -57,8 +83,10 @@ a b
18 t2
19 Testing
19 Testing
+explain select a from t3 order by a desc limit 10;
table type possible_keys key key_len ref rows Extra
t3 index NULL a 4 NULL 1131 Using index
+select a from t3 order by a desc limit 10;
a
699
698
@@ -70,6 +98,7 @@ a
692
691
690
+select a from t3 order by a desc limit 300,10;
a
416
415
@@ -81,12 +110,87 @@ a
412
412
411
+delete from t3 where a=3;
+select * from t3 where a < 10;
+a b
+1 Testing
+1 Testing
+2 table
+2 table
+4 Testing
+4 Testing
+5 table
+5 table
+6 t2
+6 t1
+7 Testing
+7 Testing
+8 table
+8 table
+9 t2
+9 t2
+delete from t3 where a >= 6 and a <= 8;
+select * from t3 where a < 10;
+a b
+1 Testing
+1 Testing
+2 table
+2 table
+4 Testing
+4 Testing
+5 table
+5 table
+9 t2
+9 t2
+update t3 set a=3 where a=9;
+select * from t3 where a < 10;
+a b
+1 Testing
+1 Testing
+2 table
+2 table
+3 t2
+3 t2
+4 Testing
+4 Testing
+5 table
+5 table
+update t3 set a=6 where a=7;
+select * from t3 where a < 10;
+a b
+1 Testing
+1 Testing
+2 table
+2 table
+3 t2
+3 t2
+4 Testing
+4 Testing
+5 table
+5 table
+show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`a` int(11) NOT NULL default '0',
`b` char(20) default NULL,
KEY `a` (`a`)
) TYPE=MRG_MyISAM UNION=(t1,t2)
+create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2);
+select * from t4;
+Can't open file: 't4.MRG'. (errno: 143)
+create table t5 (a int not null, b char(10), key(a)) type=MERGE UNION=(test.t1,test_2.t2);
+Incorrect table definition; All MERGE tables must be in the same database
+drop table if exists t5,t4,t3,t1,t2;
+create table t1 (c char(10)) type=myisam;
+create table t2 (c char(10)) type=myisam;
+create table t3 (c char(10)) union=(t1,t2) type=merge;
+insert into t1 (c) values ('test1');
+insert into t1 (c) values ('test1');
+insert into t1 (c) values ('test1');
+insert into t2 (c) values ('test2');
+insert into t2 (c) values ('test2');
+insert into t2 (c) values ('test2');
+select * from t3;
c
test1
test1
@@ -94,6 +198,7 @@ test1
test2
test2
test2
+select * from t3;
c
test1
test1
@@ -101,38 +206,407 @@ test1
test2
test2
test2
+delete from t3 where 1=1;
+select * from t3;
c
+select * from t1;
c
+drop table t3,t2,t1;
+CREATE TABLE t1 (incr int not null, othr int not null, primary key(incr));
+CREATE TABLE t2 (incr int not null, othr int not null, primary key(incr));
+CREATE TABLE t3 (incr int not null, othr int not null, primary key(incr))
+TYPE=MERGE UNION=(t1,t2);
+SELECT * from t3;
incr othr
+INSERT INTO t1 VALUES ( 1,10),( 3,53),( 5,21),( 7,12),( 9,17);
+INSERT INTO t2 VALUES ( 2,24),( 4,33),( 6,41),( 8,26),( 0,32);
+INSERT INTO t1 VALUES (11,20),(13,43),(15,11),(17,22),(19,37);
+INSERT INTO t2 VALUES (12,25),(14,31),(16,42),(18,27),(10,30);
+SELECT * from t3 where incr in (1,2,3,4) order by othr;
incr othr
1 10
2 24
4 33
3 53
+alter table t3 UNION=(t1);
+select count(*) from t3;
count(*)
10
+alter table t3 UNION=(t1,t2);
+select count(*) from t3;
count(*)
20
+alter table t3 TYPE=MYISAM;
+select count(*) from t3;
count(*)
20
+drop table t3;
+CREATE TABLE t3 (incr int not null, othr int not null, primary key(incr))
+TYPE=MERGE UNION=(t1,t2);
+show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`incr` int(11) NOT NULL default '0',
`othr` int(11) NOT NULL default '0',
PRIMARY KEY (`incr`)
) TYPE=MRG_MyISAM UNION=(t1,t2)
+alter table t3 drop primary key;
+show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`incr` int(11) NOT NULL default '0',
`othr` int(11) NOT NULL default '0'
) TYPE=MRG_MyISAM UNION=(t1,t2)
+drop table t3,t2,t1;
+create table t1 (a int not null, key(a)) type=merge;
+select * from t1;
a
+drop table t1;
+drop table if exists t3, t2, t1;
+create table t1 (a int not null, b int not null, key(a,b));
+create table t2 (a int not null, b int not null, key(a,b));
+create table t3 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2);
+insert into t1 values (1,2),(2,1),(0,0),(4,4),(5,5),(6,6);
+insert into t2 values (1,1),(2,2),(0,0),(4,4),(5,5),(6,6);
+flush tables;
+select * from t3 where a=1 order by b limit 2;
+a b
+1 1
+1 2
+drop table t3,t1,t2;
+drop table if exists t6, t5, t4, t3, t2, t1;
+create table t1 (a int not null, b int not null auto_increment, primary key(a,b));
+create table t2 (a int not null, b int not null auto_increment, primary key(a,b));
+create table t3 (a int not null, b int not null, key(a,b)) UNION=(t1,t2) INSERT_METHOD=NO;
+create table t4 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=NO;
+create table t5 (a int not null, b int not null auto_increment, primary key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST;
+create table t6 (a int not null, b int not null auto_increment, primary key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL default '0',
+ KEY `a` (`a`,`b`)
+) TYPE=MyISAM
+show create table t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL default '0',
+ KEY `a` (`a`,`b`)
+) TYPE=MRG_MyISAM UNION=(t1,t2)
+show create table t5;
+Table Create Table
+t5 CREATE TABLE `t5` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL auto_increment,
+ PRIMARY KEY (`a`,`b`)
+) TYPE=MRG_MyISAM INSERT_METHOD=FIRST UNION=(t1,t2)
+show create table t6;
+Table Create Table
+t6 CREATE TABLE `t6` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL auto_increment,
+ PRIMARY KEY (`a`,`b`)
+) TYPE=MRG_MyISAM INSERT_METHOD=LAST UNION=(t1,t2)
+insert into t1 values (1,NULL),(1,NULL),(1,NULL),(1,NULL);
+insert into t2 values (2,NULL),(2,NULL),(2,NULL),(2,NULL);
+select * from t3 order by b,a limit 3;
+a b
+select * from t4 order by b,a limit 3;
+a b
+1 1
+2 1
+1 2
+select * from t5 order by b,a limit 3,3;
+a b
+2 2
+1 3
+2 3
+select * from t6 order by b,a limit 6,3;
+a b
+1 4
+2 4
+insert into t5 values (5,1),(5,2);
+insert into t6 values (6,1),(6,2);
+select * from t1 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+5 1
+5 2
+select * from t2 order by a,b;
+a b
+2 1
+2 2
+2 3
+2 4
+6 1
+6 2
+select * from t4 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+2 1
+2 2
+2 3
+2 4
+5 1
+5 2
+6 1
+6 2
+insert into t3 values (3,1),(3,2),(3,3),(3,4);
+select * from t3 order by a,b;
+a b
+3 1
+3 2
+3 3
+3 4
+alter table t4 UNION=(t1,t2,t3);
+show create table t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL default '0',
+ KEY `a` (`a`,`b`)
+) TYPE=MRG_MyISAM UNION=(t1,t2,t3)
+select * from t4 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+2 1
+2 2
+2 3
+2 4
+3 1
+3 2
+3 3
+3 4
+5 1
+5 2
+6 1
+6 2
+alter table t4 INSERT_METHOD=FIRST;
+show create table t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) NOT NULL default '0',
+ KEY `a` (`a`,`b`)
+) TYPE=MRG_MyISAM INSERT_METHOD=FIRST UNION=(t1,t2,t3)
+insert into t4 values (4,1),(4,2);
+select * from t1 order by a,b;
a b
1 1
1 2
+1 3
+1 4
+4 1
+4 2
+5 1
+5 2
+select * from t2 order by a,b;
+a b
+2 1
+2 2
+2 3
+2 4
+6 1
+6 2
+select * from t3 order by a,b;
+a b
+3 1
+3 2
+3 3
+3 4
+select * from t4 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+2 1
+2 2
+2 3
+2 4
+3 1
+3 2
+3 3
+3 4
+4 1
+4 2
+5 1
+5 2
+6 1
+6 2
+select * from t5 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+2 1
+2 2
+2 3
+2 4
+4 1
+4 2
+5 1
+5 2
+6 1
+6 2
+select 1;
+1
+1
+insert into t5 values (1,NULL),(5,NULL);
+insert into t6 values (2,NULL),(6,NULL);
+select * from t1 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+1 5
+4 1
+4 2
+5 1
+5 2
+5 3
+select * from t2 order by a,b;
+a b
+2 1
+2 2
+2 3
+2 4
+2 5
+6 1
+6 2
+6 3
+select * from t5 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+1 5
+2 1
+2 2
+2 3
+2 4
+2 5
+4 1
+4 2
+5 1
+5 2
+5 3
+6 1
+6 2
+6 3
+select * from t6 order by a,b;
+a b
+1 1
+1 2
+1 3
+1 4
+1 5
+2 1
+2 2
+2 3
+2 4
+2 5
+4 1
+4 2
+5 1
+5 2
+5 3
+6 1
+6 2
+6 3
+drop table if exists t6, t5, t4, t3, t2, t1;
+CREATE TABLE t1 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,1), (2,1);
+CREATE TABLE t2 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,2), (2,2);
+CREATE TABLE t ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', KEY a (a,b)) TYPE=MRG_MyISAM UNION=(t1,t2);
+select max(b) from t where a = 2;
+max(b)
+2
+select max(b) from t1 where a = 2;
+max(b)
+1
+drop table if exists t,t1,t2;
+drop table if exists t1, t2, t3, t4, t5, t6;
+create table t1 (a int not null);
+create table t2 (a int not null);
+insert into t1 values (1);
+insert into t2 values (2);
+create temporary table t3 (a int not null) TYPE=MERGE UNION=(t1,t2);
+select * from t3;
a
1
2
+create temporary table t4 (a int not null);
+create temporary table t5 (a int not null);
+insert into t4 values (1);
+insert into t5 values (2);
+create temporary table t6 (a int not null) TYPE=MERGE UNION=(t4,t5);
+select * from t6;
a
1
2
+drop table if exists t1, t2, t3, t4, t5, t6;
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+fileset_id tinyint(3) unsigned NOT NULL default '0',
+file_code varchar(32) NOT NULL default '',
+fileset_root_id tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (fileset_id,file_code),
+KEY files (fileset_id,fileset_root_id)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (2, '0000000111', 1), (2, '0000000112', 1), (2, '0000000113', 1),
+(2, '0000000114', 1), (2, '0000000115', 1), (2, '0000000116', 1), (2, '0000000117', 1),
+(2, '0000000118', 1), (2, '0000000119', 1), (2, '0000000120', 1);
+CREATE TABLE t2 (
+fileset_id tinyint(3) unsigned NOT NULL default '0',
+file_code varchar(32) NOT NULL default '',
+fileset_root_id tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (fileset_id,file_code),
+KEY files (fileset_id,fileset_root_id)
+) TYPE=MRG_MyISAM UNION=(t1);
+EXPLAIN SELECT * FROM t2 IGNORE INDEX (files) WHERE fileset_id = 2
+AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1;
+table type possible_keys key key_len ref rows Extra
+t2 range PRIMARY PRIMARY 33 NULL 5 Using where
+EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2
+AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1;
+table type possible_keys key key_len ref rows Extra
+t2 range PRIMARY,files PRIMARY 33 NULL 5 Using where
+EXPLAIN SELECT * FROM t1 WHERE fileset_id = 2
+AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1;
+table type possible_keys key key_len ref rows Extra
+t1 range PRIMARY,files PRIMARY 33 NULL 5 Using where
+EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2
+AND file_code = '0000000115' LIMIT 1;
+table type possible_keys key key_len ref rows Extra
+t2 const PRIMARY,files PRIMARY 33 const,const 1
+DROP TABLE IF EXISTS t1, t2;
+create table t1 (x int, y int, index xy(x, y));
+create table t2 (x int, y int, index xy(x, y));
+create table t3 (x int, y int, index xy(x, y)) type=merge union=(t1,t2);
+insert into t1 values(1, 2);
+insert into t2 values(1, 3);
+select * from t3 where x = 1 and y < 5 order by y;
+x y
+1 2
+1 3
+select * from t3 where x = 1 and y < 5 order by y desc;
+x y
+1 3
+1 2
+drop table t1,t2,t3;
diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result
new file mode 100644
index 00000000000..7b266544c92
--- /dev/null
+++ b/mysql-test/r/mix_innodb_myisam_binlog.result
@@ -0,0 +1,180 @@
+drop table if exists t1, t2;
+create table t1 (a int) type=innodb;
+create table t2 (a int) type=myisam;
+reset master;
+begin;
+insert into t1 values(1);
+insert into t2 select * from t1;
+commit;
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; BEGIN
+master-bin.001 119 Query 1 79 use `test`; insert into t1 values(1)
+master-bin.001 178 Query 1 79 use `test`; insert into t2 select * from t1
+master-bin.001 244 Query 1 244 use `test`; COMMIT
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(2);
+insert into t2 select * from t1;
+rollback;
+Warning: Some non-transactional changed tables couldn't be rolled back
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; BEGIN
+master-bin.001 119 Query 1 79 use `test`; insert into t1 values(2)
+master-bin.001 178 Query 1 79 use `test`; insert into t2 select * from t1
+master-bin.001 244 Query 1 244 use `test`; ROLLBACK
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(3);
+savepoint my_savepoint;
+insert into t1 values(4);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+Warning: Some non-transactional changed tables couldn't be rolled back
+commit;
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; BEGIN
+master-bin.001 119 Query 1 79 use `test`; insert into t1 values(3)
+master-bin.001 178 Query 1 79 use `test`; savepoint my_savepoint
+master-bin.001 235 Query 1 79 use `test`; insert into t1 values(4)
+master-bin.001 294 Query 1 79 use `test`; insert into t2 select * from t1
+master-bin.001 360 Query 1 79 use `test`; rollback to savepoint my_savepoint
+master-bin.001 429 Query 1 429 use `test`; COMMIT
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(5);
+savepoint my_savepoint;
+insert into t1 values(6);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+Warning: Some non-transactional changed tables couldn't be rolled back
+insert into t1 values(7);
+commit;
+select a from t1 order by a;
+a
+5
+7
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; BEGIN
+master-bin.001 119 Query 1 79 use `test`; insert into t1 values(5)
+master-bin.001 178 Query 1 79 use `test`; savepoint my_savepoint
+master-bin.001 235 Query 1 79 use `test`; insert into t1 values(6)
+master-bin.001 294 Query 1 79 use `test`; insert into t2 select * from t1
+master-bin.001 360 Query 1 79 use `test`; rollback to savepoint my_savepoint
+master-bin.001 429 Query 1 79 use `test`; insert into t1 values(7)
+master-bin.001 488 Query 1 488 use `test`; COMMIT
+delete from t1;
+delete from t2;
+reset master;
+select get_lock("a",10);
+get_lock("a",10)
+1
+begin;
+insert into t1 values(8);
+insert into t2 select * from t1;
+select get_lock("a",10);
+get_lock("a",10)
+1
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; BEGIN
+master-bin.001 119 Query 1 79 use `test`; insert into t1 values(8)
+master-bin.001 178 Query 1 79 use `test`; insert into t2 select * from t1
+master-bin.001 244 Query 1 244 use `test`; ROLLBACK
+delete from t1;
+delete from t2;
+reset master;
+insert into t1 values(9);
+insert into t2 select * from t1;
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; insert into t1 values(9)
+master-bin.001 138 Query 1 138 use `test`; insert into t2 select * from t1
+delete from t1;
+delete from t2;
+reset master;
+insert into t1 values(10);
+begin;
+insert into t2 select * from t1;
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; insert into t1 values(10)
+master-bin.001 139 Query 1 139 use `test`; insert into t2 select * from t1
+insert into t1 values(11);
+commit;
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; insert into t1 values(10)
+master-bin.001 139 Query 1 139 use `test`; insert into t2 select * from t1
+master-bin.001 205 Query 1 205 use `test`; BEGIN
+master-bin.001 245 Query 1 205 use `test`; insert into t1 values(11)
+master-bin.001 305 Query 1 305 use `test`; COMMIT
+alter table t2 type=INNODB;
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(12);
+insert into t2 select * from t1;
+commit;
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; BEGIN
+master-bin.001 119 Query 1 79 use `test`; insert into t1 values(12)
+master-bin.001 179 Query 1 79 use `test`; insert into t2 select * from t1
+master-bin.001 245 Query 1 245 use `test`; COMMIT
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(13);
+insert into t2 select * from t1;
+rollback;
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(14);
+savepoint my_savepoint;
+insert into t1 values(15);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+commit;
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; BEGIN
+master-bin.001 119 Query 1 79 use `test`; insert into t1 values(14)
+master-bin.001 179 Query 1 179 use `test`; COMMIT
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(16);
+savepoint my_savepoint;
+insert into t1 values(17);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+insert into t1 values(18);
+commit;
+select a from t1 order by a;
+a
+16
+18
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; BEGIN
+master-bin.001 119 Query 1 79 use `test`; insert into t1 values(16)
+master-bin.001 179 Query 1 79 use `test`; insert into t1 values(18)
+master-bin.001 239 Query 1 239 use `test`; COMMIT
+drop table t1,t2;
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
new file mode 100644
index 00000000000..31be96fc0fd
--- /dev/null
+++ b/mysql-test/r/multi_update.result
@@ -0,0 +1,362 @@
+drop table if exists t1,t2,t3;
+create table t1(id1 int not null auto_increment primary key, t char(12));
+create table t2(id2 int not null, t char(12));
+create table t3(id3 int not null, t char(12), index(id3));
+select count(*) from t1 where id1 > 95;
+count(*)
+5
+select count(*) from t2 where id2 > 95;
+count(*)
+25
+select count(*) from t3 where id3 > 95;
+count(*)
+250
+update t1,t2,t3 set t1.t="aaa", t2.t="bbb", t3.t="cc" where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 90;
+select count(*) from t1 where t = "aaa";
+count(*)
+10
+select count(*) from t1 where id1 > 90;
+count(*)
+10
+select count(*) from t2 where t = "bbb";
+count(*)
+50
+select count(*) from t2 where id2 > 90;
+count(*)
+50
+select count(*) from t3 where t = "cc";
+count(*)
+500
+select count(*) from t3 where id3 > 90;
+count(*)
+500
+delete t1.*, t2.*, t3.* from t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 95;
+check table t1, t2, t3;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+test.t3 check status OK
+select count(*) from t1 where id1 > 95;
+count(*)
+0
+select count(*) from t2 where id2 > 95;
+count(*)
+0
+select count(*) from t3 where id3 > 95;
+count(*)
+0
+delete t1, t2, t3 from t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 5;
+select count(*) from t1 where id1 > 5;
+count(*)
+0
+select count(*) from t2 where id2 > 5;
+count(*)
+0
+select count(*) from t3 where id3 > 5;
+count(*)
+0
+delete from t1, t2, t3 using t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 0;
+select count(*) from t1 where id1;
+count(*)
+0
+select count(*) from t2 where id2;
+count(*)
+0
+select count(*) from t3 where id3;
+count(*)
+0
+drop table t1,t2,t3;
+create table t1(id1 int not null primary key, t varchar(100)) pack_keys = 1;
+create table t2(id2 int not null, t varchar(100), index(id2)) pack_keys = 1;
+delete t1 from t1,t2 where t1.id1 = t2.id2 and t1.id1 > 500;
+drop table t1,t2;
+CREATE TABLE t1 (
+id int(11) NOT NULL default '0',
+name varchar(10) default NULL,
+PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'aaa'),(2,'aaa'),(3,'aaa');
+CREATE TABLE t2 (
+id int(11) NOT NULL default '0',
+name varchar(10) default NULL,
+PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (2,'bbb'),(3,'bbb'),(4,'bbb');
+CREATE TABLE t3 (
+id int(11) NOT NULL default '0',
+mydate datetime default NULL,
+PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t3 VALUES (1,'2002-02-04 00:00:00'),(3,'2002-05-12 00:00:00'),(5,'2002-05-12 00:00:00'),(6,'2002-06-22
+00:00:00'),(7,'2002-07-22 00:00:00');
+delete t1,t2,t3 from t1,t2,t3 where to_days(now())-to_days(t3.mydate)>=30 and t3.id=t1.id and t3.id=t2.id;
+select * from t3;
+id mydate
+1 2002-02-04 00:00:00
+5 2002-05-12 00:00:00
+6 2002-06-22 00:00:00
+7 2002-07-22 00:00:00
+DROP TABLE IF EXISTS t1,t2,t3;
+CREATE TABLE IF NOT EXISTS `t1` (
+`id` int(11) NOT NULL auto_increment,
+`tst` text,
+`tst1` text,
+PRIMARY KEY (`id`)
+) TYPE=MyISAM;
+CREATE TABLE IF NOT EXISTS `t2` (
+`ID` int(11) NOT NULL auto_increment,
+`ParId` int(11) default NULL,
+`tst` text,
+`tst1` text,
+PRIMARY KEY (`ID`),
+KEY `IX_ParId_t2` (`ParId`),
+FOREIGN KEY (`ParId`) REFERENCES `t1` (`id`)
+) TYPE=MyISAM;
+INSERT INTO t1(tst,tst1) VALUES("MySQL","MySQL AB"), ("MSSQL","Microsoft"), ("ORACLE","ORACLE");
+INSERT INTO t2(ParId) VALUES(1), (2), (3);
+select * from t2;
+ID ParId tst tst1
+1 1 NULL NULL
+2 2 NULL NULL
+3 3 NULL NULL
+UPDATE t2, t1 SET t2.tst = t1.tst, t2.tst1 = t1.tst1 WHERE t2.ParId = t1.Id;
+select * from t2;
+ID ParId tst tst1
+1 1 MySQL MySQL AB
+2 2 MSSQL Microsoft
+3 3 ORACLE ORACLE
+drop table if exists t1, t2 ;
+create table t1 (n numeric(10));
+create table t2 (n numeric(10));
+insert into t2 values (1),(2),(4),(8),(16),(32);
+select * from t2 left outer join t1 using (n);
+n n
+1 NULL
+2 NULL
+4 NULL
+8 NULL
+16 NULL
+32 NULL
+delete t1,t2 from t2 left outer join t1 using (n);
+select * from t2 left outer join t1 using (n);
+n n
+drop table t1,t2 ;
+create table t1 (n int(10) not null primary key, d int(10));
+create table t2 (n int(10) not null primary key, d int(10));
+insert into t1 values(1,1);
+insert into t2 values(1,10),(2,20);
+LOCK TABLES t1 write, t2 read;
+DELETE t1.*, t2.* FROM t1,t2 where t1.n=t2.n;
+Table 't2' was locked with a READ lock and can't be updated
+UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+Table 't2' was locked with a READ lock and can't be updated
+UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
+Table 't2' was locked with a READ lock and can't be updated
+unlock tables;
+LOCK TABLES t1 write, t2 write;
+UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
+select * from t1;
+n d
+1 10
+DELETE t1.*, t2.* FROM t1,t2 where t1.n=t2.n;
+select * from t1;
+n d
+select * from t2;
+n d
+2 20
+unlock tables;
+drop table t1,t2;
+set sql_safe_updates=1;
+create table t1 (n int(10), d int(10));
+create table t2 (n int(10), d int(10));
+insert into t1 values(1,1);
+insert into t2 values(1,10),(2,20);
+UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+set sql_safe_updates=0;
+drop table t1,t2;
+set timestamp=1038401397;
+create table t1 (n int(10) not null primary key, d int(10), t timestamp);
+create table t2 (n int(10) not null primary key, d int(10), t timestamp);
+insert into t1 values(1,1,NULL);
+insert into t2 values(1,10,NULL),(2,20,NULL);
+set timestamp=1038000000;
+UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
+select n,d,unix_timestamp(t) from t1;
+n d unix_timestamp(t)
+1 10 1038000000
+select n,d,unix_timestamp(t) from t2;
+n d unix_timestamp(t)
+1 10 1038401397
+2 20 1038401397
+UPDATE t1,t2 SET 1=2 WHERE t1.n=t2.n;
+You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '1=2 WHERE t1.n=t2.n' at line 1
+drop table t1,t2;
+set timestamp=0;
+set sql_safe_updates=0;
+create table t1 (n int(10) not null primary key, d int(10));
+create table t2 (n int(10) not null primary key, d int(10));
+insert into t1 values(1,1), (3,3);
+insert into t2 values(1,10),(2,20);
+UPDATE t2 left outer join t1 on t1.n=t2.n SET t1.d=t2.d;
+select * from t1;
+n d
+1 10
+3 3
+select * from t2;
+n d
+1 10
+2 20
+drop table t1,t2;
+create table t1 (n int(10), d int(10));
+create table t2 (n int(10), d int(10));
+insert into t1 values(1,1),(1,2);
+insert into t2 values(1,10),(2,20);
+UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+select * from t1;
+n d
+1 10
+1 10
+select * from t2;
+n d
+1 30
+2 20
+drop table t1,t2;
+create table t1 (n int(10), d int(10));
+create table t2 (n int(10), d int(10));
+insert into t1 values(1,1),(3,2);
+insert into t2 values(1,10),(1,20);
+UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+select * from t1;
+n d
+1 10
+3 2
+select * from t2;
+n d
+1 30
+1 30
+drop table t1,t2;
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'jedan'),(2,'dva'),(3,'tri'),(4,'xxxxxxxxxx'),(5,'a'),(10,''),(11,''),(12,''),(13,'');
+CREATE TABLE t2 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,'jedan'),(2,'dva'),(3,'tri'),(4,'xxxxxxxxxx'),(5,'a');
+CREATE TABLE t3 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM;
+INSERT INTO t3 VALUES (1,'jedan'),(2,'dva');
+update t1,t2 set t1.naziv="aaaa" where t1.broj=t2.broj;
+update t1,t2,t3 set t1.naziv="bbbb", t2.naziv="aaaa" where t1.broj=t2.broj and t2.broj=t3.broj;
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (a int not null primary key, b int not null, key (b));
+CREATE TABLE t2 (a int not null primary key, b int not null, key (b));
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+INSERT INTO t2 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+update t1,t2 set t1.a=t1.a+100;
+select * from t1;
+a b
+101 1
+102 2
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+update t1,t2 set t1.a=t1.a+100 where t1.a=101;
+select * from t1;
+a b
+201 1
+102 2
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+update t1,t2 set t1.b=t1.b+10 where t1.b=2;
+select * from t1;
+a b
+201 1
+102 12
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t2.a=t1.a-100;
+select * from t1;
+a b
+201 1
+102 12
+103 5
+104 6
+105 7
+106 6
+107 7
+108 8
+109 9
+select * from t2;
+a b
+1 1
+2 2
+3 13
+4 14
+5 15
+6 6
+7 7
+8 8
+9 9
+drop table t1,t2;
+CREATE TABLE t3 ( KEY1 varchar(50) NOT NULL default '', PARAM_CORR_DISTANCE_RUSH double default NULL, PARAM_CORR_DISTANCE_GEM double default NULL, PARAM_AVG_TARE double default NULL, PARAM_AVG_NB_DAYS double default NULL, PARAM_DEFAULT_PROP_GEM_SRVC varchar(50) default NULL, PARAM_DEFAULT_PROP_GEM_NO_ETIK varchar(50) default NULL, PARAM_SCENARIO_COSTS varchar(50) default NULL, PARAM_DEFAULT_WAGON_COST double default NULL, tmp int(11) default NULL, PRIMARY KEY (KEY1)) TYPE=MyISAM;
+INSERT INTO t3 VALUES ('A',1,1,22,3.2,'R','R','BASE2',0.24,NULL);
+create table t1 (A varchar(1));
+insert into t1 values ("A") ,("B"),("C"),("D");
+create table t2(Z varchar(15));
+insert into t2(Z) select concat(a.a,b.a,c.a,d.a) from t1 as a, t1 as b, t1 as c, t1 as d;
+update t2,t3 set Z =param_scenario_costs;
+drop table t1,t2,t3;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,1),(2,1),(3,1);
+insert into t2 values (1,1), (3,1);
+update t1 left join t2 on t1.a=t2.a set t1.b=2, t2.b=2 where t1.b=1 and t2.b=1 or t2.a is NULL;
+select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and t2.b=1 or t2.a is NULL;
+a b a b
+2 2 NULL NULL
+drop table t1,t2;
+create table t1 (a int not null auto_increment primary key, b int not null);
+insert into t1 (b) values (1),(2),(3),(4);
+update t1, t1 as t2 set t1.b=t2.b+1 where t1.a=t2.a;
+select * from t1;
+a b
+1 2
+2 3
+3 4
+4 5
+drop table t1;
+drop table if exists t1, t2;
+create table t1(id1 smallint(5), field char(5));
+create table t2(id2 smallint(5), field char(5));
+insert into t1 values (1, 'a'), (2, 'aa');
+insert into t2 values (1, 'b'), (2, 'bb');
+select * from t1;
+id1 field
+1 a
+2 aa
+select * from t2;
+id2 field
+1 b
+2 bb
+update t2 inner join t1 on t1.id1=t2.id2
+set t2.field=t1.field
+where 0=1;
+update t2, t1 set t2.field=t1.field
+where t1.id1=t2.id2 and 0=1;
+delete t1, t2 from t2 inner join t1 on t1.id1=t2.id2
+where 0=1;
+delete t1, t2 from t2,t1
+where t1.id1=t2.id2 and 0=1;
+drop table t1,t2;
diff --git a/mysql-test/r/myisam-blob.result b/mysql-test/r/myisam-blob.result
new file mode 100644
index 00000000000..743d4dac254
--- /dev/null
+++ b/mysql-test/r/myisam-blob.result
@@ -0,0 +1,27 @@
+drop table if exists t1;
+CREATE TABLE t1 (data LONGBLOB) ENGINE=myisam;
+INSERT INTO t1 (data) VALUES (NULL);
+UPDATE t1 set data=repeat('a',18*1024*1024);
+select length(data) from t1;
+length(data)
+18874368
+delete from t1 where left(data,1)='a';
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+truncate table t1;
+INSERT INTO t1 (data) VALUES (repeat('a',1*1024*1024));
+INSERT INTO t1 (data) VALUES (repeat('b',16*1024*1024-1024));
+delete from t1 where left(data,1)='b';
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+UPDATE t1 set data=repeat('c',17*1024*1024);
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+delete from t1 where left(data,1)='c';
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 31478f14c93..cc541388a5c 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1,44 +1,433 @@
+drop table if exists t1,t2;
+CREATE TABLE t1 (
+STRING_DATA char(255) default NULL,
+KEY STRING_DATA (STRING_DATA)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
+INSERT INTO t1 VALUES ('DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD');
+INSERT INTO t1 VALUES ('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF');
+INSERT INTO t1 VALUES ('FGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG');
+INSERT INTO t1 VALUES ('HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH');
+INSERT INTO t1 VALUES ('WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW');
+CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a));
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+repair table t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
+delete from t1 where (a & 1);
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+repair table t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+create table t1 (a int not null auto_increment, b int not null, primary key (a), index(b));
+insert into t1 (b) values (1),(2),(2),(2),(2);
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 5 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status Table is already up to date
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 5 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
+drop table t1;
+create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) type=myisam;
+insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4);
+explain select * from t1 order by a;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 Using filesort
+explain select * from t1 order by b;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 Using filesort
+explain select * from t1 order by c;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 Using filesort
+explain select a from t1 order by a;
table type possible_keys key key_len ref rows Extra
t1 index NULL PRIMARY 4 NULL 4 Using index
+explain select b from t1 order by b;
table type possible_keys key key_len ref rows Extra
t1 index NULL b 4 NULL 4 Using index
+explain select a,b from t1 order by b;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 Using filesort
+explain select a,b from t1;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4
+explain select a,b,c from t1;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4
+drop table t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2), (3);
+LOCK TABLES t1 WRITE;
+INSERT INTO t1 VALUES (1), (2), (3);
+OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
+DROP TABLE t1;
+create table t1 ( t1 char(255), key(t1(250)));
+insert t1 values ('137513751375137513751375137513751375137569516951695169516951695169516951695169');
+insert t1 values ('178417841784178417841784178417841784178403420342034203420342034203420342034203');
+insert t1 values ('213872387238723872387238723872387238723867376737673767376737673767376737673767');
+insert t1 values ('242624262426242624262426242624262426242607890789078907890789078907890789078907');
+insert t1 values ('256025602560256025602560256025602560256011701170117011701170117011701170117011');
+insert t1 values ('276027602760276027602760276027602760276001610161016101610161016101610161016101');
+insert t1 values ('281528152815281528152815281528152815281564956495649564956495649564956495649564');
+insert t1 values ('292129212921292129212921292129212921292102100210021002100210021002100210021002');
+insert t1 values ('380638063806380638063806380638063806380634483448344834483448344834483448344834');
+insert t1 values ('411641164116411641164116411641164116411616301630163016301630163016301630163016');
+insert t1 values ('420842084208420842084208420842084208420899889988998899889988998899889988998899');
+insert t1 values ('438443844384438443844384438443844384438482448244824482448244824482448244824482');
+insert t1 values ('443244324432443244324432443244324432443239613961396139613961396139613961396139');
+insert t1 values ('485448544854485448544854485448544854485477847784778477847784778477847784778477');
+insert t1 values ('494549454945494549454945494549454945494555275527552755275527552755275527552755');
+insert t1 values ('538647864786478647864786478647864786478688918891889188918891889188918891889188');
+insert t1 values ('565556555655565556555655565556555655565554845484548454845484548454845484548454');
+insert t1 values ('607860786078607860786078607860786078607856665666566656665666566656665666566656');
+insert t1 values ('640164016401640164016401640164016401640141274127412741274127412741274127412741');
+insert t1 values ('719471947194719471947194719471947194719478717871787178717871787178717871787178');
+insert t1 values ('742574257425742574257425742574257425742549604960496049604960496049604960496049');
+insert t1 values ('887088708870887088708870887088708870887035963596359635963596359635963596359635');
+insert t1 values ('917791779177917791779177917791779177917773857385738573857385738573857385738573');
+insert t1 values ('933293329332933293329332933293329332933278987898789878987898789878987898789878');
+insert t1 values ('963896389638963896389638963896389638963877807780778077807780778077807780778077');
+delete from t1 where t1>'2';
+insert t1 values ('70'), ('84'), ('60'), ('20'), ('76'), ('89'), ('49'), ('50'),
+('88'), ('61'), ('42'), ('98'), ('39'), ('30'), ('25'), ('66'), ('61'), ('48'),
+('80'), ('84'), ('98'), ('19'), ('91'), ('42'), ('47');
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+create table t1 (i1 int, i2 int, i3 int, i4 int, i5 int, i6 int, i7 int, i8
+int, i9 int, i10 int, i11 int, i12 int, i13 int, i14 int, i15 int, i16 int, i17
+int, i18 int, i19 int, i20 int, i21 int, i22 int, i23 int, i24 int, i25 int,
+i26 int, i27 int, i28 int, i29 int, i30 int, i31 int, i32 int, i33 int, i34
+int, i35 int, i36 int, i37 int, i38 int, i39 int, i40 int, i41 int, i42 int,
+i43 int, i44 int, i45 int, i46 int, i47 int, i48 int, i49 int, i50 int, i51
+int, i52 int, i53 int, i54 int, i55 int, i56 int, i57 int, i58 int, i59 int,
+i60 int, i61 int, i62 int, i63 int, i64 int, i65 int, i66 int, i67 int, i68
+int, i69 int, i70 int, i71 int, i72 int, i73 int, i74 int, i75 int, i76 int,
+i77 int, i78 int, i79 int, i80 int, i81 int, i82 int, i83 int, i84 int, i85
+int, i86 int, i87 int, i88 int, i89 int, i90 int, i91 int, i92 int, i93 int,
+i94 int, i95 int, i96 int, i97 int, i98 int, i99 int, i100 int, i101 int, i102
+int, i103 int, i104 int, i105 int, i106 int, i107 int, i108 int, i109 int, i110
+int, i111 int, i112 int, i113 int, i114 int, i115 int, i116 int, i117 int, i118
+int, i119 int, i120 int, i121 int, i122 int, i123 int, i124 int, i125 int, i126
+int, i127 int, i128 int, i129 int, i130 int, i131 int, i132 int, i133 int, i134
+int, i135 int, i136 int, i137 int, i138 int, i139 int, i140 int, i141 int, i142
+int, i143 int, i144 int, i145 int, i146 int, i147 int, i148 int, i149 int, i150
+int, i151 int, i152 int, i153 int, i154 int, i155 int, i156 int, i157 int, i158
+int, i159 int, i160 int, i161 int, i162 int, i163 int, i164 int, i165 int, i166
+int, i167 int, i168 int, i169 int, i170 int, i171 int, i172 int, i173 int, i174
+int, i175 int, i176 int, i177 int, i178 int, i179 int, i180 int, i181 int, i182
+int, i183 int, i184 int, i185 int, i186 int, i187 int, i188 int, i189 int, i190
+int, i191 int, i192 int, i193 int, i194 int, i195 int, i196 int, i197 int, i198
+int, i199 int, i200 int, i201 int, i202 int, i203 int, i204 int, i205 int, i206
+int, i207 int, i208 int, i209 int, i210 int, i211 int, i212 int, i213 int, i214
+int, i215 int, i216 int, i217 int, i218 int, i219 int, i220 int, i221 int, i222
+int, i223 int, i224 int, i225 int, i226 int, i227 int, i228 int, i229 int, i230
+int, i231 int, i232 int, i233 int, i234 int, i235 int, i236 int, i237 int, i238
+int, i239 int, i240 int, i241 int, i242 int, i243 int, i244 int, i245 int, i246
+int, i247 int, i248 int, i249 int, i250 int, i251 int, i252 int, i253 int, i254
+int, i255 int, i256 int, i257 int, i258 int, i259 int, i260 int, i261 int, i262
+int, i263 int, i264 int, i265 int, i266 int, i267 int, i268 int, i269 int, i270
+int, i271 int, i272 int, i273 int, i274 int, i275 int, i276 int, i277 int, i278
+int, i279 int, i280 int, i281 int, i282 int, i283 int, i284 int, i285 int, i286
+int, i287 int, i288 int, i289 int, i290 int, i291 int, i292 int, i293 int, i294
+int, i295 int, i296 int, i297 int, i298 int, i299 int, i300 int, i301 int, i302
+int, i303 int, i304 int, i305 int, i306 int, i307 int, i308 int, i309 int, i310
+int, i311 int, i312 int, i313 int, i314 int, i315 int, i316 int, i317 int, i318
+int, i319 int, i320 int, i321 int, i322 int, i323 int, i324 int, i325 int, i326
+int, i327 int, i328 int, i329 int, i330 int, i331 int, i332 int, i333 int, i334
+int, i335 int, i336 int, i337 int, i338 int, i339 int, i340 int, i341 int, i342
+int, i343 int, i344 int, i345 int, i346 int, i347 int, i348 int, i349 int, i350
+int, i351 int, i352 int, i353 int, i354 int, i355 int, i356 int, i357 int, i358
+int, i359 int, i360 int, i361 int, i362 int, i363 int, i364 int, i365 int, i366
+int, i367 int, i368 int, i369 int, i370 int, i371 int, i372 int, i373 int, i374
+int, i375 int, i376 int, i377 int, i378 int, i379 int, i380 int, i381 int, i382
+int, i383 int, i384 int, i385 int, i386 int, i387 int, i388 int, i389 int, i390
+int, i391 int, i392 int, i393 int, i394 int, i395 int, i396 int, i397 int, i398
+int, i399 int, i400 int, i401 int, i402 int, i403 int, i404 int, i405 int, i406
+int, i407 int, i408 int, i409 int, i410 int, i411 int, i412 int, i413 int, i414
+int, i415 int, i416 int, i417 int, i418 int, i419 int, i420 int, i421 int, i422
+int, i423 int, i424 int, i425 int, i426 int, i427 int, i428 int, i429 int, i430
+int, i431 int, i432 int, i433 int, i434 int, i435 int, i436 int, i437 int, i438
+int, i439 int, i440 int, i441 int, i442 int, i443 int, i444 int, i445 int, i446
+int, i447 int, i448 int, i449 int, i450 int, i451 int, i452 int, i453 int, i454
+int, i455 int, i456 int, i457 int, i458 int, i459 int, i460 int, i461 int, i462
+int, i463 int, i464 int, i465 int, i466 int, i467 int, i468 int, i469 int, i470
+int, i471 int, i472 int, i473 int, i474 int, i475 int, i476 int, i477 int, i478
+int, i479 int, i480 int, i481 int, i482 int, i483 int, i484 int, i485 int, i486
+int, i487 int, i488 int, i489 int, i490 int, i491 int, i492 int, i493 int, i494
+int, i495 int, i496 int, i497 int, i498 int, i499 int, i500 int, i501 int, i502
+int, i503 int, i504 int, i505 int, i506 int, i507 int, i508 int, i509 int, i510
+int, i511 int, i512 int, i513 int, i514 int, i515 int, i516 int, i517 int, i518
+int, i519 int, i520 int, i521 int, i522 int, i523 int, i524 int, i525 int, i526
+int, i527 int, i528 int, i529 int, i530 int, i531 int, i532 int, i533 int, i534
+int, i535 int, i536 int, i537 int, i538 int, i539 int, i540 int, i541 int, i542
+int, i543 int, i544 int, i545 int, i546 int, i547 int, i548 int, i549 int, i550
+int, i551 int, i552 int, i553 int, i554 int, i555 int, i556 int, i557 int, i558
+int, i559 int, i560 int, i561 int, i562 int, i563 int, i564 int, i565 int, i566
+int, i567 int, i568 int, i569 int, i570 int, i571 int, i572 int, i573 int, i574
+int, i575 int, i576 int, i577 int, i578 int, i579 int, i580 int, i581 int, i582
+int, i583 int, i584 int, i585 int, i586 int, i587 int, i588 int, i589 int, i590
+int, i591 int, i592 int, i593 int, i594 int, i595 int, i596 int, i597 int, i598
+int, i599 int, i600 int, i601 int, i602 int, i603 int, i604 int, i605 int, i606
+int, i607 int, i608 int, i609 int, i610 int, i611 int, i612 int, i613 int, i614
+int, i615 int, i616 int, i617 int, i618 int, i619 int, i620 int, i621 int, i622
+int, i623 int, i624 int, i625 int, i626 int, i627 int, i628 int, i629 int, i630
+int, i631 int, i632 int, i633 int, i634 int, i635 int, i636 int, i637 int, i638
+int, i639 int, i640 int, i641 int, i642 int, i643 int, i644 int, i645 int, i646
+int, i647 int, i648 int, i649 int, i650 int, i651 int, i652 int, i653 int, i654
+int, i655 int, i656 int, i657 int, i658 int, i659 int, i660 int, i661 int, i662
+int, i663 int, i664 int, i665 int, i666 int, i667 int, i668 int, i669 int, i670
+int, i671 int, i672 int, i673 int, i674 int, i675 int, i676 int, i677 int, i678
+int, i679 int, i680 int, i681 int, i682 int, i683 int, i684 int, i685 int, i686
+int, i687 int, i688 int, i689 int, i690 int, i691 int, i692 int, i693 int, i694
+int, i695 int, i696 int, i697 int, i698 int, i699 int, i700 int, i701 int, i702
+int, i703 int, i704 int, i705 int, i706 int, i707 int, i708 int, i709 int, i710
+int, i711 int, i712 int, i713 int, i714 int, i715 int, i716 int, i717 int, i718
+int, i719 int, i720 int, i721 int, i722 int, i723 int, i724 int, i725 int, i726
+int, i727 int, i728 int, i729 int, i730 int, i731 int, i732 int, i733 int, i734
+int, i735 int, i736 int, i737 int, i738 int, i739 int, i740 int, i741 int, i742
+int, i743 int, i744 int, i745 int, i746 int, i747 int, i748 int, i749 int, i750
+int, i751 int, i752 int, i753 int, i754 int, i755 int, i756 int, i757 int, i758
+int, i759 int, i760 int, i761 int, i762 int, i763 int, i764 int, i765 int, i766
+int, i767 int, i768 int, i769 int, i770 int, i771 int, i772 int, i773 int, i774
+int, i775 int, i776 int, i777 int, i778 int, i779 int, i780 int, i781 int, i782
+int, i783 int, i784 int, i785 int, i786 int, i787 int, i788 int, i789 int, i790
+int, i791 int, i792 int, i793 int, i794 int, i795 int, i796 int, i797 int, i798
+int, i799 int, i800 int, i801 int, i802 int, i803 int, i804 int, i805 int, i806
+int, i807 int, i808 int, i809 int, i810 int, i811 int, i812 int, i813 int, i814
+int, i815 int, i816 int, i817 int, i818 int, i819 int, i820 int, i821 int, i822
+int, i823 int, i824 int, i825 int, i826 int, i827 int, i828 int, i829 int, i830
+int, i831 int, i832 int, i833 int, i834 int, i835 int, i836 int, i837 int, i838
+int, i839 int, i840 int, i841 int, i842 int, i843 int, i844 int, i845 int, i846
+int, i847 int, i848 int, i849 int, i850 int, i851 int, i852 int, i853 int, i854
+int, i855 int, i856 int, i857 int, i858 int, i859 int, i860 int, i861 int, i862
+int, i863 int, i864 int, i865 int, i866 int, i867 int, i868 int, i869 int, i870
+int, i871 int, i872 int, i873 int, i874 int, i875 int, i876 int, i877 int, i878
+int, i879 int, i880 int, i881 int, i882 int, i883 int, i884 int, i885 int, i886
+int, i887 int, i888 int, i889 int, i890 int, i891 int, i892 int, i893 int, i894
+int, i895 int, i896 int, i897 int, i898 int, i899 int, i900 int, i901 int, i902
+int, i903 int, i904 int, i905 int, i906 int, i907 int, i908 int, i909 int, i910
+int, i911 int, i912 int, i913 int, i914 int, i915 int, i916 int, i917 int, i918
+int, i919 int, i920 int, i921 int, i922 int, i923 int, i924 int, i925 int, i926
+int, i927 int, i928 int, i929 int, i930 int, i931 int, i932 int, i933 int, i934
+int, i935 int, i936 int, i937 int, i938 int, i939 int, i940 int, i941 int, i942
+int, i943 int, i944 int, i945 int, i946 int, i947 int, i948 int, i949 int, i950
+int, i951 int, i952 int, i953 int, i954 int, i955 int, i956 int, i957 int, i958
+int, i959 int, i960 int, i961 int, i962 int, i963 int, i964 int, i965 int, i966
+int, i967 int, i968 int, i969 int, i970 int, i971 int, i972 int, i973 int, i974
+int, i975 int, i976 int, i977 int, i978 int, i979 int, i980 int, i981 int, i982
+int, i983 int, i984 int, i985 int, i986 int, i987 int, i988 int, i989 int, i990
+int, i991 int, i992 int, i993 int, i994 int, i995 int, i996 int, i997 int, i998
+int, i999 int, i1000 int, b blob) row_format=dynamic;
+insert into t1 values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Sergei");
+update t1 set b=repeat('a',256);
+update t1 set i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+CREATE TABLE `t1` (
+`post_id` mediumint(8) unsigned NOT NULL auto_increment,
+`topic_id` mediumint(8) unsigned NOT NULL default '0',
+`post_time` datetime NOT NULL default '0000-00-00 00:00:00',
+`post_text` text NOT NULL,
+`icon_url` varchar(10) NOT NULL default '',
+`sign` tinyint(1) unsigned NOT NULL default '0',
+`post_edit` varchar(150) NOT NULL default '',
+`poster_login` varchar(35) NOT NULL default '',
+`ip` varchar(15) NOT NULL default '',
+PRIMARY KEY (`post_id`),
+KEY `post_time` (`post_time`),
+KEY `ip` (`ip`),
+KEY `poster_login` (`poster_login`),
+KEY `topic_id` (`topic_id`),
+FULLTEXT KEY `post_text` (`post_text`)
+) TYPE=MyISAM;
+INSERT INTO t1 (post_text) VALUES ('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test');
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), KEY t1 (a, b, c));
+Specified key was too long. Max key length is 500
+CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255));
+ALTER TABLE t1 ADD INDEX t1 (a, b, c);
+Specified key was too long. Max key length is 500
+DROP TABLE t1;
+CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
+INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
+INSERT into t2 values (1,1,1), (2,2,2);
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 b 1 b A 5 NULL NULL YES BTREE
+t1 1 c 1 c A 5 NULL NULL YES BTREE
+t1 1 a 1 a A 1 NULL NULL BTREE
+t1 1 a 2 b A 5 NULL NULL YES BTREE
+t1 1 c_2 1 c A 5 NULL NULL YES BTREE
+t1 1 c_2 2 a A 5 NULL NULL BTREE
+explain select * from t1,t2 where t1.a=t2.a;
+table type possible_keys key key_len ref rows Extra
+t2 ALL a NULL NULL NULL 2
+t1 ALL a NULL NULL NULL 4 Using where
+explain select * from t1,t2 force index(a) where t1.a=t2.a;
+table type possible_keys key key_len ref rows Extra
+t2 ALL a NULL NULL NULL 2
+t1 ALL a NULL NULL NULL 4 Using where
+explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
+table type possible_keys key key_len ref rows Extra
+t2 ALL a NULL NULL NULL 2
+t1 ref a a 4 t2.a 3
+explain select * from t1,t2 where t1.b=t2.b;
+table type possible_keys key key_len ref rows Extra
+t2 ALL b NULL NULL NULL 2
+t1 ref b b 5 t2.b 1 Using where
+explain select * from t1,t2 force index(c) where t1.a=t2.a;
+table type possible_keys key key_len ref rows Extra
+t2 ALL NULL NULL NULL NULL 2
+t1 ALL a NULL NULL NULL 4 Using where
+explain select * from t1 where a=0 or a=2;
+table type possible_keys key key_len ref rows Extra
+t1 ALL a NULL NULL NULL 5 Using where
+explain select * from t1 force index (a) where a=0 or a=2;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 4 NULL 4 Using where
+drop table t1,t2;
+create table t1 (a int not null auto_increment primary key, b varchar(255));
+insert into t1 (b) values (repeat('a',100)),(repeat('b',100)),(repeat('c',100));
+update t1 set b=repeat(left(b,1),200) where a=1;
+delete from t1 where (a & 1)= 0;
+update t1 set b=repeat('e',200) where a=1;
+flush tables;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+update t1 set b=repeat(left(b,1),255) where a between 1 and 5;
+update t1 set b=repeat(left(b,1),10) where a between 32 and 43;
+update t1 set b=repeat(left(b,1),2) where a between 64 and 66;
+update t1 set b=repeat(left(b,1),65) where a between 67 and 70;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+insert into t1 (b) values (repeat('z',100));
+update t1 set b="test" where left(b,1) > 'n';
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+create table t1 ( a text not null, key a (a(20)));
+insert into t1 values ('aaa '),('aaa'),('aa');
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+select concat(a,'.') from t1 where a='aaa';
+concat(a,'.')
+aaa.
+aaa .
+select concat(a,'.') from t1 where binary a='aaa';
+concat(a,'.')
+aaa.
+update t1 set a='bbb' where a='aaa';
+select concat(a,'.') from t1;
+concat(a,'.')
+bbb.
+bbb.
+aa.
+drop table t1;
+create table t1(a text not null, b text not null, c text not null, index (a(10),b(10),c(10)));
+insert into t1 values('807780', '477', '165');
+insert into t1 values('807780', '477', '162');
+insert into t1 values('807780', '472', '162');
+select * from t1 where a='807780' and b='477' and c='165';
+a b c
+807780 477 165
+drop table t1;
+create table t1 (a int not null auto_increment primary key, b text not null, unique b (b(20)));
+insert into t1 (b) values ('a'),('a '),('a ');
+select concat(b,'.') from t1;
+concat(b,'.')
+a.
+a .
+a .
+update t1 set b='b ' where a=2;
+update t1 set b='b ' where a > 1;
+Duplicate entry 'b ' for key 2
+delete from t1 where b='b';
+select a,concat(b,'.') from t1;
+a concat(b,'.')
+1 a.
+3 a .
+drop table t1;
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
new file mode 100644
index 00000000000..eeac31ba40b
--- /dev/null
+++ b/mysql-test/r/mysqlbinlog.result
@@ -0,0 +1,83 @@
+drop table if exists t1,t2;
+set timestamp=1000000000;
+create table t1 (word varchar(20));
+create table t2 (id int auto_increment not null primary key);
+insert into t1 values ("abirvalg");
+insert into t2 values ();
+load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words.dat' into table t1;
+insert into t1 values ("Alas");
+flush logs;
+
+--- Local --
+use test;
+SET TIMESTAMP=1000000000;
+create table t1 (word varchar(20));
+SET TIMESTAMP=1000000000;
+create table t2 (id int auto_increment not null primary key);
+SET TIMESTAMP=1000000000;
+insert into t1 values ("abirvalg");
+SET INSERT_ID=1;
+SET TIMESTAMP=1000000000;
+insert into t2 values ();
+LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-1-0' INTO TABLE t1 FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word);
+LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-2-0' INTO TABLE t1 FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word);
+LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-3-0' INTO TABLE t1 FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word);
+LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-4-0' INTO TABLE t1 FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word);
+LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/words.dat-5-0' INTO TABLE t1 FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' (word);
+
+--- Broken LOAD DATA --
+use test;
+SET TIMESTAMP=1000000000;
+insert into t1 values ("Alas");
+
+--- --database --
+SET INSERT_ID=1;
+
+--- --position --
+use test;
+SET TIMESTAMP=1000000000;
+insert into t1 values ("Alas");
+
+--- Remote --
+use test;
+SET TIMESTAMP=1000000000;
+create table t1 (word varchar(20));
+SET TIMESTAMP=1000000000;
+create table t2 (id int auto_increment not null primary key);
+SET TIMESTAMP=1000000000;
+insert into t1 values ("abirvalg");
+SET INSERT_ID=1;
+SET TIMESTAMP=1000000000;
+insert into t2 values ();
+SET TIMESTAMP=1000000000;
+insert into t1 values ("Alas");
+
+--- Broken LOAD DATA --
+use test;
+SET TIMESTAMP=1000000000;
+insert into t1 values ("Alas");
+
+--- --database --
+use test;
+SET TIMESTAMP=1000000000;
+create table t1 (word varchar(20));
+SET TIMESTAMP=1000000000;
+create table t2 (id int auto_increment not null primary key);
+SET TIMESTAMP=1000000000;
+insert into t1 values ("abirvalg");
+SET INSERT_ID=1;
+SET TIMESTAMP=1000000000;
+insert into t2 values ();
+SET TIMESTAMP=1000000000;
+insert into t1 values ("Alas");
+
+--- --position --
+use test;
+SET TIMESTAMP=1000000000;
+insert into t1 values ("Alas");
+drop table t1;
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
new file mode 100644
index 00000000000..837a3627647
--- /dev/null
+++ b/mysql-test/r/mysqldump.result
@@ -0,0 +1,37 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(a int);
+INSERT INTO t1 VALUES (1), (2);
+<?xml version="1.0"?>
+<mysqldump>
+<database name="test">
+ <table name="t1">
+ <row>
+ <field name="a">1</field>
+ </row>
+ <row>
+ <field name="a">2</field>
+ </row>
+ </table>
+</database>
+</mysqldump>
+DROP TABLE t1;
+CREATE TABLE t1 (a decimal(240, 20));
+INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"),
+("0987654321098765432109876543210987654321");
+CREATE TABLE t1 (
+ a decimal(240,20) default NULL
+) TYPE=MyISAM;
+
+INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890.00000000000000000000");
+INSERT INTO t1 VALUES ("0987654321098765432109876543210987654321.00000000000000000000");
+
+DROP TABLE t1;
+CREATE TABLE t1 (a double);
+INSERT INTO t1 VALUES (-9e999999);
+CREATE TABLE t1 (
+ a double default NULL
+) TYPE=MyISAM;
+
+INSERT INTO t1 VALUES (RES);
+
+DROP TABLE t1;
diff --git a/mysql-test/r/not_embedded.require b/mysql-test/r/not_embedded.require
new file mode 100644
index 00000000000..b2ea98bcd0a
--- /dev/null
+++ b/mysql-test/r/not_embedded.require
@@ -0,0 +1,2 @@
+have_embedded
+0
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index 9f0bdb07973..ba2161d3147 100644
--- a/mysql-test/r/null.result
+++ b/mysql-test/r/null.result
@@ -1,32 +1,111 @@
+select null,\N,isnull(null),isnull(1/0),isnull(1/0 = null),ifnull(null,1),ifnull(null,"TRUE"),ifnull("TRUE","ERROR"),1/0 is null,1 is not null;
NULL NULL isnull(null) isnull(1/0) isnull(1/0 = null) ifnull(null,1) ifnull(null,"TRUE") ifnull("TRUE","ERROR") 1/0 is null 1 is not null
NULL NULL 1 1 1 1 TRUE TRUE 1 1
+select 1 | NULL,1 & NULL,1+NULL,1-NULL;
1 | NULL 1 & NULL 1+NULL 1-NULL
NULL NULL NULL NULL
+select NULL=NULL,NULL<>NULL,IFNULL(NULL,1.1)+0,IFNULL(NULL,1) | 0;
NULL=NULL NULL<>NULL IFNULL(NULL,1.1)+0 IFNULL(NULL,1) | 0
-NULL NULL 1.1 1
+NULL NULL 1 1
+select strcmp("a",NULL),(1<NULL)+0.0,NULL regexp "a",null like "a%","a%" like null;
strcmp("a",NULL) (1<NULL)+0.0 NULL regexp "a" null like "a%" "a%" like null
NULL NULL NULL NULL NULL
+select concat("a",NULL),replace(NULL,"a","b"),replace("string","i",NULL),replace("string",NULL,"i"),insert("abc",1,1,NULL),left(NULL,1);
concat("a",NULL) replace(NULL,"a","b") replace("string","i",NULL) replace("string",NULL,"i") insert("abc",1,1,NULL) left(NULL,1)
NULL NULL NULL NULL NULL NULL
+select repeat("a",0),repeat("ab",5+5),repeat("ab",-1),reverse(NULL);
repeat("a",0) repeat("ab",5+5) repeat("ab",-1) reverse(NULL)
abababababababababab NULL
+select field(NULL,"a","b","c");
field(NULL,"a","b","c")
0
+select 2 between null and 1,2 between 3 AND NULL,NULL between 1 and 2,2 between NULL and 3, 2 between 1 AND null;
2 between null and 1 2 between 3 AND NULL NULL between 1 and 2 2 between NULL and 3 2 between 1 AND null
0 0 NULL NULL NULL
+SELECT NULL AND NULL, 1 AND NULL, NULL AND 1, NULL OR NULL, 0 OR NULL, NULL OR 0;
NULL AND NULL 1 AND NULL NULL AND 1 NULL OR NULL 0 OR NULL NULL OR 0
NULL NULL NULL NULL NULL NULL
+SELECT (NULL OR NULL) IS NULL;
(NULL OR NULL) IS NULL
1
+select NULL AND 0, 0 and NULL;
NULL AND 0 0 and NULL
-NULL 0
+0 0
+select inet_ntoa(null),inet_aton(null),inet_aton("122.256"),inet_aton("122.226."),inet_aton("");
inet_ntoa(null) inet_aton(null) inet_aton("122.256") inet_aton("122.226.") inet_aton("")
NULL NULL NULL NULL NULL
+drop table if exists t1;
+create table t1 (x int);
+insert into t1 values (null);
+select * from t1 where x != 0;
x
+drop table t1;
+CREATE TABLE t1 (
+indexed_field int default NULL,
+KEY indexed_field (indexed_field)
+);
+INSERT INTO t1 VALUES (NULL),(NULL);
+SELECT * FROM t1 WHERE indexed_field=NULL;
indexed_field
+SELECT * FROM t1 WHERE indexed_field IS NULL;
indexed_field
NULL
NULL
+SELECT * FROM t1 WHERE indexed_field<=>NULL;
indexed_field
NULL
NULL
+DROP TABLE t1;
+create table t1 (a int, b int) type=myisam;
+insert into t1 values(20,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a;
+b ifnull(t2.b,"this is null")
+NULL this is null
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+b ifnull(t2.b,"this is null")
+NULL this is null
+insert into t1 values(10,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+b ifnull(t2.b,"this is null")
+NULL this is null
+NULL this is null
+drop table t1;
+CREATE TABLE t1 (a varchar(16) NOT NULL, b smallint(6) NOT NULL, c datetime NOT NULL, d smallint(6) NOT NULL);
+INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55";
+UPDATE t1 SET d=1/NULL;
+UPDATE t1 SET d=NULL;
+INSERT INTO t1 (a) values (null);
+Column 'a' cannot be null
+INSERT INTO t1 (a) values (1/null);
+Column 'a' cannot be null
+INSERT INTO t1 (a) values (null),(null);
+INSERT INTO t1 (b) values (null);
+Column 'b' cannot be null
+INSERT INTO t1 (b) values (1/null);
+Column 'b' cannot be null
+INSERT INTO t1 (b) values (null),(null);
+INSERT INTO t1 (c) values (null);
+Column 'c' cannot be null
+INSERT INTO t1 (c) values (1/null);
+Column 'c' cannot be null
+INSERT INTO t1 (c) values (null),(null);
+INSERT INTO t1 (d) values (null);
+Column 'd' cannot be null
+INSERT INTO t1 (d) values (1/null);
+Column 'd' cannot be null
+INSERT INTO t1 (d) values (null),(null);
+select * from t1;
+a b c d
+ 0 0000-00-00 00:00:00 0
+ 0 0000-00-00 00:00:00 0
+ 0 0000-00-00 00:00:00 0
+ 0 0000-00-00 00:00:00 0
+ 0 0000-00-00 00:00:00 0
+ 0 0000-00-00 00:00:00 0
+ 0 0000-00-00 00:00:00 0
+ 0 0000-00-00 00:00:00 0
+ 0 0000-00-00 00:00:00 0
+drop table t1;
diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result
index 46bcbebe170..009a3e06eb2 100644
--- a/mysql-test/r/null_key.result
+++ b/mysql-test/r/null_key.result
@@ -1,101 +1,164 @@
+drop table if exists t1;
+create table t1 (a int, b int not null,unique key (a,b),index(b)) type=myisam;
+insert ignore into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(null,7),(9,9),(8,8),(7,7),(null,9),(null,9),(6,6);
+explain select * from t1 where a is null;
table type possible_keys key key_len ref rows Extra
-t1 ref a a 5 const 3 where used; Using index
+t1 ref a a 5 const 3 Using where; Using index
+explain select * from t1 where a is null and b = 2;
table type possible_keys key key_len ref rows Extra
-t1 ref a,b a 9 const,const 1 where used; Using index
+t1 ref a,b a 9 const,const 1 Using where; Using index
+explain select * from t1 where a is null and b = 7;
table type possible_keys key key_len ref rows Extra
-t1 ref a,b a 9 const,const 1 where used; Using index
+t1 ref a,b a 9 const,const 1 Using where; Using index
+explain select * from t1 where a=2 and b = 2;
table type possible_keys key key_len ref rows Extra
t1 const a,b a 9 const,const 1
+explain select * from t1 where a<=>b limit 2;
table type possible_keys key key_len ref rows Extra
-t1 index NULL a 9 NULL 12 where used; Using index
+t1 index NULL a 9 NULL 12 Using where; Using index
+explain select * from t1 where (a is null or a > 0 and a < 3) and b < 5 limit 3;
table type possible_keys key key_len ref rows Extra
-t1 range a,b a 9 NULL 3 where used; Using index
+t1 range a,b a 9 NULL 3 Using where; Using index
+explain select * from t1 where (a is null or a = 7) and b=7;
table type possible_keys key key_len ref rows Extra
-t1 ref a,b b 4 const 2 where used
+t1 ref a,b b 4 const 2 Using where
+explain select * from t1 where (a is null and b>a) or a is null and b=7 limit 2;
table type possible_keys key key_len ref rows Extra
-t1 ref a,b a 5 const 3 where used; Using index
+t1 ref a,b a 5 const 3 Using where; Using index
+explain select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
table type possible_keys key key_len ref rows Extra
-t1 range a,b a 9 NULL 2 where used; Using index
+t1 range a,b a 9 NULL 2 Using where; Using index
+explain select * from t1 where a > 1 and a < 3 limit 1;
table type possible_keys key key_len ref rows Extra
-t1 range a a 5 NULL 1 where used; Using index
+t1 range a a 5 NULL 1 Using where; Using index
+explain select * from t1 where a > 8 and a < 9;
table type possible_keys key key_len ref rows Extra
-t1 range a a 5 NULL 1 where used; Using index
+t1 range a a 5 NULL 1 Using where; Using index
+select * from t1 where a is null;
a b
NULL 7
NULL 9
NULL 9
+select * from t1 where a is null and b = 7;
a b
NULL 7
+select * from t1 where a<=>b limit 2;
a b
1 1
2 2
+select * from t1 where (a is null or a > 0 and a < 3) and b < 5 limit 3;
a b
1 1
2 2
+select * from t1 where (a is null or a > 0 and a < 3) and b > 7 limit 3;
a b
NULL 9
NULL 9
+select * from t1 where (a is null or a = 7) and b=7;
a b
NULL 7
7 7
+select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
a b
NULL 7
NULL 9
NULL 9
+alter table t1 modify b blob not null, add c int not null, drop key a, add unique key (a,b(20),c), drop key b, add key (b(10));
+explain select * from t1 where a is null and b = 2;
table type possible_keys key key_len ref rows Extra
-t1 ref a,b a 5 const 3 where used
+t1 ref a,b a 5 const 3 Using where
+explain select * from t1 where a is null and b = 2 and c=0;
table type possible_keys key key_len ref rows Extra
-t1 ref a,b a 5 const 3 where used
+t1 ref a,b a 5 const 3 Using where
+explain select * from t1 where a is null and b = 7 and c=0;
table type possible_keys key key_len ref rows Extra
-t1 ref a,b a 5 const 3 where used
+t1 ref a,b a 5 const 3 Using where
+explain select * from t1 where a=2 and b = 2;
table type possible_keys key key_len ref rows Extra
-t1 ref a,b a 5 const 1 where used
+t1 ref a,b a 5 const 1 Using where
+explain select * from t1 where a<=>b limit 2;
table type possible_keys key key_len ref rows Extra
-t1 ALL NULL NULL NULL NULL 12 where used
+t1 ALL NULL NULL NULL NULL 12 Using where
+explain select * from t1 where (a is null or a > 0 and a < 3) and b < 5 and c=0 limit 3;
table type possible_keys key key_len ref rows Extra
-t1 range a,b a 5 NULL 12 where used
+t1 range a,b a 5 NULL 5 Using where
+explain select * from t1 where (a is null or a = 7) and b=7 and c=0;
table type possible_keys key key_len ref rows Extra
-t1 range a,b a 5 NULL 4 where used
+t1 ALL a,b NULL NULL NULL 12 Using where
+explain select * from t1 where (a is null and b>a) or a is null and b=7 limit 2;
table type possible_keys key key_len ref rows Extra
-t1 ref a,b a 5 const 3 where used
+t1 ref a,b a 5 const 3 Using where
+explain select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
table type possible_keys key key_len ref rows Extra
-t1 ref a,b a 5 const 3 where used
+t1 ref a,b a 5 const 3 Using where
+explain select * from t1 where a > 1 and a < 3 limit 1;
table type possible_keys key key_len ref rows Extra
-t1 range a a 5 NULL 1 where used
+t1 range a a 5 NULL 1 Using where
+explain select * from t1 where a is null and b=7 or a > 1 and a < 3 limit 1;
table type possible_keys key key_len ref rows Extra
-t1 range a,b a 5 NULL 4 where used
+t1 range a,b a 5 NULL 4 Using where
+explain select * from t1 where a > 8 and a < 9;
table type possible_keys key key_len ref rows Extra
-t1 range a a 5 NULL 1 where used
+t1 range a a 5 NULL 1 Using where
+explain select * from t1 where b like "6%";
table type possible_keys key key_len ref rows Extra
-t1 range b b 12 NULL 1 where used
+t1 range b b 12 NULL 1 Using where
+select * from t1 where a is null;
a b c
NULL 7 0
NULL 9 0
NULL 9 0
+select * from t1 where a is null and b = 7 and c=0;
a b c
NULL 7 0
+select * from t1 where a<=>b limit 2;
a b c
1 1 0
2 2 0
+select * from t1 where (a is null or a > 0 and a < 3) and b < 5 limit 3;
a b c
1 1 0
2 2 0
+select * from t1 where (a is null or a > 0 and a < 3) and b > 7 limit 3;
a b c
NULL 9 0
NULL 9 0
+select * from t1 where (a is null or a = 7) and b=7 and c=0;
a b c
NULL 7 0
7 7 0
+select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
a b c
NULL 7 0
NULL 9 0
NULL 9 0
+select * from t1 where b like "6%";
a b c
6 6 0
+drop table t1;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (
+id int(10) unsigned NOT NULL auto_increment,
+uniq_id int(10) unsigned default NULL,
+PRIMARY KEY (id),
+UNIQUE KEY idx1 (uniq_id)
+) TYPE=MyISAM;
+CREATE TABLE t2 (
+id int(10) unsigned NOT NULL auto_increment,
+uniq_id int(10) unsigned default NULL,
+PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL);
+INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL);
+explain select id from t1 where uniq_id is null;
table type possible_keys key key_len ref rows Extra
-t1 ref idx1 idx1 5 const 1 where used
+t1 ref idx1 idx1 5 const 1 Using where
+explain select id from t1 where uniq_id =1;
table type possible_keys key key_len ref rows Extra
t1 const idx1 idx1 5 const 1
+UPDATE t1 SET id=id+100 where uniq_id is null;
+UPDATE t2 SET id=id+100 where uniq_id is null;
+select id from t1 where uniq_id is null;
id
101
102
@@ -103,6 +166,7 @@ id
106
109
110
+select id from t2 where uniq_id is null;
id
101
102
@@ -110,36 +174,90 @@ id
106
109
110
+DELETE FROM t1 WHERE uniq_id IS NULL;
+DELETE FROM t2 WHERE uniq_id IS NULL;
+SELECT * FROM t1 ORDER BY uniq_id, id;
id uniq_id
3 1
4 2
7 3
8 4
+SELECT * FROM t2 ORDER BY uniq_id, id;
id uniq_id
3 1
4 2
7 3
8 4
+DROP table t1,t2;
+CREATE TABLE `t1` (
+`order_id` char(32) NOT NULL default '',
+`product_id` char(32) NOT NULL default '',
+`product_type` int(11) NOT NULL default '0',
+PRIMARY KEY (`order_id`,`product_id`,`product_type`)
+) TYPE=MyISAM;
+CREATE TABLE `t2` (
+`order_id` char(32) NOT NULL default '',
+`product_id` char(32) NOT NULL default '',
+`product_type` int(11) NOT NULL default '0',
+PRIMARY KEY (`order_id`,`product_id`,`product_type`)
+) TYPE=MyISAM;
+INSERT INTO t1 (order_id, product_id, product_type) VALUES
+('3d7ce39b5d4b3e3d22aaafe9b633de51',1206029, 3),
+('3d7ce39b5d4b3e3d22aaafe9b633de51',5880836, 3),
+('9d9aad7764b5b2c53004348ef8d34500',2315652, 3);
+INSERT INTO t2 (order_id, product_id, product_type) VALUES
+('9d9aad7764b5b2c53004348ef8d34500',2315652, 3);
+select t1.* from t1
+left join t2 using(order_id, product_id, product_type)
+where t2.order_id=NULL;
order_id product_id product_type
+select t1.* from t1
+left join t2 using(order_id, product_id, product_type)
+where t2.order_id is NULL;
order_id product_id product_type
3d7ce39b5d4b3e3d22aaafe9b633de51 1206029 3
3d7ce39b5d4b3e3d22aaafe9b633de51 5880836 3
+drop table t1,t2;
+create table t1 (id int);
+insert into t1 values (null), (0);
+create table t2 (id int);
+insert into t2 values (null);
+select * from t1, t2 where t1.id = t2.id;
id id
+alter table t1 add key id (id);
+select * from t1, t2 where t1.id = t2.id;
id id
+drop table t1,t2;
+create table t1 (
+id integer,
+id2 integer not null,
+index (id),
+index (id2)
+);
+insert into t1 values(null,null),(1,1);
+select * from t1;
id id2
NULL 0
1 1
+select * from t1 where id <=> null;
id id2
NULL 0
+select * from t1 where id <=> null or id > 0;
id id2
NULL 0
1 1
+select * from t1 where id is null or id > 0;
id id2
NULL 0
1 1
+select * from t1 where id2 <=> null or id2 > 0;
id id2
1 1
+select * from t1 where id2 is null or id2 > 0;
id id2
1 1
+delete from t1 where id <=> NULL;
+select * from t1;
id id2
1 1
+drop table t1;
diff --git a/mysql-test/r/odbc.result b/mysql-test/r/odbc.result
index 753d80e4539..5aa163a663e 100644
--- a/mysql-test/r/odbc.result
+++ b/mysql-test/r/odbc.result
@@ -1,7 +1,16 @@
+select {fn length("hello")}, { date "1997-10-20" };
{fn length("hello")} 1997-10-20
5 1997-10-20
+drop table if exists t1;
+create table t1 (a int not null auto_increment,b int not null,primary key (a,b));
+insert into t1 SET A=NULL,B=1;
+insert into t1 SET a=null,b=2;
+select * from t1 where a is null and b=2;
a b
2 2
+select * from t1 where a is null;
a b
+explain select * from t1 where b is null;
Comment
Impossible WHERE noticed after reading const tables
+drop table t1;
diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result
new file mode 100644
index 00000000000..52bd83df5ed
--- /dev/null
+++ b/mysql-test/r/olap.result
@@ -0,0 +1,27 @@
+drop table if exists sales;
+create table sales ( product varchar(32), country varchar(32), year int, profit int);
+insert into sales values ( 'Computer', 'India',2000, 1200),
+( 'TV', 'United States', 1999, 150),
+( 'Calculator', 'United States', 1999,50),
+( 'Computer', 'United States', 1999,1500),
+( 'Computer', 'United States', 2000,1500),
+( 'TV', 'United States', 2000, 150),
+( 'TV', 'India', 2000, 100),
+( 'TV', 'India', 2000, 100),
+( 'Calculator', 'United States', 2000,75),
+( 'Calculator', 'India', 2000,75),
+( 'TV', 'India', 1999, 100),
+( 'Computer', 'India', 1999,1200),
+( 'Computer', 'United States', 2000,1500),
+( 'Calculator', 'United States', 2000,75);
+select product, country , year, sum(profit) from sales group by product, country, year with cube;
+This version of MySQL doesn't yet support 'CUBE'
+explain select product, country , year, sum(profit) from sales group by product, country, year with cube;
+This version of MySQL doesn't yet support 'CUBE'
+select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+This version of MySQL doesn't yet support 'ROLLUP'
+explain select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+This version of MySQL doesn't yet support 'ROLLUP'
+select product, country , year, sum(profit) from sales group by product, country, year with cube union all select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+This version of MySQL doesn't yet support 'CUBE'
+drop table sales;
diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result
new file mode 100644
index 00000000000..f6c7bf5bc79
--- /dev/null
+++ b/mysql-test/r/openssl_1.result
@@ -0,0 +1,32 @@
+drop table if exists t1;
+create table t1(f1 int);
+insert into t1 values (5);
+grant select on test.* to ssl_user1@localhost require SSL;
+grant select on test.* to ssl_user2@localhost require cipher "EDH-RSA-DES-CBC3-SHA";
+grant select on test.* to ssl_user3@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com";
+grant select on test.* to ssl_user4@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com";
+flush privileges;
+select * from t1;
+f1
+5
+delete from t1;
+Access denied for user: 'ssl_user1@localhost' to database 'test'
+select * from t1;
+f1
+5
+delete from t1;
+Access denied for user: 'ssl_user2@localhost' to database 'test'
+select * from t1;
+f1
+5
+delete from t1;
+Access denied for user: 'ssl_user3@localhost' to database 'test'
+select * from t1;
+f1
+5
+delete from t1;
+Access denied for user: 'ssl_user4@localhost' to database 'test'
+delete from mysql.user where user='ssl_user%';
+delete from mysql.db where user='ssl_user%';
+flush privileges;
+drop table t1;
diff --git a/mysql-test/r/openssl_2.result b/mysql-test/r/openssl_2.result
new file mode 100644
index 00000000000..b5c67dfbcb0
--- /dev/null
+++ b/mysql-test/r/openssl_2.result
@@ -0,0 +1,2 @@
+SHOW STATUS LIKE 'SSL%';
+Variable_name Value
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index d45ae6b6dec..093633d5f5a 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -1,3 +1,39 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (
+id int(6) DEFAULT '0' NOT NULL,
+idservice int(5),
+clee char(20) NOT NULL,
+flag char(1),
+KEY id (id),
+PRIMARY KEY (clee)
+);
+INSERT INTO t1 VALUES (2,4,'6067169d','Y');
+INSERT INTO t1 VALUES (2,5,'606716d1','Y');
+INSERT INTO t1 VALUES (2,1,'606717c1','Y');
+INSERT INTO t1 VALUES (3,1,'6067178d','Y');
+INSERT INTO t1 VALUES (2,6,'60671515','Y');
+INSERT INTO t1 VALUES (2,7,'60671569','Y');
+INSERT INTO t1 VALUES (2,3,'dd','Y');
+CREATE TABLE t2 (
+id int(6) NOT NULL auto_increment,
+description varchar(40) NOT NULL,
+idform varchar(40),
+ordre int(6) unsigned DEFAULT '0' NOT NULL,
+image varchar(60),
+PRIMARY KEY (id),
+KEY id (id,ordre)
+);
+INSERT INTO t2 VALUES (1,'Emettre un appel d''offres','en_construction.html',10,'emettre.gif');
+INSERT INTO t2 VALUES (2,'Emettre des soumissions','en_construction.html',20,'emettre.gif');
+INSERT INTO t2 VALUES (7,'Liste des t2','t2_liste_form.phtml',51060,'link.gif');
+INSERT INTO t2 VALUES (8,'Consulter les soumissions','consulter_soumissions.phtml',200,'link.gif');
+INSERT INTO t2 VALUES (9,'Ajouter un type de materiel','typeMateriel_ajoute_form.phtml',51000,'link.gif');
+INSERT INTO t2 VALUES (10,'Lister/modifier un type de materiel','typeMateriel_liste_form.phtml',51010,'link.gif');
+INSERT INTO t2 VALUES (3,'Créer une fiche de client','clients_ajoute_form.phtml',40000,'link.gif');
+INSERT INTO t2 VALUES (4,'Modifier des clients','en_construction.html',40010,'link.gif');
+INSERT INTO t2 VALUES (5,'Effacer des clients','en_construction.html',40020,'link.gif');
+INSERT INTO t2 VALUES (6,'Ajouter un service','t2_ajoute_form.phtml',51050,'link.gif');
+select t1.id,t1.idservice,t2.ordre,t2.description from t1, t2 where t1.id = 2 and t1.idservice = t2.id order by t2.ordre;
id idservice ordre description
2 1 10 Emettre un appel d'offres
2 3 40000 Créer une fiche de client
@@ -5,34 +41,53 @@ id idservice ordre description
2 5 40020 Effacer des clients
2 6 51050 Ajouter un service
2 7 51060 Liste des t2
+drop table t1,t2;
+create table t1 (first char(10),last char(10));
+insert into t1 values ("Michael","Widenius");
+insert into t1 values ("Allan","Larsson");
+insert into t1 values ("David","Axmark");
+select concat(first," ",last) as name from t1 order by name;
name
Allan Larsson
David Axmark
Michael Widenius
+select concat(last," ",first) as name from t1 order by name;
name
Axmark David
Larsson Allan
Widenius Michael
+drop table t1;
+create table t1 (i int);
+insert into t1 values(1),(2),(1),(2),(1),(2),(3);
+select distinct i from t1;
i
1
2
3
+select distinct i from t1 order by rand(5);
i
1
3
2
+select distinct i from t1 order by i desc;
i
3
2
1
+select distinct i from t1 order by 1-i;
i
3
2
1
+select distinct i from t1 order by mod(i,2),i;
i
2
1
3
+drop table t1;
+create table t1 (id int not null,col1 int not null,col2 int not null,index(col1));
+insert into t1 values(1,2,2),(2,2,1),(3,1,2),(4,1,1),(5,1,4),(6,2,3),(7,3,1),(8,2,4);
+select * from t1 order by col1,col2;
id col1 col2
4 1 1
3 1 2
@@ -42,6 +97,7 @@ id col1 col2
6 2 3
8 2 4
7 3 1
+select col1 from t1 order by id;
col1
2
2
@@ -51,6 +107,7 @@ col1
2
3
2
+select col1 as id from t1 order by t1.id;
id
1
1
@@ -60,6 +117,7 @@ id
2
2
3
+select concat(col1) as id from t1 order by t1.id;
id
2
2
@@ -69,21 +127,75 @@ id
2
3
2
+drop table t1;
+CREATE TABLE t1 (id int auto_increment primary key,aika varchar(40),aikakentta timestamp);
+insert into t1 (aika) values ('Keskiviikko');
+insert into t1 (aika) values ('Tiistai');
+insert into t1 (aika) values ('Maanantai');
+insert into t1 (aika) values ('Sunnuntai');
+SELECT FIELD(SUBSTRING(t1.aika,1,2),'Ma','Ti','Ke','To','Pe','La','Su') AS test FROM t1 ORDER by test;
test
1
2
3
7
+drop table t1;
+CREATE TABLE t1
+(
+a int unsigned NOT NULL,
+b int unsigned NOT NULL,
+c int unsigned NOT NULL,
+UNIQUE(a),
+INDEX(b),
+INDEX(c)
+);
+CREATE TABLE t2
+(
+c int unsigned NOT NULL,
+i int unsigned NOT NULL,
+INDEX(c)
+);
+CREATE TABLE t3
+(
+c int unsigned NOT NULL,
+v varchar(64),
+INDEX(c)
+);
+INSERT INTO t1 VALUES (1,1,1);
+INSERT INTO t1 VALUES (2,1,2);
+INSERT INTO t1 VALUES (3,2,1);
+INSERT INTO t1 VALUES (4,2,2);
+INSERT INTO t2 VALUES (1,50);
+INSERT INTO t2 VALUES (2,25);
+INSERT INTO t3 VALUES (1,'123 Park Place');
+INSERT INTO t3 VALUES (2,'453 Boardwalk');
+SELECT a,b,if(b = 1,i,if(b = 2,v,''))
+FROM t1
+LEFT JOIN t2 USING(c)
+LEFT JOIN t3 ON t3.c = t1.c;
a b if(b = 1,i,if(b = 2,v,''))
1 1 50
2 1 25
3 2 123 Park Place
4 2 453 Boardwalk
+SELECT a,b,if(b = 1,i,if(b = 2,v,''))
+FROM t1
+LEFT JOIN t2 USING(c)
+LEFT JOIN t3 ON t3.c = t1.c
+ORDER BY a;
a b if(b = 1,i,if(b = 2,v,''))
1 1 50
2 1 25
3 2 123 Park Place
4 2 453 Boardwalk
+drop table t1,t2,t3;
+create table t1 (ID int not null primary key, TransactionID int not null);
+insert into t1 (ID, TransactionID) values (1, 87), (2, 89), (3, 92), (4, 94), (5, 486), (6, 490), (7, 753), (9, 828), (10, 832), (11, 834), (12, 840);
+create table t2 (ID int not null primary key, GroupID int not null);
+insert into t2 (ID, GroupID) values (87, 87), (89, 89), (92, 92), (94, 94), (486, 486), (490, 490),(753, 753), (828, 828), (832, 832), (834, 834), (840, 840);
+create table t3 (ID int not null primary key, DateOfAction date not null);
+insert into t3 (ID, DateOfAction) values (87, '1999-07-19'), (89, '1999-07-19'), (92, '1999-07-19'), (94, '1999-07-19'), (486, '1999-07-18'), (490, '2000-03-27'), (753, '2000-03-28'), (828, '1999-07-27'), (832, '1999-07-27'),(834, '1999-07-27'), (840, '1999-07-27');
+select t3.DateOfAction, t1.TransactionID from t1 join t2 join t3 where t2.ID = t1.TransactionID and t3.ID = t2.GroupID order by t3.DateOfAction, t1.TransactionID;
DateOfAction TransactionID
1999-07-18 486
1999-07-19 87
@@ -96,6 +208,7 @@ DateOfAction TransactionID
1999-07-27 840
2000-03-27 490
2000-03-28 753
+select t3.DateOfAction, t1.TransactionID from t1 join t2 join t3 where t2.ID = t1.TransactionID and t3.ID = t2.GroupID order by t1.TransactionID,t3.DateOfAction;
DateOfAction TransactionID
1999-07-19 87
1999-07-19 89
@@ -108,9 +221,229 @@ DateOfAction TransactionID
1999-07-27 832
1999-07-27 834
1999-07-27 840
+drop table t1,t2,t3;
+drop table if exists t1;
+CREATE TABLE t1 (
+member_id int(11) NOT NULL auto_increment,
+inschrijf_datum varchar(20) NOT NULL default '',
+lastchange_datum varchar(20) NOT NULL default '',
+nickname varchar(20) NOT NULL default '',
+password varchar(8) NOT NULL default '',
+voornaam varchar(30) NOT NULL default '',
+tussenvoegsels varchar(10) NOT NULL default '',
+achternaam varchar(50) NOT NULL default '',
+straat varchar(100) NOT NULL default '',
+postcode varchar(10) NOT NULL default '',
+wijk varchar(40) NOT NULL default '',
+plaats varchar(50) NOT NULL default '',
+telefoon varchar(10) NOT NULL default '',
+geboortedatum date NOT NULL default '0000-00-00',
+geslacht varchar(5) NOT NULL default '',
+email varchar(80) NOT NULL default '',
+uin varchar(15) NOT NULL default '',
+homepage varchar(100) NOT NULL default '',
+internet varchar(15) NOT NULL default '',
+scherk varchar(30) NOT NULL default '',
+favo_boek varchar(50) NOT NULL default '',
+favo_tijdschrift varchar(50) NOT NULL default '',
+favo_tv varchar(50) NOT NULL default '',
+favo_eten varchar(50) NOT NULL default '',
+favo_muziek varchar(30) NOT NULL default '',
+info text NOT NULL,
+ipnr varchar(30) NOT NULL default '',
+PRIMARY KEY (member_id)
+) TYPE=MyISAM PACK_KEYS=1;
+insert into t1 (member_id) values (1),(2),(3);
+select member_id, nickname, voornaam FROM t1
+ORDER by lastchange_datum DESC LIMIT 2;
member_id nickname voornaam
1
2
+drop table t1;
+create table t1 (a int not null, b int, c varchar(10), key (a, b, c));
+insert into t1 values (1, NULL, NULL), (1, NULL, 'b'), (1, 1, NULL), (1, 1, 'b'), (1, 1, 'b'), (2, 1, 'a'), (2, 1, 'b'), (2, 2, 'a'), (2, 2, 'b'), (2, 3, 'c'),(1,3,'b');
+explain select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 20 NULL 2 Using where; Using index
+select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc;
+a b c
+1 NULL b
+explain select * from t1 where a >= 1 and a < 3 order by a desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 4 NULL 10 Using where; Using index
+select * from t1 where a >= 1 and a < 3 order by a desc;
+a b c
+2 3 c
+2 2 b
+2 2 a
+2 1 b
+2 1 a
+1 3 b
+1 1 b
+1 1 b
+1 1 NULL
+1 NULL b
+1 NULL NULL
+explain select * from t1 where a = 1 order by a desc, b desc;
+table type possible_keys key key_len ref rows Extra
+t1 ref a a 4 const 5 Using where; Using index
+select * from t1 where a = 1 order by a desc, b desc;
+a b c
+1 3 b
+1 1 b
+1 1 b
+1 1 NULL
+1 NULL b
+1 NULL NULL
+explain select * from t1 where a = 1 and b is null order by a desc, b desc;
+table type possible_keys key key_len ref rows Extra
+t1 ref a a 9 const,const 2 Using where; Using index; Using filesort
+select * from t1 where a = 1 and b is null order by a desc, b desc;
+a b c
+1 NULL NULL
+1 NULL b
+explain select * from t1 where a >= 1 and a < 3 and b >0 order by a desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 9 NULL 8 Using where; Using index
+explain select * from t1 where a = 2 and b >0 order by a desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 9 NULL 4 Using where; Using index
+explain select * from t1 where a = 2 and b is null order by a desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 ref a a 9 const,const 1 Using where; Using index; Using filesort
+explain select * from t1 where a = 2 and (b is null or b > 0) order by a
+desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 9 NULL 5 Using where; Using index
+explain select * from t1 where a = 2 and b > 0 order by a desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 9 NULL 4 Using where; Using index
+explain select * from t1 where a = 2 and b < 2 order by a desc,b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 9 NULL 2 Using where; Using index
+explain select * from t1 where a = 1 order by b desc;
+table type possible_keys key key_len ref rows Extra
+t1 ref a a 4 const 5 Using where; Using index
+select * from t1 where a = 1 order by b desc;
+a b c
+1 3 b
+1 1 b
+1 1 b
+1 1 NULL
+1 NULL b
+1 NULL NULL
+alter table t1 modify b int not null, modify c varchar(10) not null;
+explain select * from t1 order by a, b, c;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL a 18 NULL 11 Using index
+select * from t1 order by a, b, c;
+a b c
+1 0
+1 0 b
+1 1
+1 1 b
+1 1 b
+1 3 b
+2 1 a
+2 1 b
+2 2 a
+2 2 b
+2 3 c
+explain select * from t1 order by a desc, b desc, c desc;
+table type possible_keys key key_len ref rows Extra
+t1 index NULL a 18 NULL 11 Using index
+select * from t1 order by a desc, b desc, c desc;
+a b c
+2 3 c
+2 2 b
+2 2 a
+2 1 b
+2 1 a
+1 3 b
+1 1 b
+1 1 b
+1 1
+1 0 b
+1 0
+explain select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 18 NULL 3 Using where; Using index
+select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc;
+a b c
+1 1 b
+1 1 b
+explain select * from t1 where a < 2 and b <= 1 order by a desc, b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 4 NULL 6 Using where; Using index
+select * from t1 where a < 2 and b <= 1 order by a desc, b desc;
+a b c
+1 1 b
+1 1 b
+1 1
+1 0 b
+1 0
+select count(*) from t1 where a < 5 and b > 0;
+count(*)
+9
+select * from t1 where a < 5 and b > 0 order by a desc,b desc;
+a b c
+2 3 c
+2 2 b
+2 2 a
+2 1 b
+2 1 a
+1 3 b
+1 1 b
+1 1 b
+1 1
+explain select * from t1 where a between 1 and 3 and b <= 1 order by a desc, b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 8 NULL 10 Using where; Using index
+select * from t1 where a between 1 and 3 and b <= 1 order by a desc, b desc;
+a b c
+2 1 b
+2 1 a
+1 1 b
+1 1 b
+1 1
+1 0 b
+1 0
+explain select * from t1 where a between 0 and 1 order by a desc, b desc;
+table type possible_keys key key_len ref rows Extra
+t1 range a a 4 NULL 5 Using where; Using index
+select * from t1 where a between 0 and 1 order by a desc, b desc;
+a b c
+1 3 b
+1 1 b
+1 1 b
+1 1
+1 0 b
+1 0
+drop table t1;
+CREATE TABLE t1 (
+gid int(10) unsigned NOT NULL auto_increment,
+cid smallint(5) unsigned NOT NULL default '0',
+PRIMARY KEY (gid),
+KEY component_id (cid)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (103853,108),(103867,108),(103962,108),(104505,108),(104619,108),(104620,108);
+ALTER TABLE t1 add skr int(10) not null;
+CREATE TABLE t2 (
+gid int(10) unsigned NOT NULL default '0',
+uid smallint(5) unsigned NOT NULL default '1',
+sid tinyint(3) unsigned NOT NULL default '1',
+PRIMARY KEY (gid),
+KEY uid (uid),
+KEY status_id (sid)
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (103853,250,5),(103867,27,5),(103962,27,5),(104505,117,5),(104619,75,5),(104620,15,5);
+CREATE TABLE t3 (
+uid smallint(6) NOT NULL auto_increment,
+PRIMARY KEY (uid)
+) TYPE=MyISAM;
+INSERT INTO t3 VALUES (1),(15),(27),(75),(117),(250);
+ALTER TABLE t3 add skr int(10) not null;
+select t1.gid, t2.sid, t3.uid from t2, t1, t3 where t2.gid = t1.gid and t2.uid = t3.uid order by t3.uid, t1.gid;
gid sid uid
104620 5 15
103867 5 27
@@ -118,6 +451,7 @@ gid sid uid
104619 5 75
104505 5 117
103853 5 250
+select t1.gid, t2.sid, t3.uid from t3, t2, t1 where t2.gid = t1.gid and t2.uid = t3.uid order by t3.uid, t1.gid;
gid sid uid
104620 5 15
103867 5 27
@@ -125,24 +459,90 @@ gid sid uid
104619 5 75
104505 5 117
103853 5 250
+EXPLAIN select t1.gid, t2.sid, t3.uid from t3, t2, t1 where t2.gid = t1.gid and t2.uid = t3.uid order by t1.gid, t3.uid;
table type possible_keys key key_len ref rows Extra
t1 index PRIMARY PRIMARY 4 NULL 6 Using index
t2 eq_ref PRIMARY,uid PRIMARY 4 t1.gid 1
-t3 eq_ref PRIMARY PRIMARY 2 t2.uid 1 where used; Using index
+t3 eq_ref PRIMARY PRIMARY 2 t2.uid 1 Using where; Using index
+EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.gid = t3.uid order by t1.gid,t3.skr;
table type possible_keys key key_len ref rows Extra
-t1 index PRIMARY PRIMARY 4 NULL 6 Using index
-t3 eq_ref PRIMARY PRIMARY 2 t1.gid 1 where used
+t3 ALL PRIMARY NULL NULL NULL 6 Using temporary; Using filesort
+t1 eq_ref PRIMARY PRIMARY 4 t3.uid 1 Using where; Using index
+EXPLAIN SELECT t1.gid, t2.sid, t3.uid from t2, t1, t3 where t2.gid = t1.gid and t2.uid = t3.uid order by t3.uid, t1.gid;
table type possible_keys key key_len ref rows Extra
t1 index PRIMARY PRIMARY 4 NULL 6 Using index; Using temporary; Using filesort
t2 eq_ref PRIMARY,uid PRIMARY 4 t1.gid 1
-t3 eq_ref PRIMARY PRIMARY 2 t2.uid 1 where used; Using index
+t3 eq_ref PRIMARY PRIMARY 2 t2.uid 1 Using where; Using index
+EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.gid = t3.uid order by t3.skr,t1.gid;
table type possible_keys key key_len ref rows Extra
-t1 index PRIMARY PRIMARY 4 NULL 6 Using index; Using temporary; Using filesort
-t3 eq_ref PRIMARY PRIMARY 2 t1.gid 1 where used
+t3 ALL PRIMARY NULL NULL NULL 6 Using temporary; Using filesort
+t1 eq_ref PRIMARY PRIMARY 4 t3.uid 1 Using where; Using index
+EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.skr = t3.uid order by t1.gid,t3.skr;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
-t3 eq_ref PRIMARY PRIMARY 2 t1.skr 1 where used
-t2_id str
-112633 t2 112633
-112634 t2 112634
-t2_id str
+t3 eq_ref PRIMARY PRIMARY 2 t1.skr 1 Using where
+drop table t1,t2,t3;
+CREATE TABLE t1 (
+`titre` char(80) NOT NULL default '',
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`date` datetime NOT NULL default '0000-00-00 00:00:00',
+`auteur` char(35) NOT NULL default '',
+`icone` tinyint(2) unsigned NOT NULL default '0',
+`lastauteur` char(35) NOT NULL default '',
+`nbrep` smallint(6) unsigned NOT NULL default '0',
+`dest` char(35) NOT NULL default '',
+`lu` tinyint(1) unsigned NOT NULL default '0',
+`vue` mediumint(8) unsigned NOT NULL default '0',
+`ludest` tinyint(1) unsigned NOT NULL default '0',
+`ouvert` tinyint(1) unsigned NOT NULL default '1',
+PRIMARY KEY (`numeropost`),
+KEY `date` (`date`),
+KEY `dest` (`dest`,`ludest`),
+KEY `auteur` (`auteur`,`lu`),
+KEY `auteur_2` (`auteur`,`date`),
+KEY `dest_2` (`dest`,`date`)
+) CHECKSUM=1;
+CREATE TABLE t2 (
+`numeropost` mediumint(8) unsigned NOT NULL default '0',
+`pseudo` char(35) NOT NULL default '',
+PRIMARY KEY (`numeropost`,`pseudo`),
+KEY `pseudo` (`pseudo`)
+);
+INSERT INTO t1 (titre,auteur,dest) VALUES ('test','joce','bug');
+INSERT INTO t2 (numeropost,pseudo) VALUES (1,'joce'),(1,'bug');
+SELECT titre,t1.numeropost,auteur,icone,nbrep,0,date,vue,ouvert,lastauteur,dest FROM t2 LEFT JOIN t1 USING(numeropost) WHERE t2.pseudo='joce' ORDER BY date DESC LIMIT 0,30;
+titre numeropost auteur icone nbrep 0 date vue ouvert lastauteur dest
+test 1 joce 0 0 0 0000-00-00 00:00:00 0 1 bug
+SELECT titre,t1.numeropost,auteur,icone,nbrep,'0',date,vue,ouvert,lastauteur,dest FROM t2 LEFT JOIN t1 USING(numeropost) WHERE t2.pseudo='joce' ORDER BY date DESC LIMIT 0,30;
+titre numeropost auteur icone nbrep 0 date vue ouvert lastauteur dest
+test 1 joce 0 0 0 0000-00-00 00:00:00 0 1 bug
+drop table t1,t2;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (1, 2);
+INSERT INTO t1 VALUES (3, 4);
+INSERT INTO t1 VALUES (5, NULL);
+SELECT * FROM t1 ORDER BY b;
+a b
+5 NULL
+1 2
+3 4
+SELECT * FROM t1 ORDER BY b DESC;
+a b
+3 4
+1 2
+5 NULL
+SELECT * FROM t1 ORDER BY (a + b);
+a b
+5 NULL
+1 2
+3 4
+SELECT * FROM t1 ORDER BY (a + b) DESC;
+a b
+3 4
+1 2
+5 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+SET @id=0;
+UPDATE t1 SET a=0 ORDER BY (a=@id), b;
+DROP TABLE t1;
diff --git a/mysql-test/r/order_fill_sortbuf.result b/mysql-test/r/order_fill_sortbuf.result
new file mode 100644
index 00000000000..2226e842901
--- /dev/null
+++ b/mysql-test/r/order_fill_sortbuf.result
@@ -0,0 +1,10 @@
+drop table if exists t1,t2;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL default '0',
+`id2` int(11) NOT NULL default '0',
+`id3` int(11) NOT NULL default '0');
+create table t2 select id2 from t1 order by id3;
+select count(*) from t2;
+count(*)
+4000
+drop table t1,t2;
diff --git a/mysql-test/r/overflow.result b/mysql-test/r/overflow.result
new file mode 100644
index 00000000000..a5fa7154833
--- /dev/null
+++ b/mysql-test/r/overflow.result
@@ -0,0 +1,2 @@
+drop database AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;
+Got one of the listed errors
diff --git a/mysql-test/r/packet.result b/mysql-test/r/packet.result
new file mode 100644
index 00000000000..6733f2b142e
--- /dev/null
+++ b/mysql-test/r/packet.result
@@ -0,0 +1,25 @@
+set global max_allowed_packet=100;
+set max_allowed_packet=100;
+set global net_buffer_length=100;
+set net_buffer_length=100;
+SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
+len
+1024
+select repeat('a',2000);
+repeat('a',2000)
+NULL
+select @@net_buffer_length, @@max_allowed_packet;
+@@net_buffer_length @@max_allowed_packet
+1024 1024
+SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
+Got a packet bigger than 'max_allowed_packet'
+set global max_allowed_packet=default;
+set max_allowed_packet=default;
+set global net_buffer_length=default;
+set net_buffer_length=default;
+SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
+len
+100
+select length(repeat('a',2000));
+length(repeat('a',2000))
+2000
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
new file mode 100644
index 00000000000..c7554211a1a
--- /dev/null
+++ b/mysql-test/r/query_cache.result
@@ -0,0 +1,690 @@
+set GLOBAL query_cache_size=1355776;
+flush query cache;
+flush query cache;
+reset query cache;
+flush status;
+drop table if exists t1,t2,t3,t4,t11,t21;
+drop database if exists mysqltest;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+select * from t1;
+a
+1
+2
+3
+select sql_no_cache * from t1;
+a
+1
+2
+3
+select length(now()) from t1;
+length(now())
+19
+19
+19
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+show status like "Qcache_inserts";
+Variable_name Value
+Qcache_inserts 1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 1
+drop table t1;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+create table t2 (a int not null);
+insert into t2 values (4),(5),(6);
+create table t3 (a int not null) type=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST;
+select * from t3;
+a
+1
+2
+3
+4
+5
+6
+select * from t3;
+a
+1
+2
+3
+4
+5
+6
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+insert into t2 values (7);
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t1;
+a
+1
+2
+3
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+insert into t3 values (8);
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t3;
+a
+1
+2
+3
+8
+4
+5
+6
+7
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+update t2 set a=9 where a=7;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t1;
+a
+1
+2
+3
+8
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+update t3 set a=10 where a=1;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t3;
+a
+10
+2
+3
+8
+4
+5
+6
+9
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+delete from t2 where a=9;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t1;
+a
+10
+2
+3
+8
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+delete from t3 where a=10;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1, t2, t3;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+create table t2 (a int not null);
+insert into t2 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+select * from t2;
+a
+1
+2
+3
+insert into t1 values (4);
+show status like "Qcache_free_blocks";
+Variable_name Value
+Qcache_free_blocks 2
+flush query cache;
+show status like "Qcache_free_blocks";
+Variable_name Value
+Qcache_free_blocks 1
+drop table t1, t2;
+create table t1 (a text not null);
+create table t11 (a text not null);
+create table t2 (a text not null);
+create table t21 (a text not null);
+create table t3 (a text not null);
+insert into t1 values("1111111111111111111111111111111111111111111111111111");
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t11 select * from t1;
+insert into t21 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t3 select * from t1;
+insert into t3 select * from t2;
+insert into t3 select * from t1;
+select * from t11;
+select * from t21;
+show status like "Qcache_total_blocks";
+Variable_name Value
+Qcache_total_blocks 7
+show status like "Qcache_free_blocks";
+Variable_name Value
+Qcache_free_blocks 1
+insert into t11 values("");
+select * from t3;
+show status like "Qcache_total_blocks";
+Variable_name Value
+Qcache_total_blocks 8
+show status like "Qcache_free_blocks";
+Variable_name Value
+Qcache_free_blocks 1
+flush query cache;
+show status like "Qcache_total_blocks";
+Variable_name Value
+Qcache_total_blocks 7
+show status like "Qcache_free_blocks";
+Variable_name Value
+Qcache_free_blocks 1
+drop table t1, t2, t3, t11, t21;
+set query_cache_type=demand;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select sql_cache * from t1 union select * from t1;
+a
+1
+2
+3
+set query_cache_type=2;
+select sql_cache * from t1 union select * from t1;
+a
+1
+2
+3
+select * from t1 union select sql_cache * from t1;
+a
+1
+2
+3
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 4
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+set query_cache_type=on;
+reset query cache;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select sql_no_cache * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+create table t1 (a text not null);
+select CONNECTION_ID() from t1;
+CONNECTION_ID()
+select FOUND_ROWS();
+FOUND_ROWS()
+0
+select NOW() from t1;
+NOW()
+select CURDATE() from t1;
+CURDATE()
+select CURTIME() from t1;
+CURTIME()
+select DATABASE() from t1;
+DATABASE()
+select ENCRYPT("test") from t1;
+ENCRYPT("test")
+select LAST_INSERT_ID() from t1;
+last_insert_id()
+select RAND() from t1;
+RAND()
+select UNIX_TIMESTAMP() from t1;
+UNIX_TIMESTAMP()
+select USER() from t1;
+USER()
+select benchmark(1,1) from t1;
+benchmark(1,1)
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+create table t2 (a text not null);
+insert into t1 values("1111111111111111111111111111111111111111111111111111");
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 4
+show status like "Qcache_lowmem_prunes";
+Variable_name Value
+Qcache_lowmem_prunes 0
+select a as a1, a as a2 from t1;
+select a as a2, a as a3 from t1;
+select a as a3, a as a4 from t1;
+select a as a1, a as a2 from t1;
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 4
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+show status like "Qcache_lowmem_prunes";
+Variable_name Value
+Qcache_lowmem_prunes 2
+reset query cache;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+select * from t1;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1,t2;
+create database mysqltest;
+create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i));
+insert into mysqltest.t1 (a) values (1);
+select * from mysqltest.t1 where i is null;
+i a
+1 1
+create table t1(a int);
+select * from t1;
+a
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+select * from mysqltest.t1;
+i a
+1 1
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+drop database mysqltest;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+drop table t1;
+create table t1 (a char(1) not null);
+insert into t1 values("á");
+select * from t1;
+a
+set CHARACTER SET cp1251_koi8;
+select * from t1;
+a
+set CHARACTER SET DEFAULT;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 4
+drop table t1;
+create database if not exists mysqltest;
+create table mysqltest.t1 (i int not null);
+create table t1 (i int not null);
+insert into mysqltest.t1 (i) values (1);
+insert into t1 (i) values (2);
+select * from t1;
+i
+2
+use mysqltest;
+select * from t1;
+i
+1
+select * from t1;
+i
+1
+use test;
+select * from t1;
+i
+2
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 6
+drop database mysqltest;
+drop table t1;
+create table t1 (i int not null);
+insert into t1 (i) values (1),(2),(3),(4);
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+i
+1
+2
+select FOUND_ROWS();
+FOUND_ROWS()
+4
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 6
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+select * from t1 where i=1;
+i
+1
+select FOUND_ROWS();
+FOUND_ROWS()
+1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 6
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+i
+1
+2
+select FOUND_ROWS();
+FOUND_ROWS()
+4
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 7
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+select * from t1 where i=1;
+i
+1
+select FOUND_ROWS();
+FOUND_ROWS()
+1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 8
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+drop table t1;
+flush query cache;
+reset query cache;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+a
+1
+2
+3
+select * from t1;
+a
+1
+2
+3
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+insert delayed into t1 values (4);
+select a from t1;
+a
+1
+2
+3
+4
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+drop table t1;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+create table t1 (a int);
+set GLOBAL query_cache_size=1000;
+show global variables like "query_cache_size";
+Variable_name Value
+query_cache_size 0
+select * from t1;
+a
+set GLOBAL query_cache_size=1024;
+show global variables like "query_cache_size";
+Variable_name Value
+query_cache_size 0
+select * from t1;
+a
+set GLOBAL query_cache_size=10240;
+show global variables like "query_cache_size";
+Variable_name Value
+query_cache_size 0
+select * from t1;
+a
+set GLOBAL query_cache_size=20480;
+show global variables like "query_cache_size";
+Variable_name Value
+query_cache_size 0
+select * from t1;
+a
+set GLOBAL query_cache_size=40960;
+show global variables like "query_cache_size";
+Variable_name Value
+query_cache_size 0
+select * from t1;
+a
+set GLOBAL query_cache_size=51200;
+show global variables like "query_cache_size";
+Variable_name Value
+query_cache_size 51200
+select * from t1;
+a
+set GLOBAL query_cache_size=61440;
+show global variables like "query_cache_size";
+Variable_name Value
+query_cache_size 61440
+select * from t1;
+a
+set GLOBAL query_cache_size=81920;
+show global variables like "query_cache_size";
+Variable_name Value
+query_cache_size 81920
+select * from t1;
+a
+set GLOBAL query_cache_size=102400;
+show global variables like "query_cache_size";
+Variable_name Value
+query_cache_size 102400
+select * from t1;
+a
+drop table t1;
+set GLOBAL query_cache_size=1048576;
+create table t1 (i int not null);
+create table t2 (i int not null);
+select * from t1;
+i
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+create temporary table t3 (i int not null);
+select * from t2;
+i
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+select * from t3;
+i
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+drop table t1, t2, t3;
+use mysql;
+select * from db;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+use test;
+select * from mysql.db;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+create table t1(id int auto_increment primary key);
+insert into t1 values (NULL), (NULL), (NULL);
+select * from t1 where id=2;
+id
+2
+alter table t1 rename to t2;
+select * from t1 where id=2;
+Table 'test.t1' doesn't exist
+drop table t2;
+select * from t1 where id=2;
+Table 'test.t1' doesn't exist
+create table t1 (word char(20) not null);
+select * from t1;
+word
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+load data infile '../../std_data/words.dat' into table t1;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+drop table if exists t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t1 into outfile "query_caceh.out.file";
+select * from t1 limit 1 into dumpfile "query_cache.dump.file";
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2);
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select * from t1;
+a
+1
+2
+SET OPTION SQL_SELECT_LIMIT=1;
+select * from t1;
+a
+1
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 2
+SET OPTION SQL_SELECT_LIMIT=DEFAULT;
+drop table t1;
+flush query cache;
+reset query cache;
+flush status;
+set GLOBAL query_cache_size=1048576;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+create table t2 (a text not null);
+create table t3 (a text not null);
+insert into t3 values("1111111111111111111111111111111111111111111111111111");
+insert into t2 select * from t3;
+insert into t3 select * from t2;
+insert into t2 select * from t3;
+insert into t3 select * from t2;
+insert into t2 select * from t3;
+insert into t3 select * from t2;
+insert into t2 select * from t3;
+insert into t3 select * from t2;
+insert into t2 select * from t3;
+insert into t3 select * from t2;
+drop table t2;
+create table t2 (a int not null);
+insert into t2 values (1),(2),(3);
+create table t4 (a int not null);
+insert into t4 values (1),(2),(3);
+select * from t4;
+select * from t2;
+select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
+select * from t2;
+select * from t4;
+select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
+select * from t2;
+select * from t4;
+select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
+delete from t2 where a=1;
+flush query cache;
+select * from t3;
+delete from t4 where a=1;
+flush query cache;
+drop table t1,t2,t3,t4;
+set GLOBAL query_cache_size=0;
diff --git a/mysql-test/r/query_cache_merge.result b/mysql-test/r/query_cache_merge.result
new file mode 100644
index 00000000000..c6df4266de2
--- /dev/null
+++ b/mysql-test/r/query_cache_merge.result
@@ -0,0 +1,20 @@
+SET @@global.query_cache_size=1355776;
+flush status;
+select count(*) from t00;
+count(*)
+514
+select count(*) from t00;
+count(*)
+514
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 1
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 1
+delete from t256;
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t257,t00;
+SET @@global.query_cache_size=0;
diff --git a/mysql-test/r/raid.result b/mysql-test/r/raid.result
index ffda2a6966d..3d27a599cf3 100644
--- a/mysql-test/r/raid.result
+++ b/mysql-test/r/raid.result
@@ -1,8 +1,200 @@
+create database test_raid;
+create table test_raid.r1 (i int) raid_type=1;
+create table test_raid.r2 (i int) raid_type=1 raid_chunks=32;
+drop database test_raid;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (
+id int unsigned not null auto_increment primary key,
+c char(255) not null
+) RAID_TYPE=STRIPED RAID_CHUNKS=2 RAID_CHUNKSIZE=123;
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+select count(*) from t1;
count(*)
450
+ALTER TABLE t1 ADD COLUMN x INT UNSIGNED NOT NULL;
+ALTER TABLE t1 ADD KEY c (c);
+ALTER TABLE t1 DROP KEY c;
+ALTER TABLE t1 DROP COLUMN x;
+ALTER TABLE t1 RENAME t2;
+select count(*) from t2;
count(*)
450
+DROP TABLE t2;
+/* variable rows */
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1 (
+id int unsigned not null auto_increment primary key,
+c varchar(255) not null
+) RAID_TYPE=STRIPED RAID_CHUNKS=5 RAID_CHUNKSIZE=121;
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+INSERT INTO t1 VALUES
+(NULL,'1'),(NULL,'a'),(NULL,'a'),(NULL,'a'),(NULL,'p'),(NULL,'a'),
+(NULL,'2'),(NULL,'b'),(NULL,'a'),(NULL,'a'),(NULL,'q'),(NULL,'a'),
+(NULL,'3'),(NULL,'c'),(NULL,'a'),(NULL,'a'),(NULL,'r'),(NULL,'a'),
+(NULL,'4'),(NULL,'d'),(NULL,'a'),(NULL,'a'),(NULL,'s'),(NULL,'a'),
+(NULL,'5'),(NULL,'e'),(NULL,'a'),(NULL,'a'),(NULL,'t'),(NULL,'a'),
+(NULL,'6'),(NULL,'f'),(NULL,'a'),(NULL,'a'),(NULL,'u'),(NULL,'a'),
+(NULL,'7'),(NULL,'g'),(NULL,'a'),(NULL,'a'),(NULL,'v'),(NULL,'a'),
+(NULL,'8'),(NULL,'h'),(NULL,'a'),(NULL,'a'),(NULL,'w'),(NULL,'a'),
+(NULL,'9'),(NULL,'i'),(NULL,'a'),(NULL,'a'),(NULL,'x'),(NULL,'a'),
+(NULL,'0'),(NULL,'j'),(NULL,'a'),(NULL,'a'),(NULL,'y'),(NULL,'a'),
+(NULL,'1'),(NULL,'k'),(NULL,'a'),(NULL,'a'),(NULL,'z'),(NULL,'a'),
+(NULL,'2'),(NULL,'l'),(NULL,'a'),(NULL,'a'),(NULL,'/'),(NULL,'a'),
+(NULL,'3'),(NULL,'m'),(NULL,'a'),(NULL,'a'),(NULL,'*'),(NULL,'a'),
+(NULL,'4'),(NULL,'n'),(NULL,'a'),(NULL,'a'),(NULL,'+'),(NULL,'a'),
+(NULL,'5'),(NULL,'o'),(NULL,'a'),(NULL,'a'),(NULL,'?'),(NULL,'a');
+select count(*) from t1;
count(*)
450
+ALTER TABLE t1 ADD COLUMN x INT UNSIGNED NOT NULL;
+ALTER TABLE t1 ADD KEY c (c);
+ALTER TABLE t1 DROP KEY c;
+ALTER TABLE t1 DROP COLUMN x;
+ALTER TABLE t1 RENAME t2;
+ALTER TABLE t2 CHANGE COLUMN c c VARCHAR(251) NOT NULL;
+select count(*) from t2;
count(*)
450
+DROP TABLE t2;
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 1a45c252b7c..ccfdbd62a42 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1,3 +1,29 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+event_date date DEFAULT '0000-00-00' NOT NULL,
+type int(11) DEFAULT '0' NOT NULL,
+event_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (event_date,type,event_id)
+);
+INSERT INTO t1 VALUES ('1999-07-10',100100,24), ('1999-07-11',100100,25),
+('1999-07-13',100600,0), ('1999-07-13',100600,4), ('1999-07-13',100600,26),
+('1999-07-14',100600,10), ('1999-07-15',100600,16), ('1999-07-15',100800,45),
+('1999-07-15',101000,47), ('1999-07-16',100800,46), ('1999-07-20',100600,5),
+('1999-07-20',100600,27), ('1999-07-21',100600,11), ('1999-07-22',100600,17),
+('1999-07-23',100100,39), ('1999-07-24',100100,39), ('1999-07-24',100500,40),
+('1999-07-25',100100,39), ('1999-07-27',100600,1), ('1999-07-27',100600,6),
+('1999-07-27',100600,28), ('1999-07-28',100600,12), ('1999-07-29',100500,41),
+('1999-07-29',100600,18), ('1999-07-30',100500,41), ('1999-07-31',100500,41),
+('1999-08-01',100700,34), ('1999-08-03',100600,7), ('1999-08-03',100600,29),
+('1999-08-04',100600,13), ('1999-08-05',100500,42), ('1999-08-05',100600,19),
+('1999-08-06',100500,42), ('1999-08-07',100500,42), ('1999-08-08',100500,42),
+('1999-08-10',100600,2), ('1999-08-10',100600,9), ('1999-08-10',100600,30),
+('1999-08-11',100600,14), ('1999-08-12',100600,20), ('1999-08-17',100500,8),
+('1999-08-17',100600,31), ('1999-08-18',100600,15), ('1999-08-19',100600,22),
+('1999-08-24',100600,3), ('1999-08-24',100600,32), ('1999-08-27',100500,43),
+('1999-08-31',100600,33), ('1999-09-17',100100,37), ('1999-09-18',100100,37),
+('1999-09-19',100100,37), ('2000-12-18',100700,38);
+select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
event_date type event_id
1999-07-10 100100 24
1999-07-11 100100 25
@@ -5,8 +31,10 @@ event_date type event_id
1999-07-13 100600 4
1999-07-13 100600 26
1999-07-14 100600 10
+explain select event_date,type,event_id from t1 WHERE type = 100601 and event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
Comment
Impossible WHERE
+select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date <= "1999-07-15" AND (type=100600 OR type=100100) or event_date >= "1999-07-01" AND event_date <= "1999-07-15" AND type=100099;
event_date type event_id
1999-07-10 100100 24
1999-07-11 100100 25
@@ -15,6 +43,31 @@ event_date type event_id
1999-07-13 100600 26
1999-07-14 100600 10
1999-07-15 100600 16
+drop table t1;
+CREATE TABLE t1 (
+PAPER_ID smallint(6) DEFAULT '0' NOT NULL,
+YEAR smallint(6) DEFAULT '0' NOT NULL,
+ISSUE smallint(6) DEFAULT '0' NOT NULL,
+CLOSED tinyint(4) DEFAULT '0' NOT NULL,
+ISS_DATE date DEFAULT '0000-00-00' NOT NULL,
+PRIMARY KEY (PAPER_ID,YEAR,ISSUE)
+);
+INSERT INTO t1 VALUES (3,1999,34,0,'1999-07-12'), (1,1999,111,0,'1999-03-23'),
+(1,1999,222,0,'1999-03-23'), (3,1999,33,0,'1999-07-12'),
+(3,1999,32,0,'1999-07-12'), (3,1999,31,0,'1999-07-12'),
+(3,1999,30,0,'1999-07-12'), (3,1999,29,0,'1999-07-12'),
+(3,1999,28,0,'1999-07-12'), (1,1999,40,1,'1999-05-01'),
+(1,1999,41,1,'1999-05-01'), (1,1999,42,1,'1999-05-01'),
+(1,1999,46,1,'1999-05-01'), (1,1999,47,1,'1999-05-01'),
+(1,1999,48,1,'1999-05-01'), (1,1999,49,1,'1999-05-01'),
+(1,1999,50,0,'1999-05-01'), (1,1999,51,0,'1999-05-01'),
+(1,1999,200,0,'1999-06-28'), (1,1999,52,0,'1999-06-28'),
+(1,1999,53,0,'1999-06-28'), (1,1999,54,0,'1999-06-28'),
+(1,1999,55,0,'1999-06-28'), (1,1999,56,0,'1999-07-01'),
+(1,1999,57,0,'1999-07-01'), (1,1999,58,0,'1999-07-01'),
+(1,1999,59,0,'1999-07-01'), (1,1999,60,0,'1999-07-01'),
+(3,1999,35,0,'1999-07-12');
+select YEAR,ISSUE from t1 where PAPER_ID=3 and (YEAR>1999 or (YEAR=1999 and ISSUE>28)) order by YEAR,ISSUE;
YEAR ISSUE
1999 29
1999 30
@@ -23,10 +76,28 @@ YEAR ISSUE
1999 33
1999 34
1999 35
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+repair table t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+);
+INSERT INTO t1 VALUES (1,0,0), (3,1,1), (4,1,1), (8,2,2), (9,2,2), (17,3,2),
+(22,4,2), (24,4,2), (28,5,2), (29,5,2), (30,5,2), (31,6,2), (32,6,2), (33,6,2),
+(203,7,2), (202,7,2), (20,3,2), (157,0,0), (193,5,2), (40,7,2), (2,1,1),
+(15,2,2), (6,1,1), (34,6,2), (35,6,2), (16,3,2), (7,1,1), (36,7,2), (18,3,2),
+(26,5,2), (27,5,2), (183,4,2), (38,7,2), (25,5,2), (37,7,2), (21,4,2),
+(19,3,2), (5,1,1), (179,5,2);
+SELECT * FROM t1 WHERE level = 1 AND parent_id = 1;
id parent_id level
3 1 1
4 1 1
@@ -34,6 +105,7 @@ id parent_id level
6 1 1
7 1 1
5 1 1
+SELECT * FROM t1 WHERE level = 1 AND parent_id = 1 order by id;
id parent_id level
2 1 1
3 1 1
@@ -41,27 +113,203 @@ id parent_id level
5 1 1
6 1 1
7 1 1
+drop table t1;
+create table t1(
+Satellite varchar(25) not null,
+SensorMode varchar(25) not null,
+FullImageCornersUpperLeftLongitude double not null,
+FullImageCornersUpperRightLongitude double not null,
+FullImageCornersUpperRightLatitude double not null,
+FullImageCornersLowerRightLatitude double not null,
+index two (Satellite, SensorMode, FullImageCornersUpperLeftLongitude, FullImageCornersUpperRightLongitude, FullImageCornersUpperRightLatitude, FullImageCornersLowerRightLatitude));
+insert into t1 values("OV-3","PAN1",91,-92,40,50);
+insert into t1 values("OV-4","PAN1",91,-92,40,50);
+select * from t1 where t1.Satellite = "OV-3" and t1.SensorMode = "PAN1" and t1.FullImageCornersUpperLeftLongitude > -90.000000 and t1.FullImageCornersUpperRightLongitude < -82.000000;
Satellite SensorMode FullImageCornersUpperLeftLongitude FullImageCornersUpperRightLongitude FullImageCornersUpperRightLatitude FullImageCornersLowerRightLatitude
OV-3 PAN1 91 -92 40 50
+drop table t1;
+create table t1 ( aString char(100) not null default "", key aString (aString(10)) );
+insert t1 (aString) values ( "believe in myself" ), ( "believe" ), ("baaa" ), ( "believe in love");
+select * from t1 where aString < "believe in myself" order by aString;
aString
baaa
believe
believe in love
+select * from t1 where aString > "believe in love" order by aString;
aString
believe in myself
+alter table t1 drop key aString;
+select * from t1 where aString < "believe in myself" order by aString;
aString
baaa
believe
believe in love
+select * from t1 where aString > "believe in love" order by aString;
aString
believe in myself
+drop table t1;
+CREATE TABLE t1 (
+t1ID int(10) unsigned NOT NULL auto_increment,
+art char(1) binary NOT NULL default '',
+KNR char(5) NOT NULL default '',
+RECHNR char(6) NOT NULL default '',
+POSNR char(2) NOT NULL default '',
+ARTNR char(10) NOT NULL default '',
+TEX char(70) NOT NULL default '',
+PRIMARY KEY (t1ID),
+KEY IdxArt (art),
+KEY IdxKnr (KNR),
+KEY IdxArtnr (ARTNR)
+) TYPE=MyISAM;
+INSERT INTO t1 (art) VALUES ('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j');
+select count(*) from t1 where upper(art) = 'J';
count(*)
602
+select count(*) from t1 where art = 'J' or art = 'j';
count(*)
602
+select count(*) from t1 where art = 'j' or art = 'J';
count(*)
602
+select count(*) from t1 where art = 'j';
count(*)
389
+select count(*) from t1 where art = 'J';
count(*)
213
+drop table t1;
+create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
+insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
+(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
+(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
+(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
+(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
+(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
+(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
+select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
+id1 idnull
+drop table t1;
+create table t1 (x int, y int, index(x), index(y));
+insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
+update t1 set y=x;
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 7 and t1.y+0;
+table type possible_keys key key_len ref rows Extra
+t1 ref y y 5 const 1 Using where
+t2 range x x 5 NULL 4 Using where
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 7 and t2.x <= t1.y+0;
+table type possible_keys key key_len ref rows Extra
+t1 ref y y 5 const 1 Using where
+t2 range x x 5 NULL 4 Using where
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
+table type possible_keys key key_len ref rows Extra
+t1 ref y y 5 const 1 Using where
+t2 ALL x NULL NULL NULL 9 Range checked for each record (index map: 1)
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
+table type possible_keys key key_len ref rows Extra
+t1 ref y y 5 const 1 Using where
+t2 ALL x NULL NULL NULL 9 Range checked for each record (index map: 1)
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
+table type possible_keys key key_len ref rows Extra
+t1 ref y y 5 const 1 Using where
+t2 ALL x NULL NULL NULL 9 Using where
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
+table type possible_keys key key_len ref rows Extra
+t1 ref y y 5 const 1 Using where
+t2 range x x 5 NULL 2 Using where
+explain select count(*) from t1 where x in (1);
+table type possible_keys key key_len ref rows Extra
+t1 range x x 5 NULL 1 Using where; Using index
+explain select count(*) from t1 where x in (1,2);
+table type possible_keys key key_len ref rows Extra
+t1 range x x 5 NULL 2 Using where; Using index
+drop table t1;
+CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1), KEY i2 (key1));
+INSERT INTO t1 VALUES (0),(0),(1),(1);
+CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya));
+INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2);
+explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
+table type possible_keys key key_len ref rows Extra
+t2 ref j1 j1 4 const 1 Using where; Using index
+t1 ALL i1,i2 NULL NULL NULL 4 Range checked for each record (index map: 3)
+explain select * from t1 force index(i2), t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
+table type possible_keys key key_len ref rows Extra
+t2 ref j1 j1 4 const 1 Using where; Using index
+t1 ALL i2 NULL NULL NULL 4 Range checked for each record (index map: 2)
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+a int(11) default NULL,
+b int(11) default NULL,
+KEY a (a),
+KEY b (b)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES
+(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(10,2),
+(13,2),(14,2),(15,2),(16,2),(17,3),(17,3),(16,3),(17,3),(19,3),(20,3),
+(21,4),(22,5),(23,5),(24,5),(25,5),(26,5),(30,5),(31,5),(32,5),(33,5),
+(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
+EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
+table type possible_keys key key_len ref rows Extra
+t1 range a,b a 5 NULL 2 Using where
+SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
+a b
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int, c int, INDEX (c,a,b));
+INSERT INTO t1 VALUES (1,0,0),(1,0,0),(1,0,0);
+INSERT INTO t1 VALUES (0,1,0),(0,1,0),(0,1,0);
+SELECT COUNT(*) FROM t1 WHERE (c=0 and a=1) or (c=0 and b=1);
+COUNT(*)
+6
+SELECT COUNT(*) FROM t1 WHERE (c=0 and b=1) or (c=0 and a=1);
+COUNT(*)
+6
+DROP TABLE t1;
+CREATE TABLE t1 ( a int not null, b int not null, INDEX ab(a,b) );
+INSERT INTO t1 VALUES (47,1), (70,1), (15,1), (15, 4);
+SELECT * FROM t1
+WHERE
+(
+( b =1 AND a BETWEEN 14 AND 21 ) OR
+( b =2 AND a BETWEEN 16 AND 18 ) OR
+( b =3 AND a BETWEEN 15 AND 19 ) OR
+(a BETWEEN 19 AND 47)
+);
+a b
+15 1
+47 1
diff --git a/mysql-test/r/rename.result b/mysql-test/r/rename.result
index 57ef20e41b1..b2bb659502a 100644
--- a/mysql-test/r/rename.result
+++ b/mysql-test/r/rename.result
@@ -1,14 +1,39 @@
+drop table if exists t0,t1,t2,t3,t4;
+create table t0 SELECT 1,"table 1";
+create table t2 SELECT 2,"table 2";
+create table t3 SELECT 3,"table 3";
+rename table t0 to t1;
+rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
+select * from t1;
3 table 3
3 table 3
+rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
+rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
+select * from t1;
1 table 1
1 table 1
+rename table t1 to t2;
+Got one of the listed errors
+rename table t1 to t1;
+Got one of the listed errors
+rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2;
+Got one of the listed errors
+show tables like "t_";
Tables_in_test (t_)
t1
t2
t3
+rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1;
+Got one of the listed errors
+rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1;
+Got one of the listed errors
+select * from t1;
1 table 1
1 table 1
+select * from t2;
2 table 2
2 table 2
+select * from t3;
3 table 3
3 table 3
+drop table if exists t1,t2,t3,t4;
diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result
new file mode 100644
index 00000000000..6c2107b2cf3
--- /dev/null
+++ b/mysql-test/r/repair.result
@@ -0,0 +1,15 @@
+drop table if exists t1;
+create table t1 SELECT 1,"table 1";
+repair table t1 use_frm;
+Table Op Msg_type Msg_text
+test.t1 repair warning Number of rows changed from 0 to 1
+test.t1 repair status OK
+alter table t1 TYPE=HEAP;
+repair table t1 use_frm;
+Table Op Msg_type Msg_text
+test.t1 repair error The handler for the table doesn't support repair
+drop table t1;
+repair table t1 use_frm;
+Table Op Msg_type Msg_text
+test.t1 repair error Table 'test.t1' doesn't exist
+create table t1 type=myisam SELECT 1,"table 1";
diff --git a/mysql-test/r/repair_part2.result b/mysql-test/r/repair_part2.result
new file mode 100644
index 00000000000..77aa98c3da9
--- /dev/null
+++ b/mysql-test/r/repair_part2.result
@@ -0,0 +1,8 @@
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair error Can't open file: 't1.MYI'. (errno: 130)
+repair table t1 use_frm;
+Table Op Msg_type Msg_text
+test.t1 repair warning Number of rows changed from 0 to 1
+test.t1 repair status OK
+drop table t1;
diff --git a/mysql-test/r/replace.result b/mysql-test/r/replace.result
index 25a6a17da35..0aa80e18ccc 100644
--- a/mysql-test/r/replace.result
+++ b/mysql-test/r/replace.result
@@ -1,3 +1,26 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+gesuchnr int(11) DEFAULT '0' NOT NULL,
+benutzer_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (gesuchnr,benutzer_id)
+) type=ISAM;
+replace into t1 (gesuchnr,benutzer_id) values (2,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+alter table t1 type=myisam;
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+alter table t1 type=heap;
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+drop table t1;
+create table t1 (a tinyint not null auto_increment primary key, b char(20));
+insert into t1 values (126,"first"),(0,"last");
+insert into t1 values (0,"error");
+Duplicate entry '127' for key 1
+replace into t1 values (0,"error");
+Duplicate entry '127' for key 1
+replace into t1 values (126,"first updated");
+select * from t1;
a b
126 first updated
127 last
+drop table t1;
diff --git a/mysql-test/r/rollback.result b/mysql-test/r/rollback.result
index ac3743e1dc7..a5eb6f8729f 100644
--- a/mysql-test/r/rollback.result
+++ b/mysql-test/r/rollback.result
@@ -1,3 +1,12 @@
+drop table if exists t1;
+create table t1 (n int not null primary key) type=myisam;
+begin work;
+insert into t1 values (4);
+insert into t1 values (5);
+rollback;
+Warning: Some non-transactional changed tables couldn't be rolled back
+select * from t1;
n
4
5
+drop table t1;
diff --git a/mysql-test/r/rpl000001.result b/mysql-test/r/rpl000001.result
index ebccb1e1e6b..f3b52b43b19 100644
--- a/mysql-test/r/rpl000001.result
+++ b/mysql-test/r/rpl000001.result
@@ -1,17 +1,83 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1,t2,t3;
+create table t1 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t1;
+load data local infile 'MYSQL_TEST_DIR/std_data/words.dat' into table t1;
+select * from t1 limit 10;
+word
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+slave stop;
+set password for root@"localhost" = password('foo');
+slave start;
+set password for root@"localhost" = password('');
+create table t3(n int);
+insert into t3 values(1),(2);
+select * from t3;
n
1
2
+select sum(length(word)) from t1;
sum(length(word))
-71
+1022
+drop table t1,t3;
+reset master;
+slave stop;
+reset slave;
+create table t1(n int);
+select get_lock("hold_slave",10);
+get_lock("hold_slave",10)
+1
+slave start;
+select release_lock("hold_slave");
+release_lock("hold_slave")
+1
+unlock tables;
+create table t2(id int);
+insert into t2 values(connection_id());
+create temporary table t3(n int);
+insert into t3 select get_lock('crash_lock%20C', 1) from t2;
+ update t1 set n = n + get_lock('crash_lock%20C', 2);
+select (@id := id) - id from t2;
(@id := id) - id
0
+kill @id;
+drop table t2;
+Server shutdown in progress
+set global sql_slave_skip_counter=1;
+slave start;
+select count(*) from t1;
count(*)
-10
+5000
+drop table t1;
+create table t1 (n int);
+insert into t1 values(3456);
+insert into mysql.user (Host, User, Password)
+VALUES ("10.10.10.%", "blafasel2", password("blafasel2"));
+select select_priv,user from mysql.user where user = 'blafasel2';
select_priv user
N blafasel2
+update mysql.user set Select_priv = "Y" where User="blafasel2";
+select select_priv,user from mysql.user where user = 'blafasel2';
select_priv user
Y blafasel2
+select n from t1;
n
3456
+select select_priv,user from mysql.user where user = 'blafasel2';
select_priv user
Y blafasel2
+drop table t1;
diff --git a/mysql-test/r/rpl000002.result b/mysql-test/r/rpl000002.result
index a68ef517708..4c2b3bdfde6 100644
--- a/mysql-test/r/rpl000002.result
+++ b/mysql-test/r/rpl000002.result
@@ -1,8 +1,32 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+create table t1 (n int auto_increment primary key);
+set insert_id = 2000;
+insert into t1 values (NULL),(NULL),(NULL);
+select * from t1;
n
2000
2001
2002
+show slave hosts;
+Server_id Host Port Rpl_recovery_rank Master_id
+2 127.0.0.1 9999 2 1
+drop table t1;
+slave stop;
+drop table if exists t2;
+create table t2(id int auto_increment primary key, created datetime);
+set timestamp=12345;
+insert into t2 set created=now();
+select * from t2;
id created
1 1970-01-01 06:25:45
+slave start;
+select * from t2;
id created
1 1970-01-01 06:25:45
+drop table t2;
diff --git a/mysql-test/r/rpl000003.result b/mysql-test/r/rpl000003.result
index f85b057eefa..b123b3d98c5 100644
--- a/mysql-test/r/rpl000003.result
+++ b/mysql-test/r/rpl000003.result
@@ -1,4 +1,17 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+create table t1(n int primary key);
+insert into t1 values (1),(2),(2);
+Duplicate entry '2' for key 1
+insert into t1 values (3);
+select * from t1;
n
1
2
3
+drop table t1;
diff --git a/mysql-test/r/rpl000004.result b/mysql-test/r/rpl000004.result
index a1c135a142e..3142adc50d6 100644
--- a/mysql-test/r/rpl000004.result
+++ b/mysql-test/r/rpl000004.result
@@ -1,6 +1,33 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+set SQL_LOG_BIN=0;
+drop table if exists t1;
+create table t1 (word char(20) not null, index(word));
+load data infile '../../std_data/words.dat' into table t1;
+drop table if exists t2;
+create table t2 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t2;
+create table t3 (word char(20) not null primary key);
+drop table if exists t1;
+load table t1 from master;
+drop table if exists t2;
+load table t2 from master;
+drop table if exists t3;
+load table t3 from master;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+select count(*) from t2;
count(*)
-10
+70
+select count(*) from t3;
count(*)
0
+set SQL_LOG_BIN=1;
+drop table if exists t1,t2,t3;
+create table t1(n int);
+drop table t1;
diff --git a/mysql-test/r/rpl000005.result b/mysql-test/r/rpl000005.result
index 4f1541c75ca..3e9028bf2cf 100644
--- a/mysql-test/r/rpl000005.result
+++ b/mysql-test/r/rpl000005.result
@@ -1,8 +1,23 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+CREATE TABLE t1 (name varchar(64), age smallint(3));
+INSERT INTO t1 SET name='Andy', age=31;
+INSERT t1 SET name='Jacob', age=2;
+INSERT into t1 SET name='Caleb', age=1;
+ALTER TABLE t1 ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY;
+select * from t1;
name age id
Andy 31 00000001
Jacob 2 00000002
Caleb 1 00000003
+select * from t1;
name age id
Andy 31 00000001
Jacob 2 00000002
Caleb 1 00000003
+drop table t1;
diff --git a/mysql-test/r/rpl000006.result b/mysql-test/r/rpl000006.result
index 56cd7166510..e7fc5151ac4 100644
--- a/mysql-test/r/rpl000006.result
+++ b/mysql-test/r/rpl000006.result
@@ -1,6 +1,31 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+set SQL_LOG_BIN=0,timestamp=200006;
+drop table if exists t1;
+create table t1(t timestamp not null,a char(1));
+insert into t1 ( a) values ('F');
+select unix_timestamp(t) from t1;
unix_timestamp(t)
200006
+drop table if exists t1;
+load table t1 from master;
+select unix_timestamp(t) from t1;
unix_timestamp(t)
200006
+set SQL_LOG_BIN=1,timestamp=default;
+drop table t1;
+set SQL_LOG_BIN=0;
+CREATE TABLE t1 (
+a int not null
+) TYPE=MyISAM MAX_ROWS=4000 CHECKSUM=1;
+INSERT INTO t1 VALUES (1);
+load table t1 from master;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+drop table t1;
diff --git a/mysql-test/r/rpl000007.result b/mysql-test/r/rpl000007.result
deleted file mode 100644
index d5b4cdf3bee..00000000000
--- a/mysql-test/r/rpl000007.result
+++ /dev/null
@@ -1,2 +0,0 @@
-n m
-4 15
diff --git a/mysql-test/r/rpl000008.result b/mysql-test/r/rpl000008.result
index 870e8a5510d..a0230d55702 100644
--- a/mysql-test/r/rpl000008.result
+++ b/mysql-test/r/rpl000008.result
@@ -1,2 +1,25 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+use test;
+drop table if exists foo;
+create table foo (n int);
+insert into foo values(4);
+use test;
+drop table if exists foo;
+create table foo (n int);
+insert into foo values(5);
+drop table if exists bar;
+create table bar (m int);
+insert into bar values(15);
+drop table if exists choo;
+create table choo (k int);
+insert into choo values(55);
+select foo.n,bar.m,choo.k from foo,bar,choo;
n m k
4 15 55
+drop table if exists foo,bar,choo;
+drop table if exists foo,bar,choo;
diff --git a/mysql-test/r/rpl000009.result b/mysql-test/r/rpl000009.result
index d5b4cdf3bee..569dd301143 100644
--- a/mysql-test/r/rpl000009.result
+++ b/mysql-test/r/rpl000009.result
@@ -1,2 +1,121 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop database if exists foo;
+create database foo;
+drop database if exists bar;
+create database bar;
+create database foo;
+drop table if exists foo.foo;
+create table foo.foo (n int);
+insert into foo.foo values(4);
+drop table if exists foo.foo;
+create table foo.foo (n int);
+insert into foo.foo values(5);
+drop table if exists bar.bar;
+create table bar.bar (m int);
+insert into bar.bar values(15);
+select foo.foo.n,bar.bar.m from foo.foo,bar.bar;
n m
4 15
+drop database bar;
+drop database if exists foo;
+drop database bar;
+Can't drop database 'bar'. Database doesn't exist
+drop database foo;
+set sql_log_bin = 0;
+create database foo;
+create database bar;
+show databases;
+Database
+bar
+foo
+mysql
+test
+create table foo.t1(n int, s char(20));
+create table foo.t2(n int, s text);
+insert into foo.t1 values (1, 'one'), (2, 'two'), (3, 'three');
+insert into foo.t2 values (11, 'eleven'), (12, 'twelve'), (13, 'thirteen');
+create table bar.t1(n int, s char(20));
+create table bar.t2(n int, s text);
+insert into bar.t1 values (1, 'one bar'), (2, 'two bar'), (3, 'three bar');
+insert into bar.t2 values (11, 'eleven bar'), (12, 'twelve bar'),
+(13, 'thirteen bar');
+set sql_log_bin = 1;
+show databases;
+Database
+mysql
+test
+create database foo;
+create table foo.t1(n int, s char(20));
+insert into foo.t1 values (1, 'original foo.t1');
+create table foo.t3(n int, s char(20));
+insert into foo.t3 values (1, 'original foo.t3');
+create database foo2;
+create table foo2.t1(n int, s char(20));
+insert into foo2.t1 values (1, 'original foo2.t1');
+create database bar;
+create table bar.t1(n int, s char(20));
+insert into bar.t1 values (1, 'original bar.t1');
+create table bar.t3(n int, s char(20));
+insert into bar.t3 values (1, 'original bar.t3');
+load data from master;
+show databases;
+Database
+bar
+foo
+foo2
+mysql
+test
+use foo;
+show tables;
+Tables_in_foo
+t1
+t3
+select * from t1;
+n s
+1 original foo.t1
+use foo2;
+show tables;
+Tables_in_foo2
+t1
+select * from t1;
+n s
+1 original foo2.t1
+use bar;
+show tables;
+Tables_in_bar
+t1
+t2
+t3
+select * from bar.t1;
+n s
+1 one bar
+2 two bar
+3 three bar
+select * from bar.t2;
+n s
+11 eleven bar
+12 twelve bar
+13 thirteen bar
+select * from bar.t3;
+n s
+1 original bar.t3
+insert into bar.t1 values (4, 'four bar');
+select * from bar.t1;
+n s
+1 one bar
+2 two bar
+3 three bar
+4 four bar
+load table bar.t1 from master;
+Table 't1' already exists
+drop table bar.t1;
+load table bar.t1 from master;
+drop database bar;
+drop database foo;
+drop database foo;
+drop database foo2;
diff --git a/mysql-test/r/rpl000010.result b/mysql-test/r/rpl000010.result
index c52b83d729a..49538ed148e 100644
--- a/mysql-test/r/rpl000010.result
+++ b/mysql-test/r/rpl000010.result
@@ -1,3 +1,16 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+drop table if exists t1;
+create table t1 (n int not null auto_increment primary key);
+insert into t1 values(NULL);
+insert into t1 values(2);
+select n from t1;
n
1
2
+drop table t1;
diff --git a/mysql-test/r/rpl000011.result b/mysql-test/r/rpl000011.result
index c52b83d729a..5d22c29bdba 100644
--- a/mysql-test/r/rpl000011.result
+++ b/mysql-test/r/rpl000011.result
@@ -1,3 +1,17 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+create table t1 (n int);
+insert into t1 values(1);
+slave stop;
+slave start;
+insert into t1 values(2);
+select * from t1;
n
1
2
+drop table t1;
diff --git a/mysql-test/r/rpl000012.result b/mysql-test/r/rpl000012.result
index 9ce7037101e..45de6502bbd 100644
--- a/mysql-test/r/rpl000012.result
+++ b/mysql-test/r/rpl000012.result
@@ -1,3 +1,27 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1,t2,t3;
+create table t2 (n int);
+create temporary table t1 (n int);
+insert into t1 values(1),(2),(3);
+insert into t2 select * from t1;
+drop table if exists test.t3;
+create temporary table test.t3 (n int not null);
+alter table test.t3 add primary key(n);
+flush logs;
+insert into t3 values (100);
+insert into t2 select * from t3;
+drop table if exists test.t3;
+insert into t2 values (101);
+create temporary table t1 (n int);
+insert into t1 values (4),(5);
+insert into t2 select * from t1;
+insert into t2 values(6);
+select * from t2;
n
1
2
@@ -7,5 +31,7 @@ n
4
5
6
+show status like 'Slave_open_temp_tables';
Variable_name Value
Slave_open_temp_tables 0
+drop table if exists t1,t2;
diff --git a/mysql-test/r/rpl000013.result b/mysql-test/r/rpl000013.result
index ec2bd0684f1..9e802da59c5 100644
--- a/mysql-test/r/rpl000013.result
+++ b/mysql-test/r/rpl000013.result
@@ -1,3 +1,19 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t2;
+create table t2(n int);
+create temporary table t1 (n int);
+insert into t1 values(1),(2),(3);
+insert into t2 select * from t1;
+create temporary table t1 (n int);
+insert into t1 values (4),(5);
+insert into t2 select * from t1 as t10;
+insert into t2 values(6);
+select * from t2;
n
1
2
@@ -5,5 +21,7 @@ n
4
5
6
+show status like 'Slave_open_temp_tables';
Variable_name Value
Slave_open_temp_tables 0
+drop table if exists t1,t2;
diff --git a/mysql-test/r/rpl000014.result b/mysql-test/r/rpl000014.result
deleted file mode 100644
index a47c3c91c1d..00000000000
--- a/mysql-test/r/rpl000014.result
+++ /dev/null
@@ -1,16 +0,0 @@
-File Position Binlog_do_db Binlog_ignore_db
-master-bin.001 73
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 1 master-bin.001 73 Yes 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 1 master-bin.001 73 No 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 1 master-bin.001 73 Yes 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 1 master-bin.001 173 Yes 0 0
-File Position Binlog_do_db Binlog_ignore_db
-master-bin.001 73
-n
-1
-2
-3
diff --git a/mysql-test/r/rpl000015.result b/mysql-test/r/rpl000015.result
index 58487af27f8..7010349e5ff 100644
--- a/mysql-test/r/rpl000015.result
+++ b/mysql-test/r/rpl000015.result
@@ -1,14 +1,29 @@
+reset master;
+show master status;
File Position Binlog_do_db Binlog_ignore_db
-master-bin.001 73
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
- 0 0 0 No 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 test 9998 60 4 No 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 60 4 No 0 0
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 60 master-bin.001 73 Yes 0 0
+master-bin.001 79
+reset slave;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+change master to master_host='127.0.0.1';
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 test MASTER_PORT 7 4 slave-relay-bin.001 4 No No 0 0 0 4
+change master to master_host='127.0.0.1',master_user='root',
+master_password='',master_port=MASTER_PORT;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 7 4 slave-relay-bin.001 4 No No 0 0 0 4
+slave start;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 7 master-bin.001 79 slave-relay-bin.001 120 master-bin.001 Yes Yes 0 0 79 120
+drop table if exists t1;
+create table t1 (n int);
+insert into t1 values (10),(45),(90);
+select * from t1;
n
10
45
90
+drop table t1;
diff --git a/mysql-test/r/rpl000017.result b/mysql-test/r/rpl000017.result
index e4f324047f8..bac0573165d 100644
--- a/mysql-test/r/rpl000017.result
+++ b/mysql-test/r/rpl000017.result
@@ -1,2 +1,11 @@
+reset master;
+grant replication slave on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
+grant replication slave on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
+slave start;
+drop table if exists t1;
+create table t1(n int);
+insert into t1 values(24);
+select * from t1;
n
24
+drop table t1;
diff --git a/mysql-test/r/rpl000018.result b/mysql-test/r/rpl000018.result
index 7c89c2ef2b2..282c1e492a1 100644
--- a/mysql-test/r/rpl000018.result
+++ b/mysql-test/r/rpl000018.result
@@ -1,5 +1,14 @@
+reset master;
+reset slave;
+slave start;
+show master logs;
Log_name
master-bin.001
master-bin.002
+drop table if exists t1;
+create table t1(n int);
+insert into t1 values (3351);
+select * from t1;
n
3351
+drop table t1;
diff --git a/mysql-test/r/rpl_EE_error.result b/mysql-test/r/rpl_EE_error.result
new file mode 100644
index 00000000000..a5043250df6
--- /dev/null
+++ b/mysql-test/r/rpl_EE_error.result
@@ -0,0 +1,16 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+create table t1 (a int) type=myisam;
+flush tables;
+drop table t1;
+create table t1 (a int, unique(a)) type=myisam;
+set sql_log_bin=0;
+insert into t1 values(2);
+set sql_log_bin=1;
+insert into t1 values(1),(2);
+Duplicate entry '2' for key 1
+drop table t1;
diff --git a/mysql-test/r/rpl_alter.result b/mysql-test/r/rpl_alter.result
index 7883e725e3a..729c7df6808 100644
--- a/mysql-test/r/rpl_alter.result
+++ b/mysql-test/r/rpl_alter.result
@@ -1,4 +1,21 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop database if exists test_$1;
+create database test_$1;
+create table test_$1.t1 ( n int);
+alter table test_$1.t1 add m int;
+insert into test_$1.t1 values (1,2);
+create table test_$1.t2 (n int);
+insert into test_$1.t2 values (45);
+rename table test_$1.t2 to test_$1.t3, test_$1.t1 to test_$1.t2;
+select * from test_$1.t2;
n m
1 2
+select * from test_$1.t3;
n
45
+drop database test_$1;
diff --git a/mysql-test/r/rpl_chain_temp_table.result b/mysql-test/r/rpl_chain_temp_table.result
new file mode 100644
index 00000000000..5ece80565c7
--- /dev/null
+++ b/mysql-test/r/rpl_chain_temp_table.result
@@ -0,0 +1,30 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+reset master;
+change master to master_host='127.0.0.1',master_port=9307, master_user='root';
+start slave;
+create temporary table t1 (a int);
+create temporary table t1 (a int);
+show status like 'slave_open_temp_tables';
+Variable_name Value
+Slave_open_temp_tables 2
+create temporary table t1 (a int);
+create temporary table t1 (a int);
+show status like 'slave_open_temp_tables';
+Variable_name Value
+Slave_open_temp_tables 4
+stop slave;
+insert into t1 values(1);
+create table t2 as select * from t1;
+start slave;
+show status like 'slave_open_temp_tables';
+Variable_name Value
+Slave_open_temp_tables 4
+select * from t2;
+a
+1
+drop table t2;
diff --git a/mysql-test/r/rpl_change_master.result b/mysql-test/r/rpl_change_master.result
new file mode 100644
index 00000000000..966f07af9d5
--- /dev/null
+++ b/mysql-test/r/rpl_change_master.result
@@ -0,0 +1,32 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+select get_lock("a",5);
+get_lock("a",5)
+1
+create table t1(n int);
+insert into t1 values(1+get_lock("a",15)*0);
+insert into t1 values(2);
+stop slave;
+select * from t1;
+n
+1
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_MYPORT 1 master-bin.001 273 slave-relay-bin.002 255 master-bin.001 No No 0 0 214 314
+change master to master_user='root';
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_MYPORT 1 master-bin.001 214 slave-relay-bin.001 4 master-bin.001 No No 0 0 214 4
+select release_lock("a");
+release_lock("a")
+1
+start slave;
+select * from t1;
+n
+1
+2
+drop table t1;
diff --git a/mysql-test/r/rpl_do_grant.result b/mysql-test/r/rpl_do_grant.result
new file mode 100644
index 00000000000..fec935ae7ac
--- /dev/null
+++ b/mysql-test/r/rpl_do_grant.result
@@ -0,0 +1,26 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+delete from mysql.user where user='rpl_do_grant';
+delete from mysql.db where user='rpl_do_grant';
+flush privileges;
+delete from mysql.user where user='rpl_ignore_grant';
+delete from mysql.db where user='rpl_ignore_grant';
+flush privileges;
+grant select on *.* to rpl_do_grant@localhost;
+grant drop on test.* to rpl_do_grant@localhost;
+show grants for rpl_do_grant@localhost;
+Grants for rpl_do_grant@localhost
+GRANT SELECT ON *.* TO 'rpl_do_grant'@'localhost'
+GRANT DROP ON `test`.* TO 'rpl_do_grant'@'localhost'
+set password for rpl_do_grant@localhost=password("does it work?");
+select password<>'' from mysql.user where user='rpl_do_grant';
+password<>''
+1
+delete from mysql.user where user='rpl_do_grant';
+delete from mysql.db where user='rpl_do_grant';
+flush privileges;
+flush privileges;
diff --git a/mysql-test/r/rpl_empty_master_crash.result b/mysql-test/r/rpl_empty_master_crash.result
index e9111fdb401..19e2bf28dcd 100644
--- a/mysql-test/r/rpl_empty_master_crash.result
+++ b/mysql-test/r/rpl_empty_master_crash.result
@@ -1,2 +1,13 @@
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
- 0 0 0 No 0 0
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+load table t1 from master;
+Error connecting to master: Master is not configured
+load table t1 from master;
+Error from master: 'Table 'test.t1' doesn't exist'
diff --git a/mysql-test/r/rpl_error_ignored_table.result b/mysql-test/r/rpl_error_ignored_table.result
new file mode 100644
index 00000000000..e1486220542
--- /dev/null
+++ b/mysql-test/r/rpl_error_ignored_table.result
@@ -0,0 +1,15 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+create table t1 (a int primary key);
+insert into t1 values (1),(1);
+Duplicate entry '1' for key 1
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 213 slave-relay-bin.002 254 master-bin.001 Yes Yes 0 0 213 254
+show tables like 't1';
+Tables_in_test (t1)
+drop table t1;
diff --git a/mysql-test/r/rpl_failsafe.result b/mysql-test/r/rpl_failsafe.result
new file mode 100644
index 00000000000..7e8aeea64f7
--- /dev/null
+++ b/mysql-test/r/rpl_failsafe.result
@@ -0,0 +1,34 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+show variables like 'rpl_recovery_rank';
+Variable_name Value
+rpl_recovery_rank 1
+show status like 'Rpl_status';
+Variable_name Value
+Rpl_status AUTH_MASTER
+create table t1(n int);
+drop table t1;
+show variables like 'rpl_recovery_rank';
+Variable_name Value
+rpl_recovery_rank 2
+show status like 'Rpl_status';
+Variable_name Value
+Rpl_status ACTIVE_SLAVE
+slave start;
+show variables like 'rpl_recovery_rank';
+Variable_name Value
+rpl_recovery_rank 3
+show status like 'Rpl_status';
+Variable_name Value
+Rpl_status ACTIVE_SLAVE
+slave start;
+show variables like 'rpl_recovery_rank';
+Variable_name Value
+rpl_recovery_rank 4
+show status like 'Rpl_status';
+Variable_name Value
+Rpl_status ACTIVE_SLAVE
diff --git a/mysql-test/r/rpl_flush_log_loop.result b/mysql-test/r/rpl_flush_log_loop.result
new file mode 100644
index 00000000000..18786b1931b
--- /dev/null
+++ b/mysql-test/r/rpl_flush_log_loop.result
@@ -0,0 +1,17 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+change master to master_host='127.0.0.1',master_user='root',
+master_password='',master_port=MASTER_PORT;
+slave start;
+slave stop;
+change master to master_host='127.0.0.1',master_user='root',
+master_password='',master_port=SLAVE_PORT;
+slave start;
+flush logs;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root SLAVE_PORT 60 slave-bin.001 79 relay-log.002 4 slave-bin.001 Yes Yes 0 0 79 4
diff --git a/mysql-test/r/rpl_get_lock.result b/mysql-test/r/rpl_get_lock.result
index 84749c1a9b1..a8e602be03f 100644
--- a/mysql-test/r/rpl_get_lock.result
+++ b/mysql-test/r/rpl_get_lock.result
@@ -1,8 +1,30 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+create table t1(n int);
+insert into t1 values(get_lock("lock",2));
+select get_lock("lock",2);
get_lock("lock",2)
1
+select release_lock("lock");
release_lock("lock")
1
+select get_lock("lock",3);
get_lock("lock",3)
1
+select * from t1;
n
1
+select is_free_lock("lock");
+is_free_lock("lock")
+0
+select is_free_lock("lock2");
+is_free_lock("lock2")
+1
+select is_free_lock(NULL);
+is_free_lock(NULL)
+NULL
+drop table t1;
diff --git a/mysql-test/r/rpl_heap.result b/mysql-test/r/rpl_heap.result
new file mode 100644
index 00000000000..1556bcd5f25
--- /dev/null
+++ b/mysql-test/r/rpl_heap.result
@@ -0,0 +1,29 @@
+reset master;
+drop table if exists t1;
+create table t1 (a int) type=HEAP;
+insert into t1 values(10);
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; create table t1 (a int) type=HEAP
+master-bin.001 147 Query 1 147 use `test`; DELETE FROM `test`.`t1`
+master-bin.001 205 Query 1 205 use `test`; insert into t1 values(10)
+reset slave;
+start slave;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) default NULL
+) TYPE=HEAP
+select * from t1;
+a
+10
+select * from t1;
+a
+select * from t1 limit 10;
+a
+show binlog events in 'master-bin.002' from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.002 79 Query 1 79 use `test`; DELETE FROM `test`.`t1`
+select * from t1;
+a
+drop table t1;
diff --git a/mysql-test/r/rpl_ignore_grant.result b/mysql-test/r/rpl_ignore_grant.result
new file mode 100644
index 00000000000..6cd7d5b4c00
--- /dev/null
+++ b/mysql-test/r/rpl_ignore_grant.result
@@ -0,0 +1,37 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+delete from mysql.user where user='rpl_ignore_grant';
+delete from mysql.db where user='rpl_ignore_grant';
+flush privileges;
+delete from mysql.user where user='rpl_ignore_grant';
+delete from mysql.db where user='rpl_ignore_grant';
+flush privileges;
+grant select on *.* to rpl_ignore_grant@localhost;
+grant drop on test.* to rpl_ignore_grant@localhost;
+show grants for rpl_ignore_grant@localhost;
+Grants for rpl_ignore_grant@localhost
+GRANT SELECT ON *.* TO 'rpl_ignore_grant'@'localhost'
+GRANT DROP ON `test`.* TO 'rpl_ignore_grant'@'localhost'
+show grants for rpl_ignore_grant@localhost;
+There is no such grant defined for user 'rpl_ignore_grant' on host 'localhost'
+select count(*) from mysql.user where user='rpl_ignore_grant';
+count(*)
+0
+select count(*) from mysql.db where user='rpl_ignore_grant';
+count(*)
+0
+grant select on *.* to rpl_ignore_grant@localhost;
+set password for rpl_ignore_grant@localhost=password("does it work?");
+select password<>'' from mysql.user where user='rpl_ignore_grant';
+password<>''
+0
+delete from mysql.user where user='rpl_ignore_grant';
+delete from mysql.db where user='rpl_ignore_grant';
+flush privileges;
+delete from mysql.user where user='rpl_ignore_grant';
+delete from mysql.db where user='rpl_ignore_grant';
+flush privileges;
diff --git a/mysql-test/r/rpl_insert_id.result b/mysql-test/r/rpl_insert_id.result
index 0298cca5da5..d2dfbb05675 100644
--- a/mysql-test/r/rpl_insert_id.result
+++ b/mysql-test/r/rpl_insert_id.result
@@ -1,15 +1,71 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+create table t1(a int auto_increment, key(a));
+create table t2(b int auto_increment, c int, key(b));
+insert into t1 values (1),(2),(3);
+insert into t1 values (null);
+insert into t2 values (null,last_insert_id());
+select * from t1;
a
1
2
3
4
+select * from t2;
b c
1 4
+drop table t1;
+drop table t2;
+create table t1(a int auto_increment, key(a)) type=innodb;
+create table t2(b int auto_increment, c int, key(b), foreign key(b) references t1(a)) type=innodb;
+SET FOREIGN_KEY_CHECKS=0;
+insert into t1 values (10);
+insert into t1 values (null),(null),(null);
+insert into t2 values (5,0);
+insert into t2 values (null,last_insert_id());
+SET FOREIGN_KEY_CHECKS=1;
+select * from t1;
a
10
11
12
13
+select * from t2;
b c
5 0
6 11
+drop table t2;
+drop table t1;
+create table t1(a int auto_increment, key(a));
+create table t2(b int auto_increment, c int, key(b));
+insert into t1 values (10);
+insert into t1 values (null),(null),(null);
+insert into t2 values (5,0);
+insert into t2 (c) select * from t1;
+select * from t2;
+b c
+5 0
+6 10
+7 11
+8 12
+9 13
+select * from t1;
+a
+10
+11
+12
+13
+select * from t2;
+b c
+5 0
+6 10
+7 11
+8 12
+9 13
+drop table t1;
+drop table t2;
diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result
new file mode 100644
index 00000000000..268e383ce69
--- /dev/null
+++ b/mysql-test/r/rpl_loaddata.result
@@ -0,0 +1,68 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+reset master;
+create table t1(a int not null auto_increment, b int, primary key(a) );
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60));
+load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines;
+create table t3 (day date,id int(9),category enum('a','b','c'),name varchar(60));
+insert into t3 select * from t2;
+select * from t1;
+a b
+1 10
+2 15
+select * from t3;
+day id category name
+2003-02-22 2461 b a a a @ %  ' " a
+2003-03-22 2161 c asdf
+2003-03-22 2416 a bbbbb
+show master status;
+File Position Binlog_do_db Binlog_ignore_db
+slave-bin.001 964
+drop table t1;
+drop table t2;
+drop table t3;
+create table t1(a int, b int, unique(b));
+insert into t1 values(1,10);
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+set global sql_slave_skip_counter=1;
+start slave;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 1311 slave-relay-bin.002 1352 master-bin.001 Yes Yes 0 0 1311 1352
+set sql_log_bin=0;
+delete from t1;
+set sql_log_bin=1;
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+stop slave;
+change master to master_user='test';
+change master to master_user='root';
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 1419 slave-relay-bin.001 4 master-bin.001 No No 0 0 1419 4
+set global sql_slave_skip_counter=1;
+start slave;
+set sql_log_bin=0;
+delete from t1;
+set sql_log_bin=1;
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+stop slave;
+reset slave;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4
+reset master;
+create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60),
+unique(day));
+load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
+terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
+'\n##\n' starting by '>' ignore 1 lines;
+Duplicate entry '2003-03-22' for key 1
+show master status;
+File Position Binlog_do_db Binlog_ignore_db
+master-bin.001 491
+drop table t2;
diff --git a/mysql-test/r/rpl_loaddata_rule_m.result b/mysql-test/r/rpl_loaddata_rule_m.result
new file mode 100644
index 00000000000..8d8ed749c71
--- /dev/null
+++ b/mysql-test/r/rpl_loaddata_rule_m.result
@@ -0,0 +1,14 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+reset master;
+create database test2;
+create table t1(a int, b int, unique(b));
+use test2;
+load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+drop database test2;
diff --git a/mysql-test/r/rpl_loaddata_rule_s.result b/mysql-test/r/rpl_loaddata_rule_s.result
new file mode 100644
index 00000000000..a84368501a9
--- /dev/null
+++ b/mysql-test/r/rpl_loaddata_rule_s.result
@@ -0,0 +1,14 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+reset master;
+create table t1(a int, b int, unique(b));
+load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
+select count(*) from t1;
+count(*)
+2
+show binlog events from 79;
+Log_name Pos Event_type Server_id Orig_log_pos Info
diff --git a/mysql-test/r/rpl_loaddatalocal.result b/mysql-test/r/rpl_loaddatalocal.result
new file mode 100644
index 00000000000..dc98b1b5bfb
--- /dev/null
+++ b/mysql-test/r/rpl_loaddatalocal.result
@@ -0,0 +1,14 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+create table t1(a int);
+select * into outfile '../../var/master-data/rpl_loaddatalocal.select_outfile' from t1;
+truncate table t1;
+load data local infile './var/master-data/rpl_loaddatalocal.select_outfile' into table t1;
+select a,count(*) from t1 group by a;
+a count(*)
+1 10000
+drop table t1;
diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result
new file mode 100644
index 00000000000..7e2a8df75ac
--- /dev/null
+++ b/mysql-test/r/rpl_log.result
@@ -0,0 +1,101 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+slave stop;
+reset master;
+reset slave;
+reset master;
+create table t1(n int not null auto_increment primary key);
+insert into t1 values (NULL);
+drop table t1;
+create table t1 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t1 ignore 1 lines;
+select count(*) from t1;
+count(*)
+69
+drop table t1;
+show binlog events;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
+master-bin.001 79 Query 1 79 use `test`; create table t1(n int not null auto_increment primary key)
+master-bin.001 172 Intvar 1 172 INSERT_ID=1
+master-bin.001 200 Query 1 200 use `test`; insert into t1 values (NULL)
+master-bin.001 263 Query 1 263 use `test`; drop table t1
+master-bin.001 311 Query 1 311 use `test`; create table t1 (word char(20) not null)
+master-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=581
+master-bin.001 1056 Exec_load 1 1056 ;file_id=1
+master-bin.001 1079 Query 1 1079 use `test`; drop table t1
+show binlog events from 79 limit 1;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; create table t1(n int not null auto_increment primary key)
+show binlog events from 79 limit 2;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 79 Query 1 79 use `test`; create table t1(n int not null auto_increment primary key)
+master-bin.001 172 Intvar 1 172 INSERT_ID=1
+show binlog events from 79 limit 2,1;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 200 Query 1 200 use `test`; insert into t1 values (NULL)
+flush logs;
+create table t5 (a int);
+drop table t5;
+slave start;
+flush logs;
+slave stop;
+create table t1 (n int);
+insert into t1 values (1);
+drop table t1;
+show binlog events;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
+master-bin.001 79 Query 1 79 use `test`; create table t1(n int not null auto_increment primary key)
+master-bin.001 172 Intvar 1 172 INSERT_ID=1
+master-bin.001 200 Query 1 200 use `test`; insert into t1 values (NULL)
+master-bin.001 263 Query 1 263 use `test`; drop table t1
+master-bin.001 311 Query 1 311 use `test`; create table t1 (word char(20) not null)
+master-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=581
+master-bin.001 1056 Exec_load 1 1056 ;file_id=1
+master-bin.001 1079 Query 1 1079 use `test`; drop table t1
+master-bin.001 1127 Rotate 1 1127 master-bin.002;pos=4
+show binlog events in 'master-bin.002';
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.002 4 Query 1 4 use `test`; create table t5 (a int)
+master-bin.002 62 Query 1 62 use `test`; drop table t5
+master-bin.002 110 Query 1 110 use `test`; create table t1 (n int)
+master-bin.002 168 Query 1 168 use `test`; insert into t1 values (1)
+master-bin.002 228 Query 1 228 use `test`; drop table t1
+show master logs;
+Log_name
+master-bin.001
+master-bin.002
+slave start;
+show master logs;
+Log_name
+slave-bin.001
+slave-bin.002
+show binlog events in 'slave-bin.001' from 4;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+slave-bin.001 4 Start 2 4 Server ver: VERSION, Binlog ver: 3
+slave-bin.001 79 Query 1 79 use `test`; create table t1(n int not null auto_increment primary key)
+slave-bin.001 172 Intvar 1 172 INSERT_ID=1
+slave-bin.001 200 Query 1 200 use `test`; insert into t1 values (NULL)
+slave-bin.001 263 Query 1 263 use `test`; drop table t1
+slave-bin.001 311 Query 1 311 use `test`; create table t1 (word char(20) not null)
+slave-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=581
+slave-bin.001 1065 Exec_load 1 1065 ;file_id=1
+slave-bin.001 1088 Query 1 1088 use `test`; drop table t1
+slave-bin.001 1136 Query 1 1136 use `test`; create table t5 (a int)
+slave-bin.001 1194 Query 1 1194 use `test`; drop table t5
+slave-bin.001 1242 Rotate 2 1242 slave-bin.002;pos=4
+show binlog events in 'slave-bin.002' from 4;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+slave-bin.002 4 Query 1 4 use `test`; create table t1 (n int)
+slave-bin.002 62 Query 1 62 use `test`; insert into t1 values (1)
+slave-bin.002 122 Query 1 122 use `test`; drop table t1
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.003 211 master-bin.002 Yes Yes 0 0 276 211
+show binlog events in 'slave-bin.005' from 4;
+Error when executing command SHOW BINLOG EVENTS: Could not find target log
diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result
new file mode 100644
index 00000000000..f7e59e55577
--- /dev/null
+++ b/mysql-test/r/rpl_log_pos.result
@@ -0,0 +1,46 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+show master status;
+File Position Binlog_do_db Binlog_ignore_db
+master-bin.001 79
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 120
+slave stop;
+change master to master_log_pos=73;
+slave start;
+slave stop;
+change master to master_log_pos=73;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 4 master-bin.001 No No 0 0 73 4
+slave start;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 45 master-bin.001 No Yes 0 0 73 45
+slave stop;
+change master to master_log_pos=173;
+slave start;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 173 slave-relay-bin.001 4 master-bin.001 No Yes 0 0 173 4
+show master status;
+File Position Binlog_do_db Binlog_ignore_db
+master-bin.001 79
+create table if not exists t1 (n int);
+drop table if exists t1;
+create table t1 (n int);
+insert into t1 values (1),(2),(3);
+slave stop;
+change master to master_log_pos=79;
+slave start;
+select * from t1;
+n
+1
+2
+3
+drop table t1;
diff --git a/mysql-test/r/rpl_master_pos_wait.result b/mysql-test/r/rpl_master_pos_wait.result
new file mode 100644
index 00000000000..cb6ee31a54d
--- /dev/null
+++ b/mysql-test/r/rpl_master_pos_wait.result
@@ -0,0 +1,13 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+select master_pos_wait('master-bin.999999',0,2);
+master_pos_wait('master-bin.999999',0,2)
+-1
+ select master_pos_wait('master-bin.999999',0);
+stop slave sql_thread;
+master_pos_wait('master-bin.999999',0)
+NULL
diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_max_relay_size.result
new file mode 100644
index 00000000000..d74bc80c0ab
--- /dev/null
+++ b/mysql-test/r/rpl_max_relay_size.result
@@ -0,0 +1,61 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+stop slave;
+create table t1 (a int);
+drop table t1;
+reset slave;
+set global max_binlog_size=8192;
+set global max_relay_log_size=8192-1;
+select @@global.max_relay_log_size;
+@@global.max_relay_log_size
+4096
+start slave;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.014 1221 master-bin.001 Yes Yes 0 0 50477 1221
+stop slave;
+reset slave;
+set global max_relay_log_size=(5*4096);
+select @@global.max_relay_log_size;
+@@global.max_relay_log_size
+20480
+start slave;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.004 9457 master-bin.001 Yes Yes 0 0 50477 #
+stop slave;
+reset slave;
+set global max_relay_log_size=0;
+select @@global.max_relay_log_size;
+@@global.max_relay_log_size
+0
+start slave;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.008 1283 master-bin.001 Yes Yes 0 0 50477 1283
+stop slave;
+reset slave;
+flush logs;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4
+reset slave;
+start slave;
+flush logs;
+create table t1 (a int);
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 50535 slave-relay-bin.009 62 master-bin.001 Yes Yes 0 0 50535 62
+flush logs;
+drop table t1;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 50583 slave-relay-bin.010 52 master-bin.001 Yes Yes 0 0 50583 52
+flush logs;
+show master status;
+File Position Binlog_do_db Binlog_ignore_db
+master-bin.002 4
diff --git a/mysql-test/r/rpl_multi_delete.result b/mysql-test/r/rpl_multi_delete.result
new file mode 100644
index 00000000000..fa254d76393
--- /dev/null
+++ b/mysql-test/r/rpl_multi_delete.result
@@ -0,0 +1,22 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1);
+insert into t2 values (1);
+delete t1.* from t1, t2 where t1.a = t2.a;
+select * from t1;
+a
+select * from t2;
+a
+1
+select * from t1;
+a
+select * from t2;
+a
+1
+drop table t1,t2;
diff --git a/mysql-test/r/rpl_multi_update.result b/mysql-test/r/rpl_multi_update.result
new file mode 100644
index 00000000000..1fa1dd104d2
--- /dev/null
+++ b/mysql-test/r/rpl_multi_update.result
@@ -0,0 +1,27 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1,t2;
+CREATE TABLE t1 (
+a int unsigned not null auto_increment primary key,
+b int unsigned,
+) TYPE=MyISAM;
+CREATE TABLE t2 (
+a int unsigned not null auto_increment primary key,
+b int unsigned
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (NULL, 0);
+INSERT INTO t1 SELECT NULL, 0 FROM t1;
+INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
+SELECT * FROM t1 ORDER BY a;
+a b
+1 0
+2 0
+SELECT * FROM t2 ORDER BY a;
+a b
+1 0
+2 1
+UPDATE t1, t2 SET t1.b = t2.b WHERE t1.a = t2.a;
diff --git a/mysql-test/r/rpl_mystery22.result b/mysql-test/r/rpl_mystery22.result
index f85b057eefa..5dd665fe9d5 100644
--- a/mysql-test/r/rpl_mystery22.result
+++ b/mysql-test/r/rpl_mystery22.result
@@ -1,4 +1,23 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+create table t1(n int auto_increment primary key);
+insert into t1 values (2);
+insert into t1 values(NULL);
+insert into t1 values(NULL);
+delete from t1 where n = 2;
+slave start;
+slave stop;
+create table t2(n int);
+drop table t2;
+insert into t1 values(NULL);
+slave start;
+select * from t1;
n
1
2
3
+drop table t1;
diff --git a/mysql-test/r/rpl_redirect.result b/mysql-test/r/rpl_redirect.result
new file mode 100644
index 00000000000..6103a075684
--- /dev/null
+++ b/mysql-test/r/rpl_redirect.result
@@ -0,0 +1,43 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+SHOW SLAVE STATUS;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+SHOW SLAVE HOSTS;
+Server_id Host Port Rpl_recovery_rank Master_id
+2 127.0.0.1 SLAVE_PORT 2 1
+drop table if exists t1;
+create table t1 ( n int);
+insert into t1 values (1),(2),(3),(4);
+insert into t1 values(5);
+select * from t1;
+n
+1
+2
+3
+4
+5
+select * from t1;
+n
+1
+2
+3
+4
+select * from t1;
+n
+1
+2
+3
+4
+select * from t1;
+n
+1
+2
+3
+4
+5
+drop table t1;
+drop table t1;
diff --git a/mysql-test/r/rpl_relayspace.result b/mysql-test/r/rpl_relayspace.result
new file mode 100644
index 00000000000..721c6a882bd
--- /dev/null
+++ b/mysql-test/r/rpl_relayspace.result
@@ -0,0 +1,19 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+stop slave;
+create table t1 (a int);
+drop table t1;
+create table t1 (a int);
+drop table t1;
+reset slave;
+start slave io_thread;
+stop slave io_thread;
+reset slave;
+start slave;
+select master_pos_wait('master-bin.001',200,6)=-1;
+master_pos_wait('master-bin.001',200,6)=-1
+0
diff --git a/mysql-test/r/rpl_replicate_do.result b/mysql-test/r/rpl_replicate_do.result
new file mode 100644
index 00000000000..372d8c07f64
--- /dev/null
+++ b/mysql-test/r/rpl_replicate_do.result
@@ -0,0 +1,28 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t11;
+drop table if exists t11;
+create table t2 (n int);
+insert into t2 values(4);
+create table t2 (s char(20));
+load data infile '../../std_data/words.dat' into table t2;
+insert into t2 values('five');
+create table t1 (m int);
+insert into t1 values(15),(16),(17);
+update t1 set m=20 where m=16;
+delete from t1 where m=17;
+create table t11 select * from t1;
+select * from t1;
+m
+15
+20
+select * from t2;
+n
+4
+select * from t11;
+Table 'test.t11' doesn't exist
+drop table if exists t1,t2,t3,t11;
diff --git a/mysql-test/r/rpl_reset_slave.result b/mysql-test/r/rpl_reset_slave.result
new file mode 100644
index 00000000000..fb931064720
--- /dev/null
+++ b/mysql-test/r/rpl_reset_slave.result
@@ -0,0 +1,32 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 120
+stop slave;
+change master to master_user='test';
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 test MASTER_PORT 1 master-bin.001 79 slave-relay-bin.001 4 master-bin.001 No No 0 0 79 4
+reset slave;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4
+start slave;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 120
+stop slave;
+reset slave;
+start slave;
+create temporary table t1 (a int);
+stop slave;
+reset slave;
+start slave;
+show status like 'slave_open_temp_tables';
+Variable_name Value
+Slave_open_temp_tables 1
diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result
index cf432d07b08..89d7f4a795a 100644
--- a/mysql-test/r/rpl_rotate_logs.result
+++ b/mysql-test/r/rpl_rotate_logs.result
@@ -1,34 +1,83 @@
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 60 master-bin.001 387 Yes 0 0
+drop table if exists t1, t2, t3, t4;
+drop table if exists t1, t2, t3, t4;
+slave start;
+Could not initialize master info structure, more error messages can be found in the MySQL error log
+slave start;
+Could not initialize master info structure, more error messages can be found in the MySQL error log
+change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root';
+Could not initialize master info structure, more error messages can be found in the MySQL error log
+reset slave;
+change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root';
+reset master;
+slave start;
+create temporary table temp_table (a char(80) not null);
+insert into temp_table values ("testing temporary tables");
+create table t1 (s text);
+insert into t1 values('Could not break slave'),('Tried hard');
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 60 master-bin.001 417 slave-relay-bin.001 458 master-bin.001 Yes Yes 0 0 417 #
+select * from t1;
s
Could not break slave
Tried hard
+flush logs;
+create table t2(m int not null auto_increment primary key);
+insert into t2 values (34),(67),(123);
+flush logs;
+show master logs;
Log_name
master-bin.001
master-bin.002
master-bin.003
+create table t3 select * from temp_table;
+select * from t3;
a
testing temporary tables
+drop table temp_table, t3;
+insert into t2 values(1234);
+set insert_id=1234;
+insert into t2 values(NULL);
+set global sql_slave_skip_counter=1;
+slave start;
+purge master logs to 'master-bin.003';
+show master logs;
Log_name
master-bin.003
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 60 master-bin.003 329 Yes 0 0
+insert into t2 values (65);
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 60 master-bin.003 290 slave-relay-bin.001 1073 master-bin.003 Yes Yes 0 0 290 #
+select * from t2;
m
34
65
67
123
1234
+create temporary table temp_table (a char(80) not null);
+insert into temp_table values ("testing temporary tables part 2");
+create table t3 (n int);
+select count(*) from t3 where n >= 4;
+count(*)
+100
+create table t4 select * from temp_table;
+show master logs;
Log_name
master-bin.003
master-bin.004
-master-bin.005
-master-bin.006
+show master status;
File Position Binlog_do_db Binlog_ignore_db
-master-bin.006 490
+master-bin.004 2886
+select * from t4;
a
testing temporary tables part 2
-Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
-127.0.0.1 root 9999 60 master-bin.006 490 Yes 0 0
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 60 master-bin.004 2886 slave-relay-bin.001 7870 master-bin.004 Yes Yes 0 0 2886 #
+lock tables t3 read;
+select count(*) from t3 where n >= 4;
count(*)
100
+unlock tables;
+drop table if exists t1,t2,t3,t4;
diff --git a/mysql-test/r/rpl_skip_error.result b/mysql-test/r/rpl_skip_error.result
index f85b057eefa..946d64ad7c5 100644
--- a/mysql-test/r/rpl_skip_error.result
+++ b/mysql-test/r/rpl_skip_error.result
@@ -1,3 +1,15 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+drop table if exists t1;
+create table t1 (n int not null primary key);
+insert into t1 values (1);
+insert into t1 values (1);
+insert into t1 values (2),(3);
+select * from t1;
n
1
2
diff --git a/mysql-test/r/rpl_sporadic_master.result b/mysql-test/r/rpl_sporadic_master.result
index ed616c26b67..a6a58515f0a 100644
--- a/mysql-test/r/rpl_sporadic_master.result
+++ b/mysql-test/r/rpl_sporadic_master.result
@@ -1,3 +1,21 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+create table t2(n int);
+create table t1(n int not null auto_increment primary key);
+insert into t1 values (NULL),(NULL);
+truncate table t1;
+insert into t1 values (4),(NULL);
+slave stop;
+slave start;
+insert into t1 values (NULL),(NULL);
+flush logs;
+truncate table t1;
+insert into t1 values (10),(NULL),(NULL),(NULL),(NULL),(NULL);
+select * from t1;
n
10
11
@@ -5,3 +23,4 @@ n
13
14
15
+drop table t1,t2;
diff --git a/mysql-test/r/rpl_trunc_binlog.result b/mysql-test/r/rpl_trunc_binlog.result
new file mode 100644
index 00000000000..272fa210807
--- /dev/null
+++ b/mysql-test/r/rpl_trunc_binlog.result
@@ -0,0 +1,13 @@
+slave stop;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+slave start;
+stop slave;
+flush logs;
+reset slave;
+start slave;
+show slave status;
+Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
+127.0.0.1 root MASTER_PORT 1 master-bin.002 4 slave-relay-bin.002 161 master-bin.001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. Probably cause is that the master died while writing the transaction to it's binary log. 0 79 #
diff --git a/mysql-test/r/sel000001.result b/mysql-test/r/sel000001.result
index bee97cc7b53..6b6b9b7dffc 100644
--- a/mysql-test/r/sel000001.result
+++ b/mysql-test/r/sel000001.result
@@ -1,2 +1,21 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (s CHAR(20) PRIMARY KEY, id INT);
+INSERT INTO t1 VALUES ('cat', 1), ('mouse', 3), ('dog', 2), ('snake', 77);
+SELECT s, id FROM t1 WHERE s = 'mouse';
s id
mouse 3
+drop table t1;
+CREATE TABLE t1 (
+node int(11) NOT NULL default '0',
+maxchild int(11) NOT NULL default '0',
+PRIMARY KEY (`node`)
+);
+INSERT INTO t1 (node, maxchild) VALUES (4,4),(5,5),(1,244);
+SELECT * FROM t1 g1, t1 g2
+WHERE g1.node <= g2.node and g2.node <= g1.maxchild and g2.node = g2.maxchild;
+node maxchild node maxchild
+4 4 4 4
+5 5 5 5
+1 244 4 4
+1 244 5 5
+DROP TABLE t1;
diff --git a/mysql-test/r/sel000002.result b/mysql-test/r/sel000002.result
index f85b057eefa..b824de8de4a 100644
--- a/mysql-test/r/sel000002.result
+++ b/mysql-test/r/sel000002.result
@@ -1,4 +1,9 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (n INT);
+INSERT INTO t1 VALUES (1), (2), (3);
+SELECT * FROM t1;
n
1
2
3
+drop table t1;
diff --git a/mysql-test/r/sel000003.result b/mysql-test/r/sel000003.result
index 77312414818..c3853832f87 100644
--- a/mysql-test/r/sel000003.result
+++ b/mysql-test/r/sel000003.result
@@ -1,3 +1,8 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (name CHAR(20) NOT NULL PRIMARY KEY, score SMALLINT NOT NULL, KEY(score));
+INSERT INTO t1 VALUES ('Sasha', 20), ('Matt', 20), ('Monty', 10), ('David', 10), ('Tim', 10), ('Jeremy', 10);
+SELECT COUNT(*) as n, score FROM t1 GROUP BY score;
n score
4 10
2 20
+drop table t1;
diff --git a/mysql-test/r/sel000031.result b/mysql-test/r/sel000031.result
index c1caa04a00a..d3f01ab687f 100644
--- a/mysql-test/r/sel000031.result
+++ b/mysql-test/r/sel000031.result
@@ -1,4 +1,12 @@
+drop table if exists t1,t2;
+create table t1 (id int(10) not null unique);
+create table t2 (id int(10) not null primary key,
+val int(10) not null);
+insert into t1 values (1),(2),(4);
+insert into t2 values (1,1),(2,1),(3,1),(4,2);
+select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id;
id elt(two.val,'one','two')
1 one
2 one
4 two
+drop table t1,t2;
diff --git a/mysql-test/r/sel000032.result b/mysql-test/r/sel000032.result
index c1caa04a00a..4cca245d75b 100644
--- a/mysql-test/r/sel000032.result
+++ b/mysql-test/r/sel000032.result
@@ -1,4 +1,12 @@
+drop table if exists t1,t2;
+create table t1 (id int(10) not null unique);
+create table t2 (id int(10) not null primary key,
+val int(10) not null);
+insert into t1 values (1),(2),(4);
+insert into t2 values (1,1),(2,1),(3,1),(4,2);
+select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id;
id elt(two.val,'one','two')
1 one
2 one
4 two
+drop table t1,t2;
diff --git a/mysql-test/r/sel000033.result b/mysql-test/r/sel000033.result
index 689c94082e7..1bfafaf5b27 100644
--- a/mysql-test/r/sel000033.result
+++ b/mysql-test/r/sel000033.result
@@ -1,8 +1,14 @@
+drop table if exists t1;
+create table t1 (id int(10) primary key);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
+select id from t1 where id in (2,5,9) ;
id
2
5
9
+select id from t1 where id=2 or id=5 or id=9 ;
id
2
5
9
+drop table t1;
diff --git a/mysql-test/r/sel000100.result b/mysql-test/r/sel000100.result
index e7d8cf0e7ac..3ffa4004b84 100644
--- a/mysql-test/r/sel000100.result
+++ b/mysql-test/r/sel000100.result
@@ -1,2 +1,38 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+NAME varchar(75) DEFAULT '' NOT NULL,
+LINK_ID int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (ID),
+KEY NAME (NAME),
+KEY LINK_ID (LINK_ID)
+);
+INSERT INTO t1 (ID, NAME, LINK_ID) VALUES (1,'Mike',0);
+INSERT INTO t1 (ID, NAME, LINK_ID) VALUES (2,'Jack',0);
+INSERT INTO t1 (ID, NAME, LINK_ID) VALUES (3,'Bill',0);
+CREATE TABLE t2 (
+ID int(11) NOT NULL auto_increment,
+NAME varchar(150) DEFAULT '' NOT NULL,
+PRIMARY KEY (ID),
+KEY NAME (NAME)
+);
+SELECT DISTINCT
+t2.id AS key_link_id,
+t2.name AS link
+FROM t1
+LEFT JOIN t2 ON t1.link_id=t2.id
+GROUP BY t1.id
+ORDER BY link;
key_link_id link
NULL NULL
+drop table t1,t2;
+CREATE TABLE t1 (
+html varchar(5) default NULL,
+rin int(11) default '0',
+out int(11) default '0'
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('1',1,0);
+SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
+html prod
+1 0.00
+drop table t1;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index dcb796b8e00..206fa507615 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -1,13 +1,37 @@
+drop table if exists t1,t2,t3,t4;
+CREATE TABLE t1 (
+Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
+Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
+);
+INSERT INTO t1 VALUES (9410,9412);
+select period from t1;
period
9410
+select * from t1;
Period Varor_period
9410 9412
+select t1.* from t1;
Period Varor_period
9410 9412
+CREATE TABLE t2 (
+auto int not null auto_increment,
+fld1 int(6) unsigned zerofill DEFAULT '000000' NOT NULL,
+companynr tinyint(2) unsigned zerofill DEFAULT '00' NOT NULL,
+fld3 char(30) DEFAULT '' NOT NULL,
+fld4 char(35) DEFAULT '' NOT NULL,
+fld5 char(35) DEFAULT '' NOT NULL,
+fld6 char(4) DEFAULT '' NOT NULL,
+UNIQUE fld1 (fld1),
+KEY fld3 (fld3),
+PRIMARY KEY (auto)
+);
+select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%";
fld3
imaginable
+select fld3 from t2 where fld3 like "%cultivation" ;
fld3
cultivation
+select t2.fld3,companynr from t2 where companynr = 57+1 order by fld3;
fld3 companynr
concoct 58
druggists 58
@@ -32,6 +56,7 @@ synergy 58
thanking 58
tying 58
unlocks 58
+select fld3,companynr from t2 where companynr = 58 order by fld3;
fld3 companynr
concoct 58
druggists 58
@@ -56,6 +81,7 @@ synergy 58
thanking 58
tying 58
unlocks 58
+select fld3 from t2 order by fld3 desc limit 10;
fld3
youthfulness
yelped
@@ -67,49 +93,71 @@ Winsett
Willy
willed
wildcats
+select fld3 from t2 order by fld3 desc limit 5;
fld3
youthfulness
yelped
Wotan
workers
Witt
+select fld3 from t2 order by fld3 desc limit 5,5;
fld3
witchcraft
Winsett
Willy
willed
wildcats
+select t2.fld3 from t2 where fld3 = 'honeysuckle';
fld3
honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_';
fld3
honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_';
fld3
honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%';
fld3
honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'h%le';
fld3
honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_';
fld3
+select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%';
fld3
+explain select t2.fld3 from t2 where fld3 = 'honeysuckle';
table type possible_keys key key_len ref rows Extra
-t2 ref fld3 fld3 30 const 1 where used; Using index
+t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 ignore index (fld3) where fld3 = 'honeysuckle';
table type possible_keys key key_len ref rows Extra
-t2 ALL fld3 NULL NULL NULL 1199 where used
+t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select fld3 from t2 use index (fld1) where fld3 = 'honeysuckle';
table type possible_keys key key_len ref rows Extra
-t2 ALL fld3 NULL NULL NULL 1199 where used
+t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select fld3 from t2 use index (fld3) where fld3 = 'honeysuckle';
table type possible_keys key key_len ref rows Extra
-t2 ref fld3 fld3 30 const 1 where used; Using index
+t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 use index (fld1,fld3) where fld3 = 'honeysuckle';
table type possible_keys key key_len ref rows Extra
-t2 ref fld3 fld3 30 const 1 where used; Using index
+t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 ignore index (fld3,not_used);
+Key column 'not_used' doesn't exist in table
+explain select fld3 from t2 use index (not_used);
+Key column 'not_used' doesn't exist in table
+select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
fld3
honeysuckle
honoring
+explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
table type possible_keys key key_len ref rows Extra
-t2 range fld3 fld3 30 NULL 2 where used; Using index
+t2 range fld3 fld3 30 NULL 2 Using where; Using index
+select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3;
fld1 fld3
148504 Colombo
068305 Colombo
000000 nondecreasing
+select fld1,fld3 from t2 where companynr = 37 and fld3 = 'appendixes';
fld1 fld3
232605 appendixes
1232605 appendixes
@@ -117,18 +165,23 @@ fld1 fld3
1232607 appendixes
1232608 appendixes
1232609 appendixes
+select fld1 from t2 where fld1=250501 or fld1="250502";
fld1
250501
250502
+explain select fld1 from t2 where fld1=250501 or fld1="250502";
table type possible_keys key key_len ref rows Extra
-t2 range fld1 fld1 4 NULL 2 where used; Using index
+t2 range fld1 fld1 4 NULL 2 Using where; Using index
+select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
fld1
250501
250502
250505
250601
+explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
table type possible_keys key key_len ref rows Extra
-t2 range fld1 fld1 4 NULL 4 where used; Using index
+t2 range fld1 fld1 4 NULL 4 Using where; Using index
+select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
218401 faithful
018007 fanatic
@@ -161,21 +214,26 @@ fld1 fld3
036002 funereal
226209 furnishings
198006 furthermore
+select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
+select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
fld3
Chantilly
+select fld1,fld3 from t2 where fld1 like "25050%";
fld1 fld3
250501 poisoning
250502 Iraqis
250503 heaving
250504 population
250505 bomb
+select fld1,fld3 from t2 where fld1 like "25050_";
fld1 fld3
250501 poisoning
250502 Iraqis
250503 heaving
250504 population
250505 bomb
+select distinct companynr from t2;
companynr
00
37
@@ -189,6 +247,7 @@ companynr
41
34
68
+select distinct companynr from t2 order by companynr;
companynr
00
29
@@ -202,6 +261,7 @@ companynr
58
65
68
+select distinct companynr from t2 order by companynr desc;
companynr
68
65
@@ -215,6 +275,7 @@ companynr
34
29
00
+select distinct t2.fld3,period from t2,t1 where companynr=37 and fld3 like "O%";
fld3 period
obliterates 9410
offload 9410
@@ -222,6 +283,7 @@ opaquely 9410
organizer 9410
overestimating 9410
overlay 9410
+select distinct fld3 from t2 where companynr = 34 order by fld3;
fld3
absentee
accessed
@@ -293,6 +355,7 @@ unexpected
uprisings
versatility
vest
+select distinct fld3 from t2 limit 10;
fld3
abates
abiding
@@ -304,6 +367,7 @@ accessed
accruing
accumulating
accuracies
+select distinct fld3 from t2 having fld3 like "A%" limit 10;
fld3
abates
abiding
@@ -315,6 +379,7 @@ accessed
accruing
accumulating
accuracies
+select distinct substring(fld3,1,3) from t2 where fld3 like "A%";
substring(fld3,1,3)
aba
abi
@@ -378,6 +443,7 @@ avo
awe
aye
Azt
+select distinct substring(fld3,1,3) as a from t2 having a like "A%" order by a limit 10;
a
aba
abi
@@ -389,6 +455,7 @@ acq
acu
Ade
adj
+select distinct substring(fld3,1,3) from t2 where fld3 like "A%" limit 10;
substring(fld3,1,3)
aba
abi
@@ -400,6 +467,7 @@ acq
acu
Ade
adj
+select distinct substring(fld3,1,3) as a from t2 having a like "A%" limit 10;
a
aba
abi
@@ -411,6 +479,37 @@ acq
acu
Ade
adj
+create table t3 (
+period int not null,
+name char(32) not null,
+companynr int not null,
+price double(11,0),
+price2 double(11,0),
+key (period),
+key (name)
+);
+create temporary table tmp type = myisam select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+alter table t3 add t2nr int not null auto_increment primary key first;
+drop table tmp;
+SET SQL_BIG_TABLES=1;
+select distinct concat(fld3," ",fld3) as namn from t2,t3 where t2.fld1=t3.t2nr order by namn limit 10;
namn
Abraham Abraham
abrogating abrogating
@@ -422,6 +521,8 @@ ammonium ammonium
analyzable analyzable
animals animals
animized animized
+SET SQL_BIG_TABLES=0;
+select distinct concat(fld3," ",fld3) from t2,t3 where t2.fld1=t3.t2nr order by fld3 limit 10;
concat(fld3," ",fld3)
Abraham Abraham
abrogating abrogating
@@ -433,6 +534,7 @@ ammonium ammonium
analyzable analyzable
animals animals
animized animized
+select distinct fld5 from t2 limit 10;
fld5
neat
Steinberg
@@ -444,6 +546,7 @@ attainments
fanatic
measures
rightfulness
+select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
fld3 count(*)
affixed 1
and 1
@@ -455,6 +558,8 @@ attendants 1
bedlam 1
bedpost 1
boasted 1
+SET SQL_BIG_TABLES=1;
+select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
fld3 count(*)
affixed 1
and 1
@@ -466,6 +571,8 @@ attendants 1
bedlam 1
bedpost 1
boasted 1
+SET SQL_BIG_TABLES=0;
+select distinct fld3,repeat("a",length(fld3)),count(*) from t2 group by companynr,fld3 limit 100,10;
fld3 repeat("a",length(fld3)) count(*)
circus aaaaaa 1
cited aaaaa 1
@@ -477,6 +584,7 @@ cultivation aaaaaaaaaaa 1
definiteness aaaaaaaaaaaa 1
demultiplex aaaaaaaaaaa 1
disappointing aaaaaaaaaaaaa 1
+select distinct companynr,rtrim(space(512+companynr)) from t3 order by 1,2;
companynr rtrim(space(512+companynr))
37
78
@@ -485,20 +593,40 @@ companynr rtrim(space(512+companynr))
311
447
512
+select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by fld3;
fld3
+explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3;
table type possible_keys key key_len ref rows Extra
-t2 ALL fld1 NULL NULL NULL 1199 where used; Using temporary; Using filesort
-t3 eq_ref PRIMARY PRIMARY 4 t2.fld1 1 where used; Using index
+t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort
+t3 eq_ref PRIMARY PRIMARY 4 t2.fld1 1 Using where; Using index
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
+table type possible_keys key key_len ref rows Extra
+t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
+t3 ref period period 4 t1.period 4181
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
+table type possible_keys key key_len ref rows Extra
+t3 index period period 4 NULL 41810
+t1 ref period period 4 t3.period 4181
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10;
+table type possible_keys key key_len ref rows Extra
+t1 index period period 4 NULL 41810
+t3 ref period period 4 t1.period 4181
+select period from t1;
period
9410
+select period from t1 where period=1900;
period
+select fld3,period from t1,t2 where fld1 = 011401 order by period;
fld3 period
breaking 9410
+select fld3,period from t2,t3 where t2.fld1 = 011401 and t2.fld1=t3.t2nr and t3.period=1001;
fld3 period
breaking 1001
+explain select fld3,period from t2,t3 where t2.fld1 = 011401 and t3.t2nr=t2.fld1 and 1001 = t3.period;
table type possible_keys key key_len ref rows Extra
t2 const fld1 fld1 4 const 1
t3 const PRIMARY,period PRIMARY 4 const 1
+select fld3,period from t2,t1 where companynr*10 = 37*10;
fld3 period
breaking 9410
Romans 9410
@@ -1088,6 +1216,7 @@ dusted 9410
encompasses 9410
presentation 9410
Kantian 9410
+select fld3,period,price,price2 from t2,t3 where t2.fld1=t3.t2nr and period >= 1001 and period <= 1002 and t2.companynr = 37 order by fld3,period, price;
fld3 period price price2
admonishing 1002 28357832 8723648
analyzable 1002 28357832 8723648
@@ -1148,11 +1277,20 @@ ventilate 1001 5987435 234724
wallet 1001 5987435 234724
Weissmuller 1002 28357832 8723648
Wotan 1002 28357832 8723648
+select t2.fld1,fld3,period,price,price2 from t2,t3 where t2.fld1>= 18201 and t2.fld1 <= 18811 and t2.fld1=t3.t2nr and period = 1001 and t2.companynr = 37;
fld1 fld3 period price price2
018201 relaxing 1001 5987435 234724
018601 vacuuming 1001 5987435 234724
018801 inch 1001 5987435 234724
018811 repetitions 1001 5987435 234724
+drop table if exists company;
+create table t4 (
+companynr tinyint(2) unsigned zerofill NOT NULL default '00',
+companyname char(30) NOT NULL default '',
+PRIMARY KEY (companynr),
+UNIQUE KEY companyname(companyname)
+) TYPE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames';
+select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr;
companynr companyname
00 Unknown
29 company 1
@@ -1166,6 +1304,7 @@ companynr companyname
58 company 8
65 company 9
68 company 10
+select SQL_SMALL_RESULT t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr;
companynr companyname
00 Unknown
29 company 1
@@ -1179,8 +1318,10 @@ companynr companyname
58 company 8
65 company 9
68 company 10
+select * from t1,t1 t12;
Period Varor_period Period Varor_period
9410 9412 9410 9412
+select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 250505 and t22.fld1 >= 250501 and t22.fld1 <= 250505;
fld1 fld1
250501 250501
250502 250501
@@ -1207,44 +1348,88 @@ fld1 fld1
250503 250505
250504 250505
250505 250505
+insert into t2 (fld1, companynr) values (999999,99);
+select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
companynr companyname
+99 NULL
+select count(*) from t2 left join t4 using (companynr) where t4.companynr is not null;
+count(*)
+1199
+explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
table type possible_keys key key_len ref rows Extra
-t2 ALL NULL NULL NULL NULL 1199
-t4 eq_ref PRIMARY PRIMARY 1 t2.companynr 1 where used; Not exists
+t2 ALL NULL NULL NULL NULL 1200
+t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where; Not exists
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null;
+table type possible_keys key key_len ref rows Extra
+t4 ALL NULL NULL NULL NULL 12
+t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists
+delete from t2 where fld1=999999;
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0;
+table type possible_keys key key_len ref rows Extra
+t2 ALL NULL NULL NULL NULL 1199 Using where
+t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0;
+table type possible_keys key key_len ref rows Extra
+t2 ALL NULL NULL NULL NULL 1199 Using where
+t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0;
+table type possible_keys key key_len ref rows Extra
+t2 ALL NULL NULL NULL NULL 1199 Using where
+t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
+table type possible_keys key key_len ref rows Extra
+t4 ALL NULL NULL NULL NULL 12
+t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0;
+table type possible_keys key key_len ref rows Extra
+t4 ALL PRIMARY NULL NULL NULL 12
+t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0;
table type possible_keys key key_len ref rows Extra
t4 ALL NULL NULL NULL NULL 12
-t2 ALL NULL NULL NULL NULL 1199 where used; Not exists
+t2 ALL NULL NULL NULL NULL 1199 Using where
+select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
41 40
+explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
table type possible_keys key key_len ref rows Extra
t2 ALL NULL NULL NULL NULL 1199 Using temporary
-t4 index NULL PRIMARY 1 NULL 12 where used; Using index
+t4 index NULL PRIMARY 1 NULL 12 Using where; Using index
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
fld1 companynr fld3 period
038008 37 reporters 1008
038208 37 Selfridge 1008
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t2.fld1 = 38208 or t2.fld1 = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009;
fld1 companynr fld3 period
038008 37 reporters 1008
038208 37 Selfridge 1008
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t3.t2nr = 38208 or t3.t2nr = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009;
fld1 companynr fld3 period
038008 37 reporters 1008
038208 37 Selfridge 1008
+select period from t1 where (((period > 0) or period < 10000 or (period = 1900)) and (period=1900 and period <= 1901) or (period=1903 and (period=1903)) and period>=1902) or ((period=1904 or period=1905) or (period=1906 or period>1907)) or (period=1908 and period = 1909);
period
9410
+select period from t1 where ((period > 0 and period < 1) or (((period > 0 and period < 100) and (period > 10)) or (period > 10)) or (period > 0 and (period > 5 or period > 6)));
period
9410
+select a.fld1 from t2 as a,t2 b where ((a.fld1 = 250501 and a.fld1=b.fld1) or a.fld1=250502 or a.fld1=250503 or (a.fld1=250505 and a.fld1<=b.fld1 and b.fld1>=a.fld1)) and a.fld1=b.fld1;
fld1
250501
250502
250503
250505
+select fld1 from t2 where fld1 in (250502,98005,98006,250503,250605,250606) and fld1 >=250502 and fld1 not in (250605,250606);
fld1
250502
250503
+select fld1 from t2 where fld1 between 250502 and 250504;
fld1
250502
250503
250504
+select fld3 from t2 where (((fld3 like "_%L%" ) or (fld3 like "%ok%")) and ( fld3 like "L%" or fld3 like "G%")) and fld3 like "L%" ;
fld3
label
labeled
@@ -1255,8 +1440,10 @@ leaflet
lewdly
Lillian
luckily
+select count(*) from t1;
count(*)
1
+select companynr,count(*),sum(fld1) from t2 group by companynr;
companynr count(*) sum(fld1)
00 82 10355753
29 95 14473298
@@ -1270,18 +1457,22 @@ companynr count(*) sum(fld1)
58 23 2254293
65 10 2284055
68 12 3097288
+select companynr,count(*) from t2 group by companynr order by companynr desc limit 5;
companynr count(*)
68 12
65 10
58 23
53 4
50 11
+select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1) from t2 where companynr = 34 and fld4<>"";
count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1)
70 absentee vest 17788966 254128.0857 3272.5940
+select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1) from t2 group by companynr limit 3;
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1)
00 82 Anthony windmills 10355753 126289.6707 115550.9757
29 95 abut wetness 14473298 152350.5053 8368.5480
34 70 absentee vest 17788966 254128.0857 3272.5940
+select companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
37 1 1 5987435 5987435 5987435 5987435.0000
37 2 1 28357832 28357832 28357832 28357832.0000
@@ -1293,6 +1484,7 @@ companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
37 22 1 28357832 28357832 28357832 28357832.0000
37 23 1 39654943 39654943 39654943 39654943.0000
37 31 1 5987435 5987435 5987435 5987435.0000
+select /*! SQL_SMALL_RESULT */ companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
37 1 1 5987435 5987435 5987435 5987435.0000
37 2 1 28357832 28357832 28357832 28357832.0000
@@ -1304,6 +1496,7 @@ companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
37 22 1 28357832 28357832 28357832 28357832.0000
37 23 1 39654943 39654943 39654943 39654943.0000
37 31 1 5987435 5987435 5987435 5987435.0000
+select companynr,count(price),sum(price),min(price),max(price),avg(price) from t3 group by companynr ;
companynr count(price) sum(price) min(price) max(price) avg(price)
37 12543 309394878010 5987435 39654943 24666736.6667
78 8362 414611089292 726498 98439034 49582766.0000
@@ -1312,6 +1505,7 @@ companynr count(price) sum(price) min(price) max(price) avg(price)
311 4181 979599938 234298 234298 234298.0000
447 4181 9929180954 2374834 2374834 2374834.0000
512 4181 3288532102 786542 786542 786542.0000
+select distinct mod(companynr,10) from t4 group by companynr;
mod(companynr,10)
0
9
@@ -1322,10 +1516,13 @@ mod(companynr,10)
3
8
5
+select distinct 1 from t4 group by companynr;
1
1
+select count(distinct fld1) from t2;
count(distinct fld1)
1199
+select companynr,count(distinct fld1) from t2 group by companynr;
companynr count(distinct fld1)
00 82
29 95
@@ -1339,6 +1536,7 @@ companynr count(distinct fld1)
58 23
65 10
68 12
+select companynr,count(*) from t2 group by companynr;
companynr count(*)
00 82
29 95
@@ -1352,6 +1550,7 @@ companynr count(*)
58 23
65 10
68 12
+select companynr,count(distinct concat(fld1,repeat(65,1000))) from t2 group by companynr;
companynr count(distinct concat(fld1,repeat(65,1000)))
00 82
29 95
@@ -1365,6 +1564,7 @@ companynr count(distinct concat(fld1,repeat(65,1000)))
58 23
65 10
68 12
+select companynr,count(distinct concat(fld1,repeat(65,200))) from t2 group by companynr;
companynr count(distinct concat(fld1,repeat(65,200)))
00 82
29 95
@@ -1378,6 +1578,7 @@ companynr count(distinct concat(fld1,repeat(65,200)))
58 23
65 10
68 12
+select companynr,count(distinct floor(fld1/100)) from t2 group by companynr;
companynr count(distinct floor(fld1/100))
00 47
29 35
@@ -1391,6 +1592,7 @@ companynr count(distinct floor(fld1/100))
58 1
65 1
68 1
+select companynr,count(distinct concat(repeat(65,1000),floor(fld1/100))) from t2 group by companynr;
companynr count(distinct concat(repeat(65,1000),floor(fld1/100)))
00 47
29 35
@@ -1404,16 +1606,22 @@ companynr count(distinct concat(repeat(65,1000),floor(fld1/100)))
58 1
65 1
68 1
+select sum(fld1),fld3 from t2 where fld3="Romans" group by fld1 limit 10;
sum(fld1) fld3
11402 Romans
+select name,count(*) from t3 where name='cloakroom' group by name;
name count(*)
cloakroom 4181
+select name,count(*) from t3 where name='cloakroom' and price>10 group by name;
name count(*)
cloakroom 4181
+select count(*) from t3 where name='cloakroom' and price2=823742;
count(*)
4181
+select name,count(*) from t3 where name='cloakroom' and price2=823742 group by name;
name count(*)
cloakroom 4181
+select name,count(*) from t3 where name >= "extramarital" and price <= 39654943 group by name;
name count(*)
extramarital 4181
gazer 4181
@@ -1422,8 +1630,10 @@ Iranizes 4181
spates 4181
tucked 4181
violinist 4181
+select t2.fld3,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name;
fld3 count(*)
spates 4181
+select companynr|0,companyname from t4 group by 1;
companynr|0 companyname
0 Unknown
29 company 1
@@ -1437,6 +1647,7 @@ companynr|0 companyname
58 company 8
65 company 9
68 company 10
+select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by t2.companynr order by companyname;
companynr companyname count(*)
29 company 1 95
68 company 10 12
@@ -1450,10 +1661,13 @@ companynr companyname count(*)
58 company 8 23
65 company 9 10
00 Unknown 82
+select t2.fld1,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name;
fld1 count(*)
158402 4181
+select sum(Period)/count(*) from t1;
sum(Period)/count(*)
9410.00
+select companynr,count(price) as "count",sum(price) as "sum" ,abs(sum(price)/count(price)-avg(price)) as "diff",(0+count(price))*companynr as func from t3 group by companynr;
companynr count sum diff func
37 12543 309394878010 0.0000 464091
78 8362 414611089292 0.0000 652236
@@ -1462,8 +1676,10 @@ companynr count sum diff func
311 4181 979599938 0.0000 1300291
447 4181 9929180954 0.0000 1868907
512 4181 3288532102 0.0000 2140672
+select companynr,sum(price)/count(price) as avg from t3 group by companynr having avg > 70000000 order by avg;
companynr avg
154 983543950.00
+select companynr,count(*) from t2 group by companynr order by 2 desc;
companynr count(*)
37 588
36 215
@@ -1477,6 +1693,7 @@ companynr count(*)
50 11
65 10
53 4
+select companynr,count(*) from t2 where companynr > 40 group by companynr order by 2 desc;
companynr count(*)
41 52
58 23
@@ -1484,6 +1701,7 @@ companynr count(*)
50 11
65 10
53 4
+select t2.fld4,t2.fld1,count(price),sum(price),min(price),max(price),avg(price) from t3,t2 where t3.companynr = 37 and t2.fld1 = t3.t2nr group by fld1,t2.fld4;
fld4 fld1 count(price) sum(price) min(price) max(price) avg(price)
teethe 000001 1 5987435 5987435 5987435 5987435.0000
dreaded 011401 1 5987435 5987435 5987435 5987435.0000
@@ -1572,6 +1790,7 @@ partridges 038103 1 39654943 39654943 39654943 39654943.0000
recruited 038201 1 5987435 5987435 5987435 5987435.0000
dimensions 038202 1 28357832 28357832 28357832 28357832.0000
Chicana 038203 1 39654943 39654943 39654943 39654943.0000
+select t3.companynr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 group by companynr,fld3;
companynr fld3 sum(price)
512 boat 786542
512 capably 786542
@@ -1583,11 +1802,13 @@ companynr fld3 sum(price)
512 Micronesia 786542
512 Miles 786542
512 skies 786542
+select t2.companynr,count(*),min(fld3),max(fld3),sum(price),avg(price) from t2,t3 where t3.companynr >= 30 and t3.companynr <= 58 and t3.t2nr = t2.fld1 and 1+1=2 group by t2.companynr;
companynr count(*) min(fld3) max(fld3) sum(price) avg(price)
00 1 Omaha Omaha 5987435 5987435.0000
36 1 dubbed dubbed 28357832 28357832.0000
37 83 Abraham Wotan 1908978016 22999735.1325
50 2 scribbled tapestry 68012775 34006387.5000
+select t3.companynr+0,t3.t2nr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 37 group by 1,t3.t2nr,fld3,fld3,fld3,fld3,fld3 order by fld1;
t3.companynr+0 t2nr fld3 sum(price)
37 1 Omaha 5987435
37 11401 breaking 5987435
@@ -1676,32 +1897,41 @@ t3.companynr+0 t2nr fld3 sum(price)
37 38201 resumes 5987435
37 38202 analyzable 28357832
37 38203 terminator 39654943
+select sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1= t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008;
sum(price)
234298
+select t2.fld1,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1 = t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008 or t3.t2nr = t2.fld1 and t2.fld1 = 38008 group by t2.fld1;
fld1 sum(price)
038008 234298
+explain select fld3 from t2 where 1>2 or 2>3;
Comment
Impossible WHERE
+explain select fld3 from t2 where fld1=fld1;
table type possible_keys key key_len ref rows Extra
t2 ALL NULL NULL NULL NULL 1199
+select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502;
companynr fld1
34 250501
34 250502
+select companynr,fld1 from t2 WHERE fld1>=250501 HAVING fld1<=250502;
companynr fld1
34 250501
34 250502
+select companynr,count(*) as count,sum(fld1) as sum from t2 group by companynr having count > 40 and sum/count >= 120000;
companynr count sum
00 82 10355753
29 95 14473298
34 70 17788966
37 588 83602098
41 52 12816335
+select companynr from t2 group by companynr having count(*) > 40 and sum(fld1)/count(*) >= 120000 ;
companynr
00
29
34
37
41
+select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by companyname having t2.companynr >= 40;
companynr companyname count(*)
68 company 10 12
50 company 11 11
@@ -1710,26 +1940,37 @@ companynr companyname count(*)
53 company 7 4
58 company 8 23
65 company 9 10
+select count(*) from t2;
count(*)
1199
+select count(*) from t2 where fld1 < 098024;
count(*)
387
+select min(fld1) from t2 where fld1>= 098024;
min(fld1)
98024
+select max(fld1) from t2 where fld1>= 098024;
max(fld1)
1232609
+select count(*) from t3 where price2=76234234;
count(*)
4181
+select count(*) from t3 where companynr=512 and price2=76234234;
count(*)
4181
+explain select min(fld1),max(fld1),count(*) from t2;
Comment
Select tables optimized away
+select min(fld1),max(fld1),count(*) from t2;
min(fld1) max(fld1) count(*)
0 1232609 1199
+select min(t2nr),max(t2nr) from t3 where t2nr=2115 and price2=823742;
min(t2nr) max(t2nr)
2115 2115
+select count(*),min(t2nr),max(t2nr) from t3 where name='spates' and companynr=78;
count(*) min(t2nr) max(t2nr)
4181 4 41804
+select t2nr,count(*) from t3 where name='gems' group by t2nr limit 20;
t2nr count(*)
9 1
19 1
@@ -1751,29 +1992,41 @@ t2nr count(*)
179 1
189 1
199 1
+select max(t2nr) from t3 where price=983543950;
max(t2nr)
41807
+select t1.period from t3 = t1 limit 1;
period
1001
+select t1.period from t1 as t1 limit 1;
period
9410
+select t1.period as "Nuvarande period" from t1 as t1 limit 1;
Nuvarande period
9410
+select period as ok_period from t1 limit 1;
ok_period
9410
+select period as ok_period from t1 group by ok_period limit 1;
ok_period
9410
+select 1+1 as summa from t1 group by summa limit 1;
summa
2
+select period as "Nuvarande period" from t1 group by "Nuvarande period" limit 1;
Nuvarande period
9410
+show tables;
Tables_in_test
t1
t2
t3
t4
+show tables from test like "s%";
Tables_in_test (s%)
+show tables from test like "t?";
Tables_in_test (t?)
+show full columns from t2;
Field Type Null Key Default Extra Privileges
auto int(11) PRI NULL auto_increment select,insert,update,references
fld1 int(6) unsigned zerofill UNI 000000 select,insert,update,references
@@ -1782,15 +2035,295 @@ fld3 char(30) MUL select,insert,update,references
fld4 char(35) select,insert,update,references
fld5 char(35) select,insert,update,references
fld6 char(4) select,insert,update,references
+show full columns from t2 from test like 'f%';
Field Type Null Key Default Extra Privileges
fld1 int(6) unsigned zerofill UNI 000000 select,insert,update,references
fld3 char(30) MUL select,insert,update,references
fld4 char(35) select,insert,update,references
fld5 char(35) select,insert,update,references
fld6 char(4) select,insert,update,references
+show full columns from t2 from test like 's%';
Field Type Null Key Default Extra Privileges
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t2 0 PRIMARY 1 auto A 1199 NULL NULL
-t2 0 fld1 1 fld1 A 1199 NULL NULL
-t2 1 fld3 1 fld3 A NULL NULL NULL
-1
+show keys from t2;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE
+t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE
+t2 1 fld3 1 fld3 A NULL NULL NULL BTREE
+drop table t4, t3, t2, t1;
+DO 1;
+DO benchmark(100,1+1),1,1;
+CREATE TABLE t1 (
+id mediumint(8) unsigned NOT NULL auto_increment,
+pseudo varchar(35) NOT NULL default '',
+PRIMARY KEY (id),
+UNIQUE KEY pseudo (pseudo)
+);
+INSERT INTO t1 (pseudo) VALUES ('test');
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 1 as rnd1 from t1 where rand() > 2;
+rnd1
+DROP TABLE t1;
+CREATE TABLE t1 (gvid int(10) unsigned default NULL, hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, mmid int(10) unsigned default NULL, hdid int(10) unsigned default NULL, fsid int(10) unsigned default NULL, ctid int(10) unsigned default NULL, dtid int(10) unsigned default NULL, cost int(10) unsigned default NULL, performance int(10) unsigned default NULL, serialnumber bigint(20) unsigned default NULL, monitored tinyint(3) unsigned default '1', removed tinyint(3) unsigned default '0', target tinyint(3) unsigned default '0', dt_modified timestamp(14) NOT NULL, name varchar(255) binary default NULL, description varchar(255) default NULL, UNIQUE KEY hmid (hmid,volid)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (200001,2,1,1,100,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\E$',''),(200002,2,2,1,101,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\C$',''),(200003,1,3,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,0,1,20020425060427,'c:',NULL);
+CREATE TABLE t2 ( hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, sampletid smallint(5) unsigned default NULL, sampletime datetime default NULL, samplevalue bigint(20) unsigned default NULL, KEY idx1 (hmid,volid,sampletid,sampletime)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12:00:01',35);
+SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'NULL' AND b.sampletime < 'NULL' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid;
+gvid the_success the_fail the_size the_time
+DROP TABLE t1,t2;
+create table t1 ( A_Id bigint(20) NOT NULL default '0', A_UpdateBy char(10) NOT NULL default '', A_UpdateDate bigint(20) NOT NULL default '0', A_UpdateSerial int(11) NOT NULL default '0', other_types bigint(20) NOT NULL default '0', wss_type bigint(20) NOT NULL default '0');
+INSERT INTO t1 VALUES (102935998719055004,'brade',1029359987,2,102935229116544068,102935229216544093);
+select wss_type from t1 where wss_type ='102935229216544106';
+wss_type
+select wss_type from t1 where wss_type ='102935229216544105';
+wss_type
+select wss_type from t1 where wss_type ='102935229216544104';
+wss_type
+select wss_type from t1 where wss_type ='102935229216544093';
+wss_type
+102935229216544093
+select wss_type from t1 where wss_type =102935229216544093;
+wss_type
+102935229216544093
+drop table t1;
+create table t1 (a int not null auto_increment primary key);
+insert into t1 values ();
+insert into t1 values ();
+insert into t1 values ();
+select * from (t1 as t2 left join t1 as t3 using (a)), t1;
+a a a
+1 1 1
+2 2 1
+3 3 1
+1 1 2
+2 2 2
+3 3 2
+1 1 3
+2 2 3
+3 3 3
+select * from t1, (t1 as t2 left join t1 as t3 using (a));
+a a a
+1 1 1
+2 1 1
+3 1 1
+1 2 2
+2 2 2
+3 2 2
+1 3 3
+2 3 3
+3 3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) straight_join t1;
+a a a
+1 1 1
+2 2 1
+3 3 1
+1 1 2
+2 2 2
+3 3 2
+1 1 3
+2 2 3
+3 3 3
+select * from t1 straight_join (t1 as t2 left join t1 as t3 using (a));
+a a a
+1 1 1
+2 1 1
+3 1 1
+1 2 2
+2 2 2
+3 2 2
+1 3 3
+2 3 3
+3 3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1;
+a a a
+1 1 2
+1 1 3
+2 2 2
+2 2 3
+3 3 2
+3 3 3
+select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a a
+1 1 NULL
+2 1 1
+3 1 1
+1 2 NULL
+2 2 2
+3 2 2
+1 3 NULL
+2 3 3
+3 3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 using ( a );
+a a a
+1 1 1
+2 2 2
+3 3 3
+select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+a a a
+1 1 1
+2 1 NULL
+3 1 NULL
+1 2 NULL
+2 2 2
+3 2 NULL
+1 3 NULL
+2 3 NULL
+3 3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) left outer join t1 on t1.a>1;
+a a a
+1 1 2
+1 1 3
+2 2 2
+2 2 3
+3 3 2
+3 3 3
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a a
+1 1 NULL
+2 1 1
+3 1 1
+1 2 NULL
+2 2 2
+3 2 2
+1 3 NULL
+2 3 3
+3 3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) left join t1 using ( a );
+a a a
+1 1 1
+2 2 2
+3 3 3
+select * from t1 left join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+a a a
+1 1 1
+2 1 NULL
+3 1 NULL
+1 2 NULL
+2 2 2
+3 2 NULL
+1 3 NULL
+2 3 NULL
+3 3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
+a a a
+1 1 1
+2 2 2
+3 3 3
+select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a));
+a a a
+1 1 1
+2 2 2
+3 3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1;
+a a a
+1 NULL 1
+2 NULL 1
+3 NULL 1
+1 1 2
+2 2 2
+3 3 2
+1 1 3
+2 2 3
+3 3 3
+select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+a a a
+2 1 1
+3 1 1
+2 2 2
+3 2 2
+2 3 3
+3 3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a );
+a a a
+1 1 1
+2 NULL 1
+3 NULL 1
+1 NULL 2
+2 2 2
+3 NULL 2
+1 NULL 3
+2 NULL 3
+3 3 3
+select * from t1 right outer join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+a a a
+1 1 1
+2 2 2
+3 3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) natural right join t1;
+a a a
+1 1 1
+2 NULL 1
+3 NULL 1
+1 NULL 2
+2 2 2
+3 NULL 2
+1 NULL 3
+2 NULL 3
+3 3 3
+select * from t1 natural right join (t1 as t2 left join t1 as t3 using (a));
+a a a
+1 1 1
+2 2 2
+3 3 3
+select * from t1 natural join (t1 as t2 left join t1 as t3 using (a));
+a a a
+1 1 1
+2 2 2
+3 3 3
+select * from (t1 as t2 left join t1 as t3 using (a)) natural join t1;
+a a a
+1 1 1
+2 2 2
+3 3 3
+drop table t1;
+CREATE TABLE t1 ( aa char(2), id int(11) NOT NULL auto_increment, t2_id int(11) NOT NULL default '0', PRIMARY KEY (id), KEY replace_id (t2_id)) TYPE=MyISAM;
+INSERT INTO t1 VALUES ("1",8264,2506),("2",8299,2517),("3",8301,2518),("4",8302,2519),("5",8303,2520),("6",8304,2521),("7",8305,2522);
+CREATE TABLE t2 ( id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (2517), (2518), (2519), (2520), (2521), (2522);
+select * from t1, t2 WHERE t1.t2_id = t2.id and t1.t2_id > 0 order by t1.id LIMIT 0, 5;
+aa id t2_id id
+2 8299 2517 2517
+3 8301 2518 2518
+4 8302 2519 2519
+5 8303 2520 2520
+6 8304 2521 2521
+drop table t1,t2;
+create table t1 (id1 int NOT NULL);
+create table t2 (id2 int NOT NULL);
+create table t3 (id3 int NOT NULL);
+create table t4 (id4 int NOT NULL, id44 int NOT NULL, KEY (id4));
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t2 values (1);
+insert into t4 values (1,1);
+explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
+left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
+table type possible_keys key key_len ref rows Extra
+t3 system NULL NULL NULL NULL 0 const row not found
+t1 ALL NULL NULL NULL NULL 2
+t2 ALL NULL NULL NULL NULL 1
+t4 ALL id4 NULL NULL NULL 1 Using where
+select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
+left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
+id1 id2 id3 id4 id44
+1 1 NULL NULL NULL
+drop table t1,t2,t3,t4;
+create table t1(s varchar(10) not null);
+create table t2(s varchar(10) not null primary key);
+create table t3(s varchar(10) not null primary key);
+insert into t1 values ('one\t'), ('two\t');
+insert into t2 values ('one\r'), ('two\t');
+insert into t3 values ('one '), ('two\t');
+select * from t1 where s = 'one';
+s
+select * from t2 where s = 'one';
+s
+select * from t3 where s = 'one';
+s
+one
+select * from t1,t2 where t1.s = t2.s;
+s s
+two two
+select * from t2,t3 where t2.s = t3.s;
+s s
+two two
+drop table t1, t2, t3;
diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result
new file mode 100644
index 00000000000..419ffb73d59
--- /dev/null
+++ b/mysql-test/r/select_found.result
@@ -0,0 +1,190 @@
+drop table if exists t1,t2;
+create table t1 (a int not null auto_increment, b int not null, primary key(a));
+insert into t1 (b) values (2),(3),(5),(5),(5),(6),(7),(9);
+select SQL_CALC_FOUND_ROWS * from t1;
+a b
+1 2
+2 3
+3 5
+4 5
+5 5
+6 6
+7 7
+8 9
+select found_rows();
+found_rows()
+8
+select SQL_CALC_FOUND_ROWS * from t1 limit 1;
+a b
+1 2
+select found_rows();
+found_rows()
+8
+select SQL_BUFFER_RESULT SQL_CALC_FOUND_ROWS * from t1 limit 1;
+a b
+1 2
+select found_rows();
+found_rows()
+8
+select SQL_CALC_FOUND_ROWS * from t1 order by b desc limit 1;
+a b
+8 9
+select found_rows();
+found_rows()
+8
+select SQL_CALC_FOUND_ROWS distinct b from t1 limit 1;
+b
+2
+select found_rows();
+found_rows()
+6
+select SQL_CALC_FOUND_ROWS b,count(*) as c from t1 group by b order by c desc limit 1;
+b c
+5 3
+select found_rows();
+found_rows()
+6
+select SQL_CALC_FOUND_ROWS * from t1 left join t1 as t2 on (t1.b=t2.a) limit 2,1;
+a b a b
+3 5 5 5
+select found_rows();
+found_rows()
+8
+drop table t1;
+create table t1 (a int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+select sql_calc_found_rows a from t1 where a in (1,2,3) order by a desc limit 0,2;
+a
+3
+2
+select FOUND_ROWS();
+FOUND_ROWS()
+3
+select sql_calc_found_rows a from t1 where a in (1,2,3) order by a+2 desc limit 0,2;
+a
+3
+2
+select FOUND_ROWS();
+FOUND_ROWS()
+3
+drop table t1;
+CREATE TABLE t1 (
+`id` smallint(5) unsigned NOT NULL auto_increment,
+`kid` smallint(5) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+KEY `kid` (`kid`)
+);
+CREATE TABLE t2 (
+id smallint(5) unsigned NOT NULL auto_increment,
+name varchar(50) NOT NULL default '',
+email varchar(50) NOT NULL default '',
+PRIMARY KEY (id),
+UNIQUE KEY e_n (email,name)
+);
+INSERT INTO t2 VALUES (1,'name1','email1'),(2,'name2','email2'),(3,'name3','email3'),(4,'name4','email4'),(5,'name5','email5'),(6,'name6','email6'),(7,'name7','email7'),(8,'name8','email8'),(9,'name9','email9'),(10,'name10','email10'),(11,'name11','email11'),(12,'name12','email12'),(13,'name13','email13'),(14,'name14','email14'),(15,'name15','email15'),(16,'name16','email16'),(17,'name17','email17'),(18,'name18','email18'),(19,'name19','email19'),(20,'name20','email20'),(21,'name21','email21'),(22,'name22','email22'),(23,'name23','email23'),(24,'name24','email24'),(25,'name25','email25'),(26,'name26','email26'),(27,'name27','email27'),(28,'name28','email28'),(29,'name29','email29'),(30,'name30','email30'),(31,'name31','email31'),(32,'name32','email32'),(33,'name33','email33'),(34,'name34','email34'),(35,'name35','email35'),(36,'name36','email36'),(37,'name37','email37'),(38,'name38','email38'),(39,'name39','email39'),(40,'name40','email40'),(41,'name41','email41'),(42,'name42','email42'),(43,'name43','email43'),(44,'name44','email44'),(45,'name45','email45'),(46,'name46','email46'),(47,'name47','email47'),(48,'name48','email48'),(49,'name49','email49'),(50,'name50','email50'),(51,'name51','email51'),(52,'name52','email52'),(53,'name53','email53'),(54,'name54','email54'),(55,'name55','email55'),(56,'name56','email56'),(57,'name57','email57'),(58,'name58','email58'),(59,'name59','email59'),(60,'name60','email60'),(61,'name61','email61'),(62,'name62','email62'),(63,'name63','email63'),(64,'name64','email64'),(65,'name65','email65'),(66,'name66','email66'),(67,'name67','email67'),(68,'name68','email68'),(69,'name69','email69'),(70,'name70','email70'),(71,'name71','email71'),(72,'name72','email72'),(73,'name73','email73'),(74,'name74','email74'),(75,'name75','email75'),(76,'name76','email76'),(77,'name77','email77'),(78,'name78','email78'),(79,'name79','email79'),(80,'name80','email80'),(81,'name81','email81'),(82,'name82','email82'),(83,'name83','email83'),(84,'name84','email84'),(85,'name85','email85'),(86,'name86','email86'),(87,'name87','email87'),(88,'name88','email88'),(89,'name89','email89'),(90,'name90','email90'),(91,'name91','email91'),(92,'name92','email92'),(93,'name93','email93'),(94,'name94','email94'),(95,'name95','email95'),(96,'name96','email96'),(97,'name97','email97'),(98,'name98','email98'),(99,'name99','email99'),(100,'name100','email100'),(101,'name101','email101'),(102,'name102','email102'),(103,'name103','email103'),(104,'name104','email104'),(105,'name105','email105'),(106,'name106','email106'),(107,'name107','email107'),(108,'name108','email108'),(109,'name109','email109'),(110,'name110','email110'),(111,'name111','email111'),(112,'name112','email112'),(113,'name113','email113'),(114,'name114','email114'),(115,'name115','email115'),(116,'name116','email116'),(117,'name117','email117'),(118,'name118','email118'),(119,'name119','email119'),(120,'name120','email120'),(121,'name121','email121'),(122,'name122','email122'),(123,'name123','email123'),(124,'name124','email124'),(125,'name125','email125'),(126,'name126','email126'),(127,'name127','email127'),(128,'name128','email128'),(129,'name129','email129'),(130,'name130','email130'),(131,'name131','email131'),(132,'name132','email132'),(133,'name133','email133'),(134,'name134','email134'),(135,'name135','email135'),(136,'name136','email136'),(137,'name137','email137'),(138,'name138','email138'),(139,'name139','email139'),(140,'name140','email140'),(141,'name141','email141'),(142,'name142','email142'),(143,'name143','email143'),(144,'name144','email144'),(145,'name145','email145'),(146,'name146','email146'),(147,'name147','email147'),(148,'name148','email148'),(149,'name149','email149'),(150,'name150','email150'),(151,'name151','email151'),(152,'name152','email152'),(153,'name153','email153'),(154,'name154','email154'),(155,'name155','email155'),(156,'name156','email156'),(157,'name157','email157'),(158,'name158','email158'),(159,'name159','email159'),(160,'name160','email160'),(161,'name161','email161'),(162,'name162','email162'),(163,'name163','email163'),(164,'name164','email164'),(165,'name165','email165'),(166,'name166','email166'),(167,'name167','email167'),(168,'name168','email168'),(169,'name169','email169'),(170,'name170','email170'),(171,'name171','email171'),(172,'name172','email172'),(173,'name173','email173'),(174,'name174','email174'),(175,'name175','email175'),(176,'name176','email176'),(177,'name177','email177'),(178,'name178','email178'),(179,'name179','email179'),(180,'name180','email180'),(181,'name181','email181'),(182,'name182','email182'),(183,'name183','email183'),(184,'name184','email184'),(185,'name185','email185'),(186,'name186','email186'),(187,'name187','email187'),(188,'name188','email188'),(189,'name189','email189'),(190,'name190','email190'),(191,'name191','email191'),(192,'name192','email192'),(193,'name193','email193'),(194,'name194','email194'),(195,'name195','email195'),(196,'name196','email196'),(197,'name197','email197'),(198,'name198','email198'),(199,'name199','email199'),(200,'name200','email200');
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+email
+email1
+email10
+email100
+email101
+email102
+email103
+email104
+email105
+email106
+email107
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+200
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL order by email LIMIT 10;
+email
+email1
+email10
+email100
+email101
+email102
+email103
+email104
+email105
+email106
+email107
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+200
+SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+email
+email1
+email2
+email3
+email4
+email5
+email6
+email7
+email8
+email9
+email10
+SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL ORDER BY email LIMIT 10;
+email
+email1
+email10
+email100
+email101
+email102
+email103
+email104
+email105
+email106
+email107
+INSERT INTO `t1` (`id`, `kid`) VALUES ('', '150');
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+email
+email1
+email2
+email3
+email4
+email5
+email6
+email7
+email8
+email9
+email10
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+199
+drop table t1,t2;
+CREATE TABLE `t1` (
+`titre` char(80) NOT NULL default '',
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+KEY `maxnumrep` (`maxnumrep`)
+) TYPE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (titre,maxnumrep) VALUES
+('test1','1'),('test2','2'),('test3','3');
+SELECT SQL_CALC_FOUND_ROWS titre,numeropost,maxnumrep FROM t1 WHERE numeropost IN (1,2) ORDER BY maxnumrep DESC LIMIT 0, 1;
+titre numeropost maxnumrep
+test2 2 2
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+2
+drop table t1;
+create table t1 (id int, primary key (id));
+insert into t1 values (1), (2), (3), (4), (5);
+select SQL_CALC_FOUND_ROWS * from t1 where id > 3 limit 0, 1;
+id
+4
+select FOUND_ROWS();
+FOUND_ROWS()
+2
+select SQL_CALC_FOUND_ROWS * from t1 where id > 3 AND 1=2 limit 0, 1;
+id
+select FOUND_ROWS();
+FOUND_ROWS()
+0
+select SQL_CALC_FOUND_ROWS * from t1 where id > 6 limit 0, 1;
+id
+select FOUND_ROWS();
+FOUND_ROWS()
+0
+drop table t1;
diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result
index 1111ba00cd9..1ee1368d029 100644
--- a/mysql-test/r/select_safe.result
+++ b/mysql-test/r/select_safe.result
@@ -1,10 +1,81 @@
+drop table if exists t1;
+SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=4, SQL_MAX_JOIN_SIZE=9;
+create table t1 (a int auto_increment primary key, b char(20));
+insert into t1 values(1,"test");
+SELECT SQL_BUFFER_RESULT * from t1;
a b
1 test
+update t1 set b="a" where a=1;
+delete from t1 where a=1;
+insert into t1 values(1,"test"),(2,"test2");
+SELECT SQL_BUFFER_RESULT * from t1;
a b
1 test
2 test2
+update t1 set b="a" where a=1;
+select 1 from t1,t1 as t2,t1 as t3;
1
1
1
1
1
+update t1 set b="a";
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+update t1 set b="a" where b="test";
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+delete from t1;
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+delete from t1 where b="test";
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+delete from t1 where a+0=1;
+You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
+select 1 from t1,t1 as t2,t1 as t3,t1 as t4,t1 as t5;
+The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok
+update t1 set b="a" limit 1;
+update t1 set b="a" where b="b" limit 2;
+delete from t1 where b="test" limit 1;
+delete from t1 where a+0=1 limit 2;
+alter table t1 add key b (b);
+SET MAX_JOIN_SIZE=2;
+SELECT @@MAX_JOIN_SIZE, @@SQL_BIG_SELECTS;
+@@max_join_size @@sql_big_selects
+2 0
+insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a");
+SELECT * from t1 order by a;
+The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok
+SET SQL_BIG_SELECTS=1;
+SELECT * from t1 order by a;
+a b
+2 test2
+3 a
+4 a
+5 a
+SET MAX_JOIN_SIZE=2;
+SELECT * from t1;
+The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok
+SET MAX_JOIN_SIZE=DEFAULT;
+SELECT * from t1;
+a b
+2 test2
+3 a
+4 a
+5 a
+SELECT @@MAX_SEEKS_FOR_KEY;
+@@max_seeks_for_key
+4294967295
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a");
+explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
+table type possible_keys key key_len ref rows Extra
+t1 ALL b NULL NULL NULL 21
+t2 ref b b 21 t1.b 6 Using where
+set MAX_SEEKS_FOR_KEY=1;
+explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
+table type possible_keys key key_len ref rows Extra
+t1 ALL b NULL NULL NULL 21
+t2 ref b b 21 t1.b 6 Using where
+SET MAX_SEEKS_FOR_KEY=DEFAULT;
+drop table t1;
+SET SQL_SAFE_UPDATES=0,SQL_SELECT_LIMIT=DEFAULT, SQL_MAX_JOIN_SIZE=DEFAULT;
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index 44e2b2ec1c9..f40b0693585 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -1,97 +1,153 @@
-Table Op Msg_type Msg_text
-test.t1 optimize status OK
-Table Op Msg_type Msg_text
-test.t1 check status OK
-test.t2 check error The handler for the table doesn't support check/repair
-Table Op Msg_type Msg_text
-test.t1 repair status OK
-test.t2 repair error The handler for the table doesn't support check/repair
-Table Op Msg_type Msg_text
-test.t2 check error The handler for the table doesn't support check/repair
-test.t1 check status OK
-Table Op Msg_type Msg_text
-test.t2 check error Table 't2' was not locked with LOCK TABLES
-test.t1 check status OK
-Field Type Null Key Default Extra
-a int(11) PRI 0
-b int(11) MUL 0
-c int(11) 0
-Field Type Null Key Default Extra Privileges
-a int(11) PRI 0 select,insert,update,references
-b int(11) MUL 0 select,insert,update,references
-c int(11) 0 select,insert,update,references
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 4 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
-t1 1 b 2 c A 4 NULL NULL
+drop table if exists t1,t2;
+create table t1 (a int not null primary key, b int not null,c int not null, key(b,c));
+insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4);
+check table t1 fast;
Table Op Msg_type Msg_text
test.t1 check status Table is already up to date
+check table t1 fast;
Table Op Msg_type Msg_text
test.t1 check status Table is already up to date
+check table t1 changed;
Table Op Msg_type Msg_text
test.t1 check status OK
+insert into t1 values (5,5,5);
+check table t1 changed;
Table Op Msg_type Msg_text
test.t1 check status OK
+check table t1 medium;
Table Op Msg_type Msg_text
test.t1 check status OK
+check table t1 extended;
Table Op Msg_type Msg_text
test.t1 check status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 a A 5 NULL NULL
-t1 1 b 1 b A 1 NULL NULL
-t1 1 b 2 c A 5 NULL NULL
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 1 NULL NULL BTREE
+t1 1 b 2 c A 5 NULL NULL BTREE
+insert into t1 values (5,5,5);
+Duplicate entry '5' for key 1
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status Table is already up to date
+drop table t1;
+show variables like "wait_timeout%";
Variable_name Value
wait_timeout 28800
+show variables like "WAIT_timeout%";
Variable_name Value
wait_timeout 28800
+show variables like "this_doesn't_exists%";
Variable_name Value
+show table status from test like "this_doesn't_exists%";
Name Type Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Create_options Comment
+show databases;
Database
mysql
test
+show databases like "test%";
Database (test%)
test
+create table t1 (f1 int not null, f2 int not null, f3 int not null, f4 int not null, primary key(f1,f2,f3,f4));
+insert into t1 values (1,1,1,0),(1,1,2,0),(1,1,3,0),(1,2,1,0),(1,2,2,0),(1,2,3,0),(1,3,1,0),(1,3,2,0),(1,3,3,0),(1,1,1,1),(1,1,2,1),(1,1,3,1),(1,2,1,1),(1,2,2,1),(1,2,3,1),(1,3,1,1),(1,3,2,1),(1,3,3,1);
+analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 f1 A 1 NULL NULL
-t1 0 PRIMARY 2 f2 A 3 NULL NULL
-t1 0 PRIMARY 3 f3 A 9 NULL NULL
-t1 0 PRIMARY 4 f4 A 18 NULL NULL
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 f1 A 1 NULL NULL BTREE
+t1 0 PRIMARY 2 f2 A 3 NULL NULL BTREE
+t1 0 PRIMARY 3 f3 A 9 NULL NULL BTREE
+t1 0 PRIMARY 4 f4 A 18 NULL NULL BTREE
+repair table t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 f1 A 1 NULL NULL
-t1 0 PRIMARY 2 f2 A 3 NULL NULL
-t1 0 PRIMARY 3 f3 A 9 NULL NULL
-t1 0 PRIMARY 4 f4 A 18 NULL NULL
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 f1 A 1 NULL NULL BTREE
+t1 0 PRIMARY 2 f2 A 3 NULL NULL BTREE
+t1 0 PRIMARY 3 f3 A 9 NULL NULL BTREE
+t1 0 PRIMARY 4 f4 A 18 NULL NULL BTREE
+drop table t1;
+create temporary table t1 (a int not null);
+show create table t1;
Table Create Table
t1 CREATE TEMPORARY TABLE `t1` (
`a` int(11) NOT NULL default '0'
) TYPE=MyISAM
+alter table t1 rename t2;
+show create table t2;
Table Create Table
t2 CREATE TEMPORARY TABLE `t2` (
`a` int(11) NOT NULL default '0'
) TYPE=MyISAM
+drop table t2;
+create table t1 (
+test_set set( 'val1', 'val2', 'val3' ) not null default '',
+name char(20) default 'O''Brien'
+ ) comment = 'it\'s a table' ;
+show create table t1 ;
Table Create Table
t1 CREATE TABLE `t1` (
`test_set` set('val1','val2','val3') NOT NULL default '',
`name` char(20) default 'O''Brien'
) TYPE=MyISAM COMMENT='it''s a table'
+drop table t1;
+create table t1 (a int not null, unique aa (a));
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0',
UNIQUE KEY `aa` (`a`)
) TYPE=MyISAM
+drop table t1;
+create table t1 (a int not null, primary key (a));
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0',
PRIMARY KEY (`a`)
) TYPE=MyISAM
+drop table t1;
+flush tables;
+show open tables;
+Database Table In_use Name_locked
+create table t1(n int);
+insert into t1 values (1);
+show open tables;
+Database Table In_use Name_locked
+test t1 0 0
+drop table t1;
+create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" TYPE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0',
+ `b` char(10) default NULL,
+ KEY `b` (`b`)
+) TYPE=MyISAM MIN_ROWS=10 MAX_ROWS=100 AVG_ROW_LENGTH=10 PACK_KEYS=1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED COMMENT='test'
+alter table t1 MAX_ROWS=200 ROW_FORMAT=dynamic PACK_KEYS=0;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0',
+ `b` varchar(10) default NULL,
+ KEY `b` (`b`)
+) TYPE=MyISAM MIN_ROWS=10 MAX_ROWS=200 AVG_ROW_LENGTH=10 PACK_KEYS=0 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='test'
+ALTER TABLE t1 AVG_ROW_LENGTH=0 CHECKSUM=0 COMMENT="" MIN_ROWS=0 MAX_ROWS=0 PACK_KEYS=DEFAULT DELAY_KEY_WRITE=0 ROW_FORMAT=default;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0',
+ `b` varchar(10) default NULL,
+ KEY `b` (`b`)
+) TYPE=MyISAM
+drop table t1;
+create table t1 (a decimal(9,2), b decimal (9,0), e double(9,2), f double(5,0), h float(3,2), i float(3,0));
+show columns from t1;
Field Type Null Key Default Extra
a decimal(9,2) YES NULL
b decimal(9,0) YES NULL
@@ -99,12 +155,81 @@ e double(9,2) YES NULL
f double(5,0) YES NULL
h float(3,2) YES NULL
i float(3,0) YES NULL
+drop table t1;
+create table t1 (
+type_bool bool not null,
+type_tiny tinyint not null auto_increment primary key,
+type_short smallint(3),
+type_mediumint mediumint,
+type_bigint bigint,
+type_decimal decimal(5,2),
+type_numeric numeric(5,2),
+empty_char char(0),
+type_char char(2),
+type_varchar varchar(10),
+type_timestamp timestamp not null,
+type_date date not null,
+type_time time not null,
+type_datetime datetime not null,
+type_year year,
+type_enum enum ('red', 'green', 'blue'),
+type_set enum ('red', 'green', 'blue'),
+type_tinyblob tinyblob,
+type_blob blob,
+type_medium_blob mediumblob,
+type_long_blob longblob,
+index(type_short)
+) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" TYPE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed CHARSET=latin1;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `type_bool` tinyint(1) NOT NULL default '0',
+ `type_tiny` tinyint(4) NOT NULL auto_increment,
+ `type_short` smallint(3) default NULL,
+ `type_mediumint` mediumint(9) default NULL,
+ `type_bigint` bigint(20) default NULL,
+ `type_decimal` decimal(5,2) default NULL,
+ `type_numeric` decimal(5,2) default NULL,
+ `empty_char` char(0) default NULL,
+ `type_char` char(2) default NULL,
+ `type_varchar` varchar(10) default NULL,
+ `type_timestamp` timestamp(14) NOT NULL,
+ `type_date` date NOT NULL default '0000-00-00',
+ `type_time` time NOT NULL default '00:00:00',
+ `type_datetime` datetime NOT NULL default '0000-00-00 00:00:00',
+ `type_year` year(4) default NULL,
+ `type_enum` enum('red','green','blue') default NULL,
+ `type_set` enum('red','green','blue') default NULL,
+ `type_tinyblob` tinyblob,
+ `type_blob` blob,
+ `type_medium_blob` mediumblob,
+ `type_long_blob` longblob,
+ PRIMARY KEY (`type_tiny`),
+ KEY `type_short` (`type_short`)
+) TYPE=MyISAM MIN_ROWS=10 MAX_ROWS=100 AVG_ROW_LENGTH=10 PACK_KEYS=1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED COMMENT='test'
+insert into t1 (type_timestamp) values ("2003-02-07 10:00:01");
+select * from t1;
+type_bool type_tiny type_short type_mediumint type_bigint type_decimal type_numeric empty_char type_char type_varchar type_timestamp type_date type_time type_datetime type_year type_enum type_set type_tinyblob type_blob type_medium_blob type_long_blob
+0 1 NULL NULL NULL NULL NULL NULL NULL NULL 20030207100001 0000-00-00 00:00:00 0000-00-00 00:00:00 NULL NULL NULL NULL NULL NULL NULL
+drop table t1;
+create table t1 (a int not null);
+create table t2 select max(a) from t1;
+show columns from t2;
+Field Type Null Key Default Extra
+max(a) bigint(20) YES NULL
+drop table t1,t2;
+create table t1 (c decimal, d double, f float, r real);
+show columns from t1;
Field Type Null Key Default Extra
c decimal(10,0) YES NULL
d double YES NULL
f float YES NULL
r double YES NULL
+drop table t1;
+create table t1 (c decimal(3,3), d double(3,3), f float(3,3));
+show columns from t1;
Field Type Null Key Default Extra
c decimal(4,3) YES NULL
d double(4,3) YES NULL
f float(4,3) YES NULL
+drop table t1;
diff --git a/mysql-test/r/slave-running.result b/mysql-test/r/slave-running.result
index 794d0935ef4..3699390a7d3 100644
--- a/mysql-test/r/slave-running.result
+++ b/mysql-test/r/slave-running.result
@@ -1,2 +1,3 @@
+show status like 'Slave_running';
Variable_name Value
Slave_running ON
diff --git a/mysql-test/r/slave-stopped.result b/mysql-test/r/slave-stopped.result
index 29ab2ac73e4..90b416b7bd7 100644
--- a/mysql-test/r/slave-stopped.result
+++ b/mysql-test/r/slave-stopped.result
@@ -1,2 +1,3 @@
+show status like 'Slave_running';
Variable_name Value
Slave_running OFF
diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result
index 8f3ad3e0d59..3ef6cec32b3 100644
--- a/mysql-test/r/status.result
+++ b/mysql-test/r/status.result
@@ -1,6 +1,19 @@
+flush status;
+show status like 'Table_lock%';
Variable_name Value
Table_locks_immediate 0
Table_locks_waited 0
+SET SQL_LOG_BIN=0;
+drop table if exists t1;
+create table t1(n int) type=myisam;
+insert into t1 values(1);
+lock tables t1 read;
+unlock tables;
+lock tables t1 read;
+update t1 set n = 3;
+unlock tables;
+show status like 'Table_lock%';
Variable_name Value
Table_locks_immediate 3
Table_locks_waited 1
+drop table t1;
diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result
new file mode 100644
index 00000000000..d07a8613883
--- /dev/null
+++ b/mysql-test/r/symlink.result
@@ -0,0 +1,86 @@
+drop table if exists t1,t2,t7,t8,t9;
+drop database if exists mysqltest;
+create table t1 (a int not null auto_increment, b char(16) not null, primary key (a));
+create table t2 (a int not null auto_increment, b char(16) not null, primary key (a));
+insert into t1 (b) values ("test"),("test1"),("test2"),("test3");
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+drop table t2;
+insert into t9 select * from t1;
+check table t9;
+Table Op Msg_type Msg_text
+test.t9 check status OK
+optimize table t9;
+Table Op Msg_type Msg_text
+test.t9 optimize status OK
+repair table t9;
+Table Op Msg_type Msg_text
+test.t9 repair status OK
+alter table t9 add column c int not null;
+show create table t9;
+Table Create Table
+t9 CREATE TABLE `t9` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` char(16) NOT NULL default '',
+ `c` int(11) NOT NULL default '0',
+ PRIMARY KEY (`a`)
+) TYPE=MyISAM DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/'
+alter table t9 rename t8, add column d int not null;
+alter table t8 rename t7;
+rename table t7 to t9;
+drop table t1;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+alter table t9 rename mysqltest.t9;
+select count(*) from mysqltest.t9;
+count(*)
+16724
+show create table mysqltest.t9;
+Table Create Table
+t9 CREATE TABLE `t9` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` char(16) NOT NULL default '',
+ `c` int(11) NOT NULL default '0',
+ `d` int(11) NOT NULL default '0',
+ PRIMARY KEY (`a`)
+) TYPE=MyISAM DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/'
+drop database mysqltest;
+create table t1 (a int not null) type=myisam;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0'
+) TYPE=MyISAM
+alter table t1 add b int;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) default NULL
+) TYPE=MyISAM
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0',
+ `b` int(11) default NULL
+) TYPE=MyISAM
+drop table t1;
diff --git a/mysql-test/r/tablelock.result b/mysql-test/r/tablelock.result
index 4fbeac979b1..2ffd8f928a9 100644
--- a/mysql-test/r/tablelock.result
+++ b/mysql-test/r/tablelock.result
@@ -1,12 +1,48 @@
+drop table if exists t1,t2;
+create table t1 ( n int auto_increment primary key);
+lock tables t1 write;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write, t1 as t0 read;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write, t1 as t0 read, t1 as t2 read;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write, t1 as t0 write, t1 as t2 read;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write, t1 as t0 write, t1 as t2 read, t1 as t3 read;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+lock tables t1 write, t1 as t0 write, t1 as t2 write;
+insert into t1 values(NULL);
+unlock tables;
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+drop table t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+lock tables t1 write,t1 as b write, t2 write, t2 as c read;
+drop table t1,t2;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+lock tables t1 write,t1 as b write, t2 write, t2 as c read;
+drop table t2,t1;
+unlock tables;
diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result
index 12e76bba3f7..7c8d10cf0a6 100644
--- a/mysql-test/r/temp_table.result
+++ b/mysql-test/r/temp_table.result
@@ -1,30 +1,101 @@
+drop table if exists t1,t2;
+CREATE TABLE t1 (c int not null, d char (10) not null);
+insert into t1 values(1,""),(2,"a"),(3,"b");
+CREATE TEMPORARY TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(4,"e"),(5,"f"),(6,"g");
+alter table t1 rename t2;
+select * from t1;
c d
1
2 a
3 b
+select * from t2;
a b
4 e
5 f
6 g
+CREATE TABLE t2 (x int not null, y int not null);
+alter table t2 rename t1;
+select * from t1;
a b
4 e
5 f
6 g
+create TEMPORARY TABLE t2 type=heap select * from t1;
+create TEMPORARY TABLE IF NOT EXISTS t2 (a int) type=heap;
+CREATE TEMPORARY TABLE t1 (a int not null, b char (10) not null);
+Table 't1' already exists
+ALTER TABLE t1 RENAME t2;
+Table 't2' already exists
+select * from t2;
a b
4 e
5 f
6 g
+alter table t2 add primary key (a,b);
+drop table t1,t2;
+select * from t1;
c d
1
2 a
3 b
+drop table t2;
+create temporary table t1 select *,2 as "e" from t1;
+select * from t1;
c d e
1 2
2 a 2
3 b 2
+drop table t1;
+drop table t1;
+drop table if exists t1;
+CREATE TABLE t1 (pkCrash INTEGER PRIMARY KEY,strCrash VARCHAR(255));
+INSERT INTO t1 ( pkCrash, strCrash ) VALUES ( 1, '1');
+SELECT CONCAT_WS(pkCrash, strCrash) FROM t1;
CONCAT_WS(pkCrash, strCrash)
1
+drop table t1;
+create temporary table t1 select 1 as 'x';
+drop table t1;
+CREATE TABLE t1 (x INT);
+INSERT INTO t1 VALUES (1), (2), (3);
+CREATE TEMPORARY TABLE tmp SELECT *, NULL FROM t1;
+drop table t1;
+create temporary table t1 (id int(10) not null unique);
+create temporary table t2 (id int(10) not null primary key,
+val int(10) not null);
+insert into t1 values (1),(2),(4);
+insert into t2 values (1,1),(2,1),(3,1),(4,2);
+select one.id, two.val, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id;
id val elt(two.val,'one','two')
1 1 one
2 1 one
4 2 two
+drop table t1,t2;
+create temporary table t1 (a int not null);
+insert into t1 values (1),(1);
+alter table t1 add primary key (a);
+Duplicate entry '1' for key 1
+drop table t1;
+drop table if exists t1;
+CREATE TABLE t1 (
+d datetime default NULL
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES ('2002-10-24 14:50:32'),('2002-10-24 14:50:33'),('2002-10-24 14:50:34'),('2002-10-24 14:50:34'),('2002-10-24 14:50:34'),('2002-10-24 14:50:35'),('2002-10-24 14:50:35'),('2002-10-24 14:50:35'),('2002-10-24 14:50:35'),('2002-10-24 14:50:36'),('2002-10-24 14:50:36'),('2002-10-24 14:50:36'),('2002-10-24 14:50:36'),('2002-10-24 14:50:37'),('2002-10-24 14:50:37'),('2002-10-24 14:50:37'),('2002-10-24 14:50:37'),('2002-10-24 14:50:38'),('2002-10-24 14:50:38'),('2002-10-24 14:50:38'),('2002-10-24 14:50:39'),('2002-10-24 14:50:39'),('2002-10-24 14:50:39'),('2002-10-24 14:50:39'),('2002-10-24 14:50:40'),('2002-10-24 14:50:40'),('2002-10-24 14:50:40');
+flush status;
+select * from t1 group by d;
+d
+2002-10-24 14:50:32
+2002-10-24 14:50:33
+2002-10-24 14:50:34
+2002-10-24 14:50:35
+2002-10-24 14:50:36
+2002-10-24 14:50:37
+2002-10-24 14:50:38
+2002-10-24 14:50:39
+2002-10-24 14:50:40
+show status like "created_tmp%tables";
+Variable_name Value
+Created_tmp_disk_tables 0
+Created_tmp_tables 1
+drop table t1;
diff --git a/mysql-test/r/timezone.result b/mysql-test/r/timezone.result
new file mode 100644
index 00000000000..15f0d4121c7
--- /dev/null
+++ b/mysql-test/r/timezone.result
@@ -0,0 +1,40 @@
+DROP TABLE IF EXISTS t1;
+show variables like "timezone";
+Variable_name Value
+timezone MET
+select @a:=FROM_UNIXTIME(1);
+@a:=FROM_UNIXTIME(1)
+1970-01-01 01:00:01
+select unix_timestamp(@a);
+unix_timestamp(@a)
+1
+CREATE TABLE t1 (ts int);
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 03:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 02:59:59'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 03:00:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 03:59:59'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 04:00:01'));
+SELECT ts,from_unixtime(ts) FROM t1;
+ts from_unixtime(ts)
+1035673200 2002-10-27 01:00:00
+1035680400 2002-10-27 02:00:00
+1035684000 2002-10-27 03:00:00
+1035680400 2002-10-27 02:00:00
+1035673200 2002-10-27 01:00:00
+1035680400 2002-10-27 02:00:00
+1048986000 2003-03-30 03:00:00
+1048986000 2003-03-30 03:00:00
+1048989599 2003-03-30 03:59:59
+1048989601 2003-03-30 04:00:01
+DROP TABLE t1;
+select unix_timestamp('1970-01-01 01:00:00'),
+unix_timestamp('1970-01-01 01:00:01'),
+unix_timestamp('2038-01-01 00:59:59'),
+unix_timestamp('2038-01-01 01:00:00');
+unix_timestamp('1970-01-01 01:00:00') unix_timestamp('1970-01-01 01:00:01') unix_timestamp('2038-01-01 00:59:59') unix_timestamp('2038-01-01 01:00:00')
+0 1 2145916799 0
diff --git a/mysql-test/r/truncate.result b/mysql-test/r/truncate.result
index 716b38c57c7..1b387214292 100644
--- a/mysql-test/r/truncate.result
+++ b/mysql-test/r/truncate.result
@@ -1,4 +1,34 @@
+drop table if exists t1;
+create table t1 (a integer, b integer,c1 CHAR(10));
+insert into t1 (a) values (1),(2);
+truncate table t1;
+select count(*) from t1;
count(*)
0
+insert into t1 values(1,2,"test");
+select count(*) from t1;
count(*)
1
+delete from t1;
+select * from t1;
+a b c1
+drop table t1;
+select count(*) from t1;
+Table 'test.t1' doesn't exist
+create temporary table t1 (n int);
+insert into t1 values (1),(2),(3);
+truncate table t1;
+select * from t1;
+n
+drop table t1;
+truncate non_existing_table;
+Table 'test.non_existing_table' doesn't exist
+create table t1 (a integer auto_increment primary key);
+insert into t1 (a) values (NULL),(NULL);
+truncate table t1;
+insert into t1 (a) values (NULL),(NULL);
+SELECT * from t1;
+a
+1
+2
+drop table t1;
diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result
index bc80ba38452..685301f3639 100644
--- a/mysql-test/r/type_blob.result
+++ b/mysql-test/r/type_blob.result
@@ -1,5 +1,12 @@
+drop table if exists t1,t2,t3,t4,t5,t6,t7;
+create table t1 (nr int(5) not null auto_increment,b blob,str char(10), primary key (nr));
+insert into t1 values (null,"a","A");
+insert into t1 values (null,"bbb","BBB");
+insert into t1 values (null,"ccc","CCC");
+select last_insert_id();
last_insert_id()
3
+select * from t1,t1 as t2;
nr b str nr b str
1 a A 1 a A
2 bbb BBB 1 a A
@@ -10,54 +17,88 @@ nr b str nr b str
1 a A 3 ccc CCC
2 bbb BBB 3 ccc CCC
3 ccc CCC 3 ccc CCC
+drop table t1;
+create table t1 (a text);
+insert into t1 values ('where');
+update t1 set a='Where';
+select * from t1;
a
Where
+drop table t1;
+create table t1 (t text,c char(10),b blob, d char(10) binary);
+insert into t1 values (NULL,NULL,NULL,NULL);
+insert into t1 values ("","","","");
+insert into t1 values ("hello","hello","hello","hello");
+insert into t1 values ("HELLO","HELLO","HELLO","HELLO");
+insert into t1 values ("HELLO MY","HELLO MY","HELLO MY","HELLO MY");
+insert into t1 values ("a","a","a","a");
+insert into t1 values (1,1,1,1);
+insert into t1 values (NULL,NULL,NULL,NULL);
+update t1 set c="",b=null where c="1";
+lock tables t1 READ;
+show full fields from t1;
Field Type Null Key Default Extra Privileges
t text YES NULL select,insert,update,references
c varchar(10) YES NULL select,insert,update,references
b blob YES NULL select,insert,update,references
d varchar(10) binary YES NULL select,insert,update,references
+lock tables t1 WRITE;
+show full fields from t1;
Field Type Null Key Default Extra Privileges
t text YES NULL select,insert,update,references
c varchar(10) YES NULL select,insert,update,references
b blob YES NULL select,insert,update,references
d varchar(10) binary YES NULL select,insert,update,references
+unlock tables;
+select t from t1 where t like "hello";
t
hello
HELLO
+select c from t1 where c like "hello";
c
hello
HELLO
+select b from t1 where b like "hello";
b
hello
+select d from t1 where d like "hello";
d
hello
+select c from t1 having c like "hello";
c
hello
HELLO
+select d from t1 having d like "hello";
d
hello
+select t from t1 where t like "%HELLO%";
t
hello
HELLO
HELLO MY
+select c from t1 where c like "%HELLO%";
c
hello
HELLO
HELLO MY
+select b from t1 where b like "%HELLO%";
b
HELLO
HELLO MY
+select d from t1 where d like "%HELLO%";
d
HELLO
HELLO MY
+select c from t1 having c like "%HELLO%";
c
hello
HELLO
HELLO MY
+select d from t1 having d like "%HELLO%";
d
HELLO
HELLO MY
+select t from t1 order by t;
t
NULL
NULL
@@ -67,6 +108,7 @@ a
hello
HELLO
HELLO MY
+select c from t1 order by c;
c
NULL
NULL
@@ -76,6 +118,7 @@ a
hello
HELLO
HELLO MY
+select b from t1 order by b;
b
NULL
NULL
@@ -85,6 +128,7 @@ HELLO
HELLO MY
a
hello
+select d from t1 order by d;
d
NULL
NULL
@@ -94,6 +138,7 @@ HELLO
HELLO MY
a
hello
+select distinct t from t1;
t
NULL
@@ -101,6 +146,7 @@ hello
HELLO MY
a
1
+select distinct b from t1;
b
NULL
@@ -108,6 +154,7 @@ hello
HELLO
HELLO MY
a
+select distinct t from t1 order by t;
t
NULL
@@ -115,6 +162,7 @@ NULL
a
hello
HELLO MY
+select distinct b from t1 order by b;
b
NULL
@@ -122,6 +170,7 @@ HELLO
HELLO MY
a
hello
+select t from t1 group by t;
t
NULL
@@ -129,6 +178,7 @@ NULL
a
hello
HELLO MY
+select b from t1 group by b;
b
NULL
@@ -136,6 +186,8 @@ HELLO
HELLO MY
a
hello
+set option sql_big_tables=1;
+select distinct t from t1;
t
NULL
@@ -143,6 +195,7 @@ hello
HELLO MY
a
1
+select distinct b from t1;
b
NULL
@@ -150,6 +203,7 @@ hello
HELLO
HELLO MY
a
+select distinct t from t1 order by t;
t
NULL
@@ -157,6 +211,7 @@ NULL
a
hello
HELLO MY
+select distinct b from t1 order by b;
b
NULL
@@ -164,12 +219,14 @@ HELLO
HELLO MY
a
hello
+select distinct c from t1;
c
NULL
hello
HELLO MY
a
+select distinct d from t1;
d
NULL
@@ -178,12 +235,14 @@ HELLO
HELLO MY
a
1
+select distinct c from t1 order by c;
c
NULL
a
hello
HELLO MY
+select distinct d from t1 order by d;
d
NULL
@@ -192,12 +251,14 @@ HELLO
HELLO MY
a
hello
+select c from t1 group by c;
c
NULL
a
hello
HELLO MY
+select d from t1 group by d;
d
NULL
@@ -206,6 +267,8 @@ HELLO
HELLO MY
a
hello
+set option sql_big_tables=0;
+select distinct * from t1;
t c b d
NULL NULL NULL NULL
@@ -214,6 +277,7 @@ HELLO HELLO HELLO HELLO
HELLO MY HELLO MY HELLO MY HELLO MY
a a a a
1 NULL 1
+select t,count(*) from t1 group by t;
t count(*)
NULL 2
1
@@ -221,6 +285,7 @@ NULL 2
a 1
hello 2
HELLO MY 1
+select b,count(*) from t1 group by b;
b count(*)
NULL 3
1
@@ -228,12 +293,14 @@ HELLO 1
HELLO MY 1
a 1
hello 1
+select c,count(*) from t1 group by c;
c count(*)
NULL 2
2
a 1
hello 2
HELLO MY 1
+select d,count(*) from t1 group by d;
d count(*)
NULL 2
1
@@ -242,22 +309,301 @@ HELLO 1
HELLO MY 1
a 1
hello 1
+drop table t1;
+create table t1 (a text, key (a(300)));
+Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the table handler doesn't support unique sub keys
+create table t1 (a text, key (a(255)));
+drop table t1;
+CREATE TABLE t1 (
+t1_id bigint(21) NOT NULL auto_increment,
+_field_72 varchar(128) DEFAULT '' NOT NULL,
+_field_95 varchar(32),
+_field_115 tinyint(4) DEFAULT '0' NOT NULL,
+_field_122 tinyint(4) DEFAULT '0' NOT NULL,
+_field_126 tinyint(4),
+_field_134 tinyint(4),
+PRIMARY KEY (t1_id),
+UNIQUE _field_72 (_field_72),
+KEY _field_115 (_field_115),
+KEY _field_122 (_field_122)
+);
+INSERT INTO t1 VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',0,1,NULL,NULL);
+INSERT INTO t1 VALUES (2,'hroberts','7415275a8c95952901e42b13a6b78566',0,1,NULL,NULL);
+INSERT INTO t1 VALUES (3,'guest','d41d8cd98f00b204e9800998ecf8427e',1,0,NULL,NULL);
+CREATE TABLE t2 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+PRIMARY KEY (seq_0_id,seq_1_id)
+);
+INSERT INTO t2 VALUES (1,1);
+INSERT INTO t2 VALUES (2,1);
+INSERT INTO t2 VALUES (2,2);
+CREATE TABLE t3 (
+t3_id bigint(21) NOT NULL auto_increment,
+_field_131 varchar(128),
+_field_133 tinyint(4) DEFAULT '0' NOT NULL,
+_field_135 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+_field_137 tinyint(4),
+_field_139 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+_field_140 blob,
+_field_142 tinyint(4) DEFAULT '0' NOT NULL,
+_field_145 tinyint(4) DEFAULT '0' NOT NULL,
+_field_148 tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (t3_id),
+KEY _field_133 (_field_133),
+KEY _field_135 (_field_135),
+KEY _field_139 (_field_139),
+KEY _field_142 (_field_142),
+KEY _field_145 (_field_145),
+KEY _field_148 (_field_148)
+);
+INSERT INTO t3 VALUES (1,'test job 1',0,'0000-00-00 00:00:00',0,'1999-02-25 22:43:32','test\r\njob\r\n1',0,0,0);
+INSERT INTO t3 VALUES (2,'test job 2',0,'0000-00-00 00:00:00',0,'1999-02-26 21:08:04','',0,0,0);
+CREATE TABLE t4 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+PRIMARY KEY (seq_0_id,seq_1_id)
+);
+INSERT INTO t4 VALUES (1,1);
+INSERT INTO t4 VALUES (2,1);
+CREATE TABLE t5 (
+t5_id bigint(21) NOT NULL auto_increment,
+_field_149 tinyint(4),
+_field_156 varchar(128) DEFAULT '' NOT NULL,
+_field_157 varchar(128) DEFAULT '' NOT NULL,
+_field_158 varchar(128) DEFAULT '' NOT NULL,
+_field_159 varchar(128) DEFAULT '' NOT NULL,
+_field_160 varchar(128) DEFAULT '' NOT NULL,
+_field_161 varchar(128) DEFAULT '' NOT NULL,
+PRIMARY KEY (t5_id),
+KEY _field_156 (_field_156),
+KEY _field_157 (_field_157),
+KEY _field_158 (_field_158),
+KEY _field_159 (_field_159),
+KEY _field_160 (_field_160),
+KEY _field_161 (_field_161)
+);
+INSERT INTO t5 VALUES (1,0,'tomato','','','','','');
+INSERT INTO t5 VALUES (2,0,'cilantro','','','','','');
+CREATE TABLE t6 (
+seq_0_id bigint(21) DEFAULT '0' NOT NULL,
+seq_1_id bigint(21) DEFAULT '0' NOT NULL,
+PRIMARY KEY (seq_0_id,seq_1_id)
+);
+INSERT INTO t6 VALUES (1,1);
+INSERT INTO t6 VALUES (1,2);
+INSERT INTO t6 VALUES (2,2);
+CREATE TABLE t7 (
+t7_id bigint(21) NOT NULL auto_increment,
+_field_143 tinyint(4),
+_field_165 varchar(32),
+_field_166 smallint(6) DEFAULT '0' NOT NULL,
+PRIMARY KEY (t7_id),
+KEY _field_166 (_field_166)
+);
+INSERT INTO t7 VALUES (1,0,'High',1);
+INSERT INTO t7 VALUES (2,0,'Medium',2);
+INSERT INTO t7 VALUES (3,0,'Low',3);
+select replace(t3._field_140, "\r","^M"),t3_id,min(t3._field_131), min(t3._field_135), min(t3._field_139), min(t3._field_137), min(link_alias_142._field_165), min(link_alias_133._field_72), min(t3._field_145), min(link_alias_148._field_156), replace(min(t3._field_140), "\r","^M"),t3.t3_id from t3 left join t4 on t4.seq_0_id = t3.t3_id left join t7 link_alias_142 on t4.seq_1_id = link_alias_142.t7_id left join t6 on t6.seq_0_id = t3.t3_id left join t1 link_alias_133 on t6.seq_1_id = link_alias_133.t1_id left join t2 on t2.seq_0_id = t3.t3_id left join t5 link_alias_148 on t2.seq_1_id = link_alias_148.t5_id where t3.t3_id in (1) group by t3.t3_id order by link_alias_142._field_166, _field_139, link_alias_133._field_72, _field_135, link_alias_148._field_156;
replace(t3._field_140, "\r","^M") t3_id min(t3._field_131) min(t3._field_135) min(t3._field_139) min(t3._field_137) min(link_alias_142._field_165) min(link_alias_133._field_72) min(t3._field_145) min(link_alias_148._field_156) replace(min(t3._field_140), "\r","^M") t3_id
test^M
job^M
1 1 test job 1 0000-00-00 00:00:00 1999-02-25 22:43:32 0 High admin 0 tomato test^M
job^M
1 1
+drop table t1,t2,t3,t4,t5,t6,t7;
+create table t1 (a blob);
+insert into t1 values ("empty"),("");
+select a,reverse(a) from t1;
a reverse(a)
empty ytpme
+drop table t1;
+create table t1 (a blob, key (a(10)));
+insert into t1 values ("bye"),("hello"),("hello"),("hello word");
+select * from t1 where a like "hello%";
a
hello
hello
hello word
+drop table t1;
+CREATE TABLE t1 (
+f1 int(11) DEFAULT '0' NOT NULL,
+f2 varchar(16) DEFAULT '' NOT NULL,
+f5 text,
+KEY index_name (f1,f2,f5(16))
+);
+INSERT INTO t1 VALUES (0,'traktor','1111111111111');
+INSERT INTO t1 VALUES (1,'traktor','1111111111111111111111111');
+select count(*) from t1 where f2='traktor';
count(*)
2
+drop table t1;
+create table t1 (foobar tinyblob not null, boggle smallint not null, key (foobar(32), boggle));
+insert into t1 values ('fish', 10),('bear', 20);
+select foobar, boggle from t1 where foobar = 'fish';
foobar boggle
fish 10
+select foobar, boggle from t1 where foobar = 'fish' and boggle = 10;
foobar boggle
fish 10
+drop table t1;
+create table t1 (id integer auto_increment unique,imagem LONGBLOB not null);
+insert into t1 (id) values (1);
+update t1 set imagem=load_file('../../std_data/words.dat') where id=1;
+select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1;
+if(imagem is null, "ERROR", "OK") length(imagem)
+OK 581
+drop table t1;
+create table t1 (id integer primary key auto_increment, txt text not null, unique index txt_index (txt (20)));
+insert into t1 (txt) values ('Chevy'), ('Chevy ');
+select * from t1 where txt='Chevy';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt='Chevy ';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt='Chevy ' or txt='Chevy';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt='Chevy' or txt='Chevy ';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where id='1' or id='2';
+id txt
+1 Chevy
+2 Chevy
+insert into t1 (txt) values('Ford');
+select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
+id txt
+1 Chevy
+2 Chevy
+3 Ford
+select * from t1 where txt='Chevy' or txt='Chevy ';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt in ('Chevy ','Chevy');
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt in ('Chevy');
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt between 'Chevy' and 'Chevy';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt between 'Chevy' and 'Chevy ';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt < 'Chevy ';
+id txt
+select * from t1 where txt <= 'Chevy';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt > 'Chevy';
+id txt
+3 Ford
+select * from t1 where txt >= 'Chevy';
+id txt
+1 Chevy
+2 Chevy
+3 Ford
+drop table t1;
+create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20)));
+insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL);
+select * from t1 where txt='Chevy' or txt is NULL;
+id txt
+3 NULL
+1 Chevy
+2 Chevy
+select * from t1 where txt='Chevy ';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt='Chevy ' or txt='Chevy';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt='Chevy' or txt='Chevy ';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where id='1' or id='2';
+id txt
+1 Chevy
+2 Chevy
+insert into t1 (txt) values('Ford');
+select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
+id txt
+1 Chevy
+2 Chevy
+4 Ford
+select * from t1 where txt='Chevy' or txt='Chevy ';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt in ('Chevy ','Chevy');
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt in ('Chevy');
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt between 'Chevy' and 'Chevy';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt between 'Chevy' and 'Chevy ';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt < 'Chevy ';
+id txt
+select * from t1 where txt < 'Chevy ' or txt is NULL;
+id txt
+3 NULL
+select * from t1 where txt <= 'Chevy';
+id txt
+1 Chevy
+2 Chevy
+select * from t1 where txt > 'Chevy';
+id txt
+4 Ford
+select * from t1 where txt >= 'Chevy';
+id txt
+1 Chevy
+2 Chevy
+4 Ford
+drop table t1;
+CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1)));
+INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
+select max(i) from t1 where c = '';
+max(i)
+4
+drop table t1;
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index df8f0ee1814..8dfe14bc1a2 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -1,24 +1,75 @@
+create table t1 (a char(16), b date, c datetime);
+insert into t1 SET a='test 2000-01-01', b='2000-01-01', c='2000-01-01';
+select * from t1 where c = '2000-01-01';
a b c
test 2000-01-01 2000-01-01 2000-01-01 00:00:00
+select * from t1 where b = '2000-01-01';
a b c
test 2000-01-01 2000-01-01 2000-01-01 00:00:00
+drop table t1;
+drop table if exists t1,t2;
+CREATE TABLE t1 (name char(6),cdate date);
+INSERT INTO t1 VALUES ('name1','1998-01-01');
+INSERT INTO t1 VALUES ('name2','1998-01-01');
+INSERT INTO t1 VALUES ('name1','1998-01-02');
+INSERT INTO t1 VALUES ('name2','1998-01-02');
+CREATE TABLE t2 (cdate date, note char(6));
+INSERT INTO t2 VALUES ('1998-01-01','note01');
+INSERT INTO t2 VALUES ('1998-01-02','note02');
+select name,t1.cdate,note from t1,t2 where t1.cdate=t2.cdate and t1.cdate='1998-01-01';
name cdate note
name1 1998-01-01 note01
name2 1998-01-01 note01
+drop table t1,t2;
+CREATE TABLE t1 ( datum DATE );
+INSERT INTO t1 VALUES ( "2000-1-1" );
+INSERT INTO t1 VALUES ( "2000-1-2" );
+INSERT INTO t1 VALUES ( "2000-1-3" );
+INSERT INTO t1 VALUES ( "2000-1-4" );
+INSERT INTO t1 VALUES ( "2000-1-5" );
+SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4";
datum
2000-01-02
2000-01-03
2000-01-04
+SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY;
+datum
+DROP TABLE t1;
+CREATE TABLE t1 (
+user_id char(10),
+summa int(11),
+rdate date
+);
+INSERT INTO t1 VALUES ('aaa',100,'1998-01-01');
+INSERT INTO t1 VALUES ('aaa',200,'1998-01-03');
+INSERT INTO t1 VALUES ('bbb',50,'1998-01-02');
+INSERT INTO t1 VALUES ('bbb',200,'1998-01-04');
+select max(rdate) as s from t1 where rdate < '1998-01-03' having s> "1998-01-01";
s
1998-01-02
+select max(rdate) as s from t1 having s="1998-01-04";
s
1998-01-04
+select max(rdate+0) as s from t1 having s="19980104";
s
19980104
+drop table t1;
+create table t1 (date date);
+insert into t1 values ("2000-08-10"),("2000-08-11");
+select date_add(date,INTERVAL 1 DAY),date_add(date,INTERVAL 1 SECOND) from t1;
date_add(date,INTERVAL 1 DAY) date_add(date,INTERVAL 1 SECOND)
2000-08-11 2000-08-10 00:00:01
2000-08-12 2000-08-11 00:00:01
+drop table t1;
+CREATE TABLE t1(AFIELD INT);
+INSERT INTO t1 VALUES(1);
+CREATE TABLE t2(GMT VARCHAR(32));
+INSERT INTO t2 VALUES('GMT-0800');
+SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) FROM t1, t2 GROUP BY t1.AFIELD;
DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT))
Wed, 06 March 2002 10:11:12 GMT-0800
+INSERT INTO t1 VALUES(1);
+SELECT DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)), DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) FROM t1,t2 GROUP BY t1.AFIELD;
DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT)) DATE_FORMAT("2002-03-06 10:11:12", CONCAT('%a, %d %M %Y %H:%i:%s ' , t2.GMT))
Wed, 06 March 2002 10:11:12 GMT-0800 Wed, 06 March 2002 10:11:12 GMT-0800
+drop table t1,t2;
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 6c461b10930..756deab80e0 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -1,3 +1,7 @@
+drop table if exists t1;
+create table t1 (t datetime);
+insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959),(20030102030460),(20030102036301),(20030102240401),(20030132030401),(20031302030460);
+select * from t1;
t
2000-01-01 00:00:00
2069-12-31 00:00:00
@@ -11,10 +15,21 @@ t
1999-12-31 23:59:59
1000-01-01 00:00:00
9999-12-31 23:59:59
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+delete from t1 where t > 0;
+optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
+check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
+delete from t1;
+insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030102030460"),("20030102036301"),("20030102240401"),("20030132030401"),("20031302030460");
+select * from t1;
t
2000-01-01 00:00:00
2069-12-31 00:00:00
@@ -29,15 +44,61 @@ t
1999-12-31 23:59:59
1000-01-01 00:00:00
9999-12-31 23:59:59
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+0000-00-00 00:00:00
+drop table t1;
+CREATE TABLE t1 (a timestamp, b date, c time, d datetime);
+insert into t1 (b,c,d) values(now(),curtime(),now());
+select date_format(a,"%Y-%m-%d")=b,right(a,6)=c+0,a=d+0 from t1;
date_format(a,"%Y-%m-%d")=b right(a,6)=c+0 a=d+0
1 1 1
+drop table t1;
+CREATE TABLE t1 (a datetime not null);
+insert into t1 values (0);
+select * from t1 where a is null;
a
0000-00-00 00:00:00
+drop table t1;
+create table t1 (id int, dt datetime);
+insert into t1 values (1,"2001-08-14 00:00:00"),(2,"2001-08-15 00:00:00"),(3,"2001-08-16 00:00:00"),(4,"2003-09-15 01:20:30");
+select * from t1 where dt='2001-08-14 00:00:00' and dt = if(id=1,'2001-08-14 00:00:00','1999-08-15');
+id dt
+1 2001-08-14 00:00:00
+create index dt on t1 (dt);
+select * from t1 where dt > 20021020;
+id dt
+4 2003-09-15 01:20:30
+select * from t1 ignore index (dt) where dt > 20021020;
+id dt
+4 2003-09-15 01:20:30
+drop table t1;
+CREATE TABLE `t1` (
+`date` datetime NOT NULL default '0000-00-00 00:00:00',
+`numfacture` int(6) unsigned NOT NULL default '0',
+`expedition` datetime NOT NULL default '0000-00-00 00:00:00',
+PRIMARY KEY (`numfacture`),
+KEY `date` (`date`),
+KEY `expedition` (`expedition`)
+) TYPE=MyISAM;
+INSERT INTO t1 (expedition) VALUES ('0001-00-00 00:00:00');
+SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
date numfacture expedition
0000-00-00 00:00:00 0 0001-00-00 00:00:00
+INSERT INTO t1 (numfacture,expedition) VALUES ('1212','0001-00-00 00:00:00');
+SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
date numfacture expedition
0000-00-00 00:00:00 0 0001-00-00 00:00:00
0000-00-00 00:00:00 1212 0001-00-00 00:00:00
+EXPLAIN SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
table type possible_keys key key_len ref rows Extra
-t1 ref expedition expedition 8 const 1 where used
+t1 ref expedition expedition 8 const 1 Using where
+drop table t1;
+create table t1 (a datetime not null, b datetime not null);
+insert into t1 values (now(), now());
+insert into t1 values (now(), now());
+select * from t1 where a is null or b is null;
a b
+drop table t1;
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index 82b7d155822..5268ff3696b 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -1,8 +1,164 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+datatype_id int(11) DEFAULT '0' NOT NULL,
+minvalue decimal(20,10) DEFAULT '0.0000000000' NOT NULL,
+maxvalue decimal(20,10) DEFAULT '0.0000000000' NOT NULL,
+valuename varchar(20),
+forecolor int(11),
+backcolor int(11),
+PRIMARY KEY (id),
+UNIQUE datatype_id (datatype_id, minvalue, maxvalue)
+);
+INSERT INTO t1 VALUES ( '1', '4', '0.0000000000', '0.0000000000', 'Ei saja', '0', '16776960');
+INSERT INTO t1 VALUES ( '2', '4', '1.0000000000', '1.0000000000', 'Sajab', '16777215', '255');
+INSERT INTO t1 VALUES ( '3', '1', '2.0000000000', '49.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '60', '11', '0.0000000000', '0.0000000000', 'Rikkis', '16777215', '16711680');
+INSERT INTO t1 VALUES ( '4', '12', '1.0000000000', '1.0000000000', 'nork sadu', '65280', '14474460');
+INSERT INTO t1 VALUES ( '5', '12', '2.0000000000', '2.0000000000', 'keskmine sadu', '255', '14474460');
+INSERT INTO t1 VALUES ( '6', '12', '3.0000000000', '3.0000000000', 'tugev sadu', '127', '14474460');
+INSERT INTO t1 VALUES ( '43', '39', '6.0000000000', '6.0000000000', 'lobjakas', '13107327', '16763080');
+INSERT INTO t1 VALUES ( '40', '39', '2.0000000000', '2.0000000000', 'vihm', '8355839', '16777215');
+INSERT INTO t1 VALUES ( '53', '1', '-35.0000000000', '-5.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '41', '39', '3.0000000000', '3.0000000000', 'külm vihm', '120', '16763080');
+INSERT INTO t1 VALUES ( '12', '21', '21.0000000000', '21.0000000000', 'Kuiv', '13158600', '16777215');
+INSERT INTO t1 VALUES ( '13', '21', '13.0000000000', '13.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '14', '21', '22.0000000000', '22.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '19', '21', '33.0000000000', '33.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '15', '21', '23.0000000000', '23.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '16', '21', '31.0000000000', '31.0000000000', 'Kuiv', '13158600', '16777215');
+INSERT INTO t1 VALUES ( '17', '21', '12.0000000000', '12.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '18', '21', '32.0000000000', '32.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '20', '21', '331.0000000000', '331.0000000000', 'Härmatise hoiatus!', '14448840', '13158600');
+INSERT INTO t1 VALUES ( '21', '21', '11.0000000000', '11.0000000000', 'Kuiv', '13158600', '16777215');
+INSERT INTO t1 VALUES ( '22', '33', '21.0000000000', '21.0000000000', 'Pilves, kuiv', '8355711', '12632256');
+INSERT INTO t1 VALUES ( '23', '33', '13.0000000000', '13.0000000000', 'Sajab, märg', '0', '8355839');
+INSERT INTO t1 VALUES ( '24', '33', '22.0000000000', '22.0000000000', 'Pilves, niiske', '8355711', '12632319');
+INSERT INTO t1 VALUES ( '29', '33', '33.0000000000', '33.0000000000', 'Selge, märg', '16777215', '8355839');
+INSERT INTO t1 VALUES ( '25', '33', '23.0000000000', '23.0000000000', 'Pilves, märg', '8355711', '8355839');
+INSERT INTO t1 VALUES ( '26', '33', '31.0000000000', '31.0000000000', 'Selge, kuiv', '16777215', '12632256');
+INSERT INTO t1 VALUES ( '27', '33', '12.0000000000', '12.0000000000', 'Sajab, niiske', '0', '12632319');
+INSERT INTO t1 VALUES ( '28', '33', '32.0000000000', '32.0000000000', 'Selge, niiske', '16777215', '12632319');
+INSERT INTO t1 VALUES ( '30', '33', '331.0000000000', '331.0000000000', 'Härmatis! selge,kuiv', '16711680', '12632256');
+INSERT INTO t1 VALUES ( '31', '33', '11.0000000000', '11.0000000000', 'Sajab, kuiv', '0', '12632256');
+INSERT INTO t1 VALUES ( '32', '11', '1.0000000000', '1.0000000000', 'Korras', '16777215', '49152');
+INSERT INTO t1 VALUES ( '33', '21', '335.0000000000', '335.0000000000', 'Härmatis!', '14448840', '11842740');
+INSERT INTO t1 VALUES ( '34', '21', '134.0000000000', '134.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '35', '21', '133.0000000000', '133.0000000000', 'Hoiatus, märg!', '5263615', '13158600');
+INSERT INTO t1 VALUES ( '36', '21', '135.0000000000', '135.0000000000', 'Härmatis!', '14448840', '11842740');
+INSERT INTO t1 VALUES ( '37', '21', '334.0000000000', '334.0000000000', 'Härmatise hoiatus!', '14448840', '13158600');
+INSERT INTO t1 VALUES ( '38', '21', '132.0000000000', '132.0000000000', 'Hoiatus, niiske!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '39', '39', '1.0000000000', '1.0000000000', 'ei saja', '11206570', '16777215');
+INSERT INTO t1 VALUES ( '44', '39', '4.0000000000', '5.0000000000', 'lumi', '16711680', '16763080');
+INSERT INTO t1 VALUES ( '45', '12', '0.0000000000', '0.0000000000', '', '16777215', '14474460');
+INSERT INTO t1 VALUES ( '46', '39', '8.0000000000', '8.0000000000', 'rahe', '9830400', '16763080');
+INSERT INTO t1 VALUES ( '47', '39', '9.0000000000', '9.0000000000', 'tüüp ebaselge', '12582912', '16777215');
+INSERT INTO t1 VALUES ( '48', '39', '7.0000000000', '7.0000000000', 'lumetuisk', '7209070', '16763080');
+INSERT INTO t1 VALUES ( '142', '15', '2.0000000000', '49.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '52', '1', '-4.9000000000', '-0.1000000000', '', '0', '15774720');
+INSERT INTO t1 VALUES ( '141', '15', '-4.9000000000', '-0.1000000000', '', '0', '15774720');
+INSERT INTO t1 VALUES ( '55', '8', '0.0000000000', '0.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '56', '8', '0.0100000000', '0.1000000000', '', '0', '16770560');
+INSERT INTO t1 VALUES ( '57', '8', '0.1100000000', '25.0000000000', '', '0', '15774720');
+INSERT INTO t1 VALUES ( '58', '2', '90.0000000000', '94.9000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '59', '6', '0.0000000000', '360.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '61', '21', '38.0000000000', '38.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '62', '38', '500.0000000000', '999.0000000000', '', '0', '16770560');
+INSERT INTO t1 VALUES ( '63', '38', '1000.0000000000', '2000.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '64', '17', '0.0000000000', '0.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '65', '17', '0.1000000000', '10.0000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '67', '21', '412.0000000000', '412.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '68', '21', '413.0000000000', '413.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '69', '21', '113.0000000000', '113.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '70', '21', '416.0000000000', '416.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '71', '38', '0.0000000000', '499.0000000000', '', NULL, '16711680');
+INSERT INTO t1 VALUES ( '72', '22', '-49.0000000000', '49.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '73', '13', '0.0000000000', '9.9000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '74', '13', '10.0000000000', '14.9000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '75', '7', '0.0000000000', '50.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '76', '18', '0.0000000000', '0.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '77', '18', '0.1000000000', '10.0000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '78', '19', '300.0000000000', '400.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '79', '19', '0.0000000000', '299.0000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '80', '23', '0.0000000000', '100.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '81', '24', '0.0000000000', '200.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '82', '26', '0.0000000000', '0.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '83', '26', '0.1000000000', '5.0000000000', '', NULL, '16776960');
+INSERT INTO t1 VALUES ( '84', '21', '422.0000000000', '422.0000000000', 'Niiske', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '85', '21', '411.0000000000', '411.0000000000', 'Saju hoiat.,kuiv!', '16777215', '13158600');
+INSERT INTO t1 VALUES ( '86', '21', '423.0000000000', '423.0000000000', 'Märg', '5263615', '16777215');
+INSERT INTO t1 VALUES ( '144', '16', '-49.0000000000', '-5.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '88', '16', '2.0000000000', '49.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '89', '21', '338.0000000000', '338.0000000000', 'Härm.hoiatus, N+S!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '90', '21', '332.0000000000', '332.0000000000', 'Härm.hoiat., niiske!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '91', '21', '114.0000000000', '114.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '92', '21', '117.0000000000', '117.0000000000', 'Hoiatus, JÄÄ!', '14448840', '16711680');
+INSERT INTO t1 VALUES ( '93', '21', '116.0000000000', '116.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '94', '21', '414.0000000000', '414.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '95', '21', '325.0000000000', '325.0000000000', 'Härmatis!', '14448840', '11842740');
+INSERT INTO t1 VALUES ( '96', '21', '321.0000000000', '321.0000000000', 'Härmatise hoiatus!', '14448840', '13158600');
+INSERT INTO t1 VALUES ( '97', '21', '328.0000000000', '328.0000000000', 'Härm.hoiatus, N+S!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '98', '21', '28.0000000000', '28.0000000000', 'Niiske ja sool', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '99', '21', '118.0000000000', '118.0000000000', 'Hoiatus, N+S!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '100', '21', '418.0000000000', '418.0000000000', 'Hoiatus, N+S!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '101', '21', '322.0000000000', '322.0000000000', 'Härm.hoiat., niiske!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '102', '21', '428.0000000000', '428.0000000000', 'Hoiatus, N+S!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '103', '21', '432.0000000000', '432.0000000000', 'Hoiatus, niiske!', '7895240', '13158600');
+INSERT INTO t1 VALUES ( '104', '21', '421.0000000000', '421.0000000000', 'Saju hoiat.,kuiv!', '16777215', '13158600');
+INSERT INTO t1 VALUES ( '105', '21', '24.0000000000', '24.0000000000', 'Märg ja sool', '255', '16777215');
+INSERT INTO t1 VALUES ( '106', '21', '438.0000000000', '438.0000000000', 'Hoiatus, N+S!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '107', '21', '112.0000000000', '112.0000000000', 'Hoiatus, niiske!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '108', '21', '34.0000000000', '34.0000000000', 'Märg ja sool', '255', '16777215');
+INSERT INTO t1 VALUES ( '109', '21', '434.0000000000', '434.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '110', '21', '124.0000000000', '124.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '111', '21', '424.0000000000', '424.0000000000', 'Hoiatus, M+S!', '255', '13158600');
+INSERT INTO t1 VALUES ( '112', '21', '123.0000000000', '123.0000000000', 'Hoiatus, märg!', '5263615', '13158600');
+INSERT INTO t1 VALUES ( '140', '15', '-49.0000000000', '-5.0000000000', '', '0', '16777215');
+INSERT INTO t1 VALUES ( '114', '21', '18.0000000000', '18.0000000000', 'Niiske ja sool', '9869055', '16777215');
+INSERT INTO t1 VALUES ( '115', '21', '122.0000000000', '122.0000000000', 'Hoiatus, niiske!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '116', '21', '14.0000000000', '14.0000000000', 'Märg ja sool', '255', '16777215');
+INSERT INTO t1 VALUES ( '117', '21', '311.0000000000', '311.0000000000', 'Härmatise hoiatus!', '14448840', '13158600');
+INSERT INTO t1 VALUES ( '121', '2', '95.0000000000', '100.0000000000', '', NULL, '15774720');
+INSERT INTO t1 VALUES ( '118', '2', '0.0000000000', '89.9000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '119', '21', '16.0000000000', '16.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '120', '21', '26.0000000000', '26.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '122', '13', '15.0000000000', '50.0000000000', '', NULL, '15774720');
+INSERT INTO t1 VALUES ( '123', '5', '0.0000000000', '9.9000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '124', '5', '10.0000000000', '14.9000000000', '', NULL, '16770560');
+INSERT INTO t1 VALUES ( '125', '5', '15.0000000000', '50.0000000000', '', NULL, '15774720');
+INSERT INTO t1 VALUES ( '126', '21', '128.0000000000', '128.0000000000', 'Hoiatus, N+S!', '9869055', '13158600');
+INSERT INTO t1 VALUES ( '127', '21', '318.0000000000', '318.0000000000', 'Härm.hoiatus, N+S!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '128', '21', '312.0000000000', '312.0000000000', 'Härm.hoiat., niiske!', '16744319', '13158600');
+INSERT INTO t1 VALUES ( '129', '21', '126.0000000000', '126.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '130', '21', '324.0000000000', '324.0000000000', 'Härmatise hoiatus!', '14448840', '13158600');
+INSERT INTO t1 VALUES ( '131', '21', '316.0000000000', '316.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '132', '1', '0.0000000000', '1.9000000000', '', NULL, '16769024');
+INSERT INTO t1 VALUES ( '134', '3', '-50.0000000000', '50.0000000000', '', NULL, '16777215');
+INSERT INTO t1 VALUES ( '135', '8', '26.0000000000', '2000.0000000000', '', '9868950', '15774720');
+INSERT INTO t1 VALUES ( '136', '21', '426.0000000000', '426.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '137', '21', '127.0000000000', '127.0000000000', 'Hoiatus, JÄÄ!', '14448840', '16711680');
+INSERT INTO t1 VALUES ( '138', '21', '121.0000000000', '121.0000000000', 'Kuiv', '13158600', '16777215');
+INSERT INTO t1 VALUES ( '139', '21', '326.0000000000', '326.0000000000', 'Lumine!', '16711680', '11842740');
+INSERT INTO t1 VALUES ( '143', '16', '-4.9000000000', '-0.1000000000', '', NULL, '15774720');
+INSERT INTO t1 VALUES ( '145', '15', '0.0000000000', '1.9000000000', '', '0', '16769024');
+INSERT INTO t1 VALUES ( '146', '16', '0.0000000000', '1.9000000000', '', '0', '16769024');
+select * from t1 where minvalue<=1 and maxvalue>=-1 and datatype_id=16;
id datatype_id minvalue maxvalue valuename forecolor backcolor
143 16 -4.9000000000 -0.1000000000 NULL 15774720
146 16 0.0000000000 1.9000000000 0 16769024
+select * from t1 where minvalue<=-1 and maxvalue>=-1 and datatype_id=16;
id datatype_id minvalue maxvalue valuename forecolor backcolor
143 16 -4.9000000000 -0.1000000000 NULL 15774720
+drop table t1;
+create table t1 (a decimal(10,2));
+insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0");
+insert into t1 values ("-.1"),("+.1"),(".1");
+insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
+insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
+insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
+select * from t1;
a
0.00
-0.00
@@ -22,18 +178,36 @@ a
-99999999.99
999999999.99
999999999.99
-a
+999999999.99
0.00
+-99999999.99
+123.40
+12340.00
+1.23
+1230.00
+123.00
+drop table t1;
+create table t1 (a decimal(10,2) unsigned);
+insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0");
+insert into t1 values ("-.1"),("+.1"),(".1");
+insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
+insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
+insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
+select * from t1;
+a
0.00
0.00
++0.00
01.00
-01.00
++01.00
0.00
0.00
-0.10
++0.10
0.10
00000001.00
-00000001.00
++0000001.00
0.00
99999999.99
99999999.99
@@ -41,6 +215,24 @@ a
0.00
99999999.99
99999999.99
+99999999.99
+0.00
+0.00
+123.40
+12340.00
+1.23
+1230.00
+123.00
+drop table t1;
+create table t1 (a decimal(10,2) zerofill);
+insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0");
+insert into t1 values ("-.1"),("+.1"),(".1");
+insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
+insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
+insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
+select * from t1;
a
00000000.00
00000000.00
@@ -60,6 +252,24 @@ a
00000000.00
99999999.99
99999999.99
+99999999.99
+00000000.00
+00000000.00
+00000123.40
+00012340.00
+00000001.23
+00001230.00
+00000123.00
+drop table t1;
+create table t1 (a decimal(10,2));
+insert into t1 values (0.0),("-0.0"),(+0.0),(01.0),(+01.0),(-01.0);
+insert into t1 values (-.1),(+.1),(.1);
+insert into t1 values (00000000000001),(+0000000000001),(-0000000000001);
+insert into t1 values (+111111111.11),(111111111.11),(-11111111.11);
+insert into t1 values (-111111111.11),(+1111111111.11),(1111111111.11);
+insert into t1 values (1e+100),(1e-100),(-1e+100);
+insert into t1 values (123.4e0),(123.4e+2),(123.4e-2),(123e1),(123e+0);
+select * from t1;
a
0.00
-0.00
@@ -79,6 +289,18 @@ a
-99999999.99
999999999.99
999999999.99
+999999999.99
+0.00
+-99999999.99
+123.40
+12340.00
+1.23
+1230.00
+123.00
+drop table t1;
+create table t1 (a decimal);
+insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+12345678901'),(99999999999999);
+select * from t1;
a
-9999999999
-1
@@ -87,14 +309,22 @@ a
+0000000001
12345678901
99999999999
+drop table t1;
+create table t1 (a decimal unsigned);
+insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999);
+select * from t1;
a
0
0
-1
++1
01
-0000000001
++000000001
1234567890
9999999999
+drop table t1;
+create table t1 (a decimal zerofill);
+insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999);
+select * from t1;
a
0000000000
0000000000
@@ -103,6 +333,10 @@ a
0000000001
1234567890
9999999999
+drop table t1;
+create table t1 (a decimal unsigned zerofill);
+insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999);
+select * from t1;
a
0000000000
0000000000
@@ -111,3 +345,216 @@ a
0000000001
1234567890
9999999999
+drop table t1;
+create table t1(a decimal(10,0));
+insert into t1 values ("1e4294967295");
+select * from t1;
+a
+99999999999
+delete from t1;
+insert into t1 values("1e4294967297");
+select * from t1;
+a
+99999999999
+drop table t1;
+CREATE TABLE t1 (a_dec DECIMAL(-1,0));
+Too big column length for column 'a_dec' (max = 255). Use BLOB instead
+CREATE TABLE t1 (a_dec DECIMAL(-2,1));
+Too big column length for column 'a_dec' (max = 255). Use BLOB instead
+CREATE TABLE t1 (a_dec DECIMAL(-1,1));
+Too big column length for column 'a_dec' (max = 255). Use BLOB instead
+create table t1(a decimal(7,3));
+insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000');
+select * from t1;
+a
+1.000
++1.000
+-1.000
+00001.000
++0001.000
+-0001.000
+10.000
++10.000
+-10.000
+00010.000
++0010.000
+-0010.000
+100.000
++100.000
+-100.000
+00100.000
++0100.000
+-0100.000
+1000.000
++1000.000
+-1000.000
+01000.000
++1000.000
+-1000.000
+10000.000
+10000.000
+-9999.999
+10000.000
+10000.000
+-9999.999
+99999.999
+99999.999
+-9999.999
+99999.999
+99999.999
+-9999.999
+99999.999
+99999.999
+-9999.999
+99999.999
+99999.999
+-9999.999
+99999.999
+99999.999
+-9999.999
+99999.999
+99999.999
+-9999.999
+99999.999
+99999.999
+-9999.999
+99999.999
+99999.999
+-9999.999
+99999.999
+99999.999
+-9999.999
+99999.999
+99999.999
+-9999.999
+drop table t1;
+create table t1(a decimal(7,3) unsigned);
+insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000');
+select * from t1;
+a
+1.000
++1.000
+0.000
+0001.000
++001.000
+0.000
+10.000
++10.000
+0.000
+0010.000
++010.000
+0.000
+100.000
++100.000
+0.000
+0100.000
++100.000
+0.000
+1000.000
+1000.000
+0.000
+1000.000
+1000.000
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+9999.999
+9999.999
+0.000
+drop table t1;
+create table t1(a decimal(7,3) zerofill);
+insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000');
+select * from t1;
+a
+0001.000
+0001.000
+0000.000
+0001.000
+0001.000
+0000.000
+0010.000
+0010.000
+0000.000
+0010.000
+0010.000
+0000.000
+0100.000
+0100.000
+0000.000
+0100.000
+0100.000
+0000.000
+1000.000
+1000.000
+0000.000
+1000.000
+1000.000
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+9999.999
+9999.999
+0000.000
+drop table t1;
diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result
index 35e27f6dd9e..03cfdc3c286 100644
--- a/mysql-test/r/type_enum.result
+++ b/mysql-test/r/type_enum.result
@@ -1,3 +1,10 @@
+DROP TABLE if exists t1;
+CREATE TABLE t1 (
+field enum('001001','001004','001010','001018','001019','001020','001021','001027','001028','001029','001030','001031','001100','002003','002004','002005','002007','002008','002009','002012','002013','002014','003002','003003','003004','003005','003006','003007','003008','003009','003010','003011','003012','003013','003014','003015','003016','003017','003018','003019','004002','004003','004005','004006','004007','004008','004010','004012','004014','004016','004017','004020','004021','004022','004023','004024','004025','004026','006002','006004','006006','006010','006011','006012','006013','006014','007001','007002','007003','007004','007005','007006','007007','007008','007009','007010','007011','007012','007013','007014','007015','007016','007017','007018','007019','007020','007021','007022','007023','007024','007025','007026','007027','007028','007029','007030','007031','007032','007033','007034','007035','007036','007037','007038','007039','007040','007043','007044','009001','009002','009004','009005','009006','009007','009008','009009','009010','009011','009012','009013','010002','010003','010004','010005','010006','010007','010008','010009','010010','010011','010012','010013','010015','010016','010017','010018','010019','010020','010021','010022','010023','010024','010025','010026','010027','010028','011001','011002','011003','011004','011006','011012','011013','011014','011015','011016','012017','012018','012019','012023','012027','012028','012029','012030','012031','012032','012033','012034','012035','012036','012037','012038','012039','014001','016002','016003','016004','016007','016010','016011','016016','016019','016020','016021','016022','016023','016024','016026','016027','016028','016029','016030','016031','016032','016033','016034','017002','018001','019002','019004','020001','020003','020004','020005','020006','020007','020008','020009','022001','022002','022003','023001','023002','023003','023004','023005','023006','023007','023008','023010','023011','023012','023017','023019','023020','023021','023025','023026','023027','023028','023029','023030','023031','023032','023033','023034','023035','025001','025003','025004','025005','025006','025007','025008','025009','025010','025011','025012','025013','025014','025015','025016','025017','025018','025019','025020','025021','025022','025023','025024','025025','025026','025027','025028','025029','025030','025031','025032','025033','025034','025035','025036','025037','025038','025039','025040','025041','025042','025043','025044','025045','025046','025047','025048','025049','025050','025051','025052','025053','025054','025055','025056','025057','025058','025059','025060','025061','025062','025063','027001','027002','027011','035008','035012','036001','037001','037003','037004','037005','037006','037007','037008','037009','038004','038005','038006','038007','038009','039001','039002','039003','039004','039005','039006','046001','046002','046003','046004','046005','046007','046008','046009','046010','046011','046012','046013','046014','047001','047002','048001','051001','051002','051003','051004','052001','052002','052005','053015','053016','053019','053020','053023','053024','053026','053028','053029','053033','053034','053036','053037','053038','053039','053041','053042','053043','053045','053046','053047','053048','053051','053052','053054','053055','053056','053057','053068','053069','053070','053073','053074','053075','053086','053094','053095','053096','053097','053098','053099','053100','053101','053102','053103','053104','053105','053107','053122','053123','053124','053125','053127','053128','054001','054002','054003','054004','054005','054006','054007','054009','054010','056001','056002','056003','056004','056005','056006','056009','056010','056011','056016','056017','056018','056019','056020','056021','056022','057001','057002','057003','057004','058002','058003','058004','058005','060001','060003','060004','060005','060006','060007','061002','061003','061004','061005','061006','069006','069007','069010','069011','069012','069013','069014','069015','069016','069017','069018','069020','069021','069022','069023','069024','071002','071003','071004','071005','071006','071008','071011','071013','071020','071021','071022','072001','073001','073002','073003','073004','074001','074002','074003','074004','074005','074006','074007','074008','074009','074010','074011','074012','075001','075007','076101','076102','076103','077001','077002','077003','077004','077006','077007','077008','077009','078005','079002','079003','079004','079005','079006','079007','081001','082006','082007','082011','082013','082014','082015','082016','082017','082021','082022','082023','082024','082025','082026','082027','082028','082029','082030','082031','082032','082033','082034','082035','082036','082037','082038','082039','082040','082041','082042','082043','082044','084001','084002','084003','084004','084005','084007','084008','084009','084011','084013','084014','084016','084017','084027','084031','084032','084033','084035','084036','084037','084038','084039','084040','084041','084042','084043','084044','084045','084046','084047','084048','084049','084050','084051','085001','085002','085003','085004','085005','085006','085007','085009','085011','085012','085013','085014','085015','085016','085017','085018','085019','085020','085021','085022','085023','085028','085029','085030','085031','085033','085034','085035','085036','085037','085038','085040','085041','085042','085043','085044','085045','085046','085047','085048','085063','085064','085065','085068','085070','085071','085073','085082','085083','085086','085088','085089','085090','085091','085092','085093','085094','085095','085096','085097','085098','085099','085100','085101','085102','085103','085104','085105','085106','085107','085108','085109','085110','085111','085112','085113','085115','085119','085120','085121','085122','085123','085124','085125','085126','085127','085128','085129','085130','085132','085133','085134','085135','085136','085137','086001','086002','086003','086004','086005','088001','088003','088005','088006','088007','088008','088009','089001','090001','090002','090003','090004','090005','090006','090007','090008','090009','090010','090013','090015','090016','090017','090018','090019','090022','090027','090028','091001','091002','091005','091008','091009','091010','091011','091012','091013','091014','091015','091016','091017','091018','093001','093003','093098','093100','093102','093104','093141','093142','093146','093151','093153','093167','093168','093176','094001','094002','094004','094005','095004','099001','099002','100001','101001','102002','102003','105001','105002','106001','113001','113002','113003','113004','113005','113006','113007','113008','113009','113010','113011','113012','113013','113014','113015','113016','113017','113018','113019','113020','113021','113022','113023','113024','113025','113026','113027','113028','114001','115001','115002','115003','115004','115005','115006','115007','115008','115009','115010','115011','115012','115013','115014','115015','115016','115017','115018','115020','115021','115022','115023','115025','115026','115027','115028','115029','115030','115031','115032','115033','115034','115035','115036','115039','115040','115041','115042','115043','115044','115045','115046','115047','115048','115049','115050','115051','115052','115053','115054','115055','115056','115057','115059','115060','115061','115062','115063','115064','115065','115066','115067','115068','115069','115070','115071','115072','115073','115075','115076','115081','115082','115085','115086','115087','115088','115095','115096','115097','115098','115099','115101','115102','115103','115104','115105','115106','115108','115109','115110','115111','115112','115113','115114','115115','115116','115117','115118','115119','115120','115121','115122','116001','116002','116003','116004','116005','116006','116007','116008','116009','116010','116011','116012','117001','117002','117003','123001','124010','124014','124015','124019','124024','124025','124026','124027','124028','124029','124030','124031','124032','124033','124035','124036','124037','124038','124039','124040','124041','124042','124043','124044','124045','124046','124047','124048','124049','124050','124051','124052','124053','124054','124055','124056','124057','124058','124059','124060','124061','124062','124063','124064','124065','126001','126002','126003','126004','126005','126006','126007','126008','126009','126010','126011','126012','130001','132001','132002','132003','133001','133008','133009','133010','133011','133012','133013','133014','133015','133016','133017','133018','133019','133020','133021','133022','133023','133024','133025','133027','133028','133029','133030','133031','134001','135001','135002','135003','135004','135005','135006','135007','135008','135009','135010','136001','137009','137010','137011','137012','137013','137014','137015','137016','137017','137018','137019','138001','138002','138003','138004','139001','139003','140001','141001','141002','141003','141006','141007','141008','141009','141011','141012','141014','141015','141016','141017','141018','141019','141020','141021','141022','141023','141024','141025','141026','141027','141028','142001','142002','142003','142004','142005','142006','142007','142008','142010','142011','142012','144001','145001','145002','145003','145004','145005','145006','145007','145008','145009','145010','145011','145012','145013','145014','145015','145016','147001','150003','150005','150009','150013','150014','150015','150016','150017','150020','150021','152001','152002','152003','152004','152005','152006','152007','154001','154002','154003','155001','155002','155003','155004','155005','155006','159001','159002','159003','159004','160001','160002','160003','161001','162001','162002','162003','162004','162007','162010','162011','162012','163001','163002','163003','163005','163010','163011','163014','163015','163016','165001','165002','165003','165004','165005','165006','165007','165008','165009','165010','165011','165012','165013','165014','165015','165016','165017','165018','165019','165020','165021','165022','165023','165024','165025','165026','165027','165028','165029','165030','165031','165032','165033','165034','165035','165036','167001','168001','168002','168003','168004','168005','168007','168008','168009','168010','168011','168012','168013','168014','169001','169002','169003','169007','169008','169009','169010','170001','171001','171002','171003','171004','171005','171006','171007','171008','171009','172001','174001','174002','174003','176001','176002','176003','177001','177002','179001','179002','179003','179004','179005','179006','179007','179008','179009','179010','179011','179012','179013','179014','179015','179016','179017','179018','179019','179020','179021','179022','179023','179024','179025','179026','179027','179028','179029','179030','179031','179032','179033','179034','179035','179036','179037','179038','179039','179040','179041','179042','179043','179044','179045','179046','179047','180001','180010','180012','180013','180014','180015','180016','180017','180018','180019','180020','180021','180022','180023','180024','180025','180026','180027','180028','180030','180031','180032','180033','180034','180035','180036','180037','180038','180039','180041','180042','180043','180044','180045','180046','180047','180048','180049','180050','180051','180052','180053','180054','180055','180056','180057','180058','180059','180060','180061','180062','180063','180064','180065','180066','180067','180068','180069','180070','180071','182001','184001','184002','184005','184006','184007','184008','184009','184010','184011','185001','185003','187001','188001','188002','188003','188004','188005','188006','188007','188008','188009','188010','188011','191001','191002','192002','194001','194002','194003','194004','194005','194006','194007','195001','195002','195003','195004','195005','195006','195007','196001','196002','197001','197002','197003','197004','197005','197006','198001','198003','198004','198005','198006','198007','198008','198009','198010','198011','198012','198013','198014','198015','198016','198017','201001','201002','201005','202001','203001','203002','203003','203017','203018','203019','204001','204002','204003','205001','208001','208002','208003','208004','208005','209001','209002','209003','210001','210002','210003','210004','210005','210006','210007','210008','210009','210010','210011','210012','210013','211017','212001','212002','212003','212004','212005','212006','212007','212008','212009','212010','212011','212012','212013','218001','218003','218004','218006','218007','218008','218009','218011','218015','218016','218017','218018','218019','218020','218021','218022','218023','218024','218025','218026','218027','218028','218029','218030','218031','218032','218033','218034','218035','218036','221001','221002','221003','221004','221005','221006','221007','221008','221009','221010','221011','221012','221013','223001','223002','223003','224001','224002','224003','224006','224007','224008','225001','225002','225003','225004','225005','225006','225007','225008','225009','225010','225011','225012','225013','226001','226002','226003','226004','226005','226006','226007','226008','226009','227001','227002','227003','227004','227005','227006','227007','227008','227009','227010','227011','227012','227013','227014','227015','227016','227017','227018','227019','227020','227021','227022','227023','227024','227025','227026','227027','227028','227029','227030','227031','227032','227033','227034','227035','227036','227037','227038','227039','227040','227041','227042','227043','227044','227045','227046','227047','227048','227049','227050','227051','227052','227053','227054','227055','227056','227057','227058','227059','227060','227061','227062','227063','227064','227065','227066','227067','227068','227069','227070','227071','227072','227073','227074','227075','227076','227077','227078','227079','227080','227081','227082','227083','227084','227085','227086','227087','227088','227089','227090','227091','227092','227093','227094','227095','227096','227097','227098','227099','227100','227101','227102','227103','227104','227105','227106','227107','227108','227109','227110','227111','227112','227113','227114','227115','227116','227117','227118','227119','227120','227122','227123','227124','227125','227126','227127','227128','227129','227130','227131','227132','227133','227134','227135','227136','227137','227138','227139','227140','227141','227142','227143','227144','227145','227146','227147','227148','227149','227150','227151','227152','228001','229001','229002','229003','229004','229005','230001','230002','232001','233001','233002','233003','233004','233005','233006','233007','233008','234001','234002','234003','234004','234005','234006','234007','234008','234009','234010','234011','234012','234013','234014','234015','234016','234017','234018','234019','234020','234021','234022','234023','234024','234025','234026','234027','234028','234029','234030','235001','235002','235003','235004','235005','236001','236002','236003','237001','238002','238003','238004','238005','238006','238007','238008','333013','333014','333015','333016','333017','333018','333019','333020','333021','333022','333023','333024','333025','333030','333031','333032','333033','333034','333035','334001','334002','334003','334004','334005','334006','334007','336004','337001','337002','337003','337004','339001','339002','343001','344001','344002','344003','344004','344005','345001','345002','345003','347001','347002','348001','348002','348003','348004','348005','349001','349002','349003','350001','353001','353002','353003','353004','355001','355002','355003','355004','355005','355006','356001','358001','359001','359002','360001','360002','360003','360004','360005','366001','366002','366003','366004','369001','373001','373002','373003','373004','373005','373006','373007','373008','373009','373010','373011','373012','373013','373014','373015','373016','373017','373018','373019','373020','373021','374001','374002','374003','374004','374005','374006','374007','374008','374009','374010','374011','374012','374013','374014','374015','374016','376001','376002','376003','376004','376005','376006','376007','376008','376009','376010','376011','376012','376013','376016','376017','376018','376019','376020','376021','379003','382001','382002','383001','384001','384002','385001','385002','386001','386002','386003','386004','386005','386006','386007','386008','386009','386010','386011','386012','386013','386014','387001','389001','389002','389003','389004','392001','393001','393002','393003','393004','395001','396001','397001','397002','399001','399002','399003','400001','400002','401001','401002','401003','402001','402002','402003','402004','402005','403001','403002','403003','504001','504002','504004','504005','504006','504007','504008','504009','504010','504011','504012','504013','504014','504017','504018','504019','504021','504022','504023','504024','504025','506001','506002','508001','508002','511001','511002','511003','511004','511005','511006','511007','511008','511009','511010','511011','511012','511013','511014','511017','511018','511020','511021','511022','511024','511028','511029','513001','513002','513003','513004','514001','515001','515002','515003','515007','515008','515009','515010','515011','515012','515013','515014','515015','518001','518002','518003','520001','520002','521001','521002','521003','521004','521005','521006','521007','521008','521009','521010','521011','521012','521013','521014','521015','521016','523001','523002','523003','523004','523005','523006','523007','524001','700001','701001','701002','701003','702001','702002','702003','702004','702005','702006','702007','702008','703001','703002','703003','704001','704002','704003','704004','705001','706001','706002','707001','707002','707003','708001','709001','709002','710001','710002','711001','711002','712001','713001','713002','714001','714002','715001','716001','718001','718002','719001','719002','991001','991002','991003','991004','991005','991006','991007','991008','992001','995001','996001','996002','996003','998001','998002','998003','998004','998005','998006','998007','999001','999002','011017','011018','034001','034002','071010','208006','239001','519001','519003','126013','184012','053071','374017','374018','374019','374020','374021','404001','405002','405001','405003','405007','405006','405005','405004','240011','240010','240009','240008','240007','240006','240005','240004','240003','240002','240001','240012','240013','240014','240015','240016','240017','357001','235006','235007','712002','355008','355007','056023','999999','046015','019005','126014','241003','241002','241001','240018','240020','240019','242001','242002','242003','242004','242005','242006','089002','406001','406002','406003','406004','406005','406006','243001','243002','243003','243004','243005','243006','243007','243008','010030','010029','407001','407006','407005','407004','407003','407002','408001','366005','133032','016035','077010','996004','025064','011019','407007','407008','407009','409001','115123','504026','039007','039009','039008','039010','039011','039012','180072','240021','240023','408002','405008','235008','525001','525002','525003','525004','410001','410002','410003','410004','410005','410006','410007','410008','410009','410010','410011','410012','410013','410014','410015','410016','344006','240031','240030','240029','240028','240027','240026','240025','240024','240034','240033','240032','410017','410018','411001','411002','411003','411004','411005','411006','411007','411008','203020','203021','203022','412001','412002','412003','412004','069025','244001','244002','244009','244008','244007','244006','244005','244004','244003','244015','244014','244013','244012','244011','244010','244016','244017','240042','240041','240040','240039','240038','240037','240036','240035','405009','405010','240043','504034','504033','504032','504031','504030','504029','504028','504027','504042','504041','504040','504039','504038','504037','504036','504035','800001','410019','410020','410021','244018','244019','244020','399004','413001','504043','198018','198019','344007','082045','010031','010032','010033','010034','010035','504044','515016','801002','801003','801004','801005','802001','801001','414001','414002','414003','141029','141030','803001','803002','803003','803004','803005','803006','803007','803008','803009','803010','803011','803012','803013','803014','803015','803016','803017','410022','410023','803018','803019','803020','415002','415001','244021','011020','011023','011022','011021','025065','165037','165038','165039','416001','416002','416003','417001','418001','504045','803022','803021','240022','419001','420001','804010','804009','804008','804007','804006','804005','804004','804003','804002','804001','804020','804019','804018','804017','804016','804015','804014','804013','804012','804011','804024','804021','804023','804022','511019','511016','511015','511032','511031','511030','511027','511026','511025','511033','511023','133034','133033','169011','344008','344009','244022','244026','244025','244030','244023','244024','244027','244028','244029','244031','082046','082047','082048','126015','126016','416004','416005','421001','421002','016037','016036','115124','115125','115126','240049','240048','240047','240046','240045','240044','244032','244033','422001','422002','422003','422004','422005','184013','239002','805001','805002','805003','805004','805005','056024','423001','344010','235009','212014','056025','056026','802002','244034','244035','244036','244037','244038','244039','515017','504046','203015','245002','245001','071023','056027','056028','056029','056030','056031','056032','424001','056034','056033','805006','805007','805008','805009','805010','422008','422007','422006','422010','422009','422011','209004','150022','150023','100002','056035','023036','185004','185005','246001','247001','247002','425001','416006','165042','165041','165040','165043','010040','010039','010038','010037','010036','422012','422013','422014','422015','426000','248001','248002','248003','248004','248005','249001','249002','249003','249004','249005','249006','250007','250001','250002','250003','250004','250005','250006','250008','250009','250010','250011','250012','250013','251001','251002','422016','422017','422018','806001','806002','116013','235010','235011','091026','091027','091028','091029','091019','091020','091021','091022','091023','091024','091025','252001','243009','249007','249008','249009','011024','011025','427001','428002','428001','169012','429001','429002','429003') DEFAULT '001001' NOT NULL,
+KEY field (field)
+);
+INSERT INTO t1 VALUES ('001001'),('001001'),('001001'),('001001'),('001001'),('001001'),('001001'),('001001'),('001001'),('001010'),('001010'),('001010'),('001010'),('001010'),('001018'),('001018'),('001018'),('001018'),('001018'),('001018'),('001020'),('001020'),('001020'),('001020'),('001020'),('001020'),('001020'),('001020'),('001021'),('001021'),('001021'),('001021'),('001021'),('001021'),('001027'),('001027'),('001028'),('001030'),('001030'),('001030'),('001030'),('001031'),('001031'),('001031'),('001031'),('001031'),('001100'),('001100'),('002003'),('002003'),('002003'),('002003'),('002003'),('002003'),('002003'),('002003'),('002003'),('002004'),('002004'),('002004'),('002004'),('002004'),('002004'),('002004'),('002004'),('002004'),('002005'),('002005'),('002005'),('002005'),('002005'),('002005'),('002005'),('002005'),('002007'),('002007'),('002007'),('002007'),('002007'),('002007'),('002007'),('002008'),('002008'),('002008'),('002008'),('002008'),('002008'),('002008'),('002008'),('002009'),('002009'),('002009'),('002009'),('002009'),('002009'),('002009'),('002009'),('002012'),('002012'),('002012'),('002012'),('002012'),('002012'),('002012'),('002013'),('002013'),('002013'),('002013'),('002013'),('002013'),('002013'),('002013'),('002013'),('002014'),('002014'),('002014'),('002014'),('002014'),('002014'),('002014'),('002014'),('003002'),('003002'),('003002'),('003002'),('003002'),('003002'),('003003'),('003003'),('003003'),('003003'),('003003'),('003003'),('003004'),('003004'),('003004'),('003004'),('003004'),('003004'),('003005'),('003005'),('003005'),('003005'),('003005'),('003005'),('003005'),('003005'),('003005'),('003006'),('003006'),('003006'),('003006'),('003006'),('003006'),('003006'),('003006'),('003007'),('003007'),('003007'),('003007'),('003007'),('003008'),('003008'),('003008'),('003008'),('003008'),('003008'),('003009'),('003009'),('003009'),('003009'),('003009'),('003009'),('003009'),('003009'),('003009'),('003010'),('003010'),('003010'),('003010'),('003010'),('003010'),('003010'),('003010'),('003010'),('003011'),('003011'),('003011'),('003011'),('003011'),('003011'),('003011'),('003011'),('003012'),('003012'),('003012'),('003012'),('003012'),('003012'),('003012'),('003012'),('003013'),('003013'),('003013'),('003013'),('003013'),('003013'),('003013'),('003013'),('003014'),('003014'),('003014'),('003014'),('003014'),('003014'),('003014'),('003014'),('003015'),('003015'),('003015'),('003015'),('003015'),('003015'),('003016'),('003016'),('003016'),('003016'),('003016'),('003016'),('003017'),('003017'),('003017'),('003017'),('003017'),('003018'),('003018'),('003018'),('003018'),('003018'),('003019'),('003019'),('004003'),('004005'),('004005'),('004005'),('004005'),('004005'),('004005'),('004006'),('004008'),('004010'),('004012'),('004012'),('004014'),('004014'),('004014'),('004014'),('004014'),('004016'),('004017'),('004017'),('004017'),('004017'),('004017'),('004017'),('004017'),('004017'),('004020'),('004020'),('004020'),('004020'),('004020'),('004020'),('004021'),('004021'),('004021'),('004021'),('004021'),('004021'),('004021'),('004022'),('004023'),('004023'),('004023'),('004023'),('004023'),('004023'),('004023'),('004025'),('004026'),('004026'),('004026'),('004026'),('004026'),('006004'),('006006'),('006010'),('006010'),('006010'),('006010'),('006010'),('006010'),('006010'),('006011'),('006011'),('006011'),('006011'),('006011'),('006011'),('006012'),('006012'),('006012'),('006012'),('006012'),('006012'),('006014'),('006014'),('006014'),('007001'),('007001'),('007002'),('007003'),('007005'),('007007'),('007008'),('007009'),('007011'),('007012'),('007013'),('007015'),('007016'),('007017'),('007018'),('007019'),('007019'),('007020'),('007021'),('007021'),('007022'),('007023'),('007023'),('007025'),('007025'),('007025'),('007027'),('007029'),('007031'),('007031'),('007032'),('007034'),('007034'),('007036'),('007036'),('007036'),('007037'),('007037'),('007038'),('007040'),('007040'),('007040'),('007043'),('009001'),('009001'),('009001'),('009001'),('009001'),('009001'),('009001'),('009002'),('009002'),('009002'),('009002'),('009002'),('009004'),('009004'),('009004'),('009004'),('009005'),('009005'),('009005'),('009005'),('009005'),('009005'),('009005'),('009005'),('009006'),('009006'),('009006'),('009006'),('009007'),('009007'),('009007'),('009007'),('009007'),('009007'),('009008'),('009010'),('009010'),('009010'),('009010'),('009010'),('009010'),('009011'),('009011'),('009011'),('009011'),('009011'),('009012'),('009013'),('009013'),('009013'),('010002'),('010002'),('010002'),('010002'),('010002'),('010002'),('010002'),('010002'),('010003'),('010003'),('010003'),('010003'),('010003'),('010003'),('010003'),('010003'),('010003'),('010004'),('010004'),('010004'),('010004'),('010004'),('010004'),('010004'),('010004'),('010004'),('010005'),('010005'),('010005'),('010005'),('010006'),('010006'),('010006'),('010006'),('010006'),('010006'),('010006'),('010006'),('010006'),('010007'),('010007'),('010007'),('010007'),('010007'),('010007'),('010008'),('010008'),('010008'),('010008'),('010008'),('010008'),('010008'),('010009'),('010009'),('010009'),('010009'),('010009'),('010009'),('010010'),('010010'),('010010'),('010010'),('010010'),('010010'),('010010'),('010011'),('010011'),('010011'),('010011'),('010011'),('010011'),('010011'),('010011'),('010012'),('010012'),('010012'),('010012'),('010012'),('010012'),('010012'),('010013'),('010013'),('010013'),('010013'),('010013'),('010013'),('010015'),('010016'),('010016'),('010016'),('010016'),('010016'),('010016'),('010016'),('010016'),('010017'),('010017'),('010017'),('010017'),('010017'),('010017'),('010018'),('010018'),('010018'),('010018'),('010018'),('010018'),('010018'),('010018'),('010018'),('010019'),('010019'),('010019'),('010019'),('010019'),('010019'),('010020'),('010020'),('010020'),('010021'),('010021'),('010021'),('010021'),('010021'),('010021'),('010022'),('010022'),('010022'),('010022'),('010022'),('010022'),('010022'),('010022'),('010023'),('010023'),('010023'),('010023'),('010023'),('010023'),('010023'),('010023'),('010026'),('010027'),('010028'),('010028'),('011001'),('011001'),('011001'),('011001'),('011001'),('011001'),('011001'),('011002'),('011002'),('011002'),('011002'),('011002'),('011002'),('011002'),('011003'),('011003'),('011003'),('011003'),('011003'),('011003'),('011003'),('011003'),('011004'),('011004'),('011004'),('011004'),('011004'),('011004'),('011004'),('011006'),('011006'),('011006'),('011006'),('011006'),('011006'),('011006'),('011012'),('011012'),('011012'),('011013'),('011013'),('011013'),('011013'),('011013'),('011013'),('011014'),('011014'),('011014'),('011014'),('011015'),('011015'),('011015'),('011015'),('011015'),('011016'),('011016'),('011016'),('011016'),('011016'),('012017'),('012017'),('012027'),('012027'),('012032'),('012034'),('012036'),('012036'),('012037'),('012037'),('012038'),('012039'),('014001'),('014001'),('016016'),('016016'),('016016'),('016019'),('016020'),('016020'),('016020'),('016020'),('016020'),('016020'),('016020'),('016020'),('016021'),('016021'),('016021'),('016021'),('016021'),('016021'),('016021'),('016022'),('016022'),('016022'),('016023'),('016023'),('016023'),('016024'),('016024'),('016024'),('016024'),('016024'),('016024'),('016024'),('016026'),('016026'),('016026'),('016026'),('016026'),('016026'),('016028'),('016028'),('016028'),('016028'),('016028'),('016028'),('016028'),('016029'),('016029'),('016030'),('016031'),('016032'),('016032'),('016032'),('016032'),('016032'),('016032'),('016032'),('016033'),('016033'),('016033'),('016033'),('016033'),('016034'),('016034'),('016034'),('016034'),('016034'),('017002'),('017002'),('017002'),('017002'),('017002'),('018001'),('018001'),('018001'),('018001'),('018001'),('018001'),('018001'),('018001'),('019002'),('019002'),('019002'),('019002'),('019002'),('019002'),('019004'),('019004'),('019004'),('019004'),('019004'),('019004'),('020001'),('020001'),('020001'),('020001'),('020004'),('020006'),('020006'),('020006'),('020006'),('020006'),('020006'),('020008'),('020009'),('020009'),('020009'),('020009'),('020009'),('022001'),('022001'),('022001'),('022001'),('022002'),('022002'),('022002'),('022002'),('022003'),('022003'),('022003'),('022003'),('023001'),('023002'),('023002'),('023002'),('023002'),('023002'),('023002'),('023003'),('023003'),('023003'),('023003'),('023004'),('023004'),('023005'),('023005'),('023006'),('023006'),('023006'),('023006'),('023006'),('023006'),('023007'),('023007'),('023010'),('023010'),('023011'),('023011'),('023017'),('023019'),('023019'),('023019'),('023020'),('023020'),('023025'),('023025'),('023025'),('023026'),('023026'),('023026'),('023027'),('023027'),('023027'),('023028'),('023028'),('023029'),('023029'),('023030'),('023030'),('023032'),('023033'),('023033'),('023033'),('023033'),('023033'),('023033'),('023034'),('023035'),('023035'),('025001'),('025001'),('025001'),('025001'),('025001'),('025001'),('025001'),('025003'),('025003'),('025004'),('025004'),('025005'),('025005'),('025007'),('025007'),('025008'),('025008'),('025009'),('025010'),('025010'),('025010'),('025011'),('025011'),('025012'),('025012'),('025013'),('025013'),('025013'),('025014'),('025015'),('025016'),('025018'),('025018'),('025019'),('025019'),('025020'),('025020'),('025021'),('025022'),('025022'),('025023'),('025023'),('025024'),('025025'),('025025'),('025026'),('025026'),('025027'),('025027'),('025027'),('025028'),('025030'),('025031'),('025033'),('025034'),('025035'),('025037'),('025041'),('025042'),('025043'),('025046'),('025048'),('025048'),('025048'),('025049'),('025049'),('025049'),('025050'),('025050'),('025050'),('025051'),('025051'),('025052'),('025052'),('025052'),('025053'),('025053'),('025054'),('025054'),('025054'),('025054'),('025055'),('025056'),('025056'),('025056'),('025056'),('025056'),('025056'),('025056'),('025056'),('025056'),('025057'),('025057'),('025058'),('025058'),('025060'),('025060'),('025061'),('025062'),('025063'),('027001'),('027002'),('027011'),('036001'),('036001'),('036001'),('036001'),('036001'),('037003'),('037006'),('037007'),('037008'),('037008'),('038009'),('039001'),('039001'),('039001'),('039001'),('039001'),('039001'),('039002'),('039002'),('039002'),('039002'),('039002'),('039003'),('039003'),('039003'),('039003'),('039003'),('039003'),('039004'),('039004'),('039004'),('039004'),('039004'),('039005'),('039005'),('039005'),('039005'),('039005'),('039006'),('039006'),('039006'),('039006'),('046001'),('046001'),('046001'),('046001'),('046001'),('046001'),('046001'),('046001'),('046002'),('046002'),('046002'),('046002'),('046002'),('046002'),('046002'),('046002'),('046003'),('046003'),('046003'),('046003'),('046003'),('046003'),('046003'),('046005'),('046005'),('046005'),('046005'),('046005'),('046005'),('046005'),('046007'),('046007'),('046007'),('046007'),('046007'),('046007'),('046008'),('046008'),('046008'),('046008'),('046008'),('046009'),('046009'),('046009'),('046010'),('046012'),('046012'),('046012'),('046013'),('046014'),('046014'),('046014'),('047001'),('047001'),('047001'),('047001'),('047001'),('047001'),('047001'),('047001'),('047002'),('047002'),('047002'),('047002'),('047002'),('047002'),('047002'),('047002'),('048001'),('048001'),('048001'),('048001'),('048001'),('048001'),('048001'),('048001'),('051003'),('051003'),('051003'),('051003'),('051003'),('051004'),('051004'),('051004'),('051004'),('052001'),('052001'),('052001'),('052001'),('052001'),('052001'),('052001'),('052001'),('052002'),('052002'),('052005'),('052005'),('052005'),('052005'),('052005'),('052005'),('053016'),('053019'),('053019'),('053023'),('053023'),('053023'),('053023'),('053024'),('053024'),('053024'),('053026'),('053026'),('053026'),('053026'),('053028'),('053028'),('053029'),('053029'),('053029'),('053029'),('053033'),('053033'),('053033'),('053045'),('053046'),('053051'),('053051'),('053051'),('053054'),('053054'),('053054'),('053054'),('053057'),('053069'),('053069'),('053097'),('053107'),('053125'),('053125'),('053127'),('054001'),('054001'),('054001'),('054001'),('054001'),('054001'),('054001'),('054002'),('054002'),('054002'),('054002'),('054002'),('054002'),('054003'),('054003'),('054003'),('054003'),('054003'),('054003'),('054003'),('054004'),('054004'),('054004'),('054004'),('054004'),('054004'),('054004'),('054006'),('054006'),('054006'),('054007'),('054007'),('054007'),('054007'),('054007'),('054009'),('054009'),('054009'),('054009'),('054010'),('054010'),('054010'),('054010'),('054010'),('054010'),('054010'),('056001'),('056001'),('056001'),('056001'),('056001'),('056001'),('056001'),('056001'),('056001'),('056002'),('056002'),('056002'),('056002'),('056002'),('056002'),('056002'),('056002'),('056003'),('056003'),('056003'),('056003'),('056003'),('056003'),('056004'),('056004'),('056004'),('056004'),('056004'),('056004'),('056004'),('056005'),('056005'),('056005'),('056005'),('056005'),('056005'),('056005'),('056005'),('056005'),('056006'),('056006'),('056006'),('056006'),('056006'),('056006'),('056006'),('056006'),('056006'),('056009'),('056009'),('056009'),('056011'),('056016'),('056016'),('056016'),('056016'),('056016'),('056016'),('056016'),('056017'),('056017'),('056017'),('056017'),('056017'),('056017'),('056017'),('056017'),('056017'),('056018'),('056018'),('056018'),('056018'),('056018'),('056018'),('056019'),('056019'),('056019'),('056019'),('056019'),('056019'),('056019'),('056019'),('056020'),('056020'),('056020'),('056020'),('056022'),('056022'),('056022'),('056022'),('056022'),('057003'),('057003'),('057004'),('058002'),('058002'),('058002'),('058002'),('058003'),('058003'),('058003'),('058003'),('058004'),('058004'),('058004'),('058005'),('058005'),('058005'),('060001'),('060001'),('060001'),('060001'),('060001'),('060004'),('060004'),('060004'),('060004'),('060004'),('060004'),('060005'),('060005'),('060005'),('060005'),('060005'),('060005'),('060007'),('060007'),('060007'),('060007'),('060007'),('060007'),('060007'),('061004'),('061004'),('061004'),('061004'),('061004'),('061004'),('061006'),('061006'),('061006'),('061006'),('061006'),('061006'),('069006'),('069006'),('069006'),('069006'),('069006'),('069006'),('069006'),('069006'),('069006'),('069007'),('069007'),('069007'),('069007'),('069007'),('069007'),('069007'),('069007'),('069010'),('069010'),('069010'),('069010'),('069010'),('069010'),('069011'),('069012'),('069012'),('069012'),('069012'),('069012'),('069012'),('069012'),('069012'),('069012'),('069012'),('069013'),('069013'),('069013'),('069013'),('069013'),('069013'),('069013'),('069013'),('069013'),('069014'),('069014'),('069014'),('069014'),('069014'),('069014'),('069014'),('069014'),('069014'),('069015'),('069015'),('069015'),('069015'),('069015'),('069015'),('069015'),('069015'),('069015'),('069015'),('069016'),('069016'),('069016'),('069016'),('069016'),('069018'),('069018'),('069018'),('069018'),('069018'),('069018'),('069018'),('069018'),('069018'),('069020'),('069020'),('069020'),('069020'),('069021'),('069023'),('071002'),('071002'),('071002'),('071002'),('071002'),('071003'),('071003'),('071003'),('071003'),('071003'),('071004'),('071004'),('071004'),('071004'),('071004'),('071005'),('071005'),('071005'),('071005'),('071005'),('071005'),('071006'),('071006'),('071006'),('071006'),('071008'),('071008'),('071008'),('071008'),('071008'),('071008'),('071011'),('071011'),('071011'),('071011'),('071011'),('071020'),('071020'),('071020'),('071020'),('071020'),('071021'),('071022'),('071022'),('071022'),('072001'),('072001'),('074001'),('074002'),('074002'),('074002'),('074002'),('074002'),('074002'),('074002'),('074002'),('074003'),('074003'),('074003'),('074003'),('074003'),('074003'),('074003'),('074003'),('074004'),('074004'),('074004'),('074004'),('074004'),('074004'),('074004'),('074004'),('074005'),('074005'),('074005'),('074005'),('074005'),('074005'),('074005'),('074005'),('074006'),('074006'),('074006'),('074006'),('074006'),('074006'),('074006'),('074006'),('074007'),('074007'),('074007'),('074007'),('074007'),('074007'),('074007'),('074007'),('074008'),('074008'),('074008'),('074008'),('074008'),('074008'),('074008'),('074008'),('074009'),('074009'),('074009'),('074009'),('074009'),('074009'),('074009'),('074009'),('074010'),('074010'),('074010'),('074010'),('074010'),('074010'),('074010'),('074010'),('074011'),('074011'),('074011'),('074011'),('074011'),('074011'),('074011'),('074011'),('074012'),('074012'),('074012'),('074012'),('074012'),('074012'),('074012'),('075001'),('075001'),('075001'),('075007'),('075007'),('075007'),('075007'),('076101'),('076101'),('076101'),('076101'),('076102'),('076102'),('076102'),('076103'),('076103'),('076103'),('076103'),('076103'),('077001'),('077001'),('077001'),('077002'),('077002'),('077002'),('077002'),('077002'),('077002'),('077002'),('077003'),('077003'),('077003'),('077003'),('077003'),('077003'),('077003'),('077004'),('077004'),('077004'),('077004'),('077004'),('077004'),('077006'),('077006'),('077008'),('077008'),('077008'),('077008'),('077008'),('077008'),('077008'),('077009'),('077009'),('077009'),('077009'),('077009'),('077009'),('077009'),('078005'),('078005'),('078005'),('079002'),('079002'),('079002'),('079002'),('079002'),('079002'),('079002'),('079003'),('079003'),('079004'),('079004'),('079005'),('079005'),('079005'),('079005'),('079005'),('079005'),('079006'),('079006'),('079006'),('079006'),('079007'),('079007'),('079007'),('079007'),('079007'),('081001'),('081001'),('081001'),('081001'),('081001'),('082011'),('082011'),('082011'),('082011'),('082011'),('082013'),('082013'),('082013'),('082013'),('082013'),('082013'),('082014'),('082014'),('082014'),('082014'),('082014'),('082014'),('082014'),('082015'),('082015'),('082015'),('082015'),('082015'),('082016'),('082016'),('082016'),('082016'),('082016'),('082016'),('082017'),('082017'),('082017'),('082017'),('082017'),('082017'),('082017'),('082021'),('082021'),('082022'),('082022'),('082022'),('082022'),('082022'),('082023'),('082023'),('082023'),('082023'),('082023'),('082024'),('082024'),('082024'),('082024'),('082024'),('082025'),('082025'),('082025'),('082025'),('082025'),('082026'),('082026'),('082026'),('082026'),('082026'),('082027'),('082027'),('082027'),('082027'),('082027'),('082028'),('082028'),('082028'),('082028'),('082029'),('082029'),('082029'),('082029'),('082029'),('082030'),('082030'),('082030'),('082030'),('082031'),('082031'),('082031'),('082031'),('082031'),('082032'),('082032'),('082032'),('082033'),('082033'),('082034'),('082034'),('082034'),('082034'),('082034'),('082034'),('082034'),('082035'),('082035'),('082035'),('082036'),('082036'),('082036'),('082036'),('082037'),('082037'),('082037'),('082038'),('082038'),('082038'),('082038'),('082039'),('082039'),('082039'),('082039'),('082040'),('082040'),('082040'),('082040'),('082040'),('082041'),('082041'),('082041'),('082041'),('082042'),('082042'),('082043'),('082043'),('082043'),('082043'),('082043'),('082044'),('082044'),('082044'),('082044'),('084001'),('084002'),('084002'),('084002'),('084002'),('084003'),('084003'),('084003'),('084003'),('084003'),('084003'),('084003'),('084003'),('084004'),('084004'),('084004'),('084004'),('084004'),('084005'),('084005'),('084005'),('084005'),('084005'),('084007'),('084007'),('084007'),('084007'),('084007'),('084007'),('084008'),('084008'),('084008'),('084008'),('084008'),('084008'),('084009'),('084009'),('084009'),('084009'),('084009'),('084009'),('084011'),('084013'),('084013'),('084013'),('084013'),('084013'),('084014'),('084014'),('084014'),('084016'),('084016'),('084016'),('084016'),('084016'),('084016'),('084016'),('084016'),('084017'),('084017'),('084017'),('084017'),('084017'),('084017'),('084017'),('084017'),('084017'),('084027'),('084027'),('084027'),('084027'),('084027'),('084027'),('084032'),('084032'),('084033'),('084033'),('084033'),('084035'),('084035'),('084035'),('084036'),('084036'),('084036'),('084036'),('084036'),('084036'),('084037'),('084037'),('084038'),('084038'),('084038'),('084038'),('084038'),('084038'),('084039'),('084039'),('084039'),('084039'),('084040'),('084040'),('084040'),('084040'),('084040'),('084041'),('084041'),('084041'),('084041'),('084042'),('084042'),('084043'),('084043'),('084043'),('084043'),('084044'),('084044'),('084044'),('084044'),('084044'),('084045'),('084046'),('084046'),('084046'),('084047'),('084048'),('084048'),('084049'),('084049'),('084050'),('084051'),('084051'),('085001'),('085001'),('085001'),('085001'),('085001'),('085001'),('085002'),('085002'),('085002'),('085002'),('085003'),('085003'),('085003'),('085003'),('085003'),('085003'),('085003'),('085004'),('085004'),('085004'),('085004'),('085004'),('085004'),('085004'),('085005'),('085005'),('085005'),('085005'),('085005'),('085005'),('085006'),('085006'),('085006'),('085006'),('085006'),('085006'),('085006'),('085006'),('085007'),('085007'),('085007'),('085007'),('085007'),('085007'),('085007'),('085009'),('085009'),('085009'),('085009'),('085009'),('085009'),('085011'),('085011'),('085011'),('085011'),('085011'),('085011'),('085011'),('085011'),('085012'),('085012'),('085012'),('085012'),('085012'),('085012'),('085012'),('085014'),('085014'),('085014'),('085014'),('085014'),('085014'),('085014'),('085014'),('085014'),('085015'),('085015'),('085015'),('085015'),('085015'),('085015'),('085015'),('085015'),('085016'),('085016'),('085016'),('085016'),('085016'),('085016'),('085016'),('085016'),('085017'),('085017'),('085017'),('085017'),('085017'),('085018'),('085018'),('085018'),('085018'),('085018'),('085019'),('085019'),('085019'),('085019'),('085019'),('085019'),('085019'),('085019'),('085019'),('085020'),('085020'),('085020'),('085020'),('085020'),('085020'),('085022'),('085022'),('085022'),('085022'),('085022'),('085022'),('085023'),('085023'),('085023'),('085023'),('085023'),('085028'),('085028'),('085028'),('085028'),('085028'),('085028'),('085028'),('085029'),('085029'),('085029'),('085029'),('085029'),('085029'),('085029'),('085030'),('085030'),('085030'),('085030'),('085030'),('085030'),('085030'),('085031'),('085031'),('085031'),('085031'),('085031'),('085031'),('085031'),('085033'),('085034'),('085034'),('085034'),('085034'),('085034'),('085034'),('085034'),('085035'),('085035'),('085035'),('085035'),('085035'),('085035'),('085036'),('085036'),('085036'),('085036'),('085036'),('085036'),('085037'),('085037'),('085037'),('085037'),('085037'),('085037'),('085038'),('085038'),('085038'),('085038'),('085038'),('085038'),('085038'),('085040'),('085040'),('085040'),('085040'),('085040'),('085040'),('085040'),('085040'),('085041'),('085041'),('085041'),('085041'),('085041'),('085041'),('085041'),('085041'),('085042'),('085042'),('085042'),('085042'),('085042'),('085042'),('085042'),('085043'),('085043'),('085043'),('085043'),('085043'),('085043'),('085044'),('085044'),('085044'),('085044'),('085044'),('085044'),('085044'),('085045'),('085045'),('085045'),('085045'),('085045'),('085046'),('085046'),('085046'),('085046'),('085046'),('085046'),('085046'),('085046'),('085047'),('085047'),('085047'),('085047'),('085047'),('085047'),('085047'),('085047'),('085048'),('085048'),('085048'),('085048'),('085048'),('085048'),('085048'),('085063'),('085063'),('085063'),('085063'),('085063'),('085064'),('085064'),('085064'),('085064'),('085064'),('085065'),('085065'),('085068'),('085068'),('085068'),('085068'),('085068'),('085068'),('085071'),('085071'),('085071'),('085071'),('085071'),('085071'),('085073'),('085073'),('085082'),('085082'),('085082'),('085082'),('085082'),('085086'),('085086'),('085086'),('085088'),('085088'),('085088'),('085088'),('085088'),('085088'),('085088'),('085089'),('085089'),('085090'),('085090'),('085090'),('085090'),('085090'),('085090'),('085090'),('085090'),('085091'),('085091'),('085091'),('085091'),('085091'),('085092'),('085092'),('085092'),('085093'),('085093'),('085095'),('085095'),('085095'),('085095'),('085095'),('085096'),('085096'),('085096'),('085096'),('085096'),('085096'),('085097'),('085097'),('085097'),('085097'),('085097'),('085098'),('085098'),('085098'),('085098'),('085098'),('085098'),('085098'),('085099'),('085099'),('085099'),('085099'),('085099'),('085099'),('085099'),('085100'),('085100'),('085100'),('085100'),('085100'),('085100'),('085100'),('085100'),('085100'),('085100'),('085101'),('085101'),('085101'),('085101'),('085101'),('085101'),('085101'),('085101'),('085102'),('085102'),('085103'),('085103'),('085103'),('085104'),('085104'),('085104'),('085104'),('085104'),('085105'),('085105'),('085106'),('085106'),('085106'),('085106'),('085106'),('085106'),('085108'),('085108'),('085109'),('085109'),('085109'),('085109'),('085109'),('085109'),('085109'),('085109'),('085110'),('085110'),('085110'),('085110'),('085110'),('085111'),('085111'),('085111'),('085112'),('085112'),('085112'),('085112'),('085113'),('085113'),('085113'),('085113'),('085113'),('085115'),('085120'),('085121'),('085121'),('085121'),('085121'),('085122'),('085122'),('085122'),('085122'),('085122'),('085122'),('085122'),('085122'),('085123'),('085123'),('085123'),('085123'),('085123'),('085123'),('085123'),('085123'),('085125'),('085125'),('085125'),('085125'),('085125'),('085126'),('085126'),('085126'),('085126'),('085126'),('085127'),('085127'),('085127'),('085127'),('085127'),('085127'),('085127'),('085127'),('085128'),('085128'),('085128'),('085128'),('085128'),('085129'),('085129'),('085129'),('085129'),('085129'),('085130'),('085130'),('085130'),('085130'),('085130'),('085132'),('085132'),('085132'),('085132'),('085132'),('085132'),('085133'),('085133'),('085133'),('085133'),('085133'),('085134'),('085134'),('085134'),('085135'),('085135'),('085135'),('085136'),('085136'),('085136'),('085136'),('085137'),('085137'),('085137'),('085137'),('085137'),('085137'),('085137'),('086002'),('086002'),('086002'),('086002'),('086003'),('086003'),('086003'),('086003'),('086005'),('088001'),('088001'),('088001'),('088001'),('088001'),('088003'),('088003'),('088003'),('088003'),('088003'),('088003'),('088005'),('088005'),('088005'),('088005'),('088005'),('088006'),('088006'),('088006'),('088006'),('088006'),('088007'),('088007'),('088007'),('088008'),('088008'),('088008'),('088008'),('088009'),('088009'),('088009'),('088009'),('088009'),('089001'),('089001'),('089001'),('089001'),('089001'),('089001'),('089001'),('090001'),('090001'),('090001'),('090001'),('090001'),('090001'),('090001'),('090002'),('090002'),('090002'),('090002'),('090002'),('090002'),('090003'),('090003'),('090003'),('090003'),('090003'),('090003'),('090003'),('090004'),('090004'),('090004'),('090004'),('090004'),('090004'),('090004'),('090006'),('090006'),('090006'),('090006'),('090006'),('090006'),('090006'),('090008'),('090008'),('090008'),('090008'),('090008'),('090009'),('090009'),('090009'),('090009'),('090009'),('090010'),('090010'),('090013'),('090013'),('090013'),('090016'),('090016'),('090017'),('090018'),('090022'),('090027'),('091001'),('091001'),('091001'),('091001'),('091001'),('091001'),('091002'),('091002'),('091002'),('091002'),('091002'),('091002'),('091009'),('091009'),('091009'),('091009'),('091009'),('091011'),('091011'),('091011'),('091011'),('091011'),('091011'),('091011'),('091012'),('091012'),('091013'),('091013'),('091013'),('091013'),('091013'),('091013'),('091015'),('091015'),('091015'),('091015'),('091015'),('091015'),('091016'),('091016'),('091016'),('091016'),('091016'),('091017'),('091017'),('091018'),('091018'),('091018'),('091018'),('093003'),('093003'),('093003'),('093003'),('093003'),('093003'),('099001'),('099001'),('099001'),('099001'),('099001'),('099001'),('099001'),('100001'),('100001'),('100001'),('100001'),('106001'),('113005'),('113005'),('113005'),('113006'),('113006'),('113018'),('113019'),('113020'),('115001'),('115001'),('115001'),('115002'),('115002'),('115003'),('115004'),('115004'),('115004'),('115004'),('115005'),('115005'),('115005'),('115006'),('115006'),('115006'),('115007'),('115007'),('115007'),('115007'),('115007'),('115008'),('115008'),('115008'),('115009'),('115010'),('115010'),('115010'),('115010'),('115010'),('115011'),('115011'),('115011'),('115011'),('115012'),('115012'),('115013'),('115013'),('115013'),('115014'),('115014'),('115014'),('115014'),('115015'),('115015'),('115015'),('115016'),('115016'),('115016'),('115016'),('115017'),('115017'),('115017'),('115017'),('115017'),('115018'),('115018'),('115020'),('115020'),('115021'),('115021'),('115022'),('115022'),('115022'),('115023'),('115023'),('115023'),('115023'),('115023'),('115025'),('115025'),('115025'),('115026'),('115026'),('115027'),('115027'),('115027'),('115028'),('115028'),('115028'),('115028'),('115029'),('115029'),('115029'),('115030'),('115030'),('115030'),('115031'),('115031'),('115032'),('115032'),('115032'),('115033'),('115033'),('115033'),('115033'),('115034'),('115034'),('115034'),('115035'),('115035'),('115036'),('115036'),('115036'),('115036'),('115036'),('115039'),('115040'),('115040'),('115040'),('115041'),('115041'),('115041'),('115041'),('115041'),('115042'),('115042'),('115042'),('115042'),('115042'),('115043'),('115043'),('115043'),('115044'),('115044'),('115044'),('115044'),('115046'),('115046'),('115046'),('115047'),('115048'),('115050'),('115050'),('115050'),('115050'),('115050'),('115051'),('115051'),('115051'),('115052'),('115053'),('115053'),('115054'),('115054'),('115054'),('115055'),('115055'),('115055'),('115057'),('115059'),('115059'),('115059'),('115059'),('115060'),('115060'),('115060'),('115060'),('115060'),('115060'),('115061'),('115061'),('115061'),('115062'),('115062'),('115062'),('115062'),('115064'),('115064'),('115064'),('115065'),('115065'),('115065'),('115065'),('115066'),('115066'),('115066'),('115067'),('115067'),('115067'),('115068'),('115068'),('115068'),('115069'),('115069'),('115069'),('115069'),('115069'),('115070'),('115070'),('115070'),('115071'),('115071'),('115071'),('115072'),('115072'),('115072'),('115073'),('115073'),('115075'),('115075'),('115075'),('115076'),('115076'),('115076'),('115076'),('115076'),('115076'),('115081'),('115081'),('115081'),('115082'),('115082'),('115082'),('115085'),('115085'),('115085'),('115085'),('115085'),('115086'),('115086'),('115086'),('115087'),('115087'),('115088'),('115088'),('115088'),('115088'),('115088'),('115095'),('115095'),('115095'),('115096'),('115096'),('115097'),('115097'),('115098'),('115098'),('115099'),('115101'),('115102'),('115102'),('115102'),('115103'),('115103'),('115104'),('115104'),('115104'),('115104'),('115105'),('115105'),('115106'),('115106'),('115106'),('115106'),('115106'),('115108'),('115109'),('115111'),('115111'),('115111'),('115111'),('115112'),('115112'),('115112'),('115112'),('115112'),('115113'),('115113'),('115113'),('115114'),('115114'),('115114'),('115114'),('115114'),('115115'),('115115'),('115115'),('115115'),('115116'),('115117'),('115117'),('115117'),('115118'),('115118'),('115119'),('115119'),('115119'),('115119'),('115120'),('115121'),('115121'),('115122'),('115122'),('116001'),('116003'),('116003'),('116003'),('116003'),('116004'),('116004'),('116005'),('116005'),('116006'),('116006'),('116006'),('116007'),('116007'),('116008'),('116008'),('116009'),('116009'),('116009'),('116010'),('116010'),('116010'),('116010'),('116011'),('116011'),('116011'),('116011'),('116012'),('116012'),('123001'),('123001'),('123001'),('123001'),('123001'),('124065'),('126001'),('126001'),('126001'),('126001'),('126001'),('126001'),('126001'),('126001'),('126002'),('126002'),('126002'),('126002'),('126002'),('126002'),('126002'),('126002'),('126003'),('126003'),('126003'),('126003'),('126003'),('126003'),('126003'),('126003'),('126003'),('126004'),('126004'),('126004'),('126004'),('126004'),('126004'),('126004'),('126004'),('126004'),('126004'),('126005'),('126005'),('126005'),('126005'),('126005'),('126005'),('126005'),('126005'),('126005'),('126006'),('126006'),('126006'),('126006'),('126006'),('126006'),('126006'),('126006'),('126006'),('126007'),('126007'),('126007'),('126007'),('126007'),('126007'),('126007'),('126008'),('126008'),('126008'),('126008'),('126008'),('126008'),('126008'),('126008'),('126009'),('126009'),('126009'),('126009'),('126009'),('126009'),('126009'),('126009'),('126010'),('126010'),('126010'),('126010'),('126010'),('126010'),('126010'),('126010'),('126010'),('126011'),('126011'),('126011'),('126011'),('126011'),('126011'),('126011'),('126012'),('126012'),('126012'),('126012'),('130001'),('130001'),('130001'),('130001'),('132001'),('132001'),('132001'),('132001'),('132001'),('132002'),('132002'),('132002'),('132002'),('132002'),('132002'),('132002'),('133001'),('133001'),('133008'),('133009'),('133010'),('133011'),('133011'),('133011'),('133011'),('133011'),('133011'),('133012'),('133015'),('133015'),('133015'),('133015'),('133016'),('133018'),('133018'),('133018'),('133018'),('133018'),('133019'),('133021'),('133021'),('133022'),('133022'),('133023'),('133023'),('133024'),('133024'),('133024'),('133024'),('133024'),('133024'),('133025'),('133027'),('133027'),('133027'),('133027'),('133027'),('133028'),('133028'),('133028'),('133029'),('133029'),('133029'),('133029'),('133029'),('133029'),('133030'),('133030'),('133031'),('133031'),('133031'),('134001'),('134001'),('134001'),('135001'),('135001'),('135001'),('135001'),('135001'),('135002'),('135002'),('135002'),('135004'),('135010'),('135010'),('135010'),('135010'),('135010'),('135010'),('137010'),('137011'),('137012'),('137014'),('137015'),('137015'),('137016'),('137019'),('139001'),('140001'),('140001'),('140001'),('140001'),('140001'),('140001'),('141001'),('141001'),('141001'),('141001'),('141001'),('141002'),('141002'),('141002'),('141002'),('141002'),('141003'),('141003'),('141003'),('141003'),('141003'),('141003'),('141003'),('141003'),('141006'),('141006'),('141006'),('141006'),('141006'),('141006'),('141006'),('141006'),('141007'),('141007'),('141007'),('141007'),('141007'),('141009'),('141009'),('141009'),('141009'),('141009'),('141011'),('141011'),('141011'),('141011'),('141011'),('141011'),('141012'),('141014'),('141014'),('141014'),('141014'),('141014'),('141014'),('141014'),('141014'),('141015'),('141015'),('141015'),('141015'),('141015'),('141016'),('141016'),('141016'),('141016'),('141016'),('141016'),('141017'),('141017'),('141017'),('141017'),('141017'),('141017'),('141018'),('141018'),('141018'),('141018'),('141019'),('141019'),('141019'),('141019'),('141020'),('141020'),('141020'),('141020'),('141020'),('141020'),('141020'),('141021'),('141021'),('141021'),('141021'),('141021'),('141021'),('141022'),('141022'),('141022'),('141022'),('141022'),('141022'),('141023'),('141023'),('141023'),('141023'),('141023'),('141023'),('141023'),('141024'),('141025'),('141025'),('141025'),('141026'),('141026'),('141026'),('141026'),('141026'),('141026'),('141027'),('141027'),('141027'),('141027'),('141027'),('141028'),('141028'),('145001'),('145001'),('145001'),('145001'),('145001'),('145001'),('145001'),('145001'),('145001'),('145002'),('145002'),('145002'),('145002'),('145002'),('145002'),('145002'),('145002'),('145002'),('145003'),('145003'),('145003'),('145003'),('145003'),('145003'),('145003'),('145003'),('145003'),('145003'),('145004'),('145004'),('145004'),('145004'),('145004'),('145004'),('145004'),('145004'),('145004'),('145005'),('145005'),('145005'),('145005'),('145005'),('145005'),('145005'),('145005'),('145005'),('145006'),('145006'),('145006'),('145006'),('145006'),('145006'),('145006'),('145006'),('145006'),('145008'),('145008'),('145008'),('145008'),('145008'),('145008'),('145008'),('145008'),('145009'),('145009'),('145009'),('145009'),('145009'),('145009'),('145009'),('145011'),('145011'),('145011'),('145011'),('145011'),('145011'),('145011'),('145011'),('145012'),('145012'),('145012'),('145012'),('145012'),('145012'),('145012'),('145012'),('145013'),('145013'),('145013'),('145013'),('145013'),('145013'),('145013'),('150009'),('150013'),('150014'),('150015'),('150015'),('150015'),('150016'),('150016'),('150017'),('150017'),('150017'),('150017'),('150020'),('152001'),('152001'),('152001'),('152002'),('152003'),('152003'),('152003'),('152003'),('152004'),('152005'),('152006'),('152006'),('152006'),('152006'),('152007'),('154001'),('154002'),('154002'),('155001'),('155001'),('155002'),('155003'),('155004'),('155004'),('155006'),('159001'),('159003'),('160001'),('160001'),('160001'),('160001'),('160002'),('160002'),('161001'),('162002'),('162002'),('162003'),('162003'),('162003'),('162003'),('162003'),('162007'),('162012'),('162012'),('162012'),('163001'),('163001'),('163001'),('163011'),('163015'),('163016'),('163016'),('165001'),('165001'),('165001'),('165001'),('165002'),('165002'),('165002'),('165002'),('165003'),('165003'),('165003'),('165004'),('165004'),('165004'),('165005'),('165005'),('165005'),('165006'),('165006'),('165006'),('165006'),('165007'),('165007'),('165007'),('165007'),('165008'),('165008'),('165008'),('165008'),('165009'),('165009'),('165009'),('165009'),('165010'),('165010'),('165010'),('165011'),('165011'),('165012'),('165012'),('165012'),('165013'),('165013'),('165013'),('165014'),('165014'),('165014'),('165015'),('165015'),('165015'),('165015'),('165016'),('165016'),('165016'),('165017'),('165017'),('165017'),('165017'),('165018'),('165018'),('165018'),('165018'),('165019'),('165019'),('165019'),('165019'),('165020'),('165020'),('165020'),('165020'),('165021'),('165021'),('165021'),('165021'),('165022'),('165022'),('165022'),('165023'),('165024'),('165024'),('165024'),('165025'),('165025'),('165025'),('165026'),('165026'),('165026'),('165028'),('165029'),('165030'),('165030'),('165030'),('165031'),('165031'),('165033'),('165033'),('165034'),('165034'),('165034'),('165035'),('165035'),('165035'),('165036'),('165036'),('165036'),('168003'),('168003'),('168004'),('168005'),('168014'),('169001'),('169001'),('169001'),('169001'),('169001'),('169001'),('169001'),('169001'),('169001'),('169001'),('169002'),('169002'),('169002'),('169002'),('169002'),('169002'),('169002'),('169002'),('169002'),('169002'),('169003'),('169003'),('169003'),('169003'),('169007'),('169007'),('169007'),('169007'),('169007'),('169007'),('169007'),('169007'),('169007'),('169007'),('169008'),('169008'),('169008'),('169008'),('169008'),('169008'),('169008'),('169009'),('169009'),('169009'),('169009'),('169010'),('171006'),('171006'),('171007'),('171007'),('171008'),('171008'),('171008'),('171009'),('171009'),('171009'),('172001'),('176001'),('176001'),('176001'),('176001'),('176001'),('176001'),('176001'),('176002'),('176002'),('176002'),('176002'),('176002'),('176003'),('176003'),('176003'),('176003'),('176003'),('176003'),('177001'),('177001'),('177001'),('177001'),('177001'),('177001'),('179007'),('179007'),('179012'),('179012'),('179012'),('179012'),('179012'),('179012'),('179013'),('179013'),('179013'),('179013'),('179013'),('179013'),('179042'),('179044'),('179045'),('180001'),('180013'),('180014'),('180014'),('180015'),('180017'),('180018'),('180020'),('180020'),('180021'),('180021'),('180027'),('180030'),('180033'),('180035'),('180036'),('180037'),('180038'),('180041'),('180042'),('180045'),('180045'),('180047'),('180048'),('180049'),('180050'),('180054'),('180060'),('180066'),('180067'),('180068'),('180070'),('182001'),('184001'),('184002'),('184005'),('184005'),('184005'),('184005'),('184006'),('184006'),('184006'),('184006'),('184008'),('184008'),('184008'),('184008'),('184009'),('184009'),('184009'),('184009'),('184010'),('184010'),('184010'),('184010'),('184011'),('184011'),('184011'),('184011'),('185001'),('185001'),('185001'),('185001'),('185001'),('185001'),('185001'),('185003'),('185003'),('185003'),('185003'),('185003'),('185003'),('185003'),('187001'),('191002'),('191002'),('192002'),('194003'),('197001'),('197001'),('197001'),('197001'),('197001'),('197001'),('197001'),('197002'),('197002'),('197002'),('197002'),('197002'),('197002'),('197002'),('197003'),('197003'),('197003'),('197003'),('197003'),('197003'),('197003'),('197004'),('197004'),('197004'),('197004'),('197004'),('197004'),('197004'),('197005'),('197005'),('197005'),('197005'),('197005'),('197005'),('197006'),('197006'),('197006'),('197006'),('197006'),('198001'),('198001'),('198001'),('198001'),('198001'),('198001'),('198003'),('198003'),('198003'),('198004'),('198004'),('198004'),('198004'),('198004'),('198004'),('198005'),('198005'),('198005'),('198005'),('198005'),('198005'),('198005'),('198006'),('198006'),('198006'),('198006'),('198006'),('198006'),('198007'),('198007'),('198007'),('198007'),('198007'),('198007'),('198007'),('198008'),('198008'),('198008'),('198008'),('198008'),('198008'),('198009'),('198009'),('198009'),('198009'),('198009'),('198009'),('198009'),('198010'),('198010'),('198010'),('198010'),('198010'),('198010'),('198011'),('198012'),('198012'),('198012'),('198012'),('198015'),('198015'),('198016'),('198016'),('198016'),('198016'),('198016'),('198016'),('198017'),('198017'),('198017'),('198017'),('198017'),('198017'),('201001'),('201001'),('201001'),('201001'),('201001'),('201002'),('202001'),('202001'),('203001'),('203001'),('203001'),('203001'),('203001'),('203001'),('203001'),('203002'),('203002'),('203002'),('203002'),('203003'),('203003'),('203003'),('203003'),('203003'),('203017'),('203017'),('203017'),('203017'),('203017'),('203017'),('203017'),('203017'),('203017'),('203018'),('203018'),('203018'),('203018'),('203018'),('203019'),('203019'),('203019'),('203019'),('203019'),('204001'),('204002'),('205001'),('205001'),('205001'),('205001'),('205001'),('205001'),('205001'),('208001'),('208001'),('208002'),('208002'),('208002'),('208003'),('208003'),('208003'),('208004'),('208004'),('208004'),('208004'),('208004'),('208004'),('208004'),('208005'),('208005'),('208005'),('208005'),('208005'),('209001'),('209001'),('209001'),('209001'),('209001'),('209002'),('209002'),('209002'),('209002'),('209002'),('209003'),('209003'),('209003'),('209003'),('209003'),('210001'),('210001'),('210001'),('210001'),('210001'),('210004'),('210004'),('210004'),('210004'),('210004'),('210004'),('210009'),('210010'),('212001'),('212001'),('212002'),('212002'),('212002'),('212002'),('212003'),('212003'),('212003'),('212004'),('212004'),('212004'),('212005'),('212005'),('212005'),('212005'),('212005'),('212006'),('212006'),('212006'),('212007'),('212007'),('212008'),('212008'),('212008'),('212008'),('212009'),('212009'),('212009'),('212009'),('212010'),('212010'),('212010'),('212010'),('212011'),('212011'),('212012'),('212012'),('212013'),('212013'),('212013'),('218001'),('218004'),('218009'),('218011'),('218011'),('218015'),('218020'),('218021'),('218021'),('218022'),('218022'),('218022'),('218023'),('218024'),('218025'),('218026'),('218026'),('218027'),('218028'),('218029'),('218029'),('218029'),('218030'),('218031'),('221001'),('221001'),('221001'),('221001'),('221001'),('221001'),('221002'),('221002'),('221002'),('221002'),('221002'),('221002'),('221003'),('221003'),('221003'),('221003'),('221003'),('221003'),('221004'),('221004'),('221004'),('221004'),('221004'),('221004'),('221005'),('221005'),('221005'),('221005'),('221005'),('221006'),('221006'),('221006'),('221006'),('221006'),('221007'),('221007'),('221007'),('221007'),('221007'),('221007'),('221008'),('221008'),('221008'),('221008'),('221008'),('221008'),('221009'),('221009'),('221009'),('221009'),('221009'),('221009'),('221010'),('221010'),('221010'),('221010'),('221011'),('221011'),('221011'),('221011'),('221012'),('221012'),('221012'),('221012'),('221012'),('221012'),('221013'),('221013'),('221013'),('221013'),('221013'),('221013'),('223003'),('223003'),('224001'),('224001'),('224002'),('224002'),('224003'),('224007'),('224008'),('225001'),('225002'),('225002'),('225002'),('225003'),('225003'),('225003'),('225003'),('225004'),('225004'),('225004'),('225005'),('225005'),('225005'),('225005'),('225005'),('225005'),('225006'),('225006'),('225006'),('225007'),('225007'),('225007'),('225008'),('225008'),('225008'),('225008'),('225008'),('225009'),('225009'),('225009'),('225010'),('225010'),('225010'),('225011'),('225011'),('225011'),('225011'),('225011'),('225012'),('225012'),('225012'),('225012'),('225012'),('225012'),('225013'),('225013'),('226001'),('226002'),('226003'),('226003'),('226005'),('226005'),('226006'),('226007'),('226007'),('226007'),('226007'),('227011'),('227015'),('227015'),('227041'),('227045'),('227052'),('227056'),('227063'),('227064'),('227066'),('227067'),('227069'),('227071'),('227073'),('227085'),('227116'),('227119'),('227131'),('227133'),('227147'),('229005'),('229005'),('229005'),('233003'),('233004'),('235001'),('235001'),('235002'),('235003'),('235003'),('235003'),('235004'),('235005'),('235005'),('235005'),('235005'),('235005'),('235005'),('235005'),('236001'),('236001'),('236001'),('236001'),('236002'),('236003'),('236003'),('236003'),('236003'),('236003'),('236003'),('238002'),('238002'),('238002'),('238002'),('238002'),('238002'),('238003'),('238003'),('238003'),('238003'),('238003'),('238003'),('238004'),('238004'),('238004'),('238004'),('238004'),('238005'),('238005'),('238005'),('238007'),('238007'),('238007'),('238007'),('238007'),('238007'),('238007'),('238008'),('238008'),('238008'),('238008'),('238008'),('238008'),('238008'),('334005'),('334006'),('337001'),('337001'),('337001'),('337002'),('337002'),('337003'),('337003'),('337003'),('337004'),('343001'),('343001'),('344001'),('344002'),('344003'),('344004'),('344005'),('344005'),('345001'),('345001'),('348001'),('348004'),('348005'),('348005'),('349001'),('349001'),('349002'),('349002'),('349002'),('350001'),('353002'),('353002'),('353002'),('353003'),('355001'),('355002'),('355005'),('355006'),('355006'),('356001'),('358001'),('358001'),('358001'),('359001'),('359001'),('359002'),('359002'),('359002'),('359002'),('360001'),('360001'),('360002'),('360002'),('360003'),('360003'),('360004'),('360004'),('360005'),('360005'),('360005'),('366001'),('366002'),('366002'),('366003'),('366004'),('369001'),('369001'),('373001'),('373002'),('373002'),('373003'),('373003'),('373005'),('373007'),('373008'),('373009'),('373009'),('373010'),('373010'),('373010'),('373011'),('373011'),('373011'),('373011'),('373012'),('373012'),('373012'),('373013'),('373013'),('373014'),('373014'),('373015'),('373015'),('373015'),('373015'),('373017'),('373017'),('373017'),('373017'),('373018'),('373021'),('374002'),('374004'),('374006'),('374007'),('374008'),('374009'),('374010'),('374011'),('374012'),('374015'),('374016'),('382001'),('382002'),('382002'),('384001'),('386001'),('386001'),('386001'),('386001'),('386001'),('386001'),('386001'),('386002'),('386002'),('386002'),('386002'),('386002'),('386002'),('386002'),('386003'),('386003'),('386003'),('386003'),('386003'),('386003'),('386003'),('386003'),('386003'),('386004'),('386004'),('386004'),('386004'),('386004'),('386004'),('386004'),('386004'),('386005'),('386005'),('386005'),('386005'),('386005'),('386005'),('386005'),('386006'),('386006'),('386006'),('386006'),('386006'),('386006'),('386007'),('386007'),('386007'),('386007'),('386007'),('386007'),('386007'),('386007'),('386007'),('386008'),('386008'),('386008'),('386008'),('386008'),('386008'),('386008'),('386008'),('386009'),('386009'),('386009'),('386010'),('386010'),('386010'),('386010'),('386010'),('386010'),('386010'),('386010'),('386011'),('386011'),('386011'),('386011'),('386011'),('386011'),('386011'),('386011'),('386011'),('386012'),('386012'),('386012'),('386012'),('386012'),('386012'),('386012'),('386012'),('386012'),('386013'),('386013'),('386013'),('386013'),('386013'),('386013'),('386013'),('386014'),('386014'),('386014'),('386014'),('389001'),('389002'),('389002'),('389003'),('389003'),('389003'),('389003'),('389004'),('389004'),('389004'),('389004'),('392001'),('393001'),('393002'),('393002'),('393003'),('393004'),('395001'),('395001'),('397001'),('397001'),('397001'),('397002'),('399001'),('399001'),('399001'),('399001'),('399001'),('399001'),('399001'),('399002'),('399002'),('399002'),('399002'),('399002'),('399002'),('399002'),('399003'),('400001'),('400001'),('400001'),('400001'),('400002'),('403002'),('504001'),('504001'),('504002'),('504002'),('504002'),('504004'),('504004'),('504005'),('504006'),('504007'),('504007'),('504007'),('504008'),('504008'),('504009'),('504009'),('504009'),('504009'),('504009'),('504010'),('504011'),('504011'),('504012'),('504012'),('504014'),('504014'),('504014'),('504014'),('504014'),('504014'),('504014'),('504014'),('504017'),('504017'),('504021'),('504021'),('504021'),('504021'),('504021'),('504021'),('504021'),('504022'),('504023'),('504023'),('504024'),('504024'),('504025'),('504025'),('506001'),('506001'),('506001'),('506001'),('506001'),('506001'),('506002'),('506002'),('506002'),('506002'),('506002'),('511001'),('511001'),('511001'),('511001'),('511001'),('511001'),('511001'),('511002'),('511002'),('511002'),('511002'),('511002'),('511002'),('511002'),('511003'),('511003'),('511003'),('511003'),('511003'),('511003'),('511004'),('511004'),('511004'),('511004'),('511004'),('511004'),('511004'),('511005'),('511005'),('511005'),('511005'),('511005'),('511005'),('511005'),('511006'),('511006'),('511006'),('511006'),('511006'),('511006'),('511006'),('511007'),('511007'),('511007'),('511007'),('511007'),('511008'),('511008'),('511008'),('511008'),('511008'),('511008'),('511009'),('511009'),('511009'),('511009'),('511009'),('511009'),('511010'),('511010'),('511010'),('511010'),('511010'),('511010'),('511011'),('511011'),('511011'),('511011'),('511011'),('511011'),('511012'),('511012'),('511012'),('511012'),('511012'),('511012'),('511012'),('511013'),('511013'),('511013'),('511013'),('511013'),('511013'),('511013'),('511014'),('511014'),('511014'),('511014'),('511014'),('511017'),('511018'),('511020'),('511021'),('511022'),('511024'),('511028'),('511029'),('511029'),('511029'),('511029'),('511029'),('511029'),('513001'),('513001'),('513001'),('513001'),('513001'),('513001'),('513001'),('513001'),('513002'),('513002'),('513002'),('513002'),('513002'),('513002'),('513003'),('513003'),('513003'),('513003'),('513003'),('513003'),('513003'),('513003'),('513004'),('513004'),('513004'),('515001'),('515001'),('515001'),('515001'),('515001'),('515002'),('515002'),('515003'),('515003'),('515007'),('515007'),('515008'),('515011'),('515011'),('515011'),('515011'),('515011'),('515011'),('515012'),('515012'),('515012'),('515012'),('515013'),('515013'),('515013'),('515013'),('515013'),('515014'),('515014'),('515014'),('515014'),('515014'),('515015'),('515015'),('515015'),('515015'),('515015'),('518001'),('518002'),('521001'),('521002'),('521002'),('521002'),('521003'),('521003'),('521003'),('521003'),('521004'),('521004'),('521004'),('521004'),('521005'),('521005'),('521005'),('521005'),('521006'),('521006'),('521006'),('521009'),('521010'),('521010'),('521010'),('521010'),('521011'),('521011'),('521011'),('521011'),('521012'),('521013'),('521013'),('521015'),('521016'),('521016'),('523001'),('523001'),('523001'),('523001'),('523001'),('523001'),('523001'),('523002'),('523002'),('523002'),('523002'),('523002'),('523002'),('523003'),('523003'),('523003'),('523003'),('523003'),('523003'),('523003'),('523004'),('523004'),('523004'),('523004'),('523004'),('523004'),('523005'),('523005'),('523005'),('523005'),('523005'),('523005'),('523005'),('523005'),('523006'),('523006'),('523006'),('523006'),('523006'),('523006'),('523006'),('523007'),('523007'),('523007'),('523007'),('523007'),('523007'),('523007'),('524001'),('700001'),('701001'),('701002'),('701003'),('702001'),('702002'),('702004'),('702005'),('704001'),('704004'),('705001'),('706001'),('706002'),('707001'),('707002'),('707003'),('708001'),('710001'),('710002'),('711001'),('711002'),('712001'),('714001'),('714002'),('715001'),('719001'),('719002'),('991002'),('991002'),('991002'),('991003'),('991003'),('991003'),('991003'),('991003'),('991003'),('991003'),('991004'),('991004'),('991004'),('991005'),('991005'),('991005'),('991006'),('991007'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('995001'),('996001'),('996001'),('996001'),('996001'),('996001'),('996001'),('996001'),('996001'),('996002'),('996002'),('996003'),('996003'),('996003'),('996003'),('996003'),('998001'),('998001'),('998001'),('998001'),('998001'),('998001'),('998001'),('998001'),('998001'),('998001'),('998002'),('998002'),('998002'),('998002'),('998002'),('998002'),('998002'),('998002'),('998002'),('998002'),('998003'),('998003'),('998003'),('998003'),('998003'),('998003'),('998003'),('998003'),('998004'),('998004'),('998005'),('998005'),('998006'),('998007'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999001'),('999002'),('999002'),('011017'),('011017'),('011017'),('011017'),('011017'),('011017'),('011017'),('011018'),('011018'),('011018'),('011018'),('034001'),('034001'),('034002'),('034002'),('071010'),('071010'),('071010'),('519001'),('126013'),('126013'),('126013'),('126013'),('126013'),('184012'),('184012'),('184012'),('404001'),('405002'),('405002'),('405001'),('405003'),('405006'),('240011'),('240011'),('240011'),('240011'),('240011'),('240011'),('240010'),('240010'),('240010'),('240009'),('240009'),('240009'),('240009'),('240008'),('240008'),('240008'),('240007'),('240007'),('240007'),('240007'),('240007'),('240007'),('240005'),('240005'),('240005'),('240005'),('240005'),('240004'),('240004'),('240004'),('240004'),('240004'),('240003'),('240003'),('240003'),('240003'),('240002'),('240002'),('240002'),('240002'),('240002'),('240002'),('240002'),('240001'),('240001'),('240001'),('240001'),('240001'),('240012'),('240012'),('240012'),('240012'),('240012'),('240013'),('240014'),('240015'),('240015'),('240015'),('240015'),('240015'),('240015'),('240015'),('240015'),('240016'),('240016'),('240016'),('240016'),('240016'),('240016'),('240017'),('240017'),('240017'),('357001'),('357001'),('235006'),('235006'),('235007'),('235007'),('235007'),('235007'),('235007'),('056023'),('056023'),('056023'),('056023'),('056023'),('046015'),('019005'),('019005'),('126014'),('126014'),('126014'),('126014'),('126014'),('126014'),('241003'),('241003'),('241003'),('241003'),('241003'),('241003'),('241002'),('241002'),('241002'),('241002'),('241002'),('241002'),('241001'),('241001'),('241001'),('241001'),('241001'),('240020'),('240020'),('240020'),('240020'),('240020'),('240020'),('240019'),('240019'),('240019'),('242001'),('242002'),('242004'),('242005'),('242006'),('089002'),('089002'),('089002'),('089002'),('089002'),('089002'),('406001'),('406002'),('406003'),('406004'),('406004'),('243001'),('243005'),('243006'),('243007'),('243008'),('408001'),('408001'),('408001'),('408001'),('408001'),('366005'),('366005'),('016035'),('016035'),('016035'),('016035'),('077010'),('996004'),('996004'),('996004'),('996004'),('996004'),('996004'),('996004'),('996004'),('025064'),('025064'),('025064'),('025064'),('011019'),('011019'),('011019'),('011019'),('011019'),('115123'),('115123'),('504026'),('039007'),('039009'),('039008'),('039008'),('039010'),('039010'),('039011'),('039012'),('180072'),('240021'),('240021'),('240021'),('240021'),('240021'),('240021'),('240021'),('240023'),('240023'),('240023'),('240023'),('405008'),('405008'),('525002'),('410002'),('410002'),('410004'),('410005'),('410005'),('410006'),('410007'),('410007'),('410008'),('410009'),('410010'),('410011'),('410011'),('410012'),('410012'),('410013'),('410013'),('410014'),('410014'),('410016'),('410016'),('344006'),('240031'),('240031'),('240031'),('240031'),('240030'),('240030'),('240030'),('240030'),('240029'),('240029'),('240029'),('240029'),('240028'),('240028'),('240028'),('240028'),('240027'),('240027'),('240026'),('240026'),('240026'),('240025'),('240025'),('240025'),('240025'),('240024'),('240024'),('240034'),('240034'),('240034'),('240033'),('240033'),('240033'),('240032'),('240032'),('240032'),('240032'),('411001'),('411002'),('203020'),('069025'),('069025'),('069025'),('069025'),('069025'),('069025'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244001'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244002'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244009'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244008'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244007'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244006'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244004'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244003'),('244014'),('244014'),('244014'),('244014'),('244014'),('244014'),('244014'),('244014'),('244013'),('244013'),('244013'),('244013'),('244013'),('244013'),('244013'),('244013'),('244012'),('244012'),('244012'),('244012'),('244012'),('244012'),('244012'),('244012'),('244011'),('244011'),('244011'),('244011'),('244011'),('244011'),('244011'),('244011'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244016'),('244017'),('244017'),('244017'),('244017'),('244017'),('244017'),('244017'),('244017'),('244017'),('240040'),('240037'),('405009'),('405009'),('405009'),('405010'),('405010'),('240043'),('240043'),('504028'),('504040'),('800001'),('410019'),('410019'),('410020'),('410020'),('410020'),('410021'),('410021'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244018'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244019'),('244020'),('244020'),('244020'),('244020'),('244020'),('244020'),('244020'),('244020'),('413001'),('344007'),('082045'),('082045'),('082045'),('082045'),('082045'),('010031'),('010031'),('010031'),('010031'),('010032'),('010032'),('010032'),('010032'),('010033'),('010033'),('010033'),('010033'),('010033'),('010034'),('010034'),('010034'),('010034'),('010035'),('010035'),('010035'),('010035'),('504044'),('515016'),('515016'),('515016'),('515016'),('801002'),('801003'),('801004'),('801005'),('802001'),('801001'),('414001'),('141029'),('803001'),('803002'),('803004'),('803005'),('803006'),('803007'),('803008'),('803009'),('803013'),('803014'),('803015'),('803016'),('803017'),('410022'),('410023'),('410023'),('803019'),('415002'),('415001'),('244021'),('244021'),('244021'),('244021'),('244021'),('244021'),('244021'),('011020'),('011020'),('011020'),('011020'),('011023'),('011023'),('011023'),('011023'),('011022'),('011022'),('011022'),('011022'),('011022'),('011022'),('011021'),('011021'),('011021'),('011021'),('025065'),('025065'),('025065'),('025065'),('165037'),('165037'),('165038'),('165038'),('165038'),('165039'),('416001'),('416001'),('416001'),('416001'),('416001'),('416002'),('416003'),('417001'),('418001'),('504045'),('504045'),('504045'),('803022'),('240022'),('240022'),('240022'),('240022'),('420001'),('420001'),('420001'),('420001'),('804010'),('804005'),('804002'),('804018'),('804013'),('511019'),('511016'),('511015'),('511032'),('511031'),('511030'),('511027'),('511026'),('511025'),('511033'),('511023'),('133034'),('133034'),('133034'),('133033'),('169011'),('169011'),('169011'),('169011'),('169011'),('344008'),('244022'),('244022'),('244022'),('244022'),('244022'),('244022'),('244022'),('244026'),('244026'),('244026'),('244026'),('244026'),('244026'),('244025'),('244025'),('244025'),('244025'),('244025'),('244025'),('244025'),('244025'),('244030'),('244030'),('244030'),('244030'),('244030'),('244030'),('244030'),('244030'),('244023'),('244023'),('244023'),('244023'),('244023'),('244023'),('244024'),('244024'),('244024'),('244024'),('244024'),('244024'),('244024'),('244024'),('244027'),('244027'),('244027'),('244027'),('244027'),('244027'),('244027'),('244027'),('244028'),('244028'),('244028'),('244028'),('244028'),('244028'),('244028'),('244028'),('244029'),('244029'),('244029'),('244029'),('244029'),('244029'),('244029'),('244029'),('244031'),('244031'),('244031'),('244031'),('244031'),('244031'),('244031'),('244031'),('082046'),('082046'),('082046'),('082046'),('082047'),('082047'),('082048'),('082048'),('126015'),('126015'),('126016'),('126016'),('126016'),('126016'),('126016'),('416005'),('421001'),('421001'),('421002'),('016037'),('016037'),('016037'),('016037'),('016036'),('016036'),('016036'),('016036'),('115124'),('115124'),('115126'),('240049'),('240049'),('240048'),('240048'),('240047'),('240047'),('240046'),('240046'),('240045'),('240044'),('244032'),('244033'),('422002'),('422004'),('422004'),('422004'),('422005'),('422005'),('184013'),('184013'),('184013'),('805001'),('805002'),('805003'),('805004'),('805005'),('056024'),('056024'),('056024'),('423001'),('344010'),('235009'),('235009'),('235009'),('235009'),('212014'),('212014'),('056025'),('056025'),('056025'),('056026'),('056026'),('056026'),('056026'),('056026'),('056026'),('244034'),('244034'),('244034'),('244034'),('244034'),('244034'),('244035'),('244035'),('244035'),('244035'),('244035'),('244035'),('244035'),('244036'),('244036'),('244036'),('244036'),('244036'),('244036'),('244036'),('244037'),('244037'),('244037'),('244037'),('244037'),('244037'),('244037'),('244038'),('244038'),('244038'),('244038'),('244038'),('244038'),('244038'),('244039'),('244039'),('244039'),('244039'),('244039'),('244039'),('244039'),('203015'),('245002'),('245002'),('245001'),('245001'),('056029'),('056030'),('056032'),('424001'),('056034'),('056034'),('056034'),('056034'),('056033'),('056033'),('056033'),('805006'),('805007'),('805008'),('805009'),('805010'),('422008'),('422008'),('422007'),('422007'),('422006'),('422006'),('422010'),('422009'),('422009'),('422011'),('422011'),('209004'),('209004'),('150022'),('100002'),('056035'),('056035'),('056035'),('023036'),('023036'),('185005'),('246001'),('246001'),('247001'),('247001'),('247001'),('247001'),('247001'),('247001'),('247001'),('247002'),('247002'),('425001'),('416006'),('416006'),('165042'),('165041'),('165040'),('165043'),('010040'),('010039'),('010038'),('010036'),('248001'),('248002'),('248003'),('248004'),('248005'),('249001'),('249003'),('249004'),('249005'),('250007'),('250001'),('250002'),('250003'),('250004'),('250005'),('250006'),('250008'),('250009'),('250010'),('250011'),('250012'),('250013'),('251001'),('251002'),('806001'),('806002'),('235010'),('243009'),('249007'),('249008'),('249009'),('011024'),('011025'),('429001'),('429001'),('429002'),('429002'),('429003'),('429003');
+select field from t1 group by field;
field
001001
001010
@@ -1614,11 +1621,28 @@ field
429001
429002
429003
+drop table t1;
+create table t1 (a enum (' ','a','b') not null);
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('','a','b') NOT NULL default ''
) TYPE=MyISAM
+drop table t1;
+create table t1 (a enum (' ','a','b ') not null default 'b ');
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('','a','b') NOT NULL default 'b'
) TYPE=MyISAM
+drop table t1;
+create table t1 (a enum ('0','1'));
+insert into t1 set a='foobar';
+select * from t1;
+a
+
+update t1 set a = replace(a,'x','y');
+select * from t1;
+a
+
+drop table t1;
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index d8fbc5bc725..e85bced353a 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -1,12 +1,21 @@
+SELECT 10,10.0,10.,.1e+2,100.0e-1;
10 10.0 10. .1e+2 100.0e-1
10 10.0 10 10 10
+SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000;
6e-05 -6e-05 --6e-05 -6e-05+1.000000
6e-05 -6e-05 6e-05 0.99994
+SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1;
1e1 1.e1 1.0e1 1e+1 1.e+1 1.0e+1 1e-1 1.e-1 1.0e-1
10 10 10 10 10 10 0.1 0.1 0.1
+drop table if exists t1;
+create table t1 (f1 float(24),f2 float(52));
+show full columns from t1;
Field Type Null Key Default Extra Privileges
f1 float YES NULL select,insert,update,references
f2 double YES NULL select,insert,update,references
+insert into t1 values(10,10),(1e+5,1e+5),(1234567890,1234567890),(1e+10,1e+10),(1e+15,1e+15),(1e+20,1e+20),(1e+50,1e+50),(1e+150,1e+150);
+insert into t1 values(-10,-10),(1e-5,1e-5),(1e-10,1e-10),(1e-15,1e-15),(1e-20,1e-20),(1e-50,1e-50),(1e-150,1e-150);
+select * from t1;
f1 f2
10 10
100000 100000
@@ -23,28 +32,43 @@ f1 f2
1e-20 1e-20
0 1e-50
0 1e-150
+drop table t1;
+create table t1 (datum double);
+insert into t1 values (0.5),(1.0),(1.5),(2.0),(2.5);
+select * from t1;
datum
0.5
1
1.5
2
2.5
+select * from t1 where datum < 1.5;
datum
0.5
1
+select * from t1 where datum > 1.5;
datum
2
2.5
+select * from t1 where datum = 1.5;
datum
1.5
+drop table t1;
+create table t1 (a decimal(7,3) not null, key (a));
+insert into t1 values ("0"),("-0.00"),("-0.01"),("-0.002"),("1");
+select a from t1 order by a;
a
-0.010
-0.002
-0.000
0.000
1.000
+select min(a) from t1;
min(a)
-0.010
+drop table t1;
+create table t1 (f float, f2 float(24), f3 float(6,2), d double, d2 float(53), d3 double(10,3), de decimal, de2 decimal(6), de3 decimal(5,2), n numeric, n2 numeric(8), n3 numeric(5,6));
+show full columns from t1;
Field Type Null Key Default Extra Privileges
f float YES NULL select,insert,update,references
f2 float YES NULL select,insert,update,references
@@ -58,11 +82,20 @@ de3 decimal(5,2) YES NULL select,insert,update,references
n decimal(10,0) YES NULL select,insert,update,references
n2 decimal(8,0) YES NULL select,insert,update,references
n3 decimal(7,6) YES NULL select,insert,update,references
+drop table t1;
+create table t1 (a decimal(7,3) not null, key (a));
+insert into t1 values ("0"),("-0.00"),("-0.01"),("-0.002"),("1");
+select a from t1 order by a;
a
-0.010
-0.002
-0.000
0.000
1.000
+select min(a) from t1;
min(a)
-0.010
+drop table t1;
+create table t1 (f float(54));
+Incorrect column specifier for column 'f'
+drop table if exists t1;
diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result
index abb8ef8cb09..4f4b4eb43eb 100644
--- a/mysql-test/r/type_ranges.result
+++ b/mysql-test/r/type_ranges.result
@@ -1,3 +1,43 @@
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (
+auto int(5) unsigned NOT NULL auto_increment,
+string char(10) default "hello",
+tiny tinyint(4) DEFAULT '0' NOT NULL ,
+short smallint(6) DEFAULT '1' NOT NULL ,
+medium mediumint(8) DEFAULT '0' NOT NULL,
+long_int int(11) DEFAULT '0' NOT NULL,
+longlong bigint(13) DEFAULT '0' NOT NULL,
+real_float float(13,1) DEFAULT 0.0 NOT NULL,
+real_double double(16,4),
+utiny tinyint(3) unsigned DEFAULT '0' NOT NULL,
+ushort smallint(5) unsigned zerofill DEFAULT '00000' NOT NULL,
+umedium mediumint(8) unsigned DEFAULT '0' NOT NULL,
+ulong int(11) unsigned DEFAULT '0' NOT NULL,
+ulonglong bigint(13) unsigned DEFAULT '0' NOT NULL,
+time_stamp timestamp,
+date_field date,
+time_field time,
+date_time datetime,
+blob_col blob,
+tinyblob_col tinyblob,
+mediumblob_col mediumblob not null,
+longblob_col longblob not null,
+options enum('one','two','tree') not null,
+flags set('one','two','tree') not null,
+PRIMARY KEY (auto),
+KEY (utiny),
+KEY (tiny),
+KEY (short),
+KEY any_name (medium),
+KEY (longlong),
+KEY (real_float),
+KEY (ushort),
+KEY (umedium),
+KEY (ulong),
+KEY (ulonglong,ulong),
+KEY (options,flags)
+);
+show full fields from t1;
Field Type Null Key Default Extra Privileges
auto int(5) unsigned PRI NULL auto_increment select,insert,update,references
string varchar(10) YES hello select,insert,update,references
@@ -23,21 +63,34 @@ mediumblob_col mediumblob select,insert,update,references
longblob_col longblob select,insert,update,references
options enum('one','two','tree') MUL one select,insert,update,references
flags set('one','two','tree') select,insert,update,references
-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
-t1 0 PRIMARY 1 auto A 0 NULL NULL
-t1 1 utiny 1 utiny A NULL NULL NULL
-t1 1 tiny 1 tiny A NULL NULL NULL
-t1 1 short 1 short A NULL NULL NULL
-t1 1 any_name 1 medium A NULL NULL NULL
-t1 1 longlong 1 longlong A NULL NULL NULL
-t1 1 real_float 1 real_float A NULL NULL NULL
-t1 1 ushort 1 ushort A NULL NULL NULL
-t1 1 umedium 1 umedium A NULL NULL NULL
-t1 1 ulong 1 ulong A NULL NULL NULL
-t1 1 ulonglong 1 ulonglong A NULL NULL NULL
-t1 1 ulonglong 2 ulong A NULL NULL NULL
-t1 1 options 1 options A NULL NULL NULL
-t1 1 options 2 flags A NULL NULL NULL
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 auto A 0 NULL NULL BTREE
+t1 1 utiny 1 utiny A NULL NULL NULL BTREE
+t1 1 tiny 1 tiny A NULL NULL NULL BTREE
+t1 1 short 1 short A NULL NULL NULL BTREE
+t1 1 any_name 1 medium A NULL NULL NULL BTREE
+t1 1 longlong 1 longlong A NULL NULL NULL BTREE
+t1 1 real_float 1 real_float A NULL NULL NULL BTREE
+t1 1 ushort 1 ushort A NULL NULL NULL BTREE
+t1 1 umedium 1 umedium A NULL NULL NULL BTREE
+t1 1 ulong 1 ulong A NULL NULL NULL BTREE
+t1 1 ulonglong 1 ulonglong A NULL NULL NULL BTREE
+t1 1 ulonglong 2 ulong A NULL NULL NULL BTREE
+t1 1 options 1 options A NULL NULL NULL BTREE
+t1 1 options 2 flags A NULL NULL NULL BTREE
+CREATE UNIQUE INDEX test on t1 ( auto ) ;
+CREATE INDEX test2 on t1 ( ulonglong,ulong) ;
+CREATE INDEX test3 on t1 ( medium ) ;
+DROP INDEX test ON t1;
+insert into t1 values (10, 1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one');
+insert into t1 values (NULL,2,2,2,2,2,2,2,2,2,2,2,2,2,NULL,NULL,NULL,NULL,NULL,NULL,2,2,'two','two,one');
+insert into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','10:10:10','19970303 101010','','','','3',3,3);
+insert into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,080706,19970403090807,-1,-1,-1,'-1',-1,-1);
+insert into t1 values (0,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,NULL,0,0,0,-4294967295,-4294967295,-4294967295,'-4294967295',0,"one,two,tree");
+insert into t1 values (0,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,NULL,0,0,0,4294967295,4294967295,4294967295,'4294967295',0,0);
+insert into t1 (tiny) values (1);
+select auto,string,tiny,short,medium,long_int,longlong,real_float,real_double,utiny,ushort,umedium,ulong,ulonglong,mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000),date_field,time_field,date_time,blob_col,tinyblob_col,mediumblob_col,longblob_col from t1;
auto string tiny short medium long_int longlong real_float real_double utiny ushort umedium ulong ulonglong mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000) date_field time_field date_time blob_col tinyblob_col mediumblob_col longblob_col
10 1 1 1 1 1 1 1.0 1.0000 1 00001 1 1 1 0 0000-00-00 00:00:00 0000-00-00 00:00:00 1 1 1 1
11 2 2 2 2 2 2 2.0 2.0000 2 00002 2 2 2 0 NULL NULL NULL NULL NULL 2 2
@@ -46,6 +99,27 @@ auto string tiny short medium long_int longlong real_float real_double utiny ush
14 -429496729 -128 -32768 -8388608 -2147483648 -4294967295 -4294967296.0 -4294967295.0000 0 00000 0 0 18446744069414584321 0 0000-00-00 00:00:00 0000-00-00 00:00:00 -4294967295 -4294967295 -4294967295 -4294967295
15 4294967295 127 32767 8388607 2147483647 4294967295 4294967296.0 4294967295.0000 255 65535 16777215 4294967295 4294967295 0 0000-00-00 00:00:00 0000-00-00 00:00:00 4294967295 4294967295 4294967295 4294967295
16 hello 1 1 0 0 0 0.0 NULL 0 00000 0 0 0 0 NULL NULL NULL NULL NULL
+ALTER TABLE t1
+add new_field char(10) default "new" not null,
+change blob_col new_blob_col varchar(20),
+change date_field date_field char(10),
+alter column string set default "new default",
+alter short drop default,
+DROP INDEX utiny,
+DROP INDEX ushort,
+DROP PRIMARY KEY,
+DROP FOREIGN KEY any_name,
+ADD INDEX (auto);
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1
+RENAME as t2,
+DROP longblob_col;
+UNLOCK TABLES;
+ALTER TABLE t2 rename as t3;
+LOCK TABLES t3 WRITE ;
+ALTER TABLE t3 rename as t1;
+UNLOCK TABLES;
+select auto,new_field,new_blob_col,date_field from t1 ;
auto new_field new_blob_col date_field
10 new 1 0000-00-00
11 new NULL NULL
@@ -54,6 +128,15 @@ auto new_field new_blob_col date_field
14 new -4294967295 0000-00-00
15 new 4294967295 0000-00-00
16 new NULL NULL
+CREATE TABLE t2 (
+auto int(5) unsigned NOT NULL auto_increment,
+string char(20),
+mediumblob_col mediumblob not null,
+new_field char(2),
+PRIMARY KEY (auto)
+);
+INSERT INTO t2 (string,mediumblob_col,new_field) SELECT string,mediumblob_col,new_field from t1 where auto > 10;
+select * from t2;
auto string mediumblob_col new_field
1 2 2 ne
2 0.33 ne
@@ -61,21 +144,30 @@ auto string mediumblob_col new_field
4 -429496729 -4294967295 ne
5 4294967295 4294967295 ne
6 hello ne
+select distinct flags from t1;
flags
one,two,tree
one
one,two
+select flags from t1 where find_in_set("two",flags)>0;
flags
one,two,tree
one,two,tree
one,two
one,two
+select flags from t1 where find_in_set("unknown",flags)>0;
flags
+select options,flags from t1 where options="ONE" and flags="ONE";
options flags
one one
+select options,flags from t1 where options="one" and flags="one";
options flags
one one
+drop table t2;
+create table t2 select * from t1;
+update t2 set string="changed" where auto=16;
+show full columns from t1;
Field Type Null Key Default Extra Privileges
auto int(5) unsigned MUL NULL auto_increment select,insert,update,references
string varchar(10) YES new defaul select,insert,update,references
@@ -101,6 +193,7 @@ mediumblob_col mediumblob select,insert,update,references
options enum('one','two','tree') MUL one select,insert,update,references
flags set('one','two','tree') select,insert,update,references
new_field varchar(10) new select,insert,update,references
+show full columns from t2;
Field Type Null Key Default Extra Privileges
auto int(5) unsigned 0 select,insert,update,references
string varchar(10) YES new defaul select,insert,update,references
@@ -126,16 +219,22 @@ mediumblob_col mediumblob select,insert,update,references
options enum('one','two','tree') one select,insert,update,references
flags set('one','two','tree') select,insert,update,references
new_field varchar(10) new select,insert,update,references
+select t1.auto,t2.auto from t1,t2 where t1.auto=t2.auto and ((t1.string<>t2.string and (t1.string is not null or t2.string is not null)) or (t1.tiny<>t2.tiny and (t1.tiny is not null or t2.tiny is not null)) or (t1.short<>t2.short and (t1.short is not null or t2.short is not null)) or (t1.medium<>t2.medium and (t1.medium is not null or t2.medium is not null)) or (t1.long_int<>t2.long_int and (t1.long_int is not null or t2.long_int is not null)) or (t1.longlong<>t2.longlong and (t1.longlong is not null or t2.longlong is not null)) or (t1.real_float<>t2.real_float and (t1.real_float is not null or t2.real_float is not null)) or (t1.real_double<>t2.real_double and (t1.real_double is not null or t2.real_double is not null)) or (t1.utiny<>t2.utiny and (t1.utiny is not null or t2.utiny is not null)) or (t1.ushort<>t2.ushort and (t1.ushort is not null or t2.ushort is not null)) or (t1.umedium<>t2.umedium and (t1.umedium is not null or t2.umedium is not null)) or (t1.ulong<>t2.ulong and (t1.ulong is not null or t2.ulong is not null)) or (t1.ulonglong<>t2.ulonglong and (t1.ulonglong is not null or t2.ulonglong is not null)) or (t1.time_stamp<>t2.time_stamp and (t1.time_stamp is not null or t2.time_stamp is not null)) or (t1.date_field<>t2.date_field and (t1.date_field is not null or t2.date_field is not null)) or (t1.time_field<>t2.time_field and (t1.time_field is not null or t2.time_field is not null)) or (t1.date_time<>t2.date_time and (t1.date_time is not null or t2.date_time is not null)) or (t1.new_blob_col<>t2.new_blob_col and (t1.new_blob_col is not null or t2.new_blob_col is not null)) or (t1.tinyblob_col<>t2.tinyblob_col and (t1.tinyblob_col is not null or t2.tinyblob_col is not null)) or (t1.mediumblob_col<>t2.mediumblob_col and (t1.mediumblob_col is not null or t2.mediumblob_col is not null)) or (t1.options<>t2.options and (t1.options is not null or t2.options is not null)) or (t1.flags<>t2.flags and (t1.flags is not null or t2.flags is not null)) or (t1.new_field<>t2.new_field and (t1.new_field is not null or t2.new_field is not null)));
auto auto
16 16
+select t1.auto,t2.auto from t1,t2 where t1.auto=t2.auto and not (t1.string<=>t2.string and t1.tiny<=>t2.tiny and t1.short<=>t2.short and t1.medium<=>t2.medium and t1.long_int<=>t2.long_int and t1.longlong<=>t2.longlong and t1.real_float<=>t2.real_float and t1.real_double<=>t2.real_double and t1.utiny<=>t2.utiny and t1.ushort<=>t2.ushort and t1.umedium<=>t2.umedium and t1.ulong<=>t2.ulong and t1.ulonglong<=>t2.ulonglong and t1.time_stamp<=>t2.time_stamp and t1.date_field<=>t2.date_field and t1.time_field<=>t2.time_field and t1.date_time<=>t2.date_time and t1.new_blob_col<=>t2.new_blob_col and t1.tinyblob_col<=>t2.tinyblob_col and t1.mediumblob_col<=>t2.mediumblob_col and t1.options<=>t2.options and t1.flags<=>t2.flags and t1.new_field<=>t2.new_field);
auto auto
16 16
+drop table t2;
+create table t2 (primary key (auto)) select auto+1 as auto,1 as t1, "a" as t2, repeat("a",256) as t3, binary repeat("b",256) as t4 from t1;
+show full columns from t2;
Field Type Null Key Default Extra Privileges
-auto bigint(17) PRI 0 select,insert,update,references
+auto bigint(17) unsigned PRI 0 select,insert,update,references
t1 bigint(1) 0 select,insert,update,references
t2 char(1) select,insert,update,references
t3 mediumtext select,insert,update,references
t4 mediumblob select,insert,update,references
+select * from t2;
auto t1 t2 t3 t4
11 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
12 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
@@ -144,16 +243,39 @@ auto t1 t2 t3 t4
15 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
16 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
17 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+drop table t1,t2;
+create table t1 (c int);
+insert into t1 values(1),(2);
+create table t2 select * from t1;
+create table t3 select * from t1, t2;
+Duplicate column name 'c'
+create table t3 select t1.c AS c1, t2.c AS c2,1 as "const" from t1, t2;
+show full columns from t3;
Field Type Null Key Default Extra Privileges
c1 int(11) YES NULL select,insert,update,references
c2 int(11) YES NULL select,insert,update,references
const bigint(1) 0 select,insert,update,references
+drop table t1,t2,t3;
+create table t1 ( myfield INT NOT NULL, UNIQUE INDEX (myfield), unique (myfield), index(myfield));
+drop table t1;
+create table t1 ( id integer unsigned not null primary key );
+create table t2 ( id integer unsigned not null primary key );
+insert into t1 values (1), (2);
+insert into t2 values (1);
+select t1.id as id_A, t2.id as id_B from t1 left join t2 using ( id );
id_A id_B
1 1
2 NULL
+create table t3 (id_A integer unsigned not null, id_B integer unsigned null );
+insert into t3 select t1.id as id_A, t2.id as id_B from t1 left join t2 using ( id );
+select * from t3;
id_A id_B
1 1
2 NULL
+drop table t3;
+create table t3 select t1.id as id_A, t2.id as id_B from t1 left join t2 using ( id );
+select * from t3;
id_A id_B
1 1
2 NULL
+drop table t1,t2,t3;
diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result
index 8b065618742..59f8744e2ec 100644
--- a/mysql-test/r/type_set.result
+++ b/mysql-test/r/type_set.result
@@ -1,8 +1,15 @@
+drop table if exists t1;
+create table t1 (a set (' ','a','b') not null);
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` set('','a','b') NOT NULL default ''
) TYPE=MyISAM
+drop table t1;
+create table t1 (a set (' ','a','b ') not null default 'b ');
+show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` set('','a','b') NOT NULL default 'b'
) TYPE=MyISAM
+drop table t1;
diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result
index 1a137a89b1e..bacc3ec0176 100644
--- a/mysql-test/r/type_time.result
+++ b/mysql-test/r/type_time.result
@@ -1,3 +1,8 @@
+drop table if exists t1;
+create table t1 (t time);
+insert into t1 values("10:22:33"),("12:34:56.78"),(10),(1234),(123456.78),(1234559.99),("1"),("1:23"),("1:23:45"), ("10.22"), ("-10 1:22:33.45"),("20 10:22:33"),("1999-02-03 20:33:34");
+insert t1 values (30),(1230),("1230"),("12:30"),("12:30:35"),("1 12:30:31.32");
+select * from t1;
t
10:22:33
12:34:56
@@ -18,6 +23,8 @@ t
12:30:00
12:30:35
36:30:31
+insert into t1 values("10.22.22"),(1234567),(123456789),(123456789.10),("10 22:22"),("12.45a");
+select * from t1;
t
10:22:33
12:34:56
@@ -44,6 +51,10 @@ t
838:59:59
262:22:00
00:00:12
+drop table t1;
+create table t1 (t time);
+insert into t1 values ('09:00:00'),('13:00:00'),('19:38:34'), ('13:00:00'),('09:00:00'),('09:00:00'),('13:00:00'),('13:00:00'),('13:00:00'),('09:00:00');
+select t, time_to_sec(t),sec_to_time(time_to_sec(t)) from t1;
t time_to_sec(t) sec_to_time(time_to_sec(t))
09:00:00 32400 09:00:00
13:00:00 46800 13:00:00
@@ -55,6 +66,7 @@ t time_to_sec(t) sec_to_time(time_to_sec(t))
13:00:00 46800 13:00:00
13:00:00 46800 13:00:00
09:00:00 32400 09:00:00
+select sec_to_time(time_to_sec(t)) from t1;
sec_to_time(time_to_sec(t))
09:00:00
13:00:00
@@ -66,3 +78,4 @@ sec_to_time(time_to_sec(t))
13:00:00
13:00:00
09:00:00
+drop table t1;
diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result
index 8996ca59f7f..cd45bcf911d 100644
--- a/mysql-test/r/type_timestamp.result
+++ b/mysql-test/r/type_timestamp.result
@@ -1,11 +1,50 @@
-t
-19700101032034
+drop table if exists t1,t2;
+CREATE TABLE t1 (a int, t timestamp);
+CREATE TABLE t2 (a int, t datetime);
+SET TIMESTAMP=1234;
+insert into t1 values(1,NULL);
+insert into t1 values(2,"2002-03-03");
+SET TIMESTAMP=1235;
+insert into t1 values(3,NULL);
+SET TIMESTAMP=1236;
+insert into t1 (a) values(4);
+insert into t2 values(5,"2002-03-04"),(6,NULL),(7,"2002-03-05"),(8,"00-00-00");
+SET TIMESTAMP=1237;
+insert into t1 select * from t2;
+SET TIMESTAMP=1238;
+insert into t1 (a) select a+1 from t2 where a=8;
+select * from t1;
+a t
+1 19700101032034
+2 20020303000000
+3 19700101032035
+4 19700101032036
+5 20020304000000
+6 19700101032037
+7 20020305000000
+8 00000000000000
+9 19700101032038
+drop table t1,t2;
+SET TIMESTAMP=1234;
+CREATE TABLE t1 (value TEXT NOT NULL, id VARCHAR(32) NOT NULL, stamp timestamp, PRIMARY KEY (id));
+INSERT INTO t1 VALUES ("my value", "myKey","1999-04-02 00:00:00");
+SELECT stamp FROM t1 WHERE id="myKey";
stamp
19990402000000
+UPDATE t1 SET value="my value" WHERE id="myKey";
+SELECT stamp FROM t1 WHERE id="myKey";
stamp
19990402000000
+drop table t1;
+create table t1 (a timestamp);
+insert into t1 values (now());
+select date_format(a,"%Y %y"),year(a),year(now()) from t1;
date_format(a,"%Y %y") year(a) year(now())
1970 70 1970 1970
+drop table t1;
+create table t1 (ix timestamp);
+insert into t1 values (19991101000000),(19990102030405),(19990630232922),(19990601000000),(19990930232922),(19990531232922),(19990501000000),(19991101000000),(19990501000000),(20030101010160),(20030101016001),(20030101240101),(20030132010101),(20031301010101);
+select * from t1;
ix
19991101000000
19990102030405
@@ -16,6 +55,39 @@ ix
19990501000000
19991101000000
19990501000000
+00000000000000
+00000000000000
+00000000000000
+00000000000000
+00000000000000
+delete from t1;
+insert into t1 values ("19991101000000"),("19990102030405"),("19990630232922"),("19990601000000"),("20030101010160"),("20030101016001"),("20030101240101"),("20030132010101"),("20031301010101");
+select * from t1;
+ix
+19991101000000
+19990102030405
+19990630232922
+19990601000000
+00000000000000
+00000000000000
+00000000000000
+00000000000000
+00000000000000
+drop table t1;
+CREATE TABLE t1 (date date, date_time datetime, time_stamp timestamp);
+INSERT INTO t1 VALUES ("1998-12-31","1998-12-31 23:59:59",19981231235959);
+INSERT INTO t1 VALUES ("1999-01-01","1999-01-01 00:00:00",19990101000000);
+INSERT INTO t1 VALUES ("1999-09-09","1999-09-09 23:59:59",19990909235959);
+INSERT INTO t1 VALUES ("2000-01-01","2000-01-01 00:00:00",20000101000000);
+INSERT INTO t1 VALUES ("2000-02-28","2000-02-28 00:00:00",20000228000000);
+INSERT INTO t1 VALUES ("2000-02-29","2000-02-29 00:00:00",20000229000000);
+INSERT INTO t1 VALUES ("2000-03-01","2000-03-01 00:00:00",20000301000000);
+INSERT INTO t1 VALUES ("2000-12-31","2000-12-31 23:59:59",20001231235959);
+INSERT INTO t1 VALUES ("2001-01-01","2001-01-01 00:00:00",20010101000000);
+INSERT INTO t1 VALUES ("2004-12-31","2004-12-31 23:59:59",20041231235959);
+INSERT INTO t1 VALUES ("2005-01-01","2005-01-01 00:00:00",20050101000000);
+INSERT INTO t1 VALUES ("2030-01-01","2030-01-01 00:00:00",20300101000000);
+SELECT * FROM t1;
date date_time time_stamp
1998-12-31 1998-12-31 23:59:59 19981231235959
1999-01-01 1999-01-01 00:00:00 19990101000000
@@ -29,3 +101,69 @@ date date_time time_stamp
2004-12-31 2004-12-31 23:59:59 20041231235959
2005-01-01 2005-01-01 00:00:00 20050101000000
2030-01-01 2030-01-01 00:00:00 20300101000000
+drop table t1;
+show variables like 'new';
+Variable_name Value
+new OFF
+create table t1 (t2 timestamp(2), t4 timestamp(4), t6 timestamp(6),
+t8 timestamp(8), t10 timestamp(10), t12 timestamp(12),
+t14 timestamp(14));
+insert t1 values (0,0,0,0,0,0,0),
+("1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
+"1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
+"1997-12-31 23:47:59");
+select * from t1;
+t2 t4 t6 t8 t10 t12 t14
+00 0000 000000 00000000 0000000000 000000000000 00000000000000
+97 9712 971231 19971231 9712312347 971231234759 19971231234759
+set new=1;
+select * from t1;
+t2 t4 t6 t8 t10 t12 t14
+0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00
+1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59
+drop table t1;
+create table t1 (t1 timestamp default '2003-01-01 00:00:00',
+t2 timestamp default '2003-01-01 00:00:00');
+set TIMESTAMP=1000000000;
+insert into t1 values();
+select * from t1;
+t1 t2
+2001-09-09 04:46:40 2003-01-01 00:00:00
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `t1` timestamp(14) NOT NULL,
+ `t2` timestamp(14) NOT NULL default '2003-01-01 00:00:00'
+) TYPE=MyISAM
+show columns from t1;
+Field Type Null Key Default Extra
+t1 timestamp(14) YES NULL
+t2 timestamp(14) YES 2003-01-01 00:00:00
+show columns from t1 like 't2';
+Field Type Null Key Default Extra
+t2 timestamp(14) YES 2003-01-01 00:00:00
+create table t2 (select * from t1);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `t1` timestamp(14) NOT NULL,
+ `t2` timestamp(14) NOT NULL default '2003-01-01 00:00:00'
+) TYPE=MyISAM
+alter table t1 add column t0 timestamp first;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `t0` timestamp(14) NOT NULL,
+ `t1` timestamp(14) NOT NULL default '2003-01-01 00:00:00',
+ `t2` timestamp(14) NOT NULL default '2003-01-01 00:00:00'
+) TYPE=MyISAM
+drop table t1,t2;
+create table t1 (ts1 timestamp, ts2 timestamp);
+set TIMESTAMP=1000000000;
+insert into t1 values ();
+insert into t1 values (DEFAULT, DEFAULT);
+select * from t1;
+ts1 ts2
+2001-09-09 04:46:40 0000-00-00 00:00:00
+2001-09-09 04:46:40 0000-00-00 00:00:00
+drop table t1;
diff --git a/mysql-test/r/type_uint.result b/mysql-test/r/type_uint.result
index 54fa717e0f8..1acfc700d3a 100644
--- a/mysql-test/r/type_uint.result
+++ b/mysql-test/r/type_uint.result
@@ -1,3 +1,9 @@
+drop table if exists t1;
+create table t1 (this int unsigned);
+insert into t1 values (1);
+insert into t1 values (-1);
+select * from t1;
this
1
0
+drop table t1;
diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result
index 7dc15a4dd1b..5ef3c1bba81 100644
--- a/mysql-test/r/type_year.result
+++ b/mysql-test/r/type_year.result
@@ -1,3 +1,7 @@
+drop table if exists t1;
+create table t1 (y year,y2 year(2));
+insert into t1 values (0,0),(1999,1999),(2000,2000),(2001,2001),(70,70),(69,69);
+select * from t1;
y y2
0000 00
1999 99
@@ -5,6 +9,7 @@ y y2
2001 01
1970 70
2069 69
+select * from t1 order by y;
y y2
0000 00
1970 70
@@ -12,6 +17,7 @@ y y2
2000 00
2001 01
2069 69
+select * from t1 order by y2;
y y2
1970 70
1999 99
@@ -19,3 +25,10 @@ y y2
2000 00
2001 01
2069 69
+drop table t1;
+create table t1 (y year);
+insert into t1 values (now());
+select if(y = now(), 1, 0) from t1;
+if(y = now(), 1, 0)
+1
+drop table t1;
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
new file mode 100644
index 00000000000..fc5aa1ad0cb
--- /dev/null
+++ b/mysql-test/r/union.result
@@ -0,0 +1,429 @@
+drop table if exists t1,t2,t3,t4,t5,t6;
+CREATE TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
+CREATE TABLE t2 (a int not null, b char (10) not null);
+insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
+select a,b from t1 union distinct select a,b from t2;
+a b
+1 a
+2 b
+3 c
+4 d
+5 f
+6 e
+select a,b from t1 union all select a,b from t2;
+a b
+1 a
+2 b
+3 c
+3 c
+3 c
+4 d
+5 f
+6 e
+select a,b from t1 union all select a,b from t2 order by b;
+a b
+1 a
+2 b
+3 c
+3 c
+3 c
+4 d
+6 e
+5 f
+select a,b from t1 union all select a,b from t2 union select 7,'g';
+a b
+1 a
+2 b
+3 c
+3 c
+3 c
+4 d
+5 f
+6 e
+7 g
+select 0,'#' union select a,b from t1 union all select a,b from t2 union select 7,'gg';
+0 #
+0 #
+1 a
+2 b
+3 c
+3 c
+3 c
+4 d
+5 f
+6 e
+7 g
+select a,b from t1 union select a,b from t1;
+a b
+1 a
+2 b
+3 c
+select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b;
+t1 b count(*)
+t1 a 1
+t1 b 1
+t1 c 2
+t2 c 1
+t2 d 1
+t2 e 1
+t2 f 1
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4;
+a b
+1 a
+2 b
+3 c
+4 d
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1);
+a b
+1 a
+2 b
+3 c
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
+a b
+3 c
+2 b
+1 a
+explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 4
+t2 ALL NULL NULL NULL NULL 4 Using filesort
+t1 ALL NULL NULL NULL NULL 4
+(select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2;
+a b
+1 a
+2 b
+select found_rows();
+found_rows()
+6
+select sql_calc_found_rows a,b from t1 union all select a,b from t2 limit 2;
+a b
+1 a
+2 b
+select found_rows();
+found_rows()
+8
+explain select a,b from t1 union all select a,b from t2;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 4
+t2 ALL NULL NULL NULL NULL 4
+explain select xx from t1 union select 1;
+Unknown column 'xx' in 'field list'
+explain select a,b from t1 union select 1;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 4
+ 0 0 No tables used
+explain select 1 union select a,b from t1 union select 1;
+table type possible_keys key key_len ref rows Extra
+ 0 0 No tables used
+t1 ALL NULL NULL NULL NULL 4
+ 0 0 No tables used
+explain select a,b from t1 union select 1 limit 0;
+table type possible_keys key key_len ref rows Extra
+t1 ALL NULL NULL NULL NULL 4
+ 0 0 Impossible WHERE
+select a,b from t1 into outfile 'skr' union select a,b from t2;
+Wrong usage of UNION and INTO
+select a,b from t1 order by a union select a,b from t2;
+Wrong usage of UNION and ORDER BY
+insert into t3 select a from t1 order by a union select a from t2;
+Wrong usage of UNION and ORDER BY
+create table t3 select a,b from t1 union select a from t2;
+The used SELECT statements have a different number of columns
+select a,b from t1 union select a from t2;
+The used SELECT statements have a different number of columns
+select * from t1 union select a from t2;
+The used SELECT statements have a different number of columns
+select a from t1 union select * from t2;
+The used SELECT statements have a different number of columns
+select * from t1 union select SQL_BUFFER_RESULT * from t2;
+Wrong usage/placement of 'SQL_BUFFER_RESULT'
+create table t3 select a,b from t1 union all select a,b from t2;
+insert into t3 select a,b from t1 union all select a,b from t2;
+replace into t3 select a,b as c from t1 union all select a,b from t2;
+drop table t1,t2,t3;
+CREATE TABLE t1 (
+`pseudo` char(35) NOT NULL default '',
+`pseudo1` char(35) NOT NULL default '',
+`same` tinyint(1) unsigned NOT NULL default '1',
+PRIMARY KEY (`pseudo1`),
+KEY `pseudo` (`pseudo`)
+) TYPE=MyISAM;
+INSERT INTO t1 (pseudo,pseudo1,same) VALUES ('joce', 'testtt', 1),('joce', 'tsestset', 1),('dekad', 'joce', 1);
+SELECT pseudo FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo FROM t1 WHERE pseudo='joce';
+pseudo
+dekad
+joce
+SELECT pseudo1 FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo1 FROM t1 WHERE pseudo='joce';
+pseudo1
+joce
+testtt
+tsestset
+SELECT * FROM t1 WHERE pseudo1='joce' UNION SELECT * FROM t1 WHERE pseudo='joce' order by pseudo desc,pseudo1 desc;
+pseudo pseudo1 same
+joce tsestset 1
+joce testtt 1
+dekad joce 1
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT pseudo FROM t1 WHERE pseudo1='joce';
+pseudo1
+testtt
+tsestset
+dekad
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION ALL SELECT pseudo FROM t1 WHERE pseudo1='joce';
+pseudo1
+testtt
+tsestset
+dekad
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT 1;
+pseudo1
+testtt
+tsestset
+1
+drop table t1;
+drop table if exists t1,t2;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(2),(3),(4),(5);
+insert into t2 values (11),(12),(13),(14),(15);
+(select * from t1 limit 2) union (select * from t2 limit 3) limit 4;
+a
+1
+2
+11
+12
+(select * from t1 limit 2) union (select * from t2 limit 3);
+a
+1
+2
+11
+12
+13
+(select * from t1 limit 2) union (select * from t2 limit 20,3);
+a
+1
+2
+set SQL_SELECT_LIMIT=2;
+(select * from t1 limit 1) union (select * from t2 limit 3);
+a
+1
+11
+set SQL_SELECT_LIMIT=DEFAULT;
+drop table t1,t2;
+CREATE TABLE t1 (
+cid smallint(5) unsigned NOT NULL default '0',
+cv varchar(250) NOT NULL default '',
+PRIMARY KEY (cid),
+UNIQUE KEY cv (cv)
+) ;
+INSERT INTO t1 VALUES (8,'dummy');
+CREATE TABLE t2 (
+cid bigint(20) unsigned NOT NULL auto_increment,
+cap varchar(255) NOT NULL default '',
+PRIMARY KEY (cid),
+KEY cap (cap)
+) ;
+CREATE TABLE t3 (
+gid bigint(20) unsigned NOT NULL auto_increment,
+gn varchar(255) NOT NULL default '',
+must tinyint(4) default NULL,
+PRIMARY KEY (gid),
+KEY gn (gn)
+) ;
+INSERT INTO t3 VALUES (1,'V1',NULL);
+CREATE TABLE t4 (
+uid bigint(20) unsigned NOT NULL default '0',
+gid bigint(20) unsigned default NULL,
+rid bigint(20) unsigned default NULL,
+cid bigint(20) unsigned default NULL,
+UNIQUE KEY m (uid,gid,rid,cid),
+KEY uid (uid),
+KEY rid (rid),
+KEY cid (cid),
+KEY container (gid,rid,cid)
+) ;
+INSERT INTO t4 VALUES (1,1,NULL,NULL);
+CREATE TABLE t5 (
+rid bigint(20) unsigned NOT NULL auto_increment,
+rl varchar(255) NOT NULL default '',
+PRIMARY KEY (rid),
+KEY rl (rl)
+) ;
+CREATE TABLE t6 (
+uid bigint(20) unsigned NOT NULL auto_increment,
+un varchar(250) NOT NULL default '',
+uc smallint(5) unsigned NOT NULL default '0',
+PRIMARY KEY (uid),
+UNIQUE KEY nc (un,uc),
+KEY un (un)
+) ;
+INSERT INTO t6 VALUES (1,'test',8);
+SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left join t5 on t5.rid = t4.rid left join t2 on t2.cid = t4.cid WHERE t3.gid=t4.gid AND t6.uid = t4.uid AND t6.uc = t1.cid AND t1.cv = "dummy" AND t6.un = "test";
+uid rl g1 cid gg
+1 NULL V1 NULL 1
+SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left join t5 on t5.rid = t4.rid left join t2 on t2.cid = t4.cid WHERE t3.gid=t4.gid AND t6.uid = t4.uid AND t3.must IS NOT NULL AND t6.uc = t1.cid AND t1.cv = "dummy" AND t6.un = "test";
+uid rl g1 cid gg
+(SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left join t5 on t5.rid = t4.rid left join t2 on t2.cid = t4.cid WHERE t3.gid=t4.gid AND t6.uid = t4.uid AND t3.must IS NOT NULL AND t6.uc = t1.cid AND t1.cv = "dummy" AND t6.un = "test") UNION (SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left join t5 on t5.rid = t4.rid left join t2 on t2.cid = t4.cid WHERE t3.gid=t4.gid AND t6.uid = t4.uid AND t6.uc = t1.cid AND t1.cv = "dummy" AND t6.un = "test");
+uid rl g1 cid gg
+1 NULL V1 NULL 1
+drop table t1,t2,t3,t4,t5,t6;
+CREATE TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
+CREATE TABLE t2 (a int not null, b char (10) not null);
+insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
+create table t3 select a,b from t1 union select a,b from t2;
+create table t4 (select a,b from t1) union (select a,b from t2) limit 2;
+insert into t4 select a,b from t1 union select a,b from t2;
+insert into t3 (select a,b from t1) union (select a,b from t2) limit 2;
+select * from t3;
+a b
+1 a
+2 b
+3 c
+4 d
+5 f
+6 e
+1 a
+2 b
+select * from t4;
+a b
+1 a
+2 b
+1 a
+2 b
+3 c
+4 d
+5 f
+6 e
+drop table t1,t2,t3,t4;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+create table t2 (a int);
+insert into t2 values (3),(4),(5);
+(SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2) LIMIT 1;
+a
+1
+select found_rows();
+found_rows()
+6
+(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2) LIMIT 2;
+a
+1
+3
+select found_rows();
+found_rows()
+4
+(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2);
+a
+1
+3
+4
+5
+select found_rows();
+found_rows()
+4
+(SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2 LIMIT 1);
+a
+1
+2
+3
+3
+select found_rows();
+found_rows()
+4
+(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION SELECT * FROM t2 LIMIT 1;
+a
+1
+select found_rows();
+found_rows()
+4
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION all SELECT * FROM t2 LIMIT 2;
+a
+1
+3
+select found_rows();
+found_rows()
+6
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION all SELECT * FROM t2 LIMIT 2;
+a
+1
+2
+select found_rows();
+found_rows()
+6
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2;
+a
+1
+2
+select found_rows();
+found_rows()
+6
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100;
+a
+1
+2
+3
+4
+5
+select found_rows();
+found_rows()
+6
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2;
+a
+1
+2
+3
+4
+5
+select found_rows();
+found_rows()
+5
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2;
+a
+1
+3
+4
+5
+select found_rows();
+found_rows()
+6
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2 LIMIT 2;
+a
+1
+3
+select found_rows();
+found_rows()
+6
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2,2;
+a
+3
+4
+select found_rows();
+found_rows()
+6
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2;
+a
+3
+4
+5
+select found_rows();
+found_rows()
+5
+SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a desc LIMIT 1;
+a
+5
+(SELECT * FROM t1 ORDER by a) UNION ALL (SELECT * FROM t2 ORDER BY a) ORDER BY A desc LIMIT 4;
+a
+5
+4
+3
+3
+(SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1;
+Wrong usage/placement of 'SQL_CALC_FOUND_ROWS'
+create temporary table t1 select a from t1 union select a from t2;
+create table t1 select a from t1 union select a from t2;
+INSERT TABLE 't1' isn't allowed in FROM table list
+drop table t1,t2;
+select length(version()) > 1 as `*` UNION select 2;
+*
+1
+2
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index bd34700e5ec..11aff8fe50a 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -1,3 +1,16 @@
+drop table if exists t1;
+create table t1 (a int auto_increment , primary key (a));
+insert into t1 values (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+update t1 set a=a+10 where a > 34;
+update t1 set a=a+100 where a > 0;
+update t1 set a=a+100 where a=1 and a=2;
+update t1 set a=b+100 where a=1 and a=2;
+Unknown column 'b' in 'field list'
+update t1 set a=b+100 where c=1 and a=2;
+Unknown column 'c' in 'where clause'
+update t1 set d=a+100 where a=1;
+Unknown column 'd' in 'field list'
+select * from t1;
a
101
102
@@ -35,7 +48,121 @@ a
134
145
146
+drop table t1;
+CREATE TABLE t1
+(
+place_id int (10) unsigned NOT NULL,
+shows int(10) unsigned DEFAULT '0' NOT NULL,
+ishows int(10) unsigned DEFAULT '0' NOT NULL,
+ushows int(10) unsigned DEFAULT '0' NOT NULL,
+clicks int(10) unsigned DEFAULT '0' NOT NULL,
+iclicks int(10) unsigned DEFAULT '0' NOT NULL,
+uclicks int(10) unsigned DEFAULT '0' NOT NULL,
+ts timestamp(14),
+PRIMARY KEY (place_id,ts)
+);
+INSERT INTO t1 (place_id,shows,ishows,ushows,clicks,iclicks,uclicks,ts)
+VALUES (1,0,0,0,0,0,0,20000928174434);
+UPDATE t1 SET shows=shows+1,ishows=ishows+1,ushows=ushows+1,clicks=clicks+1,iclicks=iclicks+1,uclicks=uclicks+1 WHERE place_id=1 AND ts>="2000-09-28 00:00:00";
+select place_id,shows from t1;
place_id shows
1 1
+drop table t1;
+CREATE TABLE t1 (
+lfdnr int(10) unsigned NOT NULL default '0',
+ticket int(10) unsigned NOT NULL default '0',
+client varchar(255) NOT NULL default '',
+replyto varchar(255) NOT NULL default '',
+subject varchar(100) NOT NULL default '',
+timestamp int(10) unsigned NOT NULL default '0',
+tstamp timestamp(14) NOT NULL,
+status int(3) NOT NULL default '0',
+type varchar(15) NOT NULL default '',
+assignment int(10) unsigned NOT NULL default '0',
+fupcount int(4) unsigned NOT NULL default '0',
+parent int(10) unsigned NOT NULL default '0',
+activity int(10) unsigned NOT NULL default '0',
+priority tinyint(1) unsigned NOT NULL default '1',
+cc varchar(255) NOT NULL default '',
+bcc varchar(255) NOT NULL default '',
+body text NOT NULL,
+comment text,
+header text,
+PRIMARY KEY (lfdnr),
+KEY k1 (timestamp),
+KEY k2 (type),
+KEY k3 (parent),
+KEY k4 (assignment),
+KEY ticket (ticket)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (773,773,'','','',980257344,20010318180652,0,'Open',10,0,0,0,1,'','','','','');
+alter table t1 change lfdnr lfdnr int(10) unsigned not null auto_increment;
+update t1 set status=1 where type='Open';
+select status from t1;
status
1
+drop table t1;
+create table t1 (a int not null, b int not null, key (a));
+insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3);
+SET @tmp=0;
+update t1 set b=(@tmp:=@tmp+1) order by a;
+update t1 set b=99 where a=1 order by b asc limit 1;
+select * from t1 order by a,b;
+a b
+1 2
+1 3
+1 99
+2 4
+2 5
+2 6
+3 7
+3 8
+3 9
+3 10
+3 11
+3 12
+update t1 set b=100 where a=1 order by b desc limit 2;
+update t1 set a=a+10+b where a=1 order by b;
+select * from t1 order by a,b;
+a b
+2 4
+2 5
+2 6
+3 7
+3 8
+3 9
+3 10
+3 11
+3 12
+13 2
+111 100
+111 100
+drop table t1;
+CREATE TABLE t1 (
+`id_param` smallint(3) unsigned NOT NULL default '0',
+`nom_option` char(40) NOT NULL default '',
+`valid` tinyint(1) NOT NULL default '0',
+KEY `id_param` (`id_param`,`nom_option`)
+) TYPE=MyISAM;
+INSERT INTO t1 (id_param,nom_option,valid) VALUES (185,'600x1200',1);
+UPDATE t1 SET nom_option='test' WHERE id_param=185 AND nom_option='600x1200' AND valid=1 LIMIT 1;
+select * from t1;
+id_param nom_option valid
+185 test 1
+drop table t1;
+create table t1 (F1 VARCHAR(30), F2 VARCHAR(30), F3 VARCHAR(30), cnt int, groupid int, KEY groupid_index (groupid));
+insert into t1 (F1,F2,F3,cnt,groupid) values ('0','0','0',1,6),
+('0','1','2',1,5), ('0','2','0',1,3), ('1','0','1',1,2),
+('1','2','1',1,1), ('1','2','2',1,1), ('2','0','1',2,4),
+('2','2','0',1,7);
+delete from t1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3);
+select * from t1;
+F1 F2 F3 cnt groupid
+0 0 0 1 6
+0 1 2 1 5
+0 2 0 1 3
+1 0 1 1 2
+1 2 1 1 1
+2 0 1 2 4
+2 2 0 1 7
+drop table t1;
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 8abdb40399a..3e83438b273 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -1,24 +1,118 @@
+set @a := foo;
+Unknown column 'foo' in 'field list'
+set @a := connection_id() + 3;
+select @a - connection_id();
@a - connection_id()
3
+drop table if exists t1,t2;
+CREATE TABLE t1 ( i int not null, v int not null,index (i));
+insert into t1 values (1,1),(1,3),(2,1);
+create table t2 (i int not null, unique (i));
+insert into t2 select distinct i from t1;
+select * from t2;
i
1
2
+select distinct t2.i,@vv1:=if(sv1.i,1,0),@vv2:=if(sv2.i,1,0),@vv3:=if(sv3.i,1,0), @vv1+@vv2+@vv3 from t2 left join t1 as sv1 on sv1.i=t2.i and sv1.v=1 left join t1 as sv2 on sv2.i=t2.i and sv2.v=2 left join t1 as sv3 on sv3.i=t2.i and sv3.v=3;
i @vv1:=if(sv1.i,1,0) @vv2:=if(sv2.i,1,0) @vv3:=if(sv3.i,1,0) @vv1+@vv2+@vv3
1 1 0 1 2
2 1 0 0 1
+explain select * from t1 where i=@vv1;
table type possible_keys key key_len ref rows Extra
-t1 ref i i 4 const 1 where used
+t1 ref i i 4 const 1 Using where
+explain select * from t1 where @vv1:=@vv1+1 and i=@vv1;
table type possible_keys key key_len ref rows Extra
-t1 ALL NULL NULL NULL NULL 3 where used
+t1 ALL NULL NULL NULL NULL 3 Using where
+explain select @vv1:=i from t1 where i=@vv1;
table type possible_keys key key_len ref rows Extra
-t1 index NULL i 4 NULL 3 where used; Using index
+t1 index NULL i 4 NULL 3 Using where; Using index
+explain select * from t1 where i=@vv1;
table type possible_keys key key_len ref rows Extra
-t1 ref i i 4 const 1 where used
+t1 ref i i 4 const 1 Using where
+drop table t1,t2;
+set @a=0,@b=0;
+select @a:=10, @b:=1, @a > @b, @a < @b;
@a:=10 @b:=1 @a > @b @a < @b
10 1 1 0
+select @a:="10", @b:="1", @a > @b, @a < @b;
@a:="10" @b:="1" @a > @b @a < @b
10 1 1 0
+select @a:=10, @b:=2, @a > @b, @a < @b;
@a:=10 @b:=2 @a > @b @a < @b
-10 2 1 0
-@a:="10" @b:="2" @a > @b @a < @b
10 2 0 1
+select @a:="10", @b:="2", @a > @b, @a < @b;
+@a:="10" @b:="2" @a > @b @a < @b
+10 2 1 0
+select @a:=1;
+@a:=1
+1
+select @a, @a:=1;
+@a @a:=1
+1 1
+create table t1 (id int, d double, c char(10));
+insert into t1 values (1,2.0, "test");
+select @c:=0;
+@c:=0
+0
+update t1 SET id=(@c:=@c+1);
+select @c;
+@c
+1
+select @c:=0;
+@c:=0
+0
+update t1 set id=(@c:=@c+1);
+select @c;
+@c
+1
+select @c:=0;
+@c:=0
+0
+select @c:=@c+1;
+@c:=@c+1
+1
+select @d,(@d:=id),@d from t1;
+@d (@d:=id) @d
+NULL 1 1
+select @e,(@e:=d),@e from t1;
+@e (@e:=d) @e
+NULL 2 2
+select @f,(@f:=c),@f from t1;
+@f (@f:=c) @f
+NULL test test
+set @g=1;
+select @g,(@g:=c),@g from t1;
+@g (@g:=c) @g
+1 test test
+select @c, @d, @e, @f;
+@c @d @e @f
+1 1 2 test
+select @d:=id, @e:=id, @f:=id, @g:=@id from t1;
+@d:=id @e:=id @f:=id @g:=@id
+1 1 1 NULL
+select @c, @d, @e, @f, @g;
+@c @d @e @f @g
+1 1 1 1 NULL
+drop table t1;
+select @a:=10, @b:=2, @a>@b, @a:="10", @b:="2", @a>@b, @a:=10, @b:=2, @a>@b, @a:="10", @b:="2", @a>@b;
+@a:=10 @b:=2 @a>@b @a:="10" @b:="2" @a>@b @a:=10 @b:=2 @a>@b @a:="10" @b:="2" @a>@b
+10 2 1 10 2 1 10 2 1 10 2 1
+create table t1 (i int not null);
+insert t1 values (1),(2),(2),(3),(3),(3);
+select @a:=0;
+@a:=0
+0
+select @a, @a:=@a+count(*), count(*), @a from t1 group by i;
+@a @a:=@a+count(*) count(*) @a
+0 1 1 0
+0 2 2 0
+0 3 3 0
+select @a:=0;
+@a:=0
+0
+select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i;
+@a+0 @a:=@a+0+count(*) count(*) @a+0
+0 1 1 0
+1 3 2 0
+3 6 3 0
+drop table t1;
diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result
index 62aeae21970..4eb34ebfd63 100644
--- a/mysql-test/r/varbinary.result
+++ b/mysql-test/r/varbinary.result
@@ -1,6 +1,26 @@
+select 0x41,0x41+0,0x41 | 0x7fffffffffffffff | 0,0xffffffffffffffff | 0 ;
0x41 0x41+0 0x41 | 0x7fffffffffffffff | 0 0xffffffffffffffff | 0
-A 65 9223372036854775807 -1
+A 65 9223372036854775807 18446744073709551615
+select 0x31+1,concat(0x31)+1,-0xf;
0x31+1 concat(0x31)+1 -0xf
50 2 -15
+select x'31',X'ffff'+0;
+x'31' X'ffff'+0
+1 65535
+drop table if exists t1;
+create table t1 (ID int(8) unsigned zerofill not null auto_increment,UNIQ bigint(21) unsigned zerofill not null,primary key (ID),unique (UNIQ) );
+insert into t1 set UNIQ=0x38afba1d73e6a18a;
+insert into t1 set UNIQ=123;
+explain select * from t1 where UNIQ=0x38afba1d73e6a18a;
table type possible_keys key key_len ref rows Extra
t1 const UNIQ UNIQ 8 const 1
+drop table t1;
+select x'hello';
+You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'x'hello'' at line 1
+select 0xfg;
+Unknown column '0xfg' in 'field list'
+create table t1 select 1 as x, 2 as xx;
+select x,xx from t1;
+x xx
+1 2
+drop table t1;
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index adf8100f052..b4a607cb174 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -1,33 +1,379 @@
+drop table if exists t1;
+set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
+select @test,@`select`,@TEST,@not_used;
@test @`select` @TEST @not_used
1 2 3 NULL
+set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
+select @test_int,@test_double,@test_string,@test_string2,@select;
@test_int @test_double @test_string @test_string2 @select
10 1e-10 abcdeghi abcdefghij NULL
+set @test_int="hello",@test_double="hello",@test_string="hello",@test_string2="hello";
+select @test_int,@test_double,@test_string,@test_string2;
@test_int @test_double @test_string @test_string2
hello hello hello hello
+set @test_int="hellohello",@test_double="hellohello",@test_string="hellohello",@test_string2="hellohello";
+select @test_int,@test_double,@test_string,@test_string2;
@test_int @test_double @test_string @test_string2
hellohello hellohello hellohello hellohello
+set @test_int=null,@test_double=null,@test_string=null,@test_string2=null;
+select @test_int,@test_double,@test_string,@test_string2;
@test_int @test_double @test_string @test_string2
NULL NULL NULL NULL
+select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
@t1:=(@t2:=1)+@t3:=4 @t1 @t2 @t3
5 5 1 4
+select @t5;
@t5
1.23456
+CREATE TABLE t1 (c_id INT(4) NOT NULL, c_name CHAR(20), c_country CHAR(3), PRIMARY KEY(c_id));
+INSERT INTO t1 VALUES (1,'Bozo','USA'),(2,'Ronald','USA'),(3,'Kinko','IRE'),(4,'Mr. Floppy','GB');
+SELECT @min_cid:=min(c_id), @max_cid:=max(c_id) from t1;
@min_cid:=min(c_id) @max_cid:=max(c_id)
1 4
+SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid;
c_id c_name c_country
1 Bozo USA
4 Mr. Floppy GB
+SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid OR c_id=666;
c_id c_name c_country
1 Bozo USA
4 Mr. Floppy GB
+ALTER TABLE t1 DROP PRIMARY KEY;
+select * from t1 where c_id=@min_cid OR c_id=@max_cid;
c_id c_name c_country
1 Bozo USA
4 Mr. Floppy GB
+drop table t1;
+set max_join_size=100;
+show variables like 'max_join_size';
+Variable_name Value
+max_join_size 100
+show global variables like 'max_join_size';
+Variable_name Value
+max_join_size HA_POS_ERROR
+set GLOBAL max_join_size=2000;
+show global variables like 'max_join_size';
+Variable_name Value
+max_join_size 2000
+set max_join_size=DEFAULT;
+show variables like 'max_join_size';
+Variable_name Value
+max_join_size 2000
+set GLOBAL max_join_size=DEFAULT;
+show global variables like 'max_join_size';
+Variable_name Value
+max_join_size HA_POS_ERROR
+set @@max_join_size=1000, @@global.max_join_size=2000;
+select @@local.max_join_size, @@global.max_join_size;
+@@session.max_join_size @@global.max_join_size
+1000 2000
+select @@identity, length(@@version)>0;
+@@identity length(@@version)>0
+0 1
+select @@VERSION=version();
@@VERSION=version()
1
+select last_insert_id(345);
last_insert_id(345)
345
-@@IDENTITY last_insert_id()
-345 345
-@@IDENTITY
-345
+select @@IDENTITY,last_insert_id(), @@identity;
+@@identity last_insert_id() @@identity
+345 345 345
+set big_tables=OFF, big_tables=ON, big_tables=0, big_tables=1, big_tables="OFF", big_tables="ON";
+set global concurrent_insert=ON;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert ON
+set global concurrent_insert=1;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert ON
+set global concurrent_insert=0;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert OFF
+set global concurrent_insert=OFF;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert OFF
+set global concurrent_insert=DEFAULT;
+show variables like 'concurrent_insert';
+Variable_name Value
+concurrent_insert ON
+set table_type=MYISAM, table_type="HEAP", global table_type="INNODB";
+show local variables like 'table_type';
+Variable_name Value
+table_type HEAP
+show global variables like 'table_type';
+Variable_name Value
+table_type INNODB
+set GLOBAL query_cache_size=100000;
+set GLOBAL myisam_max_sort_file_size=2000000;
+show global variables like 'myisam_max_sort_file_size';
+Variable_name Value
+myisam_max_sort_file_size 1048576
+set GLOBAL myisam_max_sort_file_size=default;
+show variables like 'myisam_max_sort_file_size';
+Variable_name Value
+myisam_max_sort_file_size FILE_SIZE
+set global net_retry_count=10, session net_retry_count=10;
+set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300;
+set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600;
+show global variables like 'net_%';
+Variable_name Value
+net_buffer_length 1024
+net_read_timeout 300
+net_retry_count 10
+net_write_timeout 200
+show session variables like 'net_%';
+Variable_name Value
+net_buffer_length 2048
+net_read_timeout 600
+net_retry_count 10
+net_write_timeout 500
+set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000;
+show global variables like 'net_%';
+Variable_name Value
+net_buffer_length 1024
+net_read_timeout 900
+net_retry_count 10
+net_write_timeout 1000
+show session variables like 'net_%';
+Variable_name Value
+net_buffer_length 7168
+net_read_timeout 600
+net_retry_count 10
+net_write_timeout 500
+set net_buffer_length=1;
+show variables like 'net_buffer_length';
+Variable_name Value
+net_buffer_length 1024
+set net_buffer_length=2000000000;
+show variables like 'net_buffer_length';
+Variable_name Value
+net_buffer_length 1048576
+set GLOBAL character set cp1251_koi8;
+show global variables like "convert_character_set";
+Variable_name Value
+convert_character_set cp1251_koi8
+set character set cp1251_koi8;
+show variables like "convert_character_set";
+Variable_name Value
+convert_character_set cp1251_koi8
+set global character set default, session character set default;
+show variables like "convert_character_set";
+Variable_name Value
+convert_character_set cp1251_koi8
+select @@timestamp>0;
+@@timestamp>0
+1
+set @@rand_seed1=10000000,@@rand_seed2=1000000;
+select ROUND(RAND(),5);
+ROUND(RAND(),5)
+0.02887
+show variables like '%alloc%';
+Variable_name Value
+query_alloc_block_size 8192
+query_prealloc_size 8192
+range_alloc_block_size 2048
+transaction_alloc_block_size 8192
+transaction_prealloc_size 4096
+set @@range_alloc_block_size=1024*16;
+set @@query_alloc_block_size=1024*17+2;
+set @@query_prealloc_size=1024*18;
+set @@transaction_alloc_block_size=1024*20-1;
+set @@transaction_prealloc_size=1024*21-1;
+select @@query_alloc_block_size;
+@@query_alloc_block_size
+17408
+show variables like '%alloc%';
+Variable_name Value
+query_alloc_block_size 17408
+query_prealloc_size 18432
+range_alloc_block_size 16384
+transaction_alloc_block_size 19456
+transaction_prealloc_size 20480
+set @@range_alloc_block_size=default;
+set @@query_alloc_block_size=default, @@query_prealloc_size=default;
+set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
+show variables like '%alloc%';
+Variable_name Value
+query_alloc_block_size 8192
+query_prealloc_size 8192
+range_alloc_block_size 2048
+transaction_alloc_block_size 8192
+transaction_prealloc_size 4096
+set big_tables=OFFF;
+Variable 'big_tables' can't be set to the value of 'OFFF'
+set big_tables="OFFF";
+Variable 'big_tables' can't be set to the value of 'OFFF'
+set unknown_variable=1;
+Unknown system variable 'unknown_variable'
+set max_join_size="hello";
+Wrong argument type to variable 'max_join_size'
+set table_type=UNKNOWN_TABLE_TYPE;
+Variable 'table_type' can't be set to the value of 'UNKNOWN_TABLE_TYPE'
+set table_type=INNODB, big_tables=2;
+Variable 'big_tables' can't be set to the value of '2'
+show local variables like 'table_type';
+Variable_name Value
+table_type HEAP
+set SESSION query_cache_size=10000;
+Variable 'query_cache_size' is a GLOBAL variable and should be set with SET GLOBAL
+set GLOBAL table_type=DEFAULT;
+Variable 'table_type' doesn't have a default value
+set convert_character_set=UNKNOWN_CHARACTER_SET;
+Unknown character set: 'UNKNOWN_CHARACTER_SET'
+set character set unknown;
+Unknown character set: 'unknown'
+set character set 0;
+Wrong argument type to variable 'convert_character_set'
+set global autocommit=1;
+Variable 'autocommit' is a LOCAL variable and can't be used with SET GLOBAL
+select @@global.timestamp;
+Variable 'timestamp' is a LOCAL variable
+set @@version='';
+Unknown system variable 'version'
+set @@concurrent_insert=1;
+Variable 'concurrent_insert' is a GLOBAL variable and should be set with SET GLOBAL
+set @@global.sql_auto_is_null=1;
+Variable 'sql_auto_is_null' is a LOCAL variable and can't be used with SET GLOBAL
+select @@global.sql_auto_is_null;
+Variable 'sql_auto_is_null' is a LOCAL variable
+set myisam_max_sort_file_size=100;
+Variable 'myisam_max_sort_file_size' is a GLOBAL variable and should be set with SET GLOBAL
+set myisam_max_extra_sort_file_size=100;
+Variable 'myisam_max_extra_sort_file_size' is a GLOBAL variable and should be set with SET GLOBAL
+set @@SQL_WARNINGS=NULL;
+Variable 'sql_warnings' can't be set to the value of 'NULL'
+set autocommit=1;
+set big_tables=1;
+select @@autocommit, @@big_tables;
+@@autocommit @@big_tables
+1 1
+set global binlog_cache_size=100;
+set bulk_insert_buffer_size=100;
+set convert_character_set=cp1251_koi8;
+set convert_character_set=default;
+set @@global.concurrent_insert=1;
+set global connect_timeout=100;
+select @@delay_key_write;
+@@delay_key_write
+ON
+set global delay_key_write="OFF";
+select @@delay_key_write;
+@@delay_key_write
+OFF
+set global delay_key_write=ALL;
+select @@delay_key_write;
+@@delay_key_write
+ALL
+set global delay_key_write=1;
+select @@delay_key_write;
+@@delay_key_write
+ON
+set global delayed_insert_limit=100;
+set global delayed_insert_timeout=100;
+set global delayed_queue_size=100;
+set global flush=1;
+set global flush_time=100;
+set insert_id=1;
+set interactive_timeout=100;
+set join_buffer_size=100;
+set last_insert_id=1;
+set global local_infile=1;
+set long_query_time=100;
+set low_priority_updates=1;
+set max_allowed_packet=100;
+set global max_binlog_cache_size=100;
+set global max_binlog_size=100;
+set global max_connect_errors=100;
+set global max_connections=100;
+set global max_delayed_threads=100;
+set max_heap_table_size=100;
+set max_join_size=100;
+set max_sort_length=100;
+set max_tmp_tables=100;
+set global max_user_connections=100;
+select @@max_user_connections;
+@@max_user_connections
+100
+set global max_write_lock_count=100;
+set global myisam_max_extra_sort_file_size=100;
+select @@myisam_max_extra_sort_file_size;
+@@myisam_max_extra_sort_file_size
+100
+set global myisam_max_sort_file_size=100;
+set myisam_sort_buffer_size=100;
+set net_buffer_length=100;
+set net_read_timeout=100;
+set net_write_timeout=100;
+set global query_cache_limit=100;
+set global query_cache_size=100;
+set global query_cache_type=demand;
+set read_buffer_size=100;
+set read_rnd_buffer_size=100;
+set global rpl_recovery_rank=100;
+set global server_id=100;
+set global slave_net_timeout=100;
+set global slow_launch_time=100;
+set sort_buffer_size=100;
+set sql_auto_is_null=1;
+select @@sql_auto_is_null;
+@@sql_auto_is_null
+1
+set @@sql_auto_is_null=0;
+select @@sql_auto_is_null;
+@@sql_auto_is_null
+0
+set sql_big_selects=1;
+set sql_big_tables=1;
+set sql_buffer_result=1;
+set sql_log_bin=1;
+set sql_log_off=1;
+set sql_log_update=1;
+set sql_low_priority_updates=1;
+set sql_max_join_size=200;
+select @@sql_max_join_size,@@max_join_size;
+@@sql_max_join_size @@max_join_size
+200 200
+set sql_quote_show_create=1;
+set sql_safe_updates=1;
+set sql_select_limit=1;
+set global sql_slave_skip_counter=100;
+set sql_warnings=1;
+set global table_cache=100;
+set table_type=myisam;
+set global thread_cache_size=100;
+set timestamp=1, timestamp=default;
+set tmp_table_size=100;
+set tx_isolation="READ-COMMITTED";
+set wait_timeout=100;
+set log_warnings=1;
+DROP TABLE IF EXISTS t1,t2;
+create table t1 (a int not null auto_increment, primary key(a));
+create table t2 (a int not null auto_increment, primary key(a));
+insert into t1 values(null),(null),(null);
+insert into t2 values(null),(null),(null);
+set global key_buffer_size=100000;
+select @@key_buffer_size;
+@@key_buffer_size
+98304
+select * from t1 where a=2;
+a
+2
+select * from t2 where a=3;
+a
+3
+check table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+drop table t1,t2;
+select @@xxxxxxxxxx;
+Unknown system variable 'xxxxxxxxxx'
+select 1;
+1
+1
+select @@session.key_buffer_size;
+Variable 'key_buffer_size' is a GLOBAL variable
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
new file mode 100644
index 00000000000..e5713718db0
--- /dev/null
+++ b/mysql-test/r/warnings.result
@@ -0,0 +1,10 @@
+drop table if exists t1;
+create table t1 (a int);
+insert into t1 values (1);
+insert into t1 values ("hej");
+insert into t1 values ("hej"),("då");
+set SQL_WARNINGS=1;
+insert into t1 values ("hej");
+insert into t1 values ("hej"),("då");
+drop table t1;
+set SQL_WARNINGS=0;
diff --git a/mysql-test/resolve-stack b/mysql-test/resolve-stack
new file mode 100755
index 00000000000..cdbe362c752
--- /dev/null
+++ b/mysql-test/resolve-stack
@@ -0,0 +1,8 @@
+#! /bin/sh
+# A shortcut for resolving stacks when debugging when
+# we cannot duplicate the crash in a debugger and have to
+# resort to using stack traces
+
+nm --numeric-sort ../sql/mysqld > var/tmp/mysqld.sym
+echo "Please type or paste the numeric stack trace,Ctrl-C to quit:"
+../extra/resolve_stack_dump -s var/tmp/mysqld.sym
diff --git a/mysql-test/std_data/des_key_file b/mysql-test/std_data/des_key_file
new file mode 100644
index 00000000000..fa53802d449
--- /dev/null
+++ b/mysql-test/std_data/des_key_file
@@ -0,0 +1,4 @@
+5 default_password
+1 password1
+4 password4
+2 password2
diff --git a/mysql-test/std_data/gemini.dat b/mysql-test/std_data/gemini.dat
deleted file mode 100644
index c2e1045f5ac..00000000000
--- a/mysql-test/std_data/gemini.dat
+++ /dev/null
@@ -1,5 +0,0 @@
-65,-1,1
-379,-1,1
-468,-1,1
-469,-1,1
-508,-1,1
diff --git a/mysql-test/std_data/init_file.dat b/mysql-test/std_data/init_file.dat
new file mode 100644
index 00000000000..4236ada1142
--- /dev/null
+++ b/mysql-test/std_data/init_file.dat
@@ -0,0 +1 @@
+select * from mysql.user as t1, mysql.user as t2, mysql.user as t3, mysql.user as t4, mysql.user as t5, mysql.user as t6, mysql.user as t7, mysql.user as t8; \ No newline at end of file
diff --git a/mysql-test/std_data/loaddata1.dat b/mysql-test/std_data/loaddata1.dat
new file mode 100644
index 00000000000..c9e8549b211
--- /dev/null
+++ b/mysql-test/std_data/loaddata1.dat
@@ -0,0 +1,3 @@
+,\N,NULL,,
+00,0,000000,,
+2003-03-03, 20030303,030303,\N
diff --git a/mysql-test/std_data/loaddata2.dat b/mysql-test/std_data/loaddata2.dat
new file mode 100644
index 00000000000..6e9d6745b8d
--- /dev/null
+++ b/mysql-test/std_data/loaddata2.dat
@@ -0,0 +1,5 @@
+Field A,'Field B'
+Field 1,'Field 2'
+Field 3,'Field 4'
+'Field 5' ,'Field 6'
+Field 6, 'Field 7'
diff --git a/mysql-test/std_data/loaddata3.dat b/mysql-test/std_data/loaddata3.dat
new file mode 100644
index 00000000000..4c82f1396c5
--- /dev/null
+++ b/mysql-test/std_data/loaddata3.dat
@@ -0,0 +1,6 @@
+number row data
+1 row 1
+2 row 2
+error 12345678901234567890123456789012345678901234567890
+3 row 3
+wrong end 12345678901234567890123456789012345678901234567890
diff --git a/mysql-test/std_data/loaddata4.dat b/mysql-test/std_data/loaddata4.dat
new file mode 100644
index 00000000000..9c0d744438c
--- /dev/null
+++ b/mysql-test/std_data/loaddata4.dat
@@ -0,0 +1 @@
+test row data 1 row 1 2 row 2 3 row 3
diff --git a/mysql-test/std_data/master-bin.001 b/mysql-test/std_data/master-bin.001
index fa30d8e5302..2ec2397acdd 100644
--- a/mysql-test/std_data/master-bin.001
+++ b/mysql-test/std_data/master-bin.001
Binary files differ
diff --git a/mysql-test/std_data/rpl_loaddata.dat b/mysql-test/std_data/rpl_loaddata.dat
new file mode 100644
index 00000000000..a70a059c2ab
--- /dev/null
+++ b/mysql-test/std_data/rpl_loaddata.dat
@@ -0,0 +1,2 @@
+\N 10
+\N 15
diff --git a/mysql-test/std_data/rpl_loaddata2.dat b/mysql-test/std_data/rpl_loaddata2.dat
new file mode 100644
index 00000000000..04d84f1f45e
--- /dev/null
+++ b/mysql-test/std_data/rpl_loaddata2.dat
@@ -0,0 +1,8 @@
+>2003-01-21,6328,%a%,%aaaaa%
+##
+>2003-02-22,2461,b,%a a a @@ @% @b ' " a%
+##
+>2003-03-22,2161,%c%,%asdf%
+##
+>2003-03-22,2416,%a%,%bbbbb%
+##
diff --git a/mysql-test/std_data/trunc_binlog.001 b/mysql-test/std_data/trunc_binlog.001
new file mode 100644
index 00000000000..2c2b4ec6ce4
--- /dev/null
+++ b/mysql-test/std_data/trunc_binlog.001
Binary files differ
diff --git a/mysql-test/std_data/words.dat b/mysql-test/std_data/words.dat
index c2d1cb70cbf..1b28624e354 100644
--- a/mysql-test/std_data/words.dat
+++ b/mysql-test/std_data/words.dat
@@ -8,3 +8,63 @@ abandoned
abandoning
abandonment
abandons
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
diff --git a/mysql-test/t/alias.test b/mysql-test/t/alias.test
index 5c6813d93aa..57b46181fa1 100644
--- a/mysql-test/t/alias.test
+++ b/mysql-test/t/alias.test
@@ -62,3 +62,24 @@ INSERT INTO t1 VALUES (3359362,406,3359362,'Mustermann Musterfrau',7001,'2000-05
SELECT ELT(FIELD(kundentyp,'PP','PPA','PG','PGA','FK','FKA','FP','FPA','K','KA','V','VA',''), 'Privat (Private Nutzung)','Privat (Private Nutzung) Sitz im Ausland','Privat (geschaeftliche Nutzung)','Privat (geschaeftliche Nutzung) Sitz im Ausland','Firma (Kapitalgesellschaft)','Firma (Kapitalgesellschaft) Sitz im Ausland','Firma (Personengesellschaft)','Firma (Personengesellschaft) Sitz im Ausland','oeff. rechtl. Koerperschaft','oeff. rechtl. Koerperschaft Sitz im Ausland','Eingetragener Verein','Eingetragener Verein Sitz im Ausland','Typ unbekannt') AS Kundentyp ,kategorie FROM t1 WHERE hdl_nr < 2000000 AND kategorie IN ('Prepaid','Mobilfunk') AND st_klasse = 'Workflow' GROUP BY kundentyp ORDER BY kategorie;
drop table t1;
+
+#
+# test case for #570
+#
+
+CREATE TABLE t1 (
+ AUFNR varchar(12) NOT NULL default '',
+ PLNFL varchar(6) NOT NULL default '',
+ VORNR varchar(4) NOT NULL default '',
+ xstatus_vor smallint(5) unsigned NOT NULL default '0',
+
+);
+
+INSERT INTO t1 VALUES ('40004712','000001','0010',9);
+INSERT INTO t1 VALUES ('40004712','000001','0020',0);
+
+UPDATE t1 SET t1.xstatus_vor = Greatest(t1.xstatus_vor,1) WHERE t1.aufnr =
+"40004712" AND t1.plnfl = "000001" AND t1.vornr > "0010" ORDER BY t1.vornr
+ASC LIMIT 1;
+
+drop table t1;
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index cfb4f958372..1937cdbe985 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -2,7 +2,7 @@
# Test of alter table
#
-drop table if exists t1;
+drop table if exists t1,t2;
create table t1 (
col1 int not null auto_increment primary key,
col2 varchar(30) not null,
@@ -10,10 +10,14 @@ col3 varchar (20) not null,
col4 varchar(4) not null,
col5 enum('PENDING', 'ACTIVE', 'DISABLED') not null,
col6 int not null, to_be_deleted int);
+insert into t1 values (2,4,3,5,"PENDING",1,7);
alter table t1
add column col4_5 varchar(20) not null after col4,
-add column col7 varchar(30) not null after col6,
-add column col8 datetime not null, drop column to_be_deleted;
+add column col7 varchar(30) not null after col5,
+add column col8 datetime not null, drop column to_be_deleted,
+change column col2 fourth varchar(30) not null after col3,
+modify column col6 int not null first;
+select * from t1;
drop table t1;
create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
@@ -73,6 +77,28 @@ OPTIMIZE TABLE t1;
DROP TABLE t1;
#
+# ALTER TABLE ... ENABLE/DISABLE KEYS
+
+create table t1 (n1 int not null, n2 int, n3 int, n4 float,
+ unique(n1),
+ key (n1, n2, n3, n4),
+ key (n2, n3, n4, n1),
+ key (n3, n4, n1, n2),
+ key (n4, n1, n2, n3) );
+alter table t1 disable keys;
+show keys from t1;
+#let $1=10000;
+let $1=10;
+while ($1)
+{
+ eval insert into t1 values($1,RAND()*1000,RAND()*1000,RAND());
+ dec $1;
+}
+alter table t1 enable keys;
+show keys from t1;
+drop table t1;
+
+#
# Drop and add an auto_increment column
#
@@ -83,6 +109,102 @@ select * from t1;
drop table t1;
#
+# Alter table and rename
+#
+
+create table t1 (i int unsigned not null auto_increment primary key);
+alter table t1 rename t2;
+alter table t2 rename t1, add c char(10) comment "no comment";
+show columns from t1;
+drop table t1;
+
+# implicit analyze
+
+create table t1 (a int, b int);
+let $1=100;
+while ($1)
+{
+ eval insert into t1 values(1,$1), (2,$1), (3, $1);
+ dec $1;
+}
+alter table t1 add unique (a,b), add key (b);
+show keys from t1;
+analyze table t1;
+show keys from t1;
+drop table t1;
+
+#
+# Test of ALTER TABLE DELAYED
+#
+
+CREATE TABLE t1 (i int(10), index(i) );
+ALTER TABLE t1 DISABLE KEYS;
+INSERT DELAYED INTO t1 VALUES(1),(2),(3);
+ALTER TABLE t1 ENABLE KEYS;
+drop table t1;
+
+#
+# Test ALTER TABLE ENABLE/DISABLE keys when things are locked
+#
+
+CREATE TABLE t1 (
+ Host varchar(16) binary NOT NULL default '',
+ User varchar(16) binary NOT NULL default '',
+ PRIMARY KEY (Host,User)
+) TYPE=MyISAM;
+
+ALTER TABLE t1 DISABLE KEYS;
+LOCK TABLES t1 WRITE;
+INSERT INTO t1 VALUES ('localhost','root'),('localhost',''),('games','monty');
+SHOW INDEX FROM t1;
+ALTER TABLE t1 ENABLE KEYS;
+UNLOCK TABLES;
+CHECK TABLES t1;
+DROP TABLE t1;
+
+#
+# Test with two keys
+#
+
+CREATE TABLE t1 (
+ Host varchar(16) binary NOT NULL default '',
+ User varchar(16) binary NOT NULL default '',
+ PRIMARY KEY (Host,User),
+ KEY (Host)
+) TYPE=MyISAM;
+
+ALTER TABLE t1 DISABLE KEYS;
+SHOW INDEX FROM t1;
+LOCK TABLES t1 WRITE;
+INSERT INTO t1 VALUES ('localhost','root'),('localhost','');
+SHOW INDEX FROM t1;
+ALTER TABLE t1 ENABLE KEYS;
+SHOW INDEX FROM t1;
+UNLOCK TABLES;
+CHECK TABLES t1;
+
+# Test RENAME with LOCK TABLES
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1 RENAME t2;
+UNLOCK TABLES;
+select * from t2;
+DROP TABLE t2;
+
+#
+# Test disable keys with locking
+#
+CREATE TABLE t1 (
+ Host varchar(16) binary NOT NULL default '',
+ User varchar(16) binary NOT NULL default '',
+ PRIMARY KEY (Host,User),
+ KEY (Host)
+) TYPE=MyISAM;
+
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1 DISABLE KEYS;
+SHOW INDEX FROM t1;
+DROP TABLE t1;
+#
# Bug #2628: 'alter table t1 rename mysqltest.t1' silently drops mysqltest.t1
# if it exists
#
diff --git a/mysql-test/t/analyse.test b/mysql-test/t/analyse.test
index a937318aa6c..9bf737c9515 100644
--- a/mysql-test/t/analyse.test
+++ b/mysql-test/t/analyse.test
@@ -2,6 +2,7 @@
# Test of procedure analyse
#
+drop table if exists t1,t2;
create table t1 (i int, j int, empty_string char(10), bool char(1), d date);
insert into t1 values (1,2,"","Y","2002-03-03"), (3,4,"","N","2002-03-04"), (5,6,"","Y","2002-03-04"), (7,8,"","N","2002-03-05");
select * from t1 procedure analyse();
@@ -9,3 +10,4 @@ select * from t1 procedure analyse(2);
create table t2 select * from t1 procedure analyse();
select * from t2;
drop table t1,t2;
+
diff --git a/mysql-test/t/ansi-master.opt b/mysql-test/t/ansi-master.opt
new file mode 100644
index 00000000000..6bf7a4f30e2
--- /dev/null
+++ b/mysql-test/t/ansi-master.opt
@@ -0,0 +1 @@
+--ansi
diff --git a/mysql-test/t/ansi.test b/mysql-test/t/ansi.test
new file mode 100644
index 00000000000..e1ac8ffd4f9
--- /dev/null
+++ b/mysql-test/t/ansi.test
@@ -0,0 +1,17 @@
+#
+# Test of ansi mode
+#
+
+drop table if exists t1;
+
+# Test some functions that works different in ansi mode
+
+SELECT 'A' || 'B';
+
+# Test GROUP BY behaviour
+
+CREATE TABLE t1 (id INT, id2 int);
+SELECT id,NULL,1,1.1,'a' FROM t1 GROUP BY id;
+--error 1055
+SELECT id FROM t1 GROUP BY id2;
+drop table t1;
diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test
index b9b8c244699..c26983b5eec 100644
--- a/mysql-test/t/auto_increment.test
+++ b/mysql-test/t/auto_increment.test
@@ -2,6 +2,7 @@
# Test of auto_increment; The test for BDB tables is in bdb.test
#
+drop table if exists t1;
create table t1 (a int not null auto_increment,b int, primary key (a)) type=myisam auto_increment=3;
insert into t1 values (1,1),(NULL,3),(NULL,4);
delete from t1 where a=4;
@@ -18,20 +19,6 @@ insert into t1 values (NULL,9,9);
select * from t1;
drop table t1;
-create table t1 (a int not null auto_increment,b int, primary key (a)) type=isam;
-insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4);
-delete from t1 where a=4 or a=2;
-insert into t1 values (NULL,4),(NULL,5),(6,6);
-select * from t1;
-delete from t1 where a=6;
-#show table status like "t1";
-replace t1 values (3,1);
-replace t1 values (3,3);
-ALTER TABLE t1 add c int;
-insert into t1 values (NULL,6,6);
-select * from t1;
-drop table t1;
-
create table t1 (
skey tinyint unsigned NOT NULL auto_increment PRIMARY KEY,
sval char(20)
@@ -65,6 +52,13 @@ insert into t1 values (NULL,'sdj'),(NULL,'sdj'),(NULL,"abc"),(NULL,'abc'),(NULL,
select * from t1;
drop table t1;
+create table t1 (sid char(5), id int(2) NOT NULL auto_increment, key(sid, id));
+create table t2 (sid char(20), id int(2));
+insert into t2 values ('skr',NULL),('skr',NULL),('test',NULL);
+insert into t1 select * from t2;
+select * from t1;
+drop table t1,t2;
+
#
# Test of auto_increment columns when they are set to 0
#
@@ -75,3 +69,23 @@ update t1 set a=0;
select * from t1;
check table t1;
drop table t1;
+
+#
+# Test negative values (Bug #1366)
+#
+
+create table t1 (a int not null auto_increment primary key);
+insert into t1 values (NULL);
+insert into t1 values (-1);
+select last_insert_id();
+insert into t1 values (NULL);
+select * from t1;
+drop table t1;
+
+create table t1 (a int not null auto_increment primary key) /*!40102 type=heap */;
+insert into t1 values (NULL);
+insert into t1 values (-1);
+select last_insert_id();
+insert into t1 values (NULL);
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/backup.test b/mysql-test/t/backup.test
index e4d5be00445..650b85477f5 100644
--- a/mysql-test/t/backup.test
+++ b/mysql-test/t/backup.test
@@ -6,12 +6,11 @@ connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
connection con1;
set SQL_LOG_BIN=0;
-drop table if exists t1,t2,t3,t4;
create table t4(n int);
---replace_result "errno: 2" "errno: X" "errno: 22" "errno: X" "errno: 23" "errno: X"
+--replace_result "errno: 1" "errno: X" "errno: 2" "errno: X" "errno: 22" "errno: X" "errno: 23" "errno: X"
backup table t4 to '../bogus';
backup table t4 to '../tmp';
---replace_result "errno: 17" "errno: X"
+--replace_result "errno: 7" "errno: X" "errno: 17" "errno: X"
backup table t4 to '../tmp';
drop table t4;
restore table t4 from '../tmp';
diff --git a/mysql-test/t/bdb-alter-table-1.test b/mysql-test/t/bdb-alter-table-1.test
index 25a86cd92f6..5861c2fe0bf 100644
--- a/mysql-test/t/bdb-alter-table-1.test
+++ b/mysql-test/t/bdb-alter-table-1.test
@@ -1,8 +1,7 @@
--- source include/have_bdb.inc
-
#
-# Small basic test for ALTER TABLE bug ..
+# Test of problem when shutting down mysqld at once after ALTER TABLE
#
+-- source include/have_bdb.inc
drop table if exists t1;
create table t1(objid BIGINT not null, tablename varchar(64), oid BIGINT not null, test BIGINT, PRIMARY KEY (objid), UNIQUE(tablename)) type=BDB;
insert into t1 values(1, 't1',4,9);
@@ -10,3 +9,5 @@ insert into t1 values(2, 'metatable',1,9);
insert into t1 values(3, 'metaindex',1,9 );
select * from t1;
alter table t1 drop column test;
+
+# Now we do a reboot and continue with the next test
diff --git a/mysql-test/t/bdb-alter-table-2-master.opt b/mysql-test/t/bdb-alter-table-2-master.opt
new file mode 100644
index 00000000000..15ad73c500f
--- /dev/null
+++ b/mysql-test/t/bdb-alter-table-2-master.opt
@@ -0,0 +1,2 @@
+--skip-external-locking
+
diff --git a/mysql-test/t/bdb-alter-table-2.test b/mysql-test/t/bdb-alter-table-2.test
index 69ff04ee24a..a474efe42e1 100644
--- a/mysql-test/t/bdb-alter-table-2.test
+++ b/mysql-test/t/bdb-alter-table-2.test
@@ -1,3 +1,8 @@
+#
+# Note that this test uses tables from the previous test
+# This is to test that the table t1 survives a reboot of MySQL
+# The options in the -master.opt file are just there to force the reboot
+#
-- source include/have_bdb.inc
select * from t1;
-drop table t1; \ No newline at end of file
+drop table t1;
diff --git a/mysql-test/t/bdb-crash.test b/mysql-test/t/bdb-crash.test
index 0005b631a46..4575a612728 100644
--- a/mysql-test/t/bdb-crash.test
+++ b/mysql-test/t/bdb-crash.test
@@ -4,7 +4,7 @@
drop table if exists t1;
CREATE TABLE t1 (
- ChargeID int(10) unsigned DEFAULT '0' NOT NULL auto_increment,
+ ChargeID int(10) unsigned NOT NULL auto_increment,
ServiceID int(10) unsigned DEFAULT '0' NOT NULL,
ChargeDate date DEFAULT '0000-00-00' NOT NULL,
ChargeAmount decimal(20,2) DEFAULT '0.00' NOT NULL,
diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test
index 50698bb8df6..4b490052535 100644
--- a/mysql-test/t/bdb.test
+++ b/mysql-test/t/bdb.test
@@ -39,7 +39,7 @@ select * from t1;
update ignore t1 set id=id+1; # This will change all rows
select * from t1;
update ignore t1 set id=1023 where id=1010;
-select * from t1 where parent_id=102;
+select * from t1 where parent_id=102 order by parent_id,id;
explain select level from t1 where level=1;
explain select level,id from t1 where level=1;
explain select level,id,parent_id from t1 where level=1;
@@ -767,3 +767,65 @@ select INFO_NOTE from t1 where STR_DATE = '20010610';
select INFO_NOTE from t1 where STR_DATE < '20010610';
select INFO_NOTE from t1 where STR_DATE > '20010610';
drop table t1;
+
+#
+# Test problem with multi table delete which quickly shows up with bdb tables.
+#
+
+create table t1 (a int not null, b int, primary key (a)) type =bdb;
+create table t2 (a int not null, b int, primary key (a)) type =bdb;
+insert into t1 values (2, 3),(1, 7),(10, 7);
+insert into t2 values (2, 3),(1, 7),(10, 7);
+select * from t1;
+select * from t2;
+delete t1, t2 from t1, t2 where t1.a = t2.a;
+select * from t1;
+select * from t2;
+select * from t2;
+drop table t1,t2;
+
+#
+# The bug #971
+#
+
+create table t1 (x int not null, index(x)) type=bdb;
+insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+select * from t1 where x <= 10 and x >= 7;
+select * from t1 where x <= 10 and x >= 7 order by x;
+select * from t1 where x <= 10 and x >= 7 order by x desc;
+select * from t1 where x <= 8 and x >= 5 order by x desc;
+select * from t1 where x < 8 and x > 5 order by x desc;
+drop table t1;
+
+#
+# Test of multi-table-updates (bug #1980).
+#
+
+create table t1 ( c char(8) not null ) type=bdb;
+insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9');
+insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F');
+
+alter table t1 add b char(8) not null;
+alter table t1 add a char(8) not null;
+alter table t1 add primary key (a,b,c);
+update t1 set a=c, b=c;
+
+create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=bdb;
+insert into t2 select * from t1;
+
+delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
+drop table t1,t2;
+
+#
+# Test index only read (Bug #2509)
+#
+create table t1 (a char(10), key(a), b int not null, key(b)) engine=bdb;
+insert into t1 values ('a',1),('A',2);
+explain select a from t1;
+select a from t1;
+explain select b from t1;
+select b from t1;
+alter table t1 modify a char(10) binary;
+explain select a from t1;
+select a from t1;
+drop table t1;
diff --git a/mysql-test/t/bdb_cache-master.opt b/mysql-test/t/bdb_cache-master.opt
new file mode 100644
index 00000000000..5f0ebff98f6
--- /dev/null
+++ b/mysql-test/t/bdb_cache-master.opt
@@ -0,0 +1 @@
+--set-variable=query_cache_size=1M
diff --git a/mysql-test/t/bdb_cache.test b/mysql-test/t/bdb_cache.test
new file mode 100644
index 00000000000..aa5572886c5
--- /dev/null
+++ b/mysql-test/t/bdb_cache.test
@@ -0,0 +1,50 @@
+-- source include/have_bdb.inc
+-- source include/have_query_cache.inc
+
+#
+# Without auto_commit.
+#
+drop table if exists t1, t2, t3;
+flush status;
+set autocommit=0;
+create table t1 (a int not null) type=bdb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+commit;
+set autocommit=1;
+begin;
+create table t1 (a int not null) type=bdb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+commit;
+create table t1 (a int not null) type=bdb;
+create table t2 (a int not null) type=bdb;
+create table t3 (a int not null) type=bdb;
+insert into t1 values (1),(2);
+insert into t2 values (1),(2);
+insert into t3 values (1),(2);
+select * from t1;
+select * from t2;
+select * from t3;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+begin;
+select * from t1;
+select * from t2;
+select * from t3;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+insert into t1 values (3);
+insert into t2 values (3);
+insert into t1 values (4);
+select * from t1;
+select * from t2;
+select * from t3;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+commit;
+show status like "Qcache_queries_in_cache"; \ No newline at end of file
diff --git a/mysql-test/t/bench_count_distinct.test b/mysql-test/t/bench_count_distinct.test
index 62d456a3cf8..9059428bea4 100644
--- a/mysql-test/t/bench_count_distinct.test
+++ b/mysql-test/t/bench_count_distinct.test
@@ -1,12 +1,13 @@
drop table if exists t1;
create table t1(n int not null, key(n)) delay_key_write = 1;
let $1=100;
+disable_query_log;
while ($1)
{
eval insert into t1 values($1);
eval insert into t1 values($1);
dec $1;
}
-
+enable_query_log;
select count(distinct n) from t1;
drop table t1;
diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test
index f7437d77c36..353e9fd44b1 100644
--- a/mysql-test/t/bigint.test
+++ b/mysql-test/t/bigint.test
@@ -4,7 +4,8 @@
select 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296;
select 9223372036854775807,-009223372036854775808;
select +9999999999999999999,-9999999999999999999;
-
+select cast(9223372036854775808 as unsigned)+1;
+select 9223372036854775808+1;
#
# In 3.23 we have to disable the test of column to bigint as
# this fails on AIX powerpc (the resolution for double is not good enough)
@@ -13,10 +14,52 @@ select +9999999999999999999,-9999999999999999999;
drop table if exists t1;
create table t1 (a bigint unsigned not null, primary key(a));
-insert into t1 values (18446744073709551615), (0xFFFFFFFFFFFFFFFE);
+insert into t1 values (18446744073709551615), (0xFFFFFFFFFFFFFFFE), (18446744073709551613), (18446744073709551612);
select * from t1;
select * from t1 where a=18446744073709551615;
-select * from t1 where a='18446744073709551615';
+# select * from t1 where a='18446744073709551615';
delete from t1 where a=18446744073709551615;
select * from t1;
drop table t1;
+
+create table t1 ( a int not null default 1, big bigint );
+insert into t1 (big) values (-1),(12345678901234567),(9223372036854775807),(18446744073709551615);
+select min(big),max(big),max(big)-1 from t1;
+select min(big),max(big),max(big)-1 from t1 group by a;
+alter table t1 modify big bigint unsigned not null;
+select min(big),max(big),max(big)-1 from t1;
+select min(big),max(big),max(big)-1 from t1 group by a;
+alter table t1 add key (big);
+select min(big),max(big),max(big)-1 from t1;
+select min(big),max(big),max(big)-1 from t1 group by a;
+alter table t1 modify big bigint not null;
+select min(big),max(big),max(big)-1 from t1;
+select min(big),max(big),max(big)-1 from t1 group by a;
+drop table t1;
+
+#
+# Test problem with big values fir auto_increment
+#
+
+create table t1 (id bigint auto_increment primary key, a int) auto_increment=9999999999;
+insert into t1 values (null,1);
+select * from t1;
+select * from t1 limit 9999999999;
+drop table t1;
+
+#
+# Item_uint::save_to_field()
+# BUG#1845
+# This can't be fixed in MySQL 4.0 without loosing precisions for bigints
+#
+
+CREATE TABLE t1 ( quantity decimal(60,0));
+insert into t1 values (10000000000000000000);
+insert into t1 values (10000000000000000000.0);
+insert into t1 values ('10000000000000000000');
+select * from t1;
+drop table t1;
+
+# atof() behaviour is different of different systems. to be fixed in 4.1
+#SELECT '0x8000000000000001'+0;
+
diff --git a/mysql-test/t/binary.test b/mysql-test/t/binary.test
index ef4249c39f8..95815cda60f 100644
--- a/mysql-test/t/binary.test
+++ b/mysql-test/t/binary.test
@@ -2,6 +2,7 @@
# test sort,min and max on binary fields
#
+drop table if exists t1,t2;
create table t1 (name char(20) not null, primary key (name));
create table t2 (name char(20) binary not null, primary key (name));
insert into t1 values ("å");
@@ -25,11 +26,18 @@ drop table t1,t2;
# Test of binary and normal strings
#
-create table t1 (a char(10) not null, b char(10) binary not null,index (a));
+create table t1 (a char(10) not null, b char(10) binary not null,key (a), key(b));
insert into t1 values ("hello ","hello "),("hello2 ","hello2 ");
+select * from t1 where a="hello";
select * from t1 where a="hello ";
-select * from t1 where b="hello ";
+select * from t1 ignore index (a) where a="hello ";
select * from t1 where b="hello";
+select * from t1 where b="hello ";
+select * from t1 ignore index (b) where b="hello ";
+# blob test
+alter table t1 modify b tinytext not null, drop key b, add key (b(100));
+select * from t1 where b="hello ";
+select * from t1 ignore index (b) where b="hello ";
drop table t1;
#
diff --git a/mysql-test/t/bool.test b/mysql-test/t/bool.test
new file mode 100644
index 00000000000..10f97fefb73
--- /dev/null
+++ b/mysql-test/t/bool.test
@@ -0,0 +1,51 @@
+#
+# Test of boolean operations with NULL
+#
+
+DROP TABLE IF EXISTS t1;
+
+SELECT IF(NULL AND 1, 1, 2), IF(1 AND NULL, 1, 2);
+SELECT NULL AND 1, 1 AND NULL, 0 AND NULL, NULL and 0;
+
+create table t1 (a int);
+insert into t1 values (0),(1),(NULL);
+SELECT * FROM t1 WHERE IF(a AND 1, 0, 1);
+SELECT * FROM t1 WHERE IF(1 AND a, 0, 1);
+SELECT * FROM t1 where NOT(a AND 1);
+SELECT * FROM t1 where NOT(1 AND a);
+SELECT * FROM t1 where (a AND 1)=0;
+SELECT * FROM t1 where (1 AND a)=0;
+SELECT * FROM t1 where (1 AND a)=1;
+SELECT * FROM t1 where (1 AND a) IS NULL;
+
+# Verify that NULL optimisation works in AND clause:
+SET @a=0, @b=0;
+SELECT * FROM t1 WHERE NULL AND (@a:=@a+1);
+SELECT * FROM t1 WHERE NOT(a>=0 AND NULL AND (@b:=@b+1));
+SELECT * FROM t1 WHERE a=2 OR (NULL AND (@a:=@a+1));
+SELECT * FROM t1 WHERE NOT(a=2 OR (NULL AND (@b:=@b+1)));
+SELECT @a, @b;
+DROP TABLE t1;
+
+
+# Test boolean operators in select part
+# NULLs are represented as N for readability
+# Read nA as !A, AB as A && B, AoB as A || B
+# Result table makes ANSI happy
+
+drop table if exists t;
+create table t(a int, b int);
+insert into t values(null, null), (0, null), (1, null), (null, 0), (null, 1), (0, 0), (0, 1), (1, 0), (1, 1);
+
+# Below test is valid untill we have True/False implemented as 1/0
+# To comply to all rules it must show that: n(AB) = nAonB, n(AoB) = nAnB
+
+select ifnull(A, 'N') as A, ifnull(B, 'N') as B, ifnull(not A, 'N') as nA, ifnull(not B, 'N') as nB, ifnull(A and B, 'N') as AB, ifnull(not (A and B), 'N') as `n(AB)`, ifnull((not A or not B), 'N') as nAonB, ifnull(A or B, 'N') as AoB, ifnull(not(A or B), 'N') as `n(AoB)`, ifnull(not A and not B, 'N') as nAnB from t;
+
+# This should work with any internal representation of True/False
+# Result must be same as above
+
+select ifnull(A=1, 'N') as A, ifnull(B=1, 'N') as B, ifnull(not (A=1), 'N') as nA, ifnull(not (B=1), 'N') as nB, ifnull((A=1) and (B=1), 'N') as AB, ifnull(not ((A=1) and (B=1)), 'N') as `n(AB)`, ifnull((not (A=1) or not (B=1)), 'N') as nAonB, ifnull((A=1) or (B=1), 'N') as AoB, ifnull(not((A=1) or (B=1)), 'N') as `n(AoB)`, ifnull(not (A=1) and not (B=1), 'N') as nAnB from t;
+
+
+drop table t;
diff --git a/mysql-test/t/bulk_replace.test b/mysql-test/t/bulk_replace.test
new file mode 100644
index 00000000000..d366004c16f
--- /dev/null
+++ b/mysql-test/t/bulk_replace.test
@@ -0,0 +1,14 @@
+#
+# this is a test of bulk-insert code
+# as used by REPLACE
+#
+# by Monty
+#
+
+drop table if exists t1;
+CREATE TABLE t1 (a int, unique (a), b int not null, unique(b), c int not null, index(c));
+replace into t1 values (1,1,1),(2,2,2),(3,1,3);
+select * from t1;
+check table t1;
+drop table t1;
+
diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test
index f2b8d42e07c..3ba3a292c77 100644
--- a/mysql-test/t/case.test
+++ b/mysql-test/t/case.test
@@ -30,8 +30,12 @@ insert into t1 values(1),(2),(3),(4);
select case a when 1 then 2 when 2 then 3 else 0 end as fcase, count(*) from t1 group by fcase;
select case a when 1 then "one" when 2 then "two" else "nothing" end as fcase, count(*) from t1 group by fcase;
drop table t1;
-drop table if exists t;
+
+#
+# Test MAX(CASE ... ) that can return null
+#
+
create table t1 (row int not null, col int not null, val varchar(255) not null);
insert into t1 values (1,1,'orange'),(1,2,'large'),(2,1,'yellow'),(2,2,'medium'),(3,1,'green'),(3,2,'small');
select max(case col when 1 then val else null end) as color from t1 group by row;
-drop table if exists t;
+drop table t1;
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
new file mode 100644
index 00000000000..7a120ef5005
--- /dev/null
+++ b/mysql-test/t/cast.test
@@ -0,0 +1,22 @@
+#
+# Test of cast function
+#
+
+select CAST(1-2 AS UNSIGNED);
+select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
+select CONVERT('-1',UNSIGNED);
+select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
+select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
+select ~5, cast(~5 as signed);
+select cast(5 as unsigned) -6.0;
+select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A";
+select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME);
+select cast("1:2:3" as TIME);
+
+#
+# The following should be fixed in 4.1
+#
+
+select cast("2001-1-1" as date) = "2001-01-01";
+select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
+select cast("1:2:3" as TIME) = "1:02:03";
diff --git a/mysql-test/t/check.test b/mysql-test/t/check.test
index 62af9f92e65..947566e725b 100644
--- a/mysql-test/t/check.test
+++ b/mysql-test/t/check.test
@@ -5,14 +5,17 @@ drop table if exists t1;
#add a lot of keys to slow down check
create table t1(n int not null, key(n), key(n), key(n), key(n));
let $1=10000;
+disable_query_log;
while ($1)
{
eval insert into t1 values ($1);
dec $1;
}
-send check table t1 type=extended;
+enable_query_log;
+send check table t1 extended;
connection con2;
insert into t1 values (200000);
connection con1;
reap;
drop table t1;
+
diff --git a/mysql-test/t/constraints.test b/mysql-test/t/constraints.test
new file mode 100644
index 00000000000..8682cdc42a2
--- /dev/null
+++ b/mysql-test/t/constraints.test
@@ -0,0 +1,21 @@
+#
+# Testing of constraints
+# Currently MySQL only ignores the syntax.
+#
+drop table if exists t1;
+
+create table t1 (a int check (a>0));
+insert into t1 values (1);
+insert into t1 values (0);
+drop table t1;
+create table t1 (a int ,b int, check a>b);
+insert into t1 values (1,0);
+insert into t1 values (0,1);
+drop table t1;
+create table t1 (a int ,b int, constraint abc check (a>b));
+insert into t1 values (1,0);
+insert into t1 values (0,1);
+drop table t1;
+create table t1 (a int null);
+insert into t1 values (1),(NULL);
+drop table t1;
diff --git a/mysql-test/t/convert.test b/mysql-test/t/convert.test
new file mode 100644
index 00000000000..f26ef3a8c72
--- /dev/null
+++ b/mysql-test/t/convert.test
@@ -0,0 +1,11 @@
+# Test of character set conversions
+
+# Test that SET DEFAULT works
+
+select @@convert_character_set;
+select @@global.convert_character_set;
+show variables like "%convert_character_set%";
+SET CHARACTER SET cp1251_koi8;
+select @@convert_character_set;
+SET CHARACTER SET DEFAULT;
+select @@convert_character_set;
diff --git a/mysql-test/t/count_distinct.test b/mysql-test/t/count_distinct.test
index 3d795d44821..cb84d0211d7 100644
--- a/mysql-test/t/count_distinct.test
+++ b/mysql-test/t/count_distinct.test
@@ -31,6 +31,7 @@ insert into t1 values ('Berkeley Public2','Berkeley');
insert into t1 values ('NYC Lib','New York');
select t2.isbn,city,t1.libname,count(t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city,t1.libname;
select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct t1.libname) > 1;
+select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct concat(t1.libname,'a')) > 1;
drop table t1, t2, t3;
#
@@ -42,3 +43,12 @@ insert into t1 values (1);
create table t2 (f1 int,f2 int);
select t1.f1,count(distinct t2.f2),count(distinct 1,NULL) from t1 left join t2 on t1.f1=t2.f1 group by t1.f1;
drop table t1,t2;
+
+
+#
+# Empty tables
+#
+create table t1 (f int);
+select count(distinct f) from t1;
+drop table t1;
+
diff --git a/mysql-test/t/count_distinct2-master.opt b/mysql-test/t/count_distinct2-master.opt
new file mode 100644
index 00000000000..d81cc55090d
--- /dev/null
+++ b/mysql-test/t/count_distinct2-master.opt
@@ -0,0 +1 @@
+--set-variable=max_heap_table_size=16384
diff --git a/mysql-test/t/count_distinct2.test b/mysql-test/t/count_distinct2.test
new file mode 100644
index 00000000000..d1bea7614c8
--- /dev/null
+++ b/mysql-test/t/count_distinct2.test
@@ -0,0 +1,79 @@
+drop table if exists t1;
+
+create table t1(n1 int, n2 int, s char(20), vs varchar(20), t text);
+insert into t1 values (1,11, 'one','eleven', 'eleven'),
+ (1,11, 'one','eleven', 'eleven'),
+ (2,11, 'two','eleven', 'eleven'),
+ (2,12, 'two','twevle', 'twelve'),
+ (2,13, 'two','thirteen', 'foo'),
+ (2,13, 'two','thirteen', 'foo'),
+ (2,13, 'two','thirteen', 'bar'),
+ (NULL,13, 'two','thirteen', 'bar'),
+ (2,NULL, 'two','thirteen', 'bar'),
+ (2,13, NULL,'thirteen', 'bar'),
+ (2,13, 'two',NULL, 'bar'),
+ (2,13, 'two','thirteen', NULL);
+
+select distinct n1 from t1;
+select count(distinct n1) from t1;
+
+select distinct n2 from t1;
+select count(distinct n2) from t1;
+
+select distinct s from t1;
+select count(distinct s) from t1;
+
+select distinct vs from t1;
+select count(distinct vs) from t1;
+
+select distinct t from t1;
+select count(distinct t) from t1;
+
+select distinct n1,n2 from t1;
+select count(distinct n1,n2) from t1;
+
+select distinct n1,s from t1;
+select count(distinct n1,s) from t1;
+
+select distinct s,n1,vs from t1;
+select count(distinct s,n1,vs) from t1;
+
+select distinct s,t from t1;
+select count(distinct s,t) from t1;
+
+select count(distinct n1), count(distinct n2) from t1;
+
+select count(distinct n2), n1 from t1 group by n1;
+drop table t1;
+
+# test the conversion from tree to MyISAM
+create table t1 (n int default NULL);
+let $1=5000;
+disable_query_log;
+while ($1)
+{
+ eval insert into t1 values($1);
+ dec $1;
+}
+enable_query_log;
+
+flush status;
+select count(distinct n) from t1;
+show status like 'Created_tmp_disk_tables';
+drop table t1;
+
+#test conversion from heap to MyISAM
+create table t1 (s text);
+let $1=5000;
+disable_query_log;
+while ($1)
+{
+ eval insert into t1 values('$1');
+ dec $1;
+}
+enable_query_log;
+flush status;
+select count(distinct s) from t1;
+show status like 'Created_tmp_disk_tables';
+drop table t1;
+
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index b11c07e5b8d..8aee586268f 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -18,27 +18,30 @@ drop table if exists t1;
# Test of some CREATE TABLE'S that should fail
#
-!$1146 create table t2 type=heap select * from t1;
-!$1146 create table t2 select auto+1 from t1;
+--error 1146
+create table t2 type=heap select * from t1;
+--error 1146
+create table t2 select auto+1 from t1;
drop table if exists t1,t2;
-!$1167 create table t1 (b char(0) not null, index(b));
-!$1164 create table t1 (a int not null auto_increment,primary key (a)) type=heap;
-!$1163 create table t1 (a int not null,b text) type=heap;
-!$1171 create table t1 (a int ,primary key(a)) type=heap;
-!$1121 create table t1 (a int,b text, index(a)) type=isam;
-!$1073 create table t1 (a int,b text, index(b)) type=isam;
+--error 1167
+create table t1 (b char(0) not null, index(b));
+--error 1164
+create table t1 (a int not null auto_increment,primary key (a)) type=heap;
+--error 1163
+create table t1 (a int not null,b text) type=heap;
drop table if exists t1;
-!$1075 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=isam;
-!$1164 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap;
-!$1171 create table t1 (ordid int(8), primary key (ordid));
-!$1121 create table t1 (ordid int(8), unique (ordid)) type=isam;
+--error 1164
+create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap;
-- error 1044,1
create table not_existing_database.test (a int);
-!$1103 create table `a/a` (a int);
-!$1103 create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int);
-!$1059 create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
+--error 1103
+create table `a/a` (a int);
+--error 1103
+create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int);
+--error 1059
+create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
#
# test of dummy table names
@@ -79,9 +82,100 @@ select * from t2 where b="world";
drop table t1,t2;
#
+# Test types after CREATE ... SELECT
+#
+
+create table t1(x varchar(50) );
+create table t2 select x from t1 where 1=2;
+describe t1;
+describe t2;
+drop table t2;
+create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f;
+describe t2;
+drop table t2;
+create table t2 select CAST("2001-12-29" AS DATE) as d, CAST("20:45:11" AS TIME) as t, CAST("2001-12-29 20:45:11" AS DATETIME) as dt;
+describe t2;
+drop table t1,t2;
+
+#
# Test of primary key with 32 index
#
create table t1 (a int not null, b int, primary key(a), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b));
show create table t1;
drop table t1;
+create table t1 select if(1,'1','0'), month("2002-08-02");
+drop table t1;
+create table t1 select if('2002'='2002','Y','N');
+select * from t1;
+drop table if exists t1;
+
+#
+# Test default table type
+#
+SET SESSION table_type="heap";
+SELECT @@table_type;
+CREATE TABLE t1 (a int not null);
+show create table t1;
+drop table t1;
+# Test what happens when using a non existing table type
+SET SESSION table_type="gemini";
+SELECT @@table_type;
+CREATE TABLE t1 (a int not null);
+show create table t1;
+SET SESSION table_type=default;
+drop table t1;
+
+
+#
+# ISO requires that primary keys are implicitly NOT NULL
+#
+create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2));
+insert into t1 values ("a", 1), ("b", 2);
+--error 1048
+insert into t1 values ("c", NULL);
+--error 1048
+insert into t1 values (NULL, 3);
+--error 1048
+insert into t1 values (NULL, NULL);
+drop table t1;
+
+#
+# Bug #801
+#
+
+create table t1 select x'4132';
+drop table t1;
+
+#
+# bug #1434
+#
+
+create table t1 select 1,2,3;
+create table if not exists t1 select 1,2;
+--error 1136
+create table if not exists t1 select 1,2,3,4;
+create table if not exists t1 select 1;
+select * from t1;
+drop table t1;
+create table t1 select 1,2,3;
+create table if not exists t1 select 1,2;
+--error 1136
+create table if not exists t1 select 1,2,3,4;
+create table if not exists t1 select 1;
+select * from t1;
+drop table t1;
+
+#
+# Test create table if not exists with duplicate key error
+#
+
+create table t1 (a int not null, b int, primary key (a));
+insert into t1 values (1,1);
+create table if not exists t1 select 2;
+select * from t1;
+create table if not exists t1 select 3 as 'a',4 as 'b';
+--error 1062
+create table if not exists t1 select 3 as 'a',3 as 'b';
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/ctype_cp1251-master.opt b/mysql-test/t/ctype_cp1251-master.opt
new file mode 100644
index 00000000000..af089d9f176
--- /dev/null
+++ b/mysql-test/t/ctype_cp1251-master.opt
@@ -0,0 +1,2 @@
+--default-character-set=cp1251 --new
+
diff --git a/mysql-test/t/ctype_cp1251.test b/mysql-test/t/ctype_cp1251.test
new file mode 100644
index 00000000000..fffade35389
--- /dev/null
+++ b/mysql-test/t/ctype_cp1251.test
@@ -0,0 +1,17 @@
+# Test of charset cp1251
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+#
+# Test problem with LEFT() (Bug #514)
+#
+
+create table t1 (a varchar(10) not null);
+insert into t1 values ("a"),("ab"),("abc");
+select * from t1;
+select a, left(a,1) as b from t1;
+select a, left(a,1) as b from t1 group by a;
+SELECT DISTINCT RIGHT(a,1) from t1;
+drop table t1;
diff --git a/mysql-test/t/ctype_latin1_de-master.opt b/mysql-test/t/ctype_latin1_de-master.opt
new file mode 100644
index 00000000000..895a62364d6
--- /dev/null
+++ b/mysql-test/t/ctype_latin1_de-master.opt
@@ -0,0 +1,2 @@
+--default-character-set=latin1_de --new
+
diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test
new file mode 100644
index 00000000000..3a0f2658969
--- /dev/null
+++ b/mysql-test/t/ctype_latin1_de.test
@@ -0,0 +1,74 @@
+#
+# Test latin_de character set
+#
+drop table if exists t1;
+create table t1 (a char (20) not null, b int not null auto_increment, index (a,b));
+insert into t1 (a) values ('ä'),('ac'),('ae'),('ad'),('Äc'),('aeb');
+insert into t1 (a) values ('üc'),('uc'),('ue'),('ud'),('Ü'),('ueb'),('uf');
+insert into t1 (a) values ('ö'),('oc'),('Öa'),('oe'),('od'),('Öc'),('oeb');
+insert into t1 (a) values ('s'),('ss'),('ß'),('ßb'),('ssa'),('ssc'),('ßa');
+insert into t1 (a) values ('eä'),('uü'),('öo'),('ää'),('ääa'),('aeae');
+insert into t1 (a) values ('q'),('a'),('u'),('o'),('é'),('É'),('a');
+select a,b from t1 order by a,b;
+select a,b from t1 order by upper(a),b;
+select a from t1 order by a desc;
+check table t1;
+select * from t1 where a like "ö%";
+select * from t1 where a like binary "%É%";
+select * from t1 where a like "%Á%";
+select * from t1 where a like "%U%";
+select * from t1 where a like "%ss%";
+drop table t1;
+
+# The following should all be true
+select strcmp('ä','ae'),strcmp('ae','ä'),strcmp('aeq','äq'),strcmp('äq','aeq');
+select strcmp('ss','ß'),strcmp('ß','ss'),strcmp('ßs','sss'),strcmp('ßq','ssq');
+
+# The following should all return -1
+select strcmp('ä','af'),strcmp('a','ä'),strcmp('ää','aeq'),strcmp('ää','aeaeq');
+select strcmp('ss','ßa'),strcmp('ß','ssa'),strcmp('sßa','sssb'),strcmp('s','ß');
+select strcmp('ö','oö'),strcmp('Ü','uü'),strcmp('ö','oeb');
+
+# The following should all return 1
+select strcmp('af','ä'),strcmp('ä','a'),strcmp('aeq','ää'),strcmp('aeaeq','ää');
+select strcmp('ßa','ss'),strcmp('ssa','ß'),strcmp('sssb','sßa'),strcmp('ß','s');
+select strcmp('u','öa'),strcmp('u','ö');
+
+#
+# overlapping combo's
+#
+select strcmp('sä', 'ßa'), strcmp('aä', 'äx');
+#
+# Some other simple tests with the current character set
+#
+
+create table t1 (a varchar(10), key(a), fulltext (a));
+insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
+select * from t1 where a like "abc%";
+select * from t1 where a like "test%";
+select * from t1 where a like "te_t";
+select * from t1 where match a against ("te*" in boolean mode)+0;
+drop table t1;
+
+#
+# Test bug report #152 (problem with index on latin1_de)
+#
+
+create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word));
+insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae');
+update t1 set word2=word;
+select word, word=0xdf as t from t1 having t > 0;
+select word, word=cast(0xdf AS CHAR) as t from t1 having t > 0;
+select * from t1 where word=0xDF;
+select * from t1 where word=CAST(0xDF as CHAR);
+select * from t1 where word2=0xDF;
+select * from t1 where word2=CAST(0xDF as CHAR);
+select * from t1 where word='ae';
+select * from t1 where word= 0xe4 or word=CAST(0xe4 as CHAR);
+select * from t1 where word between 0xDF and 0xDF;
+select * from t1 where word between CAST(0xDF AS CHAR) and CAST(0xDF AS CHAR);
+select * from t1 where word like 'ae';
+select * from t1 where word like 'AE';
+select * from t1 where word like 0xDF;
+select * from t1 where word like CAST(0xDF as CHAR);
+drop table t1;
diff --git a/mysql-test/t/ctype_tis620-master.opt b/mysql-test/t/ctype_tis620-master.opt
new file mode 100644
index 00000000000..69d47c06e42
--- /dev/null
+++ b/mysql-test/t/ctype_tis620-master.opt
@@ -0,0 +1 @@
+--default-character-set=tis620
diff --git a/mysql-test/t/ctype_tis620.test b/mysql-test/t/ctype_tis620.test
new file mode 100644
index 00000000000..7314b52e301
--- /dev/null
+++ b/mysql-test/t/ctype_tis620.test
@@ -0,0 +1,23 @@
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+ recid int(11) NOT NULL auto_increment,
+ dyninfo text,
+ PRIMARY KEY (recid)
+) ENGINE=MyISAM;
+
+INSERT INTO t1 VALUES (1,'color=\"STB,NPG\"\r\nengine=\"J30A13\"\r\nframe=\"MRHCG1640YP4\"\r\ngrade=\"V6\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CG164YEN\"\r\ntype=\"VT6\"\r\n');
+INSERT INTO t1 VALUES (2,'color=\"HTM,NPG,DEG,RGS\"\r\nengine=\"F23A5YP1\"\r\nframe=\"MRHCF8640YP3\"\r\ngrade=\"EXi AT\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CF864YE\"\r\ntype=\"EXA\"\r\n');
+
+SELECT DISTINCT
+ (IF( LOCATE( 'year=\"', dyninfo ) = 1,
+ SUBSTRING( dyninfo, 6+1, LOCATE('\"\r',dyninfo) - 6 -1),
+ IF( LOCATE( '\nyear=\"', dyninfo ),
+ SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) + 7,
+ LOCATE( '\"\r', SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) +7 )) - 1), '' ))) AS year
+FROM t1
+HAVING year != '' ORDER BY year;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/ctype_ujis-master.opt b/mysql-test/t/ctype_ujis-master.opt
new file mode 100644
index 00000000000..1f4183d5027
--- /dev/null
+++ b/mysql-test/t/ctype_ujis-master.opt
@@ -0,0 +1 @@
+--default-character-set=ujis
diff --git a/mysql-test/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test
new file mode 100644
index 00000000000..cd1dc965000
--- /dev/null
+++ b/mysql-test/t/ctype_ujis.test
@@ -0,0 +1,13 @@
+#
+# Tests with the ujis character set
+#
+drop table if exists t1;
+
+#
+# Test problem with LEFT()
+#
+
+create table t1 (c text);
+insert into t1 values (0xa4a2),(0xa4a3);
+select hex(left(c,1)) from t1 group by c;
+drop table t1;
diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test
index 6fbd99e3283..67111ea1734 100644
--- a/mysql-test/t/delayed.test
+++ b/mysql-test/t/delayed.test
@@ -3,6 +3,7 @@
# (Can't be tested with purify :( )
#
+drop table if exists t1;
create table t1 (a char(10), tmsp timestamp);
insert into t1 set a = 1;
insert delayed into t1 set a = 2;
diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test
index 13fa617b3cf..904d959d148 100644
--- a/mysql-test/t/delete.test
+++ b/mysql-test/t/delete.test
@@ -53,5 +53,11 @@ select * from t1 where misc > 5 and bool is null;
delete from t1 where misc > 5 and bool is null;
select * from t1 where misc > 5 and bool is null;
+select count(*) from t1;
+delete from t1 where 1 > 2;
+select count(*) from t1;
+delete from t1 where 3 > 2;
+select count(*) from t1;
+
drop table t1;
diff --git a/mysql-test/t/dirty-close.test b/mysql-test/t/dirty_close.test
index 3ed22f26d5b..3ed22f26d5b 100644
--- a/mysql-test/t/dirty-close.test
+++ b/mysql-test/t/dirty_close.test
diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test
index bf8a03ac40d..79770a17baa 100644
--- a/mysql-test/t/distinct.test
+++ b/mysql-test/t/distinct.test
@@ -60,7 +60,7 @@ drop table t1;
#
CREATE TABLE t1 (a int(10) unsigned not null primary key,b int(10) unsigned);
-INSERT INTO t1 VALUES (1,1),(2,1);
+INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1);
CREATE TABLE t2 (a int(10) unsigned not null, key (A));
INSERT INTO t2 VALUES (1),(2);
CREATE TABLE t3 (a int(10) unsigned, key(A), b text);
@@ -88,6 +88,16 @@ select distinct t1.a from t1,t3 where t1.a=t3.a;
#flush status;
select distinct 1 from t1,t3 where t1.a=t3.a;
#show status like 'Handler%';
+
+explain SELECT distinct t1.a from t1;
+explain SELECT distinct t1.a from t1 order by a desc;
+explain SELECT t1.a from t1 group by a order by a desc;
+explain SELECT distinct t1.a from t1 order by a desc limit 1;
+explain SELECT distinct a from t3 order by a desc limit 2;
+explain SELECT distinct a,b from t3 order by a+1;
+explain SELECT distinct a,b from t3 order by a limit 10;
+explain SELECT a,b from t3 group by a,b order by a+1;
+
drop table t1,t2,t3,t4;
CREATE TABLE t1 (name varchar(255));
@@ -207,3 +217,70 @@ insert into t1 (a) values (1),(2),(3),(4),(1),(2),(3),(4);
select distinct a from t1 group by b,a having a > 2 order by a desc;
select distinct a,c from t1 group by b,c,a having a > 2 order by a desc;
drop table t1;
+
+#
+# Test problem with DISTINCT and ORDER BY DESC
+#
+
+create table t1 (a char(1), key(a)) type=myisam;
+insert into t1 values('1'),('1');
+select * from t1 where a >= '1';
+select distinct a from t1 order by a desc;
+select distinct a from t1 where a >= '1' order by a desc;
+drop table t1;
+
+#
+# Test when using a not previously used column in ORDER BY
+#
+
+CREATE TABLE t1 (email varchar(50), infoID BIGINT, dateentered DATETIME);
+CREATE TABLE t2 (infoID BIGINT, shipcode varchar(10));
+
+INSERT INTO t1 (email, infoID, dateentered) VALUES
+ ('test1@testdomain.com', 1, '2002-07-30 22:56:38'),
+ ('test1@testdomain.com', 1, '2002-07-27 22:58:16'),
+ ('test2@testdomain.com', 1, '2002-06-19 15:22:19'),
+ ('test2@testdomain.com', 2, '2002-06-18 14:23:47'),
+ ('test3@testdomain.com', 1, '2002-05-19 22:17:32');
+
+INSERT INTO t2(infoID, shipcode) VALUES
+ (1, 'Z001'),
+ (2, 'R002');
+
+SELECT DISTINCTROW email, shipcode FROM t1, t2 WHERE t1.infoID=t2.infoID;
+SELECT DISTINCTROW email FROM t1 ORDER BY dateentered DESC;
+SELECT DISTINCTROW email, shipcode FROM t1, t2 WHERE t1.infoID=t2.infoID ORDER BY dateentered DESC;
+drop table t1,t2;
+
+#
+# test with table.* in DISTINCT
+#
+
+CREATE TABLE t1 (privatemessageid int(10) unsigned NOT NULL auto_increment, folderid smallint(6) NOT NULL default '0', userid int(10) unsigned NOT NULL default '0', touserid int(10) unsigned NOT NULL default '0', fromuserid int(10) unsigned NOT NULL default '0', title varchar(250) NOT NULL default '', message mediumtext NOT NULL, dateline int(10) unsigned NOT NULL default '0', showsignature smallint(6) NOT NULL default '0', iconid smallint(5) unsigned NOT NULL default '0', messageread smallint(6) NOT NULL default '0', readtime int(10) unsigned NOT NULL default '0', receipt smallint(6) unsigned NOT NULL default '0', deleteprompt smallint(6) unsigned NOT NULL default '0', multiplerecipients smallint(6) unsigned NOT NULL default '0', PRIMARY KEY (privatemessageid), KEY userid (userid)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (128,0,33,33,8,':D','',996121863,1,0,2,996122850,2,0,0);
+CREATE TABLE t2 (userid int(10) unsigned NOT NULL auto_increment, usergroupid smallint(5) unsigned NOT NULL default '0', username varchar(50) NOT NULL default '', password varchar(50) NOT NULL default '', email varchar(50) NOT NULL default '', styleid smallint(5) unsigned NOT NULL default '0', parentemail varchar(50) NOT NULL default '', coppauser smallint(6) NOT NULL default '0', homepage varchar(100) NOT NULL default '', icq varchar(20) NOT NULL default '', aim varchar(20) NOT NULL default '', yahoo varchar(20) NOT NULL default '', signature mediumtext NOT NULL, adminemail smallint(6) NOT NULL default '0', showemail smallint(6) NOT NULL default '0', invisible smallint(6) NOT NULL default '0', usertitle varchar(250) NOT NULL default '', customtitle smallint(6) NOT NULL default '0', joindate int(10) unsigned NOT NULL default '0', cookieuser smallint(6) NOT NULL default '0', daysprune smallint(6) NOT NULL default '0', lastvisit int(10) unsigned NOT NULL default '0', lastactivity int(10) unsigned NOT NULL default '0', lastpost int(10) unsigned NOT NULL default '0', posts smallint(5) unsigned NOT NULL default '0', timezoneoffset varchar(4) NOT NULL default '', emailnotification smallint(6) NOT NULL default '0', buddylist mediumtext NOT NULL, ignorelist mediumtext NOT NULL, pmfolders mediumtext NOT NULL, receivepm smallint(6) NOT NULL default '0', emailonpm smallint(6) NOT NULL default '0', pmpopup smallint(6) NOT NULL default '0', avatarid smallint(6) NOT NULL default '0', avatarrevision int(6) unsigned NOT NULL default '0', options smallint(6) NOT NULL default '15', birthday date NOT NULL default '0000-00-00', maxposts smallint(6) NOT NULL default '-1', startofweek smallint(6) NOT NULL default '1', ipaddress varchar(20) NOT NULL default '', referrerid int(10) unsigned NOT NULL default '0', nosessionhash smallint(6) NOT NULL default '0', autorefresh smallint(6) NOT NULL default '-1', messagepopup tinyint(2) NOT NULL default '0', inforum smallint(5) unsigned NOT NULL default '0', ratenum smallint(5) unsigned NOT NULL default '0', ratetotal smallint(5) unsigned NOT NULL default '0', allowrate smallint(5) unsigned NOT NULL default '1', PRIMARY KEY (userid), KEY usergroupid (usergroupid), KEY username (username), KEY inforum (inforum)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (33,6,'Kevin','0','kevin@stileproject.com',1,'',0,'http://www.stileproject.com','','','','',1,1,0,'Administrator',0,996120694,1,-1,1030996168,1031027028,1030599436,36,'-6',0,'','','',1,0,1,0,0,15,'0000-00-00',-1,1,'64.0.0.0',0,1,-1,0,0,4,19,1);
+SELECT DISTINCT t1.*, t2.* FROM t1 LEFT JOIN t2 ON (t2.userid = t1.touserid);
+DROP TABLE IF EXISTS t1,t2;
+
+#
+# test with const_item in ORDER BY
+#
+
+CREATE TABLE t1 (a int primary key, b int, c int);
+INSERT t1 VALUES (1,2,3);
+CREATE TABLE t2 (a int primary key, b int, c int);
+INSERT t2 VALUES (3,4,5);
+SELECT DISTINCT t1.a, t2.b FROM t1, t2 WHERE t1.a=1 ORDER BY t2.c;
+DROP TABLE IF EXISTS t1,t2;
+
+#
+# Test of LEFT() with distinct
+#
+
+CREATE table t1 ( `id` int(11) NOT NULL auto_increment, `name` varchar(50) NOT NULL default '', PRIMARY KEY (`id`)) TYPE=MyISAM AUTO_INCREMENT=3 ;
+INSERT INTO t1 VALUES (1, 'aaaaa');
+INSERT INTO t1 VALUES (3, 'aaaaa');
+INSERT INTO t1 VALUES (2, 'eeeeeee');
+select distinct left(name,1) as name from t1;
+drop table t1;
diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test
index 2a45fe8253b..2f3fa99bac0 100644
--- a/mysql-test/t/drop.test
+++ b/mysql-test/t/drop.test
@@ -1,5 +1,4 @@
drop table if exists t1;
-drop table if exists t1;
--error 1051;
drop table t1;
create table t1(n int);
@@ -11,33 +10,32 @@ create table t1(n int);
drop table t1;
select * from t1;
-#now test for a bug in drop database - it is important that the name
-#of the table is the same as the name of the database - in the original
-#code this triggered a bug
-drop database if exists foo;
-create database foo;
-drop database if exists foo;
-create database foo;
-create table foo.foo (n int);
-insert into foo.foo values (4);
-select * from foo.foo;
-drop database if exists foo;
-create database foo;
-drop database foo;
+# now test for a bug in drop database - it is important that the name
+# of the table is the same as the name of the database - in the original
+# code this triggered a bug
+drop database if exists mysqltest;
+create database mysqltest;
+drop database if exists mysqltest;
+create database mysqltest;
+create table mysqltest.mysqltest (n int);
+insert into mysqltest.mysqltest values (4);
+select * from mysqltest.mysqltest;
+drop database if exists mysqltest;
+create database mysqltest;
+drop database mysqltest;
# test drop/create database and FLUSH TABLES WITH READ LOCK
-drop database if exists foo;
flush tables with read lock;
---error 1209
-create database foo;
+--error 1209,1223;
+create database mysqltest;
unlock tables;
-create database foo;
+create database mysqltest;
show databases;
flush tables with read lock;
---error 1208
-drop database foo;
+--error 1208,1223;
+drop database mysqltest;
unlock tables;
-drop database foo;
+drop database mysqltest;
show databases;
-
-
+--error 1008
+drop database mysqltest;
diff --git a/mysql-test/t/drop_temp_table.test b/mysql-test/t/drop_temp_table.test
new file mode 100644
index 00000000000..1a7d8796bb3
--- /dev/null
+++ b/mysql-test/t/drop_temp_table.test
@@ -0,0 +1,19 @@
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+connection con1;
+reset master;
+create database `drop-temp+table-test`;
+use `drop-temp+table-test`;
+create temporary table `table:name` (a int);
+select get_lock("a",10);
+disconnect con1;
+
+connection con2;
+# We want to SHOW BINLOG EVENTS, to know what was logged. But there is no
+# guarantee that logging of the terminated con1 has been done yet.
+# To be sure that logging has been done, we use a user lock.
+select get_lock("a",10);
+let $VERSION=`select version()`;
+--replace_result $VERSION VERSION
+show binlog events;
+drop database `drop-temp+table-test`;
diff --git a/mysql-test/t/err000001.test b/mysql-test/t/err000001.test
deleted file mode 100644
index d9898054a83..00000000000
--- a/mysql-test/t/err000001.test
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Test some error conditions
-#
-
-drop table if exists t1;
-!$1146 insert into t1 values(1);
-!$1146 delete from t1;
-!$1146 update t1 set a=1;
-create table t1 (a int);
-!$1054 select count(test.t1.b) from t1;
-!$1109 select count(not_existing_database.t1) from t1;
-!$1109 select count(not_existing_database.t1.a) from t1;
---error 1044,1146
-select count(not_existing_database.t1.a) from not_existing_database.t1;
-!$1054 select 1 from t1 order by 2;
-!$1054 select 1 from t1 group by 2;
-!$1054 select 1 from t1 order by t1.b;
-!$1054 select count(*),b from t1;
-drop table t1;
diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test
new file mode 100644
index 00000000000..afb0cce9005
--- /dev/null
+++ b/mysql-test/t/errors.test
@@ -0,0 +1,32 @@
+#
+# Test some error conditions
+#
+
+drop table if exists t1;
+--error 1146
+insert into t1 values(1);
+--error 1146
+delete from t1;
+--error 1146
+update t1 set a=1;
+
+#
+
+create table t1 (a int);
+--error 1054
+select count(test.t1.b) from t1;
+--error 1109
+select count(not_existing_database.t1) from t1;
+--error 1109
+ select count(not_existing_database.t1.a) from t1;
+--error 1044,1146
+select count(not_existing_database.t1.a) from not_existing_database.t1;
+--error 1054
+select 1 from t1 order by 2;
+--error 1054
+select 1 from t1 group by 2;
+--error 1054
+select 1 from t1 order by t1.b;
+--error 1054
+select count(*),b from t1;
+drop table t1;
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index 31a01ae1360..045598e97df 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -3,6 +3,7 @@
drop table if exists t1;
create table t1 (id int not null, str char(10), unique(str));
+explain select * from t1;
insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar");
select * from t1 where str is null;
select * from t1 where str="foo";
@@ -12,8 +13,18 @@ explain select * from t1 ignore key (str) where str="foo";
explain select * from t1 use key (str,str) where str="foo";
#The following should give errors
-!$1072 explain select * from t1 use key (str,str,foo) where str="foo";
-!$1072 explain select * from t1 ignore key (str,str,foo) where str="foo";
+--error 1072
+explain select * from t1 use key (str,str,foo) where str="foo";
+--error 1072
+explain select * from t1 ignore key (str,str,foo) where str="foo";
drop table t1;
explain select 1;
+
+create table t1 (a int not null);
+explain select count(*) from t1;
+insert into t1 values(1);
+explain select count(*) from t1;
+insert into t1 values(1);
+explain select count(*) from t1;
+drop table t1;
diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test
index 4491de1f82b..7754fc2e197 100644
--- a/mysql-test/t/flush.test
+++ b/mysql-test/t/flush.test
@@ -1,12 +1,23 @@
+# This test doesn't work with the embedded version as this code
+# assumes that one query is running while we are doing queries on
+# a second connection.
+# This would work if mysqltest run would be threaded and handle each
+# connection in a separate thread.
+#
+-- source include/not_embedded.inc
+
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
connection con1;
drop table if exists t1;
+drop database if exists mysqltest;
+
create temporary table t1(n int not null primary key);
drop table if exists t2;
create table t2(n int);
insert into t2 values(3);
let $1=100;
+disable_query_log;
while ($1)
{
connection con1;
@@ -19,7 +30,7 @@ while ($1)
reap;
dec $1;
}
-
+enable_query_log;
connection con1;
select * from t1;
connection con2;
@@ -35,15 +46,14 @@ reap;
#test if drop database will wait until we release the global read lock
connection con1;
-drop database if exists foo;
-create database foo;
-create table foo.t1(n int);
-insert into foo.t1 values (23);
+create database mysqltest;
+create table mysqltest.t1(n int);
+insert into mysqltest.t1 values (23);
flush tables with read lock;
connection con2;
-send drop database foo;
+send drop database mysqltest;
connection con1;
-select * from foo.t1;
+select * from mysqltest.t1;
unlock tables;
connection con2;
reap;
diff --git a/mysql-test/t/flush_table.test b/mysql-test/t/flush_table.test
index a4f12886120..4ddcd53d5c8 100644
--- a/mysql-test/t/flush_table.test
+++ b/mysql-test/t/flush_table.test
@@ -4,6 +4,7 @@
# Test of flush table
#
+#drop table if exists t1;
#create table t1 (a int not null auto_increment primary key);
#insert into t1 values(0);
#lock table t1 read;
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 83e328ca616..02657ba3775 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -5,10 +5,66 @@
drop table if exists t1,t2,t3;
CREATE TABLE t1 (a VARCHAR(200), b TEXT, FULLTEXT (a,b));
-INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),('Full-text indexes', 'are called collections'),('Only MyISAM tables','support collections'),('Function MATCH ... AGAINST()','is used to do a search'),('Full-text search in MySQL', 'implements vector space model');
+INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),
+ ('Full-text indexes', 'are called collections'),
+ ('Only MyISAM tables','support collections'),
+ ('Function MATCH ... AGAINST()','is used to do a search'),
+ ('Full-text search in MySQL', 'implements vector space model');
+SHOW INDEX FROM t1;
+
+# nl search
+
select * from t1 where MATCH(a,b) AGAINST ("collections");
select * from t1 where MATCH(a,b) AGAINST ("indexes");
select * from t1 where MATCH(a,b) AGAINST ("indexes collections");
+
+
+# add_ft_keys() tests
+
+explain select * from t1 where MATCH(a,b) AGAINST ("collections");
+explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0;
+explain select * from t1 where MATCH(a,b) AGAINST ("collections")>1;
+explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=0;
+explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=1;
+explain select * from t1 where 0<MATCH(a,b) AGAINST ("collections");
+explain select * from t1 where 1<MATCH(a,b) AGAINST ("collections");
+explain select * from t1 where 0<=MATCH(a,b) AGAINST ("collections");
+explain select * from t1 where 1<=MATCH(a,b) AGAINST ("collections");
+explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0 and a like '%ll%';
+
+# boolean search
+
+select * from t1 where MATCH(a,b) AGAINST("support -collections" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("support +collections" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("sear*" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE);
+select * from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE);
+select *, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1;
+select *, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1;
+
+select * from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE);
+
+select * from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE);
+select * from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE);
+select * from t1 where MATCH a,b AGAINST ('"text search" "now support"' IN BOOLEAN MODE);
+select * from t1 where MATCH a,b AGAINST ('"text search" -"now support"' IN BOOLEAN MODE);
+select * from t1 where MATCH a,b AGAINST ('"text search" +"now support"' IN BOOLEAN MODE);
+select * from t1 where MATCH a,b AGAINST ('"text i"' IN BOOLEAN MODE);
+
+# boolean w/o index:
+
+select * from t1 where MATCH a AGAINST ("search" IN BOOLEAN MODE);
+select * from t1 where MATCH b AGAINST ("sear*" IN BOOLEAN MODE);
+
+# UNION of fulltext's
+
+select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes");
+
+#update/delete with fulltext index
+
delete from t1 where a like "MySQL%";
update t1 set a='some test foobar' where MATCH a,b AGAINST ('model');
delete from t1 where MATCH(a,b) AGAINST ("indexes");
@@ -16,6 +72,17 @@ select * from t1;
drop table t1;
#
+# why to scan strings for trunc*
+#
+create table t1 (a varchar(200) not null, fulltext (a));
+insert t1 values ("aaa10 bbb20"), ("aaa20 bbb15"), ("aaa30 bbb10");
+select * from t1 where match a against ("+aaa* +bbb*" in boolean mode);
+select * from t1 where match a against ("+aaa* +bbb1*" in boolean mode);
+select * from t1 where match a against ("+aaa* +ccc*" in boolean mode);
+select * from t1 where match a against ("+aaa10 +(bbb*)" in boolean mode);
+drop table t1;
+
+#
# Check bug reported by Matthias Urlichs
#
@@ -77,14 +144,92 @@ CREATE TABLE t3 (
--error 1210
select * from t2 where MATCH inhalt AGAINST (t2.inhalt);
-
---error 1210
-select * from t2 where MATCH inhalt AGAINST (t2.inhalt);
-
--error 1191
select * from t2 where MATCH ticket AGAINST ('foobar');
-
--error 1210
select * from t2,t3 where MATCH (t2.inhalt,t3.inhalt) AGAINST ('foobar');
drop table t1,t2,t3;
+
+#
+# three more bugtests
+#
+
+CREATE TABLE t1 (
+ id int(11) auto_increment,
+ title varchar(100) default '',
+ PRIMARY KEY (id),
+ KEY ind5 (title),
+ FULLTEXT KEY FT1 (title)
+) TYPE=MyISAM;
+
+insert into t1 (title) values ('this is a test');
+select * from t1 where match title against ('test' in boolean mode);
+update t1 set title='this is A test' where id=1;
+check table t1;
+update t1 set title='this test once revealed a bug' where id=1;
+select * from t1;
+update t1 set title=NULL where id=1;
+
+drop table t1;
+
+# one more bug - const_table related
+
+CREATE TABLE t1 (a int(11), b text, FULLTEXT KEY (b)) TYPE=MyISAM;
+insert into t1 values (1,"I wonder why the fulltext index doesnt work?");
+SELECT * from t1 where MATCH (b) AGAINST ('apples');
+
+insert into t1 values (2,"fullaaa fullzzz");
+select * from t1 where match b against ('full*' in boolean mode);
+
+drop table t1;
+CREATE TABLE t1 ( id int(11) NOT NULL auto_increment primary key, mytext text NOT NULL, FULLTEXT KEY mytext (mytext)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'my small mouse'),(2,'la-la-la'),(3,'It is so funny'),(4,'MySQL Tutorial');
+select 8 from t1;
+drop table t1;
+
+#
+# Check bug reported by Julian Ladisch
+# ERROR 1030: Got error 127 from table handler
+#
+
+drop table if exists t1;
+create table t1 (a text, fulltext key (a));
+insert into t1 values ('aaaa');
+repair table t1;
+select * from t1 where match (a) against ('aaaa');
+drop table t1;
+
+#
+# bug #283 by jocelyn fournier <joc@presence-pc.com>
+# FULLTEXT index on a TEXT filed converted to a CHAR field doesn't work anymore
+#
+
+drop table if exists t1;
+create table t1 ( ref_mag text not null, fulltext (ref_mag));
+insert into t1 values ('test');
+select ref_mag from t1 where match ref_mag against ('+test' in boolean mode);
+alter table t1 change ref_mag ref_mag char (255) not null;
+select ref_mag from t1 where match ref_mag against ('+test' in boolean mode);
+drop table t1;
+
+#
+# bug #942: JOIN
+#
+
+create table t1 (t1_id int(11) primary key, name varchar(32));
+insert into t1 values (1, 'data1');
+insert into t1 values (2, 'data2');
+create table t2 (t2_id int(11) primary key, t1_id int(11), name varchar(32));
+insert into t2 values (1, 1, 'xxfoo');
+insert into t2 values (2, 1, 'xxbar');
+insert into t2 values (3, 1, 'xxbuz');
+select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode);
+
+#
+# bug with many short (< ft_min_word_len) words in boolean search
+#
+select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
+
+drop table t1,t2;
+
diff --git a/mysql-test/t/fulltext_cache.test b/mysql-test/t/fulltext_cache.test
index fc5f0e266b3..0b15e57a97b 100644
--- a/mysql-test/t/fulltext_cache.test
+++ b/mysql-test/t/fulltext_cache.test
@@ -26,10 +26,16 @@ INSERT INTO t2 VALUES (6,2,'um chocolate Snickers');
INSERT INTO t2 VALUES (7,1,'Bife');
INSERT INTO t2 VALUES (8,1,'Pizza de Salmao');
-SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi') as x FROM t1, t2
-WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
+as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
-SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi') as x FROM t2, t1
-WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
+as x FROM t1, t2 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi')
+as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
+
+SELECT t1.q, t2.item, t2.id, MATCH t2.item AGAINST ('sushi' IN BOOLEAN MODE)
+as x FROM t2, t1 WHERE (t2.id2 = t1.id) ORDER BY x DESC,t2.id;
drop table t1, t2;
diff --git a/mysql-test/t/fulltext_distinct.test b/mysql-test/t/fulltext_distinct.test
new file mode 100644
index 00000000000..86e2f7ca1b4
--- /dev/null
+++ b/mysql-test/t/fulltext_distinct.test
@@ -0,0 +1,41 @@
+#
+# Test of fulltext index
+# bug reported by Tibor Simko <tibor.simko@cern.ch>
+#
+
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+ id mediumint unsigned NOT NULL auto_increment,
+ tag char(6) NOT NULL default '',
+ value text NOT NULL default '',
+ PRIMARY KEY (id),
+ KEY kt(tag),
+ KEY kv(value(15)),
+ FULLTEXT KEY kvf(value)
+) TYPE=MyISAM;
+CREATE TABLE t2 (
+ id_t2 mediumint unsigned NOT NULL default '0',
+ id_t1 mediumint unsigned NOT NULL default '0',
+ field_number tinyint unsigned NOT NULL default '0',
+ PRIMARY KEY (id_t2,id_t1,field_number),
+ KEY id_t1(id_t1)
+) TYPE=MyISAM;
+
+INSERT INTO t1 (tag,value) VALUES ('foo123','bar111');
+INSERT INTO t1 (tag,value) VALUES ('foo123','bar222');
+INSERT INTO t1 (tag,value) VALUES ('bar345','baz333 ar');
+
+INSERT INTO t2 VALUES (2231626,64280,0);
+INSERT INTO t2 VALUES (2231626,64281,0);
+INSERT INTO t2 VALUES (12346, 3, 1);
+
+SELECT * FROM t1; SELECT * FROM t2;
+
+SELECT DISTINCT t2.id_t2 FROM t2, t1
+WHERE MATCH (t1.value) AGAINST ('baz333') AND t1.id = t2.id_t1;
+
+SELECT DISTINCT t2.id_t2 FROM t2, t1
+WHERE MATCH (t1.value) AGAINST ('baz333' IN BOOLEAN MODE)
+AND t1.id = t2.id_t1;
+
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/fulltext_left_join.test b/mysql-test/t/fulltext_left_join.test
index d09d577d04b..a785cc6a61c 100644
--- a/mysql-test/t/fulltext_left_join.test
+++ b/mysql-test/t/fulltext_left_join.test
@@ -2,6 +2,7 @@
# Test for bug from Jean-Cédric COSTA <jean-cedric.costa@ensmp.fr>
#
+drop table if exists t1, t2;
CREATE TABLE t1 (
id VARCHAR(255) NOT NULL PRIMARY KEY,
sujet VARCHAR(255),
@@ -22,6 +23,22 @@ INSERT INTO t2 VALUES('456', 'lui');
select match(t1.texte,t1.sujet,t1.motsclefs) against('droit')
from t1 left join t2 on t2.id=t1.id;
+select match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE)
+ from t1 left join t2 on t2.id=t1.id;
drop table t1, t2;
+#
+# Bug #484, reported by Stephen Brandon <stephen@brandonitconsulting.co.uk>
+#
+
+create table t1 (venue_id int(11) default null, venue_text varchar(255) default null, dt datetime default null) type=myisam;
+insert into t1 (venue_id, venue_text, dt) values (1, 'a1', '2003-05-23 19:30:00'),(null, 'a2', '2003-05-23 19:30:00');
+create table t2 (name varchar(255) not null default '', entity_id int(11) not null auto_increment, primary key (entity_id), fulltext key name (name)) type=myisam;
+insert into t2 (name, entity_id) values ('aberdeen town hall', 1), ('glasgow royal concert hall', 2), ('queen\'s hall, edinburgh', 3);
+select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen' in boolean mode) and dt = '2003-05-23 19:30:00';
+select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen') and dt = '2003-05-23 19:30:00';
+select * from t1 left join t2 on (venue_id = entity_id and match(name) against('aberdeen' in boolean mode)) where dt = '2003-05-23 19:30:00';
+select * from t1 left join t2 on (venue_id = entity_id and match(name) against('aberdeen')) where dt = '2003-05-23 19:30:00';
+drop table t1,t2;
+
diff --git a/mysql-test/t/fulltext_multi.test b/mysql-test/t/fulltext_multi.test
index 233c243146e..f71704e1bb9 100644
--- a/mysql-test/t/fulltext_multi.test
+++ b/mysql-test/t/fulltext_multi.test
@@ -1,5 +1,5 @@
# several FULLTEXT indexes in one table test
-use test;
+
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
a int(11) NOT NULL auto_increment,
diff --git a/mysql-test/t/fulltext_order_by.test b/mysql-test/t/fulltext_order_by.test
index 9f35d58e699..8c34230cfe3 100644
--- a/mysql-test/t/fulltext_order_by.test
+++ b/mysql-test/t/fulltext_order_by.test
@@ -1,4 +1,3 @@
-use test;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
a INT AUTO_INCREMENT PRIMARY KEY,
@@ -9,17 +8,38 @@ INSERT INTO t1 (message) VALUES ("Testing"),("table"),("testbug"),
("steve"),("is"),("cool"),("steve is cool");
# basic MATCH
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve');
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve');
+SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
# MATCH + ORDER BY (with ft-ranges)
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve') ORDER BY a;
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a;
# MATCH + ORDER BY (with normal ranges) + UNIQUE
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve') ORDER BY a DESC;
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a DESC;
# MATCH + ORDER BY + UNIQUE (const_table)
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve') ORDER BY 1;
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY 1;
# ORDER BY MATCH
SELECT a, MATCH (message) AGAINST ('steve') as rel FROM t1 ORDER BY rel;
+SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
drop table t1;
+
+#
+# reused boolean scan bug
+#
+CREATE TABLE t1 (
+ a INT AUTO_INCREMENT PRIMARY KEY,
+ message CHAR(20),
+ FULLTEXT(message)
+);
+INSERT INTO t1 (message) VALUES ("testbug"),("testbug foobar");
+SELECT a, MATCH (message) AGAINST ('t* f*' IN BOOLEAN MODE) as rel FROM t1;
+SELECT a, MATCH (message) AGAINST ('t* f*' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel,a;
+drop table t1;
+
diff --git a/mysql-test/t/fulltext_var.test b/mysql-test/t/fulltext_var.test
new file mode 100644
index 00000000000..71213d1195a
--- /dev/null
+++ b/mysql-test/t/fulltext_var.test
@@ -0,0 +1,5 @@
+#
+# Fulltext configurable parameters
+#
+
+show variables like "ft\_%";
diff --git a/mysql-test/t/func_crypt.test b/mysql-test/t/func_crypt.test
index ddc0816e301..e612405c5e9 100644
--- a/mysql-test/t/func_crypt.test
+++ b/mysql-test/t/func_crypt.test
@@ -1,2 +1,15 @@
+-- source include/have_crypt.inc
select length(encrypt('foo', 'ff')) <> 0;
+--replace_result $1$aa$4OSUA5cjdx0RUQ08opV27/ aaqPiZY5xR5l.
+select old_password('test'), password('test');
+select length(encrypt('test')), encrypt('test','aa');
+
+drop table if exists t1;
+create table t1 (name varchar(50), pw varchar(16));
+insert into t1 values ('tom', password('my_pass'));
+set @pass='my_pass';
+select name from t1 where name='tom' and pw=password(@pass);
+select name from t1 where name='tom' and pw=password(@undefined);
+drop table t1;
+
diff --git a/mysql-test/t/func_encrypt-master.opt b/mysql-test/t/func_encrypt-master.opt
new file mode 100644
index 00000000000..ab687810d5f
--- /dev/null
+++ b/mysql-test/t/func_encrypt-master.opt
@@ -0,0 +1 @@
+--loose-des-key-file=$MYSQL_TEST_DIR/std_data/des_key_file
diff --git a/mysql-test/t/func_encrypt.test b/mysql-test/t/func_encrypt.test
new file mode 100644
index 00000000000..3b6acc54ec9
--- /dev/null
+++ b/mysql-test/t/func_encrypt.test
@@ -0,0 +1,67 @@
+-- source include/have_openssl.inc
+
+drop table if exists t1;
+create table t1 (x blob);
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('a','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','a'));
+insert into t1 values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab'));
+insert into t1 values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc'));
+insert into t1 values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd'));
+insert into t1 values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde'));
+insert into t1 values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef'));
+insert into t1 values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg'));
+insert into t1 values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh'));
+insert into t1 values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi'));
+insert into t1 values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij'));
+insert into t1 values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk'));
+insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('red fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('fox jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('brown dog','sabakala'));
+insert into t1 values (des_encrypt('dog','sabakala'));
+insert into t1 values (des_encrypt('dog!','sabakala'));
+insert into t1 values (des_encrypt('dog!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!!','sabakala'));
+insert into t1 values (des_encrypt('dog!!!!!','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala'));
+select hex(x), hex(des_decrypt(x,'sabakala')) from t1;
+select des_decrypt(x,'sabakala') as s from t1 having s like '%dog%';
+drop table t1;
+
+#
+# Test default keys
+#
+select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello"));
+select des_decrypt(des_encrypt("hello",4));
+select des_decrypt(des_encrypt("hello",'test'),'test');
+select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password'));
+select des_decrypt(des_encrypt("hello"),'default_password');
+select des_decrypt(des_encrypt("hello",4),'password4');
+
+# Test flush
+SET @a=des_decrypt(des_encrypt("hello"));
+flush des_key_file;
+select @a = des_decrypt(des_encrypt("hello"));
+
+# Test usage of wrong password
+select hex("hello");
+select hex(des_decrypt(des_encrypt("hello",4),'password2'));
+select hex(des_decrypt(des_encrypt("hello","hidden")));
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index b97afc06340..d03e4b9b629 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -2,6 +2,7 @@
# simple test of all group functions
#
+drop table if exists t1,t2;
create table t1 (grp int, a bigint unsigned, c char(10) not null);
insert into t1 values (1,1,"a");
insert into t1 values (2,2,"b");
@@ -20,7 +21,7 @@ select count(distinct a),count(distinct grp) from t1;
insert into t1 values (null,null,'');
select count(distinct a),count(distinct grp) from t1;
-select sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1;
+select sum(all a),count(all a),avg(all a),std(all a),bit_or(all a),bit_and(all a),min(all a),max(all a),min(all c),max(all c) from t1;
select grp, sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp;
select grp, sum(a)+count(a)+avg(a)+std(a)+bit_or(a)+bit_and(a)+min(a)+max(a)+min(c)+max(c) as sum from t1 group by grp;
@@ -98,3 +99,59 @@ insert into t1 values (5.2,'nem'),(8.64,'monty'),(11.12,'sinisa');
select sum(num) from t1;
select sum(num) from t1 group by user;
drop table t1;
+
+#
+# Test problem with MIN() optimization in case of null values
+#
+
+create table t1 (a1 int, a2 char(3), key k1(a1), key k2(a2));
+insert into t1 values(10,'aaa'), (10,null), (10,'bbb'), (20,'zzz');
+create table t2(a1 char(3), a2 int, a3 real, key k1(a1), key k2(a2, a1));
+select * from t1;
+# The following returned NULL in 4.0.10
+select min(a2) from t1;
+select max(t1.a1), max(t2.a2) from t1, t2;
+select max(t1.a1) from t1, t2;
+select max(t2.a2), max(t1.a1) from t1, t2;
+
+explain select min(a2) from t1;
+explain select max(t1.a1), max(t2.a2) from t1, t2;
+
+insert into t2 values('AAA', 10, 0.5);
+select max(t1.a1), max(t2.a1) from t1, t2 where t2.a2=9;
+select max(t2.a1), max(t1.a1) from t1, t2 where t2.a2=9;
+select t1.a1, t1.a2, t2.a1, t2.a2 from t1 left outer join t2 on t1.a1=10;
+select max(t1.a2) from t1 left outer join t2 on t1.a1=10;
+select max(t1.a2) from t1 left outer join t2 on t1.a1=10 where t1.a1=20;
+select max(t1.a2) from t1 left outer join t2 on t1.a1=10 where t1.a1=10;
+select max(t2.a1) from t1 left outer join t2 on t1.a2=t2.a1 and 1=0 where t2.a1='AAA';
+drop table t1,t2;
+
+#
+# Test of group function and NULL values
+#
+
+CREATE TABLE t1 (a int, b int);
+select count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1;
+select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+insert into t1 values (1,null);
+select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+insert into t1 values (1,null);
+insert into t1 values (2,null);
+select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+insert into t1 values (2,1);
+select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+insert into t1 values (3,1);
+select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a;
+drop table t1;
+#
+# Bug #1972: test for bit_and(), bit_or() and negative values
+#
+create table t1 (col int);
+insert into t1 values (-1), (-2), (-3);
+select bit_and(col), bit_or(col) from t1;
+select SQL_BIG_RESULT bit_and(col), bit_or(col) from t1 group by col;
+drop table t1;
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 6830534e761..e5d42ec25c4 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -2,6 +2,7 @@
# test of IN (NULL)
#
+drop table if exists t1;
CREATE TABLE t1 (field char(1));
INSERT INTO t1 VALUES ('A'),(NULL);
SELECT * from t1 WHERE field IN (NULL);
diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test
index d160b04176c..6d6ee8f86a3 100644
--- a/mysql-test/t/func_like.test
+++ b/mysql-test/t/func_like.test
@@ -2,9 +2,32 @@
# Test of like
#
+drop table if exists t1;
create table t1 (a varchar(10), key(a));
insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
-select * from t1 where a like "abc%";
-select * from t1 where a like "test%";
-select * from t1 where a like "te_t";
+explain select * from t1 where a like 'abc%';
+explain select * from t1 where a like concat('abc','%');
+select * from t1 where a like "abc%";
+select * from t1 where a like concat("abc","%");
+select * from t1 where a like "ABC%";
+select * from t1 where a like "test%";
+select * from t1 where a like "te_t";
+
+#
+# The following will test the Turbo Boyer-Moore code
+#
+select * from t1 where a like "%a%";
+select * from t1 where a like "%abcd%";
+select * from t1 where a like "%abc\d%";
+
+drop table t1;
+
+#
+# Bug #2231
+#
+
+create table t1 (a varchar(10), key(a));
+insert into t1 values ('a'), ('a\\b');
+select * from t1 where a like 'a\\%' escape '#';
+select * from t1 where a like 'a\\%' escape '#' and a like 'a\\\\b';
drop table t1;
diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test
index 42ba8c73f69..2de692d4389 100644
--- a/mysql-test/t/func_math.test
+++ b/mysql-test/t/func_math.test
@@ -8,8 +8,12 @@ select truncate(52.64,1),truncate(52.64,2),truncate(52.64,-1),truncate(52.64,-2)
select round(5.5),round(-5.5);
select round(5.64,1),round(5.64,2),round(5.64,-1),round(5.64,-2);
select abs(-10), sign(-5), sign(5), sign(0);
-select log(exp(10)),exp(log(sqrt(10))*2);
+select log(exp(10)),exp(log(sqrt(10))*2),log(-1),log(NULL),log(1,1),log(3,9),log(-1,2),log(NULL,2);
+select ln(exp(10)),exp(ln(sqrt(10))*2),ln(-1),ln(0),ln(NULL);
+select log2(8),log2(15),log2(-2),log2(0),log2(NULL);
+select log10(100),log10(18),log10(-4),log10(0),log10(NULL);
select pow(10,log10(10)),power(2,4);
+set @@rand_seed1=10000000,@@rand_seed2=1000000;
select rand(999999),rand();
select pi(),sin(pi()/2),cos(pi()/2),abs(tan(pi())),cot(1),asin(1),acos(0),atan(1);
select degrees(pi()),radians(360);
diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index d48b17e87af..d15c26279ec 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -7,3 +7,13 @@ select format(1.5555,0),format(123.5555,1),format(1234.5555,2),format(12345.5555
select inet_ntoa(inet_aton("255.255.255.255.255.255.255.255"));
select inet_aton("255.255.255.255.255"),inet_aton("255.255.1.255"),inet_aton("0.1.255");
select inet_ntoa(1099511627775),inet_ntoa(4294902271),inet_ntoa(511);
+
+#
+# Test for core dump with nan
+#
+select length(format('nan', 2)) > 0;
+
+#
+# Test for bug #628
+#
+select concat("$",format(2500,2));
diff --git a/mysql-test/t/func_op.test b/mysql-test/t/func_op.test
index 778c8406b8d..a312d6ac8c0 100644
--- a/mysql-test/t/func_op.test
+++ b/mysql-test/t/func_op.test
@@ -5,3 +5,12 @@
select 1+1,1-1,1+1*2,8/5,8%5,mod(8,5),mod(8,5)|0,-(1+1)*-2;
select 1 | (1+1),5 & 3,bit_count(7) ;
select 1 << 32,1 << 63, 1 << 64, 4 >> 2, 4 >> 63, 1<< 63 >> 60;
+#
+# bug #1993: bit functions must be unsigned
+#
+select -1 | 0, -1 ^ 0, -1 & 0;
+select -1 | 1, -1 ^ 1, -1 & 1;
+select 1 | -1, 1 ^ -1, 1 & -1;
+select 0 | -1, 0 ^ -1, 0 & -1;
+select -1 >> 0, -1 << 0;
+select -1 >> 1, -1 << 1;
diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test
index cb1aa543d43..81f561989d5 100644
--- a/mysql-test/t/func_set.test
+++ b/mysql-test/t/func_set.test
@@ -15,3 +15,4 @@ select export_set(9,"Y","N","-",5),export_set(9,"Y","N"),export_set(9,"Y","N",""
select elt(2,1),field(NULL,"a","b","c");
select find_in_set("","a,b,c"),find_in_set("","a,b,c,"),find_in_set("",",a,b,c");
select find_in_set("abc","abc"),find_in_set("ab","abc"),find_in_set("abcd","abc");
+select interval(null, 1, 10, 100);
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index b7200b2d144..1eba49a9583 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -9,10 +9,11 @@ drop table if exists t1;
select 'hello',"'hello'",'""hello""','''h''e''l''l''o''',"hel""lo",'hel\'lo';
select 'hello' 'monty';
select length('\n\t\r\b\0\_\%\\');
+select bit_length('\n\t\r\b\0\_\%\\');
select concat('monty',' was here ','again'),length('hello'),char(ascii('h'));
select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
-select instr('hello','he');
-select position('ll' in 'hello'),position('a' in 'hello');
+select instr('hello','HE'), instr('hello',binary 'HE'), instr(binary 'hello','HE');
+select position(binary 'll' in 'hello'),position('a' in binary 'hello');
select left('hello',2),right('hello',2),substring('hello',2,2),mid('hello',1,5) ;
select concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',substring('monty',5,1)) ;
select substring_index('www.tcx.se','.',-2),substring_index('www.tcx.se','.',1);
@@ -35,15 +36,26 @@ select insert('txs',2,1,'hi'),insert('is ',4,0,'a'),insert('txxxxt',2,4,'es');
select replace('aaaa','a','b'),replace('aaaa','aa','b'),replace('aaaa','a','bb'),replace('aaaa','','b'),replace('bbbb','a','c');
select replace(concat(lcase(concat('THIS',' ','IS',' ','A',' ')),ucase('false'),' ','test'),'FALSE','REAL') ;
select soundex(''),soundex('he'),soundex('hello all folks');
-select password('test'),length(encrypt('test')),encrypt('test','aa');
select md5('hello');
+select sha('abc');
+select sha1('abc');
+select aes_decrypt(aes_encrypt('abc','1'),'1');
+select aes_decrypt(aes_encrypt('abc','1'),1);
+select aes_encrypt(NULL,"a");
+select aes_encrypt("a",NULL);
+select aes_decrypt(NULL,"a");
+select aes_decrypt("a",NULL);
+select aes_decrypt("a","a");
+select aes_decrypt(aes_encrypt("","a"),"a");
select repeat('monty',5),concat('*',space(5),'*');
select reverse('abc'),reverse('abcd');
-select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12');
-select lpad('a',4,'1'),lpad('a',4,'12'),lpad('abcd',3,'12');
+select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12'), rpad(11, 10 , 22), rpad("ab", 10, 22);
+select lpad('a',4,'1'),lpad('a',4,'12'),lpad('abcd',3,'12'), lpad(11, 10 , 22);
select rpad(741653838,17,'0'),lpad(741653838,17,'0');
select rpad('abcd',7,'ab'),lpad('abcd',7,'ab');
select rpad('abcd',1,'ab'),lpad('abcd',1,'ab');
+select rpad('STRING', 20, CONCAT('p','a','d') );
+select lpad('STRING', 20, CONCAT('p','a','d') );
select LEAST(NULL,'HARRY','HARRIOT',NULL,'HAROLD'),GREATEST(NULL,'HARRY','HARRIOT',NULL,'HAROLD');
select least(1,2,3) | greatest(16,32,8), least(5,4)*1,greatest(-1.0,1.0)*1,least(3,2,1)*1.0,greatest(1,1.1,1.0),least("10",9),greatest("A","B","0");
@@ -51,6 +63,12 @@ select least(1,2,3) | greatest(16,32,8), least(5,4)*1,greatest(-1.0,1.0)*1,least
select decode(encode(repeat("a",100000),"monty"),"monty")=repeat("a",100000);
select decode(encode("abcdef","monty"),"monty")="abcdef";
+select quote('\'\"\\test');
+select quote(concat('abc\'', '\\cba'));
+select quote(1/0), quote('\0\Z');
+select length(quote(concat(char(0),"test")));
+select hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235))));
+
#
# Wrong usage of functions
#
@@ -99,4 +117,49 @@ INSERT INTO t1 VALUES (1,'Link',1,1,1,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
SELECT CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter), '"') FROM t1;
SELECT CONCAT('"',CONCAT_WS('";"',title,prio,category,program,bugstatus,submitter), '"') FROM t1;
SELECT CONCAT_WS('";"',title,prio,category,program,bugdesc,created,modified,bugstatus,submitter) FROM t1;
+SELECT bugdesc, REPLACE(bugdesc, 'xxxxxxxxxxxxxxxxxxxx', 'bbbbbbbbbbbbbbbbbbbb') from t1 group by bugdesc;
drop table t1;
+
+#
+# Test bug in AES_DECRYPT() when called with wrong argument
+#
+
+CREATE TABLE t1 (id int(11) NOT NULL auto_increment, tmp text NOT NULL, KEY id (id)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
+SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ wid int(10) unsigned NOT NULL auto_increment,
+ data_podp date default NULL,
+ status_wnio enum('nowy','podp','real','arch') NOT NULL default 'nowy',
+ PRIMARY KEY(wid),
+);
+
+INSERT INTO t1 VALUES (8,NULL,'real');
+INSERT INTO t1 VALUES (9,NULL,'nowy');
+SELECT elt(status_wnio,data_podp) FROM t1 GROUP BY wid;
+DROP TABLE t1;
+
+#
+# test for #739
+
+CREATE TABLE t1 (
+ title text
+) TYPE=MyISAM;
+
+INSERT INTO t1 VALUES ('Congress reconvenes in September to debate welfare and adult education');
+INSERT INTO t1 VALUES ('House passes the CAREERS bill');
+
+SELECT CONCAT("</a>",RPAD("",(55 - LENGTH(title)),".")) from t1;
+
+DROP TABLE t1;
+
+#
+# test for Bug #2290 "output truncated with ELT when using DISTINCT"
+#
+
+CREATE TABLE t1 (i int, j int);
+INSERT INTO t1 VALUES (1,1),(2,2);
+SELECT DISTINCT i, ELT(j, '345', '34') FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/func_system.test b/mysql-test/t/func_system.test
index b0bdbe472dd..052e0530cf6 100644
--- a/mysql-test/t/func_system.test
+++ b/mysql-test/t/func_system.test
@@ -2,5 +2,5 @@
# system functions
#
-select database(),user();
+select database(),user() like "%@%";
select version()>="3.23.29";
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index ec44009b1a6..e03d0dd0f0f 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -15,6 +15,13 @@ select 2 between 1 and 3, "monty" between "max" and "my",2=2 and "monty" between
select 'b' between 'a' and 'c', 'B' between 'a' and 'c';
select 2 in (3,2,5,9,5,1),"monty" in ("david","monty","allan"), 1.2 in (1.4,1.2,1.0);
select -1.49 or -1.49,0.6 or 0.6;
+select 3 ^ 11, 1 ^ 1, 1 ^ 0, 1 ^ NULL, NULL ^ 1;
+select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL;
+
+create table t1 (a int);
+insert t1 values (1);
+select * from t1 where 1 xor 1;
+drop table t1;
#
# Wrong usage of functions
@@ -23,3 +30,10 @@ select -1.49 or -1.49,0.6 or 0.6;
select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1;
select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1;
select 1 and 0 or 2, 2 or 1 and 0;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 ( faq_group_id int(11) NOT NULL default '0', faq_id int(11) NOT NULL default '0', title varchar(240) default NULL, keywords text, description longblob, solution longblob, status tinyint(4) NOT NULL default '0', access_id smallint(6) default NULL, lang_id smallint(6) NOT NULL default '0', created datetime NOT NULL default '0000-00-00 00:00:00', updated datetime default NULL, last_access datetime default NULL, last_notify datetime default NULL, solved_count int(11) NOT NULL default '0', static_solved int(11) default NULL, solved_1 int(11) default NULL, solved_2 int(11) default NULL, solved_3 int(11) default NULL, solved_4 int(11) default NULL, solved_5 int(11) default NULL, expires datetime default NULL, notes text, assigned_to smallint(6) default NULL, assigned_group smallint(6) default NULL, last_edited_by smallint(6) default NULL, orig_ref_no varchar(15) binary default NULL, c$fundstate smallint(6) default NULL, c$contributor smallint(6) default NULL, UNIQUE KEY t1$faq_id (faq_id), KEY t1$group_id$faq_id (faq_group_id,faq_id), KEY t1$c$fundstate (c$fundstate) ) TYPE=MyISAM;
+INSERT INTO t1 VALUES (82,82,'How to use the DynaVox Usage Counts Feature','usages count, number, corner, white, box, button','<as-html>\r\n<table width=\"100%\" border=\"0\">\r\n <tr>\r\n <td width=\"3%\"> </td>\r\n <td width=\"97%\">\r\n <h3><font face=\"Verdana, Arial, Helvetica, sans-serif\" color=\"#000000\">How \r\n To</font><!-- #BeginEditable \"CS_troubleshoot_question\" --><font face=\"Verdana, Arial, Helvetica, sans-serif\" color=\"#000099\"><font color=\"#000000\">: \r\n Display or Hide the Usage Counts to find out how many times each button is being selected. </font></font><!-- #EndEditable --></h3>\r\n </td>\r\n </tr>\r\n</table>','<as-html>\r\n <table width=\"100%\" border=\"0\">\r\n <tr>\r\n <td width=\"3%\"> </td>\r\n \r\n<td width=\"97%\"><!-- #BeginEditable \"CS_troubleshoot_answer\" --> \r\n \r\n<p><font color=\"#000000\" face=\"Verdana, Arial, Helvetica, sans-serif\">1. Select \r\n the <i>On/Setup</i> button to access the DynaVox Setup Menu.<br>\r\n 2. Select <b>Button Features.</b><br>\r\n 3. Below the <b>OK</b> button is the <b>Usage Counts</b> button.<br>\r\n a. If it says \"Hidden\" then the Usage Counts will not be displayed.<br>\r\n b. If it says \"Displayed\" then the Usage Counts will be shown.<br>\r\n c. Select the <b>Usage Counts</b> Option Ring once and it will toggle \r\n to the alternative option.<br>\r\n 4. Once the correct setting has been chosen, select <b>OK</b> to leave the <i>Button \r\n Features</i> menu.<br>\r\n 5. Select <b>OK</b> out of the <i>Setup</i> menu and return to the communication \r\n page.</font></p>\r\n <p><font color=\"#000000\" face=\"Verdana, Arial, Helvetica, sans-serif\">For \r\n further information on <i>Usage Counts,</i> see the <i>Button Features \r\n Menu Entry</i> in the DynaVox/DynaMyte Reference Manual.</font></p>\r\n<!-- #EndEditable --></td>\r\n </tr>\r\n</table>',4,1,1,'2001-11-16 16:43:34','2002-11-25 12:09:43','2003-07-24 01:04:48',NULL,11,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,11,NULL,NULL,NULL);
+CREATE TABLE t2 ( access_id smallint(6) NOT NULL default '0', name varchar(20) binary default NULL, rank smallint(6) NOT NULL default '0', KEY t2$access_id (access_id) ) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,'Everyone',2),(2,'Help',3),(3,'Customer Support',1);
+SELECT f_acc.rank, a1.rank, a2.rank FROM t1 LEFT JOIN t1 f1 ON (f1.access_id=1 AND f1.faq_group_id = t1.faq_group_id) LEFT JOIN t2 a1 ON (a1.access_id = f1.access_id) LEFT JOIN t1 f2 ON (f2.access_id=3 AND f2.faq_group_id = t1.faq_group_id) LEFT JOIN t2 a2 ON (a2.access_id = f2.access_id), t2 f_acc WHERE LEAST(a1.rank,a2.rank) = f_acc.rank;
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index e267339d64c..99824ab121d 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -1,7 +1,7 @@
#
# time functions
#
-drop table if exists t1,t2;
+drop table if exists t1,t2,t3;
select from_days(to_days("960101")),to_days(960201)-to_days("19960101"),to_days(date_add(curdate(), interval 1 day))-to_days(curdate()),weekday("1997-11-29");
select period_add("9602",-12),period_diff(199505,"9404") ;
@@ -12,6 +12,8 @@ select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
select sec_to_time(time_to_sec('-838:59:59'));
select now()-curdate()*1000000-curtime();
select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
+select strcmp(localtime(),concat(current_date()," ",current_time()));
+select strcmp(localtimestamp(),concat(current_date()," ",current_time()));
select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w");
select date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w"));
select dayofmonth("1997-01-02"),dayofmonth(19970323);
@@ -19,13 +21,42 @@ select month("1997-01-02"),year("98-02-03"),dayofyear("1997-12-31");
select month("2001-02-00"),year("2001-00-00");
select DAYOFYEAR("1997-03-03"), WEEK("1998-03-03"), QUARTER(980303);
select HOUR("1997-03-03 23:03:22"), MINUTE("23:03:22"), SECOND(230322);
+
+# Test of week and yearweek
select week(19980101),week(19970101),week(19980101,1),week(19970101,1);
select week(19981231),week(19971231),week(19981231,1),week(19971231,1);
select week(19950101),week(19950101,1);
select yearweek('1981-12-31',1),yearweek('1982-01-01',1),yearweek('1982-12-31',1),yearweek('1983-01-01',1);
+select yearweek('1987-01-01',1),yearweek('1987-01-01');
+select week("2000-01-01",0) as '2000', week("2001-01-01",0) as '2001', week("2002-01-01",0) as '2002',week("2003-01-01",0) as '2003', week("2004-01-01",0) as '2004', week("2005-01-01",0) as '2005', week("2006-01-01",0) as '2006';
+select week("2000-01-06",0) as '2000', week("2001-01-06",0) as '2001', week("2002-01-06",0) as '2002',week("2003-01-06",0) as '2003', week("2004-01-06",0) as '2004', week("2005-01-06",0) as '2005', week("2006-01-06",0) as '2006';
+select week("2000-01-01",1) as '2000', week("2001-01-01",1) as '2001', week("2002-01-01",1) as '2002',week("2003-01-01",1) as '2003', week("2004-01-01",1) as '2004', week("2005-01-01",1) as '2005', week("2006-01-01",1) as '2006';
+select week("2000-01-06",1) as '2000', week("2001-01-06",1) as '2001', week("2002-01-06",1) as '2002',week("2003-01-06",1) as '2003', week("2004-01-06",1) as '2004', week("2005-01-06",1) as '2005', week("2006-01-06",1) as '2006';
+select yearweek("2000-01-01",0) as '2000', yearweek("2001-01-01",0) as '2001', yearweek("2002-01-01",0) as '2002',yearweek("2003-01-01",0) as '2003', yearweek("2004-01-01",0) as '2004', yearweek("2005-01-01",0) as '2005', yearweek("2006-01-01",0) as '2006';
+select yearweek("2000-01-06",0) as '2000', yearweek("2001-01-06",0) as '2001', yearweek("2002-01-06",0) as '2002',yearweek("2003-01-06",0) as '2003', yearweek("2004-01-06",0) as '2004', yearweek("2005-01-06",0) as '2005', yearweek("2006-01-06",0) as '2006';
+select yearweek("2000-01-01",1) as '2000', yearweek("2001-01-01",1) as '2001', yearweek("2002-01-01",1) as '2002',yearweek("2003-01-01",1) as '2003', yearweek("2004-01-01",1) as '2004', yearweek("2005-01-01",1) as '2005', yearweek("2006-01-01",1) as '2006';
+select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', yearweek("2002-01-06",1) as '2002',yearweek("2003-01-06",1) as '2003', yearweek("2004-01-06",1) as '2004', yearweek("2005-01-06",1) as '2005', yearweek("2006-01-06",1) as '2006';
+select week(19981231,2), week(19981231,3), week(20000101,2), week(20000101,3);
+select week(20001231,2),week(20001231,3);
+
+select week(19981231,0) as '0', week(19981231,1) as '1', week(19981231,2) as '2', week(19981231,3) as '3', week(19981231,4) as '4', week(19981231,5) as '5', week(19981231,6) as '6', week(19981231,7) as '7';
+select week(20000101,0) as '0', week(20000101,1) as '1', week(20000101,2) as '2', week(20000101,3) as '3', week(20000101,4) as '4', week(20000101,5) as '5', week(20000101,6) as '6', week(20000101,7) as '7';
+select week(20000106,0) as '0', week(20000106,1) as '1', week(20000106,2) as '2', week(20000106,3) as '3', week(20000106,4) as '4', week(20000106,5) as '5', week(20000106,6) as '6', week(20000106,7) as '7';
+select week(20001231,0) as '0', week(20001231,1) as '1', week(20001231,2) as '2', week(20001231,3) as '3', week(20001231,4) as '4', week(20001231,5) as '5', week(20001231,6) as '6', week(20001231,7) as '7';
+select week(20010101,0) as '0', week(20010101,1) as '1', week(20010101,2) as '2', week(20010101,3) as '3', week(20010101,4) as '4', week(20010101,5) as '5', week(20010101,6) as '6', week(20010101,7) as '7';
+
+select yearweek(20001231,0), yearweek(20001231,1), yearweek(20001231,2), yearweek(20001231,3), yearweek(20001231,4), yearweek(20001231,5), yearweek(20001231,6), yearweek(20001231,7);
+
+set default_week_format = 6;
+select week(20001231), week(20001231,6);
+set default_week_format = 0;
+
+set default_week_format = 2;
+select week(20001231),week(20001231,2),week(20001231,0);
+set default_week_format = 0;
+
select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v');
select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v');
-select yearweek('1987-01-01',1),yearweek('1987-01-01');
select dayname("1962-03-03"),dayname("1962-03-03")+0;
select monthname("1972-03-04"),monthname("1972-03-04")+0;
@@ -108,6 +139,8 @@ select extract(MONTH FROM "2001-02-00");
create table t1 (ctime varchar(20));
insert into t1 values ('2001-01-12 12:23:40');
select ctime, hour(ctime) from t1;
+# test bug 614 (multiple extracts in where)
+select ctime from t1 where extract(MONTH FROM ctime) = 1 AND extract(YEAR FROM ctime) = 2001;
drop table t1;
#
@@ -168,3 +201,10 @@ select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2;
select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2;
select * from t1, t3 where t1.start between t3.ctime1 and t3.ctime2;
drop table t1,t2,t3;
+
+#
+# Test unix timestamp
+#
+select @a:=FROM_UNIXTIME(1);
+select unix_timestamp(@a);
+select unix_timestamp('1969-12-01 19:00:01');
diff --git a/mysql-test/t/gemini.test b/mysql-test/t/gemini.test
deleted file mode 100644
index 9d4451c3551..00000000000
--- a/mysql-test/t/gemini.test
+++ /dev/null
@@ -1,355 +0,0 @@
--- source include/have_gemini.inc
-
-#
-# Small basic test with ignore
-#
-
-drop table if exists t1;
-create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=gemini;
-
-insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
-select id, code, name from t1 order by id;
-
-update ignore t1 set id = 8, name = 'Sinisa' where id < 3;
-select id, code, name from t1 order by id;
-update ignore t1 set id = id + 10, name = 'Ralph' where id < 4;
-select id, code, name from t1 order by id;
-
-drop table t1;
-
-#
-# A bit bigger test
-#
-
-CREATE TABLE t1 (
- id int(11) NOT NULL auto_increment,
- parent_id int(11) DEFAULT '0' NOT NULL,
- level tinyint(4) DEFAULT '0' NOT NULL,
- PRIMARY KEY (id),
- KEY parent_id (parent_id),
- KEY level (level)
-) type=gemini;
-INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
-update t1 set parent_id=parent_id+100;
-select * from t1 where parent_id=102;
-update t1 set id=id+1000;
-!$1062 update t1 set id=1024 where id=1009;
-select * from t1;
-update ignore t1 set id=id+1; # This will change all rows
-select * from t1;
-update ignore t1 set id=1023 where id=1010;
-select * from t1 where parent_id=102;
-explain select level from t1 where level=1;
-explain select level,id from t1 where level=1;
-explain select level,id,parent_id from t1 where level=1;
-select level,id from t1 where level=1;
-select level,id,parent_id from t1 where level=1;
-drop table t1;
-
-#
-# Test replace
-#
-
-CREATE TABLE t1 (
- gesuchnr int(11) DEFAULT '0' NOT NULL,
- benutzer_id int(11) DEFAULT '0' NOT NULL,
- PRIMARY KEY (gesuchnr,benutzer_id)
-) type=gemini;
-
-replace into t1 (gesuchnr,benutzer_id) values (2,1);
-replace into t1 (gesuchnr,benutzer_id) values (1,1);
-replace into t1 (gesuchnr,benutzer_id) values (1,1);
-select * from t1;
-drop table t1;
-
-#
-# test delete using hidden_primary_key
-#
-
-create table t1 (a int) type=gemini;
-insert into t1 values (1), (2);
-delete from t1 where a = 1;
-select * from t1;
-drop table t1;
-
-#
-# Test auto_increment on sub key
-#
-
-#create table t1 (a char(10) not null, b int not null auto_increment, primary key(a,b)) type=gemini;
-#insert into t1 values ("a",1),("b",2),("a",2),("c",1);
-#insert into t1 values ("a",NULL),("b",NULL),("c",NULL),("e",NULL);
-#insert into t1 (a) values ("a"),("b"),("c"),("d");
-#insert into t1 (a) values ('k'),('d');
-#insert into t1 (a) values ("a");
-#insert into t1 values ("d",last_insert_id());
-#select * from t1;
-#drop table t1;
-
-#
-# Test when reading on part of unique key
-#
-CREATE TABLE t1 (
- user_id int(10) DEFAULT '0' NOT NULL,
- name varchar(100),
- phone varchar(100),
- ref_email varchar(100) DEFAULT '' NOT NULL,
- detail varchar(200),
- PRIMARY KEY (user_id,ref_email)
-)type=gemini;
-
-INSERT INTO t1 VALUES (10292,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10292,'shirish','2333604','shirish@yahoo.com','ddsds'),(10292,'sonali','323232','sonali@bolly.com','filmstar');
-select * from t1 where user_id=10292;
-INSERT INTO t1 VALUES (10291,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10293,'shirish','2333604','shirish@yahoo.com','ddsds');
-select * from t1 where user_id=10292;
-select * from t1 where user_id>=10292;
-select * from t1 where user_id>10292;
-select * from t1 where user_id<10292;
-drop table t1;
-
-#
-# Test that keys are created in right order
-# - Needs ANALYZE TABLE to work - MikeF 2/12/01
-#
-#CREATE TABLE t1 (a int not null, b int not null,c int not null,
-#key(a),primary key(a,b), unique(c),key(a),unique(b)) type = gemini;
-#show index from t1;
-#drop table t1;
-
-#
-# Test of ALTER TABLE and gemini tables
-#
-
-#create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
-#alter table t1 type=gemini;
-#insert into t1 values ('1','1'),('5','2'),('2','3'),('3','4'),('4','4');
-#select * from t1;
-#update t1 set col2='7' where col1='4';
-#select * from t1;
-#alter table t1 add co3 int not null;
-#select * from t1;
-#update t1 set col2='9' where col1='2';
-#select * from t1;
-#drop table t1;
-
-#
-# INSERT INTO gemini tables
-#
-
-create table t1 (a int not null , b int, primary key (a)) type = gemini;
-create table t2 (a int not null , b int, primary key (a)) type = myisam;
-insert into t1 VALUES (1,3) , (2,3), (3,3);
-select * from t1;
-insert into t2 select * from t1;
-select * from t2;
-delete from t1 where b = 3;
-select * from t1;
-insert into t1 select * from t2;
-select * from t1;
-select * from t2;
-drop table t1,t2;
-
-#
-# Search on unique key
-#
-
-CREATE TABLE t1 (
- id int(11) NOT NULL auto_increment,
- ggid varchar(32) binary DEFAULT '' NOT NULL,
- email varchar(64) DEFAULT '' NOT NULL,
- passwd varchar(32) binary DEFAULT '' NOT NULL,
- PRIMARY KEY (id),
- UNIQUE ggid (ggid)
-) TYPE=gemini;
-
-insert into t1 (ggid,passwd) values ('test1','xxx');
-insert into t1 (ggid,passwd) values ('test2','yyy');
-
-select * from t1 where ggid='test1';
-select * from t1 where passwd='xxx';
-select * from t1 where id=2;
-drop table t1;
-
-#
-# ORDER BY on not primary key
-#
-
-#CREATE TABLE t1 (
-# user_name varchar(12),
- #password text,
- #subscribed char(1),
- #user_id int(11) DEFAULT '0' NOT NULL,
- #quota bigint(20),
- #weight double,
- #access_date date,
- #access_time time,
- #approved datetime,
- #dummy_primary_key int(11) NOT NULL auto_increment,
- #PRIMARY KEY (dummy_primary_key)
-#) TYPE=gemini;
-#INSERT INTO t1 VALUES ('user_0','somepassword','N',0,0,0,'2000-09-07','23:06:59','2000-09-07 23:06:59',1);
-#INSERT INTO t1 VALUES ('user_1','somepassword','Y',1,1,1,'2000-09-07','23:06:59','2000-09-07 23:06:59',2);
-#INSERT INTO t1 VALUES ('user_2','somepassword','N',2,2,1.4142135623731,'2000-09-07','23:06:59','2000-09-07 23:06:59',3);
-#INSERT INTO t1 VALUES ('user_3','somepassword','Y',3,3,1.7320508075689,'2000-09-07','23:06:59','2000-09-07 23:06:59',4);
-#INSERT INTO t1 VALUES ('user_4','somepassword','N',4,4,2,'2000-09-07','23:06:59','2000-09-07 23:06:59',5);
-#select user_name, password , subscribed, user_id, quota, weight, access_date, access_time, approved, dummy_primary_key from t1 order by user_name;
-#drop table t1;
-
-#
-# Testing of tables without primary keys
-#
-
-CREATE TABLE t1 (
- id int(11) NOT NULL auto_increment,
- parent_id int(11) DEFAULT '0' NOT NULL,
- level tinyint(4) DEFAULT '0' NOT NULL,
- KEY (id),
- KEY parent_id (parent_id),
- KEY level (level)
-) type=gemini;
-INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1);
-INSERT INTO t1 values (179,5,2);
-update t1 set parent_id=parent_id+100;
-select * from t1 where parent_id=102;
-update t1 set id=id+1000;
-update t1 set id=1024 where id=1009;
-select * from t1;
-update ignore t1 set id=id+1; # This will change all rows
-select * from t1;
-update ignore t1 set id=1023 where id=1010;
-select * from t1 where parent_id=102;
-explain select level from t1 where level=1;
-select level,id from t1 where level=1;
-select level,id,parent_id from t1 where level=1;
-select level,id from t1 where level=1 order by id;
-delete from t1 where level=1;
-select * from t1;
-drop table t1;
-
-#
-# Test of index only reads
-#
-CREATE TABLE t1 (
- sca_code char(6) NOT NULL,
- cat_code char(6) NOT NULL,
- sca_desc varchar(50),
- lan_code char(2) NOT NULL,
- sca_pic varchar(100),
- sca_sdesc varchar(50),
- sca_sch_desc varchar(16),
- PRIMARY KEY (sca_code, cat_code, lan_code)
-) type = gemini ;
-
-INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING');
-select count(*) from t1 where sca_code = 'PD';
-drop table t1;
-
-#
-# Test of opening table twice
-#
-CREATE TABLE t1 (a int not null, primary key (a)) type=gemini;
-insert into t1 values(1),(2),(3);
-select t1.a from t1 natural join t1 as t2 order by t1.a;
-drop table t1;
-
-#
-# Test rollback
-#
-
-select "test for rollback";
-create table t1 (n int not null primary key) type=gemini;
-set autocommit=0;
-insert into t1 values (4);
-commit;
-insert into t1 values (5);
-rollback;
-select n, "after rollback" from t1;
-insert into t1 values (5);
-commit;
-select n, "after commit" from t1;
-commit;
-insert into t1 values (6);
-!$1062 insert into t1 values (4);
-commit;
-select n, "after commit" from t1;
-set autocommit=1;
-insert into t1 values (7);
-!$1062 insert into t1 values (4);
-select n from t1;
-# nop
-rollback;
-drop table t1;
-
-#
-# Testing transactions
-#
-
-create table t1 ( id int NOT NULL PRIMARY KEY, nom varchar(64)) type=gemini;
-insert into t1 values(1,'first');
-begin;
-insert into t1 values(2,'hamdouni');
-select id as afterbegin_id,nom as afterbegin_nom from t1;
-rollback;
-select id as afterrollback_id,nom as afterrollback_nom from t1;
-set autocommit=0;
-insert into t1 values(3,'mysql');
-select id as afterautocommit0_id,nom as afterautocommit0_nom from t1;
-rollback;
-select id as afterrollback_id,nom as afterrollback_nom from t1;
-set autocommit=1;
-drop table t1;
-
-#
-# Simple not autocommit test
-#
-
-CREATE TABLE t1 (id char(8) not null primary key, val int not null) type=gemini;
-insert into t1 values ('pippo', 12);
-!$1062 insert into t1 values ('pippo', 12); # Gives error
-delete from t1;
-delete from t1 where id = 'pippo';
-select * from t1;
-
-insert into t1 values ('pippo', 12);
-set autocommit=0;
-delete from t1;
-rollback;
-select * from t1;
-delete from t1;
-commit;
-select * from t1;
-drop table t1;
-set autocommit=1;
-
-#
-# The following simple tests failed at some point
-#
-
-CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR(64)) TYPE=gemini;
-INSERT INTO t1 VALUES (1, 'Jochen');
-select * from t1;
-drop table t1;
-
-CREATE TABLE t1 ( _userid VARCHAR(60) NOT NULL PRIMARY KEY) TYPE=gemini;
-set autocommit=0;
-INSERT INTO t1 SET _userid='marc@anyware.co.uk';
-COMMIT;
-SELECT * FROM t1;
-SELECT _userid FROM t1 WHERE _userid='marc@anyware.co.uk';
-drop table t1;
-set autocommit=1;
-
-#
-# Test of load data infile
-#
-
-CREATE TABLE if not exists `t1` (
- `f1` int(11) unsigned NOT NULL default '0',
- `f2` tinyint(3) unsigned NOT NULL default '0',
- `f3` tinyint(3) unsigned NOT NULL default '0',
- PRIMARY KEY (`f1`)
-) TYPE=Gemini;
-lock table t1 write;
-load data infile ''../../std_data/gemini.dat' ignore into table t1 fields terminated by ',';
-select f1 from t1;
-drop table t1;
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
new file mode 100644
index 00000000000..598a7186a6e
--- /dev/null
+++ b/mysql-test/t/grant.test
@@ -0,0 +1,91 @@
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+#
+# Test that SSL options works properly
+#
+
+delete from mysql.user where user='mysqltest_1';
+delete from mysql.db where user='mysqltest_1';
+flush privileges;
+grant select on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA";
+show grants for mysqltest_1@localhost;
+grant delete on mysqltest.* to mysqltest_1@localhost;
+select * from mysql.user where user="mysqltest_1";
+show grants for mysqltest_1@localhost;
+revoke delete on mysqltest.* from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+grant select on mysqltest.* to mysqltest_1@localhost require NONE;
+show grants for mysqltest_1@localhost;
+grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "MySQL AB";
+show grants for mysqltest_1@localhost;
+revoke all privileges on mysqltest.* from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+delete from mysql.user where user='mysqltest_1';
+flush privileges;
+
+#
+# Test that the new db privileges are stored/retrieved correctly
+#
+
+grant CREATE TEMPORARY TABLES, LOCK TABLES on mysqltest.* to mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+flush privileges;
+show grants for mysqltest_1@localhost;
+revoke CREATE TEMPORARY TABLES on mysqltest.* from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+grant ALL PRIVILEGES on mysqltest.* to mysqltest_1@localhost with GRANT OPTION;
+flush privileges;
+show grants for mysqltest_1@localhost;
+revoke LOCK TABLES, ALTER on mysqltest.* from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+revoke all privileges on mysqltest.* from mysqltest_1@localhost;
+delete from mysql.user where user='mysqltest_1';
+flush privileges;
+grant usage on test.* to mysqltest_1@localhost with grant option;
+show grants for mysqltest_1@localhost;
+delete from mysql.user where user='mysqltest_1';
+delete from mysql.db where user='mysqltest_1';
+delete from mysql.tables_priv where user='mysqltest_1';
+delete from mysql.columns_priv where user='mysqltest_1';
+flush privileges;
+
+#
+# Test what happens when you have same table and colum level grants
+#
+
+create table t1 (a int);
+GRANT select,update,insert on t1 to mysqltest_1@localhost;
+GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
+REVOKE select (a), update on t1 from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+REVOKE select,update,insert,insert (a) on t1 from mysqltest_1@localhost;
+show grants for mysqltest_1@localhost;
+GRANT select,references on t1 to mysqltest_1@localhost;
+select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
+grant all on test.* to mysqltest_3@localhost with grant option;
+revoke all on test.* from mysqltest_3@localhost;
+show grants for mysqltest_3@localhost;
+revoke grant option on test.* from mysqltest_3@localhost;
+show grants for mysqltest_3@localhost;
+grant all on test.t1 to mysqltest_2@localhost with grant option;
+revoke all on test.t1 from mysqltest_2@localhost;
+show grants for mysqltest_2@localhost;
+revoke grant option on test.t1 from mysqltest_2@localhost;
+show grants for mysqltest_2@localhost;
+delete from mysql.user where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.db where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.tables_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+delete from mysql.columns_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3";
+flush privileges;
+drop table t1;
+
+#
+# Test some error conditions
+#
+--error 1221
+GRANT FILE on mysqltest.* to mysqltest_1@localhost;
+select 1; -- To test that the previous command didn't cause problems
diff --git a/mysql-test/t/grant_cache-master.opt b/mysql-test/t/grant_cache-master.opt
new file mode 100644
index 00000000000..cfdce628e74
--- /dev/null
+++ b/mysql-test/t/grant_cache-master.opt
@@ -0,0 +1 @@
+--set-variable=query_cache_size=1355776
diff --git a/mysql-test/t/grant_cache.test b/mysql-test/t/grant_cache.test
new file mode 100644
index 00000000000..95989d1ee99
--- /dev/null
+++ b/mysql-test/t/grant_cache.test
@@ -0,0 +1,112 @@
+-- source include/have_query_cache.inc
+
+drop table if exists test.t1,mysqltest.t1,mysqltest.t2;
+drop database if exists mysqltest;
+
+#
+# Test grants with query cache
+#
+
+reset query cache;
+flush status;
+connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock);
+connection root;
+create database if not exists mysqltest;
+
+create table mysqltest.t1 (a int,b int,c int);
+create table mysqltest.t2 (a int,b int,c int);
+insert into mysqltest.t1 values (1,1,1),(2,2,2);
+insert into mysqltest.t2 values (3,3,3);
+create table test.t1 (a char (10));
+insert into test.t1 values ("test.t1");
+select * from t1;
+connect (root2,localhost,root,,mysqltest,$MASTER_MYPORT,master.sock);
+connection root2;
+# put queries in cache
+select * from t1;
+select a from t1;
+select c from t1;
+select * from t2;
+select * from mysqltest.t1,test.t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits%";
+
+# Create the test users
+grant SELECT on mysqltest.* to mysqltest_1@localhost;
+grant SELECT on mysqltest.t1 to mysqltest_2@localhost;
+grant SELECT on test.t1 to mysqltest_2@localhost;
+grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost;
+
+# The following queries should be fetched from cache
+connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,master.sock);
+connection user1;
+select "user1";
+select * from t1;
+# The pre and end space are intentional
+ select a from t1 ;
+select c from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_not_cached";
+
+# The following queries should be fetched from cache
+connect (user2,localhost,mysqltest_2,,mysqltest,$MASTER_MYPORT,master.sock);
+connection user2;
+select "user2";
+select * from t1;
+select a from t1;
+select c from t1;
+select * from mysqltest.t1,test.t1;
+--replace_result 127.0.0.1 localhost
+--error 1142
+select * from t2;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_not_cached";
+
+# The following queries should not be fetched from cache
+connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,master.sock);
+connection user3;
+select "user3";
+--replace_result 127.0.0.1 localhost
+--error 1143
+select * from t1;
+select a from t1;
+--replace_result 127.0.0.1 localhost
+--error 1143
+select c from t1;
+--replace_result 127.0.0.1 localhost
+--error 1142
+select * from t2;
+--replace_result 127.0.0.1 localhost
+--error 1143
+select mysqltest.t1.c from test.t1,mysqltest.t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_not_cached";
+
+# Connect without a database
+connect (user4,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,master.sock);
+connection user4;
+select "user4";
+--error 1046
+select a from t1;
+# The following query is not cached before (different database)
+select * from mysqltest.t1,test.t1;
+# Cache a query with 'no database'
+select a from mysqltest.t1;
+select a from mysqltest.t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+show status like "Qcache_not_cached";
+
+# Cleanup
+
+connection root;
+delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.tables_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+delete from mysql.columns_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
+flush privileges;
+drop table test.t1,mysqltest.t1,mysqltest.t2;
+drop database mysqltest;
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index 20e11713d31..58bb4b3e268 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -17,7 +17,7 @@ INSERT INTO t1 VALUES (2,1,1,'','0000-00-00');
INSERT INTO t1 VALUES (3,3,3,'','0000-00-00');
CREATE TABLE t2 (
- userID int(10) unsigned DEFAULT '0' NOT NULL auto_increment,
+ userID int(10) unsigned NOT NULL auto_increment,
niName char(15),
passwd char(8),
mail char(50),
@@ -34,10 +34,15 @@ CREATE TABLE t2 (
INSERT INTO t2 VALUES (1,'name','pass','mail','Y','v','n','adr','1','1','1');
INSERT INTO t2 VALUES (2,'name','pass','mail','Y','v','n','adr','1','1','1');
INSERT INTO t2 VALUES (3,'name','pass','mail','Y','v','n','adr','1','1','1');
+INSERT INTO t2 VALUES (4,'name','pass','mail','Y','v','n','adr','1','1','1');
+INSERT INTO t2 VALUES (5,'name','pass','mail','Y','v','n','adr','1','1','1');
SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID GROUP BY t2.userid;
+SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID GROUP BY t2.userid ORDER BY NULL;
SELECT t2.userid, MIN(t1.score) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid;
SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid;
+SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid ORDER BY NULL;
+EXPLAIN SELECT t2.userid, MIN(t1.score+0.0) FROM t1, t2 WHERE t1.userID=t2.userID AND t1.spID=2 GROUP BY t2.userid ORDER BY NULL;
drop table test.t1,test.t2;
#
@@ -45,7 +50,7 @@ drop table test.t1,test.t2;
#
CREATE TABLE t1 (
- PID int(10) unsigned DEFAULT '0' NOT NULL auto_increment,
+ PID int(10) unsigned NOT NULL auto_increment,
payDate date DEFAULT '0000-00-00' NOT NULL,
recDate datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
URID int(10) unsigned DEFAULT '0' NOT NULL,
@@ -66,7 +71,8 @@ CREATE TABLE t1 (
INSERT INTO t1 VALUES (1,'1970-01-01','1997-10-17 00:00:00',2529,1,21000,11886,'check',0,'F',16200,6);
-!$1056 SELECT COUNT(P.URID),SUM(P.amount),P.method, MIN(PP.recdate+0) > 19980501000000 AS IsNew FROM t1 AS P JOIN t1 as PP WHERE P.URID = PP.URID GROUP BY method,IsNew;
+--error 1056
+SELECT COUNT(P.URID),SUM(P.amount),P.method, MIN(PP.recdate+0) > 19980501000000 AS IsNew FROM t1 AS P JOIN t1 as PP WHERE P.URID = PP.URID GROUP BY method,IsNew;
drop table t1;
@@ -76,7 +82,7 @@ drop table t1;
#
CREATE TABLE t1 (
- cid mediumint(9) DEFAULT '0' NOT NULL auto_increment,
+ cid mediumint(9) NOT NULL auto_increment,
firstname varchar(32) DEFAULT '' NOT NULL,
surname varchar(32) DEFAULT '' NOT NULL,
PRIMARY KEY (cid)
@@ -85,7 +91,7 @@ INSERT INTO t1 VALUES (1,'That','Guy');
INSERT INTO t1 VALUES (2,'Another','Gent');
CREATE TABLE t2 (
- call_id mediumint(8) DEFAULT '0' NOT NULL auto_increment,
+ call_id mediumint(8) NOT NULL auto_increment,
contact_id mediumint(8) DEFAULT '0' NOT NULL,
PRIMARY KEY (call_id),
KEY contact_id (contact_id)
@@ -100,6 +106,7 @@ INSERT INTO t2 VALUES (91,2);
INSERT INTO t2 VALUES (92,2);
SELECT cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid;
+SELECT cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid ORDER BY NULL;
SELECT HIGH_PRIORITY cid, CONCAT(firstname, ' ', surname), COUNT(call_id) FROM t1 LEFT JOIN t2 ON cid=contact_id WHERE firstname like '%foo%' GROUP BY cid ORDER BY surname, firstname;
drop table t1,t2;
@@ -110,7 +117,7 @@ unlock tables;
#
CREATE TABLE t1 (
- bug_id mediumint(9) DEFAULT '0' NOT NULL auto_increment,
+ bug_id mediumint(9) NOT NULL auto_increment,
groupset bigint(20) DEFAULT '0' NOT NULL,
assigned_to mediumint(9) DEFAULT '0' NOT NULL,
bug_file_loc text,
@@ -232,36 +239,87 @@ CREATE TABLE t1 (
key (score)
);
-INSERT INTO t1 VALUES (1,1,1),(2,2,2),(2,1,1),(3,3,3),(4,3,3),(5,3,3);
+INSERT INTO t1 VALUES (1,1,1),(2,2,2),(2,1,1),(3,3,3),(4,3,3),(5,3,3),(6,3,3),(7,3,3);
explain select userid,count(*) from t1 group by userid desc;
+explain select userid,count(*) from t1 group by userid desc order by null;
select userid,count(*) from t1 group by userid desc;
select userid,count(*) from t1 group by userid desc having (count(*)+1) IN (4,3);
select userid,count(*) from t1 group by userid desc having 3 IN (1,COUNT(*));
explain select spid,count(*) from t1 where spid between 1 and 2 group by spid desc;
explain select spid,count(*) from t1 where spid between 1 and 2 group by spid;
+explain select spid,count(*) from t1 where spid between 1 and 2 group by spid order by null;
select spid,count(*) from t1 where spid between 1 and 2 group by spid;
select spid,count(*) from t1 where spid between 1 and 2 group by spid desc;
explain select sql_big_result spid,sum(userid) from t1 group by spid desc;
+explain select sql_big_result spid,sum(userid) from t1 group by spid desc order by null;
select sql_big_result spid,sum(userid) from t1 group by spid desc;
explain select sql_big_result score,count(*) from t1 group by score desc;
+explain select sql_big_result score,count(*) from t1 group by score desc order by null;
select sql_big_result score,count(*) from t1 group by score desc;
drop table t1;
+
+# not purely group_by bug, but group_by is involved...
+
+create table t1 (a date default null, b date default null);
+insert t1 values ('1999-10-01','2000-01-10'), ('1997-01-01','1998-10-01');
+select a,min(b) c,count(distinct rand()) from t1 group by a having c<a + interval 1 day;
+drop table t1;
+
+# Compare with hash keys
+
+CREATE TABLE t1 (a char(1));
+INSERT INTO t1 VALUES ('A'),('B'),('A'),('B'),('A'),('B'),(NULL),('a'),('b'),(NULL),('A'),('B'),(NULL);
+SELECT a FROM t1 GROUP BY a;
+SELECT a,count(*) FROM t1 GROUP BY a;
+SELECT a FROM t1 GROUP BY binary a;
+SELECT a,count(*) FROM t1 GROUP BY binary a;
+SELECT binary a FROM t1 GROUP BY 1;
+SELECT binary a,count(*) FROM t1 GROUP BY 1;
+# Do the same tests with MyISAM temporary tables
+SET SQL_BIG_TABLES=1;
+SELECT a FROM t1 GROUP BY a;
+SELECT a,count(*) FROM t1 GROUP BY a;
+SELECT a FROM t1 GROUP BY binary a;
+SELECT a,count(*) FROM t1 GROUP BY binary a;
+SELECT binary a FROM t1 GROUP BY 1;
+SELECT binary a,count(*) FROM t1 GROUP BY 1;
+SET SQL_BIG_TABLES=0;
+drop table t1;
+
+#
+# Test of key >= 256 bytes
+#
+
+CREATE TABLE t1 (
+ `a` char(193) default NULL,
+ `b` char(63) default NULL
+);
+INSERT INTO t1 VALUES ('abc','def'),('hij','klm');
+SELECT CONCAT(a, b) FROM t1 GROUP BY 1;
+SELECT CONCAT(a, b),count(*) FROM t1 GROUP BY 1;
+SELECT CONCAT(a, b),count(distinct a) FROM t1 GROUP BY 1;
+SELECT 1 FROM t1 GROUP BY CONCAT(a, b);
+INSERT INTO t1 values ('hij','klm');
+SELECT CONCAT(a, b),count(*) FROM t1 GROUP BY 1;
+DROP TABLE t1;
drop table if exists t1;
+
+#
+# Test problem with ORDER BY on a SUM() column
+#
+
create table t1 (One int unsigned, Two int unsigned, Three int unsigned, Four int unsigned);
-insert into t1 values (1,2,1,4);
-insert into t1 values (1,2,2,4);
-insert into t1 values (1,2,3,4);
-insert into t1 values (1,2,4,4);
-insert into t1 values (1,1,1,4);
-insert into t1 values (1,1,2,4);
-insert into t1 values (1,1,3,4);
-insert into t1 values (1,1,4,4);
-insert into t1 values (1,3,1,4);
-insert into t1 values (1,3,2,4);
-insert into t1 values (1,3,3,4);
-insert into t1 values (1,3,4,4);
+insert into t1 values (1,2,1,4),(1,2,2,4),(1,2,3,4),(1,2,4,4),(1,1,1,4),(1,1,2,4),(1,1,3,4),(1,1,4,4),(1,3,1,4),(1,3,2,4),(1,3,3,4),(1,3,4,4);
select One, Two, sum(Four) from t1 group by One,Two;
-drop table if exists t1;
+drop table t1;
+
+create table t1 (id integer primary key not null auto_increment, gender char(1));
+insert into t1 values (NULL, 'M'), (NULL, 'F'),(NULL, 'F'),(NULL, 'F'),(NULL, 'M');
+create table t2 (user_id integer not null, date date);
+insert into t2 values (1, '2002-06-09'),(2, '2002-06-09'),(1, '2002-06-09'),(3, '2002-06-09'),(4, '2002-06-09'),(4, '2002-06-09');
+select u.gender as gender, count(distinct u.id) as dist_count, (count(distinct u.id)/5*100) as percentage from t1 u, t2 l where l.user_id = u.id group by u.gender;
+select u.gender as gender, count(distinct u.id) as dist_count, (count(distinct u.id)/5*100) as percentage from t1 u, t2 l where l.user_id = u.id group by u.gender order by percentage;
+drop table t1,t2;
#
# The GROUP BY returned rows in wrong order in 3.23.51
@@ -324,21 +382,26 @@ set option sql_big_tables=1;
select a,count(*) from t1 group by a;
drop table t1;
+#
+# Test of GROUP BY ... ORDER BY NULL optimization
+#
+
+create table t1 (a int not null, b int not null);
+insert into t1 values (1,1),(1,2),(3,1),(3,2),(2,2),(2,1);
+create table t2 (a int not null, b int not null, key(a));
+insert into t2 values (1,3),(3,1),(2,2),(1,1);
+select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b;
+select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b ORDER BY NULL;
+explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b;
+explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b ORDER BY NULL;
+drop table t1,t2;
#
# group function arguments in some functions
#
create table t1 (a int, b int);
-insert into t1 values (1, 4);
-insert into t1 values (10, 40);
-insert into t1 values (1, 4);
-insert into t1 values (10, 43);
-insert into t1 values (1, 4);
-insert into t1 values (10, 41);
-insert into t1 values (1, 4);
-insert into t1 values (10, 43);
-insert into t1 values (1, 4);
+insert into t1 values (1, 4),(10, 40),(1, 4),(10, 43),(1, 4),(10, 41),(1, 4),(10, 43),(1, 4);
select a, MAX(b), INTERVAL (MAX(b), 1,3,10,30,39,40,50,60,100,1000) from t1 group by a;
select a, MAX(b), CASE MAX(b) when 4 then 4 when 43 then 43 else 0 end from t1 group by a;
select a, MAX(b), FIELD(MAX(b), '43', '4', '5') from t1 group by a;
@@ -347,10 +410,40 @@ select a, MAX(b), ELT(MAX(b), 'a', 'b', 'c', 'd', 'e', 'f') from t1 group by a;
select a, MAX(b), MAKE_SET(MAX(b), 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h') from t1 group by a;
drop table t1;
-# not purely group_by bug, but group_by is involved...
+#
+# Problem with group by and alias
+#
-create table t1 (a date default null, b date default null);
-insert t1 values ('1999-10-01','2000-01-10'), ('1997-01-01','1998-10-01');
-select a,min(b) c,count(distinct rand()) from t1 group by a having c<a + interval 1 day;
+create table t1 (id int not null, qty int not null);
+insert into t1 values (1,2),(1,3),(2,4),(2,5);
+select id, sum(qty) as sqty, count(qty) as cqty from t1 group by id having sum(qty)>2 and cqty>1;
+select id, sum(qty) as sqty from t1 group by id having sqty>2 and count(qty)>1;
+select id, sum(qty) as sqty, count(qty) as cqty from t1 group by id having sqty>2 and cqty>1;
+select id, sum(qty) as sqty, count(qty) as cqty from t1 group by id having sum(qty)>2 and count(qty)>1;
+select count(*), case interval(qty,2,3,4,5,6,7,8) when -1 then NULL when 0 then "zero" when 1 then "one" when 2 then "two" end as category from t1 group by category;
+select count(*), interval(qty,2,3,4,5,6,7,8) as category from t1 group by category;
drop table t1;
-
+#
+# Tests for bug #1355: 'Using filesort' is missing in EXPLAIN when ORDER BY
+# NULL is used.
+#
+CREATE TABLE t1 (
+ userid int(10) unsigned,
+ score smallint(5) unsigned,
+ key (score)
+);
+INSERT INTO t1 VALUES (1,1),(2,2),(1,1),(3,3),(3,3),(3,3),(3,3),(3,3);
+# Here we select unordered GROUP BY into a temporary talbe,
+# and then sort it with filesort (GROUP BY in MySQL
+# implies sorted order of results)
+SELECT userid,count(*) FROM t1 GROUP BY userid DESC;
+EXPLAIN SELECT userid,count(*) FROM t1 GROUP BY userid DESC;
+DROP TABLE t1;
+CREATE TABLE t1 (
+ i int(11) default NULL,
+ j int(11) default NULL
+);
+INSERT INTO t1 VALUES (1,2),(2,3),(4,5),(3,5),(1,5),(23,5);
+SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL;
+explain SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL;
+DROP TABLE t1;
diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test
new file mode 100644
index 00000000000..936902fd9bf
--- /dev/null
+++ b/mysql-test/t/handler.test
@@ -0,0 +1,125 @@
+#
+# test of HANDLER ...
+#
+
+drop table if exists t1;
+create table t1 (a int, b char(10), key a(a), key b(a,b));
+insert into t1 values
+(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
+(14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"),
+(20,"ggg"),(21,"hhh"),(22,"iii");
+handler t1 open as t2;
+handler t2 read a first;
+handler t2 read a next;
+handler t2 read a next;
+handler t2 read a prev;
+handler t2 read a last;
+handler t2 read a prev;
+handler t2 read a prev;
+
+handler t2 read a first;
+handler t2 read a prev;
+
+handler t2 read a last;
+handler t2 read a prev;
+handler t2 read a next;
+handler t2 read a next;
+
+handler t2 read a=(15);
+handler t2 read a=(16);
+
+--error 1070
+handler t2 read a=(19,"fff");
+
+handler t2 read b=(19,"fff");
+handler t2 read b=(19,"yyy");
+handler t2 read b=(19);
+
+--error 1109
+handler t1 read a last;
+
+handler t2 read a=(11);
+handler t2 read a>=(11);
+
+handler t2 read a=(18);
+handler t2 read a>=(18);
+handler t2 read a>(18);
+handler t2 read a<=(18);
+handler t2 read a<(18);
+
+handler t2 read a first limit 5;
+handler t2 read a next limit 3;
+handler t2 read a prev limit 10;
+
+handler t2 read a>=(16) limit 4;
+handler t2 read a>=(16) limit 2,2;
+handler t2 read a last limit 3;
+
+handler t2 read a=(19);
+handler t2 read a=(19) where b="yyy";
+
+handler t2 read first;
+handler t2 read next;
+handler t2 read next;
+--error 1064
+handler t2 read last;
+handler t2 close;
+
+#
+# DROP TABLE / ALTER TABLE
+#
+handler t1 open as t2;
+drop table t1;
+create table t1 (a int);
+insert into t1 values (17);
+--error 1109
+handler t2 read first;
+handler t1 open as t2;
+alter table t1 engine=MyISAM;
+--error 1109
+handler t2 read first;
+drop table t1;
+
+#
+# test case for the bug #787
+#
+
+create table t1 (a int);
+insert into t1 values (1),(2),(3),(4),(5),(6);
+delete from t1 limit 2;
+handler t1 open;
+handler t1 read first;
+handler t1 read first limit 1,1;
+handler t1 read first limit 2,2;
+delete from t1 limit 3;
+handler t1 read first;
+drop table t1;
+
+#
+#test for #751
+#
+create table t1(a int, index(a));
+insert into t1 values (1), (2), (3);
+handler t1 open;
+--error 1054
+handler t1 read a=(W);
+--error 1210
+handler t1 read a=(a);
+drop table t1;
+
+#
+# BUG#2304
+#
+create table t1 (a char(5));
+insert into t1 values ("Ok");
+handler t1 open as t;
+handler t read first;
+use mysql;
+handler t read first;
+handler t close;
+handler test.t1 open as t;
+handler t read first;
+handler t close;
+use test;
+drop table t1;
+
diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test
index fff5415976c..cb6fa85ffde 100644
--- a/mysql-test/t/having.test
+++ b/mysql-test/t/having.test
@@ -48,3 +48,21 @@ GROUP BY e.id
HAVING chr_strand= -1 and end >= 0
AND start <= 999660;
drop table t1,t2;
+
+#
+# Test problem with having and MAX() IS NOT NULL
+#
+
+CREATE TABLE t1 (Fld1 int(11) default NULL,Fld2 int(11) default NULL);
+INSERT INTO t1 VALUES (1,10),(1,20),(2,NULL),(2,NULL),(3,50);
+select Fld1, max(Fld2) as q from t1 group by Fld1 having q is not null;
+select Fld1, max(Fld2) from t1 group by Fld1 having max(Fld2) is not null;
+select Fld1, max(Fld2) from t1 group by Fld1 having avg(Fld2) is not null;
+select Fld1, max(Fld2) from t1 group by Fld1 having std(Fld2) is not null;
+drop table t1;
+create table t1 (id int not null, qty int not null);
+insert into t1 values (1,2),(1,3),(2,4),(2,5);
+select id, sum(qty) as sqty from t1 group by id having sqty>2;
+select sum(qty) as sqty from t1 group by id having count(id) > 0;
+select sum(qty) as sqty from t1 group by id having count(distinct id) > 0;
+drop table t1;
diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test
index abb9e1fd1bc..b2de58ca083 100644
--- a/mysql-test/t/heap.test
+++ b/mysql-test/t/heap.test
@@ -17,6 +17,12 @@ select * from t1;
alter table t1 add c int not null, add key (c,a);
drop table t1;
+create table t1 (a int not null,b int not null, primary key (a)) type=memory comment="testing heaps";
+insert into t1 values(1,1),(2,2),(3,3),(4,4);
+delete from t1 where a > 0;
+select * from t1;
+drop table t1;
+
create table t1 (a int not null,b int not null, primary key (a)) type=heap comment="testing heaps";
insert into t1 values(1,1),(2,2),(3,3),(4,4);
alter table t1 modify a int not null auto_increment, type=myisam, comment="new myisam table";
@@ -100,3 +106,44 @@ update t1 set new_col=btn;
explain select * from t1 where btn="a";
explain select * from t1 where btn="a" and new_col="a";
drop table t1;
+
+#
+# Test of NULL keys
+#
+
+CREATE TABLE t1 (
+ a int default NULL,
+ b int default NULL,
+ KEY a (a),
+ UNIQUE b (b)
+) type=heap;
+INSERT INTO t1 VALUES (NULL,99),(99,NULL),(1,1),(2,2),(1,3);
+SELECT * FROM t1 WHERE a=NULL;
+explain SELECT * FROM t1 WHERE a IS NULL;
+SELECT * FROM t1 WHERE a<=>NULL;
+SELECT * FROM t1 WHERE b=NULL;
+explain SELECT * FROM t1 WHERE b IS NULL;
+SELECT * FROM t1 WHERE b<=>NULL;
+
+--error 1062
+INSERT INTO t1 VALUES (1,3);
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ a int default NULL,
+ key a (a)
+) TYPE=HEAP;
+INSERT INTO t1 VALUES (10), (10), (10);
+EXPLAIN SELECT * FROM t1 WHERE a=10;
+SELECT * FROM t1 WHERE a=10;
+DROP TABLE t1;
+
+#
+# Test when deleting all rows
+#
+
+CREATE TABLE t1 (a int not null, primary key(a)) type=heap;
+INSERT into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11);
+DELETE from t1 where a < 100;
+SELECT * from t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/init_file-master.opt b/mysql-test/t/init_file-master.opt
new file mode 100644
index 00000000000..825311dabf2
--- /dev/null
+++ b/mysql-test/t/init_file-master.opt
@@ -0,0 +1 @@
+--init-file=$MYSQL_TEST_DIR/std_data/init_file.dat
diff --git a/mysql-test/t/init_file.test b/mysql-test/t/init_file.test
new file mode 100644
index 00000000000..604d0a01794
--- /dev/null
+++ b/mysql-test/t/init_file.test
@@ -0,0 +1,7 @@
+#
+# This is a regression test for bug #2526 "--init-file crashes MySQL if it
+# contains a large select"
+#
+# See mysql-test/std_data/init_file.dat and
+# mysql-test/t/init_file-master.opt for the actual test
+#
diff --git a/mysql-test/t/innodb-deadlock.test b/mysql-test/t/innodb-deadlock.test
new file mode 100644
index 00000000000..bc2839bfb3a
--- /dev/null
+++ b/mysql-test/t/innodb-deadlock.test
@@ -0,0 +1,38 @@
+-- source include/have_innodb.inc
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+drop table if exists t1;
+
+#
+# Testing of FOR UPDATE
+#
+
+connection con1;
+create table t1 (id integer, x integer) type=INNODB;
+insert into t1 values(0, 0);
+set autocommit=0;
+SELECT * from t1 where id = 0 FOR UPDATE;
+
+connection con2;
+set autocommit=0;
+
+# The following query should hang because con1 is locking the page
+--send
+update t1 set x=2 where id = 0;
+--sleep 2;
+
+connection con1;
+update t1 set x=1 where id = 0;
+select * from t1;
+commit;
+
+connection con2;
+reap;
+commit;
+
+connection con1;
+select * from t1;
+commit;
+
+drop table t1;
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 0362ec69ebf..ec9aa83ae16 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -4,7 +4,9 @@
# Small basic test with ignore
#
-drop table if exists t1,t2;
+drop table if exists t1,t2,t3;
+drop database if exists mysqltest;
+
create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=innodb;
insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
@@ -40,13 +42,12 @@ update ignore t1 set id=id+1; # This will change all rows
select * from t1;
update ignore t1 set id=1023 where id=1010;
select * from t1 where parent_id=102;
-explain select level from t1 where level=1;
-explain select level,id from t1 where level=1;
-explain select level,id,parent_id from t1 where level=1;
+# explain select level from t1 where level=1;
+# explain select level,id from t1 where level=1;
+# explain select level,id,parent_id from t1 where level=1;
select level,id from t1 where level=1;
select level,id,parent_id from t1 where level=1;
optimize table t1;
-show keys from t1;
drop table t1;
#
@@ -84,7 +85,6 @@ select * from t1;
create index skr on t1 (a);
insert into t1 values (3,""), (4,"testing");
analyze table t1;
-show keys from t1;
drop table t1;
@@ -167,7 +167,7 @@ drop table t1;
#
create table t1 (a integer) type=innodb;
-begin;
+start transaction;
rename table t1 to t2;
create table t1 (b integer) type=innodb;
insert into t1 values (1);
@@ -222,7 +222,6 @@ drop table t1;
CREATE TABLE t1 (a int not null, b int not null,c int not null,
key(a),primary key(a,b), unique(c),key(a),unique(b));
-show index from t1;
drop table t1;
#
@@ -339,7 +338,7 @@ update ignore t1 set id=id+1; # This will change all rows
select * from t1;
update ignore t1 set id=1023 where id=1010;
select * from t1 where parent_id=102;
-explain select level from t1 where level=1;
+# explain select level from t1 where level=1;
select level,id from t1 where level=1;
select level,id,parent_id from t1 where level=1;
select level,id from t1 where level=1 order by id;
@@ -396,7 +395,6 @@ create table t1 (a varchar(100) not null, primary key(a), b int not null) type=i
insert into t1 values("hello",1),("world",2);
select * from t1 order by b desc;
optimize table t1;
-show keys from t1;
drop table t1;
#
@@ -441,7 +439,6 @@ DROP TABLE t1;
create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h int, i int, j int, k int, l int, m int, n int, o int, p int, q int, r int, s int, t int, u int, v int, w int, x int, y int, z int, a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, b1 int, b2 int, b3 int, b4 int, b5 int, b6 int) type = innodb;
insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
-explain select * from t1 where a > 0 and a < 50;
drop table t1;
#
@@ -472,15 +469,6 @@ UNLOCK TABLES;
DROP TABLE t1;
#
-# Test prefix key
-#
---error 1089
-create table t1 (a char(20), unique (a(5))) type=innodb;
-create table t1 (a char(20), index (a(5))) type=innodb;
-show create table t1;
-drop table t1;
-
-#
# Test using temporary table and auto_increment
#
@@ -515,30 +503,241 @@ select * from t1;
drop table t1;
#
+# Test DROP DATABASE
+#
+
+create database mysqltest;
+create table mysqltest.t1 (a int not null) type= innodb;
+insert into mysqltest.t1 values(1);
+create table mysqltest.t2 (a int not null) type= myisam;
+insert into mysqltest.t2 values(1);
+create table mysqltest.t3 (a int not null) type= heap;
+insert into mysqltest.t3 values(1);
+commit;
+drop database mysqltest;
+# Don't check error message
+
+#
+# Test truncate table with and without auto_commit
+#
+
+set autocommit=0;
+create table t1 (a int not null) type= innodb;
+insert into t1 values(1),(2);
+--error 1192
+truncate table t1;
+commit;
+truncate table t1;
+select * from t1;
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+commit;
+drop table t1;
+set autocommit=1;
+
+create table t1 (a int not null) type= innodb;
+insert into t1 values(1),(2);
+truncate table t1;
+insert into t1 values(1),(2);
+select * from t1;
+truncate table t1;
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+drop table t1;
+
+#
# Test of how ORDER BY works when doing it on the whole table
#
create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) type=innodb;
insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4);
-explain select * from t1 order by a;
-explain select * from t1 order by b;
-explain select * from t1 order by c;
-explain select a from t1 order by a;
-explain select b from t1 order by b;
-explain select a,b from t1 order by b;
-explain select a,b from t1;
-explain select a,b,c from t1;
drop table t1;
#
# Check describe
#
-create table t1 (testint int not null default 1) type=innodb;
+create table t1 (t int not null default 1, key (t)) type=innodb;
desc t1;
drop table t1;
#
+# Test of multi-table-delete
+#
+
+CREATE TABLE t1 (
+ number bigint(20) NOT NULL default '0',
+ cname char(15) NOT NULL default '',
+ carrier_id smallint(6) NOT NULL default '0',
+ privacy tinyint(4) NOT NULL default '0',
+ last_mod_date timestamp(14) NOT NULL,
+ last_mod_id smallint(6) NOT NULL default '0',
+ last_app_date timestamp(14) NOT NULL,
+ last_app_id smallint(6) default '-1',
+ version smallint(6) NOT NULL default '0',
+ assigned_scps int(11) default '0',
+ status tinyint(4) default '0'
+) TYPE=InnoDB;
+INSERT INTO t1 VALUES (4077711111,'SeanWheeler',90,2,20020111112846,500,00000000000000,-1,2,3,1);
+INSERT INTO t1 VALUES (9197722223,'berry',90,3,20020111112809,500,20020102114532,501,4,10,0);
+INSERT INTO t1 VALUES (650,'San Francisco',0,0,20011227111336,342,00000000000000,-1,1,24,1);
+INSERT INTO t1 VALUES (302467,'Sue\'s Subshop',90,3,20020109113241,500,20020102115111,501,7,24,0);
+INSERT INTO t1 VALUES (6014911113,'SudzCarwash',520,1,20020102115234,500,20020102115259,501,33,32768,0);
+INSERT INTO t1 VALUES (333,'tubs',99,2,20020109113440,501,20020109113440,500,3,10,0);
+CREATE TABLE t2 (
+ number bigint(20) NOT NULL default '0',
+ cname char(15) NOT NULL default '',
+ carrier_id smallint(6) NOT NULL default '0',
+ privacy tinyint(4) NOT NULL default '0',
+ last_mod_date timestamp(14) NOT NULL,
+ last_mod_id smallint(6) NOT NULL default '0',
+ last_app_date timestamp(14) NOT NULL,
+ last_app_id smallint(6) default '-1',
+ version smallint(6) NOT NULL default '0',
+ assigned_scps int(11) default '0',
+ status tinyint(4) default '0'
+) TYPE=InnoDB;
+INSERT INTO t2 VALUES (4077711111,'SeanWheeler',0,2,20020111112853,500,00000000000000,-1,2,3,1);
+INSERT INTO t2 VALUES (9197722223,'berry',90,3,20020111112818,500,20020102114532,501,4,10,0);
+INSERT INTO t2 VALUES (650,'San Francisco',90,0,20020109113158,342,00000000000000,-1,1,24,1);
+INSERT INTO t2 VALUES (333,'tubs',99,2,20020109113453,501,20020109113453,500,3,10,0);
+select * from t1;
+select * from t2;
+delete t1, t2 from t1 left join t2 on t1.number=t2.number where (t1.carrier_id=90 and t1.number=t2.number) or (t2.carrier_id=90 and t1.number=t2.number) or (t1.carrier_id=90 and t2.number is null);
+select * from t1;
+select * from t2;
+select * from t2;
+drop table t1,t2;
+
+#
+# A simple test with some isolation levels
+# TODO: Make this into a test using replication to really test how
+# this works.
+#
+
+create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=innodb;
+
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+SELECT @@tx_isolation,@@global.tx_isolation;
+insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David');
+select id, code, name from t1 order by id;
+COMMIT;
+
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+insert into t1 (code, name) values (2, 'Erik'), (3, 'Sasha');
+select id, code, name from t1 order by id;
+COMMIT;
+
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+insert into t1 (code, name) values (3, 'Jeremy'), (4, 'Matt');
+select id, code, name from t1 order by id;
+COMMIT;
+DROP TABLE t1;
+
+#
+# Test of multi-table-update
+#
+drop table if exists t1,t2;
+create table t1 (n int(10), d int(10)) type=innodb;
+create table t2 (n int(10), d int(10)) type=innodb;
+insert into t1 values(1,1),(1,2);
+insert into t2 values(1,10),(2,20);
+UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+select * from t1;
+select * from t2;
+drop table t1,t2;
+
+#
+# Testing of IFNULL
+#
+create table t1 (a int, b int) type=innodb;
+insert into t1 values(20,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a;
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+insert into t1 values(10,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+drop table t1;
+
+#
+# Test of read_through not existing const_table
+#
+
+create table t1 (a varchar(10) not null) type=myisam;
+create table t2 (b varchar(10) not null unique) type=innodb;
+select t1.a from t1,t2 where t1.a=t2.b;
+drop table t1,t2;
+create table t1 (a int not null, b int, primary key (a)) type = innodb;
+create table t2 (a int not null, b int, primary key (a)) type = innodb;
+insert into t1 values (10, 20);
+insert into t2 values (10, 20);
+update t1, t2 set t1.b = 150, t2.b = t1.b where t2.a = t1.a and t1.a = 10;
+drop table t1,t2;
+
+#
+# Test of multi-table-delete with foreign key constraints
+#
+
+CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
+CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE ) TYPE=INNODB;
+insert into t1 set id=1;
+insert into t2 set id=1, t1_id=1;
+delete t1,t2 from t1,t2 where t1.id=t2.t1_id;
+select * from t1;
+select * from t2;
+drop table t2,t1;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1(id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
+CREATE TABLE t2(id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id) ) TYPE=INNODB;
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1, 1);
+SELECT * from t1;
+UPDATE t1,t2 SET t1.id=t1.id+1, t2.t1_id=t1.id+1;
+SELECT * from t1;
+UPDATE t1,t2 SET t1.id=t1.id+1 where t1.id!=t2.id;
+SELECT * from t1;
+DROP TABLE t1,t2;
+
+#
+# Test of range_optimizer
+#
+
+set autocommit=0;
+
+CREATE TABLE t1 (id CHAR(15) NOT NULL, value CHAR(40) NOT NULL, PRIMARY KEY(id)) TYPE=InnoDB;
+
+CREATE TABLE t2 (id CHAR(15) NOT NULL, value CHAR(40) NOT NULL, PRIMARY KEY(id)) TYPE=InnoDB;
+
+CREATE TABLE t3 (id1 CHAR(15) NOT NULL, id2 CHAR(15) NOT NULL, PRIMARY KEY(id1, id2)) TYPE=InnoDB;
+
+INSERT INTO t3 VALUES("my-test-1", "my-test-2");
+COMMIT;
+
+INSERT INTO t1 VALUES("this-key", "will disappear");
+INSERT INTO t2 VALUES("this-key", "will also disappear");
+DELETE FROM t3 WHERE id1="my-test-1";
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+SELECT * FROM t3;
+ROLLBACK;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+SELECT * FROM t3;
+SELECT * FROM t3 WHERE id1="my-test-1" LOCK IN SHARE MODE;
+COMMIT;
+set autocommit=1;
+DROP TABLE t1,t2,t3;
+
+#
# Check update with conflicting key
#
@@ -548,3 +747,134 @@ INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
UPDATE t1 set a=a+100 where b between 2 and 3 and a < 1000;
SELECT * from t1;
drop table t1;
+
+#
+# Test multi update with different join methods
+#
+
+CREATE TABLE t1 (a int not null primary key, b int not null, key (b)) type=innodb;
+CREATE TABLE t2 (a int not null primary key, b int not null, key (b)) type=innodb;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10),(11,11),(12,12);
+INSERT INTO t2 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+
+# Full join, without key
+update t1,t2 set t1.a=t1.a+100;
+select * from t1;
+
+# unique key
+update t1,t2 set t1.a=t1.a+100 where t1.a=101;
+select * from t1;
+
+# ref key
+update t1,t2 set t1.b=t1.b+10 where t1.b=2;
+select * from t1;
+
+# Range key (in t1)
+update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t1.a=t2.a+100;
+select * from t1;
+select * from t2;
+
+drop table t1,t2;
+CREATE TABLE t2 ( NEXT_T BIGINT NOT NULL PRIMARY KEY) TYPE=MyISAM;
+CREATE TABLE t1 ( B_ID INTEGER NOT NULL PRIMARY KEY) TYPE=InnoDB;
+SET AUTOCOMMIT=0;
+INSERT INTO t1 ( B_ID ) VALUES ( 1 );
+INSERT INTO t2 ( NEXT_T ) VALUES ( 1 );
+-- error 1196
+ROLLBACK;
+SELECT * FROM t1;
+drop table t1,t2;
+create table t1 ( pk int primary key, parent int not null, child int not null, index (parent) ) type = innodb;
+insert into t1 values (1,0,4), (2,1,3), (3,2,1), (4,1,2);
+select distinct parent,child from t1 order by parent;
+drop table t1;
+
+#
+# Test that MySQL priorities clustered indexes
+#
+
+create table t1 (a int not null auto_increment primary key, b int, c int, key(c)) type=innodb;
+create table t2 (a int not null auto_increment primary key, b int);
+insert into t1 (b) values (null),(null),(null),(null),(null),(null),(null);
+insert into t2 (a) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+select count(*) from t1;
+update t1 set c=a;
+drop table t1,t2;
+
+#
+# Test of UPDATE ... ORDER BY
+#
+
+create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) type=innodb;
+
+insert into t1 (id) values (null),(null),(null),(null),(null);
+update t1 set fk=69 where fk is null order by id limit 1;
+SELECT * from t1;
+drop table t1;
+
+create table t1 (a int not null, b int not null, key (a));
+insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3);
+SET @tmp=0;
+update t1 set b=(@tmp:=@tmp+1) order by a;
+update t1 set b=99 where a=1 order by b asc limit 1;
+update t1 set b=100 where a=1 order by b desc limit 2;
+update t1 set a=a+10+b where a=1 order by b;
+select * from t1 order by a,b;
+drop table t1;
+
+#
+# Test of multi-table-updates (bug #1980).
+#
+
+create table t1 ( c char(8) not null ) type=innodb;
+insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9');
+insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F');
+
+alter table t1 add b char(8) not null;
+alter table t1 add a char(8) not null;
+alter table t1 add primary key (a,b,c);
+update t1 set a=c, b=c;
+
+create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=innodb;
+insert into t2 select * from t1;
+
+delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
+drop table t1,t2;
+
+#
+# test autoincrement with TRUNCATE
+#
+
+SET AUTOCOMMIT=1;
+create table t1 (a integer auto_increment primary key) type=innodb;
+insert into t1 (a) values (NULL),(NULL);
+truncate table t1;
+insert into t1 (a) values (NULL),(NULL);
+SELECT * from t1;
+drop table t1;
+
+#
+# Test dictionary handling with spaceand quoting
+#
+
+CREATE TABLE t1 (`id 1` INT NOT NULL, PRIMARY KEY (`id 1`)) TYPE=INNODB;
+CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (`t1_id`) REFERENCES `t1`(`id 1`) ON DELETE CASCADE ) TYPE=INNODB;
+#show create table t2;
+drop table t2,t1;
diff --git a/mysql-test/t/innodb_cache-master.opt b/mysql-test/t/innodb_cache-master.opt
new file mode 100644
index 00000000000..5f0ebff98f6
--- /dev/null
+++ b/mysql-test/t/innodb_cache-master.opt
@@ -0,0 +1 @@
+--set-variable=query_cache_size=1M
diff --git a/mysql-test/t/innodb_cache.test b/mysql-test/t/innodb_cache.test
new file mode 100644
index 00000000000..9066a5f19ba
--- /dev/null
+++ b/mysql-test/t/innodb_cache.test
@@ -0,0 +1,57 @@
+-- source include/have_innodb.inc
+-- source include/have_query_cache.inc
+
+#
+# Without auto_commit.
+#
+drop table if exists t1, t2, t3;
+flush status;
+set autocommit=0;
+create table t1 (a int not null) type=innodb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+commit;
+set autocommit=1;
+begin;
+create table t1 (a int not null) type=innodb;
+insert into t1 values (1),(2),(3);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+commit;
+create table t1 (a int not null) type=innodb;
+create table t2 (a int not null) type=innodb;
+create table t3 (a int not null) type=innodb;
+insert into t1 values (1),(2);
+insert into t2 values (1),(2);
+insert into t3 values (1),(2);
+select * from t1;
+select * from t2;
+select * from t3;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+begin;
+select * from t1;
+select * from t2;
+select * from t3;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+insert into t1 values (3);
+insert into t2 values (3);
+insert into t1 values (4);
+select * from t1;
+select * from t2;
+select * from t3;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+commit;
+show status like "Qcache_queries_in_cache";
+
+drop table if exists t1;
+CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) TYPE=InnoDB;
+select count(*) from t1;
+insert into t1 (id) values (0);
+select count(*) from t1;
+drop table t1;
diff --git a/mysql-test/t/innodb_handler.test b/mysql-test/t/innodb_handler.test
new file mode 100644
index 00000000000..6777e4f49bd
--- /dev/null
+++ b/mysql-test/t/innodb_handler.test
@@ -0,0 +1,82 @@
+-- source include/have_innodb.inc
+
+#
+# test of HANDLER ...
+#
+
+drop table if exists t1;
+create table t1 (a int, b char(10), key a(a), key b(a,b)) type=innodb;
+insert into t1 values
+(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
+(14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"),
+(20,"ggg"),(21,"hhh"),(22,"iii");
+handler t1 open as t2;
+handler t2 read a first;
+handler t2 read a next;
+handler t2 read a next;
+handler t2 read a prev;
+handler t2 read a last;
+handler t2 read a prev;
+handler t2 read a prev;
+
+handler t2 read a first;
+handler t2 read a prev;
+
+handler t2 read a last;
+handler t2 read a prev;
+handler t2 read a next;
+handler t2 read a next;
+
+handler t2 read a=(15);
+handler t2 read a=(16);
+
+--error 1070
+handler t2 read a=(19,"fff");
+
+handler t2 read b=(19,"fff");
+handler t2 read b=(19,"yyy");
+handler t2 read b=(19);
+
+--error 1109
+handler t1 read a last;
+
+handler t2 read a=(11);
+handler t2 read a>=(11);
+
+handler t2 read a=(18);
+handler t2 read a>=(18);
+handler t2 read a>(18);
+handler t2 read a<=(18);
+handler t2 read a<(18);
+
+handler t2 read a first limit 5;
+handler t2 read a next limit 3;
+handler t2 read a prev limit 10;
+
+handler t2 read a>=(16) limit 4;
+handler t2 read a>=(16) limit 2,2;
+handler t2 read a last limit 3;
+
+handler t2 read a=(19);
+handler t2 read a=(19) where b="yyy";
+
+handler t2 read first;
+handler t2 read next;
+--error 1064
+handler t2 read last;
+handler t2 close;
+
+handler t1 open as t2;
+handler t2 read first;
+alter table t1 type=innodb;
+--error 1109
+handler t2 read first;
+
+drop table t1;
+CREATE TABLE t1 ( no1 smallint(5) NOT NULL default '0', no2 int(10) NOT NULL default '0', PRIMARY KEY (no1,no2)) TYPE=InnoDB;
+INSERT INTO t1 VALUES (1,274),(1,275),(2,6),(2,8),(4,1),(4,2);
+HANDLER t1 OPEN;
+HANDLER t1 READ `primary` = (1, 1000);
+HANDLER t1 READ `primary` PREV;
+DROP TABLE t1;
+
diff --git a/mysql-test/t/ins000001.test b/mysql-test/t/ins000001.test
deleted file mode 100644
index 4d75b4e7fe3..00000000000
--- a/mysql-test/t/ins000001.test
+++ /dev/null
@@ -1,9 +0,0 @@
-use test;
-drop table if exists t1,t2;
-create table t1 (email varchar(50));
-insert into t1 values ('sasha@mysql.com'),('monty@mysql.com'),
-('foo@hotmail.com'),('foo@aol.com'),('bar@aol.com');
-create table t2(id int not null auto_increment primary key,
- t2 varchar(50), unique(t2));
-insert into t2 (t2) select distinct substring(email, locate('@', email)+1) from t1;
-select * from t2;
diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test
index cf6f41d454d..12dfe6e50a9 100644
--- a/mysql-test/t/insert.test
+++ b/mysql-test/t/insert.test
@@ -2,7 +2,7 @@
# Test of refering to old values
#
-drop table if exists t1;
+drop table if exists t1,t2;
create table t1 (a int not null);
insert into t1 values (1);
insert into t1 values (a+2);
@@ -10,3 +10,77 @@ insert into t1 values (a+3);
insert into t1 values (4),(a+5);
select * from t1;
drop table t1;
+
+#
+# Test of duplicate key values with packed keys
+#
+
+create table t1 (id int not null auto_increment primary key, username varchar(32) not null, unique (username));
+insert into t1 values (0,"mysql");
+insert into t1 values (0,"mysql ab");
+insert into t1 values (0,"mysql a");
+insert into t1 values (0,"r1manic");
+insert into t1 values (0,"r1man");
+drop table t1;
+
+#
+# Test insert syntax
+#
+
+create table t1 (a int not null auto_increment, primary key (a), t timestamp, c char(10) default "hello", i int);
+insert into t1 values (default,default,default,default), (default,default,default,default), (4,0,"a",5),(default,default,default,default);
+select a,t>0,c,i from t1;
+truncate table t1;
+insert into t1 set a=default,t=default,c=default;
+insert into t1 set a=default,t=default,c=default,i=default;
+insert into t1 set a=4,t=0,c="a",i=5;
+insert into t1 set a=5,t=0,c="a",i=null;
+insert into t1 set a=default,t=default,c=default,i=default;
+select a,t>0,c,i from t1;
+drop table t1;
+
+#
+# Test problem with bulk insert and auto_increment on second part keys
+#
+
+create table t1 (sid char(20), id int(2) NOT NULL auto_increment, key(sid, id));
+insert into t1 values ('skr',NULL),('skr',NULL),('test',NULL);
+select * from t1;
+insert into t1 values ('rts',NULL),('rts',NULL),('test',NULL);
+select * from t1;
+drop table t1;
+
+#
+#Test of behaviour with INSERT VALUES (NULL)
+#
+
+create table t1 (id int NOT NULL DEFAULT 8);
+-- error 1048
+insert into t1 values(NULL);
+insert into t1 values (1), (NULL), (2);
+select * from t1;
+drop table t1;
+
+#
+# Test if insert ... select distinct
+#
+
+create table t1 (email varchar(50));
+insert into t1 values ('sasha@mysql.com'),('monty@mysql.com'),('foo@hotmail.com'),('foo@aol.com'),('bar@aol.com');
+create table t2(id int not null auto_increment primary key, t2 varchar(50), unique(t2));
+insert delayed into t2 (t2) select distinct substring(email, locate('@', email)+1) from t1;
+select * from t2;
+drop table t1,t2;
+
+#
+# Test of mysqld crash with fully qualified column names
+#
+
+--disable_warnings
+drop database if exists mysqltest;
+--enable_warnings
+create database mysqltest;
+use mysqltest;
+create table t1 (c int);
+insert into mysqltest.t1 set mysqltest.t1.c = '1';
+drop database mysqltest;
diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test
index 625f4755a79..3a8118f7fff 100644
--- a/mysql-test/t/insert_select.test
+++ b/mysql-test/t/insert_select.test
@@ -7,11 +7,131 @@ create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLI
insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12);
create table t2 (payoutID SMALLINT UNSIGNED NOT NULL PRIMARY KEY);
insert into t2 (payoutID) SELECT DISTINCT payoutID FROM t1;
+--error 1062
insert into t2 (payoutID) SELECT payoutID+10 FROM t1;
+insert ignore into t2 (payoutID) SELECT payoutID+10 FROM t1;
select * from t2;
drop table t1,t2;
#
+# bug in bulk insert optimization
+# test case by Fournier Jocelyn <joc@presence-pc.com>
+#
+
+CREATE TABLE `t1` (
+ `numeropost` bigint(20) unsigned NOT NULL default '0',
+ `icone` tinyint(4) unsigned NOT NULL default '0',
+ `numreponse` bigint(20) unsigned NOT NULL auto_increment,
+ `contenu` text NOT NULL,
+ `pseudo` varchar(50) NOT NULL default '',
+ `date` datetime NOT NULL default '0000-00-00 00:00:00',
+ `ip` bigint(11) NOT NULL default '0',
+ `signature` tinyint(1) unsigned NOT NULL default '0',
+ PRIMARY KEY (`numeropost`,`numreponse`)
+ ,KEY `ip` (`ip`),
+ KEY `date` (`date`),
+ KEY `pseudo` (`pseudo`),
+ KEY `numreponse` (`numreponse`)
+) TYPE=MyISAM;
+
+CREATE TABLE `t2` (
+ `numeropost` bigint(20) unsigned NOT NULL default '0',
+ `icone` tinyint(4) unsigned NOT NULL default '0',
+ `numreponse` bigint(20) unsigned NOT NULL auto_increment,
+ `contenu` text NOT NULL,
+ `pseudo` varchar(50) NOT NULL default '',
+ `date` datetime NOT NULL default '0000-00-00 00:00:00',
+ `ip` bigint(11) NOT NULL default '0',
+ `signature` tinyint(1) unsigned NOT NULL default '0',
+ PRIMARY KEY (`numeropost`,`numreponse`),
+ KEY `ip` (`ip`),
+ KEY `date` (`date`),
+ KEY `pseudo` (`pseudo`),
+ KEY `numreponse` (`numreponse`)
+) TYPE=MyISAM;
+
+INSERT INTO t2
+(numeropost,icone,numreponse,contenu,pseudo,date,ip,signature) VALUES
+(9,1,56,'test','joce','2001-07-25 13:50:53'
+,3649052399,0);
+
+
+INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip)
+SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM t2
+WHERE numeropost=9 ORDER BY numreponse ASC;
+
+show variables like '%bulk%';
+
+INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip)
+SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM t2
+WHERE numeropost=9 ORDER BY numreponse ASC;
+
+DROP TABLE t1,t2;
+
+# Check if a partly-completed INSERT SELECT in a MyISAM table goes
+# into the binlog
+
+create table t1(a int, unique(a));
+insert into t1 values(2);
+create table t2(a int);
+insert into t2 values(1),(2);
+reset master;
+--error 1062
+insert into t1 select * from t2;
+# The above should produce an error, but still be in the binlog;
+# verify the binlog :
+let $VERSION=`select version()`;
+--replace_result $VERSION VERSION
+show binlog events;
+drop table t1, t2;
+drop table if exists t1, t2;
+
+#
+# Test of insert ... select from same table
+#
+
+create table t1 (a int not null);
+create table t2 (a int not null);
+insert into t1 values (1);
+insert into t1 values (a+2);
+insert into t1 values (a+3);
+insert into t1 values (4),(a+5);
+insert into t1 select * from t1;
+select * from t1;
+insert into t1 select * from t1 as t2;
+select * from t1;
+insert into t2 select * from t1 as t2;
+select * from t1;
+insert into t1 select t2.a from t1,t2;
+select * from t1;
+--error 1066
+insert into t1 select * from t1,t1;
+drop table t1,t2;
+
+#
+# test replace ... select
+#
+
+create table t1 (a int not null primary key, b char(10));
+create table t2 (a int not null, b char(10));
+insert into t1 values (1,"t1:1"),(3,"t1:3");
+insert into t2 values (2,"t2:2"), (3,"t2:3");
+--error 1062
+insert into t1 select * from t2;
+select * from t1;
+replace into t1 select * from t2;
+select * from t1;
+drop table t1,t2;
+
+#
+# Test that caused uninitialized memory access in auto_increment_key update
+#
+
+CREATE TABLE t1 ( USID INTEGER UNSIGNED, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User CHAR(32) NOT NULL DEFAULT '<UNKNOWN>', NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL);
+CREATE TABLE t2 ( USID INTEGER UNSIGNED AUTO_INCREMENT, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User TEXT NOT NULL, NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL, INDEX(USID,ServerID,NASAddr,SessionID), INDEX(AssignedAddr));
+INSERT INTO t1 VALUES (39,42,'Access-Granted','46','491721000045',2130706433,17690,NULL,NULL,'Localnet','491721000045','49172200000',754974766,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2003-07-18 00:11:21',NULL,NULL,20030718001121);
+INSERT INTO t2 SELECT USID, ServerID, State, SessionID, User, NASAddr, NASPort, NASPortType, ConnectSpeed, CarrierType, CallingStationID, CalledStationID, AssignedAddr, SessionTime, PacketsIn, OctetsIn, PacketsOut, OctetsOut, TerminateCause, UnauthTime, AccessRequestTime, AcctStartTime, AcctLastTime, LastModification from t1 LIMIT 1;
+drop table t1,t2;
# Another problem from Bug #2012
#
diff --git a/mysql-test/t/isam.test b/mysql-test/t/isam.test
index 76923adf747..e807112dab4 100644
--- a/mysql-test/t/isam.test
+++ b/mysql-test/t/isam.test
@@ -1,24 +1,71 @@
+-- source include/have_isam.inc
+
+drop table if exists t1,t2;
+
#
# Test possible problem with rows that are about 65535 bytes long
#
-create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a));
+create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a)) type=isam;
let $1=100;
+disable_query_log;
while ($1)
{
eval insert into t1 (b) values(repeat(char(65+$1),65540-$1));
dec $1;
}
-check table t1;
-repair table t1;
+enable_query_log;
delete from t1 where (a & 1);
-check table t1;
-repair table t1;
-check table t1;
+select sum(length(b)) from t1;
drop table t1;
#
+# Test of auto_increment; The test for BDB tables is in bdb.test
+#
+
+create table t1 (a int not null auto_increment,b int, primary key (a)) type=isam;
+insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4);
+delete from t1 where a=4 or a=2;
+insert into t1 values (NULL,4),(NULL,5),(6,6);
+select * from t1;
+delete from t1 where a=6;
+#show table status like "t1";
+replace t1 values (3,1);
+replace t1 values (3,3);
+ALTER TABLE t1 add c int;
+insert into t1 values (NULL,6,6);
+select * from t1;
+drop table t1;
+
+#
+# Test of some CREATE TABLE's that should fail
+#
+!$1121 create table t1 (a int,b text, index(a)) type=isam;
+!$1073 create table t1 (a int,b text, index(b)) type=isam;
+!$1075 create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=isam;
+!$1121 create table t1 (ordid int(8), unique (ordid)) type=isam;
+drop table if exists t1;
+
+#
+# Test of some show commands
+#
+
+create table t1 (a int not null primary key, b int not null,c int not null, key(b,c));
+insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4);
+create table t2 type=isam select * from t1;
+optimize table t1;
+check table t1,t2;
+repair table t1,t2;
+check table t2,t1;
+lock tables t1 write;
+check table t2,t1;
+show columns from t1;
+show full columns from t1;
+show index from t1;
+drop table t1,t2;
+
+#
# test of table with huge number of packed fields
#
diff --git a/mysql-test/t/isolation.test b/mysql-test/t/isolation.test
deleted file mode 100644
index d9750ecb351..00000000000
--- a/mysql-test/t/isolation.test
+++ /dev/null
@@ -1,208 +0,0 @@
-source include/have_gemini.inc
-source include/master-slave.inc;
-connection master;
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set autocommit=0;
-
-insert into t1 (f1) values ("test1"), ("bar");
-connection master1;
-!$1030 select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-insert into t1 (f1) values ("test2"), ("bar");
-connection master1;
-set transaction isolation level serializable;
-!$-1217 select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-insert into t1 (f1) values ("test3"), ("bar");
-connection master1;
-set transaction isolation level read uncommitted;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-connection master1;
-set transaction isolation level read committed;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-insert into t1 (f1) values ("test4"), ("bar");
-connection master1;
-set transaction isolation level repeatable read;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level serializable;
-insert into t1 (f1) values ("test5"), ("bar");
-connection master1;
-set transaction isolation level serializable;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level serializable;
-insert into t1 (f1) values ("test6"), ("bar");
-connection master1;
-set transaction isolation level read uncommitted;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level serializable;
-insert into t1 (f1) values ("test7"), ("bar");
-connection master1;
-set transaction isolation level read committed;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level serializable;
-insert into t1 (f1) values ("test8"), ("bar");
-connection master1;
-set transaction isolation level repeatable read;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read uncommitted;
-insert into t1 (f1) values ("test9"), ("bar");
-connection master1;
-set transaction isolation level serializable;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read uncommitted;
-insert into t1 (f1) values ("test10"), ("bar");
-connection master1;
-set transaction isolation level read uncommitted;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read uncommitted;
-insert into t1 (f1) values ("test11"), ("bar");
-connection master1;
-set transaction isolation level read committed;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read uncommitted;
-insert into t1 (f1) values ("test12"), ("bar");
-connection master1;
-set transaction isolation level repeatable read;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read committed;
-insert into t1 (f1) values ("test13"), ("bar");
-connection master1;
-set transaction isolation level serializable;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read committed;
-insert into t1 (f1) values ("test14"), ("bar");
-connection master1;
-set transaction isolation level read uncommitted;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read committed;
-insert into t1 (f1) values ("test15"), ("bar");
-connection master1;
-set transaction isolation level read committed;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level read committed;
-insert into t1 (f1) values ("test16"), ("bar");
-connection master1;
-set transaction isolation level repeatable read;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level repeatable read;
-insert into t1 (f1) values ("test17"), ("bar");
-connection master1;
-set transaction isolation level serializable;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level repeatable read;
-insert into t1 (f1) values ("test18"), ("bar");
-connection master1;
-set transaction isolation level read uncommitted;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level repeatable read;
-insert into t1 (f1) values ("test19"), ("bar");
-connection master1;
-set transaction isolation level read committed;
-select * from t1;
-connection master;
-commit;
-
-drop table if exists t1;
-create table t1 (f1 char(20) not null) type = gemini;
-set transaction isolation level repeatable read;
-insert into t1 (f1) values ("test20"), ("bar");
-connection master1;
-set transaction isolation level repeatable read;
-select * from t1;
-connection master;
-commit;
-drop table t1;
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index 5fe1834873f..19e04d2aa7e 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -1,8 +1,30 @@
#
+# Initialization
+drop table if exists t1,t2,t3;
+
+#
+# Test different join syntaxes
+#
+
+CREATE TABLE t1 (S1 INT);
+CREATE TABLE t2 (S1 INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t1 JOIN t2;
+SELECT * FROM t1 INNER JOIN t2;
+SELECT * from t1 JOIN t2 USING (S1);
+SELECT * FROM t1 INNER JOIN t2 USING (S1);
+SELECT * from t1 CROSS JOIN t2;
+SELECT * from t1 LEFT JOIN t2 USING(S1);
+SELECT * from t1 LEFT JOIN t2 ON(t2.S1=2);
+SELECT * from t1 RIGHT JOIN t2 USING(S1);
+SELECT * from t1 RIGHT JOIN t2 ON(t1.S1=1);
+drop table t1,t2;
+
+#
# This failed for lia Perminov
#
-drop table if exists t1,t2,t3;
create table t1 (id int primary key);
create table t2 (id int);
@@ -20,13 +42,18 @@ insert into t1 values (105);
insert into t1 values (106);
insert into t1 values (107);
-insert into t2 values (107);
-insert into t2 values (75);
+insert into t2 values (107),(75),(1000);
select t1.id, t2.id from t1, t2 where t2.id = t1.id;
select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id;
select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id;
+#
+# Test problems with impossible ON or WHERE
+#
+select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
+explain select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
+explain select t1.id, t2.id from t1, t2 where t2.id = t1.id and t1.id <0 and t1.id > 0;
drop table t1,t2;
#
@@ -71,10 +98,7 @@ CREATE TABLE t2 (
INSERT INTO t2 VALUES (3,2,11,12,5400,7800);
INSERT INTO t2 VALUES (4,2,25,12,6500,11200);
INSERT INTO t2 VALUES (5,1,37,6,10000,12000);
-
-select a.id, b.category as catid, b.state as stateid, b.county as
-countyid from t1 a, t2 b where (a.token =
-'a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id);
+select a.id, b.category as catid, b.state as stateid, b.county as countyid from t1 a, t2 b ignore index (primary) where (a.token ='a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id);
select a.id, b.category as catid, b.state as stateid, b.county as
countyid from t1 a, t2 b where (a.token =
'a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id) order by a.id;
@@ -87,6 +111,7 @@ drop table t1, t2;
create table t1 (a int primary key);
insert into t1 values(1),(2);
select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a);
+--replace_result "31 tables" "XX tables" "63 tables" "XX tables"
--error 1116
select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a) left join t1 as t32 using (a) left join t1 as t33 using (a) left join t1 as t34 using (a) left join t1 as t35 using (a) left join t1 as t36 using (a) left join t1 as t37 using (a) left join t1 as t38 using (a) left join t1 as t39 using (a) left join t1 as t40 using (a) left join t1 as t41 using (a) left join t1 as t42 using (a) left join t1 as t43 using (a) left join t1 as t44 using (a) left join t1 as t45 using (a) left join t1 as t46 using (a) left join t1 as t47 using (a) left join t1 as t48 using (a) left join t1 as t49 using (a) left join t1 as t50 using (a) left join t1 as t51 using (a) left join t1 as t52 using (a) left join t1 as t53 using (a) left join t1 as t54 using (a) left join t1 as t55 using (a) left join t1 as t56 using (a) left join t1 as t57 using (a) left join t1 as t58 using (a) left join t1 as t59 using (a) left join t1 as t60 using (a) left join t1 as t61 using (a) left join t1 as t62 using (a) left join t1 as t63 using (a) left join t1 as t64 using (a) left join t1 as t65 using (a);
drop table t1;
@@ -257,3 +282,35 @@ SELECT * FROM t1 NATURAL JOIN t2 WHERE 1 AND (Value1 = 'A' AND Value2 <> 'B');
SELECT * FROM t1 NATURAL JOIN t2 WHERE 1 AND Value1 = 'A' AND Value2 <> 'B';
SELECT * FROM t1 NATURAL JOIN t2 WHERE (Value1 = 'A' AND Value2 <> 'B') AND 1;
drop table t1,t2;
+
+#
+# Test combination of join methods
+#
+
+create table t1 (i int);
+create table t2 (i int);
+create table t3 (i int);
+insert into t1 values(1),(2);
+insert into t2 values(2),(3);
+insert into t3 values (2),(4);
+
+select * from t1 natural left join t2;
+select * from t1 left join t2 on (t1.i=t2.i);
+select * from t1 natural left join t2 natural left join t3;
+select * from t1 left join t2 on (t1.i=t2.i) left join t3 on (t2.i=t3.i);
+
+select * from t3 natural right join t2;
+select * from t3 right join t2 on (t3.i=t2.i);
+select * from t3 natural right join t2 natural right join t1;
+select * from t3 right join t2 on (t3.i=t2.i) right join t1 on (t2.i=t1.i);
+
+select * from t1,t2 natural left join t3 order by t1.i,t2.i,t3.i;
+select * from t1,t2 left join t3 on (t2.i=t3.i) order by t1.i,t2.i,t3.i;
+select t1.i,t2.i,t3.i from t2 natural left join t3,t1 order by t1.i,t2.i,t3.i;
+select t1.i,t2.i,t3.i from t2 left join t3 on (t2.i=t3.i),t1 order by t1.i,t2.i,t3.i;
+
+select * from t1,t2 natural right join t3 order by t1.i,t2.i,t3.i;
+select * from t1,t2 right join t3 on (t2.i=t3.i) order by t1.i,t2.i,t3.i;
+select t1.i,t2.i,t3.i from t2 natural right join t3,t1 order by t1.i,t2.i,t3.i;
+select t1.i,t2.i,t3.i from t2 right join t3 on (t2.i=t3.i),t1 order by t1.i,t2.i,t3.i;
+drop table t1,t2,t3;
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index af5f377afb5..bed4d4b033b 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -168,7 +168,7 @@ INSERT INTO t2 VALUES (11416,11416,32767,0);
INSERT INTO t2 VALUES (11409,0,0,0);
CREATE TABLE t3 (
- id int(11) DEFAULT '0' NOT NULL auto_increment,
+ id int(11) NOT NULL auto_increment,
dni_pasaporte char(16) DEFAULT '' NOT NULL,
idPla int(11) DEFAULT '0' NOT NULL,
cod_asig int(11) DEFAULT '0' NOT NULL,
@@ -183,7 +183,7 @@ CREATE TABLE t3 (
INSERT INTO t3 VALUES (1,'11111111',1,10362,98,1,'M');
CREATE TABLE t4 (
- id int(11) DEFAULT '0' NOT NULL auto_increment,
+ id int(11) NOT NULL auto_increment,
papa int(11) DEFAULT '0' NOT NULL,
fill int(11) DEFAULT '0' NOT NULL,
idPla int(11) DEFAULT '0' NOT NULL,
@@ -210,7 +210,7 @@ drop table t1,t2,t3,test.t4;
#
CREATE TABLE t1 (
- id smallint(5) unsigned DEFAULT '0' NOT NULL auto_increment,
+ id smallint(5) unsigned NOT NULL auto_increment,
name char(60) DEFAULT '' NOT NULL,
PRIMARY KEY (id)
);
@@ -219,7 +219,7 @@ INSERT INTO t1 VALUES (2,'Lilliana Angelovska');
INSERT INTO t1 VALUES (3,'Thimble Smith');
CREATE TABLE t2 (
- id smallint(5) unsigned DEFAULT '0' NOT NULL auto_increment,
+ id smallint(5) unsigned NOT NULL auto_increment,
owner smallint(5) unsigned DEFAULT '0' NOT NULL,
name char(60),
PRIMARY KEY (id)
@@ -248,7 +248,7 @@ drop table t1,t2;
create table t1 (id int not null, str char(10), index(str));
insert into t1 values (1, null), (2, null), (3, "foo"), (4, "bar");
-select * from t1 where str is not null;
+select * from t1 where str is not null order by id;
select * from t1 where str is null;
drop table t1;
@@ -257,15 +257,15 @@ drop table t1;
#
CREATE TABLE t1 (
- t1_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+ t1_id bigint(21) NOT NULL auto_increment,
PRIMARY KEY (t1_id)
);
CREATE TABLE t2 (
- t2_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+ t2_id bigint(21) NOT NULL auto_increment,
PRIMARY KEY (t2_id)
);
CREATE TABLE t3 (
- t3_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+ t3_id bigint(21) NOT NULL auto_increment,
PRIMARY KEY (t3_id)
);
CREATE TABLE t4 (
@@ -416,3 +416,37 @@ explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
select * from t2 left join t1 ignore index(primary) on t1.fooID = t2.fooID and t1.fooID = 30;
drop table t1,t2;
+drop table if exists t3;
+create table t1 (i int);
+create table t2 (i int);
+create table t3 (i int);
+insert into t1 values(1),(2);
+insert into t2 values(2),(3);
+insert into t3 values(2),(4);
+select * from t1 natural left join t2 natural left join t3;
+drop table t1,t2,t3;
+
+#
+# Test of USING
+#
+create table t1 (f1 integer,f2 integer,f3 integer);
+create table t2 (f2 integer,f4 integer);
+create table t3 (f3 integer,f5 integer);
+--error 1054
+select * from t1
+ left outer join t2 using (f2)
+ left outer join t3 using (f3);
+drop table t1,t2,t3;
+
+create table t1 (a1 int, a2 int);
+create table t2 (b1 int not null, b2 int);
+create table t3 (c1 int, c2 int);
+
+insert into t1 values (1,2), (2,2), (3,2);
+insert into t2 values (1,3), (2,3);
+insert into t3 values (2,4), (3,4);
+
+select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
+explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
+
+drop table t1, t2, t3;
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index a8417fad876..cb80d88aee8 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -54,12 +54,12 @@ INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y');
drop table t1;
#
-# problem med primary key
+# No longer a problem with primary key
#
CREATE TABLE t1 (program enum('signup','unique','sliding') not null, type enum('basic','sliding','signup'), sites set('mt'), PRIMARY KEY (program));
-# The following should give an error for wrong primary key
-!$1171 ALTER TABLE t1 modify program enum('signup','unique','sliding');
+# This no longer give an error for wrong primary key
+ALTER TABLE t1 modify program enum('signup','unique','sliding');
drop table t1;
#
@@ -160,3 +160,31 @@ SELECT * FROM t1 WHERE a='a' AND b=2;
SELECT * FROM t1 WHERE a='a' AND b in (2);
SELECT * FROM t1 WHERE a='a' AND b in (1,2);
drop table t1;
+
+#
+# Test of create key order
+#
+
+create table t1 (a int not null unique, b int unique, c int, d int not null primary key, key(c), e int not null unique);
+show keys from t1;
+drop table t1;
+
+#
+# Problem with UNIQUE() with NULL parts and auto increment
+#
+
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NOT NULL,i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c CHAR(10) NULL, i INT NOT NULL AUTO_INCREMENT,
+UNIQUE (c,i));
+INSERT INTO t1 (c) VALUES (NULL),(NULL);
+SELECT * FROM t1;
+INSERT INTO t1 (c) VALUES ('a'),('a');
+SELECT * FROM t1;
+drop table t1;
diff --git a/mysql-test/t/key_primary.test b/mysql-test/t/key_primary.test
index 75dded5d667..2cdb117128f 100644
--- a/mysql-test/t/key_primary.test
+++ b/mysql-test/t/key_primary.test
@@ -2,6 +2,7 @@
# test of primary key conversions
#
+drop table if exists t1;
create table t1 (t1 char(3) primary key);
insert into t1 values("ABC");
insert into t1 values("ABA");
diff --git a/mysql-test/t/keywords.test b/mysql-test/t/keywords.test
index b9a1f34c715..3bd757aa069 100644
--- a/mysql-test/t/keywords.test
+++ b/mysql-test/t/keywords.test
@@ -8,3 +8,7 @@ insert into t1 values ("12:22:22","97:02:03","1997-01-02");
select * from t1;
select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time) from t1;
drop table t1;
+create table events(binlog int);
+insert into events values(1);
+select events.binlog from events;
+drop table events;
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index be6860a3cc3..6bcc43ac916 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -1,3 +1,11 @@
+# This test doesn't work with the embedded version as this code
+# assumes that one query is running while we are doing queries on
+# a second connection.
+# This would work if mysqltest run would be threaded and handle each
+# connection in a separate thread.
+#
+-- source include/not_embedded.inc
+
connect (con1, localhost, root,,);
connect (con2, localhost, root,,);
diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test
index 112761abd87..32962073eee 100644
--- a/mysql-test/t/limit.test
+++ b/mysql-test/t/limit.test
@@ -19,12 +19,30 @@ select * from t1;
drop table t1;
create table t1 (i int);
-insert into t1 (i) values(1);
-insert into t1 (i) values(1);
-insert into t1 (i) values(1);
+insert into t1 (i) values(1),(1),(1);
delete from t1 limit 1;
update t1 set i=2 limit 1;
delete from t1 limit 0;
update t1 set i=3 limit 0;
select * from t1;
drop table t1;
+
+# LIMIT 0
+
+select 0 limit 0;
+
+#
+# Test with DELETE, ORDER BY and limit (bug #1024)
+#
+
+CREATE TABLE t1(id int auto_increment primary key, id2 int, index(id2));
+INSERT INTO t1 (id2) values (0),(0),(0);
+DELETE FROM t1 WHERE id=1;
+INSERT INTO t1 SET id2=0;
+SELECT * FROM t1;
+DELETE FROM t1 WHERE id2 = 0 ORDER BY id LIMIT 1;
+# should have deleted WHERE id=2
+SELECT * FROM t1;
+DELETE FROM t1 WHERE id2 = 0 ORDER BY id desc LIMIT 1;
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
new file mode 100644
index 00000000000..9269eb19b05
--- /dev/null
+++ b/mysql-test/t/loaddata.test
@@ -0,0 +1,31 @@
+#
+# Some simple test of load data
+#
+
+drop table if exists t1;
+
+create table t1 (a date, b date, c date not null, d date);
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',';
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' IGNORE 2 LINES;
+SELECT * from t1;
+truncate table t1;
+
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' LINES STARTING BY ',' (b,c,d);
+SELECT * from t1;
+drop table t1;
+
+create table t1 (a text, b text);
+load data infile '../../std_data/loaddata2.dat' into table t1 fields terminated by ',' enclosed by '''';
+select concat('|',a,'|'), concat('|',b,'|') from t1;
+drop table t1;
+
+create table t1 (a int, b char(10));
+load data infile '../../std_data/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines;
+select * from t1;
+truncate table t1;
+load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines;
+
+# The empty line last comes from the end line field in the file
+select * from t1;
+drop table t1;
+
diff --git a/mysql-test/t/lock.test b/mysql-test/t/lock.test
index 77354e63252..9015ce12fde 100644
--- a/mysql-test/t/lock.test
+++ b/mysql-test/t/lock.test
@@ -51,47 +51,9 @@ check table t1;
# Check error message
lock tables t1 write;
check table t2;
+--error 1100
+insert into t1 select nr from t1;
unlock tables;
+lock tables t1 write, t1 as t1_alias read;
+insert into t1 select index1,nr from t1 as t1_alias;
drop table t1,t2;
-
-#test to see if select will get the lock ahead of low priority update
-connect (locker,localhost,root,,);
-connect (reader,localhost,root,,);
-connect (writer,localhost,root,,);
-
-connection locker;
-create table t1(n int);
-insert into t1 values (1);
-lock tables t1 write;
-connection writer;
-send update low_priority t1 set n = 4;
-connection reader;
---sleep 2
-send select n from t1;
-connection locker;
---sleep 2
-unlock tables;
-connection writer;
-reap;
-connection reader;
-reap;
-drop table t1;
-
-connection locker;
-create table t1(n int);
-insert into t1 values (1);
-lock tables t1 read;
-connection writer;
-send update low_priority t1 set n = 4;
-connection reader;
---sleep 2
-send select n from t1;
-connection locker;
---sleep 2
-unlock tables;
-connection writer;
-reap;
-connection reader;
-reap;
-drop table t1;
-
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
new file mode 100644
index 00000000000..0295fca29e7
--- /dev/null
+++ b/mysql-test/t/lock_multi.test
@@ -0,0 +1,70 @@
+# This test doesn't work with the embedded version as this code
+# assumes that one query is running while we are doing queries on
+# a second connection.
+# This would work if mysqltest run would be threaded and handle each
+# connection in a separate thread.
+#
+-- source include/not_embedded.inc
+
+drop table if exists t1,t2;
+
+# test to see if select will get the lock ahead of low priority update
+
+connect (locker,localhost,root,,);
+connect (reader,localhost,root,,);
+connect (writer,localhost,root,,);
+
+connection locker;
+create table t1(n int);
+insert into t1 values (1);
+lock tables t1 write;
+connection writer;
+send update low_priority t1 set n = 4;
+connection reader;
+--sleep 2
+send select n from t1;
+connection locker;
+--sleep 2
+unlock tables;
+connection writer;
+reap;
+connection reader;
+reap;
+drop table t1;
+
+connection locker;
+create table t1(n int);
+insert into t1 values (1);
+lock tables t1 read;
+connection writer;
+send update low_priority t1 set n = 4;
+connection reader;
+--sleep 2
+send select n from t1;
+connection locker;
+--sleep 2
+unlock tables;
+connection writer;
+reap;
+connection reader;
+reap;
+drop table t1;
+
+#
+# Test problem when using locks on many tables and droping a table that
+# is to-be-locked by another thread
+#
+
+connection locker;
+create table t1 (a int);
+create table t2 (a int);
+lock table t1 write, t2 write;
+connection reader;
+send insert t1 select * from t2;
+connection locker;
+drop table t2;
+connection reader;
+--error 1146
+reap;
+connection locker;
+drop table t1;
diff --git a/mysql-test/t/lock_tables_lost_commit-master.opt b/mysql-test/t/lock_tables_lost_commit-master.opt
new file mode 100644
index 00000000000..51ccb915ef0
--- /dev/null
+++ b/mysql-test/t/lock_tables_lost_commit-master.opt
@@ -0,0 +1 @@
+--binlog-ignore-db=test
diff --git a/mysql-test/t/lock_tables_lost_commit.test b/mysql-test/t/lock_tables_lost_commit.test
new file mode 100644
index 00000000000..a12ee7369cb
--- /dev/null
+++ b/mysql-test/t/lock_tables_lost_commit.test
@@ -0,0 +1,18 @@
+# This is a test for bug 578
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+drop table if exists t1;
+create table t1(a int) type=innodb;
+lock tables t1 write;
+insert into t1 values(10);
+disconnect con1;
+
+connection con2;
+# The bug was that, because of the LOCK TABLES, the handler "forgot" to commit,
+# and the other commit when we write to the binlog was not done because of
+# binlog-ignore-db
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/lowercase_table-master.opt b/mysql-test/t/lowercase_table-master.opt
new file mode 100644
index 00000000000..c718e2feb1b
--- /dev/null
+++ b/mysql-test/t/lowercase_table-master.opt
@@ -0,0 +1 @@
+--lower_case_table_names
diff --git a/mysql-test/t/lowercase_table.test b/mysql-test/t/lowercase_table.test
new file mode 100644
index 00000000000..5bc19f26c0e
--- /dev/null
+++ b/mysql-test/t/lowercase_table.test
@@ -0,0 +1,32 @@
+#
+# Test of --lower-case-table-names
+#
+
+drop table if exists t1,t2,t3,t4,T1;
+create table T1 (id int primary key, Word varchar(40) not null, Index(Word));
+create table t4 (id int primary key, Word varchar(40) not null);
+INSERT INTO T1 VALUES (1, 'a'), (2, 'b'), (3, 'c');
+INSERT INTO T4 VALUES(1,'match');
+SELECT * FROM t1;
+SELECT T1.id from T1 LIMIT 1;
+SELECT T2.id from t1 as T2 LIMIT 1;
+SELECT * from t1 left join t4 on (test.t1.id= TEST.t4.id) where TEST.t1.id >= test.t4.id;
+--error 1109
+SELECT T2.id from t1 as t2 LIMIT 1;
+RENAME TABLE T1 TO T2;
+ALTER TABLE T2 ADD new_col int not null;
+ALTER TABLE T2 RENAME T3;
+show tables like 't_';
+drop table t3,t4;
+
+#
+# Test alias
+#
+create table t1 (a int);
+select count(*) from T1;
+select count(*) from t1;
+--error 1109
+select count(T1.a) from t1;
+--error 1109
+select count(bags.a) from t1 as Bags;
+drop table t1;
diff --git a/mysql-test/t/lowercase_table2-master.opt b/mysql-test/t/lowercase_table2-master.opt
new file mode 100644
index 00000000000..9b27aef9bf8
--- /dev/null
+++ b/mysql-test/t/lowercase_table2-master.opt
@@ -0,0 +1 @@
+--lower_case_table_names=0
diff --git a/mysql-test/t/lowercase_table2.test b/mysql-test/t/lowercase_table2.test
new file mode 100644
index 00000000000..86bb26f0cf9
--- /dev/null
+++ b/mysql-test/t/lowercase_table2.test
@@ -0,0 +1,80 @@
+#
+# Test of --lower-case-table-names=2
+# (User has case insensitive file system and want's to preserve case of
+# table names)
+#
+--source include/have_innodb.inc
+--require r/lowercase2.require
+disable_query_log;
+show variables like "lower_case_table_names";
+enable_query_log;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2,T1,T2,t3,T3;
+DROP DATABASE IF EXISTS `TEST_$1`;
+DROP DATABASE IF EXISTS `test_$1`;
+--enable_warnings
+
+CREATE TABLE T1 (a int);
+INSERT INTO T1 VALUES (1);
+SHOW TABLES LIKE "T1";
+SHOW TABLES LIKE "t1";
+SHOW CREATE TABLE T1;
+RENAME TABLE T1 TO T2;
+SHOW TABLES LIKE "T2";
+SELECT * FROM t2;
+RENAME TABLE T2 TO t3;
+SHOW TABLES LIKE "T3";
+RENAME TABLE T3 TO T1;
+SHOW TABLES LIKE "T1";
+ALTER TABLE T1 add b int;
+SHOW TABLES LIKE "T1";
+ALTER TABLE T1 RENAME T2;
+SHOW TABLES LIKE "T2";
+
+LOCK TABLE T2 WRITE;
+ALTER TABLE T2 drop b;
+SHOW TABLES LIKE "T2";
+UNLOCK TABLES;
+RENAME TABLE T2 TO T1;
+SHOW TABLES LIKE "T1";
+SELECT * from T1;
+DROP TABLE T1;
+
+#
+# Test database level
+#
+
+CREATE DATABASE `TEST_$1`;
+SHOW DATABASES LIKE "TEST%";
+DROP DATABASE `test_$1`;
+
+#
+# Test of innodb tables with lower_case_table_names=2
+#
+
+CREATE TABLE T1 (a int) engine=innodb;
+INSERT INTO T1 VALUES (1);
+SHOW TABLES LIKE "T1";
+SHOW TABLES LIKE "t1";
+SHOW CREATE TABLE T1;
+RENAME TABLE T1 TO T2;
+SHOW TABLES LIKE "T2";
+SELECT * FROM t2;
+RENAME TABLE T2 TO t3;
+SHOW TABLES LIKE "T3";
+RENAME TABLE T3 TO T1;
+SHOW TABLES LIKE "T1";
+ALTER TABLE T1 add b int;
+SHOW TABLES LIKE "T1";
+ALTER TABLE T1 RENAME T2;
+SHOW TABLES LIKE "T2";
+
+LOCK TABLE T2 WRITE;
+ALTER TABLE T2 drop b;
+SHOW TABLES LIKE "T2";
+UNLOCK TABLES;
+RENAME TABLE T2 TO T1;
+SHOW TABLES LIKE "T1";
+SELECT * from T1;
+DROP TABLE T1;
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 6ea9ecc269f..b625e780f1f 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -2,7 +2,7 @@
# test of MERGE TABLES
#
-drop table if exists t1,t2,t3;
+drop table if exists t1,t2,t3,t4,t5,t6;
create table t1 (a int not null primary key auto_increment, message char(20));
create table t2 (a int not null primary key auto_increment, message char(20));
INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1");
@@ -22,7 +22,7 @@ insert into t2 select NULL,message from t1;
insert into t1 select NULL,message from t2;
insert into t2 select NULL,message from t1;
insert into t1 select NULL,message from t2;
-create table t3 (a int not null, b char(20), key(a)) type=MERGE UNION=(t1,t2);
+create table t3 (a int not null, b char(20), key(a)) type=MERGE UNION=(test.t1,test.t2);
explain select * from t3 where a < 10;
explain select * from t3 where a > 10 and a < 20;
select * from t3 where a = 10;
@@ -31,6 +31,14 @@ select * from t3 where a > 10 and a < 20;
explain select a from t3 order by a desc limit 10;
select a from t3 order by a desc limit 10;
select a from t3 order by a desc limit 300,10;
+delete from t3 where a=3;
+select * from t3 where a < 10;
+delete from t3 where a >= 6 and a <= 8;
+select * from t3 where a < 10;
+update t3 set a=3 where a=9;
+select * from t3 where a < 10;
+update t3 set a=6 where a=7;
+select * from t3 where a < 10;
show create table t3;
# The following should give errors
@@ -97,7 +105,7 @@ drop table t3,t2,t1;
#
# Test table without unions
#
-create table t1 (a int not null) type=merge;
+create table t1 (a int not null, key(a)) type=merge;
select * from t1;
drop table t1;
@@ -116,6 +124,69 @@ select * from t3 where a=1 order by b limit 2;
drop table t3,t1,t2;
#
+# [phi] testing INSERT_METHOD stuff
+#
+
+drop table if exists t6, t5, t4, t3, t2, t1;
+# first testing of common stuff with new parameters
+create table t1 (a int not null, b int not null auto_increment, primary key(a,b));
+create table t2 (a int not null, b int not null auto_increment, primary key(a,b));
+create table t3 (a int not null, b int not null, key(a,b)) UNION=(t1,t2) INSERT_METHOD=NO;
+create table t4 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=NO;
+create table t5 (a int not null, b int not null auto_increment, primary key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST;
+create table t6 (a int not null, b int not null auto_increment, primary key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
+show create table t3;
+show create table t4;
+show create table t5;
+show create table t6;
+insert into t1 values (1,NULL),(1,NULL),(1,NULL),(1,NULL);
+insert into t2 values (2,NULL),(2,NULL),(2,NULL),(2,NULL);
+select * from t3 order by b,a limit 3;
+select * from t4 order by b,a limit 3;
+select * from t5 order by b,a limit 3,3;
+select * from t6 order by b,a limit 6,3;
+# now testing inserts and where the data gets written
+insert into t5 values (5,1),(5,2);
+insert into t6 values (6,1),(6,2);
+select * from t1 order by a,b;
+select * from t2 order by a,b;
+select * from t4 order by a,b;
+# preperation for next test
+insert into t3 values (3,1),(3,2),(3,3),(3,4);
+select * from t3 order by a,b;
+# now testing whether options are kept by alter table
+alter table t4 UNION=(t1,t2,t3);
+show create table t4;
+select * from t4 order by a,b;
+# testing switching off insert method and inserts again
+alter table t4 INSERT_METHOD=FIRST;
+show create table t4;
+insert into t4 values (4,1),(4,2);
+select * from t1 order by a,b;
+select * from t2 order by a,b;
+select * from t3 order by a,b;
+select * from t4 order by a,b;
+select * from t5 order by a,b;
+# auto_increment
+select 1;
+insert into t5 values (1,NULL),(5,NULL);
+insert into t6 values (2,NULL),(6,NULL);
+select * from t1 order by a,b;
+select * from t2 order by a,b;
+select * from t5 order by a,b;
+select * from t6 order by a,b;
+drop table if exists t6, t5, t4, t3, t2, t1;
+
+CREATE TABLE t1 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,1), (2,1);
+CREATE TABLE t2 ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', PRIMARY KEY (a,b)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,2), (2,2);
+CREATE TABLE t ( a int(11) NOT NULL default '0', b int(11) NOT NULL default '0', KEY a (a,b)) TYPE=MRG_MyISAM UNION=(t1,t2);
+select max(b) from t where a = 2;
+select max(b) from t1 where a = 2;
+drop table if exists t,t1,t2;
+
+#
# temporary merge tables
#
drop table if exists t1, t2, t3, t4, t5, t6;
@@ -133,3 +204,49 @@ create temporary table t6 (a int not null) TYPE=MERGE UNION=(t4,t5);
select * from t6;
drop table if exists t1, t2, t3, t4, t5, t6;
+#
+# testing merge::records_in_range and optimizer
+#
+
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+ fileset_id tinyint(3) unsigned NOT NULL default '0',
+ file_code varchar(32) NOT NULL default '',
+ fileset_root_id tinyint(3) unsigned NOT NULL default '0',
+ PRIMARY KEY (fileset_id,file_code),
+ KEY files (fileset_id,fileset_root_id)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (2, '0000000111', 1), (2, '0000000112', 1), (2, '0000000113', 1),
+(2, '0000000114', 1), (2, '0000000115', 1), (2, '0000000116', 1), (2, '0000000117', 1),
+(2, '0000000118', 1), (2, '0000000119', 1), (2, '0000000120', 1);
+CREATE TABLE t2 (
+ fileset_id tinyint(3) unsigned NOT NULL default '0',
+ file_code varchar(32) NOT NULL default '',
+ fileset_root_id tinyint(3) unsigned NOT NULL default '0',
+ PRIMARY KEY (fileset_id,file_code),
+ KEY files (fileset_id,fileset_root_id)
+) TYPE=MRG_MyISAM UNION=(t1);
+
+EXPLAIN SELECT * FROM t2 IGNORE INDEX (files) WHERE fileset_id = 2
+AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1;
+EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2
+AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1;
+EXPLAIN SELECT * FROM t1 WHERE fileset_id = 2
+AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1;
+EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2
+AND file_code = '0000000115' LIMIT 1;
+DROP TABLE IF EXISTS t1, t2;
+
+#
+# Test of ORDER BY DESC on key (Bug #515)
+#
+
+create table t1 (x int, y int, index xy(x, y));
+create table t2 (x int, y int, index xy(x, y));
+create table t3 (x int, y int, index xy(x, y)) type=merge union=(t1,t2);
+insert into t1 values(1, 2);
+insert into t2 values(1, 3);
+select * from t3 where x = 1 and y < 5 order by y;
+# Bug is that followng query returns empty set while it must be same as above
+select * from t3 where x = 1 and y < 5 order by y desc;
+drop table t1,t2,t3;
diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test
new file mode 100644
index 00000000000..be45c2c3133
--- /dev/null
+++ b/mysql-test/t/mix_innodb_myisam_binlog.test
@@ -0,0 +1,178 @@
+# Check that binlog is ok when a transaction mixes updates to InnoDB and
+# MyISAM.
+# It would be nice to make this a replication test, but in 4.0 the
+# slave is always with --skip-innodb in the testsuite. I (Guilhem) however
+# did some tests manually on a slave; tables are replicated fine and
+# Exec_master_log_pos advances as expected.
+
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+create table t1 (a int) type=innodb;
+create table t2 (a int) type=myisam;
+
+reset master;
+
+begin;
+insert into t1 values(1);
+insert into t2 select * from t1;
+commit;
+
+show binlog events from 79;
+
+delete from t1;
+delete from t2;
+reset master;
+
+begin;
+insert into t1 values(2);
+insert into t2 select * from t1;
+# should say some changes to non-transact1onal tables couldn't be rolled back
+--error 1196
+rollback;
+
+show binlog events from 79;
+
+delete from t1;
+delete from t2;
+reset master;
+
+begin;
+insert into t1 values(3);
+savepoint my_savepoint;
+insert into t1 values(4);
+insert into t2 select * from t1;
+--error 1196
+rollback to savepoint my_savepoint;
+commit;
+
+show binlog events from 79;
+
+delete from t1;
+delete from t2;
+reset master;
+
+begin;
+insert into t1 values(5);
+savepoint my_savepoint;
+insert into t1 values(6);
+insert into t2 select * from t1;
+--error 1196
+rollback to savepoint my_savepoint;
+insert into t1 values(7);
+commit;
+select a from t1 order by a; # check that savepoints work :)
+
+show binlog events from 79;
+
+# and when ROLLBACK is not explicit?
+delete from t1;
+delete from t2;
+reset master;
+
+select get_lock("a",10);
+begin;
+insert into t1 values(8);
+insert into t2 select * from t1;
+disconnect con1;
+
+connection con2;
+# We want to SHOW BINLOG EVENTS, to know what was logged. But there is no
+# guarantee that logging of the terminated con1 has been done yet (it may not
+# even be started, so con1 may have not even attempted to lock the binlog yet;
+# so SHOW BINLOG EVENTS may come before con1 does the loggin. To be sure that
+# logging has been done, we use a user lock.
+select get_lock("a",10);
+show binlog events from 79;
+
+# and when not in a transact1on?
+delete from t1;
+delete from t2;
+reset master;
+
+insert into t1 values(9);
+insert into t2 select * from t1;
+
+show binlog events from 79;
+
+# Check that when the query updat1ng the MyISAM table is the first in the
+# transact1on, we log it immediately.
+delete from t1;
+delete from t2;
+reset master;
+
+insert into t1 values(10); # first make t1 non-empty
+begin;
+insert into t2 select * from t1;
+show binlog events from 79;
+insert into t1 values(11);
+commit;
+
+show binlog events from 79;
+
+
+# Check that things work like before this BEGIN/ROLLBACK code was added,
+# when t2 is INNODB
+
+alter table t2 type=INNODB;
+
+delete from t1;
+delete from t2;
+reset master;
+
+begin;
+insert into t1 values(12);
+insert into t2 select * from t1;
+commit;
+
+show binlog events from 79;
+
+delete from t1;
+delete from t2;
+reset master;
+
+begin;
+insert into t1 values(13);
+insert into t2 select * from t1;
+rollback;
+
+show binlog events from 79;
+
+delete from t1;
+delete from t2;
+reset master;
+
+begin;
+insert into t1 values(14);
+savepoint my_savepoint;
+insert into t1 values(15);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+commit;
+
+show binlog events from 79;
+
+delete from t1;
+delete from t2;
+reset master;
+
+begin;
+insert into t1 values(16);
+savepoint my_savepoint;
+insert into t1 values(17);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+insert into t1 values(18);
+commit;
+select a from t1 order by a; # check that savepoints work :)
+
+show binlog events from 79;
+
+drop table t1,t2;
diff --git a/mysql-test/t/multi_update-master.opt b/mysql-test/t/multi_update-master.opt
new file mode 100644
index 00000000000..9f1a29461ff
--- /dev/null
+++ b/mysql-test/t/multi_update-master.opt
@@ -0,0 +1 @@
+--set-variable=tmp_table_size=1024
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
new file mode 100644
index 00000000000..56dcf9a03a9
--- /dev/null
+++ b/mysql-test/t/multi_update.test
@@ -0,0 +1,305 @@
+#
+# Test of update statement that uses many tables.
+#
+
+drop table if exists t1,t2,t3;
+create table t1(id1 int not null auto_increment primary key, t char(12));
+create table t2(id2 int not null, t char(12));
+create table t3(id3 int not null, t char(12), index(id3));
+disable_query_log;
+let $1 = 100;
+while ($1)
+ {
+ let $2 = 5;
+ eval insert into t1(t) values ('$1');
+ while ($2)
+ {
+ eval insert into t2(id2,t) values ($1,'$2');
+ let $3 = 10;
+ while ($3)
+ {
+ eval insert into t3(id3,t) values ($1,'$2');
+ dec $3;
+ }
+ dec $2;
+ }
+ dec $1;
+ }
+enable_query_log;
+
+select count(*) from t1 where id1 > 95;
+select count(*) from t2 where id2 > 95;
+select count(*) from t3 where id3 > 95;
+
+update t1,t2,t3 set t1.t="aaa", t2.t="bbb", t3.t="cc" where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 90;
+select count(*) from t1 where t = "aaa";
+select count(*) from t1 where id1 > 90;
+select count(*) from t2 where t = "bbb";
+select count(*) from t2 where id2 > 90;
+select count(*) from t3 where t = "cc";
+select count(*) from t3 where id3 > 90;
+delete t1.*, t2.*, t3.* from t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 95;
+
+check table t1, t2, t3;
+
+select count(*) from t1 where id1 > 95;
+select count(*) from t2 where id2 > 95;
+select count(*) from t3 where id3 > 95;
+
+delete t1, t2, t3 from t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 5;
+select count(*) from t1 where id1 > 5;
+select count(*) from t2 where id2 > 5;
+select count(*) from t3 where id3 > 5;
+
+delete from t1, t2, t3 using t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 0;
+
+# These queries will force a scan of the table
+select count(*) from t1 where id1;
+select count(*) from t2 where id2;
+select count(*) from t3 where id3;
+
+drop table t1,t2,t3;
+create table t1(id1 int not null primary key, t varchar(100)) pack_keys = 1;
+create table t2(id2 int not null, t varchar(100), index(id2)) pack_keys = 1;
+disable_query_log;
+let $1 = 1000;
+while ($1)
+ {
+ let $2 = 5;
+ eval insert into t1 values ($1,'aaaaaaaaaaaaaaaaaaaa');
+ while ($2)
+ {
+ eval insert into t2(id2,t) values ($1,'bbbbbbbbbbbbbbbbb');
+ dec $2;
+ }
+ dec $1;
+ }
+enable_query_log;
+delete t1 from t1,t2 where t1.id1 = t2.id2 and t1.id1 > 500;
+drop table t1,t2;
+
+CREATE TABLE t1 (
+ id int(11) NOT NULL default '0',
+ name varchar(10) default NULL,
+ PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'aaa'),(2,'aaa'),(3,'aaa');
+CREATE TABLE t2 (
+ id int(11) NOT NULL default '0',
+ name varchar(10) default NULL,
+ PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t2 VALUES (2,'bbb'),(3,'bbb'),(4,'bbb');
+CREATE TABLE t3 (
+ id int(11) NOT NULL default '0',
+ mydate datetime default NULL,
+ PRIMARY KEY (id)
+) TYPE=MyISAM;
+INSERT INTO t3 VALUES (1,'2002-02-04 00:00:00'),(3,'2002-05-12 00:00:00'),(5,'2002-05-12 00:00:00'),(6,'2002-06-22
+00:00:00'),(7,'2002-07-22 00:00:00');
+delete t1,t2,t3 from t1,t2,t3 where to_days(now())-to_days(t3.mydate)>=30 and t3.id=t1.id and t3.id=t2.id;
+select * from t3;
+DROP TABLE IF EXISTS t1,t2,t3;
+
+CREATE TABLE IF NOT EXISTS `t1` (
+ `id` int(11) NOT NULL auto_increment,
+ `tst` text,
+ `tst1` text,
+ PRIMARY KEY (`id`)
+) TYPE=MyISAM;
+
+CREATE TABLE IF NOT EXISTS `t2` (
+ `ID` int(11) NOT NULL auto_increment,
+ `ParId` int(11) default NULL,
+ `tst` text,
+ `tst1` text,
+ PRIMARY KEY (`ID`),
+ KEY `IX_ParId_t2` (`ParId`),
+ FOREIGN KEY (`ParId`) REFERENCES `t1` (`id`)
+) TYPE=MyISAM;
+
+INSERT INTO t1(tst,tst1) VALUES("MySQL","MySQL AB"), ("MSSQL","Microsoft"), ("ORACLE","ORACLE");
+
+INSERT INTO t2(ParId) VALUES(1), (2), (3);
+
+select * from t2;
+
+UPDATE t2, t1 SET t2.tst = t1.tst, t2.tst1 = t1.tst1 WHERE t2.ParId = t1.Id;
+
+select * from t2;
+
+drop table if exists t1, t2 ;
+
+create table t1 (n numeric(10));
+create table t2 (n numeric(10));
+insert into t2 values (1),(2),(4),(8),(16),(32);
+select * from t2 left outer join t1 using (n);
+delete t1,t2 from t2 left outer join t1 using (n);
+select * from t2 left outer join t1 using (n);
+drop table t1,t2 ;
+
+#
+# Test with locking
+#
+
+create table t1 (n int(10) not null primary key, d int(10));
+create table t2 (n int(10) not null primary key, d int(10));
+insert into t1 values(1,1);
+insert into t2 values(1,10),(2,20);
+LOCK TABLES t1 write, t2 read;
+--error 1099
+DELETE t1.*, t2.* FROM t1,t2 where t1.n=t2.n;
+--error 1099
+UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+# The following should be fixed to not give an error
+--error 1099
+UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
+unlock tables;
+LOCK TABLES t1 write, t2 write;
+UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
+select * from t1;
+DELETE t1.*, t2.* FROM t1,t2 where t1.n=t2.n;
+select * from t1;
+select * from t2;
+unlock tables;
+drop table t1,t2;
+
+#
+# Test safe updates and timestamps
+#
+set sql_safe_updates=1;
+create table t1 (n int(10), d int(10));
+create table t2 (n int(10), d int(10));
+insert into t1 values(1,1);
+insert into t2 values(1,10),(2,20);
+--error 1175
+UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
+set sql_safe_updates=0;
+drop table t1,t2;
+set timestamp=1038401397;
+create table t1 (n int(10) not null primary key, d int(10), t timestamp);
+create table t2 (n int(10) not null primary key, d int(10), t timestamp);
+insert into t1 values(1,1,NULL);
+insert into t2 values(1,10,NULL),(2,20,NULL);
+set timestamp=1038000000;
+UPDATE t1,t2 SET t1.d=t2.d WHERE t1.n=t2.n;
+select n,d,unix_timestamp(t) from t1;
+select n,d,unix_timestamp(t) from t2;
+--error 1064
+UPDATE t1,t2 SET 1=2 WHERE t1.n=t2.n;
+drop table t1,t2;
+set timestamp=0;
+set sql_safe_updates=0;
+create table t1 (n int(10) not null primary key, d int(10));
+create table t2 (n int(10) not null primary key, d int(10));
+insert into t1 values(1,1), (3,3);
+insert into t2 values(1,10),(2,20);
+UPDATE t2 left outer join t1 on t1.n=t2.n SET t1.d=t2.d;
+select * from t1;
+select * from t2;
+drop table t1,t2;
+create table t1 (n int(10), d int(10));
+create table t2 (n int(10), d int(10));
+insert into t1 values(1,1),(1,2);
+insert into t2 values(1,10),(2,20);
+UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+select * from t1;
+select * from t2;
+drop table t1,t2;
+create table t1 (n int(10), d int(10));
+create table t2 (n int(10), d int(10));
+insert into t1 values(1,1),(3,2);
+insert into t2 values(1,10),(1,20);
+UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+select * from t1;
+select * from t2;
+drop table t1,t2;
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (1,'jedan'),(2,'dva'),(3,'tri'),(4,'xxxxxxxxxx'),(5,'a'),(10,''),(11,''),(12,''),(13,'');
+CREATE TABLE t2 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,'jedan'),(2,'dva'),(3,'tri'),(4,'xxxxxxxxxx'),(5,'a');
+CREATE TABLE t3 ( broj int(4) unsigned NOT NULL default '0', naziv char(25) NOT NULL default 'NEPOZNAT', PRIMARY KEY (broj)) TYPE=MyISAM;
+INSERT INTO t3 VALUES (1,'jedan'),(2,'dva');
+update t1,t2 set t1.naziv="aaaa" where t1.broj=t2.broj;
+update t1,t2,t3 set t1.naziv="bbbb", t2.naziv="aaaa" where t1.broj=t2.broj and t2.broj=t3.broj;
+drop table if exists t1,t2,t3;
+
+#
+# Test multi update with different join methods
+#
+
+CREATE TABLE t1 (a int not null primary key, b int not null, key (b));
+CREATE TABLE t2 (a int not null primary key, b int not null, key (b));
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+INSERT INTO t2 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+
+# Full join, without key
+update t1,t2 set t1.a=t1.a+100;
+select * from t1;
+
+# unique key
+update t1,t2 set t1.a=t1.a+100 where t1.a=101;
+select * from t1;
+
+# ref key
+update t1,t2 set t1.b=t1.b+10 where t1.b=2;
+select * from t1;
+
+# Range key (in t1)
+update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t2.a=t1.a-100;
+select * from t1;
+select * from t2;
+
+drop table t1,t2;
+CREATE TABLE t3 ( KEY1 varchar(50) NOT NULL default '', PARAM_CORR_DISTANCE_RUSH double default NULL, PARAM_CORR_DISTANCE_GEM double default NULL, PARAM_AVG_TARE double default NULL, PARAM_AVG_NB_DAYS double default NULL, PARAM_DEFAULT_PROP_GEM_SRVC varchar(50) default NULL, PARAM_DEFAULT_PROP_GEM_NO_ETIK varchar(50) default NULL, PARAM_SCENARIO_COSTS varchar(50) default NULL, PARAM_DEFAULT_WAGON_COST double default NULL, tmp int(11) default NULL, PRIMARY KEY (KEY1)) TYPE=MyISAM;
+INSERT INTO t3 VALUES ('A',1,1,22,3.2,'R','R','BASE2',0.24,NULL);
+create table t1 (A varchar(1));
+insert into t1 values ("A") ,("B"),("C"),("D");
+create table t2(Z varchar(15));
+insert into t2(Z) select concat(a.a,b.a,c.a,d.a) from t1 as a, t1 as b, t1 as c, t1 as d;
+update t2,t3 set Z =param_scenario_costs;
+drop table t1,t2,t3;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,1),(2,1),(3,1);
+insert into t2 values (1,1), (3,1);
+update t1 left join t2 on t1.a=t2.a set t1.b=2, t2.b=2 where t1.b=1 and t2.b=1 or t2.a is NULL;
+select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and t2.b=1 or t2.a is NULL;
+drop table t1,t2;
+
+#
+# Test reuse of same table
+#
+
+create table t1 (a int not null auto_increment primary key, b int not null);
+insert into t1 (b) values (1),(2),(3),(4);
+update t1, t1 as t2 set t1.b=t2.b+1 where t1.a=t2.a;
+select * from t1;
+drop table t1;
+
+# Test multi-update and multi-delete with impossible where
+
+drop table if exists t1, t2;
+create table t1(id1 smallint(5), field char(5));
+create table t2(id2 smallint(5), field char(5));
+
+insert into t1 values (1, 'a'), (2, 'aa');
+insert into t2 values (1, 'b'), (2, 'bb');
+
+select * from t1;
+select * from t2;
+
+update t2 inner join t1 on t1.id1=t2.id2
+ set t2.field=t1.field
+ where 0=1;
+update t2, t1 set t2.field=t1.field
+ where t1.id1=t2.id2 and 0=1;
+
+delete t1, t2 from t2 inner join t1 on t1.id1=t2.id2
+ where 0=1;
+delete t1, t2 from t2,t1
+ where t1.id1=t2.id2 and 0=1;
+
+drop table t1,t2;
+
diff --git a/mysql-test/t/myisam-blob-master.opt b/mysql-test/t/myisam-blob-master.opt
new file mode 100644
index 00000000000..1a1076c7bad
--- /dev/null
+++ b/mysql-test/t/myisam-blob-master.opt
@@ -0,0 +1 @@
+--max-allowed-packet=24M --skip-innodb --key-buffer-size=1M
diff --git a/mysql-test/t/myisam-blob.test b/mysql-test/t/myisam-blob.test
new file mode 100644
index 00000000000..d58222ec8bf
--- /dev/null
+++ b/mysql-test/t/myisam-blob.test
@@ -0,0 +1,30 @@
+#
+# Test bugs in the MyISAM code with blobs
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+# Bug #2159 (Problem with update of blob to > 16M)
+
+CREATE TABLE t1 (data LONGBLOB) ENGINE=myisam;
+INSERT INTO t1 (data) VALUES (NULL);
+UPDATE t1 set data=repeat('a',18*1024*1024);
+select length(data) from t1;
+delete from t1 where left(data,1)='a';
+check table t1;
+truncate table t1;
+INSERT INTO t1 (data) VALUES (repeat('a',1*1024*1024));
+INSERT INTO t1 (data) VALUES (repeat('b',16*1024*1024-1024));
+delete from t1 where left(data,1)='b';
+check table t1;
+
+# now we have two blocks in the table, first is a 1M record and second is
+# a 16M delete block.
+
+UPDATE t1 set data=repeat('c',17*1024*1024);
+check table t1;
+delete from t1 where left(data,1)='c';
+check table t1;
+drop table t1;
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index e6772c4c0ac..7302e5dfdda 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -2,7 +2,13 @@
# Test bugs in the MyISAM code
#
-drop table if exists t1;
+# Initialise
+drop table if exists t1,t2;
+
+#
+# Test problem with CHECK TABLE;
+#
+
CREATE TABLE t1 (
STRING_DATA char(255) default NULL,
KEY STRING_DATA (STRING_DATA)
@@ -24,11 +30,13 @@ drop table t1;
create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a));
let $1=100;
+disable_query_log;
while ($1)
{
eval insert into t1 (b) values(repeat(char(65+$1),65550-$1));
dec $1;
}
+enable_query_log;
check table t1;
repair table t1;
delete from t1 where (a & 1);
@@ -80,7 +88,6 @@ DROP TABLE t1;
# in ha_myisam::repair, and index size is changed (decreased).
#
-drop table if exists t1;
create table t1 ( t1 char(255), key(t1(250)));
insert t1 values ('137513751375137513751375137513751375137569516951695169516951695169516951695169');
insert t1 values ('178417841784178417841784178417841784178403420342034203420342034203420342034203');
@@ -119,7 +126,6 @@ drop table t1;
# test of myisam with huge number of packed fields
#
-drop table if exists t1;
create table t1 (i1 int, i2 int, i3 int, i4 int, i5 int, i6 int, i7 int, i8
int, i9 int, i10 int, i11 int, i12 int, i13 int, i14 int, i15 int, i16 int, i17
int, i18 int, i19 int, i20 int, i21 int, i22 int, i23 int, i24 int, i25 int,
@@ -284,4 +290,135 @@ insert into t1 values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Sergei");
+update t1 set b=repeat('a',256);
+update t1 set i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0;
+check table t1;
+drop table t1;
+
+#
+# Test of REPAIR that once failed
+#
+CREATE TABLE `t1` (
+ `post_id` mediumint(8) unsigned NOT NULL auto_increment,
+ `topic_id` mediumint(8) unsigned NOT NULL default '0',
+ `post_time` datetime NOT NULL default '0000-00-00 00:00:00',
+ `post_text` text NOT NULL,
+ `icon_url` varchar(10) NOT NULL default '',
+ `sign` tinyint(1) unsigned NOT NULL default '0',
+ `post_edit` varchar(150) NOT NULL default '',
+ `poster_login` varchar(35) NOT NULL default '',
+ `ip` varchar(15) NOT NULL default '',
+ PRIMARY KEY (`post_id`),
+ KEY `post_time` (`post_time`),
+ KEY `ip` (`ip`),
+ KEY `poster_login` (`poster_login`),
+ KEY `topic_id` (`topic_id`),
+ FULLTEXT KEY `post_text` (`post_text`)
+) TYPE=MyISAM;
+
+INSERT INTO t1 (post_text) VALUES ('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test'),('ceci est un test');
+
+REPAIR TABLE t1;
+CHECK TABLE t1;
+drop table t1;
+
+#
+# Test of creating table with too long key
+#
+
+--error 1071
+CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), KEY t1 (a, b, c));
+CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255));
+--error 1071
+ALTER TABLE t1 ADD INDEX t1 (a, b, c);
+DROP TABLE t1;
+
+#
+# Test of cardinality of keys with NULL
+#
+
+CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
+INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
+INSERT into t2 values (1,1,1), (2,2,2);
+optimize table t1;
+show index from t1;
+explain select * from t1,t2 where t1.a=t2.a;
+explain select * from t1,t2 force index(a) where t1.a=t2.a;
+explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
+explain select * from t1,t2 where t1.b=t2.b;
+explain select * from t1,t2 force index(c) where t1.a=t2.a;
+explain select * from t1 where a=0 or a=2;
+explain select * from t1 force index (a) where a=0 or a=2;
+drop table t1,t2;
+
+#
+# Test bug when updating a split dynamic row where keys are not changed
+#
+
+create table t1 (a int not null auto_increment primary key, b varchar(255));
+insert into t1 (b) values (repeat('a',100)),(repeat('b',100)),(repeat('c',100));
+update t1 set b=repeat(left(b,1),200) where a=1;
+delete from t1 where (a & 1)= 0;
+update t1 set b=repeat('e',200) where a=1;
+flush tables;
+check table t1;
+
+#
+# check updating with keys
+#
+
+disable_query_log;
+let $1 = 100;
+while ($1)
+{
+ eval insert into t1 (b) values (repeat(char(($1 & 32)+65), $1));
+ dec $1;
+}
+enable_query_log;
+update t1 set b=repeat(left(b,1),255) where a between 1 and 5;
+update t1 set b=repeat(left(b,1),10) where a between 32 and 43;
+update t1 set b=repeat(left(b,1),2) where a between 64 and 66;
+update t1 set b=repeat(left(b,1),65) where a between 67 and 70;
+check table t1;
+insert into t1 (b) values (repeat('z',100));
+update t1 set b="test" where left(b,1) > 'n';
+check table t1;
+drop table t1;
+
+#
+# two bugs in myisam-space-stripping feature
+#
+create table t1 ( a text not null, key a (a(20)));
+insert into t1 values ('aaa '),('aaa'),('aa');
+check table t1;
+repair table t1;
+select concat(a,'.') from t1 where a='aaa';
+select concat(a,'.') from t1 where binary a='aaa';
+update t1 set a='bbb' where a='aaa';
+select concat(a,'.') from t1;
+drop table t1;
+
+#
+# Third bug in the same code (BUG#2295)
+#
+
+create table t1(a text not null, b text not null, c text not null, index (a(10),b(10),c(10)));
+insert into t1 values('807780', '477', '165');
+insert into t1 values('807780', '477', '162');
+insert into t1 values('807780', '472', '162');
+select * from t1 where a='807780' and b='477' and c='165';
+drop table t1;
+
+#
+# Test text and unique
+#
+create table t1 (a int not null auto_increment primary key, b text not null, unique b (b(20)));
+insert into t1 (b) values ('a'),('a '),('a ');
+select concat(b,'.') from t1;
+update t1 set b='b ' where a=2;
+--error 1062
+update t1 set b='b ' where a > 1;
+delete from t1 where b='b';
+select a,concat(b,'.') from t1;
drop table t1;
diff --git a/mysql-test/t/mysqlbinlog-master.opt b/mysql-test/t/mysqlbinlog-master.opt
new file mode 100644
index 00000000000..ac1a87c73b3
--- /dev/null
+++ b/mysql-test/t/mysqlbinlog-master.opt
@@ -0,0 +1 @@
+--max-binlog-size=4096
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
new file mode 100644
index 00000000000..e22a37fabfd
--- /dev/null
+++ b/mysql-test/t/mysqlbinlog.test
@@ -0,0 +1,103 @@
+# We are using .opt file since we need small binlog size
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+# we need this for getting fixed timestamps inside of this test
+set timestamp=1000000000;
+
+create table t1 (word varchar(20));
+create table t2 (id int auto_increment not null primary key);
+
+# simple test for simple statement and various events
+insert into t1 values ("abirvalg");
+insert into t2 values ();
+# Should be uncommented in 4.1
+# set @a:=1
+# insert into t2 values (@a);
+
+# test for load data and load data distributed among the several
+# files (we need to fill up first binlog)
+load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words.dat' into table t1;
+load data infile '../../std_data/words.dat' into table t1;
+# simple query to show more in second binlog
+insert into t1 values ("Alas");
+flush logs;
+
+# delimiters are for easier debugging in future
+--disable_query_log
+select "--- Local --" as "";
+--enable_query_log
+
+#
+# We should use --short-form everywhere because in other case output will
+# be time dependend. Better than nothing.
+#
+
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ $MYSQL_TEST_DIR/var/log/master-bin.001
+
+# this should not fail but shouldn't produce any working statements
+--disable_query_log
+select "--- Broken LOAD DATA --" as "";
+--enable_query_log
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ $MYSQL_TEST_DIR/var/log/master-bin.002
+
+# this should show almost nothing
+--disable_query_log
+select "--- --database --" as "";
+--enable_query_log
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --database=nottest $MYSQL_TEST_DIR/var/log/master-bin.001
+
+# this test for position option
+--disable_query_log
+select "--- --position --" as "";
+--enable_query_log
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --position=27 $MYSQL_TEST_DIR/var/log/master-bin.002
+
+# These are tests for remote binlog.
+# They should return the same as previous test.
+# But now they are not. V. Vagin should fix this.
+# We test all the same options second time since code for remote case is
+# essentially different. If code for both cases will be unified we'll be
+# able to throw out most of this.
+
+--disable_query_log
+select "--- Remote --" as "";
+--enable_query_log
+
+# This is broken now
+# By the way it seems that remote version fetches all events with name >= master-bin.001
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.001
+
+# This is broken too
+--disable_query_log
+select "--- Broken LOAD DATA --" as "";
+--enable_query_log
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.002
+
+# And this too ! (altough it is documented)
+--disable_query_log
+select "--- --database --" as "";
+--enable_query_log
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --database=nottest master-bin.001
+
+# Strangely but this works
+--disable_query_log
+select "--- --position --" as "";
+--enable_query_log
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --position=27 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.002
+
+# clean up
+drop table t1;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
new file mode 100644
index 00000000000..bc63dc37d96
--- /dev/null
+++ b/mysql-test/t/mysqldump.test
@@ -0,0 +1,32 @@
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# XML output
+
+CREATE TABLE t1(a int);
+INSERT INTO t1 VALUES (1), (2);
+--exec $MYSQL_DUMP --skip-comments -X test t1
+DROP TABLE t1;
+
+#
+# Bug #2005
+#
+
+CREATE TABLE t1 (a decimal(240, 20));
+INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"),
+("0987654321098765432109876543210987654321");
+--exec $MYSQL_DUMP --skip-comments test t1
+DROP TABLE t1;
+
+#
+# Bug #2055
+#
+
+CREATE TABLE t1 (a double);
+INSERT INTO t1 VALUES (-9e999999);
+# The following replaces is here because some systems replaces the above
+# double with '-inf' and others with MAX_DOUBLE
+--replace_result (-1.79769313486232e+308) (RES) (NULL) (RES)
+--exec $MYSQL_DUMP --skip-comments test t1
+DROP TABLE t1;
diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test
index a010ab38e07..6fea7f0d10d 100644
--- a/mysql-test/t/null.test
+++ b/mysql-test/t/null.test
@@ -25,7 +25,6 @@ drop table t1;
# Test problem med index on NULL columns and testing with =NULL;
#
-DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
indexed_field int default NULL,
KEY indexed_field (indexed_field)
@@ -35,3 +34,48 @@ SELECT * FROM t1 WHERE indexed_field=NULL;
SELECT * FROM t1 WHERE indexed_field IS NULL;
SELECT * FROM t1 WHERE indexed_field<=>NULL;
DROP TABLE t1;
+
+#
+# Testing of IFNULL
+#
+create table t1 (a int, b int) type=myisam;
+insert into t1 values(20,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a;
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+insert into t1 values(10,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+drop table t1;
+
+#
+# Test inserting and updating with NULL
+#
+CREATE TABLE t1 (a varchar(16) NOT NULL, b smallint(6) NOT NULL, c datetime NOT NULL, d smallint(6) NOT NULL);
+INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55";
+UPDATE t1 SET d=1/NULL;
+UPDATE t1 SET d=NULL;
+--error 1048
+INSERT INTO t1 (a) values (null);
+--error 1048
+INSERT INTO t1 (a) values (1/null);
+INSERT INTO t1 (a) values (null),(null);
+--error 1048
+INSERT INTO t1 (b) values (null);
+--error 1048
+INSERT INTO t1 (b) values (1/null);
+INSERT INTO t1 (b) values (null),(null);
+--error 1048
+INSERT INTO t1 (c) values (null);
+--error 1048
+INSERT INTO t1 (c) values (1/null);
+INSERT INTO t1 (c) values (null),(null);
+--error 1048
+INSERT INTO t1 (d) values (null);
+--error 1048
+INSERT INTO t1 (d) values (1/null);
+INSERT INTO t1 (d) values (null),(null);
+select * from t1;
+drop table t1;
+
diff --git a/mysql-test/t/odbc.test b/mysql-test/t/odbc.test
index 4629a08fd3f..3e0fc214d3e 100644
--- a/mysql-test/t/odbc.test
+++ b/mysql-test/t/odbc.test
@@ -8,6 +8,7 @@ select {fn length("hello")}, { date "1997-10-20" };
# Test retreiving row with last insert_id value.
#
+drop table if exists t1;
create table t1 (a int not null auto_increment,b int not null,primary key (a,b));
insert into t1 SET A=NULL,B=1;
insert into t1 SET a=null,b=2;
diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test
new file mode 100644
index 00000000000..8fe547db615
--- /dev/null
+++ b/mysql-test/t/olap.test
@@ -0,0 +1,27 @@
+drop table if exists sales;
+create table sales ( product varchar(32), country varchar(32), year int, profit int);
+insert into sales values ( 'Computer', 'India',2000, 1200),
+( 'TV', 'United States', 1999, 150),
+( 'Calculator', 'United States', 1999,50),
+( 'Computer', 'United States', 1999,1500),
+( 'Computer', 'United States', 2000,1500),
+( 'TV', 'United States', 2000, 150),
+( 'TV', 'India', 2000, 100),
+( 'TV', 'India', 2000, 100),
+( 'Calculator', 'United States', 2000,75),
+( 'Calculator', 'India', 2000,75),
+( 'TV', 'India', 1999, 100),
+( 'Computer', 'India', 1999,1200),
+( 'Computer', 'United States', 2000,1500),
+( 'Calculator', 'United States', 2000,75);
+--error 1235
+select product, country , year, sum(profit) from sales group by product, country, year with cube;
+--error 1235
+explain select product, country , year, sum(profit) from sales group by product, country, year with cube;
+--error 1235
+select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+--error 1235
+explain select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+--error 1235
+select product, country , year, sum(profit) from sales group by product, country, year with cube union all select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+drop table sales;
diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test
new file mode 100644
index 00000000000..25790f24738
--- /dev/null
+++ b/mysql-test/t/openssl_1.test
@@ -0,0 +1,43 @@
+# We test openssl. Result set is optimized to be compiled with --with-openssl.
+# Use mysql-test-run with --with-openssl option.
+-- source include/have_openssl_1.inc
+
+drop table if exists t1;
+create table t1(f1 int);
+insert into t1 values (5);
+
+grant select on test.* to ssl_user1@localhost require SSL;
+grant select on test.* to ssl_user2@localhost require cipher "EDH-RSA-DES-CBC3-SHA";
+grant select on test.* to ssl_user3@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com";
+grant select on test.* to ssl_user4@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/Email=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com";
+flush privileges;
+connect (con1,localhost,ssl_user1,,);
+connect (con2,localhost,ssl_user2,,);
+connect (con3,localhost,ssl_user3,,);
+connect (con4,localhost,ssl_user4,,);
+
+connection con1;
+select * from t1;
+--error 1044;
+delete from t1;
+
+connection con2;
+select * from t1;
+--error 1044;
+delete from t1;
+
+connection con3;
+select * from t1;
+--error 1044;
+delete from t1;
+
+connection con4;
+select * from t1;
+--error 1044;
+delete from t1;
+
+connection default;
+delete from mysql.user where user='ssl_user%';
+delete from mysql.db where user='ssl_user%';
+flush privileges;
+drop table t1;
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index d6be4c1c45c..8215ec84ae3 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -23,7 +23,7 @@ INSERT INTO t1 VALUES (2,7,'60671569','Y');
INSERT INTO t1 VALUES (2,3,'dd','Y');
CREATE TABLE t2 (
- id int(6) DEFAULT '0' NOT NULL auto_increment,
+ id int(6) NOT NULL auto_increment,
description varchar(40) NOT NULL,
idform varchar(40),
ordre int(6) unsigned DEFAULT '0' NOT NULL,
@@ -206,8 +206,54 @@ ORDER by lastchange_datum DESC LIMIT 2;
drop table t1;
#
-# Test optimizing bug with EQ_REF tables, where some ORDER BY parts where
-# wrongly removed.
+# Test optimization of ORDER BY DESC
+#
+
+create table t1 (a int not null, b int, c varchar(10), key (a, b, c));
+insert into t1 values (1, NULL, NULL), (1, NULL, 'b'), (1, 1, NULL), (1, 1, 'b'), (1, 1, 'b'), (2, 1, 'a'), (2, 1, 'b'), (2, 2, 'a'), (2, 2, 'b'), (2, 3, 'c'),(1,3,'b');
+
+explain select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc;
+select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc;
+explain select * from t1 where a >= 1 and a < 3 order by a desc;
+select * from t1 where a >= 1 and a < 3 order by a desc;
+explain select * from t1 where a = 1 order by a desc, b desc;
+select * from t1 where a = 1 order by a desc, b desc;
+explain select * from t1 where a = 1 and b is null order by a desc, b desc;
+select * from t1 where a = 1 and b is null order by a desc, b desc;
+explain select * from t1 where a >= 1 and a < 3 and b >0 order by a desc,b desc;
+explain select * from t1 where a = 2 and b >0 order by a desc,b desc;
+explain select * from t1 where a = 2 and b is null order by a desc,b desc;
+explain select * from t1 where a = 2 and (b is null or b > 0) order by a
+desc,b desc;
+explain select * from t1 where a = 2 and b > 0 order by a desc,b desc;
+explain select * from t1 where a = 2 and b < 2 order by a desc,b desc;
+explain select * from t1 where a = 1 order by b desc;
+select * from t1 where a = 1 order by b desc;
+#
+# Test things when we don't have NULL keys
+#
+
+alter table t1 modify b int not null, modify c varchar(10) not null;
+explain select * from t1 order by a, b, c;
+select * from t1 order by a, b, c;
+explain select * from t1 order by a desc, b desc, c desc;
+select * from t1 order by a desc, b desc, c desc;
+# test multiple ranges, NO_MAX_RANGE and EQ_RANGE
+explain select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc;
+select * from t1 where (a = 1 and b = 1 and c = 'b') or (a > 2) order by a desc;
+# test NEAR_MAX, NO_MIN_RANGE
+explain select * from t1 where a < 2 and b <= 1 order by a desc, b desc;
+select * from t1 where a < 2 and b <= 1 order by a desc, b desc;
+select count(*) from t1 where a < 5 and b > 0;
+select * from t1 where a < 5 and b > 0 order by a desc,b desc;
+# test HA_READ_AFTER_KEY (at the end of the file), NEAR_MIN
+explain select * from t1 where a between 1 and 3 and b <= 1 order by a desc, b desc;
+select * from t1 where a between 1 and 3 and b <= 1 order by a desc, b desc;
+# test HA_READ_AFTER_KEY (in the middle of the file)
+explain select * from t1 where a between 0 and 1 order by a desc, b desc;
+select * from t1 where a between 0 and 1 order by a desc, b desc;
+drop table t1;
+
CREATE TABLE t1 (
gid int(10) unsigned NOT NULL auto_increment,
@@ -249,24 +295,61 @@ EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.skr = t3.uid order by t1.gid,
drop table t1,t2,t3;
#
-# Problem with lookup on NULL (Bug 479)
+# Test of bug when doing an ORDER BY with const items
#
CREATE TABLE t1 (
- t1_id int(10) unsigned NOT NULL default '0',
- ref_id int(10) unsigned default NULL,
- PRIMARY KEY (t1_id)
-) TYPE=MyISAM;
-INSERT INTO t1 VALUES (2401,14590),(2425,NULL);
+ `titre` char(80) NOT NULL default '',
+ `numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+ `date` datetime NOT NULL default '0000-00-00 00:00:00',
+ `auteur` char(35) NOT NULL default '',
+ `icone` tinyint(2) unsigned NOT NULL default '0',
+ `lastauteur` char(35) NOT NULL default '',
+ `nbrep` smallint(6) unsigned NOT NULL default '0',
+ `dest` char(35) NOT NULL default '',
+ `lu` tinyint(1) unsigned NOT NULL default '0',
+ `vue` mediumint(8) unsigned NOT NULL default '0',
+ `ludest` tinyint(1) unsigned NOT NULL default '0',
+ `ouvert` tinyint(1) unsigned NOT NULL default '1',
+ PRIMARY KEY (`numeropost`),
+ KEY `date` (`date`),
+ KEY `dest` (`dest`,`ludest`),
+ KEY `auteur` (`auteur`,`lu`),
+ KEY `auteur_2` (`auteur`,`date`),
+ KEY `dest_2` (`dest`,`date`)
+) CHECKSUM=1;
+
CREATE TABLE t2 (
- t2_id int(10) unsigned NOT NULL default '0',
- ref_id int(10) unsigned NOT NULL default '0',
- str varchar(20) default NULL,
- PRIMARY KEY (t2_id),
- KEY ref_id (ref_id)
-) TYPE=MyISAM;
-INSERT INTO t2 VALUES (112633,14590,'t2 112633'),(112634,14590,'t2 112634'),(113166,14641,'t2 113166'),(113167,14641,'t2 113167'),(113168,14641,'t2 113168'),(113169,14641,'t2 113169'),(113170,14641,'t2 113170'),(113171,14641,'t2 113171'),(113172,14641,'t2 113172'),(113173,14641,'t2 113173'),(113174,14641,'t2 113174'),(113175,14641,'t2 113175'),(113436,14674,'t2 113436'),(113437,14674,'t2 113437'),(113486,14689,'t2 113486'),(113487,14689,'t2 113487'),(113488,14689,'t2 113488'),(113489,14689,'t2 113489'),(113504,14795,'t2 113504'),(115396,15024,'t2 115396'),(115397,15024,'t2 115397');
-SELECT t2_id, str FROM t1, t2 WHERE t1_id = 2401 AND t1.ref_id = t2.ref_id ORDER BY str, t2_id;
-# This one gave an error
-SELECT t2_id, str FROM t1, t2 WHERE t1_id = 2425 AND t1.ref_id = t2.ref_id ORDER BY str, t2_id;
-DROP TABLE t1,t2;
+ `numeropost` mediumint(8) unsigned NOT NULL default '0',
+ `pseudo` char(35) NOT NULL default '',
+ PRIMARY KEY (`numeropost`,`pseudo`),
+ KEY `pseudo` (`pseudo`)
+);
+
+INSERT INTO t1 (titre,auteur,dest) VALUES ('test','joce','bug');
+INSERT INTO t2 (numeropost,pseudo) VALUES (1,'joce'),(1,'bug');
+SELECT titre,t1.numeropost,auteur,icone,nbrep,0,date,vue,ouvert,lastauteur,dest FROM t2 LEFT JOIN t1 USING(numeropost) WHERE t2.pseudo='joce' ORDER BY date DESC LIMIT 0,30;
+SELECT titre,t1.numeropost,auteur,icone,nbrep,'0',date,vue,ouvert,lastauteur,dest FROM t2 LEFT JOIN t1 USING(numeropost) WHERE t2.pseudo='joce' ORDER BY date DESC LIMIT 0,30;
+drop table t1,t2;
+
+#
+# Test order by with NULL values
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (1, 2);
+INSERT INTO t1 VALUES (3, 4);
+INSERT INTO t1 VALUES (5, NULL);
+SELECT * FROM t1 ORDER BY b;
+SELECT * FROM t1 ORDER BY b DESC;
+SELECT * FROM t1 ORDER BY (a + b);
+SELECT * FROM t1 ORDER BY (a + b) DESC;
+DROP TABLE t1;
+
+#
+# Bug #1945 - Crashing bug with bad User Variables in UPDATE ... ORDER BY ...
+#
+CREATE TABLE t1 (a INT, b INT);
+SET @id=0;
+UPDATE t1 SET a=0 ORDER BY (a=@id), b;
+DROP TABLE t1;
+
diff --git a/mysql-test/t/order_fill_sortbuf-master.opt b/mysql-test/t/order_fill_sortbuf-master.opt
new file mode 100644
index 00000000000..116494d4588
--- /dev/null
+++ b/mysql-test/t/order_fill_sortbuf-master.opt
@@ -0,0 +1 @@
+--set-variable=sort_buffer=0
diff --git a/mysql-test/t/order_fill_sortbuf.test b/mysql-test/t/order_fill_sortbuf.test
new file mode 100644
index 00000000000..6419f2a93df
--- /dev/null
+++ b/mysql-test/t/order_fill_sortbuf.test
@@ -0,0 +1,21 @@
+#
+# This test does a create-select with ORDER BY, where there is so many
+# rows MySQL needs to use a merge during the sort phase.
+#
+
+drop table if exists t1,t2;
+CREATE TABLE `t1` (
+ `id` int(11) NOT NULL default '0',
+ `id2` int(11) NOT NULL default '0',
+ `id3` int(11) NOT NULL default '0');
+let $1=4000;
+disable_query_log;
+while ($1)
+ {
+ eval insert into t1 (id,id2,id3) values ($1,$1,$1);
+ dec $1;
+ }
+enable_query_log;
+create table t2 select id2 from t1 order by id3;
+select count(*) from t2;
+drop table t1,t2;
diff --git a/mysql-test/t/packet.test b/mysql-test/t/packet.test
new file mode 100644
index 00000000000..cbeaa04ca52
--- /dev/null
+++ b/mysql-test/t/packet.test
@@ -0,0 +1,31 @@
+
+#
+# Check protocol handling
+#
+
+connect (con1,localhost,root,,);
+
+connection con1;
+set global max_allowed_packet=100;
+set max_allowed_packet=100;
+set global net_buffer_length=100;
+set net_buffer_length=100;
+# Have to be > 1024 as min value of net_buffer_length is 1024
+SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
+# Should return NULL as 2000 is bigger than max_allowed_packet
+select repeat('a',2000);
+
+#
+# Connection 2 should get error for too big packets
+#
+connect (con2,localhost,root,,);
+connection con2;
+select @@net_buffer_length, @@max_allowed_packet;
+--error 1153
+SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
+set global max_allowed_packet=default;
+set max_allowed_packet=default;
+set global net_buffer_length=default;
+set net_buffer_length=default;
+SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
+select length(repeat('a',2000));
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
new file mode 100644
index 00000000000..ad0dc80e2f7
--- /dev/null
+++ b/mysql-test/t/query_cache.test
@@ -0,0 +1,509 @@
+-- source include/have_query_cache.inc
+
+#
+# Tests with query cache
+#
+set GLOBAL query_cache_size=1355776;
+
+# Reset query cache variables.
+
+flush query cache; # This crashed in some versions
+flush query cache; # This crashed in some versions
+reset query cache;
+flush status;
+drop table if exists t1,t2,t3,t4,t11,t21;
+drop database if exists mysqltest;
+
+#
+# First simple test
+#
+
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+select * from t1;
+select sql_no_cache * from t1;
+select length(now()) from t1;
+
+# Only check the variables that are independent of the machine and startup
+# options
+
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+
+drop table t1;
+
+show status like "Qcache_queries_in_cache";
+
+#
+# MERGE TABLES with INSERT/UPDATE and DELETE
+#
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+create table t2 (a int not null);
+insert into t2 values (4),(5),(6);
+create table t3 (a int not null) type=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST;
+# insert
+select * from t3;
+select * from t3;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+insert into t2 values (7);
+show status like "Qcache_queries_in_cache";
+select * from t1;
+select * from t1;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+insert into t3 values (8);
+show status like "Qcache_queries_in_cache";
+# update
+select * from t3;
+show status like "Qcache_queries_in_cache";
+update t2 set a=9 where a=7;
+show status like "Qcache_queries_in_cache";
+select * from t1;
+show status like "Qcache_queries_in_cache";
+update t3 set a=10 where a=1;
+show status like "Qcache_queries_in_cache";
+#delete
+select * from t3;
+show status like "Qcache_queries_in_cache";
+delete from t2 where a=9;
+show status like "Qcache_queries_in_cache";
+select * from t1;
+show status like "Qcache_queries_in_cache";
+delete from t3 where a=10;
+show status like "Qcache_queries_in_cache";
+drop table t1, t2, t3;
+#
+# FLUSH QUERY CACHE
+#
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+create table t2 (a int not null);
+insert into t2 values (1),(2),(3);
+select * from t1;
+select * from t2;
+insert into t1 values (4);
+show status like "Qcache_free_blocks";
+flush query cache;
+show status like "Qcache_free_blocks";
+drop table t1, t2;
+# With join results...
+create table t1 (a text not null);
+create table t11 (a text not null);
+create table t2 (a text not null);
+create table t21 (a text not null);
+create table t3 (a text not null);
+insert into t1 values("1111111111111111111111111111111111111111111111111111");
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+# t11 and t21 must be over 4Kb (QUERY_CACHE_MIN_RESULT_DATA_SIZE)
+insert into t11 select * from t1;
+insert into t21 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+#results of t3 must be > 0.5Mb
+insert into t3 select * from t1;
+insert into t3 select * from t2;
+insert into t3 select * from t1;
+disable_result_log;
+select * from t11;
+select * from t21;
+enable_result_log;
+show status like "Qcache_total_blocks";
+show status like "Qcache_free_blocks";
+disable_result_log;
+insert into t11 values("");
+select * from t3;
+enable_result_log;
+show status like "Qcache_total_blocks";
+show status like "Qcache_free_blocks";
+flush query cache;
+show status like "Qcache_total_blocks";
+show status like "Qcache_free_blocks";
+drop table t1, t2, t3, t11, t21;
+#
+# SELECT SQL_CACHE ...
+#
+set query_cache_type=demand;
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+select sql_cache * from t1 union select * from t1;
+set query_cache_type=2;
+select sql_cache * from t1 union select * from t1;
+select * from t1 union select sql_cache * from t1;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+set query_cache_type=on;
+#
+# RESET QUERY CACHE
+#
+reset query cache;
+show status like "Qcache_queries_in_cache";
+#
+# SELECT SQL_NO_CACHE
+#
+select sql_no_cache * from t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+#
+# Check that queries that uses NOW(), LAST_INSERT_ID()... are not cached.
+#
+create table t1 (a text not null);
+select CONNECTION_ID() from t1;
+#GET_LOCK
+#RELEASE_LOCK
+#LOAD_FILE
+select FOUND_ROWS();
+select NOW() from t1;
+select CURDATE() from t1;
+select CURTIME() from t1;
+select DATABASE() from t1;
+select ENCRYPT("test") from t1;
+select LAST_INSERT_ID() from t1;
+select RAND() from t1;
+select UNIX_TIMESTAMP() from t1;
+select USER() from t1;
+select benchmark(1,1) from t1;
+show status like "Qcache_queries_in_cache";
+#
+# Tests when the cache is filled
+#
+create table t2 (a text not null);
+insert into t1 values("1111111111111111111111111111111111111111111111111111");
+insert into t2 select * from t1;
+insert into t1 select * from t2; # 2
+insert into t2 select * from t1; # 3
+insert into t1 select * from t2; # 5
+insert into t2 select * from t1; # 8
+insert into t1 select * from t2; # 13
+insert into t2 select * from t1; # 21
+insert into t1 select * from t2; # 34
+insert into t2 select * from t1; # 55
+insert into t1 select * from t2; # 89
+insert into t2 select * from t1; # 144
+insert into t1 select * from t2; # 233
+insert into t2 select * from t1; # 357
+insert into t1 select * from t2; # 610
+insert into t2 select * from t1; # 987
+insert into t1 select * from t2; # 1597
+insert into t2 select * from t1; # 2584
+insert into t1 select * from t2; # 4181
+
+show status like "Qcache_hits";
+show status like "Qcache_lowmem_prunes";
+disable_result_log;
+select a as a1, a as a2 from t1;
+select a as a2, a as a3 from t1;
+select a as a3, a as a4 from t1;
+# next query must be out of 1Mb cache
+select a as a1, a as a2 from t1;
+enable_result_log;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_lowmem_prunes";
+reset query cache;
+#
+# Query bigger then query_cache_limit
+#
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+insert into t2 select * from t1;
+insert into t1 select * from t2;
+disable_result_log;
+select * from t1;
+enable_result_log;
+show status like "Qcache_queries_in_cache";
+drop table t1,t2;
+
+#
+# noncachable ODBC work around (and prepare cache for drop database)
+#
+create database mysqltest;
+create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i));
+insert into mysqltest.t1 (a) values (1);
+select * from mysqltest.t1 where i is null;
+
+#
+# drop db
+#
+create table t1(a int);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+select * from mysqltest.t1;
+show status like "Qcache_queries_in_cache";
+drop database mysqltest;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+
+#
+# Charset convertion (cp1251_koi8 always present)
+#
+create table t1 (a char(1) not null);
+insert into t1 values("á");
+select * from t1;
+set CHARACTER SET cp1251_koi8;
+select * from t1;
+set CHARACTER SET DEFAULT;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+drop table t1;
+
+# The following tests can't be done as the values differen on 32 and 64 bit
+# machines :(
+#show variables like "query_cache_size";
+#show status like "Qcache_free_memory";
+
+#
+# same tables in different db
+#
+create database if not exists mysqltest;
+create table mysqltest.t1 (i int not null);
+create table t1 (i int not null);
+insert into mysqltest.t1 (i) values (1);
+insert into t1 (i) values (2);
+
+select * from t1;
+use mysqltest;
+select * from t1;
+select * from t1;
+use test;
+select * from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+
+drop database mysqltest;
+drop table t1;
+
+#
+# FOUND_ROWS()
+#
+
+create table t1 (i int not null);
+insert into t1 (i) values (1),(2),(3),(4);
+
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select * from t1 where i=1;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select SQL_CALC_FOUND_ROWS * from t1 limit 2;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select * from t1 where i=1;
+select FOUND_ROWS();
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+drop table t1;
+
+#
+# Test insert delayed
+#
+
+flush query cache;
+reset query cache;
+
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+select * from t1;
+select * from t1;
+show status like "Qcache_queries_in_cache";
+insert delayed into t1 values (4);
+--sleep 5 # Wait for insert delayed to be executed.
+select a from t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+show status like "Qcache_queries_in_cache";
+
+#
+# Test of query cache resizing
+#
+create table t1 (a int);
+set GLOBAL query_cache_size=1000;
+show global variables like "query_cache_size";
+select * from t1;
+set GLOBAL query_cache_size=1024;
+show global variables like "query_cache_size";
+select * from t1;
+set GLOBAL query_cache_size=10240;
+show global variables like "query_cache_size";
+select * from t1;
+set GLOBAL query_cache_size=20480;
+show global variables like "query_cache_size";
+select * from t1;
+set GLOBAL query_cache_size=40960;
+show global variables like "query_cache_size";
+select * from t1;
+set GLOBAL query_cache_size=51200;
+show global variables like "query_cache_size";
+select * from t1;
+set GLOBAL query_cache_size=61440;
+show global variables like "query_cache_size";
+select * from t1;
+set GLOBAL query_cache_size=81920;
+show global variables like "query_cache_size";
+select * from t1;
+set GLOBAL query_cache_size=102400;
+show global variables like "query_cache_size";
+select * from t1;
+drop table t1;
+
+#
+# Temporary tables
+#
+set GLOBAL query_cache_size=1048576;
+create table t1 (i int not null);
+create table t2 (i int not null);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+create temporary table t3 (i int not null);
+select * from t2;
+show status like "Qcache_queries_in_cache";
+select * from t3;
+show status like "Qcache_queries_in_cache";
+drop table t1, t2, t3;
+
+#
+# system databse test
+#
+use mysql;
+disable_result_log;
+select * from db;
+enable_result_log;
+show status like "Qcache_queries_in_cache";
+use test;
+disable_result_log;
+select * from mysql.db;
+enable_result_log;
+show status like "Qcache_queries_in_cache";
+
+#
+# simple rename test
+#
+create table t1(id int auto_increment primary key);
+insert into t1 values (NULL), (NULL), (NULL);
+select * from t1 where id=2;
+alter table t1 rename to t2;
+-- error 1146
+select * from t1 where id=2;
+drop table t2;
+-- error 1146
+select * from t1 where id=2;
+
+#
+# Load data invalidation test
+#
+create table t1 (word char(20) not null);
+select * from t1;
+show status like "Qcache_queries_in_cache";
+load data infile '../../std_data/words.dat' into table t1;
+show status like "Qcache_queries_in_cache";
+drop table t1;
+
+#
+# INTO OUTFILE/DUMPFILE test
+#
+drop table if exists t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+show status like "Qcache_queries_in_cache";
+select * from t1 into outfile "query_caceh.out.file";
+select * from t1 limit 1 into dumpfile "query_cache.dump.file";
+show status like "Qcache_queries_in_cache";
+drop table t1;
+
+#
+# test of SQL_SELECT_LIMIT
+#
+create table t1 (a int);
+insert into t1 values (1),(2);
+show status like "Qcache_queries_in_cache";
+select * from t1;
+SET OPTION SQL_SELECT_LIMIT=1;
+select * from t1;
+show status like "Qcache_queries_in_cache";
+SET OPTION SQL_SELECT_LIMIT=DEFAULT;
+drop table t1;
+
+
+#
+# query cache crash on using same table twice in one query test
+#
+flush query cache;
+reset query cache;
+flush status;
+set GLOBAL query_cache_size=1048576;
+
+
+create table t1 (a int not null);
+insert into t1 values (1),(2),(3);
+create table t2 (a text not null);
+create table t3 (a text not null);
+insert into t3 values("1111111111111111111111111111111111111111111111111111");
+insert into t2 select * from t3;
+insert into t3 select * from t2;
+insert into t2 select * from t3;
+insert into t3 select * from t2;
+insert into t2 select * from t3;
+insert into t3 select * from t2;
+insert into t2 select * from t3;
+insert into t3 select * from t2;
+insert into t2 select * from t3;
+insert into t3 select * from t2;
+drop table t2;
+create table t2 (a int not null);
+insert into t2 values (1),(2),(3);
+create table t4 (a int not null);
+insert into t4 values (1),(2),(3);
+
+disable_result_log;
+select * from t4;
+select * from t2;
+select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
+select * from t2;
+select * from t4;
+select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
+select * from t2;
+select * from t4;
+select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
+
+delete from t2 where a=1;
+flush query cache;
+select * from t3;
+enable_result_log;
+delete from t4 where a=1;
+flush query cache;
+
+drop table t1,t2,t3,t4;
+set GLOBAL query_cache_size=0;
diff --git a/mysql-test/t/query_cache_merge.test b/mysql-test/t/query_cache_merge.test
new file mode 100644
index 00000000000..02e316932a3
--- /dev/null
+++ b/mysql-test/t/query_cache_merge.test
@@ -0,0 +1,38 @@
+# Test query cache with many tables
+
+--source include/have_query_cache.inc
+let $LIMIT=`SHOW VARIABLES LIKE 'open_files_limit'`;
+let $MIN_LIMIT=600;
+let $MAX_LIMIT=65536;
+--source include/check_var_limit.inc
+
+SET @@global.query_cache_size=1355776;
+
+#
+# more then 255 (257) merged tables test
+#
+
+flush status;
+disable_query_log;
+--disable_warnings
+let $1 = 257;
+while ($1)
+{
+ eval drop table if exists t$1;
+ eval create table t$1(a int);
+ eval insert into t$1 values (1),(2);
+ dec $1;
+}
+--enable_warnings
+
+create table t00 (a int) type=MERGE UNION=(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t257) INSERT_METHOD=FIRST;
+enable_query_log;
+select count(*) from t00;
+select count(*) from t00;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_hits";
+delete from t256;
+show status like "Qcache_queries_in_cache";
+drop table t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t257,t00;
+
+SET @@global.query_cache_size=0;
diff --git a/mysql-test/t/raid.test b/mysql-test/t/raid.test
index 8b608c1069f..43ad58ab368 100644
--- a/mysql-test/t/raid.test
+++ b/mysql-test/t/raid.test
@@ -1,10 +1,16 @@
-- require r/have_raid.require
+disable_query_log;
show variables like "have_raid";
+enable_query_log;
#
# Test of raided tables
#
+create database test_raid;
+create table test_raid.r1 (i int) raid_type=1;
+create table test_raid.r2 (i int) raid_type=1 raid_chunks=32;
+drop database test_raid;
DROP TABLE IF EXISTS t1,t2;
CREATE TABLE t1 (
id int unsigned not null auto_increment primary key,
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 278807eeea4..2899c7c99a4 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -1,5 +1,5 @@
#
-# Problem med range optimizer
+# Problem with range optimizer
#
drop table if exists t1;
@@ -10,7 +10,24 @@ CREATE TABLE t1 (
PRIMARY KEY (event_date,type,event_id)
);
-INSERT INTO t1 VALUES ('1999-07-10',100100,24),('1999-07-11',100100,25),('1999-07-13',100600,0),('1999-07-13',100600,4),('1999-07-13',100600,26),('1999-07-14',100600,10),('1999-07-15',100600,16),('1999-07-15',100800,45),('1999-07-15',101000,47),('1999-07-16',100800,46),('1999-07-20',100600,5),('1999-07-20',100600,27),('1999-07-21',100600,11),('1999-07-22',100600,17),('1999-07-23',100100,39),('1999-07-24',100100,39),('1999-07-24',100500,40),('1999-07-25',100100,39),('1999-07-27',100600,1),('1999-07-27',100600,6),('1999-07-27',100600,28),('1999-07-28',100600,12),('1999-07-29',100500,41),('1999-07-29',100600,18),('1999-07-30',100500,41),('1999-07-31',100500,41),('1999-08-01',100700,34),('1999-08-03',100600,7),('1999-08-03',100600,29),('1999-08-04',100600,13),('1999-08-05',100500,42),('1999-08-05',100600,19),('1999-08-06',100500,42),('1999-08-07',100500,42),('1999-08-08',100500,42),('1999-08-10',100600,2),('1999-08-10',100600,9),('1999-08-10',100600,30),('1999-08-11',100600,14),('1999-08-12',100600,20),('1999-08-17',100500,8),('1999-08-17',100600,31),('1999-08-18',100600,15),('1999-08-19',100600,22),('1999-08-24',100600,3),('1999-08-24',100600,32),('1999-08-27',100500,43),('1999-08-31',100600,33),('1999-09-17',100100,37),('1999-09-18',100100,37),('1999-09-19',100100,37),('2000-12-18',100700,38);
+INSERT INTO t1 VALUES ('1999-07-10',100100,24), ('1999-07-11',100100,25),
+('1999-07-13',100600,0), ('1999-07-13',100600,4), ('1999-07-13',100600,26),
+('1999-07-14',100600,10), ('1999-07-15',100600,16), ('1999-07-15',100800,45),
+('1999-07-15',101000,47), ('1999-07-16',100800,46), ('1999-07-20',100600,5),
+('1999-07-20',100600,27), ('1999-07-21',100600,11), ('1999-07-22',100600,17),
+('1999-07-23',100100,39), ('1999-07-24',100100,39), ('1999-07-24',100500,40),
+('1999-07-25',100100,39), ('1999-07-27',100600,1), ('1999-07-27',100600,6),
+('1999-07-27',100600,28), ('1999-07-28',100600,12), ('1999-07-29',100500,41),
+('1999-07-29',100600,18), ('1999-07-30',100500,41), ('1999-07-31',100500,41),
+('1999-08-01',100700,34), ('1999-08-03',100600,7), ('1999-08-03',100600,29),
+('1999-08-04',100600,13), ('1999-08-05',100500,42), ('1999-08-05',100600,19),
+('1999-08-06',100500,42), ('1999-08-07',100500,42), ('1999-08-08',100500,42),
+('1999-08-10',100600,2), ('1999-08-10',100600,9), ('1999-08-10',100600,30),
+('1999-08-11',100600,14), ('1999-08-12',100600,20), ('1999-08-17',100500,8),
+('1999-08-17',100600,31), ('1999-08-18',100600,15), ('1999-08-19',100600,22),
+('1999-08-24',100600,3), ('1999-08-24',100600,32), ('1999-08-27',100500,43),
+('1999-08-31',100600,33), ('1999-09-17',100100,37), ('1999-09-18',100100,37),
+('1999-09-19',100100,37), ('2000-12-18',100700,38);
select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
explain select event_date,type,event_id from t1 WHERE type = 100601 and event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
@@ -25,35 +42,21 @@ CREATE TABLE t1 (
ISS_DATE date DEFAULT '0000-00-00' NOT NULL,
PRIMARY KEY (PAPER_ID,YEAR,ISSUE)
);
-INSERT INTO t1 VALUES (3,1999,34,0,'1999-07-12');
-INSERT INTO t1 VALUES (1,1999,111,0,'1999-03-23');
-INSERT INTO t1 VALUES (1,1999,222,0,'1999-03-23');
-INSERT INTO t1 VALUES (3,1999,33,0,'1999-07-12');
-INSERT INTO t1 VALUES (3,1999,32,0,'1999-07-12');
-INSERT INTO t1 VALUES (3,1999,31,0,'1999-07-12');
-INSERT INTO t1 VALUES (3,1999,30,0,'1999-07-12');
-INSERT INTO t1 VALUES (3,1999,29,0,'1999-07-12');
-INSERT INTO t1 VALUES (3,1999,28,0,'1999-07-12');
-INSERT INTO t1 VALUES (1,1999,40,1,'1999-05-01');
-INSERT INTO t1 VALUES (1,1999,41,1,'1999-05-01');
-INSERT INTO t1 VALUES (1,1999,42,1,'1999-05-01');
-INSERT INTO t1 VALUES (1,1999,46,1,'1999-05-01');
-INSERT INTO t1 VALUES (1,1999,47,1,'1999-05-01');
-INSERT INTO t1 VALUES (1,1999,48,1,'1999-05-01');
-INSERT INTO t1 VALUES (1,1999,49,1,'1999-05-01');
-INSERT INTO t1 VALUES (1,1999,50,0,'1999-05-01');
-INSERT INTO t1 VALUES (1,1999,51,0,'1999-05-01');
-INSERT INTO t1 VALUES (1,1999,200,0,'1999-06-28');
-INSERT INTO t1 VALUES (1,1999,52,0,'1999-06-28');
-INSERT INTO t1 VALUES (1,1999,53,0,'1999-06-28');
-INSERT INTO t1 VALUES (1,1999,54,0,'1999-06-28');
-INSERT INTO t1 VALUES (1,1999,55,0,'1999-06-28');
-INSERT INTO t1 VALUES (1,1999,56,0,'1999-07-01');
-INSERT INTO t1 VALUES (1,1999,57,0,'1999-07-01');
-INSERT INTO t1 VALUES (1,1999,58,0,'1999-07-01');
-INSERT INTO t1 VALUES (1,1999,59,0,'1999-07-01');
-INSERT INTO t1 VALUES (1,1999,60,0,'1999-07-01');
-INSERT INTO t1 VALUES (3,1999,35,0,'1999-07-12');
+INSERT INTO t1 VALUES (3,1999,34,0,'1999-07-12'), (1,1999,111,0,'1999-03-23'),
+ (1,1999,222,0,'1999-03-23'), (3,1999,33,0,'1999-07-12'),
+ (3,1999,32,0,'1999-07-12'), (3,1999,31,0,'1999-07-12'),
+ (3,1999,30,0,'1999-07-12'), (3,1999,29,0,'1999-07-12'),
+ (3,1999,28,0,'1999-07-12'), (1,1999,40,1,'1999-05-01'),
+ (1,1999,41,1,'1999-05-01'), (1,1999,42,1,'1999-05-01'),
+ (1,1999,46,1,'1999-05-01'), (1,1999,47,1,'1999-05-01'),
+ (1,1999,48,1,'1999-05-01'), (1,1999,49,1,'1999-05-01'),
+ (1,1999,50,0,'1999-05-01'), (1,1999,51,0,'1999-05-01'),
+ (1,1999,200,0,'1999-06-28'), (1,1999,52,0,'1999-06-28'),
+ (1,1999,53,0,'1999-06-28'), (1,1999,54,0,'1999-06-28'),
+ (1,1999,55,0,'1999-06-28'), (1,1999,56,0,'1999-07-01'),
+ (1,1999,57,0,'1999-07-01'), (1,1999,58,0,'1999-07-01'),
+ (1,1999,59,0,'1999-07-01'), (1,1999,60,0,'1999-07-01'),
+ (3,1999,35,0,'1999-07-12');
select YEAR,ISSUE from t1 where PAPER_ID=3 and (YEAR>1999 or (YEAR=1999 and ISSUE>28)) order by YEAR,ISSUE;
check table t1;
repair table t1;
@@ -67,7 +70,12 @@ CREATE TABLE t1 (
KEY parent_id (parent_id),
KEY level (level)
);
-INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
+INSERT INTO t1 VALUES (1,0,0), (3,1,1), (4,1,1), (8,2,2), (9,2,2), (17,3,2),
+(22,4,2), (24,4,2), (28,5,2), (29,5,2), (30,5,2), (31,6,2), (32,6,2), (33,6,2),
+(203,7,2), (202,7,2), (20,3,2), (157,0,0), (193,5,2), (40,7,2), (2,1,1),
+(15,2,2), (6,1,1), (34,6,2), (35,6,2), (16,3,2), (7,1,1), (36,7,2), (18,3,2),
+(26,5,2), (27,5,2), (183,4,2), (38,7,2), (25,5,2), (37,7,2), (21,4,2),
+(19,3,2), (5,1,1), (179,5,2);
SELECT * FROM t1 WHERE level = 1 AND parent_id = 1;
# The following select returned 0 rows in 3.23.8
SELECT * FROM t1 WHERE level = 1 AND parent_id = 1 order by id;
@@ -163,3 +171,95 @@ select count(*) from t1 where art = 'j' or art = 'J';
select count(*) from t1 where art = 'j';
select count(*) from t1 where art = 'J';
drop table t1;
+
+create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
+insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
+ (3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
+ (6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
+ (9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
+ (12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
+ (15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
+ (18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
+select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
+drop table t1;
+
+#
+# BETWEEN problems
+#
+create table t1 (x int, y int, index(x), index(y));
+insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
+update t1 set y=x;
+# between with only one end fixed
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 7 and t1.y+0;
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 7 and t2.x <= t1.y+0;
+# between with both expressions on both ends
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
+# equation propagation
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
+# testing IN
+explain select count(*) from t1 where x in (1);
+explain select count(*) from t1 where x in (1,2);
+drop table t1;
+
+#
+# bug #1172
+#
+CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1), KEY i2 (key1));
+INSERT INTO t1 VALUES (0),(0),(1),(1);
+CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya));
+INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2);
+explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
+explain select * from t1 force index(i2), t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
+DROP TABLE t1,t2;
+
+# bug #1724: use RANGE on more selective column instead of REF on less
+# selective
+
+CREATE TABLE t1 (
+ a int(11) default NULL,
+ b int(11) default NULL,
+ KEY a (a),
+ KEY b (b)
+) TYPE=MyISAM;
+
+
+INSERT INTO t1 VALUES
+(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(10,2),
+(13,2),(14,2),(15,2),(16,2),(17,3),(17,3),(16,3),(17,3),(19,3),(20,3),
+(21,4),(22,5),(23,5),(24,5),(25,5),(26,5),(30,5),(31,5),(32,5),(33,5),
+(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
+
+# we expect that optimizer will choose index on A
+EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
+SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
+
+DROP TABLE t1;
+
+#
+# Test problem with range optimzer and sub ranges
+#
+
+CREATE TABLE t1 (a int, b int, c int, INDEX (c,a,b));
+INSERT INTO t1 VALUES (1,0,0),(1,0,0),(1,0,0);
+INSERT INTO t1 VALUES (0,1,0),(0,1,0),(0,1,0);
+# -- First reports 3; second reports 6
+SELECT COUNT(*) FROM t1 WHERE (c=0 and a=1) or (c=0 and b=1);
+SELECT COUNT(*) FROM t1 WHERE (c=0 and b=1) or (c=0 and a=1);
+DROP TABLE t1;
+
+#
+# Test problem with range optimization over overlapping ranges (#2448)
+#
+
+CREATE TABLE t1 ( a int not null, b int not null, INDEX ab(a,b) );
+INSERT INTO t1 VALUES (47,1), (70,1), (15,1), (15, 4);
+SELECT * FROM t1
+WHERE
+(
+ ( b =1 AND a BETWEEN 14 AND 21 ) OR
+ ( b =2 AND a BETWEEN 16 AND 18 ) OR
+ ( b =3 AND a BETWEEN 15 AND 19 ) OR
+ (a BETWEEN 19 AND 47)
+);
diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test
index 2a9cf113a47..ce4651d8de3 100644
--- a/mysql-test/t/rename.test
+++ b/mysql-test/t/rename.test
@@ -12,13 +12,19 @@ select * from t1;
rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1;
select * from t1;
+
# The following should give errors
-!$1050 rename table t1 to t2;
-!$1050 rename table t1 to t1;
-!$1050 rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2;
+--error 1050,1050
+rename table t1 to t2;
+--error 1050,1050
+rename table t1 to t1;
+--error 1050,1050
+rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2;
show tables like "t_";
-!$1050 rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1;
-!$1017 rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1;
+--error 1050,1050
+rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1;
+--error 1017,1017
+rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1;
select * from t1;
select * from t2;
diff --git a/mysql-test/t/repair.test b/mysql-test/t/repair.test
new file mode 100644
index 00000000000..159fc090653
--- /dev/null
+++ b/mysql-test/t/repair.test
@@ -0,0 +1,19 @@
+#
+# Test of repair table
+#
+
+drop table if exists t1;
+create table t1 SELECT 1,"table 1";
+repair table t1 use_frm;
+alter table t1 TYPE=HEAP;
+repair table t1 use_frm;
+drop table t1;
+
+# non-existent table
+repair table t1 use_frm;
+
+#
+# Create test table for repair2
+# The following must be last in this file
+
+create table t1 type=myisam SELECT 1,"table 1";
diff --git a/mysql-test/t/repair_part2-master.sh b/mysql-test/t/repair_part2-master.sh
new file mode 100644
index 00000000000..964bde06c18
--- /dev/null
+++ b/mysql-test/t/repair_part2-master.sh
@@ -0,0 +1 @@
+echo "1" > $MYSQL_TEST_DIR/var/master-data/test/t1.MYI
diff --git a/mysql-test/t/repair_part2.test b/mysql-test/t/repair_part2.test
new file mode 100644
index 00000000000..8c27e382dff
--- /dev/null
+++ b/mysql-test/t/repair_part2.test
@@ -0,0 +1,7 @@
+#
+# This test starts with a crashed t1.MYI file left over from repair.test
+#
+
+repair table t1;
+repair table t1 use_frm;
+drop table t1;
diff --git a/mysql-test/t/rpl000001.test b/mysql-test/t/rpl000001.test
index 6a827368fa4..ebce3d0ac94 100644
--- a/mysql-test/t/rpl000001.test
+++ b/mysql-test/t/rpl000001.test
@@ -1,17 +1,36 @@
source include/master-slave.inc;
-connection master;
-use test;
-drop table if exists t1,t3;
+drop table if exists t1,t2,t3;
create table t1 (word char(20) not null);
load data infile '../../std_data/words.dat' into table t1;
-set password = password('foo');
-set password = password('');
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+eval load data local infile '$MYSQL_TEST_DIR/std_data/words.dat' into table t1;
+select * from t1 limit 10;
+
+#
+# Test slave with wrong password
+#
+save_master_pos;
+connection slave;
+sync_with_master;
+slave stop;
+connection master;
+set password for root@"localhost" = password('foo');
+connection slave;
+slave start;
+connection master;
+#
+# Give slave time to do at last one failed connect retry
+# This one must be short so that the slave will not stop retrying
+real_sleep 2;
+set password for root@"localhost" = password('');
+# Give slave time to connect (will retry every second)
+sleep 2;
+
create table t3(n int);
insert into t3 values(1),(2);
save_master_pos;
connection slave;
sync_with_master;
-use test;
select * from t3;
select sum(length(word)) from t1;
connection master;
@@ -24,60 +43,74 @@ sync_with_master;
connection master;
reset master;
connection slave;
+slave stop;
reset slave;
connection master;
-drop table if exists t1,t2;
create table t1(n int);
-let $1=10;
+#we want the log to exceed 16K to test deal with the log that is bigger than
+#IO_SIZE
+let $1=5000;
+disable_query_log;
while ($1)
{
- eval insert into t1 values($1);
+ eval insert into t1 values($1+get_lock("hold_slave",10)*0);
dec $1;
}
+enable_query_log;
+
+# Try to cause a large relay log lag on the slave
+connection slave;
+select get_lock("hold_slave",10);
+slave start;
+#hope this is long enough for I/O thread to fetch over 16K relay log data
+sleep 3;
+select release_lock("hold_slave");
+unlock tables;
+
+connection master;
create table t2(id int);
insert into t2 values(connection_id());
save_master_pos;
connection master1;
-#avoid generating result
-create temporary table t1_temp(n int);
-insert into t1_temp select get_lock('crash_lock%20C', 1) from t2;
+# Avoid generating result
+create temporary table t3(n int);
+insert into t3 select get_lock('crash_lock%20C', 1) from t2;
connection master;
send update t1 set n = n + get_lock('crash_lock%20C', 2);
connection master1;
-sleep 2;
+sleep 3;
select (@id := id) - id from t2;
kill @id;
+# We don't drop t3 as this is a temporary table
drop table t2;
connection master;
--error 1053;
reap;
connection slave;
-sync_with_master ;
-#give the slave a chance to exit
-sleep 2;
+# The SQL slave thread should now have stopped because the query was killed on
+# the master (so it has a non-zero error code in the binlog).
+wait_for_slave_to_stop;
# The following test can't be done because the result of Pos will differ
# on different computers
# --replace_result 9306 9999 3334 9999 3335 9999
# show slave status;
-set sql_slave_skip_counter=1;
+set global sql_slave_skip_counter=1;
slave start;
select count(*) from t1;
connection master1;
drop table t1;
create table t1 (n int);
insert into t1 values(3456);
-use mysql;
-insert into user (Host, User, Password)
+insert into mysql.user (Host, User, Password)
VALUES ("10.10.10.%", "blafasel2", password("blafasel2"));
select select_priv,user from mysql.user where user = 'blafasel2';
-update user set Select_priv = "Y" where User="blafasel2";
+update mysql.user set Select_priv = "Y" where User="blafasel2";
select select_priv,user from mysql.user where user = 'blafasel2';
-use test;
save_master_pos;
connection slave;
sync_with_master;
@@ -88,5 +121,3 @@ drop table t1;
save_master_pos;
connection slave;
sync_with_master;
-
-
diff --git a/mysql-test/t/rpl000002.test b/mysql-test/t/rpl000002.test
index 0c490e6316d..caf0b4ef6d8 100644
--- a/mysql-test/t/rpl000002.test
+++ b/mysql-test/t/rpl000002.test
@@ -1,16 +1,15 @@
source include/master-slave.inc;
-connection master;
-use test;
drop table if exists t1;
create table t1 (n int auto_increment primary key);
set insert_id = 2000;
insert into t1 values (NULL),(NULL),(NULL);
save_master_pos;
connection slave;
-use test;
sync_with_master;
select * from t1;
connection master;
+--replace_result $SLAVE_MYPORT 9999
+show slave hosts;
drop table t1;
save_master_pos;
connection slave;
diff --git a/mysql-test/t/rpl000003.test b/mysql-test/t/rpl000003.test
index c4b120d31b0..f994ed94371 100644
--- a/mysql-test/t/rpl000003.test
+++ b/mysql-test/t/rpl000003.test
@@ -1,5 +1,4 @@
source include/master-slave.inc;
-connection master;
drop table if exists t1;
create table t1(n int primary key);
!insert into t1 values (1),(2),(2);
diff --git a/mysql-test/t/rpl000004.test b/mysql-test/t/rpl000004.test
index 5b2c41293a2..705e0d51b7b 100644
--- a/mysql-test/t/rpl000004.test
+++ b/mysql-test/t/rpl000004.test
@@ -1,6 +1,4 @@
source include/master-slave.inc;
-connection master;
-use test;
set SQL_LOG_BIN=0;
drop table if exists t1;
create table t1 (word char(20) not null, index(word));
@@ -10,7 +8,6 @@ create table t2 (word char(20) not null);
load data infile '../../std_data/words.dat' into table t2;
create table t3 (word char(20) not null primary key);
connection slave;
-use test;
drop table if exists t1;
load table t1 from master;
drop table if exists t2;
diff --git a/mysql-test/t/rpl000005.test b/mysql-test/t/rpl000005.test
index 92d954a6182..1cfea242b69 100644
--- a/mysql-test/t/rpl000005.test
+++ b/mysql-test/t/rpl000005.test
@@ -1,5 +1,4 @@
source include/master-slave.inc;
-connection master;
drop table if exists t1;
CREATE TABLE t1 (name varchar(64), age smallint(3));
INSERT INTO t1 SET name='Andy', age=31;
diff --git a/mysql-test/t/rpl000006.test b/mysql-test/t/rpl000006.test
index 495f34bd5e7..ad8622c2a81 100644
--- a/mysql-test/t/rpl000006.test
+++ b/mysql-test/t/rpl000006.test
@@ -2,7 +2,6 @@
# Test forced timestamp
#
source include/master-slave.inc;
-connection master;
# Don't log table creating to the slave as we want to test LOAD TABLE
set SQL_LOG_BIN=0,timestamp=200006;
diff --git a/mysql-test/t/rpl000007-slave.opt b/mysql-test/t/rpl000007-slave.opt
deleted file mode 100644
index 9ff99337d1f..00000000000
--- a/mysql-test/t/rpl000007-slave.opt
+++ /dev/null
@@ -1 +0,0 @@
---replicate-do-table=test.bar
diff --git a/mysql-test/t/rpl000007.test b/mysql-test/t/rpl000007.test
deleted file mode 100644
index 4425a5725e8..00000000000
--- a/mysql-test/t/rpl000007.test
+++ /dev/null
@@ -1,26 +0,0 @@
-#this one assumes we are ignoring updates on table foo, but doing
-#the ones on bar
-source include/master-slave.inc;
-connection slave;
-use test;
-drop table if exists foo;
-create table foo (n int);
-insert into foo values(4);
-connection master;
-use test;
-drop table if exists foo;
-create table foo (s char(20));
-load data infile '../../std_data/words.dat' into table foo;
-insert into foo values('five');
-drop table if exists bar;
-create table bar (m int);
-insert into bar values(15);
-save_master_pos;
-connection slave;
-sync_with_master;
-select foo.n,bar.m from foo,bar;
-connection master;
-drop table if exists bar,foo;
-save_master_pos;
-connection slave;
-sync_with_master;
diff --git a/mysql-test/t/rpl000009.test b/mysql-test/t/rpl000009.test
index 768c6c151b4..e019e1fc3a7 100644
--- a/mysql-test/t/rpl000009.test
+++ b/mysql-test/t/rpl000009.test
@@ -1,7 +1,7 @@
-#this one assumes we are ignoring updates on tables in database foo, but doing
-#the ones in database bar
+# This one assumes we are ignoring updates on tables in database foo, but doing
+# the ones in database bar
+
source include/master-slave.inc;
-connection master;
drop database if exists foo;
create database foo;
drop database if exists bar;
@@ -9,6 +9,7 @@ create database bar;
save_master_pos;
connection slave;
sync_with_master;
+create database foo;
drop table if exists foo.foo;
create table foo.foo (n int);
insert into foo.foo values(4);
@@ -24,10 +25,117 @@ connection slave;
sync_with_master;
select foo.foo.n,bar.bar.m from foo.foo,bar.bar;
connection master;
-drop database if exists bar;
+drop database bar;
drop database if exists foo;
save_master_pos;
connection slave;
sync_with_master;
-drop database if exists bar;
-drop database if exists foo;
+--error 1008
+drop database bar;
+drop database foo;
+
+# Now let's test load data from master
+
+# First create some databases and tables on the master
+
+connection master;
+set sql_log_bin = 0;
+create database foo;
+create database bar;
+show databases;
+create table foo.t1(n int, s char(20));
+create table foo.t2(n int, s text);
+insert into foo.t1 values (1, 'one'), (2, 'two'), (3, 'three');
+insert into foo.t2 values (11, 'eleven'), (12, 'twelve'), (13, 'thirteen');
+
+create table bar.t1(n int, s char(20));
+create table bar.t2(n int, s text);
+insert into bar.t1 values (1, 'one bar'), (2, 'two bar'), (3, 'three bar');
+insert into bar.t2 values (11, 'eleven bar'), (12, 'twelve bar'),
+ (13, 'thirteen bar');
+set sql_log_bin = 1;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# This should show that the slave is empty at this point
+show databases;
+# Create foo and foo2 on slave; we expect that LOAD DATA FROM MASTER will
+# neither touch database foo nor foo2.
+create database foo;
+create table foo.t1(n int, s char(20));
+insert into foo.t1 values (1, 'original foo.t1');
+create table foo.t3(n int, s char(20));
+insert into foo.t3 values (1, 'original foo.t3');
+create database foo2;
+create table foo2.t1(n int, s char(20));
+insert into foo2.t1 values (1, 'original foo2.t1');
+# Create bar, and bar.t1, to check that it gets replaced,
+# and bar.t3 to check that it is not touched (there is no bar.t3 on master)
+create database bar;
+create table bar.t1(n int, s char(20));
+insert into bar.t1 values (1, 'original bar.t1');
+create table bar.t3(n int, s char(20));
+insert into bar.t3 values (1, 'original bar.t3');
+
+load data from master;
+
+# Now let's check if we have the right tables and the right data in them
+show databases;
+use foo;
+# LOAD DATA FROM MASTER uses only replicate_*_db rules to decide which databases
+# have to be copied. So it thinks "foo" has to be copied. Before 4.0.16 it would
+# first drop "foo", then create "foo". This "drop" is a bug; in that case t3
+# would disappear.
+# So here the effect of this bug (BUG#1248) would be to leave an empty "foo" on
+# the slave.
+show tables; # should be t1 & t3
+select * from t1; # should be slave's original
+use foo2;
+show tables; # should be t1
+select * from t1; # should be slave's original
+use bar;
+show tables; # should contain master's copied t1&t2, slave's original t3
+select * from bar.t1;
+select * from bar.t2;
+select * from bar.t3;
+
+# Now let's see if replication works
+connection master;
+insert into bar.t1 values (4, 'four bar');
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from bar.t1;
+
+# Check that LOAD DATA FROM MASTER reports the error if it can't drop a
+# table to be overwritten.
+# DISABLED FOR NOW AS chmod IS NOT PORTABLE ON NON-UNIX
+# insert into bar.t1 values(10, 'should be there');
+# flush tables;
+# system chmod 500 var/slave-data/bar/;
+# --error 6
+# load data from master; # should fail (errno 13)
+# system chmod 700 var/slave-data/bar/;
+# select * from bar.t1; # should contain the row (10, ...)
+
+
+# Check that LOAD TABLE FROM MASTER fails if the table exists on slave
+--error 1050
+load table bar.t1 from master;
+drop table bar.t1;
+load table bar.t1 from master;
+
+# as LOAD DATA FROM MASTER failed it did not restart slave threads
+# DISABLED FOR NOW
+# start slave;
+
+# Now time for cleanup
+connection master;
+drop database bar;
+drop database foo;
+save_master_pos;
+connection slave;
+sync_with_master;
+drop database foo;
+drop database foo2;
diff --git a/mysql-test/t/rpl000011.test b/mysql-test/t/rpl000011.test
index 7d99222b3c7..d75937e3f81 100644
--- a/mysql-test/t/rpl000011.test
+++ b/mysql-test/t/rpl000011.test
@@ -1,6 +1,4 @@
source include/master-slave.inc;
-connection master;
-use test;
drop table if exists t1;
create table t1 (n int);
insert into t1 values(1);
diff --git a/mysql-test/t/rpl000013.test b/mysql-test/t/rpl000013.test
index a190d5324ae..14619796e01 100644
--- a/mysql-test/t/rpl000013.test
+++ b/mysql-test/t/rpl000013.test
@@ -1,5 +1,4 @@
source include/master-slave.inc;
-connection master;
save_master_pos;
connection slave;
sync_with_master;
diff --git a/mysql-test/t/rpl000014.test b/mysql-test/t/rpl000014.test
deleted file mode 100644
index b501d63b10e..00000000000
--- a/mysql-test/t/rpl000014.test
+++ /dev/null
@@ -1,35 +0,0 @@
-source include/master-slave.inc;
-connection master;
-show master status;
-save_master_pos;
-connection slave;
-sync_with_master;
---replace_result 9306 9999 3334 9999 3335 9999
-show slave status;
-change master to master_log_pos=73;
-slave stop;
-change master to master_log_pos=73;
---replace_result 9306 9999 3334 9999 3335 9999
-show slave status;
-slave start;
---replace_result 9306 9999 3334 9999 3335 9999
-show slave status;
-change master to master_log_pos=173;
---replace_result 9306 9999 3334 9999 3335 9999
-show slave status;
-connection master;
-show master status;
-create table if not exists foo(n int);
-drop table if exists foo;
-create table foo (n int);
-insert into foo values (1),(2),(3);
-save_master_pos;
-connection slave;
-change master to master_log_pos=73;
-sync_with_master;
-select * from foo;
-connection master;
-drop table foo;
-save_master_pos;
-connection slave;
-sync_with_master;
diff --git a/mysql-test/t/rpl000015.slave-mi b/mysql-test/t/rpl000015.slave-mi
index 80190bf6d29..28bc753dd56 100644
--- a/mysql-test/t/rpl000015.slave-mi
+++ b/mysql-test/t/rpl000015.slave-mi
@@ -1 +1 @@
---server-id=2
+--server-id=22 --master-connect-retry=7
diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test
index 73a10bed7b3..26d32ea3e11 100644
--- a/mysql-test/t/rpl000015.test
+++ b/mysql-test/t/rpl000015.test
@@ -1,22 +1,26 @@
-connect (master,localhost,root,,test,0,mysql-master.sock);
-connect (slave,localhost,root,,test,0, mysql-slave.sock);
+connect (master,localhost,root,,test,$MASTER_MYPORT,master.sock);
+connect (slave,localhost,root,,test,$SLAVE_MYPORT,slave.sock);
connection master;
reset master;
show master status;
save_master_pos;
connection slave;
reset slave;
+--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
+
change master to master_host='127.0.0.1';
---replace_result 3306 9998 9306 9999 3334 9999 3335 9999
+# The following needs to be cleaned up when change master is fixed
+--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT
show slave status;
+--replace_result $MASTER_MYPORT MASTER_PORT
eval change master to master_host='127.0.0.1',master_user='root',
master_password='',master_port=$MASTER_MYPORT;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
slave start;
sync_with_master;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
connection master;
drop table if exists t1;
@@ -31,4 +35,3 @@ drop table t1;
save_master_pos;
connection slave;
sync_with_master;
-
diff --git a/mysql-test/t/rpl000016-slave.opt b/mysql-test/t/rpl000016-slave.opt
new file mode 100644
index 00000000000..f27601e0d7d
--- /dev/null
+++ b/mysql-test/t/rpl000016-slave.opt
@@ -0,0 +1 @@
+-O max_binlog_size=2048
diff --git a/mysql-test/t/rpl000017-slave.sh b/mysql-test/t/rpl000017-slave.sh
index 0588859c591..066b4880cc1 100755
--- a/mysql-test/t/rpl000017-slave.sh
+++ b/mysql-test/t/rpl000017-slave.sh
@@ -1,3 +1,5 @@
+rm -f $MYSQL_TEST_DIR/var/log/*relay*
+rm -f $MYSQL_TEST_DIR/var/slave-data/relay-log.info
cat > $MYSQL_TEST_DIR/var/slave-data/master.info <<EOF
master-bin.001
4
@@ -6,4 +8,5 @@ replicate
aaaaaaaaaaaaaaabthispartofthepasswordisnotused
$MASTER_MYPORT
1
+0
EOF
diff --git a/mysql-test/t/rpl000017.test b/mysql-test/t/rpl000017.test
index 8e4e61cb9d6..d4f41f1e374 100644
--- a/mysql-test/t/rpl000017.test
+++ b/mysql-test/t/rpl000017.test
@@ -1,9 +1,9 @@
-connect (master,localhost,root,,test,0,mysql-master.sock);
-connect (slave,localhost,root,,test,0,mysql-slave.sock);
+connect (master,localhost,root,,test,$MASTER_MYPORT,master.sock);
+connect (slave,localhost,root,,test,$SLAVE_MYPORT,slave.sock);
connection master;
reset master;
-grant file on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
-grant file on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
+grant replication slave on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
+grant replication slave on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
connection slave;
slave start;
connection master;
diff --git a/mysql-test/t/rpl000018-master.sh b/mysql-test/t/rpl000018-master.sh
deleted file mode 100755
index e570f106ec6..00000000000
--- a/mysql-test/t/rpl000018-master.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-rm -f $MYSQL_TEST_DIR/var/master-data/master-bin.*
-cp $MYSQL_TEST_DIR/std_data/master-bin.001 $MYSQL_TEST_DIR/var/master-data/
-echo ./master-bin.001 > $MYSQL_TEST_DIR/var/master-data/master-bin.index
diff --git a/mysql-test/t/rpl000018.test b/mysql-test/t/rpl000018.test
index e1204bad975..3bd5fd0ef09 100644
--- a/mysql-test/t/rpl000018.test
+++ b/mysql-test/t/rpl000018.test
@@ -3,8 +3,13 @@
# This will force slave to reconnect after every event
#
-connect (master,localhost,root,,test,0,mysql-master.sock);
-connect (slave,localhost,root,,test,0,mysql-slave.sock);
+require_manager;
+connect (master,localhost,root,,test,0,master.sock);
+connect (slave,localhost,root,,test,0,slave.sock);
+connection master;
+reset master;
+server_stop master;
+server_start master;
connection slave;
reset slave;
slave start;
diff --git a/mysql-test/t/rpl_EE_error.test b/mysql-test/t/rpl_EE_error.test
new file mode 100644
index 00000000000..de69c4897c3
--- /dev/null
+++ b/mysql-test/t/rpl_EE_error.test
@@ -0,0 +1,30 @@
+# See if an EE_ error in one event of the master's binlog stops replication
+# (it should not: in this configuration the EE_ error is probably not
+# critical). Example: you do a DROP TABLE on a table which has no MYI file
+# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and
+# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986).
+
+source include/master-slave.inc;
+
+create table t1 (a int) type=myisam;
+flush tables;
+system rm ./var/master-data/test/t1.MYI ;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# Now a real error.
+
+connection master;
+create table t1 (a int, unique(a)) type=myisam;
+set sql_log_bin=0;
+insert into t1 values(2);
+set sql_log_bin=1;
+save_master_pos;
+--error 1062;
+insert into t1 values(1),(2);
+drop table t1;
+save_master_pos;
+connection slave;
+wait_for_slave_to_stop;
diff --git a/mysql-test/t/rpl_alter.test b/mysql-test/t/rpl_alter.test
index 61ac55843cf..f1fbf60776b 100644
--- a/mysql-test/t/rpl_alter.test
+++ b/mysql-test/t/rpl_alter.test
@@ -1,6 +1,4 @@
source include/master-slave.inc;
-connection master;
-use test;
drop database if exists test_$1;
create database test_$1;
create table test_$1.t1 ( n int);
diff --git a/mysql-test/t/rpl_chain_temp_table.test b/mysql-test/t/rpl_chain_temp_table.test
new file mode 100644
index 00000000000..007b018e9d8
--- /dev/null
+++ b/mysql-test/t/rpl_chain_temp_table.test
@@ -0,0 +1,99 @@
+ # This test makes some assumptions about values of thread ids, which should be
+# true if the servers have been restarted for this test. So we want to
+# stop/restart servers. Note that if assumptions are wrong, the test will not
+# fail; it will just fail to test the error-prone scenario.
+# Using the manager is the only way to have more than one slave server.
+# So you must run this test with --manager.
+
+require_manager;
+server_stop master;
+server_start master;
+server_stop slave;
+server_start slave;
+# no need for slave_sec (no assumptions on thread ids for this server).
+
+source include/master-slave.inc;
+connect (slave_sec,localhost,root,,test,0,slave.sock-1);
+connection master;
+save_master_pos;
+connection slave;
+sync_with_master;
+reset master;
+save_master_pos;
+connection slave_sec;
+eval change master to master_host='127.0.0.1',master_port=$SLAVE_MYPORT, master_user='root';
+start slave;
+sync_with_master;
+
+# :P now we have a chain ready-to-test.
+
+connection master;
+create temporary table t1 (a int);
+save_master_pos;
+connection slave;
+sync_with_master;
+connection master1;
+create temporary table t1 (a int);
+save_master_pos;
+connection slave;
+sync_with_master;
+save_master_pos;
+
+# First test:
+
+connection slave_sec;
+# Before BUG#1686 ("If 2 master threads with same-name temp table, slave makes
+# bad binlog") was fixed, sync_with_master failed
+sync_with_master;
+show status like 'slave_open_temp_tables';
+
+# 'master' and 'master1' usually have thread id 2-3 or 3-4.
+# 'slave' and 'slave1' usually have thread id 2-3.
+connection slave;
+create temporary table t1 (a int);
+connection slave1;
+create temporary table t1 (a int);
+# So it's likely that in the binlog of slave we get
+# server_id=of_master thread_id=3 create temp...
+# server_id=of_slave thread_id=3 create temp...
+# which would confuse slave-sec unless slave-sec uses server id to distinguish
+# between temp tables (here thread id is obviously not enough to distinguish).
+
+save_master_pos;
+
+# Second test:
+
+connection slave_sec;
+# If we did not use the server id to distinguish between temp tables,
+# sync_with_master would fail
+sync_with_master;
+show status like 'slave_open_temp_tables';
+
+# Third test (BUG#1240 "slave of slave breaks when STOP SLAVE was issud on
+# parent slave and temp tables").
+stop slave;
+connection slave;
+insert into t1 values(1);
+create table t2 as select * from t1;
+save_master_pos;
+connection slave_sec;
+start slave;
+sync_with_master;
+show status like 'slave_open_temp_tables';
+select * from t2;
+
+# clean up
+connection slave;
+drop table t2;
+save_master_pos;
+connection slave_sec;
+sync_with_master;
+
+# On purpose, we don't delete the temporary tables explicitely.
+# So temp tables remain on slave (remember they are not deleted when the slave
+# SQL thread terminates). If you run this test with
+# --valgrind --valgrind-options=--show-reachable=yes
+# you will see if they get cleaned up at slave's shutdown (that is, if the
+# memory they use is freed (it should) by mysqld before it terminates).
+# If they wouldn't be cleaned up, you would see some "still reachable" blocks in
+# Valgrind.
diff --git a/mysql-test/t/rpl_change_master.test b/mysql-test/t/rpl_change_master.test
new file mode 100644
index 00000000000..a13e045cf48
--- /dev/null
+++ b/mysql-test/t/rpl_change_master.test
@@ -0,0 +1,28 @@
+source include/master-slave.inc;
+
+connection slave;
+select get_lock("a",5);
+connection master;
+create table t1(n int);
+insert into t1 values(1+get_lock("a",15)*0);
+insert into t1 values(2);
+save_master_pos;
+connection slave;
+--real_sleep 3; # can't sync_with_master as we should be blocked
+stop slave;
+select * from t1;
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+show slave status;
+change master to master_user='root';
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+show slave status;
+# Will restart from after the values(2), which is bug
+select release_lock("a");
+start slave;
+sync_with_master;
+select * from t1;
+connection master;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
diff --git a/mysql-test/t/rpl_do_grant.test b/mysql-test/t/rpl_do_grant.test
new file mode 100644
index 00000000000..89ff1afb5c9
--- /dev/null
+++ b/mysql-test/t/rpl_do_grant.test
@@ -0,0 +1,46 @@
+# Test that GRANT and SET PASSWORD are replicated to the slave
+
+source include/master-slave.inc;
+
+# do not be influenced by other tests.
+connection master;
+delete from mysql.user where user='rpl_do_grant';
+delete from mysql.db where user='rpl_do_grant';
+flush privileges;
+save_master_pos;
+connection slave;
+sync_with_master;
+# if these DELETE did nothing on the master, we need to do them manually on the
+# slave.
+delete from mysql.user where user='rpl_ignore_grant';
+delete from mysql.db where user='rpl_ignore_grant';
+flush privileges;
+
+# test replication of GRANT
+connection master;
+grant select on *.* to rpl_do_grant@localhost;
+grant drop on test.* to rpl_do_grant@localhost;
+save_master_pos;
+connection slave;
+sync_with_master;
+show grants for rpl_do_grant@localhost;
+
+# test replication of SET PASSWORD
+connection master;
+set password for rpl_do_grant@localhost=password("does it work?");
+save_master_pos;
+connection slave;
+sync_with_master;
+select password<>'' from mysql.user where user='rpl_do_grant';
+
+# clear what we have done, to not influence other tests.
+connection master;
+delete from mysql.user where user='rpl_do_grant';
+delete from mysql.db where user='rpl_do_grant';
+flush privileges;
+save_master_pos;
+connection slave;
+sync_with_master;
+# no need to delete manually, as the DELETEs must have done some real job on
+# master (updated binlog)
+flush privileges;
diff --git a/mysql-test/t/rpl_empty_master_crash.test b/mysql-test/t/rpl_empty_master_crash.test
index 7c4437a3657..afa76ce10bb 100644
--- a/mysql-test/t/rpl_empty_master_crash.test
+++ b/mysql-test/t/rpl_empty_master_crash.test
@@ -1,8 +1,11 @@
source include/master-slave.inc;
-connection master;
-use test;
drop table if exists t1;
show slave status;
-#--error 1218 # for mysql-4.0
---error 1042
+#
+# Load table should not succeed on the master as this is not a slave
+#
+--error 1218
+load table t1 from master;
+connection slave;
+--error 1188
load table t1 from master;
diff --git a/mysql-test/t/rpl_error_ignored_table-slave.opt b/mysql-test/t/rpl_error_ignored_table-slave.opt
new file mode 100644
index 00000000000..0d3485f9e25
--- /dev/null
+++ b/mysql-test/t/rpl_error_ignored_table-slave.opt
@@ -0,0 +1 @@
+--replicate-ignore-table=test.t1
diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/t/rpl_error_ignored_table.test
new file mode 100644
index 00000000000..686472433eb
--- /dev/null
+++ b/mysql-test/t/rpl_error_ignored_table.test
@@ -0,0 +1,25 @@
+# Test for
+# Bug #797: If a query is ignored on slave (replicate-ignore-table) the slave
+# still checks that it has the same error as on the master.
+
+source include/master-slave.inc;
+connection master;
+create table t1 (a int primary key);
+# generate an error that goes to the binlog
+--error 1062;
+insert into t1 values (1),(1);
+save_master_pos;
+connection slave;
+# as the t1 table is ignored on the slave, the slave should be able to sync
+sync_with_master;
+# The port number is different when doing the release build with
+# Do-compile, hence we have to replace the port number here accordingly
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+show slave status;
+# check that the table has been ignored, because otherwise the test is nonsense
+show tables like 't1';
+connection master;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
diff --git a/mysql-test/t/rpl_failsafe.test b/mysql-test/t/rpl_failsafe.test
new file mode 100644
index 00000000000..866efbce5bf
--- /dev/null
+++ b/mysql-test/t/rpl_failsafe.test
@@ -0,0 +1,24 @@
+require_manager;
+source include/master-slave.inc;
+connect (slave_sec,localhost,root,,test,0,slave.sock-1);
+connect (slave_ter,localhost,root,,test,0,slave.sock-2);
+connection master;
+show variables like 'rpl_recovery_rank';
+show status like 'Rpl_status';
+create table t1(n int);
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+show variables like 'rpl_recovery_rank';
+show status like 'Rpl_status';
+connection slave_sec;
+slave start;
+sync_with_master;
+show variables like 'rpl_recovery_rank';
+show status like 'Rpl_status';
+connection slave_ter;
+slave start;
+sync_with_master;
+show variables like 'rpl_recovery_rank';
+show status like 'Rpl_status';
diff --git a/mysql-test/t/rpl_flush_log_loop-master.opt b/mysql-test/t/rpl_flush_log_loop-master.opt
new file mode 100644
index 00000000000..4f6e0f3d00c
--- /dev/null
+++ b/mysql-test/t/rpl_flush_log_loop-master.opt
@@ -0,0 +1 @@
+-O max_binlog_size=1M --relay-log=$MYSQL_TEST_DIR/var/master-data/relay-log
diff --git a/mysql-test/t/rpl_flush_log_loop-master.sh b/mysql-test/t/rpl_flush_log_loop-master.sh
new file mode 100755
index 00000000000..9e56af99f5c
--- /dev/null
+++ b/mysql-test/t/rpl_flush_log_loop-master.sh
@@ -0,0 +1,5 @@
+rm -f $MYSQL_TEST_DIR/var/slave-data/*-bin.*
+rm -f $MYSQL_TEST_DIR/var/slave-data/master.info
+rm -f $MYSQL_TEST_DIR/var/slave-data/*.index
+
+
diff --git a/mysql-test/t/rpl_flush_log_loop-slave.opt b/mysql-test/t/rpl_flush_log_loop-slave.opt
new file mode 100644
index 00000000000..d1373f139b1
--- /dev/null
+++ b/mysql-test/t/rpl_flush_log_loop-slave.opt
@@ -0,0 +1 @@
+-O max_binlog_size=1M --relay-log=$MYSQL_TEST_DIR/var/slave-data/relay-log
diff --git a/mysql-test/t/rpl_flush_log_loop-slave.sh b/mysql-test/t/rpl_flush_log_loop-slave.sh
new file mode 100755
index 00000000000..b8814e059a9
--- /dev/null
+++ b/mysql-test/t/rpl_flush_log_loop-slave.sh
@@ -0,0 +1,4 @@
+rm -f $MYSQL_TEST_DIR/var/master-data/master.info
+rm -f $MYSQL_TEST_DIR/var/master-data/*-bin.*
+rm -f $MYSQL_TEST_DIR/var/master-data/*.index
+
diff --git a/mysql-test/t/rpl_flush_log_loop.test b/mysql-test/t/rpl_flush_log_loop.test
new file mode 100644
index 00000000000..8a3da1a2b02
--- /dev/null
+++ b/mysql-test/t/rpl_flush_log_loop.test
@@ -0,0 +1,21 @@
+# Testing if "flush logs" command bouncing resulting in logs created in a loop
+# in case of bi-directional replication
+
+source include/master-slave.inc
+
+connection slave;
+--replace_result $MASTER_MYPORT MASTER_PORT
+eval change master to master_host='127.0.0.1',master_user='root',
+ master_password='',master_port=$MASTER_MYPORT;
+slave start;
+connection master;
+slave stop;
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval change master to master_host='127.0.0.1',master_user='root',
+ master_password='',master_port=$SLAVE_MYPORT;
+slave start;
+sleep 5;
+flush logs;
+sleep 5;
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+show slave status;
diff --git a/mysql-test/t/rpl_get_lock.test b/mysql-test/t/rpl_get_lock.test
index 3c33103e4c7..e93268e6074 100644
--- a/mysql-test/t/rpl_get_lock.test
+++ b/mysql-test/t/rpl_get_lock.test
@@ -1,11 +1,13 @@
source include/master-slave.inc;
-connection master;
+
create table t1(n int);
insert into t1 values(get_lock("lock",2));
dirty_close master;
connection master1;
select get_lock("lock",2);
select release_lock("lock");
+#ignore
+disable_query_log;
let $1=2000;
while ($1)
{
@@ -13,11 +15,16 @@ while ($1)
do release_lock("lock");
dec $1;
}
+enable_query_log;
save_master_pos;
connection slave;
sync_with_master;
select get_lock("lock",3);
select * from t1;
+select is_free_lock("lock");
+# Check lock functions
+select is_free_lock("lock2");
+select is_free_lock(NULL);
connection master1;
drop table t1;
save_master_pos;
diff --git a/mysql-test/t/rpl_heap.test b/mysql-test/t/rpl_heap.test
new file mode 100644
index 00000000000..15f61918034
--- /dev/null
+++ b/mysql-test/t/rpl_heap.test
@@ -0,0 +1,47 @@
+# You must run this test with --manager.
+
+require_manager;
+
+# Don't know why, but using TCP/IP connections makes this test fail
+# with "Lost connection to MySQL server during query" when we
+# issue a query after the server restart.
+# Maybe this is something awkward in mysqltest or in the manager?
+# So we use sockets.
+connect (master,localhost,root,,test,0,master.sock);
+connect (slave,localhost,root,,test,0,slave.sock);
+
+connection master;
+reset master;
+drop table if exists t1;
+create table t1 (a int) type=HEAP;
+insert into t1 values(10);
+save_master_pos;
+show binlog events from 79;
+connection slave;
+reset slave;
+start slave;
+sync_with_master;
+show create table t1;
+select * from t1; # should be one row
+
+server_stop master;
+server_start master;
+
+connection master;
+select * from t1;
+# to check that DELETE is not written twice
+# (the LIMIT is to not use the query cache)
+select * from t1 limit 10;
+save_master_pos;
+show binlog events in 'master-bin.002' from 79;
+
+connection slave;
+sync_with_master;
+select * from t1; # should be empty
+
+# clean up
+connection master;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
diff --git a/mysql-test/t/rpl_ignore_grant-slave.opt b/mysql-test/t/rpl_ignore_grant-slave.opt
new file mode 100644
index 00000000000..e931bfbd37e
--- /dev/null
+++ b/mysql-test/t/rpl_ignore_grant-slave.opt
@@ -0,0 +1 @@
+--replicate-wild-ignore-table=mysql.%
diff --git a/mysql-test/t/rpl_ignore_grant.test b/mysql-test/t/rpl_ignore_grant.test
new file mode 100644
index 00000000000..2fd7f186b3e
--- /dev/null
+++ b/mysql-test/t/rpl_ignore_grant.test
@@ -0,0 +1,57 @@
+# Test that GRANT is not replicated to the slave
+# when --replicate-wild-ignore-table=mysql.%
+# In BUG#980, this test would _randomly_ fail.
+
+source include/master-slave.inc;
+
+# do not be influenced by other tests.
+connection master;
+delete from mysql.user where user='rpl_ignore_grant';
+delete from mysql.db where user='rpl_ignore_grant';
+flush privileges;
+save_master_pos;
+connection slave;
+sync_with_master;
+# as these DELETE were not replicated, we need to do them manually on the
+# slave.
+delete from mysql.user where user='rpl_ignore_grant';
+delete from mysql.db where user='rpl_ignore_grant';
+flush privileges;
+
+# test non-replication of GRANT
+connection master;
+grant select on *.* to rpl_ignore_grant@localhost;
+grant drop on test.* to rpl_ignore_grant@localhost;
+show grants for rpl_ignore_grant@localhost;
+save_master_pos;
+connection slave;
+sync_with_master;
+--error 1141 #("no such grant for user")
+show grants for rpl_ignore_grant@localhost;
+# check it another way
+select count(*) from mysql.user where user='rpl_ignore_grant';
+select count(*) from mysql.db where user='rpl_ignore_grant';
+
+# test non-replication of SET PASSWORD
+# first force creation of the user on slave (because as the user does not exist
+# on slave, the SET PASSWORD may be replicated but silently do nothing; this is
+# not what we want; we want it to be not-replicated).
+grant select on *.* to rpl_ignore_grant@localhost;
+connection master;
+set password for rpl_ignore_grant@localhost=password("does it work?");
+save_master_pos;
+connection slave;
+sync_with_master;
+select password<>'' from mysql.user where user='rpl_ignore_grant';
+
+# clear what we have done, to not influence other tests.
+connection master;
+delete from mysql.user where user='rpl_ignore_grant';
+delete from mysql.db where user='rpl_ignore_grant';
+flush privileges;
+save_master_pos;
+connection slave;
+sync_with_master;
+delete from mysql.user where user='rpl_ignore_grant';
+delete from mysql.db where user='rpl_ignore_grant';
+flush privileges;
diff --git a/mysql-test/t/rpl_insert_id.test b/mysql-test/t/rpl_insert_id.test
index 3f3636d3082..a6da44de456 100644
--- a/mysql-test/t/rpl_insert_id.test
+++ b/mysql-test/t/rpl_insert_id.test
@@ -1,7 +1,10 @@
-#see if queries that use both
-#auto_increment and LAST_INSERT_ID()
-#are replicated well
+# See if queries that use both auto_increment and LAST_INSERT_ID()
+# are replicated well
+
+# We also check how the foreign_key_check variable is replicated
+
source include/master-slave.inc;
+source include/have_innodb.inc
connection master;
drop table if exists t1;
create table t1(a int auto_increment, key(a));
@@ -20,12 +23,34 @@ connection master;
#are replicated the same way
drop table t1;
drop table t2;
+--disable_warnings
+create table t1(a int auto_increment, key(a)) type=innodb;
+create table t2(b int auto_increment, c int, key(b), foreign key(b) references t1(a)) type=innodb;
+--enable_warnings
+SET FOREIGN_KEY_CHECKS=0;
+insert into t1 values (10);
+insert into t1 values (null),(null),(null);
+insert into t2 values (5,0);
+insert into t2 values (null,last_insert_id());
+SET FOREIGN_KEY_CHECKS=1;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from t1;
+select * from t2;
+connection master;
+
+# check if INSERT SELECT in auto_increment is well replicated (bug #490)
+
+drop table t2;
+drop table t1;
create table t1(a int auto_increment, key(a));
create table t2(b int auto_increment, c int, key(b));
insert into t1 values (10);
insert into t1 values (null),(null),(null);
insert into t2 values (5,0);
-insert into t2 values (null,last_insert_id());
+insert into t2 (c) select * from t1;
+select * from t2;
save_master_pos;
connection slave;
sync_with_master;
diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test
new file mode 100644
index 00000000000..a3bb8c9aec9
--- /dev/null
+++ b/mysql-test/t/rpl_loaddata.test
@@ -0,0 +1,129 @@
+# See if replication of a "LOAD DATA in an autoincrement column"
+# Honours autoincrement values
+# i.e. if the master and slave have the same sequence
+#
+# check replication of load data for temporary tables with additional parameters
+#
+# check if duplicate entries trigger an error (they should unless IGNORE or
+# REPLACE was used on the master) (bug 571).
+#
+# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and
+# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986).
+
+source include/master-slave.inc;
+
+connection slave;
+reset master;
+connection master;
+
+create table t1(a int not null auto_increment, b int, primary key(a) );
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+
+create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60));
+load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines;
+
+create table t3 (day date,id int(9),category enum('a','b','c'),name varchar(60));
+insert into t3 select * from t2;
+
+save_master_pos;
+connection slave;
+sync_with_master;
+
+select * from t1;
+select * from t3;
+# We want to be sure that LOAD DATA is in the slave's binlog.
+# But we can't simply read this binlog, because as the slave has not been
+# restarted for this test, the file_id is uncertain (would cause test
+# failures). So instead, we test if the binlog looks long enough to
+# contain LOAD DATA. That is, I (Guilhem) have done SHOW BINLOG EVENTS on my
+# machine, saw that the binlog is of size 964 when things go fine.
+# If LOAD DATA was not logged, the binlog would be shorter.
+show master status;
+
+connection master;
+
+drop table t1;
+drop table t2;
+drop table t3;
+create table t1(a int, b int, unique(b));
+
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# See if slave stops when there's a duplicate entry for key error in LOAD DATA
+
+insert into t1 values(1,10);
+
+connection master;
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+
+save_master_pos;
+connection slave;
+# The SQL slave thread should be stopped now.
+wait_for_slave_to_stop;
+
+# Skip the bad event and see if error is cleared in SHOW SLAVE STATUS by START
+# SLAVE, even though we are not executing any event (as sql_slave_skip_counter
+# takes us directly to the end of the relay log).
+
+set global sql_slave_skip_counter=1;
+start slave;
+sync_with_master;
+--replace_result $MASTER_MYPORT MASTER_PORT
+show slave status;
+
+# Trigger error again to test CHANGE MASTER
+
+connection master;
+set sql_log_bin=0;
+delete from t1;
+set sql_log_bin=1;
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+save_master_pos;
+connection slave;
+# The SQL slave thread should be stopped now.
+wait_for_slave_to_stop;
+
+# CHANGE MASTER and see if error is cleared in SHOW SLAVE STATUS.
+stop slave;
+change master to master_user='test';
+change master to master_user='root';
+--replace_result $MASTER_MYPORT MASTER_PORT
+show slave status;
+
+# Trigger error again to test RESET SLAVE
+
+set global sql_slave_skip_counter=1;
+start slave;
+sync_with_master;
+connection master;
+set sql_log_bin=0;
+delete from t1;
+set sql_log_bin=1;
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+save_master_pos;
+connection slave;
+# The SQL slave thread should be stopped now.
+wait_for_slave_to_stop;
+
+# RESET SLAVE and see if error is cleared in SHOW SLAVE STATUS.
+stop slave;
+reset slave;
+--replace_result $MASTER_MYPORT MASTER_PORT
+show slave status;
+
+# Finally, see if logging is done ok on master for a failing LOAD DATA INFILE
+
+connection master;
+reset master;
+create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60),
+unique(day));
+--error 1062;
+load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
+terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
+'\n##\n' starting by '>' ignore 1 lines;
+# To test that there is Create_file & Delete_file, we test if the binlog is as
+# long as expected (can't do SHOW BINLOG EVENTS because of varying file_id).
+show master status;
+drop table t2;
diff --git a/mysql-test/t/rpl_loaddata_rule_m-master.opt b/mysql-test/t/rpl_loaddata_rule_m-master.opt
new file mode 100644
index 00000000000..9d4a8f0b95e
--- /dev/null
+++ b/mysql-test/t/rpl_loaddata_rule_m-master.opt
@@ -0,0 +1 @@
+--binlog_ignore_db=test
diff --git a/mysql-test/t/rpl_loaddata_rule_m.test b/mysql-test/t/rpl_loaddata_rule_m.test
new file mode 100644
index 00000000000..18f295f8ce2
--- /dev/null
+++ b/mysql-test/t/rpl_loaddata_rule_m.test
@@ -0,0 +1,18 @@
+# See if the master logs LOAD DATA INFILE correctly when binlog_*_db rules
+# exist.
+# This is for BUG#1100 (LOAD DATA INFILE was half-logged).
+
+source include/master-slave.inc;
+connection slave;
+reset master;
+
+# Test logging on master
+
+connection master;
+# 'test' is the current database
+create database test2;
+create table t1(a int, b int, unique(b));
+use test2;
+load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
+show binlog events from 79; # should be nothing
+drop database test2;
diff --git a/mysql-test/t/rpl_loaddata_rule_s-slave.opt b/mysql-test/t/rpl_loaddata_rule_s-slave.opt
new file mode 100644
index 00000000000..9d4a8f0b95e
--- /dev/null
+++ b/mysql-test/t/rpl_loaddata_rule_s-slave.opt
@@ -0,0 +1 @@
+--binlog_ignore_db=test
diff --git a/mysql-test/t/rpl_loaddata_rule_s.test b/mysql-test/t/rpl_loaddata_rule_s.test
new file mode 100644
index 00000000000..1ea4f6825f5
--- /dev/null
+++ b/mysql-test/t/rpl_loaddata_rule_s.test
@@ -0,0 +1,20 @@
+# See if the slave logs (in its own binlog, with --log-slave-updates) a
+# replicated LOAD DATA INFILE correctly when it has binlog_*_db rules.
+# This is for BUG#1100 (LOAD DATA INFILE was half-logged).
+
+source include/master-slave.inc;
+connection slave;
+reset master;
+
+connection master;
+# 'test' is the current database
+create table t1(a int, b int, unique(b));
+load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
+
+# Test logging on slave;
+
+save_master_pos;
+connection slave;
+sync_with_master;
+select count(*) from t1; # check that LOAD was replicated
+show binlog events from 79; # should be nothing
diff --git a/mysql-test/t/rpl_loaddatalocal.test b/mysql-test/t/rpl_loaddatalocal.test
new file mode 100644
index 00000000000..70f4ab96b6a
--- /dev/null
+++ b/mysql-test/t/rpl_loaddatalocal.test
@@ -0,0 +1,36 @@
+# See if "LOAD DATA LOCAL INFILE" is well replicated
+# (LOAD DATA LOCAL INFILE is not written to the binlog
+# the same way as LOAD DATA INFILE : Append_blocks are smaller).
+# In MySQL 4.0 <4.0.12 there were 2 bugs with LOAD DATA LOCAL INFILE :
+# - the loaded file was not written entirely to the master's binlog,
+# only the first 4KB, 8KB or 16KB usually.
+# - the loaded file's first line was not written entirely to the
+# master's binlog (1st char was absent)
+source include/master-slave.inc;
+
+create table t1(a int);
+let $1=10000;
+disable_query_log;
+set SQL_LOG_BIN=0;
+while ($1)
+{
+#eval means expand $ expressions
+ eval insert into t1 values(1);
+ dec $1;
+}
+set SQL_LOG_BIN=1;
+enable_query_log;
+select * into outfile '../../var/master-data/rpl_loaddatalocal.select_outfile' from t1;
+#This will generate a 20KB file, now test LOAD DATA LOCAL
+truncate table t1;
+load data local infile './var/master-data/rpl_loaddatalocal.select_outfile' into table t1;
+system rm ./var/master-data/rpl_loaddatalocal.select_outfile ;
+save_master_pos;
+connection slave;
+sync_with_master;
+select a,count(*) from t1 group by a;
+connection master;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
diff --git a/mysql-test/t/rpl_log-master.opt b/mysql-test/t/rpl_log-master.opt
new file mode 100644
index 00000000000..e0d075c3fbd
--- /dev/null
+++ b/mysql-test/t/rpl_log-master.opt
@@ -0,0 +1 @@
+--skip-external-locking
diff --git a/mysql-test/t/rpl_log-slave.opt b/mysql-test/t/rpl_log-slave.opt
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/mysql-test/t/rpl_log-slave.opt
@@ -0,0 +1 @@
+
diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test
new file mode 100644
index 00000000000..e01b3e4e09c
--- /dev/null
+++ b/mysql-test/t/rpl_log.test
@@ -0,0 +1,98 @@
+source include/master-slave.inc;
+
+#clean up slave binlogs
+connection slave;
+slave stop;
+reset master;
+reset slave;
+# We are going to read the slave's binlog which contains file_id (for some LOAD
+# DATA INFILE); to make it repeatable (not influenced by other tests), we need
+# to stop and start the slave, to be sure file_id will start from 1.
+# This can be done with 'server_stop slave', but
+# this would require the manager, so most of the time the test will be skipped
+# :(
+# To workaround this, I (Guilhem) add a (empty) rpl_log-slave.opt (because when
+# mysql-test-run finds such a file it restarts the slave before doing the
+# test). That's not very elegant but I could find no better way, sorry.
+
+let $VERSION=`select version()`;
+
+connection master;
+reset master;
+create table t1(n int not null auto_increment primary key);
+insert into t1 values (NULL);
+drop table t1;
+create table t1 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t1 ignore 1 lines;
+select count(*) from t1;
+drop table t1;
+--replace_result $VERSION VERSION
+show binlog events;
+show binlog events from 79 limit 1;
+show binlog events from 79 limit 2;
+show binlog events from 79 limit 2,1;
+flush logs;
+
+# We need an extra update before doing save_master_pos.
+# Otherwise, an unlikely scenario may occur:
+# * When the master's binlog_dump thread reads the end of master-bin.001,
+# it send the rotate event which is at this end, plus a fake rotate event
+# because it's starting to read a new binlog.
+# save_master_pos will record the position of the first of the two rotate
+# (because the fake one is not in the master's binlog anyway).
+# * Later the slave waits for the position of the first rotate event,
+# and it may quickly stop (in 'slave stop') without having received the fake
+# one.
+# So, depending on a few milliseconds, we end up with 2 rotate events in the
+# relay log or one, which influences the output of SHOW SLAVE STATUS, making
+# it not predictable and causing random test failures.
+# To make it predictable, we do a useless update now, but which has the
+# interest of making the slave catch both rotate events.
+
+create table t5 (a int);
+drop table t5;
+
+# Sync slave and force it to start on another binary log
+
+save_master_pos;
+connection slave;
+# Note that the above 'slave start' will cause a 3rd rotate event (a fake one)
+# to go into the relay log (the master always sends a fake one when replication
+# starts).
+slave start;
+sync_with_master;
+flush logs;
+slave stop;
+connection master;
+
+# Create some entries for second log
+
+create table t1 (n int);
+insert into t1 values (1);
+drop table t1;
+--replace_result $VERSION VERSION
+show binlog events;
+show binlog events in 'master-bin.002';
+show master logs;
+save_master_pos;
+connection slave;
+slave start;
+sync_with_master;
+show master logs;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION
+show binlog events in 'slave-bin.001' from 4;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION
+show binlog events in 'slave-bin.002' from 4;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+show slave status;
+
+# Need to recode the following
+
+#show new master for slave with master_log_file='master-bin.001' and master_log_pos=4 and master_server_id=1;
+#show new master for slave with master_log_file='master-bin.001' and master_log_pos=79 and master_server_id=1;
+#show new master for slave with master_log_file='master-bin.001' and master_log_pos=311 and master_server_id=1;
+#show new master for slave with master_log_file='master-bin.002' and master_log_pos=4 and master_server_id=1;
+#show new master for slave with master_log_file='master-bin.002' and master_log_pos=122 and master_server_id=1;
+
+--error 1220
+show binlog events in 'slave-bin.005' from 4;
diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test
new file mode 100644
index 00000000000..859180d4e25
--- /dev/null
+++ b/mysql-test/t/rpl_log_pos.test
@@ -0,0 +1,47 @@
+#
+# Testing of setting slave to wrong log position with master_log_pos
+#
+source include/master-slave.inc;
+show master status;
+save_master_pos;
+connection slave;
+sync_with_master;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+show slave status;
+slave stop;
+change master to master_log_pos=73;
+slave start;
+sleep 5;
+slave stop;
+
+change master to master_log_pos=73;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+show slave status;
+slave start;
+sleep 5;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+show slave status;
+slave stop;
+change master to master_log_pos=173;
+slave start;
+sleep 2;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+show slave status;
+connection master;
+show master status;
+create table if not exists t1 (n int);
+drop table if exists t1;
+create table t1 (n int);
+insert into t1 values (1),(2),(3);
+save_master_pos;
+connection slave;
+slave stop;
+change master to master_log_pos=79;
+slave start;
+sync_with_master;
+select * from t1;
+connection master;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
diff --git a/mysql-test/t/rpl_master_pos_wait.test b/mysql-test/t/rpl_master_pos_wait.test
new file mode 100644
index 00000000000..24479636c91
--- /dev/null
+++ b/mysql-test/t/rpl_master_pos_wait.test
@@ -0,0 +1,15 @@
+# See if master_pos_wait(,,timeout)
+# Terminates with "timeout expired" (-1)
+source include/master-slave.inc;
+save_master_pos;
+connection slave;
+sync_with_master;
+# Ask for a master log that has certainly not been reached yet
+# timeout= 2 seconds
+select master_pos_wait('master-bin.999999',0,2);
+# Testcase for bug 651 (master_pos_wait() hangs if slave idle and STOP SLAVE).
+send select master_pos_wait('master-bin.999999',0);
+connection slave1;
+stop slave sql_thread;
+connection slave;
+reap;
diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test
new file mode 100644
index 00000000000..7e9a8a1872e
--- /dev/null
+++ b/mysql-test/t/rpl_max_relay_size.test
@@ -0,0 +1,88 @@
+# Test of options max_binlog_size and max_relay_log_size and
+# how they act (if max_relay_log_size == 0, use max_binlog_size
+# for relay logs too).
+# Test of manual relay log rotation with FLUSH LOGS.
+
+source include/master-slave.inc;
+connection slave;
+stop slave;
+connection master;
+# Generate a big enough master's binlog to cause relay log rotations
+create table t1 (a int);
+let $1=800;
+disable_query_log;
+begin;
+while ($1)
+{
+# eval means expand $ expressions
+ eval insert into t1 values( $1 );
+ dec $1;
+}
+enable_query_log;
+drop table t1;
+save_master_pos;
+connection slave;
+reset slave;
+set global max_binlog_size=8192;
+set global max_relay_log_size=8192-1; # mapped to 4096
+select @@global.max_relay_log_size;
+start slave;
+sync_with_master;
+--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT
+show slave status;
+stop slave;
+reset slave;
+set global max_relay_log_size=(5*4096);
+select @@global.max_relay_log_size;
+start slave;
+sync_with_master;
+--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT
+--replace_column 18 #
+show slave status;
+stop slave;
+reset slave;
+set global max_relay_log_size=0;
+select @@global.max_relay_log_size;
+start slave;
+sync_with_master;
+--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT
+show slave status;
+
+# Tests below are mainly to ensure that we have not coded with wrong assumptions
+
+stop slave;
+reset slave;
+# test of relay log rotation when the slave is stopped
+# (to make sure it does not crash).
+flush logs;
+--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT
+show slave status;
+
+reset slave;
+start slave;
+sync_with_master;
+# test of relay log rotation when the slave is started
+flush logs;
+# We have now easy way to be sure that the SQL thread has now deleted the
+# log we just closed. But a trick to achieve this is do an update on the master.
+connection master;
+create table t1 (a int);
+save_master_pos;
+connection slave;
+sync_with_master;
+--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT
+show slave status;
+# one more rotation, to be sure Relay_log_space is correctly updated
+flush logs;
+connection master;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT
+show slave status;
+
+connection master;
+# test that the absence of relay logs does not make a master crash
+flush logs;
+show master status;
diff --git a/mysql-test/t/rpl_multi_delete-slave.opt b/mysql-test/t/rpl_multi_delete-slave.opt
new file mode 100644
index 00000000000..c98fe0b0a46
--- /dev/null
+++ b/mysql-test/t/rpl_multi_delete-slave.opt
@@ -0,0 +1 @@
+--replicate-wild-do-table=test.%
diff --git a/mysql-test/t/rpl_multi_delete.test b/mysql-test/t/rpl_multi_delete.test
new file mode 100644
index 00000000000..299cb720b62
--- /dev/null
+++ b/mysql-test/t/rpl_multi_delete.test
@@ -0,0 +1,23 @@
+source include/master-slave.inc;
+create table t1 (a int);
+create table t2 (a int);
+
+insert into t1 values (1);
+insert into t2 values (1);
+
+delete t1.* from t1, t2 where t1.a = t2.a;
+
+save_master_pos;
+select * from t1;
+select * from t2;
+
+connection slave;
+sync_with_master;
+select * from t1;
+select * from t2;
+
+connection master;
+drop table t1,t2;
+save_master_pos;
+connection slave;
+sync_with_master;
diff --git a/mysql-test/t/rpl_multi_update.test b/mysql-test/t/rpl_multi_update.test
new file mode 100644
index 00000000000..c44239594dd
--- /dev/null
+++ b/mysql-test/t/rpl_multi_update.test
@@ -0,0 +1,25 @@
+source include/master-slave.inc;
+drop table if exists t1,t2;
+
+CREATE TABLE t1 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned,
+) TYPE=MyISAM;
+
+CREATE TABLE t2 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned
+) TYPE=MyISAM;
+
+INSERT INTO t1 VALUES (NULL, 0);
+INSERT INTO t1 SELECT NULL, 0 FROM t1;
+
+INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
+
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+UPDATE t1, t2 SET t1.b = t2.b WHERE t1.a = t2.a;
+save_master_pos;
+connection slave;
+sync_with_master;
diff --git a/mysql-test/t/rpl_mystery22.test b/mysql-test/t/rpl_mystery22.test
index 3a48ef84dc1..5280cb360dd 100644
--- a/mysql-test/t/rpl_mystery22.test
+++ b/mysql-test/t/rpl_mystery22.test
@@ -1,7 +1,7 @@
# test case to make slave thread get ahead by 22 bytes
source include/master-slave.inc;
-connection master;
+
# first, cause a duplicate key problem on the slave
create table t1(n int auto_increment primary key);
save_master_pos;
@@ -13,7 +13,7 @@ insert into t1 values(NULL);
insert into t1 values(NULL);
save_master_pos;
connection slave;
-sleep 1; # there is no way around this sleep - we have to wait until
+sleep 3; # there is no way around this sleep - we have to wait until
# the slave tries to run the query, fails and aborts slave thread
delete from t1 where n = 2;
slave start;
diff --git a/mysql-test/t/rpl_redirect.test b/mysql-test/t/rpl_redirect.test
new file mode 100644
index 00000000000..4082542f295
--- /dev/null
+++ b/mysql-test/t/rpl_redirect.test
@@ -0,0 +1,41 @@
+#
+# Test of automatic redirection of queries to master/slave.
+#
+
+source include/master-slave.inc;
+
+#first, make sure the slave has had enough time to register
+save_master_pos;
+connection slave;
+sync_with_master;
+
+#discover slaves
+connection master;
+--replace_result $MASTER_MYPORT MASTER_PORT
+SHOW SLAVE STATUS;
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+SHOW SLAVE HOSTS;
+rpl_probe;
+
+#turn on master/slave query direction auto-magic
+enable_rpl_parse;
+drop table if exists t1;
+create table t1 ( n int);
+insert into t1 values (1),(2),(3),(4);
+disable_rpl_parse;
+save_master_pos;
+connection slave;
+sync_with_master;
+insert into t1 values(5);
+connection master;
+enable_rpl_parse;
+# The first of the queries will be sent to the slave, the second to the master.
+select * from t1;
+select * from t1;
+disable_rpl_parse;
+select * from t1;
+connection slave;
+select * from t1;
+drop table t1;
+connection master;
+drop table t1;
diff --git a/mysql-test/t/rpl_relayspace-slave.opt b/mysql-test/t/rpl_relayspace-slave.opt
new file mode 100644
index 00000000000..05cb01731d2
--- /dev/null
+++ b/mysql-test/t/rpl_relayspace-slave.opt
@@ -0,0 +1 @@
+ -O relay_log_space_limit=10 \ No newline at end of file
diff --git a/mysql-test/t/rpl_relayspace.test b/mysql-test/t/rpl_relayspace.test
new file mode 100644
index 00000000000..bb82781b511
--- /dev/null
+++ b/mysql-test/t/rpl_relayspace.test
@@ -0,0 +1,32 @@
+# The slave is started with relay_log_space_limit=10 bytes,
+# to force the deadlock after one event.
+
+source include/master-slave.inc;
+connection slave;
+stop slave;
+connection master;
+# This will generate a master's binlog > 10 bytes
+create table t1 (a int);
+drop table t1;
+create table t1 (a int);
+drop table t1;
+connection slave;
+reset slave;
+start slave io_thread;
+# Give the I/O thread time to block.
+sleep 2;
+# A bug caused the I/O thread to refuse stopping.
+stop slave io_thread;
+reset slave;
+start slave;
+# The I/O thread stops filling the relay log when
+# it's >10b. And the SQL thread cannot purge this relay log
+# as purge is done only when the SQL thread switches to another
+# relay log, which does not exist here.
+# So we should have a deadlock.
+# if it is not resolved automatically we'll detect
+# it with master_pos_wait that waits for farther than 1Ob;
+# it will timeout after 10 seconds;
+# also the slave will probably not cooperate to shutdown
+# (as 2 threads are locked)
+select master_pos_wait('master-bin.001',200,6)=-1;
diff --git a/mysql-test/t/rpl_replicate_do-slave.opt b/mysql-test/t/rpl_replicate_do-slave.opt
new file mode 100644
index 00000000000..da345474216
--- /dev/null
+++ b/mysql-test/t/rpl_replicate_do-slave.opt
@@ -0,0 +1 @@
+--replicate-do-table=test.t1
diff --git a/mysql-test/t/rpl_replicate_do.test b/mysql-test/t/rpl_replicate_do.test
new file mode 100644
index 00000000000..0800062dc05
--- /dev/null
+++ b/mysql-test/t/rpl_replicate_do.test
@@ -0,0 +1,30 @@
+# This test assumes we are ignoring updates on table t2, but doing
+# updates on t1
+
+source include/master-slave.inc;
+drop table if exists t11;
+connection slave;
+drop table if exists t11;
+create table t2 (n int);
+insert into t2 values(4);
+connection master;
+create table t2 (s char(20));
+load data infile '../../std_data/words.dat' into table t2;
+insert into t2 values('five');
+create table t1 (m int);
+insert into t1 values(15),(16),(17);
+update t1 set m=20 where m=16;
+delete from t1 where m=17;
+create table t11 select * from t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from t1;
+select * from t2;
+--error 1146
+select * from t11;
+connection master;
+drop table if exists t1,t2,t3,t11;
+save_master_pos;
+connection slave;
+sync_with_master;
diff --git a/mysql-test/t/rpl_reset_slave.test b/mysql-test/t/rpl_reset_slave.test
new file mode 100644
index 00000000000..083492c3fc0
--- /dev/null
+++ b/mysql-test/t/rpl_reset_slave.test
@@ -0,0 +1,44 @@
+# See SHOW SLAVE STATUS displays well after RESET SLAVE (it should display the
+# --master-* options from mysqld, as this is what is going to be used next time
+# slave threads will be started). In bug 985, it displayed old values (of before
+# RESET SLAVE).
+# See if slave crashes when doing a CREATE TEMPORARY TABLE twice, separated by
+# RESET SLAVE.
+
+source include/master-slave.inc;
+connection master;
+save_master_pos;
+connection slave;
+sync_with_master;
+--replace_result $MASTER_MYPORT MASTER_PORT
+show slave status;
+
+stop slave;
+change master to master_user='test';
+--replace_result $MASTER_MYPORT MASTER_PORT
+show slave status;
+
+reset slave;
+--replace_result $MASTER_MYPORT MASTER_PORT
+show slave status;
+
+start slave;
+sync_with_master;
+--replace_result $MASTER_MYPORT MASTER_PORT
+show slave status;
+
+# test of crash with temp tables & RESET SLAVE
+# (test to see if RESET SLAVE clears temp tables in memory and disk)
+stop slave;
+reset slave;
+start slave;
+connection master;
+create temporary table t1 (a int);
+save_master_pos;
+connection slave;
+sync_with_master;
+stop slave;
+reset slave;
+start slave;
+sync_with_master;
+show status like 'slave_open_temp_tables';
diff --git a/mysql-test/t/rpl_rotate_logs-master.opt b/mysql-test/t/rpl_rotate_logs-master.opt
index f27601e0d7d..ad2c6a647b5 100644
--- a/mysql-test/t/rpl_rotate_logs-master.opt
+++ b/mysql-test/t/rpl_rotate_logs-master.opt
@@ -1 +1 @@
--O max_binlog_size=2048
+-O max_binlog_size=4096
diff --git a/mysql-test/t/rpl_rotate_logs-slave.sh b/mysql-test/t/rpl_rotate_logs-slave.sh
index 62748605af1..9259f593e54 100755
--- a/mysql-test/t/rpl_rotate_logs-slave.sh
+++ b/mysql-test/t/rpl_rotate_logs-slave.sh
@@ -1 +1,2 @@
rm -f $MYSQL_TEST_DIR/var/slave-data/master.info
+rm -f $MYSQL_TEST_DIR/var/slave-data/*relay*
diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test
index ab88def5b2d..70366fc1749 100644
--- a/mysql-test/t/rpl_rotate_logs.test
+++ b/mysql-test/t/rpl_rotate_logs.test
@@ -9,27 +9,36 @@
# changes
# - Test creating a duplicate key error and recover from it
#
-connect (master,localhost,root,,test,0,mysql-master.sock);
-connect (slave,localhost,root,,test,0,mysql-slave.sock);
+connect (master,localhost,root,,test,$MASTER_MYPORT,master.sock);
+drop table if exists t1, t2, t3, t4;
+connect (slave,localhost,root,,test,$SLAVE_MYPORT,slave.sock);
system cat /dev/null > var/slave-data/master.info;
system chmod 000 var/slave-data/master.info;
connection slave;
-!slave start;
+drop table if exists t1, t2, t3, t4;
+# START SLAVE will fail because it can't read the file (mode 000) (system error 13)
+--error 1201
+slave start;
system chmod 600 var/slave-data/master.info;
-!slave start;
-!eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT,
- master_user='root';
+# It will fail again because the file is empty so the slave cannot get valuable
+# info about how to connect to the master from it (failure in
+# init_strvar_from_file() in init_master_info()).
+--error 1201
+slave start;
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+# CHANGE MASTER will fail because it first parses master.info before changing it
+# (so when master.info is bad, people have to use RESET SLAVE first).
+--error 1201
+eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root';
reset slave;
-eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT,
- master_user='root';
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root';
connection master;
reset master;
connection slave;
slave start;
connection master;
-drop table if exists t1, t2, t3, t4;
-
#
# Test FLUSH LOGS
#
@@ -40,12 +49,12 @@ insert into t1 values('Could not break slave'),('Tried hard');
save_master_pos;
connection slave;
sync_with_master;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+--replace_column 18 #
show slave status;
select * from t1;
connection master;
flush logs;
-drop table if exists t2;
create table t2(m int not null auto_increment primary key);
insert into t2 values (34),(67),(123);
flush logs;
@@ -70,17 +79,13 @@ insert into t2 values(1234);
#same value on the master
connection master;
-save_master_pos;
set insert_id=1234;
insert into t2 values(NULL);
connection slave;
-sync_with_master;
-
-#the slave may have already stopped, so we ignore the error
-!slave stop;
+wait_for_slave_to_stop;
#restart slave skipping one event
-set sql_slave_skip_counter=1;
+set global sql_slave_skip_counter=1;
slave start;
connection master;
@@ -96,7 +101,8 @@ insert into t2 values (65);
save_master_pos;
connection slave;
sync_with_master;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+--replace_column 18 #
show slave status;
select * from t2;
@@ -108,25 +114,27 @@ connection master;
create temporary table temp_table (a char(80) not null);
insert into temp_table values ("testing temporary tables part 2");
let $1=100;
-drop table if exists t3;
+
create table t3 (n int);
+disable_query_log;
while ($1)
{
#eval means expand $ expressions
eval insert into t3 values($1 + 4);
dec $1;
}
+enable_query_log;
+select count(*) from t3 where n >= 4;
create table t4 select * from temp_table;
show master logs;
show master status;
save_master_pos;
connection slave;
-#slave stop;
-#slave start;
sync_with_master;
select * from t4;
---replace_result 9306 9999 3334 9999 3335 9999
+--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
+--replace_column 18 #
show slave status;
# because of concurrent insert, the table may not be up to date
# if we do not lock
@@ -135,7 +143,7 @@ select count(*) from t3 where n >= 4;
unlock tables;
#clean up
connection master;
-drop table if exists t1,t2,t3;
+drop table if exists t1,t2,t3,t4;
save_master_pos;
connection slave;
sync_with_master;
diff --git a/mysql-test/t/rpl_skip_error.test b/mysql-test/t/rpl_skip_error.test
index 3303b45c1ca..d43c59ef024 100644
--- a/mysql-test/t/rpl_skip_error.test
+++ b/mysql-test/t/rpl_skip_error.test
@@ -1,6 +1,6 @@
source include/master-slave.inc;
-connection master;
drop table if exists t1;
+
create table t1 (n int not null primary key);
save_master_pos;
connection slave;
diff --git a/mysql-test/t/rpl_sporadic_master.test b/mysql-test/t/rpl_sporadic_master.test
index c1a47781ddf..e59b93b4475 100644
--- a/mysql-test/t/rpl_sporadic_master.test
+++ b/mysql-test/t/rpl_sporadic_master.test
@@ -2,12 +2,11 @@
# COM_BINLOG_DUMP and additionally limits the number of events per dump
source include/master-slave.inc;
-connection master;
-drop table if exists t1,t2;
+
create table t2(n int);
create table t1(n int not null auto_increment primary key);
insert into t1 values (NULL),(NULL);
-delete from t1;
+truncate table t1;
# We have to use 4 in the following to make this test work with all table types
insert into t1 values (4),(NULL);
save_master_pos;
@@ -18,10 +17,8 @@ slave start;
connection master;
insert into t1 values (NULL),(NULL);
flush logs;
-delete from t1;
-insert into t1 values (10),(NULL);
-insert into t1 values (NULL),(NULL);
-insert into t1 values (NULL),(NULL);
+truncate table t1;
+insert into t1 values (10),(NULL),(NULL),(NULL),(NULL),(NULL);
save_master_pos;
connection slave;
sync_with_master;
diff --git a/mysql-test/t/rpl_trunc_binlog.test b/mysql-test/t/rpl_trunc_binlog.test
new file mode 100644
index 00000000000..98138b61ab7
--- /dev/null
+++ b/mysql-test/t/rpl_trunc_binlog.test
@@ -0,0 +1,25 @@
+# We are testing if a binlog which contains BEGIN but not COMMIT (the master did
+# while writing the transaction to the binlog) triggers an error on slave.
+# So we use such a truncated binlog and simulate that the master restarted after
+# this.
+
+source include/master-slave.inc;
+
+connection slave;
+# If we are not supporting transactions in the slave, the unfinished transaction
+# won't cause any error, so we need to skip the test. In the 4.0 testsuite, the
+# slave always runs without InnoDB, so we check for BDB.
+source include/have_bdb.inc;
+stop slave;
+connection master;
+flush logs;
+system mv -f var/log/master-bin.001 var/log/master-bin.002;
+system cp std_data/trunc_binlog.001 var/log/master-bin.001;
+connection slave;
+reset slave;
+start slave;
+# can't sync_with_master so we must sleep
+sleep 3;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 18 #
+show slave status;
diff --git a/mysql-test/t/sel000001.test b/mysql-test/t/sel000001.test
index 77355f8d535..ad4af1f92fb 100644
--- a/mysql-test/t/sel000001.test
+++ b/mysql-test/t/sel000001.test
@@ -16,3 +16,16 @@ CREATE TABLE t1 (s CHAR(20) PRIMARY KEY, id INT);
INSERT INTO t1 VALUES ('cat', 1), ('mouse', 3), ('dog', 2), ('snake', 77);
SELECT s, id FROM t1 WHERE s = 'mouse';
drop table t1;
+
+#
+#test for bug #717
+#
+CREATE TABLE t1 (
+ node int(11) NOT NULL default '0',
+ maxchild int(11) NOT NULL default '0',
+ PRIMARY KEY (`node`)
+);
+INSERT INTO t1 (node, maxchild) VALUES (4,4),(5,5),(1,244);
+SELECT * FROM t1 g1, t1 g2
+ WHERE g1.node <= g2.node and g2.node <= g1.maxchild and g2.node = g2.maxchild;
+DROP TABLE t1;
diff --git a/mysql-test/t/sel000100.test b/mysql-test/t/sel000100.test
index cedb78b17e7..d587fa4ebd0 100644
--- a/mysql-test/t/sel000100.test
+++ b/mysql-test/t/sel000100.test
@@ -29,3 +29,18 @@ GROUP BY t1.id
ORDER BY link;
drop table t1,t2;
+
+#
+# test case for #674
+#
+CREATE TABLE t1 (
+ html varchar(5) default NULL,
+ rin int(11) default '0',
+ out int(11) default '0'
+) TYPE=MyISAM;
+
+INSERT INTO t1 VALUES ('1',1,0);
+
+SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
+
+drop table t1;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 2caadd99dbb..7cb157f194e 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -6,8 +6,6 @@
# Simple select test
#
-use test;
-
drop table if exists t1,t2,t3,t4;
CREATE TABLE t1 (
@@ -42,6 +40,7 @@ CREATE TABLE t2 (
# Populate table
#
+--disable_query_log
INSERT INTO t2 VALUES (1,000001,00,'Omaha','teethe','neat','');
INSERT INTO t2 VALUES (2,011401,37,'breaking','dreaded','Steinberg','W');
INSERT INTO t2 VALUES (3,011402,37,'Romans','scholastics','jarring','');
@@ -1241,6 +1240,7 @@ INSERT INTO t2 VALUES (1190,123304,00,'bruises','Medicare','backer','');
INSERT INTO t2 VALUES (1191,068504,00,'bonfire','corresponds','positively','');
INSERT INTO t2 VALUES (1192,068305,00,'Colombo','hardware','colicky','');
INSERT INTO t2 VALUES (1193,000000,00,'nondecreasing','implant','thrillingly','');
+--enable_query_log
#
# Search with a key
@@ -1366,6 +1366,7 @@ create table t3 (
key (name)
);
+--disable_query_log
INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1001,"Iranizes",37,5987435,234724);
INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1002,"violinist",37,28357832,8723648);
INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1003,"extramarital",37,39654943,235872);
@@ -1376,6 +1377,7 @@ INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1007,"hand",154,9835
INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1008,"tucked",311,234298,3275892);
INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1009,"gems",447,2374834,9872392);
INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1010,"clinker",512,786542,76234234);
+--enable_query_log
create temporary table tmp type = myisam select * from t3;
@@ -1405,9 +1407,9 @@ drop table tmp;
# big table done
-SET OPTION SQL_BIG_TABLES=1;
+SET SQL_BIG_TABLES=1;
select distinct concat(fld3," ",fld3) as namn from t2,t3 where t2.fld1=t3.t2nr order by namn limit 10;
-SET OPTION SQL_BIG_TABLES=0;
+SET SQL_BIG_TABLES=0;
select distinct concat(fld3," ",fld3) from t2,t3 where t2.fld1=t3.t2nr order by fld3 limit 10;
select distinct fld5 from t2 limit 10;
@@ -1416,9 +1418,9 @@ select distinct fld5 from t2 limit 10;
#
select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
-SET OPTION SQL_BIG_TABLES=1; # Force use of MyISAM
+SET SQL_BIG_TABLES=1; # Force use of MyISAM
select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
-SET OPTION SQL_BIG_TABLES=0;
+SET SQL_BIG_TABLES=0;
select distinct fld3,repeat("a",length(fld3)),count(*) from t2 group by companynr,fld3 limit 100,10;
#
@@ -1440,6 +1442,14 @@ select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr orde
explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3;
#
+# Some test with ORDER BY and limit
+#
+
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10;
+
+#
# Search with a constant table.
#
@@ -1490,6 +1500,7 @@ create table t4 (
UNIQUE KEY companyname(companyname)
) TYPE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames';
+--disable_query_log
INSERT INTO t4 (companynr, companyname) VALUES (29,'company 1');
INSERT INTO t4 (companynr, companyname) VALUES (34,'company 2');
INSERT INTO t4 (companynr, companyname) VALUES (36,'company 3');
@@ -1502,6 +1513,7 @@ INSERT INTO t4 (companynr, companyname) VALUES (65,'company 9');
INSERT INTO t4 (companynr, companyname) VALUES (68,'company 10');
INSERT INTO t4 (companynr, companyname) VALUES (50,'company 11');
INSERT INTO t4 (companynr, companyname) VALUES (00,'Unknown');
+--enable_query_log
#
# Test of stright join to force a full join.
@@ -1521,10 +1533,24 @@ select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 25
#
# Test of left join.
#
+insert into t2 (fld1, companynr) values (999999,99);
select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
+select count(*) from t2 left join t4 using (companynr) where t4.companynr is not null;
explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null;
+delete from t2 where fld1=999999;
+
+#
+# Test left join optimization
+
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0;
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0;
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0;
+# Following can't be optimized
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0;
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0;
#
# Joins with forms.
@@ -1712,11 +1738,19 @@ show full columns from t2 from test like 'f%';
show full columns from t2 from test like 's%';
show keys from t2;
+drop table t4, t3, t2, t1;
+
+#
+# Test of DO
+#
+
+DO 1;
+DO benchmark(100,1+1),1,1;
+
#
# random in WHERE clause
#
-drop table t1;
CREATE TABLE t1 (
id mediumint(8) unsigned NOT NULL auto_increment,
pseudo varchar(35) NOT NULL default '',
@@ -1725,10 +1759,118 @@ CREATE TABLE t1 (
);
INSERT INTO t1 (pseudo) VALUES ('test');
INSERT INTO t1 (pseudo) VALUES ('test1');
-SELECT 1 from t1 where rand() > 2;
+SELECT 1 as rnd1 from t1 where rand() > 2;
+DROP TABLE t1;
#
-# Drop the test tables
+# Test of bug with SUM(CASE...)
#
-drop table t4, t3, t2, t1;
+CREATE TABLE t1 (gvid int(10) unsigned default NULL, hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, mmid int(10) unsigned default NULL, hdid int(10) unsigned default NULL, fsid int(10) unsigned default NULL, ctid int(10) unsigned default NULL, dtid int(10) unsigned default NULL, cost int(10) unsigned default NULL, performance int(10) unsigned default NULL, serialnumber bigint(20) unsigned default NULL, monitored tinyint(3) unsigned default '1', removed tinyint(3) unsigned default '0', target tinyint(3) unsigned default '0', dt_modified timestamp(14) NOT NULL, name varchar(255) binary default NULL, description varchar(255) default NULL, UNIQUE KEY hmid (hmid,volid)) TYPE=MyISAM;
+INSERT INTO t1 VALUES (200001,2,1,1,100,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\E$',''),(200002,2,2,1,101,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\C$',''),(200003,1,3,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,0,1,20020425060427,'c:',NULL);
+CREATE TABLE t2 ( hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, sampletid smallint(5) unsigned default NULL, sampletime datetime default NULL, samplevalue bigint(20) unsigned default NULL, KEY idx1 (hmid,volid,sampletid,sampletime)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12:00:01',35);
+SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'NULL' AND b.sampletime < 'NULL' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid;
+DROP TABLE t1,t2;
+
+#
+# Test of bigint comparision
+#
+
+create table t1 ( A_Id bigint(20) NOT NULL default '0', A_UpdateBy char(10) NOT NULL default '', A_UpdateDate bigint(20) NOT NULL default '0', A_UpdateSerial int(11) NOT NULL default '0', other_types bigint(20) NOT NULL default '0', wss_type bigint(20) NOT NULL default '0');
+INSERT INTO t1 VALUES (102935998719055004,'brade',1029359987,2,102935229116544068,102935229216544093);
+select wss_type from t1 where wss_type ='102935229216544106';
+select wss_type from t1 where wss_type ='102935229216544105';
+select wss_type from t1 where wss_type ='102935229216544104';
+select wss_type from t1 where wss_type ='102935229216544093';
+select wss_type from t1 where wss_type =102935229216544093;
+drop table t1;
+
+#
+# Test of removing redundant braces in the FROM part
+# (We test each construct with the braced join to the left and right;
+# the latter case used to cause a syntax errors.)
+#
+
+create table t1 (a int not null auto_increment primary key);
+insert into t1 values ();
+insert into t1 values ();
+insert into t1 values ();
+# ,
+select * from (t1 as t2 left join t1 as t3 using (a)), t1;
+select * from t1, (t1 as t2 left join t1 as t3 using (a));
+# stright_join
+select * from (t1 as t2 left join t1 as t3 using (a)) straight_join t1;
+select * from t1 straight_join (t1 as t2 left join t1 as t3 using (a));
+# inner join on
+select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1;
+select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+# inner join using
+select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 using ( a );
+select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+# left [outer] join on
+select * from (t1 as t2 left join t1 as t3 using (a)) left outer join t1 on t1.a>1;
+select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+# left join using
+select * from (t1 as t2 left join t1 as t3 using (a)) left join t1 using ( a );
+select * from t1 left join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+# natural left join
+select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
+select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a));
+# right join on
+select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1;
+select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
+# right [outer] joing using
+select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a );
+select * from t1 right outer join (t1 as t2 left join t1 as t3 using (a)) using ( a );
+# natural right join
+select * from (t1 as t2 left join t1 as t3 using (a)) natural right join t1;
+select * from t1 natural right join (t1 as t2 left join t1 as t3 using (a));
+# natural join
+select * from t1 natural join (t1 as t2 left join t1 as t3 using (a));
+select * from (t1 as t2 left join t1 as t3 using (a)) natural join t1;
+drop table t1;
+
+CREATE TABLE t1 ( aa char(2), id int(11) NOT NULL auto_increment, t2_id int(11) NOT NULL default '0', PRIMARY KEY (id), KEY replace_id (t2_id)) TYPE=MyISAM;
+INSERT INTO t1 VALUES ("1",8264,2506),("2",8299,2517),("3",8301,2518),("4",8302,2519),("5",8303,2520),("6",8304,2521),("7",8305,2522);
+CREATE TABLE t2 ( id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) TYPE=MyISAM;
+INSERT INTO t2 VALUES (2517), (2518), (2519), (2520), (2521), (2522);
+select * from t1, t2 WHERE t1.t2_id = t2.id and t1.t2_id > 0 order by t1.id LIMIT 0, 5;
+drop table t1,t2;
+
+#
+# outer join, impossible on condition, where, and usable key for range
+#
+create table t1 (id1 int NOT NULL);
+create table t2 (id2 int NOT NULL);
+create table t3 (id3 int NOT NULL);
+create table t4 (id4 int NOT NULL, id44 int NOT NULL, KEY (id4));
+
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t2 values (1);
+insert into t4 values (1,1);
+
+explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
+left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
+select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
+left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
+
+drop table t1,t2,t3,t4;
+
+#
+# Bug #2298
+#
+
+create table t1(s varchar(10) not null);
+create table t2(s varchar(10) not null primary key);
+create table t3(s varchar(10) not null primary key);
+insert into t1 values ('one\t'), ('two\t');
+insert into t2 values ('one\r'), ('two\t');
+insert into t3 values ('one '), ('two\t');
+select * from t1 where s = 'one';
+select * from t2 where s = 'one';
+select * from t3 where s = 'one';
+select * from t1,t2 where t1.s = t2.s;
+select * from t2,t3 where t2.s = t3.s;
+drop table t1, t2, t3;
diff --git a/mysql-test/t/select_found.test b/mysql-test/t/select_found.test
new file mode 100644
index 00000000000..f5ee4d5c010
--- /dev/null
+++ b/mysql-test/t/select_found.test
@@ -0,0 +1,101 @@
+#
+# Testing of found_rows()
+#
+
+drop table if exists t1,t2;
+create table t1 (a int not null auto_increment, b int not null, primary key(a));
+insert into t1 (b) values (2),(3),(5),(5),(5),(6),(7),(9);
+select SQL_CALC_FOUND_ROWS * from t1;
+select found_rows();
+select SQL_CALC_FOUND_ROWS * from t1 limit 1;
+select found_rows();
+select SQL_BUFFER_RESULT SQL_CALC_FOUND_ROWS * from t1 limit 1;
+select found_rows();
+select SQL_CALC_FOUND_ROWS * from t1 order by b desc limit 1;
+select found_rows();
+select SQL_CALC_FOUND_ROWS distinct b from t1 limit 1;
+select found_rows();
+select SQL_CALC_FOUND_ROWS b,count(*) as c from t1 group by b order by c desc limit 1;
+select found_rows();
+select SQL_CALC_FOUND_ROWS * from t1 left join t1 as t2 on (t1.b=t2.a) limit 2,1;
+select found_rows();
+drop table t1;
+
+#
+# Test SQL_CALC_FOUND_ROWS optimization when used with one table and filesort
+#
+
+create table t1 (a int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+select sql_calc_found_rows a from t1 where a in (1,2,3) order by a desc limit 0,2;
+select FOUND_ROWS();
+select sql_calc_found_rows a from t1 where a in (1,2,3) order by a+2 desc limit 0,2;
+select FOUND_ROWS();
+drop table t1;
+
+#
+# Test of SQL_CALC_FOUND_ROWS with DISTINCT
+#
+
+CREATE TABLE t1 (
+`id` smallint(5) unsigned NOT NULL auto_increment,
+`kid` smallint(5) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+KEY `kid` (`kid`)
+);
+
+CREATE TABLE t2 (
+ id smallint(5) unsigned NOT NULL auto_increment,
+ name varchar(50) NOT NULL default '',
+ email varchar(50) NOT NULL default '',
+ PRIMARY KEY (id),
+ UNIQUE KEY e_n (email,name)
+);
+
+INSERT INTO t2 VALUES (1,'name1','email1'),(2,'name2','email2'),(3,'name3','email3'),(4,'name4','email4'),(5,'name5','email5'),(6,'name6','email6'),(7,'name7','email7'),(8,'name8','email8'),(9,'name9','email9'),(10,'name10','email10'),(11,'name11','email11'),(12,'name12','email12'),(13,'name13','email13'),(14,'name14','email14'),(15,'name15','email15'),(16,'name16','email16'),(17,'name17','email17'),(18,'name18','email18'),(19,'name19','email19'),(20,'name20','email20'),(21,'name21','email21'),(22,'name22','email22'),(23,'name23','email23'),(24,'name24','email24'),(25,'name25','email25'),(26,'name26','email26'),(27,'name27','email27'),(28,'name28','email28'),(29,'name29','email29'),(30,'name30','email30'),(31,'name31','email31'),(32,'name32','email32'),(33,'name33','email33'),(34,'name34','email34'),(35,'name35','email35'),(36,'name36','email36'),(37,'name37','email37'),(38,'name38','email38'),(39,'name39','email39'),(40,'name40','email40'),(41,'name41','email41'),(42,'name42','email42'),(43,'name43','email43'),(44,'name44','email44'),(45,'name45','email45'),(46,'name46','email46'),(47,'name47','email47'),(48,'name48','email48'),(49,'name49','email49'),(50,'name50','email50'),(51,'name51','email51'),(52,'name52','email52'),(53,'name53','email53'),(54,'name54','email54'),(55,'name55','email55'),(56,'name56','email56'),(57,'name57','email57'),(58,'name58','email58'),(59,'name59','email59'),(60,'name60','email60'),(61,'name61','email61'),(62,'name62','email62'),(63,'name63','email63'),(64,'name64','email64'),(65,'name65','email65'),(66,'name66','email66'),(67,'name67','email67'),(68,'name68','email68'),(69,'name69','email69'),(70,'name70','email70'),(71,'name71','email71'),(72,'name72','email72'),(73,'name73','email73'),(74,'name74','email74'),(75,'name75','email75'),(76,'name76','email76'),(77,'name77','email77'),(78,'name78','email78'),(79,'name79','email79'),(80,'name80','email80'),(81,'name81','email81'),(82,'name82','email82'),(83,'name83','email83'),(84,'name84','email84'),(85,'name85','email85'),(86,'name86','email86'),(87,'name87','email87'),(88,'name88','email88'),(89,'name89','email89'),(90,'name90','email90'),(91,'name91','email91'),(92,'name92','email92'),(93,'name93','email93'),(94,'name94','email94'),(95,'name95','email95'),(96,'name96','email96'),(97,'name97','email97'),(98,'name98','email98'),(99,'name99','email99'),(100,'name100','email100'),(101,'name101','email101'),(102,'name102','email102'),(103,'name103','email103'),(104,'name104','email104'),(105,'name105','email105'),(106,'name106','email106'),(107,'name107','email107'),(108,'name108','email108'),(109,'name109','email109'),(110,'name110','email110'),(111,'name111','email111'),(112,'name112','email112'),(113,'name113','email113'),(114,'name114','email114'),(115,'name115','email115'),(116,'name116','email116'),(117,'name117','email117'),(118,'name118','email118'),(119,'name119','email119'),(120,'name120','email120'),(121,'name121','email121'),(122,'name122','email122'),(123,'name123','email123'),(124,'name124','email124'),(125,'name125','email125'),(126,'name126','email126'),(127,'name127','email127'),(128,'name128','email128'),(129,'name129','email129'),(130,'name130','email130'),(131,'name131','email131'),(132,'name132','email132'),(133,'name133','email133'),(134,'name134','email134'),(135,'name135','email135'),(136,'name136','email136'),(137,'name137','email137'),(138,'name138','email138'),(139,'name139','email139'),(140,'name140','email140'),(141,'name141','email141'),(142,'name142','email142'),(143,'name143','email143'),(144,'name144','email144'),(145,'name145','email145'),(146,'name146','email146'),(147,'name147','email147'),(148,'name148','email148'),(149,'name149','email149'),(150,'name150','email150'),(151,'name151','email151'),(152,'name152','email152'),(153,'name153','email153'),(154,'name154','email154'),(155,'name155','email155'),(156,'name156','email156'),(157,'name157','email157'),(158,'name158','email158'),(159,'name159','email159'),(160,'name160','email160'),(161,'name161','email161'),(162,'name162','email162'),(163,'name163','email163'),(164,'name164','email164'),(165,'name165','email165'),(166,'name166','email166'),(167,'name167','email167'),(168,'name168','email168'),(169,'name169','email169'),(170,'name170','email170'),(171,'name171','email171'),(172,'name172','email172'),(173,'name173','email173'),(174,'name174','email174'),(175,'name175','email175'),(176,'name176','email176'),(177,'name177','email177'),(178,'name178','email178'),(179,'name179','email179'),(180,'name180','email180'),(181,'name181','email181'),(182,'name182','email182'),(183,'name183','email183'),(184,'name184','email184'),(185,'name185','email185'),(186,'name186','email186'),(187,'name187','email187'),(188,'name188','email188'),(189,'name189','email189'),(190,'name190','email190'),(191,'name191','email191'),(192,'name192','email192'),(193,'name193','email193'),(194,'name194','email194'),(195,'name195','email195'),(196,'name196','email196'),(197,'name197','email197'),(198,'name198','email198'),(199,'name199','email199'),(200,'name200','email200');
+
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+SELECT FOUND_ROWS();
+
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL order by email LIMIT 10;
+SELECT FOUND_ROWS();
+
+SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+SELECT DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL ORDER BY email LIMIT 10;
+INSERT INTO `t1` (`id`, `kid`) VALUES ('', '150');
+
+SELECT SQL_CALC_FOUND_ROWS DISTINCT email FROM t2 LEFT JOIN t1 ON kid = t2.id WHERE t1.id IS NULL LIMIT 10;
+SELECT FOUND_ROWS();
+
+drop table t1,t2;
+
+#
+# Test bug when using range optimization
+#
+
+CREATE TABLE `t1` (
+ `titre` char(80) NOT NULL default '',
+ `numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+ `maxnumrep` int(10) unsigned NOT NULL default '0',
+ PRIMARY KEY (`numeropost`),
+ KEY `maxnumrep` (`maxnumrep`)
+) TYPE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (titre,maxnumrep) VALUES
+('test1','1'),('test2','2'),('test3','3');
+SELECT SQL_CALC_FOUND_ROWS titre,numeropost,maxnumrep FROM t1 WHERE numeropost IN (1,2) ORDER BY maxnumrep DESC LIMIT 0, 1;
+SELECT FOUND_ROWS();
+drop table t1;
+
+#
+# Test problem with impossible WHERE (Bug #1468)
+#
+
+create table t1 (id int, primary key (id));
+insert into t1 values (1), (2), (3), (4), (5);
+select SQL_CALC_FOUND_ROWS * from t1 where id > 3 limit 0, 1;
+select FOUND_ROWS();
+select SQL_CALC_FOUND_ROWS * from t1 where id > 3 AND 1=2 limit 0, 1;
+select FOUND_ROWS();
+select SQL_CALC_FOUND_ROWS * from t1 where id > 6 limit 0, 1;
+select FOUND_ROWS();
+drop table t1;
diff --git a/mysql-test/t/select_safe.test b/mysql-test/t/select_safe.test
index e76b7558997..904479635c2 100644
--- a/mysql-test/t/select_safe.test
+++ b/mysql-test/t/select_safe.test
@@ -4,7 +4,7 @@
drop table if exists t1;
SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=4, SQL_MAX_JOIN_SIZE=9;
-create table t1 (a int primary key, b char(20));
+create table t1 (a int auto_increment primary key, b char(20));
insert into t1 values(1,"test");
SELECT SQL_BUFFER_RESULT * from t1;
update t1 set b="a" where a=1;
@@ -12,21 +12,55 @@ delete from t1 where a=1;
insert into t1 values(1,"test"),(2,"test2");
SELECT SQL_BUFFER_RESULT * from t1;
update t1 set b="a" where a=1;
-select 1 from t1,t1 as t2,t1 as t3,t1 as t4;
+select 1 from t1,t1 as t2,t1 as t3;
# The following should give errors:
-!$1175 update t1 set b="a";
-!$1175 update t1 set b="a" where b="test";
-!$1175 delete from t1;
-!$1175 delete from t1 where b="test";
-!$1175 delete from t1 where a+0=1;
-!$1104 select 1 from t1,t1 as t2,t1 as t3,t1 as t4,t1 as t5;
+--error 1175
+update t1 set b="a";
+--error 1175
+update t1 set b="a" where b="test";
+--error 1175
+delete from t1;
+--error 1175
+delete from t1 where b="test";
+--error 1175
+delete from t1 where a+0=1;
+--error 1104
+select 1 from t1,t1 as t2,t1 as t3,t1 as t4,t1 as t5;
# The following should be ok:
update t1 set b="a" limit 1;
update t1 set b="a" where b="b" limit 2;
delete from t1 where b="test" limit 1;
delete from t1 where a+0=1 limit 2;
+
+# Test SQL_BIG_SELECTS
+
+alter table t1 add key b (b);
+SET MAX_JOIN_SIZE=2;
+SELECT @@MAX_JOIN_SIZE, @@SQL_BIG_SELECTS;
+insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a");
+--error 1104
+SELECT * from t1 order by a;
+SET SQL_BIG_SELECTS=1;
+SELECT * from t1 order by a;
+SET MAX_JOIN_SIZE=2;
+--error 1104
+SELECT * from t1;
+SET MAX_JOIN_SIZE=DEFAULT;
+SELECT * from t1;
+
+#
+# Test MAX_SEEKS_FOR_KEY
+#
+SELECT @@MAX_SEEKS_FOR_KEY;
+analyze table t1;
+insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a");
+explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
+set MAX_SEEKS_FOR_KEY=1;
+explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
+SET MAX_SEEKS_FOR_KEY=DEFAULT;
+
drop table t1;
SET SQL_SAFE_UPDATES=0,SQL_SELECT_LIMIT=DEFAULT, SQL_MAX_JOIN_SIZE=DEFAULT;
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index e9c7ffa6bb8..2cd2012d109 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -1,30 +1,17 @@
#
# Test of some show commands
#
-drop table if exists t1,t2;
-create table t1 (a int not null primary key, b int not null,c int not null, key(b,c));
-insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4);
-create table t2 type=isam select * from t1;
-optimize table t1;
-check table t1,t2;
-repair table t1,t2;
-check table t2,t1;
-lock tables t1 write;
-check table t2,t1;
-show columns from t1;
-show full columns from t1;
-show index from t1;
-drop table t1,t2;
+drop table if exists t1,t2;
create table t1 (a int not null primary key, b int not null,c int not null, key(b,c));
insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4);
-check table t1 type=fast;
-check table t1 type=fast;
-check table t1 type=changed;
+check table t1 fast;
+check table t1 fast;
+check table t1 changed;
insert into t1 values (5,5,5);
-check table t1 type=changed;
-check table t1 type=medium;
-check table t1 type=extended;
+check table t1 changed;
+check table t1 medium;
+check table t1 extended;
show index from t1;
!$1062 insert into t1 values (5,5,5);
optimize table t1;
@@ -74,10 +61,67 @@ create table t1 (a int not null, primary key (a));
show create table t1;
drop table t1;
+flush tables;
+show open tables;
+create table t1(n int);
+insert into t1 values (1);
+show open tables;
+drop table t1;
+
+create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" TYPE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed;
+show create table t1;
+alter table t1 MAX_ROWS=200 ROW_FORMAT=dynamic PACK_KEYS=0;
+show create table t1;
+ALTER TABLE t1 AVG_ROW_LENGTH=0 CHECKSUM=0 COMMENT="" MIN_ROWS=0 MAX_ROWS=0 PACK_KEYS=DEFAULT DELAY_KEY_WRITE=0 ROW_FORMAT=default;
+show create table t1;
+drop table t1;
+
create table t1 (a decimal(9,2), b decimal (9,0), e double(9,2), f double(5,0), h float(3,2), i float(3,0));
show columns from t1;
drop table t1;
+#
+# Do a create table that tries to cover all types and options
+#
+create table t1 (
+type_bool bool not null,
+type_tiny tinyint not null auto_increment primary key,
+type_short smallint(3),
+type_mediumint mediumint,
+type_bigint bigint,
+type_decimal decimal(5,2),
+type_numeric numeric(5,2),
+empty_char char(0),
+type_char char(2),
+type_varchar varchar(10),
+type_timestamp timestamp not null,
+type_date date not null,
+type_time time not null,
+type_datetime datetime not null,
+type_year year,
+type_enum enum ('red', 'green', 'blue'),
+type_set enum ('red', 'green', 'blue'),
+type_tinyblob tinyblob,
+type_blob blob,
+type_medium_blob mediumblob,
+type_long_blob longblob,
+index(type_short)
+) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" TYPE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed CHARSET=latin1;
+
+# Not tested above: RAID_# UNION INSERT_METHOD DATA DIRECTORY INDEX DIRECTORY
+show create table t1;
+insert into t1 (type_timestamp) values ("2003-02-07 10:00:01");
+select * from t1;
+drop table t1;
+
+#
+# Check metadata
+#
+create table t1 (a int not null);
+create table t2 select max(a) from t1;
+show columns from t2;
+drop table t1,t2;
+
# Check auto conversions of types
create table t1 (c decimal, d double, f float, r real);
diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test
index 70a7a3ab584..cffca437cf1 100644
--- a/mysql-test/t/status.test
+++ b/mysql-test/t/status.test
@@ -1,3 +1,11 @@
+# This test doesn't work with the embedded version as this code
+# assumes that one query is running while we are doing queries on
+# a second connection.
+# This would work if mysqltest run would be threaded and handle each
+# connection in a separate thread.
+#
+-- source include/not_embedded.inc
+
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
@@ -6,7 +14,7 @@ show status like 'Table_lock%';
connection con1;
SET SQL_LOG_BIN=0;
drop table if exists t1;
-create table t1(n int);
+create table t1(n int) type=myisam;
insert into t1 values(1);
connection con2;
lock tables t1 read;
diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test
new file mode 100644
index 00000000000..7a42a60054e
--- /dev/null
+++ b/mysql-test/t/symlink.test
@@ -0,0 +1,114 @@
+-- require r/have_symlink.require
+disable_query_log;
+show variables like "have_symlink";
+enable_query_log;
+
+drop table if exists t1,t2,t7,t8,t9;
+drop database if exists mysqltest;
+
+#
+# First create little data to play with
+#
+create table t1 (a int not null auto_increment, b char(16) not null, primary key (a));
+create table t2 (a int not null auto_increment, b char(16) not null, primary key (a));
+insert into t1 (b) values ("test"),("test1"),("test2"),("test3");
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (b) select b from t1;
+insert into t1 (b) select b from t2;
+drop table t2;
+
+#
+# Start the test
+# We use t9 here to not crash with tables generated by the backup test
+#
+
+disable_query_log;
+eval create table t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam data directory="$MYSQL_TEST_DIR/var/tmp" index directory="$MYSQL_TEST_DIR/var/run";
+enable_query_log;
+
+insert into t9 select * from t1;
+check table t9;
+optimize table t9;
+repair table t9;
+alter table t9 add column c int not null;
+--replace_result $MYSQL_TEST_DIR TEST_DIR
+show create table t9;
+
+# Test renames
+alter table t9 rename t8, add column d int not null;
+alter table t8 rename t7;
+rename table t7 to t9;
+# Drop old t1 table, keep t9
+drop table t1;
+
+#
+# Test error handling
+# Note that we are using the above table t9 here!
+#
+
+disable_query_log;
+--error 1103,1103
+create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam data directory="tmp";
+
+# Check that we cannot link over a table from another database.
+
+create database mysqltest;
+
+--error 1,1
+create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="/this-dir-does-not-exist";
+
+--error 1103,1103
+create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="not-hard-path";
+
+--error 1,1
+eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="$MYSQL_TEST_DIR/var/run";
+
+--error 1,1
+eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam data directory="$MYSQL_TEST_DIR/var/tmp";
+enable_query_log;
+
+# Check moving table t9 from default database to mysqltest;
+# In this case the symlinks should be removed.
+
+alter table t9 rename mysqltest.t9;
+select count(*) from mysqltest.t9;
+--replace_result $MYSQL_TEST_DIR TEST_DIR
+show create table mysqltest.t9;
+drop database mysqltest;
+
+#
+# Test changing data dir (Bug #1662)
+#
+
+create table t1 (a int not null) type=myisam;
+disable_query_log;
+eval alter table t1 data directory="$MYSQL_TEST_DIR/var/tmp";
+enable_query_log;
+--replace_result $MYSQL_TEST_DIR TEST_DIR
+show create table t1;
+alter table t1 add b int;
+disable_query_log;
+eval alter table t1 data directory="$MYSQL_TEST_DIR/var/log";
+enable_query_log;
+--replace_result $MYSQL_TEST_DIR TEST_DIR
+show create table t1;
+disable_query_log;
+eval alter table t1 index directory="$MYSQL_TEST_DIR/var/log";
+enable_query_log;
+show create table t1;
+drop table t1;
diff --git a/mysql-test/t/tablelock.test b/mysql-test/t/tablelock.test
index c32a3f7cd35..fa8c4f03675 100644
--- a/mysql-test/t/tablelock.test
+++ b/mysql-test/t/tablelock.test
@@ -2,6 +2,7 @@
# Test of lock tables
#
+drop table if exists t1,t2;
create table t1 ( n int auto_increment primary key);
lock tables t1 write;
insert into t1 values(NULL);
@@ -36,12 +37,10 @@ drop table t1;
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int);
lock tables t1 write,t1 as b write, t2 write, t2 as c read;
-drop table t1;
-drop table t2;
+drop table t1,t2;
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int);
lock tables t1 write,t1 as b write, t2 write, t2 as c read;
-drop table t2;
-drop table t1;
+drop table t2,t1;
unlock tables;
diff --git a/mysql-test/t/temp_table.test b/mysql-test/t/temp_table.test
index 0eba893fe60..665e690a322 100644
--- a/mysql-test/t/temp_table.test
+++ b/mysql-test/t/temp_table.test
@@ -60,8 +60,30 @@ insert into t2 values (1,1),(2,1),(3,1),(4,2);
# do a query using ELT, a join and an ORDER BY.
select one.id, two.val, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id;
drop table t1,t2;
+
+#
+# Test of failed ALTER TABLE on temporary table
+#
create temporary table t1 (a int not null);
insert into t1 values (1),(1);
-- error 1062
alter table t1 add primary key (a);
drop table t1;
+
+#
+# In MySQL 4.0.4 doing a GROUP BY on a NULL column created a disk based
+# temporary table when a memory based one would be good enough.
+
+drop table if exists t1;
+
+CREATE TABLE t1 (
+ d datetime default NULL
+) TYPE=MyISAM;
+
+
+INSERT INTO t1 VALUES ('2002-10-24 14:50:32'),('2002-10-24 14:50:33'),('2002-10-24 14:50:34'),('2002-10-24 14:50:34'),('2002-10-24 14:50:34'),('2002-10-24 14:50:35'),('2002-10-24 14:50:35'),('2002-10-24 14:50:35'),('2002-10-24 14:50:35'),('2002-10-24 14:50:36'),('2002-10-24 14:50:36'),('2002-10-24 14:50:36'),('2002-10-24 14:50:36'),('2002-10-24 14:50:37'),('2002-10-24 14:50:37'),('2002-10-24 14:50:37'),('2002-10-24 14:50:37'),('2002-10-24 14:50:38'),('2002-10-24 14:50:38'),('2002-10-24 14:50:38'),('2002-10-24 14:50:39'),('2002-10-24 14:50:39'),('2002-10-24 14:50:39'),('2002-10-24 14:50:39'),('2002-10-24 14:50:40'),('2002-10-24 14:50:40'),('2002-10-24 14:50:40');
+
+flush status;
+select * from t1 group by d;
+show status like "created_tmp%tables";
+drop table t1;
diff --git a/mysql-test/t/timezone-master.opt b/mysql-test/t/timezone-master.opt
new file mode 100644
index 00000000000..0477f941e9d
--- /dev/null
+++ b/mysql-test/t/timezone-master.opt
@@ -0,0 +1 @@
+--timezone=MET
diff --git a/mysql-test/t/timezone.test b/mysql-test/t/timezone.test
new file mode 100644
index 00000000000..ba65eb72fe6
--- /dev/null
+++ b/mysql-test/t/timezone.test
@@ -0,0 +1,47 @@
+#
+# Test of timezone handling. This script must be run with TZ=MET
+
+-- require r/have_met_timezone.require
+disable_query_log;
+select FROM_UNIXTIME(24*3600);
+enable_query_log;
+
+# Initialization
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+show variables like "timezone";
+
+#
+# Test unix timestamp
+#
+select @a:=FROM_UNIXTIME(1);
+select unix_timestamp(@a);
+
+#
+# Test of some values, including some with daylight saving time
+#
+
+CREATE TABLE t1 (ts int);
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 03:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 02:59:59'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 03:00:00'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 03:59:59'));
+INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 04:00:01'));
+
+SELECT ts,from_unixtime(ts) FROM t1;
+DROP TABLE t1;
+
+#
+# Test for fix for Bug#2523
+#
+select unix_timestamp('1970-01-01 01:00:00'),
+ unix_timestamp('1970-01-01 01:00:01'),
+ unix_timestamp('2038-01-01 00:59:59'),
+ unix_timestamp('2038-01-01 01:00:00');
diff --git a/mysql-test/t/truncate.test b/mysql-test/t/truncate.test
index e995517cf1e..3acab9f56de 100644
--- a/mysql-test/t/truncate.test
+++ b/mysql-test/t/truncate.test
@@ -1,11 +1,35 @@
#
# Test of truncate
#
+drop table if exists t1;
create table t1 (a integer, b integer,c1 CHAR(10));
+insert into t1 (a) values (1),(2);
truncate table t1;
select count(*) from t1;
insert into t1 values(1,2,"test");
select count(*) from t1;
+delete from t1;
+select * from t1;
drop table t1;
# The following should fail
-!$1146 select count(*) from t1;
+--error 1146
+select count(*) from t1;
+create temporary table t1 (n int);
+insert into t1 values (1),(2),(3);
+truncate table t1;
+select * from t1;
+drop table t1;
+--error 1146
+truncate non_existing_table;
+
+#
+# test autoincrement with TRUNCATE
+#
+
+create table t1 (a integer auto_increment primary key);
+insert into t1 (a) values (NULL),(NULL);
+truncate table t1;
+insert into t1 (a) values (NULL),(NULL);
+SELECT * from t1;
+drop table t1;
+
diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test
index 2b23617ec8b..928f79a661e 100644
--- a/mysql-test/t/type_blob.test
+++ b/mysql-test/t/type_blob.test
@@ -1,3 +1,7 @@
+# This test can't be run with running server (--extern) as this uses
+# load_file() on a file in the tree.
+#
+
#
# test of full join with blob
#
@@ -92,7 +96,7 @@ drop table t1;
#
CREATE TABLE t1 (
- t1_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+ t1_id bigint(21) NOT NULL auto_increment,
_field_72 varchar(128) DEFAULT '' NOT NULL,
_field_95 varchar(32),
_field_115 tinyint(4) DEFAULT '0' NOT NULL,
@@ -123,7 +127,7 @@ INSERT INTO t2 VALUES (2,1);
INSERT INTO t2 VALUES (2,2);
CREATE TABLE t3 (
- t3_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+ t3_id bigint(21) NOT NULL auto_increment,
_field_131 varchar(128),
_field_133 tinyint(4) DEFAULT '0' NOT NULL,
_field_135 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
@@ -158,7 +162,7 @@ INSERT INTO t4 VALUES (1,1);
INSERT INTO t4 VALUES (2,1);
CREATE TABLE t5 (
- t5_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+ t5_id bigint(21) NOT NULL auto_increment,
_field_149 tinyint(4),
_field_156 varchar(128) DEFAULT '' NOT NULL,
_field_157 varchar(128) DEFAULT '' NOT NULL,
@@ -190,7 +194,7 @@ INSERT INTO t6 VALUES (1,2);
INSERT INTO t6 VALUES (2,2);
CREATE TABLE t7 (
- t7_id bigint(21) DEFAULT '0' NOT NULL auto_increment,
+ t7_id bigint(21) NOT NULL auto_increment,
_field_143 tinyint(4),
_field_165 varchar(32),
_field_166 smallint(6) DEFAULT '0' NOT NULL,
@@ -249,3 +253,68 @@ insert into t1 values ('fish', 10),('bear', 20);
select foobar, boggle from t1 where foobar = 'fish';
select foobar, boggle from t1 where foobar = 'fish' and boggle = 10;
drop table t1;
+
+#
+# Bug when blob is updated
+#
+
+create table t1 (id integer auto_increment unique,imagem LONGBLOB not null);
+insert into t1 (id) values (1);
+update t1 set imagem=load_file('../../std_data/words.dat') where id=1;
+select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1;
+drop table t1;
+
+#
+# Test blob's with end space (Bug #1651)
+#
+
+create table t1 (id integer primary key auto_increment, txt text not null, unique index txt_index (txt (20)));
+insert into t1 (txt) values ('Chevy'), ('Chevy ');
+select * from t1 where txt='Chevy';
+select * from t1 where txt='Chevy ';
+select * from t1 where txt='Chevy ' or txt='Chevy';
+select * from t1 where txt='Chevy' or txt='Chevy ';
+select * from t1 where id='1' or id='2';
+insert into t1 (txt) values('Ford');
+select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
+select * from t1 where txt='Chevy' or txt='Chevy ';
+select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
+select * from t1 where txt in ('Chevy ','Chevy');
+select * from t1 where txt in ('Chevy');
+select * from t1 where txt between 'Chevy' and 'Chevy';
+select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
+select * from t1 where txt between 'Chevy' and 'Chevy ';
+select * from t1 where txt < 'Chevy ';
+select * from t1 where txt <= 'Chevy';
+select * from t1 where txt > 'Chevy';
+select * from t1 where txt >= 'Chevy';
+drop table t1;
+
+create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20)));
+insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL);
+select * from t1 where txt='Chevy' or txt is NULL;
+select * from t1 where txt='Chevy ';
+select * from t1 where txt='Chevy ' or txt='Chevy';
+select * from t1 where txt='Chevy' or txt='Chevy ';
+select * from t1 where id='1' or id='2';
+insert into t1 (txt) values('Ford');
+select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford';
+select * from t1 where txt='Chevy' or txt='Chevy ';
+select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy';
+select * from t1 where txt in ('Chevy ','Chevy');
+select * from t1 where txt in ('Chevy');
+select * from t1 where txt between 'Chevy' and 'Chevy';
+select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy ';
+select * from t1 where txt between 'Chevy' and 'Chevy ';
+select * from t1 where txt < 'Chevy ';
+select * from t1 where txt < 'Chevy ' or txt is NULL;
+select * from t1 where txt <= 'Chevy';
+select * from t1 where txt > 'Chevy';
+select * from t1 where txt >= 'Chevy';
+drop table t1;
+CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1)));
+INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
+select max(i) from t1 where c = '';
+drop table t1;
+
+
diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test
index 68c2d55aac9..bd6d8c49c22 100644
--- a/mysql-test/t/type_date.test
+++ b/mysql-test/t/type_date.test
@@ -34,6 +34,7 @@ INSERT INTO t1 VALUES ( "2000-1-3" );
INSERT INTO t1 VALUES ( "2000-1-4" );
INSERT INTO t1 VALUES ( "2000-1-5" );
SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4";
+SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY;
DROP TABLE t1;
#
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index eed3f831383..850e5238111 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -4,12 +4,13 @@
drop table if exists t1;
create table t1 (t datetime);
-insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959);
+insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959),(20030102030460),(20030102036301),(20030102240401),(20030132030401),(20031302030460);
select * from t1;
delete from t1 where t > 0;
optimize table t1;
check table t1;
-insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959");
+delete from t1;
+insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030102030460"),("20030102036301"),("20030102240401"),("20030132030401"),("20031302030460");
select * from t1;
drop table t1;
@@ -32,6 +33,18 @@ select * from t1 where a is null;
drop table t1;
#
+# Test with bug when propagating DATETIME to integer and WHERE optimization
+#
+
+create table t1 (id int, dt datetime);
+insert into t1 values (1,"2001-08-14 00:00:00"),(2,"2001-08-15 00:00:00"),(3,"2001-08-16 00:00:00"),(4,"2003-09-15 01:20:30");
+select * from t1 where dt='2001-08-14 00:00:00' and dt = if(id=1,'2001-08-14 00:00:00','1999-08-15');
+create index dt on t1 (dt);
+select * from t1 where dt > 20021020;
+select * from t1 ignore index (dt) where dt > 20021020;
+drop table t1;
+
+#
# Test of datetime optimization
#
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index 7d4dcf3403e..82e53e7bde6 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -2,7 +2,7 @@
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
- id int(11) DEFAULT '0' NOT NULL auto_increment,
+ id int(11) NOT NULL auto_increment,
datatype_id int(11) DEFAULT '0' NOT NULL,
minvalue decimal(20,10) DEFAULT '0.0000000000' NOT NULL,
maxvalue decimal(20,10) DEFAULT '0.0000000000' NOT NULL,
@@ -160,6 +160,8 @@ insert into t1 values ("-.1"),("+.1"),(".1");
insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
select * from t1;
drop table t1;
@@ -169,6 +171,8 @@ insert into t1 values ("-.1"),("+.1"),(".1");
insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
select * from t1;
drop table t1;
@@ -178,16 +182,21 @@ insert into t1 values ("-.1"),("+.1"),(".1");
insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
+insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000");
+insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0");
select * from t1;
drop table t1;
create table t1 (a decimal(10,2));
+# The -0.0 needs to be quoted as not all platforms supports this
insert into t1 values (0.0),("-0.0"),(+0.0),(01.0),(+01.0),(-01.0);
insert into t1 values (-.1),(+.1),(.1);
insert into t1 values (00000000000001),(+0000000000001),(-0000000000001);
insert into t1 values (+111111111.11),(111111111.11),(-11111111.11);
insert into t1 values (-111111111.11),(+1111111111.11),(1111111111.11);
+insert into t1 values (1e+100),(1e-100),(-1e+100);
+insert into t1 values (123.4e0),(123.4e+2),(123.4e-2),(123e1),(123e+0);
select * from t1;
drop table t1;
@@ -211,3 +220,40 @@ create table t1 (a decimal unsigned zerofill);
insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999);
select * from t1;
drop table t1;
+
+# Exponent overflow bug
+create table t1(a decimal(10,0));
+insert into t1 values ("1e4294967295");
+select * from t1;
+delete from t1;
+insert into t1 values("1e4294967297");
+select * from t1;
+drop table t1;
+
+#
+# Test of wrong decimal type
+#
+
+--error 1074
+CREATE TABLE t1 (a_dec DECIMAL(-1,0));
+--error 1074
+CREATE TABLE t1 (a_dec DECIMAL(-2,1));
+--error 1074
+CREATE TABLE t1 (a_dec DECIMAL(-1,1));
+
+#
+# Zero prepend overflow bug
+#
+
+create table t1(a decimal(7,3));
+insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000');
+select * from t1;
+drop table t1;
+create table t1(a decimal(7,3) unsigned);
+insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000');
+select * from t1;
+drop table t1;
+create table t1(a decimal(7,3) zerofill);
+insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000');
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test
index 6e90ae437f8..78b850b6ea6 100644
--- a/mysql-test/t/type_enum.test
+++ b/mysql-test/t/type_enum.test
@@ -2,6 +2,7 @@
# Problem with many enums
#
+DROP TABLE if exists t1;
CREATE TABLE t1 (
field enum('001001','001004','001010','001018','001019','001020','001021','001027','001028','001029','001030','001031','001100','002003','002004','002005','002007','002008','002009','002012','002013','002014','003002','003003','003004','003005','003006','003007','003008','003009','003010','003011','003012','003013','003014','003015','003016','003017','003018','003019','004002','004003','004005','004006','004007','004008','004010','004012','004014','004016','004017','004020','004021','004022','004023','004024','004025','004026','006002','006004','006006','006010','006011','006012','006013','006014','007001','007002','007003','007004','007005','007006','007007','007008','007009','007010','007011','007012','007013','007014','007015','007016','007017','007018','007019','007020','007021','007022','007023','007024','007025','007026','007027','007028','007029','007030','007031','007032','007033','007034','007035','007036','007037','007038','007039','007040','007043','007044','009001','009002','009004','009005','009006','009007','009008','009009','009010','009011','009012','009013','010002','010003','010004','010005','010006','010007','010008','010009','010010','010011','010012','010013','010015','010016','010017','010018','010019','010020','010021','010022','010023','010024','010025','010026','010027','010028','011001','011002','011003','011004','011006','011012','011013','011014','011015','011016','012017','012018','012019','012023','012027','012028','012029','012030','012031','012032','012033','012034','012035','012036','012037','012038','012039','014001','016002','016003','016004','016007','016010','016011','016016','016019','016020','016021','016022','016023','016024','016026','016027','016028','016029','016030','016031','016032','016033','016034','017002','018001','019002','019004','020001','020003','020004','020005','020006','020007','020008','020009','022001','022002','022003','023001','023002','023003','023004','023005','023006','023007','023008','023010','023011','023012','023017','023019','023020','023021','023025','023026','023027','023028','023029','023030','023031','023032','023033','023034','023035','025001','025003','025004','025005','025006','025007','025008','025009','025010','025011','025012','025013','025014','025015','025016','025017','025018','025019','025020','025021','025022','025023','025024','025025','025026','025027','025028','025029','025030','025031','025032','025033','025034','025035','025036','025037','025038','025039','025040','025041','025042','025043','025044','025045','025046','025047','025048','025049','025050','025051','025052','025053','025054','025055','025056','025057','025058','025059','025060','025061','025062','025063','027001','027002','027011','035008','035012','036001','037001','037003','037004','037005','037006','037007','037008','037009','038004','038005','038006','038007','038009','039001','039002','039003','039004','039005','039006','046001','046002','046003','046004','046005','046007','046008','046009','046010','046011','046012','046013','046014','047001','047002','048001','051001','051002','051003','051004','052001','052002','052005','053015','053016','053019','053020','053023','053024','053026','053028','053029','053033','053034','053036','053037','053038','053039','053041','053042','053043','053045','053046','053047','053048','053051','053052','053054','053055','053056','053057','053068','053069','053070','053073','053074','053075','053086','053094','053095','053096','053097','053098','053099','053100','053101','053102','053103','053104','053105','053107','053122','053123','053124','053125','053127','053128','054001','054002','054003','054004','054005','054006','054007','054009','054010','056001','056002','056003','056004','056005','056006','056009','056010','056011','056016','056017','056018','056019','056020','056021','056022','057001','057002','057003','057004','058002','058003','058004','058005','060001','060003','060004','060005','060006','060007','061002','061003','061004','061005','061006','069006','069007','069010','069011','069012','069013','069014','069015','069016','069017','069018','069020','069021','069022','069023','069024','071002','071003','071004','071005','071006','071008','071011','071013','071020','071021','071022','072001','073001','073002','073003','073004','074001','074002','074003','074004','074005','074006','074007','074008','074009','074010','074011','074012','075001','075007','076101','076102','076103','077001','077002','077003','077004','077006','077007','077008','077009','078005','079002','079003','079004','079005','079006','079007','081001','082006','082007','082011','082013','082014','082015','082016','082017','082021','082022','082023','082024','082025','082026','082027','082028','082029','082030','082031','082032','082033','082034','082035','082036','082037','082038','082039','082040','082041','082042','082043','082044','084001','084002','084003','084004','084005','084007','084008','084009','084011','084013','084014','084016','084017','084027','084031','084032','084033','084035','084036','084037','084038','084039','084040','084041','084042','084043','084044','084045','084046','084047','084048','084049','084050','084051','085001','085002','085003','085004','085005','085006','085007','085009','085011','085012','085013','085014','085015','085016','085017','085018','085019','085020','085021','085022','085023','085028','085029','085030','085031','085033','085034','085035','085036','085037','085038','085040','085041','085042','085043','085044','085045','085046','085047','085048','085063','085064','085065','085068','085070','085071','085073','085082','085083','085086','085088','085089','085090','085091','085092','085093','085094','085095','085096','085097','085098','085099','085100','085101','085102','085103','085104','085105','085106','085107','085108','085109','085110','085111','085112','085113','085115','085119','085120','085121','085122','085123','085124','085125','085126','085127','085128','085129','085130','085132','085133','085134','085135','085136','085137','086001','086002','086003','086004','086005','088001','088003','088005','088006','088007','088008','088009','089001','090001','090002','090003','090004','090005','090006','090007','090008','090009','090010','090013','090015','090016','090017','090018','090019','090022','090027','090028','091001','091002','091005','091008','091009','091010','091011','091012','091013','091014','091015','091016','091017','091018','093001','093003','093098','093100','093102','093104','093141','093142','093146','093151','093153','093167','093168','093176','094001','094002','094004','094005','095004','099001','099002','100001','101001','102002','102003','105001','105002','106001','113001','113002','113003','113004','113005','113006','113007','113008','113009','113010','113011','113012','113013','113014','113015','113016','113017','113018','113019','113020','113021','113022','113023','113024','113025','113026','113027','113028','114001','115001','115002','115003','115004','115005','115006','115007','115008','115009','115010','115011','115012','115013','115014','115015','115016','115017','115018','115020','115021','115022','115023','115025','115026','115027','115028','115029','115030','115031','115032','115033','115034','115035','115036','115039','115040','115041','115042','115043','115044','115045','115046','115047','115048','115049','115050','115051','115052','115053','115054','115055','115056','115057','115059','115060','115061','115062','115063','115064','115065','115066','115067','115068','115069','115070','115071','115072','115073','115075','115076','115081','115082','115085','115086','115087','115088','115095','115096','115097','115098','115099','115101','115102','115103','115104','115105','115106','115108','115109','115110','115111','115112','115113','115114','115115','115116','115117','115118','115119','115120','115121','115122','116001','116002','116003','116004','116005','116006','116007','116008','116009','116010','116011','116012','117001','117002','117003','123001','124010','124014','124015','124019','124024','124025','124026','124027','124028','124029','124030','124031','124032','124033','124035','124036','124037','124038','124039','124040','124041','124042','124043','124044','124045','124046','124047','124048','124049','124050','124051','124052','124053','124054','124055','124056','124057','124058','124059','124060','124061','124062','124063','124064','124065','126001','126002','126003','126004','126005','126006','126007','126008','126009','126010','126011','126012','130001','132001','132002','132003','133001','133008','133009','133010','133011','133012','133013','133014','133015','133016','133017','133018','133019','133020','133021','133022','133023','133024','133025','133027','133028','133029','133030','133031','134001','135001','135002','135003','135004','135005','135006','135007','135008','135009','135010','136001','137009','137010','137011','137012','137013','137014','137015','137016','137017','137018','137019','138001','138002','138003','138004','139001','139003','140001','141001','141002','141003','141006','141007','141008','141009','141011','141012','141014','141015','141016','141017','141018','141019','141020','141021','141022','141023','141024','141025','141026','141027','141028','142001','142002','142003','142004','142005','142006','142007','142008','142010','142011','142012','144001','145001','145002','145003','145004','145005','145006','145007','145008','145009','145010','145011','145012','145013','145014','145015','145016','147001','150003','150005','150009','150013','150014','150015','150016','150017','150020','150021','152001','152002','152003','152004','152005','152006','152007','154001','154002','154003','155001','155002','155003','155004','155005','155006','159001','159002','159003','159004','160001','160002','160003','161001','162001','162002','162003','162004','162007','162010','162011','162012','163001','163002','163003','163005','163010','163011','163014','163015','163016','165001','165002','165003','165004','165005','165006','165007','165008','165009','165010','165011','165012','165013','165014','165015','165016','165017','165018','165019','165020','165021','165022','165023','165024','165025','165026','165027','165028','165029','165030','165031','165032','165033','165034','165035','165036','167001','168001','168002','168003','168004','168005','168007','168008','168009','168010','168011','168012','168013','168014','169001','169002','169003','169007','169008','169009','169010','170001','171001','171002','171003','171004','171005','171006','171007','171008','171009','172001','174001','174002','174003','176001','176002','176003','177001','177002','179001','179002','179003','179004','179005','179006','179007','179008','179009','179010','179011','179012','179013','179014','179015','179016','179017','179018','179019','179020','179021','179022','179023','179024','179025','179026','179027','179028','179029','179030','179031','179032','179033','179034','179035','179036','179037','179038','179039','179040','179041','179042','179043','179044','179045','179046','179047','180001','180010','180012','180013','180014','180015','180016','180017','180018','180019','180020','180021','180022','180023','180024','180025','180026','180027','180028','180030','180031','180032','180033','180034','180035','180036','180037','180038','180039','180041','180042','180043','180044','180045','180046','180047','180048','180049','180050','180051','180052','180053','180054','180055','180056','180057','180058','180059','180060','180061','180062','180063','180064','180065','180066','180067','180068','180069','180070','180071','182001','184001','184002','184005','184006','184007','184008','184009','184010','184011','185001','185003','187001','188001','188002','188003','188004','188005','188006','188007','188008','188009','188010','188011','191001','191002','192002','194001','194002','194003','194004','194005','194006','194007','195001','195002','195003','195004','195005','195006','195007','196001','196002','197001','197002','197003','197004','197005','197006','198001','198003','198004','198005','198006','198007','198008','198009','198010','198011','198012','198013','198014','198015','198016','198017','201001','201002','201005','202001','203001','203002','203003','203017','203018','203019','204001','204002','204003','205001','208001','208002','208003','208004','208005','209001','209002','209003','210001','210002','210003','210004','210005','210006','210007','210008','210009','210010','210011','210012','210013','211017','212001','212002','212003','212004','212005','212006','212007','212008','212009','212010','212011','212012','212013','218001','218003','218004','218006','218007','218008','218009','218011','218015','218016','218017','218018','218019','218020','218021','218022','218023','218024','218025','218026','218027','218028','218029','218030','218031','218032','218033','218034','218035','218036','221001','221002','221003','221004','221005','221006','221007','221008','221009','221010','221011','221012','221013','223001','223002','223003','224001','224002','224003','224006','224007','224008','225001','225002','225003','225004','225005','225006','225007','225008','225009','225010','225011','225012','225013','226001','226002','226003','226004','226005','226006','226007','226008','226009','227001','227002','227003','227004','227005','227006','227007','227008','227009','227010','227011','227012','227013','227014','227015','227016','227017','227018','227019','227020','227021','227022','227023','227024','227025','227026','227027','227028','227029','227030','227031','227032','227033','227034','227035','227036','227037','227038','227039','227040','227041','227042','227043','227044','227045','227046','227047','227048','227049','227050','227051','227052','227053','227054','227055','227056','227057','227058','227059','227060','227061','227062','227063','227064','227065','227066','227067','227068','227069','227070','227071','227072','227073','227074','227075','227076','227077','227078','227079','227080','227081','227082','227083','227084','227085','227086','227087','227088','227089','227090','227091','227092','227093','227094','227095','227096','227097','227098','227099','227100','227101','227102','227103','227104','227105','227106','227107','227108','227109','227110','227111','227112','227113','227114','227115','227116','227117','227118','227119','227120','227122','227123','227124','227125','227126','227127','227128','227129','227130','227131','227132','227133','227134','227135','227136','227137','227138','227139','227140','227141','227142','227143','227144','227145','227146','227147','227148','227149','227150','227151','227152','228001','229001','229002','229003','229004','229005','230001','230002','232001','233001','233002','233003','233004','233005','233006','233007','233008','234001','234002','234003','234004','234005','234006','234007','234008','234009','234010','234011','234012','234013','234014','234015','234016','234017','234018','234019','234020','234021','234022','234023','234024','234025','234026','234027','234028','234029','234030','235001','235002','235003','235004','235005','236001','236002','236003','237001','238002','238003','238004','238005','238006','238007','238008','333013','333014','333015','333016','333017','333018','333019','333020','333021','333022','333023','333024','333025','333030','333031','333032','333033','333034','333035','334001','334002','334003','334004','334005','334006','334007','336004','337001','337002','337003','337004','339001','339002','343001','344001','344002','344003','344004','344005','345001','345002','345003','347001','347002','348001','348002','348003','348004','348005','349001','349002','349003','350001','353001','353002','353003','353004','355001','355002','355003','355004','355005','355006','356001','358001','359001','359002','360001','360002','360003','360004','360005','366001','366002','366003','366004','369001','373001','373002','373003','373004','373005','373006','373007','373008','373009','373010','373011','373012','373013','373014','373015','373016','373017','373018','373019','373020','373021','374001','374002','374003','374004','374005','374006','374007','374008','374009','374010','374011','374012','374013','374014','374015','374016','376001','376002','376003','376004','376005','376006','376007','376008','376009','376010','376011','376012','376013','376016','376017','376018','376019','376020','376021','379003','382001','382002','383001','384001','384002','385001','385002','386001','386002','386003','386004','386005','386006','386007','386008','386009','386010','386011','386012','386013','386014','387001','389001','389002','389003','389004','392001','393001','393002','393003','393004','395001','396001','397001','397002','399001','399002','399003','400001','400002','401001','401002','401003','402001','402002','402003','402004','402005','403001','403002','403003','504001','504002','504004','504005','504006','504007','504008','504009','504010','504011','504012','504013','504014','504017','504018','504019','504021','504022','504023','504024','504025','506001','506002','508001','508002','511001','511002','511003','511004','511005','511006','511007','511008','511009','511010','511011','511012','511013','511014','511017','511018','511020','511021','511022','511024','511028','511029','513001','513002','513003','513004','514001','515001','515002','515003','515007','515008','515009','515010','515011','515012','515013','515014','515015','518001','518002','518003','520001','520002','521001','521002','521003','521004','521005','521006','521007','521008','521009','521010','521011','521012','521013','521014','521015','521016','523001','523002','523003','523004','523005','523006','523007','524001','700001','701001','701002','701003','702001','702002','702003','702004','702005','702006','702007','702008','703001','703002','703003','704001','704002','704003','704004','705001','706001','706002','707001','707002','707003','708001','709001','709002','710001','710002','711001','711002','712001','713001','713002','714001','714002','715001','716001','718001','718002','719001','719002','991001','991002','991003','991004','991005','991006','991007','991008','992001','995001','996001','996002','996003','998001','998002','998003','998004','998005','998006','998007','999001','999002','011017','011018','034001','034002','071010','208006','239001','519001','519003','126013','184012','053071','374017','374018','374019','374020','374021','404001','405002','405001','405003','405007','405006','405005','405004','240011','240010','240009','240008','240007','240006','240005','240004','240003','240002','240001','240012','240013','240014','240015','240016','240017','357001','235006','235007','712002','355008','355007','056023','999999','046015','019005','126014','241003','241002','241001','240018','240020','240019','242001','242002','242003','242004','242005','242006','089002','406001','406002','406003','406004','406005','406006','243001','243002','243003','243004','243005','243006','243007','243008','010030','010029','407001','407006','407005','407004','407003','407002','408001','366005','133032','016035','077010','996004','025064','011019','407007','407008','407009','409001','115123','504026','039007','039009','039008','039010','039011','039012','180072','240021','240023','408002','405008','235008','525001','525002','525003','525004','410001','410002','410003','410004','410005','410006','410007','410008','410009','410010','410011','410012','410013','410014','410015','410016','344006','240031','240030','240029','240028','240027','240026','240025','240024','240034','240033','240032','410017','410018','411001','411002','411003','411004','411005','411006','411007','411008','203020','203021','203022','412001','412002','412003','412004','069025','244001','244002','244009','244008','244007','244006','244005','244004','244003','244015','244014','244013','244012','244011','244010','244016','244017','240042','240041','240040','240039','240038','240037','240036','240035','405009','405010','240043','504034','504033','504032','504031','504030','504029','504028','504027','504042','504041','504040','504039','504038','504037','504036','504035','800001','410019','410020','410021','244018','244019','244020','399004','413001','504043','198018','198019','344007','082045','010031','010032','010033','010034','010035','504044','515016','801002','801003','801004','801005','802001','801001','414001','414002','414003','141029','141030','803001','803002','803003','803004','803005','803006','803007','803008','803009','803010','803011','803012','803013','803014','803015','803016','803017','410022','410023','803018','803019','803020','415002','415001','244021','011020','011023','011022','011021','025065','165037','165038','165039','416001','416002','416003','417001','418001','504045','803022','803021','240022','419001','420001','804010','804009','804008','804007','804006','804005','804004','804003','804002','804001','804020','804019','804018','804017','804016','804015','804014','804013','804012','804011','804024','804021','804023','804022','511019','511016','511015','511032','511031','511030','511027','511026','511025','511033','511023','133034','133033','169011','344008','344009','244022','244026','244025','244030','244023','244024','244027','244028','244029','244031','082046','082047','082048','126015','126016','416004','416005','421001','421002','016037','016036','115124','115125','115126','240049','240048','240047','240046','240045','240044','244032','244033','422001','422002','422003','422004','422005','184013','239002','805001','805002','805003','805004','805005','056024','423001','344010','235009','212014','056025','056026','802002','244034','244035','244036','244037','244038','244039','515017','504046','203015','245002','245001','071023','056027','056028','056029','056030','056031','056032','424001','056034','056033','805006','805007','805008','805009','805010','422008','422007','422006','422010','422009','422011','209004','150022','150023','100002','056035','023036','185004','185005','246001','247001','247002','425001','416006','165042','165041','165040','165043','010040','010039','010038','010037','010036','422012','422013','422014','422015','426000','248001','248002','248003','248004','248005','249001','249002','249003','249004','249005','249006','250007','250001','250002','250003','250004','250005','250006','250008','250009','250010','250011','250012','250013','251001','251002','422016','422017','422018','806001','806002','116013','235010','235011','091026','091027','091028','091029','091019','091020','091021','091022','091023','091024','091025','252001','243009','249007','249008','249009','011024','011025','427001','428002','428001','169012','429001','429002','429003') DEFAULT '001001' NOT NULL,
KEY field (field)
@@ -20,3 +21,14 @@ drop table t1;
create table t1 (a enum (' ','a','b ') not null default 'b ');
show create table t1;
drop table t1;
+
+#
+# Tests of wrong enum values (bug #2023)
+#
+
+create table t1 (a enum ('0','1'));
+insert into t1 set a='foobar';
+select * from t1;
+update t1 set a = replace(a,'x','y');
+select * from t1;
+drop table t1; \ No newline at end of file
diff --git a/mysql-test/t/type_ranges.test b/mysql-test/t/type_ranges.test
index a07a1d97f37..63bbe43512d 100644
--- a/mysql-test/t/type_ranges.test
+++ b/mysql-test/t/type_ranges.test
@@ -5,7 +5,7 @@
drop table if exists t1,t2,t3;
CREATE TABLE t1 (
- auto int(5) unsigned DEFAULT 0 NOT NULL auto_increment,
+ auto int(5) unsigned NOT NULL auto_increment,
string char(10) default "hello",
tiny tinyint(4) DEFAULT '0' NOT NULL ,
short smallint(6) DEFAULT '1' NOT NULL ,
@@ -91,7 +91,7 @@ select auto,new_field,new_blob_col,date_field from t1 ;
# check with old syntax
#
CREATE TABLE t2 (
- auto int(5) unsigned NOT NULL DEFAULT 0 auto_increment,
+ auto int(5) unsigned NOT NULL auto_increment,
string char(20),
mediumblob_col mediumblob not null,
new_field char(2),
diff --git a/mysql-test/t/type_set.test b/mysql-test/t/type_set.test
index 39bcbcbf75d..7f1a75e5dbd 100644
--- a/mysql-test/t/type_set.test
+++ b/mysql-test/t/type_set.test
@@ -2,6 +2,7 @@
# Test of SET with space
#
+drop table if exists t1;
create table t1 (a set (' ','a','b') not null);
show create table t1;
drop table t1;
diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test
index fde93576510..2496ec36915 100644
--- a/mysql-test/t/type_time.test
+++ b/mysql-test/t/type_time.test
@@ -1,6 +1,7 @@
#
# testing of the TIME column type
#
+drop table if exists t1;
create table t1 (t time);
insert into t1 values("10:22:33"),("12:34:56.78"),(10),(1234),(123456.78),(1234559.99),("1"),("1:23"),("1:23:45"), ("10.22"), ("-10 1:22:33.45"),("20 10:22:33"),("1999-02-03 20:33:34");
insert t1 values (30),(1230),("1230"),("12:30"),("12:30:35"),("1 12:30:31.32");
diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test
index a6169c03d3d..3483227376e 100644
--- a/mysql-test/t/type_timestamp.test
+++ b/mysql-test/t/type_timestamp.test
@@ -2,13 +2,25 @@
# Test timestamp
#
-CREATE TABLE t1 ( t timestamp);
+drop table if exists t1,t2;
+CREATE TABLE t1 (a int, t timestamp);
+CREATE TABLE t2 (a int, t datetime);
SET TIMESTAMP=1234;
-insert into t1 values(NULL);
+insert into t1 values(1,NULL);
+insert into t1 values(2,"2002-03-03");
+SET TIMESTAMP=1235;
+insert into t1 values(3,NULL);
+SET TIMESTAMP=1236;
+insert into t1 (a) values(4);
+insert into t2 values(5,"2002-03-04"),(6,NULL),(7,"2002-03-05"),(8,"00-00-00");
+SET TIMESTAMP=1237;
+insert into t1 select * from t2;
+SET TIMESTAMP=1238;
+insert into t1 (a) select a+1 from t2 where a=8;
select * from t1;
-drop table t1;
-
+drop table t1,t2;
+SET TIMESTAMP=1234;
CREATE TABLE t1 (value TEXT NOT NULL, id VARCHAR(32) NOT NULL, stamp timestamp, PRIMARY KEY (id));
INSERT INTO t1 VALUES ("my value", "myKey","1999-04-02 00:00:00");
SELECT stamp FROM t1 WHERE id="myKey";
@@ -22,8 +34,11 @@ select date_format(a,"%Y %y"),year(a),year(now()) from t1;
drop table t1;
create table t1 (ix timestamp);
-insert into t1 values (19991101000000),(19990102030405),(19990630232922),(19990601000000),(19990930232922),(19990531232922),(19990501000000),(19991101000000),(19990501000000);
-select * from t1;
+insert into t1 values (19991101000000),(19990102030405),(19990630232922),(19990601000000),(19990930232922),(19990531232922),(19990501000000),(19991101000000),(19990501000000),(20030101010160),(20030101016001),(20030101240101),(20030132010101),(20031301010101);
+select * from t1;
+delete from t1;
+insert into t1 values ("19991101000000"),("19990102030405"),("19990630232922"),("19990601000000"),("20030101010160"),("20030101016001"),("20030101240101"),("20030132010101"),("20031301010101");
+select * from t1;
drop table t1;
CREATE TABLE t1 (date date, date_time datetime, time_stamp timestamp);
@@ -43,3 +58,50 @@ INSERT INTO t1 VALUES ("2030-01-01","2030-01-01 00:00:00",20300101000000);
#INSERT INTO t1 VALUES ("2050-01-01","2050-01-01 00:00:00",20500101000000);
SELECT * FROM t1;
drop table t1;
+
+show variables like 'new';
+create table t1 (t2 timestamp(2), t4 timestamp(4), t6 timestamp(6),
+ t8 timestamp(8), t10 timestamp(10), t12 timestamp(12),
+ t14 timestamp(14));
+insert t1 values (0,0,0,0,0,0,0),
+("1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
+"1997-12-31 23:47:59", "1997-12-31 23:47:59", "1997-12-31 23:47:59",
+"1997-12-31 23:47:59");
+select * from t1;
+set new=1;
+select * from t1;
+drop table t1;
+
+#
+# Bug #1885, bug #2539.
+# Not perfect but still sensible attitude towards defaults for TIMESTAMP
+# We will ignore default value for first TIMESTAMP column.
+#
+create table t1 (t1 timestamp default '2003-01-01 00:00:00',
+ t2 timestamp default '2003-01-01 00:00:00');
+set TIMESTAMP=1000000000;
+insert into t1 values();
+select * from t1;
+show create table t1;
+show columns from t1;
+show columns from t1 like 't2';
+create table t2 (select * from t1);
+show create table t2;
+
+# Ugly, but we can't do anything about this in 4.0
+alter table t1 add column t0 timestamp first;
+show create table t1;
+
+drop table t1,t2;
+
+#
+# Test for bug 2464, DEFAULT keyword in INSERT statement should return
+# default value for column.
+#
+
+create table t1 (ts1 timestamp, ts2 timestamp);
+set TIMESTAMP=1000000000;
+insert into t1 values ();
+insert into t1 values (DEFAULT, DEFAULT);
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test
index 70a3053f19b..e9e34dbc29f 100644
--- a/mysql-test/t/type_year.test
+++ b/mysql-test/t/type_year.test
@@ -1,10 +1,19 @@
#
# Test year
#
-
+drop table if exists t1;
create table t1 (y year,y2 year(2));
insert into t1 values (0,0),(1999,1999),(2000,2000),(2001,2001),(70,70),(69,69);
select * from t1;
select * from t1 order by y;
select * from t1 order by y2;
drop table t1;
+
+#
+# Bug 2335
+#
+
+create table t1 (y year);
+insert into t1 values (now());
+select if(y = now(), 1, 0) from t1;
+drop table t1;
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
new file mode 100644
index 00000000000..badfe4b9a3a
--- /dev/null
+++ b/mysql-test/t/union.test
@@ -0,0 +1,236 @@
+#
+# Test of unions
+#
+
+drop table if exists t1,t2,t3,t4,t5,t6;
+CREATE TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
+CREATE TABLE t2 (a int not null, b char (10) not null);
+insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
+
+select a,b from t1 union distinct select a,b from t2;
+select a,b from t1 union all select a,b from t2;
+select a,b from t1 union all select a,b from t2 order by b;
+select a,b from t1 union all select a,b from t2 union select 7,'g';
+select 0,'#' union select a,b from t1 union all select a,b from t2 union select 7,'gg';
+select a,b from t1 union select a,b from t1;
+select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b;
+
+# Test alternate syntax for unions
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4;
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1);
+(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
+explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
+(select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2;
+select found_rows();
+select sql_calc_found_rows a,b from t1 union all select a,b from t2 limit 2;
+select found_rows();
+
+#
+# Test some error conditions with UNION
+#
+
+explain select a,b from t1 union all select a,b from t2;
+
+--error 1054
+explain select xx from t1 union select 1;
+explain select a,b from t1 union select 1;
+explain select 1 union select a,b from t1 union select 1;
+explain select a,b from t1 union select 1 limit 0;
+
+--error 1221
+select a,b from t1 into outfile 'skr' union select a,b from t2;
+
+--error 1221
+select a,b from t1 order by a union select a,b from t2;
+
+--error 1221
+insert into t3 select a from t1 order by a union select a from t2;
+
+--error 1222
+create table t3 select a,b from t1 union select a from t2;
+
+--error 1222
+select a,b from t1 union select a from t2;
+
+--error 1222
+select * from t1 union select a from t2;
+
+--error 1222
+select a from t1 union select * from t2;
+
+--error 1234
+select * from t1 union select SQL_BUFFER_RESULT * from t2;
+
+# Test CREATE, INSERT and REPLACE
+create table t3 select a,b from t1 union all select a,b from t2;
+insert into t3 select a,b from t1 union all select a,b from t2;
+replace into t3 select a,b as c from t1 union all select a,b from t2;
+
+drop table t1,t2,t3;
+
+#
+# Test bug reported by joc@presence-pc.com
+#
+
+CREATE TABLE t1 (
+ `pseudo` char(35) NOT NULL default '',
+ `pseudo1` char(35) NOT NULL default '',
+ `same` tinyint(1) unsigned NOT NULL default '1',
+ PRIMARY KEY (`pseudo1`),
+ KEY `pseudo` (`pseudo`)
+) TYPE=MyISAM;
+INSERT INTO t1 (pseudo,pseudo1,same) VALUES ('joce', 'testtt', 1),('joce', 'tsestset', 1),('dekad', 'joce', 1);
+SELECT pseudo FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo FROM t1 WHERE pseudo='joce';
+SELECT pseudo1 FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo1 FROM t1 WHERE pseudo='joce';
+SELECT * FROM t1 WHERE pseudo1='joce' UNION SELECT * FROM t1 WHERE pseudo='joce' order by pseudo desc,pseudo1 desc;
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT pseudo FROM t1 WHERE pseudo1='joce';
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION ALL SELECT pseudo FROM t1 WHERE pseudo1='joce';
+SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT 1;
+drop table t1;
+drop table if exists t1,t2;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(2),(3),(4),(5);
+insert into t2 values (11),(12),(13),(14),(15);
+(select * from t1 limit 2) union (select * from t2 limit 3) limit 4;
+(select * from t1 limit 2) union (select * from t2 limit 3);
+(select * from t1 limit 2) union (select * from t2 limit 20,3);
+set SQL_SELECT_LIMIT=2;
+(select * from t1 limit 1) union (select * from t2 limit 3);
+set SQL_SELECT_LIMIT=DEFAULT;
+drop table t1,t2;
+
+#
+# Test error with left join
+#
+
+CREATE TABLE t1 (
+ cid smallint(5) unsigned NOT NULL default '0',
+ cv varchar(250) NOT NULL default '',
+ PRIMARY KEY (cid),
+ UNIQUE KEY cv (cv)
+) ;
+INSERT INTO t1 VALUES (8,'dummy');
+CREATE TABLE t2 (
+ cid bigint(20) unsigned NOT NULL auto_increment,
+ cap varchar(255) NOT NULL default '',
+ PRIMARY KEY (cid),
+ KEY cap (cap)
+) ;
+CREATE TABLE t3 (
+ gid bigint(20) unsigned NOT NULL auto_increment,
+ gn varchar(255) NOT NULL default '',
+ must tinyint(4) default NULL,
+ PRIMARY KEY (gid),
+ KEY gn (gn)
+) ;
+INSERT INTO t3 VALUES (1,'V1',NULL);
+CREATE TABLE t4 (
+ uid bigint(20) unsigned NOT NULL default '0',
+ gid bigint(20) unsigned default NULL,
+ rid bigint(20) unsigned default NULL,
+ cid bigint(20) unsigned default NULL,
+ UNIQUE KEY m (uid,gid,rid,cid),
+ KEY uid (uid),
+ KEY rid (rid),
+ KEY cid (cid),
+ KEY container (gid,rid,cid)
+) ;
+INSERT INTO t4 VALUES (1,1,NULL,NULL);
+CREATE TABLE t5 (
+ rid bigint(20) unsigned NOT NULL auto_increment,
+ rl varchar(255) NOT NULL default '',
+ PRIMARY KEY (rid),
+ KEY rl (rl)
+) ;
+CREATE TABLE t6 (
+ uid bigint(20) unsigned NOT NULL auto_increment,
+ un varchar(250) NOT NULL default '',
+ uc smallint(5) unsigned NOT NULL default '0',
+ PRIMARY KEY (uid),
+ UNIQUE KEY nc (un,uc),
+ KEY un (un)
+) ;
+INSERT INTO t6 VALUES (1,'test',8);
+
+SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left join t5 on t5.rid = t4.rid left join t2 on t2.cid = t4.cid WHERE t3.gid=t4.gid AND t6.uid = t4.uid AND t6.uc = t1.cid AND t1.cv = "dummy" AND t6.un = "test";
+SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left join t5 on t5.rid = t4.rid left join t2 on t2.cid = t4.cid WHERE t3.gid=t4.gid AND t6.uid = t4.uid AND t3.must IS NOT NULL AND t6.uc = t1.cid AND t1.cv = "dummy" AND t6.un = "test";
+(SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left join t5 on t5.rid = t4.rid left join t2 on t2.cid = t4.cid WHERE t3.gid=t4.gid AND t6.uid = t4.uid AND t3.must IS NOT NULL AND t6.uc = t1.cid AND t1.cv = "dummy" AND t6.un = "test") UNION (SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left join t5 on t5.rid = t4.rid left join t2 on t2.cid = t4.cid WHERE t3.gid=t4.gid AND t6.uid = t4.uid AND t6.uc = t1.cid AND t1.cv = "dummy" AND t6.un = "test");
+
+drop table t1,t2,t3,t4,t5,t6;
+CREATE TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
+CREATE TABLE t2 (a int not null, b char (10) not null);
+insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
+create table t3 select a,b from t1 union select a,b from t2;
+create table t4 (select a,b from t1) union (select a,b from t2) limit 2;
+insert into t4 select a,b from t1 union select a,b from t2;
+insert into t3 (select a,b from t1) union (select a,b from t2) limit 2;
+select * from t3;
+select * from t4;
+drop table t1,t2,t3,t4;
+
+#
+# Test of SQL_CALC_FOUND_ROW handling
+#
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+create table t2 (a int);
+insert into t2 values (3),(4),(5);
+
+# Test global limits
+(SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2) LIMIT 1;
+select found_rows();
+(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2) LIMIT 2;
+select found_rows();
+
+# Test cases where found_rows() should return number of returned rows
+(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2);
+select found_rows();
+(SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2 LIMIT 1);
+select found_rows();
+(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION SELECT * FROM t2 LIMIT 1;
+select found_rows();
+
+# In these case found_rows() should work
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION all SELECT * FROM t2 LIMIT 2;
+select found_rows();
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION all SELECT * FROM t2 LIMIT 2;
+select found_rows();
+
+# The following examples will not be exact
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2;
+select found_rows();
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100;
+select found_rows();
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2;
+select found_rows();
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2;
+select found_rows();
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2 LIMIT 2;
+select found_rows();
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2,2;
+select found_rows();
+SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2;
+select found_rows();
+
+# Test some limits with ORDER BY
+SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a desc LIMIT 1;
+(SELECT * FROM t1 ORDER by a) UNION ALL (SELECT * FROM t2 ORDER BY a) ORDER BY A desc LIMIT 4;
+
+# Wrong usage
+--error 1234
+(SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1;
+
+create temporary table t1 select a from t1 union select a from t2;
+--error 1093
+create table t1 select a from t1 union select a from t2;
+drop table t1,t2;
+
+#
+# Problem with alias '*' (BUG #1249)
+#
+
+select length(version()) > 1 as `*` UNION select 2;
+
diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test
index 6f446a11521..a455b308158 100644
--- a/mysql-test/t/update.test
+++ b/mysql-test/t/update.test
@@ -72,7 +72,54 @@ CREATE TABLE t1 (
INSERT INTO t1 VALUES (773,773,'','','',980257344,20010318180652,0,'Open',10,0,0,0,1,'','','','','');
-alter table t1 change lfdnr lfdnr int(10) unsigned default 0 not null auto_increment;
+alter table t1 change lfdnr lfdnr int(10) unsigned not null auto_increment;
update t1 set status=1 where type='Open';
select status from t1;
drop table t1;
+
+#
+# Test of ORDER BY
+#
+
+create table t1 (a int not null, b int not null, key (a));
+insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3);
+SET @tmp=0;
+update t1 set b=(@tmp:=@tmp+1) order by a;
+update t1 set b=99 where a=1 order by b asc limit 1;
+select * from t1 order by a,b;
+update t1 set b=100 where a=1 order by b desc limit 2;
+update t1 set a=a+10+b where a=1 order by b;
+select * from t1 order by a,b;
+drop table t1;
+
+#
+# Test with limit (Bug #393)
+#
+
+CREATE TABLE t1 (
+ `id_param` smallint(3) unsigned NOT NULL default '0',
+ `nom_option` char(40) NOT NULL default '',
+ `valid` tinyint(1) NOT NULL default '0',
+ KEY `id_param` (`id_param`,`nom_option`)
+ ) TYPE=MyISAM;
+
+INSERT INTO t1 (id_param,nom_option,valid) VALUES (185,'600x1200',1);
+
+UPDATE t1 SET nom_option='test' WHERE id_param=185 AND nom_option='600x1200' AND valid=1 LIMIT 1;
+select * from t1;
+drop table t1;
+
+#
+# Multi table update test from bugs
+#
+
+create table t1 (F1 VARCHAR(30), F2 VARCHAR(30), F3 VARCHAR(30), cnt int, groupid int, KEY groupid_index (groupid));
+
+insert into t1 (F1,F2,F3,cnt,groupid) values ('0','0','0',1,6),
+('0','1','2',1,5), ('0','2','0',1,3), ('1','0','1',1,2),
+('1','2','1',1,1), ('1','2','2',1,1), ('2','0','1',2,4),
+('2','2','0',1,7);
+
+delete from t1 using t1 m1,t1 m2 where m1.groupid=m2.groupid and (m1.cnt < m2.cnt or m1.cnt=m2.cnt and m1.F3>m2.F3);
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 3103de2dac5..9cb5d5e1eb0 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -1,4 +1,4 @@
-error 1204;
+error 1054;
set @a := foo;
set @a := connection_id() + 3;
select @a - connection_id();
@@ -19,7 +19,48 @@ explain select * from t1 where i=@vv1;
drop table t1,t2;
# Check types of variables
+set @a=0,@b=0;
select @a:=10, @b:=1, @a > @b, @a < @b;
+# Note that here a and b will be avaluated as number
select @a:="10", @b:="1", @a > @b, @a < @b;
+# Note that here a and b will be avaluated as strings
select @a:=10, @b:=2, @a > @b, @a < @b;
select @a:="10", @b:="2", @a > @b, @a < @b;
+
+# Fixed bug #1194
+select @a:=1;
+select @a, @a:=1;
+
+create table t1 (id int, d double, c char(10));
+insert into t1 values (1,2.0, "test");
+select @c:=0;
+update t1 SET id=(@c:=@c+1);
+select @c;
+select @c:=0;
+update t1 set id=(@c:=@c+1);
+select @c;
+select @c:=0;
+select @c:=@c+1;
+select @d,(@d:=id),@d from t1;
+select @e,(@e:=d),@e from t1;
+select @f,(@f:=c),@f from t1;
+set @g=1;
+select @g,(@g:=c),@g from t1;
+select @c, @d, @e, @f;
+select @d:=id, @e:=id, @f:=id, @g:=@id from t1;
+select @c, @d, @e, @f, @g;
+drop table t1;
+
+# just for fun :)
+select @a:=10, @b:=2, @a>@b, @a:="10", @b:="2", @a>@b, @a:=10, @b:=2, @a>@b, @a:="10", @b:="2", @a>@b;
+
+#
+# bug#1739
+# Item_func_set_user_var sets update_query_id, Item_func_get_user_var checks it
+#
+create table t1 (i int not null);
+insert t1 values (1),(2),(2),(3),(3),(3);
+select @a:=0; select @a, @a:=@a+count(*), count(*), @a from t1 group by i;
+select @a:=0; select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i;
+drop table t1;
+
diff --git a/mysql-test/t/varbinary.test b/mysql-test/t/varbinary.test
index 0ab26f51e65..cc9ee99b7f9 100644
--- a/mysql-test/t/varbinary.test
+++ b/mysql-test/t/varbinary.test
@@ -4,13 +4,30 @@
select 0x41,0x41+0,0x41 | 0x7fffffffffffffff | 0,0xffffffffffffffff | 0 ;
select 0x31+1,concat(0x31)+1,-0xf;
+select x'31',X'ffff'+0;
#
# Test of hex constants in WHERE:
#
+drop table if exists t1;
create table t1 (ID int(8) unsigned zerofill not null auto_increment,UNIQ bigint(21) unsigned zerofill not null,primary key (ID),unique (UNIQ) );
insert into t1 set UNIQ=0x38afba1d73e6a18a;
insert into t1 set UNIQ=123;
explain select * from t1 where UNIQ=0x38afba1d73e6a18a;
drop table t1;
+
+#
+# Test error conditions
+#
+--error 1064
+select x'hello';
+--error 1054
+select 0xfg;
+
+#
+# Test likely error conditions
+#
+create table t1 select 1 as x, 2 as xx;
+select x,xx from t1;
+drop table t1;
diff --git a/mysql-test/t/variables-master.opt b/mysql-test/t/variables-master.opt
new file mode 100644
index 00000000000..5851d32ec31
--- /dev/null
+++ b/mysql-test/t/variables-master.opt
@@ -0,0 +1 @@
+max_join_size=10
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index b3127402238..ec86a763023 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -32,9 +32,240 @@ drop table t1;
# Test system variables
#
+set max_join_size=100;
+show variables like 'max_join_size';
+--replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR
+show global variables like 'max_join_size';
+set GLOBAL max_join_size=2000;
+show global variables like 'max_join_size';
+set max_join_size=DEFAULT;
+--replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR
+show variables like 'max_join_size';
+set GLOBAL max_join_size=DEFAULT;
+--replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR
+show global variables like 'max_join_size';
+set @@max_join_size=1000, @@global.max_join_size=2000;
+select @@local.max_join_size, @@global.max_join_size;
+select @@identity, length(@@version)>0;
select @@VERSION=version();
select last_insert_id(345);
-select @@IDENTITY,last_insert_id();
-select @@identity;
+select @@IDENTITY,last_insert_id(), @@identity;
+
+set big_tables=OFF, big_tables=ON, big_tables=0, big_tables=1, big_tables="OFF", big_tables="ON";
+
+set global concurrent_insert=ON;
+show variables like 'concurrent_insert';
+set global concurrent_insert=1;
+show variables like 'concurrent_insert';
+set global concurrent_insert=0;
+show variables like 'concurrent_insert';
+set global concurrent_insert=OFF;
+show variables like 'concurrent_insert';
+set global concurrent_insert=DEFAULT;
+show variables like 'concurrent_insert';
+
+set table_type=MYISAM, table_type="HEAP", global table_type="INNODB";
+show local variables like 'table_type';
+show global variables like 'table_type';
+set GLOBAL query_cache_size=100000;
+
+set GLOBAL myisam_max_sort_file_size=2000000;
+show global variables like 'myisam_max_sort_file_size';
+set GLOBAL myisam_max_sort_file_size=default;
+--replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE
+show variables like 'myisam_max_sort_file_size';
+
+set global net_retry_count=10, session net_retry_count=10;
+set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300;
+set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600;
+show global variables like 'net_%';
+show session variables like 'net_%';
+set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000;
+show global variables like 'net_%';
+show session variables like 'net_%';
+set net_buffer_length=1;
+show variables like 'net_buffer_length';
+set net_buffer_length=2000000000;
+show variables like 'net_buffer_length';
+
+set GLOBAL character set cp1251_koi8;
+show global variables like "convert_character_set";
+set character set cp1251_koi8;
+show variables like "convert_character_set";
+set global character set default, session character set default;
+show variables like "convert_character_set";
+select @@timestamp>0;
+
+set @@rand_seed1=10000000,@@rand_seed2=1000000;
+select ROUND(RAND(),5);
+
+show variables like '%alloc%';
+set @@range_alloc_block_size=1024*16;
+set @@query_alloc_block_size=1024*17+2;
+set @@query_prealloc_size=1024*18;
+set @@transaction_alloc_block_size=1024*20-1;
+set @@transaction_prealloc_size=1024*21-1;
+select @@query_alloc_block_size;
+show variables like '%alloc%';
+set @@range_alloc_block_size=default;
+set @@query_alloc_block_size=default, @@query_prealloc_size=default;
+set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
+show variables like '%alloc%';
+
+# The following should give errors
+
+--error 1231
+set big_tables=OFFF;
+--error 1231
+set big_tables="OFFF";
+--error 1193
+set unknown_variable=1;
+--error 1232
+set max_join_size="hello";
+--error 1231
+set table_type=UNKNOWN_TABLE_TYPE;
+--error 1231
+set table_type=INNODB, big_tables=2;
+show local variables like 'table_type';
+--error 1229
+set SESSION query_cache_size=10000;
+--error 1230
+set GLOBAL table_type=DEFAULT;
+--error 1115
+set convert_character_set=UNKNOWN_CHARACTER_SET;
+--error 1115
+set character set unknown;
+--error 1232
+set character set 0;
+--error 1228
+set global autocommit=1;
+--error 1238
+select @@global.timestamp;
--error 1193
-select @@unknown_variable;
+set @@version='';
+--error 1229
+set @@concurrent_insert=1;
+--error 1228
+set @@global.sql_auto_is_null=1;
+--error 1238
+select @@global.sql_auto_is_null;
+--error 1229
+set myisam_max_sort_file_size=100;
+--error 1229
+set myisam_max_extra_sort_file_size=100;
+--error 1231
+set @@SQL_WARNINGS=NULL;
+
+# Test setting all variables
+
+set autocommit=1;
+set big_tables=1;
+select @@autocommit, @@big_tables;
+set global binlog_cache_size=100;
+set bulk_insert_buffer_size=100;
+set convert_character_set=cp1251_koi8;
+set convert_character_set=default;
+set @@global.concurrent_insert=1;
+set global connect_timeout=100;
+select @@delay_key_write;
+set global delay_key_write="OFF";
+select @@delay_key_write;
+set global delay_key_write=ALL;
+select @@delay_key_write;
+set global delay_key_write=1;
+select @@delay_key_write;
+set global delayed_insert_limit=100;
+set global delayed_insert_timeout=100;
+set global delayed_queue_size=100;
+set global flush=1;
+set global flush_time=100;
+set insert_id=1;
+set interactive_timeout=100;
+set join_buffer_size=100;
+set last_insert_id=1;
+set global local_infile=1;
+set long_query_time=100;
+set low_priority_updates=1;
+set max_allowed_packet=100;
+set global max_binlog_cache_size=100;
+set global max_binlog_size=100;
+set global max_connect_errors=100;
+set global max_connections=100;
+set global max_delayed_threads=100;
+set max_heap_table_size=100;
+set max_join_size=100;
+set max_sort_length=100;
+set max_tmp_tables=100;
+set global max_user_connections=100;
+select @@max_user_connections;
+set global max_write_lock_count=100;
+set global myisam_max_extra_sort_file_size=100;
+select @@myisam_max_extra_sort_file_size;
+set global myisam_max_sort_file_size=100;
+set myisam_sort_buffer_size=100;
+set net_buffer_length=100;
+set net_read_timeout=100;
+set net_write_timeout=100;
+set global query_cache_limit=100;
+set global query_cache_size=100;
+set global query_cache_type=demand;
+set read_buffer_size=100;
+set read_rnd_buffer_size=100;
+set global rpl_recovery_rank=100;
+set global server_id=100;
+set global slave_net_timeout=100;
+set global slow_launch_time=100;
+set sort_buffer_size=100;
+set sql_auto_is_null=1;
+select @@sql_auto_is_null;
+set @@sql_auto_is_null=0;
+select @@sql_auto_is_null;
+set sql_big_selects=1;
+set sql_big_tables=1;
+set sql_buffer_result=1;
+set sql_log_bin=1;
+set sql_log_off=1;
+set sql_log_update=1;
+set sql_low_priority_updates=1;
+set sql_max_join_size=200;
+select @@sql_max_join_size,@@max_join_size;
+set sql_quote_show_create=1;
+set sql_safe_updates=1;
+set sql_select_limit=1;
+set global sql_slave_skip_counter=100;
+set sql_warnings=1;
+set global table_cache=100;
+set table_type=myisam;
+set global thread_cache_size=100;
+set timestamp=1, timestamp=default;
+set tmp_table_size=100;
+set tx_isolation="READ-COMMITTED";
+set wait_timeout=100;
+set log_warnings=1;
+
+#
+# key buffer
+#
+
+DROP TABLE IF EXISTS t1,t2;
+create table t1 (a int not null auto_increment, primary key(a));
+create table t2 (a int not null auto_increment, primary key(a));
+insert into t1 values(null),(null),(null);
+insert into t2 values(null),(null),(null);
+set global key_buffer_size=100000;
+select @@key_buffer_size;
+select * from t1 where a=2;
+select * from t2 where a=3;
+check table t1,t2;
+drop table t1,t2;
+
+#
+# error conditions
+#
+
+--error 1193
+select @@xxxxxxxxxx;
+select 1;
+
+--error 1238
+select @@session.key_buffer_size; \ No newline at end of file
diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test
index e7cb1f46ec3..5fb536def71 100644
--- a/mysql-test/t/warnings.test
+++ b/mysql-test/t/warnings.test
@@ -1,7 +1,7 @@
#
# Test some warnings
#
-
+drop table if exists t1;
create table t1 (a int);
insert into t1 values (1);
insert into t1 values ("hej");
diff --git a/mysql-test/xml/README b/mysql-test/xml/README
deleted file mode 100644
index ee1af30db33..00000000000
--- a/mysql-test/xml/README
+++ /dev/null
@@ -1,74 +0,0 @@
-This directory contains all of the test cases for the MySQL Test Suite
-marked up in XML.
-
-To convert these test cases from XML into 'mysqltest' format, one needs
-an XSL translator installed on their system. At MySQL, we use Sablotron
-(http://www.gingerall.com/). Once installed, conversion happens with a
-command like this:
-
- sabcmd xsl/mysqltest.xsl < tests/sel000001.xml > sel000001.test
-
-The file 'sel000001.test' contains the plain text conversion that is
-to be fed into the 'mysqltest' program.
-
-Below is an example of a test case marked up in XML; illustrating all
-of the XML mark-up currently supported in our 'mysqltest.xsl' stylesheet.
-
-----------------------------------------------------
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000001">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>This test will monkey around trying to kill mysqld.</description>
-
- <connect name="Test_Connect1"
- host="MyHostName"
- user="Matt"
- pass="MattPass"
- db="MyDB"
- port="3306"
- sock="MyDB.sock"
- />
-
- <connection name="Test_Connect1">
- <resultfile name="sel000001.result">
- <sql>SELECT y FROM foo WHERE bar='2'</sql>
- </resultfile>
- <sql>INSERT INTO foo VALUES (y='2') WHERE bar='1'</sql>
- </connection>
-
-</test>
-----------------------------------------------------
-
-
-The converted (mysqltest format) output of this source XML file looks
-like:
-
-
-----------------------------------------------------
-# sel000001
-#
-# Versions
-# --------
-# 3.22
-# 3.23
-#
-# Description
-# -----------
-# This test will monkey around trying to kill mysqld.
-#
-
-
-connect(Test_Connect1, MyHostName, Matt, MattPass, MyDB, 3306, MyDB.sock)
-
-connection Test_Connect1
-INSERT INTO foo VALUES (y='2') WHERE bar='1';
-@sel000001.result SELECT y FROM foo WHERE bar='2';
-----------------------------------------------------
-
-
diff --git a/mysql-test/xml/tests/sel000001.xml b/mysql-test/xml/tests/sel000001.xml
deleted file mode 100644
index 7ce4dae8ee1..00000000000
--- a/mysql-test/xml/tests/sel000001.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000001">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>This test is just a simple select.</description>
- <description>Testing WHERE clause.</description>
-
- <sql>DROP TABLE IF EXISTS t</sql>
- <sql>CREATE TABLE t (s CHAR(20) PRIMARY KEY, id INT)</sql>
- <sql>INSERT INTO t VALUES ('cat', 1), ('mouse', 3), ('dog', 2), ('snake', 77)</sql>
-
- <resultfile name="r/3.23/sel000001.result">
- <sql>SELECT s, id FROM t WHERE s = 'mouse'</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000002.xml b/mysql-test/xml/tests/sel000002.xml
deleted file mode 100644
index 902233cbbf0..00000000000
--- a/mysql-test/xml/tests/sel000002.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000002">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>This test is just a simple select.</description>
-
- <sql>DROP TABLE IF EXISTS t</sql>
- <sql>CREATE TABLE t (n INT)</sql>
- <sql>INSERT INTO t VALUES (1), (2), (3)</sql>
-
- <resultfile name="r/3.23/sel000002.result">
- <sql>SELECT * FROM t</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000003.xml b/mysql-test/xml/tests/sel000003.xml
deleted file mode 100644
index c9334c972d8..00000000000
--- a/mysql-test/xml/tests/sel000003.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000003">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>This test is just a simple select.</description>
- <description>Testing count() function and GROUP BY clause.</description>
-
- <sql>DROP TABLE IF EXISTS t</sql>
- <sql>CREATE TABLE t (name CHAR(20) NOT NULL PRIMARY KEY, score SMALLINT NOT NULL, KEY(score))</sql>
- <sql>INSERT INTO t VALUES ('Sasha', 20), ('Matt', 20), ('Monty', 10), ('David', 10), ('Tim', 10), ('Jeremy', 10)</sql>
-
- <resultfile name="r/3.23/sel000003.result">
- <sql>SELECT COUNT(*) as n, score FROM t GROUP BY score</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000004.xml b/mysql-test/xml/tests/sel000004.xml
deleted file mode 100644
index 9c28c632c32..00000000000
--- a/mysql-test/xml/tests/sel000004.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000004">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Simple arithmetic.</description>
- <description>Testing MOD(), SIGN(), and arithmetic grouping.</description>
-
- <resultfile name="r/3.23/sel000004.result">
- <sql>SELECT 1+1,1-1,1+1*2,8/5,8%5,MOD(8,5),MOD(8,5)|0,-(1+1)*-2,SIGN(-5)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000005.xml b/mysql-test/xml/tests/sel000005.xml
deleted file mode 100644
index 0bcddb2fbb6..00000000000
--- a/mysql-test/xml/tests/sel000005.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000005">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric functions.</description>
- <description>Testing FLOOR(), CEILING(), ROUND().</description>
-
- <resultfile name="r/3.23/sel000005.result">
- <sql>SELECT FLOOR(5.5),FLOOR(-5.5),CEILING(5.5),CEILING(-5.5),ROUND(5.5),ROUND(-5.5)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000006.xml b/mysql-test/xml/tests/sel000006.xml
deleted file mode 100644
index 3059f8bb7df..00000000000
--- a/mysql-test/xml/tests/sel000006.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000006">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric functions.</description>
- <description>Testing ROUND(); hundreths precision.</description>
-
- <resultfile name="r/3.23/sel000006.result">
- <sql>SELECT ROUND(5.64,1),ROUND(5.64,2),ROUND(5.64,-1),ROUND(5.64,-2)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000007.xml b/mysql-test/xml/tests/sel000007.xml
deleted file mode 100644
index 8f8bb7162c3..00000000000
--- a/mysql-test/xml/tests/sel000007.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000007">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric functions.</description>
- <description>Testing TRUNCATE().</description>
-
- <resultfile name="r/3.23/sel000007.result">
- <sql>SELECT TRUNCATE(52.64,1),TRUNCATE(52.64,2),TRUNCATE(52.64,-1),TRUNCATE(52.64,-2)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000008.xml b/mysql-test/xml/tests/sel000008.xml
deleted file mode 100644
index 70a54a15d5b..00000000000
--- a/mysql-test/xml/tests/sel000008.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000008">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric functions.</description>
- <description>Testing ABS(), LOG(), LOG10(), EXP(), SQRT(), POW(), RAND(), POWER().</description>
-
- <resultfile name="r/3.23/sel000008.result">
- <sql>SELECT ABS(-10),LOG(EXP(10)),EXP(LOG(SQRT(10))*2),POW(10,LOG10(10)),RAND(999999),RAND(),POWER(2,4)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000009.xml b/mysql-test/xml/tests/sel000009.xml
deleted file mode 100644
index 0c79f032112..00000000000
--- a/mysql-test/xml/tests/sel000009.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000009">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric functions.</description>
- <description>Testing PI(), SIN(), COS(), TAN(), COT(), ASIN(), ACOS(), ATAN().</description>
-
- <resultfile name="r/3.23/sel000009.result">
- <sql>SELECT PI(),SIN(PI()/2),COS(PI()/2),TAN(PI()),COT(1),ASIN(1),ACOS(0),ATAN(1)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000010.xml b/mysql-test/xml/tests/sel000010.xml
deleted file mode 100644
index 6954fef0750..00000000000
--- a/mysql-test/xml/tests/sel000010.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000010">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric bitwise comparisons.</description>
- <description>Testing |, &amp;, BIT_COUNT().</description>
-
- <resultfile name="r/3.23/sel000010.result">
- <sql>SELECT 1 | (1+1),5 &amp; 3,BIT_COUNT(7)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000011.xml b/mysql-test/xml/tests/sel000011.xml
deleted file mode 100644
index 5c981b2f85a..00000000000
--- a/mysql-test/xml/tests/sel000011.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000011">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric bitmoving comparisons.</description>
- <description>Testing &lt;&lt;, >>.</description>
-
- <resultfile name="r/3.23/sel000011.result">
- <sql>SELECT 1 &lt;&lt; 32,1 &lt;&lt; 63, 1 &lt;&lt; 64, 4 >> 2, 4 >> 63, 1&lt;&lt; 63 >> 60</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000012.xml b/mysql-test/xml/tests/sel000012.xml
deleted file mode 100644
index 7abcc498164..00000000000
--- a/mysql-test/xml/tests/sel000012.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000012">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric floating point.</description>
-
- <resultfile name="r/3.23/sel000012.result">
- <sql>SELECT 10,10.0,10.,.1e+2,100.0e-1</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000013.xml b/mysql-test/xml/tests/sel000013.xml
deleted file mode 100644
index fbeca6663fc..00000000000
--- a/mysql-test/xml/tests/sel000013.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000013">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numeric floating point.</description>
-
- <resultfile name="r/3.23/sel000013.result">
- <sql>SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000014.xml b/mysql-test/xml/tests/sel000014.xml
deleted file mode 100644
index 96a51e671fc..00000000000
--- a/mysql-test/xml/tests/sel000014.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000014">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing pos/neg and zero padding.</description>
-
- <resultfile name="r/3.23/sel000014.result">
- <sql>SELECT 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000015.xml b/mysql-test/xml/tests/sel000015.xml
deleted file mode 100644
index a339330e6b1..00000000000
--- a/mysql-test/xml/tests/sel000015.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000015">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing big numbers.</description>
-
- <resultfile name="r/3.23/sel000015.result">
- <sql>SELECT 922337203685477580,92233720368547758000</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000016.xml b/mysql-test/xml/tests/sel000016.xml
deleted file mode 100644
index ae971e6576a..00000000000
--- a/mysql-test/xml/tests/sel000016.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000016">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing big negative numbers.</description>
-
- <resultfile name="r/3.23/sel000016.result">
- <sql>SELECT -922337203685477580,-92233720368547758000</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000017.xml b/mysql-test/xml/tests/sel000017.xml
deleted file mode 100644
index 9d06d640ac3..00000000000
--- a/mysql-test/xml/tests/sel000017.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000017">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing big pos/neg numbers.</description>
-
- <resultfile name="r/3.23/sel000017.result">
- <sql>SELECT 9223372036854775807,-009223372036854775808</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000018.xml b/mysql-test/xml/tests/sel000018.xml
deleted file mode 100644
index 909728599fa..00000000000
--- a/mysql-test/xml/tests/sel000018.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000018">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing big pos/neg numbers.</description>
-
- <resultfile name="r/3.23/sel000018.result">
- <sql>SELECT +9999999999999999999,-9999999999999999999</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000019.xml b/mysql-test/xml/tests/sel000019.xml
deleted file mode 100644
index e0286ae2db7..00000000000
--- a/mysql-test/xml/tests/sel000019.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000019">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Numerics.</description>
- <description>Testing DEGREES(), RADIANS().</description>
-
- <resultfile name="r/3.23/sel000019.result">
- <sql>SELECT DEGREES(PI()),RADIANS(360)</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000020.xml b/mysql-test/xml/tests/sel000020.xml
deleted file mode 100644
index 41ad5981cb9..00000000000
--- a/mysql-test/xml/tests/sel000020.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000020">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; STRCMP(), =, >, >=, &lt;=, !=.</description>
-
- <resultfile name="r/3.23/sel000020.result">
- <sql>SELECT 0=0,1>0,1>=1,1&lt;0,1&lt;=0,1!=0,STRCMP("abc","abcd"),STRCMP("b","a"),STRCMP("a","a")</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000021.xml b/mysql-test/xml/tests/sel000021.xml
deleted file mode 100644
index ba2e8149abd..00000000000
--- a/mysql-test/xml/tests/sel000021.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000021">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; =, >, >=, &lt;=, &lt;>.</description>
-
- <resultfile name="r/3.23/sel000021.result">
- <sql>SELECT "a"&lt;"b","a"&lt;="b","b">="a","b">"a","a"="A","a"&lt;>"b"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000022.xml b/mysql-test/xml/tests/sel000022.xml
deleted file mode 100644
index 3dca0eb9b7f..00000000000
--- a/mysql-test/xml/tests/sel000022.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000022">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; =, >, &lt;=.</description>
-
- <resultfile name="r/3.23/sel000022.result">
- <sql>SELECT "a "="A", "A "="a", "a " &lt;= "A b"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000023.xml b/mysql-test/xml/tests/sel000023.xml
deleted file mode 100644
index 7cceb4aabca..00000000000
--- a/mysql-test/xml/tests/sel000023.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000023">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; LIKE, NOT LIKE, '%'.</description>
-
- <resultfile name="r/3.23/sel000023.result">
- <sql>SELECT "abc" LIKE "a%", "abc" NOT LIKE "%d%", "a%" LIKE "a\%","abc%" LIKE "a%\%","abcd" LIKE "a%b_%d", "a" LIKE "%%a","abcde" LIKE "a%_e","abc" LIKE "abc%"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000024.xml b/mysql-test/xml/tests/sel000024.xml
deleted file mode 100644
index 5bf9c0be7dc..00000000000
--- a/mysql-test/xml/tests/sel000024.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000024">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; LIKE, '%'.</description>
-
- <resultfile name="r/3.23/sel000024.result">
- <sql>SELECT "a" LIKE "%%b","a" LIKE "%%ab","ab" LIKE "a\%", "ab" LIKE "_", "ab" LIKE "ab_", "abc" LIKE "%_d", "abc" LIKE "abc%d"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000025.xml b/mysql-test/xml/tests/sel000025.xml
deleted file mode 100644
index 4144b65775f..00000000000
--- a/mysql-test/xml/tests/sel000025.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000025">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; LIKE, ESCAPE, '%'.</description>
-
- <resultfile name="r/3.23/sel000025.result">
- <sql>SELECT '?' LIKE '|%', '?' LIKE '|%' ESCAPE '|', '%' LIKE '|%', '%' LIKE '|%' ESCAPE '|', '%' LIKE '%'</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000026.xml b/mysql-test/xml/tests/sel000026.xml
deleted file mode 100644
index afaa34009fa..00000000000
--- a/mysql-test/xml/tests/sel000026.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000026">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; LIKE, '%'.</description>
-
- <resultfile name="r/3.23/sel000026.result">
- <sql>SELECT 'abc' LIKE '%c','abcabc' LIKE '%c', "ab" LIKE "", "ab" LIKE "a", "ab" LIKE "ab"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000027.xml b/mysql-test/xml/tests/sel000027.xml
deleted file mode 100644
index 641d5d3a619..00000000000
--- a/mysql-test/xml/tests/sel000027.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000027">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; REGEXP.</description>
-
- <resultfile name="r/3.23/sel000027.result">
- <sql>SELECT "Det här är svenska" REGEXP "h[[:alpha:]]+r", "aba" REGEXP "^(a|b)*$"</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000028.xml b/mysql-test/xml/tests/sel000028.xml
deleted file mode 100644
index c8db245c25d..00000000000
--- a/mysql-test/xml/tests/sel000028.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000028">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; REGEXP, CONCAT().</description>
-
- <resultfile name="r/3.23/sel000028.result">
- <sql>SELECT "aba" REGEXP CONCAT("^","a")</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000029.xml b/mysql-test/xml/tests/sel000029.xml
deleted file mode 100644
index 84d12a44dc5..00000000000
--- a/mysql-test/xml/tests/sel000029.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000029">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Strings.</description>
- <description>Testing string comparisons; NOT, AND, OR, !, &amp;&amp;, ||.</description>
-
- <resultfile name="r/3.23/sel000029.result">
- <sql>SELECT !0,NOT 0=1,!(0=0),1 AND 1,1 &amp;&amp; 0,0 OR 1,1 || NULL, 1=1 OR 1=1 AND 1=0</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/tests/sel000030.xml b/mysql-test/xml/tests/sel000030.xml
deleted file mode 100644
index 8a8a4d5e0d2..00000000000
--- a/mysql-test/xml/tests/sel000030.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- This file is maintained by matt@mysql.com -->
-
-<test name="sel000030">
-
- <version value="3.22"/>
- <version value="3.23"/>
-
- <description>Control flow.</description>
- <description>Testing control flow; IF()</description>
-
- <resultfile name="r/3.23/sel000030.result">
- <sql>SELECT IF(0,"ERROR","this"),IF(1,"is","ERROR"),IF(NULL,"ERROR","a"),IF(1,2,3)|0,IF(1,2.0,3.0)+0</sql>
- </resultfile>
-
-</test>
diff --git a/mysql-test/xml/xsl/README b/mysql-test/xml/xsl/README
deleted file mode 100644
index fe11b57cf11..00000000000
--- a/mysql-test/xml/xsl/README
+++ /dev/null
@@ -1,4 +0,0 @@
-XML Stylesheets for converting test cases in XML to other forms.
-
- - mysqltest.xsl -> mysqltest format (text)
-
diff --git a/mysql-test/xml/xsl/mysqltest.xsl b/mysql-test/xml/xsl/mysqltest.xsl
deleted file mode 100644
index 8a1e738e611..00000000000
--- a/mysql-test/xml/xsl/mysqltest.xsl
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-
-<xsl:output method="text"/>
-
-<xsl:template match="/"><xsl:apply-templates /></xsl:template>
-
-<!-- Main Template -->
-
-<xsl:template match="/test"># <xsl:apply-templates select="@name"/>
-#
-# Versions
-# --------<xsl:apply-templates select="version"/>
-#
-# Description
-# -----------<xsl:apply-templates select="description"/>
-#
-
-<xsl:apply-templates select="connect"/>
-
-<xsl:apply-templates select="connection"/>
-
-<xsl:apply-templates select="sql"/>
-
-<xsl:apply-templates select="resultfile"/>
-
-</xsl:template>
-
-<!-- End Main Template -->
-
-
-<xsl:template match="version">
-# <xsl:apply-templates select="@value"/>
-</xsl:template>
-
-<xsl:template match="description">
-# <xsl:apply-templates />
-</xsl:template>
-
-<xsl:template match="connect">
-connect(<xsl:apply-templates select="@name"/>, <xsl:apply-templates select="@host"/>, <xsl:apply-templates select="@user"/>, <xsl:apply-templates select="@pass"/>, <xsl:apply-templates select="@db"/>, <xsl:apply-templates select="@port"/>, <xsl:apply-templates select="@sock"/>)
-</xsl:template>
-
-<xsl:template match="connection">
-<xsl:text>
-connection </xsl:text><xsl:apply-templates select="@name"/>
-<xsl:text>
-</xsl:text>
-<xsl:apply-templates select="sql"/>
-<xsl:apply-templates select="resultfile"/>
-</xsl:template>
-
-<xsl:template match="resultfile">@<xsl:apply-templates select="@name"/><xsl:text> </xsl:text><xsl:apply-templates select="sql"/>
-</xsl:template>
-
-<xsl:template match="sql">
-<xsl:apply-templates />;
-</xsl:template>
-</xsl:stylesheet>
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 9141ab132bd..5dc54817fd7 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -27,7 +27,7 @@ noinst_HEADERS = mysys_priv.h my_static.h \
my_os2thread.c my_os2tls.c
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
mf_path.c mf_loadpath.c\
- my_open.c my_create.c my_seek.c my_read.c \
+ my_open.c my_create.c my_dup.c my_seek.c my_read.c \
my_pread.c my_write.c \
mf_keycache.c \
mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
@@ -38,7 +38,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
my_error.c errors.c my_div.c my_messnc.c \
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
my_symlink.c my_symlink2.c \
- mf_pack.c mf_pack2.c mf_unixpath.c mf_strip.c \
+ mf_pack.c mf_unixpath.c mf_strip.c \
mf_casecnv.c mf_soundex.c mf_wcomp.c mf_wfile.c \
mf_qsort.c mf_qsort2.c mf_sort.c \
ptr_cmp.c mf_radix.c queues.c \
@@ -47,23 +47,24 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
my_delete.c my_rename.c my_redel.c my_tempnam.c \
my_chsize.c my_lread.c my_lwrite.c my_clock.c \
my_quick.c my_lockmem.c my_static.c \
- getopt.c getopt1.c getvar.c my_mkdir.c \
- default.c my_compress.c checksum.c raid.cc raid2.c \
- my_net.c my_port.c \
- my_vsnprintf.c charset.c my_bitmap.c my_gethostbyname.c
+ my_sync.c my_getopt.c my_mkdir.c \
+ default.c my_compress.c checksum.c raid.cc \
+ my_net.c my_semaphore.c my_port.c my_sleep.c \
+ my_vsnprintf.c charset.c my_bitmap.c my_bit.c md5.c \
+ my_gethostbyname.c rijndael.c my_aes.c sha1.c \
+ my_netware.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c
libmysys_a_LIBADD = @THREAD_LOBJECTS@
-# test_fn removed 980815 since it not upp to date test_dir
-noinst_PROGRAMS = test_charset @THREAD_LPROGRAMS@
+# test_fn removed 980815 since it not up to date test_dir
+noinst_PROGRAMS = @THREAD_LPROGRAMS@
# test_dir_DEPENDENCIES= $(LIBRARIES)
# testhash_DEPENDENCIES= $(LIBRARIES)
-test_charset_DEPENDENCIES= $(LIBRARIES)
+# test_charset_DEPENDENCIES= $(LIBRARIES)
EXTRA_PROGRAMS =
DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \
-DDATADIR="\"$(MYSQLDATAdir)\"" \
-DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
- -DDATADIR="\"$(MYSQLDATAdir)\"" \
-DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
@DEFS@
@@ -77,28 +78,32 @@ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
# which automaticly removes the object files you use to compile a final program
#
-test_thr_alarm: thr_alarm.c $(LIBRARIES)
+test_thr_alarm$(EXEEXT): thr_alarm.c $(LIBRARIES)
$(CP) $(srcdir)/thr_alarm.c ./test_thr_alarm.c
$(LINK) $(FLAGS) -DMAIN ./test_thr_alarm.c $(LDADD) $(LIBS)
- $(RM) -f ./test_thr_alarm.*
+ $(RM) -f ./test_thr_alarm.c
-test_thr_lock: thr_lock.c $(LIBRARIES)
+test_thr_lock$(EXEEXT): thr_lock.c $(LIBRARIES)
$(CP) $(srcdir)/thr_lock.c test_thr_lock.c
$(LINK) $(FLAGS) -DMAIN ./test_thr_lock.c $(LDADD) $(LIBS)
- $(RM) -f ./test_thr_lock.*
+ $(RM) -f ./test_thr_lock.c
-test_vsnprintf: my_vsnprintf.c $(LIBRARIES)
+test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LIBRARIES)
$(CP) $(srcdir)/my_vsnprintf.c test_vsnprintf.c
$(LINK) $(FLAGS) -DMAIN ./test_vsnprintf.c $(LDADD) $(LIBS)
- $(RM) -f test_vsnprintf.*
+ $(RM) -f test_vsnprintf.c
+test_io_cache$(EXEEXT): mf_iocache.c $(LIBRARIES)
+ $(CP) $(srcdir)/mf_iocache.c test_io_cache.c
+ $(LINK) $(FLAGS) -DMAIN ./test_io_cache.c $(LDADD) $(LIBS)
+ $(RM) -f test_io_cache.c
-test_dir: test_dir.c $(LIBRARIES)
+test_dir$(EXEEXT): test_dir.c $(LIBRARIES)
$(LINK) $(FLAGS) -DMAIN $(srcdir)/test_dir.c $(LDADD) $(LIBS)
test_charset$(EXEEXT): test_charset.c $(LIBRARIES)
$(LINK) $(FLAGS) -DMAIN $(srcdir)/test_charset.c $(LDADD) $(LIBS)
-testhash: testhash.c $(LIBRARIES)
+testhash$(EXEEXT): testhash.c $(LIBRARIES)
$(LINK) $(FLAGS) -DMAIN $(srcdir)/testhash.c $(LDADD) $(LIBS)
# Don't update the files from bitkeeper
diff --git a/mysys/array.c b/mysys/array.c
index cc6710124d7..6d00585f24d 100644
--- a/mysys/array.c
+++ b/mysys/array.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Handling of arrays that can grow dynamicly. */
@@ -25,12 +24,28 @@
#include "m_string.h"
/*
- Initiate array and alloc space for init_alloc elements. Array is usable
- even if space allocation failed
+ Initiate dynamic array
+
+ SYNOPSIS
+ init_dynamic_array()
+ array Pointer to an array
+ element_size Size of element
+ init_alloc Number of initial elements
+ alloc_increment Increment for adding new elements
+
+ DESCRIPTION
+ init_dynamic_array() initiates array and allocate space for
+ init_alloc eilements.
+ Array is usable even if space allocation failed.
+
+ RETURN VALUE
+ TRUE my_malloc_ci() failed
+ FALSE Ok
*/
my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
- uint init_alloc, uint alloc_increment CALLER_INFO_PROTO)
+ uint init_alloc,
+ uint alloc_increment CALLER_INFO_PROTO)
{
DBUG_ENTER("init_dynamic_array");
if (!alloc_increment)
@@ -52,8 +67,20 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
DBUG_RETURN(TRUE);
}
DBUG_RETURN(FALSE);
-}
+}
+/*
+ Insert element at the end of array. Allocate memory if needed.
+
+ SYNOPSIS
+ insert_dynamic()
+ array
+ element
+
+ RETURN VALUE
+ TRUE Insert failed
+ FALSE Ok
+*/
my_bool insert_dynamic(DYNAMIC_ARRAY *array, gptr element)
{
@@ -73,7 +100,22 @@ my_bool insert_dynamic(DYNAMIC_ARRAY *array, gptr element)
}
- /* Alloc room for one element */
+/*
+ Alloc space for next element(s)
+
+ SYNOPSIS
+ alloc_dynamic()
+ array
+
+ DESCRIPTION
+ alloc_dynamic() checks if there is empty space for at least
+ one element if not tries to allocate space for alloc_increment
+ elements at the end of array.
+
+ RETURN VALUE
+ pointer Pointer to empty space for element
+ 0 Error
+*/
byte *alloc_dynamic(DYNAMIC_ARRAY *array)
{
@@ -92,7 +134,17 @@ byte *alloc_dynamic(DYNAMIC_ARRAY *array)
}
- /* remove last element from array and return it */
+/*
+ Pop last element from array.
+
+ SYNOPSIS
+ pop_dynamic()
+ array
+
+ RETURN VALUE
+ pointer Ok
+ 0 Array is empty
+*/
byte *pop_dynamic(DYNAMIC_ARRAY *array)
{
@@ -101,6 +153,23 @@ byte *pop_dynamic(DYNAMIC_ARRAY *array)
return 0;
}
+/*
+ Replace elemnent in array with given element and index
+
+ SYNOPSIS
+ set_dynamic()
+ array
+ element Element to be inserted
+ idx Index where element is to be inserted
+
+ DESCRIPTION
+ set_dynamic() replaces element in array.
+ If idx > max_element insert new element. Allocate memory if needed.
+
+ RETURN VALUE
+ TRUE Idx was out of range and allocation of new memory failed
+ FALSE Ok
+*/
my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
{
@@ -128,6 +197,15 @@ my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
return FALSE;
}
+/*
+ Get an element from array by given index
+
+ SYNOPSIS
+ get_dynamic()
+ array
+ gptr Element to be returned. If idx > elements contain zeroes.
+ idx Index of element wanted.
+*/
void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
{
@@ -143,6 +221,14 @@ void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
}
+/*
+ Empty array by freeing all memory
+
+ SYNOPSIS
+ delete_dynamic()
+ array Array to be deleted
+*/
+
void delete_dynamic(DYNAMIC_ARRAY *array)
{
if (array->buffer)
@@ -153,6 +239,14 @@ void delete_dynamic(DYNAMIC_ARRAY *array)
}
}
+/*
+ Delete element by given index
+
+ SYNOPSIS
+ delete_dynamic_element()
+ array
+ idx Index of element to be deleted
+*/
void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
{
@@ -163,6 +257,15 @@ void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
}
+/*
+ Free unused memory
+
+ SYNOPSIS
+ freeze_size()
+ array Array to be freed
+
+*/
+
void freeze_size(DYNAMIC_ARRAY *array)
{
uint elements=max(array->elements,1);
diff --git a/mysys/charset.c b/mysys/charset.c
index 4cd32e7e3da..5e5be9e1b42 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -44,13 +43,6 @@ struct simpleconfig_buf_st {
char *p;
};
-/* Defined in strings/ctype.c */
-
-CHARSET_INFO *find_compiled_charset(uint cs_number);
-uint compiled_charset_number(const char *name);
-const char *compiled_charset_name(uint charset_number);
-
-
static uint num_from_csname(CS_ID **cs, const char *name)
{
CS_ID **c;
@@ -110,7 +102,7 @@ char *get_charsets_dir(char *buf)
strxmov(buf, DEFAULT_CHARSET_HOME, "/", sharedir, "/", CHARSET_DIR,
NullS);
}
- convert_dirname(buf);
+ convert_dirname(buf,buf,NullS);
DBUG_PRINT("info",("charsets dir='%s'", buf));
DBUG_RETURN(strend(buf));
}
@@ -172,7 +164,11 @@ static my_bool read_charset_index(CS_ID ***charsets, myf myflags)
}
+#ifdef __NETWARE__
+my_bool STDCALL init_available_charsets(myf myflags)
+#else
static my_bool init_available_charsets(myf myflags)
+#endif
{
my_bool error=0;
/*
@@ -203,6 +199,7 @@ static my_bool init_available_charsets(myf myflags)
void free_charsets(void)
{
delete_dynamic(&cs_info_table);
+ charset_initialized=0;
}
@@ -264,22 +261,22 @@ static my_bool read_charset_file(uint cs_number, CHARSET_INFO *set,
uint get_charset_number(const char *charset_name)
{
- my_bool error;
- error = init_available_charsets(MYF(0)); /* If it isn't initialized */
- if (error)
- return compiled_charset_number(charset_name);
- else
- return num_from_csname(available_charsets, charset_name);
+ uint number=compiled_charset_number(charset_name);
+ if (number)
+ return number;
+ if (init_available_charsets(MYF(0))) /* If it isn't initialized */
+ return 0;
+ return num_from_csname(available_charsets, charset_name);
}
const char *get_charset_name(uint charset_number)
{
- my_bool error;
- error = init_available_charsets(MYF(0)); /* If it isn't initialized */
- if (error)
- return compiled_charset_name(charset_number);
- else
- return name_from_csnum(available_charsets, charset_number);
+ const char *name=compiled_charset_name(charset_number);
+ if (*name != '?')
+ return name;
+ if (init_available_charsets(MYF(0))) /* If it isn't initialized */
+ return "?";
+ return name_from_csnum(available_charsets, charset_number);
}
@@ -293,8 +290,8 @@ static CHARSET_INFO *find_charset(CHARSET_INFO **table, uint cs_number,
return NULL;
}
-static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table, const char *name,
- size_t tablesz)
+static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table,
+ const char *name, size_t tablesz)
{
uint i;
for (i = 0; i < tablesz; ++i)
@@ -303,7 +300,25 @@ static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table, const char *name
return NULL;
}
-static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name)
+/*
+ Read charset from file.
+
+ NOTES
+ One never has to deallocate character sets. They will all be deallocated
+ by my_once_free() when program ends.
+
+ If my_once_alloc() fails then this function may 'leak' some memory
+ which my_once_free() will deallocate, but this is so unlikely to happen
+ that this can be ignored.
+
+ RETURN
+ 0 Error
+ # Pointer to allocated charset structure
+*/
+
+
+static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name,
+ myf flags)
{
CHARSET_INFO tmp_cs,*cs;
uchar tmp_ctype[CTYPE_TABLE_SIZE];
@@ -318,29 +333,36 @@ static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name)
cs->to_lower=tmp_to_lower;
cs->to_upper=tmp_to_upper;
cs->sort_order=tmp_sort_order;
- if (read_charset_file(cs_number, cs, MYF(MY_WME)))
- return NULL;
-
- cs = (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),
- MYF(MY_WME));
- *cs=tmp_cs;
- cs->name = (char *) my_once_alloc((uint) strlen(cs_name)+1, MYF(MY_WME));
- cs->ctype = (uchar*) my_once_alloc(CTYPE_TABLE_SIZE, MYF(MY_WME));
- cs->to_lower = (uchar*) my_once_alloc(TO_LOWER_TABLE_SIZE, MYF(MY_WME));
- cs->to_upper = (uchar*) my_once_alloc(TO_UPPER_TABLE_SIZE, MYF(MY_WME));
+ cs->strxfrm_multiply=cs->mbmaxlen=1;
+ if (read_charset_file(cs_number, cs, flags))
+ return 0;
+
+ if (!(cs= (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),
+ MYF(MY_WME))))
+ return 0;
+
+ *cs= tmp_cs;
+ cs->name= (char *) my_once_alloc((uint) strlen(cs_name)+1, MYF(MY_WME));
+ cs->ctype= (uchar*) my_once_alloc(CTYPE_TABLE_SIZE, MYF(MY_WME));
+ cs->to_lower= (uchar*) my_once_alloc(TO_LOWER_TABLE_SIZE, MYF(MY_WME));
+ cs->to_upper= (uchar*) my_once_alloc(TO_UPPER_TABLE_SIZE, MYF(MY_WME));
cs->sort_order=(uchar*) my_once_alloc(SORT_ORDER_TABLE_SIZE, MYF(MY_WME));
- cs->number = cs_number;
- memcpy((char*) cs->name, (char*) cs_name, strlen(cs_name) + 1);
- memcpy((char*) cs->ctype, (char*) tmp_ctype, sizeof(tmp_ctype));
- memcpy((char*) cs->to_lower, (char*) tmp_to_lower, sizeof(tmp_to_lower));
- memcpy((char*) cs->to_upper, (char*) tmp_to_upper, sizeof(tmp_to_upper));
+ if (!cs->name || !cs->ctype || !cs->to_lower || !cs->to_upper ||
+ !cs->sort_order)
+ return 0;
+
+ cs->number= cs_number;
+ memcpy((char*) cs->name, (char*) cs_name, strlen(cs_name) + 1);
+ memcpy((char*) cs->ctype, (char*) tmp_ctype, sizeof(tmp_ctype));
+ memcpy((char*) cs->to_lower, (char*) tmp_to_lower, sizeof(tmp_to_lower));
+ memcpy((char*) cs->to_upper, (char*) tmp_to_upper, sizeof(tmp_to_upper));
memcpy((char*) cs->sort_order, (char*) tmp_sort_order,
sizeof(tmp_sort_order));
insert_dynamic(&cs_info_table, (gptr) &cs);
return cs;
}
-static CHARSET_INFO *get_internal_charset(uint cs_number)
+static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
{
CHARSET_INFO *cs;
/*
@@ -351,13 +373,13 @@ static CHARSET_INFO *get_internal_charset(uint cs_number)
if (!(cs = find_charset((CHARSET_INFO**) cs_info_table.buffer, cs_number,
cs_info_table.elements)))
if (!(cs = find_compiled_charset(cs_number)))
- cs=add_charset(cs_number, get_charset_name(cs_number));
+ cs=add_charset(cs_number, get_charset_name(cs_number), flags);
pthread_mutex_unlock(&THR_LOCK_charset);
return cs;
}
-static CHARSET_INFO *get_internal_charset_by_name(const char *name)
+static CHARSET_INFO *get_internal_charset_by_name(const char *name, myf flags)
{
CHARSET_INFO *cs;
/*
@@ -368,7 +390,7 @@ static CHARSET_INFO *get_internal_charset_by_name(const char *name)
if (!(cs = find_charset_by_name((CHARSET_INFO**) cs_info_table.buffer, name,
cs_info_table.elements)))
if (!(cs = find_compiled_charset_by_name(name)))
- cs=add_charset(get_charset_number(name), name);
+ cs=add_charset(get_charset_number(name), name, flags);
pthread_mutex_unlock(&THR_LOCK_charset);
return cs;
}
@@ -378,7 +400,7 @@ CHARSET_INFO *get_charset(uint cs_number, myf flags)
{
CHARSET_INFO *cs;
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
- cs=get_internal_charset(cs_number);
+ cs=get_internal_charset(cs_number, flags);
if (!cs && (flags & MY_WME))
{
@@ -410,7 +432,7 @@ CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags)
{
CHARSET_INFO *cs;
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
- cs=get_internal_charset_by_name(cs_name);
+ cs=get_internal_charset_by_name(cs_name, flags);
if (!cs && (flags & MY_WME))
{
@@ -455,20 +477,37 @@ static my_bool charset_in_string(const char *name, DYNAMIC_STRING *s)
static void charset_append(DYNAMIC_STRING *s, const char *name)
{
- if (!charset_in_string(name, s)) {
+ if (!charset_in_string(name, s))
+ {
dynstr_append(s, name);
dynstr_append(s, " ");
}
}
-/* Returns a dynamically-allocated string listing the character sets
- requested. The caller is responsible for freeing the memory. */
+/*
+ Returns a dynamically-allocated string listing the character sets
+ requested.
+
+ SYNOPSIS
+ list_charsets()
+ want_flags Flags for which character sets to return:
+ MY_COMPILED_SETS: Return incompiled charsets
+ MY_INDEX_SETS:
+ MY_LOADED_SETS:
+
+ NOTES
+ The caller is responsible for freeing the memory.
+
+
+ RETURN
+ A string with available character sets separated by space
+*/
char * list_charsets(myf want_flags)
{
DYNAMIC_STRING s;
- char *p;
+ char *result;
(void)init_available_charsets(MYF(0));
init_dynamic_string(&s, NullS, 256, 1024);
@@ -485,42 +524,45 @@ char * list_charsets(myf want_flags)
if (want_flags & MY_CONFIG_SETS)
{
- CS_ID **c;
+ CS_ID **charset;
char buf[FN_REFLEN];
MY_STAT status;
- if((c=available_charsets))
- for (; *c; ++c)
- {
- if (charset_in_string((*c)->name, &s))
- continue;
- get_charset_conf_name((*c)->number, buf);
- if (!my_stat(buf, &status, MYF(0)))
- continue; /* conf file doesn't exist */
- dynstr_append(&s, (*c)->name);
- dynstr_append(&s, " ");
- }
+ if ((charset=available_charsets))
+ {
+ for (; *charset; charset++)
+ {
+ if (charset_in_string((*charset)->name, &s))
+ continue;
+ get_charset_conf_name((*charset)->number, buf);
+ if (!my_stat(buf, &status, MYF(0)))
+ continue; /* conf file doesn't exist */
+ dynstr_append(&s, (*charset)->name);
+ dynstr_append(&s, " ");
+ }
+ }
}
if (want_flags & MY_INDEX_SETS)
{
- CS_ID **c;
- for (c = available_charsets; *c; ++c)
- charset_append(&s, (*c)->name);
+ CS_ID **charset;
+ for (charset = available_charsets; *charset; charset++)
+ charset_append(&s, (*charset)->name);
}
if (want_flags & MY_LOADED_SETS)
{
uint i;
for (i = 0; i < cs_info_table.elements; i++)
- charset_append(&s,
+ charset_append(&s,
dynamic_element(&cs_info_table, i, CHARSET_INFO *)->name);
}
- s.str[s.length - 1] = '\0'; /* chop trailing space */
- p = my_strdup(s.str, MYF(MY_WME));
+ if (s.length)
+ s.length--; /* Remove end space */
+ result= my_strdup_with_length(s.str, s.length, MYF(MY_WME));
dynstr_free(&s);
- return p;
+ return result;
}
/****************************************************************************
diff --git a/mysys/checksum.c b/mysys/checksum.c
index 00861853945..1dd135c7ad9 100644
--- a/mysys/checksum.c
+++ b/mysys/checksum.c
@@ -1,30 +1,37 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Calculate a long checksum for a memoryblock. Used to verify pack_isam */
-#include <global.h>
+#include <my_global.h>
#include "my_sys.h"
+/*
+ Calculate a long checksum for a memoryblock. Used to verify pack_isam
+
+ SYNOPSIS
+ checksum()
+ mem Pointer to memory block
+ count Count of bytes
+*/
+
ulong checksum(const byte *mem, uint count)
{
ulong crc;
- for (crc=0; count-- ; mem++)
- crc=((crc << 1) + *((uchar*) mem)) +
+ for (crc= 0; count-- ; mem++)
+ crc= ((crc << 1) + *((uchar*) mem)) +
test(crc & ((ulong) 1L << (8*sizeof(ulong)-1)));
return crc;
}
diff --git a/mysys/default.c b/mysys/default.c
index 0f8712d3298..3c9f9c823a1 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -1,40 +1,37 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/****************************************************************************
-** Add all options from files named "group".cnf from the default_directories
-** before the command line arguments.
-** On Windows defaults will also search in the Windows directory for a file
-** called 'group'.ini
-** As long as the program uses the last argument for conflicting
-** options one only have to add a call to "load_defaults" to enable
-** use of default values.
-** pre- and end 'blank space' are removed from options and values. The
-** following escape sequences are recognized in values: \b \t \n \r \\
-**
-** The following arguments are handled automaticly; If used, they must be
-** first argument on the command line!
-** --no-defaults ; no options are read.
-** --defaults-file=full-path-to-default-file ; Only this file will be read.
-** --defaults-extra-file=full-path-to-default-file ; Read this file before ~/
-** --print-defaults ; Print the modified command line and exit
-****************************************************************************/
+ Add all options from files named "group".cnf from the default_directories
+ before the command line arguments.
+ On Windows defaults will also search in the Windows directory for a file
+ called 'group'.ini
+ As long as the program uses the last argument for conflicting
+ options one only have to add a call to "load_defaults" to enable
+ use of default values.
+ pre- and end 'blank space' are removed from options and values. The
+ following escape sequences are recognized in values: \b \t \n \r \\
-#undef SAFEMALLOC /* safe_malloc is not yet initailized */
+ The following arguments are handled automaticly; If used, they must be
+ first argument on the command line!
+ --no-defaults ; no options are read.
+ --defaults-file=full-path-to-default-file ; Only this file will be read.
+ --defaults-extra-file=full-path-to-default-file ; Read this file before ~/
+ --print-defaults ; Print the modified command line and exit
+****************************************************************************/
#include "mysys_priv.h"
#include "m_string.h"
@@ -48,6 +45,8 @@ char *defaults_extra_file=0;
const char *default_directories[]= {
#ifdef __WIN__
"C:/",
+#elif defined(__NETWARE__)
+"sys:/etc/",
#else
"/etc/",
#endif
@@ -55,7 +54,7 @@ const char *default_directories[]= {
DATADIR,
#endif
"", /* Place for defaults_extra_dir */
-#ifndef __WIN__
+#if !defined(__WIN__) && !defined(__NETWARE__)
"~/",
#endif
NullS,
@@ -67,12 +66,46 @@ NullS,
#define windows_ext ".ini"
#endif
-static my_bool search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc,
- const char *dir, const char *config_file,
- const char *ext, TYPELIB *group);
+static int search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc,
+ const char *dir, const char *config_file,
+ const char *ext, TYPELIB *group);
+
+static char *remove_end_comment(char *ptr);
+
+
+/*
+ Read options from configurations files
+
+ SYNOPSIS
+ load_defaults()
+ conf_file Basename for configuration file to search for.
+ If this is a path, then only this file is read.
+ groups Which [group] entrys to read.
+ Points to an null terminated array of pointers
+ argc Pointer to argc of original program
+ argv Pointer to argv of original program
+
+ IMPLEMENTATION
+ Read options from configuration files and put them BEFORE the arguments
+ that are already in argc and argv. This way the calling program can
+ easily command line options override options in configuration files
-void load_defaults(const char *conf_file, const char **groups,
+ NOTES
+ In case of fatal error, the function will print a warning and do
+ exit(1)
+
+ To free used memory one should call free_defaults() with the argument
+ that was put in *argv
+
+ RETURN
+ 0 ok
+ 1 The given conf_file didn't exists
+ 2 The given conf_file was not a normal readable file
+*/
+
+
+int load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv)
{
DYNAMIC_ARRAY args;
@@ -80,11 +113,12 @@ void load_defaults(const char *conf_file, const char **groups,
TYPELIB group;
my_bool found_print_defaults=0;
uint args_used=0;
+ int error= 0;
MEM_ROOT alloc;
char *ptr,**res;
DBUG_ENTER("load_defaults");
- init_alloc_root(&alloc,128,0);
+ init_alloc_root(&alloc,512,0);
if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
{
/* remove the --no-defaults argument and return only the other arguments */
@@ -96,10 +130,11 @@ void load_defaults(const char *conf_file, const char **groups,
res[0]= **argv; /* Copy program name */
for (i=2 ; i < (uint) *argc ; i++)
res[i-1]=argv[0][i];
+ res[i-1]=0; /* End pointer */
(*argc)--;
*argv=res;
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
- DBUG_VOID_RETURN;
+ DBUG_RETURN(0);
}
/* Check if we want to force the use a specific default file */
@@ -128,14 +163,14 @@ void load_defaults(const char *conf_file, const char **groups,
goto err;
if (forced_default_file)
{
- if (search_default_file(&args, &alloc, "", forced_default_file, "",
- &group))
+ if ((error= search_default_file(&args, &alloc, "",
+ forced_default_file, "", &group)) < 0)
goto err;
}
else if (dirname_length(conf_file))
{
- if (search_default_file(&args, &alloc, NullS, conf_file, default_ext,
- &group))
+ if ((error= search_default_file(&args, &alloc, NullS, conf_file,
+ default_ext, &group)) < 0)
goto err;
}
else
@@ -143,29 +178,36 @@ void load_defaults(const char *conf_file, const char **groups,
#ifdef __WIN__
char system_dir[FN_REFLEN];
GetWindowsDirectory(system_dir,sizeof(system_dir));
- if (search_default_file(&args, &alloc, system_dir, conf_file, windows_ext,
- &group))
+ if ((search_default_file(&args, &alloc, system_dir, conf_file,
+ windows_ext, &group)))
goto err;
#endif
#if defined(__EMX__) || defined(OS2)
if (getenv("ETC") &&
- search_default_file(&args, &alloc, getenv("ETC"), conf_file,
- default_ext, &group))
+ (search_default_file(&args, &alloc, getenv("ETC"), conf_file,
+ default_ext, &group)) < 0)
goto err;
#endif
for (dirs=default_directories ; *dirs; dirs++)
{
- int error=0;
if (**dirs)
- error=search_default_file(&args, &alloc, *dirs, conf_file,
- default_ext, &group);
+ {
+ if (search_default_file(&args, &alloc, *dirs, conf_file,
+ default_ext, &group) < 0)
+ goto err;
+ }
else if (defaults_extra_file)
- error=search_default_file(&args, &alloc, NullS, defaults_extra_file,
- default_ext, &group);
- if (error)
- goto err;
+ {
+ if (search_default_file(&args, &alloc, NullS, defaults_extra_file,
+ default_ext, &group) < 0)
+ goto err; /* Fatal error */
+ }
}
}
+ /*
+ Here error contains <> 0 only if we have a fully specified conf_file
+ or a forced default file
+ */
if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
(args.elements + *argc +1) *sizeof(char*))))
goto err;
@@ -201,12 +243,12 @@ void load_defaults(const char *conf_file, const char **groups,
for (i=1 ; i < *argc ; i++)
printf("%s ", (*argv)[i]);
puts("");
- exit(1);
+ exit(0);
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(error);
err:
- fprintf(stderr,"Program aborted\n");
+ fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
exit(1);
}
@@ -219,9 +261,28 @@ void free_defaults(char **argv)
}
-static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
- const char *dir, const char *config_file,
- const char *ext, TYPELIB *group)
+/*
+ Open a configuration file (if exists) and read given options from it
+
+ SYNOPSIS
+ search_default_file()
+ args Store pointer to found options here
+ alloc Allocate strings in this object
+ dir directory to read
+ config_file Name of configuration file
+ ext Extension for configuration file
+ group groups to read
+
+ RETURN
+ 0 Success
+ -1 Fatal error, abort
+ 1 File not found (Warning)
+ 2 File is not a regular file (Warning)
+*/
+
+static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
+ const char *dir, const char *config_file,
+ const char *ext, TYPELIB *group)
{
char name[FN_REFLEN+10],buff[4096],*ptr,*end,*value,*tmp;
FILE *fp;
@@ -232,23 +293,28 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
return 0; /* Ignore wrong paths */
if (dir)
{
- strmov(name,dir);
- convert_dirname(name);
+ end=convert_dirname(name, dir, NullS);
if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */
- strcat(name,".");
- strxmov(strend(name),config_file,ext,NullS);
+ *end++='.';
+ strxmov(end,config_file,ext,NullS);
}
else
{
strmov(name,config_file);
}
fn_format(name,name,"","",4);
-#if !defined(__WIN__) && !defined(OS2)
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
{
MY_STAT stat_info;
if (!my_stat(name,&stat_info,MYF(0)))
- return 0;
- if (stat_info.st_mode & S_IWOTH) /* ignore world-writeable files */
+ return 1;
+ /*
+ Ignore world-writable regular files.
+ This is mainly done to protect us to not read a file created by
+ the mysqld server, but the check is still valid in most context.
+ */
+ if ((stat_info.st_mode & S_IWOTH) &&
+ (stat_info.st_mode & S_IFMT) == S_IFREG)
{
fprintf(stderr, "warning: World-writeable config file %s is ignored\n",
name);
@@ -290,9 +356,11 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
}
if (!read_values)
continue;
- if (!(end=value=strchr(ptr,'=')))
- end=strend(ptr); /* Option without argument */
+ end= remove_end_comment(ptr);
+ if ((value= strchr(ptr, '=')))
+ end= value; /* Option without argument */
for ( ; isspace(end[-1]) ; end--) ;
+
if (!value)
{
if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3)))
@@ -307,9 +375,20 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
char *value_end;
for (value++ ; isspace(*value); value++) ;
value_end=strend(value);
+ /*
+ We don't have to test for value_end >= value as we know there is
+ an '=' before
+ */
for ( ; isspace(value_end[-1]) ; value_end--) ;
if (value_end < value) /* Empty string */
value_end=value;
+
+ /* remove quotes around argument */
+ if ((*value == '\"' || *value == '\'') && *value == value_end[-1])
+ {
+ value++;
+ value_end--;
+ }
if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3 +
(uint) (value_end-value)+1)))
goto err;
@@ -317,6 +396,7 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
goto err;
ptr=strnmov(strmov(tmp,"--"),ptr,(uint) (end-ptr));
*ptr++= '=';
+
for ( ; value != value_end; value++)
{
if (*value == '\\' && value != value_end-1)
@@ -337,6 +417,12 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
case 's':
*ptr++= ' '; /* space */
break;
+ case '\"':
+ *ptr++= '\"';
+ break;
+ case '\'':
+ *ptr++= '\'';
+ break;
case '\\':
*ptr++= '\\';
break;
@@ -357,7 +443,30 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
err:
my_fclose(fp,MYF(0));
- return 1;
+ return -1; /* Fatal error */
+}
+
+
+static char *remove_end_comment(char *ptr)
+{
+ char quote= 0;
+
+ for (; *ptr; ptr++)
+ {
+ if (*ptr == '\'' || *ptr == '\"')
+ {
+ if (!quote)
+ quote= *ptr;
+ else if (quote == *ptr)
+ quote= 0;
+ }
+ if (!quote && *ptr == '#') /* We are not inside a comment */
+ {
+ *ptr= 0;
+ return ptr;
+ }
+ }
+ return ptr;
}
@@ -384,16 +493,18 @@ void print_defaults(const char *conf_file, const char **groups)
#endif
for (dirs=default_directories ; *dirs; dirs++)
{
+ const char *pos;
+ char *end;
if (**dirs)
- strmov(name,*dirs);
+ pos= *dirs;
else if (defaults_extra_file)
- strmov(name,defaults_extra_file);
+ pos= defaults_extra_file;
else
continue;
- convert_dirname(name);
+ end=convert_dirname(name, pos, NullS);
if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
- strcat(name,".");
- strxmov(strend(name),conf_file,default_ext," ",NullS);
+ *end++='.';
+ strxmov(end,conf_file,default_ext," ",NullS);
fputs(name,stdout);
}
puts("");
@@ -410,4 +521,3 @@ void print_defaults(const char *conf_file, const char **groups)
--defaults-file=# Only read default options from the given file #\n\
--defaults-extra-file=# Read this file after the global files are read");
}
-
diff --git a/mysys/errors.c b/mysys/errors.c
index 77e52c2f0b3..7d755718b16 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -49,6 +48,7 @@ const char * NEAR globerrs[GLOBERRS]=
"Can't read value for symlink '%s' (Error %d)",
"Can't create symlink '%s' pointing at '%s' (Error %d)",
"Error on realpath() on '%s' (Error %d)",
+ "Can't sync file '%s' to disk (Errcode: %d)",
};
void init_glob_errs(void)
@@ -85,8 +85,9 @@ void init_glob_errs()
EE(EE_CANT_MKDIR) ="Can't create directory '%s' (Errcode: %d)";
EE(EE_UNKNOWN_CHARSET)= "Character set is not a compiled character set and is not specified in the %s file";
EE(EE_OUT_OF_FILERESOURCES)="Out of resources when opening file '%s' (Errcode: %d)";
- EE(EE_CANT_READLINK)="Can't read value for symlink '%s' (Error %d)";
- EE(EE_CANT_SYMLINK)="Can't create symlink '%s' pointing at '%s' (Error %d)";
- EE(EE_REALPATH)="Error on realpath() on '%s' (Error %d)";
+ EE(EE_CANT_READLINK)= "Can't read value for symlink '%s' (Error %d)";
+ EE(EE_CANT_SYMLINK)= "Can't create symlink '%s' pointing at '%s' (Error %d)";
+ EE(EE_REALPATH)= "Error on realpath() on '%s' (Error %d)";
+ EE(EE_SYNC)= "Can't sync file '%s' to disk (Errcode: %d)";
}
#endif
diff --git a/mysys/getopt.c b/mysys/getopt.c
deleted file mode 100644
index 774cf3b82f4..00000000000
--- a/mysys/getopt.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/* Getopt for GNU.
- NOTE: getopt is now part of the C library, so if you don't know what
- "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
- before changing it!
-
- Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
- Free Software Foundation, Inc.
-
-Changes by monty:
-- Added include of string.h when nessessary.
-- Removed two warnings from gcc.
-
-This file is part of the GNU C Library. Its master source is NOT part of
-the C library, however. The master source lives in /gd/gnu/lib.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
- Ditto for AIX 3.2 and <stdlib.h>. */
-#ifndef _NO_PROTO
-#define _NO_PROTO
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if (!defined (__STDC__) || !__STDC__) && !defined(MSDOS) && !defined(OS2)
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <global.h> /* Changes for mysys */
-#include <m_string.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
-
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
- contain conflicting prototypes for getopt. */
-#include <stdlib.h>
-#endif /* GNU C library. */
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
- but it behaves differently for the user, since it allows the user
- to intersperse the options with the other arguments.
-
- As `getopt' works, it permutes the elements of ARGV so that,
- when it is done, all the options precede everything else. Thus
- all application programs are extended to handle flexible argument order.
-
- Setting the environment variable POSIXLY_CORRECT disables permutation.
- Then the behavior is completely standard.
-
- GNU application programs can use a third alternative mode in which
- they can distinguish the relative order of options and other arguments. */
-
-#include "getopt.h"
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-char *optarg = NULL;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns EOF, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-/* XXX 1003.2 says this must be 1 before any call. */
-int optind = 1;
-
-/* The next char to be scanned in the option-element
- in which the last option character we returned was found.
- This allows us to pick up the scan where we left off.
-
- If this is zero, or a null string, it means resume the scan
- by advancing to the next ARGV-element. */
-
-static char *nextchar;
-
-/* Callers store zero here to inhibit the error message
- for unrecognized options. */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
- This must be initialized on some systems to avoid linking in the
- system's own getopt implementation. */
-
-int optopt = '?';
-
-/* Describe how to deal with options that follow non-option ARGV-elements.
-
- If the caller did not specify anything,
- the default is REQUIRE_ORDER if the environment variable
- POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options;
- stop option processing when the first non-option is seen.
- This is what Unix does.
- This mode of operation is selected by either setting the environment
- variable POSIXLY_CORRECT, or using `+' as the first character
- of the list of option characters.
-
- PERMUTE is the default. We permute the contents of ARGV as we scan,
- so that eventually all the non-options are at the end. This allows options
- to be given in any order, even with programs that were not written to
- expect this.
-
- RETURN_IN_ORDER is an option available to programs that were written
- to expect options and other ARGV-elements in any order and that care about
- the ordering of the two. We describe each non-option ARGV-element
- as if it were the argument of an option with character code 1.
- Using `-' as the first character of the list of option characters
- selects this mode of operation.
-
- The special argument `--' forces an end of option-scanning regardless
- of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- `--' can cause `getopt' to return EOF with `optind' != ARGC. */
-
-static enum
-{
- REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-
-/* Value of POSIXLY_CORRECT environment variable. */
-static char *posixly_correct;
-
-#ifdef __GNU_LIBRARY__
-/* We want to avoid inclusion of string.h with non-GNU libraries
- because there are many ways it can cause trouble.
- On some systems, it contains special magic macros that don't work
- in GCC. */
-#include <string.h>
-#define my_index strchr
-#else
-
-/* Avoid depending on library functions or files
- whose names are inconsistent. */
-
-#ifndef OS2
-char *getenv (const char *);
-#endif
-
-static char *
-my_index (const char *str, int chr)
-{
- while (*str)
- {
- if (*str == chr)
- return (char *) str;
- str++;
- }
- return 0;
-}
-
-/* If using GCC, we can safely declare strlen this way.
- If not using GCC, it is ok not to declare it. */
-#ifdef __GNUC__
-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
- That was relevant to code that was here before. */
-#if !defined (__STDC__) || !__STDC__
-/* gcc with -traditional declares the built-in strlen to return int,
- and has done so at least since version 2.4.5. -- rms. */
-extern int strlen (const char *);
-#endif /* not __STDC__ */
-#endif /* __GNUC__ */
-
-#endif /* not __GNU_LIBRARY__ */
-
-/* Handle permutation of arguments. */
-
-/* Describe the part of ARGV that contains non-options that have
- been skipped. `first_nonopt' is the index in ARGV of the first of them;
- `last_nonopt' is the index after the last of them. */
-
-static int first_nonopt;
-static int last_nonopt;
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,optind), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved. */
-
-static void
-exchange (char **argv)
-{
- int bottom = first_nonopt;
- int middle = last_nonopt;
- int top = optind;
- char *tem;
-
- /* Exchange the shorter segment with the far end of the longer segment.
- That puts the shorter segment into the right place.
- It leaves the longer segment in the right place overall,
- but it consists of two parts that need to be swapped next. */
-
- while (top > middle && middle > bottom)
- {
- if (top - middle > middle - bottom)
- {
- /* Bottom segment is the short one. */
- int len = middle - bottom;
- register int i;
-
- /* Swap it with the top part of the top segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[top - (middle - bottom) + i];
- argv[top - (middle - bottom) + i] = tem;
- }
- /* Exclude the moved bottom segment from further swapping. */
- top -= len;
- }
- else
- {
- /* Top segment is the short one. */
- int len = top - middle;
- register int i;
-
- /* Swap it with the bottom part of the bottom segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[middle + i];
- argv[middle + i] = tem;
- }
- /* Exclude the moved top segment from further swapping. */
- bottom += len;
- }
- }
-
- /* Update records for the slots the non-options now occupy. */
-
- first_nonopt += (optind - last_nonopt);
- last_nonopt = optind;
-}
-
-/* Initialize the internal data when the first call is made. */
-
-static const char *
-_getopt_initialize (const char *optstring)
-{
- /* Start processing options with ARGV-element 1 (since ARGV-element 0
- is the program name); the sequence of previously skipped
- non-option ARGV-elements is empty. */
-
- first_nonopt = last_nonopt = optind = 1;
-
- nextchar = NULL;
-
- posixly_correct = getenv ("POSIXLY_CORRECT");
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-')
- {
- ordering = RETURN_IN_ORDER;
- ++optstring;
- }
- else if (optstring[0] == '+')
- {
- ordering = REQUIRE_ORDER;
- ++optstring;
- }
- else if (posixly_correct != NULL)
- ordering = REQUIRE_ORDER;
- else
- ordering = PERMUTE;
-
- return optstring;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
- given in OPTSTRING.
-
- If an element of ARGV starts with '-', and is not exactly "-" or "--",
- then it is an option element. The characters of this element
- (aside from the initial '-') are option characters. If `getopt'
- is called repeatedly, it returns successively each of the option characters
- from each of the option elements.
-
- If `getopt' finds another option character, it returns that character,
- updating `optind' and `nextchar' so that the next call to `getopt' can
- resume the scan with the following option character or ARGV-element.
-
- If there are no more option characters, `getopt' returns `EOF'.
- Then `optind' is the index in ARGV of the first ARGV-element
- that is not an option. (The ARGV-elements have been permuted
- so that those that are not options now come last.)
-
- OPTSTRING is a string containing the legitimate option characters.
- If an option character is seen that is not listed in OPTSTRING,
- return '?' after printing an error message. If you set `opterr' to
- zero, the error message is suppressed but we still return '?'.
-
- If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- so the following text in the same ARGV-element, or the text of the following
- ARGV-element, is returned in `optarg'. Two colons mean an option that
- wants an optional arg; if there is text in the current ARGV-element,
- it is returned in `optarg', otherwise `optarg' is set to zero.
-
- If OPTSTRING starts with `-' or `+', it requests different methods of
- handling the non-option ARGV-elements.
- See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
- Long-named options begin with `--' instead of `-'.
- Their names may be abbreviated as long as the abbreviation is unique
- or is an exact match for some defined option. If they have an
- argument, it follows the option name in the same ARGV-element, separated
- from the option name by a `=', or else the in next ARGV-element.
- When `getopt' finds a long-named option, it returns 0 if that option's
- `flag' field is nonzero, the value of the option's `val' field
- if the `flag' field is zero.
-
- The elements of ARGV aren't really const, because we permute them.
- But we pretend they're const in the prototype to be compatible
- with other systems.
-
- LONGOPTS is a vector of `struct option' terminated by an
- element containing a name which is zero.
-
- LONGIND returns the index in LONGOPT of the long-named option found.
- It is only valid when a long-named option has been found by the most
- recent call.
-
- If LONG_ONLY is nonzero, '-' as well as '--' can introduce
- long-named options. */
-
-int
-_getopt_internal (int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longind, int long_only)
-{
- optarg = NULL;
-
- if (optind == 0)
- optstring = _getopt_initialize (optstring);
-
- if (nextchar == NULL || *nextchar == '\0')
- {
- /* Advance to the next ARGV-element. */
-
- if (ordering == PERMUTE)
- {
- /* If we have just processed some options following some non-options,
- exchange them so that the options come first. */
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange ((char **) argv);
- else if (last_nonopt != optind)
- first_nonopt = optind;
-
- /* Skip any additional non-options
- and extend the range of non-options previously skipped. */
-
- while (optind < argc
- && (argv[optind][0] != '-' || argv[optind][1] == '\0'))
- optind++;
- last_nonopt = optind;
- }
-
- /* The special ARGV-element `--' means premature end of options.
- Skip it like a null option,
- then exchange with previous non-options as if it were an option,
- then skip everything else like a non-option. */
-
- if (optind != argc && !strcmp (argv[optind], "--"))
- {
- optind++;
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange ((char **) argv);
- else if (first_nonopt == last_nonopt)
- first_nonopt = optind;
- last_nonopt = argc;
-
- optind = argc;
- }
-
- /* If we have done all the ARGV-elements, stop the scan
- and back over any non-options that we skipped and permuted. */
-
- if (optind == argc)
- {
- /* Set the next-arg-index to point at the non-options
- that we previously skipped, so the caller will digest them. */
- if (first_nonopt != last_nonopt)
- optind = first_nonopt;
- return EOF;
- }
-
- /* If we have come to a non-option and did not permute it,
- either stop the scan or describe it to the caller and pass it by. */
-
- if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
- {
- if (ordering == REQUIRE_ORDER)
- return EOF;
- optarg = argv[optind++];
- return 1;
- }
-
- /* We have found another option-ARGV-element.
- Skip the initial punctuation. */
-
- nextchar = (argv[optind] + 1
- + (longopts != NULL && argv[optind][1] == '-'));
- }
-
- /* Decode the current option-ARGV-element. */
-
- /* Check whether the ARGV-element is a long option.
-
- If long_only and the ARGV-element has the form "-f", where f is
- a valid short option, don't consider it an abbreviated form of
- a long option that starts with f. Otherwise there would be no
- way to give the -f short option.
-
- On the other hand, if there's a long option "fubar" and
- the ARGV-element is "-fu", do consider that an abbreviation of
- the long option, just like "--fu", and not "-f" with arg "u".
-
- This distinction seems to be the most useful approach. */
-
- if (longopts != NULL
- && (argv[optind][1] == '-'
- || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
- {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound=0; /* Keep gcc happy */
- int option_index;
-
- for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp (p->name, nextchar, nameend - nextchar))
- {
- if ((size_t) (nameend - nextchar) == (size_t) strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else
- /* Second or later nonexact match found. */
- ambig = 1;
- }
-
- if (ambig && !exact)
- {
- if (opterr)
- fprintf (stderr, "%s: option `%s' is ambiguous\n",
- argv[0], argv[optind]);
- nextchar += strlen (nextchar);
- optind++;
- return '?';
- }
-
- if (pfound != NULL)
- {
- option_index = indfound;
- optind++;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- optarg = nameend + 1;
- else
- {
- if (opterr)
- {
- if (argv[optind - 1][1] == '-')
- /* --option */
- fprintf (stderr,
- "%s: option `--%s' doesn't allow an argument\n",
- argv[0], pfound->name);
- else
- /* +option or -option */
- fprintf (stderr,
- "%s: option `%c%s' doesn't allow an argument\n",
- argv[0], argv[optind - 1][0], pfound->name);
- }
- nextchar += strlen (nextchar);
- return '?';
- }
- }
- else if (pfound->has_arg == 1)
- {
- if (optind < argc)
- optarg = argv[optind++];
- else
- {
- if (opterr)
- fprintf (stderr, "%s: option `%s' requires an argument\n",
- argv[0], argv[optind - 1]);
- nextchar += strlen (nextchar);
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- nextchar += strlen (nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
-
- /* Can't find it as a long option. If this is not getopt_long_only,
- or the option starts with '--' or is not a valid short
- option, then it's an error.
- Otherwise interpret it as a short option. */
- if (!long_only || argv[optind][1] == '-'
- || my_index (optstring, *nextchar) == NULL)
- {
- if (opterr)
- {
- if (argv[optind][1] == '-')
- /* --option */
- fprintf (stderr, "%s: unrecognized option `--%s'\n",
- argv[0], nextchar);
- else
- /* +option or -option */
- fprintf (stderr, "%s: unrecognized option `%c%s'\n",
- argv[0], argv[optind][0], nextchar);
- }
- nextchar = (char *) "";
- optind++;
- return '?';
- }
- }
-
- /* Look at and handle the next short option-character. */
-
- {
- char c = *nextchar++;
- char *temp = my_index (optstring, c);
-
- /* Increment `optind' when we start to process its last character. */
- if (*nextchar == '\0')
- ++optind;
-
- if (temp == NULL || c == ':')
- {
- if (opterr)
- {
- if (posixly_correct)
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
- else
- fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
- }
- optopt = c;
- return '?';
- }
- if (temp[1] == ':')
- {
- if (temp[2] == ':')
- {
- /* This is an option that accepts an argument optionally. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- optind++;
- }
- else
- optarg = NULL;
- nextchar = NULL;
- }
- else
- {
- /* This is an option that requires an argument. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- optind++;
- }
- else if (optind == argc)
- {
- if (opterr)
- {
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, "%s: option requires an argument -- %c\n",
- argv[0], c);
- }
- optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- }
- else
- /* We already incremented `optind' once;
- increment it again when taking next ARGV-elt as argument. */
- optarg = argv[optind++];
- nextchar = NULL;
- }
- }
- return c;
- }
-}
-
-#ifdef __EMX__
-int getopt (int argc, char **argv, __const__ char *optstring)
-#else
-int
-getopt (int argc, char *const *argv, const char *optstring)
-#endif
-{
- return _getopt_internal (argc, argv, optstring,
- (const struct option *) 0,
- (int *) 0,
- 0);
-}
-
-#endif /* _LIBC or not __GNU_LIBRARY__. */
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
- the above definition of `getopt'. */
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
-
- c = getopt (argc, argv, "abc:d:0123456789");
- if (c == EOF)
- break;
-
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
diff --git a/mysys/getopt1.c b/mysys/getopt1.c
deleted file mode 100644
index bff76d6e5b2..00000000000
--- a/mysys/getopt1.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* getopt_long and getopt_long_only entry points for GNU getopt.
- Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994
- Free Software Foundation, Inc.
-
-This file is part of the GNU C Library. Its master source is NOT part of
-the C library, however. The master source lives in /gd/gnu/lib.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <global.h>
-#include "getopt.h"
-
-#if (!defined (__STDC__) || !__STDC__) && !defined(MSDOS) && !defined(OS2)
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
-
-#ifndef __WIN__
-#include <stdlib.h>
-#endif /* __WIN__ */
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-int
-getopt_long (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index)
-{
- return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
-}
-
-/* Like getopt_long, but '-' as well as '--' can indicate a long option.
- If an option that starts with '-' (not '--') doesn't match a long option,
- but does match a short option, it is parsed as a short option
- instead. */
-
-int
-getopt_long_only (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index)
-{
- return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
-}
-
-
-#endif /* _LIBC or not __GNU_LIBRARY__. */
-
-#ifdef TEST
-
-#include <stdio.h>
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
- int option_index = 0;
- static struct option long_options[] =
- {
- {"add", 1, 0, 0},
- {"append", 0, 0, 0},
- {"delete", 1, 0, 0},
- {"verbose", 0, 0, 0},
- {"create", 0, 0, 0},
- {"file", 1, 0, 0},
- {0, 0, 0, 0}
- };
-
- c = getopt_long (argc, argv, "abc:d:0123456789",
- long_options, &option_index);
- if (c == EOF)
- break;
-
- switch (c)
- {
- case 0:
- printf ("option %s", long_options[option_index].name);
- if (optarg)
- printf (" with arg %s", optarg);
- printf ("\n");
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case 'd':
- printf ("option d with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
diff --git a/mysys/getvar.c b/mysys/getvar.c
deleted file mode 100644
index 90ab599244d..00000000000
--- a/mysys/getvar.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* Allow use of the -O variable= option to set long variables */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#include <m_ctype.h>
-
- /* set all changeable variables */
-
-void set_all_changeable_vars(CHANGEABLE_VAR *vars)
-{
- for ( ; vars->name ; vars++)
- *vars->varptr= vars->def_value;
-}
-
-
-my_bool set_changeable_varval(const char* var, ulong val,
- CHANGEABLE_VAR *vars)
-{
- char buffer[256];
- sprintf( buffer, "%s=%lu", var, (unsigned long) val );
- return set_changeable_var( buffer, vars );
-}
-
-
-my_bool set_changeable_var(my_string str,CHANGEABLE_VAR *vars)
-{
- char endchar;
- my_string end;
- DBUG_ENTER("set_changeable_var");
- DBUG_PRINT("enter",("%s",str));
-
- if (str)
- {
- if (!(end=strchr(str,'=')))
- fprintf(stderr,"Can't find '=' in expression '%s' to option -O\n",str);
- else
- {
- uint length,found_count=0;
- CHANGEABLE_VAR *var,*found;
- my_string var_end;
- const char *name;
- longlong num;
-
- /* Skip end space from variable */
- for (var_end=end ; end > str && isspace(var_end[-1]) ; var_end--) ;
- length=(uint) (var_end-str);
- /* Skip start space from argument */
- for (end++ ; isspace(*end) ; end++) ;
-
- for (var=vars,found=0 ; (name=var->name) ; var++)
- {
- if (!my_casecmp(name,str,length))
- {
- found=var; found_count++;
- if (!name[length])
- {
- found_count=1;
- break;
- }
- }
- }
- if (found_count == 0)
- {
- fprintf(stderr,"No variable match for: -O '%s'\n",str);
- DBUG_RETURN(1);
- }
- if (found_count > 1)
- {
- fprintf(stderr,"Variable prefix '%*s' is not unique\n",length,str);
- DBUG_RETURN(1);
- }
-
- num=strtoll(end, (char **)NULL, 10); endchar=strend(end)[-1];
- if (endchar == 'k' || endchar == 'K')
- num*=1024;
- else if (endchar == 'm' || endchar == 'M')
- num*=1024L*1024L;
- else if (endchar == 'g' || endchar == 'G')
- num*=1024L*1024L*1024L;
- else if (!isdigit(endchar))
- {
- fprintf(stderr,"Unknown prefix used for variable value '%s'\n",str);
- DBUG_RETURN(1);
- }
- if (num < (longlong) found->min_value)
- num=(longlong) found->min_value;
- else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) found->max_value)
- num=(longlong) (ulong) found->max_value;
- num=((num- (longlong) found->sub_size) / (ulonglong) found->block_size);
- (*found->varptr)= (long) (num*(ulonglong) found->block_size);
- DBUG_RETURN(0);
- }
- }
- DBUG_RETURN(1);
-}
diff --git a/mysys/hash.c b/mysys/hash.c
index 602823e6d43..3afd31a079b 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* The hash functions used for saveing keys */
/* One of key_length or key_length_offset must be given */
@@ -153,9 +152,7 @@ static uint calc_hashnr_caseup(const byte *key,uint length)
*
* The magic is in the interesting relationship between the special prime
* 16777619 (2^24 + 403) and 2^32 and 2^8.
- *
- * This hash produces the fewest collisions of any function that we've seen so
- * far, and works well on both numbers and strings.
+ * This works well on both numbers and strings.
*/
uint calc_hashnr(const byte *key, uint len)
@@ -522,8 +519,8 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length)
/* Search after record with key */
idx=hash_mask((*hash->calc_hashnr)(old_key,(old_key_length ?
- old_key_length :
- hash->key_length)),
+ old_key_length :
+ hash->key_length)),
blength,records);
new_index=hash_mask(rec_hashnr(hash,record),blength,records);
if (idx == new_index)
@@ -583,6 +580,18 @@ byte *hash_element(HASH *hash,uint idx)
}
+/*
+ Replace old row with new row. This should only be used when key
+ isn't changed
+*/
+
+void hash_replace(HASH *hash, uint idx, byte *new_row)
+{
+ if (idx != NO_RECORD) /* Safety */
+ dynamic_element(&hash->array,idx,HASH_LINK*)->data=new_row;
+}
+
+
#ifndef DBUG_OFF
my_bool hash_check(HASH *hash)
diff --git a/mysys/list.c b/mysys/list.c
index c9c863d4cc2..ac9e1b979a0 100644
--- a/mysys/list.c
+++ b/mysys/list.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Code for handling dubble-linked lists in C
diff --git a/mysys/make-conf.c b/mysys/make-conf.c
index 9db766574e2..404299e1726 100644
--- a/mysys/make-conf.c
+++ b/mysys/make-conf.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* make-conf.c
* make a charset .conf file out of a ctype-charset.c file.
@@ -34,7 +33,7 @@
#define CH_INCLUDE STRINGIZE(CH_SRC)
/* aaaah, that's better */
-#include <my_global.h>
+#include <my_my_global.h>
#include CH_INCLUDE
#include <stdio.h>
diff --git a/mysys/md5.c b/mysys/md5.c
new file mode 100644
index 00000000000..5de95288141
--- /dev/null
+++ b/mysys/md5.c
@@ -0,0 +1,369 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+*/
+
+/*
+ Changes by Monty:
+ Replace of MD5_memset and MD5_memcpy with memset & memcpy
+*/
+
+#include <my_global.h>
+#include <m_string.h>
+#include "md5.h"
+
+/* Constants for MD5Transform routine. */
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+ ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+ ((UINT4 *, unsigned char *, unsigned int));
+#ifdef OLD_CODE
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+#else
+#define MD5_memcpy(A,B,C) memcpy((char*) (A),(char*) (B), (C))
+#define MD5_memset(A,B,C) memset((char*) (A),(B), (C))
+#endif
+
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void my_MD5Init (my_MD5_CTX *context) /* context */
+{
+ context->count[0] = context->count[1] = 0;
+ /* Load magic initialization constants.
+*/
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+
+void my_MD5Update (
+my_MD5_CTX *context, /* context */
+unsigned char *input, /* input block */
+unsigned int inputLen) /* length of input block */
+{
+ unsigned int i, idx, partLen;
+
+ /* Compute number of bytes mod 64 */
+ idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3))
+ < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - idx;
+
+ /* Transform as many times as possible.
+*/
+ if (inputLen >= partLen) {
+ MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen);
+ MD5Transform(context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+
+ idx = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i],
+ inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ */
+
+void my_MD5Final (
+unsigned char digest[16], /* message digest */
+my_MD5_CTX *context) /* context */
+{
+ unsigned char bits[8];
+ unsigned int idx, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64.
+*/
+ idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (idx < 56) ? (56 - idx) : (120 - idx);
+ my_MD5Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ my_MD5Update (context, bits, 8);
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information.
+*/
+ MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (
+UINT4 state[4],
+unsigned char block[64])
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information.
+*/
+ MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+ a multiple of 4.
+ */
+static void Encode (
+unsigned char *output,
+UINT4 *input,
+unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+ a multiple of 4.
+ */
+static void Decode (
+UINT4 *output,
+unsigned char *input,
+unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+
+#ifndef MD5_memcpy
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ output[i] = input[i];
+}
+#endif
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+
+#ifndef MD5_memset
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}
+#endif
diff --git a/mysys/mf_brkhant.c b/mysys/mf_brkhant.c
index debf5d9a712..4180bd6df66 100644
--- a/mysys/mf_brkhant.c
+++ b/mysys/mf_brkhant.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Dont let the user break when you are doing something important */
/* Remembers if it got 'SIGINT' and executes it on allow_break */
diff --git a/mysys/mf_cache.c b/mysys/mf_cache.c
index 85b6b19b328..2c5d8658625 100644
--- a/mysys/mf_cache.c
+++ b/mysys/mf_cache.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Open a temporary file and cache it with io_cache. Delete it on close */
diff --git a/mysys/mf_casecnv.c b/mysys/mf_casecnv.c
index 125f54b2594..c037cbd0f16 100644
--- a/mysys/mf_casecnv.c
+++ b/mysys/mf_casecnv.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Functions to convert to lover_case and to upper_case in scandinavia.
@@ -25,9 +24,25 @@
#include "mysys_priv.h"
#include <m_ctype.h>
+#ifndef SCO
#include <m_string.h>
+#endif
- /* string to uppercase */
+/*
+ Upcase string
+
+ SYNOPSIS
+ str IN/OUT String to upcase
+
+ RETURN VALUE
+ none
+ DESCRIPTION
+ Function changes input parameter so all chars it consist from
+ are replaced with matching one in upper case.
+ String should be writable with exception read-only empty string
+ constant is handled correctly.
+*/
+
void caseup_str(my_string str)
{
@@ -35,7 +50,7 @@ void caseup_str(my_string str)
if (use_mb(default_charset_info))
{
register uint32 l;
- register char *end=str+(uint) strlen(str);
+ register char *end=str+strlen(str);
while (*str)
{
if ((l=my_ismbchar(default_charset_info, str,end))) str+=l;
@@ -44,11 +59,29 @@ void caseup_str(my_string str)
}
else
#endif
- while ((*str = toupper(*str)) != 0)
+ while (*str!=0) /* iterate till the end of string */
+ {
+ *str= toupper(*str);
str++;
+ }
} /* caseup_str */
- /* string to lowercase */
+
+/*
+ Downcase string
+
+ SYNOPSIS
+ str IN/OUT String to downcase
+
+ RETURN VALUE
+ none
+ DESCRIPTION
+ Function changes input parameter so all chars it consist from
+ are replaced with matching one in lower case.
+ String should be writable with exception read-only empty string
+ constant is handled correctly.
+*/
+
void casedn_str(my_string str)
{
@@ -56,7 +89,7 @@ void casedn_str(my_string str)
if (use_mb(default_charset_info))
{
register uint32 l;
- register char *end=str+(uint) strlen(str);
+ register char *end=str+strlen(str);
while (*str)
{
if ((l=my_ismbchar(default_charset_info, str,end))) str+=l;
@@ -65,8 +98,11 @@ void casedn_str(my_string str)
}
else
#endif
- while ((*str= tolower(*str)) != 0)
+ while (*str!=0) /* iterate till the end of string */
+ {
+ *str= tolower(*str);
str++;
+ }
} /* casedn_str */
@@ -155,7 +191,7 @@ int my_strcasecmp(const char *s, const char *t)
if (use_mb(default_charset_info))
{
register uint32 l;
- register const char *end=s+(uint) strlen(s);
+ register const char *end=s+strlen(s);
while (s<end)
{
if ((l=my_ismbchar(default_charset_info, s,end)))
diff --git a/mysys/mf_dirname.c b/mysys/mf_dirname.c
index 399082a238b..d35f2c4f7ae 100644
--- a/mysys/mf_dirname.c
+++ b/mysys/mf_dirname.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -50,57 +49,80 @@ uint dirname_part(my_string to, const char *name)
DBUG_PRINT("enter",("'%s'",name));
length=dirname_length(name);
- (void) strmake(to,(char*) name,min(length,FN_REFLEN-2));
- convert_dirname(to); /* Convert chars */
+ convert_dirname(to, name, name+length);
DBUG_RETURN(length);
} /* dirname */
- /* convert dirname to use under this system */
- /* If MSDOS converts '/' to '\' */
- /* If VMS converts '<' to '[' and '>' to ']' */
- /* Adds a '/' to end if there isn't one and the last isn't a dev_char */
- /* ARGSUSED */
+/*
+ Convert directory name to use under this system
+
+ SYNPOSIS
+ convert_dirname()
+ to Store result here
+ from Original filename
+ from_end Pointer at end of filename (normally end \0)
+
+ IMPLEMENTATION
+ If MSDOS converts '/' to '\'
+ If VMS converts '<' to '[' and '>' to ']'
+ Adds a FN_LIBCHAR to end if the result string if there isn't one
+ and the last isn't dev_char.
+ Copies data from 'from' until ASCII(0) for until from == from_end
+ If you want to use the whole 'from' string, just send NullS as the
+ last argument.
+
+ If the result string is larger than FN_REFLEN -1, then it's cut.
+
+ RETURN
+ Returns pointer to end \0 in to
+*/
#ifndef FN_DEVCHAR
#define FN_DEVCHAR '\0' /* For easier code */
#endif
-char *convert_dirname(my_string to)
+char *convert_dirname(char *to, const char *from, const char *from_end)
{
- reg1 char *pos;
-#ifdef FN_UPPER_CASE
- caseup_str(to);
-#endif
-#ifdef FN_LOWER_CASE
- casedn_str(to);
-#endif
-#if FN_LIBCHAR != '/'
- {
- pos=to-1; /* Change from '/' */
- while ((pos=strchr(pos+1,'/')) != 0)
- *pos=FN_LIBCHAR;
- }
-#endif
-#ifdef FN_C_BEFORE_DIR_2
+ char *to_org=to;
+
+ /* We use -2 here, becasue we need place for the last FN_LIBCHAR */
+ if (!from_end || (from_end - from) > FN_REFLEN-2)
+ from_end=from+FN_REFLEN -2;
+
+#if FN_LIBCHAR != '/' || defined(FN_C_BEFORE_DIR_2)
{
- for (pos=to ; *pos ; pos++)
+ for (; *from && from != from_end; from++)
{
- if (*pos == FN_C_BEFORE_DIR_2)
- *pos=FN_C_BEFORE_DIR;
- if (*pos == FN_C_AFTER_DIR_2)
- *pos=FN_C_AFTER_DIR;
+ if (*from == '/')
+ *to++= FN_LIBCHAR;
+#ifdef FN_C_BEFORE_DIR_2
+ else if (*from == FN_C_BEFORE_DIR_2)
+ *to++= FN_C_BEFORE_DIR;
+ else if (*from == FN_C_AFTER_DIR_2)
+ *to++= FN_C_AFTER_DIR;
+#endif
+ else
+ *to++= *from;
}
+ *to=0;
}
#else
- { /* Append FN_LIBCHAR if not there */
- pos=strend(to);
- if (pos != to && (pos[-1] != FN_LIBCHAR && pos[-1] != FN_DEVCHAR))
- {
- *pos++=FN_LIBCHAR;
- *pos=0;
- }
+ /* This is ok even if to == from, becasue we need to cut the string */
+ to= strmake(to, from, (uint) (from_end-from));
+#endif
+
+ /* Add FN_LIBCHAR to the end of directory path */
+ if (to != to_org && (to[-1] != FN_LIBCHAR && to[-1] != FN_DEVCHAR))
+ {
+ *to++=FN_LIBCHAR;
+ *to=0;
}
+#ifdef FN_UPPER_CASE
+ caseup_str(to_org);
+#endif
+#ifdef FN_LOWER_CASE
+ casedn_str(to_org);
#endif
- return pos; /* Pointer to end of dir */
+ return to; /* Pointer to end of dir */
} /* convert_dirname */
diff --git a/mysys/mf_fn_ext.c b/mysys/mf_fn_ext.c
index 6a9b9d18341..9c86a8072ef 100644
--- a/mysys/mf_fn_ext.c
+++ b/mysys/mf_fn_ext.c
@@ -1,30 +1,38 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Returnerar en pekare till filnamnets extension. */
#include "mysys_priv.h"
#include <m_string.h>
- /* Return a pointerto the extension of the filename
- The pointer points at the extension character (normally '.'))
- If there isn't any extension, the pointer points at the end
- NULL of the filename
- */
+/*
+ Return a pointer to the extension of the filename.
+
+ SYNOPSIS
+ fn_ext()
+ name Name of file
+
+ DESCRIPTION
+ The extension is defined as everything after the first extension character
+ (normally '.') after the directory name.
+
+ RETURN VALUES
+ Pointer to to the extension character. If there isn't any extension,
+ points at the end ASCII(0) of the filename.
+*/
my_string fn_ext(const char *name)
{
@@ -41,6 +49,6 @@ my_string fn_ext(const char *name)
if (!(gpos=strrchr(name,FNLIBCHAR)))
gpos=name;
#endif
- pos=strrchr(gpos,FN_EXTCHAR);
+ pos=strchr(gpos,FN_EXTCHAR);
DBUG_RETURN (pos ? pos : strend(gpos));
} /* fn_ext */
diff --git a/mysys/mf_format.c b/mysys/mf_format.c
index 7dac46cf0d0..937904847ee 100644
--- a/mysys/mf_format.c
+++ b/mysys/mf_format.c
@@ -1,94 +1,84 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
-#ifdef HAVE_REALPATH
-#include <sys/param.h>
-#include <sys/stat.h>
-#endif
- /* format a filename with replace of library and extension */
- /* params to and name may be identicall */
- /* function doesn't change name if name != to */
- /* Flag may be: 1 replace filenames library with 'dsk' */
- /* 2 replace extension with 'form' */
- /* 4 Unpack filename (replace ~ with home) */
- /* 8 Pack filename as short as possibly */
- /* 16 Resolve symbolic links for filename */
- /* 32 Resolve filename to full path */
- /* 64 Return NULL if too long path */
+ /*
+ Formats a filename with possible replace of directory of extension
+ Function can handle the case where 'to' == 'name'
+ For a description of the flag values, consult my_sys.h
+ The arguments should be in unix format.
+ */
-#ifdef SCO
-#define BUFF_LEN 4097
-#else
-#ifdef MAXPATHLEN
-#define BUFF_LEN MAXPATHLEN
-#else
-#define BUFF_LEN FN_LEN
-#endif
-#endif
-my_string fn_format(my_string to, const char *name, const char *dsk,
- const char *form, int flag)
+my_string fn_format(my_string to, const char *name, const char *dir,
+ const char *extension, uint flag)
{
reg1 uint length;
- char dev[FN_REFLEN], buff[BUFF_LEN], *pos, *startpos;
+ char dev[FN_REFLEN], buff[FN_REFLEN], *pos, *startpos;
const char *ext;
DBUG_ENTER("fn_format");
- DBUG_PRINT("enter",("name: %s dsk: %s form: %s flag: %d",
- name,dsk,form,flag));
+ DBUG_PRINT("enter",("name: %s dir: %s extension: %s flag: %d",
+ name,dir,extension,flag));
- /* Kopiera & skippa enheten */
+ /* Copy and skip directory */
name+=(length=dirname_part(dev,(startpos=(my_string) name)));
- if (length == 0 || flag & 1)
+ if (length == 0 || (flag & MY_REPLACE_DIR))
{
- (void) strmake(dev,dsk, sizeof(dev) - 2);
- /* Use given directory */
- convert_dirname(dev); /* Fix to this OS */
+ /* Use given directory */
+ convert_dirname(dev,dir,NullS); /* Fix to this OS */
}
- if (flag & 8)
+ else if ((flag & MY_RELATIVE_PATH) && !test_if_hard_path(name))
+ {
+ /* Put 'dir' before the given path */
+ strmake(buff,dev,sizeof(buff)-1);
+ pos=convert_dirname(dev,dir,NullS);
+ strmake(pos,buff,sizeof(buff)-1- (int) (pos-dev));
+ }
+
+ if (flag & MY_PACK_FILENAME)
pack_dirname(dev,dev); /* Put in ./.. and ~/.. */
- if (flag & 4)
+ if (flag & MY_UNPACK_FILENAME)
(void) unpack_dirname(dev,dev); /* Replace ~/.. with dir */
- if ((pos=(char*)strchr(name,FN_EXTCHAR)) != NullS)
+ if ((pos= (char*) strchr(name,FN_EXTCHAR)) != NullS)
{
- if ((flag & 2) == 0) /* Skall vi byta extension ? */
+ if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */
{
- length=strlength(name); /* Old extension */
+ length=strlength(name); /* Use old extension */
ext = "";
}
else
{
length=(uint) (pos-(char*) name); /* Change extension */
- ext= form;
+ ext= extension;
}
}
else
{
- length=strlength(name); /* Har ingen ext- tag nya */
- ext=form;
+ length=strlength(name); /* No ext, use the now one */
+ ext=extension;
}
if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN )
- { /* To long path, return original */
+ {
+ /* To long path, return original or NULL */
uint tmp_length;
- if (flag & 64)
- return 0;
+ if (flag & MY_SAFE_PATH)
+ return NullS;
tmp_length=strlength(startpos);
DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %d",dev,ext,length));
(void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
@@ -109,19 +99,19 @@ my_string fn_format(my_string to, const char *name, const char *dsk,
#endif
(void) strmov(pos,ext); /* Don't convert extension */
}
- /* Purify gives a lot of UMR errors when using realpath */
-#if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH)
- if (flag & 16)
+ /*
+ If MY_RETURN_REAL_PATH and MY_RESOLVE_SYMLINK is given, only do
+ realpath if the file is a symbolic link
+ */
+ if (flag & MY_RETURN_REAL_PATH)
+ (void) my_realpath(to, to, MYF(flag & MY_RESOLVE_SYMLINKS ?
+ MY_RESOLVE_LINK: 0));
+ else if (flag & MY_RESOLVE_SYMLINKS)
{
- struct stat stat_buff;
- if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
- {
- if (realpath(to,buff))
- strmake(to,buff,FN_REFLEN-1);
- }
+ strmov(buff,to);
+ (void) my_readlink(to, buff, MYF(0));
}
-#endif
- DBUG_RETURN (to);
+ DBUG_RETURN(to);
} /* fn_format */
diff --git a/mysys/mf_getdate.c b/mysys/mf_getdate.c
index f01d1d7633a..189d43e782a 100644
--- a/mysys/mf_getdate.c
+++ b/mysys/mf_getdate.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Get date in a printable form: yyyy-mm-dd hh:mm:ss */
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 0d1c227c2b2..d96d4c0db3c 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Cashing of files with only does (sequential) read or writes of fixed-
@@ -23,12 +22,30 @@
Possibly use of asyncronic io.
macros for read and writes for faster io.
Used instead of FILE when reading or writing whole files.
- This will make mf_rec_cache obsolete.
+ This code makes mf_rec_cache obsolete (currently only used by ISAM)
One can change info->pos_in_file to a higher value to skip bytes in file if
- also info->rc_pos is set to info->rc_end.
+ also info->read_pos is set to info->read_end.
If called through open_cached_file(), then the temporary file will
only be created if a write exeeds the file buffer or if one calls
- flush_io_cache().
+ flush_io_cache().
+
+ If one uses SEQ_READ_APPEND, then two buffers are allocated, one for
+ reading and another for writing. Reads are first done from disk and
+ then done from the write buffer. This is an efficient way to read
+ from a log file when one is writing to it at the same time.
+ For this to work, the file has to be opened in append mode!
+ Note that when one uses SEQ_READ_APPEND, one MUST write using
+ my_b_append ! This is needed because we need to lock the mutex
+ every time we access the write buffer.
+
+TODO:
+ When one SEQ_READ_APPEND and we are reading and writing at the same time,
+ each time the write buffer gets full and it's written to disk, we will
+ always do a disk read to read a part of the buffer from disk to the
+ read buffer.
+ This should be fixed so that when we do a flush_io_cache() and
+ we have been reading the write buffer, we should transfer the rest of the
+ write buffer to the read buffer before we start to reuse it.
*/
#define MAP_TO_USE_RAID
@@ -36,10 +53,62 @@
#include <m_string.h>
#ifdef HAVE_AIOWAIT
#include "mysys_err.h"
-#include <errno.h>
static void my_aiowait(my_aio_result *result);
#endif
+#include <assert.h>
+#include <errno.h>
+
+#ifdef THREAD
+#define lock_append_buffer(info) \
+ pthread_mutex_lock(&(info)->append_buffer_lock)
+#define unlock_append_buffer(info) \
+ pthread_mutex_unlock(&(info)->append_buffer_lock)
+#else
+#define lock_append_buffer(info)
+#define unlock_append_buffer(info)
+#endif
+#define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1))
+#define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1))
+
+static void
+init_functions(IO_CACHE* info, enum cache_type type)
+{
+ switch (type) {
+ case READ_NET:
+ /*
+ Must be initialized by the caller. The problem is that
+ _my_b_net_read has to be defined in sql directory because of
+ the dependency on THD, and therefore cannot be visible to
+ programs that link against mysys but know nothing about THD, such
+ as myisamchk
+ */
+ break;
+ case SEQ_READ_APPEND:
+ info->read_function = _my_b_seq_read;
+ info->write_function = 0; /* Force a core if used */
+ break;
+ default:
+ info->read_function =
+#ifdef THREAD
+ info->share ? _my_b_read_r :
+#endif
+ _my_b_read;
+ info->write_function = _my_b_write;
+ }
+
+ /* Ensure that my_b_tell() and my_b_bytes_in_cache works */
+ if (type == WRITE_CACHE)
+ {
+ info->current_pos= &info->write_pos;
+ info->current_end= &info->write_end;
+ }
+ else
+ {
+ info->current_pos= &info->read_pos;
+ info->current_end= &info->read_end;
+ }
+}
/*
** if cachesize == 0 then use default cachesize (from s-file)
@@ -52,70 +121,97 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
pbool use_async_io, myf cache_myflags)
{
uint min_cache;
+ my_off_t end_of_file= ~(my_off_t) 0;
DBUG_ENTER("init_io_cache");
- DBUG_PRINT("enter",("type: %d pos: %ld",(int) type, (ulong) seek_offset));
+ DBUG_PRINT("enter",("cache: %lx type: %d pos: %ld",
+ (ulong) info, (int) type, (ulong) seek_offset));
+
+ info->file= file;
+ info->type=type;
+ info->pos_in_file= seek_offset;
+ info->pre_close = info->pre_read = info->post_read = 0;
+ info->arg = 0;
+ info->alloced_buffer = 0;
+ info->buffer=0;
+ info->seek_not_done= test(file >= 0);
+#ifdef THREAD
+ info->share=0;
+#endif
- info->file=file;
if (!cachesize)
if (! (cachesize= my_default_record_cache_size))
DBUG_RETURN(1); /* No cache requested */
min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
- if (type == READ_CACHE)
+ if (type == READ_CACHE || type == SEQ_READ_APPEND)
{ /* Assume file isn't growing */
- if (cache_myflags & MY_DONT_CHECK_FILESIZE)
- {
- cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
- }
- else
+ if (!(cache_myflags & MY_DONT_CHECK_FILESIZE))
{
- my_off_t file_pos,end_of_file;
- if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
- DBUG_RETURN(1);
+ /* Calculate end of file to not allocate to big buffers */
end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
if (end_of_file < seek_offset)
end_of_file=seek_offset;
- VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
+ /* Trim cache size if the file is very small */
if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
{
cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
- use_async_io=0; /* No nead to use async */
+ use_async_io=0; /* No need to use async */
}
}
}
-
- for (;;)
+ cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
+ if (type != READ_NET && type != WRITE_NET)
{
- cachesize=(uint) ((ulong) (cachesize + min_cache-1) &
- (ulong) ~(min_cache-1));
- if (cachesize < min_cache)
- cachesize = min_cache;
- if ((info->buffer=
- (byte*) my_malloc(cachesize,
- MYF((cache_myflags & ~ MY_WME) |
- (cachesize == min_cache ? MY_WME : 0)))) != 0)
- break; /* Enough memory found */
- if (cachesize == min_cache)
- DBUG_RETURN(2); /* Can't alloc cache */
- cachesize= (uint) ((long) cachesize*3/4); /* Try with less memory */
+ /* Retry allocating memory in smaller blocks until we get one */
+ for (;;)
+ {
+ uint buffer_block;
+ cachesize=(uint) ((ulong) (cachesize + min_cache-1) &
+ (ulong) ~(min_cache-1));
+ if (cachesize < min_cache)
+ cachesize = min_cache;
+ buffer_block = cachesize;
+ if (type == SEQ_READ_APPEND)
+ buffer_block *= 2;
+ if ((info->buffer=
+ (byte*) my_malloc(buffer_block,
+ MYF((cache_myflags & ~ MY_WME) |
+ (cachesize == min_cache ? MY_WME : 0)))) != 0)
+ {
+ info->write_buffer=info->buffer;
+ if (type == SEQ_READ_APPEND)
+ info->write_buffer = info->buffer + cachesize;
+ info->alloced_buffer=1;
+ break; /* Enough memory found */
+ }
+ if (cachesize == min_cache)
+ DBUG_RETURN(2); /* Can't alloc cache */
+ cachesize= (uint) ((long) cachesize*3/4); /* Try with less memory */
+ }
}
- info->pos_in_file=seek_offset;
+
+ DBUG_PRINT("info",("init_io_cache: cachesize = %u",cachesize));
info->read_length=info->buffer_length=cachesize;
- info->seek_not_done= test(file >= 0); /* Seek not done */
info->myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
- info->rc_request_pos=info->rc_pos=info->buffer;
-
- if (type == READ_CACHE)
- {
- info->rc_end=info->buffer; /* Nothing in cache */
- }
- else /* type == WRITE_CACHE */
+ info->request_pos= info->read_pos= info->write_pos = info->buffer;
+ if (type == SEQ_READ_APPEND)
{
- info->rc_end=info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));
+ info->append_read_pos = info->write_pos = info->write_buffer;
+ info->write_end = info->write_buffer + info->buffer_length;
+#ifdef THREAD
+ pthread_mutex_init(&info->append_buffer_lock,MY_MUTEX_INIT_FAST);
+#endif
}
- info->end_of_file=MY_FILEPOS_ERROR; /* May be changed by user */
- info->type=type;
+
+ if (type == WRITE_CACHE)
+ info->write_end=
+ info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));
+ else
+ info->read_end=info->buffer; /* Nothing in cache */
+
+ /* End_of_file may be changed by user later */
+ info->end_of_file= end_of_file;
info->error=0;
- info->read_function=_my_b_read;
+ init_functions(info,type);
#ifdef HAVE_AIOWAIT
if (use_async_io && ! my_disable_async_io)
{
@@ -128,7 +224,6 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
DBUG_RETURN(0);
} /* init_io_cache */
-
/* Wait until current request is ready */
#ifdef HAVE_AIOWAIT
@@ -156,8 +251,13 @@ static void my_aiowait(my_aio_result *result)
}
#endif
- /* Use this to reset cache to start or other type */
- /* Some simple optimizing is done when reinit in current buffer */
+
+/*
+ Use this to reset cache to re-start reading or to change the type
+ between READ_CACHE <-> WRITE_CACHE
+ If we are doing a reinit of a cache where we have the start of the file
+ in the cache, we are reusing this memory without flushing it to disk.
+*/
my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
my_off_t seek_offset,
@@ -165,47 +265,76 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
pbool clear_cache)
{
DBUG_ENTER("reinit_io_cache");
+ DBUG_PRINT("enter",("cache: %lx type: %d seek_offset: %lu clear_cache: %d",
+ (ulong) info, type, (ulong) seek_offset,
+ (int) clear_cache));
+
+ /* One can't do reinit with the following types */
+ DBUG_ASSERT(type != READ_NET && info->type != READ_NET &&
+ type != WRITE_NET && info->type != WRITE_NET &&
+ type != SEQ_READ_APPEND && info->type != SEQ_READ_APPEND);
- info->seek_not_done= test(info->file >= 0); /* Seek not done */
+ /* If the whole file is in memory, avoid flushing to disk */
if (! clear_cache &&
seek_offset >= info->pos_in_file &&
- seek_offset <= info->pos_in_file +
- (uint) (info->rc_end - info->rc_request_pos))
- { /* use current buffer */
+ seek_offset <= my_b_tell(info))
+ {
+ /* Reuse current buffer without flushing it to disk */
+ byte *pos;
if (info->type == WRITE_CACHE && type == READ_CACHE)
{
- info->rc_end=info->rc_pos;
+ info->read_end=info->write_pos;
info->end_of_file=my_b_tell(info);
+ info->seek_not_done=1;
}
- else if (info->type == READ_CACHE && type == WRITE_CACHE)
- info->rc_end=info->buffer+info->buffer_length;
- info->rc_pos=info->rc_request_pos+(seek_offset-info->pos_in_file);
+ else if (type == WRITE_CACHE)
+ {
+ if (info->type == READ_CACHE)
+ {
+ info->write_end=info->write_buffer+info->buffer_length;
+ info->seek_not_done=1;
+ }
+ info->end_of_file = ~(my_off_t) 0;
+ }
+ pos=info->request_pos+(seek_offset-info->pos_in_file);
+ if (type == WRITE_CACHE)
+ info->write_pos=pos;
+ else
+ info->read_pos= pos;
#ifdef HAVE_AIOWAIT
my_aiowait(&info->aio_result); /* Wait for outstanding req */
#endif
}
else
{
+ /*
+ If we change from WRITE_CACHE to READ_CACHE, assume that everything
+ after the current positions should be ignored
+ */
if (info->type == WRITE_CACHE && type == READ_CACHE)
info->end_of_file=my_b_tell(info);
- if (flush_io_cache(info))
+ /* flush cache if we want to reuse it */
+ if (!clear_cache && flush_io_cache(info))
DBUG_RETURN(1);
info->pos_in_file=seek_offset;
- info->rc_request_pos=info->rc_pos=info->buffer;
+ /* Better to do always do a seek */
+ info->seek_not_done=1;
+ info->request_pos=info->read_pos=info->write_pos=info->buffer;
if (type == READ_CACHE)
{
- info->rc_end=info->buffer; /* Nothing in cache */
+ info->read_end=info->buffer; /* Nothing in cache */
}
else
{
- info->rc_end=info->buffer+info->buffer_length-
- (seek_offset & (IO_SIZE-1));
- info->end_of_file=MY_FILEPOS_ERROR; /* May be changed by user */
+ info->write_end=(info->buffer + info->buffer_length -
+ (seek_offset & (IO_SIZE-1)));
+ info->end_of_file= ~(my_off_t) 0;
}
}
info->type=type;
info->error=0;
- info->read_function=_my_b_read;
+ init_functions(info,type);
+
#ifdef HAVE_AIOWAIT
if (use_async_io && ! my_disable_async_io &&
((ulong) info->buffer_length <
@@ -217,23 +346,34 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
info->inited=0;
#endif
DBUG_RETURN(0);
-} /* init_io_cache */
+} /* reinit_io_cache */
- /* Read buffered. Returns 1 if can't read requested characters */
- /* Returns 0 if record read */
+/*
+ Read buffered. Returns 1 if can't read requested characters
+ This function is only called from the my_b_read() macro
+ when there isn't enough characters in the buffer to
+ satisfy the request.
+ Returns 0 we succeeded in reading all data
+*/
int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
{
uint length,diff_length,left_length;
my_off_t max_length, pos_in_file;
+ DBUG_ENTER("_my_b_read");
- memcpy(Buffer,info->rc_pos,
- (size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
- Buffer+=left_length;
- Count-=left_length;
- pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
+ if ((left_length=(uint) (info->read_end-info->read_pos)))
+ {
+ DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
+ memcpy(Buffer,info->read_pos, (size_t) (left_length));
+ Buffer+=left_length;
+ Count-=left_length;
+ }
+
+ /* pos_in_file always point on where info->buffer was read */
+ pos_in_file=info->pos_in_file+(uint) (info->read_end - info->buffer);
if (info->seek_not_done)
{ /* File touched, do seek */
VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
@@ -246,15 +386,15 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
if (info->end_of_file == pos_in_file)
{ /* End of file */
info->error=(int) left_length;
- return 1;
+ DBUG_RETURN(1);
}
length=(Count & (uint) ~(IO_SIZE-1))-diff_length;
if ((read_length=my_read(info->file,Buffer,(uint) length,info->myflags))
!= (uint) length)
{
- info->error= read_length == (uint) -1 ? -1 :
- (int) (read_length+left_length);
- return 1;
+ info->error= (read_length == (uint) -1 ? -1 :
+ (int) (read_length+left_length));
+ DBUG_RETURN(1);
}
Count-=length;
Buffer+=length;
@@ -262,16 +402,17 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
left_length+=length;
diff_length=0;
}
- max_length=info->end_of_file - pos_in_file;
- if (max_length > info->read_length-diff_length)
- max_length=info->read_length-diff_length;
+ max_length=info->read_length-diff_length;
+ if (info->type != READ_FIFO &&
+ max_length > (info->end_of_file - pos_in_file))
+ max_length = info->end_of_file - pos_in_file;
if (!max_length)
{
if (Count)
{
info->error= left_length; /* We only got this many char */
- return 1;
+ DBUG_RETURN(1);
}
length=0; /* Didn't read any chars */
}
@@ -281,14 +422,301 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
{
if (length != (uint) -1)
memcpy(Buffer,info->buffer,(size_t) length);
+ info->pos_in_file= pos_in_file;
info->error= length == (uint) -1 ? -1 : (int) (length+left_length);
+ info->read_pos=info->read_end=info->buffer;
+ DBUG_RETURN(1);
+ }
+ info->read_pos=info->buffer+Count;
+ info->read_end=info->buffer+length;
+ info->pos_in_file=pos_in_file;
+ memcpy(Buffer,info->buffer,(size_t) Count);
+ DBUG_RETURN(0);
+}
+
+#ifdef THREAD
+/* Prepare IO_CACHE for shared use */
+void init_io_cache_share(IO_CACHE *info, IO_CACHE_SHARE *s, uint num_threads)
+{
+ DBUG_ASSERT(info->type == READ_CACHE);
+ pthread_mutex_init(&s->mutex, MY_MUTEX_INIT_FAST);
+ pthread_cond_init (&s->cond, 0);
+ s->total=s->count=num_threads-1;
+ s->active=0;
+ info->share=s;
+ info->read_function=_my_b_read_r;
+ info->current_pos= info->current_end= 0;
+}
+
+/*
+ Remove a thread from shared access to IO_CACHE
+ Every thread should do that on exit for not
+ to deadlock other threads
+*/
+void remove_io_thread(IO_CACHE *info)
+{
+ IO_CACHE_SHARE *s=info->share;
+
+ pthread_mutex_lock(&s->mutex);
+ s->total--;
+ if (! s->count--)
+ pthread_cond_signal(&s->cond);
+ pthread_mutex_unlock(&s->mutex);
+}
+
+static int lock_io_cache(IO_CACHE *info, my_off_t pos)
+{
+ int total;
+ IO_CACHE_SHARE *s=info->share;
+
+ pthread_mutex_lock(&s->mutex);
+ if (!s->count)
+ {
+ s->count=s->total;
return 1;
}
- info->rc_pos=info->buffer+Count;
- info->rc_end=info->buffer+length;
+
+ total=s->total;
+ s->count--;
+ while (!s->active || s->active->pos_in_file < pos)
+ pthread_cond_wait(&s->cond, &s->mutex);
+
+ if (s->total < total)
+ return 1;
+
+ pthread_mutex_unlock(&s->mutex);
+ return 0;
+}
+
+static void unlock_io_cache(IO_CACHE *info)
+{
+ pthread_cond_broadcast(&info->share->cond);
+ pthread_mutex_unlock(&info->share->mutex);
+}
+
+
+/*
+ Read from IO_CACHE when it is shared between several threads.
+ It works as follows: when a thread tries to read from a file
+ (that is, after using all the data from the (shared) buffer),
+ it just hangs on lock_io_cache(), wating for other threads.
+ When the very last thread attempts a read, lock_io_cache()
+ returns 1, the thread does actual IO and unlock_io_cache(),
+ which signals all the waiting threads that data is in the buffer.
+*/
+
+int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count)
+{
+ my_off_t pos_in_file;
+ uint length,diff_length,read_len;
+ DBUG_ENTER("_my_b_read_r");
+
+ if ((read_len=(uint) (info->read_end-info->read_pos)))
+ {
+ DBUG_ASSERT(Count >= read_len); /* User is not using my_b_read() */
+ memcpy(Buffer,info->read_pos, (size_t) (read_len));
+ Buffer+=read_len;
+ Count-=read_len;
+ }
+ while (Count)
+ {
+ int cnt, len;
+
+ pos_in_file= info->pos_in_file + (uint)(info->read_end - info->buffer);
+ diff_length= (uint) (pos_in_file & (IO_SIZE-1));
+ length=IO_ROUND_UP(Count+diff_length)-diff_length;
+ length=(length <= info->read_length) ?
+ length + IO_ROUND_DN(info->read_length - length) :
+ length - IO_ROUND_UP(length - info->read_length) ;
+ if (info->type != READ_FIFO &&
+ (length > (uint) (info->end_of_file - pos_in_file)))
+ length= (uint) (info->end_of_file - pos_in_file);
+ if (length == 0)
+ {
+ info->error=(int) read_len;
+ DBUG_RETURN(1);
+ }
+ if (lock_io_cache(info, pos_in_file))
+ {
+ info->share->active=info;
+ if (info->seek_not_done) /* File touched, do seek */
+ VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
+ len=(int)my_read(info->file,info->buffer, length, info->myflags);
+ info->read_end=info->buffer + (len == -1 ? 0 : len);
+ info->error=(len == (int)length ? 0 : len);
+ info->pos_in_file=pos_in_file;
+ unlock_io_cache(info);
+ }
+ else
+ {
+ info->error= info->share->active->error;
+ info->read_end= info->share->active->read_end;
+ info->pos_in_file= info->share->active->pos_in_file;
+ len= (info->error == -1 ? -1 : info->read_end-info->buffer);
+ }
+ info->read_pos=info->buffer;
+ info->seek_not_done=0;
+ if (len <= 0)
+ {
+ info->error=(int) read_len;
+ DBUG_RETURN(1);
+ }
+ cnt=((uint) len > Count) ? (int) Count : len;
+ memcpy(Buffer,info->read_pos, (size_t)cnt);
+ Count -=cnt;
+ Buffer+=cnt;
+ read_len+=cnt;
+ info->read_pos+=cnt;
+ }
+ DBUG_RETURN(0);
+}
+#endif
+
+
+/*
+ Do sequential read from the SEQ_READ_APPEND cache
+ we do this in three stages:
+ - first read from info->buffer
+ - then if there are still data to read, try the file descriptor
+ - afterwards, if there are still data to read, try append buffer
+*/
+
+int _my_b_seq_read(register IO_CACHE *info, byte *Buffer, uint Count)
+{
+ uint length,diff_length,left_length,save_count;
+ my_off_t max_length, pos_in_file;
+ save_count=Count;
+
+ /* first, read the regular buffer */
+ if ((left_length=(uint) (info->read_end-info->read_pos)))
+ {
+ DBUG_ASSERT(Count > left_length); /* User is not using my_b_read() */
+ memcpy(Buffer,info->read_pos, (size_t) (left_length));
+ Buffer+=left_length;
+ Count-=left_length;
+ }
+ lock_append_buffer(info);
+
+ /* pos_in_file always point on where info->buffer was read */
+ if ((pos_in_file=info->pos_in_file+(uint) (info->read_end - info->buffer)) >=
+ info->end_of_file)
+ goto read_append_buffer;
+
+ /*
+ With read-append cache we must always do a seek before we read,
+ because the write could have moved the file pointer astray
+ */
+ VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
+ info->seek_not_done=0;
+
+ diff_length=(uint) (pos_in_file & (IO_SIZE-1));
+
+ /* now the second stage begins - read from file descriptor */
+ if (Count >= (uint) (IO_SIZE+(IO_SIZE-diff_length)))
+ { /* Fill first intern buffer */
+ uint read_length;
+
+ length=(Count & (uint) ~(IO_SIZE-1))-diff_length;
+ if ((read_length=my_read(info->file,Buffer,(uint) length,info->myflags)) ==
+ (uint)-1)
+ {
+ info->error= -1;
+ unlock_append_buffer(info);
+ return 1;
+ }
+ Count-=read_length;
+ Buffer+=read_length;
+ pos_in_file+=read_length;
+
+ if (read_length != (uint) length)
+ {
+ /*
+ We only got part of data; Read the rest of the data from the
+ write buffer
+ */
+ goto read_append_buffer;
+ }
+ left_length+=length;
+ diff_length=0;
+ }
+
+ max_length=info->read_length-diff_length;
+ if (max_length > (info->end_of_file - pos_in_file))
+ max_length = info->end_of_file - pos_in_file;
+ if (!max_length)
+ {
+ if (Count)
+ goto read_append_buffer;
+ length=0; /* Didn't read any more chars */
+ }
+ else
+ {
+ length=my_read(info->file,info->buffer,(uint) max_length,
+ info->myflags);
+ if (length == (uint) -1)
+ {
+ info->error= -1;
+ unlock_append_buffer(info);
+ return 1;
+ }
+ if (length < Count)
+ {
+ memcpy(Buffer,info->buffer,(size_t) length);
+ Count -= length;
+ Buffer += length;
+
+ /*
+ added the line below to make
+ DBUG_ASSERT(pos_in_file==info->end_of_file) pass.
+ otherwise this does not appear to be needed
+ */
+ pos_in_file += length;
+ goto read_append_buffer;
+ }
+ }
+ unlock_append_buffer(info);
+ info->read_pos=info->buffer+Count;
+ info->read_end=info->buffer+length;
info->pos_in_file=pos_in_file;
memcpy(Buffer,info->buffer,(size_t) Count);
return 0;
+
+read_append_buffer:
+
+ /*
+ Read data from the current write buffer.
+ Count should never be == 0 here (The code will work even if count is 0)
+ */
+
+ {
+ /* First copy the data to Count */
+ uint len_in_buff = (uint) (info->write_pos - info->append_read_pos);
+ uint copy_len;
+ uint transfer_len;
+
+ DBUG_ASSERT(info->append_read_pos <= info->write_pos);
+ /*
+ TODO: figure out if the assert below is needed or correct.
+ */
+ DBUG_ASSERT(pos_in_file == info->end_of_file);
+ copy_len=min(Count, len_in_buff);
+ memcpy(Buffer, info->append_read_pos, copy_len);
+ info->append_read_pos += copy_len;
+ Count -= copy_len;
+ if (Count)
+ info->error = save_count - Count;
+
+ /* Fill read buffer with data from write buffer */
+ memcpy(info->buffer, info->append_read_pos,
+ (size_t) (transfer_len=len_in_buff - copy_len));
+ info->read_pos= info->buffer;
+ info->read_end= info->buffer+transfer_len;
+ info->append_read_pos=info->write_pos;
+ info->pos_in_file=pos_in_file+copy_len;
+ info->end_of_file+=len_in_buff;
+ }
+ unlock_append_buffer(info);
+ return Count ? 1 : 0;
}
@@ -301,8 +729,8 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
my_off_t next_pos_in_file;
byte *read_buffer;
- memcpy(Buffer,info->rc_pos,
- (size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
+ memcpy(Buffer,info->read_pos,
+ (size_t) (left_length=(uint) (info->read_end-info->read_pos)));
Buffer+=left_length;
org_Count=Count;
Count-=left_length;
@@ -329,13 +757,13 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
(int) (read_length+left_length));
return(1);
}
- info->pos_in_file+=(uint) (info->rc_end - info->rc_request_pos);
+ info->pos_in_file+=(uint) (info->read_end - info->request_pos);
- if (info->rc_request_pos != info->buffer)
- info->rc_request_pos=info->buffer;
+ if (info->request_pos != info->buffer)
+ info->request_pos=info->buffer;
else
- info->rc_request_pos=info->buffer+info->read_length;
- info->rc_pos=info->rc_request_pos;
+ info->request_pos=info->buffer+info->read_length;
+ info->read_pos=info->request_pos;
next_pos_in_file=info->aio_read_pos+read_length;
/* Check if pos_in_file is changed
@@ -352,8 +780,8 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
{
my_off_t offset= (info->pos_in_file - info->aio_read_pos);
info->pos_in_file=info->aio_read_pos; /* Whe are here */
- info->rc_pos=info->rc_request_pos+offset;
- read_length-=offset; /* Bytes left from rc_pos */
+ info->read_pos=info->request_pos+offset;
+ read_length-=offset; /* Bytes left from read_pos */
}
}
#ifndef DBUG_OFF
@@ -365,16 +793,16 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
#endif
/* Copy found bytes to buffer */
length=min(Count,read_length);
- memcpy(Buffer,info->rc_pos,(size_t) length);
+ memcpy(Buffer,info->read_pos,(size_t) length);
Buffer+=length;
Count-=length;
left_length+=length;
- info->rc_end=info->rc_pos+read_length;
- info->rc_pos+=length;
+ info->read_end=info->rc_pos+read_length;
+ info->read_pos+=length;
}
else
next_pos_in_file=(info->pos_in_file+ (uint)
- (info->rc_end - info->rc_request_pos));
+ (info->read_end - info->request_pos));
/* If reading large blocks, or first read or read with skipp */
if (Count)
@@ -388,13 +816,13 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
read_length=IO_SIZE*2- (uint) (next_pos_in_file & (IO_SIZE-1));
if (Count < read_length)
{ /* Small block, read to cache */
- if ((read_length=my_read(info->file,info->rc_request_pos,
+ if ((read_length=my_read(info->file,info->request_pos,
read_length, info->myflags)) == (uint) -1)
return info->error= -1;
use_length=min(Count,read_length);
- memcpy(Buffer,info->rc_request_pos,(size_t) use_length);
- info->rc_pos=info->rc_request_pos+Count;
- info->rc_end=info->rc_request_pos+read_length;
+ memcpy(Buffer,info->request_pos,(size_t) use_length);
+ info->read_pos=info->request_pos+Count;
+ info->read_end=info->request_pos+read_length;
info->pos_in_file=next_pos_in_file; /* Start of block in cache */
next_pos_in_file+=read_length;
@@ -415,7 +843,7 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
info->error= read_length == (uint) -1 ? -1 : read_length+left_length;
return 1;
}
- info->rc_pos=info->rc_end=info->rc_request_pos;
+ info->read_pos=info->read_end=info->request_pos;
info->pos_in_file=(next_pos_in_file+=Count);
}
}
@@ -426,7 +854,7 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
if (max_length > (my_off_t) info->read_length - diff_length)
max_length= (my_off_t) info->read_length - diff_length;
- if (info->rc_request_pos != info->buffer)
+ if (info->request_pos != info->buffer)
read_buffer=info->buffer;
else
read_buffer=info->buffer+info->read_length;
@@ -443,13 +871,13 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
my_errno=errno;
DBUG_PRINT("error",("got error: %d, aio_result: %d from aioread, async skipped",
errno, info->aio_result.result.aio_errno));
- if (info->rc_request_pos != info->buffer)
+ if (info->request_pos != info->buffer)
{
- bmove(info->buffer,info->rc_request_pos,
- (uint) (info->rc_end - info->rc_pos));
- info->rc_request_pos=info->buffer;
- info->rc_pos-=info->read_length;
- info->rc_end-=info->read_length;
+ bmove(info->buffer,info->request_pos,
+ (uint) (info->read_end - info->read_pos));
+ info->request_pos=info->buffer;
+ info->read_pos-=info->read_length;
+ info->read_end-=info->read_length;
}
info->read_length=info->buffer_length; /* Use hole buffer */
info->read_function=_my_b_read; /* Use normal IO_READ next */
@@ -467,8 +895,13 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
int _my_b_get(IO_CACHE *info)
{
byte buff;
+ IO_CACHE_CALLBACK pre_read,post_read;
+ if ((pre_read = info->pre_read))
+ (*pre_read)(info);
if ((*(info)->read_function)(info,&buff,1))
return my_b_EOF;
+ if ((post_read = info->post_read))
+ (*post_read)(info);
return (int) (uchar) buff;
}
@@ -478,11 +911,17 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
{
uint rest_length,length;
- rest_length=(uint) (info->rc_end - info->rc_pos);
- memcpy(info->rc_pos,Buffer,(size_t) rest_length);
+ if (info->pos_in_file+info->buffer_length > info->end_of_file)
+ {
+ my_errno=errno=EFBIG;
+ return info->error = -1;
+ }
+
+ rest_length=(uint) (info->write_end - info->write_pos);
+ memcpy(info->write_pos,Buffer,(size_t) rest_length);
Buffer+=rest_length;
Count-=rest_length;
- info->rc_pos+=rest_length;
+ info->write_pos+=rest_length;
if (flush_io_cache(info))
return 1;
if (Count >= IO_SIZE)
@@ -499,12 +938,70 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
Buffer+=length;
info->pos_in_file+=length;
}
- memcpy(info->rc_pos,Buffer,(size_t) Count);
- info->rc_pos+=Count;
+ memcpy(info->write_pos,Buffer,(size_t) Count);
+ info->write_pos+=Count;
+ return 0;
+}
+
+
+/*
+ Append a block to the write buffer.
+ This is done with the buffer locked to ensure that we don't read from
+ the write buffer before we are ready with it.
+*/
+
+int my_b_append(register IO_CACHE *info, const byte *Buffer, uint Count)
+{
+ uint rest_length,length;
+
+ lock_append_buffer(info);
+ rest_length=(uint) (info->write_end - info->write_pos);
+ if (Count <= rest_length)
+ goto end;
+ memcpy(info->write_pos,Buffer,(size_t) rest_length);
+ Buffer+=rest_length;
+ Count-=rest_length;
+ info->write_pos+=rest_length;
+ if (_flush_io_cache(info,0))
+ {
+ unlock_append_buffer(info);
+ return 1;
+ }
+ if (Count >= IO_SIZE)
+ { /* Fill first intern buffer */
+ length=Count & (uint) ~(IO_SIZE-1);
+ if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
+ {
+ unlock_append_buffer(info);
+ return info->error= -1;
+ }
+ Count-=length;
+ Buffer+=length;
+ info->end_of_file+=length;
+ }
+
+end:
+ memcpy(info->write_pos,Buffer,(size_t) Count);
+ info->write_pos+=Count;
+ unlock_append_buffer(info);
return 0;
}
+int my_b_safe_write(IO_CACHE *info, const byte *Buffer, uint Count)
+{
+ /*
+ Sasha: We are not writing this with the ? operator to avoid hitting
+ a possible compiler bug. At least gcc 2.95 cannot deal with
+ several layers of ternary operators that evaluated comma(,) operator
+ expressions inside - I do have a test case if somebody wants it
+ */
+ if (info->type == SEQ_READ_APPEND)
+ return my_b_append(info, Buffer, Count);
+ return my_b_write(info, Buffer, Count);
+}
+
+
/*
Write a block to disk where part of the data may be inside the record
buffer. As all write calls to the data goes through the cache,
@@ -530,10 +1027,13 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
Buffer+=length;
pos+= length;
Count-= length;
+#ifndef HAVE_PREAD
+ info->seek_not_done=1;
+#endif
}
/* Check if we want to write inside the used part of the buffer.*/
- length= (uint) (info->rc_end - info->buffer);
+ length= (uint) (info->write_end - info->buffer);
if (pos < info->pos_in_file + length)
{
uint offset= (uint) (pos - info->pos_in_file);
@@ -544,8 +1044,8 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
Buffer+=length;
Count-= length;
/* Fix length of buffer if the new data was larger */
- if (info->buffer+length > info->rc_pos)
- info->rc_pos=info->buffer+length;
+ if (info->buffer+length > info->write_pos)
+ info->write_pos=info->buffer+length;
if (!Count)
return (error);
}
@@ -555,46 +1055,90 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
return error;
}
+
/* Flush write cache */
-int flush_io_cache(IO_CACHE *info)
+#ifdef THREAD
+#define LOCK_APPEND_BUFFER if (need_append_buffer_lock) \
+ lock_append_buffer(info);
+#define UNLOCK_APPEND_BUFFER if (need_append_buffer_lock) \
+ unlock_append_buffer(info);
+#else
+#define LOCK_APPEND_BUFFER
+#define UNLOCK_APPEND_BUFFER
+#endif
+
+
+int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
{
uint length;
- DBUG_ENTER("flush_io_cache");
+ my_bool append_cache;
+ my_off_t pos_in_file;
+ DBUG_ENTER("_flush_io_cache");
+
+ if (!(append_cache = (info->type == SEQ_READ_APPEND)))
+ need_append_buffer_lock=0;
- if (info->type == WRITE_CACHE)
+ if (info->type == WRITE_CACHE || append_cache)
{
if (info->file == -1)
{
if (real_open_cached_file(info))
DBUG_RETURN((info->error= -1));
}
- if (info->rc_pos != info->buffer)
+ LOCK_APPEND_BUFFER;
+
+ if ((length=(uint) (info->write_pos - info->write_buffer)))
{
- length=(uint) (info->rc_pos - info->buffer);
- if (info->seek_not_done)
+ pos_in_file=info->pos_in_file;
+ /*
+ If we have append cache, we always open the file with
+ O_APPEND which moves the pos to EOF automatically on every write
+ */
+ if (!append_cache && info->seek_not_done)
{ /* File touched, do seek */
- if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) ==
+ if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
MY_FILEPOS_ERROR)
+ {
+ UNLOCK_APPEND_BUFFER;
DBUG_RETURN((info->error= -1));
- info->seek_not_done=0;
+ }
+ if (!append_cache)
+ info->seek_not_done=0;
}
- info->rc_pos=info->buffer;
- info->pos_in_file+=length;
- info->rc_end=(info->buffer+info->buffer_length-
- (info->pos_in_file & (IO_SIZE-1)));
- if (my_write(info->file,info->buffer,length,info->myflags | MY_NABP))
- DBUG_RETURN((info->error= -1));
- DBUG_RETURN(0);
+ if (!append_cache)
+ info->pos_in_file+=length;
+ info->write_end= (info->write_buffer+info->buffer_length-
+ ((pos_in_file+length) & (IO_SIZE-1)));
+
+ if (my_write(info->file,info->write_buffer,length,
+ info->myflags | MY_NABP))
+ info->error= -1;
+ else
+ info->error= 0;
+ if (!append_cache)
+ {
+ set_if_bigger(info->end_of_file,(pos_in_file+length));
+ }
+ else
+ {
+ info->end_of_file+=(info->write_pos-info->append_read_pos);
+ DBUG_ASSERT(info->end_of_file == my_tell(info->file,MYF(0)));
+ }
+
+ info->append_read_pos=info->write_pos=info->write_buffer;
+ UNLOCK_APPEND_BUFFER;
+ DBUG_RETURN(info->error);
}
}
#ifdef HAVE_AIOWAIT
- else
+ else if (info->type != READ_NET)
{
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
+ my_aiowait(&info->aio_result); /* Wait for outstanding req */
info->inited=0;
}
#endif
+ UNLOCK_APPEND_BUFFER;
DBUG_RETURN(0);
}
@@ -602,13 +1146,132 @@ int flush_io_cache(IO_CACHE *info)
int end_io_cache(IO_CACHE *info)
{
int error=0;
+ IO_CACHE_CALLBACK pre_close;
DBUG_ENTER("end_io_cache");
- if (info->buffer)
+
+#ifdef THREAD
+ /*
+ if IO_CACHE is shared between several threads, only one
+ thread needs to call end_io_cache() - just as init_io_cache()
+ should be called only once and then memcopy'ed
+ */
+ if (info->share)
{
+ pthread_cond_destroy (&info->share->cond);
+ pthread_mutex_destroy(&info->share->mutex);
+ info->share=0;
+ }
+#endif
+
+ if ((pre_close=info->pre_close))
+ (*pre_close)(info);
+ if (info->alloced_buffer)
+ {
+ info->alloced_buffer=0;
if (info->file != -1) /* File doesn't exist */
error=flush_io_cache(info);
my_free((gptr) info->buffer,MYF(MY_WME));
- info->buffer=info->rc_pos=(byte*) 0;
+ info->buffer=info->read_pos=(byte*) 0;
+ }
+ if (info->type == SEQ_READ_APPEND)
+ {
+ /* Destroy allocated mutex */
+ info->type=0;
+#ifdef THREAD
+ pthread_mutex_destroy(&info->append_buffer_lock);
+#endif
}
DBUG_RETURN(error);
} /* end_io_cache */
+
+
+/**********************************************************************
+ Testing of MF_IOCACHE
+**********************************************************************/
+
+#ifdef MAIN
+
+#include <my_dir.h>
+
+void die(const char* fmt, ...)
+{
+ va_list va_args;
+ va_start(va_args,fmt);
+ fprintf(stderr,"Error:");
+ vfprintf(stderr, fmt,va_args);
+ fprintf(stderr,", errno=%d\n", errno);
+ exit(1);
+}
+
+int open_file(const char* fname, IO_CACHE* info, int cache_size)
+{
+ int fd;
+ if ((fd=my_open(fname,O_CREAT | O_RDWR,MYF(MY_WME))) < 0)
+ die("Could not open %s", fname);
+ if (init_io_cache(info, fd, cache_size, SEQ_READ_APPEND, 0,0,MYF(MY_WME)))
+ die("failed in init_io_cache()");
+ return fd;
+}
+
+void close_file(IO_CACHE* info)
+{
+ end_io_cache(info);
+ my_close(info->file, MYF(MY_WME));
+}
+
+int main(int argc, char** argv)
+{
+ IO_CACHE sra_cache; /* SEQ_READ_APPEND */
+ MY_STAT status;
+ const char* fname="/tmp/iocache.test";
+ int cache_size=16384;
+ char llstr_buf[22];
+ int max_block,total_bytes=0;
+ int i,num_loops=100,error=0;
+ char *p;
+ char* block, *block_end;
+ MY_INIT(argv[0]);
+ max_block = cache_size*3;
+ if (!(block=(char*)my_malloc(max_block,MYF(MY_WME))))
+ die("Not enough memory to allocate test block");
+ block_end = block + max_block;
+ for (p = block,i=0; p < block_end;i++)
+ {
+ *p++ = (char)i;
+ }
+ if (my_stat(fname,&status, MYF(0)) &&
+ my_delete(fname,MYF(MY_WME)))
+ {
+ die("Delete of %s failed, aborting", fname);
+ }
+ open_file(fname,&sra_cache, cache_size);
+ for (i = 0; i < num_loops; i++)
+ {
+ char buf[4];
+ int block_size = abs(rand() % max_block);
+ int4store(buf, block_size);
+ if (my_b_append(&sra_cache,buf,4) ||
+ my_b_append(&sra_cache, block, block_size))
+ die("write failed");
+ total_bytes += 4+block_size;
+ }
+ close_file(&sra_cache);
+ my_free(block,MYF(MY_WME));
+ if (!my_stat(fname,&status,MYF(MY_WME)))
+ die("%s failed to stat, but I had just closed it,\
+ wonder how that happened");
+ printf("Final size of %s is %s, wrote %d bytes\n",fname,
+ llstr(status.st_size,llstr_buf),
+ total_bytes);
+ my_delete(fname, MYF(MY_WME));
+ /* check correctness of tests */
+ if (total_bytes != status.st_size)
+ {
+ fprintf(stderr,"Not the same number of bytes acutally in file as bytes \
+supposedly written\n");
+ error=1;
+ }
+ exit(error);
+ return 0;
+}
+#endif
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index 3e9cc74e0a2..344b7ac2251 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
More functions to be used with IO_CACHE files
@@ -24,58 +23,118 @@
#include <m_string.h>
#include <stdarg.h>
#include <m_ctype.h>
+#include <assert.h>
+
+my_off_t my_b_append_tell(IO_CACHE* info)
+{
+ /*
+ Prevent optimizer from putting res in a register when debugging
+ we need this to be able to see the value of res when the assert fails
+ */
+ dbug_volatile my_off_t res;
+
+ /*
+ We need to lock the append buffer mutex to keep flush_io_cache()
+ from messing with the variables that we need in order to provide the
+ answer to the question.
+ */
+#ifdef THREAD
+ pthread_mutex_lock(&info->append_buffer_lock);
+#endif
+#ifndef DBUG_OFF
+ /*
+ Make sure EOF is where we think it is. Note that we cannot just use
+ my_tell() because we have a reader thread that could have left the
+ file offset in a non-EOF location
+ */
+ {
+ volatile my_off_t save_pos;
+ save_pos = my_tell(info->file,MYF(0));
+ my_seek(info->file,(my_off_t)0,MY_SEEK_END,MYF(0));
+ /*
+ Save the value of my_tell in res so we can see it when studying coredump
+ */
+ DBUG_ASSERT(info->end_of_file - (info->append_read_pos-info->write_buffer)
+ == (res=my_tell(info->file,MYF(0))));
+ my_seek(info->file,save_pos,MY_SEEK_SET,MYF(0));
+ }
+#endif
+ res = info->end_of_file + (info->write_pos-info->append_read_pos);
+#ifdef THREAD
+ pthread_mutex_unlock(&info->append_buffer_lock);
+#endif
+ return res;
+}
/*
-** Fix that next read will be made at certain position
-** For write cache, make next write happen at a certain position
+ Make next read happen at the given position
+ For write cache, make next write happen at the given position
*/
void my_b_seek(IO_CACHE *info,my_off_t pos)
{
- my_off_t offset = (pos - info->pos_in_file);
+ my_off_t offset;
DBUG_ENTER("my_b_seek");
DBUG_PRINT("enter",("pos: %lu", (ulong) pos));
- if (info->type == READ_CACHE)
+ /*
+ TODO:
+ Verify that it is OK to do seek in the non-append
+ area in SEQ_READ_APPEND cache
+ a) see if this always works
+ b) see if there is a better way to make it work
+ */
+ if (info->type == SEQ_READ_APPEND)
+ flush_io_cache(info);
+
+ offset=(pos - info->pos_in_file);
+
+ if (info->type == READ_CACHE || info->type == SEQ_READ_APPEND)
{
- if ((ulonglong) offset < (ulonglong) (info->rc_end - info->buffer))
+ /* TODO: explain why this works if pos < info->pos_in_file */
+ if ((ulonglong) offset < (ulonglong) (info->read_end - info->buffer))
{
/* The read is in the current buffer; Reuse it */
- info->rc_pos = info->buffer + offset;
+ info->read_pos = info->buffer + offset;
DBUG_VOID_RETURN;
}
else
{
/* Force a new read on next my_b_read */
- info->rc_pos=info->rc_end=info->buffer;
+ info->read_pos=info->read_end=info->buffer;
}
}
else if (info->type == WRITE_CACHE)
{
/* If write is in current buffer, reuse it */
if ((ulonglong) offset <
- (ulonglong) (info->rc_end - info->buffer))
+ (ulonglong) (info->write_end - info->write_buffer))
{
- info->rc_pos = info->buffer + offset;
+ info->write_pos = info->write_buffer + offset;
DBUG_VOID_RETURN;
}
flush_io_cache(info);
- info->rc_end=(info->buffer+info->buffer_length-(pos & (IO_SIZE-1)));
+ /* Correct buffer end so that we write in increments of IO_SIZE */
+ info->write_end=(info->write_buffer+info->buffer_length-
+ (pos & (IO_SIZE-1)));
}
info->pos_in_file=pos;
info->seek_not_done=1;
+ DBUG_VOID_RETURN;
}
+
/*
-** Fill buffer. Note that this assumes that you have already used
-** all characters in the CACHE, independent of the rc_pos value!
-** return: 0 on error or EOF (info->error = -1 on error)
-** number of characters
+ Fill buffer. Note that this assumes that you have already used
+ all characters in the CACHE, independent of the read_pos value!
+ return: 0 on error or EOF (info->error = -1 on error)
+ number of characters
*/
uint my_b_fill(IO_CACHE *info)
{
- my_off_t pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
+ my_off_t pos_in_file=(info->pos_in_file+
+ (uint) (info->read_end - info->buffer));
my_off_t max_length;
uint diff_length,length;
if (info->seek_not_done)
@@ -103,16 +162,18 @@ uint my_b_fill(IO_CACHE *info)
info->error= -1;
return 0;
}
- info->rc_pos=info->buffer;
- info->rc_end=info->buffer+length;
+ info->read_pos=info->buffer;
+ info->read_end=info->buffer+length;
info->pos_in_file=pos_in_file;
return length;
}
+
/*
-** Read a string ended by '\n' into a buffer of 'max_length' size.
-** Returns number of characters read, 0 on error.
-** last byte is set to '\0'
+ Read a string ended by '\n' into a buffer of 'max_length' size.
+ Returns number of characters read, 0 on error.
+ last byte is set to '\0'
+ If buffer is full then to[max_length-1] will be set to \0.
*/
uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
@@ -129,11 +190,11 @@ uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
char *pos,*end;
if (length > max_length)
length=max_length;
- for (pos=info->rc_pos,end=pos+length ; pos < end ;)
+ for (pos=info->read_pos,end=pos+length ; pos < end ;)
{
if ((*to++ = *pos++) == '\n')
{
- info->rc_pos=pos;
+ info->read_pos=pos;
*to='\0';
return (uint) (to-start);
}
@@ -141,7 +202,7 @@ uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
if (!(max_length-=length))
{
/* Found enough charcters; Return found string */
- info->rc_pos=pos;
+ info->read_pos=pos;
*to='\0';
return (uint) (to-start);
}
@@ -150,6 +211,21 @@ uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
}
}
+
+my_off_t my_b_filelength(IO_CACHE *info)
+{
+ if (info->type == WRITE_CACHE)
+ {
+ return my_b_tell(info);
+ }
+ else
+ {
+ info->seek_not_done=1;
+ return my_seek(info->file,0L,MY_SEEK_END,MYF(0));
+ }
+}
+
+
/*
Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
Used for logging in MySQL
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index d5b0a0a056a..977ca6b11a7 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
This functions is handle keyblock cacheing for NISAM, MISAM and PISAM
@@ -53,17 +52,19 @@ typedef struct sec_link {
} SEC_LINK;
-static uint find_next_bigger_power(uint value);
static SEC_LINK *find_key_block(int file,my_off_t filepos,int *error);
+static int flush_all_key_blocks();
/* static variables in this file */
static SEC_LINK *_my_block_root,**_my_hash_root,
*_my_used_first,*_my_used_last;
static int _my_disk_blocks;
static uint _my_disk_blocks_used, _my_hash_blocks;
+static uint key_cache_shift;
ulong _my_blocks_used,_my_blocks_changed;
ulong _my_cache_w_requests,_my_cache_write,_my_cache_r_requests,
_my_cache_read;
+uint key_cache_block_size=DEFAULT_KEYCACHE_BLOCK_SIZE;
static byte HUGE_PTR *_my_block_mem;
static SEC_LINK *changed_blocks[CHANGED_BLOCKS_HASH];
static SEC_LINK *file_blocks[CHANGED_BLOCKS_HASH];
@@ -76,11 +77,9 @@ static my_bool _my_printed;
/* Returns blocks in use */
/* ARGSUSED */
-int init_key_cache(ulong use_mem,
- ulong leave_this_much_mem __attribute__((unused)))
+int init_key_cache(ulong use_mem)
{
uint blocks,length;
- byte *extra_mem=0;
DBUG_ENTER("init_key_cache");
if (key_cache_inited && _my_disk_blocks > 0)
@@ -92,28 +91,30 @@ int init_key_cache(ulong use_mem,
{
key_cache_inited=TRUE;
_my_disk_blocks= -1;
+ key_cache_shift=my_bit_log2(key_cache_block_size);
+ DBUG_PRINT("info",("key_cache_block_size: %u key_cache_shift: %u",
+ key_cache_block_size, key_cache_shift));
#ifndef DBUG_OFF
_my_printed=0;
#endif
}
- blocks= (uint) (use_mem/(sizeof(SEC_LINK)+sizeof(SEC_LINK*)*5/4+KEYCACHE_BLOCK_SIZE));
+ blocks= (uint) (use_mem/(sizeof(SEC_LINK)+sizeof(SEC_LINK*)*5/4+
+ key_cache_block_size));
/* No use to have very few blocks */
if (blocks >= 8 && _my_disk_blocks < 0)
{
-#if !defined(HAVE_ALLOCA) && !defined(THREAD)
- if ((extra_mem=my_malloc((uint) leave_this_much_mem,MYF(0))) == 0)
- goto err;
-#endif
for (;;)
{
- if ((_my_hash_blocks=find_next_bigger_power((uint) blocks)) < blocks*5/4)
- _my_hash_blocks<<=1;
+ /* Set my_hash_blocks to the next bigger 2 power */
+ _my_hash_blocks=(uint) 1 << (my_bit_log2(blocks*5/4)+1);
while ((length=(uint) blocks*sizeof(SEC_LINK)+
- sizeof(SEC_LINK*)*_my_hash_blocks)+(ulong) blocks*KEYCACHE_BLOCK_SIZE >
+ sizeof(SEC_LINK*)*_my_hash_blocks)+
+ ((ulong) blocks << key_cache_shift) >
use_mem)
blocks--;
- if ((_my_block_mem=my_malloc_lock((ulong) blocks * KEYCACHE_BLOCK_SIZE,MYF(0))))
+ if ((_my_block_mem=my_malloc_lock((ulong) blocks << key_cache_shift,
+ MYF(0))))
{
if ((_my_block_root=(SEC_LINK*) my_malloc((uint) length,MYF(0))) != 0)
break;
@@ -132,21 +133,48 @@ int init_key_cache(ulong use_mem,
DBUG_PRINT("exit",("disk_blocks: %d block_root: %lx _my_hash_blocks: %d hash_root: %lx",
_my_disk_blocks,_my_block_root,_my_hash_blocks,
_my_hash_root));
-#if !defined(HAVE_ALLOCA) && !defined(THREAD)
- my_free(extra_mem,MYF(0));
-#endif
}
bzero((gptr) changed_blocks,sizeof(changed_blocks[0])*CHANGED_BLOCKS_HASH);
bzero((gptr) file_blocks,sizeof(file_blocks[0])*CHANGED_BLOCKS_HASH);
DBUG_RETURN((int) blocks);
+
err:
- if (extra_mem) /* purecov: inspected */
- my_free(extra_mem,MYF(0));
my_errno=ENOMEM;
DBUG_RETURN(0);
} /* init_key_cache */
+/*
+ Resize the key cache
+
+ SYNOPSIS
+ resize_key_cache()
+ use_mem Bytes to use for new key cache
+
+ RETURN VALUES
+ 0 Error
+ # number of blocks in key cache
+*/
+
+
+int resize_key_cache(ulong use_mem)
+{
+ int block;
+ pthread_mutex_lock(&THR_LOCK_keycache);
+ if (flush_all_key_blocks())
+ {
+ /* TODO: If this happens, we should write a warning in the log file ! */
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return 0;
+ }
+ end_key_cache();
+ /* The following will work even if memory is 0 */
+ block=init_key_cache(use_mem);
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return block;
+}
+
+
/* Remove key_cache from memory */
void end_key_cache(void)
@@ -162,6 +190,7 @@ void end_key_cache(void)
}
}
key_cache_inited=0;
+ _my_hash_blocks=_my_blocks_used=0;
DBUG_PRINT("status",
("used: %d changed: %d w_requests: %ld writes: %ld r_requests: %ld reads: %ld",
_my_blocks_used,_my_blocks_changed,_my_cache_w_requests,
@@ -170,17 +199,6 @@ void end_key_cache(void)
} /* end_key_cache */
-static uint find_next_bigger_power(uint value)
-{
- uint old_value=1;
- while (value)
- {
- old_value=value;
- value&= value-1;
- }
- return (old_value << 1);
-}
-
static inline void link_into_file_blocks(SEC_LINK *next, int file)
{
reg1 SEC_LINK **ptr= &file_blocks[(uint) file & CHANGED_BLOCKS_MASK];
@@ -243,7 +261,7 @@ static void test_key_cache(const char *where, my_bool lock);
/*
** read a key_buffer
- ** filepos must point at a even KEYCACHE_BLOCK_SIZE block
+ ** filepos must point at a even key_cache_block_size block
** if return_buffer is set then the intern buffer is returned if
** it can be used
** Returns adress to where data is read
@@ -255,9 +273,12 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
{
reg1 SEC_LINK *next;
int error=0;
+ DBUG_ENTER("key_cache_read");
+ DBUG_PRINT("enter", ("file %u, filepos %lu, length %u",
+ (uint) file, (ulong) filepos, length));
#ifndef THREAD
- if (block_length > KEYCACHE_BLOCK_SIZE)
+ if (block_length > key_cache_block_size)
return_buffer=0;
#endif
if (_my_disk_blocks > 0)
@@ -265,21 +286,27 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
byte *start=buff;
uint read_length;
pthread_mutex_lock(&THR_LOCK_keycache);
+ if (_my_disk_blocks <= 0) /* Resize failed */
+ {
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ goto no_key_cache;
+ }
do
{
_my_cache_r_requests++;
- read_length= length > KEYCACHE_BLOCK_SIZE ? KEYCACHE_BLOCK_SIZE : length;
+ read_length= (length > key_cache_block_size ? key_cache_block_size :
+ length);
if (!(next=find_key_block(file,filepos,&error)))
{
pthread_mutex_unlock(&THR_LOCK_keycache);
- return (byte*) 0; /* Got a fatal error */
+ DBUG_RETURN ((byte*) 0); /* Got a fatal error */
}
if (error)
{ /* Didn't find it in cache */
if (my_pread(file,next->buffer,read_length,filepos,MYF(MY_NABP)))
{
pthread_mutex_unlock(&THR_LOCK_keycache);
- return((byte*) 0);
+ DBUG_RETURN((byte*) 0);
}
_my_cache_read++;
}
@@ -287,7 +314,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
if (return_buffer)
{
pthread_mutex_unlock(&THR_LOCK_keycache);
- return (next->buffer);
+ DBUG_RETURN (next->buffer);
}
#endif
if (! (read_length & 511))
@@ -298,19 +325,21 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
filepos+=read_length;
} while ((length-= read_length));
pthread_mutex_unlock(&THR_LOCK_keycache);
- return(start);
+ DBUG_RETURN(start);
}
+
+no_key_cache:
_my_cache_r_requests++;
_my_cache_read++;
if (my_pread(file,(byte*) buff,length,filepos,MYF(MY_NABP)))
error=1;
- return (error ? (byte*) 0 : buff);
+ DBUG_RETURN(error ? (byte*) 0 : buff);
} /* key_cache_read */
/* write a key_buffer */
/* We don't have to use pwrite because of write locking */
- /* buff must point at a even KEYCACHE_BLOCK_SIZE block */
+ /* buff must point at a even key_cache_block_size block */
int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
uint block_length __attribute__((unused)),
@@ -318,12 +347,15 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
{
reg1 SEC_LINK *next;
int error=0;
+ DBUG_ENTER("key_cache_write");
+ DBUG_PRINT("enter", ("file %u, filepos %lu, length %u",
+ (uint) file, (ulong) filepos, length));
if (!dont_write)
{ /* Forced write of buffer */
_my_cache_write++;
if (my_pwrite(file,buff,length,filepos,MYF(MY_NABP | MY_WAIT_IF_FULL)))
- return(1);
+ DBUG_RETURN(1);
}
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
@@ -333,10 +365,16 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
{ /* We have key_cacheing */
uint read_length;
pthread_mutex_lock(&THR_LOCK_keycache);
+ if (_my_disk_blocks <= 0) /* If resize failed */
+ {
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ goto no_key_cache;
+ }
+
_my_cache_w_requests++;
do
{
- read_length= length > KEYCACHE_BLOCK_SIZE ? KEYCACHE_BLOCK_SIZE : length;
+ read_length= length > key_cache_block_size ? key_cache_block_size : length;
if (!(next=find_key_block(file,filepos,&error)))
goto end; /* Fatal error */
if (!dont_write) /* If we wrote buff at start */
@@ -356,8 +394,11 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
} while ((length-= read_length));
error=0;
pthread_mutex_unlock(&THR_LOCK_keycache);
+ goto end;
}
- else if (dont_write)
+
+no_key_cache:
+ if (dont_write)
{ /* We must write, no cache */
_my_cache_w_requests++;
_my_cache_write++;
@@ -365,11 +406,12 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
MYF(MY_NABP | MY_WAIT_IF_FULL)))
error=1;
}
+
end:
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache",test_key_cache("end of key_cache_write",1););
#endif
- return(error);
+ DBUG_RETURN(error);
} /* key_cache_write */
@@ -379,13 +421,16 @@ end:
static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
{
reg1 SEC_LINK *next,**start;
+ DBUG_ENTER("find_key_block");
+ DBUG_PRINT("enter", ("file %u, filepos %lu",
+ (uint) file, (ulong) filepos));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache2",test_key_cache("start of find_key_block",0););
#endif
*error=0;
- next= *(start= &_my_hash_root[((ulong) (filepos/KEYCACHE_BLOCK_SIZE)+(ulong) file) &
+ next= *(start= &_my_hash_root[((ulong) (filepos >> key_cache_shift)+(ulong) file) &
(_my_hash_blocks-1)]);
while (next && (next->diskpos != filepos || next->file != file))
next= next->next_hash;
@@ -411,7 +456,8 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
{ /* There are unused blocks */
next= &_my_block_root[_my_blocks_used++]; /* Link in hash-chain */
next->buffer=ADD_TO_PTR(_my_block_mem,
- (ulong) _my_disk_blocks_used*KEYCACHE_BLOCK_SIZE,byte*);
+ ((ulong) _my_disk_blocks_used << key_cache_shift),
+ byte*);
/* link first in file_blocks */
next->changed=0;
link_into_file_blocks(next,file);
@@ -426,7 +472,8 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
next= _my_used_first;
if (next->changed)
{
- if (my_pwrite(next->file,next->buffer,KEYCACHE_BLOCK_SIZE,next->diskpos,
+ if (my_pwrite(next->file,next->buffer,key_cache_block_size,
+ next->diskpos,
MYF(MY_NABP | MY_WAIT_IF_FULL)))
{
*error=1;
@@ -461,7 +508,7 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache2",test_key_cache("end of find_key_block",0););
#endif
- return next;
+ DBUG_RETURN(next);
} /* find_key_block */
@@ -499,13 +546,15 @@ static int cmp_sec_link(SEC_LINK **a, SEC_LINK **b)
((*a)->diskpos > (*b)->diskpos) ? 1 : 0);
}
+
static int flush_cached_blocks(File file, SEC_LINK **cache, uint count)
{
uint last_errno=0;
qsort((byte*) cache, count, sizeof(*cache), (qsort_cmp) cmp_sec_link);
for ( ; count-- ; cache++)
{
- if (my_pwrite(file,(*cache)->buffer,KEYCACHE_BLOCK_SIZE,(*cache)->diskpos,
+ if (my_pwrite(file,(*cache)->buffer,key_cache_block_size,
+ (*cache)->diskpos,
MYF(MY_NABP | MY_WAIT_IF_FULL)))
{
if (!last_errno)
@@ -516,25 +565,23 @@ static int flush_cached_blocks(File file, SEC_LINK **cache, uint count)
}
-int flush_key_blocks(File file, enum flush_type type)
+static int flush_key_blocks_int(File file, enum flush_type type)
{
int error=0,last_errno=0;
uint count=0;
SEC_LINK *cache_buff[FLUSH_CACHE],**cache,**pos,**end;
SEC_LINK *used,*next;
- DBUG_ENTER("flush_key_blocks");
+ DBUG_ENTER("flush_key_blocks_int");
DBUG_PRINT("enter",("file: %d blocks_used: %d blocks_changed: %d",
file,_my_blocks_used,_my_blocks_changed));
- pthread_mutex_lock(&THR_LOCK_keycache);
-
-#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
- DBUG_EXECUTE("check_keycache",test_key_cache("start of flush_key_blocks",0););
-#endif
cache=cache_buff; /* If no key cache */
if (_my_disk_blocks > 0 &&
(!my_disable_flush_key_blocks || type != FLUSH_KEEP))
{
+#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
+ DBUG_EXECUTE("check_keycache",test_key_cache("start of flush_key_blocks",0););
+#endif
if (type != FLUSH_IGNORE_CHANGED)
{
/* Count how many key blocks we have to cache to be able to
@@ -606,22 +653,77 @@ int flush_key_blocks(File file, enum flush_type type)
free_block(used);
}
}
- }
#ifndef DBUG_OFF
- DBUG_EXECUTE("check_keycache",test_key_cache("end of flush_key_blocks",0););
+ DBUG_EXECUTE("check_keycache",test_key_cache("end of flush_key_blocks",0););
#endif
- pthread_mutex_unlock(&THR_LOCK_keycache);
+ }
if (cache != cache_buff)
my_free((gptr) cache,MYF(0));
if (last_errno)
errno=last_errno; /* Return first error */
DBUG_RETURN(last_errno != 0);
-} /* flush_key_blocks */
+}
+
+
+/*
+ Flush all blocks for a specific file to disk
+
+ SYNOPSIS
+ flush_key_blocks()
+ file File descriptor
+ type Type of flush operation
+
+ RETURN VALUES
+ 0 Ok
+ 1 Error
+*/
+
+int flush_key_blocks(File file, enum flush_type type)
+{
+ int res;
+ pthread_mutex_lock(&THR_LOCK_keycache);
+ res=flush_key_blocks_int(file, type);
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return res;
+}
+
+
+/*
+ Flush all blocks in the key cache to disk
+
+ SYNOPSIS
+ flush_all_key_blocks()
+
+ NOTE
+ We must have a lock on THR_LOCK_keycache before calling this function
+
+ RETURN VALUES
+ 0 Ok
+ 1 Error
+*/
+
+
+static int flush_all_key_blocks()
+{
+ SEC_LINK **block, **end;
+ for (block= changed_blocks, end= block+CHANGED_BLOCKS_HASH;
+ block < end;
+ block++
+ )
+ {
+ while (*block)
+ {
+ if (flush_key_blocks_int((*block)->file, FLUSH_RELEASE))
+ return 1;
+ }
+ }
+ return 0;
+}
#ifndef DBUG_OFF
- /* Test if disk-cachee is ok */
+ /* Test if disk-cache is ok */
static void test_key_cache(const char *where, my_bool lock)
{
@@ -630,7 +732,14 @@ static void test_key_cache(const char *where, my_bool lock)
SEC_LINK *pos,**prev;
if (lock)
+ {
pthread_mutex_lock(&THR_LOCK_keycache);
+ if (_my_disk_blocks <= 0) /* No active key cache */
+ {
+ pthread_mutex_unlock(&THR_LOCK_keycache);
+ return;
+ }
+ }
found=error=0;
for (i= 0 ; i < _my_hash_blocks ; i++)
{
@@ -647,7 +756,7 @@ static void test_key_cache(const char *where, my_bool lock)
i,(ulong) pos,(ulong) prev,(ulong) pos->prev_hash));
}
- if (((pos->diskpos/KEYCACHE_BLOCK_SIZE)+pos->file) % _my_hash_blocks != i)
+ if (((pos->diskpos >> key_cache_shift)+pos->file) % _my_hash_blocks != i)
{
DBUG_PRINT("error",("hash: %d pos: %lx : Wrong disk_buffer %ld",
i,(ulong) pos,(ulong) pos->diskpos));
diff --git a/mysys/mf_loadpath.c b/mysys/mf_loadpath.c
index 641528b8b5d..291ad62e297 100644
--- a/mysys/mf_loadpath.c
+++ b/mysys/mf_loadpath.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -37,8 +36,7 @@ my_string my_load_path(my_string to, const char *path,
test_if_hard_path(path))
VOID(strmov(buff,path));
else if ((path[0] == FN_CURLIB && path[1] == FN_LIBCHAR) ||
- (is_prefix((gptr) path,FN_PARENTDIR) &&
- path[strlen(FN_PARENTDIR)] == FN_LIBCHAR) ||
+ (is_prefix((gptr) path,FN_PARENTDIR)) ||
! own_path_prefix)
{
if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)),MYF(0)))
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index b442af7e9e5..e2e811fe89a 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -40,6 +39,7 @@ void pack_dirname(my_string to, const char *from)
char buff[FN_REFLEN];
DBUG_ENTER("pack_dirname");
+ LINT_INIT(buff_length);
(void) intern_filename(to,from); /* Change to intern name */
#ifdef FN_DEVCHAR
@@ -49,7 +49,6 @@ void pack_dirname(my_string to, const char *from)
#endif
start=to;
- LINT_INIT(buff_length);
if (!(cwd_err= my_getwd(buff,FN_REFLEN,MYF(0))))
{
buff_length= (uint) strlen(buff);
@@ -211,14 +210,14 @@ uint cleanup_dirname(register my_string to, const char *from)
} /* cleanup_dirname */
- /*
- On system where you don't have symbolic links, the following
- code will allow you to create a file:
- directory-name.lnk that should contain the real path
- to the directory. This will be used if the directory name
- doesn't exists
- */
-
+/*
+ On system where you don't have symbolic links, the following
+ code will allow you to create a file:
+ directory-name.sym that should contain the real path
+ to the directory. This will be used if the directory name
+ doesn't exists
+*/
+
my_bool my_use_symdir=0; /* Set this if you want to use symdirs */
@@ -229,16 +228,17 @@ void symdirget(char *dir)
char *pos=strend(dir);
if (dir[0] && pos[-1] != FN_DEVCHAR && access(dir, F_OK))
{
- FILE *fp;
+ File file;
+ uint length;
char temp= *(--pos); /* May be "/" or "\" */
strmov(pos,".sym");
- fp = my_fopen(dir, O_RDONLY,MYF(0));
+ file= my_open(dir, O_RDONLY, MYF(0));
*pos++=temp; *pos=0; /* Restore old filename */
- if (fp)
+ if (file >= 0)
{
- if (fgets(buff, sizeof(buff)-1, fp))
+ if ((length= my_read(file, buff, sizeof(buff), MYF(0))) > 0)
{
- for (pos=strend(buff);
+ for (pos= buff + length ;
pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ;
pos --);
@@ -248,21 +248,33 @@ void symdirget(char *dir)
strmake(dir,buff, (uint) (pos-buff));
}
- my_fclose(fp,MYF(0));
+ my_close(file, MYF(0));
}
}
}
#endif /* USE_SYMDIR */
- /* Unpacks dirname to name that can be used by open... */
- /* Make that last char of to is '/' if from not empty and
- from doesn't end in FN_DEVCHAR */
- /* Uses cleanup_dirname and changes ~/.. to home_dir/.. */
- /* Returns length of new directory */
-uint unpack_dirname(my_string to, const char *from)
+/*
+ Fixes a directroy name so that can be used by open()
+
+ SYNOPSIS
+ unpack_dirname()
+ to Store result here. May be = from
+ from 'Packed' directory name (may contain ~)
+
+ IMPLEMENTATION
+ Make that last char of to is '/' if from not empty and
+ from doesn't end in FN_DEVCHAR
+ Uses cleanup_dirname and changes ~/.. to home_dir/..
- /* to may be == from */
+ Changes a UNIX filename to system filename (replaces / with \ on windows)
+
+ RETURN
+ Length of new directory name (= length of to)
+*/
+
+uint unpack_dirname(my_string to, const char *from)
{
uint length,h_length;
char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion;
@@ -459,8 +471,7 @@ my_string intern_filename(my_string to, const char *from)
my_string pos,from_pos,to_pos,end_pos;
char buff[FN_REFLEN];
- (void) strmov(buff,from);
- convert_dirname(buff); /* change '<>' to '[]' */
+ convert_dirname(buff,from,NullS); /* change '<>' to '[]' */
from_pos=buff;
if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skipp device part */
{
diff --git a/mysys/mf_pack2.c b/mysys/mf_pack2.c
deleted file mode 100644
index 1cda7797457..00000000000
--- a/mysys/mf_pack2.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
- /* Pack a filename for output on screen */
- /* Changes long paths to .../ */
- /* Removes pathname and extension */
- /* If not possibly to pack returns '?' in to and returns 1*/
-
-int pack_filename(my_string to, const char *name, size_s max_length)
- /* to may be name */
-
-{
- int i;
- char buff[FN_REFLEN];
-
- if (strlen(fn_format(to,name,"","",0)) <= max_length)
- return 0;
- if (strlen(fn_format(to,name,"","",8)) <= max_length)
- return 0;
- if (strlen(fn_format(buff,name,".../","",1)) <= max_length)
- {
- VOID(strmov(to,buff));
- return 0;
- }
- for (i= 0 ; i < 3 ; i++)
- {
- if (strlen(fn_format(buff,to,"","", i == 0 ? 2 : i == 1 ? 1 : 3 ))
- <= max_length)
- {
- VOID(strmov(to,buff));
- return 0;
- }
- }
- to[0]='?'; to[1]=0; /* Can't pack filename */
- return 1;
-} /* pack_filename */
diff --git a/mysys/mf_path.c b/mysys/mf_path.c
index 9a88b938e2c..1ecd5fbb2b1 100644
--- a/mysys/mf_path.c
+++ b/mysys/mf_path.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -78,6 +77,9 @@ my_string my_path(my_string to, const char *progname,
#define F_OK 0
#define PATH_SEP ';'
#define PROGRAM_EXTENSION ".exe"
+#elif defined(__NETWARE__)
+#define PATH_SEP ';'
+#define PROGRAM_EXTENSION ".nlm"
#else
#define PATH_SEP ':'
#endif
diff --git a/mysys/mf_qsort2.c b/mysys/mf_qsort2.c
index 7b1ca4e39ab..160bb6df817 100644
--- a/mysys/mf_qsort2.c
+++ b/mysys/mf_qsort2.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* qsort that sends one extra argument to the compare subrutine */
diff --git a/mysys/mf_radix.c b/mysys/mf_radix.c
index 99aa4d0b073..7ee96b966b9 100644
--- a/mysys/mf_radix.c
+++ b/mysys/mf_radix.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Radixsort for pointers to fixed length strings.
diff --git a/mysys/mf_same.c b/mysys/mf_same.c
index c1a5cae11cb..efd6e7b2ca4 100644
--- a/mysys/mf_same.c
+++ b/mysys/mf_same.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Kopierar biblioteksstrukturen och extensionen fr}n ett filnamn */
diff --git a/mysys/mf_sleep.c b/mysys/mf_sleep.c
deleted file mode 100644
index f33a904cf5a..00000000000
--- a/mysys/mf_sleep.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* Wait a given time (On systems that dont have sleep !!; MSDOS) */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
-#ifdef _MSC_VER
-
-void sleep(sec)
-int sec;
-{
- ulong start;
- DBUG_ENTER("sleep");
-
- start=(ulong) time((time_t*) 0);
- while ((ulong) time((time_t*) 0) < start+sec);
- DBUG_VOID_RETURN;
-} /* sleep */
-
-#endif /* MSDOS */
diff --git a/mysys/mf_sort.c b/mysys/mf_sort.c
index 754a1deb1a7..0dc6c78a589 100644
--- a/mysys/mf_sort.c
+++ b/mysys/mf_sort.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Sort of string pointers in string-order with radix or qsort */
@@ -25,7 +24,7 @@ void my_string_ptr_sort(void *base, uint items, size_s size)
#if INT_MAX > 65536L
uchar **ptr=0;
- if (size <= 20 && items >= 1000 &&
+ if (size <= 20 && items >= 1000 && items < 100000 &&
(ptr= (uchar**) my_malloc(items*sizeof(char*),MYF(0))))
{
radixsort_for_str_ptr((uchar**) base,items,size,ptr);
diff --git a/mysys/mf_soundex.c b/mysys/mf_soundex.c
index 827385a1466..4f7aa7da601 100644
--- a/mysys/mf_soundex.c
+++ b/mysys/mf_soundex.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/****************************************************************
* SOUNDEX ALGORITHM in C *
diff --git a/mysys/mf_strip.c b/mysys/mf_strip.c
index 682c9c32cb0..ef2aab2c0a3 100644
--- a/mysys/mf_strip.c
+++ b/mysys/mf_strip.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* T|mmer en str{ng p{ slut_space */
diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c
index 465311088c1..cca80dcd552 100644
--- a/mysys/mf_tempfile.c
+++ b/mysys/mf_tempfile.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
@@ -25,7 +24,7 @@
#endif
#ifdef HAVE_TEMPNAM
-#if !defined( MSDOS) && !defined(OS2)
+#if !defined(MSDOS) && !defined(OS2) && !defined(__NETWARE__)
extern char **environ;
#endif
#endif
@@ -90,9 +89,10 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
uint pfx_len;
File org_file;
- pfx_len=(strmov(strnmov(prefix_buff,
- prefix ? prefix : "tmp.",
- sizeof(prefix_buff)-7),"XXXXXX") - prefix_buff);
+ pfx_len= (uint) (strmov(strnmov(prefix_buff,
+ prefix ? prefix : "tmp.",
+ sizeof(prefix_buff)-7),"XXXXXX") -
+ prefix_buff);
if (!dir && ! (dir =getenv("TMPDIR")))
dir=P_tmpdir;
if (strlen(dir)+ pfx_len > FN_REFLEN-2)
@@ -100,8 +100,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
errno=my_errno= ENAMETOOLONG;
return 1;
}
- strmov(to,dir);
- strmov(convert_dirname(to),prefix_buff);
+ strmov(convert_dirname(to,dir,NullS),prefix_buff);
org_file=mkstemp(to);
file=my_register_filename(org_file, to, FILE_BY_MKSTEMP,
EE_CANTCREATEFILE, MyFlags);
@@ -123,14 +122,14 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
dir=to;
}
#ifdef OS2
- // changing environ variable doesn't work with VACPP
+ /* changing environ variable doesn't work with VACPP */
char buffer[256];
sprintf( buffer, "TMP=%s", dir);
- // remove ending backslash
+ /* remove ending backslash */
if (buffer[strlen(buffer)-1] == '\\')
buffer[strlen(buffer)-1] = '\0';
putenv( buffer);
-#else
+#elif !defined(__NETWARE__)
old_env= (char**) environ;
if (dir)
{ /* Don't use TMPDIR if dir is given */
@@ -152,7 +151,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
{
DBUG_PRINT("error",("Got error: %d from tempnam",errno));
}
-#ifndef OS2
+#if !defined(OS2) && !defined(__NETWARE__)
environ=(const char**) old_env;
#endif
}
@@ -178,7 +177,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
if (end_pos != to && end_pos[-1] != FN_LIBCHAR)
*end_pos++=FN_LIBCHAR;
end_pos=strmov(end_pos,pfx);
-
+
for (length=0 ; length < 8 && uniq ; length++)
{
*end_pos++= _dig_vec[(int) (uniq & 31)];
diff --git a/mysys/mf_unixpath.c b/mysys/mf_unixpath.c
index 6ae29f99136..9efc3e5d9b8 100644
--- a/mysys/mf_unixpath.c
+++ b/mysys/mf_unixpath.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <m_string.h>
diff --git a/mysys/mf_util.c b/mysys/mf_util.c
index 12af323680e..132c83b4623 100644
--- a/mysys/mf_util.c
+++ b/mysys/mf_util.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Utilities with are missing on some systems */
diff --git a/mysys/mf_wcomp.c b/mysys/mf_wcomp.c
index 5f1ab9b813e..bdcfb0501d8 100644
--- a/mysys/mf_wcomp.c
+++ b/mysys/mf_wcomp.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Funktions for comparing with wild-cards */
diff --git a/mysys/mf_wfile.c b/mysys/mf_wfile.c
index 87d1392250a..e9e12c72755 100644
--- a/mysys/mf_wfile.c
+++ b/mysys/mf_wfile.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Functions for finding files with wildcards */
diff --git a/mysys/mulalloc.c b/mysys/mulalloc.c
index 8a7ee312aa9..6b025bca699 100644
--- a/mysys/mulalloc.c
+++ b/mysys/mulalloc.c
@@ -1,26 +1,35 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- /* Malloc many pointers at the same time */
- /* format myFlags,ptr,length,ptr,length ... until null ptr */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include <stdarg.h>
+/*
+ Malloc many pointers at the same time
+
+ SYNOPSIS
+ my_multi_malloc()
+ myFlags Flags
+ ... Multiple arguments terminated by null ptr
+
+ ptr, length
+ ptr, length
+ NULL
+*/
+
gptr my_multi_malloc(myf myFlags, ...)
{
va_list args;
diff --git a/mysys/my_aes.c b/mysys/my_aes.c
new file mode 100644
index 00000000000..16d326d7d1f
--- /dev/null
+++ b/mysys/my_aes.c
@@ -0,0 +1,228 @@
+/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ Implementation of AES Encryption for MySQL
+ Initial version by Peter Zaitsev June 2002
+*/
+
+
+#include <my_global.h>
+#include <m_string.h>
+#include "my_aes.h"
+
+enum encrypt_dir { AES_ENCRYPT, AES_DECRYPT };
+
+#define AES_BLOCK_SIZE 16 /* Block size in bytes */
+
+#define AES_BAD_DATA -1 /* If bad data discovered during decoding */
+
+
+/* The structure for key information */
+typedef struct {
+ int nr; /* Number of rounds */
+ uint32 rk[4*(AES_MAXNR + 1)]; /* key schedule */
+} KEYINSTANCE;
+
+
+/*
+ This is internal function just keeps joint code of Key generation
+
+ SYNOPSIS
+ my_aes_create_key()
+ aes_key Address of Key Instance to be created
+ direction Direction (are we encoding or decoding)
+ key Key to use for real key creation
+ key_length Length of the key
+
+ DESCRIPTION
+
+ RESULT
+ 0 ok
+ -1 Error Note: The current impementation never returns this
+*/
+
+static int my_aes_create_key(KEYINSTANCE *aes_key,
+ enum encrypt_dir direction, const char *key,
+ int key_length)
+{
+ uint8 rkey[AES_KEY_LENGTH/8]; /* The real key to be used for encryption */
+ uint8 *rkey_end=rkey+AES_KEY_LENGTH/8; /* Real key boundary */
+ uint8 *ptr; /* Start of the real key*/
+ const char *sptr; /* Start of the working key */
+ const char *key_end=key+key_length; /* Working key boundary*/
+
+ bzero((char*) rkey,AES_KEY_LENGTH/8); /* Set initial key */
+
+ for (ptr= rkey, sptr= key; sptr < key_end; ptr++,sptr++)
+ {
+ if (ptr == rkey_end)
+ ptr= rkey; /* Just loop over tmp_key until we used all key */
+ *ptr^= (uint8) *sptr;
+ }
+#ifdef AES_USE_KEY_BITS
+ /*
+ This block is intended to allow more weak encryption if application
+ build with libmysqld needs to correspond to export regulations
+ It should be never used in normal distribution as does not give
+ any speed improvement.
+ To get worse security define AES_USE_KEY_BITS to number of bits
+ you want key to be. It should be divisible by 8
+
+ WARNING: Changing this value results in changing of enryption for
+ all key lengths so altering this value will result in impossibility
+ to decrypt data encrypted with previous value
+ */
+#define AES_USE_KEY_BYTES (AES_USE_KEY_BITS/8)
+ /*
+ To get weaker key we use first AES_USE_KEY_BYTES bytes of created key
+ and cyclically copy them until we created all required key length
+ */
+ for (ptr= rkey+AES_USE_KEY_BYTES, sptr=rkey ; ptr < rkey_end;
+ ptr++,sptr++)
+ {
+ if (sptr == rkey+AES_USE_KEY_BYTES)
+ sptr=rkey;
+ *ptr=*sptr;
+ }
+#endif
+ if (direction == AES_DECRYPT)
+ aes_key->nr = rijndaelKeySetupDec(aes_key->rk, rkey, AES_KEY_LENGTH);
+ else
+ aes_key->nr = rijndaelKeySetupEnc(aes_key->rk, rkey, AES_KEY_LENGTH);
+ return 0;
+}
+
+
+/*
+ Crypt buffer with AES encryption algorithm.
+
+ SYNOPSIS
+ my_aes_encrypt()
+ source Pointer to data for encryption
+ source_length Size of encryption data
+ dest Buffer to place encrypted data (must be large enough)
+ key Key to be used for encryption
+ key_length Length of the key. Will handle keys of any length
+
+ RETURN
+ >= 0 Size of encrypted data
+ < 0 Error
+*/
+
+int my_aes_encrypt(const char* source, int source_length, char* dest,
+ const char* key, int key_length)
+{
+ KEYINSTANCE aes_key;
+ uint8 block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
+ int rc; /* result codes */
+ int num_blocks; /* number of complete blocks */
+ char pad_len; /* pad size for the last block */
+ int i;
+
+ if ((rc= my_aes_create_key(&aes_key,AES_ENCRYPT,key,key_length)))
+ return rc;
+
+ num_blocks = source_length/AES_BLOCK_SIZE;
+
+ for (i = num_blocks; i > 0; i--) /* Encode complete blocks */
+ {
+ rijndaelEncrypt(aes_key.rk, aes_key.nr, (const uint8*) source,
+ (uint8*) dest);
+ source+= AES_BLOCK_SIZE;
+ dest+= AES_BLOCK_SIZE;
+ }
+
+ /* Encode the rest. We always have incomplete block */
+ pad_len = AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE*num_blocks);
+ memcpy(block, source, 16 - pad_len);
+ bfill(block + AES_BLOCK_SIZE - pad_len, pad_len, pad_len);
+ rijndaelEncrypt(aes_key.rk, aes_key.nr, block, (uint8*) dest);
+ return AES_BLOCK_SIZE*(num_blocks + 1);
+}
+
+
+/*
+ DeCrypt buffer with AES encryption algorithm.
+
+ SYNOPSIS
+ my_aes_decrypt()
+ source Pointer to data for decryption
+ source_length Size of encrypted data
+ dest Buffer to place decrypted data (must be large enough)
+ key Key to be used for decryption
+ key_length Length of the key. Will handle keys of any length
+
+ RETURN
+ >= 0 Size of encrypted data
+ < 0 Error
+*/
+
+int my_aes_decrypt(const char *source, int source_length, char *dest,
+ const char *key, int key_length)
+{
+ KEYINSTANCE aes_key;
+ uint8 block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
+ int rc; /* Result codes */
+ int num_blocks; /* Number of complete blocks */
+ uint pad_len; /* Pad size for the last block */
+ int i;
+
+ if ((rc=my_aes_create_key(&aes_key,AES_DECRYPT,key,key_length)))
+ return rc;
+
+ num_blocks = source_length/AES_BLOCK_SIZE;
+
+ if ((source_length != num_blocks*AES_BLOCK_SIZE) || num_blocks ==0 )
+ return AES_BAD_DATA; /* Input size has to be even and at least one block */
+
+ for (i = num_blocks-1; i > 0; i--) /* Decode all but last blocks */
+ {
+ rijndaelDecrypt(aes_key.rk, aes_key.nr, (const uint8*) source,
+ (uint8*) dest);
+ source+= AES_BLOCK_SIZE;
+ dest+= AES_BLOCK_SIZE;
+ }
+
+ rijndaelDecrypt(aes_key.rk, aes_key.nr, (const uint8*) source, block);
+ /* Use last char in the block as size */
+ pad_len = (uint) (uchar) block[AES_BLOCK_SIZE-1];
+
+ if (pad_len > AES_BLOCK_SIZE)
+ return AES_BAD_DATA;
+ /* We could also check whole padding but we do not really need this */
+
+ memcpy(dest, block, AES_BLOCK_SIZE - pad_len);
+ return AES_BLOCK_SIZE*num_blocks - pad_len;
+}
+
+
+/*
+ Get size of buffer which will be large enough for encrypted data
+
+ SYNOPSIS
+ my_aes_get_size()
+ source_length Length of data to be encrypted
+
+ RETURN
+ Size of buffer required to store encrypted data
+*/
+
+int my_aes_get_size(int source_length)
+{
+ return AES_BLOCK_SIZE*(source_length/AES_BLOCK_SIZE)+AES_BLOCK_SIZE;
+}
diff --git a/mysys/my_alarm.c b/mysys/my_alarm.c
index aab01ad77f4..70daf4a9dd0 100644
--- a/mysys/my_alarm.c
+++ b/mysys/my_alarm.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Function to set a varible when we got a alarm */
/* Used by my_lock samt functions in m_alarm.h */
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index db482454e69..d03ec5841af 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -1,47 +1,118 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Routines to handle mallocing of results which will be freed the same time */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
+#undef EXTRA_DEBUG
+#define EXTRA_DEBUG
-void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size)
+void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
+ uint pre_alloc_size __attribute__((unused)))
{
- mem_root->free=mem_root->used=0;
- mem_root->min_malloc=32;
- mem_root->block_size=block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
- mem_root->error_handler=0;
+ mem_root->free= mem_root->used= mem_root->pre_alloc= 0;
+ mem_root->min_malloc= 32;
+ mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
+ mem_root->error_handler= 0;
+ mem_root->block_num= 4; /* We shift this with >>2 */
+ mem_root->first_block_usage= 0;
+
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
if (pre_alloc_size)
{
- if ((mem_root->free = mem_root->pre_alloc=
+ if ((mem_root->free= mem_root->pre_alloc=
(USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)),
MYF(0))))
{
- mem_root->free->size=pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
- mem_root->free->left=pre_alloc_size;
- mem_root->free->next=0;
+ mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
+ mem_root->free->left= pre_alloc_size;
+ mem_root->free->next= 0;
}
}
#endif
}
+/*
+ SYNOPSIS
+ reset_root_defaults()
+ mem_root memory root to change defaults of
+ block_size new value of block size. Must be
+ greater than ~68 bytes (the exact value depends on
+ platform and compilation flags)
+ pre_alloc_size new size of preallocated block. If not zero,
+ must be equal to or greater than block size,
+ otherwise means 'no prealloc'.
+ DESCRIPTION
+ Function aligns and assigns new value to block size; then it tries to
+ reuse one of existing blocks as prealloc block, or malloc new one of
+ requested size. If no blocks can be reused, all unused blocks are freed
+ before allocation.
+ */
+
+void reset_root_defaults(MEM_ROOT *mem_root, uint block_size,
+ uint pre_alloc_size)
+{
+ mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
+#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
+ if (pre_alloc_size)
+ {
+ uint size= pre_alloc_size + ALIGN_SIZE(sizeof(USED_MEM));
+ if (!mem_root->pre_alloc || mem_root->pre_alloc->size != size)
+ {
+ USED_MEM *mem, **prev= &mem_root->free;
+ /*
+ Free unused blocks, so that consequent calls
+ to reset_root_defaults won't eat away memory.
+ */
+ while (*prev)
+ {
+ mem= *prev;
+ if (mem->size == size)
+ {
+ /* We found a suitable block, no need to do anything else */
+ mem_root->pre_alloc= mem;
+ return;
+ }
+ if (mem->left + ALIGN_SIZE(sizeof(USED_MEM)) == mem->size)
+ {
+ /* remove block from the list and free it */
+ *prev= mem->next;
+ my_free((gptr) mem, MYF(0));
+ }
+ else
+ prev= &mem->next;
+ }
+ /* Allocate new prealloc block and add it to the end of free list */
+ if ((mem= (USED_MEM *) my_malloc(size, MYF(0))))
+ {
+ mem->size= size;
+ mem->left= pre_alloc_size;
+ mem->next= *prev;
+ *prev= mem_root->pre_alloc= mem;
+ }
+ }
+ }
+ else
+#endif
+ mem_root->pre_alloc= 0;
+}
+
+
gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
{
#if defined(HAVE_purify) && defined(EXTRA_DEBUG)
@@ -54,29 +125,37 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
(*mem_root->error_handler)();
return((gptr) 0); /* purecov: inspected */
}
- next->next=mem_root->used;
- mem_root->used=next;
+ next->next= mem_root->used;
+ next->size= Size;
+ mem_root->used= next;
return (gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)));
#else
- uint get_size,max_left;
+ uint get_size, block_size;
gptr point;
- reg1 USED_MEM *next;
+ reg1 USED_MEM *next= 0;
reg2 USED_MEM **prev;
Size= ALIGN_SIZE(Size);
- prev= &mem_root->free;
- max_left=0;
- for (next= *prev ; next && next->left < Size ; next= next->next)
+ if ((*(prev= &mem_root->free)) != NULL)
{
- if (next->left > max_left)
- max_left=next->left;
- prev= &next->next;
+ if ((*prev)->left < Size &&
+ mem_root->first_block_usage++ >= ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP &&
+ (*prev)->left < ALLOC_MAX_BLOCK_TO_DROP)
+ {
+ next= *prev;
+ *prev= next->next; /* Remove block from list */
+ next->next= mem_root->used;
+ mem_root->used= next;
+ mem_root->first_block_usage= 0;
+ }
+ for (next= *prev ; next && next->left < Size ; next= next->next)
+ prev= &next->next;
}
if (! next)
{ /* Time to alloc new block */
+ block_size= mem_root->block_size * (mem_root->block_num >> 2);
get_size= Size+ALIGN_SIZE(sizeof(USED_MEM));
- if (max_left*4 < mem_root->block_size && get_size < mem_root->block_size)
- get_size=mem_root->block_size; /* Normal alloc */
+ get_size= max(get_size, block_size);
if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
{
@@ -84,23 +163,55 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
(*mem_root->error_handler)();
return((gptr) 0); /* purecov: inspected */
}
+ mem_root->block_num++;
next->next= *prev;
next->size= get_size;
next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
*prev=next;
}
+
point= (gptr) ((char*) next+ (next->size-next->left));
+ /*TODO: next part may be unneded due to mem_root->first_block_usage counter*/
if ((next->left-= Size) < mem_root->min_malloc)
{ /* Full block */
- *prev=next->next; /* Remove block from list */
- next->next=mem_root->used;
- mem_root->used=next;
+ *prev= next->next; /* Remove block from list */
+ next->next= mem_root->used;
+ mem_root->used= next;
+ mem_root->first_block_usage= 0;
}
return(point);
#endif
}
- /* deallocate everything used by alloc_root */
+/* Mark all data in blocks free for reusage */
+
+static inline void mark_blocks_free(MEM_ROOT* root)
+{
+ reg1 USED_MEM *next;
+ reg2 USED_MEM **last;
+
+ /* iterate through (partially) free blocks, mark them free */
+ last= &root->free;
+ for (next= root->free; next; next= *(last= &next->next))
+ next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
+
+ /* Combine the free and the used list */
+ *last= next=root->used;
+
+ /* now go through the used blocks and mark them free */
+ for (; next; next= next->next)
+ next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
+
+ /* Now everything is set; Indicate that nothing is used anymore */
+ root->used= 0;
+ root->first_block_usage= 0;
+}
+
+
+/*
+ Deallocate everything used by alloc_root or just move
+ used blocks to free list if called with MY_USED_TO_FREE
+*/
void free_root(MEM_ROOT *root, myf MyFlags)
{
@@ -109,18 +220,23 @@ void free_root(MEM_ROOT *root, myf MyFlags)
if (!root)
DBUG_VOID_RETURN; /* purecov: inspected */
+ if (MyFlags & MY_MARK_BLOCKS_FREE)
+ {
+ mark_blocks_free(root);
+ DBUG_VOID_RETURN;
+ }
if (!(MyFlags & MY_KEEP_PREALLOC))
root->pre_alloc=0;
- for ( next=root->used; next ;)
+ for (next=root->used; next ;)
{
old=next; next= next->next ;
if (old != root->pre_alloc)
my_free((gptr) old,MYF(0));
}
- for (next= root->free ; next ; )
+ for (next=root->free ; next ;)
{
- old=next; next= next->next ;
+ old=next; next= next->next;
if (old != root->pre_alloc)
my_free((gptr) old,MYF(0));
}
@@ -131,16 +247,50 @@ void free_root(MEM_ROOT *root, myf MyFlags)
root->free->left=root->pre_alloc->size-ALIGN_SIZE(sizeof(USED_MEM));
root->free->next=0;
}
+ root->block_num= 4;
+ root->first_block_usage= 0;
DBUG_VOID_RETURN;
}
+/*
+ Find block that contains an object and set the pre_alloc to it
+*/
+
+void set_prealloc_root(MEM_ROOT *root, char *ptr)
+{
+ USED_MEM *next;
+ for (next=root->used; next ; next=next->next)
+ {
+ if ((char*) next <= ptr && (char*) next + next->size > ptr)
+ {
+ root->pre_alloc=next;
+ return;
+ }
+ }
+ for (next=root->free ; next ; next=next->next)
+ {
+ if ((char*) next <= ptr && (char*) next + next->size > ptr)
+ {
+ root->pre_alloc=next;
+ return;
+ }
+ }
+}
+
char *strdup_root(MEM_ROOT *root,const char *str)
{
- uint len= (uint) strlen(str)+1;
+ return strmake_root(root, str, strlen(str));
+}
+
+char *strmake_root(MEM_ROOT *root,const char *str, uint len)
+{
char *pos;
- if ((pos=alloc_root(root,len)))
+ if ((pos=alloc_root(root,len+1)))
+ {
memcpy(pos,str,len);
+ pos[len]=0;
+ }
return pos;
}
diff --git a/mysys/my_append.c b/mysys/my_append.c
index 0d3296fb278..dc5ed084bb3 100644
--- a/mysys/my_append.c
+++ b/mysys/my_append.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
@@ -23,7 +22,7 @@
#include <sys/utime.h>
#elif defined(HAVE_UTIME_H)
#include <utime.h>
-#elif !defined(HPUX)
+#elif !defined(HPUX10)
struct utimbuf {
time_t actime;
time_t modtime;
diff --git a/mysys/my_bit.c b/mysys/my_bit.c
new file mode 100644
index 00000000000..55dd72f5f76
--- /dev/null
+++ b/mysys/my_bit.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Some useful bit functions */
+
+#include "mysys_priv.h"
+
+/*
+ Find smallest X in 2^X >= value
+ This can be used to divide a number with value by doing a shift instead
+*/
+
+uint my_bit_log2(ulong value)
+{
+ uint bit;
+ for (bit=0 ; value > 1 ; value>>=1, bit++) ;
+ return bit;
+}
+
+static char nbits[256] = {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
+};
+
+uint my_count_bits(ulonglong v)
+{
+#if SIZEOF_LONG_LONG > 4
+ /* The following code is a bit faster on 16 bit machines than if we would
+ only shift v */
+ ulong v2=(ulong) (v >> 32);
+ return (uint) (uchar) (nbits[(uchar) v] +
+ nbits[(uchar) (v >> 8)] +
+ nbits[(uchar) (v >> 16)] +
+ nbits[(uchar) (v >> 24)] +
+ nbits[(uchar) (v2)] +
+ nbits[(uchar) (v2 >> 8)] +
+ nbits[(uchar) (v2 >> 16)] +
+ nbits[(uchar) (v2 >> 24)]);
+#else
+ return (uint) (uchar) (nbits[(uchar) v] +
+ nbits[(uchar) (v >> 8)] +
+ nbits[(uchar) (v >> 16)] +
+ nbits[(uchar) (v >> 24)]);
+#endif
+}
+
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index a18fcba0b60..8834dda98e1 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Handling of uchar arrays as large bitmaps.
@@ -26,7 +25,6 @@
#include "mysys_priv.h"
#include <my_bitmap.h>
#include <assert.h>
-#include <string.h>
#include <m_string.h>
inline void bitmap_lock(MY_BITMAP* map)
@@ -50,7 +48,7 @@ my_bool bitmap_init(MY_BITMAP *map, uint bitmap_size, my_bool thread_safe)
if (!(map->bitmap=(uchar*) my_malloc((bitmap_size+7)/8,
MYF(MY_WME | MY_ZEROFILL))))
return 1;
- dbug_assert(bitmap_size != ~(uint) 0);
+ DBUG_ASSERT(bitmap_size != ~(uint) 0);
#ifdef THREAD
if ((map->thread_safe = thread_safe))
pthread_mutex_init(&map->mutex, MY_MUTEX_INIT_FAST);
@@ -123,6 +121,7 @@ void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit)
}
}
+
void bitmap_set_all(MY_BITMAP* map)
{
bitmap_lock(map);
diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c
index 2c07e8d136f..653ea569172 100644
--- a/mysys/my_chsize.c
+++ b/mysys/my_chsize.c
@@ -1,88 +1,113 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#include "m_string.h"
- /* Change size of file. Truncate file if shorter, */
- /* else expand with zero. */
+/*
+ Change size of file.
+
+ SYNOPSIS
+ my_chsize()
+ fd File descriptor
+ new_length New file size
+ filler If we don't have truncate, fill up all bytes after
+ new_length with this character
+ MyFlags Flags
-int my_chsize(File fd, my_off_t newlength, myf MyFlags)
+ DESCRIPTION
+ my_chsize() truncates file if shorter else fill with the filler character
+
+ RETURN VALUE
+ 0 Ok
+ 1 Error
+*/
+int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
{
+ my_off_t oldsize;
+ char buff[IO_SIZE];
DBUG_ENTER("my_chsize");
DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength,
MyFlags));
-#ifdef HAVE_CHSIZE
- if (chsize(fd,(off_t) newlength))
+ oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE));
+ DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
+
+ if (oldsize > newlength)
+#if defined(HAVE_SETFILEPOINTER)
+ /* This is for the moment only true on windows */
{
- DBUG_PRINT("error",("errno: %d",errno));
- my_errno=errno;
- if (MyFlags & MY_WME)
- my_error(EE_CANT_CHSIZE,MYF(ME_BELL+ME_WAITTANG),errno);
- DBUG_RETURN(1);
+ long is_success;
+ HANDLE win_file= (HANDLE) _get_osfhandle(fd);
+ long length_low, length_high;
+ length_low= (long) (ulong) newlength;
+ length_high= (long) ((ulonglong) newlength >> 32);
+ is_success= SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN);
+ if (is_success == -1 && (my_errno= GetLastError()) != NO_ERROR)
+ goto err;
+ if (SetEndOfFile(win_file))
+ DBUG_RETURN(0);
+ my_errno= GetLastError();
+ goto err;
}
- DBUG_RETURN(0);
-#else
- /* if file is shorter, expand with null, else fill unused part with null */
+#elif defined(HAVE_FTRUNCATE)
{
- my_off_t oldsize;
- char buff[IO_SIZE];
-
- oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE));
- DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
-
-#ifdef HAVE_FTRUNCATE
- if (oldsize > newlength)
+ if (ftruncate(fd, (off_t) newlength))
{
- if (ftruncate(fd, (off_t) newlength))
- {
- my_errno=errno;
- DBUG_PRINT("error",("errno: %d",errno));
- if (MyFlags & MY_WME)
- my_error(EE_CANT_CHSIZE, MYF(ME_BELL+ME_WAITTANG), errno);
- DBUG_RETURN(1);
- }
- DBUG_RETURN(0);
- }
-#else
- if (oldsize > newlength)
- { /* Fill diff with null */
- VOID(my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE)));
- swap(my_off_t, newlength, oldsize);
+ my_errno= errno;
+ goto err;
}
-#endif
- /* Full file with 0 until it's as big as requested */
- bzero(buff,IO_SIZE);
- while (newlength-oldsize > IO_SIZE)
+ DBUG_RETURN(0);
+ }
+#elif defined(HAVE_CHSIZE)
+ {
+ if (chsize(fd, (off_t) newlength))
{
- if (my_write(fd,(byte*) buff,IO_SIZE,MYF(MY_NABP)))
- goto err;
- oldsize+= IO_SIZE;
- }
- if (my_write(fd,(byte*) buff,(uint) (newlength-oldsize),MYF(MY_NABP)))
+ my_errno=errno;
goto err;
+ }
DBUG_RETURN(0);
- err:
- if (MyFlags & MY_WME)
- my_error(EE_CANT_CHSIZE,MYF(ME_BELL+ME_WAITTANG),my_errno);
- DBUG_PRINT("error",("errno: %d",my_errno));
- DBUG_RETURN(1);
+ }
+#else
+ {
+ /*
+ Fill space between requested length and true length with 'filler'
+ We should never come here on any modern machine
+ */
+ VOID(my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE)));
+ swap(my_off_t, newlength, oldsize);
}
#endif
-} /* my_chsize */
+
+ /* Full file with 'filler' until it's as big as requested */
+ bfill(buff, IO_SIZE, filler);
+ while (newlength-oldsize > IO_SIZE)
+ {
+ if (my_write(fd,(byte*) buff,IO_SIZE,MYF(MY_NABP)))
+ goto err;
+ oldsize+= IO_SIZE;
+ }
+ if (my_write(fd,(byte*) buff,(uint) (newlength-oldsize),MYF(MY_NABP)))
+ goto err;
+ DBUG_RETURN(0);
+
+err:
+ DBUG_PRINT("error", ("errno: %d", errno));
+ if (MyFlags & MY_WME)
+ my_error(EE_CANT_CHSIZE, MYF(ME_BELL+ME_WAITTANG), my_errno);
+ DBUG_RETURN(1);
+} /* my_chsize */
diff --git a/mysys/my_clock.c b/mysys/my_clock.c
index e7d1758fa2e..a192bde056d 100644
--- a/mysys/my_clock.c
+++ b/mysys/my_clock.c
@@ -1,31 +1,30 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES
-#include "global.h"
+#include "my_global.h"
-#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(OS2)
+#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(OS2) && !defined(__NETWARE__)
#include "mysys_priv.h"
#include <sys/times.h>
#endif
long my_clock(void)
{
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(OS2)
+#if !defined(MSDOS) && !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
struct tms tmsbuf;
VOID(times(&tmsbuf));
return (tmsbuf.tms_utime + tmsbuf.tms_stime);
diff --git a/mysys/my_compress.c b/mysys/my_compress.c
index f97d28c25ea..dd076311188 100644
--- a/mysys/my_compress.c
+++ b/mysys/my_compress.c
@@ -1,26 +1,27 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Written by Sinisa Milivojevic <sinisa@coresinc.com> */
+/* Written by Sinisa Milivojevic <sinisa@mysql.com> */
-#include <global.h>
+#include <my_global.h>
#ifdef HAVE_COMPRESS
#include <my_sys.h>
+#ifndef SCO
#include <m_string.h>
+#endif
#include <zlib.h>
/*
@@ -31,24 +32,28 @@
my_bool my_compress(byte *packet, ulong *len, ulong *complen)
{
+ DBUG_ENTER("my_compress");
if (*len < MIN_COMPRESS_LENGTH)
+ {
*complen=0;
+ DBUG_PRINT("note",("Packet too short: Not compressed"));
+ }
else
{
byte *compbuf=my_compress_alloc(packet,len,complen);
if (!compbuf)
- return *complen ? 0 : 1;
+ DBUG_RETURN(*complen ? 0 : 1);
memcpy(packet,compbuf,*len);
my_free(compbuf,MYF(MY_WME)); }
- return 0;
+ DBUG_RETURN(0);
}
byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen)
{
byte *compbuf;
- *complen = *len * 120 / 100 + 12;
- if (!(compbuf = (byte *) my_malloc(*complen,MYF(MY_WME))))
+ *complen= *len * 120 / 100 + 12;
+ if (!(compbuf= (byte *) my_malloc(*complen,MYF(MY_WME))))
return 0; /* Not enough memory */
if (compress((Bytef*) compbuf,(ulong *) complen, (Bytef*) packet,
(uLong) *len ) != Z_OK)
@@ -58,31 +63,36 @@ byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen)
}
if (*complen >= *len)
{
- *complen=0;
- my_free(compbuf,MYF(MY_WME));
+ *complen= 0;
+ my_free(compbuf, MYF(MY_WME));
+ DBUG_PRINT("note",("Packet got longer on compression; Not compressed"));
return 0;
}
- swap(ulong,*len,*complen); /* *len is now packet length */
+ swap(ulong, *len, *complen); /* *len is now packet length */
return compbuf;
}
my_bool my_uncompress (byte *packet, ulong *len, ulong *complen)
{
+ DBUG_ENTER("my_uncompress");
if (*complen) /* If compressed */
{
- byte *compbuf = (byte *) my_malloc (*complen,MYF(MY_WME));
+ byte *compbuf= (byte *) my_malloc(*complen,MYF(MY_WME));
+ int error;
if (!compbuf)
- return 1; /* Not enough memory */
- if (uncompress((Bytef*) compbuf, complen, (Bytef*) packet, *len) != Z_OK)
+ DBUG_RETURN(1); /* Not enough memory */
+ if ((error=uncompress((Bytef*) compbuf, complen, (Bytef*) packet, *len))
+ != Z_OK)
{ /* Probably wrong packet */
- my_free (compbuf,MYF(MY_WME));
- return 1;
+ DBUG_PRINT("error",("Can't uncompress packet, error: %d",error));
+ my_free(compbuf, MYF(MY_WME));
+ DBUG_RETURN(1);
}
- *len = *complen;
- memcpy(packet,compbuf,*len);
- my_free(compbuf,MYF(MY_WME));
+ *len= *complen;
+ memcpy(packet, compbuf, *len);
+ my_free(compbuf, MYF(MY_WME));
}
- return 0;
+ DBUG_RETURN(0);
}
#endif /* HAVE_COMPRESS */
diff --git a/mysys/my_copy.c b/mysys/my_copy.c
index 5bc4d1d51fa..84eda781a09 100644
--- a/mysys/my_copy.c
+++ b/mysys/my_copy.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
@@ -23,7 +22,7 @@
#include <sys/utime.h>
#elif defined(HAVE_UTIME_H)
#include <utime.h>
-#elif !defined(HPUX)
+#elif !defined(HPUX10)
#include <time.h>
struct utimbuf {
time_t actime;
@@ -95,7 +94,7 @@ int my_copy(const char *from, const char *to, myf MyFlags)
if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
DBUG_RETURN(0); /* File copyed but not stat */
VOID(chmod(to, stat_buff.st_mode & 07777)); /* Copy modes */
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
+#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)
VOID(chown(to, stat_buff.st_uid,stat_buff.st_gid)); /* Copy ownership */
#endif
#if !defined(VMS) && !defined(__ZTC__)
diff --git a/mysys/my_create.c b/mysys/my_create.c
index 5a10b0fd8b5..5fa97a9ca78 100644
--- a/mysys/my_create.c
+++ b/mysys/my_create.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES
#include "mysys_priv.h"
diff --git a/mysys/my_delete.c b/mysys/my_delete.c
index 77d5f311418..5670f03da64 100644
--- a/mysys/my_delete.c
+++ b/mysys/my_delete.c
@@ -1,22 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-#include "mysys_priv.h"
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#include "mysys_priv.h"
#include "mysys_err.h"
int my_delete(const char *name, myf MyFlags)
diff --git a/mysys/my_div.c b/mysys/my_div.c
index 24794679376..777ffe403d7 100644
--- a/mysys/my_div.c
+++ b/mysys/my_div.c
@@ -1,22 +1,29 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
+/*
+ Get filename of file
+
+ SYNOPSIS
+ my_filename()
+ fd File descriptor
+*/
+
my_string my_filename(File fd)
{
DBUG_ENTER("my_filename");
diff --git a/mysys/my_dup.c b/mysys/my_dup.c
new file mode 100644
index 00000000000..df298780e3e
--- /dev/null
+++ b/mysys/my_dup.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#define USES_TYPES
+#include "mysys_priv.h"
+#include "mysys_err.h"
+#include <my_dir.h>
+#include <errno.h>
+#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
+#include <share.h>
+#endif
+
+ /* Open a file */
+
+File my_dup(File file, myf MyFlags)
+{
+ File fd;
+ const char *filename;
+ DBUG_ENTER("my_dup");
+ DBUG_PRINT("my",("file: %d MyFlags: %d", MyFlags));
+ fd = dup(file);
+ filename= (((int) file < MY_NFILE) ?
+ my_file_info[(int) file].name : "Unknown");
+ DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP,
+ EE_FILENOTFOUND, MyFlags));
+} /* my_open */
diff --git a/mysys/my_error.c b/mysys/my_error.c
index 4aa946aa6c3..5ce061212b5 100644
--- a/mysys/my_error.c
+++ b/mysys/my_error.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -26,8 +25,15 @@
const char ** NEAR my_errmsg[MAXMAPS]={0,0,0,0};
char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE];
-/* Error message to user */
-/*VARARGS2*/
+/*
+ Error message to user
+
+ SYNOPSIS
+ my_error()
+ nr Errno
+ MyFlags Flags
+ ... variable list
+*/
int my_error(int nr,myf MyFlags, ...)
{
@@ -103,7 +109,16 @@ int my_error(int nr,myf MyFlags, ...)
DBUG_RETURN((*error_handler_hook)(nr, ebuff, MyFlags));
}
- /* Error as printf */
+/*
+ Error as printf
+
+ SYNOPSIS
+ my_printf_error()
+ error Errno
+ format Format string
+ MyFlags Flags
+ ... variable list
+*/
int my_printf_error (uint error, const char *format, myf MyFlags, ...)
{
@@ -116,7 +131,15 @@ int my_printf_error (uint error, const char *format, myf MyFlags, ...)
return (*error_handler_hook)(error, ebuff, MyFlags);
}
- /* Give message using error_handler_hook */
+/*
+ Give message using error_handler_hook
+
+ SYNOPSIS
+ my_message()
+ error Errno
+ str Error message
+ MyFlags Flags
+*/
int my_message(uint error, const char *str, register myf MyFlags)
{
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index e1575b0af48..d3b0b90f9c5 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "my_static.h"
diff --git a/mysys/my_fstream.c b/mysys/my_fstream.c
index d93caadbcdc..94f3aaf3464 100644
--- a/mysys/my_fstream.c
+++ b/mysys/my_fstream.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* USE_MY_STREAM isn't set because we can't thrust my_fclose! */
@@ -147,7 +146,8 @@ uint my_fwrite(FILE *stream, const byte *Buffer, uint Count, myf MyFlags)
/* Seek to position in file */
/* ARGSUSED */
-my_off_t my_fseek(FILE *stream, my_off_t pos, int whence, myf MyFlags)
+my_off_t my_fseek(FILE *stream, my_off_t pos, int whence,
+ myf MyFlags __attribute__((unused)))
{
DBUG_ENTER("my_fseek");
DBUG_PRINT("my",("stream: %lx pos: %lu whence: %d MyFlags: %d",
@@ -160,7 +160,7 @@ my_off_t my_fseek(FILE *stream, my_off_t pos, int whence, myf MyFlags)
/* Tell current position of file */
/* ARGSUSED */
-my_off_t my_ftell(FILE *stream, myf MyFlags)
+my_off_t my_ftell(FILE *stream, myf MyFlags __attribute__((unused)))
{
off_t pos;
DBUG_ENTER("my_ftell");
diff --git a/mysys/my_gethostbyname.c b/mysys/my_gethostbyname.c
index ffbfc424d0a..5044a505054 100644
--- a/mysys/my_gethostbyname.c
+++ b/mysys/my_gethostbyname.c
@@ -41,7 +41,7 @@ struct hostent *my_gethostbyname_r(const char *name,
int buflen, int *h_errnop)
{
struct hostent *hp;
- dbug_assert((size_t) buflen >= sizeof(*result));
+ DBUG_ASSERT((size_t) buflen >= sizeof(*result));
if (gethostbyname_r(name,result, buffer, (size_t) buflen, &hp, h_errnop))
return 0;
return hp;
@@ -53,7 +53,6 @@ struct hostent *my_gethostbyname_r(const char *name,
struct hostent *result, char *buffer,
int buflen, int *h_errnop)
{
- dbug_assert(buflen >= sizeof(struct hostent_data));
if (gethostbyname_r(name,result,(struct hostent_data *) buffer) == -1)
{
*h_errnop= errno;
@@ -71,7 +70,7 @@ struct hostent *my_gethostbyname_r(const char *name,
int buflen, int *h_errnop)
{
struct hostent *hp;
- dbug_assert(buflen >= sizeof(struct hostent_data));
+ DBUG_ASSERT(buflen >= sizeof(struct hostent_data));
hp= gethostbyname_r(name,result,(struct hostent_data *) buffer);
*h_errnop= errno;
return hp;
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
new file mode 100644
index 00000000000..a8c57b4cd1d
--- /dev/null
+++ b/mysys/my_getopt.c
@@ -0,0 +1,810 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#include <m_string.h>
+#include <stdlib.h>
+#include <my_getopt.h>
+#include <assert.h>
+#include <my_sys.h>
+#include <mysys_err.h>
+
+static int findopt(char *optpat, uint length,
+ const struct my_option **opt_res,
+ char **ffname);
+my_bool getopt_compare_strings(const char *s,
+ const char *t,
+ uint length);
+static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
+static ulonglong getopt_ull(char *arg, const struct my_option *optp,
+ int *err);
+static void init_variables(const struct my_option *options);
+static int setval(const struct my_option *opts, char *argument,
+ my_bool set_maximum_value);
+
+/*
+ The following three variables belong to same group and the number and
+ order of their arguments must correspond to each other.
+*/
+static const char *special_opt_prefix[]=
+{"skip", "disable", "enable", "maximum", "loose", 0};
+static const uint special_opt_prefix_lengths[]=
+{ 4, 7, 6, 7, 5, 0};
+enum enum_special_opt
+{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
+
+char *disabled_my_option= (char*) "0";
+
+/*
+ This is a flag that can be set in client programs. 0 means that
+ my_getopt will not print error messages, but the client should do
+ it by itself
+*/
+
+my_bool my_getopt_print_errors= 1;
+
+
+/*
+ function: handle_options
+
+ Sort options; put options first, until special end of options (--), or
+ until end of argv. Parse options; check that the given option matches with
+ one of the options in struct 'my_option', return error in case of ambiguous
+ or unknown option. Check that option was given an argument if it requires
+ one. Call function 'get_one_option()' once for each option.
+*/
+
+int handle_options(int *argc, char ***argv,
+ const struct my_option *longopts,
+ my_bool (*get_one_option)(int,
+ const struct my_option *,
+ char *))
+{
+ uint opt_found, argvpos= 0, length, i;
+ my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used,
+ option_is_loose;
+ char *progname= *(*argv), **pos, **pos_end, *optend, *prev_found;
+ const struct my_option *optp;
+ int error;
+
+ LINT_INIT(opt_found);
+ (*argc)--; /* Skip the program name */
+ (*argv)++; /* --- || ---- */
+ init_variables(longopts);
+
+ for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
+ {
+ char *cur_arg= *pos;
+ if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
+ {
+ char *argument= 0;
+ must_be_var= 0;
+ set_maximum_value= 0;
+ special_used= 0;
+ option_is_loose= 0;
+
+ cur_arg++; /* skip '-' */
+ if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
+ { /* --set-variable, or -O */
+ if (*cur_arg == 'O')
+ {
+ must_be_var= 1;
+
+ if (!(*++cur_arg)) /* If not -Ovar=# */
+ {
+ /* the argument must be in next argv */
+ if (!*++pos)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: Option '-O' requires an argument\n",
+ progname);
+ return EXIT_ARGUMENT_REQUIRED;
+ }
+ cur_arg= *pos;
+ (*argc)--;
+ }
+ }
+ else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
+ {
+ must_be_var= 1;
+ if (cur_arg[13] == '=')
+ {
+ cur_arg+= 14;
+ if (!*cur_arg)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: Option '--set-variable' requires an argument\n",
+ progname);
+ return EXIT_ARGUMENT_REQUIRED;
+ }
+ }
+ else if (cur_arg[14]) /* garbage, or another option. break out */
+ must_be_var= 0;
+ else
+ {
+ /* the argument must be in next argv */
+ if (!*++pos)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: Option '--set-variable' requires an argument\n",
+ progname);
+ return EXIT_ARGUMENT_REQUIRED;
+ }
+ cur_arg= *pos;
+ (*argc)--;
+ }
+ }
+ else if (!must_be_var)
+ {
+ if (!*++cur_arg) /* skip the double dash */
+ {
+ /* '--' means end of options, look no further */
+ end_of_options= 1;
+ (*argc)--;
+ continue;
+ }
+ }
+ optend= strcend(cur_arg, '=');
+ length= optend - cur_arg;
+ if (*optend == '=')
+ optend++;
+ else
+ optend=0;
+
+ /*
+ Find first the right option. Return error in case of an ambiguous,
+ or unknown option
+ */
+ optp= longopts;
+ if (!(opt_found= findopt(cur_arg, length, &optp, &prev_found)))
+ {
+ /*
+ Didn't find any matching option. Let's see if someone called
+ option with a special option prefix
+ */
+ if (!must_be_var)
+ {
+ if (optend)
+ must_be_var= 1; /* option is followed by an argument */
+ for (i= 0; special_opt_prefix[i]; i++)
+ {
+ if (!getopt_compare_strings(special_opt_prefix[i], cur_arg,
+ special_opt_prefix_lengths[i]) &&
+ cur_arg[special_opt_prefix_lengths[i]] == '-')
+ {
+ /*
+ We were called with a special prefix, we can reuse opt_found
+ */
+ special_used= 1;
+ cur_arg+= (special_opt_prefix_lengths[i] + 1);
+ if (i == OPT_LOOSE)
+ option_is_loose= 1;
+ if ((opt_found= findopt(cur_arg, length -
+ (special_opt_prefix_lengths[i] + 1),
+ &optp, &prev_found)))
+ {
+ if (opt_found > 1)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: ambiguous option '--%s-%s' (--%s-%s)\n",
+ progname, special_opt_prefix[i], cur_arg,
+ special_opt_prefix[i], prev_found);
+ return EXIT_AMBIGUOUS_OPTION;
+ }
+ switch (i) {
+ case OPT_SKIP:
+ case OPT_DISABLE: /* fall through */
+ /*
+ double negation is actually enable again,
+ for example: --skip-option=0 -> option = TRUE
+ */
+ optend= (optend && *optend == '0' && !(*(optend + 1))) ?
+ (char*) "1" : disabled_my_option;
+ break;
+ case OPT_ENABLE:
+ optend= (optend && *optend == '0' && !(*(optend + 1))) ?
+ disabled_my_option : (char*) "1";
+ break;
+ case OPT_MAXIMUM:
+ set_maximum_value= 1;
+ must_be_var= 1;
+ break;
+ }
+ break; /* break from the inner loop, main loop continues */
+ }
+ }
+ }
+ }
+ if (!opt_found)
+ {
+ if (must_be_var)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: %s: unknown variable '%s'\n", progname,
+ option_is_loose ? "WARNING" : "ERROR", cur_arg);
+ if (!option_is_loose)
+ return EXIT_UNKNOWN_VARIABLE;
+ }
+ else
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: %s: unknown option '--%s'\n", progname,
+ option_is_loose ? "WARNING" : "ERROR", cur_arg);
+ if (!option_is_loose)
+ return EXIT_UNKNOWN_OPTION;
+ }
+ if (option_is_loose)
+ {
+ (*argc)--;
+ continue;
+ }
+ }
+ }
+ if (opt_found > 1)
+ {
+ if (must_be_var)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: variable prefix '%s' is not unique\n",
+ progname, cur_arg);
+ return EXIT_VAR_PREFIX_NOT_UNIQUE;
+ }
+ else
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: ambiguous option '--%s' (%s, %s)\n",
+ progname, cur_arg, prev_found, optp->name);
+ return EXIT_AMBIGUOUS_OPTION;
+ }
+ }
+ if (must_be_var && optp->var_type == GET_NO_ARG)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: option '%s' cannot take an argument\n",
+ progname, optp->name);
+ return EXIT_NO_ARGUMENT_ALLOWED;
+ }
+ if (optp->arg_type == NO_ARG)
+ {
+ if (optend && optp->var_type != GET_BOOL)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: option '--%s' cannot take an argument\n",
+ progname, optp->name);
+ return EXIT_NO_ARGUMENT_ALLOWED;
+ }
+ if (optp->var_type == GET_BOOL)
+ {
+ /*
+ Set bool to 1 if no argument or if the user has used
+ --enable-'option-name'.
+ *optend was set to '0' if one used --disable-option
+ */
+ my_bool tmp= (my_bool) (!optend || *optend == '1');
+ *((my_bool*) optp->value)= tmp;
+ (*argc)--;
+ get_one_option(optp->id, optp,
+ tmp ? (char*) "1" : disabled_my_option);
+ continue;
+ }
+ argument= optend;
+ }
+ else if (optp->arg_type == OPT_ARG && optp->var_type == GET_BOOL)
+ {
+ if (optend == disabled_my_option)
+ *((my_bool*) optp->value)= (my_bool) 0;
+ else
+ {
+ if (!optend) /* No argument -> enable option */
+ *((my_bool*) optp->value)= (my_bool) 1;
+ else /* If argument differs from 0, enable option, else disable */
+ *((my_bool*) optp->value)= (my_bool) atoi(optend) != 0;
+ }
+ }
+ else if (optp->arg_type == REQUIRED_ARG && !optend)
+ {
+ /* Check if there are more arguments after this one */
+ if (!*++pos)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr, "%s: option '--%s' requires an argument\n",
+ progname, optp->name);
+ return EXIT_ARGUMENT_REQUIRED;
+ }
+ argument= *pos;
+ (*argc)--;
+ }
+ else
+ argument= optend;
+ }
+ else /* must be short option */
+ {
+ for (optend= cur_arg; *optend; optend++)
+ {
+ opt_found= 0;
+ for (optp= longopts; optp->id; optp++)
+ {
+ if (optp->id == (int) (uchar) *optend)
+ {
+ /* Option recognized. Find next what to do with it */
+ opt_found= 1;
+ if (optp->var_type == GET_BOOL && optp->arg_type == NO_ARG)
+ {
+ *((my_bool*) optp->value)= (my_bool) 1;
+ get_one_option(optp->id, optp, argument);
+ continue;
+ }
+ else if (optp->arg_type == REQUIRED_ARG ||
+ optp->arg_type == OPT_ARG)
+ {
+ if (*(optend + 1))
+ {
+ /* The rest of the option is option argument */
+ argument= optend + 1;
+ /* This is in effect a jump out of the outer loop */
+ optend= (char*) " ";
+ }
+ else if (optp->arg_type == REQUIRED_ARG)
+ {
+ /* Check if there are more arguments after this one */
+ if (!*++pos)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: option '-%c' requires an argument\n",
+ progname, optp->id);
+ return EXIT_ARGUMENT_REQUIRED;
+ }
+ argument= *pos;
+ (*argc)--;
+ /* the other loop will break, because *optend + 1 == 0 */
+ }
+ }
+ if ((error= setval(optp, argument, set_maximum_value)))
+ {
+ fprintf(stderr,
+ "%s: Error while setting value '%s' to '%s'\n",
+ progname, argument, optp->name);
+ return error;
+ }
+ get_one_option(optp->id, optp, argument);
+ break;
+ }
+ }
+ if (!opt_found)
+ {
+ if (my_getopt_print_errors)
+ fprintf(stderr,
+ "%s: unknown option '-%c'\n", progname, *optend);
+ return EXIT_UNKNOWN_OPTION;
+ }
+ }
+ (*argc)--; /* option handled (short), decrease argument count */
+ continue;
+ }
+ if ((error= setval(optp, argument, set_maximum_value)))
+ {
+ fprintf(stderr,
+ "%s: Error while setting value '%s' to '%s'\n",
+ progname, argument, optp->name);
+ return error;
+ }
+ get_one_option(optp->id, optp, argument);
+
+ (*argc)--; /* option handled (short or long), decrease argument count */
+ }
+ else /* non-option found */
+ (*argv)[argvpos++]= cur_arg;
+ }
+ /*
+ Destroy the first, already handled option, so that programs that look
+ for arguments in 'argv', without checking 'argc', know when to stop.
+ Items in argv, before the destroyed one, are all non-option -arguments
+ to the program, yet to be (possibly) handled.
+ */
+ (*argv)[argvpos]= 0;
+ return 0;
+}
+
+/*
+ function: setval
+
+ Arguments: opts, argument
+ Will set the option value to given value
+*/
+
+static int setval(const struct my_option *opts, char *argument,
+ my_bool set_maximum_value)
+{
+ int err= 0;
+
+ if (opts->value && argument)
+ {
+ gptr *result_pos= ((set_maximum_value) ?
+ opts->u_max_value : opts->value);
+
+ if (!result_pos)
+ return EXIT_NO_PTR_TO_VARIABLE;
+
+ switch (opts->var_type) {
+ case GET_INT:
+ case GET_UINT: /* fall through */
+ *((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
+ break;
+ case GET_LONG:
+ case GET_ULONG: /* fall through */
+ *((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
+ break;
+ case GET_LL:
+ *((longlong*) result_pos)= getopt_ll(argument, opts, &err);
+ break;
+ case GET_ULL:
+ *((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
+ break;
+ case GET_STR:
+ *((char**) result_pos)= argument;
+ break;
+ case GET_STR_ALLOC:
+ if ((*((char**) result_pos)))
+ my_free((*(char**) result_pos), MYF(MY_WME | MY_FAE));
+ if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
+ return EXIT_OUT_OF_MEMORY;
+ break;
+ default: /* dummy default to avoid compiler warnings */
+ break;
+ }
+ if (err)
+ return EXIT_UNKNOWN_SUFFIX;
+ }
+ return 0;
+}
+
+/*
+ function: findopt
+
+ Arguments: opt_pattern, length of opt_pattern, opt_struct, first found
+ name (ffname)
+
+ Go through all options in the my_option struct. Return number
+ of options found that match the pattern and in the argument
+ list the option found, if any. In case of ambiguous option, store
+ the name in ffname argument
+*/
+
+static int findopt(char *optpat, uint length,
+ const struct my_option **opt_res,
+ char **ffname)
+{
+ int count;
+ struct my_option *opt= (struct my_option *) *opt_res;
+
+ for (count= 0; opt->name; opt++)
+ {
+ if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
+ {
+ (*opt_res)= opt;
+ if (!count)
+ *ffname= (char *) opt->name; /* We only need to know one prev */
+ if (!opt->name[length]) /* Exact match */
+ return 1;
+ count++;
+ }
+ }
+ return count;
+}
+
+
+/*
+ function: compare_strings
+
+ Works like strncmp, other than 1.) considers '-' and '_' the same.
+ 2.) Returns -1 if strings differ, 0 if they are equal
+*/
+
+my_bool getopt_compare_strings(register const char *s, register const char *t,
+ uint length)
+{
+ char const *end= s + length;
+ for (;s != end ; s++, t++)
+ {
+ if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ function: eval_num_suffix
+
+ Transforms a number with a suffix to real number. Suffix can
+ be k|K for kilo, m|M for mega or g|G for giga.
+*/
+
+static longlong eval_num_suffix (char *argument, int *error, char *option_name)
+{
+ char *endchar;
+ longlong num;
+
+ *error= 0;
+ num= strtoll(argument, &endchar, 10);
+ if (*endchar == 'k' || *endchar == 'K')
+ num*= 1024L;
+ else if (*endchar == 'm' || *endchar == 'M')
+ num*= 1024L * 1024L;
+ else if (*endchar == 'g' || *endchar == 'G')
+ num*= 1024L * 1024L * 1024L;
+ else if (*endchar)
+ {
+ fprintf(stderr,
+ "Unknown suffix '%c' used for variable '%s' (value '%s')\n",
+ *endchar, option_name, argument);
+ *error= 1;
+ return 0;
+ }
+ return num;
+}
+
+/*
+ function: getopt_ll
+
+ Evaluates and returns the value that user gave as an argument
+ to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
+ and G as GIGA bytes. Some values must be in certain blocks, as
+ defined in the given my_option struct, this function will check
+ that those values are honored.
+ In case of an error, set error value in *err.
+*/
+
+static longlong getopt_ll(char *arg, const struct my_option *optp, int *err)
+{
+ longlong num;
+
+ num= eval_num_suffix(arg, err, (char*) optp->name);
+ if (num < (longlong) optp->min_value)
+ num= (longlong) optp->min_value;
+ else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value
+ && optp->max_value) /* if max value is not set -> no upper limit */
+ num= (longlong) (ulong) optp->max_value;
+ num= ((num - (longlong) optp->sub_size) / (optp->block_size ?
+ (ulonglong) optp->block_size :
+ 1L));
+ return (longlong) (num * (optp->block_size ? (ulonglong) optp->block_size :
+ 1L));
+}
+
+/*
+ function: getopt_ull
+
+ This is the same as getopt_ll, but is meant for unsigned long long
+ values.
+*/
+
+static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err)
+{
+ ulonglong num;
+
+ num= eval_num_suffix(arg, err, (char*) optp->name);
+ return getopt_ull_limit_value(num, optp);
+}
+
+
+ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp)
+{
+ if ((ulonglong) num > (ulonglong) optp->max_value &&
+ optp->max_value) /* if max value is not set -> no upper limit */
+ num= (ulonglong) optp->max_value;
+ if (optp->block_size > 1)
+ {
+ num/= (ulonglong) optp->block_size;
+ num*= (ulonglong) optp->block_size;
+ }
+ if (num < (ulonglong) optp->min_value)
+ num= (ulonglong) optp->min_value;
+ return num;
+}
+
+/*
+ function: init_variables
+
+ initialize all variables to their default values
+*/
+
+static void init_variables(const struct my_option *options)
+{
+ for (; options->name; options++)
+ {
+ if (options->value)
+ {
+ switch (options->var_type) {
+ case GET_BOOL:
+ if (options->u_max_value)
+ *((my_bool*) options->u_max_value)= (my_bool) options->max_value;
+ *((my_bool*) options->value)= (my_bool) options->def_value;
+ break;
+ case GET_INT:
+ if (options->u_max_value)
+ *((int*) options->u_max_value)= (int) options->max_value;
+ *((int*) options->value)= (int) options->def_value;
+ break;
+ case GET_UINT:
+ if (options->u_max_value)
+ *((uint*) options->u_max_value)= (uint) options->max_value;
+ *((uint*) options->value)= (uint) options->def_value;
+ break;
+ case GET_LONG:
+ if (options->u_max_value)
+ *((long*) options->u_max_value)= (long) options->max_value;
+ *((long*) options->value)= (long) options->def_value;
+ break;
+ case GET_ULONG:
+ if (options->u_max_value)
+ *((ulong*) options->u_max_value)= (ulong) options->max_value;
+ *((ulong*) options->value)= (ulong) options->def_value;
+ break;
+ case GET_LL:
+ if (options->u_max_value)
+ *((longlong*) options->u_max_value)= (longlong) options->max_value;
+ *((longlong*) options->value)= (longlong) options->def_value;
+ break;
+ case GET_ULL:
+ if (options->u_max_value)
+ *((ulonglong*) options->u_max_value)= (ulonglong) options->max_value;
+ *((ulonglong*) options->value)= (ulonglong) options->def_value;
+ break;
+ default: /* dummy default to avoid compiler warnings */
+ break;
+ }
+ }
+ }
+}
+
+
+/*
+ function: my_print_options
+
+ Print help for all options and variables.
+*/
+
+void my_print_help(const struct my_option *options)
+{
+ uint col, name_space= 22, comment_space= 57;
+ const char *line_end;
+ const struct my_option *optp;
+
+ for (optp= options; optp->id; optp++)
+ {
+ if (optp->id < 256)
+ {
+ printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
+ col= 6;
+ }
+ else
+ {
+ printf(" ");
+ col= 2;
+ }
+ if (strlen(optp->name))
+ {
+ printf("--%s", optp->name);
+ col+= 2 + strlen(optp->name);
+ if (optp->var_type == GET_STR || optp->var_type == GET_STR_ALLOC)
+ {
+ printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
+ optp->arg_type == OPT_ARG ? "]" : "");
+ col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
+ }
+ else if (optp->var_type == GET_NO_ARG || optp->var_type == GET_BOOL)
+ {
+ putchar(' ');
+ col++;
+ }
+ else
+ {
+ printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
+ optp->arg_type == OPT_ARG ? "]" : "");
+ col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
+ }
+ if (col > name_space && optp->comment && *optp->comment)
+ {
+ putchar('\n');
+ col= 0;
+ }
+ }
+ for (; col < name_space; col++)
+ putchar(' ');
+ if (optp->comment && *optp->comment)
+ {
+ const char *comment= optp->comment, *end= strend(comment);
+
+ while ((uint) (end - comment) > comment_space)
+ {
+ for (line_end= comment + comment_space; *line_end != ' '; line_end--);
+ for (; comment != line_end; comment++)
+ putchar(*comment);
+ comment++; /* skip the space, as a newline will take it's place now */
+ putchar('\n');
+ for (col= 0; col < name_space; col++)
+ putchar(' ');
+ }
+ printf("%s", comment);
+ }
+ putchar('\n');
+ }
+}
+
+
+/*
+ function: my_print_options
+
+ Print variables.
+*/
+
+void my_print_variables(const struct my_option *options)
+{
+ uint name_space= 34, length;
+ char buff[255];
+ const struct my_option *optp;
+
+ printf("\nVariables (--variable-name=value)\n");
+ printf("and boolean options {FALSE|TRUE} Value (after reading options)\n");
+ printf("--------------------------------- -----------------------------\n");
+ for (optp= options; optp->id; optp++)
+ {
+ if (optp->value)
+ {
+ printf("%s", optp->name);
+ length= strlen(optp->name);
+ for (; length < name_space; length++)
+ putchar(' ');
+ switch (optp->var_type) {
+ case GET_STR:
+ case GET_STR_ALLOC: /* fall through */
+ printf("%s\n", *((char**) optp->value) ? *((char**) optp->value) :
+ "(No default value)");
+ break;
+ case GET_BOOL:
+ printf("%s\n", *((my_bool*) optp->value) ? "TRUE" : "FALSE");
+ break;
+ case GET_INT:
+ printf("%d\n", *((int*) optp->value));
+ break;
+ case GET_UINT:
+ printf("%d\n", *((uint*) optp->value));
+ break;
+ case GET_LONG:
+ printf("%lu\n", *((long*) optp->value));
+ break;
+ case GET_ULONG:
+ printf("%lu\n", *((ulong*) optp->value));
+ break;
+ case GET_LL:
+ printf("%s\n", llstr(*((longlong*) optp->value), buff));
+ break;
+ case GET_ULL:
+ longlong2str(*((ulonglong*) optp->value), buff, 10);
+ printf("%s\n", buff);
+ break;
+ default: /* dummy default to avoid compiler warnings */
+ break;
+ }
+ }
+ }
+}
diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c
index 6bdea813fe4..63ab17b4c51 100644
--- a/mysys/my_getwd.c
+++ b/mysys/my_getwd.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* my_setwd() and my_getwd() works with intern_filenames !! */
@@ -33,7 +32,7 @@
#endif
#ifdef __EMX__
-// chdir2 support also drive change
+/* chdir2 support also drive change */
#define chdir _chdir2
#endif
diff --git a/mysys/my_init.c b/mysys/my_init.c
index c1b2260c121..8d4ba2c97b6 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000-2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "my_static.h"
@@ -42,9 +41,14 @@ static my_bool win32_init_tcp_ip();
#else
#define my_win_init()
#endif
-static my_bool my_init_done=0;
+#ifdef __NETWARE__
+static void netware_init();
+#else
+#define netware_init()
+#endif
+my_bool my_init_done=0;
static ulong atoi_octal(const char *str)
{
@@ -58,20 +62,34 @@ static ulong atoi_octal(const char *str)
}
- /* Init my_sys functions and my_sys variabels */
+/*
+ Init my_sys functions and my_sys variabels
-void my_init(void)
+ SYNOPSIS
+ my_init()
+
+ RETURN
+ 0 ok
+ 1 Couldn't initialize environment
+*/
+
+my_bool my_init(void)
{
my_string str;
if (my_init_done)
- return;
+ return 0;
my_init_done=1;
+#if defined(THREAD) && defined(SAFE_MUTEX)
+ safe_mutex_global_init(); /* Must be called early */
+#endif
+ netware_init();
#ifdef THREAD
#if defined(HAVE_PTHREAD_INIT)
pthread_init(); /* Must be called before DBUG_ENTER */
#endif
- my_thread_global_init();
-#if !defined( __WIN__) && !defined(OS2)
+ if (my_thread_global_init())
+ return 1;
+#if !defined( __WIN__) && !defined(OS2) && !defined(__NETWARE__)
sigfillset(&my_signals); /* signals blocked by mf_brkhant */
#endif
#endif /* THREAD */
@@ -102,7 +120,7 @@ void my_init(void)
#ifdef __WIN__
win32_init_tcp_ip();
#endif
- DBUG_VOID_RETURN;
+ DBUG_RETURN(0);
}
} /* my_init */
@@ -145,7 +163,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
rus.ru_nvcsw, rus.ru_nivcsw);
#endif
-#if defined(MSDOS) && !defined(__WIN__)
+#if ( defined(MSDOS) || defined(__NETWARE__) ) && !defined(__WIN__)
fprintf(info_file,"\nRun time: %.1f\n",(double) clock()/CLOCKS_PER_SEC);
#endif
#if defined(SAFEMALLOC)
@@ -162,20 +180,27 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
#endif
}
#ifdef THREAD
- pthread_mutex_destroy(&THR_LOCK_keycache);
- pthread_mutex_destroy(&THR_LOCK_malloc);
- pthread_mutex_destroy(&THR_LOCK_open);
DBUG_POP(); /* Must be done before my_thread_end */
+ my_once_free();
my_thread_end();
my_thread_global_end();
-#endif
+#if defined(SAFE_MUTEX)
+ /*
+ Check on destroying of mutexes. A few may be left that will get cleaned
+ up by C++ destructors
+ */
+ safe_mutex_end(infoflag & MY_GIVE_INFO ? stderr : (FILE *) 0);
+#endif /* defined(SAFE_MUTEX) */
+#endif /* THREAD */
+
#ifdef __WIN__
- if (have_tcpip);
- WSACleanup( );
+ if (have_tcpip)
+ WSACleanup();
#endif /* __WIN__ */
- my_init_done=0;
+ my_init_done=0;
} /* my_end */
+
#ifdef __WIN__
/*
@@ -264,10 +289,10 @@ static void my_win_init(void)
/*------------------------------------------------------------------
-** Name: CheckForTcpip| Desc: checks if tcpip has been installed on system
-** According to Microsoft Developers documentation the first registry
-** entry should be enough to check if TCP/IP is installed, but as expected
-** this doesn't work on all Win32 machines :(
+ Name: CheckForTcpip| Desc: checks if tcpip has been installed on system
+ According to Microsoft Developers documentation the first registry
+ entry should be enough to check if TCP/IP is installed, but as expected
+ this doesn't work on all Win32 machines :(
------------------------------------------------------------------*/
#define TCPIPKEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
@@ -293,6 +318,7 @@ static my_bool win32_have_tcpip(void)
return (TRUE);
}
+
static my_bool win32_init_tcp_ip()
{
if (win32_have_tcpip())
@@ -324,4 +350,54 @@ static my_bool win32_init_tcp_ip()
}
return(0);
}
-#endif
+#endif /* __WIN__ */
+
+
+#ifdef __NETWARE__
+/****************************************************************************
+ Do basic initialisation for netware needed by most programs
+****************************************************************************/
+
+static void netware_init()
+{
+ char cwd[PATH_MAX], *name;
+
+ /* init only if we are not a client library */
+ if (my_progname)
+ {
+#if SUPPORTED_BY_LIBC /* Removed until supported in Libc */
+ struct termios tp;
+ /* Disable control characters */
+ tcgetattr(STDIN_FILENO, &tp);
+ tp.c_cc[VINTR] = _POSIX_VDISABLE;
+ tp.c_cc[VEOF] = _POSIX_VDISABLE;
+ tp.c_cc[VSUSP] = _POSIX_VDISABLE;
+ tcsetattr(STDIN_FILENO, TCSANOW, &tp);
+#endif /* SUPPORTED_BY_LIBC */
+
+ /* With stdout redirection */
+ if (!isatty(STDOUT_FILENO))
+ {
+ setscreenmode(SCR_AUTOCLOSE_ON_EXIT); /* auto close the screen */
+ }
+ else
+ {
+ setscreenmode(SCR_NO_MODE); /* keep the screen up */
+ }
+
+ /* Parse program name and change to base format */
+ name= my_progname;
+ for (; *name; name++)
+ {
+ if (*name == '\\')
+ {
+ *name = '/';
+ }
+ else
+ {
+ *name = tolower(*name);
+ }
+ }
+ }
+}
+#endif /* __NETWARE__ */
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index f9774d8a4aa..055e00d2efc 100644
--- a/mysys/my_lib.c
+++ b/mysys/my_lib.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* TODO: check for overun of memory for names. */
/* Convert MSDOS-TIME to standar time_t */
@@ -63,8 +62,15 @@
#define READDIR(A,B,C) (!(C=readdir(A)))
#endif
+/*
+ We are assuming that directory we are reading is either has less than
+ 100 files and so can be read in one initial chunk or has more than 1000
+ files and so big increment are suitable.
+*/
+#define ENTRIES_START_SIZE (8192/sizeof(FILEINFO))
+#define ENTRIES_INCREMENT (65536/sizeof(FILEINFO))
+#define NAMES_START_SIZE 32768
-#define STARTSIZE ONCE_ALLOC_INIT*8 /* some mallocmargin */
static int comp_names(struct fileinfo *a,struct fileinfo *b);
@@ -75,7 +81,13 @@ void my_dirend(MY_DIR *buffer)
{
DBUG_ENTER("my_dirend");
if (buffer)
+ {
+ delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer +
+ ALIGN_SIZE(sizeof(MY_DIR))));
+ free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
+ ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0));
my_free((gptr) buffer,MYF(0));
+ }
DBUG_VOID_RETURN;
} /* my_dirend */
@@ -92,89 +104,91 @@ static int comp_names(struct fileinfo *a, struct fileinfo *b)
MY_DIR *my_dir(const char *path, myf MyFlags)
{
+ char *buffer;
+ MY_DIR *result= 0;
+ FILEINFO finfo;
+ DYNAMIC_ARRAY *dir_entries_storage;
+ MEM_ROOT *names_storage;
DIR *dirp;
struct dirent *dp;
- struct fileinfo *fnames;
- char *buffer, *obuffer, *tempptr;
- uint fcnt,i,size,firstfcnt, maxfcnt,length;
char tmp_path[FN_REFLEN+1],*tmp_file;
- my_ptrdiff_t diff;
- bool eof;
#ifdef THREAD
char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
#endif
DBUG_ENTER("my_dir");
- DBUG_PRINT("my",("path: '%s' stat: %d MyFlags: %d",path,MyFlags));
+ DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags));
#if defined(THREAD) && !defined(HAVE_READDIR_R)
pthread_mutex_lock(&THR_LOCK_open);
#endif
dirp = opendir(directory_file_name(tmp_path,(my_string) path));
- size = STARTSIZE;
- if (dirp == NULL || ! (buffer = (char *) my_malloc(size, MyFlags)))
+#if defined(__amiga__)
+ if ((dirp->dd_fd) < 0) /* Directory doesn't exists */
goto error;
+#endif
+ if (dirp == NULL ||
+ ! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) +
+ ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
+ sizeof(MEM_ROOT), MyFlags)))
+ goto error;
+
+ dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)));
+ names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
+ ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
+
+ if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
+ ENTRIES_START_SIZE, ENTRIES_INCREMENT))
+ {
+ my_free((gptr) buffer,MYF(0));
+ goto error;
+ }
+ init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
+
+ /* MY_DIR structure is allocated and completly initialized at this point */
+ result= (MY_DIR*)buffer;
- fcnt = 0;
tmp_file=strend(tmp_path);
- firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) /
- (sizeof(struct fileinfo) + FN_LEN);
- fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
- tempptr = (char *) (fnames + maxfcnt);
#ifdef THREAD
dp= (struct dirent*) dirent_tmp;
#else
dp=0;
#endif
- eof=0;
- for (;;)
+
+ while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
{
- while (fcnt < maxfcnt &&
- !(eof= READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
+ if (!(finfo.name= strdup_root(names_storage, dp->d_name)))
+ goto error;
+
+ if (MyFlags & MY_WANT_STAT)
{
- bzero((gptr) (fnames+fcnt),sizeof(fnames[0])); /* for purify */
- fnames[fcnt].name = tempptr;
- tempptr = strmov(tempptr,dp->d_name) + 1;
- if (MyFlags & MY_WANT_STAT)
- {
- VOID(strmov(tmp_file,dp->d_name));
- VOID(my_stat(tmp_path, &fnames[fcnt].mystat, MyFlags));
- }
- ++fcnt;
+ if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage,
+ sizeof(MY_STAT))))
+ goto error;
+
+ bzero(finfo.mystat, sizeof(MY_STAT));
+ VOID(strmov(tmp_file,dp->d_name));
+ VOID(my_stat(tmp_path, finfo.mystat, MyFlags));
}
- if (eof)
- break;
- size += STARTSIZE; obuffer = buffer;
- if (!(buffer = (char *) my_realloc((gptr) buffer, size,
- MyFlags | MY_FREE_ON_ERROR)))
- goto error; /* No memory */
- length= (uint) (sizeof(struct fileinfo ) * firstfcnt);
- diff= PTR_BYTE_DIFF(buffer , obuffer) + (int) length;
- fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
- tempptr= ADD_TO_PTR(tempptr,diff,char*);
- for (i = 0; i < maxfcnt; i++)
- fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*);
-
- /* move filenames upp a bit */
- maxfcnt += firstfcnt;
- bmove_upp(tempptr,tempptr-length,
- (uint) (tempptr- (char*) (fnames+maxfcnt)));
+ else
+ finfo.mystat= NULL;
+
+ if (push_dynamic(dir_entries_storage, (gptr)&finfo))
+ goto error;
}
(void) closedir(dirp);
- {
- MY_DIR * s = (MY_DIR *) buffer;
- s->number_off_files = (uint) fcnt;
- s->dir_entry = fnames;
- }
- if (!(MyFlags & MY_DONT_SORT))
- qsort((void *) fnames, (size_s) fcnt, sizeof(struct fileinfo),
- (qsort_cmp) comp_names);
#if defined(THREAD) && !defined(HAVE_READDIR_R)
pthread_mutex_unlock(&THR_LOCK_open);
#endif
- DBUG_RETURN((MY_DIR *) buffer);
+ result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
+ result->number_off_files= dir_entries_storage->elements;
+
+ if (!(MyFlags & MY_DONT_SORT))
+ qsort((void *) result->dir_entry, result->number_off_files,
+ sizeof(FILEINFO), (qsort_cmp) comp_names);
+ DBUG_RETURN(result);
error:
#if defined(THREAD) && !defined(HAVE_READDIR_R)
@@ -183,7 +197,8 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
my_errno=errno;
if (dirp)
(void) closedir(dirp);
- if (MyFlags & (MY_FAE+MY_WME))
+ my_dirend(result);
+ if (MyFlags & (MY_FAE | MY_WME))
my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
DBUG_RETURN((MY_DIR *) NULL);
} /* my_dir */
@@ -346,10 +361,11 @@ my_string directory_file_name (my_string dst, const char *src)
MY_DIR *my_dir(const char *path, myf MyFlags)
{
- struct fileinfo *fnames;
- char *buffer, *obuffer, *tempptr;
- int eof,i,fcnt,firstfcnt,length,maxfcnt;
- uint size;
+ char *buffer;
+ MY_DIR *result= 0;
+ FILEINFO finfo;
+ DYNAMIC_ARRAY *dir_entries_storage;
+ MEM_ROOT *names_storage;
#ifdef __BORLANDC__
struct ffblk find;
#else
@@ -357,7 +373,6 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
#endif
ushort mode;
char tmp_path[FN_REFLEN],*tmp_file,attrib;
- my_ptrdiff_t diff;
#ifdef _WIN64
__int64 handle;
#else
@@ -389,85 +404,88 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
goto error;
#endif
- size = STARTSIZE;
- firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) /
- (sizeof(struct fileinfo) + FN_LEN);
- if ((buffer = (char *) my_malloc(size, MyFlags)) == 0)
+ if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) +
+ ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
+ sizeof(MEM_ROOT), MyFlags)))
goto error;
- fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
- tempptr = (char *) (fnames + maxfcnt);
- fcnt = 0;
- for (;;)
+ dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)));
+ names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
+ ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
+
+ if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
+ ENTRIES_START_SIZE, ENTRIES_INCREMENT))
+ {
+ my_free((gptr) buffer,MYF(0));
+ goto error;
+ }
+ init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
+
+ /* MY_DIR structure is allocated and completly initialized at this point */
+ result= (MY_DIR*)buffer;
+
+ do
{
- do
+#ifdef __BORLANDC__
+ if (!(finfo.name= strdup_root(names_storage, find.ff_name)))
+ goto error;
+#else
+ if (!(finfo.name= strdup_root(names_storage, find.name)))
+ goto error;
+#endif
+ if (MyFlags & MY_WANT_STAT)
{
- fnames[fcnt].name = tempptr;
+ if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage,
+ sizeof(MY_STAT))))
+ goto error;
+
+ bzero(finfo.mystat, sizeof(MY_STAT));
#ifdef __BORLANDC__
- tempptr = strmov(tempptr,find.ff_name) + 1;
- fnames[fcnt].mystat.st_size=find.ff_fsize;
- fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0;
+ finfo.mystat->st_size=find.ff_fsize;
mode=MY_S_IREAD; attrib=find.ff_attrib;
#else
- tempptr = strmov(tempptr,find.name) + 1;
- fnames[fcnt].mystat.st_size=find.size;
- fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0;
+ finfo.mystat->st_size=find.size;
mode=MY_S_IREAD; attrib=find.attrib;
#endif
if (!(attrib & _A_RDONLY))
mode|=MY_S_IWRITE;
if (attrib & _A_SUBDIR)
mode|=MY_S_IFDIR;
- fnames[fcnt].mystat.st_mode=mode;
-#ifdef __BORLANDC__
- fnames[fcnt].mystat.st_mtime=((uint32) find.ff_ftime);
-#else
- fnames[fcnt].mystat.st_mtime=((uint32) find.time_write);
-#endif
- ++fcnt;
+ finfo.mystat->st_mode=mode;
#ifdef __BORLANDC__
- } while ((eof= findnext(&find)) == 0 && fcnt < maxfcnt);
+ finfo.mystat->st_mtime=((uint32) find.ff_ftime);
#else
- } while ((eof= _findnext(handle,&find)) == 0 && fcnt < maxfcnt);
+ finfo.mystat->st_mtime=((uint32) find.time_write);
#endif
+ }
+ else
+ finfo.mystat= NULL;
- DBUG_PRINT("test",("eof: %d errno: %d",eof,errno));
- if (eof)
- break;
- size += STARTSIZE; obuffer = buffer;
- if (!(buffer = (char *) my_realloc((gptr) buffer, size,
- MyFlags | MY_FREE_ON_ERROR)))
+ if (push_dynamic(dir_entries_storage, (gptr)&finfo))
goto error;
- length= sizeof(struct fileinfo ) * firstfcnt;
- diff= PTR_BYTE_DIFF(buffer , obuffer) +length;
- fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
- tempptr= ADD_TO_PTR(tempptr,diff,char*);
- for (i = 0; i < maxfcnt; i++)
- fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*);
-
- /* move filenames upp a bit */
- maxfcnt += firstfcnt;
- bmove_upp(tempptr,ADD_TO_PTR(tempptr,-length,char*),
- (int) PTR_BYTE_DIFF(tempptr,fnames+maxfcnt));
- }
- {
- MY_DIR * s = (MY_DIR *) buffer;
- s->number_off_files = (uint) fcnt;
- s->dir_entry = fnames;
- }
- if (!(MyFlags & MY_DONT_SORT))
- qsort(fnames,fcnt,sizeof(struct fileinfo),(qsort_cmp) comp_names);
-#ifndef __BORLANDC__
+
+#ifdef __BORLANDC__
+ } while (findnext(&find) == 0);
+#else
+ } while (_findnext(handle,&find) == 0);
+
_findclose(handle);
#endif
- DBUG_RETURN((MY_DIR *) buffer);
+ result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
+ result->number_off_files= dir_entries_storage->elements;
+
+ if (!(MyFlags & MY_DONT_SORT))
+ qsort((void *) result->dir_entry, result->number_off_files,
+ sizeof(FILEINFO), (qsort_cmp) comp_names);
+ DBUG_RETURN(result);
error:
my_errno=errno;
#ifndef __BORLANDC__
if (handle != -1)
_findclose(handle);
#endif
+ my_dirend(result);
if (MyFlags & MY_FAE+MY_WME)
my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno);
DBUG_RETURN((MY_DIR *) NULL);
@@ -482,14 +500,14 @@ error:
MY_DIR *my_dir(const char* path, myf MyFlags)
{
- struct fileinfo *fnames;
- char *buffer, *obuffer, *tempptr;
- int eof,i,fcnt,firstfcnt,length,maxfcnt;
- uint size;
+ char *buffer;
+ MY_DIR *result= 0;
+ FILEINFO finfo;
+ DYNAMIC_ARRAY *dir_entries_storage;
+ MEM_ROOT *names_storage;
struct find_t find;
ushort mode;
char tmp_path[FN_REFLEN],*tmp_file,attrib;
- my_ptrdiff_t diff;
DBUG_ENTER("my_dir");
DBUG_PRINT("my",("path: '%s' stat: %d MyFlags: %d",path,MyFlags));
@@ -511,63 +529,65 @@ MY_DIR *my_dir(const char* path, myf MyFlags)
if (_dos_findfirst(tmp_path,_A_NORMAL | _A_SUBDIR, &find))
goto error;
- size = STARTSIZE;
- firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) /
- (sizeof(struct fileinfo) + FN_LEN);
- if ((buffer = (char *) my_malloc(size, MyFlags)) == 0)
+ if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) +
+ ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
+ sizeof(MEM_ROOT), MyFlags)))
goto error;
- fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
- tempptr = (char *) (fnames + maxfcnt);
- fcnt = 0;
- for (;;)
+ dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)));
+ names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
+ ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
+
+ if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
+ ENTRIES_START_SIZE, ENTRIES_INCREMENT))
+ {
+ my_free((gptr) buffer,MYF(0));
+ goto error;
+ }
+ init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
+
+ /* MY_DIR structure is allocated and completly initialized at this point */
+ result= (MY_DIR*)buffer;
+
+ do
{
- do
+ if (!(finfo.name= strdup_root(names_storage, find.name)))
+ goto error;
+
+ if (MyFlags & MY_WANT_STAT)
{
- fnames[fcnt].name = tempptr;
- tempptr = strmov(tempptr,find.name) + 1;
- fnames[fcnt].mystat.st_size=find.size;
- fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0;
- mode=MY_S_IREAD; attrib=find.attrib;
+ if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage,
+ sizeof(MY_STAT))))
+ goto error;
+
+ bzero(finfo.mystat, sizeof(MY_STAT));
+ finfo.mystat->st_size= find.size;
+ mode= MY_S_IREAD; attrib= find.attrib;
if (!(attrib & _A_RDONLY))
- mode|=MY_S_IWRITE;
+ mode|= MY_S_IWRITE;
if (attrib & _A_SUBDIR)
- mode|=MY_S_IFDIR;
- fnames[fcnt].mystat.st_mode=mode;
- fnames[fcnt].mystat.st_mtime=((uint32) find.wr_date << 16) +
- find.wr_time;
- ++fcnt;
- } while ((eof= _dos_findnext(&find)) == 0 && fcnt < maxfcnt);
-
- DBUG_PRINT("test",("eof: %d errno: %d",eof,errno));
- if (eof)
- break;
- size += STARTSIZE; obuffer = buffer;
- if (!(buffer = (char *) my_realloc((gptr) buffer, size,
- MyFlags | MY_FREE_ON_ERROR)))
+ mode|= MY_S_IFDIR;
+ finfo.mystat->st_mode= mode;
+ finfo.mystat->st_mtime= ((uint32) find.wr_date << 16) + find.wr_time;
+ }
+ else
+ finfo.mystat= NULL;
+
+ if (push_dynamic(dir_entries_storage, (gptr)&finfo))
goto error;
- length= sizeof(struct fileinfo ) * firstfcnt;
- diff= PTR_BYTE_DIFF(buffer , obuffer) +length;
- fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR));
- tempptr= ADD_TO_PTR(tempptr,diff,char*);
- for (i = 0; i < maxfcnt; i++)
- fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*);
-
- /* move filenames upp a bit */
- maxfcnt += firstfcnt;
- bmove_upp(tempptr,ADD_TO_PTR(tempptr,-length,char*),
- (int) PTR_BYTE_DIFF(tempptr,fnames+maxfcnt));
- }
- {
- MY_DIR * s = (MY_DIR *) buffer;
- s->number_off_files = (uint) fcnt;
- s->dir_entry = fnames;
- }
+
+ } while (_dos_findnext(&find) == 0);
+
+ result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
+ result->number_off_files= dir_entries_storage->elements;
+
if (!(MyFlags & MY_DONT_SORT))
- qsort(fnames,fcnt,sizeof(struct fileinfo),(qsort_cmp) comp_names);
- DBUG_RETURN((MY_DIR *) buffer);
+ qsort((void *) result->dir_entry, result->number_off_files,
+ sizeof(FILEINFO), (qsort_cmp) comp_names);
+ DBUG_RETURN(result);
error:
+ my_dirend(result);
if (MyFlags & MY_FAE+MY_WME)
my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno);
DBUG_RETURN((MY_DIR *) NULL);
@@ -580,13 +600,15 @@ error:
** Note that MY_STAT is assumed to be same as struct stat
****************************************************************************/
-int my_fstat(int Filedes, MY_STAT *stat_area, myf MyFlags )
+int my_fstat(int Filedes, MY_STAT *stat_area,
+ myf MyFlags __attribute__((unused)))
{
DBUG_ENTER("my_fstat");
DBUG_PRINT("my",("fd: %d MyFlags: %d",Filedes,MyFlags));
DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area));
}
+
MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
{
int m_used;
@@ -597,9 +619,11 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
if ((m_used= (stat_area == NULL)))
if (!(stat_area = (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags)))
goto error;
- if ( ! stat((my_string) path, (struct stat *) stat_area) )
+ if (! stat((my_string) path, (struct stat *) stat_area) )
DBUG_RETURN(stat_area);
- my_errno=errno;
+
+ DBUG_PRINT("error",("Got errno: %d from stat", errno));
+ my_errno= errno;
if (m_used) /* Free if new area */
my_free((gptr) stat_area,MYF(0));
@@ -611,4 +635,3 @@ error:
}
DBUG_RETURN((MY_STAT *) NULL);
} /* my_stat */
-
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index c002f447f59..5058c301adb 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000-2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -32,6 +31,9 @@
#define INCL_NOPMAPI
#include <os2emx.h>
#endif
+#ifdef __NETWARE__
+#include <nks/fsio.h>
+#endif
/* Lock a part of a file */
@@ -42,6 +44,9 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
int value;
ALARM_VARIABLES;
#endif
+#ifdef __NETWARE__
+ int nxErrno;
+#endif
DBUG_ENTER("my_lock");
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
fd,locktype,(long) start,(long) length,MyFlags));
@@ -51,7 +56,47 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
if (my_disable_locking)
DBUG_RETURN(0);
-#if defined(__EMX__) || defined(OS2)
+#if defined(__NETWARE__)
+ {
+ NXSOffset_t nxLength = length;
+ unsigned long nxLockFlags = 0;
+
+ if (length == F_TO_EOF)
+ {
+ /* EOF is interpreted as a very large length. */
+ nxLength = 0x7FFFFFFFFFFFFFFF;
+ }
+
+ if (locktype == F_UNLCK)
+ {
+ /* The lock flags are currently ignored by NKS. */
+ if (!(nxErrno= NXFileRangeUnlock(fd, 0L, start, nxLength)))
+ DBUG_RETURN(0);
+ }
+ else
+ {
+ if (locktype == F_RDLCK)
+ {
+ /* A read lock is mapped to a shared lock. */
+ nxLockFlags = NX_RANGE_LOCK_SHARED;
+ }
+ else
+ {
+ /* A write lock is mapped to an exclusive lock. */
+ nxLockFlags = NX_RANGE_LOCK_EXCL;
+ }
+
+ if (MyFlags & MY_DONT_WAIT)
+ {
+ /* Don't block on the lock. */
+ nxLockFlags |= NX_RANGE_LOCK_TRYLOCK;
+ }
+
+ if (!(nxErrno= NXFileRangeLock(fd, nxLockFlags, start, nxLength)))
+ DBUG_RETURN(0);
+ }
+ }
+#elif defined(__EMX__) || defined(OS2)
if (!_lock64( fd, locktype, start, length, MyFlags))
DBUG_RETURN(0);
@@ -104,8 +149,12 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
#endif /* HAVE_FCNTL */
#endif /* HAVE_LOCKING */
+#ifdef __NETWARE__
+ my_errno = nxErrno;
+#else
/* We got an error. We don't want EACCES errors */
my_errno=(errno == EACCES) ? EAGAIN : errno ? errno : -1;
+#endif
if (MyFlags & MY_WME)
{
if (locktype == F_UNLCK)
diff --git a/mysys/my_lockmem.c b/mysys/my_lockmem.c
index 9c77c885797..6712c387a71 100644
--- a/mysys/my_lockmem.c
+++ b/mysys/my_lockmem.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Alloc a block of locked memory */
diff --git a/mysys/my_lread.c b/mysys/my_lread.c
index 94ed258151e..601d772b844 100644
--- a/mysys/my_lread.c
+++ b/mysys/my_lread.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_lwrite.c b/mysys/my_lwrite.c
index 734916173ce..e1a3decd053 100644
--- a/mysys/my_lwrite.c
+++ b/mysys/my_lwrite.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index c2df22ec7ec..b273363aaf1 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef SAFEMALLOC /* We don't need SAFEMALLOC here */
#undef SAFEMALLOC
@@ -74,7 +73,7 @@ gptr my_memdup(const byte *from, uint length, myf MyFlags)
}
-my_string my_strdup(const char *from, myf MyFlags)
+char *my_strdup(const char *from, myf MyFlags)
{
gptr ptr;
uint length=(uint) strlen(from)+1;
@@ -82,3 +81,15 @@ my_string my_strdup(const char *from, myf MyFlags)
memcpy((byte*) ptr, (byte*) from,(size_t) length);
return((my_string) ptr);
}
+
+
+char *my_strdup_with_length(const byte *from, uint length, myf MyFlags)
+{
+ gptr ptr;
+ if ((ptr=my_malloc(length+1,MyFlags)) != 0)
+ {
+ memcpy((byte*) ptr, (byte*) from,(size_t) length);
+ ((char*) ptr)[length]=0;
+ }
+ return((char*) ptr);
+}
diff --git a/mysys/my_messnc.c b/mysys/my_messnc.c
index 0dd3be5ba98..1f9df3c7c2c 100644
--- a/mysys/my_messnc.c
+++ b/mysys/my_messnc.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
@@ -24,7 +23,11 @@ int my_message_no_curses(uint error __attribute__((unused)),
DBUG_PRINT("enter",("message: %s",str));
(void) fflush(stdout);
if (MyFlags & ME_BELL)
+#ifdef __NETWARE__
+ ringbell(); /* Bell */
+#else
(void) fputc('\007',stderr); /* Bell */
+#endif /* __NETWARE__ */
if (my_progname)
{
(void)fputs(my_progname,stderr); (void)fputs(": ",stderr);
diff --git a/mysys/my_mkdir.c b/mysys/my_mkdir.c
index 3685312132c..ba1f4c1f2d8 100644
--- a/mysys/my_mkdir.c
+++ b/mysys/my_mkdir.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_net.c b/mysys/my_net.c
index 575c843f297..be92adae353 100644
--- a/mysys/my_net.c
+++ b/mysys/my_net.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* thread safe version of some common functions */
diff --git a/mysys/my_netware.c b/mysys/my_netware.c
new file mode 100644
index 00000000000..e41dbd0a029
--- /dev/null
+++ b/mysys/my_netware.c
@@ -0,0 +1,151 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Function specific to netware
+*/
+
+#include <mysys_priv.h>
+#ifdef __NETWARE__
+ #include <string.h>
+ #include <library.h>
+
+/*
+ PMUserLicenseRequest is an API exported by the polimgr.nlm
+ (loaded by the NetWare OS when it comes up) for use by other
+ NLM-based NetWare products/services.
+ PMUserLicenseRequest provides a couple of functions:
+ 1) it will optionally request a User license or ensure that
+ one already exists for the specified User in userInfo
+ 2) it utilizes the NetWare usage metering service to
+ record usage information about your product/service.
+*/
+
+long PMMeteredUsageRequest
+(
+ /*
+ NDS distinguished name or IP address or ??. asciiz string, e.g.
+ ".CN=Admin.O=this.T=MYTREE."
+ */
+ char *userInfo,
+ long infoType, /* see defined values */
+ /*
+ string used to identify the calling service, used to index the
+ metered info e.g. "iPrint"
+ */
+ char *serviceID,
+ char tranAddrType, /* type of address that follows */
+ char *tranAddr, /* ptr to a 10-byte array */
+ long flags, /* see defined values */
+ /* NLS error code, if any. NULL input is okay */
+ long *licRequestErrCode,
+ /* meter service error code, if any. NULL input is okay */
+ long *storeMeterInfoErrCode,
+ /*
+ error code from NLSMeter if
+ storeMeterInfoErrCode == PM_LICREQ_NLSMETERERROR.
+ NULL input is okay
+ */
+ long *NLSMeterErrCode
+);
+
+typedef long(*PMUR)(const char*, long, const char*, char,
+ const char*, long, long*, long*, long*);
+
+/* infoType */
+/* indicates that the info in the userInfo param is an NDS user */
+#define PM_USERINFO_TYPE_NDS 1
+/* indicates that the info in the userInfo param is NOT an NDS user */
+#define PM_USERINFO_TYPE_ADDRESS 2
+
+/* Flags */
+
+/*
+ Tells the service that it should not check to see if the NDS user
+ contained in the userInfo param has a NetWare User License - just
+ record metering information; this is ignored if infoType !=
+ PM_USERINFO_TYPE_NDS
+*/
+
+#define PM_FLAGS_METER_ONLY 0x0000001
+
+/*
+ Indicates that the values in the userInfo and serviceID parameters
+ are unicode strings, so that the metering service bypasses
+ converting these to unicode (again)
+*/
+#define PM_LICREQ_ALREADY_UNICODE 0x0000002
+/*
+ Useful only if infoType is PM_USERINFO_TYPE_NDS - indicates a "no
+ stop" policy of the calling service
+*/
+#define PM_LICREQ_ALWAYS_METER 0x0000004
+
+
+/*
+ net Address Types - system-defined types of net addresses that can
+ be used in the tranAddrType field
+*/
+
+#define NLS_TRAN_TYPE_IPX 0x00000001 /* An IPX address */
+#define NLS_TRAN_TYPE_IP 0x00000008 /* An IP address */
+#define NLS_ADDR_TYPE_MAC 0x000000F1 /* a MAC address */
+
+/*
+ Net Address Sizes - lengths that correspond to the tranAddrType
+ field (just fyi)
+*/
+#define NLS_IPX_ADDR_SIZE 10 /* the size of an IPX address */
+#define NLS_IP_ADDR_SIZE 4 /* the size of an IP address */
+#define NLS_MAC_ADDR_SIZE 6 /* the size of a MAC address */
+
+
+void netware_reg_user(const char *ip, const char *user,
+ const char *application)
+{
+ PMUR usage_request;
+ long licRequestErrCode = 0;
+ long storeMeterInfoErrCode = 0;
+ long nlsMeterErrCode = 0;
+
+ /* import the symbol */
+ usage_request= ((PMUR)ImportPublicObject(getnlmhandle(),
+ "PMMeteredUsageRequest"));
+ if (usage_request != NULL)
+ {
+ unsigned long iaddr;
+ char addr[NLS_IPX_ADDR_SIZE];
+
+ /* create address */
+ iaddr = htonl(inet_addr(ip));
+ bzero(addr, NLS_IPX_ADDR_SIZE);
+ memcpy(addr, &iaddr, NLS_IP_ADDR_SIZE);
+
+ /* call to NLS */
+ usage_request(user,
+ PM_USERINFO_TYPE_ADDRESS,
+ application,
+ NLS_TRAN_TYPE_IP,
+ addr,
+ PM_FLAGS_METER_ONLY,
+ &licRequestErrCode,
+ &storeMeterInfoErrCode,
+ &nlsMeterErrCode);
+ /* release symbol */
+ UnImportPublicObject(getnlmhandle(), "PMMeteredUsageRequest");
+ }
+}
+#endif /* __NETWARE__ */
diff --git a/mysys/my_new.cc b/mysys/my_new.cc
index 5cc291af9aa..5f2da90bbd1 100644
--- a/mysys/my_new.cc
+++ b/mysys/my_new.cc
@@ -25,12 +25,12 @@
void *operator new (size_t sz)
{
- return (void *) malloc (sz ? sz+1 : sz);
+ return (void *) malloc (sz ? sz : 1);
}
void *operator new[] (size_t sz)
{
- return (void *) malloc (sz ? sz+1 : sz);
+ return (void *) malloc (sz ? sz : 1);
}
void operator delete (void *ptr)
diff --git a/mysys/my_once.c b/mysys/my_once.c
index 0b8b5addc16..1250ce24994 100644
--- a/mysys/my_once.c
+++ b/mysys/my_once.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Not MT-SAFE */
@@ -25,8 +24,17 @@
#include "my_static.h"
#include "mysys_err.h"
- /* alloc for things we don't nead to free */
- /* No DBUG_ENTER... here to get smaller dbug-startup */
+/*
+ Alloc for things we don't nead to free
+
+ SYNOPSIS
+ my_once_alloc()
+ Size
+ MyFlags
+
+ NOTES
+ No DBUG_ENTER... here to get smaller dbug-startup
+*/
gptr my_once_alloc(unsigned int Size, myf MyFlags)
{
@@ -70,7 +78,12 @@ gptr my_once_alloc(unsigned int Size, myf MyFlags)
} /* my_once_alloc */
- /* deallocate everything used by my_once_alloc */
+/*
+ Deallocate everything used by my_once_alloc
+
+ SYNOPSIS
+ my_once_free()
+*/
void my_once_free(void)
{
diff --git a/mysys/my_open.c b/mysys/my_open.c
index 748113528a1..97f21724e1c 100644
--- a/mysys/my_open.c
+++ b/mysys/my_open.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES
#include "mysys_priv.h"
@@ -24,7 +23,18 @@
#include <share.h>
#endif
- /* Open a file */
+/*
+ Open a file
+
+ SYNOPSIS
+ my_open()
+ FileName Fully qualified file name
+ Flags Read | write
+ MyFlags Special flags
+
+ RETURN VALUE
+ File descriptor
+*/
File my_open(const char *FileName, int Flags, myf MyFlags)
/* Path-name of file */
@@ -52,7 +62,15 @@ File my_open(const char *FileName, int Flags, myf MyFlags)
} /* my_open */
- /* Close a file */
+/*
+ Close a file
+
+ SYNOPSIS
+ my_close()
+ fd File sescriptor
+ myf Special Flags
+
+*/
int my_close(File fd, myf MyFlags)
{
@@ -82,6 +100,16 @@ int my_close(File fd, myf MyFlags)
} /* my_close */
+/*
+ Register file in my_file_info[]
+
+ SYNOPSIS
+ my_register_filename()
+ fd
+ FileName
+ type_file_type
+*/
+
File my_register_filename(File fd, const char *FileName, enum file_type
type_of_file, uint error_message_number, myf MyFlags)
{
diff --git a/mysys/my_os2cond.c b/mysys/my_os2cond.c
index d930aadb2d1..e23afb89e66 100644
--- a/mysys/my_os2cond.c
+++ b/mysys/my_os2cond.c
@@ -26,7 +26,6 @@
#include "mysys_priv.h"
#if defined(THREAD) && defined(OS2)
#include <m_string.h>
-//#undef getpid
#include <process.h>
#include <sys/timeb.h>
diff --git a/mysys/my_os2dirsrch.c b/mysys/my_os2dirsrch.c
index 773d6800d1e..8d1f6ddd947 100644
--- a/mysys/my_os2dirsrch.c
+++ b/mysys/my_os2dirsrch.c
@@ -1,4 +1,4 @@
-/* Copyright (C) Yuri Dario & 2000 MySQL AB
+/* Copyright (C) Yuri Dario & 2000-2003 MySQL AB
All the above parties has a full, independent copyright to
the following code, including the right to use the code in
any manner without any demands from the other parties.
@@ -18,77 +18,79 @@
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
+
/* Win32 directory search emulation */
#if defined(OS2)
-//#define _DEBUG
-
long _findfirst( char* path, struct _finddata_t* dos_file)
{
- HDIR hdir = HDIR_CREATE;
- APIRET rc;
- FILEFINDBUF3 buf3;
- ULONG entries = 1;
+ HDIR hdir = HDIR_CREATE;
+ APIRET rc;
+ FILEFINDBUF3 buf3;
+ ULONG entries = 1;
#ifdef _DEBUG
- printf( "_findfirst path %s\n", path);
+ printf( "_findfirst path %s\n", path);
#endif
- memset( &buf3, 0, sizeof( buf3));
- rc = DosFindFirst(
- path, /* Address of the ASCIIZ path name of the file or subdirectory to be found. */
- &hdir, /* Address of the handle associated with this DosFindFirst request. */
- FILE_NORMAL | FILE_DIRECTORY, /* Attribute value that determines the file objects to be searched for. */
- &buf3, /* Result buffer. */
- sizeof( buf3), /* The length, in bytes, of pfindbuf. */
- &entries, /* Pointer to the number of entries: */
- FIL_STANDARD); /* The level of file information required. */
+ memset( &buf3, 0, sizeof( buf3));
+ rc = DosFindFirst(
+ path, /* The ASCIIZ path name of the file or subdirectory to be found. */
+ &hdir, /* The handle associated with this DosFindFirst request. */
+ FILE_NORMAL | FILE_DIRECTORY, /* Attribute value that determines the file objects to be searched for. */
+ &buf3, /* Result buffer. */
+ sizeof( buf3), /* The length, in bytes, of pfindbuf. */
+ &entries, /* Pointer to the number of entries: */
+ FIL_STANDARD); /* The level of file information required. */
#ifdef _DEBUG
- printf( "_findfirst rc=%d hdir=%d entries=%d->%s\n", rc, hdir, entries, buf3.achName);
+ printf( "_findfirst rc=%d hdir=%d entries=%d->%s\n", rc, hdir, entries,
+ buf3.achName);
#endif
- if (rc /* && entries == 0 */)
- return -1;
-
- if (dos_file) {
- memset( dos_file, 0, sizeof( struct _finddata_t));
- strcpy( dos_file->name, buf3.achName);
- dos_file->size = buf3.cbFile;
- dos_file->attrib = buf3.attrFile;
- }
- return (ULONG) hdir;
+ if (rc /* && entries == 0 */)
+ return -1;
+
+ if (dos_file)
+ {
+ memset( dos_file, 0, sizeof( struct _finddata_t));
+ strcpy( dos_file->name, buf3.achName);
+ dos_file->size = buf3.cbFile;
+ dos_file->attrib = buf3.attrFile;
+ }
+ return (ULONG) hdir;
}
long _findnext( long hdir, struct _finddata_t* dos_file)
{
- APIRET rc;
- FILEFINDBUF3 buf3;
- ULONG entries = 1;
+ APIRET rc;
+ FILEFINDBUF3 buf3;
+ ULONG entries = 1;
- memset( &buf3, 0, sizeof( buf3));
- rc = DosFindNext(
- hdir,
- &buf3, /* Result buffer. */
- sizeof( buf3), /* The length, in bytes, of pfindbuf. */
- &entries); /* Pointer to the number of entries: */
+ memset( &buf3, 0, sizeof( buf3));
+ rc = DosFindNext(hdir,
+ &buf3, /* Result buffer. */
+ sizeof( buf3), /* Length, in bytes, of pfindbuf. */
+ &entries); /* Pointer to the number of entries */
#ifdef _DEBUG
- printf( "_findnext rc=%d hdir=%d entries=%d->%s\n", rc, hdir, entries, buf3.achName);
+ printf( "_findnext rc=%d hdir=%d entries=%d->%s\n", rc, hdir, entries,
+ buf3.achName);
#endif
- if (rc /* && entries == 0 */)
- return -1;
-
- if (dos_file) {
- memset( dos_file, 0, sizeof( struct _finddata_t));
- strcpy( dos_file->name, buf3.achName);
- dos_file->size = buf3.cbFile;
- dos_file->attrib = buf3.attrFile;
- }
- return 0;
+ if (rc /* && entries == 0 */)
+ return -1;
+
+ if (dos_file)
+ {
+ memset( dos_file, 0, sizeof( struct _finddata_t));
+ strcpy( dos_file->name, buf3.achName);
+ dos_file->size = buf3.cbFile;
+ dos_file->attrib = buf3.attrFile;
+ }
+ return 0;
}
void _findclose( long hdir)
@@ -101,82 +103,82 @@ void _findclose( long hdir)
#endif
}
-DIR* opendir( char* path)
+DIR* opendir(char* path)
{
- DIR* dir = (DIR*) calloc( 1, sizeof( DIR));
- char buffer[260];
- APIRET rc;
- ULONG entries = 1;
+ DIR* dir = (DIR*) calloc(1, sizeof( DIR));
+ char buffer[260];
+ APIRET rc;
+ ULONG entries = 1;
- strcpy( buffer, path);
- strcat( buffer, "*.*");
+ strmov(strmov(buffer, path), "*.*");
#ifdef _DEBUG
- printf( "_findfirst path %s\n", buffer);
+ printf( "_findfirst path %s\n", buffer);
#endif
- dir->hdir = HDIR_CREATE;
- memset( &dir->buf3, 0, sizeof( dir->buf3));
- rc = DosFindFirst(
- buffer, /* Address of the ASCIIZ path name of the file or subdirectory to be found. */
- &dir->hdir, /* Address of the handle associated with this DosFindFirst request. */
- FILE_NORMAL | FILE_DIRECTORY, /* Attribute value that determines the file objects to be searched for. */
- &dir->buf3, /* Result buffer. */
- sizeof( dir->buf3), /* The length, in bytes, of pfindbuf. */
- &entries, /* Pointer to the number of entries: */
- FIL_STANDARD); /* The level of file information required. */
+ dir->hdir = HDIR_CREATE;
+ memset( &dir->buf3, 0, sizeof( dir->buf3));
+ rc = DosFindFirst(
+ buffer, /* Address of the ASCIIZ path name of the file or subdirectory to be found. */
+ &dir->hdir, /* Address of the handle associated with this DosFindFirst request. */
+ FILE_NORMAL | FILE_DIRECTORY, /* Attribute value that determines the file objects to be searched for. */
+ &dir->buf3, /* Result buffer. */
+ sizeof( dir->buf3), /* The length, in bytes, of pfindbuf. */
+ &entries, /* Pointer to the number of entries: */
+ FIL_STANDARD); /* The level of file information required. */
#ifdef _DEBUG
- printf( "opendir rc=%d hdir=%d entries=%d->%s\n", rc, dir->hdir, entries, dir->buf3.achName);
+ printf( "opendir rc=%d hdir=%d entries=%d->%s\n", rc, dir->hdir, entries, dir->buf3.achName);
#endif
- if (rc /* && entries == 0 */)
- return NULL;
+ if (rc /* && entries == 0 */)
+ return NULL;
- return dir;
+ return dir;
}
+
struct dirent* readdir( DIR* dir)
{
- APIRET rc;
- //FILEFINDBUF3 buf3;
- ULONG entries = 1;
+ APIRET rc;
+ ULONG entries = 1;
- if (!dir->buf3.achName[0]) // file not found on previous query
- return NULL;
+ if (!dir->buf3.achName[0]) /* file not found on previous query */
+ return NULL;
- // copy last file name
- strcpy( dir->ent.d_name, dir->buf3.achName);
+ /* copy last file name */
+ strcpy( dir->ent.d_name, dir->buf3.achName);
- // query next file
- memset( &dir->buf3, 0, sizeof( dir->buf3));
- rc = DosFindNext(
- dir->hdir,
- &dir->buf3, /* Result buffer. */
- sizeof( dir->buf3), /* The length, in bytes, of pfindbuf. */
- &entries); /* Pointer to the number of entries: */
+ /* query next file */
+ memset( &dir->buf3, 0, sizeof( dir->buf3));
+ rc= DosFindNext(
+ dir->hdir,
+ &dir->buf3, /* Result buffer. */
+ sizeof(dir->buf3), /* Length, in bytes, of pfindbuf. */
+ &entries); /* Pointer to the number of entries */
#ifdef _DEBUG
- printf( "_findnext rc=%d hdir=%d entries=%d->%s\n", rc, dir->hdir, entries, dir->buf3.achName);
+ printf( "_findnext rc=%d hdir=%d entries=%d->%s\n", rc, dir->hdir, entries,
+ dir->buf3.achName);
#endif
- if (rc /* && entries == 0 */)
- strcpy( dir->buf3.achName, ""); // reset name for next query
+ if (rc /* && entries == 0 */)
+ *dir->buf3.achName= 0; /* reset name for next query */
- return &dir->ent;
+ return &dir->ent;
}
+
int closedir (DIR *dir)
{
- APIRET rc;
+ APIRET rc;
- rc = DosFindClose( dir->hdir);
+ rc = DosFindClose( dir->hdir);
#ifdef _DEBUG
- printf( "_findclose rc=%d hdir=%d\n", rc, dir->hdir);
+ printf( "_findclose rc=%d hdir=%d\n", rc, dir->hdir);
#endif
- free(dir);
- return 0;
+ free(dir);
+ return 0;
}
-
-#endif // OS2
+#endif /* OS2 */
diff --git a/mysys/my_os2dirsrch.h b/mysys/my_os2dirsrch.h
index e894d27b576..3889f628bad 100644
--- a/mysys/my_os2dirsrch.h
+++ b/mysys/my_os2dirsrch.h
@@ -29,26 +29,35 @@ extern "C" {
struct _finddata_t
{
- unsigned attrib;
- //unsigned long time_create; /* -1 for FAT file systems */
- //unsigned long time_access; /* -1 for FAT file systems */
- //unsigned long time_write;
- unsigned long size;
- char name[260];
- //uint16 wr_date;
- //uint16 wr_time;
+ unsigned attrib;
+#ifdef NOT_USED
+ unsigned long time_create; /* -1 for FAT file systems */
+ unsigned long time_access; /* -1 for FAT file systems */
+ unsigned long time_write;
+#endif
+ unsigned long size;
+ char name[260];
+#ifdef NOT_USED
+ uint16 wr_date;
+ uint16 wr_time;
+#endif
};
+
struct dirent
{
- //unsigned attrib;
- //unsigned long time_create; /* -1 for FAT file systems */
- //unsigned long time_access; /* -1 for FAT file systems */
- //unsigned long time_write;
- //unsigned long size;
- char d_name[260];
- //uint16 wr_date;
- //uint16 wr_time;
+#ifdef NOT_USED
+ unsigned attrib;
+ unsigned long time_create; /* -1 for FAT file systems */
+ unsigned long time_access; /* -1 for FAT file systems */
+ unsigned long time_write;
+ unsigned long size;
+#endif
+ char d_name[260];
+#ifdef NOT_USED
+ uint16 wr_date;
+ uint16 wr_time;
+#endif
};
struct DIR
@@ -62,16 +71,18 @@ DIR *opendir ( char *);
struct dirent *readdir (DIR *);
int closedir (DIR *);
-//#define _A_NORMAL FILE_NORMAL
-//#define _A_SUBDIR FILE_DIRECTORY
-//#define _A_RDONLY FILE_READONLY
+#ifdef NOT_USED
+#define _A_NORMAL FILE_NORMAL
+#define _A_SUBDIR FILE_DIRECTORY
+#define _A_RDONLY FILE_READONLY
-//long _findfirst( char*, struct _finddata_t*);
-//long _findnext( long, struct _finddata_t*);
-//void _findclose( long);
+long _findfirst( char*, struct _finddata_t*);
+long _findnext( long, struct _finddata_t*);
+void _findclose( long);
+#endif
#ifdef __cplusplus_00
}
#endif
-#endif // __MY_OS2DIRSRCH2_H__
+#endif /* __MY_OS2DIRSRCH2_H__ */
diff --git a/mysys/my_os2file64.c b/mysys/my_os2file64.c
index bc24c92b87f..786e083adc4 100644
--- a/mysys/my_os2file64.c
+++ b/mysys/my_os2file64.c
@@ -24,10 +24,11 @@ int _lock64( int fd, int locktype, my_off_t start,
my_off_t length, myf MyFlags);
int _sopen64( const char *name, int oflag, int shflag, int mask);
-//
-// this class is used to define a global c++ variable, that
-// is initialized before main() gets called.
-//
+/*
+ This class is used to define a global c++ variable, that
+ is initialized before main() gets called.
+*/
+
class File64bit
{
public:
@@ -150,7 +151,7 @@ static unsigned char const errno_tab[] =
_DosSetFilePtrL = NULL;
return;
}
- // notify success
+ /* notify success */
#ifdef MYSQL_SERVER
printf( "WSeB 64bit file API loaded.\n");
#endif
@@ -164,230 +165,230 @@ void _OS2errno( APIRET rc)
errno = errno_tab[rc];
}
-longlong _lseek64( int fd, longlong offset, int seektype)
-{
- APIRET rc;
- longlong actual;
-
- if (_DosSetFilePtrL)
- rc = _DosSetFilePtrL( fd, offset, seektype, &actual);
- else {
- ULONG ulActual;
- rc = DosSetFilePtr( fd, (long) offset, seektype, &ulActual);
- actual = ulActual;
- }
-
- if (!rc)
- return( actual);/* NO_ERROR */
-
- // set errno
- _OS2errno( rc);
- // seek failed
- return(-1);
-}
-inline _SetFileLocksL(HFILE hFile,
- PFILELOCKL pflUnlock,
- PFILELOCKL pflLock,
- ULONG timeout,
- ULONG flags)
+longlong _lseek64( int fd, longlong offset, int seektype)
{
- if (_DosSetFileLocksL) {
- APIRET rc;
- rc = _DosSetFileLocksL( hFile, pflUnlock, pflLock, timeout, flags);
+ APIRET rc;
+ longlong actual;
- // on FAT/HPFS/LAN a INVALID_PARAMETER is returned, seems that
- // only JFS can handle >2GB ranges.
- if (rc != 87)
- return rc;
+ if (_DosSetFilePtrL)
+ rc = _DosSetFilePtrL( fd, offset, seektype, &actual);
+ else
+ {
+ ULONG ulActual;
+ rc = DosSetFilePtr( fd, (long) offset, seektype, &ulActual);
+ actual = ulActual;
+ }
- // got INVALID_PARAMETER, fallback to standard call
- }
+ if (!rc)
+ return( actual); /* NO_ERROR */
- FILELOCK flUnlock = { pflUnlock->lOffset, pflUnlock->lRange };
- FILELOCK flLock = { pflLock->lOffset, pflLock->lRange };
- return DosSetFileLocks( hFile, &flUnlock, &flLock, timeout, flags);
+ _OS2errno( rc); /* set errno */
+ return(-1); /* seek failed */
}
-int _lock64( int fd, int locktype, my_off_t start,
- my_off_t length, myf MyFlags)
-{
- FILELOCKL LockArea = {0,0}, UnlockArea = {0,0};
- ULONG readonly = 0;
- APIRET rc = -1;
-
- switch( locktype) {
- case F_UNLCK:
- UnlockArea.lOffset = start;
- UnlockArea.lRange = length ? length : LONGLONG_MAX;
- break;
-
- case F_RDLCK:
- case F_WRLCK:
- LockArea.lOffset = start;
- LockArea.lRange = length ? length : LONGLONG_MAX;
- readonly = (locktype == F_RDLCK ? 1 : 0);
- break;
-
- default:
- errno = EINVAL;
- rc = -1;
- break;
- }
-
- if (MyFlags & MY_DONT_WAIT) {
-
- rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly);
- //printf( "fd %d, locktype %d, rc %d (dont_wait)\n", fd, locktype, rc);
- if (rc == 33) { /* Lock Violation */
-
- DBUG_PRINT("info",("Was locked, trying with timeout"));
- rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 1 * 1000, readonly);
- //printf( "fd %d, locktype %d, rc %d (dont_wait with timeout)\n", fd, locktype, rc);
- }
-
- } else {
-
- while( rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly) && (rc == 33)) {
- printf(".");
- DosSleep(1 * 1000);
- }
- //printf( "fd %d, locktype %d, rc %d (wait2)\n", fd, locktype, rc);
- }
-
- if (!rc)
- return( 0);/* NO_ERROR */
- // set errno
- _OS2errno( rc);
- // lock failed
- return(-1);
+inline APIRET _SetFileLocksL(HFILE hFile,
+ PFILELOCKL pflUnlock,
+ PFILELOCKL pflLock,
+ ULONG timeout,
+ ULONG flags)
+{
+ if (_DosSetFileLocksL)
+ {
+ APIRET rc;
+ rc = _DosSetFileLocksL( hFile, pflUnlock, pflLock, timeout, flags);
+
+ /*
+ on FAT/HPFS/LAN a INVALID_PARAMETER is returned, seems that
+ only JFS can handle >2GB ranges.
+ */
+ if (rc != 87)
+ return rc;
+ /* got INVALID_PARAMETER, fallback to standard call */
+ }
+
+ FILELOCK flUnlock = { pflUnlock->lOffset, pflUnlock->lRange };
+ FILELOCK flLock = { pflLock->lOffset, pflLock->lRange };
+ return DosSetFileLocks( hFile, &flUnlock, &flLock, timeout, flags);
}
-int sopen( const char *name, int oflag, int shflag, int mask)
+
+int _lock64( int fd, int locktype, my_off_t start,
+ my_off_t length, myf MyFlags)
{
- int fail_errno;
- APIRET rc = 0;
- HFILE hf = 0;
- ULONG ulAction = 0;
- LONGLONG cbFile = 0;
- ULONG ulAttribute = FILE_NORMAL;
- ULONG fsOpenFlags = 0;
- ULONG fsOpenMode = 0;
-
- /* Extract the access mode and sharing mode bits. */
- fsOpenMode = (shflag & 0xFF) | (oflag & 0x03);
-
- /* Translate ERROR_OPEN_FAILED to ENOENT unless O_EXCL is set (see
- below). */
- fail_errno = ENOENT;
-
- /* Compute `open_flag' depending on `flags'. Note that _SO_CREAT is
- set for O_CREAT. */
-
- if (oflag & O_CREAT)
- {
- if (oflag & O_EXCL)
- {
- fsOpenFlags = OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
- fail_errno = EEXIST;
- }
- else if (oflag & O_TRUNC)
- fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
- else
- fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
-
- if (mask & S_IWRITE)
- ulAttribute = FILE_NORMAL;
- else
- ulAttribute = FILE_READONLY;
+ FILELOCKL LockArea = {0,0}, UnlockArea = {0,0};
+ ULONG readonly = 0;
+ APIRET rc = -1;
+
+ switch (locktype) {
+ case F_UNLCK:
+ UnlockArea.lOffset = start;
+ UnlockArea.lRange = length ? length : LONGLONG_MAX;
+ break;
+
+ case F_RDLCK:
+ case F_WRLCK:
+ LockArea.lOffset = start;
+ LockArea.lRange = length ? length : LONGLONG_MAX;
+ readonly = (locktype == F_RDLCK ? 1 : 0);
+ break;
+
+ default:
+ errno = EINVAL;
+ rc = -1;
+ break;
+ }
+
+ if (MyFlags & MY_DONT_WAIT)
+ {
+ rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly);
+ /* printf("fd %d, locktype %d, rc %d (dont_wait)\n", fd, locktype, rc); */
+ if (rc == 33) { /* Lock Violation */
+
+ DBUG_PRINT("info",("Was locked, trying with timeout"));
+ rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 1 * 1000, readonly);
+ /* printf( "fd %d, locktype %d, rc %d (dont_wait with timeout)\n", fd, locktype, rc); */
+ }
+ }
+ else
+ {
+ while (rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly) &&
+ (rc == 33))
+ {
+ printf(".");
+ DosSleep(1 * 1000);
+ }
+ /* printf( "fd %d, locktype %d, rc %d (wait2)\n", fd, locktype, rc); */
+ }
+ if (!rc)
+ return(0); /* NO_ERROR */
+ _OS2errno( rc); /* set errno */
+ return(-1); /* lock failed */
+}
- }
- else if (oflag & O_TRUNC)
- fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
- else
- fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
-
- /* Try to open the file and handle errors. */
- if (_DosOpenL)
- rc = _DosOpenL( name, &hf, &ulAction, cbFile,
- ulAttribute, fsOpenFlags, fsOpenMode, NULL);
- else
- rc = DosOpen( name, &hf, &ulAction, (LONG) cbFile,
- ulAttribute, fsOpenFlags, fsOpenMode, NULL);
-
- if (rc == ERROR_OPEN_FAILED)
- {
- errno = fail_errno;
- return -1;
- }
- if (rc != 0)
- {
- // set errno
- _OS2errno( rc);
- return -1;
- }
- if (oflag & O_APPEND)
- _lseek64( hf, 0L, SEEK_END);
+int sopen(const char *name, int oflag, int shflag, int mask)
+{
+ int fail_errno;
+ APIRET rc = 0;
+ HFILE hf = 0;
+ ULONG ulAction = 0;
+ LONGLONG cbFile = 0;
+ ULONG ulAttribute = FILE_NORMAL;
+ ULONG fsOpenFlags = 0;
+ ULONG fsOpenMode = 0;
+
+ /* Extract the access mode and sharing mode bits. */
+ fsOpenMode = (shflag & 0xFF) | (oflag & 0x03);
+
+ /*
+ Translate ERROR_OPEN_FAILED to ENOENT unless O_EXCL is set (see
+ below).
+ */
+ fail_errno = ENOENT;
+
+ /*
+ Compute `open_flag' depending on `flags'. Note that _SO_CREAT is
+ set for O_CREAT.
+ */
+
+ if (oflag & O_CREAT)
+ {
+ if (oflag & O_EXCL)
+ {
+ fsOpenFlags = OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
+ fail_errno = EEXIST;
+ }
+ else if (oflag & O_TRUNC)
+ fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
+ else
+ fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
+
+ if (mask & S_IWRITE)
+ ulAttribute = FILE_NORMAL;
+ else
+ ulAttribute = FILE_READONLY;
+
+ }
+ else if (oflag & O_TRUNC)
+ fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
+ else
+ fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
- return hf;
+ /* Try to open the file and handle errors. */
+ if (_DosOpenL)
+ rc = _DosOpenL( name, &hf, &ulAction, cbFile,
+ ulAttribute, fsOpenFlags, fsOpenMode, NULL);
+ else
+ rc = DosOpen( name, &hf, &ulAction, (LONG) cbFile,
+ ulAttribute, fsOpenFlags, fsOpenMode, NULL);
+
+ if (rc == ERROR_OPEN_FAILED)
+ {
+ errno = fail_errno;
+ return -1;
+ }
+ if (rc != 0)
+ {
+ _OS2errno( rc); /* set errno */
+ return -1;
+ }
+ if (oflag & O_APPEND)
+ _lseek64( hf, 0L, SEEK_END);
+ return hf;
}
-int read( int fd, void *buffer, unsigned int count)
-{
- APIRET rc;
- ULONG actual;
- rc = DosRead( fd, (PVOID) buffer, count, &actual);
+int read(int fd, void *buffer, unsigned int count)
+{
+ APIRET rc;
+ ULONG actual;
- if (!rc)
- return( actual);/* NO_ERROR */
+ rc= DosRead( fd, (PVOID) buffer, count, &actual);
- // set errno
- _OS2errno( rc);
- // write failed
- return(-1);
+ if (!rc)
+ return( actual); /* NO_ERROR */
+ _OS2errno( rc); /* set errno */
+ return(-1); /* read failed */
}
-int write( int fd, const void *buffer, unsigned int count)
-{
- APIRET rc;
- ULONG actual;
- rc = DosWrite( fd, (PVOID) buffer, count, &actual);
+int write(int fd, const void *buffer, unsigned int count)
+{
+ APIRET rc;
+ ULONG actual;
- if (!rc)
- return( actual);/* NO_ERROR */
+ rc = DosWrite( fd, (PVOID) buffer, count, &actual);
- // set errno
- _OS2errno( rc);
- // write failed
- return(-1);
+ if (!rc)
+ return( actual); /* NO_ERROR */
+ _OS2errno( rc); /* set errno */
+ return(-1); /* write failed */
}
-int close( int fd)
-{
- APIRET rc;
- ULONG actual;
- rc = DosClose( fd);
+int close( int fd)
+{
+ APIRET rc;
+ ULONG actual;
- if (!rc)
- return( 0);/* NO_ERROR */
+ rc = DosClose( fd);
- // set errno
- _OS2errno( rc);
- // write failed
- return(-1);
+ if (!rc)
+ return( 0); /* NO_ERROR */
+ _OS2errno( rc); /* set errno */
+ return(-1); /* close failed */
}
-inline int open( const char *name, int oflag)
+
+int open( const char *name, int oflag)
{
return sopen( name, oflag, OPEN_SHARE_DENYNONE, S_IREAD | S_IWRITE);
}
-inline int open( const char *name, int oflag, int mask)
+
+int open( const char *name, int oflag, int mask)
{
return sopen( name, oflag, OPEN_SHARE_DENYNONE, mask);
}
diff --git a/mysys/my_os2mutex.c b/mysys/my_os2mutex.c
index 718aa9f2932..5010d6e8dd5 100644
--- a/mysys/my_os2mutex.c
+++ b/mysys/my_os2mutex.c
@@ -36,63 +36,48 @@
#include <stdlib.h>
#include <errno.h>
#ifdef _THREAD_SAFE
-//#include <pthread.h>
-//#include "pthread_private.h"
int
pthread_mutex_init(pthread_mutex_t * mutex,
const pthread_mutexattr_t * mutex_attr)
{
- APIRET rc = 0;
-
- rc = DosCreateMutexSem(NULL,mutex,0,0);
-
- /* Return the completion status: */
- return (0);
+ (void) DosCreateMutexSem(NULL,mutex,0,0);
+ return (0); /* Return the completion status: */
}
+
int
pthread_mutex_destroy(pthread_mutex_t * mutex)
{
- APIRET rc = 0;
-
+ APIRET rc;
- do {
- rc = DosCloseMutexSem(*mutex);
- if (rc == 301) DosReleaseMutexSem(*mutex);
- } while (rc == 301);
+ do
+ {
+ rc = DosCloseMutexSem(*mutex);
+ if (rc == 301) DosReleaseMutexSem(*mutex);
+ } while (rc == 301);
- *mutex = 0;
-
- /* Return the completion status: */
- return (0);
+ *mutex = 0;
+ return (0); /* Return the completion status: */
}
int
pthread_mutex_lock(pthread_mutex_t * mutex)
{
- int ret = 0;
- int status = 0;
- APIRET rc = 0;
+ APIRET rc;
- rc = DosRequestMutexSem(*mutex,SEM_INDEFINITE_WAIT);
- if (rc)
- return(EINVAL);
- /* Return the completion status: */
- return (0);
+ rc = DosRequestMutexSem(*mutex,SEM_INDEFINITE_WAIT);
+ if (rc)
+ return(EINVAL);
+ return (0); /* Return the completion status: */
}
+
int
pthread_mutex_unlock(pthread_mutex_t * mutex)
{
- int ret = 0;
- APIRET rc = 0;
- int status;
-
- rc = DosReleaseMutexSem(*mutex);
-
- /* Return the completion status: */
- return (0);
+ (void) DosReleaseMutexSem(*mutex);
+ return (0); /* Return the completion status: */
}
#endif
diff --git a/mysys/my_os2thread.c b/mysys/my_os2thread.c
index 6f196f43d75..0696f480a91 100644
--- a/mysys/my_os2thread.c
+++ b/mysys/my_os2thread.c
@@ -61,10 +61,9 @@ static pthread_handler_decl(pthread_start,param)
win_pthread_self=((struct pthread_map *) param)->pthreadself;
pthread_mutex_unlock(&THR_LOCK_thread);
free((char*) param); /* Free param from create */
- //pthread_exit((void*) (*func)(func_param));
+ /* pthread_exit((void*) (*func)(func_param)); */
(*func)(func_param);
DBUG_RETURN(0);
- //return 0; /* Safety */
}
diff --git a/mysys/my_os2tls.c b/mysys/my_os2tls.c
index 1598fa34e2b..f7cf3b09283 100644
--- a/mysys/my_os2tls.c
+++ b/mysys/my_os2tls.c
@@ -30,115 +30,122 @@ PULONG tls_storage; /* TLS local storage */
DWORD tls_bits[2]; /* TLS in-use bits */
pthread_mutex_t tls_mutex; /* TLS mutex for in-use bits */
+
DWORD TlsAlloc( void)
{
- DWORD index = -1;
- DWORD mask, tibidx;
- int i;
-
- if (tls_storage == NULL) {
-
- APIRET rc;
-
- // allocate memory for TLS storage
- rc = DosAllocThreadLocalMemory( 1, &tls_storage);
- if (rc) {
- fprintf( stderr, "DosAllocThreadLocalMemory error: return code = %u\n", rc);
- }
-
- // create a mutex
- if (pthread_mutex_init( &tls_mutex, NULL))
- fprintf( stderr, "Failed to init TLS mutex\n");
- }
-
- pthread_mutex_lock( &tls_mutex);
-
- tibidx = 0;
- if (tls_bits[0] == 0xFFFFFFFF) {
- if (tls_bits[1] == 0xFFFFFFFF) {
- fprintf( stderr, "tid#%d, no more TLS bits available\n", _threadid);
- pthread_mutex_unlock( &tls_mutex);
- return -1;
- }
- tibidx = 1;
- }
- for( i=0; i<32; i++) {
- mask = (1 << i);
- if ((tls_bits[ tibidx] & mask) == 0) {
- tls_bits[ tibidx] |= mask;
- index = (tibidx*32) + i;
- break;
- }
- }
- tls_storage[index] = 0;
-
- pthread_mutex_unlock( &tls_mutex);
-
- //fprintf( stderr, "tid#%d, TlsAlloc index %d\n", _threadid, index);
-
- return index;
+ DWORD index = -1;
+ DWORD mask, tibidx;
+ int i;
+
+ if (tls_storage == NULL)
+ {
+
+ APIRET rc;
+
+ /* allocate memory for TLS storage */
+ rc = DosAllocThreadLocalMemory( 1, &tls_storage);
+ if (rc)
+ fprintf( stderr, "DosAllocThreadLocalMemory error: return code = %u\n",
+ rc);
+ /* create a mutex */
+ if (pthread_mutex_init( &tls_mutex, NULL))
+ fprintf( stderr, "Failed to init TLS mutex\n");
+ }
+
+ pthread_mutex_lock( &tls_mutex);
+
+ tibidx = 0;
+ if (tls_bits[0] == 0xFFFFFFFF)
+ {
+ if (tls_bits[1] == 0xFFFFFFFF)
+ {
+ fprintf( stderr, "tid#%d, no more TLS bits available\n", _threadid);
+ pthread_mutex_unlock( &tls_mutex);
+ return -1;
+ }
+ tibidx = 1;
+ }
+
+ for (i=0; i<32; i++)
+ {
+ mask = (1 << i);
+ if ((tls_bits[ tibidx] & mask) == 0)
+ {
+ tls_bits[ tibidx] |= mask;
+ index = (tibidx*32) + i;
+ break;
+ }
+ }
+ tls_storage[index] = 0;
+
+ pthread_mutex_unlock( &tls_mutex);
+ /* fprintf( stderr, "tid#%d, TlsAlloc index %d\n", _threadid, index); */
+ return index;
}
-BOOL TlsFree( DWORD index)
+BOOL TlsFree( DWORD index)
{
- int tlsidx;
- DWORD mask;
-
- if (index >= TLS_MINIMUM_AVAILABLE)
- return NULL;
-
- pthread_mutex_lock( &tls_mutex);
-
- tlsidx = 0;
- if (index > 32) {
- tlsidx++;
- }
- mask = (1 << index);
- if (tls_bits[ tlsidx] & mask) {
- tls_bits[tlsidx] &= ~mask;
- tls_storage[index] = 0;
- pthread_mutex_unlock( &tls_mutex);
- return TRUE;
- }
+ int tlsidx;
+ DWORD mask;
- pthread_mutex_unlock( &tls_mutex);
- return FALSE;
-}
+ if (index >= TLS_MINIMUM_AVAILABLE)
+ return NULL;
+ pthread_mutex_lock( &tls_mutex);
-PVOID TlsGetValue( DWORD index)
-{
- if (index >= TLS_MINIMUM_AVAILABLE)
- return NULL;
-
- // verify if memory has been allocated for this thread
- if (*tls_storage == NULL) {
- // allocate memory for indexes
- *tls_storage = (ULONG)calloc( TLS_MINIMUM_AVAILABLE, sizeof(int));
- //fprintf( stderr, "tid#%d, tls_storage %x\n", _threadid, *tls_storage);
- }
-
- ULONG* tls_array = (ULONG*) *tls_storage;
- return (PVOID) tls_array[ index];
+ tlsidx = 0;
+ if (index > 32)
+ tlsidx++;
+
+ mask = (1 << index);
+ if (tls_bits[ tlsidx] & mask)
+ {
+ tls_bits[tlsidx] &= ~mask;
+ tls_storage[index] = 0;
+ pthread_mutex_unlock( &tls_mutex);
+ return TRUE;
+ }
+
+ pthread_mutex_unlock( &tls_mutex);
+ return FALSE;
}
-BOOL TlsSetValue( DWORD index, PVOID val)
-{
- // verify if memory has been allocated for this thread
- if (*tls_storage == NULL) {
- // allocate memory for indexes
- *tls_storage = (ULONG)calloc( TLS_MINIMUM_AVAILABLE, sizeof(int));
- //fprintf( stderr, "tid#%d, tls_storage %x\n", _threadid, *tls_storage);
- }
+PVOID TlsGetValue( DWORD index)
+{
+ if (index >= TLS_MINIMUM_AVAILABLE)
+ return NULL;
+
+ /* verify if memory has been allocated for this thread */
+ if (*tls_storage == NULL)
+ {
+ /* allocate memory for indexes */
+ *tls_storage = (ULONG)calloc( TLS_MINIMUM_AVAILABLE, sizeof(int));
+ /* fprintf(stderr, "tid#%d, tls_storage %x\n", _threadid, *tls_storage); */
+ }
+
+ ULONG* tls_array = (ULONG*) *tls_storage;
+ return (PVOID) tls_array[index];
+}
- if (index >= TLS_MINIMUM_AVAILABLE)
- return FALSE;
- ULONG* tls_array = (ULONG*) *tls_storage;
- //fprintf( stderr, "tid#%d, TlsSetValue array %08x index %d -> %08x (old)\n", _threadid, tls_array, index, tls_array[ index]);
- tls_array[ index] = (ULONG) val;
- //fprintf( stderr, "tid#%d, TlsSetValue array %08x index %d -> %08x\n", _threadid, tls_array, index, val);
+BOOL TlsSetValue( DWORD index, PVOID val)
+{
- return TRUE;
+ /* verify if memory has been allocated for this thread */
+ if (*tls_storage == NULL)
+ {
+ /* allocate memory for indexes */
+ *tls_storage = (ULONG)calloc( TLS_MINIMUM_AVAILABLE, sizeof(int));
+ /* fprintf(stderr, "tid#%d, tls_storage %x\n", _threadid, *tls_storage); */
+ }
+
+ if (index >= TLS_MINIMUM_AVAILABLE)
+ return FALSE;
+
+ ULONG* tls_array = (ULONG*) *tls_storage;
+ /* fprintf( stderr, "tid#%d, TlsSetValue array %08x index %d -> %08x (old)\n", _threadid, tls_array, index, tls_array[ index]); */
+ tls_array[ index] = (ULONG) val;
+ /* fprintf( stderr, "tid#%d, TlsSetValue array %08x index %d -> %08x\n", _threadid, tls_array, index, val); */
+ return TRUE;
}
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index 5c7d0be5854..661ef48ab3e 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c
index ecd3631f59d..5be38fad734 100644
--- a/mysys/my_pthread.c
+++ b/mysys/my_pthread.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000-2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Functions to get threads more portable */
@@ -91,9 +90,36 @@ void *my_pthread_getspecific_imp(pthread_key_t key)
}
#endif
+#ifdef __NETWARE__
+/*
+ Don't kill the LibC Reaper thread or the main thread
+*/
+#include <nks/thread.h>
+#undef pthread_exit
+void my_pthread_exit(void *status)
+{
+ NXThreadId_t tid = NXThreadGetId();
+ NXContext_t ctx;
+ char name[PATH_MAX] = "";
+
+ NXThreadGetContext(tid, &ctx);
+ NXContextGetName(ctx, name, PATH_MAX);
+
+ /*
+ "MYSQLD.NLM's LibC Reaper" or "MYSQLD.NLM's main thread"
+ with a debug build of LibC the reaper can have different names
+ */
+ if (!strindex(name, "\'s"))
+ {
+ pthread_exit(status);
+ }
+}
+#endif
-/* Some functions for RTS threads, AIX, Siemens Unix and UnixWare 7
- (and DEC OSF/1 3.2 too) */
+/*
+ Some functions for RTS threads, AIX, Siemens Unix and UnixWare 7
+ (and DEC OSF/1 3.2 too)
+*/
int my_pthread_create_detached=1;
@@ -394,7 +420,7 @@ int pthread_signal(int sig, void (*func)())
#undef pthread_cond_wait
#undef pthread_cond_timedwait
#undef pthread_cond_t
-
+#undef pthread_attr_getstacksize
/*****************************************************************************
** Patches for AIX and DEC OSF/1 3.2
@@ -437,7 +463,7 @@ int my_pthread_cond_init(pthread_cond_t *mp, const pthread_condattr_t *attr)
this has to be added here.
****************************************************************************/
-#if defined(HPUX) || defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT)
+#if defined(HPUX10) || defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT)
int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec *abstime)
@@ -454,6 +480,15 @@ int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
}
#endif
+#if defined(HPUX10)
+
+void my_pthread_attr_getstacksize(pthread_attr_t *connection_attrib,
+ size_t *stack_size)
+{
+ *stack_size= pthread_attr_getstacksize(*connection_attrib);
+}
+#endif
+
#ifdef HAVE_POSIX1003_4a_MUTEX
/*
diff --git a/mysys/my_quick.c b/mysys/my_quick.c
index 6151d5037ae..44ed3fc0b2c 100644
--- a/mysys/my_quick.c
+++ b/mysys/my_quick.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Quicker interface to read & write. Used with my_nosys.h */
diff --git a/mysys/my_read.c b/mysys/my_read.c
index b317630f4bd..b7621ac99eb 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -1,37 +1,46 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#include <errno.h>
- /* Read a chunk of bytes from a file */
+/*
+ Read a chunk of bytes from a file with retry's if needed
+
+ The parameters are:
+ File descriptor
+ Buffer to hold at least Count bytes
+ Bytes to read
+ Flags on what to do on error
+
+ Return:
+ -1 on error
+ 0 if flag has bits MY_NABP or MY_FNABP set
+ N number of bytes read.
+*/
uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags)
- /* File descriptor */
- /* Buffer must be at least count bytes */
- /* Max number of bytes returnd */
- /* Flags on what to do on error */
{
- uint readbytes;
+ uint readbytes,save_count;
DBUG_ENTER("my_read");
DBUG_PRINT("my",("Fd: %d Buffer: %lx Count: %u MyFlags: %d",
Filedes, Buffer, Count, MyFlags));
+ save_count=Count;
for (;;)
{
@@ -54,12 +63,21 @@ uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags)
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
my_filename(Filedes),my_errno);
}
- if ((int) readbytes == -1 || (MyFlags & (MY_FNABP | MY_NABP)))
+ if ((int) readbytes == -1 ||
+ ((MyFlags & (MY_FNABP | MY_NABP)) && !(MyFlags & MY_FULL_IO)))
DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
+ if (readbytes > 0 && (MyFlags & MY_FULL_IO))
+ {
+ Buffer+=readbytes;
+ Count-=readbytes;
+ continue;
+ }
}
if (MyFlags & (MY_NABP | MY_FNABP))
readbytes=0; /* Ok on read */
+ else if (MyFlags & MY_FULL_IO)
+ readbytes=save_count;
break;
}
DBUG_RETURN(readbytes);
diff --git a/mysys/my_realloc.c b/mysys/my_realloc.c
index 7ab75d47619..49d96c2eb4f 100644
--- a/mysys/my_realloc.c
+++ b/mysys/my_realloc.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef SAFEMALLOC /* We don't need SAFEMALLOC here */
#undef SAFEMALLOC
diff --git a/mysys/my_redel.c b/mysys/my_redel.c
index 16ec77394d2..9ba03cd9526 100644
--- a/mysys/my_redel.c
+++ b/mysys/my_redel.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
@@ -24,7 +23,7 @@
#include <sys/utime.h>
#elif defined(HAVE_UTIME_H)
#include <utime.h>
-#elif !defined(HPUX)
+#elif !defined(HPUX10)
struct utimbuf {
time_t actime;
time_t modtime;
@@ -91,7 +90,7 @@ int my_copystat(const char *from, const char *to, int MyFlags)
return 1;
VOID(chmod(to, statbuf.st_mode & 07777)); /* Copy modes */
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
+#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)
if (statbuf.st_nlink > 1 && MyFlags & MY_LINK_WARNING)
{
if (MyFlags & MY_LINK_WARNING)
diff --git a/mysys/my_rename.c b/mysys/my_rename.c
index 1b7f434e792..d4f99e83247 100644
--- a/mysys/my_rename.c
+++ b/mysys/my_rename.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define USES_TYPES
#include "mysys_priv.h"
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index 7c4da4f6010..ec24a26b3d9 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -1,21 +1,21 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
+#include <assert.h>
/* Seek to position in file */
/*ARGSUSED*/
@@ -26,7 +26,10 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
reg1 os_off_t newpos;
DBUG_ENTER("my_seek");
DBUG_PRINT("my",("Fd: %d Hpos: %lu Pos: %lu Whence: %d MyFlags: %d",
- fd, ((ulonglong) pos) >> 32, (ulong) pos, whence, MyFlags));
+ fd, (ulong) (((ulonglong) pos) >> 32), (ulong) pos,
+ whence, MyFlags));
+ DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */
+
newpos=lseek(fd, pos, whence);
if (newpos == (os_off_t) -1)
{
@@ -34,6 +37,10 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
DBUG_PRINT("error",("lseek: %lu, errno: %d",newpos,errno));
DBUG_RETURN(MY_FILEPOS_ERROR);
}
+ if ((my_off_t) newpos != pos)
+ {
+ DBUG_PRINT("exit",("pos: %lu", (ulong) newpos));
+ }
DBUG_RETURN((my_off_t) newpos);
} /* my_seek */
@@ -53,6 +60,6 @@ my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
#endif
if (pos == (os_off_t) -1)
my_errno=errno;
- DBUG_PRINT("exit",("pos: %lu",pos));
+ DBUG_PRINT("exit",("pos: %lu", (ulong) pos));
DBUG_RETURN((my_off_t) pos);
} /* my_tell */
diff --git a/mysys/my_semaphore.c b/mysys/my_semaphore.c
new file mode 100644
index 00000000000..aa216cbc289
--- /dev/null
+++ b/mysys/my_semaphore.c
@@ -0,0 +1,104 @@
+/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Simple implementation of semaphores, needed to compile MySQL on systems
+ that doesn't support semaphores.
+*/
+
+#include <my_global.h>
+#include <my_semaphore.h>
+#include <errno.h>
+
+#if !defined(__WIN__) && !defined(HAVE_SEMAPHORE_H) && defined(THREAD)
+
+int sem_init(sem_t * sem, int pshared, uint value)
+{
+ sem->count=value;
+ pthread_cond_init(&sem->cond, 0);
+ pthread_mutex_init(&sem->mutex, 0);
+ return 0;
+}
+
+int sem_destroy(sem_t * sem)
+{
+ int err1,err2;
+ err1=pthread_cond_destroy(&sem->cond);
+ err2=pthread_mutex_destroy(&sem->mutex);
+ if (err1 || err2)
+ {
+ errno=err1 ? err1 : err2;
+ return -1;
+ }
+ return 0;
+}
+
+int sem_wait(sem_t * sem)
+{
+ if ((errno=pthread_mutex_lock(&sem->mutex)))
+ return -1;
+ while (!sem->count)
+ pthread_cond_wait(&sem->cond, &sem->mutex);
+ if (errno)
+ return -1;
+ sem->count--; /* mutex is locked here */
+ pthread_mutex_unlock(&sem->mutex);
+ return 0;
+}
+
+int sem_trywait(sem_t * sem)
+{
+ if ((errno=pthread_mutex_lock(&sem->mutex)))
+ return -1;
+ if (sem->count)
+ sem->count--;
+ else
+ errno=EAGAIN;
+ pthread_mutex_unlock(&sem->mutex);
+ return errno ? -1 : 0;
+}
+
+
+int sem_post(sem_t * sem)
+{
+ if ((errno=pthread_mutex_lock(&sem->mutex)))
+ return -1;
+ sem->count++;
+ pthread_mutex_unlock(&sem->mutex); /* does it really matter what to do */
+ pthread_cond_signal(&sem->cond); /* first: x_unlock or x_signal ? */
+ return 0;
+}
+
+int sem_post_multiple(sem_t * sem, uint count)
+{
+ if ((errno=pthread_mutex_lock(&sem->mutex)))
+ return -1;
+ sem->count+=count;
+ pthread_mutex_unlock(&sem->mutex); /* does it really matter what to do */
+ pthread_cond_broadcast(&sem->cond); /* first: x_unlock or x_broadcast ? */
+ return 0;
+}
+
+int sem_getvalue(sem_t * sem, uint *sval)
+{
+ if ((errno=pthread_mutex_lock(&sem->mutex)))
+ return -1;
+ *sval=sem->count;
+ pthread_mutex_unlock(&sem->mutex);
+ return 0;
+}
+
+#endif /* !defined(__WIN__) && !defined(HAVE_SEMAPHORE_H) && defined(THREAD) */
diff --git a/mysys/my_sleep.c b/mysys/my_sleep.c
new file mode 100644
index 00000000000..3de2d2abd13
--- /dev/null
+++ b/mysys/my_sleep.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Wait a given number of microseconds */
+
+#include "mysys_priv.h"
+#include <m_string.h>
+
+void my_sleep(ulong m_seconds)
+{
+#ifdef __NETWARE__
+ delay(m_seconds/1000+1);
+#elif defined(OS2)
+ DosSleep(m_seconds/1000+1);
+#elif defined(HAVE_SELECT)
+ struct timeval t;
+ t.tv_sec= m_seconds / 1000000L;
+ t.tv_usec= m_seconds % 1000000L;
+ select(0,0,0,0,&t); /* sleep */
+#else
+ uint sec= (uint) (m_seconds / 1000000L);
+ ulong start= (ulong) time((time_t*) 0);
+ while ((ulong) time((time_t*) 0) < start+sec);
+#endif
+}
diff --git a/mysys/my_static.c b/mysys/my_static.c
index 72bf7207efa..b24ef28b7b1 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Static variables for mysys library. All definied here for easy making of
@@ -70,19 +69,25 @@ uint sf_malloc_prehunc=0, /* If you have problem with core- */
sf_malloc_endhunc=0, /* dump when malloc-message.... */
/* set theese to 64 or 128 */
sf_malloc_quick=0; /* set if no calls to sanity */
-long lCurMemory = 0L; /* Current memory usage */
-long lMaxMemory = 0L; /* Maximum memory usage */
-uint cNewCount = 0; /* Number of times NEW() was called */
+ulong sf_malloc_cur_memory= 0L; /* Current memory usage */
+ulong sf_malloc_max_memory= 0L; /* Maximum memory usage */
+uint sf_malloc_count= 0; /* Number of times NEW() was called */
byte *sf_min_adress= (byte*) ~(unsigned long) 0L,
*sf_max_adress= (byte*) 0L;
-
-/* Root of the linked list of remembers */
-struct remember *pRememberRoot = NULL;
+/* Root of the linked list of struct st_irem */
+struct st_irem *sf_malloc_root = NULL;
/* from my_alarm */
int volatile my_have_got_alarm=0; /* declare variable to reset */
ulong my_time_to_wait_for_lock=2; /* In seconds */
+ /*
+ We need to have this define here as otherwise linking will fail
+ on OSF1 when compiling --without-raid --with-debug
+ */
+
+const char *raid_type_string[]={"none","striped"};
+
/* from errors.c */
#ifdef SHARED_LIBRARY
char * NEAR globerrs[GLOBERRS]; /* my_error_messages is here */
diff --git a/mysys/my_static.h b/mysys/my_static.h
index e139b0ec127..1a33bcf21f3 100644
--- a/mysys/my_static.h
+++ b/mysys/my_static.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Static variables for mysys library. All definied here for easy making of
@@ -33,20 +32,25 @@ struct st_remember {
sig_handler (*func)(int number);
};
-struct irem {
- struct remember *_pNext; /* Linked list of structures */
- struct remember *_pPrev; /* Other link */
- my_string _sFileName; /* File in which memory was new'ed */
- uint _uLineNum; /* Line number in above file */
- uint _uDataSize; /* Size requested */
- long _lSpecialValue; /* Underrun marker value */
-};
+/*
+ Structure that stores information of a allocated memory block
+ The data is at &struct_adr+sizeof(ALIGN_SIZE(sizeof(struct irem)))
+ The lspecialvalue is at the previous 4 bytes from this, which may not
+ necessarily be in the struct if the struct size isn't aligned at a 8 byte
+ boundary.
+*/
-struct remember {
- struct irem tInt;
- char aData[1];
+struct st_irem
+{
+ struct st_irem *next; /* Linked list of structures */
+ struct st_irem *prev; /* Other link */
+ char *filename; /* File in which memory was new'ed */
+ uint32 linenum; /* Line number in above file */
+ uint32 datasize; /* Size requested */
+ uint32 SpecialValue; /* Underrun marker value */
};
+
extern char NEAR curr_dir[FN_REFLEN],NEAR home_dir_buff[FN_REFLEN];
extern volatile int _my_signals;
@@ -62,8 +66,8 @@ extern int _my_tempnam_used;
#endif
extern byte *sf_min_adress,*sf_max_adress;
-extern uint cNewCount;
-extern struct remember *pRememberRoot;
+extern uint sf_malloc_count;
+extern struct st_irem *sf_malloc_root;
#if defined(THREAD) && !defined(__WIN__)
extern sigset_t my_signals; /* signals blocked by mf_brkhant */
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c
index 65d165fc026..b366678769e 100644
--- a/mysys/my_symlink.c
+++ b/mysys/my_symlink.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
@@ -73,6 +72,7 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags)
#else
int result;
DBUG_ENTER("my_symlink");
+ DBUG_PRINT("enter",("content: %s linkname: %s", content, linkname));
result= 0;
if (symlink(content, linkname))
@@ -104,7 +104,8 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags)
#define BUFF_LEN FN_LEN
#endif
-int my_realpath(char *to, const char *filename, myf MyFlags)
+int my_realpath(char *to, const char *filename,
+ myf MyFlags __attribute__((unused)))
{
#if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH)
int result=0;
@@ -116,11 +117,15 @@ int my_realpath(char *to, const char *filename, myf MyFlags)
(!lstat(filename,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
{
char *ptr;
+ DBUG_PRINT("info",("executing realpath"));
if ((ptr=realpath(filename,buff)))
+ {
strmake(to,ptr,FN_REFLEN-1);
+ }
else
{
/* Realpath didn't work; Use original name */
+ DBUG_PRINT("error",("realpath failed with errno: %d", errno));
my_errno=errno;
if (MyFlags & MY_WME)
my_error(EE_REALPATH, MYF(0), filename, my_errno);
diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c
index f1e90abaa9b..913f632fbb4 100644
--- a/mysys/my_symlink2.c
+++ b/mysys/my_symlink2.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Advanced symlink handling.
@@ -23,6 +22,7 @@
*/
#include "mysys_priv.h"
+#include "mysys_err.h"
#include <m_string.h>
File my_create_with_symlink(const char *linkname, const char *filename,
@@ -30,11 +30,37 @@ File my_create_with_symlink(const char *linkname, const char *filename,
{
File file;
int tmp_errno;
+ /* Test if we should create a link */
+ int create_link;
DBUG_ENTER("my_create_with_symlink");
+
+ if (my_disable_symlinks)
+ {
+ /* Create only the file, not the link and file */
+ create_link= 0;
+ if (linkname)
+ filename= linkname;
+ }
+ else
+ create_link= (linkname && strcmp(linkname,filename));
+
+ if (!(MyFlags & MY_DELETE_OLD))
+ {
+ if (!access(filename,F_OK))
+ {
+ my_error(EE_CANTCREATEFILE, MYF(0), filename, EEXIST);
+ DBUG_RETURN(-1);
+ }
+ if (create_link && !access(linkname,F_OK))
+ {
+ my_error(EE_CANTCREATEFILE, MYF(0), linkname, EEXIST);
+ DBUG_RETURN(-1);
+ }
+ }
+
if ((file=my_create(filename, createflags, access_flags, MyFlags)) >= 0)
{
- /* Test if we should create a link */
- if (linkname && strcmp(linkname,filename))
+ if (create_link)
{
/* Delete old link/file */
if (MyFlags & MY_DELETE_OLD)
diff --git a/mysys/my_sync.c b/mysys/my_sync.c
new file mode 100644
index 00000000000..317ca039346
--- /dev/null
+++ b/mysys/my_sync.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mysys_priv.h"
+#include "mysys_err.h"
+#include <errno.h>
+
+/*
+ Sync data in file to disk
+
+ SYNOPSIS
+ my_sync()
+ fd File descritor to sync
+ my_flags Flags (now only MY_WME is supported)
+
+ NOTE
+ If file system supports its, only file data is synced, not inode date
+
+ RETURN
+ 0 ok
+ -1 error
+*/
+
+int my_sync(File fd, myf my_flags)
+{
+ int res;
+ DBUG_ENTER("my_sync");
+ DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags));
+
+#if defined(HAVE_FDATASYNC)
+ res= fdatasync(fd);
+#elif defined(HAVE_FSYNC)
+ res=fsync(fd);
+#elif defined(__WIN__)
+ res= _commit(fd);
+#else
+ res= 0; /* No sync (strange OS) */
+#endif
+ if (res)
+ {
+ if (!(my_errno= errno))
+ my_errno= -1; /* Unknown error */
+ if (my_flags & MY_WME)
+ my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), my_filename(fd), my_errno);
+ }
+ DBUG_RETURN(res);
+} /* my_read */
diff --git a/mysys/my_tempnam.c b/mysys/my_tempnam.c
index d4979fcaa6e..d079b9f66a5 100644
--- a/mysys/my_tempnam.c
+++ b/mysys/my_tempnam.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
This function is only used by some old ISAM code.
@@ -39,7 +38,7 @@
#endif
#ifdef HAVE_TEMPNAM
-#if !defined( MSDOS) && !defined(OS2)
+#if !defined( MSDOS) && !defined(OS2) && !defined(__NETWARE__)
extern char **environ;
#endif
#endif
@@ -105,24 +104,30 @@ my_string my_tempnam(const char *dir, const char *pfx,
dir=temp;
}
#ifdef OS2
- // changing environ variable doesn't work with VACPP
+ /* changing environ variable doesn't work with VACPP */
char buffer[256];
sprintf( buffer, "TMP=%s", dir);
- // remove ending backslash
+ /* remove ending backslash */
if (buffer[strlen(buffer)-1] == '\\')
buffer[strlen(buffer)-1] = '\0';
putenv( buffer);
-#else
+#elif !defined(__NETWARE__)
old_env=(char**)environ;
if (dir)
{ /* Don't use TMPDIR if dir is given */
- environ=(const char**)temp_env; /* May give warning */
+ /*
+ The following strange cast is required because the IBM compiler on AIX
+ doesn't allow us to cast the value of environ.
+ The cast of environ is needed as some systems doesn't allow us to
+ update environ with a char ** pointer. (const mismatch)
+ */
+ (*(char***) &environ)=(char**) temp_env;
temp_env[0]=0;
}
#endif
res=tempnam((char*) dir,(my_string) pfx); /* Use stand. dir with prefix */
-#ifndef OS2
- environ=(const char**)old_env; /* May give warning */
+#if !defined(OS2) && !defined(__NETWARE__)
+ (*(char***) &environ)=(char**) old_env;
#endif
if (!res)
DBUG_PRINT("error",("Got error: %d from tempnam",errno));
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 2782576d8cd..878a861bc94 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
-** Functions to handle initializating and allocationg of all mysys & debug
-** thread variables.
+ Functions to handle initializating and allocationg of all mysys & debug
+ thread variables.
*/
#include "mysys_priv.h"
@@ -45,22 +44,29 @@ pthread_mutexattr_t my_fast_mutexattr;
pthread_mutexattr_t my_errchk_mutexattr;
#endif
-/* FIXME Note. TlsAlloc does not set an auto destructor, so
- the function my_thread_global_free must be called from
- somewhere before final exit of the library */
+/*
+ initialize thread environment
+
+ SYNOPSIS
+ my_thread_global_init()
+
+ RETURN
+ 0 ok
+ 1 error (Couldn't create THR_KEY_mysys)
+*/
my_bool my_thread_global_init(void)
{
- if (pthread_key_create(&THR_KEY_mysys,free))
+ if (pthread_key_create(&THR_KEY_mysys,0))
{
fprintf(stderr,"Can't initialize threads: error %d\n",errno);
- exit(1);
+ return 1;
}
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
pthread_mutexattr_init(&my_fast_mutexattr);
pthread_mutexattr_setkind_np(&my_fast_mutexattr,PTHREAD_MUTEX_ADAPTIVE_NP);
#endif
-#ifdef PPTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
pthread_mutexattr_init(&my_errchk_mutexattr);
pthread_mutexattr_setkind_np(&my_errchk_mutexattr,
PTHREAD_MUTEX_ERRORCHECK_NP);
@@ -84,20 +90,36 @@ my_bool my_thread_global_init(void)
#ifndef HAVE_GETHOSTBYNAME_R
pthread_mutex_init(&LOCK_gethostbyname_r,MY_MUTEX_INIT_SLOW);
#endif
- return my_thread_init();
+ if (my_thread_init())
+ {
+ my_thread_global_end(); /* Clean up */
+ return 1;
+ }
+ return 0;
}
+
void my_thread_global_end(void)
{
-#if defined(USE_TLS)
- (void) TlsFree(THR_KEY_mysys);
-#endif
+ pthread_key_delete(THR_KEY_mysys);
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
pthread_mutexattr_destroy(&my_fast_mutexattr);
#endif
-#ifdef PPTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
pthread_mutexattr_destroy(&my_errchk_mutexattr);
#endif
+ pthread_mutex_destroy(&THR_LOCK_malloc);
+ pthread_mutex_destroy(&THR_LOCK_open);
+ pthread_mutex_destroy(&THR_LOCK_keycache);
+ pthread_mutex_destroy(&THR_LOCK_lock);
+ pthread_mutex_destroy(&THR_LOCK_isam);
+ pthread_mutex_destroy(&THR_LOCK_myisam);
+ pthread_mutex_destroy(&THR_LOCK_heap);
+ pthread_mutex_destroy(&THR_LOCK_net);
+ pthread_mutex_destroy(&THR_LOCK_charset);
+#ifndef HAVE_LOCALTIME_R
+ pthread_mutex_destroy(&LOCK_localtime_r);
+#endif
#ifndef HAVE_GETHOSTBYNAME_R
pthread_mutex_destroy(&LOCK_gethostbyname_r);
#endif
@@ -115,50 +137,68 @@ static long thread_id=0;
my_bool my_thread_init(void)
{
struct st_my_thread_var *tmp;
+ my_bool error=0;
+
+#ifdef EXTRA_DEBUG_THREADS
+ fprintf(stderr,"my_thread_init(): thread_id=%ld\n",pthread_self());
+#endif
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
pthread_mutex_lock(&THR_LOCK_lock);
#endif
+
#if !defined(__WIN__) || defined(USE_TLS)
if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
{
- pthread_mutex_unlock(&THR_LOCK_lock);
- return 0; /* Safequard */
+#ifdef EXTRA_DEBUG_THREADS
+ fprintf(stderr,"my_thread_init() called more than once in thread %ld\n",
+ pthread_self());
+#endif
+ goto end;
}
- /* We must have many calloc() here because these are freed on
- pthread_exit */
- if (!(tmp=(struct st_my_thread_var *)
- calloc(1,sizeof(struct st_my_thread_var))))
+ if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
{
- pthread_mutex_unlock(&THR_LOCK_lock);
- return 1;
+ error= 1;
+ goto end;
}
pthread_setspecific(THR_KEY_mysys,tmp);
#else
- if (THR_KEY_mysys.id) /* Already initialized */
- {
-#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
- pthread_mutex_unlock(&THR_LOCK_lock);
-#endif
- return 0;
- }
+ /*
+ Skip initialization if the thread specific variable is already initialized
+ */
+ if (THR_KEY_mysys.id)
+ goto end;
tmp= &THR_KEY_mysys;
#endif
tmp->id= ++thread_id;
+#if defined(__WIN__) && defined(EMBEDDED_LIBRARY)
+ tmp->thread_self= (pthread_t)getpid();
+#endif
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
pthread_cond_init(&tmp->suspend, NULL);
+ tmp->init= 1;
+
+end:
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
pthread_mutex_unlock(&THR_LOCK_lock);
#endif
- return 0;
+ return error;
}
+
void my_thread_end(void)
{
- struct st_my_thread_var *tmp=my_thread_var;
- if (tmp)
+ struct st_my_thread_var *tmp;
+ tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
+
+#ifdef EXTRA_DEBUG_THREADS
+ fprintf(stderr,"my_thread_end(): tmp=%p,thread_id=%ld\n",
+ tmp,pthread_self());
+#endif
+ if (tmp && tmp->init)
{
#if !defined(DBUG_OFF)
+ /* tmp->dbug is allocated inside DBUG library */
if (tmp->dbug)
{
free(tmp->dbug);
@@ -171,8 +211,11 @@ void my_thread_end(void)
pthread_mutex_destroy(&tmp->mutex);
#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
free(tmp);
+#else
+ tmp->init= 0;
#endif
}
+ /* The following free has to be done, even if my_thread_var() is 0 */
#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
pthread_setspecific(THR_KEY_mysys,0);
#endif
@@ -193,8 +236,9 @@ struct st_my_thread_var *_my_thread_var(void)
return tmp;
}
+
/****************************************************************************
-** Get name of current thread.
+ Get name of current thread.
****************************************************************************/
#define UNKNOWN_THREAD -1
diff --git a/mysys/my_vsnprintf.c b/mysys/my_vsnprintf.c
index 9bc33e28ba1..e49b1d0e729 100644
--- a/mysys/my_vsnprintf.c
+++ b/mysys/my_vsnprintf.c
@@ -1,26 +1,25 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#include <m_string.h>
#include <stdarg.h>
#include <m_ctype.h>
-
+#include <assert.h>
int my_snprintf(char* to, size_t n, const char* fmt, ...)
{
@@ -45,7 +44,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
*to++= *fmt; /* Copy ordinary char */
continue;
}
- /* Skipp if max size is used (to be compatible with printf) */
+ /* Skip if max size is used (to be compatible with printf) */
fmt++;
while (isdigit(*fmt) || *fmt == '.' || *fmt == '-')
fmt++;
@@ -54,14 +53,13 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
if (*fmt == 's') /* String parameter */
{
reg2 char *par = va_arg(ap, char *);
- uint plen;
+ uint plen,left_len = (uint)(end-to);
if (!par) par = (char*)"(null)";
plen = (uint) strlen(par);
- if ((uint) (end-to) > plen) /* Replace if possible */
- {
- to=strmov(to,par);
- continue;
- }
+ if (left_len <= plen)
+ plen = left_len - 1;
+ to=strnmov(to,par,plen);
+ continue;
}
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
{
@@ -80,28 +78,36 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
break;
*to++='%'; /* % used as % or unknown code */
}
+ DBUG_ASSERT(to <= end);
*to='\0'; /* End of errmessage */
return (uint) (to - start);
}
#ifdef MAIN
+#define OVERRUN_SENTRY 250
static void my_printf(const char * fmt, ...)
{
- char buf[32];
+ char buf[33];
int n;
va_list ar;
va_start(ar, fmt);
- n = my_vsnprintf(buf, sizeof(buf),fmt, ar);
+ buf[sizeof(buf)-1]=OVERRUN_SENTRY;
+ n = my_vsnprintf(buf, sizeof(buf)-1,fmt, ar);
printf(buf);
printf("n=%d, strlen=%d\n", n, strlen(buf));
+ if (buf[sizeof(buf)-1] != OVERRUN_SENTRY)
+ {
+ fprintf(stderr, "Buffer overrun\n");
+ abort();
+ }
va_end(ar);
}
int main()
{
-
+
my_printf("Hello\n");
my_printf("Hello int, %d\n", 1);
my_printf("Hello string '%s'\n", "I am a string");
@@ -116,4 +122,3 @@ int main()
return 0;
}
#endif
-
diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c
index 0c5b01f90d8..8c497e8f250 100644
--- a/mysys/my_wincond.c
+++ b/mysys/my_wincond.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*****************************************************************************
** The following is a simple implementation of posix conditions
diff --git a/mysys/my_winsem.c b/mysys/my_winsem.c
new file mode 100644
index 00000000000..e2713d189b2
--- /dev/null
+++ b/mysys/my_winsem.c
@@ -0,0 +1,406 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: my_semaphore.c (Original: semaphore.c from pthreads library)
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA
+ */
+
+/*
+ NEED_SEM is not used in MySQL and should only be needed under
+ Windows CE.
+
+ The big changes compared to the original version was to not allocate
+ any additional memory in sem_init() but to instead store everthing
+ we need in sem_t.
+
+ TODO:
+ To get HAVE_CREATESEMAPHORE we have to define the struct
+ in my_semaphore.h
+*/
+
+#include "mysys_priv.h"
+#ifdef __WIN__
+#include "my_semaphore.h"
+#include <errno.h>
+
+/*
+ DOCPUBLIC
+ This function initializes an unnamed semaphore. the
+ initial value of the semaphore is 'value'
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+
+ pshared If zero, this semaphore may only be shared between
+ threads in the same process.
+ If nonzero, the semaphore can be shared between
+ processes
+
+ value Initial value of the semaphore counter
+
+ RESULTS
+ 0 Successfully created semaphore,
+ -1 Failed, error in errno
+
+ ERRNO
+ EINVAL 'sem' is not a valid semaphore,
+ ENOSPC A required resource has been exhausted,
+ ENOSYS Semaphores are not supported,
+ EPERM The process lacks appropriate privilege
+
+*/
+
+int
+sem_init (sem_t *sem, int pshared, unsigned int value)
+{
+ int result = 0;
+
+ if (pshared != 0)
+ {
+ /*
+ We don't support creating a semaphore that can be shared between
+ processes
+ */
+ result = EPERM;
+ }
+ else
+ {
+#ifndef HAVE_CREATESEMAPHORE
+ sem->value = value;
+ sem->event = CreateEvent(NULL,
+ FALSE, /* manual reset */
+ FALSE, /* initial state */
+ NULL);
+ if (!sem->event)
+ result = ENOSPC;
+ else
+ {
+ if (value)
+ SetEvent(sem->event);
+ InitializeCriticalSection(&sem->sem_lock_cs);
+ }
+#else /* HAVE_CREATESEMAPHORE */
+ *sem = CreateSemaphore (NULL, /* Always NULL */
+ value, /* Initial value */
+ 0x7FFFFFFFL, /* Maximum value */
+ NULL); /* Name */
+ if (!*sem)
+ result = ENOSPC;
+#endif /* HAVE_CREATESEMAPHORE */
+ }
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+ return 0;
+} /* sem_init */
+
+
+/*
+ DOCPUBLIC
+ This function destroys an unnamed semaphore.
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+
+ RESULTS
+ 0 Successfully destroyed semaphore,
+ -1 Failed, error in errno
+ ERRNO
+ EINVAL 'sem' is not a valid semaphore,
+ ENOSYS Semaphores are not supported,
+ EBUSY Threads (or processes) are currently blocked on 'sem'
+*/
+
+int
+sem_destroy (sem_t * sem)
+{
+ int result = 0;
+
+#ifdef EXTRA_DEBUG
+ if (sem == NULL || *sem == NULL)
+ {
+ errno=EINVAL;
+ return;
+ }
+#endif /* EXTRA_DEBUG */
+
+#ifndef HAVE_CREATESEMAPHORE
+ if (! CloseHandle(sem->event))
+ result = EINVAL;
+ else
+ DeleteCriticalSection(&sem->sem_lock_cs);
+#else /* HAVE_CREATESEMAPHORE */
+ if (!CloseHandle(*sem))
+ result = EINVAL;
+#endif /* HAVE_CREATESEMAPHORE */
+ if (result)
+ {
+ errno = result;
+ return -1;
+ }
+ *sem=0; /* Safety */
+ return 0;
+} /* sem_destroy */
+
+
+/*
+ DOCPUBLIC
+ This function tries to wait on a semaphore. If the
+ semaphore value is greater than zero, it decreases
+ its value by one. If the semaphore value is zero, then
+ this function returns immediately with the error EAGAIN
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+
+ RESULTS
+ 0 Successfully decreased semaphore,
+ -1 Failed, error in errno
+
+ ERRNO
+ EAGAIN The semaphore was already locked,
+ EINVAL 'sem' is not a valid semaphore,
+ ENOSYS Semaphores are not supported,
+ EINTR The function was interrupted by a signal,
+ EDEADLK A deadlock condition was detected.
+*/
+
+int
+sem_trywait(sem_t * sem)
+{
+#ifndef HAVE_CREATESEMAPHORE
+ /* not yet implemented! */
+ int errno = EINVAL;
+ return -1;
+#else /* HAVE_CREATESEMAPHORE */
+#ifdef EXTRA_DEBUG
+ if (sem == NULL || *sem == NULL)
+ {
+ errno=EINVAL;
+ return -1;
+ }
+#endif /* EXTRA_DEBUG */
+ if (WaitForSingleObject (*sem, 0) == WAIT_TIMEOUT)
+ {
+ errno= EAGAIN;
+ return -1;
+ }
+ return 0;
+#endif /* HAVE_CREATESEMAPHORE */
+
+} /* sem_trywait */
+
+
+#ifndef HAVE_CREATESEMAPHORE
+
+static void
+ptw32_decrease_semaphore(sem_t * sem)
+{
+ EnterCriticalSection(&sem->sem_lock_cs);
+ DBUG_ASSERT(sem->value != 0);
+ sem->value--;
+ if (sem->value != 0)
+ SetEvent(sem->event);
+ LeaveCriticalSection(&sem->sem_lock_cs);
+}
+
+static BOOL
+ptw32_increase_semaphore(sem_t * sem, unsigned int n)
+{
+ BOOL result=FALSE;
+
+ EnterCriticalSection(&sem->sem_lock_cs);
+ if (sem->value + n > sem->value)
+ {
+ sem->value += n;
+ SetEvent(sem->event);
+ result = TRUE;
+ }
+ LeaveCriticalSection(&sem->sem_lock_cs);
+ return result;
+}
+
+#endif /* HAVE_CREATESEMAPHORE */
+
+
+/*
+ ------------------------------------------------------
+ DOCPUBLIC
+ This function waits on a semaphore. If the
+ semaphore value is greater than zero, it decreases
+ its value by one. If the semaphore value is zero, then
+ the calling thread (or process) is blocked until it can
+ successfully decrease the value or until interrupted by
+ a signal.
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+
+ RESULTS
+ 0 Successfully decreased semaphore,
+ -1 Failed, error in errno
+
+ ERRNO
+ EINVAL 'Sem' is not a valid semaphore,
+ ENOSYS Semaphores are not supported,
+ EINTR The function was interrupted by a signal,
+ EDEADLK A deadlock condition was detected.
+*/
+
+int
+sem_wait(sem_t *sem)
+{
+ int result;
+
+#ifdef EXTRA_DEBUG
+ if (sem == NULL || *sem == NULL)
+ {
+ errno=EINVAL;
+ return -1;
+ }
+#endif /* EXTRA_DEBUG */
+
+#ifndef HAVE_CREATESEMAPHORE
+ result=WaitForSingleObject(sem->event, INFINITE);
+#else
+ result=WaitForSingleObject(*sem, INFINITE);
+#endif
+ if (result == WAIT_FAILED || result == WAIT_ABANDONED_0)
+ result = EINVAL;
+ else if (result == WAIT_TIMEOUT)
+ result = ETIMEDOUT;
+ else
+ result=0;
+ if (result)
+ {
+ errno = result;
+ return -1;
+ }
+#ifndef HAVE_CREATESEMAPHORE
+ ptw32_decrease_semaphore(sem);
+#endif /* HAVE_CREATESEMAPHORE */
+ return 0;
+}
+
+
+/*
+ ------------------------------------------------------
+ DOCPUBLIC
+ This function posts a wakeup to a semaphore. If there
+ are waiting threads (or processes), one is awakened;
+ otherwise, the semaphore value is incremented by one.
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+
+ RESULTS
+ 0 Successfully posted semaphore,
+ -1 Failed, error in errno
+
+ ERRNO
+ EINVAL 'sem' is not a valid semaphore,
+ ENOSYS Semaphores are not supported,
+
+*/
+
+int
+sem_post (sem_t * sem)
+{
+#ifdef EXTRA_DEBUG
+ if (sem == NULL || *sem == NULL)
+ {
+ errno=EINVAL;
+ return -1;
+ }
+#endif /* EXTRA_DEBUG */
+
+#ifndef HAVE_CREATESEMAPHORE
+ if (! ptw32_increase_semaphore(sem, 1))
+#else /* HAVE_CREATESEMAPHORE */
+ if (! ReleaseSemaphore(*sem, 1, 0))
+#endif /* HAVE_CREATESEMAPHORE */
+ {
+ errno=EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ ------------------------------------------------------
+ DOCPUBLIC
+ This function posts multiple wakeups to a semaphore. If there
+ are waiting threads (or processes), n <= count are awakened;
+ the semaphore value is incremented by count - n.
+
+ PARAMETERS
+ sem Pointer to an instance of sem_t
+ count Counter, must be greater than zero.
+
+ RESULTS
+ 0 Successfully posted semaphore,
+ -1 Failed, error in errno
+
+ ERRNO
+ EINVAL 'sem' is not a valid semaphore or count is less
+ than or equal to zero.
+*/
+
+int
+sem_post_multiple (sem_t * sem, unsigned int count)
+{
+#ifdef EXTRA_DEBUG
+ if (sem == NULL || *sem == NULL || count <= 0)
+ {
+ errno=EINVAL;
+ return -1;
+ }
+#endif /* EXTRA_DEBUG */
+#ifndef HAVE_CREATESEMAPHORE
+ if (! ptw32_increase_semaphore (sem, count))
+#else /* HAVE_CREATESEMAPHORE */
+ if (! ReleaseSemaphore(*sem, count, 0))
+#endif /* HAVE_CREATESEMAPHORE */
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
+int
+sem_getvalue (sem_t *sem, unsigned int *sval)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_getvalue */
+
+#endif /* __WIN__ */
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c
index a77167c23e4..eebc07df180 100644
--- a/mysys/my_winthread.c
+++ b/mysys/my_winthread.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*****************************************************************************
** Simulation of posix threads calls for WIN95 and NT
diff --git a/mysys/my_write.c b/mysys/my_write.c
index 5d5a48a3dda..61fd6097e28 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 2049347cb36..f79431a0b0b 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -1,21 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#ifdef USE_SYSTEM_WRAPPERS
@@ -24,9 +23,9 @@
#ifdef THREAD
#include <my_pthread.h>
-extern pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
- THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_net,THR_LOCK_charset;
-extern pthread_mutex_t LOCK_bitmap;
+extern pthread_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache;
+extern pthread_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net;
+extern pthread_mutex_t THR_LOCK_charset;
#else
#include <my_no_pthread.h>
#endif
diff --git a/mysys/ptr_cmp.c b/mysys/ptr_cmp.c
index 65b2c51aafd..5fc7ccab4fa 100644
--- a/mysys/ptr_cmp.c
+++ b/mysys/ptr_cmp.c
@@ -1,27 +1,23 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
get_ptr_compare(len) returns a pointer to a optimal byte-compare function
for a array of stringpointer where all strings have size len.
The bytes are compare as unsigned chars.
- Because the size is saved in a static variable.
- When using threads the program must have called my_init and the thread
- my_init_thread()
*/
#include "mysys_priv.h"
diff --git a/mysys/queues.c b/mysys/queues.c
index 1c7a1a4a618..93d4c303f22 100644
--- a/mysys/queues.c
+++ b/mysys/queues.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Code for generell handling of priority Queues.
@@ -45,28 +44,58 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
}
/*
- Reinitialize queue for new usage; Note that you can't currently resize
- the number of elements! If you need this, fix it :)
+ Reinitialize queue for new usage;
*/
-
int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
pbool max_at_top, int (*compare) (void *, byte *, byte *),
void *first_cmp_arg)
{
DBUG_ENTER("reinit_queue");
- if (queue->max_elements < max_elements)
- /* It's real easy to do realloc here, just don't want to bother */
- DBUG_RETURN(my_errno=EE_OUTOFMEMORY);
-
queue->elements=0;
queue->compare=compare;
queue->first_cmp_arg=first_cmp_arg;
queue->offset_to_key=offset_to_key;
queue->max_at_top= max_at_top ? (-1 ^ 1) : 0;
+ resize_queue(queue, max_elements);
DBUG_RETURN(0);
}
+
+/*
+ Resize queue
+
+ SYNOPSIS
+ resize_queue()
+ queue Queue
+ max_elements New max size for queue
+
+ NOTES
+ If you resize queue to be less than the elements you have in it,
+ the extra elements will be deleted
+
+ RETURN
+ 0 ok
+ 1 Error. In this case the queue is unchanged
+*/
+
+int resize_queue(QUEUE *queue, uint max_elements)
+{
+ byte **new_root;
+ DBUG_ENTER("resize_queue");
+ if (queue->max_elements == max_elements)
+ DBUG_RETURN(0);
+ if ((new_root= (byte **) my_realloc((void *)queue->root,
+ (max_elements+1)*sizeof(void*),
+ MYF(MY_WME))) == 0)
+ DBUG_RETURN(1);
+ set_if_smaller(queue->elements, max_elements);
+ queue->max_elements= max_elements;
+ queue->root= new_root;
+ DBUG_RETURN(0);
+}
+
+
void delete_queue(QUEUE *queue)
{
DBUG_ENTER("delete_queue");
@@ -124,7 +153,6 @@ byte *queue_remove(register QUEUE *queue, uint idx)
}
}
-
/* Fix when element on top has been replaced */
#ifndef queue_replaced
@@ -166,3 +194,22 @@ void _downheap(register QUEUE *queue, uint idx)
}
queue->root[idx]=element;
}
+
+
+static int queue_fix_cmp(QUEUE *queue, void **a, void **b)
+{
+ return queue->compare(queue->first_cmp_arg,
+ (char*) (*a)+queue->offset_to_key,
+ (char*) (*b)+queue->offset_to_key);
+}
+
+/*
+ Fix heap when every element was changed,
+ actually, it can be done better, in linear time, not in n*log(n)
+*/
+
+void queue_fix(QUEUE *queue)
+{
+ qsort2(queue->root+1,queue->elements, sizeof(void *),
+ (qsort2_cmp)queue_fix_cmp, queue);
+}
diff --git a/mysys/raid.cc b/mysys/raid.cc
index 47326f29f60..0b688464fb3 100644
--- a/mysys/raid.cc
+++ b/mysys/raid.cc
@@ -1,82 +1,81 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* --------------------------------------------------------*
-*
-* RAID support for MySQL. Raid 0 (stiping) only implemented yet.
-*
-* Why RAID? Why it must be in MySQL?
-*
-* This is because then you can:
-* 1. Have bigger tables than your OS limit. In time of writing this
-* we are hitting to 2GB limit under linux/ext2
-* 2. You can get more speed from IO bottleneck by putting
-* Raid dirs on different physical disks.
-* 3. Getting more fault tolerance (not implemented yet)
-*
-* Why not to use RAID:
-*
-* 1. You are losing some processor power to calculate things,
-* do more syscalls and interrupts.
-*
-* Functionality is supplied by two classes: RaidFd and RaidName.
-* RaidFd supports funtionality over file descriptors like
-* open/create/write/seek/close. RaidName supports functionality
-* like rename/delete where we have no relations to filedescriptors.
-* RaidName can be prorably unchanged for different Raid levels. RaidFd
-* have to be virtual I think ;).
-* You can speed up some calls in MySQL code by skipping RAID code.
-* For example LOAD DATA INFILE never needs to read RAID-ed files.
-* This can be done adding proper "#undef my_read" or similar undef-s
-* in your code. Check out the raid.h!
-*
-* Some explanation about _seek_vector[]
-* This is seek cache. RAID seeks too much and we cacheing this. We
-* fool it and just storing new position in file to _seek_vector.
-* When there is no seeks to do, we are putting RAID_SEEK_DONE into it.
-* Any other value requires seeking to that position.
-*
-* TODO:
-*
-*
-* - Implement other fancy things like RAID 1 (mirroring) and RAID 5.
-* Should not to be very complex.
-*
-* - Optimize big blob writes by resorting write buffers and writing
-* big chunks at once instead of doing many syscalls. - after thinking I
-* found this is useless. This is because same thing one can do with just
-* increasing RAID_CHUNKSIZE. Monty, what do you think? tonu.
-*
-* - If needed, then implement missing syscalls. One known to miss is stat();
-*
-* - Make and use a thread safe dynamic_array buffer. The used one
-* will not work if needs to be extended at the same time someone is
-* accessing it.
-*
-*
-* tonu@mysql.com & monty@mysql.com
-* --------------------------------------------------------*/
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+
+ RAID support for MySQL. Raid 0 (stiping) only implemented yet.
+
+ Why RAID? Why it must be in MySQL?
+
+ This is because then you can:
+ 1. Have bigger tables than your OS limit. In time of writing this
+ we are hitting to 2GB limit under linux/ext2
+ 2. You can get more speed from IO bottleneck by putting
+ Raid dirs on different physical disks.
+ 3. Getting more fault tolerance (not implemented yet)
+
+ Why not to use RAID:
+
+ 1. You are losing some processor power to calculate things,
+ do more syscalls and interrupts.
+
+ Functionality is supplied by two classes: RaidFd and RaidName.
+ RaidFd supports funtionality over file descriptors like
+ open/create/write/seek/close. RaidName supports functionality
+ like rename/delete where we have no relations to filedescriptors.
+ RaidName can be prorably unchanged for different Raid levels. RaidFd
+ have to be virtual I think ;).
+ You can speed up some calls in MySQL code by skipping RAID code.
+ For example LOAD DATA INFILE never needs to read RAID-ed files.
+ This can be done adding proper "#undef my_read" or similar undef-s
+ in your code. Check out the raid.h!
+
+ Some explanation about _seek_vector[]
+ This is seek cache. RAID seeks too much and we cacheing this. We
+ fool it and just storing new position in file to _seek_vector.
+ When there is no seeks to do, we are putting RAID_SEEK_DONE into it.
+ Any other value requires seeking to that position.
+
+ TODO:
+
+
+ - Implement other fancy things like RAID 1 (mirroring) and RAID 5.
+ Should not to be very complex.
+
+ - Optimize big blob writes by resorting write buffers and writing
+ big chunks at once instead of doing many syscalls. - after thinking I
+ found this is useless. This is because same thing one can do with just
+ increasing RAID_CHUNKSIZE. Monty, what do you think? tonu.
+
+ - If needed, then implement missing syscalls. One known to miss is stat();
+
+ - Make and use a thread safe dynamic_array buffer. The used one
+ will not work if needs to be extended at the same time someone is
+ accessing it.
+
+
+ tonu@mysql.com & monty@mysql.com
+*/
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
#include "mysys_priv.h"
-#include "my_dir.h"
+#include <my_dir.h>
#include <m_string.h>
#include <assert.h>
@@ -158,10 +157,10 @@ extern "C" {
DBUG_PRINT("enter",("Fd: %d pos: %lu whence: %d MyFlags: %d",
fd, (ulong) pos, whence, MyFlags));
- assert(pos != MY_FILEPOS_ERROR);
-
if (is_raid(fd))
{
+ assert(pos != MY_FILEPOS_ERROR);
+
RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
DBUG_RETURN(raid->Seek(pos,whence,MyFlags));
}
@@ -282,7 +281,7 @@ extern "C" {
DBUG_RETURN(my_close(fd, MyFlags));
}
- int my_raid_chsize(File fd, my_off_t newlength, myf MyFlags)
+ int my_raid_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
{
DBUG_ENTER("my_raid_chsize");
DBUG_PRINT("enter",("Fd: %d newlength: %u MyFlags: %d",
@@ -290,10 +289,10 @@ extern "C" {
if (is_raid(fd))
{
RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
- DBUG_RETURN(raid->Chsize(fd, newlength, MyFlags));
+ DBUG_RETURN(raid->Chsize(fd, newlength, filler, MyFlags));
}
else
- DBUG_RETURN(my_chsize(fd, newlength, MyFlags));
+ DBUG_RETURN(my_chsize(fd, newlength, filler, MyFlags));
}
int my_raid_rename(const char *from, const char *to,
@@ -410,8 +409,8 @@ IsRaid(File fd)
RaidFd::
RaidFd(uint raid_type, uint raid_chunks, ulong raid_chunksize)
:_raid_type(raid_type), _raid_chunks(raid_chunks),
- _raid_chunksize(raid_chunksize), _position(0), _fd_vector(0),
- _size(RAID_SIZE_UNKNOWN)
+ _raid_chunksize(raid_chunksize), _position(0), _size(RAID_SIZE_UNKNOWN),
+ _fd_vector(0)
{
DBUG_ENTER("RaidFd::RaidFd");
DBUG_PRINT("enter",("RaidFd_type: %u Disks: %u Chunksize: %d",
@@ -739,7 +738,7 @@ Tell(myf MyFlags)
}
int RaidFd::
-Chsize(File fd, my_off_t newlength, myf MyFlags)
+Chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
{
DBUG_ENTER("RaidFd::Chsize");
DBUG_PRINT("enter",("Fd: %d, newlength: %d, MyFlags: %d",
@@ -753,17 +752,16 @@ Chsize(File fd, my_off_t newlength, myf MyFlags)
if ( i < _this_block )
newpos = my_chsize(_fd_vector[i],
_this_block * _raid_chunksize + (_rounds + 1) *
- _raid_chunksize,
- MyFlags);
+ _raid_chunksize, filler, MyFlags);
else if ( i == _this_block )
newpos = my_chsize(_fd_vector[i],
_this_block * _raid_chunksize + _rounds *
_raid_chunksize + (newlength % _raid_chunksize),
- MyFlags);
+ filler, MyFlags);
else // this means: i > _this_block
newpos = my_chsize(_fd_vector[i],
_this_block * _raid_chunksize + _rounds *
- _raid_chunksize, MyFlags);
+ _raid_chunksize, filler, MyFlags);
if (newpos)
DBUG_RETURN(1);
}
diff --git a/mysys/rijndael.c b/mysys/rijndael.c
new file mode 100644
index 00000000000..dd0c45445d5
--- /dev/null
+++ b/mysys/rijndael.c
@@ -0,0 +1,1397 @@
+/* Copyright (C) 2002 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ Based on version 3.0 (December 2000)
+
+ Optimised ANSI C code for the Rijndael cipher (now AES)
+
+ author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ author Paulo Barreto <paulo.barreto@terra.com.br>
+*/
+
+#include <my_global.h>
+#include <assert.h>
+#include "rijndael.h"
+
+/*
+ Define the following to use fastest and much larger code (~10K extra code)
+ #define FULL_UNROLL
+*/
+
+
+#ifdef NOT_USED
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+#endif
+
+
+static const uint32 Te0[256]=
+{
+ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+
+static const uint32 Te1[256]=
+{
+ 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+ 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+ 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+ 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+ 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+ 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+ 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+ 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+ 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+ 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+ 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+ 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+ 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+ 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+ 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+ 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+ 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+ 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+ 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+ 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+ 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+ 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+ 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+ 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+ 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+ 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+ 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+ 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+ 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+ 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+ 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+ 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+ 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+ 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+ 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+ 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+ 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+ 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+ 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+ 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+ 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+ 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+ 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+ 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+ 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+ 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+ 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+ 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+ 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+ 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+ 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+ 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+ 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+ 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+ 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+ 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+ 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+ 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+ 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+ 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+ 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+ 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+ 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+ 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+
+static const uint32 Te2[256]=
+{
+ 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+ 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+ 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+ 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+ 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+ 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+ 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+ 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+ 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+ 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+ 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+ 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+ 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+ 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+ 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+ 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+ 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+ 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+ 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+ 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+ 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+ 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+ 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+ 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+ 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+ 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+ 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+ 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+ 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+ 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+ 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+ 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+ 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+ 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+ 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+ 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+ 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+ 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+ 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+ 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+ 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+ 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+ 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+ 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+ 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+ 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+ 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+ 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+ 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+ 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+ 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+ 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+ 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+ 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+ 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+ 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+ 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+ 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+ 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+ 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+ 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+ 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+ 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+ 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+
+static const uint32 Te3[256]=
+{
+ 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+ 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+ 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+ 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+ 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+ 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+ 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+ 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+ 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+ 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+ 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+ 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+ 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+ 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+ 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+ 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+ 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+ 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+ 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+ 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+ 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+ 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+ 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+ 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+ 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+ 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+ 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+ 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+ 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+ 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+ 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+ 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+ 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+ 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+ 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+ 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+ 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+ 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+ 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+ 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+ 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+ 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+ 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+ 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+ 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+ 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+ 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+ 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+ 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+ 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+ 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+ 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+ 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+ 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+ 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+ 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+ 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+ 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+ 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+ 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+ 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+ 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+ 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+ 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+
+static const uint32 Te4[256]=
+{
+ 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+ 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+ 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+ 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+ 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+ 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+ 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+ 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+ 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+ 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+ 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+ 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+ 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+ 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+ 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+ 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+ 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+ 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+ 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+ 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+ 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+ 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+ 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+ 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+ 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+ 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+ 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+ 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+ 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+ 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+ 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+ 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+ 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+ 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+ 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+ 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+ 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+ 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+ 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+ 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+ 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+ 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+ 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+ 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+ 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+ 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+ 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+ 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+ 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+ 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+ 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+ 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+ 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+ 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+ 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+ 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+ 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+ 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+ 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+ 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+ 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+ 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+ 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+ 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+
+static const uint32 Td0[256]=
+{
+ 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+ 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+ 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+ 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+ 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+ 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+ 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+ 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+ 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+ 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+ 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+ 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+ 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+ 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+ 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+ 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+ 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+ 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+ 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+ 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+ 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+ 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+ 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+ 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+ 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+ 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+ 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+ 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+ 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+ 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+ 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+ 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+ 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+ 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+ 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+ 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+ 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+ 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+ 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+ 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+ 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+ 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+ 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+ 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+ 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+ 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+ 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+ 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+ 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+ 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+ 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+ 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+ 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+ 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+ 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+ 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+ 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+ 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+ 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+ 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+ 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+ 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+ 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+ 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+
+static const uint32 Td1[256]=
+{
+ 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+ 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+ 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+ 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+ 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+ 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+ 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+ 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+ 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+ 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+ 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+ 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+ 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+ 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+ 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+ 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+ 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+ 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+ 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+ 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+ 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+ 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+ 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+ 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+ 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+ 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+ 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+ 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+ 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+ 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+ 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+ 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+ 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+ 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+ 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+ 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+ 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+ 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+ 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+ 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+ 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+ 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+ 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+ 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+ 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+ 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+ 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+ 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+ 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+ 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+ 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+ 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+ 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+ 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+ 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+ 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+ 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+ 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+ 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+ 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+ 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+ 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+ 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+ 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+
+static const uint32 Td2[256]=
+{
+ 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+ 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+ 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+ 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+ 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+ 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+ 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+ 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+ 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+ 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+ 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+ 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+ 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+ 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+ 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+ 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+ 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+ 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+ 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+ 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+ 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+ 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+ 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+ 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+ 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+ 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+ 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+ 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+ 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+ 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+ 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+ 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+ 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+ 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+ 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+ 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+ 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+ 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+ 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+ 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+ 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+ 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+ 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+ 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+ 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+ 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+ 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+ 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+ 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+ 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+ 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+ 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+ 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+ 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+ 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+ 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+ 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+ 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+ 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+ 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+ 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+ 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+ 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+ 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+
+static const uint32 Td3[256]=
+{
+ 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+ 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+ 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+ 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+ 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+ 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+ 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+ 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+ 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+ 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+ 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+ 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+ 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+ 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+ 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+ 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+ 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+ 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+ 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+ 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+ 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+ 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+ 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+ 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+ 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+ 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+ 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+ 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+ 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+ 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+ 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+ 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+ 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+ 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+ 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+ 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+ 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+ 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+ 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+ 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+ 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+ 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+ 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+ 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+ 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+ 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+ 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+ 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+ 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+ 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+ 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+ 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+ 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+ 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+ 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+ 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+ 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+ 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+ 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+ 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+ 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+ 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+ 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+ 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+
+static const uint32 Td4[256]=
+{
+ 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+ 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+ 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+ 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+ 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+ 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+ 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+ 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+ 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+ 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+ 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+ 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+ 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+ 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+ 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+ 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+ 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+ 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+ 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+ 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+ 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+ 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+ 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+ 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+ 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+ 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+ 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+ 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+ 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+ 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+ 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+ 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+ 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+ 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+ 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+ 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+ 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+ 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+ 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+ 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+ 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+ 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+ 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+ 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+ 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+ 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+ 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+ 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+ 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+ 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+ 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+ 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+ 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+ 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+ 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+ 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+ 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+ 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+ 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+ 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+ 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+ 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+ 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+ 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+
+
+/* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+static const uint32 rcon[]=
+{
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+ 0x1B000000, 0x36000000,
+};
+
+#if defined(_MSC_VER) && defined(__i386__)
+
+#define RJ_SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+#define GETuint32(p) RJ_SWAP(*((uint32 *)(p)))
+#define PUTuint32(ct, st) { *((uint32 *)(ct)) = RJ_SWAP((st)); }
+
+#else
+
+#define GETuint32(pt) (((uint32)(pt)[0] << 24) ^ ((uint32)(pt)[1] << 16)\
+ ^ ((uint32)(pt)[2] << 8) ^ ((uint32)(pt)[3]))
+#define PUTuint32(ct, st) { (ct)[0] = (uint8)((st) >> 24); (ct)[1]\
+= (uint8)((st) >> 16); (ct)[2] = (uint8)((st) >> 8); (ct)[3] = (uint8)(st); }
+
+#endif /* defined(_MSC_VER) && defined(__i386__) */
+
+
+/*
+ Expand the cipher key into the encryption key schedule.
+
+ RETURN
+ The number of rounds for the given cipher key size.
+*/
+
+int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
+ int keyBits)
+{
+ int i = 0;
+ uint32 temp;
+
+ rk[0] = GETuint32(cipherKey );
+ rk[1] = GETuint32(cipherKey + 4);
+ rk[2] = GETuint32(cipherKey + 8);
+ rk[3] = GETuint32(cipherKey + 12);
+ if (keyBits == 128)
+ {
+ for (;;)
+ {
+ temp = rk[3];
+ rk[4] = (rk[0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i]);
+ rk[5] = rk[1] ^ rk[4];
+ rk[6] = rk[2] ^ rk[5];
+ rk[7] = rk[3] ^ rk[6];
+ if (++i == 10)
+ return 10;
+ rk += 4;
+ }
+ }
+ rk[4] = GETuint32(cipherKey + 16);
+ rk[5] = GETuint32(cipherKey + 20);
+ if (keyBits == 192)
+ {
+ for (;;)
+ {
+ temp = rk[ 5];
+ rk[ 6] = (rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i]);
+ rk[ 7] = rk[ 1] ^ rk[ 6];
+ rk[ 8] = rk[ 2] ^ rk[ 7];
+ rk[ 9] = rk[ 3] ^ rk[ 8];
+ if (++i == 8)
+ {
+ return 12;
+ }
+ rk[10] = rk[ 4] ^ rk[ 9];
+ rk[11] = rk[ 5] ^ rk[10];
+ rk += 6;
+ }
+ }
+ rk[6] = GETuint32(cipherKey + 24);
+ rk[7] = GETuint32(cipherKey + 28);
+ if (keyBits == 256)
+ {
+ for (;;)
+ {
+ temp = rk[ 7];
+ rk[ 8] = (rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i]);
+ rk[ 9] = rk[ 1] ^ rk[ 8];
+ rk[10] = rk[ 2] ^ rk[ 9];
+ rk[11] = rk[ 3] ^ rk[10];
+ if (++i == 7)
+ {
+ return 14;
+ }
+ temp = rk[11];
+ rk[12] = (rk[ 4] ^
+ (Te4[(temp >> 24) ] & 0xff000000) ^
+ (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp ) & 0xff] & 0x000000ff));
+ rk[13] = rk[ 5] ^ rk[12];
+ rk[14] = rk[ 6] ^ rk[13];
+ rk[15] = rk[ 7] ^ rk[14];
+ rk += 8;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ Expand the cipher key into the decryption key schedule.
+
+ RETURN
+ The number of rounds for the given cipher key size.
+*/
+
+int rijndaelKeySetupDec(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
+ int keyBits)
+{
+ int nr, i, j;
+ uint32 temp;
+
+ /* expand the cipher key: */
+ nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
+ /* invert the order of the round keys: */
+ for (i = 0, j = 4*nr; i < j; i += 4, j -= 4)
+ {
+ temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
+ temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+ temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+ temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+ }
+ /*
+ Apply the inverse MixColumn transform to all round keys but the first
+ and the last:
+ */
+ for (i = 1; i < nr; i++)
+ {
+ rk += 4;
+
+ rk[0]= (
+ Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[0] ) & 0xff] & 0xff]);
+
+ rk[1]= (Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[1] ) & 0xff] & 0xff]);
+
+ rk[2]= (Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[2] ) & 0xff] & 0xff]);
+
+ rk[3]= (Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[3] ) & 0xff] & 0xff]);
+ }
+ return nr;
+}
+
+
+void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
+ const uint8 pt[16], uint8 ct[16])
+{
+ uint32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* FULL_UNROLL */
+
+ /* map byte array block to cipher state and add initial round key: */
+ s0 = GETuint32(pt ) ^ rk[0];
+ s1 = GETuint32(pt + 4) ^ rk[1];
+ s2 = GETuint32(pt + 8) ^ rk[2];
+ s3 = GETuint32(pt + 12) ^ rk[3];
+
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[ 4]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[ 5]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[ 6]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[ 7]);
+
+ /* round 2: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[ 8]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[ 9]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[10]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[11]);
+
+ /* round 3: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[12]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[13]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[14]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[15]);
+
+ /* round 4: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[16]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[17]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[18]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[19]);
+
+ /* round 5: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[20]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[21]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[22]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[23]);
+
+ /* round 6: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[24]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[25]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[26]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[27]);
+
+ /* round 7: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[28]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[29]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[30]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[31]);
+
+ /* round 8: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[32]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[33]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[34]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[35]);
+
+ /* round 9: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[36]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[37]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[38]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[39]);
+
+ if (Nr > 10)
+ {
+ /* round 10: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[40]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[41]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[42]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[43]);
+
+ /* round 11: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[44]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[45]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[46]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[47]);
+
+ if (Nr > 12)
+ {
+ /* round 12: */
+ s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
+ ^ Te3[t3 & 0xff] ^ rk[48]);
+ s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
+ ^ Te3[t0 & 0xff] ^ rk[49]);
+ s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
+ ^ Te3[t1 & 0xff] ^ rk[50]);
+ s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
+ ^ Te3[t2 & 0xff] ^ rk[51]);
+
+ /* round 13: */
+ t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
+ ^ Te3[s3 & 0xff] ^ rk[52]);
+ t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
+ ^ Te3[s0 & 0xff] ^ rk[53]);
+ t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
+ ^ Te3[s1 & 0xff] ^ rk[54]);
+ t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
+ ^ Te3[s2 & 0xff] ^ rk[55]);
+ }
+ }
+ rk += Nr << 2;
+#else /* !FULL_UNROLL */
+
+ /* Nr - 1 full rounds: */
+
+ r = Nr >> 1;
+ for (;;)
+ {
+ t0= (Te0[(s0 >> 24) ] ^
+ Te1[(s1 >> 16) & 0xff] ^
+ Te2[(s2 >> 8) & 0xff] ^
+ Te3[(s3 ) & 0xff] ^
+ rk[4]);
+
+ t1= (Te0[(s1 >> 24) ] ^
+ Te1[(s2 >> 16) & 0xff] ^
+ Te2[(s3 >> 8) & 0xff] ^
+ Te3[(s0 ) & 0xff] ^
+ rk[5]);
+
+ t2= (Te0[(s2 >> 24) ] ^
+ Te1[(s3 >> 16) & 0xff] ^
+ Te2[(s0 >> 8) & 0xff] ^
+ Te3[(s1 ) & 0xff] ^
+ rk[6]);
+
+ t3= (Te0[(s3 >> 24) ] ^
+ Te1[(s0 >> 16) & 0xff] ^
+ Te2[(s1 >> 8) & 0xff] ^
+ Te3[(s2 ) & 0xff] ^
+ rk[7]);
+
+ rk+= 8;
+ if (--r == 0)
+ break;
+
+ s0= (Te0[(t0 >> 24) ] ^
+ Te1[(t1 >> 16) & 0xff] ^
+ Te2[(t2 >> 8) & 0xff] ^
+ Te3[(t3 ) & 0xff] ^
+ rk[0]);
+
+ s1= (Te0[(t1 >> 24) ] ^
+ Te1[(t2 >> 16) & 0xff] ^
+ Te2[(t3 >> 8) & 0xff] ^
+ Te3[(t0 ) & 0xff] ^
+ rk[1]);
+
+ s2= (Te0[(t2 >> 24) ] ^
+ Te1[(t3 >> 16) & 0xff] ^
+ Te2[(t0 >> 8) & 0xff] ^
+ Te3[(t1 ) & 0xff] ^
+ rk[2]);
+
+ s3= (Te0[(t3 >> 24) ] ^
+ Te1[(t0 >> 16) & 0xff] ^
+ Te2[(t1 >> 8) & 0xff] ^
+ Te3[(t2 ) & 0xff] ^
+ rk[3]);
+ }
+#endif /* FULL_UNROLL */
+
+ /* Apply last round and map cipher state to byte array block: */
+ s0= ((Te4[(t0 >> 24) ] & 0xff000000) ^
+ (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[0]);
+ PUTuint32(ct , s0);
+
+ s1= ((Te4[(t1 >> 24) ] & 0xff000000) ^
+ (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[1]);
+ PUTuint32(ct + 4, s1);
+
+ s2= ((Te4[(t2 >> 24) ] & 0xff000000) ^
+ (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[2]);
+ PUTuint32(ct + 8, s2);
+
+ s3= ((Te4[(t3 >> 24) ] & 0xff000000) ^
+ (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[3]);
+ PUTuint32(ct + 12, s3);
+}
+
+
+void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
+ const uint8 ct[16], uint8 pt[16])
+{
+ uint32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* FULL_UNROLL */
+
+ /* Map byte array block to cipher state and add initial round key: */
+
+ s0 = GETuint32(ct ) ^ rk[0];
+ s1 = GETuint32(ct + 4) ^ rk[1];
+ s2 = GETuint32(ct + 8) ^ rk[2];
+ s3 = GETuint32(ct + 12) ^ rk[3];
+
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[ 4]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[ 5]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[ 6]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[ 7]);
+
+ /* round 2: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[ 8]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[ 9]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[10]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[11]);
+
+ /* round 3: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[12]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[13]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[14]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[15]);
+
+ /* round 4: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[16]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[17]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[18]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[19]);
+
+ /* round 5: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[20]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[21]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[22]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[23]);
+
+ /* round 6: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[24]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[25]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[26]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[27]);
+
+ /* round 7: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[28]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[29]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[30]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[31]);
+
+ /* round 8: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[32]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[33]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[34]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[35]);
+
+ /* round 9: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[36]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[37]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[38]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[39]);
+
+ if (Nr > 10)
+ {
+ /* round 10: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[40]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[41]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[42]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[43]);
+
+ /* round 11: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[44]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[45]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[46]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[47]);
+
+ if (Nr > 12)
+ {
+ /* round 12: */
+ s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
+ ^ Td3[t1 & 0xff] ^ rk[48]);
+ s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
+ ^ Td3[t2 & 0xff] ^ rk[49]);
+ s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
+ ^ Td3[t3 & 0xff] ^ rk[50]);
+ s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
+ ^ Td3[t0 & 0xff] ^ rk[51]);
+
+ /* round 13: */
+ t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
+ ^ Td3[s1 & 0xff] ^ rk[52]);
+ t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
+ ^ Td3[s2 & 0xff] ^ rk[53]);
+ t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
+ ^ Td3[s3 & 0xff] ^ rk[54]);
+ t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
+ ^ Td3[s0 & 0xff] ^ rk[55]);
+ }
+ }
+ rk += Nr << 2;
+#else /* !FULL_UNROLL */
+
+ /* Nr - 1 full rounds: */
+ r= (Nr >> 1);
+ for (;;)
+ {
+ t0= (Td0[(s0 >> 24) ] ^
+ Td1[(s3 >> 16) & 0xff] ^
+ Td2[(s2 >> 8) & 0xff] ^
+ Td3[(s1 ) & 0xff] ^
+ rk[4]);
+
+ t1= (Td0[(s1 >> 24) ] ^
+ Td1[(s0 >> 16) & 0xff] ^
+ Td2[(s3 >> 8) & 0xff] ^
+ Td3[(s2 ) & 0xff] ^
+ rk[5]);
+
+ t2= (Td0[(s2 >> 24) ] ^
+ Td1[(s1 >> 16) & 0xff] ^
+ Td2[(s0 >> 8) & 0xff] ^
+ Td3[(s3 ) & 0xff] ^
+ rk[6]);
+
+ t3= (Td0[(s3 >> 24) ] ^
+ Td1[(s2 >> 16) & 0xff] ^
+ Td2[(s1 >> 8) & 0xff] ^
+ Td3[(s0 ) & 0xff] ^
+ rk[7]);
+
+ rk+= 8;
+ if (--r == 0)
+ break;
+
+ s0= (Td0[(t0 >> 24) ] ^
+ Td1[(t3 >> 16) & 0xff] ^
+ Td2[(t2 >> 8) & 0xff] ^
+ Td3[(t1 ) & 0xff] ^
+ rk[0]);
+
+ s1= (Td0[(t1 >> 24) ] ^
+ Td1[(t0 >> 16) & 0xff] ^
+ Td2[(t3 >> 8) & 0xff] ^
+ Td3[(t2 ) & 0xff] ^
+ rk[1]);
+
+ s2= (Td0[(t2 >> 24) ] ^
+ Td1[(t1 >> 16) & 0xff] ^
+ Td2[(t0 >> 8) & 0xff] ^
+ Td3[(t3 ) & 0xff] ^
+ rk[2]);
+
+ s3= (Td0[(t3 >> 24) ] ^
+ Td1[(t2 >> 16) & 0xff] ^
+ Td2[(t1 >> 8) & 0xff] ^
+ Td3[(t0 ) & 0xff] ^
+ rk[3]);
+ }
+
+#endif /* FULL_UNROLL */
+
+ /* Apply last round and map cipher state to byte array block: */
+
+ s0= ((Td4[(t0 >> 24) ] & 0xff000000) ^
+ (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[0]);
+ PUTuint32(pt , s0);
+
+ s1= ((Td4[(t1 >> 24) ] & 0xff000000) ^
+ (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[1]);
+ PUTuint32(pt + 4, s1);
+
+ s2= ((Td4[(t2 >> 24) ] & 0xff000000) ^
+ (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[2]);
+ PUTuint32(pt + 8, s2);
+
+ s3= ((Td4[(t3 >> 24) ] & 0xff000000) ^
+ (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[3]);
+ PUTuint32(pt + 12, s3);
+}
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index 0bf9341e3c1..07c40fd91b6 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -1,68 +1,64 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+/* Copyright (C) 2000-2003 MySQL AB
-/*
- * [This posting refers to an article entitled "oops, corrupted memory
- * again!" in net.lang.c. I am posting it here because it is source.]
- *
- * My tool for approaching this problem is to build another level of data
- * abstraction on top of malloc() and free() that implements some checking.
- * This does a number of things for you:
- * - Checks for overruns and underruns on allocated data
- * - Keeps track of where in the program the memory was malloc'ed
- * - Reports on pieces of memory that were not free'ed
- * - Records some statistics such as maximum memory used
- * - Marks newly malloc'ed and newly free'ed memory with special values
- * You can use this scheme to:
- * - Find bugs such as overrun, underrun, etc because you know where
- * a piece of data was malloc'ed and where it was free'ed
- * - Find bugs where memory was not free'ed
- * - Find bugs where newly malloc'ed memory is used without initializing
- * - Find bugs where newly free'ed memory is still used
- * - Determine how much memory your program really uses
- * - and other things
- */
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-/*
- * To implement my scheme you must have a C compiler that has __LINE__ and
- * __FILE__ macros. If your compiler doesn't have these then (a) buy another:
- * compilers that do are available on UNIX 4.2bsd based systems and the PC,
- * and probably on other machines; or (b) change my scheme somehow. I have
- * recomendations on both these points if you would like them (e-mail please).
- *
- * There are 4 functions in my package:
- * char *NEW( uSize ) Allocate memory of uSize bytes
- * (equivalent to malloc())
- * char *REA( pPtr, uSize) Allocate memory of uSize bytes, move data and
- * free pPtr.
- * (equivalent to realloc())
- * FREE( pPtr ) Free memory allocated by NEW
- * (equivalent to free())
- * TERMINATE(file) End system, report errors and stats on file
- * I personally use two more functions, but have not included them here:
- * char *STRSAVE( sPtr ) Save a copy of the string in dynamic memory
- * char *RENEW( pPtr, uSize )
- * (equivalent to realloc())
- */
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* Memory sub-system, written by Bjorn Benson
Fixed to use my_sys scheme by Michael Widenius
- */
+
+ [This posting refers to an article entitled "oops, corrupted memory
+ again!" in net.lang.c. I am posting it here because it is source.]
+
+ My tool for approaching this problem is to build another level of data
+ abstraction on top of malloc() and free() that implements some checking.
+ This does a number of things for you:
+ - Checks for overruns and underruns on allocated data
+ - Keeps track of where in the program the memory was malloc'ed
+ - Reports on pieces of memory that were not free'ed
+ - Records some statistics such as maximum memory used
+ - Marks newly malloc'ed and newly free'ed memory with special values
+ You can use this scheme to:
+ - Find bugs such as overrun, underrun, etc because you know where
+ a piece of data was malloc'ed and where it was free'ed
+ - Find bugs where memory was not free'ed
+ - Find bugs where newly malloc'ed memory is used without initializing
+ - Find bugs where newly free'ed memory is still used
+ - Determine how much memory your program really uses
+ - and other things
+
+ To implement my scheme you must have a C compiler that has __LINE__ and
+ __FILE__ macros. If your compiler doesn't have these then (a) buy another:
+ compilers that do are available on UNIX 4.2bsd based systems and the PC,
+ and probably on other machines; or (b) change my scheme somehow. I have
+ recomendations on both these points if you would like them (e-mail please).
+
+ There are 4 functions in my package:
+ char *NEW( uSize ) Allocate memory of uSize bytes
+ (equivalent to malloc())
+ char *REA( pPtr, uSize) Allocate memory of uSize bytes, move data and
+ free pPtr.
+ (equivalent to realloc())
+ FREE( pPtr ) Free memory allocated by NEW
+ (equivalent to free())
+ TERMINATE(file) End system, report errors and stats on file
+ I personally use two more functions, but have not included them here:
+ char *STRSAVE( sPtr ) Save a copy of the string in dynamic memory
+ char *RENEW( pPtr, uSize )
+ (equivalent to realloc())
+
+*/
#ifndef SAFEMALLOC
#define SAFEMALLOC /* Get protos from my_sys */
@@ -73,286 +69,282 @@
#include "my_static.h"
#include "mysys_err.h"
-ulonglong safemalloc_mem_limit = ~(ulonglong)0;
+ulonglong sf_malloc_mem_limit= ~(ulonglong)0;
-#define pNext tInt._pNext
-#define pPrev tInt._pPrev
-#define sFileName tInt._sFileName
-#define uLineNum tInt._uLineNum
-#define uDataSize tInt._uDataSize
-#define lSpecialValue tInt._lSpecialValue
+#ifndef PEDANTIC_SAFEMALLOC
+/*
+ Set to 1 after TERMINATE() if we had to fiddle with sf_malloc_count and
+ the linked list of blocks so that _sanity() will not fuss when it
+ is not supposed to
+*/
+static int sf_malloc_tampered= 0;
+#endif
+
/* Static functions prototypes */
static int check_ptr(const char *where, byte *ptr, const char *sFile,
uint uLine);
-static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
+static int _checkchunk(struct st_irem *pRec, const char *sFile, uint uLine);
/*
- * Note: both these refer to the NEW'ed
- * data only. They do not include
- * malloc() roundoff or the extra
- * space required by the remember
- * structures.
- */
-
-#define ALLOC_VAL (uchar) 0xA5 /* NEW'ed memory is filled with this */
- /* value so that references to it will */
- /* end up being very strange. */
-#define FREE_VAL (uchar) 0x8F /* FREE'ed memory is filled with this */
- /* value so that references to it will */
- /* also end up being strange. */
+ Note: We only fill up the allocated block. This do not include
+ malloc() roundoff or the extra space required by the irem
+ structures.
+*/
+/*
+ NEW'ed memory is filled with this value so that references to it will
+ end up being very strange.
+*/
+#define ALLOC_VAL (uchar) 0xA5
+/*
+ FEEE'ed memory is filled with this value so that references to it will
+ end up being very strange.
+*/
+#define FREE_VAL (uchar) 0x8F
#define MAGICKEY 0x14235296 /* A magic value for underrun key */
+
+/*
+ Warning: do not change the MAGICEND? values to something with the
+ high bit set. Various C compilers (like the 4.2bsd one) do not do
+ the sign extension right later on in this code and you will get
+ erroneous errors.
+*/
+
#define MAGICEND0 0x68 /* Magic values for overrun keys */
#define MAGICEND1 0x34 /* " */
#define MAGICEND2 0x7A /* " */
#define MAGICEND3 0x15 /* " */
- /* Warning: do not change the MAGICEND? values to */
- /* something with the high bit set. Various C */
- /* compilers (like the 4.2bsd one) do not do the */
- /* sign extension right later on in this code and */
- /* you will get erroneous errors. */
+/* Allocate some memory. */
-/*
- * gptr _mymalloc( uint uSize, my_string sFile, uint uLine, MyFlags )
- * Allocate some memory.
- */
-
-gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
+gptr _mymalloc(uint size, const char *filename, uint lineno, myf MyFlags)
{
- struct remember *pTmp;
- DBUG_ENTER("_mymalloc");
- DBUG_PRINT("enter",("Size: %u",uSize));
-
-
- if (!sf_malloc_quick)
- (void) _sanity (sFile, uLine);
-
- if(uSize + lCurMemory > safemalloc_mem_limit)
- pTmp = 0;
- else
- /* Allocate the physical memory */
- pTmp = (struct remember *) malloc (
- sizeof (struct irem) /* remember data */
- + sf_malloc_prehunc
- + uSize /* size requested */
- + 4 /* overrun mark */
- + sf_malloc_endhunc
- );
-
- /* Check if there isn't anymore memory avaiable */
- if (pTmp == NULL)
- {
- if (MyFlags & MY_FAE)
- error_handler_hook=fatal_error_handler_hook;
- if (MyFlags & (MY_FAE+MY_WME))
- {
- char buff[SC_MAXWIDTH];
- my_errno=errno;
- sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile);
- my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
- sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)",
- uSize, (uSize + 1023L) / 1024L,
- lMaxMemory, (lMaxMemory + 1023L) / 1024L);
- my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
- }
- DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
- lMaxMemory,uLine, sFile));
- if (MyFlags & MY_FAE)
- exit(1);
- DBUG_RETURN ((gptr) NULL);
- }
+ struct st_irem *irem;
+ char *data;
+ DBUG_ENTER("_mymalloc");
+ DBUG_PRINT("enter",("Size: %u",size));
+
+ if (!sf_malloc_quick)
+ (void) _sanity (filename, lineno);
- /* Fill up the structure */
- *((long*) ((char*) &pTmp -> lSpecialValue+sf_malloc_prehunc)) = MAGICKEY;
- pTmp -> aData[uSize + sf_malloc_prehunc+0] = MAGICEND0;
- pTmp -> aData[uSize + sf_malloc_prehunc+1] = MAGICEND1;
- pTmp -> aData[uSize + sf_malloc_prehunc+2] = MAGICEND2;
- pTmp -> aData[uSize + sf_malloc_prehunc+3] = MAGICEND3;
- pTmp -> sFileName = (my_string) sFile;
- pTmp -> uLineNum = uLine;
- pTmp -> uDataSize = uSize;
- pTmp -> pPrev = NULL;
-
- /* Add this remember structure to the linked list */
- pthread_mutex_lock(&THR_LOCK_malloc);
- if ((pTmp->pNext=pRememberRoot))
+ if (size + sf_malloc_cur_memory > sf_malloc_mem_limit)
+ irem= 0;
+ else
+ {
+ /* Allocate the physical memory */
+ irem= (struct st_irem *) malloc (ALIGN_SIZE(sizeof(struct st_irem)) +
+ sf_malloc_prehunc +
+ size + /* size requested */
+ 4 + /* overrun mark */
+ sf_malloc_endhunc);
+ }
+ /* Check if there isn't anymore memory avaiable */
+ if (!irem)
+ {
+ if (MyFlags & MY_FAE)
+ error_handler_hook=fatal_error_handler_hook;
+ if (MyFlags & (MY_FAE+MY_WME))
{
- pRememberRoot -> pPrev = pTmp;
+ char buff[SC_MAXWIDTH];
+ my_errno=errno;
+ sprintf(buff,"Out of memory at line %d, '%s'", lineno, filename);
+ my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
+ sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)",
+ size, (size + 1023L) / 1024L,
+ sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L);
+ my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
}
- pRememberRoot = pTmp;
+ DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
+ sf_malloc_max_memory,lineno, filename));
+ if (MyFlags & MY_FAE)
+ exit(1);
+ DBUG_RETURN ((gptr) 0);
+ }
- /* Keep the statistics */
- lCurMemory += uSize;
- if (lCurMemory > lMaxMemory) {
- lMaxMemory = lCurMemory;
- }
- cNewCount++;
- pthread_mutex_unlock(&THR_LOCK_malloc);
-
- /* Set the memory to the aribtrary wierd value */
- if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick)
- bfill(&pTmp -> aData[sf_malloc_prehunc],uSize,
- (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
- /* Return a pointer to the real data */
- DBUG_PRINT("exit",("ptr: %lx",&(pTmp -> aData[sf_malloc_prehunc])));
- if (sf_min_adress > &(pTmp -> aData[sf_malloc_prehunc]))
- sf_min_adress = &(pTmp -> aData[sf_malloc_prehunc]);
- if (sf_max_adress < &(pTmp -> aData[sf_malloc_prehunc]))
- sf_max_adress = &(pTmp -> aData[sf_malloc_prehunc]);
- DBUG_RETURN ((gptr) &(pTmp -> aData[sf_malloc_prehunc]));
+ /* Fill up the structure */
+ data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
+ sf_malloc_prehunc);
+ *((uint32*) (data-sizeof(uint32)))= MAGICKEY;
+ data[size + 0]= MAGICEND0;
+ data[size + 1]= MAGICEND1;
+ data[size + 2]= MAGICEND2;
+ data[size + 3]= MAGICEND3;
+ irem->filename= (my_string) filename;
+ irem->linenum= lineno;
+ irem->datasize= size;
+ irem->prev= NULL;
+
+ /* Add this remember structure to the linked list */
+ pthread_mutex_lock(&THR_LOCK_malloc);
+ if ((irem->next= sf_malloc_root))
+ sf_malloc_root->prev= irem;
+ sf_malloc_root= irem;
+
+ /* Keep the statistics */
+ sf_malloc_cur_memory+= size;
+ if (sf_malloc_cur_memory > sf_malloc_max_memory)
+ sf_malloc_max_memory= sf_malloc_cur_memory;
+ sf_malloc_count++;
+ pthread_mutex_unlock(&THR_LOCK_malloc);
+
+ /* Set the memory to the aribtrary wierd value */
+ if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick)
+ bfill(data, size, (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
+ /* Return a pointer to the real data */
+ DBUG_PRINT("exit",("ptr: %lx", data));
+ if (sf_min_adress > data)
+ sf_min_adress= data;
+ if (sf_max_adress < data)
+ sf_max_adress= data;
+ DBUG_RETURN ((gptr) data);
}
+
/*
- * Allocate some new memory and move old memoryblock there.
- * Free then old memoryblock
- */
+ Allocate some new memory and move old memoryblock there.
+ Free then old memoryblock
+*/
-gptr _myrealloc (register gptr pPtr, register uint uSize,
- const char *sFile, uint uLine, myf MyFlags)
+gptr _myrealloc(register gptr ptr, register uint size,
+ const char *filename, uint lineno, myf MyFlags)
{
- struct remember *pRec;
- gptr ptr;
+ struct st_irem *irem;
+ char *data;
DBUG_ENTER("_myrealloc");
- if (!pPtr && (MyFlags & MY_ALLOW_ZERO_PTR))
- DBUG_RETURN(_mymalloc(uSize,sFile,uLine,MyFlags));
+ if (!ptr && (MyFlags & MY_ALLOW_ZERO_PTR))
+ DBUG_RETURN(_mymalloc(size, filename, lineno, MyFlags));
if (!sf_malloc_quick)
- (void) _sanity (sFile, uLine);
+ (void) _sanity (filename, lineno);
- if (check_ptr("Reallocating",(byte*) pPtr,sFile,uLine))
+ if (check_ptr("Reallocating", (byte*) ptr, filename, lineno))
DBUG_RETURN((gptr) NULL);
- pRec = (struct remember *) ((char*) pPtr - sizeof (struct irem)-
- sf_malloc_prehunc);
- if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
- != MAGICKEY)
+ irem= (struct st_irem *) (((char*) ptr) - ALIGN_SIZE(sizeof(struct st_irem))-
+ sf_malloc_prehunc);
+ if (*((uint32*) (((char*) ptr)- sizeof(uint32))) != MAGICKEY)
{
- fprintf (stderr, "Reallocating unallocated data at line %d, '%s'\n",
- uLine, sFile);
+ fprintf(stderr, "Error: Reallocating unallocated data at line %d, '%s'\n",
+ lineno, filename);
DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'",
- uLine, sFile));
+ lineno, filename));
(void) fflush(stderr);
DBUG_RETURN((gptr) NULL);
}
- if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags))) /* Allocate new area */
+ if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
{
- uSize=min(uSize,pRec-> uDataSize); /* Move as much as possibly */
- memcpy((byte*) ptr,pPtr,(size_t) uSize); /* Copy old data */
- _myfree(pPtr,sFile,uLine,0); /* Free not needed area */
+ size=min(size, irem->datasize); /* Move as much as possibly */
+ memcpy((byte*) data, ptr, (size_t) size); /* Copy old data */
+ _myfree(ptr, filename, lineno, 0); /* Free not needed area */
}
else
{
if (MyFlags & MY_HOLD_ON_ERROR)
- DBUG_RETURN(pPtr);
+ DBUG_RETURN(ptr);
if (MyFlags & MY_FREE_ON_ERROR)
- _myfree(pPtr,sFile,uLine,0);
+ _myfree(ptr, filename, lineno, 0);
}
- DBUG_RETURN(ptr);
+ DBUG_RETURN(data);
} /* _myrealloc */
-/*
- * void _myfree( my_string pPtr, my_string sFile, uint uLine, myf myflags)
- * Deallocate some memory.
- */
+/* Deallocate some memory. */
-void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
+void _myfree(gptr ptr, const char *filename, uint lineno, myf myflags)
{
- struct remember *pRec;
+ struct st_irem *irem;
DBUG_ENTER("_myfree");
- DBUG_PRINT("enter",("ptr: %lx",pPtr));
+ DBUG_PRINT("enter",("ptr: %lx", ptr));
if (!sf_malloc_quick)
- (void) _sanity (sFile, uLine);
+ (void) _sanity (filename, lineno);
- if ((!pPtr && (myflags & MY_ALLOW_ZERO_PTR)) ||
- check_ptr("Freeing",(byte*) pPtr,sFile,uLine))
+ if ((!ptr && (myflags & MY_ALLOW_ZERO_PTR)) ||
+ check_ptr("Freeing",(byte*) ptr,filename,lineno))
DBUG_VOID_RETURN;
/* Calculate the address of the remember structure */
- pRec = (struct remember *) ((byte*) pPtr-sizeof(struct irem)-
- sf_malloc_prehunc);
-
- /* Check to make sure that we have a real remember structure */
- /* Note: this test could fail for four reasons: */
- /* (1) The memory was already free'ed */
- /* (2) The memory was never new'ed */
- /* (3) There was an underrun */
- /* (4) A stray pointer hit this location */
-
- if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
- != MAGICKEY)
+ irem= (struct st_irem *) ((char*) ptr- ALIGN_SIZE(sizeof(struct st_irem))-
+ sf_malloc_prehunc);
+
+ /*
+ Check to make sure that we have a real remember structure.
+ Note: this test could fail for four reasons:
+ (1) The memory was already free'ed
+ (2) The memory was never new'ed
+ (3) There was an underrun
+ (4) A stray pointer hit this location
+ */
+
+ if (*((uint32*) ((char*) ptr- sizeof(uint32))) != MAGICKEY)
{
- fprintf (stderr, "Freeing unallocated data at line %d, '%s'\n",
- uLine, sFile);
- DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",uLine,sFile));
+ fprintf(stderr, "Error: Freeing unallocated data at line %d, '%s'\n",
+ lineno, filename);
+ DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",lineno,filename));
(void) fflush(stderr);
DBUG_VOID_RETURN;
}
/* Remove this structure from the linked list */
pthread_mutex_lock(&THR_LOCK_malloc);
- if (pRec -> pPrev) {
- pRec -> pPrev -> pNext = pRec -> pNext;
- } else {
- pRememberRoot = pRec -> pNext;
- }
- if (pRec -> pNext) {
- pRec -> pNext -> pPrev = pRec -> pPrev;
- }
+ if (irem->prev)
+ irem->prev->next= irem->next;
+ else
+ sf_malloc_root= irem->next;
+
+ if (irem->next)
+ irem->next->prev= irem->prev;
/* Handle the statistics */
- lCurMemory -= pRec -> uDataSize;
- cNewCount--;
+ sf_malloc_cur_memory-= irem->datasize;
+ sf_malloc_count--;
pthread_mutex_unlock(&THR_LOCK_malloc);
#ifndef HAVE_purify
/* Mark this data as free'ed */
if (!sf_malloc_quick)
- bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL);
+ bfill(ptr, irem->datasize, (pchar) FREE_VAL);
#endif
- *((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) = ~MAGICKEY;
-
+ *((uint32*) ((char*) ptr- sizeof(uint32)))= ~MAGICKEY;
/* Actually free the memory */
- free ((my_string ) pRec);
+ free((char*) irem);
DBUG_VOID_RETURN;
}
/* Check if we have a wrong pointer */
-static int check_ptr(const char *where, byte *ptr, const char *sFile,
- uint uLine)
+static int check_ptr(const char *where, byte *ptr, const char *filename,
+ uint lineno)
{
if (!ptr)
{
- fprintf (stderr, "%s NULL pointer at line %d, '%s'\n",
- where,uLine, sFile);
- DBUG_PRINT("safe",("Null pointer at line %d '%s'", uLine, sFile));
+ fprintf(stderr, "Error: %s NULL pointer at line %d, '%s'\n",
+ where,lineno, filename);
+ DBUG_PRINT("safe",("Null pointer at line %d '%s'", lineno, filename));
(void) fflush(stderr);
return 1;
}
#ifndef _MSC_VER
- if ((long) ptr & (MY_ALIGN(1,sizeof(char *))-1))
+ if ((long) ptr & (ALIGN_SIZE(1)-1))
{
- fprintf (stderr, "%s wrong aligned pointer at line %d, '%s'\n",
- where,uLine, sFile);
+ fprintf(stderr, "Error: %s wrong aligned pointer at line %d, '%s'\n",
+ where,lineno, filename);
DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'",
- uLine,sFile));
+ lineno,filename));
(void) fflush(stderr);
return 1;
}
#endif
if (ptr < sf_min_adress || ptr > sf_max_adress)
{
- fprintf (stderr, "%s pointer out of range at line %d, '%s'\n",
- where,uLine, sFile);
+ fprintf(stderr, "Error: %s pointer out of range at line %d, '%s'\n",
+ where,lineno, filename);
DBUG_PRINT("safe",("Pointer out of range at line %d '%s'",
- uLine,sFile));
+ lineno,filename));
(void) fflush(stderr);
return 1;
}
@@ -361,69 +353,77 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
/*
- * TERMINATE(FILE *file)
- * Report on all the memory pieces that have not been
- * free'ed as well as the statistics.
+ TERMINATE(FILE *file)
+ Report on all the memory pieces that have not been
+ free'ed as well as the statistics.
*/
-void TERMINATE (FILE *file)
+void TERMINATE(FILE *file)
{
- struct remember *pPtr;
+ struct st_irem *irem;
DBUG_ENTER("TERMINATE");
pthread_mutex_lock(&THR_LOCK_malloc);
- /* Report the difference between number of calls to */
- /* NEW and the number of calls to FREE. >0 means more */
- /* NEWs than FREEs. <0, etc. */
+ /*
+ Report the difference between number of calls to
+ NEW and the number of calls to FREE. >0 means more
+ NEWs than FREEs. <0, etc.
+ */
- if (cNewCount)
+ if (sf_malloc_count)
{
if (file)
{
- fprintf (file, "cNewCount: %d\n", cNewCount);
+ fprintf(file, "Warning: Not freed memory segments: %u\n",
+ sf_malloc_count);
(void) fflush(file);
}
- DBUG_PRINT("safe",("cNewCount: %d",cNewCount));
+ DBUG_PRINT("safe",("sf_malloc_count: %u", sf_malloc_count));
}
- /* Report on all the memory that was allocated with NEW */
- /* but not free'ed with FREE. */
+ /*
+ Report on all the memory that was allocated with NEW
+ but not free'ed with FREE.
+ */
- if ((pPtr=pRememberRoot))
+ if ((irem= sf_malloc_root))
{
if (file)
{
- fprintf(file, "Memory that was not free'ed (%ld bytes):\n",lCurMemory);
+ fprintf(file, "Warning: Memory that was not free'ed (%ld bytes):\n",
+ sf_malloc_cur_memory);
(void) fflush(file);
}
- DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",lCurMemory));
- while (pPtr)
+ DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",
+ sf_malloc_cur_memory));
+ while (irem)
{
+ char *data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
+ sf_malloc_prehunc);
if (file)
{
- fprintf (file,
- "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'\n",
- pPtr -> uDataSize,
- (ulong) &(pPtr -> aData[sf_malloc_prehunc]),
- pPtr -> uLineNum, pPtr -> sFileName);
+ fprintf(file,
+ "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'",
+ irem->datasize, (long) data, irem->linenum, irem->filename);
+ fprintf(file, "\n");
(void) fflush(file);
}
DBUG_PRINT("safe",
("%6u bytes at 0x%09lx, allocated at line %4d in '%s'",
- pPtr -> uDataSize, &(pPtr -> aData[sf_malloc_prehunc]),
- pPtr -> uLineNum, pPtr -> sFileName));
- pPtr = pPtr -> pNext;
+ irem->datasize, data, irem->linenum, irem->filename));
+ irem= irem->next;
}
}
/* Report the memory usage statistics */
if (file)
{
- fprintf (file, "Maximum memory usage: %ld bytes (%ldk)\n",
- lMaxMemory, (lMaxMemory + 1023L) / 1024L);
+ fprintf(file, "Maximum memory usage: %ld bytes (%ldk)\n",
+ sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L);
(void) fflush(file);
}
DBUG_PRINT("safe",("Maximum memory usage: %ld bytes (%ldk)",
- lMaxMemory, (lMaxMemory + 1023L) / 1024L));
+ sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) /
+ 1024L));
pthread_mutex_unlock(&THR_LOCK_malloc);
DBUG_VOID_RETURN;
}
@@ -431,44 +431,41 @@ void TERMINATE (FILE *file)
/* Returns 0 if chunk is ok */
-static int _checkchunk (register struct remember *pRec, const char *sFile,
- uint uLine)
+static int _checkchunk(register struct st_irem *irem, const char *filename,
+ uint lineno)
{
- reg1 uint uSize;
- reg2 my_string magicp;
- reg3 int flag=0;
+ int flag=0;
+ char *magicp, *data;
+ data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
+ sf_malloc_prehunc);
/* Check for a possible underrun */
- if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
- != MAGICKEY)
+ if (*((uint32*) (data- sizeof(uint32))) != MAGICKEY)
{
- fprintf (stderr, "Memory allocated at %s:%d was underrun,",
- pRec -> sFileName, pRec -> uLineNum);
- fprintf (stderr, " discovered at %s:%d\n", sFile, uLine);
+ fprintf(stderr, "Error: Memory allocated at %s:%d was underrun,",
+ irem->filename, irem->linenum);
+ fprintf(stderr, " discovered at %s:%d\n", filename, lineno);
(void) fflush(stderr);
DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d",
- &(pRec -> aData[sf_malloc_prehunc]),
- pRec -> sFileName,
- pRec -> uLineNum));
+ data, irem->filename, irem->linenum));
flag=1;
}
/* Check for a possible overrun */
- uSize = pRec -> uDataSize;
- magicp = &(pRec -> aData[uSize+sf_malloc_prehunc]);
+ magicp= data + irem->datasize;
if (*magicp++ != MAGICEND0 ||
*magicp++ != MAGICEND1 ||
*magicp++ != MAGICEND2 ||
*magicp++ != MAGICEND3)
{
- fprintf (stderr, "Memory allocated at %s:%d was overrun,",
- pRec -> sFileName, pRec -> uLineNum);
- fprintf (stderr, " discovered at '%s:%d'\n", sFile, uLine);
+ fprintf(stderr, "Error: Memory allocated at %s:%d was overrun,",
+ irem->filename, irem->linenum);
+ fprintf(stderr, " discovered at '%s:%d'\n", filename, lineno);
(void) fflush(stderr);
DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d",
- &(pRec -> aData[sf_malloc_prehunc]),
- pRec -> sFileName,
- pRec -> uLineNum));
+ data,
+ irem->filename,
+ irem->linenum));
flag=1;
}
return(flag);
@@ -477,23 +474,28 @@ static int _checkchunk (register struct remember *pRec, const char *sFile,
/* Returns how many wrong chunks */
-int _sanity (const char *sFile, uint uLine)
+int _sanity(const char *filename, uint lineno)
{
- reg1 struct remember *pTmp;
+ reg1 struct st_irem *irem;
reg2 int flag=0;
uint count=0;
pthread_mutex_lock(&THR_LOCK_malloc);
- count=cNewCount;
- for (pTmp = pRememberRoot; pTmp != NULL && count-- ; pTmp = pTmp -> pNext)
- flag+=_checkchunk (pTmp, sFile, uLine);
+#ifndef PEDANTIC_SAFEMALLOC
+ if (sf_malloc_tampered && (int) sf_malloc_count < 0)
+ sf_malloc_count=0;
+#endif
+ count=sf_malloc_count;
+ for (irem= sf_malloc_root; irem != NULL && count-- ; irem= irem->next)
+ flag+= _checkchunk (irem, filename, lineno);
pthread_mutex_unlock(&THR_LOCK_malloc);
- if (count || pTmp)
+ if (count || irem)
{
- const char *format="Safemalloc link list destroyed, discovered at '%s:%d'";
- fprintf (stderr, format, sFile, uLine); fputc('\n',stderr);
+ const char *format="Error: Safemalloc link list destroyed, discovered at '%s:%d'";
+ fprintf(stderr, format, filename, lineno); fputc('\n',stderr);
+ fprintf(stderr, "root=%p,count=%d,irem=%p\n", sf_malloc_root,count,irem);
(void) fflush(stderr);
- DBUG_PRINT("safe",(format, sFile, uLine));
+ DBUG_PRINT("safe",(format, filename, lineno));
flag=1;
}
return flag;
@@ -502,22 +504,36 @@ int _sanity (const char *sFile, uint uLine)
/* malloc and copy */
-gptr _my_memdup(const byte *from, uint length, const char *sFile, uint uLine,
- myf MyFlags)
+gptr _my_memdup(const byte *from, uint length, const char *filename,
+ uint lineno, myf MyFlags)
{
gptr ptr;
- if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0)
+ if ((ptr=_mymalloc(length,filename,lineno,MyFlags)) != 0)
memcpy((byte*) ptr, (byte*) from,(size_t) length);
return(ptr);
} /*_my_memdup */
-my_string _my_strdup(const char *from, const char *sFile, uint uLine,
- myf MyFlags)
+char *_my_strdup(const char *from, const char *filename, uint lineno,
+ myf MyFlags)
{
gptr ptr;
uint length=(uint) strlen(from)+1;
- if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0)
+ if ((ptr=_mymalloc(length,filename,lineno,MyFlags)) != 0)
memcpy((byte*) ptr, (byte*) from,(size_t) length);
- return((my_string) ptr);
+ return((char*) ptr);
} /* _my_strdup */
+
+
+char *_my_strdup_with_length(const byte *from, uint length,
+ const char *filename, uint lineno,
+ myf MyFlags)
+{
+ gptr ptr;
+ if ((ptr=_mymalloc(length+1,filename,lineno,MyFlags)) != 0)
+ {
+ memcpy((byte*) ptr, (byte*) from,(size_t) length);
+ ptr[length]=0;
+ }
+ return((char *) ptr);
+}
diff --git a/mysys/sha1.c b/mysys/sha1.c
new file mode 100644
index 00000000000..5271b369b6c
--- /dev/null
+++ b/mysys/sha1.c
@@ -0,0 +1,392 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Original Source from: http://www.faqs.org/rfcs/rfc3174.html
+
+ DESCRIPTION
+ This file implements the Secure Hashing Algorithm 1 as
+ defined in FIPS PUB 180-1 published April 17, 1995.
+
+ The SHA-1, produces a 160-bit message digest for a given data
+ stream. It should take about 2**n steps to find a message with the
+ same digest as a given message and 2**(n/2) to find any two
+ messages with the same digest, when n is the digest size in bits.
+ Therefore, this algorithm can serve as a means of providing a
+ "fingerprint" for a message.
+
+ PORTABILITY ISSUES
+ SHA-1 is defined in terms of 32-bit "words". This code uses
+ <stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned
+ integer types. If your C compiler does not support 32 bit unsigned
+ integers, this code is not appropriate.
+
+ CAVEATS
+ SHA-1 is designed to work with messages less than 2^64 bits long.
+ Although SHA-1 allows a message digest to be generated for messages
+ of any number of bits less than 2^64, this implementation only
+ works with messages with a length that is a multiple of the size of
+ an 8-bit character.
+
+ CHANGES
+ 2002 by Peter Zaitsev to
+ - fit to new prototypes according to MySQL standard
+ - Some optimizations
+ - All checking is now done in debug only mode
+ - More comments
+*/
+
+#include "my_global.h"
+#include "m_string.h"
+#include "sha1.h"
+
+/*
+ Define the SHA1 circular left shift macro
+*/
+
+#define SHA1CircularShift(bits,word) \
+ (((word) << (bits)) | ((word) >> (32-(bits))))
+
+/* Local Function Prototyptes */
+static void SHA1PadMessage(SHA1_CONTEXT*);
+static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
+
+
+/*
+ Initialize SHA1Context
+
+ SYNOPSIS
+ sha1_reset()
+ context [in/out] The context to reset.
+
+ DESCRIPTION
+ This function will initialize the SHA1Context in preparation
+ for computing a new SHA1 message digest.
+
+ RETURN
+ SHA_SUCCESS ok
+ != SHA_SUCCESS sha Error Code.
+*/
+
+
+const uint32 sha_const_key[5]=
+{
+ 0x67452301,
+ 0xEFCDAB89,
+ 0x98BADCFE,
+ 0x10325476,
+ 0xC3D2E1F0
+};
+
+
+int sha1_reset(SHA1_CONTEXT *context)
+{
+#ifndef DBUG_OFF
+ if (!context)
+ return SHA_NULL;
+#endif
+
+ context->Length = 0;
+ context->Message_Block_Index = 0;
+
+ context->Intermediate_Hash[0] = sha_const_key[0];
+ context->Intermediate_Hash[1] = sha_const_key[1];
+ context->Intermediate_Hash[2] = sha_const_key[2];
+ context->Intermediate_Hash[3] = sha_const_key[3];
+ context->Intermediate_Hash[4] = sha_const_key[4];
+
+ context->Computed = 0;
+ context->Corrupted = 0;
+
+ return SHA_SUCCESS;
+}
+
+
+/*
+ Return the 160-bit message digest into the array provided by the caller
+
+ SYNOPSIS
+ sha1_result()
+ context [in/out] The context to use to calculate the SHA-1 hash.
+ Message_Digest: [out] Where the digest is returned.
+
+ DESCRIPTION
+ NOTE: The first octet of hash is stored in the 0th element,
+ the last octet of hash in the 19th element.
+
+ RETURN
+ SHA_SUCCESS ok
+ != SHA_SUCCESS sha Error Code.
+*/
+
+int sha1_result(SHA1_CONTEXT *context,
+ uint8 Message_Digest[SHA1_HASH_SIZE])
+{
+ int i;
+
+#ifndef DBUG_OFF
+ if (!context || !Message_Digest)
+ return SHA_NULL;
+
+ if (context->Corrupted)
+ return context->Corrupted;
+#endif
+
+ if (!context->Computed)
+ {
+ SHA1PadMessage(context);
+ /* message may be sensitive, clear it out */
+ bzero((char*) context->Message_Block,64);
+ context->Length = 0; /* and clear length */
+ context->Computed = 1;
+ }
+
+ for (i = 0; i < SHA1_HASH_SIZE; i++)
+ Message_Digest[i] = (int8)((context->Intermediate_Hash[i>>2] >> 8
+ * ( 3 - ( i & 0x03 ) )));
+ return SHA_SUCCESS;
+}
+
+
+/*
+ Accepts an array of octets as the next portion of the message.
+
+ SYNOPSIS
+ sha1_input()
+ context [in/out] The SHA context to update
+ message_array An array of characters representing the next portion
+ of the message.
+ length The length of the message in message_array
+
+ RETURN
+ SHA_SUCCESS ok
+ != SHA_SUCCESS sha Error Code.
+*/
+
+int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
+ unsigned length)
+{
+ if (!length)
+ return SHA_SUCCESS;
+
+#ifndef DBUG_OFF
+ /* We assume client konows what it is doing in non-debug mode */
+ if (!context || !message_array)
+ return SHA_NULL;
+ if (context->Computed)
+ return (context->Corrupted= SHA_STATE_ERROR);
+ if (context->Corrupted)
+ return context->Corrupted;
+#endif
+
+ while (length--)
+ {
+ context->Message_Block[context->Message_Block_Index++]=
+ (*message_array & 0xFF);
+ context->Length += 8; /* Length is in bits */
+
+#ifndef DBUG_OFF
+ /*
+ Then we're not debugging we assume we never will get message longer
+ 2^64 bits.
+ */
+ if (context->Length == 0)
+ return (context->Corrupted= 1); /* Message is too long */
+#endif
+
+ if (context->Message_Block_Index == 64)
+ {
+ SHA1ProcessMessageBlock(context);
+ }
+ message_array++;
+ }
+ return SHA_SUCCESS;
+}
+
+
+/*
+ Process the next 512 bits of the message stored in the Message_Block array.
+
+ SYNOPSIS
+ SHA1ProcessMessageBlock()
+
+ DESCRIPTION
+ Many of the variable names in this code, especially the single
+ character names, were used because those were the names used in
+ the publication.
+*/
+
+/* Constants defined in SHA-1 */
+static const uint32 K[]=
+{
+ 0x5A827999,
+ 0x6ED9EBA1,
+ 0x8F1BBCDC,
+ 0xCA62C1D6
+};
+
+
+static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
+{
+ int t; /* Loop counter */
+ uint32 temp; /* Temporary word value */
+ uint32 W[80]; /* Word sequence */
+ uint32 A, B, C, D, E; /* Word buffers */
+ int index;
+
+ /*
+ Initialize the first 16 words in the array W
+ */
+
+ for (t = 0; t < 16; t++)
+ {
+ index=t*4;
+ W[t] = context->Message_Block[index] << 24;
+ W[t] |= context->Message_Block[index + 1] << 16;
+ W[t] |= context->Message_Block[index + 2] << 8;
+ W[t] |= context->Message_Block[index + 3];
+ }
+
+
+ for (t = 16; t < 80; t++)
+ {
+ W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+ }
+
+ A = context->Intermediate_Hash[0];
+ B = context->Intermediate_Hash[1];
+ C = context->Intermediate_Hash[2];
+ D = context->Intermediate_Hash[3];
+ E = context->Intermediate_Hash[4];
+
+ for (t = 0; t < 20; t++)
+ {
+ temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 20; t < 40; t++)
+ {
+ temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 40; t < 60; t++)
+ {
+ temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] +
+ K[2]);
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 60; t < 80; t++)
+ {
+ temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
+ E = D;
+ D = C;
+ C = SHA1CircularShift(30,B);
+ B = A;
+ A = temp;
+ }
+
+ context->Intermediate_Hash[0] += A;
+ context->Intermediate_Hash[1] += B;
+ context->Intermediate_Hash[2] += C;
+ context->Intermediate_Hash[3] += D;
+ context->Intermediate_Hash[4] += E;
+
+ context->Message_Block_Index = 0;
+}
+
+
+/*
+ Pad message
+
+ SYNOPSIS
+ SHA1PadMessage()
+ context: [in/out] The context to pad
+
+ DESCRIPTION
+ According to the standard, the message must be padded to an even
+ 512 bits. The first padding bit must be a '1'. The last 64 bits
+ represent the length of the original message. All bits in between
+ should be 0. This function will pad the message according to
+ those rules by filling the Message_Block array accordingly. It
+ will also call the ProcessMessageBlock function provided
+ appropriately. When it returns, it can be assumed that the message
+ digest has been computed.
+
+*/
+
+void SHA1PadMessage(SHA1_CONTEXT *context)
+{
+ /*
+ Check to see if the current message block is too small to hold
+ the initial padding bits and length. If so, we will pad the
+ block, process it, and then continue padding into a second
+ block.
+ */
+
+ int i=context->Message_Block_Index;
+
+ if (i > 55)
+ {
+ context->Message_Block[i++] = 0x80;
+ bzero((char*) &context->Message_Block[i],
+ sizeof(context->Message_Block[0])*(64-i));
+ context->Message_Block_Index=64;
+
+ /* This function sets context->Message_Block_Index to zero */
+ SHA1ProcessMessageBlock(context);
+
+ bzero((char*) &context->Message_Block[0],
+ sizeof(context->Message_Block[0])*56);
+ context->Message_Block_Index=56;
+ }
+ else
+ {
+ context->Message_Block[i++] = 0x80;
+ bzero((char*) &context->Message_Block[i],
+ sizeof(context->Message_Block[0])*(56-i));
+ context->Message_Block_Index=56;
+ }
+
+ /*
+ Store the message length as the last 8 octets
+ */
+
+ context->Message_Block[56] = (int8) (context->Length >> 56);
+ context->Message_Block[57] = (int8) (context->Length >> 48);
+ context->Message_Block[58] = (int8) (context->Length >> 40);
+ context->Message_Block[59] = (int8) (context->Length >> 32);
+ context->Message_Block[60] = (int8) (context->Length >> 24);
+ context->Message_Block[61] = (int8) (context->Length >> 16);
+ context->Message_Block[62] = (int8) (context->Length >> 8);
+ context->Message_Block[63] = (int8) (context->Length);
+
+ SHA1ProcessMessageBlock(context);
+}
diff --git a/mysys/string.c b/mysys/string.c
index 96a503c1179..ea747bc9847 100644
--- a/mysys/string.c
+++ b/mysys/string.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Code for handling strings with can grow dynamicly.
@@ -51,7 +50,7 @@ my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str)
{
- uint length;
+ uint length=0;
DBUG_ENTER("dynstr_set");
if (init_str && (length= (uint) strlen(init_str)+1) > str->max_length)
diff --git a/mysys/test_charset.c b/mysys/test_charset.c
index 6a5183d2cd3..15e46f3ff82 100644
--- a/mysys/test_charset.c
+++ b/mysys/test_charset.c
@@ -1,21 +1,20 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-#include <global.h>
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <mysql_version.h>
diff --git a/mysys/test_dir.c b/mysys/test_dir.c
index fafdde137b6..f3d220e942f 100644
--- a/mysys/test_dir.c
+++ b/mysys/test_dir.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* TODO: Test all functions */
diff --git a/mysys/test_fn.c b/mysys/test_fn.c
index 224b899ebe1..5a0546392ab 100644
--- a/mysys/test_fn.c
+++ b/mysys/test_fn.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
diff --git a/mysys/testhash.c b/mysys/testhash.c
index a8fbf800595..a1d14dc225d 100644
--- a/mysys/testhash.c
+++ b/mysys/testhash.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Test av hash libarary: stor test */
+/* Test of hash library: big test */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <hash.h>
#include <m_string.h>
@@ -37,6 +36,7 @@ static uint16 key1[1000];
#else
my_bool hash_check(HASH *hash);
#endif
+
void free_record(void *record);
static byte *hash2_key(const byte *rec,uint *length,
@@ -46,7 +46,7 @@ static byte *hash2_key(const byte *rec,uint *length,
return (byte*) rec;
}
- /* Huvudprogrammet */
+/* main program */
int main(int argc,char *argv[])
{
@@ -76,7 +76,7 @@ static int do_test()
printf("- Creating hash\n");
if (hash_init(&hash,recant/2,0,6,0,free_record,0))
goto err;
- printf("- Writing records:s\n");
+ printf("- Writing records:\n");
for (i=0 ; i < recant ; i++)
{
@@ -243,8 +243,8 @@ err:
} /* main */
- /* l{ser optioner */
- /* OBS! intierar endast DEBUG - ingen debuggning h{r ! */
+/* read options */
+/* NOTE! DBUG not initialised - no debugging here! */
static int get_options(int argc, char **argv)
{
@@ -265,7 +265,7 @@ static int get_options(int argc, char **argv)
case 'I':
case '?':
printf("%s Ver 1.0 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
- puts("TCX Datakonsult AB, by Monty, for your professional use\n");
+ printf("MySQL AB, by Monty\n\n");
printf("Usage: %s [-?ABIKLWv] [-m#] [-t#]\n",progname);
exit(0);
case '#':
@@ -275,9 +275,10 @@ static int get_options(int argc, char **argv)
}
}
return 0;
-} /* get options */
+} /* get_options */
+
- /* Ge ett randomv{rde inom ett intervall 0 <=x <= n */
+/* Get a random number in the interval 0 <= x <= n */
static int rnd(int max_value)
{
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index 564d46aca3a..54aa4d421f6 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -1,21 +1,23 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-#include <global.h>
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* To avoid problems with alarms in debug code, we disable DBUG here */
+#undef DBUG_OFF
+#define DBUG_OFF
+#include <my_global.h>
#if defined(THREAD) && !defined(DONT_USE_THR_ALARM)
#include <errno.h>
@@ -25,6 +27,7 @@
#include <m_string.h>
#include <queues.h>
#include "thr_alarm.h"
+#include <assert.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h> /* AIX needs this for fd_set */
@@ -34,18 +37,22 @@
#define ETIME ETIMEDOUT
#endif
-static my_bool alarm_aborted=1;
-my_bool thr_alarm_inited=0;
+static int alarm_aborted=1; /* No alarm thread */
+my_bool thr_alarm_inited= 0;
+volatile my_bool alarm_thread_running= 0;
+
+static sig_handler process_alarm_part2(int sig);
#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
static pthread_mutex_t LOCK_alarm;
+static pthread_cond_t COND_alarm;
static sigset_t full_signal_set;
static QUEUE alarm_queue;
+static uint max_used_alarms=0;
pthread_t alarm_thread;
#ifdef USE_ALARM_THREAD
-static pthread_cond_t COND_alarm;
static void *alarm_handler(void *arg);
#define reschedule_alarms() pthread_cond_signal(&COND_alarm)
#else
@@ -72,6 +79,7 @@ void init_thr_alarm(uint max_alarms)
compare_ulong,NullS);
sigfillset(&full_signal_set); /* Neaded to block signals */
pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&COND_alarm,NULL);
#if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD)
#if defined(HAVE_mit_thread)
sigset(THR_CLIENT_ALARM,thread_alarm); /* int. thread system calls */
@@ -91,7 +99,6 @@ void init_thr_alarm(uint max_alarms)
{
pthread_attr_t thr_attr;
pthread_attr_init(&thr_attr);
- pthread_cond_init(&COND_alarm,NULL);
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&thr_attr,8196);
@@ -113,14 +120,40 @@ void init_thr_alarm(uint max_alarms)
DBUG_VOID_RETURN;
}
+
+void resize_thr_alarm(uint max_alarms)
+{
+ pthread_mutex_lock(&LOCK_alarm);
+ /*
+ It's ok not to shrink the queue as there may be more pending alarms than
+ than max_alarms
+ */
+ if (alarm_queue.elements < max_alarms)
+ resize_queue(&alarm_queue,max_alarms+1);
+ pthread_mutex_unlock(&LOCK_alarm);
+}
+
+
/*
-** Request alarm after sec seconds.
-** A pointer is returned with points to a non-zero int when the alarm has been
-** given. This can't be called from the alarm-handling thread.
-** Returns 0 if no more alarms are allowed (aborted by process)
+ Request alarm after sec seconds.
+
+ SYNOPSIS
+ thr_alarm()
+ alrm Pointer to alarm detection
+ alarm_data Structure to store in alarm queue
+
+ NOTES
+ This function can't be called from the alarm-handling thread.
+
+ RETURN VALUES
+ 0 ok
+ 1 If no more alarms are allowed (aborted by process)
+
+ Stores in first argument a pointer to a non-zero int which is set to 0
+ when the alarm has been given
*/
-bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
+my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
{
ulong now;
sigset_t old_mask;
@@ -131,20 +164,29 @@ bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
now=(ulong) time((time_t*) 0);
pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
- if (alarm_aborted)
+ if (alarm_aborted > 0)
{ /* No signal thread */
DBUG_PRINT("info", ("alarm aborted"));
+ *alrm= 0; /* No alarm */
pthread_mutex_unlock(&LOCK_alarm);
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
DBUG_RETURN(1);
}
- if (alarm_queue.elements == alarm_queue.max_elements)
+ if (alarm_aborted < 0)
+ sec= 1; /* Abort mode */
+
+ if (alarm_queue.elements >= max_used_alarms)
{
- DBUG_PRINT("info", ("alarm queue full"));
- fprintf(stderr,"Warning: thr_alarm queue is full\n");
- pthread_mutex_unlock(&LOCK_alarm);
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
- DBUG_RETURN(1);
+ if (alarm_queue.elements == alarm_queue.max_elements)
+ {
+ DBUG_PRINT("info", ("alarm queue full"));
+ fprintf(stderr,"Warning: thr_alarm queue is full\n");
+ *alrm= 0; /* No alarm */
+ pthread_mutex_unlock(&LOCK_alarm);
+ pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
+ DBUG_RETURN(1);
+ }
+ max_used_alarms=alarm_queue.elements+1;
}
reschedule= (!alarm_queue.elements ||
(int) (((ALARM*) queue_top(&alarm_queue))->expire_time - now) >
@@ -154,6 +196,7 @@ bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
{
DBUG_PRINT("info", ("failed my_malloc()"));
+ *alrm= 0; /* No alarm */
pthread_mutex_unlock(&LOCK_alarm);
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
DBUG_RETURN(1);
@@ -184,15 +227,14 @@ bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
/*
-** Remove alarm from list of alarms
+ Remove alarm from list of alarms
*/
void thr_end_alarm(thr_alarm_t *alarmed)
{
ALARM *alarm_data;
sigset_t old_mask;
- uint i;
- bool found=0;
+ uint i, found=0;
DBUG_ENTER("thr_end_alarm");
pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
@@ -206,39 +248,40 @@ void thr_end_alarm(thr_alarm_t *alarmed)
queue_remove(&alarm_queue,i),MYF(0);
if (alarm_data->malloced)
my_free((gptr) alarm_data,MYF(0));
- found=1;
+ found++;
+#ifndef DBUG_OFF
break;
+#endif
}
}
+ DBUG_ASSERT(!*alarmed || found == 1);
if (!found)
{
-#ifdef MAIN
- printf("Warning: Didn't find alarm %lx in queue of %d alarms\n",
- (long) *alarmed, alarm_queue.elements);
-#endif
- DBUG_PRINT("warning",("Didn't find alarm %lx in queue\n",*alarmed));
+ if (*alarmed)
+ fprintf(stderr,"Warning: Didn't find alarm %lx in queue of %d alarms\n",
+ (long) *alarmed, alarm_queue.elements);
+ DBUG_PRINT("warning",("Didn't find alarm %lx in queue\n",
+ (long) *alarmed));
}
- if (alarm_aborted && !alarm_queue.elements)
- delete_queue(&alarm_queue);
pthread_mutex_unlock(&LOCK_alarm);
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
DBUG_VOID_RETURN;
}
- /*
- Come here when some alarm in queue is due.
- Mark all alarms with are finnished in list.
- Shedule alarms to be sent again after 1-10 sec (many alarms at once)
- If alarm_aborted is set then all alarms are given and resent
- every second.
- */
+/*
+ Come here when some alarm in queue is due.
+ Mark all alarms with are finnished in list.
+ Shedule alarms to be sent again after 1-10 sec (many alarms at once)
+ If alarm_aborted is set then all alarms are given and resent
+ every second.
+*/
sig_handler process_alarm(int sig __attribute__((unused)))
{
sigset_t old_mask;
- ALARM *alarm_data;
- DBUG_ENTER("process_alarm");
- DBUG_PRINT("info",("sig: %d active alarms: %d",sig,alarm_queue.elements));
+/*
+ This must be first as we can't call DBUG inside an alarm for a normal thread
+*/
#if THR_SERVER_ALARM == THR_CLIENT_ALARM
if (!pthread_equal(pthread_self(),alarm_thread))
@@ -249,17 +292,42 @@ sig_handler process_alarm(int sig __attribute__((unused)))
#ifdef DONT_REMEMBER_SIGNAL
sigset(THR_CLIENT_ALARM,process_alarm); /* int. thread system calls */
#endif
- DBUG_VOID_RETURN;
+ return;
}
#endif
-#if defined(MAIN) && !defined(__bsdi__)
- printf("process_alarm\n"); fflush(stdout);
-#endif
+ /*
+ We have to do do the handling of the alarm in a sub function,
+ because otherwise we would get problems with two threads calling
+ DBUG_... functions at the same time (as two threads may call
+ process_alarm() at the same time
+ */
+
#ifndef USE_ALARM_THREAD
pthread_sigmask(SIG_SETMASK,&full_signal_set,&old_mask);
pthread_mutex_lock(&LOCK_alarm);
#endif
+ process_alarm_part2(sig);
+#ifndef USE_ALARM_THREAD
+#if defined(DONT_REMEMBER_SIGNAL) && !defined(USE_ONE_SIGNAL_HAND)
+ sigset(THR_SERVER_ALARM,process_alarm);
+#endif
+ pthread_mutex_unlock(&LOCK_alarm);
+ pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
+#endif
+ return;
+}
+
+
+static sig_handler process_alarm_part2(int sig __attribute__((unused)))
+{
+ ALARM *alarm_data;
+ DBUG_ENTER("process_alarm");
+ DBUG_PRINT("info",("sig: %d active alarms: %d",sig,alarm_queue.elements));
+
+#if defined(MAIN) && !defined(__bsdi__)
+ printf("process_alarm\n"); fflush(stdout);
+#endif
if (alarm_queue.elements)
{
if (alarm_aborted)
@@ -320,49 +388,85 @@ sig_handler process_alarm(int sig __attribute__((unused)))
#endif
}
}
-#ifndef USE_ALARM_THREAD
-#if defined(DONT_REMEMBER_SIGNAL) && !defined(USE_ONE_SIGNAL_HAND)
- sigset(THR_SERVER_ALARM,process_alarm);
-#endif
- pthread_mutex_unlock(&LOCK_alarm);
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
DBUG_VOID_RETURN;
}
/*
-** Shedule all alarms now.
-** When all alarms are given, Free alarm memory and don't allow more alarms.
+ Schedule all alarms now and optionally free all structures
+
+ SYNPOSIS
+ end_thr_alarm()
+ free_structures Set to 1 if we should free memory used for
+ the alarm queue.
+ When we call this we should KNOW that there
+ is no active alarms
+ IMPLEMENTATION
+ Set alarm_abort to -1 which will change the behavior of alarms as follows:
+ - All old alarms will be rescheduled at once
+ - All new alarms will be rescheduled to one second
*/
-void end_thr_alarm(void)
+void end_thr_alarm(my_bool free_structures)
{
DBUG_ENTER("end_thr_alarm");
- pthread_mutex_lock(&LOCK_alarm);
- if (!alarm_aborted)
- {
+ if (alarm_aborted != 1) /* If memory not freed */
+ {
+ pthread_mutex_lock(&LOCK_alarm);
DBUG_PRINT("info",("Resheduling %d waiting alarms",alarm_queue.elements));
- alarm_aborted=1; /* mark aborted */
- if (!alarm_queue.elements)
- delete_queue(&alarm_queue);
- if (pthread_equal(pthread_self(),alarm_thread))
- alarm(1); /* Shut down everything soon */
+ alarm_aborted= -1; /* mark aborted */
+ if (alarm_queue.elements || (alarm_thread_running && free_structures))
+ {
+ if (pthread_equal(pthread_self(),alarm_thread))
+ alarm(1); /* Shut down everything soon */
+ else
+ reschedule_alarms();
+ }
+ if (free_structures)
+ {
+ struct timespec abstime;
+ /*
+ The following test is just for safety, the caller should not
+ depend on this
+ */
+ DBUG_ASSERT(!alarm_queue.elements);
+ /* Wait until alarm thread dies */
+
+ set_timespec(abstime, 10); /* Wait up to 10 seconds */
+ while (alarm_thread_running)
+ {
+ int error= pthread_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime);
+ if (error == ETIME || error == ETIMEDOUT)
+ break; /* Don't wait forever */
+ }
+ if (!alarm_queue.elements)
+ {
+ delete_queue(&alarm_queue);
+ alarm_aborted= 1;
+ pthread_mutex_unlock(&LOCK_alarm);
+ if (!alarm_thread_running) /* Safety */
+ {
+ pthread_mutex_destroy(&LOCK_alarm);
+ pthread_cond_destroy(&COND_alarm);
+ }
+ }
+ }
else
- reschedule_alarms();
+ pthread_mutex_unlock(&LOCK_alarm);
}
- pthread_mutex_unlock(&LOCK_alarm);
DBUG_VOID_RETURN;
}
/*
-** Remove another thread from the alarm
+ Remove another thread from the alarm
*/
void thr_alarm_kill(pthread_t thread_id)
{
uint i;
+ if (alarm_aborted)
+ return;
pthread_mutex_lock(&LOCK_alarm);
for (i=0 ; i < alarm_queue.elements ; i++)
{
@@ -380,9 +484,25 @@ void thr_alarm_kill(pthread_t thread_id)
}
+void thr_alarm_info(ALARM_INFO *info)
+{
+ pthread_mutex_lock(&LOCK_alarm);
+ info->next_alarm_time= 0;
+ info->max_used_alarms= max_used_alarms;
+ if ((info->active_alarms= alarm_queue.elements))
+ {
+ ulong now=(ulong) time((time_t*) 0);
+ long time_diff;
+ ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
+ time_diff= (long) (alarm_data->expire_time - now);
+ info->next_alarm_time= (ulong) (time_diff < 0 ? 0 : time_diff);
+ }
+ pthread_mutex_unlock(&LOCK_alarm);
+}
+
/*
-** This is here for thread to get interruptet from read/write/fcntl
-** ARGSUSED
+ This is here for thread to get interruptet from read/write/fcntl
+ ARGSUSED
*/
#if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD)
@@ -414,6 +534,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
puts("Starting alarm thread");
#endif
my_thread_init();
+ alarm_thread_running= 1;
pthread_mutex_lock(&LOCK_alarm);
for (;;)
{
@@ -438,7 +559,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
}
}
}
- else if (alarm_aborted)
+ else if (alarm_aborted == -1)
break;
else if ((error=pthread_cond_wait(&COND_alarm,&LOCK_alarm)))
{
@@ -450,6 +571,8 @@ static void *alarm_handler(void *arg __attribute__((unused)))
process_alarm(0);
}
bzero((char*) &alarm_thread,sizeof(alarm_thread)); /* For easy debugging */
+ alarm_thread_running= 0;
+ pthread_cond_signal(&COND_alarm);
pthread_mutex_unlock(&LOCK_alarm);
pthread_exit(0);
return 0; /* Impossible */
@@ -457,7 +580,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
#endif /* USE_ALARM_THREAD */
/*****************************************************************************
-** thr_alarm for OS/2
+ thr_alarm for OS/2
*****************************************************************************/
#elif defined(__EMX__) || defined(OS2)
@@ -488,7 +611,7 @@ sig_handler process_alarm(int sig __attribute__((unused)))
/*
-** Remove another thread from the alarm
+ Remove another thread from the alarm
*/
void thr_alarm_kill(pthread_t thread_id)
@@ -572,7 +695,7 @@ void thr_end_alarm(thr_alarm_t *alrm_ptr)
}
}
-void end_thr_alarm(void)
+void end_thr_alarm(my_bool free_structures)
{
DBUG_ENTER("end_thr_alarm");
alarm_aborted=1; /* No more alarms */
@@ -586,8 +709,17 @@ void init_thr_alarm(uint max_alarm)
DBUG_VOID_RETURN;
}
+void thr_alarm_info(ALARM_INFO *info)
+{
+ bzero((char*) info, sizeof(*info));
+}
+
+void resize_thr_alarm(uint max_alarms)
+{
+}
+
/*****************************************************************************
-** thr_alarm for win95
+ thr_alarm for win95
*****************************************************************************/
#else /* __WIN__ */
@@ -603,8 +735,9 @@ sig_handler process_alarm(int sig __attribute__((unused)))
}
-bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm)
+my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm)
{
+ (*alrm)= &alarm->alarmed;
if (alarm_aborted)
{
alarm->alarmed.crono=0;
@@ -613,7 +746,6 @@ bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm)
if (!(alarm->alarmed.crono=SetTimer((HWND) NULL,0, sec*1000,
(TIMERPROC) NULL)))
return 1;
- (*alrm)= &alarm->alarmed;
return 0;
}
@@ -640,13 +772,14 @@ void thr_end_alarm(thr_alarm_t *alrm_ptr)
thr_alarm_t alrm= *alrm_ptr;
/* alrm may be zero if thr_alarm aborted with an error */
if (alrm && alrm->crono)
+
{
KillTimer(NULL, alrm->crono);
alrm->crono = 0;
}
}
-void end_thr_alarm(void)
+void end_thr_alarm(my_bool free_structures)
{
DBUG_ENTER("end_thr_alarm");
alarm_aborted=1; /* No more alarms */
@@ -660,13 +793,22 @@ void init_thr_alarm(uint max_alarm)
DBUG_VOID_RETURN;
}
+void thr_alarm_info(ALARM_INFO *info)
+{
+ bzero((char*) info, sizeof(*info));
+}
+
+void resize_thr_alarm(uint max_alarms)
+{
+}
+
#endif /* __WIN__ */
#endif /* THREAD */
/****************************************************************************
-** Handling of MAIN
+ Handling of test case (when compiled with -DMAIN)
***************************************************************************/
#ifdef MAIN
@@ -676,11 +818,11 @@ static pthread_cond_t COND_thread_count;
static pthread_mutex_t LOCK_thread_count;
static uint thread_count;
-#ifdef HPUX
+#ifdef HPUX10
typedef int * fd_set_ptr;
#else
typedef fd_set * fd_set_ptr;
-#endif /* HPUX */
+#endif /* HPUX10 */
static void *test_thread(void *arg)
{
@@ -840,7 +982,7 @@ static void *signal_hand(void *arg __attribute__((unused)))
case SIGHUP:
#endif
printf("Aborting nicely\n");
- end_thr_alarm();
+ end_thr_alarm(0);
break;
#ifdef SIGTSTP
case SIGTSTP:
@@ -866,6 +1008,7 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
pthread_attr_t thr_attr;
int i,*param,error;
sigset_t set;
+ ALARM_INFO alarm_info;
MY_INIT(argv[0]);
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '#')
@@ -926,16 +1069,25 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
pthread_attr_destroy(&thr_attr);
pthread_mutex_lock(&LOCK_thread_count);
+ thr_alarm_info(&alarm_info);
+ printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n",
+ alarm_info.active_alarms, alarm_info.max_used_alarms,
+ alarm_info.next_alarm_time);
while (thread_count)
{
VOID(pthread_cond_wait(&COND_thread_count,&LOCK_thread_count));
if (thread_count == 1)
{
printf("Calling end_thr_alarm. This should cancel the last thread\n");
- end_thr_alarm();
+ end_thr_alarm(0);
}
}
pthread_mutex_unlock(&LOCK_thread_count);
+ end_thr_alarm(1);
+ thr_alarm_info(&alarm_info);
+ printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n",
+ alarm_info.active_alarms, alarm_info.max_used_alarms,
+ alarm_info.next_alarm_time);
printf("Test succeeded\n");
return 0;
}
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index aa50877072d..d5236cb1ef9 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Read and write locks for Posix threads. All tread must acquire
@@ -173,10 +172,13 @@ static int check_lock(struct st_lock_list *list, const char* lock_type,
return 0;
}
+
static void check_locks(THR_LOCK *lock, const char *where,
my_bool allow_no_locks)
{
uint old_found_errors=found_errors;
+ DBUG_ENTER("check_locks");
+
if (found_errors < MAX_FOUND_ERRORS)
{
if (check_lock(&lock->write,"write",where,1,1) |
@@ -253,18 +255,21 @@ static void check_locks(THR_LOCK *lock, const char *where,
}
if (lock->read.data)
{
- if ((!pthread_equal(lock->write.data->thread,
- lock->read.data->thread) &&
- lock->write.data->type > TL_WRITE_DELAYED &&
- lock->write.data->type != TL_WRITE_ONLY) ||
- ((lock->write.data->type == TL_WRITE_CONCURRENT_INSERT ||
- lock->write.data->type == TL_WRITE_ALLOW_WRITE) &&
- lock->read_no_write_count))
+ if (!pthread_equal(lock->write.data->thread,
+ lock->read.data->thread) &&
+ ((lock->write.data->type > TL_WRITE_DELAYED &&
+ lock->write.data->type != TL_WRITE_ONLY) ||
+ ((lock->write.data->type == TL_WRITE_CONCURRENT_INSERT ||
+ lock->write.data->type == TL_WRITE_ALLOW_WRITE) &&
+ lock->read_no_write_count)))
{
found_errors++;
fprintf(stderr,
"Warning at '%s': Found lock of type %d that is write and read locked\n",
where, lock->write.data->type);
+ DBUG_PRINT("warning",("At '%s': Found lock of type %d that is write and read locked\n",
+ where, lock->write.data->type));
+
}
}
if (lock->read_wait.data)
@@ -287,6 +292,7 @@ static void check_locks(THR_LOCK *lock, const char *where,
DBUG_PRINT("error",("Found wrong lock"));
}
}
+ DBUG_VOID_RETURN;
}
#else /* EXTRA_DEBUG */
@@ -946,6 +952,54 @@ void thr_abort_locks(THR_LOCK *lock)
}
+/*
+ Abort all locks for specific table/thread combination
+
+ This is used to abort all locks for a specific thread
+*/
+
+void thr_abort_locks_for_thread(THR_LOCK *lock, pthread_t thread)
+{
+ THR_LOCK_DATA *data;
+ DBUG_ENTER("thr_abort_locks_for_thread");
+
+ pthread_mutex_lock(&lock->mutex);
+ for (data= lock->read_wait.data; data ; data= data->next)
+ {
+ if (pthread_equal(thread, data->thread))
+ {
+ DBUG_PRINT("info",("Aborting read-wait lock"));
+ data->type= TL_UNLOCK; /* Mark killed */
+ pthread_cond_signal(data->cond);
+ data->cond= 0; /* Removed from list */
+
+ if (((*data->prev)= data->next))
+ data->next->prev= data->prev;
+ else
+ lock->read_wait.last= data->prev;
+ }
+ }
+ for (data= lock->write_wait.data; data ; data= data->next)
+ {
+ if (pthread_equal(thread, data->thread))
+ {
+ DBUG_PRINT("info",("Aborting write-wait lock"));
+ data->type= TL_UNLOCK;
+ pthread_cond_signal(data->cond);
+ data->cond= 0;
+
+ if (((*data->prev)= data->next))
+ data->next->prev= data->prev;
+ else
+ lock->write_wait.last= data->prev;
+ }
+ }
+ pthread_mutex_unlock(&lock->mutex);
+ DBUG_VOID_RETURN;
+}
+
+
+
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index fa7ae4f1e82..3abac2dc737 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -1,33 +1,34 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000-2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This makes a wrapper for mutex handling to make it easier to debug mutex */
-#include <global.h>
+#include <my_global.h>
#if defined(HAVE_LINUXTHREADS) && !defined (__USE_UNIX98)
#define __USE_UNIX98 /* To get rw locks under Linux */
#endif
-#include <m_string.h>
#if defined(THREAD) && defined(SAFE_MUTEX)
#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
-#include <my_pthread.h>
+#include "mysys_priv.h"
+#include "my_static.h"
+#include <m_string.h>
#ifndef DO_NOT_REMOVE_THREAD_WRAPPERS
/* Remove wrappers */
+#undef pthread_mutex_t
#undef pthread_mutex_init
#undef pthread_mutex_lock
#undef pthread_mutex_unlock
@@ -39,23 +40,63 @@
#endif
#endif /* DO_NOT_REMOVE_THREAD_WRAPPERS */
+static pthread_mutex_t THR_LOCK_mutex;
+static ulong safe_mutex_count= 0; /* Number of mutexes created */
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+static struct st_safe_mutex_info_t *safe_mutex_root= NULL;
+#endif
+
+void safe_mutex_global_init(void)
+{
+ pthread_mutex_init(&THR_LOCK_mutex,MY_MUTEX_INIT_FAST);
+}
+
+
int safe_mutex_init(safe_mutex_t *mp,
- const pthread_mutexattr_t *attr __attribute__((unused)))
+ const pthread_mutexattr_t *attr __attribute__((unused)),
+ const char *file __attribute__((unused)),
+ uint line __attribute__((unused)))
{
bzero((char*) mp,sizeof(*mp));
pthread_mutex_init(&mp->global,MY_MUTEX_INIT_ERRCHK);
pthread_mutex_init(&mp->mutex,attr);
+
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+ /*
+ Monitor the freeing of mutexes. This code depends on single thread init
+ and destroy
+ */
+ if ((mp->info= (safe_mutex_info_t *) malloc(sizeof(safe_mutex_info_t))))
+ {
+ struct st_safe_mutex_info_t *info =mp->info;
+
+ info->init_file= (char *) file;
+ info->init_line= line;
+ info->prev= NULL;
+ info->next= NULL;
+
+ pthread_mutex_lock(&THR_LOCK_mutex);
+ if ((info->next= safe_mutex_root))
+ safe_mutex_root->prev= info;
+ safe_mutex_root= info;
+ safe_mutex_count++;
+ pthread_mutex_unlock(&THR_LOCK_mutex);
+ }
+#else
+ thread_safe_increment(safe_mutex_count, &THR_LOCK_mutex);
+#endif /* SAFE_MUTEX_DETECT_DESTROY */
return 0;
}
+
int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
{
int error;
pthread_mutex_lock(&mp->global);
if (mp->count > 0 && pthread_equal(pthread_self(),mp->thread))
{
- fprintf(stderr,"safe_mutex: Trying to lock mutex at %s, line %d, when the mutex was already locked at %s, line %d\n",
- file,line,mp->file,mp->line);
+ fprintf(stderr,"safe_mutex: Trying to lock mutex at %s, line %d, when the mutex was already locked at %s, line %d in thread %s\n",
+ file,line,mp->file, mp->line, my_thread_name());
fflush(stderr);
abort();
}
@@ -70,7 +111,8 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
}
if (mp->count++)
{
- fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, line %d more than 1 time\n", file,line);
+ fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, \
+line %d more than 1 time\n", file,line);
fflush(stderr);
abort();
}
@@ -108,7 +150,7 @@ int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line)
error=pthread_mutex_unlock(&mp->mutex);
if (error)
{
- fprintf(stderr,"safe_mutex: Got error: %d when trying to unlock mutex at %s, line %d\n", error, file, line);
+ fprintf(stderr,"safe_mutex: Got error: %d (%d) when trying to unlock mutex at %s, line %d\n", error, errno, file, line);
fflush(stderr);
abort();
}
@@ -149,7 +191,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
pthread_mutex_lock(&mp->global);
if (error)
{
- fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_wait at %s, line %d\n", error, file, line);
+ fprintf(stderr,"safe_mutex: Got error: %d (%d) when doing a safe_mutex_wait at %s, line %d\n", error, errno, file, line);
fflush(stderr);
abort();
}
@@ -187,15 +229,15 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
#ifdef EXTRA_DEBUG
if (error && (error != EINTR && error != ETIMEDOUT))
{
- fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_timedwait at %s, line %d\n", error, file, line);
+ fprintf(stderr,"safe_mutex: Got error: %d (%d) when doing a safe_mutex_timedwait at %s, line %d\n", error, errno, file, line);
}
#endif
pthread_mutex_lock(&mp->global);
if (mp->count++)
{
fprintf(stderr,
- "safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d (error: %d)\n",
- mp->count-1, my_thread_id(), file, line, error);
+ "safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d (error: %d (%d))\n",
+ mp->count-1, my_thread_id(), file, line, error, error);
fflush(stderr);
abort();
}
@@ -206,6 +248,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
return error;
}
+
int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
{
int error=0;
@@ -225,7 +268,70 @@ int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
if (pthread_mutex_destroy(&mp->mutex))
error=1;
#endif
+
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+ if (mp->info)
+ {
+ struct st_safe_mutex_info_t *info= mp->info;
+ pthread_mutex_lock(&THR_LOCK_mutex);
+
+ if (info->prev)
+ info->prev->next = info->next;
+ else
+ safe_mutex_root = info->next;
+ if (info->next)
+ info->next->prev = info->prev;
+ safe_mutex_count--;
+
+ pthread_mutex_unlock(&THR_LOCK_mutex);
+ free(info);
+ mp->info= NULL; /* Get crash if double free */
+ }
+#else
+ thread_safe_sub(safe_mutex_count, 1, &THR_LOCK_mutex);
+#endif /* SAFE_MUTEX_DETECT_DESTROY */
return error;
}
+
+/*
+ Free global resources and check that all mutex has been destroyed
+
+ SYNOPSIS
+ safe_mutex_end()
+ file Print errors on this file
+
+ NOTES
+ We can't use DBUG_PRINT() here as we have in my_end() disabled
+ DBUG handling before calling this function.
+
+ In MySQL one may get one warning for a mutex created in my_thr_init.c
+ This is ok, as this thread may not yet have been exited.
+*/
+
+void safe_mutex_end(FILE *file __attribute__((unused)))
+{
+ if (!safe_mutex_count) /* safetly */
+ pthread_mutex_destroy(&THR_LOCK_mutex);
+#ifdef SAFE_MUTEX_DETECT_DESTROY
+ if (!file)
+ return;
+
+ if (safe_mutex_count)
+ {
+ fprintf(file, "Warning: Not destroyed mutex: %lu\n", safe_mutex_count);
+ (void) fflush(file);
+ }
+ {
+ struct st_safe_mutex_info_t *ptr;
+ for (ptr= safe_mutex_root ; ptr ; ptr= ptr->next)
+ {
+ fprintf(file, "\tMutex initiated at line %4u in '%s'\n",
+ ptr->init_line, ptr->init_file);
+ (void) fflush(file);
+ }
+ }
+#endif /* SAFE_MUTEX_DETECT_DESTROY */
+}
+
#endif /* THREAD && SAFE_MUTEX */
diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c
index d4fe79a06ac..29db2b997a0 100644
--- a/mysys/thr_rwlock.c
+++ b/mysys/thr_rwlock.c
@@ -1,29 +1,30 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Synchronization - readers / writer thread locks */
#include "mysys_priv.h"
#if defined(THREAD) && !defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && !defined(HAVE_RWLOCK_INIT)
+#include <errno.h>
/*
- * Source base from Sun Microsystems SPILT, simplified
- * for MySQL use -- Joshua Chamas
- */
+ Source base from Sun Microsystems SPILT, simplified for MySQL use
+ -- Joshua Chamas
+ Some cleanup and additional code by Monty
+*/
/*
* Multithreaded Demo Source
@@ -58,7 +59,7 @@
* Mountain View, California 94043
*/
-int my_rwlock_init( rw_lock_t *rwp, void *arg __attribute__((unused)))
+int my_rwlock_init(rw_lock_t *rwp, void *arg __attribute__((unused)))
{
pthread_condattr_t cond_attr;
@@ -71,64 +72,101 @@ int my_rwlock_init( rw_lock_t *rwp, void *arg __attribute__((unused)))
rwp->state = 0;
rwp->waiters = 0;
- return( 0 );
+ return(0);
}
-int my_rwlock_destroy( rw_lock_t *rwp ) {
+
+int my_rwlock_destroy(rw_lock_t *rwp)
+{
pthread_mutex_destroy( &rwp->lock );
pthread_cond_destroy( &rwp->readers );
pthread_cond_destroy( &rwp->writers );
-
- return( 0 );
+ return(0);
}
-int my_rw_rdlock( rw_lock_t *rwp ) {
+
+int my_rw_rdlock(rw_lock_t *rwp)
+{
pthread_mutex_lock(&rwp->lock);
- /* active or queued writers */
- while ( ( rwp->state < 0 ) || rwp->waiters )
+ /* active or queued writers */
+ while (( rwp->state < 0 ) || rwp->waiters)
pthread_cond_wait( &rwp->readers, &rwp->lock);
rwp->state++;
pthread_mutex_unlock(&rwp->lock);
+ return(0);
+}
- return( 0 );
+int my_rw_tryrdlock(rw_lock_t *rwp)
+{
+ int res;
+ pthread_mutex_lock(&rwp->lock);
+ if ((rwp->state < 0 ) || rwp->waiters)
+ res= EBUSY; /* Can't get lock */
+ else
+ {
+ res=0;
+ rwp->state++;
+ }
+ pthread_mutex_unlock(&rwp->lock);
+ return(res);
}
-int my_rw_wrlock( rw_lock_t *rwp ) {
+int my_rw_wrlock(rw_lock_t *rwp)
+{
pthread_mutex_lock(&rwp->lock);
- rwp->waiters++; /* another writer queued */
+ rwp->waiters++; /* another writer queued */
- while ( rwp->state )
- pthread_cond_wait( &rwp->writers, &rwp->lock);
+ while (rwp->state)
+ pthread_cond_wait(&rwp->writers, &rwp->lock);
rwp->state = -1;
- --rwp->waiters;
- pthread_mutex_unlock( &rwp->lock );
+ rwp->waiters--;
+ pthread_mutex_unlock(&rwp->lock);
+ return(0);
+}
- return( 0 );
+
+int my_rw_trywrlock(rw_lock_t *rwp)
+{
+ int res;
+ pthread_mutex_lock(&rwp->lock);
+ if (rwp->state)
+ res= EBUSY; /* Can't get lock */
+ else
+ {
+ res=0;
+ rwp->state = -1;
+ }
+ pthread_mutex_unlock(&rwp->lock);
+ return(res);
}
-int my_rw_unlock( rw_lock_t *rwp ) {
+
+int my_rw_unlock(rw_lock_t *rwp)
+{
DBUG_PRINT("rw_unlock",
("state: %d waiters: %d", rwp->state, rwp->waiters));
pthread_mutex_lock(&rwp->lock);
- if ( rwp->state == -1 ) { /* writer releasing */
- rwp->state = 0; /* mark as available */
+ if (rwp->state == -1) /* writer releasing */
+ {
+ rwp->state= 0; /* mark as available */
- if ( rwp->waiters ) /* writers queued */
+ if ( rwp->waiters ) /* writers queued */
pthread_cond_signal( &rwp->writers );
else
pthread_cond_broadcast( &rwp->readers );
- } else {
- if ( --rwp->state == 0 ) /* no more readers */
+ }
+ else
+ {
+ if ( --rwp->state == 0 ) /* no more readers */
pthread_cond_signal( &rwp->writers );
}
pthread_mutex_unlock( &rwp->lock );
-
- return( 0 );
+ return(0);
}
#endif
diff --git a/mysys/tree.c b/mysys/tree.c
index cd05a17fd72..2b5ea717809 100644
--- a/mysys/tree.c
+++ b/mysys/tree.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Code for handling red-black (balanced) binary trees.
@@ -46,7 +45,8 @@
#define BLACK 1
#define RED 0
-#define DEFAULT_ALLOC_SIZE (8192-MALLOC_OVERHEAD)
+#define DEFAULT_ALLOC_SIZE 8192
+#define DEFAULT_ALIGN_SIZE 8192
static void delete_tree_element(TREE *,TREE_ELEMENT *);
static int tree_walk_left_root_right(TREE *,TREE_ELEMENT *,
@@ -62,28 +62,41 @@ static void rb_delete_fixup(TREE *tree,TREE_ELEMENT ***parent);
/* The actuall code for handling binary trees */
-void init_tree(TREE *tree, uint default_alloc_size, int size,
- qsort_cmp compare, my_bool with_delete,
- void (*free_element) (void *))
+#ifndef DBUG_OFF
+static int test_rb_tree(TREE_ELEMENT *element);
+#endif
+
+void init_tree(TREE *tree, uint default_alloc_size, uint memory_limit,
+ int size, qsort_cmp2 compare, my_bool with_delete,
+ tree_element_free free_element, void *custom_arg)
{
DBUG_ENTER("init_tree");
DBUG_PRINT("enter",("tree: %lx size: %d",tree,size));
- if (!default_alloc_size)
+ if (default_alloc_size < DEFAULT_ALLOC_SIZE)
default_alloc_size= DEFAULT_ALLOC_SIZE;
+ default_alloc_size= MY_ALIGN(default_alloc_size, DEFAULT_ALIGN_SIZE);
bzero((gptr) &tree->null_element,sizeof(tree->null_element));
tree->root= &tree->null_element;
tree->compare=compare;
tree->size_of_element=size > 0 ? (uint) size : 0;
+ tree->memory_limit=memory_limit;
tree->free=free_element;
+ tree->allocated=0;
tree->elements_in_tree=0;
+ tree->custom_arg = custom_arg;
tree->null_element.colour=BLACK;
tree->null_element.left=tree->null_element.right=0;
if (!free_element && size >= 0 &&
((uint) size <= sizeof(void*) || ((uint) size & (sizeof(void*)-1))))
{
+ /*
+ We know that the data doesn't have to be aligned (like if the key
+ contains a double), so we can store the data combined with the
+ TREE_ELEMENT.
+ */
tree->offset_to_key=sizeof(TREE_ELEMENT); /* Put key after element */
- /* Fix allocation size so that we don't loose any memory */
+ /* Fix allocation size so that we don't lose any memory */
default_alloc_size/=(sizeof(TREE_ELEMENT)+size);
if (!default_alloc_size)
default_alloc_size=1;
@@ -102,9 +115,9 @@ void init_tree(TREE *tree, uint default_alloc_size, int size,
DBUG_VOID_RETURN;
}
-void delete_tree(TREE *tree)
+static void free_tree(TREE *tree, myf free_flags)
{
- DBUG_ENTER("delete_tree");
+ DBUG_ENTER("free_tree");
DBUG_PRINT("enter",("tree: %lx",tree));
if (tree->root) /* If initialized */
@@ -114,24 +127,43 @@ void delete_tree(TREE *tree)
else
{
if (tree->free)
+ {
+ if (tree->memory_limit)
+ (*tree->free)(NULL, free_init, tree->custom_arg);
delete_tree_element(tree,tree->root);
- free_root(&tree->mem_root,MYF(0));
+ if (tree->memory_limit)
+ (*tree->free)(NULL, free_end, tree->custom_arg);
+ }
+ free_root(&tree->mem_root, free_flags);
}
}
tree->root= &tree->null_element;
tree->elements_in_tree=0;
+ tree->allocated=0;
DBUG_VOID_RETURN;
}
+void delete_tree(TREE* tree)
+{
+ free_tree(tree, MYF(0)); /* my_free() mem_root if applicable */
+}
+
+void reset_tree(TREE* tree)
+{
+ free_tree(tree, MYF(MY_MARK_BLOCKS_FREE));
+ /* do not my_free() mem_root if applicable, just mark blocks as free */
+}
+
+
static void delete_tree_element(TREE *tree, TREE_ELEMENT *element)
{
if (element != &tree->null_element)
{
delete_tree_element(tree,element->left);
- delete_tree_element(tree,element->right);
if (tree->free)
- (*tree->free)(ELEMENT_KEY(tree,element));
+ (*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg);
+ delete_tree_element(tree,element->right);
if (tree->with_delete)
my_free((char*) element,MYF(0));
}
@@ -152,7 +184,8 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size)
for (;;)
{
if (element == &tree->null_element ||
- (cmp=(*tree->compare)(ELEMENT_KEY(tree,element),key)) == 0)
+ (cmp=(*tree->compare)(tree->custom_arg,
+ ELEMENT_KEY(tree,element),key)) == 0)
break;
if (cmp < 0)
{
@@ -165,13 +198,22 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size)
}
if (element == &tree->null_element)
{
+ uint alloc_size=sizeof(TREE_ELEMENT)+key_size+tree->size_of_element;
+ tree->allocated+=alloc_size;
+
+ if (tree->memory_limit && tree->elements_in_tree
+ && tree->allocated > tree->memory_limit)
+ {
+ reset_tree(tree);
+ return tree_insert(tree, key, key_size);
+ }
+
key_size+=tree->size_of_element;
if (tree->with_delete)
- element=(TREE_ELEMENT *) my_malloc(sizeof(TREE_ELEMENT)+key_size,
- MYF(MY_WME));
+ element=(TREE_ELEMENT *) my_malloc(alloc_size, MYF(MY_WME));
else
element=(TREE_ELEMENT *)
- alloc_root(&tree->mem_root,sizeof(TREE_ELEMENT)+key_size);
+ alloc_root(&tree->mem_root,alloc_size);
if (!element)
return(NULL);
**parent=element;
@@ -195,6 +237,7 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size)
}
else
element->count++;
+ DBUG_EXECUTE("check_tree", test_rb_tree(tree->root););
return element;
}
@@ -212,7 +255,8 @@ int tree_delete(TREE *tree, void *key)
{
if (element == &tree->null_element)
return 1; /* Was not in tree */
- if ((cmp=(*tree->compare)(ELEMENT_KEY(tree,element),key)) == 0)
+ if ((cmp=(*tree->compare)(tree->custom_arg,
+ ELEMENT_KEY(tree,element),key)) == 0)
break;
if (cmp < 0)
{
@@ -252,7 +296,7 @@ int tree_delete(TREE *tree, void *key)
if (remove_colour == BLACK)
rb_delete_fixup(tree,parent);
if (tree->free)
- (*tree->free)(ELEMENT_KEY(tree,element));
+ (*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg);
my_free((gptr) element,MYF(0));
tree->elements_in_tree--;
return 0;
@@ -268,7 +312,8 @@ void *tree_search(TREE *tree, void *key)
{
if (element == &tree->null_element)
return (void*) 0;
- if ((cmp=(*tree->compare)(ELEMENT_KEY(tree,element),key)) == 0)
+ if ((cmp=(*tree->compare)(tree->custom_arg,
+ ELEMENT_KEY(tree,element),key)) == 0)
return ELEMENT_KEY(tree,element);
if (cmp < 0)
element=element->right;
@@ -484,8 +529,7 @@ static void rb_delete_fixup(TREE *tree, TREE_ELEMENT ***parent)
x->colour=BLACK;
}
-
-#ifdef TESTING_TREES
+#ifndef DBUG_OFF
/* Test that the proporties for a red-black tree holds */
@@ -511,5 +555,4 @@ static int test_rb_tree(TREE_ELEMENT *element)
}
return -1;
}
-
#endif
diff --git a/mysys/typelib.c b/mysys/typelib.c
index b18959442ae..e2c8eade5c8 100644
--- a/mysys/typelib.c
+++ b/mysys/typelib.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Functions to handle typelib */
@@ -84,7 +83,8 @@ int find_type(my_string x, TYPELIB *typelib, uint full_name)
/* Get name of type nr 'nr' */
/* Warning first type is 1, 0 = empty field */
-void make_type(register my_string to, register uint nr, register TYPELIB *typelib)
+void make_type(register my_string to, register uint nr,
+ register TYPELIB *typelib)
{
DBUG_ENTER("make_type");
if (!nr)
diff --git a/mytest-old.c b/mytest-old.c
new file mode 100644
index 00000000000..8b4029f5e1e
--- /dev/null
+++ b/mytest-old.c
@@ -0,0 +1,169 @@
+/*C4*/
+/****************************************************************/
+/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */
+/* Date: 02/18/1998 */
+/* mytest.c : do some testing of the libmySQL.DLL.... */
+/* */
+/* History: */
+/* 02/18/1998 jw3 also sprach zarathustra.... */
+/****************************************************************/
+
+
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <mysql.h>
+
+#define DEFALT_SQL_STMT "SELECT * FROM db"
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+
+/********************************************************
+**
+** main :-
+**
+********************************************************/
+
+int
+main( int argc, char * argv[] )
+{
+
+ char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], * pszT, szDB[ 50 ] ;
+ int i, j, k, l, x ;
+ MYSQL * myData ;
+ MYSQL_RES * res ;
+ MYSQL_FIELD * fd ;
+ MYSQL_ROW row ;
+
+ //....just curious....
+ printf( "sizeof( MYSQL ) == %d\n", sizeof( MYSQL ) ) ;
+ if ( argc == 2 )
+ {
+ strcpy( szDB, argv[ 1 ] ) ;
+ strcpy( szSQL, DEFALT_SQL_STMT ) ;
+ if (!strcmp(szDB,"--debug"))
+ {
+ strcpy( szDB, "mysql" ) ;
+ printf("Some mysql struct information (size and offset):\n");
+ printf("net:\t%3d %3d\n",sizeof(myData->net),offsetof(MYSQL,net));
+ printf("host:\t%3d %3d\n",sizeof(myData->host),offsetof(MYSQL,host));
+ printf("port:\t%3d %3d\n",sizeof(myData->port),offsetof(MYSQL,port));
+ printf("protocol_version:\t%3d %3d\n",sizeof(myData->protocol_version),
+ offsetof(MYSQL,protocol_version));
+ printf("thread_id:\t%3d %3d\n",sizeof(myData->thread_id),
+ offsetof(MYSQL,thread_id));
+ printf("affected_rows:\t%3d %3d\n",sizeof(myData->affected_rows),
+ offsetof(MYSQL,affected_rows));
+ printf("packet_length:\t%3d %3d\n",sizeof(myData->packet_length),
+ offsetof(MYSQL,packet_length));
+ printf("status:\t%3d %3d\n",sizeof(myData->status),
+ offsetof(MYSQL,status));
+ printf("fields:\t%3d %3d\n",sizeof(myData->fields),
+ offsetof(MYSQL,fields));
+ printf("field_alloc:\t%3d %3d\n",sizeof(myData->field_alloc),
+ offsetof(MYSQL,field_alloc));
+ printf("free_me:\t%3d %3d\n",sizeof(myData->free_me),
+ offsetof(MYSQL,free_me));
+ printf("options:\t%3d %3d\n",sizeof(myData->options),
+ offsetof(MYSQL,options));
+ puts("");
+ }
+ }
+ else if ( argc > 2 ) {
+ strcpy( szDB, argv[ 1 ] ) ;
+ strcpy( szSQL, argv[ 2 ] ) ;
+ }
+ else {
+ strcpy( szDB, "mysql" ) ;
+ strcpy( szSQL, DEFALT_SQL_STMT ) ;
+ }
+ //....
+
+ if ( (myData = mysql_init((MYSQL*) 0)) &&
+ mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT,
+ NULL, 0 ) )
+ {
+ if ( mysql_select_db( myData, szDB ) < 0 ) {
+ printf( "Can't select the %s database !\n", szDB ) ;
+ mysql_close( myData ) ;
+ return 2 ;
+ }
+ }
+ else {
+ printf( "Can't connect to the mysql server on port %d !\n",
+ MYSQL_PORT ) ;
+ mysql_close( myData ) ;
+ return 1 ;
+ }
+ //....
+ if ( ! mysql_query( myData, szSQL ) ) {
+ res = mysql_store_result( myData ) ;
+ i = (int) mysql_num_rows( res ) ; l = 1 ;
+ printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ;
+ //....we can get the field-specific characteristics here....
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ //....
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Record #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ mysql_free_result( res ) ;
+ }
+ else printf( "Couldn't execute %s on the server !\n", szSQL ) ;
+ //....
+ puts( "==== Diagnostic info ====" ) ;
+ pszT = mysql_get_client_info() ;
+ printf( "Client info: %s\n", pszT ) ;
+ //....
+ pszT = mysql_get_host_info( myData ) ;
+ printf( "Host info: %s\n", pszT ) ;
+ //....
+ pszT = mysql_get_server_info( myData ) ;
+ printf( "Server info: %s\n", pszT ) ;
+ //....
+ res = mysql_list_processes( myData ) ; l = 1 ;
+ if (res)
+ {
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Process #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ }
+ else
+ {
+ printf("Got error %s when retreiving processlist\n",mysql_error(myData));
+ }
+ //....
+ res = mysql_list_tables( myData, "%" ) ; l = 1 ;
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Table #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ //....
+ pszT = mysql_stat( myData ) ;
+ puts( pszT ) ;
+ //....
+ mysql_close( myData ) ;
+ return 0 ;
+
+}
diff --git a/netware/BUILD/apply-patch b/netware/BUILD/apply-patch
new file mode 100755
index 00000000000..3fe5a077f9a
--- /dev/null
+++ b/netware/BUILD/apply-patch
@@ -0,0 +1,41 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+# repository directory
+repo_dir=`pwd`
+
+# show usage
+show_usage()
+{
+ cat << EOF
+
+usage: apply-patch
+
+Imports netware/current-changes.patch so that current changes
+for the platform are present on the local repository.
+
+Use from the root directory of the repository, with BitKeeper
+installed.
+
+EOF
+ exit 0;
+}
+
+if test $1 || test -z $BK_USER
+then
+ show_usage
+fi
+
+echo "starting patch..."
+
+echo "user: $BK_USER"
+
+# import patch
+# Note: In future this should be changed to check whether
+# the repo already has this patch
+bk import -tpatch $repo_dir/netware/current-changes.patch $repo_dir
diff --git a/netware/BUILD/compile-AUTOTOOLS b/netware/BUILD/compile-AUTOTOOLS
new file mode 100755
index 00000000000..57213b1b3d0
--- /dev/null
+++ b/netware/BUILD/compile-AUTOTOOLS
@@ -0,0 +1,22 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+for package in . ./innobase
+do
+ (cd $package
+ rm -rf config.cache autom4te.cache
+ aclocal
+ autoheader
+ libtoolize --force
+ aclocal
+ automake --add-missing --force-missing
+ autoconf)
+done
+
+#rm -rf ./bdb/build_unix/config.cache ./bdb/dist/autom4te.cache
+#(cd ./bdb/dist && sh s_all)
diff --git a/netware/BUILD/compile-linux-tools b/netware/BUILD/compile-linux-tools
new file mode 100755
index 00000000000..886f866d674
--- /dev/null
+++ b/netware/BUILD/compile-linux-tools
@@ -0,0 +1,58 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+if test ! -r ./sql/mysqld.cc
+then
+ echo "you must start from the top source directory"
+ exit 1
+fi
+
+path=`dirname $0`
+
+# clean
+if test -e "Makefile"; then make -k clean; fi
+
+# remove files
+rm -f NEW-RPMS/*
+rm -f */.deps/*.P
+rm -f */*.linux
+
+# run autotools
+. $path/compile-AUTOTOOLS
+
+# configure
+./configure --without-innodb --without-docs
+
+# build tools only
+make clean config.h
+(cd dbug; make libdbug.a)
+(cd strings; make libmystrings.a)
+(cd mysys; make libmysys.a)
+(cd heap; make libheap.a)
+(cd vio; make libvio.a)
+(cd regex; make libregex.a)
+(cd isam; make libnisam.a)
+(cd merge; make libmerge.a)
+(cd myisam; make libmyisam.a)
+(cd myisammrg; make libmyisammrg.a)
+(cd extra; make comp_err)
+(cd libmysql; make conf_to_src)
+(cd libmysql_r; make conf_to_src)
+(cd sql; make gen_lex_hash)
+(cd strings; make conf_to_src)
+
+# so the file will be linked
+(cd sql; make sql_yacc.cc)
+
+# copying required linux tools
+cp extra/comp_err extra/comp_err.linux
+cp libmysql/conf_to_src libmysql/conf_to_src.linux
+cp libmysql_r/conf_to_src libmysql_r/conf_to_src.linux
+cp sql/gen_lex_hash sql/gen_lex_hash.linux
+cp strings/conf_to_src strings/conf_to_src.linux
+
diff --git a/netware/BUILD/compile-netware-END b/netware/BUILD/compile-netware-END
new file mode 100755
index 00000000000..2bd59f97114
--- /dev/null
+++ b/netware/BUILD/compile-netware-END
@@ -0,0 +1,41 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+path=`dirname $0`
+
+# clean
+if test -e "Makefile"; then make -k clean; fi
+
+# remove files
+rm -f NEW-RPMS/*
+rm -f */.deps/*.P
+rm -rf Makefile.in.bk
+
+# Metrowerks enviornment
+. $path/mwenv
+
+# run auto tools
+. $path/compile-AUTOTOOLS
+
+# configure
+./configure $base_configs $extra_configs
+
+# make
+make clean bin-dist
+
+# mark the build
+for file in *.tar.gz *.zip
+do
+ if (expr "$file" : "mysql-[1-9].*" > /dev/null)
+ then
+ new_file=`echo $file | sed -e "s/mysql-/mysql-$suffix-/"`
+ if test -e "$new_file"; then mv -f $new_file $new_file.old; fi
+ mv $file $new_file
+ fi
+done
+
diff --git a/netware/BUILD/compile-netware-START b/netware/BUILD/compile-netware-START
new file mode 100755
index 00000000000..7eef192a907
--- /dev/null
+++ b/netware/BUILD/compile-netware-START
@@ -0,0 +1,26 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+if test ! -r ./sql/mysqld.cc
+then
+ echo "you must start from the top source directory"
+ exit 1
+fi
+
+path=`dirname $0`
+
+# stop on errors
+set -e
+
+base_configs=" \
+ --host=i686-pc-netware \
+ --enable-local-infile \
+ --with-extra-charsets=all \
+ --prefix=N:/mysql \
+ "
+
diff --git a/netware/BUILD/compile-netware-all b/netware/BUILD/compile-netware-all
new file mode 100755
index 00000000000..6baff699e94
--- /dev/null
+++ b/netware/BUILD/compile-netware-all
@@ -0,0 +1,15 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+path=`dirname $0`
+
+$path/compile-netware-src
+$path/compile-netware-standard
+$path/compile-netware-debug
+#$path/compile-netware-max
+#$path/compile-netware-max-debug
diff --git a/netware/BUILD/compile-netware-debug b/netware/BUILD/compile-netware-debug
new file mode 100755
index 00000000000..e44d64e3074
--- /dev/null
+++ b/netware/BUILD/compile-netware-debug
@@ -0,0 +1,21 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+path=`dirname $0`
+. $path/compile-netware-START
+
+suffix="debug"
+
+extra_configs=" \
+ --with-innodb \
+ --with-debug=full \
+ "
+
+. $path/compile-netware-END
+
+
diff --git a/netware/BUILD/compile-netware-max b/netware/BUILD/compile-netware-max
new file mode 100644
index 00000000000..ec737d4615c
--- /dev/null
+++ b/netware/BUILD/compile-netware-max
@@ -0,0 +1,23 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+
+path=`dirname $0`
+. $path/compile-netware-START
+
+suffix="max"
+
+extra_configs=" \
+ --with-innodb \
+ --with-embedded-server \
+ --with-openssl \
+ "
+
+. $path/compile-netware-END
+
+
diff --git a/netware/BUILD/compile-netware-max-debug b/netware/BUILD/compile-netware-max-debug
new file mode 100644
index 00000000000..ea3553ae6e1
--- /dev/null
+++ b/netware/BUILD/compile-netware-max-debug
@@ -0,0 +1,23 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+path=`dirname $0`
+. $path/compile-netware-START
+
+suffix="max-debug"
+
+extra_configs=" \
+ --with-innodb \
+ --with-debug=full \
+ --with-embedded-server \
+ --with-openssl \
+ "
+
+. $path/compile-netware-END
+
+
diff --git a/netware/BUILD/compile-netware-src b/netware/BUILD/compile-netware-src
new file mode 100644
index 00000000000..df7f6fcdd1a
--- /dev/null
+++ b/netware/BUILD/compile-netware-src
@@ -0,0 +1,36 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+if test ! -r ./sql/mysqld.cc
+then
+ echo "you must start from the top source directory"
+ exit 1
+fi
+
+path=`dirname $0`
+
+# clean
+if test -e "Makefile"; then
+ make -k clean;
+ make -k distclean;
+fi
+
+# remove other files
+rm -f NEW-RPMS/*
+rm -f */.deps/*.P
+rm -rf Makefile.in.bk
+
+# zip source
+files=`pwd | sed -e "s/.*\\\(mysql-.*\)/\1/"`
+file=`pwd | sed -e "s/.*\\mysql-\(.*\)/mysql-src-\1-pc-netware-i686/"`
+cd ..
+if test -e "$file.zip"; then rm -f $file.zip; fi
+zip -r $file.zip $files -x \*.zip -x \*.tar.gz
+if test -e "./$files/$file.zip"; then mv -f ./$files/$file.zip ./$files/$file.zip.old; fi
+mv -f $file.zip ./$files/$file.zip
+
diff --git a/netware/BUILD/compile-netware-standard b/netware/BUILD/compile-netware-standard
new file mode 100755
index 00000000000..45f5021862c
--- /dev/null
+++ b/netware/BUILD/compile-netware-standard
@@ -0,0 +1,21 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+
+path=`dirname $0`
+. $path/compile-netware-START
+
+suffix="standard"
+
+extra_configs=" \
+ --with-innodb \
+ "
+
+. $path/compile-netware-END
+
+
diff --git a/netware/BUILD/create-patch b/netware/BUILD/create-patch
new file mode 100755
index 00000000000..711eabf2d89
--- /dev/null
+++ b/netware/BUILD/create-patch
@@ -0,0 +1,56 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+# repository direcotry
+repo_dir=`pwd`
+
+# show usage
+show_usage()
+{
+ cat << EOF
+
+usage: create-patch
+
+Creates a patch file between the latest revision of the current tree
+and the latest revision not create by \$BK_USER.
+
+EOF
+ exit 0;
+}
+
+if test $1 || test -z $BK_USER
+then
+ show_usage
+fi
+
+echo "starting patch..."
+
+echo "user: $BK_USER"
+
+# check for bk and repo_dir
+bk help > /dev/null
+repo_dir=`bk root $repo_dir`
+cd $repo_dir
+
+# determine version
+version=`grep -e "AM_INIT_AUTOMAKE(mysql, .*)" < configure.in | sed -e "s/AM_INIT_AUTOMAKE(mysql, \(.*\))/\1/"`
+echo "version: $version"
+
+# user revision
+user_rev=`bk changes -e -n -d':REV:' | head -1`
+echo "latest revision: $user_rev"
+
+# tree revision
+tree_rev=`bk changes -e -n -d':REV:' -U$BK_USER | head -1`
+echo "latest non-$BK_USER revision: $tree_rev"
+
+# create patch
+patch="$repo_dir/../$BK_USER-$version.patch"
+echo "creating \"$patch\"..."
+bk export -tpatch -r$tree_rev..$user_rev > $patch
+
diff --git a/netware/BUILD/cron-build b/netware/BUILD/cron-build
new file mode 100755
index 00000000000..26ccde28e2a
--- /dev/null
+++ b/netware/BUILD/cron-build
@@ -0,0 +1,46 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+# repository direcotry
+repo_dir=`pwd`
+
+# show usage
+show_usage()
+{
+ cat << EOF
+
+usage: cron-patch
+
+EOF
+ exit 0;
+}
+
+echo "starting build..."
+
+# check for bk and repo_dir
+bk help > /dev/null
+repo_dir=`bk root $repo_dir`
+cd $repo_dir
+
+# pull latest code
+echo 'y' | bk pull
+
+# determine version
+version=`grep -e "AM_INIT_AUTOMAKE(mysql, .*)" < configure.in | sed -e "s/AM_INIT_AUTOMAKE(mysql, \(.*\))/\1/"`
+echo "version: $version"
+
+# latest revision
+rev=`bk changes -e -n -d':REV:' | head -1`
+echo "latest revision: $rev"
+
+# run bootstrap
+./netware/BUILD/nwbootstrap --revision=$rev --suffix=$rev --build=all
+
+echo "done"
+
+
diff --git a/netware/BUILD/crontab b/netware/BUILD/crontab
new file mode 100755
index 00000000000..0097f8acaaf
--- /dev/null
+++ b/netware/BUILD/crontab
@@ -0,0 +1,4 @@
+00 23 * * * (export PATH='/usr/local/bin:/usr/bin:/bin'; export DISPLAY=':0'; cd ~/bk/mysqldoc; echo 'y' | bk pull)
+00 00 * * * (export PATH='/usr/local/bin:/usr/bin:/bin'; export DISPLAY=':0'; cd ~/bk/mysql-4.0; ./netware/BUILD/cron-build)
+00 04 * * * (export PATH='/usr/local/bin:/usr/bin:/bin'; export DISPLAY=':0'; cd ~/bk/mysql-4.1; ./netware/BUILD/cron-build)
+
diff --git a/netware/BUILD/knetware.imp b/netware/BUILD/knetware.imp
new file mode 100644
index 00000000000..d9a9372b34f
--- /dev/null
+++ b/netware/BUILD/knetware.imp
@@ -0,0 +1,2 @@
+kYieldIfTimeSliceUp
+
diff --git a/netware/BUILD/mwasmnlm b/netware/BUILD/mwasmnlm
new file mode 100755
index 00000000000..381f84ec0c8
--- /dev/null
+++ b/netware/BUILD/mwasmnlm
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+# stop on errors
+set -e
+
+args=" $*"
+
+wine --debugmsg -all -- mwasmnlm $args
diff --git a/netware/BUILD/mwccnlm b/netware/BUILD/mwccnlm
new file mode 100755
index 00000000000..cb2d62fe8cf
--- /dev/null
+++ b/netware/BUILD/mwccnlm
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+# stop on errors
+set -e
+
+# mwccnlm is having a hard time understanding "-I./../include"
+# convert it to "-I../include"
+args=" "`echo $* | sed -e 's/-I.\/../-I../g'`
+
+wine --debugmsg -all -- mwccnlm $args
diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv
new file mode 100755
index 00000000000..c16ada6552a
--- /dev/null
+++ b/netware/BUILD/mwenv
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+# WINE_BUILD_DIR, BUILD_DIR, and VERSION must be correct before compiling
+# This values are normally changed by the nwbootstrap script
+
+# the default is "F:/mydev"
+export MYDEV="WINE_BUILD_DIR"
+
+export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV"
+export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/mysql-VERSION/netware/BUILD"
+export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib;knetware.imp"
+
+export WINEPATH="$MYDEV/mw/bin"
+
+# the default added path is "$HOME/mydev/mysql-x.x-x/netware/BUILD"
+export PATH="$PATH:BUILD_DIR/mysql-VERSION/netware/BUILD"
+
+export AR='mwldnlm'
+export AR_FLAGS='-type library -o'
+export AS='mwasmnlm'
+export CC='mwccnlm -gccincludes'
+export CFLAGS='-align 8 -proc 686 -relax_pointers -dialect c'
+export CXX='mwccnlm -gccincludes'
+export CXXFLAGS='-align 8 -proc 686 -relax_pointers -dialect c++ -bool on -wchar_t on -D_WCHAR_T'
+export LD='mwldnlm'
+export LDFLAGS='-entry _LibCPrelude -exit _LibCPostlude -map -flags pseudopreemption'
+export RANLIB=:
+export STRIP=:
+
diff --git a/netware/BUILD/mwldnlm b/netware/BUILD/mwldnlm
new file mode 100755
index 00000000000..28566fc5cb1
--- /dev/null
+++ b/netware/BUILD/mwldnlm
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+# stop on errors
+set -e
+
+args=" $*"
+
+wine --debugmsg -all -- mwldnlm $args
diff --git a/netware/BUILD/nwbootstrap b/netware/BUILD/nwbootstrap
new file mode 100755
index 00000000000..f54775bf054
--- /dev/null
+++ b/netware/BUILD/nwbootstrap
@@ -0,0 +1,187 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+path=`dirname $0`
+
+# repository direcotry
+repo_dir=`pwd`
+
+# build directory
+build_dir="$HOME/mydev"
+wine_build_dir="F:/mydev"
+
+# doc directory
+doc_dir="$repo_dir/../mysqldoc"
+
+# init
+target_dir=""
+temp_dir=""
+revision=""
+rev=""
+build=""
+suffix=""
+mwenv=""
+
+# show usage
+show_usage()
+{
+ cat << EOF
+
+usage: nwbootstrap [options]
+
+Exports a revision of the BitKeeper tree (nwbootstrap must be run inside a
+directory of the BitKeeper tree to be used). Creates the ChangeLog file.
+Adds the latest manual.texi from the mysqldoc BitKeeper tree. Builds the
+Linux tools required for cross-platform builds. Optionally, builds the
+binary distributions for NetWare.
+
+options:
+
+--build=<opt> Build the binary distributions for NetWare,
+ where <opt> is "standard", "debug", or "all"
+ (default is to not build a binary distribution)
+
+--build-dir=<dir> Export the BitKeeper tree to the <dir> directroy
+ (default is "$build_dir")
+
+--doc-dir=<dir> Use the mysqldoc BitKeeper tree located in the
+ <dir> directory
+ (default is parallel to current BitKeeper tree)
+
+--help Show this help information
+
+--revision=<rev> Export the BitKeeper tree as of revision <rev>
+ (default is the latest revision)
+
+--wine-build-dir=<dir> Use the WINE directory <dir>, which should
+ correspond to the --build-dir directory
+ (default is "$wine_build_dir")
+
+examples:
+
+ nwbootstrap
+
+ nwbootstrap --revision=1.1594 --build=all
+
+ nwbootstrap --build-dir=/home/jdoe/dev --wine-build-dir=F:/dev
+
+
+EOF
+ exit 0;
+}
+
+# parse arguments
+for arg do
+ case "$arg" in
+ --build-dir=*) build_dir=`echo "$arg" | sed -e "s;--build-dir=;;"` ;;
+ --wine-build-dir=*) wine_build_dir=`echo "$arg" | sed -e "s;--wine-build-dir=;;"` ;;
+ --revision=*) revision=`echo "$arg" | sed -e "s;--revision=;;"` ;;
+ --build=*) build=`echo "$arg" | sed -e "s;--build=;;"` ;;
+ --suffix=*) suffix=`echo "$arg" | sed -e "s;--suffix=;;"` ;;
+ --doc-dir=*) doc_dir=`echo "$arg" | sed -e "s;--doc-dir=;;"` ;;
+ *) show_usage ;;
+ esac
+done
+
+echo "starting build..."
+
+# check for bk and repo_dir
+bk help > /dev/null
+repo_dir=`bk root $repo_dir`
+cd $repo_dir
+doc_dir="$repo_dir/../mysqldoc"
+
+# build temporary directory
+temp_dir="$build_dir/mysql-$$.tmp"
+
+# export the bk tree
+command="bk export";
+if test $revision; then command="$command -r$revision"; fi
+command="$command $temp_dir"
+echo "exporting $repo_dir..."
+$command
+
+# determine version
+version=`grep -e "AM_INIT_AUTOMAKE(mysql, .*)" < $temp_dir/configure.in | sed -e "s/AM_INIT_AUTOMAKE(mysql, \(.*\))/\1/"`
+echo "version: $version"
+
+# build target directory
+target_dir="$build_dir/mysql-$version"
+
+# add suffix
+if test $suffix
+then
+ target_dir="$target_dir-$suffix"
+fi
+
+# delete any old target
+if test -d $target_dir.old; then rm -rf $target_dir.old; fi
+
+# rename old target
+if test -d $target_dir; then mv -f $target_dir $target_dir.old; fi
+
+# rename directory to use version
+mv $temp_dir $target_dir
+
+# create ChangeLog
+if test $revision
+then
+ rev=`bk changes -r..$revision -t -d':REV:' -n | head -2 | tail -1`
+else
+ rev=`bk changes -t -d':REV:' -n | head -1`
+fi
+
+echo "creating ChangeLog..."
+bk changes -v -r$rev..$revision > $target_dir/ChangeLog
+
+# add the latest manual
+if test -d $doc_dir
+then
+ echo "adding the latest manual..."
+ install -m 644 $doc_dir/Docs/{manual,reservedwords}.texi $target_dir/Docs/
+fi
+
+# make files writeable
+echo "making files writable..."
+cd $target_dir
+chmod -R u+rw,g+rw .
+
+# edit the mvenv file
+echo "updating the mwenv environment file..."
+mwenv="./netware/BUILD/mwenv"
+mv -f $mwenv $mwenv.org
+sed -e "s;WINE_BUILD_DIR;$wine_build_dir;g" \
+ -e "s;BUILD_DIR;$build_dir;g" \
+ -e "s;VERSION;$version;g" $mwenv.org > $mwenv
+chmod +rwx $mwenv
+
+# edit the def file versions
+echo "updating *.def file versions..."
+nlm_version=`echo "$version" | sed -e "s;\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*;\1, \2, \3;"`
+
+for file in ./netware/*.def
+do
+ mv -f $file $file.org
+ sed -e "s;VERSION.*;VERSION $nlm_version;g" $file.org > $file
+ rm $file.org
+done
+
+# build linux tools
+echo "compiling linux tools..."
+./netware/BUILD/compile-linux-tools
+
+# compile
+if test $build
+then
+ echo "compiling $build..."
+ ./netware/BUILD/compile-netware-$build
+fi
+
+echo "done"
+
+
diff --git a/netware/BUILD/openssl.imp b/netware/BUILD/openssl.imp
new file mode 100644
index 00000000000..8972ff5d58c
--- /dev/null
+++ b/netware/BUILD/openssl.imp
@@ -0,0 +1,9 @@
+WS2_32_shutdown
+WS2_32_closesocket
+WSASetLastError
+WS2_32_recv
+WSASetLastError
+WS2_32_send
+WSAGetLastError
+GetProcessSwitchCount
+RunningProcess
diff --git a/netware/BUILD/save-patch b/netware/BUILD/save-patch
new file mode 100755
index 00000000000..9f9979ace5b
--- /dev/null
+++ b/netware/BUILD/save-patch
@@ -0,0 +1,56 @@
+#! /bin/sh
+
+# debug
+#set -x
+
+# stop on errors
+set -e
+
+# repository directory
+repo_dir=`pwd`
+
+# show usage
+show_usage()
+{
+ cat << EOF
+
+usage: save-patch
+
+Creates a patch file between the latest revision of the current tree
+and the latest revision not created by \$BK_USER and places it in
+the tree as netware/current-changes.patch
+
+EOF
+ exit 0;
+}
+
+if test $1 || test -z $BK_USER
+then
+ show_usage
+fi
+
+echo "starting patch..."
+
+echo "user: $BK_USER"
+
+# check for bk and repo_dir
+bk help > /dev/null
+repo_dir=`bk root $repo_dir`
+cd $repo_dir
+
+# determine version
+version=`grep -e "AM_INIT_AUTOMAKE(mysql, .*)" < configure.in | sed -e "s/AM_INIT_AUTOMAKE(mysql, \(.*\))/\1/"`
+echo "version: $version"
+
+# user revision
+user_rev=`bk changes -e -n -d':REV:' | head -1`
+echo "latest revision: $user_rev"
+
+# tree revision
+tree_rev=`bk changes -e -n -d':REV:' -U$BK_USER | head -1`
+echo "latest non-$BK_USER revision: $tree_rev"
+
+# create patch
+patch="$repo_dir/netware/current-changes.patch"
+echo "creating \"$patch\"..."
+bk export -tpatch -r$tree_rev..$user_rev -xnetware/current-changes.patch > $patch
diff --git a/netware/Makefile.am b/netware/Makefile.am
new file mode 100644
index 00000000000..0f5e862c579
--- /dev/null
+++ b/netware/Makefile.am
@@ -0,0 +1,48 @@
+# Copyright (c) 2002 Novell, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+INCLUDES = -I$(srcdir)/../include -I../include -I..
+bin_PROGRAMS = mysqld_safe mysql_install_db mysql_test_run libmysql
+mysqld_safe_SOURCES= mysqld_safe.c my_manage.c
+mysql_install_db_SOURCES= mysql_install_db.c my_manage.c
+mysql_test_run_SOURCES= mysql_test_run.c my_manage.c
+libmysql_SOURCES= libmysqlmain.c
+libmysql_LDADD = ../libmysql/.libs/libmysqlclient.a @openssl_libs@
+
+netware_build_files = client/mysql.def client/mysqladmin.def \
+ client/mysqlbinlog.def client/mysqlcheck.def \
+ client/mysqldump.def client/mysqlimport.def \
+ client/mysqlshow.def client/mysqltest.def \
+ extra/mysql_install.def extra/my_print_defaults.def \
+ extra/perror.def extra/replace.def \
+ extra/resolveip.def extra/comp_err.def \
+ isam/isamchk.def \
+ isam/isamlog.def isam/pack_isam.def \
+ libmysqld/libmysqld.def myisam/myisamchk.def \
+ myisam/myisamlog.def myisam/myisampack.def \
+ sql/mysqld.def
+
+link_sources:
+ set -x; \
+ for f in $(netware_build_files); do \
+ rm -f $(srcdir)/../$$f; \
+ org=`echo $$f | sed -e 's/.*\/\(.*\)/\1/g'`; \
+ @LN_CP_F@ $(srcdir)/$$org $(srcdir)/../$$f; \
+ done;
+
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/netware/comp_err.def b/netware/comp_err.def
new file mode 100644
index 00000000000..d694c07174a
--- /dev/null
+++ b/netware/comp_err.def
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# MySQL Error File Compiler
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Error File Compiler"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/init_db.sql b/netware/init_db.sql
new file mode 100644
index 00000000000..1e8354e13a1
--- /dev/null
+++ b/netware/init_db.sql
@@ -0,0 +1,25 @@
+CREATE DATABASE mysql;
+CREATE DATABASE test;
+
+USE mysql;
+
+CREATE TABLE db (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User)) comment='Database privileges';
+
+INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
+INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
+
+CREATE TABLE host (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db)) comment='Host privileges; Merged with database privileges';
+
+CREATE TABLE user (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') DEFAULT 'N' NOT NULL, File_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User)) comment='Users and global privileges';
+
+INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+INSERT INTO user VALUES ('%','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+
+INSERT INTO user (host,user) values ('localhost','');
+INSERT INTO user (host,user) values ('%','');
+
+CREATE TABLE func (name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') NOT NULL, PRIMARY KEY (name)) comment='User defined functions';
+
+CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(60) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor)) comment='Table privileges';
+
+CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name)) comment='Column privileges';
diff --git a/netware/install_test_db.ncf b/netware/install_test_db.ncf
new file mode 100644
index 00000000000..06befc5d9bd
--- /dev/null
+++ b/netware/install_test_db.ncf
@@ -0,0 +1 @@
+# This functionality is handled by mysql-test-run.nlm on NetWare
diff --git a/netware/isamchk.def b/netware/isamchk.def
new file mode 100644
index 00000000000..69e8ac0405b
--- /dev/null
+++ b/netware/isamchk.def
@@ -0,0 +1,12 @@
+#------------------------------------------------------------------------------
+# ISAM Check
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL ISAM Table Check Tool"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL ISAM Table Check Tool"
+VERSION 4, 0
+STACKSIZE 65536
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/isamlog.def b/netware/isamlog.def
new file mode 100644
index 00000000000..bb8312066ef
--- /dev/null
+++ b/netware/isamlog.def
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# ISAM Log
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL ISAM Table Log Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/libmysql.def b/netware/libmysql.def
new file mode 100644
index 00000000000..7804c4468a5
--- /dev/null
+++ b/netware/libmysql.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MySQL Client
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+EXPORT @libmysql.imp
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Client Library"
+VERSION 4, 0
+AUTOUNLOAD
+XDCDATA ../netware/mysql.xdc
+#DEBUG
diff --git a/netware/libmysql.imp b/netware/libmysql.imp
new file mode 100644
index 00000000000..75fcc8d1a99
--- /dev/null
+++ b/netware/libmysql.imp
@@ -0,0 +1,85 @@
+myodbc_remove_escape,
+mysql_add_slave,
+mysql_affected_rows,
+mysql_change_user,
+mysql_character_set_name,
+mysql_close,
+mysql_data_seek,
+mysql_debug,
+mysql_disable_reads_from_master,
+mysql_disable_rpl_parse,
+mysql_dump_debug_info,
+mysql_enable_reads_from_master,
+mysql_enable_rpl_parse,
+mysql_eof,
+mysql_errno,
+mysql_error,
+mysql_escape_string,
+mysql_fetch_field,
+mysql_fetch_field_direct,
+mysql_fetch_fields,
+mysql_fetch_lengths,
+mysql_fetch_row,
+mysql_field_count,
+mysql_field_seek,
+mysql_field_tell,
+mysql_free_result,
+mysql_get_client_info,
+mysql_get_host_info,
+mysql_get_proto_info,
+mysql_get_server_info,
+mysql_info,
+mysql_init,
+mysql_insert_id,
+mysql_kill,
+mysql_list_dbs,
+mysql_list_fields,
+mysql_list_processes,
+mysql_list_tables,
+mysql_manager_close,
+mysql_manager_command,
+mysql_manager_connect,
+mysql_manager_fetch_line,
+mysql_manager_init,
+mysql_master_query,
+mysql_master_send_query,
+mysql_num_fields,
+mysql_num_rows,
+mysql_odbc_escape_string,
+mysql_options,
+mysql_ping,
+mysql_query,
+mysql_read_query_result,
+mysql_reads_from_master_enabled,
+mysql_real_connect,
+mysql_real_escape_string,
+mysql_real_query,
+mysql_refresh,
+mysql_row_seek,
+mysql_row_tell,
+mysql_rpl_parse_enabled,
+mysql_rpl_probe,
+mysql_rpl_query_type,
+mysql_select_db,
+mysql_send_query,
+mysql_server_end,
+mysql_server_init,
+mysql_set_master,
+mysql_shutdown,
+mysql_slave_query,
+mysql_slave_send_query,
+mysql_ssl_set,
+mysql_stat,
+mysql_store_result,
+mysql_thread_end,
+mysql_thread_id,
+mysql_thread_init,
+mysql_thread_safe,
+mysql_use_result,
+net_safe_read,
+simple_command,
+mysql_connect,
+mysql_create_db,
+mysql_drop_db,
+
+
diff --git a/netware/libmysqlmain.c b/netware/libmysqlmain.c
new file mode 100644
index 00000000000..03fdb832176
--- /dev/null
+++ b/netware/libmysqlmain.c
@@ -0,0 +1,38 @@
+/*
+ Copyright (c) 2002 Novell, Inc. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "my_global.h"
+
+my_bool init_available_charsets(myf myflags);
+
+/* this function is required so that global memory is allocated against this
+library nlm, and not against a paticular client */
+int _NonAppStart(void *NLMHandle, void *errorScreen, const char *commandLine,
+ const char *loadDirPath, size_t uninitializedDataLength,
+ void *NLMFileHandle, int (*readRoutineP)( int conn, void *fileHandle,
+ size_t offset, size_t nbytes, size_t *bytesRead, void *buffer ),
+ size_t customDataOffset, size_t customDataSize, int messageCount,
+ const char **messages)
+{
+ mysql_server_init(0, NULL, NULL);
+
+ init_available_charsets(MYF(0));
+
+ return 0;
+}
+
diff --git a/netware/my_manage.c b/netware/my_manage.c
new file mode 100644
index 00000000000..1c1e75990b4
--- /dev/null
+++ b/netware/my_manage.c
@@ -0,0 +1,478 @@
+/*
+ Copyright (c) 2003 Novell, Inc. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <dirent.h>
+#include <string.h>
+#include <screen.h>
+#include <proc.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+
+#include "my_manage.h"
+
+/******************************************************************************
+
+ macros
+
+******************************************************************************/
+
+/******************************************************************************
+
+ global variables
+
+******************************************************************************/
+
+/******************************************************************************
+
+ functions
+
+******************************************************************************/
+
+/******************************************************************************
+
+ init_args()
+
+ Init an argument list.
+
+******************************************************************************/
+void init_args(arg_list_t *al)
+{
+ ASSERT(al != NULL);
+
+ al->argc = 0;
+ al->size = ARG_BUF;
+ al->argv = malloc(al->size * sizeof(char *));
+ ASSERT(al->argv != NULL);
+
+ return;
+}
+
+/******************************************************************************
+
+ add_arg()
+
+ Add an argument to a list.
+
+******************************************************************************/
+void add_arg(arg_list_t *al, char *format, ...)
+{
+ va_list ap;
+ char temp[PATH_MAX];
+
+ ASSERT(al != NULL);
+
+ // increase size
+ if (al->argc >= al->size)
+ {
+ al->size += ARG_BUF;
+ al->argv = realloc(al->argv, al->size * sizeof(char *));
+ ASSERT(al->argv != NULL);
+ }
+
+ if (format)
+ {
+ va_start(ap, format);
+ vsprintf(temp, format, ap);
+ va_end(ap);
+
+ al->argv[al->argc] = malloc(strlen(temp)+1);
+ ASSERT(al->argv[al->argc] != NULL);
+ strcpy(al->argv[al->argc], temp);
+
+ ++(al->argc);
+ }
+ else
+ {
+ al->argv[al->argc] = NULL;
+ }
+
+ return;
+}
+
+/******************************************************************************
+
+ free_args()
+
+ Free an argument list.
+
+******************************************************************************/
+void free_args(arg_list_t *al)
+{
+ int i;
+
+ ASSERT(al != NULL);
+
+ for(i = 0; i < al->argc; i++)
+ {
+ ASSERT(al->argv[i] != NULL);
+ free(al->argv[i]);
+ al->argv[i] = NULL;
+ }
+
+ free(al->argv);
+ al->argc = 0;
+ al->argv = NULL;
+
+ return;
+}
+
+/******************************************************************************
+
+ sleep_until_file_deleted()
+
+ Sleep until the given file is no longer found.
+
+******************************************************************************/
+int sleep_until_file_deleted(char *pid_file)
+{
+ struct stat buf;
+ int i, err;
+
+ for(i = 0; (i < TRY_MAX) && (err = !stat(pid_file, &buf)); i++) sleep(1);
+
+ if (err != 0) err = errno;
+
+ return err;
+}
+
+/******************************************************************************
+
+ sleep_until_file_exists()
+
+ Sleep until the given file exists.
+
+******************************************************************************/
+int sleep_until_file_exists(char *pid_file)
+{
+ struct stat buf;
+ int i, err;
+
+ for(i = 0; (i < TRY_MAX) && (err = stat(pid_file, &buf)); i++) sleep(1);
+
+ if (err != 0) err = errno;
+
+ return err;
+}
+
+/******************************************************************************
+
+ wait_for_server_start()
+
+ Wait for the server on the given port to start.
+
+******************************************************************************/
+int wait_for_server_start(char *bin_dir, char *user, char *password, int port)
+{
+ arg_list_t al;
+ int err, i;
+ char mysqladmin_file[PATH_MAX];
+ char trash[PATH_MAX];
+
+ // mysqladmin file
+ snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
+ snprintf(trash, PATH_MAX, "/tmp/trash.out");
+
+ // args
+ init_args(&al);
+ add_arg(&al, "%s", mysqladmin_file);
+ add_arg(&al, "--no-defaults");
+ add_arg(&al, "--port=%u", port);
+ add_arg(&al, "--user=%s", user);
+ add_arg(&al, "--password=%s", password);
+ add_arg(&al, "--silent");
+
+ /** Not supported on NetWare
+ add_arg(&al, "-O");
+ add_arg(&al, "connect_timeout=10");
+ add_arg(&al, "-w");
+ **/
+
+ add_arg(&al, "--host=localhost");
+ add_arg(&al, "ping");
+
+ // NetWare does not support the connect timeout in the TCP/IP stack
+ // -- we will try the ping multiple times
+ for(i = 0; (i < TRY_MAX)
+ && (err = spawn(mysqladmin_file, &al, TRUE, NULL,
+ trash, NULL)); i++) sleep(1);
+
+ // free args
+ free_args(&al);
+
+ return err;
+}
+
+/******************************************************************************
+
+ spawn()
+
+ Spawn the given path with the given arguments.
+
+******************************************************************************/
+int spawn(char *path, arg_list_t *al, int join, char *input,
+ char *output, char *error)
+{
+ pid_t pid;
+ int result = 0;
+ wiring_t wiring = { FD_UNUSED, FD_UNUSED, FD_UNUSED };
+ unsigned long flags = PROC_CURRENT_SPACE | PROC_INHERIT_CWD;
+
+ // open wiring
+ if (input)
+ wiring.infd = open(input, O_RDONLY);
+
+ if (output)
+ wiring.outfd = open(output, O_WRONLY | O_CREAT | O_TRUNC);
+
+ if (error)
+ wiring.errfd = open(error, O_WRONLY | O_CREAT | O_TRUNC);
+
+ // procve requires a NULL
+ add_arg(al, NULL);
+
+ // go
+ pid = procve(path, flags, NULL, &wiring, NULL, NULL, 0,
+ NULL, (const char **)al->argv);
+
+ if (pid == -1)
+ {
+ result = -1;
+ }
+ else if (join)
+ {
+ waitpid(pid, &result, 0);
+ }
+
+ // close wiring
+ if (wiring.infd != -1)
+ close(wiring.infd);
+
+ if (wiring.outfd != -1)
+ close(wiring.outfd);
+
+ if (wiring.errfd != -1)
+ close(wiring.errfd);
+
+ return result;
+}
+
+/******************************************************************************
+
+ stop_server()
+
+ Stop the server with the given port and pid file.
+
+******************************************************************************/
+int stop_server(char *bin_dir, char *user, char *password, int port,
+ char *pid_file)
+{
+ arg_list_t al;
+ int err, i, argc = 0;
+ char mysqladmin_file[PATH_MAX];
+ char trash[PATH_MAX];
+
+ // mysqladmin file
+ snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
+ snprintf(trash, PATH_MAX, "/tmp/trash.out");
+
+ // args
+ init_args(&al);
+ add_arg(&al, "%s", mysqladmin_file);
+ add_arg(&al, "--no-defaults");
+ add_arg(&al, "--port=%u", port);
+ add_arg(&al, "--user=%s", user);
+ add_arg(&al, "--password=%s", password);
+ add_arg(&al, "-O");
+ add_arg(&al, "shutdown_timeout=20");
+ add_arg(&al, "shutdown");
+
+ // spawn
+ if ((err = spawn(mysqladmin_file, &al, TRUE, NULL,
+ trash, NULL)) == 0)
+ {
+ sleep_until_file_deleted(pid_file);
+ }
+ else
+ {
+ pid_t pid = get_server_pid(pid_file);
+
+ // shutdown failed - kill server
+ kill_server(pid);
+
+ sleep(TRY_MAX);
+
+ // remove pid file if possible
+ err = remove(pid_file);
+ }
+
+ // free args
+ free_args(&al);
+
+ return err;
+}
+
+/******************************************************************************
+
+ get_server_pid()
+
+ Get the VM id with the given pid file.
+
+******************************************************************************/
+pid_t get_server_pid(char *pid_file)
+{
+ char buf[PATH_MAX];
+ int fd, err;
+ char *p;
+ pid_t id;
+
+ // discover id
+ fd = open(pid_file, O_RDONLY);
+
+ err = read(fd, buf, PATH_MAX);
+
+ close(fd);
+
+ if (err > 0)
+ {
+ // terminate string
+ if ((p = strchr(buf, '\n')) != NULL)
+ {
+ *p = NULL;
+
+ // check for a '\r'
+ if ((p = strchr(buf, '\r')) != NULL)
+ {
+ *p = NULL;
+ }
+ }
+ else
+ {
+ buf[err] = NULL;
+ }
+
+ id = strtol(buf, NULL, 0);
+ }
+
+ return id;
+}
+
+/******************************************************************************
+
+ kill_server()
+
+ Force a kill of the server with the given pid.
+
+******************************************************************************/
+void kill_server(pid_t pid)
+{
+ if (pid > 0)
+ {
+ // destroy vm
+ NXVmDestroy(pid);
+ }
+}
+
+/******************************************************************************
+
+ del_tree()
+
+ Delete the directory and subdirectories.
+
+******************************************************************************/
+void del_tree(char *dir)
+{
+ DIR *parent = opendir(dir);
+ DIR *entry;
+ char temp[PATH_MAX];
+
+ if (parent == NULL)
+ {
+ return;
+ }
+
+ while((entry = readdir(parent)) != NULL)
+ {
+ // create long name
+ snprintf(temp, PATH_MAX, "%s/%s", dir, entry->d_name);
+
+ if (entry->d_name[0] == '.')
+ {
+ // Skip
+ }
+ else if (S_ISDIR(entry->d_type))
+ {
+ // delete subdirectory
+ del_tree(temp);
+ }
+ else
+ {
+ // remove file
+ remove(temp);
+ }
+ }
+
+ // remove directory
+ rmdir(dir);
+}
+
+/******************************************************************************
+
+ removef()
+
+******************************************************************************/
+int removef(char *format, ...)
+{
+ va_list ap;
+ char path[PATH_MAX];
+
+ va_start(ap, format);
+
+ vsnprintf(path, PATH_MAX, format, ap);
+
+ va_end(ap);
+
+ return remove(path);
+}
+
+/******************************************************************************
+
+ get_basedir()
+
+******************************************************************************/
+void get_basedir(char *argv0, char *basedir)
+{
+ char temp[PATH_MAX];
+ char *p;
+
+ ASSERT(argv0 != NULL);
+ ASSERT(basedir != NULL);
+
+ strcpy(temp, strlwr(argv0));
+ while((p = strchr(temp, '\\')) != NULL) *p = '/';
+
+ if ((p = strindex(temp, "/bin/")) != NULL)
+ {
+ *p = NULL;
+ strcpy(basedir, temp);
+ }
+}
+
diff --git a/netware/my_manage.h b/netware/my_manage.h
new file mode 100644
index 00000000000..b19662c4ee9
--- /dev/null
+++ b/netware/my_manage.h
@@ -0,0 +1,87 @@
+/*
+ Copyright (c) 2002 Novell, Inc. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _MY_MANAGE
+#define _MY_MANAGE
+
+/******************************************************************************
+
+ includes
+
+******************************************************************************/
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/******************************************************************************
+
+ macros
+
+******************************************************************************/
+
+#define ARG_BUF 10
+#define TRY_MAX 5
+
+/******************************************************************************
+
+ structures
+
+******************************************************************************/
+
+typedef struct
+{
+
+ int argc;
+ char **argv;
+
+ size_t size;
+
+} arg_list_t;
+
+/******************************************************************************
+
+ global variables
+
+******************************************************************************/
+
+/******************************************************************************
+
+ prototypes
+
+******************************************************************************/
+
+void init_args(arg_list_t *);
+void add_arg(arg_list_t *, char *, ...);
+void free_args(arg_list_t *);
+
+int sleep_until_file_exists(char *);
+int sleep_until_file_deleted(char *);
+int wait_for_server_start(char *, char *, char *, int);
+
+int spawn(char *, arg_list_t *, int, char *, char *, char *);
+
+int stop_server(char *, char *, char *, int, char *);
+pid_t get_server_pid(char *);
+void kill_server(pid_t pid);
+
+void del_tree(char *);
+int removef(char *, ...);
+
+void get_basedir(char *, char *);
+
+#endif /* _MY_MANAGE */
diff --git a/netware/my_print_defaults.def b/netware/my_print_defaults.def
new file mode 100644
index 00000000000..49f167341ae
--- /dev/null
+++ b/netware/my_print_defaults.def
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# My Print Defaults
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Print Defaults Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/myisamchk.def b/netware/myisamchk.def
new file mode 100644
index 00000000000..cdfe186058f
--- /dev/null
+++ b/netware/myisamchk.def
@@ -0,0 +1,12 @@
+#------------------------------------------------------------------------------
+# MyISAM Check
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL MyISAM Table Check Tool"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL MyISAM Table Check Tool"
+VERSION 4, 0
+STACKSIZE 65536
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/myisamlog.def b/netware/myisamlog.def
new file mode 100644
index 00000000000..5c4cbb23361
--- /dev/null
+++ b/netware/myisamlog.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MyISAM Log
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL MyISAM Table Log Tool"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL MyISAM Table Log Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/myisampack.def b/netware/myisampack.def
new file mode 100644
index 00000000000..9111538c2c0
--- /dev/null
+++ b/netware/myisampack.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MyISAM Pack
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL MyISAM Table Pack Tool"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL MyISAM Table Pack Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysql.def b/netware/mysql.def
new file mode 100644
index 00000000000..9b4424ed4fb
--- /dev/null
+++ b/netware/mysql.def
@@ -0,0 +1,12 @@
+#------------------------------------------------------------------------------
+# MySQL Client
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL Monitor"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Monitor"
+VERSION 4, 0
+MULTIPLE
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysql.xdc b/netware/mysql.xdc
new file mode 100644
index 00000000000..a6c430f7314
--- /dev/null
+++ b/netware/mysql.xdc
Binary files differ
diff --git a/netware/mysql_fix_privilege_tables.pl b/netware/mysql_fix_privilege_tables.pl
new file mode 100644
index 00000000000..fd5bc11dde1
--- /dev/null
+++ b/netware/mysql_fix_privilege_tables.pl
@@ -0,0 +1,125 @@
+#-----------------------------------------------------------------------------
+# Copyright (C) 2002 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# This notice applies to changes, created by or for Novell, Inc.,
+# to preexisting works for which notices appear elsewhere in this file.
+
+# Copyright (c) 2003 Novell, Inc. All Rights Reserved.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#-----------------------------------------------------------------------------
+
+use strict;
+use Mysql;
+
+print "MySQL Fix Privilege Tables Script\n\n";
+
+print "NOTE: This script updates your privilege tables to the lastest\n";
+print " specifications!\n\n";
+
+#-----------------------------------------------------------------------------
+# get the current root password
+#-----------------------------------------------------------------------------
+
+print "In order to log into MySQL to update it, we'll need the current\n";
+print "password for the root user. If you've just installed MySQL, and\n";
+print "you haven't set the root password yet, the password will be blank,\n";
+print "so you should just press enter here.\n\n";
+
+print "Enter the current password for root: ";
+my $password = <STDIN>;
+chomp $password;
+print "\n";
+
+my $conn = Mysql->connect("localhost", "mysql", "root", $password)
+ || die "Unable to connect to MySQL.";
+
+print "OK, successfully used the password, moving on...\n\n";
+
+
+#-----------------------------------------------------------------------------
+# MySQL 4.0.2
+#-----------------------------------------------------------------------------
+
+print "Adding new fields used by MySQL 4.0.2 to the privilege tables...\n";
+print "NOTE: You can ignore any Duplicate column errors.\n";
+$conn->query(" \
+ALTER TABLE user \
+ADD Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER alter_priv, \
+ADD Super_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Show_db_priv, \
+ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Super_priv, \
+ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_tmp_table_priv, \
+ADD Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Lock_tables_priv, \
+ADD Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Execute_priv, \
+ADD Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Repl_slave_priv; \
+") && $conn->query(" \
+UPDATE user SET show_db_priv=select_priv, super_priv=process_priv, execute_priv=process_priv, create_tmp_table_priv='Y', Lock_tables_priv='Y', Repl_slave_priv=file_priv, Repl_client_priv=file_priv where user<>''; \
+");
+
+#-----------------------------------------------------------------------------
+# MySQL 4.0 Limitations
+#-----------------------------------------------------------------------------
+
+print "Adding new fields used by MySQL 4.0 security limitations...\n";
+
+$conn->query(" \
+ALTER TABLE user \
+ADD max_questions int(11) NOT NULL AFTER x509_subject, \
+ADD max_updates int(11) unsigned NOT NULL AFTER max_questions, \
+ADD max_connections int(11) unsigned NOT NULL AFTER max_updates; \
+");
+
+#-----------------------------------------------------------------------------
+# MySQL 4.0 DB and Host privs
+#-----------------------------------------------------------------------------
+
+print "Adding new fields used by MySQL 4.0 locking and temporary table security...\n";
+
+$conn->query(" \
+ALTER TABLE db \
+ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, \
+ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; \
+");
+
+$conn->query(" \
+ALTER TABLE host \
+ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, \
+ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; \
+");
+
+#-----------------------------------------------------------------------------
+# done
+#-----------------------------------------------------------------------------
+
+print "\n\nAll done!\n\n";
+
+print "Thanks for using MySQL!\n\n";
+
diff --git a/netware/mysql_install.def b/netware/mysql_install.def
new file mode 100644
index 00000000000..87fc76919f9
--- /dev/null
+++ b/netware/mysql_install.def
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# My Print Defaults
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Install Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysql_install_db.c b/netware/mysql_install_db.c
new file mode 100644
index 00000000000..b4060bfdb7e
--- /dev/null
+++ b/netware/mysql_install_db.c
@@ -0,0 +1,428 @@
+/*
+ Copyright (c) 2002 Novell, Inc. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <monitor.h>
+#include <strings.h>
+#include <getopt.h>
+#include <screen.h>
+#include <errno.h>
+
+#include "my_config.h"
+#include "my_manage.h"
+
+/******************************************************************************
+
+ global variables
+
+******************************************************************************/
+char autoclose;
+char basedir[PATH_MAX];
+char datadir[PATH_MAX];
+char err_log[PATH_MAX];
+char out_log[PATH_MAX];
+char mysqld[PATH_MAX];
+char hostname[PATH_MAX];
+char sql_file[PATH_MAX];
+char default_option[PATH_MAX];
+
+/******************************************************************************
+
+ prototypes
+
+******************************************************************************/
+
+void start_defaults(int, char*[]);
+void finish_defaults();
+void read_defaults(arg_list_t *);
+void parse_args(int, char*[]);
+void get_options(int, char*[]);
+void create_paths();
+int mysql_install_db(int argc, char *argv[]);
+
+/******************************************************************************
+
+ functions
+
+******************************************************************************/
+
+/******************************************************************************
+
+ start_defaults()
+
+ Start setting the defaults.
+
+******************************************************************************/
+void start_defaults(int argc, char *argv[])
+{
+ struct stat buf;
+ int i;
+
+ // default options
+ static char *default_options[] =
+ {
+ "--no-defaults",
+ "--defaults-file=",
+ "--defaults-extra-file=",
+ NULL
+ };
+
+ // autoclose
+ autoclose = FALSE;
+
+ // basedir
+ get_basedir(argv[0], basedir);
+
+ // hostname
+ if (gethostname(hostname,PATH_MAX) < 0)
+ {
+ // default
+ strcpy(hostname,"mysql");
+ }
+
+ // default option
+ default_option[0] = NULL;
+ for (i=0; (argc > 1) && default_options[i]; i++)
+ {
+ if(!strnicmp(argv[1], default_options[i], strlen(default_options[i])))
+ {
+ strncpy(default_option, argv[1], PATH_MAX);
+ break;
+ }
+ }
+
+ // set after basedir is established
+ datadir[0] = NULL;
+ err_log[0] = NULL;
+ out_log[0] = NULL;
+ mysqld[0] = NULL;
+ sql_file[0] = NULL;
+}
+
+/******************************************************************************
+
+ finish_defaults()
+
+ Finish setting the defaults.
+
+******************************************************************************/
+void finish_defaults()
+{
+ struct stat buf;
+ int i;
+
+ // datadir
+ if (!datadir[0]) snprintf(datadir, PATH_MAX, "%s/data", basedir);
+
+ // err-log
+ if (!err_log[0]) snprintf(err_log, PATH_MAX, "%s/%s.err", datadir, hostname);
+
+ // out-log
+ if (!out_log[0]) snprintf(out_log, PATH_MAX, "%s/%s.out", datadir, hostname);
+
+ // sql-file
+ if (!sql_file[0]) snprintf(sql_file, PATH_MAX, "%s/bin/init_db.sql", basedir);
+
+ // mysqld
+ if (!mysqld[0]) snprintf(mysqld, PATH_MAX, "%s/bin/mysqld", basedir);
+}
+
+/******************************************************************************
+
+ read_defaults()
+
+ Read the defaults.
+
+******************************************************************************/
+void read_defaults(arg_list_t *pal)
+{
+ arg_list_t al;
+ char defaults_file[PATH_MAX];
+ char mydefaults[PATH_MAX];
+ char line[PATH_MAX];
+ FILE *fp;
+
+ // defaults output file
+ snprintf(defaults_file, PATH_MAX, "%s/bin/defaults.out", basedir);
+ remove(defaults_file);
+
+ // mysqladmin file
+ snprintf(mydefaults, PATH_MAX, "%s/bin/my_print_defaults", basedir);
+
+ // args
+ init_args(&al);
+ add_arg(&al, mydefaults);
+ if (default_option[0]) add_arg(&al, default_option);
+ add_arg(&al, "mysqld");
+ add_arg(&al, "mysql_install_db");
+
+ spawn(mydefaults, &al, TRUE, NULL, defaults_file, NULL);
+
+ free_args(&al);
+
+ // gather defaults
+ if((fp = fopen(defaults_file, "r")) != NULL)
+ {
+ while(fgets(line, PATH_MAX, fp))
+ {
+ char *p;
+
+ // remove end-of-line character
+ if ((p = strrchr(line, '\n')) != NULL) *p = '\0';
+
+ // add the option as an argument
+ add_arg(pal, line);
+ }
+
+ fclose(fp);
+ }
+
+ // remove file
+ remove(defaults_file);
+}
+
+/******************************************************************************
+
+ parse_args()
+
+ Get the options.
+
+******************************************************************************/
+void parse_args(int argc, char *argv[])
+{
+ int index = 0;
+ int c;
+
+ // parse options
+ enum opts
+ {
+ OPT_BASEDIR = 0xFF,
+ OPT_DATADIR,
+ OPT_SQL_FILE
+ };
+
+ static struct option options[] =
+ {
+ {"autoclose", no_argument, &autoclose, TRUE},
+ {"basedir", required_argument, 0, OPT_BASEDIR},
+ {"datadir", required_argument, 0, OPT_DATADIR},
+ {"sql-file", required_argument, 0, OPT_SQL_FILE},
+ {0, 0, 0, 0}
+ };
+
+ // we have to reset getopt_long because we use it multiple times
+ optind = 1;
+
+ // turn off error reporting
+ opterr = 0;
+
+ while ((c = getopt_long(argc, argv, "b:h:", options, &index)) >= 0)
+ {
+ switch (c)
+ {
+ case OPT_BASEDIR:
+ case 'b':
+ strcpy(basedir, optarg);
+ break;
+
+ case OPT_DATADIR:
+ case 'h':
+ strcpy(datadir, optarg);
+ break;
+
+ case OPT_SQL_FILE:
+ strcpy(sql_file, optarg);
+ break;
+
+ default:
+ // ignore
+ break;
+ }
+ }
+}
+
+/******************************************************************************
+
+ get_options()
+
+ Get the options.
+
+******************************************************************************/
+void get_options(int argc, char *argv[])
+{
+ arg_list_t al;
+
+ // start defaults
+ start_defaults(argc, argv);
+
+ // default file arguments
+ init_args(&al);
+ add_arg(&al, "ignore");
+ read_defaults(&al);
+ parse_args(al.argc, al.argv);
+ free_args(&al);
+
+ // command-line arguments
+ parse_args(argc, argv);
+
+ // finish defaults
+ finish_defaults();
+}
+
+/******************************************************************************
+
+ create_paths()
+
+ Create database paths.
+
+******************************************************************************/
+void create_paths()
+{
+ struct stat info;
+ char temp[PATH_MAX];
+
+ // check for tables
+ snprintf(temp, PATH_MAX, "%s/mysql/host.frm", datadir);
+ if (!stat(temp, &info))
+ {
+ printf("A database already exists in the directory:\n");
+ printf("\t%s\n\n", datadir);
+ exit(-1);
+ }
+
+ // data directory
+ if (stat(datadir, &info))
+ {
+ mkdir(datadir, 0);
+ }
+}
+
+/******************************************************************************
+
+ mysql_install_db()
+
+ Install the database.
+
+******************************************************************************/
+int mysql_install_db(int argc, char *argv[])
+{
+ arg_list_t al;
+ int i, j, err;
+ char skip;
+
+ // private options
+ static char *private_options[] =
+ {
+ "--autoclose",
+ "--sql-file=",
+ NULL
+ };
+
+ // args
+ init_args(&al);
+ add_arg(&al, "%s", mysqld);
+
+ // parent args
+ for(i = 1; i < argc; i++)
+ {
+ skip = FALSE;
+
+ // skip private arguments
+ for (j=0; private_options[j]; j++)
+ {
+ if(!strnicmp(argv[i], private_options[j], strlen(private_options[j])))
+ {
+ skip = TRUE;
+ break;
+ }
+ }
+
+ if (!skip) add_arg(&al, "%s", argv[i]);
+ }
+
+ add_arg(&al, "--bootstrap");
+ add_arg(&al, "--skip-grant-tables");
+ add_arg(&al, "--skip-innodb");
+ add_arg(&al, "--skip-bdb");
+
+ // spawn mysqld
+ err = spawn(mysqld, &al, TRUE, sql_file, out_log, err_log);
+
+ // free args
+ free_args(&al);
+
+ return err;
+}
+
+/******************************************************************************
+
+ main()
+
+******************************************************************************/
+int main(int argc, char **argv)
+{
+ // get options
+ get_options(argc, argv);
+
+ // check for an autoclose option
+ if (!autoclose) setscreenmode(SCR_NO_MODE);
+
+ // header
+ printf("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+
+ // create paths
+ create_paths();
+
+ // install the database
+ if (mysql_install_db(argc, argv))
+ {
+ printf("ERROR - The database creation failed!\n");
+ printf(" %s\n", strerror(errno));
+ printf("See the following log for more infomration:\n");
+ printf("\t%s\n\n", err_log);
+ exit(-1);
+ }
+
+ // status
+ printf("Initial database successfully created in the directory:\n");
+ printf("\t%s\n", datadir);
+
+ // info
+ printf("\nPLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !\n");
+
+ printf("\nThis is done with:\n");
+ printf("\tmysqladmin -u root password 'new-password'\n");
+
+ printf("\nSee the manual for more instructions.\n");
+
+ printf("\nYou can start the MySQL daemon with:\n");
+ printf("\tmysqld_safe\n");
+
+ printf("\nPlease report any problems with:\n");
+ printf("\t/mysql/mysqlbug.txt\n");
+
+ printf("\nThe latest information about MySQL is available on the web at\n");
+ printf("\thttp://www.mysql.com\n");
+
+ printf("\nSupport MySQL by buying support at https://order.mysql.com\n\n");
+
+ return 0;
+}
diff --git a/netware/mysql_install_db.def b/netware/mysql_install_db.def
new file mode 100644
index 00000000000..4653638b5ad
--- /dev/null
+++ b/netware/mysql_install_db.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MySQL Install DB
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL Install"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Initial Database Installer"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysql_secure_installation.pl b/netware/mysql_secure_installation.pl
new file mode 100644
index 00000000000..e363cacbc0d
--- /dev/null
+++ b/netware/mysql_secure_installation.pl
@@ -0,0 +1,219 @@
+#-----------------------------------------------------------------------------
+# Copyright (C) 2002 MySQL AB and Jeremy Cole
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# This notice applies to changes, created by or for Novell, Inc.,
+# to preexisting works for which notices appear elsewhere in this file.
+
+# Copyright (c) 2003 Novell, Inc. All Rights Reserved.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#-----------------------------------------------------------------------------
+
+use strict;
+use Mysql;
+
+print "MySQL Secure Installation Script\n\n";
+
+print "NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL\n";
+print " SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!\n\n";
+
+#-----------------------------------------------------------------------------
+# get the current root password
+#-----------------------------------------------------------------------------
+
+print "In order to log into MySQL to secure it, we'll need the current\n";
+print "password for the root user. If you've just installed MySQL, and\n";
+print "you haven't set the root password yet, the password will be blank,\n";
+print "so you should just press enter here.\n\n";
+
+print "Enter the current password for root: ";
+my $password = <STDIN>;
+chomp $password;
+print "\n";
+
+my $conn = Mysql->connect("localhost", "mysql", "root", $password)
+ || die "Unable to connect to MySQL.";
+
+print "OK, successfully used the password, moving on...\n\n";
+
+#-----------------------------------------------------------------------------
+# set the root password
+#-----------------------------------------------------------------------------
+
+unless ($password)
+{
+ print "Setting the root password ensures that no one can log into MySQL\n";
+ print "using the root user without the proper authorization.\n\n";
+
+ print "Set root password (Y/N)? ";
+ my $reply = <STDIN>;
+ chomp $reply;
+ print "\n";
+
+ if ($reply =~ /Y/i)
+ {
+ print "New password for root: ";
+ my $pass1 = <STDIN>;
+ chomp $pass1;
+ print "\n";
+
+ print "Re-enter new password for root: ";
+ my $pass2 = <STDIN>;
+ chomp $pass2;
+ print "\n";
+
+ unless ($pass1 eq $pass2) { die "Sorry, the passwords do not match."; }
+
+ unless ($pass1) { die "Sorry, you can't use an empty password here."; }
+
+ $conn->query("SET PASSWORD FOR root\@localhost=PASSWORD('$pass1')")
+ || die "Unable to set password.";
+
+ print "OK, successfully set the password, moving on...\n\n";
+ }
+ else
+ {
+ print "WARNING, the password is not set, moving on...\n\n";
+ }
+}
+
+#-----------------------------------------------------------------------------
+# remove anonymous users
+#-----------------------------------------------------------------------------
+
+print "By default, a MySQL installation has anonymous users, allowing anyone\n";
+print "to log into MySQL without having to have a user account created for\n";
+print "them. This is intended only for testing, and to make the installation\n";
+print "go a bit smoother. You should remove them before moving into a\n";
+print "production environment.\n\n";
+
+print "Remove anonymous users (Y/N)? ";
+my $reply = <STDIN>;
+chomp $reply;
+print "\n";
+
+if ($reply =~ /Y/i)
+{
+ $conn->query("DELETE FROM mysql.user WHERE user=''")
+ || die "Unable to remove anonymous users.";
+
+ print "OK, successfully removed anonymous users, moving on...\n\n";
+}
+else
+{
+ print "WARNING, the anonymous users have not been removed, moving on...\n\n";
+}
+
+#-----------------------------------------------------------------------------
+# disallow remote root login
+#-----------------------------------------------------------------------------
+
+print "Normally, root should only be allowed to connect from 'localhost'. This\n";
+print "ensures that someone cannot guess at the root password from the network.\n\n";
+
+print "Disallow remote root login (Y/N)? ";
+my $reply = <STDIN>;
+chomp $reply;
+print "\n";
+
+if ($reply =~ /Y/i)
+{
+ $conn->query("DELETE FROM mysql.user WHERE user='root' AND host!='localhost'")
+ || die "Unable to disallow remote root login.";
+
+ print "OK, successfully disallowed remote root login, moving on...\n\n";
+}
+else
+{
+ print "WARNING, remote root login has not been disallowed, moving on...\n\n";
+}
+
+#-----------------------------------------------------------------------------
+# remove test database
+#-----------------------------------------------------------------------------
+
+print "By default, MySQL comes with a database named 'test' that anyone can\n";
+print "access. This is intended only for testing, and should be removed\n";
+print "before moving into a production environment.\n\n";
+
+print "Remove the test database (Y/N)? ";
+my $reply = <STDIN>;
+chomp $reply;
+print "\n";
+
+if ($reply =~ /Y/i)
+{
+ $conn->query("DROP DATABASE IF EXISTS test")
+ || die "Unable to remove test database.";
+
+ $conn->query("DELETE FROM mysql.db WHERE db='test' OR db='test\\_%'")
+ || die "Unable to remove access to the test database.";
+
+ print "OK, successfully removed the test database, moving on...\n\n";
+}
+else
+{
+ print "WARNING, the test database has not been removed, moving on...\n\n";
+}
+
+#-----------------------------------------------------------------------------
+# reload privilege tables
+#-----------------------------------------------------------------------------
+
+print "Reloading the privilege tables will ensure that all changes made so far\n";
+print "will take effect immediately.\n\n";
+
+print "Reload privilege tables (Y/N)? ";
+my $reply = <STDIN>;
+chomp $reply;
+print "\n";
+
+if ($reply =~ /Y/i)
+{
+ $conn->query("FLUSH PRIVILEGES")
+ || die "Unable to reload privilege tables.";
+
+ print "OK, successfully reloaded privilege tables, moving on...\n\n";
+}
+else
+{
+ print "WARNING, the privilege tables have not been reloaded, moving on...\n\n";
+}
+
+#-----------------------------------------------------------------------------
+# done
+#-----------------------------------------------------------------------------
+
+print "\n\nAll done! If you've completed all of the above steps, your MySQL\n";
+print "installation should now be secure.\n\n";
+
+print "Thanks for using MySQL!\n\n";
+
diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c
new file mode 100644
index 00000000000..e1a07baca6c
--- /dev/null
+++ b/netware/mysql_test_run.c
@@ -0,0 +1,1237 @@
+/*
+ Copyright (c) 2002, 2003 Novell, Inc. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <dirent.h>
+#include <string.h>
+#include <screen.h>
+#include <nks/vm.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mode.h>
+
+#include "my_config.h"
+#include "my_manage.h"
+
+/******************************************************************************
+
+ macros
+
+******************************************************************************/
+
+#define HEADER "TEST ELAPSED RESULT \n"
+#define DASH "------------------------------------------------------------------------\n"
+
+#define NW_TEST_SUFFIX ".nw-test"
+#define NW_RESULT_SUFFIX ".nw-result"
+#define TEST_SUFFIX ".test"
+#define RESULT_SUFFIX ".result"
+#define REJECT_SUFFIX ".reject"
+#define OUT_SUFFIX ".out"
+#define ERR_SUFFIX ".err"
+
+#define TEST_PASS "[ pass ]"
+#define TEST_SKIP "[ skip ]"
+#define TEST_FAIL "[ fail ]"
+#define TEST_BAD "[ bad ]"
+
+/******************************************************************************
+
+ global variables
+
+******************************************************************************/
+
+char base_dir[PATH_MAX] = "sys:/mysql";
+char db[PATH_MAX] = "test";
+char user[PATH_MAX] = "root";
+char password[PATH_MAX] = "";
+
+int master_port = 9306;
+int slave_port = 9307;
+
+// comma delimited list of tests to skip or empty string
+char skip_test[PATH_MAX] = "";
+
+char bin_dir[PATH_MAX];
+char mysql_test_dir[PATH_MAX];
+char test_dir[PATH_MAX];
+char mysql_tmp_dir[PATH_MAX];
+char result_dir[PATH_MAX];
+char master_dir[PATH_MAX];
+char slave_dir[PATH_MAX];
+char lang_dir[PATH_MAX];
+char char_dir[PATH_MAX];
+
+char mysqladmin_file[PATH_MAX];
+char mysqld_file[PATH_MAX];
+char mysqltest_file[PATH_MAX];
+char master_pid[PATH_MAX];
+char slave_pid[PATH_MAX];
+
+char master_opt[PATH_MAX] = "";
+char slave_opt[PATH_MAX] = "";
+
+char slave_master_info[PATH_MAX] = "";
+
+char master_init_script[PATH_MAX] = "";
+char slave_init_script[PATH_MAX] = "";
+
+// OpenSSL
+char ca_cert[PATH_MAX];
+char server_cert[PATH_MAX];
+char server_key[PATH_MAX];
+char client_cert[PATH_MAX];
+char client_key[PATH_MAX];
+
+int total_skip = 0;
+int total_pass = 0;
+int total_fail = 0;
+int total_test = 0;
+
+double total_time = 0;
+
+int use_openssl = FALSE;
+int master_running = FALSE;
+int slave_running = FALSE;
+int skip_slave = TRUE;
+int single_test = TRUE;
+
+int restarts = 0;
+
+FILE *log_fd = NULL;
+
+/******************************************************************************
+
+ functions
+
+******************************************************************************/
+
+/******************************************************************************
+
+ prototypes
+
+******************************************************************************/
+
+void report_stats();
+void install_db(char *);
+void mysql_install_db();
+void start_master();
+void start_slave();
+void mysql_start();
+void stop_slave();
+void stop_master();
+void mysql_stop();
+void mysql_restart();
+int read_option(char *, char *);
+void run_test(char *);
+void setup(char *);
+void vlog(char *, va_list);
+void log(char *, ...);
+void log_info(char *, ...);
+void log_error(char *, ...);
+void log_errno(char *, ...);
+void die(char *);
+
+/******************************************************************************
+
+ report_stats()
+
+ Report the gathered statistics.
+
+******************************************************************************/
+void report_stats()
+{
+ if (total_fail == 0)
+ {
+ log("\nAll %d test(s) were successful.\n", total_test);
+ }
+ else
+ {
+ double percent = ((double)total_pass / total_test) * 100;
+
+ log("\nFailed %u/%u test(s), %.02f%% successful.\n",
+ total_fail, total_test, percent);
+ log("\nThe .out and .err files in %s may give you some\n", result_dir);
+ log("hint of what when wrong.\n");
+ log("\nIf you want to report this error, please first read the documentation\n");
+ log("at: http://www.mysql.com/doc/M/y/MySQL_test_suite.html\n");
+ }
+
+ log("\n%.02f total minutes elapsed in the test cases\n\n", total_time / 60);
+}
+
+/******************************************************************************
+
+ install_db()
+
+ Install the a database.
+
+******************************************************************************/
+void install_db(char *datadir)
+{
+ arg_list_t al;
+ int err, i;
+ char input[PATH_MAX];
+ char output[PATH_MAX];
+ char error[PATH_MAX];
+
+ // input file
+ snprintf(input, PATH_MAX, "%s/bin/init_db.sql", base_dir);
+ snprintf(output, PATH_MAX, "%s/install.out", datadir);
+ snprintf(error, PATH_MAX, "%s/install.err", datadir);
+
+ // args
+ init_args(&al);
+ add_arg(&al, mysqld_file);
+ add_arg(&al, "--no-defaults");
+ add_arg(&al, "--bootstrap");
+ add_arg(&al, "--skip-grant-tables");
+ add_arg(&al, "--basedir=%s", base_dir);
+ add_arg(&al, "--datadir=%s", datadir);
+ add_arg(&al, "--skip-innodb");
+ add_arg(&al, "--skip-bdb");
+
+ // spawn
+ if ((err = spawn(mysqld_file, &al, TRUE, input, output, error)) != 0)
+ {
+ die("Unable to create database.");
+ }
+
+ // free args
+ free_args(&al);
+}
+
+/******************************************************************************
+
+ mysql_install_db()
+
+ Install the test databases.
+
+******************************************************************************/
+void mysql_install_db()
+{
+ char temp[PATH_MAX];
+
+ // var directory
+ snprintf(temp, PATH_MAX, "%s/var", mysql_test_dir);
+
+ // clean up old direcotry
+ del_tree(temp);
+
+ // create var directory
+ mkdir(temp, S_IRWXU);
+
+ // create subdirectories
+ snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+
+ // install databases
+ install_db(master_dir);
+ install_db(slave_dir);
+}
+
+/******************************************************************************
+
+ start_master()
+
+ Start the master server.
+
+******************************************************************************/
+void start_master()
+{
+ arg_list_t al;
+ int err, i;
+ char master_out[PATH_MAX];
+ char master_err[PATH_MAX];
+ char temp[PATH_MAX], temp2[PATH_MAX];
+
+ // remove old berkeley db log files that can confuse the server
+ removef("%s/log.*", master_dir);
+
+ // remove stale binary logs
+ removef("%s/var/log/*-bin.*", mysql_test_dir);
+
+ // remove stale binary logs
+ removef("%s/var/log/*.index", mysql_test_dir);
+
+ // remove master.info file
+ removef("%s/master.info", master_dir);
+
+ // remove relay files
+ removef("%s/var/log/*relay*", mysql_test_dir);
+
+ // remove relay-log.info file
+ removef("%s/relay-log.info", master_dir);
+
+ // init script
+ if (master_init_script[0] != NULL)
+ {
+ // run_init_script(master_init_script);
+
+ // TODO: use the scripts
+ if (strindex(master_init_script, "repair_part2-master.sh") != NULL)
+ {
+ FILE *fp;
+
+ // create an empty index file
+ snprintf(temp, PATH_MAX, "%s/test/t1.MYI", master_dir);
+ fp = fopen(temp, "wb+");
+
+ fputs("1", fp);
+
+ fclose(fp);
+ }
+
+ }
+
+ // redirection files
+ snprintf(master_out, PATH_MAX, "%s/var/run/master%u.out",
+ mysql_test_dir, restarts);
+ snprintf(master_err, PATH_MAX, "%s/var/run/master%u.err",
+ mysql_test_dir, restarts);
+
+ snprintf(temp2,PATH_MAX,"%s/var",mysql_test_dir);
+ mkdir(temp2,0);
+ snprintf(temp2,PATH_MAX,"%s/var/log",mysql_test_dir);
+ mkdir(temp2,0);
+
+ // args
+ init_args(&al);
+ add_arg(&al, "%s", mysqld_file);
+ add_arg(&al, "--no-defaults");
+ add_arg(&al, "--log-bin=%s/var/log/master-bin",mysql_test_dir);
+ add_arg(&al, "--server-id=1");
+ add_arg(&al, "--basedir=%s", base_dir);
+ add_arg(&al, "--port=%u", master_port);
+ add_arg(&al, "--local-infile");
+ add_arg(&al, "--core");
+ add_arg(&al, "--datadir=%s", master_dir);
+ add_arg(&al, "--pid-file=%s", master_pid);
+ add_arg(&al, "--character-sets-dir=%s", char_dir);
+ add_arg(&al, "--tmpdir=%s", mysql_tmp_dir);
+ add_arg(&al, "--language=%s", lang_dir);
+
+ if (use_openssl)
+ {
+ add_arg(&al, "--ssl-ca=%s", ca_cert);
+ add_arg(&al, "--ssl-cert=%s", server_cert);
+ add_arg(&al, "--ssl-key=%s", server_key);
+ }
+
+ // $MASTER_40_ARGS
+ add_arg(&al, "--rpl-recovery-rank=1");
+ add_arg(&al, "--init-rpl-role=master");
+
+ // $SMALL_SERVER
+ add_arg(&al, "-O");
+ add_arg(&al, "key_buffer_size=1M");
+ add_arg(&al, "-O");
+ add_arg(&al, "sort_buffer=256K");
+ add_arg(&al, "-O");
+ add_arg(&al, "max_heap_table_size=1M");
+
+ // $EXTRA_MASTER_OPT
+ if (master_opt[0] != NULL)
+ {
+ char *p;
+ char *temp;
+
+ p = (char *)strtok(master_opt, " \t");
+
+ if ((temp = strstr(p, "timezone")) == NULL)
+ {
+ while(p)
+ {
+ add_arg(&al, "%s", p);
+ p = (char *)strtok(NULL, " \t");
+ }
+ }
+ else
+ {
+ //do nothing
+ }
+ }
+
+ // remove the pid file if it exists
+ remove(master_pid);
+
+ // spawn
+ if ((err = spawn(mysqld_file, &al, FALSE, NULL, master_out, master_err)) == 0)
+ {
+ sleep_until_file_exists(master_pid);
+
+ if ((err = wait_for_server_start(bin_dir, user, password, master_port)) == 0)
+ {
+ master_running = TRUE;
+ }
+ else
+ {
+ log_error("The master server went down early.");
+ }
+ }
+ else
+ {
+ log_error("Unable to start master server.");
+ }
+
+ // free_args
+ free_args(&al);
+}
+
+/******************************************************************************
+
+ start_slave()
+
+ Start the slave server.
+
+******************************************************************************/
+void start_slave()
+{
+ arg_list_t al;
+ int err, i;
+ char slave_out[PATH_MAX];
+ char slave_err[PATH_MAX];
+ char temp[PATH_MAX];
+
+ // skip?
+ if (skip_slave) return;
+
+ // remove stale binary logs
+ removef("%s/*-bin.*", slave_dir);
+
+ // remove stale binary logs
+ removef("%s/*.index", slave_dir);
+
+ // remove master.info file
+ removef("%s/master.info", slave_dir);
+
+ // remove relay files
+ removef("%s/var/log/*relay*", mysql_test_dir);
+
+ // remove relay-log.info file
+ removef("%s/relay-log.info", slave_dir);
+
+ // init script
+ if (slave_init_script[0] != NULL)
+ {
+ // run_init_script(slave_init_script);
+
+ // TODO: use the scripts
+ if (strindex(slave_init_script, "rpl000016-slave.sh") != NULL)
+ {
+ // create empty master.info file
+ snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
+ close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO));
+ }
+ else if (strindex(slave_init_script, "rpl000017-slave.sh") != NULL)
+ {
+ FILE *fp;
+
+ // create a master.info file
+ snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
+ fp = fopen(temp, "wb+");
+
+ fputs("master-bin.001\n", fp);
+ fputs("4\n", fp);
+ fputs("127.0.0.1\n", fp);
+ fputs("replicate\n", fp);
+ fputs("aaaaaaaaaaaaaaabthispartofthepasswordisnotused\n", fp);
+ fputs("9306\n", fp);
+ fputs("1\n", fp);
+ fputs("0\n", fp);
+
+ fclose(fp);
+ }
+ else if (strindex(slave_init_script, "rpl_rotate_logs-slave.sh") != NULL)
+ {
+ // create empty master.info file
+ snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
+ close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO));
+ }
+ }
+
+ // redirection files
+ snprintf(slave_out, PATH_MAX, "%s/var/run/slave%u.out",
+ mysql_test_dir, restarts);
+ snprintf(slave_err, PATH_MAX, "%s/var/run/slave%u.err",
+ mysql_test_dir, restarts);
+
+ // args
+ init_args(&al);
+ add_arg(&al, "%s", mysqld_file);
+ add_arg(&al, "--no-defaults");
+ add_arg(&al, "--log-bin=slave-bin");
+ add_arg(&al, "--relay_log=slave-relay-bin");
+ add_arg(&al, "--basedir=%s", base_dir);
+ add_arg(&al, "--port=%u", slave_port);
+ add_arg(&al, "--datadir=%s", slave_dir);
+ add_arg(&al, "--pid-file=%s", slave_pid);
+ add_arg(&al, "--character-sets-dir=%s", char_dir);
+ add_arg(&al, "--core");
+ add_arg(&al, "--tmpdir=%s", mysql_tmp_dir);
+ add_arg(&al, "--language=%s", lang_dir);
+
+ add_arg(&al, "--exit-info=256");
+ add_arg(&al, "--log-slave-updates");
+ add_arg(&al, "--init-rpl-role=slave");
+ add_arg(&al, "--skip-innodb");
+ add_arg(&al, "--skip-slave-start");
+ add_arg(&al, "--slave-load-tmpdir=../../var/tmp");
+
+ add_arg(&al, "--report-user=%s", user);
+ add_arg(&al, "--report-host=127.0.0.1");
+ add_arg(&al, "--report-port=%u", slave_port);
+
+ add_arg(&al, "--master-retry-count=10");
+ add_arg(&al, "-O");
+ add_arg(&al, "slave_net_timeout=10");
+
+ if (use_openssl)
+ {
+ add_arg(&al, "--ssl-ca=%s", ca_cert);
+ add_arg(&al, "--ssl-cert=%s", server_cert);
+ add_arg(&al, "--ssl-key=%s", server_key);
+ }
+
+ // slave master info
+ if (slave_master_info[0] != NULL)
+ {
+ char *p;
+
+ p = (char *)strtok(slave_master_info, " \t");
+
+ while(p)
+ {
+ add_arg(&al, "%s", p);
+
+ p = (char *)strtok(NULL, " \t");
+ }
+ }
+ else
+ {
+ add_arg(&al, "--master-user=%s", user);
+ add_arg(&al, "--master-password=%s", password);
+ add_arg(&al, "--master-host=127.0.0.1");
+ add_arg(&al, "--master-port=%u", master_port);
+ add_arg(&al, "--master-connect-retry=1");
+ add_arg(&al, "--server-id=2");
+ add_arg(&al, "--rpl-recovery-rank=2");
+ }
+
+ // small server
+ add_arg(&al, "-O");
+ add_arg(&al, "key_buffer_size=1M");
+ add_arg(&al, "-O");
+ add_arg(&al, "sort_buffer=256K");
+ add_arg(&al, "-O");
+ add_arg(&al, "max_heap_table_size=1M");
+
+ // opt args
+ if (slave_opt[0] != NULL)
+ {
+ char *p;
+
+ p = (char *)strtok(slave_opt, " \t");
+
+ while(p)
+ {
+ add_arg(&al, "%s", p);
+
+ p = (char *)strtok(NULL, " \t");
+ }
+ }
+
+ // remove the pid file if it exists
+ remove(slave_pid);
+
+ // spawn
+ if ((err = spawn(mysqld_file, &al, FALSE, NULL, slave_out, slave_err)) == 0)
+ {
+ sleep_until_file_exists(slave_pid);
+
+ if ((err = wait_for_server_start(bin_dir, user, password, slave_port)) == 0)
+ {
+ slave_running = TRUE;
+ }
+ else
+ {
+ log_error("The slave server went down early.");
+ }
+ }
+ else
+ {
+ log_error("Unable to start slave server.");
+ }
+
+ // free args
+ free_args(&al);
+}
+
+/******************************************************************************
+
+ mysql_start()
+
+ Start the mysql servers.
+
+******************************************************************************/
+void mysql_start()
+{
+ log_info("Starting the MySQL server(s): %u", ++restarts);
+ start_master();
+
+ start_slave();
+
+ // activate the test screen
+ ActivateScreen(getscreenhandle());
+}
+
+/******************************************************************************
+
+ stop_slave()
+
+ Stop the slave server.
+
+******************************************************************************/
+void stop_slave()
+{
+ int err;
+
+ // running?
+ if (!slave_running) return;
+
+ // stop
+ if ((err = stop_server(bin_dir, user, password, slave_port, slave_pid)) == 0)
+ {
+ slave_running = FALSE;
+ }
+ else
+ {
+ log_error("Unable to stop slave server.");
+ }
+}
+
+/******************************************************************************
+
+ stop_master()
+
+ Stop the master server.
+
+******************************************************************************/
+void stop_master()
+{
+ int err;
+
+ // running?
+ if (!master_running) return;
+
+ if ((err = stop_server(bin_dir, user, password, master_port, master_pid)) == 0)
+ {
+ master_running = FALSE;
+ }
+ else
+ {
+ log_error("Unable to stop master server.");
+ }
+}
+
+/******************************************************************************
+
+ mysql_stop()
+
+ Stop the mysql servers.
+
+******************************************************************************/
+void mysql_stop()
+{
+ log_info("Stopping the MySQL server(s)...");
+ stop_master();
+
+ stop_slave();
+
+ // activate the test screen
+ ActivateScreen(getscreenhandle());
+}
+
+/******************************************************************************
+
+ mysql_restart()
+
+ Restart the mysql servers.
+
+******************************************************************************/
+void mysql_restart()
+{
+
+ mysql_stop();
+
+ mysql_start();
+}
+
+/******************************************************************************
+
+ read_option()
+
+ Read the option file.
+
+******************************************************************************/
+int read_option(char *opt_file, char *opt)
+{
+ int fd, err;
+ int result;
+ char *p;
+ char buf[PATH_MAX];
+
+ // copy current option
+ strncpy(buf, opt, PATH_MAX);
+
+ // open options file
+ fd = open(opt_file, O_RDONLY);
+
+ err = read(fd, opt, PATH_MAX);
+
+ close(fd);
+
+ if (err > 0)
+ {
+ // terminate string
+ if ((p = strchr(opt, '\n')) != NULL)
+ {
+ *p = NULL;
+
+ // check for a '\r'
+ if ((p = strchr(opt, '\r')) != NULL)
+ {
+ *p = NULL;
+ }
+ }
+ else
+ {
+ opt[err] = NULL;
+ }
+
+ // check for $MYSQL_TEST_DIR
+ if ((p = strstr(opt, "$MYSQL_TEST_DIR")) != NULL)
+ {
+ char temp[PATH_MAX];
+
+ *p = NULL;
+
+ strcpy(temp, p + strlen("$MYSQL_TEST_DIR"));
+
+ strcat(opt, mysql_test_dir);
+
+ strcat(opt, temp);
+ }
+ }
+ else
+ {
+ // clear option
+ *opt = NULL;
+ }
+
+ // compare current option with previous
+ return strcmp(opt, buf);
+}
+
+/******************************************************************************
+
+ run_test()
+
+ Run the given test case.
+
+******************************************************************************/
+void run_test(char *test)
+{
+ char temp[PATH_MAX];
+ char *rstr;
+ double elapsed = 0;
+ int skip = FALSE;
+ int restart = FALSE;
+ int flag = FALSE;
+ struct stat info;
+
+ // single test?
+ if (!single_test)
+ {
+ // skip tests in the skip list
+ snprintf(temp, PATH_MAX, " %s ", test);
+ skip = (strindex(skip_test, temp) != NULL);
+ }
+
+ // skip test?
+ if (!skip)
+ {
+ char test_file[PATH_MAX];
+ char master_opt_file[PATH_MAX];
+ char slave_opt_file[PATH_MAX];
+ char slave_master_info_file[PATH_MAX];
+ char result_file[PATH_MAX];
+ char reject_file[PATH_MAX];
+ char out_file[PATH_MAX];
+ char err_file[PATH_MAX];
+ int err;
+ arg_list_t al;
+ NXTime_t start, stop;
+
+ // skip slave?
+ flag = skip_slave;
+ skip_slave = (strncmp(test, "rpl", 3) != 0);
+ if (flag != skip_slave) restart = TRUE;
+
+ // create files
+ snprintf(master_opt_file, PATH_MAX, "%s/%s-master.opt", test_dir, test);
+ snprintf(slave_opt_file, PATH_MAX, "%s/%s-slave.opt", test_dir, test);
+ snprintf(slave_master_info_file, PATH_MAX, "%s/%s.slave-mi", test_dir, test);
+ snprintf(reject_file, PATH_MAX, "%s/%s%s", result_dir, test, REJECT_SUFFIX);
+ snprintf(out_file, PATH_MAX, "%s/%s%s", result_dir, test, OUT_SUFFIX);
+ snprintf(err_file, PATH_MAX, "%s/%s%s", result_dir, test, ERR_SUFFIX);
+
+ // netware specific files
+ snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, NW_TEST_SUFFIX);
+ if (stat(test_file, &info))
+ {
+ snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, TEST_SUFFIX);
+ if(access(test_file,0))
+ {
+ printf("Invalid test name %s, %s file not found\n",test,test_file);
+ return;
+ }
+ }
+
+ snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, NW_RESULT_SUFFIX);
+ if (stat(result_file, &info))
+ {
+ snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, RESULT_SUFFIX);
+ }
+
+ // init scripts
+ snprintf(master_init_script, PATH_MAX, "%s/%s-master.sh", test_dir, test);
+ if (stat(master_init_script, &info))
+ master_init_script[0] = NULL;
+ else
+ restart = TRUE;
+
+ snprintf(slave_init_script, PATH_MAX, "%s/%s-slave.sh", test_dir, test);
+ if (stat(slave_init_script, &info))
+ slave_init_script[0] = NULL;
+ else
+ restart = TRUE;
+
+ // read options
+ if (read_option(master_opt_file, master_opt)) restart = TRUE;
+ if (read_option(slave_opt_file, slave_opt)) restart = TRUE;
+ if (read_option(slave_master_info_file, slave_master_info)) restart = TRUE;
+
+ // cleanup previous run
+ remove(reject_file);
+ remove(out_file);
+ remove(err_file);
+
+ // start or restart?
+ if (!master_running) mysql_start();
+ else if (restart) mysql_restart();
+
+ // let the system stabalize
+ sleep(1);
+
+ // show test
+ log("%-46s ", test);
+
+ // args
+ init_args(&al);
+ add_arg(&al, "%s", mysqltest_file);
+ add_arg(&al, "--no-defaults");
+ add_arg(&al, "--port=%u", master_port);
+ add_arg(&al, "--database=%s", db);
+ add_arg(&al, "--user=%s", user);
+ add_arg(&al, "--password=%s", password);
+ add_arg(&al, "--silent");
+ add_arg(&al, "--basedir=%s/", mysql_test_dir);
+ add_arg(&al, "--host=127.0.0.1");
+ add_arg(&al, "-v");
+ add_arg(&al, "-R");
+ add_arg(&al, "%s", result_file);
+
+ if (use_openssl)
+ {
+ add_arg(&al, "--ssl-ca=%s", ca_cert);
+ add_arg(&al, "--ssl-cert=%s", client_cert);
+ add_arg(&al, "--ssl-key=%s", client_key);
+ }
+
+ // start timer
+ NXGetTime(NX_SINCE_BOOT, NX_USECONDS, &start);
+
+ // spawn
+ err = spawn(mysqltest_file, &al, TRUE, test_file, out_file, err_file);
+
+ // stop timer
+ NXGetTime(NX_SINCE_BOOT, NX_USECONDS, &stop);
+
+ // calculate
+ elapsed = ((double)(stop - start)) / NX_USECONDS;
+ total_time += elapsed;
+
+ // free args
+ free_args(&al);
+
+ if (err == 0)
+ {
+ // pass
+ rstr = TEST_PASS;
+ ++total_pass;
+
+ // increment total
+ ++total_test;
+ }
+ else if (err == 2)
+ {
+ // skip
+ rstr = TEST_SKIP;
+ ++total_skip;
+ }
+ else if (err == 1)
+ {
+ // fail
+ rstr = TEST_FAIL;
+ ++total_fail;
+
+ // increment total
+ ++total_test;
+ }
+ else
+ {
+ rstr = TEST_BAD;
+ }
+ }
+ else // early skips
+ {
+ // show test
+ log("%-46s ", test);
+
+ // skip
+ rstr = TEST_SKIP;
+ ++total_skip;
+ }
+
+ // result
+ log("%10.06f %-14s\n", elapsed, rstr);
+}
+
+/******************************************************************************
+
+ vlog()
+
+ Log the message.
+
+******************************************************************************/
+void vlog(char *format, va_list ap)
+{
+ vfprintf(stdout, format, ap);
+ fflush(stdout);
+
+ if (log_fd)
+ {
+ vfprintf(log_fd, format, ap);
+ fflush(log_fd);
+ }
+}
+
+/******************************************************************************
+
+ log()
+
+ Log the message.
+
+******************************************************************************/
+void log(char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ vlog(format, ap);
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ log_info()
+
+ Log the given information.
+
+******************************************************************************/
+void log_info(char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ log("-- INFO : ");
+ vlog(format, ap);
+ log("\n");
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ log_error()
+
+ Log the given error.
+
+******************************************************************************/
+void log_error(char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ log("-- ERROR: ");
+ vlog(format, ap);
+ log("\n");
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ log_errno()
+
+ Log the given error and errno.
+
+******************************************************************************/
+void log_errno(char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ log("-- ERROR: (%003u) ", errno);
+ vlog(format, ap);
+ log("\n");
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ die()
+
+ Exit the application.
+
+******************************************************************************/
+void die(char *msg)
+{
+ log_error(msg);
+
+ pressanykey();
+
+ exit(-1);
+}
+
+/******************************************************************************
+
+ setup()
+
+ Setup the mysql test enviornment.
+
+******************************************************************************/
+void setup(char *file)
+{
+ char temp[PATH_MAX];
+ char mysqldump_load[PATH_MAX*2],mysqlbinlog_load[PATH_MAX*2];
+
+ char *p;
+
+ // set the timezone for the timestamp test
+ setenv("TZ", "GMT-3", TRUE);
+
+ // find base dir
+ strcpy(temp, strlwr(file));
+ while((p = strchr(temp, '\\')) != NULL) *p = '/';
+
+ if ((p = strindex(temp, "/mysql-test/")) != NULL)
+ {
+ *p = NULL;
+ strcpy(base_dir, temp);
+ }
+
+ // setup paths
+ snprintf(bin_dir, PATH_MAX, "%s/bin", base_dir);
+ snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir);
+ snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir);
+ snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir);
+ snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir);
+ snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir);
+ snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
+ snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir);
+ snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir);
+
+#ifdef HAVE_OPENSSL
+ use_openssl = TRUE;
+#endif // HAVE_OPENSSL
+
+ // OpenSSL paths
+ snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir);
+ snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir);
+ snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir);
+ snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir);
+ snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir);
+
+ // setup files
+ snprintf(mysqld_file, PATH_MAX, "%s/mysqld", bin_dir);
+ snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir);
+ snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
+ snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir);
+ snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir);
+
+ // create log file
+ snprintf(temp, PATH_MAX, "%s/mysql-test-run.log", mysql_test_dir);
+ if ((log_fd = fopen(temp, "w+")) == NULL)
+ {
+ log_errno("Unable to create log file.");
+ }
+
+ // prepare skip test list
+ while((p = strchr(skip_test, ',')) != NULL) *p = ' ';
+ strcpy(temp, strlwr(skip_test));
+ snprintf(skip_test, PATH_MAX, " %s ", temp);
+
+ snprintf(mysqlbinlog_load,PATH_MAX*2,"%s/mysqlbinlog --no-defaults --local-load=%s",bin_dir,mysql_tmp_dir);
+ snprintf(mysqldump_load,PATH_MAX*2,"%s/mysqldump --no-defaults -uroot --port=%d",bin_dir,master_port);
+ // environment
+ setenv("MYSQL_TEST_DIR", mysql_test_dir, 1);
+ setenv("MYSQL_DUMP", mysqldump_load, 1);
+ setenv("MYSQL_BINLOG", mysqlbinlog_load, 1);
+ setenv("MASTER_MYPORT", "9306", 1);
+}
+
+/******************************************************************************
+
+ main()
+
+******************************************************************************/
+int main(int argc, char **argv)
+{
+ // setup
+ setup(argv[0]);
+
+ // header
+ log("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+
+ log("Initializing Tests...\n");
+
+ // install test databases
+ mysql_install_db();
+
+ log("Starting Tests...\n");
+
+ log("\n");
+ log(HEADER);
+ log(DASH);
+
+ if (argc > 1)
+ {
+ int i;
+
+ // single test
+ single_test = TRUE;
+
+ for (i = 1; i < argc; i++)
+ {
+ // run given test
+ run_test(argv[i]);
+ }
+ }
+ else
+ {
+ // run all tests
+ DIR *dir = opendir(test_dir);
+ DIR *entry;
+ char test[NAME_MAX];
+ char *p;
+
+ // single test
+ single_test = FALSE;
+
+ if (dir == NULL)
+ {
+ die("Unable to open tests directory.");
+ }
+
+ while((entry = readdir(dir)) != NULL)
+ {
+ if (!S_ISDIR(entry->d_type))
+ {
+ strcpy(test, strlwr(entry->d_name));
+
+ // find the test suffix
+ if ((p = strindex(test, TEST_SUFFIX)) != NULL)
+ {
+ // null terminate at the suffix
+ *p = '\0';
+
+ // run test
+ run_test(test);
+ }
+ }
+ }
+
+ closedir(dir);
+ }
+
+ // stop server
+ mysql_stop();
+
+ log(DASH);
+ log("\n");
+
+ log("Ending Tests...\n");
+
+ // report stats
+ report_stats();
+
+ // close log
+ if (log_fd) fclose(log_fd);
+
+ // keep results up
+ pressanykey();
+
+ return 0;
+}
+
diff --git a/netware/mysql_test_run.def b/netware/mysql_test_run.def
new file mode 100644
index 00000000000..b34f62a1f91
--- /dev/null
+++ b/netware/mysql_test_run.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MySQL Test Run
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+STACKSIZE 65536
+SCREENNAME "MySQL Test Run"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Test Run"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
diff --git a/netware/mysqladmin.def b/netware/mysqladmin.def
new file mode 100644
index 00000000000..0ace36992b1
--- /dev/null
+++ b/netware/mysqladmin.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MySQL Admin
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL Admin"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Admin Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysqlbinlog.def b/netware/mysqlbinlog.def
new file mode 100644
index 00000000000..89677b4a353
--- /dev/null
+++ b/netware/mysqlbinlog.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MySQL Binary Log
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL Binary Log Dump Tool"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Binary Log Dump Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysqlcheck.def b/netware/mysqlcheck.def
new file mode 100644
index 00000000000..8820e9aae8e
--- /dev/null
+++ b/netware/mysqlcheck.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MySQL Client
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL Check Tool"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Check Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysqld.def b/netware/mysqld.def
new file mode 100644
index 00000000000..6856aefe56c
--- /dev/null
+++ b/netware/mysqld.def
@@ -0,0 +1,12 @@
+#------------------------------------------------------------------------------
+# MySQL Server
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Database Server"
+VERSION 4, 0
+MULTIPLE
+STACKSIZE 65536
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysqld_safe.c b/netware/mysqld_safe.c
new file mode 100644
index 00000000000..a815497ac0f
--- /dev/null
+++ b/netware/mysqld_safe.c
@@ -0,0 +1,712 @@
+/*
+ Copyright (c) 2003 Novell, Inc. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <monitor.h>
+#include <strings.h>
+#include <getopt.h>
+#include <screen.h>
+#include <dirent.h>
+
+#include "my_config.h"
+#include "my_manage.h"
+
+/******************************************************************************
+
+ global variables
+
+******************************************************************************/
+char autoclose;
+char basedir[PATH_MAX];
+char checktables;
+char datadir[PATH_MAX];
+char pid_file[PATH_MAX];
+char address[PATH_MAX];
+char port[PATH_MAX];
+char err_log[PATH_MAX];
+char safe_log[PATH_MAX];
+char mysqld[PATH_MAX];
+char hostname[PATH_MAX];
+char default_option[PATH_MAX];
+
+FILE *log_fd = NULL;
+
+/******************************************************************************
+
+ prototypes
+
+******************************************************************************/
+
+void usage(void);
+void vlog(char *, va_list);
+void log(char *, ...);
+void start_defaults(int, char*[]);
+void finish_defaults();
+void read_defaults(arg_list_t *);
+void parse_args(int, char*[]);
+void get_options(int, char*[]);
+void check_data_vol();
+void check_setup();
+void check_tables();
+void mysql_start(int, char*[]);
+
+/******************************************************************************
+
+ functions
+
+******************************************************************************/
+
+/******************************************************************************
+
+ usage()
+
+ Show usage.
+
+******************************************************************************/
+void usage(void)
+{
+ // keep the screen up
+ setscreenmode(SCR_NO_MODE);
+
+ puts("\
+\n\
+usage: mysqld_safe [options]\n\
+\n\
+Program to start the MySQL daemon and restart it if it dies unexpectedly.\n\
+All options, besides those listed below, are passed on to the MySQL daemon.\n\
+\n\
+options:\n\
+\n\
+--autoclose Automatically close the mysqld_safe screen.\n\
+\n\
+--check-tables Check the tables before starting the MySQL daemon.\n\
+\n\
+--err-log=<file> Send the MySQL daemon error output to <file>.\n\
+\n\
+--help Show this help information.\n\
+\n\
+--mysqld=<file> Use the <file> MySQL daemon.\n\
+\n\
+ ");
+
+ exit(-1);
+}
+
+/******************************************************************************
+
+ vlog()
+
+ Log the message.
+
+******************************************************************************/
+void vlog(char *format, va_list ap)
+{
+ vfprintf(stdout, format, ap);
+ fflush(stdout);
+
+ if (log_fd)
+ {
+ vfprintf(log_fd, format, ap);
+ fflush(log_fd);
+ }
+}
+
+/******************************************************************************
+
+ log()
+
+ Log the message.
+
+******************************************************************************/
+void log(char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ vlog(format, ap);
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ start_defaults()
+
+ Start setting the defaults.
+
+******************************************************************************/
+void start_defaults(int argc, char *argv[])
+{
+ struct stat buf;
+ int i;
+
+ // default options
+ static char *default_options[] =
+ {
+ "--no-defaults",
+ "--defaults-file=",
+ "--defaults-extra-file=",
+ NULL
+ };
+
+ // autoclose
+ autoclose = FALSE;
+
+ // basedir
+ get_basedir(argv[0], basedir);
+
+ // check-tables
+ checktables = FALSE;
+
+ // hostname
+ if (gethostname(hostname,PATH_MAX) < 0)
+ {
+ // default
+ strcpy(hostname,"mysql");
+ }
+
+ // address
+ snprintf(address, PATH_MAX, "0.0.0.0");
+
+ // port
+ snprintf(port, PATH_MAX, "3306");
+
+ // default option
+ default_option[0] = NULL;
+ for (i=0; (argc > 1) && default_options[i]; i++)
+ {
+ if(!strnicmp(argv[1], default_options[i], strlen(default_options[i])))
+ {
+ strncpy(default_option, argv[1], PATH_MAX);
+ break;
+ }
+ }
+
+ // set after basedir is established
+ datadir[0] = NULL;
+ pid_file[0] = NULL;
+ err_log[0] = NULL;
+ safe_log[0] = NULL;
+ mysqld[0] = NULL;
+}
+
+/******************************************************************************
+
+ finish_defaults()
+
+ Finish settig the defaults.
+
+******************************************************************************/
+void finish_defaults()
+{
+ struct stat buf;
+ int i;
+
+ // datadir
+ if (!datadir[0]) snprintf(datadir, PATH_MAX, "%s/data", basedir);
+
+ // pid-file
+ if (!pid_file[0]) snprintf(pid_file, PATH_MAX, "%s/%s.pid", datadir, hostname);
+
+ // err-log
+ if (!err_log[0]) snprintf(err_log, PATH_MAX, "%s/%s.err", datadir, hostname);
+
+ // safe-log
+ if (!safe_log[0]) snprintf(safe_log, PATH_MAX, "%s/%s.safe", datadir, hostname);
+
+ // mysqld
+ if (!mysqld[0]) snprintf(mysqld, PATH_MAX, "%s/bin/mysqld-max", basedir);
+
+ if (stat(mysqld, &buf))
+ {
+ snprintf(mysqld, PATH_MAX, "%s/bin/mysqld", basedir);
+ }
+}
+
+/******************************************************************************
+
+ read_defaults()
+
+ Read the defaults.
+
+******************************************************************************/
+void read_defaults(arg_list_t *pal)
+{
+ arg_list_t al;
+ char defaults_file[PATH_MAX];
+ char mydefaults[PATH_MAX];
+ char line[PATH_MAX];
+ FILE *fp;
+
+ // defaults output file
+ snprintf(defaults_file, PATH_MAX, "%s/bin/defaults.out", basedir);
+ remove(defaults_file);
+
+ // mysqladmin file
+ snprintf(mydefaults, PATH_MAX, "%s/bin/my_print_defaults", basedir);
+
+ // args
+ init_args(&al);
+ add_arg(&al, mydefaults);
+ if (default_option[0]) add_arg(&al, default_option);
+ add_arg(&al, "mysqld");
+ add_arg(&al, "server");
+ add_arg(&al, "mysqld_safe");
+ add_arg(&al, "safe_mysqld");
+
+ spawn(mydefaults, &al, TRUE, NULL, defaults_file, NULL);
+
+ free_args(&al);
+
+ // gather defaults
+ if((fp = fopen(defaults_file, "r")) != NULL)
+ {
+ while(fgets(line, PATH_MAX, fp))
+ {
+ char *p;
+
+ // remove end-of-line character
+ if ((p = strrchr(line, '\n')) != NULL) *p = '\0';
+
+ // add the option as an argument
+ add_arg(pal, line);
+ }
+
+ fclose(fp);
+ }
+
+ // remove file
+ remove(defaults_file);
+}
+
+/******************************************************************************
+
+ parse_args()
+
+ Get the options.
+
+******************************************************************************/
+void parse_args(int argc, char *argv[])
+{
+ int index = 0;
+ int c;
+
+ // parse options
+ enum opts
+ {
+ OPT_BASEDIR = 0xFF,
+ OPT_DATADIR,
+ OPT_PID_FILE,
+ OPT_BIND_ADDRESS,
+ OPT_PORT,
+ OPT_ERR_LOG,
+ OPT_SAFE_LOG,
+ OPT_MYSQLD,
+ OPT_HELP
+ };
+
+ static struct option options[] =
+ {
+ {"autoclose", no_argument, &autoclose, TRUE},
+ {"basedir", required_argument, 0, OPT_BASEDIR},
+ {"check-tables", no_argument, &checktables, TRUE},
+ {"datadir", required_argument, 0, OPT_DATADIR},
+ {"pid-file", required_argument, 0, OPT_PID_FILE},
+ {"bind-address", required_argument, 0, OPT_BIND_ADDRESS},
+ {"port", required_argument, 0, OPT_PORT},
+ {"err-log", required_argument, 0, OPT_ERR_LOG},
+ {"safe-log", required_argument, 0, OPT_SAFE_LOG},
+ {"mysqld", required_argument, 0, OPT_MYSQLD},
+ {"help", no_argument, 0, OPT_HELP},
+ {0, 0, 0, 0}
+ };
+
+ // we have to reset getopt_long because we use it multiple times
+ optind = 1;
+
+ // turn off error reporting
+ opterr = 0;
+
+ while ((c = getopt_long(argc, argv, "b:h:P:", options, &index)) >= 0)
+ {
+ switch (c)
+ {
+ case OPT_BASEDIR:
+ case 'b':
+ strcpy(basedir, optarg);
+ break;
+
+ case OPT_DATADIR:
+ case 'h':
+ strcpy(datadir, optarg);
+ break;
+
+ case OPT_PID_FILE:
+ strcpy(pid_file, optarg);
+ break;
+
+ case OPT_BIND_ADDRESS:
+ strcpy(address, optarg);
+ break;
+
+ case OPT_PORT:
+ case 'P':
+ strcpy(port, optarg);
+ break;
+
+ case OPT_ERR_LOG:
+ strcpy(err_log, optarg);
+ break;
+
+ case OPT_SAFE_LOG:
+ strcpy(safe_log, optarg);
+ break;
+
+ case OPT_MYSQLD:
+ strcpy(mysqld, optarg);
+ break;
+
+ case OPT_HELP:
+ usage();
+ break;
+
+ default:
+ // ignore
+ break;
+ }
+ }
+}
+
+/******************************************************************************
+
+ get_options()
+
+ Get the options.
+
+******************************************************************************/
+void get_options(int argc, char *argv[])
+{
+ arg_list_t al;
+
+ // start defaults
+ start_defaults(argc, argv);
+
+ // default file arguments
+ init_args(&al);
+ add_arg(&al, "ignore");
+ read_defaults(&al);
+ parse_args(al.argc, al.argv);
+ free_args(&al);
+
+ // command-line arguments
+ parse_args(argc, argv);
+
+ // finish defaults
+ finish_defaults();
+}
+
+/******************************************************************************
+
+ check_data_vol()
+
+ Check the database volume.
+
+******************************************************************************/
+void check_data_vol()
+{
+ // warn if the data is on a Traditional volume
+ struct volume_info vol;
+ char buff[PATH_MAX];
+ char *p;
+
+ // clear struct
+ memset(&vol, 0, sizeof(vol));
+
+ // find volume name
+ strcpy(buff, datadir);
+ if (p = strchr(buff, ':'))
+ {
+ // terminate after volume name
+ *p = 0;
+ }
+ else
+ {
+ // assume SYS volume
+ strcpy(buff, "SYS");
+ }
+
+ // retrieve information
+ netware_vol_info_from_name(&vol, buff);
+
+ if ((vol.flags & VOL_NSS_PRESENT) == 0)
+ {
+ log("Error: Either the data directory does not exist or is not on an NSS volume!\n\n");
+ exit(-1);
+ }
+}
+
+/******************************************************************************
+
+ check_setup()
+
+ Check the current setup.
+
+******************************************************************************/
+void check_setup()
+{
+ struct stat info;
+ char temp[PATH_MAX];
+
+ // remove any current pid_file
+ if (!stat(pid_file, &info) && (remove(pid_file) < 0))
+ {
+ log("ERROR: Unable to remove current pid file!\n\n");
+ exit(-1);
+ }
+
+ // check the data volume
+ check_data_vol();
+
+ // check for a database
+ snprintf(temp, PATH_MAX, "%s/mysql/host.frm", datadir);
+ if (stat(temp, &info))
+ {
+ log("ERROR: No database found in the data directory!\n\n");
+ exit(-1);
+ }
+}
+
+/******************************************************************************
+
+ check_tables()
+
+ Check the database tables.
+
+******************************************************************************/
+void check_tables()
+{
+ arg_list_t al;
+ char mycheck[PATH_MAX];
+ char table[PATH_MAX];
+ char db[PATH_MAX];
+ DIR *datadir_entry, *db_entry, *table_entry;
+
+ // status
+ log("checking tables...\n");
+
+ // list databases
+ if ((datadir_entry = opendir(datadir)) == NULL)
+ {
+ return;
+ }
+
+ while((db_entry = readdir(datadir_entry)) != NULL)
+ {
+ if (db_entry->d_name[0] == '.')
+ {
+ // Skip
+ }
+ else if (S_ISDIR(db_entry->d_type))
+ {
+ // create long db name
+ snprintf(db, PATH_MAX, "%s/%s", datadir, db_entry->d_name);
+
+ // list tables
+ if ((db_entry = opendir(db)) == NULL)
+ {
+ continue;
+ }
+
+ while((table_entry = readdir(db_entry)) != NULL)
+ {
+ // create long table name
+ snprintf(table, PATH_MAX, "%s/%s", db, strlwr(table_entry->d_name));
+
+ if (strindex(table, ".myi"))
+ {
+ // ** myisamchk
+
+ // mysqladmin file
+ snprintf(mycheck, PATH_MAX, "%s/bin/myisamchk", basedir);
+
+ // args
+ init_args(&al);
+ add_arg(&al, mycheck);
+ add_arg(&al, "--silent");
+ add_arg(&al, "--force");
+ add_arg(&al, "--fast");
+ add_arg(&al, "--medium-check");
+ add_arg(&al, "-O");
+ add_arg(&al, "key_buffer=64M");
+ add_arg(&al, "-O");
+ add_arg(&al, "sort_buffer=64M");
+ add_arg(&al, table);
+
+ spawn(mycheck, &al, TRUE, NULL, NULL, NULL);
+
+ free_args(&al);
+ }
+ else if (strindex(table, ".ism"))
+ {
+ // ** isamchk
+
+ // mysqladmin file
+ snprintf(mycheck, PATH_MAX, "%s/bin/isamchk", basedir);
+
+ // args
+ init_args(&al);
+ add_arg(&al, mycheck);
+ add_arg(&al, "--silent");
+ add_arg(&al, "--force");
+ add_arg(&al, "-O");
+ add_arg(&al, "sort_buffer=64M");
+ add_arg(&al, table);
+
+ spawn(mycheck, &al, TRUE, NULL, NULL, NULL);
+
+ free_args(&al);
+ }
+ }
+ }
+ }
+}
+
+/******************************************************************************
+
+ mysql_start()
+
+ Start the mysql server.
+
+******************************************************************************/
+void mysql_start(int argc, char *argv[])
+{
+ arg_list_t al;
+ int i, j, err;
+ struct stat info;
+ time_t cal;
+ struct tm lt;
+ char stamp[PATH_MAX];
+ char skip;
+
+ // private options
+ static char *private_options[] =
+ {
+ "--autoclose",
+ "--check-tables",
+ "--help",
+ "--err-log=",
+ "--mysqld=",
+ NULL
+ };
+
+ // args
+ init_args(&al);
+ add_arg(&al, "%s", mysqld);
+
+ // parent args
+ for(i = 1; i < argc; i++)
+ {
+ skip = FALSE;
+
+ // skip private arguments
+ for (j=0; private_options[j]; j++)
+ {
+ if(!strnicmp(argv[i], private_options[j], strlen(private_options[j])))
+ {
+ skip = TRUE;
+ break;
+ }
+ }
+
+ if (!skip) add_arg(&al, "%s", argv[i]);
+ }
+
+ // spawn
+ do
+ {
+ // check the database tables
+ if (checktables) check_tables();
+
+ // status
+ time(&cal);
+ localtime_r(&cal, &lt);
+ strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", &lt);
+ log("mysql started : %s\n", stamp);
+
+ // spawn mysqld
+ spawn(mysqld, &al, TRUE, NULL, NULL, err_log);
+ }
+ while (!stat(pid_file, &info));
+
+ // status
+ time(&cal);
+ localtime_r(&cal, &lt);
+ strftime(stamp, PATH_MAX, "%d %b %Y %H:%M:%S", &lt);
+ log("mysql stopped : %s\n\n", stamp);
+
+ // free args
+ free_args(&al);
+}
+
+/******************************************************************************
+
+ main()
+
+******************************************************************************/
+int main(int argc, char **argv)
+{
+ char temp[PATH_MAX];
+
+ // get the options
+ get_options(argc, argv);
+
+ // keep the screen up
+ if (!autoclose) setscreenmode(SCR_NO_MODE);
+
+ // create log file
+ log_fd = fopen(safe_log, "w+");
+
+ // header
+ log("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+
+ // status
+ log("address : %s\n", address);
+ log("port : %s\n", port);
+ log("daemon : %s\n", mysqld);
+ log("base directory : %s\n", basedir);
+ log("data directory : %s\n", datadir);
+ log("pid file : %s\n", pid_file);
+ log("error file : %s\n", err_log);
+ log("log file : %s\n", safe_log);
+ log("\n");
+
+ // check setup
+ check_setup();
+
+ // start the MySQL server
+ mysql_start(argc, argv);
+
+ // close log file
+ if (log_fd) fclose(log_fd);
+
+ return 0;
+}
diff --git a/netware/mysqld_safe.def b/netware/mysqld_safe.def
new file mode 100644
index 00000000000..9080ef783c9
--- /dev/null
+++ b/netware/mysqld_safe.def
@@ -0,0 +1,12 @@
+#------------------------------------------------------------------------------
+# MySQLd Safe
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL Database Server"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Database Server Monitor"
+VERSION 4, 0
+MULTIPLE
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysqldump.def b/netware/mysqldump.def
new file mode 100644
index 00000000000..901c9b262dc
--- /dev/null
+++ b/netware/mysqldump.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MySQL Admin
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL Dump Tool"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Dump Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysqlimport.def b/netware/mysqlimport.def
new file mode 100644
index 00000000000..d6f7fcb6bbd
--- /dev/null
+++ b/netware/mysqlimport.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MySQL Client
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL Import"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Import Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysqlshow.def b/netware/mysqlshow.def
new file mode 100644
index 00000000000..2b41386f643
--- /dev/null
+++ b/netware/mysqlshow.def
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# MySQL Show
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+SCREENNAME "MySQL Show"
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Show Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/mysqltest.def b/netware/mysqltest.def
new file mode 100644
index 00000000000..d98f6436a4a
--- /dev/null
+++ b/netware/mysqltest.def
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# MySQL Admin
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Test Case Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/pack_isam.def b/netware/pack_isam.def
new file mode 100644
index 00000000000..f0f5a7e328a
--- /dev/null
+++ b/netware/pack_isam.def
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# Pack ISAM
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL ISAM Table Pack Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/perror.def b/netware/perror.def
new file mode 100644
index 00000000000..f1d23715f55
--- /dev/null
+++ b/netware/perror.def
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# PERROR
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Error Code Description Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/replace.def b/netware/replace.def
new file mode 100644
index 00000000000..b55690152b9
--- /dev/null
+++ b/netware/replace.def
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# Replace
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL Text Replacement Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/resolveip.def b/netware/resolveip.def
new file mode 100644
index 00000000000..10b99304e22
--- /dev/null
+++ b/netware/resolveip.def
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# Resolve IP
+#------------------------------------------------------------------------------
+MODULE libc.nlm
+COPYRIGHT "(c) 2003 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
+DESCRIPTION "MySQL IP/Hostname Resolve Tool"
+VERSION 4, 0
+XDCDATA ../netware/mysql.xdc
+#DEBUG
+
diff --git a/netware/test_db.sql b/netware/test_db.sql
new file mode 100644
index 00000000000..d43b632289c
--- /dev/null
+++ b/netware/test_db.sql
@@ -0,0 +1,20 @@
+CREATE DATABASE mysql;
+CREATE DATABASE test;
+
+USE mysql;
+
+CREATE TABLE db (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User)) comment='Database privileges';
+
+CREATE TABLE host (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db)) comment='Host privileges; Merged with database privileges';
+
+CREATE TABLE user (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') DEFAULT 'N' NOT NULL, File_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User)) comment='Users and global privileges';
+
+INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+INSERT INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+
+CREATE TABLE func (name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') NOT NULL, PRIMARY KEY (name)) comment='User defined functions';
+
+CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(60) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor)) comment='Table privileges';
+
+CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name)) comment='Column privileges';
diff --git a/pstack/Makefile.am b/pstack/Makefile.am
new file mode 100644
index 00000000000..863a52f4488
--- /dev/null
+++ b/pstack/Makefile.am
@@ -0,0 +1,36 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#
+# As pstack doesn't work on all configurations, we have to use
+# the USE_PSTACK hack to get all files into distribution
+#
+
+SUBDIRS = aout
+INCLUDES = -I$(srcdir)/../include -I../include
+noinst_HEADERS = bucomm.h debug.h ieee.h budbg.h demangle.h \
+ linuxthreads.h pstack.h pstacktrace.h
+SRC= bucomm.c filemode.c linuxthreads.c rddbg.c \
+ debug.c ieee.c pstack.c stabs.c
+EXTRA_DIST= $(SRC)
+
+if COMPILE_PSTACK
+pkglib_LIBRARIES = libpstack.a
+libpstack_a_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c debug.c ieee.c pstack.c stabs.c
+endif
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/pstack/aout/Makefile.am b/pstack/aout/Makefile.am
new file mode 100644
index 00000000000..0b02cb7b643
--- /dev/null
+++ b/pstack/aout/Makefile.am
@@ -0,0 +1 @@
+noinst_HEADERS = aout64.h stab.def stab_gnu.h
diff --git a/pstack/aout/aout64.h b/pstack/aout/aout64.h
new file mode 100644
index 00000000000..76f1140b682
--- /dev/null
+++ b/pstack/aout/aout64.h
@@ -0,0 +1,475 @@
+/* `a.out' object-file definitions, including extensions to 64-bit fields */
+
+#ifndef __A_OUT_64_H__
+#define __A_OUT_64_H__
+
+/* This is the layout on disk of the 32-bit or 64-bit exec header. */
+
+#ifndef external_exec
+struct external_exec
+{
+ bfd_byte e_info[4]; /* magic number and stuff */
+ bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */
+ bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */
+ bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */
+ bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */
+ bfd_byte e_entry[BYTES_IN_WORD]; /* start address */
+ bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */
+ bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */
+};
+
+#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7)
+
+/* Magic numbers for a.out files */
+
+#if ARCH_SIZE==64
+#define OMAGIC 0x1001 /* Code indicating object file */
+#define ZMAGIC 0x1002 /* Code indicating demand-paged executable. */
+#define NMAGIC 0x1003 /* Code indicating pure executable. */
+
+/* There is no 64-bit QMAGIC as far as I know. */
+
+#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC)
+#else
+#define OMAGIC 0407 /* ...object file or impure executable. */
+#define NMAGIC 0410 /* Code indicating pure executable. */
+#define ZMAGIC 0413 /* Code indicating demand-paged executable. */
+#define BMAGIC 0415 /* Used by a b.out object. */
+
+/* This indicates a demand-paged executable with the header in the text.
+ It is used by 386BSD (and variants) and Linux, at least. */
+#ifndef QMAGIC
+#define QMAGIC 0314
+#endif
+# ifndef N_BADMAG
+# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC \
+ && N_MAGIC(x) != QMAGIC)
+# endif /* N_BADMAG */
+#endif
+
+#endif
+
+#ifdef QMAGIC
+#define N_IS_QMAGIC(x) (N_MAGIC (x) == QMAGIC)
+#else
+#define N_IS_QMAGIC(x) (0)
+#endif
+
+/* The difference between TARGET_PAGE_SIZE and N_SEGSIZE is that TARGET_PAGE_SIZE is
+ the finest granularity at which you can page something, thus it
+ controls the padding (if any) before the text segment of a ZMAGIC
+ file. N_SEGSIZE is the resolution at which things can be marked as
+ read-only versus read/write, so it controls the padding between the
+ text segment and the data segment (in memory; on disk the padding
+ between them is TARGET_PAGE_SIZE). TARGET_PAGE_SIZE and N_SEGSIZE are the same
+ for most machines, but different for sun3. */
+
+/* By default, segment size is constant. But some machines override this
+ to be a function of the a.out header (e.g. machine type). */
+
+#ifndef N_SEGSIZE
+#define N_SEGSIZE(x) SEGMENT_SIZE
+#endif
+
+/* Virtual memory address of the text section.
+ This is getting very complicated. A good reason to discard a.out format
+ for something that specifies these fields explicitly. But til then...
+
+ * OMAGIC and NMAGIC files:
+ (object files: text for "relocatable addr 0" right after the header)
+ start at 0, offset is EXEC_BYTES_SIZE, size as stated.
+ * The text address, offset, and size of ZMAGIC files depend
+ on the entry point of the file:
+ * entry point below TEXT_START_ADDR:
+ (hack for SunOS shared libraries)
+ start at 0, offset is 0, size as stated.
+ * If N_HEADER_IN_TEXT(x) is true (which defaults to being the
+ case when the entry point is EXEC_BYTES_SIZE or further into a page):
+ no padding is needed; text can start after exec header. Sun
+ considers the text segment of such files to include the exec header;
+ for BFD's purposes, we don't, which makes more work for us.
+ start at TEXT_START_ADDR + EXEC_BYTES_SIZE, offset is EXEC_BYTES_SIZE,
+ size as stated minus EXEC_BYTES_SIZE.
+ * If N_HEADER_IN_TEXT(x) is false (which defaults to being the case when
+ the entry point is less than EXEC_BYTES_SIZE into a page (e.g. page
+ aligned)): (padding is needed so that text can start at a page boundary)
+ start at TEXT_START_ADDR, offset TARGET_PAGE_SIZE, size as stated.
+
+ Specific configurations may want to hardwire N_HEADER_IN_TEXT,
+ for efficiency or to allow people to play games with the entry point.
+ In that case, you would #define N_HEADER_IN_TEXT(x) as 1 for sunos,
+ and as 0 for most other hosts (Sony News, Vax Ultrix, etc).
+ (Do this in the appropriate bfd target file.)
+ (The default is a heuristic that will break if people try changing
+ the entry point, perhaps with the ld -e flag.)
+
+ * QMAGIC is always like a ZMAGIC for which N_HEADER_IN_TEXT is true,
+ and for which the starting address is TARGET_PAGE_SIZE (or should this be
+ SEGMENT_SIZE?) (TEXT_START_ADDR only applies to ZMAGIC, not to QMAGIC).
+ */
+
+/* This macro is only relevant for ZMAGIC files; QMAGIC always has the header
+ in the text. */
+#ifndef N_HEADER_IN_TEXT
+#define N_HEADER_IN_TEXT(x) (((x).a_entry & (TARGET_PAGE_SIZE-1)) >= EXEC_BYTES_SIZE)
+#endif
+
+/* Sun shared libraries, not linux. This macro is only relevant for ZMAGIC
+ files. */
+#ifndef N_SHARED_LIB
+#define N_SHARED_LIB(x) ((x).a_entry < TEXT_START_ADDR)
+#endif
+
+/* Returning 0 not TEXT_START_ADDR for OMAGIC and NMAGIC is based on
+ the assumption that we are dealing with a .o file, not an
+ executable. This is necessary for OMAGIC (but means we don't work
+ right on the output from ld -N); more questionable for NMAGIC. */
+
+#ifndef N_TXTADDR
+#define N_TXTADDR(x) \
+ (/* The address of a QMAGIC file is always one page in, */ \
+ /* with the header in the text. */ \
+ N_IS_QMAGIC (x) ? TARGET_PAGE_SIZE + EXEC_BYTES_SIZE : \
+ N_MAGIC(x) != ZMAGIC ? 0 : /* object file or NMAGIC */\
+ N_SHARED_LIB(x) ? 0 : \
+ N_HEADER_IN_TEXT(x) ? \
+ TEXT_START_ADDR + EXEC_BYTES_SIZE : /* no padding */\
+ TEXT_START_ADDR /* a page of padding */\
+ )
+#endif
+
+/* If N_HEADER_IN_TEXT is not true for ZMAGIC, there is some padding
+ to make the text segment start at a certain boundary. For most
+ systems, this boundary is TARGET_PAGE_SIZE. But for Linux, in the
+ time-honored tradition of crazy ZMAGIC hacks, it is 1024 which is
+ not what TARGET_PAGE_SIZE needs to be for QMAGIC. */
+
+#ifndef ZMAGIC_DISK_BLOCK_SIZE
+#define ZMAGIC_DISK_BLOCK_SIZE TARGET_PAGE_SIZE
+#endif
+
+#define N_DISK_BLOCK_SIZE(x) \
+ (N_MAGIC(x) == ZMAGIC ? ZMAGIC_DISK_BLOCK_SIZE : TARGET_PAGE_SIZE)
+
+/* Offset in an a.out of the start of the text section. */
+#ifndef N_TXTOFF
+#define N_TXTOFF(x) \
+ (/* For {O,N,Q}MAGIC, no padding. */ \
+ N_MAGIC(x) != ZMAGIC ? EXEC_BYTES_SIZE : \
+ N_SHARED_LIB(x) ? 0 : \
+ N_HEADER_IN_TEXT(x) ? \
+ EXEC_BYTES_SIZE : /* no padding */\
+ ZMAGIC_DISK_BLOCK_SIZE /* a page of padding */\
+ )
+#endif
+/* Size of the text section. It's always as stated, except that we
+ offset it to `undo' the adjustment to N_TXTADDR and N_TXTOFF
+ for ZMAGIC files that nominally include the exec header
+ as part of the first page of text. (BFD doesn't consider the
+ exec header to be part of the text segment.) */
+#ifndef N_TXTSIZE
+#define N_TXTSIZE(x) \
+ (/* For QMAGIC, we don't consider the header part of the text section. */\
+ N_IS_QMAGIC (x) ? (x).a_text - EXEC_BYTES_SIZE : \
+ (N_MAGIC(x) != ZMAGIC || N_SHARED_LIB(x)) ? (x).a_text : \
+ N_HEADER_IN_TEXT(x) ? \
+ (x).a_text - EXEC_BYTES_SIZE: /* no padding */\
+ (x).a_text /* a page of padding */\
+ )
+#endif
+/* The address of the data segment in virtual memory.
+ It is the text segment address, plus text segment size, rounded
+ up to a N_SEGSIZE boundary for pure or pageable files. */
+#ifndef N_DATADDR
+#define N_DATADDR(x) \
+ (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+N_TXTSIZE(x)) \
+ : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1))))
+#endif
+/* The address of the BSS segment -- immediately after the data segment. */
+
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+
+/* Offsets of the various portions of the file after the text segment. */
+
+/* For {Q,Z}MAGIC, there is padding to make the data segment start on
+ a page boundary. Most of the time the a_text field (and thus
+ N_TXTSIZE) already contains this padding. It is possible that for
+ BSDI and/or 386BSD it sometimes doesn't contain the padding, and
+ perhaps we should be adding it here. But this seems kind of
+ questionable and probably should be BSDI/386BSD-specific if we do
+ do it.
+
+ For NMAGIC (at least for hp300 BSD, probably others), there is
+ padding in memory only, not on disk, so we must *not* ever pad here
+ for NMAGIC. */
+
+#ifndef N_DATOFF
+#define N_DATOFF(x) \
+ (N_TXTOFF(x) + N_TXTSIZE(x))
+#endif
+
+#ifndef N_TRELOFF
+#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data )
+#endif
+#ifndef N_DRELOFF
+#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
+#endif
+#ifndef N_SYMOFF
+#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize )
+#endif
+#ifndef N_STROFF
+#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+#endif
+
+/* Symbols */
+#ifndef external_nlist
+struct external_nlist {
+ bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */
+ bfd_byte e_type[1]; /* type of symbol */
+ bfd_byte e_other[1]; /* misc info (usually empty) */
+ bfd_byte e_desc[2]; /* description field */
+ bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */
+};
+#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD)
+#endif
+
+struct internal_nlist {
+ unsigned long n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ bfd_vma n_value; /* value of symbol */
+};
+
+/* The n_type field is the symbol type, containing: */
+
+#define N_UNDF 0 /* Undefined symbol */
+#define N_ABS 2 /* Absolute symbol -- defined at particular addr */
+#define N_TEXT 4 /* Text sym -- defined at offset in text seg */
+#define N_DATA 6 /* Data sym -- defined at offset in data seg */
+#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */
+#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */
+#define N_FN 0x1f /* File name of .o file */
+#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */
+/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT,
+ N_DATA, or N_BSS. When the low-order bit of other types is set,
+ (e.g. N_WARNING versus N_FN), they are two different types. */
+#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */
+#define N_TYPE 0x1e
+#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */
+
+#define N_INDR 0x0a
+
+/* The following symbols refer to set elements.
+ All the N_SET[ATDB] symbols with the same name form one set.
+ Space is allocated for the set in the text section, and each set
+ elements value is stored into one word of the space.
+ The first word of the space is the length of the set (number of elements).
+
+ The address of the set is made into an N_SETV symbol
+ whose name is the same as the name of the set.
+ This symbol acts like a N_DATA global symbol
+ in that it can satisfy undefined external references. */
+
+/* These appear as input to LD, in a .o file. */
+#define N_SETA 0x14 /* Absolute set element symbol */
+#define N_SETT 0x16 /* Text set element symbol */
+#define N_SETD 0x18 /* Data set element symbol */
+#define N_SETB 0x1A /* Bss set element symbol */
+
+/* This is output from LD. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+/* Warning symbol. The text gives a warning message, the next symbol
+ in the table will be undefined. When the symbol is referenced, the
+ message is printed. */
+
+#define N_WARNING 0x1e
+
+/* Weak symbols. These are a GNU extension to the a.out format. The
+ semantics are those of ELF weak symbols. Weak symbols are always
+ externally visible. The N_WEAK? values are squeezed into the
+ available slots. The value of a N_WEAKU symbol is 0. The values
+ of the other types are the definitions. */
+#define N_WEAKU 0x0d /* Weak undefined symbol. */
+#define N_WEAKA 0x0e /* Weak absolute symbol. */
+#define N_WEAKT 0x0f /* Weak text symbol. */
+#define N_WEAKD 0x10 /* Weak data symbol. */
+#define N_WEAKB 0x11 /* Weak bss symbol. */
+
+/* Relocations
+
+ There are two types of relocation flavours for a.out systems,
+ standard and extended. The standard form is used on systems where the
+ instruction has room for all the bits of an offset to the operand, whilst
+ the extended form is used when an address operand has to be split over n
+ instructions. Eg, on the 68k, each move instruction can reference
+ the target with a displacement of 16 or 32 bits. On the sparc, move
+ instructions use an offset of 14 bits, so the offset is stored in
+ the reloc field, and the data in the section is ignored.
+*/
+
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+struct reloc_std_external {
+ bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
+ bfd_byte r_index[3]; /* symbol table index of symbol */
+ bfd_byte r_type[1]; /* relocation type */
+};
+
+#define RELOC_STD_BITS_PCREL_BIG ((unsigned int) 0x80)
+#define RELOC_STD_BITS_PCREL_LITTLE ((unsigned int) 0x01)
+
+#define RELOC_STD_BITS_LENGTH_BIG ((unsigned int) 0x60)
+#define RELOC_STD_BITS_LENGTH_SH_BIG 5
+#define RELOC_STD_BITS_LENGTH_LITTLE ((unsigned int) 0x06)
+#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1
+
+#define RELOC_STD_BITS_EXTERN_BIG ((unsigned int) 0x10)
+#define RELOC_STD_BITS_EXTERN_LITTLE ((unsigned int) 0x08)
+
+#define RELOC_STD_BITS_BASEREL_BIG ((unsigned int) 0x08)
+#define RELOC_STD_BITS_BASEREL_LITTLE ((unsigned int) 0x10)
+
+#define RELOC_STD_BITS_JMPTABLE_BIG ((unsigned int) 0x04)
+#define RELOC_STD_BITS_JMPTABLE_LITTLE ((unsigned int) 0x20)
+
+#define RELOC_STD_BITS_RELATIVE_BIG ((unsigned int) 0x02)
+#define RELOC_STD_BITS_RELATIVE_LITTLE ((unsigned int) 0x40)
+
+#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */
+
+struct reloc_std_internal
+{
+ bfd_vma r_address; /* Address (within segment) to be relocated. */
+ /* The meaning of r_symbolnum depends on r_extern. */
+ unsigned int r_symbolnum:24;
+ /* Nonzero means value is a pc-relative offset
+ and it should be relocated for changes in its own address
+ as well as for changes in the symbol or section specified. */
+ unsigned int r_pcrel:1;
+ /* Length (as exponent of 2) of the field to be relocated.
+ Thus, a value of 2 indicates 1<<2 bytes. */
+ unsigned int r_length:2;
+ /* 1 => relocate with value of symbol.
+ r_symbolnum is the index of the symbol
+ in files the symbol table.
+ 0 => relocate with the address of a segment.
+ r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
+ (the N_EXT bit may be set also, but signifies nothing). */
+ unsigned int r_extern:1;
+ /* The next three bits are for SunOS shared libraries, and seem to
+ be undocumented. */
+ unsigned int r_baserel:1; /* Linkage table relative */
+ unsigned int r_jmptable:1; /* pc-relative to jump table */
+ unsigned int r_relative:1; /* "relative relocation" */
+ /* unused */
+ unsigned int r_pad:1; /* Padding -- set to zero */
+};
+
+
+/* EXTENDED RELOCS */
+
+struct reloc_ext_external {
+ bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
+ bfd_byte r_index[3]; /* symbol table index of symbol */
+ bfd_byte r_type[1]; /* relocation type */
+ bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */
+};
+
+#define RELOC_EXT_BITS_EXTERN_BIG ((unsigned int) 0x80)
+#define RELOC_EXT_BITS_EXTERN_LITTLE ((unsigned int) 0x01)
+
+#define RELOC_EXT_BITS_TYPE_BIG ((unsigned int) 0x1F)
+#define RELOC_EXT_BITS_TYPE_SH_BIG 0
+#define RELOC_EXT_BITS_TYPE_LITTLE ((unsigned int) 0xF8)
+#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
+
+/* Bytes per relocation entry */
+#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD)
+
+enum reloc_type
+{
+ /* simple relocations */
+ RELOC_8, /* data[0:7] = addend + sv */
+ RELOC_16, /* data[0:15] = addend + sv */
+ RELOC_32, /* data[0:31] = addend + sv */
+ /* pc-rel displacement */
+ RELOC_DISP8, /* data[0:7] = addend - pc + sv */
+ RELOC_DISP16, /* data[0:15] = addend - pc + sv */
+ RELOC_DISP32, /* data[0:31] = addend - pc + sv */
+ /* Special */
+ RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */
+ RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */
+ RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */
+ RELOC_22, /* data[0:21] = (addend + sv) */
+ RELOC_13, /* data[0:12] = (addend + sv) */
+ RELOC_LO10, /* data[0:9] = (addend + sv) */
+ RELOC_SFA_BASE,
+ RELOC_SFA_OFF13,
+ /* P.I.C. (base-relative) */
+ RELOC_BASE10, /* Not sure - maybe we can do this the */
+ RELOC_BASE13, /* right way now */
+ RELOC_BASE22,
+ /* for some sort of pc-rel P.I.C. (?) */
+ RELOC_PC10,
+ RELOC_PC22,
+ /* P.I.C. jump table */
+ RELOC_JMP_TBL,
+ /* reputedly for shared libraries somehow */
+ RELOC_SEGOFF16,
+ RELOC_GLOB_DAT,
+ RELOC_JMP_SLOT,
+ RELOC_RELATIVE,
+
+ RELOC_11,
+ RELOC_WDISP2_14,
+ RELOC_WDISP19,
+ RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */
+ RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */
+
+ /* 29K relocation types */
+ RELOC_JUMPTARG,
+ RELOC_CONST,
+ RELOC_CONSTH,
+
+ /* All the new ones I can think of, for sparc v9 */
+
+ RELOC_64, /* data[0:63] = addend + sv */
+ RELOC_DISP64, /* data[0:63] = addend - pc + sv */
+ RELOC_WDISP21, /* data[0:20] = (addend + sv - pc)>>2 */
+ RELOC_DISP21, /* data[0:20] = addend - pc + sv */
+ RELOC_DISP14, /* data[0:13] = addend - pc + sv */
+ /* Q .
+ What are the other ones,
+ Since this is a clean slate, can we throw away the ones we dont
+ understand ? Should we sort the values ? What about using a
+ microcode format like the 68k ?
+ */
+ NO_RELOC
+ };
+
+
+struct reloc_internal {
+ bfd_vma r_address; /* offset of of data to relocate */
+ long r_index; /* symbol table index of symbol */
+ enum reloc_type r_type; /* relocation type */
+ bfd_vma r_addend; /* datum addend */
+};
+
+/* Q.
+ Should the length of the string table be 4 bytes or 8 bytes ?
+
+ Q.
+ What about archive indexes ?
+
+ */
+
+#endif /* __A_OUT_64_H__ */
diff --git a/pstack/aout/stab.def b/pstack/aout/stab.def
new file mode 100644
index 00000000000..3c6b456d3a9
--- /dev/null
+++ b/pstack/aout/stab.def
@@ -0,0 +1,264 @@
+/* Table of DBX symbol codes for the GNU system.
+ Copyright (C) 1988, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* New stab from Solaris 2. This uses an n_type of 0, which in a.out files
+ overlaps the N_UNDF used for ordinary symbols. In ELF files, the
+ debug information is in a different file section, so there is no conflict.
+ This symbol's n_value gives the size of the string section associated
+ with this file. The symbol's n_strx (relative to the just-updated
+ string section start address) gives the name of the source file,
+ e.g. "foo.c", without any path information. The symbol's n_desc gives
+ the count of upcoming symbols associated with this file (not including
+ this one). */
+/* __define_stab (N_UNDF, 0x00, "UNDF") */
+
+/* Global variable. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_GSYM, 0x20, "GSYM")
+
+/* Function name for BSD Fortran. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_FNAME, 0x22, "FNAME")
+
+/* Function name or text-segment variable for C. Value is its address.
+ Desc is supposedly starting line number, but GCC doesn't set it
+ and DBX seems not to miss it. */
+__define_stab (N_FUN, 0x24, "FUN")
+
+/* Data-segment variable with internal linkage. Value is its address.
+ "Static Sym". */
+__define_stab (N_STSYM, 0x26, "STSYM")
+
+/* BSS-segment variable with internal linkage. Value is its address. */
+__define_stab (N_LCSYM, 0x28, "LCSYM")
+
+/* Name of main routine. Only the name is significant. */
+__define_stab (N_MAIN, 0x2a, "MAIN")
+
+/* Solaris2: Read-only data symbols. */
+__define_stab (N_ROSYM, 0x2c, "ROSYM")
+
+/* Global symbol in Pascal.
+ Supposedly the value is its line number; I'm skeptical. */
+__define_stab (N_PC, 0x30, "PC")
+
+/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */
+__define_stab (N_NSYMS, 0x32, "NSYMS")
+
+/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */
+__define_stab (N_NOMAP, 0x34, "NOMAP")
+
+/* New stab from Solaris 2. Like N_SO, but for the object file. Two in
+ a row provide the build directory and the relative path of the .o from it.
+ Solaris2 uses this to avoid putting the stabs info into the linked
+ executable; this stab goes into the ".stab.index" section, and the debugger
+ reads the real stabs directly from the .o files instead. */
+__define_stab (N_OBJ, 0x38, "OBJ")
+
+/* New stab from Solaris 2. Options for the debugger, related to the
+ source language for this module. E.g. whether to use ANSI
+ integral promotions or traditional integral promotions. */
+__define_stab (N_OPT, 0x3c, "OPT")
+
+/* Register variable. Value is number of register. */
+__define_stab (N_RSYM, 0x40, "RSYM")
+
+/* Modula-2 compilation unit. Can someone say what info it contains? */
+__define_stab (N_M2C, 0x42, "M2C")
+
+/* Line number in text segment. Desc is the line number;
+ value is corresponding address. On Solaris2, the line number is
+ relative to the start of the current function. */
+__define_stab (N_SLINE, 0x44, "SLINE")
+
+/* Similar, for data segment. */
+__define_stab (N_DSLINE, 0x46, "DSLINE")
+
+/* Similar, for bss segment. */
+__define_stab (N_BSLINE, 0x48, "BSLINE")
+
+/* Sun's source-code browser stabs. ?? Don't know what the fields are.
+ Supposedly the field is "path to associated .cb file". THIS VALUE
+ OVERLAPS WITH N_BSLINE! */
+__define_stab_duplicate (N_BROWS, 0x48, "BROWS")
+
+/* GNU Modula-2 definition module dependency. Value is the modification time
+ of the definition file. Other is non-zero if it is imported with the
+ GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
+ are enough empty fields? */
+__define_stab(N_DEFD, 0x4a, "DEFD")
+
+/* New in Solaris2. Function start/body/end line numbers. */
+__define_stab(N_FLINE, 0x4C, "FLINE")
+
+/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2
+ and one is for C++. Still,... */
+/* GNU C++ exception variable. Name is variable name. */
+__define_stab (N_EHDECL, 0x50, "EHDECL")
+/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */
+__define_stab_duplicate (N_MOD2, 0x50, "MOD2")
+
+/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if
+ this entry is immediately followed by a CAUGHT stab saying what exception
+ was caught. Multiple CAUGHT stabs means that multiple exceptions
+ can be caught here. If Desc is 0, it means all exceptions are caught
+ here. */
+__define_stab (N_CATCH, 0x54, "CATCH")
+
+/* Structure or union element. Value is offset in the structure. */
+__define_stab (N_SSYM, 0x60, "SSYM")
+
+/* Solaris2: Last stab emitted for module. */
+__define_stab (N_ENDM, 0x62, "ENDM")
+
+/* Name of main source file.
+ Value is starting text address of the compilation.
+ If multiple N_SO's appear, the first to contain a trailing / is the
+ compilation directory. The first to not contain a trailing / is the
+ source file name, relative to the compilation directory. Others (perhaps
+ resulting from cfront) are ignored.
+ On Solaris2, value is undefined, but desc is a source-language code. */
+
+__define_stab (N_SO, 0x64, "SO")
+
+/* Automatic variable in the stack. Value is offset from frame pointer.
+ Also used for type descriptions. */
+__define_stab (N_LSYM, 0x80, "LSYM")
+
+/* Beginning of an include file. Only Sun uses this.
+ In an object file, only the name is significant.
+ The Sun linker puts data into some of the other fields. */
+__define_stab (N_BINCL, 0x82, "BINCL")
+
+/* Name of sub-source file (#include file).
+ Value is starting text address of the compilation. */
+__define_stab (N_SOL, 0x84, "SOL")
+
+/* Parameter variable. Value is offset from argument pointer.
+ (On most machines the argument pointer is the same as the frame pointer. */
+__define_stab (N_PSYM, 0xa0, "PSYM")
+
+/* End of an include file. No name.
+ This and N_BINCL act as brackets around the file's output.
+ In an object file, there is no significant data in this entry.
+ The Sun linker puts data into some of the fields. */
+__define_stab (N_EINCL, 0xa2, "EINCL")
+
+/* Alternate entry point. Value is its address. */
+__define_stab (N_ENTRY, 0xa4, "ENTRY")
+
+/* Beginning of lexical block.
+ The desc is the nesting level in lexical blocks.
+ The value is the address of the start of the text for the block.
+ The variables declared inside the block *precede* the N_LBRAC symbol.
+ On Solaris2, the value is relative to the start of the current function. */
+__define_stab (N_LBRAC, 0xc0, "LBRAC")
+
+/* Place holder for deleted include file. Replaces a N_BINCL and everything
+ up to the corresponding N_EINCL. The Sun linker generates these when
+ it finds multiple identical copies of the symbols from an include file.
+ This appears only in output from the Sun linker. */
+__define_stab (N_EXCL, 0xc2, "EXCL")
+
+/* Modula-2 scope information. Can someone say what info it contains? */
+__define_stab (N_SCOPE, 0xc4, "SCOPE")
+
+/* End of a lexical block. Desc matches the N_LBRAC's desc.
+ The value is the address of the end of the text for the block.
+ On Solaris2, the value is relative to the start of the current function. */
+__define_stab (N_RBRAC, 0xe0, "RBRAC")
+
+/* Begin named common block. Only the name is significant. */
+__define_stab (N_BCOMM, 0xe2, "BCOMM")
+
+/* End named common block. Only the name is significant
+ (and it should match the N_BCOMM). */
+__define_stab (N_ECOMM, 0xe4, "ECOMM")
+
+/* Member of a common block; value is offset within the common block.
+ This should occur within a BCOMM/ECOMM pair. */
+__define_stab (N_ECOML, 0xe8, "ECOML")
+
+/* Solaris2: Pascal "with" statement: type,,0,0,offset */
+__define_stab (N_WITH, 0xea, "WITH")
+
+/* These STAB's are used on Gould systems for Non-Base register symbols
+ or something like that. FIXME. I have assigned the values at random
+ since I don't have a Gould here. Fixups from Gould folk welcome... */
+__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
+__define_stab (N_NBDATA, 0xF2, "NBDATA")
+__define_stab (N_NBBSS, 0xF4, "NBBSS")
+__define_stab (N_NBSTS, 0xF6, "NBSTS")
+__define_stab (N_NBLCS, 0xF8, "NBLCS")
+
+/* Second symbol entry containing a length-value for the preceding entry.
+ The value is the length. */
+__define_stab (N_LENG, 0xfe, "LENG")
+
+/* The above information, in matrix format.
+
+ STAB MATRIX
+ _________________________________________________
+ | 00 - 1F are not dbx stab symbols |
+ | In most cases, the low bit is the EXTernal bit|
+
+ | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
+ | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
+
+ | 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA |
+ | 09 |EXT | 0B | 0D WEAKU | 0F WEAKT |
+
+ | 10 WEAKD | 12 COMM | 14 SETA | 16 SETT |
+ | 11 WEAKB | 13 | 15 | 17 |
+
+ | 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
+ | 19 | 1B | 1D | 1F FN |
+
+ |_______________________________________________|
+ | Debug entries with bit 01 set are unused. |
+ | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM |
+ | 28 LCSYM | 2A MAIN | 2C ROSYM | 2E |
+ | 30 PC | 32 NSYMS | 34 NOMAP | 36 |
+ | 38 OBJ | 3A | 3C OPT | 3E |
+ | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE |
+ | 48 BSLINE*| 4A DEFD | 4C FLINE | 4E |
+ | 50 EHDECL*| 52 | 54 CATCH | 56 |
+ | 58 | 5A | 5C | 5E |
+ | 60 SSYM | 62 ENDM | 64 SO | 66 |
+ | 68 | 6A | 6C | 6E |
+ | 70 | 72 | 74 | 76 |
+ | 78 | 7A | 7C | 7E |
+ | 80 LSYM | 82 BINCL | 84 SOL | 86 |
+ | 88 | 8A | 8C | 8E |
+ | 90 | 92 | 94 | 96 |
+ | 98 | 9A | 9C | 9E |
+ | A0 PSYM | A2 EINCL | A4 ENTRY | A6 |
+ | A8 | AA | AC | AE |
+ | B0 | B2 | B4 | B6 |
+ | B8 | BA | BC | BE |
+ | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 |
+ | C8 | CA | CC | CE |
+ | D0 | D2 | D4 | D6 |
+ | D8 | DA | DC | DE |
+ | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 |
+ | E8 ECOML | EA WITH | EC | EE |
+ | F0 | F2 | F4 | F6 |
+ | F8 | FA | FC | FE LENG |
+ +-----------------------------------------------+
+ * 50 EHDECL is also MOD2.
+ * 48 BSLINE is also BROWS.
+ */
diff --git a/pstack/aout/stab_gnu.h b/pstack/aout/stab_gnu.h
new file mode 100644
index 00000000000..7d18e14a263
--- /dev/null
+++ b/pstack/aout/stab_gnu.h
@@ -0,0 +1,37 @@
+#ifndef __GNU_STAB__
+
+/* Indicate the GNU stab.h is in use. */
+
+#define __GNU_STAB__
+
+#define __define_stab(NAME, CODE, STRING) NAME=CODE,
+#define __define_stab_duplicate(NAME, CODE, STRING) NAME=CODE,
+
+enum __stab_debug_code
+{
+#include "aout/stab.def"
+LAST_UNUSED_STAB_CODE
+};
+
+#undef __define_stab
+
+/* Definitions of "desc" field for N_SO stabs in Solaris2. */
+
+#define N_SO_AS 1
+#define N_SO_C 2
+#define N_SO_ANSI_C 3
+#define N_SO_CC 4 /* C++ */
+#define N_SO_FORTRAN 5
+#define N_SO_PASCAL 6
+
+/* Solaris2: Floating point type values in basic types. */
+
+#define NF_NONE 0
+#define NF_SINGLE 1 /* IEEE 32-bit */
+#define NF_DOUBLE 2 /* IEEE 64-bit */
+#define NF_COMPLEX 3 /* Fortran complex */
+#define NF_COMPLEX16 4 /* Fortran double complex */
+#define NF_COMPLEX32 5 /* Fortran complex*16 */
+#define NF_LDOUBLE 6 /* Long double (whatever that is) */
+
+#endif /* __GNU_STAB_ */
diff --git a/pstack/bucomm.c b/pstack/bucomm.c
new file mode 100644
index 00000000000..d3231e71747
--- /dev/null
+++ b/pstack/bucomm.c
@@ -0,0 +1,238 @@
+/* bucomm.c -- Bin Utils COMmon code.
+ Copyright (C) 1991, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* We might put this in a library someday so it could be dynamically
+ loaded, but for now it's not necessary. */
+
+#include <bfd.h>
+#include <libiberty.h>
+#include "bucomm.h"
+
+#include <sys/stat.h>
+#include <time.h> /* ctime, maybe time_t */
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/* Error reporting */
+
+char *program_name;
+
+void
+bfd_nonfatal (string)
+ CONST char *string;
+{
+ CONST char *errmsg = bfd_errmsg (bfd_get_error ());
+
+ if (string)
+ fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
+ else
+ fprintf (stderr, "%s: %s\n", program_name, errmsg);
+}
+
+void
+bfd_fatal (string)
+ CONST char *string;
+{
+ bfd_nonfatal (string);
+ xexit (1);
+}
+
+#ifdef ANSI_PROTOTYPES
+void
+fatal (const char *format, ...)
+{
+ va_list args;
+
+ fprintf (stderr, "%s: ", program_name);
+ va_start (args, format);
+ vfprintf (stderr, format, args);
+ va_end (args);
+ putc ('\n', stderr);
+ xexit (1);
+}
+#else
+void
+fatal (va_alist)
+ va_dcl
+{
+ char *Format;
+ va_list args;
+
+ fprintf (stderr, "%s: ", program_name);
+ va_start (args);
+ Format = va_arg (args, char *);
+ vfprintf (stderr, Format, args);
+ va_end (args);
+ putc ('\n', stderr);
+ xexit (1);
+}
+#endif
+
+/* Set the default BFD target based on the configured target. Doing
+ this permits the binutils to be configured for a particular target,
+ and linked against a shared BFD library which was configured for a
+ different target. */
+
+#define TARGET "elf32-i386" /* FIXME: hard-coded! */
+void
+set_default_bfd_target ()
+{
+ /* The macro TARGET is defined by Makefile. */
+ const char *target = TARGET;
+
+ if (! bfd_set_default_target (target))
+ {
+ char *errmsg;
+
+ errmsg = (char *) xmalloc (100 + strlen (target));
+ sprintf (errmsg, "can't set BFD default target to `%s'", target);
+ bfd_fatal (errmsg);
+ }
+}
+
+/* After a false return from bfd_check_format_matches with
+ bfd_get_error () == bfd_error_file_ambiguously_recognized, print
+ the possible matching targets. */
+
+void
+list_matching_formats (p)
+ char **p;
+{
+ fprintf(stderr, "%s: Matching formats:", program_name);
+ while (*p)
+ fprintf(stderr, " %s", *p++);
+ fprintf(stderr, "\n");
+}
+
+/* List the supported targets. */
+
+void
+list_supported_targets (name, f)
+ const char *name;
+ FILE *f;
+{
+ extern bfd_target *bfd_target_vector[];
+ int t;
+
+ if (name == NULL)
+ fprintf (f, "Supported targets:");
+ else
+ fprintf (f, "%s: supported targets:", name);
+ for (t = 0; bfd_target_vector[t] != NULL; t++)
+ fprintf (f, " %s", bfd_target_vector[t]->name);
+ fprintf (f, "\n");
+}
+
+/* Display the archive header for an element as if it were an ls -l listing:
+
+ Mode User\tGroup\tSize\tDate Name */
+
+void
+print_arelt_descr (file, abfd, verbose)
+ FILE *file;
+ bfd *abfd;
+ boolean verbose;
+{
+ struct stat buf;
+
+ if (verbose)
+ {
+ if (bfd_stat_arch_elt (abfd, &buf) == 0)
+ {
+ char modebuf[11];
+ char timebuf[40];
+ time_t when = buf.st_mtime;
+ CONST char *ctime_result = (CONST char *) ctime (&when);
+
+ /* POSIX format: skip weekday and seconds from ctime output. */
+ sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
+
+ mode_string (buf.st_mode, modebuf);
+ modebuf[10] = '\0';
+ /* POSIX 1003.2/D11 says to skip first character (entry type). */
+ fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
+ (long) buf.st_uid, (long) buf.st_gid,
+ (long) buf.st_size, timebuf);
+ }
+ }
+
+ fprintf (file, "%s\n", bfd_get_filename (abfd));
+}
+
+/* Return the name of a temporary file in the same directory as FILENAME. */
+
+char *
+make_tempname (filename)
+ char *filename;
+{
+ static char template[] = "stXXXXXX";
+ char *tmpname;
+ char *slash = strrchr (filename, '/');
+
+#if defined (__DJGPP__) || defined (__GO32__) || defined (_WIN32)
+ if (slash == NULL)
+ slash = strrchr (filename, '\\');
+#endif
+
+ if (slash != (char *) NULL)
+ {
+ char c;
+
+ c = *slash;
+ *slash = 0;
+ tmpname = xmalloc (strlen (filename) + sizeof (template) + 1);
+ strcpy (tmpname, filename);
+ strcat (tmpname, "/");
+ strcat (tmpname, template);
+ mkstemp (tmpname);
+ *slash = c;
+ }
+ else
+ {
+ tmpname = xmalloc (sizeof (template));
+ strcpy (tmpname, template);
+ mkstemp (tmpname);
+ }
+ return tmpname;
+}
+
+/* Parse a string into a VMA, with a fatal error if it can't be
+ parsed. */
+
+bfd_vma
+parse_vma (s, arg)
+ const char *s;
+ const char *arg;
+{
+ bfd_vma ret;
+ const char *end;
+
+ ret = bfd_scan_vma (s, &end, 0);
+ if (*end != '\0')
+ {
+ fprintf (stderr, "%s: %s: bad number: %s\n", program_name, arg, s);
+ exit (1);
+ }
+ return ret;
+}
diff --git a/pstack/bucomm.h b/pstack/bucomm.h
new file mode 100644
index 00000000000..7712a70f5a2
--- /dev/null
+++ b/pstack/bucomm.h
@@ -0,0 +1,85 @@
+/* bucomm.h -- binutils common include file.
+ Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+
+This file is part of GNU Binutils.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _BUCOMM_H
+#define _BUCOMM_H
+
+#include "ansidecl.h"
+#include <stdio.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <string.h>
+
+#include <stdlib.h>
+
+#include <fcntl.h>
+
+#ifdef __GNUC__
+# undef alloca
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+# if !defined (__STDC__) && !defined (__hpux)
+char *alloca ();
+# else
+void *alloca ();
+# endif /* __STDC__, __hpux */
+# endif /* alloca */
+# endif /* HAVE_ALLOCA_H */
+#endif
+
+/* bucomm.c */
+void bfd_nonfatal PARAMS ((CONST char *));
+
+void bfd_fatal PARAMS ((CONST char *));
+
+void fatal PARAMS ((CONST char *, ...));
+
+void set_default_bfd_target PARAMS ((void));
+
+void list_matching_formats PARAMS ((char **p));
+
+void list_supported_targets PARAMS ((const char *, FILE *));
+
+void print_arelt_descr PARAMS ((FILE *file, bfd *abfd, boolean verbose));
+
+char *make_tempname PARAMS ((char *));
+
+bfd_vma parse_vma PARAMS ((const char *, const char *));
+
+extern char *program_name;
+
+/* filemode.c */
+void mode_string PARAMS ((unsigned long mode, char *buf));
+
+/* version.c */
+extern void print_version PARAMS ((const char *));
+
+/* libiberty */
+PTR xmalloc PARAMS ((size_t));
+
+PTR xrealloc PARAMS ((PTR, size_t));
+
+#endif /* _BUCOMM_H */
diff --git a/pstack/budbg.h b/pstack/budbg.h
new file mode 100644
index 00000000000..d8ee8895e76
--- /dev/null
+++ b/pstack/budbg.h
@@ -0,0 +1,58 @@
+/* budbg.c -- Interfaces to the generic debugging information routines.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef BUDBG_H
+#define BUDBG_H
+
+#include <stdio.h>
+
+/* Routine used to read generic debugging information. */
+
+extern PTR read_debugging_info PARAMS ((bfd *, asymbol **, long));
+
+/* Routine used to print generic debugging information. */
+
+extern boolean print_debugging_info PARAMS ((FILE *, PTR));
+
+/* Routines used to read and write stabs information. */
+
+extern PTR start_stab PARAMS ((PTR, bfd *, boolean, asymbol **, long));
+
+extern boolean finish_stab PARAMS ((PTR, PTR));
+
+extern boolean parse_stab PARAMS ((PTR, PTR, int, int, bfd_vma, const char *));
+
+extern boolean write_stabs_in_sections_debugging_info
+ PARAMS ((bfd *, PTR, bfd_byte **, bfd_size_type *, bfd_byte **,
+ bfd_size_type *));
+
+/* Routines used to read and write IEEE debugging information. */
+
+extern boolean parse_ieee
+ PARAMS ((PTR, bfd *, const bfd_byte *, bfd_size_type));
+
+extern boolean write_ieee_debugging_info PARAMS ((bfd *, PTR));
+
+/* Routine used to read COFF debugging information. */
+
+extern boolean parse_coff PARAMS ((bfd *, asymbol **, long, PTR));
+
+#endif
diff --git a/pstack/debug.c b/pstack/debug.c
new file mode 100644
index 00000000000..73412ae3f03
--- /dev/null
+++ b/pstack/debug.c
@@ -0,0 +1,3509 @@
+/* debug.c -- Handle generic debugging information.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file implements a generic debugging format. We may eventually
+ have readers which convert different formats into this generic
+ format, and writers which write it out. The initial impetus for
+ this was writing a convertor from stabs to HP IEEE-695 debugging
+ format. */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <bfd.h>
+#include "bucomm.h"
+#include <libiberty.h>
+#include "debug.h"
+
+/* Global information we keep for debugging. A pointer to this
+ structure is the debugging handle passed to all the routines. */
+
+struct debug_handle
+{
+ /* A linked list of compilation units. */
+ struct debug_unit *units;
+ /* The current compilation unit. */
+ struct debug_unit *current_unit;
+ /* The current source file. */
+ struct debug_file *current_file;
+ /* The current function. */
+ struct debug_function *current_function;
+ /* The current block. */
+ struct debug_block *current_block;
+ /* The current line number information for the current unit. */
+ struct debug_lineno *current_lineno;
+ /* Mark. This is used by debug_write. */
+ unsigned int mark;
+ /* A struct/class ID used by debug_write. */
+ unsigned int class_id;
+ /* The base for class_id for this call to debug_write. */
+ unsigned int base_id;
+ /* The current line number in debug_write. */
+ struct debug_lineno *current_write_lineno;
+ unsigned int current_write_lineno_index;
+ /* A list of classes which have assigned ID's during debug_write.
+ This is linked through the next_id field of debug_class_type. */
+ struct debug_class_id *id_list;
+ /* A list used to avoid recursion during debug_type_samep. */
+ struct debug_type_compare_list *compare_list;
+};
+
+/* Information we keep for a single compilation unit. */
+
+struct debug_unit
+{
+ /* The next compilation unit. */
+ struct debug_unit *next;
+ /* A list of files included in this compilation unit. The first
+ file is always the main one, and that is where the main file name
+ is stored. */
+ struct debug_file *files;
+ /* Line number information for this compilation unit. This is not
+ stored by function, because assembler code may have line number
+ information without function information. */
+ struct debug_lineno *linenos;
+};
+
+/* Information kept for a single source file. */
+
+struct debug_file
+{
+ /* The next source file in this compilation unit. */
+ struct debug_file *next;
+ /* The name of the source file. */
+ const char *filename;
+ /* Global functions, variables, types, etc. */
+ struct debug_namespace *globals;
+};
+
+/* A type. */
+
+struct debug_type
+{
+ /* Kind of type. */
+ enum debug_type_kind kind;
+ /* Size of type (0 if not known). */
+ unsigned int size;
+ /* Type which is a pointer to this type. */
+ debug_type pointer;
+ /* Tagged union with additional information about the type. */
+ union
+ {
+ /* DEBUG_KIND_INDIRECT. */
+ struct debug_indirect_type *kindirect;
+ /* DEBUG_KIND_INT. */
+ /* Whether the integer is unsigned. */
+ boolean kint;
+ /* DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_CLASS,
+ DEBUG_KIND_UNION_CLASS. */
+ struct debug_class_type *kclass;
+ /* DEBUG_KIND_ENUM. */
+ struct debug_enum_type *kenum;
+ /* DEBUG_KIND_POINTER. */
+ struct debug_type *kpointer;
+ /* DEBUG_KIND_FUNCTION. */
+ struct debug_function_type *kfunction;
+ /* DEBUG_KIND_REFERENCE. */
+ struct debug_type *kreference;
+ /* DEBUG_KIND_RANGE. */
+ struct debug_range_type *krange;
+ /* DEBUG_KIND_ARRAY. */
+ struct debug_array_type *karray;
+ /* DEBUG_KIND_SET. */
+ struct debug_set_type *kset;
+ /* DEBUG_KIND_OFFSET. */
+ struct debug_offset_type *koffset;
+ /* DEBUG_KIND_METHOD. */
+ struct debug_method_type *kmethod;
+ /* DEBUG_KIND_CONST. */
+ struct debug_type *kconst;
+ /* DEBUG_KIND_VOLATILE. */
+ struct debug_type *kvolatile;
+ /* DEBUG_KIND_NAMED, DEBUG_KIND_TAGGED. */
+ struct debug_named_type *knamed;
+ } u;
+};
+
+/* Information kept for an indirect type. */
+
+struct debug_indirect_type
+{
+ /* Slot where the final type will appear. */
+ debug_type *slot;
+ /* Tag. */
+ const char *tag;
+};
+
+/* Information kept for a struct, union, or class. */
+
+struct debug_class_type
+{
+ /* NULL terminated array of fields. */
+ debug_field *fields;
+ /* A mark field which indicates whether the struct has already been
+ printed. */
+ unsigned int mark;
+ /* This is used to uniquely identify unnamed structs when printing. */
+ unsigned int id;
+ /* The remaining fields are only used for DEBUG_KIND_CLASS and
+ DEBUG_KIND_UNION_CLASS. */
+ /* NULL terminated array of base classes. */
+ debug_baseclass *baseclasses;
+ /* NULL terminated array of methods. */
+ debug_method *methods;
+ /* The type of the class providing the virtual function table for
+ this class. This may point to the type itself. */
+ debug_type vptrbase;
+};
+
+/* Information kept for an enum. */
+
+struct debug_enum_type
+{
+ /* NULL terminated array of names. */
+ const char **names;
+ /* Array of corresponding values. */
+ bfd_signed_vma *values;
+};
+
+/* Information kept for a function. FIXME: We should be able to
+ record the parameter types. */
+
+struct debug_function_type
+{
+ /* Return type. */
+ debug_type return_type;
+ /* NULL terminated array of argument types. */
+ debug_type *arg_types;
+ /* Whether the function takes a variable number of arguments. */
+ boolean varargs;
+};
+
+/* Information kept for a range. */
+
+struct debug_range_type
+{
+ /* Range base type. */
+ debug_type type;
+ /* Lower bound. */
+ bfd_signed_vma lower;
+ /* Upper bound. */
+ bfd_signed_vma upper;
+};
+
+/* Information kept for an array. */
+
+struct debug_array_type
+{
+ /* Element type. */
+ debug_type element_type;
+ /* Range type. */
+ debug_type range_type;
+ /* Lower bound. */
+ bfd_signed_vma lower;
+ /* Upper bound. */
+ bfd_signed_vma upper;
+ /* Whether this array is really a string. */
+ boolean stringp;
+};
+
+/* Information kept for a set. */
+
+struct debug_set_type
+{
+ /* Base type. */
+ debug_type type;
+ /* Whether this set is really a bitstring. */
+ boolean bitstringp;
+};
+
+/* Information kept for an offset type (a based pointer). */
+
+struct debug_offset_type
+{
+ /* The type the pointer is an offset from. */
+ debug_type base_type;
+ /* The type the pointer points to. */
+ debug_type target_type;
+};
+
+/* Information kept for a method type. */
+
+struct debug_method_type
+{
+ /* The return type. */
+ debug_type return_type;
+ /* The object type which this method is for. */
+ debug_type domain_type;
+ /* A NULL terminated array of argument types. */
+ debug_type *arg_types;
+ /* Whether the method takes a variable number of arguments. */
+ boolean varargs;
+};
+
+/* Information kept for a named type. */
+
+struct debug_named_type
+{
+ /* Name. */
+ struct debug_name *name;
+ /* Real type. */
+ debug_type type;
+};
+
+/* A field in a struct or union. */
+
+struct debug_field
+{
+ /* Name of the field. */
+ const char *name;
+ /* Type of the field. */
+ struct debug_type *type;
+ /* Visibility of the field. */
+ enum debug_visibility visibility;
+ /* Whether this is a static member. */
+ boolean static_member;
+ union
+ {
+ /* If static_member is false. */
+ struct
+ {
+ /* Bit position of the field in the struct. */
+ unsigned int bitpos;
+ /* Size of the field in bits. */
+ unsigned int bitsize;
+ } f;
+ /* If static_member is true. */
+ struct
+ {
+ const char *physname;
+ } s;
+ } u;
+};
+
+/* A base class for an object. */
+
+struct debug_baseclass
+{
+ /* Type of the base class. */
+ struct debug_type *type;
+ /* Bit position of the base class in the object. */
+ unsigned int bitpos;
+ /* Whether the base class is virtual. */
+ boolean virtual;
+ /* Visibility of the base class. */
+ enum debug_visibility visibility;
+};
+
+/* A method of an object. */
+
+struct debug_method
+{
+ /* The name of the method. */
+ const char *name;
+ /* A NULL terminated array of different types of variants. */
+ struct debug_method_variant **variants;
+};
+
+/* The variants of a method function of an object. These indicate
+ which method to run. */
+
+struct debug_method_variant
+{
+ /* The physical name of the function. */
+ const char *physname;
+ /* The type of the function. */
+ struct debug_type *type;
+ /* The visibility of the function. */
+ enum debug_visibility visibility;
+ /* Whether the function is const. */
+ boolean constp;
+ /* Whether the function is volatile. */
+ boolean volatilep;
+ /* The offset to the function in the virtual function table. */
+ bfd_vma voffset;
+ /* If voffset is VOFFSET_STATIC_METHOD, this is a static method. */
+#define VOFFSET_STATIC_METHOD ((bfd_vma) -1)
+ /* Context of a virtual method function. */
+ struct debug_type *context;
+};
+
+/* A variable. This is the information we keep for a variable object.
+ This has no name; a name is associated with a variable in a
+ debug_name structure. */
+
+struct debug_variable
+{
+ /* Kind of variable. */
+ enum debug_var_kind kind;
+ /* Type. */
+ debug_type type;
+ /* Value. The interpretation of the value depends upon kind. */
+ bfd_vma val;
+};
+
+/* A function. This has no name; a name is associated with a function
+ in a debug_name structure. */
+
+struct debug_function
+{
+ /* Return type. */
+ debug_type return_type;
+ /* Parameter information. */
+ struct debug_parameter *parameters;
+ /* Block information. The first structure on the list is the main
+ block of the function, and describes function local variables. */
+ struct debug_block *blocks;
+};
+
+/* A function parameter. */
+
+struct debug_parameter
+{
+ /* Next parameter. */
+ struct debug_parameter *next;
+ /* Name. */
+ const char *name;
+ /* Type. */
+ debug_type type;
+ /* Kind. */
+ enum debug_parm_kind kind;
+ /* Value (meaning depends upon kind). */
+ bfd_vma val;
+};
+
+/* A typed constant. */
+
+struct debug_typed_constant
+{
+ /* Type. */
+ debug_type type;
+ /* Value. FIXME: We may eventually need to support non-integral
+ values. */
+ bfd_vma val;
+};
+
+/* Information about a block within a function. */
+
+struct debug_block
+{
+ /* Next block with the same parent. */
+ struct debug_block *next;
+ /* Parent block. */
+ struct debug_block *parent;
+ /* List of child blocks. */
+ struct debug_block *children;
+ /* Start address of the block. */
+ bfd_vma start;
+ /* End address of the block. */
+ bfd_vma end;
+ /* Local variables. */
+ struct debug_namespace *locals;
+};
+
+/* Line number information we keep for a compilation unit. FIXME:
+ This structure is easy to create, but can be very space
+ inefficient. */
+
+struct debug_lineno
+{
+ /* More line number information for this block. */
+ struct debug_lineno *next;
+ /* Source file. */
+ struct debug_file *file;
+ /* Line numbers, terminated by a -1 or the end of the array. */
+#define DEBUG_LINENO_COUNT 10
+ unsigned long linenos[DEBUG_LINENO_COUNT];
+ /* Addresses for the line numbers. */
+ bfd_vma addrs[DEBUG_LINENO_COUNT];
+};
+
+/* A namespace. This is a mapping from names to objects. FIXME: This
+ should be implemented as a hash table. */
+
+struct debug_namespace
+{
+ /* List of items in this namespace. */
+ struct debug_name *list;
+ /* Pointer to where the next item in this namespace should go. */
+ struct debug_name **tail;
+};
+
+/* Kinds of objects that appear in a namespace. */
+
+enum debug_object_kind
+{
+ /* A type. */
+ DEBUG_OBJECT_TYPE,
+ /* A tagged type (really a different sort of namespace). */
+ DEBUG_OBJECT_TAG,
+ /* A variable. */
+ DEBUG_OBJECT_VARIABLE,
+ /* A function. */
+ DEBUG_OBJECT_FUNCTION,
+ /* An integer constant. */
+ DEBUG_OBJECT_INT_CONSTANT,
+ /* A floating point constant. */
+ DEBUG_OBJECT_FLOAT_CONSTANT,
+ /* A typed constant. */
+ DEBUG_OBJECT_TYPED_CONSTANT
+};
+
+/* Linkage of an object that appears in a namespace. */
+
+enum debug_object_linkage
+{
+ /* Local variable. */
+ DEBUG_LINKAGE_AUTOMATIC,
+ /* Static--either file static or function static, depending upon the
+ namespace is. */
+ DEBUG_LINKAGE_STATIC,
+ /* Global. */
+ DEBUG_LINKAGE_GLOBAL,
+ /* No linkage. */
+ DEBUG_LINKAGE_NONE
+};
+
+/* A name in a namespace. */
+
+struct debug_name
+{
+ /* Next name in this namespace. */
+ struct debug_name *next;
+ /* Name. */
+ const char *name;
+ /* Mark. This is used by debug_write. */
+ unsigned int mark;
+ /* Kind of object. */
+ enum debug_object_kind kind;
+ /* Linkage of object. */
+ enum debug_object_linkage linkage;
+ /* Tagged union with additional information about the object. */
+ union
+ {
+ /* DEBUG_OBJECT_TYPE. */
+ struct debug_type *type;
+ /* DEBUG_OBJECT_TAG. */
+ struct debug_type *tag;
+ /* DEBUG_OBJECT_VARIABLE. */
+ struct debug_variable *variable;
+ /* DEBUG_OBJECT_FUNCTION. */
+ struct debug_function *function;
+ /* DEBUG_OBJECT_INT_CONSTANT. */
+ bfd_vma int_constant;
+ /* DEBUG_OBJECT_FLOAT_CONSTANT. */
+ double float_constant;
+ /* DEBUG_OBJECT_TYPED_CONSTANT. */
+ struct debug_typed_constant *typed_constant;
+ } u;
+};
+
+/* During debug_write, a linked list of these structures is used to
+ keep track of ID numbers that have been assigned to classes. */
+
+struct debug_class_id
+{
+ /* Next ID number. */
+ struct debug_class_id *next;
+ /* The type with the ID. */
+ struct debug_type *type;
+ /* The tag; NULL if no tag. */
+ const char *tag;
+};
+
+/* During debug_type_samep, a linked list of these structures is kept
+ on the stack to avoid infinite recursion. */
+
+struct debug_type_compare_list
+{
+ /* Next type on list. */
+ struct debug_type_compare_list *next;
+ /* The types we are comparing. */
+ struct debug_type *t1;
+ struct debug_type *t2;
+};
+
+/* Local functions. */
+
+static void debug_error PARAMS ((const char *));
+static struct debug_name *debug_add_to_namespace
+ PARAMS ((struct debug_handle *, struct debug_namespace **, const char *,
+ enum debug_object_kind, enum debug_object_linkage));
+static struct debug_name *debug_add_to_current_namespace
+ PARAMS ((struct debug_handle *, const char *, enum debug_object_kind,
+ enum debug_object_linkage));
+static struct debug_type *debug_make_type
+ PARAMS ((struct debug_handle *, enum debug_type_kind, unsigned int));
+static struct debug_type *debug_get_real_type PARAMS ((PTR, debug_type));
+static boolean debug_write_name
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_name *));
+static boolean debug_write_type
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_type *, struct debug_name *));
+static boolean debug_write_class_type
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_type *, const char *));
+static boolean debug_write_function
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ const char *, enum debug_object_linkage, struct debug_function *));
+static boolean debug_write_block
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_block *));
+static boolean debug_write_linenos
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ bfd_vma));
+static boolean debug_set_class_id
+ PARAMS ((struct debug_handle *, const char *, struct debug_type *));
+static boolean debug_type_samep
+ PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
+static boolean debug_class_type_samep
+ PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
+
+/* Issue an error message. */
+
+static void
+debug_error (message)
+ const char *message;
+{
+ fprintf (stderr, "%s\n", message);
+}
+
+/* Add an object to a namespace. */
+
+static struct debug_name *
+debug_add_to_namespace (info, nsp, name, kind, linkage)
+ struct debug_handle *info;
+ struct debug_namespace **nsp;
+ const char *name;
+ enum debug_object_kind kind;
+ enum debug_object_linkage linkage;
+{
+ struct debug_name *n;
+ struct debug_namespace *ns;
+
+ n = (struct debug_name *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->name = name;
+ n->kind = kind;
+ n->linkage = linkage;
+
+ ns = *nsp;
+ if (ns == NULL)
+ {
+ ns = (struct debug_namespace *) xmalloc (sizeof *ns);
+ memset (ns, 0, sizeof *ns);
+
+ ns->tail = &ns->list;
+
+ *nsp = ns;
+ }
+
+ *ns->tail = n;
+ ns->tail = &n->next;
+
+ return n;
+}
+
+/* Add an object to the current namespace. */
+
+static struct debug_name *
+debug_add_to_current_namespace (info, name, kind, linkage)
+ struct debug_handle *info;
+ const char *name;
+ enum debug_object_kind kind;
+ enum debug_object_linkage linkage;
+{
+ struct debug_namespace **nsp;
+
+ if (info->current_unit == NULL
+ || info->current_file == NULL)
+ {
+ debug_error ("debug_add_to_current_namespace: no current file");
+ return NULL;
+ }
+
+ if (info->current_block != NULL)
+ nsp = &info->current_block->locals;
+ else
+ nsp = &info->current_file->globals;
+
+ return debug_add_to_namespace (info, nsp, name, kind, linkage);
+}
+
+/* Return a handle for debugging information. */
+
+PTR
+debug_init ()
+{
+ struct debug_handle *ret;
+
+ ret = (struct debug_handle *) xmalloc (sizeof *ret);
+ memset (ret, 0, sizeof *ret);
+ return (PTR) ret;
+}
+
+/* Set the source filename. This implicitly starts a new compilation
+ unit. */
+
+boolean
+debug_set_filename (handle, name)
+ PTR handle;
+ const char *name;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_file *nfile;
+ struct debug_unit *nunit;
+
+ if (name == NULL)
+ name = "";
+
+ nfile = (struct debug_file *) xmalloc (sizeof *nfile);
+ memset (nfile, 0, sizeof *nfile);
+
+ nfile->filename = name;
+
+ nunit = (struct debug_unit *) xmalloc (sizeof *nunit);
+ memset (nunit, 0, sizeof *nunit);
+
+ nunit->files = nfile;
+ info->current_file = nfile;
+
+ if (info->current_unit != NULL)
+ info->current_unit->next = nunit;
+ else
+ {
+ assert (info->units == NULL);
+ info->units = nunit;
+ }
+
+ info->current_unit = nunit;
+
+ info->current_function = NULL;
+ info->current_block = NULL;
+ info->current_lineno = NULL;
+
+ return true;
+}
+
+/* Change source files to the given file name. This is used for
+ include files in a single compilation unit. */
+
+boolean
+debug_start_source (handle, name)
+ PTR handle;
+ const char *name;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_file *f, **pf;
+
+ if (name == NULL)
+ name = "";
+
+ if (info->current_unit == NULL)
+ {
+ debug_error ("debug_start_source: no debug_set_filename call");
+ return false;
+ }
+
+ for (f = info->current_unit->files; f != NULL; f = f->next)
+ {
+ if (f->filename[0] == name[0]
+ && f->filename[1] == name[1]
+ && strcmp (f->filename, name) == 0)
+ {
+ info->current_file = f;
+ return true;
+ }
+ }
+
+ f = (struct debug_file *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->filename = name;
+
+ for (pf = &info->current_file->next;
+ *pf != NULL;
+ pf = &(*pf)->next)
+ ;
+ *pf = f;
+
+ info->current_file = f;
+
+ return true;
+}
+
+/* Record a function definition. This implicitly starts a function
+ block. The debug_type argument is the type of the return value.
+ The boolean indicates whether the function is globally visible.
+ The bfd_vma is the address of the start of the function. Currently
+ the parameter types are specified by calls to
+ debug_record_parameter. FIXME: There is no way to specify nested
+ functions. */
+
+boolean
+debug_record_function (handle, name, return_type, global, addr)
+ PTR handle;
+ const char *name;
+ debug_type return_type;
+ boolean global;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_function *f;
+ struct debug_block *b;
+ struct debug_name *n;
+
+ if (name == NULL)
+ name = "";
+ if (return_type == NULL)
+ return false;
+
+ if (info->current_unit == NULL)
+ {
+ debug_error ("debug_record_function: no debug_set_filename call");
+ return false;
+ }
+
+ f = (struct debug_function *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->return_type = return_type;
+
+ b = (struct debug_block *) xmalloc (sizeof *b);
+ memset (b, 0, sizeof *b);
+
+ b->start = addr;
+ b->end = (bfd_vma) -1;
+
+ f->blocks = b;
+
+ info->current_function = f;
+ info->current_block = b;
+
+ /* FIXME: If we could handle nested functions, this would be the
+ place: we would want to use a different namespace. */
+ n = debug_add_to_namespace (info,
+ &info->current_file->globals,
+ name,
+ DEBUG_OBJECT_FUNCTION,
+ (global
+ ? DEBUG_LINKAGE_GLOBAL
+ : DEBUG_LINKAGE_STATIC));
+ if (n == NULL)
+ return false;
+
+ n->u.function = f;
+
+ return true;
+}
+
+/* Record a parameter for the current function. */
+
+boolean
+debug_record_parameter (handle, name, type, kind, val)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ enum debug_parm_kind kind;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_parameter *p, **pp;
+
+ if (name == NULL || type == NULL)
+ return false;
+
+ if (info->current_unit == NULL
+ || info->current_function == NULL)
+ {
+ debug_error ("debug_record_parameter: no current function");
+ return false;
+ }
+
+ p = (struct debug_parameter *) xmalloc (sizeof *p);
+ memset (p, 0, sizeof *p);
+
+ p->name = name;
+ p->type = type;
+ p->kind = kind;
+ p->val = val;
+
+ for (pp = &info->current_function->parameters;
+ *pp != NULL;
+ pp = &(*pp)->next)
+ ;
+ *pp = p;
+
+ return true;
+}
+
+/* End a function. FIXME: This should handle function nesting. */
+
+boolean
+debug_end_function (handle, addr)
+ PTR handle;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ if (info->current_unit == NULL
+ || info->current_block == NULL
+ || info->current_function == NULL)
+ {
+ debug_error ("debug_end_function: no current function");
+ return false;
+ }
+
+ if (info->current_block->parent != NULL)
+ {
+ debug_error ("debug_end_function: some blocks were not closed");
+ return false;
+ }
+
+ info->current_block->end = addr;
+
+ info->current_function = NULL;
+ info->current_block = NULL;
+
+ return true;
+}
+
+/* Start a block in a function. All local information will be
+ recorded in this block, until the matching call to debug_end_block.
+ debug_start_block and debug_end_block may be nested. The bfd_vma
+ argument is the address at which this block starts. */
+
+boolean
+debug_start_block (handle, addr)
+ PTR handle;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_block *b, **pb;
+
+ /* We must always have a current block: debug_record_function sets
+ one up. */
+ if (info->current_unit == NULL
+ || info->current_block == NULL)
+ {
+ debug_error ("debug_start_block: no current block");
+ return false;
+ }
+
+ b = (struct debug_block *) xmalloc (sizeof *b);
+ memset (b, 0, sizeof *b);
+
+ b->parent = info->current_block;
+ b->start = addr;
+ b->end = (bfd_vma) -1;
+
+ /* This new block is a child of the current block. */
+ for (pb = &info->current_block->children;
+ *pb != NULL;
+ pb = &(*pb)->next)
+ ;
+ *pb = b;
+
+ info->current_block = b;
+
+ return true;
+}
+
+/* Finish a block in a function. This matches the call to
+ debug_start_block. The argument is the address at which this block
+ ends. */
+
+boolean
+debug_end_block (handle, addr)
+ PTR handle;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_block *parent;
+
+ if (info->current_unit == NULL
+ || info->current_block == NULL)
+ {
+ debug_error ("debug_end_block: no current block");
+ return false;
+ }
+
+ parent = info->current_block->parent;
+ if (parent == NULL)
+ {
+ debug_error ("debug_end_block: attempt to close top level block");
+ return false;
+ }
+
+ info->current_block->end = addr;
+
+ info->current_block = parent;
+
+ return true;
+}
+
+/* Associate a line number in the current source file and function
+ with a given address. */
+
+boolean
+debug_record_line (handle, lineno, addr)
+ PTR handle;
+ unsigned long lineno;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_lineno *l;
+ unsigned int i;
+
+ if (info->current_unit == NULL)
+ {
+ debug_error ("debug_record_line: no current unit");
+ return false;
+ }
+
+ l = info->current_lineno;
+ if (l != NULL && l->file == info->current_file)
+ {
+ for (i = 0; i < DEBUG_LINENO_COUNT; i++)
+ {
+ if (l->linenos[i] == (unsigned long) -1)
+ {
+ l->linenos[i] = lineno;
+ l->addrs[i] = addr;
+ return true;
+ }
+ }
+ }
+
+ /* If we get here, then either 1) there is no current_lineno
+ structure, which means this is the first line number in this
+ compilation unit, 2) the current_lineno structure is for a
+ different file, or 3) the current_lineno structure is full.
+ Regardless, we want to allocate a new debug_lineno structure, put
+ it in the right place, and make it the new current_lineno
+ structure. */
+
+ l = (struct debug_lineno *) xmalloc (sizeof *l);
+ memset (l, 0, sizeof *l);
+
+ l->file = info->current_file;
+ l->linenos[0] = lineno;
+ l->addrs[0] = addr;
+ for (i = 1; i < DEBUG_LINENO_COUNT; i++)
+ l->linenos[i] = (unsigned long) -1;
+
+ if (info->current_lineno != NULL)
+ info->current_lineno->next = l;
+ else
+ info->current_unit->linenos = l;
+
+ info->current_lineno = l;
+
+ return true;
+}
+
+/* Start a named common block. This is a block of variables that may
+ move in memory. */
+
+boolean
+debug_start_common_block (handle, name)
+ PTR handle;
+ const char *name;
+{
+ /* FIXME */
+ debug_error ("debug_start_common_block: not implemented");
+ return false;
+}
+
+/* End a named common block. */
+
+boolean
+debug_end_common_block (handle, name)
+ PTR handle;
+ const char *name;
+{
+ /* FIXME */
+ debug_error ("debug_end_common_block: not implemented");
+ return false;
+}
+
+/* Record a named integer constant. */
+
+boolean
+debug_record_int_const (handle, name, val)
+ PTR handle;
+ const char *name;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_name *n;
+
+ if (name == NULL)
+ return false;
+
+ n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT,
+ DEBUG_LINKAGE_NONE);
+ if (n == NULL)
+ return false;
+
+ n->u.int_constant = val;
+
+ return true;
+}
+
+/* Record a named floating point constant. */
+
+boolean
+debug_record_float_const (handle, name, val)
+ PTR handle;
+ const char *name;
+ double val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_name *n;
+
+ if (name == NULL)
+ return false;
+
+ n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT,
+ DEBUG_LINKAGE_NONE);
+ if (n == NULL)
+ return false;
+
+ n->u.float_constant = val;
+
+ return true;
+}
+
+/* Record a typed constant with an integral value. */
+
+boolean
+debug_record_typed_const (handle, name, type, val)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_name *n;
+ struct debug_typed_constant *tc;
+
+ if (name == NULL || type == NULL)
+ return false;
+
+ n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT,
+ DEBUG_LINKAGE_NONE);
+ if (n == NULL)
+ return false;
+
+ tc = (struct debug_typed_constant *) xmalloc (sizeof *tc);
+ memset (tc, 0, sizeof *tc);
+
+ tc->type = type;
+ tc->val = val;
+
+ n->u.typed_constant = tc;
+
+ return true;
+}
+
+/* Record a label. */
+
+boolean
+debug_record_label (handle, name, type, addr)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ bfd_vma addr;
+{
+ /* FIXME. */
+ debug_error ("debug_record_label not implemented");
+ return false;
+}
+
+/* Record a variable. */
+
+boolean
+debug_record_variable (handle, name, type, kind, val)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_namespace **nsp;
+ enum debug_object_linkage linkage;
+ struct debug_name *n;
+ struct debug_variable *v;
+
+ if (name == NULL || type == NULL)
+ return false;
+
+ if (info->current_unit == NULL
+ || info->current_file == NULL)
+ {
+ debug_error ("debug_record_variable: no current file");
+ return false;
+ }
+
+ if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
+ {
+ nsp = &info->current_file->globals;
+ if (kind == DEBUG_GLOBAL)
+ linkage = DEBUG_LINKAGE_GLOBAL;
+ else
+ linkage = DEBUG_LINKAGE_STATIC;
+ }
+ else
+ {
+ if (info->current_block == NULL)
+ {
+ debug_error ("debug_record_variable: no current block");
+ return false;
+ }
+ nsp = &info->current_block->locals;
+ linkage = DEBUG_LINKAGE_AUTOMATIC;
+ }
+
+ n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage);
+ if (n == NULL)
+ return false;
+
+ v = (struct debug_variable *) xmalloc (sizeof *v);
+ memset (v, 0, sizeof *v);
+
+ v->kind = kind;
+ v->type = type;
+ v->val = val;
+
+ n->u.variable = v;
+
+ return true;
+}
+
+/* Make a type with a given kind and size. */
+
+/*ARGSUSED*/
+static struct debug_type *
+debug_make_type (info, kind, size)
+ struct debug_handle *info;
+ enum debug_type_kind kind;
+ unsigned int size;
+{
+ struct debug_type *t;
+
+ t = (struct debug_type *) xmalloc (sizeof *t);
+ memset (t, 0, sizeof *t);
+
+ t->kind = kind;
+ t->size = size;
+
+ return t;
+}
+
+/* Make an indirect type which may be used as a placeholder for a type
+ which is referenced before it is defined. */
+
+debug_type
+debug_make_indirect_type (handle, slot, tag)
+ PTR handle;
+ debug_type *slot;
+ const char *tag;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_indirect_type *i;
+
+ t = debug_make_type (info, DEBUG_KIND_INDIRECT, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ i = (struct debug_indirect_type *) xmalloc (sizeof *i);
+ memset (i, 0, sizeof *i);
+
+ i->slot = slot;
+ i->tag = tag;
+
+ t->u.kindirect = i;
+
+ return t;
+}
+
+/* Make a void type. There is only one of these. */
+
+debug_type
+debug_make_void_type (handle)
+ PTR handle;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_VOID, 0);
+}
+
+/* Make an integer type of a given size. The boolean argument is true
+ if the integer is unsigned. */
+
+debug_type
+debug_make_int_type (handle, size, unsignedp)
+ PTR handle;
+ unsigned int size;
+ boolean unsignedp;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ t = debug_make_type (info, DEBUG_KIND_INT, size);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kint = unsignedp;
+
+ return t;
+}
+
+/* Make a floating point type of a given size. FIXME: On some
+ platforms, like an Alpha, you probably need to be able to specify
+ the format. */
+
+debug_type
+debug_make_float_type (handle, size)
+ PTR handle;
+ unsigned int size;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_FLOAT, size);
+}
+
+/* Make a boolean type of a given size. */
+
+debug_type
+debug_make_bool_type (handle, size)
+ PTR handle;
+ unsigned int size;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_BOOL, size);
+}
+
+/* Make a complex type of a given size. */
+
+debug_type
+debug_make_complex_type (handle, size)
+ PTR handle;
+ unsigned int size;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_COMPLEX, size);
+}
+
+/* Make a structure type. The second argument is true for a struct,
+ false for a union. The third argument is the size of the struct.
+ The fourth argument is a NULL terminated array of fields. */
+
+debug_type
+debug_make_struct_type (handle, structp, size, fields)
+ PTR handle;
+ boolean structp;
+ bfd_vma size;
+ debug_field *fields;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_class_type *c;
+
+ t = debug_make_type (info,
+ structp ? DEBUG_KIND_STRUCT : DEBUG_KIND_UNION,
+ size);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ c = (struct debug_class_type *) xmalloc (sizeof *c);
+ memset (c, 0, sizeof *c);
+
+ c->fields = fields;
+
+ t->u.kclass = c;
+
+ return t;
+}
+
+/* Make an object type. The first three arguments after the handle
+ are the same as for debug_make_struct_type. The next arguments are
+ a NULL terminated array of base classes, a NULL terminated array of
+ methods, the type of the object holding the virtual function table
+ if it is not this object, and a boolean which is true if this
+ object has its own virtual function table. */
+
+debug_type
+debug_make_object_type (handle, structp, size, fields, baseclasses,
+ methods, vptrbase, ownvptr)
+ PTR handle;
+ boolean structp;
+ bfd_vma size;
+ debug_field *fields;
+ debug_baseclass *baseclasses;
+ debug_method *methods;
+ debug_type vptrbase;
+ boolean ownvptr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_class_type *c;
+
+ t = debug_make_type (info,
+ structp ? DEBUG_KIND_CLASS : DEBUG_KIND_UNION_CLASS,
+ size);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ c = (struct debug_class_type *) xmalloc (sizeof *c);
+ memset (c, 0, sizeof *c);
+
+ c->fields = fields;
+ c->baseclasses = baseclasses;
+ c->methods = methods;
+ if (ownvptr)
+ c->vptrbase = t;
+ else
+ c->vptrbase = vptrbase;
+
+ t->u.kclass = c;
+
+ return t;
+}
+
+/* Make an enumeration type. The arguments are a null terminated
+ array of strings, and an array of corresponding values. */
+
+debug_type
+debug_make_enum_type (handle, names, values)
+ PTR handle;
+ const char **names;
+ bfd_signed_vma *values;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_enum_type *e;
+
+ t = debug_make_type (info, DEBUG_KIND_ENUM, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ e = (struct debug_enum_type *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+
+ e->names = names;
+ e->values = values;
+
+ t->u.kenum = e;
+
+ return t;
+}
+
+/* Make a pointer to a given type. */
+
+debug_type
+debug_make_pointer_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (type->pointer != DEBUG_TYPE_NULL)
+ return type->pointer;
+
+ t = debug_make_type (info, DEBUG_KIND_POINTER, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kpointer = type;
+
+ type->pointer = t;
+
+ return t;
+}
+
+/* Make a function returning a given type. FIXME: We should be able
+ to record the parameter types. */
+
+debug_type
+debug_make_function_type (handle, type, arg_types, varargs)
+ PTR handle;
+ debug_type type;
+ debug_type *arg_types;
+ boolean varargs;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_function_type *f;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_FUNCTION, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ f = (struct debug_function_type *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->return_type = type;
+ f->arg_types = arg_types;
+ f->varargs = varargs;
+
+ t->u.kfunction = f;
+
+ return t;
+}
+
+/* Make a reference to a given type. */
+
+debug_type
+debug_make_reference_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_REFERENCE, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kreference = type;
+
+ return t;
+}
+
+/* Make a range of a given type from a lower to an upper bound. */
+
+debug_type
+debug_make_range_type (handle, type, lower, upper)
+ PTR handle;
+ debug_type type;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_range_type *r;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_RANGE, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ r = (struct debug_range_type *) xmalloc (sizeof *r);
+ memset (r, 0, sizeof *r);
+
+ r->type = type;
+ r->lower = lower;
+ r->upper = upper;
+
+ t->u.krange = r;
+
+ return t;
+}
+
+/* Make an array type. The second argument is the type of an element
+ of the array. The third argument is the type of a range of the
+ array. The fourth and fifth argument are the lower and upper
+ bounds, respectively. The sixth argument is true if this array is
+ actually a string, as in C. */
+
+debug_type
+debug_make_array_type (handle, element_type, range_type, lower, upper,
+ stringp)
+ PTR handle;
+ debug_type element_type;
+ debug_type range_type;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+ boolean stringp;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_array_type *a;
+
+ if (element_type == NULL || range_type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_ARRAY, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ a = (struct debug_array_type *) xmalloc (sizeof *a);
+ memset (a, 0, sizeof *a);
+
+ a->element_type = element_type;
+ a->range_type = range_type;
+ a->lower = lower;
+ a->upper = upper;
+ a->stringp = stringp;
+
+ t->u.karray = a;
+
+ return t;
+}
+
+/* Make a set of a given type. For example, a Pascal set type. The
+ boolean argument is true if this set is actually a bitstring, as in
+ CHILL. */
+
+debug_type
+debug_make_set_type (handle, type, bitstringp)
+ PTR handle;
+ debug_type type;
+ boolean bitstringp;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_set_type *s;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_SET, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ s = (struct debug_set_type *) xmalloc (sizeof *s);
+ memset (s, 0, sizeof *s);
+
+ s->type = type;
+ s->bitstringp = bitstringp;
+
+ t->u.kset = s;
+
+ return t;
+}
+
+/* Make a type for a pointer which is relative to an object. The
+ second argument is the type of the object to which the pointer is
+ relative. The third argument is the type that the pointer points
+ to. */
+
+debug_type
+debug_make_offset_type (handle, base_type, target_type)
+ PTR handle;
+ debug_type base_type;
+ debug_type target_type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_offset_type *o;
+
+ if (base_type == NULL || target_type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_OFFSET, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ o = (struct debug_offset_type *) xmalloc (sizeof *o);
+ memset (o, 0, sizeof *o);
+
+ o->base_type = base_type;
+ o->target_type = target_type;
+
+ t->u.koffset = o;
+
+ return t;
+}
+
+/* Make a type for a method function. The second argument is the
+ return type, the third argument is the domain, and the fourth
+ argument is a NULL terminated array of argument types. */
+
+debug_type
+debug_make_method_type (handle, return_type, domain_type, arg_types, varargs)
+ PTR handle;
+ debug_type return_type;
+ debug_type domain_type;
+ debug_type *arg_types;
+ boolean varargs;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_method_type *m;
+
+ if (return_type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_METHOD, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ m = (struct debug_method_type *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->return_type = return_type;
+ m->domain_type = domain_type;
+ m->arg_types = arg_types;
+ m->varargs = varargs;
+
+ t->u.kmethod = m;
+
+ return t;
+}
+
+/* Make a const qualified version of a given type. */
+
+debug_type
+debug_make_const_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_CONST, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kconst = type;
+
+ return t;
+}
+
+/* Make a volatile qualified version of a given type. */
+
+debug_type
+debug_make_volatile_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_VOLATILE, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kvolatile = type;
+
+ return t;
+}
+
+/* Make an undefined tagged type. For example, a struct which has
+ been mentioned, but not defined. */
+
+debug_type
+debug_make_undefined_tagged_type (handle, name, kind)
+ PTR handle;
+ const char *name;
+ enum debug_type_kind kind;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (name == NULL)
+ return DEBUG_TYPE_NULL;
+
+ switch (kind)
+ {
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ case DEBUG_KIND_ENUM:
+ break;
+
+ default:
+ debug_error ("debug_make_undefined_type: unsupported kind");
+ return DEBUG_TYPE_NULL;
+ }
+
+ t = debug_make_type (info, kind, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ return debug_tag_type (handle, name, t);
+}
+
+/* Make a base class for an object. The second argument is the base
+ class type. The third argument is the bit position of this base
+ class in the object (always 0 unless doing multiple inheritance).
+ The fourth argument is whether this is a virtual class. The fifth
+ argument is the visibility of the base class. */
+
+/*ARGSUSED*/
+debug_baseclass
+debug_make_baseclass (handle, type, bitpos, virtual, visibility)
+ PTR handle;
+ debug_type type;
+ bfd_vma bitpos;
+ boolean virtual;
+ enum debug_visibility visibility;
+{
+ struct debug_baseclass *b;
+
+ b = (struct debug_baseclass *) xmalloc (sizeof *b);
+ memset (b, 0, sizeof *b);
+
+ b->type = type;
+ b->bitpos = bitpos;
+ b->virtual = virtual;
+ b->visibility = visibility;
+
+ return b;
+}
+
+/* Make a field for a struct. The second argument is the name. The
+ third argument is the type of the field. The fourth argument is
+ the bit position of the field. The fifth argument is the size of
+ the field (it may be zero). The sixth argument is the visibility
+ of the field. */
+
+/*ARGSUSED*/
+debug_field
+debug_make_field (handle, name, type, bitpos, bitsize, visibility)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+ enum debug_visibility visibility;
+{
+ struct debug_field *f;
+
+ f = (struct debug_field *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->name = name;
+ f->type = type;
+ f->static_member = false;
+ f->u.f.bitpos = bitpos;
+ f->u.f.bitsize = bitsize;
+ f->visibility = visibility;
+
+ return f;
+}
+
+/* Make a static member of an object. The second argument is the
+ name. The third argument is the type of the member. The fourth
+ argument is the physical name of the member (i.e., the name as a
+ global variable). The fifth argument is the visibility of the
+ member. */
+
+/*ARGSUSED*/
+debug_field
+debug_make_static_member (handle, name, type, physname, visibility)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ const char *physname;
+ enum debug_visibility visibility;
+{
+ struct debug_field *f;
+
+ f = (struct debug_field *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->name = name;
+ f->type = type;
+ f->static_member = true;
+ f->u.s.physname = physname;
+ f->visibility = visibility;
+
+ return f;
+}
+
+/* Make a method. The second argument is the name, and the third
+ argument is a NULL terminated array of method variants. */
+
+/*ARGSUSED*/
+debug_method
+debug_make_method (handle, name, variants)
+ PTR handle;
+ const char *name;
+ debug_method_variant *variants;
+{
+ struct debug_method *m;
+
+ m = (struct debug_method *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->name = name;
+ m->variants = variants;
+
+ return m;
+}
+
+/* Make a method argument. The second argument is the real name of
+ the function. The third argument is the type of the function. The
+ fourth argument is the visibility. The fifth argument is whether
+ this is a const function. The sixth argument is whether this is a
+ volatile function. The seventh argument is the offset in the
+ virtual function table, if any. The eighth argument is the virtual
+ function context. FIXME: Are the const and volatile arguments
+ necessary? Could we just use debug_make_const_type? */
+
+/*ARGSUSED*/
+debug_method_variant
+debug_make_method_variant (handle, physname, type, visibility, constp,
+ volatilep, voffset, context)
+ PTR handle;
+ const char *physname;
+ debug_type type;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ debug_type context;
+{
+ struct debug_method_variant *m;
+
+ m = (struct debug_method_variant *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->physname = physname;
+ m->type = type;
+ m->visibility = visibility;
+ m->constp = constp;
+ m->volatilep = volatilep;
+ m->voffset = voffset;
+ m->context = context;
+
+ return m;
+}
+
+/* Make a static method argument. The arguments are the same as for
+ debug_make_method_variant, except that the last two are omitted
+ since a static method can not also be virtual. */
+
+debug_method_variant
+debug_make_static_method_variant (handle, physname, type, visibility,
+ constp, volatilep)
+ PTR handle;
+ const char *physname;
+ debug_type type;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+{
+ struct debug_method_variant *m;
+
+ m = (struct debug_method_variant *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->physname = physname;
+ m->type = type;
+ m->visibility = visibility;
+ m->constp = constp;
+ m->volatilep = volatilep;
+ m->voffset = VOFFSET_STATIC_METHOD;
+
+ return m;
+}
+
+/* Name a type. */
+
+debug_type
+debug_name_type (handle, name, type)
+ PTR handle;
+ const char *name;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_named_type *n;
+ struct debug_name *nm;
+
+ if (name == NULL || type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (info->current_unit == NULL
+ || info->current_file == NULL)
+ {
+ debug_error ("debug_name_type: no current file");
+ return DEBUG_TYPE_NULL;
+ /* return false; */
+ }
+
+ t = debug_make_type (info, DEBUG_KIND_NAMED, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ n = (struct debug_named_type *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->type = type;
+
+ t->u.knamed = n;
+
+ /* We always add the name to the global namespace. This is probably
+ wrong in some cases, but it seems to be right for stabs. FIXME. */
+
+ nm = debug_add_to_namespace (info, &info->current_file->globals, name,
+ DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE);
+ if (nm == NULL)
+ return DEBUG_TYPE_NULL;
+
+ nm->u.type = t;
+
+ n->name = nm;
+
+ return t;
+}
+
+/* Tag a type. */
+
+debug_type
+debug_tag_type (handle, name, type)
+ PTR handle;
+ const char *name;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_named_type *n;
+ struct debug_name *nm;
+
+ if (name == NULL || type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (info->current_file == NULL)
+ {
+ debug_error ("debug_tag_type: no current file");
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (type->kind == DEBUG_KIND_TAGGED)
+ {
+ if (strcmp (type->u.knamed->name->name, name) == 0)
+ return type;
+ debug_error ("debug_tag_type: extra tag attempted");
+ return DEBUG_TYPE_NULL;
+ }
+
+ t = debug_make_type (info, DEBUG_KIND_TAGGED, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ n = (struct debug_named_type *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->type = type;
+
+ t->u.knamed = n;
+
+ /* We keep a global namespace of tags for each compilation unit. I
+ don't know if that is the right thing to do. */
+
+ nm = debug_add_to_namespace (info, &info->current_file->globals, name,
+ DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE);
+ if (nm == NULL)
+ return DEBUG_TYPE_NULL;
+
+ nm->u.tag = t;
+
+ n->name = nm;
+
+ return t;
+}
+
+/* Record the size of a given type. */
+
+/*ARGSUSED*/
+boolean
+debug_record_type_size (handle, type, size)
+ PTR handle;
+ debug_type type;
+ unsigned int size;
+{
+#if 0
+ if (type->size != 0 && type->size != size)
+ fprintf (stderr, "Warning: changing type size from %d to %d\n",
+ type->size, size);
+#endif
+
+ type->size = size;
+
+ return true;
+}
+
+/* Find a named type. */
+
+debug_type
+debug_find_named_type (handle, name)
+ PTR handle;
+ const char *name;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_block *b;
+ struct debug_file *f;
+
+ /* We only search the current compilation unit. I don't know if
+ this is right or not. */
+
+ if (info->current_unit == NULL)
+ {
+ debug_error ("debug_find_named_type: no current compilation unit");
+ return DEBUG_TYPE_NULL;
+ }
+
+ for (b = info->current_block; b != NULL; b = b->parent)
+ {
+ if (b->locals != NULL)
+ {
+ struct debug_name *n;
+
+ for (n = b->locals->list; n != NULL; n = n->next)
+ {
+ if (n->kind == DEBUG_OBJECT_TYPE
+ && n->name[0] == name[0]
+ && strcmp (n->name, name) == 0)
+ return n->u.type;
+ }
+ }
+ }
+
+ for (f = info->current_unit->files; f != NULL; f = f->next)
+ {
+ if (f->globals != NULL)
+ {
+ struct debug_name *n;
+
+ for (n = f->globals->list; n != NULL; n = n->next)
+ {
+ if (n->kind == DEBUG_OBJECT_TYPE
+ && n->name[0] == name[0]
+ && strcmp (n->name, name) == 0)
+ return n->u.type;
+ }
+ }
+ }
+
+ return DEBUG_TYPE_NULL;
+}
+
+/* Find a tagged type. */
+
+debug_type
+debug_find_tagged_type (handle, name, kind)
+ PTR handle;
+ const char *name;
+ enum debug_type_kind kind;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_unit *u;
+
+ /* We search the globals of all the compilation units. I don't know
+ if this is correct or not. It would be easy to change. */
+
+ for (u = info->units; u != NULL; u = u->next)
+ {
+ struct debug_file *f;
+
+ for (f = u->files; f != NULL; f = f->next)
+ {
+ struct debug_name *n;
+
+ if (f->globals != NULL)
+ {
+ for (n = f->globals->list; n != NULL; n = n->next)
+ {
+ if (n->kind == DEBUG_OBJECT_TAG
+ && (kind == DEBUG_KIND_ILLEGAL
+ || n->u.tag->kind == kind)
+ && n->name[0] == name[0]
+ && strcmp (n->name, name) == 0)
+ return n->u.tag;
+ }
+ }
+ }
+ }
+
+ return DEBUG_TYPE_NULL;
+}
+
+/* Get a base type. */
+
+static struct debug_type *
+debug_get_real_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ switch (type->kind)
+ {
+ default:
+ return type;
+ case DEBUG_KIND_INDIRECT:
+ if (*type->u.kindirect->slot != NULL)
+ return debug_get_real_type (handle, *type->u.kindirect->slot);
+ return type;
+ case DEBUG_KIND_NAMED:
+ case DEBUG_KIND_TAGGED:
+ return debug_get_real_type (handle, type->u.knamed->type);
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the kind of a type. */
+
+enum debug_type_kind
+debug_get_type_kind (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return DEBUG_KIND_ILLEGAL;
+ type = debug_get_real_type (handle, type);
+ return type->kind;
+}
+
+/* Get the name of a type. */
+
+const char *
+debug_get_type_name (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type->kind == DEBUG_KIND_INDIRECT)
+ {
+ if (*type->u.kindirect->slot != NULL)
+ return debug_get_type_name (handle, *type->u.kindirect->slot);
+ return type->u.kindirect->tag;
+ }
+ if (type->kind == DEBUG_KIND_NAMED
+ || type->kind == DEBUG_KIND_TAGGED)
+ return type->u.knamed->name->name;
+ return NULL;
+}
+
+/* Get the size of a type. */
+
+bfd_vma
+debug_get_type_size (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return 0;
+
+ /* We don't call debug_get_real_type, because somebody might have
+ called debug_record_type_size on a named or indirect type. */
+
+ if (type->size != 0)
+ return type->size;
+
+ switch (type->kind)
+ {
+ default:
+ return 0;
+ case DEBUG_KIND_INDIRECT:
+ if (*type->u.kindirect->slot != NULL)
+ return debug_get_type_size (handle, *type->u.kindirect->slot);
+ return 0;
+ case DEBUG_KIND_NAMED:
+ case DEBUG_KIND_TAGGED:
+ return debug_get_type_size (handle, type->u.knamed->type);
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the return type of a function or method type. */
+
+debug_type
+debug_get_return_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+ type = debug_get_real_type (handle, type);
+ switch (type->kind)
+ {
+ default:
+ return DEBUG_TYPE_NULL;
+ case DEBUG_KIND_FUNCTION:
+ return type->u.kfunction->return_type;
+ case DEBUG_KIND_METHOD:
+ return type->u.kmethod->return_type;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the parameter types of a function or method type (except that
+ we don't currently store the parameter types of a function). */
+
+const debug_type *
+debug_get_parameter_types (handle, type, pvarargs)
+ PTR handle;
+ debug_type type;
+ boolean *pvarargs;
+{
+ if (type == NULL)
+ return NULL;
+ type = debug_get_real_type (handle, type);
+ switch (type->kind)
+ {
+ default:
+ return NULL;
+ case DEBUG_KIND_FUNCTION:
+ *pvarargs = type->u.kfunction->varargs;
+ return type->u.kfunction->arg_types;
+ case DEBUG_KIND_METHOD:
+ *pvarargs = type->u.kmethod->varargs;
+ return type->u.kmethod->arg_types;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the target type of a type. */
+
+debug_type
+debug_get_target_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return NULL;
+ type = debug_get_real_type (handle, type);
+ switch (type->kind)
+ {
+ default:
+ return NULL;
+ case DEBUG_KIND_POINTER:
+ return type->u.kpointer;
+ case DEBUG_KIND_REFERENCE:
+ return type->u.kreference;
+ case DEBUG_KIND_CONST:
+ return type->u.kconst;
+ case DEBUG_KIND_VOLATILE:
+ return type->u.kvolatile;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the NULL terminated array of fields for a struct, union, or
+ class. */
+
+const debug_field *
+debug_get_fields (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return NULL;
+ type = debug_get_real_type (handle, type);
+ switch (type->kind)
+ {
+ default:
+ return NULL;
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ return type->u.kclass->fields;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the type of a field. */
+
+/*ARGSUSED*/
+debug_type
+debug_get_field_type (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL)
+ return NULL;
+ return field->type;
+}
+
+/* Get the name of a field. */
+
+/*ARGSUSED*/
+const char *
+debug_get_field_name (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL)
+ return NULL;
+ return field->name;
+}
+
+/* Get the bit position of a field. */
+
+/*ARGSUSED*/
+bfd_vma
+debug_get_field_bitpos (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL || field->static_member)
+ return (bfd_vma) -1;
+ return field->u.f.bitpos;
+}
+
+/* Get the bit size of a field. */
+
+/*ARGSUSED*/
+bfd_vma
+debug_get_field_bitsize (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL || field->static_member)
+ return (bfd_vma) -1;
+ return field->u.f.bitsize;
+}
+
+/* Get the visibility of a field. */
+
+/*ARGSUSED*/
+enum debug_visibility
+debug_get_field_visibility (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL)
+ return DEBUG_VISIBILITY_IGNORE;
+ return field->visibility;
+}
+
+/* Get the physical name of a field. */
+
+const char *
+debug_get_field_physname (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL || ! field->static_member)
+ return NULL;
+ return field->u.s.physname;
+}
+
+/* Write out the debugging information. This is given a handle to
+ debugging information, and a set of function pointers to call. */
+
+boolean
+debug_write (handle, fns, fhandle)
+ PTR handle;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_unit *u;
+
+ /* We use a mark to tell whether we have already written out a
+ particular name. We use an integer, so that we don't have to
+ clear the mark fields if we happen to write out the same
+ information more than once. */
+ ++info->mark;
+
+ /* The base_id field holds an ID value which will never be used, so
+ that we can tell whether we have assigned an ID during this call
+ to debug_write. */
+ info->base_id = info->class_id;
+
+ /* We keep a linked list of classes for which was have assigned ID's
+ during this call to debug_write. */
+ info->id_list = NULL;
+
+ for (u = info->units; u != NULL; u = u->next)
+ {
+ struct debug_file *f;
+ boolean first_file;
+
+ info->current_write_lineno = u->linenos;
+ info->current_write_lineno_index = 0;
+
+ if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))
+ return false;
+
+ first_file = true;
+ for (f = u->files; f != NULL; f = f->next)
+ {
+ struct debug_name *n;
+
+ if (first_file)
+ first_file = false;
+ else
+ {
+ if (! (*fns->start_source) (fhandle, f->filename))
+ return false;
+ }
+
+ if (f->globals != NULL)
+ {
+ for (n = f->globals->list; n != NULL; n = n->next)
+ {
+ if (! debug_write_name (info, fns, fhandle, n))
+ return false;
+ }
+ }
+ }
+
+ /* Output any line number information which hasn't already been
+ handled. */
+ if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out an element in a namespace. */
+
+static boolean
+debug_write_name (info, fns, fhandle, n)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_name *n;
+{
+ switch (n->kind)
+ {
+ case DEBUG_OBJECT_TYPE:
+ if (! debug_write_type (info, fns, fhandle, n->u.type, n)
+ || ! (*fns->typdef) (fhandle, n->name))
+ return false;
+ return true;
+ case DEBUG_OBJECT_TAG:
+ if (! debug_write_type (info, fns, fhandle, n->u.tag, n))
+ return false;
+ return (*fns->tag) (fhandle, n->name);
+ case DEBUG_OBJECT_VARIABLE:
+ if (! debug_write_type (info, fns, fhandle, n->u.variable->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->variable) (fhandle, n->name, n->u.variable->kind,
+ n->u.variable->val);
+ case DEBUG_OBJECT_FUNCTION:
+ return debug_write_function (info, fns, fhandle, n->name,
+ n->linkage, n->u.function);
+ case DEBUG_OBJECT_INT_CONSTANT:
+ return (*fns->int_constant) (fhandle, n->name, n->u.int_constant);
+ case DEBUG_OBJECT_FLOAT_CONSTANT:
+ return (*fns->float_constant) (fhandle, n->name, n->u.float_constant);
+ case DEBUG_OBJECT_TYPED_CONSTANT:
+ if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->typed_constant) (fhandle, n->name,
+ n->u.typed_constant->val);
+ default:
+ abort ();
+ return false;
+ }
+ /*NOTREACHED*/
+}
+
+/* Write out a type. If the type is DEBUG_KIND_NAMED or
+ DEBUG_KIND_TAGGED, then the name argument is the name for which we
+ are about to call typedef or tag. If the type is anything else,
+ then the name argument is a tag from a DEBUG_KIND_TAGGED type which
+ points to this one. */
+
+static boolean
+debug_write_type (info, fns, fhandle, type, name)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_type *type;
+ struct debug_name *name;
+{
+ unsigned int i;
+ int is;
+ const char *tag;
+
+ /* If we have a name for this type, just output it. We only output
+ typedef names after they have been defined. We output type tags
+ whenever we are not actually defining them. */
+ if ((type->kind == DEBUG_KIND_NAMED
+ || type->kind == DEBUG_KIND_TAGGED)
+ && (type->u.knamed->name->mark == info->mark
+ || (type->kind == DEBUG_KIND_TAGGED
+ && type->u.knamed->name != name)))
+ {
+ if (type->kind == DEBUG_KIND_NAMED)
+ return (*fns->typedef_type) (fhandle, type->u.knamed->name->name);
+ else
+ {
+ struct debug_type *real;
+ unsigned int id;
+
+ real = debug_get_real_type ((PTR) info, type);
+ id = 0;
+ if ((real->kind == DEBUG_KIND_STRUCT
+ || real->kind == DEBUG_KIND_UNION
+ || real->kind == DEBUG_KIND_CLASS
+ || real->kind == DEBUG_KIND_UNION_CLASS)
+ && real->u.kclass != NULL)
+ {
+ if (real->u.kclass->id <= info->base_id)
+ {
+ if (! debug_set_class_id (info,
+ type->u.knamed->name->name,
+ real))
+ return false;
+ }
+ id = real->u.kclass->id;
+ }
+
+ return (*fns->tag_type) (fhandle, type->u.knamed->name->name, id,
+ real->kind);
+ }
+ }
+
+ /* Mark the name after we have already looked for a known name, so
+ that we don't just define a type in terms of itself. We need to
+ mark the name here so that a struct containing a pointer to
+ itself will work. */
+ if (name != NULL)
+ name->mark = info->mark;
+
+ tag = NULL;
+ if (name != NULL
+ && type->kind != DEBUG_KIND_NAMED
+ && type->kind != DEBUG_KIND_TAGGED)
+ {
+ assert (name->kind == DEBUG_OBJECT_TAG);
+ tag = name->name;
+ }
+
+ switch (type->kind)
+ {
+ case DEBUG_KIND_ILLEGAL:
+ debug_error ("debug_write_type: illegal type encountered");
+ return false;
+ case DEBUG_KIND_INDIRECT:
+ if (*type->u.kindirect->slot == DEBUG_TYPE_NULL)
+ return (*fns->empty_type) (fhandle);
+ return debug_write_type (info, fns, fhandle, *type->u.kindirect->slot,
+ name);
+ case DEBUG_KIND_VOID:
+ return (*fns->void_type) (fhandle);
+ case DEBUG_KIND_INT:
+ return (*fns->int_type) (fhandle, type->size, type->u.kint);
+ case DEBUG_KIND_FLOAT:
+ return (*fns->float_type) (fhandle, type->size);
+ case DEBUG_KIND_COMPLEX:
+ return (*fns->complex_type) (fhandle, type->size);
+ case DEBUG_KIND_BOOL:
+ return (*fns->bool_type) (fhandle, type->size);
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ if (type->u.kclass != NULL)
+ {
+ if (type->u.kclass->id <= info->base_id)
+ {
+ if (! debug_set_class_id (info, tag, type))
+ return false;
+ }
+
+ if (info->mark == type->u.kclass->mark)
+ {
+ /* We are currently outputting this struct, or we have
+ already output it. I don't know if this can happen,
+ but it can happen for a class. */
+ assert (type->u.kclass->id > info->base_id);
+ return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
+ type->kind);
+ }
+ type->u.kclass->mark = info->mark;
+ }
+
+ if (! (*fns->start_struct_type) (fhandle, tag,
+ (type->u.kclass != NULL
+ ? type->u.kclass->id
+ : 0),
+ type->kind == DEBUG_KIND_STRUCT,
+ type->size))
+ return false;
+ if (type->u.kclass != NULL
+ && type->u.kclass->fields != NULL)
+ {
+ for (i = 0; type->u.kclass->fields[i] != NULL; i++)
+ {
+ struct debug_field *f;
+
+ f = type->u.kclass->fields[i];
+ if (! debug_write_type (info, fns, fhandle, f->type,
+ (struct debug_name *) NULL)
+ || ! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
+ f->u.f.bitsize, f->visibility))
+ return false;
+ }
+ }
+ return (*fns->end_struct_type) (fhandle);
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ return debug_write_class_type (info, fns, fhandle, type, tag);
+ case DEBUG_KIND_ENUM:
+ if (type->u.kenum == NULL)
+ return (*fns->enum_type) (fhandle, tag, (const char **) NULL,
+ (bfd_signed_vma *) NULL);
+ return (*fns->enum_type) (fhandle, tag, type->u.kenum->names,
+ type->u.kenum->values);
+ case DEBUG_KIND_POINTER:
+ if (! debug_write_type (info, fns, fhandle, type->u.kpointer,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->pointer_type) (fhandle);
+ case DEBUG_KIND_FUNCTION:
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kfunction->return_type,
+ (struct debug_name *) NULL))
+ return false;
+ if (type->u.kfunction->arg_types == NULL)
+ is = -1;
+ else
+ {
+ for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++)
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kfunction->arg_types[is],
+ (struct debug_name *) NULL))
+ return false;
+ }
+ return (*fns->function_type) (fhandle, is,
+ type->u.kfunction->varargs);
+ case DEBUG_KIND_REFERENCE:
+ if (! debug_write_type (info, fns, fhandle, type->u.kreference,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->reference_type) (fhandle);
+ case DEBUG_KIND_RANGE:
+ if (! debug_write_type (info, fns, fhandle, type->u.krange->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->range_type) (fhandle, type->u.krange->lower,
+ type->u.krange->upper);
+ case DEBUG_KIND_ARRAY:
+ if (! debug_write_type (info, fns, fhandle, type->u.karray->element_type,
+ (struct debug_name *) NULL)
+ || ! debug_write_type (info, fns, fhandle,
+ type->u.karray->range_type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->array_type) (fhandle, type->u.karray->lower,
+ type->u.karray->upper,
+ type->u.karray->stringp);
+ case DEBUG_KIND_SET:
+ if (! debug_write_type (info, fns, fhandle, type->u.kset->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->set_type) (fhandle, type->u.kset->bitstringp);
+ case DEBUG_KIND_OFFSET:
+ if (! debug_write_type (info, fns, fhandle, type->u.koffset->base_type,
+ (struct debug_name *) NULL)
+ || ! debug_write_type (info, fns, fhandle,
+ type->u.koffset->target_type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->offset_type) (fhandle);
+ case DEBUG_KIND_METHOD:
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kmethod->return_type,
+ (struct debug_name *) NULL))
+ return false;
+ if (type->u.kmethod->arg_types == NULL)
+ is = -1;
+ else
+ {
+ for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++)
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kmethod->arg_types[is],
+ (struct debug_name *) NULL))
+ return false;
+ }
+ if (type->u.kmethod->domain_type != NULL)
+ {
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kmethod->domain_type,
+ (struct debug_name *) NULL))
+ return false;
+ }
+ return (*fns->method_type) (fhandle,
+ type->u.kmethod->domain_type != NULL,
+ is,
+ type->u.kmethod->varargs);
+ case DEBUG_KIND_CONST:
+ if (! debug_write_type (info, fns, fhandle, type->u.kconst,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->const_type) (fhandle);
+ case DEBUG_KIND_VOLATILE:
+ if (! debug_write_type (info, fns, fhandle, type->u.kvolatile,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->volatile_type) (fhandle);
+ case DEBUG_KIND_NAMED:
+ return debug_write_type (info, fns, fhandle, type->u.knamed->type,
+ (struct debug_name *) NULL);
+ case DEBUG_KIND_TAGGED:
+ return debug_write_type (info, fns, fhandle, type->u.knamed->type,
+ type->u.knamed->name);
+ default:
+ abort ();
+ return false;
+ }
+}
+
+/* Write out a class type. */
+
+static boolean
+debug_write_class_type (info, fns, fhandle, type, tag)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_type *type;
+ const char *tag;
+{
+ unsigned int i;
+ unsigned int id;
+ struct debug_type *vptrbase;
+
+ if (type->u.kclass == NULL)
+ {
+ id = 0;
+ vptrbase = NULL;
+ }
+ else
+ {
+ if (type->u.kclass->id <= info->base_id)
+ {
+ if (! debug_set_class_id (info, tag, type))
+ return false;
+ }
+
+ if (info->mark == type->u.kclass->mark)
+ {
+ /* We are currently outputting this class, or we have
+ already output it. This can happen when there are
+ methods for an anonymous class. */
+ assert (type->u.kclass->id > info->base_id);
+ return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
+ type->kind);
+ }
+ type->u.kclass->mark = info->mark;
+ id = type->u.kclass->id;
+
+ vptrbase = type->u.kclass->vptrbase;
+ if (vptrbase != NULL && vptrbase != type)
+ {
+ if (! debug_write_type (info, fns, fhandle, vptrbase,
+ (struct debug_name *) NULL))
+ return false;
+ }
+ }
+
+ if (! (*fns->start_class_type) (fhandle, tag, id,
+ type->kind == DEBUG_KIND_CLASS,
+ type->size,
+ vptrbase != NULL,
+ vptrbase == type))
+ return false;
+
+ if (type->u.kclass != NULL)
+ {
+ if (type->u.kclass->fields != NULL)
+ {
+ for (i = 0; type->u.kclass->fields[i] != NULL; i++)
+ {
+ struct debug_field *f;
+
+ f = type->u.kclass->fields[i];
+ if (! debug_write_type (info, fns, fhandle, f->type,
+ (struct debug_name *) NULL))
+ return false;
+ if (f->static_member)
+ {
+ if (! (*fns->class_static_member) (fhandle, f->name,
+ f->u.s.physname,
+ f->visibility))
+ return false;
+ }
+ else
+ {
+ if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
+ f->u.f.bitsize, f->visibility))
+ return false;
+ }
+ }
+ }
+
+ if (type->u.kclass->baseclasses != NULL)
+ {
+ for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++)
+ {
+ struct debug_baseclass *b;
+
+ b = type->u.kclass->baseclasses[i];
+ if (! debug_write_type (info, fns, fhandle, b->type,
+ (struct debug_name *) NULL))
+ return false;
+ if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual,
+ b->visibility))
+ return false;
+ }
+ }
+
+ if (type->u.kclass->methods != NULL)
+ {
+ for (i = 0; type->u.kclass->methods[i] != NULL; i++)
+ {
+ struct debug_method *m;
+ unsigned int j;
+
+ m = type->u.kclass->methods[i];
+ if (! (*fns->class_start_method) (fhandle, m->name))
+ return false;
+ for (j = 0; m->variants[j] != NULL; j++)
+ {
+ struct debug_method_variant *v;
+
+ v = m->variants[j];
+ if (v->context != NULL)
+ {
+ if (! debug_write_type (info, fns, fhandle, v->context,
+ (struct debug_name *) NULL))
+ return false;
+ }
+ if (! debug_write_type (info, fns, fhandle, v->type,
+ (struct debug_name *) NULL))
+ return false;
+ if (v->voffset != VOFFSET_STATIC_METHOD)
+ {
+ if (! (*fns->class_method_variant) (fhandle, v->physname,
+ v->visibility,
+ v->constp,
+ v->volatilep,
+ v->voffset,
+ v->context != NULL))
+ return false;
+ }
+ else
+ {
+ if (! (*fns->class_static_method_variant) (fhandle,
+ v->physname,
+ v->visibility,
+ v->constp,
+ v->volatilep))
+ return false;
+ }
+ }
+ if (! (*fns->class_end_method) (fhandle))
+ return false;
+ }
+ }
+ }
+
+ return (*fns->end_class_type) (fhandle);
+}
+
+/* Write out information for a function. */
+
+static boolean
+debug_write_function (info, fns, fhandle, name, linkage, function)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ const char *name;
+ enum debug_object_linkage linkage;
+ struct debug_function *function;
+{
+ struct debug_parameter *p;
+ struct debug_block *b;
+
+ if (! debug_write_linenos (info, fns, fhandle, function->blocks->start))
+ return false;
+
+ if (! debug_write_type (info, fns, fhandle, function->return_type,
+ (struct debug_name *) NULL))
+ return false;
+
+ if (! (*fns->start_function) (fhandle, name,
+ linkage == DEBUG_LINKAGE_GLOBAL))
+ return false;
+
+ for (p = function->parameters; p != NULL; p = p->next)
+ {
+ if (! debug_write_type (info, fns, fhandle, p->type,
+ (struct debug_name *) NULL)
+ || ! (*fns->function_parameter) (fhandle, p->name, p->kind, p->val))
+ return false;
+ }
+
+ for (b = function->blocks; b != NULL; b = b->next)
+ {
+ if (! debug_write_block (info, fns, fhandle, b))
+ return false;
+ }
+
+ return (*fns->end_function) (fhandle);
+}
+
+/* Write out information for a block. */
+
+static boolean
+debug_write_block (info, fns, fhandle, block)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_block *block;
+{
+ struct debug_name *n;
+ struct debug_block *b;
+
+ if (! debug_write_linenos (info, fns, fhandle, block->start))
+ return false;
+
+ /* I can't see any point to writing out a block with no local
+ variables, so we don't bother, except for the top level block. */
+ if (block->locals != NULL || block->parent == NULL)
+ {
+ if (! (*fns->start_block) (fhandle, block->start))
+ return false;
+ }
+
+ if (block->locals != NULL)
+ {
+ for (n = block->locals->list; n != NULL; n = n->next)
+ {
+ if (! debug_write_name (info, fns, fhandle, n))
+ return false;
+ }
+ }
+
+ for (b = block->children; b != NULL; b = b->next)
+ {
+ if (! debug_write_block (info, fns, fhandle, b))
+ return false;
+ }
+
+ if (! debug_write_linenos (info, fns, fhandle, block->end))
+ return false;
+
+ if (block->locals != NULL || block->parent == NULL)
+ {
+ if (! (*fns->end_block) (fhandle, block->end))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out line number information up to ADDRESS. */
+
+static boolean
+debug_write_linenos (info, fns, fhandle, address)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ bfd_vma address;
+{
+ while (info->current_write_lineno != NULL)
+ {
+ struct debug_lineno *l;
+
+ l = info->current_write_lineno;
+
+ while (info->current_write_lineno_index < DEBUG_LINENO_COUNT)
+ {
+ if (l->linenos[info->current_write_lineno_index]
+ == (unsigned long) -1)
+ break;
+
+ if (l->addrs[info->current_write_lineno_index] >= address)
+ return true;
+
+ if (! (*fns->lineno) (fhandle, l->file->filename,
+ l->linenos[info->current_write_lineno_index],
+ l->addrs[info->current_write_lineno_index]))
+ return false;
+
+ ++info->current_write_lineno_index;
+ }
+
+ info->current_write_lineno = l->next;
+ info->current_write_lineno_index = 0;
+ }
+
+ return true;
+}
+
+/* Get the ID number for a class. If during the same call to
+ debug_write we find a struct with the same definition with the same
+ name, we use the same ID. This type of things happens because the
+ same struct will be defined by multiple compilation units. */
+
+static boolean
+debug_set_class_id (info, tag, type)
+ struct debug_handle *info;
+ const char *tag;
+ struct debug_type *type;
+{
+ struct debug_class_type *c;
+ struct debug_class_id *l;
+
+ assert (type->kind == DEBUG_KIND_STRUCT
+ || type->kind == DEBUG_KIND_UNION
+ || type->kind == DEBUG_KIND_CLASS
+ || type->kind == DEBUG_KIND_UNION_CLASS);
+
+ c = type->u.kclass;
+
+ if (c->id > info->base_id)
+ return true;
+
+ for (l = info->id_list; l != NULL; l = l->next)
+ {
+ if (l->type->kind != type->kind)
+ continue;
+
+ if (tag == NULL)
+ {
+ if (l->tag != NULL)
+ continue;
+ }
+ else
+ {
+ if (l->tag == NULL
+ || l->tag[0] != tag[0]
+ || strcmp (l->tag, tag) != 0)
+ continue;
+ }
+
+ if (debug_type_samep (info, l->type, type))
+ {
+ c->id = l->type->u.kclass->id;
+ return true;
+ }
+ }
+
+ /* There are no identical types. Use a new ID, and add it to the
+ list. */
+ ++info->class_id;
+ c->id = info->class_id;
+
+ l = (struct debug_class_id *) xmalloc (sizeof *l);
+ memset (l, 0, sizeof *l);
+
+ l->type = type;
+ l->tag = tag;
+
+ l->next = info->id_list;
+ info->id_list = l;
+
+ return true;
+}
+
+/* See if two types are the same. At this point, we don't care about
+ tags and the like. */
+
+static boolean
+debug_type_samep (info, t1, t2)
+ struct debug_handle *info;
+ struct debug_type *t1;
+ struct debug_type *t2;
+{
+ struct debug_type_compare_list *l;
+ struct debug_type_compare_list top;
+ boolean ret;
+
+ if (t1 == NULL)
+ return t2 == NULL;
+ if (t2 == NULL)
+ return false;
+
+ while (t1->kind == DEBUG_KIND_INDIRECT)
+ {
+ t1 = *t1->u.kindirect->slot;
+ if (t1 == NULL)
+ return false;
+ }
+ while (t2->kind == DEBUG_KIND_INDIRECT)
+ {
+ t2 = *t2->u.kindirect->slot;
+ if (t2 == NULL)
+ return false;
+ }
+
+ if (t1 == t2)
+ return true;
+
+ /* As a special case, permit a typedef to match a tag, since C++
+ debugging output will sometimes add a typedef where C debugging
+ output will not. */
+ if (t1->kind == DEBUG_KIND_NAMED
+ && t2->kind == DEBUG_KIND_TAGGED)
+ return debug_type_samep (info, t1->u.knamed->type, t2);
+ else if (t1->kind == DEBUG_KIND_TAGGED
+ && t2->kind == DEBUG_KIND_NAMED)
+ return debug_type_samep (info, t1, t2->u.knamed->type);
+
+ if (t1->kind != t2->kind
+ || t1->size != t2->size)
+ return false;
+
+ /* Get rid of the trivial cases first. */
+ switch (t1->kind)
+ {
+ default:
+ break;
+ case DEBUG_KIND_VOID:
+ case DEBUG_KIND_FLOAT:
+ case DEBUG_KIND_COMPLEX:
+ case DEBUG_KIND_BOOL:
+ return true;
+ case DEBUG_KIND_INT:
+ return t1->u.kint == t2->u.kint;
+ }
+
+ /* We have to avoid an infinite recursion. We do this by keeping a
+ list of types which we are comparing. We just keep the list on
+ the stack. If we encounter a pair of types we are currently
+ comparing, we just assume that they are equal. */
+ for (l = info->compare_list; l != NULL; l = l->next)
+ {
+ if (l->t1 == t1 && l->t2 == t2)
+ return true;
+ }
+
+ top.t1 = t1;
+ top.t2 = t2;
+ top.next = info->compare_list;
+ info->compare_list = &top;
+
+ switch (t1->kind)
+ {
+ default:
+ abort ();
+ ret = false;
+ break;
+
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ if (t1->u.kclass == NULL)
+ ret = t2->u.kclass == NULL;
+ else if (t2->u.kclass == NULL)
+ ret = false;
+ else if (t1->u.kclass->id > info->base_id
+ && t1->u.kclass->id == t2->u.kclass->id)
+ ret = true;
+ else
+ ret = debug_class_type_samep (info, t1, t2);
+ break;
+
+ case DEBUG_KIND_ENUM:
+ if (t1->u.kenum == NULL)
+ ret = t2->u.kenum == NULL;
+ else if (t2->u.kenum == NULL)
+ ret = false;
+ else
+ {
+ const char **pn1, **pn2;
+ bfd_signed_vma *pv1, *pv2;
+
+ pn1 = t1->u.kenum->names;
+ pn2 = t2->u.kenum->names;
+ pv1 = t1->u.kenum->values;
+ pv2 = t2->u.kenum->values;
+ while (*pn1 != NULL && *pn2 != NULL)
+ {
+ if (**pn1 != **pn2
+ || *pv1 != *pv2
+ || strcmp (*pn1, *pn2) != 0)
+ break;
+ ++pn1;
+ ++pn2;
+ ++pv1;
+ ++pv2;
+ }
+ ret = *pn1 == NULL && *pn2 == NULL;
+ }
+ break;
+
+ case DEBUG_KIND_POINTER:
+ ret = debug_type_samep (info, t1->u.kpointer, t2->u.kpointer);
+ break;
+
+ case DEBUG_KIND_FUNCTION:
+ if (t1->u.kfunction->varargs != t2->u.kfunction->varargs
+ || ! debug_type_samep (info, t1->u.kfunction->return_type,
+ t2->u.kfunction->return_type)
+ || ((t1->u.kfunction->arg_types == NULL)
+ != (t2->u.kfunction->arg_types == NULL)))
+ ret = false;
+ else if (t1->u.kfunction->arg_types == NULL)
+ ret = true;
+ else
+ {
+ struct debug_type **a1, **a2;
+
+ a1 = t1->u.kfunction->arg_types;
+ a2 = t2->u.kfunction->arg_types;
+ while (*a1 != NULL && *a2 != NULL)
+ if (! debug_type_samep (info, *a1, *a2))
+ break;
+ ret = *a1 == NULL && *a2 == NULL;
+ }
+ break;
+
+ case DEBUG_KIND_REFERENCE:
+ ret = debug_type_samep (info, t1->u.kreference, t2->u.kreference);
+ break;
+
+ case DEBUG_KIND_RANGE:
+ ret = (t1->u.krange->lower == t2->u.krange->lower
+ && t1->u.krange->upper == t2->u.krange->upper
+ && debug_type_samep (info, t1->u.krange->type,
+ t2->u.krange->type));
+
+ case DEBUG_KIND_ARRAY:
+ ret = (t1->u.karray->lower == t2->u.karray->lower
+ && t1->u.karray->upper == t2->u.karray->upper
+ && t1->u.karray->stringp == t2->u.karray->stringp
+ && debug_type_samep (info, t1->u.karray->element_type,
+ t2->u.karray->element_type));
+ break;
+
+ case DEBUG_KIND_SET:
+ ret = (t1->u.kset->bitstringp == t2->u.kset->bitstringp
+ && debug_type_samep (info, t1->u.kset->type, t2->u.kset->type));
+ break;
+
+ case DEBUG_KIND_OFFSET:
+ ret = (debug_type_samep (info, t1->u.koffset->base_type,
+ t2->u.koffset->base_type)
+ && debug_type_samep (info, t1->u.koffset->target_type,
+ t2->u.koffset->target_type));
+ break;
+
+ case DEBUG_KIND_METHOD:
+ if (t1->u.kmethod->varargs != t2->u.kmethod->varargs
+ || ! debug_type_samep (info, t1->u.kmethod->return_type,
+ t2->u.kmethod->return_type)
+ || ! debug_type_samep (info, t1->u.kmethod->domain_type,
+ t2->u.kmethod->domain_type)
+ || ((t1->u.kmethod->arg_types == NULL)
+ != (t2->u.kmethod->arg_types == NULL)))
+ ret = false;
+ else if (t1->u.kmethod->arg_types == NULL)
+ ret = true;
+ else
+ {
+ struct debug_type **a1, **a2;
+
+ a1 = t1->u.kmethod->arg_types;
+ a2 = t2->u.kmethod->arg_types;
+ while (*a1 != NULL && *a2 != NULL)
+ if (! debug_type_samep (info, *a1, *a2))
+ break;
+ ret = *a1 == NULL && *a2 == NULL;
+ }
+ break;
+
+ case DEBUG_KIND_CONST:
+ ret = debug_type_samep (info, t1->u.kconst, t2->u.kconst);
+ break;
+
+ case DEBUG_KIND_VOLATILE:
+ ret = debug_type_samep (info, t1->u.kvolatile, t2->u.kvolatile);
+ break;
+
+ case DEBUG_KIND_NAMED:
+ case DEBUG_KIND_TAGGED:
+ ret = (strcmp (t1->u.knamed->name->name, t2->u.knamed->name->name) == 0
+ && debug_type_samep (info, t1->u.knamed->type,
+ t2->u.knamed->type));
+ break;
+ }
+
+ info->compare_list = top.next;
+
+ return ret;
+}
+
+/* See if two classes are the same. This is a subroutine of
+ debug_type_samep. */
+
+static boolean
+debug_class_type_samep (info, t1, t2)
+ struct debug_handle *info;
+ struct debug_type *t1;
+ struct debug_type *t2;
+{
+ struct debug_class_type *c1, *c2;
+
+ c1 = t1->u.kclass;
+ c2 = t2->u.kclass;
+
+ if ((c1->fields == NULL) != (c2->fields == NULL)
+ || (c1->baseclasses == NULL) != (c2->baseclasses == NULL)
+ || (c1->methods == NULL) != (c2->methods == NULL)
+ || (c1->vptrbase == NULL) != (c2->vptrbase == NULL))
+ return false;
+
+ if (c1->fields != NULL)
+ {
+ struct debug_field **pf1, **pf2;
+
+ for (pf1 = c1->fields, pf2 = c2->fields;
+ *pf1 != NULL && *pf2 != NULL;
+ pf1++, pf2++)
+ {
+ struct debug_field *f1, *f2;
+
+ f1 = *pf1;
+ f2 = *pf2;
+ if (f1->name[0] != f2->name[0]
+ || f1->visibility != f2->visibility
+ || f1->static_member != f2->static_member)
+ return false;
+ if (f1->static_member)
+ {
+ if (strcmp (f1->u.s.physname, f2->u.s.physname) != 0)
+ return false;
+ }
+ else
+ {
+ if (f1->u.f.bitpos != f2->u.f.bitpos
+ || f1->u.f.bitsize != f2->u.f.bitsize)
+ return false;
+ }
+ /* We do the checks which require function calls last. We
+ don't require that the types of fields have the same
+ names, since that sometimes fails in the presence of
+ typedefs and we really don't care. */
+ if (strcmp (f1->name, f2->name) != 0
+ || ! debug_type_samep (info,
+ debug_get_real_type ((PTR) info,
+ f1->type),
+ debug_get_real_type ((PTR) info,
+ f2->type)))
+ return false;
+ }
+ if (*pf1 != NULL || *pf2 != NULL)
+ return false;
+ }
+
+ if (c1->vptrbase != NULL)
+ {
+ if (! debug_type_samep (info, c1->vptrbase, c2->vptrbase))
+ return false;
+ }
+
+ if (c1->baseclasses != NULL)
+ {
+ struct debug_baseclass **pb1, **pb2;
+
+ for (pb1 = c1->baseclasses, pb2 = c2->baseclasses;
+ *pb1 != NULL && *pb2 != NULL;
+ ++pb1, ++pb2)
+ {
+ struct debug_baseclass *b1, *b2;
+
+ b1 = *pb1;
+ b2 = *pb2;
+ if (b1->bitpos != b2->bitpos
+ || b1->virtual != b2->virtual
+ || b1->visibility != b2->visibility
+ || ! debug_type_samep (info, b1->type, b2->type))
+ return false;
+ }
+ if (*pb1 != NULL || *pb2 != NULL)
+ return false;
+ }
+
+ if (c1->methods != NULL)
+ {
+ struct debug_method **pm1, **pm2;
+
+ for (pm1 = c1->methods, pm2 = c2->methods;
+ *pm1 != NULL && *pm2 != NULL;
+ ++pm1, ++pm2)
+ {
+ struct debug_method *m1, *m2;
+
+ m1 = *pm1;
+ m2 = *pm2;
+ if (m1->name[0] != m2->name[0]
+ || strcmp (m1->name, m2->name) != 0
+ || (m1->variants == NULL) != (m2->variants == NULL))
+ return false;
+ if (m1->variants == NULL)
+ {
+ struct debug_method_variant **pv1, **pv2;
+
+ for (pv1 = m1->variants, pv2 = m2->variants;
+ *pv1 != NULL && *pv2 != NULL;
+ ++pv1, ++pv2)
+ {
+ struct debug_method_variant *v1, *v2;
+
+ v1 = *pv1;
+ v2 = *pv2;
+ if (v1->physname[0] != v2->physname[0]
+ || v1->visibility != v2->visibility
+ || v1->constp != v2->constp
+ || v1->volatilep != v2->volatilep
+ || v1->voffset != v2->voffset
+ || (v1->context == NULL) != (v2->context == NULL)
+ || strcmp (v1->physname, v2->physname) != 0
+ || ! debug_type_samep (info, v1->type, v2->type))
+ return false;
+ if (v1->context != NULL)
+ {
+ if (! debug_type_samep (info, v1->context,
+ v2->context))
+ return false;
+ }
+ }
+ if (*pv1 != NULL || *pv2 != NULL)
+ return false;
+ }
+ }
+ if (*pm1 != NULL || *pm2 != NULL)
+ return false;
+ }
+
+ return true;
+}
diff --git a/pstack/debug.h b/pstack/debug.h
new file mode 100644
index 00000000000..a4d3d8306cd
--- /dev/null
+++ b/pstack/debug.h
@@ -0,0 +1,798 @@
+/* debug.h -- Describe generic debugging information.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+/* This header file describes a generic debugging information format.
+ We may eventually have readers which convert different formats into
+ this generic format, and writers which write it out. The initial
+ impetus for this was writing a convertor from stabs to HP IEEE-695
+ debugging format. */
+
+/* Different kinds of types. */
+
+enum debug_type_kind
+{
+ /* Not used. */
+ DEBUG_KIND_ILLEGAL,
+ /* Indirect via a pointer. */
+ DEBUG_KIND_INDIRECT,
+ /* Void. */
+ DEBUG_KIND_VOID,
+ /* Integer. */
+ DEBUG_KIND_INT,
+ /* Floating point. */
+ DEBUG_KIND_FLOAT,
+ /* Complex. */
+ DEBUG_KIND_COMPLEX,
+ /* Boolean. */
+ DEBUG_KIND_BOOL,
+ /* Struct. */
+ DEBUG_KIND_STRUCT,
+ /* Union. */
+ DEBUG_KIND_UNION,
+ /* Class. */
+ DEBUG_KIND_CLASS,
+ /* Union class (can this really happen?). */
+ DEBUG_KIND_UNION_CLASS,
+ /* Enumeration type. */
+ DEBUG_KIND_ENUM,
+ /* Pointer. */
+ DEBUG_KIND_POINTER,
+ /* Function. */
+ DEBUG_KIND_FUNCTION,
+ /* Reference. */
+ DEBUG_KIND_REFERENCE,
+ /* Range. */
+ DEBUG_KIND_RANGE,
+ /* Array. */
+ DEBUG_KIND_ARRAY,
+ /* Set. */
+ DEBUG_KIND_SET,
+ /* Based pointer. */
+ DEBUG_KIND_OFFSET,
+ /* Method. */
+ DEBUG_KIND_METHOD,
+ /* Const qualified type. */
+ DEBUG_KIND_CONST,
+ /* Volatile qualified type. */
+ DEBUG_KIND_VOLATILE,
+ /* Named type. */
+ DEBUG_KIND_NAMED,
+ /* Tagged type. */
+ DEBUG_KIND_TAGGED
+};
+
+/* Different kinds of variables. */
+
+enum debug_var_kind
+{
+ /* Not used. */
+ DEBUG_VAR_ILLEGAL,
+ /* A global variable. */
+ DEBUG_GLOBAL,
+ /* A static variable. */
+ DEBUG_STATIC,
+ /* A local static variable. */
+ DEBUG_LOCAL_STATIC,
+ /* A local variable. */
+ DEBUG_LOCAL,
+ /* A register variable. */
+ DEBUG_REGISTER
+};
+
+/* Different kinds of function parameters. */
+
+enum debug_parm_kind
+{
+ /* Not used. */
+ DEBUG_PARM_ILLEGAL,
+ /* A stack based parameter. */
+ DEBUG_PARM_STACK,
+ /* A register parameter. */
+ DEBUG_PARM_REG,
+ /* A stack based reference parameter. */
+ DEBUG_PARM_REFERENCE,
+ /* A register reference parameter. */
+ DEBUG_PARM_REF_REG
+};
+
+/* Different kinds of visibility. */
+
+enum debug_visibility
+{
+ /* A public field (e.g., a field in a C struct). */
+ DEBUG_VISIBILITY_PUBLIC,
+ /* A protected field. */
+ DEBUG_VISIBILITY_PROTECTED,
+ /* A private field. */
+ DEBUG_VISIBILITY_PRIVATE,
+ /* A field which should be ignored. */
+ DEBUG_VISIBILITY_IGNORE
+};
+
+/* A type. */
+
+typedef struct debug_type *debug_type;
+
+#define DEBUG_TYPE_NULL ((debug_type) NULL)
+
+/* A field in a struct or union. */
+
+typedef struct debug_field *debug_field;
+
+#define DEBUG_FIELD_NULL ((debug_field) NULL)
+
+/* A base class for an object. */
+
+typedef struct debug_baseclass *debug_baseclass;
+
+#define DEBUG_BASECLASS_NULL ((debug_baseclass) NULL)
+
+/* A method of an object. */
+
+typedef struct debug_method *debug_method;
+
+#define DEBUG_METHOD_NULL ((debug_method) NULL)
+
+/* The arguments to a method function of an object. These indicate
+ which method to run. */
+
+typedef struct debug_method_variant *debug_method_variant;
+
+#define DEBUG_METHOD_VARIANT_NULL ((debug_method_variant) NULL)
+
+/* This structure is passed to debug_write. It holds function
+ pointers that debug_write will call based on the accumulated
+ debugging information. */
+
+struct debug_write_fns
+{
+ /* This is called at the start of each new compilation unit with the
+ name of the main file in the new unit. */
+ boolean (*start_compilation_unit) PARAMS ((PTR, const char *));
+
+ /* This is called at the start of each source file within a
+ compilation unit, before outputting any global information for
+ that file. The argument is the name of the file. */
+ boolean (*start_source) PARAMS ((PTR, const char *));
+
+ /* Each writer must keep a stack of types. */
+
+ /* Push an empty type onto the type stack. This type can appear if
+ there is a reference to a type which is never defined. */
+ boolean (*empty_type) PARAMS ((PTR));
+
+ /* Push a void type onto the type stack. */
+ boolean (*void_type) PARAMS ((PTR));
+
+ /* Push an integer type onto the type stack, given the size and
+ whether it is unsigned. */
+ boolean (*int_type) PARAMS ((PTR, unsigned int, boolean));
+
+ /* Push a floating type onto the type stack, given the size. */
+ boolean (*float_type) PARAMS ((PTR, unsigned int));
+
+ /* Push a complex type onto the type stack, given the size. */
+ boolean (*complex_type) PARAMS ((PTR, unsigned int));
+
+ /* Push a boolean type onto the type stack, given the size. */
+ boolean (*bool_type) PARAMS ((PTR, unsigned int));
+
+ /* Push an enum type onto the type stack, given the tag, a NULL
+ terminated array of names and the associated values. If there is
+ no tag, the tag argument will be NULL. If this is an undefined
+ enum, the names and values arguments will be NULL. */
+ boolean (*enum_type) PARAMS ((PTR, const char *, const char **,
+ bfd_signed_vma *));
+
+ /* Pop the top type on the type stack, and push a pointer to that
+ type onto the type stack. */
+ boolean (*pointer_type) PARAMS ((PTR));
+
+ /* Push a function type onto the type stack. The second argument
+ indicates the number of argument types that have been pushed onto
+ the stack. If the number of argument types is passed as -1, then
+ the argument types of the function are unknown, and no types have
+ been pushed onto the stack. The third argument is true if the
+ function takes a variable number of arguments. The return type
+ of the function is pushed onto the type stack below the argument
+ types, if any. */
+ boolean (*function_type) PARAMS ((PTR, int, boolean));
+
+ /* Pop the top type on the type stack, and push a reference to that
+ type onto the type stack. */
+ boolean (*reference_type) PARAMS ((PTR));
+
+ /* Pop the top type on the type stack, and push a range of that type
+ with the given lower and upper bounds onto the type stack. */
+ boolean (*range_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
+
+ /* Push an array type onto the type stack. The top type on the type
+ stack is the range, and the next type on the type stack is the
+ element type. These should be popped before the array type is
+ pushed. The arguments are the lower bound, the upper bound, and
+ whether the array is a string. */
+ boolean (*array_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma,
+ boolean));
+
+ /* Pop the top type on the type stack, and push a set of that type
+ onto the type stack. The argument indicates whether this set is
+ a bitstring. */
+ boolean (*set_type) PARAMS ((PTR, boolean));
+
+ /* Push an offset type onto the type stack. The top type on the
+ type stack is the target type, and the next type on the type
+ stack is the base type. These should be popped before the offset
+ type is pushed. */
+ boolean (*offset_type) PARAMS ((PTR));
+
+ /* Push a method type onto the type stack. If the second argument
+ is true, the top type on the stack is the class to which the
+ method belongs; otherwise, the class must be determined by the
+ class to which the method is attached. The third argument is the
+ number of argument types; these are pushed onto the type stack in
+ reverse order (the first type popped is the last argument to the
+ method). A value of -1 for the third argument means that no
+ argument information is available. The fourth argument is true
+ if the function takes a variable number of arguments. The next
+ type on the type stack below the domain and the argument types is
+ the return type of the method. All these types must be popped,
+ and then the method type must be pushed. */
+ boolean (*method_type) PARAMS ((PTR, boolean, int, boolean));
+
+ /* Pop the top type off the type stack, and push a const qualified
+ version of that type onto the type stack. */
+ boolean (*const_type) PARAMS ((PTR));
+
+ /* Pop the top type off the type stack, and push a volatile
+ qualified version of that type onto the type stack. */
+ boolean (*volatile_type) PARAMS ((PTR));
+
+ /* Start building a struct. This is followed by calls to the
+ struct_field function, and finished by a call to the
+ end_struct_type function. The second argument is the tag; this
+ will be NULL if there isn't one. If the second argument is NULL,
+ the third argument is a constant identifying this struct for use
+ with tag_type. The fourth argument is true for a struct, false
+ for a union. The fifth argument is the size. If this is an
+ undefined struct or union, the size will be 0 and struct_field
+ will not be called before end_struct_type is called. */
+ boolean (*start_struct_type) PARAMS ((PTR, const char *, unsigned int,
+ boolean, unsigned int));
+
+ /* Add a field to the struct type currently being built. The type
+ of the field should be popped off the type stack. The arguments
+ are the name, the bit position, the bit size (may be zero if the
+ field is not packed), and the visibility. */
+ boolean (*struct_field) PARAMS ((PTR, const char *, bfd_vma, bfd_vma,
+ enum debug_visibility));
+
+ /* Finish building a struct, and push it onto the type stack. */
+ boolean (*end_struct_type) PARAMS ((PTR));
+
+ /* Start building a class. This is followed by calls to several
+ functions: struct_field, class_static_member, class_baseclass,
+ class_start_method, class_method_variant,
+ class_static_method_variant, and class_end_method. The class is
+ finished by a call to end_class_type. The first five arguments
+ are the same as for start_struct_type. The sixth argument is
+ true if there is a virtual function table; if there is, the
+ seventh argument is true if the virtual function table can be
+ found in the type itself, and is false if the type of the object
+ holding the virtual function table should be popped from the type
+ stack. */
+ boolean (*start_class_type) PARAMS ((PTR, const char *, unsigned int,
+ boolean, unsigned int, boolean,
+ boolean));
+
+ /* Add a static member to the class currently being built. The
+ arguments are the field name, the physical name, and the
+ visibility. The type must be popped off the type stack. */
+ boolean (*class_static_member) PARAMS ((PTR, const char *, const char *,
+ enum debug_visibility));
+
+ /* Add a baseclass to the class currently being built. The type of
+ the baseclass must be popped off the type stack. The arguments
+ are the bit position, whether the class is virtual, and the
+ visibility. */
+ boolean (*class_baseclass) PARAMS ((PTR, bfd_vma, boolean,
+ enum debug_visibility));
+
+ /* Start adding a method to the class currently being built. This
+ is followed by calls to class_method_variant and
+ class_static_method_variant to describe different variants of the
+ method which take different arguments. The method is finished
+ with a call to class_end_method. The argument is the method
+ name. */
+ boolean (*class_start_method) PARAMS ((PTR, const char *));
+
+ /* Describe a variant to the class method currently being built.
+ The type of the variant must be popped off the type stack. The
+ second argument is the physical name of the function. The
+ following arguments are the visibility, whether the variant is
+ const, whether the variant is volatile, the offset in the virtual
+ function table, and whether the context is on the type stack
+ (below the variant type). */
+ boolean (*class_method_variant) PARAMS ((PTR, const char *,
+ enum debug_visibility,
+ boolean, boolean,
+ bfd_vma, boolean));
+
+ /* Describe a static variant to the class method currently being
+ built. The arguments are the same as for class_method_variant,
+ except that the last two arguments are omitted. The type of the
+ variant must be popped off the type stack. */
+ boolean (*class_static_method_variant) PARAMS ((PTR, const char *,
+ enum debug_visibility,
+ boolean, boolean));
+
+ /* Finish describing a class method. */
+ boolean (*class_end_method) PARAMS ((PTR));
+
+ /* Finish describing a class, and push it onto the type stack. */
+ boolean (*end_class_type) PARAMS ((PTR));
+
+ /* Push a type on the stack which was given a name by an earlier
+ call to typdef. */
+ boolean (*typedef_type) PARAMS ((PTR, const char *));
+
+ /* Push a tagged type on the stack which was defined earlier. If
+ the second argument is not NULL, the type was defined by a call
+ to tag. If the second argument is NULL, the type was defined by
+ a call to start_struct_type or start_class_type with a tag of
+ NULL and the number of the third argument. Either way, the
+ fourth argument is the tag kind. Note that this may be called
+ for a struct (class) being defined, in between the call to
+ start_struct_type (start_class_type) and the call to
+ end_struct_type (end_class_type). */
+ boolean (*tag_type) PARAMS ((PTR, const char *, unsigned int,
+ enum debug_type_kind));
+
+ /* Pop the type stack, and typedef it to the given name. */
+ boolean (*typdef) PARAMS ((PTR, const char *));
+
+ /* Pop the type stack, and declare it as a tagged struct or union or
+ enum or whatever. The tag passed down here is redundant, since
+ was also passed when enum_type, start_struct_type, or
+ start_class_type was called. */
+ boolean (*tag) PARAMS ((PTR, const char *));
+
+ /* This is called to record a named integer constant. */
+ boolean (*int_constant) PARAMS ((PTR, const char *, bfd_vma));
+
+ /* This is called to record a named floating point constant. */
+ boolean (*float_constant) PARAMS ((PTR, const char *, double));
+
+ /* This is called to record a typed integer constant. The type is
+ popped off the type stack. */
+ boolean (*typed_constant) PARAMS ((PTR, const char *, bfd_vma));
+
+ /* This is called to record a variable. The type is popped off the
+ type stack. */
+ boolean (*variable) PARAMS ((PTR, const char *, enum debug_var_kind,
+ bfd_vma));
+
+ /* Start writing out a function. The return type must be popped off
+ the stack. The boolean is true if the function is global. This
+ is followed by calls to function_parameter, followed by block
+ information. */
+ boolean (*start_function) PARAMS ((PTR, const char *, boolean));
+
+ /* Record a function parameter for the current function. The type
+ must be popped off the stack. */
+ boolean (*function_parameter) PARAMS ((PTR, const char *,
+ enum debug_parm_kind, bfd_vma));
+
+ /* Start writing out a block. There is at least one top level block
+ per function. Blocks may be nested. The argument is the
+ starting address of the block. */
+ boolean (*start_block) PARAMS ((PTR, bfd_vma));
+
+ /* Finish writing out a block. The argument is the ending address
+ of the block. */
+ boolean (*end_block) PARAMS ((PTR, bfd_vma));
+
+ /* Finish writing out a function. */
+ boolean (*end_function) PARAMS ((PTR));
+
+ /* Record line number information for the current compilation unit. */
+ boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma));
+};
+
+/* Exported functions. */
+
+/* The first argument to most of these functions is a handle. This
+ handle is returned by the debug_init function. The purpose of the
+ handle is to permit the debugging routines to not use static
+ variables, and hence to be reentrant. This would be useful for a
+ program which wanted to handle two executables simultaneously. */
+
+/* Return a debugging handle. */
+
+extern PTR debug_init PARAMS ((void));
+
+/* Set the source filename. This implicitly starts a new compilation
+ unit. */
+
+extern boolean debug_set_filename PARAMS ((PTR, const char *));
+
+/* Change source files to the given file name. This is used for
+ include files in a single compilation unit. */
+
+extern boolean debug_start_source PARAMS ((PTR, const char *));
+
+/* Record a function definition. This implicitly starts a function
+ block. The debug_type argument is the type of the return value.
+ The boolean indicates whether the function is globally visible.
+ The bfd_vma is the address of the start of the function. Currently
+ the parameter types are specified by calls to
+ debug_record_parameter. */
+
+extern boolean debug_record_function
+ PARAMS ((PTR, const char *, debug_type, boolean, bfd_vma));
+
+/* Record a parameter for the current function. */
+
+extern boolean debug_record_parameter
+ PARAMS ((PTR, const char *, debug_type, enum debug_parm_kind, bfd_vma));
+
+/* End a function definition. The argument is the address where the
+ function ends. */
+
+extern boolean debug_end_function PARAMS ((PTR, bfd_vma));
+
+/* Start a block in a function. All local information will be
+ recorded in this block, until the matching call to debug_end_block.
+ debug_start_block and debug_end_block may be nested. The argument
+ is the address at which this block starts. */
+
+extern boolean debug_start_block PARAMS ((PTR, bfd_vma));
+
+/* Finish a block in a function. This matches the call to
+ debug_start_block. The argument is the address at which this block
+ ends. */
+
+extern boolean debug_end_block PARAMS ((PTR, bfd_vma));
+
+/* Associate a line number in the current source file with a given
+ address. */
+
+extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma));
+
+/* Start a named common block. This is a block of variables that may
+ move in memory. */
+
+extern boolean debug_start_common_block PARAMS ((PTR, const char *));
+
+/* End a named common block. */
+
+extern boolean debug_end_common_block PARAMS ((PTR, const char *));
+
+/* Record a named integer constant. */
+
+extern boolean debug_record_int_const PARAMS ((PTR, const char *, bfd_vma));
+
+/* Record a named floating point constant. */
+
+extern boolean debug_record_float_const PARAMS ((PTR, const char *, double));
+
+/* Record a typed constant with an integral value. */
+
+extern boolean debug_record_typed_const
+ PARAMS ((PTR, const char *, debug_type, bfd_vma));
+
+/* Record a label. */
+
+extern boolean debug_record_label
+ PARAMS ((PTR, const char *, debug_type, bfd_vma));
+
+/* Record a variable. */
+
+extern boolean debug_record_variable
+ PARAMS ((PTR, const char *, debug_type, enum debug_var_kind, bfd_vma));
+
+/* Make an indirect type. The first argument is a pointer to the
+ location where the real type will be placed. The second argument
+ is the type tag, if there is one; this may be NULL; the only
+ purpose of this argument is so that debug_get_type_name can return
+ something useful. This function may be used when a type is
+ referenced before it is defined. */
+
+extern debug_type debug_make_indirect_type
+ PARAMS ((PTR, debug_type *, const char *));
+
+/* Make a void type. */
+
+extern debug_type debug_make_void_type PARAMS ((PTR));
+
+/* Make an integer type of a given size. The boolean argument is true
+ if the integer is unsigned. */
+
+extern debug_type debug_make_int_type PARAMS ((PTR, unsigned int, boolean));
+
+/* Make a floating point type of a given size. FIXME: On some
+ platforms, like an Alpha, you probably need to be able to specify
+ the format. */
+
+extern debug_type debug_make_float_type PARAMS ((PTR, unsigned int));
+
+/* Make a boolean type of a given size. */
+
+extern debug_type debug_make_bool_type PARAMS ((PTR, unsigned int));
+
+/* Make a complex type of a given size. */
+
+extern debug_type debug_make_complex_type PARAMS ((PTR, unsigned int));
+
+/* Make a structure type. The second argument is true for a struct,
+ false for a union. The third argument is the size of the struct.
+ The fourth argument is a NULL terminated array of fields. */
+
+extern debug_type debug_make_struct_type
+ PARAMS ((PTR, boolean, bfd_vma, debug_field *));
+
+/* Make an object type. The first three arguments after the handle
+ are the same as for debug_make_struct_type. The next arguments are
+ a NULL terminated array of base classes, a NULL terminated array of
+ methods, the type of the object holding the virtual function table
+ if it is not this object, and a boolean which is true if this
+ object has its own virtual function table. */
+
+extern debug_type debug_make_object_type
+ PARAMS ((PTR, boolean, bfd_vma, debug_field *, debug_baseclass *,
+ debug_method *, debug_type, boolean));
+
+/* Make an enumeration type. The arguments are a null terminated
+ array of strings, and an array of corresponding values. */
+
+extern debug_type debug_make_enum_type
+ PARAMS ((PTR, const char **, bfd_signed_vma *));
+
+/* Make a pointer to a given type. */
+
+extern debug_type debug_make_pointer_type
+ PARAMS ((PTR, debug_type));
+
+/* Make a function type. The second argument is the return type. The
+ third argument is a NULL terminated array of argument types. The
+ fourth argument is true if the function takes a variable number of
+ arguments. If the third argument is NULL, then the argument types
+ are unknown. */
+
+extern debug_type debug_make_function_type
+ PARAMS ((PTR, debug_type, debug_type *, boolean));
+
+/* Make a reference to a given type. */
+
+extern debug_type debug_make_reference_type PARAMS ((PTR, debug_type));
+
+/* Make a range of a given type from a lower to an upper bound. */
+
+extern debug_type debug_make_range_type
+ PARAMS ((PTR, debug_type, bfd_signed_vma, bfd_signed_vma));
+
+/* Make an array type. The second argument is the type of an element
+ of the array. The third argument is the type of a range of the
+ array. The fourth and fifth argument are the lower and upper
+ bounds, respectively (if the bounds are not known, lower should be
+ 0 and upper should be -1). The sixth argument is true if this
+ array is actually a string, as in C. */
+
+extern debug_type debug_make_array_type
+ PARAMS ((PTR, debug_type, debug_type, bfd_signed_vma, bfd_signed_vma,
+ boolean));
+
+/* Make a set of a given type. For example, a Pascal set type. The
+ boolean argument is true if this set is actually a bitstring, as in
+ CHILL. */
+
+extern debug_type debug_make_set_type PARAMS ((PTR, debug_type, boolean));
+
+/* Make a type for a pointer which is relative to an object. The
+ second argument is the type of the object to which the pointer is
+ relative. The third argument is the type that the pointer points
+ to. */
+
+extern debug_type debug_make_offset_type
+ PARAMS ((PTR, debug_type, debug_type));
+
+/* Make a type for a method function. The second argument is the
+ return type. The third argument is the domain. The fourth
+ argument is a NULL terminated array of argument types. The fifth
+ argument is true if the function takes a variable number of
+ arguments, in which case the array of argument types indicates the
+ types of the first arguments. The domain and the argument array
+ may be NULL, in which case this is a stub method and that
+ information is not available. Stabs debugging uses this, and gets
+ the argument types from the mangled name. */
+
+extern debug_type debug_make_method_type
+ PARAMS ((PTR, debug_type, debug_type, debug_type *, boolean));
+
+/* Make a const qualified version of a given type. */
+
+extern debug_type debug_make_const_type PARAMS ((PTR, debug_type));
+
+/* Make a volatile qualified version of a given type. */
+
+extern debug_type debug_make_volatile_type PARAMS ((PTR, debug_type));
+
+/* Make an undefined tagged type. For example, a struct which has
+ been mentioned, but not defined. */
+
+extern debug_type debug_make_undefined_tagged_type
+ PARAMS ((PTR, const char *, enum debug_type_kind));
+
+/* Make a base class for an object. The second argument is the base
+ class type. The third argument is the bit position of this base
+ class in the object. The fourth argument is whether this is a
+ virtual class. The fifth argument is the visibility of the base
+ class. */
+
+extern debug_baseclass debug_make_baseclass
+ PARAMS ((PTR, debug_type, bfd_vma, boolean, enum debug_visibility));
+
+/* Make a field for a struct. The second argument is the name. The
+ third argument is the type of the field. The fourth argument is
+ the bit position of the field. The fifth argument is the size of
+ the field (it may be zero). The sixth argument is the visibility
+ of the field. */
+
+extern debug_field debug_make_field
+ PARAMS ((PTR, const char *, debug_type, bfd_vma, bfd_vma,
+ enum debug_visibility));
+
+/* Make a static member of an object. The second argument is the
+ name. The third argument is the type of the member. The fourth
+ argument is the physical name of the member (i.e., the name as a
+ global variable). The fifth argument is the visibility of the
+ member. */
+
+extern debug_field debug_make_static_member
+ PARAMS ((PTR, const char *, debug_type, const char *,
+ enum debug_visibility));
+
+/* Make a method. The second argument is the name, and the third
+ argument is a NULL terminated array of method variants. Each
+ method variant is a method with this name but with different
+ argument types. */
+
+extern debug_method debug_make_method
+ PARAMS ((PTR, const char *, debug_method_variant *));
+
+/* Make a method variant. The second argument is the physical name of
+ the function. The third argument is the type of the function,
+ probably constructed by debug_make_method_type. The fourth
+ argument is the visibility. The fifth argument is whether this is
+ a const function. The sixth argument is whether this is a volatile
+ function. The seventh argument is the index in the virtual
+ function table, if any. The eighth argument is the virtual
+ function context. */
+
+extern debug_method_variant debug_make_method_variant
+ PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean,
+ boolean, bfd_vma, debug_type));
+
+/* Make a static method argument. The arguments are the same as for
+ debug_make_method_variant, except that the last two are omitted
+ since a static method can not also be virtual. */
+
+extern debug_method_variant debug_make_static_method_variant
+ PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean,
+ boolean));
+
+/* Name a type. This returns a new type with an attached name. */
+
+extern debug_type debug_name_type PARAMS ((PTR, const char *, debug_type));
+
+/* Give a tag to a type, such as a struct or union. This returns a
+ new type with an attached tag. */
+
+extern debug_type debug_tag_type PARAMS ((PTR, const char *, debug_type));
+
+/* Record the size of a given type. */
+
+extern boolean debug_record_type_size PARAMS ((PTR, debug_type, unsigned int));
+
+/* Find a named type. */
+
+extern debug_type debug_find_named_type PARAMS ((PTR, const char *));
+
+/* Find a tagged type. */
+
+extern debug_type debug_find_tagged_type
+ PARAMS ((PTR, const char *, enum debug_type_kind));
+
+/* Get the kind of a type. */
+
+extern enum debug_type_kind debug_get_type_kind PARAMS ((PTR, debug_type));
+
+/* Get the name of a type. */
+
+extern const char *debug_get_type_name PARAMS ((PTR, debug_type));
+
+/* Get the size of a type. */
+
+extern bfd_vma debug_get_type_size PARAMS ((PTR, debug_type));
+
+/* Get the return type of a function or method type. */
+
+extern debug_type debug_get_return_type PARAMS ((PTR, debug_type));
+
+/* Get the NULL terminated array of parameter types for a function or
+ method type (actually, parameter types are not currently stored for
+ function types). This may be used to determine whether a method
+ type is a stub method or not. The last argument points to a
+ boolean which is set to true if the function takes a variable
+ number of arguments. */
+
+extern const debug_type *debug_get_parameter_types PARAMS ((PTR,
+ debug_type,
+ boolean *));
+
+/* Get the target type of a pointer or reference or const or volatile
+ type. */
+
+extern debug_type debug_get_target_type PARAMS ((PTR, debug_type));
+
+/* Get the NULL terminated array of fields for a struct, union, or
+ class. */
+
+extern const debug_field *debug_get_fields PARAMS ((PTR, debug_type));
+
+/* Get the type of a field. */
+
+extern debug_type debug_get_field_type PARAMS ((PTR, debug_field));
+
+/* Get the name of a field. */
+
+extern const char *debug_get_field_name PARAMS ((PTR, debug_field));
+
+/* Get the bit position of a field within the containing structure.
+ If the field is a static member, this will return (bfd_vma) -1. */
+
+extern bfd_vma debug_get_field_bitpos PARAMS ((PTR, debug_field));
+
+/* Get the bit size of a field. If the field is a static member, this
+ will return (bfd_vma) -1. */
+
+extern bfd_vma debug_get_field_bitsize PARAMS ((PTR, debug_field));
+
+/* Get the visibility of a field. */
+
+extern enum debug_visibility debug_get_field_visibility
+ PARAMS ((PTR, debug_field));
+
+/* Get the physical name of a field, if it is a static member. If the
+ field is not a static member, this will return NULL. */
+
+extern const char *debug_get_field_physname PARAMS ((PTR, debug_field));
+
+/* Write out the recorded debugging information. This takes a set of
+ function pointers which are called to do the actual writing. The
+ first PTR is the debugging handle. The second PTR is a handle
+ which is passed to the functions. */
+
+extern boolean debug_write PARAMS ((PTR, const struct debug_write_fns *, PTR));
+
+#endif /* DEBUG_H */
diff --git a/pstack/demangle.h b/pstack/demangle.h
new file mode 100644
index 00000000000..a961436ca77
--- /dev/null
+++ b/pstack/demangle.h
@@ -0,0 +1,90 @@
+/* Defs for interface to demanglers.
+ Copyright 1992, 1995, 1996 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+#if !defined (DEMANGLE_H)
+#define DEMANGLE_H
+
+#ifdef IN_GCC
+#include "gansidecl.h"
+#define PARAMS(ARGS) PROTO(ARGS)
+#else /* ! IN_GCC */
+#include <ansidecl.h>
+#endif /* IN_GCC */
+
+/* Options passed to cplus_demangle (in 2nd parameter). */
+
+#define DMGL_NO_OPTS 0 /* For readability... */
+#define DMGL_PARAMS (1 << 0) /* Include function args */
+#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
+#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
+
+#define DMGL_AUTO (1 << 8)
+#define DMGL_GNU (1 << 9)
+#define DMGL_LUCID (1 << 10)
+#define DMGL_ARM (1 << 11)
+/* If none of these are set, use 'current_demangling_style' as the default. */
+#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM)
+
+/* Enumeration of possible demangling styles.
+
+ Lucid and ARM styles are still kept logically distinct, even though
+ they now both behave identically. The resulting style is actual the
+ union of both. I.E. either style recognizes both "__pt__" and "__rf__"
+ for operator "->", even though the first is lucid style and the second
+ is ARM style. (FIXME?) */
+
+extern enum demangling_styles
+{
+ unknown_demangling = 0,
+ auto_demangling = DMGL_AUTO,
+ gnu_demangling = DMGL_GNU,
+ lucid_demangling = DMGL_LUCID,
+ arm_demangling = DMGL_ARM
+} current_demangling_style;
+
+/* Define string names for the various demangling styles. */
+
+#define AUTO_DEMANGLING_STYLE_STRING "auto"
+#define GNU_DEMANGLING_STYLE_STRING "gnu"
+#define LUCID_DEMANGLING_STYLE_STRING "lucid"
+#define ARM_DEMANGLING_STYLE_STRING "arm"
+
+/* Some macros to test what demangling style is active. */
+
+#define CURRENT_DEMANGLING_STYLE current_demangling_style
+#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
+#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
+#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
+#define ARM_DEMANGLING (CURRENT_DEMANGLING_STYLE & DMGL_ARM)
+
+extern char *
+cplus_demangle PARAMS ((const char *mangled, int options));
+
+extern int
+cplus_demangle_opname PARAMS ((const char *opname, char *result, int options));
+
+extern const char *
+cplus_mangle_opname PARAMS ((const char *opname, int options));
+
+/* Note: This sets global state. FIXME if you care about multi-threading. */
+
+extern void
+set_cplus_marker_for_demangling PARAMS ((int ch));
+
+#endif /* DEMANGLE_H */
diff --git a/pstack/filemode.c b/pstack/filemode.c
new file mode 100644
index 00000000000..58b52ba7489
--- /dev/null
+++ b/pstack/filemode.c
@@ -0,0 +1,266 @@
+/* filemode.c -- make a string describing file modes
+ Copyright (C) 1985, 90, 91, 94, 95, 1997 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "bucomm.h"
+
+static char ftypelet PARAMS ((unsigned long));
+static void setst PARAMS ((unsigned long, char *));
+
+/* filemodestring - fill in string STR with an ls-style ASCII
+ representation of the st_mode field of file stats block STATP.
+ 10 characters are stored in STR; no terminating null is added.
+ The characters stored in STR are:
+
+ 0 File type. 'd' for directory, 'c' for character
+ special, 'b' for block special, 'm' for multiplex,
+ 'l' for symbolic link, 's' for socket, 'p' for fifo,
+ '-' for any other file type
+
+ 1 'r' if the owner may read, '-' otherwise.
+
+ 2 'w' if the owner may write, '-' otherwise.
+
+ 3 'x' if the owner may execute, 's' if the file is
+ set-user-id, '-' otherwise.
+ 'S' if the file is set-user-id, but the execute
+ bit isn't set.
+
+ 4 'r' if group members may read, '-' otherwise.
+
+ 5 'w' if group members may write, '-' otherwise.
+
+ 6 'x' if group members may execute, 's' if the file is
+ set-group-id, '-' otherwise.
+ 'S' if it is set-group-id but not executable.
+
+ 7 'r' if any user may read, '-' otherwise.
+
+ 8 'w' if any user may write, '-' otherwise.
+
+ 9 'x' if any user may execute, 't' if the file is "sticky"
+ (will be retained in swap space after execution), '-'
+ otherwise.
+ 'T' if the file is sticky but not executable. */
+
+#if 0
+
+/* This is not used; only mode_string is used. */
+
+void
+filemodestring (statp, str)
+ struct stat *statp;
+ char *str;
+{
+ mode_string ((unsigned long) statp->st_mode, str);
+}
+
+#endif
+
+/* Get definitions for the file permission bits. */
+
+#ifndef S_IRWXU
+#define S_IRWXU 0700
+#endif
+#ifndef S_IRUSR
+#define S_IRUSR 0400
+#endif
+#ifndef S_IWUSR
+#define S_IWUSR 0200
+#endif
+#ifndef S_IXUSR
+#define S_IXUSR 0100
+#endif
+
+#ifndef S_IRWXG
+#define S_IRWXG 0070
+#endif
+#ifndef S_IRGRP
+#define S_IRGRP 0040
+#endif
+#ifndef S_IWGRP
+#define S_IWGRP 0020
+#endif
+#ifndef S_IXGRP
+#define S_IXGRP 0010
+#endif
+
+#ifndef S_IRWXO
+#define S_IRWXO 0007
+#endif
+#ifndef S_IROTH
+#define S_IROTH 0004
+#endif
+#ifndef S_IWOTH
+#define S_IWOTH 0002
+#endif
+#ifndef S_IXOTH
+#define S_IXOTH 0001
+#endif
+
+/* Like filemodestring, but only the relevant part of the `struct stat'
+ is given as an argument. */
+
+void
+mode_string (mode, str)
+ unsigned long mode;
+ char *str;
+{
+ str[0] = ftypelet ((unsigned long) mode);
+ str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-';
+ str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-';
+ str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-';
+ str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-';
+ str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-';
+ str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-';
+ str[7] = (mode & S_IROTH) != 0 ? 'r' : '-';
+ str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-';
+ str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-';
+ setst ((unsigned long) mode, str);
+}
+
+/* Return a character indicating the type of file described by
+ file mode BITS:
+ 'd' for directories
+ 'b' for block special files
+ 'c' for character special files
+ 'm' for multiplexor files
+ 'l' for symbolic links
+ 's' for sockets
+ 'p' for fifos
+ '-' for any other file type. */
+
+#ifndef S_ISDIR
+#ifdef S_IFDIR
+#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
+#else /* ! defined (S_IFDIR) */
+#define S_ISDIR(i) (((i) & 0170000) == 040000)
+#endif /* ! defined (S_IFDIR) */
+#endif /* ! defined (S_ISDIR) */
+
+#ifndef S_ISBLK
+#ifdef S_IFBLK
+#define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK)
+#else /* ! defined (S_IFBLK) */
+#define S_ISBLK(i) 0
+#endif /* ! defined (S_IFBLK) */
+#endif /* ! defined (S_ISBLK) */
+
+#ifndef S_ISCHR
+#ifdef S_IFCHR
+#define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR)
+#else /* ! defined (S_IFCHR) */
+#define S_ISCHR(i) 0
+#endif /* ! defined (S_IFCHR) */
+#endif /* ! defined (S_ISCHR) */
+
+#ifndef S_ISFIFO
+#ifdef S_IFIFO
+#define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO)
+#else /* ! defined (S_IFIFO) */
+#define S_ISFIFO(i) 0
+#endif /* ! defined (S_IFIFO) */
+#endif /* ! defined (S_ISFIFO) */
+
+#ifndef S_ISSOCK
+#ifdef S_IFSOCK
+#define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK)
+#else /* ! defined (S_IFSOCK) */
+#define S_ISSOCK(i) 0
+#endif /* ! defined (S_IFSOCK) */
+#endif /* ! defined (S_ISSOCK) */
+
+#ifndef S_ISLNK
+#ifdef S_IFLNK
+#define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK)
+#else /* ! defined (S_IFLNK) */
+#define S_ISLNK(i) 0
+#endif /* ! defined (S_IFLNK) */
+#endif /* ! defined (S_ISLNK) */
+
+static char
+ftypelet (bits)
+ unsigned long bits;
+{
+ if (S_ISDIR (bits))
+ return 'd';
+ if (S_ISLNK (bits))
+ return 'l';
+ if (S_ISBLK (bits))
+ return 'b';
+ if (S_ISCHR (bits))
+ return 'c';
+ if (S_ISSOCK (bits))
+ return 's';
+ if (S_ISFIFO (bits))
+ return 'p';
+
+#ifdef S_IFMT
+#ifdef S_IFMPC
+ if ((bits & S_IFMT) == S_IFMPC
+ || (bits & S_IFMT) == S_IFMPB)
+ return 'm';
+#endif
+#ifdef S_IFNWK
+ if ((bits & S_IFMT) == S_IFNWK)
+ return 'n';
+#endif
+#endif
+
+ return '-';
+}
+
+/* Set the 's' and 't' flags in file attributes string CHARS,
+ according to the file mode BITS. */
+
+static void
+setst (bits, chars)
+ unsigned long bits;
+ char *chars;
+{
+#ifdef S_ISUID
+ if (bits & S_ISUID)
+ {
+ if (chars[3] != 'x')
+ /* Set-uid, but not executable by owner. */
+ chars[3] = 'S';
+ else
+ chars[3] = 's';
+ }
+#endif
+#ifdef S_ISGID
+ if (bits & S_ISGID)
+ {
+ if (chars[6] != 'x')
+ /* Set-gid, but not executable by group. */
+ chars[6] = 'S';
+ else
+ chars[6] = 's';
+ }
+#endif
+#ifdef S_ISVTX
+ if (bits & S_ISVTX)
+ {
+ if (chars[9] != 'x')
+ /* Sticky, but not executable by others. */
+ chars[9] = 'T';
+ else
+ chars[9] = 't';
+ }
+#endif
+}
diff --git a/pstack/ieee.c b/pstack/ieee.c
new file mode 100644
index 00000000000..8084656a5ef
--- /dev/null
+++ b/pstack/ieee.c
@@ -0,0 +1,7602 @@
+/* ieee.c -- Read and write IEEE-695 debugging information.
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file reads and writes IEEE-695 debugging information. */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <bfd.h>
+#include "ieee.h"
+#include "bucomm.h"
+#include <libiberty.h>
+#include "debug.h"
+#include "budbg.h"
+
+/* This structure holds an entry on the block stack. */
+
+struct ieee_block
+{
+ /* The kind of block. */
+ int kind;
+ /* The source file name, for a BB5 block. */
+ const char *filename;
+ /* The index of the function type, for a BB4 or BB6 block. */
+ unsigned int fnindx;
+ /* True if this function is being skipped. */
+ boolean skip;
+};
+
+/* This structure is the block stack. */
+
+#define BLOCKSTACK_SIZE (16)
+
+struct ieee_blockstack
+{
+ /* The stack pointer. */
+ struct ieee_block *bsp;
+ /* The stack. */
+ struct ieee_block stack[BLOCKSTACK_SIZE];
+};
+
+/* This structure holds information for a variable. */
+
+struct ieee_var
+{
+ /* Start of name. */
+ const char *name;
+ /* Length of name. */
+ unsigned long namlen;
+ /* Type. */
+ debug_type type;
+ /* Slot if we make an indirect type. */
+ debug_type *pslot;
+ /* Kind of variable or function. */
+ enum
+ {
+ IEEE_UNKNOWN,
+ IEEE_EXTERNAL,
+ IEEE_GLOBAL,
+ IEEE_STATIC,
+ IEEE_LOCAL,
+ IEEE_FUNCTION
+ } kind;
+};
+
+/* This structure holds all the variables. */
+
+struct ieee_vars
+{
+ /* Number of slots allocated. */
+ unsigned int alloc;
+ /* Variables. */
+ struct ieee_var *vars;
+};
+
+/* This structure holds information for a type. We need this because
+ we don't want to represent bitfields as real types. */
+
+struct ieee_type
+{
+ /* Type. */
+ debug_type type;
+ /* Slot if this is type is referenced before it is defined. */
+ debug_type *pslot;
+ /* Slots for arguments if we make indirect types for them. */
+ debug_type *arg_slots;
+ /* If this is a bitfield, this is the size in bits. If this is not
+ a bitfield, this is zero. */
+ unsigned long bitsize;
+};
+
+/* This structure holds all the type information. */
+
+struct ieee_types
+{
+ /* Number of slots allocated. */
+ unsigned int alloc;
+ /* Types. */
+ struct ieee_type *types;
+ /* Builtin types. */
+#define BUILTIN_TYPE_COUNT (60)
+ debug_type builtins[BUILTIN_TYPE_COUNT];
+};
+
+/* This structure holds a linked last of structs with their tag names,
+ so that we can convert them to C++ classes if necessary. */
+
+struct ieee_tag
+{
+ /* Next tag. */
+ struct ieee_tag *next;
+ /* This tag name. */
+ const char *name;
+ /* The type of the tag. */
+ debug_type type;
+ /* The tagged type is an indirect type pointing at this slot. */
+ debug_type slot;
+ /* This is an array of slots used when a field type is converted
+ into a indirect type, in case it needs to be later converted into
+ a reference type. */
+ debug_type *fslots;
+};
+
+/* This structure holds the information we pass around to the parsing
+ functions. */
+
+struct ieee_info
+{
+ /* The debugging handle. */
+ PTR dhandle;
+ /* The BFD. */
+ bfd *abfd;
+ /* The start of the bytes to be parsed. */
+ const bfd_byte *bytes;
+ /* The end of the bytes to be parsed. */
+ const bfd_byte *pend;
+ /* The block stack. */
+ struct ieee_blockstack blockstack;
+ /* Whether we have seen a BB1 or BB2. */
+ boolean saw_filename;
+ /* The variables. */
+ struct ieee_vars vars;
+ /* The global variables, after a global typedef block. */
+ struct ieee_vars *global_vars;
+ /* The types. */
+ struct ieee_types types;
+ /* The global types, after a global typedef block. */
+ struct ieee_types *global_types;
+ /* The list of tagged structs. */
+ struct ieee_tag *tags;
+};
+
+/* Basic builtin types, not including the pointers. */
+
+enum builtin_types
+{
+ builtin_unknown = 0,
+ builtin_void = 1,
+ builtin_signed_char = 2,
+ builtin_unsigned_char = 3,
+ builtin_signed_short_int = 4,
+ builtin_unsigned_short_int = 5,
+ builtin_signed_long = 6,
+ builtin_unsigned_long = 7,
+ builtin_signed_long_long = 8,
+ builtin_unsigned_long_long = 9,
+ builtin_float = 10,
+ builtin_double = 11,
+ builtin_long_double = 12,
+ builtin_long_long_double = 13,
+ builtin_quoted_string = 14,
+ builtin_instruction_address = 15,
+ builtin_int = 16,
+ builtin_unsigned = 17,
+ builtin_unsigned_int = 18,
+ builtin_char = 19,
+ builtin_long = 20,
+ builtin_short = 21,
+ builtin_unsigned_short = 22,
+ builtin_short_int = 23,
+ builtin_signed_short = 24,
+ builtin_bcd_float = 25
+};
+
+/* These are the values found in the derivation flags of a 'b'
+ component record of a 'T' type extension record in a C++ pmisc
+ record. These are bitmasks. */
+
+/* Set for a private base class, clear for a public base class.
+ Protected base classes are not supported. */
+#define BASEFLAGS_PRIVATE (0x1)
+/* Set for a virtual base class. */
+#define BASEFLAGS_VIRTUAL (0x2)
+/* Set for a friend class, clear for a base class. */
+#define BASEFLAGS_FRIEND (0x10)
+
+/* These are the values found in the specs flags of a 'd', 'm', or 'v'
+ component record of a 'T' type extension record in a C++ pmisc
+ record. The same flags are used for a 'M' record in a C++ pmisc
+ record. */
+
+/* The lower two bits hold visibility information. */
+#define CXXFLAGS_VISIBILITY (0x3)
+/* This value in the lower two bits indicates a public member. */
+#define CXXFLAGS_VISIBILITY_PUBLIC (0x0)
+/* This value in the lower two bits indicates a private member. */
+#define CXXFLAGS_VISIBILITY_PRIVATE (0x1)
+/* This value in the lower two bits indicates a protected member. */
+#define CXXFLAGS_VISIBILITY_PROTECTED (0x2)
+/* Set for a static member. */
+#define CXXFLAGS_STATIC (0x4)
+/* Set for a virtual override. */
+#define CXXFLAGS_OVERRIDE (0x8)
+/* Set for a friend function. */
+#define CXXFLAGS_FRIEND (0x10)
+/* Set for a const function. */
+#define CXXFLAGS_CONST (0x20)
+/* Set for a volatile function. */
+#define CXXFLAGS_VOLATILE (0x40)
+/* Set for an overloaded function. */
+#define CXXFLAGS_OVERLOADED (0x80)
+/* Set for an operator function. */
+#define CXXFLAGS_OPERATOR (0x100)
+/* Set for a constructor or destructor. */
+#define CXXFLAGS_CTORDTOR (0x400)
+/* Set for a constructor. */
+#define CXXFLAGS_CTOR (0x200)
+/* Set for an inline function. */
+#define CXXFLAGS_INLINE (0x800)
+
+/* Local functions. */
+
+static void ieee_error
+ PARAMS ((struct ieee_info *, const bfd_byte *, const char *));
+static void ieee_eof PARAMS ((struct ieee_info *));
+static char *savestring PARAMS ((const char *, unsigned long));
+static boolean ieee_read_number
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
+static boolean ieee_read_optional_number
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *, boolean *));
+static boolean ieee_read_id
+ PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
+ unsigned long *));
+static boolean ieee_read_optional_id
+ PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
+ unsigned long *, boolean *));
+static boolean ieee_read_expression
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
+static debug_type ieee_builtin_type
+ PARAMS ((struct ieee_info *, const bfd_byte *, unsigned int));
+static boolean ieee_alloc_type
+ PARAMS ((struct ieee_info *, unsigned int, boolean));
+static boolean ieee_read_type_index
+ PARAMS ((struct ieee_info *, const bfd_byte **, debug_type *));
+static int ieee_regno_to_genreg PARAMS ((bfd *, int));
+static int ieee_genreg_to_regno PARAMS ((bfd *, int));
+static boolean parse_ieee_bb PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_be PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_nn PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_ty PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_atn PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean ieee_read_cxx_misc
+ PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
+static boolean ieee_read_cxx_class
+ PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
+static boolean ieee_read_cxx_defaults
+ PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
+static boolean ieee_read_reference
+ PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean ieee_require_asn
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
+static boolean ieee_require_atn65
+ PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
+ unsigned long *));
+
+/* Report an error in the IEEE debugging information. */
+
+static void
+ieee_error (info, p, s)
+ struct ieee_info *info;
+ const bfd_byte *p;
+ const char *s;
+{
+ if (p != NULL)
+ fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd),
+ (unsigned long) (p - info->bytes), s, *p);
+ else
+ fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s);
+}
+
+/* Report an unexpected EOF in the IEEE debugging information. */
+
+static void
+ieee_eof (info)
+ struct ieee_info *info;
+{
+ ieee_error (info, (const bfd_byte *) NULL,
+ "unexpected end of debugging information");
+}
+
+/* Save a string in memory. */
+
+static char *
+savestring (start, len)
+ const char *start;
+ unsigned long len;
+{
+ char *ret;
+
+ ret = (char *) xmalloc (len + 1);
+ memcpy (ret, start, len);
+ ret[len] = '\0';
+ return ret;
+}
+
+/* Read a number which must be present in an IEEE file. */
+
+static boolean
+ieee_read_number (info, pp, pv)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+{
+ return ieee_read_optional_number (info, pp, pv, (boolean *) NULL);
+}
+
+/* Read a number in an IEEE file. If ppresent is not NULL, the number
+ need not be there. */
+
+static boolean
+ieee_read_optional_number (info, pp, pv, ppresent)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+ boolean *ppresent;
+{
+ ieee_record_enum_type b;
+
+ if (*pp >= info->pend)
+ {
+ if (ppresent != NULL)
+ {
+ *ppresent = false;
+ return true;
+ }
+ ieee_eof (info);
+ return false;
+ }
+
+ b = (ieee_record_enum_type) **pp;
+ ++*pp;
+
+ if (b <= ieee_number_end_enum)
+ {
+ *pv = (bfd_vma) b;
+ if (ppresent != NULL)
+ *ppresent = true;
+ return true;
+ }
+
+ if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum)
+ {
+ unsigned int i;
+
+ i = (int) b - (int) ieee_number_repeat_start_enum;
+ if (*pp + i - 1 >= info->pend)
+ {
+ ieee_eof (info);
+ return false;
+ }
+
+ *pv = 0;
+ for (; i > 0; i--)
+ {
+ *pv <<= 8;
+ *pv += **pp;
+ ++*pp;
+ }
+
+ if (ppresent != NULL)
+ *ppresent = true;
+
+ return true;
+ }
+
+ if (ppresent != NULL)
+ {
+ --*pp;
+ *ppresent = false;
+ return true;
+ }
+
+ ieee_error (info, *pp - 1, "invalid number");
+ return false;
+}
+
+/* Read a required string from an IEEE file. */
+
+static boolean
+ieee_read_id (info, pp, pname, pnamlen)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ const char **pname;
+ unsigned long *pnamlen;
+{
+ return ieee_read_optional_id (info, pp, pname, pnamlen, (boolean *) NULL);
+}
+
+/* Read a string from an IEEE file. If ppresent is not NULL, the
+ string is optional. */
+
+static boolean
+ieee_read_optional_id (info, pp, pname, pnamlen, ppresent)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ const char **pname;
+ unsigned long *pnamlen;
+ boolean *ppresent;
+{
+ bfd_byte b;
+ unsigned long len;
+
+ if (*pp >= info->pend)
+ {
+ ieee_eof (info);
+ return false;
+ }
+
+ b = **pp;
+ ++*pp;
+
+ if (b <= 0x7f)
+ len = b;
+ else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum)
+ {
+ len = **pp;
+ ++*pp;
+ }
+ else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum)
+ {
+ len = (**pp << 8) + (*pp)[1];
+ *pp += 2;
+ }
+ else
+ {
+ if (ppresent != NULL)
+ {
+ --*pp;
+ *ppresent = false;
+ return true;
+ }
+ ieee_error (info, *pp - 1, "invalid string length");
+ return false;
+ }
+
+ if ((unsigned long) (info->pend - *pp) < len)
+ {
+ ieee_eof (info);
+ return false;
+ }
+
+ *pname = (const char *) *pp;
+ *pnamlen = len;
+ *pp += len;
+
+ if (ppresent != NULL)
+ *ppresent = true;
+
+ return true;
+}
+
+/* Read an expression from an IEEE file. Since this code is only used
+ to parse debugging information, I haven't bothered to write a full
+ blown IEEE expression parser. I've only thrown in the things I've
+ seen in debugging information. This can be easily extended if
+ necessary. */
+
+static boolean
+ieee_read_expression (info, pp, pv)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+{
+ const bfd_byte *expr_start;
+#define EXPR_STACK_SIZE (10)
+ bfd_vma expr_stack[EXPR_STACK_SIZE];
+ bfd_vma *esp;
+
+ expr_start = *pp;
+
+ esp = expr_stack;
+
+ while (1)
+ {
+ const bfd_byte *start;
+ bfd_vma val;
+ boolean present;
+ ieee_record_enum_type c;
+
+ start = *pp;
+
+ if (! ieee_read_optional_number (info, pp, &val, &present))
+ return false;
+
+ if (present)
+ {
+ if (esp - expr_stack >= EXPR_STACK_SIZE)
+ {
+ ieee_error (info, start, "expression stack overflow");
+ return false;
+ }
+ *esp++ = val;
+ continue;
+ }
+
+ c = (ieee_record_enum_type) **pp;
+
+ if (c >= ieee_module_beginning_enum)
+ break;
+
+ ++*pp;
+
+ if (c == ieee_comma)
+ break;
+
+ switch (c)
+ {
+ default:
+ ieee_error (info, start, "unsupported IEEE expression operator");
+ break;
+
+ case ieee_variable_R_enum:
+ {
+ bfd_vma indx;
+ asection *s;
+
+ if (! ieee_read_number (info, pp, &indx))
+ return false;
+ for (s = info->abfd->sections; s != NULL; s = s->next)
+ if ((bfd_vma) s->target_index == indx)
+ break;
+ if (s == NULL)
+ {
+ ieee_error (info, start, "unknown section");
+ return false;
+ }
+
+ if (esp - expr_stack >= EXPR_STACK_SIZE)
+ {
+ ieee_error (info, start, "expression stack overflow");
+ return false;
+ }
+
+ *esp++ = bfd_get_section_vma (info->abfd, s);
+ }
+ break;
+
+ case ieee_function_plus_enum:
+ case ieee_function_minus_enum:
+ {
+ bfd_vma v1, v2;
+
+ if (esp - expr_stack < 2)
+ {
+ ieee_error (info, start, "expression stack underflow");
+ return false;
+ }
+
+ v1 = *--esp;
+ v2 = *--esp;
+ *esp++ = v1 + v2;
+ }
+ break;
+ }
+ }
+
+ if (esp - 1 != expr_stack)
+ {
+ ieee_error (info, expr_start, "expression stack mismatch");
+ return false;
+ }
+
+ *pv = *--esp;
+
+ return true;
+}
+
+/* Return an IEEE builtin type. */
+
+static debug_type
+ieee_builtin_type (info, p, indx)
+ struct ieee_info *info;
+ const bfd_byte *p;
+ unsigned int indx;
+{
+ PTR dhandle;
+ debug_type type;
+ const char *name;
+
+ if (indx < BUILTIN_TYPE_COUNT
+ && info->types.builtins[indx] != DEBUG_TYPE_NULL)
+ return info->types.builtins[indx];
+
+ dhandle = info->dhandle;
+
+ if (indx >= 32 && indx < 64)
+ {
+ type = debug_make_pointer_type (dhandle,
+ ieee_builtin_type (info, p, indx - 32));
+ assert (indx < BUILTIN_TYPE_COUNT);
+ info->types.builtins[indx] = type;
+ return type;
+ }
+
+ switch ((enum builtin_types) indx)
+ {
+ default:
+ ieee_error (info, p, "unknown builtin type");
+ return NULL;
+
+ case builtin_unknown:
+ type = debug_make_void_type (dhandle);
+ name = NULL;
+ break;
+
+ case builtin_void:
+ type = debug_make_void_type (dhandle);
+ name = "void";
+ break;
+
+ case builtin_signed_char:
+ type = debug_make_int_type (dhandle, 1, false);
+ name = "signed char";
+ break;
+
+ case builtin_unsigned_char:
+ type = debug_make_int_type (dhandle, 1, true);
+ name = "unsigned char";
+ break;
+
+ case builtin_signed_short_int:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "signed short int";
+ break;
+
+ case builtin_unsigned_short_int:
+ type = debug_make_int_type (dhandle, 2, true);
+ name = "unsigned short int";
+ break;
+
+ case builtin_signed_long:
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "signed long";
+ break;
+
+ case builtin_unsigned_long:
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned long";
+ break;
+
+ case builtin_signed_long_long:
+ type = debug_make_int_type (dhandle, 8, false);
+ name = "signed long long";
+ break;
+
+ case builtin_unsigned_long_long:
+ type = debug_make_int_type (dhandle, 8, true);
+ name = "unsigned long long";
+ break;
+
+ case builtin_float:
+ type = debug_make_float_type (dhandle, 4);
+ name = "float";
+ break;
+
+ case builtin_double:
+ type = debug_make_float_type (dhandle, 8);
+ name = "double";
+ break;
+
+ case builtin_long_double:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_float_type (dhandle, 12);
+ name = "long double";
+ break;
+
+ case builtin_long_long_double:
+ type = debug_make_float_type (dhandle, 16);
+ name = "long long double";
+ break;
+
+ case builtin_quoted_string:
+ type = debug_make_array_type (dhandle,
+ ieee_builtin_type (info, p,
+ ((unsigned int)
+ builtin_char)),
+ ieee_builtin_type (info, p,
+ ((unsigned int)
+ builtin_int)),
+ 0, -1, true);
+ name = "QUOTED STRING";
+ break;
+
+ case builtin_instruction_address:
+ /* FIXME: This should be a code address. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "instruction address";
+ break;
+
+ case builtin_int:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "int";
+ break;
+
+ case builtin_unsigned:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned";
+ break;
+
+ case builtin_unsigned_int:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned int";
+ break;
+
+ case builtin_char:
+ type = debug_make_int_type (dhandle, 1, false);
+ name = "char";
+ break;
+
+ case builtin_long:
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "long";
+ break;
+
+ case builtin_short:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "short";
+ break;
+
+ case builtin_unsigned_short:
+ type = debug_make_int_type (dhandle, 2, true);
+ name = "unsigned short";
+ break;
+
+ case builtin_short_int:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "short int";
+ break;
+
+ case builtin_signed_short:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "signed short";
+ break;
+
+ case builtin_bcd_float:
+ ieee_error (info, p, "BCD float type not supported");
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (name != NULL)
+ type = debug_name_type (dhandle, name, type);
+
+ assert (indx < BUILTIN_TYPE_COUNT);
+
+ info->types.builtins[indx] = type;
+
+ return type;
+}
+
+/* Allocate more space in the type table. If ref is true, this is a
+ reference to the type; if it is not already defined, we should set
+ up an indirect type. */
+
+static boolean
+ieee_alloc_type (info, indx, ref)
+ struct ieee_info *info;
+ unsigned int indx;
+ boolean ref;
+{
+ unsigned int nalloc;
+ register struct ieee_type *t;
+ struct ieee_type *tend;
+
+ if (indx >= info->types.alloc)
+ {
+ nalloc = info->types.alloc;
+ if (nalloc == 0)
+ nalloc = 4;
+ while (indx >= nalloc)
+ nalloc *= 2;
+
+ info->types.types = ((struct ieee_type *)
+ xrealloc (info->types.types,
+ nalloc * sizeof *info->types.types));
+
+ memset (info->types.types + info->types.alloc, 0,
+ (nalloc - info->types.alloc) * sizeof *info->types.types);
+
+ tend = info->types.types + nalloc;
+ for (t = info->types.types + info->types.alloc; t < tend; t++)
+ t->type = DEBUG_TYPE_NULL;
+
+ info->types.alloc = nalloc;
+ }
+
+ if (ref)
+ {
+ t = info->types.types + indx;
+ if (t->type == NULL)
+ {
+ t->pslot = (debug_type *) xmalloc (sizeof *t->pslot);
+ *t->pslot = DEBUG_TYPE_NULL;
+ t->type = debug_make_indirect_type (info->dhandle, t->pslot,
+ (const char *) NULL);
+ if (t->type == NULL)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Read a type index and return the corresponding type. */
+
+static boolean
+ieee_read_type_index (info, pp, ptype)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ debug_type *ptype;
+{
+ const bfd_byte *start;
+ bfd_vma indx;
+
+ start = *pp;
+
+ if (! ieee_read_number (info, pp, &indx))
+ return false;
+
+ if (indx < 256)
+ {
+ *ptype = ieee_builtin_type (info, start, indx);
+ if (*ptype == NULL)
+ return false;
+ return true;
+ }
+
+ indx -= 256;
+ if (! ieee_alloc_type (info, indx, true))
+ return false;
+
+ *ptype = info->types.types[indx].type;
+
+ return true;
+}
+
+/* Parse IEEE debugging information for a file. This is passed the
+ bytes which compose the Debug Information Part of an IEEE file. */
+
+boolean
+parse_ieee (dhandle, abfd, bytes, len)
+ PTR dhandle;
+ bfd *abfd;
+ const bfd_byte *bytes;
+ bfd_size_type len;
+{
+ struct ieee_info info;
+ unsigned int i;
+ const bfd_byte *p, *pend;
+
+ info.dhandle = dhandle;
+ info.abfd = abfd;
+ info.bytes = bytes;
+ info.pend = bytes + len;
+ info.blockstack.bsp = info.blockstack.stack;
+ info.saw_filename = false;
+ info.vars.alloc = 0;
+ info.vars.vars = NULL;
+ info.types.alloc = 0;
+ info.types.types = NULL;
+ info.tags = NULL;
+ for (i = 0; i < BUILTIN_TYPE_COUNT; i++)
+ info.types.builtins[i] = DEBUG_TYPE_NULL;
+
+ p = bytes;
+ pend = info.pend;
+ while (p < pend)
+ {
+ const bfd_byte *record_start;
+ ieee_record_enum_type c;
+
+ record_start = p;
+
+ c = (ieee_record_enum_type) *p++;
+
+ if (c == ieee_at_record_enum)
+ c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++);
+
+ if (c <= ieee_number_repeat_end_enum)
+ {
+ ieee_error (&info, record_start, "unexpected number");
+ return false;
+ }
+
+ switch (c)
+ {
+ default:
+ ieee_error (&info, record_start, "unexpected record type");
+ return false;
+
+ case ieee_bb_record_enum:
+ if (! parse_ieee_bb (&info, &p))
+ return false;
+ break;
+
+ case ieee_be_record_enum:
+ if (! parse_ieee_be (&info, &p))
+ return false;
+ break;
+
+ case ieee_nn_record:
+ if (! parse_ieee_nn (&info, &p))
+ return false;
+ break;
+
+ case ieee_ty_record_enum:
+ if (! parse_ieee_ty (&info, &p))
+ return false;
+ break;
+
+ case ieee_atn_record_enum:
+ if (! parse_ieee_atn (&info, &p))
+ return false;
+ break;
+ }
+ }
+
+ if (info.blockstack.bsp != info.blockstack.stack)
+ {
+ ieee_error (&info, (const bfd_byte *) NULL,
+ "blocks left on stack at end");
+ return false;
+ }
+
+ return true;
+}
+
+/* Handle an IEEE BB record. */
+
+static boolean
+parse_ieee_bb (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *block_start;
+ bfd_byte b;
+ bfd_vma size;
+ const char *name;
+ unsigned long namlen;
+ char *namcopy = NULL;
+ unsigned int fnindx;
+ boolean skip;
+
+ block_start = *pp;
+
+ b = **pp;
+ ++*pp;
+
+ if (! ieee_read_number (info, pp, &size)
+ || ! ieee_read_id (info, pp, &name, &namlen))
+ return false;
+
+ fnindx = (unsigned int) -1;
+ skip = false;
+
+ switch (b)
+ {
+ case 1:
+ /* BB1: Type definitions local to a module. */
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_set_filename (info->dhandle, namcopy))
+ return false;
+ info->saw_filename = true;
+
+ /* Discard any variables or types we may have seen before. */
+ if (info->vars.vars != NULL)
+ free (info->vars.vars);
+ info->vars.vars = NULL;
+ info->vars.alloc = 0;
+ if (info->types.types != NULL)
+ free (info->types.types);
+ info->types.types = NULL;
+ info->types.alloc = 0;
+
+ /* Initialize the types to the global types. */
+ if (info->global_types != NULL)
+ {
+ info->types.alloc = info->global_types->alloc;
+ info->types.types = ((struct ieee_type *)
+ xmalloc (info->types.alloc
+ * sizeof (*info->types.types)));
+ memcpy (info->types.types, info->global_types->types,
+ info->types.alloc * sizeof (*info->types.types));
+ }
+
+ break;
+
+ case 2:
+ /* BB2: Global type definitions. The name is supposed to be
+ empty, but we don't check. */
+ if (! debug_set_filename (info->dhandle, "*global*"))
+ return false;
+ info->saw_filename = true;
+ break;
+
+ case 3:
+ /* BB3: High level module block begin. We don't have to do
+ anything here. The name is supposed to be the same as for
+ the BB1, but we don't check. */
+ break;
+
+ case 4:
+ /* BB4: Global function. */
+ {
+ bfd_vma stackspace, typindx, offset;
+ debug_type return_type;
+
+ if (! ieee_read_number (info, pp, &stackspace)
+ || ! ieee_read_number (info, pp, &typindx)
+ || ! ieee_read_expression (info, pp, &offset))
+ return false;
+
+ /* We have no way to record the stack space. FIXME. */
+
+ if (typindx < 256)
+ {
+ return_type = ieee_builtin_type (info, block_start, typindx);
+ if (return_type == DEBUG_TYPE_NULL)
+ return false;
+ }
+ else
+ {
+ typindx -= 256;
+ if (! ieee_alloc_type (info, typindx, true))
+ return false;
+ fnindx = typindx;
+ return_type = info->types.types[typindx].type;
+ if (debug_get_type_kind (info->dhandle, return_type)
+ == DEBUG_KIND_FUNCTION)
+ return_type = debug_get_return_type (info->dhandle,
+ return_type);
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_record_function (info->dhandle, namcopy, return_type,
+ true, offset))
+ return false;
+ }
+ break;
+
+ case 5:
+ /* BB5: File name for source line numbers. */
+ {
+ unsigned int i;
+
+ /* We ignore the date and time. FIXME. */
+ for (i = 0; i < 6; i++)
+ {
+ bfd_vma ignore;
+ boolean present;
+
+ if (! ieee_read_optional_number (info, pp, &ignore, &present))
+ return false;
+ if (! present)
+ break;
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_start_source (info->dhandle, namcopy))
+ return false;
+ }
+ break;
+
+ case 6:
+ /* BB6: Local function or block. */
+ {
+ bfd_vma stackspace, typindx, offset;
+
+ if (! ieee_read_number (info, pp, &stackspace)
+ || ! ieee_read_number (info, pp, &typindx)
+ || ! ieee_read_expression (info, pp, &offset))
+ return false;
+
+ /* We have no way to record the stack space. FIXME. */
+
+ if (namlen == 0)
+ {
+ if (! debug_start_block (info->dhandle, offset))
+ return false;
+ /* Change b to indicate that this is a block
+ rather than a function. */
+ b = 0x86;
+ }
+ else
+ {
+ /* The MRI C++ compiler will output a fake function named
+ __XRYCPP to hold C++ debugging information. We skip
+ that function. This is not crucial, but it makes
+ converting from IEEE to other debug formats work
+ better. */
+ if (strncmp (name, "__XRYCPP", namlen) == 0)
+ skip = true;
+ else
+ {
+ debug_type return_type;
+
+ if (typindx < 256)
+ {
+ return_type = ieee_builtin_type (info, block_start,
+ typindx);
+ if (return_type == NULL)
+ return false;
+ }
+ else
+ {
+ typindx -= 256;
+ if (! ieee_alloc_type (info, typindx, true))
+ return false;
+ fnindx = typindx;
+ return_type = info->types.types[typindx].type;
+ if (debug_get_type_kind (info->dhandle, return_type)
+ == DEBUG_KIND_FUNCTION)
+ return_type = debug_get_return_type (info->dhandle,
+ return_type);
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_record_function (info->dhandle, namcopy,
+ return_type, false, offset))
+ return false;
+ }
+ }
+ }
+ break;
+
+ case 10:
+ /* BB10: Assembler module scope. In the normal case, we
+ completely ignore all this information. FIXME. */
+ {
+ const char *inam, *vstr;
+ unsigned long inamlen, vstrlen;
+ bfd_vma tool_type;
+ boolean present;
+ unsigned int i;
+
+ if (! info->saw_filename)
+ {
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_set_filename (info->dhandle, namcopy))
+ return false;
+ info->saw_filename = true;
+ }
+
+ if (! ieee_read_id (info, pp, &inam, &inamlen)
+ || ! ieee_read_number (info, pp, &tool_type)
+ || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present))
+ return false;
+ for (i = 0; i < 6; i++)
+ {
+ bfd_vma ignore;
+
+ if (! ieee_read_optional_number (info, pp, &ignore, &present))
+ return false;
+ if (! present)
+ break;
+ }
+ }
+ break;
+
+ case 11:
+ /* BB11: Module section. We completely ignore all this
+ information. FIXME. */
+ {
+ bfd_vma sectype, secindx, offset, map;
+ boolean present;
+
+ if (! ieee_read_number (info, pp, &sectype)
+ || ! ieee_read_number (info, pp, &secindx)
+ || ! ieee_read_expression (info, pp, &offset)
+ || ! ieee_read_optional_number (info, pp, &map, &present))
+ return false;
+ }
+ break;
+
+ default:
+ ieee_error (info, block_start, "unknown BB type");
+ return false;
+ }
+
+
+ /* Push this block on the block stack. */
+
+ if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE)
+ {
+ ieee_error (info, (const bfd_byte *) NULL, "stack overflow");
+ return false;
+ }
+
+ info->blockstack.bsp->kind = b;
+ if (b == 5)
+ info->blockstack.bsp->filename = namcopy;
+ info->blockstack.bsp->fnindx = fnindx;
+ info->blockstack.bsp->skip = skip;
+ ++info->blockstack.bsp;
+
+ return true;
+}
+
+/* Handle an IEEE BE record. */
+
+static boolean
+parse_ieee_be (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ bfd_vma offset;
+
+ if (info->blockstack.bsp <= info->blockstack.stack)
+ {
+ ieee_error (info, *pp, "stack underflow");
+ return false;
+ }
+ --info->blockstack.bsp;
+
+ switch (info->blockstack.bsp->kind)
+ {
+ case 2:
+ /* When we end the global typedefs block, we copy out the the
+ contents of info->vars. This is because the variable indices
+ may be reused in the local blocks. However, we need to
+ preserve them so that we can locate a function returning a
+ reference variable whose type is named in the global typedef
+ block. */
+ info->global_vars = ((struct ieee_vars *)
+ xmalloc (sizeof *info->global_vars));
+ info->global_vars->alloc = info->vars.alloc;
+ info->global_vars->vars = ((struct ieee_var *)
+ xmalloc (info->vars.alloc
+ * sizeof (*info->vars.vars)));
+ memcpy (info->global_vars->vars, info->vars.vars,
+ info->vars.alloc * sizeof (*info->vars.vars));
+
+ /* We also copy out the non builtin parts of info->types, since
+ the types are discarded when we start a new block. */
+ info->global_types = ((struct ieee_types *)
+ xmalloc (sizeof *info->global_types));
+ info->global_types->alloc = info->types.alloc;
+ info->global_types->types = ((struct ieee_type *)
+ xmalloc (info->types.alloc
+ * sizeof (*info->types.types)));
+ memcpy (info->global_types->types, info->types.types,
+ info->types.alloc * sizeof (*info->types.types));
+ memset (info->global_types->builtins, 0,
+ sizeof (info->global_types->builtins));
+
+ break;
+
+ case 4:
+ case 6:
+ if (! ieee_read_expression (info, pp, &offset))
+ return false;
+ if (! info->blockstack.bsp->skip)
+ {
+ if (! debug_end_function (info->dhandle, offset + 1))
+ return false;
+ }
+ break;
+
+ case 0x86:
+ /* This is BE6 when BB6 started a block rather than a local
+ function. */
+ if (! ieee_read_expression (info, pp, &offset))
+ return false;
+ if (! debug_end_block (info->dhandle, offset + 1))
+ return false;
+ break;
+
+ case 5:
+ /* When we end a BB5, we look up the stack for the last BB5, if
+ there is one, so that we can call debug_start_source. */
+ if (info->blockstack.bsp > info->blockstack.stack)
+ {
+ struct ieee_block *bl;
+
+ bl = info->blockstack.bsp;
+ do
+ {
+ --bl;
+ if (bl->kind == 5)
+ {
+ if (! debug_start_source (info->dhandle, bl->filename))
+ return false;
+ break;
+ }
+ }
+ while (bl != info->blockstack.stack);
+ }
+ break;
+
+ case 11:
+ if (! ieee_read_expression (info, pp, &offset))
+ return false;
+ /* We just ignore the module size. FIXME. */
+ break;
+
+ default:
+ /* Other block types do not have any trailing information. */
+ break;
+ }
+
+ return true;
+}
+
+/* Parse an NN record. */
+
+static boolean
+parse_ieee_nn (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *nn_start;
+ bfd_vma varindx;
+ const char *name;
+ unsigned long namlen;
+
+ nn_start = *pp;
+
+ if (! ieee_read_number (info, pp, &varindx)
+ || ! ieee_read_id (info, pp, &name, &namlen))
+ return false;
+
+ if (varindx < 32)
+ {
+ ieee_error (info, nn_start, "illegal variable index");
+ return false;
+ }
+ varindx -= 32;
+
+ if (varindx >= info->vars.alloc)
+ {
+ unsigned int alloc;
+
+ alloc = info->vars.alloc;
+ if (alloc == 0)
+ alloc = 4;
+ while (varindx >= alloc)
+ alloc *= 2;
+ info->vars.vars = ((struct ieee_var *)
+ xrealloc (info->vars.vars,
+ alloc * sizeof *info->vars.vars));
+ memset (info->vars.vars + info->vars.alloc, 0,
+ (alloc - info->vars.alloc) * sizeof *info->vars.vars);
+ info->vars.alloc = alloc;
+ }
+
+ info->vars.vars[varindx].name = name;
+ info->vars.vars[varindx].namlen = namlen;
+
+ return true;
+}
+
+/* Parse a TY record. */
+
+static boolean
+parse_ieee_ty (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *ty_start, *ty_var_start, *ty_code_start;
+ bfd_vma typeindx, varindx, tc;
+ PTR dhandle;
+ boolean tag, typdef;
+ debug_type *arg_slots;
+ unsigned long type_bitsize;
+ debug_type type;
+
+ ty_start = *pp;
+
+ if (! ieee_read_number (info, pp, &typeindx))
+ return false;
+
+ if (typeindx < 256)
+ {
+ ieee_error (info, ty_start, "illegal type index");
+ return false;
+ }
+
+ typeindx -= 256;
+ if (! ieee_alloc_type (info, typeindx, false))
+ return false;
+
+ if (**pp != 0xce)
+ {
+ ieee_error (info, *pp, "unknown TY code");
+ return false;
+ }
+ ++*pp;
+
+ ty_var_start = *pp;
+
+ if (! ieee_read_number (info, pp, &varindx))
+ return false;
+
+ if (varindx < 32)
+ {
+ ieee_error (info, ty_var_start, "illegal variable index");
+ return false;
+ }
+ varindx -= 32;
+
+ if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL)
+ {
+ ieee_error (info, ty_var_start, "undefined variable in TY");
+ return false;
+ }
+
+ ty_code_start = *pp;
+
+ if (! ieee_read_number (info, pp, &tc))
+ return false;
+
+ dhandle = info->dhandle;
+
+ tag = false;
+ typdef = false;
+ arg_slots = NULL;
+ type_bitsize = 0;
+ switch (tc)
+ {
+ default:
+ ieee_error (info, ty_code_start, "unknown TY code");
+ return false;
+
+ case '!':
+ /* Unknown type, with size. We treat it as int. FIXME. */
+ {
+ bfd_vma size;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+ type = debug_make_int_type (dhandle, size, false);
+ }
+ break;
+
+ case 'A': /* Array. */
+ case 'a': /* FORTRAN array in column/row order. FIXME: Not
+ distinguished from normal array. */
+ {
+ debug_type ele_type;
+ bfd_vma lower, upper;
+
+ if (! ieee_read_type_index (info, pp, &ele_type)
+ || ! ieee_read_number (info, pp, &lower)
+ || ! ieee_read_number (info, pp, &upper))
+ return false;
+ type = debug_make_array_type (dhandle, ele_type,
+ ieee_builtin_type (info, ty_code_start,
+ ((unsigned int)
+ builtin_int)),
+ (bfd_signed_vma) lower,
+ (bfd_signed_vma) upper,
+ false);
+ }
+ break;
+
+ case 'E':
+ /* Simple enumeration. */
+ {
+ bfd_vma size;
+ unsigned int alloc;
+ const char **names;
+ unsigned int c;
+ bfd_signed_vma *vals;
+ unsigned int i;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+ /* FIXME: we ignore the enumeration size. */
+
+ alloc = 10;
+ names = (const char **) xmalloc (alloc * sizeof *names);
+ memset (names, 0, alloc * sizeof *names);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ names = ((const char **)
+ xrealloc (names, alloc * sizeof *names));
+ }
+
+ names[c] = savestring (name, namlen);
+ if (names[c] == NULL)
+ return false;
+ ++c;
+ }
+
+ names[c] = NULL;
+
+ vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals);
+ for (i = 0; i < c; i++)
+ vals[i] = i;
+
+ type = debug_make_enum_type (dhandle, names, vals);
+ tag = true;
+ }
+ break;
+
+ case 'G':
+ /* Struct with bit fields. */
+ {
+ bfd_vma size;
+ unsigned int alloc;
+ debug_field *fields;
+ unsigned int c;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+
+ alloc = 10;
+ fields = (debug_field *) xmalloc (alloc * sizeof *fields);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+ debug_type ftype;
+ bfd_vma bitpos, bitsize;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_type_index (info, pp, &ftype)
+ || ! ieee_read_number (info, pp, &bitpos)
+ || ! ieee_read_number (info, pp, &bitsize))
+ return false;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ fields = ((debug_field *)
+ xrealloc (fields, alloc * sizeof *fields));
+ }
+
+ fields[c] = debug_make_field (dhandle, savestring (name, namlen),
+ ftype, bitpos, bitsize,
+ DEBUG_VISIBILITY_PUBLIC);
+ if (fields[c] == NULL)
+ return false;
+ ++c;
+ }
+
+ fields[c] = NULL;
+
+ type = debug_make_struct_type (dhandle, true, size, fields);
+ tag = true;
+ }
+ break;
+
+ case 'N':
+ /* Enumeration. */
+ {
+ unsigned int alloc;
+ const char **names;
+ bfd_signed_vma *vals;
+ unsigned int c;
+
+ alloc = 10;
+ names = (const char **) xmalloc (alloc * sizeof *names);
+ vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+ bfd_vma val;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_number (info, pp, &val))
+ return false;
+
+ /* If the length of the name is zero, then the value is
+ actually the size of the enum. We ignore this
+ information. FIXME. */
+ if (namlen == 0)
+ continue;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ names = ((const char **)
+ xrealloc (names, alloc * sizeof *names));
+ vals = ((bfd_signed_vma *)
+ xrealloc (vals, alloc * sizeof *vals));
+ }
+
+ names[c] = savestring (name, namlen);
+ if (names[c] == NULL)
+ return false;
+ vals[c] = (bfd_signed_vma) val;
+ ++c;
+ }
+
+ names[c] = NULL;
+
+ type = debug_make_enum_type (dhandle, names, vals);
+ tag = true;
+ }
+ break;
+
+ case 'O': /* Small pointer. We don't distinguish small and large
+ pointers. FIXME. */
+ case 'P': /* Large pointer. */
+ {
+ debug_type t;
+
+ if (! ieee_read_type_index (info, pp, &t))
+ return false;
+ type = debug_make_pointer_type (dhandle, t);
+ }
+ break;
+
+ case 'R':
+ /* Range. */
+ {
+ bfd_vma low, high, signedp, size;
+
+ if (! ieee_read_number (info, pp, &low)
+ || ! ieee_read_number (info, pp, &high)
+ || ! ieee_read_number (info, pp, &signedp)
+ || ! ieee_read_number (info, pp, &size))
+ return false;
+
+ type = debug_make_range_type (dhandle,
+ debug_make_int_type (dhandle, size,
+ ! signedp),
+ (bfd_signed_vma) low,
+ (bfd_signed_vma) high);
+ }
+ break;
+
+ case 'S': /* Struct. */
+ case 'U': /* Union. */
+ {
+ bfd_vma size;
+ unsigned int alloc;
+ debug_field *fields;
+ unsigned int c;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+
+ alloc = 10;
+ fields = (debug_field *) xmalloc (alloc * sizeof *fields);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+ bfd_vma tindx;
+ bfd_vma offset;
+ debug_type ftype;
+ bfd_vma bitsize;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_number (info, pp, &tindx)
+ || ! ieee_read_number (info, pp, &offset))
+ return false;
+
+ if (tindx < 256)
+ {
+ ftype = ieee_builtin_type (info, ty_code_start, tindx);
+ bitsize = 0;
+ offset *= 8;
+ }
+ else
+ {
+ struct ieee_type *t;
+
+ tindx -= 256;
+ if (! ieee_alloc_type (info, tindx, true))
+ return false;
+ t = info->types.types + tindx;
+ ftype = t->type;
+ bitsize = t->bitsize;
+ if (bitsize == 0)
+ offset *= 8;
+ }
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ fields = ((debug_field *)
+ xrealloc (fields, alloc * sizeof *fields));
+ }
+
+ fields[c] = debug_make_field (dhandle, savestring (name, namlen),
+ ftype, offset, bitsize,
+ DEBUG_VISIBILITY_PUBLIC);
+ if (fields[c] == NULL)
+ return false;
+ ++c;
+ }
+
+ fields[c] = NULL;
+
+ type = debug_make_struct_type (dhandle, tc == 'S', size, fields);
+ tag = true;
+ }
+ break;
+
+ case 'T':
+ /* Typedef. */
+ if (! ieee_read_type_index (info, pp, &type))
+ return false;
+ typdef = true;
+ break;
+
+ case 'X':
+ /* Procedure. FIXME: This is an extern declaration, which we
+ have no way of representing. */
+ {
+ bfd_vma attr;
+ debug_type rtype;
+ bfd_vma nargs;
+ boolean present;
+ struct ieee_var *pv;
+
+ /* FIXME: We ignore the attribute and the argument names. */
+
+ if (! ieee_read_number (info, pp, &attr)
+ || ! ieee_read_type_index (info, pp, &rtype)
+ || ! ieee_read_number (info, pp, &nargs))
+ return false;
+ do
+ {
+ const char *name;
+ unsigned long namlen;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ }
+ while (present);
+
+ pv = info->vars.vars + varindx;
+ pv->kind = IEEE_EXTERNAL;
+ if (pv->namlen > 0
+ && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
+ {
+ /* Set up the return type as an indirect type pointing to
+ the variable slot, so that we can change it to a
+ reference later if appropriate. */
+ pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
+ *pv->pslot = rtype;
+ rtype = debug_make_indirect_type (dhandle, pv->pslot,
+ (const char *) NULL);
+ }
+
+ type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
+ false);
+ }
+ break;
+
+ case 'V':
+ /* Void. This is not documented, but the MRI compiler emits it. */
+ type = debug_make_void_type (dhandle);
+ break;
+
+ case 'Z':
+ /* Array with 0 lower bound. */
+ {
+ debug_type etype;
+ bfd_vma high;
+
+ if (! ieee_read_type_index (info, pp, &etype)
+ || ! ieee_read_number (info, pp, &high))
+ return false;
+
+ type = debug_make_array_type (dhandle, etype,
+ ieee_builtin_type (info, ty_code_start,
+ ((unsigned int)
+ builtin_int)),
+ 0, (bfd_signed_vma) high, false);
+ }
+ break;
+
+ case 'c': /* Complex. */
+ case 'd': /* Double complex. */
+ {
+ const char *name;
+ unsigned long namlen;
+
+ /* FIXME: I don't know what the name means. */
+
+ if (! ieee_read_id (info, pp, &name, &namlen))
+ return false;
+
+ type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8);
+ }
+ break;
+
+ case 'f':
+ /* Pascal file name. FIXME. */
+ ieee_error (info, ty_code_start, "Pascal file name not supported");
+ return false;
+
+ case 'g':
+ /* Bitfield type. */
+ {
+ bfd_vma signedp, bitsize, dummy;
+ const bfd_byte *hold;
+ boolean present;
+
+ if (! ieee_read_number (info, pp, &signedp)
+ || ! ieee_read_number (info, pp, &bitsize))
+ return false;
+
+ /* I think the documentation says that there is a type index,
+ but some actual files do not have one. */
+ hold = *pp;
+ if (! ieee_read_optional_number (info, pp, &dummy, &present))
+ return false;
+ if (! present)
+ {
+ /* FIXME: This is just a guess. */
+ type = debug_make_int_type (dhandle, 4,
+ signedp ? false : true);
+ }
+ else
+ {
+ *pp = hold;
+ if (! ieee_read_type_index (info, pp, &type))
+ return false;
+ }
+ type_bitsize = bitsize;
+ }
+ break;
+
+ case 'n':
+ /* Qualifier. */
+ {
+ bfd_vma kind;
+ debug_type t;
+
+ if (! ieee_read_number (info, pp, &kind)
+ || ! ieee_read_type_index (info, pp, &t))
+ return false;
+
+ switch (kind)
+ {
+ default:
+ ieee_error (info, ty_start, "unsupported qualifer");
+ return false;
+
+ case 1:
+ type = debug_make_const_type (dhandle, t);
+ break;
+
+ case 2:
+ type = debug_make_volatile_type (dhandle, t);
+ break;
+ }
+ }
+ break;
+
+ case 's':
+ /* Set. */
+ {
+ bfd_vma size;
+ debug_type etype;
+
+ if (! ieee_read_number (info, pp, &size)
+ || ! ieee_read_type_index (info, pp, &etype))
+ return false;
+
+ /* FIXME: We ignore the size. */
+
+ type = debug_make_set_type (dhandle, etype, false);
+ }
+ break;
+
+ case 'x':
+ /* Procedure with compiler dependencies. */
+ {
+ struct ieee_var *pv;
+ bfd_vma attr, frame_type, push_mask, nargs, level, father;
+ debug_type rtype;
+ debug_type *arg_types;
+ boolean varargs;
+ boolean present;
+
+ /* FIXME: We ignore some of this information. */
+
+ pv = info->vars.vars + varindx;
+
+ if (! ieee_read_number (info, pp, &attr)
+ || ! ieee_read_number (info, pp, &frame_type)
+ || ! ieee_read_number (info, pp, &push_mask)
+ || ! ieee_read_type_index (info, pp, &rtype)
+ || ! ieee_read_number (info, pp, &nargs))
+ return false;
+ if (nargs == (bfd_vma) -1)
+ {
+ arg_types = NULL;
+ varargs = false;
+ }
+ else
+ {
+ unsigned int i;
+
+ arg_types = ((debug_type *)
+ xmalloc ((nargs + 1) * sizeof *arg_types));
+ for (i = 0; i < nargs; i++)
+ if (! ieee_read_type_index (info, pp, arg_types + i))
+ return false;
+
+ /* If the last type is pointer to void, this is really a
+ varargs function. */
+ varargs = false;
+ if (nargs > 0)
+ {
+ debug_type last;
+
+ last = arg_types[nargs - 1];
+ if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER
+ && (debug_get_type_kind (dhandle,
+ debug_get_target_type (dhandle,
+ last))
+ == DEBUG_KIND_VOID))
+ {
+ --nargs;
+ varargs = true;
+ }
+ }
+
+ /* If there are any pointer arguments, turn them into
+ indirect types in case we later need to convert them to
+ reference types. */
+ for (i = 0; i < nargs; i++)
+ {
+ if (debug_get_type_kind (dhandle, arg_types[i])
+ == DEBUG_KIND_POINTER)
+ {
+ if (arg_slots == NULL)
+ {
+ arg_slots = ((debug_type *)
+ xmalloc (nargs * sizeof *arg_slots));
+ memset (arg_slots, 0, nargs * sizeof *arg_slots);
+ }
+ arg_slots[i] = arg_types[i];
+ arg_types[i] =
+ debug_make_indirect_type (dhandle,
+ arg_slots + i,
+ (const char *) NULL);
+ }
+ }
+
+ arg_types[nargs] = DEBUG_TYPE_NULL;
+ }
+ if (! ieee_read_number (info, pp, &level)
+ || ! ieee_read_optional_number (info, pp, &father, &present))
+ return false;
+
+ /* We can't distinguish between a global function and a static
+ function. */
+ pv->kind = IEEE_FUNCTION;
+
+ if (pv->namlen > 0
+ && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
+ {
+ /* Set up the return type as an indirect type pointing to
+ the variable slot, so that we can change it to a
+ reference later if appropriate. */
+ pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
+ *pv->pslot = rtype;
+ rtype = debug_make_indirect_type (dhandle, pv->pslot,
+ (const char *) NULL);
+ }
+
+ type = debug_make_function_type (dhandle, rtype, arg_types, varargs);
+ }
+ break;
+ }
+
+ /* Record the type in the table. */
+
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ info->vars.vars[varindx].type = type;
+
+ if ((tag || typdef)
+ && info->vars.vars[varindx].namlen > 0)
+ {
+ const char *name;
+
+ name = savestring (info->vars.vars[varindx].name,
+ info->vars.vars[varindx].namlen);
+ if (typdef)
+ type = debug_name_type (dhandle, name, type);
+ else if (tc == 'E' || tc == 'N')
+ type = debug_tag_type (dhandle, name, type);
+ else
+ {
+ struct ieee_tag *it;
+
+ /* We must allocate all struct tags as indirect types, so
+ that if we later see a definition of the tag as a C++
+ record we can update the indirect slot and automatically
+ change all the existing references. */
+ it = (struct ieee_tag *) xmalloc (sizeof *it);
+ memset (it, 0, sizeof *it);
+ it->next = info->tags;
+ info->tags = it;
+ it->name = name;
+ it->slot = type;
+
+ type = debug_make_indirect_type (dhandle, &it->slot, name);
+ type = debug_tag_type (dhandle, name, type);
+
+ it->type = type;
+ }
+ if (type == NULL)
+ return false;
+ }
+
+ info->types.types[typeindx].type = type;
+ info->types.types[typeindx].arg_slots = arg_slots;
+ info->types.types[typeindx].bitsize = type_bitsize;
+
+ /* We may have already allocated type as an indirect type pointing
+ to slot. It does no harm to replace the indirect type with the
+ real type. Filling in slot as well handles the indirect types
+ which are already hanging around. */
+ if (info->types.types[typeindx].pslot != NULL)
+ *info->types.types[typeindx].pslot = type;
+
+ return true;
+}
+
+/* Parse an ATN record. */
+
+static boolean
+parse_ieee_atn (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *atn_start, *atn_code_start;
+ bfd_vma varindx;
+ struct ieee_var *pvar;
+ debug_type type;
+ bfd_vma atn_code;
+ PTR dhandle;
+ bfd_vma v, v2, v3, v4, v5;
+ const char *name;
+ unsigned long namlen;
+ char *namcopy;
+ boolean present;
+ int blocktype;
+
+ atn_start = *pp;
+
+ if (! ieee_read_number (info, pp, &varindx)
+ || ! ieee_read_type_index (info, pp, &type))
+ return false;
+
+ atn_code_start = *pp;
+
+ if (! ieee_read_number (info, pp, &atn_code))
+ return false;
+
+ if (varindx == 0)
+ {
+ pvar = NULL;
+ name = "";
+ namlen = 0;
+ }
+ else if (varindx < 32)
+ {
+ ieee_error (info, atn_start, "illegal variable index");
+ return false;
+ }
+ else
+ {
+ varindx -= 32;
+ if (varindx >= info->vars.alloc
+ || info->vars.vars[varindx].name == NULL)
+ {
+ /* The MRI compiler or linker sometimes omits the NN record
+ for a pmisc record. */
+ if (atn_code == 62)
+ {
+ if (varindx >= info->vars.alloc)
+ {
+ unsigned int alloc;
+
+ alloc = info->vars.alloc;
+ if (alloc == 0)
+ alloc = 4;
+ while (varindx >= alloc)
+ alloc *= 2;
+ info->vars.vars = ((struct ieee_var *)
+ xrealloc (info->vars.vars,
+ (alloc
+ * sizeof *info->vars.vars)));
+ memset (info->vars.vars + info->vars.alloc, 0,
+ ((alloc - info->vars.alloc)
+ * sizeof *info->vars.vars));
+ info->vars.alloc = alloc;
+ }
+
+ pvar = info->vars.vars + varindx;
+ pvar->name = "";
+ pvar->namlen = 0;
+ }
+ else
+ {
+ ieee_error (info, atn_start, "undefined variable in ATN");
+ return false;
+ }
+ }
+
+ pvar = info->vars.vars + varindx;
+
+ pvar->type = type;
+
+ name = pvar->name;
+ namlen = pvar->namlen;
+ }
+
+ dhandle = info->dhandle;
+
+ /* If we are going to call debug_record_variable with a pointer
+ type, change the type to an indirect type so that we can later
+ change it to a reference type if we encounter a C++ pmisc 'R'
+ record. */
+ if (pvar != NULL
+ && type != DEBUG_TYPE_NULL
+ && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER)
+ {
+ switch (atn_code)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 5:
+ case 8:
+ case 10:
+ pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot);
+ *pvar->pslot = type;
+ type = debug_make_indirect_type (dhandle, pvar->pslot,
+ (const char *) NULL);
+ pvar->type = type;
+ break;
+ }
+ }
+
+ switch (atn_code)
+ {
+ default:
+ ieee_error (info, atn_code_start, "unknown ATN type");
+ return false;
+
+ case 1:
+ /* Automatic variable. */
+ if (! ieee_read_number (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_LOCAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v);
+
+ case 2:
+ /* Register variable. */
+ if (! ieee_read_number (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_LOCAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER,
+ ieee_regno_to_genreg (info->abfd, v));
+
+ case 3:
+ /* Static variable. */
+ if (! ieee_require_asn (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (info->blockstack.bsp <= info->blockstack.stack)
+ blocktype = 0;
+ else
+ blocktype = info->blockstack.bsp[-1].kind;
+ if (pvar != NULL)
+ {
+ if (blocktype == 4 || blocktype == 6)
+ pvar->kind = IEEE_LOCAL;
+ else
+ pvar->kind = IEEE_STATIC;
+ }
+ return debug_record_variable (dhandle, namcopy, type,
+ (blocktype == 4 || blocktype == 6
+ ? DEBUG_LOCAL_STATIC
+ : DEBUG_STATIC),
+ v);
+
+ case 4:
+ /* External function. We don't currently record these. FIXME. */
+ if (pvar != NULL)
+ pvar->kind = IEEE_EXTERNAL;
+ return true;
+
+ case 5:
+ /* External variable. We don't currently record these. FIXME. */
+ if (pvar != NULL)
+ pvar->kind = IEEE_EXTERNAL;
+ return true;
+
+ case 7:
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_number (info, pp, &v2)
+ || ! ieee_read_optional_number (info, pp, &v3, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v4, &present))
+ return false;
+ }
+
+ /* We just ignore the two optional fields in v3 and v4, since
+ they are not defined. */
+
+ if (! ieee_require_asn (info, pp, &v3))
+ return false;
+
+ /* We have no way to record the column number. FIXME. */
+
+ return debug_record_line (dhandle, v, v3);
+
+ case 8:
+ /* Global variable. */
+ if (! ieee_require_asn (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_GLOBAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v);
+
+ case 9:
+ /* Variable lifetime information. */
+ if (! ieee_read_number (info, pp, &v))
+ return false;
+
+ /* We have no way to record this information. FIXME. */
+ return true;
+
+ case 10:
+ /* Locked register. The spec says that there are two required
+ fields, but at least on occasion the MRI compiler only emits
+ one. */
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_optional_number (info, pp, &v2, &present))
+ return false;
+
+ /* I think this means a variable that is both in a register and
+ a frame slot. We ignore the frame slot. FIXME. */
+
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_LOCAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v);
+
+ case 11:
+ /* Reserved for FORTRAN common. */
+ ieee_error (info, atn_code_start, "unsupported ATN11");
+
+ /* Return true to keep going. */
+ return true;
+
+ case 12:
+ /* Based variable. */
+ v3 = 0;
+ v4 = 0x80;
+ v5 = 0;
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_number (info, pp, &v2)
+ || ! ieee_read_optional_number (info, pp, &v3, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v4, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v5, &present))
+ return false;
+ }
+ }
+
+ /* We have no way to record this information. FIXME. */
+
+ ieee_error (info, atn_code_start, "unsupported ATN12");
+
+ /* Return true to keep going. */
+ return true;
+
+ case 16:
+ /* Constant. The description of this that I have is ambiguous,
+ so I'm not going to try to implement it. */
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_optional_number (info, pp, &v2, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v2, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ }
+ }
+
+ if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum)
+ {
+ if (! ieee_require_asn (info, pp, &v3))
+ return false;
+ }
+
+ return true;
+
+ case 19:
+ /* Static variable from assembler. */
+ v2 = 0;
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_optional_number (info, pp, &v2, &present)
+ || ! ieee_require_asn (info, pp, &v3))
+ return false;
+ namcopy = savestring (name, namlen);
+ /* We don't really handle this correctly. FIXME. */
+ return debug_record_variable (dhandle, namcopy,
+ debug_make_void_type (dhandle),
+ v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC,
+ v3);
+
+ case 62:
+ /* Procedure miscellaneous information. */
+ case 63:
+ /* Variable miscellaneous information. */
+ case 64:
+ /* Module miscellaneous information. */
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_number (info, pp, &v2)
+ || ! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+
+ if (atn_code == 62 && v == 80)
+ {
+ if (present)
+ {
+ ieee_error (info, atn_code_start,
+ "unexpected string in C++ misc");
+ return false;
+ }
+ return ieee_read_cxx_misc (info, pp, v2);
+ }
+
+ /* We just ignore all of this stuff. FIXME. */
+
+ for (; v2 > 0; --v2)
+ {
+ switch ((ieee_record_enum_type) **pp)
+ {
+ default:
+ ieee_error (info, *pp, "bad misc record");
+ return false;
+
+ case ieee_at_record_enum:
+ if (! ieee_require_atn65 (info, pp, &name, &namlen))
+ return false;
+ break;
+
+ case ieee_e2_first_byte_enum:
+ if (! ieee_require_asn (info, pp, &v3))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ /*NOTREACHED*/
+}
+
+/* Handle C++ debugging miscellaneous records. This is called for
+ procedure miscellaneous records of type 80. */
+
+static boolean
+ieee_read_cxx_misc (info, pp, count)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ unsigned long count;
+{
+ const bfd_byte *start;
+ bfd_vma category;
+
+ start = *pp;
+
+ /* Get the category of C++ misc record. */
+ if (! ieee_require_asn (info, pp, &category))
+ return false;
+ --count;
+
+ switch (category)
+ {
+ default:
+ ieee_error (info, start, "unrecognized C++ misc record");
+ return false;
+
+ case 'T':
+ if (! ieee_read_cxx_class (info, pp, count))
+ return false;
+ break;
+
+ case 'M':
+ {
+ bfd_vma flags;
+ const char *name;
+ unsigned long namlen;
+
+ /* The IEEE spec indicates that the 'M' record only has a
+ flags field. The MRI compiler also emits the name of the
+ function. */
+
+ if (! ieee_require_asn (info, pp, &flags))
+ return false;
+ if (*pp < info->pend
+ && (ieee_record_enum_type) **pp == ieee_at_record_enum)
+ {
+ if (! ieee_require_atn65 (info, pp, &name, &namlen))
+ return false;
+ }
+
+ /* This is emitted for method functions, but I don't think we
+ care very much. It might help if it told us useful
+ information like the class with which this function is
+ associated, but it doesn't, so it isn't helpful. */
+ }
+ break;
+
+ case 'B':
+ if (! ieee_read_cxx_defaults (info, pp, count))
+ return false;
+ break;
+
+ case 'z':
+ {
+ const char *name, *mangled, *class;
+ unsigned long namlen, mangledlen, classlen;
+ bfd_vma control;
+
+ /* Pointer to member. */
+
+ if (! ieee_require_atn65 (info, pp, &name, &namlen)
+ || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)
+ || ! ieee_require_atn65 (info, pp, &class, &classlen)
+ || ! ieee_require_asn (info, pp, &control))
+ return false;
+
+ /* FIXME: We should now track down name and change its type. */
+ }
+ break;
+
+ case 'R':
+ if (! ieee_read_reference (info, pp))
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+/* Read a C++ class definition. This is a pmisc type 80 record of
+ category 'T'. */
+
+static boolean
+ieee_read_cxx_class (info, pp, count)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ unsigned long count;
+{
+ const bfd_byte *start;
+ bfd_vma class;
+ const char *tag;
+ unsigned long taglen;
+ struct ieee_tag *it;
+ PTR dhandle;
+ debug_field *fields;
+ unsigned int field_count, field_alloc;
+ debug_baseclass *baseclasses;
+ unsigned int baseclasses_count, baseclasses_alloc;
+ const debug_field *structfields;
+ struct ieee_method
+ {
+ const char *name;
+ unsigned long namlen;
+ debug_method_variant *variants;
+ unsigned count;
+ unsigned int alloc;
+ } *methods;
+ unsigned int methods_count, methods_alloc;
+ debug_type vptrbase;
+ boolean ownvptr;
+ debug_method *dmethods;
+
+ start = *pp;
+
+ if (! ieee_require_asn (info, pp, &class))
+ return false;
+ --count;
+
+ if (! ieee_require_atn65 (info, pp, &tag, &taglen))
+ return false;
+ --count;
+
+ /* Find the C struct with this name. */
+ for (it = info->tags; it != NULL; it = it->next)
+ if (it->name[0] == tag[0]
+ && strncmp (it->name, tag, taglen) == 0
+ && strlen (it->name) == taglen)
+ break;
+ if (it == NULL)
+ {
+ ieee_error (info, start, "undefined C++ object");
+ return false;
+ }
+
+ dhandle = info->dhandle;
+
+ fields = NULL;
+ field_count = 0;
+ field_alloc = 0;
+ baseclasses = NULL;
+ baseclasses_count = 0;
+ baseclasses_alloc = 0;
+ methods = NULL;
+ methods_count = 0;
+ methods_alloc = 0;
+ vptrbase = DEBUG_TYPE_NULL;
+ ownvptr = false;
+
+ structfields = debug_get_fields (dhandle, it->type);
+
+ while (count > 0)
+ {
+ bfd_vma id;
+ const bfd_byte *spec_start;
+
+ spec_start = *pp;
+
+ if (! ieee_require_asn (info, pp, &id))
+ return false;
+ --count;
+
+ switch (id)
+ {
+ default:
+ ieee_error (info, spec_start, "unrecognized C++ object spec");
+ return false;
+
+ case 'b':
+ {
+ bfd_vma flags, cinline;
+ const char *basename, *fieldname;
+ unsigned long baselen, fieldlen;
+ char *basecopy;
+ debug_type basetype;
+ bfd_vma bitpos;
+ boolean virtualp;
+ enum debug_visibility visibility;
+ debug_baseclass baseclass;
+
+ /* This represents a base or friend class. */
+
+ if (! ieee_require_asn (info, pp, &flags)
+ || ! ieee_require_atn65 (info, pp, &basename, &baselen)
+ || ! ieee_require_asn (info, pp, &cinline)
+ || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen))
+ return false;
+ count -= 4;
+
+ /* We have no way of recording friend information, so we
+ just ignore it. */
+ if ((flags & BASEFLAGS_FRIEND) != 0)
+ break;
+
+ /* I assume that either all of the members of the
+ baseclass are included in the object, starting at the
+ beginning of the object, or that none of them are
+ included. */
+
+ if ((fieldlen == 0) == (cinline == 0))
+ {
+ ieee_error (info, start, "unsupported C++ object type");
+ return false;
+ }
+
+ basecopy = savestring (basename, baselen);
+ basetype = debug_find_tagged_type (dhandle, basecopy,
+ DEBUG_KIND_ILLEGAL);
+ free (basecopy);
+ if (basetype == DEBUG_TYPE_NULL)
+ {
+ ieee_error (info, start, "C++ base class not defined");
+ return false;
+ }
+
+ if (fieldlen == 0)
+ bitpos = 0;
+ else
+ {
+ const debug_field *pf;
+
+ if (structfields == NULL)
+ {
+ ieee_error (info, start, "C++ object has no fields");
+ return false;
+ }
+
+ for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++)
+ {
+ const char *fname;
+
+ fname = debug_get_field_name (dhandle, *pf);
+ if (fname == NULL)
+ return false;
+ if (fname[0] == fieldname[0]
+ && strncmp (fname, fieldname, fieldlen) == 0
+ && strlen (fname) == fieldlen)
+ break;
+ }
+ if (*pf == DEBUG_FIELD_NULL)
+ {
+ ieee_error (info, start,
+ "C++ base class not found in container");
+ return false;
+ }
+
+ bitpos = debug_get_field_bitpos (dhandle, *pf);
+ }
+
+ if ((flags & BASEFLAGS_VIRTUAL) != 0)
+ virtualp = true;
+ else
+ virtualp = false;
+ if ((flags & BASEFLAGS_PRIVATE) != 0)
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ else
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+
+ baseclass = debug_make_baseclass (dhandle, basetype, bitpos,
+ virtualp, visibility);
+ if (baseclass == DEBUG_BASECLASS_NULL)
+ return false;
+
+ if (baseclasses_count + 1 >= baseclasses_alloc)
+ {
+ baseclasses_alloc += 10;
+ baseclasses = ((debug_baseclass *)
+ xrealloc (baseclasses,
+ (baseclasses_alloc
+ * sizeof *baseclasses)));
+ }
+
+ baseclasses[baseclasses_count] = baseclass;
+ ++baseclasses_count;
+ baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL;
+ }
+ break;
+
+ case 'd':
+ {
+ bfd_vma flags;
+ const char *fieldname, *mangledname;
+ unsigned long fieldlen, mangledlen;
+ char *fieldcopy;
+ boolean staticp;
+ debug_type ftype;
+ const debug_field *pf = NULL;
+ enum debug_visibility visibility;
+ debug_field field;
+
+ /* This represents a data member. */
+
+ if (! ieee_require_asn (info, pp, &flags)
+ || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)
+ || ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen))
+ return false;
+ count -= 3;
+
+ fieldcopy = savestring (fieldname, fieldlen);
+
+ staticp = (flags & CXXFLAGS_STATIC) != 0 ? true : false;
+
+ if (staticp)
+ {
+ struct ieee_var *pv, *pvend;
+
+ /* See if we can find a definition for this variable. */
+ pv = info->vars.vars;
+ pvend = pv + info->vars.alloc;
+ for (; pv < pvend; pv++)
+ if (pv->namlen == mangledlen
+ && strncmp (pv->name, mangledname, mangledlen) == 0)
+ break;
+ if (pv < pvend)
+ ftype = pv->type;
+ else
+ {
+ /* This can happen if the variable is never used. */
+ ftype = ieee_builtin_type (info, start,
+ (unsigned int) builtin_void);
+ }
+ }
+ else
+ {
+ unsigned int findx;
+
+ if (structfields == NULL)
+ {
+ ieee_error (info, start, "C++ object has no fields");
+ return false;
+ }
+
+ for (pf = structfields, findx = 0;
+ *pf != DEBUG_FIELD_NULL;
+ pf++, findx++)
+ {
+ const char *fname;
+
+ fname = debug_get_field_name (dhandle, *pf);
+ if (fname == NULL)
+ return false;
+ if (fname[0] == mangledname[0]
+ && strncmp (fname, mangledname, mangledlen) == 0
+ && strlen (fname) == mangledlen)
+ break;
+ }
+ if (*pf == DEBUG_FIELD_NULL)
+ {
+ ieee_error (info, start,
+ "C++ data member not found in container");
+ return false;
+ }
+
+ ftype = debug_get_field_type (dhandle, *pf);
+
+ if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER)
+ {
+ /* We might need to convert this field into a
+ reference type later on, so make it an indirect
+ type. */
+ if (it->fslots == NULL)
+ {
+ unsigned int fcnt;
+ const debug_field *pfcnt;
+
+ fcnt = 0;
+ for (pfcnt = structfields;
+ *pfcnt != DEBUG_FIELD_NULL;
+ pfcnt++)
+ ++fcnt;
+ it->fslots = ((debug_type *)
+ xmalloc (fcnt * sizeof *it->fslots));
+ memset (it->fslots, 0,
+ fcnt * sizeof *it->fslots);
+ }
+
+ if (ftype == DEBUG_TYPE_NULL)
+ return false;
+ it->fslots[findx] = ftype;
+ ftype = debug_make_indirect_type (dhandle,
+ it->fslots + findx,
+ (const char *) NULL);
+ }
+ }
+ if (ftype == DEBUG_TYPE_NULL)
+ return false;
+
+ switch (flags & CXXFLAGS_VISIBILITY)
+ {
+ default:
+ ieee_error (info, start, "unknown C++ visibility");
+ return false;
+
+ case CXXFLAGS_VISIBILITY_PUBLIC:
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PRIVATE:
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PROTECTED:
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ }
+
+ if (staticp)
+ {
+ char *mangledcopy;
+
+ mangledcopy = savestring (mangledname, mangledlen);
+
+ field = debug_make_static_member (dhandle, fieldcopy,
+ ftype, mangledcopy,
+ visibility);
+ }
+ else
+ {
+ bfd_vma bitpos, bitsize;
+
+ bitpos = debug_get_field_bitpos (dhandle, *pf);
+ bitsize = debug_get_field_bitsize (dhandle, *pf);
+ if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1)
+ {
+ ieee_error (info, start, "bad C++ field bit pos or size");
+ return false;
+ }
+ field = debug_make_field (dhandle, fieldcopy, ftype, bitpos,
+ bitsize, visibility);
+ }
+
+ if (field == DEBUG_FIELD_NULL)
+ return false;
+
+ if (field_count + 1 >= field_alloc)
+ {
+ field_alloc += 10;
+ fields = ((debug_field *)
+ xrealloc (fields, field_alloc * sizeof *fields));
+ }
+
+ fields[field_count] = field;
+ ++field_count;
+ fields[field_count] = DEBUG_FIELD_NULL;
+ }
+ break;
+
+ case 'm':
+ case 'v':
+ {
+ bfd_vma flags, voffset, control;
+ const char *name, *mangled;
+ unsigned long namlen, mangledlen;
+ struct ieee_var *pv, *pvend;
+ debug_type type;
+ enum debug_visibility visibility;
+ boolean constp, volatilep;
+ char *mangledcopy;
+ debug_method_variant mv;
+ struct ieee_method *meth;
+ unsigned int im;
+
+ if (! ieee_require_asn (info, pp, &flags)
+ || ! ieee_require_atn65 (info, pp, &name, &namlen)
+ || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
+ return false;
+ count -= 3;
+ if (id != 'v')
+ voffset = 0;
+ else
+ {
+ if (! ieee_require_asn (info, pp, &voffset))
+ return false;
+ --count;
+ }
+ if (! ieee_require_asn (info, pp, &control))
+ return false;
+ --count;
+
+ /* We just ignore the control information. */
+
+ /* We have no way to represent friend information, so we
+ just ignore it. */
+ if ((flags & CXXFLAGS_FRIEND) != 0)
+ break;
+
+ /* We should already have seen a type for the function. */
+ pv = info->vars.vars;
+ pvend = pv + info->vars.alloc;
+ for (; pv < pvend; pv++)
+ if (pv->namlen == mangledlen
+ && strncmp (pv->name, mangled, mangledlen) == 0)
+ break;
+
+ if (pv >= pvend)
+ {
+ /* We won't have type information for this function if
+ it is not included in this file. We don't try to
+ handle this case. FIXME. */
+ type = (debug_make_function_type
+ (dhandle,
+ ieee_builtin_type (info, start,
+ (unsigned int) builtin_void),
+ (debug_type *) NULL,
+ false));
+ }
+ else
+ {
+ debug_type return_type;
+ const debug_type *arg_types;
+ boolean varargs;
+
+ if (debug_get_type_kind (dhandle, pv->type)
+ != DEBUG_KIND_FUNCTION)
+ {
+ ieee_error (info, start,
+ "bad type for C++ method function");
+ return false;
+ }
+
+ return_type = debug_get_return_type (dhandle, pv->type);
+ arg_types = debug_get_parameter_types (dhandle, pv->type,
+ &varargs);
+ if (return_type == DEBUG_TYPE_NULL || arg_types == NULL)
+ {
+ ieee_error (info, start,
+ "no type information for C++ method function");
+ return false;
+ }
+
+ type = debug_make_method_type (dhandle, return_type, it->type,
+ (debug_type *) arg_types,
+ varargs);
+ }
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ switch (flags & CXXFLAGS_VISIBILITY)
+ {
+ default:
+ ieee_error (info, start, "unknown C++ visibility");
+ return false;
+
+ case CXXFLAGS_VISIBILITY_PUBLIC:
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PRIVATE:
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PROTECTED:
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ }
+
+ constp = (flags & CXXFLAGS_CONST) != 0 ? true : false;
+ volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? true : false;
+
+ mangledcopy = savestring (mangled, mangledlen);
+
+ if ((flags & CXXFLAGS_STATIC) != 0)
+ {
+ if (id == 'v')
+ {
+ ieee_error (info, start, "C++ static virtual method");
+ return false;
+ }
+ mv = debug_make_static_method_variant (dhandle, mangledcopy,
+ type, visibility,
+ constp, volatilep);
+ }
+ else
+ {
+ debug_type vcontext;
+
+ if (id != 'v')
+ vcontext = DEBUG_TYPE_NULL;
+ else
+ {
+ /* FIXME: How can we calculate this correctly? */
+ vcontext = it->type;
+ }
+ mv = debug_make_method_variant (dhandle, mangledcopy, type,
+ visibility, constp,
+ volatilep, voffset,
+ vcontext);
+ }
+ if (mv == DEBUG_METHOD_VARIANT_NULL)
+ return false;
+
+ for (meth = methods, im = 0; im < methods_count; meth++, im++)
+ if (meth->namlen == namlen
+ && strncmp (meth->name, name, namlen) == 0)
+ break;
+ if (im >= methods_count)
+ {
+ if (methods_count >= methods_alloc)
+ {
+ methods_alloc += 10;
+ methods = ((struct ieee_method *)
+ xrealloc (methods,
+ methods_alloc * sizeof *methods));
+ }
+ methods[methods_count].name = name;
+ methods[methods_count].namlen = namlen;
+ methods[methods_count].variants = NULL;
+ methods[methods_count].count = 0;
+ methods[methods_count].alloc = 0;
+ meth = methods + methods_count;
+ ++methods_count;
+ }
+
+ if (meth->count + 1 >= meth->alloc)
+ {
+ meth->alloc += 10;
+ meth->variants = ((debug_method_variant *)
+ xrealloc (meth->variants,
+ (meth->alloc
+ * sizeof *meth->variants)));
+ }
+
+ meth->variants[meth->count] = mv;
+ ++meth->count;
+ meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL;
+ }
+ break;
+
+ case 'o':
+ {
+ bfd_vma spec;
+
+ /* We have no way to store this information, so we just
+ ignore it. */
+ if (! ieee_require_asn (info, pp, &spec))
+ return false;
+ --count;
+ if ((spec & 4) != 0)
+ {
+ const char *filename;
+ unsigned long filenamlen;
+ bfd_vma lineno;
+
+ if (! ieee_require_atn65 (info, pp, &filename, &filenamlen)
+ || ! ieee_require_asn (info, pp, &lineno))
+ return false;
+ count -= 2;
+ }
+ else if ((spec & 8) != 0)
+ {
+ const char *mangled;
+ unsigned long mangledlen;
+
+ if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
+ return false;
+ --count;
+ }
+ else
+ {
+ ieee_error (info, start,
+ "unrecognized C++ object overhead spec");
+ return false;
+ }
+ }
+ break;
+
+ case 'z':
+ {
+ const char *vname, *basename;
+ unsigned long vnamelen, baselen;
+ bfd_vma vsize, control;
+
+ /* A virtual table pointer. */
+
+ if (! ieee_require_atn65 (info, pp, &vname, &vnamelen)
+ || ! ieee_require_asn (info, pp, &vsize)
+ || ! ieee_require_atn65 (info, pp, &basename, &baselen)
+ || ! ieee_require_asn (info, pp, &control))
+ return false;
+ count -= 4;
+
+ /* We just ignore the control number. We don't care what
+ the virtual table name is. We have no way to store the
+ virtual table size, and I don't think we care anyhow. */
+
+ /* FIXME: We can't handle multiple virtual table pointers. */
+
+ if (baselen == 0)
+ ownvptr = true;
+ else
+ {
+ char *basecopy;
+
+ basecopy = savestring (basename, baselen);
+ vptrbase = debug_find_tagged_type (dhandle, basecopy,
+ DEBUG_KIND_ILLEGAL);
+ free (basecopy);
+ if (vptrbase == DEBUG_TYPE_NULL)
+ {
+ ieee_error (info, start, "undefined C++ vtable");
+ return false;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ /* Now that we have seen all the method variants, we can call
+ debug_make_method for each one. */
+
+ if (methods_count == 0)
+ dmethods = NULL;
+ else
+ {
+ unsigned int i;
+
+ dmethods = ((debug_method *)
+ xmalloc ((methods_count + 1) * sizeof *dmethods));
+ for (i = 0; i < methods_count; i++)
+ {
+ char *namcopy;
+
+ namcopy = savestring (methods[i].name, methods[i].namlen);
+ dmethods[i] = debug_make_method (dhandle, namcopy,
+ methods[i].variants);
+ if (dmethods[i] == DEBUG_METHOD_NULL)
+ return false;
+ }
+ dmethods[i] = DEBUG_METHOD_NULL;
+ free (methods);
+ }
+
+ /* The struct type was created as an indirect type pointing at
+ it->slot. We update it->slot to automatically update all
+ references to this struct. */
+ it->slot = debug_make_object_type (dhandle,
+ class != 'u',
+ debug_get_type_size (dhandle,
+ it->slot),
+ fields, baseclasses, dmethods,
+ vptrbase, ownvptr);
+ if (it->slot == DEBUG_TYPE_NULL)
+ return false;
+
+ return true;
+}
+
+/* Read C++ default argument value and reference type information. */
+
+static boolean
+ieee_read_cxx_defaults (info, pp, count)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ unsigned long count;
+{
+ const bfd_byte *start;
+ const char *fnname;
+ unsigned long fnlen;
+ bfd_vma defcount;
+
+ start = *pp;
+
+ /* Giving the function name before the argument count is an addendum
+ to the spec. The function name is demangled, though, so this
+ record must always refer to the current function. */
+
+ if (info->blockstack.bsp <= info->blockstack.stack
+ || info->blockstack.bsp[-1].fnindx == (unsigned int) -1)
+ {
+ ieee_error (info, start, "C++ default values not in a function");
+ return false;
+ }
+
+ if (! ieee_require_atn65 (info, pp, &fnname, &fnlen)
+ || ! ieee_require_asn (info, pp, &defcount))
+ return false;
+ count -= 2;
+
+ while (defcount-- > 0)
+ {
+ bfd_vma type, val;
+ const char *strval;
+ unsigned long strvallen;
+
+ if (! ieee_require_asn (info, pp, &type))
+ return false;
+ --count;
+
+ switch (type)
+ {
+ case 0:
+ case 4:
+ break;
+
+ case 1:
+ case 2:
+ if (! ieee_require_asn (info, pp, &val))
+ return false;
+ --count;
+ break;
+
+ case 3:
+ case 7:
+ if (! ieee_require_atn65 (info, pp, &strval, &strvallen))
+ return false;
+ --count;
+ break;
+
+ default:
+ ieee_error (info, start, "unrecognized C++ default type");
+ return false;
+ }
+
+ /* We have no way to record the default argument values, so we
+ just ignore them. FIXME. */
+ }
+
+ /* Any remaining arguments are indices of parameters that are really
+ reference type. */
+ if (count > 0)
+ {
+ PTR dhandle;
+ debug_type *arg_slots;
+
+ dhandle = info->dhandle;
+ arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots;
+ while (count-- > 0)
+ {
+ bfd_vma indx;
+ debug_type target;
+
+ if (! ieee_require_asn (info, pp, &indx))
+ return false;
+ /* The index is 1 based. */
+ --indx;
+ if (arg_slots == NULL
+ || arg_slots[indx] == DEBUG_TYPE_NULL
+ || (debug_get_type_kind (dhandle, arg_slots[indx])
+ != DEBUG_KIND_POINTER))
+ {
+ ieee_error (info, start, "reference parameter is not a pointer");
+ return false;
+ }
+
+ target = debug_get_target_type (dhandle, arg_slots[indx]);
+ arg_slots[indx] = debug_make_reference_type (dhandle, target);
+ if (arg_slots[indx] == DEBUG_TYPE_NULL)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Read a C++ reference definition. */
+
+static boolean
+ieee_read_reference (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *start;
+ bfd_vma flags;
+ const char *class, *name;
+ unsigned long classlen, namlen;
+ debug_type *pslot;
+ debug_type target;
+
+ start = *pp;
+
+ if (! ieee_require_asn (info, pp, &flags))
+ return false;
+
+ /* Giving the class name before the member name is in an addendum to
+ the spec. */
+ if (flags == 3)
+ {
+ if (! ieee_require_atn65 (info, pp, &class, &classlen))
+ return false;
+ }
+
+ if (! ieee_require_atn65 (info, pp, &name, &namlen))
+ return false;
+
+ pslot = NULL;
+ if (flags != 3)
+ {
+ int pass;
+
+ /* We search from the last variable indices to the first in
+ hopes of finding local variables correctly. We search the
+ local variables on the first pass, and the global variables
+ on the second. FIXME: This probably won't work in all cases.
+ On the other hand, I don't know what will. */
+ for (pass = 0; pass < 2; pass++)
+ {
+ struct ieee_vars *vars;
+ int i;
+ struct ieee_var *pv = NULL;
+
+ if (pass == 0)
+ vars = &info->vars;
+ else
+ {
+ vars = info->global_vars;
+ if (vars == NULL)
+ break;
+ }
+
+ for (i = (int) vars->alloc - 1; i >= 0; i--)
+ {
+ boolean found;
+
+ pv = vars->vars + i;
+
+ if (pv->pslot == NULL
+ || pv->namlen != namlen
+ || strncmp (pv->name, name, namlen) != 0)
+ continue;
+
+ found = false;
+ switch (flags)
+ {
+ default:
+ ieee_error (info, start,
+ "unrecognized C++ reference type");
+ return false;
+
+ case 0:
+ /* Global variable or function. */
+ if (pv->kind == IEEE_GLOBAL
+ || pv->kind == IEEE_EXTERNAL
+ || pv->kind == IEEE_FUNCTION)
+ found = true;
+ break;
+
+ case 1:
+ /* Global static variable or function. */
+ if (pv->kind == IEEE_STATIC
+ || pv->kind == IEEE_FUNCTION)
+ found = true;
+ break;
+
+ case 2:
+ /* Local variable. */
+ if (pv->kind == IEEE_LOCAL)
+ found = true;
+ break;
+ }
+
+ if (found)
+ break;
+ }
+
+ if (i >= 0)
+ {
+ pslot = pv->pslot;
+ break;
+ }
+ }
+ }
+ else
+ {
+ struct ieee_tag *it;
+
+ for (it = info->tags; it != NULL; it = it->next)
+ {
+ if (it->name[0] == class[0]
+ && strncmp (it->name, class, classlen) == 0
+ && strlen (it->name) == classlen)
+ {
+ if (it->fslots != NULL)
+ {
+ const debug_field *pf;
+ unsigned int findx;
+
+ pf = debug_get_fields (info->dhandle, it->type);
+ if (pf == NULL)
+ {
+ ieee_error (info, start,
+ "C++ reference in class with no fields");
+ return false;
+ }
+
+ for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++)
+ {
+ const char *fname;
+
+ fname = debug_get_field_name (info->dhandle, *pf);
+ if (fname == NULL)
+ return false;
+ if (strncmp (fname, name, namlen) == 0
+ && strlen (fname) == namlen)
+ {
+ pslot = it->fslots + findx;
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ if (pslot == NULL)
+ {
+ ieee_error (info, start, "C++ reference not found");
+ return false;
+ }
+
+ /* We allocated the type of the object as an indirect type pointing
+ to *pslot, which we can now update to be a reference type. */
+ if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER)
+ {
+ ieee_error (info, start, "C++ reference is not pointer");
+ return false;
+ }
+
+ target = debug_get_target_type (info->dhandle, *pslot);
+ *pslot = debug_make_reference_type (info->dhandle, target);
+ if (*pslot == DEBUG_TYPE_NULL)
+ return false;
+
+ return true;
+}
+
+/* Require an ASN record. */
+
+static boolean
+ieee_require_asn (info, pp, pv)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+{
+ const bfd_byte *start;
+ ieee_record_enum_type c;
+ bfd_vma varindx;
+
+ start = *pp;
+
+ c = (ieee_record_enum_type) **pp;
+ if (c != ieee_e2_first_byte_enum)
+ {
+ ieee_error (info, start, "missing required ASN");
+ return false;
+ }
+ ++*pp;
+
+ c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
+ if (c != ieee_asn_record_enum)
+ {
+ ieee_error (info, start, "missing required ASN");
+ return false;
+ }
+ ++*pp;
+
+ /* Just ignore the variable index. */
+ if (! ieee_read_number (info, pp, &varindx))
+ return false;
+
+ return ieee_read_expression (info, pp, pv);
+}
+
+/* Require an ATN65 record. */
+
+static boolean
+ieee_require_atn65 (info, pp, pname, pnamlen)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ const char **pname;
+ unsigned long *pnamlen;
+{
+ const bfd_byte *start;
+ ieee_record_enum_type c;
+ bfd_vma name_indx, type_indx, atn_code;
+
+ start = *pp;
+
+ c = (ieee_record_enum_type) **pp;
+ if (c != ieee_at_record_enum)
+ {
+ ieee_error (info, start, "missing required ATN65");
+ return false;
+ }
+ ++*pp;
+
+ c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
+ if (c != ieee_atn_record_enum)
+ {
+ ieee_error (info, start, "missing required ATN65");
+ return false;
+ }
+ ++*pp;
+
+ if (! ieee_read_number (info, pp, &name_indx)
+ || ! ieee_read_number (info, pp, &type_indx)
+ || ! ieee_read_number (info, pp, &atn_code))
+ return false;
+
+ /* Just ignore name_indx. */
+
+ if (type_indx != 0 || atn_code != 65)
+ {
+ ieee_error (info, start, "bad ATN65 record");
+ return false;
+ }
+
+ return ieee_read_id (info, pp, pname, pnamlen);
+}
+
+/* Convert a register number in IEEE debugging information into a
+ generic register number. */
+
+static int
+ieee_regno_to_genreg (abfd, r)
+ bfd *abfd;
+ int r;
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_m68k:
+ /* For some reasons stabs adds 2 to the floating point register
+ numbers. */
+ if (r >= 16)
+ r += 2;
+ break;
+
+ case bfd_arch_i960:
+ /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
+ 32 to 35 for fp0 to fp3. */
+ --r;
+ break;
+
+ default:
+ break;
+ }
+
+ return r;
+}
+
+/* Convert a generic register number to an IEEE specific one. */
+
+static int
+ieee_genreg_to_regno (abfd, r)
+ bfd *abfd;
+ int r;
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_m68k:
+ /* For some reason stabs add 2 to the floating point register
+ numbers. */
+ if (r >= 18)
+ r -= 2;
+ break;
+
+ case bfd_arch_i960:
+ /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
+ 32 to 35 for fp0 to fp3. */
+ ++r;
+ break;
+
+ default:
+ break;
+ }
+
+ return r;
+}
+
+/* These routines build IEEE debugging information out of the generic
+ debugging information. */
+
+/* We build the IEEE debugging information byte by byte. Rather than
+ waste time copying data around, we use a linked list of buffers to
+ hold the data. */
+
+#define IEEE_BUFSIZE (490)
+
+struct ieee_buf
+{
+ /* Next buffer. */
+ struct ieee_buf *next;
+ /* Number of data bytes in this buffer. */
+ unsigned int c;
+ /* Bytes. */
+ bfd_byte buf[IEEE_BUFSIZE];
+};
+
+/* A list of buffers. */
+
+struct ieee_buflist
+{
+ /* Head of list. */
+ struct ieee_buf *head;
+ /* Tail--last buffer on list. */
+ struct ieee_buf *tail;
+};
+
+/* In order to generate the BB11 blocks required by the HP emulator,
+ we keep track of ranges of addresses which correspond to a given
+ compilation unit. */
+
+struct ieee_range
+{
+ /* Next range. */
+ struct ieee_range *next;
+ /* Low address. */
+ bfd_vma low;
+ /* High address. */
+ bfd_vma high;
+};
+
+/* This structure holds information for a class on the type stack. */
+
+struct ieee_type_class
+{
+ /* The name index in the debugging information. */
+ unsigned int indx;
+ /* The pmisc records for the class. */
+ struct ieee_buflist pmiscbuf;
+ /* The number of pmisc records. */
+ unsigned int pmisccount;
+ /* The name of the class holding the virtual table, if not this
+ class. */
+ const char *vclass;
+ /* Whether this class holds its own virtual table. */
+ boolean ownvptr;
+ /* The largest virtual table offset seen so far. */
+ bfd_vma voffset;
+ /* The current method. */
+ const char *method;
+ /* Additional pmisc records used to record fields of reference type. */
+ struct ieee_buflist refs;
+};
+
+/* This is how we store types for the writing routines. Most types
+ are simply represented by a type index. */
+
+struct ieee_write_type
+{
+ /* Type index. */
+ unsigned int indx;
+ /* The size of the type, if known. */
+ unsigned int size;
+ /* The name of the type, if any. */
+ const char *name;
+ /* If this is a function or method type, we build the type here, and
+ only add it to the output buffers if we need it. */
+ struct ieee_buflist fndef;
+ /* If this is a struct, this is where the struct definition is
+ built. */
+ struct ieee_buflist strdef;
+ /* If this is a class, this is where the class information is built. */
+ struct ieee_type_class *classdef;
+ /* Whether the type is unsigned. */
+ unsigned int unsignedp : 1;
+ /* Whether this is a reference type. */
+ unsigned int referencep : 1;
+ /* Whether this is in the local type block. */
+ unsigned int localp : 1;
+ /* Whether this is a duplicate struct definition which we are
+ ignoring. */
+ unsigned int ignorep : 1;
+};
+
+/* This is the type stack used by the debug writing routines. FIXME:
+ We could generate more efficient output if we remembered when we
+ have output a particular type before. */
+
+struct ieee_type_stack
+{
+ /* Next entry on stack. */
+ struct ieee_type_stack *next;
+ /* Type information. */
+ struct ieee_write_type type;
+};
+
+/* This is a list of associations between a name and some types.
+ These are used for typedefs and tags. */
+
+struct ieee_name_type
+{
+ /* Next type for this name. */
+ struct ieee_name_type *next;
+ /* ID number. For a typedef, this is the index of the type to which
+ this name is typedefed. */
+ unsigned int id;
+ /* Type. */
+ struct ieee_write_type type;
+ /* If this is a tag which has not yet been defined, this is the
+ kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */
+ enum debug_type_kind kind;
+};
+
+/* We use a hash table to associate names and types. */
+
+struct ieee_name_type_hash_table
+{
+ struct bfd_hash_table root;
+};
+
+struct ieee_name_type_hash_entry
+{
+ struct bfd_hash_entry root;
+ /* Information for this name. */
+ struct ieee_name_type *types;
+};
+
+/* This is a list of enums. */
+
+struct ieee_defined_enum
+{
+ /* Next enum. */
+ struct ieee_defined_enum *next;
+ /* Type index. */
+ unsigned int indx;
+ /* Whether this enum has been defined. */
+ boolean defined;
+ /* Tag. */
+ const char *tag;
+ /* Names. */
+ const char **names;
+ /* Values. */
+ bfd_signed_vma *vals;
+};
+
+/* We keep a list of modified versions of types, so that we don't
+ output them more than once. */
+
+struct ieee_modified_type
+{
+ /* Pointer to this type. */
+ unsigned int pointer;
+ /* Function with unknown arguments returning this type. */
+ unsigned int function;
+ /* Const version of this type. */
+ unsigned int const_qualified;
+ /* Volatile version of this type. */
+ unsigned int volatile_qualified;
+ /* List of arrays of this type of various bounds. */
+ struct ieee_modified_array_type *arrays;
+};
+
+/* A list of arrays bounds. */
+
+struct ieee_modified_array_type
+{
+ /* Next array bounds. */
+ struct ieee_modified_array_type *next;
+ /* Type index with these bounds. */
+ unsigned int indx;
+ /* Low bound. */
+ bfd_signed_vma low;
+ /* High bound. */
+ bfd_signed_vma high;
+};
+
+/* This is a list of pending function parameter information. We don't
+ output them until we see the first block. */
+
+struct ieee_pending_parm
+{
+ /* Next pending parameter. */
+ struct ieee_pending_parm *next;
+ /* Name. */
+ const char *name;
+ /* Type index. */
+ unsigned int type;
+ /* Whether the type is a reference. */
+ boolean referencep;
+ /* Kind. */
+ enum debug_parm_kind kind;
+ /* Value. */
+ bfd_vma val;
+};
+
+/* This is the handle passed down by debug_write. */
+
+struct ieee_handle
+{
+ /* BFD we are writing to. */
+ bfd *abfd;
+ /* Whether we got an error in a subroutine called via traverse or
+ map_over_sections. */
+ boolean error;
+ /* Current data buffer list. */
+ struct ieee_buflist *current;
+ /* Current data buffer. */
+ struct ieee_buf *curbuf;
+ /* Filename of current compilation unit. */
+ const char *filename;
+ /* Module name of current compilation unit. */
+ const char *modname;
+ /* List of buffer for global types. */
+ struct ieee_buflist global_types;
+ /* List of finished data buffers. */
+ struct ieee_buflist data;
+ /* List of buffers for typedefs in the current compilation unit. */
+ struct ieee_buflist types;
+ /* List of buffers for variables and functions in the current
+ compilation unit. */
+ struct ieee_buflist vars;
+ /* List of buffers for C++ class definitions in the current
+ compilation unit. */
+ struct ieee_buflist cxx;
+ /* List of buffers for line numbers in the current compilation unit. */
+ struct ieee_buflist linenos;
+ /* Ranges for the current compilation unit. */
+ struct ieee_range *ranges;
+ /* Ranges for all debugging information. */
+ struct ieee_range *global_ranges;
+ /* Nested pending ranges. */
+ struct ieee_range *pending_ranges;
+ /* Type stack. */
+ struct ieee_type_stack *type_stack;
+ /* Next unallocated type index. */
+ unsigned int type_indx;
+ /* Next unallocated name index. */
+ unsigned int name_indx;
+ /* Typedefs. */
+ struct ieee_name_type_hash_table typedefs;
+ /* Tags. */
+ struct ieee_name_type_hash_table tags;
+ /* Enums. */
+ struct ieee_defined_enum *enums;
+ /* Modified versions of types. */
+ struct ieee_modified_type *modified;
+ /* Number of entries allocated in modified. */
+ unsigned int modified_alloc;
+ /* 4 byte complex type. */
+ unsigned int complex_float_index;
+ /* 8 byte complex type. */
+ unsigned int complex_double_index;
+ /* The depth of block nesting. This is 0 outside a function, and 1
+ just after start_function is called. */
+ unsigned int block_depth;
+ /* The name of the current function. */
+ const char *fnname;
+ /* List of buffers for the type of the function we are currently
+ writing out. */
+ struct ieee_buflist fntype;
+ /* List of buffers for the parameters of the function we are
+ currently writing out. */
+ struct ieee_buflist fnargs;
+ /* Number of arguments written to fnargs. */
+ unsigned int fnargcount;
+ /* Pending function parameters. */
+ struct ieee_pending_parm *pending_parms;
+ /* Current line number filename. */
+ const char *lineno_filename;
+ /* Line number name index. */
+ unsigned int lineno_name_indx;
+ /* Filename of pending line number. */
+ const char *pending_lineno_filename;
+ /* Pending line number. */
+ unsigned long pending_lineno;
+ /* Address of pending line number. */
+ bfd_vma pending_lineno_addr;
+ /* Highest address seen at end of procedure. */
+ bfd_vma highaddr;
+};
+
+static boolean ieee_init_buffer
+ PARAMS ((struct ieee_handle *, struct ieee_buflist *));
+static boolean ieee_change_buffer
+ PARAMS ((struct ieee_handle *, struct ieee_buflist *));
+static boolean ieee_append_buffer
+ PARAMS ((struct ieee_handle *, struct ieee_buflist *,
+ struct ieee_buflist *));
+static boolean ieee_real_write_byte PARAMS ((struct ieee_handle *, int));
+static boolean ieee_write_2bytes PARAMS ((struct ieee_handle *, int));
+static boolean ieee_write_number PARAMS ((struct ieee_handle *, bfd_vma));
+static boolean ieee_write_id PARAMS ((struct ieee_handle *, const char *));
+static boolean ieee_write_asn
+ PARAMS ((struct ieee_handle *, unsigned int, bfd_vma));
+static boolean ieee_write_atn65
+ PARAMS ((struct ieee_handle *, unsigned int, const char *));
+static boolean ieee_push_type
+ PARAMS ((struct ieee_handle *, unsigned int, unsigned int, boolean,
+ boolean));
+static unsigned int ieee_pop_type PARAMS ((struct ieee_handle *));
+static void ieee_pop_unused_type PARAMS ((struct ieee_handle *));
+static unsigned int ieee_pop_type_used
+ PARAMS ((struct ieee_handle *, boolean));
+static boolean ieee_add_range
+ PARAMS ((struct ieee_handle *, boolean, bfd_vma, bfd_vma));
+static boolean ieee_start_range PARAMS ((struct ieee_handle *, bfd_vma));
+static boolean ieee_end_range PARAMS ((struct ieee_handle *, bfd_vma));
+static boolean ieee_define_type
+ PARAMS ((struct ieee_handle *, unsigned int, boolean, boolean));
+static boolean ieee_define_named_type
+ PARAMS ((struct ieee_handle *, const char *, unsigned int, unsigned int,
+ boolean, boolean, struct ieee_buflist *));
+static struct ieee_modified_type *ieee_get_modified_info
+ PARAMS ((struct ieee_handle *, unsigned int));
+static struct bfd_hash_entry *ieee_name_type_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static boolean ieee_write_undefined_tag
+ PARAMS ((struct ieee_name_type_hash_entry *, PTR));
+static boolean ieee_finish_compilation_unit PARAMS ((struct ieee_handle *));
+static void ieee_add_bb11_blocks PARAMS ((bfd *, asection *, PTR));
+static boolean ieee_add_bb11
+ PARAMS ((struct ieee_handle *, asection *, bfd_vma, bfd_vma));
+static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *));
+static unsigned int ieee_vis_to_flags PARAMS ((enum debug_visibility));
+static boolean ieee_class_method_var
+ PARAMS ((struct ieee_handle *, const char *, enum debug_visibility, boolean,
+ boolean, boolean, bfd_vma, boolean));
+
+static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *));
+static boolean ieee_start_source PARAMS ((PTR, const char *));
+static boolean ieee_empty_type PARAMS ((PTR));
+static boolean ieee_void_type PARAMS ((PTR));
+static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean));
+static boolean ieee_float_type PARAMS ((PTR, unsigned int));
+static boolean ieee_complex_type PARAMS ((PTR, unsigned int));
+static boolean ieee_bool_type PARAMS ((PTR, unsigned int));
+static boolean ieee_enum_type
+ PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
+static boolean ieee_pointer_type PARAMS ((PTR));
+static boolean ieee_function_type PARAMS ((PTR, int, boolean));
+static boolean ieee_reference_type PARAMS ((PTR));
+static boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
+static boolean ieee_array_type
+ PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
+static boolean ieee_set_type PARAMS ((PTR, boolean));
+static boolean ieee_offset_type PARAMS ((PTR));
+static boolean ieee_method_type PARAMS ((PTR, boolean, int, boolean));
+static boolean ieee_const_type PARAMS ((PTR));
+static boolean ieee_volatile_type PARAMS ((PTR));
+static boolean ieee_start_struct_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
+static boolean ieee_struct_field
+ PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
+static boolean ieee_end_struct_type PARAMS ((PTR));
+static boolean ieee_start_class_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
+ boolean));
+static boolean ieee_class_static_member
+ PARAMS ((PTR, const char *, const char *, enum debug_visibility));
+static boolean ieee_class_baseclass
+ PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
+static boolean ieee_class_start_method PARAMS ((PTR, const char *));
+static boolean ieee_class_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
+ bfd_vma, boolean));
+static boolean ieee_class_static_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
+static boolean ieee_class_end_method PARAMS ((PTR));
+static boolean ieee_end_class_type PARAMS ((PTR));
+static boolean ieee_typedef_type PARAMS ((PTR, const char *));
+static boolean ieee_tag_type
+ PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
+static boolean ieee_typdef PARAMS ((PTR, const char *));
+static boolean ieee_tag PARAMS ((PTR, const char *));
+static boolean ieee_int_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean ieee_float_constant PARAMS ((PTR, const char *, double));
+static boolean ieee_typed_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean ieee_variable
+ PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
+static boolean ieee_start_function PARAMS ((PTR, const char *, boolean));
+static boolean ieee_function_parameter
+ PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
+static boolean ieee_start_block PARAMS ((PTR, bfd_vma));
+static boolean ieee_end_block PARAMS ((PTR, bfd_vma));
+static boolean ieee_end_function PARAMS ((PTR));
+static boolean ieee_lineno
+ PARAMS ((PTR, const char *, unsigned long, bfd_vma));
+
+static const struct debug_write_fns ieee_fns =
+{
+ ieee_start_compilation_unit,
+ ieee_start_source,
+ ieee_empty_type,
+ ieee_void_type,
+ ieee_int_type,
+ ieee_float_type,
+ ieee_complex_type,
+ ieee_bool_type,
+ ieee_enum_type,
+ ieee_pointer_type,
+ ieee_function_type,
+ ieee_reference_type,
+ ieee_range_type,
+ ieee_array_type,
+ ieee_set_type,
+ ieee_offset_type,
+ ieee_method_type,
+ ieee_const_type,
+ ieee_volatile_type,
+ ieee_start_struct_type,
+ ieee_struct_field,
+ ieee_end_struct_type,
+ ieee_start_class_type,
+ ieee_class_static_member,
+ ieee_class_baseclass,
+ ieee_class_start_method,
+ ieee_class_method_variant,
+ ieee_class_static_method_variant,
+ ieee_class_end_method,
+ ieee_end_class_type,
+ ieee_typedef_type,
+ ieee_tag_type,
+ ieee_typdef,
+ ieee_tag,
+ ieee_int_constant,
+ ieee_float_constant,
+ ieee_typed_constant,
+ ieee_variable,
+ ieee_start_function,
+ ieee_function_parameter,
+ ieee_start_block,
+ ieee_end_block,
+ ieee_end_function,
+ ieee_lineno
+};
+
+/* Initialize a buffer to be empty. */
+
+/*ARGSUSED*/
+static boolean
+ieee_init_buffer (info, buflist)
+ struct ieee_handle *info;
+ struct ieee_buflist *buflist;
+{
+ buflist->head = NULL;
+ buflist->tail = NULL;
+ return true;
+}
+
+/* See whether a buffer list has any data. */
+
+#define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL)
+
+/* Change the current buffer to a specified buffer chain. */
+
+static boolean
+ieee_change_buffer (info, buflist)
+ struct ieee_handle *info;
+ struct ieee_buflist *buflist;
+{
+ if (buflist->head == NULL)
+ {
+ struct ieee_buf *buf;
+
+ buf = (struct ieee_buf *) xmalloc (sizeof *buf);
+ buf->next = NULL;
+ buf->c = 0;
+ buflist->head = buf;
+ buflist->tail = buf;
+ }
+
+ info->current = buflist;
+ info->curbuf = buflist->tail;
+
+ return true;
+}
+
+/* Append a buffer chain. */
+
+/*ARGSUSED*/
+static boolean
+ieee_append_buffer (info, mainbuf, newbuf)
+ struct ieee_handle *info;
+ struct ieee_buflist *mainbuf;
+ struct ieee_buflist *newbuf;
+{
+ if (newbuf->head != NULL)
+ {
+ if (mainbuf->head == NULL)
+ mainbuf->head = newbuf->head;
+ else
+ mainbuf->tail->next = newbuf->head;
+ mainbuf->tail = newbuf->tail;
+ }
+ return true;
+}
+
+/* Write a byte into the buffer. We use a macro for speed and a
+ function for the complex cases. */
+
+#define ieee_write_byte(info, b) \
+ ((info)->curbuf->c < IEEE_BUFSIZE \
+ ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), true) \
+ : ieee_real_write_byte ((info), (b)))
+
+static boolean
+ieee_real_write_byte (info, b)
+ struct ieee_handle *info;
+ int b;
+{
+ if (info->curbuf->c >= IEEE_BUFSIZE)
+ {
+ struct ieee_buf *n;
+
+ n = (struct ieee_buf *) xmalloc (sizeof *n);
+ n->next = NULL;
+ n->c = 0;
+ if (info->current->head == NULL)
+ info->current->head = n;
+ else
+ info->current->tail->next = n;
+ info->current->tail = n;
+ info->curbuf = n;
+ }
+
+ info->curbuf->buf[info->curbuf->c] = b;
+ ++info->curbuf->c;
+
+ return true;
+}
+
+/* Write out two bytes. */
+
+static boolean
+ieee_write_2bytes (info, i)
+ struct ieee_handle *info;
+ int i;
+{
+ return (ieee_write_byte (info, i >> 8)
+ && ieee_write_byte (info, i & 0xff));
+}
+
+/* Write out an integer. */
+
+static boolean
+ieee_write_number (info, v)
+ struct ieee_handle *info;
+ bfd_vma v;
+{
+ bfd_vma t;
+ bfd_byte ab[20];
+ bfd_byte *p;
+ unsigned int c;
+
+ if (v <= (bfd_vma) ieee_number_end_enum)
+ return ieee_write_byte (info, (int) v);
+
+ t = v;
+ p = ab + sizeof ab;
+ while (t != 0)
+ {
+ *--p = t & 0xff;
+ t >>= 8;
+ }
+ c = (ab + 20) - p;
+
+ if (c > (unsigned int) (ieee_number_repeat_end_enum
+ - ieee_number_repeat_start_enum))
+ {
+ fprintf (stderr, "IEEE numeric overflow: 0x");
+ fprintf_vma (stderr, v);
+ fprintf (stderr, "\n");
+ return false;
+ }
+
+ if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c))
+ return false;
+ for (; c > 0; --c, ++p)
+ {
+ if (! ieee_write_byte (info, *p))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out a string. */
+
+static boolean
+ieee_write_id (info, s)
+ struct ieee_handle *info;
+ const char *s;
+{
+ unsigned int len;
+
+ len = strlen (s);
+ if (len <= 0x7f)
+ {
+ if (! ieee_write_byte (info, len))
+ return false;
+ }
+ else if (len <= 0xff)
+ {
+ if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum)
+ || ! ieee_write_byte (info, len))
+ return false;
+ }
+ else if (len <= 0xffff)
+ {
+ if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum)
+ || ! ieee_write_2bytes (info, len))
+ return false;
+ }
+ else
+ {
+ fprintf (stderr, "IEEE string length overflow: %u\n", len);
+ return false;
+ }
+
+ for (; *s != '\0'; s++)
+ if (! ieee_write_byte (info, *s))
+ return false;
+
+ return true;
+}
+
+/* Write out an ASN record. */
+
+static boolean
+ieee_write_asn (info, indx, val)
+ struct ieee_handle *info;
+ unsigned int indx;
+ bfd_vma val;
+{
+ return (ieee_write_2bytes (info, (int) ieee_asn_record_enum)
+ && ieee_write_number (info, indx)
+ && ieee_write_number (info, val));
+}
+
+/* Write out an ATN65 record. */
+
+static boolean
+ieee_write_atn65 (info, indx, s)
+ struct ieee_handle *info;
+ unsigned int indx;
+ const char *s;
+{
+ return (ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ && ieee_write_number (info, indx)
+ && ieee_write_number (info, 0)
+ && ieee_write_number (info, 65)
+ && ieee_write_id (info, s));
+}
+
+/* Push a type index onto the type stack. */
+
+static boolean
+ieee_push_type (info, indx, size, unsignedp, localp)
+ struct ieee_handle *info;
+ unsigned int indx;
+ unsigned int size;
+ boolean unsignedp;
+ boolean localp;
+{
+ struct ieee_type_stack *ts;
+
+ ts = (struct ieee_type_stack *) xmalloc (sizeof *ts);
+ memset (ts, 0, sizeof *ts);
+
+ ts->type.indx = indx;
+ ts->type.size = size;
+ ts->type.unsignedp = unsignedp;
+ ts->type.localp = localp;
+
+ ts->next = info->type_stack;
+ info->type_stack = ts;
+
+ return true;
+}
+
+/* Pop a type index off the type stack. */
+
+static unsigned int
+ieee_pop_type (info)
+ struct ieee_handle *info;
+{
+ return ieee_pop_type_used (info, true);
+}
+
+/* Pop an unused type index off the type stack. */
+
+static void
+ieee_pop_unused_type (info)
+ struct ieee_handle *info;
+{
+ (void) ieee_pop_type_used (info, false);
+}
+
+/* Pop a used or unused type index off the type stack. */
+
+static unsigned int
+ieee_pop_type_used (info, used)
+ struct ieee_handle *info;
+ boolean used;
+{
+ struct ieee_type_stack *ts;
+ unsigned int ret;
+
+ ts = info->type_stack;
+ assert (ts != NULL);
+
+ /* If this is a function type, and we need it, we need to append the
+ actual definition to the typedef block now. */
+ if (used && ! ieee_buffer_emptyp (&ts->type.fndef))
+ {
+ struct ieee_buflist *buflist;
+
+ if (ts->type.localp)
+ {
+ /* Make sure we have started the types block. */
+ if (ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+ buflist = &info->types;
+ }
+ else
+ {
+ /* Make sure we started the global type block. */
+ if (ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ buflist = &info->global_types;
+ }
+
+ if (! ieee_append_buffer (info, buflist, &ts->type.fndef))
+ return false;
+ }
+
+ ret = ts->type.indx;
+ info->type_stack = ts->next;
+ free (ts);
+ return ret;
+}
+
+/* Add a range of bytes included in the current compilation unit. */
+
+static boolean
+ieee_add_range (info, global, low, high)
+ struct ieee_handle *info;
+ boolean global;
+ bfd_vma low;
+ bfd_vma high;
+{
+ struct ieee_range **plist, *r, **pr;
+
+ if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high)
+ return true;
+
+ if (global)
+ plist = &info->global_ranges;
+ else
+ plist = &info->ranges;
+
+ for (r = *plist; r != NULL; r = r->next)
+ {
+ if (high >= r->low && low <= r->high)
+ {
+ /* The new range overlaps r. */
+ if (low < r->low)
+ r->low = low;
+ if (high > r->high)
+ r->high = high;
+ pr = &r->next;
+ while (*pr != NULL && (*pr)->low <= r->high)
+ {
+ struct ieee_range *n;
+
+ if ((*pr)->high > r->high)
+ r->high = (*pr)->high;
+ n = (*pr)->next;
+ free (*pr);
+ *pr = n;
+ }
+ return true;
+ }
+ }
+
+ r = (struct ieee_range *) xmalloc (sizeof *r);
+ memset (r, 0, sizeof *r);
+
+ r->low = low;
+ r->high = high;
+
+ /* Store the ranges sorted by address. */
+ for (pr = plist; *pr != NULL; pr = &(*pr)->next)
+ if ((*pr)->low > high)
+ break;
+ r->next = *pr;
+ *pr = r;
+
+ return true;
+}
+
+/* Start a new range for which we only have the low address. */
+
+static boolean
+ieee_start_range (info, low)
+ struct ieee_handle *info;
+ bfd_vma low;
+{
+ struct ieee_range *r;
+
+ r = (struct ieee_range *) xmalloc (sizeof *r);
+ memset (r, 0, sizeof *r);
+ r->low = low;
+ r->next = info->pending_ranges;
+ info->pending_ranges = r;
+ return true;
+}
+
+/* Finish a range started by ieee_start_range. */
+
+static boolean
+ieee_end_range (info, high)
+ struct ieee_handle *info;
+ bfd_vma high;
+{
+ struct ieee_range *r;
+ bfd_vma low;
+
+ assert (info->pending_ranges != NULL);
+ r = info->pending_ranges;
+ low = r->low;
+ info->pending_ranges = r->next;
+ free (r);
+ return ieee_add_range (info, false, low, high);
+}
+
+/* Start defining a type. */
+
+static boolean
+ieee_define_type (info, size, unsignedp, localp)
+ struct ieee_handle *info;
+ unsigned int size;
+ boolean unsignedp;
+ boolean localp;
+{
+ return ieee_define_named_type (info, (const char *) NULL,
+ (unsigned int) -1, size, unsignedp,
+ localp, (struct ieee_buflist *) NULL);
+}
+
+/* Start defining a named type. */
+
+static boolean
+ieee_define_named_type (info, name, indx, size, unsignedp, localp, buflist)
+ struct ieee_handle *info;
+ const char *name;
+ unsigned int indx;
+ unsigned int size;
+ boolean unsignedp;
+ boolean localp;
+ struct ieee_buflist *buflist;
+{
+ unsigned int type_indx;
+ unsigned int name_indx;
+
+ if (indx != (unsigned int) -1)
+ type_indx = indx;
+ else
+ {
+ type_indx = info->type_indx;
+ ++info->type_indx;
+ }
+
+ name_indx = info->name_indx;
+ ++info->name_indx;
+
+ if (name == NULL)
+ name = "";
+
+ /* If we were given a buffer, use it; otherwise, use either the
+ local or the global type information, and make sure that the type
+ block is started. */
+ if (buflist != NULL)
+ {
+ if (! ieee_change_buffer (info, buflist))
+ return false;
+ }
+ else if (localp)
+ {
+ if (! ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types))
+ return false;
+ }
+ else
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+ }
+ else
+ {
+ if (! ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types))
+ return false;
+ }
+ else
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ }
+
+ /* Push the new type on the type stack, write out an NN record, and
+ write out the start of a TY record. The caller will then finish
+ the TY record. */
+ if (! ieee_push_type (info, type_indx, size, unsignedp, localp))
+ return false;
+
+ return (ieee_write_byte (info, (int) ieee_nn_record)
+ && ieee_write_number (info, name_indx)
+ && ieee_write_id (info, name)
+ && ieee_write_byte (info, (int) ieee_ty_record_enum)
+ && ieee_write_number (info, type_indx)
+ && ieee_write_byte (info, 0xce)
+ && ieee_write_number (info, name_indx));
+}
+
+/* Get an entry to the list of modified versions of a type. */
+
+static struct ieee_modified_type *
+ieee_get_modified_info (info, indx)
+ struct ieee_handle *info;
+ unsigned int indx;
+{
+ if (indx >= info->modified_alloc)
+ {
+ unsigned int nalloc;
+
+ nalloc = info->modified_alloc;
+ if (nalloc == 0)
+ nalloc = 16;
+ while (indx >= nalloc)
+ nalloc *= 2;
+ info->modified = ((struct ieee_modified_type *)
+ xrealloc (info->modified,
+ nalloc * sizeof *info->modified));
+ memset (info->modified + info->modified_alloc, 0,
+ (nalloc - info->modified_alloc) * sizeof *info->modified);
+ info->modified_alloc = nalloc;
+ }
+
+ return info->modified + indx;
+}
+
+/* Routines for the hash table mapping names to types. */
+
+/* Initialize an entry in the hash table. */
+
+static struct bfd_hash_entry *
+ieee_name_type_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct ieee_name_type_hash_entry *ret =
+ (struct ieee_name_type_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = ((struct ieee_name_type_hash_entry *)
+ bfd_hash_allocate (table, sizeof *ret));
+ if (ret == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct ieee_name_type_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+ if (ret)
+ {
+ /* Set local fields. */
+ ret->types = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Look up an entry in the hash table. */
+
+#define ieee_name_type_hash_lookup(table, string, create, copy) \
+ ((struct ieee_name_type_hash_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+/* Traverse the hash table. */
+
+#define ieee_name_type_hash_traverse(table, func, info) \
+ (bfd_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* The general routine to write out IEEE debugging information. */
+
+boolean
+write_ieee_debugging_info (abfd, dhandle)
+ bfd *abfd;
+ PTR dhandle;
+{
+ struct ieee_handle info;
+ asection *s;
+ const char *err;
+ struct ieee_buf *b;
+
+ memset (&info, 0, sizeof info);
+ info.abfd = abfd;
+ info.type_indx = 256;
+ info.name_indx = 32;
+
+ if (! bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc)
+ || ! bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc))
+ return false;
+
+ if (! ieee_init_buffer (&info, &info.global_types)
+ || ! ieee_init_buffer (&info, &info.data)
+ || ! ieee_init_buffer (&info, &info.types)
+ || ! ieee_init_buffer (&info, &info.vars)
+ || ! ieee_init_buffer (&info, &info.cxx)
+ || ! ieee_init_buffer (&info, &info.linenos)
+ || ! ieee_init_buffer (&info, &info.fntype)
+ || ! ieee_init_buffer (&info, &info.fnargs))
+ return false;
+
+ if (! debug_write (dhandle, &ieee_fns, (PTR) &info))
+ return false;
+
+ if (info.filename != NULL)
+ {
+ if (! ieee_finish_compilation_unit (&info))
+ return false;
+ }
+
+ /* Put any undefined tags in the global typedef information. */
+ info.error = false;
+ ieee_name_type_hash_traverse (&info.tags,
+ ieee_write_undefined_tag,
+ (PTR) &info);
+ if (info.error)
+ return false;
+
+ /* Prepend the global typedef information to the other data. */
+ if (! ieee_buffer_emptyp (&info.global_types))
+ {
+ /* The HP debugger seems to have a bug in which it ignores the
+ last entry in the global types, so we add a dummy entry. */
+ if (! ieee_change_buffer (&info, &info.global_types)
+ || ! ieee_write_byte (&info, (int) ieee_nn_record)
+ || ! ieee_write_number (&info, info.name_indx)
+ || ! ieee_write_id (&info, "")
+ || ! ieee_write_byte (&info, (int) ieee_ty_record_enum)
+ || ! ieee_write_number (&info, info.type_indx)
+ || ! ieee_write_byte (&info, 0xce)
+ || ! ieee_write_number (&info, info.name_indx)
+ || ! ieee_write_number (&info, 'P')
+ || ! ieee_write_number (&info, (int) builtin_void + 32)
+ || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
+ return false;
+
+ if (! ieee_append_buffer (&info, &info.global_types, &info.data))
+ return false;
+ info.data = info.global_types;
+ }
+
+ /* Make sure that we have declare BB11 blocks for each range in the
+ file. They are added to info->vars. */
+ info.error = false;
+ if (! ieee_init_buffer (&info, &info.vars))
+ return false;
+ bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (PTR) &info);
+ if (info.error)
+ return false;
+ if (! ieee_buffer_emptyp (&info.vars))
+ {
+ if (! ieee_change_buffer (&info, &info.vars)
+ || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
+ return false;
+
+ if (! ieee_append_buffer (&info, &info.data, &info.vars))
+ return false;
+ }
+
+ /* Now all the data is in info.data. Write it out to the BFD. We
+ normally would need to worry about whether all the other sections
+ are set up yet, but the IEEE backend will handle this particular
+ case correctly regardless. */
+ if (ieee_buffer_emptyp (&info.data))
+ {
+ /* There is no debugging information. */
+ return true;
+ }
+ err = NULL;
+ s = bfd_make_section (abfd, ".debug");
+ if (s == NULL)
+ err = "bfd_make_section";
+ if (err == NULL)
+ {
+ if (! bfd_set_section_flags (abfd, s, SEC_DEBUGGING | SEC_HAS_CONTENTS))
+ err = "bfd_set_section_flags";
+ }
+ if (err == NULL)
+ {
+ bfd_size_type size;
+
+ size = 0;
+ for (b = info.data.head; b != NULL; b = b->next)
+ size += b->c;
+ if (! bfd_set_section_size (abfd, s, size))
+ err = "bfd_set_section_size";
+ }
+ if (err == NULL)
+ {
+ file_ptr offset;
+
+ offset = 0;
+ for (b = info.data.head; b != NULL; b = b->next)
+ {
+ if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c))
+ {
+ err = "bfd_set_section_contents";
+ break;
+ }
+ offset += b->c;
+ }
+ }
+
+ if (err != NULL)
+ {
+ fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err,
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ bfd_hash_table_free (&info.typedefs.root);
+ bfd_hash_table_free (&info.tags.root);
+
+ return true;
+}
+
+/* Write out information for an undefined tag. This is called via
+ ieee_name_type_hash_traverse. */
+
+static boolean
+ieee_write_undefined_tag (h, p)
+ struct ieee_name_type_hash_entry *h;
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_name_type *nt;
+
+ for (nt = h->types; nt != NULL; nt = nt->next)
+ {
+ unsigned int name_indx;
+ char code;
+
+ if (nt->kind == DEBUG_KIND_ILLEGAL)
+ continue;
+
+ if (ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ {
+ info->error = true;
+ return false;
+ }
+ }
+ else
+ {
+ if (! ieee_change_buffer (info, &info->global_types))
+ {
+ info->error = true;
+ return false;
+ }
+ }
+
+ name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, name_indx)
+ || ! ieee_write_id (info, nt->type.name)
+ || ! ieee_write_byte (info, (int) ieee_ty_record_enum)
+ || ! ieee_write_number (info, nt->type.indx)
+ || ! ieee_write_byte (info, 0xce)
+ || ! ieee_write_number (info, name_indx))
+ {
+ info->error = true;
+ return false;
+ }
+
+ switch (nt->kind)
+ {
+ default:
+ abort ();
+ info->error = true;
+ return false;
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_CLASS:
+ code = 'S';
+ break;
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_UNION_CLASS:
+ code = 'U';
+ break;
+ case DEBUG_KIND_ENUM:
+ code = 'E';
+ break;
+ }
+ if (! ieee_write_number (info, code)
+ || ! ieee_write_number (info, 0))
+ {
+ info->error = true;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Start writing out information for a compilation unit. */
+
+static boolean
+ieee_start_compilation_unit (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ const char *modname;
+ char *c, *s;
+ unsigned int nindx;
+
+ if (info->filename != NULL)
+ {
+ if (! ieee_finish_compilation_unit (info))
+ return false;
+ }
+
+ info->filename = filename;
+ modname = strrchr (filename, '/');
+ if (modname != NULL)
+ ++modname;
+ else
+ {
+ modname = strrchr (filename, '\\');
+ if (modname != NULL)
+ ++modname;
+ else
+ modname = filename;
+ }
+ c = xstrdup (modname);
+ s = strrchr (c, '.');
+ if (s != NULL)
+ *s = '\0';
+ info->modname = c;
+
+ if (! ieee_init_buffer (info, &info->types)
+ || ! ieee_init_buffer (info, &info->vars)
+ || ! ieee_init_buffer (info, &info->cxx)
+ || ! ieee_init_buffer (info, &info->linenos))
+ return false;
+ info->ranges = NULL;
+
+ /* Always include a BB1 and a BB3 block. That is what the output of
+ the MRI linker seems to look like. */
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 3)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+
+ return true;
+}
+
+/* Finish up a compilation unit. */
+
+static boolean
+ieee_finish_compilation_unit (info)
+ struct ieee_handle *info;
+{
+ struct ieee_range *r;
+
+ if (! ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ }
+
+ if (! ieee_buffer_emptyp (&info->cxx))
+ {
+ /* Append any C++ information to the global function and
+ variable information. */
+ assert (! ieee_buffer_emptyp (&info->vars));
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ /* We put the pmisc records in a dummy procedure, just as the
+ MRI compiler does. */
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 6)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "__XRYCPP")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, info->highaddr - 1)
+ || ! ieee_append_buffer (info, &info->vars, &info->cxx)
+ || ! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, info->highaddr - 1))
+ return false;
+ }
+
+ if (! ieee_buffer_emptyp (&info->vars))
+ {
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ }
+
+ if (info->pending_lineno_filename != NULL)
+ {
+ /* Force out the pending line number. */
+ if (! ieee_lineno ((PTR) info, (const char *) NULL, 0, (bfd_vma) -1))
+ return false;
+ }
+ if (! ieee_buffer_emptyp (&info->linenos))
+ {
+ if (! ieee_change_buffer (info, &info->linenos)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ if (strcmp (info->filename, info->lineno_filename) != 0)
+ {
+ /* We were not in the main file. We just closed the
+ included line number block, and now we must close the
+ main line number block. */
+ if (! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ }
+ }
+
+ if (! ieee_append_buffer (info, &info->data, &info->types)
+ || ! ieee_append_buffer (info, &info->data, &info->vars)
+ || ! ieee_append_buffer (info, &info->data, &info->linenos))
+ return false;
+
+ /* Build BB10/BB11 blocks based on the ranges we recorded. */
+ if (! ieee_change_buffer (info, &info->data))
+ return false;
+
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 10)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "GNU objcopy"))
+ return false;
+
+ for (r = info->ranges; r != NULL; r = r->next)
+ {
+ bfd_vma low, high;
+ asection *s;
+ int kind;
+
+ low = r->low;
+ high = r->high;
+
+ /* Find the section corresponding to this range. */
+ for (s = info->abfd->sections; s != NULL; s = s->next)
+ {
+ if (bfd_get_section_vma (info->abfd, s) <= low
+ && high <= (bfd_get_section_vma (info->abfd, s)
+ + bfd_section_size (info->abfd, s)))
+ break;
+ }
+
+ if (s == NULL)
+ {
+ /* Just ignore this range. */
+ continue;
+ }
+
+ /* Coalesce ranges if it seems reasonable. */
+ while (r->next != NULL
+ && high + 0x1000 >= r->next->low
+ && (r->next->high
+ <= (bfd_get_section_vma (info->abfd, s)
+ + bfd_section_size (info->abfd, s))))
+ {
+ r = r->next;
+ high = r->high;
+ }
+
+ if ((s->flags & SEC_CODE) != 0)
+ kind = 1;
+ else if ((s->flags & SEC_READONLY) != 0)
+ kind = 3;
+ else
+ kind = 2;
+
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 11)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, kind)
+ || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE)
+ || ! ieee_write_number (info, low)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, high - low))
+ return false;
+
+ /* Add this range to the list of global ranges. */
+ if (! ieee_add_range (info, true, low, high))
+ return false;
+ }
+
+ if (! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+
+ return true;
+}
+
+/* Add BB11 blocks describing each range that we have not already
+ described. */
+
+static void
+ieee_add_bb11_blocks (abfd, sec, data)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+{
+ struct ieee_handle *info = (struct ieee_handle *) data;
+ bfd_vma low, high;
+ struct ieee_range *r;
+
+ low = bfd_get_section_vma (abfd, sec);
+ high = low + bfd_section_size (abfd, sec);
+
+ /* Find the first range at or after this section. The ranges are
+ sorted by address. */
+ for (r = info->global_ranges; r != NULL; r = r->next)
+ if (r->high > low)
+ break;
+
+ while (low < high)
+ {
+ if (r == NULL || r->low >= high)
+ {
+ if (! ieee_add_bb11 (info, sec, low, high))
+ info->error = true;
+ return;
+ }
+
+ if (low < r->low
+ && r->low - low > 0x100)
+ {
+ if (! ieee_add_bb11 (info, sec, low, r->low))
+ {
+ info->error = true;
+ return;
+ }
+ }
+ low = r->high;
+
+ r = r->next;
+ }
+}
+
+/* Add a single BB11 block for a range. We add it to info->vars. */
+
+static boolean
+ieee_add_bb11 (info, sec, low, high)
+ struct ieee_handle *info;
+ asection *sec;
+ bfd_vma low;
+ bfd_vma high;
+{
+ int kind;
+
+ if (! ieee_buffer_emptyp (&info->vars))
+ {
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+ }
+ else
+ {
+ const char *filename, *modname;
+ char *c, *s;
+
+ /* Start the enclosing BB10 block. */
+ filename = bfd_get_filename (info->abfd);
+ modname = strrchr (filename, '/');
+ if (modname != NULL)
+ ++modname;
+ else
+ {
+ modname = strrchr (filename, '\\');
+ if (modname != NULL)
+ ++modname;
+ else
+ modname = filename;
+ }
+ c = xstrdup (modname);
+ s = strrchr (c, '.');
+ if (s != NULL)
+ *s = '\0';
+
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 10)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, c)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "GNU objcopy"))
+ return false;
+
+ free (c);
+ }
+
+ if ((sec->flags & SEC_CODE) != 0)
+ kind = 1;
+ else if ((sec->flags & SEC_READONLY) != 0)
+ kind = 3;
+ else
+ kind = 2;
+
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 11)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, kind)
+ || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE)
+ || ! ieee_write_number (info, low)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, high - low))
+ return false;
+
+ return true;
+}
+
+/* Start recording information from a particular source file. This is
+ used to record which file defined which types, variables, etc. It
+ is not used for line numbers, since the lineno entry point passes
+ down the file name anyhow. IEEE debugging information doesn't seem
+ to store this information anywhere. */
+
+/*ARGSUSED*/
+static boolean
+ieee_start_source (p, filename)
+ PTR p;
+ const char *filename;
+{
+ return true;
+}
+
+/* Make an empty type. */
+
+static boolean
+ieee_empty_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_push_type (info, (int) builtin_unknown, 0, false, false);
+}
+
+/* Make a void type. */
+
+static boolean
+ieee_void_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_push_type (info, (int) builtin_void, 0, false, false);
+}
+
+/* Make an integer type. */
+
+static boolean
+ieee_int_type (p, size, unsignedp)
+ PTR p;
+ unsigned int size;
+ boolean unsignedp;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int indx;
+
+ switch (size)
+ {
+ case 1:
+ indx = (int) builtin_signed_char;
+ break;
+ case 2:
+ indx = (int) builtin_signed_short_int;
+ break;
+ case 4:
+ indx = (int) builtin_signed_long;
+ break;
+ case 8:
+ indx = (int) builtin_signed_long_long;
+ break;
+ default:
+ fprintf (stderr, "IEEE unsupported integer type size %u\n", size);
+ return false;
+ }
+
+ if (unsignedp)
+ ++indx;
+
+ return ieee_push_type (info, indx, size, unsignedp, false);
+}
+
+/* Make a floating point type. */
+
+static boolean
+ieee_float_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int indx;
+
+ switch (size)
+ {
+ case 4:
+ indx = (int) builtin_float;
+ break;
+ case 8:
+ indx = (int) builtin_double;
+ break;
+ case 12:
+ /* FIXME: This size really depends upon the processor. */
+ indx = (int) builtin_long_double;
+ break;
+ case 16:
+ indx = (int) builtin_long_long_double;
+ break;
+ default:
+ fprintf (stderr, "IEEE unsupported float type size %u\n", size);
+ return false;
+ }
+
+ return ieee_push_type (info, indx, size, false, false);
+}
+
+/* Make a complex type. */
+
+static boolean
+ieee_complex_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ char code;
+
+ switch (size)
+ {
+ case 4:
+ if (info->complex_float_index != 0)
+ return ieee_push_type (info, info->complex_float_index, size * 2,
+ false, false);
+ code = 'c';
+ break;
+ case 12:
+ case 16:
+ /* These cases can be output by gcc -gstabs. Outputting the
+ wrong type is better than crashing. */
+ case 8:
+ if (info->complex_double_index != 0)
+ return ieee_push_type (info, info->complex_double_index, size * 2,
+ false, false);
+ code = 'd';
+ break;
+ default:
+ fprintf (stderr, "IEEE unsupported complex type size %u\n", size);
+ return false;
+ }
+
+ /* FIXME: I don't know what the string is for. */
+ if (! ieee_define_type (info, size * 2, false, false)
+ || ! ieee_write_number (info, code)
+ || ! ieee_write_id (info, ""))
+ return false;
+
+ if (size == 4)
+ info->complex_float_index = info->type_stack->type.indx;
+ else
+ info->complex_double_index = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a boolean type. IEEE doesn't support these, so we just make
+ an integer type instead. */
+
+static boolean
+ieee_bool_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ return ieee_int_type (p, size, true);
+}
+
+/* Make an enumeration. */
+
+static boolean
+ieee_enum_type (p, tag, names, vals)
+ PTR p;
+ const char *tag;
+ const char **names;
+ bfd_signed_vma *vals;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_defined_enum *e;
+ boolean localp, simple;
+ unsigned int indx;
+ int i = 0;
+
+ localp = false;
+ indx = (unsigned int) -1;
+ for (e = info->enums; e != NULL; e = e->next)
+ {
+ if (tag == NULL)
+ {
+ if (e->tag != NULL)
+ continue;
+ }
+ else
+ {
+ if (e->tag == NULL
+ || tag[0] != e->tag[0]
+ || strcmp (tag, e->tag) != 0)
+ continue;
+ }
+
+ if (! e->defined)
+ {
+ /* This enum tag has been seen but not defined. */
+ indx = e->indx;
+ break;
+ }
+
+ if (names != NULL && e->names != NULL)
+ {
+ for (i = 0; names[i] != NULL && e->names[i] != NULL; i++)
+ {
+ if (names[i][0] != e->names[i][0]
+ || vals[i] != e->vals[i]
+ || strcmp (names[i], e->names[i]) != 0)
+ break;
+ }
+ }
+
+ if ((names == NULL && e->names == NULL)
+ || (names != NULL
+ && e->names != NULL
+ && names[i] == NULL
+ && e->names[i] == NULL))
+ {
+ /* We've seen this enum before. */
+ return ieee_push_type (info, e->indx, 0, true, false);
+ }
+
+ if (tag != NULL)
+ {
+ /* We've already seen an enum of the same name, so we must make
+ sure to output this one locally. */
+ localp = true;
+ break;
+ }
+ }
+
+ /* If this is a simple enumeration, in which the values start at 0
+ and always increment by 1, we can use type E. Otherwise we must
+ use type N. */
+
+ simple = true;
+ if (names != NULL)
+ {
+ for (i = 0; names[i] != NULL; i++)
+ {
+ if (vals[i] != i)
+ {
+ simple = false;
+ break;
+ }
+ }
+ }
+
+ if (! ieee_define_named_type (info, tag, indx, 0, true, localp,
+ (struct ieee_buflist *) NULL)
+ || ! ieee_write_number (info, simple ? 'E' : 'N'))
+ return false;
+ if (simple)
+ {
+ /* FIXME: This is supposed to be the enumeration size, but we
+ don't store that. */
+ if (! ieee_write_number (info, 4))
+ return false;
+ }
+ if (names != NULL)
+ {
+ for (i = 0; names[i] != NULL; i++)
+ {
+ if (! ieee_write_id (info, names[i]))
+ return false;
+ if (! simple)
+ {
+ if (! ieee_write_number (info, vals[i]))
+ return false;
+ }
+ }
+ }
+
+ if (! localp)
+ {
+ if (indx == (unsigned int) -1)
+ {
+ e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+ e->indx = info->type_stack->type.indx;
+ e->tag = tag;
+
+ e->next = info->enums;
+ info->enums = e;
+ }
+
+ e->names = names;
+ e->vals = vals;
+ e->defined = true;
+ }
+
+ return true;
+}
+
+/* Make a pointer type. */
+
+static boolean
+ieee_pointer_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ unsigned int indx;
+ struct ieee_modified_type *m = NULL;
+
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ /* A pointer to a simple builtin type can be obtained by adding 32.
+ FIXME: Will this be a short pointer, and will that matter? */
+ if (indx < 32)
+ return ieee_push_type (info, indx + 32, 0, true, false);
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (p, indx);
+ if (m == NULL)
+ return false;
+
+ /* FIXME: The size should depend upon the architecture. */
+ if (m->pointer > 0)
+ return ieee_push_type (info, m->pointer, 4, true, false);
+ }
+
+ if (! ieee_define_type (info, 4, true, localp)
+ || ! ieee_write_number (info, 'P')
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ if (! localp)
+ m->pointer = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a function type. This will be called for a method, but we
+ don't want to actually add it to the type table in that case. We
+ handle this by defining the type in a private buffer, and only
+ adding that buffer to the typedef block if we are going to use it. */
+
+static boolean
+ieee_function_type (p, argcount, varargs)
+ PTR p;
+ int argcount;
+ boolean varargs;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ unsigned int *args = NULL;
+ int i;
+ unsigned int retindx;
+ struct ieee_buflist fndef;
+ struct ieee_modified_type *m;
+
+ localp = false;
+
+ if (argcount > 0)
+ {
+ args = (unsigned int *) xmalloc (argcount * sizeof *args);
+ for (i = argcount - 1; i >= 0; i--)
+ {
+ if (info->type_stack->type.localp)
+ localp = true;
+ args[i] = ieee_pop_type (info);
+ }
+ }
+ else if (argcount < 0)
+ varargs = false;
+
+ if (info->type_stack->type.localp)
+ localp = true;
+ retindx = ieee_pop_type (info);
+
+ m = NULL;
+ if (argcount < 0 && ! localp)
+ {
+ m = ieee_get_modified_info (p, retindx);
+ if (m == NULL)
+ return false;
+
+ if (m->function > 0)
+ return ieee_push_type (info, m->function, 0, true, false);
+ }
+
+ /* An attribute of 0x41 means that the frame and push mask are
+ unknown. */
+ if (! ieee_init_buffer (info, &fndef)
+ || ! ieee_define_named_type (info, (const char *) NULL,
+ (unsigned int) -1, 0, true, localp,
+ &fndef)
+ || ! ieee_write_number (info, 'x')
+ || ! ieee_write_number (info, 0x41)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, retindx)
+ || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0)))
+ return false;
+ if (argcount > 0)
+ {
+ for (i = 0; i < argcount; i++)
+ if (! ieee_write_number (info, args[i]))
+ return false;
+ free (args);
+ }
+ if (varargs)
+ {
+ /* A varargs function is represented by writing out the last
+ argument as type void *, although this makes little sense. */
+ if (! ieee_write_number (info, (bfd_vma) builtin_void + 32))
+ return false;
+ }
+
+ if (! ieee_write_number (info, 0))
+ return false;
+
+ /* We wrote the information into fndef, in case we don't need it.
+ It will be appended to info->types by ieee_pop_type. */
+ info->type_stack->type.fndef = fndef;
+
+ if (m != NULL)
+ m->function = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a reference type. */
+
+static boolean
+ieee_reference_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* IEEE appears to record a normal pointer type, and then use a
+ pmisc record to indicate that it is really a reference. */
+
+ if (! ieee_pointer_type (p))
+ return false;
+ info->type_stack->type.referencep = true;
+ return true;
+}
+
+/* Make a range type. */
+
+static boolean
+ieee_range_type (p, low, high)
+ PTR p;
+ bfd_signed_vma low;
+ bfd_signed_vma high;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp, localp;
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ localp = info->type_stack->type.localp;
+ ieee_pop_unused_type (info);
+ return (ieee_define_type (info, size, unsignedp, localp)
+ && ieee_write_number (info, 'R')
+ && ieee_write_number (info, (bfd_vma) low)
+ && ieee_write_number (info, (bfd_vma) high)
+ && ieee_write_number (info, unsignedp ? 0 : 1)
+ && ieee_write_number (info, size));
+}
+
+/* Make an array type. */
+
+/*ARGSUSED*/
+static boolean
+ieee_array_type (p, low, high, stringp)
+ PTR p;
+ bfd_signed_vma low;
+ bfd_signed_vma high;
+ boolean stringp;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int eleindx;
+ boolean localp;
+ unsigned int size;
+ struct ieee_modified_type *m = NULL;
+ struct ieee_modified_array_type *a;
+
+ /* IEEE does not store the range, so we just ignore it. */
+ ieee_pop_unused_type (info);
+ localp = info->type_stack->type.localp;
+ size = info->type_stack->type.size;
+ eleindx = ieee_pop_type (info);
+
+ /* If we don't know the range, treat the size as exactly one
+ element. */
+ if (low < high)
+ size *= (high - low) + 1;
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (info, eleindx);
+ if (m == NULL)
+ return false;
+
+ for (a = m->arrays; a != NULL; a = a->next)
+ {
+ if (a->low == low && a->high == high)
+ return ieee_push_type (info, a->indx, size, false, false);
+ }
+ }
+
+ if (! ieee_define_type (info, size, false, localp)
+ || ! ieee_write_number (info, low == 0 ? 'Z' : 'C')
+ || ! ieee_write_number (info, eleindx))
+ return false;
+ if (low != 0)
+ {
+ if (! ieee_write_number (info, low))
+ return false;
+ }
+
+ if (! ieee_write_number (info, high + 1))
+ return false;
+
+ if (! localp)
+ {
+ a = (struct ieee_modified_array_type *) xmalloc (sizeof *a);
+ memset (a, 0, sizeof *a);
+
+ a->indx = info->type_stack->type.indx;
+ a->low = low;
+ a->high = high;
+
+ a->next = m->arrays;
+ m->arrays = a;
+ }
+
+ return true;
+}
+
+/* Make a set type. */
+
+static boolean
+ieee_set_type (p, bitstringp)
+ PTR p;
+ boolean bitstringp;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ unsigned int eleindx;
+
+ localp = info->type_stack->type.localp;
+ eleindx = ieee_pop_type (info);
+
+ /* FIXME: We don't know the size, so we just use 4. */
+
+ return (ieee_define_type (info, 0, true, localp)
+ && ieee_write_number (info, 's')
+ && ieee_write_number (info, 4)
+ && ieee_write_number (info, eleindx));
+}
+
+/* Make an offset type. */
+
+static boolean
+ieee_offset_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int targetindx, baseindx;
+
+ targetindx = ieee_pop_type (info);
+ baseindx = ieee_pop_type (info);
+
+ /* FIXME: The MRI C++ compiler does not appear to generate any
+ useful type information about an offset type. It just records a
+ pointer to member as an integer. The MRI/HP IEEE spec does
+ describe a pmisc record which can be used for a pointer to
+ member. Unfortunately, it does not describe the target type,
+ which seems pretty important. I'm going to punt this for now. */
+
+ return ieee_int_type (p, 4, true);
+}
+
+/* Make a method type. */
+
+static boolean
+ieee_method_type (p, domain, argcount, varargs)
+ PTR p;
+ boolean domain;
+ int argcount;
+ boolean varargs;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a
+ method, but the definition is incomplete. We just output an 'x'
+ type. */
+
+ if (domain)
+ ieee_pop_unused_type (info);
+
+ return ieee_function_type (p, argcount, varargs);
+}
+
+/* Make a const qualified type. */
+
+static boolean
+ieee_const_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp, localp;
+ unsigned int indx;
+ struct ieee_modified_type *m = NULL;
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (info, indx);
+ if (m == NULL)
+ return false;
+
+ if (m->const_qualified > 0)
+ return ieee_push_type (info, m->const_qualified, size, unsignedp,
+ false);
+ }
+
+ if (! ieee_define_type (info, size, unsignedp, localp)
+ || ! ieee_write_number (info, 'n')
+ || ! ieee_write_number (info, 1)
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ if (! localp)
+ m->const_qualified = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a volatile qualified type. */
+
+static boolean
+ieee_volatile_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp, localp;
+ unsigned int indx;
+ struct ieee_modified_type *m = NULL;
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (info, indx);
+ if (m == NULL)
+ return false;
+
+ if (m->volatile_qualified > 0)
+ return ieee_push_type (info, m->volatile_qualified, size, unsignedp,
+ false);
+ }
+
+ if (! ieee_define_type (info, size, unsignedp, localp)
+ || ! ieee_write_number (info, 'n')
+ || ! ieee_write_number (info, 2)
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ if (! localp)
+ m->volatile_qualified = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Convert an enum debug_visibility into a CXXFLAGS value. */
+
+static unsigned int
+ieee_vis_to_flags (visibility)
+ enum debug_visibility visibility;
+{
+ switch (visibility)
+ {
+ default:
+ abort ();
+ case DEBUG_VISIBILITY_PUBLIC:
+ return CXXFLAGS_VISIBILITY_PUBLIC;
+ case DEBUG_VISIBILITY_PRIVATE:
+ return CXXFLAGS_VISIBILITY_PRIVATE;
+ case DEBUG_VISIBILITY_PROTECTED:
+ return CXXFLAGS_VISIBILITY_PROTECTED;
+ }
+ /*NOTREACHED*/
+}
+
+/* Start defining a struct type. We build it in the strdef field on
+ the stack, to avoid confusing type definitions required by the
+ fields with the struct type itself. */
+
+static boolean
+ieee_start_struct_type (p, tag, id, structp, size)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp, ignorep;
+ boolean copy;
+ char ab[20];
+ const char *look;
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt, *ntlook;
+ struct ieee_buflist strdef;
+
+ localp = false;
+ ignorep = false;
+
+ /* We need to create a tag for internal use even if we don't want
+ one for external use. This will let us refer to an anonymous
+ struct. */
+ if (tag != NULL)
+ {
+ look = tag;
+ copy = false;
+ }
+ else
+ {
+ sprintf (ab, "__anon%u", id);
+ look = ab;
+ copy = true;
+ }
+
+ /* If we already have references to the tag, we must use the
+ existing type index. */
+ h = ieee_name_type_hash_lookup (&info->tags, look, true, copy);
+ if (h == NULL)
+ return false;
+
+ nt = NULL;
+ for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next)
+ {
+ if (ntlook->id == id)
+ nt = ntlook;
+ else if (! ntlook->type.localp)
+ {
+ /* We are creating a duplicate definition of a globally
+ defined tag. Force it to be local to avoid
+ confusion. */
+ localp = true;
+ }
+ }
+
+ if (nt != NULL)
+ {
+ assert (localp == nt->type.localp);
+ if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp)
+ {
+ /* We've already seen a global definition of the type.
+ Ignore this new definition. */
+ ignorep = true;
+ }
+ }
+ else
+ {
+ nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
+ memset (nt, 0, sizeof *nt);
+ nt->id = id;
+ nt->type.name = h->root.string;
+ nt->next = h->types;
+ h->types = nt;
+ nt->type.indx = info->type_indx;
+ ++info->type_indx;
+ }
+
+ nt->kind = DEBUG_KIND_ILLEGAL;
+
+ if (! ieee_init_buffer (info, &strdef)
+ || ! ieee_define_named_type (info, tag, nt->type.indx, size, true,
+ localp, &strdef)
+ || ! ieee_write_number (info, structp ? 'S' : 'U')
+ || ! ieee_write_number (info, size))
+ return false;
+
+ if (! ignorep)
+ {
+ const char *hold;
+
+ /* We never want nt->type.name to be NULL. We want the rest of
+ the type to be the object set up on the type stack; it will
+ have a NULL name if tag is NULL. */
+ hold = nt->type.name;
+ nt->type = info->type_stack->type;
+ nt->type.name = hold;
+ }
+
+ info->type_stack->type.name = tag;
+ info->type_stack->type.strdef = strdef;
+ info->type_stack->type.ignorep = ignorep;
+
+ return true;
+}
+
+/* Add a field to a struct. */
+
+static boolean
+ieee_struct_field (p, name, bitpos, bitsize, visibility)
+ PTR p;
+ const char *name;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+ enum debug_visibility visibility;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp;
+ boolean referencep;
+ boolean localp;
+ unsigned int indx;
+ bfd_vma offset;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->next != NULL
+ && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
+
+ /* If we are ignoring this struct definition, just pop and ignore
+ the type. */
+ if (info->type_stack->next->type.ignorep)
+ {
+ ieee_pop_unused_type (info);
+ return true;
+ }
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ referencep = info->type_stack->type.referencep;
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ if (localp)
+ info->type_stack->type.localp = true;
+
+ if (info->type_stack->type.classdef != NULL)
+ {
+ unsigned int flags;
+ unsigned int nindx;
+
+ /* This is a class. We must add a description of this field to
+ the class records we are building. */
+
+ flags = ieee_vis_to_flags (visibility);
+ nindx = info->type_stack->type.classdef->indx;
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'd')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx, name)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 4;
+
+ if (referencep)
+ {
+ unsigned int nindx;
+
+ /* We need to output a record recording that this field is
+ really of reference type. We put this on the refs field
+ of classdef, so that it can be appended to the C++
+ records after the class is defined. */
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->refs)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, 4)
+ || ! ieee_write_asn (info, nindx, 'R')
+ || ! ieee_write_asn (info, nindx, 3)
+ || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ }
+ }
+
+ /* If the bitsize doesn't match the expected size, we need to output
+ a bitfield type. */
+ if (size == 0 || bitsize == 0 || bitsize == size * 8)
+ offset = bitpos / 8;
+ else
+ {
+ if (! ieee_define_type (info, 0, unsignedp,
+ info->type_stack->type.localp)
+ || ! ieee_write_number (info, 'g')
+ || ! ieee_write_number (info, unsignedp ? 0 : 1)
+ || ! ieee_write_number (info, bitsize)
+ || ! ieee_write_number (info, indx))
+ return false;
+ indx = ieee_pop_type (info);
+ offset = bitpos;
+ }
+
+ /* Switch to the struct we are building in order to output this
+ field definition. */
+ return (ieee_change_buffer (info, &info->type_stack->type.strdef)
+ && ieee_write_id (info, name)
+ && ieee_write_number (info, indx)
+ && ieee_write_number (info, offset));
+}
+
+/* Finish up a struct type. */
+
+static boolean
+ieee_end_struct_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_buflist *pb;
+
+ assert (info->type_stack != NULL
+ && ! ieee_buffer_emptyp (&info->type_stack->type.strdef));
+
+ /* If we were ignoring this struct definition because it was a
+ duplicate defintion, just through away whatever bytes we have
+ accumulated. Leave the type on the stack. */
+ if (info->type_stack->type.ignorep)
+ return true;
+
+ /* If this is not a duplicate definition of this tag, then localp
+ will be false, and we can put it in the global type block.
+ FIXME: We should avoid outputting duplicate definitions which are
+ the same. */
+ if (! info->type_stack->type.localp)
+ {
+ /* Make sure we have started the global type block. */
+ if (ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ pb = &info->global_types;
+ }
+ else
+ {
+ /* Make sure we have started the types block. */
+ if (ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+ pb = &info->types;
+ }
+
+ /* Append the struct definition to the types. */
+ if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef)
+ || ! ieee_init_buffer (info, &info->type_stack->type.strdef))
+ return false;
+
+ /* Leave the struct on the type stack. */
+
+ return true;
+}
+
+/* Start a class type. */
+
+static boolean
+ieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+ boolean vptr;
+ boolean ownvptr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ const char *vclass;
+ struct ieee_buflist pmiscbuf;
+ unsigned int indx;
+ struct ieee_type_class *classdef;
+
+ /* A C++ class is output as a C++ struct along with a set of pmisc
+ records describing the class. */
+
+ /* We need to have a name so that we can associate the struct and
+ the class. */
+ if (tag == NULL)
+ {
+ char *t;
+
+ t = (char *) xmalloc (20);
+ sprintf (t, "__anon%u", id);
+ tag = t;
+ }
+
+ /* We can't write out the virtual table information until we have
+ finished the class, because we don't know the virtual table size.
+ We get the size from the largest voffset we see. */
+ vclass = NULL;
+ if (vptr && ! ownvptr)
+ {
+ vclass = info->type_stack->type.name;
+ assert (vclass != NULL);
+ /* We don't call ieee_pop_unused_type, since the class should
+ get defined. */
+ (void) ieee_pop_type (info);
+ }
+
+ if (! ieee_start_struct_type (p, tag, id, structp, size))
+ return false;
+
+ indx = info->name_indx;
+ ++info->name_indx;
+
+ /* We write out pmisc records into the classdef field. We will
+ write out the pmisc start after we know the number of records we
+ need. */
+ if (! ieee_init_buffer (info, &pmiscbuf)
+ || ! ieee_change_buffer (info, &pmiscbuf)
+ || ! ieee_write_asn (info, indx, 'T')
+ || ! ieee_write_asn (info, indx, structp ? 'o' : 'u')
+ || ! ieee_write_atn65 (info, indx, tag))
+ return false;
+
+ classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef);
+ memset (classdef, 0, sizeof *classdef);
+
+ classdef->indx = indx;
+ classdef->pmiscbuf = pmiscbuf;
+ classdef->pmisccount = 3;
+ classdef->vclass = vclass;
+ classdef->ownvptr = ownvptr;
+
+ info->type_stack->type.classdef = classdef;
+
+ return true;
+}
+
+/* Add a static member to a class. */
+
+static boolean
+ieee_class_static_member (p, name, physname, visibility)
+ PTR p;
+ const char *name;
+ const char *physname;
+ enum debug_visibility visibility;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int flags;
+ unsigned int nindx;
+
+ /* We don't care about the type. Hopefully there will be a call to
+ ieee_variable declaring the physical name and the type, since
+ that is where an IEEE consumer must get the type. */
+ ieee_pop_unused_type (info);
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL);
+
+ flags = ieee_vis_to_flags (visibility);
+ flags |= CXXFLAGS_STATIC;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'd')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx, name)
+ || ! ieee_write_atn65 (info, nindx, physname))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 4;
+
+ return true;
+}
+
+/* Add a base class to a class. */
+
+static boolean
+ieee_class_baseclass (p, bitpos, virtual, visibility)
+ PTR p;
+ bfd_vma bitpos;
+ boolean virtual;
+ enum debug_visibility visibility;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ const char *bname;
+ boolean localp;
+ unsigned int bindx;
+ char *fname;
+ unsigned int flags;
+ unsigned int nindx;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.name != NULL
+ && info->type_stack->next != NULL
+ && info->type_stack->next->type.classdef != NULL
+ && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
+
+ bname = info->type_stack->type.name;
+ localp = info->type_stack->type.localp;
+ bindx = ieee_pop_type (info);
+
+ /* We are currently defining both a struct and a class. We must
+ write out a field definition in the struct which holds the base
+ class. The stabs debugging reader will create a field named
+ _vb$CLASS for a virtual base class, so we just use that. FIXME:
+ we should not depend upon a detail of stabs debugging. */
+ if (virtual)
+ {
+ fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$");
+ sprintf (fname, "_vb$%s", bname);
+ flags = BASEFLAGS_VIRTUAL;
+ }
+ else
+ {
+ if (localp)
+ info->type_stack->type.localp = true;
+
+ fname = (char *) xmalloc (strlen (bname) + sizeof "_b$");
+ sprintf (fname, "_b$%s", bname);
+
+ if (! ieee_change_buffer (info, &info->type_stack->type.strdef)
+ || ! ieee_write_id (info, fname)
+ || ! ieee_write_number (info, bindx)
+ || ! ieee_write_number (info, bitpos / 8))
+ return false;
+ flags = 0;
+ }
+
+ if (visibility == DEBUG_VISIBILITY_PRIVATE)
+ flags |= BASEFLAGS_PRIVATE;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'b')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx, bname)
+ || ! ieee_write_asn (info, nindx, 0)
+ || ! ieee_write_atn65 (info, nindx, fname))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 5;
+
+ free (fname);
+
+ return true;
+}
+
+/* Start building a method for a class. */
+
+static boolean
+ieee_class_start_method (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL
+ && info->type_stack->type.classdef->method == NULL);
+
+ info->type_stack->type.classdef->method = name;
+
+ return true;
+}
+
+/* Define a new method variant, either static or not. */
+
+static boolean
+ieee_class_method_var (info, physname, visibility, staticp, constp,
+ volatilep, voffset, context)
+ struct ieee_handle *info;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean staticp;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean context;
+{
+ unsigned int flags;
+ unsigned int nindx;
+ boolean virtual;
+
+ /* We don't need the type of the method. An IEEE consumer which
+ wants the type must track down the function by the physical name
+ and get the type from that. */
+ ieee_pop_unused_type (info);
+
+ /* We don't use the context. FIXME: We probably ought to use it to
+ adjust the voffset somehow, but I don't really know how. */
+ if (context)
+ ieee_pop_unused_type (info);
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL
+ && info->type_stack->type.classdef->method != NULL);
+
+ flags = ieee_vis_to_flags (visibility);
+
+ /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR,
+ CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */
+
+ if (staticp)
+ flags |= CXXFLAGS_STATIC;
+ if (constp)
+ flags |= CXXFLAGS_CONST;
+ if (volatilep)
+ flags |= CXXFLAGS_VOLATILE;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ virtual = context || voffset > 0;
+
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx,
+ info->type_stack->type.classdef->method)
+ || ! ieee_write_atn65 (info, nindx, physname))
+ return false;
+
+ if (virtual)
+ {
+ if (voffset > info->type_stack->type.classdef->voffset)
+ info->type_stack->type.classdef->voffset = voffset;
+ if (! ieee_write_asn (info, nindx, voffset))
+ return false;
+ ++info->type_stack->type.classdef->pmisccount;
+ }
+
+ if (! ieee_write_asn (info, nindx, 0))
+ return false;
+
+ info->type_stack->type.classdef->pmisccount += 5;
+
+ return true;
+}
+
+/* Define a new method variant. */
+
+static boolean
+ieee_class_method_variant (p, physname, visibility, constp, volatilep,
+ voffset, context)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean context;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_class_method_var (info, physname, visibility, false, constp,
+ volatilep, voffset, context);
+}
+
+/* Define a new static method variant. */
+
+static boolean
+ieee_class_static_method_variant (p, physname, visibility, constp, volatilep)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_class_method_var (info, physname, visibility, true, constp,
+ volatilep, 0, false);
+}
+
+/* Finish up a method. */
+
+static boolean
+ieee_class_end_method (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL
+ && info->type_stack->type.classdef->method != NULL);
+
+ info->type_stack->type.classdef->method = NULL;
+
+ return true;
+}
+
+/* Finish up a class. */
+
+static boolean
+ieee_end_class_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int nindx;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL);
+
+ /* If we were ignoring this class definition because it was a
+ duplicate definition, just through away whatever bytes we have
+ accumulated. Leave the type on the stack. */
+ if (info->type_stack->type.ignorep)
+ return true;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ /* If we have a virtual table, we can write out the information now. */
+ if (info->type_stack->type.classdef->vclass != NULL
+ || info->type_stack->type.classdef->ownvptr)
+ {
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'z')
+ || ! ieee_write_atn65 (info, nindx, "")
+ || ! ieee_write_asn (info, nindx,
+ info->type_stack->type.classdef->voffset))
+ return false;
+ if (info->type_stack->type.classdef->ownvptr)
+ {
+ if (! ieee_write_atn65 (info, nindx, ""))
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_atn65 (info, nindx,
+ info->type_stack->type.classdef->vclass))
+ return false;
+ }
+ if (! ieee_write_asn (info, nindx, 0))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 5;
+ }
+
+ /* Now that we know the number of pmisc records, we can write out
+ the atn62 which starts the pmisc records, and append them to the
+ C++ buffers. */
+
+ if (! ieee_change_buffer (info, &info->cxx)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info,
+ info->type_stack->type.classdef->pmisccount))
+ return false;
+
+ if (! ieee_append_buffer (info, &info->cxx,
+ &info->type_stack->type.classdef->pmiscbuf))
+ return false;
+ if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs))
+ {
+ if (! ieee_append_buffer (info, &info->cxx,
+ &info->type_stack->type.classdef->refs))
+ return false;
+ }
+
+ return ieee_end_struct_type (p);
+}
+
+/* Push a previously seen typedef onto the type stack. */
+
+static boolean
+ieee_typedef_type (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt;
+
+ h = ieee_name_type_hash_lookup (&info->typedefs, name, false, false);
+
+ /* h should never be NULL, since that would imply that the generic
+ debugging code has asked for a typedef which it has not yet
+ defined. */
+ assert (h != NULL);
+
+ /* We always use the most recently defined type for this name, which
+ will be the first one on the list. */
+
+ nt = h->types;
+ if (! ieee_push_type (info, nt->type.indx, nt->type.size,
+ nt->type.unsignedp, nt->type.localp))
+ return false;
+
+ /* Copy over any other type information we may have. */
+ info->type_stack->type = nt->type;
+
+ return true;
+}
+
+/* Push a tagged type onto the type stack. */
+
+static boolean
+ieee_tag_type (p, name, id, kind)
+ PTR p;
+ const char *name;
+ unsigned int id;
+ enum debug_type_kind kind;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ boolean copy;
+ char ab[20];
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt;
+
+ if (kind == DEBUG_KIND_ENUM)
+ {
+ struct ieee_defined_enum *e;
+
+ if (name == NULL)
+ abort ();
+ for (e = info->enums; e != NULL; e = e->next)
+ if (e->tag != NULL && strcmp (e->tag, name) == 0)
+ return ieee_push_type (info, e->indx, 0, true, false);
+
+ e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+
+ e->indx = info->type_indx;
+ ++info->type_indx;
+ e->tag = name;
+ e->defined = false;
+
+ e->next = info->enums;
+ info->enums = e;
+
+ return ieee_push_type (info, e->indx, 0, true, false);
+ }
+
+ localp = false;
+
+ copy = false;
+ if (name == NULL)
+ {
+ sprintf (ab, "__anon%u", id);
+ name = ab;
+ copy = true;
+ }
+
+ h = ieee_name_type_hash_lookup (&info->tags, name, true, copy);
+ if (h == NULL)
+ return false;
+
+ for (nt = h->types; nt != NULL; nt = nt->next)
+ {
+ if (nt->id == id)
+ {
+ if (! ieee_push_type (info, nt->type.indx, nt->type.size,
+ nt->type.unsignedp, nt->type.localp))
+ return false;
+ /* Copy over any other type information we may have. */
+ info->type_stack->type = nt->type;
+ return true;
+ }
+
+ if (! nt->type.localp)
+ {
+ /* This is a duplicate of a global type, so it must be
+ local. */
+ localp = true;
+ }
+ }
+
+ nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
+ memset (nt, 0, sizeof *nt);
+
+ nt->id = id;
+ nt->type.name = h->root.string;
+ nt->type.indx = info->type_indx;
+ nt->type.localp = localp;
+ ++info->type_indx;
+ nt->kind = kind;
+
+ nt->next = h->types;
+ h->types = nt;
+
+ if (! ieee_push_type (info, nt->type.indx, 0, false, localp))
+ return false;
+
+ info->type_stack->type.name = h->root.string;
+
+ return true;
+}
+
+/* Output a typedef. */
+
+static boolean
+ieee_typdef (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_write_type type;
+ unsigned int indx;
+ boolean found;
+ boolean localp;
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt;
+
+ type = info->type_stack->type;
+ indx = type.indx;
+
+ /* If this is a simple builtin type using a builtin name, we don't
+ want to output the typedef itself. We also want to change the
+ type index to correspond to the name being used. We recognize
+ names used in stabs debugging output even if they don't exactly
+ correspond to the names used for the IEEE builtin types. */
+ found = false;
+ if (indx <= (unsigned int) builtin_bcd_float)
+ {
+ switch ((enum builtin_types) indx)
+ {
+ default:
+ break;
+
+ case builtin_void:
+ if (strcmp (name, "void") == 0)
+ found = true;
+ break;
+
+ case builtin_signed_char:
+ case builtin_char:
+ if (strcmp (name, "signed char") == 0)
+ {
+ indx = (unsigned int) builtin_signed_char;
+ found = true;
+ }
+ else if (strcmp (name, "char") == 0)
+ {
+ indx = (unsigned int) builtin_char;
+ found = true;
+ }
+ break;
+
+ case builtin_unsigned_char:
+ if (strcmp (name, "unsigned char") == 0)
+ found = true;
+ break;
+
+ case builtin_signed_short_int:
+ case builtin_short:
+ case builtin_short_int:
+ case builtin_signed_short:
+ if (strcmp (name, "signed short int") == 0)
+ {
+ indx = (unsigned int) builtin_signed_short_int;
+ found = true;
+ }
+ else if (strcmp (name, "short") == 0)
+ {
+ indx = (unsigned int) builtin_short;
+ found = true;
+ }
+ else if (strcmp (name, "short int") == 0)
+ {
+ indx = (unsigned int) builtin_short_int;
+ found = true;
+ }
+ else if (strcmp (name, "signed short") == 0)
+ {
+ indx = (unsigned int) builtin_signed_short;
+ found = true;
+ }
+ break;
+
+ case builtin_unsigned_short_int:
+ case builtin_unsigned_short:
+ if (strcmp (name, "unsigned short int") == 0
+ || strcmp (name, "short unsigned int") == 0)
+ {
+ indx = builtin_unsigned_short_int;
+ found = true;
+ }
+ else if (strcmp (name, "unsigned short") == 0)
+ {
+ indx = builtin_unsigned_short;
+ found = true;
+ }
+ break;
+
+ case builtin_signed_long:
+ case builtin_int: /* FIXME: Size depends upon architecture. */
+ case builtin_long:
+ if (strcmp (name, "signed long") == 0)
+ {
+ indx = builtin_signed_long;
+ found = true;
+ }
+ else if (strcmp (name, "int") == 0)
+ {
+ indx = builtin_int;
+ found = true;
+ }
+ else if (strcmp (name, "long") == 0
+ || strcmp (name, "long int") == 0)
+ {
+ indx = builtin_long;
+ found = true;
+ }
+ break;
+
+ case builtin_unsigned_long:
+ case builtin_unsigned: /* FIXME: Size depends upon architecture. */
+ case builtin_unsigned_int: /* FIXME: Like builtin_unsigned. */
+ if (strcmp (name, "unsigned long") == 0
+ || strcmp (name, "long unsigned int") == 0)
+ {
+ indx = builtin_unsigned_long;
+ found = true;
+ }
+ else if (strcmp (name, "unsigned") == 0)
+ {
+ indx = builtin_unsigned;
+ found = true;
+ }
+ else if (strcmp (name, "unsigned int") == 0)
+ {
+ indx = builtin_unsigned_int;
+ found = true;
+ }
+ break;
+
+ case builtin_signed_long_long:
+ if (strcmp (name, "signed long long") == 0
+ || strcmp (name, "long long int") == 0)
+ found = true;
+ break;
+
+ case builtin_unsigned_long_long:
+ if (strcmp (name, "unsigned long long") == 0
+ || strcmp (name, "long long unsigned int") == 0)
+ found = true;
+ break;
+
+ case builtin_float:
+ if (strcmp (name, "float") == 0)
+ found = true;
+ break;
+
+ case builtin_double:
+ if (strcmp (name, "double") == 0)
+ found = true;
+ break;
+
+ case builtin_long_double:
+ if (strcmp (name, "long double") == 0)
+ found = true;
+ break;
+
+ case builtin_long_long_double:
+ if (strcmp (name, "long long double") == 0)
+ found = true;
+ break;
+ }
+
+ if (found)
+ type.indx = indx;
+ }
+
+ h = ieee_name_type_hash_lookup (&info->typedefs, name, true, false);
+ if (h == NULL)
+ return false;
+
+ /* See if we have already defined this type with this name. */
+ localp = type.localp;
+ for (nt = h->types; nt != NULL; nt = nt->next)
+ {
+ if (nt->id == indx)
+ {
+ /* If this is a global definition, then we don't need to
+ do anything here. */
+ if (! nt->type.localp)
+ {
+ ieee_pop_unused_type (info);
+ return true;
+ }
+ }
+ else
+ {
+ /* This is a duplicate definition, so make this one local. */
+ localp = true;
+ }
+ }
+
+ /* We need to add a new typedef for this type. */
+
+ nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
+ memset (nt, 0, sizeof *nt);
+ nt->id = indx;
+ nt->type = type;
+ nt->type.name = name;
+ nt->type.localp = localp;
+ nt->kind = DEBUG_KIND_ILLEGAL;
+
+ nt->next = h->types;
+ h->types = nt;
+
+ if (found)
+ {
+ /* This is one of the builtin typedefs, so we don't need to
+ actually define it. */
+ ieee_pop_unused_type (info);
+ return true;
+ }
+
+ indx = ieee_pop_type (info);
+
+ if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size,
+ type.unsignedp, localp,
+ (struct ieee_buflist *) NULL)
+ || ! ieee_write_number (info, 'T')
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ /* Remove the type we just added to the type stack. This should not
+ be ieee_pop_unused_type, since the type is used, we just don't
+ need it now. */
+ (void) ieee_pop_type (info);
+
+ return true;
+}
+
+/* Output a tag for a type. We don't have to do anything here. */
+
+static boolean
+ieee_tag (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* This should not be ieee_pop_unused_type, since we want the type
+ to be defined. */
+ (void) ieee_pop_type (info);
+ return true;
+}
+
+/* Output an integer constant. */
+
+static boolean
+ieee_int_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ /* FIXME. */
+ return true;
+}
+
+/* Output a floating point constant. */
+
+static boolean
+ieee_float_constant (p, name, val)
+ PTR p;
+ const char *name;
+ double val;
+{
+ /* FIXME. */
+ return true;
+}
+
+/* Output a typed constant. */
+
+static boolean
+ieee_typed_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* FIXME. */
+ ieee_pop_unused_type (info);
+ return true;
+}
+
+/* Output a variable. */
+
+static boolean
+ieee_variable (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int name_indx;
+ unsigned int size;
+ boolean referencep;
+ unsigned int type_indx;
+ boolean asn;
+ int refflag;
+
+ size = info->type_stack->type.size;
+ referencep = info->type_stack->type.referencep;
+ type_indx = ieee_pop_type (info);
+
+ assert (! ieee_buffer_emptyp (&info->vars));
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ name_indx = info->name_indx;
+ ++info->name_indx;
+
+ /* Write out an NN and an ATN record for this variable. */
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, name_indx)
+ || ! ieee_write_id (info, name)
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, name_indx)
+ || ! ieee_write_number (info, type_indx))
+ return false;
+ switch (kind)
+ {
+ default:
+ abort ();
+ return false;
+ case DEBUG_GLOBAL:
+ if (! ieee_write_number (info, 8)
+ || ! ieee_add_range (info, false, val, val + size))
+ return false;
+ refflag = 0;
+ asn = true;
+ break;
+ case DEBUG_STATIC:
+ if (! ieee_write_number (info, 3)
+ || ! ieee_add_range (info, false, val, val + size))
+ return false;
+ refflag = 1;
+ asn = true;
+ break;
+ case DEBUG_LOCAL_STATIC:
+ if (! ieee_write_number (info, 3)
+ || ! ieee_add_range (info, false, val, val + size))
+ return false;
+ refflag = 2;
+ asn = true;
+ break;
+ case DEBUG_LOCAL:
+ if (! ieee_write_number (info, 1)
+ || ! ieee_write_number (info, val))
+ return false;
+ refflag = 2;
+ asn = false;
+ break;
+ case DEBUG_REGISTER:
+ if (! ieee_write_number (info, 2)
+ || ! ieee_write_number (info,
+ ieee_genreg_to_regno (info->abfd, val)))
+ return false;
+ refflag = 2;
+ asn = false;
+ break;
+ }
+
+ if (asn)
+ {
+ if (! ieee_write_asn (info, name_indx, val))
+ return false;
+ }
+
+ /* If this is really a reference type, then we just output it with
+ pointer type, and must now output a C++ record indicating that it
+ is really reference type. */
+ if (referencep)
+ {
+ unsigned int nindx;
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+
+ /* If this is a global variable, we want to output the misc
+ record in the C++ misc record block. Otherwise, we want to
+ output it just after the variable definition, which is where
+ the current buffer is. */
+ if (refflag != 2)
+ {
+ if (! ieee_change_buffer (info, &info->cxx))
+ return false;
+ }
+
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, 3)
+ || ! ieee_write_asn (info, nindx, 'R')
+ || ! ieee_write_asn (info, nindx, refflag)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ }
+
+ return true;
+}
+
+/* Start outputting information for a function. */
+
+static boolean
+ieee_start_function (p, name, global)
+ PTR p;
+ const char *name;
+ boolean global;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean referencep;
+ unsigned int retindx, typeindx;
+
+ referencep = info->type_stack->type.referencep;
+ retindx = ieee_pop_type (info);
+
+ /* Besides recording a BB4 or BB6 block, we record the type of the
+ function in the BB1 typedef block. We can't write out the full
+ type until we have seen all the parameters, so we accumulate it
+ in info->fntype and info->fnargs. */
+ if (! ieee_buffer_emptyp (&info->fntype))
+ {
+ /* FIXME: This might happen someday if we support nested
+ functions. */
+ abort ();
+ }
+
+ info->fnname = name;
+
+ /* An attribute of 0x40 means that the push mask is unknown. */
+ if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, false, true,
+ &info->fntype)
+ || ! ieee_write_number (info, 'x')
+ || ! ieee_write_number (info, 0x40)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, retindx))
+ return false;
+
+ typeindx = ieee_pop_type (info);
+
+ if (! ieee_init_buffer (info, &info->fnargs))
+ return false;
+ info->fnargcount = 0;
+
+ /* If the function return value is actually a reference type, we
+ must add a record indicating that. */
+ if (referencep)
+ {
+ unsigned int nindx;
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->cxx)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, 3)
+ || ! ieee_write_asn (info, nindx, 'R')
+ || ! ieee_write_asn (info, nindx, global ? 0 : 1)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ }
+
+ assert (! ieee_buffer_emptyp (&info->vars));
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ /* The address is written out as the first block. */
+
+ ++info->block_depth;
+
+ return (ieee_write_byte (info, (int) ieee_bb_record_enum)
+ && ieee_write_byte (info, global ? 4 : 6)
+ && ieee_write_number (info, 0)
+ && ieee_write_id (info, name)
+ && ieee_write_number (info, 0)
+ && ieee_write_number (info, typeindx));
+}
+
+/* Add a function parameter. This will normally be called before the
+ first block, so we postpone them until we see the block. */
+
+static boolean
+ieee_function_parameter (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_parm_kind kind;
+ bfd_vma val;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_pending_parm *m, **pm;
+
+ assert (info->block_depth == 1);
+
+ m = (struct ieee_pending_parm *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->next = NULL;
+ m->name = name;
+ m->referencep = info->type_stack->type.referencep;
+ m->type = ieee_pop_type (info);
+ m->kind = kind;
+ m->val = val;
+
+ for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next)
+ ;
+ *pm = m;
+
+ /* Add the type to the fnargs list. */
+ if (! ieee_change_buffer (info, &info->fnargs)
+ || ! ieee_write_number (info, m->type))
+ return false;
+ ++info->fnargcount;
+
+ return true;
+}
+
+/* Output pending function parameters. */
+
+static boolean
+ieee_output_pending_parms (info)
+ struct ieee_handle *info;
+{
+ struct ieee_pending_parm *m;
+ unsigned int refcount;
+
+ refcount = 0;
+ for (m = info->pending_parms; m != NULL; m = m->next)
+ {
+ enum debug_var_kind vkind;
+
+ switch (m->kind)
+ {
+ default:
+ abort ();
+ return false;
+ case DEBUG_PARM_STACK:
+ case DEBUG_PARM_REFERENCE:
+ vkind = DEBUG_LOCAL;
+ break;
+ case DEBUG_PARM_REG:
+ case DEBUG_PARM_REF_REG:
+ vkind = DEBUG_REGISTER;
+ break;
+ }
+
+ if (! ieee_push_type (info, m->type, 0, false, false))
+ return false;
+ info->type_stack->type.referencep = m->referencep;
+ if (m->referencep)
+ ++refcount;
+ if (! ieee_variable ((PTR) info, m->name, vkind, m->val))
+ return false;
+ }
+
+ /* If there are any reference parameters, we need to output a
+ miscellaneous record indicating them. */
+ if (refcount > 0)
+ {
+ unsigned int nindx, varindx;
+
+ /* FIXME: The MRI compiler outputs the demangled function name
+ here, but we are outputting the mangled name. */
+ nindx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, refcount + 3)
+ || ! ieee_write_asn (info, nindx, 'B')
+ || ! ieee_write_atn65 (info, nindx, info->fnname)
+ || ! ieee_write_asn (info, nindx, 0))
+ return false;
+ for (m = info->pending_parms, varindx = 1;
+ m != NULL;
+ m = m->next, varindx++)
+ {
+ if (m->referencep)
+ {
+ if (! ieee_write_asn (info, nindx, varindx))
+ return false;
+ }
+ }
+ }
+
+ m = info->pending_parms;
+ while (m != NULL)
+ {
+ struct ieee_pending_parm *next;
+
+ next = m->next;
+ free (m);
+ m = next;
+ }
+
+ info->pending_parms = NULL;
+
+ return true;
+}
+
+/* Start a block. If this is the first block, we output the address
+ to finish the BB4 or BB6, and then output the function parameters. */
+
+static boolean
+ieee_start_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ if (info->block_depth == 1)
+ {
+ if (! ieee_write_number (info, addr)
+ || ! ieee_output_pending_parms (info))
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 6)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, addr))
+ return false;
+ }
+
+ if (! ieee_start_range (info, addr))
+ return false;
+
+ ++info->block_depth;
+
+ return true;
+}
+
+/* End a block. */
+
+static boolean
+ieee_end_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* The address we are given is the end of the block, but IEEE seems
+ to want to the address of the last byte in the block, so we
+ subtract one. */
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, addr - 1))
+ return false;
+
+ if (! ieee_end_range (info, addr))
+ return false;
+
+ --info->block_depth;
+
+ if (addr > info->highaddr)
+ info->highaddr = addr;
+
+ return true;
+}
+
+/* End a function. */
+
+static boolean
+ieee_end_function (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->block_depth == 1);
+
+ --info->block_depth;
+
+ /* Now we can finish up fntype, and add it to the typdef section.
+ At this point, fntype is the 'x' type up to the argument count,
+ and fnargs is the argument types. We must add the argument
+ count, and we must add the level. FIXME: We don't record varargs
+ functions correctly. In fact, stabs debugging does not give us
+ enough information to do so. */
+ if (! ieee_change_buffer (info, &info->fntype)
+ || ! ieee_write_number (info, info->fnargcount)
+ || ! ieee_change_buffer (info, &info->fnargs)
+ || ! ieee_write_number (info, 0))
+ return false;
+
+ /* Make sure the typdef block has been started. */
+ if (ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+
+ if (! ieee_append_buffer (info, &info->types, &info->fntype)
+ || ! ieee_append_buffer (info, &info->types, &info->fnargs))
+ return false;
+
+ info->fnname = NULL;
+ if (! ieee_init_buffer (info, &info->fntype)
+ || ! ieee_init_buffer (info, &info->fnargs))
+ return false;
+ info->fnargcount = 0;
+
+ return true;
+}
+
+/* Record line number information. */
+
+static boolean
+ieee_lineno (p, filename, lineno, addr)
+ PTR p;
+ const char *filename;
+ unsigned long lineno;
+ bfd_vma addr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->filename != NULL);
+
+ /* The HP simulator seems to get confused when more than one line is
+ listed for the same address, at least if they are in different
+ files. We handle this by always listing the last line for a
+ given address, since that seems to be the one that gdb uses. */
+ if (info->pending_lineno_filename != NULL
+ && addr != info->pending_lineno_addr)
+ {
+ /* Make sure we have a line number block. */
+ if (! ieee_buffer_emptyp (&info->linenos))
+ {
+ if (! ieee_change_buffer (info, &info->linenos))
+ return false;
+ }
+ else
+ {
+ info->lineno_name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->linenos)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 5)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->filename)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_id (info, ""))
+ return false;
+ info->lineno_filename = info->filename;
+ }
+
+ if (strcmp (info->pending_lineno_filename, info->lineno_filename) != 0)
+ {
+ if (strcmp (info->filename, info->lineno_filename) != 0)
+ {
+ /* We were not in the main file. Close the block for the
+ included file. */
+ if (! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ if (strcmp (info->filename, info->pending_lineno_filename) == 0)
+ {
+ /* We need a new NN record, and we aren't about to
+ output one. */
+ info->lineno_name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ }
+ if (strcmp (info->filename, info->pending_lineno_filename) != 0)
+ {
+ /* We are not changing to the main file. Open a block for
+ the new included file. */
+ info->lineno_name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 5)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->pending_lineno_filename)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ info->lineno_filename = info->pending_lineno_filename;
+ }
+
+ if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 7)
+ || ! ieee_write_number (info, info->pending_lineno)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_asn (info, info->lineno_name_indx,
+ info->pending_lineno_addr))
+ return false;
+ }
+
+ info->pending_lineno_filename = filename;
+ info->pending_lineno = lineno;
+ info->pending_lineno_addr = addr;
+
+ return true;
+}
diff --git a/pstack/ieee.h b/pstack/ieee.h
new file mode 100644
index 00000000000..56634b2819a
--- /dev/null
+++ b/pstack/ieee.h
@@ -0,0 +1,138 @@
+/* IEEE Standard 695-1980 "Universal Format for Object Modules" header file
+ Contributed by Cygnus Support. */
+
+#define N_W_VARIABLES 8
+#define Module_Beginning 0xe0
+
+typedef struct ieee_module {
+ char *processor;
+ char *module_name;
+} ieee_module_begin_type;
+
+#define Address_Descriptor 0xec
+typedef struct ieee_address {
+bfd_vma number_of_bits_mau;
+ bfd_vma number_of_maus_in_address;
+
+ unsigned char byte_order;
+#define IEEE_LITTLE 0xcc
+#define IEEE_BIG 0xcd
+} ieee_address_descriptor_type;
+
+typedef union ieee_w_variable {
+ file_ptr offset[N_W_VARIABLES];
+ struct {
+ file_ptr extension_record;
+ file_ptr environmental_record;
+ file_ptr section_part;
+ file_ptr external_part;
+ file_ptr debug_information_part;
+ file_ptr data_part;
+ file_ptr trailer_part;
+ file_ptr me_record;
+ } r;
+} ieee_w_variable_type;
+
+
+
+
+
+typedef enum ieee_record
+{
+ ieee_number_start_enum = 0x00,
+ ieee_number_end_enum=0x7f,
+ ieee_number_repeat_start_enum = 0x80,
+ ieee_number_repeat_end_enum = 0x88,
+ ieee_number_repeat_4_enum = 0x84,
+ ieee_number_repeat_3_enum = 0x83,
+ ieee_number_repeat_2_enum = 0x82,
+ ieee_number_repeat_1_enum = 0x81,
+ ieee_module_beginning_enum = 0xe0,
+ ieee_module_end_enum = 0xe1,
+ ieee_extension_length_1_enum = 0xde,
+ ieee_extension_length_2_enum = 0xdf,
+ ieee_section_type_enum = 0xe6,
+ ieee_section_alignment_enum = 0xe7,
+ ieee_external_symbol_enum = 0xe8,
+ ieee_comma = 0x90,
+ ieee_external_reference_enum = 0xe9,
+ ieee_set_current_section_enum = 0xe5,
+ ieee_address_descriptor_enum = 0xec,
+ ieee_load_constant_bytes_enum = 0xed,
+ ieee_load_with_relocation_enum = 0xe4,
+
+ ieee_variable_A_enum = 0xc1,
+ ieee_variable_B_enum = 0xc2,
+ ieee_variable_C_enum = 0xc3,
+ ieee_variable_D_enum = 0xc4,
+ ieee_variable_E_enum = 0xc5,
+ ieee_variable_F_enum = 0xc6,
+ ieee_variable_G_enum = 0xc7,
+ ieee_variable_H_enum = 0xc8,
+ ieee_variable_I_enum = 0xc9,
+ ieee_variable_J_enum = 0xca,
+ ieee_variable_K_enum = 0xcb,
+ ieee_variable_L_enum = 0xcc,
+ ieee_variable_M_enum = 0xcd,
+ ieee_variable_N_enum = 0xce,
+ ieee_variable_O_enum = 0xcf,
+ ieee_variable_P_enum = 0xd0,
+ ieee_variable_Q_enum = 0xd1,
+ ieee_variable_R_enum = 0xd2,
+ ieee_variable_S_enum = 0xd3,
+ ieee_variable_T_enum = 0xd4,
+ ieee_variable_U_enum = 0xd5,
+ ieee_variable_V_enum = 0xd6,
+ ieee_variable_W_enum = 0xd7,
+ ieee_variable_X_enum = 0xd8,
+ ieee_variable_Y_enum = 0xd9,
+ ieee_variable_Z_enum = 0xda,
+ ieee_function_plus_enum = 0xa5,
+ ieee_function_minus_enum = 0xa6,
+ ieee_function_signed_open_b_enum = 0xba,
+ ieee_function_signed_close_b_enum = 0xbb,
+
+ ieee_function_unsigned_open_b_enum = 0xbc,
+ ieee_function_unsigned_close_b_enum = 0xbd,
+
+ ieee_function_either_open_b_enum = 0xbe,
+ ieee_function_either_close_b_enum = 0xbf,
+ ieee_record_seperator_enum = 0xdb,
+
+ ieee_e2_first_byte_enum = 0xe2,
+ ieee_section_size_enum = 0xe2d3,
+ ieee_physical_region_size_enum = 0xe2c1,
+ ieee_region_base_address_enum = 0xe2c2,
+ ieee_mau_size_enum = 0xe2c6,
+ ieee_m_value_enum = 0xe2cd,
+ ieee_section_base_address_enum = 0xe2cc,
+ ieee_asn_record_enum = 0xe2ce,
+ ieee_section_offset_enum = 0xe2d2,
+ ieee_value_starting_address_enum = 0xe2c7,
+ ieee_assign_value_to_variable_enum = 0xe2d7,
+ ieee_set_current_pc_enum = 0xe2d0,
+ ieee_value_record_enum = 0xe2c9,
+ ieee_nn_record = 0xf0,
+ ieee_at_record_enum = 0xf1,
+ ieee_ty_record_enum = 0xf2,
+ ieee_attribute_record_enum = 0xf1c9,
+ ieee_atn_record_enum = 0xf1ce,
+ ieee_external_reference_info_record_enum = 0xf1d8,
+ ieee_weak_external_reference_enum= 0xf4,
+ ieee_repeat_data_enum = 0xf7,
+ ieee_bb_record_enum = 0xf8,
+ ieee_be_record_enum = 0xf9
+} ieee_record_enum_type;
+
+
+typedef struct ieee_section {
+ unsigned int section_index;
+ unsigned int section_type;
+ char *section_name;
+ unsigned int parent_section_index;
+ unsigned int sibling_section_index;
+ unsigned int context_index;
+} ieee_section_type;
+#define IEEE_REFERENCE_BASE 11
+#define IEEE_PUBLIC_BASE 32
+#define IEEE_SECTION_NUMBER_BASE 1
diff --git a/pstack/libiberty.h b/pstack/libiberty.h
new file mode 100644
index 00000000000..ca0043d31c6
--- /dev/null
+++ b/pstack/libiberty.h
@@ -0,0 +1,180 @@
+/* Function declarations for libiberty.
+ Written by Cygnus Support, 1994.
+
+ The libiberty library provides a number of functions which are
+ missing on some operating systems. We do not declare those here,
+ to avoid conflicts with the system header files on operating
+ systems that do support those functions. In this file we only
+ declare those functions which are specific to libiberty. */
+
+#ifndef LIBIBERTY_H
+#define LIBIBERTY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ansidecl.h"
+
+/* Build an argument vector from a string. Allocates memory using
+ malloc. Use freeargv to free the vector. */
+
+extern char **buildargv PARAMS ((char *));
+
+/* Free a vector returned by buildargv. */
+
+extern void freeargv PARAMS ((char **));
+
+/* Duplicate an argument vector. Allocates memory using malloc. Use
+ freeargv to free the vector. */
+
+extern char **dupargv PARAMS ((char **));
+
+
+/* Return the last component of a path name. Note that we can't use a
+ prototype here because the parameter is declared inconsistently
+ across different systems, sometimes as "char *" and sometimes as
+ "const char *" */
+
+#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__)
+extern char *basename PARAMS ((const char *));
+#else
+extern char *basename ();
+#endif
+
+/* Concatenate an arbitrary number of strings, up to (char *) NULL.
+ Allocates memory using xmalloc. */
+
+extern char *concat PARAMS ((const char *, ...));
+
+/* Check whether two file descriptors refer to the same file. */
+
+extern int fdmatch PARAMS ((int fd1, int fd2));
+
+/* Get the amount of time the process has run, in microseconds. */
+
+extern long get_run_time PARAMS ((void));
+
+/* Choose a temporary directory to use for scratch files. */
+
+extern char *choose_temp_base PARAMS ((void));
+
+/* Allocate memory filled with spaces. Allocates using malloc. */
+
+extern const char *spaces PARAMS ((int count));
+
+/* Return the maximum error number for which strerror will return a
+ string. */
+
+extern int errno_max PARAMS ((void));
+
+/* Return the name of an errno value (e.g., strerrno (EINVAL) returns
+ "EINVAL"). */
+
+extern const char *strerrno PARAMS ((int));
+
+/* Given the name of an errno value, return the value. */
+
+extern int strtoerrno PARAMS ((const char *));
+
+/* ANSI's strerror(), but more robust. */
+
+extern char *xstrerror PARAMS ((int));
+
+/* Return the maximum signal number for which strsignal will return a
+ string. */
+
+extern int signo_max PARAMS ((void));
+
+/* Return a signal message string for a signal number
+ (e.g., strsignal (SIGHUP) returns something like "Hangup"). */
+/* This is commented out as it can conflict with one in system headers.
+ We still document its existence though. */
+
+/*extern const char *strsignal PARAMS ((int));*/
+
+/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
+ "SIGHUP"). */
+
+extern const char *strsigno PARAMS ((int));
+
+/* Given the name of a signal, return its number. */
+
+extern int strtosigno PARAMS ((const char *));
+
+/* Register a function to be run by xexit. Returns 0 on success. */
+
+extern int xatexit PARAMS ((void (*fn) (void)));
+
+/* Exit, calling all the functions registered with xatexit. */
+
+#ifndef __GNUC__
+extern void xexit PARAMS ((int status));
+#else
+void xexit PARAMS ((int status)) __attribute__ ((noreturn));
+#endif
+
+/* Set the program name used by xmalloc. */
+
+extern void xmalloc_set_program_name PARAMS ((const char *));
+
+/* Allocate memory without fail. If malloc fails, this will print a
+ message to stderr (using the name set by xmalloc_set_program_name,
+ if any) and then call xexit. */
+
+#ifdef ANSI_PROTOTYPES
+/* Get a definition for size_t. */
+#include <stddef.h>
+#endif
+extern PTR xmalloc PARAMS ((size_t));
+
+/* Reallocate memory without fail. This works like xmalloc.
+
+ FIXME: We do not declare the parameter types for the same reason as
+ xmalloc. */
+
+extern PTR xrealloc PARAMS ((PTR, size_t));
+
+/* Allocate memory without fail and set it to zero. This works like
+ xmalloc. */
+
+extern PTR xcalloc PARAMS ((size_t, size_t));
+
+/* Copy a string into a memory buffer without fail. */
+
+extern char *xstrdup PARAMS ((const char *));
+
+/* hex character manipulation routines */
+
+#define _hex_array_size 256
+#define _hex_bad 99
+extern char _hex_value[_hex_array_size];
+extern void hex_init PARAMS ((void));
+#define hex_p(c) (hex_value (c) != _hex_bad)
+/* If you change this, note well: Some code relies on side effects in
+ the argument being performed exactly once. */
+#define hex_value(c) (_hex_value[(unsigned char) (c)])
+
+/* Definitions used by the pexecute routine. */
+
+#define PEXECUTE_FIRST 1
+#define PEXECUTE_LAST 2
+#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST)
+#define PEXECUTE_SEARCH 4
+#define PEXECUTE_VERBOSE 8
+
+/* Execute a program. */
+
+extern int pexecute PARAMS ((const char *, char * const *, const char *,
+ const char *, char **, char **, int));
+
+/* Wait for pexecute to finish. */
+
+extern int pwait PARAMS ((int, int *, int));
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* ! defined (LIBIBERTY_H) */
diff --git a/pstack/linuxthreads.c b/pstack/linuxthreads.c
new file mode 100644
index 00000000000..8624bd21782
--- /dev/null
+++ b/pstack/linuxthreads.c
@@ -0,0 +1,90 @@
+/* $Header$ */
+
+/*
+ * LinuxThreads specific stuff.
+ */
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <limits.h> /* PTHREAD_THREADS_MAX */
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sched.h>
+
+#include "linuxthreads.h"
+
+#define AT_INT(intval) *((int32_t*)(intval))
+
+/*
+ * Internal LinuxThreads variables.
+ * Official interface exposed to GDB.
+ */
+#if 1
+extern volatile int __pthread_threads_debug;
+extern volatile char __pthread_handles;
+extern char __pthread_initial_thread;
+/*extern volatile Elf32_Sym* __pthread_manager_thread;*/
+extern const int __pthread_sizeof_handle;
+extern const int __pthread_offsetof_descr;
+extern const int __pthread_offsetof_pid;
+extern volatile int __pthread_handles_num;
+#endif /* 0 */
+
+/*
+ * Notify others.
+ */
+int
+linuxthreads_notify_others( const int signotify)
+{
+ const pid_t mypid = getpid();
+ //const pthread_t mytid = pthread_self();
+ int i;
+ int threadcount = 0;
+ int threads[PTHREAD_THREADS_MAX];
+ int pid;
+
+ TRACE_FPRINTF((stderr, "theadcount:%d\n", __pthread_handles_num));
+ if (__pthread_handles_num==2) {
+ /* no threads beside the initial thread */
+ return 0;
+ }
+ /*assert(maxthreads>=3);
+ assert(maxthreads>=__pthread_handles_num+2);*/
+
+ // take the initial thread with us
+ pid = AT_INT(&__pthread_initial_thread + __pthread_offsetof_pid);
+ if (pid!=mypid && pid!=0)
+ threads[threadcount++] = pid;
+ // don't know why, but always handles[0]==handles[1]
+ for (i=1; i<__pthread_handles_num; ++i) {
+ const int descr = AT_INT(&__pthread_handles+i*__pthread_sizeof_handle+__pthread_offsetof_descr);
+ assert(descr!=0);
+ pid = AT_INT(descr+__pthread_offsetof_pid);
+ if (pid!=mypid && pid!=0)
+ threads[threadcount++] = pid;
+ }
+ /* TRACE_FPRINTF((stderr, "Stopping threads...")); */
+ //for (i=0; i<threadcount; ++i) {
+ // /* TRACE_FPRINTF((stderr, "%d ", threads[i])); */
+ // fflush(stdout);
+ // kill(threads[i], SIGSTOP); /* Tell thread to stop */
+ //}
+ /* TRACE_FPRINTF((stderr, " done!\n")); */
+ for (i=0; i<threadcount; ++i) {
+ TRACE_FPRINTF((stderr, "--- NOTIFYING %d\n", threads[i]));
+ kill(threads[i], signotify); /* Tell to print stack trace */
+ /* TRACE_FPRINTF((stderr, "--- WAITING FOR %d\n", threads[i])); */
+ /*pause(); Wait for confirmation. */
+ }
+ for (i=0; i<threadcount; ++i)
+ sched_yield();
+ for (i=0; i<threadcount; ++i) {
+ TRACE_FPRINTF((stderr, "--- KILLING %d\n", threads[i]));
+ kill(threads[i], SIGKILL); /* Tell thread die :) */
+ }
+ return __pthread_handles_num;
+}
+
diff --git a/pstack/linuxthreads.h b/pstack/linuxthreads.h
new file mode 100644
index 00000000000..f5eb0f652d8
--- /dev/null
+++ b/pstack/linuxthreads.h
@@ -0,0 +1,28 @@
+/* $Header$ */
+
+/*
+ * LinuxThreads specific stuff.
+ */
+
+#ifndef pstack_linuxthreads_h_
+#define pstack_linuxthreads_h_
+
+#include <pthread.h>
+#include "pstacktrace.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Tell other threads to dump stacks...
+ */
+int
+linuxthreads_notify_others( const int signotify);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pstack_linuxthreads_h_ */
+
diff --git a/pstack/pstack.c b/pstack/pstack.c
new file mode 100644
index 00000000000..48280d4aedb
--- /dev/null
+++ b/pstack/pstack.c
@@ -0,0 +1,2745 @@
+/*
+ pstack.c -- asynchronous stack trace of a running process
+ Copyright (c) 1999 Ross Thompson
+ Author: Ross Thompson <ross@whatsis.com>
+ Critical bug fix: Tim Waugh
+*/
+
+/*
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* RESTRICTIONS:
+
+ pstack currently works only on Linux, only on an x86 machine running
+ 32 bit ELF binaries (64 bit not supported). Also, for symbolic
+ information, you need to use a GNU compiler to generate your
+ program, and you can't strip symbols from the binaries. For thread
+ information to be dumped, you have to use the debug-aware version
+ of libpthread.so. (To check, run 'nm' on your libpthread.so, and
+ make sure that the symbol "__pthread_threads_debug" is defined.)
+
+ The details of pulling stuff out of ELF files and running through
+ program images is very platform specific, and I don't want to
+ try to support modes or machine types I can't test in or on.
+ If someone wants to generalize this to other architectures, I would
+ be happy to help and coordinate the activity. Please send me whatever
+ changes you make to support these machines, so that I can own the
+ central font of all truth (at least as regards this program).
+
+ Thanks
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+
+#include <assert.h>
+#include <fcntl.h>
+#include <link.h>
+#include <malloc.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <pthread.h>
+#include <limits.h> /* PTHREAD_THREADS_MAX */
+
+
+#include <bfd.h>
+
+#include "libiberty.h"
+
+#include "pstack.h" /* just one function */
+#include "budbg.h" /* binutils stuff related to debugging symbols. */
+#include "bucomm.h" /* some common stuff */
+#include "debug.h" /* and more binutils stuff... */
+#include "budbg.h"
+#include "linuxthreads.h" /* LinuxThreads specific stuff... */
+
+
+/*
+ * fprintf for file descriptors :) NOTE: we have to use fixed-size buffer :)(
+ * due to malloc's unavalaibility.
+ */
+int
+fdprintf( int fd,
+ const char* fmt,...)
+{
+ char xbuf[2048];// FIXME: enough?
+ va_list ap;
+ int r;
+ if (fd<0)
+ return -1;
+ va_start(ap, fmt);
+ r = vsnprintf(xbuf, sizeof(xbuf), fmt, ap);
+ va_end(ap);
+ return write(fd, xbuf, r);
+}
+
+int
+fdputc( char c,
+ int fd)
+{
+ if (fd<0)
+ return -1;
+ return write(fd, &c, sizeof(c));
+}
+
+int
+fdputs( const char* s,
+ int fd)
+{
+ if (fd<0)
+ return -1;
+ return write(fd, s, strlen(s));
+}
+
+/*
+ * Use this function to open log file.
+ * Flags: truncate on opening.
+ */
+static const char* path_format = "stack-trace-on-segv-%d.txt";
+static int
+open_log_file( const pthread_t tid,
+ const pid_t pid)
+{
+ char fname[PATH_MAX];
+ int r;
+ snprintf(fname, sizeof(fname), path_format, tid, pid);
+ r = open(fname, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRUSR|S_IWUSR);
+ if (r<0)
+ perror("open");
+ return r;
+}
+/*
+ * Add additional debugging information for functions.
+ */
+
+/*
+ * Lineno
+ */
+typedef struct {
+ int lineno;
+ bfd_vma addr;
+} debug_lineno_t;
+
+/*
+ * Block - a {} pair.
+ */
+typedef struct debug_block_st {
+ bfd_vma begin_addr; /* where did it start */
+ bfd_vma end_addr; /* where did it end */
+ struct debug_block_st* parent;
+ struct debug_block_st* childs;
+ int childs_count;
+} debug_block_t;
+
+/*
+ * Function parameter.
+ */
+typedef struct {
+ bfd_vma offset; /* Offset in the stack */
+ const char* name; /* And name. */
+} debug_parameter_t;
+
+/*
+ * Extra information about functions.
+ */
+typedef struct {
+ asymbol* symbol; /* mangled function name, addr */
+ debug_lineno_t* lines;
+ int lines_count;
+ int max_lines_count;
+ const char* name;
+ const char* filename;/* a file name it occured in... */
+ debug_block_t* block; /* each function has a block, or not, you know */
+ debug_parameter_t* argv; /* argument types. */
+ int argc;
+ int max_argc;
+} debug_function_t;
+
+/* This is the structure we use as a handle for these routines. */
+struct pr_handle
+{
+ /* File to print information to. */
+ FILE *f;
+ /* Current indentation level. */
+ unsigned int indent;
+ /* Type stack. */
+ struct pr_stack *stack;
+ /* Parameter number we are about to output. */
+ int parameter;
+ debug_block_t* block; /* current block */
+ debug_function_t* function; /* current function */
+ debug_function_t* functions; /* all functions */
+ int functions_size; /* current size */
+ int functions_maxsize; /* maximum size */
+};
+
+/* The type stack. */
+
+struct pr_stack
+{
+ /* Next element on the stack. */
+ struct pr_stack *next;
+ /* This element. */
+ char *type;
+ /* Current visibility of fields if this is a class. */
+ enum debug_visibility visibility;
+ /* Name of the current method we are handling. */
+ const char *method;
+};
+
+static void indent PARAMS ((struct pr_handle *));
+static boolean push_type PARAMS ((struct pr_handle *, const char *));
+static boolean prepend_type PARAMS ((struct pr_handle *, const char *));
+static boolean append_type PARAMS ((struct pr_handle *, const char *));
+static boolean substitute_type PARAMS ((struct pr_handle *, const char *));
+static boolean indent_type PARAMS ((struct pr_handle *));
+static char *pop_type PARAMS ((struct pr_handle *));
+static void print_vma PARAMS ((bfd_vma, char *, boolean, boolean));
+static boolean pr_fix_visibility
+ PARAMS ((struct pr_handle *, enum debug_visibility));
+
+static boolean pr_start_compilation_unit PARAMS ((PTR, const char *));
+static boolean pr_start_source PARAMS ((PTR, const char *));
+static boolean pr_empty_type PARAMS ((PTR));
+static boolean pr_void_type PARAMS ((PTR));
+static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
+static boolean pr_float_type PARAMS ((PTR, unsigned int));
+static boolean pr_complex_type PARAMS ((PTR, unsigned int));
+static boolean pr_bool_type PARAMS ((PTR, unsigned int));
+static boolean pr_enum_type
+ PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
+static boolean pr_pointer_type PARAMS ((PTR));
+static boolean pr_function_type PARAMS ((PTR, int, boolean));
+static boolean pr_reference_type PARAMS ((PTR));
+static boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
+static boolean pr_array_type
+ PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
+static boolean pr_set_type PARAMS ((PTR, boolean));
+static boolean pr_offset_type PARAMS ((PTR));
+static boolean pr_method_type PARAMS ((PTR, boolean, int, boolean));
+static boolean pr_const_type PARAMS ((PTR));
+static boolean pr_volatile_type PARAMS ((PTR));
+static boolean pr_start_struct_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
+static boolean pr_struct_field
+ PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
+static boolean pr_end_struct_type PARAMS ((PTR));
+static boolean pr_start_class_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
+ boolean));
+static boolean pr_class_static_member
+ PARAMS ((PTR, const char *, const char *, enum debug_visibility));
+static boolean pr_class_baseclass
+ PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
+static boolean pr_class_start_method PARAMS ((PTR, const char *));
+static boolean pr_class_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
+ bfd_vma, boolean));
+static boolean pr_class_static_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
+static boolean pr_class_end_method PARAMS ((PTR));
+static boolean pr_end_class_type PARAMS ((PTR));
+static boolean pr_typedef_type PARAMS ((PTR, const char *));
+static boolean pr_tag_type
+ PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
+static boolean pr_typdef PARAMS ((PTR, const char *));
+static boolean pr_tag PARAMS ((PTR, const char *));
+static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean pr_float_constant PARAMS ((PTR, const char *, double));
+static boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean pr_variable
+ PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
+static boolean pr_start_function PARAMS ((PTR, const char *, boolean));
+static boolean pr_function_parameter
+ PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
+static boolean pr_start_block PARAMS ((PTR, bfd_vma));
+static boolean pr_end_block PARAMS ((PTR, bfd_vma));
+static boolean pr_end_function PARAMS ((PTR));
+static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
+
+static const struct debug_write_fns pr_fns =
+{
+ pr_start_compilation_unit,
+ pr_start_source,
+ pr_empty_type,
+ pr_void_type,
+ pr_int_type,
+ pr_float_type,
+ pr_complex_type,
+ pr_bool_type,
+ pr_enum_type,
+ pr_pointer_type,
+ pr_function_type,
+ pr_reference_type,
+ pr_range_type,
+ pr_array_type,
+ pr_set_type,
+ pr_offset_type,
+ pr_method_type,
+ pr_const_type,
+ pr_volatile_type,
+ pr_start_struct_type,
+ pr_struct_field,
+ pr_end_struct_type,
+ pr_start_class_type,
+ pr_class_static_member,
+ pr_class_baseclass,
+ pr_class_start_method,
+ pr_class_method_variant,
+ pr_class_static_method_variant,
+ pr_class_end_method,
+ pr_end_class_type,
+ pr_typedef_type,
+ pr_tag_type,
+ pr_typdef,
+ pr_tag,
+ pr_int_constant,
+ pr_float_constant,
+ pr_typed_constant,
+ pr_variable,
+ pr_start_function,
+ pr_function_parameter,
+ pr_start_block,
+ pr_end_block,
+ pr_end_function,
+ pr_lineno
+};
+
+
+/* Indent to the current indentation level. */
+
+static void
+indent (info)
+ struct pr_handle *info;
+{
+ unsigned int i;
+
+ for (i = 0; i < info->indent; i++)
+ TRACE_PUTC ((' ', info->f));
+}
+
+/* Push a type on the type stack. */
+
+static boolean
+push_type (info, type)
+ struct pr_handle *info;
+ const char *type;
+{
+ struct pr_stack *n;
+
+ if (type == NULL)
+ return false;
+
+ n = (struct pr_stack *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->type = xstrdup (type);
+ n->visibility = DEBUG_VISIBILITY_IGNORE;
+ n->method = NULL;
+ n->next = info->stack;
+ info->stack = n;
+
+ return true;
+}
+
+/* Prepend a string onto the type on the top of the type stack. */
+
+static boolean
+prepend_type (info, s)
+ struct pr_handle *info;
+ const char *s;
+{
+ char *n;
+
+ assert (info->stack != NULL);
+
+ n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
+ sprintf (n, "%s%s", s, info->stack->type);
+ free (info->stack->type);
+ info->stack->type = n;
+
+ return true;
+}
+
+/* Append a string to the type on the top of the type stack. */
+
+static boolean
+append_type (info, s)
+ struct pr_handle *info;
+ const char *s;
+{
+ unsigned int len;
+
+ if (s == NULL)
+ return false;
+
+ assert (info->stack != NULL);
+
+ len = strlen (info->stack->type);
+ info->stack->type = (char *) xrealloc (info->stack->type,
+ len + strlen (s) + 1);
+ strcpy (info->stack->type + len, s);
+
+ return true;
+}
+
+/* We use an underscore to indicate where the name should go in a type
+ string. This function substitutes a string for the underscore. If
+ there is no underscore, the name follows the type. */
+
+static boolean
+substitute_type (info, s)
+ struct pr_handle *info;
+ const char *s;
+{
+ char *u;
+
+ assert (info->stack != NULL);
+
+ u = strchr (info->stack->type, '|');
+ if (u != NULL)
+ {
+ char *n;
+
+ n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
+
+ memcpy (n, info->stack->type, u - info->stack->type);
+ strcpy (n + (u - info->stack->type), s);
+ strcat (n, u + 1);
+
+ free (info->stack->type);
+ info->stack->type = n;
+
+ return true;
+ }
+
+ if (strchr (s, '|') != NULL
+ && (strchr (info->stack->type, '{') != NULL
+ || strchr (info->stack->type, '(') != NULL))
+ {
+ if (! prepend_type (info, "(")
+ || ! append_type (info, ")"))
+ return false;
+ }
+
+ if (*s == '\0')
+ return true;
+
+ return (append_type (info, " ")
+ && append_type (info, s));
+}
+
+/* Indent the type at the top of the stack by appending spaces. */
+
+static boolean
+indent_type (info)
+ struct pr_handle *info;
+{
+ unsigned int i;
+
+ for (i = 0; i < info->indent; i++)
+ {
+ if (! append_type (info, " "))
+ return false;
+ }
+
+ return true;
+}
+
+/* Pop a type from the type stack. */
+
+static char *
+pop_type (info)
+ struct pr_handle *info;
+{
+ struct pr_stack *o;
+ char *ret;
+
+ assert (info->stack != NULL);
+
+ o = info->stack;
+ info->stack = o->next;
+ ret = o->type;
+ free (o);
+
+ return ret;
+}
+
+/* Print a VMA value into a string. */
+
+static void
+print_vma (vma, buf, unsignedp, hexp)
+ bfd_vma vma;
+ char *buf;
+ boolean unsignedp;
+ boolean hexp;
+{
+ if (sizeof (vma) <= sizeof (unsigned long))
+ {
+ if (hexp)
+ sprintf (buf, "0x%lx", (unsigned long) vma);
+ else if (unsignedp)
+ sprintf (buf, "%lu", (unsigned long) vma);
+ else
+ sprintf (buf, "%ld", (long) vma);
+ }
+ else
+ {
+ buf[0] = '0';
+ buf[1] = 'x';
+ sprintf_vma (buf + 2, vma);
+ }
+}
+
+/* Start a new compilation unit. */
+
+static boolean
+pr_start_compilation_unit (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->indent == 0);
+/*
+ TRACE_FPRINTF( (info->f, "%s:\n", filename));
+*/
+ return true;
+}
+
+/* Start a source file within a compilation unit. */
+
+static boolean
+pr_start_source (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->indent == 0);
+/*
+ TRACE_FPRINTF( (info->f, " %s:\n", filename));
+*/
+ return true;
+}
+
+/* Push an empty type onto the type stack. */
+
+static boolean
+pr_empty_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return push_type (info, "<undefined>");
+}
+
+/* Push a void type onto the type stack. */
+
+static boolean
+pr_void_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return push_type (info, "void");
+}
+
+/* Push an integer type onto the type stack. */
+
+static boolean
+pr_int_type (p, size, unsignedp)
+ PTR p;
+ unsigned int size;
+ boolean unsignedp;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[10];
+
+ sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
+ return push_type (info, ab);
+}
+
+/* Push a floating type onto the type stack. */
+
+static boolean
+pr_float_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[10];
+
+ if (size == 4)
+ return push_type (info, "float");
+ else if (size == 8)
+ return push_type (info, "double");
+
+ sprintf (ab, "float%d", size * 8);
+ return push_type (info, ab);
+}
+
+/* Push a complex type onto the type stack. */
+
+static boolean
+pr_complex_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ if (! pr_float_type (p, size))
+ return false;
+
+ return prepend_type (info, "complex ");
+}
+
+/* Push a boolean type onto the type stack. */
+
+static boolean
+pr_bool_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[10];
+
+ sprintf (ab, "bool%d", size * 8);
+
+ return push_type (info, ab);
+}
+
+/* Push an enum type onto the type stack. */
+
+static boolean
+pr_enum_type (p, tag, names, values)
+ PTR p;
+ const char *tag;
+ const char **names;
+ bfd_signed_vma *values;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ unsigned int i;
+ bfd_signed_vma val;
+
+ if (! push_type (info, "enum "))
+ return false;
+ if (tag != NULL)
+ {
+ if (! append_type (info, tag)
+ || ! append_type (info, " "))
+ return false;
+ }
+ if (! append_type (info, "{ "))
+ return false;
+
+ if (names == NULL)
+ {
+ if (! append_type (info, "/* undefined */"))
+ return false;
+ }
+ else
+ {
+ val = 0;
+ for (i = 0; names[i] != NULL; i++)
+ {
+ if (i > 0)
+ {
+ if (! append_type (info, ", "))
+ return false;
+ }
+
+ if (! append_type (info, names[i]))
+ return false;
+
+ if (values[i] != val)
+ {
+ char ab[20];
+
+ print_vma (values[i], ab, false, false);
+ if (! append_type (info, " = ")
+ || ! append_type (info, ab))
+ return false;
+ val = values[i];
+ }
+
+ ++val;
+ }
+ }
+
+ return append_type (info, " }");
+}
+
+/* Turn the top type on the stack into a pointer. */
+
+static boolean
+pr_pointer_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *s;
+
+ assert (info->stack != NULL);
+
+ s = strchr (info->stack->type, '|');
+ if (s != NULL && s[1] == '[')
+ return substitute_type (info, "(*|)");
+ return substitute_type (info, "*|");
+}
+
+/* Turn the top type on the stack into a function returning that type. */
+
+static boolean
+pr_function_type (p, argcount, varargs)
+ PTR p;
+ int argcount;
+ boolean varargs;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char **arg_types;
+ unsigned int len;
+ char *s;
+
+ assert (info->stack != NULL);
+
+ len = 10;
+
+ if (argcount <= 0)
+ {
+ arg_types = NULL;
+ len += 15;
+ }
+ else
+ {
+ int i;
+
+ arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
+ for (i = argcount - 1; i >= 0; i--)
+ {
+ if (! substitute_type (info, ""))
+ return false;
+ arg_types[i] = pop_type (info);
+ if (arg_types[i] == NULL)
+ return false;
+ len += strlen (arg_types[i]) + 2;
+ }
+ if (varargs)
+ len += 5;
+ }
+
+ /* Now the return type is on the top of the stack. */
+
+ s = (char *) xmalloc (len);
+ strcpy (s, "(|) (");
+
+ if (argcount < 0)
+ {
+#if 0
+ /* Turn off unknown arguments. */
+ strcat (s, "/* unknown */");
+#endif
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < argcount; i++)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, arg_types[i]);
+ }
+ if (varargs)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, "...");
+ }
+ if (argcount > 0)
+ free (arg_types);
+ }
+
+ strcat (s, ")");
+
+ if (! substitute_type (info, s))
+ return false;
+
+ free (s);
+
+ return true;
+}
+
+/* Turn the top type on the stack into a reference to that type. */
+
+static boolean
+pr_reference_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->stack != NULL);
+
+ return substitute_type (info, "&|");
+}
+
+/* Make a range type. */
+
+static boolean
+pr_range_type (p, lower, upper)
+ PTR p;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char abl[20], abu[20];
+
+ assert (info->stack != NULL);
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ print_vma (lower, abl, false, false);
+ print_vma (upper, abu, false, false);
+
+ return (prepend_type (info, "range (")
+ && append_type (info, "):")
+ && append_type (info, abl)
+ && append_type (info, ":")
+ && append_type (info, abu));
+}
+
+/* Make an array type. */
+
+/*ARGSUSED*/
+static boolean
+pr_array_type (p, lower, upper, stringp)
+ PTR p;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+ boolean stringp;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *range_type;
+ char abl[20], abu[20], ab[50];
+
+ range_type = pop_type (info);
+ if (range_type == NULL)
+ return false;
+
+ if (lower == 0)
+ {
+ if (upper == -1)
+ sprintf (ab, "|[]");
+ else
+ {
+ print_vma (upper + 1, abu, false, false);
+ sprintf (ab, "|[%s]", abu);
+ }
+ }
+ else
+ {
+ print_vma (lower, abl, false, false);
+ print_vma (upper, abu, false, false);
+ sprintf (ab, "|[%s:%s]", abl, abu);
+ }
+
+ if (! substitute_type (info, ab))
+ return false;
+
+ if (strcmp (range_type, "int") != 0)
+ {
+ if (! append_type (info, ":")
+ || ! append_type (info, range_type))
+ return false;
+ }
+
+ if (stringp)
+ {
+ if (! append_type (info, " /* string */"))
+ return false;
+ }
+
+ return true;
+}
+
+/* Make a set type. */
+
+/*ARGSUSED*/
+static boolean
+pr_set_type (p, bitstringp)
+ PTR p;
+ boolean bitstringp;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ if (! prepend_type (info, "set { ")
+ || ! append_type (info, " }"))
+ return false;
+
+ if (bitstringp)
+ {
+ if (! append_type (info, "/* bitstring */"))
+ return false;
+ }
+
+ return true;
+}
+
+/* Make an offset type. */
+
+static boolean
+pr_offset_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ return (substitute_type (info, "")
+ && prepend_type (info, " ")
+ && prepend_type (info, t)
+ && append_type (info, "::|"));
+}
+
+/* Make a method type. */
+
+static boolean
+pr_method_type (p, domain, argcount, varargs)
+ PTR p;
+ boolean domain;
+ int argcount;
+ boolean varargs;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ unsigned int len;
+ char *domain_type;
+ char **arg_types;
+ char *s;
+
+ len = 10;
+
+ if (! domain)
+ domain_type = NULL;
+ else
+ {
+ if (! substitute_type (info, ""))
+ return false;
+ domain_type = pop_type (info);
+ if (domain_type == NULL)
+ return false;
+ if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0
+ && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
+ domain_type += sizeof "class " - 1;
+ else if (strncmp (domain_type, "union class ",
+ sizeof "union class ") == 0
+ && (strchr (domain_type + sizeof "union class " - 1, ' ')
+ == NULL))
+ domain_type += sizeof "union class " - 1;
+ len += strlen (domain_type);
+ }
+
+ if (argcount <= 0)
+ {
+ arg_types = NULL;
+ len += 15;
+ }
+ else
+ {
+ int i;
+
+ arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
+ for (i = argcount - 1; i >= 0; i--)
+ {
+ if (! substitute_type (info, ""))
+ return false;
+ arg_types[i] = pop_type (info);
+ if (arg_types[i] == NULL)
+ return false;
+ len += strlen (arg_types[i]) + 2;
+ }
+ if (varargs)
+ len += 5;
+ }
+
+ /* Now the return type is on the top of the stack. */
+
+ s = (char *) xmalloc (len);
+ if (! domain)
+ *s = '\0';
+ else
+ strcpy (s, domain_type);
+ strcat (s, "::| (");
+
+ if (argcount < 0)
+ strcat (s, "/* unknown */");
+ else
+ {
+ int i;
+
+ for (i = 0; i < argcount; i++)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, arg_types[i]);
+ }
+ if (varargs)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, "...");
+ }
+ if (argcount > 0)
+ free (arg_types);
+ }
+
+ strcat (s, ")");
+
+ if (! substitute_type (info, s))
+ return false;
+
+ free (s);
+
+ return true;
+}
+
+/* Make a const qualified type. */
+
+static boolean
+pr_const_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return substitute_type (info, "const |");
+}
+
+/* Make a volatile qualified type. */
+
+static boolean
+pr_volatile_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return substitute_type (info, "volatile |");
+}
+
+/* Start accumulating a struct type. */
+
+static boolean
+pr_start_struct_type (p, tag, id, structp, size)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ info->indent += 2;
+
+ if (! push_type (info, structp ? "struct " : "union "))
+ return false;
+ if (tag != NULL)
+ {
+ if (! append_type (info, tag))
+ return false;
+ }
+ else
+ {
+ char idbuf[20];
+
+ sprintf (idbuf, "%%anon%u", id);
+ if (! append_type (info, idbuf))
+ return false;
+ }
+
+ if (! append_type (info, " {"))
+ return false;
+ if (size != 0 || tag != NULL)
+ {
+ char ab[30];
+
+ if (! append_type (info, " /*"))
+ return false;
+
+ if (size != 0)
+ {
+ sprintf (ab, " size %u", size);
+ if (! append_type (info, ab))
+ return false;
+ }
+ if (tag != NULL)
+ {
+ sprintf (ab, " id %u", id);
+ if (! append_type (info, ab))
+ return false;
+ }
+ if (! append_type (info, " */"))
+ return false;
+ }
+ if (! append_type (info, "\n"))
+ return false;
+
+ info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
+
+ return indent_type (info);
+}
+
+/* Output the visibility of a field in a struct. */
+
+static boolean
+pr_fix_visibility (info, visibility)
+ struct pr_handle *info;
+ enum debug_visibility visibility;
+{
+ const char *s;
+ char *t;
+ unsigned int len;
+
+ assert (info->stack != NULL);
+
+ if (info->stack->visibility == visibility)
+ return true;
+
+ assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
+
+ switch (visibility)
+ {
+ case DEBUG_VISIBILITY_PUBLIC:
+ s = "public";
+ break;
+ case DEBUG_VISIBILITY_PRIVATE:
+ s = "private";
+ break;
+ case DEBUG_VISIBILITY_PROTECTED:
+ s = "protected";
+ break;
+ case DEBUG_VISIBILITY_IGNORE:
+ s = "/* ignore */";
+ break;
+ default:
+ abort ();
+ return false;
+ }
+
+ /* Trim off a trailing space in the struct string, to make the
+ output look a bit better, then stick on the visibility string. */
+
+ t = info->stack->type;
+ len = strlen (t);
+ assert (t[len - 1] == ' ');
+ t[len - 1] = '\0';
+
+ if (! append_type (info, s)
+ || ! append_type (info, ":\n")
+ || ! indent_type (info))
+ return false;
+
+ info->stack->visibility = visibility;
+
+ return true;
+}
+
+/* Add a field to a struct type. */
+
+static boolean
+pr_struct_field (p, name, bitpos, bitsize, visibility)
+ PTR p;
+ const char *name;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+ enum debug_visibility visibility;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+ char *t;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ if (! append_type (info, "; /* "))
+ return false;
+
+ if (bitsize != 0)
+ {
+ print_vma (bitsize, ab, true, false);
+ if (! append_type (info, "bitsize ")
+ || ! append_type (info, ab)
+ || ! append_type (info, ", "))
+ return false;
+ }
+
+ print_vma (bitpos, ab, true, false);
+ if (! append_type (info, "bitpos ")
+ || ! append_type (info, ab)
+ || ! append_type (info, " */\n")
+ || ! indent_type (info))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ return append_type (info, t);
+}
+
+/* Finish a struct type. */
+
+static boolean
+pr_end_struct_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *s;
+
+ assert (info->stack != NULL);
+ assert (info->indent >= 2);
+
+ info->indent -= 2;
+
+ /* Change the trailing indentation to have a close brace. */
+ s = info->stack->type + strlen (info->stack->type) - 2;
+ assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
+
+ *s++ = '}';
+ *s = '\0';
+
+ return true;
+}
+
+/* Start a class type. */
+
+static boolean
+pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+ boolean vptr;
+ boolean ownvptr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *tv = NULL;
+
+ info->indent += 2;
+
+ if (vptr && ! ownvptr)
+ {
+ tv = pop_type (info);
+ if (tv == NULL)
+ return false;
+ }
+
+ if (! push_type (info, structp ? "class " : "union class "))
+ return false;
+ if (tag != NULL)
+ {
+ if (! append_type (info, tag))
+ return false;
+ }
+ else
+ {
+ char idbuf[20];
+
+ sprintf (idbuf, "%%anon%u", id);
+ if (! append_type (info, idbuf))
+ return false;
+ }
+
+ if (! append_type (info, " {"))
+ return false;
+ if (size != 0 || vptr || ownvptr || tag != NULL)
+ {
+ if (! append_type (info, " /*"))
+ return false;
+
+ if (size != 0)
+ {
+ char ab[20];
+
+ sprintf (ab, "%u", size);
+ if (! append_type (info, " size ")
+ || ! append_type (info, ab))
+ return false;
+ }
+
+ if (vptr)
+ {
+ if (! append_type (info, " vtable "))
+ return false;
+ if (ownvptr)
+ {
+ if (! append_type (info, "self "))
+ return false;
+ }
+ else
+ {
+ if (! append_type (info, tv)
+ || ! append_type (info, " "))
+ return false;
+ }
+ }
+
+ if (tag != NULL)
+ {
+ char ab[30];
+
+ sprintf (ab, " id %u", id);
+ if (! append_type (info, ab))
+ return false;
+ }
+
+ if (! append_type (info, " */"))
+ return false;
+ }
+
+ info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
+
+ return (append_type (info, "\n")
+ && indent_type (info));
+}
+
+/* Add a static member to a class. */
+
+static boolean
+pr_class_static_member (p, name, physname, visibility)
+ PTR p;
+ const char *name;
+ const char *physname;
+ enum debug_visibility visibility;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ if (! prepend_type (info, "static ")
+ || ! append_type (info, "; /* ")
+ || ! append_type (info, physname)
+ || ! append_type (info, " */\n")
+ || ! indent_type (info))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ return append_type (info, t);
+}
+
+/* Add a base class to a class. */
+
+static boolean
+pr_class_baseclass (p, bitpos, virtual, visibility)
+ PTR p;
+ bfd_vma bitpos;
+ boolean virtual;
+ enum debug_visibility visibility;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+ const char *prefix;
+ char ab[20];
+ char *s, *l, *n;
+
+ assert (info->stack != NULL && info->stack->next != NULL);
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ if (strncmp (t, "class ", sizeof "class " - 1) == 0)
+ t += sizeof "class " - 1;
+
+ /* Push it back on to take advantage of the prepend_type and
+ append_type routines. */
+ if (! push_type (info, t))
+ return false;
+
+ if (virtual)
+ {
+ if (! prepend_type (info, "virtual "))
+ return false;
+ }
+
+ switch (visibility)
+ {
+ case DEBUG_VISIBILITY_PUBLIC:
+ prefix = "public ";
+ break;
+ case DEBUG_VISIBILITY_PROTECTED:
+ prefix = "protected ";
+ break;
+ case DEBUG_VISIBILITY_PRIVATE:
+ prefix = "private ";
+ break;
+ default:
+ prefix = "/* unknown visibility */ ";
+ break;
+ }
+
+ if (! prepend_type (info, prefix))
+ return false;
+
+ if (bitpos != 0)
+ {
+ print_vma (bitpos, ab, true, false);
+ if (! append_type (info, " /* bitpos ")
+ || ! append_type (info, ab)
+ || ! append_type (info, " */"))
+ return false;
+ }
+
+ /* Now the top of the stack is something like "public A / * bitpos
+ 10 * /". The next element on the stack is something like "class
+ xx { / * size 8 * /\n...". We want to substitute the top of the
+ stack in before the {. */
+ s = strchr (info->stack->next->type, '{');
+ assert (s != NULL);
+ --s;
+
+ /* If there is already a ':', then we already have a baseclass, and
+ we must append this one after a comma. */
+ for (l = info->stack->next->type; l != s; l++)
+ if (*l == ':')
+ break;
+ if (! prepend_type (info, l == s ? " : " : ", "))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
+ memcpy (n, info->stack->type, s - info->stack->type);
+ strcpy (n + (s - info->stack->type), t);
+ strcat (n, s);
+
+ free (info->stack->type);
+ info->stack->type = n;
+
+ free (t);
+
+ return true;
+}
+
+/* Start adding a method to a class. */
+
+static boolean
+pr_class_start_method (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->stack != NULL);
+ info->stack->method = name;
+ return true;
+}
+
+/* Add a variant to a method. */
+
+static boolean
+pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset,
+ context)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean context;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *method_type;
+ char *context_type;
+
+ assert (info->stack != NULL);
+ assert (info->stack->next != NULL);
+
+ /* Put the const and volatile qualifiers on the type. */
+ if (volatilep)
+ {
+ if (! append_type (info, " volatile"))
+ return false;
+ }
+ if (constp)
+ {
+ if (! append_type (info, " const"))
+ return false;
+ }
+
+ /* Stick the name of the method into its type. */
+ if (! substitute_type (info,
+ (context
+ ? info->stack->next->next->method
+ : info->stack->next->method)))
+ return false;
+
+ /* Get the type. */
+ method_type = pop_type (info);
+ if (method_type == NULL)
+ return false;
+
+ /* Pull off the context type if there is one. */
+ if (! context)
+ context_type = NULL;
+ else
+ {
+ context_type = pop_type (info);
+ if (context_type == NULL)
+ return false;
+ }
+
+ /* Now the top of the stack is the class. */
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ if (! append_type (info, method_type)
+ || ! append_type (info, " /* ")
+ || ! append_type (info, physname)
+ || ! append_type (info, " "))
+ return false;
+ if (context || voffset != 0)
+ {
+ char ab[20];
+
+ if (context)
+ {
+ if (! append_type (info, "context ")
+ || ! append_type (info, context_type)
+ || ! append_type (info, " "))
+ return false;
+ }
+ print_vma (voffset, ab, true, false);
+ if (! append_type (info, "voffset ")
+ || ! append_type (info, ab))
+ return false;
+ }
+
+ return (append_type (info, " */;\n")
+ && indent_type (info));
+}
+
+/* Add a static variant to a method. */
+
+static boolean
+pr_class_static_method_variant (p, physname, visibility, constp, volatilep)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *method_type;
+
+ assert (info->stack != NULL);
+ assert (info->stack->next != NULL);
+ assert (info->stack->next->method != NULL);
+
+ /* Put the const and volatile qualifiers on the type. */
+ if (volatilep)
+ {
+ if (! append_type (info, " volatile"))
+ return false;
+ }
+ if (constp)
+ {
+ if (! append_type (info, " const"))
+ return false;
+ }
+
+ /* Mark it as static. */
+ if (! prepend_type (info, "static "))
+ return false;
+
+ /* Stick the name of the method into its type. */
+ if (! substitute_type (info, info->stack->next->method))
+ return false;
+
+ /* Get the type. */
+ method_type = pop_type (info);
+ if (method_type == NULL)
+ return false;
+
+ /* Now the top of the stack is the class. */
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ return (append_type (info, method_type)
+ && append_type (info, " /* ")
+ && append_type (info, physname)
+ && append_type (info, " */;\n")
+ && indent_type (info));
+}
+
+/* Finish up a method. */
+
+static boolean
+pr_class_end_method (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ info->stack->method = NULL;
+ return true;
+}
+
+/* Finish up a class. */
+
+static boolean
+pr_end_class_type (p)
+ PTR p;
+{
+ return pr_end_struct_type (p);
+}
+
+/* Push a type on the stack using a typedef name. */
+
+static boolean
+pr_typedef_type (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return push_type (info, name);
+}
+
+/* Push a type on the stack using a tag name. */
+
+static boolean
+pr_tag_type (p, name, id, kind)
+ PTR p;
+ const char *name;
+ unsigned int id;
+ enum debug_type_kind kind;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ const char *t, *tag;
+ char idbuf[20];
+
+ switch (kind)
+ {
+ case DEBUG_KIND_STRUCT:
+ t = "struct ";
+ break;
+ case DEBUG_KIND_UNION:
+ t = "union ";
+ break;
+ case DEBUG_KIND_ENUM:
+ t = "enum ";
+ break;
+ case DEBUG_KIND_CLASS:
+ t = "class ";
+ break;
+ case DEBUG_KIND_UNION_CLASS:
+ t = "union class ";
+ break;
+ default:
+ abort ();
+ return false;
+ }
+
+ if (! push_type (info, t))
+ return false;
+ if (name != NULL)
+ tag = name;
+ else
+ {
+ sprintf (idbuf, "%%anon%u", id);
+ tag = idbuf;
+ }
+
+ if (! append_type (info, tag))
+ return false;
+ if (name != NULL && kind != DEBUG_KIND_ENUM)
+ {
+ sprintf (idbuf, " /* id %u */", id);
+ if (! append_type (info, idbuf))
+ return false;
+ }
+
+ return true;
+}
+
+/* Output a typedef. */
+
+static boolean
+pr_typdef (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *s;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ s = pop_type (info);
+ if (s == NULL)
+ return false;
+/*
+ indent (info);
+ TRACE_FPRINTF( (info->f, "typedef %s;\n", s));
+*/
+ free (s);
+
+ return true;
+}
+
+/* Output a tag. The tag should already be in the string on the
+ stack, so all we have to do here is print it out. */
+
+/*ARGSUSED*/
+static boolean
+pr_tag (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+/*
+ indent (info);
+ TRACE_FPRINTF( (info->f, "%s;\n", t));
+*/
+ free (t);
+
+ return true;
+}
+
+/* Output an integer constant. */
+
+static boolean
+pr_int_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+/*
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+ indent (info);
+ print_vma (val, ab, false, false);
+ TRACE_FPRINTF( (info->f, "const int %s = %s;\n", name, ab));
+ */
+ return true;
+}
+
+/* Output a floating point constant. */
+
+static boolean
+pr_float_constant (p, name, val)
+ PTR p;
+ const char *name;
+ double val;
+{
+/*
+ struct pr_handle *info = (struct pr_handle *) p;
+ indent (info);
+ TRACE_FPRINTF( (info->f, "const double %s = %g;\n", name, val));
+ */
+ return true;
+}
+
+/* Output a typed constant. */
+
+static boolean
+pr_typed_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+/*
+ char ab[20];
+ indent (info);
+ print_vma (val, ab, false, false);
+ TRACE_FPRINTF( (info->f, "const %s %s = %s;\n", t, name, ab));
+*/
+ free (t);
+
+ return true;
+}
+
+/* Output a variable. */
+
+static boolean
+pr_variable (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+ char ab[20];
+ (void)ab;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+#if 0
+ indent (info);
+ switch (kind)
+ {
+ case DEBUG_STATIC:
+ case DEBUG_LOCAL_STATIC:
+ TRACE_FPRINTF( (info->f, "static "));
+ break;
+ case DEBUG_REGISTER:
+ TRACE_FPRINTF( (info->f, "register "));
+ break;
+ default:
+ break;
+ }
+ print_vma (val, ab, true, true);
+ TRACE_FPRINTF( (info->f, "%s /* %s */;\n", t, ab));
+#else /* 0 */
+#if 0
+ if (kind==DEBUG_STATIC || kind==DEBUG_LOCAL_STATIC) {
+ print_vma (val, ab, true, true);
+ TRACE_FPRINTF( (info->f, "STATIC_VAR: %s /* %s */;\n", t, ab));
+ }
+#endif /* 0 */
+#endif /* !0 */
+
+ free (t);
+
+ return true;
+}
+
+/* Start outputting a function. */
+
+static boolean
+pr_start_function (p, name, global)
+ PTR p;
+ const char *name;
+ boolean global;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+#if 0
+ indent (info);
+ if (! global)
+ TRACE_FPRINTF( (info->f, "static "));
+ TRACE_FPRINTF( (info->f, "%s (", t));
+ info->parameter = 1;
+#else /* 0 */
+ if (info->functions_size==info->functions_maxsize) {
+ info->functions_maxsize *= 2;
+ info->functions = xrealloc(info->functions,
+ info->functions_maxsize*sizeof(debug_function_t));
+ assert(info->functions!=0);
+ }
+ /* info->functions[info->functions_size] = xmalloc(sizeof(debug_function_t)); */
+ info->function = &info->functions[info->functions_size];
+ ++info->functions_size;
+ info->function->symbol = NULL;
+ info->function->lines = NULL;
+ info->function->lines_count = 0;
+ info->function->max_lines_count = 0;
+ info->function->name = t;
+ info->function->filename = NULL;
+ info->function->block = NULL;
+ info->function->argv = NULL;
+ info->function->argc = 0;
+ info->function->max_argc = 0;
+#endif /* !0 */
+ return true;
+}
+
+/* Output a function parameter. */
+
+static boolean
+pr_function_parameter (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_parm_kind kind;
+ bfd_vma val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ debug_function_t* f = info->function;
+ char *t;
+ char ab[20];
+ (void)ab;
+
+ if (kind == DEBUG_PARM_REFERENCE
+ || kind == DEBUG_PARM_REF_REG)
+ {
+ if (! pr_reference_type (p))
+ return false;
+ }
+
+ if (! substitute_type (info, name))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+#if 0
+ if (info->parameter != 1)
+ TRACE_FPRINTF( (info->f, ", "));
+
+ if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
+ TRACE_FPRINTF( (info->f, "register "));
+
+ print_vma (val, ab, true, true);
+ TRACE_FPRINTF( (info->f, "%s /* %s */", t, ab));
+ free (t);
+ ++info->parameter;
+#else /* 0 */
+ assert(f!=NULL);
+ if (f->argv==NULL) {
+ f->max_argc = 7; /* rarely anyone has more than that many args... */
+ f->argv = xmalloc(sizeof(debug_parameter_t)*f->max_argc);
+ } else if (f->argc==f->max_argc) {
+ f->max_argc *= 2;
+ f->argv = realloc(f->argv,sizeof(debug_parameter_t)*f->max_argc);
+ }
+ f->argv[f->argc].offset = val;
+ f->argv[f->argc].name = t;
+ ++f->argc;
+#endif /* !0 */
+ return true;
+}
+
+/* Start writing out a block. */
+
+static boolean
+pr_start_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+ debug_block_t* block = 0;
+ (void)ab;
+#if 0
+ if (info->parameter > 0)
+ {
+ TRACE_FPRINTF( (info->f, ")\n"));
+ info->parameter = 0;
+ }
+ indent (info);
+ print_vma (addr, ab, true, true);
+ TRACE_FPRINTF( (info->f, "{ /* %s */\n", ab));
+ info->indent += 2;
+#else
+ if (info->block) {
+ if (info->block->childs_count==0)
+ info->block->childs = xmalloc(sizeof(debug_block_t));
+ else
+ info->block->childs = xrealloc(info->block->childs,
+ info->block->childs_count*sizeof(debug_block_t));
+ block = &info->block->childs[info->block->childs_count];
+ } else {
+ block = xmalloc(sizeof(debug_block_t));
+ info->function->block = block;
+ }
+ block->begin_addr = addr;
+ block->end_addr = 0;
+ block->parent = info->block;
+ block->childs = NULL;
+ block->childs_count = 0;
+ info->block = block;
+#endif
+ return true;
+}
+
+/* Write out line number information. */
+
+static boolean
+pr_lineno (p, filename, lineno, addr)
+ PTR p;
+ const char *filename;
+ unsigned long lineno;
+ bfd_vma addr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+ debug_function_t* f = info->function;
+ (void)ab;
+
+#if 0
+ indent (info);
+ print_vma (addr, ab, true, true);
+ TRACE_FPRINTF( (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab));
+#else /* 0 */
+ if (f==NULL) /* FIXME: skips junk silently. */
+ return true;
+ /* assert(f!=NULL); */
+ if (f->filename==NULL) {
+ f->filename = filename;
+ assert(f->lines==0);
+ f->max_lines_count = 4;
+ f->lines = xmalloc(sizeof(debug_lineno_t)*f->max_lines_count);
+ }
+ if (f->lines_count==f->max_lines_count) {
+ f->max_lines_count *= 2;
+ f->lines = xrealloc(f->lines, sizeof(debug_lineno_t)*f->max_lines_count);
+ }
+ f->lines[f->lines_count].lineno = lineno;
+ f->lines[f->lines_count].addr = addr;
+ ++f->lines_count;
+#endif /* !0 */
+
+ return true;
+}
+
+/* Finish writing out a block. */
+
+static boolean
+pr_end_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+#if 0
+ char ab[20];
+
+ info->indent -= 2;
+ indent (info);
+ print_vma (addr, ab, true, true);
+ TRACE_FPRINTF( (info->f, "} /* %s */\n", ab));
+#else /* 0 */
+ assert(info->block!=0);
+ info->block->end_addr = addr;
+ info->block = info->block->parent;
+#endif /* !0 */
+
+ return true;
+}
+
+/* Finish writing out a function. */
+
+/*ARGSUSED*/
+static boolean
+pr_end_function (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ assert(info->block==0);
+ info->function = NULL;
+ return true;
+}
+
+/* third parameter to segv_action. */
+/* Got it after a bit of head scratching and stack dumping. */
+typedef struct {
+ u_int32_t foo1; /* +0x00 */
+ u_int32_t foo2;
+ u_int32_t foo3;
+ u_int32_t foo4; /* usually 2 */
+ u_int32_t foo5; /* +0x10 */
+ u_int32_t xgs; /* always zero */
+ u_int32_t xfs; /* always zero */
+ u_int32_t xes; /* always es=ds=ss */
+ u_int32_t xds; /* +0x20 */
+ u_int32_t edi;
+ u_int32_t esi;
+ u_int32_t ebp;
+ u_int32_t esp; /* +0x30 */
+ u_int32_t ebx;
+ u_int32_t edx;
+ u_int32_t ecx;
+ u_int32_t eax; /* +0x40 */
+ u_int32_t foo11; /* usually 0xe */
+ u_int32_t foo12; /* usually 0x6 */
+ u_int32_t eip; /* instruction pointer */
+ u_int32_t xcs; /* +0x50 */
+ u_int32_t foo21; /* usually 0x2 */
+ u_int32_t foo22; /* second stack pointer?! Probably. */
+ u_int32_t xss;
+ u_int32_t foo31; /* +0x60 */ /* usually 0x0 */
+ u_int32_t foo32; /* usually 0x2 */
+ u_int32_t fault_addr; /* Address which caused a fault */
+ u_int32_t foo41; /* usually 0x2 */
+} signal_regs_t;
+
+signal_regs_t* ptrace_regs = 0; /* Tells my_ptrace to "ptrace" current process" */
+/*
+ * my_ptrace: small wrapper around ptrace.
+ * Act as normal ptrace if ptrace_regs==0.
+ * Read data from current process if ptrace_regs!=0.
+ */
+static int
+my_ptrace( int request,
+ int pid,
+ int addr,
+ int data)
+{
+ if (ptrace_regs==0)
+ return ptrace(request, pid, addr, data);
+ /* we are tracing ourselves! */
+ switch (request) {
+ case PTRACE_ATTACH: return 0;
+ case PTRACE_CONT: return 0;
+ case PTRACE_DETACH: return 0;
+ case PTRACE_PEEKUSER:
+ switch (addr / 4) {
+ case EIP: return ptrace_regs->eip;
+ case EBP: return ptrace_regs->ebp;
+ default: assert(0);
+ }
+ case PTRACE_PEEKTEXT: /* FALLTHROUGH */
+ case PTRACE_PEEKDATA: return *(int*)(addr);
+ default: assert(0);
+ }
+ errno = 1; /* what to do here? */
+ return 1; /* failed?! */
+}
+
+#define MAXARGS 6
+
+/*
+ * To minimize the number of parameters.
+ */
+typedef struct {
+ asymbol** syms; /* Sorted! */
+ int symcount;
+ debug_function_t** functions;
+ int functions_size;
+} symbol_data_t;
+
+/*
+ * Perform a search. A binary search for a symbol.
+ */
+static void
+decode_symbol( symbol_data_t* symbol_data,
+ const unsigned long addr,
+ char* buf,
+ const int bufsize)
+{
+ asymbol** syms = symbol_data->syms;
+ const int symcount = symbol_data->symcount;
+ int bottom = 0;
+ int top = symcount - 1;
+ int i;
+ if (symcount==0) {
+ sprintf(buf, "????");
+ return;
+ }
+ while (top>bottom+1) {
+ i = (top+bottom) / 2;
+ if (bfd_asymbol_value(syms[i])==addr) {
+ sprintf(buf, "%s", syms[i]->name);
+ return;
+ } else if (bfd_asymbol_value(syms[i]) > addr)
+ top = i;
+ else
+ bottom = i;
+ }
+ i = bottom;
+ if (addr<bfd_asymbol_value(syms[i]) || addr>(syms[i]->section->vma+syms[i]->section->_cooked_size))
+ sprintf(buf, "????");
+ else
+ sprintf(buf, "%s + 0x%lx", syms[i]->name, addr-bfd_asymbol_value(syms[i]));
+}
+
+/*
+ * 1. Perform a binary search for an debug_function_t.
+ * 2. Fill buf/bufsize with name, parameters and lineno, if found
+ * Or with '????' otherwise.
+ */
+static debug_function_t*
+find_debug_function_t( symbol_data_t* symbol_data,
+ const pid_t pid,
+ const unsigned long fp, /* frame pointer */
+ const unsigned long addr,
+ char* buf, /* string buffer */
+ const int bufsize)/* FIXME: not used! */
+{
+ debug_function_t** syms = symbol_data->functions;
+ debug_function_t* f = NULL;
+ debug_block_t* block = NULL;
+ debug_lineno_t* lineno = NULL;
+ const int symcount = symbol_data->functions_size;
+ int bottom = 0;
+ int top = symcount - 1;
+ int i;
+ char* bufptr = buf;
+
+ if (symcount==0) {
+ sprintf(buf, "????");
+ return NULL;
+ }
+ while (top>bottom+1) {
+ i = (top+bottom) / 2;
+ if (syms[i]->block->begin_addr==addr) {
+ f = syms[i];
+ break;
+ } else if (syms[i]->block->begin_addr > addr)
+ top = i;
+ else
+ if (syms[i]->block->end_addr >= addr) {
+ f = syms[i];
+ break;
+ } else
+ bottom = i;
+ }
+ i = bottom;
+ if (f!=0)
+ block = f->block;
+ else {
+ block = syms[i]->block;
+ if (block->begin_addr>=addr && block->end_addr<=addr)
+ f = syms[i];
+ }
+ if (f==0)
+ sprintf(buf, "????");
+ else {
+ /*
+ * Do the backtrace the GDB way...
+ */
+ unsigned long arg;
+ /* assert(f->lines_count>0); */
+ if (f->lines_count>0) {
+ lineno = &f->lines[f->lines_count-1];
+ for (i=1; i<f->lines_count; ++i)
+ if (f->lines[i].addr>addr) {
+ lineno = &f->lines[i-1];
+ break;
+ }
+ }
+ bufptr[0] = 0;
+ bufptr += sprintf(bufptr, "%s+0x%lx (", f->name, addr-block->begin_addr);
+ for (i=0; i<f->argc; ++i) {
+ bufptr += sprintf(bufptr, "%s = ", f->argv[i].name);
+ /* FIXME: better parameter printing */
+ errno = 0;
+ arg = my_ptrace(PTRACE_PEEKDATA, pid, fp+f->argv[i].offset, 0);
+ assert(errno==0);
+ bufptr += sprintf(bufptr, "0x%x", arg);
+ if (i!=f->argc-1)
+ bufptr += sprintf(bufptr, ", ");
+ }
+ if (lineno!=0)
+ bufptr += sprintf(bufptr, ") at %s:%d", f->filename, lineno->lineno);
+ }
+ return f;
+}
+
+/*
+ * Advance through the stacks and display frames as needed.
+ */
+static int
+my_crawl( int pid,
+ symbol_data_t* symbol_data,
+ int fout)
+{
+ unsigned long pc = 0;
+ unsigned long fp = 0;
+ unsigned long nextfp;
+ unsigned long nargs;
+ unsigned long i;
+ unsigned long arg;
+ char buf[8096]; // FIXME: enough?
+ debug_function_t* f = 0;
+
+ errno = 0;
+
+ pc = my_ptrace(PTRACE_PEEKUSER, pid, EIP * 4, 0);
+ if (!errno)
+ fp = my_ptrace(PTRACE_PEEKUSER, pid, EBP * 4, 0);
+
+ if (!errno) {
+#if 1
+ f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
+ fdprintf(fout,"0x%08lx: %s", pc, buf);
+ for ( ; !errno && fp; ) {
+ nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
+ if (errno)
+ break;
+
+ if (f==0) {
+ nargs = (nextfp - fp - 8) / 4;
+ if (nargs > MAXARGS)
+ nargs = MAXARGS;
+ if (nargs > 0) {
+ fdputs(" (", fout);
+ for (i = 1; i <= nargs; i++) {
+ arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
+ if (errno)
+ break;
+ fdprintf(fout,"%lx", arg);
+ if (i < nargs)
+ fdputs(", ", fout);
+ }
+ fdputc(')', fout);
+ nargs = nextfp - fp - 8 - (4 * nargs);
+ if (!errno && nargs > 0)
+ fdprintf(fout," + %lx\n", nargs);
+ else
+ fdputc('\n', fout);
+ } else
+ fdputc('\n', fout);
+ } else
+ fdputc('\n', fout);
+
+ if (errno || !nextfp)
+ break;
+ pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
+ fp = nextfp;
+ if (errno)
+ break;
+ f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
+ fdprintf(fout,"0x%08lx: %s", pc, buf);
+ }
+#else /* 1 */
+ decode_symbol(symbol_data, pc, buf, sizeof(buf));
+ fdprintf(fout,"0x%08lx: %s", pc, buf);
+ for ( ; !errno && fp; ) {
+ nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
+ if (errno)
+ break;
+
+ nargs = (nextfp - fp - 8) / 4;
+ if (nargs > MAXARGS)
+ nargs = MAXARGS;
+ if (nargs > 0) {
+ fputs(" (", fout);
+ for (i = 1; i <= nargs; i++) {
+ arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
+ if (errno)
+ break;
+ fdprintf(fout,"%lx", arg);
+ if (i < nargs)
+ fputs(", ", fout);
+ }
+ fdputc(')', fout);
+ nargs = nextfp - fp - 8 - (4 * nargs);
+ if (!errno && nargs > 0)
+ fdprintf(fout," + %lx\n", nargs);
+ else
+ fdputc('\n', fout);
+ } else
+ fdputc('\n', fout);
+
+ if (errno || !nextfp)
+ break;
+ pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
+ fp = nextfp;
+ if (errno)
+ break;
+ decode_symbol(symbol_data, pc, buf, sizeof(buf));
+ fdprintf(fout,"0x%08lx: %s", pc, buf);
+ }
+#endif /* !1 */
+ }
+ if (errno)
+ perror("my_crawl");
+ return errno;
+}
+
+/* layout from /usr/src/linux/arch/i386/kernel/process.c */
+static void
+show_regs( signal_regs_t* regs,
+ int fd)
+{
+ /* long cr0 = 0L, cr2 = 0L, cr3 = 0L; */
+
+ fdprintf(fd,"\n");
+ fdprintf(fd,"FAULT ADDR: %08x\n", regs->fault_addr);
+ fdprintf(fd,"EIP: %04x:[<%08x>]",0xffff & regs->xcs,regs->eip);
+ if (regs->xcs & 3)
+ fdprintf(fd," ESP: %04x:%08x",0xffff & regs->xss,regs->esp);
+ /*fdprintf(fd," EFLAGS: %08lx\n",regs->eflags); */
+ fdprintf(fd, "\n");
+ fdprintf(fd,"EAX: %08x EBX: %08x ECX: %08x EDX: %08x\n",
+ regs->eax,regs->ebx,regs->ecx,regs->edx);
+ fdprintf(fd,"ESI: %08x EDI: %08x EBP: %08x",
+ regs->esi, regs->edi, regs->ebp);
+ fdprintf(fd," DS: %04x ES: %04x\n",
+ 0xffff & regs->xds,0xffff & regs->xes);
+ /*
+ __asm__("movl %%cr0, %0": "=r" (cr0));
+ __asm__("movl %%cr2, %0": "=r" (cr2));
+ __asm__("movl %%cr3, %0": "=r" (cr3));
+ fprintf(stderr,"CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3); */
+}
+
+/*
+ * Load a BFD for an executable based on PID. Return 0 on failure.
+ */
+static bfd*
+load_bfd( const int pid)
+{
+ char filename[512];
+ bfd* abfd = 0;
+
+ /* Get the contents from procfs. */
+#if 1
+ sprintf(filename, "/proc/%d/exe", pid);
+#else
+ sprintf(filename, "crashing");
+#endif
+
+ if ((abfd = bfd_openr (filename, 0))== NULL)
+ bfd_nonfatal (filename);
+ else {
+ char** matching;
+ assert(bfd_check_format(abfd, bfd_archive)!=true);
+
+ /*
+ * There is no indication in BFD documentation that it should be done.
+ * God knows why...
+ */
+ if (!bfd_check_format_matches (abfd, bfd_object, &matching)) {
+ bfd_nonfatal (bfd_get_filename (abfd));
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized) {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ }
+ }
+ return abfd;
+}
+
+/*
+ * Those are for qsort. We need only function addresses, so all the others don't count.
+ */
+/*
+ * Compare two BFD::asymbol-s.
+ */
+static int
+compare_symbols(const void* ap,
+ const void* bp)
+{
+ const asymbol *a = *(const asymbol **)ap;
+ const asymbol *b = *(const asymbol **)bp;
+ if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
+ return 1;
+ else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
+ return -1;
+ return 0;
+}
+
+/*
+ * Compare two debug_asymbol_t-s.
+ */
+static int
+compare_debug_function_t(const void* ap,
+ const void* bp)
+{
+ const debug_function_t *a = *(const debug_function_t **)ap;
+ const debug_function_t *b = *(const debug_function_t **)bp;
+ assert(a->block!=0);
+ assert(b->block!=0);
+ {
+ const bfd_vma addr1 = a->block->begin_addr;
+ const bfd_vma addr2 = b->block->begin_addr;
+ if (addr1 > addr2)
+ return 1;
+ else if (addr2 > addr1)
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Filter out (in place) symbols that are useless for stack tracing.
+ * COUNT is the number of elements in SYMBOLS.
+ * Return the number of useful symbols.
+ */
+
+static long
+remove_useless_symbols( asymbol** symbols,
+ long count)
+{
+ asymbol** in_ptr = symbols;
+ asymbol** out_ptr = symbols;
+
+ while (--count >= 0) {
+ asymbol *sym = *in_ptr++;
+
+ if (sym->name == NULL || sym->name[0] == '\0' || sym->value==0)
+ continue;
+ if (sym->flags & (BSF_DEBUGGING))
+ continue;
+ if (bfd_is_und_section (sym->section) || bfd_is_com_section (sym->section))
+ continue;
+ *out_ptr++ = sym;
+ }
+ return out_ptr - symbols;
+}
+
+/*
+ * Debugging information.
+ */
+static bfd* abfd = 0;
+static PTR dhandle = 0;
+static asymbol** syms = 0;
+static long symcount = 0;
+static asymbol** sorted_syms = 0;
+static long sorted_symcount = 0;
+static debug_function_t** functions = 0;
+static int functions_size = 0;
+static int sigreport = SIGUSR1;
+static pthread_t segv_tid; /* What thread did SEGV? */
+static pid_t segv_pid;
+
+/*
+ * We'll get here after a SIGSEGV. But you can install it on other signals, too :)
+ * Because we are in the middle of the SIGSEGV, we are on our own. We can't do
+ * any malloc(), any fopen(), nothing. The last is actually a sin. We event can't
+ * fprintf(stderr,...)!!!
+ */
+static void
+segv_action(int signo, siginfo_t* siginfo, void* ptr)
+{
+ symbol_data_t symbol_data;
+ int fd = -1;
+
+ segv_pid = getpid();
+ segv_tid = pthread_self();
+ fd = open_log_file(segv_tid, segv_pid);
+ /* signal(SIGSEGV, SIG_DFL); */
+ ptrace_regs = (signal_regs_t*)ptr;
+ assert(ptrace_regs!=0);
+
+ /* Show user how guilty we are. */
+ fdprintf(fd,"--------- SEGV in PROCESS %d, THREAD %d ---------------\n", segv_pid, pthread_self());
+ show_regs(ptrace_regs, fd);
+
+ /* Some form of stack trace, too. */
+ fdprintf(fd, "STACK TRACE:\n");
+
+ symbol_data.syms = sorted_syms;
+ symbol_data.symcount = sorted_symcount;
+ symbol_data.functions = functions;
+ symbol_data.functions_size = functions_size;
+ my_crawl(segv_pid, &symbol_data, fd);
+ //fflush(stdout);
+ close(fd);
+ linuxthreads_notify_others(sigreport);
+}
+
+
+static void
+report_action(int signo, siginfo_t* siginfo, void* ptr)
+{
+ const int pid = getpid();
+ pthread_t tid = pthread_self();
+ symbol_data_t symbol_data;
+ int fd;
+ if (pthread_equal(tid, segv_tid)) {
+ /* We have already printed our stack trace... */
+ return;
+ }
+
+ fd = open_log_file(tid, pid);
+ fdprintf(fd, "REPORT: CURRENT PROCESS:%d, THREAD:%d\n", getpid(), pthread_self());
+ /* signal(SIGSEGV, SIG_DFL); */
+ ptrace_regs = (signal_regs_t*)ptr;
+ assert(ptrace_regs!=0);
+
+ /* Show user how guilty we are. */
+ fdprintf(fd,"--------- STACK TRACE FOR PROCESS %d, THREAD %d ---------------\n", pid, pthread_self());
+ show_regs(ptrace_regs, fd);
+
+ /* Some form of stack trace, too. */
+ fdprintf(fd, "STACK TRACE:\n");
+
+ symbol_data.syms = sorted_syms;
+ symbol_data.symcount = sorted_symcount;
+ symbol_data.functions = functions;
+ symbol_data.functions_size = functions_size;
+ my_crawl(pid, &symbol_data, fd);
+ //fflush(stdout);
+ close(fd);
+ /* Tell segv_thread to proceed after pause(). */
+ /*pthread_kill(segv_tid, sigreport);
+ kill(segv_pid, sigreport);
+ pthread_cancel(tid); */
+}
+
+/*
+ * Main library routine. Just call it on your program.
+ */
+int
+pstack_install_segv_action( const char* path_format_)
+{
+ const int pid = getpid();
+ struct sigaction act;
+
+ /* Store what we have to for later usage. */
+ path_format = path_format_;
+
+ /* We need a signal action for SIGSEGV and sigreport ! */
+ sigreport = SIGUSR1;
+ act.sa_handler = 0;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO|SA_ONESHOT; /* Just one SIGSEGV. */
+ act.sa_sigaction = segv_action;
+ act.sa_restorer = NULL;
+ if (sigaction(SIGSEGV, &act, NULL)!=0) {
+ perror("sigaction");
+ return 1;
+ }
+ act.sa_sigaction = report_action;
+ act.sa_flags = SA_SIGINFO; /* But many sigreports. */
+ if (sigaction(sigreport, &act, NULL)!=0) {
+ perror("sigaction");
+ return 1;
+ }
+
+ /* And a little setup for libiberty. */
+ program_name = "crashing";
+ xmalloc_set_program_name (program_name);
+
+ /* Umm, and initialize BFD, too */
+ bfd_init();
+#if 0
+ list_supported_targets(0, stdout);
+ set_default_bfd_target();
+#endif /* 0 */
+
+ if ((abfd = load_bfd(pid))==0)
+ fprintf(stderr, "BFD load failed..\n");
+ else {
+ long storage_needed = bfd_get_symtab_upper_bound (abfd);
+ long i;
+ (void)i;
+
+ if (storage_needed < 0)
+ fprintf(stderr, "Symbol table size estimation failure.\n");
+ else if (storage_needed > 0) {
+ syms = (asymbol **) xmalloc (storage_needed);
+ symcount = bfd_canonicalize_symtab (abfd, syms);
+
+ TRACE_FPRINTF((stderr, "TOTAL: %ld SYMBOLS.\n", symcount));
+ /* We need debugging info, too! */
+ if (symcount==0 || (dhandle = read_debugging_info (abfd, syms, symcount))==0)
+ fprintf(stderr, "NO DEBUGGING INFORMATION FOUND.\n");
+
+ /* We make a copy of syms to sort. We don't want to sort syms
+ because that will screw up the relocs. */
+ sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
+ memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
+
+#if 0
+ for (i=0; i<symcount; ++i)
+ if (syms[i]->name!=0 && strlen(syms[i]->name)>0 && syms[i]->value!=0)
+ printf("%08lx T %s\n", syms[i]->section->vma + syms[i]->value, syms[i]->name);
+#endif
+ sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
+ TRACE_FPRINTF((stderr, "SORTED: %ld SYMBOLS.\n", sorted_symcount));
+
+ /* Sort the symbols into section and symbol order */
+ qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
+#if 0
+ for (i=0; i<sorted_symcount; ++i)
+ if (sorted_syms[i]->name!=0 && strlen(sorted_syms[i]->name)>0 && sorted_syms[i]->value!=0)
+ printf("%08lx T %s\n", sorted_syms[i]->section->vma + sorted_syms[i]->value, sorted_syms[i]->name);
+#endif
+ /* We have symbols, we need debugging info somehow sorted out. */
+ if (dhandle==0) {
+ fprintf(stderr, "STACK TRACE WILL BE UNCOMFORTABLE.\n");
+ } else {
+ /* Start collecting the debugging information.... */
+ struct pr_handle info;
+
+ info.f = stdout;
+ info.indent = 0;
+ info.stack = NULL;
+ info.parameter = 0;
+ info.block = NULL;
+ info.function = NULL;
+ info.functions_size = 0;
+ info.functions_maxsize = 1000;
+ info.functions = (debug_function_t*)xmalloc(sizeof(debug_function_t)*info.functions_maxsize);
+ debug_write (dhandle, &pr_fns, (PTR) &info);
+ TRACE_FPRINTF((stdout, "\n%d DEBUG SYMBOLS\n", info.functions_size));
+ assert(info.functions_size!=0);
+ functions = xmalloc(sizeof(debug_function_t*)*info.functions_size);
+ functions_size = info.functions_size;
+ for (i=0; i<functions_size; ++i)
+ functions[i] = &info.functions[i];
+ /* Sort the symbols into section and symbol order */
+ qsort (functions, functions_size, sizeof(debug_function_t*),
+ compare_debug_function_t);
+#if 0
+ for (i=0; i<info.functions_size; ++i)
+ fprintf(stdout, "%08lx T %s\n", info.functions[i].block->begin_addr, info.functions[i].name);
+#endif
+ fflush(stdout);
+ }
+ } else /* storage_needed == 0 */
+ fprintf(stderr, "NO SYMBOLS FOUND.\n");
+ }
+ return 0;
+}
+
+/*********************************************************************/
+/*********************************************************************/
+/*********************************************************************/
diff --git a/pstack/pstack.h b/pstack/pstack.h
new file mode 100644
index 00000000000..4c4fad7e754
--- /dev/null
+++ b/pstack/pstack.h
@@ -0,0 +1,22 @@
+/* $Header$ */
+
+#ifndef pstack_pstack_h_
+#define pstack_pstack_h_
+
+#include "pstacktrace.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Install the stack-trace-on-SEGV handler....
+ */
+extern int
+pstack_install_segv_action( const char* path_format);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pstack_pstack_h_ */
+
diff --git a/pstack/pstacktrace.h b/pstack/pstacktrace.h
new file mode 100644
index 00000000000..c884bcb9f87
--- /dev/null
+++ b/pstack/pstacktrace.h
@@ -0,0 +1,24 @@
+/* $Header$ */
+
+/*
+ * Debugging macros.
+ */
+
+#ifndef pstacktrace_h_
+#define pstacktrace_h_
+
+#define PSTACK_DEBUG 1
+#undef PSTACK_DEBUG
+
+#ifdef PSTACK_DEBUG
+# define TRACE_PUTC(a) putc a
+# define TRACE_FPUTS(a) fputs a
+# define TRACE_FPRINTF(a) fprintf a
+#else /* PSTACK_DEBUG */
+# define TRACE_PUTC(a) (void)0
+# define TRACE_FPUTS(a) (void)0
+# define TRACE_FPRINTF(a) (void)0
+#endif /* !PSTACK_DEBUG */
+
+#endif /* pstacktrace_h_ */
+
diff --git a/pstack/rddbg.c b/pstack/rddbg.c
new file mode 100644
index 00000000000..be3dfc21c57
--- /dev/null
+++ b/pstack/rddbg.c
@@ -0,0 +1,462 @@
+/* rddbg.c -- Read debugging information into a generic form.
+ Copyright (C) 1995, 96, 1997 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file reads debugging information into a generic form. This
+ file knows how to dig the debugging information out of an object
+ file. */
+
+#include <bfd.h>
+#include "bucomm.h"
+#include <libiberty.h>
+#include "debug.h"
+#include "budbg.h"
+
+static boolean read_section_stabs_debugging_info
+ PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
+static boolean read_symbol_stabs_debugging_info
+ PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
+static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *));
+static void save_stab PARAMS ((int, int, bfd_vma, const char *));
+static void stab_context PARAMS ((void));
+static void free_saved_stabs PARAMS ((void));
+
+/* Read debugging information from a BFD. Returns a generic debugging
+ pointer. */
+
+PTR
+read_debugging_info (abfd, syms, symcount)
+ bfd *abfd;
+ asymbol **syms;
+ long symcount;
+{
+ PTR dhandle;
+ boolean found;
+
+ dhandle = debug_init ();
+ if (dhandle == NULL)
+ return NULL;
+
+ if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
+ &found))
+ return NULL;
+
+ if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
+ {
+ if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle,
+ &found))
+ return NULL;
+ }
+
+ if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour)
+ {
+ if (! read_ieee_debugging_info (abfd, dhandle, &found))
+ return NULL;
+ }
+
+ /* Try reading the COFF symbols if we didn't find any stabs in COFF
+ sections. */
+ if (! found
+ && bfd_get_flavour (abfd) == bfd_target_coff_flavour
+ && symcount > 0)
+ {
+#if 0
+/*
+ * JZ: Do we need coff?
+ */
+ if (! parse_coff (abfd, syms, symcount, dhandle))
+#else
+ fprintf (stderr, "%s: COFF support temporarily disabled\n",
+ bfd_get_filename (abfd));
+ return NULL;
+#endif
+ return NULL;
+ found = true;
+ }
+
+ if (! found)
+ {
+ fprintf (stderr, "%s: no recognized debugging information\n",
+ bfd_get_filename (abfd));
+ return NULL;
+ }
+
+ return dhandle;
+}
+
+/* Read stabs in sections debugging information from a BFD. */
+
+static boolean
+read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
+ bfd *abfd;
+ asymbol **syms;
+ long symcount;
+ PTR dhandle;
+ boolean *pfound;
+{
+ static struct
+ {
+ const char *secname;
+ const char *strsecname;
+ } names[] = { { ".stab", ".stabstr" } };
+ unsigned int i;
+ PTR shandle;
+
+ *pfound = false;
+ shandle = NULL;
+
+ for (i = 0; i < sizeof names / sizeof names[0]; i++)
+ {
+ asection *sec, *strsec;
+
+ sec = bfd_get_section_by_name (abfd, names[i].secname);
+ strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
+ if (sec != NULL && strsec != NULL)
+ {
+ bfd_size_type stabsize, strsize;
+ bfd_byte *stabs, *strings;
+ bfd_byte *stab;
+ bfd_size_type stroff, next_stroff;
+
+ stabsize = bfd_section_size (abfd, sec);
+ stabs = (bfd_byte *) xmalloc (stabsize);
+ if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
+ {
+ fprintf (stderr, "%s: %s: %s\n",
+ bfd_get_filename (abfd), names[i].secname,
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ strsize = bfd_section_size (abfd, strsec);
+ strings = (bfd_byte *) xmalloc (strsize);
+ if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
+ {
+ fprintf (stderr, "%s: %s: %s\n",
+ bfd_get_filename (abfd), names[i].strsecname,
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ if (shandle == NULL)
+ {
+ shandle = start_stab (dhandle, abfd, true, syms, symcount);
+ if (shandle == NULL)
+ return false;
+ }
+
+ *pfound = true;
+
+ stroff = 0;
+ next_stroff = 0;
+ for (stab = stabs; stab < stabs + stabsize; stab += 12)
+ {
+ bfd_size_type strx;
+ int type;
+ int other;
+ int desc;
+ bfd_vma value;
+
+ /* This code presumes 32 bit values. */
+
+ strx = bfd_get_32 (abfd, stab);
+ type = bfd_get_8 (abfd, stab + 4);
+ other = bfd_get_8 (abfd, stab + 5);
+ desc = bfd_get_16 (abfd, stab + 6);
+ value = bfd_get_32 (abfd, stab + 8);
+
+ if (type == 0)
+ {
+ /* Special type 0 stabs indicate the offset to the
+ next string table. */
+ stroff = next_stroff;
+ next_stroff += value;
+ }
+ else
+ {
+ char *f, *s;
+
+ f = NULL;
+ s = (char *) strings + stroff + strx;
+ while (s[strlen (s) - 1] == '\\'
+ && stab + 12 < stabs + stabsize)
+ {
+ char *p;
+
+ stab += 12;
+ p = s + strlen (s) - 1;
+ *p = '\0';
+ s = concat (s,
+ ((char *) strings
+ + stroff
+ + bfd_get_32 (abfd, stab)),
+ (const char *) NULL);
+
+ /* We have to restore the backslash, because, if
+ the linker is hashing stabs strings, we may
+ see the same string more than once. */
+ *p = '\\';
+
+ if (f != NULL)
+ free (f);
+ f = s;
+ }
+
+ save_stab (type, desc, value, s);
+
+ if (! parse_stab (dhandle, shandle, type, desc, value, s))
+ {
+#if 0
+/*
+ * JZ: skip the junk.
+ */
+ stab_context ();
+ free_saved_stabs ();
+ return false;
+#endif
+ }
+
+ /* Don't free f, since I think the stabs code
+ expects strings to hang around. This should be
+ straightened out. FIXME. */
+ }
+ }
+
+ free_saved_stabs ();
+ free (stabs);
+
+ /* Don't free strings, since I think the stabs code expects
+ the strings to hang around. This should be straightened
+ out. FIXME. */
+ }
+ }
+
+ if (shandle != NULL)
+ {
+ if (! finish_stab (dhandle, shandle))
+ return false;
+ }
+
+ return true;
+}
+
+/* Read stabs in the symbol table. */
+
+static boolean
+read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
+ bfd *abfd;
+ asymbol **syms;
+ long symcount;
+ PTR dhandle;
+ boolean *pfound;
+{
+ PTR shandle;
+ asymbol **ps, **symend;
+
+ shandle = NULL;
+ symend = syms + symcount;
+ for (ps = syms; ps < symend; ps++)
+ {
+ symbol_info i;
+
+ bfd_get_symbol_info (abfd, *ps, &i);
+
+ if (i.type == '-')
+ {
+ const char *s;
+ char *f;
+
+ if (shandle == NULL)
+ {
+ shandle = start_stab (dhandle, abfd, false, syms, symcount);
+ if (shandle == NULL)
+ return false;
+ }
+
+ *pfound = true;
+
+ s = i.name;
+ f = NULL;
+ while (s[strlen (s) - 1] == '\\'
+ && ps + 1 < symend)
+ {
+ char *sc, *n;
+
+ ++ps;
+ sc = xstrdup (s);
+ sc[strlen (sc) - 1] = '\0';
+ n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
+ free (sc);
+ if (f != NULL)
+ free (f);
+ f = n;
+ s = n;
+ }
+
+ save_stab (i.stab_type, i.stab_desc, i.value, s);
+
+ if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
+ i.value, s))
+ {
+ stab_context ();
+ free_saved_stabs ();
+ return false;
+ }
+
+ /* Don't free f, since I think the stabs code expects
+ strings to hang around. This should be straightened out.
+ FIXME. */
+ }
+ }
+
+ free_saved_stabs ();
+
+ if (shandle != NULL)
+ {
+ if (! finish_stab (dhandle, shandle))
+ return false;
+ }
+
+ return true;
+}
+
+/* Read IEEE debugging information. */
+
+static boolean
+read_ieee_debugging_info (abfd, dhandle, pfound)
+ bfd *abfd;
+ PTR dhandle;
+ boolean *pfound;
+{
+ asection *dsec;
+ bfd_size_type size;
+ bfd_byte *contents;
+
+ /* The BFD backend puts the debugging information into a section
+ named .debug. */
+
+ dsec = bfd_get_section_by_name (abfd, ".debug");
+ if (dsec == NULL)
+ return true;
+
+ size = bfd_section_size (abfd, dsec);
+ contents = (bfd_byte *) xmalloc (size);
+ if (! bfd_get_section_contents (abfd, dsec, contents, 0, size))
+ return false;
+
+ if (! parse_ieee (dhandle, abfd, contents, size))
+ return false;
+
+ free (contents);
+
+ *pfound = true;
+
+ return true;
+}
+
+/* Record stabs strings, so that we can give some context for errors. */
+
+#define SAVE_STABS_COUNT (16)
+
+struct saved_stab
+{
+ int type;
+ int desc;
+ bfd_vma value;
+ char *string;
+};
+
+static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
+static int saved_stabs_index;
+
+/* Save a stabs string. */
+
+static void
+save_stab (type, desc, value, string)
+ int type;
+ int desc;
+ bfd_vma value;
+ const char *string;
+{
+ if (saved_stabs[saved_stabs_index].string != NULL)
+ free (saved_stabs[saved_stabs_index].string);
+ saved_stabs[saved_stabs_index].type = type;
+ saved_stabs[saved_stabs_index].desc = desc;
+ saved_stabs[saved_stabs_index].value = value;
+ saved_stabs[saved_stabs_index].string = xstrdup (string);
+ saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
+}
+
+/* Provide context for an error. */
+
+static void
+stab_context ()
+{
+ int i;
+
+ fprintf (stderr, "Last stabs entries before error:\n");
+ fprintf (stderr, "n_type n_desc n_value string\n");
+
+ i = saved_stabs_index;
+ do
+ {
+ struct saved_stab *stabp;
+
+ stabp = saved_stabs + i;
+ if (stabp->string != NULL)
+ {
+ const char *s;
+
+ s = bfd_get_stab_name (stabp->type);
+ if (s != NULL)
+ fprintf (stderr, "%-6s", s);
+ else if (stabp->type == 0)
+ fprintf (stderr, "HdrSym");
+ else
+ fprintf (stderr, "%-6d", stabp->type);
+ fprintf (stderr, " %-6d ", stabp->desc);
+ fprintf_vma (stderr, stabp->value);
+ if (stabp->type != 0)
+ fprintf (stderr, " %s", stabp->string);
+ fprintf (stderr, "\n");
+ }
+ i = (i + 1) % SAVE_STABS_COUNT;
+ }
+ while (i != saved_stabs_index);
+}
+
+/* Free the saved stab strings. */
+
+static void
+free_saved_stabs ()
+{
+ int i;
+
+ for (i = 0; i < SAVE_STABS_COUNT; i++)
+ {
+ if (saved_stabs[i].string != NULL)
+ {
+ free (saved_stabs[i].string);
+ saved_stabs[i].string = NULL;
+ }
+ }
+
+ saved_stabs_index = 0;
+}
diff --git a/pstack/stabs.c b/pstack/stabs.c
new file mode 100644
index 00000000000..076231d19cb
--- /dev/null
+++ b/pstack/stabs.c
@@ -0,0 +1,5082 @@
+/* stabs.c -- Parse stabs debugging information
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GNU Binutils.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file contains code which parses stabs debugging information.
+ The organization of this code is based on the gdb stabs reading
+ code. The job it does is somewhat different, because it is not
+ trying to identify the correct address for anything. */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include <bfd.h>
+#include "bucomm.h"
+#include <libiberty.h>
+#include "demangle.h"
+#include "debug.h"
+#include "budbg.h"
+
+/* Meaningless definition needs by aout64.h. FIXME. */
+#define BYTES_IN_WORD 4
+
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+
+/* The number of predefined XCOFF types. */
+
+#define XCOFF_TYPE_COUNT 34
+
+/* This structure is used as a handle so that the stab parsing doesn't
+ need to use any static variables. */
+
+struct stab_handle
+{
+ /* The BFD. */
+ bfd *abfd;
+ /* True if this is stabs in sections. */
+ boolean sections;
+ /* The symbol table. */
+ asymbol **syms;
+ /* The number of symbols. */
+ long symcount;
+ /* The accumulated file name string. */
+ char *so_string;
+ /* The value of the last N_SO symbol. */
+ bfd_vma so_value;
+ /* The value of the start of the file, so that we can handle file
+ relative N_LBRAC and N_RBRAC symbols. */
+ bfd_vma file_start_offset;
+ /* The offset of the start of the function, so that we can handle
+ function relative N_LBRAC and N_RBRAC symbols. */
+ bfd_vma function_start_offset;
+ /* The version number of gcc which compiled the current compilation
+ unit, 0 if not compiled by gcc. */
+ int gcc_compiled;
+ /* Whether an N_OPT symbol was seen that was not generated by gcc,
+ so that we can detect the SunPRO compiler. */
+ boolean n_opt_found;
+ /* The main file name. */
+ char *main_filename;
+ /* A stack of unfinished N_BINCL files. */
+ struct bincl_file *bincl_stack;
+ /* A list of finished N_BINCL files. */
+ struct bincl_file *bincl_list;
+ /* Whether we are inside a function or not. */
+ boolean within_function;
+ /* The address of the end of the function, used if we have seen an
+ N_FUN symbol while in a function. This is -1 if we have not seen
+ an N_FUN (the normal case). */
+ bfd_vma function_end;
+ /* The depth of block nesting. */
+ int block_depth;
+ /* List of pending variable definitions. */
+ struct stab_pending_var *pending;
+ /* Number of files for which we have types. */
+ unsigned int files;
+ /* Lists of types per file. */
+ struct stab_types **file_types;
+ /* Predefined XCOFF types. */
+ debug_type xcoff_types[XCOFF_TYPE_COUNT];
+ /* Undefined tags. */
+ struct stab_tag *tags;
+};
+
+/* A list of these structures is used to hold pending variable
+ definitions seen before the N_LBRAC of a block. */
+
+struct stab_pending_var
+{
+ /* Next pending variable definition. */
+ struct stab_pending_var *next;
+ /* Name. */
+ const char *name;
+ /* Type. */
+ debug_type type;
+ /* Kind. */
+ enum debug_var_kind kind;
+ /* Value. */
+ bfd_vma val;
+};
+
+/* A list of these structures is used to hold the types for a single
+ file. */
+
+struct stab_types
+{
+ /* Next set of slots for this file. */
+ struct stab_types *next;
+ /* Types indexed by type number. */
+#define STAB_TYPES_SLOTS (16)
+ debug_type types[STAB_TYPES_SLOTS];
+};
+
+/* We keep a list of undefined tags that we encounter, so that we can
+ fill them in if the tag is later defined. */
+
+struct stab_tag
+{
+ /* Next undefined tag. */
+ struct stab_tag *next;
+ /* Tag name. */
+ const char *name;
+ /* Type kind. */
+ enum debug_type_kind kind;
+ /* Slot to hold real type when we discover it. If we don't, we fill
+ in an undefined tag type. */
+ debug_type slot;
+ /* Indirect type we have created to point at slot. */
+ debug_type type;
+};
+
+static char *savestring PARAMS ((const char *, int));
+static bfd_vma parse_number PARAMS ((const char **, boolean *));
+static void bad_stab PARAMS ((const char *));
+static void warn_stab PARAMS ((const char *, const char *));
+static boolean parse_stab_string
+ PARAMS ((PTR, struct stab_handle *, int, int, bfd_vma, const char *));
+static debug_type parse_stab_type
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **,
+ debug_type **));
+static boolean parse_stab_type_number
+ PARAMS ((const char **, int *));
+static debug_type parse_stab_range_type
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **,
+ const int *));
+static debug_type parse_stab_sun_builtin_type PARAMS ((PTR, const char **));
+static debug_type parse_stab_sun_floating_type
+ PARAMS ((PTR, const char **));
+static debug_type parse_stab_enum_type PARAMS ((PTR, const char **));
+static debug_type parse_stab_struct_type
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **, boolean,
+ const int *));
+static boolean parse_stab_baseclasses
+ PARAMS ((PTR, struct stab_handle *, const char **, debug_baseclass **));
+static boolean parse_stab_struct_fields
+ PARAMS ((PTR, struct stab_handle *, const char **, debug_field **,
+ boolean *));
+static boolean parse_stab_cpp_abbrev
+ PARAMS ((PTR, struct stab_handle *, const char **, debug_field *));
+static boolean parse_stab_one_struct_field
+ PARAMS ((PTR, struct stab_handle *, const char **, const char *,
+ debug_field *, boolean *));
+static boolean parse_stab_members
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **,
+ const int *, debug_method **));
+static debug_type parse_stab_argtypes
+ PARAMS ((PTR, struct stab_handle *, debug_type, const char *, const char *,
+ debug_type, const char *, boolean, boolean, const char **));
+static boolean parse_stab_tilde_field
+ PARAMS ((PTR, struct stab_handle *, const char **, const int *,
+ debug_type *, boolean *));
+static debug_type parse_stab_array_type
+ PARAMS ((PTR, struct stab_handle *, const char **, boolean));
+static void push_bincl PARAMS ((struct stab_handle *, const char *, bfd_vma));
+static const char *pop_bincl PARAMS ((struct stab_handle *));
+static boolean find_excl
+ PARAMS ((struct stab_handle *, const char *, bfd_vma));
+static boolean stab_record_variable
+ PARAMS ((PTR, struct stab_handle *, const char *, debug_type,
+ enum debug_var_kind, bfd_vma));
+static boolean stab_emit_pending_vars PARAMS ((PTR, struct stab_handle *));
+static debug_type *stab_find_slot
+ PARAMS ((struct stab_handle *, const int *));
+static debug_type stab_find_type
+ PARAMS ((PTR, struct stab_handle *, const int *));
+static boolean stab_record_type
+ PARAMS ((PTR, struct stab_handle *, const int *, debug_type));
+static debug_type stab_xcoff_builtin_type
+ PARAMS ((PTR, struct stab_handle *, int));
+static debug_type stab_find_tagged_type
+ PARAMS ((PTR, struct stab_handle *, const char *, int,
+ enum debug_type_kind));
+static debug_type *stab_demangle_argtypes
+ PARAMS ((PTR, struct stab_handle *, const char *, boolean *));
+
+/* Save a string in memory. */
+
+static char *
+savestring (start, len)
+ const char *start;
+ int len;
+{
+ char *ret;
+
+ ret = (char *) xmalloc (len + 1);
+ memcpy (ret, start, len);
+ ret[len] = '\0';
+ return ret;
+}
+
+/* Read a number from a string. */
+
+static bfd_vma
+parse_number (pp, poverflow)
+ const char **pp;
+ boolean *poverflow;
+{
+ unsigned long ul;
+ const char *orig;
+
+ if (poverflow != NULL)
+ *poverflow = false;
+
+ orig = *pp;
+
+ errno = 0;
+ ul = strtoul (*pp, (char **) pp, 0);
+ if (ul + 1 != 0 || errno == 0)
+ return (bfd_vma) ul;
+
+ /* Note that even though strtoul overflowed, it should have set *pp
+ to the end of the number, which is where we want it. */
+
+ if (sizeof (bfd_vma) > sizeof (unsigned long))
+ {
+ const char *p;
+ boolean neg;
+ int base;
+ bfd_vma over, lastdig;
+ boolean overflow;
+ bfd_vma v;
+
+ /* Our own version of strtoul, for a bfd_vma. */
+
+ p = orig;
+
+ neg = false;
+ if (*p == '+')
+ ++p;
+ else if (*p == '-')
+ {
+ neg = true;
+ ++p;
+ }
+
+ base = 10;
+ if (*p == '0')
+ {
+ if (p[1] == 'x' || p[1] == 'X')
+ {
+ base = 16;
+ p += 2;
+ }
+ else
+ {
+ base = 8;
+ ++p;
+ }
+ }
+
+ over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base;
+ lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base;
+
+ overflow = false;
+ v = 0;
+ while (1)
+ {
+ int d;
+
+ d = *p++;
+ if (isdigit ((unsigned char) d))
+ d -= '0';
+ else if (isupper ((unsigned char) d))
+ d -= 'A';
+ else if (islower ((unsigned char) d))
+ d -= 'a';
+ else
+ break;
+
+ if (d >= base)
+ break;
+
+ if (v > over || (v == over && (bfd_vma) d > lastdig))
+ {
+ overflow = true;
+ break;
+ }
+ }
+
+ if (! overflow)
+ {
+ if (neg)
+ v = - v;
+ return v;
+ }
+ }
+
+ /* If we get here, the number is too large to represent in a
+ bfd_vma. */
+
+ if (poverflow != NULL)
+ *poverflow = true;
+ else
+ warn_stab (orig, "numeric overflow");
+
+ return 0;
+}
+
+/* Give an error for a bad stab string. */
+
+static void
+bad_stab (p)
+ const char *p;
+{
+ fprintf (stderr, "Bad stab: %s\n", p);
+}
+
+/* Warn about something in a stab string. */
+
+static void
+warn_stab (p, err)
+ const char *p;
+ const char *err;
+{
+ fprintf (stderr, "Warning: %s: %s\n", err, p);
+}
+
+/* Create a handle to parse stabs symbols with. */
+
+/*ARGSUSED*/
+PTR
+start_stab (dhandle, abfd, sections, syms, symcount)
+ PTR dhandle;
+ bfd *abfd;
+ boolean sections;
+ asymbol **syms;
+ long symcount;
+{
+ struct stab_handle *ret;
+
+ ret = (struct stab_handle *) xmalloc (sizeof *ret);
+ memset (ret, 0, sizeof *ret);
+ ret->abfd = abfd;
+ ret->sections = sections;
+ ret->syms = syms;
+ ret->symcount = symcount;
+ ret->files = 1;
+ ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types);
+ ret->file_types[0] = NULL;
+ ret->function_end = (bfd_vma) -1;
+ return (PTR) ret;
+}
+
+/* When we have processed all the stabs information, we need to go
+ through and fill in all the undefined tags. */
+
+boolean
+finish_stab (dhandle, handle)
+ PTR dhandle;
+ PTR handle;
+{
+ struct stab_handle *info = (struct stab_handle *) handle;
+ struct stab_tag *st;
+
+ if (info->within_function)
+ {
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, info->function_end))
+ return false;
+ info->within_function = false;
+ info->function_end = (bfd_vma) -1;
+ }
+
+ for (st = info->tags; st != NULL; st = st->next)
+ {
+ enum debug_type_kind kind;
+
+ kind = st->kind;
+ if (kind == DEBUG_KIND_ILLEGAL)
+ kind = DEBUG_KIND_STRUCT;
+ st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind);
+ if (st->slot == DEBUG_TYPE_NULL)
+ return false;
+ }
+
+ return true;
+}
+
+/* Handle a single stabs symbol. */
+
+boolean
+parse_stab (dhandle, handle, type, desc, value, string)
+ PTR dhandle;
+ PTR handle;
+ int type;
+ int desc;
+ bfd_vma value;
+ const char *string;
+{
+ struct stab_handle *info = (struct stab_handle *) handle;
+
+ /* gcc will emit two N_SO strings per compilation unit, one for the
+ directory name and one for the file name. We just collect N_SO
+ strings as we see them, and start the new compilation unit when
+ we see a non N_SO symbol. */
+ if (info->so_string != NULL
+ && (type != N_SO || *string == '\0' || value != info->so_value))
+ {
+ if (! debug_set_filename (dhandle, info->so_string))
+ return false;
+ info->main_filename = info->so_string;
+
+ info->gcc_compiled = 0;
+ info->n_opt_found = false;
+
+ /* Generally, for stabs in the symbol table, the N_LBRAC and
+ N_RBRAC symbols are relative to the N_SO symbol value. */
+ if (! info->sections)
+ info->file_start_offset = info->so_value;
+
+ /* We need to reset the mapping from type numbers to types. We
+ can't free the old mapping, because of the use of
+ debug_make_indirect_type. */
+ info->files = 1;
+ info->file_types = ((struct stab_types **)
+ xmalloc (sizeof *info->file_types));
+ info->file_types[0] = NULL;
+
+ info->so_string = NULL;
+
+ /* Now process whatever type we just got. */
+ }
+
+ switch (type)
+ {
+ case N_FN:
+ case N_FN_SEQ:
+ break;
+
+ case N_LBRAC:
+ /* Ignore extra outermost context from SunPRO cc and acc. */
+ if (info->n_opt_found && desc == 1)
+ break;
+
+ if (! info->within_function)
+ {
+ fprintf (stderr, "N_LBRAC not within function\n");
+ return false;
+ }
+
+ /* Start an inner lexical block. */
+ if (! debug_start_block (dhandle,
+ (value
+ + info->file_start_offset
+ + info->function_start_offset)))
+ return false;
+
+ /* Emit any pending variable definitions. */
+ if (! stab_emit_pending_vars (dhandle, info))
+ return false;
+
+ ++info->block_depth;
+ break;
+
+ case N_RBRAC:
+ /* Ignore extra outermost context from SunPRO cc and acc. */
+ if (info->n_opt_found && desc == 1)
+ break;
+
+ /* We shouldn't have any pending variable definitions here, but,
+ if we do, we probably need to emit them before closing the
+ block. */
+ if (! stab_emit_pending_vars (dhandle, info))
+ return false;
+
+ /* End an inner lexical block. */
+ if (! debug_end_block (dhandle,
+ (value
+ + info->file_start_offset
+ + info->function_start_offset)))
+ return false;
+
+ --info->block_depth;
+ if (info->block_depth < 0)
+ {
+ fprintf (stderr, "Too many N_RBRACs\n");
+ return false;
+ }
+ break;
+
+ case N_SO:
+ /* This always ends a function. */
+ if (info->within_function)
+ {
+ bfd_vma endval;
+
+ endval = value;
+ if (*string != '\0'
+ && info->function_end != (bfd_vma) -1
+ && info->function_end < endval)
+ endval = info->function_end;
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, endval))
+ return false;
+ info->within_function = false;
+ info->function_end = (bfd_vma) -1;
+ }
+
+ /* An empty string is emitted by gcc at the end of a compilation
+ unit. */
+ if (*string == '\0')
+ return true;
+
+ /* Just accumulate strings until we see a non N_SO symbol. If
+ the string starts with '/', we discard the previously
+ accumulated strings. */
+ if (info->so_string == NULL)
+ info->so_string = xstrdup (string);
+ else
+ {
+ char *f;
+
+ f = info->so_string;
+ if (*string == '/')
+ info->so_string = xstrdup (string);
+ else
+ info->so_string = concat (info->so_string, string,
+ (const char *) NULL);
+ free (f);
+ }
+
+ info->so_value = value;
+
+ break;
+
+ case N_SOL:
+ /* Start an include file. */
+ if (! debug_start_source (dhandle, string))
+ return false;
+ break;
+
+ case N_BINCL:
+ /* Start an include file which may be replaced. */
+ push_bincl (info, string, value);
+ if (! debug_start_source (dhandle, string))
+ return false;
+ break;
+
+ case N_EINCL:
+ /* End an N_BINCL include. */
+ if (! debug_start_source (dhandle, pop_bincl (info)))
+ return false;
+ break;
+
+ case N_EXCL:
+ /* This is a duplicate of a header file named by N_BINCL which
+ was eliminated by the linker. */
+ if (! find_excl (info, string, value))
+ return false;
+ break;
+
+ case N_SLINE:
+ if (! debug_record_line (dhandle, desc,
+ value + info->function_start_offset))
+ return false;
+ break;
+
+ case N_BCOMM:
+ if (! debug_start_common_block (dhandle, string))
+ return false;
+ break;
+
+ case N_ECOMM:
+ if (! debug_end_common_block (dhandle, string))
+ return false;
+ break;
+
+ case N_FUN:
+ if (*string == '\0')
+ {
+ if (info->within_function)
+ {
+ /* This always marks the end of a function; we don't
+ need to worry about info->function_end. */
+ if (info->sections)
+ value += info->function_start_offset;
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, value))
+ return false;
+ info->within_function = false;
+ info->function_end = (bfd_vma) -1;
+ }
+ break;
+ }
+
+ /* A const static symbol in the .text section will have an N_FUN
+ entry. We need to use these to mark the end of the function,
+ in case we are looking at gcc output before it was changed to
+ always emit an empty N_FUN. We can't call debug_end_function
+ here, because it might be a local static symbol. */
+ if (info->within_function
+ && (info->function_end == (bfd_vma) -1
+ || value < info->function_end))
+ info->function_end = value;
+
+ /* Fall through. */
+ /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM
+ symbols, and if it does not start with :S, gdb relocates the
+ value to the start of the section. gcc always seems to use
+ :S, so we don't worry about this. */
+ /* Fall through. */
+ default:
+ {
+ const char *colon;
+
+ colon = strchr (string, ':');
+ if (colon != NULL
+ && (colon[1] == 'f' || colon[1] == 'F'))
+ {
+ if (info->within_function)
+ {
+ bfd_vma endval;
+
+ endval = value;
+ if (info->function_end != (bfd_vma) -1
+ && info->function_end < endval)
+ endval = info->function_end;
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, endval))
+ return false;
+ info->function_end = (bfd_vma) -1;
+ }
+ /* For stabs in sections, line numbers and block addresses
+ are offsets from the start of the function. */
+ if (info->sections)
+ info->function_start_offset = value;
+ info->within_function = true;
+ }
+
+ if (! parse_stab_string (dhandle, info, type, desc, value, string))
+ return false;
+ }
+ break;
+
+ case N_OPT:
+ if (string != NULL && strcmp (string, "gcc2_compiled.") == 0)
+ info->gcc_compiled = 2;
+ else if (string != NULL && strcmp (string, "gcc_compiled.") == 0)
+ info->gcc_compiled = 1;
+ else
+ info->n_opt_found = true;
+ break;
+
+ case N_OBJ:
+ case N_ENDM:
+ case N_MAIN:
+ break;
+ }
+
+ return true;
+}
+
+/* Parse the stabs string. */
+
+static boolean
+parse_stab_string (dhandle, info, stabtype, desc, value, string)
+ PTR dhandle;
+ struct stab_handle *info;
+ int stabtype;
+ int desc;
+ bfd_vma value;
+ const char *string;
+{
+ const char *p;
+ char *name;
+ int type;
+ debug_type dtype;
+ boolean synonym;
+ unsigned int lineno;
+ debug_type *slot;
+
+ p = strchr (string, ':');
+ if (p == NULL)
+ return true;
+
+ while (p[1] == ':')
+ {
+ p += 2;
+ p = strchr (p, ':');
+ if (p == NULL)
+ {
+ bad_stab (string);
+ return false;
+ }
+ }
+
+ /* GCC 2.x puts the line number in desc. SunOS apparently puts in
+ the number of bytes occupied by a type or object, which we
+ ignore. */
+ if (info->gcc_compiled >= 2)
+ lineno = desc;
+ else
+ lineno = 0;
+
+ /* FIXME: Sometimes the special C++ names start with '.'. */
+ name = NULL;
+ if (string[0] == '$')
+ {
+ switch (string[1])
+ {
+ case 't':
+ name = "this";
+ break;
+ case 'v':
+ /* Was: name = "vptr"; */
+ break;
+ case 'e':
+ name = "eh_throw";
+ break;
+ case '_':
+ /* This was an anonymous type that was never fixed up. */
+ break;
+ case 'X':
+ /* SunPRO (3.0 at least) static variable encoding. */
+ break;
+ default:
+ warn_stab (string, "unknown C++ encoded name");
+ break;
+ }
+ }
+
+ if (name == NULL)
+ {
+ if (p == string || (string[0] == ' ' && p == string + 1))
+ name = NULL;
+ else
+ name = savestring (string, p - string);
+ }
+
+ ++p;
+ if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
+ type = 'l';
+ else
+ type = *p++;
+
+ switch (type)
+ {
+ case 'c':
+ /* c is a special case, not followed by a type-number.
+ SYMBOL:c=iVALUE for an integer constant symbol.
+ SYMBOL:c=rVALUE for a floating constant symbol.
+ SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
+ e.g. "b:c=e6,0" for "const b = blob1"
+ (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
+ if (*p != '=')
+ {
+ bad_stab (string);
+ return false;
+ }
+ ++p;
+ switch (*p++)
+ {
+ case 'r':
+ /* Floating point constant. */
+ if (! debug_record_float_const (dhandle, name, atof (p)))
+ return false;
+ break;
+ case 'i':
+ /* Integer constant. */
+ /* Defining integer constants this way is kind of silly,
+ since 'e' constants allows the compiler to give not only
+ the value, but the type as well. C has at least int,
+ long, unsigned int, and long long as constant types;
+ other languages probably should have at least unsigned as
+ well as signed constants. */
+ if (! debug_record_int_const (dhandle, name, atoi (p)))
+ return false;
+ break;
+ case 'e':
+ /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
+ can be represented as integral.
+ e.g. "b:c=e6,0" for "const b = blob1"
+ (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL,
+ &p, (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (*p != ',')
+ {
+ bad_stab (string);
+ return false;
+ }
+ if (! debug_record_typed_const (dhandle, name, dtype, atoi (p)))
+ return false;
+ break;
+ default:
+ bad_stab (string);
+ return false;
+ }
+
+ break;
+
+ case 'C':
+ /* The name of a caught exception. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL,
+ &p, (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_label (dhandle, name, dtype, value))
+ return false;
+ break;
+
+ case 'f':
+ case 'F':
+ /* A function definition. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_function (dhandle, name, dtype, type == 'F', value))
+ return false;
+
+ /* Sun acc puts declared types of arguments here. We don't care
+ about their actual types (FIXME -- we should remember the whole
+ function prototype), but the list may define some new types
+ that we have to remember, so we must scan it now. */
+ while (*p == ';')
+ {
+ ++p;
+ if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL)
+ == DEBUG_TYPE_NULL)
+ return false;
+ }
+
+ break;
+
+ case 'G':
+ {
+ char leading;
+ long c;
+ asymbol **ps;
+
+ /* A global symbol. The value must be extracted from the
+ symbol table. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ leading = bfd_get_symbol_leading_char (info->abfd);
+ for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+ {
+ const char *n;
+
+ n = bfd_asymbol_name (*ps);
+ if (leading != '\0' && *n == leading)
+ ++n;
+ if (*n == *name && strcmp (n, name) == 0)
+ break;
+ }
+ if (c > 0)
+ value = bfd_asymbol_value (*ps);
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
+ value))
+ return false;
+ }
+ break;
+
+ /* This case is faked by a conditional above, when there is no
+ code letter in the dbx data. Dbx data never actually
+ contains 'l'. */
+ case 'l':
+ case 's':
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
+ value))
+ return false;
+ break;
+
+ case 'p':
+ /* A function parameter. */
+ if (*p != 'F')
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ else
+ {
+ /* pF is a two-letter code that means a function parameter in
+ Fortran. The type-number specifies the type of the return
+ value. Translate it into a pointer-to-function type. */
+ ++p;
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype != DEBUG_TYPE_NULL)
+ {
+ debug_type ftype;
+
+ ftype = debug_make_function_type (dhandle, dtype,
+ (debug_type *) NULL, false);
+ dtype = debug_make_pointer_type (dhandle, ftype);
+ }
+ }
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK,
+ value))
+ return false;
+
+ /* FIXME: At this point gdb considers rearranging the parameter
+ address on a big endian machine if it is smaller than an int.
+ We have no way to do that, since we don't really know much
+ about the target. */
+
+ break;
+
+ case 'P':
+ if (stabtype == N_FUN)
+ {
+ /* Prototype of a function referenced by this file. */
+ while (*p == ';')
+ {
+ ++p;
+ if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL)
+ == DEBUG_TYPE_NULL)
+ return false;
+ }
+ break;
+ }
+ /* Fall through. */
+ case 'R':
+ /* Parameter which is in a register. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG,
+ value))
+ return false;
+ break;
+
+ case 'r':
+ /* Register variable (either global or local). */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER,
+ value))
+ return false;
+
+ /* FIXME: At this point gdb checks to combine pairs of 'p' and
+ 'r' stabs into a single 'P' stab. */
+
+ break;
+
+ case 'S':
+ /* Static symbol at top level of file */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC,
+ value))
+ return false;
+ break;
+
+ case 't':
+ /* A typedef. */
+ dtype = parse_stab_type (dhandle, info, name, &p, &slot);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (name == NULL)
+ {
+ /* A nameless type. Nothing to do. */
+ return true;
+ }
+
+ dtype = debug_name_type (dhandle, name, dtype);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+
+ if (slot != NULL)
+ *slot = dtype;
+
+ break;
+
+ case 'T':
+ /* Struct, union, or enum tag. For GNU C++, this can be be followed
+ by 't' which means we are typedef'ing it as well. */
+ if (*p != 't')
+ {
+ synonym = false;
+ /* FIXME: gdb sets synonym to true if the current language
+ is C++. */
+ }
+ else
+ {
+ synonym = true;
+ ++p;
+ }
+
+ dtype = parse_stab_type (dhandle, info, name, &p, &slot);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (name == NULL)
+ return true;
+
+ dtype = debug_tag_type (dhandle, name, dtype);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (slot != NULL)
+ *slot = dtype;
+
+ /* See if we have a cross reference to this tag which we can now
+ fill in. */
+ {
+ register struct stab_tag **pst;
+
+ for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next)
+ {
+ if ((*pst)->name[0] == name[0]
+ && strcmp ((*pst)->name, name) == 0)
+ {
+ (*pst)->slot = dtype;
+ *pst = (*pst)->next;
+ break;
+ }
+ }
+ }
+
+ if (synonym)
+ {
+ dtype = debug_name_type (dhandle, name, dtype);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+
+ if (slot != NULL)
+ *slot = dtype;
+ }
+
+ break;
+
+ case 'V':
+ /* Static symbol of local scope */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ /* FIXME: gdb checks os9k_stabs here. */
+ if (! stab_record_variable (dhandle, info, name, dtype,
+ DEBUG_LOCAL_STATIC, value))
+ return false;
+ break;
+
+ case 'v':
+ /* Reference parameter. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE,
+ value))
+ return false;
+ break;
+
+ case 'a':
+ /* Reference parameter which is in a register. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG,
+ value))
+ return false;
+ break;
+
+ case 'X':
+ /* This is used by Sun FORTRAN for "function result value".
+ Sun claims ("dbx and dbxtool interfaces", 2nd ed)
+ that Pascal uses it too, but when I tried it Pascal used
+ "x:3" (local symbol) instead. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
+ value))
+ return false;
+ break;
+
+ default:
+ bad_stab (string);
+ return false;
+ }
+
+ /* FIXME: gdb converts structure values to structure pointers in a
+ couple of cases, depending upon the target. */
+
+ return true;
+}
+
+/* Parse a stabs type. The typename argument is non-NULL if this is a
+ typedef or a tag definition. The pp argument points to the stab
+ string, and is updated. The slotp argument points to a place to
+ store the slot used if the type is being defined. */
+
+static debug_type
+parse_stab_type (dhandle, info, typename, pp, slotp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *typename;
+ const char **pp;
+ debug_type **slotp;
+{
+ const char *orig;
+ int typenums[2];
+ int size;
+ boolean stringp;
+ int descriptor;
+ debug_type dtype;
+
+ if (slotp != NULL)
+ *slotp = NULL;
+
+ orig = *pp;
+
+ size = -1;
+ stringp = false;
+
+ /* Read type number if present. The type number may be omitted.
+ for instance in a two-dimensional array declared with type
+ "ar1;1;10;ar1;1;10;4". */
+ if (! isdigit ((unsigned char) **pp) && **pp != '(' && **pp != '-')
+ {
+ /* 'typenums=' not present, type is anonymous. Read and return
+ the definition, but don't put it in the type vector. */
+ typenums[0] = typenums[1] = -1;
+ }
+ else
+ {
+ if (! parse_stab_type_number (pp, typenums))
+ return DEBUG_TYPE_NULL;
+
+ if (**pp != '=')
+ {
+ /* Type is not being defined here. Either it already
+ exists, or this is a forward reference to it. */
+ return stab_find_type (dhandle, info, typenums);
+ }
+
+ /* Only set the slot if the type is being defined. This means
+ that the mapping from type numbers to types will only record
+ the name of the typedef which defines a type. If we don't do
+ this, then something like
+ typedef int foo;
+ int i;
+ will record that i is of type foo. Unfortunately, stabs
+ information is ambiguous about variable types. For this code,
+ typedef int foo;
+ int i;
+ foo j;
+ the stabs information records both i and j as having the same
+ type. This could be fixed by patching the compiler. */
+ if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0)
+ *slotp = stab_find_slot (info, typenums);
+
+ /* Type is being defined here. */
+ /* Skip the '='. */
+ ++*pp;
+
+ while (**pp == '@')
+ {
+ const char *p = *pp + 1;
+ const char *attr;
+
+ if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
+ {
+ /* Member type. */
+ break;
+ }
+
+ /* Type attributes. */
+ attr = p;
+
+ for (; *p != ';'; ++p)
+ {
+ if (*p == '\0')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ }
+ *pp = p + 1;
+
+ switch (*attr)
+ {
+ case 's':
+ size = atoi (attr + 1);
+ if (size <= 0)
+ size = -1;
+ break;
+
+ case 'S':
+ stringp = true;
+ break;
+
+ default:
+ /* Ignore unrecognized type attributes, so future
+ compilers can invent new ones. */
+ break;
+ }
+ }
+ }
+
+ descriptor = **pp;
+ ++*pp;
+
+ switch (descriptor)
+ {
+ case 'x':
+ {
+ enum debug_type_kind code;
+ const char *q1, *q2, *p;
+
+ /* A cross reference to another type. */
+
+ switch (**pp)
+ {
+ case 's':
+ code = DEBUG_KIND_STRUCT;
+ break;
+ case 'u':
+ code = DEBUG_KIND_UNION;
+ break;
+ case 'e':
+ code = DEBUG_KIND_ENUM;
+ break;
+ default:
+ /* Complain and keep going, so compilers can invent new
+ cross-reference types. */
+ warn_stab (orig, "unrecognized cross reference type");
+ code = DEBUG_KIND_STRUCT;
+ break;
+ }
+ ++*pp;
+
+ q1 = strchr (*pp, '<');
+ p = strchr (*pp, ':');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ while (q1 != NULL && p > q1 && p[1] == ':')
+ {
+ q2 = strchr (q1, '>');
+ if (q2 == NULL || q2 < p)
+ break;
+ p += 2;
+ p = strchr (p, ':');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ }
+
+ dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code);
+
+ *pp = p + 1;
+ }
+ break;
+
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '(':
+ {
+ const char *hold;
+ int xtypenums[2];
+
+ /* This type is defined as another type. */
+
+ (*pp)--;
+ hold = *pp;
+
+ /* Peek ahead at the number to detect void. */
+ if (! parse_stab_type_number (pp, xtypenums))
+ return DEBUG_TYPE_NULL;
+
+ if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
+ {
+ /* This type is being defined as itself, which means that
+ it is void. */
+ dtype = debug_make_void_type (dhandle);
+ }
+ else
+ {
+ *pp = hold;
+
+ /* Go back to the number and have parse_stab_type get it.
+ This means that we can deal with something like
+ t(1,2)=(3,4)=... which the Lucid compiler uses. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (typenums[0] != -1)
+ {
+ if (! stab_record_type (dhandle, info, typenums, dtype))
+ return DEBUG_TYPE_NULL;
+ }
+
+ break;
+ }
+
+ case '*':
+ dtype = debug_make_pointer_type (dhandle,
+ parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL));
+ break;
+
+ case '&':
+ /* Reference to another type. */
+ dtype = (debug_make_reference_type
+ (dhandle,
+ parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL)));
+ break;
+
+ case 'f':
+ /* Function returning another type. */
+ /* FIXME: gdb checks os9k_stabs here. */
+ dtype = (debug_make_function_type
+ (dhandle,
+ parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL),
+ (debug_type *) NULL, false));
+ break;
+
+ case 'k':
+ /* Const qualifier on some type (Sun). */
+ /* FIXME: gdb accepts 'c' here if os9k_stabs. */
+ dtype = debug_make_const_type (dhandle,
+ parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL));
+ break;
+
+ case 'B':
+ /* Volatile qual on some type (Sun). */
+ /* FIXME: gdb accepts 'i' here if os9k_stabs. */
+ dtype = (debug_make_volatile_type
+ (dhandle,
+ parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL)));
+ break;
+
+ case '@':
+ /* Offset (class & variable) type. This is used for a pointer
+ relative to an object. */
+ {
+ debug_type domain;
+ debug_type memtype;
+
+ /* Member type. */
+
+ domain = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (domain == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (memtype == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ dtype = debug_make_offset_type (dhandle, domain, memtype);
+ }
+ break;
+
+ case '#':
+ /* Method (class & fn) type. */
+ if (**pp == '#')
+ {
+ debug_type return_type;
+
+ ++*pp;
+ return_type = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (return_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+ dtype = debug_make_method_type (dhandle, return_type,
+ DEBUG_TYPE_NULL,
+ (debug_type *) NULL, false);
+ }
+ else
+ {
+ debug_type domain;
+ debug_type return_type;
+ debug_type *args;
+ unsigned int n;
+ unsigned int alloc;
+ boolean varargs;
+
+ domain = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (domain == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ return_type = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (return_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ alloc = 10;
+ args = (debug_type *) xmalloc (alloc * sizeof *args);
+ n = 0;
+ while (**pp != ';')
+ {
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (n + 1 >= alloc)
+ {
+ alloc += 10;
+ args = ((debug_type *)
+ xrealloc ((PTR) args, alloc * sizeof *args));
+ }
+
+ args[n] = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (args[n] == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ ++n;
+ }
+ ++*pp;
+
+ /* If the last type is not void, then this function takes a
+ variable number of arguments. Otherwise, we must strip
+ the void type. */
+ if (n == 0
+ || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
+ varargs = true;
+ else
+ {
+ --n;
+ varargs = false;
+ }
+
+ args[n] = DEBUG_TYPE_NULL;
+
+ dtype = debug_make_method_type (dhandle, return_type, domain, args,
+ varargs);
+ }
+ break;
+
+ case 'r':
+ /* Range type. */
+ dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);
+ break;
+
+ case 'b':
+ /* FIXME: gdb checks os9k_stabs here. */
+ /* Sun ACC builtin int type. */
+ dtype = parse_stab_sun_builtin_type (dhandle, pp);
+ break;
+
+ case 'R':
+ /* Sun ACC builtin float type. */
+ dtype = parse_stab_sun_floating_type (dhandle, pp);
+ break;
+
+ case 'e':
+ /* Enumeration type. */
+ dtype = parse_stab_enum_type (dhandle, pp);
+ break;
+
+ case 's':
+ case 'u':
+ /* Struct or union type. */
+ dtype = parse_stab_struct_type (dhandle, info, typename, pp,
+ descriptor == 's', typenums);
+ break;
+
+ case 'a':
+ /* Array type. */
+ if (**pp != 'r')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ dtype = parse_stab_array_type (dhandle, info, pp, stringp);
+ break;
+
+ case 'S':
+ dtype = debug_make_set_type (dhandle,
+ parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL),
+ stringp);
+ break;
+
+ default:
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (dtype == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (typenums[0] != -1)
+ {
+ if (! stab_record_type (dhandle, info, typenums, dtype))
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (size != -1)
+ {
+ if (! debug_record_type_size (dhandle, dtype, (unsigned int) size))
+ return DEBUG_TYPE_NULL;
+ }
+
+ return dtype;
+}
+
+/* Read a number by which a type is referred to in dbx data, or
+ perhaps read a pair (FILENUM, TYPENUM) in parentheses. Just a
+ single number N is equivalent to (0,N). Return the two numbers by
+ storing them in the vector TYPENUMS. */
+
+static boolean
+parse_stab_type_number (pp, typenums)
+ const char **pp;
+ int *typenums;
+{
+ const char *orig;
+
+ orig = *pp;
+
+ if (**pp != '(')
+ {
+ typenums[0] = 0;
+ typenums[1] = (int) parse_number (pp, (boolean *) NULL);
+ }
+ else
+ {
+ ++*pp;
+ typenums[0] = (int) parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ typenums[1] = (int) parse_number (pp, (boolean *) NULL);
+ if (**pp != ')')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ }
+
+ return true;
+}
+
+/* Parse a range type. */
+
+static debug_type
+parse_stab_range_type (dhandle, info, typename, pp, typenums)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *typename;
+ const char **pp;
+ const int *typenums;
+{
+ const char *orig;
+ int rangenums[2];
+ boolean self_subrange;
+ debug_type index_type;
+ const char *s2, *s3;
+ bfd_signed_vma n2, n3;
+ boolean ov2, ov3;
+
+ orig = *pp;
+
+ index_type = DEBUG_TYPE_NULL;
+
+ /* First comes a type we are a subrange of.
+ In C it is usually 0, 1 or the type being defined. */
+ if (! parse_stab_type_number (pp, rangenums))
+ return DEBUG_TYPE_NULL;
+
+ self_subrange = (rangenums[0] == typenums[0]
+ && rangenums[1] == typenums[1]);
+
+ if (**pp == '=')
+ {
+ *pp = orig;
+ index_type = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (index_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (**pp == ';')
+ ++*pp;
+
+ /* The remaining two operands are usually lower and upper bounds of
+ the range. But in some special cases they mean something else. */
+ s2 = *pp;
+ n2 = parse_number (pp, &ov2);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ s3 = *pp;
+ n3 = parse_number (pp, &ov3);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (ov2 || ov3)
+ {
+ /* gcc will emit range stabs for long long types. Handle this
+ as a special case. FIXME: This needs to be more general. */
+#define LLLOW "01000000000000000000000;"
+#define LLHIGH "0777777777777777777777;"
+#define ULLHIGH "01777777777777777777777;"
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0
+ && strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0)
+ return debug_make_int_type (dhandle, 8, false);
+ if (! ov2
+ && n2 == 0
+ && strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0)
+ return debug_make_int_type (dhandle, 8, true);
+ }
+
+ warn_stab (orig, "numeric overflow");
+ }
+
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ /* A type defined as a subrange of itself, with both bounds 0,
+ is void. */
+ if (self_subrange && n2 == 0 && n3 == 0)
+ return debug_make_void_type (dhandle);
+
+ /* A type defined as a subrange of itself, with n2 positive and
+ n3 zero, is a complex type, and n2 is the number of bytes. */
+ if (self_subrange && n3 == 0 && n2 > 0)
+ return debug_make_complex_type (dhandle, n2);
+
+ /* If n3 is zero and n2 is positive, this is a floating point
+ type, and n2 is the number of bytes. */
+ if (n3 == 0 && n2 > 0)
+ return debug_make_float_type (dhandle, n2);
+
+ /* If the upper bound is -1, this is an unsigned int. */
+ if (n2 == 0 && n3 == -1)
+ {
+ /* When gcc is used with -gstabs, but not -gstabs+, it will emit
+ long long int:t6=r1;0;-1;
+ long long unsigned int:t7=r1;0;-1;
+ We hack here to handle this reasonably. */
+ if (typename != NULL)
+ {
+ if (strcmp (typename, "long long int") == 0)
+ return debug_make_int_type (dhandle, 8, false);
+ else if (strcmp (typename, "long long unsigned int") == 0)
+ return debug_make_int_type (dhandle, 8, true);
+ }
+ /* FIXME: The size here really depends upon the target. */
+ return debug_make_int_type (dhandle, 4, true);
+ }
+
+ /* A range of 0 to 127 is char. */
+ if (self_subrange && n2 == 0 && n3 == 127)
+ return debug_make_int_type (dhandle, 1, false);
+
+ /* FIXME: gdb checks for the language CHILL here. */
+
+ if (n2 == 0)
+ {
+ if (n3 < 0)
+ return debug_make_int_type (dhandle, - n3, true);
+ else if (n3 == 0xff)
+ return debug_make_int_type (dhandle, 1, true);
+ else if (n3 == 0xffff)
+ return debug_make_int_type (dhandle, 2, true);
+ /* -1 is used for the upper bound of (4 byte) "unsigned int"
+ and "unsigned long", and we already checked for that, so
+ don't need to test for it here. */
+ }
+ else if (n3 == 0
+ && n2 < 0
+ && (self_subrange || n2 == -8))
+ return debug_make_int_type (dhandle, - n2, true);
+ else if (n2 == - n3 - 1)
+ {
+ if (n3 == 0x7f)
+ return debug_make_int_type (dhandle, 1, false);
+ else if (n3 == 0x7fff)
+ return debug_make_int_type (dhandle, 2, false);
+ else if (n3 == 0x7fffffff)
+ return debug_make_int_type (dhandle, 4, false);
+ }
+ }
+
+ /* At this point I don't have the faintest idea how to deal with a
+ self_subrange type; I'm going to assume that this is used as an
+ idiom, and that all of them are special cases. So . . . */
+ if (self_subrange)
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ index_type = stab_find_type (dhandle, info, rangenums);
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ /* Does this actually ever happen? Is that why we are worrying
+ about dealing with it rather than just calling error_type? */
+ warn_stab (orig, "missing index type");
+ index_type = debug_make_int_type (dhandle, 4, false);
+ }
+
+ return debug_make_range_type (dhandle, index_type, n2, n3);
+}
+
+/* Sun's ACC uses a somewhat saner method for specifying the builtin
+ typedefs in every file (for int, long, etc):
+
+ type = b <signed> <width>; <offset>; <nbits>
+ signed = u or s. Possible c in addition to u or s (for char?).
+ offset = offset from high order bit to start bit of type.
+ width is # bytes in object of this type, nbits is # bits in type.
+
+ The width/offset stuff appears to be for small objects stored in
+ larger ones (e.g. `shorts' in `int' registers). We ignore it for now,
+ FIXME. */
+
+static debug_type
+parse_stab_sun_builtin_type (dhandle, pp)
+ PTR dhandle;
+ const char **pp;
+{
+ const char *orig;
+ boolean unsignedp;
+ bfd_vma bits;
+
+ orig = *pp;
+
+ switch (**pp)
+ {
+ case 's':
+ unsignedp = false;
+ break;
+ case 'u':
+ unsignedp = true;
+ break;
+ default:
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ /* For some odd reason, all forms of char put a c here. This is strange
+ because no other type has this honor. We can safely ignore this because
+ we actually determine 'char'acterness by the number of bits specified in
+ the descriptor. */
+ if (**pp == 'c')
+ ++*pp;
+
+ /* The first number appears to be the number of bytes occupied
+ by this type, except that unsigned short is 4 instead of 2.
+ Since this information is redundant with the third number,
+ we will ignore it. */
+ (void) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ /* The second number is always 0, so ignore it too. */
+ (void) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ /* The third number is the number of bits for this type. */
+ bits = parse_number (pp, (boolean *) NULL);
+
+ /* The type *should* end with a semicolon. If it are embedded
+ in a larger type the semicolon may be the only way to know where
+ the type ends. If this type is at the end of the stabstring we
+ can deal with the omitted semicolon (but we don't have to like
+ it). Don't bother to complain(), Sun's compiler omits the semicolon
+ for "void". */
+ if (**pp == ';')
+ ++*pp;
+
+ if (bits == 0)
+ return debug_make_void_type (dhandle);
+
+ return debug_make_int_type (dhandle, bits / 8, unsignedp);
+}
+
+/* Parse a builtin floating type generated by the Sun compiler. */
+
+static debug_type
+parse_stab_sun_floating_type (dhandle, pp)
+ PTR dhandle;
+ const char **pp;
+{
+ const char *orig;
+ bfd_vma details;
+ bfd_vma bytes;
+
+ orig = *pp;
+
+ /* The first number has more details about the type, for example
+ FN_COMPLEX. */
+ details = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ /* The second number is the number of bytes occupied by this type */
+ bytes = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (details == NF_COMPLEX
+ || details == NF_COMPLEX16
+ || details == NF_COMPLEX32)
+ return debug_make_complex_type (dhandle, bytes);
+
+ return debug_make_float_type (dhandle, bytes);
+}
+
+/* Handle an enum type. */
+
+static debug_type
+parse_stab_enum_type (dhandle, pp)
+ PTR dhandle;
+ const char **pp;
+{
+ const char *orig;
+ const char **names;
+ bfd_signed_vma *values;
+ unsigned int n;
+ unsigned int alloc;
+
+ orig = *pp;
+
+ /* FIXME: gdb checks os9k_stabs here. */
+
+ /* The aix4 compiler emits an extra field before the enum members;
+ my guess is it's a type of some sort. Just ignore it. */
+ if (**pp == '-')
+ {
+ while (**pp != ':')
+ ++*pp;
+ ++*pp;
+ }
+
+ /* Read the value-names and their values.
+ The input syntax is NAME:VALUE,NAME:VALUE, and so on.
+ A semicolon or comma instead of a NAME means the end. */
+ alloc = 10;
+ names = (const char **) xmalloc (alloc * sizeof *names);
+ values = (bfd_signed_vma *) xmalloc (alloc * sizeof *values);
+ n = 0;
+ while (**pp != '\0' && **pp != ';' && **pp != ',')
+ {
+ const char *p;
+ char *name;
+ bfd_signed_vma val;
+
+ p = *pp;
+ while (*p != ':')
+ ++p;
+
+ name = savestring (*pp, p - *pp);
+
+ *pp = p + 1;
+ val = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (n + 1 >= alloc)
+ {
+ alloc += 10;
+ names = ((const char **)
+ xrealloc ((PTR) names, alloc * sizeof *names));
+ values = ((bfd_signed_vma *)
+ xrealloc ((PTR) values, alloc * sizeof *values));
+ }
+
+ names[n] = name;
+ values[n] = val;
+ ++n;
+ }
+
+ names[n] = NULL;
+ values[n] = 0;
+
+ if (**pp == ';')
+ ++*pp;
+
+ return debug_make_enum_type (dhandle, names, values);
+}
+
+/* Read the description of a structure (or union type) and return an object
+ describing the type.
+
+ PP points to a character pointer that points to the next unconsumed token
+ in the the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;",
+ *PP will point to "4a:1,0,32;;". */
+
+static debug_type
+parse_stab_struct_type (dhandle, info, tagname, pp, structp, typenums)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *tagname;
+ const char **pp;
+ boolean structp;
+ const int *typenums;
+{
+ const char *orig;
+ bfd_vma size;
+ debug_baseclass *baseclasses;
+ debug_field *fields;
+ boolean statics;
+ debug_method *methods;
+ debug_type vptrbase;
+ boolean ownvptr;
+
+ orig = *pp;
+
+ /* Get the size. */
+ size = parse_number (pp, (boolean *) NULL);
+
+ /* Get the other information. */
+ if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses)
+ || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics)
+ || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods)
+ || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase,
+ &ownvptr))
+ return DEBUG_TYPE_NULL;
+
+ if (! statics
+ && baseclasses == NULL
+ && methods == NULL
+ && vptrbase == DEBUG_TYPE_NULL
+ && ! ownvptr)
+ return debug_make_struct_type (dhandle, structp, size, fields);
+
+ return debug_make_object_type (dhandle, structp, size, fields, baseclasses,
+ methods, vptrbase, ownvptr);
+}
+
+/* The stabs for C++ derived classes contain baseclass information which
+ is marked by a '!' character after the total size. This function is
+ called when we encounter the baseclass marker, and slurps up all the
+ baseclass information.
+
+ Immediately following the '!' marker is the number of base classes that
+ the class is derived from, followed by information for each base class.
+ For each base class, there are two visibility specifiers, a bit offset
+ to the base class information within the derived class, a reference to
+ the type for the base class, and a terminating semicolon.
+
+ A typical example, with two base classes, would be "!2,020,19;0264,21;".
+ ^^ ^ ^ ^ ^ ^ ^
+ Baseclass information marker __________________|| | | | | | |
+ Number of baseclasses __________________________| | | | | | |
+ Visibility specifiers (2) ________________________| | | | | |
+ Offset in bits from start of class _________________| | | | |
+ Type number for base class ___________________________| | | |
+ Visibility specifiers (2) _______________________________| | |
+ Offset in bits from start of class ________________________| |
+ Type number of base class ____________________________________|
+
+ Return true for success, false for failure. */
+
+static boolean
+parse_stab_baseclasses (dhandle, info, pp, retp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ debug_baseclass **retp;
+{
+ const char *orig;
+ unsigned int c, i;
+ debug_baseclass *classes;
+
+ *retp = NULL;
+
+ orig = *pp;
+
+ if (**pp != '!')
+ {
+ /* No base classes. */
+ return true;
+ }
+ ++*pp;
+
+ c = (unsigned int) parse_number (pp, (boolean *) NULL);
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ classes = (debug_baseclass *) xmalloc ((c + 1) * sizeof (**retp));
+
+ for (i = 0; i < c; i++)
+ {
+ boolean virtual;
+ enum debug_visibility visibility;
+ bfd_vma bitpos;
+ debug_type type;
+
+ switch (**pp)
+ {
+ case '0':
+ virtual = false;
+ break;
+ case '1':
+ virtual = true;
+ break;
+ default:
+ warn_stab (orig, "unknown virtual character for baseclass");
+ virtual = false;
+ break;
+ }
+ ++*pp;
+
+ switch (**pp)
+ {
+ case '0':
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+ case '1':
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ case '2':
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ default:
+ warn_stab (orig, "unknown visibility character for baseclass");
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ }
+ ++*pp;
+
+ /* The remaining value is the bit offset of the portion of the
+ object corresponding to this baseclass. Always zero in the
+ absence of multiple inheritance. */
+ bitpos = parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual,
+ visibility);
+ if (classes[i] == DEBUG_BASECLASS_NULL)
+ return false;
+
+ if (**pp != ';')
+ return false;
+ ++*pp;
+ }
+
+ classes[i] = DEBUG_BASECLASS_NULL;
+
+ *retp = classes;
+
+ return true;
+}
+
+/* Read struct or class data fields. They have the form:
+
+ NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ;
+
+ At the end, we see a semicolon instead of a field.
+
+ In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for
+ a static field.
+
+ The optional VISIBILITY is one of:
+
+ '/0' (VISIBILITY_PRIVATE)
+ '/1' (VISIBILITY_PROTECTED)
+ '/2' (VISIBILITY_PUBLIC)
+ '/9' (VISIBILITY_IGNORE)
+
+ or nothing, for C style fields with public visibility.
+
+ Returns 1 for success, 0 for failure. */
+
+static boolean
+parse_stab_struct_fields (dhandle, info, pp, retp, staticsp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ debug_field **retp;
+ boolean *staticsp;
+{
+ const char *orig;
+ const char *p;
+ debug_field *fields;
+ unsigned int c;
+ unsigned int alloc;
+
+ *retp = NULL;
+ *staticsp = false;
+
+ orig = *pp;
+
+ c = 0;
+ alloc = 10;
+ fields = (debug_field *) xmalloc (alloc * sizeof *fields);
+ while (**pp != ';')
+ {
+ /* FIXME: gdb checks os9k_stabs here. */
+
+ p = *pp;
+
+ /* Add 1 to c to leave room for NULL pointer at end. */
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ fields = ((debug_field *)
+ xrealloc ((PTR) fields, alloc * sizeof *fields));
+ }
+
+ /* If it starts with CPLUS_MARKER it is a special abbreviation,
+ unless the CPLUS_MARKER is followed by an underscore, in
+ which case it is just the name of an anonymous type, which we
+ should handle like any other type name. We accept either '$'
+ or '.', because a field name can never contain one of these
+ characters except as a CPLUS_MARKER. */
+
+ if ((*p == '$' || *p == '.') && p[1] != '_')
+ {
+ ++*pp;
+ if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c))
+ return false;
+ ++c;
+ continue;
+ }
+
+ /* Look for the ':' that separates the field name from the field
+ values. Data members are delimited by a single ':', while member
+ functions are delimited by a pair of ':'s. When we hit the member
+ functions (if any), terminate scan loop and return. */
+
+ p = strchr (p, ':');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ if (p[1] == ':')
+ break;
+
+ if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c,
+ staticsp))
+ return false;
+
+ ++c;
+ }
+
+ fields[c] = DEBUG_FIELD_NULL;
+
+ *retp = fields;
+
+ return true;
+}
+
+/* Special GNU C++ name. */
+
+static boolean
+parse_stab_cpp_abbrev (dhandle, info, pp, retp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ debug_field *retp;
+{
+ const char *orig;
+ int cpp_abbrev;
+ debug_type context;
+ const char *name;
+ const char *typename;
+ debug_type type;
+ bfd_vma bitpos;
+
+ *retp = DEBUG_FIELD_NULL;
+
+ orig = *pp;
+
+ if (**pp != 'v')
+ {
+ bad_stab (*pp);
+ return false;
+ }
+ ++*pp;
+
+ cpp_abbrev = **pp;
+ ++*pp;
+
+ /* At this point, *pp points to something like "22:23=*22...", where
+ the type number before the ':' is the "context" and everything
+ after is a regular type definition. Lookup the type, find it's
+ name, and construct the field name. */
+
+ context = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (context == DEBUG_TYPE_NULL)
+ return false;
+
+ switch (cpp_abbrev)
+ {
+ case 'f':
+ /* $vf -- a virtual function table pointer. */
+ name = "_vptr$";
+ break;
+ case 'b':
+ /* $vb -- a virtual bsomethingorother */
+ typename = debug_get_type_name (dhandle, context);
+ if (typename == NULL)
+ {
+ warn_stab (orig, "unnamed $vb type");
+ typename = "FOO";
+ }
+ name = concat ("_vb$", typename, (const char *) NULL);
+ break;
+ default:
+ warn_stab (orig, "unrecognized C++ abbreviation");
+ name = "INVALID_CPLUSPLUS_ABBREV";
+ break;
+ }
+
+ if (**pp != ':')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ bitpos = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ *retp = debug_make_field (dhandle, name, type, bitpos, 0,
+ DEBUG_VISIBILITY_PRIVATE);
+ if (*retp == DEBUG_FIELD_NULL)
+ return false;
+
+ return true;
+}
+
+/* Parse a single field in a struct or union. */
+
+static boolean
+parse_stab_one_struct_field (dhandle, info, pp, p, retp, staticsp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ const char *p;
+ debug_field *retp;
+ boolean *staticsp;
+{
+ const char *orig;
+ char *name;
+ enum debug_visibility visibility;
+ debug_type type;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+
+ orig = *pp;
+
+ /* FIXME: gdb checks ARM_DEMANGLING here. */
+
+ name = savestring (*pp, p - *pp);
+
+ *pp = p + 1;
+
+ if (**pp != '/')
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ else
+ {
+ ++*pp;
+ switch (**pp)
+ {
+ case '0':
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+ case '1':
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ case '2':
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ default:
+ warn_stab (orig, "unknown visibility character for field");
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ }
+ ++*pp;
+ }
+
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (**pp == ':')
+ {
+ char *varname;
+
+ /* This is a static class member. */
+ ++*pp;
+ p = strchr (*pp, ';');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ varname = savestring (*pp, p - *pp);
+
+ *pp = p + 1;
+
+ *retp = debug_make_static_member (dhandle, name, type, varname,
+ visibility);
+ *staticsp = true;
+
+ return true;
+ }
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ bitpos = parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ bitsize = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ if (bitpos == 0 && bitsize == 0)
+ {
+ /* This can happen in two cases: (1) at least for gcc 2.4.5 or
+ so, it is a field which has been optimized out. The correct
+ stab for this case is to use VISIBILITY_IGNORE, but that is a
+ recent invention. (2) It is a 0-size array. For example
+ union { int num; char str[0]; } foo. Printing "<no value>"
+ for str in "p foo" is OK, since foo.str (and thus foo.str[3])
+ will continue to work, and a 0-size array as a whole doesn't
+ have any contents to print.
+
+ I suspect this probably could also happen with gcc -gstabs
+ (not -gstabs+) for static fields, and perhaps other C++
+ extensions. Hopefully few people use -gstabs with gdb, since
+ it is intended for dbx compatibility. */
+ visibility = DEBUG_VISIBILITY_IGNORE;
+ }
+
+ /* FIXME: gdb does some stuff here to mark fields as unpacked. */
+
+ *retp = debug_make_field (dhandle, name, type, bitpos, bitsize, visibility);
+
+ return true;
+}
+
+/* Read member function stabs info for C++ classes. The form of each member
+ function data is:
+
+ NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ;
+
+ An example with two member functions is:
+
+ afunc1::20=##15;:i;2A.;afunc2::20:i;2A.;
+
+ For the case of overloaded operators, the format is op$::*.funcs, where
+ $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator
+ name (such as `+=') and `.' marks the end of the operator name. */
+
+static boolean
+parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *tagname;
+ const char **pp;
+ const int *typenums;
+ debug_method **retp;
+{
+ const char *orig;
+ debug_method *methods;
+ unsigned int c;
+ unsigned int alloc;
+
+ *retp = NULL;
+
+ orig = *pp;
+
+ alloc = 0;
+ methods = NULL;
+ c = 0;
+
+ while (**pp != ';')
+ {
+ const char *p;
+ char *name;
+ debug_method_variant *variants;
+ unsigned int cvars;
+ unsigned int allocvars;
+ debug_type look_ahead_type;
+
+ p = strchr (*pp, ':');
+ if (p == NULL || p[1] != ':')
+ break;
+
+ /* FIXME: Some systems use something other than '$' here. */
+ if ((*pp)[0] != 'o' || (*pp)[1] != 'p' || (*pp)[2] != '$')
+ {
+ name = savestring (*pp, p - *pp);
+ *pp = p + 2;
+ }
+ else
+ {
+ /* This is a completely wierd case. In order to stuff in the
+ names that might contain colons (the usual name delimiter),
+ Mike Tiemann defined a different name format which is
+ signalled if the identifier is "op$". In that case, the
+ format is "op$::XXXX." where XXXX is the name. This is
+ used for names like "+" or "=". YUUUUUUUK! FIXME! */
+ *pp = p + 2;
+ for (p = *pp; *p != '.' && *p != '\0'; p++)
+ ;
+ if (*p != '.')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ name = savestring (*pp, p - *pp);
+ *pp = p + 1;
+ }
+
+ allocvars = 10;
+ variants = ((debug_method_variant *)
+ xmalloc (allocvars * sizeof *variants));
+ cvars = 0;
+
+ look_ahead_type = DEBUG_TYPE_NULL;
+
+ do
+ {
+ debug_type type;
+ boolean stub;
+ char *argtypes;
+ enum debug_visibility visibility;
+ boolean constp, volatilep, staticp;
+ bfd_vma voffset;
+ debug_type context;
+ const char *physname;
+ boolean varargs;
+
+ if (look_ahead_type != DEBUG_TYPE_NULL)
+ {
+ /* g++ version 1 kludge */
+ type = look_ahead_type;
+ look_ahead_type = DEBUG_TYPE_NULL;
+ }
+ else
+ {
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+ if (**pp != ':')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ }
+
+ ++*pp;
+ p = strchr (*pp, ';');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ stub = false;
+ if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
+ && debug_get_parameter_types (dhandle, type, &varargs) == NULL)
+ stub = true;
+
+ argtypes = savestring (*pp, p - *pp);
+ *pp = p + 1;
+
+ switch (**pp)
+ {
+ case '0':
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+ case '1':
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ default:
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ }
+ ++*pp;
+
+ constp = false;
+ volatilep = false;
+ switch (**pp)
+ {
+ case 'A':
+ /* Normal function. */
+ ++*pp;
+ break;
+ case 'B':
+ /* const member function. */
+ constp = true;
+ ++*pp;
+ break;
+ case 'C':
+ /* volatile member function. */
+ volatilep = true;
+ ++*pp;
+ break;
+ case 'D':
+ /* const volatile member function. */
+ constp = true;
+ volatilep = true;
+ ++*pp;
+ break;
+ case '*':
+ case '?':
+ case '.':
+ /* File compiled with g++ version 1; no information. */
+ break;
+ default:
+ warn_stab (orig, "const/volatile indicator missing");
+ break;
+ }
+
+ staticp = false;
+ switch (**pp)
+ {
+ case '*':
+ /* virtual member function, followed by index. The sign
+ bit is supposedly set to distinguish
+ pointers-to-methods from virtual function indicies. */
+ ++*pp;
+ voffset = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ voffset &= 0x7fffffff;
+
+ if (**pp == ';' || *pp == '\0')
+ {
+ /* Must be g++ version 1. */
+ context = DEBUG_TYPE_NULL;
+ }
+ else
+ {
+ /* Figure out from whence this virtual function
+ came. It may belong to virtual function table of
+ one of its baseclasses. */
+ look_ahead_type = parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL);
+ if (**pp == ':')
+ {
+ /* g++ version 1 overloaded methods. */
+ context = DEBUG_TYPE_NULL;
+ }
+ else
+ {
+ context = look_ahead_type;
+ look_ahead_type = DEBUG_TYPE_NULL;
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ }
+ }
+ break;
+
+ case '?':
+ /* static member function. */
+ ++*pp;
+ staticp = true;
+ voffset = 0;
+ context = DEBUG_TYPE_NULL;
+ if (strncmp (argtypes, name, strlen (name)) != 0)
+ stub = true;
+ break;
+
+ default:
+ warn_stab (orig, "member function type missing");
+ voffset = 0;
+ context = DEBUG_TYPE_NULL;
+ break;
+
+ case '.':
+ ++*pp;
+ voffset = 0;
+ context = DEBUG_TYPE_NULL;
+ break;
+ }
+
+ /* If the type is not a stub, then the argtypes string is
+ the physical name of the function. Otherwise the
+ argtypes string is the mangled form of the argument
+ types, and the full type and the physical name must be
+ extracted from them. */
+ if (! stub)
+ physname = argtypes;
+ else
+ {
+ debug_type class_type, return_type;
+
+ class_type = stab_find_type (dhandle, info, typenums);
+ if (class_type == DEBUG_TYPE_NULL)
+ return false;
+ return_type = debug_get_return_type (dhandle, type);
+ if (return_type == DEBUG_TYPE_NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+ type = parse_stab_argtypes (dhandle, info, class_type, name,
+ tagname, return_type, argtypes,
+ constp, volatilep, &physname);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+ }
+
+ if (cvars + 1 >= allocvars)
+ {
+ allocvars += 10;
+ variants = ((debug_method_variant *)
+ xrealloc ((PTR) variants,
+ allocvars * sizeof *variants));
+ }
+
+ if (! staticp)
+ variants[cvars] = debug_make_method_variant (dhandle, physname,
+ type, visibility,
+ constp, volatilep,
+ voffset, context);
+ else
+ variants[cvars] = debug_make_static_method_variant (dhandle,
+ physname,
+ type,
+ visibility,
+ constp,
+ volatilep);
+ if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL)
+ return false;
+
+ ++cvars;
+ }
+ while (**pp != ';' && **pp != '\0');
+
+ variants[cvars] = DEBUG_METHOD_VARIANT_NULL;
+
+ if (**pp != '\0')
+ ++*pp;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ methods = ((debug_method *)
+ xrealloc ((PTR) methods, alloc * sizeof *methods));
+ }
+
+ methods[c] = debug_make_method (dhandle, name, variants);
+
+ ++c;
+ }
+
+ if (methods != NULL)
+ methods[c] = DEBUG_METHOD_NULL;
+
+ *retp = methods;
+
+ return true;
+}
+
+/* Parse a string representing argument types for a method. Stabs
+ tries to save space by packing argument types into a mangled
+ string. This string should give us enough information to extract
+ both argument types and the physical name of the function, given
+ the tag name. */
+
+static debug_type
+parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
+ return_type, argtypes, constp, volatilep, pphysname)
+ PTR dhandle;
+ struct stab_handle *info;
+ debug_type class_type;
+ const char *fieldname;
+ const char *tagname;
+ debug_type return_type;
+ const char *argtypes;
+ boolean constp;
+ boolean volatilep;
+ const char **pphysname;
+{
+ boolean is_full_physname_constructor;
+ boolean is_constructor;
+ boolean is_destructor;
+ debug_type *args;
+ boolean varargs;
+
+ /* Constructors are sometimes handled specially. */
+ is_full_physname_constructor = ((argtypes[0] == '_'
+ && argtypes[1] == '_'
+ && (isdigit ((unsigned char) argtypes[2])
+ || argtypes[2] == 'Q'
+ || argtypes[2] == 't'))
+ || strncmp (argtypes, "__ct", 4) == 0);
+
+ is_constructor = (is_full_physname_constructor
+ || (tagname != NULL
+ && strcmp (fieldname, tagname) == 0));
+ is_destructor = ((argtypes[0] == '_'
+ && (argtypes[1] == '$' || argtypes[1] == '.')
+ && argtypes[2] == '_')
+ || strncmp (argtypes, "__dt", 4) == 0);
+
+ if (is_destructor || is_full_physname_constructor)
+ *pphysname = argtypes;
+ else
+ {
+ unsigned int len;
+ const char *const_prefix;
+ const char *volatile_prefix;
+ char buf[20];
+ unsigned int mangled_name_len;
+ char *physname;
+
+ len = tagname == NULL ? 0 : strlen (tagname);
+ const_prefix = constp ? "C" : "";
+ volatile_prefix = volatilep ? "V" : "";
+
+ if (len == 0)
+ sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+ else if (tagname != NULL && strchr (tagname, '<') != NULL)
+ {
+ /* Template methods are fully mangled. */
+ sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+ tagname = NULL;
+ len = 0;
+ }
+ else
+ sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
+
+ mangled_name_len = ((is_constructor ? 0 : strlen (fieldname))
+ + strlen (buf)
+ + len
+ + strlen (argtypes)
+ + 1);
+
+ if (fieldname[0] == 'o'
+ && fieldname[1] == 'p'
+ && (fieldname[2] == '$' || fieldname[2] == '.'))
+ {
+ const char *opname;
+
+ opname = cplus_mangle_opname (fieldname + 3, 0);
+ if (opname == NULL)
+ {
+ fprintf (stderr, "No mangling for \"%s\"\n", fieldname);
+ return DEBUG_TYPE_NULL;
+ }
+ mangled_name_len += strlen (opname);
+ physname = (char *) xmalloc (mangled_name_len);
+ strncpy (physname, fieldname, 3);
+ strcpy (physname + 3, opname);
+ }
+ else
+ {
+ physname = (char *) xmalloc (mangled_name_len);
+ if (is_constructor)
+ physname[0] = '\0';
+ else
+ strcpy (physname, fieldname);
+ }
+
+ strcat (physname, buf);
+ if (tagname != NULL)
+ strcat (physname, tagname);
+ strcat (physname, argtypes);
+
+ *pphysname = physname;
+ }
+
+ if (*argtypes == '\0' || is_destructor)
+ {
+ args = (debug_type *) xmalloc (sizeof *args);
+ *args = NULL;
+ return debug_make_method_type (dhandle, return_type, class_type, args,
+ false);
+ }
+
+ args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs);
+ if (args == NULL)
+ return DEBUG_TYPE_NULL;
+
+ return debug_make_method_type (dhandle, return_type, class_type, args,
+ varargs);
+}
+
+/* The tail end of stabs for C++ classes that contain a virtual function
+ pointer contains a tilde, a %, and a type number.
+ The type number refers to the base class (possibly this class itself) which
+ contains the vtable pointer for the current class.
+
+ This function is called when we have parsed all the method declarations,
+ so we can look for the vptr base class info. */
+
+static boolean
+parse_stab_tilde_field (dhandle, info, pp, typenums, retvptrbase, retownvptr)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ const int *typenums;
+ debug_type *retvptrbase;
+ boolean *retownvptr;
+{
+ const char *orig;
+ const char *hold;
+ int vtypenums[2];
+
+ *retvptrbase = DEBUG_TYPE_NULL;
+ *retownvptr = false;
+
+ orig = *pp;
+
+ /* If we are positioned at a ';', then skip it. */
+ if (**pp == ';')
+ ++*pp;
+
+ if (**pp != '~')
+ return true;
+
+ ++*pp;
+
+ if (**pp == '=' || **pp == '+' || **pp == '-')
+ {
+ /* Obsolete flags that used to indicate the presence of
+ constructors and/or destructors. */
+ ++*pp;
+ }
+
+ if (**pp != '%')
+ return true;
+
+ ++*pp;
+
+ hold = *pp;
+
+ /* The next number is the type number of the base class (possibly
+ our own class) which supplies the vtable for this class. */
+ if (! parse_stab_type_number (pp, vtypenums))
+ return false;
+
+ if (vtypenums[0] == typenums[0]
+ && vtypenums[1] == typenums[1])
+ *retownvptr = true;
+ else
+ {
+ debug_type vtype;
+ const char *p;
+
+ *pp = hold;
+
+ vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ for (p = *pp; *p != ';' && *p != '\0'; p++)
+ ;
+ if (*p != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ *retvptrbase = vtype;
+
+ *pp = p + 1;
+ }
+
+ return true;
+}
+
+/* Read a definition of an array type. */
+
+static debug_type
+parse_stab_array_type (dhandle, info, pp, stringp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ boolean stringp;
+{
+ const char *orig;
+ const char *p;
+ int typenums[2];
+ debug_type index_type;
+ boolean adjustable;
+ bfd_signed_vma lower, upper;
+ debug_type element_type;
+
+ /* Format of an array type:
+ "ar<index type>;lower;upper;<array_contents_type>".
+ OS9000: "arlower,upper;<array_contents_type>".
+
+ Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
+ for these, produce a type like float[][]. */
+
+ orig = *pp;
+
+ /* FIXME: gdb checks os9k_stabs here. */
+
+ /* If the index type is type 0, we take it as int. */
+ p = *pp;
+ if (! parse_stab_type_number (&p, typenums))
+ return DEBUG_TYPE_NULL;
+ if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=')
+ {
+ index_type = debug_find_named_type (dhandle, "int");
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ index_type = debug_make_int_type (dhandle, 4, false);
+ if (index_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ }
+ *pp = p;
+ }
+ else
+ {
+ index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ }
+
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ adjustable = false;
+
+ if (! isdigit ((unsigned char) **pp) && **pp != '-')
+ {
+ ++*pp;
+ adjustable = true;
+ }
+
+ lower = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (! isdigit ((unsigned char) **pp) && **pp != '-')
+ {
+ ++*pp;
+ adjustable = true;
+ }
+
+ upper = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (element_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (adjustable)
+ {
+ lower = 0;
+ upper = -1;
+ }
+
+ return debug_make_array_type (dhandle, element_type, index_type, lower,
+ upper, stringp);
+}
+
+/* This struct holds information about files we have seen using
+ N_BINCL. */
+
+struct bincl_file
+{
+ /* The next N_BINCL file. */
+ struct bincl_file *next;
+ /* The next N_BINCL on the stack. */
+ struct bincl_file *next_stack;
+ /* The file name. */
+ const char *name;
+ /* The hash value. */
+ bfd_vma hash;
+ /* The file index. */
+ unsigned int file;
+ /* The list of types defined in this file. */
+ struct stab_types *file_types;
+};
+
+/* Start a new N_BINCL file, pushing it onto the stack. */
+
+static void
+push_bincl (info, name, hash)
+ struct stab_handle *info;
+ const char *name;
+ bfd_vma hash;
+{
+ struct bincl_file *n;
+
+ n = (struct bincl_file *) xmalloc (sizeof *n);
+ n->next = info->bincl_list;
+ n->next_stack = info->bincl_stack;
+ n->name = name;
+ n->hash = hash;
+ n->file = info->files;
+ n->file_types = NULL;
+ info->bincl_list = n;
+ info->bincl_stack = n;
+
+ ++info->files;
+ info->file_types = ((struct stab_types **)
+ xrealloc ((PTR) info->file_types,
+ (info->files
+ * sizeof *info->file_types)));
+ info->file_types[n->file] = NULL;
+}
+
+/* Finish an N_BINCL file, at an N_EINCL, popping the name off the
+ stack. */
+
+static const char *
+pop_bincl (info)
+ struct stab_handle *info;
+{
+ struct bincl_file *o;
+
+ o = info->bincl_stack;
+ if (o == NULL)
+ return info->main_filename;
+ info->bincl_stack = o->next_stack;
+
+ o->file_types = info->file_types[o->file];
+
+ if (info->bincl_stack == NULL)
+ return info->main_filename;
+ return info->bincl_stack->name;
+}
+
+/* Handle an N_EXCL: get the types from the corresponding N_BINCL. */
+
+static boolean
+find_excl (info, name, hash)
+ struct stab_handle *info;
+ const char *name;
+ bfd_vma hash;
+{
+ struct bincl_file *l;
+
+ ++info->files;
+ info->file_types = ((struct stab_types **)
+ xrealloc ((PTR) info->file_types,
+ (info->files
+ * sizeof *info->file_types)));
+
+ for (l = info->bincl_list; l != NULL; l = l->next)
+ if (l->hash == hash && strcmp (l->name, name) == 0)
+ break;
+ if (l == NULL)
+ {
+ warn_stab (name, "Undefined N_EXCL");
+ info->file_types[info->files - 1] = NULL;
+ return true;
+ }
+
+ info->file_types[info->files - 1] = l->file_types;
+
+ return true;
+}
+
+/* Handle a variable definition. gcc emits variable definitions for a
+ block before the N_LBRAC, so we must hold onto them until we see
+ it. The SunPRO compiler emits variable definitions after the
+ N_LBRAC, so we can call debug_record_variable immediately. */
+
+static boolean
+stab_record_variable (dhandle, info, name, type, kind, val)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *name;
+ debug_type type;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct stab_pending_var *v;
+
+ if ((kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
+ || ! info->within_function
+ || (info->gcc_compiled == 0 && info->n_opt_found))
+ return debug_record_variable (dhandle, name, type, kind, val);
+
+ v = (struct stab_pending_var *) xmalloc (sizeof *v);
+ memset (v, 0, sizeof *v);
+
+ v->next = info->pending;
+ v->name = name;
+ v->type = type;
+ v->kind = kind;
+ v->val = val;
+ info->pending = v;
+
+ return true;
+}
+
+/* Emit pending variable definitions. This is called after we see the
+ N_LBRAC that starts the block. */
+
+static boolean
+stab_emit_pending_vars (dhandle, info)
+ PTR dhandle;
+ struct stab_handle *info;
+{
+ struct stab_pending_var *v;
+
+ v = info->pending;
+ while (v != NULL)
+ {
+ struct stab_pending_var *next;
+
+ if (! debug_record_variable (dhandle, v->name, v->type, v->kind, v->val))
+ return false;
+
+ next = v->next;
+ free (v);
+ v = next;
+ }
+
+ info->pending = NULL;
+
+ return true;
+}
+
+/* Find the slot for a type in the database. */
+
+static debug_type *
+stab_find_slot (info, typenums)
+ struct stab_handle *info;
+ const int *typenums;
+{
+ int filenum;
+ int index;
+ struct stab_types **ps;
+
+ filenum = typenums[0];
+ index = typenums[1];
+
+ if (filenum < 0 || (unsigned int) filenum >= info->files)
+ {
+ fprintf (stderr, "Type file number %d out of range\n", filenum);
+ return NULL;
+ }
+ if (index < 0)
+ {
+ fprintf (stderr, "Type index number %d out of range\n", index);
+ return NULL;
+ }
+
+ ps = info->file_types + filenum;
+
+ while (index >= STAB_TYPES_SLOTS)
+ {
+ if (*ps == NULL)
+ {
+ *ps = (struct stab_types *) xmalloc (sizeof **ps);
+ memset (*ps, 0, sizeof **ps);
+ }
+ ps = &(*ps)->next;
+ index -= STAB_TYPES_SLOTS;
+ }
+ if (*ps == NULL)
+ {
+ *ps = (struct stab_types *) xmalloc (sizeof **ps);
+ memset (*ps, 0, sizeof **ps);
+ }
+
+ return (*ps)->types + index;
+}
+
+/* Find a type given a type number. If the type has not been
+ allocated yet, create an indirect type. */
+
+static debug_type
+stab_find_type (dhandle, info, typenums)
+ PTR dhandle;
+ struct stab_handle *info;
+ const int *typenums;
+{
+ debug_type *slot;
+
+ if (typenums[0] == 0 && typenums[1] < 0)
+ {
+ /* A negative type number indicates an XCOFF builtin type. */
+ return stab_xcoff_builtin_type (dhandle, info, typenums[1]);
+ }
+
+ slot = stab_find_slot (info, typenums);
+ if (slot == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (*slot == DEBUG_TYPE_NULL)
+ return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
+
+ return *slot;
+}
+
+/* Record that a given type number refers to a given type. */
+
+static boolean
+stab_record_type (dhandle, info, typenums, type)
+ PTR dhandle;
+ struct stab_handle *info;
+ const int *typenums;
+ debug_type type;
+{
+ debug_type *slot;
+
+ slot = stab_find_slot (info, typenums);
+ if (slot == NULL)
+ return false;
+
+ /* gdb appears to ignore type redefinitions, so we do as well. */
+
+ *slot = type;
+
+ return true;
+}
+
+/* Return an XCOFF builtin type. */
+
+static debug_type
+stab_xcoff_builtin_type (dhandle, info, typenum)
+ PTR dhandle;
+ struct stab_handle *info;
+ int typenum;
+{
+ debug_type rettype;
+ const char *name;
+
+ if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT)
+ {
+ fprintf (stderr, "Unrecognized XCOFF type %d\n", typenum);
+ return DEBUG_TYPE_NULL;
+ }
+ if (info->xcoff_types[-typenum] != NULL)
+ return info->xcoff_types[-typenum];
+
+ switch (-typenum)
+ {
+ case 1:
+ /* The size of this and all the other types are fixed, defined
+ by the debugging format. */
+ name = "int";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 2:
+ name = "char";
+ rettype = debug_make_int_type (dhandle, 1, false);
+ break;
+ case 3:
+ name = "short";
+ rettype = debug_make_int_type (dhandle, 2, false);
+ break;
+ case 4:
+ name = "long";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 5:
+ name = "unsigned char";
+ rettype = debug_make_int_type (dhandle, 1, true);
+ break;
+ case 6:
+ name = "signed char";
+ rettype = debug_make_int_type (dhandle, 1, false);
+ break;
+ case 7:
+ name = "unsigned short";
+ rettype = debug_make_int_type (dhandle, 2, true);
+ break;
+ case 8:
+ name = "unsigned int";
+ rettype = debug_make_int_type (dhandle, 4, true);
+ break;
+ case 9:
+ name = "unsigned";
+ rettype = debug_make_int_type (dhandle, 4, true);
+ case 10:
+ name = "unsigned long";
+ rettype = debug_make_int_type (dhandle, 4, true);
+ break;
+ case 11:
+ name = "void";
+ rettype = debug_make_void_type (dhandle);
+ break;
+ case 12:
+ /* IEEE single precision (32 bit). */
+ name = "float";
+ rettype = debug_make_float_type (dhandle, 4);
+ break;
+ case 13:
+ /* IEEE double precision (64 bit). */
+ name = "double";
+ rettype = debug_make_float_type (dhandle, 8);
+ break;
+ case 14:
+ /* This is an IEEE double on the RS/6000, and different machines
+ with different sizes for "long double" should use different
+ negative type numbers. See stabs.texinfo. */
+ name = "long double";
+ rettype = debug_make_float_type (dhandle, 8);
+ break;
+ case 15:
+ name = "integer";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 16:
+ name = "boolean";
+ rettype = debug_make_bool_type (dhandle, 4);
+ break;
+ case 17:
+ name = "short real";
+ rettype = debug_make_float_type (dhandle, 4);
+ break;
+ case 18:
+ name = "real";
+ rettype = debug_make_float_type (dhandle, 8);
+ break;
+ case 19:
+ /* FIXME */
+ name = "stringptr";
+ rettype = NULL;
+ break;
+ case 20:
+ /* FIXME */
+ name = "character";
+ rettype = debug_make_int_type (dhandle, 1, true);
+ break;
+ case 21:
+ name = "logical*1";
+ rettype = debug_make_bool_type (dhandle, 1);
+ break;
+ case 22:
+ name = "logical*2";
+ rettype = debug_make_bool_type (dhandle, 2);
+ break;
+ case 23:
+ name = "logical*4";
+ rettype = debug_make_bool_type (dhandle, 4);
+ break;
+ case 24:
+ name = "logical";
+ rettype = debug_make_bool_type (dhandle, 4);
+ break;
+ case 25:
+ /* Complex type consisting of two IEEE single precision values. */
+ name = "complex";
+ rettype = debug_make_complex_type (dhandle, 8);
+ break;
+ case 26:
+ /* Complex type consisting of two IEEE double precision values. */
+ name = "double complex";
+ rettype = debug_make_complex_type (dhandle, 16);
+ break;
+ case 27:
+ name = "integer*1";
+ rettype = debug_make_int_type (dhandle, 1, false);
+ break;
+ case 28:
+ name = "integer*2";
+ rettype = debug_make_int_type (dhandle, 2, false);
+ break;
+ case 29:
+ name = "integer*4";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 30:
+ /* FIXME */
+ name = "wchar";
+ rettype = debug_make_int_type (dhandle, 2, false);
+ break;
+ case 31:
+ name = "long long";
+ rettype = debug_make_int_type (dhandle, 8, false);
+ break;
+ case 32:
+ name = "unsigned long long";
+ rettype = debug_make_int_type (dhandle, 8, true);
+ break;
+ case 33:
+ name = "logical*8";
+ rettype = debug_make_bool_type (dhandle, 8);
+ break;
+ case 34:
+ name = "integer*8";
+ rettype = debug_make_int_type (dhandle, 8, false);
+ break;
+ default:
+ abort ();
+ }
+
+ rettype = debug_name_type (dhandle, name, rettype);
+
+ info->xcoff_types[-typenum] = rettype;
+
+ return rettype;
+}
+
+/* Find or create a tagged type. */
+
+static debug_type
+stab_find_tagged_type (dhandle, info, p, len, kind)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *p;
+ int len;
+ enum debug_type_kind kind;
+{
+ char *name;
+ debug_type dtype;
+ struct stab_tag *st;
+
+ name = savestring (p, len);
+
+ /* We pass DEBUG_KIND_ILLEGAL because we want all tags in the same
+ namespace. This is right for C, and I don't know how to handle
+ other languages. FIXME. */
+ dtype = debug_find_tagged_type (dhandle, name, DEBUG_KIND_ILLEGAL);
+ if (dtype != DEBUG_TYPE_NULL)
+ {
+ free (name);
+ return dtype;
+ }
+
+ /* We need to allocate an entry on the undefined tag list. */
+ for (st = info->tags; st != NULL; st = st->next)
+ {
+ if (st->name[0] == name[0]
+ && strcmp (st->name, name) == 0)
+ {
+ if (st->kind == DEBUG_KIND_ILLEGAL)
+ st->kind = kind;
+ free (name);
+ break;
+ }
+ }
+ if (st == NULL)
+ {
+ st = (struct stab_tag *) xmalloc (sizeof *st);
+ memset (st, 0, sizeof *st);
+
+ st->next = info->tags;
+ st->name = name;
+ st->kind = kind;
+ st->slot = DEBUG_TYPE_NULL;
+ st->type = debug_make_indirect_type (dhandle, &st->slot, name);
+ info->tags = st;
+ }
+
+ return st->type;
+}
+
+/* In order to get the correct argument types for a stubbed method, we
+ need to extract the argument types from a C++ mangled string.
+ Since the argument types can refer back to the return type, this
+ means that we must demangle the entire physical name. In gdb this
+ is done by calling cplus_demangle and running the results back
+ through the C++ expression parser. Since we have no expression
+ parser, we must duplicate much of the work of cplus_demangle here.
+
+ We assume that GNU style demangling is used, since this is only
+ done for method stubs, and only g++ should output that form of
+ debugging information. */
+
+/* This structure is used to hold a pointer to type information which
+ demangling a string. */
+
+struct stab_demangle_typestring
+{
+ /* The start of the type. This is not null terminated. */
+ const char *typestring;
+ /* The length of the type. */
+ unsigned int len;
+};
+
+/* This structure is used to hold information while demangling a
+ string. */
+
+struct stab_demangle_info
+{
+ /* The debugging information handle. */
+ PTR dhandle;
+ /* The stab information handle. */
+ struct stab_handle *info;
+ /* The array of arguments we are building. */
+ debug_type *args;
+ /* Whether the method takes a variable number of arguments. */
+ boolean varargs;
+ /* The array of types we have remembered. */
+ struct stab_demangle_typestring *typestrings;
+ /* The number of typestrings. */
+ unsigned int typestring_count;
+ /* The number of typestring slots we have allocated. */
+ unsigned int typestring_alloc;
+};
+
+static void stab_bad_demangle PARAMS ((const char *));
+static unsigned int stab_demangle_count PARAMS ((const char **));
+static boolean stab_demangle_get_count
+ PARAMS ((const char **, unsigned int *));
+static boolean stab_demangle_prefix
+ PARAMS ((struct stab_demangle_info *, const char **));
+static boolean stab_demangle_function_name
+ PARAMS ((struct stab_demangle_info *, const char **, const char *));
+static boolean stab_demangle_signature
+ PARAMS ((struct stab_demangle_info *, const char **));
+static boolean stab_demangle_qualified
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+static boolean stab_demangle_template
+ PARAMS ((struct stab_demangle_info *, const char **));
+static boolean stab_demangle_class
+ PARAMS ((struct stab_demangle_info *, const char **, const char **));
+static boolean stab_demangle_args
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
+ boolean *));
+static boolean stab_demangle_arg
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
+ unsigned int *, unsigned int *));
+static boolean stab_demangle_type
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+static boolean stab_demangle_fund_type
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+static boolean stab_demangle_remember_type
+ PARAMS ((struct stab_demangle_info *, const char *, int));
+
+/* Warn about a bad demangling. */
+
+static void
+stab_bad_demangle (s)
+ const char *s;
+{
+ fprintf (stderr, "bad mangled name `%s'\n", s);
+}
+
+/* Get a count from a stab string. */
+
+static unsigned int
+stab_demangle_count (pp)
+ const char **pp;
+{
+ unsigned int count;
+
+ count = 0;
+ while (isdigit ((unsigned char) **pp))
+ {
+ count *= 10;
+ count += **pp - '0';
+ ++*pp;
+ }
+ return count;
+}
+
+/* Require a count in a string. The count may be multiple digits, in
+ which case it must end in an underscore. */
+
+static boolean
+stab_demangle_get_count (pp, pi)
+ const char **pp;
+ unsigned int *pi;
+{
+ if (! isdigit ((unsigned char) **pp))
+ return false;
+
+ *pi = **pp - '0';
+ ++*pp;
+ if (isdigit ((unsigned char) **pp))
+ {
+ unsigned int count;
+ const char *p;
+
+ count = *pi;
+ p = *pp;
+ do
+ {
+ count *= 10;
+ count += *p - '0';
+ ++p;
+ }
+ while (isdigit ((unsigned char) *p));
+ if (*p == '_')
+ {
+ *pp = p + 1;
+ *pi = count;
+ }
+ }
+
+ return true;
+}
+
+/* This function demangles a physical name, returning a NULL
+ terminated array of argument types. */
+
+static debug_type *
+stab_demangle_argtypes (dhandle, info, physname, pvarargs)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *physname;
+ boolean *pvarargs;
+{
+ struct stab_demangle_info minfo;
+
+ minfo.dhandle = dhandle;
+ minfo.info = info;
+ minfo.args = NULL;
+ minfo.varargs = false;
+ minfo.typestring_alloc = 10;
+ minfo.typestrings = ((struct stab_demangle_typestring *)
+ xmalloc (minfo.typestring_alloc
+ * sizeof *minfo.typestrings));
+ minfo.typestring_count = 0;
+
+ /* cplus_demangle checks for special GNU mangled forms, but we can't
+ see any of them in mangled method argument types. */
+
+ if (! stab_demangle_prefix (&minfo, &physname))
+ goto error_return;
+
+ if (*physname != '\0')
+ {
+ if (! stab_demangle_signature (&minfo, &physname))
+ goto error_return;
+ }
+
+ free (minfo.typestrings);
+ minfo.typestrings = NULL;
+
+ if (minfo.args == NULL)
+ fprintf (stderr, "no argument types in mangled string\n");
+
+ *pvarargs = minfo.varargs;
+ return minfo.args;
+
+ error_return:
+ if (minfo.typestrings != NULL)
+ free (minfo.typestrings);
+ return NULL;
+}
+
+/* Demangle the prefix of the mangled name. */
+
+static boolean
+stab_demangle_prefix (minfo, pp)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+{
+ const char *scan;
+ unsigned int i;
+
+ /* cplus_demangle checks for global constructors and destructors,
+ but we can't see them in mangled argument types. */
+
+ /* Look for `__'. */
+ scan = *pp;
+ do
+ {
+ scan = strchr (scan, '_');
+ }
+ while (scan != NULL && *++scan != '_');
+
+ if (scan == NULL)
+ {
+ stab_bad_demangle (*pp);
+ return false;
+ }
+
+ --scan;
+
+ /* We found `__'; move ahead to the last contiguous `__' pair. */
+ i = strspn (scan, "_");
+ if (i > 2)
+ scan += i - 2;
+
+ if (scan == *pp
+ && (isdigit ((unsigned char) scan[2])
+ || scan[2] == 'Q'
+ || scan[2] == 't'))
+ {
+ /* This is a GNU style constructor name. */
+ *pp = scan + 2;
+ return true;
+ }
+ else if (scan == *pp
+ && ! isdigit ((unsigned char) scan[2])
+ && scan[2] != 't')
+ {
+ /* Look for the `__' that separates the prefix from the
+ signature. */
+ while (*scan == '_')
+ ++scan;
+ scan = strstr (scan, "__");
+ if (scan == NULL || scan[2] == '\0')
+ {
+ stab_bad_demangle (*pp);
+ return false;
+ }
+
+ return stab_demangle_function_name (minfo, pp, scan);
+ }
+ else if (scan[2] != '\0')
+ {
+ /* The name doesn't start with `__', but it does contain `__'. */
+ return stab_demangle_function_name (minfo, pp, scan);
+ }
+ else
+ {
+ stab_bad_demangle (*pp);
+ return false;
+ }
+ /*NOTREACHED*/
+}
+
+/* Demangle a function name prefix. The scan argument points to the
+ double underscore which separates the function name from the
+ signature. */
+
+static boolean
+stab_demangle_function_name (minfo, pp, scan)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ const char *scan;
+{
+ const char *name;
+
+ /* The string from *pp to scan is the name of the function. We
+ don't care about the name, since we just looking for argument
+ types. However, for conversion operators, the name may include a
+ type which we must remember in order to handle backreferences. */
+
+ name = *pp;
+ *pp = scan + 2;
+
+ if (*pp - name >= 5
+ && strncmp (name, "type", 4) == 0
+ && (name[4] == '$' || name[4] == '.'))
+ {
+ const char *tem;
+
+ /* This is a type conversion operator. */
+ tem = name + 5;
+ if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
+ return false;
+ }
+ else if (name[0] == '_'
+ && name[1] == '_'
+ && name[2] == 'o'
+ && name[3] == 'p')
+ {
+ const char *tem;
+
+ /* This is a type conversion operator. */
+ tem = name + 4;
+ if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
+ return false;
+ }
+
+ return true;
+}
+
+/* Demangle the signature. This is where the argument types are
+ found. */
+
+static boolean
+stab_demangle_signature (minfo, pp)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+{
+ const char *orig;
+ boolean expect_func, func_done;
+ const char *hold;
+
+ orig = *pp;
+
+ expect_func = false;
+ func_done = false;
+ hold = NULL;
+
+ while (**pp != '\0')
+ {
+ switch (**pp)
+ {
+ case 'Q':
+ hold = *pp;
+ if (! stab_demangle_qualified (minfo, pp, (debug_type *) NULL)
+ || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
+ return false;
+ expect_func = true;
+ hold = NULL;
+ break;
+
+ case 'S':
+ /* Static member function. FIXME: Can this happen? */
+ if (hold == NULL)
+ hold = *pp;
+ ++*pp;
+ break;
+
+ case 'C':
+ /* Const member function. */
+ if (hold == NULL)
+ hold = *pp;
+ ++*pp;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (hold == NULL)
+ hold = *pp;
+ if (! stab_demangle_class (minfo, pp, (const char **) NULL)
+ || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
+ return false;
+ expect_func = true;
+ hold = NULL;
+ break;
+
+ case 'F':
+ /* Function. I don't know if this actually happens with g++
+ output. */
+ hold = NULL;
+ func_done = true;
+ ++*pp;
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ break;
+
+ case 't':
+ /* Template. */
+ if (hold == NULL)
+ hold = *pp;
+ if (! stab_demangle_template (minfo, pp)
+ || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
+ return false;
+ hold = NULL;
+ expect_func = true;
+ break;
+
+ case '_':
+ /* At the outermost level, we cannot have a return type
+ specified, so if we run into another '_' at this point we
+ are dealing with a mangled name that is either bogus, or
+ has been mangled by some algorithm we don't know how to
+ deal with. So just reject the entire demangling. */
+ stab_bad_demangle (orig);
+ return false;
+
+ default:
+ /* Assume we have stumbled onto the first outermost function
+ argument token, and start processing args. */
+ func_done = true;
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ break;
+ }
+
+ if (expect_func)
+ {
+ func_done = true;
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ }
+ }
+
+ if (! func_done)
+ {
+ /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
+ bar__3fooi is 'foo::bar(int)'. We get here when we find the
+ first case, and need to ensure that the '(void)' gets added
+ to the current declp. */
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ }
+
+ return true;
+}
+
+/* Demangle a qualified name, such as "Q25Outer5Inner" which is the
+ mangled form of "Outer::Inner". */
+
+static boolean
+stab_demangle_qualified (minfo, pp, ptype)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type *ptype;
+{
+ const char *orig;
+ const char *p;
+ unsigned int qualifiers;
+ debug_type context;
+
+ orig = *pp;
+
+ switch ((*pp)[1])
+ {
+ case '_':
+ /* GNU mangled name with more than 9 classes. The count is
+ preceded by an underscore (to distinguish it from the <= 9
+ case) and followed by an underscore. */
+ p = *pp + 2;
+ if (! isdigit ((unsigned char) *p) || *p == '0')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ qualifiers = atoi (p);
+ while (isdigit ((unsigned char) *p))
+ ++p;
+ if (*p != '_')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ *pp = p + 1;
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ qualifiers = (*pp)[1] - '0';
+ /* Skip an optional underscore after the count. */
+ if ((*pp)[2] == '_')
+ ++*pp;
+ *pp += 2;
+ break;
+
+ case '0':
+ default:
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ context = DEBUG_TYPE_NULL;
+
+ /* Pick off the names. */
+ while (qualifiers-- > 0)
+ {
+ if (**pp == '_')
+ ++*pp;
+ if (**pp == 't')
+ {
+ /* FIXME: I don't know how to handle the ptype != NULL case
+ here. */
+ if (! stab_demangle_template (minfo, pp))
+ return false;
+ }
+ else
+ {
+ unsigned int len;
+
+ len = stab_demangle_count (pp);
+ if (strlen (*pp) < len)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (ptype != NULL)
+ {
+ const debug_field *fields;
+
+ fields = NULL;
+ if (context != DEBUG_TYPE_NULL)
+ fields = debug_get_fields (minfo->dhandle, context);
+
+ context = DEBUG_TYPE_NULL;
+
+ if (fields != NULL)
+ {
+ char *name;
+
+ /* Try to find the type by looking through the
+ fields of context until we find a field with the
+ same type. This ought to work for a class
+ defined within a class, but it won't work for,
+ e.g., an enum defined within a class. stabs does
+ not give us enough information to figure out the
+ latter case. */
+
+ name = savestring (*pp, len);
+
+ for (; *fields != DEBUG_FIELD_NULL; fields++)
+ {
+ debug_type ft;
+ const char *dn;
+
+ ft = debug_get_field_type (minfo->dhandle, *fields);
+ if (ft == NULL)
+ return false;
+ dn = debug_get_type_name (minfo->dhandle, ft);
+ if (dn != NULL && strcmp (dn, name) == 0)
+ {
+ context = ft;
+ break;
+ }
+ }
+
+ free (name);
+ }
+
+ if (context == DEBUG_TYPE_NULL)
+ {
+ /* We have to fall back on finding the type by name.
+ If there are more types to come, then this must
+ be a class. Otherwise, it could be anything. */
+
+ if (qualifiers == 0)
+ {
+ char *name;
+
+ name = savestring (*pp, len);
+ context = debug_find_named_type (minfo->dhandle,
+ name);
+ free (name);
+ }
+
+ if (context == DEBUG_TYPE_NULL)
+ {
+ context = stab_find_tagged_type (minfo->dhandle,
+ minfo->info,
+ *pp, len,
+ (qualifiers == 0
+ ? DEBUG_KIND_ILLEGAL
+ : DEBUG_KIND_CLASS));
+ if (context == DEBUG_TYPE_NULL)
+ return false;
+ }
+ }
+ }
+
+ *pp += len;
+ }
+ }
+
+ if (ptype != NULL)
+ *ptype = context;
+
+ return true;
+}
+
+/* Demangle a template. */
+
+static boolean
+stab_demangle_template (minfo, pp)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+{
+ const char *orig;
+ unsigned int r, i;
+
+ orig = *pp;
+
+ ++*pp;
+
+ /* Skip the template name. */
+ r = stab_demangle_count (pp);
+ if (r == 0 || strlen (*pp) < r)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ *pp += r;
+
+ /* Get the size of the parameter list. */
+ if (stab_demangle_get_count (pp, &r) == 0)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ for (i = 0; i < r; i++)
+ {
+ if (**pp == 'Z')
+ {
+ /* This is a type parameter. */
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
+ return false;
+ }
+ else
+ {
+ const char *old_p;
+ boolean pointerp, realp, integralp, charp, boolp;
+ boolean done;
+
+ old_p = *pp;
+ pointerp = false;
+ realp = false;
+ integralp = false;
+ charp = false;
+ boolp = false;
+ done = false;
+
+ /* This is a value parameter. */
+
+ if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
+ return false;
+
+ while (*old_p != '\0' && ! done)
+ {
+ switch (*old_p)
+ {
+ case 'P':
+ case 'p':
+ case 'R':
+ pointerp = true;
+ done = true;
+ break;
+ case 'C': /* Const. */
+ case 'S': /* Signed. */
+ case 'U': /* Unsigned. */
+ case 'V': /* Volatile. */
+ case 'F': /* Function. */
+ case 'M': /* Member function. */
+ case 'O': /* ??? */
+ ++old_p;
+ break;
+ case 'Q': /* Qualified name. */
+ integralp = true;
+ done = true;
+ break;
+ case 'T': /* Remembered type. */
+ abort ();
+ case 'v': /* Void. */
+ abort ();
+ case 'x': /* Long long. */
+ case 'l': /* Long. */
+ case 'i': /* Int. */
+ case 's': /* Short. */
+ case 'w': /* Wchar_t. */
+ integralp = true;
+ done = true;
+ break;
+ case 'b': /* Bool. */
+ boolp = true;
+ done = true;
+ break;
+ case 'c': /* Char. */
+ charp = true;
+ done = true;
+ break;
+ case 'r': /* Long double. */
+ case 'd': /* Double. */
+ case 'f': /* Float. */
+ realp = true;
+ done = true;
+ break;
+ default:
+ /* Assume it's a user defined integral type. */
+ integralp = true;
+ done = true;
+ break;
+ }
+ }
+
+ if (integralp)
+ {
+ if (**pp == 'm')
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ }
+ else if (charp)
+ {
+ unsigned int val;
+
+ if (**pp == 'm')
+ ++*pp;
+ val = stab_demangle_count (pp);
+ if (val == 0)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ }
+ else if (boolp)
+ {
+ unsigned int val;
+
+ val = stab_demangle_count (pp);
+ if (val != 0 && val != 1)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ }
+ else if (realp)
+ {
+ if (**pp == 'm')
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ if (**pp == '.')
+ {
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ }
+ if (**pp == 'e')
+ {
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ }
+ }
+ else if (pointerp)
+ {
+ unsigned int len;
+
+ if (! stab_demangle_get_count (pp, &len))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ *pp += len;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Demangle a class name. */
+
+static boolean
+stab_demangle_class (minfo, pp, pstart)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ const char **pstart;
+{
+ const char *orig;
+ unsigned int n;
+
+ orig = *pp;
+
+ n = stab_demangle_count (pp);
+ if (strlen (*pp) < n)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (pstart != NULL)
+ *pstart = *pp;
+
+ *pp += n;
+
+ return true;
+}
+
+/* Demangle function arguments. If the pargs argument is not NULL, it
+ is set to a NULL terminated array holding the arguments. */
+
+static boolean
+stab_demangle_args (minfo, pp, pargs, pvarargs)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type **pargs;
+ boolean *pvarargs;
+{
+ const char *orig;
+ unsigned int alloc, count;
+
+ orig = *pp;
+
+ alloc = 10;
+ if (pargs != NULL)
+ {
+ *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
+ *pvarargs = false;
+ }
+ count = 0;
+
+ while (**pp != '_' && **pp != '\0' && **pp != 'e')
+ {
+ if (**pp == 'N' || **pp == 'T')
+ {
+ char temptype;
+ unsigned int r, t;
+
+ temptype = **pp;
+ ++*pp;
+
+ if (temptype == 'T')
+ r = 1;
+ else
+ {
+ if (! stab_demangle_get_count (pp, &r))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ }
+
+ if (! stab_demangle_get_count (pp, &t))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (t >= minfo->typestring_count)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ while (r-- > 0)
+ {
+ const char *tem;
+
+ tem = minfo->typestrings[t].typestring;
+ if (! stab_demangle_arg (minfo, &tem, pargs, &count, &alloc))
+ return false;
+ }
+ }
+ else
+ {
+ if (! stab_demangle_arg (minfo, pp, pargs, &count, &alloc))
+ return false;
+ }
+ }
+
+ if (pargs != NULL)
+ (*pargs)[count] = DEBUG_TYPE_NULL;
+
+ if (**pp == 'e')
+ {
+ if (pargs != NULL)
+ *pvarargs = true;
+ ++*pp;
+ }
+
+ return true;
+}
+
+/* Demangle a single argument. */
+
+static boolean
+stab_demangle_arg (minfo, pp, pargs, pcount, palloc)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type **pargs;
+ unsigned int *pcount;
+ unsigned int *palloc;
+{
+ const char *start;
+ debug_type type;
+
+ start = *pp;
+ if (! stab_demangle_type (minfo, pp,
+ pargs == NULL ? (debug_type *) NULL : &type)
+ || ! stab_demangle_remember_type (minfo, start, *pp - start))
+ return false;
+
+ if (pargs != NULL)
+ {
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (*pcount + 1 >= *palloc)
+ {
+ *palloc += 10;
+ *pargs = ((debug_type *)
+ xrealloc (*pargs, *palloc * sizeof **pargs));
+ }
+ (*pargs)[*pcount] = type;
+ ++*pcount;
+ }
+
+ return true;
+}
+
+/* Demangle a type. If the ptype argument is not NULL, *ptype is set
+ to the newly allocated type. */
+
+static boolean
+stab_demangle_type (minfo, pp, ptype)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type *ptype;
+{
+ const char *orig;
+
+ orig = *pp;
+
+ switch (**pp)
+ {
+ case 'P':
+ case 'p':
+ /* A pointer type. */
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_pointer_type (minfo->dhandle, *ptype);
+ break;
+
+ case 'R':
+ /* A reference type. */
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_reference_type (minfo->dhandle, *ptype);
+ break;
+
+ case 'A':
+ /* An array. */
+ {
+ unsigned long high;
+
+ ++*pp;
+ high = 0;
+ while (**pp != '\0' && **pp != '_')
+ {
+ if (! isdigit ((unsigned char) **pp))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ high *= 10;
+ high += **pp - '0';
+ ++*pp;
+ }
+ if (**pp != '_')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ {
+ debug_type int_type;
+
+ int_type = debug_find_named_type (minfo->dhandle, "int");
+ if (int_type == NULL)
+ int_type = debug_make_int_type (minfo->dhandle, 4, false);
+ *ptype = debug_make_array_type (minfo->dhandle, *ptype, int_type,
+ 0, high, false);
+ }
+ }
+ break;
+
+ case 'T':
+ /* A back reference to a remembered type. */
+ {
+ unsigned int i;
+ const char *p;
+
+ ++*pp;
+ if (! stab_demangle_get_count (pp, &i))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ if (i >= minfo->typestring_count)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ p = minfo->typestrings[i].typestring;
+ if (! stab_demangle_type (minfo, &p, ptype))
+ return false;
+ }
+ break;
+
+ case 'F':
+ /* A function. */
+ {
+ debug_type *args;
+ boolean varargs;
+
+ ++*pp;
+ if (! stab_demangle_args (minfo, pp,
+ (ptype == NULL
+ ? (debug_type **) NULL
+ : &args),
+ (ptype == NULL
+ ? (boolean *) NULL
+ : &varargs)))
+ return false;
+ if (**pp != '_')
+ {
+ /* cplus_demangle will accept a function without a return
+ type, but I don't know when that will happen, or what
+ to do if it does. */
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_function_type (minfo->dhandle, *ptype, args,
+ varargs);
+
+ }
+ break;
+
+ case 'M':
+ case 'O':
+ {
+ boolean memberp, constp, volatilep;
+ debug_type *args;
+ boolean varargs;
+ unsigned int n;
+ const char *name;
+
+ memberp = **pp == 'M';
+ constp = false;
+ volatilep = false;
+ args = NULL;
+ varargs = false;
+
+ ++*pp;
+ if (! isdigit ((unsigned char) **pp))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ n = stab_demangle_count (pp);
+ if (strlen (*pp) < n)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ name = *pp;
+ *pp += n;
+
+ if (memberp)
+ {
+ if (**pp == 'C')
+ {
+ constp = true;
+ ++*pp;
+ }
+ else if (**pp == 'V')
+ {
+ volatilep = true;
+ ++*pp;
+ }
+ if (**pp != 'F')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+ if (! stab_demangle_args (minfo, pp,
+ (ptype == NULL
+ ? (debug_type **) NULL
+ : &args),
+ (ptype == NULL
+ ? (boolean *) NULL
+ : &varargs)))
+ return false;
+ }
+
+ if (**pp != '_')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+
+ if (ptype != NULL)
+ {
+ debug_type class_type;
+
+ class_type = stab_find_tagged_type (minfo->dhandle, minfo->info,
+ name, (int) n,
+ DEBUG_KIND_CLASS);
+ if (class_type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (! memberp)
+ *ptype = debug_make_offset_type (minfo->dhandle, class_type,
+ *ptype);
+ else
+ {
+ /* FIXME: We have no way to record constp or
+ volatilep. */
+ *ptype = debug_make_method_type (minfo->dhandle, *ptype,
+ class_type, args, varargs);
+ }
+ }
+ }
+ break;
+
+ case 'G':
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ break;
+
+ case 'C':
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_const_type (minfo->dhandle, *ptype);
+ break;
+
+ case 'Q':
+ {
+ const char *hold;
+
+ hold = *pp;
+ if (! stab_demangle_qualified (minfo, pp, ptype))
+ return false;
+ }
+ break;
+
+ default:
+ if (! stab_demangle_fund_type (minfo, pp, ptype))
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+/* Demangle a fundamental type. If the ptype argument is not NULL,
+ *ptype is set to the newly allocated type. */
+
+static boolean
+stab_demangle_fund_type (minfo, pp, ptype)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type *ptype;
+{
+ const char *orig;
+ boolean constp, volatilep, unsignedp, signedp;
+ boolean done;
+
+ orig = *pp;
+
+ constp = false;
+ volatilep = false;
+ unsignedp = false;
+ signedp = false;
+
+ done = false;
+ while (! done)
+ {
+ switch (**pp)
+ {
+ case 'C':
+ constp = true;
+ ++*pp;
+ break;
+
+ case 'U':
+ unsignedp = true;
+ ++*pp;
+ break;
+
+ case 'S':
+ signedp = true;
+ ++*pp;
+ break;
+
+ case 'V':
+ volatilep = true;
+ ++*pp;
+ break;
+
+ default:
+ done = true;
+ break;
+ }
+ }
+
+ switch (**pp)
+ {
+ case '\0':
+ case '_':
+ /* cplus_demangle permits this, but I don't know what it means. */
+ stab_bad_demangle (orig);
+ break;
+
+ case 'v': /* void */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "void");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_void_type (minfo->dhandle);
+ }
+ ++*pp;
+ break;
+
+ case 'x': /* long long */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "long long unsigned int"
+ : "long long int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 8, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'l': /* long */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "long unsigned int"
+ : "long int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'i': /* int */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "unsigned int"
+ : "int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 's': /* short */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "short unsigned int"
+ : "short int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 2, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'b': /* bool */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "bool");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_bool_type (minfo->dhandle, 4);
+ }
+ ++*pp;
+ break;
+
+ case 'c': /* char */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "unsigned char"
+ : (signedp
+ ? "signed char"
+ : "char")));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 1, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'w': /* wchar_t */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "__wchar_t");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 2, true);
+ }
+ ++*pp;
+ break;
+
+ case 'r': /* long double */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "long double");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_float_type (minfo->dhandle, 8);
+ }
+ ++*pp;
+ break;
+
+ case 'd': /* double */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "double");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_float_type (minfo->dhandle, 8);
+ }
+ ++*pp;
+ break;
+
+ case 'f': /* float */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "float");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_float_type (minfo->dhandle, 4);
+ }
+ ++*pp;
+ break;
+
+ case 'G':
+ ++*pp;
+ if (! isdigit ((unsigned char) **pp))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ /* Fall through. */
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ const char *hold;
+
+ if (! stab_demangle_class (minfo, pp, &hold))
+ return false;
+ if (ptype != NULL)
+ {
+ char *name;
+
+ name = savestring (hold, *pp - hold);
+ *ptype = debug_find_named_type (minfo->dhandle, name);
+ if (*ptype == DEBUG_TYPE_NULL)
+ {
+ /* FIXME: It is probably incorrect to assume that
+ undefined types are tagged types. */
+ *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
+ hold, *pp - hold,
+ DEBUG_KIND_ILLEGAL);
+ }
+ free (name);
+ }
+ }
+ break;
+
+ case 't':
+ if (! stab_demangle_template (minfo, pp))
+ return false;
+ if (ptype != NULL)
+ {
+ debug_type t;
+
+ /* FIXME: I really don't know how a template should be
+ represented in the current type system. Perhaps the
+ template should be demangled into a string, and the type
+ should be represented as a named type. However, I don't
+ know what the base type of the named type should be. */
+ t = debug_make_void_type (minfo->dhandle);
+ t = debug_make_pointer_type (minfo->dhandle, t);
+ t = debug_name_type (minfo->dhandle, "TEMPLATE", t);
+ *ptype = t;
+ }
+ break;
+
+ default:
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (ptype != NULL)
+ {
+ if (constp)
+ *ptype = debug_make_const_type (minfo->dhandle, *ptype);
+ if (volatilep)
+ *ptype = debug_make_volatile_type (minfo->dhandle, *ptype);
+ }
+
+ return true;
+}
+
+/* Remember a type string in a demangled string. */
+
+static boolean
+stab_demangle_remember_type (minfo, p, len)
+ struct stab_demangle_info *minfo;
+ const char *p;
+ int len;
+{
+ if (minfo->typestring_count >= minfo->typestring_alloc)
+ {
+ minfo->typestring_alloc += 10;
+ minfo->typestrings = ((struct stab_demangle_typestring *)
+ xrealloc (minfo->typestrings,
+ (minfo->typestring_alloc
+ * sizeof *minfo->typestrings)));
+ }
+
+ minfo->typestrings[minfo->typestring_count].typestring = p;
+ minfo->typestrings[minfo->typestring_count].len = (unsigned int) len;
+ ++minfo->typestring_count;
+
+ return true;
+}
diff --git a/readline/bind.c b/readline/bind.c
index 57383239098..f122bdf4860 100644
--- a/readline/bind.c
+++ b/readline/bind.c
@@ -108,7 +108,7 @@ Keymap rl_binding_keymap;
/* Forward declarations */
void rl_set_keymap_from_edit_mode ();
-static int _rl_read_init_file ();
+static int _rl_read_init_file (const char *filename, int include_level);
static int glean_key_from_name ();
static int substring_member_of_array ();
@@ -570,10 +570,7 @@ rl_named_function (string)
type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap),
or ISMACR (macro). */
Function *
-rl_function_of_keyseq (keyseq, map, type)
- char *keyseq;
- Keymap map;
- int *type;
+rl_function_of_keyseq (const char *keyseq, Keymap map, int *type)
{
register int i;
@@ -629,7 +626,7 @@ rl_function_of_keyseq (keyseq, map, type)
static char *last_readline_init_file = (char *)NULL;
/* The file we're currently reading key bindings from. */
-static char *current_readline_init_file;
+static const char *current_readline_init_file;
static int current_readline_init_include_level;
static int current_readline_init_lineno;
@@ -685,8 +682,8 @@ _rl_read_file (filename, sizep)
/* Re-read the current keybindings file. */
int
-rl_re_read_init_file (count, ignore)
- int count, ignore;
+rl_re_read_init_file (int count __attribute__((unused)),
+ int ignore __attribute__((unused)))
{
int r;
r = rl_read_init_file ((char *)NULL);
@@ -702,8 +699,7 @@ rl_re_read_init_file (count, ignore)
If the file existed and could be opened and read, 0 is returned,
otherwise errno is returned. */
int
-rl_read_init_file (filename)
- char *filename;
+rl_read_init_file (const char *filename)
{
/* Default the filename. */
if (filename == 0)
@@ -722,9 +718,7 @@ rl_read_init_file (filename)
}
static int
-_rl_read_init_file (filename, include_level)
- char *filename;
- int include_level;
+_rl_read_init_file (const char *filename, int include_level)
{
register int i;
char *buffer, *openname, *line, *end;
@@ -739,7 +733,7 @@ _rl_read_init_file (filename, include_level)
if (buffer == 0)
return (errno);
-
+
if (include_level == 0 && filename != last_readline_init_file)
{
FREE (last_readline_init_file);
@@ -797,7 +791,7 @@ _rl_init_file_error (msg)
/* Conditionals. */
/* Calling programs set this to have their argv[0]. */
-char *rl_readline_name = "other";
+const char *rl_readline_name = "other";
/* Stack of previous values of parsing_conditionalized_out. */
static unsigned char *if_stack = (unsigned char *)NULL;
@@ -881,7 +875,7 @@ parser_if (args)
/* Invert the current parser state if there is anything on the stack. */
static int
parser_else (args)
- char *args;
+char *args __attribute__((unused));
{
register int i;
@@ -906,7 +900,7 @@ parser_else (args)
_rl_parsing_conditionalized_out from the stack. */
static int
parser_endif (args)
- char *args;
+char *args __attribute__((unused));
{
if (if_stack_depth)
_rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
@@ -919,7 +913,8 @@ static int
parser_include (args)
char *args;
{
- char *old_init_file, *e;
+ const char *old_init_file;
+ char *e;
int old_line_number, old_include_level, r;
if (_rl_parsing_conditionalized_out)
@@ -940,10 +935,10 @@ parser_include (args)
return r;
}
-
+
/* Associate textual names with actual functions. */
static struct {
- char *name;
+ const char *name;
Function *function;
} parser_directives [] = {
{ "if", parser_if },
@@ -1233,7 +1228,7 @@ rl_parse_and_bind (string)
false. */
static struct {
- char *name;
+ const char *name;
int *value;
} boolean_varlist [] = {
#if defined (PAREN_MATCHING)
@@ -1375,7 +1370,7 @@ rl_variable_bind (name, value)
_rl_isearch_terminators[end] = '\0';
free (v);
}
-
+
/* For the time being, unknown variable names are simply ignored. */
return 0;
}
@@ -1384,7 +1379,7 @@ rl_variable_bind (name, value)
For example, `Space' returns ' '. */
typedef struct {
- char *name;
+ const char *name;
int value;
} assoc_list;
@@ -1418,7 +1413,7 @@ glean_key_from_name (name)
/* Auxiliary functions to manage keymaps. */
static struct {
- char *name;
+ const char *name;
Keymap map;
} keymap_names[] = {
{ "emacs", emacs_standard_keymap },
@@ -1446,7 +1441,7 @@ rl_get_keymap_by_name (name)
return ((Keymap) NULL);
}
-char *
+const char *
rl_get_keymap_name (map)
Keymap map;
{
@@ -1456,7 +1451,7 @@ rl_get_keymap_name (map)
return (keymap_names[i].name);
return ((char *)NULL);
}
-
+
void
rl_set_keymap (map)
Keymap map;
@@ -1482,7 +1477,7 @@ rl_set_keymap_from_edit_mode ()
#endif /* VI_MODE */
}
-char *
+const char *
rl_get_keymap_name_from_edit_mode ()
{
if (rl_editing_mode == emacs_mode)
@@ -1675,7 +1670,7 @@ rl_invoking_keyseqs_in_map (function, map)
keyname[0] = (char) key;
keyname[1] = '\0';
}
-
+
strcat (keyname, seqs[i]);
free (seqs[i]);
@@ -1780,8 +1775,8 @@ rl_function_dumper (print_readably)
rl_outstream. If an explicit argument is given, then print
the output in such a way that it can be read back in. */
int
-rl_dump_functions (count, key)
- int count, key;
+rl_dump_functions (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
@@ -1865,8 +1860,8 @@ rl_macro_dumper (print_readably)
}
int
-rl_dump_macros (count, key)
- int count, key;
+rl_dump_macros (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
@@ -1880,7 +1875,7 @@ rl_variable_dumper (print_readably)
int print_readably;
{
int i;
- char *kname;
+ const char *kname;
for (i = 0; boolean_varlist[i].name; i++)
{
@@ -1955,8 +1950,8 @@ rl_variable_dumper (print_readably)
rl_outstream. If an explicit argument is given, then print
the output in such a way that it can be read back in. */
int
-rl_dump_variables (count, key)
- int count, key;
+rl_dump_variables (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
diff --git a/readline/callback.c b/readline/callback.c
index 6915be483a4..200f3cc37f9 100644
--- a/readline/callback.c
+++ b/readline/callback.c
@@ -29,6 +29,7 @@
#if defined (READLINE_CALLBACKS)
+#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
diff --git a/readline/complete.c b/readline/complete.c
index ade317ff578..8810ca06d5f 100644
--- a/readline/complete.c
+++ b/readline/complete.c
@@ -95,7 +95,7 @@ extern int rl_display_fixed;
VFunction *rl_completion_display_matches_hook = (VFunction *)NULL;
/* Forward declarations for functions defined and used in this file. */
-char *filename_completion_function ();
+char *filename_completion_function (const char *text, int state);
char **completion_matches ();
#if defined (VISIBLE_STATS)
@@ -186,15 +186,15 @@ int rl_completion_query_items = 100;
/* The basic list of characters that signal a break between words for the
completer routine. The contents of this variable is what breaks words
in the shell, i.e. " \t\n\"\\'`@$><=" */
-char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
+const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
/* List of basic quoting characters. */
-char *rl_basic_quote_characters = "\"'";
+const char *rl_basic_quote_characters = "\"'";
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
-char *rl_completer_word_break_characters = (char *)NULL;
+const char *rl_completer_word_break_characters = (char *)NULL;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
@@ -241,7 +241,7 @@ Function *rl_ignore_some_completions_function = (Function *)NULL;
and a pointer to the quoting character to be used, which the function can
reset if desired. */
CPFunction *rl_filename_quoting_function = rl_quote_filename;
-
+
/* Function to call to remove quoting characters from a filename. Called
before completion is attempted, so the embedded quotes do not interfere
with matching names in the file system. Readline doesn't do anything
@@ -291,14 +291,14 @@ rl_complete (ignore, invoking_key)
/* List the possible completions. See description of rl_complete (). */
int
rl_possible_completions (ignore, invoking_key)
- int ignore, invoking_key;
+ int ignore __attribute__((unused)), invoking_key __attribute__((unused));
{
return (rl_complete_internal ('?'));
}
int
rl_insert_completions (ignore, invoking_key)
- int ignore, invoking_key;
+ int ignore __attribute__((unused)), invoking_key __attribute__((unused));
{
return (rl_complete_internal ('*'));
}
@@ -513,7 +513,7 @@ print_filename (to_print, full_pathname)
static char *
rl_quote_filename (s, rtype, qcp)
char *s;
- int rtype;
+ int rtype __attribute__((unused));
char *qcp;
{
char *r;
@@ -1010,7 +1010,7 @@ display_matches (matches)
(*rl_completion_display_matches_hook) (matches, len, max);
return;
}
-
+
/* If there are many items, then ask the user if she really wants to
see them all. */
if (len >= rl_completion_query_items)
@@ -1356,9 +1356,7 @@ rl_complete_internal (what_to_do)
when there are no more matches.
*/
char **
-completion_matches (text, entry_function)
- char *text;
- CPFunction *entry_function;
+completion_matches (const char *text, CPFunction *entry_function)
{
/* Number of slots in match_list. */
int match_list_size;
@@ -1403,9 +1401,7 @@ completion_matches (text, entry_function)
TEXT contains a partial username preceded by a random
character (usually `~'). */
char *
-username_completion_function (text, state)
- char *text;
- int state;
+username_completion_function (const char *text, int state)
{
#if defined (__GO32__) || defined (__WIN__) || defined (__OPENNT)
return (char *)NULL;
@@ -1460,9 +1456,7 @@ username_completion_function (text, state)
because of all the pathnames that must be followed when looking up the
completion for a command. */
char *
-filename_completion_function (text, state)
- char *text;
- int state;
+filename_completion_function (const char *text, int state)
{
static DIR *directory = (DIR *)NULL;
static char *filename = (char *)NULL;
@@ -1639,8 +1633,7 @@ filename_completion_function (text, state)
hit the end of the match list, we restore the original unmatched text,
ring the bell, and reset the counter to zero. */
int
-rl_menu_complete (count, ignore)
- int count, ignore;
+rl_menu_complete (int count, int ignore __attribute__((unused)))
{
Function *our_func;
int matching_filenames, found_quote;
diff --git a/readline/display.c b/readline/display.c
index 25aba64ca67..df9e212ac0c 100644
--- a/readline/display.c
+++ b/readline/display.c
@@ -79,9 +79,9 @@ extern int _rl_output_character_function ();
#endif
extern int _rl_backspace ();
-extern char *term_clreol, *term_clrpag;
-extern char *term_im, *term_ic, *term_ei, *term_DC;
-extern char *term_up, *term_dc, *term_cr, *term_IC;
+extern const char *term_clreol, *term_clrpag;
+extern const char *term_im, *term_ic, *term_ei, *term_DC;
+extern const char *term_up, *term_dc, *term_cr, *term_IC;
extern int screenheight, screenwidth, screenchars;
extern int terminal_can_insert, _rl_term_autowrap;
@@ -141,7 +141,7 @@ int _rl_suppress_redisplay = 0;
/* The stuff that gets printed out before the actual text of the line.
This is usually pointing to rl_prompt. */
-char *rl_display_prompt = (char *)NULL;
+const char *rl_display_prompt = (char *)NULL;
/* Pseudo-global variables declared here. */
/* The visible cursor position. If you print some text, adjust this. */
@@ -218,7 +218,7 @@ expand_prompt (pmt, lp, lip)
l = strlen (pmt);
r = ret = xmalloc (l + 1);
-
+
for (rl = ignoring = last = 0, p = pmt; p && *p; p++)
{
/* This code strips the invisible character string markers
@@ -315,7 +315,7 @@ rl_redisplay ()
register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum;
int newlines, lpos, temp;
- char *prompt_this_line;
+ const char *prompt_this_line;
if (!readline_echoing_p)
return;
@@ -623,7 +623,7 @@ rl_redisplay ()
_rl_move_vert (linenum);
_rl_move_cursor_relative (0, tt);
_rl_clear_to_eol
- ((linenum == _rl_vis_botlin) ? strlen (tt) : screenwidth);
+ ((linenum == _rl_vis_botlin) ? (int) strlen (tt) : screenwidth);
}
}
_rl_vis_botlin = inv_botlin;
@@ -831,7 +831,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
if (old[0] && new[0])
old[0] = new[0];
}
-
+
/* Find first difference. */
for (ofd = old, nfd = new;
(ofd - old < omax) && *ofd && (*ofd == *nfd);
@@ -1229,8 +1229,7 @@ rl_message (va_alist)
}
#else /* !USE_VARARGS */
int
-rl_message (format, arg1, arg2)
- char *format;
+rl_message (char *format, void *arg1, void *arg2)
{
sprintf (msg_buf, format, arg1, arg2);
rl_display_prompt = msg_buf;
@@ -1512,7 +1511,8 @@ cr ()
void
_rl_redisplay_after_sigwinch ()
{
- char *t, *oldp, *oldl, *oldlprefix;
+ char *t, *oldl, *oldlprefix;
+ const char *oldp;
/* Clear the current line and put the cursor at column 0. Make sure
the right thing happens if we have wrapped to a new screen line. */
diff --git a/readline/funmap.c b/readline/funmap.c
index f6b86286fe0..472119bd80a 100644
--- a/readline/funmap.c
+++ b/readline/funmap.c
@@ -180,16 +180,14 @@ static FUNMAP default_funmap[] = {
};
int
-rl_add_funmap_entry (name, function)
- char *name;
- Function *function;
+rl_add_funmap_entry (const char *name, Function *function)
{
if (funmap_entry + 2 >= funmap_size)
{
funmap_size += 64;
funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
}
-
+
funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
funmap[funmap_entry]->name = name;
funmap[funmap_entry]->function = function;
@@ -236,7 +234,7 @@ rl_funmap_names ()
result = (char **)xrealloc (result, result_size * sizeof (char *));
}
- result[result_index] = funmap[result_index]->name;
+ result[result_index] = (char*) funmap[result_index]->name;
result[result_index + 1] = (char *)NULL;
}
@@ -245,10 +243,10 @@ rl_funmap_names ()
}
/* Things that mean `Control'. */
-char *possible_control_prefixes[] = {
+const char *possible_control_prefixes[] = {
"Control-", "C-", "CTRL-", (char *)NULL
};
-char *possible_meta_prefixes[] = {
+const char *possible_meta_prefixes[] = {
"Meta", "M-", (char *)NULL
};
diff --git a/readline/histexpand.c b/readline/histexpand.c
index 30c6131801d..f78838ef2ba 100644
--- a/readline/histexpand.c
+++ b/readline/histexpand.c
@@ -87,7 +87,7 @@ char history_comment_char = '\0';
/* The list of characters which inhibit the expansion of text if found
immediately following history_expansion_char. */
-char *history_no_expand_chars = " \t\n\r=";
+const char *history_no_expand_chars = " \t\n\r=";
/* If set to a non-zero value, single quotes inhibit history expansion.
The default is 0. */
@@ -249,7 +249,7 @@ get_history_event (string, caller_index, delimiting_quote)
{
entry = current_history ();
history_offset = history_length;
-
+
/* If this was a substring search, then remember the
string that we matched for word substitution. */
if (substring_okay)
@@ -342,7 +342,8 @@ hist_error(s, start, current, errtype)
char *s;
int start, current, errtype;
{
- char *temp, *emsg;
+ char *temp;
+ const char *emsg;
int ll, elen;
ll = current - start;
@@ -514,7 +515,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
quoted_search_delimiter = string[i - 1];
event = get_history_event (string, &i, quoted_search_delimiter);
}
-
+
if (event == 0)
{
*ret_string = hist_error (string, start, i, EVENT_NOT_FOUND);
@@ -825,7 +826,7 @@ history_expand (hstring, output)
*output = savestring (hstring);
return (0);
}
-
+
/* Prepare the buffer for printing error messages. */
result = xmalloc (result_len = 256);
result[0] = '\0';
@@ -904,7 +905,7 @@ history_expand (hstring, output)
i++;
}
}
-
+
if (string[i] != history_expansion_char)
{
free (result);
@@ -1239,7 +1240,7 @@ history_tokenize_internal (string, wind, indp)
return (result);
start = i;
-
+
if (member (string[i], "()\n"))
{
i++;
diff --git a/readline/histfile.c b/readline/histfile.c
index 3325b7fc1f7..1da45b00b58 100644
--- a/readline/histfile.c
+++ b/readline/histfile.c
@@ -84,14 +84,15 @@ static char *
history_filename (filename)
char *filename;
{
- char *return_val, *home;
+ char *return_val;
+ const char *home;
int home_len;
return_val = filename ? savestring (filename) : (char *)NULL;
if (return_val)
return (return_val);
-
+
home = get_env_value ("HOME");
if (home == 0)
@@ -130,11 +131,10 @@ read_history_range (filename, from, to)
char *filename;
int from, to;
{
- register int line_start, line_end;
char *input, *buffer;
int file, current_line;
struct stat finfo;
- size_t file_size;
+ size_t line_start, line_end, file_size;
buffer = (char *)NULL;
input = history_filename (filename);
diff --git a/readline/history.c b/readline/history.c
index d56ffacc6a0..804ffddcd89 100644
--- a/readline/history.c
+++ b/readline/history.c
@@ -161,7 +161,7 @@ history_set_pos (pos)
history_offset = pos;
return (1);
}
-
+
/* Return the current history array. The caller has to be carefull, since this
is the actual array of data, and could be bashed or made corrupt easily.
The array is terminated with a NULL pointer. */
diff --git a/readline/history.h b/readline/history.h
index 8ecce726779..88bf471bb62 100644
--- a/readline/history.h
+++ b/readline/history.h
@@ -116,7 +116,7 @@ extern HIST_ENTRY **history_list __P((void));
/* Returns the number which says what history element we are now
looking at. */
extern int where_history __P((void));
-
+
/* Return the history entry at the current position, as determined by
history_offset. If there is no entry there, return a NULL pointer. */
HIST_ENTRY *current_history __P((void));
@@ -232,8 +232,8 @@ extern int max_input_history;
extern char history_expansion_char;
extern char history_subst_char;
extern char history_comment_char;
-extern char *history_no_expand_chars;
-extern char *history_search_delimiter_chars;
+extern const char *history_no_expand_chars;
+extern const char *history_search_delimiter_chars;
extern int history_quotes_inhibit_expansion;
/* If set, this function is called to decide whether or not a particular
diff --git a/readline/histsearch.c b/readline/histsearch.c
index 7e98e950acb..eb17e9332e8 100644
--- a/readline/histsearch.c
+++ b/readline/histsearch.c
@@ -52,7 +52,7 @@ extern int history_offset;
/* The list of alternate characters that can delimit a history search
string. */
-char *history_search_delimiter_chars = (char *)NULL;
+const char *history_search_delimiter_chars = (char *)NULL;
/* Search the history for STRING, starting at history_offset.
If DIRECTION < 0, then the search is through previous entries, else
diff --git a/readline/input.c b/readline/input.c
index e23af552494..ea1342969b0 100644
--- a/readline/input.c
+++ b/readline/input.c
@@ -311,7 +311,7 @@ _rl_input_available ()
void
_rl_insert_typein (c)
int c;
-{
+{
int key, t, i;
char *string;
diff --git a/readline/isearch.c b/readline/isearch.c
index ae8dce520f0..a4a294b6b20 100644
--- a/readline/isearch.c
+++ b/readline/isearch.c
@@ -97,7 +97,8 @@ rl_forward_search_history (sign, key)
static void
rl_display_search (search_string, reverse_p, where)
char *search_string;
- int reverse_p, where;
+ int reverse_p;
+ int where __attribute__((unused));
{
char *message;
int msglen, searchlen;
@@ -144,8 +145,7 @@ rl_display_search (search_string, reverse_p, where)
DIRECTION is which direction to search; >= 0 means forward, < 0 means
backwards. */
static int
-rl_search_history (direction, invoking_key)
- int direction, invoking_key;
+rl_search_history (int direction, int invoking_key __attribute__((unused)))
{
/* The string that the user types in to search for. */
char *search_string;
diff --git a/readline/kill.c b/readline/kill.c
index 0b4714fafa8..78387e138c2 100644
--- a/readline/kill.c
+++ b/readline/kill.c
@@ -82,8 +82,7 @@ static int rl_kill_ring_length;
/* How to say that you only want to save a certain amount
of kill material. */
int
-rl_set_retained_kills (num)
- int num;
+rl_set_retained_kills (int num __attribute__((unused)))
{
return 0;
}
@@ -285,8 +284,8 @@ rl_backward_kill_line (direction, ignore)
/* Kill the whole line, no matter where point is. */
int
-rl_kill_full_line (count, ignore)
- int count, ignore;
+rl_kill_full_line (int count __attribute__((unused)),
+ int ignore __attribute__((unused)))
{
rl_begin_undo_group ();
rl_point = 0;
@@ -302,8 +301,7 @@ rl_kill_full_line (count, ignore)
/* This does what C-w does in Unix. We can't prevent people from
using behaviour that they expect. */
int
-rl_unix_word_rubout (count, key)
- int count, key;
+rl_unix_word_rubout (int count, int key __attribute__((unused)))
{
int orig_point;
@@ -336,8 +334,8 @@ rl_unix_word_rubout (count, key)
into the line at all, and if you aren't, then you know what you are
doing. */
int
-rl_unix_line_discard (count, key)
- int count, key;
+rl_unix_line_discard (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (rl_point == 0)
ding ();
@@ -374,16 +372,16 @@ region_kill_internal (delete)
/* Copy the text in the region to the kill ring. */
int
-rl_copy_region_to_kill (count, ignore)
- int count, ignore;
+rl_copy_region_to_kill (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
return (region_kill_internal (0));
}
/* Kill the text between the point and mark. */
int
-rl_kill_region (count, ignore)
- int count, ignore;
+rl_kill_region (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
int r;
@@ -442,11 +440,11 @@ rl_copy_backward_word (count, key)
return (_rl_copy_word_as_kill (count, -1));
}
-
+
/* Yank back the last killed text. This ignores arguments. */
int
-rl_yank (count, ignore)
- int count, ignore;
+rl_yank (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (rl_kill_ring == 0)
{
@@ -464,8 +462,8 @@ rl_yank (count, ignore)
delete that text from the line, rotate the index down, and
yank back some other text. */
int
-rl_yank_pop (count, key)
- int count, key;
+rl_yank_pop (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
int l, n;
@@ -592,7 +590,7 @@ rl_yank_last_arg (count, key)
if (history_skip < 0)
history_skip = 0;
}
-
+
if (explicit_arg_p)
retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
else
diff --git a/readline/macro.c b/readline/macro.c
index f3c442b41c3..b4d7835c631 100644
--- a/readline/macro.c
+++ b/readline/macro.c
@@ -90,7 +90,7 @@ static int current_macro_index;
It is a linked list of string/index for each saved macro. */
struct saved_macro {
struct saved_macro *next;
- char *string;
+ const char *string;
int sindex;
};
@@ -100,11 +100,10 @@ static struct saved_macro *macro_list = (struct saved_macro *)NULL;
/* Set up to read subsequent input from STRING.
STRING is free ()'ed when we are done with it. */
void
-_rl_with_macro_input (string)
- char *string;
+_rl_with_macro_input (const char *string)
{
_rl_push_executing_macro ();
- _rl_executing_macro = string;
+ _rl_executing_macro = (char*) string;
executing_macro_index = 0;
}
@@ -155,7 +154,7 @@ _rl_pop_executing_macro ()
if (macro_list)
{
macro = macro_list;
- _rl_executing_macro = macro_list->string;
+ _rl_executing_macro = (char*) macro_list->string;
executing_macro_index = macro_list->sindex;
macro_list = macro_list->next;
free (macro);
@@ -206,8 +205,8 @@ _rl_kill_kbd_macro ()
definition to the end of the existing macro, and start by
re-executing the existing macro. */
int
-rl_start_kbd_macro (ignore1, ignore2)
- int ignore1, ignore2;
+rl_start_kbd_macro (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (_rl_defining_kbd_macro)
{
@@ -231,8 +230,7 @@ rl_start_kbd_macro (ignore1, ignore2)
A numeric argument says to execute the macro right now,
that many times, counting the definition as the first time. */
int
-rl_end_kbd_macro (count, ignore)
- int count, ignore;
+rl_end_kbd_macro (int count, int ignore __attribute__((unused)))
{
if (_rl_defining_kbd_macro == 0)
{
@@ -251,8 +249,7 @@ rl_end_kbd_macro (count, ignore)
/* Execute the most recently defined keyboard macro.
COUNT says how many times to execute it. */
int
-rl_call_last_kbd_macro (count, ignore)
- int count, ignore;
+rl_call_last_kbd_macro (int count, int key __attribute__((unused)))
{
if (current_macro == 0)
_rl_abort_internal ();
diff --git a/readline/readline.c b/readline/readline.c
index 622811fc11e..1da73250773 100644
--- a/readline/readline.c
+++ b/readline/readline.c
@@ -129,8 +129,8 @@ extern int _rl_suppress_redisplay;
extern char *rl_display_prompt;
/* Variables imported from complete.c. */
-extern char *rl_completer_word_break_characters;
-extern char *rl_basic_word_break_characters;
+extern const char *rl_completer_word_break_characters;
+extern const char *rl_basic_word_break_characters;
extern int rl_completion_query_items;
extern int rl_complete_with_tilde_expansion;
@@ -181,7 +181,7 @@ extern char *xmalloc (), *xrealloc ();
/* */
/* **************************************************************** */
-char *rl_library_version = RL_LIBRARY_VERSION;
+const char *rl_library_version = RL_LIBRARY_VERSION;
/* A pointer to the keymap that is currently in use.
By default, it is the standard emacs keymap. */
@@ -280,7 +280,7 @@ int _rl_mark_modified_lines = 0;
/* The style of `bell' notification preferred. This can be set to NO_BELL,
AUDIBLE_BELL, or VISIBLE_BELL. */
int _rl_bell_preference = AUDIBLE_BELL;
-
+
/* String inserted into the line by rl_insert_comment (). */
char *_rl_comment_begin;
@@ -755,7 +755,7 @@ readline_initialize_everything ()
/* Decide whether we should automatically go into eight-bit mode. */
_rl_init_eightbit ();
-
+
/* Read in the init file. */
rl_read_init_file ((char *)NULL);
@@ -914,7 +914,7 @@ rl_digit_loop ()
/* Add the current digit to the argument in progress. */
int
rl_digit_argument (ignore, key)
- int ignore, key;
+ int ignore __attribute__((unused)), key;
{
rl_pending_input = key;
return (rl_digit_loop ());
@@ -944,7 +944,7 @@ _rl_init_argument ()
dispatch on it. If the key is the abort character then abort. */
int
rl_universal_argument (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
rl_numeric_arg *= 4;
return (rl_digit_loop ());
@@ -960,8 +960,7 @@ rl_universal_argument (count, key)
way that you should do insertion. rl_insert () calls this
function. */
int
-rl_insert_text (string)
- char *string;
+rl_insert_text (const char *string)
{
register int i, l = strlen (string);
@@ -1147,7 +1146,7 @@ rl_backward (count, key)
/* Move to the beginning of the line. */
int
rl_beg_of_line (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
rl_point = 0;
return 0;
@@ -1156,7 +1155,7 @@ rl_beg_of_line (count, key)
/* Move to the end of the line. */
int
rl_end_of_line (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
rl_point = rl_end;
return 0;
@@ -1253,7 +1252,7 @@ rl_backward_word (count, key)
/* Clear the current line. Numeric argument to C-l does this. */
int
rl_refresh_line (ignore1, ignore2)
- int ignore1, ignore2;
+ int ignore1 __attribute__((unused)), ignore2 __attribute__((unused));
{
int curr_line, nleft;
@@ -1313,7 +1312,7 @@ rl_clear_screen (count, key)
int
rl_arrow_keys (count, c)
- int count, c;
+ int count, c __attribute__((unused));
{
int ch;
@@ -1417,7 +1416,7 @@ rl_insert (count, c)
/* Insert the next typed character verbatim. */
int
rl_quoted_insert (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
int c;
@@ -1428,7 +1427,7 @@ rl_quoted_insert (count, key)
/* Insert a tab character. */
int
rl_tab_insert (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (rl_insert (count, '\t'));
}
@@ -1438,7 +1437,7 @@ rl_tab_insert (count, key)
meaning in the future. */
int
rl_newline (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
rl_done = 1;
@@ -1466,7 +1465,7 @@ rl_newline (count, key)
is special cased. */
int
rl_do_lowercase_version (ignore1, ignore2)
- int ignore1, ignore2;
+ int ignore1 __attribute__((unused)), ignore2 __attribute__((unused));
{
return 0;
}
@@ -1548,12 +1547,12 @@ rl_rubout_or_delete (count, key)
return (rl_rubout (count, key));
else
return (rl_delete (count, key));
-}
+}
/* Delete all spaces and tabs around point. */
int
rl_delete_horizontal_space (count, ignore)
- int count, ignore;
+ int count __attribute__((unused)), ignore __attribute__((unused));
{
int start = rl_point;
@@ -1594,7 +1593,7 @@ rl_delete_or_show_completions (count, key)
A K*rn shell style function. */
int
rl_insert_comment (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
rl_beg_of_line (1, key);
rl_insert_text (_rl_comment_begin ? _rl_comment_begin
@@ -1620,7 +1619,7 @@ static int rl_change_case ();
/* Uppercase the word at point. */
int
rl_upcase_word (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (rl_change_case (count, UpCase));
}
@@ -1628,7 +1627,7 @@ rl_upcase_word (count, key)
/* Lowercase the word at point. */
int
rl_downcase_word (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (rl_change_case (count, DownCase));
}
@@ -1636,7 +1635,7 @@ rl_downcase_word (count, key)
/* Upcase the first letter, downcase the rest. */
int
rl_capitalize_word (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (rl_change_case (count, CapCase));
}
@@ -1760,7 +1759,7 @@ rl_transpose_words (count, key)
then transpose the characters before point. */
int
rl_transpose_chars (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
char dummy[2];
@@ -1853,14 +1852,14 @@ _rl_char_search (count, fdir, bdir)
int
rl_char_search (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (_rl_char_search (count, FFIND, BFIND));
}
int
rl_backward_char_search (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (_rl_char_search (count, BFIND, FFIND));
}
@@ -1965,7 +1964,7 @@ maybe_save_line ()
/* Meta-< goes to the start of the history. */
int
rl_beginning_of_history (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
return (rl_get_previous_history (1 + where_history (), key));
}
@@ -1973,7 +1972,7 @@ rl_beginning_of_history (count, key)
/* Meta-> goes to the end of the history. (The current line). */
int
rl_end_of_history (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
maybe_replace_line ();
using_history ();
@@ -2105,7 +2104,7 @@ _rl_set_mark_at_pos (position)
/* A bindable command to set the mark. */
int
rl_set_mark (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
}
@@ -2113,7 +2112,7 @@ rl_set_mark (count, key)
/* Exchange the position of mark and point. */
int
rl_exchange_point_and_mark (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
if (rl_mark > rl_end)
rl_mark = -1;
@@ -2137,7 +2136,7 @@ rl_exchange_point_and_mark (count, key)
/* How to toggle back and forth between editing modes. */
int
rl_vi_editing_mode (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
#if defined (VI_MODE)
rl_editing_mode = vi_mode;
@@ -2148,7 +2147,7 @@ rl_vi_editing_mode (count, key)
int
rl_emacs_editing_mode (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
rl_editing_mode = emacs_mode;
_rl_keymap = emacs_standard_keymap;
diff --git a/readline/readline.h b/readline/readline.h
index dba1a0fdde9..7804d31efb1 100644
--- a/readline/readline.h
+++ b/readline/readline.h
@@ -60,7 +60,7 @@ extern UNDO_LIST *rl_undo_list;
/* The data structure for mapping textual names to code addresses. */
typedef struct _funmap {
- char *name;
+ const char *name;
Function *function;
} FUNMAP;
@@ -286,17 +286,17 @@ extern int rl_translate_keyseq __P((char *, char *, int *));
extern char *rl_untranslate_keyseq __P((int));
extern Function *rl_named_function __P((char *));
-extern Function *rl_function_of_keyseq __P((char *, Keymap, int *));
+extern Function *rl_function_of_keyseq __P((const char *, Keymap, int *));
extern void rl_list_funmap_names __P((void));
extern char **rl_invoking_keyseqs_in_map __P((Function *, Keymap));
extern char **rl_invoking_keyseqs __P((Function *));
-
+
extern void rl_function_dumper __P((int));
extern void rl_macro_dumper __P((int));
extern void rl_variable_dumper __P((int));
-extern int rl_read_init_file __P((char *));
+extern int rl_read_init_file __P((const char *));
extern int rl_parse_and_bind __P((char *));
/* Functions for manipulating keymaps. */
@@ -306,14 +306,14 @@ extern Keymap rl_make_keymap __P((void));
extern void rl_discard_keymap __P((Keymap));
extern Keymap rl_get_keymap_by_name __P((char *));
-extern char *rl_get_keymap_name __P((Keymap));
+extern const char *rl_get_keymap_name __P((Keymap));
extern void rl_set_keymap __P((Keymap));
extern Keymap rl_get_keymap __P((void));
extern void rl_set_keymap_from_edit_mode __P((void));
-extern char *rl_get_keymap_name_from_edit_mode __P((void));
+extern const char *rl_get_keymap_name_from_edit_mode __P((void));
/* Functions for manipulating the funmap, which maps command names to functions. */
-extern int rl_add_funmap_entry __P((char *, Function *));
+extern int rl_add_funmap_entry __P((const char *, Function *));
extern void rl_initialize_funmap __P((void));
extern char **rl_funmap_names __P((void));
@@ -351,7 +351,7 @@ extern void rl_save_prompt __P((void));
extern void rl_restore_prompt __P((void));
/* Modifying text. */
-extern int rl_insert_text __P((char *));
+extern int rl_insert_text __P((const char *));
extern int rl_delete_text __P((int, int));
extern int rl_kill_text __P((int, int));
extern char *rl_copy_text __P((int, int));
@@ -380,7 +380,7 @@ extern int rl_clear_signals __P((void));
extern void rl_cleanup_after_signal __P((void));
extern void rl_reset_after_signal __P((void));
extern void rl_free_line_state __P((void));
-
+
/* Undocumented. */
extern int rl_expand_prompt __P((char *));
@@ -392,9 +392,9 @@ extern int maybe_replace_line __P((void));
extern int rl_complete_internal __P((int));
extern void rl_display_match_list __P((char **, int, int));
-extern char **completion_matches __P((char *, CPFunction *));
-extern char *username_completion_function __P((char *, int));
-extern char *filename_completion_function __P((char *, int));
+extern char **completion_matches __P((const char *, CPFunction *));
+extern char *username_completion_function __P((const char *, int));
+extern char *filename_completion_function __P((const char *, int));
/* **************************************************************** */
/* */
@@ -403,11 +403,11 @@ extern char *filename_completion_function __P((char *, int));
/* **************************************************************** */
/* The version of this incarnation of the readline library. */
-extern char *rl_library_version;
+extern const char *rl_library_version;
/* The name of the calling program. You should initialize this to
whatever was in argv[0]. It is used when parsing conditionals. */
-extern char *rl_readline_name;
+extern const char *rl_readline_name;
/* The prompt readline uses. This is set from the argument to
readline (), and should not be assigned to directly. */
@@ -448,7 +448,7 @@ extern Function *rl_startup_hook;
readline_internal_setup () returns and readline_internal starts
reading input characters. */
extern Function *rl_pre_input_hook;
-
+
/* The address of a function to call periodically while Readline is
awaiting character input, or NULL, for no event handling. */
extern Function *rl_event_hook;
@@ -506,12 +506,12 @@ extern CPPFunction *rl_attempted_completion_function;
/* The basic list of characters that signal a break between words for the
completer routine. The initial contents of this variable is what
breaks words in the shell, i.e. "n\"\\'`@$>". */
-extern char *rl_basic_word_break_characters;
+extern const char *rl_basic_word_break_characters;
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
-extern char *rl_completer_word_break_characters;
+extern const char *rl_completer_word_break_characters;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
@@ -520,7 +520,7 @@ extern char *rl_completer_word_break_characters;
extern char *rl_completer_quote_characters;
/* List of quote characters which cause a word break. */
-extern char *rl_basic_quote_characters;
+extern const char *rl_basic_quote_characters;
/* List of characters that need to be quoted in filenames by the completer. */
extern char *rl_filename_quote_characters;
@@ -599,7 +599,7 @@ extern int rl_ignore_completion_duplicates;
/* If this is non-zero, completion is (temporarily) inhibited, and the
completion character will be inserted as any other. */
extern int rl_inhibit_completion;
-
+
/* Definitions available for use by readline clients. */
#define RL_PROMPT_START_IGNORE '\001'
#define RL_PROMPT_END_IGNORE '\002'
diff --git a/readline/rlstdc.h b/readline/rlstdc.h
index d2c5f874d7a..f79cf89fe76 100644
--- a/readline/rlstdc.h
+++ b/readline/rlstdc.h
@@ -76,4 +76,8 @@
#endif /* !__STDC__ */
+#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+#define __attribute__(A)
+#endif
+
#endif /* !_RL_STDC_H_ */
diff --git a/readline/rltty.c b/readline/rltty.c
index b4d0cf127d5..f87c1c9747f 100644
--- a/readline/rltty.c
+++ b/readline/rltty.c
@@ -368,12 +368,15 @@ static TIOTYPE otio;
# define OUTPUT_BEING_FLUSHED(tp) 0
#endif
+#if defined (_AIX) || (defined (FLUSHO) && defined (_AIX41))
static void
rltty_warning (msg)
char *msg;
{
fprintf (stderr, "readline: warning: %s\n", msg);
}
+#endif
+
#if defined (_AIX)
void
@@ -604,8 +607,8 @@ rl_deprep_terminal ()
/* **************************************************************** */
int
-rl_restart_output (count, key)
- int count, key;
+rl_restart_output (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
int fildes = fileno (rl_outstream);
#if defined (TIOCSTART)
@@ -637,8 +640,8 @@ rl_restart_output (count, key)
}
int
-rl_stop_output (count, key)
- int count, key;
+rl_stop_output (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
int fildes = fileno (rl_instream);
diff --git a/readline/search.c b/readline/search.c
index f198e7409e5..0179d8da2f1 100644
--- a/readline/search.c
+++ b/readline/search.c
@@ -247,8 +247,7 @@ noninc_search (dir, pchar)
/* Search forward through the history list for a string. If the vi-mode
code calls this, KEY will be `?'. */
int
-rl_noninc_forward_search (count, key)
- int count, key;
+rl_noninc_forward_search (int count __attribute__((unused)), int key)
{
noninc_search (1, (key == '?') ? '?' : 0);
return 0;
@@ -257,8 +256,7 @@ rl_noninc_forward_search (count, key)
/* Reverse search the history list for a string. If the vi-mode code
calls this, KEY will be `/'. */
int
-rl_noninc_reverse_search (count, key)
- int count, key;
+rl_noninc_reverse_search (int count __attribute__((unused)), int key)
{
noninc_search (-1, (key == '/') ? '/' : 0);
return 0;
@@ -267,8 +265,8 @@ rl_noninc_reverse_search (count, key)
/* Search forward through the history list for the last string searched
for. If there is no saved search string, abort. */
int
-rl_noninc_forward_search_again (count, key)
- int count, key;
+rl_noninc_forward_search_again (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (!noninc_search_string)
{
@@ -282,8 +280,8 @@ rl_noninc_forward_search_again (count, key)
/* Reverse search in the history list for the last string searched
for. If there is no saved search string, abort. */
int
-rl_noninc_reverse_search_again (count, key)
- int count, key;
+rl_noninc_reverse_search_again (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (!noninc_search_string)
{
@@ -352,8 +350,7 @@ rl_history_search_internal (count, direction)
from the start of the line to rl_point. This is a non-incremental
search. */
int
-rl_history_search_forward (count, ignore)
- int count, ignore;
+rl_history_search_forward (int count, int ignore __attribute__((unused)))
{
if (count == 0)
return (0);
@@ -366,8 +363,7 @@ rl_history_search_forward (count, ignore)
from the start of the line to rl_point. This is a non-incremental
search. */
int
-rl_history_search_backward (count, ignore)
- int count, ignore;
+rl_history_search_backward (int count, int ignore __attribute__((unused)))
{
if (count == 0)
return (0);
diff --git a/readline/shell.c b/readline/shell.c
index 4d9e0064d3f..becd66e0f9a 100644
--- a/readline/shell.c
+++ b/readline/shell.c
@@ -26,6 +26,7 @@
# include <config.h>
#endif
+#include <stdio.h>
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
diff --git a/readline/terminal.c b/readline/terminal.c
index 6e94bdc4011..1d2fead7768 100644
--- a/readline/terminal.c
+++ b/readline/terminal.c
@@ -99,8 +99,8 @@ char PC, *BC, *UP;
#endif /* __linux__ */
/* Some strings to control terminal actions. These are output by tputs (). */
-char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
-char *term_pc;
+char *term_goto, *term_clreol, *term_clrpag, *term_backspace;
+char *term_cr, *term_pc;
/* Non-zero if we determine that the terminal can do character insertion. */
int terminal_can_insert = 0;
@@ -245,8 +245,8 @@ rl_resize_terminal ()
}
struct _tc_string {
- char *tc_var;
- char **tc_value;
+ const char *tc_var;
+ char **tc_value;
};
/* This should be kept sorted, just in case we decide to change the
@@ -291,7 +291,7 @@ get_term_capabilities (bp)
{
register int i;
- for (i = 0; i < NUM_TC_STRINGS; i++)
+ for (i = 0; i < (int) NUM_TC_STRINGS; i++)
*(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
tcap_initialized = 1;
}
@@ -304,7 +304,7 @@ _rl_init_terminal_io (terminal_name)
screenwidth = ScreenCols ();
screenheight = ScreenRows ();
screenchars = screenwidth * screenheight;
- term_cr = "\r";
+ term_cr = (char*) "\r";
term_im = term_ei = term_ic = term_IC = (char *)NULL;
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
@@ -322,7 +322,8 @@ _rl_init_terminal_io (terminal_name)
return;
#else /* !__GO32__ */
- char *term, *buffer;
+ const char *term;
+ char *buffer;
int tty;
Keymap xkeymap;
@@ -347,7 +348,7 @@ _rl_init_terminal_io (terminal_name)
screenwidth = 79;
screenheight = 24;
screenchars = 79 * 24;
- term_cr = "\r";
+ term_cr = (char*) "\r";
term_im = term_ei = term_ic = term_IC = (char *)NULL;
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
term_ku = term_kd = term_kl = term_kr = (char *)NULL;
@@ -367,7 +368,7 @@ _rl_init_terminal_io (terminal_name)
UP = term_up;
if (!term_cr)
- term_cr = "\r";
+ term_cr = (char*) "\r";
tty = rl_instream ? fileno (rl_instream) : 0;
@@ -427,7 +428,7 @@ rl_get_termcap (cap)
if (tcap_initialized == 0)
return ((char *)NULL);
- for (i = 0; i < NUM_TC_STRINGS; i++)
+ for (i = 0; i < (int) NUM_TC_STRINGS; i++)
{
if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
return *(tc_strings[i].tc_value);
diff --git a/readline/tilde.c b/readline/tilde.c
index 65a1e2f3902..05c9ed741ed 100644
--- a/readline/tilde.c
+++ b/readline/tilde.c
@@ -82,13 +82,13 @@ extern char *get_env_value ();
/* The default value of tilde_additional_prefixes. This is set to
whitespace preceding a tilde so that simple programs which do not
perform any word separation get desired behaviour. */
-static char *default_prefixes[] =
+static const char *default_prefixes[] =
{ " ~", "\t~", (char *)NULL };
/* The default value of tilde_additional_suffixes. This is set to
whitespace or newline so that simple programs which do not
perform any word separation get desired behaviour. */
-static char *default_suffixes[] =
+static const char *default_suffixes[] =
{ " ", "\n", (char *)NULL };
/* If non-null, this contains the address of a function that the application
@@ -106,12 +106,12 @@ CPFunction *tilde_expansion_failure_hook = (CPFunction *)NULL;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
-char **tilde_additional_prefixes = default_prefixes;
+const char ** tilde_additional_prefixes = default_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
-char **tilde_additional_suffixes = default_suffixes;
+const char **tilde_additional_suffixes = default_suffixes;
/* Find the start of a tilde expansion in STRING, and return the index of
the tilde which starts the expansion. Place the length of the text
@@ -122,7 +122,7 @@ tilde_find_prefix (string, len)
int *len;
{
register int i, j, string_len;
- register char **prefixes = tilde_additional_prefixes;
+ register const char **prefixes = tilde_additional_prefixes;
string_len = strlen (string);
*len = 0;
@@ -154,7 +154,7 @@ tilde_find_suffix (string)
char *string;
{
register int i, j, string_len;
- register char **suffixes;
+ register const char **suffixes;
suffixes = tilde_additional_suffixes;
string_len = strlen (string);
diff --git a/readline/tilde.h b/readline/tilde.h
index 634b95449aa..45eea1b66e5 100644
--- a/readline/tilde.h
+++ b/readline/tilde.h
@@ -48,12 +48,12 @@ extern CPFunction *tilde_expansion_failure_hook;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
-extern char **tilde_additional_prefixes;
+extern const char **tilde_additional_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
-extern char **tilde_additional_suffixes;
+extern const char **tilde_additional_suffixes;
/* Return a new string which is the result of tilde expanding STRING. */
extern char *tilde_expand ();
diff --git a/readline/undo.c b/readline/undo.c
index 68710b667ed..c8f4892b774 100644
--- a/readline/undo.c
+++ b/readline/undo.c
@@ -174,7 +174,7 @@ _rl_fix_last_undo_of_type (type, start, end)
for (rl = rl_undo_list; rl; rl = rl->next)
{
- if (rl->what == type)
+ if ((int) rl->what == type)
{
rl->start = start;
rl->end = end;
@@ -225,8 +225,8 @@ rl_modifying (start, end)
/* Revert the current line to its previous state. */
int
-rl_revert_line (count, key)
- int count, key;
+rl_revert_line (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
if (!rl_undo_list)
ding ();
@@ -240,8 +240,7 @@ rl_revert_line (count, key)
/* Do some undoing of things that were done. */
int
-rl_undo_command (count, key)
- int count, key;
+rl_undo_command (int count, int key __attribute__((unused)))
{
if (count < 0)
return 0; /* Nothing to do. */
diff --git a/readline/util.c b/readline/util.c
index 1dc3b664f1c..bcd8f3bc5b2 100644
--- a/readline/util.c
+++ b/readline/util.c
@@ -81,7 +81,7 @@ extern char *xmalloc (), *xrealloc ();
in words, or 1 if it is. */
int _rl_allow_pathname_alphabetic_chars = 0;
-static char *pathname_alphabetic_chars = "/-_=~.#$";
+static const char *pathname_alphabetic_chars = "/-_=~.#$";
int
alphabetic (c)
@@ -113,15 +113,15 @@ _rl_abort_internal ()
}
int
-rl_abort (count, key)
- int count, key;
+rl_abort (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
return (_rl_abort_internal ());
}
int
-rl_tty_status (count, key)
- int count, key;
+rl_tty_status (int count __attribute__((unused)),
+ int key __attribute__((unused)))
{
#if defined (TIOCSTAT)
ioctl (1, TIOCSTAT, (char *)0);
@@ -170,8 +170,8 @@ rl_extend_line_buffer (len)
/* A function for simple tilde expansion. */
int
-rl_tilde_expand (ignore, key)
- int ignore, key;
+rl_tilde_expand (int ignore __attribute__((unused)),
+ int key __attribute__((unused)))
{
register int start, end;
char *homedir, *temp;
diff --git a/readline/vi_mode.c b/readline/vi_mode.c
index 2a4f11d28a4..eb392b643ba 100644
--- a/readline/vi_mode.c
+++ b/readline/vi_mode.c
@@ -98,7 +98,7 @@ extern int rl_vi_check ();
static int _rl_vi_doing_insert;
/* Command keys which do movement for xxx_to commands. */
-static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
+static const char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
/* Keymap used for vi replace characters. Created dynamically since
rarely used. */
@@ -126,7 +126,7 @@ static int _rl_vi_last_key_before_insert;
static int vi_redoing;
/* Text modification commands. These are the `redoable' commands. */
-static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
+static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
/* Arrays for the saved marks. */
static int vi_mark_chars[27];
@@ -136,7 +136,11 @@ static int rl_digit_loop1 ();
void
_rl_vi_initialize_line ()
{
- register int i;
+#ifndef __QNXNTO__
+ register uint i;
+#else
+ register unsigned int i;
+#endif
for (i = 0; i < (int) sizeof (vi_mark_chars) / sizeof (int); i++)
vi_mark_chars[i] = -1;
@@ -183,7 +187,7 @@ _rl_vi_stuff_insert (count)
puts you back into insert mode. */
int
rl_vi_redo (count, c)
- int count, c;
+ int count, c __attribute__((unused));
{
if (!rl_explicit_arg)
{
@@ -215,11 +219,11 @@ rl_vi_undo (count, key)
{
return (rl_undo_command (count, key));
}
-
+
/* Yank the nth arg from the previous line into this line at point. */
int
-rl_vi_yank_arg (count, key)
- int count, key;
+rl_vi_yank_arg (count, key)
+ int count, key __attribute__((unused));
{
/* Readline thinks that the first word on a line is the 0th, while vi
thinks the first word on a line is the 1st. Compensate. */
@@ -300,7 +304,7 @@ rl_vi_search (count, key)
/* Completion, from vi's point of view. */
int
rl_vi_complete (ignore, key)
- int ignore, key;
+ int ignore __attribute__((unused)), key;
{
if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
{
@@ -329,7 +333,7 @@ rl_vi_complete (ignore, key)
/* Tilde expansion for vi mode. */
int
rl_vi_tilde_expand (ignore, key)
- int ignore, key;
+ int ignore __attribute__((unused)), key;
{
rl_tilde_expand (0, key);
_rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */
@@ -401,7 +405,7 @@ rl_vi_end_word (count, key)
/* Move forward a word the way that 'W' does. */
int
rl_vi_fWord (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point < (rl_end - 1))
{
@@ -418,7 +422,7 @@ rl_vi_fWord (count, ignore)
int
rl_vi_bWord (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point > 0)
{
@@ -442,7 +446,7 @@ rl_vi_bWord (count, ignore)
int
rl_vi_eWord (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point < (rl_end - 1))
{
@@ -472,7 +476,7 @@ rl_vi_eWord (count, ignore)
int
rl_vi_fword (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point < (rl_end - 1))
{
@@ -498,7 +502,7 @@ rl_vi_fword (count, ignore)
int
rl_vi_bword (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point > 0)
{
@@ -537,7 +541,7 @@ rl_vi_bword (count, ignore)
int
rl_vi_eword (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
while (count-- && rl_point < rl_end - 1)
{
@@ -562,7 +566,7 @@ rl_vi_eword (count, ignore)
int
rl_vi_insert_beg (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
rl_beg_of_line (1, key);
rl_vi_insertion_mode (1, key);
@@ -571,7 +575,7 @@ rl_vi_insert_beg (count, key)
int
rl_vi_append_mode (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
if (rl_point < rl_end)
rl_point++;
@@ -581,7 +585,7 @@ rl_vi_append_mode (count, key)
int
rl_vi_append_eol (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
rl_end_of_line (1, key);
rl_vi_append_mode (1, key);
@@ -591,7 +595,7 @@ rl_vi_append_eol (count, key)
/* What to do in the case of C-d. */
int
rl_vi_eof_maybe (count, c)
- int count, c;
+ int count __attribute__((unused)), c __attribute__((unused));
{
return (rl_newline (1, '\n'));
}
@@ -602,7 +606,7 @@ rl_vi_eof_maybe (count, c)
switching keymaps. */
int
rl_vi_insertion_mode (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
_rl_keymap = vi_insertion_keymap;
_rl_vi_last_key_before_insert = key;
@@ -633,7 +637,7 @@ _rl_vi_save_insert (up)
strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
vi_insert_buffer[len-1] = '\0';
}
-
+
void
_rl_vi_done_inserting ()
{
@@ -664,7 +668,7 @@ _rl_vi_done_inserting ()
int
rl_vi_movement_mode (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
if (rl_point > 0)
rl_backward (1, key);
@@ -686,7 +690,7 @@ rl_vi_arg_digit (count, c)
int
rl_vi_change_case (count, ignore)
- int count, ignore;
+ int count, ignore __attribute__((unused));
{
char c = 0;
@@ -724,7 +728,7 @@ rl_vi_change_case (count, ignore)
int
rl_vi_put (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
rl_point++;
@@ -881,7 +885,7 @@ rl_digit_loop1 ()
int
rl_vi_delete_to (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
int c;
@@ -961,7 +965,7 @@ rl_vi_change_to (count, key)
int
rl_vi_yank_to (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
int c, save = rl_point;
@@ -1006,7 +1010,7 @@ rl_vi_delete (count, key)
end = rl_end;
rl_kill_text (rl_point, end);
-
+
if (rl_point > 0 && rl_point == rl_end)
rl_backward (1, key);
return (0);
@@ -1014,7 +1018,7 @@ rl_vi_delete (count, key)
int
rl_vi_back_to_indent (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
rl_beg_of_line (1, key);
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
@@ -1024,7 +1028,7 @@ rl_vi_back_to_indent (count, key)
int
rl_vi_first_print (count, key)
- int count, key;
+ int count __attribute__((unused)), key;
{
return (rl_vi_back_to_indent (1, key));
}
@@ -1071,7 +1075,7 @@ rl_vi_char_search (count, key)
/* Match brackets */
int
rl_vi_match (ignore, key)
- int ignore, key;
+ int ignore __attribute__((unused)), key;
{
int count = 1, brack, pos;
@@ -1152,7 +1156,7 @@ rl_vi_bracktype (c)
int
rl_vi_change_char (count, key)
- int count, key;
+ int count, key __attribute__((unused));
{
int c;
@@ -1278,7 +1282,7 @@ rl_vi_overstrike_delete (count, key)
int
rl_vi_replace (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
int i;
@@ -1339,7 +1343,7 @@ rl_vi_possible_completions()
/* Functions to save and restore marks. */
int
rl_vi_set_mark (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
int ch;
@@ -1356,7 +1360,7 @@ rl_vi_set_mark (count, key)
int
rl_vi_goto_mark (count, key)
- int count, key;
+ int count __attribute__((unused)), key __attribute__((unused));
{
int ch;
diff --git a/regex/cclass.h b/regex/cclass.h
index 7d9a7ccc7c2..e0f752f38b8 100644
--- a/regex/cclass.h
+++ b/regex/cclass.h
@@ -15,7 +15,7 @@
#define CCLASS_LAST 12
extern struct cclass {
- char *name;
- char *chars;
- char *multis;
+ const char *name;
+ const char *chars;
+ const char *multis;
} cclasses[];
diff --git a/regex/cname.h b/regex/cname.h
index 2b6a1a8496f..06865f3e102 100644
--- a/regex/cname.h
+++ b/regex/cname.h
@@ -1,7 +1,7 @@
/* character-name table */
static struct cname {
- char *name;
- char code;
+ const char *name;
+ const char code;
} cnames[] = {
{"NUL", '\0'},
{"SOH", '\001'},
diff --git a/regex/debug.c b/regex/debug.c
index 8c6fd14a209..35279941d48 100644
--- a/regex/debug.c
+++ b/regex/debug.c
@@ -1,4 +1,4 @@
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <m_string.h>
#include <sys/types.h>
diff --git a/regex/main.c b/regex/main.c
index 4b607f401ca..7844a4d8384 100644
--- a/regex/main.c
+++ b/regex/main.c
@@ -1,4 +1,4 @@
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#include <sys/types.h>
#include <regex.h>
@@ -133,9 +133,9 @@ FILE *in;
int i;
char erbuf[100];
size_t ne;
- char *badpat = "invalid regular expression";
+ const char *badpat = "invalid regular expression";
# define SHORT 10
- char *bpname = "REG_BADPAT";
+ const char *bpname = "REG_BADPAT";
regex_t re;
while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
@@ -152,7 +152,7 @@ FILE *in;
}
for (i = 0; i < nf; i++)
if (strcmp(f[i], "\"\"") == 0)
- f[i] = "";
+ f[i] = (char*) "";
if (nf <= 3)
f[3] = NULL;
if (nf <= 4)
@@ -217,7 +217,7 @@ int opts; /* may not match f1 */
char erbuf[100];
int err;
int len;
- char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
+ const char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
register int i;
char *grump;
char f0copy[1000];
@@ -291,7 +291,7 @@ int opts; /* may not match f1 */
nshould = split(f4, should+1, NSHOULD-1, ",");
if (nshould == 0) {
nshould = 1;
- should[1] = "";
+ should[1] = (char*) "";
}
for (i = 1; i < NSUBS; i++) {
grump = check(f2, subs[i], should[i]);
@@ -317,7 +317,7 @@ char *s;
{
register char *p;
register int o = (type == 'c') ? copts : eopts;
- register char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
+ register const char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
for (p = s; *p != '\0'; p++)
if (strchr(legal, *p) != NULL)
@@ -417,7 +417,7 @@ char *should;
should = NULL;
if (should != NULL && should[0] == '@') {
at = should + 1;
- should = "";
+ should = (char*) "";
}
/* check rm_so and rm_eo for consistency */
@@ -434,7 +434,7 @@ char *should;
if (sub.rm_so == -1 && should == NULL)
return(NULL);
if (sub.rm_so == -1)
- return("did not match");
+ return((char*) "did not match");
/* check for in range */
if ((int) sub.rm_eo > (int) strlen(str)) {
diff --git a/regex/regcomp.c b/regex/regcomp.c
index 048f45ca71c..6f8221a706d 100644
--- a/regex/regcomp.c
+++ b/regex/regcomp.c
@@ -1,4 +1,4 @@
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#include <m_ctype.h>
#include <regex.h>
@@ -219,7 +219,7 @@ int stop; /* character this ERE should end at */
conc = HERE();
while (MORE() && (c = PEEK()) != '|' && c != stop)
p_ere_exp(p);
- if(REQUIRE(HERE() != conc, REG_EMPTY)); /* require nonempty */
+ if(REQUIRE(HERE() != conc, REG_EMPTY)) {}/* require nonempty */
if (!EAT('|'))
break; /* NOTE BREAK OUT */
@@ -266,11 +266,11 @@ register struct parse *p;
pos = HERE();
switch (c) {
case '(':
- if(REQUIRE(MORE(), REG_EPAREN));
+ if(REQUIRE(MORE(), REG_EPAREN)) {}
p->g->nsub++;
subno = (sopno) p->g->nsub;
if (subno < NPAREN)
- p->pbegin[subno] = HERE();
+ p->pbegin[subno] = HERE();
EMIT(OLPAREN, subno);
if (!SEE(')'))
p_ere(p, ')');
@@ -279,7 +279,7 @@ register struct parse *p;
assert(p->pend[subno] != 0);
}
EMIT(ORPAREN, subno);
- if(MUSTEAT(')', REG_EPAREN));
+ if(MUSTEAT(')', REG_EPAREN)) {}
break;
#ifndef POSIX_MISTAKE
case ')': /* happens only if no current unmatched ( */
@@ -322,12 +322,12 @@ register struct parse *p;
p_bracket(p);
break;
case '\\':
- if(REQUIRE(MORE(), REG_EESCAPE));
+ if(REQUIRE(MORE(), REG_EESCAPE)) {}
c = GETNEXT();
ordinary(p, c);
break;
case '{': /* okay as ordinary except if digit follows */
- if(REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT));
+ if(REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT)) {}
/* FALLTHROUGH */
default:
ordinary(p, c);
@@ -343,7 +343,7 @@ register struct parse *p;
return; /* no repetition, we're done */
NEXT();
- if(REQUIRE(!wascaret, REG_BADRPT));
+ if(REQUIRE(!wascaret, REG_BADRPT)) {}
switch (c) {
case '*': /* implemented as +? */
/* this case does not require the (y|) trick, noKLUDGE */
@@ -370,7 +370,7 @@ register struct parse *p;
if (EAT(',')) {
if (isdigit(PEEK())) {
count2 = p_count(p);
- if(REQUIRE(count <= count2, REG_BADBR));
+ if(REQUIRE(count <= count2, REG_BADBR)) {}
} else /* single number with comma */
count2 = RE_INFINITY;
} else /* just a single number */
@@ -379,7 +379,7 @@ register struct parse *p;
if (!EAT('}')) { /* error heuristics */
while (MORE() && PEEK() != '}')
NEXT();
- if(REQUIRE(MORE(), REG_EBRACE));
+ if(REQUIRE(MORE(), REG_EBRACE)) {}
SETERROR(REG_BADBR);
}
break;
@@ -402,7 +402,7 @@ static void
p_str(p)
register struct parse *p;
{
- if(REQUIRE(MORE(), REG_EMPTY));
+ if(REQUIRE(MORE(), REG_EMPTY)) {}
while (MORE())
ordinary(p, GETNEXT());
}
@@ -445,7 +445,7 @@ register int end2; /* second terminating character */
p->g->neol++;
}
- if(REQUIRE(HERE() != start, REG_EMPTY)); /* require nonempty */
+ if(REQUIRE(HERE() != start, REG_EMPTY)) {} /* require nonempty */
}
/*
@@ -470,7 +470,7 @@ int starordinary; /* is a leading * an ordinary character? */
assert(MORE()); /* caller should have ensured this */
c = GETNEXT();
if (c == '\\') {
- if(REQUIRE(MORE(), REG_EESCAPE));
+ if(REQUIRE(MORE(), REG_EESCAPE)) {}
c = BACKSL | (unsigned char)GETNEXT();
}
switch (c) {
@@ -500,7 +500,7 @@ int starordinary; /* is a leading * an ordinary character? */
assert(p->pend[subno] != 0);
}
EMIT(ORPAREN, subno);
- if(REQUIRE(EATTWO('\\', ')'), REG_EPAREN));
+ if(REQUIRE(EATTWO('\\', ')'), REG_EPAREN)) {}
break;
case BACKSL|')': /* should not get here -- must be user */
case BACKSL|'}':
@@ -530,7 +530,7 @@ int starordinary; /* is a leading * an ordinary character? */
p->g->backrefs = 1;
break;
case '*':
- if(REQUIRE(starordinary, REG_BADRPT));
+ if(REQUIRE(starordinary, REG_BADRPT)) {}
/* FALLTHROUGH */
default:
ordinary(p, c &~ BACKSL);
@@ -548,7 +548,7 @@ int starordinary; /* is a leading * an ordinary character? */
if (EAT(',')) {
if (MORE() && isdigit(PEEK())) {
count2 = p_count(p);
- if(REQUIRE(count <= count2, REG_BADBR));
+ if(REQUIRE(count <= count2, REG_BADBR)) {}
} else /* single number with comma */
count2 = RE_INFINITY;
} else /* just a single number */
@@ -557,7 +557,7 @@ int starordinary; /* is a leading * an ordinary character? */
if (!EATTWO('\\', '}')) { /* error heuristics */
while (MORE() && !SEETWO('\\', '}'))
NEXT();
- if(REQUIRE(MORE(), REG_EBRACE));
+ if(REQUIRE(MORE(), REG_EBRACE)) {}
SETERROR(REG_BADBR);
}
} else if (c == (unsigned char)'$') /* $ (but not \$) ends it */
@@ -582,7 +582,7 @@ register struct parse *p;
ndigits++;
}
- if(REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR));
+ if(REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR)) {}
return(count);
}
@@ -622,7 +622,7 @@ register struct parse *p;
p_b_term(p, cs);
if (EAT('-'))
CHadd(cs, '-');
- if(MUSTEAT(']', REG_EBRACK));
+ if(MUSTEAT(']', REG_EBRACK)) {}
if (p->error != 0) /* don't mess things up further */
return;
@@ -693,21 +693,21 @@ register cset *cs;
switch (c) {
case ':': /* character class */
NEXT2();
- if(REQUIRE(MORE(), REG_EBRACK));
+ if(REQUIRE(MORE(), REG_EBRACK)) {}
c = PEEK();
- if(REQUIRE(c != '-' && c != ']', REG_ECTYPE));
+ if(REQUIRE(c != '-' && c != ']', REG_ECTYPE)) {}
p_b_cclass(p, cs);
- if(REQUIRE(MORE(), REG_EBRACK));
- if(REQUIRE(EATTWO(':', ']'), REG_ECTYPE));
+ if(REQUIRE(MORE(), REG_EBRACK)) {}
+ if(REQUIRE(EATTWO(':', ']'), REG_ECTYPE)) {}
break;
case '=': /* equivalence class */
NEXT2();
- if(REQUIRE(MORE(), REG_EBRACK));
+ if(REQUIRE(MORE(), REG_EBRACK)) {}
c = PEEK();
- if(REQUIRE(c != '-' && c != ']', REG_ECOLLATE));
+ if(REQUIRE(c != '-' && c != ']', REG_ECOLLATE)) {}
p_b_eclass(p, cs);
- if(REQUIRE(MORE(), REG_EBRACK));
- if(REQUIRE(EATTWO('=', ']'), REG_ECOLLATE));
+ if(REQUIRE(MORE(), REG_EBRACK)) {}
+ if(REQUIRE(EATTWO('=', ']'), REG_ECOLLATE)) {}
break;
default: /* symbol, ordinary character, or range */
/* xxx revision needed for multichar stuff */
@@ -722,7 +722,7 @@ register cset *cs;
} else
finish = start;
/* xxx what about signed chars here... */
- if(REQUIRE(start <= finish, REG_ERANGE));
+ if(REQUIRE(start <= finish, REG_ERANGE)) {}
for (i = start; i <= finish; i++)
CHadd(cs, i);
break;
@@ -756,10 +756,10 @@ register cset *cs;
return;
}
- u = cp->chars;
+ u = (char*) cp->chars;
while ((c = *u++) != '\0')
CHadd(cs, c);
- for (u = cp->multis; *u != '\0'; u += strlen(u) + 1)
+ for (u = (char*) cp->multis; *u != '\0'; u += strlen(u) + 1)
MCadd(p, cs, u);
}
@@ -790,13 +790,13 @@ register struct parse *p;
{
register char value;
- if(REQUIRE(MORE(), REG_EBRACK));
+ if(REQUIRE(MORE(), REG_EBRACK)) {}
if (!EATTWO('[', '.'))
return(GETNEXT());
/* collating symbol */
value = p_b_coll_elem(p, '.');
- if(REQUIRE(EATTWO('.', ']'), REG_ECOLLATE));
+ if(REQUIRE(EATTWO('.', ']'), REG_ECOLLATE)) {}
return(value);
}
@@ -1189,6 +1189,7 @@ register char *cp;
cs->multis[cs->smultis - 1] = '\0';
}
+#ifdef NOT_USED
/*
- mcsub - subtract a collating element from a cset
== static void mcsub(register cset *cs, register char *cp);
@@ -1246,6 +1247,7 @@ register char *cp;
return(p);
return(NULL);
}
+#endif
/*
- mcinvert - invert the list of collating elements in a cset
@@ -1256,8 +1258,8 @@ register char *cp;
*/
static void
mcinvert(p, cs)
-register struct parse *p;
-register cset *cs;
+ register struct parse *p __attribute__((unused));
+ register cset *cs __attribute__((unused));
{
assert(cs->multis == NULL); /* xxx */
}
@@ -1271,8 +1273,8 @@ register cset *cs;
*/
static void
mccase(p, cs)
-register struct parse *p;
-register cset *cs;
+register struct parse *p __attribute__((unused));
+register cset *cs __attribute__((unused));
{
assert(cs->multis == NULL); /* xxx */
}
diff --git a/regex/regcomp.ih b/regex/regcomp.ih
index 0776e7185cd..4ae45bbf4a9 100644
--- a/regex/regcomp.ih
+++ b/regex/regcomp.ih
@@ -28,9 +28,11 @@ static int freezeset(register struct parse *p, register cset *cs);
static int firstch(register struct parse *p, register cset *cs);
static int nch(register struct parse *p, register cset *cs);
static void mcadd(register struct parse *p, register cset *cs, register char *cp);
+#ifdef NOT_USED
static void mcsub(register cset *cs, register char *cp);
static int mcin(register cset *cs, register char *cp);
static char *mcfind(register cset *cs, register char *cp);
+#endif
static void mcinvert(register struct parse *p, register cset *cs);
static void mccase(register struct parse *p, register cset *cs);
static int isinsets(register struct re_guts *g, int c);
diff --git a/regex/regerror.c b/regex/regerror.c
index a356912564a..0a7b7c8da2c 100644
--- a/regex/regerror.c
+++ b/regex/regerror.c
@@ -1,4 +1,4 @@
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#include <m_ctype.h>
#include <regex.h>
@@ -28,8 +28,8 @@
*/
static struct rerr {
int code;
- char *name;
- char *explain;
+ const char *name;
+ const char *explain;
} rerrs[] = {
{REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"},
{REG_BADPAT, "REG_BADPAT", "invalid regular expression"},
@@ -83,7 +83,7 @@ size_t errbuf_size;
assert(strlen(convbuf) < sizeof(convbuf));
s = convbuf;
} else
- s = r->explain;
+ s = (char*) r->explain;
}
len = strlen(s) + 1;
@@ -113,7 +113,7 @@ char *localbuf;
if (strcmp(r->name, preg->re_endp) == 0)
break;
if (r->code == 0)
- return("0");
+ return((char*) "0");
sprintf(localbuf, "%d", r->code);
return(localbuf);
diff --git a/regex/regexec.c b/regex/regexec.c
index 853bd7aa263..7f2704f8214 100644
--- a/regex/regexec.c
+++ b/regex/regexec.c
@@ -5,7 +5,7 @@
* macros that code uses. This lets the same code operate on two different
* representations for state sets.
*/
-#include <global.h>
+#include <my_global.h>
#include <m_string.h>
#include <m_ctype.h>
#include <regex.h>
diff --git a/regex/regexp.c b/regex/regexp.c
index 706208a6b25..8ddf90f2943 100644
--- a/regex/regexp.c
+++ b/regex/regexp.c
@@ -58,7 +58,7 @@
*/
/* Headers */
-#include "global.h"
+#include "my_global.h"
#include <ctype.h>
#include "regexp.h"
#ifdef __WIN__
diff --git a/regex/regfree.c b/regex/regfree.c
index a0dd8087a45..6ab50735075 100644
--- a/regex/regfree.c
+++ b/regex/regfree.c
@@ -1,4 +1,4 @@
-#include <global.h>
+#include <my_global.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/regex/reginit.c b/regex/reginit.c
index b5815e7d01c..309685fadf2 100644
--- a/regex/reginit.c
+++ b/regex/reginit.c
@@ -1,6 +1,6 @@
/* Init cclasses array from ctypes */
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
#include <m_string.h>
#include "cclass.h"
@@ -49,6 +49,16 @@ void regex_init()
for (i=0; i < CCLASS_LAST ; i++)
{
char *tmp=(char*) malloc(count[i]+1);
+ if (!tmp)
+ {
+ /*
+ This is very unlikely to happen as this function is called once
+ at program startup
+ */
+ fprintf(stderr,
+ "Fatal error: Can't allocate memory in regex_init\n");
+ exit(1);
+ }
memcpy(tmp,buff[i],count[i]*sizeof(char));
tmp[count[i]]=0;
cclasses[i].chars=tmp;
@@ -63,7 +73,7 @@ void regex_end()
{
int i;
for (i=0; i < CCLASS_LAST ; i++)
- free(cclasses[i].chars);
+ free((char*) cclasses[i].chars);
regex_inited=0;
}
}
diff --git a/regex/split.c b/regex/split.c
index 188bdb775b9..bd2a53c01e3 100644
--- a/regex/split.c
+++ b/regex/split.c
@@ -27,7 +27,7 @@ char *sep; /* "" white, "c" single char, "ab" [ab]+ */
continue;
p--;
trimtrail = 1;
- sep = " \t"; /* note, code below knows this is 2 long */
+ sep = (char*) " \t"; /* note, code below knows this is 2 long */
sepc = ' ';
} else
trimtrail = 0;
diff --git a/repl-tests/README b/repl-tests/README
deleted file mode 100644
index 95611c6538d..00000000000
--- a/repl-tests/README
+++ /dev/null
@@ -1,12 +0,0 @@
-This directory contains a set of test cases for replication. To get it
-to work on your system, install this version of MySQL on the master and on
-the slave, configure them according to the Replication HOWTO in the manual,
-modify include/master-slave.inc to specify correct connection parameters
-for the master and the slave and do
-
-sh run-all-tests
-
-If you would like to add your own test case, create a directory
-test-your-test-case-name, write your own run.test following the examples
-in the other test cases. Note that you can create the files containing
-the expected output ( master files) by running mysqltest --record < run.test \ No newline at end of file
diff --git a/repl-tests/include/master-slave.inc b/repl-tests/include/master-slave.inc
deleted file mode 100644
index ad2dea1f520..00000000000
--- a/repl-tests/include/master-slave.inc
+++ /dev/null
@@ -1,2 +0,0 @@
-connect (slave,localhost,root,,test,0,/var/lib/mysql/mysql.sock);
-connect (master,sarochka,admin,,test,0,0);
diff --git a/repl-tests/run-all-tests b/repl-tests/run-all-tests
deleted file mode 100755
index d9f08d8a8fb..00000000000
--- a/repl-tests/run-all-tests
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/sh
-
-for d in test-*; do
-cd $d
-echo -n $d | sed -e s/test-//
-echo -n "...."
-../../client/mysqltest $@ < run.test
-cd ..
-done \ No newline at end of file
diff --git a/repl-tests/test-auto-inc/run.test b/repl-tests/test-auto-inc/run.test
deleted file mode 100755
index 8405329f458..00000000000
--- a/repl-tests/test-auto-inc/run.test
+++ /dev/null
@@ -1,10 +0,0 @@
-source ../include/master-slave.inc;
-connection master;
-drop table if exists x;
-create table x(n int auto_increment primary key);
-set insert_id = 2000;
-insert into x values (NULL),(NULL),(NULL);
-connection slave;
-sleep 3;
-@x.master select * from x;
-
diff --git a/repl-tests/test-auto-inc/x.master b/repl-tests/test-auto-inc/x.master
deleted file mode 100644
index c76fc46ae97..00000000000
--- a/repl-tests/test-auto-inc/x.master
+++ /dev/null
@@ -1,4 +0,0 @@
-n
-2000
-2001
-2002
diff --git a/repl-tests/test-bad-query/run.test b/repl-tests/test-bad-query/run.test
deleted file mode 100755
index a86aaf84096..00000000000
--- a/repl-tests/test-bad-query/run.test
+++ /dev/null
@@ -1,10 +0,0 @@
-source ../include/master-slave.inc;
-connection master;
-drop table if exists x;
-create table x(n int primary key);
-!insert into x values (1),(2),(2);
-insert into x values (3);
-connection slave;
-sleep 3;
-@x.master select * from x;
-
diff --git a/repl-tests/test-bad-query/x.master b/repl-tests/test-bad-query/x.master
deleted file mode 100644
index c62967af0bb..00000000000
--- a/repl-tests/test-bad-query/x.master
+++ /dev/null
@@ -1,4 +0,0 @@
-n
-1
-2
-3
diff --git a/repl-tests/test-dump/run.test b/repl-tests/test-dump/run.test
deleted file mode 100644
index c714186a67b..00000000000
--- a/repl-tests/test-dump/run.test
+++ /dev/null
@@ -1,25 +0,0 @@
-source ../include/master-slave.inc;
-connection slave;
-!slave stop;
-flush slave;
-connection master;
-flush master;
-connection slave;
-slave start;
-connection master;
-use test;
-drop table if exists words;
-create table words (word char(20) not null, index(word));
-load data infile '/usr/dict/words' into table words;
-drop table if exists words1;
-create table words1 (word char(20) not null);
-load data infile '/usr/dict/words' into table words1;
-sleep 20;
-connection slave;
-use test;
-drop table if exists words;
-load table words from master;
-drop table if exists words1;
-load table words1 from master;
-@table-dump-check.master check table words;
-@table-dump-select.master select count(*) from words1;
diff --git a/repl-tests/test-dump/table-dump-check.master b/repl-tests/test-dump/table-dump-check.master
deleted file mode 100644
index 4061fdb4a0d..00000000000
--- a/repl-tests/test-dump/table-dump-check.master
+++ /dev/null
@@ -1,2 +0,0 @@
-Table Op Msg_type Msg_text
-test.words check status OK
diff --git a/repl-tests/test-dump/table-dump-select.master b/repl-tests/test-dump/table-dump-select.master
deleted file mode 100644
index ae93d31c066..00000000000
--- a/repl-tests/test-dump/table-dump-select.master
+++ /dev/null
@@ -1,2 +0,0 @@
-count(*)
-45402
diff --git a/repl-tests/test-repl-alter/run.test b/repl-tests/test-repl-alter/run.test
deleted file mode 100644
index 2e031010d5c..00000000000
--- a/repl-tests/test-repl-alter/run.test
+++ /dev/null
@@ -1,12 +0,0 @@
-source ../include/master-slave.inc;
-connection master;
-drop table if exists test;
-CREATE TABLE test (name varchar(64), age smallint(3));
-INSERT INTO test SET name='Andy', age=31;
-INSERT test SET name='Jacob', age=2;
-INSERT into test SET name='Caleb', age=1;
-ALTER TABLE test ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY;
-@test.master select * from test;
-connection slave;
-sleep 3;
-@test.master select * from test;
diff --git a/repl-tests/test-repl-alter/test.master b/repl-tests/test-repl-alter/test.master
deleted file mode 100644
index 763154b938e..00000000000
--- a/repl-tests/test-repl-alter/test.master
+++ /dev/null
@@ -1,4 +0,0 @@
-name age id
-Andy 31 00000001
-Jacob 2 00000002
-Caleb 1 00000003
diff --git a/repl-tests/test-repl-ts/repl-timestamp.master b/repl-tests/test-repl-ts/repl-timestamp.master
deleted file mode 100644
index c3e4a2326d0..00000000000
--- a/repl-tests/test-repl-ts/repl-timestamp.master
+++ /dev/null
@@ -1,2 +0,0 @@
-unix_timestamp(t)
-200006
diff --git a/repl-tests/test-repl-ts/repl-timestamp.master.reject b/repl-tests/test-repl-ts/repl-timestamp.master.reject
deleted file mode 100644
index 091b18351ed..00000000000
--- a/repl-tests/test-repl-ts/repl-timestamp.master.reject
+++ /dev/null
@@ -1,2 +0,0 @@
-unix_timestamp(t)
-973999074
diff --git a/repl-tests/test-repl-ts/run.test b/repl-tests/test-repl-ts/run.test
deleted file mode 100644
index 0a5224ce02a..00000000000
--- a/repl-tests/test-repl-ts/run.test
+++ /dev/null
@@ -1,17 +0,0 @@
-#! ../client/mysqltest
-# tests if the replicaion preserves timestamp properly
-
-source ../include/master-slave.inc;
-connection master;
-set timestamp=200006;
-drop table if exists foo;
-create table foo(t timestamp not null,a char(1));
-insert into foo ( a) values ('F');
-@repl-timestamp.master select unix_timestamp(t) from foo;
-sleep 3;
-connection slave;
-drop table if exists foo;
-load table foo from master;
-@repl-timestamp.master select unix_timestamp(t) from foo;
-
-
diff --git a/repl-tests/test-repl/foo-dump-master.master b/repl-tests/test-repl/foo-dump-master.master
deleted file mode 100644
index 982e0523cfb..00000000000
--- a/repl-tests/test-repl/foo-dump-master.master
+++ /dev/null
@@ -1,3 +0,0 @@
-n
-1
-2
diff --git a/repl-tests/test-repl/foo-dump-slave.master b/repl-tests/test-repl/foo-dump-slave.master
deleted file mode 100644
index 982e0523cfb..00000000000
--- a/repl-tests/test-repl/foo-dump-slave.master
+++ /dev/null
@@ -1,3 +0,0 @@
-n
-1
-2
diff --git a/repl-tests/test-repl/run.test b/repl-tests/test-repl/run.test
deleted file mode 100755
index cc93d964efa..00000000000
--- a/repl-tests/test-repl/run.test
+++ /dev/null
@@ -1,24 +0,0 @@
-source ../include/master-slave.inc;
-connection slave;
-!slave stop;
-connection master;
-flush master;
-connection slave;
-flush slave;
-!slave start;
-sleep 3;
-connection master;
-use test;
-drop table if exists words;
-create table words (word char(20) not null, index(word));
-load data infile '/usr/dict/words' into table words;
-drop table if exists foo;
-create table foo(n int);
-insert into foo values(1),(2);
-@foo-dump-master.master select * from foo;
-@sum-wlen-master.master select sum(length(word)) from words;
-connection slave;
-sleep 15;
-use test;
-@sum-wlen-slave.master select sum(length(word)) from words;
-@foo-dump-slave.master select * from foo;
diff --git a/repl-tests/test-repl/sum-wlen-master.master b/repl-tests/test-repl/sum-wlen-master.master
deleted file mode 100644
index e749ab4840a..00000000000
--- a/repl-tests/test-repl/sum-wlen-master.master
+++ /dev/null
@@ -1,2 +0,0 @@
-sum(length(word))
-363634
diff --git a/repl-tests/test-repl/sum-wlen-slave.master b/repl-tests/test-repl/sum-wlen-slave.master
deleted file mode 100644
index e749ab4840a..00000000000
--- a/repl-tests/test-repl/sum-wlen-slave.master
+++ /dev/null
@@ -1,2 +0,0 @@
-sum(length(word))
-363634
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 19fb7cedc7a..d14d7f38deb 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -20,7 +20,9 @@ bin_SCRIPTS = @server_scripts@ \
msql2mysql \
mysql_config \
mysql_fix_privilege_tables \
+ mysql_fix_extensions \
mysql_setpermission \
+ mysql_secure_installation \
mysql_zap \
mysqlaccess \
mysqlbug \
@@ -28,16 +30,21 @@ bin_SCRIPTS = @server_scripts@ \
mysql_find_rows \
mysqlhotcopy \
mysqldumpslow \
+ mysql_explain_log \
+ mysql_tableinfo \
mysqld_multi \
make_win_src_distribution
EXTRA_SCRIPTS = make_binary_distribution.sh \
+ make_sharedlib_distribution.sh \
make_win_src_distribution.sh \
msql2mysql.sh \
mysql_config.sh \
mysql_fix_privilege_tables.sh \
+ mysql_fix_extensions.sh \
mysql_install_db.sh \
mysql_setpermission.sh \
+ mysql_secure_installation.sh \
mysql_zap.sh \
mysqlaccess.sh \
mysqlbug.sh \
@@ -45,23 +52,28 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \
mysql_find_rows.sh \
mysqlhotcopy.sh \
mysqldumpslow.sh \
+ mysql_explain_log.sh \
mysqld_multi.sh \
- safe_mysqld.sh
+ mysql_tableinfo.sh \
+ mysqld_safe.sh
EXTRA_DIST = $(EXTRA_SCRIPTS) \
mysqlaccess.conf \
mysqlbug
-pkgdata_DATA = make_binary_distribution
+pkgdata_DATA = make_binary_distribution make_sharedlib_distribution
# mysqlbug should be distributed built so that people can report build
# failures with it.
CLEANFILES = @server_scripts@ \
make_binary_distribution \
+ make_sharedlib_distribution \
msql2mysql \
mysql_config \
mysql_fix_privilege_tables \
+ mysql_fix_extensions \
mysql_setpermission \
+ mysql_secure_installation \
mysql_zap \
mysqlaccess \
mysql_convert_table_format \
@@ -93,11 +105,18 @@ SUFFIXES = .sh
-e 's!@''CC''@!@CC@!'\
-e 's!@''CXX''@!@CXX@!'\
-e 's!@''GXX''@!@GXX@!'\
+ -e 's!@''CC_VERSION''@!@CC_VERSION@!'\
+ -e 's!@''CXX_VERSION''@!@CXX_VERSION@!'\
-e 's!@''PERL''@!@PERL@!' \
+ -e 's!@''ASFLAGS''@!@SAVE_ASFLAGS@!'\
-e 's!@''CFLAGS''@!@SAVE_CFLAGS@!'\
-e 's!@''CXXFLAGS''@!@SAVE_CXXFLAGS@!'\
-e 's!@''LDFLAGS''@!@SAVE_LDFLAGS@!'\
-e 's!@''CLIENT_LIBS''@!@CLIENT_LIBS@!' \
+ -e 's!@''LIBS''@!@LIBS@!' \
+ -e 's!@''WRAPLIBS''@!@WRAPLIBS@!' \
+ -e 's!@''innodb_system_libs''@!@innodb_system_libs@!' \
+ -e 's!@''openssl_libs''@!@openssl_libs@!' \
-e 's!@''VERSION''@!@VERSION@!' \
-e 's!@''MYSQL_SERVER_SUFFIX''@!@MYSQL_SERVER_SUFFIX@!' \
-e 's!@''COMPILATION_COMMENT''@!@COMPILATION_COMMENT@!' \
diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh
index 801f9fb2e05..c7945e31eda 100644
--- a/scripts/make_binary_distribution.sh
+++ b/scripts/make_binary_distribution.sh
@@ -10,6 +10,7 @@ version=@VERSION@
export machine system version
SOURCE=`pwd`
CP="cp -p"
+MV="mv"
STRIP=1
DEBUG=0
@@ -46,16 +47,46 @@ if [ -d $BASE ] ; then
rm -r -f $BASE
fi
-mkdir $BASE $BASE/bin $BASE/data $BASE/data/mysql $BASE/data/test \
- $BASE/include $BASE/lib $BASE/support-files $BASE/share $BASE/share/mysql \
- $BASE/tests $BASE/scripts $BASE/sql-bench $BASE/mysql-test \
- $BASE/mysql-test/t $BASE/mysql-test/r \
- $BASE/mysql-test/include $BASE/mysql-test/std_data $BASE/man
-
-chmod o-rwx $BASE/data $BASE/data/*
+BS=""
+BIN_FILES=""
+BASE_SYSTEM="any"
+MYSQL_SHARE=$BASE/share/mysql
-for i in ChangeLog COPYING COPYING.LIB README Docs/INSTALL-BINARY \
- MySQLEULA.txt Docs/manual.html Docs/manual.txt Docs/manual_toc.html
+case $system in
+ *netware*)
+ BASE_SYSTEM="netware"
+ BS=".nlm"
+ MYSQL_SHARE=$BASE/share
+ ;;
+esac
+
+
+mkdir $BASE $BASE/bin $BASE/docs \
+ $BASE/include $BASE/lib $BASE/support-files $BASE/share $BASE/scripts \
+ $BASE/mysql-test $BASE/mysql-test/t $BASE/mysql-test/r \
+ $BASE/mysql-test/include $BASE/mysql-test/std_data
+
+if [ $BASE_SYSTEM != "netware" ] ; then
+ mkdir $BASE/share/mysql $BASE/tests $BASE/sql-bench $BASE/man \
+ $BASE/man/man1 $BASE/data $BASE/data/mysql $BASE/data/test
+
+ chmod o-rwx $BASE/data $BASE/data/*
+fi
+
+for i in ChangeLog \
+ Docs/manual.html \
+ Docs/manual.txt \
+ Docs/manual_toc.html \
+ Docs/mysql.info
+do
+ if [ -f $i ]
+ then
+ $CP $i $BASE/docs
+ fi
+done
+
+for i in COPYING README Docs/INSTALL-BINARY \
+ MySQLEULA.txt LICENSE.doc README.NW
do
if [ -f $i ]
then
@@ -63,15 +94,41 @@ do
fi
done
-for i in extra/comp_err extra/replace extra/perror extra/resolveip \
- extra/my_print_defaults extra/resolve_stack_dump \
- isam/isamchk isam/pack_isam myisam/myisamchk \
- myisam/myisampack sql/mysqld client/mysqlbinlog \
- client/mysql sql/mysqld client/mysqlshow client/mysqlcheck \
- client/mysqladmin client/mysqldump client/mysqlimport client/mysqltest \
- client/.libs/mysql client/.libs/mysqlshow client/.libs/mysqladmin \
- client/.libs/mysqldump client/.libs/mysqlimport client/.libs/mysqltest \
- client/.libs/mysqlcheck client/.libs/mysqlbinlog
+# Non platform-specific bin dir files:
+BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \
+ extra/resolveip$BS extra/my_print_defaults$BS \
+ extra/resolve_stack_dump$BS extra/mysql_waitpid$BS \
+ isam/isamchk$BS isam/pack_isam$BS \
+ myisam/myisamchk$BS myisam/myisampack$BS myisam/myisamlog$BS \
+ myisam/myisam_ftdump$BS \
+ sql/mysqld$BS \
+ client/mysql$BS client/mysqlshow$BS client/mysqladmin$BS \
+ client/mysqldump$BS client/mysqlimport$BS \
+ client/mysqltest$BS client/mysqlcheck$BS \
+ client/mysqlbinlog$BS
+";
+
+# Platform-specific bin dir files:
+if [ $BASE_SYSTEM = "netware" ] ; then
+ BIN_FILES="$BIN_FILES \
+ netware/mysqld_safe$BS netware/mysql_install_db$BS \
+ netware/init_db.sql netware/test_db.sql netware/mysql_explain_log$BS \
+ netware/mysqlhotcopy$BS netware/libmysql$BS netware/init_secure_db.sql
+ ";
+else
+ # For all other platforms:
+ BIN_FILES="$BIN_FILES \
+ client/mysqlmanagerc \
+ client/mysqlmanager-pwgen tools/mysqlmanager \
+ client/.libs/mysql client/.libs/mysqlshow client/.libs/mysqladmin \
+ client/.libs/mysqldump client/.libs/mysqlimport \
+ client/.libs/mysqltest client/.libs/mysqlcheck \
+ client/.libs/mysqlbinlog client/.libs/mysqlmanagerc \
+ client/.libs/mysqlmanager-pwgen tools/.libs/mysqlmanager \
+ ";
+fi
+
+for i in $BIN_FILES
do
if [ -f $i ]
then
@@ -83,6 +140,7 @@ if [ x$STRIP = x1 ] ; then
strip $BASE/bin/*
fi
+# Copy not binary files
for i in sql/mysqld.sym.gz
do
if [ -f $i ]
@@ -91,7 +149,17 @@ do
fi
done
-for i in libmysql/.libs/libmysqlclient.a libmysql/.libs/libmysqlclient.so* libmysql/libmysqlclient.* libmysql_r/.libs/libmysqlclient_r.a libmysql_r/.libs/libmysqlclient_r.so* libmysql_r/libmysqlclient_r.* mysys/libmysys.a strings/libmystrings.a dbug/libdbug.a $BASE/lib
+if [ $BASE_SYSTEM = "netware" ] ; then
+ $CP -r netware/*.pl $BASE/scripts
+fi
+
+for i in \
+ libmysql/.libs/libmysqlclient.a libmysql/.libs/libmysqlclient.so* \
+ libmysql/libmysqlclient.* libmysql_r/.libs/libmysqlclient_r.a \
+ libmysql_r/.libs/libmysqlclient_r.so* libmysql_r/libmysqlclient_r.* \
+ mysys/libmysys.a strings/libmystrings.a dbug/libdbug.a \
+ libmysqld/.libs/libmysqld.a libmysqld/.libs/libmysqld.so* \
+ libmysqld/libmysqld.a netware/libmysql.imp
do
if [ -f $i ]
then
@@ -99,34 +167,75 @@ do
fi
done
+# convert the libs to .lib for NetWare
+if [ $BASE_SYSTEM = "netware" ] ; then
+ for i in $BASE/lib/*.a
+ do
+ libname=`basename $i .a`
+ $MV $i $BASE/lib/$libname.lib
+ done
+fi
+
$CP config.h include/* $BASE/include
-rm $BASE/include/Makefile*; rm $BASE/include/*.in
+rm -f $BASE/include/Makefile* $BASE/include/*.in $BASE/include/config-win.h
+if [ $BASE_SYSTEM != "netware" ] ; then
+ rm -f $BASE/include/config-netware.h
+fi
+
+if [ $BASE_SYSTEM != "netware" ] ; then
+ if [ -d tests ] ; then
+ $CP tests/*.res tests/*.tst tests/*.pl $BASE/tests
+ fi
+ if [ -d man ] ; then
+ $CP man/*.1 $BASE/man/man1
+ fi
+fi
-$CP tests/*.res tests/*.tst tests/*.pl $BASE/tests
$CP support-files/* $BASE/support-files
-$CP man/*.? $BASE/man
-$CP -r sql/share/* $BASE/share/mysql
-rm -f $BASE/share/mysql/Makefile* $BASE/share/mysql/*/*.OLD
+if [ $BASE_SYSTEM = "netware" ] ; then
+ rm -f $BASE/support-files/magic \
+ $BASE/support-files/mysql.server \
+ $BASE/support-files/mysql*.spec \
+ $BASE/support-files/mysql-log-rotate \
+ $BASE/support-files/binary-configure
+fi
+
+$CP -r sql/share/* $MYSQL_SHARE
+rm -f $MYSQL_SHARE/Makefile* $MYSQL_SHARE/*/*.OLD
+
+for i in mysql-test/mysql-test-run mysql-test/install_test_db \
+ mysql-test/README \
+ netware/mysql_test_run.nlm netware/install_test_db.ncf
+do
+ if [ -f $i ]
+ then
+ $CP $i $BASE/mysql-test
+ fi
+done
-$CP mysql-test/mysql-test-run mysql-test/install_test_db $BASE/mysql-test/
-$CP mysql-test/README $BASE/mysql-test/README
$CP mysql-test/include/*.inc $BASE/mysql-test/include
$CP mysql-test/std_data/*.dat mysql-test/std_data/*.001 $BASE/mysql-test/std_data
-$CP mysql-test/t/*.test mysql-test/t/*.opt mysql-test/t/*.slave-mi mysql-test/t/*.sh $BASE/mysql-test/t
-$CP mysql-test/r/*.result mysql-test/r/*.require $BASE/mysql-test/r
+$CP mysql-test/std_data/des_key_file $BASE/mysql-test/std_data
+$CP mysql-test/t/*test mysql-test/t/*.opt mysql-test/t/*.slave-mi mysql-test/t/*.sh $BASE/mysql-test/t
+$CP mysql-test/r/*result mysql-test/r/*.require $BASE/mysql-test/r
+
+if [ $BASE_SYSTEM != "netware" ] ; then
+ $CP scripts/* $BASE/bin
+ $BASE/bin/replace \@localstatedir\@ ./data \@bindir\@ ./bin \@scriptdir\@ ./bin \@libexecdir\@ ./bin \@sbindir\@ ./bin \@prefix\@ . \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/scripts/mysql_install_db.sh > $BASE/scripts/mysql_install_db
+ $BASE/bin/replace \@prefix\@ /usr/local/mysql \@bindir\@ ./bin \@MYSQLD_USER\@ root \@localstatedir\@ /usr/local/mysql/data \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/support-files/mysql.server.sh > $BASE/support-files/mysql.server
+ $BASE/bin/replace /my/gnu/bin/hostname /bin/hostname -- $BASE/bin/mysqld_safe
+ mv $BASE/support-files/binary-configure $BASE/configure
+ chmod a+x $BASE/bin/* $BASE/scripts/* $BASE/support-files/mysql-* $BASE/support-files/mysql.server $BASE/configure
+ $CP -r sql-bench/* $BASE/sql-bench
+ rm -f $BASE/sql-bench/*.sh $BASE/sql-bench/Makefile* $BASE/lib/*.la
+fi
-$CP scripts/* $BASE/bin
rm -f $BASE/bin/Makefile* $BASE/bin/*.in $BASE/bin/*.sh $BASE/bin/mysql_install_db $BASE/bin/make_binary_distribution $BASE/bin/setsomevars $BASE/support-files/Makefile* $BASE/support-files/*.sh
-$BASE/bin/replace \@localstatedir\@ ./data \@bindir\@ ./bin \@scriptdir\@ ./bin \@libexecdir\@ ./bin \@sbindir\@ ./bin \@prefix\@ . \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/scripts/mysql_install_db.sh > $BASE/scripts/mysql_install_db
-$BASE/bin/replace \@prefix\@ /usr/local/mysql \@bindir\@ ./bin \@MYSQLD_USER\@ root \@localstatedir\@ /usr/local/mysql/data \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/support-files/mysql.server.sh > $BASE/support-files/mysql.server
-$BASE/bin/replace /my/gnu/bin/hostname /bin/hostname -- $BASE/bin/safe_mysqld
-
-mv $BASE/support-files/binary-configure $BASE/configure
-chmod a+x $BASE/bin/* $BASE/scripts/* $BASE/support-files/mysql-* $BASE/support-files/mysql.server $BASE/configure
-$CP -r sql-bench/* $BASE/sql-bench
-rm -f $BASE/sql-bench/*.sh $BASE/sql-bench/Makefile* $BASE/lib/*.la
+# Make safe_mysqld a symlink to mysqld_safe for backwards portability
+# To be removed in MySQL 4.1
+(cd $BASE/bin ; ln -s mysqld_safe safe_mysqld )
# Clean up if we did this from a bk tree
if [ -d $BASE/sql-bench/SCCS ] ; then
diff --git a/scripts/make_sharedlib_distribution.sh b/scripts/make_sharedlib_distribution.sh
new file mode 100644
index 00000000000..4104a315296
--- /dev/null
+++ b/scripts/make_sharedlib_distribution.sh
@@ -0,0 +1,117 @@
+#!/bin/sh
+# The default path should be /usr/local
+
+# Get some info from configure
+# chmod +x ./scripts/setsomevars
+
+machine=@MACHINE_TYPE@
+system=@SYSTEM_TYPE@
+version=@VERSION@
+export machine system version
+SOURCE=`pwd`
+CP="cp -p"
+MV="mv"
+
+STRIP=1
+DEBUG=0
+SILENT=0
+TMP=/tmp
+SUFFIX=""
+
+parse_arguments() {
+ for arg do
+ case "$arg" in
+ --debug) DEBUG=1;;
+ --tmp=*) TMP=`echo "$arg" | sed -e "s;--tmp=;;"` ;;
+ --suffix=*) SUFFIX=`echo "$arg" | sed -e "s;--suffix=;;"` ;;
+ --no-strip) STRIP=0 ;;
+ --silent) SILENT=1 ;;
+ *)
+ echo "Unknown argument '$arg'"
+ exit 1
+ ;;
+ esac
+ done
+}
+
+parse_arguments "$@"
+
+BASE=$TMP/my_dist$SUFFIX
+
+if [ -d $BASE ] ; then
+ rm -r -f $BASE
+fi
+
+mkdir -p $BASE/lib
+
+for i in \
+ libmysql/.libs/libmysqlclient.so* \
+ libmysql_r/.libs/libmysqlclient_r.so*
+do
+ if [ -f $i ]
+ then
+ $CP $i $BASE/lib
+ fi
+done
+
+# Change the distribution to a long descriptive name
+NEW_NAME=mysql-shared-$version-$system-$machine$SUFFIX
+BASE2=$TMP/$NEW_NAME
+rm -r -f $BASE2
+mv $BASE $BASE2
+BASE=$BASE2
+
+#if we are debugging, do not do tar/gz
+if [ x$DEBUG = x1 ] ; then
+ exit
+fi
+
+# This is needed to prefer GNU tar instead of tar because tar can't
+# always handle long filenames
+
+PATH_DIRS=`echo $PATH | sed -e 's/^:/. /' -e 's/:$/ ./' -e 's/::/ . /g' -e 's/:/ /g' `
+which_1 ()
+{
+ for cmd
+ do
+ for d in $PATH_DIRS
+ do
+ for file in $d/$cmd
+ do
+ if test -x $file -a ! -d $file
+ then
+ echo $file
+ exit 0
+ fi
+ done
+ done
+ done
+ exit 1
+}
+
+#
+# Create the result tar file
+#
+
+tar=`which_1 gnutar gtar`
+if test "$?" = "1" -o "$tar" = ""
+then
+ tar=tar
+fi
+
+echo "Using $tar to create archive"
+cd $TMP
+
+OPT=cvf
+if [ x$SILENT = x1 ] ; then
+ OPT=cf
+fi
+
+$tar $OPT $SOURCE/$NEW_NAME.tar $NEW_NAME
+cd $SOURCE
+echo "Compressing archive"
+gzip -9 $NEW_NAME.tar
+echo "Removing temporary directory"
+rm -r -f $BASE
+
+echo "$NEW_NAME.tar.gz created"
diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution.sh
index 50518f96adf..3556b00cbc7 100755
--- a/scripts/make_win_src_distribution.sh
+++ b/scripts/make_win_src_distribution.sh
@@ -155,13 +155,13 @@ vreplace()
{
for arg do
unix_to_dos $arg
- cat $arg | sed -e 's!@''VERSION''@!3.23.58!' > $arg.tmp
+ cat $arg | sed -e 's!@''VERSION''@!@VERSION@!' > $arg.tmp
rm -f $arg
mv $arg.tmp $arg
done
}
-for d in 3.23.XX-gpl 3.23.XX-com
+for d in 4.0.XX-gpl 4.0.XX-pro 4.0.XX-classic
do
cd $BASE/InstallShield/$d/String\ Tables/0009-English
vreplace value.shl
@@ -169,7 +169,6 @@ do
vreplace infolist.txt
done
-
#
# Move all error message files to root directory
#
@@ -205,7 +204,7 @@ copy_dir_files()
mkdir $BASE/$arg
fi
for i in *.c *.cpp *.h *.ih *.i *.ic *.asm *.def \
- README INSTALL* LICENSE *.yy
+ README INSTALL* LICENSE
do
if [ -f $i ]
then
@@ -251,9 +250,9 @@ copy_dir_dirs() {
# Input directories to be copied
#
-for i in client dbug div extra heap include isam \
+for i in client dbug extra heap include isam \
libmysql libmysqld merge myisam \
- myisammrg mysys readline regex sql strings \
+ myisammrg mysys regex sql strings \
tools vio zlib
do
copy_dir_files $i
@@ -269,15 +268,6 @@ do
done
#
-# Directories to be copied complete
-#
-
-for i in mysql-test repl-tests support-files
-do
- $CP -R $SOURCE/$i $BASE/$i
-done
-
-#
# Create dummy innobase configure header
#
@@ -292,7 +282,7 @@ touch $BASE/innobase/ib_config.h
#
cd $SOURCE
-for i in COPYING COPYING.LIB ChangeLog README \
+for i in COPYING ChangeLog README \
INSTALL-SOURCE INSTALL-WIN \
INSTALL-WIN-SOURCE \
Docs/manual_toc.html Docs/manual.html \
@@ -336,8 +326,7 @@ mv $BASE/README $BASE/README.txt
if [ -f scripts/mysql_install_db ]; then
print_debug "Initializing the 'data' directory"
- mkdir $BASE/data
- scripts/mysql_install_db --no-defaults --datadir=$BASE/data
+ scripts/mysql_install_db --no-defaults --windows --datadir=$BASE/data
fi
#
diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh
index 9320efdd2a1..051f3fa9c14 100644
--- a/scripts/mysql_config.sh
+++ b/scripts/mysql_config.sh
@@ -62,7 +62,7 @@ get_full_path ()
{
case $1 in
/*) echo "$1";;
- ./*) tmp=`pwd`/$1; echo $tmp | sed -e 's;/./;/;' ;;
+ ./*) tmp=`pwd`/$1; echo $tmp | sed -e 's;/\./;/;' ;;
*) which $1 ;;
esac
}
@@ -84,19 +84,33 @@ port='@MYSQL_TCP_PORT@'
ldflags='@LDFLAGS@'
client_libs='@CLIENT_LIBS@'
-libs="$ldflags -L'$pkglibdir' -lmysqlclient $client_libs"
-libs=`echo $libs | sed -e 's; +;;'`
-cflags="-I'$pkgincludedir'"
+# Create options, without end space
+
+libs="$ldflags -L$pkglibdir -lmysqlclient $client_libs"
+libs=`echo "$libs" | sed -e 's; \+; ;g' | sed -e 's;^ *;;' | sed -e 's; *\$;;'`
+libs_r="$ldflags -L$pkglibdir -lmysqlclient_r @LIBS@ @openssl_libs@"
+libs_r=`echo "$libs_r" | sed -e 's; \+; ;g' | sed -e 's;^ *;;' | sed -e 's; *\$;;'`
+cflags="-I$pkgincludedir @CFLAGS@"
+include="-I$pkgincludedir"
+embedded_libs="$ldflags -L$pkglibdir -lmysqld @LIBS@ @WRAPLIBS@ @innodb_system_libs@"
+embedded_libs=`echo "$embedded_libs" | sed -e 's; \+; ;g' | sed -e 's;^ *;;' | sed -e 's; *\$;;'`
+
+# Remove some options that a client doesn't have to care about
+
+cflags=`echo "$cflags " | sed -e 's;\(-DDBUG_OFF\|-DSAFEMALLOC\|-USAFEMALLOC\|-DSAFE_MUTEX\|-DPEDANTIC_SAFEMALLOC\|-DUNIV_MUST_NOT_INLINE\|-DFORCE_INIT_OF_VARS\|-DEXTRA_DEBUG\|-DHAVE_purify\|-O[0-9]\|-W[-A-Za-z]*\) *;;g' | sed -e 's; *\$;;'`
usage () {
cat <<EOF
Usage: $0 [OPTIONS]
Options:
- --cflags [$cflags]
- --libs [$libs]
- --socket [$socket]
- --port [$port]
- --version [$version]
+ --cflags [$cflags]
+ --include [$include]
+ --libs [$libs]
+ --libs_r [$libs_r]
+ --socket [$socket]
+ --port [$port]
+ --version [$version]
+ --libmysqld-libs [$embedded_libs]
EOF
exit 1
}
@@ -106,10 +120,13 @@ if test $# -le 0; then usage; fi
while test $# -gt 0; do
case $1 in
--cflags) echo "$cflags" ;;
+ --include) echo "$include" ;;
--libs) echo "$libs" ;;
+ --libs_r) echo "$libs_r" ;;
--socket) echo "$socket" ;;
--port) echo "$port" ;;
--version) echo "$version" ;;
+ --embedded-libs | --embedded | --libmysqld-libs) echo "$embedded_libs" ;;
*) usage ;;
esac
diff --git a/scripts/mysql_explain_log.sh b/scripts/mysql_explain_log.sh
new file mode 100644
index 00000000000..973d9e8a363
--- /dev/null
+++ b/scripts/mysql_explain_log.sh
@@ -0,0 +1,392 @@
+#!@PERL@ -w
+use strict;
+use DBI;
+
+use Getopt::Long;
+$Getopt::Long::ignorecase=0;
+
+print "explain_log provided by http://www.mobile.de\n";
+print "=========== ================================\n";
+
+my $Param={};
+
+$Param->{host}='';
+$Param->{user}='';
+$Param->{password}='';
+$Param->{PrintError}=0;
+$Param->{socket}='';
+
+if (!GetOptions ('date|d:i' => \$Param->{ViewDate},
+ 'host|h:s' => \$Param->{host},
+ 'user|u:s' => \$Param->{user},
+ 'password|p:s' => \$Param->{password},
+ 'printerror|e:s' => \$Param->{PrintError},
+ 'socket|s:s' => \$Param->{socket},
+ )) {
+ ShowOptions();
+}
+else {
+ $Param->{UpdateCount} = 0;
+ $Param->{SelectCount} = 0;
+ $Param->{IdxUseCount} = 0;
+ $Param->{LineCount} = 0;
+
+ $Param->{Init} = 0;
+ $Param->{Field} = 0;
+ $Param->{Refresh} = 0;
+ $Param->{QueryCount} = 0;
+ $Param->{Statistics} =0;
+
+ $Param->{Query} = undef;
+ $Param->{ALL} = undef ;
+ $Param->{Comment} = undef ;
+
+ @{$Param->{Rows}} = (qw|possible_keys key type|);
+
+ if ($Param->{ViewDate}) {
+ $Param->{View} = 0;
+ }
+ else {
+ $Param->{View} = 1;
+ }
+
+ #print "Date=$Param->{ViewDate}, host=$Param->{host}, user=$Param->{user}, password=$Param->{password}\n";
+
+ $Param->{dbh}=DBI->connect("DBI:mysql:host=$Param->{host}".($Param->{socket}?";mysql_socket=$Param->{socket}":""),$Param->{user},$Param->{password},{PrintError=>0});
+ if (DBI::err()) {
+ print "Error: " . DBI::errstr() . "\n";
+ }
+ else {
+ $Param->{Start} = time;
+ while(<STDIN>) {
+ $Param->{LineCount} ++ ;
+
+ if ($Param->{ViewDate} ) {
+ if (m/^(\d{6})\s+\d{1,2}:\d\d:\d\d\s.*$/) { # get date
+ #print "# $1 #\n";
+ if ($1 == $Param->{ViewDate}) {
+ $Param->{View} = 1;
+ }
+ else {
+ $Param->{View} = 0;
+ }
+ }
+ }
+ if ($Param->{View} ) {
+ #print "->>>$_";
+
+ if (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Connect.+\s+on\s+(.*)$/i) { # get connection ID($2) and database($3)
+ #print "C-$1--$2--$3------\n";
+ RunQuery($Param);
+ if (defined $3) {
+ $Param->{CID}->{$2} = $3 ;
+ #print "DB:$Param->{CID}->{$2} .. $2 .. $3 \n";
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Connect.+$/i) { # get connection ID($2) and database($3)
+ #print "\n <<<<<<<<<<<<<<<<<<----------------------------<<<<<<<<<<<<<<<< \n";
+ #print "Connect \n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Change user .*\s+on\s+(.*)$/i) { # get connection ID($2) and database($3)
+ #print "C-$1--$2--$3------\n";
+ RunQuery($Param);
+ if (defined $3) {
+ $Param->{CID}->{$2} = $3 ;
+ #print "DB:$Param->{CID}->{$2} .. $2 .. $3 \n";
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Quit\s+$/i) { # remove connection ID($2) and querystring
+ #print "Q-$1--$2--------\n";
+ RunQuery($Param);
+ delete $Param->{CID}->{$2} ;
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(select.+)$/i) { # get connection ID($2) and querystring
+ #print "S1-$1--$2--$3------\n";
+ RunQuery($Param);
+ unless ($Param->{CID}->{$2}) {
+ #print "Error: No Database for Handle: $2 found\n";
+ }
+ else {
+ $Param->{DB}=$Param->{CID}->{$2};
+
+ my $s = "$3";
+ $s =~ s/from\s/from $Param->{DB}./i;
+ $Param->{Query}="EXPLAIN $s";
+
+ #$s =~ m/from\s+(\w+[.]\w+)/i;
+ #$Param->{tab} =$1;
+ #print "-- $Param->{tab} -- $s --\n";
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(update.+)$/i) { # get connection ID($2) and querystring
+ #print "S2--$1--$2--$3------\n";
+ RunQuery($Param);
+ unless ($Param->{CID}->{$2}) {
+ #print "Error: No Database for Handle: $2 found\n";
+ }
+ else {
+ $Param->{DB}=$Param->{CID}->{$2};
+
+ my $ud = $3;
+ $ud =~ m/^update\s+(\w+).+(where.+)$/i;
+ $Param->{Query} ="EXPLAIN SELECT * FROM $1 $2";
+ $Param->{Query} =~ s/from\s/from $Param->{DB}./i;
+
+ #$Param->{Query} =~ m/from\s+(\w+[.]\w+)/i;
+ #$Param->{tab} =$1;
+ }
+ }
+
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Statistics\s+(.*)$/i) { # get connection ID($2) and info?
+ $Param->{Statistics} ++;
+ #print "Statistics--$1--$2--$3------\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Query\s+(.+)$/i) { # get connection ID($2)
+ $Param->{QueryCount} ++;
+ #print "Query-NULL $3\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Refresh\s+(.+)$/i) { # get connection ID($2)
+ $Param->{Refresh} ++;
+ #print "Refresh\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Init\s+(.+)$/i) { # get connection ID($2)
+ $Param->{Init} ++;
+ #print "Init $3\n";
+ RunQuery($Param);
+ }
+ elsif (m/^(\d{6}\s+\d{1,2}:\d\d:\d\d\s+|\s+)(\d+)\s+Field\s+(.+)$/i) { # get connection ID($2)
+ $Param->{Field} ++;
+ #print "Field $3\n";
+ RunQuery($Param);
+ }
+
+ elsif (m/^\s+(.+)$/ ) { # command could be some lines ...
+ #print "multi-lined ($1)\n";
+ my ($A)=$1;
+ chomp $A;
+ $Param->{Query} .= " $1";
+ #print "multi-lined ($1)<<$Param->{Query}>>\n";
+ }
+
+
+ }
+
+ }
+
+ $Param->{dbh}->disconnect();
+
+ if (1 == 0) {
+ print "\nunclosed handles----------------------------------------\n";
+ my $count=0;
+ foreach (sort keys %{$Param->{CID}}) {
+ print "$count | $_ : $Param->{CID}->{$_} \n";
+ $count ++;
+ }
+ }
+
+ print "\nIndex usage ------------------------------------\n";
+ foreach my $t (sort keys %{$Param->{Data}}) {
+ print "\nTable\t$t: ---\n";
+ foreach my $k (sort keys %{$Param->{Data}->{$t}}) {
+ print " count\t$k:\n";
+ my %h = %{$Param->{Data}->{$t}->{$k}};
+ foreach (sort {$h{$a} <=> $h{$b}} keys %h) {
+ print " $Param->{Data}->{$t}->{$k}->{$_}\t$_\n";
+ }
+ }
+ }
+
+ $Param->{AllCount}=0;
+ print "\nQueries causing table scans -------------------\n\n";
+ foreach (@{$Param->{ALL}}) {
+ $Param->{AllCount} ++;
+ print "$_\n";
+ }
+ print "Sum: $Param->{AllCount} table scans\n";
+
+ print "\nSummary ---------------------------------------\n\n";
+ print "Select: \t$Param->{SelectCount} queries\n";
+ print "Update: \t$Param->{UpdateCount} queries\n";
+ print "\n";
+
+ print "Init: \t$Param->{Init} times\n";
+ print "Field: \t$Param->{Field} times\n";
+ print "Refresh: \t$Param->{Refresh} times\n";
+ print "Query: \t$Param->{QueryCount} times\n";
+ print "Statistics:\t$Param->{Statistics} times\n";
+ print "\n";
+
+ print "Logfile: \t$Param->{LineCount} lines\n";
+ print "Started: \t".localtime($Param->{Start})."\n";
+ print "Finished: \t".localtime(time)."\n";
+
+ }
+}
+
+
+###########################################################################
+#
+#
+#
+sub RunQuery {
+ my $Param = shift ;
+
+ if (defined $Param->{Query}) {
+ if (defined $Param->{DB} ) {
+
+ $Param->{Query} =~ m/from\s+(\w+[.]\w+|\w+)/i;
+ $Param->{tab} =$1;
+ #print "||$Param->{tab} -- $Param->{Query}\n";
+
+ my $sth=$Param->{dbh}->prepare("USE $Param->{DB}");
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ $sth->execute();
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ $sth->finish();
+
+ $sth=$Param->{dbh}->prepare($Param->{Query});
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ #print "$Param->{Query}\n";
+ $sth->execute();
+ if (DBI::err()) {
+ if ($Param->{PrintError}) {print "[$Param->{LineCount}]<<$Param->{Query}>>\n";}
+ if ($Param->{PrintError}) {print "Error: ".DBI::errstr()."\n";}
+ }
+ else {
+ my $row = undef;
+ while ($row = $sth->fetchrow_hashref()) {
+ $Param->{SelectCount} ++;
+
+ if (defined $row->{Comment}) {
+ push (@{$Param->{Comment}}, "$row->{Comment}; $_; $Param->{DB}; $Param->{Query}");
+ }
+ foreach (@{$Param->{Rows}}) {
+ if (defined $row->{$_}) {
+ #if (($_ eq 'type' ) and ($row->{$_} eq 'ALL')) {
+ if ($row->{type} eq 'ALL') {
+ push (@{$Param->{ALL}}, "$Param->{Query}");
+ #print ">> $row->{$_} $_ $Param->{DB} $Param->{Query}\n";
+ }
+ $Param->{IdxUseCount} ++;
+ $Param->{Data}->{$Param->{tab}}->{$_}->{$row->{$_}} ++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ $sth->finish();
+ }
+ $Param->{Query} = undef ;
+ }
+}
+
+###########################################################################
+#
+#
+#
+sub ShowOptions {
+ print <<EOF;
+Usage: $0 [OPTIONS] < LOGFILE
+
+--date=YYMMDD select only entrys of date
+-d=YYMMDD
+--host=HOSTNAME db-host to ask
+-h=HOSTNAME
+--user=USERNAME db-user
+-u=USERNAME
+--password=PASSWORD password of db-user
+-p=PASSWORD
+--socket=SOCKET mysqld socket file to connect
+-s=SOCKET
+
+Read logfile from STDIN an try to EXPLAIN all SELECT statements. All UPDATE statements are rewritten to an EXPLAIN SELECT statement. The results of the EXPLAIN statement are collected and counted. All results with type=ALL are collected in an separete list. Results are printed to STDOUT.
+
+EOF
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+explain_log.pl
+
+Feed a mysqld general logfile (created with mysqld --log) back into mysql
+and collect statistics about index usage with EXPLAIN.
+
+=head1 DISCUSSION
+
+To optimize your indices, you have to know which ones are actually
+used and what kind of queries are causing table scans. Especially
+if you are generating your queries dynamically and you have a huge
+amount of queries going on, this isn't easy.
+
+Use this tool to take a look at the effects of your real life queries.
+Then add indices to avoid table scans and remove those which aren't used.
+
+=head1 USAGE
+
+explain_log.pl [--date=YYMMDD] --host=dbhost] [--user=dbuser] [--password=dbpw] [--socket=/path/to/socket] < logfile
+
+--date=YYMMDD select only entrys of date
+
+-d=YYMMDD
+
+--host=HOSTNAME db-host to ask
+
+-h=HOSTNAME
+
+--user=USERNAME db-user
+
+-u=USERNAME
+
+--password=PASSWORD password of db-user
+
+-p=PASSWORD
+
+--socket=SOCKET change path to the socket
+
+-s=SOCKET
+
+=head1 EXAMPLE
+
+explain_log.pl --host=localhost --user=foo --password=bar < /var/lib/mysql/mobile.log
+
+=head1 AUTHORS
+
+ Stefan Nitz
+ Jan Willamowius <jan@mobile.de>, http://www.mobile.de
+ Dennis Haney <davh@davh.dk> (Added socket support)
+
+=head1 RECRUITING
+
+If you are looking for a MySQL or Perl job, take a look at http://www.mobile.de
+and send me an email with your resume (you must be speaking German!).
+
+=head1 SEE ALSO
+
+mysql documentation
+
+=cut
diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh
index 1677eaf5f32..7ba42e560bb 100644
--- a/scripts/mysql_fix_privilege_tables.sh
+++ b/scripts/mysql_fix_privilege_tables.sh
@@ -1,5 +1,22 @@
#!/bin/sh
+root_password="$1"
+host="localhost"
+user="root"
+
+if test -z "$1" ; then
+ cmd="@bindir@/mysql -f --user=$user --host=$host mysql"
+else
+ root_password="$1"
+ cmd="@bindir@/mysql -f --user=$user --password=$root_password --host=$host mysql"
+fi
+
+# Debian addition
+if [ "$1" = "--sql-only" ]; then
+ root_password=""
+ cmd="/usr/share/mysql/echo_stderr"
+fi
+
echo "This scripts updates the mysql.user, mysql.db, mysql.host and the"
echo "mysql.func tables to MySQL 3.22.14 and above."
echo ""
@@ -9,15 +26,16 @@ echo ""
echo "If you get 'Access denied' errors, you should run this script again"
echo "and give the MySQL root user password as an argument!"
-host="localhost"
-user="root"
+echo "Converting all privilege tables to MyISAM format"
+$cmd <<END_OF_DATA
+ALTER TABLE user type=MyISAM;
+ALTER TABLE db type=MyISAM;
+ALTER TABLE host type=MyISAM;
+ALTER TABLE func type=MyISAM;
+ALTER TABLE columns_priv type=MyISAM;
+ALTER TABLE tables_priv type=MyISAM;
+END_OF_DATA
-if test -z $1 ; then
- cmd="@bindir@/mysql -f --user=$user --host=$host mysql"
-else
- root_password="$1"
- cmd="@bindir@/mysql -f --user=$user --password=$root_password --host=$host mysql"
-fi
# Fix old password format, add File_priv and func table
echo ""
@@ -64,6 +82,21 @@ END_OF_DATA
fi
#
+# The second alter changes ssl_type to new 4.0.2 format
+
+echo "Adding columns needed by GRANT .. REQUIRE (openssl)"
+echo "You can ignore any Duplicate column errors"
+$cmd <<END_OF_DATA
+ALTER TABLE user
+ADD ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL,
+ADD ssl_cipher BLOB NOT NULL,
+ADD x509_issuer BLOB NOT NULL,
+ADD x509_subject BLOB NOT NULL;
+ALTER TABLE user MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL;
+END_OF_DATA
+echo ""
+
+#
# Create tables_priv and columns_priv if they don't exists
#
@@ -98,11 +131,12 @@ END_OF_DATA
#
echo "Changing name of columns_priv.Type -> columns_priv.Column_priv"
-echo "You can ignore any errors from this"
+echo "You can ignore any Unknown column errors from this"
$cmd <<END_OF_DATA
ALTER TABLE columns_priv change Type Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL;
END_OF_DATA
+echo ""
#
# Add the new 'type' column to the func table.
@@ -114,3 +148,56 @@ echo "You can ignore any Duplicate column errors"
$cmd <<EOF
alter table func add type enum ('function','aggregate') NOT NULL;
EOF
+echo ""
+
+#
+# Change the user,db and host tables to MySQL 4.0 format
+#
+
+echo "Adding new fields used by MySQL 4.0.2 to the privilege tables"
+echo "You can ignore any Duplicate column errors"
+
+$cmd <<END_OF_DATA
+alter table user
+add Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER alter_priv,
+add Super_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Show_db_priv,
+add Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Super_priv,
+add Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_tmp_table_priv,
+add Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Lock_tables_priv,
+add Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Execute_priv,
+add Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Repl_slave_priv;
+END_OF_DATA
+
+if test $? -eq "0"
+then
+ # Convert privileges so that users have similar privileges as before
+ echo ""
+ echo "Updating new privileges in MySQL 4.0.2 from old ones"
+ $cmd <<END_OF_DATA
+ update user set show_db_priv= select_priv, super_priv=process_priv, execute_priv=process_priv, create_tmp_table_priv='Y', Lock_tables_priv='Y', Repl_slave_priv=file_priv, Repl_client_priv=file_priv where user<>"";
+END_OF_DATA
+ echo ""
+fi
+
+# Add fields that can be used to limit number of questions and connections
+# for some users.
+
+$cmd <<END_OF_DATA
+alter table user
+add max_questions int(11) NOT NULL AFTER x509_subject,
+add max_updates int(11) unsigned NOT NULL AFTER max_questions,
+add max_connections int(11) unsigned NOT NULL AFTER max_updates;
+END_OF_DATA
+
+#
+# Add Create_tmp_table_priv and Lock_tables_priv to db and host
+#
+
+$cmd <<END_OF_DATA
+alter table db
+add Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,
+add Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL;
+alter table host
+add Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,
+add Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL;
+END_OF_DATA
diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql
new file mode 100644
index 00000000000..2ea2e5b7373
--- /dev/null
+++ b/scripts/mysql_fix_privilege_tables.sql
@@ -0,0 +1,137 @@
+-- This script converts any old privilege tables to privilege tables suitable
+-- for MySQL 4.0.
+
+-- You can safely ignore all 'Duplicate column' and 'Unknown column' errors"
+-- as this just means that your tables where already up to date.
+-- This script is safe to run even if your tables are already up to date!
+
+-- On unix, you should use the mysql_fix_privilege_tables script to execute
+-- this sql script.
+-- On windows you should do 'mysql --force < mysql_fix_privilege_tables.sql'
+
+USE mysql;
+ALTER TABLE user type=MyISAM;
+ALTER TABLE db type=MyISAM;
+ALTER TABLE host type=MyISAM;
+ALTER TABLE func type=MyISAM;
+ALTER TABLE columns_priv type=MyISAM;
+ALTER TABLE tables_priv type=MyISAM;
+ALTER TABLE user change Password Password char(41) not null;
+ALTER TABLE user add File_priv enum('N','Y') NOT NULL;
+CREATE TABLE IF NOT EXISTS func (
+ name char(64) DEFAULT '' NOT NULL,
+ ret tinyint(1) DEFAULT '0' NOT NULL,
+ dl char(128) DEFAULT '' NOT NULL,
+ type enum ('function','aggregate') NOT NULL,
+ PRIMARY KEY (name)
+);
+
+-- Detect whether or not we had the Grant_priv column
+SET @hadGrantPriv:=0;
+SELECT @hadGrantPriv:=1 FROM user WHERE Grant_priv LIKE '%';
+
+ALTER TABLE user add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL;
+ALTER TABLE host add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL;
+ALTER TABLE db add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL;
+
+--- Fix privileges for old tables
+UPDATE user SET Grant_priv=File_priv,References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0;
+UPDATE db SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0;
+UPDATE host SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0;
+
+
+--
+-- The second alter changes ssl_type to new 4.0.2 format
+-- Adding columns needed by GRANT .. REQUIRE (openssl)"
+
+ALTER TABLE user
+ADD ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL,
+ADD ssl_cipher BLOB NOT NULL,
+ADD x509_issuer BLOB NOT NULL,
+ADD x509_subject BLOB NOT NULL;
+ALTER TABLE user MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL;
+
+--
+-- Create tables_priv and columns_priv if they don't exists
+--
+
+CREATE TABLE IF NOT EXISTS tables_priv (
+ Host char(60) DEFAULT '' NOT NULL,
+ Db char(60) DEFAULT '' NOT NULL,
+ User char(16) DEFAULT '' NOT NULL,
+ Table_name char(60) DEFAULT '' NOT NULL,
+ Grantor char(77) DEFAULT '' NOT NULL,
+ Timestamp timestamp(14),
+ Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL,
+ Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,
+ PRIMARY KEY (Host,Db,User,Table_name)
+);
+
+CREATE TABLE IF NOT EXISTS columns_priv (
+ Host char(60) DEFAULT '' NOT NULL,
+ Db char(60) DEFAULT '' NOT NULL,
+ User char(16) DEFAULT '' NOT NULL,
+ Table_name char(60) DEFAULT '' NOT NULL,
+ Column_name char(59) DEFAULT '' NOT NULL,
+ Timestamp timestamp(14),
+ Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,
+ PRIMARY KEY (Host,Db,User,Table_name,Column_name)
+);
+
+
+--
+-- Name change of Type -> Column_priv from MySQL 3.22.12
+--
+
+ALTER TABLE columns_priv change Type Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL;
+
+
+--
+-- Add the new 'type' column to the func table.
+--
+
+ALTER TABLE func add type enum ('function','aggregate') NOT NULL;
+
+--
+-- Change the user,db and host tables to MySQL 4.0 format
+--
+
+# Detect whether we had Show_db_priv
+SET @hadShowDbPriv:=0;
+SELECT @hadShowDbPriv:=1 FROM user WHERE Show_db_priv LIKE '%';
+
+ALTER TABLE user
+ADD Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Alter_priv,
+ADD Super_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Show_db_priv,
+ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Super_priv,
+ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_tmp_table_priv,
+ADD Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Lock_tables_priv,
+ADD Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Execute_priv,
+ADD Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Repl_slave_priv;
+
+
+-- Convert privileges so that users have similar privileges as before
+
+UPDATE user SET Show_db_priv= Select_priv, Super_priv=Process_priv, Execute_priv=Process_priv, Create_tmp_table_priv='Y', Lock_tables_priv='Y', Repl_slave_priv=file_priv, Repl_client_priv=File_priv where user<>"" AND @hadShowDbPriv = 0;
+
+
+-- Add fields that can be used to limit number of questions and connections
+-- for some users.
+
+ALTER TABLE user
+ADD max_questions int(11) NOT NULL AFTER x509_subject,
+ADD max_updates int(11) unsigned NOT NULL AFTER max_questions,
+ADD max_connections int(11) unsigned NOT NULL AFTER max_updates;
+
+
+--
+-- Add Create_tmp_table_priv and Lock_tables_priv to db and host
+--
+
+ALTER TABLE db
+ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,
+ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL;
+ALTER TABLE host
+ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,
+ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL;
+
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 850432fecc7..6d6bacd831e 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 1997, 1998, 1999 TCX DataKonsult AB & Monty Program KB & Detron HB
+# Copyright (C) 2002 MySQL AB
# For a more info consult the file COPYRIGHT distributed with this file.
# This scripts creates the privilege tables db, host, user, tables_priv,
@@ -37,6 +37,7 @@ parse_arguments() {
--basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
--ldata=*|--datadir=*) ldata=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
--user=*) user=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
+ --skip-name-resolve) ip_only=1 ;;
*)
if test -n "$pick_args"
then
@@ -96,7 +97,7 @@ mdata=$ldata/mysql
if test ! -x $execdir/mysqld
then
- if test "$IN_RPM" -eq 1
+ if test "$IN_RPM" = "1"
then
echo "FATAL ERROR $execdir/mysqld not found!"
exit 1
@@ -107,10 +108,11 @@ then
fi
fi
-hostname=`@HOSTNAME@` # Install this too in the user table
+# Try to determine the hostname
+hostname=`@HOSTNAME@`
# Check if hostname is valid
-if test "$IN_RPM" -eq 0 -a $force -eq 0
+if test "$IN_RPM" = "0" -a $force = "0"
then
resolved=`$bindir/resolveip $hostname 2>&1`
if [ $? -ne 0 ]
@@ -118,7 +120,8 @@ then
resolved=`$bindir/resolveip localhost 2>&1`
if [ $? -eq 0 ]
then
- echo "Sorry, the host '$hostname' could not be looked up."
+ echo "Neither host '$hostname' and 'localhost' could not be looked up with"
+ echo "$bindir/resolveip"
echo "Please configure the 'hostname' command to return a correct hostname."
echo "If you want to solve this at a later stage, restart this script with"
echo "the --force option"
@@ -126,23 +129,26 @@ then
fi
echo "WARNING: The host '$hostname' could not be looked up with resolveip."
echo "This probably means that your libc libraries are not 100 % compatible"
- echo "with this binary MySQL version. The MySQL deamon, mysqld, should work"
+ echo "with this binary MySQL version. The MySQL daemon, mysqld, should work"
echo "normally with the exception that host name resolving will not work."
echo "This means that you should use IP addresses instead of hostnames"
echo "when specifying MySQL privileges !"
fi
fi
-# Create database directories mysql & test
-if test "$IN_RPM" -eq 0
+if test "$ip_only" = "1"
then
+ ip=`echo "$resolved" | awk '/ /{print $6}'`
+ hostname=$ip
+fi
+
+# Create database directories mysql & test
if test ! -d $ldata; then mkdir $ldata; chmod 700 $ldata ; fi
if test ! -d $ldata/mysql; then mkdir $ldata/mysql; chmod 700 $ldata/mysql ; fi
if test ! -d $ldata/test; then mkdir $ldata/test; chmod 700 $ldata/test ; fi
if test -w / -a ! -z "$user"; then
chown $user $ldata $ldata/mysql $ldata/test;
fi
-fi
# Initialize variables
c_d="" i_d=""
@@ -171,13 +177,15 @@ then
c_d="$c_d References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_d="$c_d Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_d="$c_d Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_d="$c_d PRIMARY KEY Host (Host,Db,User),"
c_d="$c_d KEY User (User)"
c_d="$c_d )"
c_d="$c_d comment='Database privileges';"
- i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y');
- INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y');"
+ i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
+ INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');"
fi
if test ! -f $mdata/host.frm
@@ -197,6 +205,8 @@ then
c_h="$c_h References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_h="$c_h Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_h="$c_h Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_h="$c_h PRIMARY KEY Host (Host,Db)"
c_h="$c_h )"
c_h="$c_h comment='Host privileges; Merged with database privileges';"
@@ -224,18 +234,32 @@ then
c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Super_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL,"
+ c_u="$c_u ssl_cipher BLOB NOT NULL,"
+ c_u="$c_u x509_issuer BLOB NOT NULL,"
+ c_u="$c_u x509_subject BLOB NOT NULL,"
+ c_u="$c_u max_questions int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_updates int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_connections int(11) unsigned DEFAULT 0 NOT NULL,"
c_u="$c_u PRIMARY KEY Host (Host,User)"
c_u="$c_u )"
c_u="$c_u comment='Users and global privileges';"
- i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
- INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
+ i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
- REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
- REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
+ REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
- INSERT INTO user VALUES ('localhost','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');
- INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');"
+ INSERT INTO user (host,user) values ('localhost','');
+ INSERT INTO user (host,user) values ('$hostname','');"
fi
if test ! -f $mdata/func.frm
@@ -290,7 +314,7 @@ fi
echo "Installing all prepared tables"
if eval "$execdir/mysqld $defaults --bootstrap --skip-grant-tables \
- --basedir=$basedir --datadir=$ldata --skip-innodb --skip-gemini --skip-bdb $args" << END_OF_DATA
+ --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $args" << END_OF_DATA
use mysql;
$c_d
$i_d
@@ -309,16 +333,16 @@ $c_c
END_OF_DATA
then
echo ""
- if test "$IN_RPM" -eq 0
+ if test "$IN_RPM" = "0"
then
echo "To start mysqld at boot time you have to copy support-files/mysql.server"
echo "to the right place for your system"
echo
fi
echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !"
- echo "This is done with:"
- echo "$bindir/mysqladmin -u root password 'new-password'"
- echo "$bindir/mysqladmin -u root -h $hostname password 'new-password'"
+ echo "To do so, start the server, then issue the following commands:"
+ echo "$bindir/mysqladmin -u root password 'new-password'"
+ echo "$bindir/mysqladmin -u root -h $hostname password 'new-password'"
echo "See the manual for more instructions."
#
# Print message about upgrading unless we have created a new db table.
@@ -330,13 +354,13 @@ then
echo "able to use the new GRANT command!"
fi
echo
- if test "$IN_RPM" -eq 0
+ if test "$IN_RPM" = "0"
then
echo "You can start the MySQL daemon with:"
- echo "cd @prefix@ ; $bindir/safe_mysqld &"
+ echo "cd @prefix@ ; $bindir/mysqld_safe &"
echo
echo "You can test the MySQL daemon with the benchmarks in the 'sql-bench' directory:"
- echo "cd sql-bench ; run-all-tests"
+ echo "cd sql-bench ; perl run-all-tests"
echo
fi
echo "Please report any problems with the @scriptdir@/mysqlbug script!"
diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh
new file mode 100644
index 00000000000..1c7ca34ad59
--- /dev/null
+++ b/scripts/mysql_secure_installation.sh
@@ -0,0 +1,312 @@
+#!/bin/sh
+
+# Copyright (C) 2002 MySQL AB and Jeremy Cole
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+config=".my.cnf.$$"
+command=".mysql.$$"
+
+trap "interrupt" 2
+
+rootpass=""
+
+prepare() {
+ touch $config $command
+ chmod 600 $config $command
+}
+
+do_query() {
+ echo $1 >$command
+ mysql --defaults-file=$config <$command
+ return $?
+}
+
+make_config() {
+ echo "# mysql_secure_installation config file" >$config
+ echo "[mysql]" >>$config
+ echo "user=root" >>$config
+ echo "password=$rootpass" >>$config
+}
+
+get_root_password() {
+ status=1
+ while [ $status -eq 1 ]; do
+ stty -echo
+ echo -n "Enter current password for root (enter for none): "
+ read password
+ echo
+ stty echo
+ if [ "x$password" = "x" ]; then
+ hadpass=0
+ else
+ hadpass=1
+ fi
+ rootpass=$password
+ make_config
+ do_query ""
+ status=$?
+ done
+ echo "OK, successfully used password, moving on..."
+ echo
+}
+
+set_root_password() {
+ stty -echo
+ echo -n "New password: "
+ read password1
+ echo
+ echo -n "Re-enter new password: "
+ read password2
+ echo
+ stty echo
+
+ if [ "$password1" != "$password2" ]; then
+ echo "Sorry, passwords do not match."
+ echo
+ return 1
+ fi
+
+ if [ "$password1" = "" ]; then
+ echo "Sorry, you can't use an empty password here."
+ echo
+ return 1
+ fi
+
+ do_query "UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';"
+ if [ $? -eq 0 ]; then
+ echo "Password updated successfully!"
+ echo "Reloading privilege tables.."
+ if ! reload_privilege_tables; then
+ exit 1
+ fi
+ echo
+ rootpass=$password1
+ make_config
+ else
+ echo "Password update failed!"
+ exit 1
+ fi
+
+ return 0
+}
+
+remove_anonymous_users() {
+ do_query "DELETE FROM mysql.user WHERE User='';"
+ if [ $? -eq 0 ]; then
+ echo " ... Success!"
+ else
+ echo " ... Failed!"
+ exit 1
+ fi
+
+ return 0
+}
+
+remove_remote_root() {
+ do_query "DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';"
+ if [ $? -eq 0 ]; then
+ echo " ... Success!"
+ else
+ echo " ... Failed!"
+ fi
+}
+
+remove_test_database() {
+ echo " - Dropping test database..."
+ do_query "DROP DATABASE test;"
+ if [ $? -eq 0 ]; then
+ echo " ... Success!"
+ else
+ echo " ... Failed! Not critical, keep moving..."
+ fi
+
+ echo " - Removing privileges on test database..."
+ do_query "DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'"
+ if [ $? -eq 0 ]; then
+ echo " ... Success!"
+ else
+ echo " ... Failed! Not critical, keep moving..."
+ fi
+
+ return 0
+}
+
+reload_privilege_tables() {
+ do_query "FLUSH PRIVILEGES;"
+ if [ $? -eq 0 ]; then
+ echo " ... Success!"
+ return 0
+ else
+ echo " ... Failed!"
+ return 1
+ fi
+}
+
+interrupt() {
+ echo
+ echo "Aborting!"
+ echo
+ cleanup
+ stty echo
+ exit 1
+}
+
+cleanup() {
+ echo "Cleaning up..."
+ rm -f $config $command
+}
+
+
+# The actual script starts here
+
+prepare
+
+echo
+echo
+echo
+echo
+echo "NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL"
+echo " SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!"
+echo
+echo
+
+echo "In order to log into MySQL to secure it, we'll need the current"
+echo "password for the root user. If you've just installed MySQL, and"
+echo "you haven't set the root password yet, the password will be blank,"
+echo "so you should just press enter here."
+echo
+
+get_root_password
+
+
+#
+# Set the root password
+#
+
+echo "Setting the root password ensures that nobody can log into the MySQL"
+echo "root user without the proper authorisation."
+echo
+
+if [ $hadpass -eq 0 ]; then
+ echo -n "Set root password? [Y/n] "
+else
+ echo "You already have a root password set, so you can safely answer 'n'."
+ echo
+ echo -n "Change the root password? [Y/n] "
+fi
+
+read reply
+if [ "$reply" = "n" ]; then
+ echo " ... skipping."
+else
+ status=1
+ while [ $status -eq 1 ]; do
+ set_root_password
+ status=$?
+ done
+fi
+echo
+
+
+#
+# Remove anonymous users
+#
+
+echo "By default, a MySQL installation has an anonymous user, allowing anyone"
+echo "to log into MySQL without having to have a user account created for"
+echo "them. This is intended only for testing, and to make the installation"
+echo "go a bit smoother. You should remove them before moving into a"
+echo "production environment."
+echo
+
+echo -n "Remove anonymous users? [Y/n] "
+
+read reply
+if [ "$reply" = "n" ]; then
+ echo " ... skipping."
+else
+ remove_anonymous_users
+fi
+echo
+
+
+#
+# Disallow remote root login
+#
+
+echo "Normally, root should only be allowed to connect from 'localhost'. This"
+echo "ensures that someone cannot guess at the root password from the network."
+echo
+
+echo -n "Disallow root login remotely? [Y/n] "
+read reply
+if [ "$reply" = "n" ]; then
+ echo " ... skipping."
+else
+ remove_remote_root
+fi
+echo
+
+
+#
+# Remove test database
+#
+
+echo "By default, MySQL comes with a database named 'test' that anyone can"
+echo "access. This is also intended only for testing, and should be removed"
+echo "before moving into a production environment."
+echo
+
+echo -n "Remove test database and access to it? [Y/n] "
+read reply
+if [ "$reply" = "n" ]; then
+ echo " ... skipping."
+else
+ remove_test_database
+fi
+echo
+
+
+#
+# Reload privilege tables
+#
+
+echo "Reloading the privilege tables will ensure that all changes made so far"
+echo "will take effect immediately."
+echo
+
+echo -n "Reload privilege tables now? [Y/n] "
+read reply
+if [ "$reply" = "n" ]; then
+ echo " ... skipping."
+else
+ reload_privilege_tables
+fi
+echo
+
+cleanup
+
+echo
+echo
+echo
+echo "All done! If you've completed all of the above steps, your MySQL"
+echo "installation should now be secure."
+echo
+echo "Thanks for using MySQL!"
+echo
+echo
+
+
diff --git a/scripts/mysql_setpermission.sh b/scripts/mysql_setpermission.sh
index 43bf8a14c06..9699cd28047 100644
--- a/scripts/mysql_setpermission.sh
+++ b/scripts/mysql_setpermission.sh
@@ -16,20 +16,25 @@
## 1.2 begin screen now in a loop + quit is using 0 instead of 9
## after ideas of Paul DuBois.
## 1.2a Add Grant, References, Index and Alter privilege handling (Monty)
+## 1.3 Applied patch provided by Martin Mokrejs <mmokrejs@natur.cuni.cz>
+## (General code cleanup, use the GRANT statement instead of updating
+## the privilege tables directly, added option to revoke privileges)
#### TODO
#
# empty ... suggestions ... mail them to me ...
-$version="1.2";
+$version="1.3";
use DBI;
use Getopt::Long;
use strict;
-use vars qw($dbh $hostname $opt_user $opt_password $opt_help $opt_host
+use vars qw($dbh $sth $hostname $opt_user $opt_password $opt_help $opt_host
$opt_socket $opt_port $host $version);
+my $sqlhost = "";
+my $user = "";
$dbh=$host=$opt_user= $opt_password= $opt_help= $opt_host= $opt_socket= "";
$opt_port=0;
@@ -42,11 +47,11 @@ usage() if ($opt_help); # the help function
if ($opt_host eq '')
{
- $hostname = "localhost";
+ $sqlhost = "localhost";
}
else
{
- $hostname = $opt_host;
+ $sqlhost = $opt_host;
}
# ask for a password if no password is set already
@@ -62,7 +67,7 @@ if ($opt_password eq '')
# make the connection to MySQL
-$dbh= DBI->connect("DBI:mysql:mysql:host=$hostname:port=$opt_port:mysql_socket=$opt_socket",$opt_user,$opt_password, {PrintError => 0}) ||
+$dbh= DBI->connect("DBI:mysql:mysql:host=$sqlhost:port=$opt_port:mysql_socket=$opt_socket",$opt_user,$opt_password, {PrintError => 0}) ||
die("Can't make a connection to the mysql server.\n The error: $DBI::errstr");
# the start of the program
@@ -86,27 +91,44 @@ sub q1 { # first question ...
print "#"x70;
print "\n";
print "What would you like to do:\n";
- print " 1. Set password for a user.\n";
- print " 2. Add a database + user privilege for that database.\n";
- print " - user can do all except all admin functions\n";
- print " 3. Add user privilege for an existing database.\n";
- print " - user can do all except all admin functions\n";
- print " 4. Add user privilege for an existing database.\n";
- print " - user can do all except all admin functions + no create/drop\n";
- print " 5. Add user privilege for an existing database.\n";
- print " - user can do only selects (no update/delete/insert etc.)\n";
+ print " 1. Set password for an existing user.\n";
+ print " 2. Create a database + user privilege for that database\n";
+ print " and host combination (user can only do SELECT)\n";
+ print " 3. Create/append user privilege for an existing database\n";
+ print " and host combination (user can only do SELECT)\n";
+ print " 4. Create/append broader user privileges for an existing\n";
+ print " database and host combination\n";
+ print " (user can do SELECT,INSERT,UPDATE,DELETE)\n";
+ print " 5. Create/append quite extended user privileges for an\n";
+ print " existing database and host combination (user can do\n";
+ print " SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,\n";
+ print " LOCK TABLES,CREATE TEMPORARY TABLES)\n";
+ print " 6. Create/append database administrative privileges for an\n";
+ print " existing database and host combination (user can do\n";
+ print " SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,LOCK TABLES,\n";
+ print " CREATE TEMPORARY TABLES,SHOW DATABASES,PROCESS)\n";
+ print " 7. Create/append full privileges for an existing database\n";
+ print " and host combination (user has FULL privilege)\n";
+ print " 8. Remove all privileges for for an existing database and\n";
+ print " host combination.\n";
+ print " (user will have all permission fields set to N)\n";
print " 0. exit this program\n";
- print "\nMake your choice [1,2,3,4,5,0]: ";
+ print "\nMake your choice [1,2,3,4,5,6,7,0]: ";
while (<STDIN>) {
$answer = $_;
chomp($answer);
- if ($answer =~ /1|2|3|4|5|0/) {
- &setpwd if ($answer == 1);
- &addall($answer) if ($answer =~ /^[2345]$/);
- if ($answer == 0) {
- print "Sorry, hope we can help you next time \n\n";
+ if ($answer =~ /^[12345678]$/) {
+ if ($answer == 1) {
+ setpwd();
+ } elsif ($answer =~ /^[2345678]$/) {
+ addall($answer);
+ } else {
+ print "Sorry, something went wrong. With such option number you should not get here.\n\n";
$end = 1;
}
+ } elsif ($answer == 0) {
+ print "We hope we can help you next time \n\n";
+ $end = 1;
} else {
print "Your answer was $answer\n";
print "and that's wrong .... Try again\n";
@@ -121,7 +143,7 @@ sub q1 { # first question ...
###
sub setpwd
{
- my ($user,$pass,$host);
+ my ($user,$pass,$host) = "";
print "\n\nSetting a (new) password for a user.\n";
$user = user();
@@ -168,22 +190,18 @@ sub setpwd
###
# all things which will be added are done here
###
-sub addall
-{
+sub addall {
my ($todo) = @_;
my ($answer,$good,$db,$user,$pass,$host,$priv);
- if ($todo == 2)
- {
+ if ($todo == 2) {
$db = newdatabase();
- }
- else
- {
+ } else {
$db = database();
}
$user = newuser();
- $pass = newpass();
+ $pass = newpass("$user");
$host = newhosts();
print "#"x70;
@@ -198,104 +216,80 @@ sub addall
print "Are you pretty sure you would like to implement this [yes/no]: ";
my $no = <STDIN>;
chomp($no);
- if ($no =~ /n/i)
- {
+ if ($no =~ /n/i) {
print "Okay .. that was it then ... See ya\n\n";
return(0);
- }
- else
- {
+ } else {
print "Okay ... let's go then ...\n\n";
}
- if ($todo == 2)
- {
+ if ($todo == 2) {
# create the database
- my $sth = $dbh->do("create database $db") || $dbh->errstr;
- }
-
- # select the privilege ....
- if (($todo == 2) || ($todo == 3))
- {
- $priv = "'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'";
+ if ($db) {
+ my $sth = $dbh->do("CREATE DATABASE $db") || $dbh->errstr;
+ } else {
+ print STDERR "What do you want? You wanted to create new database and add new user, right?\n";
+ die "But then specify databasename, please\n";
}
- elsif ($todo == 4)
- {
- $priv = "'Y','Y','Y','Y','N','N','N','Y','Y','Y'";
}
- elsif ($todo == 5)
- {
- $priv = "'Y','N','N','N','N','N','N','N','N','N'";
- }
- else
- {
- print "Sorry, choice number $todo isn't known inside the program .. See ya\n";
+
+ if ( ( !$todo ) or not ( $todo =~ m/^[2-8]$/ ) ) {
+ print STDERR "Sorry, select option $todo isn't known inside the program .. See ya\n";
quit();
}
my @hosts = split(/,/,$host);
- $user = $dbh->quote($user);
- $db = $dbh->quote($db);
- if ($pass eq '')
- {
- $pass = "''";
+ if (!$user) {
+ die "username not specified: $user\n";
}
- else
- {
- $pass = "PASSWORD(". $dbh->quote($pass) . ")";
+ if (!$db) {
+ die "databasename is not specified nor *\n";
}
- foreach my $key (@hosts)
- {
- my $key1 = $dbh->quote($key);
- my $sth = $dbh->prepare("select Host,User from user where Host = $key1 and User = $user") || die $dbh->errstr;
- $sth->execute || die $dbh->errstr;
- my @r = $sth->fetchrow_array;
- if ($r[0])
- {
- print "WARNING WARNING SKIPPING CREATE FOR USER $user AND HOST $key\n";
- print "Reason: entry already exists in the user table.\n";
+ foreach $host (@hosts) {
+ # user privileges: SELECT
+ if (($todo == 2) || ($todo == 3)) {
+ $sth = $dbh->do("GRANT SELECT ON $db.* TO $user@\"$host\" IDENTIFIED BY \'$pass\'") || die $dbh->errstr;
+ } elsif ($todo == 4) {
+ # user privileges: SELECT,INSERT,UPDATE,DELETE
+ $sth = $dbh->do("GRANT SELECT,INSERT,UPDATE,DELETE ON $db.* TO $user@\"$host\" IDENTIFIED BY \'$pass\'") || die $dbh->errstr;
+ } elsif ($todo == 5) {
+ # user privileges: SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,LOCK TABLES,CREATE TEMPORARY TABLES
+ $sth = $dbh->do("GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,LOCK TABLES,CREATE TEMPORARY TABLES ON $db.* TO $user@\"$host\" IDENTIFIED BY \'$pass\'") || die $dbh->errstr;
+ } elsif ($todo == 6) {
+ # admin privileges: GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,LOCK TABLES,CREATE TEMPORARY TABLES,SHOW DATABASES,PROCESS
+ $sth = $dbh->do("GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,LOCK TABLES,CREATE TEMPORARY TABLES,SHOW DATABASES,PROCESS ON $db.* TO $user@\"$host\" IDENTIFIED BY \'$pass\'") || die $dbh->errstr;
+ } elsif ($todo == 7) {
+ # all privileges
+ $sth = $dbh->do("GRANT ALL ON $db.* TO \'$user\'\@\'$host\' IDENTIFIED BY \'$pass\'") || die $dbh->errstr;
+ } elsif ($todo == 8) {
+ # all privileges set to N
+ $sth = $dbh->do("REVOKE ALL ON *.* FROM \'$user\'\@\'$host\'") || die $dbh->errstr;
}
- else
- {
- $sth = $dbh->prepare("insert into user (Host,User,Password) values($key1,$user,$pass)") || die $dbh->errstr;
- $sth->execute || die $dbh->errstr;
- $sth->finish;
}
- $sth = $dbh->prepare("INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,References_priv,Index_priv,Alter_priv) VALUES ($key1,$db,$user,$priv)") || die $dbh->errstr;
- $sth->execute || die $dbh->errstr;
- $sth->finish;
- }
- $dbh->do("flush privileges") || print "Can't load privileges\n";
+ $dbh->do("FLUSH PRIVILEGES") || print STDERR "Can't flush privileges\n";
print "Everything is inserted and mysql privileges have been reloaded.\n\n";
}
###
# ask for a new database name
###
-sub newdatabase
-{
+sub newdatabase {
my ($answer,$good,$db);
print "\n\nWhich database would you like to add: ";
- while (<STDIN>)
- {
+ while (<STDIN>) {
$answer = $_;
$good = 0;
chomp($answer);
- if ($answer)
- {
- my $sth = $dbh->prepare("show databases") || die $dbh->errstr;
+ if ($answer) {
+ my $sth = $dbh->prepare("SHOW DATABASES") || die $dbh->errstr;
$sth->execute || die $dbh->errstr;
- while (my @r = $sth->fetchrow_array)
- {
- if ($r[0] eq $answer)
- {
+ while (my @r = $sth->fetchrow_array) {
+ if ($r[0] eq $answer) {
print "\n\nSorry, this database name is already in use; try something else: ";
$good = 1;
}
}
- }
- else
- {
+ } else {
print "You must type something ...\nTry again: ";
next;
}
@@ -309,48 +303,44 @@ sub newdatabase
###
# select a database
###
-sub database
-{
+sub database {
my ($answer,$good,$db);
- print "\n\nWhich database would you like to select: \n";
+ print "\n\nWhich database from existing databases would you like to select: \n";
print "You can choose from: \n";
my $sth = $dbh->prepare("show databases") || die $dbh->errstr;
$sth->execute || die $dbh->errstr;
- while (my @r = $sth->fetchrow_array)
- {
+ while (my @r = $sth->fetchrow_array) {
print " - $r[0] \n";
}
- print "Which database will it be (case sensitive): ";
- while (<STDIN>)
- {
+ print "Which database will it be (case sensitive). Type * for any: \n";
+ while (<STDIN>) {
$answer = $_;
$good = 0;
chomp($answer);
- if ($answer)
- {
+ if ($answer) {
+ if ($answer eq "*") {
+ print "OK, the user entry will NOT be limited to any database";
+ return("*");
+ }
my $sth = $dbh->prepare("show databases") || die $dbh->errstr;
$sth->execute || die $dbh->errstr;
- while (my @r = $sth->fetchrow_array)
- {
- if ($r[0] eq $answer)
- {
+ while (my @r = $sth->fetchrow_array) {
+ if ($r[0] eq $answer) {
$good = 1;
$db = $r[0];
last;
}
}
- }
- else
- {
- print "You must type something ...\nTry again: ";
+ } else {
+ print "Type either database name or * meaning any databasename. That means";
+ print " any of those above but also any which will be created in future!";
+ print " This option gives a user chance to operate on databse mysql, which";
+ print " contains privilege settings. That is really risky!\n";
next;
}
- if ($good == 1)
- {
+ if ($good == 1) {
last;
- }
- else
- {
+ } else {
print "You must select one from the list.\nTry again: ";
next;
}
@@ -364,7 +354,8 @@ sub database
###
sub newuser
{
- my ($answer,$user);
+ my $user = "";
+ my $answer = "";
print "\nWhat username is to be created: ";
while(<STDIN>)
@@ -430,7 +421,7 @@ sub user
sub newpass
{
my ($user) = @_;
- my ($answer,$good,$pass,$yes);
+ my ($pass,$answer,$good,$yes);
print "Would you like to set a password for $user [y/n]: ";
$yes = <STDIN>;
@@ -487,7 +478,7 @@ sub newpass
###
sub newhosts
{
- my ($answer,$good,$host);
+ my ($host,$answer,$good);
print "We now need to know from what host(s) the user will connect.\n";
print "Keep in mind that % means 'from any host' ...\n";
diff --git a/scripts/mysql_tableinfo.sh b/scripts/mysql_tableinfo.sh
new file mode 100644
index 00000000000..f5083a776c6
--- /dev/null
+++ b/scripts/mysql_tableinfo.sh
@@ -0,0 +1,476 @@
+#!@PERL@ -w
+
+use strict;
+use Getopt::Long;
+use DBI;
+
+=head1 NAME
+
+mysql_tableinfo - creates and populates information tables with
+the output of SHOW DATABASES, SHOW TABLES (or SHOW TABLE STATUS),
+SHOW COLUMNS and SHOW INDEX.
+
+This is version 1.1.
+
+=head1 SYNOPSIS
+
+ mysql_tableinfo [OPTIONS] database_to_write [database_like_wild] [table_like_wild]
+
+ Do not backquote (``) database_to_write,
+ and do not quote ('') database_like_wild or table_like_wild
+
+ Examples:
+
+ mysql_tableinfo info
+
+ mysql_tableinfo info this_db
+
+ mysql_tableinfo info %a% b%
+
+ mysql_tableinfo info --clear-only
+
+ mysql_tableinfo info --col --idx --table-status
+
+=cut
+
+# Documentation continued at end of file
+
+
+sub usage {
+ die @_,"\nExecute 'perldoc $0' for documentation\n";
+}
+
+my %opt = (
+ 'user' => scalar getpwuid($>),
+ 'host' => "localhost",
+ 'prefix' => "", #to avoid 'use of uninitialized value...'
+);
+Getopt::Long::Configure(qw(no_ignore_case)); # disambuguate -p and -P
+GetOptions( \%opt,
+ "help",
+ "user|u=s",
+ "password|p=s",
+ "host|h=s",
+ "port|P=s",
+ "socket|S=s",
+ "tbl-status",
+ "col",
+ "idx",
+ "clear",
+ "clear-only",
+ "prefix=s",
+ "quiet|q",
+) or usage("Invalid option");
+
+if ($opt{'help'}) {usage();}
+
+my ($db_to_write,$db_like_wild,$tbl_like_wild);
+if (@ARGV==0)
+{
+ usage("Not enough arguments");
+}
+$db_to_write="`$ARGV[0]`"; shift @ARGV;
+$db_like_wild=($ARGV[0])?$ARGV[0]:"%"; shift @ARGV;
+$tbl_like_wild=($ARGV[0])?$ARGV[0]:"%"; shift @ARGV;
+if (@ARGV>0) { usage("Too many arguments"); }
+
+$0 = $1 if $0 =~ m:/([^/]+)$:;
+
+my $info_db="`".$opt{'prefix'}."db`";
+my $info_tbl="`".$opt{'prefix'}."tbl".
+ (($opt{'tbl-status'})?"_status":"")."`";
+my $info_col="`".$opt{'prefix'}."col`";
+my $info_idx="`".$opt{'prefix'}."idx`";
+
+
+# --- connect to the database ---
+
+my $dsn = ";host=$opt{'host'}";
+$dsn .= ";port=$opt{'port'}" if $opt{'port'};
+$dsn .= ";mysql_socket=$opt{'socket'}" if $opt{'socket'};
+
+my $dbh = DBI->connect("dbi:mysql:$dsn;mysql_read_default_group=perl",
+ $opt{'user'}, $opt{'password'},
+{
+ RaiseError => 1,
+ PrintError => 0,
+ AutoCommit => 1,
+});
+
+$db_like_wild=$dbh->quote($db_like_wild);
+$tbl_like_wild=$dbh->quote($tbl_like_wild);
+
+#Ask
+
+if (!$opt{'quiet'})
+{
+ print "\n!! This program is doing to do:\n\n";
+ print "**DROP** TABLE ...\n" if ($opt{'clear'} or $opt{'clear-only'});
+ print "**DELETE** FROM ... WHERE `Database` LIKE $db_like_wild AND `Table` LIKE $tbl_like_wild
+**INSERT** INTO ...
+
+on the following tables :\n";
+
+ foreach (($info_db, $info_tbl),
+ (($opt{'col'})?$info_col:()),
+ (($opt{'idx'})?$info_idx:()))
+ {
+ print(" $db_to_write.$_\n");
+ }
+ print "\nContinue (you can skip this confirmation step with --quiet) ? (y|n) [n]";
+ if (<STDIN> !~ /^\s*y\s*$/i)
+ {
+ print "Nothing done!\n";exit;
+ }
+}
+
+if ($opt{'clear'} or $opt{'clear-only'})
+{
+#do not drop the $db_to_write database !
+ foreach (($info_db, $info_tbl),
+ (($opt{'col'})?$info_col:()),
+ (($opt{'idx'})?$info_idx:()))
+ {
+ $dbh->do("DROP TABLE IF EXISTS $db_to_write.$_");
+ }
+ if ($opt{'clear-only'})
+ {
+ print "Wrote to database $db_to_write .\n" unless ($opt{'quiet'});
+ exit;
+ }
+}
+
+
+my %sth;
+my %extra_col_desc;
+my %row;
+my %done_create_table;
+
+#create the $db_to_write database
+$dbh->do("CREATE DATABASE IF NOT EXISTS $db_to_write");
+$dbh->do("USE $db_to_write");
+
+#get databases
+$sth{'db'}=$dbh->prepare("SHOW DATABASES LIKE $db_like_wild");
+$sth{'db'}->execute;
+
+#create $info_db which will receive info about databases.
+#Ensure that the first column to be called "Database" (as SHOW DATABASES LIKE
+#returns a varying
+#column name (of the form "Database (%...)") which is not suitable)
+$extra_col_desc{'db'}=do_create_table("db",$info_db,undef,"`Database`");
+#we'll remember the type of the `Database` column (as returned by
+#SHOW DATABASES), which we will need when creating the next tables.
+
+#clear out-of-date info from this table
+$dbh->do("DELETE FROM $info_db WHERE `Database` LIKE $db_like_wild");
+
+
+while ($row{'db'}=$sth{'db'}->fetchrow_arrayref) #go through all databases
+{
+
+#insert the database name
+ $dbh->do("INSERT INTO $info_db VALUES("
+ .join(',' , ( map $dbh->quote($_), @{$row{'db'}} ) ).")" );
+
+#for each database, get tables
+
+ $sth{'tbl'}=$dbh->prepare("SHOW TABLE"
+ .( ($opt{'tbl-status'}) ?
+ " STATUS"
+ : "S" )
+ ." from `$row{'db'}->[0]` LIKE $tbl_like_wild");
+ $sth{'tbl'}->execute;
+ unless ($done_create_table{$info_tbl})
+
+#tables must be created only once, and out-of-date info must be
+#cleared once
+ {
+ $done_create_table{$info_tbl}=1;
+ $extra_col_desc{'tbl'}=
+ do_create_table("tbl",$info_tbl,
+#add an extra column (database name) at the left
+#and ensure that the table name will be called "Table"
+#(this is unncessesary with
+#SHOW TABLE STATUS, but necessary with SHOW TABLES (which returns a column
+#named "Tables_in_..."))
+ "`Database` ".$extra_col_desc{'db'},"`Table`");
+ $dbh->do("DELETE FROM $info_tbl WHERE `Database` LIKE $db_like_wild AND `Table` LIKE $tbl_like_wild");
+ }
+
+ while ($row{'tbl'}=$sth{'tbl'}->fetchrow_arrayref)
+ {
+ $dbh->do("INSERT INTO $info_tbl VALUES("
+ .$dbh->quote($row{'db'}->[0]).","
+ .join(',' , ( map $dbh->quote($_), @{$row{'tbl'}} ) ).")");
+
+#for each table, get columns...
+
+ if ($opt{'col'})
+ {
+ $sth{'col'}=$dbh->prepare("SHOW COLUMNS FROM `$row{'tbl'}->[0]` FROM `$row{'db'}->[0]`");
+ $sth{'col'}->execute;
+ unless ($done_create_table{$info_col})
+ {
+ $done_create_table{$info_col}=1;
+ do_create_table("col",$info_col,
+ "`Database` ".$extra_col_desc{'db'}.","
+ ."`Table` ".$extra_col_desc{'tbl'}.","
+ ."`Seq_in_table` BIGINT(3)");
+#We need to add a sequence number (1 for the first column of the table,
+#2 for the second etc) so that users are able to retrieve columns in order
+#if they want. This is not needed for INDEX
+#(where there is already Seq_in_index)
+ $dbh->do("DELETE FROM $info_col WHERE `Database`
+ LIKE $db_like_wild
+ AND `Table` LIKE $tbl_like_wild");
+ }
+ my $col_number=0;
+ while ($row{'col'}=$sth{'col'}->fetchrow_arrayref)
+ {
+ $dbh->do("INSERT INTO $info_col VALUES("
+ .$dbh->quote($row{'db'}->[0]).","
+ .$dbh->quote($row{'tbl'}->[0]).","
+ .++$col_number.","
+ .join(',' , ( map $dbh->quote($_), @{$row{'col'}} ) ).")");
+ }
+ }
+
+#and get index.
+
+ if ($opt{'idx'})
+ {
+ $sth{'idx'}=$dbh->prepare("SHOW INDEX FROM `$row{'tbl'}->[0]` FROM `$row{'db'}->[0]`");
+ $sth{'idx'}->execute;
+ unless ($done_create_table{$info_idx})
+ {
+ $done_create_table{$info_idx}=1;
+ do_create_table("idx",$info_idx,
+ "`Database` ".$extra_col_desc{'db'});
+ $dbh->do("DELETE FROM $info_idx WHERE `Database`
+ LIKE $db_like_wild
+ AND `Table` LIKE $tbl_like_wild");
+ }
+ while ($row{'idx'}=$sth{'idx'}->fetchrow_arrayref)
+ {
+ $dbh->do("INSERT INTO $info_idx VALUES("
+ .$dbh->quote($row{'db'}->[0]).","
+ .join(',' , ( map $dbh->quote($_), @{$row{'idx'}} ) ).")");
+ }
+ }
+ }
+}
+
+print "Wrote to database $db_to_write .\n" unless ($opt{'quiet'});
+exit;
+
+
+sub do_create_table
+{
+ my ($sth_key,$target_tbl,$extra_col_desc,$first_col_name)=@_;
+ my $create_table_query=$extra_col_desc;
+ my ($i,$first_col_desc,$col_desc);
+
+ for ($i=0;$i<$sth{$sth_key}->{NUM_OF_FIELDS};$i++)
+ {
+ if ($create_table_query) { $create_table_query.=", "; }
+ $col_desc=$sth{$sth_key}->{mysql_type_name}->[$i];
+ if ($col_desc =~ /char|int/i)
+ {
+ $col_desc.="($sth{$sth_key}->{PRECISION}->[$i])";
+ }
+ elsif ($col_desc =~ /decimal|numeric/i) #(never seen that)
+ {
+ $col_desc.=
+ "($sth{$sth_key}->{PRECISION}->[$i],$sth{$sth_key}->{SCALE}->[$i])";
+ }
+ elsif ($col_desc !~ /date/i) #date and datetime are OK,
+ #no precision or scale for them
+ {
+ warn "unexpected column type '$col_desc'
+(neither 'char','int','decimal|numeric')
+when creating $target_tbl, hope table creation will go OK\n";
+ }
+ if ($i==0) {$first_col_desc=$col_desc};
+ $create_table_query.=
+ ( ($i==0 and $first_col_name) ?
+ "$first_col_name " :"`$sth{$sth_key}->{NAME}->[$i]` " )
+ .$col_desc;
+ }
+if ($create_table_query)
+{
+ $dbh->do("CREATE TABLE IF NOT EXISTS $target_tbl ($create_table_query)");
+}
+return $first_col_desc;
+}
+
+__END__
+
+
+=head1 DESCRIPTION
+
+mysql_tableinfo asks a MySQL server information about its
+databases, tables, table columns and index, and stores this
+in tables called `db`, `tbl` (or `tbl_status`), `col`, `idx`
+(with an optional prefix specified with --prefix).
+After that, you can query these information tables, for example
+to build your admin scripts with SQL queries, like
+
+SELECT CONCAT("CHECK TABLE ",`database`,".",`table`," EXTENDED;")
+FROM info.tbl WHERE ... ;
+
+as people usually do with some other RDBMS
+(note: to increase the speed of your queries on the info tables,
+you may add some index on them).
+
+The database_like_wild and table_like_wild instructs the program
+to gather information only about databases and tables
+whose names match these patterns. If the info
+tables already exist, their rows matching the patterns are simply
+deleted and replaced by the new ones. That is,
+old rows not matching the patterns are not touched.
+If the database_like_wild and table_like_wild arguments
+are not specified on the command-line they default to "%".
+
+The program :
+
+- does CREATE DATABASE IF NOT EXISTS database_to_write
+where database_to_write is the database name specified on the command-line.
+
+- does CREATE TABLE IF NOT EXISTS database_to_write.`db`
+
+- fills database_to_write.`db` with the output of
+SHOW DATABASES LIKE database_like_wild
+
+- does CREATE TABLE IF NOT EXISTS database_to_write.`tbl`
+(respectively database_to_write.`tbl_status`
+if the --tbl-status option is on)
+
+- for every found database,
+fills database_to_write.`tbl` (respectively database_to_write.`tbl_status`)
+with the output of
+SHOW TABLES FROM found_db LIKE table_like_wild
+(respectively SHOW TABLE STATUS FROM found_db LIKE table_like_wild)
+
+- if the --col option is on,
+ * does CREATE TABLE IF NOT EXISTS database_to_write.`col`
+ * for every found table,
+ fills database_to_write.`col` with the output of
+ SHOW COLUMNS FROM found_tbl FROM found_db
+
+- if the --idx option is on,
+ * does CREATE TABLE IF NOT EXISTS database_to_write.`idx`
+ * for every found table,
+ fills database_to_write.`idx` with the output of
+ SHOW INDEX FROM found_tbl FROM found_db
+
+Some options may modify this general scheme (see below).
+
+As mentioned, the contents of the info tables are the output of
+SHOW commands. In fact the contents are slightly more complete :
+
+- the `tbl` (or `tbl_status`) info table
+ has an extra column which contains the database name,
+
+- the `col` info table
+ has an extra column which contains the table name,
+ and an extra column which contains, for each described column,
+ the number of this column in the table owning it (this extra column
+ is called `Seq_in_table`). `Seq_in_table` makes it possible for you
+ to retrieve your columns in sorted order, when you are querying
+ the `col` table.
+
+- the `index` info table
+ has an extra column which contains the database name.
+
+Caution: info tables contain certain columns (e.g.
+Database, Table, Null...) whose names, as they are MySQL reserved words,
+need to be backquoted (`...`) when used in SQL statements.
+
+Caution: as information fetching and info tables filling happen at the
+same time, info tables may contain inaccurate information about
+themselves.
+
+=head1 OPTIONS
+
+=over 4
+
+=item --clear
+
+Does DROP TABLE on the info tables (only those that the program is
+going to fill, for example if you do not use --col it won't drop
+the `col` table) and processes normally. Does not drop database_to_write.
+
+=item --clear-only
+
+Same as --clear but exits after the DROPs.
+
+=item --col
+
+Adds columns information (into table `col`).
+
+=item --idx
+
+Adds index information (into table `idx`).
+
+=item --prefix prefix
+
+The info tables are named from the concatenation of prefix and,
+respectively, db, tbl (or tbl_status), col, idx. Do not quote ('')
+or backquote (``) prefix.
+
+=item -q, --quiet
+
+Does not warn you about what the script is going to do (DROP TABLE etc)
+and does not ask for a confirmation before starting.
+
+=item --tbl-status
+
+Instead of using SHOW TABLES, uses SHOW TABLE STATUS
+(much more complete information, but slower).
+
+=item --help
+
+Display helpscreen and exit
+
+=item -u, --user=#
+
+user for database login if not current user. Give a user
+who has sufficient privileges (CREATE, ...).
+
+=item -p, --password=#
+
+password to use when connecting to server
+
+=item -h, --host=#
+
+host to connect to
+
+=item -P, --port=#
+
+port to use when connecting to server
+
+=item -S, --socket=#
+
+UNIX domain socket to use when connecting to server
+
+=head1 WARRANTY
+
+This software is free and comes without warranty of any kind. You
+should never trust backup software without studying the code yourself.
+Study the code inside this script and only rely on it if I<you> believe
+that it does the right thing for you.
+
+Patches adding bug fixes, documentation and new features are welcome.
+
+=head1 TO DO
+
+Use extended inserts to be faster (for servers with many databases
+or tables). But to do that, must care about net-buffer-length.
+
+=head1 AUTHOR
+
+2002-06-18 Guilhem Bichot (guilhem.bichot@mines-paris.org)
+
+And all the authors of mysqlhotcopy, which served as a model for
+the structure of the program.
diff --git a/scripts/mysql_zap.sh b/scripts/mysql_zap.sh
index 312d15e34d6..f485d164282 100644
--- a/scripts/mysql_zap.sh
+++ b/scripts/mysql_zap.sh
@@ -12,7 +12,7 @@ $opt_f= 0;
$opt_t= 0;
$opt_a = "";
-$BSD = -f '/vmunix' || $ENV{"OS"} eq "SunOS4";
+$BSD = -f '/vmunix' || $ENV{"OS"} eq "SunOS4" || $^O eq 'darwin';
$LINUX = $^O eq 'linux';
$pscmd = $BSD ? "/bin/ps -auxww" : $LINUX ? "/bin/ps axuw" : "/bin/ps -ef";
diff --git a/scripts/mysqlaccess.sh b/scripts/mysqlaccess.sh
index 699e74834e3..75ef63ecdd0 100644
--- a/scripts/mysqlaccess.sh
+++ b/scripts/mysqlaccess.sh
@@ -286,7 +286,7 @@ Release Notes:
* --old_server: mysqlaccess will now use a full where clause when
retrieving information from the MySQL-server. If
you are connecting to an old server (before v3.21)
- use the option --old_server.
+ then use the option --old_server.
2.03 : (1998-02-27)
- bugfix:
* in Host::MatchTemplate: incorrect match if host-field was left empty.
diff --git a/scripts/mysqlbug.sh b/scripts/mysqlbug.sh
index bd5cb497e59..49ac08d0013 100644
--- a/scripts/mysqlbug.sh
+++ b/scripts/mysqlbug.sh
@@ -8,7 +8,7 @@ VERSION="@VERSION@@MYSQL_SERVER_SUFFIX@"
COMPILATION_COMMENT="@COMPILATION_COMMENT@"
BUGmysql="mysql@lists.mysql.com"
# This is set by configure
-COMP_ENV_INFO="CC='@CC@' CFLAGS='@CFLAGS@' CXX='@CXX@' CXXFLAGS='@CXXFLAGS@' LDFLAGS='@LDFLAGS@'"
+COMP_ENV_INFO="CC='@CC@' CFLAGS='@CFLAGS@' CXX='@CXX@' CXXFLAGS='@CXXFLAGS@' LDFLAGS='@LDFLAGS@' ASFLAGS='@ASFLAGS@'"
CONFIGURE_LINE="@CONF_COMMAND@"
LIBC_INFO=""
@@ -231,6 +231,8 @@ ${ORGANIZATION- $ORGANIZATION_C}
>Class: $CLASS_C
>Release: mysql-${VERSION} ($COMPILATION_COMMENT)
`test -n "$MYSQL_SERVER" && echo ">Server: $MYSQL_SERVER"`
+>C compiler: @CC_VERSION@
+>C++ compiler: @CXX_VERSION@
>Environment:
$ENVIRONMENT_C
`test -n "$SYSTEM" && echo "System: $SYSTEM"`
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 1adaa458271..3165a01362c 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -4,7 +4,7 @@ use Getopt::Long;
use POSIX qw(strftime);
$|=1;
-$VER="2.2";
+$VER="2.5";
$opt_config_file = undef();
$opt_example = 0;
@@ -183,7 +183,7 @@ sub report_mysqlds
sub start_mysqlds()
{
- my (@groups, $com, $i, @options, $j);
+ my (@groups, $com, $tmp, $i, @options, $j);
if (!$opt_no_log)
{
@@ -202,11 +202,21 @@ sub start_mysqlds()
@options = `$com`;
chop @options;
- $com = "$mysqld";
- for ($j = 0; defined($options[$j]); $j++)
+ $com= "$mysqld";
+ for ($j = 0, $tmp= ""; defined($options[$j]); $j++)
{
- $com.= " $options[$j]";
+ if ("--mysqld=" eq substr($options[$j], 0, 9))
+ {
+ $options[$j]=~ s/\-\-mysqld\=//;
+ $com= $options[$j];
+ }
+ else
+ {
+ $options[$j]=~ s/;/\\;/g;
+ $tmp.= " $options[$j]";
+ }
}
+ $com.= $tmp;
$com.= " >> $opt_log 2>&1" if (!$opt_no_log);
$com.= " &";
system($com);
@@ -457,12 +467,12 @@ sub example
# directory, that you have (just change the socket, -S=...)
# See more detailed information from chapter:
# '6 The MySQL Access Privilege System' from the MySQL manual.
-# 2.pid-file is very important, if you are using safe_mysqld to start mysqld
-# (e.g. --mysqld=safe_mysqld) Every mysqld should have it's own pid-file.
-# The advantage using safe_mysqld instead of mysqld directly here is, that
-# safe_mysqld 'guards' every mysqld process and will restart it, if mysqld
+# 2.pid-file is very important, if you are using mysqld_safe to start mysqld
+# (e.g. --mysqld=mysqld_safe) Every mysqld should have it's own pid-file.
+# The advantage using mysqld_safe instead of mysqld directly here is, that
+# mysqld_safe 'guards' every mysqld process and will restart it, if mysqld
# process fails due to signal kill -9, or similar. (Like segmentation fault,
-# which MySQL should never do, of course ;) Please note that safe_mysqld
+# which MySQL should never do, of course ;) Please note that mysqld_safe
# script may require that you start it from a certain place. This means that
# you may have to CD to a certain directory, before you start the
# mysqld_multi. If you have problems starting, please see the script.
@@ -497,10 +507,10 @@ sub example
# give you extra performance in a threaded system!
#
[mysqld_multi]
-mysqld = @bindir@/safe_mysqld
+mysqld = @bindir@/mysqld_safe
mysqladmin = @bindir@/mysqladmin
-user = multi_admin
-password = multipass
+user = root
+password = your_password
[mysqld2]
socket = /tmp/mysql.sock2
@@ -591,10 +601,16 @@ Options:
Using: $opt_log
--mysqladmin=... mysqladmin binary to be used for a server shutdown.
Using: $mysqladmin
---mysqld=... mysqld binary to be used. Note that you can give safe_mysqld
+--mysqld=... mysqld binary to be used. Note that you can give mysqld_safe
to this option also. The options are passed to mysqld. Just
- make sure you have mysqld in your PATH or fix safe_mysqld.
+ make sure you have mysqld in your PATH or fix mysqld_safe.
Using: $mysqld
+ Please note: Since mysqld_multi version 2.3 you can also
+ give this option inside groups [mysqld#] in ~/.my.cnf,
+ where '#' stands for an integer (number) of the group in
+ question. This will be recognized as a special option and
+ will not be passed to the mysqld. This will allow one to
+ start different mysqld versions with mysqld_multi.
--no-log Print to stdout instead of the log file. By default the log
file is turned on.
--password=... Password for user for mysqladmin.
diff --git a/scripts/mysqld_safe-watch.sh b/scripts/mysqld_safe-watch.sh
new file mode 100644
index 00000000000..c59b3b2614d
--- /dev/null
+++ b/scripts/mysqld_safe-watch.sh
@@ -0,0 +1,150 @@
+#!/bin/sh
+# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
+# This file is public domain and comes with NO WARRANTY of any kind
+#
+# scripts to start the MySQL demon and restart it if it dies unexpectedly
+#
+# This should be executed in the MySQL base directory if you are using a
+# binary installation that has other paths than you are using.
+#
+# mysql.server works by first doing a cd to the base directory and from there
+# executing mysqld_safe
+
+# Check if we are starting this relative (for the binary release)
+if test -f ./data/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
+ -x ./bin/mysqld
+then
+ MY_BASEDIR_VERSION=`pwd` # Where bin, share and data is
+ DATADIR=$MY_BASEDIR_VERSION/data # Where the databases are
+ ledir=$MY_BASEDIR_VERSION/bin # Where mysqld are
+# Check if this is a 'moved install directory'
+elif test -f ./var/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
+ -x ./libexec/mysqld
+then
+ MY_BASEDIR_VERSION=`pwd` # Where libexec, share and var is
+ DATADIR=$MY_BASEDIR_VERSION/var # Where the databases are
+ ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld are
+else
+ MY_BASEDIR_VERSION=/usr/local/mysql
+ DATADIR=/usr/local/mysql/var
+ ledir=/usr/local/mysql/libexec
+fi
+
+hostname=`@HOSTNAME@`
+pidfile=$DATADIR/$hostname.pid
+log=$DATADIR/$hostname.log
+err=$DATADIR/$hostname.err
+lockfile=$DATADIR/$hostname.lock
+
+#
+# If there exists an old pid file, check if the demon is already running
+# Note: The switches to 'ps' may depend on your operating system
+
+if test -f $pidfile
+then
+ PID=`cat $pidfile`
+ if /bin/kill -0 $PID
+ then
+ if /bin/ps -p $PID | grep mysqld > /dev/null
+ then # The pid contains a mysqld process
+ echo "A mysqld process already exists"
+ echo "A mysqld process already exists at " `date` >> $log
+ exit 1;
+ fi
+ fi
+ rm -f $pidfile
+ if test -f $pidfile
+ then
+ echo "Fatal error: Can't remove the pid file: $pidfile"
+ echo "Fatal error: Can't remove the pid file: $pidfile at " `date` >> $log
+ echo "Please remove it manually and start $0 again"
+ echo "mysqld demon not started"
+ exit 1;
+ fi
+fi
+
+echo "Starting mysqld demon with databases from $DATADIR"
+
+#Default communication ports
+#MYSQL_TCP_PORT=3306
+if test -z "$MYSQL_UNIX_PORT"
+then
+ MYSQL_UNIX_PORT="/tmp/mysql.sock"
+ export MYSQL_UNIX_PORT
+fi
+#export MYSQL_TCP_PORT
+
+# Does this work on all systems?
+#if type ulimit | grep "shell builtin" > /dev/null
+#then
+# ulimit -n 256 > /dev/null 2>&1 # Fix for BSD and FreeBSD systems
+#fi
+
+echo "mysqld started on " `date` >> $log
+bin/zap -f $lockfile < /dev/null > /dev/null 2>&1
+rm -f $lockfile
+$MY_BASEDIR_VERSION/bin/watchdog_mysqld $lockfile $pidfile $MY_BASEDIR_VERSION/bin $DATADIR 3 10 >> $err 2>&1 &
+restart_pid=$!
+
+while true
+do
+ rm -f $MYSQL_UNIX_PORT $pidfile # Some extra safety
+ lockfile -1 -r10 $lockfile >/dev/null 2>&1
+ if test "$#" -eq 0
+ then
+ nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
+ --skip-locking >> $err 2>&1 &
+ else
+ nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
+ --skip-locking "$@" >> $err 2>&1 &
+ fi
+ pid=$!
+ rm -f $lockfile
+ wait $pid;
+
+ lockfile -1 -r10 $lockfile >/dev/null 2>&1
+ rm -f $lockfile
+ if test ! -f $pidfile # This is removed if normal shutdown
+ then
+ break;
+ fi
+ if true
+ then
+ # Test if one proces was hanging.
+ # This is only a fix for Linux (running as base 3 mysqld processes)
+ # but should work for the rest of the servers.
+ # The only thing is ps x => redhat 5 gives warnings when using ps -x.
+ # kill -9 is used or the proces won't react on the kill.
+ numofproces=`ps x | grep -v "grep" | grep -c $ledir/mysqld`
+ echo -e "\nNumber of processes running now: $numofproces" | tee -a $log
+ I=1
+ while test "$I" -le "$numofproces"
+ do
+ PROC=`ps x | grep $ledir/mysqld | grep -v "grep" | tail -1`
+ for T in $PROC
+ do
+ break
+ done
+ # echo "TEST $I - $T **"
+ if kill -9 $T
+ then
+ echo "mysqld proces hanging, pid $T - killed" | tee -a $log
+ else
+ break
+ fi
+ I=`expr $I + 1`
+ done
+ fi
+ echo "mysqld restarted" | tee -a $log
+ # Check all tables and repair any wrong tables.
+ $MY_BASEDIR_VERSION/bin/isamchk -sf $DATADIR/*/*.ISM >> $err 2>&1
+done
+if test $restart_pid -gt 0
+then
+ kill $restart_pid > /dev/null 2>&1
+ sleep 1;
+ kill -9 $restart_pid > /dev/null 2>&1
+fi
+
+echo -n "mysqld ended on " `date` >> $log
+echo "mysqld demon ended"
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
new file mode 100644
index 00000000000..0f415ccd5f0
--- /dev/null
+++ b/scripts/mysqld_safe.sh
@@ -0,0 +1,352 @@
+#!/bin/sh
+# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
+# This file is public domain and comes with NO WARRANTY of any kind
+#
+# scripts to start the MySQL daemon and restart it if it dies unexpectedly
+#
+# This should be executed in the MySQL base directory if you are using a
+# binary installation that has other paths than you are using.
+#
+# mysql.server works by first doing a cd to the base directory and from there
+# executing mysqld_safe
+
+KILL_MYSQLD=1;
+
+trap '' 1 2 3 15 # we shouldn't let anyone kill us
+
+umask 007
+
+defaults=
+case "$1" in
+ --no-defaults|--defaults-file=*|--defaults-extra-file=*)
+ defaults="$1"; shift
+ ;;
+esac
+
+parse_arguments() {
+ # We only need to pass arguments through to the server if we don't
+ # handle them here. So, we collect unrecognized options (passed on
+ # the command line) into the args variable.
+ pick_args=
+ if test "$1" = PICK-ARGS-FROM-ARGV
+ then
+ pick_args=1
+ shift
+ fi
+
+ for arg do
+ case "$arg" in
+ --skip-kill-mysqld*)
+ KILL_MYSQLD=0;
+ ;;
+ # these get passed explicitly to mysqld
+ --basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--basedir=;;"` ;;
+ --datadir=*) DATADIR=`echo "$arg" | sed -e "s;--datadir=;;"` ;;
+ --pid-file=*) pid_file=`echo "$arg" | sed -e "s;--pid-file=;;"` ;;
+ --user=*)
+ if test $SET_USER -eq 0
+ then
+ user=`echo "$arg" | sed -e "s;--[^=]*=;;"`
+ fi
+ SET_USER=1
+ ;;
+
+ # these two might have been set in a [mysqld_safe] section of my.cnf
+ # they are added to mysqld command line to override settings from my.cnf
+ --socket=*) mysql_unix_port=`echo "$arg" | sed -e "s;--socket=;;"` ;;
+ --port=*) mysql_tcp_port=`echo "$arg" | sed -e "s;--port=;;"` ;;
+
+ # mysqld_safe-specific options - must be set in my.cnf ([mysqld_safe])!
+ --ledir=*) ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;;
+ # err-log should be removed in 5.0
+ --err-log=*) err_log=`echo "$arg" | sed -e "s;--err-log=;;"` ;;
+ --log-error=*) err_log=`echo "$arg" | sed -e "s;--log-error=;;"` ;;
+ # QQ The --open-files should be removed in 5.0
+ --open-files=*) open_files=`echo "$arg" | sed -e "s;--open-files=;;"` ;;
+ --open-files-limit=*) open_files=`echo "$arg" | sed -e "s;--open-files-limit=;;"` ;;
+ --core-file-size=*) core_file_size=`echo "$arg" | sed -e "s;--core-file-size=;;"` ;;
+ --timezone=*) TZ=`echo "$arg" | sed -e "s;--timezone=;;"` ; export TZ; ;;
+ --mysqld=*) MYSQLD=`echo "$arg" | sed -e "s;--mysqld=;;"` ;;
+ --mysqld-version=*)
+ tmp=`echo "$arg" | sed -e "s;--mysqld-version=;;"`
+ if test -n "$tmp"
+ then
+ MYSQLD="mysqld-$tmp"
+ else
+ MYSQLD="mysqld"
+ fi
+ ;;
+ --nice=*) niceness=`echo "$arg" | sed -e "s;--nice=;;"` ;;
+ *)
+ if test -n "$pick_args"
+ then
+ # This sed command makes sure that any special chars are quoted,
+ # so the arg gets passed exactly to the server.
+ args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'`
+ fi
+ ;;
+ esac
+ done
+}
+
+
+MY_PWD=`pwd`
+# Check if we are starting this relative (for the binary release)
+if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
+ -x ./bin/mysqld
+then
+ MY_BASEDIR_VERSION=$MY_PWD # Where bin, share and data are
+ ledir=$MY_BASEDIR_VERSION/bin # Where mysqld is
+ DATADIR=$MY_BASEDIR_VERSION/data
+ if test -z "$defaults"
+ then
+ defaults="--defaults-extra-file=$MY_BASEDIR_VERSION/data/my.cnf"
+ fi
+# Check if this is a 'moved install directory'
+elif test -f ./var/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
+ -x ./libexec/mysqld
+then
+ MY_BASEDIR_VERSION=$MY_PWD # Where libexec, share and var are
+ ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld is
+ DATADIR=$MY_BASEDIR_VERSION/var
+else
+ MY_BASEDIR_VERSION=@prefix@
+ DATADIR=@localstatedir@
+ ledir=@libexecdir@
+fi
+
+user=@MYSQLD_USER@
+niceness=0
+
+# Use the mysqld-max binary by default if the user doesn't specify a binary
+if test -x $ledir/mysqld-max
+then
+ MYSQLD=mysqld-max
+else
+ MYSQLD=mysqld
+fi
+
+# these rely on $DATADIR by default, so we'll set them later on
+pid_file=
+err_log=
+
+# Get first arguments from the my.cnf file, groups [mysqld] and [mysqld_safe]
+# and then merge with the command line arguments
+if test -x ./bin/my_print_defaults
+then
+ print_defaults="./bin/my_print_defaults"
+elif test -x @bindir@/my_print_defaults
+then
+ print_defaults="@bindir@/my_print_defaults"
+elif test -x @bindir@/mysql_print_defaults
+then
+ print_defaults="@bindir@/mysql_print_defaults"
+else
+ print_defaults="my_print_defaults"
+fi
+
+args=
+SET_USER=2
+parse_arguments `$print_defaults --loose-verbose $defaults mysqld server`
+if test $SET_USER -eq 2
+then
+ SET_USER=0
+fi
+parse_arguments `$print_defaults --loose-verbose $defaults mysqld_safe safe_mysqld`
+parse_arguments PICK-ARGS-FROM-ARGV "$@"
+safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}}
+
+if test ! -x $ledir/$MYSQLD
+then
+ echo "The file $ledir/$MYSQLD doesn't exist or is not executable"
+ echo "Please do a cd to the mysql installation directory and restart"
+ echo "this script from there as follows:"
+ echo "./bin/mysqld_safe".
+ exit 1
+fi
+
+if test -z "$pid_file"
+then
+ pid_file=$DATADIR/`@HOSTNAME@`.pid
+else
+ case "$pid_file" in
+ /* ) ;;
+ * ) pid_file="$DATADIR/$pid_file" ;;
+ esac
+fi
+test -z "$err_log" && err_log=$DATADIR/`@HOSTNAME@`.err
+
+if test -n "$mysql_unix_port"
+then
+ args="--socket=$mysql_unix_port $args"
+fi
+if test -n "$mysql_tcp_port"
+then
+ args="--port=$mysql_tcp_port $args"
+fi
+
+if test $niceness -eq 0
+then
+ NOHUP_NICENESS="nohup"
+else
+ NOHUP_NICENESS="nohup nice -$niceness"
+fi
+
+# Using nice with no args to get the niceness level is GNU-specific.
+# This check could be extended for other operating systems (e.g.,
+# BSD could use "nohup sh -c 'ps -o nice -p $$' | tail -1").
+# But, it also seems that GNU nohup is the only one which messes
+# with the priority, so this is okay.
+if nohup nice > /dev/null 2>&1
+then
+ normal_niceness=`nice`
+ nohup_niceness=`nohup nice`
+
+ numeric_nice_values=1
+ for val in $normal_niceness $nohup_niceness
+ do
+ case "$val" in
+ -[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | \
+ [0-9] | [0-9][0-9] | [0-9][0-9][0-9] )
+ ;;
+ * )
+ numeric_nice_values=0 ;;
+ esac
+ done
+
+ if test $numeric_nice_values -eq 1
+ then
+ nice_value_diff=`expr $nohup_niceness - $normal_niceness`
+ if test $? -eq 0 && test $nice_value_diff -gt 0 && \
+ nice --$nice_value_diff echo testing > /dev/null 2>&1
+ then
+ # nohup increases the priority (bad), and we are permitted
+ # to lower the priority with respect to the value the user
+ # might have been given
+ niceness=`expr $niceness - $nice_value_diff`
+ NOHUP_NICENESS="nice -$niceness nohup"
+ fi
+ fi
+else
+ if nohup echo testing > /dev/null 2>&1
+ then
+ :
+ else
+ # nohup doesn't work on this system
+ NOHUP_NICENESS=""
+ fi
+fi
+
+USER_OPTION=""
+if test -w / -o "$USER" = "root"
+then
+ if test "$user" != "root" -o $SET_USER = 1
+ then
+ USER_OPTION="--user=$user"
+ fi
+ # If we are root, change the err log to the right user.
+ touch $err_log; chown $user $err_log
+ if test -n "$open_files"
+ then
+ ulimit -n $open_files
+ args="--open-files-limit=$open_files $args"
+ fi
+ if test -n "$core_file_size"
+ then
+ ulimit -c $core_file_size
+ fi
+fi
+
+#
+# If there exists an old pid file, check if the daemon is already running
+# Note: The switches to 'ps' may depend on your operating system
+if test -f $pid_file
+then
+ PID=`cat $pid_file`
+ if @CHECK_PID@
+ then
+ if @FIND_PROC@
+ then # The pid contains a mysqld process
+ echo "A mysqld process already exists"
+ echo "A mysqld process already exists at " `date` >> $err_log
+ exit 1
+ fi
+ fi
+ rm -f $pid_file
+ if test -f $pid_file
+ then
+ echo "Fatal error: Can't remove the pid file: $pid_file"
+ echo "Fatal error: Can't remove the pid file: $pid_file at " `date` >> $err_log
+ echo "Please remove it manually and start $0 again"
+ echo "mysqld daemon not started"
+ exit 1
+ fi
+fi
+
+#
+# Uncomment the following lines if you want all tables to be automatically
+# checked and repaired during startup. You should add sensible key_buffer
+# and sort_buffer values to my.cnf to improve check performance or require
+# less disk space.
+# Alternatively, you can start mysqld with the "myisam-recover" option. See
+# the manual for details.
+#
+# echo "Checking tables in $DATADIR"
+# $MY_BASEDIR_VERSION/bin/myisamchk --silent --force --fast --medium-check $DATADIR/*/*.MYI
+# $MY_BASEDIR_VERSION/bin/isamchk --silent --force $DATADIR/*/*.ISM
+
+echo "Starting $MYSQLD daemon with databases from $DATADIR"
+
+# Does this work on all systems?
+#if type ulimit | grep "shell builtin" > /dev/null
+#then
+# ulimit -n 256 > /dev/null 2>&1 # Fix for BSD and FreeBSD systems
+#fi
+
+echo "`date +'%y%m%d %H:%M:%S mysqld started'`" >> $err_log
+while true
+do
+ rm -f $safe_mysql_unix_port $pid_file # Some extra safety
+ if test -z "$args"
+ then
+ $NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ >> $err_log 2>&1
+ else
+ eval "$NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ $args >> $err_log 2>&1"
+ fi
+ if test ! -f $pid_file # This is removed if normal shutdown
+ then
+ break
+ fi
+
+ if test @IS_LINUX@ -a $KILL_MYSQLD -eq 1
+ then
+ # Test if one process was hanging.
+ # This is only a fix for Linux (running as base 3 mysqld processes)
+ # but should work for the rest of the servers.
+ # The only thing is ps x => redhat 5 gives warnings when using ps -x.
+ # kill -9 is used or the process won't react on the kill.
+ numofproces=`ps xa | grep -v "grep" | grep -c $ledir/$MYSQLD`
+ echo -e "\nNumber of processes running now: $numofproces" | tee -a $err_log
+ I=1
+ while test "$I" -le "$numofproces"
+ do
+ PROC=`ps xa | grep $ledir/$MYSQLD | grep -v "grep" | sed -n '$p'`
+ for T in $PROC
+ do
+ break
+ done
+ # echo "TEST $I - $T **"
+ if kill -9 $T
+ then
+ echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log
+ else
+ break
+ fi
+ I=`expr $I + 1`
+ done
+ fi
+ echo "`date +'%y%m%d %H:%M:%S'` mysqld restarted" | tee -a $err_log
+done
+
+echo "`date +'%y%m%d %H:%M:%S'` mysqld ended" | tee -a $err_log
+echo "" | tee -a $err_log
diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh
index 1a694247461..654e5466e12 100644
--- a/scripts/mysqlhotcopy.sh
+++ b/scripts/mysqlhotcopy.sh
@@ -37,7 +37,7 @@ WARNING: THIS PROGRAM IS STILL IN BETA. Comments/patches welcome.
# Documentation continued at end of file
-my $VERSION = "1.17";
+my $VERSION = "1.20";
my $opt_tmpdir = $ENV{TMPDIR} || "/tmp";
@@ -55,7 +55,8 @@ Usage: $0 db_name[./table_regex/] [new_db_name | directory]
-P, --port=# port to use when connecting to local server with TCP/IP
-S, --socket=# socket to use when connecting to local server
- --allowold don\'t abort if target already exists (rename it _old)
+ --allowold don\'t abort if target dir already exists (rename it _old)
+ --addtodest don\'t rename target dir if it exists, just add files to it
--keepold don\'t delete previous (now renamed) target when done
--noindices don\'t include full index files in copy
--method=# method for copy (only "cp" currently supported)
@@ -80,8 +81,11 @@ sub usage {
die @_, $OPTIONS;
}
+# Do not initialize user or password options; that way, any user/password
+# options specified in option files will be used. If no values are specified
+# all, the defaults will be used (login name, no password).
+
my %opt = (
- user => scalar getpwuid($>),
noindices => 0,
allowold => 0, # for safety
keepold => 0,
@@ -98,6 +102,7 @@ GetOptions( \%opt,
"socket|S=s",
"allowold!",
"keepold!",
+ "addtodest!",
"noindices!",
"method=s",
"debug",
@@ -163,6 +168,9 @@ $dsn = ";host=" . (defined($opt{host}) ? $opt{host} : "localhost");
$dsn .= ";port=$opt{port}" if $opt{port};
$dsn .= ";mysql_socket=$opt{socket}" if $opt{socket};
+# use mysql_read_default_group=mysqlhotcopy so that [client] and
+# [mysqlhotcopy] groups will be read from standard options files.
+
my $dbh = DBI->connect("dbi:mysql:$dsn;mysql_read_default_group=mysqlhotcopy",
$opt{user}, $opt{password},
{
@@ -173,6 +181,7 @@ my $dbh = DBI->connect("dbi:mysql:$dsn;mysql_read_default_group=mysqlhotcopy",
# --- check that checkpoint table exists if specified ---
if ( $opt{checkpoint} ) {
+ $opt{checkpoint} = quote_names( $opt{checkpoint} );
eval { $dbh->do( qq{ select time_stamp, src, dest, msg
from $opt{checkpoint} where 1 != 1} );
};
@@ -183,6 +192,8 @@ if ( $opt{checkpoint} ) {
# --- check that log_pos table exists if specified ---
if ( $opt{record_log_pos} ) {
+ $opt{record_log_pos} = quote_names( $opt{record_log_pos} );
+
eval { $dbh->do( qq{ select host, time_stamp, log_file, log_pos, master_host, master_log_file, master_log_pos
from $opt{record_log_pos} where 1 != 1} );
};
@@ -224,10 +235,15 @@ else
# --- resolve database names from regexp ---
if ( defined $opt{regexp} ) {
+ my $t_regex = '.*';
+ if ( $opt{regexp} =~ s{^/(.+)/\./(.+)/$}{$1} ) {
+ $t_regex = $2;
+ }
+
my $sth_dbs = $dbh->prepare("show databases");
$sth_dbs->execute;
while ( my ($db_name) = $sth_dbs->fetchrow_array ) {
- push @db_desc, { 'src' => $db_name } if ( $db_name =~ m/$opt{regexp}/o );
+ push @db_desc, { 'src' => $db_name, 't_regex' => $t_regex } if ( $db_name =~ m/$opt{regexp}/o );
}
}
@@ -309,7 +325,7 @@ foreach my $rdb ( @db_desc ) {
$rdb->{files} = [ @db_files ];
$rdb->{index} = [ @index_files ];
- my @hc_tables = map { "`$db`.`$_`" } @dbh_tables;
+ my @hc_tables = map { quote_names("$db.$_") } @dbh_tables;
$rdb->{tables} = [ @hc_tables ];
$rdb->{raid_dirs} = [ get_raid_dirs( $rdb->{files} ) ];
@@ -377,14 +393,14 @@ if ($opt{method} =~ /^cp\b/)
push @existing, $rdb->{target} if ( -d $rdb->{target} );
}
- if ( @existing && !$opt{allowold} )
+ if ( @existing && !($opt{allowold} || $opt{addtodest}) )
{
$dbh->disconnect();
- die "Can't hotcopy to '", join( "','", @existing ), "' because directory\nalready exist and the --allowold option was not given.\n"
+ die "Can't hotcopy to '", join( "','", @existing ), "' because directory\nalready exist and the --allowold or --addtodest options were not given.\n"
}
}
-retire_directory( @existing ) if ( @existing );
+retire_directory( @existing ) if @existing && !$opt{addtodest};
foreach my $rdb ( @db_desc ) {
foreach my $td ( '', @{$rdb->{raid_dirs}} ) {
@@ -400,8 +416,10 @@ foreach my $rdb ( @db_desc ) {
## ...
}
else {
- mkdir($tgt_dirpath, 0750)
- or die "Can't create '$tgt_dirpath': $!\n";
+ mkdir($tgt_dirpath, 0750) or die "Can't create '$tgt_dirpath': $!\n"
+ unless -d $tgt_dirpath;
+ my @f_info= stat "$datadir/$rdb->{src}";
+ chown $f_info[4], $f_info[5], $tgt_dirpath;
}
}
}
@@ -558,22 +576,22 @@ sub copy_files {
print "Copying ".@$files." files...\n" unless $opt{quiet};
if ($method =~ /^s?cp\b/) { # cp or scp with optional flags
- my @cp = ($method);
+ my $cp = $method;
# add option to preserve mod time etc of copied files
# not critical, but nice to have
- push @cp, "-p" if $^O =~ m/^(solaris|linux|freebsd|darwin)$/;
+ $cp.= " -p" if $^O =~ m/^(solaris|linux|freebsd|darwin)$/;
# add recursive option for scp
- push @cp, "-r" if $^O =~ /m^(solaris|linux|freebsd|darwin)$/ && $method =~ /^scp\b/;
+ $cp.= " -r" if $^O =~ /m^(solaris|linux|freebsd|darwin)$/ && $method =~ /^scp\b/;
my @non_raid = map { "'$_'" } grep { ! m:/\d{2}/[^/]+$: } @$files;
# add files to copy and the destination directory
- safe_system( @cp, @non_raid, "'$target'" );
+ safe_system( $cp, @non_raid, "'$target'" ) if (@non_raid);
foreach my $rd ( @$raid_dirs ) {
my @raid = map { "'$_'" } grep { m:$rd/: } @$files;
- safe_system( @cp, @raid, "'$target'/$rd" ) if ( @raid );
+ safe_system( $cp, @raid, "'$target'/$rd" ) if ( @raid );
}
}
else
@@ -635,26 +653,54 @@ sub copy_index
}
-sub safe_system
-{
- my @cmd= @_;
-
- if ( $opt{dryrun} )
- {
- print "@cmd\n";
- return;
+sub safe_system {
+ my @sources= @_;
+ my $method= shift @sources;
+ my $target= pop @sources;
+ ## @sources = list of source file names
+
+ ## We have to deal with very long command lines, otherwise they may generate
+ ## "Argument list too long".
+ ## With 10000 tables the command line can be around 1MB, much more than 128kB
+ ## which is the common limit on Linux (can be read from
+ ## /usr/src/linux/include/linux/binfmts.h
+ ## see http://www.linuxjournal.com/article.php?sid=6060).
+
+ my $chunk_limit= 100 * 1024; # 100 kB
+ my @chunk= ();
+ my $chunk_length= 0;
+ foreach (@sources) {
+ push @chunk, $_;
+ $chunk_length+= length($_);
+ if ($chunk_length > $chunk_limit) {
+ safe_simple_system($method, @chunk, $target);
+ @chunk=();
+ $chunk_length= 0;
+ }
}
-
- ## for some reason system fails but backticks works ok for scp...
- print "Executing '@cmd'\n" if $opt{debug};
- my $cp_status = system "@cmd > /dev/null";
- if ($cp_status != 0) {
- warn "Burp ('scuse me). Trying backtick execution...\n" if $opt{debug}; #'
- ## try something else
- `@cmd` && die "Error: @cmd failed ($cp_status) while copying files.\n";
+ if ($chunk_length > 0) { # do not forget last small chunk
+ safe_simple_system($method, @chunk, $target);
}
}
+sub safe_simple_system {
+ my @cmd= @_;
+
+ if ( $opt{dryrun} ) {
+ print "@cmd\n";
+ }
+ else {
+ ## for some reason system fails but backticks works ok for scp...
+ print "Executing '@cmd'\n" if $opt{debug};
+ my $cp_status = system "@cmd > /dev/null";
+ if ($cp_status != 0) {
+ warn "Executing command failed ($cp_status). Trying backtick execution...\n";
+ ## try something else
+ `@cmd` || die "Error: @cmd failed ($?) while copying files.\n";
+ }
+ }
+}
+
sub retire_directory {
my ( @dir ) = @_;
@@ -758,6 +804,20 @@ sub get_list_of_tables {
return @dbh_tables;
}
+sub quote_names {
+ my ( $name ) = @_;
+ # given a db.table name, add quotes
+
+ my ($db, $table, @cruft) = split( /\./, $name );
+ die "Invalid db.table name '$name'" if (@cruft || !defined $db || !defined $table );
+
+ # Earlier versions of DBD return table name non-quoted,
+ # such as DBD-2.1012 and the newer ones, such as DBD-2.9002
+ # returns it quoted. Let's have a support for both.
+ $table=~ s/\`//g;
+ return "`$db`.`$table`";
+}
+
__END__
=head1 DESCRIPTION
@@ -848,6 +908,22 @@ Any existing versions of the backup directory are deleted.
Behaves as for the --allowold, with the additional feature
of keeping the backup directory after the copy successfully completes.
+=item --addtodest
+
+Don't rename target directory if it already exists, just add the
+copied files into it.
+
+This is most useful when backing up a database with many large
+tables and you don't want to have all the tables locked for the
+whole duration.
+
+In this situation, I<if> you are happy for groups of tables to be
+backed up separately (and thus possibly not be logically consistant
+with one another) then you can run mysqlhotcopy several times on
+the same database each with different db_name./table_regex/.
+All but the first should use the --addtodest option so the tables
+all end up in the same directory.
+
=item --flushlog
Rotate the log files by executing "FLUSH LOGS" after all tables are
@@ -856,19 +932,27 @@ locked, and before they are copied.
=item --resetmaster
Reset the bin-log by executing "RESET MASTER" after all tables are
-locked, and before they are copied. Usefull if you are recovering a
+locked, and before they are copied. Useful if you are recovering a
slave in a replication setup.
=item --resetslave
Reset the master.info by executing "RESET SLAVE" after all tables are
-locked, and before they are copied. Usefull if you are recovering a
+locked, and before they are copied. Useful if you are recovering a
server in a mutual replication setup.
=item --regexp pattern
Copy all databases with names matching the pattern
+=item --regexp /pattern1/./pattern2/
+
+Copy all tables with names matching pattern2 from all databases with
+names matching pattern1. For example, to select all tables which
+names begin with 'bar' from all databases which names end with 'foo':
+
+ mysqlhotcopy --indices --method=cp --regexp /foo$/./^bar/
+
=item db_name./pattern/
Copy only tables matching pattern. Shell metacharacters ( (, ), |, !,
@@ -928,7 +1012,7 @@ will vary with your ability to understand how scp works. 'man scp'
and 'man ssh' are your friends.
The destination directory _must exist_ on the target machine using the
-scp method. --keepold and --allowold are meeningless with scp.
+scp method. --keepold and --allowold are meaningless with scp.
Liberal use of the --debug option will help you figure out what\'s
really going on when you do an scp.
diff --git a/scripts/safe_mysqld-watch.sh b/scripts/safe_mysqld-watch.sh
deleted file mode 100644
index 30f95fd7a86..00000000000
--- a/scripts/safe_mysqld-watch.sh
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/bin/sh
-# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
-# This file is public domain and comes with NO WARRANTY of any kind
-#
-# scripts to start the MySQL demon and restart it if it dies unexpectedly
-#
-# This should be executed in the MySQL base directory if you are using a
-# binary installation that has other paths than you are using.
-#
-# mysql.server works by first doing a cd to the base directory and from there
-# executing safe_mysqld
-
-# Check if we are starting this relative (for the binary release)
-if test -f ./data/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
- -x ./bin/mysqld
-then
- MY_BASEDIR_VERSION=`pwd` # Where bin, share and data is
- DATADIR=$MY_BASEDIR_VERSION/data # Where the databases are
- ledir=$MY_BASEDIR_VERSION/bin # Where mysqld are
-# Check if this is a 'moved install directory'
-elif test -f ./var/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
- -x ./libexec/mysqld
-then
- MY_BASEDIR_VERSION=`pwd` # Where libexec, share and var is
- DATADIR=$MY_BASEDIR_VERSION/var # Where the databases are
- ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld are
-else
- MY_BASEDIR_VERSION=/usr/local/mysql
- DATADIR=/usr/local/mysql/var
- ledir=/usr/local/mysql/libexec
-fi
-
-hostname=`@HOSTNAME@`
-pidfile=$DATADIR/$hostname.pid
-log=$DATADIR/$hostname.log
-err=$DATADIR/$hostname.err
-lockfile=$DATADIR/$hostname.lock
-
-#
-# If there exists an old pid file, check if the demon is already running
-# Note: The switches to 'ps' may depend on your operating system
-
-if test -f $pidfile
-then
- PID=`cat $pidfile`
- if /bin/kill -0 $PID
- then
- if /bin/ps -p $PID | grep mysqld > /dev/null
- then # The pid contains a mysqld process
- echo "A mysqld process already exists"
- echo "A mysqld process already exists at " `date` >> $log
- exit 1;
- fi
- fi
- rm -f $pidfile
- if test -f $pidfile
- then
- echo "Fatal error: Can't remove the pid file: $pidfile"
- echo "Fatal error: Can't remove the pid file: $pidfile at " `date` >> $log
- echo "Please remove it manually and start $0 again"
- echo "mysqld demon not started"
- exit 1;
- fi
-fi
-
-echo "Starting mysqld demon with databases from $DATADIR"
-
-#Default communication ports
-#MYSQL_TCP_PORT=3306
-if test -z "$MYSQL_UNIX_PORT"
-then
- MYSQL_UNIX_PORT="/tmp/mysql.sock"
- export MYSQL_UNIX_PORT
-fi
-#export MYSQL_TCP_PORT
-
-# Does this work on all systems?
-#if type ulimit | grep "shell builtin" > /dev/null
-#then
-# ulimit -n 256 > /dev/null 2>&1 # Fix for BSD and FreeBSD systems
-#fi
-
-echo "mysqld started on " `date` >> $log
-bin/zap -f $lockfile < /dev/null > /dev/null 2>&1
-rm -f $lockfile
-$MY_BASEDIR_VERSION/bin/watchdog_mysqld $lockfile $pidfile $MY_BASEDIR_VERSION/bin $DATADIR 3 10 >> $err 2>&1 &
-restart_pid=$!
-
-while true
-do
- rm -f $MYSQL_UNIX_PORT $pidfile # Some extra safety
- lockfile -1 -r10 $lockfile >/dev/null 2>&1
- if test "$#" -eq 0
- then
- nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
- --skip-locking >> $err 2>&1 &
- else
- nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
- --skip-locking "$@" >> $err 2>&1 &
- fi
- pid=$!
- rm -f $lockfile
- wait $pid;
-
- lockfile -1 -r10 $lockfile >/dev/null 2>&1
- rm -f $lockfile
- if test ! -f $pidfile # This is removed if normal shutdown
- then
- break;
- fi
- if true
- then
- # Test if one proces was hanging.
- # This is only a fix for Linux (running as base 3 mysqld processes)
- # but should work for the rest of the servers.
- # The only thing is ps x => redhat 5 gives warnings when using ps -x.
- # kill -9 is used or the proces won't react on the kill.
- numofproces=`ps x | grep -v "grep" | grep -c $ledir/mysqld`
- echo -e "\nNumber of processes running now: $numofproces" | tee -a $log
- I=1
- while test "$I" -le "$numofproces"
- do
- PROC=`ps x | grep $ledir/mysqld | grep -v "grep" | tail -1`
- for T in $PROC
- do
- break
- done
- # echo "TEST $I - $T **"
- if kill -9 $T
- then
- echo "mysqld proces hanging, pid $T - killed" | tee -a $log
- else
- break
- fi
- I=`expr $I + 1`
- done
- fi
- echo "mysqld restarted" | tee -a $log
- # Check all tables and repair any wrong tables.
- $MY_BASEDIR_VERSION/bin/isamchk -sf $DATADIR/*/*.ISM >> $err 2>&1
-done
-if test $restart_pid -gt 0
-then
- kill $restart_pid > /dev/null 2>&1
- sleep 1;
- kill -9 $restart_pid > /dev/null 2>&1
-fi
-
-echo -n "mysqld ended on " `date` >> $log
-echo "mysqld demon ended"
diff --git a/scripts/safe_mysqld.sh b/scripts/safe_mysqld.sh
deleted file mode 100644
index 6b7e16c57b0..00000000000
--- a/scripts/safe_mysqld.sh
+++ /dev/null
@@ -1,287 +0,0 @@
-#!/bin/sh
-# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
-# This file is public domain and comes with NO WARRANTY of any kind
-#
-# scripts to start the MySQL daemon and restart it if it dies unexpectedly
-#
-# This should be executed in the MySQL base directory if you are using a
-# binary installation that has other paths than you are using.
-#
-# mysql.server works by first doing a cd to the base directory and from there
-# executing safe_mysqld
-
-trap '' 1 2 3 15 # we shouldn't let anyone kill us
-
-umask 007
-
-defaults=
-case "$1" in
- --no-defaults|--defaults-file=*|--defaults-extra-file=*)
- defaults="$1"; shift
- ;;
-esac
-
-parse_arguments() {
- # We only need to pass arguments through to the server if we don't
- # handle them here. So, we collect unrecognized options (passed on
- # the command line) into the args variable.
- pick_args=$1; shift
-
- for arg do
- case "$arg" in
- # these get passed explicitly to mysqld
- --basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --datadir=*) DATADIR=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --pid-file=*) pid_file=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --user=*)
- if test $SET_USER -eq 0
- then
- user=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; SET_USER=1
- fi
- ;;
- # these two might have been set in a [safe_mysqld] section of my.cnf
- # they get passed via environment variables to safe_mysqld
- --socket=*) MYSQL_UNIX_PORT=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --port=*) MYSQL_TCP_PORT=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
-
- # safe_mysqld-specific options
- --ledir=*) ledir=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --err-log=*) err_log=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- # QQ The --open-files should be removed
- --open-files=*) open_files=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --open-files-limit=*) open_files=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --core-file-size=*) core_file_size=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --timezone=*) TZ=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; export TZ; ;;
- --mysqld=*) MYSQLD=`echo "$arg" | sed -e "s;--[^=]*=;;"` ;;
- --mysqld-version=*)
- tmp=`echo "$arg" | sed -e "s;--[^=]*=;;"`
- if test -n "$tmp"
- then
- MYSQLD="mysqld-$tmp"
- else
- MYSQLD="mysqld"
- fi
- ;;
- *)
- if test $pick_args -eq 1
- then
- # This sed command makes sure that any special chars are quoted,
- # so the arg gets passed exactly to the server.
- args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'`
- fi
- ;;
- esac
- done
-}
-
-MY_PWD=`pwd`
-# Check if we are starting this relative (for the binary release)
-if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
- -x ./bin/mysqld
-then
- MY_BASEDIR_VERSION=$MY_PWD # Where bin, share and data are
- ledir=$MY_BASEDIR_VERSION/bin # Where mysqld is
- DATADIR=$MY_BASEDIR_VERSION/data
- if test -z "$defaults"
- then
- defaults="--defaults-extra-file=$MY_BASEDIR_VERSION/data/my.cnf"
- fi
-# Check if this is a 'moved install directory'
-elif test -f ./var/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
- -x ./libexec/mysqld
-then
- MY_BASEDIR_VERSION=$MY_PWD # Where libexec, share and var are
- ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld is
- DATADIR=$MY_BASEDIR_VERSION/var
-else
- MY_BASEDIR_VERSION=@prefix@
- DATADIR=@localstatedir@
- ledir=@libexecdir@
-fi
-
-MYSQL_UNIX_PORT=${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}
-MYSQL_TCP_PORT=${MYSQL_TCP_PORT:-@MYSQL_TCP_PORT@}
-user=@MYSQLD_USER@
-
-# Use the mysqld-max binary by default if the user doesn't specify a binary
-if test -x $ledir/mysqld-max
-then
- MYSQLD=mysqld-max
-else
- MYSQLD=mysqld
-fi
-
-# these rely on $DATADIR by default, so we'll set them later on
-pid_file=
-err_log=
-SET_USER=0
-
-# Get first arguments from the my.cnf file, groups [mysqld] and [safe_mysqld]
-# and then merge with the command line arguments
-if test -x ./bin/my_print_defaults
-then
- print_defaults="./bin/my_print_defaults"
-elif test -x @bindir@/my_print_defaults
-then
- print_defaults="@bindir@/my_print_defaults"
-elif test -x @bindir@/mysql_print_defaults
-then
- print_defaults="@bindir@/mysql_print_defaults"
-else
- print_defaults="my_print_defaults"
-fi
-
-args=
-parse_arguments 0 `$print_defaults $defaults mysqld server safe_mysqld`
-parse_arguments 1 "$@"
-
-if test ! -x $ledir/$MYSQLD
-then
- echo "The file $ledir/$MYSQLD doesn't exist or is not executable"
- echo "Please do a cd to the mysql installation directory and restart"
- echo "this script from there as follows:"
- echo "./bin/safe_mysqld".
- exit 1
-fi
-
-if test -z "$pid_file"
-then
- pid_file=$DATADIR/`@HOSTNAME@`.pid
-else
- case "$pid_file" in
- /* ) ;;
- * ) pid_file="$DATADIR/$pid_file" ;;
- esac
-fi
-test -z "$err_log" && err_log=$DATADIR/`@HOSTNAME@`.err
-
-export MYSQL_UNIX_PORT
-export MYSQL_TCP_PORT
-
-
-NOHUP_NICENESS="nohup"
-if test -w /
-then
- NOHUP_NICENESS=`nohup nice 2>&1`
- if test $? -eq 0 && test x"$NOHUP_NICENESS" != x0 && nice --1 echo foo > /dev/null 2>&1
- then
- if test $NOHUP_NICENESS -gt 0
- then
- NOHUP_NICENESS="nice --$NOHUP_NICENESS nohup"
- else
- NOHUP_NICENESS="nice -$NOHUP_NICENESS nohup"
- fi
- else
- NOHUP_NICENESS="nohup"
- fi
-fi
-
-USER_OPTION=""
-if test -w /
-then
- if test "$user" != "root" -o $SET_USER = 1
- then
- USER_OPTION="--user=$user"
- fi
- # If we are root, change the err log to the right user.
- touch $err_log; chown $user $err_log
- if test -n "$open_files"
- then
- ulimit -n $open_files
- fi
- if test -n "$core_file_size"
- then
- ulimit -c $core_file_size
- fi
-fi
-
-#
-# If there exists an old pid file, check if the daemon is already running
-# Note: The switches to 'ps' may depend on your operating system
-if test -f $pid_file
-then
- PID=`cat $pid_file`
- if @CHECK_PID@
- then
- if @FIND_PROC@
- then # The pid contains a mysqld process
- echo "A mysqld process already exists"
- echo "A mysqld process already exists at " `date` >> $err_log
- exit 1
- fi
- fi
- rm -f $pid_file
- if test -f $pid_file
- then
- echo "Fatal error: Can't remove the pid file: $pid_file"
- echo "Fatal error: Can't remove the pid file: $pid_file at " `date` >> $err_log
- echo "Please remove it manually and start $0 again"
- echo "mysqld daemon not started"
- exit 1
- fi
-fi
-
-#
-# Uncomment the following lines if you want all tables to be automaticly
-# checked and repaired at start
-#
-# echo "Checking tables in $DATADIR"
-# $MY_BASEDIR_VERSION/bin/myisamchk --silent --force --fast --medium-check -O key_buffer=64M -O sort_buffer=64M $DATADIR/*/*.MYI
-# $MY_BASEDIR_VERSION/bin/isamchk --silent --force -O sort_buffer=64M $DATADIR/*/*.ISM
-
-echo "Starting $MYSQLD daemon with databases from $DATADIR"
-
-# Does this work on all systems?
-#if type ulimit | grep "shell builtin" > /dev/null
-#then
-# ulimit -n 256 > /dev/null 2>&1 # Fix for BSD and FreeBSD systems
-#fi
-
-echo "`date +'%y%m%d %H:%M:%S mysqld started'`" >> $err_log
-while true
-do
- rm -f $MYSQL_UNIX_PORT $pid_file # Some extra safety
- if test -z "$args"
- then
- $NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ >> $err_log 2>&1
- else
- eval "$NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ $args >> $err_log 2>&1"
- fi
- if test ! -f $pid_file # This is removed if normal shutdown
- then
- break
- fi
-
- if @IS_LINUX@
- then
- # Test if one process was hanging.
- # This is only a fix for Linux (running as base 3 mysqld processes)
- # but should work for the rest of the servers.
- # The only thing is ps x => redhat 5 gives warnings when using ps -x.
- # kill -9 is used or the process won't react on the kill.
- numofproces=`ps xa | grep -v "grep" | grep -c $ledir/$MYSQLD`
- echo -e "\nNumber of processes running now: $numofproces" | tee -a $err_log
- I=1
- while test "$I" -le "$numofproces"
- do
- PROC=`ps xa | grep $ledir/$MYSQLD | grep -v "grep" | sed -n '$p'`
- for T in $PROC
- do
- break
- done
- # echo "TEST $I - $T **"
- if kill -9 $T
- then
- echo "$MYSQLD process hanging, pid $T - killed" | tee -a $err_log
- else
- break
- fi
- I=`expr $I + 1`
- done
- fi
-
- echo "`date +'%y%m%d %H:%M:%S'` mysqld restarted" | tee -a $err_log
-done
-
-echo "`date +'%y%m%d %H:%M:%S'` mysqld ended" | tee -a $err_log
-echo "" | tee -a $err_log
diff --git a/sql-bench/Comments/interbase b/sql-bench/Comments/interbase
new file mode 100644
index 00000000000..addaf74b63f
--- /dev/null
+++ b/sql-bench/Comments/interbase
@@ -0,0 +1,18 @@
+Running crash-me on Interbase:
+I
+- got opensource version of interbase 6.0.1
+ (both mode, classic and superserver),
+- set up DBD::InterBase from cpan,
+- created database "test" and set sql_dialect for that database to 3
+- executed crash-me for both interbase's models (classic and superserver).
+
+There were some problems during the execution:
+1) Sometimes client side got SIGSEGV , At that moment server side
+ writes
+ gds__alloc: non-positive size allocation request
+ to log file.
+ This problem has both models. I am not shure if it's interbase or
+ DBD:InterBase problem (though DBD::InterBase made all nesessary
+ tests during the installation without any problem)
+
+2) In "superserver" mode ibserver several times died (and ibguard restarted it)
diff --git a/sql-bench/Makefile.am b/sql-bench/Makefile.am
index 9ed0fc29b30..579a2a9f7fe 100644
--- a/sql-bench/Makefile.am
+++ b/sql-bench/Makefile.am
@@ -21,28 +21,29 @@ benchdir_root= $(prefix)
benchdir = $(benchdir_root)/sql-bench
bench_SCRIPTS = test-ATIS test-connect test-create test-insert \
test-big-tables test-select test-wisconsin \
- test-alter-table graph-compare-results \
+ test-alter-table test-transactions \
+ graph-compare-results \
bench-init.pl compare-results run-all-tests \
server-cfg crash-me copy-db innotest1 innotest1a \
- innotest1b innotest2 innotest2a innotest2b
+ innotest1b innotest2 innotest2a innotest2b \
+ bench-count-distinct
CLEANFILES = $(bench_SCRIPTS)
EXTRA_SCRIPTS = test-ATIS.sh test-connect.sh test-create.sh \
test-insert.sh test-big-tables.sh test-select.sh \
test-alter-table.sh test-wisconsin.sh \
+ test-transactions.sh \
bench-init.pl.sh compare-results.sh server-cfg.sh \
run-all-tests.sh crash-me.sh copy-db.sh \
graph-compare-results.sh innotest1.sh innotest1a.sh \
- innotest1b.sh innotest2.sh innotest2a.sh innotest2b.sh
+ innotest1b.sh innotest2.sh innotest2a.sh innotest2b.sh \
+ bench-count-distinct.sh
EXTRA_DIST = $(EXTRA_SCRIPTS)
dist-hook:
mkdir -p $(distdir)/Data/ATIS $(distdir)/Data/Wisconsin \
- $(distdir)/Results $(distdir)/Results-win32 \
$(distdir)/limits $(distdir)/Comments
for i in $(srcdir)/Data/ATIS/*.* ; do $(INSTALL_DATA) $$i $(distdir)/Data/ATIS ; done
for i in $(srcdir)/Data/Wisconsin/*.* ; do $(INSTALL_DATA) $$i $(distdir)/Data/Wisconsin ; done
- for i in $(srcdir)/Results/*-* ; do $(INSTALL_DATA) $$i $(distdir)/Results; done
- for i in $(srcdir)/Results-win32/*-* ; do $(INSTALL_DATA) $$i $(distdir)/Results-win32; done
for i in $(srcdir)/limits/*.* ; do $(INSTALL_DATA) $$i $(distdir)/limits; done
for i in $(srcdir)/Comments/*.* ; do $(INSTALL_DATA) $$i $(distdir)/Comments; done
@@ -51,15 +52,11 @@ install-data-local:
$(DESTDIR)$(benchdir)/Data \
$(DESTDIR)$(benchdir)/Data/ATIS \
$(DESTDIR)$(benchdir)/Data/Wisconsin \
- $(DESTDIR)$(benchdir)/Results \
- $(DESTDIR)$(benchdir)/Results-win32 \
$(DESTDIR)$(benchdir)/limits \
$(DESTDIR)$(benchdir)/Comments
$(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(benchdir)
for i in $(srcdir)/Data/ATIS/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Data/ATIS ; done
for i in $(srcdir)/Data/Wisconsin/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Data/Wisconsin ; done
- for i in $(srcdir)/Results/*-* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Results; done
- for i in $(srcdir)/Results-win32/*-* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Results-win32; done
for i in $(srcdir)/limits/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/limits; done
for i in $(srcdir)/Comments/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Comments; done
diff --git a/sql-bench/Results/ATIS-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/ATIS-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..2b0610da26f
--- /dev/null
+++ b/sql-bench/Results/ATIS-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,20 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:34:53
+
+ATIS table test
+
+Creating tables
+Time for create_table (28): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Inserting data
+Time to insert (9768): 2 wallclock secs ( 0.44 usr 0.21 sys + 0.00 cusr 0.00 csys = 0.65 CPU)
+
+Retrieving data
+Time for select_simple_join (500): 2 wallclock secs ( 0.60 usr 0.19 sys + 0.00 cusr 0.00 csys = 0.79 CPU)
+Time for select_join (100): 1 wallclock secs ( 0.46 usr 0.14 sys + 0.00 cusr 0.00 csys = 0.60 CPU)
+Time for select_key_prefix_join (100): 10 wallclock secs ( 3.98 usr 1.52 sys + 0.00 cusr 0.00 csys = 5.50 CPU)
+Time for select_distinct (800): 9 wallclock secs ( 1.59 usr 0.55 sys + 0.00 cusr 0.00 csys = 2.14 CPU)
+Time for select_group (2800): 9 wallclock secs ( 1.34 usr 0.28 sys + 0.00 cusr 0.00 csys = 1.62 CPU)
+
+Removing tables
+Time to drop_table (28): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Total time: 33 wallclock secs ( 8.41 usr 2.89 sys + 0.00 cusr 0.00 csys = 11.30 CPU)
diff --git a/sql-bench/Results/ATIS-mysql-Linux_2.4.4_SMP_alpha b/sql-bench/Results/ATIS-mysql-Linux_2.4.4_SMP_alpha
new file mode 100644
index 00000000000..e0192d49a3d
--- /dev/null
+++ b/sql-bench/Results/ATIS-mysql-Linux_2.4.4_SMP_alpha
@@ -0,0 +1,20 @@
+Testing server 'MySQL 4.0.5 beta' at 2002-10-23 12:35:44
+
+ATIS table test
+
+Creating tables
+Time for create_table (28): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Inserting data
+Time to insert (9768): 3 wallclock secs ( 0.52 usr 0.31 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Retrieving data
+Time for select_simple_join (500): 1 wallclock secs ( 0.60 usr 0.29 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_join (100): 2 wallclock secs ( 0.44 usr 0.27 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_key_prefix_join (100): 10 wallclock secs ( 3.58 usr 2.30 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_distinct (800): 10 wallclock secs ( 1.60 usr 0.81 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_group (2800): 11 wallclock secs ( 1.44 usr 0.52 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Removing tables
+Time to drop_table (28): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Total time: 37 wallclock secs ( 8.20 usr 4.50 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
diff --git a/sql-bench/Results/RUN-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/RUN-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..6885ceddcf1
--- /dev/null
+++ b/sql-bench/Results/RUN-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,109 @@
+Benchmark DBD suite: 2.14
+Date of test: 2002-05-20 17:48:45
+Running tests on: Linux 2.4.16-64GB-SMP i686
+Arguments:
+Comments: Intel Xeon 2M cache, 4x700 Mhz, 2G, key_buffer=16M, gcc 3.1
+Limits from:
+Server version: MySQL 4.0.2 alpha
+Optimization: None
+Hardware:
+
+alter-table: Total time: 241 wallclock secs ( 0.17 usr 0.07 sys + 0.00 cusr 0.00 csys = 0.24 CPU)
+ATIS: Total time: 33 wallclock secs ( 8.41 usr 2.89 sys + 0.00 cusr 0.00 csys = 11.30 CPU)
+big-tables: Total time: 27 wallclock secs ( 9.38 usr 5.17 sys + 0.00 cusr 0.00 csys = 14.55 CPU)
+connect: Total time: 156 wallclock secs (71.06 usr 31.02 sys + 0.00 cusr 0.00 csys = 102.08 CPU)
+create: Total time: 90 wallclock secs ( 5.77 usr 1.91 sys + 0.00 cusr 0.00 csys = 7.68 CPU)
+insert: Total time: 1730 wallclock secs (523.67 usr 128.19 sys + 0.00 cusr 0.00 csys = 651.86 CPU)
+select: Total time: 1106 wallclock secs (52.54 usr 11.75 sys + 0.00 cusr 0.00 csys = 64.29 CPU)
+transactions: Test skipped because the database doesn't support transactions
+wisconsin: Total time: 12 wallclock secs ( 3.07 usr 1.20 sys + 0.00 cusr 0.00 csys = 4.27 CPU)
+
+All 9 test executed successfully
+
+Totals per operation:
+Operation seconds usr sys cpu tests
+alter_table_add 134.00 0.12 0.03 0.15 992
+alter_table_drop 102.00 0.04 0.02 0.06 496
+connect 7.00 4.50 1.62 6.12 10000
+connect+select_1_row 10.00 5.09 2.31 7.40 10000
+connect+select_simple 9.00 5.19 2.02 7.21 10000
+count 33.00 0.04 0.00 0.04 100
+count_distinct 34.00 0.24 0.05 0.29 1000
+count_distinct_2 38.00 0.25 0.07 0.32 1000
+count_distinct_big 50.00 7.15 2.75 9.90 120
+count_distinct_group 47.00 1.00 0.27 1.27 1000
+count_distinct_group_on_key 43.00 0.26 0.05 0.31 1000
+count_distinct_group_on_key_parts 47.00 0.98 0.29 1.27 1000
+count_distinct_key_prefix 28.00 0.29 0.03 0.32 1000
+count_group_on_key_parts 43.00 0.96 0.31 1.27 1000
+count_on_key 416.00 11.73 1.70 13.43 50100
+create+drop 17.00 1.49 0.50 1.99 10000
+create_MANY_tables 25.00 1.12 0.28 1.40 10000
+create_index 3.00 0.00 0.00 0.00 8
+create_key+drop 23.00 1.84 0.62 2.46 10000
+create_table 0.00 0.00 0.00 0.00 31
+delete_all_many_keys 51.00 0.02 0.00 0.02 1
+delete_big 0.00 0.00 0.00 0.00 1
+delete_big_many_keys 51.00 0.02 0.00 0.02 128
+delete_key 2.00 0.39 0.26 0.65 10000
+delete_range 11.00 0.01 0.00 0.01 12
+drop_index 2.00 0.00 0.00 0.00 8
+drop_table 0.00 0.00 0.00 0.00 28
+drop_table_when_MANY_tables 11.00 0.34 0.17 0.51 10000
+insert 78.00 14.11 7.05 21.16 350768
+insert_duplicates 16.00 2.42 2.15 4.57 100000
+insert_key 86.00 7.22 2.27 9.49 100000
+insert_many_fields 7.00 0.19 0.07 0.26 2000
+insert_select_1_key 5.00 0.00 0.00 0.00 1
+insert_select_2_keys 6.00 0.00 0.00 0.00 1
+min_max 23.00 0.02 0.00 0.02 60
+min_max_on_key 159.00 19.21 2.78 21.99 85000
+multiple_value_insert 5.00 1.29 0.00 1.29 100000
+order_by_big 40.00 21.73 8.15 29.88 10
+order_by_big_key 33.00 23.12 7.93 31.05 10
+order_by_big_key2 31.00 21.98 7.84 29.82 10
+order_by_big_key_desc 32.00 23.13 8.16 31.29 10
+order_by_big_key_diff 39.00 22.07 7.71 29.78 10
+order_by_big_key_prefix 31.00 21.76 8.21 29.97 10
+order_by_key2_diff 4.00 2.00 0.58 2.58 500
+order_by_key_prefix 3.00 0.98 0.34 1.32 500
+order_by_range 3.00 0.81 0.41 1.22 500
+outer_join 48.00 0.01 0.00 0.01 10
+outer_join_found 46.00 0.01 0.00 0.01 10
+outer_join_not_found 31.00 0.00 0.00 0.00 500
+outer_join_on_key 40.00 0.00 0.00 0.00 10
+select_1_row 22.00 9.63 4.42 14.05 100000
+select_1_row_cache 19.00 6.75 3.55 10.30 100000
+select_2_rows 24.00 9.99 4.11 14.10 100000
+select_big 31.00 21.97 8.10 30.07 80
+select_big_str 13.00 5.10 3.32 8.42 10000
+select_cache 88.00 2.21 0.38 2.59 10000
+select_cache2 89.00 2.49 0.39 2.88 10000
+select_column+column 23.00 8.62 3.65 12.27 100000
+select_diff_key 138.00 0.12 0.02 0.14 500
+select_distinct 9.00 1.59 0.55 2.14 800
+select_group 51.00 1.40 0.29 1.69 2911
+select_group_when_MANY_tables 14.00 0.98 0.34 1.32 10000
+select_join 1.00 0.46 0.14 0.60 100
+select_key 82.00 51.17 8.13 59.30 200000
+select_key2 86.00 50.00 7.89 57.89 200000
+select_key2_return_key 81.00 48.57 6.51 55.08 200000
+select_key2_return_prim 83.00 49.27 7.43 56.70 200000
+select_key_prefix 87.00 51.79 8.42 60.21 200000
+select_key_prefix_join 10.00 3.98 1.52 5.50 100
+select_key_return_key 79.00 48.93 7.01 55.94 200000
+select_many_fields 19.00 9.18 5.10 14.28 2000
+select_range 103.00 8.73 2.95 11.68 410
+select_range_key2 12.00 4.65 0.92 5.57 25010
+select_range_prefix 13.00 5.01 0.99 6.00 25010
+select_simple 15.00 8.15 2.84 10.99 100000
+select_simple_cache 14.00 8.03 3.18 11.21 100000
+select_simple_join 2.00 0.60 0.19 0.79 500
+update_big 44.00 0.00 0.00 0.00 10
+update_of_key 14.00 1.80 0.94 2.74 50000
+update_of_key_big 20.00 0.01 0.01 0.02 501
+update_of_primary_key_many_keys 25.00 0.01 0.00 0.01 256
+update_with_key 60.00 9.66 6.21 15.87 300000
+update_with_key_prefix 21.00 6.04 1.98 8.02 100000
+wisc_benchmark 4.00 2.17 0.52 2.69 114
+TOTALS 3399.00 664.19 179.00 843.19 3227247
diff --git a/sql-bench/Results/RUN-mysql-Linux_2.4.4_SMP_alpha b/sql-bench/Results/RUN-mysql-Linux_2.4.4_SMP_alpha
new file mode 100644
index 00000000000..ba144b8d226
--- /dev/null
+++ b/sql-bench/Results/RUN-mysql-Linux_2.4.4_SMP_alpha
@@ -0,0 +1,109 @@
+Benchmark DBD suite: 2.14
+Date of test: 2002-10-23 12:35:44
+Running tests on: Linux 2.4.4-SMP alpha
+Arguments:
+Comments: Alpha DS20 2x500 MHz, 2G memory, key_buffer=16M, query_cache=16M; cxx 6.3 + ccc 6.2.9
+Limits from:
+Server version: MySQL 4.0.5 beta
+Optimization: None
+Hardware:
+
+ATIS: Total time: 37 wallclock secs ( 8.20 usr 4.50 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+alter-table: Total time: 277 wallclock secs ( 0.33 usr 0.14 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+big-tables: Total time: 39 wallclock secs ( 8.71 usr 8.56 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+connect: Total time: 209 wallclock secs (62.48 usr 49.95 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+create: Total time: 288 wallclock secs (10.88 usr 3.48 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+insert: Total time: 2381 wallclock secs (693.26 usr 241.11 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+select: Total time: 1298 wallclock secs (66.92 usr 20.96 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+transactions: Test skipped because the database doesn't support transactions
+wisconsin: Total time: 17 wallclock secs ( 3.66 usr 2.13 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+All 9 test executed successfully
+
+Totals per operation:
+Operation seconds usr sys cpu tests
+alter_table_add 154.00 0.18 0.06 0.00 992
+alter_table_drop 116.00 0.07 0.03 0.00 496
+connect 14.00 8.17 2.02 0.00 10000
+connect+select_1_row 17.00 8.80 2.79 0.00 10000
+connect+select_simple 16.00 8.86 2.57 0.00 10000
+count 50.00 0.04 0.00 0.00 100
+count_distinct 32.00 0.44 0.07 0.00 1000
+count_distinct_2 32.00 0.44 0.08 0.00 1000
+count_distinct_big 54.00 7.37 4.25 0.00 120
+count_distinct_group 50.00 1.14 0.52 0.00 1000
+count_distinct_group_on_key 38.00 0.48 0.12 0.00 1000
+count_distinct_group_on_key_parts 50.00 1.15 0.47 0.00 1000
+count_distinct_key_prefix 28.00 0.44 0.09 0.00 1000
+count_group_on_key_parts 37.00 1.02 0.48 0.00 1000
+count_on_key 453.00 16.74 3.59 0.00 50100
+create+drop 15.00 2.92 0.95 0.00 10000
+create_MANY_tables 238.00 1.84 0.51 0.00 10000
+create_index 4.00 0.00 0.00 0.00 8
+create_key+drop 19.00 4.55 0.94 0.00 10000
+create_table 0.00 0.00 0.00 0.00 31
+delete_all_many_keys 47.00 0.02 0.01 0.00 1
+delete_big 0.00 0.00 0.00 0.00 1
+delete_big_many_keys 47.00 0.02 0.01 0.00 128
+delete_key 4.00 0.88 0.55 0.00 10000
+delete_range 9.00 0.00 0.00 0.00 12
+drop_index 3.00 0.00 0.00 0.00 8
+drop_table 0.00 0.00 0.00 0.00 28
+drop_table_when_MANY_tables 10.00 0.67 0.44 0.00 10000
+insert 134.00 28.43 15.57 0.00 350768
+insert_duplicates 30.00 4.71 5.50 0.00 100000
+insert_key 98.00 13.49 3.80 0.00 100000
+insert_many_fields 14.00 0.32 0.11 0.00 2000
+insert_select_1_key 6.00 0.00 0.00 0.00 1
+insert_select_2_keys 8.00 0.00 0.00 0.00 1
+min_max 23.00 0.02 0.00 0.00 60
+min_max_on_key 188.00 27.44 5.93 0.00 85000
+multiple_value_insert 7.00 1.88 0.05 0.00 100000
+order_by_big 40.00 17.31 12.40 0.00 10
+order_by_big_key 31.00 18.84 12.61 0.00 10
+order_by_big_key2 30.00 17.35 12.38 0.00 10
+order_by_big_key_desc 32.00 19.23 12.70 0.00 10
+order_by_big_key_diff 36.00 17.33 12.44 0.00 10
+order_by_big_key_prefix 30.00 17.36 12.49 0.00 10
+order_by_key2_diff 5.00 1.67 1.04 0.00 500
+order_by_key_prefix 2.00 0.92 0.56 0.00 500
+order_by_range 5.00 0.97 0.55 0.00 500
+outer_join 67.00 0.00 0.00 0.00 10
+outer_join_found 63.00 0.01 0.00 0.00 10
+outer_join_not_found 40.00 0.01 0.00 0.00 500
+outer_join_on_key 40.00 0.01 0.00 0.00 10
+select_1_row 27.00 5.70 6.78 0.00 100000
+select_1_row_cache 22.00 3.16 5.87 0.00 100000
+select_2_rows 30.00 5.96 7.15 0.00 100000
+select_big 31.00 18.08 12.50 0.00 80
+select_big_str 20.00 8.04 6.08 0.00 10000
+select_cache 89.00 3.03 0.74 0.00 10000
+select_cache2 91.00 3.53 0.76 0.00 10000
+select_column+column 30.00 5.07 5.64 0.00 100000
+select_diff_key 163.00 0.27 0.04 0.00 500
+select_distinct 10.00 1.60 0.81 0.00 800
+select_group 106.00 1.49 0.53 0.00 2911
+select_group_when_MANY_tables 6.00 0.90 0.65 0.00 10000
+select_join 2.00 0.44 0.27 0.00 100
+select_key 142.00 77.87 17.06 0.00 200000
+select_key2 142.00 74.50 19.30 0.00 200000
+select_key2_return_key 133.00 73.16 13.81 0.00 200000
+select_key2_return_prim 132.00 70.56 13.25 0.00 200000
+select_key_prefix 141.00 73.88 18.25 0.00 200000
+select_key_prefix_join 10.00 3.58 2.30 0.00 100
+select_key_return_key 146.00 82.66 16.24 0.00 200000
+select_many_fields 25.00 8.38 8.45 0.00 2000
+select_range 242.00 8.57 4.60 0.00 410
+select_range_key2 19.00 6.12 1.72 0.00 25010
+select_range_prefix 18.00 6.28 1.70 0.00 25010
+select_simple 18.00 5.08 5.46 0.00 100000
+select_simple_cache 15.00 3.64 5.58 0.00 100000
+select_simple_join 1.00 0.60 0.29 0.00 500
+update_big 22.00 0.00 0.00 0.00 10
+update_of_key 25.00 4.24 1.90 0.00 50000
+update_of_key_big 18.00 0.04 0.03 0.00 501
+update_of_primary_key_many_keys 20.00 0.03 0.01 0.00 256
+update_with_key 116.00 21.90 14.15 0.00 300000
+update_with_key_prefix 36.00 11.11 4.60 0.00 100000
+wisc_benchmark 4.00 1.66 0.73 0.00 114
+TOTALS 4518.00 844.67 325.93 0.00 3227247
diff --git a/sql-bench/Results/alter-table-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/alter-table-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..f0deae1c1c4
--- /dev/null
+++ b/sql-bench/Results/alter-table-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,16 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:30:52
+
+Testing of ALTER TABLE
+Testing with 1000 columns and 1000 rows in 20 steps
+Insert data into the table
+Time for insert (1000) 0 wallclock secs ( 0.01 usr 0.02 sys + 0.00 cusr 0.00 csys = 0.03 CPU)
+
+Time for alter_table_add (992): 134 wallclock secs ( 0.12 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.15 CPU)
+
+Time for create_index (8): 3 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for drop_index (8): 2 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for alter_table_drop (496): 102 wallclock secs ( 0.04 usr 0.02 sys + 0.00 cusr 0.00 csys = 0.06 CPU)
+
+Total time: 241 wallclock secs ( 0.17 usr 0.07 sys + 0.00 cusr 0.00 csys = 0.24 CPU)
diff --git a/sql-bench/Results/alter-table-mysql-Linux_2.4.4_SMP_alpha b/sql-bench/Results/alter-table-mysql-Linux_2.4.4_SMP_alpha
new file mode 100644
index 00000000000..1d58effc1a5
--- /dev/null
+++ b/sql-bench/Results/alter-table-mysql-Linux_2.4.4_SMP_alpha
@@ -0,0 +1,16 @@
+Testing server 'MySQL 4.0.5 beta' at 2002-10-23 12:36:21
+
+Testing of ALTER TABLE
+Testing with 1000 columns and 1000 rows in 20 steps
+Insert data into the table
+Time for insert (1000) 0 wallclock secs ( 0.06 usr 0.05 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for alter_table_add (992): 154 wallclock secs ( 0.18 usr 0.06 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for create_index (8): 4 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for drop_index (8): 3 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for alter_table_drop (496): 116 wallclock secs ( 0.07 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Total time: 277 wallclock secs ( 0.33 usr 0.14 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
diff --git a/sql-bench/Results/big-tables-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/big-tables-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..afc03860f18
--- /dev/null
+++ b/sql-bench/Results/big-tables-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,19 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:35:26
+
+Testing of some unusual tables
+All tests are done 1000 times with 1000 fields
+
+Testing table with 1000 fields
+Testing select * from table with 1 record
+Time to select_many_fields(1000): 8 wallclock secs ( 4.72 usr 2.37 sys + 0.00 cusr 0.00 csys = 7.09 CPU)
+
+Testing select all_fields from table with 1 record
+Time to select_many_fields(1000): 11 wallclock secs ( 4.46 usr 2.73 sys + 0.00 cusr 0.00 csys = 7.19 CPU)
+
+Testing insert VALUES()
+Time to insert_many_fields(1000): 2 wallclock secs ( 0.15 usr 0.05 sys + 0.00 cusr 0.00 csys = 0.20 CPU)
+
+Testing insert (all_fields) VALUES()
+Time to insert_many_fields(1000): 5 wallclock secs ( 0.04 usr 0.02 sys + 0.00 cusr 0.00 csys = 0.06 CPU)
+
+Total time: 27 wallclock secs ( 9.38 usr 5.17 sys + 0.00 cusr 0.00 csys = 14.55 CPU)
diff --git a/sql-bench/Results/big-tables-mysql-Linux_2.4.4_SMP_alpha b/sql-bench/Results/big-tables-mysql-Linux_2.4.4_SMP_alpha
new file mode 100644
index 00000000000..97f66029696
--- /dev/null
+++ b/sql-bench/Results/big-tables-mysql-Linux_2.4.4_SMP_alpha
@@ -0,0 +1,19 @@
+Testing server 'MySQL 4.0.5 beta' at 2002-10-23 12:40:58
+
+Testing of some unusual tables
+All tests are done 1000 times with 1000 fields
+
+Testing table with 1000 fields
+Testing select * from table with 1 record
+Time to select_many_fields(1000): 11 wallclock secs ( 4.59 usr 4.21 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing select all_fields from table with 1 record
+Time to select_many_fields(1000): 14 wallclock secs ( 3.79 usr 4.24 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing insert VALUES()
+Time to insert_many_fields(1000): 5 wallclock secs ( 0.29 usr 0.06 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing insert (all_fields) VALUES()
+Time to insert_many_fields(1000): 9 wallclock secs ( 0.03 usr 0.05 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Total time: 39 wallclock secs ( 8.71 usr 8.56 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
diff --git a/sql-bench/Results/connect-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/connect-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..d2a4f2eb3b6
--- /dev/null
+++ b/sql-bench/Results/connect-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,35 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:35:53
+
+Testing the speed of connecting to the server and sending of data
+Connect tests are done 10000 times and other tests 100000 times
+
+Testing connection/disconnect
+Time to connect (10000): 7 wallclock secs ( 4.50 usr 1.62 sys + 0.00 cusr 0.00 csys = 6.12 CPU)
+
+Test connect/simple select/disconnect
+Time for connect+select_simple (10000): 9 wallclock secs ( 5.19 usr 2.02 sys + 0.00 cusr 0.00 csys = 7.21 CPU)
+
+Test simple select
+Time for select_simple (100000): 15 wallclock secs ( 8.15 usr 2.84 sys + 0.00 cusr 0.00 csys = 10.99 CPU)
+
+Test simple select
+Time for select_simple_cache (100000): 14 wallclock secs ( 8.03 usr 3.18 sys + 0.00 cusr 0.00 csys = 11.21 CPU)
+
+Testing connect/select 1 row from table/disconnect
+Time to connect+select_1_row (10000): 10 wallclock secs ( 5.09 usr 2.31 sys + 0.00 cusr 0.00 csys = 7.40 CPU)
+
+Testing select 1 row from table
+Time to select_1_row (100000): 22 wallclock secs ( 9.63 usr 4.42 sys + 0.00 cusr 0.00 csys = 14.05 CPU)
+
+Time to select_1_row_cache (100000): 19 wallclock secs ( 6.75 usr 3.55 sys + 0.00 cusr 0.00 csys = 10.30 CPU)
+
+Testing select 2 rows from table
+Time to select_2_rows (100000): 24 wallclock secs ( 9.99 usr 4.11 sys + 0.00 cusr 0.00 csys = 14.10 CPU)
+
+Test select with aritmetic (+)
+Time for select_column+column (100000): 23 wallclock secs ( 8.62 usr 3.65 sys + 0.00 cusr 0.00 csys = 12.27 CPU)
+
+Testing retrieval of big records (65000 bytes)
+Time to select_big_str (10000): 13 wallclock secs ( 5.10 usr 3.32 sys + 0.00 cusr 0.00 csys = 8.42 CPU)
+
+Total time: 156 wallclock secs (71.06 usr 31.02 sys + 0.00 cusr 0.00 csys = 102.08 CPU)
diff --git a/sql-bench/Results/connect-mysql-Linux_2.4.4_SMP_alpha b/sql-bench/Results/connect-mysql-Linux_2.4.4_SMP_alpha
new file mode 100644
index 00000000000..a787d311a54
--- /dev/null
+++ b/sql-bench/Results/connect-mysql-Linux_2.4.4_SMP_alpha
@@ -0,0 +1,35 @@
+Testing server 'MySQL 4.0.5 beta' at 2002-10-23 12:41:37
+
+Testing the speed of connecting to the server and sending of data
+Connect tests are done 10000 times and other tests 100000 times
+
+Testing connection/disconnect
+Time to connect (10000): 14 wallclock secs ( 8.17 usr 2.02 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Test connect/simple select/disconnect
+Time for connect+select_simple (10000): 16 wallclock secs ( 8.86 usr 2.57 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Test simple select
+Time for select_simple (100000): 18 wallclock secs ( 5.08 usr 5.46 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Test simple select
+Time for select_simple_cache (100000): 15 wallclock secs ( 3.64 usr 5.58 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing connect/select 1 row from table/disconnect
+Time to connect+select_1_row (10000): 17 wallclock secs ( 8.80 usr 2.79 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing select 1 row from table
+Time to select_1_row (100000): 27 wallclock secs ( 5.70 usr 6.78 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time to select_1_row_cache (100000): 22 wallclock secs ( 3.16 usr 5.87 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing select 2 rows from table
+Time to select_2_rows (100000): 30 wallclock secs ( 5.96 usr 7.15 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Test select with aritmetic (+)
+Time for select_column+column (100000): 30 wallclock secs ( 5.07 usr 5.64 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing retrieval of big records (65000 bytes)
+Time to select_big_str (10000): 20 wallclock secs ( 8.04 usr 6.08 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Total time: 209 wallclock secs (62.48 usr 49.95 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
diff --git a/sql-bench/Results/create-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/create-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..864a4adb7e6
--- /dev/null
+++ b/sql-bench/Results/create-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,18 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:38:29
+
+Testing the speed of creating and droping tables
+Testing with 10000 tables and 10000 loop count
+
+Testing create of tables
+Time for create_MANY_tables (10000): 25 wallclock secs ( 1.12 usr 0.28 sys + 0.00 cusr 0.00 csys = 1.40 CPU)
+
+Accessing tables
+Time to select_group_when_MANY_tables (10000): 14 wallclock secs ( 0.98 usr 0.34 sys + 0.00 cusr 0.00 csys = 1.32 CPU)
+
+Testing drop
+Time for drop_table_when_MANY_tables (10000): 11 wallclock secs ( 0.34 usr 0.17 sys + 0.00 cusr 0.00 csys = 0.51 CPU)
+
+Testing create+drop
+Time for create+drop (10000): 17 wallclock secs ( 1.49 usr 0.50 sys + 0.00 cusr 0.00 csys = 1.99 CPU)
+Time for create_key+drop (10000): 23 wallclock secs ( 1.84 usr 0.62 sys + 0.00 cusr 0.00 csys = 2.46 CPU)
+Total time: 90 wallclock secs ( 5.77 usr 1.91 sys + 0.00 cusr 0.00 csys = 7.68 CPU)
diff --git a/sql-bench/Results/create-mysql-Linux_2.4.4_SMP_alpha b/sql-bench/Results/create-mysql-Linux_2.4.4_SMP_alpha
new file mode 100644
index 00000000000..c6b2eaf9f23
--- /dev/null
+++ b/sql-bench/Results/create-mysql-Linux_2.4.4_SMP_alpha
@@ -0,0 +1,18 @@
+Testing server 'MySQL 4.0.5 beta' at 2002-10-23 12:45:06
+
+Testing the speed of creating and droping tables
+Testing with 10000 tables and 10000 loop count
+
+Testing create of tables
+Time for create_MANY_tables (10000): 238 wallclock secs ( 1.84 usr 0.51 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Accessing tables
+Time to select_group_when_MANY_tables (10000): 6 wallclock secs ( 0.90 usr 0.65 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing drop
+Time for drop_table_when_MANY_tables (10000): 10 wallclock secs ( 0.67 usr 0.44 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing create+drop
+Time for create+drop (10000): 15 wallclock secs ( 2.92 usr 0.95 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for create_key+drop (10000): 19 wallclock secs ( 4.55 usr 0.94 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Total time: 288 wallclock secs (10.88 usr 3.48 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
diff --git a/sql-bench/Results/insert-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/insert-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..719ed9f11b9
--- /dev/null
+++ b/sql-bench/Results/insert-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,106 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 15:39:59
+
+Testing the speed of inserting data into 1 table and do some selects on it.
+The tests are done with a table that has 100000 rows.
+
+Generating random keys
+Creating tables
+Inserting 100000 rows in order
+Inserting 100000 rows in reverse order
+Inserting 100000 rows in random order
+Time for insert (300000): 65 wallclock secs (12.32 usr 5.91 sys + 0.00 cusr 0.00 csys = 18.23 CPU)
+
+Testing insert of duplicates
+Time for insert_duplicates (100000): 16 wallclock secs ( 2.42 usr 2.15 sys + 0.00 cusr 0.00 csys = 4.57 CPU)
+
+Retrieving data from the table
+Time for select_big (10:3000000): 31 wallclock secs (21.84 usr 8.07 sys + 0.00 cusr 0.00 csys = 29.91 CPU)
+Time for order_by_big_key (10:3000000): 33 wallclock secs (23.12 usr 7.93 sys + 0.00 cusr 0.00 csys = 31.05 CPU)
+Time for order_by_big_key_desc (10:3000000): 32 wallclock secs (23.13 usr 8.16 sys + 0.00 cusr 0.00 csys = 31.29 CPU)
+Time for order_by_big_key_prefix (10:3000000): 31 wallclock secs (21.76 usr 8.21 sys + 0.00 cusr 0.00 csys = 29.97 CPU)
+Time for order_by_big_key2 (10:3000000): 31 wallclock secs (21.98 usr 7.84 sys + 0.00 cusr 0.00 csys = 29.82 CPU)
+Time for order_by_big_key_diff (10:3000000): 39 wallclock secs (22.07 usr 7.71 sys + 0.00 cusr 0.00 csys = 29.78 CPU)
+Time for order_by_big (10:3000000): 40 wallclock secs (21.73 usr 8.15 sys + 0.00 cusr 0.00 csys = 29.88 CPU)
+Time for order_by_range (500:125750): 3 wallclock secs ( 0.81 usr 0.41 sys + 0.00 cusr 0.00 csys = 1.22 CPU)
+Time for order_by_key_prefix (500:125750): 3 wallclock secs ( 0.98 usr 0.34 sys + 0.00 cusr 0.00 csys = 1.32 CPU)
+Time for order_by_key2_diff (500:250500): 4 wallclock secs ( 2.00 usr 0.58 sys + 0.00 cusr 0.00 csys = 2.58 CPU)
+Time for select_diff_key (500:1000): 138 wallclock secs ( 0.12 usr 0.02 sys + 0.00 cusr 0.00 csys = 0.14 CPU)
+Time for select_range_prefix (5010:42084): 7 wallclock secs ( 2.28 usr 0.46 sys + 0.00 cusr 0.00 csys = 2.74 CPU)
+Time for select_range_key2 (5010:42084): 7 wallclock secs ( 2.16 usr 0.40 sys + 0.00 cusr 0.00 csys = 2.56 CPU)
+Time for select_key_prefix (200000): 87 wallclock secs (51.79 usr 8.42 sys + 0.00 cusr 0.00 csys = 60.21 CPU)
+Time for select_key (200000): 82 wallclock secs (51.17 usr 8.13 sys + 0.00 cusr 0.00 csys = 59.30 CPU)
+Time for select_key_return_key (200000): 79 wallclock secs (48.93 usr 7.01 sys + 0.00 cusr 0.00 csys = 55.94 CPU)
+Time for select_key2 (200000): 86 wallclock secs (50.00 usr 7.89 sys + 0.00 cusr 0.00 csys = 57.89 CPU)
+Time for select_key2_return_key (200000): 81 wallclock secs (48.57 usr 6.51 sys + 0.00 cusr 0.00 csys = 55.08 CPU)
+Time for select_key2_return_prim (200000): 83 wallclock secs (49.27 usr 7.43 sys + 0.00 cusr 0.00 csys = 56.70 CPU)
+
+Test of compares with simple ranges
+Time for select_range_prefix (20000:43500): 6 wallclock secs ( 2.73 usr 0.53 sys + 0.00 cusr 0.00 csys = 3.26 CPU)
+Time for select_range_key2 (20000:43500): 5 wallclock secs ( 2.49 usr 0.52 sys + 0.00 cusr 0.00 csys = 3.01 CPU)
+Time for select_group (111): 42 wallclock secs ( 0.06 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.07 CPU)
+Time for min_max_on_key (15000): 6 wallclock secs ( 3.53 usr 0.54 sys + 0.00 cusr 0.00 csys = 4.07 CPU)
+Time for min_max (60): 23 wallclock secs ( 0.02 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.02 CPU)
+Time for count_on_key (100): 38 wallclock secs ( 0.03 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.04 CPU)
+Time for count (100): 33 wallclock secs ( 0.04 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.04 CPU)
+Time for count_distinct_big (20): 38 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.01 CPU)
+
+Testing update of keys with functions
+Time for update_of_key (50000): 14 wallclock secs ( 1.80 usr 0.94 sys + 0.00 cusr 0.00 csys = 2.74 CPU)
+Time for update_of_key_big (501): 20 wallclock secs ( 0.01 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.02 CPU)
+
+Testing update with key
+Time for update_with_key (300000): 60 wallclock secs ( 9.66 usr 6.21 sys + 0.00 cusr 0.00 csys = 15.87 CPU)
+Time for update_with_key_prefix (100000): 21 wallclock secs ( 6.04 usr 1.98 sys + 0.00 cusr 0.00 csys = 8.02 CPU)
+
+Testing update of all rows
+Time for update_big (10): 44 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing left outer join
+Time for outer_join_on_key (10:10): 40 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for outer_join (10:10): 48 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.01 CPU)
+Time for outer_join_found (10:10): 46 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.01 CPU)
+Time for outer_join_not_found (500:10): 31 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing SELECT ... WHERE id in (10 values)
+Time for select_in (500:5000) 0 wallclock secs ( 0.19 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.22 CPU)
+
+Time for select_join_in (500:5000) 1 wallclock secs ( 0.18 usr 0.02 sys + 0.00 cusr 0.00 csys = 0.20 CPU)
+
+Testing SELECT ... WHERE id in (100 values)
+Time for select_in (500:50000) 3 wallclock secs ( 0.57 usr 0.11 sys + 0.00 cusr 0.00 csys = 0.68 CPU)
+
+Time for select_join_in (500:50000) 1 wallclock secs ( 0.51 usr 0.19 sys + 0.00 cusr 0.00 csys = 0.70 CPU)
+
+Testing SELECT ... WHERE id in (1000 values)
+Time for select_in (500:500000) 26 wallclock secs ( 4.25 usr 1.40 sys + 0.00 cusr 0.00 csys = 5.65 CPU)
+
+Time for select_join_in (500:500000) 14 wallclock secs ( 4.09 usr 1.42 sys + 0.00 cusr 0.00 csys = 5.51 CPU)
+
+
+Testing INSERT INTO ... SELECT
+Time for insert_select_1_key (1): 5 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for insert_select_2_keys (1): 6 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for drop table(2): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing delete
+Time for delete_key (10000): 2 wallclock secs ( 0.39 usr 0.26 sys + 0.00 cusr 0.00 csys = 0.65 CPU)
+Time for delete_range (12): 11 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.01 CPU)
+
+Insert into table with 16 keys and with a primary key with 16 parts
+Time for insert_key (100000): 86 wallclock secs ( 7.22 usr 2.27 sys + 0.00 cusr 0.00 csys = 9.49 CPU)
+
+Testing update of keys
+Time for update_of_primary_key_many_keys (256): 25 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.01 CPU)
+
+Deleting rows from the table
+Time for delete_big_many_keys (128): 51 wallclock secs ( 0.02 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.02 CPU)
+
+Deleting everything from table
+Time for delete_all_many_keys (1): 51 wallclock secs ( 0.02 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.02 CPU)
+
+Inserting 100000 rows with multiple values
+Time for multiple_value_insert (100000): 5 wallclock secs ( 1.29 usr 0.00 sys + 0.00 cusr 0.00 csys = 1.29 CPU)
+
+Time for drop table(1): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Total time: 1730 wallclock secs (523.67 usr 128.19 sys + 0.00 cusr 0.00 csys = 651.86 CPU)
diff --git a/sql-bench/Results/insert-mysql-Linux_2.4.4_SMP_alpha b/sql-bench/Results/insert-mysql-Linux_2.4.4_SMP_alpha
new file mode 100644
index 00000000000..0cdf5cbede8
--- /dev/null
+++ b/sql-bench/Results/insert-mysql-Linux_2.4.4_SMP_alpha
@@ -0,0 +1,106 @@
+Testing server 'MySQL 4.0.5 beta' at 2002-10-23 12:49:54
+
+Testing the speed of inserting data into 1 table and do some selects on it.
+The tests are done with a table that has 100000 rows.
+
+Generating random keys
+Creating tables
+Inserting 100000 rows in order
+Inserting 100000 rows in reverse order
+Inserting 100000 rows in random order
+Time for insert (300000): 114 wallclock secs (25.11 usr 13.48 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing insert of duplicates
+Time for insert_duplicates (100000): 30 wallclock secs ( 4.71 usr 5.50 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Retrieving data from the table
+Time for select_big (10:3000000): 31 wallclock secs (17.94 usr 12.42 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for order_by_big_key (10:3000000): 31 wallclock secs (18.84 usr 12.61 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for order_by_big_key_desc (10:3000000): 32 wallclock secs (19.23 usr 12.70 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for order_by_big_key_prefix (10:3000000): 30 wallclock secs (17.36 usr 12.49 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for order_by_big_key2 (10:3000000): 30 wallclock secs (17.35 usr 12.38 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for order_by_big_key_diff (10:3000000): 36 wallclock secs (17.33 usr 12.44 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for order_by_big (10:3000000): 40 wallclock secs (17.31 usr 12.40 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for order_by_range (500:125750): 5 wallclock secs ( 0.97 usr 0.55 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for order_by_key_prefix (500:125750): 2 wallclock secs ( 0.92 usr 0.56 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for order_by_key2_diff (500:250500): 5 wallclock secs ( 1.67 usr 1.04 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_diff_key (500:1000): 163 wallclock secs ( 0.27 usr 0.04 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_range_prefix (5010:42084): 10 wallclock secs ( 2.63 usr 0.75 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_range_key2 (5010:42084): 10 wallclock secs ( 2.64 usr 0.76 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_key_prefix (200000): 141 wallclock secs (73.88 usr 18.25 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_key (200000): 142 wallclock secs (77.87 usr 17.06 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_key_return_key (200000): 146 wallclock secs (82.66 usr 16.24 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_key2 (200000): 142 wallclock secs (74.50 usr 19.30 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_key2_return_key (200000): 133 wallclock secs (73.16 usr 13.81 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_key2_return_prim (200000): 132 wallclock secs (70.56 usr 13.25 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Test of compares with simple ranges
+Time for select_range_prefix (20000:43500): 8 wallclock secs ( 3.65 usr 0.95 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_range_key2 (20000:43500): 9 wallclock secs ( 3.48 usr 0.96 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_group (111): 95 wallclock secs ( 0.05 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for min_max_on_key (15000): 10 wallclock secs ( 5.77 usr 1.18 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for min_max (60): 23 wallclock secs ( 0.02 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for count_on_key (100): 41 wallclock secs ( 0.04 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for count (100): 50 wallclock secs ( 0.04 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for count_distinct_big (20): 39 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing update of keys with functions
+Time for update_of_key (50000): 25 wallclock secs ( 4.24 usr 1.90 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for update_of_key_big (501): 18 wallclock secs ( 0.04 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing update with key
+Time for update_with_key (300000): 116 wallclock secs (21.90 usr 14.15 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for update_with_key_prefix (100000): 36 wallclock secs (11.11 usr 4.60 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing update of all rows
+Time for update_big (10): 22 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing left outer join
+Time for outer_join_on_key (10:10): 40 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for outer_join (10:10): 67 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for outer_join_found (10:10): 63 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for outer_join_not_found (500:10): 40 wallclock secs ( 0.01 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing SELECT ... WHERE id in (10 values)
+Time for select_in (500:5000) 0 wallclock secs ( 0.22 usr 0.06 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for select_join_in (500:5000) 1 wallclock secs ( 0.23 usr 0.06 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing SELECT ... WHERE id in (100 values)
+Time for select_in (500:50000) 4 wallclock secs ( 0.56 usr 0.26 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for select_join_in (500:50000) 2 wallclock secs ( 0.57 usr 0.24 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing SELECT ... WHERE id in (1000 values)
+Time for select_in (500:500000) 32 wallclock secs ( 3.96 usr 2.13 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for select_join_in (500:500000) 17 wallclock secs ( 4.02 usr 2.07 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+
+Testing INSERT INTO ... SELECT
+Time for insert_select_1_key (1): 6 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for insert_select_2_keys (1): 8 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for drop table(2): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing delete
+Time for delete_key (10000): 4 wallclock secs ( 0.88 usr 0.55 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for delete_range (12): 9 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Insert into table with 16 keys and with a primary key with 16 parts
+Time for insert_key (100000): 98 wallclock secs (13.49 usr 3.80 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing update of keys
+Time for update_of_primary_key_many_keys (256): 20 wallclock secs ( 0.03 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Deleting rows from the table
+Time for delete_big_many_keys (128): 47 wallclock secs ( 0.02 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Deleting everything from table
+Time for delete_all_many_keys (1): 47 wallclock secs ( 0.02 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Inserting 100000 rows with multiple values
+Time for multiple_value_insert (100000): 7 wallclock secs ( 1.88 usr 0.05 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for drop table(1): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Total time: 2381 wallclock secs (693.26 usr 241.11 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
diff --git a/sql-bench/Results/select-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/select-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..d6943e5711a
--- /dev/null
+++ b/sql-bench/Results/select-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,30 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 16:08:50
+
+Testing the speed of selecting on keys that consist of many parts
+The test-table has 10000 rows and the test is done with 500 ranges.
+
+Creating table
+Inserting 10000 rows
+Time to insert (10000): 3 wallclock secs ( 0.46 usr 0.25 sys + 0.00 cusr 0.00 csys = 0.71 CPU)
+
+Test if the database has a query cache
+Time for select_cache (10000): 88 wallclock secs ( 2.21 usr 0.38 sys + 0.00 cusr 0.00 csys = 2.59 CPU)
+
+Time for select_cache2 (10000): 89 wallclock secs ( 2.49 usr 0.39 sys + 0.00 cusr 0.00 csys = 2.88 CPU)
+
+Testing big selects on the table
+Time for select_big (70:17207): 0 wallclock secs ( 0.13 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.16 CPU)
+Time for select_range (410:1057904): 103 wallclock secs ( 8.73 usr 2.95 sys + 0.00 cusr 0.00 csys = 11.68 CPU)
+Time for min_max_on_key (70000): 153 wallclock secs (15.68 usr 2.24 sys + 0.00 cusr 0.00 csys = 17.92 CPU)
+Time for count_on_key (50000): 378 wallclock secs (11.70 usr 1.69 sys + 0.00 cusr 0.00 csys = 13.39 CPU)
+
+Time for count_group_on_key_parts (1000:100000): 43 wallclock secs ( 0.96 usr 0.31 sys + 0.00 cusr 0.00 csys = 1.27 CPU)
+Testing count(distinct) on the table
+Time for count_distinct_key_prefix (1000:1000): 28 wallclock secs ( 0.29 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.32 CPU)
+Time for count_distinct (1000:1000): 34 wallclock secs ( 0.24 usr 0.05 sys + 0.00 cusr 0.00 csys = 0.29 CPU)
+Time for count_distinct_2 (1000:1000): 38 wallclock secs ( 0.25 usr 0.07 sys + 0.00 cusr 0.00 csys = 0.32 CPU)
+Time for count_distinct_group_on_key (1000:6000): 43 wallclock secs ( 0.26 usr 0.05 sys + 0.00 cusr 0.00 csys = 0.31 CPU)
+Time for count_distinct_group_on_key_parts (1000:100000): 47 wallclock secs ( 0.98 usr 0.29 sys + 0.00 cusr 0.00 csys = 1.27 CPU)
+Time for count_distinct_group (1000:100000): 47 wallclock secs ( 1.00 usr 0.27 sys + 0.00 cusr 0.00 csys = 1.27 CPU)
+Time for count_distinct_big (100:1000000): 12 wallclock secs ( 7.14 usr 2.75 sys + 0.00 cusr 0.00 csys = 9.89 CPU)
+Total time: 1106 wallclock secs (52.54 usr 11.75 sys + 0.00 cusr 0.00 csys = 64.29 CPU)
diff --git a/sql-bench/Results/select-mysql-Linux_2.4.4_SMP_alpha b/sql-bench/Results/select-mysql-Linux_2.4.4_SMP_alpha
new file mode 100644
index 00000000000..939f130f92e
--- /dev/null
+++ b/sql-bench/Results/select-mysql-Linux_2.4.4_SMP_alpha
@@ -0,0 +1,30 @@
+Testing server 'MySQL 4.0.5 beta' at 2002-10-23 13:29:36
+
+Testing the speed of selecting on keys that consist of many parts
+The test-table has 10000 rows and the test is done with 500 ranges.
+
+Creating table
+Inserting 10000 rows
+Time to insert (10000): 4 wallclock secs ( 0.81 usr 0.38 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Test if the database has a query cache
+Time for select_cache (10000): 89 wallclock secs ( 3.03 usr 0.74 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for select_cache2 (10000): 91 wallclock secs ( 3.53 usr 0.76 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Testing big selects on the table
+Time for select_big (70:17207): 0 wallclock secs ( 0.14 usr 0.08 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for select_range (410:1057904): 242 wallclock secs ( 8.57 usr 4.60 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for min_max_on_key (70000): 178 wallclock secs (21.67 usr 4.75 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for count_on_key (50000): 412 wallclock secs (16.70 usr 3.58 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Time for count_group_on_key_parts (1000:100000): 37 wallclock secs ( 1.02 usr 0.48 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Testing count(distinct) on the table
+Time for count_distinct_key_prefix (1000:1000): 28 wallclock secs ( 0.44 usr 0.09 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for count_distinct (1000:1000): 32 wallclock secs ( 0.44 usr 0.07 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for count_distinct_2 (1000:1000): 32 wallclock secs ( 0.44 usr 0.08 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for count_distinct_group_on_key (1000:6000): 38 wallclock secs ( 0.48 usr 0.12 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for count_distinct_group_on_key_parts (1000:100000): 50 wallclock secs ( 1.15 usr 0.47 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for count_distinct_group (1000:100000): 50 wallclock secs ( 1.14 usr 0.52 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time for count_distinct_big (100:1000000): 15 wallclock secs ( 7.36 usr 4.25 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Total time: 1298 wallclock secs (66.92 usr 20.96 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
diff --git a/sql-bench/Results/transactions-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/transactions-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..821d74a7c01
--- /dev/null
+++ b/sql-bench/Results/transactions-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,3 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 16:27:17
+
+Test skipped because the database doesn't support transactions
diff --git a/sql-bench/Results/transactions-mysql-Linux_2.4.4_SMP_alpha b/sql-bench/Results/transactions-mysql-Linux_2.4.4_SMP_alpha
new file mode 100644
index 00000000000..47f81534c1e
--- /dev/null
+++ b/sql-bench/Results/transactions-mysql-Linux_2.4.4_SMP_alpha
@@ -0,0 +1,3 @@
+Testing server 'MySQL 4.0.5 beta' at 2002-10-23 13:51:14
+
+Test skipped because the database doesn't support transactions
diff --git a/sql-bench/Results/wisconsin-mysql-Linux_2.4.16_64GB_SMP_i686 b/sql-bench/Results/wisconsin-mysql-Linux_2.4.16_64GB_SMP_i686
new file mode 100644
index 00000000000..8b054de0a3d
--- /dev/null
+++ b/sql-bench/Results/wisconsin-mysql-Linux_2.4.16_64GB_SMP_i686
@@ -0,0 +1,14 @@
+Testing server 'MySQL 4.0.2 alpha' at 2002-05-20 16:27:17
+
+Wisconsin benchmark test
+
+Time for create_table (3): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Inserting data
+Time to insert (31000): 8 wallclock secs ( 0.89 usr 0.68 sys + 0.00 cusr 0.00 csys = 1.57 CPU)
+Time to delete_big (1): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Running the actual benchmark
+Time for wisc_benchmark (114): 4 wallclock secs ( 2.17 usr 0.52 sys + 0.00 cusr 0.00 csys = 2.69 CPU)
+
+Total time: 12 wallclock secs ( 3.07 usr 1.20 sys + 0.00 cusr 0.00 csys = 4.27 CPU)
diff --git a/sql-bench/Results/wisconsin-mysql-Linux_2.4.4_SMP_alpha b/sql-bench/Results/wisconsin-mysql-Linux_2.4.4_SMP_alpha
new file mode 100644
index 00000000000..445246a27c7
--- /dev/null
+++ b/sql-bench/Results/wisconsin-mysql-Linux_2.4.4_SMP_alpha
@@ -0,0 +1,14 @@
+Testing server 'MySQL 4.0.5 beta' at 2002-10-23 13:51:14
+
+Wisconsin benchmark test
+
+Time for create_table (3): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Inserting data
+Time to insert (31000): 13 wallclock secs ( 1.99 usr 1.40 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+Time to delete_big (1): 0 wallclock secs ( 0.00 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Running the actual benchmark
+Time for wisc_benchmark (114): 4 wallclock secs ( 1.66 usr 0.73 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
+
+Total time: 17 wallclock secs ( 3.66 usr 2.13 sys + 0.00 cusr 0.00 csys = 0.00 CPU)
diff --git a/sql-bench/as3ap.sh b/sql-bench/as3ap.sh
new file mode 100644
index 00000000000..f6827c004d7
--- /dev/null
+++ b/sql-bench/as3ap.sh
@@ -0,0 +1,637 @@
+#!@PERL@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+#
+# AS3AP single-user benchmark.
+#
+
+##################### Standard benchmark inits ##############################
+
+use Cwd;
+use DBI;
+use Benchmark;
+
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
+require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
+
+$opt_loop_count=1;
+
+#Create tables
+
+$dbh = $server->connect();
+
+#Create Table
+$sth = $dbh->do("drop table uniques");
+$sth = $dbh->do("drop table updates");
+$sth = $dbh->do("drop table hundred");
+$sth = $dbh->do("drop table tenpct");
+$sth = $dbh->do("drop table tiny");
+
+#Temporary table
+$sth = $dbh->do("drop table saveupdates");
+
+@fields=("col_key int not null",
+ "col_int int not null",
+ "col_signed int not null",
+ "col_float float not null",
+ "col_double float not null",
+ "col_decim numeric(18,2) not null",
+ "col_date char(20) not null",
+ "col_code char(10) not null",
+ "col_name char(20) not null",
+ "col_address varchar(80) not null");
+
+do_many($dbh,$server->create("uniques",\@fields,[]));
+do_many($dbh,$server->create("updates",\@fields,[]));
+do_many($dbh,$server->create("hundred",\@fields,[]));
+do_many($dbh,$server->create("tenpct",\@fields,[]));
+do_many($dbh,$server->create("tiny",["col_key int not null"],[]));
+
+print "Start AS3AP benchmark\n\n";
+
+$start_time=new Benchmark;
+
+print "Load DATA\n";
+#Load DATA
+
+@table_names=("uniques","updates","hundred","tenpct","tiny");
+
+$loop_time=new Benchmark;
+
+if ($opt_fast && $server->{'limits'}->{'load_data_infile'})
+{
+ for ($ti = 0; $ti <= $#table_names; $ti++)
+ {
+ my $table_name = $table_names[$ti];
+ my $file = "$pwd/Data/AS3AP/${table_name}\.new";
+ print "$table_name - $file\n" if ($opt_debug);
+ $row_count += $server->insert_file($table_name,$file,$dbh);
+ }
+}
+else
+{
+ for ($ti = 0; $ti <= $#table_names; $ti++)
+ {
+ my $table_name = $table_names[$ti];
+ print "$table_name - $file\n" if ($opt_debug);
+ my $insert_start = "insert into $table_name values (";
+ open(DATA, "$pwd/Data/AS3AP/${table_name}\.new") || die "Can't open text file: $pwd/Data/AS3AP/${table_name}\.new\n";
+ while(<DATA>)
+ {
+ chomp;
+ next unless ( $_ =~ /\w/ ); # skip blank lines
+ $command = $insert_start."$_".")";
+ $command =~ $server->fix_to_insert($command);
+ print "$command\n" if ($opt_debug);
+ $sth = $dbh->do($command) or die "Got error: $DBI::errstr when executing '$command'\n";
+ $row_count++;
+ }
+ close(DATA);
+ }
+}
+
+$end_time=new Benchmark;
+print "Time for Load Data - " . "($row_count): " .
+timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+
+
+print "Create Index\n";
+
+test_command("create_idx_uniques_key_bt",
+ "time for create_idx_uniques_key_bt",
+ "create unique index uniques_key_bt on uniques (col_key)",$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_key_bt",
+ "time for create_idx_updates_key_bt",
+ "create unique index updates_key_bt on updates (col_key)",$dbh,$opt_loop_count);
+
+test_command("create_idx_hundred_key_bt",
+ "time for create_idx_hundred_key_bt",
+ "create unique index hundred_key_bt on hundred (col_key)",
+ $dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_key_bt",
+ "time for create_idx_tenpct_key_bt",
+ "create unique index tenpct_key_bt on tenpct (col_key)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_key_code_bt",
+ "time for create_idx_tenpct_key_code_bt",
+ "create index tenpct_key_code_bt on tenpct (col_key,col_code)",
+ $dbh,$opt_loop_count);
+
+test_command("create_idx_tiny_key_bt",
+ "time for create_idx_tiny_key_bt",
+ "create index tiny_key_bt on tiny (col_key)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_int_bt",
+ "time for create_idx_tenpct_int_bt",
+ "create index tenpct_int_bt on tenpct (col_int)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_signed_bt",
+ "time for create_idx_tenpct_signed_bt",
+ "create index tenpct_signed_bt on tenpct (col_signed)",$dbh,$opt_loop_count);
+
+test_command("create_idx_uniques_code_h",
+ "time for create_idx_uniques_code_h",
+ "create index uniques_code_h on uniques (col_code)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_double_bt",
+ "time for create_idx_tenpct_double_bt",
+ "create index tenpct_double_bt on tenpct (col_double)",$dbh,$opt_loop_count);
+
+
+test_command("create_idx_updates_decim_bt",
+ "time for create_idx_updates_decim_bt",
+ "create index updates_decim_bt on updates (col_decim)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_float_bt",
+ "time for create_idx_tenpct_float_bt",
+ "create index tenpct_float_bt on tenpct (col_float)",$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_int_bt",
+ "time for create_idx_updates_int_bt",
+ "create index updates_int_bt on updates (col_int)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_decim_bt",
+ "time for create_idx_tenpct_decim_bt",
+ "create index tenpct_decim_bt on tenpct (col_decim)",$dbh,$opt_loop_count);
+
+test_command("create_idx_hundred_code_h",
+ "time for create_idx_hundred_code_h",
+ "create index hundred_code_h on hundred (col_code)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_name_h",
+ "time for create_idx_tenpct_name_h",
+ "create index tenpct_name_h on tenpct (col_name)",$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_code_h",
+ "time for create_idx_updates_code_h",
+ "create index updates_code_h on updates (col_code)",$dbh,$opt_loop_count);
+
+test_command("create_idx_tenpct_code_h",
+ "time for create_idx_tenpct_code_h",
+ "create index tenpct_code_h on tenpct (col_code)",$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_double_bt",
+ "time for create_idx_updates_double_bt",
+ "create index updates_double_bt on updates (col_double)",$dbh,$opt_loop_count);
+
+test_command("create_idx_hundred_foreign",
+ "time for create_idx_hundred_foreign",
+ "alter table hundred add constraint fk_hundred_updates foreign key (col_signed)
+ references updates (col_key)",$dbh,$opt_loop_count);
+
+test_query("sel_1_cl",
+ "Time to sel_1_cl",
+ "select col_key, col_int, col_signed, col_code, col_double, col_name
+ from updates where col_key = 1000",$dbh,$opt_loop_count);
+
+test_query("join_3_cl",
+ "Time to join_3_cl",
+ "select uniques.col_signed, uniques.col_date,
+ hundred.col_signed, hundred.col_date,
+ tenpct.col_signed, tenpct.col_date
+ from uniques, hundred, tenpct
+ where uniques.col_key = hundred.col_key
+ and uniques.col_key = tenpct.col_key
+ and uniques.col_key = 1000",$dbh,$opt_loop_count);
+
+test_query("sel_100_ncl",
+ "Time to sel_100_ncl",
+ "select col_key, col_int, col_signed, col_code,col_double, col_name
+ from updates where col_int <= 100",$dbh,$opt_loop_count);
+
+test_query("table_scan",
+ "Time to table_scan",
+ "select * from uniques where col_int = 1",$dbh,$opt_loop_count);
+
+test_query("agg_func",
+ "Time for agg_func",
+ "select min(col_key) from hundred group by col_name",$dbh,$opt_loop_count);
+
+test_query("agg_scal",
+ "Time for agg_scal",
+ "select min(col_key) from uniques",$dbh,$opt_loop_count);
+
+test_query("sel_100_cl",
+ "Time for sel_100_cl",
+ "select col_key, col_int, col_signed, col_code,
+ col_double, col_name
+ from updates where col_key <= 100",$dbh,$opt_loop_count);
+
+test_query("join_3_ncl",
+ "Time for join_3_ncl",
+ "select uniques.col_signed, uniques.col_date,
+ hundred.col_signed, hundred.col_date,
+ tenpct.col_signed, tenpct.col_date
+ from uniques, hundred, tenpct
+ where uniques.col_code = hundred.col_code
+ and uniques.col_code = tenpct.col_code
+ and uniques.col_code = 'BENCHMARKS'",$dbh,$opt_loop_count);
+
+test_query("sel_10pct_ncl",
+ "Time for sel_10pct_ncl",
+ "select col_key, col_int, col_signed, col_code,
+ col_double, col_name
+ from tenpct
+ where col_name = 'THE+ASAP+BENCHMARKS+'",$dbh,$opt_loop_count);
+
+if ($limits->{'subqueries'}){
+ test_query("agg_simple_report",
+ "Time for agg_simple_report",
+ "select avg(updates.col_decim)
+ from updates
+ where updates.col_key in
+ (select updates.col_key
+ from updates, hundred
+ where hundred.col_key = updates.col_key
+ and updates.col_decim > 980000000)",$dbh,$opt_loop_count);
+}else{
+ print "agg_simple_report - Failed\n\n";
+}
+
+test_query("agg_info_retrieval",
+ "Time for agg_info_retrieval",
+ "select count(col_key)
+ from tenpct
+ where col_name = 'THE+ASAP+BENCHMARKS'
+ and col_int <= 100000000
+ and col_signed between 1 and 99999999
+ and not (col_float between -450000000 and 450000000)
+ and col_double > 600000000
+ and col_decim < -600000000",$dbh,$opt_loop_count);
+
+if ($limits->{'views'}){
+ test_query("agg_create_view",
+ "Time for agg_create_view",
+ "create view
+ reportview(col_key,col_signed,col_date,col_decim,
+ col_name,col_code,col_int) as
+ select updates.col_key, updates.col_signed,
+ updates.col_date, updates.col_decim,
+ hundred.col_name, hundred.col_code,
+ hundred.col_int
+ from updates, hundred
+ where updates.col_key = hundred.col_key",$dbh,$opt_loop_count);
+
+ test_query("agg_subtotal_report",
+ "Time for agg_subtotal_report",
+ "select avg(col_signed), min(col_signed), max(col_signed),
+ max(col_date), min(col_date),
+ count(distinct col_name), count(col_name),
+ col_code, col_int
+ from reportview
+ where col_decim >980000000
+ group by col_code, col_int",$dbh,$opt_loop_count);
+
+
+ test_query("agg_total_report",
+ "Time for agg_total_report",
+ "select avg(col_signed), min(col_signed), max(col_signed),
+ max(col_date), min(col_date),
+ count(distinct col_name), count(col_name),
+ count(col_code), count(col_int)
+ from reportview
+ where col_decim >980000000",$dbh,$opt_loop_count);
+}else{
+ print "agg_create_view - Failed\n\n";
+ print "agg_subtotal_report - Failed\n\n";
+ print "agg_total_report - Failed\n\n";
+}
+
+#fix from here
+test_query("join_2_cl",
+ "Time for join_2_cl",
+ "select uniques.col_signed, uniques.col_name,
+ hundred.col_signed, hundred.col_name
+ from uniques, hundred
+ where uniques.col_key = hundred.col_key
+ and uniques.col_key =1000"
+ ,$dbh,$opt_loop_count);
+
+test_query("join_2",
+ "Time for join_2",
+ "select uniques.col_signed, uniques.col_name,
+ hundred.col_signed, hundred.col_name
+ from uniques, hundred
+ where uniques.col_address = hundred.col_address
+ and uniques.col_address = 'SILICON VALLEY'"
+ ,$dbh,$opt_loop_count);
+
+test_query("sel_variable_select_low",
+ "Time for sel_variable_select_low",
+ "select col_key, col_int, col_signed, col_code,
+ col_double, col_name
+ from tenpct
+ where col_signed < -500000000"
+ ,$dbh,$opt_loop_count);
+
+test_query("sel_variable_select_high",
+ "Time for sel_variable_select_high",
+ "select col_key, col_int, col_signed, col_code,
+ col_double, col_name
+ from tenpct
+ where col_signed < -250000000"
+ ,$dbh,$opt_loop_count);
+
+test_query("join_4_cl",
+ "Time for join_4_cl",
+ "select uniques.col_date, hundred.col_date,
+ tenpct.col_date, updates.col_date
+ from uniques, hundred, tenpct, updates
+ where uniques.col_key = hundred.col_key
+ and uniques.col_key = tenpct.col_key
+ and uniques.col_key = updates.col_key
+ and uniques.col_key = 1000"
+ ,$dbh,$opt_loop_count);
+
+test_query("proj_100",
+ "Time for proj_100",
+ "select distinct col_address, col_signed from hundred"
+ ,$dbh,$opt_loop_count);
+
+test_query("join_4_ncl",
+ "Time for join_4_ncl",
+ "select uniques.col_date, hundred.col_date,
+ tenpct.col_date, updates.col_date
+ from uniques, hundred, tenpct, updates
+ where uniques.col_code = hundred.col_code
+ and uniques.col_code = tenpct.col_code
+ and uniques.col_code = updates.col_code
+ and uniques.col_code = 'BENCHMARKS'"
+ ,$dbh,$opt_loop_count);
+
+test_query("proj_10pct",
+ "Time for proj_10pct",
+ "select distinct col_signed from tenpct"
+ ,$dbh,$opt_loop_count);
+
+test_query("sel_1_ncl",
+ "Time for sel_1_ncl",
+ "select col_key, col_int, col_signed, col_code,
+ col_double, col_name
+ from updates where col_code = 'BENCHMARKS'"
+ ,$dbh,$opt_loop_count);
+
+test_query("join_2_ncl",
+ "Time for join_2_ncl",
+ "select uniques.col_signed, uniques.col_name,
+ hundred.col_signed, hundred.col_name
+ from uniques, hundred
+ where uniques.col_code = hundred.col_code
+ and uniques.col_code = 'BENCHMARKS'"
+ ,$dbh,$opt_loop_count);
+
+if ($limits->{'foreign_key'}){
+ do_many($dbh,$server->create("integrity_temp",\@fields,[]));
+
+ test_query("integrity_test_1",
+ "Time for integrity_test",
+ "insert into integrity_temp select *
+ from hundred where col_int=0",$dbh,$opt_loop_count);
+
+ test_query("integrity_test_2",
+ "Time for integrity_test",
+ "update hundred set col_signed = '-500000000'
+ where col_int = 0",$dbh,$opt_loop_count);
+
+ test_query("integrity_test_3",
+ "Time for integrity_test",
+ "update hundred set col_signed = '-500000000'
+ where col_int = 0",$dbh,$opt_loop_count);
+
+
+}else{
+ print "integrity_test - Failed\n\n";
+}
+
+push @drop_seq_command,$server->drop_index("updates","updates_int_bt");
+push @drop_seq_command,$server->drop_index("updates","updates_double_bt");
+push @drop_seq_command,$server->drop_index("updates","updates_decim_bt");
+push @drop_seq_command,$server->drop_index("updates","updates_code_h");
+
+test_many_command("Drop updates keys",
+ "Time for drop_updates_keys",
+ \@drop_seq_command,$dbh,$opt_loop_count);
+
+do_many($dbh,$server->create("saveupdates",\@fields,[]));
+
+test_command("bulk_save",
+ "Time for bulk_save",
+ "insert into saveupdates select *
+ from updates where col_key between 5000 and 5999"
+ ,$dbh,$opt_loop_count);
+
+test_command("bulk_modify",
+ "Time for bulk_modify",
+ "update updates
+ set col_key = col_key - 100000
+ where col_key between 5000 and 5999"
+ ,$dbh,$opt_loop_count);
+
+safe_command("upd_append_duplicate",
+ "Time for upd_append_duplicate",
+ "insert into updates
+ values (6000, 0, 60000, 39997.90,
+ 50005.00, 50005.00,
+ '11/10/1985', 'CONTROLLER',
+ 'ALICE IN WONDERLAND',
+ 'UNIVERSITY OF ILLINOIS AT CHICAGO')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_remove_duplicate",
+ "Time for upd_remove_duplicate",
+ "delete from updates where col_key = 6000 and col_int = 0"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_app_t_mid",
+ "Time for upd_app_t_mid",
+ "insert into updates
+ values (5005, 5005, 50005, 50005.00, 50005.00,
+ 50005.00, '1/1/1988', 'CONTROLLER',
+ 'ALICE IN WONDERLAND',
+ 'UNIVERSITY OF ILLINOIS AT CHICAGO')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_mod_t_mid",
+ "Time for upd_mod_t_mid",
+ "update updates set col_key = '-5000'
+ where col_key = 5005"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_del_t_mid",
+ "Time for upd_del_t_mid",
+ "delete from updates
+ where (col_key='5005') or (col_key='-5000')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_app_t_end",
+ "Time for upd_app_t_end",
+ "delete from updates
+ where (col_key='5005') or (col_key='-5000')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_mod_t_end",
+ "Time for upd_mod_t_end",
+ "update updates
+ set col_key = -1000
+ where col_key = 1000000001"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_del_t_end",
+ "Time for upd_del_t_end",
+ "delete from updates where col_key = -1000"
+ ,$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_code_h",
+ "time for create_idx_updates_code_h",
+ "create index updates_code_h on updates (col_code)",
+ $dbh,$opt_loop_count);
+
+test_command("upd_app_t_mid",
+ "Time for upd_app_t_mid",
+ "insert into updates
+ values (5005, 5005, 50005, 50005.00, 50005.00,
+ 50005.00, '1/1/1988', 'CONTROLLER',
+ 'ALICE IN WONDERLAND',
+ 'UNIVERSITY OF ILLINOIS AT CHICAGO')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_mod_t_cod",
+ "Time for upd_mod_t_cod",
+ "update updates
+ set col_code = 'SQL+GROUPS'
+ where col_key = 5005"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_del_t_mid",
+ "Time for upd_del_t_mid",
+ "delete from updates
+ where (col_key='5005') or (col_key='-5000')"
+ ,$dbh,$opt_loop_count);
+
+test_command("create_idx_updates_int_bt",
+ "time for create_idx_updates_int_bt",
+ "create index updates_int_bt on updates (col_int)",
+ $dbh,$opt_loop_count);
+
+test_command("upd_app_t_mid",
+ "Time for upd_app_t_mid",
+ "insert into updates
+ values (5005, 5005, 50005, 50005.00, 50005.00,
+ 50005.00, '1/1/1988', 'CONTROLLER',
+ 'ALICE IN WONDERLAND',
+ 'UNIVERSITY OF ILLINOIS AT CHICAGO')"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_mod_t_int",
+ "Time for upd_mod_t_int",
+ "update updates set col_int = 50015 where col_key = 5005"
+ ,$dbh,$opt_loop_count);
+
+test_command("upd_del_t_mid",
+ "Time for upd_del_t_mid",
+ "delete from updates
+ where (col_key='5005') or (col_key='-5000')"
+ ,$dbh,$opt_loop_count);
+
+test_command("bulk_append",
+ "Time for bulk_append",
+ "insert into updates select * from saveupdates"
+ ,$dbh,$opt_loop_count);
+
+test_command("bulk_delete",
+ "Time for bulk_delete",
+ "delete from updates where col_key < 0"
+ ,$dbh,$opt_loop_count);
+
+################################ END ###################################
+####
+#### End of the test...Finally print time used to execute the
+#### whole test.
+
+$dbh->disconnect;
+
+end_benchmark($start_time);
+
+############################ HELP FUNCTIONS ##############################
+
+sub test_query
+{
+ my($test_text,$result_text,$query,$dbh,$count)=@_;
+ my($i,$loop_time,$end_time);
+
+ print $test_text . "\n";
+ $loop_time=new Benchmark;
+ for ($i=0 ; $i < $count ; $i++)
+ {
+ defined(fetch_all_rows($dbh,$query)) or warn $DBI::errstr;
+ }
+ $end_time=new Benchmark;
+ print $result_text . "($count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+
+sub test_command
+{
+ my($test_text,$result_text,$query,$dbh,$count)=@_;
+ my($i,$loop_time,$end_time);
+
+ print $test_text . "\n";
+ $loop_time=new Benchmark;
+ for ($i=0 ; $i < $count ; $i++)
+ {
+ $dbh->do($query) or die $DBI::errstr;
+ }
+ $end_time=new Benchmark;
+ print $result_text . "($count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+sub safe_command
+{
+ my($test_text,$result_text,$query,$dbh,$count)=@_;
+ my($i,$loop_time,$end_time);
+
+ print $test_text . "\n";
+ $loop_time=new Benchmark;
+ for ($i=0 ; $i < $count ; $i++)
+ {
+ safe_do_many($dbh,$query);
+ }
+ $end_time=new Benchmark;
+ print $result_text . "($count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+sub test_many_command
+{
+ my($test_text,$result_text,$query,$dbh,$count)=@_;
+ my($i,$loop_time,$end_time);
+
+ $loop_time=new Benchmark;
+ for ($i=0 ; $i < $count ; $i++)
+ {
+ safe_do_many($dbh, @$query);
+ }
+ $end_time=new Benchmark;
+ print $result_text . "($count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+
diff --git a/sql-bench/bench-count-distinct.sh b/sql-bench/bench-count-distinct.sh
new file mode 100644
index 00000000000..8ebc910df59
--- /dev/null
+++ b/sql-bench/bench-count-distinct.sh
@@ -0,0 +1,259 @@
+#!@PERL@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+#
+# Test of selecting on keys that consist of many parts
+#
+##################### Standard benchmark inits ##############################
+
+use Cwd;
+use DBI;
+use Getopt::Long;
+use Benchmark;
+
+$opt_loop_count=10000;
+$opt_medium_loop_count=200;
+$opt_small_loop_count=10;
+$opt_regions=6;
+$opt_groups=100;
+
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
+require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
+
+$columns=min($limits->{'max_columns'},500,($limits->{'query_size'}-50)/24,
+ $limits->{'max_conditions'}/2-3);
+
+if ($opt_small_test)
+{
+ $opt_loop_count/=10;
+ $opt_medium_loop_count/=10;
+ $opt_small_loop_count/=10;
+ $opt_groups/=10;
+}
+
+print "Testing the speed of selecting on keys that consist of many parts\n";
+print "The test-table has $opt_loop_count rows and the test is done with $columns ranges.\n\n";
+
+####
+#### Connect and start timeing
+####
+
+$dbh = $server->connect();
+$start_time=new Benchmark;
+
+####
+#### Create needed tables
+####
+
+goto select_test if ($opt_skip_create);
+
+print "Creating table\n";
+$dbh->do("drop table bench1" . $server->{'drop_attr'});
+
+do_many($dbh,$server->create("bench1",
+ ["region char(1) NOT NULL",
+ "idn integer(6) NOT NULL",
+ "rev_idn integer(6) NOT NULL",
+ "grp integer(6) NOT NULL"],
+ ["primary key (region,idn)",
+ "unique (region,rev_idn)",
+ "unique (region,grp,idn)"]));
+if ($opt_lock_tables)
+{
+ do_query($dbh,"LOCK TABLES bench1 WRITE");
+}
+
+if ($opt_fast && defined($server->{vacuum}))
+{
+ $server->vacuum(1,\$dbh);
+}
+
+####
+#### Insert $opt_loop_count records with
+#### region: "A" -> "E"
+#### idn: 0 -> count
+#### rev_idn: count -> 0,
+#### grp: distributed values 0 - > count/100
+####
+
+print "Inserting $opt_loop_count rows\n";
+
+$loop_time=new Benchmark;
+$query="insert into bench1 values (";
+$half_done=$opt_loop_count/2;
+for ($id=0,$rev_id=$opt_loop_count-1 ; $id < $opt_loop_count ; $id++,$rev_id--)
+{
+ $grp=$id*3 % $opt_groups;
+ $region=chr(65+$id%$opt_regions);
+ do_query($dbh,"$query'$region',$id,$rev_id,$grp)");
+ if ($id == $half_done)
+ { # Test with different insert
+ $query="insert into bench1 (region,idn,rev_idn,grp) values (";
+ }
+}
+
+$end_time=new Benchmark;
+print "Time to insert ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+
+if ($opt_lock_tables)
+{
+ do_query($dbh,"UNLOCK TABLES");
+}
+
+if ($opt_fast && defined($server->{vacuum}))
+{
+ $server->vacuum(0,\$dbh,"bench1");
+}
+
+if ($opt_lock_tables)
+{
+ do_query($dbh,"LOCK TABLES bench1 WRITE");
+}
+
+####
+#### Do some selects on the table
+####
+
+select_test:
+
+
+
+if ($limits->{'group_distinct_functions'})
+{
+ print "Testing count(distinct) on the table\n";
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select count(distinct region) from bench1");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_key_prefix ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select count(distinct grp) from bench1");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select count(distinct grp),count(distinct rev_idn) from bench1");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_2 ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select region,count(distinct idn) from bench1 group by region");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_group_on_key ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select grp,count(distinct idn) from bench1 group by grp");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_group_on_key_parts ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select grp,count(distinct rev_idn) from bench1 group by grp");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_group ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ $test_count=$opt_medium_loop_count/10;
+ for ($i=0 ; $i < $test_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select idn,count(distinct region) from bench1 group by idn");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $test_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_big ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
+}
+
+####
+#### End of benchmark
+####
+
+if ($opt_lock_tables)
+{
+ do_query($dbh,"UNLOCK TABLES");
+}
+if (!$opt_skip_delete)
+{
+ do_query($dbh,"drop table bench1" . $server->{'drop_attr'});
+}
+
+if ($opt_fast && defined($server->{vacuum}))
+{
+ $server->vacuum(0,\$dbh);
+}
+
+$dbh->disconnect; # close connection
+
+end_benchmark($start_time);
diff --git a/sql-bench/bench-init.pl.sh b/sql-bench/bench-init.pl.sh
index 204d15d7ab3..d61551ffb3b 100644
--- a/sql-bench/bench-init.pl.sh
+++ b/sql-bench/bench-init.pl.sh
@@ -31,31 +31,39 @@
# $server Object for current server
# $limits Hash reference to limits for benchmark
-$benchmark_version="2.14";
+$benchmark_version="2.15";
use Getopt::Long;
+use POSIX;
require "$pwd/server-cfg" || die "Can't read Configuration file: $!\n";
$|=1; # Output data immediately
-$opt_skip_test=$opt_skip_create=$opt_skip_delete=$opt_verbose=$opt_fast_insert=$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=$opt_log=$opt_use_old_results=$opt_help=$opt_odbc=$opt_small_test=$opt_small_tables=$opt_samll_key_tables=$opt_stage=$opt_old_headers=$opt_die_on_errors=$opt_tcpip=0;
-$opt_cmp=$opt_user=$opt_password="";
+$opt_skip_test=$opt_skip_create=$opt_skip_delete=$opt_verbose=$opt_fast_insert=$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=$opt_log=$opt_use_old_results=$opt_help=$opt_odbc=$opt_small_test=$opt_small_tables=$opt_samll_key_tables=$opt_stage=$opt_old_headers=$opt_die_on_errors=$opt_tcpip=$opt_random=0;
+$opt_cmp=$opt_user=$opt_password=$opt_connect_options="";
$opt_server="mysql"; $opt_dir="output";
$opt_host="localhost";$opt_database="test";
$opt_machine=""; $opt_suffix="";
$opt_create_options=undef;
+$opt_optimization="None";
+$opt_hw="";
+$opt_threads=5;
-$opt_time_limit=10*60; # Don't wait more than 10 min for some tests
+if (!defined($opt_time_limit))
+{
+ $opt_time_limit=10*60; # Don't wait more than 10 min for some tests
+}
$log_prog_args=join(" ", skip_arguments(\@ARGV,"comments","cmp","server",
"user", "host", "database", "password",
"use-old-results","skip-test",
+ "optimization","hw",
"machine", "dir", "suffix", "log"));
-GetOptions("skip-test=s","comments=s","cmp=s","server=s","user=s","host=s","database=s","password=s","loop-count=i","row-count=i","skip-create","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","field-count=i","regions=i","groups=i","time-limit=i","log","use-old-results","machine=s","dir=s","suffix=s","help","odbc","small-test","small-tables","small-key-tables","stage=i","old-headers","die-on-errors","create-options=s","hires","tcpip","silent") || usage();
+GetOptions("skip-test=s","comments=s","cmp=s","server=s","user=s","host=s","database=s","password=s","loop-count=i","row-count=i","skip-create","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","field-count=i","regions=i","groups=i","time-limit=i","log","use-old-results","machine=s","dir=s","suffix=s","help","odbc","small-test","small-tables","small-key-tables","stage=i","threads=i","random","old-headers","die-on-errors","create-options=s","hires","tcpip","silent","optimization=s","hw=s","socket=s","connect-options=s") || usage();
usage() if ($opt_help);
$server=get_server($opt_server,$opt_host,$opt_database,$opt_odbc,
- machine_part());
+ machine_part(), $opt_socket, $opt_connect_options);
$limits=merge_limits($server,$opt_cmp);
$date=date();
@estimated=(0.0,0.0,0.0); # For estimated time support
@@ -410,24 +418,8 @@ sub machine_part
sub machine
{
- $name= `uname -s -r -m`;
- if ($?)
- {
- $name= `uname -s -m`;
- }
- if ($?)
- {
- $name= `uname -s`;
- }
- if ($?)
- {
- $name= `uname`;
- }
- if ($?)
- {
- $name="unknown";
- }
- chomp($name); $name =~ s/[\n\r]//g;
+ my @name = POSIX::uname();
+ my $name= $name[0] . " " . $name[2] . " " . $name[4];
return $name;
}
@@ -515,6 +507,10 @@ All benchmarks takes the following options:
--password='password'
Password for the current user.
+--socket='socket'
+ If the database supports connecting through a Unix socket,
+ then use this socket to connect
+
--regions
This is a test specific option that is only used when debugging a test.
This usually means how AND levels should be tested.
@@ -553,6 +549,13 @@ All benchmarks takes the following options:
different server options without overwritten old files.
When using --fast the suffix is automaticly set to '_fast'.
+--random
+ Inform test suite that we are generate random inital values for sequence of
+ test executions. It should be used for imitation of real conditions.
+
+--threads=# (Default 5)
+ Number of threads for multi-user benchmarks.
+
--tcpip
Inform test suite that we are using TCP/IP to connect to the server. In
this case we can\t do many new connections in a row as we in this case may
@@ -572,6 +575,17 @@ All benchmarks takes the following options:
--verbose
This is a test specific option that is only used when debugging a test.
Print more information about what is going on.
+
+--optimization='some comments'
+ Add coments about optimization of DBMS, which was done before the test.
+
+--hw='some comments'
+ Add coments about hardware used for this test.
+
+--connect-options='some connect options'
+ Add options, which uses at DBI connect.
+ For example --connect-options=mysql_read_default_file=/etc/my.cnf.
+
EOF
exit(0);
}
diff --git a/sql-bench/copy-db.sh b/sql-bench/copy-db.sh
index f5394b09923..3d2f418280c 100644
--- a/sql-bench/copy-db.sh
+++ b/sql-bench/copy-db.sh
@@ -22,12 +22,13 @@
$VER = "1.0";
use Getopt::Long;
+use Cwd;
use DBI;
$max_row_length=500000; # Don't create bigger SQL rows that this
$opt_lock=1; # lock tables
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/server-cfg" || die "Can't read Configuration file: $!\n";
diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh
index f6985adc5c0..00989fc0bc8 100644
--- a/sql-bench/crash-me.sh
+++ b/sql-bench/crash-me.sh
@@ -1,4 +1,5 @@
#!@PERL@
+# -*- perl -*-
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
#
# This library is free software; you can redistribute it and/or
@@ -38,23 +39,26 @@
# as such, and clarify ones such as "mediumint" with comments such as
# "3-byte int" or "same as xxx".
-$version="1.57";
+$version="1.61";
+use Cwd;
use DBI;
use Getopt::Long;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+use POSIX;
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/server-cfg" || die "Can't read Configuration file: $!\n";
$opt_server="mysql"; $opt_host="localhost"; $opt_database="test";
$opt_dir="limits";
-$opt_user=$opt_password="";
+$opt_user=$opt_password="";$opt_verbose=1;
$opt_debug=$opt_help=$opt_Information=$opt_restart=$opt_force=$opt_quick=0;
-$opt_log_all_queries=$opt_fix_limit_file=$opt_batch_mode=0;
+$opt_log_all_queries=$opt_fix_limit_file=$opt_batch_mode=$opt_version=0;
$opt_db_start_cmd=""; # the db server start command
$opt_check_server=0; # Check if server is alive before each query
$opt_sleep=10; # time to sleep while starting the db server
$limit_changed=0; # For configure file
$reconnect_count=0;
+$opt_suffix="";
$opt_comment=$opt_config_file=$opt_log_queries_to_file="";
$limits{'crash_me_safe'}='yes';
$prompts{'crash_me_safe'}='crash me safe';
@@ -62,10 +66,24 @@ $limits{'operating_system'}= machine();
$prompts{'operating_system'}='crash-me tested on';
$retry_limit=3;
-GetOptions("Information","help","server=s","debug","user=s","password=s","database=s","restart","force","quick","log-all-queries","comment=s","host=s","fix-limit-file","dir=s","db-start-cmd=s","sleep=s","batch-mode","config-file=s","log-queries-to-file=s","check-server") || usage();
+GetOptions("Information","help","server=s","debug","user=s","password=s",
+"database=s","restart","force","quick","log-all-queries","comment=s",
+"host=s","fix-limit-file","dir=s","db-start-cmd=s","sleep=s","suffix=s",
+"batch-mode","config-file=s","log-queries-to-file=s","check-server",
+"version",
+"verbose!" => \$opt_verbose) || usage();
usage() if ($opt_help || $opt_Information);
+version() && exit(0) if ($opt_version);
-$opt_config_file="$pwd/$opt_dir/$opt_server.cfg" if (length($opt_config_file) == 0);
+$opt_suffix = '-'.$opt_suffix if (length($opt_suffix) != 0);
+$opt_config_file = "$pwd/$opt_dir/$opt_server$opt_suffix.cfg"
+ if (length($opt_config_file) == 0);
+$log_prefix=' ###'; # prefix for log lines in result file
+$safe_query_log='';
+$safe_query_result_log='';
+$log{"crash-me"}="";
+
+#!!!
if ($opt_fix_limit_file)
{
@@ -112,7 +130,8 @@ if (length($opt_comment))
$opt_log=0;
if (length($opt_log_queries_to_file))
{
- open(LOG,">$opt_log_queries_to_file") || die "Can't open file $opt_log_queries_to_file\n";
+ open(LOG,">$opt_log_queries_to_file") ||
+ die "Can't open file $opt_log_queries_to_file\n";
$opt_log=1;
}
@@ -143,7 +162,15 @@ $longreadlen=16000000; # For retrieval buffer
#
use sigtrap; # Must be removed with perl5.005_2 on Win98
$SIG{PIPE} = 'IGNORE';
-$SIG{SEGV} = sub {warn('SEGFAULT')};
+$problem_counter=0;
+$SIG{SEGV} = sub {
+ $problem_counter +=1;
+ if ($problem_counter >= 100) {
+ die("Too many problems, try to restart");
+ } else {
+ warn('SEGFAULT');
+ };
+};
$dbh=safe_connect();
#
@@ -155,11 +182,13 @@ $prompt="drop table require cascade/restrict";
$drop_attr="";
$dbh->do("drop table crash_me");
$dbh->do("drop table crash_me cascade");
-if (!safe_query(["create table crash_me (a integer not null)",
+if (!safe_query_l('drop_requires_cascade',
+ ["create table crash_me (a integer not null)",
"drop table crash_me"]))
{
$dbh->do("drop table crash_me cascade");
- if (safe_query(["create table crash_me (a integer not null)",
+ if (safe_query_l('drop_requires_cascade',
+ ["create table crash_me (a integer not null)",
"drop table crash_me cascade"]))
{
save_config_data('drop_requires_cascade',"yes","$prompt");
@@ -184,11 +213,14 @@ $dbh->do("drop table crash_q $drop_attr");
$dbh->do("drop table crash_q1 $drop_attr");
$prompt="Tables without primary key";
-if (!safe_query(["create table crash_me (a integer not null,b char(10) not null)",
+if (!safe_query_l('no_primary_key',
+ ["create table crash_me (a integer not null,b char(10) not null)",
"insert into crash_me (a,b) values (1,'a')"]))
{
- if (!safe_query(["create table crash_me (a integer not null,b char(10) not null, primary key (a))",
- "insert into crash_me (a,b) values (1,'a')"]))
+ if (!safe_query_l('no_primary_key',
+ ["create table crash_me (a integer not null,b char(10) not null".
+ ", primary key (a))",
+ "insert into crash_me (a,b) values (1,'a')"]))
{
die "Can't create table 'crash_me' with one record: $DBI::errstr\n";
}
@@ -245,6 +277,9 @@ check_and_report("\` as identifier quote",'quote_ident_with_`',[],
'select `A` from crash_me',[],"1",0);
check_and_report("[] as identifier quote",'quote_ident_with_[',[],
'select [A] from crash_me',[],"1",0);
+report('Double "" in identifiers as "','quote_ident_with_dbl_"',
+ 'create table crash_me1 ("abc""d" integer)',
+ 'drop table crash_me1');
report("Column alias","column_alias","select a as ab from crash_me");
report("Table alias","table_alias","select b.a from crash_me as b");
@@ -252,6 +287,8 @@ report("Functions",'functions',"select 1+1 $end_query");
report("Group functions",'group_functions',"select count(*) from crash_me");
report("Group functions with distinct",'group_distinct_functions',
"select count(distinct a) from crash_me");
+report("Group functions with several distinct",'group_many_distinct_functions',
+ "select count(distinct a), count(distinct b) from crash_me");
report("Group by",'group_by',"select a from crash_me group by a");
report("Group by position",'group_by_position',
"select a from crash_me group by 1");
@@ -267,13 +304,14 @@ report("Order by function","order_by_function",
"select a from crash_me order by a+1");
report("Order by on unused column",'order_on_unused',
"select b from crash_me order by a");
-check_and_report("Order by DESC is remembered",'order_by_remember_desc',
- ["create table crash_q (s int,s1 int)",
- "insert into crash_q values(1,1)",
- "insert into crash_q values(3,1)",
- "insert into crash_q values(2,1)"],
- "select s,s1 from crash_q order by s1 DESC,s",
- ["drop table crash_q $drop_attr"],[3,2,1],7,undef(),3);
+# little bit deprecated
+#check_and_report("Order by DESC is remembered",'order_by_remember_desc',
+# ["create table crash_q (s int,s1 int)",
+# "insert into crash_q values(1,1)",
+# "insert into crash_q values(3,1)",
+# "insert into crash_q values(2,1)"],
+# "select s,s1 from crash_q order by s1 DESC,s",
+# ["drop table crash_q $drop_attr"],[3,2,1],7,undef(),3);
report("Compute",'compute',
"select a from crash_me order by a compute sum(a) by a");
report("INSERT with Value lists",'insert_multi_value',
@@ -284,13 +322,31 @@ report("INSERT with set syntax",'insert_with_set',
"create table crash_q (a integer)",
"insert into crash_q SET a=1",
"drop table crash_q $drop_attr");
+report("INSERT with DEFAULT","insert_with_default",
+ "create table crash_me_q (a int)",
+ "insert into crash_me_q (a) values (DEFAULT)",
+ "drop table crash_me_q $drop_attr");
+
+report("INSERT with empty value list","insert_with_empty_value_list",
+ "create table crash_me_q (a int)",
+ "insert into crash_me_q (a) values ()",
+ "drop table crash_me_q $drop_attr");
+
+report("INSERT DEFAULT VALUES","insert_default_values",
+ "create table crash_me_q (a int)",
+ "insert into crash_me_q DEFAULT VALUES",
+ "drop table crash_me_q $drop_attr");
+
report("allows end ';'","end_colon", "select * from crash_me;");
try_and_report("LIMIT number of rows","select_limit",
["with LIMIT",
"select * from crash_me limit 1"],
["with TOP",
"select TOP 1 * from crash_me"]);
-report("SELECT with LIMIT #,#","select_limit2", "select * from crash_me limit 1,1");
+report("SELECT with LIMIT #,#","select_limit2",
+ "select * from crash_me limit 1,1");
+report("SELECT with LIMIT # OFFSET #",
+ "select_limit3", "select * from crash_me limit 1 offset 1");
# The following alter table commands MUST be kept together!
if ($dbh->do("create table crash_q (a integer, b integer,c1 CHAR(10))"))
@@ -312,7 +368,8 @@ if ($dbh->do("create table crash_q (a integer, b integer,c1 CHAR(10))"))
"alter table crash_q alter b set default 10");
report_one("Alter table drop column",'alter_drop_col',
[["alter table crash_q drop column b","yes"],
- ["alter table crash_q drop column b restrict","with restrict/cascade"]]);
+ ["alter table crash_q drop column b restrict",
+ "with restrict/cascade"]]);
report("Alter table rename table",'alter_rename_table',
"alter table crash_q rename to crash_q1");
}
@@ -334,13 +391,14 @@ report("truncate","truncate_table",
"drop table crash_q $drop_attr");
if ($dbh->do("create table crash_q (a integer, b integer,c1 CHAR(10))") &&
- $dbh->do("create table crash_q1 (a integer, b integer,c1 CHAR(10) not null)"))
+ $dbh->do("create table crash_q1 (a integer, b integer,c1 CHAR(10) not null)"))
{
report("Alter table add constraint",'alter_add_constraint',
"alter table crash_q add constraint c2 check(a > b)");
report_one("Alter table drop constraint",'alter_drop_constraint',
[["alter table crash_q drop constraint c2","yes"],
- ["alter table crash_q drop constraint c2 restrict","with restrict/cascade"]]);
+ ["alter table crash_q drop constraint c2 restrict",
+ "with restrict/cascade"]]);
report("Alter table add unique",'alter_add_unique',
"alter table crash_q add constraint u1 unique(c1)");
try_and_report("Alter table drop unique",'alter_drop_unique',
@@ -356,7 +414,8 @@ if ($dbh->do("create table crash_q (a integer, b integer,c1 CHAR(10))") &&
["with add primary key",
"alter table crash_q1 add primary key(c1)"]);
report("Alter table add foreign key",'alter_add_foreign_key',
- "alter table crash_q add constraint f1 foreign key(c1) references crash_q1(c1)");
+ "alter table crash_q add constraint f1 foreign key(c1)",
+ " references crash_q1(c1)");
try_and_report("Alter table drop foreign key",'alter_drop_foreign_key',
["with drop constraint",
"alter table crash_q drop constraint f1"],
@@ -387,10 +446,12 @@ check_and_report("Group on column with null values",'group_by_null',
$prompt="Having";
if (!defined($limits{'having'}))
{ # Complicated because of postgreSQL
- if (!safe_query_result("select a from crash_me group by a having a > 0",1,0))
+ if (!safe_query_result_l("having",
+ "select a from crash_me group by a having a > 0",1,0))
{
- if (!safe_query_result("select a from crash_me group by a having a < 0",
- 1,0))
+ if (!safe_query_result_l("having",
+ "select a from crash_me group by a having a < 0",
+ 1,0))
{ save_config_data("having","error",$prompt); }
else
{ save_config_data("having","yes",$prompt); }
@@ -424,11 +485,14 @@ report("hex strings (x'1ace')","hex_strings","select x'1ace' $end_query");
report_result("Value of logical operation (1=1)","logical_value",
"select (1=1) $end_query");
+report_result("Value of TRUE","value_of_true","select TRUE $end_query");
+report_result("Value of FALSE","value_of_false","select FALSE $end_query");
+
$logical_value= $limits{'logical_value'};
$false=0;
$result="no";
-if ($res=safe_query("select (1=1)=true $end_query")) {
+if ($res=safe_query_l('has_true_false',"select (1=1)=true $end_query")) {
$false="false";
$result="yes";
}
@@ -474,10 +538,11 @@ else
if ($i == 0)
{
- print "Can't connect to server: $DBI::errstr. Please start it and try again\n";
+ print "Can't connect to server: $DBI::errstr.".
+ " Please start it and try again\n";
exit 1;
}
- $dbh=safe_connect();
+ $dbh=retry_connect();
}
@@ -507,7 +572,9 @@ if (!defined($limits{'query_size'}))
}
for ($i=$first ; $i < $end ; $i*=2)
{
- last if (!safe_query($query . (" " x ($i - length($query)-length($end_query) -1)) . "$select$end_query"));
+ last if (!safe_query($query .
+ (" " x ($i - length($query)-length($end_query) -1))
+ . "$select$end_query"));
$first=$i;
save_config_data("restart",$i,"") if ($opt_restart);
}
@@ -535,6 +602,13 @@ if (!defined($limits{'query_size'}))
$query_size=$limits{'query_size'};
print "$limits{'query_size'}\n";
+
+#
+# Check for reserved words
+#
+
+check_reserved_words($dbh);
+
#
# Test database types
#
@@ -550,7 +624,8 @@ print "$limits{'query_size'}\n";
"interval month",
"interval day", "interval day to hour", "interval day to minute",
"interval day to second",
- "interval hour", "interval hour to minute", "interval hour to second",
+ "interval hour", "interval hour to minute",
+ "interval hour to second",
"interval minute", "interval minute to second",
"interval second",
"national character varying(20)",
@@ -574,7 +649,7 @@ print "$limits{'query_size'}\n";
"int not null identity,unique(q)",
# postgres types
"box","bool","circle","polygon","point","line","lseg","path",
- "interval", "serial", "inet", "cidr", "macaddr",
+ "interval", "inet", "cidr", "macaddr",
# oracle types
"varchar2(16)","nvarchar2(16)","number(9,2)","number(9)",
@@ -615,6 +690,7 @@ foreach $types (@types)
# Test some type limits
#
+
check_and_report("Remembers end space in char()","remember_end_space",
["create table crash_q (a char(10))",
"insert into crash_q values('hello ')"],
@@ -630,55 +706,6 @@ check_and_report("Remembers end space in varchar()",
["drop table crash_q $drop_attr"],
'hello ',6);
-check_and_report("Supports 0000-00-00 dates","date_zero",
- ["create table crash_me2 (a date not null)",
- "insert into crash_me2 values ('0000-00-00')"],
- "select a from crash_me2",
- ["drop table crash_me2 $drop_attr"],
- "0000-00-00",1);
-
-check_and_report("Supports 0001-01-01 dates","date_one",
- ["create table crash_me2 (a date not null)",
- "insert into crash_me2 values (DATE '0001-01-01')"],
- "select a from crash_me2",
- ["drop table crash_me2 $drop_attr"],
- "0001-01-01",1);
-
-check_and_report("Supports 9999-12-31 dates","date_last",
- ["create table crash_me2 (a date not null)",
- "insert into crash_me2 values (DATE '9999-12-31')"],
- "select a from crash_me2",
- ["drop table crash_me2 $drop_attr"],
- "9999-12-31",1);
-
-check_and_report("Supports 'infinity dates","date_infinity",
- ["create table crash_me2 (a date not null)",
- "insert into crash_me2 values ('infinity')"],
- "select a from crash_me2",
- ["drop table crash_me2 $drop_attr"],
- "infinity",1);
-
-if (!defined($limits{'date_with_YY'}))
-{
- check_and_report("Supports YY-MM-DD dates","date_with_YY",
- ["create table crash_me2 (a date not null)",
- "insert into crash_me2 values ('98-03-03')"],
- "select a from crash_me2",
- ["drop table crash_me2 $drop_attr"],
- "1998-03-03",5);
- if ($limits{'date_with_YY'} eq "yes")
- {
- undef($limits{'date_with_YY'});
- check_and_report("Supports YY-MM-DD 2000 compilant dates",
- "date_with_YY",
- ["create table crash_me2 (a date not null)",
- "insert into crash_me2 values ('10-03-03')"],
- "select a from crash_me2",
- ["drop table crash_me2 $drop_attr"],
- "2010-03-03",5);
- }
-}
-
if (($limits{'type_extra_float(2_arg)'} eq "yes" ||
$limits{'type_sql_decimal(2_arg)'} eq "yes") &&
(!defined($limits{'storage_of_float'})))
@@ -686,33 +713,33 @@ if (($limits{'type_extra_float(2_arg)'} eq "yes" ||
my $type=$limits{'type_extra_float(2_arg)'} eq "yes" ? "float(4,1)" :
"decimal(4,1)";
my $result="undefined";
- if (execute_and_check(["create table crash_q (q1 $type)",
+ if (execute_and_check("storage_of_float",["create table crash_q (q1 $type)",
"insert into crash_q values(1.14)"],
"select q1 from crash_q",
["drop table crash_q $drop_attr"],1.1,0) &&
- execute_and_check(["create table crash_q (q1 $type)",
+ execute_and_check("storage_of_float",["create table crash_q (q1 $type)",
"insert into crash_q values(1.16)"],
"select q1 from crash_q",
["drop table crash_q $drop_attr"],1.1,0))
{
$result="truncate";
}
- elsif (execute_and_check(["create table crash_q (q1 $type)",
+ elsif (execute_and_check("storage_of_float",["create table crash_q (q1 $type)",
"insert into crash_q values(1.14)"],
"select q1 from crash_q",
["drop table crash_q $drop_attr"],1.1,0) &&
- execute_and_check(["create table crash_q (q1 $type)",
+ execute_and_check("storage_of_float",["create table crash_q (q1 $type)",
"insert into crash_q values(1.16)"],
"select q1 from crash_q",
["drop table crash_q $drop_attr"],1.2,0))
{
$result="round";
}
- elsif (execute_and_check(["create table crash_q (q1 $type)",
+ elsif (execute_and_check("storage_of_float",["create table crash_q (q1 $type)",
"insert into crash_q values(1.14)"],
"select q1 from crash_q",
["drop table crash_q $drop_attr"],1.14,0) &&
- execute_and_check(["create table crash_q (q1 $type)",
+ execute_and_check("storage_of_float",["create table crash_q (q1 $type)",
"insert into crash_q values(1.16)"],
"select q1 from crash_q",
["drop table crash_q $drop_attr"],1.16,0))
@@ -726,13 +753,17 @@ if (($limits{'type_extra_float(2_arg)'} eq "yes" ||
try_and_report("Type for row id", "rowid",
["rowid",
- "create table crash_q (a rowid)","drop table crash_q $drop_attr"],
+ "create table crash_q (a rowid)",
+ "drop table crash_q $drop_attr"],
["auto_increment",
- "create table crash_q (a int not null auto_increment, primary key(a))","drop table crash_q $drop_attr"],
+ "create table crash_q (a int not null auto_increment".
+ ", primary key(a))","drop table crash_q $drop_attr"],
["oid",
- "create table crash_q (a oid, primary key(a))","drop table crash_q $drop_attr"],
+ "create table crash_q (a oid, primary key(a))",
+ "drop table crash_q $drop_attr"],
["serial",
- "create table crash_q (a serial, primary key(a))","drop table crash_q $drop_attr"]);
+ "create table crash_q (a serial, primary key(a))",
+ "drop table crash_q $drop_attr"]);
try_and_report("Automatic row id", "automatic_rowid",
["_rowid",
@@ -749,30 +780,31 @@ try_and_report("Automatic row id", "automatic_rowid",
(["+, -, * and /","+","5*3-4/2+1",14,0],
["ANSI SQL SUBSTRING","substring","substring('abcd' from 2 for 2)","bc",1],
["BIT_LENGTH","bit_length","bit_length('abc')",24,0],
- ["searched CASE","searched_case","case when 1 > 2 then 'false' when 2 > 1 then 'true' end", "true",1],
- ["simple CASE","simple_case","case 2 when 1 then 'false' when 2 then 'true' end", "true",1],
+ ["searched CASE","searched_case",
+ "case when 1 > 2 then 'false' when 2 > 1 then 'true' end", "true",1],
+ ["simple CASE","simple_case",
+ "case 2 when 1 then 'false' when 2 then 'true' end", "true",1],
["CAST","cast","CAST(1 as CHAR)","1",1],
["CHARACTER_LENGTH","character_length","character_length('abcd')","4",0],
["CHAR_LENGTH","char_length","char_length(b)","10",0],
- ["CHAR_LENGTH(constant)","char_length(constant)","char_length('abcd')","4",0],
+ ["CHAR_LENGTH(constant)","char_length(constant)",
+ "char_length('abcd')","4",0],
["COALESCE","coalesce","coalesce($char_null,'bcd','qwe')","bcd",1],
["CURRENT_DATE","current_date","current_date",0,2],
["CURRENT_TIME","current_time","current_time",0,2],
["CURRENT_TIMESTAMP","current_timestamp","current_timestamp",0,2],
- ["CURRENT_USER","current_user","current_user",0,2],
- ["EXTRACT","extract_sql","extract(minute from timestamp '2000-02-23 18:43:12.987')",43,0],
+ ["EXTRACT","extract_sql",
+ "extract(minute from timestamp '2000-02-23 18:43:12.987')",43,0],
["LOCALTIME","localtime","localtime",0,2],
["LOCALTIMESTAMP","localtimestamp","localtimestamp",0,2],
["LOWER","lower","LOWER('ABC')","abc",1],
- ["NULLIF with strings","nullif_string","NULLIF(NULLIF('first','second'),'first')",undef(),4],
+ ["NULLIF with strings","nullif_string",
+ "NULLIF(NULLIF('first','second'),'first')",undef(),4],
["NULLIF with numbers","nullif_num","NULLIF(NULLIF(1,2),1)",undef(),4],
["OCTET_LENGTH","octet_length","octet_length('abc')",3,0],
["POSITION","position","position('ll' in 'hello')",3,0],
- ["SESSION_USER","session_user","session_user",0,2],
- ["SYSTEM_USER","system_user","system_user",0,2],
["TRIM","trim","trim(trailing from trim(LEADING FROM ' abc '))","abc",3],
["UPPER","upper","UPPER('abc')","ABC",1],
- ["USER","user","user"],
["concatenation with ||","concat_as_||","'abc' || 'def'","abcdef",1],
);
@@ -780,7 +812,7 @@ try_and_report("Automatic row id", "automatic_rowid",
(["ASCII", "ascii", "ASCII('A')","65",0],
["CHAR", "char", "CHAR(65)" ,"A",1],
["CONCAT(2 arg)","concat", "concat('a','b')","ab",1],
- ["DIFFERENCE()","difference","difference('abc','abe')",0,2],
+ ["DIFFERENCE()","difference","difference('abc','abe')",3,0],
["INSERT","insert","insert('abcd',2,2,'ef')","aefd",1],
["LEFT","left","left('abcd',2)","ab",1],
["LTRIM","ltrim","ltrim(' abcd')","abcd",1],
@@ -824,25 +856,13 @@ try_and_report("Automatic row id", "automatic_rowid",
["TRUNCATE","truncate","truncate(18.18,-1)",10,0],
["NOW","now","now()",0,2], # Any value is acceptable
["CURDATE","curdate","curdate()",0,2],
- ["DAYNAME","dayname","dayname(DATE '1997-02-01')","",2],
- ["MONTH","month","month(DATE '1997-02-01')","",2],
- ["MONTHNAME","monthname","monthname(DATE '1997-02-01')","",2],
- ["DAYOFMONTH","dayofmonth","dayofmonth(DATE '1997-02-01')",1,0],
- ["DAYOFWEEK","dayofweek","dayofweek(DATE '1997-02-01')",7,0],
- ["DAYOFYEAR","dayofyear","dayofyear(DATE '1997-02-01')",32,0],
- ["QUARTER","quarter","quarter(DATE '1997-02-01')",1,0],
- ["WEEK","week","week(DATE '1997-02-01')",5,0],
- ["YEAR","year","year(DATE '1997-02-01')",1997,0],
["CURTIME","curtime","curtime()",0,2],
- ["HOUR","hour","hour('12:13:14')",12,0],
- ["ANSI HOUR","hour_time","hour(TIME '12:13:14')",12,0],
- ["MINUTE","minute","minute('12:13:14')",13,0],
- ["SECOND","second","second('12:13:14')",14,0],
["TIMESTAMPADD","timestampadd",
"timestampadd(SQL_TSI_SECOND,1,'1997-01-01 00:00:00')",
"1997-01-01 00:00:01",1],
["TIMESTAMPDIFF","timestampdiff",
- "timestampdiff(SQL_TSI_SECOND,'1997-01-01 00:00:02', '1997-01-01 00:00:01')","1",0],
+ "timestampdiff(SQL_TSI_SECOND,'1997-01-01 00:00:02',".
+ " '1997-01-01 00:00:01')","1",0],
["USER()","user()","user()",0,2],
["DATABASE","database","database()",0,2],
["IFNULL","ifnull","ifnull(2,3)",2,0],
@@ -858,7 +878,6 @@ try_and_report("Automatic row id", "automatic_rowid",
["<> in SELECT","<>","1<>1","0",0],
["=","=","(1=1)",1,$logical_value],
["~* (case insensitive compare)","~*","'hi' ~* 'HI'",1,$logical_value],
- ["ADD_MONTHS","add_months","add_months('1997-01-01',1)","1997-02-01",0], # oracle the date plus n months
["AND and OR in SELECT","and_or","1=1 AND 2=2",$logical_value,0],
["AND as '&&'",'&&',"1=1 && 2=2",$logical_value,0],
["ASCII_CHAR", "ascii_char", "ASCII_CHAR(65)","A",1],
@@ -872,40 +891,38 @@ try_and_report("Automatic row id", "automatic_rowid",
["CONCAT(list)","concat_list", "concat('a','b','c','d')","abcd",1],
["CONVERT","convert","convert(CHAR,5)","5",1],
["COSH","cosh","cosh(0)","1",0], # oracle hyperbolic cosine of n.
- ["DATEADD","dateadd","dateadd(day,3,'Nov 30 1997')",0,2],
- ["DATEDIFF","datediff","datediff(month,'Oct 21 1997','Nov 30 1997')",0,2],
- ["DATENAME","datename","datename(month,'Nov 30 1997')",0,2],
- ["DATEPART","datepart","datepart(month,'July 20 1997')",0,2],
- ["DATE_FORMAT","date_format", "date_format('1997-01-02 03:04:05','M W D Y y m d h i s w')", 0,2],
["ELT","elt","elt(2,'ONE','TWO','THREE')","TWO",1],
["ENCRYPT","encrypt","encrypt('hello')",0,2],
["FIELD","field","field('IBM','NCA','ICL','SUN','IBM','DIGITAL')",4,0],
["FORMAT","format","format(1234.5555,2)","1,234.56",1],
- ["FROM_DAYS","from_days","from_days(729024)","1996-01-01",1],
- ["FROM_UNIXTIME","from_unixtime","from_unixtime(0)",0,2],
["GETDATE","getdate","getdate()",0,2],
- ["GREATEST","greatest","greatest('HARRY','HARRIOT','HAROLD')","HARRY",1], # oracle
+ ["GREATEST","greatest","greatest('HARRY','HARRIOT','HAROLD')","HARRY",1],
["IF","if", "if(5,6,7)",6,0],
["IN on numbers in SELECT","in_num","2 in (3,2,5,9,5,1)",$logical_value,0],
["IN on strings in SELECT","in_str","'monty' in ('david','monty','allan')", $logical_value,0],
- ["INITCAP","initcap","initcap('the soap')","The Soap",1], # oracle Returns char, with the first letter of each word in uppercase
+ ["INITCAP","initcap","initcap('the soap')","The Soap",1],
+ # oracle Returns char, with the first letter of each word in uppercase
["INSTR (Oracle syntax)", "instr_oracle", "INSTR('CORPORATE FLOOR','OR',3,2)" ,"14",0], # oracle instring
- ["INSTRB", "instrb", "INSTRB('CORPORATE FLOOR','OR',5,2)" ,"27",0], # oracle instring in bytes
+ ["INSTRB", "instrb", "INSTRB('CORPORATE FLOOR','OR',5,2)" ,"27",0],
+ # oracle instring in bytes
["INTERVAL","interval","interval(55,10,20,30,40,50,60,70,80,90,100)",5,0],
- ["LAST_DAY","last_day","last_day('1997-04-01')","1997-04-30",0], # oracle last day of month of date
["LAST_INSERT_ID","last_insert_id","last_insert_id()",0,2],
- ["LEAST","least","least('HARRY','HARRIOT','HAROLD')","HAROLD",1], # oracle
- ["LENGTHB","lengthb","lengthb('CANDIDE')","14",0], # oracle length in bytes
- ["LIKE ESCAPE in SELECT","like_escape","'%' like 'a%' escape 'a'",$logical_value,0],
+ ["LEAST","least","least('HARRY','HARRIOT','HAROLD')","HAROLD",1],
+ # oracle
+ ["LENGTHB","lengthb","lengthb('CANDIDE')","14",0],
+ # oracle length in bytes
+ ["LIKE ESCAPE in SELECT","like_escape",
+ "'%' like 'a%' escape 'a'",$logical_value,0],
["LIKE in SELECT","like","'a' like 'a%'",$logical_value,0],
- ["LN","ln","ln(95)","4.55387689",0], # oracle natural logarithm of n
+ ["LN","ln","ln(95)","4.55387689",0],
+ # oracle natural logarithm of n
["LOCATE as INSTR","instr","instr('hello','ll')",3,0],
- ["LOG(m,n)","log(m_n)","log(10,100)","2",0], # oracle logarithm, base m, of n
- ["LOGN","logn","logn(2)","0.693147",0], # informix
+ ["LOG(m,n)","log(m_n)","log(10,100)","2",0],
+ # oracle logarithm, base m, of n
+ ["LOGN","logn","logn(2)","0.693147",0],
+ # informix
["LPAD","lpad","lpad('hi',4,'??')",'??hi',3],
- ["MDY","mdy","mdy(7,1,1998)","1998-07-01",0], # informix
["MOD as %","%","10%7","3",0],
- ["MONTHS_BETWEEN","months_between","months_between('1997-02-02','1997-01-01')","1.03225806",0], # oracle number of months between 2 dates
["NOT BETWEEN in SELECT","not_between","5 not between 4 and 6",0,0],
["NOT LIKE in SELECT","not_like","'a' not like 'a%'",0,0],
["NOT as '!' in SELECT","!","! 1",0,0],
@@ -915,43 +932,74 @@ try_and_report("Automatic row id", "automatic_rowid",
["PASSWORD","password","password('hello')",0,2],
["PASTE", "paste", "paste('ABCDEFG',3,2,'1234')","AB1234EFG",1],
["PATINDEX","patindex","patindex('%a%','crash')",3,0],
- ["PERIOD_ADD","period_add","period_add(9602,-12)",199502,0],
- ["PERIOD_DIFF","period_diff","period_diff(199505,199404)",13,0],
["POW","pow","pow(3,2)",9,0],
- ["RANGE","range","range(a)","0.0",0], # informix range(a) = max(a) - min(a)
+ ["RANGE","range","range(a)","0.0",0],
+ # informix range(a) = max(a) - min(a)
["REGEXP in SELECT","regexp","'a' regexp '^(a|b)*\$'",$logical_value,0],
["REPLICATE","replicate","replicate('a',5)","aaaaa",1],
["REVERSE","reverse","reverse('abcd')","dcba",1],
["ROOT","root","root(4)",2,0], # informix
["ROUND(1 arg)","round1","round(5.63)","6",0],
["RPAD","rpad","rpad('hi',4,'??')",'hi??',3],
- ["SEC_TO_TIME","sec_to_time","sec_to_time(5001)","01:23:21",1],
["SINH","sinh","sinh(1)","1.17520119",0], # oracle hyperbolic sine of n
["STR","str","str(123.45,5,1)",123.5,3],
["STRCMP","strcmp","strcmp('abc','adc')",-1,0],
["STUFF","stuff","stuff('abc',2,3,'xyz')",'axyz',3],
- ["SUBSTRB", "substrb", "SUBSTRB('ABCDEFG',5,4.2)" ,"CD",1], # oracle substring with bytes
+ ["SUBSTRB", "substrb", "SUBSTRB('ABCDEFG',5,4.2)" ,"CD",1],
+ # oracle substring with bytes
["SUBSTRING as MID","mid","mid('hello',3,2)","ll",1],
- ["SUBSTRING_INDEX","substring_index","substring_index('www.tcx.se','.',-2)", "tcx.se",1],
+ ["SUBSTRING_INDEX","substring_index",
+ "substring_index('www.tcx.se','.',-2)", "tcx.se",1],
["SYSDATE","sysdate","sysdate()",0,2],
["TAIL","tail","tail('ABCDEFG',3)","EFG",0],
- ["TANH","tanh","tanh(1)","0.462117157",0], # oracle hyperbolic tangent of n
- ["TIME_TO_SEC","time_to_sec","time_to_sec('01:23:21')","5001",0],
- ["TO_DAYS","to_days","to_days(DATE '1996-01-01')",729024,0],
+ ["TANH","tanh","tanh(1)","0.462117157",0],
+ # oracle hyperbolic tangent of n
["TRANSLATE","translate","translate('abc','bc','de')",'ade',3],
- ["TRIM; Many char extension","trim_many_char","trim(':!' FROM ':abc!')","abc",3],
- ["TRIM; Substring extension","trim_substring","trim('cb' FROM 'abccb')","abc",3],
+ ["TRIM; Many char extension",
+ "trim_many_char","trim(':!' FROM ':abc!')","abc",3],
+ ["TRIM; Substring extension",
+ "trim_substring","trim('cb' FROM 'abccb')","abc",3],
["TRUNC","trunc","trunc(18.18,-1)",10,0], # oracle
["UID","uid","uid",0,2], # oracle uid from user
["UNIX_TIMESTAMP","unix_timestamp","unix_timestamp()",0,2],
["USERENV","userenv","userenv",0,2], # oracle user enviroment
["VERSION","version","version()",0,2],
- ["WEEKDAY","weekday","weekday(DATE '1997-11-29')",5,0],
["automatic num->string convert","auto_num2string","concat('a',2)","a2",1],
["automatic string->num convert","auto_string2num","'1'+2",3,0],
["concatenation with +","concat_as_+","'abc' + 'def'","abcdef",1],
+ ["SUBSTR (2 arg)",'substr2arg',"substr('abcd',2)",'bcd',1], #sapdb func
+ ["SUBSTR (3 arg)",'substr3arg',"substr('abcd',2,2)",'bc',1],
+ ["LFILL (3 arg)",'lfill3arg',"lfill('abcd','.',6)",'..abcd',1],
+ ["RFILL (3 arg)",'rfill3arg',"rfill('abcd','.',6)",'abcd..',1],
+ ["RPAD (4 arg)",'rpad4arg',"rpad('abcd',2,'+-',8)",'abcd+-+-',1],
+ ["LPAD (4 arg)",'rpad4arg',"lpad('abcd',2,'+-',8)",'+-+-abcd',1],
+ ["TRIM (1 arg)",'trim1arg',"trim(' abcd ')",'abcd',1],
+ ["TRIM (2 arg)",'trim2arg',"trim('..abcd..','.')",'abcd',1],
+ ["LTRIM (2 arg)",'ltrim2arg',"ltrim('..abcd..','.')",'abcd..',1],
+ ["RTRIM (2 arg)",'rtrim2arg',"rtrim('..abcd..','.')",'..abcd',1],
+ ["EXPAND",'expand2arg',"expand('abcd',6)",'abcd ',0],
+ ["REPLACE (2 arg) ",'replace2arg',"replace('AbCd','bC')",'Ad',1],
+ ["MAPCHAR",'mapchar',"mapchar('Aâ')",'Aa',1],
+ ["ALPHA",'alpha',"alpha('Aâ',2)",'AA',1],
+ ["ASCII in string cast",'ascii_string',"ascii('a')",'a',1],
+ ["EBCDIC in string cast",'ebcdic_string',"ebcdic('a')",'a',1],
+ ["TRUNC (1 arg)",'trunc1arg',"trunc(222.6)",222,0],
+ ["FIXED",'fixed',"fixed(222.6666,10,2)",'222.67',0],
+ ["FLOAT",'float',"float(6666.66,4)",6667,0],
+ ["LENGTH",'length',"length(1)",2,0],
+ ["INDEX",'index',"index('abcdefg','cd',1,1)",3,0],
+ ["MICROSECOND",'microsecond',
+ "MICROSECOND('19630816200212111111')",'111111',0],
+ ["TIMESTAMP",'timestamp',
+ "timestamp('19630816','00200212')",'19630816200212000000',0],
+ ["VALUE",'value',"value(NULL,'WALRUS')",'WALRUS',0],
+ ["DECODE",'decode',"DECODE('S-103','T72',1,'S-103',2,'Leopard',3)",2,0],
+ ["NUM",'num',"NUM('2123')",2123,0],
+ ["CHR (any type to string)",'chr_str',"CHR(67)",'67',0],
+ ["HEX",'hex',"HEX('A')",41,0],
);
+
@sql_group_functions=
(
["AVG","avg","avg(a)",1,0],
@@ -972,7 +1020,8 @@ try_and_report("Automatic row id", "automatic_rowid",
(
["BIT_AND",'bit_and',"bit_and(a)",1,0],
["BIT_OR", 'bit_or', "bit_or(a)",1,0],
- ["COUNT(DISTINCT expr,expr,...)","count_distinct_list","count(distinct a,b)",1,0],
+ ["COUNT(DISTINCT expr,expr,...)",
+ "count_distinct_list","count(distinct a,b)",1,0],
["STD","std","std(a)",0,0],
["STDDEV","stddev","stddev(a)",0,0],
["VARIANCE","variance","variance(a)",0,0],
@@ -988,13 +1037,16 @@ try_and_report("Automatic row id", "automatic_rowid",
["IN on numbers","in_num","2 in (3,2,5,9,5,1)",1,0],
["LIKE ESCAPE","like_escape","b like '%' escape 'a'",1,0],
["LIKE","like","b like 'a%'",1,0],
- ["MATCH UNIQUE","match_unique","1 match unique (select a from crash_me)",1,0],
+ ["MATCH UNIQUE","match_unique",
+ "1 match unique (select a from crash_me)",1,0],
["MATCH","match","1 match (select a from crash_me)",1,0],
["MATCHES","matches","b matcjhes 'a*'",1,0],
["NOT BETWEEN","not_between","7 not between 4 and 6",1,0],
- ["NOT EXISTS","not_exists","not exists (select * from crash_me where a = 2)",1,0],
+ ["NOT EXISTS","not_exists",
+ "not exists (select * from crash_me where a = 2)",1,0],
["NOT LIKE","not_like","b not like 'b%'",1,0],
- ["NOT UNIQUE","not_unique","not unique (select * from crash_me where a = 2)",1,0],
+ ["NOT UNIQUE","not_unique",
+ "not unique (select * from crash_me where a = 2)",1,0],
["UNIQUE","unique","unique (select * from crash_me)",1,0],
);
@@ -1111,6 +1163,8 @@ if ($limits{'functions'} eq 'yes')
"select $tmp $end_query",[], undef(),4);
}
$prompt="Need to cast NULL for arithmetic";
+ add_log("Need_cast_for_null",
+ " Check if numeric_null ($numeric_null) is 'NULL'");
save_config_data("Need_cast_for_null",
($numeric_null eq "NULL") ? "no" : "yes",
$prompt);
@@ -1121,6 +1175,479 @@ else
}
+# Test: NOROUND
+{
+ my $result = 'undefined';
+ my $error;
+ print "NOROUND: ";
+ save_incomplete('func_extra_noround','Function NOROUND');
+
+# 1) check if noround() function is supported
+ $error = safe_query_l('func_extra_noround',"select noround(22.6) $end_query");
+ if ($error ne 1) # syntax error -- noround is not supported
+ {
+ $result = 'no'
+ }
+ else # Ok, now check if it really works
+ {
+ $error=safe_query_l('func_extra_noround',
+ ["create table crash_me_nr (a int)",
+ "insert into crash_me_nr values(noround(10.2))",
+ "drop table crash_me_nr $drop_attr"]);
+ if ($error == 1)
+ {
+ $result= "syntax only";
+ }
+ else
+ {
+ $result= 'yes';
+ }
+ }
+ print "$result\n";
+ save_config_data('func_extra_noround',$result,"Function NOROUND");
+}
+
+check_parenthesis("func_sql_","CURRENT_USER");
+check_parenthesis("func_sql_","SESSION_USER");
+check_parenthesis("func_sql_","SYSTEM_USER");
+check_parenthesis("func_sql_","USER");
+
+
+if ($limits{'type_sql_date'} eq 'yes')
+{ #
+ # Checking the format of date in result.
+
+ safe_query("drop table crash_me_d $drop_attr");
+ assert("create table crash_me_d (a date)");
+ # find the example of date
+ my $dateexample;
+ if ($limits{'func_extra_sysdate'} eq 'yes') {
+ $dateexample=' sysdate() ';
+ }
+ elsif ($limits{'func_sql_current_date'} eq 'yes') {
+ $dateexample='CURRENT_DATE';
+ }
+ elsif ($limits{'func_odbc_curdate'} eq 'yes') {
+ $dateexample='curdate()';
+ }
+ elsif ($limits{'func_extra_getdate'} eq 'yes') {
+ $dateexample='getdate()';
+ }
+ elsif ($limits{'func_odbc_now'} eq 'yes') {
+ $dateexample='now()';
+ } else {
+ #try to guess
+ $dateexample="DATE '1963-08-16'";
+ } ;
+
+ my $key = 'date_format_inresult';
+ my $prompt = "Date format in result";
+ if (! safe_query_l('date_format_inresult',
+ "insert into crash_me_d values($dateexample) "))
+ {
+ die "Cannot insert date ($dateexample):".$last_error;
+ };
+ my $sth= $dbh->prepare("select a from crash_me_d");
+ add_log('date_format_inresult',"< select a from crash_me_d");
+ $sth->execute;
+ $_= $sth->fetchrow_array;
+ add_log('date_format_inresult',"> $_");
+ safe_query_l($key,"delete from crash_me_d");
+ if (/\d{4}-\d{2}-\d{2}/){ save_config_data($key,"iso",$prompt);}
+ elsif (/\d{2}-\d{2}-\d{2}/){ save_config_data($key,"short iso",$prompt);}
+ elsif (/\d{2}\.\d{2}\.\d{4}/){ save_config_data($key,"euro",$prompt);}
+ elsif (/\d{2}\.\d{2}\.\d{2}/){ save_config_data($key,"short euro",$prompt);}
+ elsif (/\d{2}\/\d{2}\/\d{4}/){ save_config_data($key,"usa",$prompt);}
+ elsif (/\d{2}\/\d{2}\/\d{2}/){ save_config_data($key,"short usa",$prompt);}
+ elsif (/\d*/){ save_config_data($key,"YYYYMMDD",$prompt);}
+ else { save_config_data($key,"unknown",$prompt);};
+ $sth->finish;
+
+ check_and_report("Supports YYYY-MM-DD (ISO) format","date_format_ISO",
+ [ "insert into crash_me_d(a) values ('1963-08-16')"],
+ "select a from crash_me_d",
+ ["delete from crash_me_d"],
+ make_date_r(1963,8,16),1);
+
+ check_and_report("Supports DATE 'YYYY-MM-DD' (ISO) format",
+ "date_format_ISO_with_date",
+ [ "insert into crash_me_d(a) values (DATE '1963-08-16')"],
+ "select a from crash_me_d",
+ ["delete from crash_me_d"],
+ make_date_r(1963,8,16),1);
+
+ check_and_report("Supports DD.MM.YYYY (EUR) format","date_format_EUR",
+ [ "insert into crash_me_d(a) values ('16.08.1963')"],
+ "select a from crash_me_d",
+ ["delete from crash_me_d"],
+ make_date_r(1963,8,16),1);
+ check_and_report("Supports DATE 'DD.MM.YYYY' (EUR) format",
+ "date_format_EUR_with_date",
+ [ "insert into crash_me_d(a) values (DATE '16.08.1963')"],
+ "select a from crash_me_d",
+ ["delete from crash_me_d"],
+ make_date_r(1963,8,16),1);
+
+ check_and_report("Supports YYYYMMDD format",
+ "date_format_YYYYMMDD",
+ [ "insert into crash_me_d(a) values ('19630816')"],
+ "select a from crash_me_d",
+ ["delete from crash_me_d"],
+ make_date_r(1963,8,16),1);
+ check_and_report("Supports DATE 'YYYYMMDD' format",
+ "date_format_YYYYMMDD_with_date",
+ [ "insert into crash_me_d(a) values (DATE '19630816')"],
+ "select a from crash_me_d",
+ ["delete from crash_me_d"],
+ make_date_r(1963,8,16),1);
+
+ check_and_report("Supports MM/DD/YYYY format",
+ "date_format_USA",
+ [ "insert into crash_me_d(a) values ('08/16/1963')"],
+ "select a from crash_me_d",
+ ["delete from crash_me_d"],
+ make_date_r(1963,8,16),1);
+ check_and_report("Supports DATE 'MM/DD/YYYY' format",
+ "date_format_USA_with_date",
+ [ "insert into crash_me_d(a) values (DATE '08/16/1963')"],
+ "select a from crash_me_d",
+ ["delete from crash_me_d"],
+ make_date_r(1963,8,16),1);
+
+
+
+
+ check_and_report("Supports 0000-00-00 dates","date_zero",
+ ["create table crash_me2 (a date not null)",
+ "insert into crash_me2 values (".make_date(0,0,0).")"],
+ "select a from crash_me2",
+ ["drop table crash_me2 $drop_attr"],
+ make_date_r(0,0,0),1);
+
+ check_and_report("Supports 0001-01-01 dates","date_one",
+ ["create table crash_me2 (a date not null)",
+ "insert into crash_me2 values (".make_date(1,1,1).")"],
+ "select a from crash_me2",
+ ["drop table crash_me2 $drop_attr"],
+ make_date_r(1,1,1),1);
+
+ check_and_report("Supports 9999-12-31 dates","date_last",
+ ["create table crash_me2 (a date not null)",
+ "insert into crash_me2 values (".make_date(9999,12,31).")"],
+ "select a from crash_me2",
+ ["drop table crash_me2 $drop_attr"],
+ make_date_r(9999,12,31),1);
+
+ check_and_report("Supports 'infinity dates","date_infinity",
+ ["create table crash_me2 (a date not null)",
+ "insert into crash_me2 values ('infinity')"],
+ "select a from crash_me2",
+ ["drop table crash_me2 $drop_attr"],
+ "infinity",1);
+
+ if (!defined($limits{'date_with_YY'}))
+ {
+ check_and_report("Supports YY-MM-DD dates","date_with_YY",
+ ["create table crash_me2 (a date not null)",
+ "insert into crash_me2 values ('98-03-03')"],
+ "select a from crash_me2",
+ ["drop table crash_me2 $drop_attr"],
+ make_date_r(1998,3,3),5);
+ if ($limits{'date_with_YY'} eq "yes")
+ {
+ undef($limits{'date_with_YY'});
+ check_and_report("Supports YY-MM-DD 2000 compilant dates",
+ "date_with_YY",
+ ["create table crash_me2 (a date not null)",
+ "insert into crash_me2 values ('10-03-03')"],
+ "select a from crash_me2",
+ ["drop table crash_me2 $drop_attr"],
+ make_date_r(2010,3,3),5);
+ }
+ }
+
+# Test: WEEK()
+ {
+ my $result="no";
+ my $error;
+ print "WEEK:";
+ save_incomplete('func_odbc_week','WEEK');
+ $error = safe_query_result_l('func_odbc_week',
+ "select week(".make_date(1997,2,1).") $end_query",5,0);
+ # actually this query must return 4 or 5 in the $last_result,
+ # $error can be 1 (not supported at all) , -1 ( probably USA weeks)
+ # and 0 - EURO weeks
+ if ($error == -1) {
+ if ($last_result == 4) {
+ $result = 'USA';
+ } else {
+ $result='error';
+ add_log('func_odbc_week',
+ " must return 4 or 5, but $last_result");
+ }
+ } elsif ($error == 0) {
+ $result = 'EURO';
+ }
+ print " $result\n";
+ save_config_data('func_odbc_week',$result,"WEEK");
+ }
+
+ my $insert_query ='insert into crash_me_d values('.
+ make_date(1997,2,1).')';
+ safe_query($insert_query);
+
+ foreach $fn ( (
+ ["DAYNAME","dayname","dayname(a)","",2],
+ ["MONTH","month","month(a)","",2],
+ ["MONTHNAME","monthname","monthname(a)","",2],
+ ["DAYOFMONTH","dayofmonth","dayofmonth(a)",1,0],
+ ["DAYOFWEEK","dayofweek","dayofweek(a)",7,0],
+ ["DAYOFYEAR","dayofyear","dayofyear(a)",32,0],
+ ["QUARTER","quarter","quarter(a)",1,0],
+ ["YEAR","year","year(a)",1997,0]))
+ {
+ $prompt='Function '.$fn->[0];
+ $key='func_odbc_'.$fn->[1];
+ add_log($key,"< ".$insert_query);
+ check_and_report($prompt,$key,
+ [],"select ".$fn->[2]." from crash_me_d",[],
+ $fn->[3],$fn->[4]
+ );
+
+ };
+ safe_query(['delete from crash_me_d',
+ 'insert into crash_me_d values('.make_date(1963,8,16).')']);
+ foreach $fn ((
+ ["DATEADD","dateadd","dateadd(day,3,make_date(1997,11,30))",0,2],
+ ["MDY","mdy","mdy(7,1,1998)","make_date_r(1998,07,01)",0], # informix
+ ["DATEDIFF","datediff",
+ "datediff(month,'Oct 21 1997','Nov 30 1997')",0,2],
+ ["DATENAME","datename","datename(month,'Nov 30 1997')",0,2],
+ ["DATEPART","datepart","datepart(month,'July 20 1997')",0,2],
+ ["DATE_FORMAT","date_format",
+ "date_format('1997-01-02 03:04:05','M W D Y y m d h i s w')", 0,2],
+ ["FROM_DAYS","from_days",
+ "from_days(729024)","make_date_r(1996,1,1)",1],
+ ["FROM_UNIXTIME","from_unixtime","from_unixtime(0)",0,2],
+ ["MONTHS_BETWEEN","months_between",
+ "months_between(make_date(1997,2,2),make_date(1997,1,1))",
+ "1.03225806",0], # oracle number of months between 2 dates
+ ["PERIOD_ADD","period_add","period_add(9602,-12)",199502,0],
+ ["PERIOD_DIFF","period_diff","period_diff(199505,199404)",13,0],
+ ["WEEKDAY","weekday","weekday(make_date(1997,11,29))",5,0],
+ ["ADDDATE",'adddate',
+ "ADDDATE(make_date(2002,12,01),3)",'make_date_r(2002,12,04)',0],
+ ["SUBDATE",'subdate',
+ "SUBDATE(make_date(2002,12,04),3)",'make_date_r(2002,12,01)',0],
+ ["DATEDIFF (2 arg)",'datediff2arg',
+ "DATEDIFF(make_date(2002,12,04),make_date(2002,12,01))",'3',0],
+ ["WEEKOFYEAR",'weekofyear',
+ "WEEKOFYEAR(make_date(1963,08,16))",'33',0],
+# table crash_me_d must contain record with 1963-08-16 (for CHAR)
+ ["CHAR (conversation date)",'char_date',
+ "CHAR(a,EUR)",'16.08.1963',0],
+ ["MAKEDATE",'makedate',"MAKEDATE(1963,228)"
+ ,'make_date_r(1963,08,16)',0],
+ ["TO_DAYS","to_days",
+ "to_days(make_date(1996,01,01))",729024,0],
+ ["ADD_MONTHS","add_months",
+ "add_months(make_date(1997,01,01),1)","make_date_r(1997,02,01)",0],
+ # oracle the date plus n months
+ ["LAST_DAY","last_day",
+ "last_day(make_date(1997,04,01))","make_date_r(1997,04,30)",0],
+ # oracle last day of month of date
+ ["DATE",'date',"date(make_date(1963,8,16))",
+ 'make_date_r(1963,8,16)',0],
+ ["DAY",'day',"DAY(make_date(2002,12,01))",1,0]))
+ {
+ $prompt='Function '.$fn->[0];
+ $key='func_extra_'.$fn->[1];
+ my $qry="select ".$fn->[2]." from crash_me_d";
+ while( $qry =~ /^(.*)make_date\((\d+),(\d+),(\d+)\)(.*)$/)
+ {
+ my $dt= &make_date($2,$3,$4);
+ $qry=$1.$dt.$5;
+ };
+ my $result=$fn->[3];
+ while( $result =~ /^(.*)make_date_r\((\d+),(\d+),(\d+)\)(.*)$/)
+ {
+ my $dt= &make_date_r($2,$3,$4);
+ $result=$1.$dt.$5;
+ };
+ check_and_report($prompt,$key,
+ [],$qry,[],
+ $result,$fn->[4]
+ );
+
+ }
+
+ safe_query("drop table crash_me_d $drop_attr");
+
+}
+
+if ($limits{'type_sql_time'} eq 'yes')
+{ #
+ # Checking the format of date in result.
+
+ safe_query("drop table crash_me_t $drop_attr");
+ assert("create table crash_me_t (a time)");
+ # find the example of time
+ my $timeexample;
+ if ($limits{'func_sql_current_time'} eq 'yes') {
+ $timeexample='CURRENT_TIME';
+ }
+ elsif ($limits{'func_odbc_curtime'} eq 'yes') {
+ $timeexample='curtime()';
+ }
+ elsif ($limits{'func_sql_localtime'} eq 'yes') {
+ $timeexample='localtime';
+ }
+ elsif ($limits{'func_odbc_now'} eq 'yes') {
+ $timeexample='now()';
+ } else {
+ #try to guess
+ $timeexample="'02:55:12'";
+ } ;
+
+ my $key = 'time_format_inresult';
+ my $prompt = "Time format in result";
+ if (! safe_query_l('time_format_inresult',
+ "insert into crash_me_t values($timeexample) "))
+ {
+ die "Cannot insert time ($timeexample):".$last_error;
+ };
+ my $sth= $dbh->prepare("select a from crash_me_t");
+ add_log('time_format_inresult',"< select a from crash_me_t");
+ $sth->execute;
+ $_= $sth->fetchrow_array;
+ add_log('time_format_inresult',"> $_");
+ safe_query_l($key,"delete from crash_me_t");
+ if (/\d{2}:\d{2}:\d{2}/){ save_config_data($key,"iso",$prompt);}
+ elsif (/\d{2}\.\d{2}\.\d{2}/){ save_config_data($key,"euro",$prompt);}
+ elsif (/\d{2}:\d{2}\s+(AM|PM)/i){ save_config_data($key,"usa",$prompt);}
+ elsif (/\d{8}$/){ save_config_data($key,"HHHHMMSS",$prompt);}
+ elsif (/\d{4}$/){ save_config_data($key,"HHMMSS",$prompt);}
+ else { save_config_data($key,"unknown",$prompt);};
+ $sth->finish;
+
+ check_and_report("Supports HH:MM:SS (ISO) time format","time_format_ISO",
+ [ "insert into crash_me_t(a) values ('20:08:16')"],
+ "select a from crash_me_t",
+ ["delete from crash_me_t"],
+ make_time_r(20,8,16),1);
+
+ check_and_report("Supports HH.MM.SS (EUR) time format","time_format_EUR",
+ [ "insert into crash_me_t(a) values ('20.08.16')"],
+ "select a from crash_me_t",
+ ["delete from crash_me_t"],
+ make_time_r(20,8,16),1);
+
+ check_and_report("Supports HHHHmmSS time format",
+ "time_format_HHHHMMSS",
+ [ "insert into crash_me_t(a) values ('00200816')"],
+ "select a from crash_me_t",
+ ["delete from crash_me_t"],
+ make_time_r(20,8,16),1);
+
+ check_and_report("Supports HHmmSS time format",
+ "time_format_HHHHMMSS",
+ [ "insert into crash_me_t(a) values ('200816')"],
+ "select a from crash_me_t",
+ ["delete from crash_me_t"],
+ make_time_r(20,8,16),1);
+
+ check_and_report("Supports HH:MM:SS (AM|PM) time format",
+ "time_format_USA",
+ [ "insert into crash_me_t(a) values ('08:08:16 PM')"],
+ "select a from crash_me_t",
+ ["delete from crash_me_t"],
+ make_time_r(20,8,16),1);
+
+ my $insert_query ='insert into crash_me_t values('.
+ make_time(20,8,16).')';
+ safe_query($insert_query);
+
+ foreach $fn ( (
+ ["HOUR","hour","hour('".make_time(12,13,14)."')",12,0],
+ ["ANSI HOUR","hour_time","hour(TIME '".make_time(12,13,14)."')",12,0],
+ ["MINUTE","minute","minute('".make_time(12,13,14)."')",13,0],
+ ["SECOND","second","second('".make_time(12,13,14)."')",14,0]
+
+ ))
+ {
+ $prompt='Function '.$fn->[0];
+ $key='func_odbc_'.$fn->[1];
+ add_log($key,"< ".$insert_query);
+ check_and_report($prompt,$key,
+ [],"select ".$fn->[2]." $end_query",[],
+ $fn->[3],$fn->[4]
+ );
+
+ };
+# safe_query(['delete from crash_me_t',
+# 'insert into crash_me_t values('.make_time(20,8,16).')']);
+ foreach $fn ((
+ ["TIME_TO_SEC","time_to_sec","time_to_sec('".
+ make_time(1,23,21)."')","5001",0],
+ ["SEC_TO_TIME","sec_to_time","sec_to_time(5001)",
+ make_time_r(01,23,21),1],
+ ["ADDTIME",'addtime',"ADDTIME('".make_time(20,2,12).
+ "','".make_time(0,0,3)."')",make_time_r(20,2,15),0],
+ ["SUBTIME",'subtime',"SUBTIME('".make_time(20,2,15)
+ ."','".make_time(0,0,3)."')",make_time_r(20,2,12),0],
+ ["TIMEDIFF",'timediff',"TIMEDIFF('".make_time(20,2,15)."','".
+ make_time(20,2,12)."')",make_time_r(0,0,3),0],
+ ["MAKETIME",'maketime',"MAKETIME(20,02,12)",make_time_r(20,2,12),0],
+ ["TIME",'time',"time('".make_time(20,2,12)."')",make_time_r(20,2,12),0]
+ ))
+ {
+ $prompt='Function '.$fn->[0];
+ $key='func_extra_'.$fn->[1];
+ my $qry="select ".$fn->[2]." $end_query";
+ my $result=$fn->[3];
+ check_and_report($prompt,$key,
+ [],$qry,[],
+ $result,$fn->[4]
+ );
+
+ }
+
+ safe_query("drop table crash_me_t $drop_attr");
+
+}
+
+
+# NOT id BETWEEN a and b
+if ($limits{'func_where_not_between'} eq 'yes')
+{
+ my $result = 'error';
+ my $err;
+ my $key='not_id_between';
+ my $prompt='NOT ID BETWEEN interprets as ID NOT BETWEEN';
+ print "$prompt:";
+ save_incomplete($key,$prompt);
+ safe_query_l($key,["create table crash_me_b (i int)",
+ "insert into crash_me_b values(2)",
+ "insert into crash_me_b values(5)"]);
+ $err =safe_query_result_l($key,
+ "select i from crash_me_b where not i between 1 and 3",
+ 5,0);
+ if ($err eq 1) {
+ if (not defined($last_result)) {
+ $result='no';
+ };
+ };
+ if ( $err eq 0) {
+ $result = 'yes';
+ };
+ safe_query_l($key,["drop table crash_me_b"]);
+ save_config_data($key,$result,$prompt);
+ print "$result\n";
+};
+
+
+
+
report("LIKE on numbers","like_with_number",
"create table crash_q (a int,b int)",
"insert into crash_q values(10,10)",
@@ -1165,19 +1692,20 @@ if (defined($tmp))
if (!defined($limits{'multi_table_update'}))
{
if (check_and_report("Update with many tables","multi_table_update",
- ["create table crash_q (a integer,b char(10))",
- "insert into crash_q values(1,'c')",
- "update crash_q left join crash_me on crash_q.a=crash_me.a set crash_q.b=crash_me.b"],
- "select b from crash_q",
- ["drop table crash_q $drop_attr"],
- "a",1,undef(),2))
+ ["create table crash_q (a integer,b char(10))",
+ "insert into crash_q values(1,'c')",
+ "update crash_q left join crash_me on crash_q.a=crash_me.a set crash_q.b=crash_me.b"],
+ "select b from crash_q",
+ ["drop table crash_q $drop_attr"],
+ "a",1,undef(),2))
{
check_and_report("Update with many tables","multi_table_update",
- ["create table crash_q (a integer,b char(10))",
- "insert into crash_q values(1,'c')",
- "update crash_q,crash_me set crash_q.b=crash_me.b where crash_q.a=crash_me.a"],
- "select b from crash_q",
- ["drop table crash_q $drop_attr"],
+ ["create table crash_q (a integer,b char(10))",
+ "insert into crash_q values(1,'c')",
+ "update crash_q,crash_me set crash_q.b=crash_me.b ".
+ "where crash_q.a=crash_me.a"],
+ "select b from crash_q",
+ ["drop table crash_q $drop_attr"],
"a",1,
1);
}
@@ -1192,7 +1720,8 @@ report("DELETE FROM table1,table2...","multi_table_delete",
check_and_report("Update with sub select","select_table_update",
["create table crash_q (a integer,b char(10))",
"insert into crash_q values(1,'c')",
- "update crash_q set b= (select b from crash_me where crash_q.a = crash_me.a)"],
+ "update crash_q set b= ".
+ "(select b from crash_me where crash_q.a = crash_me.a)"],
"select b from crash_q",
["drop table crash_q $drop_attr"],
"a",1);
@@ -1336,27 +1865,27 @@ report("index in create table",'index_in_create',
# later
if (!(defined($limits{'create_index'}) && defined($limits{'drop_index'})))
{
- if ($res=safe_query("create index crash_q on crash_me (a)"))
+ if ($res=safe_query_l('create_index',"create index crash_q on crash_me (a)"))
{
$res="yes";
$drop_res="yes";
$end_drop_keyword="";
- if (!safe_query("drop index crash_q"))
+ if (!safe_query_l('drop_index',"drop index crash_q"))
{
# Can't drop the standard way; Check if mSQL
- if (safe_query("drop index crash_q from crash_me"))
+ if (safe_query_l('drop_index',"drop index crash_q from crash_me"))
{
$drop_res="with 'FROM'"; # Drop is not ANSI SQL
$end_drop_keyword="drop index %i from %t";
}
# else check if Access or MySQL
- elsif (safe_query("drop index crash_q on crash_me"))
+ elsif (safe_query_l('drop_index',"drop index crash_q on crash_me"))
{
$drop_res="with 'ON'"; # Drop is not ANSI SQL
$end_drop_keyword="drop index %i on %t";
}
# else check if MS-SQL
- elsif (safe_query("drop index crash_me.crash_q"))
+ elsif (safe_query_l('drop_index',"drop index crash_me.crash_q"))
{
$drop_res="with 'table.index'"; # Drop is not ANSI SQL
$end_drop_keyword="drop index %t.%i";
@@ -1366,7 +1895,7 @@ if (!(defined($limits{'create_index'}) && defined($limits{'drop_index'})))
{
# Old MySQL 3.21 supports only the create index syntax
# This means that the second create doesn't give an error.
- $res=safe_query(["create index crash_q on crash_me (a)",
+ $res=safe_query_l('create_index',["create index crash_q on crash_me (a)",
"create index crash_q on crash_me (a)",
"drop index crash_q"]);
$res= $res ? 'ignored' : 'yes';
@@ -1438,6 +1967,14 @@ if (!report("case independent table names","table_name_case",
safe_query("drop table crash_q $drop_attr");
}
+if (!report("case independent field names","field_name_case",
+ "create table crash_q (q integer)",
+ "insert into crash_q(Q) values (1)",
+ "drop table crash_q $drop_attr"))
+{
+ safe_query("drop table crash_q $drop_attr");
+}
+
if (!report("drop table if exists","drop_if_exists",
"create table crash_q (q integer)",
"drop table if exists crash_q $drop_attr"))
@@ -1454,25 +1991,31 @@ safe_query("drop table crash_q $drop_attr");
# test of different join types
#
-assert("create table crash_me2 (a integer not null,b char(10) not null, c1 integer)");
+assert("create table crash_me2 (a integer not null,b char(10) not null,".
+ " c1 integer)");
assert("insert into crash_me2 (a,b,c1) values (1,'b',1)");
assert("create table crash_me3 (a integer not null,b char(10) not null)");
assert("insert into crash_me3 (a,b) values (1,'b')");
report("inner join","inner_join",
- "select crash_me.a from crash_me inner join crash_me2 ON crash_me.a=crash_me2.a");
+ "select crash_me.a from crash_me inner join crash_me2 ON ".
+ "crash_me.a=crash_me2.a");
report("left outer join","left_outer_join",
- "select crash_me.a from crash_me left join crash_me2 ON crash_me.a=crash_me2.a");
+ "select crash_me.a from crash_me left join crash_me2 ON ".
+ "crash_me.a=crash_me2.a");
report("natural left outer join","natural_left_outer_join",
"select c1 from crash_me natural left join crash_me2");
report("left outer join using","left_outer_join_using",
"select c1 from crash_me left join crash_me2 using (a)");
report("left outer join odbc style","odbc_left_outer_join",
- "select crash_me.a from { oj crash_me left outer join crash_me2 ON crash_me.a=crash_me2.a }");
+ "select crash_me.a from { oj crash_me left outer join crash_me2 ON".
+ " crash_me.a=crash_me2.a }");
report("right outer join","right_outer_join",
- "select crash_me.a from crash_me right join crash_me2 ON crash_me.a=crash_me2.a");
+ "select crash_me.a from crash_me right join crash_me2 ON ".
+ "crash_me.a=crash_me2.a");
report("full outer join","full_outer_join",
- "select crash_me.a from crash_me full join crash_me2 ON crash_me.a=crash_me2.a");
+ "select crash_me.a from crash_me full join crash_me2 ON "."
+ crash_me.a=crash_me2.a");
report("cross join (same as from a,b)","cross_join",
"select crash_me.a from crash_me cross join crash_me3");
report("natural join","natural_join",
@@ -1526,7 +2069,8 @@ assert("drop table crash_me3 $drop_attr");
# >ALL | ANY | SOME - EXISTS - UNIQUE
if (report("subqueries","subqueries",
- "select a from crash_me where crash_me.a in (select max(a) from crash_me)"))
+ "select a from crash_me where crash_me.a in ".
+ "(select max(a) from crash_me)"))
{
$tmp=new query_repeat([],"select a from crash_me","","",
" where a in (select a from crash_me",")",
@@ -1543,19 +2087,29 @@ if (!defined($limits{"transactions"}))
{
my ($limit,$type);
$limit="transactions";
+ $limit_r="rollback_metadata";
print "$limit: ";
foreach $type (('', 'type=bdb', 'type=innodb', 'type=gemini'))
{
undef($limits{$limit});
- last if (!report_trans($limit,
+ if (!report_trans($limit,
[create_table("crash_q",["a integer not null"],[],
$type),
"insert into crash_q values (1)"],
"select * from crash_q",
"drop table crash_q $drop_attr"
- ));
+ ))
+ {
+ report_rollback($limit_r,
+ [create_table("crash_q",["a integer not null"],[],
+ $type)],
+ "insert into crash_q values (1)",
+ "drop table crash_q $drop_attr" );
+ last;
+ };
}
print "$limits{$limit}\n";
+ print "$limit_r: $limits{$limit_r}\n";
}
report("atomic updates","atomic_updates",
@@ -1584,32 +2138,65 @@ report("views","views",
"create view crash_q as select a from crash_me",
"drop view crash_q $drop_attr");
-report("foreign key syntax","foreign_key_syntax",
- create_table("crash_q",["a integer not null"],["primary key (a)"]),
- create_table("crash_q2",["a integer not null",
- "foreign key (a) references crash_q (a)"],
- []),
- "insert into crash_q values (1)",
- "insert into crash_q2 values (1)",
- "drop table crash_q2 $drop_attr",
- "drop table crash_q $drop_attr");
+# Test: foreign key
+{
+ my $result = 'undefined';
+ my $error;
+ print "foreign keys: ";
+ save_incomplete('foreign_key','foreign keys');
+
+# 1) check if foreign keys are supported
+ safe_query_l('foreign_key',
+ create_table("crash_me_qf",
+ ["a integer not null"],
+ ["primary key (a)"]));
+ $error= safe_query_l('foreign_key',
+ create_table("crash_me_qf2",
+ ["a integer not null",
+ "foreign key (a) references crash_me_qf (a)"],
+ []));
+
+ if ($error == 1) # OK -- syntax is supported
+ {
+ $result = 'error';
+ # now check if foreign key really works
+ safe_query_l('foreign_key', "insert into crash_me_qf values (1)");
+ if (safe_query_l('foreign_key', "insert into crash_me_qf2 values (2)") eq 1)
+ {
+ $result = 'syntax only';
+ }
+ else
+ {
+ $result = 'yes';
+ }
+ }
+ else
+ {
+ $result = "no";
+ }
+ safe_query_l('foreign_key', "drop table crash_me_qf2 $drop_attr");
+ safe_query_l('foreign_key', "drop table crash_me_qf $drop_attr");
+ print "$result\n";
+ save_config_data('foreign_key',$result,"foreign keys");
+}
-if ($limits{'foreign_key_syntax'} eq 'yes')
+if ($limits{'foreign_key'} eq 'yes')
{
- report_fail("foreign keys","foreign_key",
- create_table("crash_q",["a integer not null"],
- ["primary key (a)"]),
- create_table("crash_q2",["a integer not null",
- "foreign key (a) references crash_q (a)"],
- []),
- "insert into crash_q values (1)",
- "insert into crash_q2 values (2)",
- "drop table crash_q2 $drop_attr",
- "drop table crash_q $drop_attr");
+ report("allows to update of foreign key values",'foreign_update',
+ "create table crash_me1 (a int not null primary key)",
+ "create table crash_me2 (a int not null," .
+ " foreign key (a) references crash_me1 (a))",
+ "insert into crash_me1 values (1)",
+ "insert into crash_me2 values (1)",
+ "update crash_me1 set a = 2", ## <- must fail
+ "drop table crash_me2 $drop_attr",
+ "drop table crash_me1 $drop_attr"
+ );
}
report("Create SCHEMA","create_schema",
- "create schema crash_schema create table crash_q (a int) create table crash_q2(b int)",
+ "create schema crash_schema create table crash_q (a int) ".
+ "create table crash_q2(b int)",
"drop schema crash_schema cascade");
if ($limits{'foreign_key'} eq 'yes')
@@ -1617,58 +2204,112 @@ if ($limits{'foreign_key'} eq 'yes')
if ($limits{'create_schema'} eq 'yes')
{
report("Circular foreign keys","foreign_key_circular",
- "create schema crash_schema create table crash_q (a int primary key, b int, foreign key (b) references crash_q2(a)) create table crash_q2(a int, b int, primary key(a), foreign key (b) references crash_q(a))",
+ "create schema crash_schema create table crash_q ".
+ "(a int primary key, b int, foreign key (b) references ".
+ "crash_q2(a)) create table crash_q2(a int, b int, ".
+ "primary key(a), foreign key (b) references crash_q(a))",
"drop schema crash_schema cascade");
}
}
-report("Column constraints","constraint_check",
- "create table crash_q (a int check (a>0))",
- "drop table crash_q $drop_attr");
+if ($limits{'func_sql_character_length'} eq 'yes')
+{
+ my $result = 'error';
+ my ($resultset);
+ my $key = 'length_of_varchar_field';
+ my $prompt='CHARACTER_LENGTH(varchar_field)';
+ print $prompt," = ";
+ if (!defined($limits{$key})) {
+ save_incomplete($key,$prompt);
+ safe_query_l($key,[
+ "CREATE TABLE crash_me1 (S1 VARCHAR(100))",
+ "INSERT INTO crash_me1 VALUES ('X')"
+ ]);
+ my $recset = get_recordset($key,
+ "SELECT CHARACTER_LENGTH(S1) FROM crash_me1");
+ print_recordset($key,$recset);
+ if (defined($recset)){
+ if ( $recset->[0][0] eq 1 ) {
+ $result = 'actual length';
+ } elsif( $recset->[0][0] eq 100 ) {
+ $result = 'defined length';
+ };
+ } else {
+ add_log($key,$DBI::errstr);
+ }
+ safe_query_l($key, "drop table crash_me1 $drop_attr");
+ save_config_data($key,$result,$prompt);
+ } else {
+ $result = $limits{$key};
+ };
+ print "$result\n";
+}
+
+
+check_constraint("Column constraints","constraint_check",
+ "create table crash_q (a int check (a>0))",
+ "insert into crash_q values(0)",
+ "drop table crash_q $drop_attr");
+
-report("Table constraints","constraint_check_table",
+check_constraint("Table constraints","constraint_check_table",
"create table crash_q (a int ,b int, check (a>b))",
+ "insert into crash_q values(0,0)",
"drop table crash_q $drop_attr");
-report("Named constraints","constraint_check",
+check_constraint("Named constraints","constraint_check_named",
"create table crash_q (a int ,b int, constraint abc check (a>b))",
+ "insert into crash_q values(0,0)",
"drop table crash_q $drop_attr");
+
report("NULL constraint (SyBase style)","constraint_null",
"create table crash_q (a int null)",
"drop table crash_q $drop_attr");
report("Triggers (ANSI SQL)","psm_trigger",
"create table crash_q (a int ,b int)",
- "create trigger crash_trigger after insert on crash_q referencing new table as new_a when (localtime > time '18:00:00') begin atomic end",
+ "create trigger crash_trigger after insert on crash_q referencing ".
+ "new table as new_a when (localtime > time '18:00:00') ".
+ "begin atomic end",
"insert into crash_q values(1,2)",
"drop trigger crash_trigger",
"drop table crash_q $drop_attr");
report("PSM procedures (ANSI SQL)","psm_procedures",
"create table crash_q (a int,b int)",
- "create procedure crash_proc(in a1 int, in b1 int) language sql modifies sql data begin declare c1 int; set c1 = a1 + b1; insert into crash_q(a,b) values (a1,c1); end",
+ "create procedure crash_proc(in a1 int, in b1 int) language ".
+ "sql modifies sql data begin declare c1 int; set c1 = a1 + b1;".
+ " insert into crash_q(a,b) values (a1,c1); end",
"call crash_proc(1,10)",
"drop procedure crash_proc",
"drop table crash_q $drop_attr");
report("PSM modules (ANSI SQL)","psm_modules",
"create table crash_q (a int,b int)",
- "create module crash_m declare procedure crash_proc(in a1 int, in b1 int) language sql modifies sql data begin declare c1 int; set c1 = a1 + b1; insert into crash_q(a,b) values (a1,c1); end; declare procedure crash_proc2(INOUT a int, in b int) contains sql set a = b + 10; end module",
+ "create module crash_m declare procedure ".
+ "crash_proc(in a1 int, in b1 int) language sql modifies sql ".
+ "data begin declare c1 int; set c1 = a1 + b1; ".
+ "insert into crash_q(a,b) values (a1,c1); end; ".
+ "declare procedure crash_proc2(INOUT a int, in b int) ".
+ "contains sql set a = b + 10; end module",
"call crash_proc(1,10)",
"drop module crash_m cascade",
"drop table crash_q cascade $drop_attr");
report("PSM functions (ANSI SQL)","psm_functions",
"create table crash_q (a int)",
- "create function crash_func(in a1 int, in b1 int) returns int language sql deterministic contains sql begin return a1 * b1; end",
+ "create function crash_func(in a1 int, in b1 int) returns int".
+ " language sql deterministic contains sql ".
+ " begin return a1 * b1; end",
"insert into crash_q values(crash_func(2,4))",
"select a,crash_func(a,2) from crash_q",
"drop function crash_func cascade",
"drop table crash_q $drop_attr");
report("Domains (ANSI SQL)","domains",
- "create domain crash_d as varchar(10) default 'Empty' check (value <> 'abcd')",
+ "create domain crash_d as varchar(10) default 'Empty' ".
+ "check (value <> 'abcd')",
"create table crash_q(a crash_d, b int)",
"insert into crash_q(a,b) values('xyz',10)",
"insert into crash_q(b) values(10)",
@@ -1844,28 +2485,31 @@ if ($limits{'unique_in_create'} eq 'yes')
$max_keys,0));
find_limit("index parts","max_index_parts",
- new query_table("create table crash_q ($key_definitions,unique (q0",
+ new query_table("create table crash_q ".
+ "($key_definitions,unique (q0",
",q%d","))",
- ["insert into crash_q ($key_fields) values ($key_values)"],
- "select q0 from crash_q",1,
- "drop table crash_q $drop_attr",
- $max_keys,1));
+ ["insert into crash_q ($key_fields) values ($key_values)"],
+ "select q0 from crash_q",1,
+ "drop table crash_q $drop_attr",
+ $max_keys,1));
find_limit("max index part length","max_index_part_length",
- new query_many(["create table crash_q (q char(%d) not null,unique(q))",
- "insert into crash_q (q) values ('%s')"],
- "select q from crash_q","%s",
- ["drop table crash_q $drop_attr"],
- $limits{'max_char_size'},0));
+ new query_many(["create table crash_q (q char(%d) not null,".
+ "unique(q))",
+ "insert into crash_q (q) values ('%s')"],
+ "select q from crash_q","%s",
+ ["drop table crash_q $drop_attr"],
+ $limits{'max_char_size'},0));
if ($limits{'type_sql_varchar(1_arg)'} eq 'yes')
{
find_limit("index varchar part length","max_index_varchar_part_length",
- new query_many(["create table crash_q (q varchar(%d) not null,unique(q))",
- "insert into crash_q (q) values ('%s')"],
- "select q from crash_q","%s",
- ["drop table crash_q $drop_attr"],
- $limits{'max_varchar_size'},0));
+ new query_many(["create table crash_q (q varchar(%d) not null,".
+ "unique(q))",
+ "insert into crash_q (q) values ('%s')"],
+ "select q from crash_q","%s",
+ ["drop table crash_q $drop_attr"],
+ $limits{'max_varchar_size'},0));
}
}
@@ -1875,6 +2519,9 @@ if ($limits{'create_index'} ne 'no')
if ($limits{'create_index'} eq 'ignored' ||
$limits{'unique_in_create'} eq 'yes')
{ # This should be true
+ add_log('max_index',
+ " max_unique_index=$limits{'max_unique_index'} ,".
+ "so max_index must be same");
save_config_data('max_index',$limits{'max_unique_index'},"max index");
print "indexes: $limits{'max_index'}\n";
}
@@ -1882,10 +2529,11 @@ if ($limits{'create_index'} ne 'no')
{
if (!defined($limits{'max_index'}))
{
- assert("create table crash_q ($key_definitions)");
+ safe_query_l('max_index',"create table crash_q ($key_definitions)");
for ($i=1; $i <= min($limits{'max_columns'},$max_keys) ; $i++)
{
- last if (!safe_query("create index crash_q$i on crash_q (q$i)"));
+ last if (!safe_query_l('max_index',
+ "create index crash_q$i on crash_q (q$i)"));
}
save_config_data('max_index',$i == $max_keys ? $max_keys : $i,
"max index");
@@ -1901,10 +2549,12 @@ if ($limits{'create_index'} ne 'no')
print "indexs: $limits{'max_index'}\n";
if (!defined($limits{'max_unique_index'}))
{
- assert("create table crash_q ($key_definitions)");
+ safe_query_l('max_unique_index',
+ "create table crash_q ($key_definitions)");
for ($i=0; $i < min($limits{'max_columns'},$max_keys) ; $i++)
{
- last if (!safe_query("create unique index crash_q$i on crash_q (q$i)"));
+ last if (!safe_query_l('max_unique_index',
+ "create unique index crash_q$i on crash_q (q$i)"));
}
save_config_data('max_unique_index',$i == $max_keys ? $max_keys : $i,
"max unique index");
@@ -1920,7 +2570,8 @@ if ($limits{'create_index'} ne 'no')
print "unique indexes: $limits{'max_unique_index'}\n";
if (!defined($limits{'max_index_parts'}))
{
- assert("create table crash_q ($key_definitions)");
+ safe_query_l('max_index_parts',
+ "create table crash_q ($key_definitions)");
$end_drop=$end_drop_keyword;
$end_drop =~ s/%i/crash_q1%d/;
$end_drop =~ s/%t/crash_q/;
@@ -1991,6 +2642,147 @@ find_limit("number of columns in group by","columns_in_group_by",
["drop table crash_q $drop_attr"],
$max_order_by));
+
+
+# Safe arithmetic test
+
+$prompt="safe decimal arithmetic";
+$key="safe_decimal_arithmetic";
+if (!defined($limits{$key}))
+{
+ print "$prompt=";
+ save_incomplete($key,$prompt);
+ if (!safe_query_l($key,$server->create("crash_me_a",
+ ["a decimal(10,2)","b decimal(10,2)"])))
+ {
+ print DBI->errstr();
+ die "Can't create table 'crash_me_a' $DBI::errstr\n";
+ };
+
+ if (!safe_query_l($key,
+ ["insert into crash_me_a (a,b) values (11.4,18.9)"]))
+ {
+ die "Can't insert into table 'crash_me_a' a record: $DBI::errstr\n";
+ };
+
+ $arithmetic_safe = 'no';
+ $arithmetic_safe = 'yes'
+ if ( (safe_query_result_l($key,
+ 'select count(*) from crash_me_a where a+b=30.3',1,0) == 0)
+ and (safe_query_result_l($key,
+ 'select count(*) from crash_me_a where a+b-30.3 = 0',1,0) == 0)
+ and (safe_query_result_l($key,
+ 'select count(*) from crash_me_a where a+b-30.3 < 0',0,0) == 0)
+ and (safe_query_result_l($key,
+ 'select count(*) from crash_me_a where a+b-30.3 > 0',0,0) == 0));
+ save_config_data($key,$arithmetic_safe,$prompt);
+ print "$arithmetic_safe\n";
+ assert("drop table crash_me_a $drop_attr");
+}
+ else
+{
+ print "$prompt=$limits{$key} (cached)\n";
+}
+
+# Check where is null values in sorted recordset
+if (!safe_query($server->create("crash_me_n",["i integer","r integer"])))
+ {
+ print DBI->errstr();
+ die "Can't create table 'crash_me_n' $DBI::errstr\n";
+ };
+
+safe_query_l("position_of_null",["insert into crash_me_n (i) values(1)",
+"insert into crash_me_n values(2,2)",
+"insert into crash_me_n values(3,3)",
+"insert into crash_me_n values(4,4)",
+"insert into crash_me_n (i) values(5)"]);
+
+$key = "position_of_null";
+$prompt ="Where is null values in sorted recordset";
+if (!defined($limits{$key}))
+{
+ save_incomplete($key,$prompt);
+ print "$prompt=";
+ $sth=$dbh->prepare("select r from crash_me_n order by r ");
+ $sth->execute;
+ add_log($key,"< select r from crash_me_n order by r ");
+ $limit= detect_null_position($key,$sth);
+ $sth->finish;
+ print "$limit\n";
+ save_config_data($key,$limit,$prompt);
+} else {
+ print "$prompt=$limits{$key} (cache)\n";
+}
+
+$key = "position_of_null_desc";
+$prompt ="Where is null values in sorted recordset (DESC)";
+if (!defined($limits{$key}))
+{
+ save_incomplete($key,$prompt);
+ print "$prompt=";
+ $sth=$dbh->prepare("select r from crash_me_n order by r desc");
+ $sth->execute;
+ add_log($key,"< select r from crash_me_n order by r desc");
+ $limit= detect_null_position($key,$sth);
+ $sth->finish;
+ print "$limit\n";
+ save_config_data($key,$limit,$prompt);
+} else {
+ print "$prompt=$limits{$key} (cache)\n";
+}
+
+
+assert("drop table crash_me_n $drop_attr");
+
+
+
+$key = 'sorted_group_by';
+$prompt = 'Group by always sorted';
+if (!defined($limits{$key}))
+{
+ save_incomplete($key,$prompt);
+ print "$prompt=";
+ safe_query_l($key,[
+ "create table crash_me_t1 (a int not null, b int not null)",
+ "insert into crash_me_t1 values (1,1)",
+ "insert into crash_me_t1 values (1,2)",
+ "insert into crash_me_t1 values (3,1)",
+ "insert into crash_me_t1 values (3,2)",
+ "insert into crash_me_t1 values (2,2)",
+ "insert into crash_me_t1 values (2,1)",
+ "create table crash_me_t2 (a int not null, b int not null)",
+ "create index crash_me_t2_ind on crash_me_t2 (a)",
+ "insert into crash_me_t2 values (1,3)",
+ "insert into crash_me_t2 values (3,1)",
+ "insert into crash_me_t2 values (2,2)",
+ "insert into crash_me_t2 values (1,1)"]);
+
+ my $bigqry = "select crash_me_t1.a,crash_me_t2.b from ".
+ "crash_me_t1,crash_me_t2 where crash_me_t1.a=crash_me_t2.a ".
+ "group by crash_me_t1.a,crash_me_t2.b";
+
+ my $limit='no';
+ my $rs = get_recordset($key,$bigqry);
+ print_recordset($key,$rs);
+ if ( defined ($rs)) {
+ if (compare_recordset($key,$rs,[[1,1],[1,3],[2,2],[3,1]]) eq 0)
+ {
+ $limit='yes'
+ }
+ } else {
+ add_log($key,"error: ".$DBI::errstr);
+ }
+
+ print "$limit\n";
+ safe_query_l($key,["drop table crash_me_t1",
+ "drop table crash_me_t2"]);
+ save_config_data($key,$limit,$prompt);
+
+} else {
+ print "$prompt=$limits{$key} (cashed)\n";
+}
+
+
#
# End of test
#
@@ -2004,10 +2796,249 @@ $dbh->disconnect || warn $dbh->errstr;
save_all_config_data();
exit 0;
+# End of test
+#
+
+$dbh->do("drop table crash_me $drop_attr"); # Remove temporary table
+
+print "crash-me safe: $limits{'crash_me_safe'}\n";
+print "reconnected $reconnect_count times\n";
+
+$dbh->disconnect || warn $dbh->errstr;
+save_all_config_data();
+exit 0;
+
+# Check where is nulls in the sorted result (for)
+# it expects exactly 5 rows in the result
+
+sub detect_null_position
+{
+ my $key = shift;
+ my $sth = shift;
+ my ($z,$r1,$r2,$r3,$r4,$r5);
+ $r1 = $sth->fetchrow_array; add_log($key,"> $r1");
+ $r2 = $sth->fetchrow_array; add_log($key,"> $r2");
+ $r3 = $sth->fetchrow_array; add_log($key,"> $r3");
+ $r4 = $sth->fetchrow_array; add_log($key,"> $r4");
+ $r5 = $sth->fetchrow_array; add_log($key,"> $r5");
+ return "first" if ( !defined($r1) && !defined($r2) && defined($r3));
+ return "last" if ( !defined($r5) && !defined($r4) && defined($r3));
+ return "random";
+}
+
+sub check_parenthesis {
+ my $prefix=shift;
+ my $fn=shift;
+ my $result='no';
+ my $param_name=$prefix.lc($fn);
+ my $r;
+
+ save_incomplete($param_name,$fn);
+ $r = safe_query("select $fn $end_query");
+ add_log($param_name,$safe_query_log);
+ if ($r == 1)
+ {
+ $result="yes";
+ }
+ else{
+ $r = safe_query("select $fn() $end_query");
+ add_log($param_name,$safe_query_log);
+ if ( $r == 1)
+ {
+ $result="with_parenthesis";
+ }
+ }
+
+ save_config_data($param_name,$result,$fn);
+}
+
+sub check_constraint {
+ my $prompt = shift;
+ my $key = shift;
+ my $create = shift;
+ my $check = shift;
+ my $drop = shift;
+ save_incomplete($key,$prompt);
+ print "$prompt=";
+ my $res = 'no';
+ my $t;
+ $t=safe_query($create);
+ add_log($key,$safe_query_log);
+ if ( $t == 1)
+ {
+ $res='yes';
+ $t= safe_query($check);
+ add_log($key,$safe_query_log);
+ if ($t == 1)
+ {
+ $res='syntax only';
+ }
+ }
+ safe_query($drop);
+ add_log($key,$safe_query_log);
+
+ save_config_data($key,$res,$prompt);
+ print "$res\n";
+}
+
+sub make_time_r {
+ my $hour=shift;
+ my $minute=shift;
+ my $second=shift;
+ $_ = $limits{'time_format_inresult'};
+ return sprintf "%02d:%02d:%02d", ($hour%24),$minute,$second if (/^iso$/);
+ return sprintf "%02d.%02d.%02d", ($hour%24),$minute,$second if (/^euro/);
+ return sprintf "%02d:%02d %s",
+ ($hour >= 13? ($hour-12) : $hour),$minute,($hour >=13 ? 'PM':'AM')
+ if (/^usa/);
+ return sprintf "%02d%02d%02d", ($hour%24),$minute,$second if (/^HHMMSS/);
+ return sprintf "%04d%02d%02d", ($hour%24),$minute,$second if (/^HHHHMMSS/);
+ return "UNKNOWN FORMAT";
+}
+
+sub make_time {
+ my $hour=shift;
+ my $minute=shift;
+ my $second=shift;
+ return sprintf "%02d:%02d:%02d", ($hour%24),$minute,$second
+ if ($limits{'time_format_ISO'} eq "yes");
+ return sprintf "%02d.%02d.%02d", ($hour%24),$minute,$second
+ if ($limits{'time_format_EUR'} eq "yes");
+ return sprintf "%02d:%02d %s",
+ ($hour >= 13? ($hour-12) : $hour),$minute,($hour >=13 ? 'PM':'AM')
+ if ($limits{'time_format_USA'} eq "yes");
+ return sprintf "%02d%02d%02d", ($hour%24),$minute,$second
+ if ($limits{'time_format_HHMMSS'} eq "yes");
+ return sprintf "%04d%02d%02d", ($hour%24),$minute,$second
+ if ($limits{'time_format_HHHHMMSS'} eq "yes");
+ return "UNKNOWN FORMAT";
+}
+
+sub make_date_r {
+ my $year=shift;
+ my $month=shift;
+ my $day=shift;
+ $_ = $limits{'date_format_inresult'};
+ return sprintf "%02d-%02d-%02d", ($year%100),$month,$day if (/^short iso$/);
+ return sprintf "%04d-%02d-%02d", $year,$month,$day if (/^iso/);
+ return sprintf "%02d.%02d.%02d", $day,$month,($year%100) if (/^short euro/);
+ return sprintf "%02d.%02d.%04d", $day,$month,$year if (/^euro/);
+ return sprintf "%02d/%02d/%02d", $month,$day,($year%100) if (/^short usa/);
+ return sprintf "%02d/%02d/%04d", $month,$day,$year if (/^usa/);
+ return sprintf "%04d%02d%02d", $year,$month,$day if (/^YYYYMMDD/);
+ return "UNKNOWN FORMAT";
+}
+
+
+sub make_date {
+ my $year=shift;
+ my $month=shift;
+ my $day=shift;
+ return sprintf "'%04d-%02d-%02d'", $year,$month,$day
+ if ($limits{'date_format_ISO'} eq yes);
+ return sprintf "DATE '%04d-%02d-%02d'", $year,$month,$day
+ if ($limits{'date_format_ISO_with_date'} eq yes);
+ return sprintf "'%02d.%02d.%04d'", $day,$month,$year
+ if ($limits{'date_format_EUR'} eq 'yes');
+ return sprintf "DATE '%02d.%02d.%04d'", $day,$month,$year
+ if ($limits{'date_format_EUR_with_date'} eq 'yes');
+ return sprintf "'%02d/%02d/%04d'", $month,$day,$year
+ if ($limits{'date_format_USA'} eq 'yes');
+ return sprintf "DATE '%02d/%02d/%04d'", $month,$day,$year
+ if ($limits{'date_format_USA_with_date'} eq 'yes');
+ return sprintf "'%04d%02d%02d'", $year,$month,$day
+ if ($limits{'date_format_YYYYMMDD'} eq 'yes');
+ return sprintf "DATE '%04d%02d%02d'", $year,$month,$day
+ if ($limits{'date_format_YYYYMMDD_with_date'} eq 'yes');
+ return "UNKNOWN FORMAT";
+}
+
+
+sub print_recordset{
+ my ($key,$recset) = @_;
+ my $rec;
+ foreach $rec (@$recset)
+ {
+ add_log($key, " > ".join(',', map(repr($_), @$rec)));
+ }
+}
+
+#
+# read result recordset from sql server.
+# returns arrayref to (arrayref to) values
+# or undef (in case of sql errors)
+#
+sub get_recordset{
+ my ($key,$query) = @_;
+ add_log($key, "< $query");
+ return $dbh->selectall_arrayref($query);
+}
+
+# function for comparing recordset (that was returned by get_recordset)
+# and arrayref of (arrayref of) values.
+#
+# returns : zero if recordset equal that array, 1 if it doesn't equal
+#
+# parameters:
+# $key - current operation (for logging)
+# $recset - recordset
+# $mustbe - array of values that we expect
+#
+# example: $a=get_recordset('some_parameter','select a,b from c');
+# if (compare_recordset('some_parameter',$a,[[1,1],[1,2],[1,3]]) neq 0)
+# {
+# print "unexpected result\n";
+# } ;
+#
+sub compare_recordset {
+ my ($key,$recset,$mustbe) = @_;
+ my $rec,$recno,$fld,$fldno,$fcount;
+ add_log($key,"\n Check recordset:");
+ $recno=0;
+ foreach $rec (@$recset)
+ {
+ add_log($key," " . join(',', map(repr($_),@$rec)) . " expected: " .
+ join(',', map(repr($_), @{$mustbe->[$recno]} ) ));
+ $fcount = @$rec;
+ $fcount--;
+ foreach $fldno (0 .. $fcount )
+ {
+ if ($mustbe->[$recno][$fldno] ne $rec->[$fldno])
+ {
+ add_log($key," Recordset doesn't correspond with template");
+ return 1;
+ };
+ }
+ $recno++;
+ }
+ add_log($key," Recordset corresponds with template");
+ return 0;
+}
+
+#
+# converts inner perl value to printable representation
+# for example: undef maps to 'NULL',
+# string -> 'string'
+# int -> int
+#
+sub repr {
+ my $s = shift;
+ return "'$s'"if ($s =~ /\D/);
+ return 'NULL'if ( not defined($s));
+ return $s;
+}
+
+
+sub version
+{
+ print "$0 Ver $version\n";
+}
+
+
sub usage
{
+ version();
print <<EOF;
-$0 Ver $version
This program tries to find all limits and capabilities for a SQL
server. As it will use the server in some 'unexpected' ways, one
@@ -2019,9 +3050,10 @@ As all used queries are legal according to some SQL standard. any
reasonable SQL server should be able to run this test without any
problems.
-All questions is cached in $opt_dir/'server_name'.cfg that future runs will use
-limits found in previous runs. Remove this file if you want to find the
-current limits for your version of the database server.
+All questions is cached in $opt_dir/'server_name'[-suffix].cfg that
+future runs will use limits found in previous runs. Remove this file
+if you want to find the current limits for your version of the
+database server.
This program uses some table names while testing things. If you have any
tables with the name of 'crash_me' or 'crash_qxxxx' where 'x' is a number,
@@ -2035,6 +3067,9 @@ $0 takes the following options:
--batch-mode
Don\'t ask any questions, quit on errors.
+--config-file='filename'
+ Read limit results from specific file
+
--comment='some comment'
Add this comment to the crash-me limit file
@@ -2071,7 +3106,7 @@ $0 takes the following options:
--password='password'
Password for the current user.
-
+
--restart
Save states during each limit tests. This will make it possible to continue
by restarting with the same options if there is some bug in the DBI or
@@ -2079,18 +3114,28 @@ $0 takes the following options:
--server='server name' (Default $opt_server)
Run the test on the given server.
- Known servers names are: Access, Adabas, AdabasD, Empress, Oracle, Informix, DB2, Mimer, mSQL, MS-SQL, MySQL, Pg, Solid or Sybase.
+ Known servers names are: Access, Adabas, AdabasD, Empress, Oracle,
+ Informix, DB2, Mimer, mSQL, MS-SQL, MySQL, Pg, Solid or Sybase.
For others $0 can\'t report the server version.
+--suffix='suffix' (Default '')
+ Add suffix to the output filename. For instance if you run crash-me like
+ "crash-me --suffix="myisam",
+ then output filename will look "mysql-myisam.cfg".
+
--user='user_name'
User name to log into the SQL server.
---start-cmd='command to restart server'
+--db-start-cmd='command to restart server'
Automaticly restarts server with this command if the database server dies.
--sleep='time in seconds' (Default $opt_sleep)
Wait this long before restarting server.
+--verbose
+--noverbose
+ Log into the result file queries performed for determination parameter value
+
EOF
exit(0);
}
@@ -2168,20 +3213,20 @@ EOF
print <<EOF;
Some of the tests you are about to execute may require a lot of
-memory. Your tests WILL adversely affect system performance. It's
+memory. Your tests WILL adversely affect system performance. It\'s
not uncommon that either this crash-me test program, or the actual
database back-end, will DIE with an out-of-memory error. So might
any other program on your system if it requests more memory at the
wrong time.
Note also that while crash-me tries to find limits for the database server
-it will make a lot of queries that can't be categorized as 'normal'. It's
+it will make a lot of queries that can\'t be categorized as \'normal\'. It\'s
not unlikely that crash-me finds some limit bug in your server so if you
run this test you have to be prepared that your server may die during it!
We, the creators of this utility, are not responsible in any way if your
database server unexpectedly crashes while this program tries to find the
-limitations of your server. By accepting the following question with 'yes',
+limitations of your server. By accepting the following question with \'yes\',
you agree to the above!
You have been warned!
@@ -2204,24 +3249,8 @@ EOF
sub machine
{
- $name= `uname -s -r -m`;
- if ($?)
- {
- $name= `uname -s -m`;
- }
- if ($?)
- {
- $name= `uname -s`;
- }
- if ($?)
- {
- $name= `uname`;
- }
- if ($?)
- {
- $name="unknown";
- }
- chomp($name); $name =~ s/[\n\r]//g;
+ my @name = POSIX::uname();
+ my $name= $name[0] . " " . $name[2] . " " . $name[4];
return $name;
}
@@ -2243,11 +3272,13 @@ sub safe_connect
$dbh->{LongReadLen}= 16000000; # Set max retrieval buffer
return $dbh;
}
- print "Error: $DBI::errstr; $server->{'data_source'} - '$opt_user' - '$opt_password'\n";
+ print "Error: $DBI::errstr; $server->{'data_source'} ".
+ " - '$opt_user' - '$opt_password'\n";
print "I got the above error when connecting to $opt_server\n";
if (defined($object) && defined($object->{'limit'}))
{
- print "This check was done with limit: $object->{'limit'}.\nNext check will be done with a smaller limit!\n";
+ print "This check was done with limit: $object->{'limit'}.".
+ "\nNext check will be done with a smaller limit!\n";
$object=undef();
}
save_config_data('crash_me_safe','no',"crash me safe");
@@ -2276,7 +3307,29 @@ sub safe_connect
}
#
-# Check if the server is upp and running. If not, ask the user to restart it
+# Test connecting a couple of times before giving an error
+# This is needed to get the server time to free old connections
+# after the connect test
+#
+
+sub retry_connect
+{
+ my ($dbh, $i);
+ for ($i=0 ; $i < 10 ; $i++)
+ {
+ if (($dbh=DBI->connect($server->{'data_source'},$opt_user,$opt_password,
+ { PrintError => 0, AutoCommit => 1})))
+ {
+ $dbh->{LongReadLen}= 16000000; # Set max retrieval buffer
+ return $dbh;
+ }
+ sleep(1);
+ }
+ return safe_connect();
+}
+
+#
+# Check if the server is up and running. If not, ask the user to restart it
#
sub check_connect
@@ -2303,6 +3356,15 @@ sub check_connect
#
# print query if debugging
#
+sub repr_query {
+ my $query=shift;
+ if (length($query) > 130)
+ {
+ $query=substr($query,0,120) . "...(" . (length($query)-120) . ")";
+ }
+ return $query;
+}
+
sub print_query
{
my ($query)=@_;
@@ -2319,13 +3381,23 @@ sub print_query
#
# Do one or many queries. Return 1 if all was ok
-# Note that all rows are executed (to ensure that we execute drop table commands)
+# Note that all rows are executed
+# (to ensure that we execute drop table commands)
#
+sub safe_query_l {
+ my $key = shift;
+ my $q = shift;
+ my $r = safe_query($q);
+ add_log($key,$safe_query_log);
+ return $r;
+}
+
sub safe_query
{
my($queries)=@_;
my($query,$ok,$retry_ok,$retry,@tmp,$sth);
+ $safe_query_log="";
$ok=1;
if (ref($queries) ne "ARRAY")
{
@@ -2334,11 +3406,14 @@ sub safe_query
}
foreach $query (@$queries)
{
- printf "query1: %-80.80s ...(%d - %d)\n",$query,length($query),$retry_limit if ($opt_log_all_queries);
+ printf "query1: %-80.80s ...(%d - %d)\n",$query,
+ length($query),$retry_limit if ($opt_log_all_queries);
print LOG "$query;\n" if ($opt_log);
+ $safe_query_log .= "< $query\n";
if (length($query) > $query_size)
{
$ok=0;
+ $safe_query_log .= "Query is too long\n";
next;
}
@@ -2348,6 +3423,7 @@ sub safe_query
if (! ($sth=$dbh->prepare($query)))
{
print_query($query);
+ $safe_query_log .= "> couldn't prepare:". $dbh->errstr. "\n";
$retry=100 if (!$server->abort_if_fatal_error());
# Force a reconnect because of Access drop table bug!
if ($retry == $retry_limit-2)
@@ -2362,6 +3438,7 @@ sub safe_query
if (!$sth->execute())
{
print_query($query);
+ $safe_query_log .= "> execute error:". $dbh->errstr. "\n";
$retry=100 if (!$server->abort_if_fatal_error());
# Force a reconnect because of Access drop table bug!
if ($retry == $retry_limit-2)
@@ -2375,6 +3452,7 @@ sub safe_query
{
$retry = $retry_limit;
$retry_ok = 1;
+ $safe_query_log .= "> OK\n";
}
$sth->finish;
}
@@ -2390,6 +3468,213 @@ sub safe_query
return $ok;
}
+sub check_reserved_words
+{
+ my ($dbh)= @_;
+
+ my $answer, $prompt, $config, $keyword_type;
+
+ my @keywords_ext = ( "ansi-92/99", "ansi92", "ansi99", "extra");
+
+ my %reserved_words = (
+ 'ABSOLUTE' => 0, 'ACTION' => 0, 'ADD' => 0,
+ 'AFTER' => 0, 'ALIAS' => 0, 'ALL' => 0,
+ 'ALLOCATE' => 0, 'ALTER' => 0, 'AND' => 0,
+ 'ANY' => 0, 'ARE' => 0, 'AS' => 0,
+ 'ASC' => 0, 'ASSERTION' => 0, 'AT' => 0,
+ 'AUTHORIZATION' => 0, 'BEFORE' => 0, 'BEGIN' => 0,
+ 'BIT' => 0, 'BOOLEAN' => 0, 'BOTH' => 0,
+ 'BREADTH' => 0, 'BY' => 0, 'CALL' => 0,
+ 'CASCADE' => 0, 'CASCADED' => 0, 'CASE' => 0,
+ 'CAST' => 0, 'CATALOG' => 0, 'CHAR' => 0,
+ 'CHARACTER' => 0, 'CHECK' => 0, 'CLOSE' => 0,
+ 'COLLATE' => 0, 'COLLATION' => 0, 'COLUMN' => 0,
+ 'COMMIT' => 0, 'COMPLETION' => 0, 'CONNECT' => 0,
+ 'CONNECTION' => 0, 'CONSTRAINT' => 0, 'CONSTRAINTS' => 0,
+ 'CONTINUE' => 0, 'CORRESPONDING' => 0, 'CREATE' => 0,
+ 'CROSS' => 0, 'CURRENT' => 0, 'CURRENT_DATE' => 0,
+ 'CURRENT_TIME' => 0,'CURRENT_TIMESTAMP' => 0, 'CURRENT_USER' => 0,
+ 'CURSOR' => 0, 'CYCLE' => 0, 'DATA' => 0,
+ 'DATE' => 0, 'DAY' => 0, 'DEALLOCATE' => 0,
+ 'DEC' => 0, 'DECIMAL' => 0, 'DECLARE' => 0,
+ 'DEFAULT' => 0, 'DEFERRABLE' => 0, 'DEFERRED' => 0,
+ 'DELETE' => 0, 'DEPTH' => 0, 'DESC' => 0,
+ 'DESCRIBE' => 0, 'DESCRIPTOR' => 0, 'DIAGNOSTICS' => 0,
+ 'DICTIONARY' => 0, 'DISCONNECT' => 0, 'DISTINCT' => 0,
+ 'DOMAIN' => 0, 'DOUBLE' => 0, 'DROP' => 0,
+ 'EACH' => 0, 'ELSE' => 0, 'ELSEIF' => 0,
+ 'END' => 0, 'END-EXEC' => 0, 'EQUALS' => 0,
+ 'ESCAPE' => 0, 'EXCEPT' => 0, 'EXCEPTION' => 0,
+ 'EXEC' => 0, 'EXECUTE' => 0, 'EXTERNAL' => 0,
+ 'FALSE' => 0, 'FETCH' => 0, 'FIRST' => 0,
+ 'FLOAT' => 0, 'FOR' => 0, 'FOREIGN' => 0,
+ 'FOUND' => 0, 'FROM' => 0, 'FULL' => 0,
+ 'GENERAL' => 0, 'GET' => 0, 'GLOBAL' => 0,
+ 'GO' => 0, 'GOTO' => 0, 'GRANT' => 0,
+ 'GROUP' => 0, 'HAVING' => 0, 'HOUR' => 0,
+ 'IDENTITY' => 0, 'IF' => 0, 'IGNORE' => 0,
+ 'IMMEDIATE' => 0, 'IN' => 0, 'INDICATOR' => 0,
+ 'INITIALLY' => 0, 'INNER' => 0, 'INPUT' => 0,
+ 'INSERT' => 0, 'INT' => 0, 'INTEGER' => 0,
+ 'INTERSECT' => 0, 'INTERVAL' => 0, 'INTO' => 0,
+ 'IS' => 0, 'ISOLATION' => 0, 'JOIN' => 0,
+ 'KEY' => 0, 'LANGUAGE' => 0, 'LAST' => 0,
+ 'LEADING' => 0, 'LEAVE' => 0, 'LEFT' => 0,
+ 'LESS' => 0, 'LEVEL' => 0, 'LIKE' => 0,
+ 'LIMIT' => 0, 'LOCAL' => 0, 'LOOP' => 0,
+ 'MATCH' => 0, 'MINUTE' => 0, 'MODIFY' => 0,
+ 'MODULE' => 0, 'MONTH' => 0, 'NAMES' => 0,
+ 'NATIONAL' => 0, 'NATURAL' => 0, 'NCHAR' => 0,
+ 'NEW' => 0, 'NEXT' => 0, 'NO' => 0,
+ 'NONE' => 0, 'NOT' => 0, 'NULL' => 0,
+ 'NUMERIC' => 0, 'OBJECT' => 0, 'OF' => 0,
+ 'OFF' => 0, 'OLD' => 0, 'ON' => 0,
+ 'ONLY' => 0, 'OPEN' => 0, 'OPERATION' => 0,
+ 'OPTION' => 0, 'OR' => 0, 'ORDER' => 0,
+ 'OUTER' => 0, 'OUTPUT' => 0, 'PAD' => 0,
+ 'PARAMETERS' => 0, 'PARTIAL' => 0, 'PRECISION' => 0,
+ 'PREORDER' => 0, 'PREPARE' => 0, 'PRESERVE' => 0,
+ 'PRIMARY' => 0, 'PRIOR' => 0, 'PRIVILEGES' => 0,
+ 'PROCEDURE' => 0, 'PUBLIC' => 0, 'READ' => 0,
+ 'REAL' => 0, 'RECURSIVE' => 0, 'REF' => 0,
+ 'REFERENCES' => 0, 'REFERENCING' => 0, 'RELATIVE' => 0,
+ 'RESIGNAL' => 0, 'RESTRICT' => 0, 'RETURN' => 0,
+ 'RETURNS' => 0, 'REVOKE' => 0, 'RIGHT' => 0,
+ 'ROLE' => 0, 'ROLLBACK' => 0, 'ROUTINE' => 0,
+ 'ROW' => 0, 'ROWS' => 0, 'SAVEPOINT' => 0,
+ 'SCHEMA' => 0, 'SCROLL' => 0, 'SEARCH' => 0,
+ 'SECOND' => 0, 'SECTION' => 0, 'SELECT' => 0,
+ 'SEQUENCE' => 0, 'SESSION' => 0, 'SESSION_USER' => 0,
+ 'SET' => 0, 'SIGNAL' => 0, 'SIZE' => 0,
+ 'SMALLINT' => 0, 'SOME' => 0, 'SPACE' => 0,
+ 'SQL' => 0, 'SQLEXCEPTION' => 0, 'SQLSTATE' => 0,
+ 'SQLWARNING' => 0, 'STRUCTURE' => 0, 'SYSTEM_USER' => 0,
+ 'TABLE' => 0, 'TEMPORARY' => 0, 'THEN' => 0,
+ 'TIME' => 0, 'TIMESTAMP' => 0, 'TIMEZONE_HOUR' => 0,
+ 'TIMEZONE_MINUTE' => 0, 'TO' => 0, 'TRAILING' => 0,
+ 'TRANSACTION' => 0, 'TRANSLATION' => 0, 'TRIGGER' => 0,
+ 'TRUE' => 0, 'UNDER' => 0, 'UNION' => 0,
+ 'UNIQUE' => 0, 'UNKNOWN' => 0, 'UPDATE' => 0,
+ 'USAGE' => 0, 'USER' => 0, 'USING' => 0,
+ 'VALUE' => 0, 'VALUES' => 0, 'VARCHAR' => 0,
+ 'VARIABLE' => 0, 'VARYING' => 0, 'VIEW' => 0,
+ 'WHEN' => 0, 'WHENEVER' => 0, 'WHERE' => 0,
+ 'WHILE' => 0, 'WITH' => 0, 'WITHOUT' => 0,
+ 'WORK' => 0, 'WRITE' => 0, 'YEAR' => 0,
+ 'ZONE' => 0,
+
+ 'ASYNC' => 1, 'AVG' => 1, 'BETWEEN' => 1,
+ 'BIT_LENGTH' => 1,'CHARACTER_LENGTH' => 1, 'CHAR_LENGTH' => 1,
+ 'COALESCE' => 1, 'CONVERT' => 1, 'COUNT' => 1,
+ 'EXISTS' => 1, 'EXTRACT' => 1, 'INSENSITIVE' => 1,
+ 'LOWER' => 1, 'MAX' => 1, 'MIN' => 1,
+ 'NULLIF' => 1, 'OCTET_LENGTH' => 1, 'OID' => 1,
+ 'OPERATORS' => 1, 'OTHERS' => 1, 'OVERLAPS' => 1,
+ 'PENDANT' => 1, 'POSITION' => 1, 'PRIVATE' => 1,
+ 'PROTECTED' => 1, 'REPLACE' => 1, 'SENSITIVE' => 1,
+ 'SIMILAR' => 1, 'SQLCODE' => 1, 'SQLERROR' => 1,
+ 'SUBSTRING' => 1, 'SUM' => 1, 'TEST' => 1,
+ 'THERE' => 1, 'TRANSLATE' => 1, 'TRIM' => 1,
+ 'TYPE' => 1, 'UPPER' => 1, 'VIRTUAL' => 1,
+ 'VISIBLE' => 1, 'WAIT' => 1,
+
+ 'ADMIN' => 2, 'AGGREGATE' => 2, 'ARRAY' => 2,
+ 'BINARY' => 2, 'BLOB' => 2, 'CLASS' => 2,
+ 'CLOB' => 2, 'CONDITION' => 2, 'CONSTRUCTOR' => 2,
+ 'CONTAINS' => 2, 'CUBE' => 2, 'CURRENT_PATH' => 2,
+ 'CURRENT_ROLE' => 2, 'DATALINK' => 2, 'DEREF' => 2,
+ 'DESTROY' => 2, 'DESTRUCTOR' => 2, 'DETERMINISTIC' => 2,
+ 'DO' => 2, 'DYNAMIC' => 2, 'EVERY' => 2,
+ 'EXIT' => 2, 'EXPAND' => 2, 'EXPANDING' => 2,
+ 'FREE' => 2, 'FUNCTION' => 2, 'GROUPING' => 2,
+ 'HANDLER' => 2, 'HAST' => 2, 'HOST' => 2,
+ 'INITIALIZE' => 2, 'INOUT' => 2, 'ITERATE' => 2,
+ 'LARGE' => 2, 'LATERAL' => 2, 'LOCALTIME' => 2,
+ 'LOCALTIMESTAMP' => 2, 'LOCATOR' => 2, 'MEETS' => 2,
+ 'MODIFIES' => 2, 'NCLOB' => 2, 'NORMALIZE' => 2,
+ 'ORDINALITY' => 2, 'OUT' => 2, 'PARAMETER' => 2,
+ 'PATH' => 2, 'PERIOD' => 2, 'POSTFIX' => 2,
+ 'PRECEDES' => 2, 'PREFIX' => 2, 'READS' => 2,
+ 'REDO' => 2, 'REPEAT' => 2, 'RESULT' => 2,
+ 'ROLLUP' => 2, 'SETS' => 2, 'SPECIFIC' => 2,
+ 'SPECIFICTYPE' => 2, 'START' => 2, 'STATE' => 2,
+ 'STATIC' => 2, 'SUCCEEDS' => 2, 'TERMINATE' => 2,
+ 'THAN' => 2, 'TREAT' => 2, 'UNDO' => 2,
+ 'UNTIL' => 2,
+
+ 'ACCESS' => 3, 'ANALYZE' => 3, 'AUDIT' => 3,
+ 'AUTO_INCREMENT' => 3, 'BACKUP' => 3, 'BDB' => 3,
+ 'BERKELEYDB' => 3, 'BIGINT' => 3, 'BREAK' => 3,
+ 'BROWSE' => 3, 'BTREE' => 3, 'BULK' => 3,
+ 'CHANGE' => 3, 'CHECKPOINT' => 3, 'CLUSTER' => 3,
+ 'CLUSTERED' => 3, 'COLUMNS' => 3, 'COMMENT' => 3,
+ 'COMPRESS' => 3, 'COMPUTE' => 3, 'CONTAINSTABLE' => 3,
+ 'DATABASE' => 3, 'DATABASES' => 3, 'DAY_HOUR' => 3,
+ 'DAY_MINUTE' => 3, 'DAY_SECOND' => 3, 'DBCC' => 3,
+ 'DELAYED' => 3, 'DENY' => 3, 'DISK' => 3,
+ 'DISTINCTROW' => 3, 'DISTRIBUTED' => 3, 'DUMMY' => 3,
+ 'DUMP' => 3, 'ENCLOSED' => 3, 'ERRLVL' => 3,
+ 'ERRORS' => 3, 'ESCAPED' => 3, 'EXCLUSIVE' => 3,
+ 'EXPLAIN' => 3, 'FIELDS' => 3, 'FILE' => 3,
+ 'FILLFACTOR' => 3, 'FREETEXT' => 3, 'FREETEXTTABLE' => 3,
+ 'FULLTEXT' => 3, 'GEOMETRY' => 3, 'HASH' => 3,
+ 'HIGH_PRIORITY' => 3, 'HOLDLOCK' => 3, 'HOUR_MINUTE' => 3,
+ 'HOUR_SECOND' => 3, 'IDENTIFIED' => 3, 'IDENTITYCOL' => 3,
+ 'IDENTITY_INSERT' => 3, 'INCREMENT' => 3, 'INDEX' => 3,
+ 'INFILE' => 3, 'INITIAL' => 3, 'INNODB' => 3,
+ 'KEYS' => 3, 'KILL' => 3, 'LINENO' => 3,
+ 'LINES' => 3, 'LOAD' => 3, 'LOCK' => 3,
+ 'LONG' => 3, 'LONGBLOB' => 3, 'LONGTEXT' => 3,
+ 'LOW_PRIORITY' => 3, 'MASTER_SERVER_ID' => 3, 'MAXEXTENTS' => 3,
+ 'MEDIUMBLOB' => 3, 'MEDIUMINT' => 3, 'MEDIUMTEXT' => 3,
+ 'MIDDLEINT' => 3, 'MINUS' => 3, 'MINUTE_SECOND' => 3,
+ 'MLSLABEL' => 3, 'MODE' => 3, 'MRG_MYISAM' => 3,
+ 'NOAUDIT' => 3, 'NOCHECK' => 3, 'NOCOMPRESS' => 3,
+ 'NONCLUSTERED' => 3, 'NOWAIT' => 3, 'NUMBER' => 3,
+ 'OFFLINE' => 3, 'OFFSETS' => 3, 'ONLINE' => 3,
+ 'OPENDATASOURCE' => 3, 'OPENQUERY' => 3, 'OPENROWSET' => 3,
+ 'OPENXML' => 3, 'OPTIMIZE' => 3, 'OPTIONALLY' => 3,
+ 'OUTFILE' => 3, 'OVER' => 3, 'PCTFREE' => 3,
+ 'PERCENT' => 3, 'PLAN' => 3, 'PRINT' => 3,
+ 'PROC' => 3, 'PURGE' => 3, 'RAISERROR' => 3,
+ 'RAW' => 3, 'READTEXT' => 3, 'RECONFIGURE' => 3,
+ 'REGEXP' => 3, 'RENAME' => 3, 'REPLICATION' => 3,
+ 'REQUIRE' => 3, 'RESOURCE' => 3, 'RESTORE' => 3,
+ 'RLIKE' => 3, 'ROWCOUNT' => 3, 'ROWGUIDCOL' => 3,
+ 'ROWID' => 3, 'ROWNUM' => 3, 'RTREE' => 3,
+ 'RULE' => 3, 'SAVE' => 3, 'SETUSER' => 3,
+ 'SHARE' => 3, 'SHOW' => 3, 'SHUTDOWN' => 3,
+ 'SONAME' => 3, 'SPATIAL' => 3, 'SQL_BIG_RESULT' => 3,
+'SQL_CALC_FOUND_ROWS' => 3,'SQL_SMALL_RESULT' => 3, 'SSL' => 3,
+ 'STARTING' => 3, 'STATISTICS' => 3, 'STRAIGHT_JOIN' => 3,
+ 'STRIPED' => 3, 'SUCCESSFUL' => 3, 'SYNONYM' => 3,
+ 'SYSDATE' => 3, 'TABLES' => 3, 'TERMINATED' => 3,
+ 'TEXTSIZE' => 3, 'TINYBLOB' => 3, 'TINYINT' => 3,
+ 'TINYTEXT' => 3, 'TOP' => 3, 'TRAN' => 3,
+ 'TRUNCATE' => 3, 'TSEQUAL' => 3, 'TYPES' => 3,
+ 'UID' => 3, 'UNLOCK' => 3, 'UNSIGNED' => 3,
+ 'UPDATETEXT' => 3, 'USE' => 3, 'USER_RESOURCES' => 3,
+ 'VALIDATE' => 3, 'VARBINARY' => 3, 'VARCHAR2' => 3,
+ 'WAITFOR' => 3, 'WARNINGS' => 3, 'WRITETEXT' => 3,
+ 'XOR' => 3, 'YEAR_MONTH' => 3, 'ZEROFILL' => 3
+);
+
+
+ safe_query("drop table crash_me10 $drop_attr");
+
+ foreach my $keyword (sort {$a cmp $b} keys %reserved_words)
+ {
+ $keyword_type= $reserved_words{$keyword};
+
+ $prompt= "Keyword ".$keyword;
+ $config= "reserved_word_".$keywords_ext[$keyword_type]."_".lc($keyword);
+
+ report_fail($prompt,$config,
+ "create table crash_me10 ($keyword int not null)",
+ "drop table crash_me10 $drop_attr"
+ );
+ }
+}
#
# Do a query on a query package object.
@@ -2450,7 +3735,17 @@ sub report
print "$prompt: ";
if (!defined($limits{$limit}))
{
- save_config_data($limit,safe_query(\@queries) ? "yes" : "no",$prompt);
+ my $queries_result = safe_query(\@queries);
+ add_log($limit, $safe_query_log);
+ my $report_result;
+ if ( $queries_result) {
+ $report_result= "yes";
+ add_log($limit,"As far as all queries returned OK, result is YES");
+ } else {
+ $report_result= "no";
+ add_log($limit,"As far as some queries didnt return OK, result is NO");
+ }
+ save_config_data($limit,$report_result,$prompt);
}
print "$limits{$limit}\n";
return $limits{$limit} ne "no";
@@ -2462,7 +3757,17 @@ sub report_fail
print "$prompt: ";
if (!defined($limits{$limit}))
{
- save_config_data($limit,safe_query(\@queries) ? "no" : "yes",$prompt);
+ my $queries_result = safe_query(\@queries);
+ add_log($limit, $safe_query_log);
+ my $report_result;
+ if ( $queries_result) {
+ $report_result= "no";
+ add_log($limit,"As far as all queries returned OK, result is NO");
+ } else {
+ $report_result= "yes";
+ add_log($limit,"As far as some queries didnt return OK, result is YES");
+ }
+ save_config_data($limit,$report_result,$prompt);
}
print "$limits{$limit}\n";
return $limits{$limit} ne "no";
@@ -2478,10 +3783,11 @@ sub report_one
print "$prompt: ";
if (!defined($limits{$limit}))
{
+ save_incomplete($limit,$prompt);
$result="no";
foreach $query (@$queries)
{
- if (safe_query($query->[0]))
+ if (safe_query_l($limit,$query->[0]))
{
$result= $query->[1];
last;
@@ -2503,11 +3809,13 @@ sub report_result
print "$prompt: ";
if (!defined($limits{$limit}))
{
+ save_incomplete($limit,$prompt);
$error=safe_query_result($query,"1",2);
- save_config_data($limit,$error ? "not supported" : $last_result,$prompt);
+ add_log($limit,$safe_query_result_log);
+ save_config_data($limit,$error ? "not supported" :$last_result,$prompt);
}
print "$limits{$limit}\n";
- return $limits{$limit} ne "no";
+ return $limits{$limit} ne "not supported";
}
sub report_trans
@@ -2515,33 +3823,71 @@ sub report_trans
my ($limit,$queries,$check,$clear)=@_;
if (!defined($limits{$limit}))
{
+ save_incomplete($limit,$prompt);
eval {undef($dbh->{AutoCommit})};
if (!$@)
{
if (safe_query(\@$queries))
{
- $rc = $dbh->rollback;
- if ($rc) {
- $dbh->{AutoCommit} = 1;
+ $dbh->rollback;
+ $dbh->{AutoCommit} = 1;
if (safe_query_result($check,"","")) {
- save_config_data($limit,"yes",$prompt);
+ add_log($limit,$safe_query_result_log);
+ save_config_data($limit,"yes",$limit);
}
safe_query($clear);
- } else {
- $dbh->{AutoCommit} = 1;
- save_config_data($limit,"error",$prompt);
- }
} else {
- save_config_data($limit,"error",$prompt);
+ add_log($limit,$safe_query_log);
+ save_config_data($limit,"error",$limit);
}
$dbh->{AutoCommit} = 1;
}
else
{
- save_config_data($limit,"no",$prompt);
+ add_log($limit,"Couldnt undef autocommit ?? ");
+ save_config_data($limit,"no",$limit);
+ }
+ safe_query($clear);
+ }
+ return $limits{$limit} ne "yes";
+}
+
+sub report_rollback
+{
+ my ($limit,$queries,$check,$clear)=@_;
+ if (!defined($limits{$limit}))
+ {
+ save_incomplete($limit,$prompt);
+ eval {undef($dbh->{AutoCommit})};
+ if (!$@)
+ {
+ if (safe_query(\@$queries))
+ {
+ add_log($limit,$safe_query_log);
+
+ $dbh->rollback;
+ $dbh->{AutoCommit} = 1;
+ if (safe_query($check)) {
+ add_log($limit,$safe_query_log);
+ save_config_data($limit,"no",$limit);
+ } else {
+ add_log($limit,$safe_query_log);
+ save_config_data($limit,"yes",$limit);
+ };
+ safe_query($clear);
+ } else {
+ add_log($limit,$safe_query_log);
+ save_config_data($limit,"error",$limit);
+ }
+ }
+ else
+ {
+ add_log($limit,'Couldnt undef Autocommit??');
+ save_config_data($limit,"error",$limit);
}
safe_query($clear);
}
+ $dbh->{AutoCommit} = 1;
return $limits{$limit} ne "yes";
}
@@ -2556,9 +3902,17 @@ sub check_and_report
print "$prompt: " if (!defined($skip_prompt));
if (!defined($limits{$limit}))
{
+ save_incomplete($limit,$prompt);
$tmp=1-safe_query(\@$pre);
- $tmp=safe_query_result($query,$answer,$string_type) if (!$tmp);
+ add_log($limit,$safe_query_log);
+ if (!$tmp)
+ {
+ $tmp=safe_query_result($query,$answer,$string_type) ;
+ add_log($limit,$safe_query_result_log);
+ };
safe_query(\@$post);
+ add_log($limit,$safe_query_log);
+ delete $limits{$limit};
if ($function == 3) # Report error as 'no'.
{
$function=0;
@@ -2587,13 +3941,15 @@ sub try_and_report
my ($tmp,$test,$type);
print "$prompt: ";
+
if (!defined($limits{$limit}))
{
+ save_incomplete($limit,$prompt);
$type="no"; # Not supported
foreach $test (@tests)
{
my $tmp_type= shift(@$test);
- if (safe_query(\@$test))
+ if (safe_query_l($limit,\@$test))
{
$type=$tmp_type;
goto outer;
@@ -2612,32 +3968,49 @@ sub try_and_report
sub execute_and_check
{
- my ($pre,$query,$post,$answer,$string_type)=@_;
+ my ($key,$pre,$query,$post,$answer,$string_type)=@_;
my ($tmp);
- $tmp=safe_query(\@$pre);
- $tmp=safe_query_result($query,$answer,$string_type) == 0 if ($tmp);
- safe_query(\@$post);
+ $tmp=safe_query_l($key,\@$pre);
+
+ $tmp=safe_query_result_l($key,$query,$answer,$string_type) == 0 if ($tmp);
+ safe_query_l($key,\@$post);
return $tmp;
}
# returns 0 if ok, 1 if error, -1 if wrong answer
# Sets $last_result to value of query
+sub safe_query_result_l{
+ my ($key,$query,$answer,$result_type)=@_;
+ my $r = safe_query_result($query,$answer,$result_type);
+ add_log($key,$safe_query_result_log);
+ return $r;
+}
sub safe_query_result
{
+# result type can be
+# 8 (must be empty), 2 (Any value), 0 (number)
+# 1 (char, endspaces can differ), 3 (exact char), 4 (NULL)
+# 5 (char with prefix), 6 (exact, errors are ignored)
+# 7 (array of numbers)
my ($query,$answer,$result_type)=@_;
my ($sth,$row,$result,$retry);
undef($last_result);
-
+ $safe_query_result_log="";
+
printf "\nquery3: %-80.80s\n",$query if ($opt_log_all_queries);
print LOG "$query;\n" if ($opt_log);
+ $safe_query_result_log="<".$query."\n";
+
for ($retry=0; $retry < $retry_limit ; $retry++)
{
if (!($sth=$dbh->prepare($query)))
{
print_query($query);
+ $safe_query_result_log .= "> prepare failed:".$dbh->errstr."\n";
+
if ($server->abort_if_fatal_error())
{
check_connect(); # Check that server is still up
@@ -2649,6 +4022,7 @@ sub safe_query_result
if (!$sth->execute)
{
print_query($query);
+ $safe_query_result_log .= "> execute failed:".$dbh->errstr."\n";
if ($server->abort_if_fatal_error())
{
check_connect(); # Check that server is still up
@@ -2665,50 +4039,83 @@ sub safe_query_result
if (!($row=$sth->fetchrow_arrayref))
{
print "\nquery: $query didn't return any result\n" if ($opt_debug);
+ $safe_query_result_log .= "> didn't return any result:".$dbh->errstr."\n";
$sth->finish;
return ($result_type == 8) ? 0 : 1;
}
- if($result_type == 8) {
+ if ($result_type == 8)
+ {
$sth->finish;
return 1;
}
$result=0; # Ok
$last_result= $row->[0]; # Save for report_result;
+ $safe_query_result_log .= ">".$last_result."\n";
+ # Note:
+ # if ($result_type == 2) We accept any return value as answer
+
if ($result_type == 0) # Compare numbers
{
- $row->[0] =~ s/,/,/; # Fix if ',' is used instead of '.'
+ $row->[0] =~ s/,/./; # Fix if ',' is used instead of '.'
if ($row->[0] != $answer && (abs($row->[0]- $answer)/
(abs($row->[0]) + abs($answer))) > 0.01)
{
$result=-1;
+ $safe_query_result_log .=
+ "We expected '$answer' but got '$last_result' \n";
}
}
elsif ($result_type == 1) # Compare where end space may differ
{
$row->[0] =~ s/\s+$//;
- $result=-1 if ($row->[0] ne $answer);
+ if ($row->[0] ne $answer)
+ {
+ $result=-1;
+ $safe_query_result_log .=
+ "We expected '$answer' but got '$last_result' \n";
+ } ;
}
elsif ($result_type == 3) # This should be a exact match
{
- $result= -1 if ($row->[0] ne $answer);
+ if ($row->[0] ne $answer)
+ {
+ $result= -1;
+ $safe_query_result_log .=
+ "We expected '$answer' but got '$last_result' \n";
+ };
}
elsif ($result_type == 4) # If results should be NULL
{
- $result= -1 if (defined($row->[0]));
+ if (defined($row->[0]))
+ {
+ $result= -1;
+ $safe_query_result_log .=
+ "We expected NULL but got '$last_result' \n";
+ };
}
elsif ($result_type == 5) # Result should have given prefix
{
- $result= -1 if (length($row->[0]) < length($answer) &&
- substring($row->[0],1,length($answer)) ne $answer);
+ if (length($row->[0]) < length($answer) &&
+ substr($row->[0],1,length($answer)) ne $answer)
+ {
+ $result= -1 ;
+ $safe_query_result_log .=
+ "Result must have prefix '$answer', but '$last_result' \n";
+ };
}
elsif ($result_type == 6) # Exact match but ignore errors
{
- $result= 1 if ($row->[0] ne $answer);
+ if ($row->[0] ne $answer)
+ { $result= 1;
+ $safe_query_result_log .=
+ "We expected '$answer' but got '$last_result' \n";
+ } ;
}
elsif ($result_type == 7) # Compare against array of numbers
{
if ($row->[0] != $answer->[0])
{
+ $safe_query_result_log .= "must be '$answer->[0]' \n";
$result= -1;
}
else
@@ -2717,16 +4124,20 @@ sub safe_query_result
shift @$answer;
while (($row=$sth->fetchrow_arrayref))
{
+ $safe_query_result_log .= ">$row\n";
+
$value=shift(@$answer);
if (!defined($value))
{
print "\nquery: $query returned to many results\n"
if ($opt_debug);
+ $safe_query_result_log .= "It returned to many results \n";
$result= 1;
last;
}
if ($row->[0] != $value)
{
+ $safe_query_result_log .= "Must return $value here \n";
$result= -1;
last;
}
@@ -2735,6 +4146,7 @@ sub safe_query_result
{
print "\nquery: $query returned too few results\n"
if ($opt_debug);
+ $safe_query_result_log .= "It returned too few results \n";
$result= 1;
}
}
@@ -2747,22 +4159,45 @@ sub safe_query_result
#
# Find limit using binary search. This is a weighed binary search that
-# will prefere lower limits to get the server to crash as few times as possible
-#
+# will prefere lower limits to get the server to crash as
+# few times as possible
+
sub find_limit()
{
my ($prompt,$limit,$query)=@_;
- my ($first,$end,$i,$tmp);
+ my ($first,$end,$i,$tmp,@tmp_array, $queries);
print "$prompt: ";
if (defined($end=$limits{$limit}))
{
print "$end (cache)\n";
return $end;
}
+ save_incomplete($limit,$prompt);
+ add_log($limit,"We are trying (example with N=5):");
+ $queries = $query->query(5);
+ if (ref($queries) ne "ARRAY")
+ {
+ push(@tmp_array,$queries);
+ $queries= \@tmp_array;
+ }
+ foreach $tmp (@$queries)
+ { add_log($limit,repr_query($tmp)); }
+
+ if (defined($queries = $query->check_query()))
+ {
+ if (ref($queries) ne "ARRAY")
+ {
+ @tmp_array=();
+ push(@tmp_array,$queries);
+ $queries= \@tmp_array;
+ }
+ foreach $tmp (@$queries)
+ { add_log($limit,repr_query($tmp)); }
+ }
if (defined($query->{'init'}) && !defined($end=$limits{'restart'}{'tohigh'}))
{
- if (!safe_query($query->{'init'}))
+ if (!safe_query_l($limit,$query->{'init'}))
{
$query->cleanup();
return "error";
@@ -2771,7 +4206,8 @@ sub find_limit()
if (!limit_query($query,1)) # This must work
{
- print "\nMaybe fatal error: Can't check '$prompt' for limit=1\nerror: $last_error\n";
+ print "\nMaybe fatal error: Can't check '$prompt' for limit=1\n".
+ "error: $last_error\n";
return "error";
}
@@ -2790,7 +4226,7 @@ sub find_limit()
$end= $query->max_limit();
$i=int(($end+$first)/2);
}
-
+ my $log_str = "";
unless(limit_query($query,0+$end)) {
while ($first < $end)
{
@@ -2799,11 +4235,13 @@ sub find_limit()
if (limit_query($query,$i))
{
$first=$i;
+ $log_str .= " $i:OK";
$i=$first+int(($end-$first+1)/2); # to be a bit faster to go up
}
else
- {
+ {
$end=$i-1;
+ $log_str .= " $i:FAIL";
$i=$first+int(($end-$first+4)/5); # Prefere lower on errors
}
}
@@ -2815,6 +4253,7 @@ sub find_limit()
$end= $query->{'max_limit'};
}
print "$end\n";
+ add_log($limit,$log_str);
save_config_data($limit,$end,$prompt);
delete $limits{'restart'};
return $end;
@@ -2864,8 +4303,9 @@ sub read_config_data
{
if ($key !~ /restart/i)
{
- $limits{$key}=$limit;
+ $limits{$key}=$limit eq "null"? undef : $limit;
$prompts{$key}=length($prompt) ? substr($prompt,2) : "";
+ $last_read=$key;
delete $limits{'restart'};
}
else
@@ -2879,6 +4319,11 @@ sub read_config_data
}
}
}
+ elsif (/\s*###(.*)$/) # log line
+ {
+ # add log line for previously read key
+ $log{$last_read} .= "$1\n";
+ }
elsif (!/^\s*$/ && !/^\#/)
{
die "Wrong config row: $_\n";
@@ -2894,11 +4339,23 @@ sub save_config_data
return if (defined($limits{$key}) && $limits{$key} eq $limit);
if (!defined($limit) || $limit eq "")
{
- die "Undefined limit for $key\n";
+# die "Undefined limit for $key\n";
+ $limit = 'null';
}
print CONFIG_FILE "$key=$limit\t# $prompt\n";
$limits{$key}=$limit;
$limit_changed=1;
+# now write log lines (immediatelly after limits)
+ my $line;
+ my $last_line_was_empty=0;
+ foreach $line (split /\n/, $log{$key})
+ {
+ print CONFIG_FILE " ###$line\n"
+ unless ( ($last_line_was_empty eq 1)
+ && ($line =~ /^\s+$/) );
+ $last_line_was_empty= ($line =~ /^\s+$/)?1:0;
+ };
+
if (($opt_restart && $limits{'operating_system'} =~ /windows/i) ||
($limits{'operating_system'} =~ /NT/))
{
@@ -2909,6 +4366,12 @@ sub save_config_data
}
}
+sub add_log
+{
+ my $key = shift;
+ my $line = shift;
+ $log{$key} .= $line . "\n" if ($opt_verbose);;
+}
sub save_all_config_data
{
@@ -2922,16 +4385,35 @@ sub save_all_config_data
select STDOUT;
delete $limits{'restart'};
- print CONFIG_FILE "#This file is automaticly generated by crash-me $version\n\n";
+ print CONFIG_FILE
+ "#This file is automaticly generated by crash-me $version\n\n";
foreach $key (sort keys %limits)
{
$tmp="$key=$limits{$key}";
print CONFIG_FILE $tmp . ("\t" x (int((32-min(length($tmp),32)+7)/8)+1)) .
"# $prompts{$key}\n";
+ my $line;
+ my $last_line_was_empty=0;
+ foreach $line (split /\n/, $log{$key})
+ {
+ print CONFIG_FILE " ###$line\n" unless
+ ( ($last_line_was_empty eq 1) && ($line =~ /^\s*$/));
+ $last_line_was_empty= ($line =~ /^\s*$/)?1:0;
+ };
}
close CONFIG_FILE;
}
+#
+# Save 'incomplete' in the limits file to be able to continue if
+# crash-me dies because of a bug in perl/DBI
+
+sub save_incomplete
+{
+ my ($limit,$prompt)= @_;
+ save_config_data($limit,"incompleted",$prompt) if ($opt_restart);
+}
+
sub check_repeat
{
@@ -3195,7 +4677,6 @@ sub new
bless $self;
}
-
sub query
{
my ($self,$i)=@_;
@@ -3486,7 +4967,8 @@ sub query
$self->{'limit'}=$limit;
$res=$parts=$values="";
- $size=main::min($main::limits{'max_index_part_length'},$main::limits{'max_char_size'});
+ $size=main::min($main::limits{'max_index_part_length'},
+ $main::limits{'max_char_size'});
$size=1 if ($size == 0); # Avoid infinite loop errors
for ($length=$i=0; $length + $size <= $limit ; $length+=$size, $i++)
{
@@ -3538,5 +5020,6 @@ sub check_query
}
+
### TODO:
# OID test instead of / in addition to _rowid
diff --git a/sql-bench/innotest1.sh b/sql-bench/innotest1.sh
index b875a431040..8675de19ae4 100644
--- a/sql-bench/innotest1.sh
+++ b/sql-bench/innotest1.sh
@@ -5,12 +5,13 @@
#
############################################################################
+use Cwd;
use DBI;
use Benchmark;
$opt_loop_count = 100000;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
print "Innotest1: MySQL/InnoDB stress test in Perl\n";
diff --git a/sql-bench/innotest1a.sh b/sql-bench/innotest1a.sh
index d78357427bc..93f8a2a443b 100644
--- a/sql-bench/innotest1a.sh
+++ b/sql-bench/innotest1a.sh
@@ -5,12 +5,13 @@
#
############################################################################
+use Cwd;
use DBI;
use Benchmark;
$opt_loop_count = 200000;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
print "Innotest1a: MySQL/InnoDB stress test in Perl\n";
diff --git a/sql-bench/innotest1b.sh b/sql-bench/innotest1b.sh
index d83fce00efc..48fe96ebe7d 100644
--- a/sql-bench/innotest1b.sh
+++ b/sql-bench/innotest1b.sh
@@ -5,12 +5,13 @@
#
############################################################################
+use Cwd;
use DBI;
use Benchmark;
$opt_loop_count = 200000;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
print "Innotest1b: MySQL/InnoDB stress test in Perl\n";
diff --git a/sql-bench/innotest2.sh b/sql-bench/innotest2.sh
index 05c21098249..aea44003903 100644
--- a/sql-bench/innotest2.sh
+++ b/sql-bench/innotest2.sh
@@ -5,12 +5,13 @@
#
############################################################################
+use Cwd;
use DBI;
use Benchmark;
$opt_loop_count = 100000;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
print "Innotest2: MySQL/InnoDB stress test in Perl for FOREIGN keys\n";
diff --git a/sql-bench/innotest2a.sh b/sql-bench/innotest2a.sh
index e0fe2001d24..3d4bb9933da 100644
--- a/sql-bench/innotest2a.sh
+++ b/sql-bench/innotest2a.sh
@@ -5,12 +5,13 @@
#
############################################################################
+use Cwd;
use DBI;
use Benchmark;
$opt_loop_count = 100000;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
print "Innotest2a: MySQL/InnoDB stress test in Perl for FOREIGN keys\n";
diff --git a/sql-bench/innotest2b.sh b/sql-bench/innotest2b.sh
index 83f48cf5352..272b6dcffd0 100644
--- a/sql-bench/innotest2b.sh
+++ b/sql-bench/innotest2b.sh
@@ -5,12 +5,13 @@
#
############################################################################
+use Cwd;
use DBI;
use Benchmark;
$opt_loop_count = 100000;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
print "Innotest2b: MySQL/InnoDB stress test in Perl for FOREIGN keys\n";
diff --git a/sql-bench/limits/db2.cfg b/sql-bench/limits/db2.cfg
index 31280fbe643..5b2c0e172e7 100644
--- a/sql-bench/limits/db2.cfg
+++ b/sql-bench/limits/db2.cfg
@@ -1,34 +1,68 @@
-#This file is automaticly generated by crash-me 1.19a
+#This file is automaticly generated by crash-me 1.57
NEG=yes # update of column= -column
+Need_cast_for_null=no # Need to cast NULL for arithmetic
alter_add_col=yes # Alter table add column
+alter_add_constraint=yes # Alter table add constraint
+alter_add_foreign_key=yes # Alter table add foreign key
+alter_add_multi_col=no # Alter table add many columns
+alter_add_primary_key=with constraint # Alter table add primary key
+alter_add_unique=no # Alter table add unique
+alter_alter_col=no # Alter table alter column default
alter_change_col=no # Alter table change column
alter_drop_col=no # Alter table drop column
+alter_drop_constraint=yes # Alter table drop constraint
+alter_drop_foreign_key=with drop constraint # Alter table drop foreign key
+alter_drop_primary_key=drop primary key # Alter table drop primary key
+alter_drop_unique=no # Alter table drop unique
alter_modify_col=no # Alter table modify column
alter_rename_table=no # Alter table rename table
atomic_updates=yes # atomic updates
atomic_updates_with_rollback=yes # atomic_updates_with_rollback
-binary_items=no # binary items (0x41)
-case_insensitive_strings=no # case insensitive compare
-char_is_space_filled=no # char are space filled
+automatic_rowid=no # Automatic row id
+binary_numbers=no # binary numbers (0b1001)
+binary_strings=no # binary strings (b'0110')
+case_insensitive_strings=no # Case insensitive compare
+char_is_space_filled=yes # char are space filled
column_alias=yes # Column alias
+columns_in_group_by=+64 # number of columns in group by
+columns_in_order_by=+64 # number of columns in order by
comment_#=no # # as comment
-comment_--=yes # -- as comment
+comment_--=yes # -- as comment (ANSI)
comment_/**/=no # /* */ as comment
+comment_//=no # // as comment
compute=no # Compute
-connections=125 # Simultaneous connections
+connections=40 # Simultaneous connections (installation default)
+constraint_check=yes # Column constraints
+constraint_check_table=yes # Table constraints
+constraint_null=no # NULL constraint (SyBase style)
crash_me_safe=no # crash me safe
-crash_me_version=1.19a # crash me version
+crash_me_version=1.57 # crash me version
create_default=yes # default value for column
+create_default_func=no # default value function for column
+create_if_not_exists=no # create table if not exists
create_index=yes # create index
+create_schema=no # Create SCHEMA
+create_table_select=no # create table from select
cross_join=no # cross join (same as from a,b)
date_as_string=no # String functions on date columns
+date_infinity=no # Supports 'infinity dates
+date_last=no # Supports 9999-12-31 dates
+date_one=no # Supports 0001-01-01 dates
date_with_YY=no # Supports YY-MM-DD dates
date_zero=no # Supports 0000-00-00 dates
+domains=no # Domains (ANSI SQL)
+dont_require_cast_to_float=yes # No need to cast from integer to float
double_quotes=yes # Double '' as ' in strings
+drop_if_exists=no # drop table if exists
drop_index=yes # drop index
+drop_requires_cascade=no # drop table require cascade/restrict
+drop_restrict=no # drop table with cascade/restrict
+end_colon=yes # allows end ';'
except=yes # except
except_all=yes # except all
+except_all_incompat=no # except all (incompatible lists)
+except_incompat=no # except (incompatible lists)
float_int_expr=yes # mixing of integer and float in expression
foreign_key=yes # foreign keys
foreign_key_syntax=yes # foreign key syntax
@@ -41,6 +75,8 @@ func_extra_<>=no # Function <> in SELECT
func_extra_==no # Function =
func_extra_add_months=no # Function ADD_MONTHS
func_extra_and_or=no # Function AND and OR in SELECT
+func_extra_ascii_char=no # Function ASCII_CHAR
+func_extra_ascii_code=no # Function ASCII_CODE
func_extra_atn2=no # Function ATN2
func_extra_auto_num2string=no # Function automatic num->string convert
func_extra_auto_string2num=no # Function automatic string->num convert
@@ -72,6 +108,7 @@ func_extra_in_num=no # Function IN on numbers in SELECT
func_extra_in_str=no # Function IN on strings in SELECT
func_extra_initcap=no # Function INITCAP
func_extra_instr=no # Function LOCATE as INSTR
+func_extra_instr_oracle=no # Function INSTR (Oracle syntax)
func_extra_instrb=no # Function INSTRB
func_extra_interval=no # Function INTERVAL
func_extra_last_day=no # Function LAST_DAY
@@ -84,16 +121,15 @@ func_extra_ln=yes # Function LN
func_extra_log(m_n)=no # Function LOG(m,n)
func_extra_logn=no # Function LOGN
func_extra_lpad=no # Function LPAD
-func_extra_max_num=no # Function MAX on numbers
func_extra_mdy=no # Function MDY
func_extra_mid=no # Function SUBSTRING as MID
-func_extra_min_num=no # Function MIN on numbers
func_extra_months_between=no # Function MONTHS_BETWEEN
func_extra_not=no # Function NOT in SELECT
func_extra_not_between=no # Function NOT BETWEEN in SELECT
func_extra_not_like=no # Function NOT LIKE in SELECT
func_extra_odbc_convert=no # Function ODBC CONVERT
func_extra_password=no # Function PASSWORD
+func_extra_paste=no # Function PASTE
func_extra_patindex=no # Function PATINDEX
func_extra_period_add=no # Function PERIOD_ADD
func_extra_period_diff=no # Function PERIOD_DIFF
@@ -112,6 +148,8 @@ func_extra_strcmp=no # Function STRCMP
func_extra_stuff=no # Function STUFF
func_extra_substrb=no # Function SUBSTRB
func_extra_substring_index=no # Function SUBSTRING_INDEX
+func_extra_sysdate=no # Function SYSDATE
+func_extra_tail=no # Function TAIL
func_extra_tanh=no # Function TANH
func_extra_time_to_sec=no # Function TIME_TO_SEC
func_extra_to_days=no # Function TO_DAYS
@@ -126,6 +164,7 @@ func_extra_version=no # Function VERSION
func_extra_weekday=no # Function WEEKDAY
func_extra_|=no # Function | (bitwise or)
func_extra_||=no # Function OR as '||'
+func_extra_~*=no # Function ~* (case insensitive compare)
func_odbc_abs=yes # Function ABS
func_odbc_acos=yes # Function ACOS
func_odbc_ascii=yes # Function ASCII
@@ -133,31 +172,30 @@ func_odbc_asin=yes # Function ASIN
func_odbc_atan=yes # Function ATAN
func_odbc_atan2=error # Function ATAN2
func_odbc_ceiling=yes # Function CEILING
-func_odbc_char=error # Function CHAR
+func_odbc_char=yes # Function CHAR
func_odbc_concat=yes # Function CONCAT(2 arg)
func_odbc_cos=yes # Function COS
func_odbc_cot=yes # Function COT
-func_odbc_curdate=no # Function CURDATE
-func_odbc_curtime=no # Function CURTIME
-func_odbc_database=no # Function DATABASE
-func_odbc_dayname=no # Function DAYNAME
-func_odbc_dayofmonth=no # Function DAYOFMONTH
-func_odbc_dayofweek=no # Function DAYOFWEEK
-func_odbc_dayofyear=no # Function DAYOFYEAR
+func_odbc_curdate=yes # Function CURDATE
+func_odbc_curtime=yes # Function CURTIME
+func_odbc_database=yes # Function DATABASE
+func_odbc_dayname=yes # Function DAYNAME
+func_odbc_dayofmonth=yes # Function DAYOFMONTH
+func_odbc_dayofweek=yes # Function DAYOFWEEK
+func_odbc_dayofyear=yes # Function DAYOFYEAR
func_odbc_degrees=yes # Function DEGREES
func_odbc_difference=yes # Function DIFFERENCE()
func_odbc_exp=yes # Function EXP
-func_odbc_extract=no # Function EXTRACT
func_odbc_floor=yes # Function FLOOR
func_odbc_fn_left=yes # Function ODBC syntax LEFT & RIGHT
func_odbc_hour=yes # Function HOUR
-func_odbc_hour_time=no # Function ANSI HOUR
-func_odbc_ifnull=no # Function IFNULL
+func_odbc_hour_time=yes # Function ANSI HOUR
+func_odbc_ifnull=yes # Function IFNULL
func_odbc_insert=yes # Function INSERT
func_odbc_lcase=yes # Function LCASE
func_odbc_left=yes # Function LEFT
func_odbc_length=yes # Function REAL LENGTH
-func_odbc_length_without_space=error # Function ODBC LENGTH
+func_odbc_length_without_space=yes # Function ODBC LENGTH
func_odbc_locate_2=yes # Function LOCATE(2 arg)
func_odbc_locate_3=yes # Function LOCATE(3 arg)
func_odbc_log=yes # Function LOG
@@ -165,12 +203,12 @@ func_odbc_log10=yes # Function LOG10
func_odbc_ltrim=yes # Function LTRIM
func_odbc_minute=yes # Function MINUTE
func_odbc_mod=yes # Function MOD
-func_odbc_month=no # Function MONTH
-func_odbc_monthname=no # Function MONTHNAME
-func_odbc_now=no # Function NOW
-func_odbc_pi=no # Function PI
+func_odbc_month=yes # Function MONTH
+func_odbc_monthname=yes # Function MONTHNAME
+func_odbc_now=yes # Function NOW
+func_odbc_pi=yes # Function PI
func_odbc_power=yes # Function POWER
-func_odbc_quarter=no # Function QUARTER
+func_odbc_quarter=yes # Function QUARTER
func_odbc_radians=yes # Function RADIANS
func_odbc_rand=yes # Function RAND
func_odbc_repeat=yes # Function REPEAT
@@ -184,38 +222,43 @@ func_odbc_sin=yes # Function SIN
func_odbc_soundex=yes # Function SOUNDEX
func_odbc_space=yes # Function SPACE
func_odbc_sqrt=yes # Function SQRT
-func_odbc_substring=no # Function ODBC SUBSTRING
+func_odbc_substring=yes # Function ODBC SUBSTRING
func_odbc_tan=yes # Function TAN
func_odbc_timestampadd=no # Function TIMESTAMPADD
func_odbc_timestampdiff=no # Function TIMESTAMPDIFF
func_odbc_truncate=yes # Function TRUNCATE
-func_odbc_ucase=no # Function UCASE
-func_odbc_user=yes # Function USER
-func_odbc_user()=no # Function USER()
-func_odbc_week=no # Function WEEK
-func_odbc_year=no # Function YEAR
+func_odbc_ucase=yes # Function UCASE
+func_odbc_user()=yes # Function USER()
+func_odbc_week=yes # Function WEEK
+func_odbc_year=yes # Function YEAR
func_sql_+=yes # Function +, -, * and /
func_sql_bit_length=no # Function BIT_LENGTH
-func_sql_case=yes # Function CASE
func_sql_cast=yes # Function CAST
func_sql_char_length=no # Function CHAR_LENGTH
+func_sql_char_length(constant)=no # Function CHAR_LENGTH(constant)
func_sql_character_length=no # Function CHARACTER_LENGTH
+func_sql_coalesce=no # Function COALESCE
func_sql_concat_as_||=yes # Function concatenation with ||
func_sql_current_date=no # Function CURRENT_DATE
-func_sql_current_date()=no # Function CURRENT_DATE()
func_sql_current_time=no # Function CURRENT_TIME
-func_sql_current_time()=no # Function CURRENT_TIME()
func_sql_current_timestamp=no # Function CURRENT_TIMESTAMP
-func_sql_current_timestamp()=no # Function CURRENT_TIMESTAMP()
-func_sql_lower=no # Function LOWER
+func_sql_current_user=no # Function CURRENT_USER
+func_sql_extract_sql=no # Function EXTRACT
+func_sql_localtime=no # Function LOCALTIME
+func_sql_localtimestamp=no # Function LOCALTIMESTAMP
+func_sql_lower=yes # Function LOWER
+func_sql_nullif_num=yes # Function NULLIF with numbers
+func_sql_nullif_string=yes # Function NULLIF with strings
func_sql_octet_length=no # Function OCTET_LENGTH
func_sql_position=no # Function POSITION
+func_sql_searched_case=yes # Function searched CASE
func_sql_session_user=no # Function SESSION_USER
+func_sql_simple_case=yes # Function simple CASE
func_sql_substring=no # Function ANSI SQL SUBSTRING
-func_extra_sysdate=no # Function SYSDATE
func_sql_system_user=no # Function SYSTEM_USER
func_sql_trim=no # Function TRIM
-func_sql_upper=no # Function UPPER
+func_sql_upper=yes # Function UPPER
+func_sql_user=yes # Function USER
func_where_between=yes # Function BETWEEN
func_where_eq_all=yes # Function = ALL
func_where_eq_any=yes # Function = ANY
@@ -235,36 +278,49 @@ func_where_unique=no # Function UNIQUE
functions=yes # Functions
group_by=yes # Group by
group_by_alias=no # Group by alias
-group_by_null=yes # Test nulls in group by
+group_by_null=yes # Group on column with null values
group_by_position=no # Group by position
group_distinct_functions=yes # Group functions with distinct
group_func_extra_bit_and=no # Group function BIT_AND
group_func_extra_bit_or=no # Group function BIT_OR
+group_func_extra_count_distinct_list=no # Group function COUNT(DISTINCT expr,expr,...)
group_func_extra_std=no # Group function STD
group_func_extra_stddev=yes # Group function STDDEV
group_func_extra_variance=yes # Group function VARIANCE
+group_func_sql_any=no # Group function ANY
group_func_sql_avg=yes # Group function AVG
group_func_sql_count_*=yes # Group function COUNT (*)
group_func_sql_count_column=yes # Group function COUNT column name
-group_func_sql_count_distinct=yes # Group function COUNT DISTINCT column name
+group_func_sql_count_distinct=yes # Group function COUNT(DISTINCT expr)
+group_func_sql_every=no # Group function EVERY
group_func_sql_max=yes # Group function MAX on numbers
group_func_sql_max_str=yes # Group function MAX on strings
group_func_sql_min=yes # Group function MIN on numbers
group_func_sql_min_str=yes # Group function MIN on strings
+group_func_sql_some=no # Group function SOME
group_func_sql_sum=yes # Group function SUM
group_functions=yes # Group functions
+group_on_unused=yes # Group on unused column
+has_true_false=no # TRUE and FALSE
having=yes # Having
having_with_alias=no # Having on alias
having_with_group=yes # Having with group function
-ignore_end_space=yes # ignore end space in compare
+hex_numbers=no # hex numbers (0x41)
+hex_strings=yes # hex strings (x'1ace')
+ignore_end_space=yes # Ignore end space in compare
index_in_create=no # index in create table
index_namespace=no # different namespace for index
index_parts=no # index on column part (extension)
+inner_join=yes # inner join
insert_empty_string=yes # insert empty string
+insert_multi_value=yes # INSERT with Value lists
insert_select=yes # insert INTO ... SELECT ...
+insert_with_set=no # INSERT with set syntax
intersect=yes # intersect
intersect_all=yes # intersect all
-join_tables=+64 # tables in join
+intersect_all_incompat=no # intersect all (incompatible lists)
+intersect_incompat=no # intersect (incompatible lists)
+join_tables=10 # tables in join
left_outer_join=yes # left outer join
left_outer_join_using=no # left outer join using
like_with_column=no # column LIKE column
@@ -273,150 +329,194 @@ lock_tables=yes # lock table
logical_value=not supported # Value of logical operation (1=1)
max_big_expressions=1 # big expressions
max_char_size=254 # max char() size
-max_column_name=18 # column name length
+max_column_name=30 # column name length
max_columns=500 # Columns in table
-max_conditions=418 # OR and AND in WHERE
-max_expressions=9820 # simple expressions
+max_conditions=2082 # OR and AND in WHERE
+max_expressions=9543 # simple expressions
max_index=+64 # max index
-max_index_length=255 # index length
+max_index_length=1024 # index length
max_index_name=18 # index name length
max_index_part_length=254 # max index part length
-max_index_parts=15 # index parts
-max_index_varchar_part_length=251 # index varchar part length
+max_index_parts=16 # index parts
+max_index_varchar_part_length=255 # index varchar part length
max_row_length=4005 # max table row length (without blobs)
max_row_length_with_null=3989 # table row length with nulls (without blobs)
-max_select_alias_name=18 # select alias name length
+max_select_alias_name=30 # select alias name length
max_stack_expression=1363 # stacked expressions
-max_table_alias_name=18 # table alias name length
-max_table_name=18 # table name length
+max_table_alias_name=128 # table alias name length
+max_table_name=128 # table name length
max_unique_index=+64 # unique indexes
max_varchar_size=4000 # max varchar() size
minus=no # minus
+minus_incompat=no # minus (incompatible lists)
minus_neg=no # Calculate 1--1
multi_drop=no # many tables to drop table
multi_strings=no # Multiple line strings
multi_table_delete=no # DELETE FROM table1,table2...
multi_table_update=no # Update with many tables
natural_join=no # natural join
+natural_join_incompat=no # natural join (incompatible lists)
natural_left_outer_join=no # natural left outer join
no_primary_key=yes # Tables without primary key
null_concat_expr=no # Is 'a' || NULL = NULL
null_in_index=yes # null in index
-null_in_unique=no # null in unique
+null_in_unique=no # null in unique index
null_num_expr=no # Is 1+NULL = NULL
+nulls_in_unique=no # null combination in unique index
odbc_left_outer_join=yes # left outer join odbc style
-operating_system=Windows NT Version 4.0 # crash-me tested on
+operating_system=Linux 2.4.4-64GB-SMP i686 # crash-me tested on
order_by=yes # Order by
order_by_alias=yes # Order by alias
+order_by_function=yes # Order by function
order_by_position=yes # Order by position
+order_by_remember_desc=no # Order by DESC is remembered
+order_on_unused=yes # Order by on unused column
primary_key_in_create=yes # primary key in create table
-query_size=19662 # query size
+psm_functions=no # PSM functions (ANSI SQL)
+psm_modules=no # PSM modules (ANSI SQL)
+psm_procedures=no # PSM procedures (ANSI SQL)
+psm_trigger=no # Triggers (ANSI SQL)
+query_size=65535 # query size
+quote_ident_with_"=yes # " as identifier quote (ANSI SQL)
+quote_ident_with_[=no # [] as identifier quote
+quote_ident_with_`=no # ` as identifier quote
quote_with_"=no # Allows ' and " as string markers
-recursive_subqueries=22 # recursive subqueries
+recursive_subqueries=8 # recursive subqueries
remember_end_space=no # Remembers end space in char()
remember_end_space_varchar=yes # Remembers end space in varchar()
+rename_table=yes # rename table
repeat_string_size=4000 # return string size from function
right_outer_join=yes # right outer join
+rowid=no # Type for row id
select_constants=yes # Select constants
-select_string_size=4000 # constant string size in SELECT
+select_limit=no # LIMIT number of rows
+select_limit2=no # SELECT with LIMIT #,#
+select_string_size=32672 # constant string size in SELECT
select_table_update=yes # Update with sub select
select_without_from=no # SELECT without FROM
-server_version=IBM DB2 5 # server version
+server_version=IBM DB2 7.2 # server version
simple_joins=yes # ANSI SQL simple joins
+storage_of_float=truncate # Storage of float values
subqueries=yes # subqueries
table_alias=yes # Table alias
+table_name_case=yes # case independent table names
table_wildcard=yes # Select table_name.*
-transactions=yes # transactions
+temporary_table=no # temporary tables
+transactions=yes # constant string size in where
+truncate_table=no # truncate
type_extra_abstime=no # Type abstime
type_extra_bfile=no # Type bfile
type_extra_blob=no # Type blob
type_extra_bool=no # Type bool
type_extra_box=no # Type box
type_extra_byte=no # Type byte
-type_extra_char(1_arg)_binary=no # Type char(1 arg) binary
-type_extra_char16=no # Type char16
-type_extra_char2=no # Type char2
-type_extra_char4=no # Type char4
-type_extra_char8=no # Type char8
+type_extra_char(1_arg)_binary=no # Type char(1 arg) binary
+type_extra_cidr=no # Type cidr
type_extra_circle=no # Type circle
type_extra_clob=no # Type clob
type_extra_datetime=no # Type datetime
-type_extra_enum(1_arg)=no # Type enum(1 arg)
-type_sql_float(1_arg)=yes # Type float(1 arg)
+type_extra_double=yes # Type double
+type_extra_enum(1_arg)=no # Type enum(1 arg)
+type_extra_float(2_arg)=no # Type float(2 arg)
type_extra_float4=no # Type float4
type_extra_float8=no # Type float8
type_extra_image=no # Type image
-type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
+type_extra_inet=no # Type inet
+type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
type_extra_int1=no # Type int1
type_extra_int2=no # Type int2
type_extra_int3=no # Type int3
type_extra_int4=no # Type int4
type_extra_int8=no # Type int8
type_extra_int_auto_increment=no # Type int not null auto_increment
+type_extra_int_identity=no # Type int not null identity
+type_extra_int_unsigned=no # Type int unsigned
+type_extra_interval=no # Type interval
type_extra_line=no # Type line
type_extra_long=no # Type long
type_extra_long_raw=no # Type long raw
type_extra_long_varbinary=no # Type long varbinary
-type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
+type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
type_extra_lseg=no # Type lseg
+type_extra_macaddr=no # Type macaddr
type_extra_mediumint=no # Type mediumint
type_extra_mediumtext=no # Type mediumtext
type_extra_middleint=no # Type middleint
type_extra_mlslabel=no # Type mlslabel
type_extra_money=no # Type money
-type_sql_nchar(1_arg)=no # Type nchar(1 arg)
type_extra_nclob=no # Type nclob
type_extra_number=no # Type number
-type_extra_number(1_arg)=no # Type number(1 arg)
-type_extra_nvarchar(2_arg)=no # Type nvarchar(2 arg)
+type_extra_number(1_arg)=no # Type number(1 arg)
+type_extra_number(2_arg)=no # Type number(2 arg)
type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg)
type_extra_path=no # Type path
type_extra_point=no # Type point
type_extra_polygon=no # Type polygon
-type_extra_raw(1_arg)=no # Type raw(1 arg)
+type_extra_raw(1_arg)=no # Type raw(1 arg)
type_extra_reltime=no # Type reltime
type_extra_rowid=no # Type rowid
type_extra_serial=no # Type serial
-type_extra_set(1_arg)=no # Type set(1 arg)
+type_extra_set(1_arg)=no # Type set(1 arg)
type_extra_smalldatetime=no # Type smalldatetime
type_extra_smallfloat=no # Type smallfloat
type_extra_smallmoney=no # Type smallmoney
type_extra_text=no # Type text
-type_extra_text(1_arg)=no # Type text(1 arg)
+type_extra_text(1_arg)=no # Type text(1 arg)
type_extra_timespan=no # Type timespan
+type_extra_uint=no # Type uint
type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
type_extra_year=no # Type year
-type_odbc_bigint=no # Type bigint
-type_odbc_binary(1_arg)=no # Type binary(1 arg)
+type_odbc_bigint=yes # Type bigint
+type_odbc_binary(1_arg)=no # Type binary(1 arg)
type_odbc_datetime=no # Type datetime
-type_sql_smallint=yes # Type smallint
type_odbc_tinyint=no # Type tinyint
type_odbc_varbinary(1_arg)=no # Type varbinary(1 arg)
type_sql_bit=no # Type bit
type_sql_bit(1_arg)=no # Type bit(1 arg)
type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg)
-type_sql_char(1_arg)=yes # Type char(1 arg)
-type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
+type_sql_boolean=no # Type boolean
+type_sql_char(1_arg)=yes # Type char(1 arg)
+type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
type_sql_character(1_arg)=yes # Type character(1 arg)
type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
type_sql_date=yes # Type date
type_sql_dec(2_arg)=yes # Type dec(2 arg)
-type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
-type_extra_double=yes # Type double
+type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
type_sql_double_precision=yes # Type double precision
type_sql_float=yes # Type float
-type_extra_float(2_arg)=no # Type float(1 arg)
+type_sql_float(1_arg)=yes # Type float(1 arg)
type_sql_int=yes # Type int
type_sql_integer=yes # Type integer
+type_sql_interval_day=no # Type interval day
+type_sql_interval_day_to_hour=no # Type interval day to hour
+type_sql_interval_day_to_minute=no # Type interval day to minute
+type_sql_interval_day_to_second=no # Type interval day to second
+type_sql_interval_hour=no # Type interval hour
+type_sql_interval_hour_to_minute=no # Type interval hour to minute
+type_sql_interval_hour_to_second=no # Type interval hour to second
+type_sql_interval_minute=no # Type interval minute
+type_sql_interval_minute_to_second=no # Type interval minute to second
+type_sql_interval_month=no # Type interval month
+type_sql_interval_second=no # Type interval second
type_sql_interval_year=no # Type interval year
-type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
+type_sql_interval_year_to_month=no # Type interval year to month
+type_sql_national_char_varying(1_arg)=no # Type national char varying(1 arg)
+type_sql_national_character(1_arg)=no # Type national character(1 arg)
+type_sql_national_character_varying(1_arg)=no # Type national character varying(1 arg)
+type_sql_nchar(1_arg)=no # Type nchar(1 arg)
+type_sql_nchar_varying(1_arg)=no # Type nchar varying(1 arg)
+type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
type_sql_real=yes # Type real
+type_sql_smallint=yes # Type smallint
type_sql_time=yes # Type time
type_sql_timestamp=yes # Type timestamp
-type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
+type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
+type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
union=yes # union
union_all=yes # union all
+union_all_incompat=yes # union all (incompatible lists)
+union_incompat=yes # union (incompatible lists)
unique_in_create=yes # unique in create table
unique_null_in_create=no # unique null in create
views=yes # views
-where_string_size=4000 # constant string size in where
+where_string_size=32672 # constant string size in where
diff --git a/sql-bench/limits/interbase-dialect1.cfg b/sql-bench/limits/interbase-dialect1.cfg
new file mode 100644
index 00000000000..046627be513
--- /dev/null
+++ b/sql-bench/limits/interbase-dialect1.cfg
@@ -0,0 +1,514 @@
+#This file is automaticly generated by crash-me 1.57
+
+NEG=no # update of column= -column
+Need_cast_for_null=no # Need to cast NULL for arithmetic
+alter_add_col=yes # Alter table add column
+alter_add_constraint=yes # Alter table add constraint
+alter_add_foreign_key=yes # Alter table add foreign key
+alter_add_multi_col=with add # Alter table add many columns
+alter_add_primary_key=with constraint # Alter table add primary key
+alter_add_unique=no # Alter table add unique
+alter_alter_col=no # Alter table alter column default
+alter_change_col=no # Alter table change column
+alter_drop_col=no # Alter table drop column
+alter_drop_constraint=yes # Alter table drop constraint
+alter_drop_foreign_key=with drop constraint # Alter table drop foreign key
+alter_drop_primary_key=no # Alter table drop primary key
+alter_drop_unique=no # Alter table drop unique
+alter_modify_col=no # Alter table modify column
+alter_rename_table=no # Alter table rename table
+atomic_updates=no # atomic updates
+automatic_rowid=no # Automatic row id
+binary_numbers=yes # binary numbers (0b1001)
+binary_strings=no # binary strings (b'0110')
+case_insensitive_strings=no # Case insensitive compare
+char_is_space_filled=yes # char are space filled
+column_alias=yes # Column alias
+columns_in_order_by=37 # number of columns in order by
+comment_#=no # # as comment
+comment_--=no # -- as comment (ANSI)
+comment_/**/=yes # /* */ as comment
+comment_//=no # // as comment
+compute=no # Compute
+connections=1000 # Simultaneous connections (installation default)
+constraint_check=no # Column constraints
+constraint_check_table=no # Table constraints
+constraint_null=no # NULL constraint (SyBase style)
+crash_me_safe=yes # crash me safe
+crash_me_version=1.57 # crash me version
+create_default=yes # default value for column
+create_default_func=no # default value function for column
+create_if_not_exists=no # create table if not exists
+create_index=yes # create index
+create_schema=no # Create SCHEMA
+create_table_select=no # create table from select
+cross_join=no # cross join (same as from a,b)
+date_infinity=no # Supports 'infinity dates
+date_last=no # Supports 9999-12-31 dates
+date_one=no # Supports 0001-01-01 dates
+date_with_YY=no # Supports YY-MM-DD dates
+date_zero=no # Supports 0000-00-00 dates
+domains=no # Domains (ANSI SQL)
+double_quotes=yes # Double '' as ' in strings
+drop_if_exists=no # drop table if exists
+drop_index=yes # drop index
+drop_requires_cascade=no # drop table require cascade/restrict
+drop_restrict=no # drop table with cascade/restrict
+end_colon=yes # allows end ';'
+except=no # except
+except_all=no # except all
+except_all_incompat=no # except all (incompatible lists)
+except_incompat=no # except (incompatible lists)
+float_int_expr=yes # mixing of integer and float in expression
+foreign_key_syntax=no # foreign key syntax
+full_outer_join=yes # full outer join
+func_extra_!=no # Function NOT as '!' in SELECT
+func_extra_%=no # Function MOD as %
+func_extra_&=no # Function & (bitwise and)
+func_extra_&&=no # Function AND as '&&'
+func_extra_<>=no # Function <> in SELECT
+func_extra_==no # Function =
+func_extra_add_months=no # Function ADD_MONTHS
+func_extra_and_or=no # Function AND and OR in SELECT
+func_extra_ascii_char=no # Function ASCII_CHAR
+func_extra_ascii_code=no # Function ASCII_CODE
+func_extra_atn2=no # Function ATN2
+func_extra_auto_num2string=no # Function automatic num->string convert
+func_extra_auto_string2num=no # Function automatic string->num convert
+func_extra_between=no # Function BETWEEN in SELECT
+func_extra_binary_shifts=no # Function << and >> (bitwise shifts)
+func_extra_bit_count=no # Function BIT_COUNT
+func_extra_ceil=no # Function CEIL
+func_extra_charindex=no # Function CHARINDEX
+func_extra_chr=no # Function CHR
+func_extra_concat_as_+=no # Function concatenation with +
+func_extra_concat_list=no # Function CONCAT(list)
+func_extra_convert=no # Function CONVERT
+func_extra_cosh=no # Function COSH
+func_extra_date_format=no # Function DATE_FORMAT
+func_extra_dateadd=no # Function DATEADD
+func_extra_datediff=no # Function DATEDIFF
+func_extra_datename=no # Function DATENAME
+func_extra_datepart=no # Function DATEPART
+func_extra_elt=no # Function ELT
+func_extra_encrypt=no # Function ENCRYPT
+func_extra_field=no # Function FIELD
+func_extra_format=no # Function FORMAT
+func_extra_from_days=no # Function FROM_DAYS
+func_extra_from_unixtime=no # Function FROM_UNIXTIME
+func_extra_getdate=no # Function GETDATE
+func_extra_greatest=no # Function GREATEST
+func_extra_if=no # Function IF
+func_extra_in_num=no # Function IN on numbers in SELECT
+func_extra_in_str=no # Function IN on strings in SELECT
+func_extra_initcap=no # Function INITCAP
+func_extra_instr=no # Function LOCATE as INSTR
+func_extra_instr_oracle=no # Function INSTR (Oracle syntax)
+func_extra_instrb=no # Function INSTRB
+func_extra_interval=no # Function INTERVAL
+func_extra_last_day=no # Function LAST_DAY
+func_extra_last_insert_id=no # Function LAST_INSERT_ID
+func_extra_least=no # Function LEAST
+func_extra_lengthb=no # Function LENGTHB
+func_extra_like=no # Function LIKE in SELECT
+func_extra_like_escape=no # Function LIKE ESCAPE in SELECT
+func_extra_ln=no # Function LN
+func_extra_log(m_n)=no # Function LOG(m,n)
+func_extra_logn=no # Function LOGN
+func_extra_lpad=no # Function LPAD
+func_extra_mdy=no # Function MDY
+func_extra_mid=no # Function SUBSTRING as MID
+func_extra_months_between=no # Function MONTHS_BETWEEN
+func_extra_not=no # Function NOT in SELECT
+func_extra_not_between=no # Function NOT BETWEEN in SELECT
+func_extra_not_like=no # Function NOT LIKE in SELECT
+func_extra_odbc_convert=no # Function ODBC CONVERT
+func_extra_password=no # Function PASSWORD
+func_extra_paste=no # Function PASTE
+func_extra_patindex=no # Function PATINDEX
+func_extra_period_add=no # Function PERIOD_ADD
+func_extra_period_diff=no # Function PERIOD_DIFF
+func_extra_pow=no # Function POW
+func_extra_range=no # Function RANGE
+func_extra_regexp=no # Function REGEXP in SELECT
+func_extra_replicate=no # Function REPLICATE
+func_extra_reverse=no # Function REVERSE
+func_extra_root=no # Function ROOT
+func_extra_round1=no # Function ROUND(1 arg)
+func_extra_rpad=no # Function RPAD
+func_extra_sec_to_time=no # Function SEC_TO_TIME
+func_extra_sinh=no # Function SINH
+func_extra_str=no # Function STR
+func_extra_strcmp=no # Function STRCMP
+func_extra_stuff=no # Function STUFF
+func_extra_substrb=no # Function SUBSTRB
+func_extra_substring_index=no # Function SUBSTRING_INDEX
+func_extra_sysdate=no # Function SYSDATE
+func_extra_tail=no # Function TAIL
+func_extra_tanh=no # Function TANH
+func_extra_time_to_sec=no # Function TIME_TO_SEC
+func_extra_to_days=no # Function TO_DAYS
+func_extra_translate=no # Function TRANSLATE
+func_extra_trim_many_char=no # Function TRIM; Many char extension
+func_extra_trim_substring=no # Function TRIM; Substring extension
+func_extra_trunc=no # Function TRUNC
+func_extra_uid=no # Function UID
+func_extra_unix_timestamp=no # Function UNIX_TIMESTAMP
+func_extra_userenv=no # Function USERENV
+func_extra_version=no # Function VERSION
+func_extra_weekday=no # Function WEEKDAY
+func_extra_|=no # Function | (bitwise or)
+func_extra_||=no # Function OR as '||'
+func_extra_~*=no # Function ~* (case insensitive compare)
+func_odbc_abs=no # Function ABS
+func_odbc_acos=no # Function ACOS
+func_odbc_ascii=no # Function ASCII
+func_odbc_asin=no # Function ASIN
+func_odbc_atan=no # Function ATAN
+func_odbc_atan2=no # Function ATAN2
+func_odbc_ceiling=no # Function CEILING
+func_odbc_char=no # Function CHAR
+func_odbc_concat=no # Function CONCAT(2 arg)
+func_odbc_cos=no # Function COS
+func_odbc_cot=no # Function COT
+func_odbc_curdate=no # Function CURDATE
+func_odbc_curtime=no # Function CURTIME
+func_odbc_database=no # Function DATABASE
+func_odbc_dayname=no # Function DAYNAME
+func_odbc_dayofmonth=no # Function DAYOFMONTH
+func_odbc_dayofweek=no # Function DAYOFWEEK
+func_odbc_dayofyear=no # Function DAYOFYEAR
+func_odbc_degrees=no # Function DEGREES
+func_odbc_difference=no # Function DIFFERENCE()
+func_odbc_exp=no # Function EXP
+func_odbc_floor=no # Function FLOOR
+func_odbc_fn_left=no # Function ODBC syntax LEFT & RIGHT
+func_odbc_hour=no # Function HOUR
+func_odbc_hour_time=no # Function ANSI HOUR
+func_odbc_ifnull=no # Function IFNULL
+func_odbc_insert=no # Function INSERT
+func_odbc_lcase=no # Function LCASE
+func_odbc_left=no # Function LEFT
+func_odbc_length=no # Function REAL LENGTH
+func_odbc_length_without_space=no # Function ODBC LENGTH
+func_odbc_locate_2=no # Function LOCATE(2 arg)
+func_odbc_locate_3=no # Function LOCATE(3 arg)
+func_odbc_log=no # Function LOG
+func_odbc_log10=no # Function LOG10
+func_odbc_ltrim=no # Function LTRIM
+func_odbc_minute=no # Function MINUTE
+func_odbc_mod=no # Function MOD
+func_odbc_month=no # Function MONTH
+func_odbc_monthname=no # Function MONTHNAME
+func_odbc_now=no # Function NOW
+func_odbc_pi=no # Function PI
+func_odbc_power=no # Function POWER
+func_odbc_quarter=no # Function QUARTER
+func_odbc_radians=no # Function RADIANS
+func_odbc_rand=no # Function RAND
+func_odbc_repeat=no # Function REPEAT
+func_odbc_replace=no # Function REPLACE
+func_odbc_right=no # Function RIGHT
+func_odbc_round=no # Function ROUND(2 arg)
+func_odbc_rtrim=no # Function RTRIM
+func_odbc_second=no # Function SECOND
+func_odbc_sign=no # Function SIGN
+func_odbc_sin=no # Function SIN
+func_odbc_soundex=no # Function SOUNDEX
+func_odbc_space=no # Function SPACE
+func_odbc_sqrt=no # Function SQRT
+func_odbc_substring=no # Function ODBC SUBSTRING
+func_odbc_tan=no # Function TAN
+func_odbc_timestampadd=no # Function TIMESTAMPADD
+func_odbc_timestampdiff=no # Function TIMESTAMPDIFF
+func_odbc_truncate=no # Function TRUNCATE
+func_odbc_ucase=no # Function UCASE
+func_odbc_user()=no # Function USER()
+func_odbc_week=no # Function WEEK
+func_odbc_year=no # Function YEAR
+func_sql_+=yes # Function +, -, * and /
+func_sql_bit_length=no # Function BIT_LENGTH
+func_sql_cast=yes # Function CAST
+func_sql_char_length=no # Function CHAR_LENGTH
+func_sql_char_length(constant)=no # Function CHAR_LENGTH(constant)
+func_sql_character_length=no # Function CHARACTER_LENGTH
+func_sql_coalesce=no # Function COALESCE
+func_sql_concat_as_||=yes # Function concatenation with ||
+func_sql_current_date=no # Function CURRENT_DATE
+func_sql_current_time=no # Function CURRENT_TIME
+func_sql_current_timestamp=yes # Function CURRENT_TIMESTAMP
+func_sql_current_user=no # Function CURRENT_USER
+func_sql_extract_sql=yes # Function EXTRACT
+func_sql_localtime=no # Function LOCALTIME
+func_sql_localtimestamp=no # Function LOCALTIMESTAMP
+func_sql_lower=no # Function LOWER
+func_sql_nullif_num=no # Function NULLIF with numbers
+func_sql_nullif_string=no # Function NULLIF with strings
+func_sql_octet_length=no # Function OCTET_LENGTH
+func_sql_position=no # Function POSITION
+func_sql_searched_case=no # Function searched CASE
+func_sql_session_user=no # Function SESSION_USER
+func_sql_simple_case=no # Function simple CASE
+func_sql_substring=no # Function ANSI SQL SUBSTRING
+func_sql_system_user=no # Function SYSTEM_USER
+func_sql_trim=no # Function TRIM
+func_sql_upper=yes # Function UPPER
+func_sql_user=yes # Function USER
+func_where_between=yes # Function BETWEEN
+func_where_eq_all=yes # Function = ALL
+func_where_eq_any=yes # Function = ANY
+func_where_eq_some=yes # Function = SOME
+func_where_exists=yes # Function EXISTS
+func_where_in_num=yes # Function IN on numbers
+func_where_like=yes # Function LIKE
+func_where_like_escape=yes # Function LIKE ESCAPE
+func_where_match=no # Function MATCH
+func_where_match_unique=no # Function MATCH UNIQUE
+func_where_matches=no # Function MATCHES
+func_where_not_between=yes # Function NOT BETWEEN
+func_where_not_exists=yes # Function NOT EXISTS
+func_where_not_like=yes # Function NOT LIKE
+func_where_not_unique=no # Function NOT UNIQUE
+func_where_unique=no # Function UNIQUE
+functions=yes # Functions
+group_by=yes # Group by
+group_by_alias=no # Group by alias
+group_by_null=yes # Group on column with null values
+group_by_position=no # Group by position
+group_distinct_functions=yes # Group functions with distinct
+group_func_extra_bit_and=no # Group function BIT_AND
+group_func_extra_bit_or=no # Group function BIT_OR
+group_func_extra_count_distinct_list=no # Group function COUNT(DISTINCT expr,expr,...)
+group_func_extra_std=no # Group function STD
+group_func_extra_stddev=no # Group function STDDEV
+group_func_extra_variance=no # Group function VARIANCE
+group_func_sql_any=no # Group function ANY
+group_func_sql_avg=yes # Group function AVG
+group_func_sql_count_*=yes # Group function COUNT (*)
+group_func_sql_count_column=yes # Group function COUNT column name
+group_func_sql_count_distinct=yes # Group function COUNT(DISTINCT expr)
+group_func_sql_every=no # Group function EVERY
+group_func_sql_max=yes # Group function MAX on numbers
+group_func_sql_max_str=yes # Group function MAX on strings
+group_func_sql_min=yes # Group function MIN on numbers
+group_func_sql_min_str=yes # Group function MIN on strings
+group_func_sql_some=no # Group function SOME
+group_func_sql_sum=yes # Group function SUM
+group_functions=yes # Group functions
+group_on_unused=yes # Group on unused column
+has_true_false=no # TRUE and FALSE
+having=yes # Having
+having_with_alias=no # Having on alias
+having_with_group=yes # Having with group function
+hex_numbers=yes # hex numbers (0x41)
+hex_strings=no # hex strings (x'1ace')
+ignore_end_space=yes # Ignore end space in compare
+index_in_create=no # index in create table
+index_namespace=no # different namespace for index
+index_parts=no # index on column part (extension)
+inner_join=yes # inner join
+insert_empty_string=no # insert empty string
+insert_multi_value=no # INSERT with Value lists
+insert_select=no # insert INTO ... SELECT ...
+insert_with_set=no # INSERT with set syntax
+intersect=no # intersect
+intersect_all=no # intersect all
+intersect_all_incompat=no # intersect all (incompatible lists)
+intersect_incompat=no # intersect (incompatible lists)
+join_tables=+64 # tables in join
+left_outer_join=yes # left outer join
+left_outer_join_using=no # left outer join using
+like_with_column=no # column LIKE column
+like_with_number=no # LIKE on numbers
+lock_tables=no # lock table
+logical_value=not supported # Value of logical operation (1=1)
+max_big_expressions=1 # big expressions
+max_char_size=32767 # max char() size
+max_column_name=18 # column name length
+max_columns=4759 # Columns in table
+max_conditions=2944 # OR and AND in WHERE
+max_expressions=+10000 # simple expressions
+max_index=+64 # max index
+max_index_name=31 # index name length
+max_index_parts=16 # index parts
+max_index_varchar_part_length=249 # index varchar part length
+max_row_length=64744 # max table row length (without blobs)
+max_row_length_with_null=64744 # table row length with nulls (without blobs)
+max_select_alias_name=132 # select alias name length
+max_stack_expression=165 # stacked expressions
+max_table_alias_name=255 # table alias name length
+max_table_name=31 # table name length
+max_unique_index=+64 # unique indexes
+max_varchar_size=10923 # max varchar() size
+minus=no # minus
+minus_incompat=no # minus (incompatible lists)
+minus_neg=yes # Calculate 1--1
+multi_drop=no # many tables to drop table
+multi_strings=no # Multiple line strings
+multi_table_delete=no # DELETE FROM table1,table2...
+multi_table_update=no # Update with many tables
+natural_join=no # natural join
+natural_join_incompat=no # natural join (incompatible lists)
+natural_left_outer_join=no # natural left outer join
+no_primary_key=yes # Tables without primary key
+null_concat_expr=no # Is 'a' || NULL = NULL
+null_in_index=yes # null in index
+null_in_unique=no # null in unique index
+null_num_expr=no # Is 1+NULL = NULL
+nulls_in_unique=no # null combination in unique index
+odbc_left_outer_join=no # left outer join odbc style
+operating_system=Linux 2.4.4-64GB-SMP i686 # crash-me tested on
+order_by=yes # Order by
+order_by_alias=no # Order by alias
+order_by_function=no # Order by function
+order_by_position=yes # Order by position
+order_by_remember_desc=no # Order by DESC is remembered
+order_on_unused=yes # Order by on unused column
+primary_key_in_create=yes # primary key in create table
+psm_functions=no # PSM functions (ANSI SQL)
+psm_modules=no # PSM modules (ANSI SQL)
+psm_procedures=no # PSM procedures (ANSI SQL)
+psm_trigger=no # Triggers (ANSI SQL)
+query_size=65535 # query size
+quote_ident_with_"=yes # " as identifier quote (ANSI SQL)
+quote_ident_with_[=no # [] as identifier quote
+quote_ident_with_`=no # ` as identifier quote
+quote_with_"=no # Allows ' and " as string markers
+recursive_subqueries=61 # recursive subqueries
+remember_end_space=no # Remembers end space in char()
+remember_end_space_varchar=yes # Remembers end space in varchar()
+rename_table=no # rename table
+right_outer_join=yes # right outer join
+rowid=no # Type for row id
+select_constants=yes # Select constants
+select_limit=no # LIMIT number of rows
+select_limit2=no # SELECT with LIMIT #,#
+select_string_size=32767 # constant string size in SELECT
+select_table_update=yes # Update with sub select
+select_without_from=no # SELECT without FROM
+server_version=6.0.1 # server version
+simple_joins=yes # ANSI SQL simple joins
+storage_of_float=round # Storage of float values
+subqueries=yes # subqueries
+table_alias=no # Table alias
+table_name_case=yes # case independent table names
+table_wildcard=yes # Select table_name.*
+temporary_table=no # temporary tables
+transactions=error # constant string size in where
+truncate_table=no # truncate
+type_extra_abstime=no # Type abstime
+type_extra_bfile=no # Type bfile
+type_extra_blob=yes # Type blob
+type_extra_bool=no # Type bool
+type_extra_box=no # Type box
+type_extra_byte=no # Type byte
+type_extra_char(1_arg)_binary=no # Type char(1 arg) binary
+type_extra_cidr=no # Type cidr
+type_extra_circle=no # Type circle
+type_extra_clob=no # Type clob
+type_extra_datetime=no # Type datetime
+type_extra_double=no # Type double
+type_extra_enum(1_arg)=no # Type enum(1 arg)
+type_extra_float(2_arg)=no # Type float(2 arg)
+type_extra_float4=no # Type float4
+type_extra_float8=no # Type float8
+type_extra_image=no # Type image
+type_extra_inet=no # Type inet
+type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
+type_extra_int1=no # Type int1
+type_extra_int2=no # Type int2
+type_extra_int3=no # Type int3
+type_extra_int4=no # Type int4
+type_extra_int8=no # Type int8
+type_extra_int_auto_increment=no # Type int not null auto_increment
+type_extra_int_identity=no # Type int not null identity
+type_extra_int_unsigned=no # Type int unsigned
+type_extra_interval=no # Type interval
+type_extra_line=no # Type line
+type_extra_long=no # Type long
+type_extra_long_raw=no # Type long raw
+type_extra_long_varbinary=no # Type long varbinary
+type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
+type_extra_lseg=no # Type lseg
+type_extra_macaddr=no # Type macaddr
+type_extra_mediumint=no # Type mediumint
+type_extra_mediumtext=no # Type mediumtext
+type_extra_middleint=no # Type middleint
+type_extra_mlslabel=no # Type mlslabel
+type_extra_money=no # Type money
+type_extra_nclob=no # Type nclob
+type_extra_number=no # Type number
+type_extra_number(1_arg)=no # Type number(1 arg)
+type_extra_number(2_arg)=no # Type number(2 arg)
+type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg)
+type_extra_path=no # Type path
+type_extra_point=no # Type point
+type_extra_polygon=no # Type polygon
+type_extra_raw(1_arg)=no # Type raw(1 arg)
+type_extra_reltime=no # Type reltime
+type_extra_rowid=no # Type rowid
+type_extra_serial=no # Type serial
+type_extra_set(1_arg)=no # Type set(1 arg)
+type_extra_smalldatetime=no # Type smalldatetime
+type_extra_smallfloat=no # Type smallfloat
+type_extra_smallmoney=no # Type smallmoney
+type_extra_text=no # Type text
+type_extra_text(1_arg)=no # Type text(1 arg)
+type_extra_timespan=no # Type timespan
+type_extra_uint=no # Type uint
+type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
+type_extra_year=no # Type year
+type_odbc_bigint=no # Type bigint
+type_odbc_binary(1_arg)=no # Type binary(1 arg)
+type_odbc_datetime=no # Type datetime
+type_odbc_tinyint=no # Type tinyint
+type_odbc_varbinary(1_arg)=no # Type varbinary(1 arg)
+type_sql_bit=no # Type bit
+type_sql_bit(1_arg)=no # Type bit(1 arg)
+type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg)
+type_sql_boolean=no # Type boolean
+type_sql_char(1_arg)=yes # Type char(1 arg)
+type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
+type_sql_character(1_arg)=yes # Type character(1 arg)
+type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
+type_sql_date=no # Type date
+type_sql_dec(2_arg)=yes # Type dec(2 arg)
+type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
+type_sql_double_precision=yes # Type double precision
+type_sql_float=yes # Type float
+type_sql_float(1_arg)=yes # Type float(1 arg)
+type_sql_int=yes # Type int
+type_sql_integer=yes # Type integer
+type_sql_interval_day=no # Type interval day
+type_sql_interval_day_to_hour=no # Type interval day to hour
+type_sql_interval_day_to_minute=no # Type interval day to minute
+type_sql_interval_day_to_second=no # Type interval day to second
+type_sql_interval_hour=no # Type interval hour
+type_sql_interval_hour_to_minute=no # Type interval hour to minute
+type_sql_interval_hour_to_second=no # Type interval hour to second
+type_sql_interval_minute=no # Type interval minute
+type_sql_interval_minute_to_second=no # Type interval minute to second
+type_sql_interval_month=no # Type interval month
+type_sql_interval_second=no # Type interval second
+type_sql_interval_year=no # Type interval year
+type_sql_interval_year_to_month=no # Type interval year to month
+type_sql_national_char_varying(1_arg)=yes # Type national char varying(1 arg)
+type_sql_national_character(1_arg)=yes # Type national character(1 arg)
+type_sql_national_character_varying(1_arg)=yes # Type national character varying(1 arg)
+type_sql_nchar(1_arg)=yes # Type nchar(1 arg)
+type_sql_nchar_varying(1_arg)=yes # Type nchar varying(1 arg)
+type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
+type_sql_real=yes # Type real
+type_sql_smallint=yes # Type smallint
+type_sql_time=no # Type time
+type_sql_timestamp=yes # Type timestamp
+type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
+type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
+union=yes # union
+union_all=yes # union all
+union_all_incompat=yes # union all (incompatible lists)
+union_incompat=yes # union (incompatible lists)
+unique_in_create=yes # unique in create table
+unique_null_in_create=no # unique null in create
+views=no # views
+where_string_size=32767 # constant string size in where
diff --git a/sql-bench/limits/interbase-dialect3.cfg b/sql-bench/limits/interbase-dialect3.cfg
new file mode 100644
index 00000000000..fdc93098688
--- /dev/null
+++ b/sql-bench/limits/interbase-dialect3.cfg
@@ -0,0 +1,514 @@
+#This file is automaticly generated by crash-me 1.57
+
+NEG=no # update of column= -column
+Need_cast_for_null=no # Need to cast NULL for arithmetic
+alter_add_col=yes # Alter table add column
+alter_add_constraint=yes # Alter table add constraint
+alter_add_foreign_key=yes # Alter table add foreign key
+alter_add_multi_col=with add # Alter table add many columns
+alter_add_primary_key=with constraint # Alter table add primary key
+alter_add_unique=no # Alter table add unique
+alter_alter_col=no # Alter table alter column default
+alter_change_col=no # Alter table change column
+alter_drop_col=no # Alter table drop column
+alter_drop_constraint=yes # Alter table drop constraint
+alter_drop_foreign_key=with drop constraint # Alter table drop foreign key
+alter_drop_primary_key=no # Alter table drop primary key
+alter_drop_unique=no # Alter table drop unique
+alter_modify_col=no # Alter table modify column
+alter_rename_table=no # Alter table rename table
+atomic_updates=no # atomic updates
+automatic_rowid=no # Automatic row id
+binary_numbers=yes # binary numbers (0b1001)
+binary_strings=no # binary strings (b'0110')
+case_insensitive_strings=no # Case insensitive compare
+char_is_space_filled=yes # char are space filled
+column_alias=yes # Column alias
+columns_in_order_by=37 # number of columns in order by
+comment_#=no # # as comment
+comment_--=no # -- as comment (ANSI)
+comment_/**/=yes # /* */ as comment
+comment_//=no # // as comment
+compute=no # Compute
+connections=1000 # Simultaneous connections (installation default)
+constraint_check=no # Column constraints
+constraint_check_table=no # Table constraints
+constraint_null=no # NULL constraint (SyBase style)
+crash_me_safe=yes # crash me safe
+crash_me_version=1.57 # crash me version
+create_default=yes # default value for column
+create_default_func=no # default value function for column
+create_if_not_exists=no # create table if not exists
+create_index=yes # create index
+create_schema=no # Create SCHEMA
+create_table_select=no # create table from select
+cross_join=no # cross join (same as from a,b)
+date_infinity=no # Supports 'infinity dates
+date_last=error # Supports 9999-12-31 dates
+date_one=error # Supports 0001-01-01 dates
+date_with_YY=no # Supports YY-MM-DD dates
+date_zero=no # Supports 0000-00-00 dates
+domains=no # Domains (ANSI SQL)
+double_quotes=yes # Double '' as ' in strings
+drop_if_exists=no # drop table if exists
+drop_index=yes # drop index
+drop_requires_cascade=no # drop table require cascade/restrict
+drop_restrict=no # drop table with cascade/restrict
+end_colon=yes # allows end ';'
+except=no # except
+except_all=no # except all
+except_all_incompat=no # except all (incompatible lists)
+except_incompat=no # except (incompatible lists)
+float_int_expr=yes # mixing of integer and float in expression
+foreign_key_syntax=no # foreign key syntax
+full_outer_join=yes # full outer join
+func_extra_!=no # Function NOT as '!' in SELECT
+func_extra_%=no # Function MOD as %
+func_extra_&=no # Function & (bitwise and)
+func_extra_&&=no # Function AND as '&&'
+func_extra_<>=no # Function <> in SELECT
+func_extra_==no # Function =
+func_extra_add_months=no # Function ADD_MONTHS
+func_extra_and_or=no # Function AND and OR in SELECT
+func_extra_ascii_char=no # Function ASCII_CHAR
+func_extra_ascii_code=no # Function ASCII_CODE
+func_extra_atn2=no # Function ATN2
+func_extra_auto_num2string=no # Function automatic num->string convert
+func_extra_auto_string2num=no # Function automatic string->num convert
+func_extra_between=no # Function BETWEEN in SELECT
+func_extra_binary_shifts=no # Function << and >> (bitwise shifts)
+func_extra_bit_count=no # Function BIT_COUNT
+func_extra_ceil=no # Function CEIL
+func_extra_charindex=no # Function CHARINDEX
+func_extra_chr=no # Function CHR
+func_extra_concat_as_+=no # Function concatenation with +
+func_extra_concat_list=no # Function CONCAT(list)
+func_extra_convert=no # Function CONVERT
+func_extra_cosh=no # Function COSH
+func_extra_date_format=no # Function DATE_FORMAT
+func_extra_dateadd=no # Function DATEADD
+func_extra_datediff=no # Function DATEDIFF
+func_extra_datename=no # Function DATENAME
+func_extra_datepart=no # Function DATEPART
+func_extra_elt=no # Function ELT
+func_extra_encrypt=no # Function ENCRYPT
+func_extra_field=no # Function FIELD
+func_extra_format=no # Function FORMAT
+func_extra_from_days=no # Function FROM_DAYS
+func_extra_from_unixtime=no # Function FROM_UNIXTIME
+func_extra_getdate=no # Function GETDATE
+func_extra_greatest=no # Function GREATEST
+func_extra_if=no # Function IF
+func_extra_in_num=no # Function IN on numbers in SELECT
+func_extra_in_str=no # Function IN on strings in SELECT
+func_extra_initcap=no # Function INITCAP
+func_extra_instr=no # Function LOCATE as INSTR
+func_extra_instr_oracle=no # Function INSTR (Oracle syntax)
+func_extra_instrb=no # Function INSTRB
+func_extra_interval=no # Function INTERVAL
+func_extra_last_day=no # Function LAST_DAY
+func_extra_last_insert_id=no # Function LAST_INSERT_ID
+func_extra_least=no # Function LEAST
+func_extra_lengthb=no # Function LENGTHB
+func_extra_like=no # Function LIKE in SELECT
+func_extra_like_escape=no # Function LIKE ESCAPE in SELECT
+func_extra_ln=no # Function LN
+func_extra_log(m_n)=no # Function LOG(m,n)
+func_extra_logn=no # Function LOGN
+func_extra_lpad=no # Function LPAD
+func_extra_mdy=no # Function MDY
+func_extra_mid=no # Function SUBSTRING as MID
+func_extra_months_between=no # Function MONTHS_BETWEEN
+func_extra_not=no # Function NOT in SELECT
+func_extra_not_between=no # Function NOT BETWEEN in SELECT
+func_extra_not_like=no # Function NOT LIKE in SELECT
+func_extra_odbc_convert=no # Function ODBC CONVERT
+func_extra_password=no # Function PASSWORD
+func_extra_paste=no # Function PASTE
+func_extra_patindex=no # Function PATINDEX
+func_extra_period_add=no # Function PERIOD_ADD
+func_extra_period_diff=no # Function PERIOD_DIFF
+func_extra_pow=no # Function POW
+func_extra_range=no # Function RANGE
+func_extra_regexp=no # Function REGEXP in SELECT
+func_extra_replicate=no # Function REPLICATE
+func_extra_reverse=no # Function REVERSE
+func_extra_root=no # Function ROOT
+func_extra_round1=no # Function ROUND(1 arg)
+func_extra_rpad=no # Function RPAD
+func_extra_sec_to_time=no # Function SEC_TO_TIME
+func_extra_sinh=no # Function SINH
+func_extra_str=no # Function STR
+func_extra_strcmp=no # Function STRCMP
+func_extra_stuff=no # Function STUFF
+func_extra_substrb=no # Function SUBSTRB
+func_extra_substring_index=no # Function SUBSTRING_INDEX
+func_extra_sysdate=no # Function SYSDATE
+func_extra_tail=no # Function TAIL
+func_extra_tanh=no # Function TANH
+func_extra_time_to_sec=no # Function TIME_TO_SEC
+func_extra_to_days=no # Function TO_DAYS
+func_extra_translate=no # Function TRANSLATE
+func_extra_trim_many_char=no # Function TRIM; Many char extension
+func_extra_trim_substring=no # Function TRIM; Substring extension
+func_extra_trunc=no # Function TRUNC
+func_extra_uid=no # Function UID
+func_extra_unix_timestamp=no # Function UNIX_TIMESTAMP
+func_extra_userenv=no # Function USERENV
+func_extra_version=no # Function VERSION
+func_extra_weekday=no # Function WEEKDAY
+func_extra_|=no # Function | (bitwise or)
+func_extra_||=no # Function OR as '||'
+func_extra_~*=no # Function ~* (case insensitive compare)
+func_odbc_abs=no # Function ABS
+func_odbc_acos=no # Function ACOS
+func_odbc_ascii=no # Function ASCII
+func_odbc_asin=no # Function ASIN
+func_odbc_atan=no # Function ATAN
+func_odbc_atan2=no # Function ATAN2
+func_odbc_ceiling=no # Function CEILING
+func_odbc_char=no # Function CHAR
+func_odbc_concat=no # Function CONCAT(2 arg)
+func_odbc_cos=no # Function COS
+func_odbc_cot=no # Function COT
+func_odbc_curdate=no # Function CURDATE
+func_odbc_curtime=no # Function CURTIME
+func_odbc_database=no # Function DATABASE
+func_odbc_dayname=no # Function DAYNAME
+func_odbc_dayofmonth=no # Function DAYOFMONTH
+func_odbc_dayofweek=no # Function DAYOFWEEK
+func_odbc_dayofyear=no # Function DAYOFYEAR
+func_odbc_degrees=no # Function DEGREES
+func_odbc_difference=no # Function DIFFERENCE()
+func_odbc_exp=no # Function EXP
+func_odbc_floor=no # Function FLOOR
+func_odbc_fn_left=no # Function ODBC syntax LEFT & RIGHT
+func_odbc_hour=no # Function HOUR
+func_odbc_hour_time=no # Function ANSI HOUR
+func_odbc_ifnull=no # Function IFNULL
+func_odbc_insert=no # Function INSERT
+func_odbc_lcase=no # Function LCASE
+func_odbc_left=no # Function LEFT
+func_odbc_length=no # Function REAL LENGTH
+func_odbc_length_without_space=no # Function ODBC LENGTH
+func_odbc_locate_2=no # Function LOCATE(2 arg)
+func_odbc_locate_3=no # Function LOCATE(3 arg)
+func_odbc_log=no # Function LOG
+func_odbc_log10=no # Function LOG10
+func_odbc_ltrim=no # Function LTRIM
+func_odbc_minute=no # Function MINUTE
+func_odbc_mod=no # Function MOD
+func_odbc_month=no # Function MONTH
+func_odbc_monthname=no # Function MONTHNAME
+func_odbc_now=no # Function NOW
+func_odbc_pi=no # Function PI
+func_odbc_power=no # Function POWER
+func_odbc_quarter=no # Function QUARTER
+func_odbc_radians=no # Function RADIANS
+func_odbc_rand=no # Function RAND
+func_odbc_repeat=no # Function REPEAT
+func_odbc_replace=no # Function REPLACE
+func_odbc_right=no # Function RIGHT
+func_odbc_round=no # Function ROUND(2 arg)
+func_odbc_rtrim=no # Function RTRIM
+func_odbc_second=no # Function SECOND
+func_odbc_sign=no # Function SIGN
+func_odbc_sin=no # Function SIN
+func_odbc_soundex=no # Function SOUNDEX
+func_odbc_space=no # Function SPACE
+func_odbc_sqrt=no # Function SQRT
+func_odbc_substring=no # Function ODBC SUBSTRING
+func_odbc_tan=no # Function TAN
+func_odbc_timestampadd=no # Function TIMESTAMPADD
+func_odbc_timestampdiff=no # Function TIMESTAMPDIFF
+func_odbc_truncate=no # Function TRUNCATE
+func_odbc_ucase=no # Function UCASE
+func_odbc_user()=no # Function USER()
+func_odbc_week=no # Function WEEK
+func_odbc_year=no # Function YEAR
+func_sql_+=yes # Function +, -, * and /
+func_sql_bit_length=no # Function BIT_LENGTH
+func_sql_cast=yes # Function CAST
+func_sql_char_length=no # Function CHAR_LENGTH
+func_sql_char_length(constant)=no # Function CHAR_LENGTH(constant)
+func_sql_character_length=no # Function CHARACTER_LENGTH
+func_sql_coalesce=no # Function COALESCE
+func_sql_concat_as_||=yes # Function concatenation with ||
+func_sql_current_date=yes # Function CURRENT_DATE
+func_sql_current_time=yes # Function CURRENT_TIME
+func_sql_current_timestamp=yes # Function CURRENT_TIMESTAMP
+func_sql_current_user=no # Function CURRENT_USER
+func_sql_extract_sql=yes # Function EXTRACT
+func_sql_localtime=no # Function LOCALTIME
+func_sql_localtimestamp=no # Function LOCALTIMESTAMP
+func_sql_lower=no # Function LOWER
+func_sql_nullif_num=no # Function NULLIF with numbers
+func_sql_nullif_string=no # Function NULLIF with strings
+func_sql_octet_length=no # Function OCTET_LENGTH
+func_sql_position=no # Function POSITION
+func_sql_searched_case=no # Function searched CASE
+func_sql_session_user=no # Function SESSION_USER
+func_sql_simple_case=no # Function simple CASE
+func_sql_substring=no # Function ANSI SQL SUBSTRING
+func_sql_system_user=no # Function SYSTEM_USER
+func_sql_trim=no # Function TRIM
+func_sql_upper=yes # Function UPPER
+func_sql_user=yes # Function USER
+func_where_between=yes # Function BETWEEN
+func_where_eq_all=yes # Function = ALL
+func_where_eq_any=yes # Function = ANY
+func_where_eq_some=yes # Function = SOME
+func_where_exists=yes # Function EXISTS
+func_where_in_num=yes # Function IN on numbers
+func_where_like=yes # Function LIKE
+func_where_like_escape=yes # Function LIKE ESCAPE
+func_where_match=no # Function MATCH
+func_where_match_unique=no # Function MATCH UNIQUE
+func_where_matches=no # Function MATCHES
+func_where_not_between=yes # Function NOT BETWEEN
+func_where_not_exists=yes # Function NOT EXISTS
+func_where_not_like=yes # Function NOT LIKE
+func_where_not_unique=no # Function NOT UNIQUE
+func_where_unique=no # Function UNIQUE
+functions=yes # Functions
+group_by=yes # Group by
+group_by_alias=no # Group by alias
+group_by_null=yes # Group on column with null values
+group_by_position=no # Group by position
+group_distinct_functions=yes # Group functions with distinct
+group_func_extra_bit_and=no # Group function BIT_AND
+group_func_extra_bit_or=no # Group function BIT_OR
+group_func_extra_count_distinct_list=no # Group function COUNT(DISTINCT expr,expr,...)
+group_func_extra_std=no # Group function STD
+group_func_extra_stddev=no # Group function STDDEV
+group_func_extra_variance=no # Group function VARIANCE
+group_func_sql_any=no # Group function ANY
+group_func_sql_avg=yes # Group function AVG
+group_func_sql_count_*=yes # Group function COUNT (*)
+group_func_sql_count_column=yes # Group function COUNT column name
+group_func_sql_count_distinct=yes # Group function COUNT(DISTINCT expr)
+group_func_sql_every=no # Group function EVERY
+group_func_sql_max=yes # Group function MAX on numbers
+group_func_sql_max_str=yes # Group function MAX on strings
+group_func_sql_min=yes # Group function MIN on numbers
+group_func_sql_min_str=yes # Group function MIN on strings
+group_func_sql_some=no # Group function SOME
+group_func_sql_sum=yes # Group function SUM
+group_functions=yes # Group functions
+group_on_unused=yes # Group on unused column
+has_true_false=no # TRUE and FALSE
+having=yes # Having
+having_with_alias=no # Having on alias
+having_with_group=yes # Having with group function
+hex_numbers=yes # hex numbers (0x41)
+hex_strings=no # hex strings (x'1ace')
+ignore_end_space=yes # Ignore end space in compare
+index_in_create=no # index in create table
+index_namespace=no # different namespace for index
+index_parts=no # index on column part (extension)
+inner_join=yes # inner join
+insert_empty_string=no # insert empty string
+insert_multi_value=no # INSERT with Value lists
+insert_select=no # insert INTO ... SELECT ...
+insert_with_set=no # INSERT with set syntax
+intersect=no # intersect
+intersect_all=no # intersect all
+intersect_all_incompat=no # intersect all (incompatible lists)
+intersect_incompat=no # intersect (incompatible lists)
+join_tables=+64 # tables in join
+left_outer_join=yes # left outer join
+left_outer_join_using=no # left outer join using
+like_with_column=no # column LIKE column
+like_with_number=no # LIKE on numbers
+lock_tables=no # lock table
+logical_value=not supported # Value of logical operation (1=1)
+max_big_expressions=1 # big expressions
+max_char_size=32767 # max char() size
+max_columns=4759 # Columns in table
+max_conditions=5888 # OR and AND in WHERE
+max_expressions=+10000 # simple expressions
+max_index=+64 # max index
+max_index_name=31 # index name length
+max_index_parts=16 # index parts
+max_index_varchar_part_length=249 # index varchar part length
+max_row_length=64744 # max table row length (without blobs)
+max_row_length_with_null=64744 # table row length with nulls (without blobs)
+max_select_alias_name=132 # select alias name length
+max_stack_expression=165 # stacked expressions
+max_table_alias_name=255 # table alias name length
+max_table_name=31 # table name length
+max_unique_index=+64 # unique indexes
+max_varchar_size=10923 # max varchar() size
+minus=no # minus
+minus_incompat=no # minus (incompatible lists)
+minus_neg=yes # Calculate 1--1
+multi_drop=no # many tables to drop table
+multi_strings=no # Multiple line strings
+multi_table_delete=no # DELETE FROM table1,table2...
+multi_table_update=no # Update with many tables
+natural_join=no # natural join
+natural_join_incompat=no # natural join (incompatible lists)
+natural_left_outer_join=no # natural left outer join
+no_primary_key=yes # Tables without primary key
+null_concat_expr=no # Is 'a' || NULL = NULL
+null_in_index=yes # null in index
+null_in_unique=no # null in unique index
+null_num_expr=no # Is 1+NULL = NULL
+nulls_in_unique=no # null combination in unique index
+odbc_left_outer_join=no # left outer join odbc style
+operating_system=Linux 2.4.4-64GB-SMP i686 # crash-me tested on
+order_by=yes # Order by
+order_by_alias=no # Order by alias
+order_by_function=no # Order by function
+order_by_position=yes # Order by position
+order_by_remember_desc=no # Order by DESC is remembered
+order_on_unused=yes # Order by on unused column
+primary_key_in_create=yes # primary key in create table
+psm_functions=no # PSM functions (ANSI SQL)
+psm_modules=no # PSM modules (ANSI SQL)
+psm_procedures=no # PSM procedures (ANSI SQL)
+psm_trigger=no # Triggers (ANSI SQL)
+query_size=65535 # query size
+quote_ident_with_"=yes # " as identifier quote (ANSI SQL)
+quote_ident_with_[=no # [] as identifier quote
+quote_ident_with_`=no # ` as identifier quote
+quote_with_"=no # Allows ' and " as string markers
+recursive_subqueries=61 # recursive subqueries
+remember_end_space=no # Remembers end space in char()
+remember_end_space_varchar=yes # Remembers end space in varchar()
+rename_table=no # rename table
+right_outer_join=yes # right outer join
+rowid=no # Type for row id
+select_constants=yes # Select constants
+select_limit=no # LIMIT number of rows
+select_limit2=no # SELECT with LIMIT #,#
+select_string_size=32767 # constant string size in SELECT
+select_table_update=yes # Update with sub select
+select_without_from=no # SELECT without FROM
+server_version=6.0.1 # server version
+simple_joins=yes # ANSI SQL simple joins
+storage_of_float=round # Storage of float values
+subqueries=yes # subqueries
+table_alias=no # Table alias
+table_name_case=yes # case independent table names
+table_wildcard=yes # Select table_name.*
+temporary_table=no # temporary tables
+transactions=error # constant string size in where
+truncate_table=no # truncate
+type_extra_abstime=no # Type abstime
+type_extra_bfile=no # Type bfile
+type_extra_blob=yes # Type blob
+type_extra_bool=no # Type bool
+type_extra_box=no # Type box
+type_extra_byte=no # Type byte
+type_extra_char(1_arg)_binary=no # Type char(1 arg) binary
+type_extra_cidr=no # Type cidr
+type_extra_circle=no # Type circle
+type_extra_clob=no # Type clob
+type_extra_datetime=no # Type datetime
+type_extra_double=no # Type double
+type_extra_enum(1_arg)=no # Type enum(1 arg)
+type_extra_float(2_arg)=no # Type float(2 arg)
+type_extra_float4=no # Type float4
+type_extra_float8=no # Type float8
+type_extra_image=no # Type image
+type_extra_inet=no # Type inet
+type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
+type_extra_int1=no # Type int1
+type_extra_int2=no # Type int2
+type_extra_int3=no # Type int3
+type_extra_int4=no # Type int4
+type_extra_int8=no # Type int8
+type_extra_int_auto_increment=no # Type int not null auto_increment
+type_extra_int_identity=no # Type int not null identity
+type_extra_int_unsigned=no # Type int unsigned
+type_extra_interval=no # Type interval
+type_extra_line=no # Type line
+type_extra_long=no # Type long
+type_extra_long_raw=no # Type long raw
+type_extra_long_varbinary=no # Type long varbinary
+type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
+type_extra_lseg=no # Type lseg
+type_extra_macaddr=no # Type macaddr
+type_extra_mediumint=no # Type mediumint
+type_extra_mediumtext=no # Type mediumtext
+type_extra_middleint=no # Type middleint
+type_extra_mlslabel=no # Type mlslabel
+type_extra_money=no # Type money
+type_extra_nclob=no # Type nclob
+type_extra_number=no # Type number
+type_extra_number(1_arg)=no # Type number(1 arg)
+type_extra_number(2_arg)=no # Type number(2 arg)
+type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg)
+type_extra_path=no # Type path
+type_extra_point=no # Type point
+type_extra_polygon=no # Type polygon
+type_extra_raw(1_arg)=no # Type raw(1 arg)
+type_extra_reltime=no # Type reltime
+type_extra_rowid=no # Type rowid
+type_extra_serial=no # Type serial
+type_extra_set(1_arg)=no # Type set(1 arg)
+type_extra_smalldatetime=no # Type smalldatetime
+type_extra_smallfloat=no # Type smallfloat
+type_extra_smallmoney=no # Type smallmoney
+type_extra_text=no # Type text
+type_extra_text(1_arg)=no # Type text(1 arg)
+type_extra_timespan=no # Type timespan
+type_extra_uint=no # Type uint
+type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
+type_extra_year=no # Type year
+type_odbc_bigint=no # Type bigint
+type_odbc_binary(1_arg)=no # Type binary(1 arg)
+type_odbc_datetime=no # Type datetime
+type_odbc_tinyint=no # Type tinyint
+type_odbc_varbinary(1_arg)=no # Type varbinary(1 arg)
+type_sql_=no # Type
+type_sql_bit=no # Type bit
+type_sql_bit(1_arg)=no # Type bit(1 arg)
+type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg)
+type_sql_boolean=no # Type boolean
+type_sql_char(1_arg)=yes # Type char(1 arg)
+type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
+type_sql_character(1_arg)=yes # Type character(1 arg)
+type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
+type_sql_date=yes # Type date
+type_sql_dec(2_arg)=yes # Type dec(2 arg)
+type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
+type_sql_double_precision=yes # Type double precision
+type_sql_float=yes # Type float
+type_sql_float(1_arg)=yes # Type float(1 arg)
+type_sql_int=yes # Type int
+type_sql_integer=yes # Type integer
+type_sql_interval_day=no # Type interval day
+type_sql_interval_day_to_hour=no # Type interval day to hour
+type_sql_interval_day_to_minute=no # Type interval day to minute
+type_sql_interval_day_to_second=no # Type interval day to second
+type_sql_interval_hour=no # Type interval hour
+type_sql_interval_hour_to_minute=no # Type interval hour to minute
+type_sql_interval_hour_to_second=no # Type interval hour to second
+type_sql_interval_minute=no # Type interval minute
+type_sql_interval_minute_to_second=no # Type interval minute to second
+type_sql_interval_month=no # Type interval month
+type_sql_interval_second=no # Type interval second
+type_sql_interval_year=no # Type interval year
+type_sql_interval_year_to_month=no # Type interval year to month
+type_sql_national_char_varying(1_arg)=yes # Type national char varying(1 arg)
+type_sql_national_character(1_arg)=yes # Type national character(1 arg)
+type_sql_national_character_varying(1_arg)=yes # Type national character varying(1 arg)
+type_sql_nchar(1_arg)=yes # Type nchar(1 arg)
+type_sql_nchar_varying(1_arg)=yes # Type nchar varying(1 arg)
+type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
+type_sql_real=yes # Type real
+type_sql_smallint=yes # Type smallint
+type_sql_time=yes # Type time
+type_sql_timestamp=yes # Type timestamp
+type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
+type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
+union=yes # union
+union_all=yes # union all
+union_all_incompat=yes # union all (incompatible lists)
+union_incompat=yes # union (incompatible lists)
+unique_in_create=yes # unique in create table
+unique_null_in_create=no # unique null in create
+views=no # views
+where_string_size=32767 # constant string size in where
diff --git a/sql-bench/limits/interbase-superserver.cfg b/sql-bench/limits/interbase-superserver.cfg
new file mode 100644
index 00000000000..87da0d0633c
--- /dev/null
+++ b/sql-bench/limits/interbase-superserver.cfg
@@ -0,0 +1,514 @@
+#This file is automaticly generated by crash-me 1.57
+
+NEG=no # update of column= -column
+Need_cast_for_null=no # Need to cast NULL for arithmetic
+alter_add_col=yes # Alter table add column
+alter_add_constraint=yes # Alter table add constraint
+alter_add_foreign_key=yes # Alter table add foreign key
+alter_add_multi_col=with add # Alter table add many columns
+alter_add_primary_key=with constraint # Alter table add primary key
+alter_add_unique=no # Alter table add unique
+alter_alter_col=no # Alter table alter column default
+alter_change_col=no # Alter table change column
+alter_drop_col=no # Alter table drop column
+alter_drop_constraint=yes # Alter table drop constraint
+alter_drop_foreign_key=with drop constraint # Alter table drop foreign key
+alter_drop_primary_key=no # Alter table drop primary key
+alter_drop_unique=no # Alter table drop unique
+alter_modify_col=no # Alter table modify column
+alter_rename_table=no # Alter table rename table
+atomic_updates=no # atomic updates
+automatic_rowid=no # Automatic row id
+binary_numbers=yes # binary numbers (0b1001)
+binary_strings=no # binary strings (b'0110')
+case_insensitive_strings=no # Case insensitive compare
+char_is_space_filled=yes # char are space filled
+column_alias=yes # Column alias
+columns_in_order_by=37 # number of columns in order by
+comment_#=no # # as comment
+comment_--=no # -- as comment (ANSI)
+comment_/**/=yes # /* */ as comment
+comment_//=no # // as comment
+compute=no # Compute
+connections=395 # Simultaneous connections (installation default)
+constraint_check=no # Column constraints
+constraint_check_table=no # Table constraints
+constraint_null=no # NULL constraint (SyBase style)
+crash_me_safe=no # crash me safe
+crash_me_version=1.57 # crash me version
+create_default=yes # default value for column
+create_default_func=no # default value function for column
+create_if_not_exists=no # create table if not exists
+create_index=yes # create index
+create_schema=no # Create SCHEMA
+create_table_select=no # create table from select
+cross_join=no # cross join (same as from a,b)
+date_infinity=no # Supports 'infinity dates
+date_last=error # Supports 9999-12-31 dates
+date_one=error # Supports 0001-01-01 dates
+date_with_YY=no # Supports YY-MM-DD dates
+date_zero=no # Supports 0000-00-00 dates
+domains=no # Domains (ANSI SQL)
+double_quotes=yes # Double '' as ' in strings
+drop_if_exists=no # drop table if exists
+drop_index=yes # drop index
+drop_requires_cascade=no # drop table require cascade/restrict
+drop_restrict=no # drop table with cascade/restrict
+end_colon=yes # allows end ';'
+except=no # except
+except_all=no # except all
+except_all_incompat=no # except all (incompatible lists)
+except_incompat=no # except (incompatible lists)
+float_int_expr=yes # mixing of integer and float in expression
+foreign_key_syntax=no # foreign key syntax
+full_outer_join=yes # full outer join
+func_extra_!=no # Function NOT as '!' in SELECT
+func_extra_%=no # Function MOD as %
+func_extra_&=no # Function & (bitwise and)
+func_extra_&&=no # Function AND as '&&'
+func_extra_<>=no # Function <> in SELECT
+func_extra_==no # Function =
+func_extra_add_months=no # Function ADD_MONTHS
+func_extra_and_or=no # Function AND and OR in SELECT
+func_extra_ascii_char=no # Function ASCII_CHAR
+func_extra_ascii_code=no # Function ASCII_CODE
+func_extra_atn2=no # Function ATN2
+func_extra_auto_num2string=no # Function automatic num->string convert
+func_extra_auto_string2num=no # Function automatic string->num convert
+func_extra_between=no # Function BETWEEN in SELECT
+func_extra_binary_shifts=no # Function << and >> (bitwise shifts)
+func_extra_bit_count=no # Function BIT_COUNT
+func_extra_ceil=no # Function CEIL
+func_extra_charindex=no # Function CHARINDEX
+func_extra_chr=no # Function CHR
+func_extra_concat_as_+=no # Function concatenation with +
+func_extra_concat_list=no # Function CONCAT(list)
+func_extra_convert=no # Function CONVERT
+func_extra_cosh=no # Function COSH
+func_extra_date_format=no # Function DATE_FORMAT
+func_extra_dateadd=no # Function DATEADD
+func_extra_datediff=no # Function DATEDIFF
+func_extra_datename=no # Function DATENAME
+func_extra_datepart=no # Function DATEPART
+func_extra_elt=no # Function ELT
+func_extra_encrypt=no # Function ENCRYPT
+func_extra_field=no # Function FIELD
+func_extra_format=no # Function FORMAT
+func_extra_from_days=no # Function FROM_DAYS
+func_extra_from_unixtime=no # Function FROM_UNIXTIME
+func_extra_getdate=no # Function GETDATE
+func_extra_greatest=no # Function GREATEST
+func_extra_if=no # Function IF
+func_extra_in_num=no # Function IN on numbers in SELECT
+func_extra_in_str=no # Function IN on strings in SELECT
+func_extra_initcap=no # Function INITCAP
+func_extra_instr=no # Function LOCATE as INSTR
+func_extra_instr_oracle=no # Function INSTR (Oracle syntax)
+func_extra_instrb=no # Function INSTRB
+func_extra_interval=no # Function INTERVAL
+func_extra_last_day=no # Function LAST_DAY
+func_extra_last_insert_id=no # Function LAST_INSERT_ID
+func_extra_least=no # Function LEAST
+func_extra_lengthb=no # Function LENGTHB
+func_extra_like=no # Function LIKE in SELECT
+func_extra_like_escape=no # Function LIKE ESCAPE in SELECT
+func_extra_ln=no # Function LN
+func_extra_log(m_n)=no # Function LOG(m,n)
+func_extra_logn=no # Function LOGN
+func_extra_lpad=no # Function LPAD
+func_extra_mdy=no # Function MDY
+func_extra_mid=no # Function SUBSTRING as MID
+func_extra_months_between=no # Function MONTHS_BETWEEN
+func_extra_not=no # Function NOT in SELECT
+func_extra_not_between=no # Function NOT BETWEEN in SELECT
+func_extra_not_like=no # Function NOT LIKE in SELECT
+func_extra_odbc_convert=no # Function ODBC CONVERT
+func_extra_password=no # Function PASSWORD
+func_extra_paste=no # Function PASTE
+func_extra_patindex=no # Function PATINDEX
+func_extra_period_add=no # Function PERIOD_ADD
+func_extra_period_diff=no # Function PERIOD_DIFF
+func_extra_pow=no # Function POW
+func_extra_range=no # Function RANGE
+func_extra_regexp=no # Function REGEXP in SELECT
+func_extra_replicate=no # Function REPLICATE
+func_extra_reverse=no # Function REVERSE
+func_extra_root=no # Function ROOT
+func_extra_round1=no # Function ROUND(1 arg)
+func_extra_rpad=no # Function RPAD
+func_extra_sec_to_time=no # Function SEC_TO_TIME
+func_extra_sinh=no # Function SINH
+func_extra_str=no # Function STR
+func_extra_strcmp=no # Function STRCMP
+func_extra_stuff=no # Function STUFF
+func_extra_substrb=no # Function SUBSTRB
+func_extra_substring_index=no # Function SUBSTRING_INDEX
+func_extra_sysdate=no # Function SYSDATE
+func_extra_tail=no # Function TAIL
+func_extra_tanh=no # Function TANH
+func_extra_time_to_sec=no # Function TIME_TO_SEC
+func_extra_to_days=no # Function TO_DAYS
+func_extra_translate=no # Function TRANSLATE
+func_extra_trim_many_char=no # Function TRIM; Many char extension
+func_extra_trim_substring=no # Function TRIM; Substring extension
+func_extra_trunc=no # Function TRUNC
+func_extra_uid=no # Function UID
+func_extra_unix_timestamp=no # Function UNIX_TIMESTAMP
+func_extra_userenv=no # Function USERENV
+func_extra_version=no # Function VERSION
+func_extra_weekday=no # Function WEEKDAY
+func_extra_|=no # Function | (bitwise or)
+func_extra_||=no # Function OR as '||'
+func_extra_~*=no # Function ~* (case insensitive compare)
+func_odbc_abs=no # Function ABS
+func_odbc_acos=no # Function ACOS
+func_odbc_ascii=no # Function ASCII
+func_odbc_asin=no # Function ASIN
+func_odbc_atan=no # Function ATAN
+func_odbc_atan2=no # Function ATAN2
+func_odbc_ceiling=no # Function CEILING
+func_odbc_char=no # Function CHAR
+func_odbc_concat=no # Function CONCAT(2 arg)
+func_odbc_cos=no # Function COS
+func_odbc_cot=no # Function COT
+func_odbc_curdate=no # Function CURDATE
+func_odbc_curtime=no # Function CURTIME
+func_odbc_database=no # Function DATABASE
+func_odbc_dayname=no # Function DAYNAME
+func_odbc_dayofmonth=no # Function DAYOFMONTH
+func_odbc_dayofweek=no # Function DAYOFWEEK
+func_odbc_dayofyear=no # Function DAYOFYEAR
+func_odbc_degrees=no # Function DEGREES
+func_odbc_difference=no # Function DIFFERENCE()
+func_odbc_exp=no # Function EXP
+func_odbc_floor=no # Function FLOOR
+func_odbc_fn_left=no # Function ODBC syntax LEFT & RIGHT
+func_odbc_hour=no # Function HOUR
+func_odbc_hour_time=no # Function ANSI HOUR
+func_odbc_ifnull=no # Function IFNULL
+func_odbc_insert=no # Function INSERT
+func_odbc_lcase=no # Function LCASE
+func_odbc_left=no # Function LEFT
+func_odbc_length=no # Function REAL LENGTH
+func_odbc_length_without_space=no # Function ODBC LENGTH
+func_odbc_locate_2=no # Function LOCATE(2 arg)
+func_odbc_locate_3=no # Function LOCATE(3 arg)
+func_odbc_log=no # Function LOG
+func_odbc_log10=no # Function LOG10
+func_odbc_ltrim=no # Function LTRIM
+func_odbc_minute=no # Function MINUTE
+func_odbc_mod=no # Function MOD
+func_odbc_month=no # Function MONTH
+func_odbc_monthname=no # Function MONTHNAME
+func_odbc_now=no # Function NOW
+func_odbc_pi=no # Function PI
+func_odbc_power=no # Function POWER
+func_odbc_quarter=no # Function QUARTER
+func_odbc_radians=no # Function RADIANS
+func_odbc_rand=no # Function RAND
+func_odbc_repeat=no # Function REPEAT
+func_odbc_replace=no # Function REPLACE
+func_odbc_right=no # Function RIGHT
+func_odbc_round=no # Function ROUND(2 arg)
+func_odbc_rtrim=no # Function RTRIM
+func_odbc_second=no # Function SECOND
+func_odbc_sign=no # Function SIGN
+func_odbc_sin=no # Function SIN
+func_odbc_soundex=no # Function SOUNDEX
+func_odbc_space=no # Function SPACE
+func_odbc_sqrt=no # Function SQRT
+func_odbc_substring=no # Function ODBC SUBSTRING
+func_odbc_tan=no # Function TAN
+func_odbc_timestampadd=no # Function TIMESTAMPADD
+func_odbc_timestampdiff=no # Function TIMESTAMPDIFF
+func_odbc_truncate=no # Function TRUNCATE
+func_odbc_ucase=no # Function UCASE
+func_odbc_user()=no # Function USER()
+func_odbc_week=no # Function WEEK
+func_odbc_year=no # Function YEAR
+func_sql_+=yes # Function +, -, * and /
+func_sql_bit_length=no # Function BIT_LENGTH
+func_sql_cast=yes # Function CAST
+func_sql_char_length=no # Function CHAR_LENGTH
+func_sql_char_length(constant)=no # Function CHAR_LENGTH(constant)
+func_sql_character_length=no # Function CHARACTER_LENGTH
+func_sql_coalesce=no # Function COALESCE
+func_sql_concat_as_||=yes # Function concatenation with ||
+func_sql_current_date=yes # Function CURRENT_DATE
+func_sql_current_time=yes # Function CURRENT_TIME
+func_sql_current_timestamp=yes # Function CURRENT_TIMESTAMP
+func_sql_current_user=no # Function CURRENT_USER
+func_sql_extract_sql=yes # Function EXTRACT
+func_sql_localtime=no # Function LOCALTIME
+func_sql_localtimestamp=no # Function LOCALTIMESTAMP
+func_sql_lower=no # Function LOWER
+func_sql_nullif_num=no # Function NULLIF with numbers
+func_sql_nullif_string=no # Function NULLIF with strings
+func_sql_octet_length=no # Function OCTET_LENGTH
+func_sql_position=no # Function POSITION
+func_sql_searched_case=no # Function searched CASE
+func_sql_session_user=no # Function SESSION_USER
+func_sql_simple_case=no # Function simple CASE
+func_sql_substring=no # Function ANSI SQL SUBSTRING
+func_sql_system_user=no # Function SYSTEM_USER
+func_sql_trim=no # Function TRIM
+func_sql_upper=yes # Function UPPER
+func_sql_user=yes # Function USER
+func_where_between=yes # Function BETWEEN
+func_where_eq_all=yes # Function = ALL
+func_where_eq_any=yes # Function = ANY
+func_where_eq_some=yes # Function = SOME
+func_where_exists=yes # Function EXISTS
+func_where_in_num=yes # Function IN on numbers
+func_where_like=yes # Function LIKE
+func_where_like_escape=yes # Function LIKE ESCAPE
+func_where_match=no # Function MATCH
+func_where_match_unique=no # Function MATCH UNIQUE
+func_where_matches=no # Function MATCHES
+func_where_not_between=yes # Function NOT BETWEEN
+func_where_not_exists=yes # Function NOT EXISTS
+func_where_not_like=yes # Function NOT LIKE
+func_where_not_unique=no # Function NOT UNIQUE
+func_where_unique=no # Function UNIQUE
+functions=yes # Functions
+group_by=yes # Group by
+group_by_alias=no # Group by alias
+group_by_null=yes # Group on column with null values
+group_by_position=no # Group by position
+group_distinct_functions=yes # Group functions with distinct
+group_func_extra_bit_and=no # Group function BIT_AND
+group_func_extra_bit_or=no # Group function BIT_OR
+group_func_extra_count_distinct_list=no # Group function COUNT(DISTINCT expr,expr,...)
+group_func_extra_std=no # Group function STD
+group_func_extra_stddev=no # Group function STDDEV
+group_func_extra_variance=no # Group function VARIANCE
+group_func_sql_any=no # Group function ANY
+group_func_sql_avg=yes # Group function AVG
+group_func_sql_count_*=yes # Group function COUNT (*)
+group_func_sql_count_column=yes # Group function COUNT column name
+group_func_sql_count_distinct=yes # Group function COUNT(DISTINCT expr)
+group_func_sql_every=no # Group function EVERY
+group_func_sql_max=yes # Group function MAX on numbers
+group_func_sql_max_str=yes # Group function MAX on strings
+group_func_sql_min=yes # Group function MIN on numbers
+group_func_sql_min_str=yes # Group function MIN on strings
+group_func_sql_some=no # Group function SOME
+group_func_sql_sum=yes # Group function SUM
+group_functions=yes # Group functions
+group_on_unused=yes # Group on unused column
+has_true_false=no # TRUE and FALSE
+having=yes # Having
+having_with_alias=no # Having on alias
+having_with_group=yes # Having with group function
+hex_numbers=yes # hex numbers (0x41)
+hex_strings=no # hex strings (x'1ace')
+ignore_end_space=yes # Ignore end space in compare
+index_in_create=no # index in create table
+index_namespace=no # different namespace for index
+index_parts=no # index on column part (extension)
+inner_join=yes # inner join
+insert_empty_string=no # insert empty string
+insert_multi_value=no # INSERT with Value lists
+insert_select=no # insert INTO ... SELECT ...
+insert_with_set=no # INSERT with set syntax
+intersect=no # intersect
+intersect_all=no # intersect all
+intersect_all_incompat=no # intersect all (incompatible lists)
+intersect_incompat=no # intersect (incompatible lists)
+join_tables=+64 # tables in join
+left_outer_join=yes # left outer join
+left_outer_join_using=no # left outer join using
+like_with_column=no # column LIKE column
+like_with_number=no # LIKE on numbers
+lock_tables=no # lock table
+logical_value=not supported # Value of logical operation (1=1)
+max_big_expressions=1 # big expressions
+max_char_size=32745 # max char() size
+max_column_name=18 # column name length
+max_columns=4759 # Columns in table
+max_conditions=441504 # OR and AND in WHERE
+max_expressions=5486 # simple expressions
+max_index=+64 # max index
+max_index_name=31 # index name length
+max_index_parts=16 # index parts
+max_index_varchar_part_length=218 # index varchar part length
+max_row_length=64744 # max table row length (without blobs)
+max_row_length_with_null=64744 # table row length with nulls (without blobs)
+max_select_alias_name=132 # select alias name length
+max_stack_expression=165 # stacked expressions
+max_table_alias_name=255 # table alias name length
+max_table_name=31 # table name length
+max_unique_index=+64 # unique indexes
+max_varchar_size=32745 # max varchar() size
+minus=no # minus
+minus_incompat=no # minus (incompatible lists)
+minus_neg=yes # Calculate 1--1
+multi_drop=no # many tables to drop table
+multi_strings=no # Multiple line strings
+multi_table_delete=no # DELETE FROM table1,table2...
+multi_table_update=no # Update with many tables
+natural_join=no # natural join
+natural_join_incompat=no # natural join (incompatible lists)
+natural_left_outer_join=no # natural left outer join
+no_primary_key=yes # Tables without primary key
+null_concat_expr=no # Is 'a' || NULL = NULL
+null_in_index=yes # null in index
+null_in_unique=no # null in unique index
+null_num_expr=no # Is 1+NULL = NULL
+nulls_in_unique=no # null combination in unique index
+odbc_left_outer_join=no # left outer join odbc style
+operating_system=Linux 2.4.4-64GB-SMP i686 # crash-me tested on
+order_by=yes # Order by
+order_by_alias=no # Order by alias
+order_by_function=no # Order by function
+order_by_position=yes # Order by position
+order_by_remember_desc=no # Order by DESC is remembered
+order_on_unused=yes # Order by on unused column
+primary_key_in_create=yes # primary key in create table
+psm_functions=no # PSM functions (ANSI SQL)
+psm_modules=no # PSM modules (ANSI SQL)
+psm_procedures=no # PSM procedures (ANSI SQL)
+psm_trigger=no # Triggers (ANSI SQL)
+query_size=16777216 # query size
+quote_ident_with_"=yes # " as identifier quote (ANSI SQL)
+quote_ident_with_[=no # [] as identifier quote
+quote_ident_with_`=no # ` as identifier quote
+quote_with_"=no # Allows ' and " as string markers
+recursive_subqueries=61 # recursive subqueries
+remember_end_space=no # Remembers end space in char()
+remember_end_space_varchar=yes # Remembers end space in varchar()
+rename_table=no # rename table
+right_outer_join=yes # right outer join
+rowid=no # Type for row id
+select_constants=yes # Select constants
+select_limit=no # LIMIT number of rows
+select_limit2=no # SELECT with LIMIT #,#
+select_string_size=32767 # constant string size in SELECT
+select_table_update=yes # Update with sub select
+select_without_from=no # SELECT without FROM
+server_version=6.0.1 # server version
+simple_joins=yes # ANSI SQL simple joins
+storage_of_float=round # Storage of float values
+subqueries=yes # subqueries
+table_alias=no # Table alias
+table_name_case=yes # case independent table names
+table_wildcard=yes # Select table_name.*
+temporary_table=no # temporary tables
+transactions=error # constant string size in where
+truncate_table=no # truncate
+type_extra_abstime=no # Type abstime
+type_extra_bfile=no # Type bfile
+type_extra_blob=yes # Type blob
+type_extra_bool=no # Type bool
+type_extra_box=no # Type box
+type_extra_byte=no # Type byte
+type_extra_char(1_arg)_binary=no # Type char(1 arg) binary
+type_extra_cidr=no # Type cidr
+type_extra_circle=no # Type circle
+type_extra_clob=no # Type clob
+type_extra_datetime=no # Type datetime
+type_extra_double=no # Type double
+type_extra_enum(1_arg)=no # Type enum(1 arg)
+type_extra_float(2_arg)=no # Type float(2 arg)
+type_extra_float4=no # Type float4
+type_extra_float8=no # Type float8
+type_extra_image=no # Type image
+type_extra_inet=no # Type inet
+type_extra_int(1_arg)_zerofill=no # Type int(1 arg) zerofill
+type_extra_int1=no # Type int1
+type_extra_int2=no # Type int2
+type_extra_int3=no # Type int3
+type_extra_int4=no # Type int4
+type_extra_int8=no # Type int8
+type_extra_int_auto_increment=no # Type int not null auto_increment
+type_extra_int_identity=no # Type int not null identity
+type_extra_int_unsigned=no # Type int unsigned
+type_extra_interval=no # Type interval
+type_extra_line=no # Type line
+type_extra_long=no # Type long
+type_extra_long_raw=no # Type long raw
+type_extra_long_varbinary=no # Type long varbinary
+type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
+type_extra_lseg=no # Type lseg
+type_extra_macaddr=no # Type macaddr
+type_extra_mediumint=no # Type mediumint
+type_extra_mediumtext=no # Type mediumtext
+type_extra_middleint=no # Type middleint
+type_extra_mlslabel=no # Type mlslabel
+type_extra_money=no # Type money
+type_extra_nclob=no # Type nclob
+type_extra_number=no # Type number
+type_extra_number(1_arg)=no # Type number(1 arg)
+type_extra_number(2_arg)=no # Type number(2 arg)
+type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg)
+type_extra_path=no # Type path
+type_extra_point=no # Type point
+type_extra_polygon=no # Type polygon
+type_extra_raw(1_arg)=no # Type raw(1 arg)
+type_extra_reltime=no # Type reltime
+type_extra_rowid=no # Type rowid
+type_extra_serial=no # Type serial
+type_extra_set(1_arg)=no # Type set(1 arg)
+type_extra_smalldatetime=no # Type smalldatetime
+type_extra_smallfloat=no # Type smallfloat
+type_extra_smallmoney=no # Type smallmoney
+type_extra_text=no # Type text
+type_extra_text(1_arg)=no # Type text(1 arg)
+type_extra_timespan=no # Type timespan
+type_extra_uint=no # Type uint
+type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
+type_extra_year=no # Type year
+type_odbc_bigint=no # Type bigint
+type_odbc_binary(1_arg)=no # Type binary(1 arg)
+type_odbc_datetime=no # Type datetime
+type_odbc_tinyint=no # Type tinyint
+type_odbc_varbinary(1_arg)=no # Type varbinary(1 arg)
+type_sql_bit=no # Type bit
+type_sql_bit(1_arg)=no # Type bit(1 arg)
+type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg)
+type_sql_boolean=no # Type boolean
+type_sql_char(1_arg)=yes # Type char(1 arg)
+type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
+type_sql_character(1_arg)=yes # Type character(1 arg)
+type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
+type_sql_date=yes # Type date
+type_sql_dec(2_arg)=yes # Type dec(2 arg)
+type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
+type_sql_double_precision=yes # Type double precision
+type_sql_float=yes # Type float
+type_sql_float(1_arg)=yes # Type float(1 arg)
+type_sql_int=yes # Type int
+type_sql_integer=yes # Type integer
+type_sql_interval_day=no # Type interval day
+type_sql_interval_day_to_hour=no # Type interval day to hour
+type_sql_interval_day_to_minute=no # Type interval day to minute
+type_sql_interval_day_to_second=no # Type interval day to second
+type_sql_interval_hour=no # Type interval hour
+type_sql_interval_hour_to_minute=no # Type interval hour to minute
+type_sql_interval_hour_to_second=no # Type interval hour to second
+type_sql_interval_minute=no # Type interval minute
+type_sql_interval_minute_to_second=no # Type interval minute to second
+type_sql_interval_month=no # Type interval month
+type_sql_interval_second=no # Type interval second
+type_sql_interval_year=no # Type interval year
+type_sql_interval_year_to_month=no # Type interval year to month
+type_sql_national_char_varying(1_arg)=yes # Type national char varying(1 arg)
+type_sql_national_character(1_arg)=yes # Type national character(1 arg)
+type_sql_national_character_varying(1_arg)=yes # Type national character varying(1 arg)
+type_sql_nchar(1_arg)=yes # Type nchar(1 arg)
+type_sql_nchar_varying(1_arg)=yes # Type nchar varying(1 arg)
+type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
+type_sql_real=yes # Type real
+type_sql_smallint=yes # Type smallint
+type_sql_time=yes # Type time
+type_sql_timestamp=yes # Type timestamp
+type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
+type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
+union=yes # union
+union_all=yes # union all
+union_all_incompat=yes # union all (incompatible lists)
+union_incompat=yes # union (incompatible lists)
+unique_in_create=yes # unique in create table
+unique_null_in_create=no # unique null in create
+views=no # views
+where_string_size=32767 # constant string size in where
diff --git a/sql-bench/limits/mysql.cfg b/sql-bench/limits/mysql.cfg
index a496bd7bf4c..feaa79e43e9 100644
--- a/sql-bench/limits/mysql.cfg
+++ b/sql-bench/limits/mysql.cfg
@@ -1,523 +1,7050 @@
-#This file is automaticly generated by crash-me 1.57
+#This file is automaticly generated by crash-me 1.61
NEG=yes # update of column= -column
+ ###< create table crash_q (a integer)
+ ###> OK
+ ###< insert into crash_q values(10)
+ ###> OK
+ ###< update crash_q set a=-a
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
Need_cast_for_null=no # Need to cast NULL for arithmetic
+ ### Check if numeric_null (NULL) is 'NULL'
alter_add_col=yes # Alter table add column
+ ###< alter table crash_q add d integer
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
alter_add_constraint=yes # Alter table add constraint
-alter_add_foreign_key=yes # Alter table add foreign key
+ ###< alter table crash_q add constraint c2 check(a > b)
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+alter_add_foreign_key=no # Alter table add foreign key
+ ###< alter table crash_q add constraint f1 foreign key(c1)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
+ ###< references crash_q1(c1)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'references crash_q1(c1)' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
alter_add_multi_col=yes # Alter table add many columns
+ ###< alter table crash_q add (f integer,g integer)
+ ###> OK
alter_add_primary_key=with constraint # Alter table add primary key
+ ###< alter table crash_q1 add constraint p1 primary key(c1)
+ ###> OK
alter_add_unique=yes # Alter table add unique
+ ###< alter table crash_q add constraint u1 unique(c1)
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
alter_alter_col=yes # Alter table alter column default
+ ###< alter table crash_q alter b set default 10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
alter_change_col=yes # Alter table change column
+ ###< alter table crash_q change a e char(50)
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
alter_drop_col=yes # Alter table drop column
+ ###< alter table crash_q drop column b
+ ###> OK
alter_drop_constraint=no # Alter table drop constraint
+ ###< alter table crash_q drop constraint c2
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint c2' at line 1
+ ###
+ ###< alter table crash_q drop constraint c2 restrict
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint c2 restrict' at line 1
alter_drop_foreign_key=with drop foreign key # Alter table drop foreign key
+ ###< alter table crash_q drop constraint f1
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint f1' at line 1
+ ###
+ ###< alter table crash_q drop constraint f1 restrict
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint f1 restrict' at line 1
+ ###
+ ###< alter table crash_q drop foreign key f1
+ ###> OK
alter_drop_primary_key=drop primary key # Alter table drop primary key
+ ###< alter table crash_q1 drop constraint p1 restrict
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint p1 restrict' at line 1
+ ###
+ ###< alter table crash_q1 drop primary key
+ ###> OK
alter_drop_unique=with drop key # Alter table drop unique
+ ###< alter table crash_q drop constraint u1
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint u1' at line 1
+ ###
+ ###< alter table crash_q drop constraint u1 restrict
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'constraint u1 restrict' at line 1
+ ###
+ ###< alter table crash_q drop key c1
+ ###> OK
alter_modify_col=yes # Alter table modify column
+ ###< alter table crash_q modify c1 CHAR(20)
+ ###> OK
alter_rename_table=yes # Alter table rename table
+ ###< alter table crash_q rename to crash_q1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
atomic_updates=no # atomic updates
+ ###< create table crash_q (a integer not null,primary key (a))
+ ###> OK
+ ###< insert into crash_q values (2)
+ ###> OK
+ ###< insert into crash_q values (3)
+ ###> OK
+ ###< insert into crash_q values (1)
+ ###> OK
+ ###< update crash_q set a=a+1
+ ###> execute error:Duplicate entry '3' for key 1
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as some queries didnt return OK, result is NO
automatic_rowid=_rowid # Automatic row id
+ ###< create table crash_q (a int not null, primary key(a))
+ ###> OK
+ ###< insert into crash_q values (1)
+ ###> OK
+ ###< select _rowid from crash_q
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
binary_numbers=no # binary numbers (0b1001)
+ ###< select 0b1001
+ ###> execute error:Unknown column '0b1001' in 'field list'
+ ###
+ ###As far as some queries didnt return OK, result is NO
binary_strings=no # binary strings (b'0110')
+ ###< select b'0110'
+ ###> execute error:Unknown column 'b' in 'field list'
+ ###
+ ###As far as some queries didnt return OK, result is NO
case_insensitive_strings=yes # Case insensitive compare
+ ###
+ ###<select b from crash_me where b = 'A'
+ ###>a
char_is_space_filled=no # char are space filled
+ ###
+ ###<select concat(b,b) from crash_me where b = 'a '
+ ###>aa
+ ###We expected 'a a ' but got 'aa'
column_alias=yes # Column alias
+ ###< select a as ab from crash_me
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
columns_in_group_by=+64 # number of columns in group by
+ ###We are trying (example with N=5):
+ ###create table crash_q (q1 integer,q2 integer,q3 integer,q4 integer,q5 integer)
+ ###insert into crash_q values(1,1,1,1,1)
+ ###insert into crash_q values(1,1,1,1,1)
+ ###select q1,q2,q3,q4,q5 from crash_q group by q1,q2,q3,q4,q5
columns_in_order_by=+64 # number of columns in order by
+ ###We are trying (example with N=5):
+ ###create table crash_q (q1 integer,q2 integer,q3 integer,q4 integer,q5 integer)
+ ###insert into crash_q values(1,1,1,1,1)
+ ###insert into crash_q values(1,1,1,1,1)
+ ###select * from crash_q order by q1,q2,q3,q4,q5
comment_#=yes # # as comment
+ ###< select * from crash_me # Testing of comments
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
comment_--=yes # -- as comment (ANSI)
+ ###< select * from crash_me -- Testing of comments
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
comment_/**/=yes # /* */ as comment
-comment_//=no # // as comment (ANSI)
+ ###< select * from crash_me /* Testing of comments */
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+comment_//=no # // as comment
+ ###< select * from crash_me // Testing of comments
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '// Testing of comments' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
compute=no # Compute
+ ###< select a from crash_me order by a compute sum(a) by a
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'compute sum(a) by a' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
connections=101 # Simultaneous connections (installation default)
-constraint_check=no # Column constraints
-constraint_check_table=no # Table constraints
+constraint_check=syntax only # Column constraints
+ ###< create table crash_q (a int check (a>0))
+ ###> OK
+ ###
+ ###< insert into crash_q values(0)
+ ###> OK
+ ###
+ ###< drop table crash_q
+ ###> OK
+constraint_check_named=syntax only # Named constraints
+ ###< create table crash_q (a int ,b int, constraint abc check (a>b))
+ ###> OK
+ ###
+ ###< insert into crash_q values(0,0)
+ ###> OK
+ ###
+ ###< drop table crash_q
+ ###> OK
+constraint_check_table=syntax only # Table constraints
+ ###< create table crash_q (a int ,b int, check (a>b))
+ ###> OK
+ ###
+ ###< insert into crash_q values(0,0)
+ ###> OK
+ ###
+ ###< drop table crash_q
+ ###> OK
constraint_null=yes # NULL constraint (SyBase style)
+ ###< create table crash_q (a int null)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
crash_me_safe=yes # crash me safe
-crash_me_version=1.57 # crash me version
+crash_me_version=1.61 # crash me version
create_default=yes # default value for column
+ ###< create table crash_q (q integer default 10 not null)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
create_default_func=no # default value function for column
+ ###< create table crash_q (q integer not null,q1 integer default (1+1))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1+1))' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
create_if_not_exists=yes # create table if not exists
+ ###< create table crash_q (q integer)
+ ###> OK
+ ###< create table if not exists crash_q (q integer)
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
create_index=yes # create index
+ ###< create index crash_q on crash_me (a)
+ ###> OK
create_schema=no # Create SCHEMA
+ ###< create schema crash_schema create table crash_q (a int) create table crash_q2(b int)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'schema crash_schema create table crash_q (a int) create table c
+ ###< drop schema crash_schema cascade
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'schema crash_schema cascade' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
create_table_select=yes # create table from select
+ ###< create table crash_q SELECT * from crash_me
+ ###> OK
cross_join=yes # cross join (same as from a,b)
+ ###< select crash_me.a from crash_me cross join crash_me3
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
date_as_string=yes # String functions on date columns
+ ###< create table crash_me2 (a date not null)
+ ###> OK
+ ###< insert into crash_me2 values ('1998-03-03')
+ ###> OK
+ ###
+ ###<select left(a,4) from crash_me2
+ ###>1998
+ ###
+ ###< drop table crash_me2
+ ###> OK
+date_format_EUR=error # Supports DD.MM.YYYY (EUR) format
+ ###< insert into crash_me_d(a) values ('16.08.1963')
+ ###> OK
+ ###
+ ###<select a from crash_me_d
+ ###>0000-00-00
+ ###We expected '1963-08-16' but got '0000-00-00'
+ ###
+ ###< delete from crash_me_d
+ ###> OK
+date_format_EUR_with_date=error # Supports DATE 'DD.MM.YYYY' (EUR) format
+ ###< insert into crash_me_d(a) values (DATE '16.08.1963')
+ ###> OK
+ ###
+ ###<select a from crash_me_d
+ ###>0000-00-00
+ ###We expected '1963-08-16' but got '0000-00-00'
+ ###
+ ###< delete from crash_me_d
+ ###> OK
+date_format_ISO=yes # Supports YYYY-MM-DD (ISO) format
+ ###< insert into crash_me_d(a) values ('1963-08-16')
+ ###> OK
+ ###
+ ###<select a from crash_me_d
+ ###>1963-08-16
+ ###
+ ###< delete from crash_me_d
+ ###> OK
+date_format_ISO_with_date=yes # Supports DATE 'YYYY-MM-DD' (ISO) format
+ ###< insert into crash_me_d(a) values (DATE '1963-08-16')
+ ###> OK
+ ###
+ ###<select a from crash_me_d
+ ###>1963-08-16
+ ###
+ ###< delete from crash_me_d
+ ###> OK
+date_format_USA=error # Supports MM/DD/YYYY format
+ ###< insert into crash_me_d(a) values ('08/16/1963')
+ ###> OK
+ ###
+ ###<select a from crash_me_d
+ ###>0000-00-00
+ ###We expected '1963-08-16' but got '0000-00-00'
+ ###
+ ###< delete from crash_me_d
+ ###> OK
+date_format_USA_with_date=error # Supports DATE 'MM/DD/YYYY' format
+ ###< insert into crash_me_d(a) values (DATE '08/16/1963')
+ ###> OK
+ ###
+ ###<select a from crash_me_d
+ ###>0000-00-00
+ ###We expected '1963-08-16' but got '0000-00-00'
+ ###
+ ###< delete from crash_me_d
+ ###> OK
+date_format_YYYYMMDD=yes # Supports YYYYMMDD format
+ ###< insert into crash_me_d(a) values ('19630816')
+ ###> OK
+ ###
+ ###<select a from crash_me_d
+ ###>1963-08-16
+ ###
+ ###< delete from crash_me_d
+ ###> OK
+date_format_YYYYMMDD_with_date=yes # Supports DATE 'YYYYMMDD' format
+ ###< insert into crash_me_d(a) values (DATE '19630816')
+ ###> OK
+ ###
+ ###<select a from crash_me_d
+ ###>1963-08-16
+ ###
+ ###< delete from crash_me_d
+ ###> OK
+date_format_inresult=iso # Date format in result
+ ###< insert into crash_me_d values( sysdate() )
+ ###> OK
+ ###
+ ###< select a from crash_me_d
+ ###> 2003-08-27
+ ###< delete from crash_me_d
+ ###> OK
date_infinity=error # Supports 'infinity dates
+ ###< create table crash_me2 (a date not null)
+ ###> OK
+ ###< insert into crash_me2 values ('infinity')
+ ###> OK
+ ###
+ ###<select a from crash_me2
+ ###>0000-00-00
+ ###We expected 'infinity' but got '0000-00-00'
+ ###
+ ###< drop table crash_me2
+ ###> OK
date_last=yes # Supports 9999-12-31 dates
+ ###< create table crash_me2 (a date not null)
+ ###> OK
+ ###< insert into crash_me2 values ('9999-12-31')
+ ###> OK
+ ###
+ ###<select a from crash_me2
+ ###>9999-12-31
+ ###
+ ###< drop table crash_me2
+ ###> OK
date_one=yes # Supports 0001-01-01 dates
+ ###< create table crash_me2 (a date not null)
+ ###> OK
+ ###< insert into crash_me2 values ('0001-01-01')
+ ###> OK
+ ###
+ ###<select a from crash_me2
+ ###>0001-01-01
+ ###
+ ###< drop table crash_me2
+ ###> OK
date_with_YY=yes # Supports YY-MM-DD 2000 compilant dates
+ ###< create table crash_me2 (a date not null)
+ ###> OK
+ ###< insert into crash_me2 values ('98-03-03')
+ ###> OK
+ ###
+ ###<select a from crash_me2
+ ###>1998-03-03
+ ###
+ ###< drop table crash_me2
+ ###> OK
+ ###
+ ###< create table crash_me2 (a date not null)
+ ###> OK
+ ###< insert into crash_me2 values ('10-03-03')
+ ###> OK
+ ###
+ ###<select a from crash_me2
+ ###>2010-03-03
+ ###
+ ###< drop table crash_me2
+ ###> OK
date_zero=yes # Supports 0000-00-00 dates
+ ###< create table crash_me2 (a date not null)
+ ###> OK
+ ###< insert into crash_me2 values ('0000-00-00')
+ ###> OK
+ ###
+ ###<select a from crash_me2
+ ###>0000-00-00
+ ###
+ ###< drop table crash_me2
+ ###> OK
domains=no # Domains (ANSI SQL)
+ ###< create domain crash_d as varchar(10) default 'Empty' check (value <> 'abcd')
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'domain crash_d as varchar(10) default 'Empty' check (value <> '
+ ###< create table crash_q(a crash_d, b int)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'crash_d, b int)' at line 1
+ ###< insert into crash_q(a,b) values('xyz',10)
+ ###> execute error:Table 'test.crash_q' doesn't exist
+ ###< insert into crash_q(b) values(10)
+ ###> execute error:Table 'test.crash_q' doesn't exist
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###< drop domain crash_d
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'domain crash_d' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
dont_require_cast_to_float=yes # No need to cast from integer to float
+ ###< select exp(1)
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
double_quotes=yes # Double '' as ' in strings
+ ###
+ ###<select 'Walker''s'
+ ###>Walker's
drop_if_exists=yes # drop table if exists
+ ###< create table crash_q (q integer)
+ ###> OK
+ ###< drop table if exists crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
drop_index=with 'ON' # drop index
+ ###< drop index crash_q
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
+ ###
+ ###< drop index crash_q from crash_me
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'from crash_me' at line 1
+ ###
+ ###< drop index crash_q on crash_me
+ ###> OK
drop_requires_cascade=no # drop table require cascade/restrict
+ ###< create table crash_me (a integer not null)
+ ###> OK
+ ###< drop table crash_me
+ ###> OK
drop_restrict=yes # drop table with cascade/restrict
+ ###< create table crash_q (a int)
+ ###> OK
+ ###< drop table crash_q restrict
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
end_colon=yes # allows end ';'
+ ###< select * from crash_me;
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
except=no # except
+ ###< select * from crash_me except select * from crash_me3
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me3' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
except_all=no # except all
+ ###< select * from crash_me except all select * from crash_me3
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me3' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
except_all_incompat=no # except all (incompatible lists)
+ ###< select * from crash_me except all select * from crash_me2
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me2' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
except_incompat=no # except (incompatible lists)
+ ###< select * from crash_me except select * from crash_me2
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me2' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
+field_name_case=yes # case independent field names
+ ###< create table crash_q (q integer)
+ ###> OK
+ ###< insert into crash_q(Q) values (1)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
float_int_expr=yes # mixing of integer and float in expression
-foreign_key=no # foreign keys
-foreign_key_syntax=yes # foreign key syntax
+ ###< select 1+1.0
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+foreign_key=syntax only # foreign keys
+ ###< create table crash_me_qf (a integer not null,primary key (a))
+ ###> OK
+ ###
+ ###< create table crash_me_qf2 (a integer not null,foreign key (a) references crash_me_qf (a))
+ ###> OK
+ ###
+ ###< insert into crash_me_qf values (1)
+ ###> OK
+ ###
+ ###< insert into crash_me_qf2 values (2)
+ ###> OK
+ ###
+ ###< drop table crash_me_qf2
+ ###> OK
+ ###
+ ###< drop table crash_me_qf
+ ###> OK
full_outer_join=no # full outer join
+ ###< select crash_me.a from crash_me full join crash_me2 ON
+ ### crash_me.a=crash_me2.a
+ ###> execute error:Unknown table 'crash_me' in field list
+ ###
+ ###As far as some queries didnt return OK, result is NO
func_extra_!=yes # Function NOT as '!' in SELECT
+ ###
+ ###<select ! 1
+ ###>0
func_extra_%=yes # Function MOD as %
+ ###
+ ###<select 10%7
+ ###>3
func_extra_&=yes # Function & (bitwise and)
+ ###
+ ###<select 5 & 3
+ ###>1
func_extra_&&=yes # Function AND as '&&'
+ ###
+ ###<select 1=1 && 2=2
+ ###>1
func_extra_<>=yes # Function <> in SELECT
+ ###
+ ###<select 1<>1
+ ###>0
func_extra_==yes # Function =
+ ###
+ ###<select (1=1)
+ ###>1
func_extra_add_months=no # Function ADD_MONTHS
+ ###
+ ###<select add_months('1997-01-01',1) from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('1997-01-01',1) from crash_me_d' at line 1
+func_extra_adddate=no # Function ADDDATE
+ ###
+ ###<select ADDDATE('2002-12-01',3) from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '3) from crash_me_d' at line 1
+func_extra_addtime=no # Function ADDTIME
+ ###
+ ###<select ADDTIME('20:02:12','00:00:03')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('20:02:12','00:00:03')' at line 1
+func_extra_alpha=no # Function ALPHA
+ ###
+ ###<select alpha('Aâ',2)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('Aâ',2)' at line 1
func_extra_and_or=yes # Function AND and OR in SELECT
+ ###
+ ###<select 1=1 AND 2=2
+ ###>1
func_extra_ascii_char=no # Function ASCII_CHAR
+ ###
+ ###<select ASCII_CHAR(65)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(65)' at line 1
func_extra_ascii_code=no # Function ASCII_CODE
+ ###
+ ###<select ASCII_CODE('A')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('A')' at line 1
+func_extra_ascii_string=error # Function ASCII in string cast
+ ###
+ ###<select ascii('a')
+ ###>97
+ ###We expected 'a' but got '97'
func_extra_atn2=no # Function ATN2
+ ###
+ ###<select atn2(1,0)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1,0)' at line 1
func_extra_auto_num2string=yes # Function automatic num->string convert
+ ###
+ ###<select concat('a',2)
+ ###>a2
func_extra_auto_string2num=yes # Function automatic string->num convert
+ ###
+ ###<select '1'+2
+ ###>3
func_extra_between=yes # Function BETWEEN in SELECT
+ ###
+ ###<select 5 between 4 and 6
+ ###>1
func_extra_binary_shifts=yes # Function << and >> (bitwise shifts)
+ ###
+ ###<select (1 << 4) >> 2
+ ###>4
func_extra_bit_count=yes # Function BIT_COUNT
-func_extra_ceil=no # Function CEIL
+ ###
+ ###<select bit_count(5)
+ ###>2
+func_extra_ceil=yes # Function CEIL
+ ###
+ ###<select ceil(-4.5)
+ ###>-4
+func_extra_char_date=no # Function CHAR (conversation date)
+ ###
+ ###<select CHAR(a,EUR) from crash_me_d
+ ###> execute failed:Unknown column 'EUR' in 'field list'
func_extra_charindex=no # Function CHARINDEX
+ ###
+ ###<select charindex('a','crash')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('a','crash')' at line 1
func_extra_chr=no # Function CHR
+ ###
+ ###<select CHR(65)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(65)' at line 1
+func_extra_chr_str=no # Function CHR (any type to string)
+ ###
+ ###<select CHR(67)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(67)' at line 1
func_extra_concat_as_+=error # Function concatenation with +
+ ###
+ ###<select 'abc' + 'def'
+ ###>0
+ ###We expected 'abcdef' but got '0'
func_extra_concat_list=yes # Function CONCAT(list)
+ ###
+ ###<select concat('a','b','c','d')
+ ###>abcd
func_extra_convert=no # Function CONVERT
+ ###
+ ###<select convert(CHAR,5)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '5)' at line 1
func_extra_cosh=no # Function COSH
+ ###
+ ###<select cosh(0)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(0)' at line 1
+func_extra_date=no # Function DATE
+ ###
+ ###<select date('1963-08-16') from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('1963-08-16') from crash_me_d' at line 1
func_extra_date_format=yes # Function DATE_FORMAT
+ ###
+ ###<select date_format('1997-01-02 03:04:05','M W D Y y m d h i s w') from crash_me_d
+ ###>M W D Y y m d h i s w
func_extra_dateadd=no # Function DATEADD
+ ###
+ ###<select dateadd(day,3,'1997-11-30') from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(day,3,'1997-11-30') from crash_me_d' at line 1
func_extra_datediff=no # Function DATEDIFF
+ ###
+ ###<select datediff(month,'Oct 21 1997','Nov 30 1997') from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(month,'Oct 21 1997','Nov 30 1997') from crash_me_d' at line 1
+func_extra_datediff2arg=no # Function DATEDIFF (2 arg)
+ ###
+ ###<select DATEDIFF('2002-12-04','2002-12-01') from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('2002-12-04','2002-12-01') from crash_me_d' at line 1
func_extra_datename=no # Function DATENAME
+ ###
+ ###<select datename(month,'Nov 30 1997') from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(month,'Nov 30 1997') from crash_me_d' at line 1
func_extra_datepart=no # Function DATEPART
+ ###
+ ###<select datepart(month,'July 20 1997') from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(month,'July 20 1997') from crash_me_d' at line 1
+func_extra_day=no # Function DAY
+ ###
+ ###<select DAY('2002-12-01') from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('2002-12-01') from crash_me_d' at line 1
+func_extra_decode=no # Function DECODE
+ ###
+ ###<select DECODE('S-103','T72',1,'S-103',2,'Leopard',3)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '1,'S-103',2,'Leopard',3)' at line 1
+func_extra_ebcdic_string=no # Function EBCDIC in string cast
+ ###
+ ###<select ebcdic('a')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('a')' at line 1
func_extra_elt=yes # Function ELT
+ ###
+ ###<select elt(2,'ONE','TWO','THREE')
+ ###>TWO
func_extra_encrypt=yes # Function ENCRYPT
+ ###
+ ###<select encrypt('hello')
+ ###>tHrzZO8Aq1FG6
+func_extra_expand2arg=no # Function EXPAND
+ ###
+ ###<select expand('abcd',6)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abcd',6)' at line 1
func_extra_field=yes # Function FIELD
+ ###
+ ###<select field('IBM','NCA','ICL','SUN','IBM','DIGITAL')
+ ###>4
+func_extra_fixed=no # Function FIXED
+ ###
+ ###<select fixed(222.6666,10,2)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(222.6666,10,2)' at line 1
+func_extra_float=no # Function FLOAT
+ ###
+ ###<select float(6666.66,4)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'float(6666.66,4)' at line 1
func_extra_format=yes # Function FORMAT
+ ###
+ ###<select format(1234.5555,2)
+ ###>1,234.56
func_extra_from_days=yes # Function FROM_DAYS
+ ###
+ ###<select from_days(729024) from crash_me_d
+ ###>1996-01-01
func_extra_from_unixtime=yes # Function FROM_UNIXTIME
+ ###
+ ###<select from_unixtime(0) from crash_me_d
+ ###>1970-01-01 02:00:00
func_extra_getdate=no # Function GETDATE
+ ###
+ ###<select getdate()
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '()' at line 1
func_extra_greatest=yes # Function GREATEST
+ ###
+ ###<select greatest('HARRY','HARRIOT','HAROLD')
+ ###>HARRY
+func_extra_hex=yes # Function HEX
+ ###
+ ###<select HEX('A')
+ ###>41
func_extra_if=yes # Function IF
+ ###
+ ###<select if(5,6,7)
+ ###>6
func_extra_in_num=yes # Function IN on numbers in SELECT
+ ###
+ ###<select 2 in (3,2,5,9,5,1)
+ ###>1
func_extra_in_str=yes # Function IN on strings in SELECT
+ ###
+ ###<select 'monty' in ('david','monty','allan')
+ ###>1
+func_extra_index=no # Function INDEX
+ ###
+ ###<select index('abcdefg','cd',1,1)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'index('abcdefg','cd',1,1)' at line 1
func_extra_initcap=no # Function INITCAP
+ ###
+ ###<select initcap('the soap')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('the soap')' at line 1
func_extra_instr=yes # Function LOCATE as INSTR
+ ###
+ ###<select instr('hello','ll')
+ ###>3
func_extra_instr_oracle=no # Function INSTR (Oracle syntax)
+ ###
+ ###<select INSTR('CORPORATE FLOOR','OR',3,2)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '3,2)' at line 1
func_extra_instrb=no # Function INSTRB
+ ###
+ ###<select INSTRB('CORPORATE FLOOR','OR',5,2)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('CORPORATE FLOOR','OR',5,2)' at line 1
func_extra_interval=yes # Function INTERVAL
+ ###
+ ###<select interval(55,10,20,30,40,50,60,70,80,90,100)
+ ###>5
func_extra_last_day=no # Function LAST_DAY
+ ###
+ ###<select last_day('1997-04-01') from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('1997-04-01') from crash_me_d' at line 1
func_extra_last_insert_id=yes # Function LAST_INSERT_ID
+ ###
+ ###<select last_insert_id()
+ ###>0
func_extra_least=yes # Function LEAST
+ ###
+ ###<select least('HARRY','HARRIOT','HAROLD')
+ ###>HAROLD
+func_extra_length=error # Function LENGTH
+ ###
+ ###<select length(1)
+ ###>1
+ ###We expected '2' but got '1'
func_extra_lengthb=no # Function LENGTHB
+ ###
+ ###<select lengthb('CANDIDE')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('CANDIDE')' at line 1
+func_extra_lfill3arg=no # Function LFILL (3 arg)
+ ###
+ ###<select lfill('abcd','.',6)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abcd','.',6)' at line 1
func_extra_like=yes # Function LIKE in SELECT
+ ###
+ ###<select 'a' like 'a%'
+ ###>1
func_extra_like_escape=yes # Function LIKE ESCAPE in SELECT
-func_extra_ln=no # Function LN
-func_extra_log(m_n)=no # Function LOG(m,n)
+ ###
+ ###<select '%' like 'a%' escape 'a'
+ ###>1
+func_extra_ln=yes # Function LN
+ ###
+ ###<select ln(95)
+ ###>4.553877
+func_extra_log(m_n)=yes # Function LOG(m,n)
+ ###
+ ###<select log(10,100)
+ ###>2.000000
func_extra_logn=no # Function LOGN
+ ###
+ ###<select logn(2)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(2)' at line 1
func_extra_lpad=yes # Function LPAD
+ ###
+ ###<select lpad('hi',4,'??')
+ ###>??hi
+func_extra_ltrim2arg=no # Function LTRIM (2 arg)
+ ###
+ ###<select ltrim('..abcd..','.')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ''.')' at line 1
+func_extra_makedate=no # Function MAKEDATE
+ ###
+ ###<select MAKEDATE(1963,228) from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1963,228) from crash_me_d' at line 1
+func_extra_maketime=no # Function MAKETIME
+ ###
+ ###<select MAKETIME(20,02,12)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(20,02,12)' at line 1
+func_extra_mapchar=no # Function MAPCHAR
+ ###
+ ###<select mapchar('Aâ')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('Aâ')' at line 1
func_extra_mdy=no # Function MDY
+ ###
+ ###<select mdy(7,1,1998) from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(7,1,1998) from crash_me_d' at line 1
+func_extra_microsecond=no # Function MICROSECOND
+ ###
+ ###<select MICROSECOND('19630816200212111111')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('19630816200212111111')' at line 1
func_extra_mid=yes # Function SUBSTRING as MID
+ ###
+ ###<select mid('hello',3,2)
+ ###>ll
func_extra_months_between=no # Function MONTHS_BETWEEN
+ ###
+ ###<select months_between('1997-02-02','1997-01-01') from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('1997-02-02','1997-01-01') from crash_me_d' at line 1
+func_extra_noround=no # Function NOROUND
+ ###< select noround(22.6)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(22.6)' at line 1
func_extra_not=yes # Function NOT in SELECT
+ ###
+ ###<select not 0
+ ###>1
func_extra_not_between=yes # Function NOT BETWEEN in SELECT
+ ###
+ ###<select 5 not between 4 and 6
+ ###>0
func_extra_not_like=yes # Function NOT LIKE in SELECT
+ ###
+ ###<select 'a' not like 'a%'
+ ###>0
+func_extra_num=no # Function NUM
+ ###
+ ###<select NUM('2123')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('2123')' at line 1
func_extra_odbc_convert=no # Function ODBC CONVERT
+ ###
+ ###<select convert(5,SQL_CHAR)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SQL_CHAR)' at line 1
func_extra_password=yes # Function PASSWORD
+ ###
+ ###<select password('hello')
+ ###>70de51425df9d787
func_extra_paste=no # Function PASTE
+ ###
+ ###<select paste('ABCDEFG',3,2,'1234')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('ABCDEFG',3,2,'1234')' at line 1
func_extra_patindex=no # Function PATINDEX
+ ###
+ ###<select patindex('%a%','crash')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('%a%','crash')' at line 1
func_extra_period_add=yes # Function PERIOD_ADD
+ ###
+ ###<select period_add(9602,-12) from crash_me_d
+ ###>199502
func_extra_period_diff=yes # Function PERIOD_DIFF
+ ###
+ ###<select period_diff(199505,199404) from crash_me_d
+ ###>13
func_extra_pow=yes # Function POW
+ ###
+ ###<select pow(3,2)
+ ###>9.000000
func_extra_range=no # Function RANGE
+ ###
+ ###<select range(a)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a)' at line 1
func_extra_regexp=yes # Function REGEXP in SELECT
+ ###
+ ###<select 'a' regexp '^(a|b)*$'
+ ###>1
+func_extra_replace2arg=no # Function REPLACE (2 arg)
+ ###
+ ###<select replace('AbCd','bC')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
func_extra_replicate=no # Function REPLICATE
+ ###
+ ###<select replicate('a',5)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('a',5)' at line 1
func_extra_reverse=yes # Function REVERSE
+ ###
+ ###<select reverse('abcd')
+ ###>dcba
+func_extra_rfill3arg=no # Function RFILL (3 arg)
+ ###
+ ###<select rfill('abcd','.',6)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abcd','.',6)' at line 1
func_extra_root=no # Function ROOT
+ ###
+ ###<select root(4)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(4)' at line 1
func_extra_round1=yes # Function ROUND(1 arg)
+ ###
+ ###<select round(5.63)
+ ###>6
func_extra_rpad=yes # Function RPAD
+ ###
+ ###<select rpad('hi',4,'??')
+ ###>hi??
+func_extra_rpad4arg=no # Function RPAD (4 arg)
+ ###
+ ###<select rpad('abcd',2,'+-',8)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '8)' at line 1
+func_extra_rtrim2arg=no # Function RTRIM (2 arg)
+ ###
+ ###<select rtrim('..abcd..','.')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ''.')' at line 1
func_extra_sec_to_time=yes # Function SEC_TO_TIME
+ ###
+ ###<select sec_to_time(5001)
+ ###>01:23:21
func_extra_sinh=no # Function SINH
+ ###
+ ###<select sinh(1)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1)' at line 1
func_extra_str=no # Function STR
+ ###
+ ###<select str(123.45,5,1)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(123.45,5,1)' at line 1
func_extra_strcmp=yes # Function STRCMP
+ ###
+ ###<select strcmp('abc','adc')
+ ###>-1
func_extra_stuff=no # Function STUFF
+ ###
+ ###<select stuff('abc',2,3,'xyz')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abc',2,3,'xyz')' at line 1
+func_extra_subdate=no # Function SUBDATE
+ ###
+ ###<select SUBDATE('2002-12-04',3) from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '3) from crash_me_d' at line 1
+func_extra_substr2arg=no # Function SUBSTR (2 arg)
+ ###
+ ###<select substr('abcd',2)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abcd',2)' at line 1
+func_extra_substr3arg=no # Function SUBSTR (3 arg)
+ ###
+ ###<select substr('abcd',2,2)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abcd',2,2)' at line 1
func_extra_substrb=no # Function SUBSTRB
+ ###
+ ###<select SUBSTRB('ABCDEFG',5,4.2)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('ABCDEFG',5,4.2)' at line 1
func_extra_substring_index=yes # Function SUBSTRING_INDEX
+ ###
+ ###<select substring_index('www.tcx.se','.',-2)
+ ###>tcx.se
+func_extra_subtime=no # Function SUBTIME
+ ###
+ ###<select SUBTIME('20:02:15','00:00:03')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('20:02:15','00:00:03')' at line 1
func_extra_sysdate=yes # Function SYSDATE
+ ###
+ ###<select sysdate()
+ ###>2003-08-27 19:55:21
func_extra_tail=no # Function TAIL
+ ###
+ ###<select tail('ABCDEFG',3)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('ABCDEFG',3)' at line 1
func_extra_tanh=no # Function TANH
+ ###
+ ###<select tanh(1)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1)' at line 1
+func_extra_time=no # Function TIME
+ ###
+ ###<select time('20:02:12')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('20:02:12')' at line 1
func_extra_time_to_sec=yes # Function TIME_TO_SEC
+ ###
+ ###<select time_to_sec('01:23:21')
+ ###>5001
+func_extra_timediff=no # Function TIMEDIFF
+ ###
+ ###<select TIMEDIFF('20:02:15','20:02:12')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('20:02:15','20:02:12')' at line 1
+func_extra_timestamp=no # Function TIMESTAMP
+ ###
+ ###<select timestamp('19630816','00200212')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('19630816','00200212')' at line 1
func_extra_to_days=yes # Function TO_DAYS
+ ###
+ ###<select to_days('1996-01-01') from crash_me_d
+ ###>729024
func_extra_translate=no # Function TRANSLATE
+ ###
+ ###<select translate('abc','bc','de')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abc','bc','de')' at line 1
+func_extra_trim1arg=yes # Function TRIM (1 arg)
+ ###
+ ###<select trim(' abcd ')
+ ###>abcd
+func_extra_trim2arg=no # Function TRIM (2 arg)
+ ###
+ ###<select trim('..abcd..','.')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ''.')' at line 1
func_extra_trim_many_char=error # Function TRIM; Many char extension
+ ###
+ ###<select trim(':!' FROM ':abc!')
+ ###>:abc!
+ ###We expected 'abc' but got ':abc!'
func_extra_trim_substring=yes # Function TRIM; Substring extension
+ ###
+ ###<select trim('cb' FROM 'abccb')
+ ###>abc
func_extra_trunc=no # Function TRUNC
+ ###
+ ###<select trunc(18.18,-1)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(18.18,-1)' at line 1
+func_extra_trunc1arg=no # Function TRUNC (1 arg)
+ ###
+ ###<select trunc(222.6)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(222.6)' at line 1
func_extra_uid=no # Function UID
+ ###
+ ###<select uid
+ ###> execute failed:Unknown column 'uid' in 'field list'
func_extra_unix_timestamp=yes # Function UNIX_TIMESTAMP
+ ###
+ ###<select unix_timestamp()
+ ###>1062003321
func_extra_userenv=no # Function USERENV
+ ###
+ ###<select userenv
+ ###> execute failed:Unknown column 'userenv' in 'field list'
+func_extra_value=no # Function VALUE
+ ###
+ ###<select value(NULL,'WALRUS')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(NULL,'WALRUS')' at line 1
func_extra_version=yes # Function VERSION
+ ###
+ ###<select version()
+ ###>4.0.15-debug-log
func_extra_weekday=yes # Function WEEKDAY
+ ###
+ ###<select weekday('1997-11-29') from crash_me_d
+ ###>5
+func_extra_weekofyear=no # Function WEEKOFYEAR
+ ###
+ ###<select WEEKOFYEAR('1963-08-16') from crash_me_d
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('1963-08-16') from crash_me_d' at line 1
func_extra_|=yes # Function | (bitwise or)
+ ###
+ ###<select 1 | 2
+ ###>3
func_extra_||=yes # Function OR as '||'
+ ###
+ ###<select 1=0 || 1=1
+ ###>1
func_extra_~*=no # Function ~* (case insensitive compare)
+ ###
+ ###<select 'hi' ~* 'HI'
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '~* 'HI'' at line 1
func_odbc_abs=yes # Function ABS
+ ###
+ ###<select abs(-5)
+ ###>5
func_odbc_acos=yes # Function ACOS
+ ###
+ ###<select acos(0)
+ ###>1.570796
func_odbc_ascii=yes # Function ASCII
+ ###
+ ###<select ASCII('A')
+ ###>65
func_odbc_asin=yes # Function ASIN
+ ###
+ ###<select asin(1)
+ ###>1.570796
func_odbc_atan=yes # Function ATAN
+ ###
+ ###<select atan(1)
+ ###>0.785398
func_odbc_atan2=yes # Function ATAN2
+ ###
+ ###<select atan2(1,0)
+ ###>1.570796
func_odbc_ceiling=yes # Function CEILING
+ ###
+ ###<select ceiling(-4.5)
+ ###>-4
func_odbc_char=yes # Function CHAR
+ ###
+ ###<select CHAR(65)
+ ###>A
func_odbc_concat=yes # Function CONCAT(2 arg)
+ ###
+ ###<select concat('a','b')
+ ###>ab
func_odbc_cos=yes # Function COS
+ ###
+ ###<select cos(0)
+ ###>1.000000
func_odbc_cot=yes # Function COT
+ ###
+ ###<select cot(1)
+ ###>0.64209262
func_odbc_curdate=yes # Function CURDATE
+ ###
+ ###<select curdate()
+ ###>2003-08-27
func_odbc_curtime=yes # Function CURTIME
+ ###
+ ###<select curtime()
+ ###>19:55:21
func_odbc_database=yes # Function DATABASE
+ ###
+ ###<select database()
+ ###>test
func_odbc_dayname=yes # Function DAYNAME
+ ###< insert into crash_me_d values('1997-02-01')
+ ###
+ ###<select dayname(a) from crash_me_d
+ ###>Saturday
func_odbc_dayofmonth=yes # Function DAYOFMONTH
+ ###< insert into crash_me_d values('1997-02-01')
+ ###
+ ###<select dayofmonth(a) from crash_me_d
+ ###>1
func_odbc_dayofweek=yes # Function DAYOFWEEK
+ ###< insert into crash_me_d values('1997-02-01')
+ ###
+ ###<select dayofweek(a) from crash_me_d
+ ###>7
func_odbc_dayofyear=yes # Function DAYOFYEAR
+ ###< insert into crash_me_d values('1997-02-01')
+ ###
+ ###<select dayofyear(a) from crash_me_d
+ ###>32
func_odbc_degrees=yes # Function DEGREES
+ ###
+ ###<select degrees(6.283185)
+ ###>359.99998239991
func_odbc_difference=no # Function DIFFERENCE()
+ ###
+ ###<select difference('abc','abe')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abc','abe')' at line 1
+ ###
+ ###<select {fn difference('abc','abe') }
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '('abc','abe') }' at line 1
func_odbc_exp=yes # Function EXP
+ ###
+ ###<select exp(1.0)
+ ###>2.718282
func_odbc_floor=yes # Function FLOOR
+ ###
+ ###<select floor(2.5)
+ ###>2
func_odbc_fn_left=yes # Function ODBC syntax LEFT & RIGHT
+ ###
+ ###<select { fn LEFT( { fn RIGHT('abcd',2) },1) }
+ ###>c
func_odbc_hour=yes # Function HOUR
+ ###< insert into crash_me_t values(20:08:16)
+ ###
+ ###<select hour('12:13:14')
+ ###>12
func_odbc_hour_time=yes # Function ANSI HOUR
+ ###< insert into crash_me_t values(20:08:16)
+ ###
+ ###<select hour(TIME '12:13:14')
+ ###>12
func_odbc_ifnull=yes # Function IFNULL
+ ###
+ ###<select ifnull(2,3)
+ ###>2
func_odbc_insert=yes # Function INSERT
+ ###
+ ###<select insert('abcd',2,2,'ef')
+ ###>aefd
func_odbc_lcase=yes # Function LCASE
+ ###
+ ###<select lcase('ABC')
+ ###>abc
func_odbc_left=yes # Function LEFT
+ ###
+ ###<select left('abcd',2)
+ ###>ab
func_odbc_length=yes # Function REAL LENGTH
+ ###
+ ###<select length('abcd ')
+ ###>5
func_odbc_length_without_space=error # Function ODBC LENGTH
+ ###
+ ###<select length('abcd ')
+ ###>5
+ ###We expected '4' but got '5'
+ ###
+ ###<select {fn length('abcd ') }
+ ###>5
+ ###We expected '4' but got '5'
func_odbc_locate_2=yes # Function LOCATE(2 arg)
+ ###
+ ###<select locate('bcd','abcd')
+ ###>2
func_odbc_locate_3=yes # Function LOCATE(3 arg)
+ ###
+ ###<select locate('bcd','abcd',3)
+ ###>0
func_odbc_log=yes # Function LOG
+ ###
+ ###<select log(2)
+ ###>0.693147
func_odbc_log10=yes # Function LOG10
+ ###
+ ###<select log10(10)
+ ###>1.000000
func_odbc_ltrim=yes # Function LTRIM
+ ###
+ ###<select ltrim(' abcd')
+ ###>abcd
func_odbc_minute=yes # Function MINUTE
+ ###< insert into crash_me_t values(20:08:16)
+ ###
+ ###<select minute('12:13:14')
+ ###>13
func_odbc_mod=yes # Function MOD
+ ###
+ ###<select mod(11,7)
+ ###>4
func_odbc_month=yes # Function MONTH
+ ###< insert into crash_me_d values('1997-02-01')
+ ###
+ ###<select month(a) from crash_me_d
+ ###>2
func_odbc_monthname=yes # Function MONTHNAME
+ ###< insert into crash_me_d values('1997-02-01')
+ ###
+ ###<select monthname(a) from crash_me_d
+ ###>February
func_odbc_now=yes # Function NOW
+ ###
+ ###<select now()
+ ###>2003-08-27 19:55:21
func_odbc_pi=yes # Function PI
+ ###
+ ###<select pi()
+ ###>3.141593
func_odbc_power=yes # Function POWER
+ ###
+ ###<select power(2,4)
+ ###>16.000000
func_odbc_quarter=yes # Function QUARTER
+ ###< insert into crash_me_d values('1997-02-01')
+ ###
+ ###<select quarter(a) from crash_me_d
+ ###>1
func_odbc_radians=yes # Function RADIANS
+ ###
+ ###<select radians(360)
+ ###>6.2831853071796
func_odbc_rand=yes # Function RAND
+ ###
+ ###<select rand(1)
+ ###>0.40540353712198
func_odbc_repeat=yes # Function REPEAT
+ ###
+ ###<select repeat('ab',3)
+ ###>ababab
func_odbc_replace=yes # Function REPLACE
+ ###
+ ###<select replace('abbaab','ab','ba')
+ ###>bababa
func_odbc_right=yes # Function RIGHT
+ ###
+ ###<select right('abcd',2)
+ ###>cd
func_odbc_round=yes # Function ROUND(2 arg)
+ ###
+ ###<select round(5.63,2)
+ ###>5.63
func_odbc_rtrim=yes # Function RTRIM
+ ###
+ ###<select rtrim(' abcd ')
+ ###> abcd
func_odbc_second=yes # Function SECOND
+ ###< insert into crash_me_t values(20:08:16)
+ ###
+ ###<select second('12:13:14')
+ ###>14
func_odbc_sign=yes # Function SIGN
+ ###
+ ###<select sign(-5)
+ ###>-1
func_odbc_sin=yes # Function SIN
+ ###
+ ###<select sin(1)
+ ###>0.841471
func_odbc_soundex=yes # Function SOUNDEX
+ ###
+ ###<select soundex('hello')
+ ###>H400
func_odbc_space=yes # Function SPACE
+ ###
+ ###<select space(5)
+ ###>
func_odbc_sqrt=yes # Function SQRT
+ ###
+ ###<select sqrt(4)
+ ###>2.000000
func_odbc_substring=yes # Function ODBC SUBSTRING
+ ###
+ ###<select substring('abcd',3,2)
+ ###>cd
func_odbc_tan=yes # Function TAN
+ ###
+ ###<select tan(1)
+ ###>1.557408
func_odbc_timestampadd=no # Function TIMESTAMPADD
+ ###
+ ###<select timestampadd(SQL_TSI_SECOND,1,'1997-01-01 00:00:00')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(SQL_TSI_SECOND,1,'1997-01-01 00:00:00')' at line 1
+ ###
+ ###<select {fn timestampadd(SQL_TSI_SECOND,1,{ts '1997-01-01 00:00:00'}) }
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(SQL_TSI_SECOND,1,{ts '1997-01-01 00:00:00'}) }' at line 1
func_odbc_timestampdiff=no # Function TIMESTAMPDIFF
+ ###
+ ###<select timestampdiff(SQL_TSI_SECOND,'1997-01-01 00:00:02', '1997-01-01 00:00:01')
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(SQL_TSI_SECOND,'1997-01-01 00:00:02', '1997-01-01 00:00:01')'
+ ###
+ ###<select {fn timestampdiff(SQL_TSI_SECOND,{ts '1997-01-01 00:00:02'}, {ts '1997-01-01 00:00:01'}) }
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(SQL_TSI_SECOND,{ts '1997-01-01 00:00:02'}, {ts '1997-01-01 00:
func_odbc_truncate=yes # Function TRUNCATE
+ ###
+ ###<select truncate(18.18,-1)
+ ###>10
func_odbc_ucase=yes # Function UCASE
+ ###
+ ###<select ucase('abc')
+ ###>ABC
func_odbc_user()=yes # Function USER()
-func_odbc_week=yes # Function WEEK
+ ###
+ ###<select user()
+ ###>monty@localhost
+func_odbc_week=USA # WEEK
+ ###<select week('1997-02-01')
+ ###>4
+ ###We expected '5' but got '4'
func_odbc_year=yes # Function YEAR
+ ###< insert into crash_me_d values('1997-02-01')
+ ###
+ ###<select year(a) from crash_me_d
+ ###>1997
func_sql_+=yes # Function +, -, * and /
-func_sql_bit_length=no # Function BIT_LENGTH
-func_sql_cast=no # Function CAST
+ ###
+ ###<select 5*3-4/2+1
+ ###>14.00
+func_sql_bit_length=yes # Function BIT_LENGTH
+ ###
+ ###<select bit_length('abc')
+ ###>24
+func_sql_cast=yes # Function CAST
+ ###
+ ###<select CAST(1 as CHAR)
+ ###>1
func_sql_char_length=error # Function CHAR_LENGTH
+ ###
+ ###<select char_length(b) from crash_me
+ ###>1
+ ###We expected '10' but got '1'
func_sql_char_length(constant)=yes # Function CHAR_LENGTH(constant)
+ ###
+ ###<select char_length('abcd')
+ ###>4
func_sql_character_length=yes # Function CHARACTER_LENGTH
+ ###
+ ###<select character_length('abcd')
+ ###>4
func_sql_coalesce=yes # Function COALESCE
+ ###
+ ###<select coalesce(NULL,'bcd','qwe')
+ ###>bcd
func_sql_concat_as_||=error # Function concatenation with ||
+ ###
+ ###<select 'abc' || 'def'
+ ###>0
+ ###We expected 'abcdef' but got '0'
func_sql_current_date=yes # Function CURRENT_DATE
+ ###
+ ###<select current_date
+ ###>2003-08-27
func_sql_current_time=yes # Function CURRENT_TIME
+ ###
+ ###<select current_time
+ ###>19:55:21
func_sql_current_timestamp=yes # Function CURRENT_TIMESTAMP
-func_sql_current_user=no # Function CURRENT_USER
+ ###
+ ###<select current_timestamp
+ ###>2003-08-27 19:55:21
+func_sql_current_user=with_parenthesis # CURRENT_USER
+ ###< select CURRENT_USER
+ ###> execute error:Unknown column 'CURRENT_USER' in 'field list'
+ ###
+ ###< select CURRENT_USER()
+ ###> OK
func_sql_extract_sql=yes # Function EXTRACT
-func_sql_localtime=no # Function LOCALTIME
-func_sql_localtimestamp=no # Function LOCALTIMESTAMP
+ ###
+ ###<select extract(minute from timestamp '2000-02-23 18:43:12.987')
+ ###>43
+func_sql_localtime=yes # Function LOCALTIME
+ ###
+ ###<select localtime
+ ###>2003-08-27 19:55:21
+func_sql_localtimestamp=yes # Function LOCALTIMESTAMP
+ ###
+ ###<select localtimestamp
+ ###>2003-08-27 19:55:21
func_sql_lower=yes # Function LOWER
+ ###
+ ###<select LOWER('ABC')
+ ###>abc
func_sql_nullif_num=yes # Function NULLIF with numbers
+ ###
+ ###<select NULLIF(NULLIF(1,2),1)
+ ###>
func_sql_nullif_string=yes # Function NULLIF with strings
+ ###
+ ###<select NULLIF(NULLIF('first','second'),'first')
+ ###>
func_sql_octet_length=yes # Function OCTET_LENGTH
+ ###
+ ###<select octet_length('abc')
+ ###>3
func_sql_position=yes # Function POSITION
+ ###
+ ###<select position('ll' in 'hello')
+ ###>3
func_sql_searched_case=yes # Function searched CASE
-func_sql_session_user=no # Function SESSION_USER
+ ###
+ ###<select case when 1 > 2 then 'false' when 2 > 1 then 'true' end
+ ###>true
+func_sql_session_user=with_parenthesis # SESSION_USER
+ ###< select SESSION_USER
+ ###> execute error:Unknown column 'SESSION_USER' in 'field list'
+ ###
+ ###< select SESSION_USER()
+ ###> OK
func_sql_simple_case=yes # Function simple CASE
+ ###
+ ###<select case 2 when 1 then 'false' when 2 then 'true' end
+ ###>true
func_sql_substring=yes # Function ANSI SQL SUBSTRING
-func_sql_system_user=no # Function SYSTEM_USER
+ ###
+ ###<select substring('abcd' from 2 for 2)
+ ###>bc
+func_sql_system_user=with_parenthesis # SYSTEM_USER
+ ###< select SYSTEM_USER
+ ###> execute error:Unknown column 'SYSTEM_USER' in 'field list'
+ ###
+ ###< select SYSTEM_USER()
+ ###> OK
func_sql_trim=yes # Function TRIM
+ ###
+ ###<select trim(trailing from trim(LEADING FROM ' abc '))
+ ###>abc
func_sql_upper=yes # Function UPPER
-func_sql_user=no # Function USER
+ ###
+ ###<select UPPER('abc')
+ ###>ABC
+func_sql_user=with_parenthesis # USER
+ ###< select USER
+ ###> execute error:Unknown column 'USER' in 'field list'
+ ###
+ ###< select USER()
+ ###> OK
func_where_between=yes # Function BETWEEN
+ ###
+ ###<select a from crash_me where 5 between 4 and 6
+ ###>1
func_where_eq_all=no # Function = ALL
+ ###
+ ###<select a from crash_me where b =all (select b from crash_me)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all (select b from crash_me)' at line 1
func_where_eq_any=no # Function = ANY
+ ###
+ ###<select a from crash_me where b =any (select b from crash_me)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(select b from crash_me)' at line 1
func_where_eq_some=no # Function = SOME
+ ###
+ ###<select a from crash_me where b =some (select b from crash_me)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(select b from crash_me)' at line 1
func_where_exists=no # Function EXISTS
+ ###
+ ###<select a from crash_me where exists (select * from crash_me)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'exists (select * from crash_me)' at line 1
func_where_in_num=yes # Function IN on numbers
+ ###
+ ###<select a from crash_me where 2 in (3,2,5,9,5,1)
+ ###>1
func_where_like=yes # Function LIKE
+ ###
+ ###<select a from crash_me where b like 'a%'
+ ###>1
func_where_like_escape=yes # Function LIKE ESCAPE
+ ###
+ ###<select a from crash_me where b like '%' escape 'a'
+ ###>1
func_where_match=no # Function MATCH
+ ###
+ ###<select a from crash_me where 1 match (select a from crash_me)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'match (select a from crash_me)' at line 1
func_where_match_unique=no # Function MATCH UNIQUE
+ ###
+ ###<select a from crash_me where 1 match unique (select a from crash_me)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'match unique (select a from crash_me)' at line 1
func_where_matches=no # Function MATCHES
+ ###
+ ###<select a from crash_me where b matcjhes 'a*'
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'matcjhes 'a*'' at line 1
func_where_not_between=yes # Function NOT BETWEEN
+ ###
+ ###<select a from crash_me where 7 not between 4 and 6
+ ###>1
func_where_not_exists=no # Function NOT EXISTS
+ ###
+ ###<select a from crash_me where not exists (select * from crash_me where a = 2)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'exists (select * from crash_me where a = 2)' at line 1
func_where_not_like=yes # Function NOT LIKE
+ ###
+ ###<select a from crash_me where b not like 'b%'
+ ###>1
func_where_not_unique=no # Function NOT UNIQUE
+ ###
+ ###<select a from crash_me where not unique (select * from crash_me where a = 2)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'unique (select * from crash_me where a = 2)' at line 1
func_where_unique=no # Function UNIQUE
+ ###
+ ###<select a from crash_me where unique (select * from crash_me)
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'unique (select * from crash_me)' at line 1
functions=yes # Functions
+ ###< select 1+1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
group_by=yes # Group by
+ ###< select a from crash_me group by a
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
group_by_alias=yes # Group by alias
+ ###< select a as ab from crash_me group by ab
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
group_by_null=yes # Group on column with null values
+ ###< create table crash_q (s char(10))
+ ###> OK
+ ###< insert into crash_q values(null)
+ ###> OK
+ ###< insert into crash_q values(null)
+ ###> OK
+ ###
+ ###<select count(*),s from crash_q group by s
+ ###>2
+ ###
+ ###< drop table crash_q
+ ###> OK
group_by_position=yes # Group by position
+ ###< select a from crash_me group by 1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
group_distinct_functions=yes # Group functions with distinct
+ ###< select count(distinct a) from crash_me
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
group_func_extra_bit_and=yes # Group function BIT_AND
+ ###
+ ###<select bit_and(a),a from crash_me group by a
+ ###>1
group_func_extra_bit_or=yes # Group function BIT_OR
+ ###
+ ###<select bit_or(a),a from crash_me group by a
+ ###>1
group_func_extra_count_distinct_list=yes # Group function COUNT(DISTINCT expr,expr,...)
+ ###
+ ###<select count(distinct a,b),a from crash_me group by a
+ ###>1
group_func_extra_std=yes # Group function STD
+ ###
+ ###<select std(a),a from crash_me group by a
+ ###>0.0000
group_func_extra_stddev=yes # Group function STDDEV
+ ###
+ ###<select stddev(a),a from crash_me group by a
+ ###>0.0000
group_func_extra_variance=no # Group function VARIANCE
+ ###
+ ###<select variance(a),a from crash_me group by a
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a),a from crash_me group by a' at line 1
group_func_sql_any=no # Group function ANY
+ ###
+ ###<select any(a),a from crash_me group by a
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a),a from crash_me group by a' at line 1
group_func_sql_avg=yes # Group function AVG
+ ###
+ ###<select avg(a),a from crash_me group by a
+ ###>1.0000
group_func_sql_count_*=yes # Group function COUNT (*)
+ ###
+ ###<select count(*),a from crash_me group by a
+ ###>1
group_func_sql_count_column=yes # Group function COUNT column name
+ ###
+ ###<select count(a),a from crash_me group by a
+ ###>1
group_func_sql_count_distinct=yes # Group function COUNT(DISTINCT expr)
+ ###
+ ###<select count(distinct a),a from crash_me group by a
+ ###>1
group_func_sql_every=no # Group function EVERY
+ ###
+ ###<select every(a),a from crash_me group by a
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a),a from crash_me group by a' at line 1
group_func_sql_max=yes # Group function MAX on numbers
+ ###
+ ###<select max(a),a from crash_me group by a
+ ###>1
group_func_sql_max_str=yes # Group function MAX on strings
+ ###
+ ###<select max(b),a from crash_me group by a
+ ###>a
group_func_sql_min=yes # Group function MIN on numbers
+ ###
+ ###<select min(a),a from crash_me group by a
+ ###>1
group_func_sql_min_str=yes # Group function MIN on strings
+ ###
+ ###<select min(b),a from crash_me group by a
+ ###>a
group_func_sql_some=no # Group function SOME
+ ###
+ ###<select some(a),a from crash_me group by a
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a),a from crash_me group by a' at line 1
group_func_sql_sum=yes # Group function SUM
+ ###
+ ###<select sum(a),a from crash_me group by a
+ ###>1
group_functions=yes # Group functions
+ ###< select count(*) from crash_me
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+group_many_distinct_functions=yes # Group functions with several distinct
+ ###< select count(distinct a), count(distinct b) from crash_me
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
group_on_unused=yes # Group on unused column
+ ###< select count(*) from crash_me group by a
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
has_true_false=no # TRUE and FALSE
+ ###< select (1=1)=true
+ ###> execute error:Unknown column 'true' in 'field list'
having=yes # Having
+ ###<select a from crash_me group by a having a > 0
+ ###>1
+ ###
+ ###<select a from crash_me group by a having a < 0
+ ###> didn't return any result:
having_with_alias=yes # Having on alias
+ ###< select a as ab from crash_me group by a having ab > 0
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
having_with_group=yes # Having with group function
+ ###< select a from crash_me group by a having count(*) = 1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
hex_numbers=yes # hex numbers (0x41)
-hex_strings=no # hex strings (x'1ace')
+ ###< select 0x41
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+hex_strings=yes # hex strings (x'1ace')
+ ###< select x'1ace'
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
ignore_end_space=yes # Ignore end space in compare
+ ###
+ ###<select b from crash_me where b = 'a '
+ ###>a
index_in_create=yes # index in create table
+ ###< create table crash_q (q integer not null,index (q))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
index_namespace=yes # different namespace for index
+ ###< create index crash_me on crash_me (b)
+ ###> OK
+ ###< drop index crash_me on crash_me
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
index_parts=yes # index on column part (extension)
+ ###< create index crash_q on crash_me (b(5))
+ ###> OK
+ ###< drop index crash_q on crash_me
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
inner_join=yes # inner join
+ ###< select crash_me.a from crash_me inner join crash_me2 ON crash_me.a=crash_me2.a
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+insert_default_values=no # INSERT DEFAULT VALUES
+ ###< create table crash_me_q (a int)
+ ###> OK
+ ###< insert into crash_me_q DEFAULT VALUES
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DEFAULT VALUES' at line 1
+ ###< drop table crash_me_q
+ ###> OK
+ ###
+ ###As far as some queries didnt return OK, result is NO
insert_empty_string=yes # insert empty string
+ ###< create table crash_q (a char(10) not null,b char(10))
+ ###> OK
+ ###< insert into crash_q values ('','')
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
insert_multi_value=yes # INSERT with Value lists
+ ###< create table crash_q (s char(10))
+ ###> OK
+ ###< insert into crash_q values ('a'),('b')
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
insert_select=yes # insert INTO ... SELECT ...
+ ###< create table crash_q (a int)
+ ###> OK
+ ###< insert into crash_q (a) SELECT crash_me.a from crash_me
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+insert_with_default=yes # INSERT with DEFAULT
+ ###< create table crash_me_q (a int)
+ ###> OK
+ ###< insert into crash_me_q (a) values (DEFAULT)
+ ###> OK
+ ###< drop table crash_me_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+insert_with_empty_value_list=no # INSERT with empty value list
+ ###< create table crash_me_q (a int)
+ ###> OK
+ ###< insert into crash_me_q (a) values ()
+ ###> execute error:Column count doesn't match value count at row 1
+ ###< drop table crash_me_q
+ ###> OK
+ ###
+ ###As far as some queries didnt return OK, result is NO
insert_with_set=yes # INSERT with set syntax
+ ###< create table crash_q (a integer)
+ ###> OK
+ ###< insert into crash_q SET a=1
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
intersect=no # intersect
+ ###< select * from crash_me intersect select * from crash_me3
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me3' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
intersect_all=no # intersect all
+ ###< select * from crash_me intersect all select * from crash_me3
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me3' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
intersect_all_incompat=no # intersect all (incompatible lists)
+ ###< select * from crash_me intersect all select * from crash_me2
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'all select * from crash_me2' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
intersect_incompat=no # intersect (incompatible lists)
-join_tables=63 # tables in join
+ ###< select * from crash_me intersect select * from crash_me2
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me2' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
+join_tables=31 # tables in join
+ ###We are trying (example with N=5):
+ ###select crash_me.a,t0.a,t1.a,t2.a,t3.a,t4.a from crash_me,crash_me t0,crash_me t1,crash_me t2,crash_me t3,crash_me t4
+ ### 32:FAIL 7:OK 19:OK 25:OK 28:OK 30:OK 31:FAIL
left_outer_join=yes # left outer join
+ ###< select crash_me.a from crash_me left join crash_me2 ON crash_me.a=crash_me2.a
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
left_outer_join_using=yes # left outer join using
+ ###< select c1 from crash_me left join crash_me2 using (a)
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+length_of_varchar_field=actual length # CHARACTER_LENGTH(varchar_field)
+ ###< CREATE TABLE crash_me1 (S1 VARCHAR(100))
+ ###> OK
+ ###< INSERT INTO crash_me1 VALUES ('X')
+ ###> OK
+ ###
+ ###< SELECT CHARACTER_LENGTH(S1) FROM crash_me1
+ ### > 1
+ ###< drop table crash_me1
+ ###> OK
like_with_column=yes # column LIKE column
+ ###< create table crash_q (a char(10),b char(10))
+ ###> OK
+ ###< insert into crash_q values('abc','abc')
+ ###> OK
+ ###< select * from crash_q where a like b
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
like_with_number=yes # LIKE on numbers
+ ###< create table crash_q (a int,b int)
+ ###> OK
+ ###< insert into crash_q values(10,10)
+ ###> OK
+ ###< select * from crash_q where a like '10'
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
lock_tables=yes # lock table
+ ###< lock table crash_me READ
+ ###> OK
+ ###< unlock tables
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
logical_value=1 # Value of logical operation (1=1)
+ ###<select (1=1)
+ ###>1
max_big_expressions=10 # big expressions
+ ###We are trying (example with N=5):
+ ###select 0+(1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+...(14308)
+ ### 50:FAIL 10:OK 30:FAIL 14:FAIL 11:FAIL
max_char_size=255 # max char() size
+ ###We are trying (example with N=5):
+ ###create table crash_q (q char(5))
+ ###insert into crash_q values ('aaaaa')
+ ###select * from crash_q
+ ### 524287:FAIL 104858:FAIL 20972:FAIL 4195:FAIL 839:FAIL 168:OK 503:FAIL 235:OK 369:FAIL 262:FAIL 241:OK 251:OK 256:FAIL 252:OK 254:OK 255:OK
max_column_name=64 # column name length
+ ###We are trying (example with N=5):
+ ###create table crash_q (qaaaaa integer)
+ ###insert into crash_q (qaaaaa) values(1)
+ ###select qaaaaa from crash_q
+ ### 256:FAIL 51:OK 153:FAIL 72:FAIL 55:OK 63:OK 67:FAIL 64:FAIL
max_columns=3398 # Columns in table
+ ###We are trying (example with N=5):
+ ###create table crash_q (a integer ,a0 integer,a1 integer,a2 integer,a3 integer,a4 integer)
+ ### 4096:FAIL 819:OK 2457:OK 3276:OK 3686:FAIL 3358:OK 3522:FAIL 3391:OK 3456:FAIL 3404:FAIL 3394:OK 3399:FAIL 3395:OK 3397:OK 3398:FAIL
max_conditions=85660 # OR and AND in WHERE
-max_expressions=1837 # simple expressions
+ ###We are trying (example with N=5):
+ ###select a from crash_me where a=1 and b='a' or a=0 and b='0' or a=1 and b='1' or a=2 and b='2' or a=3 and b='3' or a=4 and b='4'
+ ### 27592:OK 41389:OK 48287:FAIL 42769:OK 45528:FAIL 43321:FAIL 42880:FAIL 42791:OK 42835:FAIL 42800:OK 42817:OK 42826:OK 42830:OK 42832:FAIL 42831:FAIL
+max_expressions=1450 # simple expressions
+ ###We are trying (example with N=5):
+ ###select 1+1+1+1+1+1
+ ### 5000:FAIL 1000:OK 3000:FAIL 1400:OK 2200:FAIL 1560:FAIL 1432:OK 1496:FAIL 1445:OK 1470:FAIL 1450:OK 1460:FAIL 1452:FAIL 1451:FAIL
max_index=32 # max index
+ ### max_unique_index=32 ,so max_index must be same
max_index_length=500 # index length
+ ###We are trying (example with N=5):
+ ###create table crash_q (q0 char(5) not null,unique (q0))
+ ###insert into crash_q values('aaaaa')
+ ### 4096:FAIL 819:FAIL 164:OK 491:OK 655:FAIL 524:FAIL 498:OK 511:FAIL 501:FAIL 499:OK 500:OK
max_index_name=64 # index name length
+ ###We are trying (example with N=5):
+ ###create index crash_qaaaaa on crash_me (a)
+ ### 256:FAIL 51:OK 153:FAIL 72:FAIL 55:OK 63:FAIL 57:OK 60:FAIL 58:FAIL
max_index_part_length=255 # max index part length
+ ###We are trying (example with N=5):
+ ###create table crash_q (q char(5) not null,unique(q))
+ ###insert into crash_q (q) values ('aaaaa')
+ ###select q from crash_q
max_index_parts=16 # index parts
+ ###We are trying (example with N=5):
+ ###create table crash_q (q0 integer not null,q1 integer not null,q2 integer not null,q3 integer not null,q4 integer not nul...(1263)
+ ###insert into crash_q (q0,q1,q2,q3,q4,q5,q6,q7,q8,q9,q10,q11,q12,q13,q14,q15,q16,q17,q18,q19,q20,q21,q22,q23,q24,q25,q26,q...(284)
+ ###select q0 from crash_q
+ ### 32:FAIL 7:OK 19:FAIL 10:OK 14:OK 16:FAIL 15:OK
max_index_varchar_part_length=255 # index varchar part length
+ ###We are trying (example with N=5):
+ ###create table crash_q (q varchar(5) not null,unique(q))
+ ###insert into crash_q (q) values ('aaaaa')
+ ###select q from crash_q
max_row_length=65534 # max table row length (without blobs)
+ ###We are trying (example with N=5):
+ ###create table crash_q (q0 char(5) not null)
+ ###insert into crash_q values ('aaaaa')
+ ### 433245:FAIL 86649:FAIL 17330:OK 51989:OK 69319:FAIL 55455:OK 62387:OK 65853:FAIL 63080:OK 64466:OK 65159:OK 65506:OK 65679:FAIL 65541:FAIL 65513:OK 65527:OK 65534:OK 65537:FAIL 65535:FAIL
max_row_length_with_null=65502 # table row length with nulls (without blobs)
+ ###We are trying (example with N=5):
+ ###create table crash_q (q0 char(5) )
+ ###insert into crash_q values ('aaaaa')
+ ### 65534:FAIL 13107:OK 39320:OK 52427:OK 58980:OK 62257:OK 63895:OK 64714:OK 65124:OK 65329:OK 65431:OK 65482:OK 65508:FAIL 65487:OK 65497:OK 65502:OK 65505:FAIL 65503:FAIL
max_select_alias_name=+512 # select alias name length
-max_stack_expression=1837 # stacked expressions
+ ###We are trying (example with N=5):
+ ###select b as aaaaa from crash_me
+max_stack_expression=1450 # stacked expressions
+ ###We are trying (example with N=5):
+ ###select 1+(1+(1+(1+(1+(1)))))
+ ### 1000:OK 1500:FAIL 1100:OK 1300:OK 1400:OK 1450:OK 1475:FAIL 1455:FAIL 1451:FAIL
max_table_alias_name=+512 # table alias name length
+ ###We are trying (example with N=5):
+ ###select aaaaa.b from crash_me aaaaa
max_table_name=64 # table name length
+ ###We are trying (example with N=5):
+ ###create table crash_qaaaaa (q integer)
+ ###insert into crash_qaaaaa values(1)
+ ###select * from crash_qaaaaa
+ ### 256:FAIL 51:OK 153:FAIL 72:FAIL 55:OK 63:FAIL 57:OK 60:FAIL 58:FAIL
max_text_size=1048543 # max text or blob size
+ ###We are trying (example with N=5):
+ ###create table crash_q (q mediumtext)
+ ###insert into crash_q values ('aaaaa')
+ ###select * from crash_q
+ ### 524272:OK 786408:OK 917476:OK 983010:OK 1015777:OK 1032161:OK 1040353:OK 1044449:OK 1046497:OK 1047521:OK 1048033:OK 1048289:OK 1048417:OK 1048481:OK 1048513:OK 1048529:OK 1048537:OK 1048541:OK 1048543:OK 1048544:FAIL
max_unique_index=32 # unique indexes
+ ###We are trying (example with N=5):
+ ###create table crash_q (q integer,q1 integer not null,unique (q1),q2 integer not null,unique (q2),q3 integer not null,uniq...(72)
+ ###insert into crash_q (q,q1,q2,q3,q4,q5) values (1,1,1,1,1,1)
+ ###select q from crash_q
+ ### 32:OK 48:FAIL 35:FAIL 33:FAIL
max_varchar_size=255 # max varchar() size
+ ###We are trying (example with N=5):
+ ###create table crash_q (q varchar(5))
+ ###insert into crash_q values ('aaaaa')
+ ###select * from crash_q
+ ### 524287:FAIL 104858:FAIL 20972:FAIL 4195:FAIL 839:FAIL 168:OK 503:FAIL 235:OK 369:FAIL 262:FAIL 241:OK 251:OK 256:FAIL 252:OK 254:OK 255:OK
minus=no # minus
+ ###< select * from crash_me minus select * from crash_me3
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me3' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
minus_incompat=no # minus (incompatible lists)
+ ###< select * from crash_me minus select * from crash_me2
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from crash_me2' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
minus_neg=yes # Calculate 1--1
+ ###
+ ###<select a--1 from crash_me
+ ###>2
multi_drop=yes # many tables to drop table
+ ###< create table crash_q (a int)
+ ###> OK
+ ###< create table crash_q2 (a int)
+ ###> OK
+ ###< drop table crash_q,crash_q2
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
multi_null_in_unique=yes # null in unique index
+ ###< create table crash_q (q integer, x integer,unique (q))
+ ###> OK
+ ###< insert into crash_q(x) values(1)
+ ###> OK
+ ###< insert into crash_q(x) values(2)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
multi_strings=yes # Multiple line strings
-multi_table_delete=no # DELETE FROM table1,table2...
-multi_table_update=no # Update with many tables
+ ###
+ ###<select a from crash_me where b < 'a'
+ ###'b'
+ ###>1
+multi_table_delete=yes # DELETE FROM table1,table2...
+ ###< create table crash_q (a integer,b char(10))
+ ###> OK
+ ###< insert into crash_q values(1,'c')
+ ###> OK
+ ###< delete crash_q.* from crash_q,crash_me where crash_q.a=crash_me.a
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+multi_table_update=yes # Update with many tables
+ ###< create table crash_q (a integer,b char(10))
+ ###> OK
+ ###< insert into crash_q values(1,'c')
+ ###> OK
+ ###< update crash_q left join crash_me on crash_q.a=crash_me.a set crash_q.b=crash_me.b
+ ###> OK
+ ###
+ ###<select b from crash_q
+ ###>a
+ ###
+ ###< drop table crash_q
+ ###> OK
natural_join=yes # natural join
+ ###< select * from crash_me natural join crash_me3
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
natural_join_incompat=yes # natural join (incompatible lists)
+ ###< select c1 from crash_me natural join crash_me2
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
natural_left_outer_join=yes # natural left outer join
+ ###< select c1 from crash_me natural left join crash_me2
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
no_primary_key=yes # Tables without primary key
+ ###< create table crash_me (a integer not null,b char(10) not null)
+ ###> OK
+ ###< insert into crash_me (a,b) values (1,'a')
+ ###> OK
+not_id_between=no # NOT ID BETWEEN interprets as ID NOT BETWEEN
+ ###< create table crash_me_b (i int)
+ ###> OK
+ ###< insert into crash_me_b values(2)
+ ###> OK
+ ###< insert into crash_me_b values(5)
+ ###> OK
+ ###
+ ###<select i from crash_me_b where not i between 1 and 3
+ ###> didn't return any result:
+ ###
+ ###< drop table crash_me_b
+ ###> OK
null_concat_expr=yes # Is concat('a',NULL) = NULL
+ ###
+ ###<select concat('a',NULL)
+ ###>
null_in_index=yes # null in index
+ ###< create table crash_q (a char(10),index (a))
+ ###> OK
+ ###< insert into crash_q values (NULL)
+ ###> OK
+ ###
+ ###<select * from crash_q
+ ###>
+ ###
+ ###< drop table crash_q
+ ###> OK
null_in_unique=yes # null in unique index
+ ###< create table crash_q (q integer,unique (q))
+ ###> OK
+ ###< insert into crash_q (q) values(NULL)
+ ###> OK
+ ###< insert into crash_q (q) values(NULL)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
null_num_expr=yes # Is 1+NULL = NULL
+ ###
+ ###<select 1+NULL
+ ###>
nulls_in_unique=yes # null combination in unique index
+ ###< create table crash_q (q integer,q1 integer,unique (q,q1))
+ ###> OK
+ ###< insert into crash_q (q,q1) values(1,NULL)
+ ###> OK
+ ###< insert into crash_q (q,q1) values(1,NULL)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
odbc_left_outer_join=yes # left outer join odbc style
-operating_system=Linux 2.2.13-SMP alpha # crash-me tested on
+ ###< select crash_me.a from { oj crash_me left outer join crash_me2 ON crash_me.a=crash_me2.a }
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+operating_system=Linux 2.4.20-64GB-SMP i686 # crash-me tested on
order_by=yes # Order by
+ ###< select a from crash_me order by a
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
order_by_alias=yes # Order by alias
+ ###< select a as ab from crash_me order by ab
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
order_by_function=yes # Order by function
+ ###< select a from crash_me order by a+1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
order_by_position=yes # Order by position
-order_by_remember_desc=no # Order by DESC is remembered
+ ###< select a from crash_me order by 1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
order_on_unused=yes # Order by on unused column
+ ###< select b from crash_me order by a
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+position_of_null=first # Where is null values in sorted recordset
+ ###< insert into crash_me_n (i) values(1)
+ ###> OK
+ ###< insert into crash_me_n values(2,2)
+ ###> OK
+ ###< insert into crash_me_n values(3,3)
+ ###> OK
+ ###< insert into crash_me_n values(4,4)
+ ###> OK
+ ###< insert into crash_me_n (i) values(5)
+ ###> OK
+ ###
+ ###< select r from crash_me_n order by r
+ ###>
+ ###>
+ ###> 2
+ ###> 3
+ ###> 4
+position_of_null_desc=last # Where is null values in sorted recordset (DESC)
+ ###< select r from crash_me_n order by r desc
+ ###> 4
+ ###> 3
+ ###> 2
+ ###>
+ ###>
primary_key_in_create=yes # primary key in create table
+ ###< create table crash_q (q integer not null,primary key (q))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
psm_functions=no # PSM functions (ANSI SQL)
+ ###< create table crash_q (a int)
+ ###> OK
+ ###< create function crash_func(in a1 int, in b1 int) returns int language sql deterministic contains sql begin return a1 * b1; end
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(in a1 int, in b1 int) returns int language sql deterministic c
+ ###< insert into crash_q values(crash_func(2,4))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(2,4))' at line 1
+ ###< select a,crash_func(a,2) from crash_q
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(a,2) from crash_q' at line 1
+ ###< drop function crash_func cascade
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'cascade' at line 1
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as some queries didnt return OK, result is NO
psm_modules=no # PSM modules (ANSI SQL)
+ ###< create table crash_q (a int,b int)
+ ###> OK
+ ###< create module crash_m declare procedure crash_proc(in a1 int, in b1 int) language sql modifies sql data begin declare c1 int; set c1 = a1 + b1; insert into crash_q(a,b) values (a1,c1); end; declare procedure crash_proc2(INOUT a int, in b int) contains sql set a = b + 10; end module
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'module crash_m declare procedure crash_proc(in a1 int, in b1 in
+ ###< call crash_proc(1,10)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'call crash_proc(1,10)' at line 1
+ ###< drop module crash_m cascade
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'module crash_m cascade' at line 1
+ ###< drop table crash_q cascade
+ ###> OK
+ ###
+ ###As far as some queries didnt return OK, result is NO
psm_procedures=no # PSM procedures (ANSI SQL)
+ ###< create table crash_q (a int,b int)
+ ###> OK
+ ###< create procedure crash_proc(in a1 int, in b1 int) language sql modifies sql data begin declare c1 int; set c1 = a1 + b1; insert into crash_q(a,b) values (a1,c1); end
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'procedure crash_proc(in a1 int, in b1 int) language sql modifie
+ ###< call crash_proc(1,10)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'call crash_proc(1,10)' at line 1
+ ###< drop procedure crash_proc
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'procedure crash_proc' at line 1
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as some queries didnt return OK, result is NO
psm_trigger=no # Triggers (ANSI SQL)
+ ###< create table crash_q (a int ,b int)
+ ###> OK
+ ###< create trigger crash_trigger after insert on crash_q referencing new table as new_a when (localtime > time '18:00:00') begin atomic end
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'trigger crash_trigger after insert on crash_q referencing new t
+ ###< insert into crash_q values(1,2)
+ ###> OK
+ ###< drop trigger crash_trigger
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'trigger crash_trigger' at line 1
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as some queries didnt return OK, result is NO
query_size=1048574 # query size
quote_ident_with_"=error # " as identifier quote (ANSI SQL)
+ ###
+ ###<select "A" from crash_me
+ ###>A
+ ###We expected '1' but got 'A'
quote_ident_with_[=no # [] as identifier quote
+ ###
+ ###<select [A] from crash_me
+ ###> execute failed:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '[A] from crash_me' at line 1
quote_ident_with_`=yes # ` as identifier quote
+ ###
+ ###<select `A` from crash_me
+ ###>1
+quote_ident_with_dbl_"=no # Double "" in identifiers as "
+ ###< create table crash_me1 ("abc""d" integer)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '"abc""d" integer)' at line 1
+ ###< drop table crash_me1
+ ###> execute error:Unknown table 'crash_me1'
+ ###
+ ###As far as some queries didnt return OK, result is NO
quote_with_"=yes # Allows ' and " as string markers
+ ###< select a from crash_me where b<"c"
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
remember_end_space=no # Remembers end space in char()
+ ###< create table crash_q (a char(10))
+ ###> OK
+ ###< insert into crash_q values('hello ')
+ ###> OK
+ ###
+ ###<select a from crash_q where a = 'hello '
+ ###>hello
+ ###We expected 'hello ' but got 'hello'
+ ###
+ ###< drop table crash_q
+ ###> OK
remember_end_space_varchar=no # Remembers end space in varchar()
+ ###< create table crash_q (a varchar(10))
+ ###> OK
+ ###< insert into crash_q values('hello ')
+ ###> OK
+ ###
+ ###<select a from crash_q where a = 'hello '
+ ###>hello
+ ###We expected 'hello ' but got 'hello'
+ ###
+ ###< drop table crash_q
+ ###> OK
rename_table=yes # rename table
+ ###< create table crash_q (a integer, b integer,c1 CHAR(10))
+ ###> OK
+ ###< rename table crash_q to crash_q1
+ ###> OK
+ ###< drop table crash_q1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
repeat_string_size=1047552 # return string size from function
+ ###We are trying (example with N=5):
+ ###select repeat('a',5)
+ ### 4000000:FAIL 800000:OK 2400000:FAIL 1120000:FAIL 864000:OK 992000:OK 1056000:FAIL 1004800:OK 1030400:OK 1043200:OK 1049600:FAIL 1044480:OK 1047040:OK 1048320:FAIL 1047296:OK 1047808:FAIL 1047399:OK 1047603:FAIL 1047440:OK 1047521:OK 1047562:FAIL 1047529:OK 1047545:OK 1047553:FAIL 1047547:OK 1047550:OK 1047551:OK 1047552:OK
+reserved_word_ansi-92/99_absolute=no # Keyword ABSOLUTE
+ ###< create table crash_me10 (ABSOLUTE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_action=no # Keyword ACTION
+ ###< create table crash_me10 (ACTION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_add=yes # Keyword ADD
+ ###< create table crash_me10 (ADD int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ADD int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_after=no # Keyword AFTER
+ ###< create table crash_me10 (AFTER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_alias=no # Keyword ALIAS
+ ###< create table crash_me10 (ALIAS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_all=yes # Keyword ALL
+ ###< create table crash_me10 (ALL int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ALL int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_allocate=no # Keyword ALLOCATE
+ ###< create table crash_me10 (ALLOCATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_alter=yes # Keyword ALTER
+ ###< create table crash_me10 (ALTER int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ALTER int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_and=yes # Keyword AND
+ ###< create table crash_me10 (AND int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_any=no # Keyword ANY
+ ###< create table crash_me10 (ANY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_are=no # Keyword ARE
+ ###< create table crash_me10 (ARE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_as=yes # Keyword AS
+ ###< create table crash_me10 (AS int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_asc=yes # Keyword ASC
+ ###< create table crash_me10 (ASC int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ASC int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_assertion=no # Keyword ASSERTION
+ ###< create table crash_me10 (ASSERTION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_at=no # Keyword AT
+ ###< create table crash_me10 (AT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_authorization=no # Keyword AUTHORIZATION
+ ###< create table crash_me10 (AUTHORIZATION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_before=no # Keyword BEFORE
+ ###< create table crash_me10 (BEFORE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_begin=no # Keyword BEGIN
+ ###< create table crash_me10 (BEGIN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_bit=no # Keyword BIT
+ ###< create table crash_me10 (BIT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_boolean=no # Keyword BOOLEAN
+ ###< create table crash_me10 (BOOLEAN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_both=yes # Keyword BOTH
+ ###< create table crash_me10 (BOTH int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'BOTH int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_breadth=no # Keyword BREADTH
+ ###< create table crash_me10 (BREADTH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_by=yes # Keyword BY
+ ###< create table crash_me10 (BY int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'BY int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_call=no # Keyword CALL
+ ###< create table crash_me10 (CALL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_cascade=yes # Keyword CASCADE
+ ###< create table crash_me10 (CASCADE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASCADE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_cascaded=no # Keyword CASCADED
+ ###< create table crash_me10 (CASCADED int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_case=yes # Keyword CASE
+ ###< create table crash_me10 (CASE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_cast=no # Keyword CAST
+ ###< create table crash_me10 (CAST int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_catalog=no # Keyword CATALOG
+ ###< create table crash_me10 (CATALOG int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_char=yes # Keyword CHAR
+ ###< create table crash_me10 (CHAR int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAR int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_character=yes # Keyword CHARACTER
+ ###< create table crash_me10 (CHARACTER int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHARACTER int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_check=yes # Keyword CHECK
+ ###< create table crash_me10 (CHECK int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_close=no # Keyword CLOSE
+ ###< create table crash_me10 (CLOSE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_collate=no # Keyword COLLATE
+ ###< create table crash_me10 (COLLATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_collation=no # Keyword COLLATION
+ ###< create table crash_me10 (COLLATION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_column=yes # Keyword COLUMN
+ ###< create table crash_me10 (COLUMN int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'COLUMN int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_commit=no # Keyword COMMIT
+ ###< create table crash_me10 (COMMIT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_completion=no # Keyword COMPLETION
+ ###< create table crash_me10 (COMPLETION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_connect=no # Keyword CONNECT
+ ###< create table crash_me10 (CONNECT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_connection=no # Keyword CONNECTION
+ ###< create table crash_me10 (CONNECTION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_constraint=yes # Keyword CONSTRAINT
+ ###< create table crash_me10 (CONSTRAINT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_constraints=no # Keyword CONSTRAINTS
+ ###< create table crash_me10 (CONSTRAINTS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_continue=no # Keyword CONTINUE
+ ###< create table crash_me10 (CONTINUE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_corresponding=no # Keyword CORRESPONDING
+ ###< create table crash_me10 (CORRESPONDING int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_create=yes # Keyword CREATE
+ ###< create table crash_me10 (CREATE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_cross=yes # Keyword CROSS
+ ###< create table crash_me10 (CROSS int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'CROSS int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_current=no # Keyword CURRENT
+ ###< create table crash_me10 (CURRENT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_current_date=yes # Keyword CURRENT_DATE
+ ###< create table crash_me10 (CURRENT_DATE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'CURRENT_DATE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_current_time=yes # Keyword CURRENT_TIME
+ ###< create table crash_me10 (CURRENT_TIME int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'CURRENT_TIME int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_current_timestamp=yes # Keyword CURRENT_TIMESTAMP
+ ###< create table crash_me10 (CURRENT_TIMESTAMP int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'CURRENT_TIMESTAMP int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_current_user=no # Keyword CURRENT_USER
+ ###< create table crash_me10 (CURRENT_USER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_cursor=no # Keyword CURSOR
+ ###< create table crash_me10 (CURSOR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_cycle=no # Keyword CYCLE
+ ###< create table crash_me10 (CYCLE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_data=no # Keyword DATA
+ ###< create table crash_me10 (DATA int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_date=no # Keyword DATE
+ ###< create table crash_me10 (DATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_day=no # Keyword DAY
+ ###< create table crash_me10 (DAY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_deallocate=no # Keyword DEALLOCATE
+ ###< create table crash_me10 (DEALLOCATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_dec=yes # Keyword DEC
+ ###< create table crash_me10 (DEC int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DEC int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_decimal=yes # Keyword DECIMAL
+ ###< create table crash_me10 (DECIMAL int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECIMAL int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_declare=no # Keyword DECLARE
+ ###< create table crash_me10 (DECLARE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_default=yes # Keyword DEFAULT
+ ###< create table crash_me10 (DEFAULT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DEFAULT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_deferrable=no # Keyword DEFERRABLE
+ ###< create table crash_me10 (DEFERRABLE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_deferred=no # Keyword DEFERRED
+ ###< create table crash_me10 (DEFERRED int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_delete=yes # Keyword DELETE
+ ###< create table crash_me10 (DELETE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELETE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_depth=no # Keyword DEPTH
+ ###< create table crash_me10 (DEPTH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_desc=yes # Keyword DESC
+ ###< create table crash_me10 (DESC int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DESC int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_describe=yes # Keyword DESCRIBE
+ ###< create table crash_me10 (DESCRIBE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DESCRIBE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_descriptor=no # Keyword DESCRIPTOR
+ ###< create table crash_me10 (DESCRIPTOR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_diagnostics=no # Keyword DIAGNOSTICS
+ ###< create table crash_me10 (DIAGNOSTICS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_dictionary=no # Keyword DICTIONARY
+ ###< create table crash_me10 (DICTIONARY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_disconnect=no # Keyword DISCONNECT
+ ###< create table crash_me10 (DISCONNECT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_distinct=yes # Keyword DISTINCT
+ ###< create table crash_me10 (DISTINCT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DISTINCT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_domain=no # Keyword DOMAIN
+ ###< create table crash_me10 (DOMAIN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_double=yes # Keyword DOUBLE
+ ###< create table crash_me10 (DOUBLE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DOUBLE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_drop=yes # Keyword DROP
+ ###< create table crash_me10 (DROP int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DROP int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_each=no # Keyword EACH
+ ###< create table crash_me10 (EACH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_else=yes # Keyword ELSE
+ ###< create table crash_me10 (ELSE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ELSE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_elseif=no # Keyword ELSEIF
+ ###< create table crash_me10 (ELSEIF int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_end=no # Keyword END
+ ###< create table crash_me10 (END int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_end-exec=yes # Keyword END-EXEC
+ ###< create table crash_me10 (END-EXEC int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '-EXEC int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_equals=no # Keyword EQUALS
+ ###< create table crash_me10 (EQUALS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_escape=no # Keyword ESCAPE
+ ###< create table crash_me10 (ESCAPE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_except=no # Keyword EXCEPT
+ ###< create table crash_me10 (EXCEPT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_exception=no # Keyword EXCEPTION
+ ###< create table crash_me10 (EXCEPTION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_exec=no # Keyword EXEC
+ ###< create table crash_me10 (EXEC int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_execute=no # Keyword EXECUTE
+ ###< create table crash_me10 (EXECUTE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_external=no # Keyword EXTERNAL
+ ###< create table crash_me10 (EXTERNAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_false=no # Keyword FALSE
+ ###< create table crash_me10 (FALSE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_fetch=no # Keyword FETCH
+ ###< create table crash_me10 (FETCH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_first=no # Keyword FIRST
+ ###< create table crash_me10 (FIRST int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_float=yes # Keyword FLOAT
+ ###< create table crash_me10 (FLOAT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'FLOAT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_for=yes # Keyword FOR
+ ###< create table crash_me10 (FOR int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOR int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_foreign=yes # Keyword FOREIGN
+ ###< create table crash_me10 (FOREIGN int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_found=no # Keyword FOUND
+ ###< create table crash_me10 (FOUND int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_from=yes # Keyword FROM
+ ###< create table crash_me10 (FROM int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_full=no # Keyword FULL
+ ###< create table crash_me10 (FULL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_general=no # Keyword GENERAL
+ ###< create table crash_me10 (GENERAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_get=no # Keyword GET
+ ###< create table crash_me10 (GET int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_global=no # Keyword GLOBAL
+ ###< create table crash_me10 (GLOBAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_go=no # Keyword GO
+ ###< create table crash_me10 (GO int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_goto=no # Keyword GOTO
+ ###< create table crash_me10 (GOTO int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_grant=yes # Keyword GRANT
+ ###< create table crash_me10 (GRANT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'GRANT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_group=yes # Keyword GROUP
+ ###< create table crash_me10 (GROUP int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_having=yes # Keyword HAVING
+ ###< create table crash_me10 (HAVING int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'HAVING int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_hour=no # Keyword HOUR
+ ###< create table crash_me10 (HOUR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_identity=no # Keyword IDENTITY
+ ###< create table crash_me10 (IDENTITY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_if=yes # Keyword IF
+ ###< create table crash_me10 (IF int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_ignore=yes # Keyword IGNORE
+ ###< create table crash_me10 (IGNORE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'IGNORE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_immediate=no # Keyword IMMEDIATE
+ ###< create table crash_me10 (IMMEDIATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_in=yes # Keyword IN
+ ###< create table crash_me10 (IN int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'IN int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_indicator=no # Keyword INDICATOR
+ ###< create table crash_me10 (INDICATOR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_initially=no # Keyword INITIALLY
+ ###< create table crash_me10 (INITIALLY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_inner=yes # Keyword INNER
+ ###< create table crash_me10 (INNER int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'INNER int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_input=no # Keyword INPUT
+ ###< create table crash_me10 (INPUT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_insert=yes # Keyword INSERT
+ ###< create table crash_me10 (INSERT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_int=yes # Keyword INT
+ ###< create table crash_me10 (INT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'INT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_integer=yes # Keyword INTEGER
+ ###< create table crash_me10 (INTEGER int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTEGER int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_intersect=no # Keyword INTERSECT
+ ###< create table crash_me10 (INTERSECT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_interval=yes # Keyword INTERVAL
+ ###< create table crash_me10 (INTERVAL int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTERVAL int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_into=yes # Keyword INTO
+ ###< create table crash_me10 (INTO int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_is=yes # Keyword IS
+ ###< create table crash_me10 (IS int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'IS int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_isolation=no # Keyword ISOLATION
+ ###< create table crash_me10 (ISOLATION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_join=yes # Keyword JOIN
+ ###< create table crash_me10 (JOIN int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'JOIN int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_key=yes # Keyword KEY
+ ###< create table crash_me10 (KEY int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_language=no # Keyword LANGUAGE
+ ###< create table crash_me10 (LANGUAGE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_last=no # Keyword LAST
+ ###< create table crash_me10 (LAST int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_leading=yes # Keyword LEADING
+ ###< create table crash_me10 (LEADING int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LEADING int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_leave=no # Keyword LEAVE
+ ###< create table crash_me10 (LEAVE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_left=yes # Keyword LEFT
+ ###< create table crash_me10 (LEFT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LEFT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_less=no # Keyword LESS
+ ###< create table crash_me10 (LESS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_level=no # Keyword LEVEL
+ ###< create table crash_me10 (LEVEL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_like=yes # Keyword LIKE
+ ###< create table crash_me10 (LIKE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIKE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_limit=yes # Keyword LIMIT
+ ###< create table crash_me10 (LIMIT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_local=no # Keyword LOCAL
+ ###< create table crash_me10 (LOCAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_loop=no # Keyword LOOP
+ ###< create table crash_me10 (LOOP int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_match=yes # Keyword MATCH
+ ###< create table crash_me10 (MATCH int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'MATCH int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_minute=no # Keyword MINUTE
+ ###< create table crash_me10 (MINUTE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_modify=no # Keyword MODIFY
+ ###< create table crash_me10 (MODIFY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_module=no # Keyword MODULE
+ ###< create table crash_me10 (MODULE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_month=no # Keyword MONTH
+ ###< create table crash_me10 (MONTH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_names=no # Keyword NAMES
+ ###< create table crash_me10 (NAMES int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_national=no # Keyword NATIONAL
+ ###< create table crash_me10 (NATIONAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_natural=yes # Keyword NATURAL
+ ###< create table crash_me10 (NATURAL int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'NATURAL int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_nchar=no # Keyword NCHAR
+ ###< create table crash_me10 (NCHAR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_new=no # Keyword NEW
+ ###< create table crash_me10 (NEW int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_next=no # Keyword NEXT
+ ###< create table crash_me10 (NEXT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_no=no # Keyword NO
+ ###< create table crash_me10 (NO int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_none=no # Keyword NONE
+ ###< create table crash_me10 (NONE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_not=yes # Keyword NOT
+ ###< create table crash_me10 (NOT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_null=yes # Keyword NULL
+ ###< create table crash_me10 (NULL int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_numeric=yes # Keyword NUMERIC
+ ###< create table crash_me10 (NUMERIC int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'NUMERIC int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_object=no # Keyword OBJECT
+ ###< create table crash_me10 (OBJECT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_of=no # Keyword OF
+ ###< create table crash_me10 (OF int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_off=no # Keyword OFF
+ ###< create table crash_me10 (OFF int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_old=no # Keyword OLD
+ ###< create table crash_me10 (OLD int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_on=yes # Keyword ON
+ ###< create table crash_me10 (ON int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ON int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_only=no # Keyword ONLY
+ ###< create table crash_me10 (ONLY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_open=no # Keyword OPEN
+ ###< create table crash_me10 (OPEN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_operation=no # Keyword OPERATION
+ ###< create table crash_me10 (OPERATION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_option=yes # Keyword OPTION
+ ###< create table crash_me10 (OPTION int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'OPTION int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_or=yes # Keyword OR
+ ###< create table crash_me10 (OR int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'OR int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_order=yes # Keyword ORDER
+ ###< create table crash_me10 (ORDER int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ORDER int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_outer=yes # Keyword OUTER
+ ###< create table crash_me10 (OUTER int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'OUTER int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_output=no # Keyword OUTPUT
+ ###< create table crash_me10 (OUTPUT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_pad=no # Keyword PAD
+ ###< create table crash_me10 (PAD int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_parameters=no # Keyword PARAMETERS
+ ###< create table crash_me10 (PARAMETERS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_partial=yes # Keyword PARTIAL
+ ###< create table crash_me10 (PARTIAL int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'PARTIAL int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_precision=yes # Keyword PRECISION
+ ###< create table crash_me10 (PRECISION int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'PRECISION int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_preorder=no # Keyword PREORDER
+ ###< create table crash_me10 (PREORDER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_prepare=no # Keyword PREPARE
+ ###< create table crash_me10 (PREPARE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_preserve=no # Keyword PRESERVE
+ ###< create table crash_me10 (PRESERVE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_primary=yes # Keyword PRIMARY
+ ###< create table crash_me10 (PRIMARY int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_prior=no # Keyword PRIOR
+ ###< create table crash_me10 (PRIOR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_privileges=yes # Keyword PRIVILEGES
+ ###< create table crash_me10 (PRIVILEGES int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'PRIVILEGES int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_procedure=yes # Keyword PROCEDURE
+ ###< create table crash_me10 (PROCEDURE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'PROCEDURE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_public=no # Keyword PUBLIC
+ ###< create table crash_me10 (PUBLIC int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_read=yes # Keyword READ
+ ###< create table crash_me10 (READ int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'READ int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_real=yes # Keyword REAL
+ ###< create table crash_me10 (REAL int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'REAL int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_recursive=no # Keyword RECURSIVE
+ ###< create table crash_me10 (RECURSIVE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_ref=no # Keyword REF
+ ###< create table crash_me10 (REF int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_references=yes # Keyword REFERENCES
+ ###< create table crash_me10 (REFERENCES int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'REFERENCES int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_referencing=no # Keyword REFERENCING
+ ###< create table crash_me10 (REFERENCING int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_relative=no # Keyword RELATIVE
+ ###< create table crash_me10 (RELATIVE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_resignal=no # Keyword RESIGNAL
+ ###< create table crash_me10 (RESIGNAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_restrict=yes # Keyword RESTRICT
+ ###< create table crash_me10 (RESTRICT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'RESTRICT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_return=no # Keyword RETURN
+ ###< create table crash_me10 (RETURN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_returns=yes # Keyword RETURNS
+ ###< create table crash_me10 (RETURNS int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'RETURNS int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_revoke=yes # Keyword REVOKE
+ ###< create table crash_me10 (REVOKE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'REVOKE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_right=yes # Keyword RIGHT
+ ###< create table crash_me10 (RIGHT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'RIGHT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_role=no # Keyword ROLE
+ ###< create table crash_me10 (ROLE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_rollback=no # Keyword ROLLBACK
+ ###< create table crash_me10 (ROLLBACK int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_routine=no # Keyword ROUTINE
+ ###< create table crash_me10 (ROUTINE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_row=no # Keyword ROW
+ ###< create table crash_me10 (ROW int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_rows=no # Keyword ROWS
+ ###< create table crash_me10 (ROWS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_savepoint=no # Keyword SAVEPOINT
+ ###< create table crash_me10 (SAVEPOINT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_schema=no # Keyword SCHEMA
+ ###< create table crash_me10 (SCHEMA int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_scroll=no # Keyword SCROLL
+ ###< create table crash_me10 (SCROLL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_search=no # Keyword SEARCH
+ ###< create table crash_me10 (SEARCH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_second=no # Keyword SECOND
+ ###< create table crash_me10 (SECOND int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_section=no # Keyword SECTION
+ ###< create table crash_me10 (SECTION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_select=yes # Keyword SELECT
+ ###< create table crash_me10 (SELECT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_sequence=no # Keyword SEQUENCE
+ ###< create table crash_me10 (SEQUENCE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_session=no # Keyword SESSION
+ ###< create table crash_me10 (SESSION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_session_user=no # Keyword SESSION_USER
+ ###< create table crash_me10 (SESSION_USER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_set=yes # Keyword SET
+ ###< create table crash_me10 (SET int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_signal=no # Keyword SIGNAL
+ ###< create table crash_me10 (SIGNAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_size=no # Keyword SIZE
+ ###< create table crash_me10 (SIZE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_smallint=yes # Keyword SMALLINT
+ ###< create table crash_me10 (SMALLINT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SMALLINT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_some=no # Keyword SOME
+ ###< create table crash_me10 (SOME int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_space=no # Keyword SPACE
+ ###< create table crash_me10 (SPACE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_sql=no # Keyword SQL
+ ###< create table crash_me10 (SQL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_sqlexception=no # Keyword SQLEXCEPTION
+ ###< create table crash_me10 (SQLEXCEPTION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_sqlstate=no # Keyword SQLSTATE
+ ###< create table crash_me10 (SQLSTATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_sqlwarning=no # Keyword SQLWARNING
+ ###< create table crash_me10 (SQLWARNING int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_structure=no # Keyword STRUCTURE
+ ###< create table crash_me10 (STRUCTURE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_system_user=no # Keyword SYSTEM_USER
+ ###< create table crash_me10 (SYSTEM_USER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_table=yes # Keyword TABLE
+ ###< create table crash_me10 (TABLE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'TABLE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_temporary=no # Keyword TEMPORARY
+ ###< create table crash_me10 (TEMPORARY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_then=yes # Keyword THEN
+ ###< create table crash_me10 (THEN int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'THEN int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_time=no # Keyword TIME
+ ###< create table crash_me10 (TIME int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_timestamp=no # Keyword TIMESTAMP
+ ###< create table crash_me10 (TIMESTAMP int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_timezone_hour=no # Keyword TIMEZONE_HOUR
+ ###< create table crash_me10 (TIMEZONE_HOUR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_timezone_minute=no # Keyword TIMEZONE_MINUTE
+ ###< create table crash_me10 (TIMEZONE_MINUTE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_to=yes # Keyword TO
+ ###< create table crash_me10 (TO int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'TO int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_trailing=yes # Keyword TRAILING
+ ###< create table crash_me10 (TRAILING int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'TRAILING int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_transaction=no # Keyword TRANSACTION
+ ###< create table crash_me10 (TRANSACTION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_translation=no # Keyword TRANSLATION
+ ###< create table crash_me10 (TRANSLATION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_trigger=no # Keyword TRIGGER
+ ###< create table crash_me10 (TRIGGER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_true=no # Keyword TRUE
+ ###< create table crash_me10 (TRUE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_under=no # Keyword UNDER
+ ###< create table crash_me10 (UNDER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_union=yes # Keyword UNION
+ ###< create table crash_me10 (UNION int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_unique=yes # Keyword UNIQUE
+ ###< create table crash_me10 (UNIQUE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_unknown=no # Keyword UNKNOWN
+ ###< create table crash_me10 (UNKNOWN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_update=yes # Keyword UPDATE
+ ###< create table crash_me10 (UPDATE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_usage=yes # Keyword USAGE
+ ###< create table crash_me10 (USAGE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'USAGE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_user=no # Keyword USER
+ ###< create table crash_me10 (USER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_using=yes # Keyword USING
+ ###< create table crash_me10 (USING int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'USING int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_value=no # Keyword VALUE
+ ###< create table crash_me10 (VALUE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_values=yes # Keyword VALUES
+ ###< create table crash_me10 (VALUES int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_varchar=yes # Keyword VARCHAR
+ ###< create table crash_me10 (VARCHAR int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'VARCHAR int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_variable=no # Keyword VARIABLE
+ ###< create table crash_me10 (VARIABLE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_varying=yes # Keyword VARYING
+ ###< create table crash_me10 (VARYING int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'VARYING int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_view=no # Keyword VIEW
+ ###< create table crash_me10 (VIEW int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_when=yes # Keyword WHEN
+ ###< create table crash_me10 (WHEN int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHEN int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_whenever=no # Keyword WHENEVER
+ ###< create table crash_me10 (WHENEVER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_where=yes # Keyword WHERE
+ ###< create table crash_me10 (WHERE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_while=no # Keyword WHILE
+ ###< create table crash_me10 (WHILE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_with=yes # Keyword WITH
+ ###< create table crash_me10 (WITH int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'WITH int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_without=no # Keyword WITHOUT
+ ###< create table crash_me10 (WITHOUT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_work=no # Keyword WORK
+ ###< create table crash_me10 (WORK int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_write=yes # Keyword WRITE
+ ###< create table crash_me10 (WRITE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'WRITE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi-92/99_year=no # Keyword YEAR
+ ###< create table crash_me10 (YEAR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi-92/99_zone=no # Keyword ZONE
+ ###< create table crash_me10 (ZONE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_async=no # Keyword ASYNC
+ ###< create table crash_me10 (ASYNC int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_avg=no # Keyword AVG
+ ###< create table crash_me10 (AVG int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_between=yes # Keyword BETWEEN
+ ###< create table crash_me10 (BETWEEN int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'BETWEEN int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi92_bit_length=no # Keyword BIT_LENGTH
+ ###< create table crash_me10 (BIT_LENGTH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_char_length=no # Keyword CHAR_LENGTH
+ ###< create table crash_me10 (CHAR_LENGTH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_character_length=no # Keyword CHARACTER_LENGTH
+ ###< create table crash_me10 (CHARACTER_LENGTH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_coalesce=no # Keyword COALESCE
+ ###< create table crash_me10 (COALESCE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_convert=no # Keyword CONVERT
+ ###< create table crash_me10 (CONVERT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_count=no # Keyword COUNT
+ ###< create table crash_me10 (COUNT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_exists=yes # Keyword EXISTS
+ ###< create table crash_me10 (EXISTS int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'EXISTS int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi92_extract=no # Keyword EXTRACT
+ ###< create table crash_me10 (EXTRACT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_insensitive=no # Keyword INSENSITIVE
+ ###< create table crash_me10 (INSENSITIVE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_lower=no # Keyword LOWER
+ ###< create table crash_me10 (LOWER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_max=no # Keyword MAX
+ ###< create table crash_me10 (MAX int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_min=no # Keyword MIN
+ ###< create table crash_me10 (MIN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_nullif=no # Keyword NULLIF
+ ###< create table crash_me10 (NULLIF int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_octet_length=no # Keyword OCTET_LENGTH
+ ###< create table crash_me10 (OCTET_LENGTH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_oid=no # Keyword OID
+ ###< create table crash_me10 (OID int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_operators=no # Keyword OPERATORS
+ ###< create table crash_me10 (OPERATORS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_others=no # Keyword OTHERS
+ ###< create table crash_me10 (OTHERS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_overlaps=no # Keyword OVERLAPS
+ ###< create table crash_me10 (OVERLAPS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_pendant=no # Keyword PENDANT
+ ###< create table crash_me10 (PENDANT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_position=no # Keyword POSITION
+ ###< create table crash_me10 (POSITION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_private=no # Keyword PRIVATE
+ ###< create table crash_me10 (PRIVATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_protected=no # Keyword PROTECTED
+ ###< create table crash_me10 (PROTECTED int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_replace=yes # Keyword REPLACE
+ ###< create table crash_me10 (REPLACE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'REPLACE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi92_sensitive=no # Keyword SENSITIVE
+ ###< create table crash_me10 (SENSITIVE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_similar=no # Keyword SIMILAR
+ ###< create table crash_me10 (SIMILAR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_sqlcode=no # Keyword SQLCODE
+ ###< create table crash_me10 (SQLCODE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_sqlerror=no # Keyword SQLERROR
+ ###< create table crash_me10 (SQLERROR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_substring=no # Keyword SUBSTRING
+ ###< create table crash_me10 (SUBSTRING int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_sum=no # Keyword SUM
+ ###< create table crash_me10 (SUM int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_test=no # Keyword TEST
+ ###< create table crash_me10 (TEST int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_there=no # Keyword THERE
+ ###< create table crash_me10 (THERE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_translate=no # Keyword TRANSLATE
+ ###< create table crash_me10 (TRANSLATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_trim=no # Keyword TRIM
+ ###< create table crash_me10 (TRIM int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_type=no # Keyword TYPE
+ ###< create table crash_me10 (TYPE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_upper=no # Keyword UPPER
+ ###< create table crash_me10 (UPPER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_virtual=no # Keyword VIRTUAL
+ ###< create table crash_me10 (VIRTUAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_visible=no # Keyword VISIBLE
+ ###< create table crash_me10 (VISIBLE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi92_wait=no # Keyword WAIT
+ ###< create table crash_me10 (WAIT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_admin=no # Keyword ADMIN
+ ###< create table crash_me10 (ADMIN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_aggregate=no # Keyword AGGREGATE
+ ###< create table crash_me10 (AGGREGATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_array=no # Keyword ARRAY
+ ###< create table crash_me10 (ARRAY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_binary=yes # Keyword BINARY
+ ###< create table crash_me10 (BINARY int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'BINARY int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi99_blob=yes # Keyword BLOB
+ ###< create table crash_me10 (BLOB int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'BLOB int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi99_class=no # Keyword CLASS
+ ###< create table crash_me10 (CLASS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_clob=no # Keyword CLOB
+ ###< create table crash_me10 (CLOB int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_condition=no # Keyword CONDITION
+ ###< create table crash_me10 (CONDITION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_constructor=no # Keyword CONSTRUCTOR
+ ###< create table crash_me10 (CONSTRUCTOR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_contains=no # Keyword CONTAINS
+ ###< create table crash_me10 (CONTAINS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_cube=no # Keyword CUBE
+ ###< create table crash_me10 (CUBE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_current_path=no # Keyword CURRENT_PATH
+ ###< create table crash_me10 (CURRENT_PATH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_current_role=no # Keyword CURRENT_ROLE
+ ###< create table crash_me10 (CURRENT_ROLE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_datalink=no # Keyword DATALINK
+ ###< create table crash_me10 (DATALINK int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_deref=no # Keyword DEREF
+ ###< create table crash_me10 (DEREF int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_destroy=no # Keyword DESTROY
+ ###< create table crash_me10 (DESTROY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_destructor=no # Keyword DESTRUCTOR
+ ###< create table crash_me10 (DESTRUCTOR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_deterministic=no # Keyword DETERMINISTIC
+ ###< create table crash_me10 (DETERMINISTIC int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_do=no # Keyword DO
+ ###< create table crash_me10 (DO int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_dynamic=no # Keyword DYNAMIC
+ ###< create table crash_me10 (DYNAMIC int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_every=no # Keyword EVERY
+ ###< create table crash_me10 (EVERY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_exit=no # Keyword EXIT
+ ###< create table crash_me10 (EXIT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_expand=no # Keyword EXPAND
+ ###< create table crash_me10 (EXPAND int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_expanding=no # Keyword EXPANDING
+ ###< create table crash_me10 (EXPANDING int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_free=no # Keyword FREE
+ ###< create table crash_me10 (FREE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_function=no # Keyword FUNCTION
+ ###< create table crash_me10 (FUNCTION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_grouping=no # Keyword GROUPING
+ ###< create table crash_me10 (GROUPING int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_handler=no # Keyword HANDLER
+ ###< create table crash_me10 (HANDLER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_hast=no # Keyword HAST
+ ###< create table crash_me10 (HAST int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_host=no # Keyword HOST
+ ###< create table crash_me10 (HOST int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_initialize=no # Keyword INITIALIZE
+ ###< create table crash_me10 (INITIALIZE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_inout=no # Keyword INOUT
+ ###< create table crash_me10 (INOUT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_iterate=no # Keyword ITERATE
+ ###< create table crash_me10 (ITERATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_large=no # Keyword LARGE
+ ###< create table crash_me10 (LARGE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_lateral=no # Keyword LATERAL
+ ###< create table crash_me10 (LATERAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_localtime=yes # Keyword LOCALTIME
+ ###< create table crash_me10 (LOCALTIME int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LOCALTIME int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi99_localtimestamp=yes # Keyword LOCALTIMESTAMP
+ ###< create table crash_me10 (LOCALTIMESTAMP int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LOCALTIMESTAMP int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_ansi99_locator=no # Keyword LOCATOR
+ ###< create table crash_me10 (LOCATOR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_meets=no # Keyword MEETS
+ ###< create table crash_me10 (MEETS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_modifies=no # Keyword MODIFIES
+ ###< create table crash_me10 (MODIFIES int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_nclob=no # Keyword NCLOB
+ ###< create table crash_me10 (NCLOB int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_normalize=no # Keyword NORMALIZE
+ ###< create table crash_me10 (NORMALIZE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_ordinality=no # Keyword ORDINALITY
+ ###< create table crash_me10 (ORDINALITY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_out=no # Keyword OUT
+ ###< create table crash_me10 (OUT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_parameter=no # Keyword PARAMETER
+ ###< create table crash_me10 (PARAMETER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_path=no # Keyword PATH
+ ###< create table crash_me10 (PATH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_period=no # Keyword PERIOD
+ ###< create table crash_me10 (PERIOD int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_postfix=no # Keyword POSTFIX
+ ###< create table crash_me10 (POSTFIX int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_precedes=no # Keyword PRECEDES
+ ###< create table crash_me10 (PRECEDES int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_prefix=no # Keyword PREFIX
+ ###< create table crash_me10 (PREFIX int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_reads=no # Keyword READS
+ ###< create table crash_me10 (READS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_redo=no # Keyword REDO
+ ###< create table crash_me10 (REDO int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_repeat=no # Keyword REPEAT
+ ###< create table crash_me10 (REPEAT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_result=no # Keyword RESULT
+ ###< create table crash_me10 (RESULT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_rollup=no # Keyword ROLLUP
+ ###< create table crash_me10 (ROLLUP int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_sets=no # Keyword SETS
+ ###< create table crash_me10 (SETS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_specific=no # Keyword SPECIFIC
+ ###< create table crash_me10 (SPECIFIC int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_specifictype=no # Keyword SPECIFICTYPE
+ ###< create table crash_me10 (SPECIFICTYPE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_start=no # Keyword START
+ ###< create table crash_me10 (START int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_state=no # Keyword STATE
+ ###< create table crash_me10 (STATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_static=no # Keyword STATIC
+ ###< create table crash_me10 (STATIC int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_succeeds=no # Keyword SUCCEEDS
+ ###< create table crash_me10 (SUCCEEDS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_terminate=no # Keyword TERMINATE
+ ###< create table crash_me10 (TERMINATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_than=no # Keyword THAN
+ ###< create table crash_me10 (THAN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_treat=no # Keyword TREAT
+ ###< create table crash_me10 (TREAT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_undo=no # Keyword UNDO
+ ###< create table crash_me10 (UNDO int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_ansi99_until=no # Keyword UNTIL
+ ###< create table crash_me10 (UNTIL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_access=no # Keyword ACCESS
+ ###< create table crash_me10 (ACCESS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_analyze=yes # Keyword ANALYZE
+ ###< create table crash_me10 (ANALYZE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ANALYZE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_audit=no # Keyword AUDIT
+ ###< create table crash_me10 (AUDIT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_auto_increment=no # Keyword AUTO_INCREMENT
+ ###< create table crash_me10 (AUTO_INCREMENT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_backup=no # Keyword BACKUP
+ ###< create table crash_me10 (BACKUP int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_bdb=no # Keyword BDB
+ ###< create table crash_me10 (BDB int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_berkeleydb=no # Keyword BERKELEYDB
+ ###< create table crash_me10 (BERKELEYDB int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_bigint=yes # Keyword BIGINT
+ ###< create table crash_me10 (BIGINT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'BIGINT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_break=no # Keyword BREAK
+ ###< create table crash_me10 (BREAK int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_browse=no # Keyword BROWSE
+ ###< create table crash_me10 (BROWSE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_btree=no # Keyword BTREE
+ ###< create table crash_me10 (BTREE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_bulk=no # Keyword BULK
+ ###< create table crash_me10 (BULK int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_change=yes # Keyword CHANGE
+ ###< create table crash_me10 (CHANGE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHANGE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_checkpoint=no # Keyword CHECKPOINT
+ ###< create table crash_me10 (CHECKPOINT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_cluster=no # Keyword CLUSTER
+ ###< create table crash_me10 (CLUSTER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_clustered=no # Keyword CLUSTERED
+ ###< create table crash_me10 (CLUSTERED int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_columns=yes # Keyword COLUMNS
+ ###< create table crash_me10 (COLUMNS int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'COLUMNS int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_comment=no # Keyword COMMENT
+ ###< create table crash_me10 (COMMENT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_compress=no # Keyword COMPRESS
+ ###< create table crash_me10 (COMPRESS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_compute=no # Keyword COMPUTE
+ ###< create table crash_me10 (COMPUTE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_containstable=no # Keyword CONTAINSTABLE
+ ###< create table crash_me10 (CONTAINSTABLE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_database=yes # Keyword DATABASE
+ ###< create table crash_me10 (DATABASE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DATABASE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_databases=yes # Keyword DATABASES
+ ###< create table crash_me10 (DATABASES int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DATABASES int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_day_hour=yes # Keyword DAY_HOUR
+ ###< create table crash_me10 (DAY_HOUR int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DAY_HOUR int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_day_minute=yes # Keyword DAY_MINUTE
+ ###< create table crash_me10 (DAY_MINUTE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DAY_MINUTE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_day_second=yes # Keyword DAY_SECOND
+ ###< create table crash_me10 (DAY_SECOND int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DAY_SECOND int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_dbcc=no # Keyword DBCC
+ ###< create table crash_me10 (DBCC int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_delayed=yes # Keyword DELAYED
+ ###< create table crash_me10 (DELAYED int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELAYED int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_deny=no # Keyword DENY
+ ###< create table crash_me10 (DENY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_disk=no # Keyword DISK
+ ###< create table crash_me10 (DISK int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_distinctrow=yes # Keyword DISTINCTROW
+ ###< create table crash_me10 (DISTINCTROW int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'DISTINCTROW int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_distributed=no # Keyword DISTRIBUTED
+ ###< create table crash_me10 (DISTRIBUTED int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_dummy=no # Keyword DUMMY
+ ###< create table crash_me10 (DUMMY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_dump=no # Keyword DUMP
+ ###< create table crash_me10 (DUMP int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_enclosed=yes # Keyword ENCLOSED
+ ###< create table crash_me10 (ENCLOSED int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ENCLOSED int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_errlvl=no # Keyword ERRLVL
+ ###< create table crash_me10 (ERRLVL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_errors=no # Keyword ERRORS
+ ###< create table crash_me10 (ERRORS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_escaped=yes # Keyword ESCAPED
+ ###< create table crash_me10 (ESCAPED int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ESCAPED int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_exclusive=no # Keyword EXCLUSIVE
+ ###< create table crash_me10 (EXCLUSIVE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_explain=yes # Keyword EXPLAIN
+ ###< create table crash_me10 (EXPLAIN int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'EXPLAIN int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_fields=yes # Keyword FIELDS
+ ###< create table crash_me10 (FIELDS int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'FIELDS int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_file=no # Keyword FILE
+ ###< create table crash_me10 (FILE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_fillfactor=no # Keyword FILLFACTOR
+ ###< create table crash_me10 (FILLFACTOR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_freetext=no # Keyword FREETEXT
+ ###< create table crash_me10 (FREETEXT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_freetexttable=no # Keyword FREETEXTTABLE
+ ###< create table crash_me10 (FREETEXTTABLE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_fulltext=yes # Keyword FULLTEXT
+ ###< create table crash_me10 (FULLTEXT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_geometry=no # Keyword GEOMETRY
+ ###< create table crash_me10 (GEOMETRY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_hash=no # Keyword HASH
+ ###< create table crash_me10 (HASH int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_high_priority=yes # Keyword HIGH_PRIORITY
+ ###< create table crash_me10 (HIGH_PRIORITY int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'HIGH_PRIORITY int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_holdlock=no # Keyword HOLDLOCK
+ ###< create table crash_me10 (HOLDLOCK int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_hour_minute=yes # Keyword HOUR_MINUTE
+ ###< create table crash_me10 (HOUR_MINUTE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'HOUR_MINUTE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_hour_second=yes # Keyword HOUR_SECOND
+ ###< create table crash_me10 (HOUR_SECOND int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'HOUR_SECOND int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_identified=no # Keyword IDENTIFIED
+ ###< create table crash_me10 (IDENTIFIED int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_identity_insert=no # Keyword IDENTITY_INSERT
+ ###< create table crash_me10 (IDENTITY_INSERT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_identitycol=no # Keyword IDENTITYCOL
+ ###< create table crash_me10 (IDENTITYCOL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_increment=no # Keyword INCREMENT
+ ###< create table crash_me10 (INCREMENT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_index=yes # Keyword INDEX
+ ###< create table crash_me10 (INDEX int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_infile=yes # Keyword INFILE
+ ###< create table crash_me10 (INFILE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'INFILE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_initial=no # Keyword INITIAL
+ ###< create table crash_me10 (INITIAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_innodb=no # Keyword INNODB
+ ###< create table crash_me10 (INNODB int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_keys=yes # Keyword KEYS
+ ###< create table crash_me10 (KEYS int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'KEYS int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_kill=yes # Keyword KILL
+ ###< create table crash_me10 (KILL int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'KILL int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_lineno=no # Keyword LINENO
+ ###< create table crash_me10 (LINENO int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_lines=yes # Keyword LINES
+ ###< create table crash_me10 (LINES int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LINES int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_load=yes # Keyword LOAD
+ ###< create table crash_me10 (LOAD int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LOAD int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_lock=yes # Keyword LOCK
+ ###< create table crash_me10 (LOCK int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LOCK int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_long=yes # Keyword LONG
+ ###< create table crash_me10 (LONG int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LONG int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_longblob=yes # Keyword LONGBLOB
+ ###< create table crash_me10 (LONGBLOB int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LONGBLOB int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_longtext=yes # Keyword LONGTEXT
+ ###< create table crash_me10 (LONGTEXT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LONGTEXT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_low_priority=yes # Keyword LOW_PRIORITY
+ ###< create table crash_me10 (LOW_PRIORITY int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'LOW_PRIORITY int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_master_server_id=yes # Keyword MASTER_SERVER_ID
+ ###< create table crash_me10 (MASTER_SERVER_ID int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'MASTER_SERVER_ID int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_maxextents=no # Keyword MAXEXTENTS
+ ###< create table crash_me10 (MAXEXTENTS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_mediumblob=yes # Keyword MEDIUMBLOB
+ ###< create table crash_me10 (MEDIUMBLOB int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'MEDIUMBLOB int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_mediumint=yes # Keyword MEDIUMINT
+ ###< create table crash_me10 (MEDIUMINT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'MEDIUMINT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_mediumtext=yes # Keyword MEDIUMTEXT
+ ###< create table crash_me10 (MEDIUMTEXT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'MEDIUMTEXT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_middleint=yes # Keyword MIDDLEINT
+ ###< create table crash_me10 (MIDDLEINT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'MIDDLEINT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_minus=no # Keyword MINUS
+ ###< create table crash_me10 (MINUS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_minute_second=yes # Keyword MINUTE_SECOND
+ ###< create table crash_me10 (MINUTE_SECOND int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'MINUTE_SECOND int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_mlslabel=no # Keyword MLSLABEL
+ ###< create table crash_me10 (MLSLABEL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_mode=no # Keyword MODE
+ ###< create table crash_me10 (MODE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_mrg_myisam=no # Keyword MRG_MYISAM
+ ###< create table crash_me10 (MRG_MYISAM int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_noaudit=no # Keyword NOAUDIT
+ ###< create table crash_me10 (NOAUDIT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_nocheck=no # Keyword NOCHECK
+ ###< create table crash_me10 (NOCHECK int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_nocompress=no # Keyword NOCOMPRESS
+ ###< create table crash_me10 (NOCOMPRESS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_nonclustered=no # Keyword NONCLUSTERED
+ ###< create table crash_me10 (NONCLUSTERED int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_nowait=no # Keyword NOWAIT
+ ###< create table crash_me10 (NOWAIT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_number=no # Keyword NUMBER
+ ###< create table crash_me10 (NUMBER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_offline=no # Keyword OFFLINE
+ ###< create table crash_me10 (OFFLINE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_offsets=no # Keyword OFFSETS
+ ###< create table crash_me10 (OFFSETS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_online=no # Keyword ONLINE
+ ###< create table crash_me10 (ONLINE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_opendatasource=no # Keyword OPENDATASOURCE
+ ###< create table crash_me10 (OPENDATASOURCE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_openquery=no # Keyword OPENQUERY
+ ###< create table crash_me10 (OPENQUERY int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_openrowset=no # Keyword OPENROWSET
+ ###< create table crash_me10 (OPENROWSET int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_openxml=no # Keyword OPENXML
+ ###< create table crash_me10 (OPENXML int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_optimize=yes # Keyword OPTIMIZE
+ ###< create table crash_me10 (OPTIMIZE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'OPTIMIZE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_optionally=yes # Keyword OPTIONALLY
+ ###< create table crash_me10 (OPTIONALLY int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'OPTIONALLY int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_outfile=yes # Keyword OUTFILE
+ ###< create table crash_me10 (OUTFILE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'OUTFILE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_over=no # Keyword OVER
+ ###< create table crash_me10 (OVER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_pctfree=no # Keyword PCTFREE
+ ###< create table crash_me10 (PCTFREE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_percent=no # Keyword PERCENT
+ ###< create table crash_me10 (PERCENT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_plan=no # Keyword PLAN
+ ###< create table crash_me10 (PLAN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_print=no # Keyword PRINT
+ ###< create table crash_me10 (PRINT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_proc=no # Keyword PROC
+ ###< create table crash_me10 (PROC int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_purge=yes # Keyword PURGE
+ ###< create table crash_me10 (PURGE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'PURGE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_raiserror=no # Keyword RAISERROR
+ ###< create table crash_me10 (RAISERROR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_raw=no # Keyword RAW
+ ###< create table crash_me10 (RAW int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_readtext=no # Keyword READTEXT
+ ###< create table crash_me10 (READTEXT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_reconfigure=no # Keyword RECONFIGURE
+ ###< create table crash_me10 (RECONFIGURE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_regexp=yes # Keyword REGEXP
+ ###< create table crash_me10 (REGEXP int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'REGEXP int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_rename=yes # Keyword RENAME
+ ###< create table crash_me10 (RENAME int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'RENAME int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_replication=no # Keyword REPLICATION
+ ###< create table crash_me10 (REPLICATION int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_require=yes # Keyword REQUIRE
+ ###< create table crash_me10 (REQUIRE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'REQUIRE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_resource=no # Keyword RESOURCE
+ ###< create table crash_me10 (RESOURCE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_restore=no # Keyword RESTORE
+ ###< create table crash_me10 (RESTORE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_rlike=yes # Keyword RLIKE
+ ###< create table crash_me10 (RLIKE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'RLIKE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_rowcount=no # Keyword ROWCOUNT
+ ###< create table crash_me10 (ROWCOUNT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_rowguidcol=no # Keyword ROWGUIDCOL
+ ###< create table crash_me10 (ROWGUIDCOL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_rowid=no # Keyword ROWID
+ ###< create table crash_me10 (ROWID int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_rownum=no # Keyword ROWNUM
+ ###< create table crash_me10 (ROWNUM int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_rtree=no # Keyword RTREE
+ ###< create table crash_me10 (RTREE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_rule=no # Keyword RULE
+ ###< create table crash_me10 (RULE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_save=no # Keyword SAVE
+ ###< create table crash_me10 (SAVE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_setuser=no # Keyword SETUSER
+ ###< create table crash_me10 (SETUSER int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_share=no # Keyword SHARE
+ ###< create table crash_me10 (SHARE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_show=yes # Keyword SHOW
+ ###< create table crash_me10 (SHOW int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SHOW int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_shutdown=no # Keyword SHUTDOWN
+ ###< create table crash_me10 (SHUTDOWN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_soname=yes # Keyword SONAME
+ ###< create table crash_me10 (SONAME int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SONAME int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_spatial=no # Keyword SPATIAL
+ ###< create table crash_me10 (SPATIAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_sql_big_result=yes # Keyword SQL_BIG_RESULT
+ ###< create table crash_me10 (SQL_BIG_RESULT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SQL_BIG_RESULT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_sql_calc_found_rows=yes # Keyword SQL_CALC_FOUND_ROWS
+ ###< create table crash_me10 (SQL_CALC_FOUND_ROWS int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SQL_CALC_FOUND_ROWS int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_sql_small_result=yes # Keyword SQL_SMALL_RESULT
+ ###< create table crash_me10 (SQL_SMALL_RESULT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SQL_SMALL_RESULT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_ssl=yes # Keyword SSL
+ ###< create table crash_me10 (SSL int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SSL int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_starting=yes # Keyword STARTING
+ ###< create table crash_me10 (STARTING int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'STARTING int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_statistics=no # Keyword STATISTICS
+ ###< create table crash_me10 (STATISTICS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_straight_join=yes # Keyword STRAIGHT_JOIN
+ ###< create table crash_me10 (STRAIGHT_JOIN int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'STRAIGHT_JOIN int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_striped=no # Keyword STRIPED
+ ###< create table crash_me10 (STRIPED int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_successful=no # Keyword SUCCESSFUL
+ ###< create table crash_me10 (SUCCESSFUL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_synonym=no # Keyword SYNONYM
+ ###< create table crash_me10 (SYNONYM int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_sysdate=no # Keyword SYSDATE
+ ###< create table crash_me10 (SYSDATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_tables=yes # Keyword TABLES
+ ###< create table crash_me10 (TABLES int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'TABLES int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_terminated=yes # Keyword TERMINATED
+ ###< create table crash_me10 (TERMINATED int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'TERMINATED int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_textsize=no # Keyword TEXTSIZE
+ ###< create table crash_me10 (TEXTSIZE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_tinyblob=yes # Keyword TINYBLOB
+ ###< create table crash_me10 (TINYBLOB int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'TINYBLOB int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_tinyint=yes # Keyword TINYINT
+ ###< create table crash_me10 (TINYINT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'TINYINT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_tinytext=yes # Keyword TINYTEXT
+ ###< create table crash_me10 (TINYTEXT int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'TINYTEXT int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_top=no # Keyword TOP
+ ###< create table crash_me10 (TOP int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_tran=no # Keyword TRAN
+ ###< create table crash_me10 (TRAN int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_truncate=no # Keyword TRUNCATE
+ ###< create table crash_me10 (TRUNCATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_tsequal=no # Keyword TSEQUAL
+ ###< create table crash_me10 (TSEQUAL int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_types=no # Keyword TYPES
+ ###< create table crash_me10 (TYPES int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_uid=no # Keyword UID
+ ###< create table crash_me10 (UID int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_unlock=yes # Keyword UNLOCK
+ ###< create table crash_me10 (UNLOCK int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNLOCK int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_unsigned=yes # Keyword UNSIGNED
+ ###< create table crash_me10 (UNSIGNED int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNSIGNED int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_updatetext=no # Keyword UPDATETEXT
+ ###< create table crash_me10 (UPDATETEXT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_use=yes # Keyword USE
+ ###< create table crash_me10 (USE int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'USE int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_user_resources=no # Keyword USER_RESOURCES
+ ###< create table crash_me10 (USER_RESOURCES int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_validate=no # Keyword VALIDATE
+ ###< create table crash_me10 (VALIDATE int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_varbinary=yes # Keyword VARBINARY
+ ###< create table crash_me10 (VARBINARY int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'VARBINARY int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_varchar2=no # Keyword VARCHAR2
+ ###< create table crash_me10 (VARCHAR2 int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_waitfor=no # Keyword WAITFOR
+ ###< create table crash_me10 (WAITFOR int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_warnings=no # Keyword WARNINGS
+ ###< create table crash_me10 (WARNINGS int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_writetext=no # Keyword WRITETEXT
+ ###< create table crash_me10 (WRITETEXT int not null)
+ ###> OK
+ ###< drop table crash_me10
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is NO
+reserved_word_extra_xor=yes # Keyword XOR
+ ###< create table crash_me10 (XOR int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'XOR int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_year_month=yes # Keyword YEAR_MONTH
+ ###< create table crash_me10 (YEAR_MONTH int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'YEAR_MONTH int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
+reserved_word_extra_zerofill=yes # Keyword ZEROFILL
+ ###< create table crash_me10 (ZEROFILL int not null)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ZEROFILL int not null)' at line 1
+ ###< drop table crash_me10
+ ###> execute error:Unknown table 'crash_me10'
+ ###
+ ###As far as some queries didnt return OK, result is YES
right_outer_join=yes # right outer join
+ ###< select crash_me.a from crash_me right join crash_me2 ON crash_me.a=crash_me2.a
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+rollback_metadata=no # rollback_metadata
+ ###< create table crash_q (a integer not null)
+ ###> OK
+ ###
+ ###< insert into crash_q values (1)
+ ###> OK
rowid=auto_increment # Type for row id
+ ###< create table crash_q (a rowid)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'rowid)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###< create table crash_q (a int not null auto_increment, primary key(a))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+safe_decimal_arithmetic=no # safe decimal arithmetic
+ ###< create table crash_me_a (a decimal(10,2),b decimal(10,2))
+ ###> OK
+ ###
+ ###< insert into crash_me_a (a,b) values (11.4,18.9)
+ ###> OK
+ ###
+ ###<select count(*) from crash_me_a where a+b=30.3
+ ###>0
+ ###We expected '1' but got '0'
select_constants=yes # Select constants
+ ###< select 1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
select_limit=with LIMIT # LIMIT number of rows
+ ###< select * from crash_me limit 1
+ ###> OK
select_limit2=yes # SELECT with LIMIT #,#
+ ###< select * from crash_me limit 1,1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+select_limit3=yes # SELECT with LIMIT # OFFSET #
+ ###< select * from crash_me limit 1 offset 1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
select_string_size=1048565 # constant string size in SELECT
+ ###We are trying (example with N=5):
+ ###select 'aaaaa'
select_table_update=no # Update with sub select
+ ###< create table crash_q (a integer,b char(10))
+ ###> OK
+ ###< insert into crash_q values(1,'c')
+ ###> OK
+ ###< update crash_q set b= (select b from crash_me where crash_q.a = crash_me.a)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select b from crash_me where crash_q.a = crash_me.a)' at line 1
+ ###
+ ###< drop table crash_q
+ ###> OK
select_without_from=yes # SELECT without FROM
-server_version=MySQL 3.23.39 debug # server version
+ ###< select 1
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+server_version=MySQL 4.0.15 debug log/ # server version
simple_joins=yes # ANSI SQL simple joins
+ ###< select crash_me.a from crash_me, crash_me t0
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+sorted_group_by=yes # Group by always sorted
+ ###< create table crash_me_t1 (a int not null, b int not null)
+ ###> OK
+ ###< insert into crash_me_t1 values (1,1)
+ ###> OK
+ ###< insert into crash_me_t1 values (1,2)
+ ###> OK
+ ###< insert into crash_me_t1 values (3,1)
+ ###> OK
+ ###< insert into crash_me_t1 values (3,2)
+ ###> OK
+ ###< insert into crash_me_t1 values (2,2)
+ ###> OK
+ ###< insert into crash_me_t1 values (2,1)
+ ###> OK
+ ###< create table crash_me_t2 (a int not null, b int not null)
+ ###> OK
+ ###< create index crash_me_t2_ind on crash_me_t2 (a)
+ ###> OK
+ ###< insert into crash_me_t2 values (1,3)
+ ###> OK
+ ###< insert into crash_me_t2 values (3,1)
+ ###> OK
+ ###< insert into crash_me_t2 values (2,2)
+ ###> OK
+ ###< insert into crash_me_t2 values (1,1)
+ ###> OK
+ ###
+ ###< select crash_me_t1.a,crash_me_t2.b from crash_me_t1,crash_me_t2 where crash_me_t1.a=crash_me_t2.a group by crash_me_t1.a,crash_me_t2.b
+ ### > 1,1
+ ### > 1,3
+ ### > 2,2
+ ### > 3,1
+ ###
+ ### Check recordset:
+ ### 1,1 expected: 1,1
+ ### 1,3 expected: 1,3
+ ### 2,2 expected: 2,2
+ ### 3,1 expected: 3,1
+ ### Recordset corresponds with template
+ ###< drop table crash_me_t1
+ ###> OK
+ ###< drop table crash_me_t2
+ ###> OK
storage_of_float=round # Storage of float values
+ ###< create table crash_q (q1 float(4,1))
+ ###> OK
+ ###< insert into crash_q values(1.14)
+ ###> OK
+ ###
+ ###<select q1 from crash_q
+ ###>1.1
+ ###
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###< create table crash_q (q1 float(4,1))
+ ###> OK
+ ###< insert into crash_q values(1.16)
+ ###> OK
+ ###
+ ###<select q1 from crash_q
+ ###>1.2
+ ###We expected '1.1' but got '1.2'
+ ###
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###< create table crash_q (q1 float(4,1))
+ ###> OK
+ ###< insert into crash_q values(1.14)
+ ###> OK
+ ###
+ ###<select q1 from crash_q
+ ###>1.1
+ ###
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###< create table crash_q (q1 float(4,1))
+ ###> OK
+ ###< insert into crash_q values(1.16)
+ ###> OK
+ ###
+ ###<select q1 from crash_q
+ ###>1.2
+ ###
+ ###< drop table crash_q
+ ###> OK
subqueries=no # subqueries
+ ###< select a from crash_me where crash_me.a in (select max(a) from crash_me)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select max(a) from crash_me)' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
table_alias=yes # Table alias
+ ###< select b.a from crash_me as b
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
table_name_case=no # case independent table names
+ ###< create table crash_q (q integer)
+ ###> OK
+ ###< drop table CRASH_Q
+ ###> execute error:Unknown table 'CRASH_Q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
table_wildcard=yes # Select table_name.*
+ ###< select crash_me.* from crash_me
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
temporary_table=yes # temporary tables
-transactions=yes # constant string size in where
+ ###< create temporary table crash_q (q integer not null)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+time_format_EUR=error # Supports HH.MM.SS (EUR) time format
+ ###< insert into crash_me_t(a) values ('20.08.16')
+ ###> OK
+ ###
+ ###<select a from crash_me_t
+ ###>00:00:20
+ ###We expected '20:08:16' but got '00:00:20'
+ ###
+ ###< delete from crash_me_t
+ ###> OK
+time_format_HHHHMMSS=yes # Supports HHHHmmSS time format
+ ###< insert into crash_me_t(a) values ('00200816')
+ ###> OK
+ ###
+ ###<select a from crash_me_t
+ ###>20:08:16
+ ###
+ ###< delete from crash_me_t
+ ###> OK
+time_format_ISO=yes # Supports HH:MM:SS (ISO) time format
+ ###< insert into crash_me_t(a) values ('20:08:16')
+ ###> OK
+ ###
+ ###<select a from crash_me_t
+ ###>20:08:16
+ ###
+ ###< delete from crash_me_t
+ ###> OK
+time_format_USA=error # Supports HH:MM:SS (AM|PM) time format
+ ###< insert into crash_me_t(a) values ('08:08:16 PM')
+ ###> OK
+ ###
+ ###<select a from crash_me_t
+ ###>08:08:16
+ ###We expected '20:08:16' but got '08:08:16'
+ ###
+ ###< delete from crash_me_t
+ ###> OK
+time_format_inresult=iso # Time format in result
+ ###< insert into crash_me_t values(CURRENT_TIME)
+ ###> OK
+ ###
+ ###< select a from crash_me_t
+ ###> 19:55:21
+ ###< delete from crash_me_t
+ ###> OK
+transactions=yes # transactions
+ ###<select * from crash_q
+ ###>1
+ ###We expected '' but got '1'
truncate_table=yes # truncate
+ ###< create table crash_q (a integer, b integer,c1 CHAR(10))
+ ###> OK
+ ###< truncate table crash_q
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_abstime=no # Type abstime
+ ###< create table crash_q (q abstime)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'abstime)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_bfile=no # Type bfile
+ ###< create table crash_q (q bfile)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'bfile)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_blob=yes # Type blob
+ ###< create table crash_q (q blob)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_bool=yes # Type bool
+ ###< create table crash_q (q bool)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_box=no # Type box
+ ###< create table crash_q (q box)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'box)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_byte=no # Type byte
+ ###< create table crash_q (q byte)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'byte)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_char(1_arg)_binary=yes # Type char(1 arg) binary
+ ###< create table crash_q (q char(10) binary)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_cidr=no # Type cidr
+ ###< create table crash_q (q cidr)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'cidr)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_circle=no # Type circle
+ ###< create table crash_q (q circle)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'circle)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_clob=no # Type clob
+ ###< create table crash_q (q clob)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'clob)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_datetime=yes # Type datetime
+ ###< create table crash_q (q datetime)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_double=yes # Type double
+ ###< create table crash_q (q double)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_enum(1_arg)=yes # Type enum(1 arg)
+ ###< create table crash_q (q enum('red'))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_float(2_arg)=yes # Type float(2 arg)
+ ###< create table crash_q (q float(6,2))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_float4=yes # Type float4
+ ###< create table crash_q (q float4)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_float8=yes # Type float8
+ ###< create table crash_q (q float8)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_image=no # Type image
+ ###< create table crash_q (q image)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'image)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_inet=no # Type inet
+ ###< create table crash_q (q inet)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'inet)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_int(1_arg)_zerofill=yes # Type int(1 arg) zerofill
+ ###< create table crash_q (q int(5) zerofill)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_int1=yes # Type int1
+ ###< create table crash_q (q int1)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_int2=yes # Type int2
+ ###< create table crash_q (q int2)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_int3=yes # Type int3
+ ###< create table crash_q (q int3)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_int4=yes # Type int4
+ ###< create table crash_q (q int4)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_int8=yes # Type int8
+ ###< create table crash_q (q int8)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_int_auto_increment=yes # Type int not null auto_increment
+ ###< create table crash_q (q int not null auto_increment,unique(q))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_int_identity=no # Type int not null identity
+ ###< create table crash_q (q int not null identity,unique(q))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'identity,unique(q))' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_int_unsigned=yes # Type int unsigned
+ ###< create table crash_q (q int unsigned)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_interval=no # Type interval
+ ###< create table crash_q (q interval)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_line=no # Type line
+ ###< create table crash_q (q line)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'line)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_long=no # Type long
+ ###< create table crash_q (q long)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_long_raw=no # Type long raw
+ ###< create table crash_q (q long raw)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'raw)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_long_varbinary=yes # Type long varbinary
+ ###< create table crash_q (q long varbinary)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_long_varchar(1_arg)=no # Type long varchar(1 arg)
+ ###< create table crash_q (q long varchar(1))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(1))' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_lseg=no # Type lseg
+ ###< create table crash_q (q lseg)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'lseg)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_macaddr=no # Type macaddr
+ ###< create table crash_q (q macaddr)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'macaddr)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_mediumint=yes # Type mediumint
+ ###< create table crash_q (q mediumint)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_mediumtext=yes # Type mediumtext
+ ###< create table crash_q (q mediumtext)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_middleint=yes # Type middleint
+ ###< create table crash_q (q middleint)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_mlslabel=no # Type mlslabel
+ ###< create table crash_q (q mlslabel)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'mlslabel)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_money=no # Type money
+ ###< create table crash_q (q money)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'money)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_nclob=no # Type nclob
+ ###< create table crash_q (q nclob)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'nclob)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_number=no # Type number
+ ###< create table crash_q (q number)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'number)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_number(1_arg)=no # Type number(1 arg)
+ ###< create table crash_q (q number(9))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'number(9))' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_number(2_arg)=no # Type number(2 arg)
+ ###< create table crash_q (q number(9,2))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'number(9,2))' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_nvarchar2(1_arg)=no # Type nvarchar2(1 arg)
+ ###< create table crash_q (q nvarchar2(16))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'nvarchar2(16))' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_path=no # Type path
+ ###< create table crash_q (q path)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'path)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_point=no # Type point
+ ###< create table crash_q (q point)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'point)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_polygon=no # Type polygon
+ ###< create table crash_q (q polygon)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'polygon)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_raw(1_arg)=no # Type raw(1 arg)
+ ###< create table crash_q (q raw(16))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'raw(16))' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_reltime=no # Type reltime
+ ###< create table crash_q (q reltime)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'reltime)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_rowid=no # Type rowid
+ ###< create table crash_q (q rowid)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'rowid)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_serial=no # Type serial
+ ###< create table crash_q (q serial)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'serial)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_set(1_arg)=yes # Type set(1 arg)
+ ###< create table crash_q (q set('red'))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_smalldatetime=no # Type smalldatetime
+ ###< create table crash_q (q smalldatetime)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'smalldatetime)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_smallfloat=no # Type smallfloat
+ ###< create table crash_q (q smallfloat)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'smallfloat)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_smallmoney=no # Type smallmoney
+ ###< create table crash_q (q smallmoney)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'smallmoney)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_text=yes # Type text
+ ###< create table crash_q (q text)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_extra_text(1_arg)=no # Type text(1 arg)
+ ###< create table crash_q (q text(10))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '(10))' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_timespan=no # Type timespan
+ ###< create table crash_q (q timespan)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'timespan)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_uint=no # Type uint
+ ###< create table crash_q (q uint)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'uint)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
+ ###< create table crash_q (q varchar2(257))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'varchar2(257))' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_extra_year=yes # Type year
+ ###< create table crash_q (q year)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_odbc_bigint=yes # Type bigint
+ ###< create table crash_q (q bigint)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_odbc_binary(1_arg)=yes # Type binary(1 arg)
+ ###< create table crash_q (q binary(1))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_odbc_datetime=yes # Type datetime
+ ###< create table crash_q (q datetime)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_odbc_tinyint=yes # Type tinyint
+ ###< create table crash_q (q tinyint)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_odbc_varbinary(1_arg)=yes # Type varbinary(1 arg)
+ ###< create table crash_q (q varbinary(1))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_bit=yes # Type bit
+ ###< create table crash_q (q bit)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_bit(1_arg)=yes # Type bit(1 arg)
+ ###< create table crash_q (q bit(2))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_bit_varying(1_arg)=no # Type bit varying(1 arg)
+ ###< create table crash_q (q bit varying(2))
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'varying(2))' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_boolean=no # Type boolean
+ ###< create table crash_q (q boolean)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'boolean)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_char(1_arg)=yes # Type char(1 arg)
+ ###< create table crash_q (q char(1))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
+ ###< create table crash_q (q char varying(1))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_character(1_arg)=yes # Type character(1 arg)
+ ###< create table crash_q (q character(1))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
+ ###< create table crash_q (q character varying(1))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_date=yes # Type date
+ ###< create table crash_q (q date)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_dec(2_arg)=yes # Type dec(2 arg)
+ ###< create table crash_q (q dec(6,2))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
+ ###< create table crash_q (q decimal(6,2))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_double_precision=yes # Type double precision
+ ###< create table crash_q (q double precision)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_float=yes # Type float
+ ###< create table crash_q (q float)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_float(1_arg)=yes # Type float(1 arg)
+ ###< create table crash_q (q float(8))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_int=yes # Type int
+ ###< create table crash_q (q int)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_integer=yes # Type integer
+ ###< create table crash_q (q integer)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_interval_day=no # Type interval day
+ ###< create table crash_q (q interval day)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_day_to_hour=no # Type interval day to hour
+ ###< create table crash_q (q interval day to hour)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day to hour)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_day_to_minute=no # Type interval day to minute
+ ###< create table crash_q (q interval day to minute)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day to minute)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_day_to_second=no # Type interval day to second
+ ###< create table crash_q (q interval day to second)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval day to second)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_hour=no # Type interval hour
+ ###< create table crash_q (q interval hour)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval hour)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_hour_to_minute=no # Type interval hour to minute
+ ###< create table crash_q (q interval hour to minute)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval hour to minute)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_hour_to_second=no # Type interval hour to second
+ ###< create table crash_q (q interval hour to second)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval hour to second)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_minute=no # Type interval minute
+ ###< create table crash_q (q interval minute)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval minute)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_minute_to_second=no # Type interval minute to second
+ ###< create table crash_q (q interval minute to second)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval minute to second)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_month=no # Type interval month
+ ###< create table crash_q (q interval month)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval month)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_second=no # Type interval second
+ ###< create table crash_q (q interval second)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval second)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_year=no # Type interval year
+ ###< create table crash_q (q interval year)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval year)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_interval_year_to_month=no # Type interval year to month
+ ###< create table crash_q (q interval year to month)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval year to month)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_national_char_varying(1_arg)=yes # Type national char varying(1 arg)
+ ###< create table crash_q (q national char varying(20))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_national_character(1_arg)=yes # Type national character(1 arg)
+ ###< create table crash_q (q national character(20))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_national_character_varying(1_arg)=yes # Type national character varying(1 arg)
+ ###< create table crash_q (q national character varying(20))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_nchar(1_arg)=yes # Type nchar(1 arg)
+ ###< create table crash_q (q nchar(1))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_nchar_varying(1_arg)=yes # Type nchar varying(1 arg)
+ ###< create table crash_q (q nchar varying(20))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
+ ###< create table crash_q (q numeric(9,2))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_real=yes # Type real
+ ###< create table crash_q (q real)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_smallint=yes # Type smallint
+ ###< create table crash_q (q smallint)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_time=yes # Type time
+ ###< create table crash_q (q time)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_timestamp=yes # Type timestamp
+ ###< create table crash_q (q timestamp)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
+ ###< create table crash_q (q timestamp with time zone)
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'with time zone)' at line 1
+ ###< drop table crash_q
+ ###> execute error:Unknown table 'crash_q'
+ ###
+ ###As far as some queries didnt return OK, result is NO
type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
-union=no # union
-union_all=no # union all
-union_all_incompat=no # union all (incompatible lists)
-union_incompat=no # union (incompatible lists)
+ ###< create table crash_q (q varchar(1))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+union=yes # union
+ ###< select * from crash_me union select a,b from crash_me3
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+union_all=yes # union all
+ ###< select * from crash_me union all select a,b from crash_me3
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+union_all_incompat=yes # union all (incompatible lists)
+ ###< select * from crash_me union all select a,b from crash_me2
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+union_incompat=yes # union (incompatible lists)
+ ###< select * from crash_me union select a,b from crash_me2
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
unique_in_create=yes # unique in create table
+ ###< create table crash_q (q integer not null,unique (q))
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
unique_null_in_create=yes # unique null in create
-user_comment=Alpha DS20 2x500 MHz, 2G memory, key_buffer=16M; ccc + cxx # comment
+ ###< create table crash_q (q integer,unique (q))
+ ###> OK
+ ###< insert into crash_q (q) values (NULL)
+ ###> OK
+ ###< insert into crash_q (q) values (NULL)
+ ###> OK
+ ###< insert into crash_q (q) values (1)
+ ###> OK
+ ###< drop table crash_q
+ ###> OK
+ ###
+ ###As far as all queries returned OK, result is YES
+value_of_false=not supported # Value of FALSE
+ ###<select FALSE
+ ###> execute failed:Unknown column 'FALSE' in 'field list'
+value_of_true=not supported # Value of TRUE
+ ###<select TRUE
+ ###> execute failed:Unknown column 'TRUE' in 'field list'
views=no # views
+ ###< create view crash_q as select a from crash_me
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'view crash_q as select a from crash_me' at line 1
+ ###< drop view crash_q
+ ###> execute error:You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'view crash_q' at line 1
+ ###
+ ###As far as some queries didnt return OK, result is NO
where_string_size=1048539 # constant string size in where
+ ###We are trying (example with N=5):
+ ###select a from crash_me where b >='11111'
diff --git a/sql-bench/run-all-tests.sh b/sql-bench/run-all-tests.sh
index c2f687a9375..da576d73852 100644
--- a/sql-bench/run-all-tests.sh
+++ b/sql-bench/run-all-tests.sh
@@ -34,11 +34,12 @@
# --log ==> puts output in output/RUN-server-machine-cmp-$opt_cmp
use DBI;
+use Cwd;
$opt_silent=1; # Don't write header
@ORG_ARGV=@ARGV;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
$opt_silent=0;
$perl=$^X;
@@ -109,7 +110,9 @@ print "Running tests on: $machine\n";
print "Arguments: $log_prog_args\n";
print "Comments: $opt_comments\n";
print "Limits from: $opt_cmp\n";
-print "Server version: $server_version\n\n";
+print "Server version: $server_version\n";
+print "Optimization: $opt_optimization\n";
+print "Hardware: $opt_hw\n\n";
$estimated=$warning=$got_warning=0;
@@ -195,6 +198,10 @@ while (<test-*>)
print "Summary for $prog: ", join(" ",@prog_sum), "\n";
}
}
+ elsif ($last_line =~ /^Test skipped/i)
+ {
+ print "$last_line\n";
+ }
else
{
$errors++;
@@ -281,10 +288,6 @@ sub read_headers
{
$log_prog_args=$1;
}
- elsif (/^Comments.*:\s+(.*)$/)
- {
- $opt_comments=$1;
- }
elsif (/^Limits.*:\s+(.*)$/)
{
$opt_cmp=$1;
@@ -293,6 +296,14 @@ sub read_headers
{
$server_version=$1;
}
+ elsif (/^Optimiz.*:\s+(.*)$/)
+ {
+ $opt_optimization=$1;
+ }
+ elsif (/^Hardwar.*:\s+(.*)$/)
+ {
+ $opt_hw=$1;
+ }
}
close(TMP);
}
diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh
index 886c428e3b9..905e7ee65be 100644
--- a/sql-bench/server-cfg.sh
+++ b/sql-bench/server-cfg.sh
@@ -1,4 +1,5 @@
#!@PERL@
+# -*- perl -*-
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
#
# This library is free software; you can redistribute it and/or
@@ -33,10 +34,10 @@
sub get_server
{
- my ($name,$host,$database,$odbc,$machine)=@_;
+ my ($name,$host,$database,$odbc,$machine,$socket,$connect_options)=@_;
my ($server);
if ($name =~ /mysql/i)
- { $server=new db_MySQL($host, $database, $machine); }
+ { $server=new db_MySQL($host, $database, $machine, $socket,$connect_options); }
elsif ($name =~ /pg/i)
{ $server= new db_Pg($host,$database); }
elsif ($name =~ /msql/i)
@@ -69,11 +70,13 @@ sub get_server
{ $server= new db_db2($host,$database); }
elsif ($name =~ /Mimer/i)
{ $server= new db_Mimer($host,$database); }
+ elsif ($name =~ /Sapdb/i)
+ { $server= new db_sapdb($host,$database); }
elsif ($name =~ /interBase/i)
{ $server= new db_interbase($host,$database); }
else
{
- die "Unknown sql server name used: $name\nUse one of: Access, Adabas, AdabasD, Empress, FrontBase, Oracle, Informix, DB2, mSQL, Mimer, MS-SQL, MySQL, Pg, Solid or Sybase.\nIf the connection is done trough ODBC the name must end with _ODBC\n";
+ die "Unknown sql server name used: $name\nUse one of: Access, Adabas, AdabasD, Empress, FrontBase, Oracle, Informix, InterBase, DB2, mSQL, Mimer, MS-SQL, MySQL, Pg, Solid, SAPDB or Sybase.\nIf the connection is done trough ODBC the name must end with _ODBC\n";
}
if ($name =~ /_ODBC$/i || defined($odbc) && $odbc)
{
@@ -94,7 +97,7 @@ sub get_server
sub all_servers
{
return ["Access", "Adabas", "DB2", "Empress", "FrontBase", "Oracle",
- "Informix", "InterBase", "Mimer", "mSQL", "MS-SQL", "MySQL", "Pg",
+ "Informix", "InterBase", "Mimer", "mSQL", "MS-SQL", "MySQL", "Pg","SAPDB",
"Solid", "Sybase"];
}
@@ -106,20 +109,22 @@ package db_MySQL;
sub new
{
- my ($type,$host,$database,$machine)= @_;
+ my ($type,$host,$database,$machine,$socket,$connect_options)= @_;
my $self= {};
my %limits;
bless $self;
$self->{'cmp_name'} = "mysql";
- $self->{'data_source'} = "DBI:mysql:$database:$host";
+ $self->{'data_source'} = "DBI:mysql:database=$database;host=$host";
+ $self->{'data_source'} .= ";mysql_socket=$socket" if($socket);
+ $self->{'data_source'} .= ";$connect_options" if($connect_options);
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "blob";
$self->{'text'} = "text";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'vacuum'} = 1; # When using with --fast
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 0; # Transactions disabled by default
$limits{'NEG'} = 1; # Supports -id
$limits{'alter_add_multi_col'}= 1; #Have ALTER TABLE t add a int,add b int;
@@ -144,7 +149,8 @@ sub new
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
$limits{'left_outer_join'} = 1; # Supports left outer joins
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
- $limits{'limit'} = 1; # supports the limit attribute
+ $limits{'limit'} = 1; # supports the limit attribute
+ $limits{'truncate_table'} = 1;
$limits{'load_data_infile'} = 1; # Has load data infile
$limits{'lock_tables'} = 1; # Has lock tables
$limits{'max_column_name'} = 64; # max table and column name
@@ -164,25 +170,7 @@ sub new
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'working_all_fields'} = 1;
$limits{'working_blobs'} = 1; # If big varchar/blobs works
-
- $smds{'time'} = 1;
- $smds{'q1'} = 'b'; # with time not supp by mysql ('')
- $smds{'q2'} = 'b';
- $smds{'q3'} = 'b'; # with time ('')
- $smds{'q4'} = 'c'; # with time not supp by mysql (d)
- $smds{'q5'} = 'b'; # with time not supp by mysql ('')
- $smds{'q6'} = 'c'; # with time not supp by mysql ('')
- $smds{'q7'} = 'c';
- $smds{'q8'} = 'f';
- $smds{'q9'} = 'c';
- $smds{'q10'} = 'b';
- $smds{'q11'} = 'b';
- $smds{'q12'} = 'd';
- $smds{'q13'} = 'c';
- $smds{'q14'} = 'd';
- $smds{'q15'} = 'd';
- $smds{'q16'} = 'a';
- $smds{'q17'} = 'c';
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
# Some fixes that depends on the environment
if (defined($main::opt_create_options) &&
@@ -193,13 +181,19 @@ sub new
if (defined($main::opt_create_options) &&
$main::opt_create_options =~ /type=innodb/i)
{
- $limits{'max_text_size'} = 8000; # Limit in Innobase
+ $self->{'transactions'} = 1; # Transactions enabled
+ }
+ if (defined($main::opt_create_options) &&
+ $main::opt_create_options =~ /type=bdb/i)
+ {
+ $self->{'transactions'} = 1; # Transactions enabled
}
if (defined($main::opt_create_options) &&
$main::opt_create_options =~ /type=gemini/i)
{
$limits{'working_blobs'} = 0; # Blobs not implemented yet
$limits{'max_tables'} = 500;
+ $self->{'transactions'} = 1; # Transactions enabled
}
return $self;
@@ -223,7 +217,15 @@ sub version
$version="MySQL $row[0]";
}
$sth->finish;
+
+ $sth = $dbh->prepare("show status like 'ssl_version'") or die $DBI::errstr;
+ if ($sth->execute && (@row = $sth->fetchrow_array))
+ {
+ $version .= "/$row[1]";
+ }
+ $sth->finish;
$dbh->disconnect;
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
return $version;
}
@@ -259,9 +261,8 @@ sub create
$query="create table $table_name (";
foreach $field (@$fields)
{
- $field =~ s/ decimal/ double(10,2)/i;
+# $field =~ s/ decimal/ double(10,2)/i;
$field =~ s/ big_decimal/ double(10,2)/i;
- $field =~ s/ date/ int/i; # Because of tcp ?
$query.= $field . ',';
}
foreach $index (@$index)
@@ -330,6 +331,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#
# Optimize tables for better performance
#
@@ -349,7 +356,6 @@ sub vacuum
}
}
-
#############################################################################
# Definitions for mSQL
#############################################################################
@@ -368,6 +374,7 @@ sub new
$self->{'limits'} = \%limits;
$self->{'double_quotes'} = 0;
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 0; # No transactions
$self->{'blob'} = "text(" . $limits{'max_text_size'} .")";
$self->{'text'} = "text(" . $limits{'max_text_size'} .")";
@@ -414,6 +421,7 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
return $self;
}
@@ -434,6 +442,8 @@ sub version
{ # Strip pre- and endspace
$tmp=$1;
$tmp =~ s/\s+/ /g; # Remove unnecessary spaces
+ $tmp .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
+
return $tmp;
}
}
@@ -542,6 +552,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Definitions for PostgreSQL #
#############################################################################
@@ -558,11 +574,11 @@ sub new
$self->{'cmp_name'} = "pg";
$self->{'data_source'} = "DBI:Pg:dbname=$database";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "text";
$self->{'text'} = "text";
$self->{'double_quotes'} = 1;
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{"vacuum"} = 1;
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
$limits{'load_data_infile'} = 0;
@@ -603,31 +619,12 @@ sub new
$limits{'select_without_from'}= 1;
$limits{'subqueries'} = 1;
$limits{'table_wildcard'} = 1;
+ $limits{'truncate_table'} = 1;
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'working_all_fields'} = 1;
$limits{'working_blobs'} = 1; # If big varchar/blobs works
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
- # the different cases per query ...
- $smds{'q1'} = 'b'; # with time
- $smds{'q2'} = 'b';
- $smds{'q3'} = 'b'; # with time
- $smds{'q4'} = 'c'; # with time
- $smds{'q5'} = 'b'; # with time
- $smds{'q6'} = 'c'; # strange error ....
- $smds{'q7'} = 'c';
- $smds{'q8'} = 'f'; # needs 128M to execute - can't do insert ...group by
- $smds{'q9'} = 'c';
- $smds{'q10'} = 'b';
- $smds{'q11'} = 'b'; # can't do float8 * int4 - create operator
- $smds{'q12'} = 'd'; # strange error???
- $smds{'q13'} = 'c';
- $smds{'q14'} = 'd'; # strange error???
- $smds{'q15'} = 'd'; # strange error???
- $smds{'q16'} = 'a';
- $smds{'q17'} = 'c';
- $smds{'time'} = 1; # the use of the time table -> 1 is on.
- # when 0 then the date field must be a
- # date field not a int field!!!
return $self;
}
@@ -636,6 +633,7 @@ sub new
sub version
{
my ($version,$dir);
+ $version = "PostgreSQL version ???";
foreach $dir ($ENV{'PGDATA'},"/usr/local/pgsql/data", "/usr/local/pg/data")
{
if ($dir && -e "$dir/PG_VERSION")
@@ -644,11 +642,13 @@ sub version
if ($? == 0)
{
chomp($version);
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
return "PostgreSQL $version";
}
}
}
- return "PostgreSQL version ???";
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
+ return $version;
}
@@ -682,9 +682,9 @@ sub create
$field =~ s/int\(\d*\)/int/;
$field =~ s/float\(\d*,\d*\)/float/;
$field =~ s/ double/ float/;
- $field =~ s/ decimal/ float/i;
- $field =~ s/ big_decimal/ float/i;
- $field =~ s/ date/ int/i;
+# $field =~ s/ decimal/ float/i;
+# $field =~ s/ big_decimal/ float/i;
+# $field =~ s/ date/ int/i;
# Pg doesn't have blob, it has text instead
$field =~ s/ blob/ text/;
$query.= $field . ',';
@@ -798,6 +798,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
sub vacuum
{
my ($self,$full_vacuum,$dbh_ref,@tables)=@_;
@@ -846,11 +852,11 @@ sub new
$self->{'cmp_name'} = "solid";
$self->{'data_source'} = "DBI:Solid:";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "long varchar";
$self->{'text'} = "long varchar";
$self->{'double_quotes'} = 1;
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 9999; # Probably big enough
$limits{'max_columns'} = 2000; # From crash-me
@@ -895,29 +901,8 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
- # for the smds small benchmark test ....
- # the different cases per query ...
- $smds{'q1'} = 'a';
- $smds{'q2'} = '';
- $smds{'q3'} = 'b'; #doesn't work -> strange error about column -fixed
- $smds{'q4'} = 'a';
- $smds{'q5'} = 'b';
- $smds{'q6'} = 'c';
- $smds{'q7'} = 'b';
- $smds{'q8'} = 'f';
- $smds{'q9'} = 'b';
- $smds{'q10'} = 'b';
- $smds{'q11'} = '';
- $smds{'q12'} = 'd';
- $smds{'q13'} = 'b';
- $smds{'q14'} = 'd';
- $smds{'q15'} = 'd';
- $smds{'q16'} = '';
- $smds{'q17'} = '';
- $smds{'time'} = 1; # the use of the time table -> 1 is on.
- # when 0 then the date field must be a
- # date field not a int field!!!
return $self;
}
@@ -928,6 +913,7 @@ sub new
sub version
{
my ($version,$dir);
+ $version="Solid version ??";
foreach $dir ($ENV{'SOLIDDIR'},"/usr/local/solid", "/my/local/solid")
{
if ($dir && -e "$dir/bin/solcon")
@@ -936,11 +922,13 @@ sub version
if ($? == 0)
{
chomp($version);
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
return $version;
}
}
}
- return "Solid version ???";
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
+ return $version;
}
sub connect
@@ -970,9 +958,9 @@ sub create
$field =~ s/ double/ float/i;
# Solid doesn't have blob, it has long varchar
$field =~ s/ blob/ long varchar/;
- $field =~ s/ decimal/ float/i;
- $field =~ s/ big_decimal/ float/i;
- $field =~ s/ date/ int/i;
+# $field =~ s/ decimal/ float/i;
+# $field =~ s/ big_decimal/ float/i;
+# $field =~ s/ date/ int/i;
$query.= $field . ',';
}
substr($query,-1)=")"; # Remove last ',';
@@ -1063,6 +1051,12 @@ sub small_rollback_segment
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
sub reconnect_on_errors
{
return 0;
@@ -1087,11 +1081,11 @@ sub new
$self->{'cmp_name'} = "empress";
$self->{'data_source'} = "DBI:EmpressNet:SERVER=$host;Database=/usr/local/empress/rdbms/bin/$database";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "text";
$self->{'text'} = "text";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 1258;
$limits{'max_columns'} = 226; # server is disconnecting????
@@ -1138,29 +1132,8 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
- # for the smds small benchmark test ....
- # the different cases per query ... EMPRESS
- $smds{'q1'} = 'a';
- $smds{'q2'} = '';
- $smds{'q3'} = 'a';
- $smds{'q4'} = 'a';
- $smds{'q5'} = 'a';
- $smds{'q6'} = 'a';
- $smds{'q7'} = 'b';
- $smds{'q8'} = 'd';
- $smds{'q9'} = 'b';
- $smds{'q10'} = 'a';
- $smds{'q11'} = '';
- $smds{'q12'} = 'd';
- $smds{'q13'} = 'b';
- $smds{'q14'} = 'b';
- $smds{'q15'} = 'a';
- $smds{'q16'} = '';
- $smds{'q17'} = '';
- $smds{'time'} = 1; # the use of the time table -> 1 is on.
- # when 0 then the date field must be a
- # date field not a int field!!!
return $self;
}
@@ -1185,6 +1158,8 @@ sub version
{
$version="Empress version ???";
}
+
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
return $version;
}
@@ -1232,9 +1207,9 @@ sub create
$field =~ s/ blob/ text/;
$field =~ s/ varchar\((\d+)\)/ char($1,3)/;
$field =~ s/ char\((\d+)\)/ char($1,3)/;
- $field =~ s/ decimal/ float/i;
- $field =~ s/ big_decimal/ longfloat/i;
- $field =~ s/ date/ int/i;
+# $field =~ s/ decimal/ float/i;
+# $field =~ s/ big_decimal/ longfloat/i;
+# $field =~ s/ date/ int/i;
$field =~ s/ float(.*)/ float/i;
if ($field =~ / int\((\d+)\)/) {
if ($1 > 4) {
@@ -1325,6 +1300,14 @@ sub query {
return $sql;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ $cmd =~ s/\'\'/\' \'/g;
+ return $cmd;
+}
+
+
sub drop_index
{
my ($self,$table,$index) = @_;
@@ -1369,11 +1352,11 @@ sub new
$self->{'cmp_name'} = "Oracle";
$self->{'data_source'} = "DBI:Oracle:$database";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "long";
$self->{'text'} = "long";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{"vacuum"} = 1;
$limits{'max_conditions'} = 9999; # (Actually not a limit)
@@ -1385,6 +1368,7 @@ sub new
$limits{'max_index_parts'} = 16; # Max segments/key
$limits{'max_column_name'} = 32; # max table and column name
+ $limits{'truncate_table'} = 1;
$limits{'join_optimizer'} = 1; # Can optimize FROM tables
$limits{'load_data_infile'} = 0; # Has load data infile
$limits{'lock_tables'} = 0; # Has lock tables
@@ -1420,25 +1404,8 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
- $smds{'time'} = 1;
- $smds{'q1'} = 'b'; # with time not supp by mysql ('')
- $smds{'q2'} = 'b';
- $smds{'q3'} = 'b'; # with time ('')
- $smds{'q4'} = 'c'; # with time not supp by mysql (d)
- $smds{'q5'} = 'b'; # with time not supp by mysql ('')
- $smds{'q6'} = 'c'; # with time not supp by mysql ('')
- $smds{'q7'} = 'c';
- $smds{'q8'} = 'f';
- $smds{'q9'} = 'c';
- $smds{'q10'} = 'b';
- $smds{'q11'} = 'b';
- $smds{'q12'} = 'd';
- $smds{'q13'} = 'c';
- $smds{'q14'} = 'd';
- $smds{'q15'} = 'd';
- $smds{'q16'} = 'a';
- $smds{'q17'} = 'c';
return $self;
}
@@ -1461,6 +1428,7 @@ sub version
}
$sth->finish;
$dbh->disconnect;
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
return $version;
}
@@ -1546,6 +1514,14 @@ sub query {
return $sql;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ $cmd =~ s/\'\'/\' \'/g;
+ return $cmd;
+}
+
+
sub drop_index
{
my ($self,$table,$index) = @_;
@@ -1624,11 +1600,11 @@ sub new
$self->{'cmp_name'} = "Informix";
$self->{'data_source'} = "DBI:Informix:$database";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "byte in table";
$self->{'text'} = "byte in table";
$self->{'double_quotes'} = 0; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{'host'} = $host;
$limits{'NEG'} = 1; # Supports -id
@@ -1673,6 +1649,7 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
return $self;
}
@@ -1697,6 +1674,7 @@ sub version
}
$sth->finish;
$dbh->disconnect;
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
return $version;
}
@@ -1778,6 +1756,16 @@ sub query {
return $sql;
}
+
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ $cmd =~ s/\\\'//g;
+ return $cmd;
+}
+
+
+
sub drop_index
{
my ($self,$table,$index) = @_;
@@ -1805,6 +1793,7 @@ sub reconnect_on_errors
return 0;
}
+
#############################################################################
# Configuration for Access
#############################################################################
@@ -1825,11 +1814,11 @@ sub new
$self->{'data_source'} .= ":$host";
}
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "blob";
$self->{'text'} = "blob"; # text ?
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 97; # We get 'Query is too complex'
$limits{'max_columns'} = 255; # Max number of columns in table
@@ -1875,6 +1864,7 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
return $self;
}
@@ -1885,7 +1875,9 @@ sub new
sub version
{
my ($self)=@_;
- return "Access 2000"; #DBI/ODBC can't return the server version
+ my $version="Access 2000";
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
+ return $version; #DBI/ODBC can't return the server version
}
sub connect
@@ -1981,6 +1973,12 @@ sub reconnect_on_errors
return 1;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for Microsoft SQL server
#############################################################################
@@ -2001,11 +1999,11 @@ sub new
$self->{'data_source'} .= ":$host";
}
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "text";
$self->{'text'} = "text";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 1030; # We get 'Query is too complex'
$limits{'max_columns'} = 250; # Max number of columns in table
@@ -2051,6 +2049,7 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
return $self;
}
@@ -2061,7 +2060,8 @@ sub new
sub version
{
my ($self)=@_;
- my($sth,@row);
+ my($sth,@row, $version);
+ $version='MS SQL server ?';
$dbh=$self->connect();
$sth = $dbh->prepare("SELECT \@\@VERSION") or die $DBI::errstr;
$sth->execute or die $DBI::errstr;
@@ -2069,10 +2069,11 @@ sub version
if ($row[0]) {
@server = split(/\n/,$row[0]);
chomp(@server);
- return "$server[0]";
- } else {
- return "Microsoft SQL server ?";
- }
+ $version= "$server[0]";
+ }
+ $sth->finish;
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
+ return $version;
}
sub connect
@@ -2168,10 +2169,15 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for Sybase
#############################################################################
-
package db_sybase;
sub new
@@ -2182,17 +2188,17 @@ sub new
bless $self;
$self->{'cmp_name'} = "sybase";
- $self->{'data_source'} = "DBI:ODBC:$database";
+ $self->{'data_source'} = "DBI:Sybase:database=$database";
if (defined($host) && $host ne "")
{
- $self->{'data_source'} .= ":$host";
+ $self->{'data_source'} .= ";hostname=$host";
}
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "text";
$self->{'text'} = "text";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{"vacuum"} = 1;
$limits{'max_conditions'} = 1030; # We get 'Query is too complex'
@@ -2239,6 +2245,7 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
return $self;
}
@@ -2249,7 +2256,19 @@ sub new
sub version
{
my ($self)=@_;
- return "Sybase enterprise 11.5 NT"; #DBI/ODBC can't return the server version
+ my ($dbh,$sth,$version,@row);
+
+ $dbh=$self->connect();
+ $sth = $dbh->prepare('SELECT @@version') or die $DBI::errstr;
+ $version="Sybase (unknown)";
+ if ($sth->execute && (@row = $sth->fetchrow_array))
+ {
+ $version=$row[0];
+ }
+ $sth->finish;
+ $dbh->disconnect;
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
+ return $version;
}
sub connect
@@ -2257,7 +2276,7 @@ sub connect
my ($self)=@_;
my ($dbh);
$dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
- $main::opt_password,{ PrintError => 0}) ||
+ $main::opt_password,{ PrintError => 0 , AutoCommit => 1}) ||
die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
return $dbh;
}
@@ -2342,9 +2361,17 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#
# optimize the tables ....
-#
+# WARNING (from walrus)! This sub will work only from DBD:sybase
+# driver. Because if we use ODBC we don't know actual database name
+# (but DSN name only)
sub vacuum
{
my ($self,$full_vacuum,$dbh_ref)=@_;
@@ -2356,7 +2383,25 @@ sub vacuum
}
$dbh=$$dbh_ref;
$loop_time=new Benchmark;
- $dbh->do("analyze table ?? compute statistics") || die "Got error: $DBI::errstr when executing 'vacuum'\n";
+ my (@tables,$sth,$current_table,$current_base);
+ $dbh->do("dump tran $database with truncate_only");
+ $sth=$dbh->prepare("sp_tables" ) or die "prepere";
+ $sth->execute() or die "execute";
+ while (@row = $sth->fetchrow_array()) {
+ $current_table = $row[2];
+ $current_base = $row[0];
+ next if ($current_table =~ /^sys/);
+ push(@tables,$current_table) if ($database == $current_base);
+ }
+
+ $sth->finish();
+
+ foreach $table (@tables) {
+# print "$table: \n";
+ $dbh->do("update statistics $table") or print "Oops!";
+ }
+
+# $dbh->do("analyze table ?? compute statistics") || die "Got error: $DBI::errstr when executing 'vacuum'\n";
$end_time=new Benchmark;
print "Time for book-keeping (1): " .
Benchmark::timestr(Benchmark::timediff($end_time, $loop_time),"all") . "\n\n";
@@ -2364,6 +2409,8 @@ sub vacuum
}
+
+
#############################################################################
# Definitions for Adabas
#############################################################################
@@ -2380,11 +2427,11 @@ sub new
$self->{'cmp_name'} = "Adabas";
$self->{'data_source'} = "DBI:Adabas:$database";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "long";
$self->{'text'} = "long";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 50; # (Actually not a limit)
$limits{'max_columns'} = 254; # Max number of columns in table
@@ -2430,25 +2477,8 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
- $smds{'time'} = 1;
- $smds{'q1'} = 'b'; # with time not supp by mysql ('')
- $smds{'q2'} = 'b';
- $smds{'q3'} = 'b'; # with time ('')
- $smds{'q4'} = 'c'; # with time not supp by mysql (d)
- $smds{'q5'} = 'b'; # with time not supp by mysql ('')
- $smds{'q6'} = 'c'; # with time not supp by mysql ('')
- $smds{'q7'} = 'c';
- $smds{'q8'} = 'f';
- $smds{'q9'} = 'c';
- $smds{'q10'} = 'b';
- $smds{'q11'} = 'b';
- $smds{'q12'} = 'd';
- $smds{'q13'} = 'c';
- $smds{'q14'} = 'd';
- $smds{'q15'} = 'd';
- $smds{'q16'} = 'a';
- $smds{'q17'} = 'c';
return $self;
}
@@ -2472,6 +2502,7 @@ sub version
}
$sth->finish;
$dbh->disconnect;
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
return $version;
}
@@ -2574,6 +2605,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for IBM DB2
#############################################################################
@@ -2594,11 +2631,11 @@ sub new
$self->{'data_source'} .= ":$host";
}
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "varchar(255)";
$self->{'text'} = "varchar(255)";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$limits{'max_conditions'} = 418; # We get 'Query is too complex'
$limits{'max_columns'} = 500; # Max number of columns in table
@@ -2644,6 +2681,7 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
return $self;
}
@@ -2747,6 +2785,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for MIMER
#############################################################################
@@ -2763,11 +2807,11 @@ sub new
$self->{'cmp_name'} = "mimer";
$self->{'data_source'} = "DBI:mimer:$database:$host";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "binary varying(15000)";
$self->{'text'} = "character varying(15000)";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{'char_null'} = "cast(NULL as char(1))";
$self->{'numeric_null'} = "cast(NULL as int)";
@@ -2792,7 +2836,7 @@ sub new
$limits{'subqueries'} = 1; # Supports sub-queries.
$limits{'left_outer_join'} = 1; # Supports left outer joins
$limits{'table_wildcard'} = 1; # Has SELECT table_name.*
- $limits{'having_with_alias'} = 1; # Can use aliases in HAVING
+ $limits{'having_with_alias'} = 0; # Can use aliases in HAVING
$limits{'having_with_group'} = 1; # Can use group functions in HAVING
$limits{'like_with_column'} = 1; # Can use column1 LIKE column2
$limits{'order_by_position'} = 1; # Can use 'ORDER BY 1'
@@ -2801,6 +2845,7 @@ sub new
$limits{'alter_add_multi_col'}= 0; # Have ALTER TABLE t add a int,add b int;
$limits{'alter_table_dropcol'}= 1; # Have ALTER TABLE DROP column
$limits{'insert_multi_value'} = 0; # Does not have INSERT ... values (1,2),(3,4)
+ $limits{'multi_distinct'} = 0; # Does not allow select count(distinct a),count(distinct b)..
$limits{'group_func_extra_std'} = 0; # Does not have group function std().
@@ -2815,28 +2860,9 @@ sub new
$limits{'unique_index'} = 1; # Unique index works or not
$limits{'insert_select'} = 1;
$limits{'working_blobs'} = 1; # If big varchar/blobs works
- $limits{'order_by_unused'} = 1;
+ $limits{'order_by_unused'} = 0;
$limits{'working_all_fields'} = 1;
- $smds{'time'} = 1;
- $smds{'q1'} = 'b'; # with time not supp by mysql ('')
- $smds{'q2'} = 'b';
- $smds{'q3'} = 'b'; # with time ('')
- $smds{'q4'} = 'c'; # with time not supp by mysql (d)
- $smds{'q5'} = 'b'; # with time not supp by mysql ('')
- $smds{'q6'} = 'c'; # with time not supp by mysql ('')
- $smds{'q7'} = 'c';
- $smds{'q8'} = 'f';
- $smds{'q9'} = 'c';
- $smds{'q10'} = 'b';
- $smds{'q11'} = 'b';
- $smds{'q12'} = 'd';
- $smds{'q13'} = 'c';
- $smds{'q14'} = 'd';
- $smds{'q15'} = 'd';
- $smds{'q16'} = 'a';
- $smds{'q17'} = 'c';
-
return $self;
}
@@ -2855,6 +2881,7 @@ sub version
#
$version = $dbh->func(18, GetInfo);
$dbh->disconnect;
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
return $version;
}
@@ -2885,23 +2912,36 @@ sub connect
sub create
{
my($self,$table_name,$fields,$index,$options) = @_;
- my($query,@queries);
+ my($query,@queries,@indexes);
$query="create table $table_name (";
foreach $field (@$fields)
{
- $field =~ s/ decimal/ double(10,2)/i;
- $field =~ s/ big_decimal/ double(10,2)/i;
- $field =~ s/ date/ int/i; # Because of tcp ?
+# $field =~ s/ decimal/ double(10,2)/i;
+# $field =~ s/ big_decimal/ double(10,2)/i;
+ $field =~ s/ double/ double precision/i;
+ $field =~ s/ tinyint\(.*\)/ smallint/i;
+ $field =~ s/ smallint\(.*\)/ smallint/i;
+ $field =~ s/ mediumint/ integer/i;
+ $field =~ s/ float\(.*\)/ float/i;
+# $field =~ s/ date/ int/i; # Because of tcp ?
$query.= $field . ',';
}
foreach $index (@$index)
{
- $query.= $index . ',';
+ if ( $index =~ /\bINDEX\b/i )
+ {
+ my @fields = split(' ',$index);
+ my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
+ push(@indexes,$query);
+
+ } else {
+ $query.= $index . ',';
+ }
}
substr($query,-1)=")"; # Remove last ',';
$query.=" $options" if (defined($options));
- push(@queries,$query);
+ push(@queries,$query,@indexes);
return @queries;
}
@@ -2947,6 +2987,12 @@ sub reconnect_on_errors
return 0;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for InterBase
#############################################################################
@@ -2961,13 +3007,13 @@ sub new
bless $self;
$self->{'cmp_name'} = "interbase";
- $self->{'data_source'} = "DBI:InterBase:database=$database";
+ $self->{'data_source'} = "DBI:InterBase:database=$database;ib_dialect=3";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "blob";
$self->{'text'} = "";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{'char_null'} = "";
$self->{'numeric_null'} = "";
@@ -2976,7 +3022,7 @@ sub new
$limits{'max_tables'} = 65000; # Should be big enough
$limits{'max_text_size'} = 15000; # Max size with default buffers.
$limits{'query_size'} = 1000000; # Max size with default buffers.
- $limits{'max_index'} = 31; # Max number of keys
+ $limits{'max_index'} = 65000; # Max number of keys
$limits{'max_index_parts'} = 8; # Max segments/key
$limits{'max_column_name'} = 128; # max table and column name
@@ -3015,25 +3061,7 @@ sub new
$limits{'working_blobs'} = 1; # If big varchar/blobs works
$limits{'order_by_unused'} = 1;
$limits{'working_all_fields'} = 1;
-
- $smds{'time'} = 1;
- $smds{'q1'} = 'b'; # with time not supp by mysql ('')
- $smds{'q2'} = 'b';
- $smds{'q3'} = 'b'; # with time ('')
- $smds{'q4'} = 'c'; # with time not supp by mysql (d)
- $smds{'q5'} = 'b'; # with time not supp by mysql ('')
- $smds{'q6'} = 'c'; # with time not supp by mysql ('')
- $smds{'q7'} = 'c';
- $smds{'q8'} = 'f';
- $smds{'q9'} = 'c';
- $smds{'q10'} = 'b';
- $smds{'q11'} = 'b';
- $smds{'q12'} = 'd';
- $smds{'q13'} = 'c';
- $smds{'q14'} = 'd';
- $smds{'q15'} = 'd';
- $smds{'q16'} = 'a';
- $smds{'q17'} = 'c';
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
return $self;
}
@@ -3045,16 +3073,14 @@ sub new
sub version
{
my ($self)=@_;
- my ($dbh,$sth,$version,@row);
-
+ my ($dbh,$version);
+
+ $version='Interbase ?';
+
$dbh=$self->connect();
-# $sth = $dbh->prepare("show version");
-# $sth->execute;
-# @row = $sth->fetchrow_array;
-# $version = $row[0];
-# $version =~ s/.*version \"(.*)\"$/$1/;
+ eval { $version = $dbh->func('version','ib_database_info')->{'version'}; };
$dbh->disconnect;
- $version = "6.0Beta";
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
return $version;
}
@@ -3084,36 +3110,34 @@ sub connect
sub create
{
my($self,$table_name,$fields,$index,$options) = @_;
- my($query,@queries);
+ my($query,@queries,@keys,@indexes);
$query="create table $table_name (";
foreach $field (@$fields)
{
- $field =~ s/ big_decimal/ float/i;
- $field =~ s/ double/ float/i;
+# $field =~ s/ big_decimal/ decimal/i;
+ $field =~ s/ double/ double precision/i;
$field =~ s/ tinyint/ smallint/i;
- $field =~ s/ mediumint/ int/i;
- $field =~ s/ integer/ int/i;
+ $field =~ s/ mediumint/ integer/i;
+ $field =~ s/\bint\b/integer/i;
$field =~ s/ float\(\d,\d\)/ float/i;
- $field =~ s/ date/ int/i; # Because of tcp ?
$field =~ s/ smallint\(\d\)/ smallint/i;
- $field =~ s/ int\(\d\)/ int/i;
+ $field =~ s/ integer\(\d\)/ integer/i;
$query.= $field . ',';
}
foreach $ind (@$index)
{
- my @index;
- if ( $ind =~ /\bKEY\b/i ){
+ if ( $ind =~ /(\bKEY\b)|(\bUNIQUE\b)/i ){
push(@keys,"ALTER TABLE $table_name ADD $ind");
}else{
- my @fields = split(' ',$index);
+ my @fields = split(' ',$ind);
my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
- push(@index,$query);
+ push(@indexes,$query);
}
}
substr($query,-1)=")"; # Remove last ',';
$query.=" $options" if (defined($options));
- push(@queries,$query);
+ push(@queries,$query,@keys,@indexes);
return @queries;
}
@@ -3159,6 +3183,12 @@ sub reconnect_on_errors
return 1;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
#############################################################################
# Configuration for FrontBase
#############################################################################
@@ -3175,11 +3205,11 @@ sub new
$self->{'cmp_name'} = "FrontBase";
$self->{'data_source'} = "DBI:FB:dbname=$database;host=$host";
$self->{'limits'} = \%limits;
- $self->{'smds'} = \%smds;
$self->{'blob'} = "varchar(8000000)";
$self->{'text'} = "varchar(8000000)";
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
$self->{'drop_attr'} = ' restrict';
+ $self->{'transactions'} = 1; # Transactions enabled
$self->{'error_on_execute_means_zero_rows'}=1;
$limits{'max_conditions'} = 5427; # (Actually not a limit)
@@ -3234,6 +3264,7 @@ sub new
$limits{'group_func_sql_min_str'} = 0;
# If you do select f1,f2,f3...f200 from table, Frontbase dies.
$limits{'working_all_fields'} = 0;
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
return $self;
}
@@ -3247,13 +3278,14 @@ sub version
my ($self)=@_;
my ($dbh,$sth,$version,@row);
- $dbh=$self->connect();
+# $dbh=$self->connect();
#
# Pick up SQLGetInfo option SQL_DBMS_VER (18)
#
#$version = $dbh->func(18, GetInfo);
- $version="FrontBase 2.1";
- $dbh->disconnect;
+ $version="FrontBase 3.3";
+# $dbh->disconnect;
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
return $version;
}
@@ -3288,7 +3320,7 @@ sub connect
sub create
{
my($self,$table_name,$fields,$index,$options) = @_;
- my($query,@queries);
+ my($query,@queries,@indexes,@keys);
$query="create table $table_name (";
foreach $field (@$fields)
@@ -3306,18 +3338,18 @@ sub create
}
foreach $ind (@$index)
{
- my @index;
- if ( $ind =~ /\bKEY\b/i ){
+# my @index;
+ if ( $ind =~ /(\bKEY\b)|(\bUNIQUE\b)/i ){
push(@keys,"ALTER TABLE $table_name ADD $ind");
}else{
- my @fields = split(' ',$index);
+ my @fields = split(' ',$ind);
my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
- push(@index,$query);
+ push(@indexes,$query);
}
}
substr($query,-1)=")"; # Remove last ',';
$query.=" $options" if (defined($options));
- push(@queries,$query);
+ push(@queries,$query,@keys,@indexes);
return @queries;
}
@@ -3363,4 +3395,219 @@ sub reconnect_on_errors
return 1;
}
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
+#############################################################################
+# Configuration for SAPDB
+#############################################################################
+
+package db_sapdb;
+
+sub new
+{
+ my ($type,$host,$database)= @_;
+ my $self= {};
+ my %limits;
+ bless $self;
+
+ $self->{'cmp_name'} = "sapdb";
+ $self->{'data_source'} = "DBI:SAP_DB:$database";
+ $self->{'limits'} = \%limits;
+ $self->{'blob'} = "LONG"; # *
+ $self->{'text'} = "LONG"; # *
+ $self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
+ $self->{'drop_attr'} = "";
+ $self->{'transactions'} = 1; # Transactions enabled *
+ $self->{'char_null'} = "";
+ $self->{'numeric_null'} = "";
+
+ $limits{'max_conditions'} = 9999; # (Actually not a limit) *
+ $limits{'max_columns'} = 1023; # Max number of columns in table *
+ $limits{'max_tables'} = 65000; # Should be big enough * unlimited actually
+ $limits{'max_text_size'} = 15000; # Max size with default buffers.
+ $limits{'query_size'} = 64*1024; # Max size with default buffers. *64 kb by default. May be set by system variable
+ $limits{'max_index'} = 510; # Max number of keys *
+ $limits{'max_index_parts'} = 16; # Max segments/key *
+ $limits{'max_column_name'} = 32; # max table and column name *
+
+ $limits{'join_optimizer'} = 1; # Can optimize FROM tables *
+ $limits{'load_data_infile'} = 0; # Has load data infile *
+ $limits{'lock_tables'} = 1; # Has lock tables
+ $limits{'functions'} = 1; # Has simple functions (+/-) *
+ $limits{'group_functions'} = 1; # Have group functions *
+ $limits{'group_func_sql_min_str'} = 1; # Can execute MIN() and MAX() on strings *
+ $limits{'group_distinct_functions'}= 1; # Have count(distinct) *
+ $limits{'select_without_from'}= 0; # Cannot do 'select 1'; *
+ $limits{'multi_drop'} = 0; # Drop table cannot take many tables *
+ $limits{'subqueries'} = 1; # Supports sub-queries. *
+ $limits{'left_outer_join'} = 1; # Supports left outer joins *
+ $limits{'table_wildcard'} = 1; # Has SELECT table_name.*
+ $limits{'having_with_alias'} = 0; # Can use aliases in HAVING *
+ $limits{'having_with_group'} = 1; # Can use group functions in HAVING *
+ $limits{'like_with_column'} = 1; # Can use column1 LIKE column2 *
+ $limits{'order_by_position'} = 1; # Can use 'ORDER BY 1' *
+ $limits{'group_by_position'} = 0; # Cannot use 'GROUP BY 1' *
+ $limits{'alter_table'} = 1; # Have ALTER TABLE *
+ $limits{'alter_add_multi_col'}= 1; # Have ALTER TABLE t add a int,add b int; *
+ $limits{'alter_table_dropcol'}= 1; # Have ALTER TABLE DROP column *
+ $limits{'insert_multi_value'} = 0; # INSERT ... values (1,2),(3,4) *
+
+ $limits{'group_func_extra_std'} = 0; # Does not have group function std().
+
+ $limits{'func_odbc_mod'} = 0; # Have function mod. *
+ $limits{'func_extra_%'} = 0; # Does not have % as alias for mod() *
+ $limits{'func_odbc_floor'} = 1; # Has func_odbc_floor function *
+ $limits{'func_extra_if'} = 0; # Does not have function if. *
+ $limits{'column_alias'} = 1; # Alias for fields in select statement. *
+ $limits{'NEG'} = 1; # Supports -id *
+ $limits{'func_extra_in_num'} = 0; # Has function in *
+ $limits{'limit'} = 0; # Does not support the limit attribute *
+ $limits{'working_blobs'} = 1; # If big varchar/blobs works *
+ $limits{'order_by_unused'} = 1; #
+ $limits{'working_all_fields'} = 1; #
+ $limits{'multi_distinct'} = 1; # allows select count(distinct a),count(distinct b)..
+
+
+ return $self;
+}
+
+#
+# Get the version number of the database
+#
+
+sub version
+{
+ my ($self)=@_;
+ my ($dbh,$sth,$version,@row);
+
+ $dbh=$self->connect();
+ $sth = $dbh->prepare("SELECT KERNEL FROM VERSIONS") or die $DBI::errstr;
+ $version="SAP DB (unknown)";
+ if ($sth->execute && (@row = $sth->fetchrow_array)
+ && $row[0] =~ /([\d\.]+)/)
+ {
+ $version=$row[0];
+ $version =~ s/KERNEL/SAP DB/i;
+ }
+ $sth->finish;
+ $dbh->disconnect;
+ $version .= "/ODBC" if ($self->{'data_source'} =~ /:ODBC:/);
+ return $version;
+}
+
+#
+# Connection with optional disabling of logging
+#
+
+sub connect
+{
+ my ($self)=@_;
+ my ($dbh);
+ $dbh=DBI->connect($self->{'data_source'}, $main::opt_user,
+ $main::opt_password,{ PrintError => 0, AutoCommit => 1}) ||
+ die "Got error: '$DBI::errstr' when connecting to " . $self->{'data_source'} ." with user: '$main::opt_user' password: '$main::opt_password'\n";
+
+ return $dbh;
+}
+
+#
+# Returns a list of statements to create a table
+# The field types are in ANSI SQL format.
+#
+
+sub create
+{
+ my($self,$table_name,$fields,$index,$options) = @_;
+ my($query,@queries,$nr);
+ my @index;
+ my @keys;
+
+ $query="create table $table_name (";
+ foreach $field (@$fields)
+ {
+ $field =~ s/\bmediumint\b/int/i;
+ $field =~ s/\btinyint\b/int/i;
+ $field =~ s/ int\(\d\)/ int/i;
+ $field =~ s/BLOB/LONG/i;
+ $field =~ s/INTEGER\s*\(\d+\)/INTEGER/i;
+ $field =~ s/SMALLINT\s*\(\d+\)/SMALLINT/i;
+ $field =~ s/FLOAT\s*\((\d+),\d+\)/FLOAT\($1\)/i;
+ $field =~ s/DOUBLE/FLOAT\(38\)/i;
+ $field =~ s/DOUBLE\s+PRECISION/FLOAT\(38\)/i;
+ $query.= $field . ',';
+ }
+ $nr=0;
+ foreach $ind (@$index)
+ {
+ if ( $ind =~ /\bKEY\b/i ){
+ push(@keys,"ALTER TABLE $table_name ADD $ind");
+ } elsif ($ind =~ /^unique.*\(([^\(]*)\)$/i) {
+ $nr++;
+ my $query="create unique index ${table_name}_$nr on $table_name ($1)";
+ push(@index,$query);
+ }else{
+ my @fields = split(' ',$ind);
+ my $query="CREATE INDEX $fields[1] ON $table_name $fields[2]";
+ push(@index,$query);
+ }
+ }
+ substr($query,-1)=")"; # Remove last ',';
+ $query.=" $options" if (defined($options));
+ push(@queries,$query);
+ push(@queries,@keys);
+ push(@queries,@index);
+ return @queries;
+}
+
+sub insert_file {
+ my($self,$dbname, $file) = @_;
+ print "insert of an ascii file isn't supported by SAPDB\n";
+ return 0;
+}
+
+#
+# Do any conversions to the ANSI SQL query so that the database can handle it
+#
+
+sub query {
+ my($self,$sql) = @_;
+ return $sql;
+}
+
+sub drop_index {
+ my ($self,$table,$index) = @_;
+ return "DROP INDEX $index";
+}
+
+#
+# Abort if the server has crashed
+# return: 0 if ok
+# 1 question should be retried
+#
+
+sub abort_if_fatal_error
+{
+ return 0;
+}
+
+sub small_rollback_segment
+{
+ return 0;
+}
+
+sub reconnect_on_errors
+{
+ return 0;
+}
+
+sub fix_for_insert
+{
+ my ($self,$cmd) = @_;
+ return $cmd;
+}
+
1;
diff --git a/sql-bench/test-ATIS.sh b/sql-bench/test-ATIS.sh
index 77e0e7d79bf..1f11f4319b5 100644
--- a/sql-bench/test-ATIS.sh
+++ b/sql-bench/test-ATIS.sh
@@ -24,12 +24,13 @@
# - skip a couple of the tests in Q4 that Oracle doesn't understand
################### Standard benchmark inits ##############################
+use Cwd;
use DBI;
use Benchmark;
$opt_loop_count=100; # Run selects this many times
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
if ($opt_small_test)
@@ -106,6 +107,12 @@ if (!$opt_skip_create)
}
else
{
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->{AutoCommit} = 0;
+ print "Transactions enabled\n" if ($opt_debug);
+ }
+
for ($ti = 0; $ti <= $#table_names; $ti++)
{
my $table_name = $table_names[$ti];
@@ -119,8 +126,7 @@ if (!$opt_skip_create)
chomp;
next unless ( $_ =~ /\w/ ); # skip blank lines
my $command = $insert_start . $_ . ")";
- $command =~ s/\'\'/\' \'/g if ($opt_server =~ /empress/i || $opt_server =~ /oracle/i);
- $command =~ s/\\'//g if ($opt_server =~ /informix/i);
+ $command = $server->fix_for_insert($command);
print "$command\n" if ($opt_debug);
$command =~ s/\\'/\'\'/g if ($double_quotes);
@@ -128,8 +134,14 @@ if (!$opt_skip_create)
$row_count++;
}
}
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+ }
close(DATA);
}
+
if ($opt_lock_tables)
{
$dbh->do("UNLOCK TABLES");
@@ -213,7 +225,7 @@ print "Retrieving data\n";
"SELECT airport.country_name,state.state_name,city.city_name,airport_service.direction FROM airport_service,state,airport,city WHERE airport_service.city_code=city.city_code AND airport_service.airport_code=airport.airport_code AND state.state_code=airport.state_code AND state.state_code=city.state_code AND airport.state_code=city.state_code AND airport.country_name=city.country_name AND airport.country_name=state.country_name AND city.time_zone_code=airport.time_zone_code GROUP BY airport.country_name,state.state_name,city.city_name,airport_service.direction ORDER BY state_name DESC",11,$limits->{'group_functions'},
"SELECT airport.country_name,state.state_name,city.city_name,airport_service.direction FROM airport_service,state,airport,city WHERE airport_service.city_code=city.city_code AND airport_service.airport_code=airport.airport_code AND state.state_code=airport.state_code AND state.state_code=city.state_code AND airport.state_code=city.state_code AND airport.country_name=city.country_name AND airport.country_name=state.country_name AND city.time_zone_code=airport.time_zone_code GROUP BY airport.country_name,state.state_name,city.city_name,airport_service.direction ORDER BY state_name",11,$limits->{'group_functions'},
"SELECT from_airport,to_airport,fare.fare_class,night,one_way_cost,rnd_trip_cost,class_days FROM compound_class,fare WHERE compound_class.fare_class=fare.fare_class AND one_way_cost <= 825 AND one_way_cost >= 280 AND from_airport='SFO' AND to_airport='DFW' GROUP BY from_airport,to_airport,fare.fare_class,night,one_way_cost,rnd_trip_cost,class_days ORDER BY one_way_cost",10,$limits->{'group_functions'},
- "select engines,category,cruising_speed,from_airport,to_airport FROM aircraft,flight WHERE category='JET' AND ENGINES >= 1 AND aircraft.aircraft_code=flight.aircraft_code AND to_airport NOT LIKE from_airport AND stops>0 GROUP BY engines,category,cruising_speed,from_airport,to_airport ORDER BY engines DESC",29,$limits->{'group_functions'} && $limits->{'like_with_column'},
+ "select engines,category,cruising_speed,from_airport,to_airport FROM aircraft,flight WHERE category='JET' AND engines >= 1 AND aircraft.aircraft_code=flight.aircraft_code AND to_airport NOT LIKE from_airport AND stops>0 GROUP BY engines,category,cruising_speed,from_airport,to_airport ORDER BY engines DESC",29,$limits->{'group_functions'} && $limits->{'like_with_column'},
);
@Q=(\@Q1,\@Q2,\@Q21,\@Q3,\@Q4);
diff --git a/sql-bench/test-alter-table.sh b/sql-bench/test-alter-table.sh
index 276c4863d8c..2ca54000065 100644
--- a/sql-bench/test-alter-table.sh
+++ b/sql-bench/test-alter-table.sh
@@ -20,15 +20,17 @@
#
##################### Standard benchmark inits ##############################
+use Cwd;
use DBI;
use Benchmark;
$opt_start_field_count=8; # start with this many fields
-$opt_loop_count=20; # How many tests to do
+$opt_loop_count=100; # How many tests to do
$opt_row_count=1000; # Rows in the table
$opt_field_count=1000; # Add until this many fields.
+$opt_time_limit=10*60; # Don't wait more than 10 min for some tests
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
$opt_field_count=min($opt_field_count,$limits->{'max_columns'},
@@ -74,11 +76,25 @@ do_many($dbh,$server->create("bench",\@fields,\@index));
print "Insert data into the table\n";
$loop_time=new Benchmark;
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->{AutoCommit} = 0;
+ print "Transactions enabled\n" if ($opt_debug);
+}
+
for ($i=0 ; $i < $opt_row_count ; $i++)
{
$query="insert into bench values ( " . ("$i," x ($opt_start_field_count-1)) . "$i)";
$dbh->do($query) or die $DBI::errstr;
}
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+}
+
$end_time=new Benchmark;
print "Time for insert ($opt_row_count)",
@@ -99,10 +115,9 @@ if ($opt_fast)
}
else
{
- $add=1 if (!$limits{'alter_add_multi_col'});
+ $add=1 if (!$limits->{'alter_add_multi_col'});
}
-
$count=0;
while ($field_count < $opt_field_count)
{
@@ -117,19 +132,43 @@ while ($field_count < $opt_field_count)
$tmp="" if (!$multi_add); # Adabas
}
do_query($dbh,"ALTER TABLE bench " . substr($fields,1));
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$count,
+ $opt_field_count/$add+1));
}
$end_time=new Benchmark;
-print "Time for alter_table_add ($count): " .
+if ($estimated)
+{ print "Estimated time"; }
+else
+{ print "Time"; }
+print " for alter_table_add ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+#
+# If estimated, fix table to have known number of fields
+#
+if ($estimated && $field_count < $opt_field_count)
+{
+ $fields="";
+ $tmp="ADD ";
+ while ($field_count < $opt_field_count)
+ {
+ $field_count++;
+ $fields.=",$tmp i${field_count} integer";
+ $tmp="" if (!$multi_add); # Adabas
+ }
+ do_query($dbh,"ALTER TABLE bench " . substr($fields,1));
+}
+
####
#### Test adding and deleting index on the first $opt_start_fields
####
$loop_time=new Benchmark;
-for ($i=1; $i < $opt_start_field_count ; $i++)
+$count= 0;
+for ($i=1; $i <= $opt_start_field_count ; $i++)
{
$dbh->do("CREATE INDEX bench_ind$i ON bench (i${i})") || die $DBI::errstr;
}
@@ -139,7 +178,7 @@ print "Time for create_index ($opt_start_field_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
$loop_time=new Benchmark;
-for ($i=1; $i < $opt_start_field_count ; $i++)
+for ($i=1; $i <= $opt_start_field_count ; $i++)
{
$dbh->do($server->drop_index("bench","bench_ind$i")) || die $DBI::errstr;
}
@@ -168,10 +207,17 @@ while ($field_count > $opt_start_field_count)
}
$dbh->do("ALTER TABLE bench " . substr($fields,1) . $server->{'drop_attr'})
|| die $DBI::errstr;
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$count,
+ $opt_field_count/$add+1));
}
$end_time=new Benchmark;
-print "Time for alter_table_drop ($count): " .
+if ($estimated)
+{ print "Estimated time"; }
+else
+{ print "Time"; }
+print " for alter_table_drop ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
skip_dropcol:
diff --git a/sql-bench/test-big-tables.sh b/sql-bench/test-big-tables.sh
index ac942f2b571..fb58247eddd 100644
--- a/sql-bench/test-big-tables.sh
+++ b/sql-bench/test-big-tables.sh
@@ -21,13 +21,14 @@
##################### Standard benchmark inits ##############################
+use Cwd;
use DBI;
use Benchmark;
$opt_loop_count=1000; # Change this to make test harder/easier
$opt_field_count=1000;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
$opt_field_count=min($opt_field_count,$limits->{'max_columns'},
@@ -127,14 +128,28 @@ end_benchmark($start_time);
sub test_query
{
my($test_text,$result_text,$query,$dbh,$count)=@_;
- my($i,$loop_time,$end_time);
+ my($i,$loop_time,$end_time, $using_transactions);
print $test_text . "\n";
$loop_time=new Benchmark;
+
+ $using_transactions=0;
+ if ($opt_fast && server->{transactions} && $query=~ /^insert /i)
+ {
+ $using_transactions=1;
+ $dbh->{AutoCommit} = 0;
+ print "Transactions enabled\n" if ($opt_debug);
+ }
for ($i=0 ; $i < $count ; $i++)
{
defined(fetch_all_rows($dbh,$query)) or die $DBI::errstr;
}
+ if ($using_transactions)
+ {
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+ }
+
$end_time=new Benchmark;
print $result_text . "($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
diff --git a/sql-bench/test-connect.sh b/sql-bench/test-connect.sh
index 862161e3a03..b7a360cac38 100644
--- a/sql-bench/test-connect.sh
+++ b/sql-bench/test-connect.sh
@@ -24,14 +24,15 @@
# by using option --loop_value='what_ever_you_like'.
##################### Standard benchmark inits ##############################
+use Cwd;
use DBI;
use Benchmark;
-$opt_loop_count=10000; # Change this to make test harder/easier
+$opt_loop_count=100000; # Change this to make test harder/easier
$str_length=65000; # This is the length of blob strings in PART:5
$max_test=20; # How many times to test if the server is busy
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
# This is the length of blob strings in PART:5
@@ -43,9 +44,10 @@ if ($opt_small_test)
}
$opt_loop_count=min(1000, $opt_loop_count) if ($opt_tcpip);
+$small_loop_count=$opt_loop_count/10; # For connect tests
print "Testing the speed of connecting to the server and sending of data\n";
-print "All tests are done $opt_loop_count times\n\n";
+print "Connect tests are done $small_loop_count times and other tests $opt_loop_count times\n\n";
################################# PART:1 ###################################
####
@@ -59,7 +61,7 @@ print "Testing connection/disconnect\n";
$loop_time=new Benchmark;
$errors=0;
-for ($i=0 ; $i < $opt_loop_count ; $i++)
+for ($i=0 ; $i < $small_loop_count ; $i++)
{
print "$i " if (($opt_debug));
for ($j=0; $j < $max_test ; $j++)
@@ -80,27 +82,27 @@ for ($i=0 ; $i < $opt_loop_count ; $i++)
}
$end_time=new Benchmark;
print "Warning: $errors connections didn't work without a time delay\n" if ($errors);
-print "Time to connect ($opt_loop_count): " .
+print "Time to connect ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
################################# PART:2 ###################################
#### Now we shall do first one connect, then simple select
#### (select 1..) and then close connection. This will be
-#### done $opt_loop_count times.
+#### done $small_loop_count times.
if ($limits->{'select_without_from'})
{
print "Test connect/simple select/disconnect\n";
$loop_time=new Benchmark;
- for ($i=0; $i<$opt_loop_count; $i++)
+ for ($i=0; $i < $small_loop_count; $i++)
{
$dbh = DBI->connect($server->{'data_source'}, $opt_user, $opt_password) || die $DBI::errstr;
- $sth = $dbh->do("select 1") or die $DBI::errstr;
+ $sth = $dbh->do("select $i") or die $DBI::errstr;
$dbh->disconnect;
}
$end_time=new Benchmark;
- print "Time for connect+select_simple ($opt_loop_count): " .
+ print "Time for connect+select_simple ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
}
@@ -116,16 +118,33 @@ if ($limits->{'select_without_from'})
{
print "Test simple select\n";
$loop_time=new Benchmark;
- for ($i=0 ; $i<$opt_loop_count ; $i++)
+ for ($i=0 ; $i < $opt_loop_count ; $i++)
{
- $sth = $dbh->do("select 1") or die $DBI::errstr;
+ $sth = $dbh->do("select $i") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for select_simple ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
}
-################################# PART:4 ###################################
+###########################################################################
+#### The same as the previous test, but always execute the same select
+#### This is done to test the query cache for real simple selects.
+
+if ($limits->{'select_without_from'})
+{
+ print "Test simple select\n";
+ $loop_time=new Benchmark;
+ for ($i=0 ; $i < $opt_loop_count ; $i++)
+ {
+ $sth = $dbh->do("select 10000") or die $DBI::errstr;
+ }
+ $end_time=new Benchmark;
+ print "Time for select_simple_cache ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+##########################################################################
#### First, we'll create a simple table 'bench1'
#### Then we shall do $opt_loop_count selects from this table.
#### Table will contain very simple data.
@@ -152,7 +171,7 @@ print "Testing connect/select 1 row from table/disconnect\n";
$loop_time=new Benchmark;
$errors=0;
-for ($i=0 ; $i<$opt_loop_count ; $i++)
+for ($i=0 ; $i < $small_loop_count ; $i++)
{
for ($j=0; $j < $max_test ; $j++)
{
@@ -161,14 +180,14 @@ for ($i=0 ; $i<$opt_loop_count ; $i++)
}
die $DBI::errstr if ($j == $max_test);
- $sth = $dbh->do("select * from bench1") #Select * from table with 1 record
+ $sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 1 record
or die $DBI::errstr;
$dbh->disconnect;
}
$end_time=new Benchmark;
print "Warning: $errors connections didn't work without a time delay\n" if ($errors);
-print "Time to connect+select_1_row ($opt_loop_count): " .
+print "Time to connect+select_1_row ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
#
@@ -179,9 +198,9 @@ print "Testing select 1 row from table\n";
$dbh = $server->connect();
$loop_time=new Benchmark;
-for ($i=0 ; $i<$opt_loop_count ; $i++)
+for ($i=0 ; $i < $opt_loop_count ; $i++)
{
- $sth = $dbh->do("select * from bench1") # Select * from table with 1 record
+ $sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 1 record
or die $DBI::errstr;
}
@@ -190,8 +209,24 @@ print "Time to select_1_row ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
#
-# The same test, but with 2 rows.
+# Same test (as with one row) but now with a cacheable query
#
+
+$loop_time=new Benchmark;
+
+for ($i=0 ; $i < $opt_loop_count ; $i++)
+{
+ $sth = $dbh->do("select a,i,s from bench1") # Select * from table with 1 record
+ or die $DBI::errstr;
+}
+$end_time=new Benchmark;
+print "Time to select_1_row_cache ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+
+#
+# The same test, but with 2 rows (not cacheable).
+#
+
print "Testing select 2 rows from table\n";
$sth = $dbh->do("insert into bench1 values(2,200,'BBB')")
@@ -199,9 +234,9 @@ $sth = $dbh->do("insert into bench1 values(2,200,'BBB')")
$loop_time=new Benchmark;
-for ($i=0 ; $i<$opt_loop_count ; $i++)
+for ($i=0 ; $i < $opt_loop_count ; $i++)
{
- $sth = $dbh->do("select * from bench1") # Select * from table with 2 record
+ $sth = $dbh->do("select a,i,s,$i from bench1") # Select * from table with 2 record
or die $DBI::errstr;
}
@@ -209,14 +244,18 @@ $end_time=new Benchmark;
print "Time to select_2_rows ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+#
+# Simple test to test speed of functions.
+#
+
if ($limits->{'functions'})
{
print "Test select with aritmetic (+)\n";
$loop_time=new Benchmark;
- for ($i=0; $i<$opt_loop_count; $i++)
+ for ($i=0; $i < $opt_loop_count; $i++)
{
- $sth = $dbh->do("select a+a+a+a+a+a+a+a+a+a from bench1") or die $DBI::errstr;
+ $sth = $dbh->do("select a+a+a+a+a+a+a+a+a+$i from bench1") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for select_column+column ($opt_loop_count): " .
@@ -254,9 +293,9 @@ if ($opt_fast && defined($server->{vacuum}))
$loop_time=new Benchmark;
-for ($i=0 ; $i < $opt_loop_count ; $i++)
+for ($i=0 ; $i < $small_loop_count ; $i++)
{
- $sth = $dbh->prepare("select * from bench1");
+ $sth = $dbh->prepare("select b,$i from bench1");
if (!$sth->execute || !(@row = $sth->fetchrow_array) ||
length($row[0]) != $str_length)
{
@@ -266,14 +305,14 @@ for ($i=0 ; $i < $opt_loop_count ; $i++)
}
$end_time=new Benchmark;
-print "Time to select_big_str ($opt_loop_count): " .
+print "Time to select_big_str ($small_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
$sth = $dbh->do("drop table bench1" . $server->{'drop_attr'})
or do
{
# Fix for Access 2000
- die $dbh->errstr if (!$dbh->abort_if_fatal_error());
+ die $dbh->errstr if (!$server->abort_if_fatal_error());
};
if ($opt_fast && defined($server->{vacuum}))
diff --git a/sql-bench/test-create.sh b/sql-bench/test-create.sh
index 1e7d3841bb5..8188b47f587 100644
--- a/sql-bench/test-create.sh
+++ b/sql-bench/test-create.sh
@@ -30,13 +30,14 @@
##################### Standard benchmark inits ##############################
+use Cwd;
use DBI;
use Benchmark;
$opt_loop_count=10000; # Change this to make test harder/easier
# This is the default value for the amount of tables used in this test.
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
$create_loop_count=$opt_loop_count;
diff --git a/sql-bench/test-insert.sh b/sql-bench/test-insert.sh
index 655e38b1b0e..8f2d246ff12 100644
--- a/sql-bench/test-insert.sh
+++ b/sql-bench/test-insert.sh
@@ -21,14 +21,17 @@
# $opt_loop_count rows in random order
#
# changes made for Oracle compatibility
-# - $limits{'func_odbc_mod'} is OK from crash-me, but it fails here so set we
+# - $limits->{'func_odbc_mod'} is OK from crash-me, but it fails here so set we
# set it to 0 in server-cfg
-# - the default server config runs out of rollback segments, so I added a couple
-# of disconnect/connects to reset
+# - the default server config runs out of rollback segments, so we added a
+# couple of disconnect/connects to reset
+#
##################### Standard benchmark inits ##############################
+use Cwd;
use DBI;
use Benchmark;
+use Data::Dumper;
$opt_loop_count=100000; # number of rows/3
$small_loop_count=10; # Loop for full table retrieval
@@ -36,7 +39,7 @@ $range_loop_count=$small_loop_count*50;
$many_keys_loop_count=$opt_loop_count;
$opt_read_key_loop_count=$opt_loop_count;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
if ($opt_small_test)
@@ -110,7 +113,7 @@ do_many($dbh,$server->create("bench1",
"id3 int NOT NULL",
"dummy1 char(30)"],
["primary key (id,id2)",
- "index index_id3 (id3)"]));
+ "index ix_id3 (id3)"]));
if ($opt_lock_tables)
{
@@ -132,6 +135,12 @@ else
$query="insert into bench1 (id,id2,id3,dummy1) values ";
}
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->{AutoCommit} = 0;
+ print "Transactions enabled\n" if ($opt_debug);
+}
+
if (($opt_fast || $opt_fast_insert) && $server->{'limits'}->{'insert_multi_value'})
{
$query_size=$server->{'limits'}->{'query_size'};
@@ -209,6 +218,12 @@ else
}
}
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+}
+
$end_time=new Benchmark;
print "Time for insert (" . ($total_rows) . "): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -234,6 +249,12 @@ if ($limits->{'unique_index'})
{
print "Testing insert of duplicates\n";
$loop_time=new Benchmark;
+
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->{AutoCommit} = 0;
+ }
+
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$tmpvar^= ((($tmpvar + 63) + $i)*3 % $opt_loop_count);
@@ -244,6 +265,11 @@ if ($limits->{'unique_index'})
die "Didn't get an error when inserting duplicate record $tmp\n";
}
}
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+ }
$end_time=new Benchmark;
print "Time for insert_duplicates (" . ($opt_loop_count) . "): " .
@@ -577,7 +603,6 @@ if ($limits->{'group_functions'})
}
$sth->finish;
-
$count++;
$sth=$dbh->prepare($query="select count(*),sum(id+0.0),min(id),max(id),avg(id-0.0) from bench1") or die $DBI::errstr;
$sth->execute or die $DBI::errstr;
@@ -917,13 +942,19 @@ print "Time for update_with_key (" . ($opt_loop_count*3) . "): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
-for ($i=0 ; $i < $opt_loop_count*3 ; $i+=3)
+$count=0;
+for ($i=1 ; $i < $opt_loop_count*3 ; $i+=3)
{
$sth = $dbh->do("update bench1 set dummy1='updated' where id=$i") or die $DBI::errstr;
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$tests,
+ $opt_loop_count));
}
-
-$end_time=new Benchmark;
-print "Time for update_with_key_prefix (" . ($opt_loop_count) . "): " .
+if ($estimated)
+{ print "Estimated time"; }
+else
+{ print "Time"; }
+print " for update_with_key_prefix (" . ($opt_loop_count) . "): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
print "\nTesting update of all rows\n";
@@ -1167,7 +1198,7 @@ if (!$opt_skip_delete)
}
$end_time=new Benchmark;
- print "Time for delete_all ($count): " .
+ print "Time for delete_range ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
if ($opt_lock_tables)
@@ -1203,6 +1234,7 @@ print "Insert into table with $keys keys and with a primary key with $seg parts\
# Make keys on the most important types
@types=(0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1); # A 1 for each char field
push(@fields,"field1 tinyint not null");
+push(@fields,"field_search tinyint not null");
push(@fields,"field2 mediumint not null");
push(@fields,"field3 smallint not null");
push(@fields,"field4 char(16) not null");
@@ -1222,9 +1254,10 @@ for ($i= 1 ; $i <= $seg ; $i++)
}
substr($query,-1)=")";
push (@keys,$query);
+push (@keys,"index index2 (field_search)");
#Create other keys
-for ($i=2 ; $i <= $keys ; $i++)
+for ($i=3 ; $i <= $keys ; $i++)
{
push(@keys,"index index$i (field$i)");
}
@@ -1242,6 +1275,11 @@ if ($server->small_rollback_segment())
}
$loop_time=new Benchmark;
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->{AutoCommit} = 0;
+}
+
$fields=$#fields;
if (($opt_fast || $opt_fast_insert) && $server->{'limits'}->{'insert_multi_value'})
{
@@ -1250,11 +1288,11 @@ if (($opt_fast || $opt_fast_insert) && $server->{'limits'}->{'insert_multi_value
$res=$query;
for ($i=0; $i < $many_keys_loop_count; $i++)
{
+ $id= $i & 127;
$rand=$random[$i];
- $tmp="(" . ($i & 127) . ",$rand," . ($i & 32766) .
- ",'ABCDEF$rand',0,";
+ $tmp="($id,$id,$rand," . ($i & 32766) . ",'ABCDEF$rand',0,$rand,$rand.0,";
- for ($j=5; $j <= $fields ; $j++)
+ for ($j=8; $j <= $fields ; $j++)
{
$tmp.= ($types[$j] == 0) ? "$rand," : "'$rand',";
}
@@ -1275,11 +1313,12 @@ else
{
for ($i=0; $i < $many_keys_loop_count; $i++)
{
+ $id= $i & 127;
$rand=$random[$i];
- $query="insert into bench1 values (" . ($i & 127) . ",$rand," . ($i & 32767) .
- ",'ABCDEF$rand',0,";
+ $query="insert into bench1 values ($id,$id,$rand," . ($i & 32767) .
+ ",'ABCDEF$rand',0,$rand,$rand.0,";
- for ($j=5; $j <= $fields ; $j++)
+ for ($j=8; $j <= $fields ; $j++)
{
$query.= ($types[$j] == 0) ? "$rand," : "'$rand',";
}
@@ -1288,6 +1327,13 @@ else
$dbh->do($query) or die "Got error $DBI::errstr with query: $query\n";
}
}
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+}
+
$end_time=new Benchmark;
print "Time for insert_key ($many_keys_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -1316,11 +1362,24 @@ if ($opt_fast && defined($server->{vacuum}))
print "Testing update of keys\n";
$loop_time=new Benchmark;
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->{AutoCommit} = 0;
+}
+
for ($i=0 ; $i< 256; $i++)
{
- $dbh->do("update bench1 set field5=1 where field1=$i")
- or die "Got error $DBI::errstr with query: update bench1 set field5=1 where field1=$i\n";
+ $dbh->do("update bench1 set field5=1 where field_search=$i")
+ or die "Got error $DBI::errstr with query: update bench1 set field5=1 where field_search=$i\n";
+}
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
}
+
$end_time=new Benchmark;
print "Time for update_of_primary_key_many_keys (256): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -1360,29 +1419,31 @@ $count=0;
for ($i=0 ; $i < 128 ; $i++)
{
$count++;
- $dbh->do("delete from bench1 where field1 = $i") or die $DBI::errstr;
+ $dbh->do("delete from bench1 where field_search = $i") or die $DBI::errstr;
}
$end_time=new Benchmark;
print "Time for delete_big_many_keys ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+if ($opt_lock_tables)
+{
+ $sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
+}
+
print "Deleting everything from table\n";
$count=1;
if ($opt_fast)
{
- $dbh->do("delete from bench1") or die $DBI::errstr;
+ $query= ($limits->{'truncate_table'} ? "truncate table bench1" :
+ "delete from bench1");
+ $dbh->do($query) or die $DBI::errstr;
}
else
{
$dbh->do("delete from bench1 where field1 > 0") or die $DBI::errstr;
}
-if ($opt_lock_tables)
-{
- $sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
-}
-
$end_time=new Benchmark;
print "Time for delete_all_many_keys ($count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -1409,12 +1470,18 @@ if ($limits->{'insert_multi_value'})
"dummy1 char(30)"],
["primary key (id,id2)",
"index index_id3 (id3)"]));
+
+ $loop_time=new Benchmark;
+
if ($opt_lock_tables)
{
$sth = $dbh->do("LOCK TABLES bench1 write") || die $DBI::errstr;
}
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->{AutoCommit} = 0;
+ }
- $loop_time=new Benchmark;
print "Inserting $opt_loop_count rows with multiple values\n";
$query="insert into bench1 values ";
$res=$query;
@@ -1437,6 +1504,11 @@ if ($limits->{'insert_multi_value'})
{
$sth = $dbh->do("UNLOCK TABLES ") || die $DBI::errstr;
}
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+ }
$end_time=new Benchmark;
print "Time for multiple_value_insert (" . ($opt_loop_count) . "): " .
diff --git a/sql-bench/test-select.sh b/sql-bench/test-select.sh
index 1ecad5804c5..63f70b0aaa1 100644
--- a/sql-bench/test-select.sh
+++ b/sql-bench/test-select.sh
@@ -20,6 +20,7 @@
#
##################### Standard benchmark inits ##############################
+use Cwd;
use DBI;
use Getopt::Long;
use Benchmark;
@@ -30,7 +31,7 @@ $opt_small_loop_count=10;
$opt_regions=6;
$opt_groups=100;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
$columns=min($limits->{'max_columns'},500,($limits->{'query_size'}-50)/24,
@@ -92,6 +93,12 @@ if ($opt_fast && defined($server->{vacuum}))
print "Inserting $opt_loop_count rows\n";
$loop_time=new Benchmark;
+
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->{AutoCommit} = 0;
+}
+
$query="insert into bench1 values (";
$half_done=$opt_loop_count/2;
for ($id=0,$rev_id=$opt_loop_count-1 ; $id < $opt_loop_count ; $id++,$rev_id--)
@@ -105,6 +112,12 @@ for ($id=0,$rev_id=$opt_loop_count-1 ; $id < $opt_loop_count ; $id++,$rev_id--)
}
}
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+}
+
$end_time=new Benchmark;
print "Time to insert ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
@@ -141,10 +154,10 @@ if ($limits->{'group_functions'})
$loop_time=new Benchmark;
for ($tests=0 ; $tests < $opt_loop_count ; $tests++)
{
- fetch_all_rows($dbh,"select sum(idn+$tests),sum(rev_idn-$tests) from bench1");
+ fetch_all_rows($dbh,"select sum(idn+100),sum(rev_idn-100) from bench1");
}
$end_time=new Benchmark;
- print "Time for select_query_cache ($opt_loop_count): " .
+ print "Time for select_cache ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
# If the database has a query cache, the following loop should be much
@@ -156,7 +169,7 @@ if ($limits->{'group_functions'})
fetch_all_rows($dbh,"select sum(idn+$tests),sum(rev_idn-$tests) from bench1");
}
$end_time=new Benchmark;
- print "Time for select_query_cache2 ($opt_loop_count): " .
+ print "Time for select_cache2 ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
}
@@ -343,19 +356,23 @@ if ($limits->{'group_distinct_functions'})
print " for count_distinct ($count:$rows): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
- $loop_time=new Benchmark;
- $rows=$estimated=$count=0;
- for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+# Workaround mimer's behavior
+ if ($limits->{'multi_distinct'})
{
- $count++;
- $rows+=fetch_all_rows($dbh,"select count(distinct grp),count(distinct rev_idn) from bench1");
- $end_time=new Benchmark;
- last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
+ $loop_time=new Benchmark;
+ $rows=$estimated=$count=0;
+ for ($i=0 ; $i < $opt_medium_loop_count ; $i++)
+ {
+ $count++;
+ $rows+=fetch_all_rows($dbh,"select count(distinct grp),count(distinct rev_idn) from bench1");
+ $end_time=new Benchmark;
+ last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i+1,
$opt_medium_loop_count));
+ }
+ print_time($estimated);
+ print " for count_distinct_2 ($count:$rows): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n";
}
- print_time($estimated);
- print " for count_distinct_2 ($count:$rows): " .
- timestr(timediff($end_time, $loop_time),"all") . "\n";
$loop_time=new Benchmark;
$rows=$estimated=$count=0;
diff --git a/sql-bench/test-transactions.sh b/sql-bench/test-transactions.sh
new file mode 100644
index 00000000000..50d7098bca7
--- /dev/null
+++ b/sql-bench/test-transactions.sh
@@ -0,0 +1,298 @@
+#!@PERL@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+#
+# Test of transactions performance.
+#
+
+##################### Standard benchmark inits ##############################
+
+use Cwd;
+use DBI;
+use Benchmark;
+#use warnings;
+
+$opt_groups=27; # Characters are 'A' -> Z
+
+$opt_loop_count=10000; # Change this to make test harder/easier
+$opt_medium_loop_count=100; # Change this to make test harder/easier
+
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
+require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
+
+# Avoid warnings for variables in bench-init.pl
+# (Only works with perl 5.6)
+#our ($opt_small_test, $opt_small_tables, $opt_debug, $opt_force);
+
+if ($opt_small_test || $opt_small_tables)
+{
+ $opt_loop_count/=100;
+ $opt_medium_loop_count/=10;
+}
+
+
+if (!$server->{transactions} && !$opt_force)
+{
+ print "Test skipped because the database doesn't support transactions\n";
+ exit(0);
+}
+
+####
+#### Connect and start timeing
+####
+
+$start_time=new Benchmark;
+$dbh = $server->connect();
+
+###
+### Create Table
+###
+
+print "Creating tables\n";
+$dbh->do("drop table bench1");
+$dbh->do("drop table bench2");
+
+do_many($dbh,$server->create("bench1",
+ ["idn int NOT NULL",
+ "rev_idn int NOT NULL",
+ "region char(1) NOT NULL",
+ "grp int NOT NULL",
+ "updated tinyint NOT NULL"],
+ ["primary key (idn)",
+ "unique (region,grp)"]));
+do_many($dbh,$server->create("bench2",
+ ["idn int NOT NULL",
+ "rev_idn int NOT NULL",
+ "region char(1) NOT NULL",
+ "grp int NOT NULL",
+ "updated tinyint NOT NULL"],
+ ["primary key (idn)",
+ "unique (region,grp)"]));
+
+$dbh->{AutoCommit} = 0;
+
+###
+### Test insert perfomance
+###
+
+test_insert("bench1","insert_commit",0);
+test_insert("bench2","insert_autocommit",1);
+
+sub test_insert
+{
+ my ($table, $test_name, $auto_commit)= @_;
+ my ($loop_time,$end_time,$id,$rev_id,$grp,$region);
+
+ $dbh->{AutoCommit}= $auto_commit;
+ $loop_time=new Benchmark;
+
+ for ($id=0,$rev_id=$opt_loop_count-1 ; $id < $opt_loop_count ;
+ $id++,$rev_id--)
+ {
+ $grp=$id/$opt_groups;
+ $region=chr(65+$id%$opt_groups);
+ do_query($dbh,"insert into $table values ($id,$rev_id,'$region',$grp,0)");
+ }
+
+ $dbh->commit if (!$auto_commit);
+ $end_time=new Benchmark;
+ print "Time for $test_name ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+###
+### Test rollback performance
+###
+
+print "Test transactions rollback performance\n" if($opt_debug);
+
+##
+## Insert rollback test
+##
+
+#
+# Test is done by inserting 100 rows in a table with lots of rows and
+# then doing a rollback on these
+#
+
+{
+ my ($id,$rev_id,$grp,$region,$end,$loop_time,$end_time,$commit_loop,$count);
+
+ $dbh->{AutoCommit} = 0;
+ $loop_time=new Benchmark;
+ $end=$opt_loop_count*2;
+ $count=0;
+
+ for ($commit_loop=1, $id=$opt_loop_count ; $id < $end ;
+ $id++, $commit_loop++)
+ {
+ $rev_id=$end-$id;
+ $grp=$id/$opt_groups;
+ $region=chr(65+$id%$opt_groups);
+ do_query($dbh,"insert into bench1 values ($id,$rev_id,'$region',$grp,0)");
+ if ($commit_loop >= $opt_medium_loop_count)
+ {
+ $dbh->rollback;
+ $commit_loop=0;
+ $count++;
+ }
+ }
+ if ($commit_loop > 1)
+ {
+ $dbh->rollback;
+ $count++;
+ }
+ $end_time=new Benchmark;
+ print "Time for insert_rollback ($count:$opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+##
+## Update rollback test
+##
+
+#
+# Test is done by updating 100 rows in a table with lots of rows and
+# then doing a rollback on these
+#
+
+{
+ my ($id,$loop_time,$end_time,$commit_loop,$count);
+
+ $dbh->{AutoCommit} = 0;
+ $loop_time=new Benchmark;
+ $end=$opt_loop_count*2;
+ $count=0;
+
+ for ($commit_loop=1, $id=0 ; $id < $opt_loop_count ; $id++, $commit_loop++)
+ {
+ do_query($dbh,"update bench1 set updated=2 where idn=$id");
+ if ($commit_loop >= $opt_medium_loop_count)
+ {
+ $dbh->rollback;
+ $commit_loop=0;
+ $count++;
+ }
+ }
+ if ($commit_loop > 1)
+ {
+ $dbh->rollback;
+ $count++;
+ }
+ $end_time=new Benchmark;
+ print "Time for update_rollback ($count:$opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+##
+## Delete rollback test
+##
+
+#
+# Test is done by deleting 100 rows in a table with lots of rows and
+# then doing a rollback on these
+#
+
+{
+ my ($id,$loop_time,$end_time,$commit_loop,$count);
+
+ $dbh->{AutoCommit} = 0;
+ $loop_time=new Benchmark;
+ $end=$opt_loop_count*2;
+ $count=0;
+
+ for ($commit_loop=1, $id=0 ; $id < $opt_loop_count ; $id++, $commit_loop++)
+ {
+ do_query($dbh,"delete from bench1 where idn=$id");
+ if ($commit_loop >= $opt_medium_loop_count)
+ {
+ $dbh->rollback;
+ $commit_loop=0;
+ $count++;
+ }
+ }
+ if ($commit_loop > 1)
+ {
+ $dbh->rollback;
+ $count++;
+ }
+ $end_time=new Benchmark;
+ print "Time for delete_rollback ($count:$opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+
+###
+### Test update perfomance
+###
+
+test_update("bench1","update_commit",0);
+test_update("bench2","update_autocommit",1);
+
+sub test_update
+{
+ my ($table, $test_name, $auto_commit)= @_;
+ my ($loop_time,$end_time,$id);
+
+ $dbh->{AutoCommit}= $auto_commit;
+ $loop_time=new Benchmark;
+
+ for ($id=0 ; $id < $opt_loop_count ; $id++)
+ {
+ do_query($dbh,"update $table set updated=1 where idn=$id");
+ }
+
+ $dbh->commit if (!$auto_commit);
+ $end_time=new Benchmark;
+ print "Time for $test_name ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+###
+### Test delete perfomance
+###
+
+test_delete("bench1","delete_commit",0);
+test_delete("bench2","delete_autocommit",1);
+
+sub test_delete
+{
+ my ($table, $test_name, $auto_commit)= @_;
+ my ($loop_time,$end_time,$id);
+
+ $dbh->{AutoCommit}= $auto_commit;
+ $loop_time=new Benchmark;
+
+ for ($id=0 ; $id < $opt_loop_count ; $id++)
+ {
+ do_query($dbh,"delete from $table where idn=$id");
+ }
+ $dbh->commit if (!$auto_commit);
+ $end_time=new Benchmark;
+ print "Time for $test_name ($opt_loop_count): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+}
+
+####
+#### End of benchmark
+####
+
+$sth = $dbh->do("drop table bench1" . $server->{'drop_attr'}) or die $DBI::errstr;
+$sth = $dbh->do("drop table bench2" . $server->{'drop_attr'}) or die $DBI::errstr;
+
+$dbh->disconnect; # close connection
+end_benchmark($start_time);
diff --git a/sql-bench/test-wisconsin.sh b/sql-bench/test-wisconsin.sh
index a017120259e..89ffb9aa629 100644
--- a/sql-bench/test-wisconsin.sh
+++ b/sql-bench/test-wisconsin.sh
@@ -17,12 +17,13 @@
# MA 02111-1307, USA
#
+use Cwd;
use DBI;
use Benchmark;
$opt_loop_count=10;
-chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
+$pwd = cwd(); $pwd = "." if ($pwd eq '');
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
$into_table = "";
@@ -48,27 +49,36 @@ init_query();
print "Wisconsin benchmark test\n\n";
-if (!$opt_skip_create)
+if ($opt_skip_create)
{
- $loop_time= new Benchmark;
- for($ti = 0; $ti <= $#table_names; $ti++)
+ if ($opt_lock_tables)
{
- my $table_name = $table_names[$ti];
- my $array_ref = $tables[$ti];
-
- # This may fail if we have no table so do not check answer
- $sth = $dbh->do("drop table $table_name" . $server->{'drop_attr'});
- print "Creating table $table_name\n" if ($opt_verbose);
- do_many($dbh,@$array_ref);
+ @tmp=@table_names; push(@tmp,@extra_names);
+ $sth = $dbh->do("LOCK TABLES " . join(" WRITE,", @tmp) . " WRITE") ||
+ die $DBI::errstr;
}
- $end_time=new Benchmark;
- print "Time for create_table ($#tables): " .
- timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+ goto start_benchmark;
+}
- if ($opt_fast && defined($server->{vacuum}))
- {
- $server->vacuum(1,\$dbh);
- }
+$loop_time= new Benchmark;
+for($ti = 0; $ti <= $#table_names; $ti++)
+{
+ my $table_name = $table_names[$ti];
+ my $array_ref = $tables[$ti];
+
+ # This may fail if we have no table so do not check answer
+ $sth = $dbh->do("drop table $table_name" . $server->{'drop_attr'});
+ print "Creating table $table_name\n" if ($opt_verbose);
+ do_many($dbh,@$array_ref);
+}
+$end_time=new Benchmark;
+print "Time for create_table ($#tables): " .
+ timestr(timediff($end_time, $loop_time),"all") . "\n\n";
+
+if ($opt_fast && defined($server->{vacuum}))
+{
+ $server->vacuum(1,\$dbh);
+}
####
@@ -100,6 +110,11 @@ if ($opt_fast && $server->{'limits'}->{'load_data_infile'})
}
else
{
+ if ($opt_fast && $server->{transactions})
+ {
+ $dbh->{AutoCommit} = 0;
+ }
+
for ($ti = 0; $ti <= $#table_names; $ti++)
{
my $table_name = $table_names[$ti];
@@ -124,10 +139,17 @@ else
}
close(DATA);
}
+
if ($opt_lock_tables)
{
do_query($dbh,"UNLOCK TABLES");
}
+if ($opt_fast && $server->{transactions})
+{
+ $dbh->commit;
+ $dbh->{AutoCommit} = 1;
+}
+
$end_time=new Benchmark;
print "Time to insert ($row_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n";
@@ -159,13 +181,6 @@ $sth = $dbh->do("delete from Bprime where Bprime.unique2 >= 1000") or
$end_time=new Benchmark;
print "Time to delete_big (1): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
-}
-elsif ($opt_lock_tables)
-{
- @tmp=@table_names; push(@tmp,@extra_names);
- $sth = $dbh->do("LOCK TABLES " . join(" WRITE,", @tmp) . " WRITE") ||
- die $DBI::errstr;
-}
if ($opt_fast && defined($server->{vacuum}))
{
@@ -176,7 +191,9 @@ if ($opt_fast && defined($server->{vacuum}))
#### Running the benchmark
####
-print "Running actual benchmark\n";
+start_benchmark:
+
+print "Running the actual benchmark\n";
$loop_time= new Benchmark;
$count=0;
@@ -226,7 +243,7 @@ sub init_data
{
@onek=
$server->create("onek",
- ["unique1 int(4) NOT NULL",
+ ["unique1 int(5) NOT NULL",
"unique2 int(4) NOT NULL",
"two int(4)",
"four int(4)",
diff --git a/sql/ChangeLog b/sql/ChangeLog
deleted file mode 100644
index 2289765afad..00000000000
--- a/sql/ChangeLog
+++ /dev/null
@@ -1,3302 +0,0 @@
-2000-11-11 Jeremy Cole <jeremy@mysql.com>
-
-* Added ALTER TABLE ... ORDER BY ...
-
-2000-09-17 Michael Widenius <monty@mysql.com>
-
-* Added option QUICK to DELETE to tell MySQL not to balance the
- trees on delete.
-
-2000-09-15 Michael Widenius <monty@mysql.com>
-
-* Added a thd argument to log::write() to get more speed.
-
-2000-09-01 Michael Widenius <monty@mysql.com>
-
-* Avoid allocation of "localhost" string.
-* Changed that TIMESTAMP(X) is sometimes as string
-* Release of 3.23.23
-
-2000-08-21 Michael Widenius <monty@mysql.com>
-
-* Added RENAME TABLE.
-
-2000-08-20 Michael Widenius <monty@mysql.com>
-
-* Added memory as inline functions to THD to get them a bit faster
-* Don't count entries with NULL in COUNT(DISTINCT ..)
-
-2000-08-08 Michael Widenius <monty@mysql.com>
-
-* Changed ALTER TABLE and LOAD DATA INFILE to create non unique, small keys
- after all rows are inserted.
-* Fixed use of UDF function with const arguments in WHERE clause.
-
-2000-07-11 Michael Widenius <monty@mysql.com>
-
-* Extended safe_mysqld; Patch by Christian Hammers
-
-2000-07-04 Michael Widenius <monty@mysql.com>
-
-* Changed the update log to take the query length argument; This
- should make the update log \0 safe.
-
-2000-06-21 Michael Widenius <monty@mysql.com>
-
-* Added net_read_timeout and net_write_timeout as startup parameters to mysqld
-
-2000-06-19 Michael Widenius <monty@mysql.com>
-
-* Changed the copyright of MySQL to GPL and LGPL.
-* Added myisampack and pack_isam to the MySQL distribution.
-
-2000-06-01 Michael Widenius <monty@mysql.com>
-
-* Added "FLUSH TABLES WITH READ LOCK" command
-
-2000-05-31 Michael Widenius <monty@mysql.com>
-
-* Added table locks to Berkeley DB.
-
-2000-05-28 Michael Widenius <monty@mysql.com>
-
-* Allow ON and USING with INNER JOIN.
-
-2000-05-23 Sasha
-
-* Fix that USE INDEX with 'PRIMARY' keys works.
-
-2000-05-20 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Added symbolic links support for Win32.
-
-2000-05-19 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Changed protocol to let client know if the server is in AUTOCOMMIT mode
- and if there is a pending transaction. If there is a pending transaction
- the client library will give an error before reconnecting to the server to
- let the client know that the server did a rollback.
- The protocol is still backward compatible with old clients
-* 'kill' now works on a thread that is locked on a 'write' to a dead client.
-
-2000-05-18 Michael Widenius <monty@tik.pp.sci.fi>
-
-* unlock tables before sending last packet of SELECT ... result to client.
-
-2000-05-16 Michael Widenius <monty@mysql.com>
-
-* split Item_bool_func2::compare function into individual functions to get more
- speed.
-* Small optimizations of do_select() to get more speed.
-
-2000-05-15 Michael Widenius <monty@mysql.com>
-
-* CHECK will update the statistics for the keys.
-* Fixed bug in REPAIR TABLE when the table was used by other threads.
-
-2000-05-11 Michael Widenius <monty@mysql.com>
-
-* put CREATE TEMPORARY TABLE commands in the update log.
-* UPDATE IGNORE will not abort if an update gives a DUPLICATE_KEY error.
-* Ensure that all fn_format() or unpack_filename() is called for all
- generated filenames.
-
-2000-05-05 Michael Widenius <monty@mysql.com>
-
-* Added timzone variable to SHOW VARIABLES.
-
-2000-05-04 Michael Widenius <monty@mysql.com>
-
-* Don't write INSERT DELAYED to update log if SQL_LOG_UPDATE=0
-
-2000-05-03 Michael Widenius <monty@mysql.com>
-
-* Fixed problem with REPLACE on HEAP tables.
-
-2000-04-26 Michael Widenius <monty@mysql.com>
-
-* Added 'Writing to net' and 'Reading from net' as 'status' to
- mysqladmin processlist.
-
-2000-04-23 Michael Widenius <monty@mysql.com>
-
-* Added CREATE DATABASE and DROP DATABASE to the update log
-* Fixed problem when doing a GROUP BY on an enum column with MANY
- value combinations.
-* Avoid sorting for some simple GROUP BY queries.
-
-2000-04-22 Michael Widenius <monty@mysql.com>
-
-* Fixed problems in update log when using LAST_INSERT_ID() to update
- an table with an auto_increment key.
-* New function: 'NULLIF(expr1,expr2)'
-
-2000-04-14 Michael Widenius <monty@tik.pp.sci.fi>
-
-* UPDATE and DELETE on UNIQUE keys, where the whole key is used in the WHERE
- part, are now faster than before.
-
-* Added optimisation to skip ORDER BY parts where the order by column
- is a constant expression in the WHERE part. ORDER BY will also
- be skipped if ORDER BY matches a key where the key parts that are
- missing in the ORDER BY is constants:
-
- In the following case the ORDER BY will be removed:
- SELECT * FROM foo WHERE column=constant ORDER BY column;
-
- In the following case the first key will be used to solve the ORDER BY:
- SELECT * FROM foo WHERE key_part1=const ORDER BY key_part2;
-
-2000-04-10 Michael Widenius <monty@mysql.com>
-
-* Changed mysql.server to wait until the pid file is deleted on stop
-* Clients will automaticly be set to the same character set as the
- server if one hasn't specified a character set with mysql_option()
- or in the my.cnf files.
-
-2000-04-09 Michael Widenius <monty@mysql.com>
-
-* Release of 3.23.14
-* Fixed bug where complex CONCAT() use returned the wrong result.
-
-2000-04-07 Michael Widenius <monty@mysql.com>
-
-* Added some optimization to LIMIT when the used KEY matches almost all
- rows in the table. (SELECT * from table where key_column > "a" LIMIT 1).
-* REPLACE now honors the LOW_PRIORITY_UPDATES flag.
-
-2000-04-05 Michael Widenius <monty@mysql.com>
-
-* Fixed that DROP TABLE is logged in the update log.
-* Fixed problem when searching on DECIMAL() key field
- where the column data contained pre-zeros.
-
-2000-04-02 Michael Widenius <monty@mysql.com>
-
-* Fix bug in myisamchk when the auto_increment isn't the first key.
-
-2000-03-30 "Thimble Smith" <tim@mysql.com>
-
-* Allow DATETIME in ISO8601 format: 2000-03-12T12:00:00
-
-2000-03-30 Michael Widenius <monty@mysql.com>
-
-* Added UMASK_DIR environment variable.
-* Fixed problem with seek and RAID tables.
-
-2000-03-29 Michael Widenius <monty@mysql.com>
-
-* slow_queries log wasn't flushed on FLUSH LOGS.
-
-2000-03-28 Michael Widenius <monty@mysql.com>
-
-* Fix that DELETE FROM table_name; works on RAID tables.
-* Fix that DROP DATABASE works correctly with RAID tables.
-
-2000-03-27 Michael Widenius <monty@mysql.com>
-
-* Added function CONNECTION_ID()
-
-2000-03-26 Michael Widenius <monty@mysql.com>
-
-* When using = on BLOB or VARCHAR BINARY keys where only a part of the column
- was indexed, the whole column of the result row wasn't compared.
-
-2000-03-24 takeshi@SoftAgency.co.jp
-
-* Fix for sjis & order by
-
-2000-03-23 Michael Widenius <monty@mysql.com>
-
-* Added patches to allow client library to compile on BEOS.
-
-2000-03-16 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added STDCALL to some functions in libmysql that missed this.
-* When running in ANSI mode, don't allow one to use columns that isn't in
- the GROUP BY part.
-
-2000-03-14 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of 3.23.13
-* Removed end space from double/float numbers in results from temporary
- tables.
-
-2000-03-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed automatic removal of table locks if doing a DROP TABLE on the last
- locked table.
-
-2000-03-13 Sasha
-
-* Added CHECK TABLE command.
-
-2000-03-12 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed int2str and longlong2str to use the optimized
- int10_to_str / longlong10_to_str functions.
-
-2000-03-09 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed bug so that mysqladmin shutdown will wait for the local server to close
- down.
-* Fixed a possible endless loop when calculating timestamp.
-
-2000-02-27 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of 3.23.12
-* Changed that mysql_ping() doesn't increment the 'questions' status variable.
-* Fixed that mysql -D database doesn't kill 'mysql'.
-
-2000-02-24 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Only allow SHOW GRANTS if you have a privilege on the mysql
- tables
-* Fixed bug when storing 0 into a timestamp.
-
-2000-02-23 Michael Widenius <monty@monty.pp.sci.fi>
-
-* When doing mysqladmin shutdown on a local connection, mysqladmin now
- waits until the pidfile is gone before doing an shutdown.
-* Changed that the pid file is not removed until all threads have died.
-
-2000-02-23 Matt Wagner
-
-* When doing mysqladmin shutdown on a local connection, mysqladmin now
- waits until the pidfile is gone before doing an shutdown.
-
-2000-02-23 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with LEFT JOIN and key_field IS NULL.
-
-2000-02-23 Sasha
-
-* Fixed core dump with some COUNT(DISTINCT ...) queries.
-
-2000-02-21 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added options USE KEYS (key_list) and IGNORE KEYS (key_list) as
- join parameters in SELECT.
-* DROP of table is now done through the handler.
-
-2000-02-17 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added ANSI SQL syntax ALTER TABLE ADD (column_def1, column_def2 ...)
-
-2000-02-16 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with optimizer that could sometimes use wrong keys
-
-2000-02-15 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed that GRANT/REVOKE ALL PRIVILEGES doesn't affect GRANT OPTION
-* Removed extra ) from the output of SHOW GRANTS
-
-2000-02-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem when storing numbers in timestamps.
-* Fix problem with timezones that has half hour offsets.
-* Storage of numbers in timestamp columns are now faster.
-
-2000-02-11 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Allow the syntax UNIQUE INDEX in CREATE statements.
-
-2000-02-10 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added options --i-am-a-dummy and --safe-updates to mysql.cc
-* Added variables select_limit and max_join_size to mysql.cc
-* Added sql variables: SQL_MAX_JOIN_SIZE and SQL_SAFE_UPDATES
-* Added READ_LOCAL lock that doesn't lock the table for concurrent inserts
-* Changed that LOCK TABLES .. READ doesn't anymore allow concurrent inserts
-* Added option --skip-delay-key-write to mysqld.
-
-2000-02-09 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed security problem in the protocol regarding password checking.
-
-2000-02-03 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Allow 'end' as a field name.
-* Added _rowid as an alias for an auto_increment column.
-
-2000-01-28 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Ignore empty queries in mysql when running in batch mode
- (To be able to handle rows with double ';' chars).
-
-2000-01-27 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with timestamps and INSERT DELAYED
-
-2000-01-26 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Fixed problem that affected queries that did arithmetic on GROUP functions.
-
-2000-01-24 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Don't give a unnecessary GRANT error when using tables from many
- databases in the same query.
-
-2000-01-20 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Fixed that 'date_column BETWEEN const_date AND const_date' works.
-
-2000-01-19 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem when only changing a 0 to NULL in a table with BLOB/TEXT
- columns.
-* Fixed bug in range optimizer when using many key parts and or on the middle
- key parts: WHERE K1=1 and K3=2 and (K2=2 and K4=4 or K2=3 and K4=5)
-* Added the virtual VIO interface to the mysql connection streams.
- (This will make it possible to use SSL through the VIO classe interface)
-
-2000-01-14 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added command 'source' to mysql to allow reading of batch files inside
- mysql. Original patch by Matthew Vanecek.
-
-2000-01-12 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed bug that a change of all VARCHAR columns to CHAR columns didn't change
- row type from dynamic to fixed.
-
-2000-01-11 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added print of default arguments options to all clients.
-* Added --log-slow-queries to mysqld to log all queries that takes a
- long time to a separate log file with a time of how long the query took.
-* Fixed critical problem with the WITH GRANT OPTION option.
-* Added read-next-on-key to HEAP tables. This should fix all
- problems with HEAP tables when using not UNIQUE keys.
-* Disabled floating point exceptions for FreeBSD to fix core dump when
- doing SELECT floor(pow(2,63));
-
-2000-01-07 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed core dump when doing WHERE key_column=RAND(...)
- (Note that this query can never use keys as the RAND() function must be
- re-evaluated for each row)
-2000-01-04 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed optimization bug in SELECT .. LEFT JOIN ... key_column IS NULL, when
- key_column could contain NULL values.
-* Fixed problem with 8 bit characters as separators in LOAD DATA INFILE.
-
-2000-01-02 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of 3.23.8
-
-1999-12-31 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed GRANT problem when doing 'CREATE TABLE ... SELECT'
-
-1999-12-30 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with timezones that are < GMT -11
-* Fixed problem with ISAM when doing some ORDER BY .. DESC queries.
-
-1999-12-28 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed bug when doing a join on a text key which didn't covert the whole key.
-* Option --delay-key-write didn't enable delayed key writing
-* Fixed update of TEXT column which only involved case changes.
-
-1999-12-27 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed that INSERT DELAYED doesn't update timestamps that are given.
-
-1999-12-25 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added function yearweek() and options 'x', 'X', 'v' and 'V' to date_format()
-
-1999-12-22 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Fixed problem with MAX(indexed_column) and HEAP tables.
-* Fixed problem with BLOB NULL keys and LIKE "prefix%".
-
-1999-12-20 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with MyISAM and fixed length rows < 5 bytes.
-
-1999-12-10 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added RAID support (patch from Tõnu Samuel)
-
-1999-12-02 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added -O interactive_timeout to mysqld.
-* Changed the argument of mysql_data_seek to ulonglong from ulong.
-
-1999-11-30 Michael Widenius <monty@monty.pp.sci.fi>
-
-Fixed bug in replace() on Alpha. Patch by 'Tom Holroyd'
-Fixed bug in LOAD DATA LOCAL INFILE on Alpha. Patch by 'Tom Holroyd'
-
-1999-11-29 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added detection of pthread_attr_stacksize() in configure.
-* Added variable net_retry_count (needed for FreeBSD).
-
-Sun Nov 28 20:55:45 1999 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* Added option '--verbose' to mysqladmin
-
-1999-11-28 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem when converting heap to myisam.
-* Fixed bug in HEAP tables when doing insert + delete + insert + scan the
- table.
-
-1999-11-23 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fix core dump when releasing a lock from a non existing table
-* Remove locks on tables before starting to remove duplicates.
-* Added patch to make most string functions multi-byte safe (by Wei He)
-* Added Bytes_recieived/Bytes_sent statistics (by Sasha Pachev)
-* Added optimization of read_next() with MyISAM
-* Changed MyISAM to use concurrent inserts.
-
-1999-11-21 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Inverted flag 'delayed_key_write' on 'show variables'
-
-1999-11-20 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added variable max_write_lock_count
-
-1999-11-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of 3.23.6
-* Made floor() overflow safe on FREEBSD.
-* Allow quoting of identifers with `
-* Temporary tables now start with #sql
-* Added option --quote-names to mysqldump.
-* Added option --ansi to change " to a identifier delimiter and || to
- string concatenation.
-* Fixed INTO DUMPFILE to give better error messages. NULL is now written
- as an empty string.
-* Changed Field_double and double->string to use snprintf() to avoid overflows.
-* Fixed bug that one could make a part of a PRIMARY KEY not null.
-* Fixed encrypt() to be thread safe and not reuse buffer.
-
-1999-11-11 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed that FLOAT(X) where X <= 24 -> FLOAT and X <= 53 -> DOUBLE.
-* Changed DECIMAL(X) to be DECIMAL(X,0) and DECIMAL to be DECIMAL(10,0)
-
-1999-11-09 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added mysqld option -O lower_case_table_names=[0|1] to force table
- names to lower case.
-* Added mysql_odbc_escape_string() function to support big5 characters in
- MyOBC.
-
-1999-11-08 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added patch by Sasha for user defined variables.
-* Changed that FLOAT and DOUBLE (without any length modifiers) are
- not anymore fixed decimal point numbers.
-
-1999-10-22 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Added option ROW_FORMAT=[default, dynamic, static, compressed] to
- CREATE_TABLE
-
-1999-10-20 Michael Widenius <monty@monty.pp.sci.fi>
-
-* 'DELETE FROM table_name' didn't work on temporary tables
-
-1999-10-18 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of MySQL 3.23.5
-* Fixed problem with LIKE "%const"
-
-1999-10-17 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added bit function ~ (neg)
-
-1999-10-14 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added support for the GBK Chinese character set (by Wei He)
-
-1999-10-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Storage of date results is now much faster to date and datetime columns.
-
-1999-10-12 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed bug when using DISTINCT + ORDER BY RAND()
-* new option --relative to mysqladmin.
-
-1999-10-11 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added some error messages in mysqld.cc
-* Allow use of NATIONAL and NCHAR when defining character columns.
- (They don't do anything)
-* Don't allow NULL columns in PRIMARY KEY:s (only in UNIQUE keys)
-
-1999-10-10 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Clear LAST_INSERT_ID if in uses this in ODBC context:
- WHERE auto_increment_column IS NULL;
-* 'SET SQL_AUTO_IS_NULL=0|1' now turns off/on the above handling of
- auto_increment columns
-
-1999-10-09 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added parameter 'concurrency' for Solaris.
-
-1999-10-07 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem when using an auto_increment column in two keys
-
-1999-10-06 Michael Widenius <monty@monty.pp.sci.fi>
-
-* AS on fieldname with CREATE TABLE table_name SELECT ... didn't work.
-
-1999-10-01 Michael Widenius <monty@tik.pp.sci.fi>
-
-* LIKE with many % ("%xxx%yy%zz%") are now much faster.
-
-1999-09-24 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fix privilege check for LOAD DATA REPLACE .
-
-1999-09-22 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added SHOW GRANT FOR user (by Sinisa)
-* Added date + INTERVALL # date_interval_type
-
-1999-09-19 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with index optimzation with 'WHERE index is not null'
-
-* Allow creation of temporary tables with same name as original table.
-* When granting user a grant option for a database, he couldn't grant
- privileges to other users.
-
-1999-09-17 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Inserting a DATETIME into a TIME column will not anymore try to store 'days'
- in it.
-* Fixed problem with storage of float/double on low endian machines.
-
-1999-09-08 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of 3.23.3
-* Added limit to UPDATE
-* Added client library function: mysql_change_user()
-
-1999-09-07 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added character set to 'show variables'
-* Added support of '--[white-space]' as comment
-* Allow 'INSERT into table_name VALUES ();'
-
-1999-09-03 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Add mysqld option --delay-key-write to mysqld.cc
-
-1999-08-30 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with COUNT(DISTINCT) and GROUP BY
-
-1999-08-29 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added /*!version */
-* Fixed core dump with empty blob to reverse()
-* Fixed problem with year(now()) and year(curdate()).
-
-1999-08-28 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added construct:
-
- CASE value WHEN [compare-value] THEN result
- [WHEN [compare-value] THEN result ...]
- [ELSE result]
- END
-
- CASE WHEN [condition] THEN result
- [WHEN [condition] THEN result ...]
- [ELSE result]
- END
-1999-08-19 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Added check of arguments to acos() and asin().
-* unique_column IS NULL only returned the first row with NULL.
-
-1999-08-12 Michael Widenius <monty@tik.pp.sci.fi>
-
-* REGEXP(...,NULL) will not return an error anymore.
-
-* Removed ifdef mSQL_COMPLIANT when comparing NULL to NULL
-
-1999-08-05 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fix problem with LOCK TABLES and DELETE FROM table.
-
-1999-08-04 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Don't pack all keys even if one key is packed when not using PACK_KEYS=1.
-
-1999-08-03 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed core-dump bug when inserting table or column grant on user name ""
-
-1999-08-02 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fix problem with LOCK TABLES when no database is selected.
-* New functions: MD5(), (by Tõnu Samuel) and EXPORT_SET (by Sasha Pachev)
-* Changed Socket to my_socket (to avoid conflicts)
-
-1999-07-29 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with DISTINCT on BLOB column
-* new keywords: CASE, THEN, WHEN, ELSE, END
-* The CASE operator (by Tõnu Samuel) (not yet working)
-* set SQL_LOW_PRIORITY_UPDATES=# didn't work
-* Fixed range optimizer bug in
- SELECT * FROM table_name WHERE key_part1 >= const AND (key_part2 = const OR key_part2 = const)
-
-1999-07-26 Michael Widenius <monty@tik.pp.sci.fi>
-
-* One can now update indexes columns that are used in the WHERE clause.
- UPDATE tbl_name SET KEY=KEY+1 WHERE KEY > 100;
-
-1999-07-25 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Added get_date() function to all item and fields. This makes date handling
- a lot faster!
-* Added handling of fuzzy dates (dates where day or month is 0)
-
-1999-07-21 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Fixed optimization of SELECT ... WHERE key_part1=const1 and key_part_2=const2 and key_part1=const4 and key_part2=const4
- (indextype should be range instead of ref)
-
-1999-07-20 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Changed handling of 'const_item' to allow handling of
- ORDER BY RAND().
-* MyISAM tables now allows keys on NULL and BLOB columns.
-* Optimize the following LEFT JOIN:
- SELECT ... FROM t1 LEFT JOIN t2 ON ... WHERE t2.not_null_column IS NULL
-
-1999-07-19 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Added ORDER BY and GROUP BY with functions
-* Changed all handling of tables in sql_select.cc to use table_map instead
- of table_nr.
-* Added use of column_name = formula to use keys
-* column_name = column_name2 don't anymore have to have identical packing
-* field IS NULL can now use keys
-
-1999-07-16 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Changed heap tables to be stored in low_byte_first order (to make it easy
- to convert to MyISAM tables)
-* Automatic change of HEAP temporary tables to MYISAM tables in case of
- 'table is full' errors.
-* Added option --init-file=file_name to mysqld
-
-1999-07-15 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Added COUNT(DISTINCT value,[value,...])
-
-1999-07-14 Michael Widenius <monty@tik.pp.sci.fi>
-
-* changed name of temporary table to include getpid().
-* Added full support for CREATE TEMPORARY
-
-1999-07-04 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added CREATE TABLE options 'CHECKSUM' and 'PACK_KEYS'
-* Added mysqld option --default-table-type
-* Added column 'packed' to 'show index'
-* Added pack_keys and checksum to show table status
-
-1999-07-01 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of 3.23.0
-* Show NULL as the default value for AUTO_INCREMENT columns.
-* Fixed optimizer bug with tables with only one row.
-* Fixed bug when using LOCK TABLES table_name READ; FLUSH TABLES;
-
-1999-06-30 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added use of LIBWRAP (by "Henning P . Schmiedehausen" <hps@tanstaafl.de>)
-
-1999-06-28 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Don't allow AUTO_INCREMENT for other than numerical columns
-* Using AUTO_INCREMENT will now automaticly make the column NOT NULL.
-
-1999-06-22 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Added privilege column to 'show columns'
-
-1999-07-13 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Added SQL_BIG_RESULT (SQL_SMALL_RESULT is now default)
-* Use the MYISAM UNIQUE constraint to solve SELECT DISTINCT faster.
-
-1999-06-06 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed most macros in the libmysql library to functions to avoid many
- versions of shared libraries.
-
-1999-05-16 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Added "Row_type" to SHOW TABLE STATUS.
-
-1999-05-15 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added option IF NOT EXISTS to CREATE TABLE
-* Allow creation of CHAR(0) columns.
-
-1999-05-14 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added more error checking of errors from the table handler.
-
-1999-05-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added the '<=>' operator which will act as '=' but will return TRUE if both
- arguments are NULL.
-
-1999-05-12 Michael Widenius <monty@monty.pp.sci.fi>
-
-* The default base for the log, update-log and pid-file name is now
- 'hostname' with everything after the first '.' removed.
-
-1999-05-11 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Require '%' before format characters in DATE_FORMAT().
-* Add logging of GRANT and SET PASSWORD in the update log.
-
-1999-05-10 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed LIKE compare to behave as =; This means that 'e' LIKE 'é' is now
- true.
-
-1999-05-10 Michael Widenius <monty@tik.pp.sci.fi>
-
-* REPLACE now used direct read to find dupplicate row instead of key read;
- This makes REPLACE a lot faster.
-
-1999-05-05 Michael Widenius <monty@tik.pp.sci.fi>
-
-* New option: CREATE TABLE SELECT ....
-* Added syntax for CREATE TEMPORARY TABLE (not yet implemented)
-
-1999-05-03 Michael Widenius <monty@tik.pp.sci.fi>
-
-@code{DESCRIBE TABLE} returns a lot of information about the tables
-
-1999-05-02 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added comments to tables
-* Added UNIQUE, in CREATE TABLE table_name (col int not null UNIQUE);
-
-1999-04-29 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Use auto_increment value provided by MYISAM
-* Use key_part statistics if available
-
-1999-04-28 Michael Widenius <monty@monty.pp.sci.fi>
-
-* null bits are now stored at start of row instead at the end.
- (Now we only need one bit to mark a row deleted)
-
-* DELAYED is now a reserved words. (because of conflicts from yacc)
-
-1999-04-20 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added patches for DEC_3_2 by "Andrea Suatoni" <and@itaca.it>
-
-1999-04-19 Jani Tolonen <jani@monty.pp.sci.fi>
-
-* Added load_file() function
-
-1999-04-15 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added option --skip-show-databases to mysqld.
-
-1999-04-10 Michael Widenius <monty@monty.pp.sci.fi>
-
-* set start time when connection.
-
-1999-04-03 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with 'DELETE FROM TABLE' when table was locked by another
- thread.
-
-1999-04-03 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Check if rows has changed now also works with BLOB/TEXT.
-* Added the INNER JOIN syntax; This made 'INNER' a reserved word.
-
-1999-04-02 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with 'Host '..' is not allowed to connect to this MySQL
- server' after one had inserted a new MySQL user with a GRANT command.
-
-1999-04-01 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added support for netmasks to the hostname in the MySQL tables.
-
-1999-03-31 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed net.cc to use TCP_NODELAY also on Linux.
-* If one compares a NOT NULL DATE/DATETIME column with IS NULL, this
- is changed to a compare against 0 to satisfy some ODBC applications.
- (By shreeve@uci.edu)
-
-1999-03-30 Michael Widenius <monty@monty.pp.sci.fi>
-
-* NULL IN (...) now returns NULL instead of 0.
- This will ensure that 'null_column NOT IN (...)' doesn't match NULL values.
-* Changed the mysql.db entry to char(60).
-
-1999-03-16 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fix storage of floating point values in TIME columns
-* Changed parsing of TIME strings to be more strict. Now the fractional
- second part is detected (and currently skipped)
- The following formats are supported
- [[[DAYS] [H]H:]MM:]SS[.fraction] and [[[[H]H]H]H]MM]SS[.fraction]
-* Detect (and ignore) second fraction part from DATETIME
-
-1999-03-10 Michael Widenius <monty@monty.pp.sci.fi>
-
-* On Win32 detect --basedir automaticly from path to mysqld.
-* Added option --skip-column-names to mysql.
-* Added some memory checks in sql_string.cc
-
-1999-03-08 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added the ODBC 3.0 EXTRACT(interval FROM datetime) function
-* Added lots of 'out of memory' checks for SELECT statements.
-
-1999-03-05 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed std() for big tables when result should be 0.
-
-1999-03-04 Michael Widenius <monty@monty.pp.sci.fi>
-
-* INSERT DELAYED had some garbage at end in the update log.
-
-1999-03-03 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added a lot of casts in filesort.cc to make it more portable.
-
-1999-02-28 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed default size of key_buffer to 4M
-* Fixed problem with queries that needed temporary tables with blobs.
-
-1999-02-26 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added LOAD DATA [LOW_PRIORITY] INFILE.
-* Added option 'flush-time' to force MySQL-Win32 version to flush
- the tables once in a while.
-* On Linux all process didn't die on shutdown.
-
-1999-02-18 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed a core dump problem when using --log-update and connecting
- without a default database.
-* Added more error check if one get an error writing to the log files.
-
-1999-02-16 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed some configure errors
-* If one used @code{LEFT JOIN} on tables that had circular dependencies this
- caused mysqld to hang forever.
-
-1999-02-05 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of 3.22.16
-* mysqladmin processlist could core dump mysqld if a new user logged in.
-* DELETE FROM table_name WHERE key_column=column_name didn't find any matching
- rows.
-* The default index name is now using the same case as the used column name.
-
-1999-02-03 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added the MODIFY attribute to ALTER TABLE (to be compatible with some other
- SQL databases)
-* Added LIKE to 'show status'
-
-1999-01-31 Michael Widenius <monty@monty.pp.sci.fi>
-
-* DATE_ADD(column,...) didn't work.
-* INSERT DELAYED could deadlock with status 'upgrading lock'
-
-1999-01-30 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Extended item_encrypt() to take longer salt strings than 2 characters.
- (for FreeBSD)
-
-1999-01-26 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of 3.22.15
-* LIKE on binary strings didn't work if one used a multi-byte character set.
-* mysqladmin -w will now wait for the server to come up if it's killed.
-
-Tue Jan 26 00:06:10 1999 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* Fixed problem with ORDER BY whith 'only index' optimzation when there
- where multiple key definitions for an used column.
-* GRANT with password didn't update in memory GRANT table before
- 'mysqladmin flush'
-
-1999-01-20 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Updating BLOB/TEXT through formulas didn't work for short (< 256 char)
- strings.
-* Changed option --extended_insert-insert to --extended-insert in mysqldump
-
-1999-01-19 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Lots of changes to support INSERT DELAYED.
-
-1999-01-17 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed unpacking of DATE and DATETIME; These are now about 5 times faster.
-
-1999-01-16 Michael Widenius <monty@monty.pp.sci.fi>
-
-* DATE_ADD with now() or curdate() reused the same string.
-* Added BENCHMARK(loop-count,expression) function to time expressions.
-
-1999-01-14 Michael Widenius <monty@monty.pp.sci.fi>
-
-* LEFT JOIN USING (col1,col2) gave an error if one used it with tables
- from 2 different databases.
-* LOAD DATA LOCAL INFILE didn't work in the unix version because of a missing
- file in the sql directory
-* Fixed problems with VARCHAR/BLOB on very short rows (< 4 bytes); One
- could get error 127 when deleting rows.
-
-1999-01-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Nicer error messages for table types.
-* Changed default number of connections to 100
-
-1999-01-11 Michael Widenius <monty@monty.pp.sci.fi>
-
-* When one did a GRANT on a new host mysqld could die on the first connect
- from this host.
-* Use as default bigger buffers when using 'load data infile'.
-
-1999-01-06 Michael Widenius <monty@monty.pp.sci.fi>
-
-* All blob pointers have now reserved 8 bytes in the .frm files; This makes
- the .frm files portable to 64 bit architectures.
-
-* DECIMAL(x,y) now works according to ANSI SQL.
-
-1998-12-30 Michael Widenius <monty@monty.pp.sci.fi>
-
-* If one used ORDER BY on column name that was the same name as an alias,
- the ORDER BY was done on the alias.
-
-1998-12-29 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added aggregate UDF functions. Thanks to
- Andreas F. Bobak <bobak@relog.ch> for this !
-
-1998-12-28 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed sql_crypt() a bit to make it a bit more secure; This will make old
- string stored with the old decrypt() function unreadable!
-
-1998-12-27 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Allow empty arguments to mysqld to make it easier to start it
- from shell scripts!
-
-1998-12-23 Michael Widenius <monty@monty.pp.sci.fi>
-
-* last_insert_id() is now updated for INSERT INTO ... SELECT
-* Setting a TIMESTAMP column to NULL didn't record the timestamp
- value in the update log.
-
-1998-12-21 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed lock handler bug when one did:
- INSERT INTO TABLE ... SELECT ... GROUP BY.
-* Added a patch for localtime_r() on Win32 that it will not crash anymore
- if your date is > 2039, but instead it will return a time of all zero.
-* UDF function names are not longer case sensitive.
-* Added escape of '^Z' to \Z as ^Z doesn't work with pipes on Win32
-* Changed optimizer to not use 'range search' in some cases.
-* Changed optimizer to use result form 'check_range' in optimization of
- searching of part keys.
-
-1998-12-16 Michael Widenius <monty@monty.pp.sci.fi>
-
-* SELECT COUNT(*) didn't work on LEFT JOIN queries with only had expressions
- in the ON part and there where no WHERE clause.
-* Added optional support for crypted frm files.
-
-1998-12-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Saving NOW(), CURDATE() or CURTIME() directly in a column didn't work.
-* SELECT COUNT(*) didn't work on LEFT JOIN queries with only had expressions
- in the ON part and no WHERE clause.
-
-1998-12-09 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed a bug in sql_list.h that made ALTER TABLE dump a core in some context.
-
-1998-12-08 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Allow use of negative real numbers without a decimal point.
-* day number is now adjusted to max days in month if the resulting month
- after DATE_ADD/DATE_SUB() doesn't have enough days.
-
-1998-12-07 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fix that GRANT compares columns case insensitive.
-* Add / to TMPDIR if needed.
-
-1998-12-06 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Allow GLOBAL as a table or database name.
-
-Thu Dec 3 10:29:11 1998 Michael Widenius <monty@tik>
-
-* Added option SQL_SMALL_RESULT to SELECT to force use of fast temporary
- tables when one knows that the result set will be small!
-
-1998-11-27 Michael Widenius <monty@monty.pp.sci.fi>
-
-* The hostname in user@hostname can now include '.' and '-' without quotes.
-
-1998-11-26 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem when using DATE_ADD()/DATE_SUB() in a WHERE clause.
-* One can now set the password for a user with the
- GRANT ... user IDENTIFIED BY 'password' syntax.
-* Fixed bug in GRANT checking with SELECT on many tables.
-* Removed some 'no Database selected' errors.
-* Release of 3.22.11
-
-1998-11-21 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed USER() to return user@host
-* New command: FLUSH STATUS ; to reset most status variables.
-* New status variables: aborted_threads and aborted_connects.
-
-1998-11-20 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed bug in ORDER BY on FIELD()
-* New function make_set() (70% by Jani Tolonen)
-
-1998-11-18 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added functions encrypt() and decrypt(). Because of endspace stripping of
- CHAR() and VARCHAR() these should only be used with fixed size strings or
- with BLOB/TEXT columns.
-
-1998-11-17 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Silently remove DEFAULT values from AUTO_INCREMENT columns.
-* Added new variable to mysqld: connection_timeout
-
-1998-11-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Better error message when table doesn't exists.
-
-1998-11-12 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added option SET SQL_WARNINGS=1 to get a warning count also for simple
- inserts.
-* IS NULL on a AUTO_INCREMENT column in a LEFT JOIN didn't work.
-* MySQL now uses SIGTERM instead of SIGQUIT with shutdown to work better
- on FreeBSD.
-* Added option \G (print vertically) to mysql
-* SELECT HIGH_PRIORITY ... killed mysqld.
-
-1998-11-11 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added grant checking to 'show tables'
-* Large changes to get grants integrated with the current privilege system.
-
-1998-11-10 Michael Widenius <monty@monty.pp.sci.fi>
-
-* SELECT .. WHERE t1.id1=t2.id2 could fail if t1.id1 and t1.id2 was keys
- and of radically differently types.
-* Changed get_password to use getpass function. (Patch by Jaromir
- Dolecek <dolecek@ics.muni.cz>)
-
-1998-11-04 Michael Widenius <monty@analytik>
-
-* Release of 3.22.10
-* Changed +, - (sign and minus), *, /, % and ABS() to be BIGINT aware.
-* ALTER TABLE and UPDATE now writes out the values of any duplicated keys.
-
-1998-11-03 Michael Widenius <monty@monty.pp.sci.fi>
-
-* ADABASD like INSERT statement:
- INSERT INTO table_name SET column=value,column=value...
-* The client flag option 'CLIENT_IGNORE_SPACE' didn't work properly.
-* Fixed bug in ALTER TABLE that caused a core dump.
-* Added optimization of SELECT ... FROM table ORDER BY key_part1 LIMIT ...
- This query will now use indexes instead of sorting the table.
-
-Mon Nov 2 20:52:15 1998 Jani Tolonen <jani@bitch.pp.sci.fi>
-
-* Added more variables to SHOW STATUS and changed format of output
-* Added command extended-status to mysqladmin which will show the
- new status
-
-1998-10-30 Michael Widenius <monty@monty.pp.sci.fi>
-
-* columns of type date, date_time and 'set' are now stored a little
- more efficient if they are 0, NULL or ''.
-
-1998-10-26 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Most errors are now printed through sql_write_error() which will add
- date, time and thread id to the .err log.
-
-1998-10-25 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added option MYSQL_INIT_COMMAND to mysql_options() to make a query
- on connect or reconnect.
-* Added option MYSQL_READ_DEFAULT_FILE and MYSQL_READ_DEFAULT_GROUP to
- mysql_option() to read the following parameters from the my.cnf file:
- "port", "socket", "compress", "password", "pipe", "timeout", "user",
- "init-command", "host" and "database"
-
-* Added maybe_null to the UDF structure
-
-1998-10-22 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added IGNORE to INSERT with many rows.
-* Added SQL GRANT commands
-* Release of 3.22.9
-
-1998-10-18 Michael Widenius <monty@monty.pp.sci.fi>
-
-* One can new set the last_insert_id() value in an update with
- LAST_INSERT_ID(expr). This makes it possible to return a value for things
- like:
- UPDATE table SET COUNT=LAST_INSERT_ID(COUNT+1) WHERE primary_key_col=#
-* display key name used by 'range' in the 'key' column in 'show processlist'
-* new SQL command: FLUSH [ TABLES | HOSTS | LOGS | PRIVILEGES ] [, ...]
-* new SQL command: KILL thread_id
-
-Thu Oct 15 18:57:15 1998 Michael Widenius <monty@tik>
-
-* Reuse memory for identical set and enum fields.
-
-1998-10-14 Michael Widenius <monty@analytik>
-
-* Added open file information to mysqladmin debug
-* Fixed conversion problem when using ALTER TABLE from a INT to a short CHAR()
- column.
-* Added 'SELECT HIGH_PRIORITY'; This will get a lock for the SELECT even if
- there is a thread waiting another SELECT to get a WRITE LOCK.
- NOTE: This makes HIGH_PRIORITY a reserved word
-
-1998-10-12 Michael Widenius <monty@analytik>
-
-* Moved wild_compare to string class to be able to use LIKE on BLOB/TEXT columns with \0
-* Added ESCAPE option to LIKE
-
-1998-10-08 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Update for AIX: Added a cast to all bzero() calls and changed to use
- my_gethostbyname_r instead of gethostbyname_r.
-
-1998-10-03 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of 3.22.8
-* Added an extra thread signal loop on shutdown to avoid some error messages
- from the client.
-* MySQL now uses the next available number as extension for the update
- log file.
-
-1998-09-25 Michael Widenius <monty@monty.pp.sci.fi>
-
-* MySQL clients on NT will now by default first try to connect with named pipes
- and after this with TCP/IP.
-
-1998-09-24 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problems with TIME columns and negative strings.
-* Added a new column 'state' to 'mysqladmin proc' that gives some
- information what the thread is doing.
-
-* DATE_ADD() and DATE_SUB() didn't work with group functions.
-
-1998-09-23 Michael Widenius <monty@monty.pp.sci.fi>
-
-* 'mysql' will now also try to reconnect on 'use database' commands.
-
-* Fix problem with ORDER BY and LEFT JOIN and const tables.
-
-1998-09-22 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem with ORDER BY if the first ORDER BY column was a key and
- the rest wasn't.
-
-1998-09-17 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of 3.22.7
-* OPTIMIZE TABLE table_name can now be used to reclaim disk space
- after many deletes. This uses currently ALTER TABLE to re-generate
- the table, but in the future it will use an integrated isamchk
- for more speed.
-
-1998-09-16 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added functions for perfect hashing of symbols. Moved some other things
- to the LEX structure for faster setup.
-* Changed libmysql.dll on Win32 to use TLS to get better multi-threading
-
-1998-09-15 Michael Widenius <monty@monty.pp.sci.fi>
-* Added --where to mysqldump (patch by Jim Faucette).
-* Fixed slow UPDATE/DELETE when using DATETIME or DATE keys.
-
-1998-09-14 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed some optimizations parameters to make better joins.
-* Anyone can now use 'mysqladmin proc' to check ones own
- threads. Only users with the 'Process_priv' privilege can get
- information about all threads.
-* Fixed very unlikely optimizer bug in the range optimizer
- (bug introduced in 3.22.6)
-* Added handling of formats YYMMDD, YYYYMMDD, YYMMDDHHMMSS to
- DATETIME/TIMESTAMP when using numbers. (Before these formats only worked
- with strings).
-
-1998-09-06 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added connect option CLIENT_IGNORE_SPACE to allow one to use
- space after the function name and before '(' (Powerbuilder requires this).
- This will make all function names reserved words.
-* comments that start with /*! are now interpreted as commands. This feature
- allows one to use MySQL extensions like:
- 'SELECT /*! STRAIGHT_JOIN */ * from table1,table1'
- in a portable manor.
-
-1998-09-04 Michael Widenius <monty@analytik>
-
-* Added SET OPTION INSERT_ID=# to force use of specific INSERT_ID. This is
- usable with new --log-long-format option.
-
-1998-08-31 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed problem when INSERTING into TIME fields.
-
-1998-08-29 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added key cache and handler statistic to 'mysqladmin debug'.
-* changed UPDATE and DELETE to not use 'index only' range detection.
- (Fixed slow update_key in the benchmarks)
-* Changed the insert benchmark because it was impossible to use it with
- postgreSQL (to slow).
-
-Thu Aug 27 15:38:23 1998 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* mysqldump will automaticly use LOAD DATA LOCAL INFILE if one uses
- an TCP/IP connection.
-
-1998-08-27 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added support of local files with LOAD DATA LOCAL INFILE ..
-* Save history if one kills mysql with ^C. Save history in MYSQL_HISTFILE.
- Modfied patch by Tommy Larsen <tommy@mix.hive.no>
-
-1998-08-26 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed a possible problem with mysql_refresh().
-
-Tue Aug 18 14:07:53 1998 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* Give an error for queries that mix GROUP columns and fields when there
- is no GROUP BY specification.
-
-1998-08-17 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed sql_yacc.yy to allow field attributes in any order.
-
-1998-08-15 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Increased max_allowed_packed to 1M as default.
-* LOAD DATA INFILE didn't copy single field separators in some case:
- "Hello"Atif"!"
-
-1998-08-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed fatal bug in lpad().
-
-Thu Aug 13 01:00:44 1998 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* REGEXP can now take a expression as the second argument.
-
-1998-08-12 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed LIKE to be faster in some cases with many '%': LIKE '%c%ompiler%'
-
-1998-08-11 Michael Widenius <monty@monty.pp.sci.fi>
-
-* All table lock handing is changed to avoid some very subtitle
- deadlocks when using DROP TABLE, ALTER TABLE, DELETE FROM TABLE and
- mysqladmin flush-tables under heavy usage.
-
-1998-08-10 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Allow one to use the syntax 'CONSTRAINT symbol' before FOREIGN KEY.
-* new mysqld option '--low-priority-insert' to give inserts lower priority
- than selects.
-* One can now use {INSERT | REPLACE} LOW_PRIORITY INTO ...
- One side effect is that LOW_PRIORITY is now a reserved word :(
-* Changed locking code to get better handling of locks of different types.
-
-1998-08-09 Michael Widenius <monty@monty.pp.sci.fi>
-
-* mysqld will now ignore trailing ';' characters in queries. This is to
- make it easier to emigrate from some other SQL servers that require the
- end ';'
-* One can now use a LIMIT value with DELETE to make it return after deleting
- a given number of rows.
-* Fix for corrupted output of fixed format and SELECT INTO OUTFILE:
- select * from test into outfile "/tmp/test.txt" fields terminated by '' enclosed by ''
-
-1998-08-04 Michael Widenius <monty@monty.pp.sci.fi>
-
-* new mysqld option: '-O max_connect_errors=#'.
- Connect errors are now reset for each correct connection.
-* Add support for INSERT INTO table ... VALUES(...),(...),(...)
-
-1998-08-03 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added Oracle GREATEST() and LEAST() functions. One must now use
- these instead if the MAX() and MIN() functions to get the biggest/smallest
- value from a list of values. These can now handle real, bigint and
- string values.
-* The following query now uses indexing instead of sorting the table:
- SELECT ... FROM table ORDER BY key_part1 desc,key_part2 desc,...
-* Added check that the error message file has enough error messages.
-* DAYOFWEEK() had offset 0 for Sunday. Changed the offset to 1.
-
-1998-08-02 Michael Widenius <monty@monty.pp.sci.fi>
-
-* new option to mysql: '--vertical' to print results in vertical mode.
-* All count structures in the client (affected_rows, insert_id...) are now of
- type BIGINT to allow one to use 64 bit values.
- This required a minor change in the MySQL protocol which may affect
- old clients when using tables with auto_increment values > 24M.
-* The return type of mysql_fetch_lengths() has changed from uint *
- to ulong *. This may give a warning for old clients but should work
- on most machines.
-
-Thu Jul 30 15:29:05 1998 Michael Widenius <monty@tik>
-
-* COUNT(), STD() and AVG() are extended to handle more than 4G rows.
-
-Wed Jul 29 10:36:05 1998 Michael Widenius <monty@tik>
-
-* Added new option:
- SET OPTION SQL_LOG_UPDATE=[0,1] to allow users with process_priv
- privilege to bypass the update log.
- (Modified patch from Sergey A Mukhin <violet@rosnet.net>)
-
-Thu Jul 23 15:58:13 1998 Michael Widenius <monty@tik>
-
-* Initialize line buffer in mysql.cc to make blob readings from pipes safer.
-
-Tue Jul 21 22:04:43 1998 Michael Widenius <monty@tik>
-
-* One can now store -838:59:59 <= x <= 838:59:59 in a TIME column.
-* TIME_TO_SEC() and SEC_TO_TIME() can now handle negative times and hours
- up to 32767.
-
-Mon Jul 20 20:34:33 1998 Michael Widenius <monty@tik>
-
-* Change mysys/dbug to allocate all thread varibles in one struct.
- This makes it easier to make a threaded libmysql.dll
-
-Sun Jul 19 12:54:45 1998 Michael Widenius <monty@tik>
-
-* Changed ALTER TABLE to make it more multi-thread safe.
-* normal INSERT INTO TABLE are now also cached when used with
- LOCK TABLES. (previously only INSERT ... SELECT and LOAD DATA INFILE
- was cached)
-
-Fri Jul 17 20:53:23 1998 Michael Widenius <monty@tik>
-
-* Allow group functions with HAVING:
- SELECT col FROM table GROUP BY col HAVING COUNT(*)>0;
-
-Tue Jul 14 15:11:52 1998 Michael Widenius <monty@tik>
-
-* Use the result from 'gethostname' as the name for pid files
- (instead of uname()).
-
-Sun Jul 12 12:38:45 1998 Michael Widenius <monty@tik>
-
-* Index only optimization; Some queries are now resolved using
- only indexes. Until MySQL 4.0 this works only for number columns.
-
- SELECT key_part1,key_part2 FROM table WHERE key_part1=#
- SELECT COUNT(*) FROM table WHERE key_part1=# and key_part2=#
- SELECT key_part2 FROM table GROUP BY key_part1;
- SELECT * FROM table ORDER BY key_part2;
-
-1998-07-07 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added function DATE_ADD() and DATE_SUB()
-
-1998-07-06 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added function SUBSTRING() with 2 arguments.
-
-1998-07-05 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added optimization to remove const reference tables from ORDER BY and
- GROUP BY.
-* Allow '$' in table and column names.
-
-1998-07-04 Michael Widenius <monty@monty.pp.sci.fi>
-
-* new option --tmpdir for mysqld.
-
-1998-07-03 Michael Widenius <monty@monty.pp.sci.fi>
-
-* MySQL now automaticly changes a query from an ODBC client:
- SELECT ... from table WHERE auto_increment_column IS NULL
- to
- SELECT ... from table WHERE auto_increment_column == LAST_INSERT_ID().
- This allows some ODBC programs (Delphi, Access) to retrieve the newly
- inserted row to fetch the auto_increment id.
-* Drop table now waits for all users to free a table before deleting it
-
-1998-07-02 Michael Widenius <monty@monty.pp.sci.fi>
-
-* New functions: BIN(), HEX() and CONV() for converting between different
- number bases.
-
-1998-07-01 Michael Widenius <monty@monty.pp.sci.fi>
-
-* If one created a table with smaller record length than 5, one couldn't
- delete rows from this table
-* mysqld now automaticly disables system locking on Linux, Win32 and if
- one uses MIT-threads. One can force the use of locking by doing:
- --enable-locking.
-* Added new mysqld option --console, to force a console window (for error
- messages) when using Win32.
-* Removed a useless check in the ISAM delete code; Delete should now be
- a bit faster.
-
-1998-06-28 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of MySQL 3.22.3
-* New flag to mysqld: --one-thread for debugging with linuxthreads (or glibc)
-
-1998-06-27 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added the LEX structure to THD to get a bit more speed.
-* Added DROP TABLE IF EXISTS to not get an error if the table doesn't exists.
-* IF and EXISTS are now reserved words (they would have to be sooner or later)
-
-1998-06-26 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added lots of new options to mysqldump.
-
-Wed Jun 24 23:33:35 1998 Michael Widenius <monty@tik>
-
-* Server error messages are now in mysqld_errror.h
-* Added compression server/client protocol. (By Sinisa).
-
-1998-06-22 Michael Widenius <monty@monty.pp.sci.fi>
-
-* New functions: <<, >>, rpad() and lpad().
-* Fixed a core-dump bug in the range optimizer.
-
-Fri Jun 19 01:51:09 1998 Michael Widenius <monty@tik>
-
-* One can now save default options (like passwords) in a config file (my.cnf).
-
-1998-06-17 Michael Widenius <monty@monty.pp.sci.fi>
-
-* searching on multiple constant keys that matched > 30 % of the rows didn't
- always use the best possible key.
-
-1998-06-16 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Lot's of small changes to get ORDER BY to work when no records are found
- when using fields that are not in GROUP BY (MySQL extension)
-* Added new option --chroot to mysqld to start mysqld in a chroot environment
- (by Nikki Chumakov <nikkic@cityline.ru>)
-
-1998-06-15 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Add option --one-database to mysql to only update one database
- from a update log.
-
-1998-06-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* end space is now ignored when comparing case sensitive strings;
- This should fix some problems with ODBC!
-* mysql_free_result() now automaticly handles a mysql_use_result() set that
- is not completely read.
-
-1998-06-10 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of MySQL 3.22.1
-* Fixed problems with date_format() and wrong dates.
-* enum() and set() columns was compared binary; Changed to be case insensitive.
-
-1998-06-08 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added new API functions: mysql_init() and mysql_options().
- One MUST now call mysql_init() before one calls mysql_real_connect().
- One doesn't have to call mysql_init if one only calls mysql_connect().
-* LEFT JOIN core dumped if the second table is used with a constant
- WHERE/ON expression with uniquely identifies one record.
-
-1998-06-07 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Range optimizer is not used anymore when comparing a string column
- to a number. This will make such compares slower but safer.
-
-Sun Jun 7 04:47:14 1998 Michael Widenius <monty@tik>
-
-* UPDATE now returns a update information about how many rows was
- matched, updated and if one got any 'warnings' when doing the update.
-
-Sat Jun 6 22:58:02 1998 Michael Widenius <monty@tik>
-
-* Fixed wrong result from 'format(-100,2)'.
-
-1998-06-06 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added new C-API function: mysql_ping().
-* Added options AFTER column and FIRST to ALTER TABLE ... ADD columns.
- This makes is possible to add a new column at some specific location
- in an old table.
-* Fixed problem with find_in_set().
-
-1998-05-18 Michael Widenius <monty@analytik>
-
-* Added new API function: mysql_ping().
-
-1998-05-15 Michael Widenius <monty@monty.pp.sci.fi>
-
-* WEEK() now takes an optional argument to allow handling of weeks when the
- first day of the week = Sunday (default or 0) or Monday ( extra argument is
- 1). WEEK() now returns the week number in the range 0-53 for the used
- year.
-
-1998-05-13 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added flag -T32 to mysqld for running all queries under the main thread.
- This makes it possible to debug mysqld under Linux with gdb!
- (This is now called --one-thread)
-
-1998-05-12 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added optimization of 'not_null_column IS NULL' (needed for some Access
- queries)
-* Made all time functions 'more streamlined'.
-
-1998-05-09 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Allow one to use STRAIGHT_JOIN between two tables to force the optimizer
- to join them in a specific order.
-
-Fri May 8 02:35:00 1998 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* Added SET OPTION PASSWORD='new_crypted_password' and
- SET OPTION PASSWORD= 'host' : 'user' : 'new_password'. The last version
- only works for users with write access to the mysql database.
- One can also use: SET OPTION PASSWORD=PASSWORD("new_password");
-
-Tue May 5 14:41:47 1998 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* String functions now return VARCHAR() instead of CHAR() and
- the column type is now VARCHAR() for fields saved as VARCHAR().
- This should make the MyODBC driver better, but may break some old
- MySQL clients that doesn't handle FIELD_TYPE_VARCHAR identical as
- FIELD_TYPE_CHAR.
-
-Mon May 4 00:33:27 1998 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* Added BOOL as a synonym for BIT and DISTINCTROW as a synonym for DISTINCT.
-* CREATE INDEX and DROP INDEX are now implemented trough ALTER TABLE.
- CREATE TABLE is still the recommended (fast) way to create indexes.
-* Added option SET OPTION PASSWORD='new_password'.
- mysqladmin can now be used by not anonymous users to change their
- password.
-
-Sun May 3 18:47:24 1998 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* Added option wait_timeout to mysqld.
-
-Sat Apr 18 14:14:23 1998 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* Added hashing of fieldnames for tables with many fields.
-* The most frequently used string functions are now in assembler (Linux-intel).
-
-Thu Apr 16 16:14:14 1998 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* Added quick checking if ok host.
-* Changed the interface for field->val_str() to better use stack buffers.
-
-Thu Apr 9 20:02:26 1998 Michael Widenius <monty@bitch.pp.sci.fi>
-
-* One can now reference to tables in different databases with:
- table@database or database.table
-* Added cacheing of users & access rights (for faster access rights checking)
-
-1998-04-08 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Save of command line history to file in mysql client.
- by Tommy Larsen <tommy@mix.hive.no>
-
-1998-04-07 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added time column to 'mysqladmin processes' to show how long a query
- has taken or how long a thread has sleeped.
-
-1998-04-06 Michael Widenius <monty@monty.pp.sci.fi>
-
-* 'show variables' now gives the correct path for 'datadir'.
-* Added logging and update_log to "show variables"
-
-1998-03-29 Michael Widenius <monty@analytik>
-
-* Added new type: YEAR. YEAR is stored on 1 byte with range 0, 1901-2155.
-* Added new DATE type that is stored on 3 bytes instead of 4. All new
- tables will created with the new date type if one doesn't use
- --old-protocol.
-* Fixed bug in record caches; One could get 'Error from table handler: #'
- on some OS from some queries.
-
-1998-03-27 Michael Widenius <monty@monty.pp.sci.fi>
-
-* mysql (the command line tool) striped start space from new rows.
-
-1998-03-25 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added user level locks: GET_LOCK(string,timeout), RELEASE_LOCK(string)
-* Fixed bug in range optimizer when using:
- WHERE key_part_1 >= something and key_part_2 <= something_else
-* Changed connect timeout to 3 seconds to make it somewhat harder
- for crackers to kill mysqld trough telnet + TCP/IP.
-
-1998-03-24 Michael Widenius <monty@monty.pp.sci.fi>
-
-* new mysqld option --big-selects:
- Allow big result sets by saving all temporary sets on file.
- (Solves most 'table full' errors)
-
-1998-03-21 Michael Widenius <monty@monty.pp.sci.fi>
-
-* WHERE with string-column-key = constant-string didn't always find all rows
- if the column had many values differing only with characters of the same sort
- value (like e and é).
-* Added opened_tables to 'show status'.
-* Strings keys looked up with 'ref' was not compared case sensitively.
-* Added flag '--big-selects' to avoid 'Table is full' errors.
- Using this will slow down some queries thought.
-* Added umask() to make log_files non-readable for normal users.
-* Fixed some odd cases with queries that uses group functions where
- the WHERE or HAVING didn't match anything.
-* Ignore users with old password (8 byte) on startup if not using
- --old-protocol.
-* Changed name of the sql_memory allocation system and moved this to
- the mysys library.
-
-1998-03-17 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added use of current_date, current_time and current_timestamp functions
- without (). This automaticly made these reservered words :(
-
-Tue Mar 10 12:34:50 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed mysql_real_connect() to include possible db for faster connection
- to a new db.
-* select which matched all key fields returned the values in the same
- case as the matched values instead of the found values.
-* Release of 3.21.26
-* In DATE_FORMAT() PM and AM was swapped for hours 00 and 12.
-
-Mon Mar 9 14:15:00 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added some tests to the table order optimizer to get some cases with
- 'SELECT ... FROM many_tables' much faster.
-* Added a retry loop around accept() to possible fix some problems on some
- Linux machines.
-
-Fri Mar 6 01:18:47 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* from_days(0) now returns "0000-00-00"
-* Enchanted mysql_connect protocol to allow one to specify database
- on connection. This will make MySQL twice as fast to connect to a database
- for new clients.
-
-Thu Mar 5 18:09:45 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Updated record_cache code to be aligned for more speed.
-* New tests to crash-me
-* Extended the default max key size to 256.
-
-Wed Mar 4 00:02:16 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed bug when using BLOB/TEXT in GROUP BY with many tables.
-
-Mon Mar 2 18:58:10 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* A enum field that is not declared NOT NULL has NULL as default value.
- (Before the default value was the first enum option)
-
-Tue Feb 24 20:11:30 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Fixed bug in the join optimizer code when using many part keys
- on the same key: INDEX (Organisation,Surname(35),Initials(35)).
-
-Mon Feb 23 16:15:39 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* One can now kill threads that are waiting for 'disk full'.
-* Fixed some problems with UDF functions.
-* ALTER TABLE + IGNORE now returns right number of affected rows.
-* Fixed a bug when using 8 bytes long (alpha); filesort() didn't work.
- Affects DISTINCT, ORDER BY and GROUP BY on 64 bit processors.
-
-Sat Feb 21 15:36:48 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed typedef string to my_string because of C++ new string class.
-* now one can kill threads that's are waiting on 'disk full'.
-
-Fri Feb 13 23:19:23 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Release of MySQL 3.21.24
-* Fixed problem with LEFT JOIN and constant expressions in the ON part.
-
-Thu Feb 12 02:54:57 1998 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added much more descriptive error messages to mysqladmin if connect failed.
-* Dynamic loadable functions. Based on source from:
- Alexis Mikhailov <root@medinf.chuvashia.su>
-
-Thu Feb 5 15:19:14 1998 <monty@monty.pp.sci.fi>
-
-* One couldn't delete from a table if no one had done a select on the table.
-* Fixed problem with range optimizer which many OR's on key parts inside
- each other.
-
-Tue Feb 3 14:34:32 1998 <monty@monty.pp.sci.fi>
-
-* Changed default umask for new files from 0664 to 0660.
-
-Fri Jan 30 23:58:19 1998 <monty@monty.pp.sci.fi>
-
-* Release of MySQL 3.21.23
-* Changed ALTER TABLE to work with WIN32 (Win32 can't rename open files)
-
-Thu Jan 29 20:37:50 1998 <monty@monty.pp.sci.fi>
-
-* Fixed that the following symbols are not reserved words:
- TIME DATE TIMESTAMP TEXT BIT ENUM NO ACTION CHECK YEAR MONTH DAY HOUR
- MINUTE SECOND STATUS VARIABLES.
-* Changed string handling in sql_yacc.yy and sql_lex.cc to be faster.
-* Setting a TIMSTAMP to NULL in LOAD DATA INFILE... didn't set the current
- time for the TIMESTAMP.
-* Fixed that key conversions are tested in the WHERE clause
-* LOAD DATA INFILE .... REPLACE INTO ... had wrong 'skipped' count
-
-Tue Jan 27 15:24:50 1998 <monty@monty.pp.sci.fi>
-
-* Added switch --skip-thread-prior for systems where mysqld's thread
- scheduling doesn't work properly. At least BSDI 3.1 works better with
- this!
-* Added ODBC functions DAYNAME() and MONTHNAME().
-* Fixed unlikely(?) key optimizer bug when using ORs inside ANDs.
-
-Sat Jan 24 03:35:46 1998 <monty@monty.pp.sci.fi>
-
-* Release of 3.21.22
-* Added support of 'long constant strings' from ANSI SQL:
- select 'first ' 'second'; -> 'first second';
-
-Mon Jan 19 17:59:49 1998 <monty@monty.pp.sci.fi>
-
-* Fixed problem with Russian character set and LIKE.
-* Fixed bug in ORDER BY on string formula with possible NULL values.
-* Added functions DAYOFYEAR(), DAYOFMONTH(), MONTH(), YEAR(), WEEK(),
- QUARTER(), HOUR(), MINUTE(), SECOND() and FIND_IN_SET().
-* Changed weighting, when using many key parts, in join optimizer to avoid
- full joins for a couple of cases.
-
-Sun Jan 18 21:16:06 1998 <monty@monty.pp.sci.fi>
-
-* Removed that NULL = NULL is true. Now one must use IS NULL or IS NOT NULL
- to test if a value is NULL. (This is according to ANSI SQL but may break
- old applications that are ported from mSQL)
- One can get the old behaviour by compiling with -DmSQL_COMPLIANT
-* Fix of count(*) problems when the WHERE clause didn't match any records.
-* Added function DAYOFMONTH()
-
-1998-01-14 Michael Widenius <monty@analytik>
-
-* Fixed mysqladmin.c to display only the used socket or TCP/IP port.
-
-Mon Jan 12 19:32:31 1998 <monty@monty.pp.sci.fi>
-
-* Changed SHOW FIELDS to return NULL as default value for TIMESTAMP
- (This removes the DEFAULT "" entry for timestamps in mysqldump)
-* Release of MySQL 3.21.21
-* Added commands SHOW STATUS and SHOW VARIABLES.
-* Fixed optimizer bug when using
- 'WHERE data_field=date_field2 and date_field2=constant'
-
-Sun Jan 11 05:07:59 1998 <monty@monty.pp.sci.fi>
-
-* Release of MySQL 3.21.20
-* Added long comments to MySQL /* */
-* Changed lex parsing to be a bit faster in some cases.
-
-Sat Jan 10 15:17:44 1998 <monty@monty.pp.sci.fi>
-
-* Fixed bug when using SELECT DISTINCT + NULL values.
-
-Fri Jan 9 16:45:26 1998 <monty@monty.pp.sci.fi>
-
-* Changed maximum table name and column name lengths from 32 to 64.
-* Aliases can now be of 'any' length.
-
-Thu Jan 8 02:28:11 1998 <monty@monty.pp.sci.fi>
-
-* Now one gets an error if one tries to create an INDEX or UNIQUE
- on a column that allows NULL values. (Before the column was silently
- made NOT NULL).
-
-Wed Jan 7 23:19:11 1998 <monty@monty.pp.sci.fi>
-
-* Changed protocol (downward compatible) to mark if a column
- is auto_increment or a timestamp. This is needed for the
- new java driver.
-* One can now in the clients check if a column is a automatic
- TIMESTAMP or a AUTO_INCREMENT field.
-
-Sun Jan 4 20:10:21 1998 <monty@monty.pp.sci.fi>
-
-* Added update of big5 by jou@pdlc.ieo.nctu.edu.tw
-* Added hebrew sorting order by Zeev Suraski.
-
-Thu Jan 1 12:57:04 1998 <monty@monty.pp.sci.fi>
-
-* Release of 3.21.19
-* unique key fields was not marked as unique keys in mysqlshow.
-* Added function REVERSE() (by Zeev Suraski)
-* Changed ni_range() to fixed a case of slow range searching.
-
-Wed Dec 31 15:46:25 1997 <monty@monty.pp.sci.fi>
-
-* Release of 3.21.18a
-* Fixed problem with new filesort code from 3.21.18 on Linux
-
-Mon Dec 29 10:02:24 1997 <monty@monty.pp.sci.fi>
-
-* Added CROSS JOIN syntax. CROSS is now a reserved word
-* USE database was not always written to output log.
-* mysqladmin command 'status' doesn't increment 'Questions' anymore.
-
-Sun Dec 28 13:20:20 1997 <monty@monty.pp.sci.fi>
-
-* Recoded yacc/bison stack allocation to be even safer and allow MysQL
- to handle even bigger expressions.
-
-Sat Dec 27 15:28:39 1997 <monty@monty.pp.sci.fi>
-
-* last_insert_id and used timestamp is now written to update log file.
- timestamps, calculations with time and LAST_INSERT_ID() will now work
- correctly when updating from the update log.
-
-Fri Dec 26 17:03:14 1997 <monty@monty.pp.sci.fi>
-
-* Give error message if client C functions are called in wrong order.
-* Added automatic reconnect of clients for some cases.
-
-Mon Dec 22 00:25:34 1997 <monty@monty.pp.sci.fi>
-
-* Range optimizer didn't solve ranges of type:
- key_part1= x AND key_part2 > y. This forced some ORDER BY queries to
- do a full table scan when used with where like above.
-* Small sort sets doesn't use temporary files anymore.
-
-Fri Dec 19 16:30:24 1997 <monty@monty.pp.sci.fi>
-
-* Release of MySQL 3.21.17a
-* Fixed problem with compare of binary strings and blobs with ASCII
- characters over 127.
-
-Thu Dec 18 00:33:25 1997 <monty@monty.pp.sci.fi>
-
-* Fixed core dump in first() when chaning some very specific AND and OR
- key columns.
-* Fixed lock problem: When freeing a read lock on a table with multiple
- read locks, a thread waiting for write lock would have given the lock.
- This shouldn't affect data integrity, but could possible make mysqld
- to restart if one thread was reading data that another thread modified.
-* LIMIT offset,count didn't work in INSERT ... SELECT.
-
-Wed Dec 17 12:35:11 1997 <monty@monty.pp.sci.fi>
-
-* optimized key block caching. This will be quicker than the old one when
- using bigger key caches.
-
-Tue Dec 16 23:33:24 1997 <monty@monty.pp.sci.fi>
-
-* Changed bool to my_bool in some item structures to use less memory.
-* Changed optimizer to use array references. This made the code 'nicer'
-
-Mon Dec 15 17:03:43 1997 <monty@monty.pp.sci.fi>
-
-* Release of Mysql 3.21.17
-* mysql: Added ouput of line number on errors when running batch.
-* SELECT column,SUM(expr) now returns NULL for column when there is no
- matching rows.
-
-Sun Dec 14 14:59:46 1997 <monty@monty.pp.sci.fi>
-
-* Fixed create problem with fixed length records of exactly 256 bytes.
- (One couldn't insert more than 1 record in such a table).
-
-Fri Dec 12 18:31:32 1997 <monty@monty.pp.sci.fi>
-
-* Added ODBC and ANSI SQL style LEFT OUTER JOIN.
- The following are new reserved words: LEFT, NATURAL, USING
-* Changed use of table bits and key bits to use typedefs to make it easy
- to extend join tables and keys to 64.
-* The client library is now using the environment variable MYSQL_HOST as
- the default host if it's defined.
-
-Wed Dec 10 01:29:11 1997 <monty@monty.pp.sci.fi>
-
-* Release of 3.21.16a
-* Field type SET with 33-55 elements didn't work.
-* Release of 3.21.16
-* Fixed bug in ALTER TABLE when copying from DATETIME to TIMESTAMP.
- (All TIMESTAMP where set to current time).
-
-Tue Dec 9 14:53:15 1997 <monty@monty.pp.sci.fi>
-
-* Added function TIME_TO_SEC()
-
-Mon Dec 8 09:56:44 1997 <monty@monty.pp.sci.fi>
-
-* Allow empty strings as default values for BLOB and TEXT to be compatible with
- mysqldump.
-* Added ODBC 2.0 & 3.0 functions: POWER(), SPACE(), COT(), DEGREES(), RADIANS(),
- ROUND(2 arg) and TRUNCATE().
-* Added optional (ignored) argument to CURRENT_TIME() and CURRENT_TIMESTAMP().
-* LOCATE() parameters where swapped according to ODBC standard. Fixed.
-* Added detection of all ODBC 3.0 functions to crash-me
-* In some cases default values was not used for NOT NULL fields.
-* Timestamp wasn't updated in UPDATE SET... if the timestamp was used as
- a value or in the WHERE clause.
-
-Sun Nov 30 04:06:31 1997 <monty@monty.pp.sci.fi>
-
-* Renamed version.h to mysql_version.h
-
-Sat Nov 29 10:50:28 1997 <monty@monty.pp.sci.fi>
-
-* Added dayofweek() for ODBC.
-* Allow DATE '1997-01-01', TIME '12:10:10' and TIMESTAMP '1997-01-01 12:10:10'
- formats required by ANSI SQL.
- This has the unfortunate side-effect that one can't have columns named
- DATE, TIME or TIMESTAMP anymore :(
-* Changed net_write() to my_net_write() because of name conflict with sybase.
-* Added --no-auto-rehash option to mysql.
-* Added VARBINARY as synonym for VARCHAR BINARY
-
-Wed Nov 26 12:53:41 1997 <monty@monty.pp.sci.fi>
-
-* Added framework for multiple character sorting
-
-Tue Nov 25 04:03:29 1997 <monty@monty.pp.sci.fi>
-
-* Added extra client flag to mysql_real_connect to be compatible with
- MyODBC.
-* Zeev fixed bug in DATE_FORMAT: It forgot to reset the null marker.
-
-Mon Nov 24 20:19:18 1997 <monty@monty.pp.sci.fi>
-
-* Fixed problem with wrong result order when using all of
- DISTINCT + JOIN + ORDER BY + LIMIT.
-
-Sun Nov 23 14:29:54 1997 <monty@monty.pp.sci.fi>
-
-* mysql: edit command now allows one to edit last query in a editor;
- (patch by Zeev Suraski)
-* Recoded all delete item to avoid use of stack space for deletes.
- (For crash-me)
-* Added command: SET SQL_LOG_OFF=1 to not log commands to standard log.
- This will only affect users with process list privileges.
-
-Sat Nov 22 13:08:55 1997 <monty@monty.pp.sci.fi>
-
-* Added stack checking for crash-me :)
- The following failed before: select 1+1+1+1+1+.... (687 times)
-
-Fri Nov 21 01:50:34 1997 <monty@monty.pp.sci.fi>
-
-* Added new patch for Chinese Big5 code.
-* Change that blobs returns the max length for a blob instead of 8192
- to the client as field_length.
-
-Thu Nov 20 15:37:05 1997 <monty@monty.pp.sci.fi>
-
-* fixed bug in range-optimizer that crashed mysql on some queries.
-* table and column name completion for mysql by
- Zeev Suraski and Andi Gutmans
-* Fixed problem with queries that didn't find any records: This happens only
- when using multiple part keys where the first part is a number and some
- other part is a char or varchar.
-* Removed some wrong warning messages from range optimizer
-
-Wed Nov 19 16:41:14 1997 <monty@monty.pp.sci.fi>
-
-* Added new command REPLACE, which works like INSERT but replaces conflicting
- records with the new record. REPLACE INTO TABLE ... SELECT ... works also.
-* Added new commands: CREATE DATABASE db_name and DROP DATABASE db_name
-* Added RENAME option to ALTER TABLE: ALTER TABLE name RENAME AS new_name
-
-Sun Nov 16 21:41:32 1997 <monty@monty.pp.sci.fi>
-
-* The thread stack was overwritten if one tried to create a table with too many
- fields (more than 1000).
-- Table scanning was a bit slower when using LOCK TABLE xxx WRITE. Fixed.
-
-Thu Nov 13 03:12:54 1997 <monty@monty.pp.sci.fi>
-
-* ALTER TABLE forgot BINARY attribute for strings and BLOBS
-* Change comparision of strings to integer to compare as floats instead
- of as integers.
-* Added printing of Access denied errors to log.
-* Fixed some not 100% portable typedefs in mysql_com.h
-* Added Luuk de Boers defines for interval handling.
- This isn't compleat yet.
-
-Wed Nov 12 00:28:58 1997 <monty@monty.pp.sci.fi>
-
-* Added automatic removal of 'ODBC function conversions': {fn now() }
-* Added new function DATE_FORMAT(date_expr,format). The format string is the
- same one that was previously integrated with from_unix_timestamp().
-* Changed from_unix_timestamp() to call function DATE_FORMAT() with format
- element.
-
-Mon Nov 10 18:17:39 1997 <monty@monty.pp.sci.fi>
-
-* Added flag for stupid ODBC applications (like access) that wants found_rows
- instead of affected_rows.
-* Added basic functions for handling av ANSI INTERVAL.
-
-Sat Nov 8 01:20:03 1997 <monty@monty.pp.sci.fi>
-
-* compare with DATE and TIME with NULL didn't work. (IS NULL worked)
-* Added many changes from the Win32 port.
-* new function: DATE_ADD_MM().
-
-Wed Nov 5 13:10:10 1997 Michael Widenius <monty@analytik>
-
-* SORTING on calculated DOUBLE values sorted on integer results instead.
-* SELECT ... WHERE KEY=constant ORDER BY ... didn't use key to retrieve
- records. This was slow because everything was sorted..
-* CHECK isn't a reserved word anymore.
-
-Mon Nov 3 07:55:47 1997 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Allow start of mysqld.cc without a current database.
-* Changed server version to include -debug and -log if compiled with debugging
- and to show that one has a logging enabled.
-
-Sat Nov 1 13:08:00 1997 <monty@monty.pp.sci.fi>
-
-* Added missing expression 'NOT IN'
-* Changed the place where HAVING should be. According to ANSI it should be
- after GROUP BY but before ORDER BY. MySQL 3.20 had it wrongly last.
-* Added Sybase command: USE DATABASE to start using another database.
-* Fixed core dump when one had a wrong password in the password column.
-* Added automatic adjusting of number of connections and table cache size
- if the maximum number of files that can be opened are less than needed.
- This should fix that mysqld doesn't crash even if one hasn't done a
- ulimit -n 256 before starting mysqld.
-* Added limit checks for create table.
-* Added more checks of different errors from net_read for SCO port.
-
-Tue Oct 28 14:30:31 1997 <monty@monty.pp.sci.fi>
-
-* Fixed problem when using big table_caches; MySQL could previously only
- open 256 files.
-
-Mon Oct 27 10:02:19 1997 <monty@monty.pp.sci.fi>
-
-* Added options LINE STARTING WITH to LOAD DATA INFILE and
- SELECT ... into outfile. Now one can do:
-
- LOAD DATA INFILE '/tmp/syslog.sql' INTO TABLE uptime
- FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED by "'"
- LINES STARTING WITH 'VALUES (' LINES TERMINATED by ');\n' ignore 100 lines
-
-and
- SELECT * from uptime into outfile '/tmp/syslog2.sql'
- FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED by "'"
- LINES STARTING WITH 'INSERT INTO uptime VALUES (' LINES TERMINATED by ');\n'
-
-* Added IGNORE # LINES to LOAD DATA INFILE.
-
-* Allow \N as a shorthand of NULL in SQL statements.
-
-Sun Oct 26 11:34:38 1997 <monty@monty.pp.sci.fi>
-
-* More memory checking.
-* Fixed grouping of functions with many from tables.
-
-Sat Oct 25 01:46:27 1997 <monty@monty.pp.sci.fi>
-
-* New error message so one can check if the connection was lost while
- the command was running or if the connection was down from the start.
-* The mysql command tool now does a automatic reconnect if the connection
- was lost when it does a query.
-* new command: 'mysqladmin debug'. This forces the server to dump out some
- useful information to stdout. Currently it prints all lock information.
-* Rewrite lexer to be faster and more easy to extend.
-
-Fri Oct 24 13:57:06 1997 <monty@monty.pp.sci.fi>
-
-* Fixed bug when like on number key.
-* Added --table option to mysql to print in table format.
- Moved time and row information after query result.
-* Added != as an alias for <>.
-
-Thu Oct 23 16:00:22 1997 <monty@monty.pp.sci.fi>
-
-* Added function VERSION() to make easier logs.
-
-Tue Oct 21 00:09:13 1997 <monty@monty.pp.sci.fi>
-
-* Relase of 3.21.12
-* Added memory checks to all string functions to return NULL if some
- string gets bigger than max_allowed_packet. This is to make MySQL more
- secure.
-* Fixed core dump bug on range optimizer.
-* In some cases doing a join + group + INTO OUTFILE, the result wasn't
- grouped.
-* Now SQL_BIG_TABLES + DISTINCT is also optimized.
-* Changed the syntax of ALTER TABLE ... ALTER COLUMN ident SET DEFAULT ...
- (The DEFAULT keyword wasn't allowed or required before).
-* Added russian error messages.
-
-Mon Oct 20 04:10:53 1997 <monty@monty.pp.sci.fi>
-
-* LIKE with '_' as last character didn't work. Fixed
-* Added many error checks for 'end of memory'
-* Added ENCRYPT() function by Zeev Suraski.
-* Fixed better FOREIGN KEY syntax skipping.
- New reserved words: MATCH, FULL, PARTIAL
-
-Sun Oct 19 23:13:50 1997 <monty@monty.pp.sci.fi>
-
-* Force .log to logfile-name if one uses hostname as logfile.
-* mysqld now allows ip and hostname to the --bind-address option.
-
-Sat Oct 18 22:02:36 1997 <monty@monty.pp.sci.fi>
-
-* Added "SET OPTION CHARACTER SET cp1251_koi8" to enable conversions off
- data to/from different character sets. Currently cp1251_koi8 is the only
- one, but it's now trivial to add others.
- Conversions: strings in the query -> intern set
- fields and items in result -> terminal set
- One can get back to the old one with:
- SET OPTION CHARACTER SET DEFAULT
-* Lots of changes for Win95 port
-
-Fri Oct 17 15:29:44 1997 <monty@monty.pp.sci.fi>
-
-* Changed the create column syntax off NOT NULL to be after the DEFAULT value
- as specified in the ANSI SQL standard. This will make mysqldump with
- NOT NULL and default values incompatible with MySQL 3.20.
-* New reserved words are: BOTH, FOR, LEADING and TRAILING
-* Added a lot of function name alias so one can use the functions with
- ODBC or ANSI SQL92 syntax.
-* Fixed ALTER TABLE person ALTER COLUMN phone SET DEFAULT NULL syntax.
-* Added CHAR and BIT as a synonyms for CHAR(1)
-* Changed the name if the INTERVAL type to ENUM, because INTERVAL is used in
- ANSI SQL.
-* Added extended ANSI SQL TRIM() function.
-* Added CURTIME().
-
-Thu Oct 16 17:26:48 1997 <monty@monty.pp.sci.fi>
-
-* Fixed core dump when updating as user with only select privilige.
-
-Wed Oct 15 04:25:47 1997 <monty@monty.pp.sci.fi>
-
-* INSERT ... SELECT ... GROUP BY didn't work in some cases. On got
- 'Invalid use of group function'
-* When using LIMIT, SELECT now always uses keys instead of record scan.
- This will give better performance on SELECT and a WHERE that matches many
- rows.
-* Added function last_insert_id() to retreive last auto_increment value.
- This is for clients to ODBC that can't use the mysql_insert_id API function.
-* Added option '--flush-logs' to mysqladmin.
-* Added command 'status' to mysql.
-* Moved some messages from libmysql.c to errmsg.c
-
-Mon Oct 13 18:38:01 1997 <monty@monty.pp.sci.fi>
-
-* Tested on BSDI 3.0 with the newest pthread library.
-* Added new group functions: BIT_OR() and BIT_AND().
-* Added compatibility functions: CHECK, REFERENCES.
-* Added BIT as a synonym for CHAR(1) to get better compatibility.
-* Added option ALL to GRANT for better compatibility. (GRANT is still
- a dummy fuction.
-* CHECK is now a reserved word.
-
-Fri Oct 10 17:01:25 1997 <monty@monty.pp.sci.fi>
-
-* Added partly translated dutch messages.
-* Fixed bug in ORDER BY and GROUP BY with NULL columns
-
-Thu Oct 9 10:26:47 1997 <monty@monty.pp.sci.fi>
-
-* Added test of create of table without columns.
-* Release of 3.21.10
-* Fixed a couple of bugs in the range optimizer. Now test-select works.
-
-Tue Sep 30 02:40:42 1997 <monty@monty.pp.sci.fi>
-
-* Added new function: REPEAT(string,count).
-* Added patch of support of Chinese(BIG5).
-* Fixed awful slowdown of libmysql.c when configuring using '--with-debug=yes'
- This affected all clients that got large results from the server.
- (This didn't affect using --quick or mysql_use_result).
-
-Sun Sep 28 20:59:41 1997 <monty@monty.pp.sci.fi>
-
-* Made a new function: mysql_real_connect, that takes two extra arguments:
- port and socket to use on connection.
-* Added text types: TINYTEXT, TEXT, MIDDLETEXT and LONGTEXT.
- These are actually blobs, but all searching is done text independent.
- All old BLOB fields are now TEXT fields.
-* LONG VARCHAR is a synonym for TEXT. LONG BINARY is a synonym for BLOB.
-* 'LONG' is now a reserved word.
-
-Fri Sep 26 16:11:34 1997 <monty@monty.pp.sci.fi>
-
-* Release of 3.21.9
-* Fixed a couple of portable problems with include files.
-* Fixed bug in range calculation that could return empty
- set when searching on multiple key with only one entry (very rare).
-
-Wed Sep 24 15:51:37 1997 <monty@monty.pp.sci.fi>
-
-* Changed thread scope from PROCESS to SYSTEM. This should give better
- scheduling (performance) on Solaris.
-* Fixed duplicated free bug in sql_base with io_cache.
-
-Tue Sep 23 13:05:23 1997 <monty@monty.pp.sci.fi>
-
-* Allow also the old SELECT ... INTO OUTFILE syntax.
-* Fixed bug with group by and select on key with many values.
-
-Mon Sep 22 14:54:00 1997 <monty@monty.pp.sci.fi>
-
-* mysql_fetch_lengths() returned sometimes wrong lengths when one used
- mysql_use_result(). This affected at least some cases of mysqldump --quick.
-
-Sun Sep 21 20:50:07 1997 <monty@monty.pp.sci.fi>
-
-* Fixed memory leak bug in range optimizer.
-
-Sat Sep 20 00:03:51 1997 <monty@monty.pp.sci.fi>
-
-* Allow TIME, DATE and TIMESTAMP as column names.
-* Fixed bug in optimization of WHERE const op field.
-
-Fri Sep 19 12:06:37 1997 <monty@monty.pp.sci.fi>
-
-* Fixed problem when sorting on NULL fields.
-* Added handling of calculation of sum() functions.
-* Added handling of trigometric functions: PI(), ACOS(), ASIN(), ATAN(),
- COS(), SIN() and TAN().
-* Fixed sorting of big tables for 64 bit integers (Alpha).
-
-Fri Aug 29 13:06:32 1997 Michael Widenius <monty@analytik>
-
-* Added option --pid-file=# to mysqld
-* Added date formating to from_unixtime(), originally by Zeev Suraski.
-
-Wed Aug 27 01:35:18 1997 <monty@monty.pp.sci.fi>
-
-* Fixed bug when using 'unsigned long' on Alpa.
-
-Tue Aug 26 03:23:28 1997 <monty@monty.pp.sci.fi>
-
-* Added option --bind-address to mysqld.
-* Changed 'Access denied' to return username and password usage.
-* Changed 'Access to database denied' to return username and database.
-
-Sun Aug 24 22:55:24 1997 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Changed password crypt from 31 bits to 62 bits to make passwords more
- secure.
-* Changed protocol to allow for passing of mysql_errno to client.
-
-Fri Aug 22 18:14:00 1997 <monty@monty.pp.sci.fi>
-
-* Fixed bug in BETWEEN in range optimizer (Did only test = of the first
- argument).
-
-Thu Aug 21 16:40:21 1997 <monty@monty.pp.sci.fi>
-
-* Version 3.21.6
-* Enabled range optimizer for update and delete. Now update and delete can
- use keys again.
-* Fixed bug when using unknown field in group clause.
-
-Tue Aug 19 00:49:13 1997 <monty@monty.pp.sci.fi>
-
-* The range optimizer is now enabled as default. Use msyqld --skip-new
- to disable it.
-* numerous small fixes to the range optimzer and a couple if fixes to
- group and where handling.
-* Added patch from JOERG_HENNE@Non-HP-Germany-om88.om.hp.com to allow
- mit-threads to work on HPUX10. (This patch is regarded alpha)
-
-Fri Aug 15 02:29:21 1997 <monty@monty.pp.sci.fi>
-
-* Remove reverse lookup of hostnames because this takes 2 seconds
- one some machines for every connection!
- This can be enabled with the --secure option to mysqld.
-
-Thu Aug 14 22:40:15 1997 <monty@monty.pp.sci.fi>
-
-* remove HAVING -> WHERE optimization. To fix this one has to change
- all Item_ref fields to Item_fields.
-* Added patch for fast TCP/IP on FreeBSD.
-
-Wed Aug 13 17:14:50 1997 <monty@monty.pp.sci.fi>
-
-* Add optimizing of SELECT DISTINCT .... LIMIT # when there is no
- GROUP or ORDER BY.
-* Changed mysql to only print time information if not silent or if -vvv.
-* Added polish error messages
-
-Sun Aug 10 11:31:10 1997 <monty@monty.pp.sci.fi>
-
-* new function: substring_index(), originally by Zeev Suraski.
-* Added new option to mysqld: -O tmp_table_size=#
-* Removed all use of PTHREAD_MUTEX_INIT and PTHREAD_COND_INIT for
- porting to FreeBSD 3.0 and HPUX.
-
-Thu Aug 7 01:24:50 1997 <monty@monty.pp.sci.fi>
-
-* New function from_unixtime(timestamp) which returns a date string in
- YYYY-MM-DD HH:MM:DD format.
-* New function sec_to_time(seconds) which returns a string in H:MM:SS format.
-
-Sat Aug 2 17:18:22 1997 <monty@monty.pp.sci.fi>
-
-* Fixed some porting issues for OSF1 and for Alpha.
- Now MySQL is know to configure on OSF1 with the Dec compiler,
- after changeing one line in config.h:
- #define SOCKET_SIZE_TYPE int
-
-Wed Jul 30 11:05:39 1997 <monty@monty.pp.sci.fi>
-
-* Added reverse check lookup of hostnames to get better security.
-* Fixed some possible buffer overflows if one uses too long filenames.
-* mysqld doesn't accept hostnames that starts with digits followed by a '.'
- because the hostname may look like a IP.
-* Added option --skip-networking to only allow socket connections.
- (This will not work with MIT threads!)
-
-Tue Jul 29 10:38:55 1997 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Removed wrong free() that killed the server on 'create/drop database'.
-* Changed the name of some mysqld -O options to better names.
-* Added option '-O join_cache_size=#'.
-* Added option '-O max_join_size=#' to be able to set a limit how big queries
- (in this case big = slow) one should be able to handle without specifying
- 'SQL_OPTION OPTION_BIG_SELECTS=1'.
- A # = is about 10 examined records. The default is 'unlimited'.
-* When comparing a TIME, DATE, DATETIME or TIMESTAMP column to a
- constant the constant is converted to a time value before comparing.
- This will make it easier to get ODBC and particularly Access97 to work with
- the above types. It should also make dates easier to use and the compares
- should be quicker than before.
-* added check of too long table names for alias.
-
-Mon Jul 21 16:09:47 1997 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Applied patch from Jochen Wiedmann that fixes that query() in mysqlperl now
- can take queries with \0 in it.
-
-Sat Jul 19 01:11:38 1997 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Store of timestamp with 2 digit year YYMMDD didn't work.
-* Fix that timestamp isn't automaticly updated if set in a update clause.
-* Now the automatic timestamp field is the FIRST timestamp field.
-
-Thu Jul 3 13:34:26 1997 <monty@monty.pp.sci.fi>
-
-* Added check if database name is okey.
-* Addded check if too long table names.
-* SELECT * INTO OUTFILE, which didn't correctly if the outfile already existed.
-* 'mysql' now shows thread id when starting or doing a reconnect.
-* Changed the default sort buffer size from 2M to 1M.
-
-Mon Jun 30 10:18:39 1997 <monty@monty.pp.sci.fi>
-
-* mysqladmin: One can now do 'mysqladmin kill 5,6,7,8'
-* Fixed 'Packets out of order' message. This error come sometimes when the
- server was out of threads/memory. Now the correct message is retrieved by
- the client.
-* Added more checks with thread create for 'out of memory' errors.
-* Added more checks if threads is killed to get faster kill.
-* Changed the default record cache from 512K to 128K to get less problem on
- systems with little memory.
-
-Sat Jun 28 00:18:02 1997 <monty@monty.pp.sci.fi>
-
-* When the max connection limit is reached, one extra connection by a user with
- the PROCESS_ACL privilege is granted.
-
-Fri Jun 27 22:03:24 1997 <monty@monty.pp.sci.fi>
-
-* Added new mysqld option: -O backlog=#
-
-Tue Jun 24 22:08:58 1997 <monty@monty.pp.sci.fi>
-
-* Fixed SELECT DISTINCT when using 'hidden group'. For example:
- SELECT DISTINCT MOD(some_field,10) FROM test GROUP BY some_field;
-* Increased max packet size from 512K to 1024K for client.
-* Removed a lot of unused functions
-
-Mon Jun 23 22:58:07 1997 <monty@monty.pp.sci.fi>
-
-* Changed key_parts to have own field for shortened keys. This gives much
- nicer code in select.
-
-Thu Jun 19 13:09:14 1997 <monty@monty.pp.sci.fi>
-
-* ALTER TABLE now returns warnings from field conversions.
- Changed all numerical fields to check for correct number and
- increment warning counts if the value is wrong.
-
-Wed Jun 18 22:14:36 1997 <monty@monty.pp.sci.fi>
-
-* Fixed buffer overflow when retrieving big packets.
-
-Tue Jun 17 03:26:27 1997 <monty@monty.pp.sci.fi>
-
-* Port changed to 3306 (got it reserved from ISI).
-
-Mon Jun 16 15:46:42 1997 <monty@monty.pp.sci.fi>
-
-* All double are now rounded before storad as integer values.
-* Fixed bug when using: SELECT WHERE A=const1 OR A=const2 OR A=const3,
- and const1 = const3. In this case a key over A=const1 was wrongly used and
- A=const2 wasn't used.
-* Added a fix for Visual Fox Base so that any schema name from a table
- specification is automaticly removed.
-
-Sun Jun 15 12:47:23 1997 <monty@monty.pp.sci.fi>
-
-* The thr_alarm array is now initialized based on number of connections
-* Changed some memcpy() to bmove() to get rid of some warnings from purify.
-* Changed the sql_yacc.c to drop schema name from table name. This is a crude
- patch to get VFP
-
-Sat Jun 14 12:04:59 1997 <monty@monty.pp.sci.fi>
-
-* fixed missed ptr variable in filesort.
-* Fixed wrong tablename and record count EXPLAIN.
-* Changed the 'key use' test to prefere keys even more over full join.
-* Fixed LIKE to work for binary strings.
-
-Fri Jun 13 13:38:14 1997 <monty@monty.pp.sci.fi>
-
-* New function char(num,....).
-
-Wed Jun 11 14:53:17 1997 <monty@monty.pp.sci.fi>
-
-* All field types tested with extrema values. date_time and timestamp
- now require at least year, month and day on insert.
-
-Mon Jun 9 01:23:36 1997 <monty@monty.pp.sci.fi>
-
-* Added French error messages (by Therrien, Gilbert). English is still default.
-* Added option '--skip-name-resolve' to get mysqld to use only IP's to
- autenticate a host. 'localhost' will still be used for local UNIX sockets.
-* Removed the between() function. On should use the 'col BETWEEN a AND b'
- syntax instead.
-
-Sun Jun 8 11:05:46 1997 <monty@monty.pp.sci.fi>
-
-* New function ASCII.
-
-Sat May 31 01:00:18 1997 <monty@monty.pp.sci.fi>
-
-* host names are now compared case insensitive.
-
-Wed May 28 13:04:00 1997 <monty@monty.pp.sci.fi>
-
-* HAVING is added to WHERE if there is no grouping.
-* MySQL now doesn't anymore have to use a extra temporary table when sorting
- on functions or SUM functions.
-
-Tue May 27 00:54:51 1997 <monty@monty.pp.sci.fi>
-
-* Added function to print a item for debugging purposes.
-* Fixed bug that one couldn't use 'table_name.field_name' in UPDATE.
-* Removed init code with reset some of the mysqld -O variables to default after
- they where set by start options.
-
-Thu May 22 14:52:26 1997 <monty@monty.pp.sci.fi>
-
-* Added varbinary syntax: 0x###### which can be used as a string (default) or a
- number.
-
-Sun May 18 22:00:58 1997 <monty@bitch.sci.fi>
-
-* mysqldump: added options to lock tables and specify many tables to dump
-* Add support of NULL fields in filesort
-* SELECT with COUNT(),MIN() .... with no matching rows now returns 1 row.
-
-Sat May 17 22:06:29 1997 <monty@bitch.sci.fi>
-
-* New operator IN. This uses a binary search to find a match.
-* Added 'SET OPTION SQL_BIG_TABLES= (0 | 1). Setting this to 1 will force
- all temporary tables to disk. This will allow one to do big selects that
- ordinary would give a 'table full' error.
-
-Fri May 16 18:53:21 1997 <monty@bitch.sci.fi>
-
-* New command LOCK TABLES table_name [alias] (READ | WRITE), ....
-
-Wed May 14 14:33:07 1997 <monty@bitch.sci.fi>
-
-* Renamed FIELD_TYPE_CHAR to FIELD_TYPE_TINY
-
-Mon May 12 09:54:24 1997 <monty@bitch.sci.fi>
-
-* Added command --log-update to get a update log for incremental backups.
-* log file rotation for mysqld.
-* log file for incremental backups
-* new command: DESCRIBE SELECT ....
-* Removed mysql_reload() and added mysql_refresh() instead.
- Left a define to get old source to compile.
-
-Fri May 9 10:41:36 1997 <monty@bitch.sci.fi>
-
-* All functions now regards a binary type as 'sticky'.
-* The time is now only requested once at start of each query.
-* Splitted item_func.cc in two tables to get around that gcc uses too
- much memory compiling it.
-* Changed MIN() and MAX() to return the original type.
-* Fixed bug in acl with anonymous user: Now if one gets accepted by the user
- table as a empty user name, the user name is set to '' when checking against
- the 'db' and 'host' tables.
-* calculate all const expressions in the first optimizer pass.
-
-Tue May 6 19:16:56 1997 <monty@bitch.sci.fi>
-
-* Fixed ORDER BY bug when selecting on very small tables that made the
- optimizer use a full join.
-
-Mon May 5 00:15:52 1997 <monty@bitch.sci.fi>
-
-* Added use of table alias in insert, delete and update.
-* Removed FIELD_TYPE_TINY_BLOB, FIELD_TYPE_MEDIUM_BLOB, FIELD_TYPE_LONG_BLOB,
- FIELD_TYPE_VAR_STRING from client code.
-* Change syntax of SELECT .. WHERE ... INTO OUTFILE .. to the more standard
- SELECT .. INTO OUTFILE 'name' WHERE ...
-
-Thu May 1 23:16:14 1997 <monty@bitch.sci.fi>
-
-* Added new API functions:
- mysql_row_seek(),mysql_row_tell() and mysql_field_tell().
- mysql_field_seek() now returns old offset.
-* Added expr BETWEEN expr2 AND expr3.
-
-Sun Apr 27 16:16:17 1997 <monty@bitch.sci.fi>
-
-* Changed range() detection to get queries on prefix to works faster.
- Now SELECT name FROM table WHERE name="prefix" is quick even if there
- are lots of rows where name starts with prefix.
-* Fixed crash with shutdown and --log-isam
-* Added group function STD() (standard derivation).
-* mysql.cc: Fixed that NULL columns are always at least 4 wide for nicer output
- of NULL values.
-* Fixed that calculations that are not in GROUP BY works as expected.
- (ANSI SQL extension)
- Example: SELECT id,id+1 FROM table GROUP BY id
-
-Thu Apr 24 13:41:01 1997 Michael Widenius TcX DataKonsulter AB <monty@analytik>
-
-* Fixed convert bug which got mysqld to core dump with Aritmetic error on
- Sparc-386
-
-Wed Apr 23 12:11:05 1997 Michael Widenius TcX DataKonsulter AB <monty@analytik>
-
-* Added tty password to mysqlshow.c
-
-Tue Apr 22 15:44:11 1997 Michael Widenius TcX DataKonsulter AB <monty@analytik>
-
-* The test of using MYSQL_PWD was reversed. Now MYSQL_PWD is enabled as default
- in the default release
-
-Sun Apr 20 14:36:39 1997 <monty@bitch.sci.fi>
-
-* Now one usually only have to give --basedir to mysqld. All other paths
- are relative in a normal installation.
-* BLOBs contained sometimes garbage when used with a SELECT on more than
- one table and ORDER BY.
-* Added option --unbuffered to mysql. (For new mysqlaccess)
-* 'select *' without tables crashed server.
-* When using overlapping (unnecessary keys) and join over many tables
- the optimizer could get confused and return 0 records.
-* Changed safe_mysqld to allow one to move installed releases.
-
-Sun Apr 13 10:40:50 1997 <monty@bitch.sci.fi>
-
-* Release 3.20.17
-* Added new function unix_timestamp([timestamp_column])
-
-Sat Apr 12 11:27:57 1997 <monty@bitch.sci.fi>
-
-* Fixed memory over run bug when using selects with many brace levels.
-* Change from_days() and weekday() to also take a full timestamp or
- a datetime as argument. Before they only took a number of type YYYYMMDD or
- YYMMDD.
-
-Wed Apr 9 13:22:24 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Changed stack usage to use less memory.
-* All communication packages and row buffers are now alloced on demand.
- The default communication buffers are now smaller than before.
-* count(field) where field could have a NULL value didn't work.
-* IS NULL and IS NOT NULL now work in the WHERE.
-* BLOBs now work in the WHERE.
-* Remove pre-space from numbers when writing decimal() coulmns to file.
-* INSERT INTO ... SELECT .. WHERE could give the error 'Dupplicated field'
-
-Tue Apr 8 16:14:54 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added commands SET OPTION SQL_SELECT_LIMIT=# to provide framework
- for options and to get some ODBC things to work.
-* Fixed bug in SELECT ... two tables ... GROUP BY
-* Fixed bug in INSERT ... SELECT ... GROUP BY
-* Fixed bug in acl: To use FILE_PRIV one also had to have SELECT PRIV
- in the user grant table.
-* Fixed fatal bug in ranged querie with OR when one part of the query didn't
- have any matching records.
-
-Mon Apr 7 16:03:00 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Now connections are allowed even if hostname isn't found.
- In this case all hostname checks are done on IP.
-* When doing insert on timestamps, the timestamp was set to the
- current time even if updated by a value.
-* Fixed LOAD DATA.. that if one has COLUMN TERMINATED BY to be same as
- LINE TERMINATED BY, then LINE TERMINATED BY is set to a empty string.
- This wasn't a bug, but a common mistake when reading columns separated
- with newlines.
-
-Sun Apr 6 22:37:53 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Changed definition of function ELT as it should have been:
- ELT(index,element,element,element....) now returns the index:s
- element in the list. The first element has index 1.
- FIELD(find,string,string,string) searches after the 'find' string
- in the string list and returns a index to the found string.
- The strings are compared case insensitive.
-* Added some tests to safe_mysqld to make it 'safer'
-
-Fri Apr 4 02:17:40 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* When sorting the db grant table, host wasn't sorted.
-
-Wed Apr 2 03:00:14 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed case 'WHERE key_num_column = "string"'
-* LIKE was case sensitive in some places and case insensitive in other.
- Now LIKE is always case insensitive.
-* Fixed bug in select optimizer when using many tables with the same
- column used as key to different tables.
-
-Sun Mar 30 21:22:39 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* mysql.cc; Allow '#' anywhere on the line.
-
-Thu Mar 27 02:42:12 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added new latin2 and Russian KOI8 character tables.
-* Added support for a dummy GRANT command satisfy Powerbuilder.
-
-Wed Mar 26 03:03:07 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Release of 3.20.15
-* Removed possible loop when thread waits for command from client
- and fcntl() fails. Thanks to Mike Bretz for finding this bug
-
-Tue Mar 25 18:03:15 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Changed alarm loop in mysqld.cc because shutdown didn't always
- succeed in Linux.
-* Removed use of termbits from mysql.cc This conflicted with glibc 2.0
-* Fixed syntax error in get_password.c (for BSD). Added flush of line.
-* Added test if 'linux' style gethostbyaddr_r in mysqld.cc
-* Fixed bug when doing a select as superuser without a database.
-* Fixed bug when doing SELECT with group calculation to outfile.
-
-Mon Mar 24 16:03:01 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Release of 3.20.14
-* Added new function SOUNDEX()
-* If one gives '-p' or -password to mysql or mysqladmin without an argument,
- the password will be asked from the tty.
-
-Sun Mar 23 00:19:42 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Sometimes when doing a reconnect on a down connection this succeded
- first on second try. Fixed by removing handling of SIGPIPE in client.
-* When adding a auto_increment key with ALTER_TABLE on got the error:
- 'Can't write, duplicate key'.
-
-Sat Mar 22 22:55:12 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* AVG() gave too small value on some selects with GROUP BY and ORDER BY.
-
-Fri Mar 21 12:27:32 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added new DATETIME type (by Giovanni Maruzzelli <maruzz@matrice.it>)
-* Fixed that define 'DONT_USE_DEFAULT_FIELDS' works
-* Added default password from MYSQL_PWD. (by Elmar Haneke)
-* Changed C++ code to be compatible with Sun Workshop
-
-Thu Mar 20 12:28:06 1997 Michael Widenius TcX DataKonsulter AB <monty@analytik>
-
-* Changed to use a thread to handle alarms instead of signals on Solaris to
- avoid race conditions.
-* Fixed default length of signed numbers. (George Harvey <georgeh@pinacl.co.uk>)
-* Added commando 'kill' to mysqladmin to kill a specific mysql thread.
-
-Wed Mar 19 12:21:33 1997 Michael Widenius TcX DataKonsulter AB <monty@analytik>
-
-* sql_base.cc: Allow anything for CREATE INDEX.
-
-Mon Mar 17 19:54:11 1997 Michael Widenius TcX DataKonsulter AB <monty@analytik>
-
-* Add prezeros when packing numbers to DATE, TIME and TIMESTAMP.
-* Fixed the OR bug for good.
-
-Fri Mar 14 11:46:54 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Release 3.20.13
-* Added changes by bonis@kiss.de to allow WHERE const op field
-* Fixed bug in mysql.c when reading long commands from batch.
-* mysqldump.c
- Changed newlines, return and ASCII 0 to "\n", "\r" and "\0",
- to allow restoring of columns with these.
-
-Thu Mar 13 20:02:53 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed bug in select with and-or levels.
-
-Mon Mar 10 04:04:03 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added support for Slovenian characters.
-* Fixed bug with limit and order by.
-* Allow order and group on items that isn't in the select list.
-
-Sun Mar 9 00:21:36 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added ANSISQL94 DATE and TIME types. Changed TIMESTAMP fields to work better
- when updateing it with a number.
-
-Sat Mar 8 20:19:21 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Allow setting of timestamp values in INSERT.
-* Fixed bug with SELECT ... WHERE ... = NULL.
-* Added changes for glibc 2.0
-
-Fri Mar 7 07:53:01 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed bug in alter table when changeing a not null field to allow NULLs.
-* Added HAVE_READDIR_R as a define which can be removed if one has
- a broken readdir_r implementation (Sparc/Linux).
-
-Thu Mar 6 21:06:02 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added some ANS92 synonyms as field types to CREATE TABLE.
- CREATE TABLE now allows FLOAT(4) and FLOAT(8) to mean FLOAT and DOUBLE.
-
-Wed Mar 5 00:41:29 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Release 3.20.11
-* Added sync of records count in sql_update. This fixed slow updates on first
- connection. (Thanks to Vaclav Bittner for the test)
-* Changed temporary file prefix from UN to MY.
-* When using SELECT .... INTO OUTFILE all temporary tables are ISAM instead of
- HEAP to allow big dumps.
-* Changed date functions to be 'string functions'. This fixed some 'funny'
- side effects when sorting on dates.
-
-Tue Mar 4 23:07:03 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Changed FOREIGN KEY to not create a key. Now it's only for compability.
-* Extended ALTER TABLE according to SQL92.
-* Some minor compability changes.
-* Added --port and --socket to all utility programs and mysqld.
-
-Sat Feb 15 01:27:51 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added Oracle command DESCRIBE (DESC) as a synomym for some SHOW commands:
- DESC table_name <==> SHOW FIELDS FROM table_name
- DESC table_name column <==> SHOW FIELDS FROM table_name LIKE 'column'
- DESC table_name 'column' <==> SHOW FIELDS FROM table_name LIKE 'column'
- mysql.cc thought that tinyblob, mediumblob and longblob was numerical.
- (Was right adjusted)
-
-Thu Feb 13 00:49:29 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* mediumblob didn't work.
-* Fixed safe_mysqld and make_binary_distribution to work better.
-* ALTER TABLE and changeing a BLOB to a CHAR() added some garabage at
- string end.
-
-Wed Feb 12 16:10:49 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* new insert type: INSERT INTO ... SELECT ....;
-
-Tue Feb 11 12:58:36 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed some defines to get mysql to compile on freebsd 2.0 (intel)
-* Removed all _A() from prototype declaration.
-* Removed use of ulong in mysql.h and mysql_com.h
-* Changed mysqldump to dump keynames.
-* SELECT ... INTO OUTFILE 'test' create the file in the base directory
- instead in database directory (if one didn't give a full path)
-* A primary key is now defined as a key with name PRIMARY or the first
- unique key if there doesn't exist a key with name PRIMARY.
-
-Mon Feb 10 00:40:48 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed leak bug when using LOAD DATA into a blob with is sometimes NULL.
-* DROP TABLE can now take a list of tables.
-* If a databas was crashed, in some cases a read of the wrong record
- was used as a 'end of file', instead of returning an error.
-
-Sat Feb 8 00:16:07 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* merged structs field_t and FIELD to FIELD.
-
-Fri Feb 7 12:49:01 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* version 3.20.9
-* Alter table didn't copy null bit. This resulted that NULL fields where
- always NULL.
-* CREATE didn't take numbers as DEFAULT.
-
-Wed Feb 5 13:28:19 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* New scripts 'add_file_priv' which add the new field 'file_priv'
- to the user table. This scripts must be executed if one wants to
- use the new SELECT ... INTO and LOAD DATA INFILE... commands
- with a version of mysql less than 3.20.7.
-* Found bug in locking code when another thread got a table opened
- by another thread. This could make a thread block forever wating
- for a write lock.
-
-Tue Feb 4 00:57:24 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Changed select_test.c and insert_test.c to include config.h
-
-Mon Feb 3 00:42:08 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Add an optional keyname for all key declarators.
-
-Sat Feb 1 19:02:43 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added command 'status' to mysqladmin for short logging.
-* Increased max keys to 16 and max key parts to 15.
-
-Fri Jan 31 00:05:23 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added ANSI92 extended ALTER TABLE statement.
-* Changed all locking code to detect ALTER table after one got a lock.
- Tables are automaticly reopened if ALTERed.
-* Changed some structs to classes to get better code when using CREATE TABLE.
-
-Thu Jan 30 01:12:13 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added new privilege to the user grant table: file_priv
-* Added some compitibility changes to mysql.cc
-* Added new syntax for creating keys with is a sub part of some field.
-* Did a lot of changes to get around bug when comparing fields of
- different lengths. Hope I didn't break something else :)
-* Added long options to mysqldump.
-* Added new function NOW().
-
-Wed Jan 29 15:51:22 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added option -k for mysqlshow to get key info for table.
-* Changed some definitions from int to uint in mysql.h to get fewer warning
- with prolint.
-
-Mon Jan 27 02:01:29 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added sql command 'load data infile...' for export from textfiles.
-* Added new API function mysql->info to pass info to client.
-* Added INTO OUTFILE as option to select to get result to file.
-
-Fri Jan 24 14:56:19 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Relase 3.20.5-beta
-* Got first version to work which MIT-threads.
-* Added long options to mysqld
-* mysqld now starts without system locking if compiled with MIT threads.
-* Added new sql function RAND([init])
-* Changed sql_lex to handle \0 unquoted, but the client can't send
- the query through the C api, because it takes a str pointer.
- one have to use mysql_real_query() to send the query.
-
-Thu Jan 23 00:33:26 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added API function: mysql_get_client_info
-* mysqld now uses the N_MAX_KEY_LENGTH from nisam.h as the max allowed key
- length.
-* The following now works: "select filter_nr,filter_nr from filter order by
- filter_nr"
- Before you got the error: "Column: 'filter_nr' in order clause is ambiguous"
-
-Wed Jan 22 14:48:58 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Changed fctnl flag O_NDELAY to O_NONBLOCK (Posix, and to get MIT threads
- to work)
-
-Tue Jan 21 12:31:17 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* mysql now outputs \0 \t \n and \\ when writing tab separated output.
- when encountering ascii 0, tab, newline or \. This is to allow printing of
- binary data in a portable format.
- To get old behavior use -r (or --raw).
-* Added long options to mysqladmin, mysql and mysqlshow.
-* Added german error messages (60 of 80 error messages translated)
-* Added new api function: mysql_fetch_lengths(MYSQL_RES *) which
- returns a array of of column lengths (of type uint).
-
-Sat Jan 18 23:59:53 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed bug with IS NULL in where clause.
-
-Fri Jan 17 12:14:38 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Changed the optimizer a little to get better results when searching on a key
- part.
-* Added select option STRAIGHT_JOIN to tell the optimizer that it should join
- tables in the given order.
-
-Thu Jan 16 00:55:41 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added support of comment starting with '--' in mysql.cc (Postgres syntax)
-* You can now have select_expressions and table columns in a select which
- are not used in the group part. This makes it efficient to implement lookups.
- If the not used column is not a constant for the group the column value
- is unspecified.
- Example: SELECT id,lookup.text,sum(*) FROM test,lookup
- WHERE test.id=lookup.id group by id;
-
-* Fixed bug in sum(function) (Could make core dump)
-* Changed auto_increment according to SQL_SYNTAX:
- INSERT into table (auto_field) values (0) inserted 0, but the SQL_SYNTAX
- statied it should insert a auto_incremnt value.
-
-Wed Jan 15 10:42:09 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* mysqlshow.c: Added number of records in table. Had to change the client code a
- little to fix this.
-* mysql now allows double '' or "" in strings for embedded ' or ".
-* Changed copyright text in mysqlshow and mysqladmin.
-
-Mon Jan 13 02:33:09 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Relase 3.20.3
-* Using the new readline library from bash.
-* Updated a lot of text files.
-* safe_mysqld and mysql.server changed to be more compatible between the
- source and the binary releases.
-
-Sun Jan 12 18:23:30 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* LIMIT takes now one or two numerical arguments.
- If one argument the argument indicates the maximum number of rows in a result.
- If two arguments the first arguments says the offset to the first row to return,
- the second is the maximum number of rows.
- With this it's easy to do a poor mans next page/previous page www application.
-* Changed name of SQL function FIELDS to ELT.
-* Made SHOW COLUMNS a synonym for SHOW FIELDS.
- Added compatibility syntax FRIEND KEY to create table. This creates in mysql
- a non unique key on the given columns.
-* Added CREATE INDEX and DROP INDEX as compatibility functions. In mysql
- CREATE INDEX only checks if the index exists and gives an error if it doesn't
- exists. DROP INDEX always succeeds.
-
-Sat Jan 11 00:44:29 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* mysqladmin.c: Added client version to version info.
-
-Fri Jan 10 20:30:04 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed core dump bug in sql_acl (core on new connection).
-* Removed host,user and db tables from database test in the distribution.
-* FIELD_TYPE_CHAR can now be signed (-128 - 127) or unsigned (0 - 255)
- Before it was always unsigned.
-
-Thu Jan 9 00:02:03 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Changed name from mysqllib to mysqlclient for mysql client lib.
-* The following failed: concat(1,concat(2),2).
- Could not call a variable argument function in a variable argument count
- function. Fixed.
-
-Wed Jan 8 15:58:49 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* weekday() returned wrong day 6 of 7 times.
-
-Mon Jan 6 23:49:31 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* changed a lot of source to get mysqld to be compiled with SUNPRO compiler.
-* sql functions must now have a '(' directly after the function name.
- user '(' is now regarders as an identifier and a '('
-
-Fri Jan 3 12:18:14 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed possible bug when sorting with float and double.
- Changed static sort_length to thread variable. This may have caused some
- big sorts to fail when running two simultaneous sorts.
-* Changed sql function INTERVALL() to INTERVAL().
-
-Wed Jan 1 16:18:30 1997 Michael Widenius <monty@bitch.sci.fi>
-
-* Added some portability files for testing with RTS threads.
-* Lot of changes for configure.
-
-Sun Dec 29 13:26:52 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* Remove Makefile-linux-pl and Makefile-solaris-pl from the binary distribution.
- Now only Makefile.PL is needed.
-
-Sat Dec 28 22:41:09 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed that insert with a timestamp set to NULL works. (This is for a cleaner
- syntax)
-
-Fri Dec 27 01:28:02 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* mysqld now has english & swedish error messages.
-* unireg files moved to sql directory changed to c++.
-
-Thu Dec 26 11:57:57 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* mysqld: Added option 'b' for mysql basedir. All given directories is
- prefixed with this if not given with hard path.
- added option '-L' (language). Default is 'english/'
- Moved all unireg files to sql directory.
-
-Fri Dec 20 11:05:37 1996 Michael Widenius TcX DataKonsulter AB <monty@ozelot>
-
-* Changed lex to allow a database name, table name and field name to start with
- number or '_'.
-
-* mysqldump should now be able to dump all field types.
- Changed 'show fields from table' to be fully compatible with create.
-* Some bugs when parsing 'create table' fixed. (Blobs and timestamps was effected)
-* Fixed one possible dead lock bug when using many tables.
-* Changed a lot for configure
-
-Sun Dec 15 02:29:53 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* Added new functions: INSERT(),RTRIM(),LTRIM(),FORMAT().
-
-* New relase 3.19.5
-* Added functions DATABASE(),USER(),POW(),LOG10() (needed for ODBC).
-
-Sat Dec 14 10:10:42 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* In a WHERE with a ORDER BY on fields from only one table the table is
- now preferred as first table in a multi-join.
-* HAVING and IS NULL or IS NOT NULL now works.
-* a group on one column and a sort on a group function (SUM,AVG...) didn't
- work together. Fixed.
-
-Fri Dec 13 07:20:47 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* mysqldump: Didn't send password to server.
-
-* New relase 3.19.4
-* Fixed horrible locking bug when inserting in one thread and reading
- on another thread.
-* Fixed one-off decimal bug. 1.00 was outputed as 1.0
-* Added attribute 'Locked' to process list as info if a query is
- locked by another query.
-* Fixed full magic timestamp. Timestamp length may now be 14,12,10,8,6,4 or 2.
-
-Thu Dec 12 18:14:57 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* sort on some number functions could be sorted wrong on last number.
-* if(arg,syntax_error,syntax_error) crashed.
-* added functions ceiling() and round(), exp(), log() and sqrt()
-* enchanted BETWEEN to handle strings.
-
-Wed Dec 11 09:09:02 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* MYODBC: Sometimes password test failed because of faulty charactermap in
- windows.
-
-Mon Dec 9 12:50:56 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* new relase 3.19.3
-* Fixed that select with grouping on blob's doesn't return wrong blob info.
- grouping, sorting and distinct on blobs will not yet work as expected
- (Probably it will group/sort by the first 7 characters in the blob)
- Groping on formulas with a fixed string size (use mid on blob) should work.
-* When doing a full join (no direct keys) on multiple tables with blob fields,
- the blob was garbage on output.
-* Fixed distinct with calculated columns.
-
-Sun Dec 8 19:53:24 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed bug when allocation string for group
-* new release 3.19.2
-* mysqldump.c: Didn't output ' around blobs.
-
-Sat Dec 7 13:00:43 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* Added user flag to mysqldump & mysqlshow.
-* ODBC: Added full support of SQLGetInfo(). Fixed limit bug (from 1.0.3).
- myodbc-1.0.4 released
-
-Fri Dec 6 01:35:22 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* ODBC: Added more support SetStmtOptions(). Added more debugging code
- myodbc-1.0.3 released
-
-Tue Dec 3 22:12:30 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* Added 'max_connections' and 'table_cache' as start variables to mysqld.
-* Changed weights in join optimizer: Now prefers to use keys even more:
- Before the optimizer would prefer to do a full join on small tables
- (< 300 records), even if there was a usable key.
-
-Mon Dec 2 00:17:42 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* new release 3.19.1
-* Fixed bug when joining tables without keys and null fields and varchars.
- (mysqld hang)
-* Fixed output of 'mysql show'. All fields was 'unsigned zerofill'.
-
-* new release 3.19.0
-* Added new column specifier AUTO_INCREMENT.
-* Changed format of sql command 'show fields'.
-* Changed mysqlshow to use sql command 'show fields' to get more info.
-* Added synonym RLIKE for REGEXP to be compatible with mSQL
-
-Sun Dec 1 12:53:05 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* item_func.cc (fix_fields): Fixed new bug when calculation and levels.
- Crashed stack when optimizing where! (fatal bug in 3.18.1)
-
-Fri Nov 29 00:32:09 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* Distribution 3.18.1
-* Fixed optimizeing bug.
-* New ODBC version with traceing in all functions with isn't supported yet
- for easier debugging. Added NO WARRANTY info.
- Released as 1.0.2
-
-Wed Nov 27 17:18:51 1996 Michael Widenius TcX DataKonsulter AB <monty@ozelot>
-
-* Added Henry Spencer's regexp in 'field REGEXP string'. Can only be used
- in select_expression or HAVING until I fix the where clause.
-
-Mon Nov 25 20:01:05 1996 Michael Widenius TcX DataKonsulter AB <monty@ozelot>
-
-* Created files: CREDITS, PUBLIC. Updated FAQ, README, TODO, SQL_SYNTAX...
-* Done a lot of testing on HAVING.
-
-Sun Nov 24 00:45:07 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* mysql didn't stop on error in batch mode even if -f wasn't used.
-* Fixed DBD Makefile.PL for linux
-* Added a function.tst & function.res (test and result file of mysql functions)
-* libmysql.c: Added some checking for calls after connection has gone done.
-* Implemented HAVING with full expr syntax
-* Changed operators '=,
-
-Sat Nov 23 20:52:42 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* SQL_SYNTAX added 'like' as a boolean expression in select.
-* mysqladmin.c: 'mysqladmin garbage' didn't give an error.
-* sql_insert.cc: If one read a deleted record and did a insert with all fields
- then the new record was marked deleted.
-* perl DBI interface ported.
-
-Thu Nov 21 00:58:44 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* mysql only used the TCP connection, no socket was ever created
-* There was a bug in when reading from getenv(MYSQL_TCP_PORT)
-* Added some more start-logging to check for port & socket.
-* If something got wrong at startup some threads was kept alive in Linux
-* If argument -h to mysqld is a relative path, change it to './'
-* Search after the 'unireg' directory from: current dir,
- mysqld program dir/.. and in env(MY_BASEDIR_VERSION)
-* Added longlong support to Linux
-* Added copyright notices to all files. Everything should be ready for
- distribution.
-
-Wed Nov 20 19:03:02 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* Added function IF.
-* Added select without FROM clause (for easy test of functions)
-
-Tue Nov 19 11:48:55 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* mysql.c: Sometimes 'in-string' was not initialized.
-* linux distribution
-
-Mon Nov 18 13:47:09 1996 Michael Widenius <monty@bitch.sci.fi>
-
-* Fixed blob:s to work (as varchar) in ODBC (myodbc-1.0.1.zip)
-* Added option -O to set buffer sizes to mysqld
-
-Wed Nov 13 15:21:14 1996 Michael Widenius <monty@monty.pp.sci.fi>
-
-* New sql functions: REPLACE, LCASE and UCASE
-* hacked search on '%xxx' to work.
-
-Tue Nov 12 00:52:35 1996 Michael Widenius <monty@monty.pp.sci.fi>
-
-* mysql.cc: Fixed problems with strings containing not backslashed ' or ".
-
-Mon Nov 11 14:52:30 1996 Michael Widenius <monty@monty.pp.sci.fi>
-
-* added braces to where clause. Change where to use items.
-
-Wed Nov 6 00:17:37 1996 Michael Widenius <monty@analytikerna.se>
-
-* added PRIMARY KEY, KEY and UNIQUE to sql create.
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 17930242dc4..e2494e50d96 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -21,27 +21,29 @@ MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
INCLUDES = @MT_INCLUDES@ \
- @bdb_includes@ @innodb_includes@ @gemini_includes@ \
+ @bdb_includes@ @innodb_includes@ \
-I$(srcdir)/../include \
-I$(srcdir)/../regex \
- -I$(srcdir) -I../include -I.. -I.
+ -I$(srcdir) -I../include -I. $(openssl_includes)
WRAPLIBS= @WRAPLIBS@
SUBDIRS = share
libexec_PROGRAMS = mysqld
noinst_PROGRAMS = gen_lex_hash
-gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
-LDADD = ../isam/libnisam.a \
- ../merge/libmerge.a \
+gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
+LDADD = @isam_libs@ \
../myisam/libmyisam.a \
../myisammrg/libmyisammrg.a \
../heap/libheap.a \
+ ../vio/libvio.a \
../mysys/libmysys.a \
../dbug/libdbug.a \
../regex/libregex.a \
../strings/libmystrings.a
+
mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
- @bdb_libs@ @innodb_libs@ @gemini_libs@ \
- $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@
+ @bdb_libs@ @innodb_libs@ @pstack_libs@ \
+ @innodb_system_libs@ \
+ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_strfunc.h item_timefunc.h item_uniq.h \
item_create.h mysql_priv.h \
@@ -49,37 +51,37 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
sql_manager.h sql_map.h sql_string.h unireg.h \
field.h handler.h \
ha_isammrg.h ha_isam.h ha_myisammrg.h\
- ha_heap.h ha_myisam.h ha_berkeley.h ha_innobase.h \
- ha_gemini.h opt_range.h opt_ft.h \
+ ha_heap.h ha_myisam.h ha_berkeley.h ha_innodb.h \
+ opt_range.h opt_ft.h \
sql_select.h structs.h table.h sql_udf.h hash_filo.h\
- lex.h lex_symbol.h sql_acl.h sql_crypt.h md5.h \
- log_event.h mini_client.h sql_repl.h slave.h \
- stacktrace.h
-mysqld_SOURCES = sql_lex.cc \
+ lex.h lex_symbol.h sql_acl.h sql_crypt.h \
+ log_event.h mini_client.h sql_repl.h slave.h \
+ stacktrace.h sql_sort.h sql_cache.h set_var.h
+mysqld_SOURCES = sql_lex.cc sql_handler.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
thr_malloc.cc item_create.cc \
field.cc key.cc sql_class.cc sql_list.cc \
- net_serv.cc violite.c net_pkg.cc lock.cc my_lock.c \
+ net_serv.cc net_pkg.cc lock.cc my_lock.c \
sql_string.cc sql_manager.cc sql_map.cc \
mysqld.cc password.c hash_filo.cc hostname.cc \
- convert.cc sql_parse.cc sql_yacc.yy \
+ convert.cc set_var.cc sql_parse.cc sql_yacc.yy \
sql_base.cc table.cc sql_select.cc sql_insert.cc \
- sql_update.cc sql_delete.cc sql_do.cc \
+ sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
procedure.cc item_uniq.cc sql_test.cc \
log.cc log_event.cc init.cc derror.cc sql_acl.cc \
- unireg.cc \
+ unireg.cc des_key_file.cc \
time.cc opt_range.cc opt_sum.cc opt_ft.cc \
records.cc filesort.cc handler.cc \
ha_heap.cc ha_myisam.cc ha_myisammrg.cc \
- ha_berkeley.cc ha_innobase.cc ha_gemini.cc \
+ ha_berkeley.cc ha_innodb.cc \
ha_isam.cc ha_isammrg.cc \
sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \
sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
- slave.cc sql_repl.cc \
+ slave.cc sql_repl.cc sql_union.cc \
mini_client.cc mini_client_errors.c \
- md5.c stacktrace.c
+ stacktrace.c repl_failsafe.h repl_failsafe.cc sql_olap.cc
gen_lex_hash_SOURCES = gen_lex_hash.cc
gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS)
@@ -112,12 +114,17 @@ sql_yacc.o: sql_yacc.cc sql_yacc.h
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
lex_hash.h: lex.h gen_lex_hash.cc sql_yacc.h
- $(MAKE) gen_lex_hash
- ./gen_lex_hash > $@
+ $(MAKE) gen_lex_hash$(EXEEXT)
+ ./gen_lex_hash$(EXEEXT) > $@
# Hack to ensure that lex_hash.h is built early
sql_lex.o: lex_hash.h
+# For testing of udf_example.so; Works on platforms with gcc
+# (This is not part of our build process but only provided as an example)
+udf_example.so: udf_example.cc
+ $(CXXCOMPILE) -shared -o $@ $<
+
#distclean:
# rm -f lex_hash.h
diff --git a/sql/cache_manager.cc b/sql/cache_manager.cc
index 9ea25315f8c..307fe331e5c 100644
--- a/sql/cache_manager.cc
+++ b/sql/cache_manager.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,7 +18,7 @@
#pragma implementation /* gcc: Class implementation */
#endif
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "cache_manager.h"
@@ -117,7 +117,7 @@ void *cache_manager::alloc(uint size)
{
void *llist;
void *abs_ptr;
-
+
size=ALIGN_SIZE(size+HEADER_LENGTH+SUFFIX_LENGTH);
if (!(llist = find_in_llist(size)))
{
@@ -127,7 +127,7 @@ void *cache_manager::alloc(uint size)
}
size_of_found_block=int4korr((char*) llist) & ALLOC_MASK;
// if (size_of_found_block < SMALLEST_BLOCK)
-
+
abs_ptr = link_into_abs(llist);
return abs_ptr;
}
diff --git a/sql/cache_manager.h b/sql/cache_manager.h
index fc3b8f7016a..d422a86ea8e 100644
--- a/sql/cache_manager.h
+++ b/sql/cache_manager.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -59,7 +59,3 @@ class cache_manager {
bool *dealloc(void *); /* Deallocate blocks (with *ptr_arg) */
void clear(void); /* Clear the cache */
};
-
-
-
-
diff --git a/sql/convert.cc b/sql/convert.cc
index 2c8b775dca2..e4ae13d1e07 100644
--- a/sql/convert.cc
+++ b/sql/convert.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -27,7 +27,7 @@
#include "mysql_priv.h"
/****************************************************************************
-** Convert tables
+ Convert tables
****************************************************************************/
/* Windows cp1251->koi8 and reverse conversion by Timur I. Bakeyev <translate@bat.ru> */
@@ -397,19 +397,19 @@ static unsigned char win1251ukr_koi8_ukr[256] = {
****************************************************************************/
-CONVERT conv_cp1251_koi8("cp1251_koi8", cp1251_koi8, koi8_cp1251);
+CONVERT conv_cp1251_koi8("cp1251_koi8", cp1251_koi8, koi8_cp1251, 1);
#ifdef DEFINE_ALL_CHARACTER_SETS
-CONVERT conv_cp1250_latin2("cp1250_latin2", t1250_til2, til2_t1250);
-CONVERT conv_kam_latin2("kam_latin2", tkam_til2, til2_tkam);
-CONVERT conv_mac_latin2("mac_latin2", tmac_til2, til2_tmac);
-CONVERT conv_macce_latin2("macce_latin2", tmacce_til2, til2_tmacce);
-CONVERT conv_pc2_latin2("pc2_latin2", tpc2_til2, til2_tpc2);
-CONVERT conv_vga_latin2("vga_latin2", tvga_til2, til2_tvga);
-CONVERT conv_koi8_cp1251("koi8_cp1251", koi8_cp1251, cp1251_koi8);
+CONVERT conv_cp1250_latin2("cp1250_latin2", t1250_til2, til2_t1250, 2);
+CONVERT conv_kam_latin2("kam_latin2", tkam_til2, til2_tkam, 3);
+CONVERT conv_mac_latin2("mac_latin2", tmac_til2, til2_tmac, 4);
+CONVERT conv_macce_latin2("macce_latin2", tmacce_til2, til2_tmacce, 5);
+CONVERT conv_pc2_latin2("pc2_latin2", tpc2_til2, til2_tpc2, 6);
+CONVERT conv_vga_latin2("vga_latin2", tvga_til2, til2_tvga, 7);
+CONVERT conv_koi8_cp1251("koi8_cp1251", koi8_cp1251, cp1251_koi8, 8);
CONVERT conv_win1251ukr_koi8_ukr("win1251ukr_koi8_ukr", win1251ukr_koi8_ukr,
- koi8_ukr_win1251ukr);
+ koi8_ukr_win1251ukr, 9);
CONVERT conv_koi8_ukr_win1251ukr("koi8_ukr_win1251ukr", koi8_ukr_win1251ukr,
- win1251ukr_koi8_ukr);
+ win1251ukr_koi8_ukr, 10);
#endif /* DEFINE_ALL_CHARACTER_SETS */
CONVERT *convert_tables[]= {
diff --git a/sql/custom_conf.h b/sql/custom_conf.h
index af6012e28ec..19ced12bfbb 100644
--- a/sql/custom_conf.h
+++ b/sql/custom_conf.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/derror.cc b/sql/derror.cc
index 62971fde394..7ebe6e4b3c5 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -44,13 +44,14 @@ static void read_texts(const char *file_name,const char ***point,
uint error_messages)
{
register uint i;
- uint ant,funktpos,length,textant;
+ uint count,funktpos,length,textcount;
File file;
char name[FN_REFLEN];
const char *buff;
uchar head[32],*pos;
DBUG_ENTER("read_texts");
+ *point=0; // If something goes wrong
LINT_INIT(buff);
funktpos=0;
if ((file=my_open(fn_format(name,file_name,language,"",4),
@@ -63,37 +64,38 @@ static void read_texts(const char *file_name,const char ***point,
if (head[0] != (uchar) 254 || head[1] != (uchar) 254 ||
head[2] != 2 || head[3] != 1)
goto err; /* purecov: inspected */
- textant=head[4];
- length=uint2korr(head+6); ant=uint2korr(head+8);
+ textcount=head[4];
+ length=uint2korr(head+6); count=uint2korr(head+8);
- if (ant < error_messages)
+ if (count < error_messages)
{
- fprintf(stderr,"\n%s: Fatal error: Error message file '%s' had only %d error messages, but it should have at least %d error messages.\n\
-Check that the above file is the right version for this program!\n\n",
- my_progname,name,ant,error_messages);
+ sql_print_error("\
+Error message file '%s' had only %d error messages,\n\
+but it should contain at least %d error messages.\n\
+Check that the above file is the right version for this program!",
+ name,count,error_messages);
VOID(my_close(file,MYF(MY_WME)));
- clean_up(0); /* Clean_up frees everything */
- exit(1); /* We can't continue */
+ unireg_abort(1);
}
x_free((gptr) *point); /* Free old language */
if (!(*point= (const char**)
- my_malloc((uint) (length+ant*sizeof(char*)),MYF(0))))
+ my_malloc((uint) (length+count*sizeof(char*)),MYF(0))))
{
funktpos=2; /* purecov: inspected */
goto err; /* purecov: inspected */
}
- buff= (char*) (*point + ant);
+ buff= (char*) (*point + count);
- if (my_read(file,(byte*) buff,(uint) ant*2,MYF(MY_NABP))) goto err;
- for (i=0, pos= (uchar*) buff ; i< ant ; i++)
+ if (my_read(file,(byte*) buff,(uint) count*2,MYF(MY_NABP))) goto err;
+ for (i=0, pos= (uchar*) buff ; i< count ; i++)
{
(*point)[i]=buff+uint2korr(pos);
pos+=2;
}
if (my_read(file,(byte*) buff,(uint) length,MYF(MY_NABP))) goto err;
- for (i=1 ; i < textant ; i++)
+ for (i=1 ; i < textcount ; i++)
{
point[i]= *point +uint2korr(head+10+i+i);
}
@@ -103,20 +105,19 @@ Check that the above file is the right version for this program!\n\n",
err:
switch (funktpos) {
case 2:
- buff="\n%s: Fatal error: Not enough memory for messagefile '%s'\n\n";
+ buff="Not enough memory for messagefile '%s'";
break;
case 1:
- buff="\n%s: Fatal error: Can't read from messagefile '%s'\n\n";
+ buff="Can't read from messagefile '%s'";
break;
default:
- buff="\n%s: Fatal error: Can't find messagefile '%s'\n\n";
+ buff="Can't find messagefile '%s'";
break;
}
if (file != FERR)
VOID(my_close(file,MYF(MY_WME)));
- fprintf(stderr,buff,my_progname,name);
- clean_up(0); /* Clean_up frees everything */
- exit(1); /* We can't continue */
+ sql_print_error(buff,name);
+ unireg_abort(1);
} /* read_texts */
diff --git a/sql/des_key_file.cc b/sql/des_key_file.cc
new file mode 100644
index 00000000000..619691d183e
--- /dev/null
+++ b/sql/des_key_file.cc
@@ -0,0 +1,118 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <mysql_priv.h>
+#include <m_ctype.h>
+
+#ifdef HAVE_OPENSSL
+
+struct st_des_keyschedule des_keyschedule[10];
+uint des_default_key;
+pthread_mutex_t LOCK_des_key_file;
+static int initialized;
+
+/*
+ Function which loads DES keys from plaintext file into memory on MySQL
+ server startup and on command FLUSH DES_KEY_FILE.
+ Blame tonu@spam.ee on bugs ;)
+
+ RETURN
+ 0 ok
+ 1 Error
+*/
+
+bool
+load_des_key_file(const char *file_name)
+{
+ bool result=1;
+ File file;
+ IO_CACHE io;
+ DBUG_ENTER("load_des_key_file");
+ DBUG_PRINT("enter",("name: %s",file_name));
+
+ if (!initialized)
+ {
+ initialized=1;
+ pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
+ }
+
+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
+ if ((file=my_open(file_name,O_RDONLY | O_BINARY ,MYF(MY_WME))) < 0 ||
+ init_io_cache(&io, file, IO_SIZE*2, READ_CACHE, 0, 0, MYF(MY_WME)))
+ goto error;
+
+ bzero((char*) des_keyschedule,sizeof(struct st_des_keyschedule) * 10);
+ des_default_key=15; // Impossible key
+ for (;;)
+ {
+ char *start, *end;
+ char buf[1024], offset;
+ st_des_keyblock keyblock;
+ uint length;
+
+ if (!(length=my_b_gets(&io,buf,sizeof(buf)-1)))
+ break; // End of file
+ offset=buf[0];
+ if (offset >= '0' && offset <= '9') // If ok key
+ {
+ offset=(char) (offset - '0');
+ // Remove newline and possible other control characters
+ for (start=buf+1 ; isspace(*start) ; start++) ;
+ end=buf+length;
+ for (end=strend(buf) ; end > start && !isgraph(end[-1]) ; end--) ;
+
+ if (start != end)
+ {
+ DES_cblock ivec;
+ bzero((char*) &ivec,sizeof(ivec));
+ // We make good 24-byte (168 bit) key from given plaintext key with MD5
+ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
+ (uchar *) start, (int) (end-start),1,
+ (uchar *) &keyblock,
+ ivec);
+ DES_set_key_unchecked(&keyblock.key1,&(des_keyschedule[(int)offset].ks1));
+ DES_set_key_unchecked(&keyblock.key2,&(des_keyschedule[(int)offset].ks2));
+ DES_set_key_unchecked(&keyblock.key3,&(des_keyschedule[(int)offset].ks3));
+ if (des_default_key == 15)
+ des_default_key= (uint) offset; // use first as def.
+ }
+ }
+ else if (offset != '#')
+ sql_print_error("load_des_file: Found wrong key_number: %c",offset);
+ }
+ result=0;
+
+error:
+ if (file >= 0)
+ {
+ my_close(file,MYF(0));
+ end_io_cache(&io);
+ }
+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
+ DBUG_RETURN(result);
+}
+
+
+void free_des_key_file()
+{
+ if (initialized)
+ {
+ initialized= 01;
+ pthread_mutex_destroy(&LOCK_des_key_file);
+ }
+}
+
+#endif /* HAVE_OPENSSL */
diff --git a/sql/field.cc b/sql/field.cc
index 246427cc2ac..ac3ebb4bfc7 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -41,8 +41,13 @@
#include <floatingpoint.h>
#endif
+// Maximum allowed exponent value for converting string to decimal
+#define MAX_EXPONENT 1024
+
+
+
/*****************************************************************************
-** Instansiate templates and static variables
+ Instansiate templates and static variables
*****************************************************************************/
#ifdef __GNUC__
@@ -50,69 +55,13 @@ template class List<create_field>;
template class List_iterator<create_field>;
#endif
-struct st_decstr {
- uint nr_length,nr_dec,sign,extra;
- char sign_char;
-};
-
uchar Field_null::null[1]={1};
const char field_separator=',';
/*****************************************************************************
-** Static help functions
+ Static help functions
*****************************************************************************/
- /*
- Calculate length of number and it's parts
- Increment cuted_fields if wrong number
- */
-
-static bool
-number_dec(struct st_decstr *sdec, const char *str, const char *end)
-{
- sdec->sign=sdec->extra=0;
- if (str == end)
- {
- current_thd->cuted_fields++;
- sdec->nr_length=sdec->nr_dec=sdec->sign=0;
- sdec->extra=1; // We must put one 0 before .
- return 1;
- }
-
- if (*str == '-' || *str == '+') /* sign */
- {
- sdec->sign_char= *str;
- sdec->sign=1;
- str++;
- }
- const char *start=str;
- while (str != end && isdigit(*str))
- str++;
- if (!(sdec->nr_length=(uint) (str-start)))
- sdec->extra=1; // We must put one 0 before .
- start=str;
- if (str != end && *str == '.')
- {
- str++;
- start=str;
- while (str != end && isdigit(*str))
- str++;
- }
- sdec->nr_dec=(uint) (str-start);
- if (current_thd->count_cuted_fields)
- {
- while (str != end && isspace(*str))
- str++; /* purecov: inspected */
- if (str != end)
- {
- current_thd->cuted_fields++;
- return 1;
- }
- }
- return 0;
-}
-
-
void Field_num::prepend_zeros(String *value)
{
int diff;
@@ -127,8 +76,8 @@ void Field_num::prepend_zeros(String *value)
}
/*
-** Test if given number is a int (or a fixed format float with .000)
-** This is only used to give warnings in ALTER TABLE or LOAD DATA...
+ Test if given number is a int (or a fixed format float with .000)
+ This is only used to give warnings in ALTER TABLE or LOAD DATA...
*/
bool test_if_int(const char *str,int length)
@@ -141,7 +90,7 @@ bool test_if_int(const char *str,int length)
str++;
if (str == end)
return 0; // Error: Empty string
- for ( ; str != end ; str++)
+ for (; str != end ; str++)
{
if (!isdigit(*str))
{
@@ -204,7 +153,7 @@ static bool test_if_real(const char *str,int length)
length--; str++;
}
}
- for ( ; length ; length--, str++)
+ for (; length ; length--, str++)
{ // Allow end space
if (!isspace(*str))
return 0;
@@ -213,20 +162,29 @@ static bool test_if_real(const char *str,int length)
}
+static inline uint field_length_without_space(const char *ptr, uint length)
+{
+ const char *end= ptr+length;
+ while (end > ptr && end[-1] == ' ')
+ end--;
+ return (uint) (end-ptr);
+}
+
/****************************************************************************
** Functions for the base classes
-** This is a unpacked number.
+** This is an unpacked number.
****************************************************************************/
Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
- :ptr(ptr_arg),null_ptr(null_ptr_arg),null_bit(null_bit_arg),
- table(table_arg),query_id(0),key_start(0),part_of_key(0),part_of_sortkey(0),
- table_name(table_arg ? table_arg->table_name : 0),
- field_name(field_name_arg), unireg_check(unireg_check_arg),
- field_length(length_arg)
+ :ptr(ptr_arg),null_ptr(null_ptr_arg),
+ table(table_arg),table_name(table_arg ? table_arg->table_name : 0),
+ field_name(field_name_arg),
+ query_id(0),key_start(0),part_of_key(0),part_of_sortkey(0),
+ unireg_check(unireg_check_arg),
+ field_length(length_arg),null_bit(null_bit_arg)
{
flags=null_ptr ? 0: NOT_NULL_FLAG;
}
@@ -242,13 +200,13 @@ void Field::copy_from_tmp(int row_offset)
memcpy(ptr,ptr+row_offset,pack_length());
if (null_ptr)
{
- *null_ptr= ((null_ptr[0] & (uchar) ~(uint) null_bit) |
- null_ptr[row_offset] & (uchar) null_bit);
+ *null_ptr= (uchar) ((null_ptr[0] & (uchar) ~(uint) null_bit) |
+ null_ptr[row_offset] & (uchar) null_bit);
}
}
-bool Field::send(String *packet)
+bool Field::send(THD *thd, String *packet)
{
if (is_null())
return net_store_null(packet);
@@ -256,7 +214,7 @@ bool Field::send(String *packet)
String tmp(buff,sizeof(buff));
val_str(&tmp,&tmp);
CONVERT *convert;
- if ((convert=current_thd->convert_set))
+ if ((convert=thd->variables.convert_set))
return convert->store(packet,tmp.ptr(),tmp.length());
return net_store_data(packet,tmp.ptr(),tmp.length());
}
@@ -361,14 +319,14 @@ void Field::store_time(TIME *ltime,timestamp_type type)
}
-bool Field::optimize_range()
+bool Field::optimize_range(uint idx)
{
- return test(table->file->option_flag() & HA_READ_NEXT);
+ return test(table->file->index_flags(idx) & HA_READ_NEXT);
}
/****************************************************************************
-** Functions for the Field_decimal class
-** This is a unpacked number.
+ Functions for the Field_decimal class
+ This is an number stored as a pre-space (or pre-zero) string
****************************************************************************/
void
@@ -381,6 +339,8 @@ void Field_decimal::overflow(bool negative)
{
uint len=field_length;
char *to=ptr, filler= '9';
+
+ current_thd->cuted_fields++;
if (negative)
{
if (!unsigned_flag)
@@ -416,100 +376,348 @@ void Field_decimal::overflow(bool negative)
void Field_decimal::store(const char *from,uint len)
{
- reg3 int i;
- uint tmp_dec;
- char fyllchar;
- const char *end=from+len;
- struct st_decstr decstr;
- bool error;
+ const char *end= from+len;
+ /* The pointer where the field value starts (i.e., "where to write") */
+ char *to=ptr;
+ uint tmp_dec, tmp_uint;
+ /*
+ The sign of the number : will be 0 (means positive but sign not
+ specified), '+' or '-'
+ */
+ char sign_char=0;
+ /* The pointers where prezeros start and stop */
+ const char *pre_zeros_from, *pre_zeros_end;
+ /* The pointers where digits at the left of '.' start and stop */
+ const char *int_digits_from, *int_digits_end;
+ /* The pointers where digits at the right of '.' start and stop */
+ const char *frac_digits_from, *frac_digits_end;
+ /* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */
+ char expo_sign_char=0;
+ uint exponent=0; // value of the exponent
+ /*
+ Pointers used when digits move from the left of the '.' to the
+ right of the '.' (explained below)
+ */
+ const char *int_digits_tail_from;
+ /* Number of 0 that need to be added at the left of the '.' (1E3: 3 zeros) */
+ uint int_digits_added_zeros;
+ /*
+ Pointer used when digits move from the right of the '.' to the left
+ of the '.'
+ */
+ const char *frac_digits_head_end;
+ /* Number of 0 that need to be added at the right of the '.' (for 1E-3) */
+ uint frac_digits_added_zeros;
+ char *pos,*tmp_left_pos,*tmp_right_pos;
+ /* Pointers that are used as limits (begin and end of the field buffer) */
+ char *left_wall,*right_wall;
+ char tmp_char;
+ /*
+ To remember if current_thd->cuted_fields has already been incremented,
+ to do that only once
+ */
+ bool is_cuted_fields_incr=0;
+
+ LINT_INIT(int_digits_tail_from);
+ LINT_INIT(int_digits_added_zeros);
+ LINT_INIT(frac_digits_head_end);
+ LINT_INIT(frac_digits_added_zeros);
- if ((tmp_dec= dec))
- tmp_dec++; // Calculate pos of '.'
- while (from != end && isspace(*from))
- from++;
- if (zerofill)
+ /*
+ There are three steps in this function :
+ - parse the input string
+ - modify the position of digits around the decimal dot '.'
+ according to the exponent value (if specified)
+ - write the formatted number
+ */
+
+ if ((tmp_dec=dec))
+ tmp_dec++;
+
+ for (; from !=end && isspace(*from); from++) ; // Read spaces
+ if (from == end)
{
- fyllchar = '0';
- if (from != end)
- while (*from == '0' && from != end-1) // Skipp prezero
- from++;
+ current_thd->cuted_fields++;
+ is_cuted_fields_incr=1;
+ }
+ else if (*from == '+' || *from == '-') // Found some sign ?
+ {
+ sign_char= *from++;
+ /*
+ We allow "+" for unsigned decimal unless defined different
+ Both options allowed as one may wish not to have "+" for unsigned numbers
+ because of data processing issues
+ */
+ if (unsigned_flag)
+ {
+ if (sign_char=='-')
+ {
+ Field_decimal::overflow(1);
+ return;
+ }
+ /*
+ Defining this will not store "+" for unsigned decimal type even if
+ it is passed in numeric string. This will make some tests to fail
+ */
+#ifdef DONT_ALLOW_UNSIGNED_PLUS
+ else
+ sign_char=0;
+#endif
+ }
}
- else
- fyllchar=' ';
- error=number_dec(&decstr,from,end);
- if (decstr.sign)
- {
+
+ pre_zeros_from= from;
+ for (; from!=end && *from == '0'; from++) ; // Read prezeros
+ pre_zeros_end=int_digits_from=from;
+ /* Read non zero digits at the left of '.'*/
+ for (; from!=end && isdigit(*from);from++) ;
+ int_digits_end=from;
+ if (from!=end && *from == '.') // Some '.' ?
from++;
- if (unsigned_flag) // No sign with zerofill
+ frac_digits_from= from;
+ /* Read digits at the right of '.' */
+ for (;from!=end && isdigit(*from); from++) ;
+ frac_digits_end=from;
+ // Some exponentiation symbol ?
+ if (from != end && (*from == 'e' || *from == 'E'))
+ {
+ from++;
+ if (from != end && (*from == '+' || *from == '-')) // Some exponent sign ?
+ expo_sign_char= *from++;
+ else
+ expo_sign_char= '+';
+ /*
+ Read digits of the exponent and compute its value. We must care about
+ 'exponent' overflow, because as unsigned arithmetic is "modulo", big
+ exponents will become small (e.g. 1e4294967296 will become 1e0, and the
+ field will finally contain 1 instead of its max possible value).
+ */
+ for (;from!=end && isdigit(*from); from++)
{
- if (decstr.sign_char == '+') // just remove "+"
- decstr.sign= 0;
- else
- {
- if (!error)
- current_thd->cuted_fields++;
- Field_decimal::overflow(1);
- return;
- }
+ exponent=10*exponent+(*from-'0');
+ if (exponent>MAX_EXPONENT)
+ break;
}
}
+
/*
- ** Remove pre-zeros if too big number
+ We only have to generate warnings if count_cuted_fields is set.
+ This is to avoid extra checks of the number when they are not needed.
+ Even if this flag is not set, it's ok to increment warnings, if
+ it makes the code easer to read.
*/
- for (i= (int) (decstr.nr_length+decstr.extra -(field_length-tmp_dec)+
- decstr.sign) ;
- i > 0 ;
- i--)
+
+ if (current_thd->count_cuted_fields)
{
- if (*from == '0')
+ for (;from != end && isspace(*from); from++) ; // Read end spaces
+ if (from != end) // If still something left, warn
{
- from++;
- decstr.nr_length--;
- continue;
+ current_thd->cuted_fields++;
+ is_cuted_fields_incr=1;
}
- if (decstr.sign && decstr.sign_char == '+' && i == 1)
- { // Remove pre '+'
- decstr.sign=0;
- break;
+ }
+
+ /*
+ Now "move" digits around the decimal dot according to the exponent value,
+ and add necessary zeros.
+ Examples :
+ - 1E+3 : needs 3 more zeros at the left of '.' (int_digits_added_zeros=3)
+ - 1E-3 : '1' moves at the right of '.', and 2 more zeros are needed
+ between '.' and '1'
+ - 1234.5E-3 : '234' moves at the right of '.'
+ These moves are implemented with pointers which point at the begin
+ and end of each moved segment. Examples :
+ - 1234.5E-3 : before the code below is executed, the int_digits part is
+ from '1' to '4' and the frac_digits part from '5' to '5'. After the code
+ below, the int_digits part is from '1' to '1', the frac_digits_head
+ part is from '2' to '4', and the frac_digits part from '5' to '5'.
+ - 1234.5E3 : before the code below is executed, the int_digits part is
+ from '1' to '4' and the frac_digits part from '5' to '5'. After the code
+ below, the int_digits part is from '1' to '4', the int_digits_tail
+ part is from '5' to '5', the frac_digits part is empty, and
+ int_digits_added_zeros=2 (to make 1234500).
+ */
+
+ /*
+ Below tmp_uint cannot overflow with small enough MAX_EXPONENT setting,
+ as int_digits_added_zeros<=exponent<4G and
+ (int_digits_end-int_digits_from)<=max_allowed_packet<=2G and
+ (frac_digits_from-int_digits_tail_from)<=max_allowed_packet<=2G
+ */
+
+ if (!expo_sign_char)
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ else if (expo_sign_char == '-')
+ {
+ tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
+ frac_digits_added_zeros=exponent-tmp_uint;
+ int_digits_end -= tmp_uint;
+ frac_digits_head_end=int_digits_end+tmp_uint;
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ }
+ else // (expo_sign_char=='+')
+ {
+ tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from));
+ int_digits_added_zeros=exponent-tmp_uint;
+ int_digits_tail_from=frac_digits_from;
+ frac_digits_from=frac_digits_from+tmp_uint;
+ /*
+ We "eat" the heading zeros of the
+ int_digits.int_digits_tail.int_digits_added_zeros concatenation
+ (for example 0.003e3 must become 3 and not 0003)
+ */
+ if (int_digits_from == int_digits_end)
+ {
+ /*
+ There was nothing in the int_digits part, so continue
+ eating int_digits_tail zeros
+ */
+ for (; int_digits_tail_from != frac_digits_from &&
+ *int_digits_tail_from == '0'; int_digits_tail_from++) ;
+ if (int_digits_tail_from == frac_digits_from)
+ {
+ // there were only zeros in int_digits_tail too
+ int_digits_added_zeros=0;
+ }
}
- current_thd->cuted_fields++;
+ tmp_uint= (tmp_dec+(int_digits_end-int_digits_from)+
+ (uint)(frac_digits_from-int_digits_tail_from)+
+ int_digits_added_zeros);
+ }
+
+ /*
+ Now write the formated number
+
+ First the digits of the int_% parts.
+ Do we have enough room to write these digits ?
+ If the sign is defined and '-', we need one position for it
+ */
+
+ if (field_length < tmp_uint + (int) (sign_char == '-'))
+ {
// too big number, change to max or min number
- Field_decimal::overflow(decstr.sign && decstr.sign_char == '-');
+ Field_decimal::overflow(sign_char == '-');
return;
}
- char *to=ptr;
- for (i=(int) (field_length-tmp_dec-decstr.nr_length-decstr.extra - decstr.sign) ;
- i-- > 0 ;)
- *to++ = fyllchar;
- if (decstr.sign)
- *to++= decstr.sign_char;
- if (decstr.extra)
- *to++ = '0';
- for (i=(int) decstr.nr_length ; i-- > 0 ; )
- *to++ = *from++;
- if (tmp_dec--)
- {
- *to++ ='.';
- if (decstr.nr_dec) from++; // Skipp '.'
- for (i=(int) min(decstr.nr_dec,tmp_dec) ; i-- > 0 ; ) *to++ = *from++;
- for (i=(int) (tmp_dec-min(decstr.nr_dec,tmp_dec)) ; i-- > 0 ; ) *to++ = '0';
+
+ /*
+ Tmp_left_pos is the position where the leftmost digit of
+ the int_% parts will be written
+ */
+ tmp_left_pos=pos=to+(uint)(field_length-tmp_uint);
+
+ // Write all digits of the int_% parts
+ while (int_digits_from != int_digits_end)
+ *pos++ = *int_digits_from++ ;
+
+ if (expo_sign_char == '+')
+ {
+ while (int_digits_tail_from != frac_digits_from)
+ *pos++= *int_digits_tail_from++;
+ while (int_digits_added_zeros-- >0)
+ *pos++= '0';
}
+ /*
+ Note the position where the rightmost digit of the int_% parts has been
+ written (this is to later check if the int_% parts contained nothing,
+ meaning an extra 0 is needed).
+ */
+ tmp_right_pos=pos;
/*
- ** Check for incorrect string if in batch mode (ALTER TABLE/LOAD DATA...)
+ Step back to the position of the leftmost digit of the int_% parts,
+ to write sign and fill with zeros or blanks or prezeros.
*/
- if (!error && current_thd->count_cuted_fields && from != end)
- { // Check if number was cuted
- for (; from != end ; from++)
+ pos=tmp_left_pos-1;
+ if (zerofill)
+ {
+ left_wall=to-1;
+ while (pos > left_wall) // Fill with zeros
+ *pos--='0';
+ }
+ else
+ {
+ left_wall=to+(sign_char != 0)-1;
+ if (!expo_sign_char) // If exponent was specified, ignore prezeros
+ {
+ for (;pos > left_wall && pre_zeros_from !=pre_zeros_end;
+ pre_zeros_from++)
+ *pos--= '0';
+ }
+ if (pos == tmp_right_pos-1)
+ *pos--= '0'; // no 0 has ever been written, so write one
+ left_wall= to-1;
+ if (sign_char && pos != left_wall)
{
- if (*from != '0')
+ /* Write sign if possible (it is if sign is '-') */
+ *pos--= sign_char;
+ }
+ while (pos != left_wall)
+ *pos--=' '; //fill with blanks
+ }
+
+ /*
+ Write digits of the frac_% parts ;
+ Depending on current_thd->count_cutted_fields, we may also want
+ to know if some non-zero tail of these parts will
+ be truncated (for example, 0.002->0.00 will generate a warning,
+ while 0.000->0.00 will not)
+ (and 0E1000000000 will not, while 1E-1000000000 will)
+ */
+
+ pos=to+(uint)(field_length-tmp_dec); // Calculate post to '.'
+ right_wall=to+field_length;
+ if (pos != right_wall)
+ *pos++='.';
+
+ if (expo_sign_char == '-')
+ {
+ while (frac_digits_added_zeros-- > 0)
+ {
+ if (pos == right_wall)
{
- if (!isspace(*from)) // Space is ok
+ if (current_thd->count_cuted_fields && !is_cuted_fields_incr)
+ break; // Go on below to see if we lose non zero digits
+ return;
+ }
+ *pos++='0';
+ }
+ while (int_digits_end != frac_digits_head_end)
+ {
+ tmp_char= *int_digits_end++;
+ if (pos == right_wall)
+ {
+ if (tmp_char != '0') // Losing a non zero digit ?
+ {
+ if (!is_cuted_fields_incr)
+ current_thd->cuted_fields++;
+ return;
+ }
+ continue;
+ }
+ *pos++= tmp_char;
+ }
+ }
+
+ for (;frac_digits_from!=frac_digits_end;)
+ {
+ tmp_char= *frac_digits_from++;
+ if (pos == right_wall)
+ {
+ if (tmp_char != '0') // Losing a non zero digit ?
+ {
+ if (!is_cuted_fields_incr)
current_thd->cuted_fields++;
- break;
+ return;
}
+ continue;
}
+ *pos++= tmp_char;
}
+
+ while (pos != right_wall)
+ *pos++='0'; // Fill with zeros at right of '.'
+
}
@@ -518,15 +726,23 @@ void Field_decimal::store(double nr)
if (unsigned_flag && nr < 0)
{
overflow(1);
- current_thd->cuted_fields++;
return;
}
+
+#ifdef HAVE_FINITE
+ if (!finite(nr)) // Handle infinity as special case
+ {
+ overflow(nr < 0.0);
+ return;
+ }
+#endif
+
reg4 uint i,length;
char fyllchar,*to;
char buff[320];
fyllchar = zerofill ? (char) '0' : (char) ' ';
-#ifdef HAVE_SNPRINTF_
+#ifdef HAVE_SNPRINTF
buff[sizeof(buff)-1]=0; // Safety
snprintf(buff,sizeof(buff)-1, "%.*f",(int) dec,nr);
#else
@@ -535,10 +751,7 @@ void Field_decimal::store(double nr)
length=(uint) strlen(buff);
if (length > field_length)
- {
overflow(nr < 0.0);
- current_thd->cuted_fields++;
- }
else
{
to=ptr;
@@ -554,7 +767,6 @@ void Field_decimal::store(longlong nr)
if (unsigned_flag && nr < 0)
{
overflow(1);
- current_thd->cuted_fields++;
return;
}
char buff[22];
@@ -562,10 +774,7 @@ void Field_decimal::store(longlong nr)
uint int_part=field_length- (dec ? dec+1 : 0);
if (length > int_part)
- {
overflow(test(nr < 0L)); /* purecov: inspected */
- current_thd->cuted_fields++; /* purecov: inspected */
- }
else
{
char fyllchar = zerofill ? (char) '0' : (char) ' ';
@@ -639,7 +848,7 @@ int Field_decimal::cmp(const char *a_ptr,const char *b_ptr)
return 0;
if (*a_ptr == '-')
return -1;
- else if (*b_ptr == '-')
+ if (*b_ptr == '-')
return 1;
while (a_ptr != end)
@@ -1075,7 +1284,7 @@ void Field_short::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[0];
else
- to[0] = ptr[0] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */
to[1] = ptr[1];
}
else
@@ -1084,7 +1293,7 @@ void Field_short::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[1];
else
- to[0] = ptr[1] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[1] ^ 128); /* Revers signbit */
to[1] = ptr[0];
}
}
@@ -1155,12 +1364,12 @@ void Field_medium::store(double nr)
}
else if (nr >= (double) (long) (1L << 24))
{
- ulong tmp=(ulong) (1L << 24)-1L;
+ uint32 tmp=(uint32) (1L << 24)-1L;
int3store(ptr,tmp);
current_thd->cuted_fields++;
}
else
- int3store(ptr,(ulong) nr);
+ int3store(ptr,(uint32) nr);
}
else
{
@@ -1197,7 +1406,7 @@ void Field_medium::store(longlong nr)
current_thd->cuted_fields++;
}
else
- int3store(ptr,(ulong) nr);
+ int3store(ptr,(uint32) nr);
}
else
{
@@ -1290,12 +1499,14 @@ void Field_medium::sql_type(String &res) const
void Field_long::store(const char *from,uint len)
{
+ char *end;
while (len && isspace(*from))
{
len--; from++;
}
long tmp;
String tmp_str(from,len);
+ from= tmp_str.c_ptr(); // Add end null if needed
errno=0;
if (unsigned_flag)
{
@@ -1305,11 +1516,13 @@ void Field_long::store(const char *from,uint len)
errno=ERANGE;
}
else
- tmp=(long) strtoul(tmp_str.c_ptr(),NULL,10);
+ tmp=(long) strtoul(from, &end, 10);
}
else
- tmp=strtol(tmp_str.c_ptr(),NULL,10);
- if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
+ tmp=strtol(from, &end, 10);
+ if (errno ||
+ (from+len != end && current_thd->count_cuted_fields &&
+ !test_if_int(from,len)))
current_thd->cuted_fields++;
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@@ -1475,7 +1688,7 @@ int Field_long::cmp(const char *a_ptr, const char *b_ptr)
longget(b,b_ptr);
}
if (unsigned_flag)
- return ((ulong) a < (ulong) b) ? -1 : ((ulong) a > (ulong) b) ? 1 : 0;
+ return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0;
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
@@ -1487,7 +1700,7 @@ void Field_long::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[0];
else
- to[0] = ptr[0] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */
to[1] = ptr[1];
to[2] = ptr[2];
to[3] = ptr[3];
@@ -1498,7 +1711,7 @@ void Field_long::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[3];
else
- to[0] = ptr[3] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[3] ^ 128); /* Revers signbit */
to[1] = ptr[2];
to[2] = ptr[1];
to[3] = ptr[0];
@@ -1518,12 +1731,14 @@ void Field_long::sql_type(String &res) const
void Field_longlong::store(const char *from,uint len)
{
+ char *end;
while (len && isspace(*from))
{ // For easy error check
len--; from++;
}
longlong tmp;
String tmp_str(from,len);
+ from= tmp_str.c_ptr(); // Add end null if needed
errno=0;
if (unsigned_flag)
{
@@ -1533,12 +1748,14 @@ void Field_longlong::store(const char *from,uint len)
errno=ERANGE;
}
else
- tmp=(longlong) strtoull(tmp_str.c_ptr(),NULL,10);
+ tmp=(longlong) strtoull(from, &end, 10);
}
else
- tmp=strtoll(tmp_str.c_ptr(),NULL,10);
- if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
- current_thd->cuted_fields++;
+ tmp=strtoll(from, &end, 10);
+ if (errno ||
+ (from+len != end && current_thd->count_cuted_fields &&
+ !test_if_int(from,len)))
+ current_thd->cuted_fields++;
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -1619,9 +1836,16 @@ double Field_longlong::val_real(void)
else
#endif
longlongget(j,ptr);
- return unsigned_flag ? ulonglong2double((ulonglong) j) : (double) j;
+ /* The following is open coded to avoid a bug in gcc 3.3 */
+ if (unsigned_flag)
+ {
+ ulonglong tmp= (ulonglong) j;
+ return ulonglong2double(tmp);
+ }
+ return (double) j;
}
+
longlong Field_longlong::val_int(void)
{
longlong j;
@@ -1686,7 +1910,7 @@ void Field_longlong::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[0];
else
- to[0] = ptr[0] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */
to[1] = ptr[1];
to[2] = ptr[2];
to[3] = ptr[3];
@@ -1701,7 +1925,7 @@ void Field_longlong::sort_string(char *to,uint length __attribute__((unused)))
if (unsigned_flag)
to[0] = ptr[7];
else
- to[0] = ptr[7] ^ 128; /* Revers signbit */
+ to[0] = (char) (ptr[7] ^ 128); /* Revers signbit */
to[1] = ptr[6];
to[2] = ptr[5];
to[3] = ptr[4];
@@ -1738,6 +1962,11 @@ void Field_float::store(double nr)
float j;
if (dec < NOT_FIXED_DEC)
nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point
+ if (unsigned_flag && nr < 0)
+ {
+ current_thd->cuted_fields++;
+ nr=0;
+ }
if (nr < -FLT_MAX)
{
j= -FLT_MAX;
@@ -1764,6 +1993,11 @@ void Field_float::store(double nr)
void Field_float::store(longlong nr)
{
float j= (float) nr;
+ if (unsigned_flag && j < 0)
+ {
+ current_thd->cuted_fields++;
+ j=0;
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -1936,7 +2170,7 @@ void Field_float::sort_string(char *to,uint length __attribute__((unused)))
{ /* make complement */
uint i;
for (i=0 ; i < sizeof(nr); i++)
- tmp[i]=tmp[i] ^ (uchar) 255;
+ tmp[i]= (uchar) (tmp[i] ^ (uchar) 255);
}
else
{
@@ -1970,6 +2204,11 @@ void Field_double::store(const char *from,uint len)
double j= atof(tmp_str.c_ptr());
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
current_thd->cuted_fields++;
+ if (unsigned_flag && j < 0)
+ {
+ current_thd->cuted_fields++;
+ j=0;
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -1985,6 +2224,11 @@ void Field_double::store(double nr)
{
if (dec < NOT_FIXED_DEC)
nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point
+ if (unsigned_flag && nr < 0)
+ {
+ current_thd->cuted_fields++;
+ nr=0;
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -1999,6 +2243,11 @@ void Field_double::store(double nr)
void Field_double::store(longlong nr)
{
double j= (double) nr;
+ if (unsigned_flag && j < 0)
+ {
+ current_thd->cuted_fields++;
+ j=0;
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2187,6 +2436,14 @@ void Field_double::sql_type(String &res) const
** by handler.cc. The form->timestamp points at the automatic timestamp.
****************************************************************************/
+enum Item_result Field_timestamp::result_type() const
+{
+ return (!current_thd->variables.new_mode &&
+ (field_length == 8 || field_length == 14) ? INT_RESULT :
+ STRING_RESULT);
+}
+
+
Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
enum utype unireg_check_arg,
const char *field_name_arg,
@@ -2263,31 +2520,60 @@ void Field_timestamp::store(double nr)
** function.
*/
-static longlong fix_datetime(longlong nr)
+static longlong fix_datetime(longlong nr, TIME *time_res)
{
+ long part1,part2;
+
if (nr == LL(0) || nr >= LL(10000101000000))
- return nr; // Normal datetime >= Year 1000
+ goto ok;
if (nr < 101)
goto err;
if (nr <= (YY_PART_YEAR-1)*10000L+1231L)
- return (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069
+ {
+ nr= (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069
+ goto ok;
+ }
if (nr < (YY_PART_YEAR)*10000L+101L)
goto err;
if (nr <= 991231L)
- return (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999
+ {
+ nr= (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999
+ goto ok;
+ }
if (nr < 10000101L)
goto err;
if (nr <= 99991231L)
- return nr*1000000L;
+ {
+ nr= nr*1000000L;
+ goto ok;
+ }
if (nr < 101000000L)
goto err;
if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959))
- return nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069
+ {
+ nr= nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069
+ goto ok;
+ }
if (nr < YY_PART_YEAR*LL(10000000000)+ LL(101000000))
goto err;
if (nr <= LL(991231235959))
- return nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999
-
+ nr= nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999
+
+ ok:
+ part1=(long) (nr/LL(1000000));
+ part2=(long) (nr - (longlong) part1*LL(1000000));
+ time_res->year= (int) (part1/10000L); part1%=10000L;
+ time_res->month= (int) part1 / 100;
+ time_res->day= (int) part1 % 100;
+ time_res->hour= (int) (part2/10000L); part2%=10000L;
+ time_res->minute=(int) part2 / 100;
+ time_res->second=(int) part2 % 100;
+
+ if (time_res->year <= 9999 && time_res->month <= 12 &&
+ time_res->day <= 31 && time_res->hour <= 23 &&
+ time_res->minute <= 59 && time_res->second <= 59)
+ return nr;
+
err:
current_thd->cuted_fields++;
return LL(0);
@@ -2297,23 +2583,18 @@ static longlong fix_datetime(longlong nr)
void Field_timestamp::store(longlong nr)
{
TIME l_time;
- time_t timestamp;
- long part1,part2;
+ time_t timestamp= 0;
- if ((nr=fix_datetime(nr)))
+ if ((nr= fix_datetime(nr, &l_time)))
{
- part1=(long) (nr/LL(1000000));
- part2=(long) (nr - (longlong) part1*LL(1000000));
- l_time.year= part1/10000L; part1%=10000L;
- l_time.month= (int) part1 / 100;
- l_time.day= (int) part1 % 100;
- l_time.hour= part2/10000L; part2%=10000L;
- l_time.minute=(int) part2 / 100;
- l_time.second=(int) part2 % 100;
- timestamp=my_gmt_sec(&l_time);
+ long not_used;
+
+ timestamp= my_gmt_sec(&l_time, &not_used);
+
+ if (!timestamp)
+ current_thd->cuted_fields++;
}
- else
- timestamp=0;
+
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2321,7 +2602,7 @@ void Field_timestamp::store(longlong nr)
}
else
#endif
- longstore(ptr,(ulong)timestamp);
+ longstore(ptr,(uint32) timestamp);
}
@@ -2387,9 +2668,9 @@ String *Field_timestamp::val_str(String *val_buffer,
time_t time_arg;
struct tm *l_time;
struct tm tm_tmp;
-
- val_buffer->alloc(field_length+1);
- char *to=(char*) val_buffer->ptr(),*end=to+field_length;
+ my_bool new_format= (current_thd->variables.new_mode),
+ full_year=(field_length == 8 || field_length == 14 || new_format);
+ int real_field_length= new_format ? 19 : field_length;
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@@ -2400,17 +2681,23 @@ String *Field_timestamp::val_str(String *val_buffer,
if (temp == 0L)
{ /* Zero time is "000000" */
- VOID(strfill(to,field_length,'0'));
- val_buffer->length(field_length);
+ if (new_format)
+ val_buffer->copy("0000-00-00 00:00:00", real_field_length);
+ else
+ val_buffer->copy("00000000000000", real_field_length);
return val_buffer;
}
time_arg=(time_t) temp;
localtime_r(&time_arg,&tm_tmp);
l_time=&tm_tmp;
+
+ val_buffer->alloc(real_field_length+1);
+ char *to=(char*) val_buffer->ptr(),*end=to+real_field_length;
+
for (pos=0; to < end ; pos++)
{
bool year_flag=0;
- switch (dayord.pos[pos]) {
+ switch (pos) {
case 0: part_time=l_time->tm_year % 100; year_flag=1; break;
case 1: part_time=l_time->tm_mon+1; break;
case 2: part_time=l_time->tm_mday; break;
@@ -2419,7 +2706,7 @@ String *Field_timestamp::val_str(String *val_buffer,
case 5: part_time=l_time->tm_sec; break;
default: part_time=0; break; /* purecov: deadcode */
}
- if (year_flag && (field_length == 8 || field_length == 14))
+ if (year_flag && full_year)
{
if (part_time < YY_PART_YEAR)
{
@@ -2432,7 +2719,14 @@ String *Field_timestamp::val_str(String *val_buffer,
}
*to++=(char) ('0'+((uint) part_time/10));
*to++=(char) ('0'+((uint) part_time % 10));
+ if (new_format)
+ {
+ static const char delim[6]="-- ::";
+ *to++=delim[pos];
+ }
}
+ if (new_format)
+ to--;
*to=0; // Safeguard
val_buffer->length((uint) (to-val_buffer->ptr()));
return val_buffer;
@@ -2536,6 +2830,23 @@ void Field_timestamp::set_time()
longstore(ptr,tmp);
}
+/*
+ This is an exact copy of Field_num except that 'length' is depending
+ on --new mode
+*/
+
+void Field_timestamp::make_field(Send_field *field)
+{
+ field->table_name=table_name;
+ field->col_name=field_name;
+ /* If --new, then we are using "YYYY-MM-DD HH:MM:SS" format */
+ field->length= current_thd->variables.new_mode ? 19 : field_length;
+ field->type=type();
+ field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
+ field->decimals=dec;
+}
+
+
/****************************************************************************
** time type
** In string context: HH:MM:SS
@@ -2622,7 +2933,7 @@ void Field_time::store(longlong nr)
double Field_time::val_real(void)
{
- ulong j= (ulong) uint3korr(ptr);
+ uint32 j= (uint32) uint3korr(ptr);
return (double) j;
}
@@ -2658,19 +2969,19 @@ bool Field_time::get_time(TIME *ltime)
ltime->neg= 1;
tmp=-tmp;
}
- ltime->hour=tmp/10000;
+ ltime->hour= (int) (tmp/10000);
tmp-=ltime->hour*10000;
- ltime->minute= tmp/100;
- ltime->second= tmp % 100;
+ ltime->minute= (int) tmp/100;
+ ltime->second= (int) tmp % 100;
ltime->second_part=0;
return 0;
}
int Field_time::cmp(const char *a_ptr, const char *b_ptr)
{
- long a,b;
- a=(long) sint3korr(a_ptr);
- b=(long) sint3korr(b_ptr);
+ int32 a,b;
+ a=(int32) sint3korr(a_ptr);
+ b=(int32) sint3korr(b_ptr);
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
@@ -2703,7 +3014,7 @@ void Field_year::store(const char *from, uint len)
current_thd->cuted_fields++;
return;
}
- else if (current_thd->count_cuted_fields && !test_if_int(from,len))
+ if (current_thd->count_cuted_fields && !test_if_int(from,len))
current_thd->cuted_fields++;
if (nr != 0 || len != 4)
{
@@ -2781,14 +3092,14 @@ void Field_year::sql_type(String &res) const
** Stored as a 4 byte unsigned int
****************************************************************************/
-void Field_date::store(const char *from,uint len)
+void Field_date::store(const char *from, uint len)
{
TIME l_time;
- ulong tmp;
+ uint32 tmp;
if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE)
tmp=0;
else
- tmp=(ulong) l_time.year*10000L + (ulong) (l_time.month*100+l_time.day);
+ tmp=(uint32) l_time.year*10000L + (uint32) (l_time.month*100+l_time.day);
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2960,7 +3271,7 @@ void Field_newdate::store(double nr)
void Field_newdate::store(longlong nr)
{
- long tmp;
+ int32 tmp;
if (nr >= LL(100000000) && nr <= LL(99991231235959))
nr=nr/LL(1000000); // Timestamp to date
if (nr < 0L || nr > 99991231L)
@@ -2970,16 +3281,16 @@ void Field_newdate::store(longlong nr)
}
else
{
- tmp=(long) nr;
+ tmp=(int32) nr;
if (tmp)
{
if (tmp < YY_PART_YEAR*10000L) // Fix short dates
- tmp+=20000000L;
+ tmp+= (uint32) 20000000L;
else if (tmp < 999999L)
- tmp+=19000000L;
+ tmp+= (uint32) 19000000L;
}
- uint month=((tmp/100) % 100);
- uint day= tmp%100;
+ uint month= (uint) ((tmp/100) % 100);
+ uint day= (uint) (tmp%100);
if (month > 12 || day > 31)
{
tmp=0L; // Don't allow date to change
@@ -2988,7 +3299,7 @@ void Field_newdate::store(longlong nr)
else
tmp= day + month*32 + (tmp/10000)*16*32;
}
- int3store(ptr,tmp);
+ int3store(ptr,(int32) tmp);
}
void Field_newdate::store_time(TIME *ltime,timestamp_type type)
@@ -3013,7 +3324,7 @@ double Field_newdate::val_real(void)
longlong Field_newdate::val_int(void)
{
- ulong j=uint3korr(ptr);
+ ulong j= uint3korr(ptr);
j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L;
return (longlong) j;
}
@@ -3023,25 +3334,25 @@ String *Field_newdate::val_str(String *val_buffer,
{
val_buffer->alloc(field_length);
val_buffer->length(field_length);
- ulong tmp=(ulong) uint3korr(ptr);
+ uint32 tmp=(uint32) uint3korr(ptr);
int part;
char *pos=(char*) val_buffer->ptr()+10;
/* Open coded to get more speed */
- *pos--=0;
+ *pos--=0; // End NULL
part=(int) (tmp & 31);
- *pos--='0'+part%10;
- *pos--='0'+part/10;
- *pos--='-';
+ *pos--= (char) ('0'+part%10);
+ *pos--= (char) ('0'+part/10);
+ *pos--= '-';
part=(int) (tmp >> 5 & 15);
- *pos--='0'+part%10;
- *pos--='0'+part/10;
- *pos--='-';
+ *pos--= (char) ('0'+part%10);
+ *pos--= (char) ('0'+part/10);
+ *pos--= '-';
part=(int) (tmp >> 9);
- *pos--='0'+part%10; part/=10;
- *pos--='0'+part%10; part/=10;
- *pos--='0'+part%10; part/=10;
- *pos='0'+part;
+ *pos--= (char) ('0'+part%10); part/=10;
+ *pos--= (char) ('0'+part%10); part/=10;
+ *pos--= (char) ('0'+part%10); part/=10;
+ *pos= (char) ('0'+part);
return val_buffer;
}
@@ -3049,12 +3360,12 @@ bool Field_newdate::get_date(TIME *ltime,bool fuzzydate)
{
if (is_null())
return 1;
- ulong tmp=(ulong) uint3korr(ptr);
- bzero((char*) ltime,sizeof(*ltime));
+ uint32 tmp=(uint32) uint3korr(ptr);
ltime->day= tmp & 31;
ltime->month= (tmp >> 5) & 15;
ltime->year= (tmp >> 9);
ltime->time_type=TIMESTAMP_DATE;
+ ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
}
@@ -3065,9 +3376,9 @@ bool Field_newdate::get_time(TIME *ltime)
int Field_newdate::cmp(const char *a_ptr, const char *b_ptr)
{
- ulong a,b;
- a=(ulong) uint3korr(a_ptr);
- b=(ulong) uint3korr(b_ptr);
+ uint32 a,b;
+ a=(uint32) uint3korr(a_ptr);
+ b=(uint32) uint3korr(b_ptr);
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
@@ -3118,13 +3429,10 @@ void Field_datetime::store(double nr)
void Field_datetime::store(longlong nr)
{
- if (nr < 0 || nr > LL(99991231235959))
- {
- nr=0;
- current_thd->cuted_fields++;
- }
- else
- nr=fix_datetime(nr);
+ TIME not_used;
+
+ nr= fix_datetime(nr, &not_used);
+
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -3201,44 +3509,44 @@ String *Field_datetime::val_str(String *val_buffer,
pos=(char*) val_buffer->ptr()+19;
*pos--=0;
- *pos--='0'+(char) (part2%10); part2/=10;
- *pos--='0'+(char) (part2%10); part3= (int) (part2 / 10);
- *pos--=':';
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos--=':';
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos--='0'+(char) part3;
- *pos--=' ';
- *pos--='0'+(char) (part1%10); part1/=10;
- *pos--='0'+(char) (part1%10); part1/=10;
- *pos--='-';
- *pos--='0'+(char) (part1%10); part1/=10;
- *pos--='0'+(char) (part1%10); part3= (int) (part1/10);
- *pos--='-';
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos--='0'+(char) (part3%10); part3/=10;
- *pos='0'+(char) part3;
+ *pos--= (char) ('0'+(char) (part2%10)); part2/=10;
+ *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
+ *pos--= ':';
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos--= ':';
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos--= (char) ('0'+(char) part3);
+ *pos--= ' ';
+ *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
+ *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
+ *pos--= '-';
+ *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
+ *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
+ *pos--= '-';
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
+ *pos=(char) ('0'+(char) part3);
return val_buffer;
}
bool Field_datetime::get_date(TIME *ltime,bool fuzzydate)
{
longlong tmp=Field_datetime::val_int();
- long part1,part2;
- part1=(long) (tmp/LL(1000000));
- part2=(long) (tmp - (ulonglong) part1*LL(1000000));
+ uint32 part1,part2;
+ part1=(uint32) (tmp/LL(1000000));
+ part2=(uint32) (tmp - (ulonglong) part1*LL(1000000));
ltime->time_type= TIMESTAMP_FULL;
- ltime->neg=0;
- ltime->second_part=0;
- ltime->second= part2%100;
- ltime->minute= part2/100%100;
- ltime->hour= part2/10000;
- ltime->day= part1%100;
- ltime->month= part1/100%100;
- ltime->year= part1/10000;
+ ltime->neg= 0;
+ ltime->second_part= 0;
+ ltime->second= (int) (part2%100);
+ ltime->minute= (int) (part2/100%100);
+ ltime->hour= (int) (part2/10000);
+ ltime->day= (int) (part1%100);
+ ltime->month= (int) (part1/100%100);
+ ltime->year= (int) (part1/10000);
return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
}
@@ -3310,9 +3618,9 @@ void Field_datetime::sql_type(String &res) const
void Field_string::store(const char *from,uint length)
{
#ifdef USE_TIS620
- if(!binary_flag) {
+ if (!binary_flag) {
ThNormalize((uchar *)ptr, field_length, (uchar *)from, length);
- if(length < field_length) {
+ if (length < field_length) {
bfill(ptr + length, field_length - length, ' ');
}
}
@@ -3357,7 +3665,7 @@ void Field_string::store(longlong nr)
{
char buff[22];
char *end=longlong10_to_str(nr,buff,-10);
- Field_string::store(buff,end-buff);
+ Field_string::store(buff,(uint) (end-buff));
}
@@ -3401,8 +3709,21 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr)
{
if (binary_flag)
return memcmp(a_ptr,b_ptr,field_length);
- else
- return my_sortcmp(a_ptr,b_ptr,field_length);
+#ifdef USE_STRCOLL
+ if (use_strcoll(default_charset_info))
+ {
+ /*
+ We have to remove end space to be able to compare multi-byte-characters
+ like in latin_de 'ae' and 0xe4
+ */
+ uint a_length= field_length_without_space(a_ptr, field_length);
+ uint b_length= field_length_without_space(b_ptr, field_length);
+ return my_strnncoll(default_charset_info,
+ (const uchar*) a_ptr, a_length,
+ (const uchar*) b_ptr, b_length);
+ }
+#endif
+ return my_sortcmp(a_ptr,b_ptr,field_length);
}
void Field_string::sort_string(char *to,uint length)
@@ -3492,12 +3813,12 @@ int Field_string::pack_cmp(const char *b, uint length)
}
-uint Field_string::packed_col_length(const char *ptr, uint length)
+uint Field_string::packed_col_length(const char *data_ptr, uint length)
{
if (length > 255)
- return uint2korr(ptr)+2;
+ return uint2korr(data_ptr)+2;
else
- return (uint) ((uchar) *ptr)+1;
+ return (uint) ((uchar) *data_ptr)+1;
}
uint Field_string::max_packed_col_length(uint max_length)
@@ -3514,7 +3835,7 @@ uint Field_string::max_packed_col_length(uint max_length)
void Field_varstring::store(const char *from,uint length)
{
#ifdef USE_TIS620
- if(!binary_flag)
+ if (!binary_flag)
{
ThNormalize((uchar *) ptr+2, field_length, (uchar *) from, length);
}
@@ -3548,7 +3869,7 @@ void Field_varstring::store(longlong nr)
{
char buff[22];
char *end=longlong10_to_str(nr,buff,-10);
- Field_varstring::store(buff,end-buff);
+ Field_varstring::store(buff,(uint) (end-buff));
}
@@ -3639,9 +3960,9 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length)
uint length=uint2korr(from);
if (length > max_length)
length=max_length;
- *to++= (length & 255);
+ *to++= (char) (length & 255);
if (max_length > 255)
- *to++= (uchar) (length >> 8);
+ *to++= (char) (length >> 8);
if (length)
memcpy(to, from+2, length);
return to+length;
@@ -3711,12 +4032,12 @@ int Field_varstring::pack_cmp(const char *b, uint key_length)
return my_sortncmp(a,a_length, b,b_length);
}
-uint Field_varstring::packed_col_length(const char *ptr, uint length)
+uint Field_varstring::packed_col_length(const char *data_ptr, uint length)
{
if (length > 255)
- return uint2korr(ptr)+2;
+ return uint2korr(data_ptr)+2;
else
- return (uint) ((uchar) *ptr)+1;
+ return (uint) ((uchar) *data_ptr)+1;
}
uint Field_varstring::max_packed_col_length(uint max_length)
@@ -3730,7 +4051,7 @@ uint Field_varstring::max_packed_col_length(uint max_length)
** packlength slot and may be from 1-4.
****************************************************************************/
-Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
+Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,uint blob_pack_length,
bool binary_arg)
@@ -3747,7 +4068,7 @@ Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
}
-void Field_blob::store_length(ulong number)
+void Field_blob::store_length(uint32 number)
{
switch (packlength) {
case 1:
@@ -3774,9 +4095,9 @@ void Field_blob::store_length(ulong number)
shortstore(ptr,(unsigned short) number);
break;
case 3:
- if (number > (ulong) (1L << 24))
+ if (number > (uint32) (1L << 24))
{
- number= (ulong) (1L << 24)-1L;
+ number= (uint32) (1L << 24)-1L;
current_thd->cuted_fields++;
}
int3store(ptr,number);
@@ -3794,11 +4115,11 @@ void Field_blob::store_length(ulong number)
}
-ulong Field_blob::get_length(const char *pos)
+uint32 Field_blob::get_length(const char *pos)
{
switch (packlength) {
case 1:
- return (ulong) (uchar) pos[0];
+ return (uint32) (uchar) pos[0];
case 2:
{
uint16 tmp;
@@ -3808,10 +4129,10 @@ ulong Field_blob::get_length(const char *pos)
else
#endif
shortget(tmp,pos);
- return (ulong) tmp;
+ return (uint32) tmp;
}
case 3:
- return (ulong) uint3korr(pos);
+ return (uint32) uint3korr(pos);
case 4:
{
uint32 tmp;
@@ -3821,7 +4142,7 @@ ulong Field_blob::get_length(const char *pos)
else
#endif
longget(tmp,pos);
- return (ulong) tmp;
+ return (uint32) tmp;
}
}
return 0; // Impossible
@@ -3843,7 +4164,7 @@ void Field_blob::store(const char *from,uint len)
if (table->copy_blobs || len <= MAX_FIELD_WIDTH)
{ // Must make a copy
#ifdef USE_TIS620
- if(!binary_flag)
+ if (!binary_flag)
{
/* If there isn't enough memory, use original string */
if ((th_ptr=(char * ) my_malloc(sizeof(char) * len,MYF(0))))
@@ -3853,8 +4174,11 @@ void Field_blob::store(const char *from,uint len)
}
}
#endif /* USE_TIS620 */
- value.copy(from,len);
- from=value.ptr();
+ if (from != value.ptr()) // For valgrind
+ {
+ value.copy(from, len);
+ from= value.ptr();
+ }
#ifdef USE_TIS620
my_free(th_ptr,MYF(MY_ALLOW_ZERO_PTR));
#endif
@@ -3867,14 +4191,14 @@ void Field_blob::store(const char *from,uint len)
void Field_blob::store(double nr)
{
value.set(nr);
- Field_blob::store(value.ptr(),value.length());
+ Field_blob::store(value.ptr(),(uint) value.length());
}
void Field_blob::store(longlong nr)
{
value.set(nr);
- Field_blob::store(value.ptr(),value.length());
+ Field_blob::store(value.ptr(), (uint) value.length());
}
@@ -3885,7 +4209,7 @@ double Field_blob::val_real(void)
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob)
return 0.0;
- ulong length=get_length(ptr);
+ uint32 length=get_length(ptr);
char save=blob[length]; // Ok to patch blob in NISAM
blob[length]=0;
@@ -3901,7 +4225,7 @@ longlong Field_blob::val_int(void)
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob)
return 0;
- ulong length=get_length(ptr);
+ uint32 length=get_length(ptr);
char save=blob[length]; // Ok to patch blob in NISAM
blob[length]=0;
@@ -3924,8 +4248,8 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
}
-int Field_blob::cmp(const char *a,ulong a_length, const char *b,
- ulong b_length)
+int Field_blob::cmp(const char *a,uint32 a_length, const char *b,
+ uint32 b_length)
{
int diff;
if (binary_flag)
@@ -3959,11 +4283,11 @@ int Field_blob::cmp_binary_offset(uint row_offset)
int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
- ulong max_length)
+ uint32 max_length)
{
char *a,*b;
uint diff;
- ulong a_length,b_length;
+ uint32 a_length,b_length;
memcpy_fixed(&a,a_ptr+packlength,sizeof(char*));
memcpy_fixed(&b,b_ptr+packlength,sizeof(char*));
a_length=get_length(a_ptr);
@@ -3982,13 +4306,15 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
void Field_blob::get_key_image(char *buff,uint length)
{
length-=HA_KEY_BLOB_LENGTH;
- ulong blob_length=get_length(ptr);
+ uint32 blob_length=get_length(ptr);
char *blob;
- if ((ulong) length > blob_length)
+ if ((uint32) length > blob_length)
{
-#ifdef HAVE_purify
+ /*
+ Must clear this as we do a memcmp in opt_range.cc to detect
+ identical keys
+ */
bzero(buff+2+blob_length, (length-blob_length));
-#endif
length=(uint) blob_length;
}
int2store(buff,length);
@@ -4078,7 +4404,7 @@ char *Field_blob::pack(char *to, const char *from, uint max_length)
{
char *save=ptr;
ptr=(char*) from;
- ulong length=get_length(); // Length of from string
+ uint32 length=get_length(); // Length of from string
if (length > max_length)
{
ptr=to;
@@ -4101,7 +4427,7 @@ char *Field_blob::pack(char *to, const char *from, uint max_length)
const char *Field_blob::unpack(char *to, const char *from)
{
memcpy(to,from,packlength);
- ulong length=get_length(from);
+ uint32 length=get_length(from);
from+=packlength;
if (length)
memcpy_fixed(to+packlength, &from, sizeof(from));
@@ -4110,60 +4436,6 @@ const char *Field_blob::unpack(char *to, const char *from)
return from+length;
}
-
-#ifdef HAVE_GEMINI_DB
-/* Blobs in Gemini tables are stored separately from the rows which contain
-** them (except for tiny blobs, which are stored in the row). For all other
-** blob types (blob, mediumblob, longblob), the row contains the length of
-** the blob data and a blob id. These methods (pack_id, get_id, and
-** unpack_id) handle packing and unpacking blob fields in Gemini rows.
-*/
-char *Field_blob::pack_id(char *to, const char *from, ulonglong id, uint max_length)
-{
- char *save=ptr;
- ptr=(char*) from;
- ulong length=get_length(); // Length of from string
- if (length > max_length)
- {
- ptr=to;
- length=max_length;
- store_length(length); // Store max length
- ptr=(char*) from;
- }
- else
- memcpy(to,from,packlength); // Copy length
- if (length)
- {
- int8store(to+packlength, id);
- }
- ptr=save; // Restore org row pointer
- return to+packlength+sizeof(id);
-}
-
-
-ulonglong Field_blob::get_id(const char *from)
-{
- ulonglong id = 0;
- ulong length=get_length(from);
- if (length)
- id=uint8korr(from+packlength);
- return id;
-}
-
-
-const char *Field_blob::unpack_id(char *to, const char *from, const char *bdata)
-{
- memcpy(to,from,packlength);
- ulong length=get_length(from);
- from+=packlength;
- if (length)
- memcpy_fixed(to+packlength, &bdata, sizeof(bdata));
- else
- bzero(to+packlength,sizeof(bdata));
- return from+sizeof(ulonglong);
-}
-#endif /* HAVE_GEMINI_DB */
-
/* Keys for blobs are like keys on varchars */
int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
@@ -4220,7 +4492,7 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length)
{
char *save=ptr;
ptr=(char*) from;
- ulong length=get_length(); // Length of from string
+ uint32 length=get_length(); // Length of from string
if (length > max_length)
length=max_length;
*to++= (uchar) length;
@@ -4243,20 +4515,20 @@ char *Field_blob::pack_key_from_key_image(char *to, const char *from,
uint length=uint2korr(from);
if (length > max_length)
length=max_length;
- *to++= (length & 255);
+ *to++= (char) (length & 255);
if (max_length > 255)
- *to++= (uchar) (length >> 8);
+ *to++= (char) (length >> 8);
if (length)
memcpy(to, from+2, length);
return to+length;
}
-uint Field_blob::packed_col_length(const char *ptr, uint length)
+uint Field_blob::packed_col_length(const char *data_ptr, uint length)
{
if (length > 255)
- return uint2korr(ptr)+2;
+ return uint2korr(data_ptr)+2;
else
- return (uint) ((uchar) *ptr)+1;
+ return (uint) ((uchar) *data_ptr)+1;
}
uint Field_blob::max_packed_col_length(uint max_length)
@@ -4347,7 +4619,7 @@ void Field_enum::store(const char *from,uint length)
uint tmp=find_enum(typelib,from,length);
if (!tmp)
{
- if (length < 6) // Can't be more than 99999 enums
+ if (length < 6) // Can't be more than 99999 enums
{
/* This is for reading numbers with LOAD DATA INFILE */
char buff[7], *end;
@@ -4358,7 +4630,7 @@ void Field_enum::store(const char *from,uint length)
conv=buff;
}
my_errno=0;
- tmp=strtoul(conv,&end,10);
+ tmp=(uint) strtoul(conv,&end,10);
if (my_errno || end != conv+length || tmp > typelib->count)
{
tmp=0;
@@ -4445,7 +4717,7 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
{
uint tmp=(uint) Field_enum::val_int();
if (!tmp || tmp > typelib->count)
- val_ptr->length(0);
+ val_ptr->set("",0);
else
val_ptr->set((const char*) typelib->type_names[tmp-1],
(uint) strlen(typelib->type_names[tmp-1]));
@@ -4517,7 +4789,7 @@ ulonglong find_set(TYPELIB *lib,const char *x,uint length)
for (;;)
{
const char *pos=start;
- for ( ; pos != end && *pos != field_separator ; pos++) ;
+ for (; pos != end && *pos != field_separator ; pos++) ;
uint find=find_enum(lib,start,(uint) (pos-start));
if (!find)
error=1;
@@ -4628,7 +4900,7 @@ bool Field_enum::eq_def(Field *field)
if (!Field::eq_def(field))
return 0;
TYPELIB *from_lib=((Field_enum*) field)->typelib;
-
+
if (typelib->count < from_lib->count)
return 0;
for (uint i=0 ; i < from_lib->count ; i++)
@@ -4638,7 +4910,7 @@ bool Field_enum::eq_def(Field *field)
}
bool Field_num::eq_def(Field *field)
-{
+{
if (!Field::eq_def(field))
return 0;
Field_num *from_num= (Field_num*) field;
@@ -4656,7 +4928,7 @@ bool Field_num::eq_def(Field *field)
*****************************************************************************/
/*
-** Make a field from the .frm file info
+ Make a field from the .frm file info
*/
uint32 calc_pack_length(enum_field_types type,uint32 length)
@@ -4685,6 +4957,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length)
case FIELD_TYPE_LONG_BLOB: return 4+portable_sizeof_char_ptr;
case FIELD_TYPE_SET:
case FIELD_TYPE_ENUM: abort(); return 0; // This shouldn't happen
+ default: return 0;
}
return 0; // This shouldn't happen
}
@@ -4704,8 +4977,9 @@ uint pack_length_to_packflag(uint type)
Field *make_field(char *ptr, uint32 field_length,
- uchar *null_pos, uint null_bit,
+ uchar *null_pos, uchar null_bit,
uint pack_flag,
+ enum_field_types field_type,
Field::utype unireg_check,
TYPELIB *interval,
const char *field_name,
@@ -4731,6 +5005,9 @@ Field *make_field(char *ptr, uint32 field_length,
return new Field_blob(ptr,null_pos,null_bit,
unireg_check, field_name, table,
pack_length,f_is_binary(pack_flag) != 0);
+ if (f_is_geom(pack_flag))
+ return 0;
+
if (interval)
{
if (f_is_enum(pack_flag))
@@ -4744,7 +5021,7 @@ Field *make_field(char *ptr, uint32 field_length,
}
}
- switch ((enum enum_field_types) f_packtype(pack_flag)) {
+ switch (field_type) {
case FIELD_TYPE_DECIMAL:
return new Field_decimal(ptr,field_length,null_pos,null_bit,
unireg_check, field_name, table,
@@ -4807,10 +5084,11 @@ Field *make_field(char *ptr, uint32 field_length,
return new Field_datetime(ptr,null_pos,null_bit,
unireg_check, field_name, table);
case FIELD_TYPE_NULL:
- default: // Impossible (Wrong version)
return new Field_null(ptr,field_length,unireg_check,field_name,table);
+ default: // Impossible (Wrong version)
+ break;
}
- return 0; // Impossible (Wrong version)
+ return 0; // Impossible
}
@@ -4842,8 +5120,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
interval=0;
def=0;
if (!old_field->is_real_null() && ! (flags & BLOB_FLAG) &&
- old_field->type() != FIELD_TYPE_TIMESTAMP && old_field->ptr &&
- orig_field)
+ old_field->ptr && orig_field)
{
char buff[MAX_FIELD_WIDTH],*pos;
String tmp(buff,sizeof(buff));
diff --git a/sql/field.h b/sql/field.h
index fb3cf2178e2..6f049e3809e 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1,23 +1,23 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
-** Because of the function new_field all field classes that have static
-** variables must declare the size_of() member function.
+ Because of the function new_field() all field classes that have static
+ variables must declare the size_of() member function.
*/
#ifdef __GNUC__
@@ -31,27 +31,28 @@ struct st_cache_field;
void field_conv(Field *to,Field *from);
class Field {
- Field(const Item &); /* Prevent use of theese */
+ Field(const Item &); /* Prevent use of these */
void operator=(Field &);
public:
static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
static void operator delete(void *ptr_arg, size_t size) {} /*lint -e715 */
- enum utype { NONE,DATE,SHIELD,NOEMPTY,CASEUP,PNR,BGNR,PGNR,YES,NO,REL,
- CHECK,EMPTY,UNKNOWN_FIELD,CASEDN,NEXT_NUMBER,INTERVAL_FIELD,
- BIT_FIELD, TIMESTAMP_FIELD,CAPITALIZE,BLOB_FIELD};
- char *ptr; // Position to field in record
+ char *ptr; // Position to field in record
uchar *null_ptr; // Byte where null_bit is
- uint8 null_bit; // And position to it
struct st_table *table; // Pointer for table
- ulong query_id; // For quick test of used fields
- key_map key_start,part_of_key,part_of_sortkey;// Field is part of these keys.
- const char *table_name,*field_name;
- utype unireg_check;
- uint32 field_length; // Length of field
- uint16 flags;
-
- Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,uint null_bit_arg,
+ const char *table_name,*field_name;
+ ulong query_id; // For quick test of used fields
+ /* Field is part of the following keys */
+ key_map key_start,part_of_key,part_of_sortkey;
+ enum utype { NONE,DATE,SHIELD,NOEMPTY,CASEUP,PNR,BGNR,PGNR,YES,NO,REL,
+ CHECK,EMPTY,UNKNOWN_FIELD,CASEDN,NEXT_NUMBER,INTERVAL_FIELD,
+ BIT_FIELD, TIMESTAMP_FIELD,CAPITALIZE,BLOB_FIELD};
+ utype unireg_check;
+ uint32 field_length; // Length of field
+ uint16 flags;
+ uchar null_bit; // Bit used to test null bit
+
+ Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg);
virtual ~Field() {}
@@ -69,6 +70,15 @@ public:
virtual uint32 pack_length() const { return (uint32) field_length; }
virtual void reset(void) { bzero(ptr,pack_length()); }
virtual void reset_fields() {}
+ virtual void set_default()
+ {
+ my_ptrdiff_t offset = (my_ptrdiff_t) (table->record[2] -
+ table->record[0]);
+ memcpy(ptr, ptr + offset, pack_length());
+ if (null_ptr)
+ *null_ptr= ((*null_ptr & (uchar) ~null_bit) |
+ null_ptr[offset] & null_bit);
+ }
virtual bool binary() const { return 1; }
virtual bool zero_pack() const { return 1; }
virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
@@ -77,7 +87,7 @@ public:
virtual enum_field_types real_type() const { return type(); }
inline int cmp(const char *str) { return cmp(ptr,str); }
virtual int cmp(const char *,const char *)=0;
- virtual int cmp_binary(const char *a,const char *b, ulong max_length=~0L)
+ virtual int cmp_binary(const char *a,const char *b, uint32 max_length=~0L)
{ return memcmp(a,b,pack_length()); }
virtual int cmp_offset(uint row_offset)
{ return memcmp(ptr,ptr+row_offset,pack_length()); }
@@ -88,12 +98,13 @@ public:
virtual int key_cmp(const byte *str, uint length)
{ return cmp(ptr,(char*) str); }
virtual uint decimals() const { return 0; }
+ /*
+ Caller beware: sql_type can change str.Ptr, so check
+ ptr() to see if it changed if you are using your own buffer
+ in str and restore it with set() if needed
+ */
virtual void sql_type(String &str) const =0;
- // Caller beware: sql_type can change str.Ptr, so check
- // ptr() to see if it changed if you are using your own buffer
- // in str and restore it with set() if needed
-
- virtual uint size_of() const =0; // For new field
+ virtual uint size_of() const =0; // For new field
inline bool is_null(uint row_offset=0)
{ return null_ptr ? (null_ptr[row_offset] & null_bit ? 1 : 0) : table->null_row; }
inline bool is_real_null(uint row_offset=0)
@@ -101,30 +112,32 @@ public:
inline void set_null(int row_offset=0)
{ if (null_ptr) null_ptr[row_offset]|= null_bit; }
inline void set_notnull(int row_offset=0)
- { if (null_ptr) null_ptr[row_offset]&= ~null_bit; }
+ { if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; }
inline bool maybe_null(void) { return null_ptr != 0 || table->maybe_null; }
inline bool real_maybe_null(void) { return null_ptr != 0; }
virtual void make_field(Send_field *)=0;
virtual void sort_string(char *buff,uint length)=0;
- virtual bool optimize_range();
+ virtual bool optimize_range(uint idx);
virtual bool store_for_compare() { return 0; }
- inline Field *new_field(struct st_table *new_table)
- {
- Field *tmp= (Field*) sql_memdup((char*) this,size_of());
- if (tmp)
- {
- tmp->table=new_table;
- tmp->key_start=tmp->part_of_key=tmp->part_of_sortkey=0;
- tmp->unireg_check=Field::NONE;
- tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
- tmp->reset_fields();
- }
- return tmp;
- }
- inline void move_field(char *ptr_arg,uchar *null_ptr_arg,uint null_bit_arg)
+ Field *new_field(MEM_ROOT *root, struct st_table *new_table)
+ {
+ Field *tmp= (Field*) memdup_root(root,(char*) this,size_of());
+ if (tmp)
{
- ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
+ if (tmp->table->maybe_null)
+ tmp->flags&= ~NOT_NULL_FLAG;
+ tmp->table=new_table;
+ tmp->key_start=tmp->part_of_key=tmp->part_of_sortkey=0;
+ tmp->unireg_check=Field::NONE;
+ tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
+ tmp->reset_fields();
}
+ return tmp;
+ }
+ inline void move_field(char *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
+ {
+ ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
+ }
inline void move_field(char *ptr_arg) { ptr=ptr_arg; }
inline void move_field(my_ptrdiff_t ptr_diff)
{
@@ -154,10 +167,10 @@ public:
ptr-=row_offset;
return tmp;
}
- bool send(String *packet);
+ bool send(THD *thd, String *packet);
virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0)
{
- uint length=pack_length();
+ uint32 length=pack_length();
memcpy(to,from,length);
return to+length;
}
@@ -185,7 +198,7 @@ public:
{ return cmp(a,b); }
virtual int pack_cmp(const char *b, uint key_length_arg)
{ return cmp(ptr,b); }
- uint offset(); // Should be inline ...
+ uint offset(); // Should be inline ...
void copy_from_tmp(int offset);
uint fill_cache_field(struct st_cache_field *copy);
virtual bool get_date(TIME *ltime,bool fuzzydate);
@@ -210,12 +223,12 @@ public:
class Field_num :public Field {
public:
const uint8 dec;
- bool zerofill,unsigned_flag; // Purify cannot handle bit fields
+ bool zerofill,unsigned_flag; // Purify cannot handle bit fields
Field_num(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg, utype unireg_check_arg,
+ uchar null_bit_arg, utype unireg_check_arg,
const char *field_name_arg,
struct st_table *table_arg,
- uint dec_arg,bool zero_arg,bool unsigned_arg)
+ uint8 dec_arg,bool zero_arg,bool unsigned_arg)
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg),
dec(dec_arg),zerofill(zero_arg),unsigned_flag(unsigned_arg)
@@ -230,7 +243,7 @@ public:
void add_zerofill_and_unsigned(String &res) const;
friend class create_field;
void make_field(Send_field *);
- uint decimals() const { return dec; }
+ uint decimals() const { return (uint) dec; }
uint size_of() const { return sizeof(*this); }
bool eq_def(Field *field);
};
@@ -239,7 +252,7 @@ public:
class Field_str :public Field {
public:
Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg, utype unireg_check_arg,
+ uchar null_bit_arg, utype unireg_check_arg,
const char *field_name_arg,
struct st_table *table_arg)
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
@@ -256,10 +269,10 @@ public:
class Field_decimal :public Field_num {
public:
Field_decimal(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
- uint dec_arg,bool zero_arg,bool unsigned_arg)
+ uint8 dec_arg,bool zero_arg,bool unsigned_arg)
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg,
dec_arg, zero_arg,unsigned_arg)
@@ -285,7 +298,7 @@ public:
class Field_tiny :public Field_num {
public:
Field_tiny(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
bool zero_arg, bool unsigned_arg)
@@ -314,7 +327,7 @@ public:
class Field_short :public Field_num {
public:
Field_short(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
bool zero_arg, bool unsigned_arg)
@@ -343,7 +356,7 @@ public:
class Field_medium :public Field_num {
public:
Field_medium(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
bool zero_arg, bool unsigned_arg)
@@ -372,7 +385,7 @@ public:
class Field_long :public Field_num {
public:
Field_long(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
bool zero_arg, bool unsigned_arg)
@@ -407,7 +420,7 @@ public:
class Field_longlong :public Field_num {
public:
Field_longlong(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
bool zero_arg, bool unsigned_arg)
@@ -415,10 +428,11 @@ public:
unireg_check_arg, field_name_arg, table_arg,
0, zero_arg,unsigned_arg)
{}
- Field_longlong(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
- struct st_table *table_arg)
+ Field_longlong(uint32 len_arg,bool maybe_null_arg,
+ const char *field_name_arg,
+ struct st_table *table_arg, bool unsigned_arg)
:Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, table_arg,0,0,0)
+ NONE, field_name_arg, table_arg,0,0,unsigned_arg)
{}
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types type() const { return FIELD_TYPE_LONGLONG;}
@@ -435,16 +449,17 @@ public:
void sort_string(char *buff,uint length);
uint32 pack_length() const { return 8; }
void sql_type(String &str) const;
+ bool store_for_compare() { return 1; }
};
#endif
class Field_float :public Field_num {
public:
Field_float(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
- uint dec_arg,bool zero_arg,bool unsigned_arg)
+ uint8 dec_arg,bool zero_arg,bool unsigned_arg)
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg,
dec_arg, zero_arg,unsigned_arg)
@@ -468,16 +483,16 @@ public:
class Field_double :public Field_num {
public:
Field_double(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,
- uint dec_arg,bool zero_arg,bool unsigned_arg)
+ uint8 dec_arg,bool zero_arg,bool unsigned_arg)
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg,
dec_arg, zero_arg,unsigned_arg)
{}
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
- struct st_table *table_arg, uint dec_arg)
+ struct st_table *table_arg, uint8 dec_arg)
:Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0,
NONE, field_name_arg, table_arg,dec_arg,0,0)
{}
@@ -530,7 +545,7 @@ public:
Field_timestamp(char *ptr_arg, uint32 len_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg);
- enum Item_result result_type () const { return field_length == 8 || field_length == 14 ? INT_RESULT : STRING_RESULT; }
+ enum Item_result result_type () const;
enum_field_types type() const { return FIELD_TYPE_TIMESTAMP;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
void store(const char *to,uint length);
@@ -547,6 +562,13 @@ public:
bool store_for_compare() { return 1; }
bool zero_pack() const { return 0; }
void set_time();
+ virtual void set_default()
+ {
+ if (table->timestamp_field == this)
+ set_time();
+ else
+ Field::set_default();
+ }
inline long get_timestamp()
{
#ifdef WORDS_BIGENDIAN
@@ -560,13 +582,14 @@ public:
void fill_and_store(char *from,uint len);
bool get_date(TIME *ltime,bool fuzzydate);
bool get_time(TIME *ltime);
+ void make_field(Send_field *field);
};
class Field_year :public Field_tiny {
public:
Field_year(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
@@ -580,17 +603,22 @@ public:
longlong val_int(void);
String *val_str(String*,String *);
void sql_type(String &str) const;
+ bool store_for_compare() { return 1; }
};
class Field_date :public Field_str {
public:
- Field_date(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
+ Field_date(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg)
{}
+ Field_date(bool maybe_null_arg, const char *field_name_arg,
+ struct st_table *table_arg)
+ :Field_str((char*) 0,10, maybe_null_arg ? (uchar*) "": 0,0,
+ NONE, field_name_arg, table_arg) {}
enum_field_types type() const { return FIELD_TYPE_DATE;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
enum Item_result cmp_type () const { return INT_RESULT; }
@@ -611,7 +639,7 @@ public:
class Field_newdate :public Field_str {
public:
- Field_newdate(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
+ Field_newdate(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
@@ -642,12 +670,16 @@ public:
class Field_time :public Field_str {
public:
- Field_time(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
+ Field_time(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_str(ptr_arg, 8, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg)
{}
+ Field_time(bool maybe_null_arg, const char *field_name_arg,
+ struct st_table *table_arg)
+ :Field_str((char*) 0,8, maybe_null_arg ? (uchar*) "": 0,0,
+ NONE, field_name_arg, table_arg) {}
enum_field_types type() const { return FIELD_TYPE_TIME;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
enum Item_result cmp_type () const { return INT_RESULT; }
@@ -670,12 +702,16 @@ public:
class Field_datetime :public Field_str {
public:
- Field_datetime(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
+ Field_datetime(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg)
:Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg)
{}
+ Field_datetime(bool maybe_null_arg, const char *field_name_arg,
+ struct st_table *table_arg)
+ :Field_str((char*) 0,19, maybe_null_arg ? (uchar*) "": 0,0,
+ NONE, field_name_arg, table_arg) {}
enum_field_types type() const { return FIELD_TYPE_DATETIME;}
#ifdef HAVE_LONG_LONG
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
@@ -704,7 +740,7 @@ class Field_string :public Field_str {
bool binary_flag;
public:
Field_string(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,bool binary_arg)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
@@ -759,7 +795,7 @@ class Field_varstring :public Field_str {
bool binary_flag;
public:
Field_varstring(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,bool binary_arg)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
@@ -767,9 +803,10 @@ public:
binary_flag(binary_arg)
{
if (binary_arg)
- flags|=BINARY_FLAG;
+ flags|= BINARY_FLAG;
}
- Field_varstring(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
+ Field_varstring(uint32 len_arg,bool maybe_null_arg,
+ const char *field_name_arg,
struct st_table *table_arg, bool binary_arg)
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, table_arg),
@@ -809,10 +846,10 @@ public:
class Field_blob :public Field_str {
uint packlength;
- String value; // For temporaries
+ String value; // For temporaries
bool binary_flag;
public:
- Field_blob(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
+ Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,uint blob_pack_length,
bool binary_arg);
@@ -824,7 +861,7 @@ public:
{
flags|= BLOB_FLAG;
if (binary_arg)
- flags|=BINARY_FLAG;
+ flags|= BINARY_FLAG;
}
enum_field_types type() const { return FIELD_TYPE_BLOB;}
enum ha_base_keytype key_type() const
@@ -836,21 +873,22 @@ public:
longlong val_int(void);
String *val_str(String*,String *);
int cmp(const char *,const char*);
- int cmp(const char *a, ulong a_length, const char *b, ulong b_length);
+ int cmp(const char *a, uint32 a_length, const char *b, uint32 b_length);
int cmp_offset(uint offset);
- int cmp_binary(const char *a,const char *b, ulong max_length=~0L);
+ int cmp_binary(const char *a,const char *b, uint32 max_length=~0L);
int cmp_binary_offset(uint row_offset);
int key_cmp(const byte *,const byte*);
int key_cmp(const byte *str, uint length);
uint32 key_length() const { return 0; }
void sort_string(char *buff,uint length);
- uint32 pack_length() const { return (uint32) (packlength+table->blob_ptr_size); }
- void reset(void) { bzero(ptr,packlength+sizeof(char*)); }
+ uint32 pack_length() const
+ { return (uint32) (packlength+table->blob_ptr_size); }
+ void reset(void) { bzero(ptr, packlength+sizeof(char*)); }
void reset_fields() { bzero((char*) &value,sizeof(value)); }
- void store_length(ulong number);
- inline ulong get_length(uint row_offset=0)
+ void store_length(uint32 number);
+ inline uint32 get_length(uint row_offset=0)
{ return get_length(ptr+row_offset); }
- ulong get_length(const char *ptr);
+ uint32 get_length(const char *ptr);
bool binary() const { return binary_flag; }
inline void get_ptr(char **str)
{
@@ -861,7 +899,7 @@ public:
memcpy(ptr,length,packlength);
memcpy_fixed(ptr+packlength,&data,sizeof(char*));
}
- inline void set_ptr(ulong length,char *data)
+ inline void set_ptr(uint32 length,char *data)
{
store_length(length);
memcpy_fixed(ptr+packlength,&data,sizeof(char*));
@@ -882,21 +920,6 @@ public:
}
char *pack(char *to, const char *from, uint max_length= ~(uint) 0);
const char *unpack(char *to, const char *from);
-#ifdef HAVE_GEMINI_DB
- char *pack_id(char *to, const char *from, ulonglong id,
- uint max_length= ~(uint) 0);
- ulonglong get_id(const char *from);
- const char *unpack_id(char *to, const char *from, const char *bdata);
- inline void get_ptr_from_key_image(char **str,char *key_str)
- {
- *str = key_str + sizeof(uint16);
- }
- inline uint get_length_from_key_image(char *key_str)
- {
- return uint2korr(key_str);
- }
- enum_field_types blobtype() { return (packlength == 1 ? FIELD_TYPE_TINY_BLOB : FIELD_TYPE_BLOB);}
-#endif
char *pack_key(char *to, const char *from, uint max_length);
char *pack_key_from_key_image(char* to, const char *from, uint max_length);
int pack_cmp(const char *a, const char *b, uint key_length);
@@ -916,16 +939,16 @@ protected:
public:
TYPELIB *typelib;
Field_enum(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,uint packlength_arg,
TYPELIB *typelib_arg)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg),
packlength(packlength_arg),typelib(typelib_arg)
- {
+ {
flags|=ENUM_FLAG;
- }
+ }
enum_field_types type() const { return FIELD_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const;
@@ -944,7 +967,7 @@ public:
uint size_of() const { return sizeof(*this); }
enum_field_types real_type() const { return FIELD_TYPE_ENUM; }
virtual bool zero_pack() const { return 0; }
- bool optimize_range() { return 0; }
+ bool optimize_range(uint idx) { return 0; }
bool binary() const { return 0; }
bool eq_def(Field *field);
};
@@ -953,7 +976,7 @@ public:
class Field_set :public Field_enum {
public:
Field_set(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uint null_bit_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,uint32 packlength_arg,
TYPELIB *typelib_arg)
@@ -975,23 +998,23 @@ public:
/*
-** Create field class for CREATE TABLE
+ Create field class for CREATE TABLE
*/
class create_field :public Sql_alloc {
public:
const char *field_name;
- const char *change; // If done with alter table
- const char *after; // Put column after this one
- Item *def; // Default value
+ const char *change; // If done with alter table
+ const char *after; // Put column after this one
+ Item *def; // Default value
enum enum_field_types sql_type;
uint32 length;
uint decimals,flags,pack_length;
Field::utype unireg_check;
- TYPELIB *interval; // Which interval to use
- Field *field; // For alter table
+ TYPELIB *interval; // Which interval to use
+ Field *field; // For alter table
- uint8 row,col,sc_length,interval_id; // For rea_create_table
+ uint8 row,col,sc_length,interval_id; // For rea_create_table
uint offset,pack_flag;
create_field() :after(0) {}
create_field(Field *field, Field *orig_field);
@@ -999,7 +1022,7 @@ public:
/*
-** A class for sending info to the client
+ A class for sending info to the client
*/
class Send_field {
@@ -1012,7 +1035,7 @@ class Send_field {
/*
-** A class for quick copying data to fields
+ A class for quick copying data to fields
*/
class Copy_field :public Sql_alloc {
@@ -1028,7 +1051,7 @@ public:
Copy_field() {}
~Copy_field() {}
- void set(Field *to,Field *from,bool save); // Field to field
+ void set(Field *to,Field *from,bool save); // Field to field
void set(char *to,Field *from); // Field to string
void (*do_copy)(Copy_field *);
void (*do_copy2)(Copy_field *); // Used to handle null values
@@ -1036,30 +1059,33 @@ public:
Field *make_field(char *ptr, uint32 field_length,
- uchar *null_pos, uint null_bit,
- uint pack_flag, Field::utype unireg_check,
+ uchar *null_pos, uchar null_bit,
+ uint pack_flag,
+ enum_field_types field_type,
+ Field::utype unireg_check,
TYPELIB *interval, const char *field_name,
struct st_table *table);
uint pack_length_to_packflag(uint type);
uint32 calc_pack_length(enum_field_types type,uint32 length);
bool set_field_to_null(Field *field);
-bool set_field_to_null_with_conversions(Field *field);
+bool set_field_to_null_with_conversions(Field *field, bool no_conversions);
uint find_enum(TYPELIB *typelib,const char *x, uint length);
ulonglong find_set(TYPELIB *typelib,const char *x, uint length);
bool test_if_int(const char *str,int length);
/*
-** The following are for the interface with the .frm file
+ The following are for the interface with the .frm file
*/
#define FIELDFLAG_DECIMAL 1
-#define FIELDFLAG_BINARY 1 // Shares same flag
+#define FIELDFLAG_BINARY 1 // Shares same flag
#define FIELDFLAG_NUMBER 2
#define FIELDFLAG_ZEROFILL 4
#define FIELDFLAG_PACK 120 // Bits used for packing
#define FIELDFLAG_INTERVAL 256
#define FIELDFLAG_BITFIELD 512 // mangled with dec!
#define FIELDFLAG_BLOB 1024 // mangled with dec!
+#define FIELDFLAG_GEOM 2048
#define FIELDFLAG_LEFT_FULLSCREEN 8192
#define FIELDFLAG_RIGHT_FULLSCREEN 16384
#define FIELDFLAG_FORMAT_NUMBER 16384 // predit: ###,,## in output
@@ -1080,12 +1106,13 @@ bool test_if_int(const char *str,int length);
#define f_is_zerofill(x) ((x) & FIELDFLAG_ZEROFILL)
#define f_is_packed(x) ((x) & FIELDFLAG_PACK)
#define f_packtype(x) (((x) >> FIELDFLAG_PACK_SHIFT) & 15)
-#define f_decimals(x) (((x) >> FIELDFLAG_DEC_SHIFT) & FIELDFLAG_MAX_DEC)
+#define f_decimals(x) ((uint8) (((x) >> FIELDFLAG_DEC_SHIFT) & FIELDFLAG_MAX_DEC))
#define f_is_alpha(x) (!f_is_num(x))
#define f_is_binary(x) ((x) & FIELDFLAG_BINARY)
#define f_is_enum(x) ((x) & FIELDFLAG_INTERVAL)
#define f_is_bitfield(x) ((x) & FIELDFLAG_BITFIELD)
#define f_is_blob(x) (((x) & (FIELDFLAG_BLOB | FIELDFLAG_NUMBER)) == FIELDFLAG_BLOB)
+#define f_is_geom(x) ((x) & FIELDFLAG_GEOM)
#define f_is_equ(x) ((x) & (1+2+FIELDFLAG_PACK+31*256))
#define f_settype(x) (((int) x) << FIELDFLAG_PACK_SHIFT)
#define f_maybe_null(x) (x & FIELDFLAG_MAYBE_NULL)
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index dab96a9b827..db0cc71c6bf 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000-2003 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -118,12 +118,39 @@ set_field_to_null(Field *field)
field->reset();
return 0;
}
+ field->reset();
+ if (current_thd->count_cuted_fields)
+ {
+ current_thd->cuted_fields++; // Increment error counter
+ return 0;
+ }
+ if (!current_thd->no_errors)
+ my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0),
+ field->field_name);
return 1;
}
+/*
+ Set field to NULL or TIMESTAMP or to next auto_increment number
+
+ SYNOPSIS
+ set_field_to_null_with_conversions()
+ field Field to update
+ no_conversion Set to 1 if we should return 1 if field can't
+ take null values.
+ If set to 0 we will do store the 'default value'
+ if the field is a special field. If not we will
+ give an error.
+
+ RETURN VALUES
+ 0 Field could take 0 or an automatic conversion was used
+ 1 Field could not take NULL and no conversion was used.
+ If no_conversion was not set, an error message is printed
+*/
+
bool
-set_field_to_null_with_conversions(Field *field)
+set_field_to_null_with_conversions(Field *field, bool no_conversions)
{
if (field->real_maybe_null())
{
@@ -131,6 +158,8 @@ set_field_to_null_with_conversions(Field *field)
field->reset();
return 0;
}
+ if (no_conversions)
+ return 1;
/*
Check if this is a special type, which will get a special walue
@@ -156,8 +185,6 @@ set_field_to_null_with_conversions(Field *field)
}
-
-
static void do_skip(Copy_field *copy __attribute__((unused)))
{
}
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 029d9b1212f..ae6895b26b9 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -22,13 +22,11 @@
#include <stddef.h> /* for macro offsetof */
#endif
#include <m_ctype.h>
+#include "sql_sort.h"
+
#ifndef THREAD
-#define SKIPP_DBUG_IN_FILESORT
+#define SKIP_DBUG_IN_FILESORT
#endif
- /* static variabels */
-
-#define MERGEBUFF 7
-#define MERGEBUFF2 15
/* How to write record_ref. */
@@ -36,85 +34,86 @@
if (my_b_write((file),(byte*) (from),param->ref_length)) \
DBUG_RETURN(1);
-typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
- my_off_t file_pos; /* Where we are in the sort file */
- uchar *base,*key; /* key pointers */
- ha_rows count; /* Number of rows in table */
- ulong mem_count; /* numbers of keys in memory */
- ulong max_keys; /* Max keys in buffert */
-} BUFFPEK;
-
-
-typedef struct st_sort_param {
- uint sort_length; /* Length of sortarg */
- uint keys; /* Max antal nycklar / buffert */
- uint ref_length; /* Length of record ref. */
- ha_rows max_rows,examined_rows;
- TABLE *sort_form; /* For quicker make_sortkey */
- SORT_FIELD *local_sortorder;
- SORT_FIELD *end;
-#ifdef USE_STRCOLL
- char* tmp_buffer;
-#endif
-} SORTPARAM;
-
/* functions defined in this file */
static char **make_char_array(register uint fields, uint length, myf my_flag);
+static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffer_file, uint count);
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
- uchar * *sort_keys,
- BUFFPEK *buffpek,uint *maxbuffer,
+ uchar * *sort_keys, IO_CACHE *buffer_file,
IO_CACHE *tempfile,IO_CACHE *indexfile);
static int write_keys(SORTPARAM *param,uchar * *sort_keys,
- uint count,BUFFPEK *buffpek,
- IO_CACHE *tempfile);
-static void make_sortkey(SORTPARAM *param,uchar *to,
- byte *ref_pos);
-static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count);
-static int merge_many_buff(SORTPARAM *param,uchar * *sort_keys,
- BUFFPEK *buffpek,
- uint *maxbuffer, IO_CACHE *t_file);
-static uint read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
- uint sort_length);
-static int merge_buffers(SORTPARAM *param,IO_CACHE *from_file,
- IO_CACHE *to_file,uchar * *sort_keys,
- BUFFPEK *lastbuff,BUFFPEK *Fb,
- BUFFPEK *Tb,int flag);
-static int merge_index(SORTPARAM *param,uchar * *sort_keys,
+ uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
+static void make_sortkey(SORTPARAM *param,uchar *to, byte *ref_pos);
+static int merge_index(SORTPARAM *param,uchar *sort_buffer,
BUFFPEK *buffpek,
uint maxbuffer,IO_CACHE *tempfile,
IO_CACHE *outfile);
+static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count);
static uint sortlength(SORT_FIELD *sortorder,uint length);
- /* Makes a indexfil of recordnumbers of a sorted database */
- /* outfile is reset before data is written to it, if it wasn't
- open a new file is opened */
+/*
+ Sort a table
+
+ SYNOPSIS
+ filesort()
+ table Table to sort
+ sortorder How to sort the table
+ s_length Number of elements in sortorder
+ select condition to apply to the rows
+ special Not used.
+ (This could be used to sort the rows pointed on by
+ select->file)
+ examined_rows Store number of examined rows here
+
+ IMPLEMENTATION
+ Creates a set of pointers that can be used to read the rows
+ in sorted order. This should be done with the functions
+ in records.cc
+
+ REQUIREMENTS
+ Before calling filesort, one must have done
+ table->file->info(HA_STATUS_VARIABLE)
+
+ RETURN
+ HA_POS_ERROR Error
+ # Number of rows
+
+ examined_rows will be set to number of examined rows
+
+ The result set is stored in table->io_cache or
+ table->record_pointers
+*/
-ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
+ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
SQL_SELECT *select, ha_rows special, ha_rows max_rows,
ha_rows *examined_rows)
{
int error;
- uint memavl,old_memavl,min_sort_memory,maxbuffer,skr;
+ ulong memavl, min_sort_memory;
+ uint maxbuffer;
BUFFPEK *buffpek;
ha_rows records;
uchar **sort_keys;
- IO_CACHE tempfile,*selected_records_file,*outfile;
+ IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
SORTPARAM param;
+ THD *thd= current_thd;
+
DBUG_ENTER("filesort");
- DBUG_EXECUTE("info",TEST_filesort(table,sortorder,s_length,special););
-#ifdef SKIPP_DBUG_IN_FILESORT
+ DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length,special););
+#ifdef SKIP_DBUG_IN_FILESORT
DBUG_PUSH(""); /* No DBUG here */
#endif
- outfile= table[0]->io_cache;
+ outfile= table->io_cache;
my_b_clear(&tempfile);
- buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1;
- maxbuffer=1;
- param.ref_length= table[0]->file->ref_length;
+ my_b_clear(&buffpek_pointers);
+ buffpek=0;
+ sort_keys= (uchar **) NULL;
+ error= 1;
+ bzero((char*) &param,sizeof(param));
+ param.ref_length= table->file->ref_length;
param.sort_length=sortlength(sortorder,s_length)+ param.ref_length;
param.max_rows= max_rows;
- param.examined_rows=0;
if (select && select->quick)
{
@@ -139,21 +138,16 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
#ifdef CAN_TRUST_RANGE
else if (select && select->quick && select->quick->records > 0L)
{
- /* Get record-count */
- table[0]->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
- table[0]->file->records)+EXTRA_RECORDS;
+ table->file->records)+EXTRA_RECORDS;
selected_records_file=0;
}
#endif
else
{
- table[0]->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);/* Get record-count */
- records=table[0]->file->estimate_number_of_rows();
+ records=table->file->estimate_number_of_rows();
selected_records_file= 0;
}
- if (param.sort_length == param.ref_length && records > param.max_rows)
- records=param.max_rows; /* purecov: inspected */
#ifdef USE_STRCOLL
if (use_strcoll(default_charset_info) &&
@@ -161,55 +155,39 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
goto err;
#endif
- memavl=sortbuff_size;
+ memavl= thd->variables.sortbuff_size;
min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
while (memavl >= min_sort_memory)
{
- if ((ulonglong) (records+1)*(param.sort_length+sizeof(char*))+sizeof(BUFFPEK)*10 <
- (ulonglong) memavl)
- param.keys=(uint) records+1;
- else
- {
- maxbuffer=1;
- do
- {
- skr=maxbuffer;
- if (memavl < sizeof(BUFFPEK)*maxbuffer)
- {
- my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
- goto err;
- }
- param.keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
- (param.sort_length+sizeof(char*));
- }
- while ((maxbuffer= (uint) (records/param.keys+1)) != skr);
- }
- if ((sort_keys= (uchar **) make_char_array(param.keys,param.sort_length,
+ ulong old_memavl;
+ ulong keys= memavl/(param.sort_length+sizeof(char*));
+ param.keys=(uint) min(records+1, keys);
+ if ((sort_keys= (uchar **) make_char_array(param.keys, param.sort_length,
MYF(0))))
- if ((buffpek = (BUFFPEK*) my_malloc((uint) sizeof(BUFFPEK)*
- (maxbuffer+10),
- MYF(0))))
- break;
- else
- my_free((gptr) sort_keys,MYF(0));
+ break;
old_memavl=memavl;
if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
- memavl=min_sort_memory;
+ memavl= min_sort_memory;
}
- param.keys--;
- maxbuffer+=10; /* Some extra range */
-
if (memavl < min_sort_memory)
{
- my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),sortbuff_size);
+ my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),
+ thd->variables.sortbuff_size);
goto err;
}
- param.sort_form= table[0];
+ if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX,
+ DISK_BUFFER_SIZE, MYF(MY_WME)))
+ goto err;
+
+ param.keys--;
+ param.sort_form= table;
param.end=(param.local_sortorder=sortorder)+s_length;
- if ((records=find_all_keys(&param,select,sort_keys,buffpek,&maxbuffer,
+ if ((records=find_all_keys(&param,select,sort_keys, &buffpek_pointers,
&tempfile, selected_records_file)) ==
HA_POS_ERROR)
goto err;
+ maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
+
if (maxbuffer == 0) // The whole set is in memory
{
if (save_index(&param,sort_keys,(uint) records))
@@ -217,6 +195,9 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
}
else
{
+ if (!(buffpek=read_buffpek_from_file(&buffpek_pointers, maxbuffer)))
+ goto err;
+ close_cached_file(&buffpek_pointers);
/* Open cached file if it isn't open */
if (! my_b_inited(outfile) &&
open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
@@ -224,14 +205,21 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
goto err;
reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
+ /*
+ Use also the space previously used by string pointers in sort_buffer
+ for temporary key storage.
+ */
param.keys=((param.keys*(param.sort_length+sizeof(char*))) /
param.sort_length-1);
- if (merge_many_buff(&param,sort_keys,buffpek,&maxbuffer,&tempfile))
+ maxbuffer--; // Offset from 0
+ if (merge_many_buff(&param,(uchar*) sort_keys,buffpek,&maxbuffer,
+ &tempfile))
goto err;
if (flush_io_cache(&tempfile) ||
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
goto err;
- if (merge_index(&param,sort_keys,buffpek,maxbuffer,&tempfile,outfile))
+ if (merge_index(&param,(uchar*) sort_keys,buffpek,maxbuffer,&tempfile,
+ outfile))
goto err;
}
if (records > param.max_rows)
@@ -246,6 +234,7 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
x_free((gptr) sort_keys);
x_free((gptr) buffpek);
close_cached_file(&tempfile);
+ close_cached_file(&buffpek_pointers);
if (my_b_inited(outfile))
{
if (flush_io_cache(outfile))
@@ -261,9 +250,9 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
if (error)
my_error(ER_FILSORT_ABORT,MYF(ME_ERROR+ME_WAITTANG));
else
- statistic_add(filesort_rows, records, &LOCK_status);
+ statistic_add(filesort_rows, (ulong) records, &LOCK_status);
*examined_rows= param.examined_rows;
-#ifdef SKIPP_DBUG_IN_FILESORT
+#ifdef SKIP_DBUG_IN_FILESORT
DBUG_POP(); /* Ok to DBUG */
#endif
DBUG_PRINT("exit",("records: %ld",records));
@@ -290,11 +279,33 @@ static char **make_char_array(register uint fields, uint length, myf my_flag)
} /* make_char_array */
+ /* Read all buffer pointers into memory */
+
+static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
+{
+ ulong length;
+ BUFFPEK *tmp;
+ DBUG_ENTER("read_buffpek_from_file");
+ tmp=(BUFFPEK*) my_malloc(length=sizeof(BUFFPEK)*count, MYF(MY_WME));
+ if (tmp)
+ {
+ if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
+ my_b_read(buffpek_pointers, (byte*) tmp, length))
+ {
+ my_free((char*) tmp, MYF(0));
+ tmp=0;
+ }
+ }
+ DBUG_RETURN(tmp);
+}
+
+
+
/* Search after sort_keys and place them in a temp. file */
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
uchar **sort_keys,
- BUFFPEK *buffpek, uint *maxbuffer,
+ IO_CACHE *buffpek_pointers,
IO_CACHE *tempfile, IO_CACHE *indexfile)
{
int error,flag,quick_select;
@@ -315,7 +326,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
ref_pos= ref_buff;
quick_select=select && select->quick;
record=0;
- flag= ((!indexfile && file->option_flag() & HA_REC_NOT_IN_SEQ)
+ flag= ((!indexfile && file->table_flags() & HA_REC_NOT_IN_SEQ)
|| quick_select);
if (indexfile || flag)
ref_pos= &file->ref[0];
@@ -327,7 +338,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
file->extra(HA_EXTRA_KEYREAD); // QQ is removed
next_pos=(byte*) 0; /* Find records in sequence */
file->rnd_init();
- file->extra(HA_EXTRA_CACHE); /* Quicker reads */
+ file->extra_opt(HA_EXTRA_CACHE,
+ current_thd->variables.read_buff_size);
}
for (;;)
@@ -376,20 +388,9 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
{
if (idx == param->keys)
{
- if (indexpos >= *maxbuffer ||
- write_keys(param,sort_keys,idx,buffpek+indexpos,tempfile))
- DBUG_RETURN(HA_POS_ERROR);
+ if (write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
+ DBUG_RETURN(HA_POS_ERROR);
idx=0;
- if (param->ref_length == param->sort_length &&
- my_b_tell(tempfile)/param->sort_length >= param->max_rows)
- {
- /*
- We are writing the result index file and have found all
- rows that we need. Abort the sort and return the result.
- */
- error=HA_ERR_END_OF_FILE;
- break; /* Found enough records */
- }
indexpos++;
}
make_sortkey(param,sort_keys[idx++],ref_pos);
@@ -405,11 +406,9 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); /* purecov: inspected */
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
}
- if (indexpos && idx)
- if (indexpos >= *maxbuffer ||
- write_keys(param,sort_keys,idx,buffpek+indexpos,tempfile))
- DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
- *maxbuffer=indexpos;
+ if (indexpos && idx &&
+ write_keys(param,sort_keys,idx,buffpek_pointers,tempfile))
+ DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
DBUG_RETURN(my_b_inited(tempfile) ?
(ha_rows) (my_b_tell(tempfile)/param->sort_length) :
idx);
@@ -418,10 +417,13 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
/* Skriver en buffert med nycklar till filen */
-static int write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
- BUFFPEK *buffpek, IO_CACHE *tempfile)
+static int
+write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
+ IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
{
uint sort_length;
+ uchar **end;
+ BUFFPEK buffpek;
DBUG_ENTER("write_keys");
sort_length=param->sort_length;
@@ -433,15 +435,20 @@ static int write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
if (!my_b_inited(tempfile) &&
open_cached_file(tempfile,mysql_tmpdir,TEMP_PREFIX,DISK_BUFFER_SIZE,
MYF(MY_WME)))
- DBUG_RETURN(1); /* purecov: inspected */
- buffpek->file_pos=my_b_tell(tempfile);
+ goto err; /* purecov: inspected */
+ buffpek.file_pos=my_b_tell(tempfile);
if ((ha_rows) count > param->max_rows)
count=(uint) param->max_rows; /* purecov: inspected */
- buffpek->count=(ha_rows) count;
- for (uchar **end=sort_keys+count ; sort_keys != end ; sort_keys++)
+ buffpek.count=(ha_rows) count;
+ for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length))
- DBUG_RETURN(1);
+ goto err;
+ if (my_b_write(buffpek_pointers, (byte*) &buffpek, sizeof(buffpek)))
+ goto err;
DBUG_RETURN(0);
+
+err:
+ DBUG_RETURN(1);
} /* write_keys */
@@ -458,6 +465,7 @@ static void make_sortkey(register SORTPARAM *param,
sort_field != param->end ;
sort_field++)
{
+ bool maybe_null=0;
if ((field=sort_field->field))
{ // Field
if (field->maybe_null())
@@ -482,7 +490,7 @@ static void make_sortkey(register SORTPARAM *param,
switch (sort_field->result_type) {
case STRING_RESULT:
{
- if (item->maybe_null)
+ if ((maybe_null=item->maybe_null))
*to++=1;
/* All item->str() to use some extra byte for end null.. */
String tmp((char*) to,sort_field->length+4);
@@ -548,7 +556,7 @@ static void make_sortkey(register SORTPARAM *param,
case INT_RESULT:
{
longlong value=item->val_int();
- if (item->maybe_null)
+ if ((maybe_null=item->maybe_null))
*to++=1; /* purecov: inspected */
if (item->null_value)
{
@@ -582,13 +590,13 @@ static void make_sortkey(register SORTPARAM *param,
case REAL_RESULT:
{
double value=item->val();
- if (item->null_value)
+ if ((maybe_null=item->null_value))
{
bzero((char*) to,sort_field->length+1);
to++;
break;
}
- if (item->maybe_null)
+ if ((maybe_null=item->maybe_null))
*to++=1;
change_double_for_sort(value,(byte*) to);
break;
@@ -597,6 +605,8 @@ static void make_sortkey(register SORTPARAM *param,
}
if (sort_field->reverse)
{ /* Revers key */
+ if (maybe_null)
+ to[-1]= ~to[-1];
length=sort_field->length;
while (length--)
{
@@ -637,8 +647,8 @@ static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count)
/* Merge buffers to make < MERGEBUFF2 buffers */
-static int merge_many_buff(SORTPARAM *param, uchar **sort_keys,
- BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
+int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
+ BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
{
register int i;
IO_CACHE t_file2,*from_file,*to_file,*temp;
@@ -660,11 +670,11 @@ static int merge_many_buff(SORTPARAM *param, uchar **sort_keys,
lastbuff=buffpek;
for (i=0 ; i <= (int) *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
{
- if (merge_buffers(param,from_file,to_file,sort_keys,lastbuff++,
+ if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
buffpek+i,buffpek+i+MERGEBUFF-1,0))
break; /* purecov: inspected */
}
- if (merge_buffers(param,from_file,to_file,sort_keys,lastbuff++,
+ if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
buffpek+i,buffpek+ *maxbuffer,0))
break; /* purecov: inspected */
if (flush_io_cache(to_file))
@@ -683,8 +693,8 @@ static int merge_many_buff(SORTPARAM *param, uchar **sort_keys,
/* Read data to buffer */
/* This returns (uint) -1 if something goes wrong */
-static uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
- uint sort_length)
+uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
+ uint sort_length)
{
register uint count;
uint length;
@@ -705,57 +715,98 @@ static uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
/* Merge buffers to one buffer */
-static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
- IO_CACHE *to_file, uchar **sort_keys,
- BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
- int flag)
+int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
+ IO_CACHE *to_file, uchar *sort_buffer,
+ BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
+ int flag)
{
int error;
uint sort_length,offset;
ulong maxcount;
- ha_rows count,max_rows;
+ ha_rows max_rows,org_max_rows;
my_off_t to_start_filepos;
uchar *strpos;
BUFFPEK *buffpek,**refpek;
QUEUE queue;
+ qsort2_cmp cmp;
volatile bool *killed= &current_thd->killed;
+ bool not_killable;
DBUG_ENTER("merge_buffers");
statistic_increment(filesort_merge_passes, &LOCK_status);
+ if (param->not_killable)
+ {
+ killed= &not_killable;
+ not_killable=0;
+ }
- count=error=0;
- offset=param->sort_length-param->ref_length;
+ error=0;
+ offset=(sort_length=param->sort_length)-param->ref_length;
maxcount=(ulong) (param->keys/((uint) (Tb-Fb) +1));
to_start_filepos=my_b_tell(to_file);
- strpos=(uchar*) sort_keys;
- sort_length=param->sort_length;
- max_rows=param->max_rows;
+ strpos=(uchar*) sort_buffer;
+ org_max_rows=max_rows=param->max_rows;
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
- (int (*) (void *, byte *,byte*))
- get_ptr_compare(sort_length),(void*) &sort_length))
+ (queue_compare)
+ (cmp=get_ptr_compare(sort_length)),(void*) &sort_length))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
{
- count+= buffpek->count;
buffpek->base= strpos;
buffpek->max_keys=maxcount;
strpos+= (uint) (error=(int) read_to_buffer(from_file,buffpek,
sort_length));
if (error == -1)
goto err; /* purecov: inspected */
+ buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected
queue_insert(&queue,(byte*) buffpek);
}
+ if (param->unique_buff)
+ {
+ /*
+ Called by Unique::get()
+ Copy the first argument to param->unique_buff for unique removal.
+ Store it also in 'to_file'.
+
+ This is safe as we know that there is always more than one element
+ in each block to merge (This is guaranteed by the Unique:: algorithm
+ */
+ buffpek=(BUFFPEK*) queue_top(&queue);
+ memcpy(param->unique_buff, buffpek->key, sort_length);
+ if (my_b_write(to_file,(byte*) buffpek->key, sort_length))
+ {
+ error=1; goto err; /* purecov: inspected */
+ }
+ buffpek->key+=sort_length;
+ buffpek->mem_count--;
+ if (!--max_rows)
+ {
+ error=0; /* purecov: inspected */
+ goto end; /* purecov: inspected */
+ }
+ queue_replaced(&queue); // Top element has been used
+ }
+ else
+ cmp=0; // Not unique
+
while (queue.elements > 1)
{
if (*killed)
{
- error=1; goto err; /* purecov: inspected */
+ error=1; goto err; /* purecov: inspected */
}
for (;;)
{
buffpek=(BUFFPEK*) queue_top(&queue);
+ if (cmp) // Remove duplicates
+ {
+ if (!(*cmp)(&sort_length, &(param->unique_buff),
+ (uchar**) &buffpek->key))
+ goto skip_duplicate;
+ memcpy(param->unique_buff, (uchar*) buffpek->key,sort_length);
+ }
if (flag == 0)
{
if (my_b_write(to_file,(byte*) buffpek->key, sort_length))
@@ -772,6 +823,8 @@ static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
error=0; /* purecov: inspected */
goto end; /* purecov: inspected */
}
+
+ skip_duplicate:
buffpek->key+=sort_length;
if (! --buffpek->mem_count)
{
@@ -804,14 +857,28 @@ static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
break; /* One buffer have been removed */
}
else if (error == -1)
- goto err; /* purecov: inspected */
+ goto err; /* purecov: inspected */
}
queue_replaced(&queue); /* Top element has been replaced */
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
- buffpek->base=(uchar *) sort_keys;
+ buffpek->base= sort_buffer;
buffpek->max_keys=param->keys;
+
+ /*
+ As we know all entries in the buffer are unique, we only have to
+ check if the first one is the same as the last one we wrote
+ */
+ if (cmp)
+ {
+ if (!(*cmp)(&sort_length, &(param->unique_buff), (uchar**) &buffpek->key))
+ {
+ buffpek->key+=sort_length; // Remove duplicate
+ --buffpek->mem_count;
+ }
+ }
+
do
{
if ((ha_rows) buffpek->mem_count > max_rows)
@@ -819,6 +886,7 @@ static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
buffpek->mem_count=(uint) max_rows;
buffpek->count=0; /* Don't read more */
}
+ max_rows-=buffpek->mem_count;
if (flag == 0)
{
if (my_b_write(to_file,(byte*) buffpek->key,
@@ -843,7 +911,7 @@ static int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
!= -1 && error != 0);
end:
- lastbuff->count=min(count,param->max_rows);
+ lastbuff->count=min(org_max_rows-max_rows,param->max_rows);
lastbuff->file_pos=to_start_filepos;
err:
delete_queue(&queue);
@@ -853,12 +921,12 @@ err:
/* Do a merge to output-file (save only positions) */
-static int merge_index(SORTPARAM *param, uchar **sort_keys,
+static int merge_index(SORTPARAM *param, uchar *sort_buffer,
BUFFPEK *buffpek, uint maxbuffer,
IO_CACHE *tempfile, IO_CACHE *outfile)
{
DBUG_ENTER("merge_index");
- if (merge_buffers(param,tempfile,outfile,sort_keys,buffpek,buffpek,
+ if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
buffpek+maxbuffer,1))
DBUG_RETURN(1); /* purecov: inspected */
DBUG_RETURN(0);
@@ -871,6 +939,7 @@ static uint
sortlength(SORT_FIELD *sortorder, uint s_length)
{
reg2 uint length;
+ THD *thd= current_thd;
length=0;
for (; s_length-- ; sortorder++)
@@ -878,7 +947,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length)
if (sortorder->field)
{
if (sortorder->field->type() == FIELD_TYPE_BLOB)
- sortorder->length=max_item_sort_length;
+ sortorder->length= thd->variables.max_sort_length;
else
{
sortorder->length=sortorder->field->pack_length();
@@ -914,7 +983,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length)
if (sortorder->item->maybe_null)
length++; // Place for NULL marker
}
- set_if_smaller(sortorder->length,max_item_sort_length);
+ set_if_smaller(sortorder->length, thd->variables.max_sort_length);
length+=sortorder->length;
}
sortorder->field= (Field*) 0; // end marker
diff --git a/sql/frm_crypt.cc b/sql/frm_crypt.cc
index 629e4ffab95..8dd70900648 100644
--- a/sql/frm_crypt.cc
+++ b/sql/frm_crypt.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc
index 2be57a49a99..1f604659272 100644
--- a/sql/gen_lex_hash.cc
+++ b/sql/gen_lex_hash.cc
@@ -16,19 +16,19 @@
#define NO_YACC_SYMBOLS
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#ifndef __GNU_LIBRARY__
-#define __GNU_LIBRARY__ // Skipp warnings in getopt.h
+#define __GNU_LIBRARY__ // Skip warnings in getopt.h
#endif
-#include <getopt.h>
+#include <my_getopt.h>
#include "mysql_version.h"
#include "lex.h"
-bool opt_search=0;
-uint opt_verbose=0;
-ulong opt_count=100000;
+my_bool opt_search;
+int opt_verbose;
+ulong opt_count;
#define max_allowed_array 8000 // Don't generate bigger arrays than this
#define max_symbol 32767 // Use this for 'not found'
@@ -55,6 +55,26 @@ static uchar bits[how_much_and/8+1];
static uint primes[max_allowed_array+1];
static ulong hash_results[type_count][how_much_for_plus+1][total_symbols];
static ulong start_value=0;
+static uint best_type;
+static ulong best_t1,best_t2, best_start_value;
+
+static struct my_option my_long_options[] =
+{
+ {"help", '?', "Display help and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"count", 'c', "Try count times to find a optimal hash table",
+ (gptr*) &opt_count, (gptr*) &opt_count, 0, GET_ULONG, REQUIRED_ARG,
+ 100000, 0, 0, 0, 0, 0},
+ {"search", 'S', "Search after good rnd1 and rnd2 values",
+ (gptr*) &opt_search, (gptr*) &opt_search, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"verbose", 'v', "Write some information while the program executes",
+ (gptr*) &opt_verbose, (gptr*) &opt_verbose, 0, GET_INT, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"version", 'V', "Output version information and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
struct rand_struct {
unsigned long seed1,seed2,max_value;
@@ -325,86 +345,53 @@ void print_arrays()
}
-static struct option long_options[] =
-{
- {"count", required_argument, 0, 'c'},
- {"search", no_argument, 0, 'S'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"rnd1", required_argument, 0, 'r'},
- {"rnd2", required_argument, 0, 'R'},
- {"type", required_argument, 0, 't'},
- {0, 0, 0, 0}
-};
-
-
static void usage(int version)
{
- printf("%s Ver 3.3 Distrib %s, for %s (%s)\n",
+ printf("%s Ver 3.5 Distrib %s, for %s (%s)\n",
my_progname, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
if (version)
return;
puts("Copyright (C) 2001 MySQL AB, by Sinisa and Monty");
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("This program generates a perfect hashing function for the sql_lex.cc");
- printf("Usage: %s [OPTIONS]\n", my_progname);
- printf("\n\
--c, --count=# Try count times to find a optimal hash table\n\
--r, --rnd1=# Set 1 part of rnd value for hash generator\n\
--R, --rnd2=# Set 2 part of rnd value for hash generator\n\
--t, --type=# Set type of char table to generate\n\
--S, --search Search after good rnd1 and rnd2 values\n\
--v, --verbose Write some information while the program executes\n\
--V, --version Output version information and exit\n");
+ printf("Usage: %s [OPTIONS]\n\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+extern "C" my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument __attribute__((unused)))
+{
+ switch (optid) {
+ case 'v':
+ opt_verbose++;
+ break;
+ case 'V':
+ usage(1);
+ exit(0);
+ case 'I':
+ case '?':
+ usage(0);
+ exit(0);
+ }
+ return 0;
}
-static uint best_type;
-static ulong best_t1,best_t2, best_start_value;
static int get_options(int argc, char **argv)
{
- int c,option_index=0;
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
- while ((c=getopt_long(argc,argv,"?SvVc:r:R:t:",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case 'c':
- opt_count=atol(optarg);
- break;
- case 'r':
- best_t1=atol(optarg);
- break;
- case 'R':
- best_t2=atol(optarg);
- break;
- case 't':
- best_type=atoi(optarg);
- break;
- case 'S':
- opt_search=1;
- break;
- case 'v':
- opt_verbose++;
- break;
- case 'V': usage(1); exit(0);
- case 'I':
- case '?':
- usage(0);
- exit(0);
- default:
- fprintf(stderr,"illegal option: -%c\n",opterr);
- usage(0);
- exit(1);
- }
- }
- argc-=optind;
- argv+=optind;
if (argc >= 1)
{
+ fprintf(stderr,"%s: Too many arguments\n", my_progname);
usage(0);
- exit(1);
+ exit(1);
}
return(0);
}
@@ -482,7 +469,7 @@ int main(int argc,char **argv)
int error;
MY_INIT(argv[0]);
- start_value=2744811L; best_t1=5135075L; best_t2=1719450L; best_type=0; /* mode=4999 add=1 type: 0 */
+ start_value=2925024L; best_t1=654916L; best_t2=1723390L; best_type=3; /* mode=4943 add=1 type: 0 */
if (get_options(argc,(char **) argv))
exit(1);
@@ -502,7 +489,6 @@ int main(int argc,char **argv)
printf("start_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; /* mode=%d add=%d type: %d */\n",
start_value, best_t1,best_t2,best_type,best_mod,best_add,
best_functype);
-
best_start_value=start_value;
for (uint i=1 ; i <= opt_count ; i++)
{
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index f52b99f5a12..15eb7fc72c6 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -240,7 +240,7 @@ int berkeley_show_logs(THD *thd)
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
DBUG_ENTER("berkeley_show_logs");
- init_alloc_root(&show_logs_root, 1024, 1024);
+ init_sql_alloc(&show_logs_root, 1024, 1024);
my_pthread_setspecific_ptr(THR_MALLOC,&show_logs_root);
if ((error= log_archive(db_env, &all_logs, DB_ARCH_ABS | DB_ARCH_LOG,
@@ -358,7 +358,7 @@ berkeley_cmp_packed_key(DB *file, const DBT *new_key, const DBT *saved_key)
KEY_PART_INFO *key_part= key->key_part, *end=key_part+key->key_parts;
uint key_length=new_key->size;
- for ( ; key_part != end && (int) key_length > 0; key_part++)
+ for (; key_part != end && (int) key_length > 0; key_part++)
{
int cmp;
if (key_part->null_bit)
@@ -396,7 +396,7 @@ berkeley_cmp_fix_length_key(DB *file, const DBT *new_key, const DBT *saved_key)
KEY_PART_INFO *key_part= key->key_part, *end=key_part+key->key_parts;
uint key_length=new_key->size;
- for ( ; key_part != end && (int) key_length > 0 ; key_part++)
+ for (; key_part != end && (int) key_length > 0 ; key_part++)
{
int cmp;
if ((cmp=key_part->field->pack_cmp(new_key_ptr,saved_key_ptr,0)))
@@ -417,7 +417,7 @@ berkeley_key_cmp(TABLE *table, KEY *key_info, const char *key, uint key_length)
KEY_PART_INFO *key_part= key_info->key_part,
*end=key_part+key_info->key_parts;
- for ( ; key_part != end && (int) key_length > 0; key_part++)
+ for (; key_part != end && (int) key_length > 0; key_part++)
{
int cmp;
if (key_part->null_bit)
@@ -544,7 +544,10 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
(*ptr)->set_bt_compare(*ptr, berkeley_cmp_packed_key);
(*ptr)->app_private= (void*) (table->key_info+i);
if (!(table->key_info[i].flags & HA_NOSAME))
+ {
+ DBUG_PRINT("bdb",("Setting DB_DUP for key %u", i));
(*ptr)->set_flags(*ptr, DB_DUP);
+ }
if ((error=((*ptr)->open(*ptr, name_buff, part, DB_BTREE,
open_mode, 0))))
{
@@ -561,7 +564,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
ref_length=0;
KEY_PART_INFO *key_part= table->key_info[primary_key].key_part;
KEY_PART_INFO *end=key_part+table->key_info[primary_key].key_parts;
- for ( ; key_part != end ; key_part++)
+ for (; key_part != end ; key_part++)
ref_length+= key_part->field->max_packed_col_length(key_part->length);
share->fixed_length_primary_key=
(ref_length == table->key_info[primary_key].key_length);
@@ -701,7 +704,7 @@ void ha_berkeley::unpack_key(char *record, DBT *key, uint index)
*end=key_part+key_info->key_parts;
char *pos=(char*) key->data;
- for ( ; key_part != end; key_part++)
+ for (; key_part != end; key_part++)
{
if (key_part->null_bit)
{
@@ -747,7 +750,7 @@ DBT *ha_berkeley::create_key(DBT *key, uint keynr, char *buff,
key->data=buff;
key->app_private= key_info;
- for ( ; key_part != end && key_length > 0; key_part++)
+ for (; key_part != end && key_length > 0; key_part++)
{
if (key_part->null_bit)
{
@@ -925,7 +928,7 @@ int ha_berkeley::key_cmp(uint keynr, const byte * old_row,
KEY_PART_INFO *key_part=table->key_info[keynr].key_part;
KEY_PART_INFO *end=key_part+table->key_info[keynr].key_parts;
- for ( ; key_part != end ; key_part++)
+ for (; key_part != end ; key_part++)
{
if (key_part->null_bit)
{
@@ -1043,9 +1046,9 @@ int ha_berkeley::restore_keys(DB_TXN *trans, key_map changed_keys,
break; /* purecov: inspected */
}
}
-
+
err:
- dbug_assert(error != DB_KEYEXIST);
+ DBUG_ASSERT(error != DB_KEYEXIST);
DBUG_RETURN(error);
}
@@ -1187,7 +1190,7 @@ int ha_berkeley::remove_key(DB_TXN *trans, uint keynr, const byte *record,
((table->key_info[keynr].flags & (HA_NOSAME | HA_NULL_PART_KEY)) ==
HA_NOSAME))
{ // Unique key
- dbug_assert(keynr == primary_key || prim_key->data != key_buff2);
+ DBUG_ASSERT(keynr == primary_key || prim_key->data != key_buff2);
error=key_file[keynr]->del(key_file[keynr], trans,
keynr == primary_key ?
prim_key :
@@ -1201,7 +1204,7 @@ int ha_berkeley::remove_key(DB_TXN *trans, uint keynr, const byte *record,
row to find the key to be delete and delete it.
We will never come here with keynr = primary_key
*/
- dbug_assert(keynr != primary_key && prim_key->data != key_buff2);
+ DBUG_ASSERT(keynr != primary_key && prim_key->data != key_buff2);
DBC *tmp_cursor;
if (!(error=key_file[keynr]->cursor(key_file[keynr], trans,
&tmp_cursor, 0)))
@@ -1420,6 +1423,8 @@ int ha_berkeley::index_read(byte * buf, const byte * key,
bzero((char*) &row,sizeof(row));
if (key_len == key_info->key_length)
{
+ if (find_flag == HA_READ_AFTER_KEY)
+ key_info->handler.bdb_return_if_eq= 1;
error=read_row(cursor->c_get(cursor, pack_key(&last_key,
active_index,
key_buff,
@@ -1428,6 +1433,7 @@ int ha_berkeley::index_read(byte * buf, const byte * key,
(find_flag == HA_READ_KEY_EXACT ?
DB_SET : DB_SET_RANGE)),
(char*) buf, active_index, &row, (DBT*) 0, 0);
+ key_info->handler.bdb_return_if_eq= 0;
}
else
{
@@ -1454,6 +1460,37 @@ int ha_berkeley::index_read(byte * buf, const byte * key,
DBUG_RETURN(error);
}
+/*
+ Read last key is solved by reading the next key and then reading
+ the previous key
+*/
+
+int ha_berkeley::index_read_last(byte * buf, const byte * key, uint key_len)
+{
+ DBT row;
+ int error;
+ KEY *key_info= &table->key_info[active_index];
+ DBUG_ENTER("ha_berkeley::index_read");
+
+ statistic_increment(ha_read_key_count,&LOCK_status);
+ bzero((char*) &row,sizeof(row));
+
+ /* read of partial key */
+ pack_key(&last_key, active_index, key_buff, key, key_len);
+ /* Store for compare */
+ memcpy(key_buff2, key_buff, (key_len=last_key.size));
+ key_info->handler.bdb_return_if_eq= 1;
+ error=read_row(cursor->c_get(cursor, &last_key, &row, DB_SET_RANGE),
+ (char*) buf, active_index, &row, (DBT*) 0, 0);
+ key_info->handler.bdb_return_if_eq= 0;
+ bzero((char*) &row,sizeof(row));
+ if (read_row(cursor->c_get(cursor, &last_key, &row, DB_PREV),
+ (char*) buf, active_index, &row, &last_key, 1) ||
+ berkeley_key_cmp(table, key_info, key_buff2, key_len))
+ error=HA_ERR_KEY_NOT_FOUND;
+ DBUG_RETURN(error);
+}
+
int ha_berkeley::index_next(byte * buf)
{
@@ -1553,7 +1590,7 @@ DBT *ha_berkeley::get_pos(DBT *to, byte *pos)
KEY_PART_INFO *key_part=table->key_info[primary_key].key_part;
KEY_PART_INFO *end=key_part+table->key_info[primary_key].key_parts;
- for ( ; key_part != end ; key_part++)
+ for (; key_part != end ; key_part++)
pos+=key_part->field->packed_col_length((char*) pos,key_part->length);
to->size= (uint) (pos- (byte*) to->data);
}
@@ -1565,12 +1602,13 @@ int ha_berkeley::rnd_pos(byte * buf, byte *pos)
{
DBT db_pos;
statistic_increment(ha_read_rnd_count,&LOCK_status);
+ DBUG_ENTER("ha_berkeley::rnd_pos");
active_index= (uint) -1; // Don't delete via cursor
- return read_row(file->get(file, transaction,
- get_pos(&db_pos, pos),
- &current_row, 0),
- (char*) buf, primary_key, &current_row, (DBT*) 0, 0);
+ DBUG_RETURN(read_row(file->get(file, transaction,
+ get_pos(&db_pos, pos),
+ &current_row, 0),
+ (char*) buf, primary_key, &current_row, (DBT*) 0, 0));
}
void ha_berkeley::position(const byte *record)
@@ -1600,8 +1638,9 @@ void ha_berkeley::info(uint flag)
share->rec_per_key[i];
}
}
- else if (flag & HA_STATUS_ERRKEY)
- errkey=last_dup_key;
+ /* Don't return key if we got an error for the internal primary key */
+ if (flag & HA_STATUS_ERRKEY && last_dup_key < table->keys)
+ errkey= last_dup_key;
DBUG_VOID_RETURN;
}
@@ -1669,7 +1708,7 @@ int ha_berkeley::external_lock(THD *thd, int lock_type)
DBUG_ASSERT(thd->transaction.stmt.bdb_tid == 0);
transaction=0; // Safety
/* First table lock, start transaction */
- if ((thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN |
+ if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK)) &&
!thd->transaction.all.bdb_tid)
{
@@ -1799,7 +1838,7 @@ static int create_sub_table(const char *table_name, const char *sub_name,
int error;
DB *file;
DBUG_ENTER("create_sub_table");
- DBUG_PRINT("enter",("sub_name: %s",sub_name));
+ DBUG_PRINT("enter",("sub_name: %s flags: %d",sub_name, flags));
if (!(error=db_create(&file, db_env, 0)))
{
@@ -1831,14 +1870,14 @@ int ha_berkeley::create(const char *name, register TABLE *form,
char name_buff[FN_REFLEN];
char part[7];
uint index=1;
- int error=1;
+ int error;
DBUG_ENTER("ha_berkeley::create");
fn_format(name_buff,name,"", ha_berkeley_ext,2 | 4);
/* Create the main table that will hold the real rows */
- if (create_sub_table(name_buff,"main",DB_BTREE,0))
- DBUG_RETURN(1); /* purecov: inspected */
+ if ((error= create_sub_table(name_buff,"main",DB_BTREE,0)))
+ DBUG_RETURN(error); /* purecov: inspected */
primary_key=table->primary_key;
/* Create the keys */
@@ -1847,10 +1886,10 @@ int ha_berkeley::create(const char *name, register TABLE *form,
if (i != primary_key)
{
sprintf(part,"key%02d",index++);
- if (create_sub_table(name_buff, part, DB_BTREE,
- (table->key_info[i].flags & HA_NOSAME) ? 0 :
- DB_DUP))
- DBUG_RETURN(1); /* purecov: inspected */
+ if ((error= create_sub_table(name_buff, part, DB_BTREE,
+ (table->key_info[i].flags & HA_NOSAME) ? 0 :
+ DB_DUP)))
+ DBUG_RETURN(error); /* purecov: inspected */
}
}
@@ -1858,16 +1897,15 @@ int ha_berkeley::create(const char *name, register TABLE *form,
/* Is DB_BTREE the best option here ? (QUEUE can't be used in sub tables) */
DB *status_block;
- if (!db_create(&status_block, db_env, 0))
+ if (!(error=(db_create(&status_block, db_env, 0))))
{
- if (!status_block->open(status_block, name_buff,
- "status", DB_BTREE, DB_CREATE, 0))
+ if (!(error=(status_block->open(status_block, name_buff,
+ "status", DB_BTREE, DB_CREATE, 0))))
{
char rec_buff[4+MAX_KEY*4];
uint length= 4+ table->keys*4;
bzero(rec_buff, length);
- if (!write_status(status_block, rec_buff, length))
- error=0;
+ error= write_status(status_block, rec_buff, length);
status_block->close(status_block,0);
}
}
@@ -1875,19 +1913,41 @@ int ha_berkeley::create(const char *name, register TABLE *form,
}
+
int ha_berkeley::delete_table(const char *name)
{
int error;
char name_buff[FN_REFLEN];
+ DBUG_ENTER("delete_table");
if ((error=db_create(&file, db_env, 0)))
my_errno=error; /* purecov: inspected */
else
error=file->remove(file,fn_format(name_buff,name,"",ha_berkeley_ext,2 | 4),
NULL,0);
file=0; // Safety
+ DBUG_RETURN(error);
+}
+
+int ha_berkeley::rename_table(const char * from, const char * to)
+{
+ int error;
+ char from_buff[FN_REFLEN];
+ char to_buff[FN_REFLEN];
+
+ if ((error= db_create(&file, db_env, 0)))
+ my_errno= error;
+ else
+ {
+ /* On should not do a file->close() after rename returns */
+ error= file->rename(file,
+ fn_format(from_buff, from, "", ha_berkeley_ext, 2 | 4),
+ NULL, fn_format(to_buff, to, "", ha_berkeley_ext,
+ 2 | 4), 0);
+ }
return error;
}
+
/*
How many seeks it will take to read through the table
This is to be comparable to the number returned by records_in_range so
@@ -1896,7 +1956,7 @@ int ha_berkeley::delete_table(const char *name)
double ha_berkeley::scan_time()
{
- return records/3;
+ return rows2double(records/3);
}
ha_rows ha_berkeley::records_in_range(int keynr,
@@ -2047,7 +2107,7 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
free(stat);
stat=0;
}
- if (key_file[i]->stat(key_file[i], (void*) &stat, 0, 0))
+ if ((key_file[i]->stat)(key_file[i], (void*) &stat, 0, 0))
goto err; /* purecov: inspected */
share->rec_per_key[i]= (stat->bt_ndata /
(stat->bt_nkeys ? stat->bt_nkeys : 1));
@@ -2060,7 +2120,7 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
free(stat);
stat=0;
}
- if (file->stat(file, (void*) &stat, 0, 0))
+ if ((file->stat)(file, (void*) &stat, 0, 0))
goto err; /* purecov: inspected */
}
pthread_mutex_lock(&share->mutex);
@@ -2171,11 +2231,11 @@ static BDB_SHARE *get_share(const char *table_name, TABLE *table)
if (!(share=(BDB_SHARE*) hash_search(&bdb_open_tables, (byte*) table_name,
length)))
{
- ha_rows *rec_per_key;
+ ulong *rec_per_key;
char *tmp_name;
DB **key_file;
u_int32_t *key_type;
-
+
if ((share=(BDB_SHARE *)
my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&share, sizeof(*share),
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index ab1ead5a3e9..1925d1c410f 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -27,7 +27,8 @@
typedef struct st_berkeley_share {
ulonglong auto_ident;
- ha_rows rows, org_rows, *rec_per_key;
+ ha_rows rows, org_rows;
+ ulong *rec_per_key;
THR_LOCK lock;
pthread_mutex_t mutex;
char *table_name;
@@ -52,7 +53,7 @@ class ha_berkeley: public handler
u_int32_t *key_type;
DBC *cursor;
BDB_SHARE *share;
- ulong int_option_flag;
+ ulong int_table_flags;
ulong alloced_rec_buff_length;
ulong changed_rows;
uint primary_key,last_dup_key, hidden_primary_key, version;
@@ -86,20 +87,20 @@ class ha_berkeley: public handler
public:
ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0),
- int_option_flag(HA_READ_NEXT | HA_READ_PREV |
- HA_REC_NOT_IN_SEQ |
- HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
- HA_LONGLONG_KEYS | HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY |
- HA_BLOB_KEY | HA_NOT_EXACT_COUNT | HA_NO_FULLTEXT_KEY |
+ int_table_flags(HA_REC_NOT_IN_SEQ |
+ HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
+ HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT |
HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE |
- HA_AUTO_PART_KEY),
+ HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX |
+ HA_KEY_READ_WRONG_STR | HA_FILE_BASED),
changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0)
{
}
~ha_berkeley() {}
const char *table_type() const { return "BerkeleyDB"; }
+ const char *index_type(uint key_number) { return "BTREE"; }
const char **bas_ext() const;
- ulong option_flag() const { return int_option_flag; }
+ ulong table_flags(void) const { return int_table_flags; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MAX_KEY-1; }
uint max_key_parts() const { return MAX_REF_PARTS; }
@@ -122,6 +123,7 @@ class ha_berkeley: public handler
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint index, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
int index_next(byte * buf);
int index_next_same(byte * buf, const byte *key, uint keylen);
int index_prev(byte * buf);
@@ -151,6 +153,7 @@ class ha_berkeley: public handler
int create(const char *name, register TABLE *form,
HA_CREATE_INFO *create_info);
int delete_table(const char *name);
+ int rename_table(const char* from, const char* to);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
@@ -167,7 +170,6 @@ class ha_berkeley: public handler
};
extern bool berkeley_skip, berkeley_shared_data;
-extern SHOW_COMP_OPTION have_berkeley_db;
extern u_int32_t berkeley_init_flags,berkeley_env_flags, berkeley_lock_type,
berkeley_lock_types[];
extern ulong berkeley_cache_size, berkeley_max_lock, berkeley_log_buffer_size;
diff --git a/sql/ha_gemini.cc b/sql/ha_gemini.cc
deleted file mode 100644
index e8130c55fc7..00000000000
--- a/sql/ha_gemini.cc
+++ /dev/null
@@ -1,3630 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & NuSphere Corporation
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* This file is based on ha_berkeley.cc */
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-#include "mysql_priv.h"
-#ifdef HAVE_GEMINI_DB
-#include "ha_gemini.h"
-#include "dbconfig.h"
-#include "dsmpub.h"
-#include "recpub.h"
-#include "vststat.h"
-
-#include <m_ctype.h>
-#include <myisampack.h>
-#include <m_string.h>
-#include <assert.h>
-#include <hash.h>
-#include <stdarg.h>
-#include "geminikey.h"
-
-#define gemini_msg MSGD_CALLBACK
-
-pthread_mutex_t gem_mutex;
-
-static HASH gem_open_tables;
-static GEM_SHARE *get_share(const char *table_name, TABLE *table);
-static int free_share(GEM_SHARE *share, bool mutex_is_locked);
-static byte* gem_get_key(GEM_SHARE *share,uint *length,
- my_bool not_used __attribute__((unused)));
-static void gemini_lock_table_overflow_error(dsmContext_t *pcontext);
-
-const char *ha_gemini_ext=".gmd";
-const char *ha_gemini_idx_ext=".gmi";
-
-bool gemini_skip=0;
-long gemini_options = 0;
-long gemini_buffer_cache;
-long gemini_io_threads;
-long gemini_log_cluster_size;
-long gemini_locktablesize;
-long gemini_lock_wait_timeout;
-long gemini_spin_retries;
-long gemini_connection_limit;
-char *gemini_basedir;
-
-const char gemini_dbname[] = "gemini";
-dsmContext_t *pfirstContext = NULL;
-
-ulong gemini_recovery_options = GEMINI_RECOVERY_FULL;
-/* bits in gemini_recovery_options */
-const char *gemini_recovery_names[] =
-{ "FULL", "NONE", "FORCE" };
-TYPELIB gemini_recovery_typelib= {array_elements(gemini_recovery_names),"",
- gemini_recovery_names};
-
-const int start_of_name = 2; /* Name passed as ./<db>/<table-name>
- and we're not interested in the ./ */
-static const int keyBufSize = MAXKEYSZ + FULLKEYHDRSZ + MAX_REF_PARTS + 16;
-
-static int gemini_tx_begin(THD *thd);
-static void print_msg(THD *thd, const char *table_name, const char *op_name,
- const char *msg_type, const char *fmt, ...);
-
-static int gemini_helper_threads(dsmContext_t *pContext);
-pthread_handler_decl(gemini_watchdog,arg );
-pthread_handler_decl(gemini_rl_writer,arg );
-pthread_handler_decl(gemini_apw,arg);
-
-/* General functions */
-
-bool gemini_init(void)
-{
- dsmStatus_t rc = 0;
- char pmsgsfile[MAXPATHN];
-
- DBUG_ENTER("gemini_init");
-
- gemini_basedir=mysql_home;
- /* If datadir isn't set, bail out */
- if (*mysql_real_data_home == '\0')
- {
- goto badret;
- }
-
- /* dsmContextCreate and dsmContextSetString(DSM_TAGDB_DBNAME) must
- ** be the first DSM calls we make so that we can log any errors which
- ** occur in subsequent DSM calls. DO NOT INSERT ANY DSM CALLS IN
- ** BETWEEN THIS COMMENT AND THE COMMENT THAT SAYS "END OF CODE..."
- */
- /* Gotta connect to the database regardless of the operation */
- rc = dsmContextCreate(&pfirstContext);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "dsmContextCreate failed %l",rc);
- goto badret;
- }
- /* This call will also open the log file */
- rc = dsmContextSetString(pfirstContext, DSM_TAGDB_DBNAME,
- strlen(gemini_dbname), (TEXT *)gemini_dbname);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "Dbname tag failed %l", rc);
- goto badret;
- }
- /* END OF CODE NOT TO MESS WITH */
-
- fn_format(pmsgsfile, GEM_MSGS_FILE, language, ".db", 2 | 4);
- rc = dsmContextSetString(pfirstContext, DSM_TAGDB_MSGS_FILE,
- strlen(pmsgsfile), (TEXT *)pmsgsfile);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "MSGS_DIR tag failed %l", rc);
- goto badret;
- }
-
- strxmov(pmsgsfile, gemini_basedir, GEM_SYM_FILE, NullS);
- rc = dsmContextSetString(pfirstContext, DSM_TAGDB_SYMFILE,
- strlen(pmsgsfile), (TEXT *)pmsgsfile);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "SYMFILE tag failed %l", rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_TYPE,DSM_ACCESS_STARTUP);
- if ( rc != 0 )
- {
- gemini_msg(pfirstContext, "ACCESS TAG set failed %l",rc);
- goto badret;
- }
- rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_ENV, DSM_SQL_ENGINE);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "ACCESS_ENV set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetString(pfirstContext, DSM_TAGDB_DATADIR,
- strlen(mysql_real_data_home),
- (TEXT *)mysql_real_data_home);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "Datadir tag failed %l", rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_MAX_USERS,
- gemini_connection_limit);
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "MAX_USERS tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_DEFAULT_LOCK_TIMEOUT,
- gemini_lock_wait_timeout);
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "MAX_LOCK_ENTRIES tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_MAX_LOCK_ENTRIES,
- gemini_locktablesize);
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "MAX_LOCK_ENTRIES tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_SPIN_AMOUNT,
- gemini_spin_retries);
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "SPIN_AMOUNT tag set failed %l",rc);
- goto badret;
- }
-
- /* blocksize is hardcoded to 8K. Buffer cache is in bytes
- need to convert this to 8K blocks */
- gemini_buffer_cache = gemini_buffer_cache / 8192;
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_DB_BUFFERS,
- gemini_buffer_cache);
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "DB_BUFFERS tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_FLUSH_AT_COMMIT,
- ((gemini_options & GEMOPT_FLUSH_LOG) ? 0 : 1));
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "FLush_Log_At_Commit tag set failed %l",rc);
- goto badret;
- }
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_DIRECT_IO,
- ((gemini_options & GEMOPT_UNBUFFERED_IO) ? 1 : 0));
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "DIRECT_IO tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_CRASH_PROTECTION,
- ((gemini_recovery_options & GEMINI_RECOVERY_FULL) ? 1 : 0));
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "CRASH_PROTECTION tag set failed %l",rc);
- goto badret;
- }
-
- if (gemini_recovery_options & GEMINI_RECOVERY_FORCE)
- {
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_FORCE_ACCESS, 1);
- if(rc != 0)
- {
- printf("CRASH_PROTECTION tag set failed %ld",rc);
- goto badret;
- }
- }
-
- /* cluster size will come in bytes, need to convert it to
- 16 K units. */
- gemini_log_cluster_size = (gemini_log_cluster_size + 16383) / 16384;
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_BI_CLUSTER_SIZE,
- gemini_log_cluster_size);
-
- if(rc != 0)
- {
- gemini_msg(pfirstContext, "CRASH_PROTECTION tag set failed %l",rc);
- goto badret;
- }
-
- rc = dsmUserConnect(pfirstContext,(TEXT *)"Multi-user",
- DSM_DB_OPENDB | DSM_DB_OPENFILE);
- if( rc != 0 )
- {
- /* Message is output in dbenv() */
- goto badret;
- }
- /* Set access to shared for subsequent user connects */
- rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_TYPE,DSM_ACCESS_SHARED);
-
- rc = gemini_helper_threads(pfirstContext);
-
-
- (void) hash_init(&gem_open_tables,32,0,0,
- (hash_get_key) gem_get_key,0,0);
- pthread_mutex_init(&gem_mutex,NULL);
-
-
- DBUG_RETURN(0);
-
-badret:
- gemini_skip = 1;
- DBUG_RETURN(0);
-}
-
-static int gemini_helper_threads(dsmContext_t *pContext)
-{
- int rc = 0;
- int i;
- pthread_attr_t thr_attr;
-
- pthread_t hThread;
- DBUG_ENTER("gemini_helper_threads");
-
- (void) pthread_attr_init(&thr_attr);
-#if !defined(HAVE_DEC_3_2_THREADS)
- pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
- (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&thr_attr,32768);
-#endif
- rc = pthread_create (&hThread, &thr_attr, gemini_watchdog, (void *)pContext);
- if (rc)
- {
- gemini_msg(pContext, "Can't Create gemini watchdog thread");
- goto done;
- }
- if(!gemini_io_threads)
- goto done;
-
- rc = pthread_create(&hThread, &thr_attr, gemini_rl_writer, (void *)pContext);
- if(rc)
- {
- gemini_msg(pContext, "Can't create Gemini recovery log writer thread");
- goto done;
- }
-
- for(i = gemini_io_threads - 1;i;i--)
- {
- rc = pthread_create(&hThread, &thr_attr, gemini_apw, (void *)pContext);
- if(rc)
- {
- gemini_msg(pContext, "Can't create Gemini database page writer thread");
- goto done;
- }
- }
-done:
-
- DBUG_RETURN(rc);
-}
-
-pthread_handler_decl(gemini_watchdog,arg )
-{
- int rc = 0;
- dsmContext_t *pcontext = (dsmContext_t *)arg;
- dsmContext_t *pmyContext = NULL;
-
-
- rc = dsmContextCopy(pcontext,&pmyContext, DSMCONTEXTDB);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmContextCopy failed for Gemini watchdog %d",rc);
-
- return 0;
- }
- rc = dsmUserConnect(pmyContext,NULL,0);
-
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmUserConnect failed for Gemini watchdog %d",rc);
-
- return 0;
- }
-
- my_thread_init();
- pthread_detach_this_thread();
-
- while(rc == 0)
- {
- rc = dsmDatabaseProcessEvents(pmyContext);
- if(!rc)
- rc = dsmWatchdog(pmyContext);
- sleep(1);
- }
- rc = dsmUserDisconnect(pmyContext,0);
- my_thread_end();
- return 0;
-}
-
-pthread_handler_decl(gemini_rl_writer,arg )
-{
- int rc = 0;
- dsmContext_t *pcontext = (dsmContext_t *)arg;
- dsmContext_t *pmyContext = NULL;
-
-
- rc = dsmContextCopy(pcontext,&pmyContext, DSMCONTEXTDB);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmContextCopy failed for Gemini recovery log writer %d",rc);
-
- return 0;
- }
- rc = dsmUserConnect(pmyContext,NULL,0);
-
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmUserConnect failed for Gemini recovery log writer %d",rc);
-
- return 0;
- }
-
- my_thread_init();
- pthread_detach_this_thread();
-
- while(rc == 0)
- {
- rc = dsmRLwriter(pmyContext);
- }
- rc = dsmUserDisconnect(pmyContext,0);
- my_thread_end();
- return 0;
-}
-
-pthread_handler_decl(gemini_apw,arg )
-{
- int rc = 0;
- dsmContext_t *pcontext = (dsmContext_t *)arg;
- dsmContext_t *pmyContext = NULL;
-
- my_thread_init();
- pthread_detach_this_thread();
-
- rc = dsmContextCopy(pcontext,&pmyContext, DSMCONTEXTDB);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmContextCopy failed for Gemini page writer %d",rc);
- my_thread_end();
- return 0;
- }
- rc = dsmUserConnect(pmyContext,NULL,0);
-
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmUserConnect failed for Gemini page writer %d",rc);
- my_thread_end();
- return 0;
- }
-
- while(rc == 0)
- {
- rc = dsmAPW(pmyContext);
- }
- rc = dsmUserDisconnect(pmyContext,0);
- my_thread_end();
- return 0;
-}
-
-int gemini_set_option_long(int optid, long optval)
-{
- dsmStatus_t rc = 0;
-
- switch (optid)
- {
- case GEM_OPTID_SPIN_RETRIES:
- /* If we don't have a context yet, skip the set and just save the
- ** value in gemini_spin_retries for a later gemini_init(). This
- ** may not ever happen, but we're covered if it does.
- */
- if (pfirstContext)
- {
- rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_SPIN_AMOUNT,
- optval);
- }
- if (rc)
- {
- gemini_msg(pfirstContext, "SPIN_AMOUNT tag set failed %l",rc);
- }
- else
- {
- gemini_spin_retries = optval;
- }
- break;
- }
-
- return rc;
-}
-
-static int gemini_connect(THD *thd)
-{
- DBUG_ENTER("gemini_connect");
-
- dsmStatus_t rc;
-
- rc = dsmContextCopy(pfirstContext,(dsmContext_t **)&thd->gemini.context,
- DSMCONTEXTDB);
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "dsmContextCopy failed %l",rc);
-
- return(rc);
- }
- rc = dsmUserConnect((dsmContext_t *)thd->gemini.context,NULL,0);
-
- if( rc != 0 )
- {
- gemini_msg(pfirstContext, "dsmUserConnect failed %l",rc);
-
- return(rc);
- }
- rc = (dsmStatus_t)gemini_tx_begin(thd);
-
- DBUG_RETURN(rc);
-}
-
-void gemini_disconnect(THD *thd)
-{
- dsmStatus_t rc;
-
- if(thd->gemini.context)
- {
- rc = dsmUserDisconnect((dsmContext_t *)thd->gemini.context,0);
- }
- return;
-}
-
-bool gemini_end(void)
-{
- dsmStatus_t rc;
- THD *thd;
-
- DBUG_ENTER("gemini_end");
-
- hash_free(&gem_open_tables);
- pthread_mutex_destroy(&gem_mutex);
- if(pfirstContext)
- {
- rc = dsmShutdownSet(pfirstContext, DSM_SHUTDOWN_NORMAL);
- sleep(2);
- rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_TYPE,DSM_ACCESS_STARTUP);
- rc = dsmShutdown(pfirstContext, DSMNICEBIT,DSMNICEBIT);
- }
- DBUG_RETURN(0);
-}
-
-bool gemini_flush_logs()
-{
- DBUG_ENTER("gemini_flush_logs");
-
- DBUG_RETURN(0);
-}
-
-static int gemini_tx_begin(THD *thd)
-{
- dsmStatus_t rc;
- DBUG_ENTER("gemini_tx_begin");
-
- thd->gemini.savepoint = 1;
-
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,DSMTXN_START,0,NULL);
- if(!rc)
- thd->gemini.needSavepoint = 1;
-
- thd->gemini.tx_isolation = thd->tx_isolation;
-
- DBUG_PRINT("trans",("beginning transaction"));
- DBUG_RETURN(rc);
-}
-
-int gemini_commit(THD *thd)
-{
- dsmStatus_t rc;
- LONG txNumber = 0;
-
- DBUG_ENTER("gemini_commit");
-
- if(!thd->gemini.context)
- DBUG_RETURN(0);
-
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- 0,DSMTXN_COMMIT,0,NULL);
- if(!rc)
- rc = gemini_tx_begin(thd);
-
- thd->gemini.lock_count = 0;
-
- DBUG_PRINT("trans",("ending transaction"));
- DBUG_RETURN(rc);
-}
-
-int gemini_rollback(THD *thd)
-{
- dsmStatus_t rc;
- LONG txNumber;
-
- DBUG_ENTER("gemini_rollback");
- DBUG_PRINT("trans",("aborting transaction"));
-
- if(!thd->gemini.context)
- DBUG_RETURN(0);
-
- thd->gemini.savepoint = 0;
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,DSMTXN_ABORT,0,NULL);
- if(!rc)
- rc = gemini_tx_begin(thd);
-
- thd->gemini.lock_count = 0;
-
- DBUG_RETURN(rc);
-}
-
-int gemini_rollback_to_savepoint(THD *thd)
-{
- dsmStatus_t rc = 0;
- DBUG_ENTER("gemini_rollback_to_savepoint");
- if(thd->gemini.savepoint > 1)
- {
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,DSMTXN_UNSAVE,0,NULL);
- }
- DBUG_RETURN(rc);
-}
-
-int gemini_recovery_logging(THD *thd, bool on)
-{
- int error;
- int noLogging;
-
- if(!thd->gemini.context)
- return 0;
-
- if(on)
- noLogging = 0;
- else
- noLogging = 1;
-
- error = dsmContextSetLong((dsmContext_t *)thd->gemini.context,
- DSM_TAGCONTEXT_NO_LOGGING,noLogging);
- return error;
-}
-
-/* gemDataType - translates from mysql data type constant to gemini
- key services data type contstant */
-int gemDataType ( int mysqlType )
-{
- switch (mysqlType)
- {
- case FIELD_TYPE_LONG:
- case FIELD_TYPE_TINY:
- case FIELD_TYPE_SHORT:
- case FIELD_TYPE_TIMESTAMP:
- case FIELD_TYPE_LONGLONG:
- case FIELD_TYPE_INT24:
- case FIELD_TYPE_DATE:
- case FIELD_TYPE_TIME:
- case FIELD_TYPE_DATETIME:
- case FIELD_TYPE_YEAR:
- case FIELD_TYPE_NEWDATE:
- case FIELD_TYPE_ENUM:
- case FIELD_TYPE_SET:
- return GEM_INT;
- case FIELD_TYPE_DECIMAL:
- return GEM_DECIMAL;
- case FIELD_TYPE_FLOAT:
- return GEM_FLOAT;
- case FIELD_TYPE_DOUBLE:
- return GEM_DOUBLE;
- case FIELD_TYPE_TINY_BLOB:
- return GEM_TINYBLOB;
- case FIELD_TYPE_MEDIUM_BLOB:
- return GEM_MEDIUMBLOB;
- case FIELD_TYPE_LONG_BLOB:
- return GEM_LONGBLOB;
- case FIELD_TYPE_BLOB:
- return GEM_BLOB;
- case FIELD_TYPE_VAR_STRING:
- case FIELD_TYPE_STRING:
- return GEM_CHAR;
- }
- return -1;
-}
-
-/*****************************************************************************
-** Gemini tables
-*****************************************************************************/
-
-const char **ha_gemini::bas_ext() const
-{ static const char *ext[]= { ha_gemini_ext, ha_gemini_idx_ext, NullS };
- return ext;
-}
-
-
-int ha_gemini::open(const char *name, int mode, uint test_if_locked)
-{
- dsmObject_t tableId = 0;
- THD *thd;
- char name_buff[FN_REFLEN];
- char tabname_buff[FN_REFLEN];
- char dbname_buff[FN_REFLEN];
- unsigned i,nameLen;
- LONG txNumber;
- dsmStatus_t rc;
-
- DBUG_ENTER("ha_gemini::open");
-
- thd = current_thd;
- /* Init shared structure */
- if (!(share=get_share(name,table)))
- {
- DBUG_RETURN(1); /* purecov: inspected */
- }
- thr_lock_data_init(&share->lock,&lock,(void*) 0);
-
- ref_length = sizeof(dsmRecid_t);
-
- if(thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- rc = gemini_connect(thd);
- if(rc)
- return rc;
- }
- if (!(rec_buff=(byte*)my_malloc(table->rec_buff_length,
- MYF(MY_WME))))
- {
- DBUG_RETURN(1);
- }
-
- /* separate out the name of the table and the database (a VST must be
- ** created in the mysql database)
- */
- rc = gemini_parse_table_name(name, dbname_buff, tabname_buff);
- if (rc == 0)
- {
- if (strcmp(dbname_buff, "mysql") == 0)
- {
- tableId = gemini_is_vst(tabname_buff);
- }
- }
- sprintf(name_buff, "%s.%s", dbname_buff, tabname_buff);
-
- /* if it's not a VST, get the table number the regular way */
- if (!tableId)
- {
- rc = dsmObjectNameToNum((dsmContext_t *)thd->gemini.context,
- (dsmText_t *)name_buff,
- &tableId);
- if (rc)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Unable to find table number for %s", name_buff);
- DBUG_RETURN(rc);
- }
- }
- tableNumber = tableId;
-
- if(!rc)
- rc = index_open(name_buff);
-
- fixed_length_row=!(table->db_create_options & HA_OPTION_PACK_RECORD);
- key_read = 0;
- using_ignore = 0;
-
- /* Get the gemini table status -- we want to know if the table
- crashed while being in the midst of a repair operation */
- rc = dsmTableStatus((dsmContext_t *)thd->gemini.context,
- tableNumber,&tableStatus);
- if(tableStatus == DSM_OBJECT_IN_REPAIR)
- tableStatus = HA_ERR_CRASHED;
-
- pthread_mutex_lock(&share->mutex);
- share->use_count++;
- pthread_mutex_unlock(&share->mutex);
-
- if (table->blob_fields)
- {
- /* Allocate room for the blob ids from an unpacked row. Note that
- ** we may not actually need all of this space because tiny blobs
- ** are stored in the packed row, not in a separate storage object
- ** like larger blobs. But we allocate an entry for all blobs to
- ** keep the code simpler.
- */
- pBlobDescs = (gemBlobDesc_t *)my_malloc(
- table->blob_fields * sizeof(gemBlobDesc_t),
- MYF(MY_WME | MY_ZEROFILL));
- }
- else
- {
- pBlobDescs = 0;
- }
-
- get_index_stats(thd);
- info(HA_STATUS_CONST);
-
- DBUG_RETURN (rc);
-}
-
-/* Look up and store the object numbers for the indexes on this table */
-int ha_gemini::index_open(char *tableName)
-{
- dsmStatus_t rc = 0;
- int nameLen;
-
- DBUG_ENTER("ha_gemini::index_open");
- if(table->keys)
- {
- THD *thd = current_thd;
- dsmObject_t objectNumber;
- if (!(pindexNumbers=(dsmIndex_t *)my_malloc(table->keys*sizeof(dsmIndex_t),
- MYF(MY_WME))))
- {
- DBUG_RETURN(1);
- }
- nameLen = strlen(tableName);
- tableName[nameLen] = '.';
- nameLen++;
-
- for( uint i = 0; i < table->keys && !rc; i++)
- {
- strcpy(&tableName[nameLen],table->key_info[i].name);
- rc = dsmObjectNameToNum((dsmContext_t *)thd->gemini.context,
- (dsmText_t *)tableName,
- &objectNumber);
- if (rc)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Unable to file Index number for %s", tableName);
- DBUG_RETURN(rc);
- }
- pindexNumbers[i] = objectNumber;
- }
- }
- else
- pindexNumbers = 0;
-
- DBUG_RETURN(rc);
-}
-
-int ha_gemini::close(void)
-{
- DBUG_ENTER("ha_gemini::close");
- my_free((char*)rec_buff,MYF(MY_ALLOW_ZERO_PTR));
- rec_buff = 0;
- my_free((char *)pindexNumbers,MYF(MY_ALLOW_ZERO_PTR));
- pindexNumbers = 0;
-
- if (pBlobDescs)
- {
- for (uint i = 0; i < table->blob_fields; i++)
- {
- my_free((char*)pBlobDescs[i].pBlob, MYF(MY_ALLOW_ZERO_PTR));
- }
- my_free((char *)pBlobDescs, MYF(0));
- pBlobDescs = 0;
- }
-
- DBUG_RETURN(free_share(share, 0));
-}
-
-
-int ha_gemini::write_row(byte * record)
-{
- int error = 0;
- dsmRecord_t dsmRecord;
- THD *thd;
-
- DBUG_ENTER("write_row");
-
- if(tableStatus == HA_ERR_CRASHED)
- DBUG_RETURN(tableStatus);
-
- thd = current_thd;
-
- statistic_increment(ha_write_count,&LOCK_status);
- if (table->time_stamp)
- update_timestamp(record+table->time_stamp-1);
-
- if(thd->gemini.needSavepoint || using_ignore)
- {
- thd->gemini.savepoint++;
- error = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,
- DSMTXN_SAVE, 0, 0);
- if (error)
- DBUG_RETURN(error);
- thd->gemini.needSavepoint = 0;
- }
-
- if (table->next_number_field && record == table->record[0])
- {
- if(thd->next_insert_id)
- {
- ULONG64 nr;
- /* A set insert-id statement so set the auto-increment value if this
- value is higher than it's current value */
- error = dsmTableAutoIncrement((dsmContext_t *)thd->gemini.context,
- tableNumber, (ULONG64 *)&nr,1);
- if(thd->next_insert_id > nr)
- {
- error = dsmTableAutoIncrementSet((dsmContext_t *)thd->gemini.context,
- tableNumber,
- (ULONG64)thd->next_insert_id);
- }
- }
-
- update_auto_increment();
- }
-
- dsmRecord.table = tableNumber;
- dsmRecord.maxLength = table->rec_buff_length;
-
- if ((error=pack_row((byte **)&dsmRecord.pbuffer, (int *)&dsmRecord.recLength,
- record, FALSE)))
- {
- DBUG_RETURN(error);
- }
-
- error = dsmRecordCreate((dsmContext_t *)thd->gemini.context,
- &dsmRecord,0);
-
- if(!error)
- {
- error = handleIndexEntries(record, dsmRecord.recid,KEY_CREATE);
- if(error == HA_ERR_FOUND_DUPP_KEY && using_ignore)
- {
- dsmStatus_t rc;
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,DSMTXN_UNSAVE,0,NULL);
- thd->gemini.needSavepoint = 1;
- }
- }
- if(error == DSM_S_RQSTREJ)
- error = HA_ERR_LOCK_WAIT_TIMEOUT;
-
- DBUG_RETURN(error);
-}
-
-longlong ha_gemini::get_auto_increment()
-{
- longlong nr;
- int error;
- int update;
- THD *thd=current_thd;
-
- if(thd->lex.sql_command == SQLCOM_SHOW_TABLES)
- update = 0;
- else
- update = 1;
-
- error = dsmTableAutoIncrement((dsmContext_t *)thd->gemini.context,
- tableNumber, (ULONG64 *)&nr,
- update);
- return nr;
-}
-
-/* Put or delete index entries for a row */
-int ha_gemini::handleIndexEntries(const byte * record, dsmRecid_t recid,
- enum_key_string_options option)
-{
- dsmStatus_t rc = 0;
-
- DBUG_ENTER("handleIndexEntries");
-
- for (uint i = 0; i < table->keys && rc == 0; i++)
- {
- rc = handleIndexEntry(record, recid,option, i);
- }
- DBUG_RETURN(rc);
-}
-
-int ha_gemini::handleIndexEntry(const byte * record, dsmRecid_t recid,
- enum_key_string_options option,uint keynr)
-{
- dsmStatus_t rc = 0;
- KEY *key_info;
- int keyStringLen;
- bool thereIsAnull;
- THD *thd;
-
- AUTOKEY(theKey,keyBufSize);
-
- DBUG_ENTER("handleIndexEntry");
-
- thd = current_thd;
- key_info=table->key_info+keynr;
- thereIsAnull = FALSE;
- rc = createKeyString(record, key_info, theKey.akey.keystr,
- sizeof(theKey.apad),&keyStringLen,
- (short)pindexNumbers[keynr],
- &thereIsAnull);
- if(!rc)
- {
- theKey.akey.index = pindexNumbers[keynr];
- theKey.akey.keycomps = (COUNT)key_info->key_parts;
-
- /* We have to subtract three here since cxKeyPrepare
- expects that the three lead bytes of the header are
- not counted in this length -- But cxKeyPrepare also
- expects that these three bytes are present in the keystr */
- theKey.akey.keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ;
- theKey.akey.unknown_comp = (dsmBoolean_t)thereIsAnull;
- theKey.akey.word_index = 0;
- theKey.akey.descending_key =0;
- if(option == KEY_CREATE)
- {
- rc = dsmKeyCreate((dsmContext_t *)thd->gemini.context, &theKey.akey,
- (dsmTable_t)tableNumber, recid, NULL);
- if(rc == DSM_S_IXDUPKEY)
- {
- last_dup_key=keynr;
- rc = HA_ERR_FOUND_DUPP_KEY;
- }
- }
- else if(option == KEY_DELETE)
- {
- rc = dsmKeyDelete((dsmContext_t *)thd->gemini.context, &theKey.akey,
- (dsmTable_t)tableNumber, recid, 0, NULL);
- }
- else
- {
- /* KEY_CHECK */
- dsmCursid_t aCursorId;
- int error;
-
- rc = dsmCursorCreate((dsmContext_t *)thd->gemini.context,
- (dsmTable_t)tableNumber,
- (dsmIndex_t)pindexNumbers[keynr],
- &aCursorId,NULL);
-
- rc = dsmCursorFind((dsmContext_t *)thd->gemini.context,
- &aCursorId,&theKey.akey,NULL,DSMDBKEY,
- DSMFINDFIRST,DSM_LK_SHARE,0,
- &lastRowid,0);
- error = dsmCursorDelete((dsmContext_t *)thd->gemini.context,
- &aCursorId, 0);
-
- }
- }
- DBUG_RETURN(rc);
-}
-
-int ha_gemini::createKeyString(const byte * record, KEY *pkeyinfo,
- unsigned char *pkeyBuf, int bufSize,
- int *pkeyStringLen,
- short geminiIndexNumber,
- bool *thereIsAnull)
-{
- dsmStatus_t rc = 0;
- int componentLen;
- int fieldType;
- int isNull;
- uint key_part_length;
-
- KEY_PART_INFO *key_part;
-
- DBUG_ENTER("createKeyString");
-
- rc = gemKeyInit(pkeyBuf,pkeyStringLen, geminiIndexNumber);
-
- for(uint i = 0; i < pkeyinfo->key_parts && rc == 0; i++)
- {
- unsigned char *pos;
-
- key_part = pkeyinfo->key_part + i;
- key_part_length = key_part->length;
- fieldType = gemDataType(key_part->field->type());
- switch (fieldType)
- {
- case GEM_CHAR:
- {
- /* Save the current ptr to the field in case we're building a key
- to remove an old key value when an indexed character column
- gets updated. */
- char *ptr = key_part->field->ptr;
- key_part->field->ptr = (char *)record + key_part->offset;
- key_part->field->sort_string((char*)rec_buff, key_part->length);
- key_part->field->ptr = ptr;
- pos = (unsigned char *)rec_buff;
- }
- break;
-
- case GEM_TINYBLOB:
- case GEM_BLOB:
- case GEM_MEDIUMBLOB:
- case GEM_LONGBLOB:
- ((Field_blob*)key_part->field)->get_ptr((char**)&pos);
- key_part_length = ((Field_blob*)key_part->field)->get_length(
- (char*)record + key_part->offset);
- break;
-
- default:
- pos = (unsigned char *)record + key_part->offset;
- break;
- }
-
- isNull = record[key_part->null_offset] & key_part->null_bit;
- if(isNull)
- *thereIsAnull = TRUE;
-
- rc = gemFieldToIdxComponent(pos,
- (unsigned long) key_part_length,
- fieldType,
- isNull ,
- key_part->field->flags & UNSIGNED_FLAG,
- pkeyBuf + *pkeyStringLen,
- bufSize,
- &componentLen);
- *pkeyStringLen += componentLen;
- }
- DBUG_RETURN(rc);
-}
-
-
-int ha_gemini::update_row(const byte * old_record, byte * new_record)
-{
- int error = 0;
- dsmRecord_t dsmRecord;
- unsigned long savepoint;
- THD *thd = current_thd;
- DBUG_ENTER("update_row");
-
- statistic_increment(ha_update_count,&LOCK_status);
- if (table->time_stamp)
- update_timestamp(new_record+table->time_stamp-1);
-
- if(thd->gemini.needSavepoint || using_ignore)
- {
- thd->gemini.savepoint++;
- error = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,
- DSMTXN_SAVE, 0, 0);
- if (error)
- DBUG_RETURN(error);
- thd->gemini.needSavepoint = 0;
- }
- for (uint keynr=0 ; keynr < table->keys ; keynr++)
- {
- if(key_cmp(keynr,old_record, new_record,FALSE))
- {
- error = handleIndexEntry(old_record,lastRowid,KEY_DELETE,keynr);
- if(error)
- DBUG_RETURN(error);
- error = handleIndexEntry(new_record, lastRowid, KEY_CREATE, keynr);
- if(error)
- {
- if (using_ignore && error == HA_ERR_FOUND_DUPP_KEY)
- {
- dsmStatus_t rc;
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,DSMTXN_UNSAVE,0,NULL);
- thd->gemini.needSavepoint = 1;
- }
- DBUG_RETURN(error);
- }
- }
- }
-
- dsmRecord.table = tableNumber;
- dsmRecord.recid = lastRowid;
- dsmRecord.maxLength = table->rec_buff_length;
-
- if ((error=pack_row((byte **)&dsmRecord.pbuffer, (int *)&dsmRecord.recLength,
- new_record, TRUE)))
- {
- DBUG_RETURN(error);
- }
- error = dsmRecordUpdate((dsmContext_t *)thd->gemini.context,
- &dsmRecord, 0, NULL);
-
- DBUG_RETURN(error);
-}
-
-
-int ha_gemini::delete_row(const byte * record)
-{
- int error = 0;
- dsmRecord_t dsmRecord;
- THD *thd = current_thd;
- dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context;
- DBUG_ENTER("delete_row");
-
- statistic_increment(ha_delete_count,&LOCK_status);
-
- if(thd->gemini.needSavepoint)
- {
- thd->gemini.savepoint++;
- error = dsmTransaction(pcontext, &thd->gemini.savepoint, DSMTXN_SAVE, 0, 0);
- if (error)
- DBUG_RETURN(error);
- thd->gemini.needSavepoint = 0;
- }
-
- dsmRecord.table = tableNumber;
- dsmRecord.recid = lastRowid;
-
- error = handleIndexEntries(record, dsmRecord.recid,KEY_DELETE);
- if(!error)
- {
- error = dsmRecordDelete(pcontext, &dsmRecord, 0, NULL);
- }
-
- /* Delete any blobs associated with this row */
- if (table->blob_fields)
- {
- dsmBlob_t gemBlob;
-
- gemBlob.areaType = DSMOBJECT_BLOB;
- gemBlob.blobObjNo = tableNumber;
- for (uint i = 0; i < table->blob_fields; i++)
- {
- if (pBlobDescs[i].blobId)
- {
- gemBlob.blobId = pBlobDescs[i].blobId;
- my_free((char *)pBlobDescs[i].pBlob, MYF(MY_ALLOW_ZERO_PTR));
- dsmBlobStart(pcontext, &gemBlob);
- dsmBlobDelete(pcontext, &gemBlob, NULL);
- /* according to DSM doc, no need to call dsmBlobEnd() */
- }
- }
- }
-
- DBUG_RETURN(error);
-}
-
-int ha_gemini::index_init(uint keynr)
-{
- int error = 0;
- THD *thd;
- DBUG_ENTER("index_init");
- thd = current_thd;
-
- lastRowid = 0;
- active_index=keynr;
- error = dsmCursorCreate((dsmContext_t *)thd->gemini.context,
- (dsmTable_t)tableNumber,
- (dsmIndex_t)pindexNumbers[keynr],
- &cursorId,NULL);
- pbracketBase = (dsmKey_t *)my_malloc(sizeof(dsmKey_t) + keyBufSize,
- MYF(MY_WME));
- if(!pbracketBase)
- DBUG_RETURN(1);
- pbracketLimit = (dsmKey_t *)my_malloc(sizeof(dsmKey_t) + keyBufSize,MYF(MY_WME));
- if(!pbracketLimit)
- {
- my_free((char *)pbracketLimit,MYF(0));
- DBUG_RETURN(1);
- }
- pbracketBase->index = 0;
- pbracketLimit->index = (dsmIndex_t)pindexNumbers[keynr];
- pbracketBase->descending_key = pbracketLimit->descending_key = 0;
- pbracketBase->ksubstr = pbracketLimit->ksubstr = 0;
- pbracketLimit->keycomps = pbracketBase->keycomps = 1;
-
- pfoundKey = (dsmKey_t *)my_malloc(sizeof(dsmKey_t) + keyBufSize,MYF(MY_WME));
- if(!pfoundKey)
- {
- my_free((char *)pbracketLimit,MYF(0));
- my_free((char *)pbracketBase,MYF(0));
- DBUG_RETURN(1);
- }
-
- DBUG_RETURN(error);
-}
-
-int ha_gemini::index_end()
-{
- int error = 0;
- THD *thd;
- DBUG_ENTER("index_end");
- thd = current_thd;
- error = dsmCursorDelete((dsmContext_t *)thd->gemini.context,
- &cursorId, 0);
- if(pbracketLimit)
- my_free((char *)pbracketLimit,MYF(0));
- if(pbracketBase)
- my_free((char *)pbracketBase,MYF(0));
- if(pfoundKey)
- my_free((char *)pfoundKey,MYF(0));
-
- pbracketLimit = 0;
- pbracketBase = 0;
- pfoundKey = 0;
- DBUG_RETURN(error);
-}
-
-/* This is only used to read whole keys */
-
-int ha_gemini::index_read_idx(byte * buf, uint keynr, const byte * key,
- uint key_len, enum ha_rkey_function find_flag)
-{
- int error = 0;
- DBUG_ENTER("index_read_idx");
- statistic_increment(ha_read_key_count,&LOCK_status);
-
- error = index_init(keynr);
- if (!error)
- error = index_read(buf,key,key_len,find_flag);
-
- if(error == HA_ERR_END_OF_FILE)
- error = HA_ERR_KEY_NOT_FOUND;
-
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-int ha_gemini::pack_key( uint keynr, dsmKey_t *pkey,
- const byte *key_ptr, uint key_length)
-{
- KEY *key_info=table->key_info+keynr;
- KEY_PART_INFO *key_part=key_info->key_part;
- KEY_PART_INFO *end=key_part+key_info->key_parts;
- int rc;
- int componentLen;
- DBUG_ENTER("pack_key");
-
- rc = gemKeyInit(pkey->keystr,&componentLen,
- (short)pindexNumbers[active_index]);
- pkey->keyLen = componentLen;
-
- for (; key_part != end && (int) key_length > 0 && !rc; key_part++)
- {
- uint offset=0;
- unsigned char *pos;
- uint key_part_length = key_part->length;
-
- int fieldType;
- if (key_part->null_bit)
- {
- offset=1;
- if (*key_ptr != 0) // Store 0 if NULL
- {
- key_length-= key_part->store_length;
- key_ptr+= key_part->store_length;
- rc = gemFieldToIdxComponent(
- (unsigned char *)key_ptr + offset,
- (unsigned long) key_part_length,
- 0,
- 1 , /* Tells it to build a null component */
- key_part->field->flags & UNSIGNED_FLAG,
- pkey->keystr + pkey->keyLen,
- keyBufSize,
- &componentLen);
- pkey->keyLen += componentLen;
- continue;
- }
- }
- fieldType = gemDataType(key_part->field->type());
- switch (fieldType)
- {
- case GEM_CHAR:
- key_part->field->store((char*)key_ptr + offset, key_part->length);
- key_part->field->sort_string((char*)rec_buff, key_part->length);
- pos = (unsigned char *)rec_buff;
- break;
-
- case GEM_TINYBLOB:
- case GEM_BLOB:
- case GEM_MEDIUMBLOB:
- case GEM_LONGBLOB:
- ((Field_blob*)key_part->field)->get_ptr((char**)&pos);
- key_part_length = ((Field_blob*)key_part->field)->get_length(
- (char*)key_ptr + offset);
- break;
-
- default:
- pos = (unsigned char *)key_ptr + offset;
- break;
- }
-
- rc = gemFieldToIdxComponent(
- pos,
- (unsigned long) key_part_length,
- fieldType,
- 0 ,
- key_part->field->flags & UNSIGNED_FLAG,
- pkey->keystr + pkey->keyLen,
- keyBufSize,
- &componentLen);
-
- key_ptr+=key_part->store_length;
- key_length-=key_part->store_length;
- pkey->keyLen += componentLen;
- }
- DBUG_RETURN(rc);
-}
-
-void ha_gemini::unpack_key(char *record, dsmKey_t *key, uint index)
-{
- KEY *key_info=table->key_info+index;
- KEY_PART_INFO *key_part= key_info->key_part,
- *end=key_part+key_info->key_parts;
- int fieldIsNull, fieldType;
- int rc = 0;
-
- char unsigned *pos= &key->keystr[FULLKEYHDRSZ+4/* 4 for the index number*/];
-
- for ( ; key_part != end; key_part++)
- {
- fieldType = gemDataType(key_part->field->type());
- if(fieldType == GEM_CHAR)
- {
- /* Can't get data from character indexes since the sort weights
- are in the index and not the characters. */
- key_read = 0;
- }
- rc = gemIdxComponentToField(pos, fieldType,
- (unsigned char *)record + key_part->field->offset(),
- //key_part->field->field_length,
- key_part->length,
- key_part->field->decimals(),
- &fieldIsNull);
- if(fieldIsNull)
- {
- record[key_part->null_offset] |= key_part->null_bit;
- }
- else if (key_part->null_bit)
- {
- record[key_part->null_offset]&= ~key_part->null_bit;
- }
- while(*pos++); /* Advance to next field in key by finding */
- /* a null byte */
- }
-}
-
-int ha_gemini::index_read(byte * buf, const byte * key,
- uint key_len, enum ha_rkey_function find_flag)
-{
- int error = 0;
- THD *thd;
- int componentLen;
-
- DBUG_ENTER("index_read");
- statistic_increment(ha_read_key_count,&LOCK_status);
-
-
- pbracketBase->index = (short)pindexNumbers[active_index];
- pbracketBase->keycomps = 1;
-
-
- /* Its a greater than operation so create a base bracket
- from the input key data. */
- error = pack_key(active_index, pbracketBase, key, key_len);
- if(error)
- goto errorReturn;
-
- if(find_flag == HA_READ_AFTER_KEY)
- {
- /* A greater than operation */
- error = gemKeyAddLow(pbracketBase->keystr + pbracketBase->keyLen,
- &componentLen);
- pbracketBase->keyLen += componentLen;
- }
- if(find_flag == HA_READ_KEY_EXACT)
- {
- /* Need to set up a high bracket for an equality operator
- Which is a copy of the base bracket plus a hi lim term */
- bmove(pbracketLimit,pbracketBase,(size_t)pbracketBase->keyLen + sizeof(dsmKey_t));
- error = gemKeyAddHigh(pbracketLimit->keystr + pbracketLimit->keyLen,
- &componentLen);
- if(error)
- goto errorReturn;
- pbracketLimit->keyLen += componentLen;
- }
- else
- {
- /* Always add a high range -- except for HA_READ_KEY_EXACT this
- is all we need for the upper index bracket */
- error = gemKeyHigh(pbracketLimit->keystr, &componentLen,
- pbracketLimit->index);
-
- pbracketLimit->keyLen = componentLen;
- }
- /* We have to subtract the header size here since cxKeyPrepare
- expects that the three lead bytes of the header are
- not counted in this length -- But cxKeyPrepare also
- expects that these three bytes are present in the keystr */
- pbracketBase->keyLen -= FULLKEYHDRSZ;
- pbracketLimit->keyLen -= FULLKEYHDRSZ;
-
- thd = current_thd;
-
- error = findRow(thd, DSMFINDFIRST, buf);
-
-errorReturn:
- if (error == DSM_S_ENDLOOP)
- error = HA_ERR_KEY_NOT_FOUND;
-
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-
-int ha_gemini::index_next(byte * buf)
-{
- THD *thd;
- int error = 1;
- int keyStringLen=0;
- dsmMask_t findMode;
- DBUG_ENTER("index_next");
-
- if(tableStatus == HA_ERR_CRASHED)
- DBUG_RETURN(tableStatus);
-
- thd = current_thd;
-
- if(pbracketBase->index == 0)
- {
- error = gemKeyLow(pbracketBase->keystr, &keyStringLen,
- pbracketLimit->index);
-
- pbracketBase->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ;
- pbracketBase->index = pbracketLimit->index;
- error = gemKeyHigh(pbracketLimit->keystr, &keyStringLen,
- pbracketLimit->index);
- pbracketLimit->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ;
-
- findMode = DSMFINDFIRST;
- }
- else
- findMode = DSMFINDNEXT;
-
- error = findRow(thd,findMode,buf);
-
- if (error == DSM_S_ENDLOOP)
- error = HA_ERR_END_OF_FILE;
-
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-int ha_gemini::index_next_same(byte * buf, const byte *key, uint keylen)
-{
- int error = 0;
- DBUG_ENTER("index_next_same");
- statistic_increment(ha_read_next_count,&LOCK_status);
- DBUG_RETURN(index_next(buf));
-}
-
-
-int ha_gemini::index_prev(byte * buf)
-{
- int error = 0;
- THD *thd = current_thd;
-
- DBUG_ENTER("index_prev");
- statistic_increment(ha_read_prev_count,&LOCK_status);
-
- error = findRow(thd, DSMFINDPREV, buf);
-
- if (error == DSM_S_ENDLOOP)
- error = HA_ERR_END_OF_FILE;
-
-
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-
-int ha_gemini::index_first(byte * buf)
-{
- DBUG_ENTER("index_first");
- statistic_increment(ha_read_first_count,&LOCK_status);
- DBUG_RETURN(index_next(buf));
-}
-
-int ha_gemini::index_last(byte * buf)
-{
- int error = 0;
- THD *thd;
- int keyStringLen;
- dsmMask_t findMode;
- thd = current_thd;
-
- DBUG_ENTER("index_last");
- statistic_increment(ha_read_last_count,&LOCK_status);
-
- error = gemKeyLow(pbracketBase->keystr, &keyStringLen,
- pbracketLimit->index);
-
- pbracketBase->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ;
- pbracketBase->index = pbracketLimit->index;
- error = gemKeyHigh(pbracketLimit->keystr, &keyStringLen,
- pbracketLimit->index);
- pbracketLimit->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ;
-
- error = findRow(thd,DSMFINDLAST,buf);
-
- if (error == DSM_S_ENDLOOP)
- error = HA_ERR_END_OF_FILE;
-
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-int ha_gemini::rnd_init(bool scan)
-{
- THD *thd = current_thd;
-
- lastRowid = 0;
-
- return 0;
-}
-
-int ha_gemini::rnd_end()
-{
-/*
- return gem_scan_end();
-*/
- return 0;
-}
-
-int ha_gemini::rnd_next(byte *buf)
-{
- int error = 0;
- dsmRecord_t dsmRecord;
- THD *thd;
-
- DBUG_ENTER("rnd_next");
-
- if(tableStatus == HA_ERR_CRASHED)
- DBUG_RETURN(tableStatus);
-
- thd = current_thd;
- if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL)
- && lastRowid)
- error = dsmObjectUnlock((dsmContext_t *)thd->gemini.context,
- tableNumber, DSMOBJECT_RECORD, lastRowid,
- lockMode | DSM_UNLK_FREE, 0);
-
- statistic_increment(ha_read_rnd_next_count,&LOCK_status);
- dsmRecord.table = tableNumber;
- dsmRecord.recid = lastRowid;
- dsmRecord.pbuffer = (dsmBuffer_t *)rec_buff;
- dsmRecord.recLength = table->reclength;
- dsmRecord.maxLength = table->rec_buff_length;
-
- error = dsmTableScan((dsmContext_t *)thd->gemini.context,
- &dsmRecord, DSMFINDNEXT, lockMode, 0);
-
- if(!error)
- {
- lastRowid = dsmRecord.recid;
- error = unpack_row((char *)buf,(char *)dsmRecord.pbuffer);
- }
- if(!error)
- ;
- else
- {
- lastRowid = 0;
- if (error == DSM_S_ENDLOOP)
- error = HA_ERR_END_OF_FILE;
- else if (error == DSM_S_RQSTREJ)
- error = HA_ERR_LOCK_WAIT_TIMEOUT;
- else if (error == DSM_S_LKTBFULL)
- {
- error = HA_ERR_LOCK_TABLE_FULL;
- gemini_lock_table_overflow_error((dsmContext_t *)thd->gemini.context);
- }
- }
- table->status = error ? STATUS_NOT_FOUND : 0;
- DBUG_RETURN(error);
-}
-
-
-int ha_gemini::rnd_pos(byte * buf, byte *pos)
-{
- int error;
- int rc;
-
- THD *thd;
-
- statistic_increment(ha_read_rnd_count,&LOCK_status);
- thd = current_thd;
- memcpy((void *)&lastRowid,pos,ref_length);
- if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL))
- {
- /* Lock the row */
-
- error = dsmObjectLock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,DSMOBJECT_RECORD,lastRowid,
- lockMode, 1, 0);
- if ( error )
- goto errorReturn;
- }
- error = fetch_row(thd->gemini.context, buf);
- if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL))
- {
- /* Unlock the row */
-
- rc = dsmObjectUnlock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,DSMOBJECT_RECORD,lastRowid,
- lockMode | DSM_UNLK_FREE , 0);
- }
- if(error == DSM_S_RMNOTFND)
- error = HA_ERR_RECORD_DELETED;
-
- errorReturn:
- table->status = error ? STATUS_NOT_FOUND : 0;
- return error;
-}
-
-int ha_gemini::fetch_row(void *gemini_context,const byte *buf)
-{
- dsmStatus_t rc = 0;
- dsmRecord_t dsmRecord;
-
- DBUG_ENTER("fetch_row");
- dsmRecord.table = tableNumber;
- dsmRecord.recid = lastRowid;
- dsmRecord.pbuffer = (dsmBuffer_t *)rec_buff;
- dsmRecord.recLength = table->reclength;
- dsmRecord.maxLength = table->rec_buff_length;
-
- rc = dsmRecordGet((dsmContext_t *)gemini_context,
- &dsmRecord, 0);
-
- if(!rc)
- {
- rc = unpack_row((char *)buf,(char *)dsmRecord.pbuffer);
- }
-
- DBUG_RETURN(rc);
-}
-int ha_gemini::findRow(THD *thd, dsmMask_t findMode, byte *buf)
-{
- dsmStatus_t rc;
- dsmKey_t *pkey;
-
- DBUG_ENTER("findRow");
-
- if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL)
- && lastRowid)
- rc = dsmObjectUnlock((dsmContext_t *)thd->gemini.context,
- tableNumber, DSMOBJECT_RECORD, lastRowid,
- lockMode | DSM_UNLK_FREE, 0);
- if( key_read )
- pkey = pfoundKey;
- else
- pkey = 0;
-
- rc = dsmCursorFind((dsmContext_t *)thd->gemini.context,
- &cursorId,
- pbracketBase,
- pbracketLimit,
- DSMPARTIAL,
- findMode,
- lockMode,
- NULL,
- &lastRowid,
- pkey);
- if( rc )
- goto errorReturn;
-
- if(key_read)
- {
- unpack_key((char*)buf, pkey, active_index);
- }
- if(!key_read) /* unpack_key may have turned off key_read */
- {
- rc = fetch_row((dsmContext_t *)thd->gemini.context,buf);
- }
-
-errorReturn:
- if(!rc)
- ;
- else
- {
- lastRowid = 0;
- if(rc == DSM_S_RQSTREJ)
- rc = HA_ERR_LOCK_WAIT_TIMEOUT;
- else if (rc == DSM_S_LKTBFULL)
- {
- rc = HA_ERR_LOCK_TABLE_FULL;
- gemini_lock_table_overflow_error((dsmContext_t *)thd->gemini.context);
- }
- }
-
- DBUG_RETURN(rc);
-}
-
-void ha_gemini::position(const byte *record)
-{
- memcpy(ref,&lastRowid,ref_length);
-}
-
-
-void ha_gemini::info(uint flag)
-{
- DBUG_ENTER("info");
-
- if ((flag & HA_STATUS_VARIABLE))
- {
- THD *thd = current_thd;
- dsmStatus_t error;
- ULONG64 rows;
-
- if(thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- error = gemini_connect(thd);
- if(error)
- DBUG_VOID_RETURN;
- }
-
- error = dsmRowCount((dsmContext_t *)thd->gemini.context,tableNumber,&rows);
- records = (ha_rows)rows;
- deleted = 0;
- }
- if ((flag & HA_STATUS_CONST))
- {
- ha_rows *rec_per_key = share->rec_per_key;
- for (uint i = 0; i < table->keys; i++)
- for(uint k=0;
- k < table->key_info[i].key_parts; k++,rec_per_key++)
- table->key_info[i].rec_per_key[k] = *rec_per_key;
- }
- if ((flag & HA_STATUS_ERRKEY))
- {
- errkey=last_dup_key;
- }
- if ((flag & HA_STATUS_TIME))
- {
- ;
- }
- if ((flag & HA_STATUS_AUTO))
- {
- THD *thd = current_thd;
- dsmStatus_t error;
-
- error = dsmTableAutoIncrement((dsmContext_t *)thd->gemini.context,
- tableNumber,
- (ULONG64 *)&auto_increment_value,
- 0);
- /* Should return the next auto-increment value that
- will be given -- so we need to increment the one dsm
- currently reports. */
- auto_increment_value++;
- }
-
- DBUG_VOID_RETURN;
-}
-
-
-int ha_gemini::extra(enum ha_extra_function operation)
-{
- switch (operation)
- {
- case HA_EXTRA_RESET:
- case HA_EXTRA_RESET_STATE:
- key_read=0;
- using_ignore=0;
- break;
- case HA_EXTRA_KEYREAD:
- key_read=1; // Query satisfied with key
- break;
- case HA_EXTRA_NO_KEYREAD:
- key_read=0;
- break;
- case HA_EXTRA_IGNORE_DUP_KEY:
- using_ignore=1;
- break;
- case HA_EXTRA_NO_IGNORE_DUP_KEY:
- using_ignore=0;
- break;
-
- default:
- break;
- }
- return 0;
-}
-
-
-int ha_gemini::reset(void)
-{
- key_read=0; // Reset to state after open
- return 0;
-}
-
-
-/*
- As MySQL will execute an external lock for every new table it uses
- we can use this to start the transactions.
-*/
-
-int ha_gemini::external_lock(THD *thd, int lock_type)
-{
- dsmStatus_t rc = 0;
- LONG txNumber;
-
- DBUG_ENTER("ha_gemini::external_lock");
-
- if (lock_type != F_UNLCK)
- {
- if (!thd->gemini.lock_count)
- {
- thd->gemini.lock_count = 1;
- thd->gemini.tx_isolation = thd->tx_isolation;
- }
- // lockMode has already been set in store_lock
- // If the statement about to be executed calls for
- // exclusive locks and we're running at read uncommitted
- // isolation level then raise an error.
- if(thd->gemini.tx_isolation == ISO_READ_UNCOMMITTED)
- {
- if(lockMode == DSM_LK_EXCL)
- {
- DBUG_RETURN(HA_ERR_READ_ONLY_TRANSACTION);
- }
- else
- {
- lockMode = DSM_LK_NOLOCK;
- }
- }
-
- if(thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- rc = gemini_connect(thd);
- if(rc)
- return rc;
- }
- /* Set need savepoint flag */
- thd->gemini.needSavepoint = 1;
-
- if(rc)
- DBUG_RETURN(rc);
-
-
- if( thd->in_lock_tables || thd->gemini.tx_isolation == ISO_SERIALIZABLE )
- {
- rc = dsmObjectLock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,DSMOBJECT_TABLE,0,
- lockMode, 1, 0);
- if(rc == DSM_S_RQSTREJ)
- rc = HA_ERR_LOCK_WAIT_TIMEOUT;
- }
- }
- else /* lock_type == F_UNLK */
- {
- /* Commit the tx if we're in auto-commit mode */
- if (!(thd->options & OPTION_NOT_AUTO_COMMIT)&&
- !(thd->options & OPTION_BEGIN))
- gemini_commit(thd);
- }
-
- DBUG_RETURN(rc);
-}
-
-
-THR_LOCK_DATA **ha_gemini::store_lock(THD *thd, THR_LOCK_DATA **to,
- enum thr_lock_type lock_type)
-{
- if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
- {
- /* If we are not doing a LOCK TABLE, then allow multiple writers */
- if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
- lock_type <= TL_WRITE) &&
- !thd->in_lock_tables)
- lock_type = TL_WRITE_ALLOW_WRITE;
- lock.type=lock_type;
- }
- if(table->reginfo.lock_type > TL_WRITE_ALLOW_READ)
- lockMode = DSM_LK_EXCL;
- else
- lockMode = DSM_LK_SHARE;
-
- *to++= &lock;
- return to;
-}
-
-void ha_gemini::update_create_info(HA_CREATE_INFO *create_info)
-{
- table->file->info(HA_STATUS_AUTO | HA_STATUS_CONST);
- if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
- {
- create_info->auto_increment_value=auto_increment_value;
- }
-}
-
-int ha_gemini::create(const char *name, register TABLE *form,
- HA_CREATE_INFO *create_info)
-{
- THD *thd;
- char name_buff[FN_REFLEN];
- char dbname_buff[FN_REFLEN];
- DBUG_ENTER("ha_gemini::create");
- dsmContext_t *pcontext;
- dsmStatus_t rc;
- dsmArea_t areaNumber;
- dsmObject_t tableNumber = 0;
- dsmDbkey_t dummy = 0;
- unsigned i;
- int baseNameLen;
- dsmObject_t indexNumber;
-
- /* separate out the name of the table and the database (a VST must be
- ** created in the mysql database)
- */
- rc = gemini_parse_table_name(name, dbname_buff, name_buff);
- if (rc == 0)
- {
- /* If the table is a VST, don't create areas or extents */
- if (strcmp(dbname_buff, "mysql") == 0)
- {
- tableNumber = gemini_is_vst(name_buff);
- if (tableNumber)
- {
- return 0;
- }
- }
- }
-
- thd = current_thd;
- if(thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- rc = gemini_connect(thd);
- if(rc)
- return rc;
- }
- pcontext = (dsmContext_t *)thd->gemini.context;
-
- if(thd->gemini.needSavepoint || using_ignore)
- {
- thd->gemini.savepoint++;
- rc = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,
- DSMTXN_SAVE, 0, 0);
- if (rc)
- DBUG_RETURN(rc);
- thd->gemini.needSavepoint = 0;
- }
-
- fn_format(name_buff, name, "", ha_gemini_ext, 2 | 4);
- /* Create a storage area */
- rc = dsmAreaNew(pcontext,gemini_blocksize,DSMAREA_TYPE_DATA,
- &areaNumber, gemini_recbits,
- (dsmText_t *)"gemini_data_area");
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmAreaNew failed %l",rc);
- return(rc);
- }
-
- /* Create an extent */
- /* Don't pass in leading ./ in name_buff */
- rc = dsmExtentCreate(pcontext,areaNumber,1,15,5,
- (dsmText_t *)&name_buff[start_of_name]);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmExtentCreate failed %l",rc);
- return(rc);
- }
-
- /* Create the table storage object */
- /* Change slashes in the name to periods */
- for( i = 0; i < strlen(name_buff); i++)
- if(name_buff[i] == '/' || name_buff[i] == '\\')
- name_buff[i] = '.';
-
- /* Get rid of .gmd suffix */
- name_buff[strlen(name_buff) - 4] = '\0';
-
- rc = dsmObjectCreate(pcontext, areaNumber, &tableNumber,
- DSMOBJECT_MIXTABLE,0,0,0,
- (dsmText_t *)&name_buff[start_of_name],
- &dummy,&dummy);
-
- if (rc == 0 && table->blob_fields)
- {
- /* create a storage object record for blob fields */
- rc = dsmObjectCreate(pcontext, areaNumber, &tableNumber,
- DSMOBJECT_BLOB,0,0,0,
- (dsmText_t *)&name_buff[start_of_name],
- &dummy,&dummy);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmObjectCreate for blob object failed %l",rc);
- return(rc);
- }
- }
-
- if(rc == 0 && form->keys)
- {
- fn_format(name_buff, name, "", ha_gemini_idx_ext, 2 | 4);
- /* Create a storage area */
- rc = dsmAreaNew(pcontext,gemini_blocksize,DSMAREA_TYPE_DATA,
- &areaNumber, gemini_recbits,
- (dsmText_t *)"gemini_index_area");
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmAreaNew failed %l",rc);
- return(rc);
- }
- /* Create an extent */
- /* Don't pass in leading ./ in name_buff */
- rc = dsmExtentCreate(pcontext,areaNumber,1,15,5,
- (dsmText_t *)&name_buff[start_of_name]);
- if( rc != 0 )
- {
- gemini_msg(pcontext, "dsmExtentCreate failed %l",rc);
- return(rc);
- }
-
- /* Change slashes in the name to periods */
- for( i = 0; i < strlen(name_buff); i++)
- if(name_buff[i] == '/' || name_buff[i] == '\\')
- name_buff[i] = '.';
-
- /* Get rid of .gmi suffix */
- name_buff[strlen(name_buff) - 4] = '\0';
-
- baseNameLen = strlen(name_buff);
- name_buff[baseNameLen] = '.';
- baseNameLen++;
- for( i = 0; i < form->keys; i++)
- {
- dsmObjectAttr_t indexUnique;
-
- indexNumber = DSMINDEX_INVALID;
- /* Create a storage object record for each index */
- /* Add the index name so the object name is in the form
- <db>.<table>.<index_name> */
- strcpy(&name_buff[baseNameLen],table->key_info[i].name);
- if(table->key_info[i].flags & HA_NOSAME)
- indexUnique = 1;
- else
- indexUnique = 0;
- rc = dsmObjectCreate(pcontext, areaNumber, &indexNumber,
- DSMOBJECT_MIXINDEX,indexUnique,tableNumber,
- DSMOBJECT_MIXTABLE,
- (dsmText_t *)&name_buff[start_of_name],
- &dummy,&dummy);
-
- }
- }
- /* The auto_increment value is the next one to be given
- out so give dsm one less than this value */
- if(create_info->auto_increment_value)
- rc = dsmTableAutoIncrementSet(pcontext,tableNumber,
- create_info->auto_increment_value-1);
-
- /* Get a table lock on this table in case this table is being
- created as part of an alter table statement. We don't want
- the alter table statement to abort because of a lock table overflow
- */
- if (thd->lex.sql_command == SQLCOM_CREATE_INDEX ||
- thd->lex.sql_command == SQLCOM_ALTER_TABLE ||
- thd->lex.sql_command == SQLCOM_DROP_INDEX)
- {
- rc = dsmObjectLock(pcontext,
- (dsmObject_t)tableNumber,DSMOBJECT_TABLE,0,
- DSM_LK_EXCL, 1, 0);
- /* and don't commit so we won't release the table on the table number
- of the table being altered */
- }
- else
- {
- if(!rc)
- rc = gemini_commit(thd);
- }
-
- DBUG_RETURN(rc);
-}
-
-int ha_gemini::delete_table(const char *pname)
-{
- THD *thd;
- dsmStatus_t rc;
- dsmContext_t *pcontext;
- unsigned i,nameLen;
- dsmArea_t indexArea = 0;
- dsmArea_t tableArea = 0;
- dsmObjectAttr_t objectAttr;
- dsmObject_t associate;
- dsmObjectType_t associateType;
- dsmDbkey_t block, root;
- int need_txn = 0;
- dsmObject_t tableNum = 0;
- char name_buff[FN_REFLEN];
- char dbname_buff[FN_REFLEN];
- DBUG_ENTER("ha_gemini::delete_table");
-
- /* separate out the name of the table and the database (a VST must be
- ** located in the mysql database)
- */
- rc = gemini_parse_table_name(pname, dbname_buff, name_buff);
- if (rc == 0)
- {
- /* If the table is a VST, there are no areas or extents to delete */
- if (strcmp(dbname_buff, "mysql") == 0)
- {
- tableNum = gemini_is_vst(name_buff);
- if (tableNum)
- {
- return 0;
- }
- }
- }
-
- thd = current_thd;
- if(thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- rc = gemini_connect(thd);
- if(rc)
- {
- DBUG_RETURN(rc);
- }
- }
- pcontext = (dsmContext_t *)thd->gemini.context;
-
-
- bzero(name_buff, FN_REFLEN);
-
- nameLen = strlen(pname);
- for( i = start_of_name; i < nameLen; i++)
- {
- if(pname[i] == '/' || pname[i] == '\\')
- name_buff[i-start_of_name] = '.';
- else
- name_buff[i-start_of_name] = pname[i];
- }
-
- rc = dsmObjectNameToNum(pcontext, (dsmText_t *)name_buff,
- (dsmObject_t *)&tableNum);
- if (rc)
- {
- gemini_msg(pcontext, "Unable to find table number for %s", name_buff);
- rc = gemini_rollback(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Error in rollback %l",rc);
- }
- DBUG_RETURN(rc);
- }
-
- rc = dsmObjectInfo(pcontext, tableNum, DSMOBJECT_MIXTABLE, tableNum,
- &tableArea, &objectAttr, &associateType, &block, &root);
- if (rc)
- {
- gemini_msg(pcontext, "Failed to get area number for table %d, %s, return %l",
- tableNum, pname, rc);
- rc = gemini_rollback(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Error in rollback %l",rc);
- }
- }
-
- indexArea = DSMAREA_INVALID;
-
- /* Delete the indexes and tables storage objects for with the table */
- rc = dsmObjectDeleteAssociate(pcontext, tableNum, &indexArea);
- if (rc)
- {
- gemini_msg(pcontext, "Error deleting storage objects for table number %d, return %l",
- (int)tableNum, rc);
-
- /* roll back txn and return */
- rc = gemini_rollback(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Error in rollback %l",rc);
- }
- DBUG_RETURN(rc);
- }
-
- if (indexArea != DSMAREA_INVALID)
- {
- /* Delete the extents for both Index and Table */
- rc = dsmExtentDelete(pcontext, indexArea);
- rc = dsmAreaDelete(pcontext, indexArea);
- if (rc)
- {
- gemini_msg(pcontext, "Error deleting Index Area %l, return %l", indexArea, rc);
-
- /* roll back txn and return */
- rc = gemini_rollback(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Error in rollback %l",rc);
- }
- DBUG_RETURN(rc);
- }
- }
-
- rc = dsmExtentDelete(pcontext, tableArea);
- rc = dsmAreaDelete(pcontext, tableArea);
- if (rc)
- {
- gemini_msg(pcontext, "Error deleting table Area %l, name %s, return %l",
- tableArea, pname, rc);
- /* roll back txn and return */
- rc = gemini_rollback(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Error in rollback %l",rc);
- }
- DBUG_RETURN(rc);
- }
-
-
- /* Commit the transaction */
- rc = gemini_commit(thd);
- if (rc)
- {
- gemini_msg(pcontext, "Failed to commit transaction %l",rc);
- }
-
-
- /* now remove all the files that need to be removed and
- cause a checkpoint so recovery will work */
- rc = dsmExtentUnlink(pcontext);
-
- DBUG_RETURN(0);
-}
-
-
-int ha_gemini::rename_table(const char *pfrom, const char *pto)
-{
- THD *thd;
- dsmContext_t *pcontext;
- dsmStatus_t rc;
- char dbname_buff[FN_REFLEN];
- char name_buff[FN_REFLEN];
- char newname_buff[FN_REFLEN];
- char newextname_buff[FN_REFLEN];
- char newidxextname_buff[FN_REFLEN];
- unsigned i, nameLen;
- dsmObject_t tableNum;
- dsmArea_t indexArea = 0;
- dsmArea_t tableArea = 0;
-
- DBUG_ENTER("ha_gemini::rename_table");
-
- /* don't allow rename of VSTs */
- rc = gemini_parse_table_name(pfrom, dbname_buff, name_buff);
- if (rc == 0)
- {
- /* If the table is a VST, don't create areas or extents */
- if (strcmp(dbname_buff, "mysql") == 0)
- {
- if (gemini_is_vst(name_buff))
- {
- return DSM_S_CANT_RENAME_VST;
- }
- }
- }
-
- thd = current_thd;
- if (thd->gemini.context == NULL)
- {
- /* Need to get this thread a connection into the database */
- rc = gemini_connect(thd);
- if (rc)
- {
- DBUG_RETURN(rc);
- }
- }
-
- pcontext = (dsmContext_t *)thd->gemini.context;
-
- /* change the slashes to dots in the old and new names */
- nameLen = strlen(pfrom);
- for( i = start_of_name; i < nameLen; i++)
- {
- if(pfrom[i] == '/' || pfrom[i] == '\\')
- name_buff[i-start_of_name] = '.';
- else
- name_buff[i-start_of_name] = pfrom[i];
- }
- name_buff[i-start_of_name] = '\0';
-
- nameLen = strlen(pto);
- for( i = start_of_name; i < nameLen; i++)
- {
- if(pto[i] == '/' || pto[i] == '\\')
- newname_buff[i-start_of_name] = '.';
- else
- newname_buff[i-start_of_name] = pto[i];
- }
- newname_buff[i-start_of_name] = '\0';
-
- /* generate new extent names (for table and index extents) */
- fn_format(newextname_buff, pto, "", ha_gemini_ext, 2 | 4);
- fn_format(newidxextname_buff, pto, "", ha_gemini_idx_ext, 2 | 4);
-
- rc = dsmObjectNameToNum(pcontext, (dsmText_t *)name_buff, &tableNum);
- if (rc)
- {
- gemini_msg(pcontext, "Unable to file Table number for %s", name_buff);
- goto errorReturn;
- }
-
- rc = dsmObjectRename(pcontext, tableNum,
- (dsmText_t *)newname_buff,
- (dsmText_t *)&newidxextname_buff[start_of_name],
- (dsmText_t *)&newextname_buff[start_of_name],
- &indexArea, &tableArea);
- if (rc)
- {
- gemini_msg(pcontext, "Failed to rename %s to %s",name_buff,newname_buff);
- goto errorReturn;
- }
-
- /* Rename the physical table and index files (if necessary).
- ** Close the file, rename it, and reopen it (have to do it this
- ** way so rename works on Windows).
- */
- if (!(rc = dsmAreaClose(pcontext, tableArea)))
- {
- if (!(rc = rename_file_ext(pfrom, pto, ha_gemini_ext)))
- {
- rc = dsmAreaOpen(pcontext, tableArea, 0);
- if (rc)
- {
- gemini_msg(pcontext, "Failed to reopen area %d",tableArea);
- }
- }
- }
-
- if (!rc && indexArea)
- {
- if (!(rc = dsmAreaClose(pcontext, indexArea)))
- {
- if (!(rc = rename_file_ext(pfrom, pto, ha_gemini_idx_ext)))
- {
- rc = dsmAreaOpen(pcontext, indexArea, 0);
- if (rc)
- {
- gemini_msg(pcontext, "Failed to reopen area %d",tableArea);
- }
- }
- }
- }
-
-errorReturn:
- DBUG_RETURN(rc);
-}
-
-
-/*
- How many seeks it will take to read through the table
- This is to be comparable to the number returned by records_in_range so
- that we can decide if we should scan the table or use keys.
-*/
-
-double ha_gemini::scan_time()
-{
- return (double)records /
- (double)((gemini_blocksize / (double)table->reclength));
-}
-
-int ha_gemini::analyze(THD* thd, HA_CHECK_OPT* check_opt)
-{
- int error;
- uint saveIsolation;
- dsmMask_t saveLockMode;
-
- check_opt->quick = TRUE;
- check_opt->optimize = TRUE; // Tells check not to get table lock
- saveLockMode = lockMode;
- saveIsolation = thd->gemini.tx_isolation;
- thd->gemini.tx_isolation = ISO_READ_UNCOMMITTED;
- lockMode = DSM_LK_NOLOCK;
- error = check(thd,check_opt);
- lockMode = saveLockMode;
- thd->gemini.tx_isolation = saveIsolation;
- return (error);
-}
-
-int ha_gemini::check(THD* thd, HA_CHECK_OPT* check_opt)
-{
- int error = 0;
- int checkStatus = HA_ADMIN_OK;
- ha_rows indexCount;
- byte *buf = 0, *indexBuf = 0, *prevBuf = 0;
- int errorCount = 0;
-
- info(HA_STATUS_VARIABLE); // Makes sure row count is up to date
-
- /* Get a shared table lock */
- if(thd->gemini.needSavepoint)
- {
- /* We don't really need a savepoint here but do it anyway
- just to keep the savepoint number correct. */
- thd->gemini.savepoint++;
- error = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,
- DSMTXN_SAVE, 0, 0);
- if (error)
- return(error);
- thd->gemini.needSavepoint = 0;
- }
- buf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME));
- indexBuf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME));
- prevBuf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME |MY_ZEROFILL ));
-
- /* Lock the table */
- if (!check_opt->optimize)
- error = dsmObjectLock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,
- DSMOBJECT_TABLE,0,
- DSM_LK_SHARE, 1, 0);
- if(error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Failed to lock table %d, error %d",tableNumber, error);
- return error;
- }
-
- ha_rows *rec_per_key = share->rec_per_key;
- /* If quick option just scan along index converting and counting entries */
- for (uint i = 0; i < table->keys; i++)
- {
- key_read = 1; // Causes data to be extracted from the keys
- indexCount = 0;
- // Clear the cardinality stats for this index
- memset(table->key_info[i].rec_per_key,0,
- sizeof(table->key_info[0].rec_per_key[0]) *
- table->key_info[i].key_parts);
- error = index_init(i);
- error = index_first(indexBuf);
- while(!error)
- {
- indexCount++;
- if(!check_opt->quick)
- {
- /* Fetch row and compare to data produced from key */
- error = fetch_row(thd->gemini.context,buf);
- if(!error)
- {
- if(key_cmp(i,buf,indexBuf,FALSE))
- {
-
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Check Error! Key does not match row for rowid %d for index %s",
- lastRowid,table->key_info[i].name);
- print_msg(thd,table->real_name,"check","error",
- "Key does not match row for rowid %d for index %s",
- lastRowid,table->key_info[i].name);
- checkStatus = HA_ADMIN_CORRUPT;
- errorCount++;
- if(errorCount > 1000)
- goto error_return;
- }
- else if(error == DSM_S_RMNOTFND)
- {
- errorCount++;
- checkStatus = HA_ADMIN_CORRUPT;
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Check Error! Key does not have a valid row pointer %d for index %s",
- lastRowid,table->key_info[i].name);
- print_msg(thd,table->real_name,"check","error",
- "Key does not have a valid row pointer %d for index %s",
- lastRowid,table->key_info[i].name);
- if(errorCount > 1000)
- goto error_return;
- error = 0;
- }
- }
- }
-
- key_cmp(i,indexBuf,prevBuf,TRUE);
- bcopy((void *)indexBuf,(void *)prevBuf,table->rec_buff_length);
-
- if(!error)
- error = index_next(indexBuf);
- }
-
- for(uint j=1; j < table->key_info[i].key_parts; j++)
- {
- table->key_info[i].rec_per_key[j] += table->key_info[i].rec_per_key[j-1];
- }
- for(uint k=0; k < table->key_info[i].key_parts; k++)
- {
- if (table->key_info[i].rec_per_key[k])
- table->key_info[i].rec_per_key[k] =
- records / table->key_info[i].rec_per_key[k];
- *rec_per_key = table->key_info[i].rec_per_key[k];
- rec_per_key++;
- }
-
- if(error == HA_ERR_END_OF_FILE)
- {
- /* Check count of rows */
-
- if(records != indexCount)
- {
- /* Number of index entries does not agree with the number of
- rows in the index. */
- checkStatus = HA_ADMIN_CORRUPT;
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Check Error! Total rows %d does not match total index entries %d for %s",
- records, indexCount,
- table->key_info[i].name);
- print_msg(thd,table->real_name,"check","error",
- "Total rows %d does not match total index entries %d for %s",
- records, indexCount,
- table->key_info[i].name);
- }
- }
- else
- {
- checkStatus = HA_ADMIN_FAILED;
- goto error_return;
- }
- index_end();
- }
- if(!check_opt->quick)
- {
- /* Now scan the table and for each row generate the keys
- and find them in the index */
- error = fullCheck(thd, buf);
- if(error)
- checkStatus = error;
- }
- // Store the key distribution information
- error = saveKeyStats(thd);
-
-error_return:
- my_free((char*)buf,MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*)indexBuf,MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*)prevBuf,MYF(MY_ALLOW_ZERO_PTR));
-
- index_end();
- key_read = 0;
- if(!check_opt->optimize)
- {
- error = dsmObjectUnlock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,
- DSMOBJECT_TABLE,0,
- DSM_LK_SHARE,0);
- if (error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Unable to unlock table %d", tableNumber);
- }
- }
-
- return checkStatus;
-}
-
-int ha_gemini::saveKeyStats(THD *thd)
-{
- dsmStatus_t rc = 0;
-
- /* Insert a row in the indexStats table for each column of
- each index of the table */
-
- for(uint i = 0; i < table->keys; i++)
- {
- for (uint j = 0; j < table->key_info[i].key_parts && !rc ;j++)
- {
- rc = dsmIndexStatsPut((dsmContext_t *)thd->gemini.context,
- tableNumber, pindexNumbers[i],
- j, (LONG64)table->key_info[i].rec_per_key[j]);
- if (rc)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Failed to update index stats for table %d, index %d",
- tableNumber, pindexNumbers[i]);
- }
- }
- }
- return rc;
-}
-
-int ha_gemini::fullCheck(THD *thd,byte *buf)
-{
- int error;
- int errorCount = 0;
- int checkStatus = 0;
-
- lastRowid = 0;
-
- while(((error = rnd_next( buf)) != HA_ERR_END_OF_FILE) && errorCount <= 1000)
- {
- if(!error)
- {
- error = handleIndexEntries(buf,lastRowid,KEY_CHECK);
- if(error)
- {
- /* Error finding an index entry for a row. */
- print_msg(thd,table->real_name,"check","error",
- "Unable to find all index entries for row %d",
- lastRowid);
- errorCount++;
- checkStatus = HA_ADMIN_CORRUPT;
- error = 0;
- }
- }
- else
- {
- /* Error reading a row */
- print_msg(thd,table->real_name,"check","error",
- "Error reading row %d status = %d",
- lastRowid,error);
- errorCount++;
- checkStatus = HA_ADMIN_CORRUPT;
- error = 0;
- }
- }
-
- return checkStatus;
-}
-
-int ha_gemini::repair(THD* thd, HA_CHECK_OPT* check_opt)
-{
- int error;
- dsmRecord_t dsmRecord;
- byte *buf;
-
- if(thd->gemini.needSavepoint)
- {
- /* We don't really need a savepoint here but do it anyway
- just to keep the savepoint number correct. */
- thd->gemini.savepoint++;
- error = dsmTransaction((dsmContext_t *)thd->gemini.context,
- &thd->gemini.savepoint,
- DSMTXN_SAVE, 0, 0);
- if (error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Error setting savepoint number %d, error %d",
- thd->gemini.savepoint++, error);
- return(error);
- }
- thd->gemini.needSavepoint = 0;
- }
-
-
- /* Lock the table */
- error = dsmObjectLock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,
- DSMOBJECT_TABLE,0,
- DSM_LK_EXCL, 1, 0);
- if(error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Failed to lock table %d, error %d",tableNumber, error);
- return error;
- }
-
- error = dsmContextSetLong((dsmContext_t *)thd->gemini.context,
- DSM_TAGCONTEXT_NO_LOGGING,1);
-
- error = dsmTableReset((dsmContext_t *)thd->gemini.context,
- (dsmTable_t)tableNumber, table->keys,
- pindexNumbers);
- if (error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "dsmTableReset failed for table %d, error %d",tableNumber, error);
- }
-
- buf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME));
- dsmRecord.table = tableNumber;
- dsmRecord.recid = 0;
- dsmRecord.pbuffer = (dsmBuffer_t *)rec_buff;
- dsmRecord.recLength = table->reclength;
- dsmRecord.maxLength = table->rec_buff_length;
- while(!error)
- {
- error = dsmTableScan((dsmContext_t *)thd->gemini.context,
- &dsmRecord, DSMFINDNEXT, DSM_LK_NOLOCK,
- 1);
- if(!error)
- {
- if (!(error = unpack_row((char *)buf,(char *)dsmRecord.pbuffer)))
- {
- error = handleIndexEntries(buf,dsmRecord.recid,KEY_CREATE);
- if(error == HA_ERR_FOUND_DUPP_KEY)
- {
- /* We don't want to stop on duplicate keys -- we're repairing
- here so let's get as much repaired as possible. */
- error = 0;
- }
- }
- }
- }
- error = dsmObjectUnlock((dsmContext_t *)thd->gemini.context,
- (dsmObject_t)tableNumber,
- DSMOBJECT_TABLE,0,
- DSM_LK_EXCL,0);
- if (error)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Unable to unlock table %d", tableNumber);
- }
-
- my_free((char*)buf,MYF(MY_ALLOW_ZERO_PTR));
-
- error = dsmContextSetLong((dsmContext_t *)thd->gemini.context,
- DSM_TAGCONTEXT_NO_LOGGING,0);
-
- return error;
-}
-
-
-int ha_gemini::restore(THD* thd, HA_CHECK_OPT *check_opt)
-{
- dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context;
- char* backup_dir = thd->lex.backup_dir;
- char src_path[FN_REFLEN], dst_path[FN_REFLEN];
- char* table_name = table->real_name;
- int error = 0;
- int errornum;
- const char* errmsg = "";
- dsmArea_t tableArea = 0;
- dsmObjectAttr_t objectAttr;
- dsmObject_t associate;
- dsmObjectType_t associateType;
- dsmDbkey_t block, root;
- dsmStatus_t rc;
-
- rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXTABLE, tableNumber,
- &tableArea, &objectAttr, &associateType, &block, &root);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmObjectInfo (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaFlush(pcontext, tableArea, FLUSH_BUFFERS | FLUSH_SYNC);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaFlush (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaClose(pcontext, tableArea);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaClose (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- /* Restore the data file */
- if (!fn_format(src_path, table_name, backup_dir, ha_gemini_ext, 4 + 64))
- {
- return HA_ADMIN_INVALID;
- }
-
- if (my_copy(src_path, fn_format(dst_path, table->path, "",
- ha_gemini_ext, 4), MYF(MY_WME)))
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in my_copy (.gmd) (Error %d)";
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaFlush(pcontext, tableArea, FREE_BUFFERS);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaFlush (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaOpen(pcontext, tableArea, 1);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaOpen (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
-#ifdef GEMINI_BACKUP_IDX
- dsmArea_t indexArea = 0;
-
- rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXINDEX, &indexArea,
- &objectAttr, &associate, &associateType, &block, &root);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmObjectInfo (.gmi) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaClose(pcontext, indexArea);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaClose (.gmi) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- /* Restore the index file */
- if (!fn_format(src_path, table_name, backup_dir, ha_gemini_idx_ext, 4 + 64))
- {
- return HA_ADMIN_INVALID;
- }
-
- if (my_copy(src_path, fn_format(dst_path, table->path, "",
- ha_gemini_idx_ext, 4), MYF(MY_WME)))
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in my_copy (.gmi) (Error %d)";
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- rc = dsmAreaOpen(pcontext, indexArea, 1);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaOpen (.gmi) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- return HA_ADMIN_OK;
-#else /* #ifdef GEMINI_BACKUP_IDX */
- HA_CHECK_OPT tmp_check_opt;
- tmp_check_opt.init();
- /* The following aren't currently implemented in ha_gemini::repair
- ** tmp_check_opt.quick = 1;
- ** tmp_check_opt.flags |= T_VERY_SILENT;
- */
- return (repair(thd, &tmp_check_opt));
-#endif /* #ifdef GEMINI_BACKUP_IDX */
-
- err:
- {
-#if 0
- /* mi_check_print_error is in ha_myisam.cc, so none of the informative
- ** error messages above is currently being printed
- */
- MI_CHECK param;
- myisamchk_init(&param);
- param.thd = thd;
- param.op_name = (char*)"restore";
- param.table_name = table->table_name;
- param.testflag = 0;
- mi_check_print_error(&param,errmsg, errornum);
-#endif
- return error;
- }
-}
-
-
-int ha_gemini::backup(THD* thd, HA_CHECK_OPT *check_opt)
-{
- dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context;
- char* backup_dir = thd->lex.backup_dir;
- char src_path[FN_REFLEN], dst_path[FN_REFLEN];
- char* table_name = table->real_name;
- int error = 0;
- int errornum;
- const char* errmsg = "";
- dsmArea_t tableArea = 0;
- dsmObjectAttr_t objectAttr;
- dsmObject_t associate;
- dsmObjectType_t associateType;
- dsmDbkey_t block, root;
- dsmStatus_t rc;
-
- rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXTABLE, tableNumber,
- &tableArea, &objectAttr, &associateType, &block, &root);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmObjectInfo (.gmd) (Error %d)";
- errornum = rc;
- goto err;
- }
-
- /* Flush the buffers before backing up the table */
- dsmAreaFlush((dsmContext_t *)thd->gemini.context, tableArea,
- FLUSH_BUFFERS | FLUSH_SYNC);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmAreaFlush (.gmd) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- /* Backup the .FRM file */
- if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64))
- {
- errmsg = "Failed in fn_format() for .frm file: errno = %d";
- error = HA_ADMIN_INVALID;
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4),
- dst_path,
- MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )))
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed copying .frm file: errno = %d";
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- /* Backup the data file */
- if (!fn_format(dst_path, table_name, backup_dir, ha_gemini_ext, 4 + 64))
- {
- errmsg = "Failed in fn_format() for .GMD file: errno = %d";
- error = HA_ADMIN_INVALID;
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- if (my_copy(fn_format(src_path, table->path,"", ha_gemini_ext, 4),
- dst_path,
- MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) )
- {
- errmsg = "Failed copying .GMD file: errno = %d";
- error= HA_ADMIN_FAILED;
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
-#ifdef GEMINI_BACKUP_IDX
- dsmArea_t indexArea = 0;
-
- rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXINDEX, &indexArea,
- &objectAttr, &associate, &associateType, &block, &root);
- if (rc)
- {
- error = HA_ADMIN_FAILED;
- errmsg = "Failed in dsmObjectInfo (.gmi) (Error %d)";
- errornum = rc;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- /* Backup the index file */
- if (!fn_format(dst_path, table_name, backup_dir, ha_gemini_idx_ext, 4 + 64))
- {
- errmsg = "Failed in fn_format() for .GMI file: errno = %d";
- error = HA_ADMIN_INVALID;
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-
- if (my_copy(fn_format(src_path, table->path,"", ha_gemini_idx_ext, 4),
- dst_path,
- MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) )
- {
- errmsg = "Failed copying .GMI file: errno = %d";
- error= HA_ADMIN_FAILED;
- errornum = errno;
- gemini_msg(pcontext, errmsg ,errornum);
- goto err;
- }
-#endif /* #ifdef GEMINI_BACKUP_IDX */
-
- return HA_ADMIN_OK;
-
- err:
- {
-#if 0
- /* mi_check_print_error is in ha_myisam.cc, so none of the informative
- ** error messages above is currently being printed
- */
- MI_CHECK param;
- myisamchk_init(&param);
- param.thd = thd;
- param.op_name = (char*)"backup";
- param.table_name = table->table_name;
- param.testflag = 0;
- mi_check_print_error(&param,errmsg, errornum);
-#endif
- return error;
- }
-}
-
-
-int ha_gemini::optimize(THD* thd, HA_CHECK_OPT *check_opt)
-{
- return HA_ADMIN_ALREADY_DONE;
-}
-
-
-ha_rows ha_gemini::records_in_range(int keynr,
- const byte *start_key,uint start_key_len,
- enum ha_rkey_function start_search_flag,
- const byte *end_key,uint end_key_len,
- enum ha_rkey_function end_search_flag)
-{
- int error;
- int componentLen;
- float pctInrange;
- ha_rows rows = 5;
-
- DBUG_ENTER("records_in_range");
-
- error = index_init(keynr);
- if(error)
- DBUG_RETURN(rows);
-
- pbracketBase->index = (short)pindexNumbers[keynr];
- pbracketBase->keycomps = 1;
-
- if(start_key)
- {
- error = pack_key(keynr, pbracketBase, start_key, start_key_len);
- if(start_search_flag == HA_READ_AFTER_KEY)
- {
- /* A greater than operation */
- error = gemKeyAddLow(pbracketBase->keystr + pbracketBase->keyLen,
- &componentLen);
- pbracketBase->keyLen += componentLen;
- }
- }
- else
- {
- error = gemKeyLow(pbracketBase->keystr, &componentLen,
- pbracketBase->index);
- pbracketBase->keyLen = componentLen;
-
- }
- pbracketBase->keyLen -= FULLKEYHDRSZ;
-
- if(end_key)
- {
- error = pack_key(keynr, pbracketLimit, end_key, end_key_len);
- if(!error && end_search_flag == HA_READ_AFTER_KEY)
- {
- error = gemKeyAddHigh(pbracketLimit->keystr + pbracketLimit->keyLen,
- &componentLen);
- pbracketLimit->keyLen += componentLen;
- }
- }
- else
- {
- error = gemKeyHigh(pbracketLimit->keystr,&componentLen,
- pbracketLimit->index);
- pbracketLimit->keyLen = componentLen;
- }
-
- pbracketLimit->keyLen -= FULLKEYHDRSZ;
- error = dsmIndexRowsInRange((dsmContext_t *)current_thd->gemini.context,
- pbracketBase,pbracketLimit,
- tableNumber,
- &pctInrange);
- if(pctInrange >= 1)
- rows = (ha_rows)pctInrange;
- else
- {
- rows = (ha_rows)(records * pctInrange);
- if(!rows && pctInrange > 0)
- rows = 1;
- }
- index_end();
-
- DBUG_RETURN(rows);
-}
-
-
-/*
- Pack a row for storage. If the row is of fixed length, just store the
- row 'as is'.
- If not, we will generate a packed row suitable for storage.
- This will only fail if we don't have enough memory to pack the row, which;
- may only happen in rows with blobs, as the default row length is
- pre-allocated.
-*/
-int ha_gemini::pack_row(byte **pprow, int *ppackedLength, const byte *record,
- bool update)
-{
- THD *thd = current_thd;
- dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context;
- gemBlobDesc_t *pBlobDesc = pBlobDescs;
-
- if (fixed_length_row)
- {
- *pprow = (byte *)record;
- *ppackedLength=(int)table->reclength;
- return 0;
- }
- /* Copy null bits */
- memcpy(rec_buff, record, table->null_bytes);
- byte *ptr=rec_buff + table->null_bytes;
-
- for (Field **field=table->field ; *field ; field++)
- {
-#ifdef GEMINI_TINYBLOB_IN_ROW
- /* Tiny blobs (255 bytes or less) are stored in the row; larger
- ** blobs are stored in a separate storage object (see ha_gemini::create).
- */
- if ((*field)->type() == FIELD_TYPE_BLOB &&
- ((Field_blob*)*field)->blobtype() != FIELD_TYPE_TINY_BLOB)
-#else
- if ((*field)->type() == FIELD_TYPE_BLOB)
-#endif
- {
- dsmBlob_t gemBlob;
- char *blobptr;
-
- gemBlob.areaType = DSMOBJECT_BLOB;
- gemBlob.blobObjNo = tableNumber;
- gemBlob.blobId = 0;
- gemBlob.totLength = gemBlob.segLength =
- ((Field_blob*)*field)->get_length((char*)record + (*field)->offset());
- ((Field_blob*)*field)->get_ptr((char**) &blobptr);
- gemBlob.pBuffer = (dsmBuffer_t *)blobptr;
- gemBlob.blobContext.blobOffset = 0;
- if (gemBlob.totLength)
- {
- dsmBlobStart(pcontext, &gemBlob);
- if (update && pBlobDesc->blobId)
- {
- gemBlob.blobId = pBlobDesc->blobId;
- dsmBlobUpdate(pcontext, &gemBlob, NULL);
- }
- else
- {
- dsmBlobPut(pcontext, &gemBlob, NULL);
- }
- dsmBlobEnd(pcontext, &gemBlob);
- }
- ptr = (byte*)((Field_blob*)*field)->pack_id((char*) ptr,
- (char*)record + (*field)->offset(), (longlong)gemBlob.blobId);
-
- pBlobDesc++;
- }
- else
- {
- ptr=(byte*) (*field)->pack((char*) ptr, (char*)record + (*field)->offset());
- }
- }
-
- *pprow=rec_buff;
- *ppackedLength= (ptr - rec_buff);
- return 0;
-}
-
-int ha_gemini::unpack_row(char *record, char *prow)
-{
- THD *thd = current_thd;
- dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context;
- gemBlobDesc_t *pBlobDesc = pBlobDescs;
-
- if (fixed_length_row)
- {
- /* If the table is a VST, the row is in Gemini internal format.
- ** Convert the fields to MySQL format.
- */
- if (RM_IS_VST(tableNumber))
- {
- int i = 2; /* VST fields are numbered sequentially starting at 2 */
- long longValue;
- char *fld;
- unsigned long unknown;
-
- for (Field **field = table->field; *field; field++, i++)
- {
- switch ((*field)->type())
- {
- case FIELD_TYPE_LONG:
- case FIELD_TYPE_TINY:
- case FIELD_TYPE_SHORT:
- case FIELD_TYPE_TIMESTAMP:
- case FIELD_TYPE_LONGLONG:
- case FIELD_TYPE_INT24:
- case FIELD_TYPE_DATE:
- case FIELD_TYPE_TIME:
- case FIELD_TYPE_DATETIME:
- case FIELD_TYPE_YEAR:
- case FIELD_TYPE_NEWDATE:
- case FIELD_TYPE_ENUM:
- case FIELD_TYPE_SET:
- recGetLONG((dsmText_t *)prow, i, 0, &longValue, &unknown);
- if (unknown)
- {
- (*field)->set_null();
- }
- else
- {
- (*field)->set_notnull();
- (*field)->store((longlong)longValue);
- }
- break;
-
- case FIELD_TYPE_DECIMAL:
- case FIELD_TYPE_DOUBLE:
- case FIELD_TYPE_TINY_BLOB:
- case FIELD_TYPE_MEDIUM_BLOB:
- case FIELD_TYPE_LONG_BLOB:
- case FIELD_TYPE_BLOB:
- case FIELD_TYPE_VAR_STRING:
- break;
-
- case FIELD_TYPE_STRING:
- svcByteString_t stringFld;
-
- fld = (char *)my_malloc((*field)->field_length, MYF(MY_WME));
- stringFld.pbyte = (TEXT *)fld;
- stringFld.size = (*field)->field_length;
- recGetBYTES((dsmText_t *)prow, i, 0, &stringFld, &unknown);
- if (unknown)
- {
- (*field)->set_null();
- }
- else
- {
- (*field)->set_notnull();
- (*field)->store(fld, (*field)->field_length);
- }
- my_free(fld, MYF(MY_ALLOW_ZERO_PTR));
- break;
-
- default:
- break;
- }
- }
- }
- else
- {
- memcpy(record,(char*) prow,table->reclength);
- }
- }
- else
- {
- /* Copy null bits */
- const char *ptr= (const char*) prow;
- memcpy(record, ptr, table->null_bytes);
- ptr+=table->null_bytes;
-
- for (Field **field=table->field ; *field ; field++)
- {
-#ifdef GEMINI_TINYBLOB_IN_ROW
- /* Tiny blobs (255 bytes or less) are stored in the row; larger
- ** blobs are stored in a separate storage object (see ha_gemini::create).
- */
- if ((*field)->type() == FIELD_TYPE_BLOB &&
- ((Field_blob*)*field)->blobtype() != FIELD_TYPE_TINY_BLOB)
-#else
- if ((*field)->type() == FIELD_TYPE_BLOB)
-#endif
- {
- dsmBlob_t gemBlob;
-
- gemBlob.areaType = DSMOBJECT_BLOB;
- gemBlob.blobObjNo = tableNumber;
- gemBlob.blobId = (dsmBlobId_t)(((Field_blob*)*field)->get_id(ptr));
- if (gemBlob.blobId)
- {
- gemBlob.totLength =
- gemBlob.segLength = ((Field_blob*)*field)->get_length(ptr);
- /* Allocate memory to store the blob. This memory is freed
- ** the next time unpack_row is called for this table.
- */
- gemBlob.pBuffer = (dsmBuffer_t *)my_malloc(gemBlob.totLength,
- MYF(0));
- if (!gemBlob.pBuffer)
- {
- return HA_ERR_OUT_OF_MEM;
- }
- gemBlob.blobContext.blobOffset = 0;
- dsmBlobStart(pcontext, &gemBlob);
- dsmBlobGet(pcontext, &gemBlob, NULL);
- dsmBlobEnd(pcontext, &gemBlob);
- }
- else
- {
- gemBlob.pBuffer = 0;
- }
- ptr = ((Field_blob*)*field)->unpack_id(record + (*field)->offset(),
- ptr, (char *)gemBlob.pBuffer);
- pBlobDesc->blobId = gemBlob.blobId;
- my_free((char*)pBlobDesc->pBlob, MYF(MY_ALLOW_ZERO_PTR));
- pBlobDesc->pBlob = gemBlob.pBuffer;
- pBlobDesc++;
- }
- else
- {
- ptr= (*field)->unpack(record + (*field)->offset(), ptr);
- }
- }
- }
-
- return 0;
-}
-
-int ha_gemini::key_cmp(uint keynr, const byte * old_row,
- const byte * new_row, bool updateStats)
-{
- KEY_PART_INFO *key_part=table->key_info[keynr].key_part;
- KEY_PART_INFO *end=key_part+table->key_info[keynr].key_parts;
-
- for ( uint i = 0 ; key_part != end ; key_part++, i++)
- {
- if (key_part->null_bit)
- {
- if ((old_row[key_part->null_offset] & key_part->null_bit) !=
- (new_row[key_part->null_offset] & key_part->null_bit))
- {
- if(updateStats)
- table->key_info[keynr].rec_per_key[i]++;
- return 1;
- }
- else if((old_row[key_part->null_offset] & key_part->null_bit) &&
- (new_row[key_part->null_offset] & key_part->null_bit))
- /* Both are null */
- continue;
- }
- if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH))
- {
- if (key_part->field->cmp_binary((char*)(old_row + key_part->offset),
- (char*)(new_row + key_part->offset),
- (ulong) key_part->length))
- {
- if(updateStats)
- table->key_info[keynr].rec_per_key[i]++;
- return 1;
- }
- }
- else
- {
- if (memcmp(old_row+key_part->offset, new_row+key_part->offset,
- key_part->length))
- {
- /* Check for special case of -0 which causes table check
- to find an invalid key when comparing the the index
- value of 0 to the -0 stored in the row */
- if(key_part->field->type() == FIELD_TYPE_DECIMAL)
- {
- double fieldValue;
- char *ptr = key_part->field->ptr;
-
- key_part->field->ptr = (char *)old_row + key_part->offset;
- fieldValue = key_part->field->val_real();
- if(fieldValue == 0)
- {
- key_part->field->ptr = (char *)new_row + key_part->offset;
- fieldValue = key_part->field->val_real();
- if(fieldValue == 0)
- {
- key_part->field->ptr = ptr;
- continue;
- }
- }
- key_part->field->ptr = ptr;
- }
- if(updateStats)
- {
- table->key_info[keynr].rec_per_key[i]++;
- }
- return 1;
- }
- }
- }
- return 0;
-}
-
-int gemini_parse_table_name(const char *fullname, char *dbname, char *tabname)
-{
- char *namestart;
- char *nameend;
-
- /* separate out the name of the table and the database
- */
- namestart = (char *)strchr(fullname + start_of_name, '/');
- if (!namestart)
- {
- /* if on Windows, slashes go the other way */
- namestart = (char *)strchr(fullname + start_of_name, '\\');
- }
- nameend = (char *)strchr(fullname + start_of_name, '.');
- /* sometimes fullname has an extension, sometimes it doesn't */
- if (!nameend)
- {
- nameend = (char *)fullname + strlen(fullname);
- }
- strncpy(dbname, fullname + start_of_name,
- (namestart - fullname) - start_of_name);
- dbname[(namestart - fullname) - start_of_name] = '\0';
- strncpy(tabname, namestart + 1, (nameend - namestart) - 1);
- tabname[nameend - namestart - 1] = '\0';
-
- return 0;
-}
-
-/* PROGRAM: gemini_is_vst - if the name is the name of a VST, return
- * its number
- *
- * RETURNS: Table number if a match is found
- * 0 if not a VST
- */
-int
-gemini_is_vst(const char *pname) /* IN the name */
-{
- int tablenum = 0;
-
- for (int i = 0; i < vstnumfils; i++)
- {
- if (strcmp(pname, vstfil[i].filename) == 0)
- {
- tablenum = vstfil[i].filnum;
- break;
- }
- }
-
- return tablenum;
-}
-
-static void print_msg(THD *thd, const char *table_name, const char *op_name,
- const char *msg_type, const char *fmt, ...)
-{
- String* packet = &thd->packet;
- packet->length(0);
- char msgbuf[256];
- msgbuf[0] = 0;
- va_list args;
- va_start(args,fmt);
-
- my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
- msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
-
- DBUG_PRINT(msg_type,("message: %s",msgbuf));
-
- net_store_data(packet, table_name);
- net_store_data(packet, op_name);
- net_store_data(packet, msg_type);
- net_store_data(packet, msgbuf);
- if (my_net_write(&thd->net, (char*)thd->packet.ptr(),
- thd->packet.length()))
- thd->killed=1;
-}
-
-/* Load shared area with rows per key statistics */
-void
-ha_gemini::get_index_stats(THD *thd)
-{
- dsmStatus_t rc = 0;
- ha_rows *rec_per_key = share->rec_per_key;
-
- for(uint i = 0; i < table->keys && !rc; i++)
- {
- for (uint j = 0; j < table->key_info[i].key_parts && !rc;j++)
- {
- LONG64 rows_per_key;
- rc = dsmIndexStatsGet((dsmContext_t *)thd->gemini.context,
- tableNumber, pindexNumbers[i],(int)j,
- &rows_per_key);
- if (rc)
- {
- gemini_msg((dsmContext_t *)thd->gemini.context,
- "Index Statistics faild for table %d index %d, error %d",
- tableNumber, pindexNumbers[i], rc);
- }
- *rec_per_key = (ha_rows)rows_per_key;
- rec_per_key++;
- }
- }
- return;
-}
-
-/****************************************************************************
- Handling the shared GEM_SHARE structure that is needed to provide
- a global in memory storage location of the rec_per_key stats used
- by the optimizer.
-****************************************************************************/
-
-static byte* gem_get_key(GEM_SHARE *share,uint *length,
- my_bool not_used __attribute__((unused)))
-{
- *length=share->table_name_length;
- return (byte*) share->table_name;
-}
-
-static GEM_SHARE *get_share(const char *table_name, TABLE *table)
-{
- GEM_SHARE *share;
-
- pthread_mutex_lock(&gem_mutex);
- uint length=(uint) strlen(table_name);
- if (!(share=(GEM_SHARE*) hash_search(&gem_open_tables, (byte*) table_name,
- length)))
- {
- ha_rows *rec_per_key;
- char *tmp_name;
-
- if ((share=(GEM_SHARE *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
- &share, sizeof(*share),
- &rec_per_key, table->key_parts * sizeof(ha_rows),
- &tmp_name, length+1,
- NullS)))
- {
- share->rec_per_key = rec_per_key;
- share->table_name = tmp_name;
- share->table_name_length=length;
- strcpy(share->table_name,table_name);
- if (hash_insert(&gem_open_tables, (byte*) share))
- {
- pthread_mutex_unlock(&gem_mutex);
- my_free((gptr) share,0);
- return 0;
- }
- thr_lock_init(&share->lock);
- pthread_mutex_init(&share->mutex,NULL);
- }
- }
- pthread_mutex_unlock(&gem_mutex);
- return share;
-}
-
-static int free_share(GEM_SHARE *share, bool mutex_is_locked)
-{
- pthread_mutex_lock(&gem_mutex);
- if (mutex_is_locked)
- pthread_mutex_unlock(&share->mutex);
- if (!--share->use_count)
- {
- hash_delete(&gem_open_tables, (byte*) share);
- thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->mutex);
- my_free((gptr) share, MYF(0));
- }
- pthread_mutex_unlock(&gem_mutex);
- return 0;
-}
-
-static void gemini_lock_table_overflow_error(dsmContext_t *pcontext)
-{
- gemini_msg(pcontext, "The total number of locks exceeds the lock table size");
- gemini_msg(pcontext, "Either increase gemini_lock_table_size or use a");
- gemini_msg(pcontext, "different transaction isolation level");
-}
-
-#endif /* HAVE_GEMINI_DB */
diff --git a/sql/ha_gemini.h b/sql/ha_gemini.h
deleted file mode 100644
index 96c0cdd4241..00000000000
--- a/sql/ha_gemini.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & NuSphere Corporation
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-#include "gem_global.h"
-#include "dstd.h"
-#include "dsmpub.h"
-
-/* class for the the gemini handler */
-
-enum enum_key_string_options{KEY_CREATE,KEY_DELETE,KEY_CHECK};
-typedef struct st_gemini_share {
- ha_rows *rec_per_key;
- THR_LOCK lock;
- pthread_mutex_t mutex;
- char *table_name;
- uint table_name_length,use_count;
-} GEM_SHARE;
-
-typedef struct gemBlobDesc
-{
- dsmBlobId_t blobId;
- dsmBuffer_t *pBlob;
-} gemBlobDesc_t;
-
-class ha_gemini: public handler
-{
- /* define file as an int for now until we have a real file struct */
- int file;
- uint int_option_flag;
- int tableNumber;
- dsmIndex_t *pindexNumbers; // dsm object numbers for the indexes on this table
- dsmRecid_t lastRowid;
- uint last_dup_key;
- bool fixed_length_row, key_read, using_ignore;
- byte *rec_buff;
- dsmKey_t *pbracketBase;
- dsmKey_t *pbracketLimit;
- dsmKey_t *pfoundKey;
- dsmMask_t tableStatus; // Crashed/repair status
- gemBlobDesc_t *pBlobDescs;
-
- int index_open(char *tableName);
- int pack_row(byte **prow, int *ppackedLength, const byte *record,
- bool update);
- int unpack_row(char *record, char *prow);
- int findRow(THD *thd, dsmMask_t findMode, byte *buf);
- int fetch_row(void *gemini_context, const byte *buf);
- int handleIndexEntries(const byte * record, dsmRecid_t recid,
- enum_key_string_options option);
-
- int handleIndexEntry(const byte * record, dsmRecid_t recid,
- enum_key_string_options option,uint keynr);
-
- int createKeyString(const byte * record, KEY *pkeyinfo,
- unsigned char *pkeyBuf, int bufSize,
- int *pkeyStringLen, short geminiIndexNumber,
- bool *thereIsAnull);
- int fullCheck(THD *thd,byte *buf);
-
- int pack_key( uint keynr, dsmKey_t *pkey,
- const byte *key_ptr, uint key_length);
-
- void unpack_key(char *record, dsmKey_t *key, uint index);
-
- int key_cmp(uint keynr, const byte * old_row,
- const byte * new_row, bool updateStats);
-
- int saveKeyStats(THD *thd);
- void get_index_stats(THD *thd);
-
- short cursorId; /* cursorId of active index cursor if any */
- dsmMask_t lockMode; /* Shared or exclusive */
-
- /* FIXFIX Don't know why we need this because I don't know what
- store_lock method does but we core dump without this */
- THR_LOCK_DATA lock;
- GEM_SHARE *share;
-
- public:
- ha_gemini(TABLE *table): handler(table), file(0),
- int_option_flag(HA_READ_NEXT | HA_READ_PREV |
- HA_REC_NOT_IN_SEQ |
- HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
- HA_LONGLONG_KEYS | HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY |
- HA_BLOB_KEY |
- HA_NO_TEMP_TABLES | HA_NO_FULLTEXT_KEY |
- /*HA_NOT_EXACT_COUNT | */
- /*HA_KEY_READ_WRONG_STR |*/ HA_DROP_BEFORE_CREATE),
- pbracketBase(0),pbracketLimit(0),pfoundKey(0),
- cursorId(0)
- {
- }
- ~ha_gemini() {}
- const char *table_type() const { return "Gemini"; }
- const char **bas_ext() const;
- ulong option_flag() const { return int_option_flag; }
- uint max_record_length() const { return MAXRECSZ; }
- uint max_keys() const { return MAX_KEY-1; }
- uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return MAXKEYSZ / 2; }
- bool fast_key_read() { return 1;}
- bool has_transactions() { return 1;}
-
- int open(const char *name, int mode, uint test_if_locked);
- int close(void);
- double scan_time();
- int write_row(byte * buf);
- int update_row(const byte * old_data, byte * new_data);
- int delete_row(const byte * buf);
- int index_init(uint index);
- int index_end();
- int index_read(byte * buf, const byte * key,
- uint key_len, enum ha_rkey_function find_flag);
- int index_read_idx(byte * buf, uint index, const byte * key,
- uint key_len, enum ha_rkey_function find_flag);
- int index_next(byte * buf);
- int index_next_same(byte * buf, const byte *key, uint keylen);
- int index_prev(byte * buf);
- int index_first(byte * buf);
- int index_last(byte * buf);
- int rnd_init(bool scan=1);
- int rnd_end();
- int rnd_next(byte *buf);
- int rnd_pos(byte * buf, byte *pos);
- void position(const byte *record);
- void info(uint);
- int extra(enum ha_extra_function operation);
- int reset(void);
- int analyze(THD* thd, HA_CHECK_OPT* check_opt);
- int check(THD* thd, HA_CHECK_OPT* check_opt);
- int repair(THD* thd, HA_CHECK_OPT* check_opt);
- int restore(THD* thd, HA_CHECK_OPT* check_opt);
- int backup(THD* thd, HA_CHECK_OPT* check_opt);
- int optimize(THD* thd, HA_CHECK_OPT* check_opt);
- int external_lock(THD *thd, int lock_type);
- virtual longlong get_auto_increment();
- void position(byte *record);
- ha_rows records_in_range(int inx,
- const byte *start_key,uint start_key_len,
- enum ha_rkey_function start_search_flag,
- const byte *end_key,uint end_key_len,
- enum ha_rkey_function end_search_flag);
- void update_create_info(HA_CREATE_INFO *create_info);
- int create(const char *name, register TABLE *form,
- HA_CREATE_INFO *create_info);
- int delete_table(const char *name);
- int rename_table(const char* from, const char* to);
- THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
- enum thr_lock_type lock_type);
-};
-
-#define GEMOPT_FLUSH_LOG 0x00000001
-#define GEMOPT_UNBUFFERED_IO 0x00000002
-
-#define GEMINI_RECOVERY_FULL 0x00000001
-#define GEMINI_RECOVERY_NONE 0x00000002
-#define GEMINI_RECOVERY_FORCE 0x00000004
-
-#define GEM_OPTID_SPIN_RETRIES 1
-
-extern bool gemini_skip;
-extern SHOW_COMP_OPTION have_gemini;
-extern long gemini_options;
-extern long gemini_buffer_cache;
-extern long gemini_io_threads;
-extern long gemini_log_cluster_size;
-extern long gemini_locktablesize;
-extern long gemini_lock_wait_timeout;
-extern long gemini_spin_retries;
-extern long gemini_connection_limit;
-extern char *gemini_basedir;
-extern TYPELIB gemini_recovery_typelib;
-extern ulong gemini_recovery_options;
-
-bool gemini_init(void);
-bool gemini_end(void);
-bool gemini_flush_logs(void);
-int gemini_commit(THD *thd);
-int gemini_rollback(THD *thd);
-int gemini_recovery_logging(THD *thd, bool on);
-void gemini_disconnect(THD *thd);
-int gemini_rollback_to_savepoint(THD *thd);
-int gemini_parse_table_name(const char *fullname, char *dbname, char *tabname);
-int gemini_is_vst(const char *pname);
-int gemini_set_option_long(int optid, long optval);
-
-const int gemini_blocksize = BLKSIZE;
-const int gemini_recbits = DEFAULT_RECBITS;
-
-extern "C" void uttrace(void);
diff --git a/sql/ha_hash.h b/sql/ha_hash.h
deleted file mode 100644
index 80416611406..00000000000
--- a/sql/ha_hash.h
+++ /dev/null
@@ -1,31 +0,0 @@
-
-int ha_hash::create(my_string name, register TABLE *form,
- ulonglong auto_increment_value)
-{
- register uint i,j;
- char buff[FN_REFLEN];
- KEY *pos;
- H_KEYDEF keydef[MAX_KEY];
- DBUG_ENTER("cre_hash");
-
- pos=form->key_info;
- for (i=0; i < form->keys ; i++, pos++)
- {
- keydef[i].hk_flag= pos->flags & HA_NOSAME;
- for (j=0 ; (int7) j < pos->key_parts ; j++)
- {
- uint flag=pos->key_part[j].key_type;
- if (!f_is_packed(flag) && f_packtype(flag) == (int) FIELD_TYPE_DECIMAL &&
- !(flag & FIELDFLAG_BINARY))
- keydef[i].hk_keyseg[j].key_type= (int) HA_KEYTYPE_TEXT;
- else
- keydef[i].hk_keyseg[j].key_type= (int) HA_KEYTYPE_BINARY;
- keydef[i].hk_keyseg[j].start= pos->key_part[j].offset;
- keydef[i].hk_keyseg[j].length= pos->key_part[j].length;
- }
- keydef[i].hk_keyseg[j].key_type= 0;
- }
- DBUG_RETURN(h_create(fn_format(buff,name,"","",2+4+16),i,
- keydef,form->reclength,form->max_rows,form->min_rows,
- 0));
-} /* cre_hash */
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index 13dccc2bf64..eb4bf517374 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -33,10 +33,11 @@ const char **ha_heap::bas_ext() const
int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
- uint key,part,parts,mem_per_row=0;
+ uint key,parts,mem_per_row=0;
ulong max_rows;
HP_KEYDEF *keydef;
HP_KEYSEG *seg;
+ THD *thd= current_thd;
for (key=parts=0 ; key < table->keys ; key++)
parts+=table->key_info[key].key_parts;
@@ -48,36 +49,51 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
for (key=0 ; key < table->keys ; key++)
{
KEY *pos=table->key_info+key;
+ KEY_PART_INFO *key_part= pos->key_part;
+ KEY_PART_INFO *key_part_end= key_part+pos->key_parts;
+
mem_per_row += (pos->key_length + (sizeof(char*) * 2));
-
+
keydef[key].keysegs=(uint) pos->key_parts;
- keydef[key].flag = (pos->flags & HA_NOSAME);
+ keydef[key].flag = (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
keydef[key].seg=seg;
-
- for (part=0 ; part < pos->key_parts ; part++)
+
+ for (; key_part != key_part_end ; key_part++, seg++)
{
- uint flag=pos->key_part[part].key_type;
+ uint flag=key_part->key_type;
+ Field *field=key_part->field;
if (!f_is_packed(flag) &&
f_packtype(flag) == (int) FIELD_TYPE_DECIMAL &&
!(flag & FIELDFLAG_BINARY))
seg->type= (int) HA_KEYTYPE_TEXT;
else
seg->type= (int) HA_KEYTYPE_BINARY;
- seg->start=(uint) pos->key_part[part].offset;
- seg->length=(uint) pos->key_part[part].length;
- seg++;
+ seg->start=(uint) key_part->offset;
+ seg->length=(uint) key_part->length;
+ if (field->null_ptr)
+ {
+ seg->null_bit=field->null_bit;
+ seg->null_pos= (uint) (field->null_ptr-
+ (uchar*) table->record[0]);
+ }
+ else
+ {
+ seg->null_bit=0;
+ seg->null_pos=0;
+ }
}
}
mem_per_row += MY_ALIGN(table->reclength+1, sizeof(char*));
- max_rows = (ulong) (max_heap_table_size / mem_per_row);
+ max_rows = (ulong) (thd->variables.max_heap_table_size / mem_per_row);
file=heap_open(name,mode,
table->keys,keydef,
table->reclength,
- ((table->max_rows < max_rows && table->max_rows) ?
- table->max_rows : max_rows),
- table->min_rows);
+ (ulong) ((table->max_rows < max_rows && table->max_rows) ?
+ table->max_rows : max_rows),
+ (ulong) table->min_rows);
my_free((gptr) keydef,MYF(0));
- info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ if (file)
+ info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
ref_length=sizeof(HEAP_PTR);
return (!file ? errno : 0);
}
@@ -147,7 +163,7 @@ int ha_heap::index_prev(byte * buf)
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
-
+
int ha_heap::index_first(byte * buf)
{
statistic_increment(ha_read_first_count,&LOCK_status);
@@ -206,6 +222,7 @@ void ha_heap::info(uint flag)
index_file_length=info.index_length;
max_data_file_length= info.max_records* info.reclength;
delete_length= info.deleted * info.reclength;
+ implicit_emptied= info.implicit_emptied;
}
int ha_heap::extra(enum ha_extra_function operation)
@@ -227,7 +244,7 @@ int ha_heap::delete_all_rows()
int ha_heap::external_lock(THD *thd, int lock_type)
{
return 0; // No external locking
-}
+}
THR_LOCK_DATA **ha_heap::store_lock(THD *thd,
THR_LOCK_DATA **to,
@@ -247,7 +264,7 @@ THR_LOCK_DATA **ha_heap::store_lock(THD *thd,
int ha_heap::delete_table(const char *name)
{
- int error=heap_delete_all(name);
+ int error=heap_delete_table(name);
return error == ENOENT ? 0 : error;
}
@@ -272,7 +289,6 @@ ha_rows ha_heap::records_in_range(int inx,
return 10; // Good guess
}
-/* We can just delete the heap on creation */
int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info)
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index 6b7e9c6c626..31126111d9d 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -31,17 +31,32 @@ class ha_heap: public handler
ha_heap(TABLE *table): handler(table), file(0) {}
~ha_heap() {}
const char *table_type() const { return "HEAP"; }
+ const char *index_type(uint inx)
+ {
+ return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? "BTREE" :
+ "HASH");
+ }
const char **bas_ext() const;
- ulong option_flag() const
- { return (HA_READ_RND_SAME | HA_NO_INDEX | HA_ONLY_WHOLE_INDEX |
- HA_WRONG_ASCII_ORDER | HA_KEYPOS_TO_RNDPOS | HA_NO_BLOBS |
- HA_REC_NOT_IN_SEQ | HA_NO_FULLTEXT_KEY); }
+ ulong table_flags() const
+ {
+ return (HA_READ_RND_SAME | HA_NO_INDEX | HA_KEYPOS_TO_RNDPOS |
+ HA_NO_BLOBS | HA_NULL_KEY | HA_REC_NOT_IN_SEQ |
+ HA_NO_AUTO_INCREMENT);
+ }
+ ulong index_flags(uint inx) const
+ {
+ return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
+ (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER) :
+ (HA_ONLY_WHOLE_INDEX | HA_WRONG_ASCII_ORDER |
+ HA_NOT_READ_PREFIX_LAST));
+ }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
uint max_key_length() const { return HA_MAX_REC_LENGTH; }
- virtual double scan_time() { return (double) (records+deleted) / 20.0+10; }
- virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
+ double scan_time() { return (double) (records+deleted) / 20.0+10; }
+ double read_time(uint index, uint ranges, ha_rows rows)
+ { return (double) rows / 20.0+1; }
virtual bool fast_key_read() { return 1;}
int open(const char *name, int mode, uint test_if_locked);
diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc
deleted file mode 100644
index bafd41ff566..00000000000
--- a/sql/ha_innobase.cc
+++ /dev/null
@@ -1,3876 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & Innobase Oy
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* This file defines the InnoDB handler: the interface between MySQL and
-InnoDB */
-
-/* TODO list for the InnoDB handler:
- - Ask Monty if strings of different languages can exist in the same
- database. Answer: in 4.1 yes.
-*/
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-#include "mysql_priv.h"
-#include "slave.h"
-#ifdef HAVE_INNOBASE_DB
-#include <m_ctype.h>
-#include <assert.h>
-#include <hash.h>
-#include <myisampack.h>
-
-#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
-
-#include "ha_innobase.h"
-
-/* We must declare this here because we undef SAFE_MUTEX below */
-pthread_mutex_t innobase_mutex;
-
-/* Store MySQL definition of 'byte': in Linux it is char while InnoDB
-uses unsigned char */
-typedef byte mysql_byte;
-
-#ifdef SAFE_MUTEX
-#undef pthread_mutex_t
-#endif
-
-#define INSIDE_HA_INNOBASE_CC
-
-/* Include necessary InnoDB headers */
-extern "C" {
-#include "../innobase/include/univ.i"
-#include "../innobase/include/os0file.h"
-#include "../innobase/include/os0thread.h"
-#include "../innobase/include/srv0start.h"
-#include "../innobase/include/srv0srv.h"
-#include "../innobase/include/trx0roll.h"
-#include "../innobase/include/trx0trx.h"
-#include "../innobase/include/trx0sys.h"
-#include "../innobase/include/row0ins.h"
-#include "../innobase/include/row0mysql.h"
-#include "../innobase/include/row0sel.h"
-#include "../innobase/include/row0upd.h"
-#include "../innobase/include/log0log.h"
-#include "../innobase/include/lock0lock.h"
-#include "../innobase/include/dict0crea.h"
-#include "../innobase/include/btr0cur.h"
-#include "../innobase/include/btr0btr.h"
-#include "../innobase/include/fsp0fsp.h"
-}
-
-#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
-#define HA_INNOBASE_RANGE_COUNT 100
-
-bool innodb_skip = 0;
-uint innobase_init_flags = 0;
-ulong innobase_cache_size = 0;
-
-/* The default values for the following, type long, start-up parameters
-are declared in mysqld.cc: */
-
-long innobase_mirrored_log_groups, innobase_log_files_in_group,
- innobase_log_file_size, innobase_log_buffer_size,
- innobase_buffer_pool_size, innobase_additional_mem_pool_size,
- innobase_file_io_threads, innobase_lock_wait_timeout,
- innobase_thread_concurrency, innobase_force_recovery;
-
-/* The default values for the following char* start-up parameters
-are determined in innobase_init below: */
-
-/* innobase_data_file_path=ibdata:15,idata2:1,... */
-
-char* innobase_data_file_path = NULL;
-char* innobase_data_home_dir = NULL;
-char* innobase_log_group_home_dir = NULL;
-char* innobase_log_arch_dir = NULL;
-char* innobase_unix_file_flush_method = NULL;
-
-/* Below we have boolean-valued start-up parameters, and their default
-values */
-
-my_bool innobase_log_archive = FALSE;
-my_bool innobase_use_native_aio = FALSE;
-my_bool innobase_fast_shutdown = TRUE;
-
-static char *internal_innobase_data_file_path = NULL;
-
-/* innodb_flush_log_at_trx_commit can now have 3 values:
-0 : write to the log file once per second and flush it to disk;
-1 : write to the log file at each commit and flush it to disk;
-2 : write to the log file at each commit, but flush to disk only once per
-second */
-
-long innobase_flush_log_at_trx_commit = 1;
-
-/* The following counter is used to convey information to InnoDB
-about server activity: in selects it is not sensible to call
-srv_active_wake_master_thread after each fetch or search, we only do
-it every INNOBASE_WAKE_INTERVAL'th step. */
-
-#define INNOBASE_WAKE_INTERVAL 32
-ulong innobase_active_counter = 0;
-
-char* innobase_home = NULL;
-
-char innodb_dummy_stmt_trx_handle = 'D';
-
-static HASH innobase_open_tables;
-
-static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
- my_bool not_used __attribute__((unused)));
-static INNOBASE_SHARE *get_share(const char *table_name);
-static void free_share(INNOBASE_SHARE *share);
-static void innobase_print_error(const char* db_errpfx, char* buffer);
-
-/* General functions */
-
-/**********************************************************************
-Releases possible search latch and InnoDB thread FIFO ticket. These should
-be released at each SQL statement end. It does no harm to release these
-also in the middle of an SQL statement. */
-static
-void
-innobase_release_stat_resources(
-/*============================*/
- trx_t* trx) /* in: transaction object */
-{
- if (trx->has_search_latch) {
- trx_search_latch_release_if_reserved(trx);
- }
-
- if (trx->declared_to_be_inside_innodb) {
- /* Release our possible ticket in the FIFO */
-
- srv_conc_force_exit_innodb(trx);
- }
-}
-
-/************************************************************************
-Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
-time calls srv_active_wake_master_thread. This function should be used
-when a single database operation may introduce a small need for
-server utility activity, like checkpointing. */
-inline
-void
-innobase_active_small(void)
-/*=======================*/
-{
- innobase_active_counter++;
-
- if ((innobase_active_counter % INNOBASE_WAKE_INTERVAL) == 0) {
- srv_active_wake_master_thread();
- }
-}
-
-/************************************************************************
-Converts an InnoDB error code to a MySQL error code. */
-static
-int
-convert_error_code_to_mysql(
-/*========================*/
- /* out: MySQL error code */
- int error, /* in: InnoDB error code */
- THD* thd) /* in: user thread handle or NULL */
-{
- if (error == DB_SUCCESS) {
-
- return(0);
-
- } else if (error == (int) DB_DUPLICATE_KEY) {
-
- return(HA_ERR_FOUND_DUPP_KEY);
-
- } else if (error == (int) DB_RECORD_NOT_FOUND) {
-
- return(HA_ERR_NO_ACTIVE_RECORD);
-
- } else if (error == (int) DB_ERROR) {
-
- return(HA_ERR_NO_ACTIVE_RECORD);
-
- } else if (error == (int) DB_DEADLOCK) {
- /* Since we roll back the whole transaction, we must
- tell it also to MySQL so that MySQL knows to empty the
- cached binlog for this transaction */
-
- if (thd) {
- ha_rollback(thd);
- }
-
- return(HA_ERR_LOCK_DEADLOCK);
-
- } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
-
- /* Since we roll back the whole transaction, we must
- tell it also to MySQL so that MySQL knows to empty the
- cached binlog for this transaction */
-
-
- if (thd) {
- ha_rollback(thd);
- }
-
- return(HA_ERR_LOCK_WAIT_TIMEOUT);
-
- } else if (error == (int) DB_NO_REFERENCED_ROW) {
-
- return(HA_ERR_NO_REFERENCED_ROW);
-
- } else if (error == (int) DB_ROW_IS_REFERENCED) {
-
- return(HA_ERR_ROW_IS_REFERENCED);
-
- } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
-
- return(HA_ERR_CANNOT_ADD_FOREIGN);
-
- } else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) {
-
- return(HA_ERR_WRONG_TABLE_DEF);
-
- } else if (error == (int) DB_OUT_OF_FILE_SPACE) {
-
- return(HA_ERR_RECORD_FILE_FULL);
-
- } else if (error == (int) DB_TABLE_IS_BEING_USED) {
-
- return(HA_ERR_WRONG_COMMAND);
-
- } else if (error == (int) DB_TABLE_NOT_FOUND) {
-
- return(HA_ERR_KEY_NOT_FOUND);
-
- } else if (error == (int) DB_TOO_BIG_RECORD) {
-
- return(HA_ERR_TO_BIG_ROW);
- } else {
- return(-1); // Unknown error
- }
-}
-
-extern "C" {
-/*****************************************************************
-Prints info of a THD object (== user session thread) to the
-standard output. NOTE that /mysql/innobase/trx/trx0trx.c must contain
-the prototype for this function! */
-
-void
-innobase_mysql_print_thd(
-/*=====================*/
- char* buf, /* in/out: buffer where to print, must be at least
- 400 bytes */
- void* input_thd)/* in: pointer to a MySQL THD object */
-{
- THD* thd;
- char* old_buf = buf;
-
- thd = (THD*) input_thd;
-
- /* We cannot use the return value of normal sprintf() as this is
- not portable to some old non-Posix Unixes, e.g., some old SCO
- Unixes */
-
- buf += my_sprintf(buf,
- (buf, "MySQL thread id %lu, query id %lu",
- thd->thread_id, thd->query_id));
- if (thd->host) {
- *buf = ' ';
- buf++;
- buf = strnmov(buf, thd->host, 30);
- }
-
- if (thd->ip) {
- *buf = ' ';
- buf++;
- buf=strnmov(buf, thd->ip, 20);
- }
-
- if (thd->user) {
- *buf = ' ';
- buf++;
- buf=strnmov(buf, thd->user, 20);
- }
-
- if (thd->proc_info) {
- *buf = ' ';
- buf++;
- buf=strnmov(buf, thd->proc_info, 50);
- }
-
- if (thd->query) {
- *buf = '\n';
- buf++;
- buf=strnmov(buf, thd->query, 150);
- }
-
- buf[0] = '\n';
- buf[1] = '\0'; /* Note that we must put a null character here to end
- the printed string */
-
- /* We test the printed length did not overrun the buffer length of
- 400 bytes */
-
- ut_a(strlen(old_buf) < 400);
-}
-}
-
-/*************************************************************************
-Gets the InnoDB transaction handle for a MySQL handler object, creates
-an InnoDB transaction struct if the corresponding MySQL thread struct still
-lacks one. */
-static
-trx_t*
-check_trx_exists(
-/*=============*/
- /* out: InnoDB transaction handle */
- THD* thd) /* in: user thread handle */
-{
- trx_t* trx;
-
- ut_a(thd == current_thd);
-
- trx = (trx_t*) thd->transaction.all.innobase_tid;
-
- if (trx == NULL) {
- ut_a(thd != NULL);
- trx = trx_allocate_for_mysql();
-
- trx->mysql_thd = thd;
-
- thd->transaction.all.innobase_tid = trx;
-
- /* The execution of a single SQL statement is denoted by
- a 'transaction' handle which is a dummy pointer: InnoDB
- remembers internally where the latest SQL statement
- started, and if error handling requires rolling back the
- latest statement, InnoDB does a rollback to a savepoint. */
-
- thd->transaction.stmt.innobase_tid =
- (void*)&innodb_dummy_stmt_trx_handle;
- } else {
- if (trx->magic_n != TRX_MAGIC_N) {
- mem_analyze_corruption((byte*)trx);
-
- ut_a(0);
- }
- }
-
- if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
- trx->check_foreigns = FALSE;
- } else {
- trx->check_foreigns = TRUE;
- }
-
- if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
- trx->check_unique_secondary = FALSE;
- } else {
- trx->check_unique_secondary = TRUE;
- }
-
- return(trx);
-}
-
-/*************************************************************************
-Updates the user_thd field in a handle and also allocates a new InnoDB
-transaction handle if needed, and updates the transaction fields in the
-prebuilt struct. */
-inline
-int
-ha_innobase::update_thd(
-/*====================*/
- /* out: 0 or error code */
- THD* thd) /* in: thd to use the handle */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- trx_t* trx;
-
- trx = check_trx_exists(thd);
-
- if (prebuilt->trx != trx) {
-
- row_update_prebuilt_trx(prebuilt, trx);
- }
-
- user_thd = thd;
-
- return(0);
-}
-
-#ifdef notdefined
-/* The code here appears for documentational purposes only. Not used
-or tested yet. Will be used in 4.1. */
-/*********************************************************************
-Call this when you have opened a new table handle in HANDLER, before you
-call index_read_idx() etc. Actually, we can let the cursor stay open even
-over a transaction commit! Then you should call this before every operation,
-fecth next etc. This function inits the necessary things even after a
-transaction commit. */
-
-void
-ha_innobase::init_table_handle_for_HANDLER(void)
-/*============================================*/
-{
- row_prebuilt_t* prebuilt;
-
- ut_a(0); /* the code has not been used or tested yet; to prevent
- inadvertent usage we assert an error here */
-
- /* If current thd does not yet have a trx struct, create one.
- If the current handle does not yet have a prebuilt struct, create
- one. Update the trx pointers in the prebuilt struct. Normally
- this operation is done in external_lock. */
-
- update_thd(current_thd);
-
- /* Initialize the prebuilt struct much like it would be inited in
- external_lock */
-
- prebuilt = (row_prebuilt_t*)innobase_prebuilt;
-
- /* If the transaction is not started yet, start it */
-
- trx_start_if_not_started_noninline(prebuilt->trx);
-
- /* Assign a read view if the transaction does not have it yet */
-
- trx_assign_read_view(prebuilt->trx);
-
- /* We did the necessary inits in this function, no need to repeat them
- in row_search_for_mysql */
-
- prebuilt->sql_stat_start = FALSE;
-
- /* We let HANDLER always to do the reads as consistent reads, even
- if the trx isolation level would have been specified as SERIALIZABLE */
-
- prebuilt->select_lock_type = LOCK_NONE;
-
- /* Always fetch all columns in the index record */
-
- prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
-
- /* We want always to fetch all columns in the whole row? Or do
- we???? */
-
- prebuilt->read_just_key = FALSE;
-}
-#endif
-
-/*************************************************************************
-Opens an InnoDB database. */
-
-bool
-innobase_init(void)
-/*===============*/
- /* out: TRUE if error */
-{
- static char current_dir[3];
- int err;
- bool ret;
-
- DBUG_ENTER("innobase_init");
-
- os_innodb_umask = (ulint)my_umask;
-
- /* Use current_dir if no paths are set */
- current_dir[0] = FN_CURLIB;
- current_dir[1] = FN_LIBCHAR;
- current_dir[2] = 0;
-
- if (specialflag & SPECIAL_NO_PRIOR) {
- srv_set_thread_priorities = FALSE;
- } else {
- srv_set_thread_priorities = TRUE;
- srv_query_thread_priority = QUERY_PRIOR;
- }
-
- /* Set InnoDB initialization parameters according to the values
- read from MySQL .cnf file */
-
- if (!innobase_data_file_path) {
- fprintf(stderr,
- "Cannot initialize InnoDB as 'innodb_data_file_path' is not set.\n"
- "If you do not want to use transactional InnoDB tables, add a line\n"
- "skip-innodb\n"
- "to the [mysqld] section of init parameters in your my.cnf\n"
- "or my.ini. If you want to use InnoDB tables, add to the [mysqld]\n"
- "section, for example,\n"
- "innodb_data_file_path = ibdata1:10M:autoextend\n"
- "But to get good performance you should adjust for your hardware\n"
- "the InnoDB startup options listed in section 2 at\n"
- "http://www.innodb.com/ibman.html\n");
-
- innodb_skip=1;
- DBUG_RETURN(FALSE); /* Continue without InnoDB */
- }
-
- srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
- current_dir);
- srv_arch_dir = (innobase_log_arch_dir ? innobase_log_arch_dir :
- current_dir);
-
- /* Since InnoDB edits the argument in the next call, we make another
- copy of it: */
-
- internal_innobase_data_file_path = my_strdup(innobase_data_file_path,
- MYF(MY_WME));
-
- ret = (bool) srv_parse_data_file_paths_and_sizes(
- internal_innobase_data_file_path,
- &srv_data_file_names,
- &srv_data_file_sizes,
- &srv_data_file_is_raw_partition,
- &srv_n_data_files,
- &srv_auto_extend_last_data_file,
- &srv_last_file_size_max);
- if (ret == FALSE) {
- sql_print_error("InnoDB: syntax error in innodb_data_file_path");
- DBUG_RETURN(TRUE);
- }
-
- if (!innobase_log_group_home_dir)
- innobase_log_group_home_dir = current_dir;
-
- ret = (bool)
- srv_parse_log_group_home_dirs(innobase_log_group_home_dir,
- &srv_log_group_home_dirs);
-
- if (ret == FALSE || innobase_mirrored_log_groups != 1) {
- fprintf(stderr,
- "InnoDB: syntax error in innodb_log_group_home_dir\n"
- "InnoDB: or a wrong number of mirrored log groups\n");
-
- DBUG_RETURN(TRUE);
- }
-
- srv_unix_file_flush_method_str = (innobase_unix_file_flush_method ?
- innobase_unix_file_flush_method :
- (char*)"fdatasync");
-
- srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
- srv_n_log_files = (ulint) innobase_log_files_in_group;
- srv_log_file_size = (ulint) innobase_log_file_size;
-
- srv_log_archive_on = (ulint) innobase_log_archive;
- srv_log_buffer_size = (ulint) innobase_log_buffer_size;
- srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit;
-
- srv_use_native_aio = 0;
-
- srv_pool_size = (ulint) innobase_buffer_pool_size;
-
- srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
-
- srv_n_file_io_threads = (ulint) innobase_file_io_threads;
-
- srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
- srv_thread_concurrency = (ulint) innobase_thread_concurrency;
- srv_force_recovery = (ulint) innobase_force_recovery;
-
- srv_fast_shutdown = (ibool) innobase_fast_shutdown;
-
- if (strcmp(default_charset_info->name, "latin1") == 0) {
- /* Store the character ordering table to InnoDB.
- For non-latin1 charsets we use the MySQL comparison
- functions, and consequently we do not need to know
- the ordering internally in InnoDB. */
-
- memcpy(srv_latin1_ordering,
- default_charset_info->sort_order, 256);
- }
-
- err = innobase_start_or_create_for_mysql();
-
- if (err != DB_SUCCESS) {
-
- DBUG_RETURN(1);
- }
-
- (void) hash_init(&innobase_open_tables,32,0,0,
- (hash_get_key) innobase_get_key,0,0);
- pthread_mutex_init(&innobase_mutex,MY_MUTEX_INIT_FAST);
-
- /* If this is a replication slave and we needed to do a crash recovery,
- set the master binlog position to what InnoDB internally knew about
- how far we got transactions durable inside InnoDB. There is a
- problem here: if the user used also MyISAM tables, InnoDB might not
- know the right position for them.
-
- THIS DOES NOT WORK CURRENTLY because replication seems to initialize
- glob_mi also after innobase_init. */
-
-/* if (trx_sys_mysql_master_log_pos != -1) {
- ut_memcpy(glob_mi.log_file_name, trx_sys_mysql_master_log_name,
- 1 + ut_strlen(trx_sys_mysql_master_log_name));
- glob_mi.pos = trx_sys_mysql_master_log_pos;
- }
-*/
- DBUG_RETURN(0);
-}
-
-/***********************************************************************
-Closes an InnoDB database. */
-
-bool
-innobase_end(void)
-/*==============*/
- /* out: TRUE if error */
-{
- int err;
-
- DBUG_ENTER("innobase_end");
-
- err = innobase_shutdown_for_mysql();
- hash_free(&innobase_open_tables);
- my_free(internal_innobase_data_file_path,MYF(MY_ALLOW_ZERO_PTR));
-
- if (err != DB_SUCCESS) {
-
- DBUG_RETURN(1);
- }
-
- DBUG_RETURN(0);
-}
-
-/********************************************************************
-Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit
-flushes logs, and the name of this function should be innobase_checkpoint. */
-
-bool
-innobase_flush_logs(void)
-/*=====================*/
- /* out: TRUE if error */
-{
- bool result = 0;
-
- DBUG_ENTER("innobase_flush_logs");
-
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
-
- DBUG_RETURN(result);
-}
-
-/*************************************************************************
-Gets the free space in an InnoDB database: returned in units of kB. */
-
-uint
-innobase_get_free_space(void)
-/*=========================*/
- /* out: free space in kB */
-{
- return((uint) fsp_get_available_space_in_free_extents(0));
-}
-
-/*********************************************************************
-Commits a transaction in an InnoDB database. */
-
-void
-innobase_commit_low(
-/*================*/
- trx_t* trx) /* in: transaction handle */
-{
- if (current_thd->slave_thread) {
-
- /* Update the replication position info inside InnoDB */
-
- trx->mysql_master_log_file_name = glob_mi.log_file_name;
- trx->mysql_master_log_pos = (ib_longlong)
- (glob_mi.pos + glob_mi.event_len
- + glob_mi.pending);
- }
-
- trx_commit_for_mysql(trx);
-}
-
-/*********************************************************************
-Commits a transaction in an InnoDB database. */
-
-int
-innobase_commit(
-/*============*/
- /* out: 0 or error number */
- THD* thd, /* in: MySQL thread handle of the user for whom
- the transaction should be committed */
- void* trx_handle)/* in: InnoDB trx handle or NULL: NULL means
- that the current SQL statement ended, and we should
- mark the start of a new statement with a savepoint */
-{
- int error = 0;
- trx_t* trx;
-
- DBUG_ENTER("innobase_commit");
- DBUG_PRINT("trans", ("ending transaction"));
-
- trx = check_trx_exists(thd);
-
- /* Release possible statement level resources */
- innobase_release_stat_resources(trx);
-
- if (trx->auto_inc_lock) {
-
- /* If we had reserved the auto-inc lock for
- some table in this SQL statement, we release it now */
-
- row_unlock_table_autoinc_for_mysql(trx);
- }
-
- if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
- innobase_commit_low(trx);
- }
-
- trx_mark_sql_stat_end(trx);
-
-#ifndef DBUG_OFF
- if (error) {
- DBUG_PRINT("error", ("error: %d", error));
- }
-#endif
- /* Tell InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- DBUG_RETURN(error);
-}
-
-/*********************************************************************
-This is called when MySQL writes the binlog entry for the current
-transaction. Writes to the InnoDB tablespace info which tells where the
-MySQL binlog entry for the current transaction ended. Also commits the
-transaction inside InnoDB. */
-
-int
-innobase_report_binlog_offset_and_commit(
-/*=====================================*/
- /* out: 0 or error code */
- THD* thd, /* in: user thread */
- void* trx_handle, /* in: InnoDB trx handle */
- char* log_file_name, /* in: latest binlog file name */
- my_off_t end_offset) /* in: the offset in the binlog file
- up to which we wrote */
-{
- trx_t* trx;
-
- trx = (trx_t*)trx_handle;
-
- ut_a(trx != NULL);
-
- trx->mysql_log_file_name = log_file_name;
- trx->mysql_log_offset = (ib_longlong)end_offset;
-
- return(innobase_commit(thd, trx_handle));
-}
-
-/*********************************************************************
-Rolls back a transaction in an InnoDB database. */
-
-int
-innobase_rollback(
-/*==============*/
- /* out: 0 or error number */
- THD* thd, /* in: handle to the MySQL thread of the user
- whose transaction should be rolled back */
- void* trx_handle)/* in: InnoDB trx handle or a dummy stmt handle */
-{
- int error = 0;
- trx_t* trx;
-
- DBUG_ENTER("innobase_rollback");
- DBUG_PRINT("trans", ("aborting transaction"));
-
- trx = check_trx_exists(thd);
-
- /* Release possible statement level resources */
- innobase_release_stat_resources(trx);
-
- if (trx->auto_inc_lock) {
-
- /* If we had reserved the auto-inc lock for
- some table in this SQL statement, we release it now */
-
- row_unlock_table_autoinc_for_mysql(trx);
- }
-
- if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
- error = trx_rollback_for_mysql(trx);
- } else {
- error = trx_rollback_last_sql_stat_for_mysql(trx);
- }
-
- trx_mark_sql_stat_end(trx);
-
- DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
-}
-
-/*********************************************************************
-Frees a possible InnoDB trx object associated with the current
-THD. */
-
-int
-innobase_close_connection(
-/*======================*/
- /* out: 0 or error number */
- THD* thd) /* in: handle to the MySQL thread of the user
- whose transaction should be rolled back */
-{
- if (NULL != thd->transaction.all.innobase_tid) {
-
- trx_rollback_for_mysql((trx_t*)
- (thd->transaction.all.innobase_tid));
- trx_free_for_mysql((trx_t*)
- (thd->transaction.all.innobase_tid));
- thd->transaction.all.innobase_tid = NULL;
- }
-
- return(0);
-}
-
-/**********************************************************************
-Prints an error message. */
-static
-void
-innobase_print_error(
-/*=================*/
- const char* db_errpfx, /* in: error prefix text */
- char* buffer) /* in: error text */
-{
- sql_print_error("%s: %s", db_errpfx, buffer);
-}
-
-
-/*****************************************************************************
-** InnoDB database tables
-*****************************************************************************/
-
-/********************************************************************
-This function is not relevant since we store the tables and indexes
-into our own tablespace, not as files, whose extension this function would
-give. */
-
-const char**
-ha_innobase::bas_ext() const
-/*========================*/
- /* out: file extension strings, currently not
- used */
-{
- static const char* ext[] = {".InnoDB", NullS};
-
- return(ext);
-}
-
-/*********************************************************************
-Normalizes a table name string. A normalized name consists of the
-database name catenated to '/' and table name. An example:
-test/mytable. On Windows normalization puts both the database name and the
-table name always to lower case. */
-static
-void
-normalize_table_name(
-/*=================*/
- char* norm_name, /* out: normalized name as a
- null-terminated string */
- const char* name) /* in: table name string */
-{
- char* name_ptr;
- char* db_ptr;
- char* ptr;
-
- /* Scan name from the end */
-
- ptr = strend(name)-1;
-
- while (ptr >= name && *ptr != '\\' && *ptr != '/') {
- ptr--;
- }
-
- name_ptr = ptr + 1;
-
- DBUG_ASSERT(ptr > name);
-
- ptr--;
-
- while (ptr >= name && *ptr != '\\' && *ptr != '/') {
- ptr--;
- }
-
- db_ptr = ptr + 1;
-
- memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
-
- norm_name[name_ptr - db_ptr - 1] = '/';
-
-#ifdef __WIN__
- /* Put to lower case */
-
- ptr = norm_name;
-
- while (*ptr != '\0') {
- *ptr = tolower(*ptr);
- ptr++;
- }
-#endif
-}
-
-/*********************************************************************
-Creates and opens a handle to a table which already exists in an InnoDB
-database. */
-
-int
-ha_innobase::open(
-/*==============*/
- /* out: 1 if error, 0 if success */
- const char* name, /* in: table name */
- int mode, /* in: not used */
- uint test_if_locked) /* in: not used */
-{
- dict_table_t* ib_table;
- int error = 0;
- uint buff_len;
- char norm_name[1000];
-
- DBUG_ENTER("ha_innobase::open");
-
- UT_NOT_USED(mode);
- UT_NOT_USED(test_if_locked);
-
- normalize_table_name(norm_name, name);
-
- user_thd = NULL;
-
- last_query_id = (ulong)-1;
-
- if (!(share=get_share(name)))
- DBUG_RETURN(1);
-
- /* Create buffers for packing the fields of a record. Why
- table->reclength did not work here? Obviously, because char
- fields when packed actually became 1 byte longer, when we also
- stored the string length as the first byte. */
-
- buff_len = table->reclength + table->max_key_length
- + MAX_REF_PARTS * 3;
- if (!(mysql_byte*) my_multi_malloc(MYF(MY_WME),
- &upd_buff, buff_len,
- &key_val_buff, buff_len,
- NullS)) {
- free_share(share);
- DBUG_RETURN(1);
- }
-
- /* Get pointer to a table object in InnoDB dictionary cache */
-
- ib_table = dict_table_get_and_increment_handle_count(
- norm_name, NULL);
- if (NULL == ib_table) {
-
- sql_print_error("InnoDB error:\n"
-"Cannot find table %s from the internal data dictionary\n"
-"of InnoDB though the .frm file for the table exists. Maybe you\n"
-"have deleted and recreated InnoDB data files but have forgotten\n"
-"to delete the corresponding .frm files of InnoDB tables, or you\n"
-"have moved .frm files to another database?\n"
-"Look from section 15.1 of http://www.innodb.com/ibman.html\n"
-"how you can resolve the problem.\n",
- norm_name);
-
- free_share(share);
- my_free((char*) upd_buff, MYF(0));
- my_errno = ENOENT;
- DBUG_RETURN(1);
- }
-
- innobase_prebuilt = row_create_prebuilt(ib_table);
-
- ((row_prebuilt_t*)innobase_prebuilt)->mysql_row_len = table->reclength;
-
- /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
-
- primary_key = table->primary_key;
- key_used_on_scan = primary_key;
-
- /* Allocate a buffer for a 'row reference'. A row reference is
- a string of bytes of length ref_length which uniquely specifies
- a row in our table. Note that MySQL may also compare two row
- references for equality by doing a simple memcmp on the strings
- of length ref_length! */
-
- if (!row_table_got_default_clust_index(ib_table)) {
- if (primary_key >= MAX_KEY) {
- fprintf(stderr,
- "InnoDB: Error: table %s has a primary key in InnoDB\n"
- "InnoDB: data dictionary, but not in MySQL!\n", name);
- }
-
- ((row_prebuilt_t*)innobase_prebuilt)
- ->clust_index_was_generated = FALSE;
- /*
- MySQL allocates the buffer for ref. key_info->key_length
- includes space for all key columns + one byte for each column
- that may be NULL. ref_length must be as exact as possible to
- save space, because all row reference buffers are allocated
- based on ref_length.
- */
-
- ref_length = table->key_info[primary_key].key_length;
- } else {
- if (primary_key != MAX_KEY) {
- fprintf(stderr,
- "InnoDB: Error: table %s has no primary key in InnoDB\n"
- "InnoDB: data dictionary, but has one in MySQL!\n"
- "InnoDB: If you created the table with a MySQL\n"
- "InnoDB: version < 3.23.54 and did not define a primary\n"
- "InnoDB: key, but defined a unique key with all non-NULL\n"
- "InnoDB: columns, then MySQL internally treats that key\n"
- "InnoDB: as the primary key. You can fix this error by\n"
- "InnoDB: dump + DROP + CREATE + reimport of the table.\n",
- name);
- }
-
- ((row_prebuilt_t*)innobase_prebuilt)
- ->clust_index_was_generated = TRUE;
-
- ref_length = DATA_ROW_ID_LEN;
-
- /* If we automatically created the clustered index, then
- MySQL does not know about it, and MySQL must NOT be aware
- of the index used on scan, to make it avoid checking if we
- update the column of the index. That is why we assert below
- that key_used_on_scan is the undefined value MAX_KEY.
- The column is the row id in the automatical generation case,
- and it will never be updated anyway. */
-
- DBUG_ASSERT(key_used_on_scan == MAX_KEY);
- }
-
- auto_inc_counter_for_this_stat = 0;
-
- block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL
- in query optimization */
-
- /* Init table lock structure */
- thr_lock_data_init(&share->lock,&lock,(void*) 0);
-
- info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
-
- DBUG_RETURN(0);
-}
-
-/*********************************************************************
-Does nothing. */
-
-void
-ha_innobase::initialize(void)
-/*=========================*/
-{
-}
-
-/**********************************************************************
-Closes a handle to an InnoDB table. */
-
-int
-ha_innobase::close(void)
-/*====================*/
- /* out: error number */
-{
- DBUG_ENTER("ha_innobase::close");
-
- row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt);
-
- my_free((char*) upd_buff, MYF(0));
- free_share(share);
-
- /* Tell InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- DBUG_RETURN(0);
-}
-
-/* The following accessor functions should really be inside MySQL code! */
-
-/******************************************************************
-Gets field offset for a field in a table. */
-inline
-uint
-get_field_offset(
-/*=============*/
- /* out: offset */
- TABLE* table, /* in: MySQL table object */
- Field* field) /* in: MySQL field object */
-{
- return((uint) (field->ptr - (char*) table->record[0]));
-}
-
-/******************************************************************
-Checks if a field in a record is SQL NULL. Uses the record format
-information in table to track the null bit in record. */
-inline
-uint
-field_in_record_is_null(
-/*====================*/
- /* out: 1 if NULL, 0 otherwise */
- TABLE* table, /* in: MySQL table object */
- Field* field, /* in: MySQL field object */
- char* record) /* in: a row in MySQL format */
-{
- int null_offset;
-
- if (!field->null_ptr) {
-
- return(0);
- }
-
- null_offset = (uint) ((char*) field->null_ptr
- - (char*) table->record[0]);
-
- if (record[null_offset] & field->null_bit) {
-
- return(1);
- }
-
- return(0);
-}
-
-/******************************************************************
-Sets a field in a record to SQL NULL. Uses the record format
-information in table to track the null bit in record. */
-inline
-void
-set_field_in_record_to_null(
-/*========================*/
- TABLE* table, /* in: MySQL table object */
- Field* field, /* in: MySQL field object */
- char* record) /* in: a row in MySQL format */
-{
- int null_offset;
-
- null_offset = (uint) ((char*) field->null_ptr
- - (char*) table->record[0]);
-
- record[null_offset] = record[null_offset] | field->null_bit;
-}
-
-/******************************************************************
-Resets SQL NULL bits in a record to zero. */
-inline
-void
-reset_null_bits(
-/*============*/
- TABLE* table, /* in: MySQL table object */
- char* record) /* in: a row in MySQL format */
-{
- bzero(record, table->null_bytes);
-}
-
-extern "C" {
-/*****************************************************************
-InnoDB uses this function is to compare two data fields for which the
-data type is such that we must use MySQL code to compare them. NOTE that the
-prototype of this function is in rem0cmp.c in InnoDB source code!
-If you change this function, remember to update the prototype there! */
-
-int
-innobase_mysql_cmp(
-/*===============*/
- /* out: 1, 0, -1, if a is greater,
- equal, less than b, respectively */
- int mysql_type, /* in: MySQL type */
- unsigned char* a, /* in: data field */
- unsigned int a_length, /* in: data field length,
- not UNIV_SQL_NULL */
- unsigned char* b, /* in: data field */
- unsigned int b_length) /* in: data field length,
- not UNIV_SQL_NULL */
-{
- enum_field_types mysql_tp;
- int ret;
-
- DBUG_ASSERT(a_length != UNIV_SQL_NULL);
- DBUG_ASSERT(b_length != UNIV_SQL_NULL);
-
- mysql_tp = (enum_field_types) mysql_type;
-
- switch (mysql_tp) {
-
- case FIELD_TYPE_STRING:
- case FIELD_TYPE_VAR_STRING:
- ret = my_sortncmp((const char*) a, a_length,
- (const char*) b, b_length);
- if (ret < 0) {
- return(-1);
- } else if (ret > 0) {
- return(1);
- } else {
- return(0);
- }
- default:
- assert(0);
- }
-
- return(0);
-}
-}
-
-/******************************************************************
-Converts a MySQL type to an InnoDB type. */
-inline
-ulint
-get_innobase_type_from_mysql_type(
-/*==============================*/
- /* out: DATA_BINARY, DATA_VARCHAR, ... */
- Field* field) /* in: MySQL field */
-{
- /* The following asserts check that MySQL type code fits in
- 8 bits: this is used in ibuf and also when DATA_NOT_NULL is
- ORed to the type */
-
- DBUG_ASSERT((ulint)FIELD_TYPE_STRING < 256);
- DBUG_ASSERT((ulint)FIELD_TYPE_VAR_STRING < 256);
- DBUG_ASSERT((ulint)FIELD_TYPE_DOUBLE < 256);
- DBUG_ASSERT((ulint)FIELD_TYPE_FLOAT < 256);
- DBUG_ASSERT((ulint)FIELD_TYPE_DECIMAL < 256);
-
- switch (field->type()) {
- case FIELD_TYPE_VAR_STRING: if (field->flags & BINARY_FLAG) {
-
- return(DATA_BINARY);
- } else if (strcmp(
- default_charset_info->name,
- "latin1") == 0) {
- return(DATA_VARCHAR);
- } else {
- return(DATA_VARMYSQL);
- }
- case FIELD_TYPE_STRING: if (field->flags & BINARY_FLAG) {
-
- return(DATA_FIXBINARY);
- } else if (strcmp(
- default_charset_info->name,
- "latin1") == 0) {
- return(DATA_CHAR);
- } else {
- return(DATA_MYSQL);
- }
- case FIELD_TYPE_LONG:
- case FIELD_TYPE_LONGLONG:
- case FIELD_TYPE_TINY:
- case FIELD_TYPE_SHORT:
- case FIELD_TYPE_INT24:
- case FIELD_TYPE_DATE:
- case FIELD_TYPE_DATETIME:
- case FIELD_TYPE_YEAR:
- case FIELD_TYPE_NEWDATE:
- case FIELD_TYPE_ENUM:
- case FIELD_TYPE_SET:
- case FIELD_TYPE_TIME:
- case FIELD_TYPE_TIMESTAMP:
- return(DATA_INT);
- case FIELD_TYPE_FLOAT:
- return(DATA_FLOAT);
- case FIELD_TYPE_DOUBLE:
- return(DATA_DOUBLE);
- case FIELD_TYPE_DECIMAL:
- return(DATA_DECIMAL);
- case FIELD_TYPE_TINY_BLOB:
- case FIELD_TYPE_MEDIUM_BLOB:
- case FIELD_TYPE_BLOB:
- case FIELD_TYPE_LONG_BLOB:
- return(DATA_BLOB);
- default:
- assert(0);
- }
-
- return(0);
-}
-
-/***********************************************************************
-Stores a key value for a row to a buffer. This must currently only be used
-to store a row reference to the 'ref' buffer of this table handle! */
-
-uint
-ha_innobase::store_key_val_for_row(
-/*===============================*/
- /* out: key value length as stored in buff */
- uint keynr, /* in: key number */
- char* buff, /* in/out: buffer for the key value (in MySQL
- format); currently this MUST be the 'ref'
- buffer! */
- const mysql_byte* record)/* in: row in MySQL format */
-{
- KEY* key_info = table->key_info + keynr;
- KEY_PART_INFO* key_part = key_info->key_part;
- KEY_PART_INFO* end = key_part + key_info->key_parts;
- char* buff_start = buff;
-
- DBUG_ENTER("store_key_val_for_row");
-
- for (; key_part != end; key_part++) {
-
- if (key_part->null_bit) {
- /* Store 0 if the key part is a NULL part */
-
- if (record[key_part->null_offset]
- & key_part->null_bit) {
- *buff++ = 1;
- continue;
- }
-
- *buff++ = 0;
- }
-
- memcpy(buff, record + key_part->offset, key_part->length);
- buff += key_part->length;
- }
-
- /* We have to zero-fill the 'ref' buffer so that MySQL is able to
- use a simple memcmp to compare two key values to determine if they are
- equal */
-
- bzero(buff, (ref_length - (uint) (buff - buff_start)));
- DBUG_RETURN(ref_length);
-}
-
-/******************************************************************
-Builds a template to the prebuilt struct. */
-static
-void
-build_template(
-/*===========*/
- row_prebuilt_t* prebuilt, /* in: prebuilt struct */
- THD* thd, /* in: current user thread, used
- only if templ_type is
- ROW_MYSQL_REC_FIELDS */
- TABLE* table, /* in: MySQL table */
- ulint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
- ROW_MYSQL_REC_FIELDS */
-{
- dict_index_t* index;
- dict_index_t* clust_index;
- mysql_row_templ_t* templ;
- Field* field;
- ulint n_fields;
- ulint n_requested_fields = 0;
- ibool fetch_all_in_key = FALSE;
- ulint i;
-
- clust_index = dict_table_get_first_index_noninline(prebuilt->table);
-
- if (!prebuilt->hint_no_need_to_fetch_extra_cols) {
- /* We have a hint that we should at least fetch all
- columns in the key, or all columns in the table */
-
- if (prebuilt->read_just_key) {
- /* MySQL has instructed us that it is enough to
- fetch the columns in the key */
-
- fetch_all_in_key = TRUE;
- } else {
- /* We are building a temporary table: fetch all
- columns; the reason is that MySQL may use the
- clustered index key to store rows, but the mechanism
- we use below to detect required columns does not
- reveal that. Actually, it might be enough to
- fetch only all in the key also in this case! */
-
- templ_type = ROW_MYSQL_WHOLE_ROW;
- }
- }
-
- if (prebuilt->select_lock_type == LOCK_X) {
- /* We always retrieve the whole clustered index record if we
- use exclusive row level locks, for example, if the read is
- done in an UPDATE statement. */
-
- templ_type = ROW_MYSQL_WHOLE_ROW;
- }
-
- if (templ_type == ROW_MYSQL_REC_FIELDS) {
- /* In versions < 3.23.50 we always retrieved the clustered
- index record if prebuilt->select_lock_type == LOCK_S,
- but there is really not need for that, and in some cases
- performance could be seriously degraded because the MySQL
- optimizer did not know about our convention! */
-
- index = prebuilt->index;
- } else {
- index = clust_index;
- }
-
- if (index == clust_index) {
- prebuilt->need_to_access_clustered = TRUE;
- } else {
- prebuilt->need_to_access_clustered = FALSE;
- /* Below we check column by column if we need to access
- the clustered index */
- }
-
- n_fields = (ulint)table->fields;
-
- if (!prebuilt->mysql_template) {
- prebuilt->mysql_template = (mysql_row_templ_t*)
- mem_alloc_noninline(
- n_fields * sizeof(mysql_row_templ_t));
- }
-
- prebuilt->template_type = templ_type;
- prebuilt->null_bitmap_len = table->null_bytes;
-
- prebuilt->templ_contains_blob = FALSE;
-
- for (i = 0; i < n_fields; i++) {
- templ = prebuilt->mysql_template + n_requested_fields;
- field = table->field[i];
-
- if (templ_type == ROW_MYSQL_REC_FIELDS
- && !(fetch_all_in_key &&
- ULINT_UNDEFINED != dict_index_get_nth_col_pos(
- index, i))
- && thd->query_id != field->query_id
- && thd->query_id != (field->query_id ^ MAX_ULONG_BIT)
- && thd->query_id !=
- (field->query_id ^ (MAX_ULONG_BIT >> 1))) {
-
- /* This field is not needed in the query, skip it */
-
- goto skip_field;
- }
-
- n_requested_fields++;
-
- templ->col_no = i;
-
- if (index == clust_index) {
- templ->rec_field_no = (index->table->cols + i)
- ->clust_pos;
- } else {
- templ->rec_field_no = dict_index_get_nth_col_pos(
- index, i);
- }
-
- if (templ->rec_field_no == ULINT_UNDEFINED) {
- prebuilt->need_to_access_clustered = TRUE;
- }
-
- if (field->null_ptr) {
- templ->mysql_null_byte_offset =
- (ulint) ((char*) field->null_ptr
- - (char*) table->record[0]);
-
- templ->mysql_null_bit_mask = (ulint) field->null_bit;
- } else {
- templ->mysql_null_bit_mask = 0;
- }
-
- templ->mysql_col_offset = (ulint)
- get_field_offset(table, field);
-
- templ->mysql_col_len = (ulint) field->pack_length();
- templ->type = get_innobase_type_from_mysql_type(field);
- templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
-
- if (templ->type == DATA_BLOB) {
- prebuilt->templ_contains_blob = TRUE;
- }
-skip_field:
- ;
- }
-
- prebuilt->n_template = n_requested_fields;
-
- if (prebuilt->need_to_access_clustered) {
- /* Change rec_field_no's to correspond to the clustered index
- record */
- for (i = 0; i < n_requested_fields; i++) {
- templ = prebuilt->mysql_template + i;
-
- templ->rec_field_no =
- (index->table->cols + templ->col_no)->clust_pos;
- }
- }
-}
-
-/************************************************************************
-Stores a row in an InnoDB database, to the table specified in this
-handle. */
-
-int
-ha_innobase::write_row(
-/*===================*/
- /* out: error code */
- mysql_byte* record) /* in: a row in MySQL format */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
- int error;
- longlong auto_inc;
- longlong dummy;
-
- DBUG_ENTER("ha_innobase::write_row");
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- statistic_increment(ha_write_count, &LOCK_status);
-
- if (table->time_stamp) {
- update_timestamp(record + table->time_stamp - 1);
- }
-
- if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
-
- innobase_release_stat_resources(prebuilt->trx);
- }
-
- if (table->next_number_field && record == table->record[0]) {
- /* This is the case where the table has an
- auto-increment column */
-
- /* Initialize the auto-inc counter if it has not been
- initialized yet */
-
- if (0 == dict_table_autoinc_peek(prebuilt->table)) {
-
- /* This call initializes the counter */
- error = innobase_read_and_init_auto_inc(&dummy);
-
- if (error) {
- /* Deadlock or lock wait timeout */
-
- goto func_exit;
- }
-
- /* We have to set sql_stat_start to TRUE because
- the above call probably has called a select, and
- has reset that flag; row_insert_for_mysql has to
- know to set the IX intention lock on the table,
- something it only does at the start of each
- statement */
-
- prebuilt->sql_stat_start = TRUE;
- }
-
- /* Fetch the value the user possibly has set in the
- autoincrement field */
-
- auto_inc = table->next_number_field->val_int();
-
- /* In replication and also otherwise the auto-inc column
- can be set with SET INSERT_ID. Then we must look at
- user_thd->next_insert_id. If it is nonzero and the user
- has not supplied a value, we must use it, and use values
- incremented by 1 in all subsequent inserts within the
- same SQL statement! */
-
- if (auto_inc == 0 && user_thd->next_insert_id != 0) {
- auto_inc = user_thd->next_insert_id;
- auto_inc_counter_for_this_stat = auto_inc;
- }
-
- if (auto_inc == 0 && auto_inc_counter_for_this_stat) {
- /* The user set the auto-inc counter for
- this SQL statement with SET INSERT_ID. We must
- assign sequential values from the counter. */
-
- auto_inc_counter_for_this_stat++;
-
- auto_inc = auto_inc_counter_for_this_stat;
-
- /* We give MySQL a new value to place in the
- auto-inc column */
- user_thd->next_insert_id = auto_inc;
- }
-
- if (auto_inc != 0) {
- /* This call will calculate the max of the current
- value and the value supplied by the user and
- update the counter accordingly */
-
- /* We have to use the transactional lock mechanism
- on the auto-inc counter of the table to ensure
- that replication and roll-forward of the binlog
- exactly imitates also the given auto-inc values.
- The lock is released at each SQL statement's
- end. */
-
- srv_conc_enter_innodb(prebuilt->trx);
- error = row_lock_table_autoinc_for_mysql(prebuilt);
- srv_conc_exit_innodb(prebuilt->trx);
-
- if (error != DB_SUCCESS) {
-
- error = convert_error_code_to_mysql(error,
- user_thd);
- goto func_exit;
- }
-
- dict_table_autoinc_update(prebuilt->table, auto_inc);
- } else {
- srv_conc_enter_innodb(prebuilt->trx);
-
- if (!prebuilt->trx->auto_inc_lock) {
-
- error = row_lock_table_autoinc_for_mysql(
- prebuilt);
- if (error != DB_SUCCESS) {
- srv_conc_exit_innodb(prebuilt->trx);
-
- error = convert_error_code_to_mysql(
- error, user_thd);
- goto func_exit;
- }
- }
-
- auto_inc = dict_table_autoinc_get(prebuilt->table);
- srv_conc_exit_innodb(prebuilt->trx);
-
- /* We can give the new value for MySQL to place in
- the field */
-
- user_thd->next_insert_id = auto_inc;
- }
-
- /* This call of a handler.cc function places
- user_thd->next_insert_id to the column value, if the column
- value was not set by the user */
-
- update_auto_increment();
- }
-
- if (prebuilt->mysql_template == NULL
- || prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) {
- /* Build the template used in converting quickly between
- the two database formats */
-
- build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
- }
-
- if (user_thd->lex.sql_command == SQLCOM_INSERT
- && user_thd->lex.duplicates == DUP_IGNORE) {
- prebuilt->trx->ignore_duplicates_in_insert = TRUE;
- } else {
- prebuilt->trx->ignore_duplicates_in_insert = FALSE;
- }
-
- srv_conc_enter_innodb(prebuilt->trx);
-
- error = row_insert_for_mysql((byte*) record, prebuilt);
-
- srv_conc_exit_innodb(prebuilt->trx);
-
- prebuilt->trx->ignore_duplicates_in_insert = FALSE;
-
- error = convert_error_code_to_mysql(error, user_thd);
-
- /* Tell InnoDB server that there might be work for
- utility threads: */
-func_exit:
- innobase_active_small();
-
- DBUG_RETURN(error);
-}
-
-/******************************************************************
-Converts field data for storage in an InnoDB update vector. */
-inline
-mysql_byte*
-innobase_convert_and_store_changed_col(
-/*===================================*/
- /* out: pointer to the end of the converted
- data in the buffer */
- upd_field_t* ufield, /* in/out: field in the update vector */
- mysql_byte* buf, /* in: buffer we can use in conversion */
- mysql_byte* data, /* in: column data to store */
- ulint len, /* in: data len */
- ulint col_type,/* in: data type in InnoDB type numbers */
- ulint is_unsigned)/* in: != 0 if an unsigned integer type */
-{
- uint i;
-
- if (len == UNIV_SQL_NULL) {
- data = NULL;
- } else if (col_type == DATA_VARCHAR || col_type == DATA_BINARY
- || col_type == DATA_VARMYSQL) {
- /* Remove trailing spaces */
- while (len > 0 && data[len - 1] == ' ') {
- len--;
- }
-
- } else if (col_type == DATA_INT) {
- /* Store integer data in InnoDB in a big-endian
- format, sign bit negated, if signed */
-
- for (i = 0; i < len; i++) {
- buf[len - 1 - i] = data[i];
- }
-
- if (!is_unsigned) {
- buf[0] = buf[0] ^ 128;
- }
-
- data = buf;
-
- buf += len;
- }
-
- ufield->new_val.data = data;
- ufield->new_val.len = len;
-
- return(buf);
-}
-
-/**************************************************************************
-Checks which fields have changed in a row and stores information
-of them to an update vector. */
-static
-int
-calc_row_difference(
-/*================*/
- /* out: error number or 0 */
- upd_t* uvect, /* in/out: update vector */
- mysql_byte* old_row, /* in: old row in MySQL format */
- mysql_byte* new_row, /* in: new row in MySQL format */
- struct st_table* table, /* in: table in MySQL data dictionary */
- mysql_byte* upd_buff, /* in: buffer to use */
- row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
- THD* thd) /* in: user thread */
-{
- Field* field;
- uint n_fields;
- ulint o_len;
- ulint n_len;
- byte* o_ptr;
- byte* n_ptr;
- byte* buf;
- upd_field_t* ufield;
- ulint col_type;
- ulint is_unsigned;
- ulint n_changed = 0;
- uint i;
-
- n_fields = table->fields;
-
- /* We use upd_buff to convert changed fields */
- buf = (byte*) upd_buff;
-
- for (i = 0; i < n_fields; i++) {
- field = table->field[i];
-
- /* if (thd->query_id != field->query_id) { */
- /* TODO: check that these fields cannot have
- changed! */
-
- /* goto skip_field;
- }*/
-
- o_ptr = (byte*) old_row + get_field_offset(table, field);
- n_ptr = (byte*) new_row + get_field_offset(table, field);
- o_len = field->pack_length();
- n_len = field->pack_length();
-
- col_type = get_innobase_type_from_mysql_type(field);
- is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
-
- switch (col_type) {
-
- case DATA_BLOB:
- o_ptr = row_mysql_read_blob_ref(&o_len, o_ptr, o_len);
- n_ptr = row_mysql_read_blob_ref(&n_len, n_ptr, n_len);
- break;
- case DATA_VARCHAR:
- case DATA_BINARY:
- case DATA_VARMYSQL:
- o_ptr = row_mysql_read_var_ref_noninline(&o_len, o_ptr);
- n_ptr = row_mysql_read_var_ref_noninline(&n_len, n_ptr);
- default:
- ;
- }
-
- if (field->null_ptr) {
- if (field_in_record_is_null(table, field,
- (char*) old_row)) {
- o_len = UNIV_SQL_NULL;
- }
-
- if (field_in_record_is_null(table, field,
- (char*) new_row)) {
- n_len = UNIV_SQL_NULL;
- }
- }
-
- if (o_len != n_len || (o_len != UNIV_SQL_NULL &&
- 0 != memcmp(o_ptr, n_ptr, o_len))) {
- /* The field has changed */
-
- ufield = uvect->fields + n_changed;
-
- buf = (byte*)
- innobase_convert_and_store_changed_col(ufield,
- (mysql_byte*)buf,
- (mysql_byte*)n_ptr, n_len, col_type,
- is_unsigned);
- ufield->exp = NULL;
- ufield->field_no =
- (prebuilt->table->cols + i)->clust_pos;
- n_changed++;
- }
- ;
- }
-
- uvect->n_fields = n_changed;
- uvect->info_bits = 0;
-
- return(0);
-}
-
-/**************************************************************************
-Updates a row given as a parameter to a new value. Note that we are given
-whole rows, not just the fields which are updated: this incurs some
-overhead for CPU when we check which fields are actually updated.
-TODO: currently InnoDB does not prevent the 'Halloween problem':
-in a searched update a single row can get updated several times
-if its index columns are updated! */
-
-int
-ha_innobase::update_row(
-/*====================*/
- /* out: error number or 0 */
- const mysql_byte* old_row,/* in: old row in MySQL format */
- mysql_byte* new_row)/* in: new row in MySQL format */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- upd_t* uvect;
- int error = 0;
-
- DBUG_ENTER("ha_innobase::update_row");
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- if (table->time_stamp) {
- update_timestamp(new_row + table->time_stamp - 1);
- }
-
- if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
-
- innobase_release_stat_resources(prebuilt->trx);
- }
-
- if (prebuilt->upd_node) {
- uvect = prebuilt->upd_node->update;
- } else {
- uvect = row_get_prebuilt_update_vector(prebuilt);
- }
-
- /* Build an update vector from the modified fields in the rows
- (uses upd_buff of the handle) */
-
- calc_row_difference(uvect, (mysql_byte*) old_row, new_row, table,
- upd_buff, prebuilt, user_thd);
- /* This is not a delete */
- prebuilt->upd_node->is_delete = FALSE;
-
- assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
-
- srv_conc_enter_innodb(prebuilt->trx);
-
- error = row_update_for_mysql((byte*) old_row, prebuilt);
-
- srv_conc_exit_innodb(prebuilt->trx);
-
- error = convert_error_code_to_mysql(error, user_thd);
-
- /* Tell InnoDB server that there might be work for
- utility threads: */
-
- innobase_active_small();
-
- DBUG_RETURN(error);
-}
-
-/**************************************************************************
-Deletes a row given as the parameter. */
-
-int
-ha_innobase::delete_row(
-/*====================*/
- /* out: error number or 0 */
- const mysql_byte* record) /* in: a row in MySQL format */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- int error = 0;
-
- DBUG_ENTER("ha_innobase::delete_row");
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
-
- innobase_release_stat_resources(prebuilt->trx);
- }
-
- if (!prebuilt->upd_node) {
- row_get_prebuilt_update_vector(prebuilt);
- }
-
- /* This is a delete */
-
- prebuilt->upd_node->is_delete = TRUE;
-
- srv_conc_enter_innodb(prebuilt->trx);
-
- error = row_update_for_mysql((byte*) record, prebuilt);
-
- srv_conc_exit_innodb(prebuilt->trx);
-
- error = convert_error_code_to_mysql(error, user_thd);
-
- /* Tell the InnoDB server that there might be work for
- utility threads: */
-
- innobase_active_small();
-
- DBUG_RETURN(error);
-}
-
-/**********************************************************************
-Initializes a handle to use an index. */
-
-int
-ha_innobase::index_init(
-/*====================*/
- /* out: 0 or error number */
- uint keynr) /* in: key (index) number */
-{
- int error = 0;
- DBUG_ENTER("index_init");
-
- error = change_active_index(keynr);
-
- DBUG_RETURN(error);
-}
-
-/**********************************************************************
-Currently does nothing. */
-
-int
-ha_innobase::index_end(void)
-/*========================*/
-{
- int error = 0;
- DBUG_ENTER("index_end");
-
- DBUG_RETURN(error);
-}
-
-/*************************************************************************
-Converts a search mode flag understood by MySQL to a flag understood
-by InnoDB. */
-inline
-ulint
-convert_search_mode_to_innobase(
-/*============================*/
- enum ha_rkey_function find_flag)
-{
- switch (find_flag) {
- case HA_READ_KEY_EXACT: return(PAGE_CUR_GE);
- /* the above does not require the index to be UNIQUE */
- case HA_READ_KEY_OR_NEXT: return(PAGE_CUR_GE);
- case HA_READ_KEY_OR_PREV: return(PAGE_CUR_LE);
- case HA_READ_AFTER_KEY: return(PAGE_CUR_G);
- case HA_READ_BEFORE_KEY: return(PAGE_CUR_L);
- case HA_READ_PREFIX: return(PAGE_CUR_GE);
- case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE);
- /* HA_READ_PREFIX_LAST does not yet work in InnoDB! */
- /* the above PREFIX flags mean that the last
- field in the key value may just be a prefix
- of the complete fixed length field */
- default: assert(0);
- }
-
- return(0);
-}
-
-/*
- BACKGROUND INFO: HOW A SELECT SQL QUERY IS EXECUTED
- ---------------------------------------------------
-The following does not cover all the details, but explains how we determine
-the start of a new SQL statement, and what is associated with it.
-
-For each table in the database the MySQL interpreter may have several
-table handle instances in use, also in a single SQL query. For each table
-handle instance there is an InnoDB 'prebuilt' struct which contains most
-of the InnoDB data associated with this table handle instance.
-
- A) if the user has not explicitly set any MySQL table level locks:
-
- 1) MySQL calls ::external_lock to set an 'intention' table level lock on
-the table of the handle instance. There we set
-prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should be set
-true if we are taking this table handle instance to use in a new SQL
-statement issued by the user. We also increment trx->n_mysql_tables_in_use.
-
- 2) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
-instructions to prebuilt->template of the table handle instance in
-::index_read. The template is used to save CPU time in large joins.
-
- 3) In row_search_for_mysql, if prebuilt->sql_stat_start is true, we
-allocate a new consistent read view for the trx if it does not yet have one,
-or in the case of a locking read, set an InnoDB 'intention' table level
-lock on the table.
-
- 4) We do the SELECT. MySQL may repeatedly call ::index_read for the
-same table handle instance, if it is a join.
-
- 5) When the SELECT ends, MySQL removes its intention table level locks
-in ::external_lock. When trx->n_mysql_tables_in_use drops to zero,
- (a) we execute a COMMIT there if the autocommit is on,
- (b) we also release possible 'SQL statement level resources' InnoDB may
-have for this SQL statement. The MySQL interpreter does NOT execute
-autocommit for pure read transactions, though it should. That is why the
-table handler in that case has to execute the COMMIT in ::external_lock.
-
- B) If the user has explicitly set MySQL table level locks, then MySQL
-does NOT call ::external_lock at the start of the statement. To determine
-when we are at the start of a new SQL statement we at the start of
-::index_read also compare the query id to the latest query id where the
-table handle instance was used. If it has changed, we know we are at the
-start of a new SQL statement. Since the query id can theoretically
-overwrap, we use this test only as a secondary way of determining the
-start of a new SQL statement. */
-
-
-/**************************************************************************
-Positions an index cursor to the index specified in the handle. Fetches the
-row if any. */
-
-int
-ha_innobase::index_read(
-/*====================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND,
- or error number */
- mysql_byte* buf, /* in/out: buffer for the returned
- row */
- const mysql_byte* key_ptr,/* in: key value; if this is NULL
- we position the cursor at the
- start or end of index; this can
- also contain an InnoDB row id, in
- which case key_len is the InnoDB
- row id length */
- uint key_len,/* in: key value length */
- enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- ulint mode;
- dict_index_t* index;
- ulint match_mode = 0;
- int error;
- ulint ret;
-
- DBUG_ENTER("index_read");
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- statistic_increment(ha_read_key_count, &LOCK_status);
-
- if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
-
- innobase_release_stat_resources(prebuilt->trx);
- }
-
- index = prebuilt->index;
-
- /* Note that if the index for which the search template is built is not
- necessarily prebuilt->index, but can also be the clustered index */
-
- if (prebuilt->sql_stat_start) {
- build_template(prebuilt, user_thd, table,
- ROW_MYSQL_REC_FIELDS);
- }
-
- if (key_ptr) {
- /* Convert the search key value to InnoDB format into
- prebuilt->search_tuple */
-
- row_sel_convert_mysql_key_to_innobase(prebuilt->search_tuple,
- (byte*) key_val_buff,
- index,
- (byte*) key_ptr,
- (ulint) key_len);
- } else {
- /* We position the cursor to the last or the first entry
- in the index */
-
- dtuple_set_n_fields(prebuilt->search_tuple, 0);
- }
-
- mode = convert_search_mode_to_innobase(find_flag);
-
- match_mode = 0;
-
- if (find_flag == HA_READ_KEY_EXACT) {
- match_mode = ROW_SEL_EXACT;
-
- } else if (find_flag == HA_READ_PREFIX
- || find_flag == HA_READ_PREFIX_LAST) {
- match_mode = ROW_SEL_EXACT_PREFIX;
- }
-
- last_match_mode = match_mode;
-
- srv_conc_enter_innodb(prebuilt->trx);
-
- ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mode, 0);
-
- srv_conc_exit_innodb(prebuilt->trx);
-
- if (ret == DB_SUCCESS) {
- error = 0;
- table->status = 0;
-
- } else if (ret == DB_RECORD_NOT_FOUND) {
- error = HA_ERR_KEY_NOT_FOUND;
- table->status = STATUS_NOT_FOUND;
-
- } else if (ret == DB_END_OF_INDEX) {
- error = HA_ERR_KEY_NOT_FOUND;
- table->status = STATUS_NOT_FOUND;
- } else {
- error = convert_error_code_to_mysql(ret, user_thd);
- table->status = STATUS_NOT_FOUND;
- }
-
- DBUG_RETURN(error);
-}
-
-/************************************************************************
-Changes the active index of a handle. */
-
-int
-ha_innobase::change_active_index(
-/*=============================*/
- /* out: 0 or error code */
- uint keynr) /* in: use this index; MAX_KEY means always clustered
- index, even if it was internally generated by
- InnoDB */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- KEY* key=0;
-
- statistic_increment(ha_read_key_count, &LOCK_status);
-
- DBUG_ENTER("change_active_index");
-
- active_index = keynr;
-
- if (keynr != MAX_KEY && table->keys > 0) {
- key = table->key_info + active_index;
-
- prebuilt->index = dict_table_get_index_noninline(
- prebuilt->table, key->name);
- } else {
- prebuilt->index = dict_table_get_first_index_noninline(
- prebuilt->table);
- }
-
- if (!prebuilt->index) {
- sql_print_error("Innodb could not find key n:o %u with name %s from dict cache for table %s", keynr, key ? key->name : "NULL", prebuilt->table->name);
- DBUG_RETURN(1);
- }
-
- assert(prebuilt->search_tuple != 0);
-
- dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
-
- dict_index_copy_types(prebuilt->search_tuple, prebuilt->index,
- prebuilt->index->n_fields);
-
- /* Maybe MySQL changes the active index for a handle also
- during some queries, we do not know: then it is safest to build
- the template such that all columns will be fetched */
-
- build_template(prebuilt, user_thd, table, ROW_MYSQL_WHOLE_ROW);
-
- DBUG_RETURN(0);
-}
-
-/**************************************************************************
-Positions an index cursor to the index specified in keynr. Fetches the
-row if any. */
-/* ??? This is only used to read whole keys ??? */
-
-int
-ha_innobase::index_read_idx(
-/*========================*/
- /* out: error number or 0 */
- mysql_byte* buf, /* in/out: buffer for the returned
- row */
- uint keynr, /* in: use this index */
- const mysql_byte* key, /* in: key value; if this is NULL
- we position the cursor at the
- start or end of index */
- uint key_len, /* in: key value length */
- enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
-{
- if (change_active_index(keynr)) {
-
- return(1);
- }
-
- return(index_read(buf, key, key_len, find_flag));
-}
-
-/***************************************************************************
-Reads the next or previous row from a cursor, which must have previously been
-positioned using index_read. */
-
-int
-ha_innobase::general_fetch(
-/*=======================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- mysql_byte* buf, /* in/out: buffer for next row in MySQL
- format */
- uint direction, /* in: ROW_SEL_NEXT or ROW_SEL_PREV */
- uint match_mode) /* in: 0, ROW_SEL_EXACT, or
- ROW_SEL_EXACT_PREFIX */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- ulint ret;
- int error = 0;
-
- DBUG_ENTER("general_fetch");
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- srv_conc_enter_innodb(prebuilt->trx);
-
- ret = row_search_for_mysql((byte*)buf, 0, prebuilt, match_mode,
- direction);
- srv_conc_exit_innodb(prebuilt->trx);
-
- if (ret == DB_SUCCESS) {
- error = 0;
- table->status = 0;
-
- } else if (ret == DB_RECORD_NOT_FOUND) {
- error = HA_ERR_END_OF_FILE;
- table->status = STATUS_NOT_FOUND;
-
- } else if (ret == DB_END_OF_INDEX) {
- error = HA_ERR_END_OF_FILE;
- table->status = STATUS_NOT_FOUND;
- } else {
- error = convert_error_code_to_mysql(ret, user_thd);
- table->status = STATUS_NOT_FOUND;
- }
-
- DBUG_RETURN(error);
-}
-
-/***************************************************************************
-Reads the next row from a cursor, which must have previously been
-positioned using index_read. */
-
-int
-ha_innobase::index_next(
-/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- mysql_byte* buf) /* in/out: buffer for next row in MySQL
- format */
-{
- statistic_increment(ha_read_next_count, &LOCK_status);
-
- return(general_fetch(buf, ROW_SEL_NEXT, 0));
-}
-
-/***********************************************************************
-Reads the next row matching to the key value given as the parameter. */
-
-int
-ha_innobase::index_next_same(
-/*=========================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- mysql_byte* buf, /* in/out: buffer for the row */
- const mysql_byte* key, /* in: key value */
- uint keylen) /* in: key value length */
-{
- statistic_increment(ha_read_next_count, &LOCK_status);
-
- return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
-}
-
-/***************************************************************************
-Reads the previous row from a cursor, which must have previously been
-positioned using index_read. */
-
-int
-ha_innobase::index_prev(
-/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- mysql_byte* buf) /* in/out: buffer for previous row in MySQL
- format */
-{
- return(general_fetch(buf, ROW_SEL_PREV, 0));
-}
-
-/************************************************************************
-Positions a cursor on the first record in an index and reads the
-corresponding row to buf. */
-
-int
-ha_innobase::index_first(
-/*=====================*/
- /* out: 0, HA_ERR_END_OF_FILE,
- or error code */
- mysql_byte* buf) /* in/out: buffer for the row */
-{
- int error;
-
- DBUG_ENTER("index_first");
- statistic_increment(ha_read_first_count, &LOCK_status);
-
- error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
-
- /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
-
- if (error == HA_ERR_KEY_NOT_FOUND) {
- error = HA_ERR_END_OF_FILE;
- }
-
- DBUG_RETURN(error);
-}
-
-/************************************************************************
-Positions a cursor on the last record in an index and reads the
-corresponding row to buf. */
-
-int
-ha_innobase::index_last(
-/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error code */
- mysql_byte* buf) /* in/out: buffer for the row */
-{
- int error;
-
- DBUG_ENTER("index_first");
- statistic_increment(ha_read_last_count, &LOCK_status);
-
- error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
-
- /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
-
- if (error == HA_ERR_KEY_NOT_FOUND) {
- error = HA_ERR_END_OF_FILE;
- }
-
- DBUG_RETURN(error);
-}
-
-/********************************************************************
-Initialize a table scan. */
-
-int
-ha_innobase::rnd_init(
-/*==================*/
- /* out: 0 or error number */
- bool scan) /* in: ???????? */
-{
- int err;
-
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
-
- if (prebuilt->clust_index_was_generated) {
- err = change_active_index(MAX_KEY);
- } else {
- err = change_active_index(primary_key);
- }
-
- start_of_scan = 1;
-
- return(err);
-}
-
-/*********************************************************************
-Ends a table scan ???????????????? */
-
-int
-ha_innobase::rnd_end(void)
-/*======================*/
- /* out: 0 or error number */
-{
- return(index_end());
-}
-
-/*********************************************************************
-Reads the next row in a table scan (also used to read the FIRST row
-in a table scan). */
-
-int
-ha_innobase::rnd_next(
-/*==================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error number */
- mysql_byte* buf)/* in/out: returns the row in this buffer,
- in MySQL format */
-{
- int error;
-
- DBUG_ENTER("rnd_next");
- statistic_increment(ha_read_rnd_next_count, &LOCK_status);
-
- if (start_of_scan) {
- error = index_first(buf);
- if (error == HA_ERR_KEY_NOT_FOUND) {
- error = HA_ERR_END_OF_FILE;
- }
- start_of_scan = 0;
- } else {
- error = general_fetch(buf, ROW_SEL_NEXT, 0);
- }
-
- DBUG_RETURN(error);
-}
-
-/**************************************************************************
-Fetches a row from the table based on a row reference. */
-
-int
-ha_innobase::rnd_pos(
-/*=================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND,
- or error code */
- mysql_byte* buf, /* in/out: buffer for the row */
- mysql_byte* pos) /* in: primary key value of the row in the
- MySQL format, or the row id if the clustered
- index was internally generated by InnoDB;
- the length of data in pos has to be
- ref_length */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- int error;
- uint keynr = active_index;
-
- DBUG_ENTER("rnd_pos");
- statistic_increment(ha_read_rnd_count, &LOCK_status);
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- if (prebuilt->clust_index_was_generated) {
- /* No primary key was defined for the table and we
- generated the clustered index from the row id: the
- row reference is the row id, not any key value
- that MySQL knows of */
-
- error = change_active_index(MAX_KEY);
- } else {
- error = change_active_index(primary_key);
- }
-
- if (error) {
- DBUG_PRINT("error",("Got error: %ld",error));
- DBUG_RETURN(error);
- }
-
- /* Note that we assume the length of the row reference is fixed
- for the table, and it is == ref_length */
-
- error = index_read(buf, pos, ref_length, HA_READ_KEY_EXACT);
- if (error)
- {
- DBUG_PRINT("error",("Got error: %ld",error));
- }
-
- change_active_index(keynr);
-
- DBUG_RETURN(error);
-}
-
-/*************************************************************************
-Stores a reference to the current row to 'ref' field of the handle. Note
-that in the case where we have generated the clustered index for the
-table, the function parameter is illogical: we MUST ASSUME that 'record'
-is the current 'position' of the handle, because if row ref is actually
-the row id internally generated in InnoDB, then 'record' does not contain
-it. We just guess that the row id must be for the record where the handle
-was positioned the last time. */
-
-void
-ha_innobase::position(
-/*==================*/
- const mysql_byte* record) /* in: row in MySQL format */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- uint len;
-
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- if (prebuilt->clust_index_was_generated) {
- /* No primary key was defined for the table and we
- generated the clustered index from row id: the
- row reference will be the row id, not any key value
- that MySQL knows of */
-
- len = DATA_ROW_ID_LEN;
-
- memcpy(ref, prebuilt->row_id, len);
- } else {
- len = store_key_val_for_row(primary_key, (char*) ref, record);
- }
-
- /* Since we do not store len to the buffer 'ref', we must assume
- that len is always fixed for this table. The following assertion
- checks this. */
-
- ut_a(len == ref_length);
-}
-
-/*********************************************************************
-Creates a table definition to an InnoDB database. */
-static
-int
-create_table_def(
-/*=============*/
- trx_t* trx, /* in: InnoDB transaction handle */
- TABLE* form, /* in: information on table
- columns and indexes */
- const char* table_name) /* in: table name */
-{
- Field* field;
- dict_table_t* table;
- ulint n_cols;
- int error;
- ulint col_type;
- ulint nulls_allowed;
- ulint unsigned_type;
- ulint i;
-
- DBUG_ENTER("create_table_def");
- DBUG_PRINT("enter", ("table_name: %s", table_name));
-
- n_cols = form->fields;
-
- /* The '0' below specifies that everything is currently
- created in tablespace 0 */
-
- table = dict_mem_table_create((char*) table_name, 0, n_cols);
-
- for (i = 0; i < n_cols; i++) {
- field = form->field[i];
-
- col_type = get_innobase_type_from_mysql_type(field);
- if (field->null_ptr) {
- nulls_allowed = 0;
- } else {
- nulls_allowed = DATA_NOT_NULL;
- }
-
- if (field->flags & UNSIGNED_FLAG) {
- unsigned_type = DATA_UNSIGNED;
- } else {
- unsigned_type = 0;
- }
-
- dict_mem_table_add_col(table, (char*) field->field_name,
- col_type, (ulint)field->type()
- | nulls_allowed | unsigned_type,
- field->pack_length(), 0);
- }
-
- error = row_create_table_for_mysql(table, trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- DBUG_RETURN(error);
-}
-
-/*********************************************************************
-Creates an index in an InnoDB database. */
-static
-int
-create_index(
-/*=========*/
- trx_t* trx, /* in: InnoDB transaction handle */
- TABLE* form, /* in: information on table
- columns and indexes */
- const char* table_name, /* in: table name */
- uint key_num) /* in: index number */
-{
- dict_index_t* index;
- int error;
- ulint n_fields;
- KEY* key;
- KEY_PART_INFO* key_part;
- ulint ind_type;
- ulint i;
-
- DBUG_ENTER("create_index");
-
- key = form->key_info + key_num;
-
- n_fields = key->key_parts;
-
- ind_type = 0;
-
- if (key_num == form->primary_key)
- {
- ind_type = ind_type | DICT_CLUSTERED;
- }
-
- if (key->flags & HA_NOSAME ) {
- ind_type = ind_type | DICT_UNIQUE;
- }
-
- /* The '0' below specifies that everything in InnoDB is currently
- created in tablespace 0 */
-
- index = dict_mem_index_create((char*) table_name, key->name, 0,
- ind_type, n_fields);
- for (i = 0; i < n_fields; i++) {
- key_part = key->key_part + i;
-
- /* We assume all fields should be sorted in ascending
- order, hence the '0': */
- dict_mem_index_add_field(index,
- (char*) key_part->field->field_name, 0);
- }
-
- error = row_create_index_for_mysql(index, trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- DBUG_RETURN(error);
-}
-
-/*********************************************************************
-Creates an index to an InnoDB table when the user has defined no
-primary index. */
-static
-int
-create_clustered_index_when_no_primary(
-/*===================================*/
- trx_t* trx, /* in: InnoDB transaction handle */
- const char* table_name) /* in: table name */
-{
- dict_index_t* index;
- int error;
-
- /* The first '0' below specifies that everything in InnoDB is
- currently created in file space 0 */
-
- index = dict_mem_index_create((char*) table_name,
- (char*) "GEN_CLUST_INDEX",
- 0, DICT_CLUSTERED, 0);
- error = row_create_index_for_mysql(index, trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- return(error);
-}
-
-/*********************************************************************
-Creates a new table to an InnoDB database. */
-
-int
-ha_innobase::create(
-/*================*/
- /* out: error number */
- const char* name, /* in: table name */
- TABLE* form, /* in: information on table
- columns and indexes */
- HA_CREATE_INFO* create_info) /* in: more information of the
- created table, contains also the
- create statement string */
-{
- int error;
- dict_table_t* innobase_table;
- trx_t* trx;
- int primary_key_no;
- uint i;
- char name2[FN_REFLEN];
- char norm_name[FN_REFLEN];
- THD *thd= current_thd;
-
- DBUG_ENTER("ha_innobase::create");
-
- DBUG_ASSERT(thd != NULL);
-
- trx = trx_allocate_for_mysql();
-
- if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
- trx->check_foreigns = FALSE;
- }
-
- if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
- trx->check_unique_secondary = FALSE;
- }
-
- fn_format(name2, name, "", "",2); // Remove the .frm extension
-
- normalize_table_name(norm_name, name2);
-
- /* Latch the InnoDB data dictionary exclusive so that no deadlocks
- or lock waits can happen in it during a table create operation.
- (Drop table etc. do this latching in row0mysql.c.) */
-
- row_mysql_lock_data_dictionary();
-
- /* Create the table definition in InnoDB */
-
- error = create_table_def(trx, form, norm_name);
-
- if (error) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
- }
-
- /* Look for a primary key */
-
- primary_key_no= (table->primary_key != MAX_KEY ?
- (int) table->primary_key :
- -1);
-
- /* Our function row_get_mysql_key_number_for_index assumes
- the primary key is always number 0, if it exists */
-
- DBUG_ASSERT(primary_key_no == -1 || primary_key_no == 0);
-
- /* Create the keys */
-
- if (form->keys == 0 || primary_key_no == -1) {
- /* Create an index which is used as the clustered index;
- order the rows by their row id which is internally generated
- by InnoDB */
-
- error = create_clustered_index_when_no_primary(trx,
- norm_name);
- if (error) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
- }
- }
-
- if (primary_key_no != -1) {
- /* In InnoDB the clustered index must always be created
- first */
- if ((error = create_index(trx, form, norm_name,
- (uint) primary_key_no))) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
- }
- }
-
- for (i = 0; i < form->keys; i++) {
-
- if (i != (uint) primary_key_no) {
-
- if ((error = create_index(trx, form, norm_name, i))) {
-
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
- }
- }
- }
-
- error = row_table_add_foreign_constraints(trx,
- create_info->create_statement, norm_name);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- if (error) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
- }
-
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary();
-
- /* Flush the log to reduce probability that the .frm files and
- the InnoDB data dictionary get out-of-sync if the user runs
- with innodb_flush_log_at_trx_commit = 0 */
-
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
-
- innobase_table = dict_table_get(norm_name, NULL);
-
- DBUG_ASSERT(innobase_table != 0);
-
- /* Tell the InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(0);
-}
-
-/*********************************************************************
-Drops a table from an InnoDB database. Before calling this function,
-MySQL calls innobase_commit to commit the transaction of the current user.
-Then the current user cannot have locks set on the table. Drop table
-operation inside InnoDB will remove all locks any user has on the table
-inside InnoDB. */
-
-int
-ha_innobase::delete_table(
-/*======================*/
- /* out: error number */
- const char* name) /* in: table name */
-{
- ulint name_len;
- int error;
- trx_t* trx;
- char norm_name[1000];
-
- DBUG_ENTER("ha_innobase::delete_table");
-
- trx = trx_allocate_for_mysql();
-
- name_len = strlen(name);
-
- assert(name_len < 1000);
-
- /* Strangely, MySQL passes the table name without the '.frm'
- extension, in contrast to ::create */
-
- normalize_table_name(norm_name, name);
-
- /* Drop the table in InnoDB */
-
- error = row_drop_table_for_mysql(norm_name, trx, FALSE);
-
- /* Flush the log to reduce probability that the .frm files and
- the InnoDB data dictionary get out-of-sync if the user runs
- with innodb_flush_log_at_trx_commit = 0 */
-
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
-
- /* Tell the InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- innobase_commit_low(trx);
-
- trx_free_for_mysql(trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- DBUG_RETURN(error);
-}
-
-/*********************************************************************
-Removes all tables in the named database inside InnoDB. */
-
-int
-innobase_drop_database(
-/*===================*/
- /* out: error number */
- char* path) /* in: database path; inside InnoDB the name
- of the last directory in the path is used as
- the database name: for example, in 'mysql/data/test'
- the database name is 'test' */
-{
- ulint len = 0;
- trx_t* trx;
- char* ptr;
- int error;
- char namebuf[10000];
-
- ptr = strend(path) - 2;
-
- while (ptr >= path && *ptr != '\\' && *ptr != '/') {
- ptr--;
- len++;
- }
-
- ptr++;
-
- memcpy(namebuf, ptr, len);
- namebuf[len] = '/';
- namebuf[len + 1] = '\0';
-
-#ifdef __WIN__
- casedn_str(namebuf);
-#endif
- trx = trx_allocate_for_mysql();
-
- error = row_drop_database_for_mysql(namebuf, trx);
-
- /* Flush the log to reduce probability that the .frm files and
- the InnoDB data dictionary get out-of-sync if the user runs
- with innodb_flush_log_at_trx_commit = 0 */
-
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
-
- /* Tell the InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- innobase_commit_low(trx);
- trx_free_for_mysql(trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- return(error);
-}
-
-/*************************************************************************
-Renames an InnoDB table. */
-
-int
-ha_innobase::rename_table(
-/*======================*/
- /* out: 0 or error code */
- const char* from, /* in: old name of the table */
- const char* to) /* in: new name of the table */
-{
- ulint name_len1;
- ulint name_len2;
- int error;
- trx_t* trx;
- char norm_from[1000];
- char norm_to[1000];
-
- DBUG_ENTER("ha_innobase::rename_table");
-
- trx = trx_allocate_for_mysql();
-
- name_len1 = strlen(from);
- name_len2 = strlen(to);
-
- assert(name_len1 < 1000);
- assert(name_len2 < 1000);
-
- normalize_table_name(norm_from, from);
- normalize_table_name(norm_to, to);
-
- /* Rename the table in InnoDB */
-
- error = row_rename_table_for_mysql(norm_from, norm_to, trx);
-
- /* Flush the log to reduce probability that the .frm files and
- the InnoDB data dictionary get out-of-sync if the user runs
- with innodb_flush_log_at_trx_commit = 0 */
-
- log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
-
- /* Tell the InnoDB server that there might be work for
- utility threads: */
-
- srv_active_wake_master_thread();
-
- innobase_commit_low(trx);
- trx_free_for_mysql(trx);
-
- error = convert_error_code_to_mysql(error, NULL);
-
- DBUG_RETURN(error);
-}
-
-/*************************************************************************
-Estimates the number of index records in a range. */
-
-ha_rows
-ha_innobase::records_in_range(
-/*==========================*/
- /* out: estimated number of rows,
- currently 32-bit int or uint */
- int keynr, /* in: index number */
- const mysql_byte* start_key, /* in: start key value of the
- range, may also be empty */
- uint start_key_len, /* in: start key val len, may
- also be 0 */
- enum ha_rkey_function start_search_flag,/* in: start search condition
- e.g., 'greater than' */
- const mysql_byte* end_key, /* in: range end key val, may
- also be empty */
- uint end_key_len, /* in: range end key val len,
- may also be 0 */
- enum ha_rkey_function end_search_flag)/* in: range end search cond */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- KEY* key;
- dict_index_t* index;
- mysql_byte* key_val_buff2 = (mysql_byte*) my_malloc(
- table->reclength
- + table->max_key_length + 100,
- MYF(MY_WME));
- dtuple_t* range_start;
- dtuple_t* range_end;
- ib_longlong n_rows;
- ulint mode1;
- ulint mode2;
- void* heap1;
- void* heap2;
-
- DBUG_ENTER("records_in_range");
-
- update_thd(current_thd);
-
- trx_search_latch_release_if_reserved(prebuilt->trx);
-
- active_index = keynr;
-
- key = table->key_info + active_index;
-
- index = dict_table_get_index_noninline(prebuilt->table, key->name);
-
- range_start = dtuple_create_for_mysql(&heap1, key->key_parts);
- dict_index_copy_types(range_start, index, key->key_parts);
-
- range_end = dtuple_create_for_mysql(&heap2, key->key_parts);
- dict_index_copy_types(range_end, index, key->key_parts);
-
- row_sel_convert_mysql_key_to_innobase(
- range_start, (byte*) key_val_buff, index,
- (byte*) start_key,
- (ulint) start_key_len);
-
- row_sel_convert_mysql_key_to_innobase(
- range_end, (byte*) key_val_buff2, index,
- (byte*) end_key,
- (ulint) end_key_len);
-
- mode1 = convert_search_mode_to_innobase(start_search_flag);
- mode2 = convert_search_mode_to_innobase(end_search_flag);
-
- n_rows = btr_estimate_n_rows_in_range(index, range_start,
- mode1, range_end, mode2);
- dtuple_free_for_mysql(heap1);
- dtuple_free_for_mysql(heap2);
-
- my_free((char*) key_val_buff2, MYF(0));
-
- /* The MySQL optimizer seems to believe an estimate of 0 rows is
- always accurate and may return the result 'Empty set' based on that.
- The accuracy is not guaranteed, and even if it were, for a locking
- read we should anyway perform the search to set the next-key lock.
- Add 1 to the value to make sure MySQL does not make the assumption! */
-
- if (n_rows == 0) {
- n_rows = 1;
- }
-
- DBUG_RETURN((ha_rows) n_rows);
-}
-
-/*************************************************************************
-Gives an UPPER BOUND to the number of rows in a table. This is used in
-filesort.cc and the upper bound must hold. TODO: Since the number of
-rows in a table may change after this function is called, we still may
-get a 'Sort aborted' error in filesort.cc of MySQL. The ultimate fix is to
-improve the algorithm of filesort.cc. */
-
-ha_rows
-ha_innobase::estimate_number_of_rows(void)
-/*======================================*/
- /* out: upper bound of rows */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- dict_index_t* index;
- ulonglong estimate;
- ulonglong data_file_length;
-
- DBUG_ENTER("estimate_number_of_rows");
-
- update_thd(current_thd);
-
- trx_search_latch_release_if_reserved(prebuilt->trx);
-
- index = dict_table_get_first_index_noninline(prebuilt->table);
-
- data_file_length = ((ulonglong) index->stat_n_leaf_pages)
- * UNIV_PAGE_SIZE;
-
- /* Calculate a minimum length for a clustered index record and from
- that an upper bound for the number of rows. Since we only calculate
- new statistics in row0mysql.c when a tablehas grown
- by a threshold factor, we must add a safety factor 2 in front
- of the formula below. */
-
- estimate = 2 * data_file_length / dict_index_calc_min_rec_len(index);
-
- DBUG_RETURN((ha_rows) estimate);
-}
-
-/*************************************************************************
-How many seeks it will take to read through the table. This is to be
-comparable to the number returned by records_in_range so that we can
-decide if we should scan the table or use keys. */
-
-double
-ha_innobase::scan_time()
-/*====================*/
- /* out: estimated time measured in disk seeks */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
-
- /* Since MySQL seems to favor table scans too much over index
- searches, we pretend that a sequential read takes the same time
- as a random disk read, that is, we do not divide the following
- by 10, which would be physically realistic. */
-
- return((double) (prebuilt->table->stat_clustered_index_size));
-}
-
-/*************************************************************************
-Returns statistics information of the table to the MySQL interpreter,
-in various fields of the handle object. */
-
-void
-ha_innobase::info(
-/*==============*/
- uint flag) /* in: what information MySQL requests */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- dict_table_t* ib_table;
- dict_index_t* index;
- ulong rec_per_key;
- ulong j;
- ulong i;
-
- DBUG_ENTER("info");
-
- update_thd(current_thd);
-
- trx_search_latch_release_if_reserved(prebuilt->trx);
-
- ib_table = prebuilt->table;
-
- if (flag & HA_STATUS_TIME) {
- /* In sql_show we call with this flag: update then statistics
- so that they are up-to-date */
-
- dict_update_statistics(ib_table);
- }
-
- if (flag & HA_STATUS_VARIABLE) {
- records = (ha_rows)ib_table->stat_n_rows;
- deleted = 0;
- data_file_length = ((ulonglong)
- ib_table->stat_clustered_index_size)
- * UNIV_PAGE_SIZE;
- index_file_length = ((ulonglong)
- ib_table->stat_sum_of_other_index_sizes)
- * UNIV_PAGE_SIZE;
- delete_length = 0;
- check_time = 0;
-
- if (records == 0) {
- mean_rec_length = 0;
- } else {
- mean_rec_length = (ulong) (data_file_length / records);
- }
- }
-
- if (flag & HA_STATUS_CONST) {
- index = dict_table_get_first_index_noninline(ib_table);
-
- if (prebuilt->clust_index_was_generated) {
- index = dict_table_get_next_index_noninline(index);
- }
-
- for (i = 0; i < table->keys; i++) {
- for (j = 0; j < table->key_info[i].key_parts; j++) {
-
- if (index->stat_n_diff_key_vals[j + 1] == 0) {
-
- rec_per_key = records;
- } else {
- rec_per_key = (ulong)(records /
- index->stat_n_diff_key_vals[j + 1]);
- }
-
- /* Since MySQL seems to favor table scans
- too much over index searches, we pretend
- index selectivity is 2 times better than
- our estimate: */
-
- rec_per_key = rec_per_key / 2;
-
- if (rec_per_key == 0) {
- rec_per_key = 1;
- }
-
- table->key_info[i].rec_per_key[j]
- = rec_per_key;
- }
-
- index = dict_table_get_next_index_noninline(index);
- }
- }
-
- /* The trx struct in InnoDB contains a pthread mutex embedded:
- in the debug version of MySQL that it replaced by a 'safe mutex'
- which is of a different size. We have to use a function to access
- trx fields. Otherwise trx->error_info will be a random
- pointer and cause a seg fault. */
-
- if (flag & HA_STATUS_ERRKEY) {
- ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
-
- errkey = (unsigned int) row_get_mysql_key_number_for_index(
- (dict_index_t*)
- trx_get_error_info(prebuilt->trx));
- }
-
- DBUG_VOID_RETURN;
-}
-
-/***********************************************************************
-Tries to check that an InnoDB table is not corrupted. If corruption is
-noticed, prints to stderr information about it. In case of corruption
-may also assert a failure and crash the server. */
-
-int
-ha_innobase::check(
-/*===============*/
- /* out: HA_ADMIN_CORRUPT or
- HA_ADMIN_OK */
- THD* thd, /* in: user thread handle */
- HA_CHECK_OPT* check_opt) /* in: check options, currently
- ignored */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- ulint ret;
-
- ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
-
- if (prebuilt->mysql_template == NULL) {
- /* Build the template; we will use a dummy template
- in index scans done in checking */
-
- build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
- }
-
- ret = row_check_table_for_mysql(prebuilt);
-
- if (ret == DB_SUCCESS) {
- return(HA_ADMIN_OK);
- }
-
- return(HA_ADMIN_CORRUPT);
-}
-
-/*****************************************************************
-Adds information about free space in the InnoDB tablespace to a table comment
-which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
-foreign keys. */
-
-char*
-ha_innobase::update_table_comment(
-/*==============================*/
- /* out: table comment + InnoDB free space +
- info on foreign keys */
- const char* comment)/* in: table comment defined by user */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
- uint length = strlen(comment);
- char* str = my_malloc(length + 550, MYF(0));
- char* pos;
-
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
-
- if (!str) {
- return((char*)comment);
- }
-
- pos = str;
- if (length) {
- pos=strmov(str, comment);
- *pos++=';';
- *pos++=' ';
- }
-
- pos += my_sprintf(pos,
- (pos,"InnoDB free: %lu kB",
- (ulong) innobase_get_free_space()));
-
- /* We assume 450 - length bytes of space to print info */
-
- if (length < 450) {
- dict_print_info_on_foreign_keys(FALSE, pos, 450 - length,
- prebuilt->table);
- }
-
- return(str);
-}
-
-/***********************************************************************
-Gets the foreign key create info for a table stored in InnoDB. */
-
-char*
-ha_innobase::get_foreign_key_create_info(void)
-/*==========================================*/
- /* out, own: character string in the form which
- can be inserted to the CREATE TABLE statement,
- MUST be freed with ::free_foreign_key_create_info */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
- char* str;
-
- if (prebuilt == NULL) {
- fprintf(stderr,
-"InnoDB: Error: cannot get create info for foreign keys\n");
-
- return(NULL);
- }
-
- str = (char*)ut_malloc(10000);
-
- str[0] = '\0';
-
- dict_print_info_on_foreign_keys(TRUE, str, 9000, prebuilt->table);
-
- return(str);
-}
-
-/***********************************************************************
-Frees the foreign key create info for a table stored in InnoDB, if it is
-non-NULL. */
-
-void
-ha_innobase::free_foreign_key_create_info(
-/*======================================*/
- char* str) /* in, own: create info string to free */
-{
- if (str) {
- ut_free(str);
- }
-}
-
-/***********************************************************************
-Tells something additional to the handler about how to do things. */
-
-int
-ha_innobase::extra(
-/*===============*/
- /* out: 0 or error number */
- enum ha_extra_function operation)
- /* in: HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
-
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
-
- switch (operation) {
- case HA_EXTRA_RESET:
- case HA_EXTRA_RESET_STATE:
- prebuilt->read_just_key = 0;
- break;
- case HA_EXTRA_NO_KEYREAD:
- prebuilt->read_just_key = 0;
- break;
- case HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE:
- prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
- break;
- case HA_EXTRA_KEYREAD:
- prebuilt->read_just_key = 1;
- break;
- default:/* Do nothing */
- ;
- }
-
- return(0);
-}
-
-/**********************************************************************
-????????????? */
-
-int
-ha_innobase::reset(void)
-/*====================*/
-{
- return(0);
-}
-
-
-/**********************************************************************
-When we create a temporary table inside MySQL LOCK TABLES, MySQL will
-not call external_lock for the temporary table when it uses it. Instead,
-it will call this function. */
-
-int
-ha_innobase::start_stmt(
-/*====================*/
- /* out: 0 or error code */
- THD* thd) /* in: handle to the user thread */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- trx_t* trx;
-
- update_thd(thd);
-
- trx = prebuilt->trx;
-
- innobase_release_stat_resources(trx);
- trx_mark_sql_stat_end(trx);
-
- auto_inc_counter_for_this_stat = 0;
- prebuilt->sql_stat_start = TRUE;
- prebuilt->hint_no_need_to_fetch_extra_cols = TRUE;
- prebuilt->read_just_key = 0;
-
- if (!prebuilt->mysql_has_locked) {
- /* This handle is for a temporary table created inside
- this same LOCK TABLES; since MySQL does NOT call external_lock
- in this case, we must use x-row locks inside InnoDB to be
- prepared for an update of a row */
-
- prebuilt->select_lock_type = LOCK_X;
- }
-
- thd->transaction.all.innodb_active_trans = 1;
-
- return(0);
-}
-
-/**********************************************************************
-As MySQL will execute an external lock for every new table it uses when it
-starts to process an SQL statement, we can use this function to store the
-pointer to the THD in the handle. We will also use this function to communicate
-to InnoDB that a new SQL statement has started and that we must store a
-savepoint to our transaction handle, so that we are able to roll back
-the SQL statement in case of an error. */
-
-int
-ha_innobase::external_lock(
-/*=======================*/
- THD* thd, /* in: handle to the user thread */
- int lock_type) /* in: lock type */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- int error = 0;
- trx_t* trx;
-
- DBUG_ENTER("ha_innobase::external_lock");
-
- update_thd(thd);
-
- trx = prebuilt->trx;
-
- prebuilt->sql_stat_start = TRUE;
- prebuilt->hint_no_need_to_fetch_extra_cols = TRUE;
-
- prebuilt->read_just_key = 0;
-
- if (lock_type == F_WRLCK) {
-
- /* If this is a SELECT, then it is in UPDATE TABLE ...
- or SELECT ... FOR UPDATE */
- prebuilt->select_lock_type = LOCK_X;
- }
-
- if (lock_type != F_UNLCK) {
- if (trx->n_mysql_tables_in_use == 0) {
- trx_mark_sql_stat_end(trx);
- }
-
- thd->transaction.all.innodb_active_trans = 1;
- trx->n_mysql_tables_in_use++;
- prebuilt->mysql_has_locked = TRUE;
-
- if (thd->tx_isolation == ISO_SERIALIZABLE
- && prebuilt->select_lock_type == LOCK_NONE) {
-
- /* To get serializable execution we let InnoDB
- conceptually add 'LOCK IN SHARE MODE' to all SELECTs
- which otherwise would have been consistent reads */
-
- prebuilt->select_lock_type = LOCK_S;
- }
-
- if (prebuilt->select_lock_type != LOCK_NONE) {
-
- trx->mysql_n_tables_locked++;
- }
- } else {
- trx->n_mysql_tables_in_use--;
- prebuilt->mysql_has_locked = FALSE;
- auto_inc_counter_for_this_stat = 0;
-
- if (trx->n_mysql_tables_in_use == 0) {
-
- trx->mysql_n_tables_locked = 0;
-
- /* Here we release the search latch, auto_inc_lock,
- and InnoDB thread FIFO ticket if they were reserved. */
-
- innobase_release_stat_resources(trx);
-
- if (!(thd->options
- & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) {
-
- innobase_commit(thd, trx);
- thd->transaction.all.innodb_active_trans=0;
- }
- }
- }
-
- DBUG_RETURN(error);
-}
-
-/****************************************************************************
-Implements the SHOW INNODB STATUS command. Send the output of the InnoDB
-Monitor to the client. */
-
-int
-innodb_show_status(
-/*===============*/
- THD* thd) /* in: the MySQL query thread of the caller */
-{
- String* packet = &thd->packet;
- char* buf;
-
- DBUG_ENTER("innodb_show_status");
-
- if (innodb_skip) {
-
- fprintf(stderr,
- "Cannot call SHOW INNODB STATUS because skip-innodb is defined\n");
-
- DBUG_RETURN(-1);
- }
-
- /* We let the InnoDB Monitor to output at most 100 kB of text, add
- a safety margin of 10 kB for buffer overruns */
-
- buf = (char*)ut_malloc(110 * 1024);
-
- srv_sprintf_innodb_monitor(buf, 100 * 1024);
-
- List<Item> field_list;
-
- field_list.push_back(new Item_empty_string("Status", strlen(buf)));
-
- if(send_fields(thd, field_list, 1)) {
- DBUG_RETURN(-1);
- }
-
- packet->length(0);
-
- net_store_data(packet, buf);
-
- if (my_net_write(&thd->net, (char*)thd->packet.ptr(),
- packet->length())) {
- ut_free(buf);
-
- DBUG_RETURN(-1);
- }
-
- ut_free(buf);
-
- send_eof(&thd->net);
-
- DBUG_RETURN(0);
-}
-
-/****************************************************************************
- Handling the shared INNOBASE_SHARE structure that is needed to provide table
- locking.
-****************************************************************************/
-
-static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
- my_bool not_used __attribute__((unused)))
-{
- *length=share->table_name_length;
- return (mysql_byte*) share->table_name;
-}
-
-static INNOBASE_SHARE *get_share(const char *table_name)
-{
- INNOBASE_SHARE *share;
- pthread_mutex_lock(&innobase_mutex);
- uint length=(uint) strlen(table_name);
- if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables,
- (mysql_byte*) table_name,
- length)))
- {
- if ((share=(INNOBASE_SHARE *) my_malloc(sizeof(*share)+length+1,
- MYF(MY_WME | MY_ZEROFILL))))
- {
- share->table_name_length=length;
- share->table_name=(char*) (share+1);
- strmov(share->table_name,table_name);
- if (hash_insert(&innobase_open_tables, (mysql_byte*) share))
- {
- pthread_mutex_unlock(&innobase_mutex);
- my_free((gptr) share,0);
- return 0;
- }
- thr_lock_init(&share->lock);
- pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
- }
- }
- share->use_count++;
- pthread_mutex_unlock(&innobase_mutex);
- return share;
-}
-
-static void free_share(INNOBASE_SHARE *share)
-{
- pthread_mutex_lock(&innobase_mutex);
- if (!--share->use_count)
- {
- hash_delete(&innobase_open_tables, (mysql_byte*) share);
- thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->mutex);
- my_free((gptr) share, MYF(0));
- }
- pthread_mutex_unlock(&innobase_mutex);
-}
-
-/*********************************************************************
-Stores a MySQL lock into a 'lock' field in a handle. */
-
-THR_LOCK_DATA**
-ha_innobase::store_lock(
-/*====================*/
- /* out: pointer to the next
- element in the 'to' array */
- THD* thd, /* in: user thread handle */
- THR_LOCK_DATA** to, /* in: pointer to an array
- of pointers to lock structs;
- pointer to the 'lock' field
- of current handle is stored
- next to this array */
- enum thr_lock_type lock_type) /* in: lock type to store in
- 'lock' */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
-
- if (lock_type == TL_READ_WITH_SHARED_LOCKS ||
- lock_type == TL_READ_NO_INSERT) {
- /* This is a SELECT ... IN SHARE MODE, or
- we are doing a complex SQL statement like
- INSERT INTO ... SELECT ... and the logical logging (MySQL
- binlog) requires the use of a locking read */
-
- prebuilt->select_lock_type = LOCK_S;
- } else if (lock_type != TL_IGNORE) {
- /* We set possible LOCK_X value in external_lock, not yet
- here even if this would be SELECT ... FOR UPDATE */
-
- prebuilt->select_lock_type = LOCK_NONE;
- }
-
- if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
-
- /* If we are not doing a LOCK TABLE, then allow multiple
- writers */
-
- if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
- lock_type <= TL_WRITE) && !thd->in_lock_tables) {
-
- lock_type = TL_WRITE_ALLOW_WRITE;
- }
-
- /* In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
- MySQL would use the lock TL_READ_NO_INSERT on t2, and that
- would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
- to t2. Convert the lock to a normal read lock to allow
- concurrent inserts to t2. */
-
- if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) {
- lock_type = TL_READ;
- }
-
- lock.type=lock_type;
- }
-
- *to++= &lock;
-
- return(to);
-}
-
-/***********************************************************************
-This function initializes the auto-inc counter if it has not been
-initialized yet. This function does not change the value of the auto-inc
-counter if it already has been initialized. In parameter ret returns
-the value of the auto-inc counter. */
-
-int
-ha_innobase::innobase_read_and_init_auto_inc(
-/*=========================================*/
- /* out: 0 or error code: deadlock or
- lock wait timeout */
- longlong* ret) /* out: auto-inc value */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- longlong auto_inc;
- int error;
-
- ut_a(prebuilt);
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->transaction.all.innobase_tid);
- ut_a(prebuilt->table);
-
- auto_inc = dict_table_autoinc_read(prebuilt->table);
-
- if (auto_inc != 0) {
- /* Already initialized */
- *ret = auto_inc;
-
- return(0);
- }
-
- srv_conc_enter_innodb(prebuilt->trx);
- error = row_lock_table_autoinc_for_mysql(prebuilt);
- srv_conc_exit_innodb(prebuilt->trx);
-
- if (error != DB_SUCCESS) {
- error = convert_error_code_to_mysql(error, user_thd);
-
- goto func_exit;
- }
-
- /* Check again if someone has initialized the counter meanwhile */
- auto_inc = dict_table_autoinc_read(prebuilt->table);
-
- if (auto_inc != 0) {
- *ret = auto_inc;
-
- return(0);
- }
-
- (void) extra(HA_EXTRA_KEYREAD);
- index_init(table->next_number_index);
-
- /* We use an exclusive lock when we read the max key value from the
- auto-increment column index. This is because then build_template will
- advise InnoDB to fetch all columns. In SHOW TABLE STATUS the query
- id of the auto-increment column is not changed, and previously InnoDB
- did not fetch it, causing SHOW TABLE STATUS to show wrong values
- for the autoinc column. */
-
- prebuilt->select_lock_type = LOCK_X;
-
- /* Play safe and also give in another way the hint to fetch
- all columns in the key: */
-
- prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
-
- prebuilt->trx->mysql_n_tables_locked += 1;
-
- error = index_last(table->record[1]);
-
- if (error) {
- if (error == HA_ERR_END_OF_FILE) {
- /* The table was empty, initialize to 1 */
- auto_inc = 1;
-
- error = 0;
- } else {
- /* Deadlock or a lock wait timeout */
- auto_inc = -1;
-
- goto func_exit;
- }
- } else {
- /* Initialize to max(col) + 1 */
- auto_inc = (longlong) table->next_number_field->
- val_int_offset(table->rec_buff_length) + 1;
- }
-
- dict_table_autoinc_initialize(prebuilt->table, auto_inc);
-
-func_exit:
- (void) extra(HA_EXTRA_NO_KEYREAD);
-
- index_end();
-
- *ret = auto_inc;
-
- return(error);
-}
-
-/***********************************************************************
-This function initializes the auto-inc counter if it has not been
-initialized yet. This function does not change the value of the auto-inc
-counter if it already has been initialized. Returns the value of the
-auto-inc counter. */
-
-longlong
-ha_innobase::get_auto_increment()
-/*=============================*/
- /* out: auto-increment column value, -1 if error
- (deadlock or lock wait timeout) */
-{
- longlong nr;
- int error;
-
- error = innobase_read_and_init_auto_inc(&nr);
-
- if (error) {
-
- return(-1);
- }
-
- return(nr);
-}
-
-#endif /* HAVE_INNOBASE_DB */
diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h
deleted file mode 100644
index 4fd42d08390..00000000000
--- a/sql/ha_innobase.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
- && Innobase Oy
-
- -This file is modified from ha_berkeley.h of MySQL distribution-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-/* This file defines the Innobase handler: the interface between MySQL and
-Innobase */
-
-typedef struct st_innobase_share {
- THR_LOCK lock;
- pthread_mutex_t mutex;
- char *table_name;
- uint table_name_length,use_count;
-} INNOBASE_SHARE;
-
-
-/* The class defining a handle to an Innobase table */
-class ha_innobase: public handler
-{
- void* innobase_prebuilt; /* (row_prebuilt_t*) prebuilt
- struct in Innobase, used to save
- CPU */
- THD* user_thd; /* the thread handle of the user
- currently using the handle; this is
- set in external_lock function */
- ulong last_query_id; /* the latest query id where the
- handle was used */
- THR_LOCK_DATA lock;
- INNOBASE_SHARE *share;
-
- gptr alloc_ptr;
- byte* upd_buff; /* buffer used in updates */
- byte* key_val_buff; /* buffer used in converting
- search key values from MySQL format
- to Innobase format */
- ulong int_option_flag;
- uint primary_key;
- uint last_dup_key;
- ulong start_of_scan; /* this is set to 1 when we are
- starting a table scan but have not
- yet fetched any row, else 0 */
-
- uint last_match_mode;/* match mode of the latest search:
- ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
- or undefined */
- longlong auto_inc_counter_for_this_stat;
- ulong max_row_length(const byte *buf);
-
- uint store_key_val_for_row(uint keynr, char* buff, const byte* record);
- int update_thd(THD* thd);
- int change_active_index(uint keynr);
- int general_fetch(byte* buf, uint direction, uint match_mode);
- int innobase_read_and_init_auto_inc(longlong* ret);
-
- /* Init values for the class: */
- public:
- ha_innobase(TABLE *table): handler(table),
- int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER |
- HA_REC_NOT_IN_SEQ |
- HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
- HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY |
- HA_LONGLONG_KEYS | HA_NULL_KEY |
- HA_NOT_EXACT_COUNT | HA_NO_FULLTEXT_KEY |
- HA_NO_WRITE_DELAYED |
- HA_PRIMARY_KEY_IN_READ_INDEX |
- HA_DROP_BEFORE_CREATE |
- HA_NO_PREFIX_CHAR_KEYS),
- last_dup_key((uint) -1),
- start_of_scan(0)
- {
- }
- ~ha_innobase() {}
-
- const char* table_type() const { return("InnoDB");}
- const char** bas_ext() const;
- ulong option_flag() const { return int_option_flag; }
- uint max_record_length() const { return HA_MAX_REC_LENGTH; }
- uint max_keys() const { return MAX_KEY; }
- uint max_key_parts() const { return MAX_REF_PARTS; }
- /* An InnoDB page must store >= 2 keys;
- a secondary key record must also contain the
- primary key value:
- max key length is therefore set to slightly
- less than 1 / 4 of page size which is 16 kB;
- but currently MySQL does not work with keys
- whose size is > MAX_KEY_LENGTH */
- uint max_key_length() const { return((MAX_KEY_LENGTH <= 3500) ?
- MAX_KEY_LENGTH : 3500);}
- bool fast_key_read() { return 1;}
- key_map keys_to_use_for_scanning() { return ~(key_map) 0; }
- bool has_transactions() { return 1;}
-
- int open(const char *name, int mode, uint test_if_locked);
- void initialize(void);
- int close(void);
- double scan_time();
-
- int write_row(byte * buf);
- int update_row(const byte * old_data, byte * new_data);
- int delete_row(const byte * buf);
-
- int index_init(uint index);
- int index_end();
- int index_read(byte * buf, const byte * key,
- uint key_len, enum ha_rkey_function find_flag);
- int index_read_idx(byte * buf, uint index, const byte * key,
- uint key_len, enum ha_rkey_function find_flag);
- int index_next(byte * buf);
- int index_next_same(byte * buf, const byte *key, uint keylen);
- int index_prev(byte * buf);
- int index_first(byte * buf);
- int index_last(byte * buf);
-
- int rnd_init(bool scan=1);
- int rnd_end();
- int rnd_next(byte *buf);
- int rnd_pos(byte * buf, byte *pos);
-
- void position(const byte *record);
- void info(uint);
- int extra(enum ha_extra_function operation);
- int reset(void);
- int external_lock(THD *thd, int lock_type);
- int start_stmt(THD *thd);
-
- void position(byte *record);
- ha_rows records_in_range(int inx,
- const byte *start_key,uint start_key_len,
- enum ha_rkey_function start_search_flag,
- const byte *end_key,uint end_key_len,
- enum ha_rkey_function end_search_flag);
- ha_rows estimate_number_of_rows();
-
- int create(const char *name, register TABLE *form,
- HA_CREATE_INFO *create_info);
- int delete_table(const char *name);
- int rename_table(const char* from, const char* to);
- int check(THD* thd, HA_CHECK_OPT* check_opt);
- char* update_table_comment(const char* comment);
- char* get_foreign_key_create_info();
- void free_foreign_key_create_info(char* str);
- THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
- enum thr_lock_type lock_type);
- /* void init_table_handle_for_HANDLER(); Not tested or used yet, code
- included for documentational purposes only */
- longlong get_auto_increment();
-};
-
-extern bool innodb_skip;
-extern SHOW_COMP_OPTION have_innodb;
-extern uint innobase_init_flags, innobase_lock_type;
-extern ulong innobase_cache_size;
-extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
-extern long innobase_lock_scan_time;
-extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
-extern long innobase_log_file_size, innobase_log_buffer_size;
-extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
-extern long innobase_file_io_threads, innobase_lock_wait_timeout;
-extern long innobase_force_recovery, innobase_thread_concurrency;
-extern char *innobase_data_home_dir, *innobase_data_file_path;
-extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
-extern char *innobase_unix_file_flush_method;
-extern long innobase_flush_log_at_trx_commit;
-/* The following variables have to be my_bool for SHOW VARIABLES to work */
-extern my_bool innobase_log_archive,
- innobase_use_native_aio, innobase_fast_shutdown;
-
-extern TYPELIB innobase_lock_typelib;
-
-bool innobase_init(void);
-bool innobase_end(void);
-bool innobase_flush_logs(void);
-uint innobase_get_free_space(void);
-
-int innobase_commit(THD *thd, void* trx_handle);
-int innobase_report_binlog_offset_and_commit(
- THD* thd,
- void* trx_handle,
- char* log_file_name,
- my_off_t end_offset);
-int innobase_rollback(THD *thd, void* trx_handle);
-int innobase_close_connection(THD *thd);
-int innobase_drop_database(char *path);
-int innodb_show_status(THD* thd);
-
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
new file mode 100644
index 00000000000..68052014f57
--- /dev/null
+++ b/sql/ha_innodb.cc
@@ -0,0 +1,4863 @@
+/* Copyright (C) 2000 MySQL AB & Innobase Oy
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* This file defines the InnoDB handler: the interface between MySQL and
+InnoDB */
+
+#ifdef __GNUC__
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "slave.h"
+
+#ifdef HAVE_INNOBASE_DB
+#include <m_ctype.h>
+#include <assert.h>
+#include <hash.h>
+#include <myisampack.h>
+
+#define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
+
+#include "ha_innodb.h"
+
+pthread_mutex_t innobase_mutex;
+
+/* Store MySQL definition of 'byte': in Linux it is char while InnoDB
+uses unsigned char; the header univ.i which we include next defines
+'byte' as a macro which expands to 'unsigned char' */
+
+typedef byte mysql_byte;
+
+#define INSIDE_HA_INNOBASE_CC
+
+/* Include necessary InnoDB headers */
+extern "C" {
+#include "../innobase/include/univ.i"
+#include "../innobase/include/os0file.h"
+#include "../innobase/include/os0thread.h"
+#include "../innobase/include/srv0start.h"
+#include "../innobase/include/srv0srv.h"
+#include "../innobase/include/trx0roll.h"
+#include "../innobase/include/trx0trx.h"
+#include "../innobase/include/trx0sys.h"
+#include "../innobase/include/row0ins.h"
+#include "../innobase/include/row0mysql.h"
+#include "../innobase/include/row0sel.h"
+#include "../innobase/include/row0upd.h"
+#include "../innobase/include/log0log.h"
+#include "../innobase/include/lock0lock.h"
+#include "../innobase/include/dict0crea.h"
+#include "../innobase/include/btr0cur.h"
+#include "../innobase/include/btr0btr.h"
+#include "../innobase/include/fsp0fsp.h"
+}
+
+#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
+#define HA_INNOBASE_RANGE_COUNT 100
+
+bool innodb_skip = 0;
+uint innobase_init_flags = 0;
+ulong innobase_cache_size = 0;
+
+/* The default values for the following, type long, start-up parameters
+are declared in mysqld.cc: */
+
+long innobase_mirrored_log_groups, innobase_log_files_in_group,
+ innobase_log_file_size, innobase_log_buffer_size,
+ innobase_buffer_pool_size, innobase_additional_mem_pool_size,
+ innobase_file_io_threads, innobase_lock_wait_timeout,
+ innobase_thread_concurrency, innobase_force_recovery;
+
+/* The default values for the following char* start-up parameters
+are determined in innobase_init below: */
+
+char* innobase_data_home_dir = NULL;
+char* innobase_data_file_path = NULL;
+char* innobase_log_group_home_dir = NULL;
+char* innobase_log_arch_dir = NULL;
+/* The following has a misleading name: starting from 4.0.5, this also
+affects Windows: */
+char* innobase_unix_file_flush_method = NULL;
+
+/* Below we have boolean-valued start-up parameters, and their default
+values */
+
+uint innobase_flush_log_at_trx_commit = 1;
+my_bool innobase_log_archive = FALSE;
+my_bool innobase_use_native_aio = FALSE;
+my_bool innobase_fast_shutdown = TRUE;
+
+static char *internal_innobase_data_file_path = NULL;
+
+/* The following counter is used to convey information to InnoDB
+about server activity: in selects it is not sensible to call
+srv_active_wake_master_thread after each fetch or search, we only do
+it every INNOBASE_WAKE_INTERVAL'th step. */
+
+#define INNOBASE_WAKE_INTERVAL 32
+ulong innobase_active_counter = 0;
+
+char* innobase_home = NULL;
+
+char innodb_dummy_stmt_trx_handle = 'D';
+
+static HASH innobase_open_tables;
+
+static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
+ my_bool not_used __attribute__((unused)));
+static INNOBASE_SHARE *get_share(const char *table_name);
+static void free_share(INNOBASE_SHARE *share);
+static void innobase_print_error(const char* db_errpfx, char* buffer);
+
+/* General functions */
+
+/**********************************************************************
+Save some CPU by testing the value of srv_thread_concurrency in inline
+functions. */
+inline
+void
+innodb_srv_conc_enter_innodb(
+/*=========================*/
+ trx_t* trx) /* in: transaction handle */
+{
+ if (srv_thread_concurrency >= 500) {
+
+ return;
+ }
+
+ srv_conc_enter_innodb(trx);
+}
+
+/**********************************************************************
+Save some CPU by testing the value of srv_thread_concurrency in inline
+functions. */
+inline
+void
+innodb_srv_conc_exit_innodb(
+/*========================*/
+ trx_t* trx) /* in: transaction handle */
+{
+ if (srv_thread_concurrency >= 500) {
+
+ return;
+ }
+
+ srv_conc_exit_innodb(trx);
+}
+
+/**********************************************************************
+Releases possible search latch and InnoDB thread FIFO ticket. These should
+be released at each SQL statement end, and also when mysqld passes the
+control to the client. It does no harm to release these also in the middle
+of an SQL statement. */
+inline
+void
+innobase_release_stat_resources(
+/*============================*/
+ trx_t* trx) /* in: transaction object */
+{
+ if (trx->has_search_latch) {
+ trx_search_latch_release_if_reserved(trx);
+ }
+
+ if (trx->declared_to_be_inside_innodb) {
+ /* Release our possible ticket in the FIFO */
+
+ srv_conc_force_exit_innodb(trx);
+ }
+}
+
+/************************************************************************
+Call this function when mysqld passes control to the client. That is to
+avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more
+documentation, see handler.cc. */
+
+void
+innobase_release_temporary_latches(
+/*===============================*/
+ void* innobase_tid)
+{
+ innobase_release_stat_resources((trx_t*)innobase_tid);
+}
+
+/************************************************************************
+Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
+time calls srv_active_wake_master_thread. This function should be used
+when a single database operation may introduce a small need for
+server utility activity, like checkpointing. */
+inline
+void
+innobase_active_small(void)
+/*=======================*/
+{
+ innobase_active_counter++;
+
+ if ((innobase_active_counter % INNOBASE_WAKE_INTERVAL) == 0) {
+ srv_active_wake_master_thread();
+ }
+}
+
+/************************************************************************
+Converts an InnoDB error code to a MySQL error code and also tells to MySQL
+about a possible transaction rollback inside InnoDB caused by a lock wait
+timeout or a deadlock. */
+static
+int
+convert_error_code_to_mysql(
+/*========================*/
+ /* out: MySQL error code */
+ int error, /* in: InnoDB error code */
+ THD* thd) /* in: user thread handle or NULL */
+{
+ if (error == DB_SUCCESS) {
+
+ return(0);
+
+ } else if (error == (int) DB_DUPLICATE_KEY) {
+
+ return(HA_ERR_FOUND_DUPP_KEY);
+
+ } else if (error == (int) DB_RECORD_NOT_FOUND) {
+
+ return(HA_ERR_NO_ACTIVE_RECORD);
+
+ } else if (error == (int) DB_ERROR) {
+
+ return(-1); /* unspecified error */
+
+ } else if (error == (int) DB_DEADLOCK) {
+ /* Since we rolled back the whole transaction, we must
+ tell it also to MySQL so that MySQL knows to empty the
+ cached binlog for this transaction */
+
+ if (thd) {
+ ha_rollback(thd);
+ }
+
+ return(HA_ERR_LOCK_DEADLOCK);
+
+ } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
+
+ /* Since we rolled back the whole transaction, we must
+ tell it also to MySQL so that MySQL knows to empty the
+ cached binlog for this transaction */
+
+ if (thd) {
+ ha_rollback(thd);
+ }
+
+ return(HA_ERR_LOCK_WAIT_TIMEOUT);
+
+ } else if (error == (int) DB_NO_REFERENCED_ROW) {
+
+ return(HA_ERR_NO_REFERENCED_ROW);
+
+ } else if (error == (int) DB_ROW_IS_REFERENCED) {
+
+ return(HA_ERR_ROW_IS_REFERENCED);
+
+ } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
+
+ return(HA_ERR_CANNOT_ADD_FOREIGN);
+
+ } else if (error == (int) DB_CANNOT_DROP_CONSTRAINT) {
+
+ return(HA_ERR_ROW_IS_REFERENCED);
+
+ } else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) {
+
+ return(HA_ERR_CRASHED);
+
+ } else if (error == (int) DB_OUT_OF_FILE_SPACE) {
+
+ return(HA_ERR_RECORD_FILE_FULL);
+
+ } else if (error == (int) DB_TABLE_IS_BEING_USED) {
+
+ return(HA_ERR_WRONG_COMMAND);
+
+ } else if (error == (int) DB_TABLE_NOT_FOUND) {
+
+ return(HA_ERR_KEY_NOT_FOUND);
+
+ } else if (error == (int) DB_TOO_BIG_RECORD) {
+
+ return(HA_ERR_TO_BIG_ROW);
+
+ } else if (error == (int) DB_CORRUPTION) {
+
+ return(HA_ERR_CRASHED);
+ } else if (error == (int) DB_NO_SAVEPOINT) {
+
+ return(HA_ERR_NO_SAVEPOINT);
+ } else {
+ return(-1); // Unknown error
+ }
+}
+
+extern "C" {
+/*****************************************************************
+Prints info of a THD object (== user session thread) to the
+standard output. NOTE that /mysql/innobase/trx/trx0trx.c must contain
+the prototype for this function! */
+
+void
+innobase_mysql_print_thd(
+/*=====================*/
+ char* buf, /* in/out: buffer where to print, must be at least
+ 400 bytes */
+ void* input_thd)/* in: pointer to a MySQL THD object */
+{
+ THD* thd;
+ char* old_buf = buf;
+
+ thd = (THD*) input_thd;
+
+ /* We cannot use the return value of normal sprintf() as this is
+ not portable to some old non-Posix Unixes, e.g., some old SCO
+ Unixes */
+
+ buf += my_sprintf(buf,
+ (buf, "MySQL thread id %lu, query id %lu",
+ thd->thread_id, thd->query_id));
+ if (thd->host) {
+ *buf = ' ';
+ buf++;
+ buf = strnmov(buf, thd->host, 30);
+ }
+
+ if (thd->ip) {
+ *buf = ' ';
+ buf++;
+ buf=strnmov(buf, thd->ip, 20);
+ }
+
+ if (thd->user) {
+ *buf = ' ';
+ buf++;
+ buf=strnmov(buf, thd->user, 20);
+ }
+
+ if (thd->proc_info) {
+ *buf = ' ';
+ buf++;
+ buf=strnmov(buf, thd->proc_info, 50);
+ }
+
+ if (thd->query) {
+ *buf = '\n';
+ buf++;
+ buf=strnmov(buf, thd->query, 150);
+ }
+
+ buf[0] = '\n';
+ buf[1] = '\0'; /* Note that we must put a null character here to end
+ the printed string */
+
+ /* We test the printed length did not overrun the buffer length of
+ 400 bytes */
+
+ ut_a(strlen(old_buf) < 400);
+}
+}
+
+/*************************************************************************
+Gets the InnoDB transaction handle for a MySQL handler object, creates
+an InnoDB transaction struct if the corresponding MySQL thread struct still
+lacks one. */
+static
+trx_t*
+check_trx_exists(
+/*=============*/
+ /* out: InnoDB transaction handle */
+ THD* thd) /* in: user thread handle */
+{
+ trx_t* trx;
+
+ ut_a(thd == current_thd);
+
+ trx = (trx_t*) thd->transaction.all.innobase_tid;
+
+ if (trx == NULL) {
+ DBUG_ASSERT(thd != NULL);
+ trx = trx_allocate_for_mysql();
+
+ trx->mysql_thd = thd;
+ trx->mysql_query_str = &((*thd).query);
+
+ thd->transaction.all.innobase_tid = trx;
+
+ /* The execution of a single SQL statement is denoted by
+ a 'transaction' handle which is a dummy pointer: InnoDB
+ remembers internally where the latest SQL statement
+ started, and if error handling requires rolling back the
+ latest statement, InnoDB does a rollback to a savepoint. */
+
+ thd->transaction.stmt.innobase_tid =
+ (void*)&innodb_dummy_stmt_trx_handle;
+ } else {
+ if (trx->magic_n != TRX_MAGIC_N) {
+ mem_analyze_corruption((byte*)trx);
+
+ ut_a(0);
+ }
+ }
+
+ if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ trx->check_foreigns = FALSE;
+ } else {
+ trx->check_foreigns = TRUE;
+ }
+
+ if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
+ trx->check_unique_secondary = FALSE;
+ } else {
+ trx->check_unique_secondary = TRUE;
+ }
+
+ return(trx);
+}
+
+/*************************************************************************
+Updates the user_thd field in a handle and also allocates a new InnoDB
+transaction handle if needed, and updates the transaction fields in the
+prebuilt struct. */
+inline
+int
+ha_innobase::update_thd(
+/*====================*/
+ /* out: 0 or error code */
+ THD* thd) /* in: thd to use the handle */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ trx_t* trx;
+
+ trx = check_trx_exists(thd);
+
+ if (prebuilt->trx != trx) {
+
+ row_update_prebuilt_trx(prebuilt, trx);
+ }
+
+ user_thd = thd;
+
+ return(0);
+}
+
+
+/* BACKGROUND INFO: HOW THE MYSQL QUERY CACHE WORKS WITH INNODB
+ ------------------------------------------------------------
+
+1) The use of the query cache for TBL is disabled when there is an
+uncommitted change to TBL.
+
+2) When a change to TBL commits, InnoDB stores the current value of
+its global trx id counter, let us denote it by INV_TRX_ID, to the table object
+in the InnoDB data dictionary, and does only allow such transactions whose
+id >= INV_TRX_ID to use the query cache.
+
+3) When InnoDB does an INSERT/DELETE/UPDATE to a table TBL, or an implicit
+modification because an ON DELETE CASCADE, we invalidate the MySQL query cache
+of TBL immediately.
+
+How this is implemented inside InnoDB:
+
+1) Since every modification always sets an IX type table lock on the InnoDB
+table, it is easy to check if there can be uncommitted modifications for a
+table: just check if there are locks in the lock list of the table.
+
+2) When a transaction inside InnoDB commits, it reads the global trx id
+counter and stores the value INV_TRX_ID to the tables on which it had a lock.
+
+3) If there is an implicit table change from ON DELETE CASCADE or SET NULL,
+InnoDB calls an invalidate method for the MySQL query cache for that table.
+
+How this is implemented inside sql_cache.cc:
+
+1) The query cache for an InnoDB table TBL is invalidated immediately at an
+INSERT/UPDATE/DELETE, just like in the case of MyISAM. No need to delay
+invalidation to the transaction commit.
+
+2) To store or retrieve a value from the query cache of an InnoDB table TBL,
+any query must first ask InnoDB's permission. We must pass the thd as a
+parameter because InnoDB will look at the trx id, if any, associated with
+that thd.
+
+3) Use of the query cache for InnoDB tables is now allowed also when
+AUTOCOMMIT==0 or we are inside BEGIN ... COMMIT. Thus transactions no longer
+put restrictions on the use of the query cache.
+*/
+
+/**********************************************************************
+The MySQL query cache uses this to check from InnoDB if the query cache at
+the moment is allowed to operate on an InnoDB table. The SQL query must
+be a non-locking SELECT.
+
+The query cache is allowed to operate on certain query only if this function
+returns TRUE for all tables in the query.
+
+If thd is not in the autocommit state, this function also starts a new
+transaction for thd if there is no active trx yet, and assigns a consistent
+read view to it if there is no read view yet. */
+
+my_bool
+innobase_query_caching_of_table_permitted(
+/*======================================*/
+ /* out: TRUE if permitted, FALSE if not;
+ note that the value FALSE does not mean
+ we should invalidate the query cache:
+ invalidation is called explicitly */
+ THD* thd, /* in: thd of the user who is trying to
+ store a result to the query cache or
+ retrieve it */
+ char* full_name, /* in: concatenation of database name,
+ the null character '\0', and the table
+ name */
+ uint full_name_len) /* in: length of the full name, i.e.
+ len(dbname) + len(tablename) + 1 */
+{
+ ibool is_autocommit;
+ trx_t* trx;
+ char* ptr;
+ char norm_name[1000];
+
+ ut_a(full_name_len < 999);
+
+ if (thd->variables.tx_isolation == ISO_SERIALIZABLE) {
+ /* In the SERIALIZABLE mode we add LOCK IN SHARE MODE to every
+ plain SELECT */
+
+ return((my_bool)FALSE);
+ }
+
+ trx = (trx_t*) thd->transaction.all.innobase_tid;
+
+ if (trx == NULL) {
+ trx = check_trx_exists(thd);
+ }
+
+ innobase_release_stat_resources(trx);
+
+ if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
+
+ is_autocommit = TRUE;
+ } else {
+ is_autocommit = FALSE;
+
+ }
+
+ if (is_autocommit && trx->conc_state == TRX_NOT_STARTED) {
+ /* We are going to retrieve the query result from the
+ query cache. This cannot be a store operation because then
+ we would have started the trx already.
+
+ We can imagine we instantaneously serialize
+ this consistent read trx to the current trx id counter.
+ If trx2 would have changed the tables of a query
+ result stored in the cache, and trx2 would have already
+ committed, making the result obsolete, then trx2 would have
+ already invalidated the cache. Thus we can trust the result
+ in the cache is ok for this query. */
+
+ return((my_bool)TRUE);
+ }
+
+ /* Normalize the table name to InnoDB format */
+
+ memcpy(norm_name, full_name, full_name_len);
+
+ norm_name[strlen(norm_name)] = '/'; /* InnoDB uses '/' as the
+ separator between db and table */
+ norm_name[full_name_len] = '\0';
+#ifdef __WIN__
+ /* Put to lower case */
+
+ ptr = norm_name;
+
+ while (*ptr != '\0') {
+ *ptr = tolower(*ptr);
+ ptr++;
+ }
+#endif
+ if (row_search_check_if_query_cache_permitted(trx, norm_name)) {
+
+ printf("Query cache for %s permitted\n", norm_name);
+
+ return((my_bool)TRUE);
+ }
+
+ printf("Query cache for %s NOT permitted\n", norm_name);
+
+ return((my_bool)FALSE);
+}
+
+extern "C" {
+/*********************************************************************
+Invalidates the MySQL query cache for the table.
+NOTE that the exact prototype of this function has to be in
+/innobase/row/row0ins.c! */
+
+void
+innobase_invalidate_query_cache(
+/*============================*/
+ trx_t* trx, /* in: transaction which modifies the table */
+ char* full_name, /* in: concatenation of database name, null
+ char '\0', table name, null char'\0';
+ NOTE that in Windows this is always
+ in LOWER CASE! */
+ ulint full_name_len) /* in: full name length where also the null
+ chars count */
+{
+ /* Argument TRUE below means we are using transactions */
+#ifdef HAVE_QUERY_CACHE
+ query_cache.invalidate((THD*)(trx->mysql_thd),
+ (const char*)full_name,
+ (uint32)full_name_len,
+ TRUE);
+#endif
+}
+}
+
+/*********************************************************************
+Call this when you have opened a new table handle in HANDLER, before you
+call index_read_idx() etc. Actually, we can let the cursor stay open even
+over a transaction commit! Then you should call this before every operation,
+fetch next etc. This function inits the necessary things even after a
+transaction commit. */
+
+void
+ha_innobase::init_table_handle_for_HANDLER(void)
+/*============================================*/
+{
+ row_prebuilt_t* prebuilt;
+
+ /* If current thd does not yet have a trx struct, create one.
+ If the current handle does not yet have a prebuilt struct, create
+ one. Update the trx pointers in the prebuilt struct. Normally
+ this operation is done in external_lock. */
+
+ update_thd(current_thd);
+
+ /* Initialize the prebuilt struct much like it would be inited in
+ external_lock */
+
+ prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+
+ innobase_release_stat_resources(prebuilt->trx);
+
+ /* If the transaction is not started yet, start it */
+
+ trx_start_if_not_started_noninline(prebuilt->trx);
+
+ /* Assign a read view if the transaction does not have it yet */
+
+ trx_assign_read_view(prebuilt->trx);
+
+ /* We did the necessary inits in this function, no need to repeat them
+ in row_search_for_mysql */
+
+ prebuilt->sql_stat_start = FALSE;
+
+ /* We let HANDLER always to do the reads as consistent reads, even
+ if the trx isolation level would have been specified as SERIALIZABLE */
+
+ prebuilt->select_lock_type = LOCK_NONE;
+
+ /* Always fetch all columns in the index record */
+
+ prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
+
+ /* We want always to fetch all columns in the whole row? Or do
+ we???? */
+
+ prebuilt->read_just_key = FALSE;
+
+ prebuilt->used_in_HANDLER = TRUE;
+}
+
+/*************************************************************************
+Opens an InnoDB database. */
+
+bool
+innobase_init(void)
+/*===============*/
+ /* out: TRUE if error */
+{
+ static char current_dir[3]; // Set if using current lib
+ int err;
+ bool ret;
+ char *default_path;
+
+ DBUG_ENTER("innobase_init");
+
+ os_innodb_umask = (ulint)my_umask;
+
+ /* First calculate the default path for innodb_data_home_dir etc.,
+ in case the user has not given any value.
+
+ Note that when using the embedded server, the datadirectory is not
+ necessarily the current directory of this program. */
+
+ if (mysql_embedded) {
+ default_path = mysql_real_data_home;
+ } else {
+ /* It's better to use current lib, to keep paths short */
+ current_dir[0] = FN_CURLIB;
+ current_dir[1] = FN_LIBCHAR;
+ current_dir[2] = 0;
+ default_path = current_dir;
+ }
+
+ ut_a(default_path);
+
+ if (specialflag & SPECIAL_NO_PRIOR) {
+ srv_set_thread_priorities = FALSE;
+ } else {
+ srv_set_thread_priorities = TRUE;
+ srv_query_thread_priority = QUERY_PRIOR;
+ }
+
+ /* Set InnoDB initialization parameters according to the values
+ read from MySQL .cnf file */
+
+ /*--------------- Data files -------------------------*/
+
+ /* The default dir for data files is the datadir of MySQL */
+
+ srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
+ default_path);
+
+ /* Set default InnoDB data file size to 10 MB and let it be
+ auto-extending. Thus users can use InnoDB in >= 4.0 without having
+ to specify any startup options. */
+
+ if (!innobase_data_file_path) {
+ innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
+ }
+
+ /* Since InnoDB edits the argument in the next call, we make another
+ copy of it: */
+
+ internal_innobase_data_file_path = my_strdup(innobase_data_file_path,
+ MYF(MY_WME));
+
+ ret = (bool) srv_parse_data_file_paths_and_sizes(
+ internal_innobase_data_file_path,
+ &srv_data_file_names,
+ &srv_data_file_sizes,
+ &srv_data_file_is_raw_partition,
+ &srv_n_data_files,
+ &srv_auto_extend_last_data_file,
+ &srv_last_file_size_max);
+ if (ret == FALSE) {
+ sql_print_error(
+ "InnoDB: syntax error in innodb_data_file_path");
+ DBUG_RETURN(TRUE);
+ }
+
+ /* -------------- Log files ---------------------------*/
+
+ /* The default dir for log files is the datadir of MySQL */
+
+ if (!innobase_log_group_home_dir) {
+ innobase_log_group_home_dir = default_path;
+ }
+
+ /* Since innodb_log_arch_dir has no relevance under MySQL,
+ starting from 4.0.6 we always set it the same as
+ innodb_log_group_home_dir: */
+
+ innobase_log_arch_dir = innobase_log_group_home_dir;
+
+ srv_arch_dir = innobase_log_arch_dir;
+
+ ret = (bool)
+ srv_parse_log_group_home_dirs(innobase_log_group_home_dir,
+ &srv_log_group_home_dirs);
+
+ if (ret == FALSE || innobase_mirrored_log_groups != 1) {
+ fprintf(stderr,
+ "InnoDB: syntax error in innodb_log_group_home_dir\n"
+ "InnoDB: or a wrong number of mirrored log groups\n");
+
+ DBUG_RETURN(TRUE);
+ }
+
+ /* --------------------------------------------------*/
+
+ srv_file_flush_method_str = innobase_unix_file_flush_method;
+
+ srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
+ srv_n_log_files = (ulint) innobase_log_files_in_group;
+ srv_log_file_size = (ulint) innobase_log_file_size;
+
+ srv_log_archive_on = (ulint) innobase_log_archive;
+ srv_log_buffer_size = (ulint) innobase_log_buffer_size;
+ srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit;
+
+ srv_pool_size = (ulint) innobase_buffer_pool_size;
+
+ srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
+
+ srv_n_file_io_threads = (ulint) innobase_file_io_threads;
+
+ srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
+ srv_thread_concurrency = (ulint) innobase_thread_concurrency;
+ srv_force_recovery = (ulint) innobase_force_recovery;
+
+ srv_fast_shutdown = (ibool) innobase_fast_shutdown;
+
+ srv_print_verbose_log = mysql_embedded ? 0 : 1;
+
+ if (strcmp(default_charset_info->name, "latin1") == 0) {
+
+ /* Store the character ordering table to InnoDB.
+ For non-latin1 charsets we use the MySQL comparison
+ functions, and consequently we do not need to know
+ the ordering internally in InnoDB. */
+
+ memcpy(srv_latin1_ordering,
+ default_charset_info->sort_order, 256);
+ }
+
+ /* Since we in this module access directly the fields of a trx
+ struct, and due to different headers and flags it might happen that
+ mutex_t has a different size in this module and in InnoDB
+ modules, we check at run time that the size is the same in
+ these compilation modules. */
+
+ srv_sizeof_trx_t_in_ha_innodb_cc = sizeof(trx_t);
+
+ err = innobase_start_or_create_for_mysql();
+
+ if (err != DB_SUCCESS) {
+
+ DBUG_RETURN(1);
+ }
+
+ (void) hash_init(&innobase_open_tables,32,0,0,
+ (hash_get_key) innobase_get_key,0,0);
+ pthread_mutex_init(&innobase_mutex,MY_MUTEX_INIT_FAST);
+
+ /* If this is a replication slave and we needed to do a crash recovery,
+ set the master binlog position to what InnoDB internally knew about
+ how far we got transactions durable inside InnoDB. There is a
+ problem here: if the user used also MyISAM tables, InnoDB might not
+ know the right position for them.
+
+ THIS DOES NOT WORK CURRENTLY because replication seems to initialize
+ glob_mi also after innobase_init. */
+
+/* if (trx_sys_mysql_master_log_pos != -1) {
+ ut_memcpy(glob_mi.log_file_name, trx_sys_mysql_master_log_name,
+ 1 + ut_strlen(trx_sys_mysql_master_log_name));
+ glob_mi.pos = trx_sys_mysql_master_log_pos;
+ }
+*/
+ DBUG_RETURN(0);
+}
+
+/***********************************************************************
+Closes an InnoDB database. */
+
+bool
+innobase_end(void)
+/*==============*/
+ /* out: TRUE if error */
+{
+ int err;
+
+ DBUG_ENTER("innobase_end");
+
+ err = innobase_shutdown_for_mysql();
+ hash_free(&innobase_open_tables);
+ my_free(internal_innobase_data_file_path,MYF(MY_ALLOW_ZERO_PTR));
+ pthread_mutex_destroy(&innobase_mutex);
+
+ if (err != DB_SUCCESS) {
+
+ DBUG_RETURN(1);
+ }
+
+ DBUG_RETURN(0);
+}
+
+/********************************************************************
+Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit
+flushes logs, and the name of this function should be innobase_checkpoint. */
+
+bool
+innobase_flush_logs(void)
+/*=====================*/
+ /* out: TRUE if error */
+{
+ bool result = 0;
+
+ DBUG_ENTER("innobase_flush_logs");
+
+ log_buffer_flush_to_disk();
+
+ DBUG_RETURN(result);
+}
+
+/*************************************************************************
+Gets the free space in an InnoDB database: returned in units of kB. */
+
+uint
+innobase_get_free_space(void)
+/*=========================*/
+ /* out: free space in kB */
+{
+ return((uint) fsp_get_available_space_in_free_extents(0));
+}
+
+/*********************************************************************
+Commits a transaction in an InnoDB database. */
+
+void
+innobase_commit_low(
+/*================*/
+ trx_t* trx) /* in: transaction handle */
+{
+ if (trx->conc_state == TRX_NOT_STARTED) {
+
+ return;
+ }
+
+ /* TODO: Guilhem should check if master_log_name, pending
+ etc. are right if the master log gets rotated! Possible bug here.
+ Comment by Heikki March 4, 2003. */
+
+ if (current_thd->slave_thread) {
+ /* Update the replication position info inside InnoDB */
+
+ trx->mysql_master_log_file_name
+ = active_mi->rli.master_log_name;
+ trx->mysql_master_log_pos = ((ib_longlong)
+ (active_mi->rli.master_log_pos +
+ active_mi->rli.event_len +
+ active_mi->rli.pending));
+ }
+
+ trx_commit_for_mysql(trx);
+}
+
+/*********************************************************************
+Commits a transaction in an InnoDB database or marks an SQL statement
+ended. */
+
+int
+innobase_commit(
+/*============*/
+ /* out: 0 */
+ THD* thd, /* in: MySQL thread handle of the user for whom
+ the transaction should be committed */
+ void* trx_handle)/* in: InnoDB trx handle or
+ &innodb_dummy_stmt_trx_handle: the latter means
+ that the current SQL statement ended, and we should
+ mark the start of a new statement with a savepoint */
+{
+ trx_t* trx;
+
+ DBUG_ENTER("innobase_commit");
+ DBUG_PRINT("trans", ("ending transaction"));
+
+ trx = check_trx_exists(thd);
+
+ /* Release a possible FIFO ticket and search latch. Since we will
+ reserve the kernel mutex, we have to release the search system latch
+ first to obey the latching order. */
+
+ innobase_release_stat_resources(trx);
+
+ /* The flag thd->transaction.all.innodb_active_trans is set to 1 in
+ ::external_lock, ::start_stmt, and innobase_savepoint, and it is only
+ set to 0 in a commit or a rollback. If it is 0 we know there cannot be
+ resources to be freed and we could return immediately. For the time
+ being we play safe and do the cleanup though there should be nothing
+ to clean up. */
+
+ if (thd->transaction.all.innodb_active_trans == 0
+ && trx->conc_state != TRX_NOT_STARTED) {
+
+ fprintf(stderr,
+"InnoDB: Error: thd->transaction.all.innodb_active_trans == 0\n"
+"InnoDB: but trx->conc_state != TRX_NOT_STARTED\n");
+ }
+
+ if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle
+ || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
+
+ innobase_commit_low(trx);
+
+ thd->transaction.all.innodb_active_trans = 0;
+ } else {
+ if (trx->auto_inc_lock) {
+ /* If we had reserved the auto-inc lock for some
+ table in this SQL statement we release it now */
+
+ row_unlock_table_autoinc_for_mysql(trx);
+ }
+ /* Store the current undo_no of the transaction so that we
+ know where to roll back if we have to roll back the next
+ SQL statement */
+
+ trx_mark_sql_stat_end(trx);
+ }
+
+ /* Tell the InnoDB server that there might be work for utility
+ threads: */
+
+ srv_active_wake_master_thread();
+
+ DBUG_RETURN(0);
+}
+
+/*********************************************************************
+This is called when MySQL writes the binlog entry for the current
+transaction. Writes to the InnoDB tablespace info which tells where the
+MySQL binlog entry for the current transaction ended. Also commits the
+transaction inside InnoDB but does NOT flush InnoDB log files to disk.
+To flush you have to call innobase_flush_log_to_disk. We have separated
+flushing to eliminate the bottleneck of LOCK_log in log.cc which disabled
+InnoDB's group commit capability. */
+
+int
+innobase_report_binlog_offset_and_commit(
+/*=====================================*/
+ /* out: 0 */
+ THD* thd, /* in: user thread */
+ void* trx_handle, /* in: InnoDB trx handle */
+ char* log_file_name, /* in: latest binlog file name */
+ my_off_t end_offset) /* in: the offset in the binlog file
+ up to which we wrote */
+{
+ trx_t* trx;
+
+ trx = (trx_t*)trx_handle;
+
+ ut_a(trx != NULL);
+
+ trx->mysql_log_file_name = log_file_name;
+ trx->mysql_log_offset = (ib_longlong)end_offset;
+
+ trx->flush_log_later = TRUE;
+
+ innobase_commit(thd, trx_handle);
+
+ trx->flush_log_later = FALSE;
+
+ return(0);
+}
+
+/*********************************************************************
+This is called after MySQL has written the binlog entry for the current
+transaction. Flushes the InnoDB log files to disk if required. */
+
+int
+innobase_commit_complete(
+/*=====================*/
+ /* out: 0 */
+ void* trx_handle) /* in: InnoDB trx handle */
+{
+ trx_t* trx;
+
+ if (srv_flush_log_at_trx_commit == 0) {
+
+ return(0);
+ }
+
+ trx = (trx_t*)trx_handle;
+
+ ut_a(trx != NULL);
+
+ trx_commit_complete_for_mysql(trx);
+
+ return(0);
+}
+
+/*********************************************************************
+Rolls back a transaction or the latest SQL statement. */
+
+int
+innobase_rollback(
+/*==============*/
+ /* out: 0 or error number */
+ THD* thd, /* in: handle to the MySQL thread of the user
+ whose transaction should be rolled back */
+ void* trx_handle)/* in: InnoDB trx handle or a dummy stmt handle;
+ the latter means we roll back the latest SQL
+ statement */
+{
+ int error = 0;
+ trx_t* trx;
+
+ DBUG_ENTER("innobase_rollback");
+ DBUG_PRINT("trans", ("aborting transaction"));
+
+ trx = check_trx_exists(thd);
+
+ /* Release a possible FIFO ticket and search latch. Since we will
+ reserve the kernel mutex, we have to release the search system latch
+ first to obey the latching order. */
+
+ innobase_release_stat_resources(trx);
+
+ if (trx->auto_inc_lock) {
+ /* If we had reserved the auto-inc lock for some table (if
+ we come here to roll back the latest SQL statement) we
+ release it now before a possibly lengthy rollback */
+
+ row_unlock_table_autoinc_for_mysql(trx);
+ }
+
+ if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle
+ || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
+
+ error = trx_rollback_for_mysql(trx);
+ thd->transaction.all.innodb_active_trans = 0;
+ } else {
+ error = trx_rollback_last_sql_stat_for_mysql(trx);
+ }
+
+ DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
+}
+
+/*********************************************************************
+Rolls back a transaction to a savepoint. */
+
+int
+innobase_rollback_to_savepoint(
+/*===========================*/
+ /* out: 0 if success, HA_ERR_NO_SAVEPOINT if
+ no savepoint with the given name */
+ THD* thd, /* in: handle to the MySQL thread of the user
+ whose transaction should be rolled back */
+ char* savepoint_name, /* in: savepoint name */
+ my_off_t* binlog_cache_pos)/* out: position which corresponds to the
+ savepoint in the binlog cache of this
+ transaction, not defined if error */
+{
+ ib_longlong mysql_binlog_cache_pos;
+ int error = 0;
+ trx_t* trx;
+
+ DBUG_ENTER("innobase_rollback_to_savepoint");
+
+ trx = check_trx_exists(thd);
+
+ /* Release a possible FIFO ticket and search latch. Since we will
+ reserve the kernel mutex, we have to release the search system latch
+ first to obey the latching order. */
+
+ innobase_release_stat_resources(trx);
+
+ error = trx_rollback_to_savepoint_for_mysql(trx, savepoint_name,
+ &mysql_binlog_cache_pos);
+
+ *binlog_cache_pos = (my_off_t)mysql_binlog_cache_pos;
+
+ DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
+}
+
+/*********************************************************************
+Sets a transaction savepoint. */
+
+int
+innobase_savepoint(
+/*===============*/
+ /* out: always 0, that is, always succeeds */
+ THD* thd, /* in: handle to the MySQL thread */
+ char* savepoint_name, /* in: savepoint name */
+ my_off_t binlog_cache_pos)/* in: offset up to which the current
+ transaction has cached log entries to its
+ binlog cache, not defined if no transaction
+ active, or we are in the autocommit state, or
+ binlogging is not switched on */
+{
+ int error = 0;
+ trx_t* trx;
+
+ DBUG_ENTER("innobase_savepoint");
+
+ if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
+ /* In the autocommit state there is no sense to set a
+ savepoint: we return immediate success */
+ DBUG_RETURN(0);
+ }
+
+ trx = check_trx_exists(thd);
+
+ /* Release a possible FIFO ticket and search latch. Since we will
+ reserve the kernel mutex, we have to release the search system latch
+ first to obey the latching order. */
+
+ innobase_release_stat_resources(trx);
+
+ /* Setting a savepoint starts a transaction inside InnoDB since
+ it allocates resources for it (memory to store the savepoint name,
+ for example) */
+
+ thd->transaction.all.innodb_active_trans = 1;
+
+ error = trx_savepoint_for_mysql(trx, savepoint_name,
+ (ib_longlong)binlog_cache_pos);
+
+ DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
+}
+
+/*********************************************************************
+Frees a possible InnoDB trx object associated with the current THD. */
+
+int
+innobase_close_connection(
+/*======================*/
+ /* out: 0 or error number */
+ THD* thd) /* in: handle to the MySQL thread of the user
+ whose transaction should be rolled back */
+{
+ trx_t* trx;
+
+ trx = (trx_t*)thd->transaction.all.innobase_tid;
+
+ if (NULL != trx) {
+ innobase_rollback(thd, (void*)trx);
+
+ trx_free_for_mysql(trx);
+
+ thd->transaction.all.innobase_tid = NULL;
+ }
+
+ return(0);
+}
+
+/**********************************************************************
+Prints an error message. */
+static
+void
+innobase_print_error(
+/*=================*/
+ const char* db_errpfx, /* in: error prefix text */
+ char* buffer) /* in: error text */
+{
+ sql_print_error("%s: %s", db_errpfx, buffer);
+}
+
+
+/*****************************************************************************
+** InnoDB database tables
+*****************************************************************************/
+
+/********************************************************************
+This function is not relevant since we store the tables and indexes
+into our own tablespace, not as files, whose extension this function would
+give. */
+
+const char**
+ha_innobase::bas_ext() const
+/*========================*/
+ /* out: file extension strings, currently not
+ used */
+{
+ static const char* ext[] = {".InnoDB", NullS};
+
+ return(ext);
+}
+
+/*********************************************************************
+Normalizes a table name string. A normalized name consists of the
+database name catenated to '/' and table name. An example:
+test/mytable. On Windows normalization puts both the database name and the
+table name always to lower case. */
+static
+void
+normalize_table_name(
+/*=================*/
+ char* norm_name, /* out: normalized name as a
+ null-terminated string */
+ const char* name) /* in: table name string */
+{
+ char* name_ptr;
+ char* db_ptr;
+ char* ptr;
+
+ /* Scan name from the end */
+
+ ptr = strend(name)-1;
+
+ while (ptr >= name && *ptr != '\\' && *ptr != '/') {
+ ptr--;
+ }
+
+ name_ptr = ptr + 1;
+
+ DBUG_ASSERT(ptr > name);
+
+ ptr--;
+
+ while (ptr >= name && *ptr != '\\' && *ptr != '/') {
+ ptr--;
+ }
+
+ db_ptr = ptr + 1;
+
+ memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
+
+ norm_name[name_ptr - db_ptr - 1] = '/';
+
+#ifdef __WIN__
+ /* Put to lower case */
+
+ ptr = norm_name;
+
+ while (*ptr != '\0') {
+ *ptr = tolower(*ptr);
+ ptr++;
+ }
+#endif
+}
+
+/*********************************************************************
+Creates and opens a handle to a table which already exists in an InnoDB
+database. */
+
+int
+ha_innobase::open(
+/*==============*/
+ /* out: 1 if error, 0 if success */
+ const char* name, /* in: table name */
+ int mode, /* in: not used */
+ uint test_if_locked) /* in: not used */
+{
+ dict_table_t* ib_table;
+ int error = 0;
+ char norm_name[1000];
+
+ DBUG_ENTER("ha_innobase::open");
+
+ UT_NOT_USED(mode);
+ UT_NOT_USED(test_if_locked);
+
+ normalize_table_name(norm_name, name);
+
+ user_thd = NULL;
+
+ last_query_id = (ulong)-1;
+
+ active_index = 0;
+ active_index_before_scan = (uint)-1; /* undefined value */
+
+ if (!(share=get_share(name)))
+ DBUG_RETURN(1);
+
+ /* Create buffers for packing the fields of a record. Why
+ table->reclength did not work here? Obviously, because char
+ fields when packed actually became 1 byte longer, when we also
+ stored the string length as the first byte. */
+
+ upd_and_key_val_buff_len = table->reclength + table->max_key_length
+ + MAX_REF_PARTS * 3;
+ if (!(mysql_byte*) my_multi_malloc(MYF(MY_WME),
+ &upd_buff, upd_and_key_val_buff_len,
+ &key_val_buff, upd_and_key_val_buff_len,
+ NullS)) {
+ free_share(share);
+ DBUG_RETURN(1);
+ }
+
+ /* Get pointer to a table object in InnoDB dictionary cache */
+
+ ib_table = dict_table_get_and_increment_handle_count(
+ norm_name, NULL);
+ if (NULL == ib_table) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB error:\n"
+"Cannot find table %s from the internal data dictionary\n"
+"of InnoDB though the .frm file for the table exists. Maybe you\n"
+"have deleted and recreated InnoDB data files but have forgotten\n"
+"to delete the corresponding .frm files of InnoDB tables, or you\n"
+"have moved .frm files to another database?\n"
+"Look from section 15.1 of http://www.innodb.com/ibman.html\n"
+"how you can resolve the problem.\n",
+ norm_name);
+
+ free_share(share);
+ my_free((char*) upd_buff, MYF(0));
+ my_errno = ENOENT;
+ DBUG_RETURN(1);
+ }
+
+ innobase_prebuilt = row_create_prebuilt(ib_table);
+
+ ((row_prebuilt_t*)innobase_prebuilt)->mysql_row_len = table->reclength;
+
+ /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
+
+ primary_key = table->primary_key;
+ key_used_on_scan = primary_key;
+
+ /* Allocate a buffer for a 'row reference'. A row reference is
+ a string of bytes of length ref_length which uniquely specifies
+ a row in our table. Note that MySQL may also compare two row
+ references for equality by doing a simple memcmp on the strings
+ of length ref_length! */
+
+ if (!row_table_got_default_clust_index(ib_table)) {
+ if (primary_key >= MAX_KEY) {
+ fprintf(stderr,
+ "InnoDB: Error: table %s has a primary key in InnoDB\n"
+ "InnoDB: data dictionary, but not in MySQL!\n", name);
+ }
+
+ ((row_prebuilt_t*)innobase_prebuilt)
+ ->clust_index_was_generated = FALSE;
+ /*
+ MySQL allocates the buffer for ref. key_info->key_length
+ includes space for all key columns + one byte for each column
+ that may be NULL. ref_length must be as exact as possible to
+ save space, because all row reference buffers are allocated
+ based on ref_length.
+ */
+
+ ref_length = table->key_info[primary_key].key_length;
+ } else {
+ if (primary_key != MAX_KEY) {
+ fprintf(stderr,
+ "InnoDB: Error: table %s has no primary key in InnoDB\n"
+ "InnoDB: data dictionary, but has one in MySQL!\n"
+ "InnoDB: If you created the table with a MySQL\n"
+ "InnoDB: version < 3.23.54 and did not define a primary\n"
+ "InnoDB: key, but defined a unique key with all non-NULL\n"
+ "InnoDB: columns, then MySQL internally treats that key\n"
+ "InnoDB: as the primary key. You can fix this error by\n"
+ "InnoDB: dump + DROP + CREATE + reimport of the table.\n",
+ name);
+ }
+
+ ((row_prebuilt_t*)innobase_prebuilt)
+ ->clust_index_was_generated = TRUE;
+
+ ref_length = DATA_ROW_ID_LEN;
+
+ /*
+ If we automatically created the clustered index, then
+ MySQL does not know about it, and MySQL must NOT be aware
+ of the index used on scan, to make it avoid checking if we
+ update the column of the index. That is why we assert below
+ that key_used_on_scan is the undefined value MAX_KEY.
+ The column is the row id in the automatical generation case,
+ and it will never be updated anyway.
+ */
+
+ if (key_used_on_scan != MAX_KEY) {
+ fprintf(stderr,
+"InnoDB: Warning: table %s key_used_on_scan is %lu even though there is no\n"
+"InnoDB: primary key inside InnoDB.\n",
+ name, (ulint)key_used_on_scan);
+ }
+ }
+
+ auto_inc_counter_for_this_stat = 0;
+
+ block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL
+ in query optimization */
+
+ /* Init table lock structure */
+ thr_lock_data_init(&share->lock,&lock,(void*) 0);
+
+ info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
+
+ DBUG_RETURN(0);
+}
+
+/*********************************************************************
+Does nothing. */
+
+void
+ha_innobase::initialize(void)
+/*=========================*/
+{
+}
+
+/**********************************************************************
+Closes a handle to an InnoDB table. */
+
+int
+ha_innobase::close(void)
+/*====================*/
+ /* out: error number */
+{
+ DBUG_ENTER("ha_innobase::close");
+
+ row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt);
+
+ my_free((char*) upd_buff, MYF(0));
+ free_share(share);
+
+ /* Tell InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ DBUG_RETURN(0);
+}
+
+/* The following accessor functions should really be inside MySQL code! */
+
+/******************************************************************
+Gets field offset for a field in a table. */
+inline
+uint
+get_field_offset(
+/*=============*/
+ /* out: offset */
+ TABLE* table, /* in: MySQL table object */
+ Field* field) /* in: MySQL field object */
+{
+ return((uint) (field->ptr - (char*) table->record[0]));
+}
+
+/******************************************************************
+Checks if a field in a record is SQL NULL. Uses the record format
+information in table to track the null bit in record. */
+inline
+uint
+field_in_record_is_null(
+/*====================*/
+ /* out: 1 if NULL, 0 otherwise */
+ TABLE* table, /* in: MySQL table object */
+ Field* field, /* in: MySQL field object */
+ char* record) /* in: a row in MySQL format */
+{
+ int null_offset;
+
+ if (!field->null_ptr) {
+
+ return(0);
+ }
+
+ null_offset = (uint) ((char*) field->null_ptr
+ - (char*) table->record[0]);
+
+ if (record[null_offset] & field->null_bit) {
+
+ return(1);
+ }
+
+ return(0);
+}
+
+/******************************************************************
+Sets a field in a record to SQL NULL. Uses the record format
+information in table to track the null bit in record. */
+inline
+void
+set_field_in_record_to_null(
+/*========================*/
+ TABLE* table, /* in: MySQL table object */
+ Field* field, /* in: MySQL field object */
+ char* record) /* in: a row in MySQL format */
+{
+ int null_offset;
+
+ null_offset = (uint) ((char*) field->null_ptr
+ - (char*) table->record[0]);
+
+ record[null_offset] = record[null_offset] | field->null_bit;
+}
+
+/******************************************************************
+Resets SQL NULL bits in a record to zero. */
+inline
+void
+reset_null_bits(
+/*============*/
+ TABLE* table, /* in: MySQL table object */
+ char* record) /* in: a row in MySQL format */
+{
+ bzero(record, table->null_bytes);
+}
+
+extern "C" {
+/*****************************************************************
+InnoDB uses this function is to compare two data fields for which the
+data type is such that we must use MySQL code to compare them. NOTE that the
+prototype of this function is in rem0cmp.c in InnoDB source code!
+If you change this function, remember to update the prototype there! */
+
+int
+innobase_mysql_cmp(
+/*===============*/
+ /* out: 1, 0, -1, if a is greater,
+ equal, less than b, respectively */
+ int mysql_type, /* in: MySQL type */
+ unsigned char* a, /* in: data field */
+ unsigned int a_length, /* in: data field length,
+ not UNIV_SQL_NULL */
+ unsigned char* b, /* in: data field */
+ unsigned int b_length) /* in: data field length,
+ not UNIV_SQL_NULL */
+{
+ enum_field_types mysql_tp;
+ int ret;
+
+ DBUG_ASSERT(a_length != UNIV_SQL_NULL);
+ DBUG_ASSERT(b_length != UNIV_SQL_NULL);
+
+ mysql_tp = (enum_field_types) mysql_type;
+
+ switch (mysql_tp) {
+
+ case FIELD_TYPE_STRING:
+ case FIELD_TYPE_VAR_STRING:
+ case FIELD_TYPE_TINY_BLOB:
+ case FIELD_TYPE_MEDIUM_BLOB:
+ case FIELD_TYPE_BLOB:
+ case FIELD_TYPE_LONG_BLOB:
+ ret = my_sortncmp((const char*) a, a_length,
+ (const char*) b, b_length);
+ if (ret < 0) {
+ return(-1);
+ } else if (ret > 0) {
+ return(1);
+ } else {
+ return(0);
+ }
+ default:
+ assert(0);
+ }
+
+ return(0);
+}
+}
+
+/******************************************************************
+Converts a MySQL type to an InnoDB type. */
+inline
+ulint
+get_innobase_type_from_mysql_type(
+/*==============================*/
+ /* out: DATA_BINARY, DATA_VARCHAR, ... */
+ Field* field) /* in: MySQL field */
+{
+ /* The following asserts check that the MySQL type code fits in
+ 8 bits: this is used in ibuf and also when DATA_NOT_NULL is
+ ORed to the type */
+
+ DBUG_ASSERT((ulint)FIELD_TYPE_STRING < 256);
+ DBUG_ASSERT((ulint)FIELD_TYPE_VAR_STRING < 256);
+ DBUG_ASSERT((ulint)FIELD_TYPE_DOUBLE < 256);
+ DBUG_ASSERT((ulint)FIELD_TYPE_FLOAT < 256);
+ DBUG_ASSERT((ulint)FIELD_TYPE_DECIMAL < 256);
+
+ switch (field->type()) {
+ /* NOTE that we only allow string types in DATA_MYSQL
+ and DATA_VARMYSQL */
+ case FIELD_TYPE_VAR_STRING: if (field->flags & BINARY_FLAG) {
+
+ return(DATA_BINARY);
+ } else if (strcmp(
+ default_charset_info->name,
+ "latin1") == 0) {
+ return(DATA_VARCHAR);
+ } else {
+ return(DATA_VARMYSQL);
+ }
+ case FIELD_TYPE_STRING: if (field->flags & BINARY_FLAG) {
+
+ return(DATA_FIXBINARY);
+ } else if (strcmp(
+ default_charset_info->name,
+ "latin1") == 0) {
+ return(DATA_CHAR);
+ } else {
+ return(DATA_MYSQL);
+ }
+ case FIELD_TYPE_LONG:
+ case FIELD_TYPE_LONGLONG:
+ case FIELD_TYPE_TINY:
+ case FIELD_TYPE_SHORT:
+ case FIELD_TYPE_INT24:
+ case FIELD_TYPE_DATE:
+ case FIELD_TYPE_DATETIME:
+ case FIELD_TYPE_YEAR:
+ case FIELD_TYPE_NEWDATE:
+ case FIELD_TYPE_ENUM:
+ case FIELD_TYPE_SET:
+ case FIELD_TYPE_TIME:
+ case FIELD_TYPE_TIMESTAMP:
+ return(DATA_INT);
+ case FIELD_TYPE_FLOAT:
+ return(DATA_FLOAT);
+ case FIELD_TYPE_DOUBLE:
+ return(DATA_DOUBLE);
+ case FIELD_TYPE_DECIMAL:
+ return(DATA_DECIMAL);
+ case FIELD_TYPE_TINY_BLOB:
+ case FIELD_TYPE_MEDIUM_BLOB:
+ case FIELD_TYPE_BLOB:
+ case FIELD_TYPE_LONG_BLOB:
+ return(DATA_BLOB);
+ default:
+ assert(0);
+ }
+
+ return(0);
+}
+
+/***********************************************************************
+Stores a key value for a row to a buffer. */
+
+uint
+ha_innobase::store_key_val_for_row(
+/*===============================*/
+ /* out: key value length as stored in buff */
+ uint keynr, /* in: key number */
+ char* buff, /* in/out: buffer for the key value (in MySQL
+ format) */
+ uint buff_len,/* in: buffer length */
+ const mysql_byte* record)/* in: row in MySQL format */
+{
+ KEY* key_info = table->key_info + keynr;
+ KEY_PART_INFO* key_part = key_info->key_part;
+ KEY_PART_INFO* end = key_part + key_info->key_parts;
+ char* buff_start = buff;
+ enum_field_types mysql_type;
+ Field* field;
+ ulint blob_len;
+ byte* blob_data;
+ ibool is_null;
+
+ DBUG_ENTER("store_key_val_for_row");
+
+ /* The format for storing a key field in MySQL is the following:
+
+ 1. If the column can be NULL, then in the first byte we put 1 if the
+ field value is NULL, 0 otherwise.
+
+ 2. If the column is of a BLOB type (it must be a column prefix field
+ in this case), then we put the length of the data in the field to the
+ next 2 bytes, in the little-endian format. If the field is SQL NULL,
+ then these 2 bytes are set to 0. Note that the length of data in the
+ field is <= column prefix length.
+
+ 3. In a column prefix field, prefix_len next bytes are reserved for
+ data. In a normal field the max field length next bytes are reserved
+ for data. For a VARCHAR(n) the max field length is n. If the stored
+ value is the SQL NULL then these data bytes are set to 0. */
+
+ /* We have to zero-fill the buffer so that MySQL is able to use a
+ simple memcmp to compare two key values to determine if they are
+ equal. MySQL does this to compare contents of two 'ref' values. */
+
+ bzero(buff, buff_len);
+
+ for (; key_part != end; key_part++) {
+ is_null = FALSE;
+
+ if (key_part->null_bit) {
+ if (record[key_part->null_offset]
+ & key_part->null_bit) {
+ *buff = 1;
+ is_null = TRUE;
+ } else {
+ *buff = 0;
+ }
+ buff++;
+ }
+
+ field = key_part->field;
+ mysql_type = field->type();
+
+ if (mysql_type == FIELD_TYPE_TINY_BLOB
+ || mysql_type == FIELD_TYPE_MEDIUM_BLOB
+ || mysql_type == FIELD_TYPE_BLOB
+ || mysql_type == FIELD_TYPE_LONG_BLOB) {
+
+ ut_a(key_part->key_part_flag & HA_PART_KEY_SEG);
+
+ if (is_null) {
+ buff += key_part->length + 2;
+
+ continue;
+ }
+
+ blob_data = row_mysql_read_blob_ref(&blob_len,
+ (byte*) (record
+ + (ulint)get_field_offset(table, field)),
+ (ulint) field->pack_length());
+
+ ut_a(get_field_offset(table, field)
+ == key_part->offset);
+ if (blob_len > key_part->length) {
+ blob_len = key_part->length;
+ }
+
+ /* MySQL reserves 2 bytes for the length and the
+ storage of the number is little-endian */
+
+ ut_a(blob_len < 256);
+ *((byte*)buff) = (byte)blob_len;
+ buff += 2;
+
+ memcpy(buff, blob_data, blob_len);
+
+ buff += key_part->length;
+ } else {
+ if (is_null) {
+ buff += key_part->length;
+
+ continue;
+ }
+ memcpy(buff, record + key_part->offset,
+ key_part->length);
+ buff += key_part->length;
+ }
+ }
+
+ ut_a(buff <= buff_start + buff_len);
+
+ DBUG_RETURN((uint)(buff - buff_start));
+}
+
+/******************************************************************
+Builds a template to the prebuilt struct. */
+static
+void
+build_template(
+/*===========*/
+ row_prebuilt_t* prebuilt, /* in: prebuilt struct */
+ THD* thd, /* in: current user thread, used
+ only if templ_type is
+ ROW_MYSQL_REC_FIELDS */
+ TABLE* table, /* in: MySQL table */
+ ulint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
+ ROW_MYSQL_REC_FIELDS */
+{
+ dict_index_t* index;
+ dict_index_t* clust_index;
+ mysql_row_templ_t* templ;
+ Field* field;
+ ulint n_fields;
+ ulint n_requested_fields = 0;
+ ibool fetch_all_in_key = FALSE;
+ ulint i;
+
+ clust_index = dict_table_get_first_index_noninline(prebuilt->table);
+
+ if (!prebuilt->hint_no_need_to_fetch_extra_cols) {
+ /* We have a hint that we should at least fetch all
+ columns in the key, or all columns in the table */
+
+ if (prebuilt->read_just_key) {
+ /* MySQL has instructed us that it is enough to
+ fetch the columns in the key; looks like MySQL
+ can set this flag also when there is only a
+ prefix of the column in the key: in that case we
+ retrieve the whole column from the clustered
+ index */
+
+ fetch_all_in_key = TRUE;
+ } else {
+ /* We are building a temporary table: fetch all
+ columns; the reason is that MySQL may use the
+ clustered index key to store rows, but the mechanism
+ we use below to detect required columns does not
+ reveal that. Actually, it might be enough to
+ fetch only all in the key also in this case! */
+
+ templ_type = ROW_MYSQL_WHOLE_ROW;
+ }
+ }
+
+ if (prebuilt->select_lock_type == LOCK_X) {
+ /* We always retrieve the whole clustered index record if we
+ use exclusive row level locks, for example, if the read is
+ done in an UPDATE statement. */
+
+ templ_type = ROW_MYSQL_WHOLE_ROW;
+ }
+
+ if (templ_type == ROW_MYSQL_REC_FIELDS) {
+ /* In versions < 3.23.50 we always retrieved the clustered
+ index record if prebuilt->select_lock_type == LOCK_S,
+ but there is really not need for that, and in some cases
+ performance could be seriously degraded because the MySQL
+ optimizer did not know about our convention! */
+
+ index = prebuilt->index;
+ } else {
+ index = clust_index;
+ }
+
+ if (index == clust_index) {
+ prebuilt->need_to_access_clustered = TRUE;
+ } else {
+ prebuilt->need_to_access_clustered = FALSE;
+ /* Below we check column by column if we need to access
+ the clustered index */
+ }
+
+ n_fields = (ulint)table->fields;
+
+ if (!prebuilt->mysql_template) {
+ prebuilt->mysql_template = (mysql_row_templ_t*)
+ mem_alloc_noninline(
+ n_fields * sizeof(mysql_row_templ_t));
+ }
+
+ prebuilt->template_type = templ_type;
+ prebuilt->null_bitmap_len = table->null_bytes;
+
+ prebuilt->templ_contains_blob = FALSE;
+
+ for (i = 0; i < n_fields; i++) {
+ templ = prebuilt->mysql_template + n_requested_fields;
+ field = table->field[i];
+
+ if (templ_type == ROW_MYSQL_REC_FIELDS
+ && !(fetch_all_in_key
+ && dict_index_contains_col_or_prefix(index, i))
+ && thd->query_id != field->query_id
+ && thd->query_id != (field->query_id ^ MAX_ULONG_BIT)
+ && thd->query_id !=
+ (field->query_id ^ (MAX_ULONG_BIT >> 1))) {
+
+ /* This field is not needed in the query, skip it */
+
+ goto skip_field;
+ }
+
+ n_requested_fields++;
+
+ templ->col_no = i;
+
+ if (index == clust_index) {
+ templ->rec_field_no = (index->table->cols + i)
+ ->clust_pos;
+ } else {
+ templ->rec_field_no = dict_index_get_nth_col_pos(
+ index, i);
+ }
+
+ if (templ->rec_field_no == ULINT_UNDEFINED) {
+ prebuilt->need_to_access_clustered = TRUE;
+ }
+
+ if (field->null_ptr) {
+ templ->mysql_null_byte_offset =
+ (ulint) ((char*) field->null_ptr
+ - (char*) table->record[0]);
+
+ templ->mysql_null_bit_mask = (ulint) field->null_bit;
+ } else {
+ templ->mysql_null_bit_mask = 0;
+ }
+
+ templ->mysql_col_offset = (ulint)
+ get_field_offset(table, field);
+
+ templ->mysql_col_len = (ulint) field->pack_length();
+ templ->type = get_innobase_type_from_mysql_type(field);
+ templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
+
+ if (templ->type == DATA_BLOB) {
+ prebuilt->templ_contains_blob = TRUE;
+ }
+skip_field:
+ ;
+ }
+
+ prebuilt->n_template = n_requested_fields;
+
+ if (prebuilt->need_to_access_clustered) {
+ /* Change rec_field_no's to correspond to the clustered index
+ record */
+ for (i = 0; i < n_requested_fields; i++) {
+ templ = prebuilt->mysql_template + i;
+
+ templ->rec_field_no =
+ (index->table->cols + templ->col_no)->clust_pos;
+ }
+ }
+}
+
+/************************************************************************
+Stores a row in an InnoDB database, to the table specified in this
+handle. */
+
+int
+ha_innobase::write_row(
+/*===================*/
+ /* out: error code */
+ mysql_byte* record) /* in: a row in MySQL format */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ int error;
+ longlong auto_inc;
+ longlong dummy;
+ ibool incremented_auto_inc_for_stat = FALSE;
+ ibool incremented_auto_inc_counter = FALSE;
+ ibool skip_auto_inc_decr;
+
+ DBUG_ENTER("ha_innobase::write_row");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ statistic_increment(ha_write_count, &LOCK_status);
+
+ if (table->time_stamp) {
+ update_timestamp(record + table->time_stamp - 1);
+ }
+
+ if (last_query_id != user_thd->query_id) {
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
+ }
+
+ if (table->next_number_field && record == table->record[0]) {
+ /* This is the case where the table has an
+ auto-increment column */
+
+ /* Initialize the auto-inc counter if it has not been
+ initialized yet */
+
+ if (0 == dict_table_autoinc_peek(prebuilt->table)) {
+
+ /* This call initializes the counter */
+ error = innobase_read_and_init_auto_inc(&dummy);
+
+ if (error) {
+ /* Deadlock or lock wait timeout */
+
+ goto func_exit;
+ }
+
+ /* We have to set sql_stat_start to TRUE because
+ the above call probably has called a select, and
+ has reset that flag; row_insert_for_mysql has to
+ know to set the IX intention lock on the table,
+ something it only does at the start of each
+ statement */
+
+ prebuilt->sql_stat_start = TRUE;
+ }
+
+ /* Fetch the value the user possibly has set in the
+ autoincrement field */
+
+ auto_inc = table->next_number_field->val_int();
+
+ /* In replication and also otherwise the auto-inc column
+ can be set with SET INSERT_ID. Then we must look at
+ user_thd->next_insert_id. If it is nonzero and the user
+ has not supplied a value, we must use it, and use values
+ incremented by 1 in all subsequent inserts within the
+ same SQL statement! */
+
+ if (auto_inc == 0 && user_thd->next_insert_id != 0) {
+ auto_inc = user_thd->next_insert_id;
+ auto_inc_counter_for_this_stat = auto_inc;
+ }
+
+ if (auto_inc == 0 && auto_inc_counter_for_this_stat) {
+ /* The user set the auto-inc counter for
+ this SQL statement with SET INSERT_ID. We must
+ assign sequential values from the counter. */
+
+ auto_inc_counter_for_this_stat++;
+ incremented_auto_inc_for_stat = TRUE;
+
+ auto_inc = auto_inc_counter_for_this_stat;
+
+ /* We give MySQL a new value to place in the
+ auto-inc column */
+ user_thd->next_insert_id = auto_inc;
+ }
+
+ if (auto_inc != 0) {
+ /* This call will calculate the max of the current
+ value and the value supplied by the user and
+ update the counter accordingly */
+
+ /* We have to use the transactional lock mechanism
+ on the auto-inc counter of the table to ensure
+ that replication and roll-forward of the binlog
+ exactly imitates also the given auto-inc values.
+ The lock is released at each SQL statement's
+ end. */
+
+ innodb_srv_conc_enter_innodb(prebuilt->trx);
+ error = row_lock_table_autoinc_for_mysql(prebuilt);
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ if (error != DB_SUCCESS) {
+
+ error = convert_error_code_to_mysql(error,
+ user_thd);
+ goto func_exit;
+ }
+
+ dict_table_autoinc_update(prebuilt->table, auto_inc);
+ } else {
+ innodb_srv_conc_enter_innodb(prebuilt->trx);
+
+ if (!prebuilt->trx->auto_inc_lock) {
+
+ error = row_lock_table_autoinc_for_mysql(
+ prebuilt);
+ if (error != DB_SUCCESS) {
+ innodb_srv_conc_exit_innodb(
+ prebuilt->trx);
+
+ error = convert_error_code_to_mysql(
+ error, user_thd);
+ goto func_exit;
+ }
+ }
+
+ /* The following call gets the value of the auto-inc
+ counter of the table and increments it by 1 */
+
+ auto_inc = dict_table_autoinc_get(prebuilt->table);
+ incremented_auto_inc_counter = TRUE;
+
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ /* We can give the new value for MySQL to place in
+ the field */
+
+ user_thd->next_insert_id = auto_inc;
+ }
+
+ /* This call of a handler.cc function places
+ user_thd->next_insert_id to the column value, if the column
+ value was not set by the user */
+
+ update_auto_increment();
+ }
+
+ if (prebuilt->mysql_template == NULL
+ || prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) {
+ /* Build the template used in converting quickly between
+ the two database formats */
+
+ build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
+ }
+
+ innodb_srv_conc_enter_innodb(prebuilt->trx);
+
+ error = row_insert_for_mysql((byte*) record, prebuilt);
+
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ if (error != DB_SUCCESS) {
+ /* If the insert did not succeed we restore the value of
+ the auto-inc counter we used; note that this behavior was
+ introduced only in version 4.0.4.
+ NOTE that a REPLACE command handles a duplicate key error
+ itself, and we must not decrement the autoinc counter
+ if we are performing a REPLACE statement.
+ NOTE 2: if there was an error, for example a deadlock,
+ which caused InnoDB to roll back the whole transaction
+ already in the call of row_insert_for_mysql(), we may no
+ longer have the AUTO-INC lock, and cannot decrement
+ the counter here. */
+
+ skip_auto_inc_decr = FALSE;
+
+ if (error == DB_DUPLICATE_KEY
+ && (user_thd->lex.sql_command == SQLCOM_REPLACE
+ || user_thd->lex.sql_command
+ == SQLCOM_REPLACE_SELECT)) {
+
+ skip_auto_inc_decr= TRUE;
+ }
+
+ if (!skip_auto_inc_decr && incremented_auto_inc_counter
+ && prebuilt->trx->auto_inc_lock) {
+ dict_table_autoinc_decrement(prebuilt->table);
+ }
+
+ if (!skip_auto_inc_decr && incremented_auto_inc_for_stat
+ && prebuilt->trx->auto_inc_lock) {
+ auto_inc_counter_for_this_stat--;
+ }
+ }
+
+ error = convert_error_code_to_mysql(error, user_thd);
+
+ /* Tell InnoDB server that there might be work for
+ utility threads: */
+func_exit:
+ innobase_active_small();
+
+ DBUG_RETURN(error);
+}
+
+/******************************************************************
+Converts field data for storage in an InnoDB update vector. */
+inline
+mysql_byte*
+innobase_convert_and_store_changed_col(
+/*===================================*/
+ /* out: pointer to the end of the converted
+ data in the buffer */
+ upd_field_t* ufield, /* in/out: field in the update vector */
+ mysql_byte* buf, /* in: buffer we can use in conversion */
+ mysql_byte* data, /* in: column data to store */
+ ulint len, /* in: data len */
+ ulint col_type,/* in: data type in InnoDB type numbers */
+ ulint is_unsigned)/* in: != 0 if an unsigned integer type */
+{
+ uint i;
+
+ if (len == UNIV_SQL_NULL) {
+ data = NULL;
+ } else if (col_type == DATA_VARCHAR || col_type == DATA_BINARY
+ || col_type == DATA_VARMYSQL) {
+ /* Remove trailing spaces */
+ while (len > 0 && data[len - 1] == ' ') {
+ len--;
+ }
+ } else if (col_type == DATA_INT) {
+ /* Store integer data in InnoDB in a big-endian
+ format, sign bit negated, if signed */
+
+ for (i = 0; i < len; i++) {
+ buf[len - 1 - i] = data[i];
+ }
+
+ if (!is_unsigned) {
+ buf[0] = buf[0] ^ 128;
+ }
+
+ data = buf;
+
+ buf += len;
+ }
+
+ ufield->new_val.data = data;
+ ufield->new_val.len = len;
+
+ return(buf);
+}
+
+/**************************************************************************
+Checks which fields have changed in a row and stores information
+of them to an update vector. */
+static
+int
+calc_row_difference(
+/*================*/
+ /* out: error number or 0 */
+ upd_t* uvect, /* in/out: update vector */
+ mysql_byte* old_row, /* in: old row in MySQL format */
+ mysql_byte* new_row, /* in: new row in MySQL format */
+ struct st_table* table, /* in: table in MySQL data
+ dictionary */
+ mysql_byte* upd_buff, /* in: buffer to use */
+ ulint buff_len, /* in: buffer length */
+ row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
+ THD* thd) /* in: user thread */
+{
+ mysql_byte* original_upd_buff = upd_buff;
+ Field* field;
+ uint n_fields;
+ ulint o_len;
+ ulint n_len;
+ byte* o_ptr;
+ byte* n_ptr;
+ byte* buf;
+ upd_field_t* ufield;
+ ulint col_type;
+ ulint is_unsigned;
+ ulint n_changed = 0;
+ uint i;
+
+ n_fields = table->fields;
+
+ /* We use upd_buff to convert changed fields */
+ buf = (byte*) upd_buff;
+
+ for (i = 0; i < n_fields; i++) {
+ field = table->field[i];
+
+ /* if (thd->query_id != field->query_id) { */
+ /* TODO: check that these fields cannot have
+ changed! */
+
+ /* goto skip_field;
+ }*/
+
+ o_ptr = (byte*) old_row + get_field_offset(table, field);
+ n_ptr = (byte*) new_row + get_field_offset(table, field);
+ o_len = field->pack_length();
+ n_len = field->pack_length();
+
+ col_type = get_innobase_type_from_mysql_type(field);
+ is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
+
+ switch (col_type) {
+
+ case DATA_BLOB:
+ o_ptr = row_mysql_read_blob_ref(&o_len, o_ptr, o_len);
+ n_ptr = row_mysql_read_blob_ref(&n_len, n_ptr, n_len);
+ break;
+ case DATA_VARCHAR:
+ case DATA_BINARY:
+ case DATA_VARMYSQL:
+ o_ptr = row_mysql_read_var_ref_noninline(&o_len,
+ o_ptr);
+ n_ptr = row_mysql_read_var_ref_noninline(&n_len,
+ n_ptr);
+ default:
+ ;
+ }
+
+ if (field->null_ptr) {
+ if (field_in_record_is_null(table, field,
+ (char*) old_row)) {
+ o_len = UNIV_SQL_NULL;
+ }
+
+ if (field_in_record_is_null(table, field,
+ (char*) new_row)) {
+ n_len = UNIV_SQL_NULL;
+ }
+ }
+
+ if (o_len != n_len || (o_len != UNIV_SQL_NULL &&
+ 0 != memcmp(o_ptr, n_ptr, o_len))) {
+ /* The field has changed */
+
+ ufield = uvect->fields + n_changed;
+
+ buf = (byte*)
+ innobase_convert_and_store_changed_col(ufield,
+ (mysql_byte*)buf,
+ (mysql_byte*)n_ptr, n_len, col_type,
+ is_unsigned);
+ ufield->exp = NULL;
+ ufield->field_no =
+ (prebuilt->table->cols + i)->clust_pos;
+ n_changed++;
+ }
+ }
+
+ uvect->n_fields = n_changed;
+ uvect->info_bits = 0;
+
+ ut_a(buf <= (byte*)original_upd_buff + buff_len);
+
+ return(0);
+}
+
+/**************************************************************************
+Updates a row given as a parameter to a new value. Note that we are given
+whole rows, not just the fields which are updated: this incurs some
+overhead for CPU when we check which fields are actually updated.
+TODO: currently InnoDB does not prevent the 'Halloween problem':
+in a searched update a single row can get updated several times
+if its index columns are updated! */
+
+int
+ha_innobase::update_row(
+/*====================*/
+ /* out: error number or 0 */
+ const mysql_byte* old_row,/* in: old row in MySQL format */
+ mysql_byte* new_row)/* in: new row in MySQL format */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ upd_t* uvect;
+ int error = 0;
+
+ DBUG_ENTER("ha_innobase::update_row");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ if (table->time_stamp) {
+ update_timestamp(new_row + table->time_stamp - 1);
+ }
+
+ if (last_query_id != user_thd->query_id) {
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
+ }
+
+ if (prebuilt->upd_node) {
+ uvect = prebuilt->upd_node->update;
+ } else {
+ uvect = row_get_prebuilt_update_vector(prebuilt);
+ }
+
+ /* Build an update vector from the modified fields in the rows
+ (uses upd_buff of the handle) */
+
+ calc_row_difference(uvect, (mysql_byte*) old_row, new_row, table,
+ upd_buff, (ulint)upd_and_key_val_buff_len,
+ prebuilt, user_thd);
+
+ /* This is not a delete */
+ prebuilt->upd_node->is_delete = FALSE;
+
+ assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
+
+ innodb_srv_conc_enter_innodb(prebuilt->trx);
+
+ error = row_update_for_mysql((byte*) old_row, prebuilt);
+
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ error = convert_error_code_to_mysql(error, user_thd);
+
+ /* Tell InnoDB server that there might be work for
+ utility threads: */
+
+ innobase_active_small();
+
+ DBUG_RETURN(error);
+}
+
+/**************************************************************************
+Deletes a row given as the parameter. */
+
+int
+ha_innobase::delete_row(
+/*====================*/
+ /* out: error number or 0 */
+ const mysql_byte* record) /* in: a row in MySQL format */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ int error = 0;
+
+ DBUG_ENTER("ha_innobase::delete_row");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ if (last_query_id != user_thd->query_id) {
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
+ }
+
+ if (!prebuilt->upd_node) {
+ row_get_prebuilt_update_vector(prebuilt);
+ }
+
+ /* This is a delete */
+
+ prebuilt->upd_node->is_delete = TRUE;
+
+ innodb_srv_conc_enter_innodb(prebuilt->trx);
+
+ error = row_update_for_mysql((byte*) record, prebuilt);
+
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ error = convert_error_code_to_mysql(error, user_thd);
+
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ innobase_active_small();
+
+ DBUG_RETURN(error);
+}
+
+/**********************************************************************
+Initializes a handle to use an index. */
+
+int
+ha_innobase::index_init(
+/*====================*/
+ /* out: 0 or error number */
+ uint keynr) /* in: key (index) number */
+{
+ int error = 0;
+ DBUG_ENTER("index_init");
+
+ error = change_active_index(keynr);
+
+ DBUG_RETURN(error);
+}
+
+/**********************************************************************
+Currently does nothing. */
+
+int
+ha_innobase::index_end(void)
+/*========================*/
+{
+ int error = 0;
+ DBUG_ENTER("index_end");
+
+ DBUG_RETURN(error);
+}
+
+/*************************************************************************
+Converts a search mode flag understood by MySQL to a flag understood
+by InnoDB. */
+inline
+ulint
+convert_search_mode_to_innobase(
+/*============================*/
+ enum ha_rkey_function find_flag)
+{
+ switch (find_flag) {
+ case HA_READ_KEY_EXACT: return(PAGE_CUR_GE);
+ /* the above does not require the index to be UNIQUE */
+ case HA_READ_KEY_OR_NEXT: return(PAGE_CUR_GE);
+ case HA_READ_KEY_OR_PREV: return(PAGE_CUR_LE);
+ case HA_READ_AFTER_KEY: return(PAGE_CUR_G);
+ case HA_READ_BEFORE_KEY: return(PAGE_CUR_L);
+ case HA_READ_PREFIX: return(PAGE_CUR_GE);
+ case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE);
+ /* In MySQL-4.0 HA_READ_PREFIX and HA_READ_PREFIX_LAST always
+ pass a complete-field prefix of a key value as the search
+ tuple. I.e., it is not allowed that the last field would
+ just contain n first bytes of the full field value.
+ MySQL uses a 'padding' trick to convert LIKE 'abc%'
+ type queries so that it can use as a search tuple
+ a complete-field-prefix of a key value. Thus, the InnoDB
+ search mode PAGE_CUR_LE_OR_EXTENDS is never used.
+ TODO: when/if MySQL starts to use also partial-field
+ prefixes, we have to deal with stripping of spaces
+ and comparison of non-latin1 char type fields in
+ innobase_mysql_cmp() to get PAGE_CUR_LE_OR_EXTENDS to
+ work correctly. */
+
+ default: assert(0);
+ }
+
+ return(0);
+}
+
+/*
+ BACKGROUND INFO: HOW A SELECT SQL QUERY IS EXECUTED
+ ---------------------------------------------------
+The following does not cover all the details, but explains how we determine
+the start of a new SQL statement, and what is associated with it.
+
+For each table in the database the MySQL interpreter may have several
+table handle instances in use, also in a single SQL query. For each table
+handle instance there is an InnoDB 'prebuilt' struct which contains most
+of the InnoDB data associated with this table handle instance.
+
+ A) if the user has not explicitly set any MySQL table level locks:
+
+ 1) MySQL calls ::external_lock to set an 'intention' table level lock on
+the table of the handle instance. There we set
+prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should be set
+true if we are taking this table handle instance to use in a new SQL
+statement issued by the user. We also increment trx->n_mysql_tables_in_use.
+
+ 2) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
+instructions to prebuilt->template of the table handle instance in
+::index_read. The template is used to save CPU time in large joins.
+
+ 3) In row_search_for_mysql, if prebuilt->sql_stat_start is true, we
+allocate a new consistent read view for the trx if it does not yet have one,
+or in the case of a locking read, set an InnoDB 'intention' table level
+lock on the table.
+
+ 4) We do the SELECT. MySQL may repeatedly call ::index_read for the
+same table handle instance, if it is a join.
+
+ 5) When the SELECT ends, MySQL removes its intention table level locks
+in ::external_lock. When trx->n_mysql_tables_in_use drops to zero,
+ (a) we execute a COMMIT there if the autocommit is on,
+ (b) we also release possible 'SQL statement level resources' InnoDB may
+have for this SQL statement. The MySQL interpreter does NOT execute
+autocommit for pure read transactions, though it should. That is why the
+table handler in that case has to execute the COMMIT in ::external_lock.
+
+ B) If the user has explicitly set MySQL table level locks, then MySQL
+does NOT call ::external_lock at the start of the statement. To determine
+when we are at the start of a new SQL statement we at the start of
+::index_read also compare the query id to the latest query id where the
+table handle instance was used. If it has changed, we know we are at the
+start of a new SQL statement. Since the query id can theoretically
+overwrap, we use this test only as a secondary way of determining the
+start of a new SQL statement. */
+
+
+/**************************************************************************
+Positions an index cursor to the index specified in the handle. Fetches the
+row if any. */
+
+int
+ha_innobase::index_read(
+/*====================*/
+ /* out: 0, HA_ERR_KEY_NOT_FOUND,
+ or error number */
+ mysql_byte* buf, /* in/out: buffer for the returned
+ row */
+ const mysql_byte* key_ptr,/* in: key value; if this is NULL
+ we position the cursor at the
+ start or end of index; this can
+ also contain an InnoDB row id, in
+ which case key_len is the InnoDB
+ row id length; the key value can
+ also be a prefix of a full key value,
+ and the last column can be a prefix
+ of a full column */
+ uint key_len,/* in: key value length */
+ enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ ulint mode;
+ dict_index_t* index;
+ ulint match_mode = 0;
+ int error;
+ ulint ret;
+
+ DBUG_ENTER("index_read");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ statistic_increment(ha_read_key_count, &LOCK_status);
+
+ if (last_query_id != user_thd->query_id) {
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
+ }
+
+ index = prebuilt->index;
+
+ /* Note that if the index for which the search template is built is not
+ necessarily prebuilt->index, but can also be the clustered index */
+
+ if (prebuilt->sql_stat_start) {
+ build_template(prebuilt, user_thd, table,
+ ROW_MYSQL_REC_FIELDS);
+ }
+
+ if (key_ptr) {
+ /* Convert the search key value to InnoDB format into
+ prebuilt->search_tuple */
+
+ row_sel_convert_mysql_key_to_innobase(prebuilt->search_tuple,
+ (byte*) key_val_buff,
+ (ulint)upd_and_key_val_buff_len,
+ index,
+ (byte*) key_ptr,
+ (ulint) key_len);
+ } else {
+ /* We position the cursor to the last or the first entry
+ in the index */
+
+ dtuple_set_n_fields(prebuilt->search_tuple, 0);
+ }
+
+ mode = convert_search_mode_to_innobase(find_flag);
+
+ match_mode = 0;
+
+ if (find_flag == HA_READ_KEY_EXACT) {
+ match_mode = ROW_SEL_EXACT;
+
+ } else if (find_flag == HA_READ_PREFIX
+ || find_flag == HA_READ_PREFIX_LAST) {
+ match_mode = ROW_SEL_EXACT_PREFIX;
+ }
+
+ last_match_mode = match_mode;
+
+ innodb_srv_conc_enter_innodb(prebuilt->trx);
+
+ ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mode, 0);
+
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ if (ret == DB_SUCCESS) {
+ error = 0;
+ table->status = 0;
+
+ } else if (ret == DB_RECORD_NOT_FOUND) {
+ error = HA_ERR_KEY_NOT_FOUND;
+ table->status = STATUS_NOT_FOUND;
+
+ } else if (ret == DB_END_OF_INDEX) {
+ error = HA_ERR_KEY_NOT_FOUND;
+ table->status = STATUS_NOT_FOUND;
+ } else {
+ error = convert_error_code_to_mysql(ret, user_thd);
+ table->status = STATUS_NOT_FOUND;
+ }
+
+ DBUG_RETURN(error);
+}
+
+/***********************************************************************
+The following functions works like index_read, but it find the last
+row with the current key value or prefix. */
+
+int
+ha_innobase::index_read_last(
+/*=========================*/
+ /* out: 0, HA_ERR_KEY_NOT_FOUND, or an
+ error code */
+ mysql_byte* buf, /* out: fetched row */
+ const mysql_byte* key_ptr, /* in: key value, or a prefix of a full
+ key value */
+ uint key_len) /* in: length of the key val or prefix
+ in bytes */
+{
+ return(index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST));
+}
+
+/************************************************************************
+Changes the active index of a handle. */
+
+int
+ha_innobase::change_active_index(
+/*=============================*/
+ /* out: 0 or error code */
+ uint keynr) /* in: use this index; MAX_KEY means always clustered
+ index, even if it was internally generated by
+ InnoDB */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ KEY* key=0;
+ statistic_increment(ha_read_key_count, &LOCK_status);
+ DBUG_ENTER("change_active_index");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ active_index = keynr;
+
+ if (keynr != MAX_KEY && table->keys > 0) {
+ key = table->key_info + active_index;
+
+ prebuilt->index = dict_table_get_index_noninline(
+ prebuilt->table,
+ key->name);
+ } else {
+ prebuilt->index = dict_table_get_first_index_noninline(
+ prebuilt->table);
+ }
+
+ if (!prebuilt->index) {
+ sql_print_error(
+"Innodb could not find key n:o %u with name %s from dict cache for table %s",
+ keynr, key ? key->name : "NULL", prebuilt->table->name);
+ DBUG_RETURN(1);
+ }
+
+ assert(prebuilt->search_tuple != 0);
+
+ dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
+
+ dict_index_copy_types(prebuilt->search_tuple, prebuilt->index,
+ prebuilt->index->n_fields);
+
+ /* Maybe MySQL changes the active index for a handle also
+ during some queries, we do not know: then it is safest to build
+ the template such that all columns will be fetched. */
+
+ build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
+
+ DBUG_RETURN(0);
+}
+
+/**************************************************************************
+Positions an index cursor to the index specified in keynr. Fetches the
+row if any. */
+/* ??? This is only used to read whole keys ??? */
+
+int
+ha_innobase::index_read_idx(
+/*========================*/
+ /* out: error number or 0 */
+ mysql_byte* buf, /* in/out: buffer for the returned
+ row */
+ uint keynr, /* in: use this index */
+ const mysql_byte* key, /* in: key value; if this is NULL
+ we position the cursor at the
+ start or end of index */
+ uint key_len, /* in: key value length */
+ enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
+{
+ if (change_active_index(keynr)) {
+
+ return(1);
+ }
+
+ return(index_read(buf, key, key_len, find_flag));
+}
+
+/***************************************************************************
+Reads the next or previous row from a cursor, which must have previously been
+positioned using index_read. */
+
+int
+ha_innobase::general_fetch(
+/*=======================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error
+ number */
+ mysql_byte* buf, /* in/out: buffer for next row in MySQL
+ format */
+ uint direction, /* in: ROW_SEL_NEXT or ROW_SEL_PREV */
+ uint match_mode) /* in: 0, ROW_SEL_EXACT, or
+ ROW_SEL_EXACT_PREFIX */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ ulint ret;
+ int error = 0;
+
+ DBUG_ENTER("general_fetch");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ innodb_srv_conc_enter_innodb(prebuilt->trx);
+
+ ret = row_search_for_mysql((byte*)buf, 0, prebuilt, match_mode,
+ direction);
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ if (ret == DB_SUCCESS) {
+ error = 0;
+ table->status = 0;
+
+ } else if (ret == DB_RECORD_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+ table->status = STATUS_NOT_FOUND;
+
+ } else if (ret == DB_END_OF_INDEX) {
+ error = HA_ERR_END_OF_FILE;
+ table->status = STATUS_NOT_FOUND;
+ } else {
+ error = convert_error_code_to_mysql(ret, user_thd);
+ table->status = STATUS_NOT_FOUND;
+ }
+
+ DBUG_RETURN(error);
+}
+
+/***************************************************************************
+Reads the next row from a cursor, which must have previously been
+positioned using index_read. */
+
+int
+ha_innobase::index_next(
+/*====================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error
+ number */
+ mysql_byte* buf) /* in/out: buffer for next row in MySQL
+ format */
+{
+ statistic_increment(ha_read_next_count, &LOCK_status);
+
+ return(general_fetch(buf, ROW_SEL_NEXT, 0));
+}
+
+/***********************************************************************
+Reads the next row matching to the key value given as the parameter. */
+
+int
+ha_innobase::index_next_same(
+/*=========================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error
+ number */
+ mysql_byte* buf, /* in/out: buffer for the row */
+ const mysql_byte* key, /* in: key value */
+ uint keylen) /* in: key value length */
+{
+ statistic_increment(ha_read_next_count, &LOCK_status);
+
+ return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
+}
+
+/***************************************************************************
+Reads the previous row from a cursor, which must have previously been
+positioned using index_read. */
+
+int
+ha_innobase::index_prev(
+/*====================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error
+ number */
+ mysql_byte* buf) /* in/out: buffer for previous row in MySQL
+ format */
+{
+ return(general_fetch(buf, ROW_SEL_PREV, 0));
+}
+
+/************************************************************************
+Positions a cursor on the first record in an index and reads the
+corresponding row to buf. */
+
+int
+ha_innobase::index_first(
+/*=====================*/
+ /* out: 0, HA_ERR_END_OF_FILE,
+ or error code */
+ mysql_byte* buf) /* in/out: buffer for the row */
+{
+ int error;
+
+ DBUG_ENTER("index_first");
+ statistic_increment(ha_read_first_count, &LOCK_status);
+
+ error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
+
+ /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
+
+ if (error == HA_ERR_KEY_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+ }
+
+ DBUG_RETURN(error);
+}
+
+/************************************************************************
+Positions a cursor on the last record in an index and reads the
+corresponding row to buf. */
+
+int
+ha_innobase::index_last(
+/*====================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error code */
+ mysql_byte* buf) /* in/out: buffer for the row */
+{
+ int error;
+
+ DBUG_ENTER("index_first");
+ statistic_increment(ha_read_last_count, &LOCK_status);
+
+ error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
+
+ /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
+
+ if (error == HA_ERR_KEY_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+ }
+
+ DBUG_RETURN(error);
+}
+
+/********************************************************************
+Initialize a table scan. */
+
+int
+ha_innobase::rnd_init(
+/*==================*/
+ /* out: 0 or error number */
+ bool scan) /* in: ???????? */
+{
+ int err;
+
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ /* Store the active index value so that we can restore the original
+ value after a scan */
+
+ active_index_before_scan = active_index;
+
+ if (prebuilt->clust_index_was_generated) {
+ err = change_active_index(MAX_KEY);
+ } else {
+ err = change_active_index(primary_key);
+ }
+
+ start_of_scan = 1;
+
+ return(err);
+}
+
+/*********************************************************************
+Ends a table scan. */
+
+int
+ha_innobase::rnd_end(void)
+/*======================*/
+ /* out: 0 or error number */
+{
+ /* Restore the old active_index back; MySQL may assume that a table
+ scan does not change active_index. We only restore the value if
+ MySQL has called rnd_init before: sometimes MySQL seems to call
+ rnd_end WITHOUT calling rnd_init. */
+
+ if (active_index_before_scan != (uint)-1) {
+
+ change_active_index(active_index_before_scan);
+
+ active_index_before_scan = (uint)-1;
+ }
+
+ return(index_end());
+}
+
+/*********************************************************************
+Reads the next row in a table scan (also used to read the FIRST row
+in a table scan). */
+
+int
+ha_innobase::rnd_next(
+/*==================*/
+ /* out: 0, HA_ERR_END_OF_FILE, or error number */
+ mysql_byte* buf)/* in/out: returns the row in this buffer,
+ in MySQL format */
+{
+ int error;
+
+ DBUG_ENTER("rnd_next");
+ statistic_increment(ha_read_rnd_next_count, &LOCK_status);
+
+ if (start_of_scan) {
+ error = index_first(buf);
+ if (error == HA_ERR_KEY_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+ }
+ start_of_scan = 0;
+ } else {
+ error = general_fetch(buf, ROW_SEL_NEXT, 0);
+ }
+
+ DBUG_RETURN(error);
+}
+
+/**************************************************************************
+Fetches a row from the table based on a row reference. */
+
+int
+ha_innobase::rnd_pos(
+/*=================*/
+ /* out: 0, HA_ERR_KEY_NOT_FOUND,
+ or error code */
+ mysql_byte* buf, /* in/out: buffer for the row */
+ mysql_byte* pos) /* in: primary key value of the row in the
+ MySQL format, or the row id if the clustered
+ index was internally generated by InnoDB;
+ the length of data in pos has to be
+ ref_length */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ int error;
+ uint keynr = active_index;
+ DBUG_ENTER("rnd_pos");
+ DBUG_DUMP("key", (char*) pos, ref_length);
+
+ statistic_increment(ha_read_rnd_count, &LOCK_status);
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ if (prebuilt->clust_index_was_generated) {
+ /* No primary key was defined for the table and we
+ generated the clustered index from the row id: the
+ row reference is the row id, not any key value
+ that MySQL knows of */
+
+ error = change_active_index(MAX_KEY);
+ } else {
+ error = change_active_index(primary_key);
+ }
+
+ if (error) {
+ DBUG_PRINT("error",("Got error: %ld",error));
+ DBUG_RETURN(error);
+ }
+
+ /* Note that we assume the length of the row reference is fixed
+ for the table, and it is == ref_length */
+
+ error = index_read(buf, pos, ref_length, HA_READ_KEY_EXACT);
+ if (error)
+ {
+ DBUG_PRINT("error",("Got error: %ld",error));
+ }
+ change_active_index(keynr);
+
+ DBUG_RETURN(error);
+}
+
+/*************************************************************************
+Stores a reference to the current row to 'ref' field of the handle. Note
+that in the case where we have generated the clustered index for the
+table, the function parameter is illogical: we MUST ASSUME that 'record'
+is the current 'position' of the handle, because if row ref is actually
+the row id internally generated in InnoDB, then 'record' does not contain
+it. We just guess that the row id must be for the record where the handle
+was positioned the last time. */
+
+void
+ha_innobase::position(
+/*==================*/
+ const mysql_byte* record) /* in: row in MySQL format */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ uint len;
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ if (prebuilt->clust_index_was_generated) {
+ /* No primary key was defined for the table and we
+ generated the clustered index from row id: the
+ row reference will be the row id, not any key value
+ that MySQL knows of */
+
+ len = DATA_ROW_ID_LEN;
+
+ memcpy(ref, prebuilt->row_id, len);
+ } else {
+ len = store_key_val_for_row(primary_key, (char*)ref,
+ ref_length, record);
+ }
+
+ /* Since we do not store len to the buffer 'ref', we must assume
+ that len is always fixed for this table. The following assertion
+ checks this. */
+
+ if (len != ref_length) {
+ fprintf(stderr,
+ "InnoDB: Error: stored ref len is %lu, but table ref len is %lu\n",
+ (ulint)len, (ulint)ref_length);
+ }
+}
+
+/*********************************************************************
+Creates a table definition to an InnoDB database. */
+static
+int
+create_table_def(
+/*=============*/
+ trx_t* trx, /* in: InnoDB transaction handle */
+ TABLE* form, /* in: information on table
+ columns and indexes */
+ const char* table_name) /* in: table name */
+{
+ Field* field;
+ dict_table_t* table;
+ ulint n_cols;
+ int error;
+ ulint col_type;
+ ulint nulls_allowed;
+ ulint unsigned_type;
+ ulint binary_type;
+ ulint nonlatin1_type;
+ ulint i;
+
+ DBUG_ENTER("create_table_def");
+ DBUG_PRINT("enter", ("table_name: %s", table_name));
+
+ n_cols = form->fields;
+
+ /* The '0' below specifies that everything is currently
+ created in tablespace 0 */
+
+ table = dict_mem_table_create((char*) table_name, 0, n_cols);
+
+ for (i = 0; i < n_cols; i++) {
+ field = form->field[i];
+
+ col_type = get_innobase_type_from_mysql_type(field);
+ if (field->null_ptr) {
+ nulls_allowed = 0;
+ } else {
+ nulls_allowed = DATA_NOT_NULL;
+ }
+
+ if (field->flags & UNSIGNED_FLAG) {
+ unsigned_type = DATA_UNSIGNED;
+ } else {
+ unsigned_type = 0;
+ }
+
+ if (col_type == DATA_BLOB
+ && strcmp(default_charset_info->name, "latin1") != 0) {
+ nonlatin1_type = DATA_NONLATIN1;
+ } else {
+ nonlatin1_type = 0;
+ }
+
+ if (field->flags & BINARY_FLAG) {
+ binary_type = DATA_BINARY_TYPE;
+ nonlatin1_type = 0;
+ } else {
+ binary_type = 0;
+ }
+
+ dict_mem_table_add_col(table, (char*) field->field_name,
+ col_type, (ulint)field->type()
+ | nulls_allowed | unsigned_type
+ | nonlatin1_type | binary_type,
+ field->pack_length(), 0);
+ }
+
+ error = row_create_table_for_mysql(table, trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ DBUG_RETURN(error);
+}
+
+/*********************************************************************
+Creates an index in an InnoDB database. */
+static
+int
+create_index(
+/*=========*/
+ trx_t* trx, /* in: InnoDB transaction handle */
+ TABLE* form, /* in: information on table
+ columns and indexes */
+ const char* table_name, /* in: table name */
+ uint key_num) /* in: index number */
+{
+ Field* field;
+ dict_index_t* index;
+ int error;
+ ulint n_fields;
+ KEY* key;
+ KEY_PART_INFO* key_part;
+ ulint ind_type;
+ ulint col_type;
+ ulint prefix_len;
+ ulint i;
+ ulint j;
+
+ DBUG_ENTER("create_index");
+
+ key = form->key_info + key_num;
+
+ n_fields = key->key_parts;
+
+ ind_type = 0;
+
+ if (key_num == form->primary_key)
+ {
+ ind_type = ind_type | DICT_CLUSTERED;
+ }
+
+ if (key->flags & HA_NOSAME ) {
+ ind_type = ind_type | DICT_UNIQUE;
+ }
+
+ /* The '0' below specifies that everything in InnoDB is currently
+ created in tablespace 0 */
+
+ index = dict_mem_index_create((char*) table_name, key->name, 0,
+ ind_type, n_fields);
+ for (i = 0; i < n_fields; i++) {
+ key_part = key->key_part + i;
+
+ /* (The flag HA_PART_KEY_SEG denotes in MySQL a column prefix
+ field in an index: we only store a specified number of first
+ bytes of the column to the index field.) The flag does not
+ seem to be properly set by MySQL. Let us fall back on testing
+ the length of the key part versus the column. */
+
+ field = NULL;
+ for (j = 0; j < form->fields; j++) {
+
+ field = form->field[j];
+
+ if (strlen(field->field_name)
+ == strlen(key_part->field->field_name)
+ && 0 == ut_cmp_in_lower_case(
+ (char*)field->field_name,
+ (char*)key_part->field->field_name,
+ strlen(field->field_name))) {
+ /* Found the corresponding column */
+
+ break;
+ }
+ }
+
+ ut_a(j < form->fields);
+
+ col_type = get_innobase_type_from_mysql_type(key_part->field);
+
+ if (DATA_BLOB == col_type
+ || key_part->length < field->pack_length()) {
+
+ prefix_len = key_part->length;
+
+ if (col_type == DATA_INT
+ || col_type == DATA_FLOAT
+ || col_type == DATA_DOUBLE
+ || col_type == DATA_DECIMAL) {
+ fprintf(stderr,
+"InnoDB: error: MySQL is trying to create a column prefix index field\n"
+"InnoDB: on an inappropriate data type. Table name %s, column name %s.\n",
+ table_name, key_part->field->field_name);
+
+ prefix_len = 0;
+ }
+ } else {
+ prefix_len = 0;
+ }
+
+ if (prefix_len >= DICT_MAX_COL_PREFIX_LEN) {
+ DBUG_RETURN(-1);
+ }
+
+ /* We assume all fields should be sorted in ascending
+ order, hence the '0': */
+
+ dict_mem_index_add_field(index,
+ (char*) key_part->field->field_name,
+ 0, prefix_len);
+ }
+
+ error = row_create_index_for_mysql(index, trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ DBUG_RETURN(error);
+}
+
+/*********************************************************************
+Creates an index to an InnoDB table when the user has defined no
+primary index. */
+static
+int
+create_clustered_index_when_no_primary(
+/*===================================*/
+ trx_t* trx, /* in: InnoDB transaction handle */
+ const char* table_name) /* in: table name */
+{
+ dict_index_t* index;
+ int error;
+
+ /* The first '0' below specifies that everything in InnoDB is
+ currently created in file space 0 */
+
+ index = dict_mem_index_create((char*) table_name,
+ (char*) "GEN_CLUST_INDEX",
+ 0, DICT_CLUSTERED, 0);
+ error = row_create_index_for_mysql(index, trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ return(error);
+}
+
+/*********************************************************************
+Creates a new table to an InnoDB database. */
+
+int
+ha_innobase::create(
+/*================*/
+ /* out: error number */
+ const char* name, /* in: table name */
+ TABLE* form, /* in: information on table
+ columns and indexes */
+ HA_CREATE_INFO* create_info) /* in: more information of the
+ created table, contains also the
+ create statement string */
+{
+ int error;
+ dict_table_t* innobase_table;
+ trx_t* parent_trx;
+ trx_t* trx;
+ int primary_key_no;
+ uint i;
+ char name2[FN_REFLEN];
+ char norm_name[FN_REFLEN];
+ THD *thd= current_thd;
+
+ DBUG_ENTER("ha_innobase::create");
+
+ DBUG_ASSERT(thd != NULL);
+
+ if (form->fields > 1000) {
+ /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
+ but we play safe here */
+
+ DBUG_RETURN(HA_ERR_TO_BIG_ROW);
+ }
+
+ /* Get the transaction associated with the current thd, or create one
+ if not yet created */
+
+ parent_trx = check_trx_exists(current_thd);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(parent_trx);
+
+ trx = trx_allocate_for_mysql();
+
+ trx->mysql_thd = thd;
+ trx->mysql_query_str = &((*thd).query);
+
+ if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ trx->check_foreigns = FALSE;
+ }
+
+ if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
+ trx->check_unique_secondary = FALSE;
+ }
+
+ if (lower_case_table_names) {
+ srv_lower_case_table_names = TRUE;
+ } else {
+ srv_lower_case_table_names = FALSE;
+ }
+
+ fn_format(name2, name, "", "",2); // Remove the .frm extension
+
+ normalize_table_name(norm_name, name2);
+
+ /* Latch the InnoDB data dictionary exclusively so that no deadlocks
+ or lock waits can happen in it during a table create operation.
+ Drop table etc. do this latching in row0mysql.c. */
+
+ row_mysql_lock_data_dictionary(trx);
+
+ /* Create the table definition in InnoDB */
+
+ error = create_table_def(trx, form, norm_name);
+
+ if (error) {
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary(trx);
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
+ }
+
+ /* Look for a primary key */
+
+ primary_key_no= (table->primary_key != MAX_KEY ?
+ (int) table->primary_key :
+ -1);
+
+ /* Our function row_get_mysql_key_number_for_index assumes
+ the primary key is always number 0, if it exists */
+
+ DBUG_ASSERT(primary_key_no == -1 || primary_key_no == 0);
+
+ /* Create the keys */
+
+ if (form->keys == 0 || primary_key_no == -1) {
+ /* Create an index which is used as the clustered index;
+ order the rows by their row id which is internally generated
+ by InnoDB */
+
+ error = create_clustered_index_when_no_primary(trx,
+ norm_name);
+ if (error) {
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary(trx);
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
+ }
+ }
+
+ if (primary_key_no != -1) {
+ /* In InnoDB the clustered index must always be created
+ first */
+ if ((error = create_index(trx, form, norm_name,
+ (uint) primary_key_no))) {
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary(trx);
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
+ }
+ }
+
+ for (i = 0; i < form->keys; i++) {
+
+ if (i != (uint) primary_key_no) {
+
+ if ((error = create_index(trx, form, norm_name, i))) {
+
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary(trx);
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
+ }
+ }
+ }
+
+ if (current_thd->query != NULL) {
+
+ error = row_table_add_foreign_constraints(trx,
+ current_thd->query, norm_name);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ if (error) {
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary(trx);
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
+ }
+ }
+
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary(trx);
+
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_buffer_flush_to_disk();
+
+ innobase_table = dict_table_get(norm_name, NULL);
+
+ DBUG_ASSERT(innobase_table != 0);
+
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(0);
+}
+
+/*********************************************************************
+Drops a table from an InnoDB database. Before calling this function,
+MySQL calls innobase_commit to commit the transaction of the current user.
+Then the current user cannot have locks set on the table. Drop table
+operation inside InnoDB will remove all locks any user has on the table
+inside InnoDB. */
+
+int
+ha_innobase::delete_table(
+/*======================*/
+ /* out: error number */
+ const char* name) /* in: table name */
+{
+ ulint name_len;
+ int error;
+ trx_t* parent_trx;
+ trx_t* trx;
+ THD *thd= current_thd;
+ char norm_name[1000];
+
+ DBUG_ENTER("ha_innobase::delete_table");
+
+ /* Get the transaction associated with the current thd, or create one
+ if not yet created */
+
+ parent_trx = check_trx_exists(current_thd);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(parent_trx);
+
+ if (lower_case_table_names) {
+ srv_lower_case_table_names = TRUE;
+ } else {
+ srv_lower_case_table_names = FALSE;
+ }
+
+ trx = trx_allocate_for_mysql();
+
+ trx->mysql_thd = current_thd;
+ trx->mysql_query_str = &((*current_thd).query);
+
+ if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ trx->check_foreigns = FALSE;
+ }
+
+ if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
+ trx->check_unique_secondary = FALSE;
+ }
+
+ name_len = strlen(name);
+
+ assert(name_len < 1000);
+
+ /* Strangely, MySQL passes the table name without the '.frm'
+ extension, in contrast to ::create */
+
+ normalize_table_name(norm_name, name);
+
+ /* Drop the table in InnoDB */
+
+ error = row_drop_table_for_mysql(norm_name, trx);
+
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_buffer_flush_to_disk();
+
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ innobase_commit_low(trx);
+
+ trx_free_for_mysql(trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ DBUG_RETURN(error);
+}
+
+/*********************************************************************
+Removes all tables in the named database inside InnoDB. */
+
+int
+innobase_drop_database(
+/*===================*/
+ /* out: error number */
+ char* path) /* in: database path; inside InnoDB the name
+ of the last directory in the path is used as
+ the database name: for example, in 'mysql/data/test'
+ the database name is 'test' */
+{
+ ulint len = 0;
+ trx_t* parent_trx;
+ trx_t* trx;
+ char* ptr;
+ int error;
+ char namebuf[10000];
+
+ /* Get the transaction associated with the current thd, or create one
+ if not yet created */
+
+ parent_trx = check_trx_exists(current_thd);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(parent_trx);
+
+ ptr = strend(path) - 2;
+
+ while (ptr >= path && *ptr != '\\' && *ptr != '/') {
+ ptr--;
+ len++;
+ }
+
+ ptr++;
+
+ memcpy(namebuf, ptr, len);
+ namebuf[len] = '/';
+ namebuf[len + 1] = '\0';
+#ifdef __WIN__
+ casedn_str(namebuf);
+#endif
+ trx = trx_allocate_for_mysql();
+ trx->mysql_thd = current_thd;
+ trx->mysql_query_str = &((*current_thd).query);
+
+ error = row_drop_database_for_mysql(namebuf, trx);
+
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_buffer_flush_to_disk();
+
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ innobase_commit_low(trx);
+ trx_free_for_mysql(trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ return(error);
+}
+
+/*************************************************************************
+Renames an InnoDB table. */
+
+int
+ha_innobase::rename_table(
+/*======================*/
+ /* out: 0 or error code */
+ const char* from, /* in: old name of the table */
+ const char* to) /* in: new name of the table */
+{
+ ulint name_len1;
+ ulint name_len2;
+ int error;
+ trx_t* parent_trx;
+ trx_t* trx;
+ char norm_from[1000];
+ char norm_to[1000];
+
+ DBUG_ENTER("ha_innobase::rename_table");
+
+ /* Get the transaction associated with the current thd, or create one
+ if not yet created */
+
+ parent_trx = check_trx_exists(current_thd);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(parent_trx);
+
+ if (lower_case_table_names) {
+ srv_lower_case_table_names = TRUE;
+ } else {
+ srv_lower_case_table_names = FALSE;
+ }
+
+ trx = trx_allocate_for_mysql();
+ trx->mysql_thd = current_thd;
+ trx->mysql_query_str = &((*current_thd).query);
+
+ name_len1 = strlen(from);
+ name_len2 = strlen(to);
+
+ assert(name_len1 < 1000);
+ assert(name_len2 < 1000);
+
+ normalize_table_name(norm_from, from);
+ normalize_table_name(norm_to, to);
+
+ /* Rename the table in InnoDB */
+
+ error = row_rename_table_for_mysql(norm_from, norm_to, trx);
+
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
+
+ log_buffer_flush_to_disk();
+
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
+
+ srv_active_wake_master_thread();
+
+ innobase_commit_low(trx);
+ trx_free_for_mysql(trx);
+
+ error = convert_error_code_to_mysql(error, NULL);
+
+ DBUG_RETURN(error);
+}
+
+/*************************************************************************
+Estimates the number of index records in a range. */
+
+ha_rows
+ha_innobase::records_in_range(
+/*==========================*/
+ /* out: estimated number of
+ rows */
+ int keynr, /* in: index number */
+ const mysql_byte* start_key, /* in: start key value of the
+ range, may also be empty */
+ uint start_key_len, /* in: start key val len, may
+ also be 0 */
+ enum ha_rkey_function start_search_flag,/* in: start search condition
+ e.g., 'greater than' */
+ const mysql_byte* end_key, /* in: range end key val, may
+ also be empty */
+ uint end_key_len, /* in: range end key val len,
+ may also be 0 */
+ enum ha_rkey_function end_search_flag)/* in: range end search cond */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ KEY* key;
+ dict_index_t* index;
+ mysql_byte* key_val_buff2 = (mysql_byte*) my_malloc(
+ table->reclength
+ + table->max_key_length + 100,
+ MYF(MY_WME));
+ ulint buff2_len = table->reclength
+ + table->max_key_length + 100;
+ dtuple_t* range_start;
+ dtuple_t* range_end;
+ ib_longlong n_rows;
+ ulint mode1;
+ ulint mode2;
+ void* heap1;
+ void* heap2;
+
+ DBUG_ENTER("records_in_range");
+
+ /* We do not know if MySQL can call this function before calling
+ external_lock(). To be safe, update the thd of the current table
+ handle. */
+
+ update_thd(current_thd);
+
+ prebuilt->trx->op_info = (char*)"estimating records in index range";
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
+
+ active_index = keynr;
+
+ key = table->key_info + active_index;
+
+ index = dict_table_get_index_noninline(prebuilt->table, key->name);
+
+ range_start = dtuple_create_for_mysql(&heap1, key->key_parts);
+ dict_index_copy_types(range_start, index, key->key_parts);
+
+ range_end = dtuple_create_for_mysql(&heap2, key->key_parts);
+ dict_index_copy_types(range_end, index, key->key_parts);
+
+ row_sel_convert_mysql_key_to_innobase(
+ range_start, (byte*) key_val_buff,
+ (ulint)upd_and_key_val_buff_len,
+ index,
+ (byte*) start_key,
+ (ulint) start_key_len);
+
+ row_sel_convert_mysql_key_to_innobase(
+ range_end, (byte*) key_val_buff2,
+ buff2_len, index,
+ (byte*) end_key,
+ (ulint) end_key_len);
+
+ mode1 = convert_search_mode_to_innobase(start_search_flag);
+ mode2 = convert_search_mode_to_innobase(end_search_flag);
+
+ n_rows = btr_estimate_n_rows_in_range(index, range_start,
+ mode1, range_end, mode2);
+ dtuple_free_for_mysql(heap1);
+ dtuple_free_for_mysql(heap2);
+
+ my_free((char*) key_val_buff2, MYF(0));
+
+ prebuilt->trx->op_info = (char*)"";
+
+ /* The MySQL optimizer seems to believe an estimate of 0 rows is
+ always accurate and may return the result 'Empty set' based on that.
+ The accuracy is not guaranteed, and even if it were, for a locking
+ read we should anyway perform the search to set the next-key lock.
+ Add 1 to the value to make sure MySQL does not make the assumption! */
+
+ if (n_rows == 0) {
+ n_rows = 1;
+ }
+
+ DBUG_RETURN((ha_rows) n_rows);
+}
+
+/*************************************************************************
+Gives an UPPER BOUND to the number of rows in a table. This is used in
+filesort.cc. */
+
+ha_rows
+ha_innobase::estimate_number_of_rows(void)
+/*======================================*/
+ /* out: upper bound of rows */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ dict_index_t* index;
+ ulonglong estimate;
+ ulonglong local_data_file_length;
+
+ DBUG_ENTER("estimate_number_of_rows");
+
+ /* We do not know if MySQL can call this function before calling
+ external_lock(). To be safe, update the thd of the current table
+ handle. */
+
+ update_thd(current_thd);
+
+ prebuilt->trx->op_info = (char*)
+ "calculating upper bound for table rows";
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
+
+ index = dict_table_get_first_index_noninline(prebuilt->table);
+
+ local_data_file_length = ((ulonglong) index->stat_n_leaf_pages)
+ * UNIV_PAGE_SIZE;
+
+ /* Calculate a minimum length for a clustered index record and from
+ that an upper bound for the number of rows. Since we only calculate
+ new statistics in row0mysql.c when a table has grown by a threshold
+ factor, we must add a safety factor 2 in front of the formula below. */
+
+ estimate = 2 * local_data_file_length /
+ dict_index_calc_min_rec_len(index);
+
+ prebuilt->trx->op_info = (char*)"";
+
+ DBUG_RETURN((ha_rows) estimate);
+}
+
+/*************************************************************************
+How many seeks it will take to read through the table. This is to be
+comparable to the number returned by records_in_range so that we can
+decide if we should scan the table or use keys. */
+
+double
+ha_innobase::scan_time()
+/*====================*/
+ /* out: estimated time measured in disk seeks */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ /* Since MySQL seems to favor table scans too much over index
+ searches, we pretend that a sequential read takes the same time
+ as a random disk read, that is, we do not divide the following
+ by 10, which would be physically realistic. */
+
+ return((double) (prebuilt->table->stat_clustered_index_size));
+}
+
+/**********************************************************************
+Calculate the time it takes to read a set of ranges through an index
+This enables us to optimise reads for clustered indexes. */
+
+double
+ha_innobase::read_time(
+/*===================*/
+ /* out: estimated time measured in disk seeks */
+ uint index, /* in: key number */
+ uint ranges, /* in: how many ranges */
+ ha_rows rows) /* in: estimated number of rows in the ranges */
+{
+ ha_rows total_rows;
+ double time_for_scan;
+
+ if (index != table->primary_key)
+ return handler::read_time(index, ranges, rows); // Not clustered
+
+ if (rows <= 2)
+ return (double) rows;
+
+ /* Assume that the read time is proportional to the scan time for all
+ rows + at most one seek per range. */
+
+ time_for_scan= scan_time();
+
+ if ((total_rows= estimate_number_of_rows()) < rows)
+ return time_for_scan;
+
+ return (ranges + (double) rows / (double) total_rows * time_for_scan);
+}
+
+/*************************************************************************
+Returns statistics information of the table to the MySQL interpreter,
+in various fields of the handle object. */
+
+void
+ha_innobase::info(
+/*==============*/
+ uint flag) /* in: what information MySQL requests */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ dict_table_t* ib_table;
+ dict_index_t* index;
+ ha_rows rec_per_key;
+ ulong j;
+ ulong i;
+
+ DBUG_ENTER("info");
+
+ /* If we are forcing recovery at a high level, we will suppress
+ statistics calculation on tables, because that may crash the
+ server if an index is badly corrupted. */
+
+ if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
+
+ return;
+ }
+
+ /* We do not know if MySQL can call this function before calling
+ external_lock(). To be safe, update the thd of the current table
+ handle. */
+
+ update_thd(current_thd);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ prebuilt->trx->op_info = (char*)"returning various info to MySQL";
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
+
+ ib_table = prebuilt->table;
+
+ if (flag & HA_STATUS_TIME) {
+ /* In sql_show we call with this flag: update then statistics
+ so that they are up-to-date */
+
+ prebuilt->trx->op_info = (char*)"updating table statistics";
+
+ dict_update_statistics(ib_table);
+
+ prebuilt->trx->op_info = (char*)
+ "returning various info to MySQL";
+ }
+
+ if (flag & HA_STATUS_VARIABLE) {
+ records = (ha_rows)ib_table->stat_n_rows;
+ deleted = 0;
+ data_file_length = ((ulonglong)
+ ib_table->stat_clustered_index_size)
+ * UNIV_PAGE_SIZE;
+ index_file_length = ((ulonglong)
+ ib_table->stat_sum_of_other_index_sizes)
+ * UNIV_PAGE_SIZE;
+ delete_length = 0;
+ check_time = 0;
+
+ if (records == 0) {
+ mean_rec_length = 0;
+ } else {
+ mean_rec_length = (ulong) (data_file_length / records);
+ }
+ }
+
+ if (flag & HA_STATUS_CONST) {
+ index = dict_table_get_first_index_noninline(ib_table);
+
+ if (prebuilt->clust_index_was_generated) {
+ index = dict_table_get_next_index_noninline(index);
+ }
+
+ for (i = 0; i < table->keys; i++) {
+ if (index == NULL) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Error: table %s contains less indexes inside InnoDB\n"
+"InnoDB: than are defined in the MySQL .frm file. Have you mixed up\n"
+"InnoDB: .frm files from different installations? See section\n"
+"InnoDB: 15.1 at http://www.innodb.com/ibman.html\n",
+ ib_table->name);
+ break;
+ }
+
+ for (j = 0; j < table->key_info[i].key_parts; j++) {
+
+ if (j + 1 > index->n_uniq) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Error: index %s of %s has %lu columns unique inside InnoDB\n"
+"InnoDB: but MySQL is asking statistics for %lu columns. Have you mixed up\n"
+"InnoDB: .frm files from different installations? See section\n"
+"InnoDB: 15.1 at http://www.innodb.com/ibman.html\n",
+ index->name,
+ ib_table->name, index->n_uniq,
+ j + 1);
+ break;
+ }
+
+ if (index->stat_n_diff_key_vals[j + 1] == 0) {
+
+ rec_per_key = records;
+ } else {
+ rec_per_key = (ha_rows)(records /
+ index->stat_n_diff_key_vals[j + 1]);
+ }
+
+ /* Since MySQL seems to favor table scans
+ too much over index searches, we pretend
+ index selectivity is 2 times better than
+ our estimate: */
+
+ rec_per_key = rec_per_key / 2;
+
+ if (rec_per_key == 0) {
+ rec_per_key = 1;
+ }
+
+ table->key_info[i].rec_per_key[j]=
+ rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
+ rec_per_key;
+ }
+
+ index = dict_table_get_next_index_noninline(index);
+ }
+ }
+
+ if (flag & HA_STATUS_ERRKEY) {
+ ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
+
+ errkey = (unsigned int) row_get_mysql_key_number_for_index(
+ (dict_index_t*)
+ trx_get_error_info(prebuilt->trx));
+ }
+
+ prebuilt->trx->op_info = (char*)"";
+
+ DBUG_VOID_RETURN;
+}
+
+/**************************************************************************
+Updates index cardinalities of the table, based on 10 random dives into
+each index tree. This does NOT calculate exact statistics of the table. */
+
+int
+ha_innobase::analyze(
+/*=================*/
+ /* out: returns always 0 (success) */
+ THD* thd, /* in: connection thread handle */
+ HA_CHECK_OPT* check_opt) /* in: currently ignored */
+{
+ /* Simply call ::info() with all the flags */
+ info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+
+ return(0);
+}
+
+
+int ha_innobase::optimize(THD* thd, HA_CHECK_OPT* check_opt)
+{
+ return ha_innobase::analyze(thd,check_opt);
+}
+
+/***********************************************************************
+Tries to check that an InnoDB table is not corrupted. If corruption is
+noticed, prints to stderr information about it. In case of corruption
+may also assert a failure and crash the server. */
+
+int
+ha_innobase::check(
+/*===============*/
+ /* out: HA_ADMIN_CORRUPT or
+ HA_ADMIN_OK */
+ THD* thd, /* in: user thread handle */
+ HA_CHECK_OPT* check_opt) /* in: check options, currently
+ ignored */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ ulint ret;
+
+ ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
+ if (prebuilt->mysql_template == NULL) {
+ /* Build the template; we will use a dummy template
+ in index scans done in checking */
+
+ build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
+ }
+
+ ret = row_check_table_for_mysql(prebuilt);
+
+ if (ret == DB_SUCCESS) {
+ return(HA_ADMIN_OK);
+ }
+
+ return(HA_ADMIN_CORRUPT);
+}
+
+/*****************************************************************
+Adds information about free space in the InnoDB tablespace to a table comment
+which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
+foreign keys. */
+
+char*
+ha_innobase::update_table_comment(
+/*==============================*/
+ /* out: table comment + InnoDB free space +
+ info on foreign keys */
+ const char* comment)/* in: table comment defined by user */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ uint length = strlen(comment);
+ char* str = my_malloc(length + 16500, MYF(0));
+ char* pos;
+
+ /* We do not know if MySQL can call this function before calling
+ external_lock(). To be safe, update the thd of the current table
+ handle. */
+
+ update_thd(current_thd);
+
+ prebuilt->trx->op_info = (char*)"returning table comment";
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
+
+ if (!str) {
+ prebuilt->trx->op_info = (char*)"";
+
+ return((char*)comment);
+ }
+
+ pos = str;
+ if (length) {
+ pos=strmov(str, comment);
+ *pos++=';';
+ *pos++=' ';
+ }
+
+ pos += my_sprintf(pos,
+ (pos,"InnoDB free: %lu kB",
+ (ulong) innobase_get_free_space()));
+
+ /* We assume 16000 - length bytes of space to print info; the limit
+ 16000 bytes is arbitrary, and MySQL could handle at least 64000
+ bytes */
+
+ if (length < 16000) {
+ dict_print_info_on_foreign_keys(FALSE, pos, 16000 - length,
+ prebuilt->table);
+ }
+
+ prebuilt->trx->op_info = (char*)"";
+
+ return(str);
+}
+
+/***********************************************************************
+Gets the foreign key create info for a table stored in InnoDB. */
+
+char*
+ha_innobase::get_foreign_key_create_info(void)
+/*==========================================*/
+ /* out, own: character string in the form which
+ can be inserted to the CREATE TABLE statement,
+ MUST be freed with ::free_foreign_key_create_info */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ char* str;
+
+ ut_a(prebuilt != NULL);
+
+ /* We do not know if MySQL can call this function before calling
+ external_lock(). To be safe, update the thd of the current table
+ handle. */
+
+ update_thd(current_thd);
+
+ prebuilt->trx->op_info = (char*)"getting info on foreign keys";
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
+
+ str = (char*)ut_malloc(10000);
+
+ str[0] = '\0';
+
+ dict_print_info_on_foreign_keys(TRUE, str, 9000, prebuilt->table);
+
+ prebuilt->trx->op_info = (char*)"";
+
+ return(str);
+}
+
+/***********************************************************************
+Frees the foreign key create info for a table stored in InnoDB, if it is
+non-NULL. */
+
+void
+ha_innobase::free_foreign_key_create_info(
+/*======================================*/
+ char* str) /* in, own: create info string to free */
+{
+ if (str) {
+ ut_free(str);
+ }
+}
+
+/***********************************************************************
+Tells something additional to the handler about how to do things. */
+
+int
+ha_innobase::extra(
+/*===============*/
+ /* out: 0 or error number */
+ enum ha_extra_function operation)
+ /* in: HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ /* Warning: since it is not sure that MySQL calls external_lock
+ before calling this function, the trx field in prebuilt can be
+ obsolete! */
+
+ switch (operation) {
+ case HA_EXTRA_RESET:
+ case HA_EXTRA_RESET_STATE:
+ prebuilt->read_just_key = 0;
+ break;
+ case HA_EXTRA_NO_KEYREAD:
+ prebuilt->read_just_key = 0;
+ break;
+ case HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE:
+ prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
+ break;
+ case HA_EXTRA_KEYREAD:
+ prebuilt->read_just_key = 1;
+ break;
+ default:/* Do nothing */
+ ;
+ }
+
+ return(0);
+}
+
+/**********************************************************************
+????????????? */
+
+int
+ha_innobase::reset(void)
+/*====================*/
+{
+ return(0);
+}
+
+/**********************************************************************
+MySQL calls this function at the start of each SQL statement inside LOCK
+TABLES. Inside LOCK TABLES the ::external_lock method does not work to
+mark SQL statement borders. Note also a special case: if a temporary table
+is created inside LOCK TABLES, MySQL has not called external_lock() at all
+on that table. */
+
+int
+ha_innobase::start_stmt(
+/*====================*/
+ /* out: 0 or error code */
+ THD* thd) /* in: handle to the user thread */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ trx_t* trx;
+
+ update_thd(thd);
+
+ trx = prebuilt->trx;
+
+ /* Here we release the search latch and the InnoDB thread FIFO ticket
+ if they were reserved. They should have been released already at the
+ end of the previous statement, but because inside LOCK TABLES the
+ lock count method does not work to mark the end of a SELECT statement,
+ that may not be the case. We MUST release the search latch before an
+ INSERT, for example. */
+
+ innobase_release_stat_resources(trx);
+
+ if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
+ && trx->read_view) {
+ /* At low transaction isolation levels we let
+ each consistent read set its own snapshot */
+
+ read_view_close_for_mysql(trx);
+ }
+
+ auto_inc_counter_for_this_stat = 0;
+ prebuilt->sql_stat_start = TRUE;
+ prebuilt->hint_no_need_to_fetch_extra_cols = TRUE;
+ prebuilt->read_just_key = 0;
+
+ if (!prebuilt->mysql_has_locked) {
+ /* This handle is for a temporary table created inside
+ this same LOCK TABLES; since MySQL does NOT call external_lock
+ in this case, we must use x-row locks inside InnoDB to be
+ prepared for an update of a row */
+
+ prebuilt->select_lock_type = LOCK_X;
+ }
+
+ /* Set the MySQL flag to mark that there is an active transaction */
+ thd->transaction.all.innodb_active_trans = 1;
+
+ return(0);
+}
+
+/**********************************************************************
+Maps a MySQL trx isolation level code to the InnoDB isolation level code */
+inline
+ulint
+innobase_map_isolation_level(
+/*=========================*/
+ /* out: InnoDB isolation level */
+ enum_tx_isolation iso) /* in: MySQL isolation level code */
+{
+ switch(iso) {
+ case ISO_REPEATABLE_READ: return(TRX_ISO_REPEATABLE_READ);
+ case ISO_READ_COMMITTED: return(TRX_ISO_READ_COMMITTED);
+ case ISO_SERIALIZABLE: return(TRX_ISO_SERIALIZABLE);
+ case ISO_READ_UNCOMMITTED: return(TRX_ISO_READ_UNCOMMITTED);
+ default: ut_a(0); return(0);
+ }
+}
+
+/**********************************************************************
+As MySQL will execute an external lock for every new table it uses when it
+starts to process an SQL statement (an exception is when MySQL calls
+start_stmt for the handle) we can use this function to store the pointer to
+the THD in the handle. We will also use this function to communicate
+to InnoDB that a new SQL statement has started and that we must store a
+savepoint to our transaction handle, so that we are able to roll back
+the SQL statement in case of an error. */
+
+int
+ha_innobase::external_lock(
+/*=======================*/
+ /* out: 0 or error code */
+ THD* thd, /* in: handle to the user thread */
+ int lock_type) /* in: lock type */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ int error = 0;
+ trx_t* trx;
+
+ DBUG_ENTER("ha_innobase::external_lock");
+ DBUG_PRINT("enter",("lock_type: %d", lock_type));
+
+ update_thd(thd);
+
+ trx = prebuilt->trx;
+
+ prebuilt->sql_stat_start = TRUE;
+ prebuilt->hint_no_need_to_fetch_extra_cols = TRUE;
+
+ prebuilt->read_just_key = 0;
+
+ if (lock_type == F_WRLCK) {
+
+ /* If this is a SELECT, then it is in UPDATE TABLE ...
+ or SELECT ... FOR UPDATE */
+ prebuilt->select_lock_type = LOCK_X;
+ }
+
+ if (lock_type != F_UNLCK) {
+ /* MySQL is setting a new table lock */
+
+ /* Set the MySQL flag to mark that there is an active
+ transaction */
+ thd->transaction.all.innodb_active_trans = 1;
+
+ trx->n_mysql_tables_in_use++;
+ prebuilt->mysql_has_locked = TRUE;
+
+ if (trx->n_mysql_tables_in_use == 1) {
+ trx->isolation_level = innobase_map_isolation_level(
+ (enum_tx_isolation)
+ thd->variables.tx_isolation);
+ }
+
+ if (trx->isolation_level == TRX_ISO_SERIALIZABLE
+ && prebuilt->select_lock_type == LOCK_NONE) {
+
+ /* To get serializable execution we let InnoDB
+ conceptually add 'LOCK IN SHARE MODE' to all SELECTs
+ which otherwise would have been consistent reads */
+
+ prebuilt->select_lock_type = LOCK_S;
+ }
+
+ if (prebuilt->select_lock_type != LOCK_NONE) {
+
+ trx->mysql_n_tables_locked++;
+ }
+
+ DBUG_RETURN(error);
+ }
+
+ /* MySQL is releasing a table lock */
+
+ trx->n_mysql_tables_in_use--;
+ prebuilt->mysql_has_locked = FALSE;
+ auto_inc_counter_for_this_stat = 0;
+
+ /* If the MySQL lock count drops to zero we know that the current SQL
+ statement has ended */
+
+ if (trx->n_mysql_tables_in_use == 0) {
+
+ trx->mysql_n_tables_locked = 0;
+ prebuilt->used_in_HANDLER = FALSE;
+
+ /* Release a possible FIFO ticket and search latch. Since we
+ may reserve the kernel mutex, we have to release the search
+ system latch first to obey the latching order. */
+
+ innobase_release_stat_resources(trx);
+
+ if (!(thd->options
+ & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
+ if (thd->transaction.all.innodb_active_trans != 0) {
+ innobase_commit(thd, trx);
+ }
+ } else {
+ if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
+ && trx->read_view) {
+
+ /* At low transaction isolation levels we let
+ each consistent read set its own snapshot */
+
+ read_view_close_for_mysql(trx);
+ }
+ }
+ }
+
+ DBUG_RETURN(error);
+}
+
+/****************************************************************************
+Implements the SHOW INNODB STATUS command. Send the output of the InnoDB
+Monitor to the client. */
+
+int
+innodb_show_status(
+/*===============*/
+ THD* thd) /* in: the MySQL query thread of the caller */
+{
+ String* packet = &thd->packet;
+ char* buf;
+ trx_t* trx;
+
+ DBUG_ENTER("innodb_show_status");
+
+ if (innodb_skip) {
+ my_message(ER_NOT_SUPPORTED_YET,
+ "Cannot call SHOW INNODB STATUS because skip-innodb is defined",
+ MYF(0));
+ DBUG_RETURN(-1);
+ }
+
+ trx = check_trx_exists(thd);
+
+ innobase_release_stat_resources(trx);
+
+ /* We let the InnoDB Monitor to output at most 60 kB of text, add
+ a safety margin of 100 kB for buffer overruns */
+
+ buf = (char*)ut_malloc(160 * 1024);
+
+ srv_sprintf_innodb_monitor(buf, 60 * 1024);
+
+ List<Item> field_list;
+
+ field_list.push_back(new Item_empty_string("Status", strlen(buf)));
+
+ if (send_fields(thd, field_list, 1)) {
+
+ ut_free(buf);
+
+ DBUG_RETURN(-1);
+ }
+
+ packet->length(0);
+
+ net_store_data(packet, buf);
+
+ if (my_net_write(&thd->net, (char*)thd->packet.ptr(),
+ packet->length())) {
+ ut_free(buf);
+
+ DBUG_RETURN(-1);
+ }
+
+ ut_free(buf);
+
+ send_eof(&thd->net);
+
+ DBUG_RETURN(0);
+}
+
+/****************************************************************************
+ Handling the shared INNOBASE_SHARE structure that is needed to provide table
+ locking.
+****************************************************************************/
+
+static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
+ my_bool not_used __attribute__((unused)))
+{
+ *length=share->table_name_length;
+ return (mysql_byte*) share->table_name;
+}
+
+static INNOBASE_SHARE *get_share(const char *table_name)
+{
+ INNOBASE_SHARE *share;
+ pthread_mutex_lock(&innobase_mutex);
+ uint length=(uint) strlen(table_name);
+ if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables,
+ (mysql_byte*) table_name,
+ length)))
+ {
+ if ((share=(INNOBASE_SHARE *) my_malloc(sizeof(*share)+length+1,
+ MYF(MY_WME | MY_ZEROFILL))))
+ {
+ share->table_name_length=length;
+ share->table_name=(char*) (share+1);
+ strmov(share->table_name,table_name);
+ if (hash_insert(&innobase_open_tables, (mysql_byte*) share))
+ {
+ pthread_mutex_unlock(&innobase_mutex);
+ my_free((gptr) share,0);
+ return 0;
+ }
+ thr_lock_init(&share->lock);
+ pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
+ }
+ }
+ share->use_count++;
+ pthread_mutex_unlock(&innobase_mutex);
+ return share;
+}
+
+static void free_share(INNOBASE_SHARE *share)
+{
+ pthread_mutex_lock(&innobase_mutex);
+ if (!--share->use_count)
+ {
+ hash_delete(&innobase_open_tables, (mysql_byte*) share);
+ thr_lock_delete(&share->lock);
+ pthread_mutex_destroy(&share->mutex);
+ my_free((gptr) share, MYF(0));
+ }
+ pthread_mutex_unlock(&innobase_mutex);
+}
+
+/*********************************************************************
+Converts a MySQL table lock stored in the 'lock' field of the handle to
+a proper type before storing pointer to the lock into an array of pointers.
+MySQL also calls this if it wants to reset some table locks to a not-locked
+state during the processing of an SQL query. An example is that during a
+SELECT the read lock is released early on the 'const' tables where we only
+fetch one row. MySQL does not call this when it releases all locks at the
+end of an SQL statement. */
+
+THR_LOCK_DATA**
+ha_innobase::store_lock(
+/*====================*/
+ /* out: pointer to the next
+ element in the 'to' array */
+ THD* thd, /* in: user thread handle */
+ THR_LOCK_DATA** to, /* in: pointer to an array
+ of pointers to lock structs;
+ pointer to the 'lock' field
+ of current handle is stored
+ next to this array */
+ enum thr_lock_type lock_type) /* in: lock type to store in
+ 'lock' */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ if (lock_type == TL_READ_WITH_SHARED_LOCKS ||
+ lock_type == TL_READ_NO_INSERT) {
+ /* This is a SELECT ... IN SHARE MODE, or
+ we are doing a complex SQL statement like
+ INSERT INTO ... SELECT ... and the logical logging (MySQL
+ binlog) requires the use of a locking read */
+
+ prebuilt->select_lock_type = LOCK_S;
+ } else if (lock_type != TL_IGNORE) {
+
+ /* In ha_berkeley.cc there is a comment that MySQL
+ may in exceptional cases call this with TL_IGNORE also
+ when it is NOT going to release the lock. */
+
+ /* We set possible LOCK_X value in external_lock, not yet
+ here even if this would be SELECT ... FOR UPDATE */
+
+ prebuilt->select_lock_type = LOCK_NONE;
+ }
+
+ if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
+
+ /* If we are not doing a LOCK TABLE, then allow multiple
+ writers */
+
+ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
+ lock_type <= TL_WRITE) && !thd->in_lock_tables) {
+
+ lock_type = TL_WRITE_ALLOW_WRITE;
+ }
+
+ /* In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
+ MySQL would use the lock TL_READ_NO_INSERT on t2, and that
+ would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
+ to t2. Convert the lock to a normal read lock to allow
+ concurrent inserts to t2. */
+
+ if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) {
+ lock_type = TL_READ;
+ }
+
+ lock.type=lock_type;
+ }
+
+ *to++= &lock;
+
+ return(to);
+}
+
+/***********************************************************************
+This function initializes the auto-inc counter if it has not been
+initialized yet. This function does not change the value of the auto-inc
+counter if it already has been initialized. In parameter ret returns
+the value of the auto-inc counter. */
+
+int
+ha_innobase::innobase_read_and_init_auto_inc(
+/*=========================================*/
+ /* out: 0 or error code: deadlock or
+ lock wait timeout */
+ longlong* ret) /* out: auto-inc value */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ longlong auto_inc;
+ int error;
+
+ ut_a(prebuilt);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+ ut_a(prebuilt->table);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
+
+ auto_inc = dict_table_autoinc_read(prebuilt->table);
+
+ if (auto_inc != 0) {
+ /* Already initialized */
+ *ret = auto_inc;
+
+ return(0);
+ }
+
+ error = row_lock_table_autoinc_for_mysql(prebuilt);
+
+ if (error != DB_SUCCESS) {
+ error = convert_error_code_to_mysql(error, user_thd);
+
+ goto func_exit;
+ }
+
+ /* Check again if someone has initialized the counter meanwhile */
+ auto_inc = dict_table_autoinc_read(prebuilt->table);
+
+ if (auto_inc != 0) {
+ *ret = auto_inc;
+
+ return(0);
+ }
+
+ (void) extra(HA_EXTRA_KEYREAD);
+ index_init(table->next_number_index);
+
+ /* We use an exclusive lock when we read the max key value from the
+ auto-increment column index. This is because then build_template will
+ advise InnoDB to fetch all columns. In SHOW TABLE STATUS the query
+ id of the auto-increment column is not changed, and previously InnoDB
+ did not fetch it, causing SHOW TABLE STATUS to show wrong values
+ for the autoinc column. */
+
+ prebuilt->select_lock_type = LOCK_X;
+
+ /* Play safe and also give in another way the hint to fetch
+ all columns in the key: */
+
+ prebuilt->hint_no_need_to_fetch_extra_cols = FALSE;
+
+ prebuilt->trx->mysql_n_tables_locked += 1;
+
+ error = index_last(table->record[1]);
+
+ if (error) {
+ if (error == HA_ERR_END_OF_FILE) {
+ /* The table was empty, initialize to 1 */
+ auto_inc = 1;
+
+ error = 0;
+ } else {
+ /* Deadlock or a lock wait timeout */
+ auto_inc = -1;
+
+ goto func_exit;
+ }
+ } else {
+ /* Initialize to max(col) + 1 */
+ auto_inc = (longlong) table->next_number_field->
+ val_int_offset(table->rec_buff_length) + 1;
+ }
+
+ dict_table_autoinc_initialize(prebuilt->table, auto_inc);
+
+func_exit:
+ (void) extra(HA_EXTRA_NO_KEYREAD);
+
+ index_end();
+
+ *ret = auto_inc;
+
+ return(error);
+}
+
+/***********************************************************************
+This function initializes the auto-inc counter if it has not been
+initialized yet. This function does not change the value of the auto-inc
+counter if it already has been initialized. Returns the value of the
+auto-inc counter. */
+
+longlong
+ha_innobase::get_auto_increment()
+/*=============================*/
+ /* out: auto-increment column value, -1 if error
+ (deadlock or lock wait timeout) */
+{
+ longlong nr;
+ int error;
+
+ error = innobase_read_and_init_auto_inc(&nr);
+
+ if (error) {
+
+ return(-1);
+ }
+
+ return(nr);
+}
+
+#endif /* HAVE_INNOBASE_DB */
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
new file mode 100644
index 00000000000..8a51019b18e
--- /dev/null
+++ b/sql/ha_innodb.h
@@ -0,0 +1,240 @@
+/* Copyright (C) 2000 MySQL AB && Innobase Oy
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ This file is based on ha_berkeley.h of MySQL distribution
+
+ This file defines the Innodb handler: the interface between MySQL and
+ Innodb
+*/
+
+#ifdef __GNUC__
+#pragma interface /* gcc class implementation */
+#endif
+
+typedef struct st_innobase_share {
+ THR_LOCK lock;
+ pthread_mutex_t mutex;
+ char *table_name;
+ uint table_name_length,use_count;
+} INNOBASE_SHARE;
+
+/* The class defining a handle to an Innodb table */
+class ha_innobase: public handler
+{
+ void* innobase_prebuilt; /* (row_prebuilt_t*) prebuilt
+ struct in Innodb, used to save
+ CPU */
+ THD* user_thd; /* the thread handle of the user
+ currently using the handle; this is
+ set in external_lock function */
+ ulong last_query_id; /* the latest query id where the
+ handle was used */
+ THR_LOCK_DATA lock;
+ INNOBASE_SHARE *share;
+
+ gptr alloc_ptr;
+ byte* upd_buff; /* buffer used in updates */
+ byte* key_val_buff; /* buffer used in converting
+ search key values from MySQL format
+ to Innodb format */
+ ulong upd_and_key_val_buff_len;
+ /* the length of each of the previous
+ two buffers */
+ ulong int_table_flags;
+ uint primary_key;
+ uint last_dup_key;
+ ulong start_of_scan; /* this is set to 1 when we are
+ starting a table scan but have not
+ yet fetched any row, else 0 */
+ uint active_index_before_scan;
+ /* since a table scan in InnoDB is
+ always done through an index, a table
+ scan may change active_index; but
+ MySQL may assume that active_index
+ after a table scan is the same as
+ before; we store the value here so
+ that we can restore the value after
+ a scan */
+ uint last_match_mode;/* match mode of the latest search:
+ ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
+ or undefined */
+ longlong auto_inc_counter_for_this_stat;
+ ulong max_row_length(const byte *buf);
+
+ uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
+ const byte* record);
+ int update_thd(THD* thd);
+ int change_active_index(uint keynr);
+ int general_fetch(byte* buf, uint direction, uint match_mode);
+ int innobase_read_and_init_auto_inc(longlong* ret);
+
+ /* Init values for the class: */
+ public:
+ ha_innobase(TABLE *table): handler(table),
+ int_table_flags(HA_REC_NOT_IN_SEQ |
+ HA_KEYPOS_TO_RNDPOS |
+ HA_LASTKEY_ORDER |
+ HA_NULL_KEY |
+ HA_BLOB_KEY |
+ HA_CAN_SQL_HANDLER |
+ HA_NOT_EXACT_COUNT |
+ HA_NO_WRITE_DELAYED |
+ HA_PRIMARY_KEY_IN_READ_INDEX |
+ HA_DROP_BEFORE_CREATE |
+ HA_TABLE_SCAN_ON_INDEX),
+ last_dup_key((uint) -1),
+ start_of_scan(0)
+ {
+ }
+ ~ha_innobase() {}
+
+ const char* table_type() const { return("InnoDB");}
+ const char *index_type(uint key_number) { return "BTREE"; }
+ const char** bas_ext() const;
+ ulong table_flags() const { return int_table_flags; }
+ ulong index_flags(uint idx) const
+ {
+ return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER |
+ HA_KEY_READ_ONLY);
+ }
+ uint max_record_length() const { return HA_MAX_REC_LENGTH; }
+ uint max_keys() const { return MAX_KEY; }
+ uint max_key_parts() const { return MAX_REF_PARTS; }
+ /* An InnoDB page must store >= 2 keys;
+ a secondary key record must also contain the
+ primary key value:
+ max key length is therefore set to slightly
+ less than 1 / 4 of page size which is 16 kB;
+ but currently MySQL does not work with keys
+ whose size is > MAX_KEY_LENGTH */
+ uint max_key_length() const { return((MAX_KEY_LENGTH <= 3500) ?
+ MAX_KEY_LENGTH : 3500);}
+ bool fast_key_read() { return 1;}
+ key_map keys_to_use_for_scanning() { return ~(key_map) 0; }
+ bool has_transactions() { return 1;}
+
+ int open(const char *name, int mode, uint test_if_locked);
+ void initialize(void);
+ int close(void);
+ double scan_time();
+ double read_time(uint index, uint ranges, ha_rows rows);
+
+ int write_row(byte * buf);
+ int update_row(const byte * old_data, byte * new_data);
+ int delete_row(const byte * buf);
+
+ int index_init(uint index);
+ int index_end();
+ int index_read(byte * buf, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag);
+ int index_read_idx(byte * buf, uint index, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
+ int index_next(byte * buf);
+ int index_next_same(byte * buf, const byte *key, uint keylen);
+ int index_prev(byte * buf);
+ int index_first(byte * buf);
+ int index_last(byte * buf);
+
+ int rnd_init(bool scan=1);
+ int rnd_end();
+ int rnd_next(byte *buf);
+ int rnd_pos(byte * buf, byte *pos);
+
+ void position(const byte *record);
+ void info(uint);
+ int analyze(THD* thd,HA_CHECK_OPT* check_opt);
+ int optimize(THD* thd,HA_CHECK_OPT* check_opt);
+ int extra(enum ha_extra_function operation);
+ int reset(void);
+ int external_lock(THD *thd, int lock_type);
+ int start_stmt(THD *thd);
+
+ void position(byte *record);
+ ha_rows records_in_range(int inx,
+ const byte *start_key,uint start_key_len,
+ enum ha_rkey_function start_search_flag,
+ const byte *end_key,uint end_key_len,
+ enum ha_rkey_function end_search_flag);
+ ha_rows estimate_number_of_rows();
+
+ int create(const char *name, register TABLE *form,
+ HA_CREATE_INFO *create_info);
+ int delete_table(const char *name);
+ int rename_table(const char* from, const char* to);
+ int check(THD* thd, HA_CHECK_OPT* check_opt);
+ char* update_table_comment(const char* comment);
+ char* get_foreign_key_create_info();
+ void free_foreign_key_create_info(char* str);
+ THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
+ enum thr_lock_type lock_type);
+ void init_table_handle_for_HANDLER();
+ longlong get_auto_increment();
+};
+
+extern bool innodb_skip;
+extern uint innobase_init_flags, innobase_lock_type;
+extern uint innobase_flush_log_at_trx_commit;
+extern ulong innobase_cache_size;
+extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
+extern long innobase_lock_scan_time;
+extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
+extern long innobase_log_file_size, innobase_log_buffer_size;
+extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
+extern long innobase_file_io_threads, innobase_lock_wait_timeout;
+extern long innobase_force_recovery, innobase_thread_concurrency;
+extern char *innobase_data_home_dir, *innobase_data_file_path;
+extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
+extern char *innobase_unix_file_flush_method;
+/* The following variables have to be my_bool for SHOW VARIABLES to work */
+extern my_bool innobase_log_archive,
+ innobase_use_native_aio, innobase_fast_shutdown;
+extern "C" {
+extern ulong srv_max_buf_pool_modified_pct;
+}
+
+extern TYPELIB innobase_lock_typelib;
+
+bool innobase_init(void);
+bool innobase_end(void);
+bool innobase_flush_logs(void);
+uint innobase_get_free_space(void);
+
+int innobase_commit(THD *thd, void* trx_handle);
+int innobase_report_binlog_offset_and_commit(
+ THD* thd,
+ void* trx_handle,
+ char* log_file_name,
+ my_off_t end_offset);
+int innobase_commit_complete(
+ void* trx_handle);
+int innobase_rollback(THD *thd, void* trx_handle);
+int innobase_rollback_to_savepoint(
+ THD* thd,
+ char* savepoint_name,
+ my_off_t* binlog_cache_pos);
+int innobase_savepoint(
+ THD* thd,
+ char* savepoint_name,
+ my_off_t binlog_cache_pos);
+int innobase_close_connection(THD *thd);
+int innobase_drop_database(char *path);
+int innodb_show_status(THD* thd);
+
+my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name,
+ uint full_name_len);
+void innobase_release_temporary_latches(void* innobase_tid);
diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc
index ac37d09e6b4..a93bb25eb77 100644
--- a/sql/ha_isam.cc
+++ b/sql/ha_isam.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,6 +20,7 @@
#endif
#include "mysql_priv.h"
+#ifdef HAVE_ISAM
#include <m_ctype.h>
#include <myisampack.h>
#include "ha_isam.h"
@@ -34,7 +35,7 @@
*****************************************************************************/
const char **ha_isam::bas_ext() const
-{ static const char *ext[]= { ".ISD",".ISM", NullS }; return ext; }
+{ static const char *ext[]= { ".ISM",".ISD", NullS }; return ext; }
int ha_isam::open(const char *name, int mode, uint test_if_locked)
@@ -51,7 +52,7 @@ int ha_isam::open(const char *name, int mode, uint test_if_locked)
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
(void) nisam_extra(file,HA_EXTRA_WAIT_LOCK);
if (!table->db_record_offset)
- int_option_flag|=HA_REC_NOT_IN_SEQ;
+ int_table_flags|=HA_REC_NOT_IN_SEQ;
return (0);
}
@@ -108,6 +109,15 @@ int ha_isam::index_read_idx(byte * buf, uint index, const byte * key,
return !error ? 0 : my_errno ? my_errno : -1;
}
+int ha_isam::index_read_last(byte * buf, const byte * key, uint key_len)
+{
+ statistic_increment(ha_read_key_count,&LOCK_status);
+ int error=nisam_rkey(file, buf, active_index, key, key_len,
+ HA_READ_PREFIX_LAST);
+ table->status=error ? STATUS_NOT_FOUND: 0;
+ return !error ? 0 : my_errno ? my_errno : -1;
+}
+
int ha_isam::index_next(byte * buf)
{
statistic_increment(ha_read_next_count,&LOCK_status);
@@ -123,7 +133,7 @@ int ha_isam::index_prev(byte * buf)
table->status=error ? STATUS_NOT_FOUND: 0;
return !error ? 0 : my_errno ? my_errno : HA_ERR_END_OF_FILE;
}
-
+
int ha_isam::index_first(byte * buf)
{
statistic_increment(ha_read_first_count,&LOCK_status);
@@ -234,8 +244,10 @@ int ha_isam::reset(void)
int ha_isam::external_lock(THD *thd, int lock_type)
{
- return nisam_lock_database(file,lock_type);
-}
+ if (!table->tmp_table)
+ return nisam_lock_database(file,lock_type);
+ return 0;
+}
THR_LOCK_DATA **ha_isam::store_lock(THD *thd,
@@ -266,7 +278,7 @@ int ha_isam::create(const char *name, register TABLE *form,
type=HA_KEYTYPE_BINARY; // Keep compiler happy
if (!(recinfo= (N_RECINFO*) my_malloc((form->fields*2+2)*sizeof(N_RECINFO),
MYF(MY_WME))))
- DBUG_RETURN(1);
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
pos=form->key_info;
for (i=0; i < form->keys ; i++, pos++)
@@ -315,7 +327,7 @@ int ha_isam::create(const char *name, register TABLE *form,
{
/* skip null fields */
if (!(temp_length= (*field)->pack_length()))
- continue; /* Skipp null-fields */
+ continue; /* Skip null-fields */
if (! found || fieldpos < minpos ||
(fieldpos == minpos && temp_length < length))
{
@@ -343,15 +355,15 @@ int ha_isam::create(const char *name, register TABLE *form,
else if (!(options & HA_OPTION_PACK_RECORD))
recinfo_pos->base.type= (int) FIELD_NORMAL;
else if (found->zero_pack())
- recinfo_pos->base.type= (int) FIELD_SKIPP_ZERO;
+ recinfo_pos->base.type= (int) FIELD_SKIP_ZERO;
else
recinfo_pos->base.type= (int) ((length <= 3 ||
(found->flags & ZEROFILL_FLAG)) ?
FIELD_NORMAL :
found->type() == FIELD_TYPE_STRING ||
found->type() == FIELD_TYPE_VAR_STRING ?
- FIELD_SKIPP_ENDSPACE :
- FIELD_SKIPP_PRESPACE);
+ FIELD_SKIP_ENDSPACE :
+ FIELD_SKIP_PRESPACE);
recinfo_pos++ ->base.length=(uint16) length;
recpos=minpos+length;
DBUG_PRINT("loop",("length: %d type: %d",
@@ -368,7 +380,8 @@ int ha_isam::create(const char *name, register TABLE *form,
}
recinfo_pos->base.type= (int) FIELD_LAST; /* End of fieldinfo */
error=nisam_create(fn_format(buff,name,"","",2+4+16),form->keys,keydef,
- recinfo,form->max_rows,form->min_rows,0,0,0L);
+ recinfo,(ulong) form->max_rows, (ulong) form->min_rows,
+ 0, 0, 0L);
my_free((gptr) recinfo,MYF(0));
DBUG_RETURN(error);
@@ -388,3 +401,4 @@ ha_rows ha_isam::records_in_range(int inx,
end_key,end_key_len,
end_search_flag);
}
+#endif /* HAVE_ISAM */
diff --git a/sql/ha_isam.h b/sql/ha_isam.h
index 5e01edcf889..b573d4b295c 100644
--- a/sql/ha_isam.h
+++ b/sql/ha_isam.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -26,20 +26,21 @@
class ha_isam: public handler
{
N_INFO *file;
- uint int_option_flag;
+ /* We need this as table_flags() may change after open() */
+ ulong int_table_flags;
public:
- ha_isam(TABLE *table): handler(table), file(0),
- int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME |
- HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
- HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY |
- HA_LONGLONG_KEYS | HA_KEY_READ_WRONG_STR | HA_DUPP_POS |
- HA_NOT_DELETE_WITH_CACHE | HA_NO_FULLTEXT_KEY)
- {}
+ ha_isam(TABLE *table)
+ :handler(table), file(0),
+ int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
+ HA_KEY_READ_WRONG_STR | HA_DUPP_POS |
+ HA_NOT_DELETE_WITH_CACHE | HA_FILE_BASED)
+ {}
~ha_isam() {}
const char *table_type() const { return "ISAM"; }
+ const char *index_type(uint key_number) { return "BTREE"; }
const char **bas_ext() const;
- ulong option_flag() const { return int_option_flag; }
+ ulong table_flags() const { return int_table_flags; }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return N_MAXKEY; }
uint max_key_parts() const { return N_MAXKEY_SEG; }
@@ -56,6 +57,7 @@ class ha_isam: public handler
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
int index_next(byte * buf);
int index_prev(byte * buf);
int index_first(byte * buf);
@@ -78,11 +80,4 @@ class ha_isam: public handler
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
-
};
-
-
-
-
-
-
diff --git a/sql/ha_isammrg.cc b/sql/ha_isammrg.cc
index dd2e4e2f723..94e394e7665 100644
--- a/sql/ha_isammrg.cc
+++ b/sql/ha_isammrg.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,11 +20,12 @@
#endif
#include "mysql_priv.h"
+#ifdef HAVE_ISAM
#include <m_ctype.h>
#ifndef MASTER
-#include "../srclib/merge/mrgdef.h"
+#include "../srclib/merge/mrg_def.h"
#else
-#include "../merge/mrgdef.h"
+#include "../merge/mrg_def.h"
#endif
#include "ha_isammrg.h"
@@ -109,7 +110,7 @@ int ha_isammrg::index_prev(byte * buf)
{
return (my_errno=HA_ERR_WRONG_COMMAND);
}
-
+
int ha_isammrg::index_first(byte * buf)
{
return (my_errno=HA_ERR_WRONG_COMMAND);
@@ -178,7 +179,7 @@ int ha_isammrg::reset(void)
int ha_isammrg::external_lock(THD *thd, int lock_type)
{
return !mrg_lock_database(file,lock_type) ? 0 : my_errno ? my_errno : -1;
-}
+}
uint ha_isammrg::lock_count(void) const
{
@@ -189,13 +190,15 @@ THR_LOCK_DATA **ha_isammrg::store_lock(THD *thd,
THR_LOCK_DATA **to,
enum thr_lock_type lock_type)
{
- MRG_TABLE *table;
+ MRG_TABLE *open_table;
- for (table=file->open_tables ; table != file->end_table ; table++)
+ for (open_table=file->open_tables ;
+ open_table != file->end_table ;
+ open_table++)
{
- *(to++)= &table->table->lock;
- if (lock_type != TL_IGNORE && table->table->lock.type == TL_UNLOCK)
- table->table->lock.type=lock_type;
+ *(to++)= &open_table->table->lock;
+ if (lock_type != TL_IGNORE && open_table->table->lock.type == TL_UNLOCK)
+ open_table->table->lock.type=lock_type;
}
return to;
}
@@ -208,3 +211,4 @@ int ha_isammrg::create(const char *name, register TABLE *form,
char buff[FN_REFLEN];
return mrg_create(fn_format(buff,name,"","",2+4+16),0);
}
+#endif /* HAVE_ISAM */
diff --git a/sql/ha_isammrg.h b/sql/ha_isammrg.h
index c8eb7dd9f69..e5846d20212 100644
--- a/sql/ha_isammrg.h
+++ b/sql/ha_isammrg.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -32,8 +32,10 @@ class ha_isammrg: public handler
~ha_isammrg() {}
const char *table_type() const { return "MRG_ISAM"; }
const char **bas_ext() const;
- ulong option_flag() const { return HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS
- | HA_REC_NOT_IN_SEQ | HA_NO_FULLTEXT_KEY;}
+ ulong table_flags() const { return (HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS |
+ HA_REC_NOT_IN_SEQ | HA_FILE_BASED); }
+ ulong index_flags(uint idx) const { return HA_NOT_READ_PREFIX_LAST; }
+
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return 0; }
uint max_key_parts() const { return 0; }
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index d0d68156bac..d630e9774a5 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -30,13 +30,12 @@
#include "../myisam/myisamdef.h"
#endif
-ulong myisam_sort_buffer_size;
ulong myisam_recover_options= HA_RECOVER_NONE;
/* bits in myisam_recover_options */
const char *myisam_recover_names[] =
{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS};
-TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"",
+TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
myisam_recover_names};
@@ -45,6 +44,7 @@ TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"",
*****************************************************************************/
// collect errors printed by mi_check routines
+
static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
const char *fmt, va_list args)
{
@@ -66,8 +66,7 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
sql_print_error(msgbuf);
return;
}
- if (param->testflag & (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR |
- T_AUTO_REPAIR))
+ if (param->testflag & (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR | T_AUTO_REPAIR))
{
my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
return;
@@ -80,9 +79,8 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
net_store_data(packet, msgbuf);
if (my_net_write(&thd->net, (char*)thd->packet.ptr(), thd->packet.length()))
- fprintf(stderr,
- "Failed on my_net_write, writing to stderr instead: %s\n",
- msgbuf);
+ sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
+ msgbuf);
return;
}
@@ -119,18 +117,25 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
}
const char **ha_myisam::bas_ext() const
-{ static const char *ext[]= { ".MYD",".MYI", NullS }; return ext; }
+{ static const char *ext[]= { ".MYI",".MYD", NullS }; return ext; }
+const char *ha_myisam::index_type(uint key_number)
+{
+ return ((table->key_info[key_number].flags & HA_FULLTEXT) ?
+ "FULLTEXT" :
+ "BTREE");
+}
+
int ha_myisam::net_read_dump(NET* net)
{
int data_fd = file->dfile;
int error = 0;
my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME));
- for(;;)
+ for (;;)
{
- uint packet_len = my_net_read(net);
+ ulong packet_len = my_net_read(net);
if (!packet_len)
break ; // end of file
if (packet_len == packet_error)
@@ -139,7 +144,7 @@ int ha_myisam::net_read_dump(NET* net)
error= -1;
goto err;
}
- if (my_write(data_fd, (byte*)net->read_pos, packet_len,
+ if (my_write(data_fd, (byte*)net->read_pos, (uint) packet_len,
MYF(MY_WME|MY_FNABP)))
{
error = errno;
@@ -165,7 +170,7 @@ int ha_myisam::dump(THD* thd, int fd)
int error = 0;
my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME));
- for(; bytes_to_read > 0;)
+ for (; bytes_to_read > 0;)
{
uint bytes = my_read(data_fd, buf, blocksize, MYF(MY_WME));
if (bytes == MY_FILE_ERROR)
@@ -212,12 +217,12 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
return (my_errno ? my_errno : -1);
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
- VOID(mi_extra(file,HA_EXTRA_NO_WAIT_LOCK));
+ VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
- VOID(mi_extra(file,HA_EXTRA_WAIT_LOCK));
+ VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
if (!table->db_record_offset)
- int_option_flag|=HA_REC_NOT_IN_SEQ;
+ int_table_flags|=HA_REC_NOT_IN_SEQ;
return (0);
}
@@ -283,7 +288,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
error = chk_key(&param, file);
if (!error)
{
- if ((!check_opt->quick &&
+ if ((!(param.testflag & T_QUICK) &&
((share->options &
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ||
(param.testflag & (T_EXTEND | T_MEDIUM)))) ||
@@ -324,7 +329,6 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
mi_mark_crashed(file);
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
}
- check_opt->retry_without_quick=param.retry_without_quick;
thd->proc_info=old_proc_info;
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
@@ -374,14 +378,14 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
char* backup_dir = thd->lex.backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char* table_name = table->real_name;
+ int error;
+ const char* errmsg;
DBUG_ENTER("restore");
- if (!fn_format(src_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64))
+ if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
+ MI_NAME_DEXT))
DBUG_RETURN(HA_ADMIN_INVALID);
- int error = 0;
- const char* errmsg = "";
-
if (my_copy(src_path, fn_format(dst_path, table->path, "",
MI_NAME_DEXT, 4), MYF(MY_WME)))
{
@@ -391,8 +395,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
}
tmp_check_opt.init();
- tmp_check_opt.quick = 1;
- tmp_check_opt.flags |= T_VERY_SILENT | T_CALC_CHECKSUM;
+ tmp_check_opt.flags |= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK;
DBUG_RETURN(repair(thd, &tmp_check_opt));
err:
@@ -404,7 +407,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
param.db_name = table->table_cache_key;
param.table_name = table->table_name;
param.testflag = 0;
- mi_check_print_error(&param,errmsg, errno );
+ mi_check_print_error(&param, errmsg, my_errno);
DBUG_RETURN(error);
}
}
@@ -415,17 +418,19 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
char* backup_dir = thd->lex.backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char* table_name = table->real_name;
- int error = 0;
- const char* errmsg = "";
-
- if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64))
+ int error;
+ const char *errmsg;
+ DBUG_ENTER("ha_myisam::backup");
+
+ if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir,
+ reg_ext))
{
errmsg = "Failed in fn_format() for .frm file (errno: %d)";
error = HA_ADMIN_INVALID;
goto err;
}
-
- if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4),
+
+ if (my_copy(fn_format(src_path, table->path,"", reg_ext, MY_UNPACK_FILENAME),
dst_path,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_DONT_OVERWRITE_FILE)))
{
@@ -434,14 +439,17 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
goto err;
}
- if (!fn_format(dst_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64))
+ /* Change extension */
+ if (!fn_format(dst_path, dst_path, "", MI_NAME_DEXT,
+ MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH))
{
errmsg = "Failed in fn_format() for .MYD file (errno: %d)";
error = HA_ADMIN_INVALID;
goto err;
}
- if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, 4),
+ if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT,
+ MY_UNPACK_FILENAME),
dst_path,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_DONT_OVERWRITE_FILE)))
{
@@ -449,8 +457,9 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
error= HA_ADMIN_FAILED;
goto err;
}
- return HA_ADMIN_OK;
-err:
+ DBUG_RETURN(HA_ADMIN_OK);
+
+ err:
{
MI_CHECK param;
myisamchk_init(&param);
@@ -459,8 +468,8 @@ err:
param.db_name = table->table_cache_key;
param.table_name = table->table_name;
param.testflag = 0;
- mi_check_print_error(&param, errmsg, my_errno);
- return error;
+ mi_check_print_error(&param,errmsg, my_errno);
+ DBUG_RETURN(error);
}
}
@@ -476,28 +485,27 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
myisamchk_init(&param);
param.thd = thd;
param.op_name = (char*) "repair";
- param.testflag = ((check_opt->flags & ~(T_EXTEND)) |
- T_SILENT | T_FORCE_CREATE |
+ param.testflag = ((check_opt->flags & ~(T_EXTEND)) |
+ T_SILENT | T_FORCE_CREATE | T_CALC_CHECKSUM |
(check_opt->flags & T_EXTEND ? T_REP : T_REP_BY_SORT));
- if (check_opt->quick)
- param.opt_rep_quick++;
param.sort_buffer_length= check_opt->sort_buffer_size;
start_records=file->state->records;
while ((error=repair(thd,param,0)) && param.retry_repair)
{
param.retry_repair=0;
- if (param.retry_without_quick && param.opt_rep_quick)
+ if (test_all_bits(param.testflag,
+ (uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
{
- param.opt_rep_quick=0;
- sql_print_error("Warning: Retrying repair of: '%s' without quick",
+ param.testflag&= ~T_RETRY_WITHOUT_QUICK;
+ sql_print_error("Note: Retrying repair of: '%s' without quick",
table->path);
continue;
}
- param.opt_rep_quick=0; // Safety
+ param.testflag&= ~T_QUICK;
if ((param.testflag & T_REP_BY_SORT))
{
param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
- sql_print_error("Warning: Retrying repair of: '%s' with keycache",
+ sql_print_error("Note: Retrying repair of: '%s' with keycache",
table->path);
continue;
}
@@ -507,7 +515,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
!(check_opt->flags & T_VERY_SILENT))
{
char llbuff[22],llbuff2[22];
- sql_print_error("Warning: Found %s of %s rows when repairing '%s'",
+ sql_print_error("Note: Found %s of %s rows when repairing '%s'",
llstr(file->state->records, llbuff),
llstr(start_records, llbuff2),
table->path);
@@ -525,8 +533,6 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
param.op_name = (char*) "optimize";
param.testflag = (check_opt->flags | T_SILENT | T_FORCE_CREATE |
T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
- if (check_opt->quick)
- param.opt_rep_quick++;
param.sort_buffer_length= check_opt->sort_buffer_size;
return repair(thd,param,1);
}
@@ -537,8 +543,8 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
int error=0;
uint local_testflag=param.testflag;
bool optimize_done= !optimize, statistics_done=0;
- char fixed_name[FN_REFLEN];
const char *old_proc_info=thd->proc_info;
+ char fixed_name[FN_REFLEN];
MYISAM_SHARE* share = file->s;
ha_rows rows= file->state->records;
DBUG_ENTER("ha_myisam::repair");
@@ -550,11 +556,11 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
param.thd=thd;
param.tmpdir=mysql_tmpdir;
param.out_flag=0;
- VOID(fn_format(fixed_name,file->filename,"",MI_NAME_IEXT,
- 4+ (param.opt_follow_links ? 16 : 0)));
+ strmov(fixed_name,file->filename);
// Don't lock tables if we have used LOCK TABLE
- if (!thd->locked_tables && mi_lock_database(file,F_WRLCK))
+ if (!thd->locked_tables &&
+ mi_lock_database(file, table->tmp_table ? F_EXTRA_LCK : F_WRLCK))
{
mi_check_print_error(&param,ER(ER_CANT_LOCK),my_errno);
DBUG_RETURN(HA_ADMIN_FAILED);
@@ -562,10 +568,10 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
if (!optimize ||
((file->state->del || share->state.split != file->state->records) &&
- (!param.opt_rep_quick ||
+ (!(param.testflag & T_QUICK) ||
!(share->state.changed & STATE_NOT_OPTIMIZED_KEYS))))
{
- ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
+ ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ?
((ulonglong) 1L << share->base.keys)-1 :
share->state.key_map);
uint testflag=param.testflag;
@@ -574,15 +580,31 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
{
local_testflag|= T_STATISTICS;
param.testflag|= T_STATISTICS; // We get this for free
- thd->proc_info="Repair by sorting";
statistics_done=1;
- error = mi_repair_by_sort(&param, file, fixed_name, param.opt_rep_quick);
+ if (current_thd->variables.myisam_repair_threads>1)
+ {
+ char buf[40];
+ /* TODO: respect myisam_repair_threads variable */
+ my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
+ thd->proc_info=buf;
+ error = mi_repair_parallel(&param, file, fixed_name,
+ param.testflag & T_QUICK);
+ thd->proc_info="Repair done"; // to reset proc_info, as
+ // it was pointing to local buffer
+ }
+ else
+ {
+ thd->proc_info="Repair by sorting";
+ error = mi_repair_by_sort(&param, file, fixed_name,
+ param.testflag & T_QUICK);
+ }
}
else
{
thd->proc_info="Repair with keycache";
param.testflag &= ~T_REP_BY_SORT;
- error= mi_repair(&param, file, fixed_name, param.opt_rep_quick);
+ error= mi_repair(&param, file, fixed_name,
+ param.testflag & T_QUICK);
}
param.testflag=testflag;
optimize_done=1;
@@ -654,12 +676,50 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
}
-/* Deactive all not unique index that can be recreated fast */
+/*
+ Deactive all not unique index that can be recreated fast
+
+ SYNOPSIS
+ deactivate_non_unique_index()
+ rows Rows to be inserted
+ 0 if we don't know
+ HA_POS_ERROR if we want to disable all keys
+*/
void ha_myisam::deactivate_non_unique_index(ha_rows rows)
{
- if (!(specialflag & SPECIAL_SAFE_MODE))
- mi_disable_non_unique_index(file,rows);
+ MYISAM_SHARE* share = file->s;
+ if (share->state.key_map == ((ulonglong) 1L << share->base.keys)-1)
+ {
+ if (!(specialflag & SPECIAL_SAFE_MODE))
+ {
+ if (rows == HA_POS_ERROR)
+ mi_extra(file, HA_EXTRA_NO_KEYS, 0);
+ else
+ {
+ /*
+ Only disable old index if the table was empty and we are inserting
+ a lot of rows.
+ We should not do this for only a few rows as this is slower and
+ we don't want to update the key statistics based of only a few rows.
+ */
+ if (file->state->records == 0 &&
+ (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
+ mi_disable_non_unique_index(file,rows);
+ else
+ {
+ mi_init_bulk_insert(file,
+ current_thd->variables.bulk_insert_buff_size,
+ rows);
+ table->bulk_insert= 1;
+ }
+ }
+ }
+ enable_activate_all_index=1;
+ info(HA_STATUS_CONST); // Read new key info
+ }
+ else
+ enable_activate_all_index=0;
}
@@ -669,21 +729,27 @@ bool ha_myisam::activate_all_index(THD *thd)
MI_CHECK param;
MYISAM_SHARE* share = file->s;
DBUG_ENTER("activate_all_index");
- if (share->state.key_map != set_bits(ulonglong, share->base.keys))
+
+ mi_end_bulk_insert(file);
+ table->bulk_insert= 0;
+ if (enable_activate_all_index &&
+ share->state.key_map != set_bits(ulonglong, share->base.keys))
{
const char *save_proc_info=thd->proc_info;
thd->proc_info="Creating index";
myisamchk_init(&param);
param.op_name = (char*) "recreating_index";
- param.testflag = (T_SILENT | T_REP_BY_SORT |
- T_CREATE_MISSING_KEYS | T_TRUST_HEADER);
+ param.testflag = (T_SILENT | T_REP_BY_SORT | T_QUICK |
+ T_CREATE_MISSING_KEYS);
param.myf_rw&= ~MY_WAIT_IF_FULL;
- param.sort_buffer_length= myisam_sort_buffer_size;
- param.opt_rep_quick++; // Don't copy data file
+ param.sort_buffer_length= thd->variables.myisam_sort_buff_size;
param.tmpdir=mysql_tmpdir;
error=repair(thd,param,0) != HA_ADMIN_OK;
+ info(HA_STATUS_CONST);
thd->proc_info=save_proc_info;
}
+ else
+ enable_activate_all_index=1;
DBUG_RETURN(error);
}
@@ -699,16 +765,16 @@ bool ha_myisam::check_and_repair(THD *thd)
check_opt.flags= T_MEDIUM | T_AUTO_REPAIR;
// Don't use quick if deleted rows
if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK))
- check_opt.quick=1;
+ check_opt.flags|=T_QUICK;
sql_print_error("Warning: Checking table: '%s'",table->path);
if ((marked_crashed=mi_is_crashed(file)) || check(thd, &check_opt))
{
sql_print_error("Warning: Recovering table: '%s'",table->path);
- check_opt.quick= !check_opt.retry_without_quick && !marked_crashed;
- check_opt.flags=(((myisam_recover_options & HA_RECOVER_BACKUP) ?
- T_BACKUP_DATA : 0) |
- (!(myisam_recover_options & HA_RECOVER_FORCE) ?
- T_SAFE_REPAIR : 0)) | T_AUTO_REPAIR;
+ check_opt.flags=
+ ((myisam_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) |
+ (marked_crashed ? 0 : T_QUICK) |
+ (myisam_recover_options & HA_RECOVER_FORCE ? 0 : T_SAFE_REPAIR) |
+ T_AUTO_REPAIR);
if (repair(thd, &check_opt))
error=1;
}
@@ -753,6 +819,14 @@ int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key,
return error;
}
+int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len)
+{
+ statistic_increment(ha_read_key_count,&LOCK_status);
+ int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
+ table->status=error ? STATUS_NOT_FOUND: 0;
+ return error;
+}
+
int ha_myisam::index_next(byte * buf)
{
statistic_increment(ha_read_next_count,&LOCK_status);
@@ -800,8 +874,7 @@ int ha_myisam::rnd_init(bool scan)
{
if (scan)
return mi_scan_init(file);
- else
- return mi_extra(file,HA_EXTRA_RESET);
+ return mi_extra(file, HA_EXTRA_RESET, 0);
}
int ha_myisam::rnd_next(byte *buf)
@@ -834,6 +907,8 @@ void ha_myisam::position(const byte* record)
void ha_myisam::info(uint flag)
{
MI_ISAMINFO info;
+ char name_buff[FN_REFLEN];
+
(void) mi_status(file,&info,flag);
if (flag & HA_STATUS_VARIABLE)
{
@@ -854,15 +929,29 @@ void ha_myisam::info(uint flag)
ref_length=info.reflength;
table->db_options_in_use = info.options;
block_size=myisam_block_size;
- table->keys_in_use &= info.key_map;
+ table->keys_in_use= (set_bits(key_map, table->keys) &
+ (key_map) info.key_map);
+ table->keys_for_keyread= table->keys_in_use & ~table->read_only_keys;
table->db_record_offset=info.record_offset;
if (table->key_parts)
memcpy((char*) table->key_info[0].rec_per_key,
(char*) info.rec_per_key,
- sizeof(ulong)*table->key_parts);
+ sizeof(table->key_info[0].rec_per_key)*table->key_parts);
raid_type=info.raid_type;
raid_chunks=info.raid_chunks;
raid_chunksize=info.raid_chunksize;
+
+ /*
+ Set data_file_name and index_file_name to point at the symlink value
+ if table is symlinked (Ie; Real name is not same as generated name)
+ */
+ data_file_name=index_file_name=0;
+ fn_format(name_buff, file->filename, "", MI_NAME_DEXT, 2);
+ if (strcmp(name_buff, info.data_file_name))
+ data_file_name=info.data_file_name;
+ strmov(fn_ext(name_buff),MI_NAME_IEXT);
+ if (strcmp(name_buff, info.index_file_name))
+ index_file_name=info.index_file_name;
}
if (flag & HA_STATUS_ERRKEY)
{
@@ -878,16 +967,25 @@ void ha_myisam::info(uint flag)
int ha_myisam::extra(enum ha_extra_function operation)
{
- if (((specialflag & SPECIAL_SAFE_MODE) || (test_flags & TEST_NO_EXTRA)) &&
- (operation == HA_EXTRA_WRITE_CACHE ||
- operation == HA_EXTRA_KEYREAD))
+ if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_KEYREAD)
return 0;
- return mi_extra(file,operation);
+ return mi_extra(file, operation, 0);
}
+
+/* To be used with WRITE_CACHE and EXTRA_CACHE */
+
+int ha_myisam::extra_opt(enum ha_extra_function operation, ulong cache_size)
+{
+ if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_WRITE_CACHE)
+ return 0;
+ return mi_extra(file, operation, (void*) &cache_size);
+}
+
+
int ha_myisam::reset(void)
{
- return mi_extra(file,HA_EXTRA_RESET);
+ return mi_extra(file, HA_EXTRA_RESET, 0);
}
int ha_myisam::delete_all_rows()
@@ -902,7 +1000,9 @@ int ha_myisam::delete_table(const char *name)
int ha_myisam::external_lock(THD *thd, int lock_type)
{
- return mi_lock_database(file,lock_type);
+ return mi_lock_database(file, !table->tmp_table ?
+ lock_type : ((lock_type == F_UNLCK) ?
+ F_UNLCK : F_EXTRA_LCK));
}
@@ -918,7 +1018,7 @@ THR_LOCK_DATA **ha_myisam::store_lock(THD *thd,
void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
{
- table->file->info(HA_STATUS_AUTO | HA_STATUS_CONST);
+ ha_myisam::info(HA_STATUS_AUTO | HA_STATUS_CONST);
if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
{
create_info->auto_increment_value=auto_increment_value;
@@ -929,35 +1029,38 @@ void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
create_info->raid_chunks= raid_chunks;
create_info->raid_chunksize= raid_chunksize;
}
+ create_info->data_file_name=data_file_name;
+ create_info->index_file_name=index_file_name;
}
-int ha_myisam::create(const char *name, register TABLE *form,
+int ha_myisam::create(const char *name, register TABLE *table_arg,
HA_CREATE_INFO *info)
{
int error;
uint i,j,recpos,minpos,fieldpos,temp_length,length;
- bool found_auto_increment=0;
+ bool found_real_auto_increment=0;
enum ha_base_keytype type;
char buff[FN_REFLEN];
KEY *pos;
MI_KEYDEF *keydef;
MI_COLUMNDEF *recinfo,*recinfo_pos;
MI_KEYSEG *keyseg;
- uint options=form->db_options_in_use;
+ uint options=table_arg->db_options_in_use;
DBUG_ENTER("ha_myisam::create");
type=HA_KEYTYPE_BINARY; // Keep compiler happy
if (!(my_multi_malloc(MYF(MY_WME),
- &recinfo,(form->fields*2+2)*sizeof(MI_COLUMNDEF),
- &keydef, form->keys*sizeof(MI_KEYDEF),
+ &recinfo,(table_arg->fields*2+2)*sizeof(MI_COLUMNDEF),
+ &keydef, table_arg->keys*sizeof(MI_KEYDEF),
&keyseg,
- ((form->key_parts + form->keys) * sizeof(MI_KEYSEG)),
+ ((table_arg->key_parts + table_arg->keys) *
+ sizeof(MI_KEYSEG)),
NullS)))
- DBUG_RETURN(1);
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- pos=form->key_info;
- for (i=0; i < form->keys ; i++, pos++)
+ pos=table_arg->key_info;
+ for (i=0; i < table_arg->keys ; i++, pos++)
{
keydef[i].flag= (pos->flags & (HA_NOSAME | HA_FULLTEXT));
keydef[i].seg=keyseg;
@@ -1000,44 +1103,44 @@ int ha_myisam::create(const char *name, register TABLE *form,
{
keydef[i].seg[j].null_bit=field->null_bit;
keydef[i].seg[j].null_pos= (uint) (field->null_ptr-
- (uchar*) form->record[0]);
+ (uchar*) table_arg->record[0]);
}
else
{
keydef[i].seg[j].null_bit=0;
keydef[i].seg[j].null_pos=0;
}
- if (j == 0 && field->flags & AUTO_INCREMENT_FLAG &&
- !found_auto_increment)
- {
- keydef[i].flag|=HA_AUTO_KEY;
- found_auto_increment=1;
- }
if (field->type() == FIELD_TYPE_BLOB)
{
keydef[i].seg[j].flag|=HA_BLOB_PART;
/* save number of bytes used to pack length */
keydef[i].seg[j].bit_start= (uint) (field->pack_length() -
- form->blob_ptr_size);
+ table_arg->blob_ptr_size);
}
}
keyseg+=pos->key_parts;
}
+ if (table_arg->found_next_number_field)
+ {
+ keydef[table_arg->next_number_index].flag|= HA_AUTO_KEY;
+ found_real_auto_increment= table_arg->next_number_key_offset == 0;
+ }
+
recpos=0; recinfo_pos=recinfo;
- while (recpos < (uint) form->reclength)
+ while (recpos < (uint) table_arg->reclength)
{
Field **field,*found=0;
- minpos=form->reclength; length=0;
+ minpos=table_arg->reclength; length=0;
- for (field=form->field ; *field ; field++)
+ for (field=table_arg->field ; *field ; field++)
{
if ((fieldpos=(*field)->offset()) >= recpos &&
fieldpos <= minpos)
{
/* skip null fields */
if (!(temp_length= (*field)->pack_length()))
- continue; /* Skipp null-fields */
+ continue; /* Skip null-fields */
if (! found || fieldpos < minpos ||
(fieldpos == minpos && temp_length < length))
{
@@ -1063,20 +1166,20 @@ int ha_myisam::create(const char *name, register TABLE *form,
else if (!(options & HA_OPTION_PACK_RECORD))
recinfo_pos->type= (int) FIELD_NORMAL;
else if (found->zero_pack())
- recinfo_pos->type= (int) FIELD_SKIPP_ZERO;
+ recinfo_pos->type= (int) FIELD_SKIP_ZERO;
else
recinfo_pos->type= (int) ((length <= 3 ||
(found->flags & ZEROFILL_FLAG)) ?
FIELD_NORMAL :
found->type() == FIELD_TYPE_STRING ||
found->type() == FIELD_TYPE_VAR_STRING ?
- FIELD_SKIPP_ENDSPACE :
- FIELD_SKIPP_PRESPACE);
+ FIELD_SKIP_ENDSPACE :
+ FIELD_SKIP_PRESPACE);
if (found->null_ptr)
{
recinfo_pos->null_bit=found->null_bit;
recinfo_pos->null_pos= (uint) (found->null_ptr-
- (uchar*) form->record[0]);
+ (uchar*) table_arg->record[0]);
}
else
{
@@ -1091,18 +1194,24 @@ int ha_myisam::create(const char *name, register TABLE *form,
}
MI_CREATE_INFO create_info;
bzero((char*) &create_info,sizeof(create_info));
- create_info.max_rows=form->max_rows;
- create_info.reloc_rows=form->min_rows;
+ create_info.max_rows=table_arg->max_rows;
+ create_info.reloc_rows=table_arg->min_rows;
+ create_info.with_auto_increment=found_real_auto_increment;
create_info.auto_increment=(info->auto_increment_value ?
info->auto_increment_value -1 :
(ulonglong) 0);
- create_info.data_file_length=(ulonglong) form->max_rows*form->avg_row_length;
+ create_info.data_file_length= ((ulonglong) table_arg->max_rows *
+ table_arg->avg_row_length);
create_info.raid_type=info->raid_type;
- create_info.raid_chunks=info->raid_chunks ? info->raid_chunks : RAID_DEFAULT_CHUNKS;
- create_info.raid_chunksize=info->raid_chunksize ? info->raid_chunksize : RAID_DEFAULT_CHUNKSIZE;
-
- error=mi_create(fn_format(buff,name,"","",2+4+16),
- form->keys,keydef,
+ create_info.raid_chunks= (info->raid_chunks ? info->raid_chunks :
+ RAID_DEFAULT_CHUNKS);
+ create_info.raid_chunksize=(info->raid_chunksize ? info->raid_chunksize :
+ RAID_DEFAULT_CHUNKSIZE);
+ create_info.data_file_name= info->data_file_name;
+ create_info.index_file_name=info->index_file_name;
+
+ error=mi_create(fn_format(buff,name,"","",2+4),
+ table_arg->keys,keydef,
(uint) (recinfo_pos-recinfo), recinfo,
0, (MI_UNIQUEDEF*) 0,
&create_info,
@@ -1131,9 +1240,12 @@ longlong ha_myisam::get_auto_increment()
return auto_increment_value;
}
+ if (table->bulk_insert)
+ mi_flush_bulk_insert(file, table->next_number_index);
+
longlong nr;
int error;
- byte key[MAX_KEY_LENGTH];
+ byte key[MI_MAX_KEY_LENGTH];
(void) extra(HA_EXTRA_KEYREAD);
key_copy(key,table,table->next_number_index,
table->next_number_key_offset);
@@ -1149,6 +1261,35 @@ longlong ha_myisam::get_auto_increment()
}
+/*
+ Find out how many rows there is in the given range
+
+ SYNOPSIS
+ records_in_range()
+ inx Index to use
+ start_key Start of range. Null pointer if from first key
+ start_key_len Length of start key
+ start_search_flag Flag if start key should be included or not
+ end_key End of range. Null pointer if to last key
+ end_key_len Length of end key
+ end_search_flag Flag if start key should be included or not
+
+ NOTES
+ start_search_flag can have one of the following values:
+ HA_READ_KEY_EXACT Include the key in the range
+ HA_READ_AFTER_KEY Don't include key in range
+
+ end_search_flag can have one of the following values:
+ HA_READ_BEFORE_KEY Don't include key in range
+ HA_READ_AFTER_KEY Include all 'end_key' values in the range
+
+ RETURN
+ HA_POS_ERROR Something is wrong with the index tree.
+ 0 There is no matching keys in the given range
+ number > 0 There is approximately 'number' matching rows in
+ the range.
+*/
+
ha_rows ha_myisam::records_in_range(int inx,
const byte *start_key,uint start_key_len,
enum ha_rkey_function start_search_flag,
@@ -1163,6 +1304,7 @@ ha_rows ha_myisam::records_in_range(int inx,
end_search_flag);
}
+
int ha_myisam::ft_read(byte * buf)
{
int error;
@@ -1172,9 +1314,8 @@ int ha_myisam::ft_read(byte * buf)
thread_safe_increment(ha_read_next_count,&LOCK_status); // why ?
- error=ft_read_next((FT_DOCLIST *) ft_handler,(char*) buf);
+ error=ft_handler->please->read_next(ft_handler,(char*) buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
-
diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h
index 6451e2b80ee..212850d8f28 100644
--- a/sql/ha_myisam.h
+++ b/sql/ha_myisam.h
@@ -24,11 +24,11 @@
#include <myisam.h>
#include <ft_global.h>
-#define HA_RECOVER_NONE 0 // No automatic recover
-#define HA_RECOVER_DEFAULT 1 // Automatic recover active
-#define HA_RECOVER_BACKUP 2 // Make a backupfile on recover
-#define HA_RECOVER_FORCE 4 // Recover even if we loose rows
-#define HA_RECOVER_QUICK 8 // Don't check rows in data file
+#define HA_RECOVER_NONE 0 /* No automatic recover */
+#define HA_RECOVER_DEFAULT 1 /* Automatic recover active */
+#define HA_RECOVER_BACKUP 2 /* Make a backupfile on recover */
+#define HA_RECOVER_FORCE 4 /* Recover even if we loose rows */
+#define HA_RECOVER_QUICK 8 /* Don't check rows in data file */
extern ulong myisam_sort_buffer_size;
extern TYPELIB myisam_recover_typelib;
@@ -37,25 +37,34 @@ extern ulong myisam_recover_options;
class ha_myisam: public handler
{
MI_INFO *file;
- uint int_option_flag;
+ uint int_table_flags;
+ char *data_file_name, *index_file_name;
+ bool enable_activate_all_index;
int repair(THD *thd, MI_CHECK &param, bool optimize);
public:
ha_myisam(TABLE *table): handler(table), file(0),
- int_option_flag(HA_READ_NEXT | HA_READ_PREV | HA_READ_RND_SAME |
- HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
- HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY |
- HA_LONGLONG_KEYS | HA_NULL_KEY |
- HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY)
+ int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
+ HA_NULL_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
+ HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY |
+ HA_FILE_BASED),
+ enable_activate_all_index(1)
{}
~ha_myisam() {}
const char *table_type() const { return "MyISAM"; }
+ const char *index_type(uint key_number);
const char **bas_ext() const;
- ulong option_flag() const { return int_option_flag; }
+ ulong table_flags() const { return int_table_flags; }
+ ulong index_flags(uint inx) const
+ {
+ ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER);
+ return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
+ 0 : HA_KEY_READ_ONLY));
+ }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MI_MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return MAX_KEY_LENGTH; }
+ uint max_key_length() const { return MI_MAX_KEY_LENGTH; }
int open(const char *name, int mode, uint test_if_locked);
int close(void);
@@ -66,6 +75,7 @@ class ha_myisam: public handler
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
int index_next(byte * buf);
int index_prev(byte * buf);
int index_first(byte * buf);
@@ -73,9 +83,15 @@ class ha_myisam: public handler
int index_next_same(byte *buf, const byte *key, uint keylen);
int index_end() { ft_handler=NULL; return 0; }
int ft_init()
- { if(!ft_handler) return 1; ft_reinit_search(ft_handler); return 0; }
- void *ft_init_ext(uint inx,const byte *key, uint keylen, bool presort)
- { return ft_init_search(file,inx,(byte*) key,keylen,presort); }
+ {
+ if (!ft_handler)
+ return 1;
+ ft_handler->please->reinit_search(ft_handler);
+ return 0;
+ }
+ FT_INFO *ft_init_ext(uint mode, uint inx,const byte *key, uint keylen,
+ bool presort)
+ { return ft_init_search(mode, file,inx,(byte*) key,keylen,presort); }
int ft_read(byte *buf);
int rnd_init(bool scan=1);
int rnd_next(byte *buf);
@@ -85,6 +101,7 @@ class ha_myisam: public handler
my_off_t row_position() { return mi_position(file); }
void info(uint);
int extra(enum ha_extra_function operation);
+ int extra_opt(enum ha_extra_function operation, ulong cache_size);
int reset(void);
int external_lock(THD *thd, int lock_type);
int delete_all_rows(void);
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index e9b6a048264..f65c9afc786 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -23,9 +23,9 @@
#include <m_ctype.h>
#include "ha_myisammrg.h"
#ifndef MASTER
-#include "../srclib/myisammrg/mymrgdef.h"
+#include "../srclib/myisammrg/myrg_def.h"
#else
-#include "../myisammrg/mymrgdef.h"
+#include "../myisammrg/myrg_def.h"
#endif
/*****************************************************************************
@@ -38,25 +38,38 @@ const char **ha_myisammrg::bas_ext() const
int ha_myisammrg::open(const char *name, int mode, uint test_if_locked)
{
char name_buff[FN_REFLEN];
+ DBUG_PRINT("info", ("ha_myisammrg::open"));
if (!(file=myrg_open(fn_format(name_buff,name,"","",2 | 4), mode,
test_if_locked)))
+ {
+ DBUG_PRINT("info", ("ha_myisammrg::open exit %d", my_errno));
return (my_errno ? my_errno : -1);
-
+ }
+ DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc..."))
+ myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref);
if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED ||
test_if_locked == HA_OPEN_ABORT_IF_LOCKED))
- myrg_extra(file,HA_EXTRA_NO_WAIT_LOCK);
+ myrg_extra(file,HA_EXTRA_NO_WAIT_LOCK,0);
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
- myrg_extra(file,HA_EXTRA_WAIT_LOCK);
+ myrg_extra(file,HA_EXTRA_WAIT_LOCK,0);
+
if (table->reclength != mean_rec_length && mean_rec_length)
{
DBUG_PRINT("error",("reclength: %d mean_rec_length: %d",
table->reclength, mean_rec_length));
- myrg_close(file);
- file=0;
- return my_errno=HA_ERR_WRONG_TABLE_DEF;
+ goto err;
}
+#if !defined(BIG_TABLES) || SIZEOF_OFF_T == 4
+ /* Merge table has more than 2G rows */
+ if (table->crashed)
+ goto err;
+#endif
return (0);
+err:
+ myrg_close(file);
+ file=0;
+ return (my_errno= HA_ERR_WRONG_MRG_TABLE_DEF);
}
int ha_myisammrg::close(void)
@@ -66,7 +79,12 @@ int ha_myisammrg::close(void)
int ha_myisammrg::write_row(byte * buf)
{
- return (my_errno=HA_ERR_WRONG_COMMAND);
+ statistic_increment(ha_write_count,&LOCK_status);
+ if (table->time_stamp)
+ update_timestamp(buf+table->time_stamp-1);
+ if (table->next_number_field && buf == table->record[0])
+ update_auto_increment();
+ return myrg_write(file,buf);
}
int ha_myisammrg::update_row(const byte * old_data, byte * new_data)
@@ -101,6 +119,15 @@ int ha_myisammrg::index_read_idx(byte * buf, uint index, const byte * key,
return error;
}
+int ha_myisammrg::index_read_last(byte * buf, const byte * key, uint key_len)
+{
+ statistic_increment(ha_read_key_count,&LOCK_status);
+ int error=myrg_rkey(file,buf,active_index, key, key_len,
+ HA_READ_PREFIX_LAST);
+ table->status=error ? STATUS_NOT_FOUND: 0;
+ return error;
+}
+
int ha_myisammrg::index_next(byte * buf)
{
statistic_increment(ha_read_next_count,&LOCK_status);
@@ -135,7 +162,7 @@ int ha_myisammrg::index_last(byte * buf)
int ha_myisammrg::rnd_init(bool scan)
{
- return myrg_extra(file,HA_EXTRA_RESET);
+ return myrg_extra(file,HA_EXTRA_RESET,0);
}
int ha_myisammrg::rnd_next(byte *buf)
@@ -160,13 +187,35 @@ void ha_myisammrg::position(const byte *record)
ha_store_ptr(ref, ref_length, (my_off_t) position);
}
+ha_rows ha_myisammrg::records_in_range(int inx,
+ const byte *start_key,uint start_key_len,
+ enum ha_rkey_function start_search_flag,
+ const byte *end_key,uint end_key_len,
+ enum ha_rkey_function end_search_flag)
+{
+ return (ha_rows) myrg_records_in_range(file,
+ inx,
+ start_key,start_key_len,
+ start_search_flag,
+ end_key,end_key_len,
+ end_search_flag);
+}
void ha_myisammrg::info(uint flag)
{
MYMERGE_INFO info;
(void) myrg_status(file,&info,flag);
+ /*
+ The following fails if one has not compiled MySQL with -DBIG_TABLES
+ and one has more than 2^32 rows in the merge tables.
+ */
records = (ha_rows) info.records;
deleted = (ha_rows) info.deleted;
+#if !defined(BIG_TABLES) || SIZEOF_OFF_T == 4
+ if ((info.records >= (ulonglong) 1 << 32) ||
+ (info.deleted >= (ulonglong) 1 << 32))
+ table->crashed=1;
+#endif
data_file_length=info.data_file_length;
errkey = info.errkey;
table->keys_in_use= set_bits(key_map, table->keys);
@@ -180,17 +229,40 @@ void ha_myisammrg::info(uint flag)
#else
ref_length=4; // Can't be > than my_off_t
#endif
+ if (flag & HA_STATUS_CONST)
+ {
+ if (table->key_parts && info.rec_per_key)
+ memcpy((char*) table->key_info[0].rec_per_key,
+ (char*) info.rec_per_key,
+ sizeof(table->key_info[0].rec_per_key)*table->key_parts);
+ }
}
int ha_myisammrg::extra(enum ha_extra_function operation)
{
- return myrg_extra(file,operation);
+ /* As this is just a mapping, we don't have to force the underlying
+ tables to be closed */
+ if (operation == HA_EXTRA_FORCE_REOPEN ||
+ operation == HA_EXTRA_PREPARE_FOR_DELETE)
+ return 0;
+ return myrg_extra(file,operation,0);
+}
+
+
+/* To be used with WRITE_CACHE, EXTRA_CACHE and BULK_INSERT_BEGIN */
+
+int ha_myisammrg::extra_opt(enum ha_extra_function operation, ulong cache_size)
+{
+ if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_WRITE_CACHE)
+ return 0;
+ return myrg_extra(file, operation, (void*) &cache_size);
}
+
int ha_myisammrg::reset(void)
{
- return myrg_extra(file,HA_EXTRA_RESET);
+ return myrg_extra(file,HA_EXTRA_RESET,0);
}
int ha_myisammrg::external_lock(THD *thd, int lock_type)
@@ -208,30 +280,35 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd,
THR_LOCK_DATA **to,
enum thr_lock_type lock_type)
{
- MYRG_TABLE *table;
+ MYRG_TABLE *open_table;
- for (table=file->open_tables ; table != file->end_table ; table++)
+ for (open_table=file->open_tables ;
+ open_table != file->end_table ;
+ open_table++)
{
- *(to++)= &table->table->lock;
- if (lock_type != TL_IGNORE && table->table->lock.type == TL_UNLOCK)
- table->table->lock.type=lock_type;
+ *(to++)= &open_table->table->lock;
+ if (lock_type != TL_IGNORE && open_table->table->lock.type == TL_UNLOCK)
+ open_table->table->lock.type=lock_type;
}
return to;
}
void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
{
+ // [phi] auto_increment stuff is missing (but currently not needed)
DBUG_ENTER("ha_myisammrg::update_create_info");
if (!(create_info->used_fields & HA_CREATE_USED_UNION))
{
- MYRG_TABLE *table;
+ MYRG_TABLE *open_table;
THD *thd=current_thd;
create_info->merge_list.next= &create_info->merge_list.first;
create_info->merge_list.elements=0;
- for (table=file->open_tables ; table != file->end_table ; table++)
+ for (open_table=file->open_tables ;
+ open_table != file->end_table ;
+ open_table++)
{
- char *name=table->table->s->filename;
+ char *name=open_table->table->filename;
char buff[FN_REFLEN];
TABLE_LIST *ptr;
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
@@ -245,6 +322,10 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
}
*create_info->merge_list.next=0;
}
+ if (!(create_info->used_fields & HA_CREATE_USED_INSERT_METHOD))
+ {
+ create_info->merge_insert_method = file->merge_insert_method;
+ }
DBUG_VOID_RETURN;
err:
@@ -262,7 +343,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
if (!(table_names= (char**) sql_alloc((create_info->merge_list.elements+1)*
sizeof(char*))))
- DBUG_RETURN(1);
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
for (pos=table_names ; tables ; tables=tables->next)
{
char *table_name;
@@ -276,7 +357,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
my_snprintf(buff,FN_REFLEN,"%s/%s/%s",mysql_real_data_home,
tables->db, tables->real_name));
if (!table_name)
- DBUG_RETURN(1);
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
strcpy(table_name, buff);
}
else
@@ -288,20 +369,29 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
}
*pos=0;
DBUG_RETURN(myrg_create(fn_format(buff,name,"","",2+4+16),
- (const char **) table_names, (my_bool) 0));
+ (const char **) table_names,
+ create_info->merge_insert_method,
+ (my_bool) 0));
}
void ha_myisammrg::append_create_info(String *packet)
{
char buff[FN_REFLEN];
+ if (file->merge_insert_method != MERGE_INSERT_DISABLED)
+ {
+ packet->append(" INSERT_METHOD=",15);
+ packet->append(get_type(&merge_insert_method,file->merge_insert_method-1));
+ }
packet->append(" UNION=(",8);
- MYRG_TABLE *table,*first;
+ MYRG_TABLE *open_table,*first;
- for (first=table=file->open_tables ; table != file->end_table ; table++)
+ for (first=open_table=file->open_tables ;
+ open_table != file->end_table ;
+ open_table++)
{
- char *name=table->table->s->filename;
+ char *name= open_table->table->filename;
fn_format(buff,name,"","",3);
- if (table != first)
+ if (open_table != first)
packet->append(',');
packet->append(buff,(uint) strlen(buff));
}
diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h
index b97baa0703c..db3c20bede2 100644
--- a/sql/ha_myisammrg.h
+++ b/sql/ha_myisammrg.h
@@ -32,13 +32,19 @@ class ha_myisammrg: public handler
~ha_myisammrg() {}
const char *table_type() const { return "MRG_MyISAM"; }
const char **bas_ext() const;
- ulong option_flag() const
- { return (HA_REC_NOT_IN_SEQ | HA_READ_NEXT |
- HA_READ_PREV | HA_READ_RND_SAME |
- HA_HAVE_KEY_READ_ONLY | HA_NO_FULLTEXT_KEY |
- HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER |
- HA_LASTKEY_ORDER | HA_READ_NOT_EXACT_KEY |
- HA_LONGLONG_KEYS | HA_NULL_KEY | HA_BLOB_KEY); }
+ ulong table_flags() const
+ {
+ return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME | HA_AUTO_PART_KEY |
+ HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
+ HA_NULL_KEY | HA_BLOB_KEY | HA_FILE_BASED);
+ }
+ ulong index_flags(uint inx) const
+ {
+ ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER |
+ HA_NOT_READ_PREFIX_LAST); // This - last - flag is ONLY for 4.0 !!!
+ return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
+ 0 : HA_KEY_READ_ONLY));
+ }
uint max_record_length() const { return HA_MAX_REC_LENGTH; }
uint max_keys() const { return MI_MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
@@ -55,6 +61,7 @@ class ha_myisammrg: public handler
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(byte * buf, uint idx, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
+ int index_read_last(byte * buf, const byte * key, uint key_len);
int index_next(byte * buf);
int index_prev(byte * buf);
int index_first(byte * buf);
@@ -63,9 +70,15 @@ class ha_myisammrg: public handler
int rnd_next(byte *buf);
int rnd_pos(byte * buf, byte *pos);
void position(const byte *record);
+ ha_rows records_in_range(int inx,
+ const byte *start_key,uint start_key_len,
+ enum ha_rkey_function start_search_flag,
+ const byte *end_key,uint end_key_len,
+ enum ha_rkey_function end_search_flag);
my_off_t row_position() { return myrg_position(file); }
void info(uint);
int extra(enum ha_extra_function operation);
+ int extra_opt(enum ha_extra_function operation, ulong cache_size);
int reset(void);
int external_lock(THD *thd, int lock_type);
uint lock_count(void) const;
@@ -74,4 +87,5 @@ class ha_myisammrg: public handler
enum thr_lock_type lock_type);
void update_create_info(HA_CREATE_INFO *create_info);
void append_create_info(String *packet);
+ MYRG_INFO *myrg_info() { return file; }
};
diff --git a/sql/handler.cc b/sql/handler.cc
index 564d91aa887..f0756aceadb 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -25,7 +25,7 @@
#include "ha_heap.h"
#include "ha_myisam.h"
#include "ha_myisammrg.h"
-#ifndef NO_ISAM
+#ifdef HAVE_ISAM
#include "ha_isam.h"
#include "ha_isammrg.h"
#endif
@@ -33,10 +33,7 @@
#include "ha_berkeley.h"
#endif
#ifdef HAVE_INNOBASE_DB
-#include "ha_innobase.h"
-#endif
-#ifdef HAVE_GEMINI_DB
-#include "ha_gemini.h"
+#include "ha_innodb.h"
#endif
#include <myisampack.h>
#include <errno.h>
@@ -48,6 +45,7 @@ static int NEAR_F delete_file(const char *name,const char *ext,int extflag);
ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
ha_read_key_count, ha_read_next_count, ha_read_prev_count,
ha_read_first_count, ha_read_last_count,
+ ha_commit_count, ha_rollback_count,
ha_read_rnd_count, ha_read_rnd_next_count;
const char *ha_table_type[] = {
@@ -55,8 +53,10 @@ const char *ha_table_type[] = {
"MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNODB", "GEMINI", "?", "?",NullS
};
-TYPELIB ha_table_typelib= {array_elements(ha_table_type)-4,"",
- ha_table_type+1};
+TYPELIB ha_table_typelib=
+{
+ array_elements(ha_table_type)-3, "", ha_table_type
+};
const char *ha_row_type[] = {
"", "FIXED", "DYNAMIC", "COMPRESSED","?","?","?"
@@ -78,21 +78,15 @@ enum db_type ha_checktype(enum db_type database_type)
return(berkeley_skip ? DB_TYPE_MYISAM : database_type);
#endif
#ifdef HAVE_INNOBASE_DB
- case DB_TYPE_INNOBASE:
+ case DB_TYPE_INNODB:
return(innodb_skip ? DB_TYPE_MYISAM : database_type);
#endif
-#ifdef HAVE_GEMINI_DB
- case DB_TYPE_GEMINI:
- return(gemini_skip ? DB_TYPE_MYISAM : database_type);
-#endif
#ifndef NO_HASH
case DB_TYPE_HASH:
#endif
-#ifndef NO_MERGE
- case DB_TYPE_MRG_ISAM:
-#endif
-#ifndef NO_ISAM
+#ifdef HAVE_ISAM
case DB_TYPE_ISAM:
+ case DB_TYPE_MRG_ISAM:
#endif
case DB_TYPE_HEAP:
case DB_TYPE_MYISAM:
@@ -111,11 +105,9 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
#ifndef NO_HASH
return new ha_hash(table);
#endif
-#ifndef NO_MERGE
+#ifdef HAVE_ISAM
case DB_TYPE_MRG_ISAM:
return new ha_isammrg(table);
-#endif
-#ifndef NO_ISAM
case DB_TYPE_ISAM:
return new ha_isam(table);
#endif
@@ -124,17 +116,20 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
return new ha_berkeley(table);
#endif
#ifdef HAVE_INNOBASE_DB
- case DB_TYPE_INNOBASE:
+ case DB_TYPE_INNODB:
return new ha_innobase(table);
#endif
-#ifdef HAVE_GEMINI_DB
- case DB_TYPE_GEMINI:
- return new ha_gemini(table);
-#endif
case DB_TYPE_HEAP:
return new ha_heap(table);
- case DB_TYPE_MYISAM:
default: // should never happen
+ {
+ enum db_type def=(enum db_type) current_thd->variables.table_type;
+ /* Try first with 'default table type' */
+ if (db_type != def)
+ return get_new_handler(table, def);
+ }
+ /* Fall back to MyISAM */
+ case DB_TYPE_MYISAM:
return new ha_myisam(table);
case DB_TYPE_MRG_MYISAM:
return new ha_myisammrg(table);
@@ -166,17 +161,6 @@ int ha_init()
have_innodb=SHOW_OPTION_DISABLED;
}
#endif
-#ifdef HAVE_GEMINI_DB
- if (!gemini_skip)
- {
- if (gemini_init())
- return -1;
- if (!gemini_skip) // If we couldn't use handler
- opt_using_transactions=1;
- else
- have_gemini=SHOW_OPTION_DISABLED;
- }
-#endif
return 0;
}
@@ -186,14 +170,14 @@ int ha_init()
int ha_panic(enum ha_panic_function flag)
{
int error=0;
-#ifndef NO_MERGE
- error|=mrg_panic(flag);
-#endif
#ifndef NO_HASH
error|=h_panic(flag); /* fix hash */
#endif
- error|=heap_panic(flag);
+#ifdef HAVE_ISAM
+ error|=mrg_panic(flag);
error|=nisam_panic(flag);
+#endif
+ error|=heap_panic(flag);
error|=mi_panic(flag);
error|=myrg_panic(flag);
#ifdef HAVE_BERKELEY_DB
@@ -204,10 +188,6 @@ int ha_panic(enum ha_panic_function flag)
if (!innodb_skip)
error|=innobase_end();
#endif
-#ifdef HAVE_GEMINI_DB
- if (!gemini_skip)
- error|=gemini_end();
-#endif
return error;
} /* ha_panic */
@@ -225,17 +205,15 @@ void ha_close_connection(THD* thd)
if (!innodb_skip)
innobase_close_connection(thd);
#endif
-#ifdef HAVE_GEMINI_DB
- if (!gemini_skip && thd->gemini.context)
- {
- gemini_disconnect(thd);
- }
-#endif /* HAVE_GEMINI_DB */
}
/*
- This is used to commit or rollback a single statement depending
- on the value of error
+ This is used to commit or rollback a single statement depending on the value
+ of error. Note that if the autocommit is on, then the following call inside
+ InnoDB will commit or rollback the whole transaction (= the statement). The
+ autocommit mechanism built into InnoDB is based on counting locks, but if
+ the user has used LOCK TABLES then that mechanism does not know to do the
+ commit.
*/
int ha_autocommit_or_rollback(THD *thd, int error)
@@ -251,8 +229,8 @@ int ha_autocommit_or_rollback(THD *thd, int error)
}
else
(void) ha_rollback_stmt(thd);
-
- thd->tx_isolation=thd->session_tx_isolation;
+
+ thd->variables.tx_isolation=thd->session_tx_isolation;
}
#endif
DBUG_RETURN(error);
@@ -269,10 +247,15 @@ int ha_autocommit_or_rollback(THD *thd, int error)
replication. This function also calls the commit of the table
handler, because the order of transactions in the log of the table
handler must be the same as in the binlog.
+ NOTE that to eliminate the bottleneck of the group commit, we do not
+ flush the handler log files here, but only later in a call of
+ ha_commit_complete().
arguments:
+ thd: the thread handle of the current connection
log_file_name: latest binlog file name
end_offset: the offset in the binlog file up to which we wrote
+ return value: 0 if success, 1 if error
*/
int ha_report_binlog_offset_and_commit(THD *thd,
@@ -293,12 +276,65 @@ int ha_report_binlog_offset_and_commit(THD *thd,
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
}
- trans->innodb_active_trans=0;
}
#endif
return error;
}
+/*
+ Flushes the handler log files (if my.cnf settings do not free us from it)
+ after we have called ha_report_binlog_offset_and_commit(). To eliminate
+ the bottleneck from the group commit, this should be called when
+ LOCK_log has been released in log.cc.
+
+ arguments:
+ thd: the thread handle of the current connection
+ return value: always 0
+*/
+
+int ha_commit_complete(THD *thd)
+{
+#ifdef HAVE_INNOBASE_DB
+ THD_TRANS *trans;
+ trans = &thd->transaction.all;
+ if (trans->innobase_tid)
+ {
+ innobase_commit_complete(trans->innobase_tid);
+
+ trans->innodb_active_trans=0;
+ }
+#endif
+ return 0;
+}
+
+/*
+ This function should be called when MySQL sends rows of a SELECT result set
+ or the EOF mark to the client. It releases a possible adaptive hash index
+ S-latch held by thd in InnoDB and also releases a possible InnoDB query
+ FIFO ticket to enter InnoDB. To save CPU time, InnoDB allows a thd to
+ keep them over several calls of the InnoDB handler interface when a join
+ is executed. But when we let the control to pass to the client they have
+ to be released because if the application program uses mysql_use_result(),
+ it may deadlock on the S-latch if the application on another connection
+ performs another SQL query. In MySQL-4.1 this is even more important because
+ there a connection can have several SELECT queries open at the same time.
+
+ arguments:
+ thd: the thread handle of the current connection
+ return value: always 0
+*/
+
+int ha_release_temporary_latches(THD *thd)
+{
+#ifdef HAVE_INNOBASE_DB
+ THD_TRANS *trans;
+ trans = &thd->transaction.all;
+ if (trans->innobase_tid)
+ innobase_release_temporary_latches(trans->innobase_tid);
+#endif
+ return 0;
+}
+
int ha_commit_trans(THD *thd, THD_TRANS* trans)
{
int error=0;
@@ -306,41 +342,14 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
#ifdef USING_TRANSACTIONS
if (opt_using_transactions)
{
+ bool operation_done= 0;
+ bool transaction_commited= 0;
+
/* Update the binary log if we have cached some queries */
if (trans == &thd->transaction.all && mysql_bin_log.is_open() &&
my_b_tell(&thd->transaction.trans_log))
{
- /* We write the command "COMMIT" as the last SQL command in the
- binlog segment cached for this transaction */
-
- int save_query_length = thd->query_length;
-
- thd->query_length = 6; /* length of 'COMMIT'; note that we may come
- here because a DROP TABLE, for instance,
- makes an implicit commit, and then
- thd->query is not 'COMMIT'! */
-
- Query_log_event qinfo(thd, "COMMIT", TRUE);
-
- /* When we come here, and the user wrapped the transaction into
- BEGIN and COMMIT, then qinfo got above the field cache_stmt
- erroneously set to 0. Let us set it to 1: */
-
- qinfo.cache_stmt = 1;
-
- /* Write the 'COMMIT' entry to the cache */
-
- if (mysql_bin_log.write(&qinfo)) {
- my_error(ER_ERROR_DURING_COMMIT, MYF(0), 5000);
- error=1;
- }
-
- thd->query_length = save_query_length;
-
- /* Now we write the binlog segment cached for this transaction to
- the real binlog */
-
- mysql_bin_log.write(thd, &thd->transaction.trans_log);
+ mysql_bin_log.write(thd, &thd->transaction.trans_log, 1);
reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
@@ -353,6 +362,9 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
}
+ else
+ if (!(thd->options & OPTION_BEGIN))
+ transaction_commited= 1;
trans->bdb_tid=0;
}
#endif
@@ -365,25 +377,22 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
error=1;
}
trans->innodb_active_trans=0;
+ if (trans == &thd->transaction.all)
+ operation_done= transaction_commited= 1;
}
#endif
-#ifdef HAVE_GEMINI_DB
- /* Commit the transaction in behalf of the commit statement
- or if we're in auto-commit mode */
- if((trans == &thd->transaction.all) ||
- (!(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))))
- {
- error=gemini_commit(thd);
- if (error)
- {
- my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
- error=1;
- }
- }
-#endif
+#ifdef HAVE_QUERY_CACHE
+ if (transaction_commited && thd->transaction.changed_tables)
+ query_cache.invalidate(thd->transaction.changed_tables);
+#endif /*HAVE_QUERY_CACHE*/
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
sql_print_error("Error: Got error during commit; Binlog is not up to date!");
- thd->tx_isolation=thd->session_tx_isolation;
+ thd->variables.tx_isolation=thd->session_tx_isolation;
+ if (operation_done)
+ {
+ statistic_increment(ha_commit_count,&LOCK_status);
+ thd->transaction.cleanup();
+ }
}
#endif // using transactions
DBUG_RETURN(error);
@@ -397,6 +406,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
#ifdef USING_TRANSACTIONS
if (opt_using_transactions)
{
+ bool operation_done=0;
#ifdef HAVE_BERKELEY_DB
if (trans->bdb_tid)
{
@@ -406,6 +416,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
error=1;
}
trans->bdb_tid=0;
+ operation_done=1;
}
#endif
#ifdef HAVE_INNOBASE_DB
@@ -417,41 +428,141 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
error=1;
}
trans->innodb_active_trans=0;
+ operation_done=1;
}
#endif
-#ifdef HAVE_GEMINI_DB
- if((trans == &thd->transaction.stmt) &&
- (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)))
- error = gemini_rollback_to_savepoint(thd);
- else
- error=gemini_rollback(thd);
- if (error)
+ if (trans == &thd->transaction.all)
+ {
+ /*
+ Update the binary log with a BEGIN/ROLLBACK block if we have cached some
+ queries and we updated some non-transactional table. Such cases should
+ be rare (updating a non-transactional table inside a transaction...).
+ */
+ if (unlikely((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
+ mysql_bin_log.is_open() &&
+ my_b_tell(&thd->transaction.trans_log)))
+ mysql_bin_log.write(thd, &thd->transaction.trans_log, 0);
+ /* Flushed or not, empty the binlog cache */
+ reinit_io_cache(&thd->transaction.trans_log,
+ WRITE_CACHE, (my_off_t) 0, 0, 1);
+ thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
+ }
+ thd->variables.tx_isolation=thd->session_tx_isolation;
+ if (operation_done)
+ {
+ statistic_increment(ha_rollback_count,&LOCK_status);
+ thd->transaction.cleanup();
+ }
+ }
+#endif /* USING_TRANSACTIONS */
+ DBUG_RETURN(error);
+}
+
+
+/*
+ Rolls the current transaction back to a savepoint.
+ Return value: 0 if success, 1 if there was not a savepoint of the given
+ name.
+ NOTE: how do we handle this (unlikely but legal) case:
+ [transaction] + [update to non-trans table] + [rollback to savepoint] ?
+ The problem occurs when a savepoint is before the update to the
+ non-transactional table. Then when there's a rollback to the savepoint, if we
+ simply truncate the binlog cache, we lose the part of the binlog cache where
+ the update is. If we want to not lose it, we need to write the SAVEPOINT
+ command and the ROLLBACK TO SAVEPOINT command to the binlog cache. The latter
+ is easy: it's just write at the end of the binlog cache, but the former should
+ be *inserted* to the place where the user called SAVEPOINT. The solution is
+ that when the user calls SAVEPOINT, we write it to the binlog cache (so no
+ need to later insert it). As transactions are never intermixed in the binary log
+ (i.e. they are serialized), we won't have conflicts with savepoint names when
+ using mysqlbinlog or in the slave SQL thread.
+ Then when ROLLBACK TO SAVEPOINT is called, if we updated some
+ non-transactional table, we don't truncate the binlog cache but instead write
+ ROLLBACK TO SAVEPOINT to it; otherwise we truncate the binlog cache (which
+ will chop the SAVEPOINT command from the binlog cache, which is good as in
+ that case there is no need to have it in the binlog).
+*/
+
+int ha_rollback_to_savepoint(THD *thd, char *savepoint_name)
+{
+ my_off_t binlog_cache_pos=0;
+ bool operation_done=0;
+ int error=0;
+ DBUG_ENTER("ha_rollback_to_savepoint");
+#ifdef USING_TRANSACTIONS
+ if (opt_using_transactions)
+ {
+#ifdef HAVE_INNOBASE_DB
+ /*
+ Retrieve the trans_log binlog cache position corresponding to the
+ savepoint, and if the rollback is successful inside InnoDB reset the write
+ position in the binlog cache to what it was at the savepoint.
+ */
+ if ((error=innobase_rollback_to_savepoint(thd, savepoint_name,
+ &binlog_cache_pos)))
{
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
error=1;
}
+ else
+ {
+ /*
+ Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
+ non-transactional table. Otherwise, truncate the binlog cache starting
+ from the SAVEPOINT command.
+ */
+ if (unlikely((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
+ mysql_bin_log.is_open() &&
+ my_b_tell(&thd->transaction.trans_log)))
+ {
+ Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE);
+ if (mysql_bin_log.write(&qinfo))
+ error= 1;
+ }
+ else
+ reinit_io_cache(&thd->transaction.trans_log, WRITE_CACHE,
+ binlog_cache_pos, 0, 0);
+ }
+ operation_done=1;
#endif
- if (trans == &thd->transaction.all)
- reinit_io_cache(&thd->transaction.trans_log,
- WRITE_CACHE, (my_off_t) 0, 0, 1);
- thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
- thd->tx_isolation=thd->session_tx_isolation;
+ if (operation_done)
+ statistic_increment(ha_rollback_count,&LOCK_status);
}
#endif /* USING_TRANSACTIONS */
+
DBUG_RETURN(error);
}
-void ha_set_spin_retries(uint retries)
+
+/*
+Sets a transaction savepoint.
+Return value: always 0, that is, succeeds always
+*/
+
+int ha_savepoint(THD *thd, char *savepoint_name)
{
-#ifdef HAVE_GEMINI_DB
- if (!gemini_skip)
+ my_off_t binlog_cache_pos=0;
+ int error=0;
+ DBUG_ENTER("ha_savepoint");
+#ifdef USING_TRANSACTIONS
+ if (opt_using_transactions)
{
- gemini_set_option_long(GEM_OPTID_SPIN_RETRIES, retries);
+ binlog_cache_pos=my_b_tell(&thd->transaction.trans_log);
+#ifdef HAVE_INNOBASE_DB
+ innobase_savepoint(thd,savepoint_name, binlog_cache_pos);
+#endif
+ /* Write it to the binary log (see comments of ha_rollback_to_savepoint). */
+ if (mysql_bin_log.is_open())
+ {
+ Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE);
+ if (mysql_bin_log.write(&qinfo))
+ error= 1;
+ }
}
-#endif /* HAVE_GEMINI_DB */
+#endif /* USING_TRANSACTIONS */
+ DBUG_RETURN(error);
}
-
bool ha_flush_logs()
{
bool result=0;
@@ -473,14 +584,23 @@ bool ha_flush_logs()
int ha_delete_table(enum db_type table_type, const char *path)
{
+ char tmp_path[FN_REFLEN];
handler *file=get_new_handler((TABLE*) 0, table_type);
if (!file)
return ENOENT;
+ if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
+ {
+ /* Ensure that table handler get path in lower case */
+ strmov(tmp_path, path);
+ casedn_str(tmp_path);
+ path= tmp_path;
+ }
int error=file->delete_table(path);
delete file;
return error;
}
-
+
+
void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos)
{
switch (pack_length) {
@@ -547,7 +667,8 @@ int handler::ha_open(const char *name, int mode, int test_if_locked)
int error;
DBUG_ENTER("handler::open");
DBUG_PRINT("enter",("name: %s db_type: %d db_stat: %d mode: %d lock_test: %d",
- name, table->db_type, table->db_stat, mode, test_if_locked));
+ name, table->db_type, table->db_stat, mode,
+ test_if_locked));
if ((error=open(name,mode,test_if_locked)))
{
@@ -567,9 +688,8 @@ int handler::ha_open(const char *name, int mode, int test_if_locked)
{
if (table->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
table->db_stat|=HA_READ_ONLY;
- }
- if (!error)
- {
+ (void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
+
if (!alloc_root_inited(&table->mem_root)) // If temporary table
ref=(byte*) sql_alloc(ALIGN_SIZE(ref_length)*2);
else
@@ -615,17 +735,37 @@ int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt)
return HA_ADMIN_NOT_IMPLEMENTED;
}
- /* Read first row from a table */
+/*
+ Read first row (only) from a table
+ This is never called for InnoDB or BDB tables, as these table types
+ has the HA_NOT_EXACT_COUNT set.
+*/
-int handler::rnd_first(byte * buf)
+int handler::read_first_row(byte * buf, uint primary_key)
{
register int error;
- DBUG_ENTER("handler::rnd_first");
+ DBUG_ENTER("handler::read_first_row");
statistic_increment(ha_read_first_count,&LOCK_status);
- (void) rnd_init();
- while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
- (void) rnd_end();
+
+ /*
+ If there is very few deleted rows in the table, find the first row by
+ scanning the table.
+ */
+ if (deleted < 10 || primary_key >= MAX_KEY ||
+ !(index_flags(primary_key) & HA_READ_ORDER))
+ {
+ (void) rnd_init();
+ while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
+ (void) rnd_end();
+ }
+ else
+ {
+ /* Find the first row through the primary key */
+ (void) index_init(primary_key);
+ error=index_first(buf);
+ (void) index_end();
+ }
DBUG_RETURN(error);
}
@@ -641,7 +781,7 @@ int handler::restart_rnd_next(byte *buf, byte *pos)
}
- /* Set a timestamp in record */
+/* Set a timestamp in record */
void handler::update_timestamp(byte *record)
{
@@ -657,9 +797,10 @@ void handler::update_timestamp(byte *record)
return;
}
- /* Updates field with field_type NEXT_NUMBER according to following:
- ** if field = 0 change field to the next free key in database.
- */
+/*
+ Updates field with field_type NEXT_NUMBER according to following:
+ if field = 0 change field to the next free key in database.
+*/
void handler::update_auto_increment()
{
@@ -687,16 +828,29 @@ longlong handler::get_auto_increment()
{
longlong nr;
int error;
+
(void) extra(HA_EXTRA_KEYREAD);
index_init(table->next_number_index);
- error=index_last(table->record[1]);
+ if (!table->next_number_key_offset)
+ { // Autoincrement at key-start
+ error=index_last(table->record[1]);
+ }
+ else
+ {
+ byte key[MAX_KEY_LENGTH];
+ key_copy(key,table,table->next_number_index,
+ table->next_number_key_offset);
+ error=index_read(table->record[1], key, table->next_number_key_offset,
+ HA_READ_PREFIX_LAST);
+ }
+
if (error)
nr=1;
else
nr=(longlong) table->next_number_field->
val_int_offset(table->rec_buff_length)+1;
- (void) extra(HA_EXTRA_NO_KEYREAD);
index_end();
+ (void) extra(HA_EXTRA_NO_KEYREAD);
return nr;
}
@@ -709,6 +863,9 @@ void handler::print_error(int error, myf errflag)
int textno=ER_GET_ERRNO;
switch (error) {
+ case EACCES:
+ textno=ER_OPEN_AS_READONLY;
+ break;
case EAGAIN:
textno=ER_FILE_USED;
break;
@@ -720,7 +877,7 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_END_OF_FILE:
textno=ER_KEY_NOT_FOUND;
break;
- case HA_ERR_WRONG_TABLE_DEF:
+ case HA_ERR_WRONG_MRG_TABLE_DEF:
textno=ER_WRONG_MRG_TABLE;
break;
case HA_ERR_FOUND_DUPP_KEY:
@@ -805,7 +962,8 @@ void handler::print_error(int error, myf errflag)
DBUG_VOID_RETURN;
}
- /* Return key if error because of duplicated keys */
+
+/* Return key if error because of duplicated keys */
uint handler::get_dup_key(int error)
{
@@ -816,6 +974,7 @@ uint handler::get_dup_key(int error)
DBUG_RETURN(table->file->errkey);
}
+
int handler::delete_table(const char *name)
{
int error=0;
@@ -842,38 +1001,15 @@ int handler::rename_table(const char * from, const char * to)
DBUG_RETURN(0);
}
-int ha_commit_rename(THD *thd)
-{
- int error=0;
-#ifdef HAVE_GEMINI_DB
- /* Gemini needs to commit the rename; otherwise a rollback will change
- ** the table names back internally but the physical files will still
- ** have the new names.
- */
- if (ha_commit_stmt(thd))
- error= -1;
- if (ha_commit(thd))
- error= -1;
-#endif
- return error;
-}
-
-/* Tell the handler to turn on or off logging to the handler's
- recovery log
+/*
+ Tell the handler to turn on or off logging to the handler's recovery log
*/
+
int ha_recovery_logging(THD *thd, bool on)
{
int error=0;
DBUG_ENTER("ha_recovery_logging");
-#ifdef USING_TRANSACTIONS
- if (opt_using_transactions)
- {
-#ifdef HAVE_GEMINI_DB
- error = gemini_recovery_logging(thd, on);
-#endif
- }
-#endif
DBUG_RETURN(error);
}
@@ -893,8 +1029,10 @@ int handler::index_next_same(byte *buf, const byte *key, uint keylen)
/*
- The following is only needed if we would like to use the database
- for internal temporary tables
+ This is called to delete all rows in a table
+ If the handler don't support this, then this function will
+ return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
+ by one.
*/
int handler::delete_all_rows()
@@ -911,10 +1049,10 @@ int handler::delete_all_rows()
int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
bool update_create_info)
-
{
int error;
TABLE table;
+ char name_buff[FN_REFLEN];
DBUG_ENTER("ha_create_table");
if (openfrm(name,"",0,(uint) READ_ALL, 0, &table))
@@ -922,20 +1060,22 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
if (update_create_info)
{
update_create_info_from_table(create_info, &table);
- if (table.file->option_flag() & HA_DROP_BEFORE_CREATE)
+ if (table.file->table_flags() & HA_DROP_BEFORE_CREATE)
table.file->delete_table(name); // Needed for BDB tables
}
+ if (lower_case_table_names == 2 &&
+ !(table.file->table_flags() & HA_FILE_BASED))
+ {
+ /* Ensure that handler gets name in lower case */
+ strmov(name_buff, name);
+ casedn_str(name_buff);
+ name= name_buff;
+ }
+
error=table.file->create(name,&table,create_info);
VOID(closefrm(&table));
- if (error) {
- if (table.db_type == DB_TYPE_INNOBASE) {
- /* Creation of InnoDB table cannot fail because of an OS error:
- put error as the number */
- my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error);
- } else {
- my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,my_errno);
- }
- }
+ if (error)
+ my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error);
DBUG_RETURN(error != 0);
}
@@ -943,14 +1083,37 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
void ha_key_cache(void)
{
- if (keybuff_size)
- (void) init_key_cache(keybuff_size,0);
-} /* ha_key_cache */
+ /*
+ The following mutex is not really needed as long as keybuff_size is
+ treated as a long value, but we use the mutex here to guard for future
+ changes.
+ */
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ long tmp= (long) keybuff_size;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ if (tmp)
+ (void) init_key_cache(tmp);
+}
+
+
+void ha_resize_key_cache(void)
+{
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ long tmp= (long) keybuff_size;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ (void) resize_key_cache(tmp);
+}
static int NEAR_F delete_file(const char *name,const char *ext,int extflag)
{
char buff[FN_REFLEN];
VOID(fn_format(buff,name,"",ext,extflag | 4));
- return(my_delete(buff,MYF(MY_WME)));
+ return(my_delete_with_symlink(buff,MYF(MY_WME)));
+}
+
+void st_ha_check_opt::init()
+{
+ flags= sql_flags= 0;
+ sort_buffer_size = current_thd->variables.myisam_sort_buff_size;
}
diff --git a/sql/handler.h b/sql/handler.h
index 89c19993238..60edf539e2c 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -21,11 +21,13 @@
#pragma interface /* gcc class implementation */
#endif
+#include <ft_global.h>
+
#ifndef NO_HASH
#define NO_HASH /* Not yet implemented */
#endif
-#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB) || defined(HAVE_GEMINI_DB)
+#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB)
#define USING_TRANSACTIONS
#endif
@@ -39,30 +41,18 @@
#define HA_ADMIN_INTERNAL_ERROR -4
#define HA_ADMIN_INVALID -5
-/* Bits in bas_flag to show what database can do */
-
-#define HA_READ_NEXT 1 /* Read next record with same key */
-#define HA_READ_PREV 2 /* Read prev. record with same key */
-#define HA_READ_ORDER 4 /* Read through record-keys in order */
-#define HA_READ_RND_SAME 8 /* Read RND-record to KEY-record
+/* Bits in table_flags() to show what database can do */
+#define HA_READ_RND_SAME 1 /* Read RND-record to KEY-record
(To update with RND-read) */
-#define HA_KEYPOS_TO_RNDPOS 16 /* ha_info gives pos to record */
-#define HA_LASTKEY_ORDER 32 /* Next record gives next record
- according last record read (even
- if database is updated after read) */
-#define HA_REC_NOT_IN_SEQ 64 /* ha_info don't return recnumber;
+#define HA_KEYPOS_TO_RNDPOS 2 /* ha_info gives pos to record */
+#define HA_TABLE_SCAN_ON_INDEX 4 /* No separate data/index file */
+#define HA_REC_NOT_IN_SEQ 8 /* ha_info don't return recnumber;
It returns a position to ha_r_rnd */
-#define HA_ONLY_WHOLE_INDEX 128 /* Can't use part key searches */
-#define HA_RSAME_NO_INDEX 256 /* RSAME can't restore index */
-#define HA_WRONG_ASCII_ORDER 512 /* Can't use sorting through key */
-#define HA_HAVE_KEY_READ_ONLY 1024 /* Can read only keys (no record) */
-#define HA_READ_NOT_EXACT_KEY 2048 /* Can read record after/before key */
-#define HA_NO_INDEX 4096 /* No index needed for next/prev */
-#define HA_LONGLONG_KEYS 8192 /* Can have longlong as key */
-#define HA_KEY_READ_WRONG_STR 16384 /* keyread returns converted strings */
-#define HA_NULL_KEY 32768 /* One can have keys with NULL */
-#define HA_DUPP_POS 65536 /* ha_position() gives dupp row */
-#define HA_NO_BLOBS 131072 /* Doesn't support blobs */
+#define HA_NO_INDEX 32 /* No index needed for next/prev */
+#define HA_KEY_READ_WRONG_STR 64 /* keyread returns converted strings */
+#define HA_NULL_KEY 128 /* One can have keys with NULL */
+#define HA_DUPP_POS 256 /* ha_position() gives dupp row */
+#define HA_NO_BLOBS 512 /* Doesn't support blobs */
#define HA_BLOB_KEY (HA_NO_BLOBS*2) /* key on blob */
#define HA_AUTO_PART_KEY (HA_BLOB_KEY*2)
#define HA_REQUIRE_PRIMARY_KEY (HA_AUTO_PART_KEY*2)
@@ -74,26 +64,47 @@
#define HA_NOT_DELETE_WITH_CACHE (HA_NOT_READ_AFTER_KEY*2)
#define HA_NO_TEMP_TABLES (HA_NOT_DELETE_WITH_CACHE*2)
#define HA_NO_PREFIX_CHAR_KEYS (HA_NO_TEMP_TABLES*2)
-#define HA_NO_FULLTEXT_KEY (HA_NO_PREFIX_CHAR_KEYS*2)
-
- /* Parameters for open() (in register form->filestat) */
- /* HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED */
+#define HA_CAN_FULLTEXT (HA_NO_PREFIX_CHAR_KEYS*2)
+#define HA_CAN_SQL_HANDLER (HA_CAN_FULLTEXT*2)
+#define HA_NO_AUTO_INCREMENT (HA_CAN_SQL_HANDLER*2)
+/* Table data are stored in separate files */
+#define HA_FILE_BASED (HA_NO_AUTO_INCREMENT*2)
+
+/*
+ Next record gives next record according last record read (even
+ if database is updated after read). Not used at this point.
+*/
+#define HA_LASTKEY_ORDER (HA_FILE_BASED*2)
+
+
+/* bits in index_flags(index_number) for what you can do with index */
+#define HA_WRONG_ASCII_ORDER 1 /* Can't use sorting through key */
+#define HA_READ_NEXT 2 /* Read next record with same key */
+#define HA_READ_PREV 4 /* Read prev. record with same key */
+#define HA_READ_ORDER 8 /* Read through record-keys in order */
+#define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */
+#define HA_NOT_READ_PREFIX_LAST 32 /* No support for index_read_last() */
+#define HA_KEY_READ_ONLY 64 /* Support HA_EXTRA_KEYREAD */
+
+/*
+ Parameters for open() (in register form->filestat)
+ HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
+*/
#define HA_OPEN_KEYFILE 1
#define HA_OPEN_RNDFILE 2
#define HA_GET_INDEX 4
#define HA_GET_INFO 8 /* do a ha_info() after open */
#define HA_READ_ONLY 16 /* File opened as readonly */
-#define HA_TRY_READ_ONLY 32 /* Try readonly if can't */
- /* open with read and write */
+/* Try readonly if can't open with read and write */
+#define HA_TRY_READ_ONLY 32
#define HA_WAIT_IF_LOCKED 64 /* Wait if locked on open */
#define HA_ABORT_IF_LOCKED 128 /* skip if locked on open.*/
#define HA_BLOCK_LOCK 256 /* unlock when reading some records */
#define HA_OPEN_TEMPORARY 512
- /* Error on write which is recoverable (Key exist) */
-
-#define HA_WRITE_SKIPP 121 /* Duplicate key on write */
+ /* Errors on write which is recoverable (Key exist) */
+#define HA_WRITE_SKIP 121 /* Duplicate key on write */
#define HA_READ_CHECK 123 /* Update with is recoverable */
#define HA_CANT_DO_THAT 131 /* Databasehandler can't do it */
@@ -111,23 +122,27 @@ enum db_type { DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
- DB_TYPE_BERKELEY_DB, DB_TYPE_INNOBASE, DB_TYPE_GEMINI,
+ DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, DB_TYPE_GEMINI,
DB_TYPE_DEFAULT };
-enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC,
- ROW_TYPE_COMPRESSED };
+enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
+ ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED};
/* struct to hold information about the table that should be created */
/* Bits in used_fields */
-#define HA_CREATE_USED_AUTO 1
-#define HA_CREATE_USED_RAID 2
-#define HA_CREATE_USED_UNION 4
+#define HA_CREATE_USED_AUTO 1
+#define HA_CREATE_USED_RAID 2
+#define HA_CREATE_USED_UNION 4
+#define HA_CREATE_USED_INSERT_METHOD 8
+#define HA_CREATE_USED_MIN_ROWS 16
+#define HA_CREATE_USED_MAX_ROWS 32
+#define HA_CREATE_USED_AVG_ROW_LENGTH 64
+#define HA_CREATE_USED_PACK_KEYS 128
typedef struct st_thd_trans {
void *bdb_tid;
void *innobase_tid;
- void *gemini_tid;
bool innodb_active_trans;
} THD_TRANS;
@@ -136,20 +151,22 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
typedef struct st_ha_create_information
{
- ulong table_options;
- enum db_type db_type;
- enum row_type row_type;
- ulong avg_row_length;
+ const char *comment,*password;
+ const char *data_file_name, *index_file_name;
+ const char *alias;
ulonglong max_rows,min_rows;
ulonglong auto_increment_value;
- char *comment,*password;
- char *create_statement;
- uint options; /* OR of HA_CREATE_ options */
- uint raid_type,raid_chunks;
+ ulong table_options;
+ ulong avg_row_length;
ulong raid_chunksize;
- bool if_not_exists;
ulong used_fields;
SQL_LIST merge_list;
+ enum db_type db_type;
+ enum row_type row_type;
+ uint options; /* OR of HA_CREATE_ options */
+ uint raid_type,raid_chunks;
+ uint merge_insert_method;
+ bool table_existed; /* 1 in create if table existed */
} HA_CREATE_INFO;
@@ -157,60 +174,55 @@ typedef struct st_ha_create_information
struct st_table;
typedef struct st_table TABLE;
-extern ulong myisam_sort_buffer_size;
typedef struct st_ha_check_opt
{
ulong sort_buffer_size;
- uint flags;
- bool quick;
- bool changed_files;
- bool optimize;
- bool retry_without_quick;
- inline void init()
- {
- flags= 0; quick= optimize= retry_without_quick=0;
- sort_buffer_size = myisam_sort_buffer_size;
- }
+ uint flags; /* isam layer flags (e.g. for myisamchk) */
+ uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
+ void init();
} HA_CHECK_OPT;
class handler :public Sql_alloc
{
protected:
struct st_table *table; /* The table definition */
- uint active_index;
public:
byte *ref; /* Pointer to current row */
byte *dupp_ref; /* Pointer to dupp row */
- uint ref_length; /* Length of ref (1-8) */
- uint block_size; /* index block size */
- ha_rows records; /* Records i datafilen */
- ha_rows deleted; /* Deleted records */
ulonglong data_file_length; /* Length off data file */
ulonglong max_data_file_length; /* Length off data file */
ulonglong index_file_length;
ulonglong max_index_file_length;
ulonglong delete_length; /* Free bytes */
ulonglong auto_increment_value;
- uint raid_type,raid_chunks;
+ ha_rows records; /* Records in table */
+ ha_rows deleted; /* Deleted records */
ulong raid_chunksize;
- uint errkey; /* Last dup key */
- uint sortkey, key_used_on_scan;
+ ulong mean_rec_length; /* physical reclength */
time_t create_time; /* When table was created */
time_t check_time;
time_t update_time;
- ulong mean_rec_length; /* physical reclength */
- void *ft_handler;
+ uint errkey; /* Last dup key */
+ uint sortkey, key_used_on_scan;
+ uint active_index;
+ /* Length of ref (1-8 or the clustered key length) */
+ uint ref_length;
+ uint block_size; /* index block size */
+ uint raid_type,raid_chunks;
+ FT_INFO *ft_handler;
bool auto_increment_column_changed;
-
- handler(TABLE *table_arg) : table(table_arg),active_index(MAX_REF_PARTS),
- ref(0),ref_length(sizeof(my_off_t)), block_size(0),records(0),deleted(0),
- data_file_length(0), max_data_file_length(0), index_file_length(0),
- delete_length(0), auto_increment_value(0), raid_type(0),
- key_used_on_scan(MAX_KEY),
- create_time(0), check_time(0), update_time(0), mean_rec_length(0),
- ft_handler(0)
+ bool implicit_emptied; /* Can be !=0 only if HEAP */
+
+ handler(TABLE *table_arg) :table(table_arg),
+ ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0),
+ delete_length(0), auto_increment_value(0),
+ records(0), deleted(0), mean_rec_length(0),
+ create_time(0), check_time(0), update_time(0),
+ key_used_on_scan(MAX_KEY), active_index(MAX_REF_PARTS),
+ ref_length(sizeof(my_off_t)), block_size(0),
+ raid_type(0), ft_handler(0), implicit_emptied(0)
{}
virtual ~handler(void) {}
int ha_open(const char *name, int mode, int test_if_locked);
@@ -220,13 +232,15 @@ public:
uint get_dup_key(int error);
void change_table_ptr(TABLE *table_arg) { table=table_arg; }
virtual double scan_time()
- { return ulonglong2double(data_file_length) / IO_SIZE + 1; }
- virtual double read_time(ha_rows rows) { return rows; }
+ { return ulonglong2double(data_file_length) / IO_SIZE + 2; }
+ virtual double read_time(uint index, uint ranges, ha_rows rows)
+ { return rows2double(ranges+rows); }
virtual bool fast_key_read() { return 0;}
virtual key_map keys_to_use_for_scanning() { return 0; }
virtual bool has_transactions(){ return 0;}
virtual uint extra_rec_buf_length() { return 0; }
virtual ha_rows estimate_number_of_rows() { return records+EXTRA_RECORDS; }
+ virtual const char *index_type(uint key_number) { return "";}
virtual int index_init(uint idx) { active_index=idx; return 0;}
virtual int index_end() {return 0; }
@@ -238,7 +252,7 @@ public:
virtual int update_row(const byte * old_data, byte * new_data)=0;
virtual int delete_row(const byte * buf)=0;
virtual int index_read(byte * buf, const byte * key,
- uint key_len, enum ha_rkey_function find_flag)=0;
+ uint key_len, enum ha_rkey_function find_flag)=0;
virtual int index_read_idx(byte * buf, uint index, const byte * key,
uint key_len, enum ha_rkey_function find_flag)=0;
virtual int index_next(byte * buf)=0;
@@ -246,17 +260,21 @@ public:
virtual int index_first(byte * buf)=0;
virtual int index_last(byte * buf)=0;
virtual int index_next_same(byte *buf, const byte *key, uint keylen);
+ virtual int index_read_last(byte * buf, const byte * key, uint key_len)
+ {
+ return (my_errno=HA_ERR_WRONG_COMMAND);
+ }
virtual int ft_init()
{ return -1; }
- virtual void *ft_init_ext(uint inx,const byte *key, uint keylen,
+ virtual FT_INFO *ft_init_ext(uint mode,uint inx,const byte *key, uint keylen,
bool presort)
- { return (void *)NULL; }
+ { return NULL; }
virtual int ft_read(byte *buf) { return -1; }
virtual int rnd_init(bool scan=1)=0;
virtual int rnd_end() { return 0; }
virtual int rnd_next(byte *buf)=0;
virtual int rnd_pos(byte * buf, byte *pos)=0;
- virtual int rnd_first(byte *buf);
+ virtual int read_first_row(byte *buf, uint primary_key);
virtual int restart_rnd_next(byte *buf, byte *pos);
virtual ha_rows records_in_range(int inx,
const byte *start_key,uint start_key_len,
@@ -268,6 +286,10 @@ public:
virtual my_off_t row_position() { return HA_OFFSET_ERROR; }
virtual void info(uint)=0;
virtual int extra(enum ha_extra_function operation)=0;
+ virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
+ {
+ return extra(operation);
+ }
virtual int reset()=0;
virtual int external_lock(THD *thd, int lock_type)=0;
virtual void unlock_row() {}
@@ -281,10 +303,11 @@ public:
virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
+ /*
+ restore assumes .frm file must exist, and that generate_table() has been
+ called; It will just copy the data file and run repair.
+ */
virtual int restore(THD* thd, HA_CHECK_OPT* check_opt);
- // assumes .frm file must exist, and you must have already called
- // generate_table() - it will just copy the data file and run repair
-
virtual int dump(THD* thd, int fd = -1) { return ER_DUMP_NOT_IMPLEMENTED; }
virtual void deactivate_non_unique_index(ha_rows rows) {}
virtual bool activate_all_index(THD *thd) {return 0;}
@@ -296,11 +319,17 @@ public:
virtual void append_create_info(String *packet) {}
virtual char* get_foreign_key_create_info()
{ return(NULL);} /* gets foreign key create string from InnoDB */
+ virtual void init_table_handle_for_HANDLER()
+ { return; } /* prepare InnoDB for HANDLER */
virtual void free_foreign_key_create_info(char* str) {}
/* The following can be called without an open handler */
virtual const char *table_type() const =0;
virtual const char **bas_ext() const =0;
- virtual ulong option_flag() const =0;
+ virtual ulong table_flags(void) const =0;
+ virtual ulong index_flags(uint idx) const
+ {
+ return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_KEY_READ_ONLY);
+ }
virtual uint max_record_length() const =0;
virtual uint max_keys() const =0;
virtual uint max_key_parts() const =0;
@@ -320,17 +349,6 @@ public:
enum thr_lock_type lock_type)=0;
};
-#ifdef HAVE_GEMINI_DB
-struct st_gemini
-{
- void *context;
- unsigned long savepoint;
- bool needSavepoint;
- uint tx_isolation;
- uint lock_count;
-};
-#endif
-
/* Some extern variables used with handlers */
extern const char *ha_row_type[];
@@ -342,6 +360,8 @@ extern TYPELIB ha_table_typelib, tx_isolation_typelib;
#define ha_commit(thd) (ha_commit_trans((thd), &((thd)->transaction.all)))
#define ha_rollback(thd) (ha_rollback_trans((thd), &((thd)->transaction.all)))
+#define ha_supports_generate(T) (T != DB_TYPE_INNODB)
+
handler *get_new_handler(TABLE *table, enum db_type db_type);
my_off_t ha_get_ptr(byte *ptr, uint pack_length);
void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos);
@@ -354,15 +374,17 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
int ha_delete_table(enum db_type db_type, const char *path);
void ha_drop_database(char* path);
void ha_key_cache(void);
+void ha_resize_key_cache(void);
int ha_start_stmt(THD *thd);
-int ha_report_binlog_offset_and_commit(
- THD *thd,
- char *log_file_name,
- my_off_t end_offset);
+int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name,
+ my_off_t end_offset);
+int ha_commit_complete(THD *thd);
+int ha_release_temporary_latches(THD *thd);
int ha_commit_trans(THD *thd, THD_TRANS *trans);
int ha_rollback_trans(THD *thd, THD_TRANS *trans);
+int ha_rollback_to_savepoint(THD *thd, char *savepoint_name);
+int ha_savepoint(THD *thd, char *savepoint_name);
int ha_autocommit_or_rollback(THD *thd, int error);
void ha_set_spin_retries(uint retries);
bool ha_flush_logs(void);
-int ha_commit_rename(THD *thd);
int ha_recovery_logging(THD *thd, bool on);
diff --git a/sql/hash_filo.cc b/sql/hash_filo.cc
index 990d2d662d6..b85f8054f10 100644
--- a/sql/hash_filo.cc
+++ b/sql/hash_filo.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/hash_filo.h b/sql/hash_filo.h
index 157c2739add..34584b45d8c 100644
--- a/sql/hash_filo.h
+++ b/sql/hash_filo.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -24,7 +24,7 @@
#define HASH_FILO_H
#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
+#pragma interface /* gcc class interface */
#endif
class hash_filo_element
@@ -40,7 +40,7 @@ class hash_filo
{
const uint size, key_offset, key_length;
const hash_get_key get_key;
- void (*free_element)(void*);
+ hash_free_key free_element;
bool init;
hash_filo_element *first_link,*last_link;
@@ -49,7 +49,7 @@ public:
HASH cache;
hash_filo(uint size_arg, uint key_offset_arg , uint key_length_arg,
- hash_get_key get_key_arg,void (*free_element_arg)(void*))
+ hash_get_key get_key_arg, hash_free_key free_element_arg)
:size(size_arg), key_offset(key_offset_arg), key_length(key_length_arg),
get_key(get_key_arg), free_element(free_element_arg),init(0)
{
diff --git a/sql/hostname.cc b/sql/hostname.cc
index 21dbd5a2bbe..ed56e199c3c 100644
--- a/sql/hostname.cc
+++ b/sql/hostname.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -27,7 +27,9 @@
extern "C" { // Because of SCO 3.2V4.2
#endif
#if !defined( __WIN__) && !defined(OS2)
+#if !defined(__NETWARE__)
#include <sys/resource.h>
+#endif /* __NETWARE__ */
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
@@ -57,10 +59,13 @@ void hostname_cache_refresh()
bool hostname_cache_init()
{
+ host_entry tmp;
+ uint offset= (uint) ((char*) (&tmp.ip) - (char*) &tmp);
(void) pthread_mutex_init(&LOCK_hostname,MY_MUTEX_INIT_SLOW);
- if (!(hostname_cache=new hash_filo(HOST_CACHE_SIZE,offsetof(host_entry,ip),
+
+ if (!(hostname_cache=new hash_filo(HOST_CACHE_SIZE, offset,
sizeof(struct in_addr),NULL,
- (void (*)(void*)) free)))
+ (hash_free_key) free)))
return 1;
hostname_cache->clear();
return 0;
diff --git a/sql/init.cc b/sql/init.cc
index e6606b82b7c..7d90cc564a1 100644
--- a/sql/init.cc
+++ b/sql/init.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -38,13 +38,11 @@ void unireg_init(ulong options)
init_my_atof(); /* use our atof */
#endif
my_abort_hook=unireg_abort; /* Abort with close of databases */
- f_fyllchar=' '; /* Input fill char */
VOID(strmov(reg_ext,".frm"));
for (i=0 ; i < 6 ; i++) // YYMMDDHHMMSS
dayord.pos[i]=i;
specialflag=SPECIAL_SAME_DB_NAME;
- blob_newline='^'; /* Convert newline in blobs to this */
/* Make a tab of powers of 10 */
for (i=0,nr=1.0; i < array_elements(log_10) ; i++)
{ /* It's used by filesort... */
diff --git a/sql/item.cc b/sql/item.cc
index a09aa9962bc..fcc9372773a 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -37,7 +37,7 @@ void item_init(void)
Item::Item()
{
marker=0;
- binary=maybe_null=null_value=with_sum_func=0;
+ binary=maybe_null=null_value=with_sum_func=unsigned_flag=0;
name=0;
decimals=0; max_length=0;
next=current_thd->free_list; // Put in free list
@@ -117,6 +117,14 @@ bool Item::get_time(TIME *ltime)
return 0;
}
+Item_ident::Item_ident(const char *db_name_par,const char *table_name_par,
+ const char *field_name_par)
+ :db_name(db_name_par),table_name(table_name_par),field_name(field_name_par)
+{
+ name = (char*) field_name_par;
+}
+
+
Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name)
{
set_field(f);
@@ -132,6 +140,7 @@ void Item_field::set_field(Field *field_par)
table_name=field_par->table_name;
field_name=field_par->field_name;
binary=field_par->binary();
+ unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
}
const char *Item_ident::full_name() const
@@ -258,6 +267,22 @@ void Item_int::print(String *str)
str->append(name);
}
+String *Item_uint::val_str(String *str)
+{
+ str->set((ulonglong) value);
+ return str;
+}
+
+void Item_uint::print(String *str)
+{
+ if (!name)
+ {
+ str_value.set((ulonglong) value);
+ name=str_value.c_ptr();
+ }
+ str->append(name);
+}
+
String *Item_real::val_str(String *str)
{
@@ -310,13 +335,21 @@ bool Item::fix_fields(THD *thd,
bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
{
- if (!field)
+ if (!field) // If field is not checked
{
Field *tmp;
if (!(tmp=find_field_in_tables(thd,this,tables)))
return 1;
set_field(tmp);
}
+ else if (thd && thd->set_query_id && field->query_id != thd->query_id)
+ {
+ /* We only come here in unions */
+ TABLE *table=field->table;
+ field->query_id=thd->query_id;
+ table->used_fields++;
+ table->used_keys&=field->part_of_key;
+ }
return 0;
}
@@ -330,6 +363,8 @@ void Item::init_make_field(Send_field *tmp_field,
tmp_field->type=field_type;
tmp_field->length=max_length;
tmp_field->decimals=decimals;
+ if (unsigned_flag)
+ tmp_field->flags |= UNSIGNED_FLAG;
}
/* ARGSUSED */
@@ -345,6 +380,13 @@ void Item_int::make_field(Send_field *tmp_field)
init_make_field(tmp_field,FIELD_TYPE_LONGLONG);
}
+void Item_uint::make_field(Send_field *tmp_field)
+{
+ init_make_field(tmp_field,FIELD_TYPE_LONGLONG);
+ tmp_field->flags|= UNSIGNED_FLAG;
+ unsigned_flag=1;
+}
+
void Item_real::make_field(Send_field *tmp_field)
{
init_make_field(tmp_field,FIELD_TYPE_DOUBLE);
@@ -365,12 +407,14 @@ void Item_datetime::make_field(Send_field *tmp_field)
init_make_field(tmp_field,FIELD_TYPE_DATETIME);
}
+
void Item_null::make_field(Send_field *tmp_field)
{
init_make_field(tmp_field,FIELD_TYPE_NULL);
tmp_field->length=4;
}
+
void Item_func::make_field(Send_field *tmp_field)
{
init_make_field(tmp_field, ((result_type() == STRING_RESULT) ?
@@ -399,7 +443,7 @@ void Item_field::save_org_in_field(Field *to)
if (field->is_null())
{
null_value=1;
- set_field_to_null_with_conversions(to);
+ set_field_to_null_with_conversions(to, 1);
}
else
{
@@ -409,12 +453,12 @@ void Item_field::save_org_in_field(Field *to)
}
}
-bool Item_field::save_in_field(Field *to)
+bool Item_field::save_in_field(Field *to, bool no_conversions)
{
if (result_field->is_null())
{
null_value=1;
- return set_field_to_null_with_conversions(to);
+ return set_field_to_null_with_conversions(to, no_conversions);
}
else
{
@@ -441,9 +485,9 @@ bool Item_field::save_in_field(Field *to)
1 Field doesn't support NULL values and can't handle 'field = NULL'
*/
-bool Item_null::save_in_field(Field *field)
+bool Item_null::save_in_field(Field *field, bool no_conversions)
{
- return set_field_to_null_with_conversions(field);
+ return set_field_to_null_with_conversions(field, no_conversions);
}
@@ -465,7 +509,7 @@ bool Item_null::save_safe_in_field(Field *field)
}
-bool Item::save_in_field(Field *field)
+bool Item::save_in_field(Field *field, bool no_conversions)
{
if (result_type() == STRING_RESULT ||
result_type() == REAL_RESULT &&
@@ -476,7 +520,7 @@ bool Item::save_in_field(Field *field)
str_value.set_quick(buff,sizeof(buff));
result=val_str(&str_value);
if (null_value)
- return set_field_to_null_with_conversions(field);
+ return set_field_to_null_with_conversions(field, no_conversions);
field->set_notnull();
field->store(result->ptr(),result->length());
str_value.set_quick(0, 0);
@@ -493,7 +537,7 @@ bool Item::save_in_field(Field *field)
{
longlong nr=val_int();
if (null_value)
- return set_field_to_null_with_conversions(field);
+ return set_field_to_null_with_conversions(field, no_conversions);
field->set_notnull();
field->store(nr);
}
@@ -501,7 +545,7 @@ bool Item::save_in_field(Field *field)
}
-bool Item_string::save_in_field(Field *field)
+bool Item_string::save_in_field(Field *field, bool no_conversions)
{
String *result;
result=val_str(&str_value);
@@ -512,7 +556,8 @@ bool Item_string::save_in_field(Field *field)
return 0;
}
-bool Item_int::save_in_field(Field *field)
+
+bool Item_int::save_in_field(Field *field, bool no_conversions)
{
longlong nr=val_int();
if (null_value)
@@ -522,7 +567,7 @@ bool Item_int::save_in_field(Field *field)
return 0;
}
-bool Item_real::save_in_field(Field *field)
+bool Item_real::save_in_field(Field *field, bool no_conversions)
{
double nr=val();
if (null_value)
@@ -545,6 +590,14 @@ inline uint char_val(char X)
X-'a'+10);
}
+/* In MySQL 4.1 this will always return STRING_RESULT */
+
+enum Item_result Item_varbinary::result_type () const
+{
+ return (current_thd->variables.new_mode) ? STRING_RESULT : INT_RESULT;
+}
+
+
Item_varbinary::Item_varbinary(const char *str, uint str_length)
{
name=(char*) str-2; // Lex makes this start with 0x
@@ -577,7 +630,7 @@ longlong Item_varbinary::val_int()
}
-bool Item_varbinary::save_in_field(Field *field)
+bool Item_varbinary::save_in_field(Field *field, bool no_conversions)
{
field->set_notnull();
if (field->result_type() == STRING_RESULT)
@@ -602,19 +655,19 @@ void Item_varbinary::make_field(Send_field *tmp_field)
** pack data in buffer for sending
*/
-bool Item::send(String *packet)
+bool Item::send(THD *thd, String *packet)
{
char buff[MAX_FIELD_WIDTH];
+ CONVERT *convert;
String s(buff,sizeof(buff)),*res;
if (!(res=val_str(&s)))
return net_store_null(packet);
- CONVERT *convert;
- if ((convert=current_thd->convert_set))
+ if ((convert=thd->variables.convert_set))
return convert->store(packet,res->ptr(),res->length());
return net_store_data(packet,res->ptr(),res->length());
}
-bool Item_null::send(String *packet)
+bool Item_null::send(THD *thd, String *packet)
{
return net_store_null(packet);
}
@@ -628,29 +681,30 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables)
{
if (!ref)
{
- if (!(ref=find_item_in_list(this,thd->lex.item_list)))
+ if (!(ref=find_item_in_list(this,thd->lex.select->item_list)))
return 1;
max_length= (*ref)->max_length;
maybe_null= (*ref)->maybe_null;
decimals= (*ref)->decimals;
binary= (*ref)->binary;
+ with_sum_func= (*ref)->with_sum_func;
}
return 0;
}
+
/*
-** If item is a const function, calculate it and return a const item
-** The original item is freed if not returned
+ If item is a const function, calculate it and return a const item
+ The original item is freed if not returned
*/
Item_result item_cmp_type(Item_result a,Item_result b)
{
if (a == STRING_RESULT && b == STRING_RESULT)
return STRING_RESULT;
- else if (a == INT_RESULT && b == INT_RESULT)
+ if (a == INT_RESULT && b == INT_RESULT)
return INT_RESULT;
- else
- return REAL_RESULT;
+ return REAL_RESULT;
}
@@ -744,5 +798,6 @@ bool field_is_equal_to_item(Field *field,Item *item)
#ifdef __GNUC__
template class List<Item>;
template class List_iterator<Item>;
+template class List_iterator_fast<Item>;
template class List<List_item>;
#endif
diff --git a/sql/item.h b/sql/item.h
index d9d125b8bd4..f96f4cd506a 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -23,7 +23,7 @@ struct st_table_list;
void item_init(void); /* Init item functions */
class Item {
- Item(const Item &); /* Prevent use of theese */
+ Item(const Item &); /* Prevent use of these */
void operator=(Item &);
public:
static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
@@ -31,7 +31,7 @@ public:
enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM,
INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM,
- COPY_STR_ITEM,FIELD_AVG_ITEM,
+ COPY_STR_ITEM,FIELD_AVG_ITEM, DEFAULT_ITEM,
PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, CONST_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
@@ -43,6 +43,7 @@ public:
my_bool maybe_null; /* If item may be null */
my_bool null_value; /* if item is null */
my_bool binary;
+ my_bool unsigned_flag;
my_bool with_sum_func;
@@ -52,12 +53,12 @@ public:
void set_name(char* str,uint length=0);
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
virtual bool fix_fields(THD *,struct st_table_list *);
- virtual bool save_in_field(Field *field);
+ virtual bool save_in_field(Field *field, bool no_conversions);
virtual void save_org_in_field(Field *field)
- { (void) save_in_field(field); }
+ { (void) save_in_field(field, 1); }
virtual bool save_safe_in_field(Field *field)
- { return save_in_field(field); }
- virtual bool send(String *str);
+ { return save_in_field(field, 1); }
+ virtual bool send(THD *thd, String *str);
virtual bool eq(const Item *, bool binary_cmp) const;
virtual Item_result result_type () const { return REAL_RESULT; }
virtual enum Type type() const =0;
@@ -65,12 +66,29 @@ public:
virtual longlong val_int()=0;
virtual String *val_str(String*)=0;
virtual void make_field(Send_field *field)=0;
- virtual Field *tmp_table_field() { return 0; }
+ virtual Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return 0; }
virtual const char *full_name() const { return name ? name : "???"; }
virtual double val_result() { return val(); }
virtual longlong val_int_result() { return val_int(); }
virtual String *str_result(String* tmp) { return val_str(tmp); }
+ /* bit map of tables used by item */
virtual table_map used_tables() const { return (table_map) 0L; }
+ /*
+ Return table map of tables that can't be NULL tables (tables that are
+ used in a context where if they would contain a NULL row generated
+ by a LEFT or RIGHT join, the item would not be true).
+ This expression is used on WHERE item to determinate if a LEFT JOIN can be
+ converted to a normal join.
+ Generally this function should return used_tables() if the function
+ would return null if any of the arguments are null
+ As this is only used in the beginning of optimization, the value don't
+ have to be updated in update_used_tables()
+ */
+ virtual table_map not_null_tables() const { return used_tables(); }
+ /*
+ Returns true if this is a simple constant item like an integer, not
+ a constant expression
+ */
virtual bool basic_const_item() const { return 0; }
virtual Item *new_item() { return 0; } /* Only for const items */
virtual cond_result eq_cmp_result() const { return COND_OK; }
@@ -84,6 +102,13 @@ public:
virtual bool get_time(TIME *ltime);
virtual bool get_date_result(TIME *ltime,bool fuzzydate)
{ return get_date(ltime,fuzzydate); }
+ virtual bool is_null() { return 0; }
+ virtual unsigned int size_of()= 0;
+ virtual void top_level_item() {}
+ virtual void set_result_field(Field *field) {}
+ virtual bool is_result_field() { return 0; }
+ virtual void save_in_result_field(bool no_conversions) {}
+ virtual void no_rows_in_result() {}
};
@@ -94,12 +119,12 @@ public:
const char *table_name;
const char *field_name;
Item_ident(const char *db_name_par,const char *table_name_par,
- const char *field_name_par)
- :db_name(db_name_par),table_name(table_name_par),field_name(field_name_par)
- { name = (char*) field_name_par; }
+ const char *field_name_par);
const char *full_name() const;
+ unsigned int size_of() { return sizeof(*this);}
};
+
class Item_field :public Item_ident
{
void set_field(Field *field);
@@ -120,20 +145,25 @@ public:
double val_result();
longlong val_int_result();
String *str_result(String* tmp);
- bool send(String *str_arg) { return result_field->send(str_arg); }
+ bool send(THD *thd, String *str_arg)
+ {
+ return result_field->send(thd,str_arg);
+ }
void make_field(Send_field *field);
bool fix_fields(THD *,struct st_table_list *);
- bool save_in_field(Field *field);
+ bool save_in_field(Field *field,bool no_conversions);
void save_org_in_field(Field *field);
table_map used_tables() const;
enum Item_result result_type () const
{
return field->result_type();
}
- Field *tmp_table_field() { return result_field; }
+ Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return result_field; }
bool get_date(TIME *ltime,bool fuzzydate);
bool get_date_result(TIME *ltime,bool fuzzydate);
bool get_time(TIME *ltime);
+ bool is_null() { return field->is_null(); }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -148,13 +178,15 @@ public:
longlong val_int();
String *val_str(String *str);
void make_field(Send_field *field);
- bool save_in_field(Field *field);
+ bool save_in_field(Field *field, bool no_conversions);
bool save_safe_in_field(Field *field);
enum Item_result result_type () const
{ return STRING_RESULT; }
- bool send(String *str);
+ bool send(THD *thd, String *str);
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_null(name); }
+ bool is_null() { return 1; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -180,10 +212,31 @@ public:
double val() { return (double) value; }
String *val_str(String*);
void make_field(Send_field *field);
- bool save_in_field(Field *field);
+ bool save_in_field(Field *field, bool no_conversions);
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_int(name,value,max_length); }
void print(String *str);
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
+class Item_uint :public Item_int
+{
+public:
+ Item_uint(const char *str_arg, uint length) :
+ Item_int(str_arg, (longlong) strtoull(str_arg,(char**) 0,10), length) {}
+ Item_uint(uint32 i) :Item_int((longlong) i, 10) {}
+ double val() { return ulonglong2double(value); }
+ String *val_str(String*);
+ void make_field(Send_field *field);
+ Item *new_item() { return new Item_uint(name,max_length); }
+ bool fix_fields(THD *thd,struct st_table_list *table_list)
+ {
+ unsigned_flag= 1;
+ return 0;
+ }
+ void print(String *str);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -195,18 +248,18 @@ public:
Item_real(const char *str_arg,uint length) :value(atof(str_arg))
{
name=(char*) str_arg;
- decimals=nr_of_decimals(str_arg);
+ decimals=(uint8) nr_of_decimals(str_arg);
max_length=length;
}
Item_real(const char *str,double val_arg,uint decimal_par,uint length)
:value(val_arg)
{
name=(char*) str;
- decimals=decimal_par;
+ decimals=(uint8) decimal_par;
max_length=length;
}
Item_real(double value_par) :value(value_par) {}
- bool save_in_field(Field *field);
+ bool save_in_field(Field *field, bool no_conversions);
enum Type type() const { return REAL_ITEM; }
double val() { return value; }
longlong val_int() { return (longlong) (value+(value > 0 ? 0.5 : -0.5));}
@@ -214,6 +267,7 @@ public:
void make_field(Send_field *field);
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_real(name,value,decimals,max_length); }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -225,6 +279,7 @@ public:
decimals=NOT_FIXED_DEC;
max_length=DBL_DIG+8;
}
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_string :public Item
@@ -249,7 +304,7 @@ public:
double val() { return atof(str_value.ptr()); }
longlong val_int() { return strtoll(str_value.ptr(),(char**) 0,10); }
String *val_str(String*) { return (String*) &str_value; }
- bool save_in_field(Field *field);
+ bool save_in_field(Field *field, bool no_conversions);
void make_field(Send_field *field);
enum Item_result result_type () const { return STRING_RESULT; }
bool basic_const_item() const { return 1; }
@@ -258,8 +313,31 @@ public:
String *const_string() { return &str_value; }
inline void append(char *str,uint length) { str_value.append(str,length); }
void print(String *str);
+ unsigned int size_of() { return sizeof(*this);}
};
+
+/* For INSERT ... VALUES (DEFAULT) */
+
+class Item_default :public Item
+{
+public:
+ Item_default() { name= (char*) "DEFAULT"; }
+ enum Type type() const { return DEFAULT_ITEM; }
+ void make_field(Send_field *field) {}
+ bool save_in_field(Field *field, bool no_conversions)
+ {
+ field->set_default();
+ return 0;
+ }
+ virtual double val() { return 0.0; }
+ virtual longlong val_int() { return 0; }
+ virtual String *val_str(String *str) { return 0; }
+ bool basic_const_item() const { return 1; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
/* for show tables */
class Item_datetime :public Item_string
@@ -268,6 +346,7 @@ public:
Item_datetime(const char *item_name): Item_string(item_name,"",0)
{ max_length=19;}
void make_field(Send_field *field);
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_empty_string :public Item_string
@@ -276,6 +355,7 @@ public:
Item_empty_string(const char *header,uint length) :Item_string("",0)
{ name=(char*) header; max_length=length;}
void make_field(Send_field *field);
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_varbinary :public Item
@@ -287,9 +367,10 @@ public:
double val() { return (double) Item_varbinary::val_int(); }
longlong val_int();
String *val_str(String*) { return &str_value; }
- bool save_in_field(Field *field);
+ bool save_in_field(Field *field, bool no_conversions);
void make_field(Send_field *field);
- enum Item_result result_type () const { return INT_RESULT; }
+ enum Item_result result_type () const;
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -299,15 +380,23 @@ public:
Field *result_field; /* Save result here */
Item_result_field() :result_field(0) {}
~Item_result_field() {} /* Required with gcc 2.95 */
- Field *tmp_table_field() { return result_field; }
+ Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return result_field; }
table_map used_tables() const { return 1; }
virtual void fix_length_and_dec()=0;
+ unsigned int size_of() { return sizeof(*this);}
+ void set_result_field(Field *field) { result_field= field; }
+ bool is_result_field() { return 1; }
+ void save_in_result_field(bool no_conversions)
+ {
+ save_in_field(result_field, no_conversions);
+ }
};
class Item_ref :public Item_ident
{
public:
+ Field *result_field; /* Save result here */
Item **ref;
Item_ref(char *db_par,char *table_name_par,char *field_name_par)
:Item_ident(db_par,table_name_par,field_name_par),ref(0) {}
@@ -335,17 +424,30 @@ public:
null_value=(*ref)->null_value;
return tmp;
}
+ bool is_null()
+ {
+ (void) (*ref)->val_int_result();
+ return (*ref)->null_value;
+ }
bool get_date(TIME *ltime,bool fuzzydate)
{
return (null_value=(*ref)->get_date_result(ltime,fuzzydate));
}
- bool send(String *tmp) { return (*ref)->send(tmp); }
+ bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); }
void make_field(Send_field *field) { (*ref)->make_field(field); }
bool fix_fields(THD *,struct st_table_list *);
- bool save_in_field(Field *field) { return (*ref)->save_in_field(field); }
+ bool save_in_field(Field *field, bool no_conversions)
+ { return (*ref)->save_in_field(field, no_conversions); }
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
enum Item_result result_type () const { return (*ref)->result_type(); }
table_map used_tables() const { return (*ref)->used_tables(); }
+ unsigned int size_of() { return sizeof(*this);}
+ void set_result_field(Field *field) { result_field= field; }
+ bool is_result_field() { return 1; }
+ void save_in_result_field(bool no_conversions)
+ {
+ (*ref)->save_in_field(result_field, no_conversions);
+ }
};
@@ -361,10 +463,11 @@ class Item_int_with_ref :public Item_int
public:
Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg)
{}
- bool save_in_field(Field *field)
+ bool save_in_field(Field *field, bool no_conversions)
{
- return ref->save_in_field(field);
+ return ref->save_in_field(field, no_conversions);
}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -398,6 +501,8 @@ public:
void copy();
table_map used_tables() const { return (table_map) 1L; }
bool const_item() const { return 0; }
+ bool is_null() { return null_value; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -408,6 +513,7 @@ public:
Item_buff() :null_value(0) {}
virtual bool cmp(void)=0;
virtual ~Item_buff(); /*line -e1509 */
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_str_buff :public Item_buff
@@ -418,6 +524,7 @@ public:
Item_str_buff(Item *arg) :item(arg),value(arg->max_length) {}
bool cmp(void);
~Item_str_buff(); // Deallocate String:s
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -428,6 +535,7 @@ class Item_real_buff :public Item_buff
public:
Item_real_buff(Item *item_par) :item(item_par),value(0.0) {}
bool cmp(void);
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_int_buff :public Item_buff
@@ -437,6 +545,7 @@ class Item_int_buff :public Item_buff
public:
Item_int_buff(Item *item_par) :item(item_par),value(0) {}
bool cmp(void);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -453,10 +562,10 @@ public:
buff= (char*) sql_calloc(length=field->pack_length());
}
bool cmp(void);
+ unsigned int size_of() { return sizeof(*this);}
};
extern Item_buff *new_Item_buff(Item *item);
extern Item_result item_cmp_type(Item_result a,Item_result b);
extern Item *resolve_const_item(Item *item,Item *cmp_item);
extern bool field_is_equal_to_item(Field *field,Item *item);
-Item *get_system_var(LEX_STRING name);
diff --git a/sql/item_buff.cc b/sql/item_buff.cc
index 61e1f5498a9..b55a4dc66a0 100644
--- a/sql/item_buff.cc
+++ b/sql/item_buff.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index e82dc3f90ce..82f368970e2 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -26,8 +26,8 @@
/*
Test functions
- These returns 0LL if false and 1LL if true and null if some arg is null
- 'AND' and 'OR' never return null
+ Most of these returns 0LL if false and 1LL if true and
+ NULL if some arg is NULL.
*/
longlong Item_func_not::val_int()
@@ -37,18 +37,24 @@ longlong Item_func_not::val_int()
return !null_value && value == 0 ? 1 : 0;
}
+/*
+ Convert a constant expression or string to an integer.
+ This is done when comparing DATE's of different formats and
+ also when comparing bigint to strings (in which case the string
+ is converted once to a bigint).
+*/
static bool convert_constant_item(Field *field, Item **item)
{
if ((*item)->const_item())
{
- (*item)->save_in_field(field);
- if (!((*item)->null_value))
+ if (!(*item)->save_in_field(field, 1) &&
+ !((*item)->null_value))
{
Item *tmp=new Item_int_with_ref(field->val_int(), *item);
if (tmp)
*item=tmp;
- return 1;
+ return 1; // Item was replaced
}
}
return 0;
@@ -57,7 +63,7 @@ static bool convert_constant_item(Field *field, Item **item)
void Item_bool_func2::fix_length_and_dec()
{
- max_length=1;
+ max_length=1; // Function returns 0 or 1
/*
As some compare functions are generated after sql_yacc,
@@ -256,7 +262,7 @@ longlong Item_func_strcmp::val_int()
null_value=1;
return 0;
}
- int value=stringcmp(a,b);
+ int value= binary ? stringcmp(a,b) : sortcmp(a,b);
null_value=0;
return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
}
@@ -286,10 +292,13 @@ void Item_func_interval::fix_length_and_dec()
}
}
maybe_null=0; max_length=2;
- used_tables_cache|=item->used_tables();
+ used_tables_cache|= item->used_tables();
+ not_null_tables_cache&= item->not_null_tables();
with_sum_func= with_sum_func || item->with_sum_func;
+ const_item_cache&=item->const_item();
}
+
void Item_func_interval::split_sum_func(List<Item> &fields)
{
if (item->with_sum_func && item->type() != SUM_FUNC_ITEM)
@@ -311,26 +320,25 @@ void Item_func_interval::split_sum_func(List<Item> &fields)
longlong Item_func_interval::val_int()
{
- double value=item->val();
+ double value= item->val();
if (item->null_value)
- return -1; // -1 if null /* purecov: inspected */
+ return -1; // -1 if NULL
if (intervals)
{ // Use binary search to find interval
- uint start,end;
- start=0; end=arg_count-1;
+ uint start= 0, end= arg_count - 1;
while (start != end)
{
- uint mid=(start+end+1)/2;
+ uint mid= (start + end + 1) / 2;
if (intervals[mid] <= value)
- start=mid;
+ start= mid;
else
- end=mid-1;
+ end= mid - 1;
}
- return (value < intervals[start]) ? 0 : start+1;
+ return (value < intervals[start]) ? 0 : start + 1;
}
if (args[0]->val() > value)
return 0;
- for (uint i=1 ; i < arg_count ; i++)
+ for (uint i= 1; i < arg_count; i++)
{
if (args[i]->val() > value)
return i;
@@ -357,13 +365,19 @@ void Item_func_between::fix_length_and_dec()
*/
if (!args[0] || !args[1] || !args[2])
return;
- cmp_type=args[0]->result_type();
- if (args[0]->binary)
+ cmp_type=item_cmp_type(args[0]->result_type(),
+ item_cmp_type(args[1]->result_type(),
+ args[2]->result_type()));
+ if (args[0]->binary | args[1]->binary | args[2]->binary)
string_compare=stringcmp;
else
string_compare=sortcmp;
- // Make a special case of compare with fields to get nicer DATE comparisons
+ /*
+ Make a special case of compare with date/time and longlong fields.
+ They are compared as integers, so for const item this time-consuming
+ conversion can be done only once, not for every single comparison
+ */
if (args[0]->type() == FIELD_ITEM)
{
Field *field=((Item_field*) args[0])->field;
@@ -445,15 +459,28 @@ longlong Item_func_between::val_int()
return 0;
}
+static Item_result item_store_type(Item_result a,Item_result b)
+{
+ if (a == STRING_RESULT || b == STRING_RESULT)
+ return STRING_RESULT;
+ if (a == REAL_RESULT || b == REAL_RESULT)
+ return REAL_RESULT;
+ return INT_RESULT;
+}
+
void
Item_func_ifnull::fix_length_and_dec()
{
maybe_null=args[1]->maybe_null;
max_length=max(args[0]->max_length,args[1]->max_length);
decimals=max(args[0]->decimals,args[1]->decimals);
- cached_result_type=args[0]->result_type();
+ if ((cached_result_type=item_store_type(args[0]->result_type(),
+ args[1]->result_type())) !=
+ REAL_RESULT)
+ decimals= 0;
}
+
double
Item_func_ifnull::val()
{
@@ -499,6 +526,7 @@ Item_func_ifnull::val_str(String *str)
return res;
}
+
void
Item_func_if::fix_length_and_dec()
{
@@ -507,17 +535,32 @@ Item_func_if::fix_length_and_dec()
decimals=max(args[1]->decimals,args[2]->decimals);
enum Item_result arg1_type=args[1]->result_type();
enum Item_result arg2_type=args[2]->result_type();
+ bool null1=args[1]->null_value;
+ bool null2=args[2]->null_value;
- binary=1;
- if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT)
+ if (null1)
+ {
+ cached_result_type= arg2_type;
+ binary= args[2]->binary;
+ }
+ else if (null2)
+ {
+ cached_result_type= arg1_type;
+ binary= args[1]->binary;
+ }
+ else if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT)
{
cached_result_type = STRING_RESULT;
binary=args[1]->binary | args[2]->binary;
}
- else if (arg1_type == REAL_RESULT || arg2_type == REAL_RESULT)
- cached_result_type = REAL_RESULT;
else
- cached_result_type=arg1_type; // Should be INT_RESULT
+ {
+ binary=1; // Number
+ if (arg1_type == REAL_RESULT || arg2_type == REAL_RESULT)
+ cached_result_type = REAL_RESULT;
+ else
+ cached_result_type=arg1_type; // Should be INT_RESULT
+ }
}
@@ -563,7 +606,7 @@ Item_func_nullif::fix_length_and_dec()
}
/*
- nullif() returns NULL if arguments are different, else it returns the
+ nullif () returns NULL if arguments are different, else it returns the
first argument.
Note that we have to evaluate the first argument twice as the compare
may have been done with a different type than return value
@@ -840,8 +883,9 @@ String *Item_func_coalesce::val_str(String *str)
null_value=0;
for (uint i=0 ; i < arg_count ; i++)
{
- if (args[i]->val_str(str) != NULL)
- return args[i]->val_str(str);
+ String *res;
+ if ((res=args[i]->val_str(str)))
+ return res;
}
null_value=1;
return 0;
@@ -1001,15 +1045,18 @@ void Item_func_in::fix_length_and_dec()
array= new in_double(arg_count);
break;
}
- uint j=0;
- for (uint i=0 ; i < arg_count ; i++)
+ if (array && !(current_thd->fatal_error)) // If not EOM
{
- array->set(j,args[i]);
- if (!args[i]->null_value) // Skipp NULL values
- j++;
+ uint j=0;
+ for (uint i=0 ; i < arg_count ; i++)
+ {
+ array->set(j,args[i]);
+ if (!args[i]->null_value) // Skip NULL values
+ j++;
+ }
+ if ((array->used_count=j))
+ array->sort();
}
- if ((array->used_count=j))
- array->sort();
}
else
{
@@ -1030,8 +1077,9 @@ void Item_func_in::fix_length_and_dec()
}
maybe_null= item->maybe_null;
max_length=2;
- used_tables_cache|=item->used_tables();
- const_item_cache&=item->const_item();
+ used_tables_cache|= item->used_tables();
+ not_null_tables_cache&= item->not_null_tables();
+ const_item_cache&= item->const_item();
}
@@ -1128,17 +1176,27 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables)
{
List_iterator<Item> li(list);
Item *item;
+#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
char buff[sizeof(char*)]; // Max local vars in function
- used_tables_cache=0;
- const_item_cache=0;
+#endif
+
+ not_null_tables_cache= used_tables_cache= 0;
+ const_item_cache= 0;
+ /*
+ and_table_cache is the value that Item_cond_or() returns for
+ not_null_tables()
+ */
+ and_tables_cache= ~(table_map) 0;
if (thd && check_stack_overrun(thd,buff))
- return 0; // Fatal error flag is set!
+ return 1; // Fatal error flag is set!
while ((item=li++))
{
+ table_map tmp_table_map;
while (item->type() == Item::COND_ITEM &&
((Item_cond*) item)->functype() == functype())
{ // Identical function
+
li.replace(((Item_cond*) item)->list);
((Item_cond*) item)->list.empty();
#ifdef DELETE_ITEMS
@@ -1146,11 +1204,16 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables)
#endif
item= *li.ref(); // new current item
}
+ if (abort_on_null)
+ item->top_level_item();
if (item->fix_fields(thd,tables))
return 1; /* purecov: inspected */
- used_tables_cache|=item->used_tables();
- with_sum_func= with_sum_func || item->with_sum_func;
- const_item_cache&=item->const_item();
+ used_tables_cache|= item->used_tables();
+ tmp_table_map= item->not_null_tables();
+ not_null_tables_cache|= tmp_table_map;
+ and_tables_cache&= tmp_table_map;
+ const_item_cache&= item->const_item();
+ with_sum_func= with_sum_func || item->with_sum_func;
if (item->maybe_null)
maybe_null=1;
}
@@ -1189,17 +1252,19 @@ Item_cond::used_tables() const
return used_tables_cache;
}
+
void Item_cond::update_used_tables()
{
+ List_iterator_fast<Item> li(list);
+ Item *item;
+
used_tables_cache=0;
const_item_cache=1;
- List_iterator<Item> li(list);
- Item *item;
while ((item=li++))
{
item->update_used_tables();
- used_tables_cache|=item->used_tables();
- const_item_cache&= item->const_item();
+ used_tables_cache|= item->used_tables();
+ const_item_cache&= item->const_item();
}
}
@@ -1207,7 +1272,7 @@ void Item_cond::update_used_tables()
void Item_cond::print(String *str)
{
str->append('(');
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
if ((item=li++))
item->print(str);
@@ -1221,31 +1286,44 @@ void Item_cond::print(String *str)
str->append(')');
}
+/*
+ Evalution of AND(expr, expr, expr ...)
+
+ NOTES:
+ abort_if_null is set for AND expressions for which we don't care if the
+ result is NULL or 0. This is set for:
+ - WHERE clause
+ - HAVING clause
+ - IF(expression)
+
+ RETURN VALUES
+ 1 If all expressions are true
+ 0 If all expressions are false or if we find a NULL expression and
+ 'abort_on_null' is set.
+ NULL if all expression are either 1 or NULL
+*/
+
longlong Item_cond_and::val_int()
{
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
+ null_value= 0;
while ((item=li++))
{
if (item->val_int() == 0)
{
- /*
- TODO: In case of NULL, ANSI would require us to continue evaluation
- until we get a FALSE value or run out of values; This would
- require a lot of unnecessary evaluation, which we skip for now
- */
- null_value=item->null_value;
- return 0;
+ if (abort_on_null || !(null_value= item->null_value))
+ return 0; // return FALSE
}
}
- null_value=0;
- return 1;
+ return null_value ? 0 : 1;
}
+
longlong Item_cond_or::val_int()
{
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
null_value=0;
while ((item=li++))
@@ -1290,12 +1368,16 @@ Item *and_expressions(Item *a, Item *b, Item **org_item)
{
Item_cond *res;
if ((res= new Item_cond_and(a, (Item*) b)))
+ {
res->used_tables_cache= a->used_tables() | b->used_tables();
+ res->not_null_tables_cache= a->not_null_tables() | b->not_null_tables();
+ }
return res;
}
if (((Item_cond_and*) a)->add((Item*) b))
return 0;
((Item_cond_and*) a)->used_tables_cache|= b->used_tables();
+ ((Item_cond_and*) a)->not_null_tables_cache|= b->not_null_tables();
return a;
}
@@ -1308,14 +1390,12 @@ longlong Item_func_isnull::val_int()
*/
if (!used_tables_cache)
return cached_value;
- (void) args[0]->val();
- return (args[0]->null_value) ? 1 : 0;
+ return args[0]->is_null() ? 1: 0;
}
longlong Item_func_isnotnull::val_int()
{
- (void) args[0]->val();
- return !(args[0]->null_value) ? 1 : 0;
+ return args[0]->is_null() ? 0 : 1;
}
@@ -1325,23 +1405,23 @@ void Item_func_like::fix_length_and_dec()
// cmp_type=STRING_RESULT; // For quick select
}
-
longlong Item_func_like::val_int()
{
- String *res,*res2;
- res=args[0]->val_str(&tmp_value1);
+ String* res = args[0]->val_str(&tmp_value1);
if (args[0]->null_value)
{
null_value=1;
return 0;
}
- res2=args[1]->val_str(&tmp_value2);
+ String* res2 = args[1]->val_str(&tmp_value2);
if (args[1]->null_value)
{
null_value=1;
return 0;
}
null_value=0;
+ if (canDoTurboBM)
+ return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
if (binary)
return wild_compare(*res,*res2,escape) ? 0 : 1;
else
@@ -1353,18 +1433,75 @@ longlong Item_func_like::val_int()
Item_func::optimize_type Item_func_like::select_optimize() const
{
- if (args[1]->type() == STRING_ITEM)
+ if (args[1]->const_item())
{
- if (((Item_string *) args[1])->str_value[0] != wild_many)
+ String* res2= args[1]->val_str((String *)&tmp_value2);
+
+ if (!res2)
+ return OPTIMIZE_NONE;
+
+ if (*res2->ptr() != wild_many)
{
- if ((args[0]->result_type() != STRING_RESULT) ||
- ((Item_string *) args[1])->str_value[0] != wild_one)
+ if (args[0]->result_type() != STRING_RESULT || *res2->ptr() != wild_one)
return OPTIMIZE_OP;
}
}
return OPTIMIZE_NONE;
}
+bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist)
+{
+ if (Item_bool_func2::fix_fields(thd, tlist))
+ return 1;
+
+ /*
+ TODO--we could do it for non-const, but we'd have to
+ recompute the tables for each row--probably not worth it.
+ */
+ if (args[1]->const_item() && !(specialflag & SPECIAL_NO_NEW_FUNC))
+ {
+ String* res2 = args[1]->val_str(&tmp_value2);
+ if (!res2)
+ return 0; // Null argument
+
+ const size_t len = res2->length();
+ const char* first = res2->ptr();
+ const char* last = first + len - 1;
+ /*
+ len must be > 2 ('%pattern%')
+ heuristic: only do TurboBM for pattern_len > 2
+ */
+
+ if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
+ *first == wild_many &&
+ *last == wild_many)
+ {
+ const char* tmp = first + 1;
+ for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
+#ifdef USE_MB
+ canDoTurboBM = (tmp == last) && !use_mb(default_charset_info);
+#else
+ canDoTurboBM = tmp == last;
+#endif
+ }
+
+ if (canDoTurboBM)
+ {
+ pattern = first + 1;
+ pattern_len = len - 2;
+ DBUG_PRINT("info", ("Initializing pattern: '%s'", first));
+ int *suff = (int*) thd->alloc(sizeof(int)*((pattern_len + 1)*2+
+ alphabet_size));
+ bmGs = suff + pattern_len + 1;
+ bmBc = bmGs + pattern_len + 1;
+ turboBM_compute_good_suffix_shifts(suff);
+ turboBM_compute_bad_character_shifts();
+ DBUG_PRINT("info",("done"));
+ }
+ }
+ return 0;
+}
+
#ifdef USE_REGEX
bool
@@ -1376,6 +1513,8 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables)
max_length=1; decimals=0;
binary=args[0]->binary || args[1]->binary;
used_tables_cache=args[0]->used_tables() | args[1]->used_tables();
+ not_null_tables_cache= (args[0]->not_null_tables() |
+ args[1]->not_null_tables());
const_item_cache=args[0]->const_item() && args[1]->const_item();
if (!regex_compiled && args[1]->const_item())
{
@@ -1404,7 +1543,6 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables)
return 0;
}
-
longlong Item_func_regex::val_int()
{
char buff[MAX_FIELD_WIDTH];
@@ -1461,3 +1599,259 @@ Item_func_regex::~Item_func_regex()
}
#endif /* USE_REGEX */
+
+
+#ifdef LIKE_CMP_TOUPPER
+#define likeconv(A) (uchar) toupper(A)
+#else
+#define likeconv(A) (uchar) my_sort_order[(uchar) (A)]
+#endif
+
+
+/**********************************************************************
+ turboBM_compute_suffixes()
+ Precomputation dependent only on pattern_len.
+**********************************************************************/
+
+void Item_func_like::turboBM_compute_suffixes(int *suff)
+{
+ const int plm1 = pattern_len - 1;
+ int f = 0;
+ int g = plm1;
+ int *const splm1 = suff + plm1;
+
+ *splm1 = pattern_len;
+
+ if (binary)
+ {
+ int i;
+ for (i = pattern_len - 2; i >= 0; i--)
+ {
+ int tmp = *(splm1 + i - f);
+ if (g < i && tmp < i - g)
+ suff[i] = tmp;
+ else
+ {
+ if (i < g)
+ g = i; // g = min(i, g)
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
+ g--;
+ suff[i] = f - g;
+ }
+ }
+ }
+ else
+ {
+ int i;
+ for (i = pattern_len - 2; 0 <= i; --i)
+ {
+ int tmp = *(splm1 + i - f);
+ if (g < i && tmp < i - g)
+ suff[i] = tmp;
+ else
+ {
+ if (i < g)
+ g = i; // g = min(i, g)
+ f = i;
+ while (g >= 0 &&
+ likeconv(pattern[g]) == likeconv(pattern[g + plm1 - f]))
+ g--;
+ suff[i] = f - g;
+ }
+ }
+ }
+}
+
+
+/**********************************************************************
+ turboBM_compute_good_suffix_shifts()
+ Precomputation dependent only on pattern_len.
+**********************************************************************/
+
+void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
+{
+ turboBM_compute_suffixes(suff);
+
+ int *end = bmGs + pattern_len;
+ int *k;
+ for (k = bmGs; k < end; k++)
+ *k = pattern_len;
+
+ int tmp;
+ int i;
+ int j = 0;
+ const int plm1 = pattern_len - 1;
+ for (i = plm1; i > -1; i--)
+ {
+ if (suff[i] == i + 1)
+ {
+ for (tmp = plm1 - i; j < tmp; j++)
+ {
+ int *tmp2 = bmGs + j;
+ if (*tmp2 == pattern_len)
+ *tmp2 = tmp;
+ }
+ }
+ }
+
+ int *tmp2;
+ for (tmp = plm1 - i; j < tmp; j++)
+ {
+ tmp2 = bmGs + j;
+ if (*tmp2 == pattern_len)
+ *tmp2 = tmp;
+ }
+
+ tmp2 = bmGs + plm1;
+ for (i = 0; i <= pattern_len - 2; i++)
+ *(tmp2 - suff[i]) = plm1 - i;
+}
+
+
+/**********************************************************************
+ turboBM_compute_bad_character_shifts()
+ Precomputation dependent on pattern_len.
+**********************************************************************/
+
+void Item_func_like::turboBM_compute_bad_character_shifts()
+{
+ int *i;
+ int *end = bmBc + alphabet_size;
+ for (i = bmBc; i < end; i++)
+ *i = pattern_len;
+
+ int j;
+ const int plm1 = pattern_len - 1;
+ if (binary)
+ {
+ for (j = 0; j < plm1; j++)
+ bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
+ }
+ else
+ {
+ for (j = 0; j < plm1; j++)
+ bmBc[(uint) likeconv(pattern[j])] = plm1 - j;
+ }
+}
+
+
+/**********************************************************************
+ turboBM_matches()
+ Search for pattern in text, returns true/false for match/no match
+**********************************************************************/
+
+bool Item_func_like::turboBM_matches(const char* text, int text_len) const
+{
+ register int bcShift;
+ register int turboShift;
+ int shift = pattern_len;
+ int j = 0;
+ int u = 0;
+
+ const int plm1= pattern_len - 1;
+ const int tlmpl= text_len - pattern_len;
+
+ /* Searching */
+ if (binary)
+ {
+ while (j <= tlmpl)
+ {
+ register int i= plm1;
+ while (i >= 0 && pattern[i] == text[i + j])
+ {
+ i--;
+ if (i == plm1 - shift)
+ i-= u;
+ }
+ if (i < 0)
+ return 1;
+
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
+ shift = max(turboShift, bcShift);
+ shift = max(shift, bmGs[i]);
+ if (shift == bmGs[i])
+ u = min(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+ shift = max(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+ }
+ return 0;
+ }
+ else
+ {
+ while (j <= tlmpl)
+ {
+ register int i = plm1;
+ while (i >= 0 && likeconv(pattern[i]) == likeconv(text[i + j]))
+ {
+ i--;
+ if (i == plm1 - shift)
+ i-= u;
+ }
+ if (i < 0)
+ return 1;
+
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) likeconv(text[i + j])] - plm1 + i;
+ shift = max(turboShift, bcShift);
+ shift = max(shift, bmGs[i]);
+ if (shift == bmGs[i])
+ u = min(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+ shift = max(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+ }
+ return 0;
+ }
+}
+
+
+/*
+ Make a logical XOR of the arguments.
+
+ SYNOPSIS
+ val_int()
+
+ DESCRIPTION
+ If either operator is NULL, return NULL.
+
+ NOTE
+ As we don't do any index optimization on XOR this is not going to be
+ very fast to use.
+
+ TODO (low priority)
+ Change this to be optimized as:
+ A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1)
+ To be able to do this, we would however first have to extend the MySQL
+ range optimizer to handle OR better.
+*/
+
+longlong Item_cond_xor::val_int()
+{
+ List_iterator<Item> li(list);
+ Item *item;
+ int result=0;
+ null_value=0;
+ while ((item=li++))
+ {
+ result^= (item->val_int() != 0);
+ if (item->null_value)
+ {
+ null_value=1;
+ return 0;
+ }
+ }
+ return (longlong) result;
+}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index c33042e11ab..9f19e7575d5 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -28,6 +28,7 @@ public:
Item_bool_func(Item *a) :Item_int_func(a) {}
Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
void fix_length_and_dec() { decimals=0; max_length=1; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_bool_func2 :public Item_int_func
@@ -46,6 +47,8 @@ public:
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
void print(String *str) { Item_func::print_op(str); }
+ bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -79,6 +82,7 @@ public:
enum Functype rev_functype() const { return EQUAL_FUNC; }
cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return "<=>"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -185,6 +189,7 @@ public:
~Item_func_interval() { delete item; }
const char *func_name() const { return "interval"; }
void update_used_tables();
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -199,6 +204,7 @@ public:
enum Item_result result_type () const { return cached_result_type; }
void fix_length_and_dec();
const char *func_name() const { return "ifnull"; }
+ table_map not_null_tables() const { return 0; }
};
@@ -211,8 +217,14 @@ public:
longlong val_int();
String *val_str(String *str);
enum Item_result result_type () const { return cached_result_type; }
+ bool fix_fields(THD *thd,struct st_table_list *tlist)
+ {
+ args[0]->top_level_item();
+ return Item_func::fix_fields(thd,tlist);
+ }
void fix_length_and_dec();
const char *func_name() const { return "if"; }
+ table_map not_null_tables() const { return 0; }
};
@@ -227,6 +239,7 @@ public:
enum Item_result result_type () const { return cached_result_type; }
void fix_length_and_dec();
const char *func_name() const { return "nullif"; }
+ table_map not_null_tables() const { return 0; }
};
@@ -241,8 +254,10 @@ public:
void fix_length_and_dec();
enum Item_result result_type () const { return cached_result_type; }
const char *func_name() const { return "coalesce"; }
+ table_map not_null_tables() const { return 0; }
};
+
class Item_func_case :public Item_func
{
Item * first_expr, *else_expr;
@@ -256,12 +271,14 @@ public:
String *val_str(String *);
void fix_length_and_dec();
void update_used_tables();
+ table_map not_null_tables() const { return 0; }
enum Item_result result_type () const { return cached_result_type; }
const char *func_name() const { return "case"; }
void print(String *str);
bool fix_fields(THD *thd,struct st_table_list *tlist);
void split_sum_func(List<Item> &fields);
Item *find_item(String *str);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -284,9 +301,9 @@ public:
virtual void set(uint pos,Item *item)=0;
virtual byte *get_value(Item *item)=0;
void sort()
- {
- qsort(base,used_count,size,compare);
- }
+ {
+ qsort(base,used_count,size,compare);
+ }
int find(Item *item);
};
@@ -426,6 +443,7 @@ class Item_func_in :public Item_int_func
const char *func_name() const { return " IN "; }
void update_used_tables();
void split_sum_func(List<Item> &fields);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -459,37 +477,63 @@ public:
if (!(used_tables_cache=args[0]->used_tables()))
{
/* Remember if the value is always NULL or never NULL */
- args[0]->val();
- cached_value= args[0]->null_value ? (longlong) 1 : (longlong) 0;
+ cached_value= (longlong) args[0]->is_null();
}
}
}
+ table_map not_null_tables() const { return 0; }
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
+ unsigned int size_of() { return sizeof(*this);}
};
+
class Item_func_isnotnull :public Item_bool_func
{
public:
Item_func_isnotnull(Item *a) :Item_bool_func(a) {}
longlong val_int();
enum Functype functype() const { return ISNOTNULL_FUNC; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; }
+ void fix_length_and_dec()
+ {
+ decimals=0; max_length=1; maybe_null=0;
+ }
const char *func_name() const { return "isnotnull"; }
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
+ table_map not_null_tables() const { return 0; }
};
+
class Item_func_like :public Item_bool_func2
{
- char escape;
+ // Turbo Boyer-Moore data
+ bool canDoTurboBM; // pattern is '%abcd%' case
+ const char* pattern;
+ int pattern_len;
+
+ // TurboBM buffers, *this is owner
+ int* bmGs; // good suffix shift table, size is pattern_len + 1
+ int* bmBc; // bad character shift table, size is alphabet_size
+
+ void turboBM_compute_suffixes(int* suff);
+ void turboBM_compute_good_suffix_shifts(int* suff);
+ void turboBM_compute_bad_character_shifts();
+ bool turboBM_matches(const char* text, int text_len) const;
+ enum { alphabet_size = 256 };
+
public:
- Item_func_like(Item *a,Item *b, char* escape_arg) :Item_bool_func2(a,b),escape(*escape_arg)
- {}
+ char escape;
+
+ Item_func_like(Item *a,Item *b, char* escape_arg)
+ :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
+ bmGs(0), bmBc(0), escape(*escape_arg) {}
longlong val_int();
enum Functype functype() const { return LIKE_FUNC; }
optimize_type select_optimize() const;
cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return "like"; }
void fix_length_and_dec();
+ bool fix_fields(THD *thd,struct st_table_list *tlist);
+ unsigned int size_of() { return sizeof(*this);}
};
#ifdef USE_REGEX
@@ -509,6 +553,7 @@ public:
longlong val_int();
bool fix_fields(THD *thd,struct st_table_list *tlist);
const char *func_name() const { return "regex"; }
+ unsigned int size_of() { return sizeof(*this);}
};
#else
@@ -530,10 +575,14 @@ class Item_cond :public Item_bool_func
{
protected:
List<Item> list;
+ bool abort_on_null;
+ table_map and_tables_cache;
+
public:
- Item_cond() : Item_bool_func() { const_item_cache=0; }
- Item_cond(Item *i1,Item *i2) :Item_bool_func()
- { list.push_back(i1); list.push_back(i2); }
+ /* Item_cond() is only used to create top level items */
+ Item_cond() : Item_bool_func(), abort_on_null(1) { const_item_cache=0; }
+ Item_cond(Item *i1,Item *i2) :Item_bool_func(), abort_on_null(0)
+ { list.push_back(i1); list.push_back(i2); }
~Item_cond() { list.delete_elements(); }
bool add(Item *item) { return list.push_back(item); }
bool fix_fields(THD *,struct st_table_list *);
@@ -545,6 +594,8 @@ public:
void print(String *str);
void split_sum_func(List<Item> &fields);
friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
+ unsigned int size_of() { return sizeof(*this);}
+ void top_level_item() { abort_on_null=1; }
};
@@ -566,6 +617,7 @@ public:
enum Functype functype() const { return COND_OR_FUNC; }
longlong val_int();
const char *func_name() const { return "or"; }
+ table_map not_null_tables() const { return and_tables_cache; }
};
@@ -581,4 +633,21 @@ inline Item *and_conds(Item *a,Item *b)
return cond;
}
+/*
+ XOR is Item_cond, not an Item_int_func bevause we could like to
+ optimize (a XOR b) later on. It's low prio, though
+*/
+class Item_cond_xor :public Item_cond
+{
+public:
+ Item_cond_xor() :Item_cond() {}
+ Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
+ enum Functype functype() const { return COND_XOR_FUNC; }
+ /* TODO: remove the next line when implementing XOR optimization */
+ enum Type type() const { return FUNC_ITEM; }
+ longlong val_int();
+ const char *func_name() const { return "xor"; }
+};
+
+
Item *and_expressions(Item *a, Item *b, Item **org_item);
diff --git a/sql/item_create.cc b/sql/item_create.cc
index ef9f5f2d38b..6809d6892b0 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -32,6 +32,16 @@ Item *create_func_acos(Item* a)
return new Item_func_acos(a);
}
+Item *create_func_aes_encrypt(Item* a, Item* b)
+{
+ return new Item_func_aes_encrypt(a, b);
+}
+
+Item *create_func_aes_decrypt(Item* a, Item* b)
+{
+ return new Item_func_aes_decrypt(a, b);
+}
+
Item *create_func_ascii(Item* a)
{
return new Item_func_ascii(a);
@@ -65,7 +75,9 @@ Item *create_func_ceiling(Item* a)
Item *create_func_connection_id(void)
{
- return new Item_int("CONNECTION_ID()",(longlong) current_thd->thread_id,10);
+ THD *thd=current_thd;
+ thd->safe_to_cache_query=0;
+ return new Item_int(NullS,(longlong) thd->thread_id,10);
}
Item *create_func_conv(Item* a, Item *b, Item *c)
@@ -129,6 +141,13 @@ Item *create_func_floor(Item* a)
return new Item_func_floor(a);
}
+Item *create_func_found_rows(void)
+{
+ THD *thd=current_thd;
+ thd->safe_to_cache_query=0;
+ return new Item_int(NullS,(longlong) thd->found_rows(),21);
+}
+
Item *create_func_from_days(Item* a)
{
return new Item_func_from_days(a);
@@ -136,13 +155,13 @@ Item *create_func_from_days(Item* a)
Item *create_func_get_lock(Item* a, Item *b)
{
+ current_thd->safe_to_cache_query=0;
return new Item_func_get_lock(a, b);
}
Item *create_func_hex(Item *a)
{
- return new Item_func_conv(a,new Item_int((int32) 10,2),
- new Item_int((int32) 16,2));
+ return new Item_func_hex(a);
}
Item *create_func_inet_ntoa(Item* a)
@@ -191,14 +210,24 @@ Item *create_func_length(Item* a)
return new Item_func_length(a);
}
+Item *create_func_bit_length(Item* a)
+{
+ return new Item_func_bit_length(a);
+}
+
Item *create_func_char_length(Item* a)
{
return new Item_func_char_length(a);
}
-Item *create_func_log(Item* a)
+Item *create_func_ln(Item* a)
+{
+ return new Item_func_ln(a);
+}
+
+Item *create_func_log2(Item* a)
{
- return new Item_func_log(a);
+ return new Item_func_log2(a);
}
Item *create_func_log10(Item* a)
@@ -254,7 +283,7 @@ Item *create_func_period_diff(Item* a, Item *b)
Item *create_func_pi(void)
{
- return new Item_real("PI()",M_PI,6,8);
+ return new Item_real(NullS,M_PI,6,8);
}
Item *create_func_pow(Item* a, Item *b)
@@ -262,11 +291,27 @@ Item *create_func_pow(Item* a, Item *b)
return new Item_func_pow(a,b);
}
+Item *create_func_current_user()
+{
+ THD *thd=current_thd;
+ char buff[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
+ uint length;
+
+ length= (uint) (strxmov(buff, thd->priv_user, "@", thd->priv_host, NullS) -
+ buff);
+ return new Item_string(NullS, thd->memdup(buff, length), length);
+}
+
Item *create_func_quarter(Item* a)
{
return new Item_func_quarter(a);
}
+Item *create_func_password(Item* a)
+{
+ return new Item_func_password(a);
+}
+
Item *create_func_radians(Item *a)
{
return new Item_func_units((char*) "radians",a,M_PI/180,0.0);
@@ -274,6 +319,7 @@ Item *create_func_radians(Item *a)
Item *create_func_release_lock(Item* a)
{
+ current_thd->safe_to_cache_query=0;
return new Item_func_release_lock(a);
}
@@ -312,6 +358,11 @@ Item *create_func_sin(Item* a)
return new Item_func_sin(a);
}
+Item *create_func_sha(Item* a)
+{
+ return new Item_func_sha(a);
+}
+
Item *create_func_space(Item *a)
{
return new Item_func_repeat(new Item_string(" ",1),a);
@@ -359,7 +410,7 @@ Item *create_func_ucase(Item* a)
Item *create_func_version(void)
{
- return new Item_string(NullS,server_version, (uint) strlen(server_version));
+ return new Item_string(NullS,server_version, strlen(server_version));
}
Item *create_func_weekday(Item* a)
@@ -374,10 +425,33 @@ Item *create_func_year(Item* a)
Item *create_load_file(Item* a)
{
+ current_thd->safe_to_cache_query=0;
return new Item_load_file(a);
}
-Item *create_wait_for_master_pos(Item* a, Item* b)
+Item *create_func_cast(Item *a, Item_cast cast_type)
+{
+ Item *res;
+ LINT_INIT(res);
+ switch (cast_type) {
+ case ITEM_CAST_BINARY: res= new Item_func_binary(a); break;
+ case ITEM_CAST_CHAR: res= new Item_char_typecast(a); break;
+ case ITEM_CAST_SIGNED_INT: res= new Item_func_signed(a); break;
+ case ITEM_CAST_UNSIGNED_INT: res= new Item_func_unsigned(a); break;
+ case ITEM_CAST_DATE: res= new Item_date_typecast(a); break;
+ case ITEM_CAST_TIME: res= new Item_time_typecast(a); break;
+ case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break;
+ }
+ return res;
+}
+
+Item *create_func_is_free_lock(Item* a)
+{
+ current_thd->safe_to_cache_query=0;
+ return new Item_func_is_free_lock(a);
+}
+
+Item *create_func_quote(Item* a)
{
- return new Item_master_pos_wait(a, b);
+ return new Item_func_quote(a);
}
diff --git a/sql/item_create.h b/sql/item_create.h
index cc7497b0183..5381ad946ae 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,10 +18,13 @@
Item *create_func_abs(Item* a);
Item *create_func_acos(Item* a);
+Item *create_func_aes_encrypt(Item* a, Item* b);
+Item *create_func_aes_decrypt(Item* a, Item* b);
Item *create_func_ascii(Item* a);
Item *create_func_asin(Item* a);
Item *create_func_bin(Item* a);
Item *create_func_bit_count(Item* a);
+Item *create_func_bit_length(Item* a);
Item *create_func_ceiling(Item* a);
Item *create_func_char_length(Item* a);
Item *create_func_connection_id(void);
@@ -37,6 +40,7 @@ Item *create_func_degrees(Item *);
Item *create_func_exp(Item* a);
Item *create_func_find_in_set(Item* a, Item *b);
Item *create_func_floor(Item* a);
+Item *create_func_found_rows(void);
Item *create_func_from_days(Item* a);
Item *create_func_get_lock(Item* a, Item *b);
Item *create_func_hex(Item *a);
@@ -48,8 +52,9 @@ Item *create_func_instr(Item* a, Item *b);
Item *create_func_isnull(Item* a);
Item *create_func_lcase(Item* a);
Item *create_func_length(Item* a);
+Item *create_func_ln(Item* a);
Item *create_func_locate(Item* a, Item *b);
-Item *create_func_log(Item* a);
+Item *create_func_log2(Item* a);
Item *create_func_log10(Item* a);
Item *create_func_lpad(Item* a, Item *b, Item *c);
Item *create_func_ltrim(Item* a);
@@ -63,7 +68,9 @@ Item *create_func_period_add(Item* a, Item *b);
Item *create_func_period_diff(Item* a, Item *b);
Item *create_func_pi(void);
Item *create_func_pow(Item* a, Item *b);
+Item *create_func_current_user(void);
Item *create_func_quarter(Item* a);
+Item *create_func_password(Item* a);
Item *create_func_radians(Item *a);
Item *create_func_release_lock(Item* a);
Item *create_func_repeat(Item* a, Item *b);
@@ -73,6 +80,7 @@ Item *create_func_rtrim(Item* a);
Item *create_func_sec_to_time(Item* a);
Item *create_func_sign(Item* a);
Item *create_func_sin(Item* a);
+Item *create_func_sha(Item* a);
Item *create_func_soundex(Item* a);
Item *create_func_space(Item *);
Item *create_func_sqrt(Item* a);
@@ -85,4 +93,5 @@ Item *create_func_ucase(Item* a);
Item *create_func_version(void);
Item *create_func_weekday(Item* a);
Item *create_load_file(Item* a);
-Item *create_wait_for_master_pos(Item* a, Item* b);
+Item *create_func_is_free_lock(Item* a);
+Item *create_func_quote(Item* a);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 037f7861630..656dff63609 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -43,7 +43,7 @@ Item_func::Item_func(List<Item> &list)
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
{
uint i=0;
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
while ((item=li++))
@@ -59,26 +59,31 @@ bool
Item_func::fix_fields(THD *thd,TABLE_LIST *tables)
{
Item **arg,**arg_end;
+#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
char buff[STACK_BUFF_ALLOC]; // Max argument in function
+#endif
+
binary=0;
- used_tables_cache=0;
+ used_tables_cache= not_null_tables_cache= 0;
const_item_cache=1;
if (thd && check_stack_overrun(thd,buff))
- return 0; // Fatal error if flag is set!
+ return 1; // Fatal error if flag is set!
if (arg_count)
{ // Print purify happy
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
{
- if ((*arg)->fix_fields(thd,tables))
+ Item *item=*arg;
+ if (item->fix_fields(thd,tables))
return 1; /* purecov: inspected */
- if ((*arg)->maybe_null)
+ if (item->maybe_null)
maybe_null=1;
- if ((*arg)->binary)
+ if (item->binary)
binary=1;
- with_sum_func= with_sum_func || (*arg)->with_sum_func;
- used_tables_cache|=(*arg)->used_tables();
- const_item_cache&= (*arg)->const_item();
+ with_sum_func= with_sum_func || item->with_sum_func;
+ used_tables_cache|= item->used_tables();
+ not_null_tables_cache|= item->not_null_tables();
+ const_item_cache&= item->const_item();
}
}
fix_length_and_dec();
@@ -91,12 +96,13 @@ void Item_func::split_sum_func(List<Item> &fields)
Item **arg,**arg_end;
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
{
- if ((*arg)->with_sum_func && (*arg)->type() != SUM_FUNC_ITEM)
- (*arg)->split_sum_func(fields);
- else if ((*arg)->used_tables() || (*arg)->type() == SUM_FUNC_ITEM)
+ Item *item=*arg;
+ if (item->with_sum_func && item->type() != SUM_FUNC_ITEM)
+ item->split_sum_func(fields);
+ else if (item->used_tables() || item->type() == SUM_FUNC_ITEM)
{
fields.push_front(*arg);
- *arg=new Item_ref((Item**) fields.head_ref(),0,(*arg)->name);
+ *arg=new Item_ref((Item**) fields.head_ref(),0,item->name);
}
}
}
@@ -120,6 +126,13 @@ table_map Item_func::used_tables() const
return used_tables_cache;
}
+
+table_map Item_func::not_null_tables() const
+{
+ return not_null_tables_cache;
+}
+
+
void Item_func::print(String *str)
{
str->append(func_name());
@@ -166,13 +179,42 @@ bool Item_func::eq(const Item *item, bool binary_cmp) const
}
+Field *Item_func::tmp_table_field(TABLE *t_arg)
+{
+ Field *res;
+ LINT_INIT(res);
+
+ if (!t_arg)
+ return result_field;
+ switch (result_type()) {
+ case INT_RESULT:
+ if (max_length > 11)
+ res= new Field_longlong(max_length, maybe_null, name, t_arg,
+ unsigned_flag);
+ else
+ res= new Field_long(max_length, maybe_null, name, t_arg,
+ unsigned_flag);
+ break;
+ case REAL_RESULT:
+ res= new Field_double(max_length, maybe_null, name, t_arg, decimals);
+ break;
+ case STRING_RESULT:
+ if (max_length > 255)
+ res= new Field_blob(max_length, maybe_null, name, t_arg, binary);
+ else
+ res= new Field_string(max_length, maybe_null, name, t_arg, binary);
+ break;
+ }
+ return res;
+}
+
+
String *Item_real_func::val_str(String *str)
{
double nr=val();
if (null_value)
return 0; /* purecov: inspected */
- else
- str->set(nr,decimals);
+ str->set(nr,decimals);
return str;
}
@@ -184,16 +226,17 @@ String *Item_num_func::val_str(String *str)
longlong nr=val_int();
if (null_value)
return 0; /* purecov: inspected */
- else
+ if (!unsigned_flag)
str->set(nr);
+ else
+ str->set((ulonglong) nr);
}
else
{
double nr=val();
if (null_value)
return 0; /* purecov: inspected */
- else
- str->set(nr,decimals);
+ str->set(nr,decimals);
}
return str;
}
@@ -207,24 +250,31 @@ void Item_func::fix_num_length_and_dec()
max_length=float_length(decimals);
}
-
String *Item_int_func::val_str(String *str)
{
longlong nr=val_int();
if (null_value)
return 0;
- else
+ if (!unsigned_flag)
str->set(nr);
+ else
+ str->set((ulonglong) nr);
return str;
}
-/* Change from REAL_RESULT (default) to INT_RESULT if both arguments are integers */
+/*
+ Change from REAL_RESULT (default) to INT_RESULT if both arguments are
+ integers
+*/
void Item_num_op::find_num_type(void)
{
if (args[0]->result_type() == INT_RESULT &&
args[1]->result_type() == INT_RESULT)
+ {
hybrid_type=INT_RESULT;
+ unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
+ }
}
String *Item_num_op::val_str(String *str)
@@ -234,16 +284,17 @@ String *Item_num_op::val_str(String *str)
longlong nr=val_int();
if (null_value)
return 0; /* purecov: inspected */
- else
+ if (!unsigned_flag)
str->set(nr);
+ else
+ str->set((ulonglong) nr);
}
else
{
double nr=val();
if (null_value)
return 0; /* purecov: inspected */
- else
- str->set(nr,decimals);
+ str->set(nr,decimals);
}
return str;
}
@@ -269,6 +320,21 @@ longlong Item_func_plus::val_int()
return (longlong) Item_func_plus::val();
}
+
+/*
+ The following function is here to allow the user to force
+ subtraction of UNSIGNED BIGINT to return negative values.
+*/
+
+void Item_func_minus::fix_length_and_dec()
+{
+ Item_num_op::fix_length_and_dec();
+ if (unsigned_flag &&
+ (current_thd->sql_mode & MODE_NO_UNSIGNED_SUBTRACTION))
+ unsigned_flag=0;
+}
+
+
double Item_func_minus::val()
{
double value=args[0]->val() - args[1]->val();
@@ -411,14 +477,43 @@ void Item_func_abs::fix_length_and_dec()
hybrid_type= args[0]->result_type() == INT_RESULT ? INT_RESULT : REAL_RESULT;
}
+/* Gateway to natural LOG function */
+double Item_func_ln::val()
+{
+ double value=args[0]->val();
+ if ((null_value=(args[0]->null_value || value <= 0.0)))
+ return 0.0;
+ return log(value);
+}
+
+/*
+ Extended but so slower LOG function
+ We have to check if all values are > zero and first one is not one
+ as these are the cases then result is not a number.
+*/
double Item_func_log::val()
{
double value=args[0]->val();
if ((null_value=(args[0]->null_value || value <= 0.0)))
- return 0.0; /* purecov: inspected */
+ return 0.0;
+ if (arg_count == 2)
+ {
+ double value2= args[1]->val();
+ if ((null_value=(args[1]->null_value || value2 <= 0.0 || value == 1.0)))
+ return 0.0;
+ return log(value2) / log(value);
+ }
return log(value);
}
+double Item_func_log2::val()
+{
+ double value=args[0]->val();
+ if ((null_value=(args[0]->null_value || value <= 0.0)))
+ return 0.0;
+ return log(value) / log(2.0);
+}
+
double Item_func_log10::val()
{
double value=args[0]->val();
@@ -596,35 +691,64 @@ double Item_func_round::val()
double value=args[0]->val();
int dec=(int) args[1]->val_int();
uint abs_dec=abs(dec);
+ double tmp;
+ /*
+ tmp2 is here to avoid return the value with 80 bit precision
+ This will fix that the test round(0.1,1) = round(0.1,1) is true
+ */
+ volatile double tmp2;
if ((null_value=args[0]->null_value || args[1]->null_value))
return 0.0;
- double tmp=(abs_dec < array_elements(log_10) ?
- log_10[abs_dec] : pow(10.0,(double) abs_dec));
+ tmp=(abs_dec < array_elements(log_10) ?
+ log_10[abs_dec] : pow(10.0,(double) abs_dec));
if (truncate)
{
if (value >= 0)
- return dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp;
+ tmp2= dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp;
else
- return dec < 0 ? ceil(value/tmp)*tmp : ceil(value*tmp)/tmp;
+ tmp2= dec < 0 ? ceil(value/tmp)*tmp : ceil(value*tmp)/tmp;
}
- return dec < 0 ? rint(value/tmp)*tmp : rint(value*tmp)/tmp;
+ else
+ tmp2=dec < 0 ? rint(value/tmp)*tmp : rint(value*tmp)/tmp;
+ return tmp2;
}
-double Item_func_rand::val()
+void Item_func_rand::fix_length_and_dec()
{
+ decimals=NOT_FIXED_DEC;
+ max_length=float_length(decimals);
if (arg_count)
{ // Only use argument once in query
- ulong tmp=((ulong) args[0]->val_int())+55555555L;
- randominit(&current_thd->rand,tmp,tmp/2);
-#ifdef DELETE_ITEMS
- delete args[0];
-#endif
- arg_count=0;
+ uint32 tmp= (uint32) (args[0]->val_int());
+ if ((rand= (struct rand_struct*) sql_alloc(sizeof(*rand))))
+ randominit(rand,(uint32) (tmp*0x10001L+55555555L),
+ (uint32) (tmp*0x10000001L));
}
- return rnd(&current_thd->rand);
+ else
+ {
+ THD *thd= current_thd;
+ /*
+ No need to send a Rand log event if seed was given eg: RAND(seed),
+ as it will be replicated in the query as such.
+
+ Save the seed only the first time RAND() is used in the query
+ Once events are forwarded rather than recreated,
+ the following can be skipped if inside the slave thread
+ */
+ thd->rand_used=1;
+ thd->rand_saved_seed1=thd->rand.seed1;
+ thd->rand_saved_seed2=thd->rand.seed2;
+ rand= &thd->rand;
+ }
+}
+
+
+double Item_func_rand::val()
+{
+ return my_rnd(rand);
}
longlong Item_func_sign::val_int()
@@ -674,8 +798,10 @@ String *Item_func_min_max::val_str(String *str)
longlong nr=val_int();
if (null_value)
return 0;
- else
+ if (!unsigned_flag)
str->set(nr);
+ else
+ str->set((ulonglong) nr);
return str;
}
case REAL_RESULT:
@@ -683,8 +809,7 @@ String *Item_func_min_max::val_str(String *str)
double nr=val();
if (null_value)
return 0; /* purecov: inspected */
- else
- str->set(nr,decimals);
+ str->set(nr,decimals);
return str;
}
case STRING_RESULT:
@@ -791,9 +916,7 @@ longlong Item_func_locate::val_int()
{
String *a=args[0]->val_str(&value1);
String *b=args[1]->val_str(&value2);
-#ifdef USE_MB
bool binary_str = args[0]->binary || args[1]->binary;
-#endif
if (!a || !b)
{
null_value=1;
@@ -847,7 +970,8 @@ longlong Item_func_locate::val_int()
return 0;
}
#endif /* USE_MB */
- return (longlong) (a->strstr(*b,start)+1) ;
+ return (longlong) (binary ? a->strstr(*b,start) :
+ (a->strstr_case(*b,start)))+1;
}
@@ -995,47 +1119,6 @@ longlong Item_func_find_in_set::val_int()
return 0;
}
-static char nbits[256] = {
- 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
-};
-
-uint count_bits(ulonglong v)
-{
-#if SIZEOF_LONG_LONG > 4
- /* The following code is a bit faster on 16 bit machines than if we would
- only shift v */
- ulong v2=(ulong) (v >> 32);
- return (uint) (uchar) (nbits[(uchar) v] +
- nbits[(uchar) (v >> 8)] +
- nbits[(uchar) (v >> 16)] +
- nbits[(uchar) (v >> 24)] +
- nbits[(uchar) (v2)] +
- nbits[(uchar) (v2 >> 8)] +
- nbits[(uchar) (v2 >> 16)] +
- nbits[(uchar) (v2 >> 24)]);
-#else
- return (uint) (uchar) (nbits[(uchar) v] +
- nbits[(uchar) (v >> 8)] +
- nbits[(uchar) (v >> 16)] +
- nbits[(uchar) (v >> 24)]);
-#endif
-}
-
longlong Item_func_bit_count::val_int()
{
ulonglong value= (ulonglong) args[0]->val_int();
@@ -1044,7 +1127,7 @@ longlong Item_func_bit_count::val_int()
null_value=1; /* purecov: inspected */
return 0; /* purecov: inspected */
}
- return (longlong) count_bits(value);
+ return (longlong) my_count_bits(value);
}
@@ -1068,7 +1151,8 @@ udf_handler::~udf_handler()
}
free_udf(u_d);
}
- delete [] buffers;
+ if (buffers) // Because of bug in ecc
+ delete [] buffers;
}
@@ -1076,13 +1160,15 @@ bool
udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func,
uint arg_count, Item **arguments)
{
+#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
char buff[STACK_BUFF_ALLOC]; // Max argument in function
+#endif
DBUG_ENTER("Item_udf_func::fix_fields");
if (thd)
{
if (check_stack_overrun(thd,buff))
- return 0; // Fatal error flag is set!
+ DBUG_RETURN(1); // Fatal error flag is set!
}
else
thd=current_thd; // In WHERE / const clause
@@ -1117,16 +1203,17 @@ udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func,
arg != arg_end ;
arg++,i++)
{
- if ((*arg)->fix_fields(thd,tables))
+ Item *item=*arg;
+ if (item->fix_fields(thd,tables))
return 1;
- if ((*arg)->binary)
+ if (item->binary)
func->binary=1;
- if ((*arg)->maybe_null)
+ if (item->maybe_null)
func->maybe_null=1;
- func->with_sum_func= func->with_sum_func || (*arg)->with_sum_func;
- used_tables_cache|=(*arg)->used_tables();
- const_item_cache&=(*arg)->const_item();
- f_args.arg_type[i]=(*arg)->result_type();
+ func->with_sum_func= func->with_sum_func || item->with_sum_func;
+ used_tables_cache|=item->used_tables();
+ const_item_cache&=item->const_item();
+ f_args.arg_type[i]=item->result_type();
}
if (!(buffers=new String[arg_count]) ||
!(f_args.args= (char**) sql_alloc(arg_count * sizeof(char *))) ||
@@ -1303,8 +1390,7 @@ String *Item_func_udf_float::val_str(String *str)
double nr=val();
if (null_value)
return 0; /* purecov: inspected */
- else
- str->set(nr,decimals);
+ str->set(nr,decimals);
return str;
}
@@ -1324,8 +1410,10 @@ String *Item_func_udf_int::val_str(String *str)
longlong nr=val_int();
if (null_value)
return 0;
- else
+ if (!unsigned_flag)
str->set(nr);
+ else
+ str->set((ulonglong) nr);
return str;
}
@@ -1412,6 +1500,7 @@ void item_user_lock_init(void)
void item_user_lock_free(void)
{
hash_free(&hash_user_locks);
+ pthread_mutex_destroy(&LOCK_user_locks);
}
void item_user_lock_release(ULL *ull)
@@ -1419,20 +1508,15 @@ void item_user_lock_release(ULL *ull)
ull->locked=0;
if (mysql_bin_log.is_open())
{
- THD *thd = current_thd;
- int save_errno;
char buf[256];
String tmp(buf,sizeof(buf));
tmp.length(0);
tmp.append("DO RELEASE_LOCK(\"");
tmp.append(ull->key,ull->key_length);
tmp.append("\")");
- save_errno=thd->net.last_errno;
- thd->net.last_errno=0;
- thd->query_length=tmp.length();
- Query_log_event qev(thd,tmp.ptr());
+ Query_log_event qev(current_thd, tmp.ptr(), tmp.length(),1);
+ qev.error_code=0; // this query is always safe to run on slave
mysql_bin_log.write(&qev);
- thd->net.last_errno=save_errno;
}
if (--ull->count)
pthread_cond_signal(&ull->cond);
@@ -1450,22 +1534,95 @@ longlong Item_master_pos_wait::val_int()
THD* thd = current_thd;
String *log_name = args[0]->val_str(&value);
int event_count;
-
+
null_value=0;
if (thd->slave_thread || !log_name || !log_name->length())
{
null_value = 1;
return 0;
}
- ulong pos = (ulong)args[1]->val_int();
- if ((event_count = glob_mi.wait_for_pos(thd, log_name, pos)) == -1)
+ longlong pos = args[1]->val_int();
+ longlong timeout = (arg_count==3) ? args[2]->val_int() : 0 ;
+ LOCK_ACTIVE_MI;
+ if ((event_count = active_mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2)
{
null_value = 1;
event_count=0;
}
+ UNLOCK_ACTIVE_MI;
return event_count;
}
+#ifdef EXTRA_DEBUG
+void debug_sync_point(const char* lock_name, uint lock_timeout)
+{
+ THD* thd=current_thd;
+ ULL* ull;
+ struct timespec abstime;
+ int lock_name_len,error=0;
+ lock_name_len=strlen(lock_name);
+ pthread_mutex_lock(&LOCK_user_locks);
+
+ if (thd->ull)
+ {
+ item_user_lock_release(thd->ull);
+ thd->ull=0;
+ }
+
+ /*
+ If the lock has not been aquired by some client, we do not want to
+ create an entry for it, since we immediately release the lock. In
+ this case, we will not be waiting, but rather, just waste CPU and
+ memory on the whole deal
+ */
+ if (!(ull= ((ULL*) hash_search(&hash_user_locks,lock_name,
+ lock_name_len))))
+ {
+ pthread_mutex_unlock(&LOCK_user_locks);
+ return;
+ }
+ ull->count++;
+
+ /*
+ Structure is now initialized. Try to get the lock.
+ Set up control struct to allow others to abort locks
+ */
+ thd->proc_info="User lock";
+ thd->mysys_var->current_mutex= &LOCK_user_locks;
+ thd->mysys_var->current_cond= &ull->cond;
+
+ set_timespec(abstime,lock_timeout);
+ while (!thd->killed &&
+ (error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
+ != ETIME && error != ETIMEDOUT && ull->locked) ;
+ if (ull->locked)
+ {
+ if (!--ull->count)
+ delete ull; // Should never happen
+ }
+ else
+ {
+ ull->locked=1;
+ ull->thread=thd->real_id;
+ thd->ull=ull;
+ }
+ pthread_mutex_unlock(&LOCK_user_locks);
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->proc_info=0;
+ thd->mysys_var->current_mutex= 0;
+ thd->mysys_var->current_cond= 0;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
+ pthread_mutex_lock(&LOCK_user_locks);
+ if (thd->ull)
+ {
+ item_user_lock_release(thd->ull);
+ thd->ull=0;
+ }
+ pthread_mutex_unlock(&LOCK_user_locks);
+}
+
+#endif
+
/*
Get a user level lock. If the thread has an old lock this is first released.
Returns 1: Got lock
@@ -1516,20 +1673,15 @@ longlong Item_func_get_lock::val_int()
}
ull->count++;
- /* structure is now initialized. Try to get the lock */
- /* Set up control struct to allow others to abort locks */
+ /*
+ Structure is now initialized. Try to get the lock.
+ Set up control struct to allow others to abort locks.
+ */
thd->proc_info="User lock";
thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond;
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time((time_t*) 0)+(time_t) timeout;
- abstime.ts_nsec=0;
-#else
- abstime.tv_sec=time((time_t*) 0)+(time_t) timeout;
- abstime.tv_nsec=0;
-#endif
-
+ set_timespec(abstime,timeout);
while (!thd->killed &&
(error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
!= ETIME && error != ETIMEDOUT && error != EINVAL && ull->locked) ;
@@ -1565,10 +1717,11 @@ longlong Item_func_get_lock::val_int()
/*
-** Release a user level lock.
-** Returns 1 if lock released
-** 0 if lock wasn't held
-** NULL if no such lock
+ Release a user level lock.
+ Return:
+ 1 if lock released
+ 0 if lock wasn't held
+ (SQL) NULL if no such lock
*/
longlong Item_func_release_lock::val_int()
@@ -1637,6 +1790,7 @@ longlong Item_func_benchmark::val_int()
return 0;
}
+
#define extra_size sizeof(double)
static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
@@ -1674,12 +1828,12 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
bool Item_func_set_user_var::fix_fields(THD *thd,TABLE_LIST *tables)
{
if (!thd)
- thd=current_thd;
+ thd=current_thd; // Should never happen
if (Item_func::fix_fields(thd,tables) ||
!(entry= get_variable(&thd->user_vars, name, 1)))
return 1;
- entry->type= cached_result_type;
- entry->update_query_id=thd->query_id;
+ entry->update_query_id= thd->query_id;
+ cached_result_type= args[0]->result_type();
return 0;
}
@@ -1690,10 +1844,10 @@ Item_func_set_user_var::fix_length_and_dec()
maybe_null=args[0]->maybe_null;
max_length=args[0]->max_length;
decimals=args[0]->decimals;
- cached_result_type=args[0]->result_type();
}
-void Item_func_set_user_var::update_hash(void *ptr, uint length,
+
+bool Item_func_set_user_var::update_hash(const void *ptr, uint length,
Item_result type)
{
if ((null_value=args[0]->null_value))
@@ -1706,6 +1860,8 @@ void Item_func_set_user_var::update_hash(void *ptr, uint length,
}
else
{
+ if (type == STRING_RESULT)
+ length++; // Store strings with end \0
if (length <= extra_size)
{
/* Save value in value struct */
@@ -1730,64 +1886,151 @@ void Item_func_set_user_var::update_hash(void *ptr, uint length,
goto err;
}
}
+ if (type == STRING_RESULT)
+ {
+ length--; // Fix length change above
+ entry->value[length]= 0; // Store end \0
+ }
memcpy(entry->value,ptr,length);
entry->length= length;
entry->type=type;
}
- return;
+ return 0;
err:
current_thd->fatal_error=1; // Probably end of memory
null_value=1;
- return;
+ return 1; // Error
+}
+
+
+/* Get the value of a variable as a double */
+
+double user_var_entry::val(my_bool *null_value)
+{
+ if ((*null_value= (value == 0)))
+ return 0.0;
+
+ switch (type) {
+ case REAL_RESULT:
+ return *(double*) value;
+ case INT_RESULT:
+ return (double) *(longlong*) value;
+ case STRING_RESULT:
+ return atof(value); // This is null terminated
+ }
+ return 0.0; // Impossible
}
+/* Get the value of a variable as an integer */
+
+longlong user_var_entry::val_int(my_bool *null_value)
+{
+ if ((*null_value= (value == 0)))
+ return LL(0);
+
+ switch (type) {
+ case REAL_RESULT:
+ return (longlong) *(double*) value;
+ case INT_RESULT:
+ return *(longlong*) value;
+ case STRING_RESULT:
+ return strtoull(value,NULL,10); // String is null terminated
+ }
+ return LL(0); // Impossible
+}
+
+
+/* Get the value of a variable as a string */
+
+String *user_var_entry::val_str(my_bool *null_value, String *str,
+ uint decimals)
+{
+ if ((*null_value= (value == 0)))
+ return (String*) 0;
+
+ switch (type) {
+ case REAL_RESULT:
+ str->set(*(double*) value, decimals);
+ break;
+ case INT_RESULT:
+ str->set(*(longlong*) value);
+ break;
+ case STRING_RESULT:
+ if (str->copy(value, length))
+ str= 0; // EOM error
+ }
+ return(str);
+}
+
+
+/*
+ This functions is invoked on SET @variable or @variable:= expression.
+
+ SYNOPSIS
+ Item_func_set_user_var::update()
+
+ NOTES
+ We have to store the expression as such in the variable, independent of
+ the value method used by the user
+
+ RETURN
+ 0 Ok
+ 1 EOM Error
+
+*/
+
+
bool
Item_func_set_user_var::update()
{
+ bool res;
+ DBUG_ENTER("Item_func_set_user_var::update");
+ LINT_INIT(res);
+
switch (cached_result_type) {
case REAL_RESULT:
- (void) val();
+ {
+ double value=args[0]->val();
+ res= update_hash((void*) &value,sizeof(value), REAL_RESULT);
break;
+ }
case INT_RESULT:
- (void) val_int();
+ {
+ longlong value=args[0]->val_int();
+ res= update_hash((void*) &value,sizeof(longlong), INT_RESULT);
break;
+ }
case STRING_RESULT:
- char buffer[MAX_FIELD_WIDTH];
- String tmp(buffer,sizeof(buffer));
- (void) val_str(&tmp);
+ String *tmp;
+ tmp=args[0]->val_str(&value);
+ if (!tmp) // Null value
+ res= update_hash((void*) 0,0,STRING_RESULT);
+ else
+ res= update_hash((void*) tmp->ptr(),tmp->length(),STRING_RESULT);
break;
}
- return current_thd->fatal_error;
+ DBUG_RETURN(res);
}
-double
-Item_func_set_user_var::val()
+double Item_func_set_user_var::val()
{
- double value=args[0]->val();
- update_hash((void*) &value,sizeof(value), REAL_RESULT);
- return value;
+ update(); // Store expression
+ return entry->val(&null_value);
}
-longlong
-Item_func_set_user_var::val_int()
+longlong Item_func_set_user_var::val_int()
{
- longlong value=args[0]->val_int();
- update_hash((void*) &value,sizeof(longlong),INT_RESULT);
- return value;
+ update(); // Store expression
+ return entry->val_int(&null_value);
}
-String *
-Item_func_set_user_var::val_str(String *str)
+String *Item_func_set_user_var::val_str(String *str)
{
- String *res=args[0]->val_str(str);
- if (!res) // Null value
- update_hash((void*) 0,0,STRING_RESULT);
- else
- update_hash(res->c_ptr(),res->length()+1,STRING_RESULT);
- return res;
+ update(); // Store expression
+ return entry->val_str(&null_value, str, decimals);
}
@@ -1801,74 +2044,30 @@ void Item_func_set_user_var::print(String *str)
}
-user_var_entry *Item_func_get_user_var::get_entry()
-{
- if (!entry || ! entry->value)
- {
- null_value=1;
- return 0;
- }
- null_value=0;
- return entry;
-}
-
String *
Item_func_get_user_var::val_str(String *str)
{
- user_var_entry *entry=get_entry();
- if (!entry)
- return NULL;
- switch (entry->type) {
- case REAL_RESULT:
- str->set(*(double*) entry->value,decimals);
- break;
- case INT_RESULT:
- str->set(*(longlong*) entry->value);
- break;
- case STRING_RESULT:
- if (str->copy(entry->value, entry->length-1))
- {
- null_value=1;
- return NULL;
- }
- break;
- }
- return str;
+ DBUG_ENTER("Item_func_get_user_var::val_str");
+ if (!var_entry)
+ return (String*) 0; // No such variable
+ DBUG_RETURN(var_entry->val_str(&null_value, str, decimals));
}
double Item_func_get_user_var::val()
{
- user_var_entry *entry=get_entry();
- if (!entry)
- return 0.0;
- switch (entry->type) {
- case REAL_RESULT:
- return *(double*) entry->value;
- case INT_RESULT:
- return (double) *(longlong*) entry->value;
- case STRING_RESULT:
- return atof(entry->value); // This is null terminated
- }
- return 0.0; // Impossible
+ if (!var_entry)
+ return 0.0; // No such variable
+ return (var_entry->val(&null_value));
}
longlong Item_func_get_user_var::val_int()
{
- user_var_entry *entry=get_entry();
- if (!entry)
- return LL(0);
- switch (entry->type) {
- case REAL_RESULT:
- return (longlong) *(double*) entry->value;
- case INT_RESULT:
- return *(longlong*) entry->value;
- case STRING_RESULT:
- return strtoull(entry->value,NULL,10); // String is null terminated
- }
- return LL(0); // Impossible
+ if (!var_entry)
+ return LL(0); // No such variable
+ return (var_entry->val_int(&null_value));
}
@@ -1878,8 +2077,14 @@ void Item_func_get_user_var::fix_length_and_dec()
maybe_null=1;
decimals=NOT_FIXED_DEC;
max_length=MAX_BLOB_WIDTH;
- if ((entry= get_variable(&thd->user_vars, name, 0)))
- const_var_flag= thd->query_id != entry->update_query_id;
+ if (!(var_entry= get_variable(&thd->user_vars, name, 0)))
+ null_value= 1;
+}
+
+
+bool Item_func_get_user_var::const_item() const
+{
+ return (!var_entry || current_thd->query_id != var_entry->update_query_id);
}
@@ -1901,6 +2106,7 @@ void Item_func_get_user_var::print(String *str)
str->append(')');
}
+
bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
{
/* Assume we don't have rtti */
@@ -1960,48 +2166,15 @@ err:
return 0;
}
-double Item_func_match::val()
-{
- if (ft_handler==NULL)
- return -1.0;
-
- if (join_key)
- {
- if (table->file->ft_handler)
- return ft_get_relevance(ft_handler);
-
- join_key=0; // Magic here ! See ha_myisam::ft_read()
- }
-
- /* we'll have to find ft_relevance manually in ft_handler array */
-
- int a,b,c;
- FT_DOC *docs=ft_handler->doc;
- my_off_t docid=table->file->row_position();
-
- if ((null_value=(docid==HA_OFFSET_ERROR)))
- return 0.0;
-
- // Assuming docs[] is sorted by dpos...
-
- for (a=0, b=ft_handler->ndocs, c=(a+b)/2; b-a>1; c=(a+b)/2)
- {
- if (docs[c].dpos > docid)
- b=c;
- else
- a=c;
- }
- if (docs[a].dpos == docid)
- return docs[a].weight;
- else
- return 0.0;
-
-}
void Item_func_match::init_search(bool no_order)
{
+ DBUG_ENTER("Item_func_match::init_search");
if (ft_handler)
- return;
+ DBUG_VOID_RETURN;
+
+ if (key == NO_SUCH_KEY)
+ concat= new Item_func_concat_ws(new Item_string(" ",1), fields);
if (master)
{
@@ -2009,31 +2182,32 @@ void Item_func_match::init_search(bool no_order)
master->init_search(no_order);
ft_handler=master->ft_handler;
join_key=master->join_key;
- return;
+ DBUG_VOID_RETURN;
}
String *ft_tmp=0;
char tmp1[FT_QUERY_MAXLEN];
String tmp2(tmp1,sizeof(tmp1));
- // MATCH ... AGAINST (NULL) is meaningless, but possible
+ // MATCH ... AGAINST (NULL) is meaningless, but possible
if (!(ft_tmp=key_item()->val_str(&tmp2)))
{
- ft_tmp=&tmp2;
+ ft_tmp= &tmp2;
tmp2.set("",0);
}
- ft_handler=(FT_DOCLIST *)
- table->file->ft_init_ext(key, (byte*) ft_tmp->ptr(), ft_tmp->length(),
- join_key && !no_order);
+ ft_handler=table->file->ft_init_ext(mode, key,
+ (byte*) ft_tmp->ptr(),
+ ft_tmp->length(),
+ join_key && !no_order);
if (join_key)
- {
table->file->ft_handler=ft_handler;
- return;
- }
+
+ DBUG_VOID_RETURN;
}
+
bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
{
List_iterator<Item> li(fields);
@@ -2042,12 +2216,12 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
maybe_null=1;
join_key=0;
- /* Serg:
- I'd rather say now that const_item is assumed in quite a bit of
- places, so it would be difficult to remove; If it would ever to be
- removed, this should include modifications to find_best and auto_close
- as complement to auto_init code above.
- */
+ /*
+ const_item is assumed in quite a bit of places, so it would be difficult
+ to remove; If it would ever to be removed, this should include
+ modifications to find_best and auto_close as complement to auto_init code
+ above.
+ */
if (Item_func::fix_fields(thd,tlist) || !const_item())
{
my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST");
@@ -2061,106 +2235,111 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
if (item->type() == Item::REF_ITEM)
li.replace(item= *((Item_ref *)item)->ref);
if (item->type() != Item::FIELD_ITEM || !item->used_tables())
- {
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH");
- return 1;
- }
+ key=NO_SUCH_KEY;
used_tables_cache|=item->used_tables();
}
/* check that all columns come from the same table */
- if (count_bits(used_tables_cache) != 1)
+ if (my_count_bits(used_tables_cache) != 1)
+ key=NO_SUCH_KEY;
+ const_item_cache=0;
+ table=((Item_field *)fields.head())->field->table;
+ table->fulltext_searched=1;
+ record=table->record[0];
+ if (key == NO_SUCH_KEY && mode != FT_BOOL)
{
my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH");
return 1;
}
- const_item_cache=0;
- table=((Item_field *)fields.head())->field->table;
- table->fulltext_searched=1;
+
return 0;
}
bool Item_func_match::fix_index()
{
- List_iterator<Item> li(fields);
+ List_iterator_fast<Item> li(fields);
Item_field *item;
- uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts=0, key;
+ uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts=0, keynr;
+ uint max_cnt=0, mkeys=0;
+
+ if (key == NO_SUCH_KEY)
+ return 0;
- for (key=0 ; key<table->keys ; key++)
+ for (keynr=0 ; keynr < table->keys ; keynr++)
{
- if ((table->key_info[key].flags & HA_FULLTEXT) &&
- (table->keys_in_use_for_query & (((key_map)1) << key)))
+ if ((table->key_info[keynr].flags & HA_FULLTEXT) &&
+ (table->keys_in_use_for_query & (((key_map)1) << keynr)))
{
- ft_to_key[fts]=key;
+ ft_to_key[fts]=keynr;
ft_cnt[fts]=0;
fts++;
}
}
if (!fts)
- {
- my_printf_error(ER_FT_MATCHING_KEY_NOT_FOUND,
- ER(ER_FT_MATCHING_KEY_NOT_FOUND),MYF(0));
- return 1;
- }
+ goto err;
while ((item=(Item_field*)(li++)))
{
- for (key=0 ; key<fts ; key++)
+ for (keynr=0 ; keynr < fts ; keynr++)
{
- KEY *ft_key=&table->key_info[ft_to_key[key]];
+ KEY *ft_key=&table->key_info[ft_to_key[keynr]];
uint key_parts=ft_key->key_parts;
for (uint part=0 ; part < key_parts ; part++)
{
if (item->field->eq(ft_key->key_part[part].field))
- ft_cnt[key]++;
+ ft_cnt[keynr]++;
}
}
}
- uint max_cnt=0, mkeys=0;
- for (key=0 ; key<fts ; key++)
+ for (keynr=0 ; keynr < fts ; keynr++)
{
- if (ft_cnt[key] > max_cnt)
+ if (ft_cnt[keynr] > max_cnt)
{
mkeys=0;
- max_cnt=ft_cnt[mkeys]=ft_cnt[key];
- ft_to_key[mkeys]=ft_to_key[key];
+ max_cnt=ft_cnt[mkeys]=ft_cnt[keynr];
+ ft_to_key[mkeys]=ft_to_key[keynr];
continue;
}
- if (max_cnt && ft_cnt[key] == max_cnt)
+ if (max_cnt && ft_cnt[keynr] == max_cnt)
{
mkeys++;
- ft_cnt[mkeys]=ft_cnt[key];
- ft_to_key[mkeys]=ft_to_key[key];
+ ft_cnt[mkeys]=ft_cnt[keynr];
+ ft_to_key[mkeys]=ft_to_key[keynr];
continue;
}
}
- for (key=0 ; key<=mkeys ; key++)
+ for (keynr=0 ; keynr <= mkeys ; keynr++)
{
// for now, partial keys won't work. SerG
if (max_cnt < fields.elements ||
- max_cnt < table->key_info[ft_to_key[key]].key_parts)
+ max_cnt < table->key_info[ft_to_key[keynr]].key_parts)
continue;
- this->key=ft_to_key[key];
+ key=ft_to_key[keynr];
return 0;
}
+err:
+ if (mode == FT_BOOL)
+ {
+ key=NO_SUCH_KEY;
+ return 0;
+ }
my_printf_error(ER_FT_MATCHING_KEY_NOT_FOUND,
- ER(ER_FT_MATCHING_KEY_NOT_FOUND),MYF(0));
+ ER(ER_FT_MATCHING_KEY_NOT_FOUND),MYF(0));
return 1;
}
+
bool Item_func_match::eq(const Item *item, bool binary_cmp) const
{
- if (item->type() != FUNC_ITEM)
- return 0;
-
- if (func_name() != ((Item_func*)item)->func_name())
+ if (item->type() != FUNC_ITEM ||
+ func_name() != ((Item_func*)item)->func_name())
return 0;
Item_func_match *ifm=(Item_func_match*) item;
@@ -2173,19 +2352,109 @@ bool Item_func_match::eq(const Item *item, bool binary_cmp) const
}
+double Item_func_match::val()
+{
+ DBUG_ENTER("Item_func_match::val");
+ if (ft_handler == NULL)
+ DBUG_RETURN(-1.0);
+
+ if (table->null_row) /* NULL row from an outer join */
+ return 0.0;
+
+ if (join_key)
+ {
+ if (table->file->ft_handler)
+ DBUG_RETURN(ft_handler->please->get_relevance(ft_handler));
+ join_key=0;
+ }
+
+ if (key == NO_SUCH_KEY)
+ {
+ String *a= concat->val_str(&value);
+ if ((null_value= (a == 0)))
+ DBUG_RETURN(0);
+ DBUG_RETURN(ft_handler->please->find_relevance(ft_handler,
+ (byte *)a->ptr(), a->length()));
+ }
+ else
+ DBUG_RETURN(ft_handler->please->find_relevance(ft_handler, record, 0));
+}
+
+longlong Item_func_bit_xor::val_int()
+{
+ ulonglong arg1= (ulonglong) args[0]->val_int();
+ ulonglong arg2= (ulonglong) args[1]->val_int();
+ if ((null_value= (args[0]->null_value || args[1]->null_value)))
+ return 0;
+ return (longlong) (arg1 ^ arg2);
+}
+
+
/***************************************************************************
System variables
- This has to be recoded after we get more than 3 system variables
****************************************************************************/
-Item *get_system_var(LEX_STRING name)
+Item *get_system_var(enum_var_type var_type, LEX_STRING name)
{
- if (!my_strcasecmp(name.str,"IDENTITY"))
- return new Item_int((char*) "@@IDENTITY",
- current_thd->insert_id(),21);
if (!my_strcasecmp(name.str,"VERSION"))
return new Item_string("@@VERSION",server_version,
(uint) strlen(server_version));
- net_printf(&current_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, name.str);
+
+ THD *thd=current_thd;
+ Item *item;
+ sys_var *var;
+ char buff[MAX_SYS_VAR_LENGTH+3+8], *pos;
+
+ if (!(var= find_sys_var(name.str)))
+ return 0;
+ if (!(item=var->item(thd, var_type)))
+ return 0; // Impossible
+ thd->safe_to_cache_query=0;
+ buff[0]='@';
+ buff[1]='@';
+ pos=buff+2;
+ if (var_type == OPT_SESSION)
+ pos=strmov(pos,"session.");
+ else if (var_type == OPT_GLOBAL)
+ pos=strmov(pos,"global.");
+ memcpy(pos, var->name, var->name_length+1);
+ // set_name() will allocate the name
+ item->set_name(buff,(uint) (pos-buff)+var->name_length);
+ return item;
+}
+
+
+/*
+ Check a user level lock.
+
+ SYNOPSIS:
+ val_int()
+
+ RETURN VALUES
+ 1 Available
+ 0 Already taken
+ NULL Error
+*/
+
+longlong Item_func_is_free_lock::val_int()
+{
+ String *res=args[0]->val_str(&value);
+ THD *thd=current_thd;
+ ULL *ull;
+ int error=0;
+
+ null_value=0;
+ if (!res || !res->length())
+ {
+ null_value=1;
+ return 0;
+ }
+
+ pthread_mutex_lock(&LOCK_user_locks);
+ ull= (ULL*) hash_search(&hash_user_locks,(byte*) res->ptr(),
+ res->length());
+ pthread_mutex_unlock(&LOCK_user_locks);
+ if (!ull || !ull->locked)
+ return 1;
return 0;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index 853995a7c92..4d171cda490 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -34,12 +34,12 @@ protected:
Item **args,*tmp_arg[2];
public:
uint arg_count;
- table_map used_tables_cache;
+ table_map used_tables_cache, not_null_tables_cache;
bool const_item_cache;
enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
GE_FUNC,GT_FUNC,FT_FUNC,
LIKE_FUNC,NOTLIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
- COND_AND_FUNC,COND_OR_FUNC,BETWEEN,IN_FUNC,INTERVAL_FUNC};
+ COND_AND_FUNC,COND_OR_FUNC,COND_XOR_FUNC,BETWEEN,IN_FUNC,INTERVAL_FUNC};
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL };
enum Type type() const { return FUNC_ITEM; }
virtual enum Functype functype() const { return UNKNOWN_FUNC; }
@@ -97,6 +97,7 @@ public:
bool fix_fields(THD *,struct st_table_list *);
void make_field(Send_field *field);
table_map used_tables() const;
+ table_map not_null_tables() const;
void update_used_tables();
bool eq(const Item *item, bool binary_cmp) const;
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
@@ -119,7 +120,10 @@ public:
{
return (null_value=args[0]->get_time(ltime));
}
+ bool is_null() { (void) val_int(); return null_value; }
friend class udf_handler;
+ unsigned int size_of() { return sizeof(*this);}
+ Field *tmp_table_field(TABLE *t_arg);
};
@@ -134,8 +138,10 @@ public:
longlong val_int() { return (longlong) val(); }
enum Item_result result_type () const { return REAL_RESULT; }
void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); }
+ unsigned int size_of() { return sizeof(*this);}
};
+
class Item_num_func :public Item_func
{
protected:
@@ -147,6 +153,8 @@ public:
longlong val_int() { return (longlong) val(); }
enum Item_result result_type () const { return hybrid_type; }
void fix_length_and_dec() { fix_num_length_and_dec(); }
+ bool is_null() { (void) val(); return null_value; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -161,23 +169,48 @@ class Item_num_op :public Item_func
enum Item_result result_type () const { return hybrid_type; }
void fix_length_and_dec() { fix_num_length_and_dec(); find_num_type(); }
void find_num_type(void);
+ bool is_null() { (void) val(); return null_value; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_int_func :public Item_func
{
public:
- Item_int_func() :Item_func() {}
- Item_int_func(Item *a) :Item_func(a) {}
- Item_int_func(Item *a,Item *b) :Item_func(a,b) {}
- Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) {}
- Item_int_func(List<Item> &list) :Item_func(list) {}
+ Item_int_func() :Item_func() { max_length=21; }
+ Item_int_func(Item *a) :Item_func(a) { max_length=21; }
+ Item_int_func(Item *a,Item *b) :Item_func(a,b) { max_length=21; }
+ Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { max_length=21; }
+ Item_int_func(List<Item> &list) :Item_func(list) { max_length=21; }
double val() { return (double) val_int(); }
String *val_str(String*str);
enum Item_result result_type () const { return INT_RESULT; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
+ void fix_length_and_dec() {}
};
+
+class Item_func_signed :public Item_int_func
+{
+public:
+ Item_func_signed(Item *a) :Item_int_func(a) {}
+ double val() { return args[0]->val(); }
+ longlong val_int() { return args[0]->val_int(); }
+ void fix_length_and_dec()
+ { max_length=args[0]->max_length; unsigned_flag=0; }
+};
+
+
+class Item_func_unsigned :public Item_int_func
+{
+public:
+ Item_func_unsigned(Item *a) :Item_int_func(a) {}
+ double val() { return args[0]->val(); }
+ longlong val_int() { return args[0]->val_int(); }
+ void fix_length_and_dec()
+ { max_length=args[0]->max_length; unsigned_flag=1; }
+};
+
+
class Item_func_plus :public Item_num_op
{
public:
@@ -194,8 +227,10 @@ public:
const char *func_name() const { return "-"; }
double val();
longlong val_int();
+ void fix_length_and_dec();
};
+
class Item_func_mul :public Item_num_op
{
public:
@@ -284,15 +319,35 @@ public:
const char *func_name() const { return "exp"; }
};
+
+class Item_func_ln :public Item_dec_func
+{
+public:
+ Item_func_ln(Item *a) :Item_dec_func(a) {}
+ double val();
+ const char *func_name() const { return "ln"; }
+};
+
+
class Item_func_log :public Item_dec_func
{
public:
Item_func_log(Item *a) :Item_dec_func(a) {}
+ Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {}
double val();
const char *func_name() const { return "log"; }
};
+class Item_func_log2 :public Item_dec_func
+{
+public:
+ Item_func_log2(Item *a) :Item_dec_func(a) {}
+ double val();
+ const char *func_name() const { return "log2"; }
+};
+
+
class Item_func_log10 :public Item_dec_func
{
public:
@@ -410,14 +465,15 @@ public:
class Item_func_rand :public Item_real_func
{
+ struct rand_struct *rand;
public:
Item_func_rand(Item *a) :Item_real_func(a) {}
Item_func_rand() :Item_real_func() {}
double val();
const char *func_name() const { return "rand"; }
- void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); }
bool const_item() const { return 0; }
table_map used_tables() const { return RAND_TABLE_BIT; }
+ void fix_length_and_dec();
};
@@ -440,6 +496,7 @@ class Item_func_units :public Item_real_func
double val();
const char *func_name() const { return name; }
void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -456,6 +513,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
enum Item_result result_type () const { return cmp_type; }
+ unsigned int size_of() { return sizeof(*this);}
+ table_map not_null_tables() const { return 0; }
};
class Item_func_min :public Item_func_min_max
@@ -481,6 +540,15 @@ public:
longlong val_int();
const char *func_name() const { return "length"; }
void fix_length_and_dec() { max_length=10; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+class Item_func_bit_length :public Item_func_length
+{
+public:
+ Item_func_bit_length(Item *a) :Item_func_length(a) {}
+ longlong val_int() { return Item_func_length::val_int()*8; }
+ const char *func_name() const { return "bit_length"; }
};
class Item_func_char_length :public Item_int_func
@@ -491,6 +559,7 @@ public:
longlong val_int();
const char *func_name() const { return "char_length"; }
void fix_length_and_dec() { max_length=10; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_locate :public Item_int_func
@@ -502,6 +571,7 @@ public:
const char *func_name() const { return "locate"; }
longlong val_int();
void fix_length_and_dec() { maybe_null=0; max_length=11; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -520,7 +590,8 @@ public:
void split_sum_func(List<Item> &fields);
void update_used_tables()
{
- item->update_used_tables() ; Item_func::update_used_tables();
+ item->update_used_tables();
+ Item_func::update_used_tables();
used_tables_cache|= item->used_tables();
const_item_cache&= item->const_item();
}
@@ -529,9 +600,11 @@ public:
{
maybe_null=0; max_length=3;
used_tables_cache|= item->used_tables();
+ not_null_tables_cache&= item->not_null_tables();
const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -543,6 +616,7 @@ public:
longlong val_int();
const char *func_name() const { return "ascii"; }
void fix_length_and_dec() { max_length=3; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_ord :public Item_int_func
@@ -552,7 +626,7 @@ public:
Item_func_ord(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "ord"; }
- void fix_length_and_dec() { max_length=21; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_find_in_set :public Item_int_func
@@ -565,25 +639,33 @@ public:
longlong val_int();
const char *func_name() const { return "find_in_set"; }
void fix_length_and_dec();
+ unsigned int size_of() { return sizeof(*this);}
};
+/* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */
+
+class Item_func_bit: public Item_int_func
+{
+public:
+ Item_func_bit(Item *a, Item *b) :Item_int_func(a, b) {}
+ Item_func_bit(Item *a) :Item_int_func(a) {}
+ void fix_length_and_dec() { unsigned_flag= 1; }
+};
-class Item_func_bit_or :public Item_int_func
+class Item_func_bit_or :public Item_func_bit
{
public:
- Item_func_bit_or(Item *a,Item *b) :Item_int_func(a,b) {}
+ Item_func_bit_or(Item *a, Item *b) :Item_func_bit(a, b) {}
longlong val_int();
const char *func_name() const { return "|"; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
};
-class Item_func_bit_and :public Item_int_func
+class Item_func_bit_and :public Item_func_bit
{
public:
- Item_func_bit_and(Item *a,Item *b) :Item_int_func(a,b) {}
+ Item_func_bit_and(Item *a, Item *b) :Item_func_bit(a, b) {}
longlong val_int();
const char *func_name() const { return "&"; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
};
class Item_func_bit_count :public Item_int_func
@@ -592,34 +674,31 @@ public:
Item_func_bit_count(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "bit_count"; }
- void fix_length_and_dec() { decimals=0; max_length=2; }
+ void fix_length_and_dec() { max_length=2; }
};
-class Item_func_shift_left :public Item_int_func
+class Item_func_shift_left :public Item_func_bit
{
public:
- Item_func_shift_left(Item *a,Item *b) :Item_int_func(a,b) {}
+ Item_func_shift_left(Item *a, Item *b) :Item_func_bit(a, b) {}
longlong val_int();
const char *func_name() const { return "<<"; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
};
-class Item_func_shift_right :public Item_int_func
+class Item_func_shift_right :public Item_func_bit
{
public:
- Item_func_shift_right(Item *a,Item *b) :Item_int_func(a,b) {}
+ Item_func_shift_right(Item *a, Item *b) :Item_func_bit(a, b) {}
longlong val_int();
const char *func_name() const { return ">>"; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
};
-class Item_func_bit_neg :public Item_int_func
+class Item_func_bit_neg :public Item_func_bit
{
public:
- Item_func_bit_neg(Item *a) :Item_int_func(a) {}
+ Item_func_bit_neg(Item *a) :Item_func_bit(a) {}
longlong val_int();
const char *func_name() const { return "~"; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
};
class Item_func_set_last_insert_id :public Item_int_func
@@ -628,7 +707,7 @@ public:
Item_func_set_last_insert_id(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "last_insert_id"; }
- void fix_length_and_dec() { decimals=0; max_length=args[0]->max_length; }
+ void fix_length_and_dec() { max_length=args[0]->max_length; }
};
class Item_func_benchmark :public Item_int_func
@@ -640,7 +719,8 @@ class Item_func_benchmark :public Item_int_func
{}
longlong val_int();
const char *func_name() const { return "benchmark"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; }
+ void fix_length_and_dec() { max_length=1; maybe_null=0; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -665,6 +745,8 @@ public:
return res;
}
Item_result result_type () const { return udf.result_type(); }
+ table_map not_null_tables() const { return 0; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -772,7 +854,8 @@ class Item_func_get_lock :public Item_int_func
Item_func_get_lock(Item *a,Item *b) :Item_int_func(a,b) {}
longlong val_int();
const char *func_name() const { return "get_lock"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_release_lock :public Item_int_func
@@ -782,7 +865,8 @@ class Item_func_release_lock :public Item_int_func
Item_func_release_lock(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "release_lock"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ unsigned int size_of() { return sizeof(*this);}
};
/* replication functions */
@@ -792,9 +876,11 @@ class Item_master_pos_wait :public Item_int_func
String value;
public:
Item_master_pos_wait(Item *a,Item *b) :Item_int_func(a,b) {}
+ Item_master_pos_wait(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
longlong val_int();
const char *func_name() const { return "master_pos_wait"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ void fix_length_and_dec() { max_length=21; maybe_null=1;}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -807,32 +893,34 @@ class Item_func_set_user_var :public Item_func
enum Item_result cached_result_type;
LEX_STRING name;
user_var_entry *entry;
+ char buffer[MAX_FIELD_WIDTH];
+ String value;
public:
- Item_func_set_user_var(LEX_STRING a,Item *b): Item_func(b), name(a) {}
+ Item_func_set_user_var(LEX_STRING a,Item *b):
+ Item_func(b), name(a), value(buffer,sizeof(buffer)) {}
double val();
longlong val_int();
String *val_str(String *str);
- void update_hash(void *ptr, uint length, enum Item_result type);
+ bool update_hash(const void *ptr, uint length, enum Item_result type);
bool update();
enum Item_result result_type () const { return cached_result_type; }
bool fix_fields(THD *thd,struct st_table_list *tables);
void fix_length_and_dec();
void print(String *str);
const char *func_name() const { return "set_user_var"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_get_user_var :public Item_func
{
LEX_STRING name;
- user_var_entry *entry;
- bool const_var_flag;
+ user_var_entry *var_entry;
public:
Item_func_get_user_var(LEX_STRING a):
- Item_func(), name(a), const_var_flag(1) {}
- user_var_entry *get_entry();
+ Item_func(), name(a) {}
double val();
longlong val_int();
String *val_str(String* str);
@@ -840,10 +928,11 @@ public:
void print(String *str);
enum Item_result result_type() const;
const char *func_name() const { return "get_user_var"; }
- bool const_item() const { return const_var_flag; }
+ bool const_item() const;
table_map used_tables() const
- { return const_var_flag ? 0 : RAND_TABLE_BIT; }
+ { return const_item() ? 0 : RAND_TABLE_BIT; }
bool eq(const Item *item, bool binary_cmp) const;
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -864,35 +953,91 @@ class Item_func_match :public Item_real_func
{
public:
List<Item> fields;
+ String value;
TABLE *table;
- uint key;
- bool join_key;
Item_func_match *master;
- FT_DOCLIST *ft_handler;
+ FT_INFO * ft_handler;
+ Item *concat;
+ byte *record;
+ uint key, mode;
+ bool join_key;
Item_func_match(List<Item> &a, Item *b): Item_real_func(b),
- fields(a), table(0), join_key(0), master(0), ft_handler(0) {}
+ fields(a), table(0), master(0), ft_handler(0),
+ concat(0), key(0), join_key(0)
+ {}
~Item_func_match()
{
- if (!master)
+ if (!master && ft_handler)
{
- if (ft_handler)
- {
- ft_close_search(ft_handler);
- if(join_key)
- table->file->ft_handler=0;
- table->fulltext_searched=0;
- }
+ ft_handler->please->close_search(ft_handler);
+ ft_handler=0;
+ if(join_key)
+ table->file->ft_handler=0;
+ table->fulltext_searched=0;
}
+ if (concat)
+ delete concat;
}
- const char *func_name() const { return "match"; }
enum Functype functype() const { return FT_FUNC; }
void update_used_tables() {}
+ table_map not_null_tables() const { return 0; }
bool fix_fields(THD *thd,struct st_table_list *tlist);
bool eq(const Item *, bool binary_cmp) const;
- double val();
longlong val_int() { return val()!=0.0; }
+ double val();
bool fix_index();
void init_search(bool no_order);
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
+class Item_func_match_nl :public Item_func_match
+{
+public:
+ Item_func_match_nl(List<Item> &a, Item *b)
+ :Item_func_match(a,b)
+ { mode=FT_NL; }
+ const char *func_name() const { return "match_nl"; }
+};
+
+
+class Item_func_match_bool :public Item_func_match
+{
+public:
+ Item_func_match_bool(List<Item> &a, Item *b)
+ :Item_func_match(a,b)
+ { mode=FT_BOOL; }
+ const char *func_name() const { return "match_bool"; }
+};
+
+/* For type casts */
+
+enum Item_cast
+{
+ ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT,
+ ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME, ITEM_CAST_CHAR
+};
+
+Item *create_func_cast(Item *a, Item_cast cast_type);
+
+
+class Item_func_bit_xor : public Item_func_bit
+{
+public:
+ Item_func_bit_xor(Item *a, Item *b) :Item_func_bit(a, b) {}
+ longlong val_int();
+ const char *func_name() const { return "^"; }
+};
+
+class Item_func_is_free_lock :public Item_int_func
+{
+ String value;
+public:
+ Item_func_is_free_lock(Item *a) :Item_int_func(a) {}
+ longlong val_int();
+ const char *func_name() const { return "check_lock"; }
+ void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ unsigned int size_of() { return sizeof(*this);}
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index ff01d841e78..31c2dc943e5 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -17,7 +17,7 @@
/* This file defines all string functions
** Warning: Some string functions doesn't always put and end-null on a String
-** (This shouldn't be neaded)
+** (This shouldn't be needed)
*/
#ifdef __GNUC__
@@ -27,11 +27,12 @@
#include "mysql_priv.h"
#include "sql_acl.h"
#include <m_ctype.h>
-#ifdef HAVE_CRYPT_H
-#include <crypt.h>
-#endif
-
+#ifdef HAVE_OPENSSL
+#include <openssl/des.h>
+#endif /* HAVE_OPENSSL */
#include "md5.h"
+#include "sha1.h"
+#include "my_aes.h"
String empty_string("");
@@ -40,7 +41,7 @@ uint nr_of_decimals(const char *str)
if ((str=strchr(str,'.')))
{
const char *start= ++str;
- for ( ; isdigit(*str) ; str++) ;
+ for (; isdigit(*str) ; str++) ;
return (uint) (str-start);
}
return 0;
@@ -66,14 +67,18 @@ String *Item_func_md5::val_str(String *str)
String * sptr= args[0]->val_str(str);
if (sptr)
{
- MD5_CTX context;
+ my_MD5_CTX context;
unsigned char digest[16];
null_value=0;
- MD5Init (&context);
- MD5Update (&context,(unsigned char *) sptr->ptr(), sptr->length());
- MD5Final (digest, &context);
- str->alloc(32); // Ensure that memory is free
+ my_MD5Init (&context);
+ my_MD5Update (&context,(unsigned char *) sptr->ptr(), sptr->length());
+ my_MD5Final (digest, &context);
+ if (str->alloc(32)) // Ensure that memory is free
+ {
+ null_value=1;
+ return 0;
+ }
sprintf((char *) str->ptr(),
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
digest[0], digest[1], digest[2], digest[3],
@@ -93,10 +98,123 @@ void Item_func_md5::fix_length_and_dec()
max_length=32;
}
+
+String *Item_func_sha::val_str(String *str)
+{
+ String * sptr= args[0]->val_str(str);
+ if (sptr) /* If we got value different from NULL */
+ {
+ SHA1_CONTEXT context; /* Context used to generate SHA1 hash */
+ /* Temporary buffer to store 160bit digest */
+ uint8 digest[SHA1_HASH_SIZE];
+ sha1_reset(&context); /* We do not have to check for error here */
+ /* No need to check error as the only case would be too long message */
+ sha1_input(&context,(const unsigned char *) sptr->ptr(), sptr->length());
+ /* Ensure that memory is free and we got result */
+ if (!( str->alloc(SHA1_HASH_SIZE*2) || (sha1_result(&context,digest))))
+ {
+ sprintf((char *) str->ptr(),
+ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\
+%02x%02x%02x%02x%02x%02x%02x%02x",
+ digest[0], digest[1], digest[2], digest[3],
+ digest[4], digest[5], digest[6], digest[7],
+ digest[8], digest[9], digest[10], digest[11],
+ digest[12], digest[13], digest[14], digest[15],
+ digest[16], digest[17], digest[18], digest[19]);
+
+ str->length((uint) SHA1_HASH_SIZE*2);
+ null_value=0;
+ return str;
+ }
+ }
+ null_value=1;
+ return 0;
+}
+
+void Item_func_sha::fix_length_and_dec()
+{
+ max_length=SHA1_HASH_SIZE*2; // size of hex representation of hash
+}
+
+
+/* Implementation of AES encryption routines */
+
+String *Item_func_aes_encrypt::val_str(String *str)
+{
+ char key_buff[80];
+ String tmp_key_value(key_buff, sizeof(key_buff));
+ String *sptr= args[0]->val_str(str); // String to encrypt
+ String *key= args[1]->val_str(&tmp_key_value); // key
+ int aes_length;
+ if (sptr && key) // we need both arguments to be not NULL
+ {
+ null_value=0;
+ aes_length=my_aes_get_size(sptr->length()); // Calculate result length
+
+ if (!str_value.alloc(aes_length)) // Ensure that memory is free
+ {
+ // finally encrypt directly to allocated buffer.
+ if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str_value.ptr(),
+ key->ptr(), key->length()) == aes_length)
+ {
+ // We got the expected result length
+ str_value.length((uint) aes_length);
+ return &str_value;
+ }
+ }
+ }
+ null_value=1;
+ return 0;
+}
+
+
+void Item_func_aes_encrypt::fix_length_and_dec()
+{
+ max_length=my_aes_get_size(args[0]->max_length);
+}
+
+
+String *Item_func_aes_decrypt::val_str(String *str)
+{
+ char key_buff[80];
+ String tmp_key_value(key_buff, sizeof(key_buff)), *sptr, *key;
+ DBUG_ENTER("Item_func_aes_decrypt::val_str");
+
+ sptr= args[0]->val_str(str); // String to decrypt
+ key= args[1]->val_str(&tmp_key_value); // Key
+ if (sptr && key) // Need to have both arguments not NULL
+ {
+ null_value=0;
+ if (!str_value.alloc(sptr->length())) // Ensure that memory is free
+ {
+ // finally decrypt directly to allocated buffer.
+ int length;
+ length=my_aes_decrypt(sptr->ptr(), sptr->length(),
+ (char*) str_value.ptr(),
+ key->ptr(), key->length());
+ if (length >= 0) // if we got correct data data
+ {
+ str_value.length((uint) length);
+ DBUG_RETURN(&str_value);
+ }
+ }
+ }
+ // Bad parameters. No memory or bad data will all go here
+ null_value=1;
+ DBUG_RETURN(0);
+}
+
+
+void Item_func_aes_decrypt::fix_length_and_dec()
+{
+ max_length=args[0]->max_length;
+}
+
+
/*
-** Concatinate args with the following premissess
-** If only one arg which is ok, return value of arg
-** Don't reallocate val_str() if not absolute necessary.
+ Concatenate args with the following premises:
+ If only one arg (which is ok), return value of arg
+ Don't reallocate val_str() if not absolute necessary.
*/
String *Item_func_concat::val_str(String *str)
@@ -121,7 +239,8 @@ String *Item_func_concat::val_str(String *str)
goto null;
if (res2->length() == 0)
continue;
- if (res->length()+res2->length() > max_allowed_packet)
+ if (res->length()+res2->length() >
+ current_thd->variables.max_allowed_packet)
goto null; // Error check
if (res->alloced_length() >= res->length()+res2->length())
{ // Use old buffer
@@ -199,11 +318,166 @@ void Item_func_concat::fix_length_and_dec()
}
}
+/*
+ Function des_encrypt() by tonu@spam.ee & monty
+ Works only if compiled with OpenSSL library support.
+ This returns a binary string where first character is CHAR(128 | key-number).
+ If one uses a string key key_number is 127.
+ Encryption result is longer than original by formula:
+ new_length= org_length + (8-(org_length % 8))+1
+*/
+
+String *Item_func_des_encrypt::val_str(String *str)
+{
+#ifdef HAVE_OPENSSL
+ DES_cblock ivec;
+ struct st_des_keyblock keyblock;
+ struct st_des_keyschedule keyschedule;
+ const char *append_str="********";
+ uint key_number, res_length, tail;
+ String *res= args[0]->val_str(str);
+
+ if ((null_value=args[0]->null_value))
+ return 0;
+ if ((res_length=res->length()) == 0)
+ return &empty_string;
+
+ if (arg_count == 1)
+ {
+ /* Protect against someone doing FLUSH DES_KEY_FILE */
+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
+ keyschedule= des_keyschedule[key_number=des_default_key];
+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
+ }
+ else if (args[1]->result_type() == INT_RESULT)
+ {
+ key_number= (uint) args[1]->val_int();
+ if (key_number > 9)
+ goto error;
+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
+ keyschedule= des_keyschedule[key_number];
+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
+ }
+ else
+ {
+ String *keystr=args[1]->val_str(&tmp_value);
+ if (!keystr)
+ goto error;
+ key_number=127; // User key string
+
+ /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */
+ bzero((char*) &ivec,sizeof(ivec));
+ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
+ (uchar*) keystr->ptr(), (int) keystr->length(),
+ 1, (uchar*) &keyblock,ivec);
+ DES_set_key_unchecked(&keyblock.key1,&keyschedule.ks1);
+ DES_set_key_unchecked(&keyblock.key2,&keyschedule.ks2);
+ DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3);
+ }
+
+ /*
+ The problem: DES algorithm requires original data to be in 8-bytes
+ chunks. Missing bytes get filled with '*'s and result of encryption
+ can be up to 8 bytes longer than original string. When decrypted,
+ we do not know the size of original string :(
+ We add one byte with value 0x1..0x8 as the last byte of the padded
+ string marking change of string length.
+ */
+
+ tail= (8-(res_length) % 8); // 1..8 marking extra length
+ res_length+=tail;
+ if (tail && res->append(append_str, tail) || tmp_value.alloc(res_length+1))
+ goto error;
+ (*res)[res_length-1]=tail; // save extra length
+ tmp_value.length(res_length+1);
+ tmp_value[0]=(char) (128 | key_number);
+ // Real encryption
+ bzero((char*) &ivec,sizeof(ivec));
+ DES_ede3_cbc_encrypt((const uchar*) (res->ptr()),
+ (uchar*) (tmp_value.ptr()+1),
+ res_length,
+ &keyschedule.ks1,
+ &keyschedule.ks2,
+ &keyschedule.ks3,
+ &ivec, TRUE);
+ return &tmp_value;
+
+error:
+#endif /* HAVE_OPENSSL */
+ null_value=1;
+ return 0;
+}
+
+
+String *Item_func_des_decrypt::val_str(String *str)
+{
+#ifdef HAVE_OPENSSL
+ DES_key_schedule ks1, ks2, ks3;
+ DES_cblock ivec;
+ struct st_des_keyblock keyblock;
+ struct st_des_keyschedule keyschedule;
+ String *res= args[0]->val_str(str);
+ uint length=res->length(),tail;
+
+ if ((null_value=args[0]->null_value))
+ return 0;
+ length=res->length();
+ if (length < 9 || (length % 8) != 1 || !((*res)[0] & 128))
+ return res; // Skip decryption if not encrypted
+
+ if (arg_count == 1) // If automatic uncompression
+ {
+ uint key_number=(uint) (*res)[0] & 127;
+ // Check if automatic key and that we have privilege to uncompress using it
+ if (!(current_thd->master_access & SUPER_ACL) || key_number > 9)
+ goto error;
+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
+ keyschedule= des_keyschedule[key_number];
+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
+ }
+ else
+ {
+ // We make good 24-byte (168 bit) key from given plaintext key with MD5
+ String *keystr=args[1]->val_str(&tmp_value);
+ if (!keystr)
+ goto error;
+
+ bzero((char*) &ivec,sizeof(ivec));
+ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
+ (uchar*) keystr->ptr(),(int) keystr->length(),
+ 1,(uchar*) &keyblock,ivec);
+ // Here we set all 64-bit keys (56 effective) one by one
+ DES_set_key_unchecked(&keyblock.key1,&keyschedule.ks1);
+ DES_set_key_unchecked(&keyblock.key2,&keyschedule.ks2);
+ DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3);
+ }
+ if (tmp_value.alloc(length-1))
+ goto error;
+
+ bzero((char*) &ivec,sizeof(ivec));
+ DES_ede3_cbc_encrypt((const uchar*) res->ptr()+1,
+ (uchar*) (tmp_value.ptr()),
+ length-1,
+ &keyschedule.ks1,
+ &keyschedule.ks2,
+ &keyschedule.ks3,
+ &ivec, FALSE);
+ /* Restore old length of key */
+ if ((tail=(uint) (uchar) tmp_value[length-2]) > 8)
+ goto error; // Wrong key
+ tmp_value.length(length-1-tail);
+ return &tmp_value;
+
+error:
+#endif /* HAVE_OPENSSL */
+ null_value=1;
+ return 0;
+}
/*
-** concat with separator. First arg is the separator
-** concat_ws takes at least two arguments.
+ concat with separator. First arg is the separator
+ concat_ws takes at least two arguments.
*/
String *Item_func_concat_ws::val_str(String *str)
@@ -221,21 +495,21 @@ String *Item_func_concat_ws::val_str(String *str)
str->length(0); // QQ; Should be removed
res=str;
- // Skip until non-null and non-empty argument is found.
+ // Skip until non-null argument is found.
// If not, return the empty string
for (i=0; i < arg_count; i++)
- if ((res= args[i]->val_str(str)) && res->length())
+ if ((res= args[i]->val_str(str)))
break;
if (i == arg_count)
return &empty_string;
for (i++; i < arg_count ; i++)
{
- if (!(res2= args[i]->val_str(use_as_buff)) || !res2->length())
- continue; // Skipp NULL and empty string
+ if (!(res2= args[i]->val_str(use_as_buff)))
+ continue; // Skip NULL
if (res->length() + sep_str->length() + res2->length() >
- max_allowed_packet)
+ current_thd->variables.max_allowed_packet)
goto null; // Error check
if (res->alloced_length() >=
res->length() + sep_str->length() + res2->length())
@@ -332,9 +606,10 @@ void Item_func_concat_ws::fix_length_and_dec()
max_length=MAX_BLOB_WIDTH;
maybe_null=1;
}
- used_tables_cache|=separator->used_tables();
- const_item_cache&=separator->const_item();
- with_sum_func= with_sum_func || separator->with_sum_func;
+ used_tables_cache|= separator->used_tables();
+ not_null_tables_cache&= separator->not_null_tables();
+ const_item_cache&= separator->const_item();
+ with_sum_func= with_sum_func || separator->with_sum_func;
}
void Item_func_concat_ws::update_used_tables()
@@ -397,7 +672,7 @@ void Item_func_reverse::fix_length_and_dec()
/*
** Replace all occurences of string2 in string1 with string3.
-** Don't reallocate val_str() if not neaded
+** Don't reallocate val_str() if not needed
*/
/* TODO: Fix that this works with binary strings when using USE_MB */
@@ -456,7 +731,8 @@ redo:
while (j != search_end)
if (*i++ != *j++) goto skipp;
offset= (int) (ptr-res->ptr());
- if (res->length()-from_length + to_length > max_allowed_packet)
+ if (res->length()-from_length + to_length >
+ current_thd->variables.max_allowed_packet)
goto null;
if (!alloced)
{
@@ -476,7 +752,8 @@ skipp:
#endif /* USE_MB */
do
{
- if (res->length()-from_length + to_length > max_allowed_packet)
+ if (res->length()-from_length + to_length >
+ current_thd->variables.max_allowed_packet)
goto null;
if (!alloced)
{
@@ -501,8 +778,8 @@ void Item_func_replace::fix_length_and_dec()
int diff=(int) (args[2]->max_length - args[1]->max_length);
if (diff > 0 && args[1]->max_length)
{ // Calculate of maxreplaces
- max_length= max_length/args[1]->max_length;
- max_length= (max_length+1)*(uint) diff;
+ uint max_substrs= max_length/args[1]->max_length;
+ max_length+= max_substrs * (uint)diff;
}
if (max_length > MAX_BLOB_WIDTH)
{
@@ -533,10 +810,11 @@ String *Item_func_insert::val_str(String *str)
}
#endif
if (start > res->length()+1)
- return res; // Wrong param; skipp insert
+ return res; // Wrong param; skip insert
if (length > res->length()-start)
length=res->length()-start;
- if (res->length() - length + res2->length() > max_allowed_packet)
+ if (res->length() - length + res2->length() >
+ current_thd->variables.max_allowed_packet)
goto null; // OOM check
res=copy_if_not_alloced(str,res,res->length());
res->replace(start,length,*res2);
@@ -619,7 +897,7 @@ void Item_str_func::left_right_max_length()
max_length=args[0]->max_length;
if (args[1]->const_item())
{
- int length=(int) args[1]->val_int();
+ int length=(int) args[1]->val_int()*default_charset_info->mbmaxlen;
if (length <= 0)
max_length=0;
else
@@ -712,7 +990,7 @@ void Item_func_substr::fix_length_and_dec()
}
if (arg_count == 3 && args[2]->const_item())
{
- int32 length= (int32) args[2]->val_int();
+ int32 length= (int32) args[2]->val_int() * default_charset_info->mbmaxlen;
if (length <= 0)
max_length=0; /* purecov: inspected */
else
@@ -1093,9 +1371,9 @@ String *Item_func_database::val_str(String *str)
String *Item_func_user::val_str(String *str)
{
+ // TODO: make USER() replicate properly (currently it is replicated to "")
THD *thd=current_thd;
- // For a replication thread user may be a null pointer (To be fixed)
- if (!thd->user ||
+ if (!(thd->user) || // for system threads (e.g. replication SQL thread)
str->copy((const char*) thd->user,(uint) strlen(thd->user)) ||
str->append('@') ||
str->append(thd->host ? thd->host : thd->ip ? thd->ip : ""))
@@ -1112,7 +1390,7 @@ void Item_func_soundex::fix_length_and_dec()
/*
If alpha, map input letter to soundex code.
- If not alpha and remove_garbage is set then skipp to next char
+ If not alpha and remove_garbage is set then skip to next char
else return 0
*/
@@ -1139,12 +1417,12 @@ String *Item_func_soundex::val_str(String *str)
if ((null_value=args[0]->null_value))
return 0; /* purecov: inspected */
- if (str_value.alloc(max(res->length(),4)))
+ if (tmp_value.alloc(max(res->length(),4)))
return str; /* purecov: inspected */
- char *to= (char *) str_value.ptr();
+ char *to= (char *) tmp_value.ptr();
char *from= (char *) res->ptr(), *end=from+res->length();
- while (from != end && isspace(*from)) // Skipp pre-space
+ while (from != end && isspace(*from)) // Skip pre-space
from++; /* purecov: inspected */
if (from == end)
return &empty_string; // No alpha characters.
@@ -1165,11 +1443,11 @@ String *Item_func_soundex::val_str(String *str)
last_ch = ch; // save code of last input letter
} // for next double-letter check
}
- for (end=(char*) str_value.ptr()+4 ; to < end ; to++)
+ for (end=(char*) tmp_value.ptr()+4 ; to < end ; to++)
*to = '0';
*to=0; // end string
- str_value.length((uint) (to-str_value.ptr()));
- return &str_value;
+ tmp_value.length((uint) (to-tmp_value.ptr()));
+ return &tmp_value;
}
@@ -1193,18 +1471,24 @@ String *Item_func_format::val_str(String *str)
return 0; /* purecov: inspected */
dec= decimals ? decimals+1 : 0;
str->set(nr,decimals);
+#ifdef HAVE_ISNAN
+ if (isnan(nr))
+ return str;
+#endif
str_length=str->length();
if (nr < 0)
str_length--; // Don't count sign
- length=str->length()+(diff=(str_length- dec-1)/3);
- if (diff)
+
+ /* We need this test to handle 'nan' values */
+ if (str_length >= dec+4)
{
char *tmp,*pos;
- str=copy_if_not_alloced(&tmp_str,str,length);
+ length= str->length()+(diff=(str_length- dec-1)/3);
+ str= copy_if_not_alloced(&tmp_str,str,length);
str->length(length);
- tmp=(char*) str->ptr()+length - dec-1;
- for (pos=(char*) str->ptr()+length ; pos != tmp; pos--)
- pos[0]=pos[- (int) diff];
+ tmp= (char*) str->ptr()+length - dec-1;
+ for (pos= (char*) str->ptr()+length-1; pos != tmp; pos--)
+ pos[0]= pos[-(int) diff];
while (diff)
{
pos[0]=pos[-(int) diff]; pos--;
@@ -1223,15 +1507,20 @@ void Item_func_elt::fix_length_and_dec()
{
max_length=0;
decimals=0;
- for (uint i=1 ; i < arg_count ; i++)
+#if MYSQL_VERSION_ID < 40100
+ for (uint i= 0; i < arg_count ; i++)
+#else
+ for (uint i= 1; i < arg_count ; i++)
+#endif
{
set_if_bigger(max_length,args[i]->max_length);
set_if_bigger(decimals,args[i]->decimals);
}
maybe_null=1; // NULL if wrong first arg
with_sum_func= with_sum_func || item->with_sum_func;
- used_tables_cache|=item->used_tables();
- const_item_cache&=item->const_item();
+ used_tables_cache|= item->used_tables();
+ not_null_tables_cache&= item->not_null_tables();
+ const_item_cache&= item->const_item();
}
@@ -1260,37 +1549,39 @@ void Item_func_elt::update_used_tables()
double Item_func_elt::val()
{
uint tmp;
+ null_value=1;
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
- {
- null_value=1;
return 0.0;
- }
- null_value=0;
- return args[tmp-1]->val();
+
+ double result= args[tmp-1]->val();
+ null_value= args[tmp-1]->null_value;
+ return result;
}
+
longlong Item_func_elt::val_int()
{
uint tmp;
+ null_value=1;
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
- {
- null_value=1;
return 0;
- }
- null_value=0;
- return args[tmp-1]->val_int();
+
+ longlong result= args[tmp-1]->val_int();
+ null_value= args[tmp-1]->null_value;
+ return result;
}
+
String *Item_func_elt::val_str(String *str)
{
uint tmp;
+ null_value=1;
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
- {
- null_value=1;
return NULL;
- }
- null_value=0;
- return args[tmp-1]->val_str(str);
+
+ String *result= args[tmp-1]->val_str(str);
+ null_value= args[tmp-1]->null_value;
+ return result;
}
@@ -1312,8 +1603,9 @@ void Item_func_make_set::fix_length_and_dec()
max_length=arg_count-1;
for (uint i=1 ; i < arg_count ; i++)
max_length+=args[i]->max_length;
- used_tables_cache|=item->used_tables();
- const_item_cache&=item->const_item();
+ used_tables_cache|= item->used_tables();
+ not_null_tables_cache&= item->not_null_tables();
+ const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
}
@@ -1346,7 +1638,7 @@ String *Item_func_make_set::val_str(String *str)
if (bits & 1)
{
String *res= (*ptr)->val_str(str);
- if (res) // Skipp nulls
+ if (res) // Skip nulls
{
if (!first_found)
{ // First argument
@@ -1418,14 +1710,11 @@ inline String* alloc_buffer(String *res,String *str,String *tmp_value,
str->length(length);
return str;
}
- else
- {
- if (tmp_value->alloc(length))
- return 0;
- (void) tmp_value->copy(*res);
- tmp_value->length(length);
- return tmp_value;
- }
+ if (tmp_value->alloc(length))
+ return 0;
+ (void) tmp_value->copy(*res);
+ tmp_value->length(length);
+ return tmp_value;
}
res->length(length);
return res;
@@ -1470,7 +1759,8 @@ String *Item_func_repeat::val_str(String *str)
if (count == 1) // To avoid reallocs
return res;
length=res->length();
- if (length > max_allowed_packet/count)// Safe length check
+ // Safe length check
+ if (length > current_thd->variables.max_allowed_packet/count)
goto err; // Probably an error
tot_length= length*(uint) count;
if (!(res= alloc_buffer(res,str,&tmp_value,tot_length)))
@@ -1517,9 +1807,9 @@ String *Item_func_rpad::val_str(String *str)
const char *ptr_pad;
int32 count= (int32) args[1]->val_int();
String *res =args[0]->val_str(str);
- String *rpad = args[2]->val_str(str);
+ String *rpad = args[2]->val_str(&rpad_str);
- if (!res || args[1]->null_value || !rpad)
+ if (!res || args[1]->null_value || !rpad || count < 0)
goto err;
null_value=0;
if (count <= (int32) (res_length=res->length()))
@@ -1528,7 +1818,8 @@ String *Item_func_rpad::val_str(String *str)
return (res);
}
length_pad= rpad->length();
- if ((ulong) count > max_allowed_packet || args[2]->null_value || !length_pad)
+ if ((ulong) count > current_thd->variables.max_allowed_packet ||
+ args[2]->null_value || !length_pad)
goto err;
if (!(res= alloc_buffer(res,str,&tmp_value,count)))
goto err;
@@ -1576,7 +1867,7 @@ String *Item_func_lpad::val_str(String *str)
const char *ptr_pad;
ulong count= (long) args[1]->val_int();
String *res= args[0]->val_str(str);
- String *lpad= args[2]->val_str(str);
+ String *lpad= args[2]->val_str(&lpad_str);
if (!res || args[1]->null_value || !lpad)
goto err;
@@ -1587,7 +1878,8 @@ String *Item_func_lpad::val_str(String *str)
return (res);
}
length_pad= lpad->length();
- if (count > max_allowed_packet || args[2]->null_value || !length_pad)
+ if (count > current_thd->variables.max_allowed_packet ||
+ args[2]->null_value || !length_pad)
goto err;
if (res->alloced_length() < count)
@@ -1651,6 +1943,45 @@ String *Item_func_conv::val_str(String *str)
return str;
}
+
+String *Item_func_hex::val_str(String *str)
+{
+ if (args[0]->result_type() != STRING_RESULT)
+ {
+ /* Return hex of unsigned longlong value */
+ longlong dec= args[0]->val_int();
+ char ans[65],*ptr;
+ if ((null_value= args[0]->null_value))
+ return 0;
+ ptr= longlong2str(dec,ans,16);
+ if (str->copy(ans,(uint32) (ptr-ans)))
+ return &empty_string; // End of memory
+ return str;
+ }
+
+ /* Convert given string to a hex string, character by character */
+ String *res= args[0]->val_str(str);
+ const char *from, *end;
+ char *to;
+ if (!res || tmp_value.alloc(res->length()*2))
+ {
+ null_value=1;
+ return 0;
+ }
+ null_value=0;
+ tmp_value.length(res->length()*2);
+ for (from=res->ptr(), end=from+res->length(), to= (char*) tmp_value.ptr();
+ from != end ;
+ from++, to+=2)
+ {
+ uint tmp=(uint) (uchar) *from;
+ to[0]=_dig_vec[tmp >> 4];
+ to[1]=_dig_vec[tmp & 15];
+ }
+ return &tmp_value;
+}
+
+
#include <my_dir.h> // For my_stat
String *Item_load_file::val_str(String *str)
@@ -1669,7 +2000,7 @@ String *Item_load_file::val_str(String *str)
/* my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), file_name->c_ptr()); */
goto err;
}
- if (stat_info.st_size > (long) max_allowed_packet)
+ if (stat_info.st_size > (long) current_thd->variables.max_allowed_packet)
{
/* my_error(ER_TOO_LONG_STRING, MYF(0), file_name->c_ptr()); */
goto err;
@@ -1713,6 +2044,10 @@ String* Item_func_export_set::val_str(String* str)
null_value=1;
return 0;
}
+ /*
+ Arg count can only be 3, 4 or 5 here. This is guaranteed from the
+ grammar for EXPORT_SET()
+ */
switch(arg_count) {
case 5:
num_set_values = (uint) args[4]->val_int();
@@ -1743,7 +2078,7 @@ String* Item_func_export_set::val_str(String* str)
str->append(*yes);
else
str->append(*no);
- if(i != num_set_values - 1)
+ if (i != num_set_values - 1)
str->append(*sep);
}
return str;
@@ -1761,24 +2096,23 @@ String* Item_func_inet_ntoa::val_str(String* str)
uchar buf[8], *p;
ulonglong n = (ulonglong) args[0]->val_int();
char num[4];
+
/*
- we do not know if args[0] is NULL until we have called
+ We do not know if args[0] is NULL until we have called
some val function on it if args[0] is not a constant!
+
+ Also return null if n > 255.255.255.255
*/
- if ((null_value=args[0]->null_value))
+ if ((null_value= (args[0]->null_value || n > (ulonglong) LL(4294967295))))
return 0; // Null value
str->length(0);
- int8store(buf,n);
+ int4store(buf,n);
- /*
- Now we can assume little endian.
- We handle the possibility of an 8-byte IP address however, we do
- not want to confuse those who are just using 4 byte ones
- */
- for (p= buf + 8; p > buf+4 && p[-1] == 0 ; p-- ) ;
+ /* Now we can assume little endian. */
+
num[3]='.';
- while (p-- > buf)
+ for (p=buf+4 ; p-- > buf ; )
{
uint c = *p;
uint n1,n2; // Try to avoid divisions
@@ -1796,3 +2130,94 @@ String* Item_func_inet_ntoa::val_str(String* str)
str->length(str->length()-1); // Remove last '.';
return str;
}
+
+/*
+ QUOTE() function returns argument string in single quotes suitable for
+ using in a SQL statement.
+
+ DESCRIPTION
+ Adds a \ before all characters that needs to be escaped in a SQL string.
+ We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
+ running commands from a file in windows.
+
+ This function is very useful when you want to generate SQL statements
+
+ RETURN VALUES
+ str Quoted string
+ NULL Argument to QUOTE() was NULL or out of memory.
+*/
+
+#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
+
+String *Item_func_quote::val_str(String *str)
+{
+ /*
+ Bit mask that has 1 for set for the position of the following characters:
+ 0, \, ' and ^Z
+ */
+
+ static uchar escmask[32]=
+ {
+ 0x01, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ char *from, *to, *end, *start;
+ String *arg= args[0]->val_str(str);
+ uint arg_length, new_length;
+ if (!arg) // Null argument
+ goto null;
+ arg_length= arg->length();
+ new_length= arg_length+2; /* for beginning and ending ' signs */
+
+ for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
+ new_length+= get_esc_bit(escmask, (uchar) *from);
+
+ /*
+ We have to use realloc() instead of alloc() as we want to keep the
+ old result in str
+ */
+ if (str->realloc(new_length))
+ goto null;
+
+ /*
+ As 'arg' and 'str' may be the same string, we must replace characters
+ from the end to the beginning
+ */
+ to= (char*) str->ptr() + new_length - 1;
+ *to--= '\'';
+ for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--)
+ {
+ /*
+ We can't use the bitmask here as we want to replace \O and ^Z with 0
+ and Z
+ */
+ switch (*end) {
+ case 0:
+ *to--= '0';
+ *to= '\\';
+ break;
+ case '\032':
+ *to--= 'Z';
+ *to= '\\';
+ break;
+ case '\'':
+ case '\\':
+ *to--= *end;
+ *to= '\\';
+ break;
+ default:
+ *to= *end;
+ break;
+ }
+ }
+ *to= '\'';
+ str->length(new_length);
+ return str;
+
+null:
+ null_value= 1;
+ return 0;
+}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index a955c0ed4f3..fc98ebfe67d 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -35,8 +35,10 @@ public:
double val();
enum Item_result result_type () const { return STRING_RESULT; }
void left_right_max_length();
+ unsigned int size_of() { return sizeof(*this);}
};
+
class Item_func_md5 :public Item_str_func
{
String tmp_value;
@@ -45,8 +47,38 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "md5"; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
+class Item_func_sha :public Item_str_func
+{
+public:
+ Item_func_sha(Item *a) :Item_str_func(a) {}
+ String *val_str(String *);
+ void fix_length_and_dec();
+ const char *func_name() const { return "sha"; }
+};
+
+class Item_func_aes_encrypt :public Item_str_func
+{
+public:
+ Item_func_aes_encrypt(Item *a, Item *b) :Item_str_func(a,b) {}
+ String *val_str(String *);
+ void fix_length_and_dec();
+ const char *func_name() const { return "aes_encrypt"; }
};
+class Item_func_aes_decrypt :public Item_str_func
+{
+public:
+ Item_func_aes_decrypt(Item *a, Item *b) :Item_str_func(a,b) {}
+ String *val_str(String *);
+ void fix_length_and_dec();
+ const char *func_name() const { return "aes_decrypt"; }
+};
+
+
class Item_func_concat :public Item_str_func
{
String tmp_value;
@@ -56,6 +88,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "concat"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_concat_ws :public Item_str_func
@@ -97,6 +130,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "replace"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -109,6 +143,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "insert"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -155,6 +190,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "right"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -167,6 +203,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "substr"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -178,6 +215,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "substr_index"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -189,6 +227,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "ltrim"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -200,6 +239,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "rtrim"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_trim :public Item_str_func
@@ -210,6 +250,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "trim"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -221,6 +262,32 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length = 16; }
const char *func_name() const { return "password"; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+class Item_func_des_encrypt :public Item_str_func
+{
+ String tmp_value;
+public:
+ Item_func_des_encrypt(Item *a) :Item_str_func(a) {}
+ Item_func_des_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
+ String *val_str(String *);
+ void fix_length_and_dec()
+ { maybe_null=1; max_length = args[0]->max_length+8; }
+ const char *func_name() const { return "des_encrypt"; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+class Item_func_des_decrypt :public Item_str_func
+{
+ String tmp_value;
+public:
+ Item_func_des_decrypt(Item *a) :Item_str_func(a) {}
+ Item_func_des_decrypt(Item *a, Item *b): Item_str_func(a,b) {}
+ String *val_str(String *);
+ void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; }
+ const char *func_name() const { return "des_decrypt"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_encrypt :public Item_str_func
@@ -231,6 +298,7 @@ public:
Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
String *val_str(String *);
void fix_length_and_dec() { maybe_null=1; max_length = 13; }
+ unsigned int size_of() { return sizeof(*this);}
};
#include "sql_crypt.h"
@@ -244,6 +312,7 @@ public:
Item_str_func(a),sql_crypt(seed) {}
String *val_str(String *);
void fix_length_and_dec();
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_decode :public Item_func_encode
@@ -275,11 +344,13 @@ public:
class Item_func_soundex :public Item_str_func
{
+ String tmp_value;
public:
Item_func_soundex(Item *a) :Item_str_func(a) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "soundex"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -301,6 +372,7 @@ public:
void fix_length_and_dec();
void update_used_tables();
const char *func_name() const { return "elt"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -321,6 +393,7 @@ public:
void fix_length_and_dec();
void update_used_tables();
const char *func_name() const { return "make_set"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -335,6 +408,7 @@ public:
max_length=args[0]->max_length+(args[0]->max_length-args[0]->decimals)/3;
}
const char *func_name() const { return "format"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -356,30 +430,33 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "repeat"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_rpad :public Item_str_func
{
- String tmp_value;
+ String tmp_value, rpad_str;
public:
Item_func_rpad(Item *arg1,Item *arg2,Item *arg3)
:Item_str_func(arg1,arg2,arg3) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "rpad"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_lpad :public Item_str_func
{
- String tmp_value;
+ String tmp_value, lpad_str;
public:
Item_func_lpad(Item *arg1,Item *arg2,Item *arg3)
:Item_str_func(arg1,arg2,arg3) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "lpad"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -392,6 +469,19 @@ public:
void fix_length_and_dec() { decimals=0; max_length=64; }
};
+
+class Item_func_hex :public Item_str_func
+{
+ String tmp_value;
+public:
+ Item_func_hex(Item *a) :Item_str_func(a) {}
+ const char *func_name() const { return "hex"; }
+ String *val_str(String *);
+ void fix_length_and_dec() { decimals=0; max_length=args[0]->max_length*2; }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
class Item_func_binary :public Item_str_func
{
public:
@@ -417,6 +507,7 @@ public:
const char *func_name() const { return "load_file"; }
void fix_length_and_dec()
{ binary=1; maybe_null=1; max_length=MAX_BLOB_WIDTH;}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -441,3 +532,12 @@ public:
const char *func_name() const { return "inet_ntoa"; }
void fix_length_and_dec() { decimals = 0; max_length=3*8+7; }
};
+
+class Item_func_quote :public Item_str_func
+{
+public:
+ Item_func_quote(Item *a) :Item_str_func(a) {}
+ const char *func_name() const { return "quote"; }
+ String *val_str(String *);
+ void fix_length_and_dec() { max_length= args[0]->max_length * 2 + 2; }
+};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 5b24a1eda90..4121fa65433 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000-2003 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -30,7 +30,7 @@ Item_sum::Item_sum(List<Item> &list)
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
{
uint i=0;
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
while ((item=li++))
@@ -46,12 +46,18 @@ Item_sum::Item_sum(List<Item> &list)
void Item_sum::make_field(Send_field *tmp_field)
{
if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
+ {
((Item_field*) args[0])->field->make_field(tmp_field);
+ if (maybe_null)
+ tmp_field->flags&= ~NOT_NULL_FLAG;
+ }
else
{
tmp_field->flags=0;
if (!maybe_null)
tmp_field->flags|= NOT_NULL_FLAG;
+ if (unsigned_flag)
+ tmp_field->flags |= UNSIGNED_FLAG;
tmp_field->length=max_length;
tmp_field->decimals=decimals;
tmp_field->type=(result_type() == INT_RESULT ? FIELD_TYPE_LONG :
@@ -98,12 +104,13 @@ Item_sum_num::val_str(String *str)
String *
Item_sum_int::val_str(String *str)
{
- longlong nr=val_int();
+ longlong nr= val_int();
if (null_value)
return 0;
- char buff[21];
- uint length= (uint) (longlong10_to_str(nr,buff,-10)-buff);
- str->copy(buff,length);
+ if (unsigned_flag)
+ str->set((ulonglong) nr);
+ else
+ str->set(nr);
return str;
}
@@ -150,14 +157,16 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
return 1;
hybrid_type=item->result_type();
if (hybrid_type == INT_RESULT)
- max_length=21;
+ max_length=20;
else if (hybrid_type == REAL_RESULT)
max_length=float_length(decimals);
else
max_length=item->max_length;
decimals=item->decimals;
- maybe_null=item->maybe_null;
+ /* MIN/MAX can return NULL for empty set indepedent of the used column */
+ maybe_null= 1;
binary=item->binary;
+ unsigned_flag=item->unsigned_flag;
result_field=0;
null_value=1;
fix_length_and_dec();
@@ -172,12 +181,14 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
void Item_sum_sum::reset()
{
- null_value=0; sum=0.0; Item_sum_sum::add();
+ null_value=1; sum=0.0; Item_sum_sum::add();
}
bool Item_sum_sum::add()
{
sum+=args[0]->val();
+ if (!args[0]->null_value)
+ null_value= 0;
return 0;
}
@@ -295,15 +306,15 @@ void Item_sum_std::reset_field()
}
}
-void Item_sum_std::update_field(int offset)
+void Item_sum_std::update_field()
{
double nr,old_nr,old_sqr;
longlong field_count;
char *res=result_field->ptr;
- float8get(old_nr,res+offset);
- float8get(old_sqr,res+offset+sizeof(double));
- field_count=sint8korr(res+offset+sizeof(double)*2);
+ float8get(old_nr, res);
+ float8get(old_sqr, res+sizeof(double));
+ field_count=sint8korr(res+sizeof(double)*2);
nr=args[0]->val();
if (!args[0]->null_value)
@@ -323,12 +334,27 @@ double Item_sum_hybrid::val()
{
if (null_value)
return 0.0;
- if (hybrid_type == STRING_RESULT)
- {
+ switch (hybrid_type) {
+ case STRING_RESULT:
String *res; res=val_str(&str_value);
return res ? atof(res->c_ptr()) : 0.0;
+ case INT_RESULT:
+ if (unsigned_flag)
+ return ulonglong2double(sum_int);
+ return (double) sum_int;
+ case REAL_RESULT:
+ return sum;
}
- return sum;
+ return 0; // Keep compiler happy
+}
+
+longlong Item_sum_hybrid::val_int()
+{
+ if (null_value)
+ return 0;
+ if (hybrid_type == INT_RESULT)
+ return sum_int;
+ return (longlong) Item_sum_hybrid::val();
}
@@ -337,25 +363,26 @@ Item_sum_hybrid::val_str(String *str)
{
if (null_value)
return 0;
- if (hybrid_type == STRING_RESULT)
+ switch (hybrid_type) {
+ case STRING_RESULT:
return &value;
- str->set(sum,decimals);
- return str;
+ case REAL_RESULT:
+ str->set(sum,decimals);
+ break;
+ case INT_RESULT:
+ if (unsigned_flag)
+ str->set((ulonglong) sum_int);
+ else
+ str->set((longlong) sum_int);
+ break;
+ }
+ return str; // Keep compiler happy
}
-
bool Item_sum_min::add()
{
- if (hybrid_type != STRING_RESULT)
- {
- double nr=args[0]->val();
- if (!args[0]->null_value && (null_value || nr < sum))
- {
- sum=nr;
- null_value=0;
- }
- }
- else
+ switch (hybrid_type) {
+ case STRING_RESULT:
{
String *result=args[0]->val_str(&tmp_value);
if (!args[0]->null_value &&
@@ -366,22 +393,39 @@ bool Item_sum_min::add()
null_value=0;
}
}
- return 0;
-}
-
-
-bool Item_sum_max::add()
-{
- if (hybrid_type != STRING_RESULT)
+ break;
+ case INT_RESULT:
+ {
+ longlong nr=args[0]->val_int();
+ if (!args[0]->null_value && (null_value ||
+ (unsigned_flag &&
+ (ulonglong) nr < (ulonglong) sum_int) ||
+ (!unsigned_flag && nr < sum_int)))
+ {
+ sum_int=nr;
+ null_value=0;
+ }
+ }
+ break;
+ case REAL_RESULT:
{
double nr=args[0]->val();
- if (!args[0]->null_value && (null_value || nr > sum))
+ if (!args[0]->null_value && (null_value || nr < sum))
{
sum=nr;
null_value=0;
}
}
- else
+ break;
+ }
+ return 0;
+}
+
+
+bool Item_sum_max::add()
+{
+ switch (hybrid_type) {
+ case STRING_RESULT:
{
String *result=args[0]->val_str(&tmp_value);
if (!args[0]->null_value &&
@@ -392,6 +436,31 @@ bool Item_sum_max::add()
null_value=0;
}
}
+ break;
+ case INT_RESULT:
+ {
+ longlong nr=args[0]->val_int();
+ if (!args[0]->null_value && (null_value ||
+ (unsigned_flag &&
+ (ulonglong) nr > (ulonglong) sum_int) ||
+ (!unsigned_flag && nr > sum_int)))
+ {
+ sum_int=nr;
+ null_value=0;
+ }
+ }
+ break;
+ case REAL_RESULT:
+ {
+ double nr=args[0]->val();
+ if (!args[0]->null_value && (null_value || nr > sum))
+ {
+ sum=nr;
+ null_value=0;
+ }
+ }
+ break;
+ }
return 0;
}
@@ -505,8 +574,10 @@ void Item_sum_sum::reset_field()
{
double nr=args[0]->val(); // Nulls also return 0
float8store(result_field->ptr,nr);
- null_value=0;
- result_field->set_notnull();
+ if (args[0]->null_value)
+ result_field->set_null();
+ else
+ result_field->set_notnull();
}
@@ -545,34 +616,44 @@ void Item_sum_avg::reset_field()
void Item_sum_bit::reset_field()
{
+ reset();
+ int8store(result_field->ptr, bits);
+}
+
+void Item_sum_bit::update_field()
+{
char *res=result_field->ptr;
- ulonglong nr=(ulonglong) args[0]->val_int();
- int8store(res,nr);
+ bits= uint8korr(res);
+ add();
+ int8store(res, bits);
}
/*
** calc next value and merge it with field_value
*/
-void Item_sum_sum::update_field(int offset)
+void Item_sum_sum::update_field()
{
double old_nr,nr;
char *res=result_field->ptr;
- float8get(old_nr,res+offset);
+ float8get(old_nr,res);
nr=args[0]->val();
if (!args[0]->null_value)
+ {
old_nr+=nr;
+ result_field->set_notnull();
+ }
float8store(res,old_nr);
}
-void Item_sum_count::update_field(int offset)
+void Item_sum_count::update_field()
{
longlong nr;
char *res=result_field->ptr;
- nr=sint8korr(res+offset);
+ nr=sint8korr(res);
if (!args[0]->maybe_null)
nr++;
else
@@ -585,14 +666,14 @@ void Item_sum_count::update_field(int offset)
}
-void Item_sum_avg::update_field(int offset)
+void Item_sum_avg::update_field()
{
double nr,old_nr;
longlong field_count;
char *res=result_field->ptr;
- float8get(old_nr,res+offset);
- field_count=sint8korr(res+offset+sizeof(double));
+ float8get(old_nr,res);
+ field_count=sint8korr(res+sizeof(double));
nr=args[0]->val();
if (!args[0]->null_value)
@@ -605,111 +686,84 @@ void Item_sum_avg::update_field(int offset)
int8store(res,field_count);
}
-void Item_sum_hybrid::update_field(int offset)
+void Item_sum_hybrid::update_field()
{
if (hybrid_type == STRING_RESULT)
- min_max_update_str_field(offset);
+ min_max_update_str_field();
else if (hybrid_type == INT_RESULT)
- min_max_update_int_field(offset);
+ min_max_update_int_field();
else
- min_max_update_real_field(offset);
+ min_max_update_real_field();
}
void
-Item_sum_hybrid::min_max_update_str_field(int offset)
+Item_sum_hybrid::min_max_update_str_field()
{
String *res_str=args[0]->val_str(&value);
- if (args[0]->null_value)
- result_field->copy_from_tmp(offset); // Use old value
- else
+ if (!args[0]->null_value)
{
res_str->strip_sp();
- result_field->ptr+=offset; // Get old max/min
result_field->val_str(&tmp_value,&tmp_value);
- result_field->ptr-=offset;
if (result_field->is_null() ||
(cmp_sign * (binary ? stringcmp(res_str,&tmp_value) :
sortcmp(res_str,&tmp_value)) < 0))
result_field->store(res_str->ptr(),res_str->length());
- else
- { // Use old value
- char *res=result_field->ptr;
- memcpy(res,res+offset,result_field->pack_length());
- }
result_field->set_notnull();
}
}
void
-Item_sum_hybrid::min_max_update_real_field(int offset)
+Item_sum_hybrid::min_max_update_real_field()
{
double nr,old_nr;
- result_field->ptr+=offset;
old_nr=result_field->val_real();
nr=args[0]->val();
if (!args[0]->null_value)
{
- if (result_field->is_null(offset) ||
+ if (result_field->is_null(0) ||
(cmp_sign > 0 ? old_nr > nr : old_nr < nr))
old_nr=nr;
result_field->set_notnull();
}
- else if (result_field->is_null(offset))
+ else if (result_field->is_null(0))
result_field->set_null();
- result_field->ptr-=offset;
result_field->store(old_nr);
}
void
-Item_sum_hybrid::min_max_update_int_field(int offset)
+Item_sum_hybrid::min_max_update_int_field()
{
longlong nr,old_nr;
- result_field->ptr+=offset;
old_nr=result_field->val_int();
nr=args[0]->val_int();
if (!args[0]->null_value)
{
- if (result_field->is_null(offset) ||
- (cmp_sign > 0 ? old_nr > nr : old_nr < nr))
+ if (result_field->is_null(0))
old_nr=nr;
+ else
+ {
+ bool res=(unsigned_flag ?
+ (ulonglong) old_nr > (ulonglong) nr :
+ old_nr > nr);
+ /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */
+ if ((cmp_sign > 0) ^ (!res))
+ old_nr=nr;
+ }
result_field->set_notnull();
}
- else if (result_field->is_null(offset))
+ else if (result_field->is_null(0))
result_field->set_null();
- result_field->ptr-=offset;
result_field->store(old_nr);
}
-void Item_sum_or::update_field(int offset)
-{
- ulonglong nr;
- char *res=result_field->ptr;
-
- nr=uint8korr(res+offset);
- nr|= (ulonglong) args[0]->val_int();
- int8store(res,nr);
-}
-
-
-void Item_sum_and::update_field(int offset)
-{
- ulonglong nr;
- char *res=result_field->ptr;
-
- nr=uint8korr(res+offset);
- nr&= (ulonglong) args[0]->val_int();
- int8store(res,nr);
-}
-
-
Item_avg_field::Item_avg_field(Item_sum_avg *item)
{
name=item->name;
@@ -719,6 +773,7 @@ Item_avg_field::Item_avg_field(Item_sum_avg *item)
maybe_null=1;
}
+
double Item_avg_field::val()
{
double nr;
@@ -788,14 +843,76 @@ String *Item_std_field::val_str(String *str)
#include "sql_select.h"
+static int simple_raw_key_cmp(void* arg, byte* key1, byte* key2)
+{
+ return memcmp(key1, key2, *(uint*) arg);
+}
+
+static int simple_str_key_cmp(void* arg, byte* key1, byte* key2)
+{
+ return my_sortcmp((char*) key1, (char*) key2, *(uint*) arg);
+}
+
+/*
+ Did not make this one static - at least gcc gets confused when
+ I try to declare a static function as a friend. If you can figure
+ out the syntax to make a static function a friend, make this one
+ static
+*/
+
+int composite_key_cmp(void* arg, byte* key1, byte* key2)
+{
+ Item_sum_count_distinct* item = (Item_sum_count_distinct*)arg;
+ Field **field = item->table->field;
+ Field **field_end= field + item->table->fields;
+ uint32 *lengths=item->field_lengths;
+ for (; field < field_end; ++field)
+ {
+ Field* f = *field;
+ int len = *lengths++;
+ int res = f->key_cmp(key1, key2);
+ if (res)
+ return res;
+ key1 += len;
+ key2 += len;
+ }
+ return 0;
+}
+
+/*
+ helper function for walking the tree when we dump it to MyISAM -
+ tree_walk will call it for each leaf
+*/
+
+int dump_leaf(byte* key, uint32 count __attribute__((unused)),
+ Item_sum_count_distinct* item)
+{
+ byte* buf = item->table->record[0];
+ int error;
+ /*
+ The first item->rec_offset bytes are taken care of with
+ restore_record(table,2) in setup()
+ */
+ memcpy(buf + item->rec_offset, key, item->tree.size_of_element);
+ if ((error = item->table->file->write_row(buf)))
+ {
+ if (error != HA_ERR_FOUND_DUPP_KEY &&
+ error != HA_ERR_FOUND_DUPP_UNIQUE)
+ return 1;
+ }
+ return 0;
+}
+
+
Item_sum_count_distinct::~Item_sum_count_distinct()
{
if (table)
free_tmp_table(current_thd, table);
delete tmp_table_param;
+ if (use_tree)
+ delete_tree(&tree);
}
-
bool Item_sum_count_distinct::fix_fields(THD *thd,TABLE_LIST *tables)
{
if (Item_sum_num::fix_fields(thd,tables) ||
@@ -829,22 +946,126 @@ bool Item_sum_count_distinct::setup(THD *thd)
tmp_table_param->cleanup();
}
if (!(table=create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
- 0, 0, current_lex->options | thd->options)))
+ 0, 0,
+ current_lex->select->options | thd->options)))
return 1;
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
+ table->no_rows=1;
+
+
+ // no blobs, otherwise it would be MyISAM
+ if (table->db_type == DB_TYPE_HEAP)
+ {
+ qsort_cmp2 compare_key;
+ void* cmp_arg;
+
+ // to make things easier for dump_leaf if we ever have to dump to MyISAM
+ restore_record(table,2);
+
+ if (table->fields == 1)
+ {
+ /*
+ If we have only one field, which is the most common use of
+ count(distinct), it is much faster to use a simpler key
+ compare method that can take advantage of not having to worry
+ about other fields
+ */
+ Field* field = table->field[0];
+ switch(field->type())
+ {
+ /*
+ If we have a string, we must take care of charsets and case
+ sensitivity
+ */
+ case FIELD_TYPE_STRING:
+ case FIELD_TYPE_VAR_STRING:
+ compare_key = (qsort_cmp2)(field->binary() ? simple_raw_key_cmp:
+ simple_str_key_cmp);
+ break;
+ default:
+ /*
+ Since at this point we cannot have blobs anything else can
+ be compared with memcmp
+ */
+ compare_key = (qsort_cmp2)simple_raw_key_cmp;
+ break;
+ }
+ key_length = field->pack_length();
+ cmp_arg = (void*) &key_length;
+ rec_offset = 1;
+ }
+ else // too bad, cannot cheat - there is more than one field
+ {
+ bool all_binary = 1;
+ Field** field, **field_end;
+ field_end = (field = table->field) + table->fields;
+ uint32 *lengths;
+ if (!(field_lengths=
+ (uint32*) thd->alloc(sizeof(uint32) * table->fields)))
+ return 1;
+
+ for (key_length = 0, lengths=field_lengths; field < field_end; ++field)
+ {
+ uint32 length= (*field)->pack_length();
+ key_length += length;
+ *lengths++ = length;
+ if (!(*field)->binary())
+ all_binary = 0; // Can't break loop here
+ }
+ rec_offset = table->reclength - key_length;
+ if (all_binary)
+ {
+ compare_key = (qsort_cmp2)simple_raw_key_cmp;
+ cmp_arg = (void*) &key_length;
+ }
+ else
+ {
+ compare_key = (qsort_cmp2) composite_key_cmp ;
+ cmp_arg = (void*) this;
+ }
+ }
+
+ init_tree(&tree, min(thd->variables.max_heap_table_size,
+ thd->variables.sortbuff_size/16), 0,
+ key_length, compare_key, 0, NULL, cmp_arg);
+ use_tree = 1;
+
+ /*
+ The only time key_length could be 0 is if someone does
+ count(distinct) on a char(0) field - stupid thing to do,
+ but this has to be handled - otherwise someone can crash
+ the server with a DoS attack
+ */
+ max_elements_in_tree = ((key_length) ?
+ thd->variables.max_heap_table_size/key_length : 1);
+ }
return 0;
}
+int Item_sum_count_distinct::tree_to_myisam()
+{
+ if (create_myisam_from_heap(current_thd, table, tmp_table_param,
+ HA_ERR_RECORD_FILE_FULL, 1) ||
+ tree_walk(&tree, (tree_walk_action)&dump_leaf, (void*)this,
+ left_root_right))
+ return 1;
+ delete_tree(&tree);
+ use_tree = 0;
+ return 0;
+}
+
void Item_sum_count_distinct::reset()
{
- if (table)
+ if (use_tree)
+ reset_tree(&tree);
+ else if (table)
{
table->file->extra(HA_EXTRA_NO_CACHE);
table->file->delete_all_rows();
table->file->extra(HA_EXTRA_WRITE_CACHE);
- (void) add();
}
+ (void) add();
}
bool Item_sum_count_distinct::add()
@@ -853,18 +1074,33 @@ bool Item_sum_count_distinct::add()
if (always_null)
return 0;
copy_fields(tmp_table_param);
- copy_funcs(tmp_table_param->funcs);
+ copy_funcs(tmp_table_param->items_to_copy);
for (Field **field=table->field ; *field ; field++)
if ((*field)->is_real_null(0))
return 0; // Don't count NULL
- if ((error=table->file->write_row(table->record[0])))
+ if (use_tree)
+ {
+ /*
+ If the tree got too big, convert to MyISAM, otherwise insert into the
+ tree.
+ */
+ if (tree.elements_in_tree > max_elements_in_tree)
+ {
+ if (tree_to_myisam())
+ return 1;
+ }
+ else if (!tree_insert(&tree, table->record[0] + rec_offset, 0))
+ return 1;
+ }
+ else if ((error=table->file->write_row(table->record[0])))
{
if (error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE)
{
- if (create_myisam_from_heap(table, tmp_table_param, error,1))
+ if (create_myisam_from_heap(current_thd, table, tmp_table_param, error,
+ 1))
return 1; // Not a table_is_full error
}
}
@@ -875,6 +1111,8 @@ longlong Item_sum_count_distinct::val_int()
{
if (!table) // Empty query
return LL(0);
+ if (use_tree)
+ return tree.elements_in_tree;
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
return table->file->records;
}
@@ -897,7 +1135,7 @@ void Item_udf_sum::reset()
bool Item_udf_sum::add()
{
- DBUG_ENTER("Item_udf_sum::reset");
+ DBUG_ENTER("Item_udf_sum::add");
udf.add(&null_value);
DBUG_RETURN(0);
}
@@ -915,8 +1153,7 @@ String *Item_sum_udf_float::val_str(String *str)
double nr=val();
if (null_value)
return 0; /* purecov: inspected */
- else
- str->set(nr,decimals);
+ str->set(nr,decimals);
return str;
}
@@ -934,8 +1171,7 @@ String *Item_sum_udf_int::val_str(String *str)
longlong nr=val_int();
if (null_value)
return 0;
- else
- str->set(nr);
+ str->set(nr);
return str;
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index f68dfee1b61..d3a328be032 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,6 +21,8 @@
#pragma interface /* gcc class implementation */
#endif
+#include <my_tree.h>
+
class Item_sum :public Item_result_field
{
public:
@@ -53,8 +55,19 @@ public:
virtual enum Sumfunctype sum_func () const=0;
virtual void reset()=0;
virtual bool add()=0;
+ /*
+ Called when new group is started and results are being saved in
+ a temporary table. Similar to reset(), but must also store value in
+ result_field. Like reset() it is supposed to reset start value to
+ default.
+ */
virtual void reset_field()=0;
- virtual void update_field(int offset)=0;
+ /*
+ Called for each new value in the group, when temporary table is in use.
+ Similar to add(), but uses temporary table field to obtain current value,
+ Updated value is then saved in the field.
+ */
+ virtual void update_field()=0;
virtual bool keep_field_type(void) const { return 0; }
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
virtual const char *func_name() const { return "?"; }
@@ -62,11 +75,14 @@ public:
{ return new Item_field(field);}
table_map used_tables() const { return ~(table_map) 0; } /* Not used */
bool const_item() const { return 0; }
+ bool is_null() { return null_value; }
void update_used_tables() { }
void make_field(Send_field *field);
void print(String *str);
void fix_num_length_and_dec();
+ void no_rows_in_result() { reset(); }
virtual bool setup(THD *thd) {return 0;}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -81,20 +97,21 @@ public:
longlong val_int() { return (longlong) val(); } /* Real as default */
String *val_str(String*str);
void reset_field();
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_int :public Item_sum_num
{
- void fix_length_and_dec()
- { decimals=0; max_length=21; maybe_null=null_value=0; }
-
public:
Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
double val() { return (double) val_int(); }
String *val_str(String*str);
enum Item_result result_type () const { return INT_RESULT; }
+ unsigned int size_of() { return sizeof(*this);}
+ void fix_length_and_dec()
+ { decimals=0; max_length=21; maybe_null=null_value=0; }
};
@@ -110,8 +127,10 @@ class Item_sum_sum :public Item_sum_num
bool add();
double val();
void reset_field();
- void update_field(int offset);
+ void update_field();
+ void no_rows_in_result() {}
const char *func_name() const { return "sum"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -128,12 +147,14 @@ class Item_sum_count :public Item_sum_int
bool const_item() const { return !used_table_cache; }
enum Sumfunctype sum_func () const { return COUNT_FUNC; }
void reset();
+ void no_rows_in_result() { count=0; }
bool add();
void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; }
longlong val_int();
void reset_field();
- void update_field(int offset);
+ void update_field();
const char *func_name() const { return "count"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -144,24 +165,50 @@ class Item_sum_count_distinct :public Item_sum_int
TABLE *table;
table_map used_table_cache;
bool fix_fields(THD *thd,TABLE_LIST *tables);
+ uint32 *field_lengths;
TMP_TABLE_PARAM *tmp_table_param;
- bool always_null;
+ TREE tree;
+ uint key_length;
+
+ // calculated based on max_heap_table_size. If reached,
+ // walk the tree and dump it into MyISAM table
+ uint max_elements_in_tree;
+
+ // the first few bytes of record ( at least one)
+ // are just markers for deleted and NULLs. We want to skip them since
+ // they will just bloat the tree without providing any valuable info
+ int rec_offset;
+
+ // If there are no blobs, we can use a tree, which
+ // is faster than heap table. In that case, we still use the table
+ // to help get things set up, but we insert nothing in it
+ bool use_tree;
+ bool always_null; // Set to 1 if the result is always NULL
+
+ int tree_to_myisam();
+
+ friend int composite_key_cmp(void* arg, byte* key1, byte* key2);
+ friend int dump_leaf(byte* key, uint32 count __attribute__((unused)),
+ Item_sum_count_distinct* item);
public:
Item_sum_count_distinct(List<Item> &list)
:Item_sum_int(list),table(0),used_table_cache(~(table_map) 0),
- tmp_table_param(0),always_null(0)
+ tmp_table_param(0),use_tree(0),always_null(0)
{ quick_group=0; }
~Item_sum_count_distinct();
+
table_map used_tables() const { return used_table_cache; }
enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
void reset();
bool add();
longlong val_int();
void reset_field() { return ;} // Never called
- void update_field(int offset) { return ; } // Never called
+ void update_field() { return ; } // Never called
const char *func_name() const { return "count_distinct"; }
bool setup(THD *thd);
+ void no_rows_in_result() {}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -177,9 +224,11 @@ public:
enum Type type() const { return FIELD_AVG_ITEM; }
double val();
longlong val_int() { return (longlong) val(); }
+ bool is_null() { (void) val_int(); return null_value; }
String *val_str(String*);
void make_field(Send_field *field);
void fix_length_and_dec() {}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -197,10 +246,11 @@ class Item_sum_avg :public Item_sum_num
bool add();
double val();
void reset_field();
- void update_field(int offset);
+ void update_field();
Item *result_item(Field *field)
{ return new Item_avg_field(this); }
const char *func_name() const { return "avg"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_std;
@@ -214,8 +264,10 @@ public:
double val();
longlong val_int() { return (longlong) val(); }
String *val_str(String*);
+ bool is_null() { (void) val_int(); return null_value; }
void make_field(Send_field *field);
void fix_length_and_dec() {}
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_std :public Item_sum_num
@@ -232,10 +284,11 @@ class Item_sum_std :public Item_sum_num
bool add();
double val();
void reset_field();
- void update_field(int offset);
+ void update_field();
Item *result_item(Field *field)
{ return new Item_std_field(this); }
const char *func_name() const { return "std"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -246,6 +299,7 @@ class Item_sum_hybrid :public Item_sum
protected:
String value,tmp_value;
double sum;
+ longlong sum_int;
Item_result hybrid_type;
int cmp_sign;
table_map used_table_cache;
@@ -261,21 +315,23 @@ class Item_sum_hybrid :public Item_sum
void reset()
{
sum=0.0;
+ sum_int=0;
value.length(0);
null_value=1;
add();
}
double val();
- longlong val_int() { return (longlong) val(); } /* Real as default */
+ longlong val_int();
void reset_field();
String *val_str(String *);
void make_const() { used_table_cache=0; }
bool keep_field_type(void) const { return 1; }
enum Item_result result_type () const { return hybrid_type; }
- void update_field(int offset);
- void min_max_update_str_field(int offset);
- void min_max_update_real_field(int offset);
- void min_max_update_int_field(int offset);
+ void update_field();
+ void min_max_update_str_field();
+ void min_max_update_real_field();
+ void min_max_update_int_field();
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -287,6 +343,7 @@ public:
bool add();
const char *func_name() const { return "min"; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -298,41 +355,46 @@ public:
bool add();
const char *func_name() const { return "max"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_bit :public Item_sum_int
{
- protected:
+protected:
ulonglong reset_bits,bits;
- public:
+public:
Item_sum_bit(Item *item_par,ulonglong reset_arg)
:Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
void reset();
longlong val_int();
void reset_field();
+ void update_field();
+ unsigned int size_of() { return sizeof(*this);}
+ void fix_length_and_dec()
+ { decimals=0; max_length=21; unsigned_flag=1; maybe_null=null_value=0; }
};
class Item_sum_or :public Item_sum_bit
{
- public:
+public:
Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
bool add();
- void update_field(int offset);
const char *func_name() const { return "bit_or"; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_and :public Item_sum_bit
{
- public:
- Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {}
+public:
+ Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ULONGLONG_MAX) {}
bool add();
- void update_field(int offset);
const char *func_name() const { return "bit_and"; }
+ unsigned int size_of() { return sizeof(*this);}
};
/*
@@ -362,7 +424,8 @@ public:
void reset();
bool add();
void reset_field() {};
- void update_field(int offset_arg) {};
+ void update_field() {};
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -429,7 +492,7 @@ class Item_sum_udf_float :public Item_sum_num
double val() { return 0.0; }
void reset() {}
bool add() { return 0; }
- void update_field(int offset) {}
+ void update_field() {}
};
@@ -444,7 +507,7 @@ public:
double val() { return 0; }
void reset() {}
bool add() { return 0; }
- void update_field(int offset) {}
+ void update_field() {}
};
@@ -462,7 +525,7 @@ public:
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
void reset() {}
bool add() { return 0; }
- void update_field(int offset) {}
+ void update_field() {}
};
#endif /* HAVE_DLOPEN */
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index eb9b1423c78..f2b4a041b6c 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -175,7 +175,42 @@ longlong Item_func_second::val_int()
}
-// Returns the week of year in the range of 0 - 53
+uint week_mode(uint mode)
+{
+ uint week_format= (mode & 7);
+ if (!(week_format & WEEK_MONDAY_FIRST))
+ week_format^= WEEK_FIRST_WEEKDAY;
+ return week_format;
+}
+
+/*
+ The bits in week_format(for calc_week() function) has the following meaning:
+ WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
+ If set Monday is first day of week
+ WEEK_YEAR (1) If not set Week is in range 0-53
+
+ Week 0 is returned for the the last week of the previous year (for
+ a date at start of january) In this case one can get 53 for the
+ first week of next year. This flag ensures that the week is
+ relevant for the given year. Note that this flag is only
+ releveant if WEEK_JANUARY is not set.
+
+ If set Week is in range 1-53.
+
+ In this case one may get week 53 for a date in January (when
+ the week is that last week of previous year) and week 1 for a
+ date in December.
+
+ WEEK_FIRST_WEEKDAY (2) If not set Weeks are numbered according
+ to ISO 8601:1988
+ If set The week that contains the first
+ 'first-day-of-week' is week 1.
+
+ ISO 8601:1988 means that if the week containing January 1 has
+ four or more days in the new year, then it is week 1;
+ Otherwise it is the last week of the previous year, and the
+ next week is week 1.
+*/
longlong Item_func_week::val_int()
{
@@ -183,7 +218,9 @@ longlong Item_func_week::val_int()
TIME ltime;
if (get_arg0_date(&ltime,0))
return 0;
- return (longlong) calc_week(&ltime, 0, args[1]->val_int() == 0, &year);
+ return (longlong) calc_week(&ltime,
+ week_mode((uint) args[1]->val_int()),
+ &year);
}
@@ -193,7 +230,9 @@ longlong Item_func_yearweek::val_int()
TIME ltime;
if (get_arg0_date(&ltime,0))
return 0;
- week=calc_week(&ltime, 1, args[1]->val_int() == 0, &year);
+ week= calc_week(&ltime,
+ (week_mode((uint) args[1]->val_int()) | WEEK_YEAR),
+ &year);
return week+year*100;
}
@@ -390,7 +429,7 @@ String *Item_date::val_str(String *str)
}
-bool Item_date::save_in_field(Field *field)
+bool Item_date::save_in_field(Field *field, bool no_conversions)
{
TIME ltime;
timestamp_type t_type=TIMESTAMP_FULL;
@@ -505,7 +544,7 @@ bool Item_func_now::get_date(TIME *res,
}
-bool Item_func_now::save_in_field(Field *to)
+bool Item_func_now::save_in_field(Field *to, bool no_conversions)
{
to->set_notnull();
to->store_time(&ltime,TIMESTAMP_FULL);
@@ -672,7 +711,7 @@ String *Item_func_date_format::val_str(String *str)
else
size=format_length(format);
if (format == str)
- str=&value; // Save result here
+ str= &value; // Save result here
if (str->alloc(size))
{
null_value=1;
@@ -683,7 +722,7 @@ String *Item_func_date_format::val_str(String *str)
/* Create the result string */
const char *ptr=format->ptr();
const char *end=ptr+format->length();
- for ( ; ptr != end ; ptr++)
+ for (; ptr != end ; ptr++)
{
if (*ptr != '%' || ptr+1 == end)
str->append(*ptr);
@@ -691,7 +730,7 @@ String *Item_func_date_format::val_str(String *str)
{
switch (*++ptr) {
case 'M':
- if(!l_time.month)
+ if (!l_time.month)
{
null_value=1;
return 0;
@@ -699,7 +738,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(month_names[l_time.month-1]);
break;
case 'b':
- if(!l_time.month)
+ if (!l_time.month)
{
null_value=1;
return 0;
@@ -707,7 +746,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(month_names[l_time.month-1].ptr(),3);
break;
case 'W':
- if(date_or_time)
+ if (date_or_time)
{
null_value=1;
return 0;
@@ -716,7 +755,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(day_names[weekday]);
break;
case 'a':
- if(date_or_time)
+ if (date_or_time)
{
null_value=1;
return 0;
@@ -725,7 +764,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(day_names[weekday].ptr(),3);
break;
case 'D':
- if(date_or_time)
+ if (date_or_time)
{
null_value=1;
return 0;
@@ -791,7 +830,7 @@ String *Item_func_date_format::val_str(String *str)
str->append(intbuff);
break;
case 'j':
- if(date_or_time)
+ if (date_or_time)
{
null_value=1;
return 0;
@@ -831,7 +870,10 @@ String *Item_func_date_format::val_str(String *str)
case 'u':
{
uint year;
- sprintf(intbuff,"%02d",calc_week(&l_time, 0, (*ptr) == 'U', &year));
+ sprintf(intbuff,"%02d",
+ calc_week(&l_time,
+ ((*ptr) == 'U' ?
+ WEEK_FIRST_WEEKDAY : WEEK_MONDAY_FIRST) , &year));
str->append(intbuff);
}
break;
@@ -839,7 +881,11 @@ String *Item_func_date_format::val_str(String *str)
case 'V':
{
uint year;
- sprintf(intbuff,"%02d",calc_week(&l_time, 1, (*ptr) == 'V', &year));
+ sprintf(intbuff,"%02d",
+ calc_week(&l_time,
+ ((*ptr) == 'V' ? WEEK_YEAR | WEEK_FIRST_WEEKDAY :
+ WEEK_YEAR | WEEK_MONDAY_FIRST),
+ &year));
str->append(intbuff);
}
break;
@@ -847,7 +893,10 @@ String *Item_func_date_format::val_str(String *str)
case 'X':
{
uint year;
- (void) calc_week(&l_time, 1, (*ptr) == 'X', &year);
+ (void) calc_week(&l_time,
+ ((*ptr) == 'X' ? WEEK_YEAR | WEEK_FIRST_WEEKDAY :
+ WEEK_YEAR | WEEK_MONDAY_FIRST),
+ &year);
sprintf(intbuff,"%04d",year);
str->append(intbuff);
}
@@ -1045,14 +1094,12 @@ String *Item_date_add_interval::val_str(String *str)
longlong Item_date_add_interval::val_int()
{
TIME ltime;
+ longlong date;
if (Item_date_add_interval::get_date(&ltime,0))
return (longlong) 0;
- return ((longlong) (((ulong) ltime.year)*10000L+
- (((uint) ltime.month)*100+
- (uint) ltime.day))*(longlong) 1000000L+
- (longlong) ((ulong) ((uint) ltime.hour)*10000L+
- (ulong) (((uint)ltime.minute)*100L+
- (uint) ltime.second)));
+ date = (ltime.year*100L + ltime.month)*100L + ltime.day;
+ return ltime.time_type == TIMESTAMP_DATE ? date :
+ ((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second;
}
void Item_extract::fix_length_and_dec()
@@ -1123,3 +1170,29 @@ longlong Item_extract::val_int()
}
return 0; // Impossible
}
+
+bool Item_extract::eq(const Item *item, bool binary_cmp) const
+{
+ if (this == item)
+ return 1;
+ if (item->type() != FUNC_ITEM ||
+ func_name() != ((Item_func*)item)->func_name())
+ return 0;
+
+ Item_extract* ie= (Item_extract*)item;
+ if (ie->int_type != int_type)
+ return 0;
+
+ if (!args[0]->eq(ie->args[0], binary_cmp))
+ return 0;
+ return 1;
+}
+
+void Item_typecast::print(String *str)
+{
+ str->append("CAST(");
+ args[0]->print(str);
+ str->append(" AS ");
+ str->append(func_name());
+ str->append(')');
+}
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 720f8ba2882..e04e24627d9 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -73,6 +73,7 @@ public:
void fix_length_and_dec() { decimals=0; max_length=2; maybe_null=1; }
};
+
class Item_func_monthname :public Item_func_month
{
public:
@@ -175,6 +176,7 @@ public:
const char *func_name() const { return "weekday"; }
enum Item_result result_type () const { return INT_RESULT; }
void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_func_dayname :public Item_func_weekday
@@ -200,6 +202,7 @@ public:
{
decimals=0; max_length=10;
}
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -228,7 +231,35 @@ public:
double val() { return (double) val_int(); }
const char *func_name() const { return "date"; }
void fix_length_and_dec() { decimals=0; max_length=10; }
- bool save_in_field(Field *to);
+ bool save_in_field(Field *to, bool no_conversions);
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_DATE);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ return (!t_arg) ? result_field : new Field_date(maybe_null, name, t_arg);
+ }
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
+class Item_date_func :public Item_str_func
+{
+public:
+ Item_date_func() :Item_str_func() {}
+ Item_date_func(Item *a) :Item_str_func(a) {}
+ Item_date_func(Item *a,Item *b) :Item_str_func(a,b) {}
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_DATETIME);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ return (!t_arg) ? result_field : new Field_datetime(maybe_null, name,
+ t_arg);
+ }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -247,6 +278,15 @@ public:
{ str_value.set(buff,buff_length); return &str_value; }
const char *func_name() const { return "curtime"; }
void fix_length_and_dec();
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_TIME);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ return (!t_arg) ? result_field : new Field_time(maybe_null, name, t_arg);
+ }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -260,27 +300,29 @@ public:
const char *func_name() const { return "curdate"; }
void fix_length_and_dec(); /* Retrieves curtime */
bool get_date(TIME *res,bool fuzzy_date);
+ unsigned int size_of() { return sizeof(*this);}
};
-class Item_func_now :public Item_func
+class Item_func_now :public Item_date_func
{
longlong value;
char buff[20];
uint buff_length;
TIME ltime;
public:
- Item_func_now() :Item_func() {}
- Item_func_now(Item *a) :Item_func(a) {}
+ Item_func_now() :Item_date_func() {}
+ Item_func_now(Item *a) :Item_date_func(a) {}
enum Item_result result_type () const { return STRING_RESULT; }
double val() { return (double) value; }
longlong val_int() { return value; }
- bool save_in_field(Field *to);
+ bool save_in_field(Field *to, bool no_conversions);
String *val_str(String *str)
{ str_value.set(buff,buff_length); return &str_value; }
const char *func_name() const { return "now"; }
void fix_length_and_dec();
bool get_date(TIME *res,bool fuzzy_date);
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -305,19 +347,20 @@ public:
const char *func_name() const { return "date_format"; }
void fix_length_and_dec();
uint format_length(const String *format);
+ unsigned int size_of() { return sizeof(*this);}
};
-class Item_func_from_unixtime :public Item_func
+class Item_func_from_unixtime :public Item_date_func
{
public:
- Item_func_from_unixtime(Item *a) :Item_func(a) {}
+ Item_func_from_unixtime(Item *a) :Item_date_func(a) {}
double val() { return (double) Item_func_from_unixtime::val_int(); }
longlong val_int();
String *val_str(String *str);
const char *func_name() const { return "from_unixtime"; }
void fix_length_and_dec() { decimals=0; max_length=19; }
- enum Item_result result_type () const { return STRING_RESULT; }
+// enum Item_result result_type () const { return STRING_RESULT; }
bool get_date(TIME *res,bool fuzzy_date);
};
@@ -331,8 +374,17 @@ public:
String *val_str(String *);
void fix_length_and_dec() { maybe_null=1; max_length=13; }
const char *func_name() const { return "sec_to_time"; }
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_TIME);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ return (!t_arg) ? result_field : new Field_time(maybe_null, name, t_arg);
+ }
};
+
enum interval_type { INTERVAL_YEAR, INTERVAL_MONTH, INTERVAL_DAY,
INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND,
INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR,
@@ -340,7 +392,7 @@ enum interval_type { INTERVAL_YEAR, INTERVAL_MONTH, INTERVAL_DAY,
INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND,
INTERVAL_MINUTE_SECOND};
-class Item_date_add_interval :public Item_str_func
+class Item_date_add_interval :public Item_date_func
{
const interval_type int_type;
String value;
@@ -348,15 +400,17 @@ class Item_date_add_interval :public Item_str_func
public:
Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg)
- :Item_str_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
+ :Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
String *val_str(String *);
const char *func_name() const { return "date_add_interval"; }
void fix_length_and_dec() { maybe_null=1; max_length=19; value.alloc(32);}
double val() { return (double) val_int(); }
longlong val_int();
bool get_date(TIME *res,bool fuzzy_date);
+ unsigned int size_of() { return sizeof(*this);}
};
+
class Item_extract :public Item_int_func
{
const interval_type int_type;
@@ -368,4 +422,75 @@ class Item_extract :public Item_int_func
longlong val_int();
const char *func_name() const { return "extract"; }
void fix_length_and_dec();
+ bool eq(const Item *item, bool binary_cmp) const;
+ unsigned int size_of() { return sizeof(*this);}
+};
+
+
+class Item_typecast :public Item_str_func
+{
+public:
+ Item_typecast(Item *a) :Item_str_func(a) {}
+ const char *func_name() const { return "char"; }
+ String *val_str(String *a)
+ { a=args[0]->val_str(a); null_value=args[0]->null_value; return a; }
+ void fix_length_and_dec() { max_length=args[0]->max_length; }
+ void print(String *str);
+};
+
+
+class Item_char_typecast :public Item_typecast
+{
+public:
+ Item_char_typecast(Item *a) :Item_typecast(a) {}
+ void fix_length_and_dec() { binary=0; max_length=args[0]->max_length; }
+};
+
+
+class Item_date_typecast :public Item_typecast
+{
+public:
+ Item_date_typecast(Item *a) :Item_typecast(a) {}
+ const char *func_name() const { return "date"; }
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_DATE);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ return (!t_arg) ? result_field : new Field_date(maybe_null, name, t_arg);
+ }
+};
+
+
+class Item_time_typecast :public Item_typecast
+{
+public:
+ Item_time_typecast(Item *a) :Item_typecast(a) {}
+ const char *func_name() const { return "time"; }
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_TIME);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ return (!t_arg) ? result_field : new Field_time(maybe_null, name, t_arg);
+ }
+};
+
+
+class Item_datetime_typecast :public Item_typecast
+{
+public:
+ Item_datetime_typecast(Item *a) :Item_typecast(a) {}
+ const char *func_name() const { return "datetime"; }
+ void make_field(Send_field *tmp_field)
+ {
+ init_make_field(tmp_field,FIELD_TYPE_DATETIME);
+ }
+ Field *tmp_table_field(TABLE *t_arg)
+ {
+ return (!t_arg) ? result_field : new Field_datetime(maybe_null, name,
+ t_arg);
+ }
};
diff --git a/sql/item_uniq.cc b/sql/item_uniq.cc
index 80ed6433fd8..88e0cbbc0e6 100644
--- a/sql/item_uniq.cc
+++ b/sql/item_uniq.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/item_uniq.h b/sql/item_uniq.h
index ff11222e2ee..de239d3a8ec 100644
--- a/sql/item_uniq.h
+++ b/sql/item_uniq.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -29,6 +29,7 @@ public:
:Item_real_func(list) {}
double val() { return 0.0; }
void fix_length_and_dec() { decimals=0; max_length=6; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_sum_unique_users :public Item_sum_num
@@ -41,6 +42,7 @@ public:
void reset() {}
bool add() { return 0; }
void reset_field() {}
- void update_field(int offset) {}
+ void update_field() {}
bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;}
+ unsigned int size_of() { return sizeof(*this);}
};
diff --git a/sql/key.cc b/sql/key.cc
index 9f5379487c3..0a5937fc881 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -96,7 +96,7 @@ void key_copy(byte *key,TABLE *table,uint idx,uint key_length)
length=min(key_length,key_part->length);
set_if_smaller(blob_length,length);
int2store(key,(uint) blob_length);
- key+=2; // Skipp length info
+ key+=2; // Skip length info
memcpy(key,pos,blob_length);
}
else
@@ -182,9 +182,9 @@ int key_cmp(TABLE *table,const byte *key,uint idx,uint key_length)
}
if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH))
{
- if (key_part->field->key_cmp(key, key_part->length+2))
+ if (key_part->field->key_cmp(key, key_part->length+ HA_KEY_BLOB_LENGTH))
return 1;
- length=key_part->length+2;
+ length=key_part->length+HA_KEY_BLOB_LENGTH;
}
else
{
@@ -250,7 +250,7 @@ void key_unpack(String *to,TABLE *table,uint idx)
bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields)
{
- List_iterator<Item> f(fields);
+ List_iterator_fast<Item> f(fields);
KEY_PART_INFO *key_part,*key_part_end;
for (key_part=table->key_info[idx].key_part,key_part_end=key_part+
table->key_info[idx].key_parts ;
@@ -258,7 +258,7 @@ bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields)
key_part++)
{
Item_field *field;
-
+
if (key_part->field == table->timestamp_field)
return 1; // Can't be used for update
@@ -275,7 +275,7 @@ bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields)
key is not updated
*/
if (idx != table->primary_key && table->primary_key < MAX_KEY &&
- (table->file->option_flag() & HA_PRIMARY_KEY_IN_READ_INDEX))
+ (table->file->table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
return check_if_key_used(table, table->primary_key, fields);
return 0;
}
diff --git a/sql/lex.h b/sql/lex.h
index 776e03b811b..10ba11f2169 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -30,9 +30,9 @@
#endif
/*
-** Symbols are broken into separated arrays to allow fieldnames with
-** same name as functions
-** These are kept sorted for human lookup (the symbols are hashed)
+ Symbols are broken into separated arrays to allow field names with
+ same name as functions.
+ These are kept sorted for human lookup (the symbols are hashed).
*/
static SYMBOL symbols[] = {
@@ -61,27 +61,33 @@ static SYMBOL symbols[] = {
{ "AVG", SYM(AVG_SYM),0,0},
{ "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH),0,0},
{ "AUTO_INCREMENT", SYM(AUTO_INC),0,0},
- { "AUTOCOMMIT", SYM(AUTOCOMMIT),0,0},
- { "BACKUP", SYM(BACKUP_SYM),0,0},
- { "BEGIN", SYM(BEGIN_SYM),0,0},
+ { "BACKUP", SYM(BACKUP_SYM),0,0},
+ { "BEGIN", SYM(BEGIN_SYM),0,0},
{ "BERKELEYDB", SYM(BERKELEY_DB_SYM),0,0},
{ "BDB", SYM(BERKELEY_DB_SYM),0,0},
{ "BETWEEN", SYM(BETWEEN_SYM),0,0},
{ "BIGINT", SYM(BIGINT),0,0},
{ "BIT", SYM(BIT_SYM),0,0},
{ "BINARY", SYM(BINARY),0,0},
+ { "BINLOG", SYM(BINLOG_SYM),0,0},
{ "BLOB", SYM(BLOB_SYM),0,0},
{ "BOOL", SYM(BOOL_SYM),0,0},
+ { "BOOLEAN", SYM(BOOLEAN_SYM),0,0},
{ "BOTH", SYM(BOTH),0,0},
{ "BY", SYM(BY),0,0},
+ { "CACHE", SYM(CACHE_SYM),0,0},
{ "CASCADE", SYM(CASCADE),0,0},
{ "CASE", SYM(CASE_SYM),0,0},
{ "CHAR", SYM(CHAR_SYM),0,0},
{ "CHARACTER", SYM(CHAR_SYM),0,0},
+ { "CHARSET", SYM(CHARSET),0,0},
{ "CHANGE", SYM(CHANGE),0,0},
{ "CHANGED", SYM(CHANGED),0,0},
{ "CHECK", SYM(CHECK_SYM),0,0},
{ "CHECKSUM", SYM(CHECKSUM_SYM),0,0},
+ { "CIPHER", SYM(CIPHER_SYM),0,0},
+ { "CLIENT", SYM(CLIENT_SYM),0,0},
+ { "CLOSE", SYM(CLOSE_SYM),0,0},
{ "COLUMN", SYM(COLUMN_SYM),0,0},
{ "COLUMNS", SYM(COLUMNS),0,0},
{ "COMMENT", SYM(COMMENT_SYM),0,0},
@@ -92,6 +98,7 @@ static SYMBOL symbols[] = {
{ "CONSTRAINT", SYM(CONSTRAINT),0,0},
{ "CREATE", SYM(CREATE),0,0},
{ "CROSS", SYM(CROSS),0,0},
+ { "CUBE", SYM(CUBE_SYM),0,0},
{ "CURRENT_DATE", SYM(CURDATE),0,0},
{ "CURRENT_TIME", SYM(CURTIME),0,0},
{ "CURRENT_TIMESTAMP", SYM(NOW_SYM),0,0},
@@ -106,12 +113,15 @@ static SYMBOL symbols[] = {
{ "DAY_SECOND", SYM(DAY_SECOND_SYM),0,0},
{ "DEC", SYM(DECIMAL_SYM),0,0},
{ "DECIMAL", SYM(DECIMAL_SYM),0,0},
+ { "DES_KEY_FILE", SYM(DES_KEY_FILE),0,0},
{ "DEFAULT", SYM(DEFAULT),0,0},
{ "DELAYED", SYM(DELAYED_SYM),0,0},
{ "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0},
{ "DELETE", SYM(DELETE_SYM),0,0},
{ "DESC", SYM(DESC),0,0},
{ "DESCRIBE", SYM(DESCRIBE),0,0},
+ { "DIRECTORY", SYM(DIRECTORY_SYM),0,0},
+ { "DISABLE", SYM(DISABLE_SYM),0,0},
{ "DISTINCT", SYM(DISTINCT),0,0},
{ "DISTINCTROW", SYM(DISTINCT),0,0}, /* Access likes this */
{ "DO", SYM(DO_SYM),0,0},
@@ -121,10 +131,14 @@ static SYMBOL symbols[] = {
{ "DYNAMIC", SYM(DYNAMIC_SYM),0,0},
{ "END", SYM(END),0,0},
{ "ELSE", SYM(ELSE),0,0},
+ { "ENGINE", SYM(TYPE_SYM),0,0}, /* Alias for TYPE= */
{ "ESCAPE", SYM(ESCAPE_SYM),0,0},
{ "ESCAPED", SYM(ESCAPED),0,0},
+ { "ENABLE", SYM(ENABLE_SYM),0,0},
{ "ENCLOSED", SYM(ENCLOSED),0,0},
{ "ENUM", SYM(ENUM),0,0},
+ { "EVENTS", SYM(EVENTS_SYM),0,0},
+ { "EXECUTE", SYM(EXECUTE_SYM),0,0},
{ "EXPLAIN", SYM(DESCRIBE),0,0},
{ "EXISTS", SYM(EXISTS),0,0},
{ "EXTENDED", SYM(EXTENDED_SYM),0,0},
@@ -138,6 +152,7 @@ static SYMBOL symbols[] = {
{ "FLOAT8", SYM(DOUBLE_SYM),0,0},
{ "FLUSH", SYM(FLUSH_SYM),0,0},
{ "FOREIGN", SYM(FOREIGN),0,0},
+ { "FORCE", SYM(FORCE_SYM),0,0},
{ "RAID_TYPE", SYM(RAID_TYPE),0,0},
{ "RAID_CHUNKS", SYM(RAID_CHUNKS),0,0},
{ "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE),0,0},
@@ -147,13 +162,12 @@ static SYMBOL symbols[] = {
{ "FULL", SYM(FULL),0,0},
{ "FULLTEXT", SYM(FULLTEXT_SYM),0,0},
{ "FUNCTION", SYM(UDF_SYM),0,0},
- { "GEMINI", SYM(GEMINI_SYM),0,0},
- { "GEMINI_SPIN_RETRIES", SYM(GEMINI_SPIN_RETRIES),0,0},
{ "GLOBAL", SYM(GLOBAL_SYM),0,0},
{ "GRANT", SYM(GRANT),0,0},
{ "GRANTS", SYM(GRANTS),0,0},
{ "GROUP", SYM(GROUP),0,0},
{ "HAVING", SYM(HAVING),0,0},
+ { "HANDLER", SYM(HANDLER_SYM),0,0},
{ "HEAP", SYM(HEAP_SYM),0,0},
{ "HIGH_PRIORITY", SYM(HIGH_PRIORITY),0,0},
{ "HOUR", SYM(HOUR_SYM),0,0},
@@ -164,12 +178,13 @@ static SYMBOL symbols[] = {
{ "IGNORE", SYM(IGNORE_SYM),0,0},
{ "IN", SYM(IN_SYM),0,0},
{ "INDEX", SYM(INDEX),0,0},
+ { "INDEXES", SYM(INDEXES),0,0},
{ "INFILE", SYM(INFILE),0,0},
{ "INNER", SYM(INNER_SYM),0,0},
{ "INNOBASE", SYM(INNOBASE_SYM),0,0},
{ "INNODB", SYM(INNOBASE_SYM),0,0},
{ "INSERT", SYM(INSERT),0,0},
- { "INSERT_ID", SYM(INSERT_ID),0,0},
+ { "INSERT_METHOD", SYM(INSERT_METHOD),0,0},
{ "INT", SYM(INT_SYM),0,0},
{ "INTEGER", SYM(INT_SYM),0,0},
{ "INTERVAL", SYM(INTERVAL_SYM),0,0},
@@ -179,15 +194,17 @@ static SYMBOL symbols[] = {
{ "INT4", SYM(INT_SYM),0,0},
{ "INT8", SYM(BIGINT),0,0},
{ "INTO", SYM(INTO),0,0},
+ { "IO_THREAD", SYM(IO_THREAD),0,0},
{ "IF", SYM(IF),0,0},
{ "IS", SYM(IS),0,0},
{ "ISOLATION", SYM(ISOLATION),0,0},
{ "ISAM", SYM(ISAM_SYM),0,0},
+ { "ISSUER", SYM(ISSUER_SYM),0,0},
{ "JOIN", SYM(JOIN_SYM),0,0},
{ "KEY", SYM(KEY_SYM),0,0},
{ "KEYS", SYM(KEYS),0,0},
{ "KILL", SYM(KILL_SYM),0,0},
- { "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0},
+ { "LAST", SYM(LAST_SYM),0,0},
{ "LEADING", SYM(LEADING),0,0},
{ "LEFT", SYM(LEFT),0,0},
{ "LEVEL", SYM(LEVEL_SYM),0,0},
@@ -196,6 +213,8 @@ static SYMBOL symbols[] = {
{ "LIMIT", SYM(LIMIT),0,0},
{ "LOAD", SYM(LOAD),0,0},
{ "LOCAL", SYM(LOCAL_SYM),0,0},
+ { "LOCALTIME", SYM(NOW_SYM),0,0},
+ { "LOCALTIMESTAMP", SYM(NOW_SYM),0,0},
{ "LOCK", SYM(LOCK_SYM),0,0},
{ "LOCKS", SYM(LOCKS_SYM),0,0},
{ "LOGS", SYM(LOGS_SYM),0,0},
@@ -210,14 +229,19 @@ static SYMBOL symbols[] = {
{ "MASTER_LOG_POS", SYM(MASTER_LOG_POS_SYM),0,0},
{ "MASTER_PASSWORD", SYM(MASTER_PASSWORD_SYM),0,0},
{ "MASTER_PORT", SYM(MASTER_PORT_SYM),0,0},
+ { "MASTER_SERVER_ID", SYM(MASTER_SERVER_ID_SYM),0,0},
{ "MASTER_USER", SYM(MASTER_USER_SYM),0,0},
{ "MAX_ROWS", SYM(MAX_ROWS),0,0},
+ { "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR), 0,0},
+ { "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR), 0,0},
+ { "MAX_CONNECTIONS_PER_HOUR", SYM(MAX_CONNECTIONS_PER_HOUR), 0,0},
{ "MATCH", SYM(MATCH),0,0},
{ "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0},
{ "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0},
{ "MEDIUMINT", SYM(MEDIUMINT),0,0},
{ "MERGE", SYM(MERGE_SYM),0,0},
{ "MEDIUM", SYM(MEDIUM_SYM),0,0},
+ { "MEMORY", SYM(MEMORY_SYM),0,0},
{ "MIDDLEINT", SYM(MEDIUMINT),0,0}, /* For powerbuilder */
{ "MIN_ROWS", SYM(MIN_ROWS),0,0},
{ "MINUTE", SYM(MINUTE_SYM),0,0},
@@ -229,12 +253,15 @@ static SYMBOL symbols[] = {
{ "MYISAM", SYM(MYISAM_SYM),0,0},
{ "NATURAL", SYM(NATURAL),0,0},
{ "NATIONAL", SYM(NATIONAL_SYM),0,0},
+ { "NEXT", SYM(NEXT_SYM),0,0},
+ { "NEW", SYM(NEW_SYM),0,0},
{ "NCHAR", SYM(NCHAR_SYM),0,0},
- { "NUMERIC", SYM(NUMERIC_SYM),0,0},
{ "NO", SYM(NO_SYM),0,0},
- { "FOREIGN_KEY_CHECKS", SYM(FOREIGN_KEY_CHECKS), 0, 0},
+ { "NONE", SYM(NONE_SYM),0,0},
{ "NOT", SYM(NOT),0,0},
{ "NULL", SYM(NULL_SYM),0,0},
+ { "NUMERIC", SYM(NUMERIC_SYM),0,0},
+ { "OFFSET", SYM(OFFSET_SYM),0,0},
{ "ON", SYM(ON),0,0},
{ "OPEN", SYM(OPEN_SYM),0,0},
{ "OPTIMIZE", SYM(OPTIMIZE),0,0},
@@ -249,24 +276,30 @@ static SYMBOL symbols[] = {
{ "PASSWORD", SYM(PASSWORD),0,0},
{ "PURGE", SYM(PURGE),0,0},
{ "PRECISION", SYM(PRECISION),0,0},
+ { "PREV", SYM(PREV_SYM),0,0},
{ "PRIMARY", SYM(PRIMARY_SYM),0,0},
{ "PROCEDURE", SYM(PROCEDURE),0,0},
{ "PROCESS" , SYM(PROCESS),0,0},
{ "PROCESSLIST", SYM(PROCESSLIST_SYM),0,0},
{ "PRIVILEGES", SYM(PRIVILEGES),0,0},
+ { "QUERY", SYM(QUERY_SYM),0,0},
{ "QUICK", SYM(QUICK),0,0},
{ "RAID0", SYM(RAID_0_SYM),0,0},
{ "READ", SYM(READ_SYM),0,0},
{ "REAL", SYM(REAL),0,0},
{ "REFERENCES", SYM(REFERENCES),0,0},
+ { "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM),0,0},
+ { "RELAY_LOG_POS", SYM(RELAY_LOG_POS_SYM),0,0},
{ "RELOAD", SYM(RELOAD),0,0},
{ "REGEXP", SYM(REGEXP),0,0},
- { "UNIQUE_CHECKS", SYM(UNIQUE_CHECKS), 0, 0},
{ "RENAME", SYM(RENAME),0,0},
{ "REPAIR", SYM(REPAIR),0,0},
{ "REPLACE", SYM(REPLACE),0,0},
+ { "REPLICATION", SYM(REPLICATION),0,0},
{ "REPEATABLE", SYM(REPEATABLE_SYM),0,0},
+ { "REQUIRE", SYM(REQUIRE_SYM),0,0},
{ "RESET", SYM(RESET_SYM),0,0},
+ { "USER_RESOURCES", SYM(RESOURCES),0,0},
{ "RESTORE", SYM(RESTORE_SYM),0,0},
{ "RESTRICT", SYM(RESTRICT),0,0},
{ "RETURNS", SYM(UDF_RETURNS_SYM),0,0},
@@ -274,35 +307,30 @@ static SYMBOL symbols[] = {
{ "RIGHT", SYM(RIGHT),0,0},
{ "RLIKE", SYM(REGEXP),0,0}, /* Like in mSQL2 */
{ "ROLLBACK", SYM(ROLLBACK_SYM),0,0},
+ { "ROLLUP", SYM(ROLLUP_SYM),0,0},
{ "ROW", SYM(ROW_SYM),0,0},
{ "ROWS", SYM(ROWS_SYM),0,0},
+ { "SAVEPOINT", SYM(SAVEPOINT_SYM),0,0},
{ "SECOND", SYM(SECOND_SYM),0,0},
{ "SELECT", SYM(SELECT_SYM),0,0},
{ "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0},
{ "SESSION", SYM(SESSION_SYM),0,0},
{ "SET", SYM(SET),0,0},
+ { "SIGNED", SYM(SIGNED_SYM),0,0},
{ "SHARE", SYM(SHARE_SYM),0,0},
{ "SHOW", SYM(SHOW),0,0},
{ "SHUTDOWN", SYM(SHUTDOWN),0,0},
{ "SLAVE", SYM(SLAVE),0,0},
{ "SMALLINT", SYM(SMALLINT),0,0},
{ "SONAME", SYM(UDF_SONAME_SYM),0,0},
- { "SQL_AUTO_IS_NULL", SYM(SQL_AUTO_IS_NULL),0,0},
{ "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT),0,0},
- { "SQL_BIG_SELECTS", SYM(SQL_BIG_SELECTS),0,0},
- { "SQL_BIG_TABLES", SYM(SQL_BIG_TABLES),0,0},
{ "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0},
- { "SQL_LOG_BIN", SYM(SQL_LOG_BIN),0,0},
- { "SQL_LOG_OFF", SYM(SQL_LOG_OFF),0,0},
- { "SQL_LOG_UPDATE", SYM(SQL_LOG_UPDATE),0,0},
- { "SQL_LOW_PRIORITY_UPDATES", SYM(SQL_LOW_PRIORITY_UPDATES),0,0},
- { "SQL_MAX_JOIN_SIZE",SYM(SQL_MAX_JOIN_SIZE), 0, 0},
- { "SQL_QUOTE_SHOW_CREATE",SYM(SQL_QUOTE_SHOW_CREATE), 0, 0},
- { "SQL_SAFE_UPDATES", SYM(SQL_SAFE_UPDATES),0,0},
- { "SQL_SELECT_LIMIT", SYM(SQL_SELECT_LIMIT),0,0},
- { "SQL_SLAVE_SKIP_COUNTER", SYM(SQL_SLAVE_SKIP_COUNTER),0,0},
+ { "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0},
+ { "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS),0,0},
+ { "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0},
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0},
- { "SQL_WARNINGS", SYM(SQL_WARNINGS),0,0},
+ { "SQL_THREAD", SYM(SQL_THREAD),0,0},
+ { "SSL", SYM(SSL_SYM),0,0},
{ "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0},
{ "START", SYM(START_SYM),0,0},
{ "STARTING", SYM(STARTING),0,0},
@@ -310,6 +338,8 @@ static SYMBOL symbols[] = {
{ "STRING", SYM(STRING_SYM),0,0},
{ "STOP", SYM(STOP_SYM),0,0},
{ "STRIPED", SYM(RAID_STRIPED_SYM),0,0},
+ { "SUBJECT", SYM(SUBJECT_SYM),0,0},
+ { "SUPER", SYM(SUPER_SYM),0,0},
{ "TABLE", SYM(TABLE_SYM),0,0},
{ "TABLES", SYM(TABLES),0,0},
{ "TEMPORARY", SYM(TEMPORARY),0,0},
@@ -332,6 +362,7 @@ static SYMBOL symbols[] = {
{ "UNLOCK", SYM(UNLOCK_SYM),0,0},
{ "UNSIGNED", SYM(UNSIGNED),0,0},
{ "USE", SYM(USE_SYM),0,0},
+ { "USE_FRM", SYM(USE_FRM),0,0},
{ "USING", SYM(USING),0,0},
{ "UPDATE", SYM(UPDATE_SYM),0,0},
{ "USAGE", SYM(USAGE),0,0},
@@ -345,6 +376,8 @@ static SYMBOL symbols[] = {
{ "WRITE", SYM(WRITE_SYM),0,0},
{ "WHEN", SYM(WHEN_SYM),0,0},
{ "WHERE", SYM(WHERE),0,0},
+ { "XOR", SYM(XOR),0,0},
+ { "X509", SYM(X509_SYM),0,0},
{ "YEAR", SYM(YEAR_SYM),0,0},
{ "YEAR_MONTH", SYM(YEAR_MONTH_SYM),0,0},
{ "ZEROFILL", SYM(ZEROFILL),0,0},
@@ -356,6 +389,8 @@ static SYMBOL sql_functions[] = {
{ "ABS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_abs)},
{ "ACOS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_acos)},
{ "ADDDATE", SYM(DATE_ADD_INTERVAL),0,0},
+ { "AES_ENCRYPT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_encrypt)},
+ { "AES_DECRYPT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_decrypt)},
{ "ASCII", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ascii)},
{ "ASIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_asin)},
{ "ATAN", SYM(ATAN),0,0},
@@ -365,7 +400,11 @@ static SYMBOL sql_functions[] = {
{ "BIT_COUNT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_count)},
{ "BIT_OR", SYM(BIT_OR),0,0},
{ "BIT_AND", SYM(BIT_AND),0,0},
+ { "CAST", SYM(CAST_SYM),0,0},
+ { "CEIL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
{ "CEILING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
+ { "CURRENT_USER", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_current_user)},
+ { "BIT_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)},
{ "CHAR_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
{ "CHARACTER_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
{ "COALESCE", SYM(COALESCE),0,0},
@@ -373,6 +412,7 @@ static SYMBOL sql_functions[] = {
{ "CONCAT_WS", SYM(CONCAT_WS),0,0},
{ "CONNECTION_ID", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)},
{ "CONV", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)},
+ { "CONVERT", SYM(CONVERT_SYM),0,0},
{ "COUNT", SYM(COUNT_SYM),0,0},
{ "COS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)},
{ "COT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)},
@@ -387,6 +427,8 @@ static SYMBOL sql_functions[] = {
{ "DAYOFYEAR", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofyear)},
{ "DECODE", SYM(DECODE_SYM),0,0},
{ "DEGREES", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_degrees)},
+ { "DES_ENCRYPT", SYM(DES_ENCRYPT_SYM),0,0},
+ { "DES_DECRYPT", SYM(DES_DECRYPT_SYM),0,0},
{ "ELT", SYM(ELT_FUNC),0,0},
{ "ENCODE", SYM(ENCODE_SYM),0,0},
{ "ENCRYPT", SYM(ENCRYPT),0,0},
@@ -397,6 +439,7 @@ static SYMBOL sql_functions[] = {
{ "FIND_IN_SET", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_find_in_set)},
{ "FLOOR", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_floor)},
{ "FORMAT", SYM(FORMAT_SYM),0,0},
+ { "FOUND_ROWS", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_found_rows)},
{ "FROM_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_from_days)},
{ "FROM_UNIXTIME", SYM(FROM_UNIXTIME),0,0},
{ "GET_LOCK", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_get_lock)},
@@ -408,19 +451,22 @@ static SYMBOL sql_functions[] = {
{ "INET_NTOA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_ntoa)},
{ "INSTR", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_instr)},
{ "ISNULL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)},
+ { "IS_FREE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)},
+ { "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0},
{ "LCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)},
{ "LEAST", SYM(LEAST_SYM),0,0},
{ "LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
+ { "LN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ln)},
{ "LOAD_FILE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_load_file)},
{ "LOCATE", SYM(LOCATE),0,0},
- { "LOG", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log)},
+ { "LOG", SYM(LOG_SYM),0,0},
+ { "LOG2", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log2)},
{ "LOG10", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log10)},
{ "LOWER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)},
{ "LPAD", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_lpad)},
{ "LTRIM", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ltrim)},
- { "MASTER_POS_WAIT", SYM(FUNC_ARG2),0,
- CREATE_FUNC(create_wait_for_master_pos)},
{ "MAKE_SET", SYM(MAKE_SET_SYM),0,0},
+ { "MASTER_POS_WAIT", SYM(MASTER_POS_WAIT),0,0},
{ "MAX", SYM(MAX_SYM),0,0},
{ "MD5", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_md5)},
{ "MID", SYM(SUBSTRING),0,0}, /* unireg function */
@@ -431,6 +477,7 @@ static SYMBOL sql_functions[] = {
{ "NULLIF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_nullif)},
{ "OCTET_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
{ "OCT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_oct)},
+ { "OLD_PASSWORD", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_password)},
{ "ORD", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ord)},
{ "PERIOD_ADD", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_add)},
{ "PERIOD_DIFF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_diff)},
@@ -439,6 +486,7 @@ static SYMBOL sql_functions[] = {
{ "POW", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)},
{ "POWER", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)},
{ "QUARTER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quarter)},
+ { "QUOTE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quote)},
{ "RADIANS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)},
{ "RAND", SYM(RAND),0,0},
{ "RELEASE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)},
@@ -452,6 +500,8 @@ static SYMBOL sql_functions[] = {
{ "SUBDATE", SYM(DATE_SUB_INTERVAL),0,0},
{ "SIGN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sign)},
{ "SIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sin)},
+ { "SHA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)},
+ { "SHA1", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)},
{ "SOUNDEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_soundex)},
{ "SPACE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_space)},
{ "SQRT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sqrt)},
diff --git a/sql/lex_symbol.h b/sql/lex_symbol.h
index a011e27b59e..9fff1751b1b 100644
--- a/sql/lex_symbol.h
+++ b/sql/lex_symbol.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/lock.cc b/sql/lock.cc
index e46e2aac7bc..41a76007289 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,6 +21,46 @@
before getting internal locks. If we do it in the other order, the status
information is not up to date when called from the lock handler.
+ GENERAL DESCRIPTION OF LOCKING
+
+ When not using LOCK TABLES:
+
+ - For each SQL statement mysql_lock_tables() is called for all involved
+ tables.
+ - mysql_lock_tables() will call
+ table_handler->external_lock(thd,locktype) for each table.
+ This is followed by a call to thr_multi_lock() for all tables.
+
+ - When statement is done, we call mysql_unlock_tables().
+ This will call thr_multi_unlock() followed by
+ table_handler->external_lock(thd, F_UNLCK) for each table.
+
+ - Note that mysql_unlock_tables() may be called several times as
+ MySQL in some cases can free some tables earlier than others.
+
+ - The above is true both for normal and temporary tables.
+
+ - Temporary non transactional tables are never passed to thr_multi_lock()
+ and we never call external_lock(thd, F_UNLOCK) on these.
+
+ When using LOCK TABLES:
+
+ - LOCK TABLE will call mysql_lock_tables() for all tables.
+ mysql_lock_tables() will call
+ table_handler->external_lock(thd,locktype) for each table.
+ This is followed by a call to thr_multi_lock() for all tables.
+
+ - For each statement, we will call table_handler->start_stmt(THD)
+ to inform the table handler that we are using the table.
+
+ The tables used can only be tables used in LOCK TABLES or a
+ temporary table.
+
+ - When statement is done, we will call ha_commit_stmt(thd);
+
+ - When calling UNLOCK TABLES we call mysql_unlock_tables() for all
+ tables used in LOCK TABLES
+
TODO:
Change to use my_malloc() ONLY when using LOCK TABLES command or when
we are forced to use mysql_lock_merge.
@@ -28,12 +68,13 @@ TODO:
#include "mysql_priv.h"
#include <hash.h>
+#include <assert.h>
extern HASH open_cache;
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
bool unlock, TABLE **write_locked);
-static int lock_external(TABLE **table,uint count);
+static int lock_external(THD *thd, TABLE **table,uint count);
static int unlock_external(THD *thd, TABLE **table,uint count);
static void print_lock_error(int error);
@@ -55,33 +96,13 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
Wait until the lock is gone
*/
- if (thd->global_read_lock) // This thread had the read locks
+ if (wait_if_global_read_lock(thd, 1))
{
- my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
- write_lock_used->table_name);
my_free((gptr) sql_lock,MYF(0));
sql_lock=0;
break;
}
-
- pthread_mutex_lock(&LOCK_open);
- thd->mysys_var->current_mutex= &LOCK_open;
- thd->mysys_var->current_cond= &COND_refresh;
- thd->proc_info="Waiting for table";
-
- while (global_read_lock && ! thd->killed &&
- thd->version == refresh_version)
- {
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- }
- pthread_mutex_unlock(&LOCK_open);
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- thd->proc_info= 0;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
-
- if (thd->version != refresh_version || thd->killed)
+ if (thd->version != refresh_version)
{
my_free((gptr) sql_lock,MYF(0));
goto retry;
@@ -89,14 +110,14 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
}
thd->proc_info="System lock";
- if (lock_external(tables,count))
+ if (lock_external(thd, tables, count))
{
my_free((gptr) sql_lock,MYF(0));
sql_lock=0;
thd->proc_info=0;
break;
}
- thd->proc_info=0;
+ thd->proc_info="Table lock";
thd->locked=1;
if (thr_multi_lock(sql_lock->locks,sql_lock->lock_count))
{
@@ -115,6 +136,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
thd->locked=0;
break;
}
+ thd->proc_info=0;
/* some table was altered or deleted. reopen tables marked deleted */
mysql_unlock_tables(thd,sql_lock);
@@ -124,6 +146,7 @@ retry:
if (wait_for_tables(thd))
break; // Couldn't open tables
}
+ thd->proc_info=0;
if (thd->killed)
{
my_error(ER_SERVER_SHUTDOWN,MYF(0));
@@ -138,15 +161,15 @@ retry:
}
-static int lock_external(TABLE **tables,uint count)
+static int lock_external(THD *thd, TABLE **tables, uint count)
{
reg1 uint i;
int lock_type,error;
- THD *thd=current_thd;
DBUG_ENTER("lock_external");
for (i=1 ; i <= count ; i++, tables++)
{
+ DBUG_ASSERT((*tables)->reginfo.lock_type >= TL_READ);
lock_type=F_WRLCK; /* Lock exclusive */
if ((*tables)->db_stat & HA_READ_ONLY ||
((*tables)->reginfo.lock_type >= TL_READ &&
@@ -155,7 +178,7 @@ static int lock_external(TABLE **tables,uint count)
if ((error=(*tables)->file->external_lock(thd,lock_type)))
{
- for ( ; i-- ; tables--)
+ for (; i-- ; tables--)
{
(*tables)->file->external_lock(thd, F_UNLCK);
(*tables)->current_lock=F_UNLCK;
@@ -225,7 +248,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
sql_lock->lock_count= found;
}
- /* Then to the same for the external locks */
+ /* Then do the same for the external locks */
/* Move all write locked tables first */
TABLE **table=sql_lock->table;
for (i=found=0 ; i < sql_lock->table_count ; i++)
@@ -290,6 +313,25 @@ void mysql_lock_abort(THD *thd, TABLE *table)
}
+/* Abort one thread / table combination */
+
+void mysql_lock_abort_for_thread(THD *thd, TABLE *table)
+{
+ MYSQL_LOCK *locked;
+ TABLE *write_lock_used;
+ DBUG_ENTER("mysql_lock_abort_for_thread");
+
+ if ((locked = get_lock_data(thd,&table,1,1,&write_lock_used)))
+ {
+ for (uint i=0; i < locked->lock_count; i++)
+ thr_abort_locks_for_thread(locked->locks[i]->lock,
+ table->in_use->real_id);
+ my_free((gptr) locked,MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
+
+
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
{
MYSQL_LOCK *sql_lock;
@@ -401,6 +443,36 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
*****************************************************************************/
/*
+ Lock and wait for the named lock.
+ Returns 0 on ok
+*/
+
+int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
+{
+ int lock_retcode;
+ int error= -1;
+ DBUG_ENTER("lock_and_wait_for_table_name");
+
+ if (wait_if_global_read_lock(thd,0))
+ DBUG_RETURN(1);
+ VOID(pthread_mutex_lock(&LOCK_open));
+ if ((lock_retcode = lock_table_name(thd, table_list)) < 0)
+ goto end;
+ if (lock_retcode && wait_for_locked_table_names(thd, table_list))
+ {
+ unlock_table_name(thd, table_list);
+ goto end;
+ }
+ error=0;
+
+end:
+ pthread_mutex_unlock(&LOCK_open);
+ start_waiting_global_read_lock(thd);
+ DBUG_RETURN(error);
+}
+
+
+/*
Put a not open table with an old refresh version in the table cache.
This will force any other threads that uses the table to release it
as soon as possible.
@@ -411,7 +483,6 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
> 0 table locked, but someone is using it
*/
-
int lock_table_name(THD *thd, TABLE_LIST *table_list)
{
TABLE *table;
@@ -419,6 +490,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
char *db= table_list->db ? table_list->db : (thd->db ? thd->db : (char*) "");
uint key_length;
DBUG_ENTER("lock_table_name");
+ safe_mutex_assert_owner(&LOCK_open);
key_length=(uint) (strmov(strmov(key,db)+1,table_list->real_name)
-key)+ 1;
@@ -430,10 +502,11 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
if (table->in_use == thd)
DBUG_RETURN(0);
- /* Create a table entry with the right key and with an old refresh version */
- /* Note that we must use my_malloc() here as this is freed by the table
- cache */
-
+ /*
+ Create a table entry with the right key and with an old refresh version
+ Note that we must use my_malloc() here as this is freed by the table
+ cache
+ */
if (!(table= (TABLE*) my_malloc(sizeof(*table)+key_length,
MYF(MY_WME | MY_ZEROFILL))))
DBUG_RETURN(-1);
@@ -464,7 +537,7 @@ void unlock_table_name(THD *thd, TABLE_LIST *table_list)
static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
{
- for ( ; table_list ; table_list=table_list->next)
+ for (; table_list ; table_list=table_list->next)
{
if (table_list->table && table_is_used(table_list->table,0))
return 1;
@@ -477,6 +550,7 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
{
bool result=0;
DBUG_ENTER("wait_for_locked_table_names");
+ safe_mutex_assert_owner(&LOCK_open);
while (locked_named_table(thd,table_list))
{
@@ -582,3 +656,102 @@ static void print_lock_error(int error)
DBUG_VOID_RETURN;
}
+
+/****************************************************************************
+ Handling of global read locks
+
+ The global locks are handled through the global variables:
+ global_read_lock
+ waiting_for_read_lock
+ protect_against_global_read_lock
+****************************************************************************/
+
+volatile uint global_read_lock=0;
+static volatile uint protect_against_global_read_lock=0;
+static volatile uint waiting_for_read_lock=0;
+
+bool lock_global_read_lock(THD *thd)
+{
+ DBUG_ENTER("lock_global_read_lock");
+
+ if (!thd->global_read_lock)
+ {
+ (void) pthread_mutex_lock(&LOCK_open);
+ const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
+ "Waiting to get readlock");
+ DBUG_PRINT("info",
+ ("waiting_for: %d protect_against: %d",
+ waiting_for_read_lock, protect_against_global_read_lock));
+
+ waiting_for_read_lock++;
+ while (protect_against_global_read_lock && !thd->killed)
+ pthread_cond_wait(&COND_refresh, &LOCK_open);
+ waiting_for_read_lock--;
+ thd->exit_cond(old_message);
+ if (thd->killed)
+ {
+ (void) pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(1);
+ }
+ thd->global_read_lock=1;
+ global_read_lock++;
+ (void) pthread_mutex_unlock(&LOCK_open);
+ }
+ DBUG_RETURN(0);
+}
+
+void unlock_global_read_lock(THD *thd)
+{
+ uint tmp;
+ thd->global_read_lock=0;
+ pthread_mutex_lock(&LOCK_open);
+ tmp= --global_read_lock;
+ pthread_mutex_unlock(&LOCK_open);
+ /* Send the signal outside the mutex to avoid a context switch */
+ if (!tmp)
+ pthread_cond_broadcast(&COND_refresh);
+}
+
+
+bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh)
+{
+ const char *old_message;
+ bool result=0;
+ DBUG_ENTER("wait_if_global_read_lock");
+
+ (void) pthread_mutex_lock(&LOCK_open);
+ if (global_read_lock)
+ {
+ if (thd->global_read_lock) // This thread had the read locks
+ {
+ my_error(ER_CANT_UPDATE_WITH_READLOCK,MYF(0));
+ (void) pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(1);
+ }
+ old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
+ "Waiting for release of readlock");
+ while (global_read_lock && ! thd->killed &&
+ (!abort_on_refresh || thd->version == refresh_version))
+ (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
+ if (thd->killed)
+ result=1;
+ thd->exit_cond(old_message);
+ }
+ if (!abort_on_refresh && !result)
+ protect_against_global_read_lock++;
+ pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(result);
+}
+
+
+void start_waiting_global_read_lock(THD *thd)
+{
+ bool tmp;
+ DBUG_ENTER("start_waiting_global_read_lock");
+ (void) pthread_mutex_lock(&LOCK_open);
+ tmp= (!--protect_against_global_read_lock && waiting_for_read_lock);
+ (void) pthread_mutex_unlock(&LOCK_open);
+ if (tmp)
+ pthread_cond_broadcast(&COND_refresh);
+ DBUG_VOID_RETURN;
+}
diff --git a/sql/log.cc b/sql/log.cc
index 69957c5c97c..8bd42d28e59 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,10 +29,10 @@
#include <my_dir.h>
#include <stdarg.h>
#include <m_ctype.h> // For test_if_number
+#include <assert.h>
MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
extern I_List<i_string> binlog_do_db, binlog_ignore_db;
-extern ulong max_binlog_size;
static bool test_if_number(const char *str,
long *res, bool allow_wildcards);
@@ -79,44 +79,49 @@ static int find_uniq_filename(char *name)
DBUG_RETURN(0);
}
-MYSQL_LOG::MYSQL_LOG(): last_time(0), query_start(0),index_file(-1),
- name(0), log_type(LOG_CLOSED),write_error(0),
- inited(0), no_rotate(0)
+
+MYSQL_LOG::MYSQL_LOG()
+ :bytes_written(0), last_time(0), query_start(0), name(0),
+ file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0),
+ need_start_event(1)
{
/*
- We don't want to intialize LOCK_Log here as the thread system may
- not have been initailized yet. We do it instead at 'open'.
+ We don't want to initialize LOCK_Log here as such initialization depends on
+ safe_mutex (when using safe_mutex) which depends on MY_INIT(), which is
+ called only in main(). Doing initialization here would make it happen
+ before main().
*/
index_file_name[0] = 0;
bzero((char*) &log_file,sizeof(log_file));
+ bzero((char*) &index_file, sizeof(index_file));
}
+
MYSQL_LOG::~MYSQL_LOG()
{
+ cleanup();
+}
+
+/* this is called only once */
+
+void MYSQL_LOG::cleanup()
+{
if (inited)
{
+ inited= 0;
+ close(LOG_CLOSE_INDEX);
(void) pthread_mutex_destroy(&LOCK_log);
(void) pthread_mutex_destroy(&LOCK_index);
+ (void) pthread_cond_destroy(&update_cond);
}
}
-void MYSQL_LOG::set_index_file_name(const char* index_file_name)
-{
- if (index_file_name)
- fn_format(this->index_file_name,index_file_name,mysql_data_home,".index",
- 4);
- else
- this->index_file_name[0] = 0;
-}
-
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
{
- if (log_type == LOG_NORMAL)
- fn_format(new_name,log_name,mysql_data_home,"",4);
- else
+ fn_format(new_name,log_name,mysql_data_home,"",4);
+ if (log_type != LOG_NORMAL)
{
- fn_format(new_name,log_name,mysql_data_home,"",4);
if (!fn_ext(log_name)[0])
{
if (find_uniq_filename(new_name))
@@ -129,44 +134,62 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
return 0;
}
-bool MYSQL_LOG::open_index( int options)
-{
- return (index_file < 0 &&
- (index_file = my_open(index_file_name, options | O_BINARY ,
- MYF(MY_WME))) < 0);
-}
-void MYSQL_LOG::init(enum_log_type log_type_arg)
+void MYSQL_LOG::init(enum_log_type log_type_arg,
+ enum cache_type io_cache_type_arg,
+ bool no_auto_events_arg,
+ ulong max_size_arg)
{
+ DBUG_ENTER("MYSQL_LOG::init");
log_type = log_type_arg;
- if (!inited)
- {
- inited=1;
- (void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
- (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
- }
+ io_cache_type = io_cache_type_arg;
+ no_auto_events = no_auto_events_arg;
+ max_size=max_size_arg;
+ DBUG_PRINT("info",("log_type: %d max_size: %lu", log_type, max_size));
+ DBUG_VOID_RETURN;
}
-void MYSQL_LOG::close_index()
+
+void MYSQL_LOG::init_pthread_objects()
{
- if (index_file >= 0)
- {
- my_close(index_file, MYF(0));
- index_file = -1;
- }
+ DBUG_ASSERT(inited == 0);
+ inited= 1;
+ (void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
+ (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
+ (void) pthread_cond_init(&update_cond, 0);
}
-void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
- const char *new_name, bool null_created)
+
+/*
+ Open a (new) log file.
+
+ DESCRIPTION
+ - If binary logs, also open the index file and register the new
+ file name in it
+ - When calling this when the file is in use, you must have a locks
+ on LOCK_log and LOCK_index.
+
+ RETURN VALUES
+ 0 ok
+ 1 error
+*/
+
+bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
+ const char *new_name, const char *index_file_name_arg,
+ enum cache_type io_cache_type_arg,
+ bool no_auto_events_arg,
+ ulong max_size)
{
- MY_STAT tmp_stat;
char buff[512];
- File file= -1;
- bool do_magic;
-
- if (!inited && log_type_arg == LOG_BIN && *fn_ext(log_name))
- no_rotate = 1;
- init(log_type_arg);
+ File file= -1, index_file_nr= -1;
+ int open_flags = O_CREAT | O_APPEND | O_BINARY;
+ DBUG_ENTER("MYSQL_LOG::open");
+ DBUG_PRINT("enter",("log_type: %d",(int) log_type));
+
+ last_time=query_start=0;
+ write_error=0;
+
+ init(log_type_arg,io_cache_type_arg,no_auto_events_arg,max_size);
if (!(name=my_strdup(log_name,MYF(MY_WME))))
goto err;
@@ -174,21 +197,22 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
strmov(log_file_name,new_name);
else if (generate_new_name(log_file_name, name))
goto err;
-
- if (log_type == LOG_BIN && !index_file_name[0])
- fn_format(index_file_name, name, mysql_data_home, ".index", 6);
- db[0]=0;
- do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name,
- &tmp_stat, MYF(0)));
+ if (io_cache_type == SEQ_READ_APPEND)
+ open_flags |= O_RDWR;
+ else
+ open_flags |= O_WRONLY;
- if ((file=my_open(log_file_name,O_CREAT | O_APPEND | O_WRONLY | O_BINARY,
+ db[0]=0;
+ open_count++;
+ if ((file=my_open(log_file_name,open_flags,
MYF(MY_WME | ME_WAITTANG))) < 0 ||
- init_io_cache(&log_file, file, IO_SIZE, WRITE_CACHE,
+ init_io_cache(&log_file, file, IO_SIZE, io_cache_type,
my_tell(file,MYF(MY_WME)), 0, MYF(MY_WME | MY_NABP)))
goto err;
- if (log_type == LOG_NORMAL)
+ switch (log_type) {
+ case LOG_NORMAL:
{
char *end;
#ifdef __NT__
@@ -200,8 +224,9 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
if (my_b_write(&log_file, (byte*) buff,(uint) (end-buff)) ||
flush_io_cache(&log_file))
goto err;
+ break;
}
- else if (log_type == LOG_NEW)
+ case LOG_NEW:
{
time_t skr=time(NULL);
struct tm tm_tmp;
@@ -217,50 +242,103 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
if (my_b_write(&log_file, (byte*) buff,(uint) strlen(buff)) ||
flush_io_cache(&log_file))
goto err;
+ break;
}
- else if (log_type == LOG_BIN)
+ case LOG_BIN:
{
- /*
- Explanation of the boolean black magic:
- if we are supposed to write magic number try write
- clean up if failed
- then if index_file has not been previously opened, try to open it
- clean up if failed
- */
- if ((do_magic && my_b_write(&log_file, (byte*) BINLOG_MAGIC, 4)) ||
- open_index(O_APPEND | O_RDWR | O_CREAT))
- goto err;
- bool error;
- Start_log_event s;
- if (null_created)
- s.created= 0;
- s.write(&log_file);
- flush_io_cache(&log_file);
- pthread_mutex_lock(&LOCK_index);
- error=(my_write(index_file, (byte*) log_file_name, strlen(log_file_name),
- MYF(MY_NABP | MY_WME)) ||
- my_write(index_file, (byte*) "\n", 1, MYF(MY_NABP | MY_WME)));
- pthread_mutex_unlock(&LOCK_index);
- if (error)
+ bool write_file_name_to_index_file=0;
+
+ myf opt= MY_UNPACK_FILENAME;
+ if (!index_file_name_arg)
+ {
+ index_file_name_arg= name; // Use same basename for index file
+ opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT;
+ }
+
+ if (!my_b_filelength(&log_file))
+ {
+ /*
+ The binary log file was empty (probably newly created)
+ This is the normal case and happens when the user doesn't specify
+ an extension for the binary log files.
+ In this case we write a standard header to it.
+ */
+ if (my_b_safe_write(&log_file, (byte*) BINLOG_MAGIC,
+ BIN_LOG_HEADER_SIZE))
+ goto err;
+ bytes_written += BIN_LOG_HEADER_SIZE;
+ write_file_name_to_index_file=1;
+ }
+
+ if (!my_b_inited(&index_file))
{
- close_index();
+ /*
+ First open of this class instance
+ Create an index file that will hold all file names uses for logging.
+ Add new entries to the end of it.
+ */
+ fn_format(index_file_name, index_file_name_arg, mysql_data_home,
+ ".index", opt);
+ if ((index_file_nr= my_open(index_file_name,
+ O_RDWR | O_CREAT | O_BINARY ,
+ MYF(MY_WME))) < 0 ||
+ init_io_cache(&index_file, index_file_nr,
+ IO_SIZE, WRITE_CACHE,
+ my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
+ 0, MYF(MY_WME)))
+ goto err;
+ }
+ else
+ {
+ safe_mutex_assert_owner(&LOCK_index);
+ reinit_io_cache(&index_file, WRITE_CACHE, my_b_filelength(&index_file),
+ 0, 0);
+ }
+ if (need_start_event && !no_auto_events)
+ {
+ need_start_event=0;
+ Start_log_event s;
+ s.set_log_pos(this);
+ s.write(&log_file);
+ }
+ if (flush_io_cache(&log_file))
goto err;
+
+ if (write_file_name_to_index_file)
+ {
+ /* As this is a new log file, we write the file name to the index file */
+ if (my_b_write(&index_file, (byte*) log_file_name,
+ strlen(log_file_name)) ||
+ my_b_write(&index_file, (byte*) "\n", 1) ||
+ flush_io_cache(&index_file))
+ goto err;
}
+ break;
}
- return;
+ case LOG_CLOSED: // Impossible
+ case LOG_TO_BE_OPENED:
+ DBUG_ASSERT(1);
+ break;
+ }
+ DBUG_RETURN(0);
err:
- sql_print_error("Could not use %s for logging (error %d)", log_name,errno);
+ sql_print_error("Could not use %s for logging (error %d). \
+Turning logging off for the whole duration of the MySQL server process. \
+To turn it on again: fix the cause, \
+shutdown the MySQL server and restart it.", log_name, errno);
if (file >= 0)
my_close(file,MYF(0));
+ if (index_file_nr >= 0)
+ my_close(index_file_nr,MYF(0));
end_io_cache(&log_file);
- x_free(name); name=0;
- log_type=LOG_CLOSED;
-
- return;
-
+ end_io_cache(&index_file);
+ safeFree(name);
+ log_type= LOG_CLOSED;
+ DBUG_RETURN(1);
}
+
int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
{
pthread_mutex_lock(&LOCK_log);
@@ -270,304 +348,617 @@ int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
return 0;
}
-// if log_name is "" we stop at the first entry
-int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name)
+
+/*
+ Move all data up in a file in an filename index file
+
+ SYNOPSIS
+ copy_up_file_and_fill()
+ index_file File to move
+ offset Move everything from here to beginning
+
+ NOTE
+ File will be truncated to be 'offset' shorter or filled up with
+ newlines
+
+ IMPLEMENTATION
+ We do the copy outside of the IO_CACHE as the cache buffers would just
+ make things slower and more complicated.
+ In most cases the copy loop should only do one read.
+
+ RETURN VALUES
+ 0 ok
+*/
+
+static bool copy_up_file_and_fill(IO_CACHE *index_file, my_off_t offset)
{
- if (index_file < 0)
- return LOG_INFO_INVALID;
- int error = 0;
- char* fname = linfo->log_file_name;
- uint log_name_len = (uint) strlen(log_name);
- IO_CACHE io_cache;
-
- // mutex needed because we need to make sure the file pointer does not move
- // from under our feet
- pthread_mutex_lock(&LOCK_index);
- if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, (my_off_t) 0,
- 0, MYF(MY_WME)))
+ int bytes_read;
+ my_off_t init_offset= offset;
+ File file= index_file->file;
+ byte io_buf[IO_SIZE*2];
+ DBUG_ENTER("copy_up_file_and_fill");
+
+ for (;; offset+= bytes_read)
{
- error = LOG_INFO_SEEK;
- goto err;
+ (void) my_seek(file, offset, MY_SEEK_SET, MYF(0));
+ if ((bytes_read= (int) my_read(file, io_buf, sizeof(io_buf), MYF(MY_WME)))
+ < 0)
+ goto err;
+ if (!bytes_read)
+ break; // end of file
+ (void) my_seek(file, offset-init_offset, MY_SEEK_SET, MYF(0));
+ if (my_write(file, (byte*) io_buf, bytes_read, MYF(MY_WME | MY_NABP)))
+ goto err;
}
- for(;;)
+ /* The following will either truncate the file or fill the end with \n' */
+ if (my_chsize(file, offset - init_offset, '\n', MYF(MY_WME)))
+ goto err;
+
+ /* Reset data in old index cache */
+ reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 1);
+ DBUG_RETURN(0);
+
+err:
+ DBUG_RETURN(1);
+}
+
+
+/*
+ Find the position in the log-index-file for the given log name
+
+ SYNOPSIS
+ find_log_pos()
+ linfo Store here the found log file name and position to
+ the NEXT log file name in the index file.
+ log_name Filename to find in the index file.
+ Is a null pointer if we want to read the first entry
+ need_lock Set this to 1 if the parent doesn't already have a
+ lock on LOCK_index
+
+ NOTE
+ On systems without the truncate function the file will end with one or
+ more empty lines. These will be ignored when reading the file.
+
+ RETURN VALUES
+ 0 ok
+ LOG_INFO_EOF End of log-index-file found
+ LOG_INFO_IO Got IO error while reading file
+*/
+
+int MYSQL_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
+ bool need_lock)
+{
+ int error= 0;
+ char *fname= linfo->log_file_name;
+ uint log_name_len= log_name ? (uint) strlen(log_name) : 0;
+ DBUG_ENTER("find_log_pos");
+ DBUG_PRINT("enter",("log_name: %s", log_name ? log_name : "NULL"));
+
+ /*
+ Mutex needed because we need to make sure the file pointer does not move
+ from under our feet
+ */
+ if (need_lock)
+ pthread_mutex_lock(&LOCK_index);
+ safe_mutex_assert_owner(&LOCK_index);
+
+ /* As the file is flushed, we can't get an error here */
+ (void) reinit_io_cache(&index_file, READ_CACHE, (my_off_t) 0, 0, 0);
+
+ for (;;)
{
uint length;
- if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN-1)))
+ my_off_t offset= my_b_tell(&index_file);
+ /* If we get 0 or 1 characters, this is the end of the file */
+
+ if ((length= my_b_gets(&index_file, fname, FN_REFLEN)) <= 1)
{
- error = !io_cache.error ? LOG_INFO_EOF : LOG_INFO_IO;
- goto err;
+ /* Did not find the given entry; Return not found or error */
+ error= !index_file.error ? LOG_INFO_EOF : LOG_INFO_IO;
+ break;
}
- // if the log entry matches, empty string matching anything
- if (!log_name_len ||
+ // if the log entry matches, null string matching anything
+ if (!log_name ||
(log_name_len == length-1 && fname[log_name_len] == '\n' &&
!memcmp(fname, log_name, log_name_len)))
{
+ DBUG_PRINT("info",("Found log file entry"));
fname[length-1]=0; // remove last \n
- linfo->index_file_offset = my_b_tell(&io_cache);
+ linfo->index_file_start_offset= offset;
+ linfo->index_file_offset = my_b_tell(&index_file);
break;
}
}
- error = 0;
-err:
- pthread_mutex_unlock(&LOCK_index);
- end_io_cache(&io_cache);
- return error;
-
+ if (need_lock)
+ pthread_mutex_unlock(&LOCK_index);
+ DBUG_RETURN(error);
}
-int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
+/*
+ Find the position in the log-index-file for the given log name
+
+ SYNOPSIS
+ find_next_log()
+ linfo Store here the next log file name and position to
+ the file name after that.
+ need_lock Set this to 1 if the parent doesn't already have a
+ lock on LOCK_index
+
+ NOTE
+ - Before calling this function, one has to call find_log_pos()
+ to set up 'linfo'
+ - Mutex needed because we need to make sure the file pointer does not move
+ from under our feet
+
+ RETURN VALUES
+ 0 ok
+ LOG_INFO_EOF End of log-index-file found
+ LOG_INFO_SEEK Could not allocate IO cache
+ LOG_INFO_IO Got IO error while reading file
+*/
+
+int MYSQL_LOG::find_next_log(LOG_INFO* linfo, bool need_lock)
{
- // mutex needed because we need to make sure the file pointer does not move
- // from under our feet
- if (index_file < 0) return LOG_INFO_INVALID;
- int error = 0;
- char* fname = linfo->log_file_name;
- IO_CACHE io_cache;
+ int error= 0;
uint length;
+ char *fname= linfo->log_file_name;
- pthread_mutex_lock(&LOCK_index);
- if (init_io_cache(&io_cache, index_file, IO_SIZE,
- READ_CACHE, (my_off_t) linfo->index_file_offset, 0,
- MYF(MY_WME)))
- {
- error = LOG_INFO_SEEK;
- goto err;
- }
- if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN)))
+ if (need_lock)
+ pthread_mutex_lock(&LOCK_index);
+ safe_mutex_assert_owner(&LOCK_index);
+
+ /* As the file is flushed, we can't get an error here */
+ (void) reinit_io_cache(&index_file, READ_CACHE, linfo->index_file_offset, 0,
+ 0);
+
+ linfo->index_file_start_offset= linfo->index_file_offset;
+ if ((length=my_b_gets(&index_file, fname, FN_REFLEN)) <= 1)
{
- error = !io_cache.error ? LOG_INFO_EOF : LOG_INFO_IO;
+ error = !index_file.error ? LOG_INFO_EOF : LOG_INFO_IO;
goto err;
}
fname[length-1]=0; // kill /n
- linfo->index_file_offset = my_b_tell(&io_cache);
- error = 0;
+ linfo->index_file_offset = my_b_tell(&index_file);
err:
- pthread_mutex_unlock(&LOCK_index);
- end_io_cache(&io_cache);
+ if (need_lock)
+ pthread_mutex_unlock(&LOCK_index);
return error;
}
-
-int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
+
+/*
+ Delete all logs refered to in the index file
+ Start writing to a new log file. The new index file will only contain
+ this file.
+
+ SYNOPSIS
+ reset_logs()
+ thd Thread
+
+ NOTE
+ If not called from slave thread, write start event to new log
+
+
+ RETURN VALUES
+ 0 ok
+ 1 error
+*/
+
+bool MYSQL_LOG::reset_logs(THD* thd)
{
- if (index_file < 0) return LOG_INFO_INVALID;
- if (no_rotate) return LOG_INFO_PURGE_NO_ROTATE;
- int error;
- char fname[FN_REFLEN];
- char *p;
- uint fname_len, i;
- bool logs_to_purge_inited = 0, logs_to_keep_inited = 0, found_log = 0;
- DYNAMIC_ARRAY logs_to_purge, logs_to_keep;
- my_off_t purge_offset ;
- LINT_INIT(purge_offset);
- IO_CACHE io_cache;
-
+ LOG_INFO linfo;
+ bool error=0;
+ const char* save_name;
+ enum_log_type save_log_type;
+ DBUG_ENTER("reset_logs");
+
+ /*
+ We need to get both locks to be sure that no one is trying to
+ write to the index log file.
+ */
+ pthread_mutex_lock(&LOCK_log);
pthread_mutex_lock(&LOCK_index);
-
- if (init_io_cache(&io_cache,index_file, IO_SIZE*2, READ_CACHE, (my_off_t) 0,
- 0, MYF(MY_WME)))
- {
- error = LOG_INFO_MEM;
- goto err;
- }
- if (my_init_dynamic_array(&logs_to_purge, sizeof(char*), 1024, 1024))
+
+ /* Save variables so that we can reopen the log */
+ save_name=name;
+ name=0; // Protect against free
+ save_log_type=log_type;
+ close(LOG_CLOSE_TO_BE_OPENED);
+
+ /* First delete all old log files */
+
+ if (find_log_pos(&linfo, NullS, 0))
{
- error = LOG_INFO_MEM;
+ error=1;
goto err;
}
- logs_to_purge_inited = 1;
- if (my_init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024))
+ for (;;)
{
- error = LOG_INFO_MEM;
- goto err;
+ my_delete(linfo.log_file_name, MYF(MY_WME));
+ if (find_next_log(&linfo, 0))
+ break;
}
- logs_to_keep_inited = 1;
-
- for(;;)
- {
- my_off_t init_purge_offset= my_b_tell(&io_cache);
- if (!(fname_len=my_b_gets(&io_cache, fname, FN_REFLEN)))
- {
- if(!io_cache.error)
- break;
- error = LOG_INFO_IO;
- goto err;
- }
+ /* Start logging with a new file */
+ close(LOG_CLOSE_INDEX);
+ my_delete(index_file_name, MYF(MY_WME)); // Reset (open will update)
+ if (!thd->slave_thread)
+ need_start_event=1;
+ open(save_name, save_log_type, 0, index_file_name,
+ io_cache_type, no_auto_events, max_size);
+ my_free((gptr) save_name, MYF(0));
- fname[--fname_len]=0; // kill \n
- if(!memcmp(fname, to_log, fname_len + 1 ))
- {
- found_log = 1;
- purge_offset = init_purge_offset;
- }
-
- // if one of the logs before the target is in use
- if(!found_log && log_in_use(fname))
- {
- error = LOG_INFO_IN_USE;
- goto err;
- }
-
- if (!(p = sql_memdup(fname, fname_len+1)) ||
- insert_dynamic(found_log ? &logs_to_keep : &logs_to_purge,
- (gptr) &p))
- {
- error = LOG_INFO_MEM;
- goto err;
- }
- }
-
- end_io_cache(&io_cache);
- if(!found_log)
+err:
+ pthread_mutex_unlock(&LOCK_index);
+ pthread_mutex_unlock(&LOCK_log);
+ DBUG_RETURN(error);
+}
+
+
+/*
+ Delete the current log file, remove it from index file and start on next
+
+ SYNOPSIS
+ purge_first_log()
+ rli Relay log information
+
+ NOTE
+ - This is only called from the slave-execute thread when it has read
+ all commands from a log and want to switch to a new log.
+ - When this happens, we should never be in an active transaction as
+ a transaction is always written as a single block to the binary log.
+
+ IMPLEMENTATION
+ - Protects index file with LOCK_index
+ - Delete first log file,
+ - Copy all file names after this one to the front of the index file
+ - If the OS has truncate, truncate the file, else fill it with \n'
+ - Read the first file name from the index file and store in rli->linfo
+
+ RETURN VALUES
+ 0 ok
+ LOG_INFO_EOF End of log-index-file found
+ LOG_INFO_SEEK Could not allocate IO cache
+ LOG_INFO_IO Got IO error while reading file
+*/
+
+int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli)
+{
+ int error;
+ DBUG_ENTER("purge_first_log");
+
+ /*
+ Test pre-conditions.
+
+ Assume that we have previously read the first log and
+ stored it in rli->relay_log_name
+ */
+ DBUG_ASSERT(is_open());
+ DBUG_ASSERT(rli->slave_running == 1);
+ DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->relay_log_name));
+ DBUG_ASSERT(rli->linfo.index_file_offset ==
+ strlen(rli->relay_log_name) + 1);
+
+ /* We have already processed the relay log, so it's safe to delete it */
+ my_delete(rli->relay_log_name, MYF(0));
+ pthread_mutex_lock(&LOCK_index);
+ if (copy_up_file_and_fill(&index_file, rli->linfo.index_file_offset))
{
- error = LOG_INFO_EOF;
+ error= LOG_INFO_IO;
goto err;
}
+
+ /*
+ Update the space counter used by all relay logs
+ Ok to broadcast after the critical region as there is no risk of
+ the mutex being destroyed by this thread later - this helps save
+ context switches
+ */
+ pthread_mutex_lock(&rli->log_space_lock);
+ rli->log_space_total -= rli->relay_log_pos;
+ //tell the I/O thread to take the relay_log_space_limit into account
+ rli->ignore_log_space_limit= 0;
+ pthread_mutex_unlock(&rli->log_space_lock);
+ pthread_cond_broadcast(&rli->log_space_cond);
- for(i = 0; i < logs_to_purge.elements; i++)
- {
- char* l;
- get_dynamic(&logs_to_purge, (gptr)&l, i);
- if (my_delete(l, MYF(MY_WME)))
- sql_print_error("Error deleting %s during purge", l);
- }
-
- // if we get killed -9 here, the sysadmin would have to do a small
- // vi job on the log index file after restart - otherwise, this should
- // be safe
-#ifdef HAVE_FTRUNCATE
- if (ftruncate(index_file,0))
+ /*
+ Read the next log file name from the index file and pass it back to
+ the caller
+ */
+ if ((error=find_log_pos(&rli->linfo, NullS, 0 /*no mutex*/)))
{
- sql_print_error(
-"Could not truncate the binlog index file during log purge for write");
- error = LOG_INFO_FATAL;
+ char buff[22];
+ sql_print_error("next log error: %d offset: %s log: %s",
+ error,
+ llstr(rli->linfo.index_file_offset,buff),
+ rli->linfo.log_file_name);
goto err;
}
- my_seek(index_file, 0, MY_SEEK_CUR,MYF(MY_WME));
-#else
- my_close(index_file, MYF(MY_WME));
- my_delete(index_file_name, MYF(MY_WME));
- if(!(index_file = my_open(index_file_name,
- O_CREAT | O_BINARY | O_RDWR | O_APPEND,
- MYF(MY_WME))))
- {
- sql_print_error(
-"Could not re-open the binlog index file during log purge for write");
- error = LOG_INFO_FATAL;
+ /*
+ Reset position to current log. This involves setting both of the
+ position variables:
+ */
+ rli->relay_log_pos = BIN_LOG_HEADER_SIZE;
+ rli->pending = 0;
+ strmake(rli->relay_log_name,rli->linfo.log_file_name,
+ sizeof(rli->relay_log_name)-1);
+
+ /* Store where we are in the new file for the execution thread */
+ flush_relay_log_info(rli);
+
+err:
+ pthread_mutex_unlock(&LOCK_index);
+ DBUG_RETURN(error);
+}
+
+
+/*
+ Remove all logs before the given log from disk and from the index file.
+
+ SYNOPSIS
+ purge_logs()
+ thd Thread pointer
+ to_log Delete all log file name before this file. This file is not
+ deleted
+
+ NOTES
+ If any of the logs before the deleted one is in use,
+ only purge logs up to this one.
+
+ RETURN VALUES
+ 0 ok
+ LOG_INFO_EOF to_log not found
+*/
+
+int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
+{
+ int error;
+ LOG_INFO log_info;
+ DBUG_ENTER("purge_logs");
+
+ pthread_mutex_lock(&LOCK_index);
+ if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/)))
+ goto err;
+
+ /*
+ File name exists in index file; Delete until we find this file
+ or a file that is used.
+ */
+ if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
goto err;
+ while (strcmp(to_log,log_info.log_file_name) &&
+ !log_in_use(log_info.log_file_name))
+ {
+ /* It's not fatal even if we can't delete a log file */
+ my_delete(log_info.log_file_name, MYF(0));
+ if (find_next_log(&log_info, 0))
+ break;
}
-#endif
-
- for(i = 0; i < logs_to_keep.elements; i++)
+
+ /*
+ If we get killed -9 here, the sysadmin would have to edit
+ the log index file after restart - otherwise, this should be safe
+ */
+
+ if (copy_up_file_and_fill(&index_file, log_info.index_file_start_offset))
{
- char* l;
- get_dynamic(&logs_to_keep, (gptr)&l, i);
- if (my_write(index_file, (byte*) l, strlen(l), MYF(MY_WME|MY_NABP)) ||
- my_write(index_file, (byte*) "\n", 1, MYF(MY_WME|MY_NABP)))
- {
- error = LOG_INFO_FATAL;
- goto err;
- }
+ error= LOG_INFO_IO;
+ goto err;
}
- // now update offsets
- adjust_linfo_offsets(purge_offset);
- error = 0;
+ // now update offsets in index file for running threads
+ adjust_linfo_offsets(log_info.index_file_start_offset);
err:
pthread_mutex_unlock(&LOCK_index);
- if(logs_to_purge_inited)
- delete_dynamic(&logs_to_purge);
- if(logs_to_keep_inited)
- delete_dynamic(&logs_to_keep);
- end_io_cache(&io_cache);
- return error;
+ DBUG_RETURN(error);
}
-// we assume that buf has at least FN_REFLEN bytes alloced
+/*
+ Create a new log file name
+
+ SYNOPSIS
+ make_log_name()
+ buf buf of at least FN_REFLEN where new name is stored
+
+ NOTE
+ If file name will be longer then FN_REFLEN it will be truncated
+*/
+
void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
{
- buf[0] = 0; // In case of error
- if (inited)
- {
- int dir_len = dirname_length(log_file_name);
- int ident_len = (uint) strlen(log_ident);
- if (dir_len + ident_len + 1 > FN_REFLEN)
- return; // protection agains malicious buffer overflow
-
- memcpy(buf, log_file_name, dir_len);
- // copy filename + end null
- memcpy(buf + dir_len, log_ident, ident_len + 1);
- }
+ uint dir_len = dirname_length(log_file_name);
+ if (dir_len > FN_REFLEN)
+ dir_len=FN_REFLEN-1;
+ strnmov(buf, log_file_name, dir_len);
+ strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len);
}
-bool MYSQL_LOG::is_active(const char* log_file_name)
+
+/*
+ Check if we are writing/reading to the given log file
+*/
+
+bool MYSQL_LOG::is_active(const char *log_file_name_arg)
{
- return inited && !strcmp(log_file_name, this->log_file_name);
+ return !strcmp(log_file_name, log_file_name_arg);
}
-void MYSQL_LOG::new_file(bool inside_mutex)
+
+/*
+ Start writing to a new log file or reopen the old file
+
+ SYNOPSIS
+ new_file()
+ need_lock Set to 1 (default) if caller has not locked
+ LOCK_log and LOCK_index
+
+ NOTE
+ The new file name is stored last in the index file
+*/
+
+void MYSQL_LOG::new_file(bool need_lock)
{
+ char new_name[FN_REFLEN], *new_name_ptr, *old_name;
+ enum_log_type save_log_type;
+
+ DBUG_ENTER("MYSQL_LOG::new_file");
if (!is_open())
- return;
+ {
+ DBUG_PRINT("info",("log is closed"));
+ DBUG_VOID_RETURN;
+ }
- if (!inside_mutex)
- VOID(pthread_mutex_lock(&LOCK_log));
+ if (need_lock)
+ {
+ pthread_mutex_lock(&LOCK_log);
+ pthread_mutex_lock(&LOCK_index);
+ }
+ safe_mutex_assert_owner(&LOCK_log);
+ safe_mutex_assert_owner(&LOCK_index);
- char new_name[FN_REFLEN], *old_name = name;
-
- if (!no_rotate)
+ /* Reuse old name if not binlog and not update log */
+ new_name_ptr= name;
+
+ /*
+ If user hasn't specified an extension, generate a new log name
+ We have to do this here and not in open as we want to store the
+ new file name in the current binary log file.
+ */
+ if (generate_new_name(new_name, name))
+ goto end;
+ new_name_ptr=new_name;
+
+ if (log_type == LOG_BIN)
{
- /*
- only rotate open logs that are marked non-rotatable
- (binlog with constant name are non-rotatable)
- */
- if (generate_new_name(new_name, name))
- {
- if (!inside_mutex)
- VOID(pthread_mutex_unlock(&LOCK_log));
- return; // Something went wrong
- }
- if (log_type == LOG_BIN)
+ if (!no_auto_events)
{
/*
- We log the whole file name for log file as the user may decide
- to change base names at some point.
+ We log the whole file name for log file as the user may decide
+ to change base names at some point.
*/
- Rotate_log_event r(new_name+dirname_length(new_name));
+ THD* thd = current_thd; /* may be 0 if we are reacting to SIGHUP */
+ Rotate_log_event r(thd,new_name+dirname_length(new_name));
+ r.set_log_pos(this);
+
+ /*
+ Because this log rotation could have been initiated by a master of
+ the slave running with log-bin, we set the flag on rotate
+ event to prevent infinite log rotation loop
+ */
+ if (thd && thd->slave_thread)
+ r.flags|= LOG_EVENT_FORCED_ROTATE_F;
r.write(&log_file);
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ bytes_written += r.get_event_len();
}
+ /*
+ Update needs to be signalled even if there is no rotate event
+ log rotation should give the waiting thread a signal to
+ discover EOF and move on to the next log.
+ */
+ signal_update();
}
- else
- strmov(new_name, old_name); // Reopen old file name
- name=0;
- close();
+ old_name=name;
+ save_log_type=log_type;
+ name=0; // Don't free name
+ close(LOG_CLOSE_TO_BE_OPENED);
+
/*
- new_file() is only used for rotation (in FLUSH LOGS or because size >
- max_binlog_size).
- If this is a binary log, the Start_log_event at the beginning of
- the new file should have created=0 (to distinguish with the Start_log_event
- written at server startup, which should trigger temp tables deletion on
- >=4.0.14 slaves).
- */
- open(old_name, log_type, new_name, 1);
+ Note that at this point, log_type != LOG_CLOSED (important for is_open()).
+ */
+
+ open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type,
+ no_auto_events, max_size);
my_free(old_name,MYF(0));
- last_time=query_start=0;
- write_error=0;
- if (!inside_mutex)
- VOID(pthread_mutex_unlock(&LOCK_log));
+end:
+ if (need_lock)
+ {
+ pthread_mutex_unlock(&LOCK_index);
+ pthread_mutex_unlock(&LOCK_log);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+bool MYSQL_LOG::append(Log_event* ev)
+{
+ bool error = 0;
+ pthread_mutex_lock(&LOCK_log);
+ DBUG_ENTER("MYSQL_LOG::append");
+
+ DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
+ /*
+ Log_event::write() is smart enough to use my_b_write() or
+ my_b_append() depending on the kind of cache we have.
+ */
+ if (ev->write(&log_file))
+ {
+ error=1;
+ goto err;
+ }
+ bytes_written += ev->get_event_len();
+ DBUG_PRINT("info",("max_size: %lu",max_size));
+ if ((uint) my_b_append_tell(&log_file) > max_size)
+ {
+ pthread_mutex_lock(&LOCK_index);
+ new_file(0);
+ pthread_mutex_unlock(&LOCK_index);
+ }
+
+err:
+ pthread_mutex_unlock(&LOCK_log);
+ signal_update(); // Safe as we don't call close
+ DBUG_RETURN(error);
+}
+
+
+bool MYSQL_LOG::appendv(const char* buf, uint len,...)
+{
+ bool error= 0;
+ DBUG_ENTER("MYSQL_LOG::appendv");
+ va_list(args);
+ va_start(args,len);
+
+ DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
+
+ pthread_mutex_lock(&LOCK_log);
+ do
+ {
+ if (my_b_append(&log_file,(byte*) buf,len))
+ {
+ error= 1;
+ goto err;
+ }
+ bytes_written += len;
+ } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint)));
+ DBUG_PRINT("info",("max_size: %lu",max_size));
+ if ((uint) my_b_append_tell(&log_file) > max_size)
+ {
+ pthread_mutex_lock(&LOCK_index);
+ new_file(0);
+ pthread_mutex_unlock(&LOCK_index);
+ }
+
+err:
+ pthread_mutex_unlock(&LOCK_log);
+ if (!error)
+ signal_update();
+ DBUG_RETURN(error);
}
+/*
+ Write to normal (not rotable) log
+ This is the format for the 'normal', 'slow' and 'update' logs.
+*/
+
bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
const char *format,...)
{
@@ -588,7 +979,7 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
if (thd)
{ // Normal thread
if ((thd->options & OPTION_LOG_OFF) &&
- (thd->master_access & PROCESS_ACL))
+ (thd->master_access & SUPER_ACL))
{
VOID(pthread_mutex_unlock(&LOCK_log));
return 0; // No logging
@@ -647,111 +1038,183 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
return 0;
}
-/* Write to binary log in a format to be used for replication */
-bool MYSQL_LOG::write(Query_log_event* event_info)
+/*
+ Write an event to the binary log
+*/
+
+bool MYSQL_LOG::write(Log_event* event_info)
{
- /* In most cases this is only called if 'is_open()' is true */
+ THD *thd=event_info->thd;
+ bool called_handler_commit=0;
bool error=0;
- bool should_rotate = 0;
+ DBUG_ENTER("MYSQL_LOG::write(event)");
- if (!inited) // Can't use mutex if not init
- return 0;
- VOID(pthread_mutex_lock(&LOCK_log));
+ pthread_mutex_lock(&LOCK_log);
+
+ /*
+ In most cases this is only called if 'is_open()' is true; in fact this is
+ mostly called if is_open() *was* true a few instructions before, but it
+ could have changed since.
+ */
if (is_open())
{
- THD *thd=event_info->thd;
- IO_CACHE *file = (event_info->cache_stmt ? &thd->transaction.trans_log :
- &log_file);
- if ((!(thd->options & OPTION_BIN_LOG) &&
- (thd->master_access & PROCESS_ACL)) ||
- !db_ok(event_info->db, binlog_do_db, binlog_ignore_db))
+ bool should_rotate= 0;
+ const char *local_db= event_info->get_db();
+ IO_CACHE *file= &log_file;
+#ifdef USING_TRANSACTIONS
+ /*
+ Should we write to the binlog cache or to the binlog on disk?
+ Write to the binlog cache if:
+ - it is already not empty (meaning we're in a transaction; note that the
+ present event could be about a non-transactional table, but still we need
+ to write to the binlog cache in that case to handle updates to mixed
+ trans/non-trans table types the best possible in binlogging)
+ - or if the event asks for it (cache_stmt == true).
+ */
+ if (opt_using_transactions &&
+ (event_info->get_cache_stmt() ||
+ (thd && my_b_tell(&thd->transaction.trans_log))))
+ file= &thd->transaction.trans_log;
+#endif
+ DBUG_PRINT("info",("event type=%d",event_info->get_type_code()));
+ /*
+ In the future we need to add to the following if tests like
+ "do the involved tables match (to be implemented)
+ binlog_[wild_]{do|ignore}_table?" (WL#1049)"
+ */
+ if ((thd && !(thd->options & OPTION_BIN_LOG) &&
+ (thd->master_access & SUPER_ACL)) ||
+ (local_db && !db_ok(local_db, binlog_do_db, binlog_ignore_db)))
{
VOID(pthread_mutex_unlock(&LOCK_log));
- return 0;
+ DBUG_PRINT("error",("!db_ok"));
+ DBUG_RETURN(0);
}
error=1;
+ /*
+ No check for auto events flag here - this write method should
+ never be called if auto-events are enabled
+ */
- if (file == &thd->transaction.trans_log
- && !my_b_tell(&thd->transaction.trans_log)) {
+ /*
+ 1. Write first log events which describe the 'run environment'
+ of the SQL command
+ */
- /* Add the "BEGIN" and "COMMIT" in the binlog around transactions
- which may contain more than 1 SQL statement. If we run with
- AUTOCOMMIT=1, then MySQL immediately writes each SQL statement to
- the binlog when the statement has been completed. No need to add
- "BEGIN" ... "COMMIT" around such statements. Otherwise, MySQL uses
- thd->transaction.trans_log to cache the SQL statements until the
- explicit commit, and at the commit writes the contents in .trans_log
- to the binlog.
+ if (thd)
+ {
+ if (thd->last_insert_id_used)
+ {
+ Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
+ thd->current_insert_id);
+ e.set_log_pos(this);
+ if (e.write(file))
+ goto err;
+ }
+ if (thd->insert_id_used)
+ {
+ Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id);
+ e.set_log_pos(this);
+ if (e.write(file))
+ goto err;
+ }
+ if (thd->rand_used)
+ {
+ Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
+ e.set_log_pos(this);
+ if (e.write(file))
+ goto err;
+ }
+ if (thd->variables.convert_set)
+ {
+ char buf[256], *p;
+ p= strmov(strmov(buf, "SET CHARACTER SET "),
+ thd->variables.convert_set->name);
+ Query_log_event e(thd, buf, (ulong) (p - buf), 0);
+ e.set_log_pos(this);
+ if (e.write(file))
+ goto err;
+ }
- We write the "BEGIN" mark first in the buffer (.trans_log) where we
- store the SQL statements for a transaction. At the transaction commit
- we will add the "COMMIT mark and write the buffer to the binlog.
- The function my_b_tell above returns != 0 if there already is data
- in the buffer. */
+ /*
+ If the user has set FOREIGN_KEY_CHECKS=0 we wrap every SQL
+ command in the binlog inside:
+ SET FOREIGN_KEY_CHECKS=0;
+ <command>;
+ SET FOREIGN_KEY_CHECKS=1;
+ */
- int save_query_length = thd->query_length;
+ if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS)
+ {
+ Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=0", 24, 0);
+ e.set_log_pos(this);
+ if (e.write(file))
+ goto err;
+ }
+ }
- thd->query_length = 5; /* length of string BEGIN */
+ /* Write the SQL command */
- Query_log_event qinfo(thd, "BEGIN", TRUE);
-
- error = ((&qinfo)->write(file));
+ event_info->set_log_pos(this);
+ if (event_info->write(file))
+ goto err;
- thd->query_length = save_query_length;
-
- if (error)
- goto err;
- }
-
- if (thd->last_insert_id_used)
- {
- Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->current_insert_id);
- if(thd->server_id)
- e.server_id = thd->server_id;
- if (e.write(file))
- goto err;
- }
- if (thd->insert_id_used)
+ /* Write log events to reset the 'run environment' of the SQL command */
+
+ if (thd && thd->options & OPTION_NO_FOREIGN_KEY_CHECKS)
{
- Intvar_log_event e((uchar)INSERT_ID_EVENT, thd->last_insert_id);
- if(thd->server_id)
- e.server_id = thd->server_id;
+ Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0);
+ e.set_log_pos(this);
if (e.write(file))
goto err;
}
- if (thd->convert_set)
+
+ /*
+ Tell for transactional table handlers up to which position in the
+ binlog file we wrote. The table handler can store this info, and
+ after crash recovery print for the user the offset of the last
+ transactions which were recovered. Actually, we must also call
+ the table handler commit here, protected by the LOCK_log mutex,
+ because otherwise the transactions may end up in a different order
+ in the table handler log!
+
+ Note that we will NOT call ha_report_binlog_offset_and_commit() if
+ there are binlog events cached in the transaction cache. That is
+ because then the log event which we write to the binlog here is
+ not a transactional event. In versions < 4.0.13 before this fix this
+ caused an InnoDB transaction to be committed if in the middle there
+ was a MyISAM event!
+ */
+
+ if (file == &log_file) // we are writing to the real log (disk)
{
- char buf[1024] = "SET CHARACTER SET ";
- char* p = strend(buf);
- p = strmov(p, thd->convert_set->name);
- int save_query_length = thd->query_length;
- // just in case somebody wants it later
- thd->query_length = (uint)(p - buf);
- Query_log_event e(thd, buf);
- if (e.write(file))
+ if (flush_io_cache(file))
goto err;
- thd->query_length = save_query_length; // clean up
+
+ if (opt_using_transactions && !my_b_tell(&thd->transaction.trans_log))
+ {
+ /*
+ LOAD DATA INFILE in AUTOCOMMIT=1 mode writes to the binlog
+ chunks also before it is successfully completed. We only report
+ the binlog write and do the commit inside the transactional table
+ handler if the log event type is appropriate.
+ */
+
+ if (event_info->get_type_code() == QUERY_EVENT ||
+ event_info->get_type_code() == EXEC_LOAD_EVENT)
+ {
+ error = ha_report_binlog_offset_and_commit(thd, log_file_name,
+ file->pos_in_file);
+ called_handler_commit=1;
+ }
+ }
+ /* We wrote to the real log, check automatic rotation; */
+ DBUG_PRINT("info",("max_size: %lu",max_size));
+ should_rotate= (my_b_tell(file) >= (my_off_t) max_size);
}
- if (event_info->write(file) ||
- file == &log_file && flush_io_cache(file))
- goto err;
error=0;
- should_rotate = (file == &log_file && my_b_tell(file) >= max_binlog_size);
-
- /* Tell for transactional table handlers up to which position in the
- binlog file we wrote. The table handler can store this info, and
- after crash recovery print for the user the offset of the last
- transactions which were recovered. Actually, we must also call
- the table handler commit here, protected by the LOCK_log mutex,
- because otherwise the transactions may end up in a different order
- in the table handler log! */
-
- if (file == &log_file) {
- error = ha_report_binlog_offset_and_commit(thd, log_file_name,
- file->pos_in_file);
- }
err:
if (error)
@@ -763,272 +1226,424 @@ err:
write_error=1;
}
if (file == &log_file)
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ signal_update();
+ if (should_rotate)
+ {
+ pthread_mutex_lock(&LOCK_index);
+ new_file(0); // inside mutex
+ pthread_mutex_unlock(&LOCK_index);
+ }
}
- if (should_rotate)
- new_file(1); // inside mutex
- VOID(pthread_mutex_unlock(&LOCK_log));
- return error;
+
+ pthread_mutex_unlock(&LOCK_log);
+
+ /*
+ Flush the transactional handler log file now that we have released
+ LOCK_log; the flush is placed here to eliminate the bottleneck on the
+ group commit
+ */
+
+ if (called_handler_commit)
+ ha_commit_complete(thd);
+
+ DBUG_RETURN(error);
+}
+
+
+uint MYSQL_LOG::next_file_id()
+{
+ uint res;
+ pthread_mutex_lock(&LOCK_log);
+ res = file_id++;
+ pthread_mutex_unlock(&LOCK_log);
+ return res;
}
+
/*
Write a cached log entry to the binary log
- We only come here if there is something in the cache.
- 'cache' needs to be reinitialized after this functions returns.
+
+ SYNOPSIS
+ write()
+ thd
+ cache The cache to copy to the binlog
+ commit_or_rollback If true, will write "COMMIT" in the end, if false will
+ write "ROLLBACK".
+
+ NOTE
+ - We only come here if there is something in the cache.
+ - The thing in the cache is always a complete transaction
+ - 'cache' needs to be reinitialized after this functions returns.
+
+ IMPLEMENTATION
+ - To support transaction over replication, we wrap the transaction
+ with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log.
+ We want to write a BEGIN/ROLLBACK block when a non-transactional table was
+ updated in a transaction which was rolled back. This is to ensure that the
+ same updates are run on the slave.
*/
-bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache)
+bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback)
{
VOID(pthread_mutex_lock(&LOCK_log));
- bool error=1;
+ DBUG_ENTER("MYSQL_LOG::write(cache");
- if (is_open())
+ if (is_open()) // Should always be true
{
uint length;
- if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
+ /*
+ Add the "BEGIN" and "COMMIT" in the binlog around transactions
+ which may contain more than 1 SQL statement. If we run with
+ AUTOCOMMIT=1, then MySQL immediately writes each SQL statement to
+ the binlog when the statement has been completed. No need to add
+ "BEGIN" ... "COMMIT" around such statements. Otherwise, MySQL uses
+ thd->transaction.trans_log to cache the SQL statements until the
+ explicit commit, and at the commit writes the contents in .trans_log
+ to the binlog.
+
+ We write the "BEGIN" mark first in the buffer (.trans_log) where we
+ store the SQL statements for a transaction. At the transaction commit
+ we will add the "COMMIT mark and write the buffer to the binlog.
+ */
{
- sql_print_error(ER(ER_ERROR_ON_WRITE), cache->file_name, errno);
- goto err;
+ Query_log_event qinfo(thd, "BEGIN", 5, TRUE);
+ /*
+ Now this Query_log_event has artificial log_pos 0. It must be adjusted
+ to reflect the real position in the log. Not doing it would confuse the
+ slave: it would prevent this one from knowing where he is in the
+ master's binlog, which would result in wrong positions being shown to
+ the user, MASTER_POS_WAIT undue waiting etc.
+ */
+ qinfo.set_log_pos(this);
+ if (qinfo.write(&log_file))
+ goto err;
}
+ /* Read from the file used to cache the queries .*/
+ if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
+ goto err;
length=my_b_bytes_in_cache(cache);
do
{
- if (my_b_write(&log_file, cache->rc_pos, length))
- {
- if (!write_error)
- sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
+ /* Write data to the binary log file */
+ if (my_b_write(&log_file, cache->read_pos, length))
goto err;
- }
- cache->rc_pos=cache->rc_end; // Mark buffer used up
+ cache->read_pos=cache->read_end; // Mark buffer used up
} while ((length=my_b_fill(cache)));
- if (flush_io_cache(&log_file))
+
+ /*
+ We write the command "COMMIT" as the last SQL command in the
+ binlog segment cached for this transaction
+ */
+
{
- if (!write_error)
- sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
- goto err;
+ Query_log_event qinfo(thd,
+ commit_or_rollback ? "COMMIT" : "ROLLBACK",
+ commit_or_rollback ? 6 : 8,
+ TRUE);
+ qinfo.set_log_pos(this);
+ if (qinfo.write(&log_file) || flush_io_cache(&log_file))
+ goto err;
}
if (cache->error) // Error on read
{
sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
+ write_error=1; // Don't give more errors
goto err;
}
- error = ha_report_binlog_offset_and_commit(thd, log_file_name,
- log_file.pos_in_file);
- if (error)
+ if ((ha_report_binlog_offset_and_commit(thd, log_file_name,
+ log_file.pos_in_file)))
goto err;
+ signal_update();
+ DBUG_PRINT("info",("max_size: %lu",max_size));
+ if (my_b_tell(&log_file) >= (my_off_t) max_size)
+ {
+ pthread_mutex_lock(&LOCK_index);
+ new_file(0); // inside mutex
+ pthread_mutex_unlock(&LOCK_index);
+ }
- if (my_b_tell(&log_file) >= (my_off_t) max_binlog_size)
- new_file(1); // inside mutex
}
- error=0;
-
-err:
- if (error)
- write_error=1;
- else
- VOID(pthread_cond_broadcast(&COND_binlog_update));
-
VOID(pthread_mutex_unlock(&LOCK_log));
-
- return error;
-}
+ /* Flush the transactional handler log file now that we have released
+ LOCK_log; the flush is placed here to eliminate the bottleneck on the
+ group commit */
-bool MYSQL_LOG::write(Load_log_event* event_info)
-{
- bool error=0;
- bool should_rotate = 0;
-
- if (inited)
+ ha_commit_complete(thd);
+
+ DBUG_RETURN(0);
+
+err:
+ if (!write_error)
{
- VOID(pthread_mutex_lock(&LOCK_log));
- if (is_open())
- {
- THD *thd=event_info->thd;
- if ((thd->options & OPTION_BIN_LOG) ||
- !(thd->master_access & PROCESS_ACL))
- {
- if (event_info->write(&log_file) || flush_io_cache(&log_file))
- {
- if (!write_error)
- sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
- error=write_error=1;
- }
- should_rotate = (my_b_tell(&log_file) >= max_binlog_size);
- VOID(pthread_cond_broadcast(&COND_binlog_update));
- }
- }
-
- if(should_rotate)
- new_file(1); // inside mutex
-
- VOID(pthread_mutex_unlock(&LOCK_log));
+ write_error= 1;
+ sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
}
-
-
- return error;
+ VOID(pthread_mutex_unlock(&LOCK_log));
+ DBUG_RETURN(1);
}
-/* Write update log in a format suitable for incremental backup */
+/*
+ Write update log in a format suitable for incremental backup
+
+ NOTE
+ - This code should be deleted in MySQL 5,0 as the binary log
+ is a full replacement for the update log.
+
+*/
bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
- time_t query_start)
+ time_t query_start_arg)
{
bool error=0;
+ time_t current_time;
+ if (!is_open())
+ return 0;
+ VOID(pthread_mutex_lock(&LOCK_log));
if (is_open())
- {
- time_t current_time;
- VOID(pthread_mutex_lock(&LOCK_log));
- if (is_open())
- { // Safety agains reopen
- int tmp_errno=0;
- char buff[80],*end;
- end=buff;
- if (!(thd->options & OPTION_UPDATE_LOG) &&
- (thd->master_access & PROCESS_ACL))
- {
- VOID(pthread_mutex_unlock(&LOCK_log));
- return 0;
- }
- if ((specialflag & SPECIAL_LONG_LOG_FORMAT) || query_start)
- {
- current_time=time(NULL);
- if (current_time != last_time)
- {
- last_time=current_time;
- struct tm tm_tmp;
- struct tm *start;
- localtime_r(&current_time,&tm_tmp);
- start=&tm_tmp;
- /* Note that my_b_write() assumes it knows the length for this */
- sprintf(buff,"# Time: %02d%02d%02d %2d:%02d:%02d\n",
- start->tm_year % 100,
- start->tm_mon+1,
- start->tm_mday,
- start->tm_hour,
- start->tm_min,
- start->tm_sec);
- if (my_b_write(&log_file, (byte*) buff,24))
- tmp_errno=errno;
- }
- if (my_b_printf(&log_file, "# User@Host: %s[%s] @ %s [%s]\n",
- thd->priv_user,
- thd->user,
- thd->host ? thd->host : "",
- thd->ip ? thd->ip : "") == (uint) -1)
- tmp_errno=errno;
- }
- if (query_start)
- {
- /* For slow query log */
- if (my_b_printf(&log_file,
- "# Query_time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n",
- (ulong) (current_time - query_start),
- (ulong) (thd->time_after_lock - query_start),
- (ulong) thd->sent_row_count,
- (ulong) thd->examined_row_count) == (uint) -1)
- tmp_errno=errno;
- }
- if (thd->db && strcmp(thd->db,db))
- { // Database changed
- if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
- tmp_errno=errno;
- strmov(db,thd->db);
- }
- if (thd->last_insert_id_used)
- {
- end=strmov(end,",last_insert_id=");
- end=longlong10_to_str((longlong) thd->current_insert_id,end,-10);
- }
- // Save value if we do an insert.
- if (thd->insert_id_used)
- {
- if (specialflag & SPECIAL_LONG_LOG_FORMAT)
- {
- end=strmov(end,",insert_id=");
- end=longlong10_to_str((longlong) thd->last_insert_id,end,-10);
- }
- }
- if (thd->query_start_used)
+ { // Safety agains reopen
+ int tmp_errno=0;
+ char buff[80],*end;
+ end=buff;
+ if (!(thd->options & OPTION_UPDATE_LOG) &&
+ (thd->master_access & SUPER_ACL))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_log));
+ return 0;
+ }
+ if ((specialflag & SPECIAL_LONG_LOG_FORMAT) || query_start_arg)
+ {
+ current_time=time(NULL);
+ if (current_time != last_time)
{
- if (query_start != thd->query_start())
- {
- query_start=thd->query_start();
- end=strmov(end,",timestamp=");
- end=int10_to_str((long) query_start,end,10);
- }
+ last_time=current_time;
+ struct tm tm_tmp;
+ struct tm *start;
+ localtime_r(&current_time,&tm_tmp);
+ start=&tm_tmp;
+ /* Note that my_b_write() assumes it knows the length for this */
+ sprintf(buff,"# Time: %02d%02d%02d %2d:%02d:%02d\n",
+ start->tm_year % 100,
+ start->tm_mon+1,
+ start->tm_mday,
+ start->tm_hour,
+ start->tm_min,
+ start->tm_sec);
+ if (my_b_write(&log_file, (byte*) buff,24))
+ tmp_errno=errno;
}
- if (end != buff)
+ if (my_b_printf(&log_file, "# User@Host: %s[%s] @ %s [%s]\n",
+ thd->priv_user,
+ thd->user,
+ thd->host ? thd->host : "",
+ thd->ip ? thd->ip : "") == (uint) -1)
+ tmp_errno=errno;
+ }
+ if (query_start_arg)
+ {
+ /* For slow query log */
+ if (my_b_printf(&log_file,
+ "# Query_time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n",
+ (ulong) (current_time - query_start_arg),
+ (ulong) (thd->time_after_lock - query_start_arg),
+ (ulong) thd->sent_row_count,
+ (ulong) thd->examined_row_count) == (uint) -1)
+ tmp_errno=errno;
+ }
+ if (thd->db && strcmp(thd->db,db))
+ { // Database changed
+ if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
+ tmp_errno=errno;
+ strmov(db,thd->db);
+ }
+ if (thd->last_insert_id_used)
+ {
+ end=strmov(end,",last_insert_id=");
+ end=longlong10_to_str((longlong) thd->current_insert_id,end,-10);
+ }
+ // Save value if we do an insert.
+ if (thd->insert_id_used)
+ {
+ if (specialflag & SPECIAL_LONG_LOG_FORMAT)
{
- *end++=';';
- *end='\n';
- if (my_b_write(&log_file, (byte*) "SET ",4) ||
- my_b_write(&log_file, (byte*) buff+1,(uint) (end-buff)))
- tmp_errno=errno;
+ end=strmov(end,",insert_id=");
+ end=longlong10_to_str((longlong) thd->last_insert_id,end,-10);
}
- if (!query)
+ }
+ if (thd->query_start_used)
+ {
+ if (query_start_arg != thd->query_start())
{
- end=strxmov(buff, "# administrator command: ",
- command_name[thd->command], NullS);
- query_length=(ulong) (end-buff);
- query=buff;
+ query_start_arg=thd->query_start();
+ end=strmov(end,",timestamp=");
+ end=int10_to_str((long) query_start_arg,end,10);
}
- if (my_b_write(&log_file, (byte*) query,query_length) ||
- my_b_write(&log_file, (byte*) ";\n",2) ||
- flush_io_cache(&log_file))
- tmp_errno=errno;
- if (tmp_errno)
+ }
+ if (end != buff)
+ {
+ *end++=';';
+ *end='\n';
+ if (my_b_write(&log_file, (byte*) "SET ",4) ||
+ my_b_write(&log_file, (byte*) buff+1,(uint) (end-buff)))
+ tmp_errno=errno;
+ }
+ if (!query)
+ {
+ end=strxmov(buff, "# administrator command: ",
+ command_name[thd->command], NullS);
+ query_length=(ulong) (end-buff);
+ query=buff;
+ }
+ if (my_b_write(&log_file, (byte*) query,query_length) ||
+ my_b_write(&log_file, (byte*) ";\n",2) ||
+ flush_io_cache(&log_file))
+ tmp_errno=errno;
+ if (tmp_errno)
+ {
+ error=1;
+ if (! write_error)
{
- error=1;
- if (! write_error)
- {
- write_error=1;
- sql_print_error(ER(ER_ERROR_ON_WRITE),name,error);
- }
+ write_error=1;
+ sql_print_error(ER(ER_ERROR_ON_WRITE),name,error);
}
}
- VOID(pthread_mutex_unlock(&LOCK_log));
}
+ VOID(pthread_mutex_unlock(&LOCK_log));
return error;
}
-void MYSQL_LOG::close(bool exiting)
+/*
+ Wait until we get a signal that the binary log has been updated
+
+ SYNOPSIS
+ wait_for_update()
+ thd Thread variable
+ master_or_slave If 0, the caller is the Binlog_dump thread from master;
+ if 1, the caller is the SQL thread from the slave. This
+ influences only thd->proc_info.
+
+ NOTES
+ One must have a lock on LOCK_log before calling this function.
+ This lock will be freed before return!
+
+ The reason for the above is that for enter_cond() / exit_cond() to
+ work the mutex must be got before enter_cond() but releases before
+ exit_cond().
+ If you don't do it this way, you will get a deadlock in THD::awake()
+*/
+
+
+void MYSQL_LOG:: wait_for_update(THD* thd, bool master_or_slave)
+{
+ safe_mutex_assert_owner(&LOCK_log);
+ const char* old_msg = thd->enter_cond(&update_cond, &LOCK_log,
+ master_or_slave ?
+ "Has read all relay log; waiting for \
+the I/O slave thread to update it" :
+ "Has sent all binlog to slave; \
+waiting for binlog to be updated");
+ pthread_cond_wait(&update_cond, &LOCK_log);
+ pthread_mutex_unlock(&LOCK_log); // See NOTES
+ thd->exit_cond(old_msg);
+}
+
+
+/*
+ Close the log file
+
+ SYNOPSIS
+ close()
+ exiting Bitmask for one or more of the following bits:
+ LOG_CLOSE_INDEX if we should close the index file
+ LOG_CLOSE_TO_BE_OPENED if we intend to call open
+ at once after close.
+ LOG_CLOSE_STOP_EVENT write a 'stop' event to the log
+
+ NOTES
+ One can do an open on the object at once after doing a close.
+ The internal structures are not freed until cleanup() is called
+*/
+
+void MYSQL_LOG::close(uint exiting)
{ // One can't set log_type here!
- if (is_open())
+ DBUG_ENTER("MYSQL_LOG::close");
+ DBUG_PRINT("enter",("exiting: %d", (int) exiting));
+ if (log_type != LOG_CLOSED && log_type != LOG_TO_BE_OPENED)
{
- File file=log_file.file;
- if (log_type == LOG_BIN)
+ if (log_type == LOG_BIN && !no_auto_events &&
+ (exiting & LOG_CLOSE_STOP_EVENT))
{
Stop_log_event s;
+ s.set_log_pos(this);
s.write(&log_file);
- VOID(pthread_cond_broadcast(&COND_binlog_update));
+ signal_update();
}
end_io_cache(&log_file);
- if (my_close(file,MYF(0)) < 0 && ! write_error)
+ if (my_close(log_file.file,MYF(0)) < 0 && ! write_error)
{
write_error=1;
- sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
+ sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
}
}
- if (exiting && index_file >= 0)
+
+ /*
+ The following test is needed even if is_open() is not set, as we may have
+ called a not complete close earlier and the index file is still open.
+ */
+
+ if ((exiting & LOG_CLOSE_INDEX) && my_b_inited(&index_file))
{
- if (my_close(index_file,MYF(0)) < 0 && ! write_error)
+ end_io_cache(&index_file);
+ if (my_close(index_file.file, MYF(0)) < 0 && ! write_error)
{
- write_error=1;
- sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
+ write_error= 1;
+ sql_print_error(ER(ER_ERROR_ON_WRITE), index_file_name, errno);
}
- index_file=-1;
- log_type=LOG_CLOSED;
}
+ log_type= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED;
safeFree(name);
+ DBUG_VOID_RETURN;
+}
+
+
+void MYSQL_LOG::set_max_size(ulong max_size_arg)
+{
+ /*
+ We need to take locks, otherwise this may happen:
+ new_file() is called, calls open(old_max_size), then before open() starts,
+ set_max_size() sets max_size to max_size_arg, then open() starts and
+ uses the old_max_size argument, so max_size_arg has been overwritten and
+ it's like if the SET command was never run.
+ */
+ DBUG_ENTER("MYSQL_LOG::set_max_size");
+ pthread_mutex_lock(&LOCK_log);
+ if (is_open())
+ max_size= max_size_arg;
+ pthread_mutex_unlock(&LOCK_log);
+ DBUG_VOID_RETURN;
}
- /* Check if a string is a valid number */
- /* Output: TRUE -> number */
+/*
+ Check if a string is a valid number
+
+ SYNOPSIS
+ test_if_number()
+ str String to test
+ res Store value here
+ allow_wildcards Set to 1 if we should ignore '%' and '_'
+
+ NOTE
+ For the moment the allow_wildcards argument is not used
+ Should be move to some other file.
+
+ RETURN VALUES
+ 1 String is a number
+ 0 Error
+*/
static bool test_if_number(register const char *str,
long *res, bool allow_wildcards)
@@ -1101,7 +1716,6 @@ void sql_print_error(const char *format,...)
}
-
void sql_perror(const char *message)
{
#ifdef HAVE_STRERROR
@@ -1110,3 +1724,49 @@ void sql_perror(const char *message)
perror(message);
#endif
}
+
+bool flush_error_log()
+{
+ bool result=0;
+ if (opt_error_log)
+ {
+ char err_renamed[FN_REFLEN], *end;
+ end= strmake(err_renamed,log_error_file,FN_REFLEN-4);
+ strmov(end, "-old");
+#ifdef __WIN__
+ char err_temp[FN_REFLEN+4];
+ /*
+ On Windows is necessary a temporary file for to rename
+ the current error file.
+ */
+ strmov(strmov(err_temp, err_renamed),"-tmp");
+ (void) my_delete(err_temp, MYF(0));
+ if (freopen(err_temp,"a+",stdout))
+ {
+ freopen(err_temp,"a+",stderr);
+ (void) my_delete(err_renamed, MYF(0));
+ my_rename(log_error_file,err_renamed,MYF(0));
+ if (freopen(log_error_file,"a+",stdout))
+ freopen(log_error_file,"a+",stderr);
+ int fd, bytes;
+ char buf[IO_SIZE];
+ if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
+ {
+ while ((bytes = (int) my_read(fd, (byte*) buf, IO_SIZE, MYF(0))) > 0)
+ my_fwrite(stderr, (byte*) buf, (uint) strlen(buf),MYF(0));
+ my_close(fd, MYF(0));
+ }
+ (void) my_delete(err_temp, MYF(0));
+ }
+ else
+ result= 1;
+#else
+ my_rename(log_error_file,err_renamed,MYF(0));
+ if (freopen(log_error_file,"a+",stdout))
+ freopen(log_error_file,"a+",stderr);
+ else
+ result= 1;
+#endif
+ }
+ return result;
+}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index b89f3c151a7..cafd1666eac 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -20,39 +20,446 @@
#pragma implementation // gcc: Class implementation
#endif
#include "mysql_priv.h"
+#include "slave.h"
+#include <my_dir.h>
#endif /* MYSQL_CLIENT */
+#include <assert.h>
-static void pretty_print_char(FILE* file, int c)
+#ifdef MYSQL_CLIENT
+static void pretty_print_str(FILE* file, char* str, int len)
{
+ char* end = str + len;
fputc('\'', file);
- switch(c) {
- case '\n': fprintf(file, "\\n"); break;
- case '\r': fprintf(file, "\\r"); break;
- case '\\': fprintf(file, "\\\\"); break;
- case '\b': fprintf(file, "\\b"); break;
- case '\'': fprintf(file, "\\'"); break;
- case 0 : fprintf(file, "\\0"); break;
- default:
- fputc(c, file);
- break;
+ while (str < end)
+ {
+ char c;
+ switch ((c=*str++)) {
+ case '\n': fprintf(file, "\\n"); break;
+ case '\r': fprintf(file, "\\r"); break;
+ case '\\': fprintf(file, "\\\\"); break;
+ case '\b': fprintf(file, "\\b"); break;
+ case '\t': fprintf(file, "\\t"); break;
+ case '\'': fprintf(file, "\\'"); break;
+ case 0 : fprintf(file, "\\0"); break;
+ default:
+ fputc(c, file);
+ break;
+ }
}
fputc('\'', file);
}
+#endif
+
+#ifndef MYSQL_CLIENT
+
+inline int ignored_error_code(int err_code)
+{
+ return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
+ (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
+}
+
+
+static void pretty_print_str(String* packet, char* str, int len)
+{
+ char* end = str + len;
+ packet->append('\'');
+ while (str < end)
+ {
+ char c;
+ switch ((c=*str++)) {
+ case '\n': packet->append( "\\n"); break;
+ case '\r': packet->append( "\\r"); break;
+ case '\\': packet->append( "\\\\"); break;
+ case '\b': packet->append( "\\b"); break;
+ case '\t': packet->append( "\\t"); break;
+ case '\'': packet->append( "\\'"); break;
+ case 0 : packet->append( "\\0"); break;
+ default:
+ packet->append((char)c);
+ break;
+ }
+ }
+ packet->append('\'');
+}
+
+
+static inline char* slave_load_file_stem(char*buf, uint file_id,
+ int event_server_id)
+{
+ fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
+ buf = strend(buf);
+ buf = int10_to_str(::server_id, buf, 10);
+ *buf++ = '-';
+ buf = int10_to_str(event_server_id, buf, 10);
+ *buf++ = '-';
+ return int10_to_str(file_id, buf, 10);
+}
+
+#endif
+
+const char* Log_event::get_type_str()
+{
+ switch(get_type_code()) {
+ case START_EVENT: return "Start";
+ case STOP_EVENT: return "Stop";
+ case QUERY_EVENT: return "Query";
+ case ROTATE_EVENT: return "Rotate";
+ case INTVAR_EVENT: return "Intvar";
+ case LOAD_EVENT: return "Load";
+ case NEW_LOAD_EVENT: return "New_load";
+ case SLAVE_EVENT: return "Slave";
+ case CREATE_FILE_EVENT: return "Create_file";
+ case APPEND_BLOCK_EVENT: return "Append_block";
+ case DELETE_FILE_EVENT: return "Delete_file";
+ case EXEC_LOAD_EVENT: return "Exec_load";
+ default: /* impossible */ return "Unknown";
+ }
+}
+
+#ifndef MYSQL_CLIENT
+Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
+ :log_pos(0), temp_buf(0), exec_time(0), cached_event_len(0),
+ flags(flags_arg), thd(thd_arg)
+{
+ server_id = thd->server_id;
+ when = thd->start_time;
+ cache_stmt= (using_trans &&
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
+}
+
+/*
+ This minimal constructor is for when you are not even sure that there is a
+ valid THD. For example in the server when we are shutting down or flushing
+ logs after receiving a SIGHUP (then we must write a Rotate to the binlog but
+ we have no THD, so we need this minimal constructor).
+*/
+Log_event::Log_event()
+ :temp_buf(0), exec_time(0), cached_event_len(0), flags(0), cache_stmt(0),
+ thd(0)
+{
+ server_id = ::server_id;
+ when = time(NULL);
+ log_pos=0;
+}
+
+/*
+ Delete all temporary files used for SQL_LOAD.
+*/
+
+static void cleanup_load_tmpdir()
+{
+ MY_DIR *dirp;
+ FILEINFO *file;
+ uint i;
+ char fname[FN_REFLEN];
+ char prefbuf[31];
+ char *p;
+
+ if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
+ return;
+
+ /*
+ When we are deleting temporary files, we should only remove
+ the files associated with the server id of our server.
+ We don't use event_server_id here because since we've disabled
+ direct binlogging of Create_file/Append_file/Exec_load events
+ we cannot meet Start_log event in the middle of events from one
+ LOAD DATA.
+ */
+ p= strmake(prefbuf,"SQL_LOAD-",9);
+ p= int10_to_str(::server_id, p, 10);
+ *(p++)= '-';
+ *p= 0;
+
+ for (i=0 ; i < (uint)dirp->number_off_files; i++)
+ {
+ file=dirp->dir_entry+i;
+ if (is_prefix(file->name, prefbuf))
+ {
+ fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
+ my_delete(fname, MYF(0));
+ }
+ }
+
+ my_dirend(dirp);
+}
+#endif
+
+
+Log_event::Log_event(const char* buf, bool old_format)
+ :temp_buf(0), cached_event_len(0), cache_stmt(0)
+{
+ when = uint4korr(buf);
+ server_id = uint4korr(buf + SERVER_ID_OFFSET);
+ if (old_format)
+ {
+ log_pos=0;
+ flags=0;
+ }
+ else
+ {
+ log_pos = uint4korr(buf + LOG_POS_OFFSET);
+ flags = uint2korr(buf + FLAGS_OFFSET);
+ }
+#ifndef MYSQL_CLIENT
+ thd = 0;
+#endif
+}
+
+
+#ifndef MYSQL_CLIENT
+
+int Log_event::exec_event(struct st_relay_log_info* rli)
+{
+ /*
+ rli is null when (as far as I (Guilhem) know)
+ the caller is
+ Load_log_event::exec_event *and* that one is called from
+ Execute_load_log_event::exec_event.
+ In this case, we don't do anything here ;
+ Execute_load_log_event::exec_event will call Log_event::exec_event
+ again later with the proper rli.
+ Strictly speaking, if we were sure that rli is null
+ only in the case discussed above, 'if (rli)' is useless here.
+ But as we are not 100% sure, keep it for now.
+ */
+ if (rli)
+ {
+ if (rli->inside_transaction)
+ rli->inc_pending(get_event_len());
+ else
+ {
+ rli->inc_pos(get_event_len(),log_pos);
+ flush_relay_log_info(rli);
+ }
+ }
+ return 0;
+}
+
+void Log_event::pack_info(String* packet)
+{
+ net_store_data(packet, "", 0);
+}
+
+void Query_log_event::pack_info(String* packet)
+{
+ char buf[256];
+ String tmp(buf, sizeof(buf));
+ tmp.length(0);
+ if (db && db_len)
+ {
+ tmp.append("use `",5);
+ tmp.append(db, db_len);
+ tmp.append("`; ", 3);
+ }
+
+ if (query && q_len)
+ tmp.append(query, q_len);
+ net_store_data(packet, (char*)tmp.ptr(), tmp.length());
+}
+
+void Start_log_event::pack_info(String* packet)
+{
+ char buf1[256];
+ String tmp(buf1, sizeof(buf1));
+ tmp.length(0);
+ char buf[22];
+
+ tmp.append("Server ver: ");
+ tmp.append(server_version);
+ tmp.append(", Binlog ver: ");
+ tmp.append(llstr(binlog_version, buf));
+ net_store_data(packet, tmp.ptr(), tmp.length());
+}
+
+void Load_log_event::pack_info(String* packet)
+{
+ char buf[256];
+ String tmp(buf, sizeof(buf));
+ tmp.length(0);
+ if (db && db_len)
+ {
+ tmp.append("use ");
+ tmp.append(db, db_len);
+ tmp.append("; ", 2);
+ }
+
+ tmp.append("LOAD DATA INFILE '");
+ tmp.append(fname, fname_len);
+ tmp.append("' ", 2);
+ if (sql_ex.opt_flags & REPLACE_FLAG)
+ tmp.append(" REPLACE ");
+ else if (sql_ex.opt_flags & IGNORE_FLAG)
+ tmp.append(" IGNORE ");
+
+ tmp.append("INTO TABLE ");
+ tmp.append(table_name);
+ if (sql_ex.field_term_len)
+ {
+ tmp.append(" FIELDS TERMINATED BY ");
+ pretty_print_str(&tmp, sql_ex.field_term, sql_ex.field_term_len);
+ }
+
+ if (sql_ex.enclosed_len)
+ {
+ if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG )
+ tmp.append(" OPTIONALLY ");
+ tmp.append( " ENCLOSED BY ");
+ pretty_print_str(&tmp, sql_ex.enclosed, sql_ex.enclosed_len);
+ }
+
+ if (sql_ex.escaped_len)
+ {
+ tmp.append( " ESCAPED BY ");
+ pretty_print_str(&tmp, sql_ex.escaped, sql_ex.escaped_len);
+ }
+
+ bool line_lexem_added= false;
+ if (sql_ex.line_term_len)
+ {
+ tmp.append(" LINES TERMINATED BY ");
+ pretty_print_str(&tmp, sql_ex.line_term, sql_ex.line_term_len);
+ line_lexem_added= true;
+ }
+
+ if (sql_ex.line_start_len)
+ {
+ if (!line_lexem_added)
+ tmp.append(" LINES");
+ tmp.append(" STARTING BY ");
+ pretty_print_str(&tmp, sql_ex.line_start, sql_ex.line_start_len);
+ }
+
+ if ((long) skip_lines > 0)
+ {
+ char nr_buff[32], *end;
+ tmp.append( " IGNORE ");
+ end= longlong10_to_str((longlong) skip_lines, nr_buff, 10);
+ tmp.append(nr_buff, (uint) (end-nr_buff));
+ tmp.append( " LINES");
+ }
+
+ if (num_fields)
+ {
+ uint i;
+ const char* field = fields;
+ tmp.append(" (");
+ for (i = 0; i < num_fields; i++)
+ {
+ if (i)
+ tmp.append(" ,");
+ tmp.append( field);
+
+ field += field_lens[i] + 1;
+ }
+ tmp.append(')');
+ }
+
+ net_store_data(packet, tmp.ptr(), tmp.length());
+}
+
+void Rotate_log_event::pack_info(String* packet)
+{
+ char buf1[256], buf[22];
+ String tmp(buf1, sizeof(buf1));
+ tmp.length(0);
+ tmp.append(new_log_ident, ident_len);
+ tmp.append(";pos=");
+ tmp.append(llstr(pos,buf));
+ if (flags & LOG_EVENT_FORCED_ROTATE_F)
+ tmp.append("; forced by master");
+ net_store_data(packet, tmp.ptr(), tmp.length());
+}
+
+void Intvar_log_event::pack_info(String* packet)
+{
+ char buf1[256], buf[22];
+ String tmp(buf1, sizeof(buf1));
+ tmp.length(0);
+ tmp.append(get_var_type_name());
+ tmp.append('=');
+ tmp.append(llstr(val, buf));
+ net_store_data(packet, tmp.ptr(), tmp.length());
+}
+
+void Rand_log_event::pack_info(String* packet)
+{
+ char buf1[256], *pos;
+ pos=strmov(buf1,"rand_seed1=");
+ pos=int10_to_str((long) seed1, pos, 10);
+ pos=strmov(pos, ",rand_seed2=");
+ pos=int10_to_str((long) seed2, pos, 10);
+ net_store_data(packet, buf1, (uint) (pos-buf1));
+}
+
+void Slave_log_event::pack_info(String* packet)
+{
+ char buf1[256], buf[22], *end;
+ String tmp(buf1, sizeof(buf1));
+ tmp.length(0);
+ tmp.append("host=");
+ tmp.append(master_host);
+ tmp.append(",port=");
+ end= int10_to_str((long) master_port, buf, 10);
+ tmp.append(buf, (uint32) (end-buf));
+ tmp.append(",log=");
+ tmp.append(master_log);
+ tmp.append(",pos=");
+ tmp.append(llstr(master_pos,buf));
+ net_store_data(packet, tmp.ptr(), tmp.length());
+}
+
+
+void Log_event::init_show_field_list(List<Item>* field_list)
+{
+ field_list->push_back(new Item_empty_string("Log_name", 20));
+ field_list->push_back(new Item_empty_string("Pos", 20));
+ field_list->push_back(new Item_empty_string("Event_type", 20));
+ field_list->push_back(new Item_empty_string("Server_id", 20));
+ field_list->push_back(new Item_empty_string("Orig_log_pos", 20));
+ field_list->push_back(new Item_empty_string("Info", 20));
+}
+
+/*
+ * only called by SHOW BINLOG EVENTS
+ */
+int Log_event::net_send(THD* thd_arg, const char* log_name, my_off_t pos)
+{
+ String* packet = &thd_arg->packet;
+ const char* p = strrchr(log_name, FN_LIBCHAR);
+ const char* event_type;
+ if (p)
+ log_name = p + 1;
+
+ packet->length(0);
+ net_store_data(packet, log_name, strlen(log_name));
+ net_store_data(packet, (longlong) pos);
+ event_type = get_type_str();
+ net_store_data(packet, event_type, strlen(event_type));
+ net_store_data(packet, server_id);
+ net_store_data(packet, (longlong) log_pos);
+ pack_info(packet);
+ return my_net_write(&thd_arg->net, (char*) packet->ptr(), packet->length());
+}
+
+#endif /* MYSQL_CLIENT */
+
int Query_log_event::write(IO_CACHE* file)
{
return query ? Log_event::write(file) : -1;
}
+
int Log_event::write(IO_CACHE* file)
{
return (write_header(file) || write_data(file)) ? -1 : 0;
}
+
int Log_event::write_header(IO_CACHE* file)
{
- // make sure to change this when the header gets bigger
char buf[LOG_EVENT_HEADER_LEN];
char* pos = buf;
int4store(pos, (ulong) when); // timestamp
@@ -63,7 +470,11 @@ int Log_event::write_header(IO_CACHE* file)
long tmp=get_data_size() + LOG_EVENT_HEADER_LEN;
int4store(pos, tmp);
pos += 4;
- return (my_b_write(file, (byte*) buf, (uint) (pos - buf)));
+ int4store(pos, log_pos);
+ pos += 4;
+ int2store(pos, flags);
+ pos += 2;
+ return (my_b_safe_write(file, (byte*) buf, (uint) (pos - buf)));
}
#ifndef MYSQL_CLIENT
@@ -72,215 +483,234 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock)
{
ulong data_len;
+ int result=0;
char buf[LOG_EVENT_HEADER_LEN];
+ DBUG_ENTER("read_log_event");
+
if (log_lock)
pthread_mutex_lock(log_lock);
if (my_b_read(file, (byte*) buf, sizeof(buf)))
{
- if (log_lock) pthread_mutex_unlock(log_lock);
- // if the read hits eof, we must report it as eof
- // so the caller will know it can go into cond_wait to be woken up
- // on the next update to the log
- if(!file->error) return LOG_READ_EOF;
- return file->error > 0 ? LOG_READ_TRUNC: LOG_READ_IO;
+ /*
+ If the read hits eof, we must report it as eof so the caller
+ will know it can go into cond_wait to be woken up on the next
+ update to the log.
+ */
+ DBUG_PRINT("error",("file->error: %d", file->error));
+ if (!file->error)
+ result= LOG_READ_EOF;
+ else
+ result= (file->error > 0 ? LOG_READ_TRUNC : LOG_READ_IO);
+ goto end;
}
- data_len = uint4korr(buf + EVENT_LEN_OFFSET);
- if (data_len < LOG_EVENT_HEADER_LEN || data_len > max_allowed_packet)
+ data_len= uint4korr(buf + EVENT_LEN_OFFSET);
+ if (data_len < LOG_EVENT_HEADER_LEN ||
+ data_len > current_thd->variables.max_allowed_packet)
{
- if (log_lock) pthread_mutex_unlock(log_lock);
- return (data_len < LOG_EVENT_HEADER_LEN) ? LOG_READ_BOGUS :
- LOG_READ_TOO_LARGE;
+ DBUG_PRINT("error",("data_len: %ld", data_len));
+ result= ((data_len < LOG_EVENT_HEADER_LEN) ? LOG_READ_BOGUS :
+ LOG_READ_TOO_LARGE);
+ goto end;
}
packet->append(buf, sizeof(buf));
- data_len -= LOG_EVENT_HEADER_LEN;
+ data_len-= LOG_EVENT_HEADER_LEN;
if (data_len)
{
if (packet->append(file, data_len))
{
- if(log_lock)
- pthread_mutex_unlock(log_lock);
- // here we should never hit eof in a non-error condtion
- // eof means we are reading the event partially, which should
- // never happen
- return file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
+ /*
+ Here we should never hit EOF in a non-error condition.
+ EOF means we are reading the event partially, which should
+ never happen.
+ */
+ result= file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
+ /* Implicit goto end; */
}
}
- if (log_lock) pthread_mutex_unlock(log_lock);
- return 0;
+
+end:
+ if (log_lock)
+ pthread_mutex_unlock(log_lock);
+ DBUG_RETURN(result);
}
#endif // MYSQL_CLIENT
#ifndef MYSQL_CLIENT
-#define UNLOCK_MUTEX if(log_lock) pthread_mutex_unlock(log_lock);
+#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
+#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
+#define max_allowed_packet current_thd->variables.max_allowed_packet
#else
#define UNLOCK_MUTEX
+#define LOCK_MUTEX
#endif
// allocates memory - the caller is responsible for clean-up
#ifndef MYSQL_CLIENT
-Log_event* Log_event::read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock)
+Log_event* Log_event::read_log_event(IO_CACHE* file,
+ pthread_mutex_t* log_lock,
+ bool old_format)
#else
-Log_event* Log_event::read_log_event(IO_CACHE* file)
+Log_event* Log_event::read_log_event(IO_CACHE* file, bool old_format)
#endif
{
- time_t timestamp;
- uint32 server_id;
-
- char buf[LOG_EVENT_HEADER_LEN-4];
-#ifndef MYSQL_CLIENT
- if(log_lock) pthread_mutex_lock(log_lock);
-#endif
- if (my_b_read(file, (byte *) buf, sizeof(buf)))
+ char head[LOG_EVENT_HEADER_LEN];
+ uint header_size= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
+
+ LOCK_MUTEX;
+ if (my_b_read(file, (byte *) head, header_size))
{
- UNLOCK_MUTEX
- return NULL;
+ UNLOCK_MUTEX;
+ return 0;
}
- timestamp = uint4korr(buf);
- server_id = uint4korr(buf + 5);
-
- switch(buf[EVENT_TYPE_OFFSET])
- {
- case QUERY_EVENT:
- {
- Query_log_event* q = new Query_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- if (!q->query)
- {
- delete q;
- q=NULL;
- }
- return q;
- }
-
- case LOAD_EVENT:
+
+ uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
+ char *buf= 0;
+ const char *error= 0;
+ Log_event *res= 0;
+
+ if (data_len > max_allowed_packet)
{
- Load_log_event* l = new Load_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- if (!l->table_name)
- {
- delete l;
- l=NULL;
- }
- return l;
+ error = "Event too big";
+ goto err;
}
-
- case ROTATE_EVENT:
+ if (data_len < header_size)
{
- Rotate_log_event* r = new Rotate_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- if (!r->new_log_ident)
- {
- delete r;
- r=NULL;
- }
- return r;
+ error = "Event too small";
+ goto err;
}
- case INTVAR_EVENT:
+ // some events use the extra byte to null-terminate strings
+ if (!(buf = my_malloc(data_len+1, MYF(MY_WME))))
{
- Intvar_log_event* e = new Intvar_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- if (e->type == INVALID_INT_EVENT)
- {
- delete e;
- e=NULL;
- }
- return e;
+ error = "Out of memory";
+ goto err;
}
-
- case START_EVENT:
- {
- Start_log_event* e = new Start_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- return e;
- }
- case STOP_EVENT:
- {
- Stop_log_event* e = new Stop_log_event(file, timestamp, server_id);
- UNLOCK_MUTEX
- return e;
- }
- default:
- break;
+ buf[data_len] = 0;
+ memcpy(buf, head, header_size);
+ if (my_b_read(file, (byte*) buf + header_size, data_len - header_size))
+ {
+ error = "read error";
+ goto err;
}
+ if ((res = read_log_event(buf, data_len, &error, old_format)))
+ res->register_temp_buf(buf);
- // default
- UNLOCK_MUTEX
- return NULL;
+err:
+ UNLOCK_MUTEX;
+ if (error)
+ {
+ sql_print_error("\
+Error in Log_event::read_log_event(): '%s', data_len: %d, event_type: %d",
+ error,data_len,head[EVENT_TYPE_OFFSET]);
+ my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
+ /*
+ The SQL slave thread will check if file->error<0 to know
+ if there was an I/O error. Even if there is no "low-level" I/O errors
+ with 'file', any of the high-level above errors is worrying
+ enough to stop the SQL thread now ; as we are skipping the current event,
+ going on with reading and successfully executing other events can
+ only corrupt the slave's databases. So stop.
+ */
+ file->error= -1;
+ }
+ return res;
}
-Log_event* Log_event::read_log_event(const char* buf, int event_len)
+
+Log_event* Log_event::read_log_event(const char* buf, int event_len,
+ const char **error, bool old_format)
{
- if(event_len < EVENT_LEN_OFFSET ||
- (uint)event_len != uint4korr(buf+EVENT_LEN_OFFSET))
+ if (event_len < EVENT_LEN_OFFSET ||
+ (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
+ {
+ *error="Sanity check failed"; // Needed to free buffer
return NULL; // general sanity check - will fail on a partial read
+ }
- switch(buf[EVENT_TYPE_OFFSET])
- {
+ Log_event* ev = NULL;
+
+ switch(buf[EVENT_TYPE_OFFSET]) {
case QUERY_EVENT:
- {
- Query_log_event* q = new Query_log_event(buf, event_len);
- if (!q->query)
- {
- delete q;
- return NULL;
- }
-
- return q;
- }
-
+ ev = new Query_log_event(buf, event_len, old_format);
+ break;
case LOAD_EVENT:
- {
- Load_log_event* l = new Load_log_event(buf, event_len);
- if (!l->table_name)
- {
- delete l;
- return NULL;
- }
-
- return l;
- }
-
+ ev = new Create_file_log_event(buf, event_len, old_format);
+ break;
+ case NEW_LOAD_EVENT:
+ ev = new Load_log_event(buf, event_len, old_format);
+ break;
case ROTATE_EVENT:
+ ev = new Rotate_log_event(buf, event_len, old_format);
+ break;
+ case SLAVE_EVENT:
+ ev = new Slave_log_event(buf, event_len);
+ break;
+ case CREATE_FILE_EVENT:
+ ev = new Create_file_log_event(buf, event_len, old_format);
+ break;
+ case APPEND_BLOCK_EVENT:
+ ev = new Append_block_log_event(buf, event_len);
+ break;
+ case DELETE_FILE_EVENT:
+ ev = new Delete_file_log_event(buf, event_len);
+ break;
+ case EXEC_LOAD_EVENT:
+ ev = new Execute_load_log_event(buf, event_len);
+ break;
+ case START_EVENT:
+ ev = new Start_log_event(buf, old_format);
+ break;
+ case STOP_EVENT:
+ ev = new Stop_log_event(buf, old_format);
+ break;
+ case INTVAR_EVENT:
+ ev = new Intvar_log_event(buf, old_format);
+ break;
+ case RAND_EVENT:
+ ev = new Rand_log_event(buf, old_format);
+ break;
+ default:
+ break;
+ }
+ if (!ev || !ev->is_valid())
{
- Rotate_log_event* r = new Rotate_log_event(buf, event_len);
- if (!r->new_log_ident)
+ delete ev;
+#ifdef MYSQL_CLIENT
+ if (!force_opt)
{
- delete r;
- return NULL;
+ *error= "Found invalid event in binary log";
+ return 0;
}
-
- return r;
- }
- case START_EVENT: return new Start_log_event(buf);
- case STOP_EVENT: return new Stop_log_event(buf);
- case INTVAR_EVENT: return new Intvar_log_event(buf);
- default:
- break;
+ ev= new Unknown_log_event(buf, old_format);
+#else
+ *error= "Found invalid event in binary log";
+ return 0;
+#endif
}
- return NULL; // default value
+ ev->cached_event_len = event_len;
+ return ev;
}
+
+#ifdef MYSQL_CLIENT
void Log_event::print_header(FILE* file)
{
+ char llbuff[22];
fputc('#', file);
print_timestamp(file);
- fprintf(file, " server id %d ", server_id);
+ fprintf(file, " server id %d log_pos %s ", server_id,
+ llstr(log_pos,llbuff));
}
void Log_event::print_timestamp(FILE* file, time_t* ts)
{
-#ifdef MYSQL_SERVER
- struct tm tm_tmp;
-#endif
struct tm *res;
if (!ts)
- {
ts = &when;
- }
-#ifdef MYSQL_SERVER
+#ifdef MYSQL_SERVER // This is always false
+ struct tm tm_tmp;
localtime_r(ts,(res= &tm_tmp));
#else
res=localtime(ts);
@@ -323,6 +753,7 @@ void Stop_log_event::print(FILE* file, bool short_form, char* last_db)
void Rotate_log_event::print(FILE* file, bool short_form, char* last_db)
{
+ char buf[22];
if (short_form)
return;
@@ -331,134 +762,134 @@ void Rotate_log_event::print(FILE* file, bool short_form, char* last_db)
if (new_log_ident)
my_fwrite(file, (byte*) new_log_ident, (uint)ident_len,
MYF(MY_NABP | MY_WME));
- fprintf(file, "\n");
+ fprintf(file, " pos: %s", llstr(pos, buf));
+ if (flags & LOG_EVENT_FORCED_ROTATE_F)
+ fprintf(file," forced by master");
+ fputc('\n', file);
fflush(file);
}
-Rotate_log_event::Rotate_log_event(IO_CACHE* file, time_t when_arg,
- uint32 server_id):
- Log_event(when_arg, 0, 0, server_id),new_log_ident(NULL),alloced(0)
-{
- char *tmp_ident;
- char buf[4];
+#endif /* #ifdef MYSQL_CLIENT */
- if (my_b_read(file, (byte*) buf, sizeof(buf)))
- return;
- ulong event_len;
- event_len = uint4korr(buf);
- if (event_len < ROTATE_EVENT_OVERHEAD)
- return;
- ident_len = (uchar)(event_len - ROTATE_EVENT_OVERHEAD);
- if (!(tmp_ident = (char*) my_malloc((uint)ident_len, MYF(MY_WME))))
- return;
- if (my_b_read( file, (byte*) tmp_ident, (uint) ident_len))
- {
- my_free((gptr) tmp_ident, MYF(0));
- return;
- }
-
- new_log_ident = tmp_ident;
- alloced = 1;
-}
-
-Start_log_event::Start_log_event(const char* buf) :Log_event(buf)
+Start_log_event::Start_log_event(const char* buf,
+ bool old_format)
+ :Log_event(buf, old_format)
{
- buf += EVENT_LEN_OFFSET + 4; // skip even length
- binlog_version = uint2korr(buf);
- memcpy(server_version, buf + 2, sizeof(server_version));
- created = uint4korr(buf + 2 + sizeof(server_version));
+ buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
+ binlog_version = uint2korr(buf+ST_BINLOG_VER_OFFSET);
+ memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
+ ST_SERVER_VER_LEN);
+ created = uint4korr(buf+ST_CREATED_OFFSET);
}
int Start_log_event::write_data(IO_CACHE* file)
{
- char buff[sizeof(server_version)+2+4];
- int2store(buff,binlog_version);
- memcpy(buff+2,server_version,sizeof(server_version));
- int4store(buff+2+sizeof(server_version),created);
- return (my_b_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0);
+ char buff[START_HEADER_LEN];
+ int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
+ memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
+ int4store(buff + ST_CREATED_OFFSET,created);
+ return (my_b_safe_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0);
}
-Rotate_log_event::Rotate_log_event(const char* buf, int event_len):
- Log_event(buf),new_log_ident(NULL),alloced(0)
+
+Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
+ bool old_format)
+ :Log_event(buf, old_format),new_log_ident(NULL),alloced(0)
{
- // the caller will ensure that event_len is what we have at
- // EVENT_LEN_OFFSET
- if(event_len < ROTATE_EVENT_OVERHEAD)
+ // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
+ int header_size = (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
+ uint ident_offset;
+ if (event_len < header_size)
return;
-
- ident_len = (uchar)(event_len - ROTATE_EVENT_OVERHEAD);
- if (!(new_log_ident = (char*) my_memdup((byte*) buf + LOG_EVENT_HEADER_LEN,
- (uint) ident_len, MYF(MY_WME))))
+ buf += header_size;
+ if (old_format)
+ {
+ ident_len = (uint)(event_len - OLD_HEADER_LEN);
+ pos = 4;
+ ident_offset = 0;
+ }
+ else
+ {
+ ident_len = (uint)(event_len - ROTATE_EVENT_OVERHEAD);
+ pos = uint8korr(buf + R_POS_OFFSET);
+ ident_offset = ROTATE_HEADER_LEN;
+ }
+ set_if_smaller(ident_len,FN_REFLEN-1);
+ if (!(new_log_ident= my_strdup_with_length((byte*) buf +
+ ident_offset,
+ (uint) ident_len,
+ MYF(MY_WME))))
return;
-
alloced = 1;
}
+
int Rotate_log_event::write_data(IO_CACHE* file)
{
- return my_b_write(file, (byte*) new_log_ident, (uint) ident_len) ? -1 :0;
+ char buf[ROTATE_HEADER_LEN];
+ int8store(buf + R_POS_OFFSET, pos);
+ return (my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
+ my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len));
}
-Query_log_event::Query_log_event(IO_CACHE* file, time_t when_arg,
- uint32 server_id):
- Log_event(when_arg,0,0,server_id),data_buf(0),query(NULL),db(NULL)
-{
- char buf[QUERY_HEADER_LEN + 4];
- ulong data_len;
- if (my_b_read(file, (byte*) buf, sizeof(buf)))
- return; // query == NULL will tell the
- // caller there was a problem
- data_len = uint4korr(buf);
- if (data_len < QUERY_EVENT_OVERHEAD)
- return; // tear-drop attack protection :)
-
- data_len -= QUERY_EVENT_OVERHEAD;
- exec_time = uint4korr(buf + 8);
- db_len = (uint)buf[12];
- error_code = uint2korr(buf + 13);
-
- /* Allocate one byte extra for end \0 */
- if (!(data_buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
- return;
- if (my_b_read( file, (byte*) data_buf, data_len))
- {
- my_free((gptr) data_buf, MYF(0));
- data_buf = 0;
- return;
- }
- thread_id = uint4korr(buf + 4);
- db = data_buf;
- query=data_buf + db_len + 1;
- q_len = data_len - 1 - db_len;
- *((char*) query + q_len) = 0; // Safety
+#ifndef MYSQL_CLIENT
+Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
+ ulong query_length, bool using_trans)
+ :Log_event(thd_arg, 0, using_trans), data_buf(0), query(query_arg),
+ db(thd_arg->db), q_len((uint32) query_length),
+ error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
+ thread_id(thd_arg->thread_id),
+ /* save the original thread id; we already know the server id */
+ slave_proxy_id(thd_arg->slave_proxy_id)
+
+{
+ time_t end_time;
+ time(&end_time);
+ exec_time = (ulong) (end_time - thd->start_time);
+ db_len = (db) ? (uint32) strlen(db) : 0;
}
+#endif
-Query_log_event::Query_log_event(const char* buf, int event_len):
- Log_event(buf),data_buf(0), query(NULL), db(NULL)
+Query_log_event::Query_log_event(const char* buf, int event_len,
+ bool old_format)
+ :Log_event(buf, old_format),data_buf(0), query(NULL), db(NULL)
{
- if ((uint)event_len < QUERY_EVENT_OVERHEAD)
- return;
ulong data_len;
- buf += EVENT_LEN_OFFSET;
- data_len = event_len - QUERY_EVENT_OVERHEAD;
+ if (old_format)
+ {
+ if ((uint)event_len < OLD_HEADER_LEN + QUERY_HEADER_LEN)
+ return;
+ data_len = event_len - (QUERY_HEADER_LEN + OLD_HEADER_LEN);
+ buf += OLD_HEADER_LEN;
+ }
+ else
+ {
+ if ((uint)event_len < QUERY_EVENT_OVERHEAD)
+ return;
+ data_len = event_len - QUERY_EVENT_OVERHEAD;
+ buf += LOG_EVENT_HEADER_LEN;
+ }
- exec_time = uint4korr(buf + 8);
- error_code = uint2korr(buf + 13);
+ exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
+ error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
if (!(data_buf = (char*) my_malloc(data_len + 1, MYF(MY_WME))))
return;
- memcpy(data_buf, buf + QUERY_HEADER_LEN + 4, data_len);
- thread_id = uint4korr(buf + 4);
+ memcpy(data_buf, buf + Q_DATA_OFFSET, data_len);
+ slave_proxy_id= thread_id= uint4korr(buf + Q_THREAD_ID_OFFSET);
db = data_buf;
- db_len = (uint)buf[12];
+ db_len = (uint)buf[Q_DB_LEN_OFFSET];
query=data_buf + db_len + 1;
q_len = data_len - 1 - db_len;
*((char*)query+q_len) = 0;
}
+
+#ifdef MYSQL_CLIENT
+
void Query_log_event::print(FILE* file, bool short_form, char* last_db)
{
char buff[40],*end; // Enough for SET TIMESTAMP
@@ -471,11 +902,11 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db)
bool same_db = 0;
- if(db && last_db)
- {
- if(!(same_db = !memcmp(last_db, db, db_len + 1)))
- memcpy(last_db, db, db_len + 1);
- }
+ if (db && last_db)
+ {
+ if (!(same_db = !memcmp(last_db, db, db_len + 1)))
+ memcpy(last_db, db, db_len + 1);
+ }
if (db && db[0] && !same_db)
fprintf(file, "use %s;\n", db);
@@ -486,173 +917,414 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db)
my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
fprintf(file, ";\n");
}
+#endif
+
int Query_log_event::write_data(IO_CACHE* file)
{
- if (!query) return -1;
+ if (!query)
+ return -1;
char buf[QUERY_HEADER_LEN];
- char* pos = buf;
- int4store(pos, thread_id);
- pos += 4;
- int4store(pos, exec_time);
- pos += 4;
- *pos++ = (char)db_len;
- int2store(pos, error_code);
- pos += 2;
-
- return (my_b_write(file, (byte*) buf, (uint)(pos - buf)) ||
- my_b_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
- my_b_write(file, (byte*) query, q_len)) ? -1 : 0;
+ /*
+ We want to store the thread id:
+ (- as an information for the user when he reads the binlog)
+ - if the query uses temporary table: for the slave SQL thread to know to
+ which master connection the temp table belongs.
+ Now imagine we (write_data()) are called by the slave SQL thread (we are
+ logging a query executed by this thread; the slave runs with
+ --log-slave-updates). Then this query will be logged with
+ thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of the
+ same name were created simultaneously on the master (in the master binlog
+ you have
+ CREATE TEMPORARY TABLE t; (thread 1)
+ CREATE TEMPORARY TABLE t; (thread 2)
+ ...)
+ then in the slave's binlog there will be
+ CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
+ CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
+ which is bad (same thread id!).
+ To avoid this, we log the thread's thread id EXCEPT for the SQL slave thread
+ for which we log the original (master's) thread id.
+ Now this moves the bug: what happens if the thread id on the master was 10
+ and when the slave replicates the query, a connection number 10 is opened by
+ a normal client on the slave, and updates a temp table of the same name? We
+ get a problem again. To avoid this, in the handling of temp tables
+ (sql_base.cc) we use thread_id AND server_id.
+ TODO when this is merged into 4.1: in 4.1, slave_proxy_id has been renamed
+ to pseudo_thread_id and is a session variable: that's to make mysqlbinlog
+ work with temp tables. We probably need to introduce
+ SET PSEUDO_SERVER_ID
+ for mysqlbinlog in 4.1. mysqlbinlog would print:
+ SET PSEUDO_SERVER_ID=
+ SET PSEUDO_THREAD_ID=
+ for each query using temp tables.
+ */
+ int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
+ int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
+ buf[Q_DB_LEN_OFFSET] = (char) db_len;
+ int2store(buf + Q_ERR_CODE_OFFSET, error_code);
+
+ return (my_b_safe_write(file, (byte*) buf, QUERY_HEADER_LEN) ||
+ my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
+ my_b_safe_write(file, (byte*) query, q_len)) ? -1 : 0;
}
-Intvar_log_event:: Intvar_log_event(IO_CACHE* file, time_t when_arg,
- uint32 server_id)
- :Log_event(when_arg,0,0,server_id), type(INVALID_INT_EVENT)
+Intvar_log_event::Intvar_log_event(const char* buf, bool old_format)
+ :Log_event(buf, old_format)
{
- char buf[9+4];
- if (!my_b_read(file, (byte*) buf, sizeof(buf)))
- {
- type = buf[4];
- val = uint8korr(buf+1+4);
- }
+ buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
+ type = buf[I_TYPE_OFFSET];
+ val = uint8korr(buf+I_VAL_OFFSET);
}
-Intvar_log_event::Intvar_log_event(const char* buf):Log_event(buf)
+const char* Intvar_log_event::get_var_type_name()
{
- buf += LOG_EVENT_HEADER_LEN;
- type = buf[0];
- val = uint8korr(buf+1);
+ switch(type) {
+ case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
+ case INSERT_ID_EVENT: return "INSERT_ID";
+ default: /* impossible */ return "UNKNOWN";
+ }
}
int Intvar_log_event::write_data(IO_CACHE* file)
{
char buf[9];
- buf[0] = type;
- int8store(buf + 1, val);
- return my_b_write(file, (byte*) buf, sizeof(buf));
+ buf[I_TYPE_OFFSET] = type;
+ int8store(buf + I_VAL_OFFSET, val);
+ return my_b_safe_write(file, (byte*) buf, sizeof(buf));
}
+#ifdef MYSQL_CLIENT
void Intvar_log_event::print(FILE* file, bool short_form, char* last_db)
{
char llbuff[22];
- if(!short_form)
+ const char *msg;
+ LINT_INIT(msg);
+
+ if (!short_form)
{
print_header(file);
fprintf(file, "\tIntvar\n");
}
fprintf(file, "SET ");
- switch(type)
- {
+ switch (type) {
case LAST_INSERT_ID_EVENT:
- fprintf(file, "LAST_INSERT_ID = ");
+ msg="LAST_INSERT_ID";
break;
case INSERT_ID_EVENT:
- fprintf(file, "INSERT_ID = ");
+ msg="INSERT_ID";
break;
}
- fprintf(file, "%s;\n", llstr(val,llbuff));
+ fprintf(file, "%s=%s;\n", msg, llstr(val,llbuff));
fflush(file);
-
+}
+#endif
+
+/*****************************************************************************
+ *
+ * Rand log event
+ *
+ ****************************************************************************/
+Rand_log_event::Rand_log_event(const char* buf, bool old_format)
+ :Log_event(buf, old_format)
+{
+ buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
+ seed1 = uint8korr(buf+RAND_SEED1_OFFSET);
+ seed2 = uint8korr(buf+RAND_SEED2_OFFSET);
+}
+
+int Rand_log_event::write_data(IO_CACHE* file)
+{
+ char buf[16];
+ int8store(buf + RAND_SEED1_OFFSET, seed1);
+ int8store(buf + RAND_SEED2_OFFSET, seed2);
+ return my_b_safe_write(file, (byte*) buf, sizeof(buf));
}
-int Load_log_event::write_data(IO_CACHE* file)
+#ifdef MYSQL_CLIENT
+void Rand_log_event::print(FILE* file, bool short_form, char* last_db)
+{
+ char llbuff[22],llbuff2[22];
+ if (!short_form)
+ {
+ print_header(file);
+ fprintf(file, "\tRand\n");
+ }
+ fprintf(file, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;\n",
+ llstr(seed1, llbuff),llstr(seed2, llbuff2));
+ fflush(file);
+}
+#endif
+
+int Load_log_event::write_data_header(IO_CACHE* file)
{
char buf[LOAD_HEADER_LEN];
- int4store(buf, thread_id);
- int4store(buf + 4, exec_time);
- int4store(buf + 8, skip_lines);
- buf[12] = (char)table_name_len;
- buf[13] = (char)db_len;
- int4store(buf + 14, num_fields);
-
- if(my_b_write(file, (byte*)buf, sizeof(buf)) ||
- my_b_write(file, (byte*)&sql_ex, sizeof(sql_ex)))
- return 1;
+ int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
+ int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
+ int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
+ buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
+ buf[L_DB_LEN_OFFSET] = (char)db_len;
+ int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
+ return my_b_safe_write(file, (byte*)buf, LOAD_HEADER_LEN);
+}
+int Load_log_event::write_data_body(IO_CACHE* file)
+{
+ if (sql_ex.write_data(file))
+ return 1;
if (num_fields && fields && field_lens)
{
- if(my_b_write(file, (byte*)field_lens, num_fields) ||
- my_b_write(file, (byte*)fields, field_block_len))
+ if (my_b_safe_write(file, (byte*)field_lens, num_fields) ||
+ my_b_safe_write(file, (byte*)fields, field_block_len))
return 1;
}
- if(my_b_write(file, (byte*)table_name, table_name_len + 1) ||
- my_b_write(file, (byte*)db, db_len + 1) ||
- my_b_write(file, (byte*)fname, fname_len))
+ return (my_b_safe_write(file, (byte*)table_name, table_name_len + 1) ||
+ my_b_safe_write(file, (byte*)db, db_len + 1) ||
+ my_b_safe_write(file, (byte*)fname, fname_len));
+}
+
+
+
+static bool write_str(IO_CACHE *file, char *str, byte length)
+{
+ return (my_b_safe_write(file, &length, 1) ||
+ my_b_safe_write(file, (byte*) str, (int) length));
+}
+
+
+int sql_ex_info::write_data(IO_CACHE* file)
+{
+ if (new_format())
+ {
+ return (write_str(file, field_term, field_term_len) ||
+ write_str(file, enclosed, enclosed_len) ||
+ write_str(file, line_term, line_term_len) ||
+ write_str(file, line_start, line_start_len) ||
+ write_str(file, escaped, escaped_len) ||
+ my_b_safe_write(file,(byte*) &opt_flags,1));
+ }
+ else
+ {
+ old_sql_ex old_ex;
+ old_ex.field_term= *field_term;
+ old_ex.enclosed= *enclosed;
+ old_ex.line_term= *line_term;
+ old_ex.line_start= *line_start;
+ old_ex.escaped= *escaped;
+ old_ex.opt_flags= opt_flags;
+ old_ex.empty_flags=empty_flags;
+ return my_b_safe_write(file, (byte*) &old_ex, sizeof(old_ex));
+ }
+}
+
+
+static inline int read_str(char * &buf, char *buf_end, char * &str,
+ uint8 &len)
+{
+ if (buf + (uint) (uchar) *buf >= buf_end)
return 1;
+ len = (uint8) *buf;
+ str= buf+1;
+ buf+= (uint) len+1;
return 0;
}
-Load_log_event::Load_log_event(IO_CACHE* file, time_t when, uint32 server_id):
- Log_event(when,0,0,server_id),data_buf(0),num_fields(0),
- fields(0),field_lens(0),field_block_len(0),
- table_name(0),db(0),fname(0)
+
+char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
{
- char buf[LOAD_HEADER_LEN + 4];
- ulong data_len;
- if (my_b_read(file, (byte*)buf, sizeof(buf)) ||
- my_b_read(file, (byte*)&sql_ex, sizeof(sql_ex)))
- return;
+ cached_new_format = use_new_format;
+ if (use_new_format)
+ {
+ empty_flags=0;
+ /*
+ The code below assumes that buf will not disappear from
+ under our feet during the lifetime of the event. This assumption
+ holds true in the slave thread if the log is in new format, but is not
+ the case when we have old format because we will be reusing net buffer
+ to read the actual file before we write out the Create_file event.
+ */
+ if (read_str(buf, buf_end, field_term, field_term_len) ||
+ read_str(buf, buf_end, enclosed, enclosed_len) ||
+ read_str(buf, buf_end, line_term, line_term_len) ||
+ read_str(buf, buf_end, line_start, line_start_len) ||
+ read_str(buf, buf_end, escaped, escaped_len))
+ return 0;
+ opt_flags = *buf++;
+ }
+ else
+ {
+ field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
+ field_term = buf++; // Use first byte in string
+ enclosed= buf++;
+ line_term= buf++;
+ line_start= buf++;
+ escaped= buf++;
+ opt_flags = *buf++;
+ empty_flags= *buf++;
+ if (empty_flags & FIELD_TERM_EMPTY)
+ field_term_len=0;
+ if (empty_flags & ENCLOSED_EMPTY)
+ enclosed_len=0;
+ if (empty_flags & LINE_TERM_EMPTY)
+ line_term_len=0;
+ if (empty_flags & LINE_START_EMPTY)
+ line_start_len=0;
+ if (empty_flags & ESCAPED_EMPTY)
+ escaped_len=0;
+ }
+ return buf;
+}
- data_len = uint4korr(buf) - LOAD_EVENT_OVERHEAD;
- if (!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
- return;
- if (my_b_read(file, (byte*)data_buf, data_len))
- return;
- copy_log_event(buf,data_len);
+
+#ifndef MYSQL_CLIENT
+Load_log_event::Load_log_event(THD* thd_arg, sql_exchange* ex,
+ const char* db_arg, const char* table_name_arg,
+ List<Item>& fields_arg,
+ enum enum_duplicates handle_dup,
+ bool using_trans)
+ :Log_event(thd_arg, 0, using_trans),thread_id(thd_arg->thread_id),
+ slave_proxy_id(thd_arg->slave_proxy_id),
+ num_fields(0),fields(0),
+ field_lens(0),field_block_len(0),
+ table_name(table_name_arg ? table_name_arg : ""),
+ db(db_arg), fname(ex->file_name)
+{
+ time_t end_time;
+ time(&end_time);
+ exec_time = (ulong) (end_time - thd_arg->start_time);
+ /* db can never be a zero pointer in 4.0 */
+ db_len = (uint32) strlen(db);
+ table_name_len = (uint32) strlen(table_name);
+ fname_len = (fname) ? (uint) strlen(fname) : 0;
+ sql_ex.field_term = (char*) ex->field_term->ptr();
+ sql_ex.field_term_len = (uint8) ex->field_term->length();
+ sql_ex.enclosed = (char*) ex->enclosed->ptr();
+ sql_ex.enclosed_len = (uint8) ex->enclosed->length();
+ sql_ex.line_term = (char*) ex->line_term->ptr();
+ sql_ex.line_term_len = (uint8) ex->line_term->length();
+ sql_ex.line_start = (char*) ex->line_start->ptr();
+ sql_ex.line_start_len = (uint8) ex->line_start->length();
+ sql_ex.escaped = (char*) ex->escaped->ptr();
+ sql_ex.escaped_len = (uint8) ex->escaped->length();
+ sql_ex.opt_flags = 0;
+ sql_ex.cached_new_format = -1;
+
+ if (ex->dumpfile)
+ sql_ex.opt_flags|= DUMPFILE_FLAG;
+ if (ex->opt_enclosed)
+ sql_ex.opt_flags|= OPT_ENCLOSED_FLAG;
+
+ sql_ex.empty_flags = 0;
+
+ switch (handle_dup) {
+ case DUP_IGNORE: sql_ex.opt_flags|= IGNORE_FLAG; break;
+ case DUP_REPLACE: sql_ex.opt_flags|= REPLACE_FLAG; break;
+ case DUP_ERROR: break;
+ }
+
+ if (!ex->field_term->length())
+ sql_ex.empty_flags|= FIELD_TERM_EMPTY;
+ if (!ex->enclosed->length())
+ sql_ex.empty_flags|= ENCLOSED_EMPTY;
+ if (!ex->line_term->length())
+ sql_ex.empty_flags|= LINE_TERM_EMPTY;
+ if (!ex->line_start->length())
+ sql_ex.empty_flags|= LINE_START_EMPTY;
+ if (!ex->escaped->length())
+ sql_ex.empty_flags|= ESCAPED_EMPTY;
+
+ skip_lines = ex->skip_lines;
+
+ List_iterator<Item> li(fields_arg);
+ field_lens_buf.length(0);
+ fields_buf.length(0);
+ Item* item;
+ while ((item = li++))
+ {
+ num_fields++;
+ uchar len = (uchar) strlen(item->name);
+ field_block_len += len + 1;
+ fields_buf.append(item->name, len + 1);
+ field_lens_buf.append((char*)&len, 1);
+ }
+
+ field_lens = (const uchar*)field_lens_buf.ptr();
+ fields = fields_buf.ptr();
}
-Load_log_event::Load_log_event(const char* buf, int event_len):
- Log_event(buf),data_buf(0),num_fields(0),fields(0),
+#endif
+
+/*
+ The caller must do buf[event_len] = 0 before he starts using the
+ constructed event.
+*/
+
+Load_log_event::Load_log_event(const char* buf, int event_len,
+ bool old_format)
+ :Log_event(buf, old_format),num_fields(0),fields(0),
field_lens(0),field_block_len(0),
table_name(0),db(0),fname(0)
{
- ulong data_len;
-
- if((uint)event_len < (LOAD_EVENT_OVERHEAD + LOG_EVENT_HEADER_LEN))
- return;
- buf += EVENT_LEN_OFFSET;
- memcpy(&sql_ex, buf + LOAD_HEADER_LEN + 4, sizeof(sql_ex));
- data_len = event_len;
-
- if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
+ if (!event_len) // derived class, will call copy_log_event() itself
return;
- memcpy(data_buf, buf + 22 + sizeof(sql_ex), data_len);
- copy_log_event(buf, data_len);
+ copy_log_event(buf, event_len, old_format);
}
-void Load_log_event::copy_log_event(const char *buf, ulong data_len)
+int Load_log_event::copy_log_event(const char *buf, ulong event_len,
+ bool old_format)
{
- thread_id = uint4korr(buf+4);
- exec_time = uint4korr(buf+8);
- skip_lines = uint4korr(buf + 12);
- table_name_len = (uint)buf[16];
- db_len = (uint)buf[17];
- num_fields = uint4korr(buf + 18);
+ uint data_len;
+ char* buf_end = (char*)buf + event_len;
+ uint header_len= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
+ const char* data_head = buf + header_len;
+ slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
+ exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
+ skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
+ table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
+ db_len = (uint)data_head[L_DB_LEN_OFFSET];
+ num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
+ int body_offset = ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
+ LOAD_HEADER_LEN + header_len :
+ get_data_body_offset());
+
+ if ((int) event_len < body_offset)
+ return 1;
+ /*
+ Sql_ex.init() on success returns the pointer to the first byte after
+ the sql_ex structure, which is the start of field lengths array.
+ */
+ if (!(field_lens=(uchar*)sql_ex.init((char*)buf + body_offset,
+ buf_end,
+ buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
+ return 1;
+
+ data_len = event_len - body_offset;
if (num_fields > data_len) // simple sanity check against corruption
- return;
-
- field_lens = (uchar*) data_buf;
- uint i;
- for (i = 0; i < num_fields; i++)
- {
+ return 1;
+ for (uint i = 0; i < num_fields; i++)
field_block_len += (uint)field_lens[i] + 1;
- }
+
fields = (char*)field_lens + num_fields;
-
- *((char*)data_buf+data_len) = 0;
table_name = fields + field_block_len;
db = table_name + table_name_len + 1;
fname = db + db_len + 1;
- fname_len = data_len - 2 - db_len - table_name_len - num_fields -
- field_block_len;
+ fname_len = strlen(fname);
+ // null termination is accomplished by the caller doing buf[event_len]=0
+ return 0;
}
+#ifdef MYSQL_CLIENT
void Load_log_event::print(FILE* file, bool short_form, char* last_db)
{
+ print(file, short_form, last_db, 0);
+}
+
+void Load_log_event::print(FILE* file, bool short_form, char* last_db, bool commented)
+{
if (!short_form)
{
print_header(file);
@@ -661,71 +1333,76 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db)
}
bool same_db = 0;
-
- if(db && last_db)
- {
- if(!(same_db = !memcmp(last_db, db, db_len + 1)))
- memcpy(last_db, db, db_len + 1);
- }
+ if (db && last_db)
+ {
+ if (!(same_db = !memcmp(last_db, db, db_len + 1)))
+ memcpy(last_db, db, db_len + 1);
+ }
- if(db && db[0] && !same_db)
- fprintf(file, "use %s;\n", db);
+ if (db && db[0] && !same_db)
+ fprintf(file, "%suse %s;\n",
+ commented ? "# " : "",
+ db);
- fprintf(file, "LOAD DATA INFILE '%s' ", fname);
+ fprintf(file, "%sLOAD DATA ",
+ commented ? "# " : "");
+ if (check_fname_outside_temp_buf())
+ fprintf(file, "LOCAL ");
+ fprintf(file, "INFILE '%-*s' ", fname_len, fname);
- if(sql_ex.opt_flags & REPLACE_FLAG )
+ if (sql_ex.opt_flags & REPLACE_FLAG )
fprintf(file," REPLACE ");
- else if(sql_ex.opt_flags & IGNORE_FLAG )
+ else if (sql_ex.opt_flags & IGNORE_FLAG )
fprintf(file," IGNORE ");
fprintf(file, "INTO TABLE %s ", table_name);
- if(!(sql_ex.empty_flags & FIELD_TERM_EMPTY))
+ if (sql_ex.field_term)
{
fprintf(file, " FIELDS TERMINATED BY ");
- pretty_print_char(file, sql_ex.field_term);
+ pretty_print_str(file, sql_ex.field_term, sql_ex.field_term_len);
}
- if(!(sql_ex.empty_flags & ENCLOSED_EMPTY))
+ if (sql_ex.enclosed)
{
- if(sql_ex.opt_flags & OPT_ENCLOSED_FLAG )
+ if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG )
fprintf(file," OPTIONALLY ");
fprintf(file, " ENCLOSED BY ");
- pretty_print_char(file, sql_ex.enclosed);
+ pretty_print_str(file, sql_ex.enclosed, sql_ex.enclosed_len);
}
- if(!(sql_ex.empty_flags & ESCAPED_EMPTY))
+ if (sql_ex.escaped)
{
fprintf(file, " ESCAPED BY ");
- pretty_print_char(file, sql_ex.escaped);
+ pretty_print_str(file, sql_ex.escaped, sql_ex.escaped_len);
}
bool line_lexem_added= false;
- if(!(sql_ex.empty_flags & LINE_TERM_EMPTY))
+ if (sql_ex.line_term)
{
fprintf(file," LINES TERMINATED BY ");
- pretty_print_char(file, sql_ex.line_term);
+ pretty_print_str(file, sql_ex.line_term, sql_ex.line_term_len);
line_lexem_added= true;
}
- if(!(sql_ex.empty_flags & LINE_START_EMPTY))
+ if (sql_ex.line_start)
{
if (!line_lexem_added)
fprintf(file," LINES");
fprintf(file," STARTING BY ");
- pretty_print_char(file, sql_ex.line_start);
+ pretty_print_str(file, sql_ex.line_start, sql_ex.line_start_len);
}
- if((int)skip_lines > 0)
- fprintf(file, " IGNORE %ld LINES ", (long) skip_lines);
+ if ((long) skip_lines > 0)
+ fprintf(file, " IGNORE %ld LINES", (long) skip_lines);
if (num_fields)
{
uint i;
const char* field = fields;
- fprintf( file, " (");
- for(i = 0; i < num_fields; i++)
+ fprintf(file, " (");
+ for (i = 0; i < num_fields; i++)
{
- if(i)
+ if (i)
fputc(',', file);
fprintf(file, field);
@@ -737,18 +1414,1053 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db)
fprintf(file, ";\n");
}
+#endif /* #ifdef MYSQL_CLIENT */
+
#ifndef MYSQL_CLIENT
-void Load_log_event::set_fields(List<Item> &fields)
+void Log_event::set_log_pos(MYSQL_LOG* log)
+{
+ if (!log_pos)
+ log_pos = my_b_tell(&log->log_file);
+}
+
+
+void Load_log_event::set_fields(List<Item> &field_list)
{
uint i;
- const char* field = this->fields;
- for(i = 0; i < num_fields; i++)
+ const char *field= fields;
+ for (i= 0; i < num_fields; i++)
+ {
+ field_list.push_back(new Item_field(db, table_name, field));
+ field+= field_lens[i] + 1;
+ }
+}
+
+
+Slave_log_event::Slave_log_event(THD* thd_arg,
+ struct st_relay_log_info* rli):
+ Log_event(thd_arg,0,0),mem_pool(0),master_host(0)
+{
+ DBUG_ENTER("Slave_log_event");
+ if (!rli->inited) // QQ When can this happen ?
+ DBUG_VOID_RETURN;
+
+ MASTER_INFO* mi = rli->mi;
+ // TODO: re-write this better without holding both locks at the same time
+ pthread_mutex_lock(&mi->data_lock);
+ pthread_mutex_lock(&rli->data_lock);
+ master_host_len = strlen(mi->host);
+ master_log_len = strlen(rli->master_log_name);
+ // on OOM, just do not initialize the structure and print the error
+ if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
+ MYF(MY_WME))))
+ {
+ master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
+ memcpy(master_host, mi->host, master_host_len + 1);
+ master_log = master_host + master_host_len + 1;
+ memcpy(master_log, rli->master_log_name, master_log_len + 1);
+ master_port = mi->port;
+ master_pos = rli->master_log_pos;
+ DBUG_PRINT("info", ("master_log: %s pos: %d", master_log,
+ (ulong) master_pos));
+ }
+ else
+ sql_print_error("Out of memory while recording slave event");
+ pthread_mutex_unlock(&rli->data_lock);
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_VOID_RETURN;
+}
+
+#endif /* ! MYSQL_CLIENT */
+
+
+Slave_log_event::~Slave_log_event()
+{
+ my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
+}
+
+#ifdef MYSQL_CLIENT
+
+void Slave_log_event::print(FILE* file, bool short_form, char* last_db)
+{
+ char llbuff[22];
+ if (short_form)
+ return;
+ print_header(file);
+ fputc('\n', file);
+ fprintf(file, "\
+Slave: master_host: '%s' master_port: %d master_log: '%s' master_pos: %s\n",
+ master_host, master_port, master_log, llstr(master_pos, llbuff));
+}
+
+#endif /* MYSQL_CLIENT */
+
+int Slave_log_event::get_data_size()
+{
+ return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
+}
+
+int Slave_log_event::write_data(IO_CACHE* file)
+{
+ int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
+ int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port);
+ // log and host are already there
+ return my_b_safe_write(file, (byte*)mem_pool, get_data_size());
+}
+
+
+void Slave_log_event::init_from_mem_pool(int data_size)
+{
+ master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
+ master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
+ master_host = mem_pool + SL_MASTER_HOST_OFFSET;
+ master_host_len = strlen(master_host);
+ // safety
+ master_log = master_host + master_host_len + 1;
+ if (master_log > mem_pool + data_size)
+ {
+ master_host = 0;
+ return;
+ }
+ master_log_len = strlen(master_log);
+}
+
+Slave_log_event::Slave_log_event(const char* buf, int event_len)
+ :Log_event(buf,0),mem_pool(0),master_host(0)
+{
+ event_len -= LOG_EVENT_HEADER_LEN;
+ if (event_len < 0)
+ return;
+ if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
+ return;
+ memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
+ mem_pool[event_len] = 0;
+ init_from_mem_pool(event_len);
+}
+
+#ifndef MYSQL_CLIENT
+Create_file_log_event::
+Create_file_log_event(THD* thd_arg, sql_exchange* ex,
+ const char* db_arg, const char* table_name_arg,
+ List<Item>& fields_arg, enum enum_duplicates handle_dup,
+ char* block_arg, uint block_len_arg, bool using_trans)
+ :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup,
+ using_trans),
+ fake_base(0),block(block_arg),block_len(block_len_arg),
+ file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
+{
+ sql_ex.force_new_format();
+}
+#endif
+
+int Create_file_log_event::write_data_body(IO_CACHE* file)
+{
+ int res;
+ if ((res = Load_log_event::write_data_body(file)) || fake_base)
+ return res;
+ return (my_b_safe_write(file, (byte*) "", 1) ||
+ my_b_safe_write(file, (byte*) block, block_len));
+}
+
+int Create_file_log_event::write_data_header(IO_CACHE* file)
+{
+ int res;
+ if ((res = Load_log_event::write_data_header(file)) || fake_base)
+ return res;
+ byte buf[CREATE_FILE_HEADER_LEN];
+ int4store(buf + CF_FILE_ID_OFFSET, file_id);
+ return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN);
+}
+
+int Create_file_log_event::write_base(IO_CACHE* file)
+{
+ int res;
+ fake_base = 1; // pretend we are Load event
+ res = write(file);
+ fake_base = 0;
+ return res;
+}
+
+Create_file_log_event::Create_file_log_event(const char* buf, int len,
+ bool old_format)
+ :Load_log_event(buf,0,old_format),fake_base(0),block(0),inited_from_old(0)
+{
+ int block_offset;
+ if (copy_log_event(buf,len,old_format))
+ return;
+ if (!old_format)
+ {
+ file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN +
+ + LOAD_HEADER_LEN + CF_FILE_ID_OFFSET);
+ // + 1 for \0 terminating fname
+ block_offset = (LOG_EVENT_HEADER_LEN + Load_log_event::get_data_size() +
+ CREATE_FILE_HEADER_LEN + 1);
+ if (len < block_offset)
+ return;
+ block = (char*)buf + block_offset;
+ block_len = len - block_offset;
+ }
+ else
+ {
+ sql_ex.force_new_format();
+ inited_from_old = 1;
+ }
+}
+
+
+#ifdef MYSQL_CLIENT
+void Create_file_log_event::print(FILE* file, bool short_form,
+ char* last_db, bool enable_local)
+{
+ if (short_form)
+ {
+ if (enable_local && check_fname_outside_temp_buf())
+ Load_log_event::print(file, 1, last_db);
+ return;
+ }
+
+ if (enable_local)
+ {
+ Load_log_event::print(file, 1, last_db, !check_fname_outside_temp_buf());
+ /*
+ That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
+ SHOW BINLOG EVENTS we don't.
+ */
+ fprintf(file, "#");
+ }
+
+ fprintf(file, " file_id: %d block_len: %d\n", file_id, block_len);
+}
+
+void Create_file_log_event::print(FILE* file, bool short_form,
+ char* last_db)
+{
+ print(file,short_form,last_db,0);
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+void Create_file_log_event::pack_info(String* packet)
+{
+ char buf1[256],buf[22], *end;
+ String tmp(buf1, sizeof(buf1));
+ tmp.length(0);
+ tmp.append("db=");
+ tmp.append(db, db_len);
+ tmp.append(";table=");
+ tmp.append(table_name, table_name_len);
+ tmp.append(";file_id=");
+ end= int10_to_str((long) file_id, buf, 10);
+ tmp.append(buf, (uint32) (end-buf));
+ tmp.append(";block_len=");
+ end= int10_to_str((long) block_len, buf, 10);
+ tmp.append(buf, (uint32) (end-buf));
+ net_store_data(packet, (char*) tmp.ptr(), tmp.length());
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+Append_block_log_event::Append_block_log_event(THD* thd_arg, const char* db_arg,
+ char* block_arg,
+ uint block_len_arg,
+ bool using_trans)
+ :Log_event(thd_arg,0, using_trans), block(block_arg),
+ block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
+{
+}
+#endif
+
+Append_block_log_event::Append_block_log_event(const char* buf, int len)
+ :Log_event(buf, 0),block(0)
+{
+ if ((uint)len < APPEND_BLOCK_EVENT_OVERHEAD)
+ return;
+ file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + AB_FILE_ID_OFFSET);
+ block = (char*)buf + APPEND_BLOCK_EVENT_OVERHEAD;
+ block_len = len - APPEND_BLOCK_EVENT_OVERHEAD;
+}
+
+int Append_block_log_event::write_data(IO_CACHE* file)
+{
+ byte buf[APPEND_BLOCK_HEADER_LEN];
+ int4store(buf + AB_FILE_ID_OFFSET, file_id);
+ return (my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
+ my_b_safe_write(file, (byte*) block, block_len));
+}
+
+#ifdef MYSQL_CLIENT
+void Append_block_log_event::print(FILE* file, bool short_form,
+ char* last_db)
+{
+ if (short_form)
+ return;
+ print_header(file);
+ fputc('\n', file);
+ fprintf(file, "#Append_block: file_id: %d block_len: %d\n",
+ file_id, block_len);
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+void Append_block_log_event::pack_info(String* packet)
+{
+ char buf1[256];
+ sprintf(buf1, ";file_id=%u;block_len=%u", file_id, block_len);
+ net_store_data(packet, buf1);
+}
+
+Delete_file_log_event::Delete_file_log_event(THD* thd_arg, const char* db_arg,
+ bool using_trans)
+ :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
+{
+}
+#endif
+
+
+Delete_file_log_event::Delete_file_log_event(const char* buf, int len)
+ :Log_event(buf, 0),file_id(0)
+{
+ if ((uint)len < DELETE_FILE_EVENT_OVERHEAD)
+ return;
+ file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + AB_FILE_ID_OFFSET);
+}
+
+
+int Delete_file_log_event::write_data(IO_CACHE* file)
+{
+ byte buf[DELETE_FILE_HEADER_LEN];
+ int4store(buf + DF_FILE_ID_OFFSET, file_id);
+ return my_b_safe_write(file, buf, DELETE_FILE_HEADER_LEN);
+}
+
+#ifdef MYSQL_CLIENT
+void Delete_file_log_event::print(FILE* file, bool short_form,
+ char* last_db)
+{
+ if (short_form)
+ return;
+ print_header(file);
+ fputc('\n', file);
+ fprintf(file, "#Delete_file: file_id=%u\n", file_id);
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+void Delete_file_log_event::pack_info(String* packet)
+{
+ char buf1[64];
+ sprintf(buf1, ";file_id=%u", (uint) file_id);
+ net_store_data(packet, buf1);
+}
+#endif
+
+
+#ifndef MYSQL_CLIENT
+Execute_load_log_event::Execute_load_log_event(THD* thd_arg, const char* db_arg,
+ bool using_trans)
+ :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
+{
+}
+#endif
+
+Execute_load_log_event::Execute_load_log_event(const char* buf, int len)
+ :Log_event(buf, 0), file_id(0)
+{
+ if ((uint)len < EXEC_LOAD_EVENT_OVERHEAD)
+ return;
+ file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + EL_FILE_ID_OFFSET);
+}
+
+int Execute_load_log_event::write_data(IO_CACHE* file)
+{
+ byte buf[EXEC_LOAD_HEADER_LEN];
+ int4store(buf + EL_FILE_ID_OFFSET, file_id);
+ return my_b_safe_write(file, buf, EXEC_LOAD_HEADER_LEN);
+}
+
+#ifdef MYSQL_CLIENT
+void Execute_load_log_event::print(FILE* file, bool short_form,
+ char* last_db)
+{
+ if (short_form)
+ return;
+ print_header(file);
+ fputc('\n', file);
+ fprintf(file, "#Exec_load: file_id=%d\n",
+ file_id);
+}
+#endif
+#ifndef MYSQL_CLIENT
+void Execute_load_log_event::pack_info(String* packet)
+{
+ char buf[64];
+ sprintf(buf, ";file_id=%u", (uint) file_id);
+ net_store_data(packet, buf);
+}
+#endif
+
+#ifdef MYSQL_CLIENT
+void Unknown_log_event::print(FILE* file, bool short_form, char* last_db)
+{
+ if (short_form)
+ return;
+ print_header(file);
+ fputc('\n', file);
+ fprintf(file, "# %s", "Unknown event\n");
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+int Query_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ int expected_error, actual_error= 0;
+ init_sql_alloc(&thd->mem_root, thd->variables.query_alloc_block_size,0);
+ thd->db= (char*) rewrite_db(db);
+
+ /*
+ InnoDB internally stores the master log position it has processed so far;
+ position to store is really pos + pending + event_len
+ since we must store the pos of the END of the current log event
+ */
+ rli->event_len= get_event_len();
+ thd->query_error= 0; // clear error
+ thd->clear_error();
+
+ if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
+ {
+ thd->set_time((time_t)when);
+ thd->current_tablenr = 0;
+ thd->query_length= q_len;
+ thd->query= (char *) query;
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ thd->query_id = query_id++;
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ thd->slave_proxy_id = thread_id; // for temp tables
+
+ /*
+ Sanity check to make sure the master did not get a really bad
+ error on the query.
+ */
+ if (ignored_error_code((expected_error = error_code)) ||
+ !check_expected_error(thd,rli,expected_error))
{
- fields.push_back(new Item_field(db, table_name, field));
- field += field_lens[i] + 1;
+ mysql_log.write(thd,COM_QUERY,"%s",thd->query);
+ DBUG_PRINT("query",("%s",thd->query));
+ mysql_parse(thd, thd->query, q_len);
+
+ /*
+ Set a flag if we are inside an transaction so that we can restart
+ the transaction from the start if we are killed
+
+ This will only be done if we are supporting transactional tables
+ in the slave.
+ */
+ if (!strcmp(thd->query,"BEGIN"))
+ rli->inside_transaction= opt_using_transactions;
+ else if (!(strcmp(thd->query,"COMMIT") && strcmp(thd->query,"ROLLBACK")))
+ rli->inside_transaction=0;
+
+ /*
+ If we expected a non-zero error code, and we don't get the same error
+ code, and none of them should be ignored.
+ */
+ if ((expected_error != (actual_error = thd->net.last_errno)) &&
+ expected_error &&
+ !ignored_error_code(actual_error) &&
+ !ignored_error_code(expected_error))
+ {
+ slave_print_error(rli, 0,
+ "\
+Query '%s' caused different errors on master and slave. \
+Error on master: '%s' (%d), Error on slave: '%s' (%d). \
+Default database: '%s'",
+ query,
+ ER_SAFE(expected_error),
+ expected_error,
+ actual_error ? thd->net.last_error: "no error",
+ actual_error,
+ print_slave_db_safe(db));
+ thd->query_error= 1;
+ }
+ /*
+ If we get the same error code as expected, or they should be ignored.
+ */
+ else if (expected_error == actual_error ||
+ ignored_error_code(actual_error))
+ {
+ thd->query_error = 0;
+ thd->clear_error();
+ *rli->last_slave_error = 0;
+ rli->last_slave_errno = 0;
+ }
+ /*
+ Other cases: mostly we expected no error and get one.
+ */
+ else if (thd->query_error || thd->fatal_error)
+ {
+ slave_print_error(rli,actual_error,
+ "Error '%s' on query '%s'. Default database: '%s'",
+ (actual_error ? thd->net.last_error :
+ "unexpected success or fatal error"),
+ query,
+ print_slave_db_safe(db));
+ thd->query_error= 1;
+ }
+ }
+ /*
+ End of sanity check. If the test was wrong, the query got a really bad
+ error on the master, which could be inconsistent, abort and tell DBA to
+ check/fix it. check_expected_error() already printed the message to
+ stderr and rli, and set thd->query_error to 1.
+ */
+ } /* End of if (db_ok(... */
+
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ thd->db= 0; // prevent db from being freed
+ thd->query= 0; // just to be sure
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ // assume no convert for next query unless set explictly
+ thd->variables.convert_set = 0;
+ close_thread_tables(thd);
+ free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
+ return (thd->query_error ? thd->query_error : Log_event::exec_event(rli));
+}
+
+/*
+ Does the data loading job when executing a LOAD DATA on the slave
+
+ SYNOPSIS
+ Load_log_event::exec_event
+ net
+ rli
+ use_rli_only_for_errors - if set to 1, rli is provided to
+ Load_log_event::exec_event only for this
+ function to have RPL_LOG_NAME and
+ rli->last_slave_error, both being used by
+ error reports. rli's position advancing
+ is skipped (done by the caller which is
+ Execute_load_log_event::exec_event).
+ - if set to 0, rli is provided for full use,
+ i.e. for error reports and position
+ advancing.
+
+ DESCRIPTION
+ Does the data loading job when executing a LOAD DATA on the slave
+
+ RETURN VALUE
+ 0 Success
+ 1 Failure
+*/
+
+int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
+ bool use_rli_only_for_errors)
+{
+ init_sql_alloc(&thd->mem_root, thd->variables.query_alloc_block_size, 0);
+ thd->db= (char*) rewrite_db(db);
+ DBUG_ASSERT(thd->query == 0);
+ thd->query = 0; // Should not be needed
+ thd->query_error = 0;
+ thd->clear_error();
+
+ /*
+ We test replicate_*_db rules. Note that we have already prepared the file to
+ load, even if we are going to ignore and delete it now. So it is possible
+ that we did a lot of disk writes for nothing. In other words, a big LOAD
+ DATA INFILE on the master will still consume a lot of space on the slave
+ (space in the relay log + space of temp files: twice the space of the file
+ to load...) even if it will finally be ignored.
+ TODO: fix this; this can be done by testing rules in
+ Create_file_log_event::exec_event() and then discarding Append_block and
+ al. Another way is do the filtering in the I/O thread (more efficient: no
+ disk writes at all).
+ */
+ if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
+ {
+ thd->set_time((time_t)when);
+ thd->current_tablenr = 0;
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ thd->query_id = query_id++;
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+
+ TABLE_LIST tables;
+ bzero((char*) &tables,sizeof(tables));
+ tables.db = thd->db;
+ tables.alias = tables.real_name = (char*)table_name;
+ tables.lock_type = TL_WRITE;
+ tables.updating= 1;
+ // the table will be opened in mysql_load
+ if (table_rules_on && !tables_ok(thd, &tables))
+ {
+ // TODO: this is a bug - this needs to be moved to the I/O thread
+ if (net)
+ skip_load_data_infile(net);
+ }
+ else
+ {
+ char llbuff[22];
+ enum enum_duplicates handle_dup;
+ if (sql_ex.opt_flags & REPLACE_FLAG)
+ handle_dup= DUP_REPLACE;
+ else if (sql_ex.opt_flags & IGNORE_FLAG)
+ handle_dup= DUP_IGNORE;
+ else
+ {
+ /*
+ When replication is running fine, if it was DUP_ERROR on the
+ master then we could choose DUP_IGNORE here, because if DUP_ERROR
+ suceeded on master, and data is identical on the master and slave,
+ then there should be no uniqueness errors on slave, so DUP_IGNORE is
+ the same as DUP_ERROR. But in the unlikely case of uniqueness errors
+ (because the data on the master and slave happen to be different
+ (user error or bug), we want LOAD DATA to print an error message on
+ the slave to discover the problem.
+
+ If reading from net (a 3.23 master), mysql_load() will change this
+ to DUP_IGNORE.
+ */
+ handle_dup= DUP_ERROR;
+ }
+
+ sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
+ String field_term(sql_ex.field_term,sql_ex.field_term_len);
+ String enclosed(sql_ex.enclosed,sql_ex.enclosed_len);
+ String line_term(sql_ex.line_term,sql_ex.line_term_len);
+ String line_start(sql_ex.line_start,sql_ex.line_start_len);
+ String escaped(sql_ex.escaped,sql_ex.escaped_len);
+ ex.field_term= &field_term;
+ ex.enclosed= &enclosed;
+ ex.line_term= &line_term;
+ ex.line_start= &line_start;
+ ex.escaped= &escaped;
+
+ ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
+ if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
+ ex.field_term->length(0);
+
+ ex.skip_lines = skip_lines;
+ List<Item> field_list;
+ set_fields(field_list);
+ thd->slave_proxy_id = thread_id;
+ if (net)
+ {
+ // mysql_load will use thd->net to read the file
+ thd->net.vio = net->vio;
+ /*
+ Make sure the client does not get confused about the packet sequence
+ */
+ thd->net.pkt_nr = net->pkt_nr;
+ }
+ if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0,
+ TL_WRITE))
+ thd->query_error = 1;
+ /* log_pos is the position of the LOAD event in the master log */
+ if (thd->cuted_fields)
+ sql_print_error("\
+Slave: load data infile on table '%s' at log position %s in log \
+'%s' produced %ld warning(s). Default database: '%s'",
+ (char*) table_name,
+ llstr(log_pos,llbuff), RPL_LOG_NAME,
+ (ulong) thd->cuted_fields,
+ print_slave_db_safe(db));
+ if (net)
+ net->pkt_nr= thd->net.pkt_nr;
+ }
+ }
+ else
+ {
+ /*
+ We will just ask the master to send us /dev/null if we do not
+ want to load the data.
+ TODO: this a bug - needs to be done in I/O thread
+ */
+ if (net)
+ skip_load_data_infile(net);
+ }
+
+ thd->net.vio = 0;
+ thd->db= 0; // prevent db from being freed
+ close_thread_tables(thd);
+ if (thd->query_error)
+ {
+ /* this err/sql_errno code is copy-paste from send_error() */
+ const char *err;
+ int sql_errno;
+ if ((err=thd->net.last_error)[0])
+ sql_errno=thd->net.last_errno;
+ else
+ {
+ sql_errno=ER_UNKNOWN_ERROR;
+ err=ER(sql_errno);
+ }
+ slave_print_error(rli,sql_errno,"\
+Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
+ err, (char*)table_name, print_slave_db_safe(db));
+ free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
+ return 1;
+ }
+ free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
+
+ if (thd->fatal_error)
+ {
+ slave_print_error(rli,ER_UNKNOWN_ERROR, "\
+Fatal error running LOAD DATA INFILE on table '%s'. Default database: '%s'",
+ (char*)table_name, print_slave_db_safe(db));
+ return 1;
+ }
+
+ return ( use_rli_only_for_errors ? 0 : Log_event::exec_event(rli) );
+}
+
+
+/*
+ The master started
+
+ IMPLEMENTATION
+ - To handle the case where the master died without a stop event,
+ we clean up all temporary tables that we got, if we are sure we
+ can (see below).
+
+ TODO
+ - Remove all active user locks
+*/
+
+int Start_log_event::exec_event(struct st_relay_log_info* rli)
+{
+
+ switch (rli->mi->old_format) {
+ case BINLOG_FORMAT_CURRENT :
+ /*
+ This is 4.x, so a Start_log_event is only at master startup,
+ so we are sure the master has restarted and cleared his temp tables.
+ */
+ close_temporary_tables(thd);
+ cleanup_load_tmpdir();
+ /*
+ As a transaction NEVER spans on 2 or more binlogs:
+ if we have an active transaction at this point, the master died while
+ writing the transaction to the binary log, i.e. while flushing the binlog
+ cache to the binlog. As the write was started, the transaction had been
+ committed on the master, so we lack of information to replay this
+ transaction on the slave; all we can do is stop with error.
+ */
+ if (rli->inside_transaction)
+ {
+ slave_print_error(rli, 0,
+ "\
+Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. \
+Probably cause is that the master died while writing the transaction to it's \
+binary log.");
+ return(1);
}
+ break;
+ /*
+ Now the older formats; in that case load_tmpdir is cleaned up by the I/O
+ thread.
+ */
+ case BINLOG_FORMAT_323_LESS_57 :
+ /*
+ Cannot distinguish a Start_log_event generated at master startup and
+ one generated by master FLUSH LOGS, so cannot be sure temp tables
+ have to be dropped. So do nothing.
+ */
+ break;
+ case BINLOG_FORMAT_323_GEQ_57 :
+ /*
+ Can distinguish, based on the value of 'created',
+ which was generated at master startup.
+ */
+ if (created)
+ close_temporary_tables(thd);
+ break;
+ default :
+ /* this case is impossible */
+ return 1;
+ }
+
+ return Log_event::exec_event(rli);
+}
+
+
+/*
+ The master stopped. Clean up all temporary tables + locks that the
+ master may have set.
+
+ TODO
+ - Remove all active user locks
+*/
+
+int Stop_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ /*
+ do not clean up immediately after rotate event;
+ QQ: this should be a useless test: the only case when it is false is when
+ shutdown occured just after FLUSH LOGS. It has nothing to do with Rotate?
+ By the way, immediately after a Rotate
+ the I/O thread does not write the Stop to the relay log,
+ so we won't come here in that case.
+ */
+ if (rli->master_log_pos > BIN_LOG_HEADER_SIZE)
+ {
+ close_temporary_tables(thd);
+ cleanup_load_tmpdir();
+ }
+ /*
+ We do not want to update master_log pos because we get a rotate event
+ before stop, so by now master_log_name is set to the next log.
+ If we updated it, we will have incorrect master coordinates and this
+ could give false triggers in MASTER_POS_WAIT() that we have reached
+ the target position when in fact we have not.
+ */
+ rli->inc_pos(get_event_len(), 0);
+ flush_relay_log_info(rli);
+ return 0;
+}
+
+
+/*
+ Got a rotate log even from the master
+
+ IMPLEMENTATION
+ This is mainly used so that we can later figure out the logname and
+ position for the master.
+
+ We can't rotate the slave as this will cause infinitive rotations
+ in a A -> B -> A setup.
+
+ RETURN VALUES
+ 0 ok
+*/
+
+int Rotate_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ DBUG_ENTER("Rotate_log_event::exec_event");
+
+ pthread_mutex_lock(&rli->data_lock);
+ /*
+ If we are in a transaction: the only normal case is when the I/O thread was
+ copying a big transaction, then it was stopped and restarted: we have this
+ in the relay log:
+ BEGIN
+ ...
+ ROTATE (a fake one)
+ ...
+ COMMIT or ROLLBACK
+ In that case, we don't want to touch the coordinates which correspond to the
+ beginning of the transaction.
+ */
+ if (!rli->inside_transaction)
+ {
+ memcpy(rli->master_log_name, new_log_ident, ident_len+1);
+ rli->master_log_pos= pos;
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) rli->master_log_pos));
+ }
+ rli->relay_log_pos += get_event_len();
+ pthread_mutex_unlock(&rli->data_lock);
+ pthread_cond_broadcast(&rli->data_cond);
+ flush_relay_log_info(rli);
+ DBUG_RETURN(0);
+}
+
+
+int Intvar_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ switch (type) {
+ case LAST_INSERT_ID_EVENT:
+ thd->last_insert_id_used = 1;
+ thd->last_insert_id = val;
+ break;
+ case INSERT_ID_EVENT:
+ thd->next_insert_id = val;
+ break;
+ }
+ rli->inc_pending(get_event_len());
+ return 0;
+}
+
+int Rand_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ thd->rand.seed1 = (ulong) seed1;
+ thd->rand.seed2 = (ulong) seed2;
+ rli->inc_pending(get_event_len());
+ return 0;
+}
+
+int Slave_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ if (mysql_bin_log.is_open())
+ mysql_bin_log.write(this);
+ return Log_event::exec_event(rli);
+}
+
+int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ char fname_buf[FN_REFLEN+10];
+ char *p;
+ int fd = -1;
+ IO_CACHE file;
+ int error = 1;
+
+ bzero((char*)&file, sizeof(file));
+ p = slave_load_file_stem(fname_buf, file_id, server_id);
+ strmov(p, ".info"); // strmov takes less code than memcpy
+ if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC,
+ MYF(MY_WME))) < 0 ||
+ init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
+ MYF(MY_WME|MY_NABP)))
+ {
+ slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf);
+ goto err;
+ }
+ // a trick to avoid allocating another buffer
+ strmov(p, ".data");
+ fname = fname_buf;
+ fname_len = (uint)(p-fname) + 5;
+ if (write_base(&file))
+ {
+ strmov(p, ".info"); // to have it right in the error message
+ slave_print_error(rli,my_errno, "Error in Create_file event: could not write to file '%s'", fname_buf);
+ goto err;
+ }
+ end_io_cache(&file);
+ my_close(fd, MYF(0));
+
+ // fname_buf now already has .data, not .info, because we did our trick
+ if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC,
+ MYF(MY_WME))) < 0)
+ {
+ slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf);
+ goto err;
+ }
+ if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP)))
+ {
+ slave_print_error(rli,my_errno, "Error in Create_file event: write to '%s' failed", fname_buf);
+ goto err;
+ }
+ error=0; // Everything is ok
+
+err:
+ if (error)
+ end_io_cache(&file);
+ if (fd >= 0)
+ my_close(fd, MYF(0));
+ return error ? 1 : Log_event::exec_event(rli);
}
-#endif
+int Delete_file_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ char fname[FN_REFLEN+10];
+ char *p= slave_load_file_stem(fname, file_id, server_id);
+ memcpy(p, ".data", 6);
+ (void) my_delete(fname, MYF(MY_WME));
+ memcpy(p, ".info", 6);
+ (void) my_delete(fname, MYF(MY_WME));
+ return Log_event::exec_event(rli);
+}
+
+int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ char fname[FN_REFLEN+10];
+ char *p= slave_load_file_stem(fname, file_id, server_id);
+ int fd;
+ int error = 1;
+
+ memcpy(p, ".data", 6);
+ if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0)
+ {
+ slave_print_error(rli,my_errno, "Error in Append_block event: could not open file '%s'", fname);
+ goto err;
+ }
+ if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP)))
+ {
+ slave_print_error(rli,my_errno, "Error in Append_block event: write to '%s' failed", fname);
+ goto err;
+ }
+ error=0;
+
+err:
+ if (fd >= 0)
+ my_close(fd, MYF(0));
+ return error ? error : Log_event::exec_event(rli);
+}
+
+int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
+{
+ char fname[FN_REFLEN+10];
+ char *p= slave_load_file_stem(fname, file_id, server_id);
+ int fd;
+ int error = 1;
+ IO_CACHE file;
+ Load_log_event* lev = 0;
+
+ memcpy(p, ".info", 6);
+ if ((fd = my_open(fname, O_RDONLY|O_BINARY, MYF(MY_WME))) < 0 ||
+ init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
+ MYF(MY_WME|MY_NABP)))
+ {
+ slave_print_error(rli,my_errno, "Error in Exec_load event: could not open file '%s'", fname);
+ goto err;
+ }
+ if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
+ (pthread_mutex_t*)0,
+ (bool)0)) ||
+ lev->get_type_code() != NEW_LOAD_EVENT)
+ {
+ slave_print_error(rli,0, "Error in Exec_load event: file '%s' appears corrupted", fname);
+ goto err;
+ }
+
+ lev->thd = thd;
+ /*
+ lev->exec_event should use rli only for errors
+ i.e. should not advance rli's position.
+ lev->exec_event is the place where the table is loaded (it calls
+ mysql_load()).
+ */
+ if (lev->exec_event(0,rli,1))
+ {
+ /*
+ We want to indicate the name of the file that could not be loaded
+ (SQL_LOADxxx).
+ But as we are here we are sure the error is in rli->last_slave_error and
+ rli->last_slave_errno (example of error: duplicate entry for key), so we
+ don't want to overwrite it with the filename.
+ What we want instead is add the filename to the current error message.
+ */
+ char *tmp= my_strdup(rli->last_slave_error,MYF(MY_WME));
+ if (tmp)
+ {
+ slave_print_error(rli,
+ rli->last_slave_errno, /* ok to re-use error code */
+ "%s. Failed executing load from '%s'",
+ tmp, fname);
+ my_free(tmp,MYF(0));
+ }
+ goto err;
+ }
+ /*
+ We have an open file descriptor to the .info file; we need to close it
+ or Windows will refuse to delete the file in my_delete().
+ */
+ if (fd >= 0)
+ {
+ my_close(fd, MYF(0));
+ end_io_cache(&file);
+ fd= -1;
+ }
+ (void) my_delete(fname, MYF(MY_WME));
+ memcpy(p, ".data", 6);
+ (void) my_delete(fname, MYF(MY_WME));
+ error = 0;
+
+err:
+ delete lev;
+ if (fd >= 0)
+ {
+ my_close(fd, MYF(0));
+ end_io_cache(&file);
+ }
+ return error ? error : Log_event::exec_event(rli);
+}
+
+#endif /* !MYSQL_CLIENT */
diff --git a/sql/log_event.h b/sql/log_event.h
index d3c74f7f7c2..a1a7798be34 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -15,8 +15,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifndef _LOG_EVENT_H
-#define _LOG_EVENT_H
+#ifndef _log_event_h
+#define _log_event_h
#ifdef __EMX__
#undef write // remove pthread.h macro definition, conflict with write() class member
@@ -34,46 +34,236 @@
#define LOG_READ_TOO_LARGE -7
#define LOG_EVENT_OFFSET 4
-#define BINLOG_VERSION 1
+#define BINLOG_VERSION 3
+
+/*
+ We could have used SERVER_VERSION_LENGTH, but this introduces an
+ obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
+ this would have broke the replication protocol
+*/
+#define ST_SERVER_VER_LEN 50
+
+#define DUMPFILE_FLAG 0x1
+#define OPT_ENCLOSED_FLAG 0x2
+#define REPLACE_FLAG 0x4
+#define IGNORE_FLAG 0x8
+
+#define FIELD_TERM_EMPTY 0x1
+#define ENCLOSED_EMPTY 0x2
+#define LINE_TERM_EMPTY 0x4
+#define LINE_START_EMPTY 0x8
+#define ESCAPED_EMPTY 0x10
+
+struct old_sql_ex
+{
+ char field_term;
+ char enclosed;
+ char line_term;
+ char line_start;
+ char escaped;
+ char opt_flags;
+ char empty_flags;
+};
+
+#define NUM_LOAD_DELIM_STRS 5
+
+struct sql_ex_info
+{
+ char* field_term;
+ char* enclosed;
+ char* line_term;
+ char* line_start;
+ char* escaped;
+ int cached_new_format;
+ uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len;
+ char opt_flags;
+ char empty_flags;
+
+ // store in new format even if old is possible
+ void force_new_format() { cached_new_format = 1;}
+ int data_size()
+ {
+ return (new_format() ?
+ field_term_len + enclosed_len + line_term_len +
+ line_start_len + escaped_len + 6 : 7);
+ }
+ int write_data(IO_CACHE* file);
+ char* init(char* buf,char* buf_end,bool use_new_format);
+ bool new_format()
+ {
+ return ((cached_new_format != -1) ? cached_new_format :
+ (cached_new_format=(field_term_len > 1 ||
+ enclosed_len > 1 ||
+ line_term_len > 1 || line_start_len > 1 ||
+ escaped_len > 1)));
+ }
+};
+
+/*
+ Binary log consists of events. Each event has a fixed length header,
+ followed by possibly variable ( depending on the type of event) length
+ data body. The data body consists of an optional fixed length segment
+ (post-header), and an optional variable length segment. See #defines and
+ comments below for the format specifics
+*/
+
+/* event-specific post-header sizes */
+#define LOG_EVENT_HEADER_LEN 19
+#define OLD_HEADER_LEN 13
+#define QUERY_HEADER_LEN (4 + 4 + 1 + 2)
+#define LOAD_HEADER_LEN (4 + 4 + 4 + 1 +1 + 4)
+#define START_HEADER_LEN (2 + ST_SERVER_VER_LEN + 4)
+#define ROTATE_HEADER_LEN 8
+#define CREATE_FILE_HEADER_LEN 4
+#define APPEND_BLOCK_HEADER_LEN 4
+#define EXEC_LOAD_HEADER_LEN 4
+#define DELETE_FILE_HEADER_LEN 4
+
+/* event header offsets */
-#define LOG_EVENT_HEADER_LEN 13
-#define QUERY_HEADER_LEN (sizeof(uint32) + sizeof(uint32) + \
- sizeof(uchar) + sizeof(uint16))
-#define LOAD_HEADER_LEN (sizeof(uint32) + sizeof(uint32) + \
- + sizeof(uint32) + 2 + sizeof(uint32))
-#define EVENT_LEN_OFFSET 9
#define EVENT_TYPE_OFFSET 4
-#define QUERY_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
-#define ROTATE_EVENT_OVERHEAD LOG_EVENT_HEADER_LEN
-#define LOAD_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN+sizeof(sql_ex_info))
+#define SERVER_ID_OFFSET 5
+#define EVENT_LEN_OFFSET 9
+#define LOG_POS_OFFSET 13
+#define FLAGS_OFFSET 17
+
+/* start event post-header */
+
+#define ST_BINLOG_VER_OFFSET 0
+#define ST_SERVER_VER_OFFSET 2
+#define ST_CREATED_OFFSET (ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN)
+
+/* slave event post-header */
+
+#define SL_MASTER_PORT_OFFSET 8
+#define SL_MASTER_POS_OFFSET 0
+#define SL_MASTER_HOST_OFFSET 10
+
+/* query event post-header */
+
+#define Q_THREAD_ID_OFFSET 0
+#define Q_EXEC_TIME_OFFSET 4
+#define Q_DB_LEN_OFFSET 8
+#define Q_ERR_CODE_OFFSET 9
+#define Q_DATA_OFFSET QUERY_HEADER_LEN
+
+/* Intvar event post-header */
+
+#define I_TYPE_OFFSET 0
+#define I_VAL_OFFSET 1
+
+/* Rand event post-header */
+
+#define RAND_SEED1_OFFSET 0
+#define RAND_SEED2_OFFSET 8
+
+/* Load event post-header */
+
+#define L_THREAD_ID_OFFSET 0
+#define L_EXEC_TIME_OFFSET 4
+#define L_SKIP_LINES_OFFSET 8
+#define L_TBL_LEN_OFFSET 12
+#define L_DB_LEN_OFFSET 13
+#define L_NUM_FIELDS_OFFSET 14
+#define L_SQL_EX_OFFSET 18
+#define L_DATA_OFFSET LOAD_HEADER_LEN
+
+/* Rotate event post-header */
+
+#define R_POS_OFFSET 0
+#define R_IDENT_OFFSET 8
+
+#define CF_FILE_ID_OFFSET 0
+#define CF_DATA_OFFSET CREATE_FILE_HEADER_LEN
+
+#define AB_FILE_ID_OFFSET 0
+#define AB_DATA_OFFSET APPEND_BLOCK_HEADER_LEN
+
+#define EL_FILE_ID_OFFSET 0
+
+#define DF_FILE_ID_OFFSET 0
+
+#define QUERY_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
+#define QUERY_DATA_OFFSET (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
+#define ROTATE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+ROTATE_HEADER_LEN)
+#define LOAD_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN)
+#define CREATE_FILE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+\
+ +LOAD_HEADER_LEN+CREATE_FILE_HEADER_LEN)
+#define DELETE_FILE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+DELETE_FILE_HEADER_LEN)
+#define EXEC_LOAD_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+EXEC_LOAD_HEADER_LEN)
+#define APPEND_BLOCK_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+APPEND_BLOCK_HEADER_LEN)
+
#define BINLOG_MAGIC "\xfe\x62\x69\x6e"
-enum Log_event_type { START_EVENT = 1, QUERY_EVENT =2,
- STOP_EVENT=3, ROTATE_EVENT = 4, INTVAR_EVENT=5,
- LOAD_EVENT=6};
-enum Int_event_type { INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
- };
+#define LOG_EVENT_TIME_F 0x1
+#define LOG_EVENT_FORCED_ROTATE_F 0x2
+
+enum Log_event_type
+{
+ UNKNOWN_EVENT = 0, START_EVENT = 1, QUERY_EVENT =2, STOP_EVENT=3,
+ ROTATE_EVENT = 4, INTVAR_EVENT=5, LOAD_EVENT=6, SLAVE_EVENT=7,
+ CREATE_FILE_EVENT=8, APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10,
+ DELETE_FILE_EVENT=11, NEW_LOAD_EVENT=12, RAND_EVENT=13
+};
+
+enum Int_event_type
+{
+ INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
+};
+
#ifndef MYSQL_CLIENT
class String;
+class MYSQL_LOG;
+class THD;
#endif
-extern ulong server_id;
+struct st_relay_log_info;
class Log_event
{
public:
+ my_off_t log_pos;
+ char *temp_buf;
time_t when;
ulong exec_time;
- int valid_exec_time; // if false, the exec time setting is bogus
uint32 server_id;
+ uint cached_event_len;
+ uint16 flags;
+ bool cache_stmt;
+#ifndef MYSQL_CLIENT
+ THD* thd;
+
+ Log_event(THD* thd_arg, uint16 flags_arg, bool cache_stmt);
+ Log_event();
+ // if mutex is 0, the read will proceed without mutex
+ static Log_event* read_log_event(IO_CACHE* file,
+ pthread_mutex_t* log_lock,
+ bool old_format);
+ static int read_log_event(IO_CACHE* file, String* packet,
+ pthread_mutex_t* log_lock);
+ void set_log_pos(MYSQL_LOG* log);
+ virtual void pack_info(String* packet);
+ int net_send(THD* thd, const char* log_name, my_off_t pos);
+ static void init_show_field_list(List<Item>* field_list);
+ virtual int exec_event(struct st_relay_log_info* rli);
+ virtual const char* get_db()
+ {
+ return thd ? thd->db : 0;
+ }
+#else
+ // avoid having to link mysqlbinlog against libpthread
+ static Log_event* read_log_event(IO_CACHE* file, bool old_format);
+ virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0;
+ void print_timestamp(FILE* file, time_t *ts = 0);
+ void print_header(FILE* file);
+#endif
static void *operator new(size_t size)
{
return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE));
}
-
static void operator delete(void *ptr, size_t size)
{
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
@@ -81,43 +271,36 @@ public:
int write(IO_CACHE* file);
int write_header(IO_CACHE* file);
- virtual int write_data(IO_CACHE* file __attribute__((unused))) { return 0; }
+ virtual int write_data(IO_CACHE* file)
+ { return write_data_header(file) || write_data_body(file); }
+ virtual int write_data_header(IO_CACHE* file __attribute__((unused)))
+ { return 0; }
+ virtual int write_data_body(IO_CACHE* file __attribute__((unused)))
+ { return 0; }
virtual Log_event_type get_type_code() = 0;
- Log_event(time_t when_arg, ulong exec_time_arg = 0,
- int valid_exec_time_arg = 0, uint32 server_id_arg = 0):
- when(when_arg), exec_time(exec_time_arg),
- valid_exec_time(valid_exec_time_arg)
+ virtual bool is_valid() = 0;
+ inline bool get_cache_stmt() { return cache_stmt; }
+ Log_event(const char* buf, bool old_format);
+ virtual ~Log_event() { free_temp_buf();}
+ void register_temp_buf(char* buf) { temp_buf = buf; }
+ void free_temp_buf()
{
- server_id = server_id_arg ? server_id_arg : (::server_id);
+ if (temp_buf)
+ {
+ my_free(temp_buf, MYF(0));
+ temp_buf = 0;
+ }
}
-
- Log_event(const char* buf): valid_exec_time(0)
+ virtual int get_data_size() { return 0;}
+ virtual int get_data_body_offset() { return 0; }
+ int get_event_len()
{
- when = uint4korr(buf);
- server_id = uint4korr(buf + 5);
+ return (cached_event_len ? cached_event_len :
+ (cached_event_len = LOG_EVENT_HEADER_LEN + get_data_size()));
}
-
- virtual ~Log_event() {}
-
- virtual int get_data_size() { return 0;}
- virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0;
-
- void print_timestamp(FILE* file, time_t *ts = 0);
- void print_header(FILE* file);
-
-#ifndef MYSQL_CLIENT
- // if mutex is 0, the read will proceed without mutex
- static Log_event* read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock);
-#else // avoid having to link mysqlbinlog against libpthread
- static Log_event* read_log_event(IO_CACHE* file);
-#endif
- static Log_event* read_log_event(const char* buf, int event_len);
-
-#ifndef MYSQL_CLIENT
- static int read_log_event(IO_CACHE* file, String* packet,
- pthread_mutex_t* log_lock);
-#endif
-
+ static Log_event* read_log_event(const char* buf, int event_len,
+ const char **error, bool old_format);
+ const char* get_type_str();
};
@@ -128,35 +311,34 @@ protected:
public:
const char* query;
const char* db;
- uint32 q_len; // if we already know the length of the query string
- // we pass it here, so we would not have to call strlen()
- // otherwise, set it to 0, in which case, we compute it with strlen()
+ /*
+ If we already know the length of the query string
+ we pass it with q_len, so we would not have to call strlen()
+ otherwise, set it to 0, in which case, we compute it with strlen()
+ */
+ uint32 q_len;
uint32 db_len;
uint16 error_code;
ulong thread_id;
-#if !defined(MYSQL_CLIENT)
- THD* thd;
- bool cache_stmt;
- Query_log_event(THD* thd_arg, const char* query_arg, bool using_trans=0):
- Log_event(thd_arg->start_time,0,1,thd_arg->server_id), data_buf(0),
- query(query_arg), db(thd_arg->db), q_len(thd_arg->query_length),
- error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
- thread_id(thd_arg->thread_id), thd(thd_arg),
- cache_stmt(using_trans &&
- (thd_arg->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)))
- {
- time_t end_time;
- time(&end_time);
- exec_time = (ulong) (end_time - thd->start_time);
- db_len = (db) ? (uint32) strlen(db) : 0;
- // do not log stray system errors such as EE_WRITE
- if (error_code < ERRMOD)
- error_code = 0;
- }
+ /*
+ For events created by Query_log_event::exec_event (and
+ Load_log_event::exec_event()) we need the *original* thread id, to be able
+ to log the event with the original (=master's) thread id (fix for
+ BUG#1686).
+ */
+ ulong slave_proxy_id;
+#ifndef MYSQL_CLIENT
+
+ Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
+ bool using_trans);
+ const char* get_db() { return db; }
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
- Query_log_event(IO_CACHE* file, time_t when, uint32 server_id_arg);
- Query_log_event(const char* buf, int event_len);
+ Query_log_event(const char* buf, int event_len, bool old_format);
~Query_log_event()
{
if (data_buf)
@@ -167,49 +349,55 @@ public:
Log_event_type get_type_code() { return QUERY_EVENT; }
int write(IO_CACHE* file);
int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
+ bool is_valid() { return query != 0; }
int get_data_size()
{
- return q_len + db_len + 2 +
- sizeof(uint32) // thread_id
- + sizeof(uint32) // exec_time
- + sizeof(uint16) // error_code
- ;
+ return (q_len + db_len + 2
+ + 4 // thread_id
+ + 4 // exec_time
+ + 2 // error_code
+ );
}
-
- void print(FILE* file, bool short_form = 0, char* last_db = 0);
};
-#define DUMPFILE_FLAG 0x1
-#define OPT_ENCLOSED_FLAG 0x2
-#define REPLACE_FLAG 0x4
-#define IGNORE_FLAG 0x8
-#define FIELD_TERM_EMPTY 0x1
-#define ENCLOSED_EMPTY 0x2
-#define LINE_TERM_EMPTY 0x4
-#define LINE_START_EMPTY 0x8
-#define ESCAPED_EMPTY 0x10
+class Slave_log_event: public Log_event
+{
+protected:
+ char* mem_pool;
+ void init_from_mem_pool(int data_size);
+public:
+ my_off_t master_pos;
+ char* master_host;
+ char* master_log;
+ int master_host_len;
+ int master_log_len;
+ uint16 master_port;
+#ifndef MYSQL_CLIENT
+ Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
-struct sql_ex_info
- {
- char field_term;
- char enclosed;
- char line_term;
- char line_start;
- char escaped;
- char opt_flags; // flags for the options
- char empty_flags; // flags to indicate which of the terminating charact
- } ;
+ Slave_log_event(const char* buf, int event_len);
+ ~Slave_log_event();
+ int get_data_size();
+ bool is_valid() { return master_host != 0; }
+ Log_event_type get_type_code() { return SLAVE_EVENT; }
+ int write_data(IO_CACHE* file );
+};
class Load_log_event: public Log_event
{
protected:
- char* data_buf;
- void copy_log_event(const char *buf, ulong data_len);
+ int copy_log_event(const char *buf, ulong event_len, bool old_format);
public:
ulong thread_id;
+ ulong slave_proxy_id;
uint32 table_name_len;
uint32 db_len;
uint32 fname_len;
@@ -217,109 +405,67 @@ public:
const char* fields;
const uchar* field_lens;
uint32 field_block_len;
-
const char* table_name;
const char* db;
const char* fname;
uint32 skip_lines;
sql_ex_info sql_ex;
-
-#if !defined(MYSQL_CLIENT)
- THD* thd;
+
+ /* fname doesn't point to memory inside Log_event::temp_buf */
+ void set_fname_outside_temp_buf(const char *afname, uint alen)
+ {
+ fname= afname;
+ fname_len= alen;
+ }
+ /* fname doesn't point to memory inside Log_event::temp_buf */
+ int check_fname_outside_temp_buf()
+ {
+ return fname < temp_buf || fname > temp_buf+ cached_event_len;
+ }
+
+#ifndef MYSQL_CLIENT
String field_lens_buf;
String fields_buf;
- Load_log_event(THD* thd, sql_exchange* ex,
- const char *db_arg, const char* table_name_arg,
- List<Item>& fields_arg, enum enum_duplicates handle_dup ):
- Log_event(thd->start_time),data_buf(0),thread_id(thd->thread_id),
- num_fields(0),fields(0),field_lens(0),field_block_len(0),
- table_name(table_name_arg ? table_name_arg : ""),
- db(db_arg ? db_arg : ""),
- fname(ex->file_name),
- thd(thd)
+
+ Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
+ const char* table_name_arg,
+ List<Item>& fields_arg, enum enum_duplicates handle_dup,
+ bool using_trans);
+ void set_fields(List<Item> &fields_arg);
+ void pack_info(String* packet);
+ const char* get_db() { return db; }
+ int exec_event(struct st_relay_log_info* rli)
{
- time_t end_time;
- time(&end_time);
- exec_time = (ulong) (end_time - thd->start_time);
- valid_exec_time = 1;
- db_len = (uint32) strlen(db);
- table_name_len = (uint32) strlen(table_name);
- fname_len = (fname) ? (uint) strlen(fname) : 0;
- sql_ex.field_term = (*ex->field_term)[0];
- sql_ex.enclosed = (*ex->enclosed)[0];
- sql_ex.line_term = (*ex->line_term)[0];
- sql_ex.line_start = (*ex->line_start)[0];
- sql_ex.escaped = (*ex->escaped)[0];
- sql_ex.opt_flags = 0;
- if(ex->dumpfile)
- sql_ex.opt_flags |= DUMPFILE_FLAG;
- if(ex->opt_enclosed)
- sql_ex.opt_flags |= OPT_ENCLOSED_FLAG;
-
- sql_ex.empty_flags = 0;
-
- switch(handle_dup) {
- case DUP_IGNORE: sql_ex.opt_flags |= IGNORE_FLAG; break;
- case DUP_REPLACE: sql_ex.opt_flags |= REPLACE_FLAG; break;
- case DUP_ERROR: break;
- }
-
- if(!ex->field_term->length())
- sql_ex.empty_flags |= FIELD_TERM_EMPTY;
- if(!ex->enclosed->length())
- sql_ex.empty_flags |= ENCLOSED_EMPTY;
- if(!ex->line_term->length())
- sql_ex.empty_flags |= LINE_TERM_EMPTY;
- if(!ex->line_start->length())
- sql_ex.empty_flags |= LINE_START_EMPTY;
- if(!ex->escaped->length())
- sql_ex.empty_flags |= ESCAPED_EMPTY;
-
- skip_lines = ex->skip_lines;
-
- List_iterator<Item> li(fields_arg);
- field_lens_buf.length(0);
- fields_buf.length(0);
- Item* item;
- while((item = li++))
- {
- num_fields++;
- uchar len = (uchar) strlen(item->name);
- field_block_len += len + 1;
- fields_buf.append(item->name, len + 1);
- field_lens_buf.append((char*)&len, 1);
- }
-
- field_lens = (const uchar*)field_lens_buf.ptr();
- fields = fields_buf.ptr();
+ return exec_event(thd->slave_net,rli,0);
}
- void set_fields(List<Item> &fields_arg);
+ int exec_event(NET* net, struct st_relay_log_info* rli,
+ bool use_rli_only_for_errors);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+ void print(FILE* file, bool short_form, char* last_db, bool commented);
#endif
- Load_log_event(IO_CACHE * file, time_t when, uint32 server_id_arg);
- Load_log_event(const char* buf, int event_len);
+ Load_log_event(const char* buf, int event_len, bool old_format);
~Load_log_event()
+ {}
+ Log_event_type get_type_code()
{
- if (data_buf)
- {
- my_free((gptr) data_buf, MYF(0));
- }
+ return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT;
}
- Log_event_type get_type_code() { return LOAD_EVENT; }
- int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
+ int write_data_header(IO_CACHE* file);
+ int write_data_body(IO_CACHE* file);
+ bool is_valid() { return table_name != 0; }
int get_data_size()
{
- return table_name_len + 2 + db_len + 2 + fname_len
- + 4 // thread_id
- + 4 // exec_time
- + 4 // skip_lines
- + 4 // field block len
- + sizeof(sql_ex) + field_block_len + num_fields*sizeof(uchar) ;
- ;
+ return (table_name_len + 2 + db_len + 2 + fname_len
+ + 4 // thread_id
+ + 4 // exec_time
+ + 4 // skip_lines
+ + 4 // field block len
+ + sql_ex.data_size() + field_block_len + num_fields);
}
-
- void print(FILE* file, bool short_form = 0, char* last_db = 0);
+ int get_data_body_offset() { return LOAD_EVENT_OVERHEAD; }
};
extern char server_version[SERVER_VERSION_LENGTH];
@@ -349,101 +495,295 @@ public:
*/
time_t created;
uint16 binlog_version;
- char server_version[50];
-
- Start_log_event() :Log_event(time(NULL)),binlog_version(BINLOG_VERSION)
+ char server_version[ST_SERVER_VER_LEN];
+
+#ifndef MYSQL_CLIENT
+ Start_log_event() :Log_event(), binlog_version(BINLOG_VERSION)
{
created = (time_t) when;
- memcpy(server_version, ::server_version, sizeof(server_version));
- }
- Start_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id_arg) :
- Log_event(when_arg, 0, 0, server_id_arg)
- {
- char buf[sizeof(server_version) + 2 + 4 + 4];
- if (my_b_read(file, (byte*) buf, sizeof(buf)))
- return;
- binlog_version = uint2korr(buf+4);
- memcpy(server_version, buf + 6, sizeof(server_version));
- server_version[sizeof(server_version)-1]=0;
- created = (time_t) uint4korr(buf + 6 + sizeof(server_version));
+ memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
}
- Start_log_event(const char* buf);
-
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Start_log_event(const char* buf, bool old_format);
~Start_log_event() {}
Log_event_type get_type_code() { return START_EVENT;}
int write_data(IO_CACHE* file);
+ bool is_valid() { return 1; }
int get_data_size()
{
- // size(binlog_version) + sizeof(server_version) + size(created)
- return 2 + sizeof(server_version) + 4;
+ return START_HEADER_LEN;
}
- void print(FILE* file, bool short_form = 0, char* last_db = 0);
};
+
class Intvar_log_event: public Log_event
{
public:
ulonglong val;
uchar type;
- Intvar_log_event(uchar type_arg, ulonglong val_arg)
- :Log_event(time(NULL)),val(val_arg),type(type_arg)
+
+#ifndef MYSQL_CLIENT
+ Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg)
+ :Log_event(thd_arg,0,0),val(val_arg),type(type_arg)
{}
- Intvar_log_event(IO_CACHE* file, time_t when, uint32 server_id_arg);
- Intvar_log_event(const char* buf);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Intvar_log_event(const char* buf, bool old_format);
~Intvar_log_event() {}
Log_event_type get_type_code() { return INTVAR_EVENT;}
+ const char* get_var_type_name();
int get_data_size() { return sizeof(type) + sizeof(val);}
int write_data(IO_CACHE* file);
-
-
+ bool is_valid() { return 1; }
+};
+
+/*****************************************************************************
+ *
+ * Rand log event class
+ *
+ ****************************************************************************/
+class Rand_log_event: public Log_event
+{
+ public:
+ ulonglong seed1;
+ ulonglong seed2;
+
+#ifndef MYSQL_CLIENT
+ Rand_log_event(THD* thd_arg, ulonglong seed1_arg, ulonglong seed2_arg)
+ :Log_event(thd_arg,0,0),seed1(seed1_arg),seed2(seed2_arg)
+ {}
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Rand_log_event(const char* buf, bool old_format);
+ ~Rand_log_event() {}
+ Log_event_type get_type_code() { return RAND_EVENT;}
+ int get_data_size() { return sizeof(ulonglong) * 2; }
+ int write_data(IO_CACHE* file);
+ bool is_valid() { return 1; }
};
+
class Stop_log_event: public Log_event
{
public:
- Stop_log_event() :Log_event(time(NULL))
+#ifndef MYSQL_CLIENT
+ Stop_log_event() :Log_event()
+ {}
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Stop_log_event(const char* buf, bool old_format):
+ Log_event(buf, old_format)
{}
- Stop_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id_arg):
- Log_event(when_arg,0,0,server_id_arg)
- {
- byte skip[4];
- my_b_read(file, skip, sizeof(skip)); // skip the event length
- }
- Stop_log_event(const char* buf):Log_event(buf)
- {
- }
~Stop_log_event() {}
Log_event_type get_type_code() { return STOP_EVENT;}
- void print(FILE* file, bool short_form = 0, char* last_db = 0);
+ bool is_valid() { return 1; }
};
+
class Rotate_log_event: public Log_event
{
public:
const char* new_log_ident;
- uchar ident_len;
+ ulonglong pos;
+ uint ident_len;
bool alloced;
-
- Rotate_log_event(const char* new_log_ident_arg, uint ident_len_arg = 0) :
- Log_event(time(NULL)),
- new_log_ident(new_log_ident_arg),
- ident_len(ident_len_arg ? ident_len_arg : (uint) strlen(new_log_ident_arg)),
- alloced(0)
+#ifndef MYSQL_CLIENT
+ Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg,
+ uint ident_len_arg = 0,
+ ulonglong pos_arg = LOG_EVENT_OFFSET)
+ :Log_event(), new_log_ident(new_log_ident_arg),
+ pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
+ (uint) strlen(new_log_ident_arg)), alloced(0)
{}
-
- Rotate_log_event(IO_CACHE* file, time_t when, uint32 server_id_arg) ;
- Rotate_log_event(const char* buf, int event_len);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Rotate_log_event(const char* buf, int event_len, bool old_format);
~Rotate_log_event()
{
if (alloced)
my_free((gptr) new_log_ident, MYF(0));
}
Log_event_type get_type_code() { return ROTATE_EVENT;}
- int get_data_size() { return ident_len;}
+ int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
+ bool is_valid() { return new_log_ident != 0; }
int write_data(IO_CACHE* file);
-
+};
+
+/* the classes below are for the new LOAD DATA INFILE logging */
+
+class Create_file_log_event: public Load_log_event
+{
+protected:
+ /*
+ Pretend we are Load event, so we can write out just
+ our Load part - used on the slave when writing event out to
+ SQL_LOAD-*.info file
+ */
+ bool fake_base;
+public:
+ char* block;
+ uint block_len;
+ uint file_id;
+ bool inited_from_old;
+
+#ifndef MYSQL_CLIENT
+ Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
+ const char* table_name_arg,
+ List<Item>& fields_arg,
+ enum enum_duplicates handle_dup,
+ char* block_arg, uint block_len_arg,
+ bool using_trans);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
+ void print(FILE* file, bool short_form, char* last_db, bool enable_local);
+#endif
+
+ Create_file_log_event(const char* buf, int event_len, bool old_format);
+ ~Create_file_log_event() {}
+
+ Log_event_type get_type_code()
+ {
+ return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT;
+ }
+ int get_data_size()
+ {
+ return (fake_base ? Load_log_event::get_data_size() :
+ Load_log_event::get_data_size() +
+ 4 + 1 + block_len);
+ }
+ int get_data_body_offset()
+ {
+ return (fake_base ? LOAD_EVENT_OVERHEAD:
+ LOAD_EVENT_OVERHEAD + CREATE_FILE_HEADER_LEN);
+ }
+ bool is_valid() { return inited_from_old || block != 0; }
+ int write_data_header(IO_CACHE* file);
+ int write_data_body(IO_CACHE* file);
+ /*
+ Cut out Create_file extentions and
+ write it as Load event - used on the slave
+ */
+ int write_base(IO_CACHE* file);
};
+
+class Append_block_log_event: public Log_event
+{
+public:
+ char* block;
+ uint block_len;
+ uint file_id;
+ /*
+ 'db' is filled when the event is created in mysql_load() (the event needs to
+ have a 'db' member to be well filtered by binlog-*-db rules). 'db' is not
+ written to the binlog (it's not used by Append_block_log_event::write()), so
+ it can't be read in the Append_block_log_event(const char* buf, int
+ event_len) constructor.
+ In other words, 'db' is used only for filtering by binlog-*-db rules.
+ Create_file_log_event is different: its 'db' (which is inherited from
+ Load_log_event) is written to the binlog and can be re-read.
+ */
+ const char* db;
+
+#ifndef MYSQL_CLIENT
+ Append_block_log_event(THD* thd, const char* db_arg, char* block_arg,
+ uint block_len_arg, bool using_trans);
+ int exec_event(struct st_relay_log_info* rli);
+ void pack_info(String* packet);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
+
+ Append_block_log_event(const char* buf, int event_len);
+ ~Append_block_log_event() {}
+ Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
+ int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
+ bool is_valid() { return block != 0; }
+ int write_data(IO_CACHE* file);
+ const char* get_db() { return db; }
+};
+
+
+class Delete_file_log_event: public Log_event
+{
+public:
+ uint file_id;
+ const char* db; /* see comment in Append_block_log_event */
+
+#ifndef MYSQL_CLIENT
+ Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Delete_file_log_event(const char* buf, int event_len);
+ ~Delete_file_log_event() {}
+ Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
+ int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
+ bool is_valid() { return file_id != 0; }
+ int write_data(IO_CACHE* file);
+ const char* get_db() { return db; }
+};
+
+class Execute_load_log_event: public Log_event
+{
+public:
+ uint file_id;
+ const char* db; /* see comment in Append_block_log_event */
+
+#ifndef MYSQL_CLIENT
+ Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans);
+ void pack_info(String* packet);
+ int exec_event(struct st_relay_log_info* rli);
+#else
+ void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif
+
+ Execute_load_log_event(const char* buf, int event_len);
+ ~Execute_load_log_event() {}
+ Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
+ int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
+ bool is_valid() { return file_id != 0; }
+ int write_data(IO_CACHE* file);
+ const char* get_db() { return db; }
+};
+
+#ifdef MYSQL_CLIENT
+class Unknown_log_event: public Log_event
+{
+public:
+ Unknown_log_event(const char* buf, bool old_format):
+ Log_event(buf, old_format)
+ {}
+ ~Unknown_log_event() {}
+ void print(FILE* file, bool short_form= 0, char* last_db= 0);
+ Log_event_type get_type_code() { return UNKNOWN_EVENT;}
+ bool is_valid() { return 1; }
+};
+#endif
+
+#endif /* _log_event_h */
diff --git a/sql/matherr.c b/sql/matherr.c
index 8523a78ce94..ea0c15d2feb 100644
--- a/sql/matherr.c
+++ b/sql/matherr.c
@@ -1,22 +1,22 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Fix that we got POSTFIX_ERROR when doing unreasonable math (not core) */
-#include <global.h>
+#include <my_global.h>
#include <errno.h>
/* Fix that we gets POSTFIX_ERROR when error in math */
diff --git a/sql/md5.c b/sql/md5.c
deleted file mode 100644
index 4c2e80107b8..00000000000
--- a/sql/md5.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
-*/
-
-/*
- Changes by Monty:
- Replace of MD5_memset and MD5_memcpy with memset & memcpy
-*/
-
-#include <global.h>
-#include <m_string.h>
-#include "md5.h"
-
-/* Constants for MD5Transform routine. */
-
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-
-
-static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
-static void Encode PROTO_LIST
- ((unsigned char *, UINT4 *, unsigned int));
-static void Decode PROTO_LIST
- ((UINT4 *, unsigned char *, unsigned int));
-#ifdef OLD_CODE
-static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
-static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
-#else
-#define MD5_memcpy(A,B,C) memcpy((char*) (A),(char*) (B), (C))
-#define MD5_memset(A,B,C) memset((char*) (A),(B), (C))
-#endif
-
-static unsigned char PADDING[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* F, G, H and I are basic MD5 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits.
- */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-Rotation is separate from addition to prevent recomputation.
- */
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-
-/* MD5 initialization. Begins an MD5 operation, writing a new context.
- */
-void MD5Init (MD5_CTX *context) /* context */
-{
- context->count[0] = context->count[1] = 0;
- /* Load magic initialization constants.
-*/
- context->state[0] = 0x67452301;
- context->state[1] = 0xefcdab89;
- context->state[2] = 0x98badcfe;
- context->state[3] = 0x10325476;
-}
-
-/* MD5 block update operation. Continues an MD5 message-digest
- operation, processing another message block, and updating the
- context.
- */
-void MD5Update (
-MD5_CTX *context, /* context */
-unsigned char *input, /* input block */
-unsigned int inputLen) /* length of input block */
-{
- unsigned int i, idx, partLen;
-
- /* Compute number of bytes mod 64 */
- idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
-
-
- /* Update number of bits */
- if ((context->count[0] += ((UINT4)inputLen << 3))
- < ((UINT4)inputLen << 3))
- context->count[1]++;
- context->count[1] += ((UINT4)inputLen >> 29);
-
- partLen = 64 - idx;
-
- /* Transform as many times as possible.
-*/
- if (inputLen >= partLen) {
- MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen);
- MD5Transform(context->state, context->buffer);
-
- for (i = partLen; i + 63 < inputLen; i += 64)
- MD5Transform (context->state, &input[i]);
-
- idx = 0;
- }
- else
- i = 0;
-
- /* Buffer remaining input */
- MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i],
- inputLen-i);
-}
-
-/* MD5 finalization. Ends an MD5 message-digest operation, writing the
- the message digest and zeroizing the context.
- */
-void MD5Final (
-unsigned char digest[16], /* message digest */
-MD5_CTX *context) /* context */
-{
- unsigned char bits[8];
- unsigned int idx, padLen;
-
- /* Save number of bits */
- Encode (bits, context->count, 8);
-
- /* Pad out to 56 mod 64.
-*/
- idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
- padLen = (idx < 56) ? (56 - idx) : (120 - idx);
- MD5Update (context, PADDING, padLen);
-
- /* Append length (before padding) */
- MD5Update (context, bits, 8);
-
- /* Store state in digest */
- Encode (digest, context->state, 16);
-
- /* Zeroize sensitive information.
-*/
- MD5_memset ((POINTER)context, 0, sizeof (*context));
-}
-
-/* MD5 basic transformation. Transforms state based on block.
- */
-static void MD5Transform (
-UINT4 state[4],
-unsigned char block[64])
-{
- UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
- Decode (x, block, 64);
-
- /* Round 1 */
- FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
- FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
- FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
- FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
- FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
- FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
- FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
- FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
- FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
- FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
- FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
- FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
- FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
- FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
- FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
- FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
- GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
- GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
- GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
- GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
- GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
- GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
- GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
- GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
- GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
- GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
- GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
- GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
- GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
- GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
- GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
- GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
- /* Round 3 */
- HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
- HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
- HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
- HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
- HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
- HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
- HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
- HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
- HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
- HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
- HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
- HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
- HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
- HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
- HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
- HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
- /* Round 4 */
- II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
- II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
- II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
- II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
- II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
- II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
- II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
- II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
- II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
- II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
- II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
- II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
- II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
- II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
- II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
- II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-
- /* Zeroize sensitive information.
-*/
- MD5_memset ((POINTER)x, 0, sizeof (x));
-}
-
-/* Encodes input (UINT4) into output (unsigned char). Assumes len is
- a multiple of 4.
- */
-static void Encode (
-unsigned char *output,
-UINT4 *input,
-unsigned int len)
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4) {
- output[j] = (unsigned char)(input[i] & 0xff);
- output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
- output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
- output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
- }
-}
-
-
-/* Decodes input (unsigned char) into output (UINT4). Assumes len is
- a multiple of 4.
- */
-static void Decode (
-UINT4 *output,
-unsigned char *input,
-unsigned int len)
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
- (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
-}
-
-/* Note: Replace "for loop" with standard memcpy if possible.
- */
-
-#ifndef MD5_memcpy
-static void MD5_memcpy (output, input, len)
-POINTER output;
-POINTER input;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- output[i] = input[i];
-}
-#endif
-
-/* Note: Replace "for loop" with standard memset if possible.
- */
-
-#ifndef MD5_memset
-static void MD5_memset (output, value, len)
-POINTER output;
-int value;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- ((char *)output)[i] = (char)value;
-}
-#endif
diff --git a/sql/md5.h b/sql/md5.h
deleted file mode 100644
index 862129391f1..00000000000
--- a/sql/md5.h
+++ /dev/null
@@ -1,80 +0,0 @@
-
-/* MD5.H - header file for MD5C.C
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
- */
-
-/* GLOBAL.H - RSAREF types and constants
- */
-
-/* PROTOTYPES should be set to one if and only if the compiler supports
- function argument prototyping.
-The following makes PROTOTYPES default to 0 if it has not already
- been defined with C compiler flags.
- */
-
-/* egcs 1.1.2 under linux didn't defined it.... :( */
-
-#ifndef PROTOTYPES
-#define PROTOTYPES 1 /* Assume prototypes */
-#endif
-
-/* POINTER defines a generic pointer type */
-typedef unsigned char *POINTER;
-
-/* UINT2 defines a two byte word */
-typedef uint16 UINT2; /* Fix for MySQL / Alpha */
-
-/* UINT4 defines a four byte word */
-typedef uint32 UINT4; /* Fix for MySQL / Alpha */
-
-/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
-If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
- returns an empty list.
- */
-#if PROTOTYPES
-#define PROTO_LIST(list) list
-#else
-#define PROTO_LIST(list) ()
-#endif
-
-
-/* MD5 context. */
-typedef struct {
- UINT4 state[4]; /* state (ABCD) */
- UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
- unsigned char buffer[64]; /* input buffer */
-} MD5_CTX;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void MD5Init PROTO_LIST ((MD5_CTX *));
- void MD5Update PROTO_LIST
- ((MD5_CTX *, unsigned char *, unsigned int));
- void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc
index cddacaa820f..c79317cfeb3 100644
--- a/sql/mf_iocache.cc
+++ b/sql/mf_iocache.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -42,293 +42,6 @@ static void my_aiowait(my_aio_result *result);
extern "C" {
/*
- ** if cachesize == 0 then use default cachesize (from s-file)
- ** if file == -1 then real_open_cached_file() will be called.
- ** returns 0 if ok
- */
-
-int init_io_cache(IO_CACHE *info, File file, uint cachesize,
- enum cache_type type, my_off_t seek_offset,
- pbool use_async_io, myf cache_myflags)
-{
- uint min_cache;
- DBUG_ENTER("init_io_cache");
- DBUG_PRINT("enter",("type: %d pos: %ld",(int) type, (ulong) seek_offset));
-
- /* There is no file in net_reading */
- info->file= file;
- if (!cachesize)
- if (! (cachesize= my_default_record_cache_size))
- DBUG_RETURN(1); /* No cache requested */
- min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
- if (type == READ_CACHE)
- { /* Assume file isn't growing */
- if (cache_myflags & MY_DONT_CHECK_FILESIZE)
- {
- cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
- }
- else
- {
- my_off_t file_pos,end_of_file;
- if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
- DBUG_RETURN(1);
- end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
- if (end_of_file < seek_offset)
- end_of_file=seek_offset;
- VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
- if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
- {
- cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
- use_async_io=0; /* No nead to use async */
- }
- }
- }
- if ((int) type < (int) READ_NET)
- {
- for (;;)
- {
- cachesize=(uint) ((ulong) (cachesize + min_cache-1) &
- (ulong) ~(min_cache-1));
- if (cachesize < min_cache)
- cachesize = min_cache;
- if ((info->buffer=
- (byte*) my_malloc(cachesize,
- MYF((cache_myflags & ~ MY_WME) |
- (cachesize == min_cache ? MY_WME : 0)))) != 0)
- break; /* Enough memory found */
- if (cachesize == min_cache)
- DBUG_RETURN(2); /* Can't alloc cache */
- cachesize= (uint) ((long) cachesize*3/4); /* Try with less memory */
- }
- }
- else
- info->buffer=0;
- DBUG_PRINT("info",("init_io_cache: cachesize = %u",cachesize));
- info->pos_in_file= seek_offset;
- info->read_length=info->buffer_length=cachesize;
- info->seek_not_done= test(file >= 0 && type != READ_FIFO &&
- type != READ_NET);
- info->myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
- info->rc_request_pos=info->rc_pos=info->buffer;
-
- if (type == READ_CACHE || type == READ_NET || type == READ_FIFO)
- {
- info->rc_end=info->buffer; /* Nothing in cache */
- }
- else /* type == WRITE_CACHE */
- {
- info->rc_end=info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));
- }
- /* end_of_file may be changed by user later */
- info->end_of_file= ((type == READ_NET || type == READ_FIFO ) ? 0
- : ~(my_off_t) 0);
- info->type=type;
- info->error=0;
- info->read_function=(type == READ_NET) ? _my_b_net_read : _my_b_read; /* net | file */
-#ifdef HAVE_AIOWAIT
- if (use_async_io && ! my_disable_async_io)
- {
- DBUG_PRINT("info",("Using async io"));
- info->read_length/=2;
- info->read_function=_my_b_async_read;
- }
- info->inited=info->aio_result.pending=0;
-#endif
- DBUG_RETURN(0);
-} /* init_io_cache */
-
-
- /* Wait until current request is ready */
-
-#ifdef HAVE_AIOWAIT
-static void my_aiowait(my_aio_result *result)
-{
- if (result->pending)
- {
- struct aio_result_t *tmp;
- for (;;)
- {
- if ((int) (tmp=aiowait((struct timeval *) 0)) == -1)
- {
- if (errno == EINTR)
- continue;
- DBUG_PRINT("error",("No aio request, error: %d",errno));
- result->pending=0; /* Assume everythings is ok */
- break;
- }
- ((my_aio_result*) tmp)->pending=0;
- if ((my_aio_result*) tmp == result)
- break;
- }
- }
- return;
-}
-#endif
-
- /* Use this to reset cache to start or other type */
- /* Some simple optimizing is done when reinit in current buffer */
-
-my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
- my_off_t seek_offset,
- pbool use_async_io __attribute__((unused)),
- pbool clear_cache)
-{
- DBUG_ENTER("reinit_io_cache");
-
- info->seek_not_done= test(info->file >= 0); /* Seek not done */
-
- /* If the whole file is in memory, avoid flushing to disk */
- if (! clear_cache &&
- seek_offset >= info->pos_in_file &&
- seek_offset <= info->pos_in_file +
- (uint) (info->rc_end - info->rc_request_pos))
- { /* use current buffer */
- if (info->type == WRITE_CACHE && type == READ_CACHE)
- {
- info->rc_end=info->rc_pos;
- info->end_of_file=my_b_tell(info);
- }
- else if (type == WRITE_CACHE)
- {
- if (info->type == READ_CACHE)
- info->rc_end=info->buffer+info->buffer_length;
- info->end_of_file = ~(my_off_t) 0;
- }
- info->rc_pos=info->rc_request_pos+(seek_offset-info->pos_in_file);
-#ifdef HAVE_AIOWAIT
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
-#endif
- }
- else
- {
- /*
- If we change from WRITE_CACHE to READ_CACHE, assume that everything
- after the current positions should be ignored
- */
- if (info->type == WRITE_CACHE && type == READ_CACHE)
- info->end_of_file=my_b_tell(info);
- /* No need to flush cache if we want to reuse it */
- if ((type != WRITE_CACHE || !clear_cache) && flush_io_cache(info))
- DBUG_RETURN(1);
- if (info->pos_in_file != seek_offset)
- {
- info->pos_in_file=seek_offset;
- info->seek_not_done=1;
- }
- info->rc_request_pos=info->rc_pos=info->buffer;
- if (type == READ_CACHE || type == READ_NET || type == READ_FIFO)
- {
- info->rc_end=info->buffer; /* Nothing in cache */
- }
- else
- {
- info->rc_end=info->buffer+info->buffer_length-
- (seek_offset & (IO_SIZE-1));
- info->end_of_file= ((type == READ_NET || type == READ_FIFO) ? 0 :
- ~(my_off_t) 0);
- }
- }
- info->type=type;
- info->error=0;
- info->read_function=(type == READ_NET) ? _my_b_net_read : _my_b_read;
-#ifdef HAVE_AIOWAIT
- if (type != READ_NET)
- {
- if (use_async_io && ! my_disable_async_io &&
- ((ulong) info->buffer_length <
- (ulong) (info->end_of_file - seek_offset)))
- {
- info->read_length=info->buffer_length/2;
- info->read_function=_my_b_async_read;
- }
- }
- info->inited=0;
-#endif
- DBUG_RETURN(0);
-} /* init_io_cache */
-
-
-
- /*
- Read buffered. Returns 1 if can't read requested characters
- This function is only called from the my_b_read() macro
- when there isn't enough characters in the buffer to
- satisfy the request.
- Returns 0 we succeeded in reading all data
- */
-
-int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
-{
- uint length,diff_length,left_length;
- my_off_t max_length, pos_in_file;
-
- if ((left_length=(uint) (info->rc_end-info->rc_pos)))
- {
- dbug_assert(Count >= left_length); /* User is not using my_b_read() */
- memcpy(Buffer,info->rc_pos, (size_t) (left_length));
- Buffer+=left_length;
- Count-=left_length;
- }
- /* pos_in_file always point on where info->buffer was read */
- pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
- if (info->seek_not_done)
- { /* File touched, do seek */
- VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
- info->seek_not_done=0;
- }
- diff_length=(uint) (pos_in_file & (IO_SIZE-1));
- if (Count >= (uint) (IO_SIZE+(IO_SIZE-diff_length)))
- { /* Fill first intern buffer */
- uint read_length;
- if (info->end_of_file == pos_in_file)
- { /* End of file */
- info->error=(int) left_length;
- return 1;
- }
- length=(Count & (uint) ~(IO_SIZE-1))-diff_length;
- if ((read_length=my_read(info->file,Buffer,(uint) length,info->myflags))
- != (uint) length)
- {
- info->error= read_length == (uint) -1 ? -1 :
- (int) (read_length+left_length);
- return 1;
- }
- Count-=length;
- Buffer+=length;
- pos_in_file+=length;
- left_length+=length;
- diff_length=0;
- }
- max_length=info->read_length-diff_length;
- if (info->type != READ_FIFO &&
- (info->end_of_file - pos_in_file) < max_length)
- max_length = info->end_of_file - pos_in_file;
- if (!max_length)
- {
- if (Count)
- {
- info->error= left_length; /* We only got this many char */
- return 1;
- }
- length=0; /* Didn't read any chars */
- }
- else if ((length=my_read(info->file,info->buffer,(uint) max_length,
- info->myflags)) < Count ||
- length == (uint) -1)
- {
- if (length != (uint) -1)
- memcpy(Buffer,info->buffer,(size_t) length);
- info->error= length == (uint) -1 ? -1 : (int) (length+left_length);
- return 1;
- }
- info->rc_pos=info->buffer+Count;
- info->rc_end=info->buffer+length;
- info->pos_in_file=pos_in_file;
- memcpy(Buffer,info->buffer,(size_t) Count);
- return 0;
-}
-
- /*
** Read buffered from the net.
** Returns 1 if can't read requested characters
** Returns 0 if record read
@@ -337,353 +50,38 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
int _my_b_net_read(register IO_CACHE *info, byte *Buffer,
uint Count __attribute__((unused)))
{
- int read_length;
+ ulong read_length;
NET *net= &(current_thd)->net;
+ DBUG_ENTER("_my_b_net_read");
- if (info->end_of_file)
- return 1; /* because my_b_get (no _) takes 1 byte at a time */
+ if (!info->end_of_file)
+ DBUG_RETURN(1); /* because my_b_get (no _) takes 1 byte at a time */
read_length=my_net_read(net);
- if (read_length == (int) packet_error)
+ if (read_length == packet_error)
{
info->error= -1;
- return 1;
+ DBUG_RETURN(1);
}
if (read_length == 0)
{
- /* End of file from client */
- info->end_of_file = 1; return 1;
+ info->end_of_file= 0; /* End of file from client */
+ DBUG_RETURN(1);
}
/* to set up stuff for my_b_get (no _) */
- info->rc_end = (info->rc_pos = (byte*) net->read_pos) + read_length;
- Buffer[0] = info->rc_pos[0]; /* length is always 1 */
- info->rc_pos++;
- return 0;
-}
-
-#ifdef HAVE_AIOWAIT
-
-int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
-{
- uint length,read_length,diff_length,left_length,use_length,org_Count;
- my_off_t max_length;
- my_off_t next_pos_in_file;
- byte *read_buffer;
-
- memcpy(Buffer,info->rc_pos,
- (size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
- Buffer+=left_length;
- org_Count=Count;
- Count-=left_length;
-
- if (info->inited)
- { /* wait for read block */
- info->inited=0; /* No more block to read */
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
- if (info->aio_result.result.aio_errno)
- {
- if (info->myflags & MY_WME)
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(info->file),
- info->aio_result.result.aio_errno);
- my_errno=info->aio_result.result.aio_errno;
- info->error= -1;
- return(1);
- }
- if (! (read_length = (uint) info->aio_result.result.aio_return) ||
- read_length == (uint) -1)
- {
- my_errno=0; /* For testing */
- info->error= (read_length == (uint) -1 ? -1 :
- (int) (read_length+left_length));
- return(1);
- }
- info->pos_in_file+=(uint) (info->rc_end - info->rc_request_pos);
-
- if (info->rc_request_pos != info->buffer)
- info->rc_request_pos=info->buffer;
- else
- info->rc_request_pos=info->buffer+info->read_length;
- info->rc_pos=info->rc_request_pos;
- next_pos_in_file=info->aio_read_pos+read_length;
-
- /* Check if pos_in_file is changed
- (_ni_read_cache may have skipped some bytes) */
-
- if (info->aio_read_pos < info->pos_in_file)
- { /* Fix if skipped bytes */
- if (info->aio_read_pos + read_length < info->pos_in_file)
- {
- read_length=0; /* Skipp block */
- next_pos_in_file=info->pos_in_file;
- }
- else
- {
- my_off_t offset= (info->pos_in_file - info->aio_read_pos);
- info->pos_in_file=info->aio_read_pos; /* Whe are here */
- info->rc_pos=info->rc_request_pos+offset;
- read_length-=offset; /* Bytes left from rc_pos */
- }
- }
-#ifndef DBUG_OFF
- if (info->aio_read_pos > info->pos_in_file)
- {
- my_errno=EINVAL;
- return(info->read_length= -1);
- }
-#endif
- /* Copy found bytes to buffer */
- length=min(Count,read_length);
- memcpy(Buffer,info->rc_pos,(size_t) length);
- Buffer+=length;
- Count-=length;
- left_length+=length;
- info->rc_end=info->rc_pos+read_length;
- info->rc_pos+=length;
- }
- else
- next_pos_in_file=(info->pos_in_file+ (uint)
- (info->rc_end - info->rc_request_pos));
-
- /* If reading large blocks, or first read or read with skipp */
- if (Count)
- {
- if (next_pos_in_file == info->end_of_file)
- {
- info->error=(int) (read_length+left_length);
- return 1;
- }
- VOID(my_seek(info->file,next_pos_in_file,MY_SEEK_SET,MYF(0)));
- read_length=IO_SIZE*2- (uint) (next_pos_in_file & (IO_SIZE-1));
- if (Count < read_length)
- { /* Small block, read to cache */
- if ((read_length=my_read(info->file,info->rc_request_pos,
- read_length, info->myflags)) == (uint) -1)
- return info->error= -1;
- use_length=min(Count,read_length);
- memcpy(Buffer,info->rc_request_pos,(size_t) use_length);
- info->rc_pos=info->rc_request_pos+Count;
- info->rc_end=info->rc_request_pos+read_length;
- info->pos_in_file=next_pos_in_file; /* Start of block in cache */
- next_pos_in_file+=read_length;
-
- if (Count != use_length)
- { /* Didn't find hole block */
- if (info->myflags & (MY_WME | MY_FAE | MY_FNABP) && Count != org_Count)
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(info->file),my_errno);
- info->error=(int) (read_length+left_length);
- return 1;
- }
- }
- else
- { /* Big block, don't cache it */
- if ((read_length=my_read(info->file,Buffer,(uint) Count,info->myflags))
- != Count)
- {
- info->error= read_length == (uint) -1 ? -1 : read_length+left_length;
- return 1;
- }
- info->rc_pos=info->rc_end=info->rc_request_pos;
- info->pos_in_file=(next_pos_in_file+=Count);
- }
- }
-
- /* Read next block with asyncronic io */
- max_length=info->end_of_file - next_pos_in_file;
- diff_length=(next_pos_in_file & (IO_SIZE-1));
-
- if (max_length > (my_off_t) info->read_length - diff_length)
- max_length= (my_off_t) info->read_length - diff_length;
- if (info->rc_request_pos != info->buffer)
- read_buffer=info->buffer;
- else
- read_buffer=info->buffer+info->read_length;
- info->aio_read_pos=next_pos_in_file;
- if (max_length)
- {
- info->aio_result.result.aio_errno=AIO_INPROGRESS; /* Marker for test */
- DBUG_PRINT("aioread",("filepos: %ld length: %ld",
- (ulong) next_pos_in_file,(ulong) max_length));
- if (aioread(info->file,read_buffer,(int) max_length,
- (my_off_t) next_pos_in_file,MY_SEEK_SET,
- &info->aio_result.result))
- { /* Skipp async io */
- my_errno=errno;
- DBUG_PRINT("error",("got error: %d, aio_result: %d from aioread, async skipped",
- errno, info->aio_result.result.aio_errno));
- if (info->rc_request_pos != info->buffer)
- {
- bmove(info->buffer,info->rc_request_pos,
- (uint) (info->rc_end - info->rc_pos));
- info->rc_request_pos=info->buffer;
- info->rc_pos-=info->read_length;
- info->rc_end-=info->read_length;
- }
- info->read_length=info->buffer_length; /* Use hole buffer */
- info->read_function=_my_b_read; /* Use normal IO_READ next */
- }
- else
- info->inited=info->aio_result.pending=1;
- }
- return 0; /* Block read, async in use */
-} /* _my_b_async_read */
-#endif
-
-
-/* Read one byte when buffer is empty */
-
-int _my_b_get(IO_CACHE *info)
-{
- byte buff;
- if ((*(info)->read_function)(info,&buff,1))
- return my_b_EOF;
- return (int) (uchar) buff;
-}
-
- /* Returns != 0 if error on write */
-
-int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
-{
- uint rest_length,length;
-
- rest_length=(uint) (info->rc_end - info->rc_pos);
- memcpy(info->rc_pos,Buffer,(size_t) rest_length);
- Buffer+=rest_length;
- Count-=rest_length;
- info->rc_pos+=rest_length;
- if (info->pos_in_file+info->buffer_length > info->end_of_file)
- {
- my_errno=errno=EFBIG;
- return info->error = -1;
- }
- if (flush_io_cache(info))
- return 1;
- if (Count >= IO_SIZE)
- { /* Fill first intern buffer */
- length=Count & (uint) ~(IO_SIZE-1);
- if (info->seek_not_done)
- { /* File touched, do seek */
- VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)));
- info->seek_not_done=0;
- }
- if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
- return info->error= -1;
- Count-=length;
- Buffer+=length;
- info->pos_in_file+=length;
- }
- memcpy(info->rc_pos,Buffer,(size_t) Count);
- info->rc_pos+=Count;
- return 0;
-}
-
-
-/*
- Write a block to disk where part of the data may be inside the record
- buffer. As all write calls to the data goes through the cache,
- we will never get a seek over the end of the buffer
-*/
-
-int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
- my_off_t pos)
-{
- uint length;
- int error=0;
-
- if (pos < info->pos_in_file)
- {
- /* Of no overlap, write everything without buffering */
- if (pos + Count <= info->pos_in_file)
- return my_pwrite(info->file, Buffer, Count, pos,
- info->myflags | MY_NABP);
- /* Write the part of the block that is before buffer */
- length= (uint) (info->pos_in_file - pos);
- if (my_pwrite(info->file, Buffer, length, pos, info->myflags | MY_NABP))
- info->error=error=-1;
- Buffer+=length;
- pos+= length;
- Count-= length;
- }
-
- /* Check if we want to write inside the used part of the buffer.*/
- length= (uint) (info->rc_end - info->buffer);
- if (pos < info->pos_in_file + length)
- {
- uint offset= (uint) (pos - info->pos_in_file);
- length-=offset;
- if (length > Count)
- length=Count;
- memcpy(info->buffer+offset, Buffer, length);
- Buffer+=length;
- Count-= length;
- /* Fix length of buffer if the new data was larger */
- if (info->buffer+length > info->rc_pos)
- info->rc_pos=info->buffer+length;
- if (!Count)
- return (error);
- }
- /* Write at the end of the current buffer; This is the normal case */
- if (_my_b_write(info, Buffer, Count))
- error= -1;
- return error;
-}
+ info->read_end = (info->read_pos = (byte*) net->read_pos) + read_length;
+ Buffer[0] = info->read_pos[0]; /* length is always 1 */
- /* Flush write cache */
+ /*
+ info->request_pos is used by log_loaded_block() to know the size
+ of the current block.
+ info->pos_in_file is used by log_loaded_block() too.
+ */
+ info->pos_in_file+= read_length;
+ info->request_pos=info->read_pos;
-int flush_io_cache(IO_CACHE *info)
-{
- uint length;
- DBUG_ENTER("flush_io_cache");
+ info->read_pos++;
- if (info->type == WRITE_CACHE)
- {
- if (info->file == -1)
- {
- if (real_open_cached_file(info))
- DBUG_RETURN((info->error= -1));
- }
- if (info->rc_pos != info->buffer)
- {
- length=(uint) (info->rc_pos - info->buffer);
- if (info->seek_not_done)
- { /* File touched, do seek */
- if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) ==
- MY_FILEPOS_ERROR)
- DBUG_RETURN((info->error= -1));
- info->seek_not_done=0;
- }
- info->rc_pos=info->buffer;
- info->pos_in_file+=length;
- info->rc_end=(info->buffer+info->buffer_length-
- (info->pos_in_file & (IO_SIZE-1)));
- if (my_write(info->file,info->buffer,length,info->myflags | MY_NABP))
- DBUG_RETURN((info->error= -1));
- DBUG_RETURN(0);
- }
- }
-#ifdef HAVE_AIOWAIT
- else if (info->type != READ_NET)
- {
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
- info->inited=0;
- }
-#endif
DBUG_RETURN(0);
}
-
-int end_io_cache(IO_CACHE *info)
-{
- int error=0;
- DBUG_ENTER("end_io_cache");
- if (info->buffer)
- {
- if (info->file != -1) /* File doesn't exist */
- error=flush_io_cache(info);
- my_free((gptr) info->buffer,MYF(MY_WME));
- info->buffer=info->rc_pos=(byte*) 0;
- }
- DBUG_RETURN(error);
-} /* end_io_cache */
-
} /* extern "C" */
diff --git a/sql/mini_client.cc b/sql/mini_client.cc
index cd56081e6a8..7db9f046389 100644
--- a/sql/mini_client.cc
+++ b/sql/mini_client.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,30 +18,20 @@
mini MySQL client to be included into the server to do server to server
commincation by Sasha Pachev
- Note: all file-global symbols must begin with mc_ , even the static
- ones, just in case we decide to make them external at some point
+ Note: all file-global symbols must begin with mc_ , even the static ones,
+ just in case we decide to make them external at some point
*/
-#include <global.h>
-#define DONT_USE_RAID
-#if defined(__WIN__)
-#include <winsock.h>
-#include <odbcinst.h>
-/* Disable alarms */
-typedef my_bool ALARM;
-#define thr_alarm_init(A) (*(A))=0
-#define thr_alarm_in_use(A) (*(A))
-#define thr_end_alarm(A)
-#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C))
-inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused)))
-{
- *A=1;
- return 0;
-}
-#define thr_got_alarm(A) 0
+#include <my_global.h>
+/* my_pthread must be included early to be able to fix things */
+#if defined(THREAD)
+#include <my_pthread.h> /* because of signal() */
#endif
-
+#include <thr_alarm.h>
+#include <mysql_embed.h>
+#include <mysql_com.h>
#include <my_sys.h>
+#include <violite.h>
#include <mysys_err.h>
#include <m_string.h>
#include <m_ctype.h>
@@ -50,15 +40,12 @@ inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __a
#include "mysql_version.h"
#include "mysqld_error.h"
#include "errmsg.h"
-#include <violite.h>
-#if defined( OS2) && defined( MYSQL_SERVER)
+#if defined( OS2) && defined(MYSQL_SERVER)
#undef ER
#define ER CER
#endif
-extern ulong net_read_timeout;
-
extern "C" { // Because of SCO 3.2V4.2
#include <sys/stat.h>
#include <signal.h>
@@ -76,23 +63,29 @@ extern "C" { // Because of SCO 3.2V4.2
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
-#endif
+#endif /*!defined(MSDOS) && !defined(__WIN__) */
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
-#if defined(THREAD)
-#include <my_pthread.h> /* because of signal() */
-#include <thr_alarm.h>
-#endif
#ifndef INADDR_NONE
#define INADDR_NONE -1
#endif
-
}
-static void mc_end_server(MYSQL *mysql);
+static void mc_free_rows(MYSQL_DATA *cur);
+void mc_end_server(MYSQL *mysql);
static int mc_sock_connect(File s, const struct sockaddr *name, uint namelen, uint to);
static void mc_free_old_query(MYSQL *mysql);
+static int mc_send_file_to_server(MYSQL *mysql, const char *filename);
+static my_ulonglong mc_net_field_length_ll(uchar **packet);
+static ulong mc_net_field_length(uchar **packet);
+static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
+ ulong *lengths);
+static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
+ uint fields);
+#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__))
+static int wait_for_data(my_socket fd, uint timeout);
+#endif
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
@@ -189,8 +182,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
** Init MySQL structure or allocate one
****************************************************************************/
-MYSQL * STDCALL
-mc_mysql_init(MYSQL *mysql)
+MYSQL *mc_mysql_init(MYSQL *mysql)
{
init_client_errs();
if (!mysql)
@@ -205,7 +197,7 @@ mc_mysql_init(MYSQL *mysql)
#ifdef __WIN__
mysql->options.connect_timeout=20;
#endif
- mysql->net.timeout = slave_net_timeout;
+ mysql->net.read_timeout = slave_net_timeout;
return mysql;
}
@@ -213,7 +205,7 @@ mc_mysql_init(MYSQL *mysql)
** Shut down connection
**************************************************************************/
-static void
+void
mc_end_server(MYSQL *mysql)
{
DBUG_ENTER("mc_end_server");
@@ -242,104 +234,161 @@ static void mc_free_old_query(MYSQL *mysql)
/****************************************************************************
-* A modified version of connect(). mc_sock_connect() allows you to specify
-* a timeout value, in seconds, that we should wait until we
-* derermine we can't connect to a particular host. If timeout is 0,
-* mc_sock_connect() will behave exactly like connect().
-*
-* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
+ A modified version of connect(). my_connect() allows you to specify
+ a timeout value, in seconds, that we should wait until we
+ derermine we can't connect to a particular host. If timeout is 0,
+ my_connect() will behave exactly like connect().
+
+ Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/
-static int mc_sock_connect(my_socket s, const struct sockaddr *name,
- uint namelen, uint to)
+static int mc_sock_connect(my_socket fd, const struct sockaddr *name,
+ uint namelen, uint timeout)
{
-#if defined(__WIN__) || defined(OS2)
- return connect(s, (struct sockaddr*) name, namelen);
+#if defined(__WIN__) || defined(OS2) || defined(__NETWARE__)
+ return connect(fd, (struct sockaddr*) name, namelen);
#else
int flags, res, s_err;
- SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
- fd_set sfds;
- struct timeval tv;
- /* If they passed us a timeout of zero, we should behave
- * exactly like the normal connect() call does.
- */
+ /*
+ If they passed us a timeout of zero, we should behave
+ exactly like the normal connect() call does.
+ */
- if (to == 0)
- return connect(s, (struct sockaddr*) name, namelen);
+ if (timeout == 0)
+ return connect(fd, (struct sockaddr*) name, namelen);
- flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
+ flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */
#ifdef O_NONBLOCK
- fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
+ fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
#endif
- res = connect(s, (struct sockaddr*) name, namelen);
- s_err = errno; /* Save the error... */
- fcntl(s, F_SETFL, flags);
+ res= connect(fd, (struct sockaddr*) name, namelen);
+ s_err= errno; /* Save the error... */
+ fcntl(fd, F_SETFL, flags);
if ((res != 0) && (s_err != EINPROGRESS))
{
- errno = s_err; /* Restore it */
+ errno= s_err; /* Restore it */
return(-1);
}
if (res == 0) /* Connected quickly! */
return(0);
+ return wait_for_data(fd, timeout);
+#endif
+}
- /* Otherwise, our connection is "in progress." We can use
- * the select() call to wait up to a specified period of time
- * for the connection to suceed. If select() returns 0
- * (after waiting howevermany seconds), our socket never became
- * writable (host is probably unreachable.) Otherwise, if
- * select() returns 1, then one of two conditions exist:
- *
- * 1. An error occured. We use getsockopt() to check for this.
- * 2. The connection was set up sucessfully: getsockopt() will
- * return 0 as an error.
- *
- * Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
- * who posted this method of timing out a connect() in
- * comp.unix.programmer on August 15th, 1997.
- */
+
+/*
+ Wait up to timeout seconds for a connection to be established.
+
+ We prefer to do this with poll() as there is no limitations with this.
+ If not, we will use select()
+*/
+
+#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__))
+
+static int wait_for_data(my_socket fd, uint timeout)
+{
+#ifdef HAVE_POLL
+ struct pollfd ufds;
+ int res;
+
+ ufds.fd= fd;
+ ufds.events= POLLIN | POLLPRI;
+ if (!(res= poll(&ufds, 1, (int) timeout*1000)))
+ {
+ errno= EINTR;
+ return -1;
+ }
+ if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
+ return -1;
+ return 0;
+#else
+ SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
+ fd_set sfds;
+ struct timeval tv;
+ time_t start_time, now_time;
+ int res, s_err;
+
+ if (fd >= FD_SETSIZE) /* Check if wrong error */
+ return 0; /* Can't use timeout */
+
+ /*
+ Our connection is "in progress." We can use the select() call to wait
+ up to a specified period of time for the connection to suceed.
+ If select() returns 0 (after waiting howevermany seconds), our socket
+ never became writable (host is probably unreachable.) Otherwise, if
+ select() returns 1, then one of two conditions exist:
+
+ 1. An error occured. We use getsockopt() to check for this.
+ 2. The connection was set up sucessfully: getsockopt() will
+ return 0 as an error.
+
+ Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
+ who posted this method of timing out a connect() in
+ comp.unix.programmer on August 15th, 1997.
+ */
FD_ZERO(&sfds);
- FD_SET(s, &sfds);
- tv.tv_sec = (long) to;
- tv.tv_usec = 0;
-#ifdef HPUX
- res = select(s+1, NULL, (int*) &sfds, NULL, &tv);
+ FD_SET(fd, &sfds);
+ /*
+ select could be interrupted by a signal, and if it is,
+ the timeout should be adjusted and the select restarted
+ to work around OSes that don't restart select and
+ implementations of select that don't adjust tv upon
+ failure to reflect the time remaining
+ */
+ start_time = time(NULL);
+ for (;;)
+ {
+ tv.tv_sec = (long) timeout;
+ tv.tv_usec = 0;
+#if defined(HPUX10) && defined(THREAD)
+ if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
+ break;
#else
- res = select(s+1, NULL, &sfds, NULL, &tv);
+ if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
+ break;
#endif
- if (res <= 0) /* Never became writable */
- return(-1);
+ if (res == 0) /* timeout */
+ return -1;
+ now_time=time(NULL);
+ timeout-= (uint) (now_time - start_time);
+ if (errno != EINTR || (int) timeout <= 0)
+ return -1;
+ }
- /* select() returned something more interesting than zero, let's
- * see if we have any errors. If the next two statements pass,
- * we've got an open socket!
- */
+ /*
+ select() returned something more interesting than zero, let's
+ see if we have any errors. If the next two statements pass,
+ we've got an open socket!
+ */
s_err=0;
- if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
return(-1);
if (s_err)
- { // getsockopt() could succeed
+ { /* getsockopt could succeed */
errno = s_err;
- return(-1); // but return an error...
+ return(-1); /* but return an error... */
}
- return(0); /* It's all good! */
-#endif
+ return (0); /* ok */
+#endif /* HAVE_POLL */
}
+#endif /* defined(__WIN__) || defined(OS2) || defined(__NETWARE__) */
+
/*****************************************************************************
** read a packet from server. Give error message if socket was down
** or packet is an error message
*****************************************************************************/
-uint STDCALL
+ulong
mc_net_safe_read(MYSQL *mysql)
{
NET *net= &mysql->net;
- uint len=0;
+ ulong len=0;
if (net->vio != 0)
len=my_net_read(net);
@@ -351,7 +400,7 @@ mc_net_safe_read(MYSQL *mysql)
if (socket_errno != SOCKET_EINTR)
{
mc_end_server(mysql);
- if(net->last_errno != ER_NET_PACKET_TOO_LARGE)
+ if (net->last_errno != ER_NET_PACKET_TOO_LARGE)
{
net->last_errno=CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno));
@@ -359,7 +408,7 @@ mc_net_safe_read(MYSQL *mysql)
else
strmov(net->last_error, "Packet too large - increase \
max_allowed_packet on this server");
- }
+ }
return(packet_error);
}
if (net->read_pos[0] == 255)
@@ -372,7 +421,7 @@ max_allowed_packet on this server");
net->last_errno=uint2korr(pos);
pos+=2;
len-=2;
- if(!net->last_errno)
+ if (!net->last_errno)
net->last_errno = CR_UNKNOWN_ERROR;
}
else
@@ -396,34 +445,38 @@ max_allowed_packet on this server");
}
-char * STDCALL mc_mysql_error(MYSQL *mysql)
+char *mc_mysql_error(MYSQL *mysql)
{
return (mysql)->net.last_error;
}
-int STDCALL mc_mysql_errno(MYSQL *mysql)
+int mc_mysql_errno(MYSQL *mysql)
{
return (mysql)->net.last_errno;
}
-my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql)
+
+my_bool mc_mysql_reconnect(MYSQL *mysql)
{
MYSQL tmp_mysql;
DBUG_ENTER("mc_mysql_reconnect");
if (!mysql->reconnect)
+ {
+ mysql->net.last_errno=CR_SERVER_GONE_ERROR;
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno));
DBUG_RETURN(1);
-
+ }
mc_mysql_init(&tmp_mysql);
tmp_mysql.options=mysql->options;
if (!mc_mysql_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
- mysql->db, mysql->port, mysql->unix_socket,
- mysql->client_flag))
- {
- tmp_mysql.reconnect=0;
- mc_mysql_close(&tmp_mysql);
- DBUG_RETURN(1);
- }
+ mysql->db, mysql->port, mysql->unix_socket,
+ mysql->client_flag, mysql->net.read_timeout))
+ {
+ mysql->net.last_errno= tmp_mysql.net.last_errno;
+ strmov(mysql->net.last_error, tmp_mysql.net.last_error);
+ DBUG_RETURN(1);
+ }
tmp_mysql.free_me=mysql->free_me;
mysql->free_me=0;
bzero((char*) &mysql->options,sizeof(&mysql->options));
@@ -436,7 +489,7 @@ my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql)
-int STDCALL
+int
mc_simple_command(MYSQL *mysql,enum enum_server_command command,
const char *arg, uint length, my_bool skipp_check)
{
@@ -446,11 +499,7 @@ mc_simple_command(MYSQL *mysql,enum enum_server_command command,
if (mysql->net.vio == 0)
{ /* Do reconnect if possible */
if (mc_mysql_reconnect(mysql))
- {
- net->last_errno=CR_SERVER_GONE_ERROR;
- strmov(net->last_error,ER(net->last_errno));
goto end;
- }
}
if (mysql->status != MYSQL_STATUS_READY)
{
@@ -471,8 +520,9 @@ mc_simple_command(MYSQL *mysql,enum enum_server_command command,
{
DBUG_PRINT("error",("Can't send command to server. Error: %d",socket_errno));
mc_end_server(mysql);
- if (mc_mysql_reconnect(mysql) ||
- net_write_command(net,(uchar) command,arg,
+ if (mc_mysql_reconnect(mysql))
+ goto end;
+ if (net_write_command(net,(uchar) command,arg,
length ? length :(uint) strlen(arg)))
{
net->last_errno=CR_SERVER_GONE_ERROR;
@@ -489,19 +539,21 @@ mc_simple_command(MYSQL *mysql,enum enum_server_command command,
}
-MYSQL * STDCALL
+MYSQL *
mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
- const char *passwd, const char *db,
- uint port, const char *unix_socket,uint client_flag)
+ const char *passwd, const char *db,
+ uint port, const char *unix_socket,uint client_flag,
+ uint net_read_timeout)
{
- char buff[100],*end,*host_info;
+ char buff[NAME_LEN+USERNAME_LENGTH+100],*end,*host_info;
my_socket sock;
- uint32 ip_addr;
+ in_addr_t ip_addr;
struct sockaddr_in sock_addr;
- uint pkt_length;
+ ulong pkt_length;
NET *net= &mysql->net;
thr_alarm_t alarmed;
- ALARM alarm_buff;
+ ALARM alarm_buff;
+ ulong max_allowed_packet;
#ifdef __WIN__
HANDLE hPipe=INVALID_HANDLE_VALUE;
@@ -510,13 +562,13 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
struct sockaddr_un UNIXaddr;
#endif
DBUG_ENTER("mc_mysql_connect");
-
- DBUG_PRINT("enter",("host: %s db: %s user: %s",
+ DBUG_PRINT("enter",("host: %s db: %s user: %s connect_time_out: %u read_timeout: %u",
host ? host : "(Null)",
db ? db : "(Null)",
- user ? user : "(Null)"));
+ user ? user : "(Null)",
+ net_read_timeout,
+ (uint) slave_net_timeout));
- bzero((char*) &mysql->options,sizeof(mysql->options));
net->vio = 0; /* If something goes wrong */
mysql->charset=default_charset_info; /* Set character set */
if (!port)
@@ -525,13 +577,16 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
unix_socket=MYSQL_UNIX_ADDR;
mysql->reconnect=1; /* Reconnect as default */
+ mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
+ if (!mysql->options.connect_timeout)
+ mysql->options.connect_timeout= net_read_timeout;
/*
** Grab a socket and connect it to the server
*/
#if defined(HAVE_SYS_UN_H)
- if (!host || !strcmp(host,LOCAL_HOST))
+ if ((!host || !strcmp(host,LOCAL_HOST)) && unix_socket)
{
host=LOCAL_HOST;
host_info=(char*) ER(CR_LOCALHOST_CONNECTION);
@@ -546,10 +601,13 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
bzero((char*) &UNIXaddr,sizeof(UNIXaddr));
UNIXaddr.sun_family = AF_UNIX;
strmov(UNIXaddr.sun_path, unix_socket);
- if (mc_sock_connect(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
+ if (mc_sock_connect(sock,
+ my_reinterpret_cast(struct sockaddr *) (&UNIXaddr),
+ sizeof(UNIXaddr),
mysql->options.connect_timeout) <0)
{
- DBUG_PRINT("error",("Got error %d on connect to local server",socket_errno));
+ DBUG_PRINT("error",("Got error %d on connect to local server",
+ socket_errno));
net->last_errno=CR_CONNECTION_ERROR;
sprintf(net->last_error,ER(net->last_errno),unix_socket,socket_errno);
goto error;
@@ -641,7 +699,9 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
my_gethostbyname_r_free();
}
sock_addr.sin_port = (ushort) htons((ushort) port);
- if (mc_sock_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
+ if (mc_sock_connect(sock,
+ my_reinterpret_cast(struct sockaddr *) (&sock_addr),
+ sizeof(sock_addr),
mysql->options.connect_timeout) <0)
{
DBUG_PRINT("error",("Got error %d on connect to '%s'",
@@ -655,19 +715,26 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
if (!net->vio || my_net_init(net, net->vio))
{
vio_delete(net->vio);
- net->vio = 0; // safety
+ net->vio = 0;
net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->last_error,ER(net->last_errno));
goto error;
}
vio_keepalive(net->vio,TRUE);
- net->timeout=slave_net_timeout;
+ net->read_timeout=slave_net_timeout;
/* Get version info */
mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
+ if (mysql->options.connect_timeout &&
+ vio_poll_read(net->vio, mysql->options.connect_timeout))
+ {
+ net->last_errno= CR_SERVER_LOST;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
+ }
if ((pkt_length=mc_net_safe_read(mysql)) == packet_error)
goto error;
- /* Check if version of protocoll matches current one */
+ /* Check if version of protocol matches current one */
mysql->protocol_version= net->read_pos[0];
DBUG_DUMP("packet",(char*) net->read_pos,10);
@@ -685,8 +752,15 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
mysql->thread_id=uint4korr(end+1);
end+=5;
strmake(mysql->scramble_buff,end,8);
- if (pkt_length > (uint) (end+9 - (char*) net->read_pos))
- mysql->server_capabilities=uint2korr(end+9);
+ end+=9;
+ if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
+ mysql->server_capabilities=uint2korr(end);
+ if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
+ {
+ /* New protocol with 16 bytes to describe server characteristics */
+ mysql->server_language=end[2];
+ mysql->server_status=uint2korr(end+3);
+ }
/* Save connection information */
if (!user) user="";
@@ -713,7 +787,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
mysql->unix_socket=0;
strmov(mysql->server_version,(char*) net->read_pos+1);
mysql->port=port;
- mysql->client_flag=client_flag | mysql->options.client_flag;
+ client_flag|=mysql->options.client_flag;
DBUG_PRINT("info",("Server version = '%s' capabilites: %ld",
mysql->server_version,mysql->server_capabilities));
@@ -721,6 +795,10 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
client_flag|=CLIENT_CAPABILITIES;
#ifdef HAVE_OPENSSL
+ if (mysql->options.ssl_key || mysql->options.ssl_cert ||
+ mysql->options.ssl_ca || mysql->options.ssl_capath ||
+ mysql->options.ssl_cipher)
+ mysql->options.use_ssl= 1;
if (mysql->options.use_ssl)
client_flag|=CLIENT_SSL;
#endif /* HAVE_OPENSSL */
@@ -728,8 +806,8 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
if (db)
client_flag|=CLIENT_CONNECT_WITH_DB;
#ifdef HAVE_COMPRESS
- if (mysql->server_capabilities & CLIENT_COMPRESS &&
- (mysql->options.compress || client_flag & CLIENT_COMPRESS))
+ if ((mysql->server_capabilities & CLIENT_COMPRESS) &&
+ (mysql->options.compress || (client_flag & CLIENT_COMPRESS)))
client_flag|=CLIENT_COMPRESS; /* We will use compression */
else
#endif
@@ -756,42 +834,54 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
mysql->client_flag=client_flag;
#ifdef HAVE_OPENSSL
- /* Oops.. are we careful enough to not send ANY information */
- /* without encryption? */
+ /*
+ Oops.. are we careful enough to not send ANY information without
+ encryption?
+ */
if (client_flag & CLIENT_SSL)
{
if (my_net_write(net,buff,(uint) (2)) || net_flush(net))
+ {
+ net->last_errno= CR_SERVER_LOST;
+ strmov(net->last_error,ER(net->last_errno));
goto error;
+ }
/* Do the SSL layering. */
DBUG_PRINT("info", ("IO layer change in progress..."));
- VioSSLConnectorFd* connector_fd = (VioSSLConnectorFd*)
- (mysql->connector_fd);
- VioSocket* vio_socket = (VioSocket*)(mysql->net.vio);
- VioSSL* vio_ssl = connector_fd->connect(vio_socket);
- mysql->net.vio = (NetVio*)(vio_ssl);
+ DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context));
+ sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio, (long)(mysql->options.connect_timeout));
+ DBUG_PRINT("info", ("IO layer change done!"));
}
#endif /* HAVE_OPENSSL */
-
+ max_allowed_packet=mysql->net.max_packet_size;
int3store(buff+2,max_allowed_packet);
+
+
if (user && user[0])
strmake(buff+5,user,32);
else
- {
- user = getenv("USER");
- if(!user) user = "mysql";
- strmov((char*) buff+5, user );
- }
+ {
+ user = getenv("USER");
+ if (!user) user = "mysql";
+ strmov((char*) buff+5, user );
+ }
DBUG_PRINT("info",("user: %s",buff+5));
end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd,
(my_bool) (mysql->protocol_version == 9));
if (db)
{
- end=strmov(end+1,db);
+ end=strmake(end+1,db,NAME_LEN);
mysql->db=my_strdup(db,MYF(MY_WME));
+ db=0;
+ }
+ if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
+ {
+ net->last_errno= CR_SERVER_LOST;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
}
- if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net) ||
- mc_net_safe_read(mysql) == packet_error)
+ if (mc_net_safe_read(mysql) == packet_error)
goto error;
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
net->compress=1;
@@ -811,12 +901,40 @@ error:
DBUG_RETURN(0);
}
+
+#ifdef HAVE_OPENSSL
+/*
+**************************************************************************
+** Free strings in the SSL structure and clear 'use_ssl' flag.
+** NB! Errors are not reported until you do mysql_real_connect.
+**************************************************************************
+*/
+int
+mysql_ssl_clear(MYSQL *mysql)
+{
+ my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
+ mysql->options.ssl_key = 0;
+ mysql->options.ssl_cert = 0;
+ mysql->options.ssl_ca = 0;
+ mysql->options.ssl_capath = 0;
+ mysql->options.ssl_cipher= 0;
+ mysql->options.use_ssl = FALSE;
+ my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->connector_fd = 0;
+ return 0;
+}
+#endif /* HAVE_OPENSSL */
+
/*************************************************************************
** Send a QUIT to the server and close the connection
** If handle is alloced by mysql connect free it.
*************************************************************************/
-void STDCALL
+void
mc_mysql_close(MYSQL *mysql)
{
DBUG_ENTER("mysql_close");
@@ -837,13 +955,503 @@ mc_mysql_close(MYSQL *mysql)
/* Clear pointers for better safety */
mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
bzero((char*) &mysql->options,sizeof(mysql->options));
- mysql->net.vio = 0;
#ifdef HAVE_OPENSSL
- ((VioConnectorFd*)(mysql->connector_fd))->delete();
- mysql->connector_fd = 0;
+ mysql_ssl_clear(mysql);
#endif /* HAVE_OPENSSL */
if (mysql->free_me)
my_free((gptr) mysql,MYF(0));
}
DBUG_VOID_RETURN;
}
+
+void mc_mysql_free_result(MYSQL_RES *result)
+{
+ DBUG_ENTER("mc_mysql_free_result");
+ DBUG_PRINT("enter",("mysql_res: %lx",result));
+ if (result)
+ {
+ if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT)
+ {
+ DBUG_PRINT("warning",("Not all rows in set were read; Ignoring rows"));
+ for (;;)
+ {
+ ulong pkt_len;
+ if ((pkt_len=mc_net_safe_read(result->handle)) == packet_error)
+ break;
+ if (pkt_len == 1 && result->handle->net.read_pos[0] == 254)
+ break; /* End of data */
+ }
+ result->handle->status=MYSQL_STATUS_READY;
+ }
+ mc_free_rows(result->data);
+ if (result->fields)
+ free_root(&result->field_alloc,MYF(0));
+ if (result->row)
+ my_free((gptr) result->row,MYF(0));
+ my_free((gptr) result,MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
+
+static void mc_free_rows(MYSQL_DATA *cur)
+{
+ if (cur)
+ {
+ free_root(&cur->alloc,MYF(0));
+ my_free((gptr) cur,MYF(0));
+ }
+}
+
+static MYSQL_FIELD *
+mc_unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
+ my_bool default_value, my_bool long_flag_protocol)
+{
+ MYSQL_ROWS *row;
+ MYSQL_FIELD *field,*result;
+ DBUG_ENTER("unpack_fields");
+
+ field=result=(MYSQL_FIELD*) alloc_root(alloc,sizeof(MYSQL_FIELD)*fields);
+ if (!result)
+ DBUG_RETURN(0);
+
+ for (row=data->data; row ; row = row->next,field++)
+ {
+ field->table= strdup_root(alloc,(char*) row->data[0]);
+ field->name= strdup_root(alloc,(char*) row->data[1]);
+ field->length= (uint) uint3korr(row->data[2]);
+ field->type= (enum enum_field_types) (uchar) row->data[3][0];
+ if (long_flag_protocol)
+ {
+ field->flags= uint2korr(row->data[4]);
+ field->decimals=(uint) (uchar) row->data[4][2];
+ }
+ else
+ {
+ field->flags= (uint) (uchar) row->data[4][0];
+ field->decimals=(uint) (uchar) row->data[4][1];
+ }
+ if (INTERNAL_NUM_FIELD(field))
+ field->flags|= NUM_FLAG;
+ if (default_value && row->data[5])
+ field->def=strdup_root(alloc,(char*) row->data[5]);
+ else
+ field->def=0;
+ field->max_length= 0;
+ }
+ mc_free_rows(data); /* Free old data */
+ DBUG_RETURN(result);
+}
+
+int mc_mysql_send_query(MYSQL* mysql, const char* query, uint length)
+{
+ return mc_simple_command(mysql, COM_QUERY, query, length, 1);
+}
+
+
+int mc_mysql_read_query_result(MYSQL *mysql)
+{
+ uchar *pos;
+ ulong field_count;
+ MYSQL_DATA *fields;
+ ulong length;
+ DBUG_ENTER("mc_mysql_read_query_result");
+
+ if ((length = mc_net_safe_read(mysql)) == packet_error)
+ DBUG_RETURN(-1);
+ mc_free_old_query(mysql); /* Free old result */
+get_info:
+ pos=(uchar*) mysql->net.read_pos;
+ if ((field_count= mc_net_field_length(&pos)) == 0)
+ {
+ mysql->affected_rows= mc_net_field_length_ll(&pos);
+ mysql->insert_id= mc_net_field_length_ll(&pos);
+ if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
+ {
+ mysql->server_status=uint2korr(pos); pos+=2;
+ }
+ if (pos < mysql->net.read_pos+length && mc_net_field_length(&pos))
+ mysql->info=(char*) pos;
+ DBUG_RETURN(0);
+ }
+ if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
+ {
+ int error=mc_send_file_to_server(mysql,(char*) pos);
+ if ((length=mc_net_safe_read(mysql)) == packet_error || error)
+ DBUG_RETURN(-1);
+ goto get_info; /* Get info packet */
+ }
+ if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
+ mysql->server_status|= SERVER_STATUS_IN_TRANS;
+
+ mysql->extra_info= mc_net_field_length_ll(&pos); /* Maybe number of rec */
+ if (!(fields=mc_read_rows(mysql,(MYSQL_FIELD*) 0,5)))
+ DBUG_RETURN(-1);
+ if (!(mysql->fields=mc_unpack_fields(fields,&mysql->field_alloc,
+ (uint) field_count,0,
+ (my_bool) test(mysql->server_capabilities &
+ CLIENT_LONG_FLAG))))
+ DBUG_RETURN(-1);
+ mysql->status=MYSQL_STATUS_GET_RESULT;
+ mysql->field_count=field_count;
+ DBUG_RETURN(0);
+}
+
+int mc_mysql_query(MYSQL *mysql, const char *query, uint length)
+{
+ DBUG_ENTER("mysql_real_query");
+ DBUG_PRINT("enter",("handle: %lx",mysql));
+ DBUG_PRINT("query",("Query = \"%s\"",query));
+ if (!length)
+ length = strlen(query);
+ if (mc_simple_command(mysql,COM_QUERY,query,length,1))
+ DBUG_RETURN(-1);
+ DBUG_RETURN(mc_mysql_read_query_result(mysql));
+}
+
+static int mc_send_file_to_server(MYSQL *mysql, const char *filename)
+{
+ int fd, readcount, result= -1;
+ uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE);
+ char *buf, tmp_name[FN_REFLEN];
+ DBUG_ENTER("send_file_to_server");
+
+ if (!(buf=my_malloc(packet_length,MYF(0))))
+ {
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno=CR_OUT_OF_MEMORY));
+ DBUG_RETURN(-1);
+ }
+
+ fn_format(tmp_name,filename,"","",4); /* Convert to client format */
+ if ((fd = my_open(tmp_name,O_RDONLY, MYF(0))) < 0)
+ {
+ my_net_write(&mysql->net,"",0); // Server needs one packet
+ net_flush(&mysql->net);
+ mysql->net.last_errno=EE_FILENOTFOUND;
+ my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1,
+ EE(mysql->net.last_errno),tmp_name, errno);
+ goto err;
+ }
+
+ while ((readcount = (int) my_read(fd,(byte*) buf,packet_length,MYF(0))) > 0)
+ {
+ if (my_net_write(&mysql->net,buf,readcount))
+ {
+ DBUG_PRINT("error",("Lost connection to MySQL server during LOAD DATA of local file"));
+ mysql->net.last_errno=CR_SERVER_LOST;
+ strmov(mysql->net.last_error,ER(mysql->net.last_errno));
+ goto err;
+ }
+ }
+ /* Send empty packet to mark end of file */
+ if (my_net_write(&mysql->net,"",0) || net_flush(&mysql->net))
+ {
+ mysql->net.last_errno=CR_SERVER_LOST;
+ sprintf(mysql->net.last_error,ER(mysql->net.last_errno),errno);
+ goto err;
+ }
+ if (readcount < 0)
+ {
+ mysql->net.last_errno=EE_READ; /* the errmsg for not entire file read */
+ my_snprintf(mysql->net.last_error,sizeof(mysql->net.last_error)-1,
+ tmp_name,errno);
+ goto err;
+ }
+ result=0; // Ok
+
+err:
+ if (fd >= 0)
+ (void) my_close(fd,MYF(0));
+ my_free(buf,MYF(0));
+ DBUG_RETURN(result);
+}
+
+
+/* Get the length of next field. Change parameter to point at fieldstart */
+static ulong mc_net_field_length(uchar **packet)
+{
+ reg1 uchar *pos= *packet;
+ if (*pos < 251)
+ {
+ (*packet)++;
+ return (ulong) *pos;
+ }
+ if (*pos == 251)
+ {
+ (*packet)++;
+ return NULL_LENGTH;
+ }
+ if (*pos == 252)
+ {
+ (*packet)+=3;
+ return (ulong) uint2korr(pos+1);
+ }
+ if (*pos == 253)
+ {
+ (*packet)+=4;
+ return (ulong) uint3korr(pos+1);
+ }
+ (*packet)+=9; /* Must be 254 when here */
+ return (ulong) uint4korr(pos+1);
+}
+
+/* Same as above, but returns ulonglong values */
+
+static my_ulonglong mc_net_field_length_ll(uchar **packet)
+{
+ reg1 uchar *pos= *packet;
+ if (*pos < 251)
+ {
+ (*packet)++;
+ return (my_ulonglong) *pos;
+ }
+ if (*pos == 251)
+ {
+ (*packet)++;
+ return (my_ulonglong) NULL_LENGTH;
+ }
+ if (*pos == 252)
+ {
+ (*packet)+=3;
+ return (my_ulonglong) uint2korr(pos+1);
+ }
+ if (*pos == 253)
+ {
+ (*packet)+=4;
+ return (my_ulonglong) uint3korr(pos+1);
+ }
+ (*packet)+=9; /* Must be 254 when here */
+#ifdef NO_CLIENT_LONGLONG
+ return (my_ulonglong) uint4korr(pos+1);
+#else
+ return (my_ulonglong) uint8korr(pos+1);
+#endif
+}
+
+/* Read all rows (fields or data) from server */
+
+static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
+ uint fields)
+{
+ uint field;
+ ulong pkt_len;
+ ulong len;
+ uchar *cp;
+ char *to;
+ MYSQL_DATA *result;
+ MYSQL_ROWS **prev_ptr,*cur;
+ NET *net = &mysql->net;
+ DBUG_ENTER("mc_read_rows");
+
+ if ((pkt_len=mc_net_safe_read(mysql)) == packet_error)
+ DBUG_RETURN(0);
+ if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
+ MYF(MY_ZEROFILL))))
+ {
+ net->last_errno=CR_OUT_OF_MEMORY;
+ strmov(net->last_error,ER(net->last_errno));
+ DBUG_RETURN(0);
+ }
+ init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
+ result->alloc.min_malloc=sizeof(MYSQL_ROWS);
+ prev_ptr= &result->data;
+ result->rows=0;
+ result->fields=fields;
+
+ while (*(cp=net->read_pos) != 254 || pkt_len != 1)
+ {
+ result->rows++;
+ if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
+ sizeof(MYSQL_ROWS))) ||
+ !(cur->data= ((MYSQL_ROW)
+ alloc_root(&result->alloc,
+ (fields+1)*sizeof(char *)+pkt_len))))
+ {
+ mc_free_rows(result);
+ net->last_errno=CR_OUT_OF_MEMORY;
+ strmov(net->last_error,ER(net->last_errno));
+ DBUG_RETURN(0);
+ }
+ *prev_ptr=cur;
+ prev_ptr= &cur->next;
+ to= (char*) (cur->data+fields+1);
+ for (field=0 ; field < fields ; field++)
+ {
+ if ((len=(ulong) mc_net_field_length(&cp)) == NULL_LENGTH)
+ { /* null field */
+ cur->data[field] = 0;
+ }
+ else
+ {
+ cur->data[field] = to;
+ memcpy(to,(char*) cp,len); to[len]=0;
+ to+=len+1;
+ cp+=len;
+ if (mysql_fields)
+ {
+ if (mysql_fields[field].max_length < len)
+ mysql_fields[field].max_length=len;
+ }
+ }
+ }
+ cur->data[field]=to; /* End of last field */
+ if ((pkt_len=mc_net_safe_read(mysql)) == packet_error)
+ {
+ mc_free_rows(result);
+ DBUG_RETURN(0);
+ }
+ }
+ *prev_ptr=0; /* last pointer is null */
+ DBUG_PRINT("exit",("Got %d rows",result->rows));
+ DBUG_RETURN(result);
+}
+
+
+/*
+** Read one row. Uses packet buffer as storage for fields.
+** When next packet is read, the previous field values are destroyed
+*/
+
+
+static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
+ ulong *lengths)
+{
+ uint field;
+ ulong pkt_len,len;
+ uchar *pos,*prev_pos;
+
+ if ((pkt_len=mc_net_safe_read(mysql)) == packet_error)
+ return -1;
+ if (pkt_len == 1 && mysql->net.read_pos[0] == 254)
+ return 1; /* End of data */
+ prev_pos= 0; /* allowed to write at packet[-1] */
+ pos=mysql->net.read_pos;
+ for (field=0 ; field < fields ; field++)
+ {
+ if ((len=(ulong) mc_net_field_length(&pos)) == NULL_LENGTH)
+ { /* null field */
+ row[field] = 0;
+ *lengths++=0;
+ }
+ else
+ {
+ row[field] = (char*) pos;
+ pos+=len;
+ *lengths++=len;
+ }
+ if (prev_pos)
+ *prev_pos=0; /* Terminate prev field */
+ prev_pos=pos;
+ }
+ row[field]=(char*) prev_pos+1; /* End of last field */
+ *prev_pos=0; /* Terminate last field */
+ return 0;
+}
+
+my_ulonglong mc_mysql_num_rows(MYSQL_RES *res)
+{
+ return res->row_count;
+}
+
+unsigned int mc_mysql_num_fields(MYSQL_RES *res)
+{
+ return res->field_count;
+}
+
+void mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
+{
+ MYSQL_ROWS *tmp=0;
+ DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row));
+ if (result->data)
+ for (tmp=result->data->data; row-- && tmp ; tmp = tmp->next) ;
+ result->current_row=0;
+ result->data_cursor = tmp;
+}
+
+MYSQL_ROW STDCALL mc_mysql_fetch_row(MYSQL_RES *res)
+{
+ DBUG_ENTER("mc_mysql_fetch_row");
+ if (!res->data)
+ { /* Unbufferred fetch */
+ if (!res->eof)
+ {
+ if (!(mc_read_one_row(res->handle,res->field_count,res->row,
+ res->lengths)))
+ {
+ res->row_count++;
+ DBUG_RETURN(res->current_row=res->row);
+ }
+ else
+ {
+ DBUG_PRINT("info",("end of data"));
+ res->eof=1;
+ res->handle->status=MYSQL_STATUS_READY;
+ }
+ }
+ DBUG_RETURN((MYSQL_ROW) NULL);
+ }
+ {
+ MYSQL_ROW tmp;
+ if (!res->data_cursor)
+ {
+ DBUG_PRINT("info",("end of data"));
+ DBUG_RETURN(res->current_row=(MYSQL_ROW) NULL);
+ }
+ tmp = res->data_cursor->data;
+ res->data_cursor = res->data_cursor->next;
+ DBUG_RETURN(res->current_row=tmp);
+ }
+}
+
+int mc_mysql_select_db(MYSQL *mysql, const char *db)
+{
+ int error;
+ DBUG_ENTER("mysql_select_db");
+ DBUG_PRINT("enter",("db: '%s'",db));
+
+ if ((error=mc_simple_command(mysql,COM_INIT_DB,db,(uint) strlen(db),0)))
+ DBUG_RETURN(error);
+ my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+ mysql->db=my_strdup(db,MYF(MY_WME));
+ DBUG_RETURN(0);
+}
+
+
+MYSQL_RES *mc_mysql_store_result(MYSQL *mysql)
+{
+ MYSQL_RES *result;
+ DBUG_ENTER("mysql_store_result");
+
+ if (!mysql->fields)
+ DBUG_RETURN(0);
+ if (mysql->status != MYSQL_STATUS_GET_RESULT)
+ {
+ strmov(mysql->net.last_error,
+ ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
+ DBUG_RETURN(0);
+ }
+ mysql->status=MYSQL_STATUS_READY; /* server is ready */
+ if (!(result=(MYSQL_RES*) my_malloc(sizeof(MYSQL_RES)+
+ sizeof(ulong)*mysql->field_count,
+ MYF(MY_ZEROFILL))))
+ {
+ mysql->net.last_errno=CR_OUT_OF_MEMORY;
+ strmov(mysql->net.last_error, ER(mysql->net.last_errno));
+ DBUG_RETURN(0);
+ }
+ result->eof=1; /* Marker for buffered */
+ result->lengths=(ulong*) (result+1);
+ if (!(result->data=mc_read_rows(mysql,mysql->fields,mysql->field_count)))
+ {
+ my_free((gptr) result,MYF(0));
+ DBUG_RETURN(0);
+ }
+ mysql->affected_rows= result->row_count= result->data->rows;
+ result->data_cursor= result->data->data;
+ result->fields= mysql->fields;
+ result->field_alloc= mysql->field_alloc;
+ result->field_count= mysql->field_count;
+ result->current_field=0;
+ result->current_row=0; /* Must do a fetch first */
+ mysql->fields=0; /* fields is now in result */
+ DBUG_RETURN(result); /* Data fetched */
+}
diff --git a/sql/mini_client.h b/sql/mini_client.h
index f7d95a1b66e..24c13646170 100644
--- a/sql/mini_client.h
+++ b/sql/mini_client.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -18,30 +18,29 @@
#define _MINI_CLIENT_H
-MYSQL* STDCALL
-mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
- const char *passwd, const char *db,
- uint port, const char *unix_socket,uint client_flag);
-
-int STDCALL
-mc_simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
- uint length, my_bool skipp_check);
-void STDCALL
-mc_mysql_close(MYSQL *mysql);
-
-MYSQL * STDCALL
-mc_mysql_init(MYSQL *mysql);
-
-void STDCALL
-mc_mysql_debug(const char *debug);
-
-uint STDCALL
-mc_net_safe_read(MYSQL *mysql);
-
-char * STDCALL mc_mysql_error(MYSQL *mysql);
-int STDCALL mc_mysql_errno(MYSQL *mysql);
-my_bool STDCALL mc_mysql_reconnect(MYSQL* mysql);
-
+MYSQL* mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
+ const char *passwd, const char *db,
+ uint port, const char *unix_socket,uint client_flag,
+ uint net_read_timeout);
+int mc_simple_command(MYSQL *mysql,enum enum_server_command command,
+ const char *arg, uint length, my_bool skipp_check);
+void mc_mysql_close(MYSQL *mysql);
+MYSQL *mc_mysql_init(MYSQL *mysql);
+void mc_mysql_debug(const char *debug);
+ulong mc_net_safe_read(MYSQL *mysql);
+char *mc_mysql_error(MYSQL *mysql);
+int mc_mysql_errno(MYSQL *mysql);
+my_bool mc_mysql_reconnect(MYSQL* mysql);
+int mc_mysql_send_query(MYSQL* mysql, const char* query, uint length);
+int mc_mysql_read_query_result(MYSQL *mysql);
+int mc_mysql_query(MYSQL *mysql, const char *query, uint length);
+MYSQL_RES * mc_mysql_store_result(MYSQL *mysql);
+void mc_mysql_free_result(MYSQL_RES *result);
+void mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row);
+my_ulonglong mc_mysql_num_rows(MYSQL_RES *res);
+unsigned int mc_mysql_num_fields(MYSQL_RES *res);
+MYSQL_ROW STDCALL mc_mysql_fetch_row(MYSQL_RES *res);
+int mc_mysql_select_db(MYSQL *mysql, const char *db);
+void mc_end_server(MYSQL *mysql);
#endif
-
diff --git a/sql/my_lock.c b/sql/my_lock.c
index 647c07a03c3..7f47256703a 100644
--- a/sql/my_lock.c
+++ b/sql/my_lock.c
@@ -1,25 +1,25 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __EMX__
+#if defined(__EMX__) || defined(__NETWARE__)
#include "../mysys/my_lock.c"
#else
#undef MAP_TO_USE_RAID /* Avoid RAID mappings */
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <mysys_err.h>
#include <my_pthread.h>
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 833a816233e..b3c3c5648bf 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -14,29 +14,32 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifndef _MYSQL_PRIV_H
-#define _MYSQL_PRIV_H
-
-#include <global.h>
+#include <my_global.h>
+#include <mysql_version.h>
+#include <mysql_embed.h>
#include <my_sys.h>
#include <m_string.h>
-#include "mysql_version.h"
#include <hash.h>
#include <signal.h>
#include <thr_lock.h>
#include <my_base.h> /* Needed by field.h */
#include <my_bitmap.h>
-#include <violite.h>
#ifdef __EMX__
-#undef write // remove pthread.h macro definition for EMX
+#undef write /* remove pthread.h macro definition for EMX */
#endif
+#ifdef BIG_JOINS
+typedef ulonglong table_map; /* Used for table bits in join */
+#else
typedef ulong table_map; /* Used for table bits in join */
+#endif /* BIG_JOINS */
+
typedef ulong key_map; /* Used for finding keys */
typedef ulong key_part_map; /* Used for finding key parts */
#include "mysql_com.h"
+#include <violite.h>
#include "unireg.h"
void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size);
@@ -47,43 +50,48 @@ char *sql_strmake(const char *str,uint len);
gptr sql_memdup(const void * ptr,unsigned size);
void sql_element_free(void *ptr);
void kill_one_thread(THD *thd, ulong id);
+bool net_request_file(NET* net, const char* fname);
+char* query_table_status(THD *thd,const char *db,const char *table_name);
#define x_free(A) { my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); }
#define safeFree(x) { if(x) { my_free((gptr) x,MYF(0)); x = NULL; } }
#define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1))
#define all_bits_set(A,B) ((A) & (B) != (B))
-#ifndef LL
-#ifdef HAVE_LONG_LONG
-#define LL(A) A ## LL
-#else
-#define LL(A) A ## L
-#endif
-#endif
-
/***************************************************************************
Configuration parameters
****************************************************************************/
#define ACL_CACHE_SIZE 256
#define HASH_PASSWORD_LENGTH 16
+#define MAX_PASSWORD_LENGTH 32
#define HOST_CACHE_SIZE 128
#define MAX_ACCEPT_RETRY 10 // Test accept this many times
-#define MAX_BLOB_WIDTH 8192 // Default width for blob
#define MAX_FIELDS_BEFORE_HASH 32
#define USER_VARS_HASH_SIZE 16
#define STACK_MIN_SIZE 8192 // Abort if less stack during eval.
-#define STACK_BUFF_ALLOC 32 // For stack overrun checks
+#define STACK_BUFF_ALLOC 64 // For stack overrun checks
#ifndef MYSQLD_NET_RETRY_COUNT
#define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int.
#endif
#define TEMP_POOL_SIZE 128
+
+#define QUERY_ALLOC_BLOCK_SIZE 8192
+#define QUERY_ALLOC_PREALLOC_SIZE 8192
+#define TRANS_ALLOC_BLOCK_SIZE 4096
+#define TRANS_ALLOC_PREALLOC_SIZE 4096
+#define RANGE_ALLOC_BLOCK_SIZE 2048
+#define ACL_ALLOC_BLOCK_SIZE 1024
+#define UDF_ALLOC_BLOCK_SIZE 1024
+#define TABLE_ALLOC_BLOCK_SIZE 1024
+
/*
The following parameters is to decide when to use an extra cache to
- optimise seeks when reading a big table in sorted order
+ optimise seeks when reading a big table in sorted order
*/
#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (16L*1024*1024)
#define MIN_ROWS_TO_USE_TABLE_CACHE 100
+#define MIN_ROWS_TO_USE_BULK_INSERT 100
/*
The following is used to decide if MySQL should use table scanning
@@ -108,6 +116,9 @@ void kill_one_thread(THD *thd, ulong id);
/* Time handling defaults */
#define TIMESTAMP_MAX_YEAR 2038
#define YY_PART_YEAR 70
+#define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1)
+#define TIMESTAMP_MAX_VALUE 2145916799
+#define TIMESTAMP_MIN_VALUE 1
#define PRECISION_FOR_DOUBLE 53
#define PRECISION_FOR_FLOAT 24
@@ -148,6 +159,7 @@ void kill_one_thread(THD *thd, ulong id);
#define TEST_NO_EXTRA 128
#define TEST_CORE_ON_SIGNAL 256 /* Give core if signal */
#define TEST_NO_STACKTRACE 512
+#define TEST_SIGINT 1024 /* Allow sigint on threads */
/* options for select set by the yacc parser (stored in lex->options) */
#define SELECT_DISTINCT 1
@@ -155,52 +167,70 @@ void kill_one_thread(THD *thd, ulong id);
#define SELECT_DESCRIBE 4
#define SELECT_SMALL_RESULT 8
#define SELECT_BIG_RESULT 16
-#define SELECT_HIGH_PRIORITY 64 /* Intern */
-#define SELECT_USE_CACHE 256 /* Intern */
-#define SELECT_COUNT_DISTINCT 512 /* Intern */
+#define OPTION_FOUND_ROWS 32
+#define OPTION_TO_QUERY_CACHE 64
+#define SELECT_NO_JOIN_CACHE 256 /* Intern */
#define OPTION_BIG_TABLES 512 /* for SQL OPTION */
#define OPTION_BIG_SELECTS 1024 /* for SQL OPTION */
#define OPTION_LOG_OFF 2048
#define OPTION_UPDATE_LOG 4096 /* update log flag */
-#define OPTION_LOW_PRIORITY_UPDATES 8192
+#define TMP_TABLE_ALL_COLUMNS 8192
#define OPTION_WARNINGS 16384
#define OPTION_AUTO_IS_NULL 32768
#define OPTION_FOUND_COMMENT 65536L
#define OPTION_SAFE_UPDATES OPTION_FOUND_COMMENT*2
#define OPTION_BUFFER_RESULT OPTION_SAFE_UPDATES*2
#define OPTION_BIN_LOG OPTION_BUFFER_RESULT*2
-#define OPTION_NOT_AUTO_COMMIT OPTION_BIN_LOG*2
-#define OPTION_BEGIN OPTION_NOT_AUTO_COMMIT*2
+#define OPTION_NOT_AUTOCOMMIT OPTION_BIN_LOG*2
+#define OPTION_BEGIN OPTION_NOT_AUTOCOMMIT*2
#define OPTION_TABLE_LOCK OPTION_BEGIN*2
#define OPTION_QUICK OPTION_TABLE_LOCK*2
#define OPTION_QUOTE_SHOW_CREATE OPTION_QUICK*2
#define OPTION_INTERNAL_SUBTRANSACTIONS OPTION_QUOTE_SHOW_CREATE*2
/* Set if we are updating a non-transaction safe table */
-#define OPTION_STATUS_NO_TRANS_UPDATE OPTION_INTERNAL_SUBTRANSACTIONS*2
+#define OPTION_STATUS_NO_TRANS_UPDATE OPTION_INTERNAL_SUBTRANSACTIONS*2
/* The following is set when parsing the query */
#define QUERY_NO_INDEX_USED OPTION_STATUS_NO_TRANS_UPDATE*2
#define QUERY_NO_GOOD_INDEX_USED QUERY_NO_INDEX_USED*2
/* The following can be set when importing tables in a 'wrong order'
to suppress foreign key checks */
-#define OPTION_NO_FOREIGN_KEY_CHECKS QUERY_NO_GOOD_INDEX_USED*2
+#define OPTION_NO_FOREIGN_KEY_CHECKS QUERY_NO_GOOD_INDEX_USED*2
/* The following speeds up inserts to InnoDB tables by suppressing unique
key checks in some cases */
-#define OPTION_RELAXED_UNIQUE_CHECKS OPTION_NO_FOREIGN_KEY_CHECKS*2
-/* NOTE: we have now used 31 bits of the OPTION flag! */
+#define OPTION_RELAXED_UNIQUE_CHECKS OPTION_NO_FOREIGN_KEY_CHECKS*2
+#define SELECT_NO_UNLOCK ((ulong) OPTION_RELAXED_UNIQUE_CHECKS*2)
+/* NOTE: we have now used up all 32 bits of the OPTION flag! */
/* Bits for different SQL modes modes (including ANSI mode) */
-#define MODE_REAL_AS_FLOAT 1
-#define MODE_PIPES_AS_CONCAT 2
-#define MODE_ANSI_QUOTES 4
-#define MODE_IGNORE_SPACE 8
-#define MODE_SERIALIZABLE 16
-#define MODE_ONLY_FULL_GROUP_BY 32
+#define MODE_REAL_AS_FLOAT 1
+#define MODE_PIPES_AS_CONCAT 2
+#define MODE_ANSI_QUOTES 4
+#define MODE_IGNORE_SPACE 8
+#define MODE_SERIALIZABLE 16
+#define MODE_ONLY_FULL_GROUP_BY 32
+#define MODE_NO_UNSIGNED_SUBTRACTION 64
+#define MODE_NO_DIR_IN_CREATE 128
#define RAID_BLOCK_SIZE 1024
+#ifdef EXTRA_DEBUG
+/*
+ Sync points allow us to force the server to reach a certain line of code
+ and block there until the client tells the server it is ok to go on.
+ The client tells the server to block with SELECT GET_LOCK()
+ and unblocks it with SELECT RELEASE_LOCK(). Used for debugging difficult
+ concurrency problems
+*/
+#define DBUG_SYNC_POINT(lock_name,lock_timeout) \
+ debug_sync_point(lock_name,lock_timeout)
+void debug_sync_point(const char* lock_name, uint lock_timeout);
+#else
+#define DBUG_SYNC_POINT(lock_name,lock_timeout)
+#endif /* EXTRA_DEBUG */
+
/* BINLOG_DUMP options */
#define BINLOG_DUMP_NON_BLOCK 1
@@ -209,6 +239,10 @@ void kill_one_thread(THD *thd, ulong id);
#define SHOW_LOG_STATUS_FREE "FREE"
#define SHOW_LOG_STATUS_INUSE "IN USE"
+/* Options to add_table_to_list() */
+#define TL_OPTION_UPDATING 1
+#define TL_OPTION_FORCE_INDEX 2
+
/* Some portable defines */
#define portable_sizeof_char_ptr 8
@@ -216,6 +250,11 @@ void kill_one_thread(THD *thd, ulong id);
#define tmp_file_prefix "#sql" /* Prefix for tmp tables */
#define tmp_file_prefix_length 4
+/* Flags for calc_week() function. */
+#define WEEK_MONDAY_FIRST 1
+#define WEEK_YEAR 2
+#define WEEK_FIRST_WEEKDAY 4
+
struct st_table;
class THD;
@@ -225,6 +264,31 @@ typedef struct st_sql_list {
uint elements;
byte *first;
byte **next;
+
+ inline void empty()
+ {
+ elements=0;
+ first=0;
+ next= &first;
+ }
+ inline void link_in_list(byte *element,byte **next_ptr)
+ {
+ elements++;
+ (*next)=element;
+ next= next_ptr;
+ *next=0;
+ }
+ inline void save_and_clear(struct st_sql_list *save)
+ {
+ *save= *this;
+ empty();
+ }
+ inline void push_front(struct st_sql_list *save)
+ {
+ *save->next= first; /* link current list last */
+ first= save->first;
+ elements+= save->elements;
+ }
} SQL_LIST;
@@ -248,41 +312,79 @@ inline THD *_current_thd(void)
#include "sql_class.h"
#include "opt_range.h"
-
-void mysql_create_db(THD *thd, char *db, uint create_info);
-void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags);
+#ifdef HAVE_QUERY_CACHE
+#include "sql_cache.h"
+#define query_cache_store_query(A, B) query_cache.store_query(A, B)
+#define query_cache_destroy() query_cache.destroy()
+#define query_cache_result_size_limit(A) query_cache.result_size_limit(A)
+#define query_cache_resize(A) query_cache.resize(A)
+#define query_cache_invalidate3(A, B, C) query_cache.invalidate(A, B, C)
+#define query_cache_invalidate1(A) query_cache.invalidate(A)
+#define query_cache_send_result_to_client(A, B, C) \
+ query_cache.send_result_to_client(A, B, C)
+#define query_cache_invalidate_by_MyISAM_filename_ref \
+ &query_cache_invalidate_by_MyISAM_filename
+#else
+#define query_cache_store_query(A, B)
+#define query_cache_destroy()
+#define query_cache_result_size_limit(A)
+#define query_cache_resize(A)
+#define query_cache_invalidate3(A, B, C)
+#define query_cache_invalidate1(A)
+#define query_cache_send_result_to_client(A, B, C) 0
+#define query_cache_invalidate_by_MyISAM_filename_ref NULL
+
+#define query_cache_abort(A)
+#define query_cache_end_of_result(A)
+#define query_cache_invalidate_by_MyISAM_filename_ref NULL
+#endif /*HAVE_QUERY_CACHE*/
+
+int mysql_create_db(THD *thd, char *db, uint create_info, bool silent);
+int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
+void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags);
int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists);
+int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
+ bool log_query);
+int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables,
+ bool if_exists,
+ bool log_query);
int quick_rm_table(enum db_type base,const char *db,
const char *table_name);
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
bool mysql_change_db(THD *thd,const char *name);
void mysql_parse(THD *thd,char *inBuf,uint length);
void mysql_init_select(LEX *lex);
+bool mysql_new_select(LEX *lex);
+void mysql_init_multi_delete(LEX *lex);
void init_max_user_conn(void);
+void init_update_queries(void);
void free_max_user_conn(void);
-pthread_handler_decl(handle_one_connection,arg);
-pthread_handler_decl(handle_bootstrap,arg);
-sig_handler end_thread_signal(int sig);
+extern "C" pthread_handler_decl(handle_one_connection,arg);
+extern "C" pthread_handler_decl(handle_bootstrap,arg);
void end_thread(THD *thd,bool put_in_cache);
void flush_thread_cache();
void mysql_execute_command(void);
bool do_command(THD *thd);
+bool dispatch_command(enum enum_server_command command, THD *thd,
+ char* packet, uint packet_length);
+bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
+#ifndef EMBEDDED_LIBRARY
bool check_stack_overrun(THD *thd,char *dummy);
-bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables);
-void mysql_rm_db(THD *thd,char *db,bool if_exists);
+#else
+#define check_stack_overrun(A, B) 0
+#endif
+
+bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables);
void table_cache_init(void);
void table_cache_free(void);
uint cached_tables(void);
void kill_mysql(void);
void close_connection(NET *net,uint errcode=0,bool lock=1);
-bool check_access(THD *thd,uint access,const char *db=0,uint *save_priv=0,
- bool no_grant=0);
-bool check_table_access(THD *thd,uint want_access,TABLE_LIST *tables);
-bool check_process_priv(THD *thd=0);
-
-int generate_table(THD *thd, TABLE_LIST *table_list,
- TABLE *locked_table);
-
+bool check_access(THD *thd, ulong access, const char *db=0, ulong *save_priv=0,
+ bool no_grant=0, bool no_errors=0);
+bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables,
+ bool no_errors=0);
+bool check_global_access(THD *thd, ulong want_access);
int mysql_backup_table(THD* thd, TABLE_LIST* table_list);
int mysql_restore_table(THD* thd, TABLE_LIST* table_list);
@@ -295,9 +397,9 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* table_list,
HA_CHECK_OPT* check_opt);
int mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
HA_CHECK_OPT* check_opt);
+bool check_simple_select();
/* net_pkg.c */
-void send_error(NET *net,uint sql_errno=0, const char *err=0);
void send_warning(NET *net, uint sql_errno, const char *err=0);
void net_printf(NET *net,uint sql_errno, ...);
void send_ok(NET *net,ha_rows affected_rows=0L,ulonglong id=0L,
@@ -324,19 +426,18 @@ SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
int setup_order(THD *thd,TABLE_LIST *tables, List<Item> &fields,
List <Item> &all_fields, ORDER *order);
+int handle_select(THD *thd, LEX *lex, select_result *result);
int mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &list,COND *conds,
ORDER *order, ORDER *group,Item *having,ORDER *proc_param,
- uint select_type,select_result *result);
-Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
- Item_result_field ***copy_func, Field **from_field,
+ ulong select_type,select_result *result);
+int mysql_union(THD *thd,LEX *lex,select_result *result);
+Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
+ Item ***copy_func, Field **from_field,
bool group,bool modify_item);
int mysql_create_table(THD *thd,const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
List<create_field> &fields, List<Key> &keys,
bool tmp_table, bool no_log);
-// no_log is needed for the case of CREATE TABLE ... SELECT , as the logging
-// will be done later in sql_insert.cc
-
TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
const char *db, const char *name,
List<create_field> *extra_fields,
@@ -351,26 +452,31 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
List<Alter_column> &alter_list,
ORDER *order,
bool drop_primary,
- enum enum_duplicates handle_duplicates);
+ enum enum_duplicates handle_duplicates,
+ enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
+ bool simple_alter=0);
bool mysql_rename_table(enum db_type base,
const char *old_db,
const char * old_name,
const char *new_db,
const char * new_name);
-bool close_cached_table(THD *thd,TABLE *table);
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
List<Alter_drop> &drop_list);
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
- List<Item> &values,COND *conds, ha_rows limit,
- enum enum_duplicates handle_duplicates,
- thr_lock_type lock_type);
+ List<Item> &values,COND *conds,
+ ORDER *order, ha_rows limit,
+ enum enum_duplicates handle_duplicates);
+int mysql_multi_update(THD *thd, TABLE_LIST *table_list,
+ List<Item> *fields, List<Item> *values,
+ COND *conds, ulong options,
+ enum enum_duplicates handle_duplicates);
int mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
- List<List_item> &values, enum_duplicates flag,
- thr_lock_type lock_type);
+ List<List_item> &values, enum_duplicates flag);
void kill_delayed_threads(void);
-int mysql_delete(THD *thd,TABLE_LIST *table,COND *conds,ha_rows rows,
- thr_lock_type lock_type, ulong options);
+int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, ORDER *order,
+ ha_rows rows, ulong options);
+int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok=0);
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update);
TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias,
bool *refresh);
@@ -388,13 +494,30 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name);
Field *find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables);
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
bool check_grant,bool allow_rowid);
+#ifdef HAVE_OPENSSL
+#include <openssl/des.h>
+struct st_des_keyblock
+{
+ DES_cblock key1, key2, key3;
+};
+struct st_des_keyschedule
+{
+ DES_key_schedule ks1, ks2, ks3;
+};
+extern char *des_key_file;
+extern struct st_des_keyschedule des_keyschedule[10];
+extern uint des_default_key;
+extern pthread_mutex_t LOCK_des_key_file;
+bool load_des_key_file(const char *file_name);
+void free_des_key_file();
+#endif /* HAVE_OPENSSL */
/* sql_do.cc */
int mysql_do(THD *thd, List<Item> &values);
/* sql_list.c */
int mysqld_show_dbs(THD *thd,const char *wild);
-int mysqld_show_open_tables(THD *thd,const char *db,const char *wild);
+int mysqld_show_open_tables(THD *thd,const char *wild);
int mysqld_show_tables(THD *thd,const char *db,const char *wild);
int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild);
int mysqld_show_fields(THD *thd,TABLE_LIST *table, const char *wild,
@@ -408,7 +531,16 @@ int mysqld_show_create(THD *thd, TABLE_LIST *table_list);
void mysqld_list_processes(THD *thd,const char *user,bool verbose);
int mysqld_show_status(THD *thd);
int mysqld_show_variables(THD *thd,const char *wild);
-int mysqld_show(THD *thd, const char *wild, show_var_st *variables);
+int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
+ enum enum_var_type value_type,
+ pthread_mutex_t *mutex);
+
+/* sql_handler.cc */
+int mysql_ha_open(THD *thd, TABLE_LIST *tables);
+int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok=0);
+int mysql_ha_closeall(THD *thd, TABLE_LIST *tables);
+int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
+ List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
/* sql_base.cc */
void set_item_name(Item *item,char *pos,uint length);
@@ -419,21 +551,26 @@ bool add_field_to_list(char *field_name, enum enum_field_types type,
void store_position_for_column(const char *name);
bool add_to_list(SQL_LIST &list,Item *group,bool asc=0);
TABLE_LIST *add_table_to_list(Table_ident *table,LEX_STRING *alias,
- bool updating,
+ ulong table_option,
thr_lock_type flags=TL_UNLOCK,
List<String> *use_index=0,
List<String> *ignore_index=0);
+void set_lock_for_tables(thr_lock_type lock_type);
void add_join_on(TABLE_LIST *b,Item *expr);
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b);
-bool add_proc_to_list(Item *item);
+bool add_proc_to_list(THD *thd, Item *item);
TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find);
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
table_map read_tables, COND *conds, int *error);
Item ** find_item_in_list(Item *item,List<Item> &items);
+bool insert_fields(THD *thd,TABLE_LIST *tables,
+ const char *db_name, const char *table_name,
+ List_iterator<Item> *it);
bool setup_tables(TABLE_LIST *tables);
int setup_fields(THD *thd,TABLE_LIST *tables,List<Item> &item,
- bool set_query_id,List<Item> *sum_func_list);
+ bool set_query_id,List<Item> *sum_func_list,
+ bool allow_sum_func);
int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
int setup_ftfuncs(THD *thd);
int init_ftfuncs(THD *thd, bool no_order);
@@ -449,6 +586,7 @@ void free_io_cache(TABLE *entry);
void intern_close_table(TABLE *entry);
bool close_thread_table(THD *thd, TABLE **table_ptr);
void close_thread_tables(THD *thd,bool locked=0);
+bool close_thread_table(THD *thd, TABLE **table_ptr);
void close_temporary_tables(THD *thd);
TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name);
bool close_temporary_table(THD *thd, const char *db, const char *table_name);
@@ -461,10 +599,9 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table,
bool return_if_owned_by_thd=0);
bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables);
void copy_field_from_tmp_record(Field *field,int offset);
-int fill_record(List<Item> &fields,List<Item> &values);
-int fill_record(Field **field,List<Item> &values);
-int list_open_tables(THD *thd,List<char> *files, const char *db,const char *wild);
-char* query_table_status(THD *thd,const char *db,const char *table_name);
+int fill_record(List<Item> &fields,List<Item> &values, bool ignore_errors);
+int fill_record(Field **field,List<Item> &values, bool ignore_errors);
+OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild);
/* sql_calc.cc */
bool eval_const_cond(COND *cond);
@@ -479,18 +616,15 @@ int write_record(TABLE *table,COPY_INFO *info);
/* bits set in manager_status */
#define MANAGER_BERKELEY_LOG_CLEANUP (1L << 0)
extern ulong volatile manager_status;
-extern bool volatile manager_thread_in_use;
+extern bool volatile manager_thread_in_use, mqh_used;
extern pthread_t manager_thread;
-extern pthread_mutex_t LOCK_manager;
-extern pthread_cond_t COND_manager;
-pthread_handler_decl(handle_manager, arg);
+extern "C" pthread_handler_decl(handle_manager, arg);
/* sql_test.cc */
#ifndef DBUG_OFF
void print_where(COND *cond,const char *info);
void print_cached_tables(void);
-void TEST_filesort(TABLE **form,SORT_FIELD *sortorder,uint s_length,
- ha_rows special);
+void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special);
#endif
void mysql_print_status(THD *thd);
/* key.cc */
@@ -505,29 +639,80 @@ void init_errmessage(void);
void sql_perror(const char *message);
void sql_print_error(const char *format,...)
__attribute__ ((format (printf, 1, 2)));
+bool fn_format_relative_to_data_home(my_string to, const char *name,
+ const char *dir, const char *extension);
+bool open_log(MYSQL_LOG *log, const char *hostname,
+ const char *opt_name, const char *extension,
+ const char *index_file_name,
+ enum_log_type type, bool read_append,
+ bool no_auto_events, ulong max_size);
+/* mysqld.cc */
+void clear_error_message(THD *thd);
-extern ulong server_id;
-extern char mysql_data_home[2],server_version[SERVER_VERSION_LENGTH],
- max_sort_char, mysql_real_data_home[];
-extern my_string mysql_unix_port,mysql_tmpdir;
+/*
+ External variables
+*/
+
+extern time_t start_time;
+extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
+ max_sort_char, mysql_real_data_home[], *charsets_list;
+extern my_string mysql_tmpdir;
+extern const char *command_name[];
extern const char *first_keyword, *localhost, *delayed_user;
-extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables,
- created_tmp_tables, created_tmp_disk_tables,
- aborted_threads,aborted_connects,
- delayed_insert_timeout,
- delayed_insert_limit, delayed_queue_size,
- delayed_insert_threads, delayed_insert_writes,
- delayed_rows_in_use,delayed_insert_errors;
+extern const char **errmesg; /* Error messages */
+extern const char *myisam_recover_options_str;
+extern uchar *days_in_month;
+extern char language[LIBLEN],reg_ext[FN_EXTLEN];
+extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
+extern char pidfile_name[FN_REFLEN], time_zone[30], *opt_init_file;
+extern char log_error_file[FN_REFLEN];
+extern double log_10[32];
+extern ulonglong keybuff_size;
+extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables;
+extern ulong created_tmp_tables, created_tmp_disk_tables;
+extern ulong aborted_threads,aborted_connects;
+extern ulong delayed_insert_timeout;
+extern ulong delayed_insert_limit, delayed_queue_size;
+extern ulong delayed_insert_threads, delayed_insert_writes;
+extern ulong delayed_rows_in_use,delayed_insert_errors;
extern ulong filesort_rows, filesort_range_count, filesort_scan_count;
extern ulong filesort_merge_passes;
extern ulong select_range_check_count, select_range_count, select_scan_count;
-extern ulong select_full_range_join_count,select_full_join_count,
- slave_open_temp_tables;
-extern uint test_flags,select_errors,mysql_port,ha_open_options;
+extern ulong select_full_range_join_count,select_full_join_count;
+extern ulong slave_open_temp_tables, query_cache_size;
extern ulong thd_startup_options, slow_launch_threads, slow_launch_time;
-extern time_t start_time;
-extern const char *command_name[];
-extern I_List<THD> threads;
+extern ulong server_id, concurrency;
+extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count;
+extern ulong ha_read_key_count, ha_read_next_count, ha_read_prev_count;
+extern ulong ha_read_first_count, ha_read_last_count;
+extern ulong ha_read_rnd_count, ha_read_rnd_next_count;
+extern ulong ha_commit_count, ha_rollback_count,table_cache_size;
+extern ulong max_connections,max_connect_errors, connect_timeout;
+extern ulong max_insert_delayed_threads, max_user_connections;
+extern ulong long_query_count, what_to_log,flush_time,opt_sql_mode;
+extern ulong query_buff_size, thread_stack,thread_stack_min;
+extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
+extern ulong max_binlog_size, max_relay_log_size;
+extern ulong rpl_recovery_rank, thread_cache_size;
+extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log;
+extern ulong specialflag, current_pid;
+
+extern uint test_flags,select_errors,ha_open_options;
+extern uint protocol_version,dropping_tables;
+extern uint delay_key_write_options, lower_case_table_names;
+extern bool opt_endinfo, using_udf_functions, locked_in_memory;
+extern bool opt_using_transactions, mysql_embedded;
+extern bool using_update_log, opt_large_files;
+extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log, opt_error_log;
+extern bool opt_disable_networking, opt_skip_show_db;
+extern bool volatile abort_loop, shutdown_in_progress, grant_option;
+extern uint volatile thread_count, thread_running, global_read_lock;
+extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
+extern my_bool opt_safe_show_db, opt_local_infile;
+extern my_bool opt_slave_compressed_protocol, use_temp_pool;
+extern my_bool opt_readonly;
+extern my_bool opt_enable_named_pipe, opt_sync_frm;
+
extern MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
extern FILE *bootstrap_file;
extern pthread_key(MEM_ROOT*,THR_MALLOC);
@@ -536,51 +721,33 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
LOCK_grant, LOCK_error_log, LOCK_delayed_insert,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
- LOCK_binlog_update, LOCK_slave, LOCK_server_id;
-extern pthread_cond_t COND_refresh,COND_thread_count, COND_binlog_update,
- COND_slave_stopped, COND_slave_start;
+ LOCK_slave_list, LOCK_active_mi, LOCK_manager,
+ LOCK_global_system_variables;
+extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
extern pthread_attr_t connection_attrib;
-extern bool opt_endinfo, using_udf_functions, locked_in_memory,
- opt_using_transactions, use_temp_pool, opt_local_infile;
-extern char f_fyllchar;
-extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
- ha_read_key_count, ha_read_next_count, ha_read_prev_count,
- ha_read_first_count, ha_read_last_count,
- ha_read_rnd_count, ha_read_rnd_next_count;
+extern I_List<THD> threads;
extern MY_BITMAP temp_pool;
-extern uchar *days_in_month;
extern DATE_FORMAT dayord;
-extern double log_10[32];
-extern uint protocol_version,dropping_tables;
-extern ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
- max_join_size,join_buff_size,tmp_table_size,
- max_connections,max_connect_errors,long_query_time,
- max_insert_delayed_threads, max_user_connections,
- long_query_count,net_wait_timeout,net_interactive_timeout,
- net_read_timeout,net_write_timeout,
- what_to_log,flush_time, opt_sql_mode,
- max_tmp_tables,max_heap_table_size,query_buff_size,
- lower_case_table_names,thread_stack,thread_stack_min,
- binlog_cache_size, max_binlog_cache_size, record_rnd_cache_size;
-extern ulong com_stat[(uint) SQLCOM_END], com_other;
-extern ulong specialflag, current_pid;
-extern bool low_priority_updates, using_update_log,opt_warnings;
-extern bool opt_sql_bin_update, opt_safe_show_db, opt_safe_user_create;
-extern char language[LIBLEN],reg_ext[FN_EXTLEN],blob_newline;
-extern const char **errmesg; /* Error messages */
-extern const char *default_tx_isolation_name;
extern String empty_string;
-extern struct show_var_st init_vars[];
-extern struct show_var_st status_vars[];
-extern enum db_type default_table_type;
-extern enum enum_tx_isolation default_tx_isolation;
+extern SHOW_VAR init_vars[],status_vars[], internal_vars[];
+extern struct system_variables global_system_variables;
+extern struct system_variables max_system_variables;
+extern struct rand_struct sql_rand;
+
+/* optional things, have_* variables */
+
+extern SHOW_COMP_OPTION have_isam, have_innodb, have_berkeley_db;
+extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink;
+extern SHOW_COMP_OPTION have_query_cache, have_berkeley_db, have_innodb;
+extern SHOW_COMP_OPTION have_crypt;
#ifndef __WIN__
extern pthread_t signal_thread;
#endif
-extern bool volatile abort_loop, shutdown_in_progress, grant_option;
-extern uint volatile thread_count, thread_running, global_read_lock;
+#ifdef HAVE_OPENSSL
+extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
+#endif /* HAVE_OPENSSL */
MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **table,uint count);
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
@@ -588,9 +755,15 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
void mysql_lock_abort(THD *thd, TABLE *table);
+void mysql_lock_abort_for_thread(THD *thd, TABLE *table);
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
+bool lock_global_read_lock(THD *thd);
+void unlock_global_read_lock(THD *thd);
+bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh);
+void start_waiting_global_read_lock(THD *thd);
/* Lock based on name */
+int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
int lock_table_name(THD *thd, TABLE_LIST *table_list);
void unlock_table_name(THD *thd, TABLE_LIST *table_list);
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list);
@@ -602,7 +775,7 @@ void unlock_table_names(THD *thd, TABLE_LIST *table_list,
/* old unireg functions */
void unireg_init(ulong options);
-void unireg_end(int signal);
+void unireg_end(void);
int rea_create_table(my_string file_name,HA_CREATE_INFO *create_info,
List<create_field> &create_field,
uint key_count,KEY *key_info);
@@ -622,7 +795,7 @@ uint calc_days_in_year(uint year);
void get_date_from_daynr(long daynr,uint *year, uint *month,
uint *day);
void init_time(void);
-long my_gmt_sec(TIME *);
+long my_gmt_sec(TIME *, long *current_timezone);
time_t str_to_timestamp(const char *str,uint length);
bool str_to_time(const char *str,uint length,TIME *l_time);
longlong str_to_datetime(const char *str,uint length,bool fuzzy_date);
@@ -631,23 +804,21 @@ timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time,
int test_if_number(char *str,int *res,bool allow_wildcards);
void change_byte(byte *,uint,char,char);
-void unireg_abort(int exit_code);
+extern "C" void unireg_abort(int exit_code);
void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
SQL_SELECT *select,
int use_record_cache, bool print_errors);
void end_read_record(READ_RECORD *info);
-ha_rows filesort(TABLE **form,struct st_sort_field *sortorder, uint s_length,
+ha_rows filesort(TABLE *form,struct st_sort_field *sortorder, uint s_length,
SQL_SELECT *select, ha_rows special,ha_rows max_rows,
ha_rows *examined_rows);
void change_double_for_sort(double nr,byte *to);
int get_quick_record(SQL_SELECT *select);
int calc_weekday(long daynr,bool sunday_first_day_of_week);
-uint calc_week(TIME *ltime, bool with_year, bool sunday_first_day_of_week,
- uint *year);
+uint calc_week(TIME *l_time, uint week_behaviour, uint *year);
void find_date(char *pos,uint *vek,uint flag);
TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end);
TYPELIB *typelib(List<String> &strings);
-void clean_up(bool print_message=1);
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names);
ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames,
const char *newname);
@@ -677,30 +848,43 @@ void hostname_cache_free();
void hostname_cache_refresh(void);
bool get_interval_info(const char *str,uint length,uint count,
long *values);
-/* sql_cache */
-
+/* sql_cache.cc */
extern bool sql_cache_init();
extern void sql_cache_free();
extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
+/* item.cc */
+Item *get_system_var(enum_var_type var_type, LEX_STRING name);
+
+/* log.cc */
+bool flush_error_log(void);
+
+/* sql_list.cc */
+void free_list(I_List <i_string_pair> *list);
+void free_list(I_List <i_string> *list);
+
/* Some inline functions for more speed */
inline bool add_item_to_list(Item *item)
{
- return current_lex->item_list.push_back(item);
+ return current_lex->select->item_list.push_back(item);
}
+
inline bool add_value_to_list(Item *value)
{
return current_lex->value_list.push_back(value);
}
+
inline bool add_order_to_list(Item *item,bool asc)
{
- return add_to_list(current_lex->order_list,item,asc);
+ return add_to_list(current_lex->select->order_list,item,asc);
}
+
inline bool add_group_to_list(Item *item,bool asc)
{
- return add_to_list(current_lex->group_list,item,asc);
+ return add_to_list(current_lex->select->group_list,item,asc);
}
+
inline void mark_as_null_row(TABLE *table)
{
table->null_row=1;
@@ -708,4 +892,13 @@ inline void mark_as_null_row(TABLE *table)
bfill(table->null_flags,table->null_bytes,255);
}
-#endif
+inline void table_case_convert(char * name, uint length)
+{
+ if (lower_case_table_names)
+ casedn(name, length);
+}
+
+inline const char *table_case_name(HA_CREATE_INFO *info, const char *name)
+{
+ return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
+}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index b0b9837dff3..e198d477b68 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,45 +15,59 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h"
-#include <mysql.h>
#include <m_ctype.h>
#include <my_dir.h>
#include "sql_acl.h"
#include "slave.h"
#include "sql_repl.h"
+#include "repl_failsafe.h"
#include "stacktrace.h"
#ifdef HAVE_BERKELEY_DB
#include "ha_berkeley.h"
#endif
#ifdef HAVE_INNOBASE_DB
-#include "ha_innobase.h"
-#endif
-#ifdef HAVE_GEMINI_DB
-#include "ha_gemini.h"
+#include "ha_innodb.h"
#endif
#include "ha_myisam.h"
#include <nisam.h>
#include <thr_alarm.h>
#include <ft_global.h>
+#include <assert.h>
#ifndef DBUG_OFF
#define ONE_THREAD
#endif
-#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ)
-#define HAVE_CLOSE_SERVER_SOCK 1
-void close_server_sock();
+#define SHUTDOWN_THD
+#define MAIN_THD
+#define SIGNAL_THD
+
+#ifdef HAVE_purify
+#define IF_PURIFY(A,B) (A)
#else
-#define close_server_sock()
+#define IF_PURIFY(A,B) (B)
#endif
+/* stack traces are only supported on linux intel */
+#if defined(__linux__) && defined(__i386__) && defined(USE_PSTACK)
+#define HAVE_STACK_TRACE_ON_SEGV
+#include "../pstack/pstack.h"
+char pstack_file_name[80];
+#endif /* __linux__ */
+
+/* We have HAVE_purify below as this speeds up the shutdown of MySQL */
+
+#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__)
+#define HAVE_CLOSE_SERVER_SOCK 1
+#endif
+
extern "C" { // Because of SCO 3.2V4.2
#include <errno.h>
#include <sys/stat.h>
#ifndef __GNU_LIBRARY__
#define __GNU_LIBRARY__ // Skip warnings in getopt.h
#endif
-#include <getopt.h>
+#include <my_getopt.h>
#ifdef HAVE_SYSENT_H
#include <sysent.h>
#endif
@@ -67,7 +81,9 @@ extern "C" { // Because of SCO 3.2V4.2
#if defined(OS2)
# include <sys/un.h>
#elif !defined( __WIN__)
+# ifndef __NETWARE__
#include <sys/resource.h>
+# endif /* __NETWARE__ */
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
@@ -79,9 +95,7 @@ extern "C" { // Because of SCO 3.2V4.2
#include <sys/select.h>
#endif
#include <sys/utsname.h>
-#else
-#include <windows.h>
-#endif // __WIN__
+#endif /* __WIN__ */
#ifdef HAVE_LIBWRAP
#include <tcpd.h>
@@ -107,6 +121,15 @@ int deny_severity = LOG_WARNING;
#include <sys/mman.h>
#endif
+#ifdef __NETWARE__
+#include <nks/vm.h>
+#include <library.h>
+#include <monitor.h>
+
+event_handle_t eh;
+Report_t ref;
+#endif /* __NETWARE__ */
+
#ifdef _AIX41
int initgroups(const char *,unsigned int);
#endif
@@ -117,7 +140,7 @@ int initgroups(const char *,unsigned int);
typedef fp_except fp_except_t;
#endif
- /* We can't handle floating point expections with threads, so disable
+ /* We can't handle floating point exceptions with threads, so disable
this on freebsd
*/
@@ -172,10 +195,9 @@ static SECURITY_DESCRIPTOR sdPipeDescriptor;
static HANDLE hPipe = INVALID_HANDLE_VALUE;
static pthread_cond_t COND_handler_count;
static uint handler_count;
-static bool opt_enable_named_pipe = 0;
#endif
#ifdef __WIN__
-static bool opt_console=0,start_mode=0, use_opt_args;
+static bool start_mode=0, use_opt_args;
static int opt_argc;
static char **opt_argv;
#endif
@@ -184,12 +206,12 @@ static char **opt_argv;
#ifdef __WIN__
#undef MYSQL_SERVER_SUFFIX
#ifdef __NT__
-#if defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB)
+#if defined(HAVE_BERKELEY_DB)
#define MYSQL_SERVER_SUFFIX "-max-nt"
#else
#define MYSQL_SERVER_SUFFIX "-nt"
#endif /* ...DB */
-#elif defined(HAVE_INNOBASE_DB) || defined(HAVE_BERKELEY_DB)
+#elif defined(HAVE_BERKELEY_DB)
#define MYSQL_SERVER_SUFFIX "-max"
#else
#define MYSQL_SERVER_SUFFIX ""
@@ -201,17 +223,12 @@ SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_NO;
#endif
-#ifdef HAVE_GEMINI_DB
-SHOW_COMP_OPTION have_gemini=SHOW_OPTION_YES;
-#else
-SHOW_COMP_OPTION have_gemini=SHOW_OPTION_NO;
-#endif
#ifdef HAVE_INNOBASE_DB
SHOW_COMP_OPTION have_innodb=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_innodb=SHOW_OPTION_NO;
#endif
-#ifndef NO_ISAM
+#ifdef HAVE_ISAM
SHOW_COMP_OPTION have_isam=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_isam=SHOW_OPTION_NO;
@@ -222,96 +239,157 @@ SHOW_COMP_OPTION have_raid=SHOW_OPTION_YES;
SHOW_COMP_OPTION have_raid=SHOW_OPTION_NO;
#endif
#ifdef HAVE_OPENSSL
-SHOW_COMP_OPTION have_ssl=SHOW_OPTION_YES;
+SHOW_COMP_OPTION have_openssl=SHOW_OPTION_YES;
#else
-SHOW_COMP_OPTION have_ssl=SHOW_OPTION_NO;
+SHOW_COMP_OPTION have_openssl=SHOW_OPTION_NO;
+#endif
+#ifdef HAVE_BROKEN_REALPATH
+SHOW_COMP_OPTION have_symlink=SHOW_OPTION_NO;
+#else
+SHOW_COMP_OPTION have_symlink=SHOW_OPTION_YES;
+#endif
+#ifdef HAVE_QUERY_CACHE
+SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_YES;
+#else
+SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_NO;
+#endif
+#ifdef HAVE_CRYPT
+SHOW_COMP_OPTION have_crypt=SHOW_OPTION_YES;
+#else
+SHOW_COMP_OPTION have_crypt=SHOW_OPTION_NO;
#endif
+bool opt_large_files= sizeof(my_off_t) > 4;
+#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES)
+#define GET_HA_ROWS GET_ULL
+#else
+#define GET_HA_ROWS GET_ULONG
+#endif
+
+#ifdef HAVE_LIBWRAP
+char *libwrapName= NULL;
+#endif
+
+/*
+ Variables to store startup options
+*/
-static bool opt_skip_slave_start = 0; // if set, slave is not autostarted
+my_bool opt_skip_slave_start = 0; // If set, slave is not autostarted
+/*
+ If set, some standard measures to enforce slave data integrity will not
+ be performed
+*/
+my_bool opt_reckless_slave = 0;
+
+ulong back_log, connect_timeout, concurrency;
+char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], time_zone[30];
+char log_error_file[FN_REFLEN];
+bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
+bool opt_error_log= IF_WIN(1,0);
+bool opt_disable_networking=0, opt_skip_show_db=0;
+my_bool opt_enable_named_pipe= 0, opt_debugging= 0;
+my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol;
+uint delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
+uint lower_case_table_names;
+
+static my_bool opt_do_pstack = 0;
static ulong opt_specialflag=SPECIAL_ENGLISH;
+
+static ulong opt_myisam_block_size;
static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET;
-static ulong back_log,connect_timeout,concurrency;
static my_string opt_logname=0,opt_update_logname=0,
opt_binlog_index_name = 0,opt_slow_logname=0;
-static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN];
+
+static char* mysql_home_ptr= mysql_home;
+static char* pidfile_name_ptr= pidfile_name;
+char* log_error_file_ptr= log_error_file;
static pthread_t select_thread;
-static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
- opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0,
- opt_myisam_log=0,
- opt_large_files=sizeof(my_off_t) > 4;
-bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0,
- opt_safe_user_create=0;
+static my_bool opt_noacl=0, opt_bootstrap=0, opt_myisam_log=0;
+my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
+my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
+my_bool opt_log_slave_updates= 0, opt_console= 0;
+my_bool opt_readonly = 0, opt_sync_bdb_logs, opt_sync_frm;
+
+volatile bool mqh_used = 0;
FILE *bootstrap_file=0;
int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice
-extern MASTER_INFO glob_mi;
-extern int init_master_info(MASTER_INFO* mi);
-// if sql_bin_update is true, SQL_LOG_UPDATE and SQL_LOG_BIN are kept in sync,
-// and are treated as aliases for each other
+/*
+ If sql_bin_update is true, SQL_LOG_UPDATE and SQL_LOG_BIN are kept in sync,
+ and are treated as aliases for each other
+*/
static bool kill_in_progress=FALSE;
struct rand_struct sql_rand; // used by sql_class.cc:THD::THD()
static int cleanup_done;
-static char **defaults_argv,time_zone[30];
-static const char *default_table_type_name;
-static char glob_hostname[FN_REFLEN];
+static char **defaults_argv;
+char glob_hostname[FN_REFLEN];
+#include "sslopt-vars.h"
#ifdef HAVE_OPENSSL
-static bool opt_use_ssl = FALSE;
-static char *opt_ssl_key = 0;
-static char *opt_ssl_cert = 0;
-static char *opt_ssl_ca = 0;
-static char *opt_ssl_capath = 0;
-static VioSSLAcceptorFd* ssl_acceptor_fd = 0;
+char *des_key_file = 0;
+struct st_VioSSLAcceptorFd *ssl_acceptor_fd= 0;
#endif /* HAVE_OPENSSL */
-
I_List <i_string_pair> replicate_rewrite_db;
I_List<i_string> replicate_do_db, replicate_ignore_db;
// allow the user to tell us which db to replicate and which to ignore
I_List<i_string> binlog_do_db, binlog_ignore_db;
/* if we guessed server_id , we need to know about it */
-ulong server_id = 0;
+ulong server_id= 0; // Must be long becasue of set_var.cc
bool server_id_supplied = 0;
uint mysql_port;
-uint test_flags, select_errors=0, dropping_tables=0,ha_open_options=0;
+uint test_flags = 0, select_errors=0, dropping_tables=0,ha_open_options=0;
uint volatile thread_count=0, thread_running=0, kill_cached_threads=0,
- wake_thread=0, global_read_lock=0;
+ wake_thread=0;
ulong thd_startup_options=(OPTION_UPDATE_LOG | OPTION_AUTO_IS_NULL |
OPTION_BIN_LOG | OPTION_QUOTE_SHOW_CREATE );
uint protocol_version=PROTOCOL_VERSION;
-ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
- max_join_size,join_buff_size,tmp_table_size,thread_stack,
- thread_stack_min,net_wait_timeout,what_to_log= ~ (1L << (uint) COM_TIME),
- query_buff_size, lower_case_table_names, mysqld_net_retry_count,
- net_interactive_timeout, slow_launch_time = 2L,
- net_read_timeout,net_write_timeout,slave_open_temp_tables=0,
- open_files_limit=0, max_binlog_size, record_rnd_cache_size;
+struct system_variables global_system_variables;
+struct system_variables max_system_variables;
+ulonglong keybuff_size;
+ulong table_cache_size,
+ thread_stack,
+ thread_stack_min,what_to_log= ~ (1L << (uint) COM_TIME),
+ query_buff_size,
+ slow_launch_time = 2L,
+ slave_open_temp_tables=0,
+ open_files_limit=0, max_binlog_size, max_relay_log_size;
ulong com_stat[(uint) SQLCOM_END], com_other;
ulong slave_net_timeout;
ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0;
+ulong query_cache_size=0;
+#ifdef HAVE_QUERY_CACHE
+ulong query_cache_limit=0;
+Query_cache query_cache;
+#endif
+
volatile ulong cached_thread_count=0;
// replication parameters, if master_host is not NULL, we are a slave
my_string master_user = (char*) "test", master_password = 0, master_host=0,
- master_info_file = (char*) "master.info";
+ master_info_file = (char*) "master.info",
+ relay_log_info_file = (char*) "relay-log.info",
+ master_ssl_key=0, master_ssl_cert=0, master_ssl_capath=0, master_ssl_cipher=0;
+my_string report_user = 0, report_password = 0, report_host=0;
+
const char *localhost=LOCAL_HOST;
const char *delayed_user="DELAYED";
uint master_port = MYSQL_PORT, master_connect_retry = 60;
+uint report_port = MYSQL_PORT;
+my_bool master_ssl = 0;
-ulong max_tmp_tables,max_heap_table_size,master_retry_count=0;
-ulong bytes_sent = 0L, bytes_received = 0L;
+ulong master_retry_count=0;
+ulong bytes_sent= 0L, bytes_received= 0L, net_big_packet_count= 0L;
-bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory;
-bool opt_using_transactions, using_update_log, opt_warnings=0;
-bool opt_local_infile=1;
-bool volatile abort_loop,select_thread_in_use,grant_option;
-bool volatile ready_to_exit,shutdown_in_progress;
+bool opt_endinfo,using_udf_functions, locked_in_memory;
+bool opt_using_transactions, using_update_log;
+bool volatile abort_loop, select_thread_in_use, signal_thread_in_use;
+bool volatile ready_to_exit, shutdown_in_progress, grant_option;
ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */
-ulong query_id=1L,long_query_count,long_query_time,aborted_threads,
+ulong query_id=1L,long_query_count,aborted_threads, killed_threads,
aborted_connects,delayed_insert_timeout,delayed_insert_limit,
delayed_queue_size,delayed_insert_threads,delayed_insert_writes,
delayed_rows_in_use,delayed_insert_errors,flush_time, thread_created;
@@ -325,27 +403,31 @@ ulong max_connections,max_insert_delayed_threads,max_used_connections,
max_connect_errors, max_user_connections = 0;
ulong thread_id=1L,current_pid;
ulong slow_launch_threads = 0;
-ulong myisam_max_sort_file_size, myisam_max_extra_sort_file_size;
char mysql_real_data_home[FN_REFLEN],
- mysql_data_home[2],language[LIBLEN],reg_ext[FN_EXTLEN],
- default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
- blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot,
- *opt_init_file;
-char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
+ language[LIBLEN],reg_ext[FN_EXTLEN],
+ mysql_charsets_dir[FN_REFLEN], *charsets_list,
+ max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file;
+char *language_ptr= language;
+char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
+#ifndef EMBEDDED_LIBRARY
+bool mysql_embedded=0;
+#else
+bool mysql_embedded=1;
+#endif
+
+static char *opt_bin_logname = 0;
+char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION;
const char *first_keyword="first";
const char **errmesg; /* Error messages */
const char *myisam_recover_options_str="OFF";
const char *sql_mode_str="OFF";
-const char *default_tx_isolation_name;
-enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED;
+ulong rpl_recovery_rank=0;
-#ifdef HAVE_GEMINI_DB
-const char *gemini_recovery_options_str="FULL";
-#endif
-my_string mysql_unix_port=NULL,mysql_tmpdir=NULL;
+my_string mysql_unix_port=NULL, opt_mysql_tmpdir=NULL, mysql_tmpdir=NULL;
ulong my_bind_addr; /* the address we bind to */
+char *my_bind_addr_str;
DATE_FORMAT dayord;
double log_10[32]; /* 10 potences */
I_List<THD> threads,thread_cache;
@@ -353,13 +435,17 @@ time_t start_time;
ulong opt_sql_mode = 0L;
const char *sql_mode_names[] =
-{ "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
- "SERIALIZE","ONLY_FULL_GROUP_BY", NullS };
-TYPELIB sql_mode_typelib= {array_elements(sql_mode_names),"",
+{
+ "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
+ "SERIALIZE","ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
+ "NO_DIR_IN_CREATE",
+ NullS
+};
+TYPELIB sql_mode_typelib= {array_elements(sql_mode_names)-1,"",
sql_mode_names};
MY_BITMAP temp_pool;
-bool use_temp_pool=0;
+my_bool use_temp_pool=0;
pthread_key(MEM_ROOT*,THR_MALLOC);
pthread_key(THD*, THR_THD);
@@ -369,47 +455,53 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_error_log,
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
- LOCK_binlog_update, LOCK_slave, LOCK_server_id,
- LOCK_user_conn;
+ LOCK_global_system_variables,
+ LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
-pthread_cond_t COND_refresh,COND_thread_count,COND_binlog_update,
- COND_slave_stopped, COND_slave_start;
+pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped,
+ COND_slave_start;
pthread_cond_t COND_thread_cache,COND_flush_thread_cache;
pthread_t signal_thread;
pthread_attr_t connection_attrib;
-enum db_type default_table_type=DB_TYPE_MYISAM;
#ifdef __WIN__
#undef getpid
#include <process.h>
+#if !defined(EMBEDDED_LIBRARY)
HANDLE hEventShutdown;
static char shutdown_event_name[40];
#include "nt_servc.h"
static NTService Service; // Service object for WinNT
#endif
+#endif
#ifdef OS2
pthread_cond_t eventShutdown;
#endif
static void start_signal_handler(void);
-static void *signal_hand(void *arg);
+extern "C" pthread_handler_decl(signal_hand, arg);
static void set_options(void);
static void get_options(int argc,char **argv);
static char *get_relative_path(const char *path);
static void fix_paths(void);
-static pthread_handler_decl(handle_connections_sockets,arg);
-static pthread_handler_decl(kill_server_thread,arg);
+extern "C" pthread_handler_decl(handle_connections_sockets,arg);
+extern "C" pthread_handler_decl(kill_server_thread,arg);
static int bootstrap(FILE *file);
+static void close_server_sock();
static bool read_init_file(char *file_name);
#ifdef __NT__
-static pthread_handler_decl(handle_connections_namedpipes,arg);
+extern "C" pthread_handler_decl(handle_connections_namedpipes,arg);
#endif
-extern pthread_handler_decl(handle_slave,arg);
+extern "C" pthread_handler_decl(handle_slave,arg);
#ifdef SET_RLIMIT_NOFILE
static uint set_maximum_open_files(uint max_file_limit);
#endif
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
+static void clean_up(bool print_message);
+static void clean_up_mutexes(void);
+static int test_if_case_insensitive(const char *dir_name);
+static void create_pid_file();
/****************************************************************************
** Code to end mysqld
@@ -437,7 +529,7 @@ static void close_connections(void)
(void) pthread_mutex_unlock(&LOCK_manager);
/* kill connection thread */
-#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
+#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)
DBUG_PRINT("quit",("waiting for select thread: %lx",select_thread));
(void) pthread_mutex_lock(&LOCK_thread_count);
@@ -446,20 +538,14 @@ static void close_connections(void)
struct timespec abstime;
int error;
LINT_INIT(error);
+ DBUG_PRINT("info",("Waiting for select_thread"));
+
#ifndef DONT_USE_THR_ALARM
if (pthread_kill(select_thread,THR_CLIENT_ALARM))
break; // allready dead
#endif
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time(NULL)+2; // Bsd 2.1
- abstime.ts_nsec=0;
-#else
- struct timeval tv;
- gettimeofday(&tv,0);
- abstime.tv_sec=tv.tv_sec+2;
- abstime.tv_nsec=tv.tv_usec*1000;
-#endif
- for (uint tmp=0 ; tmp < 10 ; tmp++)
+ set_timespec(abstime, 2);
+ for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
{
error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
&abstime);
@@ -488,28 +574,28 @@ static void close_connections(void)
}
}
#ifdef __NT__
-if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
-{
- HANDLE temp;
- DBUG_PRINT( "quit", ("Closing named pipes") );
-
- /* Create connection to the handle named pipe handler to break the loop */
- if ((temp = CreateFile(szPipeName,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL )) != INVALID_HANDLE_VALUE)
+ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
{
- WaitNamedPipe(szPipeName, 1000);
- DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
- SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
- CancelIo(temp);
- DisconnectNamedPipe(temp);
- CloseHandle(temp);
+ HANDLE temp;
+ DBUG_PRINT( "quit", ("Closing named pipes") );
+
+ /* Create connection to the handle named pipe handler to break the loop */
+ if ((temp = CreateFile(szPipeName,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL )) != INVALID_HANDLE_VALUE)
+ {
+ WaitNamedPipe(szPipeName, 1000);
+ DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
+ SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
+ CancelIo(temp);
+ DisconnectNamedPipe(temp);
+ CloseHandle(temp);
+ }
}
- }
#endif
#ifdef HAVE_SYS_UN_H
if (unix_sock != INVALID_SOCKET)
@@ -520,7 +606,7 @@ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
unix_sock= INVALID_SOCKET;
}
#endif
- end_thr_alarm(); // Don't allow alarms
+ end_thr_alarm(0); // Abort old alarms.
end_slave();
/* First signal all threads that it's time to die */
@@ -550,13 +636,11 @@ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
(void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
if (thread_count)
- {
sleep(1); // Give threads time to die
- }
/* Force remaining threads to die by closing the connection to the client */
- (void) my_net_init(&net, (Vio*) 0);
+ (void) my_net_init(&net, (st_vio*) 0);
for (;;)
{
DBUG_PRINT("quit",("Locking LOCK_thread_count"));
@@ -589,74 +673,93 @@ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
}
(void) pthread_mutex_unlock(&LOCK_thread_count);
- mysql_log.close(1);
- mysql_slow_log.close(1);
- mysql_update_log.close(1);
- mysql_bin_log.close(1);
DBUG_PRINT("quit",("close_connections thread"));
DBUG_VOID_RETURN;
}
-#ifdef HAVE_CLOSE_SERVER_SOCK
-void close_server_sock()
+
+static void close_server_sock()
{
+#ifdef HAVE_CLOSE_SERVER_SOCK
DBUG_ENTER("close_server_sock");
-
- if (ip_sock != INVALID_SOCKET)
+ my_socket tmp_sock;
+ tmp_sock=ip_sock;
+ if (tmp_sock != INVALID_SOCKET)
{
+ ip_sock=INVALID_SOCKET;
DBUG_PRINT("info",("calling shutdown on TCP/IP socket"));
- VOID(shutdown(ip_sock,2));
-#ifdef NOT_USED
+ VOID(shutdown(tmp_sock,2));
+#if defined(__NETWARE__)
/*
- The following code is disabled as it cases MySQL to hang on
- AIX 4.3 during shutdown
+ The following code is disabled for normal systems as it causes MySQL
+ to hang on AIX 4.3 during shutdown
*/
DBUG_PRINT("info",("calling closesocket on TCP/IP socket"));
- VOID(closesocket(ip_sock));
+ VOID(closesocket(tmp_sock));
#endif
- ip_sock=INVALID_SOCKET;
}
- if (unix_sock != INVALID_SOCKET)
+ tmp_sock=unix_sock;
+ if (tmp_sock != INVALID_SOCKET)
{
+ unix_sock=INVALID_SOCKET;
DBUG_PRINT("info",("calling shutdown on unix socket"));
- VOID(shutdown(unix_sock,2));
+ VOID(shutdown(tmp_sock,2));
+#if defined(__NETWARE__)
+ /*
+ The following code is disabled for normal systems as it may cause MySQL
+ to hang on AIX 4.3 during shutdown
+ */
+ DBUG_PRINT("info",("calling closesocket on unix/IP socket"));
+ VOID(closesocket(tmp_sock));
+#endif
VOID(unlink(mysql_unix_port));
- unix_sock=INVALID_SOCKET;
}
DBUG_VOID_RETURN;
-}
#endif
+}
+
void kill_mysql(void)
{
DBUG_ENTER("kill_mysql");
+
#ifdef SIGNALS_DONT_BREAK_READ
abort_loop=1; // Break connection loops
close_server_sock(); // Force accept to wake up
-#endif
+#endif
+
#if defined(__WIN__)
+#if !defined(EMBEDDED_LIBRARY)
{
if (!SetEvent(hEventShutdown))
{
DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
}
+ /*
+ or:
+ HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
+ SetEvent(hEventShutdown);
+ CloseHandle(hEvent);
+ */
}
+#endif
#elif defined(OS2)
pthread_cond_signal( &eventShutdown); // post semaphore
#elif defined(HAVE_PTHREAD_KILL)
- if (pthread_kill(signal_thread,MYSQL_KILL_SIGNAL))// End everything nicely
+ if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
{
DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
}
#elif !defined(SIGNALS_DONT_BREAK_READ)
- kill(current_pid,MYSQL_KILL_SIGNAL);
+ kill(current_pid, MYSQL_KILL_SIGNAL);
#endif
DBUG_PRINT("quit",("After pthread_kill"));
shutdown_in_progress=1; // Safety if kill didn't work
-#ifdef SIGNALS_DONT_BREAK_READ
+#ifdef SIGNALS_DONT_BREAK_READ
if (!kill_in_progress)
{
pthread_t tmp;
+ abort_loop=1;
if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
(void*) 0))
sql_print_error("Error: Can't create thread to kill server");
@@ -668,22 +771,21 @@ void kill_mysql(void)
/* Force server down. kill all connections and threads and exit */
-#if defined(OS2)
+#if defined(OS2) || defined(__NETWARE__)
extern "C" void kill_server(int sig_ptr)
-#define RETURN_FROM_KILL_SERVER return
+#define RETURN_FROM_KILL_SERVER DBUG_VOID_RETURN
#elif !defined(__WIN__)
static void *kill_server(void *sig_ptr)
-#define RETURN_FROM_KILL_SERVER return 0
+#define RETURN_FROM_KILL_SERVER DBUG_RETURN(0)
#else
static void __cdecl kill_server(int sig_ptr)
-#define RETURN_FROM_KILL_SERVER return
+#define RETURN_FROM_KILL_SERVER DBUG_VOID_RETURN
#endif
{
int sig=(int) (long) sig_ptr; // This is passed a int
DBUG_ENTER("kill_server");
- // if there is a signal during the kill in progress, we do not need
- // another one
+ // if there is a signal during the kill in progress, ignore the other
if (kill_in_progress) // Safety
RETURN_FROM_KILL_SERVER;
kill_in_progress=TRUE;
@@ -694,22 +796,29 @@ static void __cdecl kill_server(int sig_ptr)
else
sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
-#if defined(USE_ONE_SIGNAL_HAND) && !defined(__WIN__) && !defined(OS2)
+#if defined(__NETWARE__) || (defined(USE_ONE_SIGNAL_HAND) && !defined(__WIN__) && !defined(OS2))
my_thread_init(); // If this is a new thread
#endif
close_connections();
if (sig != MYSQL_KILL_SIGNAL && sig != 0)
unireg_abort(1); /* purecov: inspected */
else
- unireg_end(0);
+ unireg_end();
+
+#ifdef __NETWARE__
+ pthread_join(select_thread, NULL); // wait for main thread
+#endif /* __NETWARE__ */
+
pthread_exit(0); /* purecov: deadcode */
+
RETURN_FROM_KILL_SERVER;
}
-#ifdef USE_ONE_SIGNAL_HAND
-pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
+#if defined(USE_ONE_SIGNAL_HAND) || (defined(__NETWARE__) && defined(SIGNALS_DONT_BREAK_READ))
+extern "C" pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
{
+ SHUTDOWN_THD;
my_thread_init(); // Initialize new thread
kill_server(0);
my_thread_end(); // Normally never reached
@@ -717,25 +826,47 @@ pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
}
#endif
-static sig_handler print_signal_warning(int sig)
+#if defined(__amiga__)
+#undef sigset
+#define sigset signal
+#endif
+
+extern "C" sig_handler print_signal_warning(int sig)
{
- if (opt_warnings)
- sql_print_error("Warning: Got signal %d from thread %d",
- sig,my_thread_id());
+ if (!DBUG_IN_USE)
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_error("Warning: Got signal %d from thread %d",
+ sig,my_thread_id());
+ }
#ifdef DONT_REMEMBER_SIGNAL
sigset(sig,print_signal_warning); /* int. thread system calls */
#endif
-#if !defined(__WIN__) && !defined(OS2)
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
if (sig == SIGALRM)
alarm(2); /* reschedule alarm */
#endif
}
+/*
+ cleanup all memory and end program nicely
+
+ SYNOPSIS
+ unireg_end()
+
+ NOTES
+ This function never returns.
+
+ If SIGNALS_DONT_BREAK_READ is defined, this function is called
+ by the main thread. To get MySQL to shut down nicely in this case
+ (Mac OS X) we have to call exit() instead if pthread_exit().
+*/
-void unireg_end(int signal_number __attribute__((unused)))
+void unireg_end(void)
{
- clean_up();
-#ifdef SIGNALS_DONT_BREAK_READ
+ clean_up(1);
+ my_thread_end();
+#if defined(SIGNALS_DONT_BREAK_READ) && !defined(__NETWARE__)
exit(0);
#else
pthread_exit(0); // Exit is in main thread
@@ -743,11 +874,15 @@ void unireg_end(int signal_number __attribute__((unused)))
}
-void unireg_abort(int exit_code)
+extern "C" void unireg_abort(int exit_code)
{
+ DBUG_ENTER("unireg_abort");
if (exit_code)
sql_print_error("Aborting\n");
- clean_up(); /* purecov: inspected */
+ clean_up(1); /* purecov: inspected */
+ DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
+ clean_up_mutexes();
+ my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(exit_code); /* purecov: inspected */
}
@@ -757,48 +892,108 @@ void clean_up(bool print_message)
DBUG_PRINT("exit",("clean_up"));
if (cleanup_done++)
return; /* purecov: inspected */
+
+ mysql_log.cleanup();
+ mysql_slow_log.cleanup();
+ mysql_update_log.cleanup();
+ mysql_bin_log.cleanup();
+
if (use_slave_mask)
bitmap_free(&slave_error_mask);
acl_free(1);
grant_free();
- sql_cache_free();
+ query_cache_destroy();
table_cache_free();
hostname_cache_free();
item_user_lock_free();
lex_free(); /* Free some memory */
+ set_var_free();
#ifdef HAVE_DLOPEN
if (!opt_noacl)
udf_free();
#endif
(void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */
end_key_cache();
+ end_thr_alarm(1); /* Free allocated memory */
#ifdef USE_RAID
end_raid();
#endif
- free_defaults(defaults_argv);
+ if (defaults_argv)
+ free_defaults(defaults_argv);
my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR));
- my_free(mysql_tmpdir,MYF(0));
+ my_free(mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
x_free(opt_bin_logname);
+ x_free(opt_relay_logname);
bitmap_free(&temp_pool);
free_max_user_conn();
-#ifndef __WIN__
- if (!opt_bootstrap)
- (void) my_delete(pidfile_name,MYF(0)); // This may not always exist
+ end_slave_list();
+ free_list(&replicate_do_db);
+ free_list(&replicate_ignore_db);
+ free_list(&binlog_do_db);
+ free_list(&binlog_ignore_db);
+ free_list(&replicate_rewrite_db);
+
+#ifdef HAVE_OPENSSL
+ if (ssl_acceptor_fd)
+ my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR));
+ free_des_key_file();
+#endif /* HAVE_OPENSSL */
+#ifdef USE_REGEX
+ regex_end();
#endif
+
if (print_message && errmesg)
sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
+#if !defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
+ if (!opt_bootstrap)
+ (void) my_delete(pidfile_name,MYF(0)); // This may not always exist
+#endif
x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */
- my_thread_end();
-
+ DBUG_PRINT("quit", ("Error messages freed"));
/* Tell main we are ready */
(void) pthread_mutex_lock(&LOCK_thread_count);
+ DBUG_PRINT("quit", ("got thread count lock"));
ready_to_exit=1;
/* do the broadcast inside the lock to ensure that my_end() is not called */
(void) pthread_cond_broadcast(&COND_thread_count);
(void) pthread_mutex_unlock(&LOCK_thread_count);
+ /*
+ The following lines may never be executed as the main thread may have
+ killed us
+ */
+ DBUG_PRINT("quit", ("done with cleanup"));
} /* clean_up */
+static void clean_up_mutexes()
+{
+ (void) pthread_mutex_destroy(&LOCK_mysql_create_db);
+ (void) pthread_mutex_destroy(&LOCK_Acl);
+ (void) pthread_mutex_destroy(&LOCK_grant);
+ (void) pthread_mutex_destroy(&LOCK_open);
+ (void) pthread_mutex_destroy(&LOCK_thread_count);
+ (void) pthread_mutex_destroy(&LOCK_mapped_file);
+ (void) pthread_mutex_destroy(&LOCK_status);
+ (void) pthread_mutex_destroy(&LOCK_error_log);
+ (void) pthread_mutex_destroy(&LOCK_delayed_insert);
+ (void) pthread_mutex_destroy(&LOCK_delayed_status);
+ (void) pthread_mutex_destroy(&LOCK_delayed_create);
+ (void) pthread_mutex_destroy(&LOCK_manager);
+ (void) pthread_mutex_destroy(&LOCK_crypt);
+ (void) pthread_mutex_destroy(&LOCK_bytes_sent);
+ (void) pthread_mutex_destroy(&LOCK_bytes_received);
+ (void) pthread_mutex_destroy(&LOCK_user_conn);
+ (void) pthread_mutex_destroy(&LOCK_rpl_status);
+ (void) pthread_mutex_destroy(&LOCK_active_mi);
+ (void) pthread_mutex_destroy(&LOCK_global_system_variables);
+ (void) pthread_cond_destroy(&COND_thread_count);
+ (void) pthread_cond_destroy(&COND_refresh);
+ (void) pthread_cond_destroy(&COND_thread_cache);
+ (void) pthread_cond_destroy(&COND_flush_thread_cache);
+ (void) pthread_cond_destroy(&COND_manager);
+ (void) pthread_cond_destroy(&COND_rpl_status);
+}
/****************************************************************************
** Init IP and UNIX socket
@@ -832,18 +1027,25 @@ static void set_ports()
static void set_user(const char *user)
{
-#if !defined(__WIN__) && !defined(OS2)
- struct passwd *ent;
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
+ struct passwd *ent;
+ uid_t user_id= geteuid();
// don't bother if we aren't superuser
- if (geteuid())
+ if (user_id)
{
if (user)
- fprintf(stderr,
- "Warning: One can only use the --user switch if running as root\n");
+ {
+ /* Don't give a warning, if real user is same as given with --user */
+ struct passwd *user_info= getpwnam(user);
+
+ if (!user_info || user_id != user_info->pw_uid)
+ fprintf(stderr,
+ "Warning: One can only use the --user switch if running as root\n");
+ }
return;
}
- else if (!user)
+ if (!user)
{
if (!opt_bootstrap)
{
@@ -855,20 +1057,33 @@ static void set_user(const char *user)
if (!strcmp(user,"root"))
return; // Avoid problem with dynamic libraries
+ uid_t uid;
if (!(ent = getpwnam(user)))
{
- fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
- unireg_abort(1);
+ // allow a numeric uid to be used
+ const char *pos;
+ for (pos=user; isdigit(*pos); pos++) ;
+ if (*pos) // Not numeric id
+ {
+ fprintf(stderr,"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
+ unireg_abort(1);
+ }
+ uid=atoi(user); // Use numberic uid
}
+ else
+ {
#ifdef HAVE_INITGROUPS
- initgroups((char*) user,ent->pw_gid);
+ initgroups((char*) user,ent->pw_gid);
#endif
- if (setgid(ent->pw_gid) == -1)
- {
- sql_perror("setgid");
- unireg_abort(1);
+ if (setgid(ent->pw_gid) == -1)
+ {
+ sql_perror("setgid");
+ unireg_abort(1);
+ }
+ uid=ent->pw_uid;
}
- if (setuid(ent->pw_uid) == -1)
+
+ if (setuid(uid) == -1)
{
sql_perror("setuid");
unireg_abort(1);
@@ -880,14 +1095,13 @@ static void set_user(const char *user)
static void set_root(const char *path)
{
-#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
+#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)
if (chroot(path) == -1)
{
sql_perror("chroot");
unireg_abort(1);
}
-// my_setwd("/", MYF(0));
- sql_print_error("Warning: --chroot option doesn't provide 100%% closed chroot jail in MySQL 3.23. Upgrade to 4.0");
+ my_setwd("/", MYF(0));
#endif
}
@@ -928,7 +1142,14 @@ static void server_init(void)
IPaddr.sin_family = AF_INET;
IPaddr.sin_addr.s_addr = my_bind_addr;
IPaddr.sin_port = (unsigned short) htons((unsigned short) mysql_port);
+
+#ifndef __WIN__
+ /*
+ We should not use SO_REUSEADDR on windows as this would enable a
+ user to open two mysqld servers with the same TCP/IP port.
+ */
(void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
+#endif
if (bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
sizeof(IPaddr)) < 0)
{
@@ -940,15 +1161,12 @@ static void server_init(void)
if (listen(ip_sock,(int) back_log) < 0)
{
sql_perror("Can't start server: listen() on TCP/IP port");
- sql_print_error("Warning: listen() on TCP/IP failed with error %d",
+ sql_print_error("Error: listen() on TCP/IP failed with error %d",
socket_errno);
unireg_abort(1);
}
}
- if (mysqld_chroot)
- set_root(mysqld_chroot);
-
- set_user(mysqld_user); // set_user now takes care of mysqld_user==NULL
+ set_user(mysqld_user); // Works also with mysqld_user==NULL
#ifdef __NT__
/* create named pipe */
@@ -978,8 +1196,8 @@ static void server_init(void)
PIPE_READMODE_BYTE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
- (int) net_buffer_length,
- (int) net_buffer_length,
+ (int) global_system_variables.net_buffer_length,
+ (int) global_system_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity )) == INVALID_HANDLE_VALUE)
{
@@ -1042,7 +1260,7 @@ void yyerror(const char *s)
{
NET *net=my_pthread_getspecific_ptr(NET*,THR_NET);
char *yytext=(char*) current_lex->tok_start;
- if (!strcmp(s,"parse error"))
+ if (!strcmp(s,"parse error") || !strcmp(s,"syntax error"))
s=ER(ER_SYNTAX_ERROR);
net_printf(net,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "",
current_lex->yylineno);
@@ -1051,7 +1269,7 @@ void yyerror(const char *s)
void close_connection(NET *net,uint errcode,bool lock)
{
- Vio* vio;
+ st_vio* vio;
DBUG_ENTER("close_connection");
DBUG_PRINT("enter",("fd: %s error: '%s'",
net->vio? vio_description(net->vio):"(not connected)",
@@ -1072,12 +1290,15 @@ void close_connection(NET *net,uint errcode,bool lock)
/* Called when a thread is aborted */
/* ARGSUSED */
-sig_handler end_thread_signal(int sig __attribute__((unused)))
+extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
{
THD *thd=current_thd;
DBUG_ENTER("end_thread_signal");
- if (thd)
+ if (thd && ! thd->bootstrap)
+ {
+ statistic_increment(killed_threads, &LOCK_status);
end_thread(thd,0);
+ }
DBUG_VOID_RETURN; /* purecov: deadcode */
}
@@ -1117,6 +1338,7 @@ void end_thread(THD *thd, bool put_in_cache)
/* Tell main we are ready */
(void) pthread_mutex_unlock(&LOCK_thread_count);
+ /* It's safe to broadcast outside a lock (COND... is not deleted here) */
(void) pthread_cond_broadcast(&COND_thread_count);
DBUG_PRINT("info", ("unlocked thread_count mutex"))
#ifdef ONE_THREAD
@@ -1129,21 +1351,6 @@ void end_thread(THD *thd, bool put_in_cache)
DBUG_VOID_RETURN;
}
-#ifdef SIGNALS_DONT_BREAK_READ
-inline void kill_broken_server()
-{
- /* hack to get around signals ignored in syscalls for problem OS's */
- if (unix_sock == INVALID_SOCKET ||
- (!opt_disable_networking && ip_sock == INVALID_SOCKET))
- {
- select_thread_in_use = 0;
- kill_server((void*)MYSQL_KILL_SIGNAL); /* never returns */
- }
-}
-#define MAYBE_BROKEN_SYSCALL kill_broken_server();
-#else
-#define MAYBE_BROKEN_SYSCALL
-#endif
/* Start a cached thread. LOCK_thread_count is locked on entry */
@@ -1170,14 +1377,14 @@ void flush_thread_cache()
}
- /*
- ** Aborts a thread nicely. Commes here on SIGPIPE
- ** TODO: One should have to fix that thr_alarm know about this
- ** thread too
- */
+/*
+ Aborts a thread nicely. Commes here on SIGPIPE
+ TODO: One should have to fix that thr_alarm know about this
+ thread too.
+*/
#ifdef THREAD_SPECIFIC_SIGPIPE
-static sig_handler abort_thread(int sig __attribute__((unused)))
+extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
{
THD *thd=current_thd;
DBUG_ENTER("abort_thread");
@@ -1188,9 +1395,9 @@ static sig_handler abort_thread(int sig __attribute__((unused)))
#endif
/******************************************************************************
-** Setup a signal thread with handles all signals
-** Because linux doesn't support scemas use a mutex to check that
-** the signal thread is ready before continuing
+ Setup a signal thread with handles all signals.
+ Because Linux doesn't support schemas use a mutex to check that
+ the signal thread is ready before continuing
******************************************************************************/
#if defined(__WIN__) || defined(OS2)
@@ -1207,26 +1414,69 @@ static void init_signals(void)
}
static void start_signal_handler(void)
+{}
+
+static void check_data_home(const char *path)
+{}
+
+#elif defined(__NETWARE__)
+
+// down server event callback
+void mysql_down_server_cb(void *, void *)
{
+ kill_server(0);
+}
+
+// destroy callback resources
+void mysql_cb_destroy(void *)
+{
+ UnRegisterEventNotification(eh); // cleanup down event notification
+ NX_UNWRAP_INTERFACE(ref);
+}
+
+// initialize callbacks
+void mysql_cb_init()
+{
+ // register for down server event
+ void *handle = getnlmhandle();
+ rtag_t rt = AllocateResourceTag(handle, "MySQL Down Server Callback",
+ EventSignature);
+ NX_WRAP_INTERFACE((void *)mysql_down_server_cb, 2, (void **)&ref);
+ eh = RegisterForEventNotification(rt, EVENT_DOWN_SERVER,
+ EVENT_PRIORITY_APPLICATION,
+ NULL, ref, NULL);
+ NXVmRegisterExitHandler(mysql_cb_destroy, NULL); // clean-up
}
-#elif defined(__EMX__)
static void init_signals(void)
{
- signal(SIGQUIT, sig_kill);
- signal(SIGKILL, sig_kill);
- signal(SIGTERM, sig_kill);
- signal(SIGINT, sig_kill);
- signal(SIGHUP, sig_reload); // Flush everything
- signal(SIGALRM, SIG_IGN);
- signal(SIGBREAK,SIG_IGN);
- signal_thread = pthread_self();
+ int signals[] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGABRT};
+
+ for (uint i=0 ; i < sizeof(signals)/sizeof(int) ; i++)
+ signal(signals[i], kill_server);
+ mysql_cb_init(); // initialize callbacks
+}
+
+static void start_signal_handler(void)
+{
+ // Save vm id of this process
+ if (!opt_bootstrap)
+ create_pid_file();
+ // no signal handler
}
+/* Warn if the data is on a Traditional volume */
+
+static void check_data_home(const char *path)
+{
+}
+
+#elif defined(__EMX__)
static void sig_reload(int signo)
{
- reload_acl_and_cache((THD*) 0,REFRESH_LOG, (TABLE_LIST*) 0); // Flush everything
+ // Flush everything
+ reload_acl_and_cache((THD*) 0,REFRESH_LOG, (TABLE_LIST*) 0);
signal(signo, SIG_ACK);
}
@@ -1240,24 +1490,39 @@ static void sig_kill(int signo)
signal(signo, SIG_ACK);
}
-
-static void start_signal_handler(void)
+static void init_signals(void)
{
+ signal(SIGQUIT, sig_kill);
+ signal(SIGKILL, sig_kill);
+ signal(SIGTERM, sig_kill);
+ signal(SIGINT, sig_kill);
+ signal(SIGHUP, sig_reload); // Flush everything
+ signal(SIGALRM, SIG_IGN);
+ signal(SIGBREAK,SIG_IGN);
+ signal_thread = pthread_self();
+ SIGNAL_THD;
}
+
+static void start_signal_handler(void)
+{}
+
+static void check_data_home(const char *path)
+{}
+
#else /* if ! __WIN__ && ! __EMX__ */
#ifdef HAVE_LINUXTHREADS
#define UNSAFE_DEFAULT_LINUX_THREADS 200
#endif
-static sig_handler handle_segfault(int sig)
+extern "C" sig_handler handle_segfault(int sig)
{
THD *thd=current_thd;
/*
- Strictly speaking, we should need a mutex here
+ Strictly speaking, one needs a mutex here
but since we have got SIGSEGV already, things are a mess
so not having the mutex is not as bad as possibly using a buggy
- mutex - so we keep things simple.
+ mutex - so we keep things simple
*/
if (segfaulted)
{
@@ -1275,37 +1540,36 @@ or misconfigured. This error can also be caused by malfunctioning hardware.\n",
fprintf(stderr, "\
We will try our best to scrape up some info that will hopefully help diagnose\n\
the problem, but since we have already crashed, something is definitely wrong\n\
-and this may fail\n\n");
- fprintf(stderr, "key_buffer_size=%ld\n", keybuff_size);
- fprintf(stderr, "record_buffer=%ld\n", my_default_record_cache_size);
- fprintf(stderr, "sort_buffer=%ld\n", sortbuff_size);
+and this may fail.\n\n");
+ fprintf(stderr, "key_buffer_size=%lu\n", (ulong) keybuff_size);
+ fprintf(stderr, "read_buffer_size=%ld\n", global_system_variables.read_buff_size);
fprintf(stderr, "max_used_connections=%ld\n", max_used_connections);
fprintf(stderr, "max_connections=%ld\n", max_connections);
fprintf(stderr, "threads_connected=%d\n", thread_count);
fprintf(stderr, "It is possible that mysqld could use up to \n\
-key_buffer_size + (record_buffer + sort_buffer)*max_connections = %ld K\n\
-bytes of memory\n", (keybuff_size + (my_default_record_cache_size +
- sortbuff_size) * max_connections)/ 1024);
- fprintf(stderr, "Hope that's ok, if not, decrease some variables in the equation\n\n");
+key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = %ld K\n\
+bytes of memory\n", ((ulong) keybuff_size +
+ (global_system_variables.read_buff_size +
+ global_system_variables.sortbuff_size) *
+ max_connections)/ 1024);
+ fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
#if defined(HAVE_LINUXTHREADS)
if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
{
fprintf(stderr, "\
You seem to be running 32-bit Linux and have %d concurrent connections.\n\
-If you have not changed STACK_SIZE in LinuxThreads and build the binary \n\
-yourself, LinuxThreads is quite likely to steal a part of global heap for\n\
+If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\
+yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\
the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n",
thread_count);
}
#endif /* HAVE_LINUXTHREADS */
#ifdef HAVE_STACKTRACE
- if(!(test_flags & TEST_NO_STACKTRACE))
+ if (!(test_flags & TEST_NO_STACKTRACE))
{
-#ifdef HAVE_GEMINI_DB
- utrace();
-#endif
+ fprintf(stderr,"thd=%p\n",thd);
print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0,
thread_stack);
}
@@ -1315,15 +1579,10 @@ the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n",
Some pointers may be invalid and cause the dump to abort...\n");
safe_print_str("thd->query", thd->query, 1024);
fprintf(stderr, "thd->thread_id=%ld\n", thd->thread_id);
- fprintf(stderr, "\n\
-Successfully dumped variables, if you ran with --log, take a look at the\n\
-details of what thread %ld did to cause the crash. In some cases of really\n\
-bad corruption, the values shown above may be invalid\n\n",
- thd->thread_id);
}
fprintf(stderr, "\
-The manual page at http://www.mysql.com/doc/C/r/Crashing.html contains\n\
-information that should help you find out what is causing the crash\n");
+The manual page at http://www.mysql.com/doc/en/Crashing.html contains\n\
+information that should help you find out what is causing the crash.\n");
fflush(stderr);
#endif /* HAVE_STACKTRACE */
@@ -1349,7 +1608,8 @@ static void init_signals(void)
struct sigaction sa;
DBUG_ENTER("init_signals");
- sigset(THR_KILL_SIGNAL,end_thread_signal);
+ if (test_flags & TEST_SIGINT)
+ sigset(THR_KILL_SIGNAL,end_thread_signal);
sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
@@ -1359,13 +1619,30 @@ static void init_signals(void)
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
init_stacktrace();
+#if defined(__amiga__)
+ sa.sa_handler=(void(*)())handle_segfault;
+#else
sa.sa_handler=handle_segfault;
+#endif
sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGABRT, &sa, NULL);
#ifdef SIGBUS
sigaction(SIGBUS, &sa, NULL);
#endif
sigaction(SIGILL, &sa, NULL);
+ sigaction(SIGFPE, &sa, NULL);
}
+
+#ifdef HAVE_GETRLIMIT
+ if (test_flags & TEST_CORE_ON_SIGNAL)
+ {
+ /* Change limits so that we will get a core file */
+ struct rlimit rl;
+ rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
+ sql_print_error("Warning: setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals");
+ }
+#endif
(void) sigemptyset(&set);
#ifdef THREAD_SPECIFIC_SIGPIPE
sigset(SIGPIPE,abort_thread);
@@ -1380,6 +1657,7 @@ static void init_signals(void)
sigaddset(&set,SIGHUP);
/* Fix signals if blocked by parents (can happen on Mac OS X) */
+ sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = print_signal_warning;
sigaction(SIGTERM, &sa, (struct sigaction*) 0);
@@ -1390,7 +1668,8 @@ static void init_signals(void)
sigaddset(&set,SIGTSTP);
#endif
sigaddset(&set,THR_SERVER_ALARM);
- sigdelset(&set,THR_KILL_SIGNAL); // May be SIGINT
+ if (test_flags & TEST_SIGINT)
+ sigdelset(&set,THR_KILL_SIGNAL); // May be SIGINT
sigdelset(&set,THR_CLIENT_ALARM); // For alarms
sigprocmask(SIG_SETMASK,&set,NULL);
pthread_sigmask(SIG_SETMASK,&set,NULL);
@@ -1410,7 +1689,7 @@ static void start_signal_handler(void)
(void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR);
- pthread_attr_setstacksize(&thr_attr,32768);
+ pthread_attr_setstacksize(&thr_attr,thread_stack);
#endif
(void) pthread_mutex_lock(&LOCK_thread_count);
@@ -1428,17 +1707,16 @@ static void start_signal_handler(void)
}
-/*
-** This threads handles all signals and alarms
-*/
+/* This threads handles all signals and alarms */
/* ARGSUSED */
-static void *signal_hand(void *arg __attribute__((unused)))
+extern "C" void *signal_hand(void *arg __attribute__((unused)))
{
sigset_t set;
int sig;
my_thread_init(); // Init new thread
DBUG_ENTER("signal_hand");
+ signal_thread_in_use= 1;
/*
Setup alarm handler
@@ -1447,9 +1725,12 @@ static void *signal_hand(void *arg __attribute__((unused)))
*/
init_thr_alarm(max_connections+max_insert_delayed_threads+10);
#if SIGINT != THR_KILL_SIGNAL
- (void) sigemptyset(&set); // Setup up SIGINT for debug
- (void) sigaddset(&set,SIGINT); // For debugging
- (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
+ if (test_flags & TEST_SIGINT)
+ {
+ (void) sigemptyset(&set); // Setup up SIGINT for debug
+ (void) sigaddset(&set,SIGINT); // For debugging
+ (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
+ }
#endif
(void) sigemptyset(&set); // Setup up SIGINT for debug
#ifdef USE_ONE_SIGNAL_HAND
@@ -1464,34 +1745,44 @@ static void *signal_hand(void *arg __attribute__((unused)))
/* Save pid to this process (or thread on Linux) */
if (!opt_bootstrap)
+ create_pid_file();
+
+#ifdef HAVE_STACK_TRACE_ON_SEGV
+ if (opt_do_pstack)
{
- File pidFile;
- if ((pidFile = my_create(pidfile_name,0664, O_WRONLY, MYF(MY_WME))) >= 0)
- {
- char buff[21];
- sprintf(buff,"%lu",(ulong) getpid());
- (void) my_write(pidFile, buff,strlen(buff),MYF(MY_WME));
- (void) my_close(pidFile,MYF(0));
- }
+ sprintf(pstack_file_name,"mysqld-%lu-%%d-%%d.backtrace", (ulong)getpid());
+ pstack_install_segv_action(pstack_file_name);
}
+#endif /* HAVE_STACK_TRACE_ON_SEGV */
- // signal to start_signal_handler that we are ready
+ /*
+ signal to start_signal_handler that we are ready
+ This works by waiting for start_signal_handler to free mutex,
+ after which we signal it that we are ready.
+ At this pointer there is no other threads running, so there
+ should not be any other pthread_cond_signal() calls.
+ */
(void) pthread_mutex_lock(&LOCK_thread_count);
- (void) pthread_cond_signal(&COND_thread_count);
(void) pthread_mutex_unlock(&LOCK_thread_count);
+ (void) pthread_cond_broadcast(&COND_thread_count);
+ (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
for (;;)
{
int error; // Used when debugging
if (shutdown_in_progress && !abort_loop)
{
- sig= MYSQL_KILL_SIGNAL;
+ sig= SIGTERM;
error=0;
}
else
while ((error=my_sigwait(&set,&sig)) == EINTR) ;
if (cleanup_done)
+ {
+ my_thread_end();
+ signal_thread_in_use= 0;
pthread_exit(0); // Safety
+ }
switch (sig) {
case SIGTERM:
case SIGQUIT:
@@ -1508,17 +1799,23 @@ static void *signal_hand(void *arg __attribute__((unused)))
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR);
if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
- (void*) 0))
+ (void*) sig))
sql_print_error("Error: Can't create thread to kill server");
#else
- kill_server((void*) sig); // MIT THREAD has a alarm thread
+ kill_server((void*) sig); // MIT THREAD has a alarm thread
#endif
}
break;
case SIGHUP:
- reload_acl_and_cache((THD*) 0,REFRESH_LOG,
- (TABLE_LIST*) 0); // Flush logs
- mysql_print_status((THD*) 0); // Send debug some info
+ if (!abort_loop)
+ {
+ reload_acl_and_cache((THD*) 0,
+ (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
+ REFRESH_STATUS | REFRESH_GRANT |
+ REFRESH_THREADS | REFRESH_HOSTS),
+ (TABLE_LIST*) 0); // Flush logs
+ mysql_print_status((THD*) 0); // Send debug some info
+ }
break;
#ifdef USE_ONE_SIGNAL_HAND
case THR_SERVER_ALARM:
@@ -1527,7 +1824,7 @@ static void *signal_hand(void *arg __attribute__((unused)))
#endif
default:
#ifdef EXTRA_DEBUG
- sql_print_error("Warning: Got signal: %d, error: %d",sig,error); /* purecov: tested */
+ sql_print_error("Warning: Got signal: %d error: %d",sig,error); /* purecov: tested */
#endif
break; /* purecov: tested */
}
@@ -1535,18 +1832,21 @@ static void *signal_hand(void *arg __attribute__((unused)))
return(0); /* purecov: deadcode */
}
+static void check_data_home(const char *path)
+{}
+
#endif /* __WIN__*/
/*
-** All global error messages are sent here where the first one is stored for
-** the client
+ All global error messages are sent here where the first one is stored for
+ the client
*/
/* ARGSUSED */
-static int my_message_sql(uint error, const char *str,
- myf MyFlags __attribute__((unused)))
+extern "C" int my_message_sql(uint error, const char *str,
+ myf MyFlags __attribute__((unused)))
{
NET *net;
DBUG_ENTER("my_message_sql");
@@ -1564,6 +1864,17 @@ static int my_message_sql(uint error, const char *str,
DBUG_RETURN(0);
}
+
+/*
+ Forget last error message (if we got one)
+*/
+
+void clear_error_message(THD *thd)
+{
+ thd->net.last_error[0]= 0;
+}
+
+
#ifdef __WIN__
struct utsname
@@ -1571,28 +1882,29 @@ struct utsname
char nodename[FN_REFLEN];
};
+
int uname(struct utsname *a)
{
return -1;
}
-#endif
-#ifdef __WIN__
-pthread_handler_decl(handle_shutdown,arg)
+extern "C" pthread_handler_decl(handle_shutdown,arg)
{
MSG msg;
+ SHUTDOWN_THD;
my_thread_init();
/* this call should create the message queue for this thread */
PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
-
+#if !defined(EMBEDDED_LIBRARY)
if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
+#endif
kill_server(MYSQL_KILL_SIGNAL);
return 0;
}
-int __stdcall handle_kill(ulong ctrl_type)
+int STDCALL handle_kill(ulong ctrl_type)
{
if (ctrl_type == CTRL_CLOSE_EVENT ||
ctrl_type == CTRL_SHUTDOWN_EVENT)
@@ -1605,8 +1917,9 @@ int __stdcall handle_kill(ulong ctrl_type)
#endif
#ifdef OS2
-pthread_handler_decl(handle_shutdown,arg)
+extern "C" pthread_handler_decl(handle_shutdown,arg)
{
+ SHUTDOWN_THD;
my_thread_init();
// wait semaphore
@@ -1615,8 +1928,10 @@ pthread_handler_decl(handle_shutdown,arg)
// close semaphore and kill server
pthread_cond_destroy( &eventShutdown);
- // exit main loop on main thread, so kill will be done from
- // main thread (this is thread 2)
+ /*
+ Exit main loop on main thread, so kill will be done from
+ main thread (this is thread 2)
+ */
abort_loop = 1;
// unblock select()
@@ -1627,38 +1942,37 @@ pthread_handler_decl(handle_shutdown,arg)
}
#endif
-const char *load_default_groups[]= { "mysqld","server",0 };
-#ifdef HAVE_LIBWRAP
-char *libwrapName=NULL;
-#endif
+const char *load_default_groups[]= { "mysqld","server",MYSQL_BASE_VERSION,0,0};
-static void open_log(MYSQL_LOG *log, const char *hostname,
- const char *opt_name, const char *extension,
- enum_log_type type)
+bool open_log(MYSQL_LOG *log, const char *hostname,
+ const char *opt_name, const char *extension,
+ const char *index_file_name,
+ enum_log_type type, bool read_append,
+ bool no_auto_events, ulong max_size)
{
char tmp[FN_REFLEN];
if (!opt_name || !opt_name[0])
{
- /* TODO: The following should be using fn_format(); We just need to
- first change fn_format() to cut the file name if it's too long.
+ /*
+ TODO: The following should be using fn_format(); We just need to
+ first change fn_format() to cut the file name if it's too long.
*/
strmake(tmp,hostname,FN_REFLEN-5);
- strmov(strcend(tmp,'.'),extension);
+ strmov(fn_ext(tmp),extension);
opt_name=tmp;
}
- // get rid of extention if the log is binary to avoid problems
+ // get rid of extension if the log is binary to avoid problems
if (type == LOG_BIN)
{
char *p = fn_ext(opt_name);
- if (p)
- {
- uint length=(uint) (p-opt_name);
- strmake(tmp,opt_name,min(length,FN_REFLEN));
- opt_name=tmp;
- }
+ uint length=(uint) (p-opt_name);
+ strmake(tmp,opt_name,min(length,FN_REFLEN));
+ opt_name=tmp;
}
- log->open(opt_name,type);
+ return log->open(opt_name, type, 0, index_file_name,
+ (read_append) ? SEQ_READ_APPEND : WRITE_CACHE,
+ no_auto_events, max_size);
}
@@ -1673,10 +1987,19 @@ int main(int argc, char **argv)
my_umask=0660; // Default umask for new files
my_umask_dir=0700; // Default umask for new directories
+ MAIN_THD;
+ /*
+ Initialize signal_th and shutdown_th to main_th for default value
+ as we need to initialize them to something safe. They are used
+ when compiled with safemalloc.
+ */
+ SIGNAL_THD;
+ SHUTDOWN_THD;
MY_INIT(argv[0]); // init my_sys library & pthreads
tzset(); // Set tzname
start_time=time((time_t*) 0);
+
#ifdef OS2
{
// fix timezone for daylight saving
@@ -1686,25 +2009,28 @@ int main(int argc, char **argv)
}
#endif
#ifdef HAVE_TZNAME
-#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
{
struct tm tm_tmp;
localtime_r(&start_time,&tm_tmp);
strmov(time_zone,tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]);
}
-#else
- {
- struct tm *start_tm;
- start_tm=localtime(&start_time);
- strmov(time_zone,tzname[start_tm->tm_isdst != 0 ? 1 : 0]);
- }
-#endif
#endif
+ /*
+ Init mutexes for the global MYSQL_LOG objects.
+ As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
+ global MYSQL_LOGs in their constructors, because then they would be inited
+ before MY_INIT(). So we do it here.
+ */
+ mysql_log.init_pthread_objects();
+ mysql_update_log.init_pthread_objects();
+ mysql_slow_log.init_pthread_objects();
+ mysql_bin_log.init_pthread_objects();
+
if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
strmov(glob_hostname,"mysql");
strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
- strmov(strcend(pidfile_name,'.'),".pid"); // Add extension
+ strmov(fn_ext(pidfile_name),".pid"); // Add proper extension
#ifndef DBUG_OFF
strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS);
#else
@@ -1719,15 +2045,17 @@ int main(int argc, char **argv)
#endif
load_defaults(MYSQL_CONFIG_NAME,load_default_groups,&argc,&argv);
defaults_argv=argv;
- mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
+
+ /* Get default temporary directory */
+ opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
#if defined( __WIN__) || defined(OS2)
- if (!mysql_tmpdir)
- mysql_tmpdir=getenv("TEMP");
- if (!mysql_tmpdir)
- mysql_tmpdir=getenv("TMP");
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TEMP");
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir=getenv("TMP");
#endif
- if (!mysql_tmpdir || !mysql_tmpdir[0])
- mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
+ if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
+ opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
set_options();
get_options(argc,argv);
@@ -1753,33 +2081,44 @@ int main(int argc, char **argv)
(void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
- (void) pthread_mutex_init(&LOCK_timezone,MY_MUTEX_INIT_FAST);
- (void) pthread_mutex_init(&LOCK_binlog_update, MY_MUTEX_INIT_FAST); // QQ NOT USED
- (void) pthread_mutex_init(&LOCK_slave, MY_MUTEX_INIT_FAST);
- (void) pthread_mutex_init(&LOCK_server_id, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
(void) pthread_cond_init(&COND_thread_count,NULL);
(void) pthread_cond_init(&COND_refresh,NULL);
(void) pthread_cond_init(&COND_thread_cache,NULL);
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
(void) pthread_cond_init(&COND_manager,NULL);
- (void) pthread_cond_init(&COND_binlog_update, NULL);
- (void) pthread_cond_init(&COND_slave_stopped, NULL);
- (void) pthread_cond_init(&COND_slave_start, NULL);
+ (void) pthread_cond_init(&COND_rpl_status, NULL);
init_signals();
- if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
- unireg_abort(1);
+ if (set_default_charset_by_name(sys_charset.value, MYF(MY_WME)))
+ exit(1);
charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS));
+ /*
+ Ensure that lower_case_table_names is set on system where we have case
+ insensitive names. If this is not done the users MyISAM tables will
+ get corrupted if accesses with names of different case.
+ */
+ if (!lower_case_table_names &&
+ test_if_case_insensitive(mysql_real_data_home) == 1)
+ {
+ sql_print_error("Warning: Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home);
+ lower_case_table_names= 2;
+ }
+
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
{
- ssl_acceptor_fd = VioSSLAcceptorFd_new(opt_ssl_key, opt_ssl_cert,
- opt_ssl_ca, opt_ssl_capath);
+ /* having ssl_acceptor_fd != 0 signals the use of SSL */
+ ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
+ opt_ssl_ca, opt_ssl_capath,
+ opt_ssl_cipher);
+ DBUG_PRINT("info",("ssl_acceptor_fd: %lx", (long) ssl_acceptor_fd));
if (!ssl_acceptor_fd)
- opt_use_ssl=0;
- /* having ssl_acceptor_fd!=0 signals the use of SSL */
+ opt_use_ssl = 0;
}
#endif /* HAVE_OPENSSL */
@@ -1795,13 +2134,27 @@ int main(int argc, char **argv)
(void) pthread_attr_setdetachstate(&connection_attrib,
PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&connection_attrib,thread_stack);
-
+#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
+ {
+ /* Retrieve used stack size; Needed for checking stack overflows */
+ size_t stack_size= 0;
+ pthread_attr_getstacksize(&connection_attrib, &stack_size);
+ /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
+ if (stack_size && stack_size < thread_stack)
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_error("Warning: Asked for %ld thread stack, but got %ld",
+ thread_stack, stack_size);
+ thread_stack= stack_size;
+ }
+ }
+#endif
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR);
pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
- /* connections and databases neads lots of files */
+ /* connections and databases needs lots of files */
{
uint wanted_files=10+(uint) max(max_connections*5,
max_connections+table_cache_size*2);
@@ -1817,12 +2170,16 @@ int main(int argc, char **argv)
max_connections,table_cache_size));
sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size);
}
+ open_files_limit= files;
}
+#else
+ open_files_limit= 0; /* Can't set or detect limit */
#endif
unireg_init(opt_specialflag); /* Set up extern variabels */
init_errmessage(); /* Read error messages from file */
lex_init();
item_init();
+ set_var_init();
mysys_uses_curses=0;
#ifdef USE_REGEX
regex_init();
@@ -1833,101 +2190,67 @@ int main(int argc, char **argv)
unireg_abort(1);
/*
- ** We have enough space for fiddling with the argv, continue
+ We have enough space for fiddling with the argv, continue
*/
umask(((~my_umask) & 0666));
+ check_data_home(mysql_real_data_home);
if (my_setwd(mysql_real_data_home,MYF(MY_WME)))
{
unireg_abort(1); /* purecov: inspected */
}
+ mysql_data_home= mysql_data_home_buff;
mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
mysql_data_home[1]=0;
server_init();
table_cache_init();
hostname_cache_init();
- sql_cache_init();
+ query_cache_result_size_limit(query_cache_limit);
+ query_cache_resize(query_cache_size);
randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
reset_floating_point_exceptions();
init_thr_lock();
-
- /* Fix varibles that are base 1024*1024 */
- myisam_max_temp_length= (my_off_t) min(((ulonglong) myisam_max_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE);
- myisam_max_extra_temp_length= (my_off_t) min(((ulonglong) myisam_max_extra_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE);
+ init_slave_list();
+#ifdef HAVE_OPENSSL
+ if (des_key_file)
+ load_des_key_file(des_key_file);
+#endif /* HAVE_OPENSSL */
/* Setup log files */
if (opt_log)
- open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL);
+ open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS,
+ LOG_NORMAL, 0, 0, 0);
if (opt_update_log)
{
open_log(&mysql_update_log, glob_hostname, opt_update_logname, "",
- LOG_NEW);
+ NullS, LOG_NEW, 0, 0, 0);
using_update_log=1;
}
+
+ if (opt_slow_log)
+ open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
+ NullS, LOG_NORMAL, 0, 0, 0);
- //make sure slave thread gets started
- // if server_id is set, valid master.info is present, and master_host has
- // not been specified
- if(server_id && !master_host)
- {
- char fname[FN_REFLEN+128];
- MY_STAT stat_area;
- fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
- if(my_stat(fname, &stat_area, MYF(0)) && !init_master_info(&glob_mi))
- master_host = glob_mi.host;
- }
-
- if (opt_bin_log && !server_id)
- {
- server_id= !master_host ? 1 : 2;
- switch (server_id) {
-#ifdef EXTRA_DEBUG
- case 1:
- sql_print_error("\
-Warning: You have enabled the binary log, but you haven't set server-id:\n\
-Updates will be logged to the binary log, but connections to slaves will\n\
-not be accepted.");
- break;
-#endif
- case 2:
- sql_print_error("\
-Warning: You should set server-id to a non-0 value if master_host is set.\n\
-The server will not act as a slave.");
- break;
- }
- }
- if (opt_bin_log)
+ if (opt_error_log)
{
- if (!opt_bin_logname)
+ if (!log_error_file_ptr[0])
+ fn_format(log_error_file, glob_hostname, mysql_data_home, ".err", 0);
+ else
+ fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
+ MY_UNPACK_FILENAME | MY_SAFE_PATH);
+ if (!log_error_file[0])
+ opt_error_log= 1; // Too long file name
+ else
{
- char tmp[FN_REFLEN];
- /* TODO: The following should be using fn_format(); We just need to
- first change fn_format() to cut the file name if it's too long.
- */
- strmake(tmp,glob_hostname,FN_REFLEN-5);
- strmov(strcend(tmp,'.'),"-bin");
- opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
+ if (freopen(log_error_file, "a+", stdout))
+ freopen(log_error_file, "a+", stderr);
}
- mysql_bin_log.set_index_file_name(opt_binlog_index_name);
- open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
- LOG_BIN);
- using_update_log=1;
}
-
- if (opt_slow_log)
- open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
- LOG_NORMAL);
-#ifdef __WIN__
-#define MYSQL_ERR_FILE "mysql.err"
- if (!opt_console)
- {
- freopen(MYSQL_ERR_FILE,"a+",stdout);
- freopen(MYSQL_ERR_FILE,"a+",stderr);
- }
-#endif
if (ha_init())
{
sql_print_error("Can't init databases");
- exit(1);
+ if (unix_sock != INVALID_SOCKET)
+ unlink(mysql_unix_port);
+ unireg_abort(1);
}
ha_key_cache();
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
@@ -1942,15 +2265,15 @@ The server will not act as a slave.");
}
#else
locked_in_memory=0;
-#endif
+#endif
if (opt_myisam_log)
- (void) mi_log( 1 );
- ft_init_stopwords(ft_precompiled_stopwords); /* SerG */
+ (void) mi_log(1);
+ ft_init_stopwords();
#ifdef __WIN__
if (!opt_console)
- FreeConsole(); // Remove window
+ FreeConsole(); // Remove window
#endif
/*
@@ -1962,45 +2285,90 @@ The server will not act as a slave.");
pthread_key_create(&THR_MALLOC,NULL))
{
sql_print_error("Can't create thread-keys");
- exit(1);
+ if (unix_sock != INVALID_SOCKET)
+ unlink(mysql_unix_port);
+ unireg_abort(1);
}
start_signal_handler(); // Creates pidfile
- if (acl_init(opt_noacl))
+ if (acl_init((THD*) 0, opt_noacl))
{
+ abort_loop=1;
select_thread_in_use=0;
- (void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL);
+#ifndef __NETWARE__
+ (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
+#endif /* __NETWARE__ */
#ifndef __WIN__
if (!opt_bootstrap)
- (void) my_delete(pidfile_name,MYF(MY_WME)); // Not neaded anymore
+ (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore
#endif
- exit(1);
+ if (unix_sock != INVALID_SOCKET)
+ unlink(mysql_unix_port);
+ unireg_abort(1);
}
if (!opt_noacl)
- (void) grant_init();
- if (max_user_connections)
- init_max_user_conn();
+ (void) grant_init((THD*) 0);
+ init_max_user_conn();
+ init_update_queries();
+ DBUG_ASSERT(current_thd == 0);
#ifdef HAVE_DLOPEN
if (!opt_noacl)
udf_init();
#endif
+ if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
+ opt_skip_slave_start= 1;
+ /* init_slave() must be called after the thread keys are created */
+ init_slave();
+
+ DBUG_ASSERT(current_thd == 0);
+ if (opt_bin_log && !server_id)
+ {
+ server_id= !master_host ? 1 : 2;
+ switch (server_id) {
+#ifdef EXTRA_DEBUG
+ case 1:
+ sql_print_error("\
+Warning: You have enabled the binary log, but you haven't set server-id:\n\
+Updates will be logged to the binary log, but connections to slaves will\n\
+not be accepted.");
+ break;
+#endif
+ case 2:
+ sql_print_error("\
+Warning: You should set server-id to a non-0 value if master_host is set.\n\
+The server will not act as a slave.");
+ break;
+ }
+ }
+ if (opt_bin_log)
+ {
+ open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
+ opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size);
+ using_update_log=1;
+ }
+ else if (opt_log_slave_updates)
+ {
+ sql_print_error("\
+Warning: you need to use --log-bin to make --log-slave-updates work. \
+Now disabling --log-slave-updates.");
+ }
if (opt_bootstrap)
{
int error=bootstrap(stdin);
- end_thr_alarm(); // Don't allow alarms
+ end_thr_alarm(1); // Don't allow alarms
unireg_abort(error ? 1 : 0);
}
if (opt_init_file)
{
if (read_init_file(opt_init_file))
{
- end_thr_alarm(); // Don't allow alarms
+ end_thr_alarm(1); // Don't allow alarms
unireg_abort(1);
}
}
(void) thr_setconcurrency(concurrency); // 10 by default
-#ifdef __WIN__ //IRENA
+#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY) //IRENA
{
hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
pthread_t hThread;
@@ -2031,18 +2399,9 @@ The server will not act as a slave.");
sql_print_error("Warning: Can't create thread to manage maintenance");
}
- // slave thread
- if (master_host)
- {
- pthread_t hThread;
- if (!opt_skip_slave_start &&
- pthread_create(&hThread, &connection_attrib, handle_slave, 0))
- sql_print_error("Warning: Can't create thread to handle slave");
- else if(opt_skip_slave_start)
- init_master_info(&glob_mi);
- }
-
- printf(ER(ER_READY),my_progname,server_version, mysql_unix_port, mysql_port);
+ printf(ER(ER_READY),my_progname,server_version,
+ ((unix_sock == INVALID_SOCKET) ? (char*) "" : mysql_unix_port),
+ mysql_port);
fflush(stdout);
#ifdef __NT__
@@ -2080,15 +2439,13 @@ The server will not act as a slave.");
}
}
while (handler_count > 0)
- {
pthread_cond_wait(&COND_handler_count,&LOCK_thread_count);
- }
}
pthread_mutex_unlock(&LOCK_thread_count);
}
#else
handle_connections_sockets(0);
-#ifdef EXTRA_DEBUG
+#ifdef EXTRA_DEBUG2
sql_print_error("Exiting main thread");
#endif
#endif /* __NT__ */
@@ -2098,49 +2455,63 @@ The server will not act as a slave.");
DBUG_PRINT("quit",("Exiting main thread"));
#ifndef __WIN__
-#ifdef EXTRA_DEBUG
+#ifdef EXTRA_DEBUG2
sql_print_error("Before Lock_thread_count");
#endif
(void) pthread_mutex_lock(&LOCK_thread_count);
+ DBUG_PRINT("quit", ("Got thread_count mutex"));
select_thread_in_use=0; // For close_connections
- (void) pthread_cond_broadcast(&COND_thread_count);
(void) pthread_mutex_unlock(&LOCK_thread_count);
-#ifdef EXTRA_DEBUG
+ (void) pthread_cond_broadcast(&COND_thread_count);
+#ifdef EXTRA_DEBUG2
sql_print_error("After lock_thread_count");
#endif
-#endif
+#endif /* __WIN__ */
/* Wait until cleanup is done */
(void) pthread_mutex_lock(&LOCK_thread_count);
while (!ready_to_exit)
- {
pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
- }
(void) pthread_mutex_unlock(&LOCK_thread_count);
-#ifdef __WIN__
- if (Service.IsNT())
- {
- if(start_mode)
- Service.Stop();
- else
+
+#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
+ if (Service.IsNT() && start_mode)
+ Service.Stop();
+ else
+ {
+ Service.SetShutdownEvent(0);
+ if (hEventShutdown)
+ CloseHandle(hEventShutdown);
+ }
+#endif
+#ifndef __NETWARE__
+ {
+ uint i;
+ /*
+ Wait up to 10 seconds for signal thread to die. We use this mainly to
+ avoid getting warnings that my_thread_end has not been called
+ */
+ for (i= 0 ; i < 100 && signal_thread_in_use; i++)
{
- Service.SetShutdownEvent(0);
- if(hEventShutdown) CloseHandle(hEventShutdown);
+ if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
+ break;
+ my_sleep(100); // Give it time to die
}
- }
- else
- {
- Service.SetShutdownEvent(0);
- if(hEventShutdown) CloseHandle(hEventShutdown);
- }
+ }
#endif
+ clean_up_mutexes();
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(0);
return(0); /* purecov: deadcode */
}
-#if defined(__WIN__)
+/****************************************************************************
+ Main and thread entry function for Win32
+ (all this is needed only to run mysqld as a service on WinNT)
+****************************************************************************/
+
+#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
int mysql_service(void *p)
{
if (use_opt_args)
@@ -2150,6 +2521,19 @@ int mysql_service(void *p)
return 0;
}
+
+/* Quote string if it contains space, else copy */
+
+static char *add_quoted_string(char *to, const char *from, char *to_end)
+{
+ uint length= (uint) (to_end-to);
+
+ if (!strchr(from, ' '))
+ return strnmov(to, from, length);
+ return strxnmov(to, length, "\"", from, "\"", NullS);
+}
+
+
/*
Handle basic handling of services, like installation and removal
@@ -2159,25 +2543,43 @@ int mysql_service(void *p)
servicename Internal name of service
displayname Display name of service (in taskbar ?)
file_path Path to this program
+ startup_option Startup option to mysqld
RETURN VALUES
0 option handled
1 Could not handle option
*/
-bool default_service_handling(char **argv,
- const char *servicename,
- const char *displayname,
- const char *file_path)
+static bool
+default_service_handling(char **argv,
+ const char *servicename,
+ const char *displayname,
+ const char *file_path,
+ const char *extra_opt)
{
+ char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
+ end= path_and_service + sizeof(path_and_service)-3;
+
+ /* We have to quote filename if it contains spaces */
+ pos= add_quoted_string(path_and_service, file_path, end);
+ if (*extra_opt)
+ {
+ /* Add (possible quoted) option after file_path */
+ *pos++= ' ';
+ pos= add_quoted_string(pos, extra_opt, end);
+ }
+ /* We must have servicename last */
+ *pos++= ' ';
+ (void) add_quoted_string(pos, servicename, end);
+
if (Service.got_service_option(argv, "install"))
{
- Service.Install(1, servicename, displayname, file_path);
+ Service.Install(1, servicename, displayname, path_and_service);
return 0;
}
if (Service.got_service_option(argv, "install-manual"))
{
- Service.Install(0, servicename, displayname, file_path);
+ Service.Install(0, servicename, displayname, path_and_service);
return 0;
}
if (Service.got_service_option(argv, "remove"))
@@ -2203,17 +2605,23 @@ int main(int argc, char **argv)
{
char file_path[FN_REFLEN];
my_path(file_path, argv[0], ""); /* Find name in path */
- fn_format(file_path,argv[0],file_path,"",1+4+16); /* Force full path */
-
+ fn_format(file_path,argv[0],file_path,"",
+ MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
if (argc == 2)
{
- if (!default_service_handling(argv,MYSQL_SERVICENAME, MYSQL_SERVICENAME,
- file_path))
+ if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
+ file_path, ""))
return 0;
- if (Service.IsService(argv[1]))
+ if (Service.IsService(argv[1])) /* Start an optional service */
{
- /* start an optional service */
- load_default_groups[0]= argv[1];
+ /*
+ Only add the service name to the groups read from the config file
+ if it's not "MySQL". (The default service name should be 'mysqld'
+ but we started a bad tradition by calling it MySQL from the start
+ and we are now stuck with it.
+ */
+ if (my_strcasecmp(argv[1],"mysql"))
+ load_default_groups[3]= argv[1];
start_mode= 1;
Service.Init(argv[1], mysql_service);
return 0;
@@ -2221,12 +2629,7 @@ int main(int argc, char **argv)
}
else if (argc == 3) /* install or remove any optional service */
{
- /* Add service name after filename */
- uint length=strlen(file_path);
- *strxnmov(file_path + length, sizeof(file_path)-length-2, " ",
- argv[2], NullS)= '\0';
-
- if (!default_service_handling(argv, argv[2], argv[2], file_path))
+ if (!default_service_handling(argv, argv[2], argv[2], file_path, ""))
return 0;
if (Service.IsService(argv[2]))
{
@@ -2238,6 +2641,8 @@ int main(int argc, char **argv)
opt_argc= 2; // Skip service-name
opt_argv=argv;
start_mode= 1;
+ if (my_strcasecmp(argv[2],"mysql"))
+ load_default_groups[3]= argv[2];
Service.Init(argv[2], mysql_service);
return 0;
}
@@ -2248,10 +2653,8 @@ int main(int argc, char **argv)
Install an optional service with optional config file
mysqld --install-manual mysqldopt --defaults-file=c:\miguel\my.ini
*/
- uint length=strlen(file_path);
- *strxnmov(file_path + length, sizeof(file_path)-length-2, " ",
- argv[3], " ", argv[2], NullS)= '\0';
- if (!default_service_handling(argv, argv[2], argv[2], file_path))
+ if (!default_service_handling(argv, argv[2], argv[2], file_path,
+ argv[3]))
return 0;
}
else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
@@ -2271,14 +2674,21 @@ int main(int argc, char **argv)
#endif
+/*
+ Execute all commands from a file. Used by the mysql_install_db script to
+ create MySQL privilege tables without having to start a full MySQL server.
+*/
+
static int bootstrap(FILE *file)
{
THD *thd= new THD;
int error;
+ DBUG_ENTER("bootstrap");
+
thd->bootstrap=1;
thd->client_capabilities=0;
- my_net_init(&thd->net,(Vio*) 0);
- thd->max_packet_length=thd->net.max_packet;
+ my_net_init(&thd->net,(st_vio*) 0);
+ thd->max_client_packet_length= thd->net.max_packet;
thd->master_access= ~0;
thd->thread_id=thread_id++;
thread_count++;
@@ -2288,7 +2698,7 @@ static int bootstrap(FILE *file)
(void*) thd))
{
sql_print_error("Warning: Can't create thread to handle bootstrap");
- return -1;
+ DBUG_RETURN(-1);
}
/* Wait for thread to die */
(void) pthread_mutex_lock(&LOCK_thread_count);
@@ -2302,7 +2712,7 @@ static int bootstrap(FILE *file)
net_end(&thd->net);
thd->cleanup();
delete thd;
- return error;
+ DBUG_RETURN(error);
}
static bool read_init_file(char *file_name)
@@ -2323,7 +2733,7 @@ static void create_new_thread(THD *thd)
DBUG_ENTER("create_new_thread");
NET *net=&thd->net; // For easy ref
- net->timeout = (uint) connect_timeout; // Timeout for read
+ net->read_timeout = (uint) connect_timeout;
if (protocol_version > 9)
net->return_errno=1;
@@ -2335,18 +2745,12 @@ static void create_new_thread(THD *thd)
delete thd;
DBUG_VOID_RETURN;
}
- if (pthread_mutex_lock(&LOCK_thread_count))
- {
- DBUG_PRINT("error",("Can't lock LOCK_thread_count"));
- close_connection(net,ER_OUT_OF_RESOURCES);
- delete thd;
- DBUG_VOID_RETURN;
- }
+ pthread_mutex_lock(&LOCK_thread_count);
if (thread_count-delayed_insert_threads > max_used_connections)
max_used_connections=thread_count-delayed_insert_threads;
thd->thread_id=thread_id++;
for (uint i=0; i < 8 ; i++) // Generate password teststring
- thd->scramble[i]= (char) (rnd(&sql_rand)*94+33);
+ thd->scramble[i]= (char) (my_rnd(&sql_rand)*94+33);
thd->scramble[8]=0;
thd->real_id=pthread_self(); // Keep purify happy
@@ -2387,6 +2791,7 @@ static void create_new_thread(THD *thd)
thread_count--;
thd->killed=1; // Safety
(void) pthread_mutex_unlock(&LOCK_thread_count);
+ statistic_increment(aborted_connects,&LOCK_status);
net_printf(net,ER_CANT_CREATE_THREAD,error);
(void) pthread_mutex_lock(&LOCK_thread_count);
close_connection(net,0,0);
@@ -2402,10 +2807,33 @@ static void create_new_thread(THD *thd)
DBUG_VOID_RETURN;
}
+#ifdef SIGNALS_DONT_BREAK_READ
+inline void kill_broken_server()
+{
+ /* hack to get around signals ignored in syscalls for problem OS's */
+ if (
+#if !defined(__NETWARE__)
+ unix_sock == INVALID_SOCKET ||
+#endif
+ (!opt_disable_networking && ip_sock == INVALID_SOCKET))
+ {
+ select_thread_in_use = 0;
+#ifdef __NETWARE__
+ kill_server(MYSQL_KILL_SIGNAL); /* never returns */
+#else
+ kill_server((void*)MYSQL_KILL_SIGNAL); /* never returns */
+#endif /* __NETWARE__ */
+ }
+}
+#define MAYBE_BROKEN_SYSCALL kill_broken_server();
+#else
+#define MAYBE_BROKEN_SYSCALL
+#endif
/* Handle new connections and spawn new process to handle them */
-pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
+extern "C" pthread_handler_decl(handle_connections_sockets,
+ arg __attribute__((unused)))
{
my_socket sock,new_sock;
uint error_count=0;
@@ -2414,7 +2842,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
THD *thd;
struct sockaddr_in cAddr;
int ip_flags=0,socket_flags=0,flags;
- Vio *vio_tmp;
+ st_vio *vio_tmp;
DBUG_ENTER("handle_connections_sockets");
LINT_INIT(new_sock);
@@ -2441,7 +2869,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
while (!abort_loop)
{
readFDs=clientFDs;
-#ifdef HPUX
+#ifdef HPUX10
if (select(max_used_connection,(int*) &readFDs,0,0,0) < 0)
continue;
#else
@@ -2452,17 +2880,17 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
if (!select_errors++ && !abort_loop) /* purecov: inspected */
sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
}
- MAYBE_BROKEN_SYSCALL;
+ MAYBE_BROKEN_SYSCALL
continue;
}
-#endif /* HPUX */
+#endif /* HPUX10 */
if (abort_loop)
+ {
+ MAYBE_BROKEN_SYSCALL;
break;
+ }
- /*
- ** Is this a new connection request
- */
-
+ /* Is this a new connection request ? */
#ifdef HAVE_SYS_UN_H
if (FD_ISSET(unix_sock,&readFDs))
{
@@ -2491,6 +2919,13 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
size_socket length=sizeof(struct sockaddr_in);
new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr),
&length);
+#ifdef __NETWARE__
+ // TODO: temporary fix, waiting for TCP/IP fix - DEFECT000303149
+ if ((new_sock == INVALID_SOCKET) && (socket_errno == EINVAL))
+ {
+ kill_server(SIGTERM);
+ }
+#endif
if (new_sock != INVALID_SOCKET ||
(socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
break;
@@ -2571,7 +3006,8 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
if (!(thd= new THD))
{
- (void) shutdown(new_sock,2); VOID(closesocket(new_sock));
+ (void) shutdown(new_sock,2);
+ VOID(closesocket(new_sock));
continue;
}
if (!(vio_tmp=vio_new(new_sock,
@@ -2592,6 +3028,12 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
}
if (sock == unix_sock)
thd->host=(char*) localhost;
+#ifdef __WIN__
+ /* Set default wait_timeout */
+ ulong wait_timeout= global_system_variables.net_wait_timeout * 1000;
+ (void) setsockopt(new_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&wait_timeout,
+ sizeof(wait_timeout));
+#endif
create_new_thread(thd);
}
@@ -2611,7 +3053,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
#ifdef __NT__
-pthread_handler_decl(handle_connections_namedpipes,arg)
+extern "C" pthread_handler_decl(handle_connections_namedpipes,arg)
{
HANDLE hConnectedPipe;
BOOL fConnected;
@@ -2638,8 +3080,8 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
PIPE_READMODE_BYTE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
- (int) net_buffer_length,
- (int) net_buffer_length,
+ (int) global_system_variables.net_buffer_length,
+ (int) global_system_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity )) ==
INVALID_HANDLE_VALUE )
@@ -2656,8 +3098,8 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
PIPE_READMODE_BYTE |
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
- (int) net_buffer_length,
- (int) net_buffer_length,
+ (int) global_system_variables.net_buffer_length,
+ (int) global_system_variables.net_buffer_length,
NMPWAIT_USE_DEFAULT_WAIT,
&saPipeSecurity)) ==
INVALID_HANDLE_VALUE)
@@ -2687,8 +3129,8 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
pthread_mutex_lock(&LOCK_thread_count);
handler_count--;
- pthread_cond_signal(&COND_handler_count);
pthread_mutex_unlock(&LOCK_thread_count);
+ pthread_cond_signal(&COND_handler_count);
DBUG_RETURN(0);
}
#endif /* __NT__ */
@@ -2698,511 +3140,980 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
** handle start options
******************************************************************************/
-enum options {
- OPT_ISAM_LOG=256, OPT_SKIP_NEW,
- OPT_SKIP_GRANT, OPT_SKIP_LOCK,
- OPT_ENABLE_LOCK, OPT_USE_LOCKING,
- OPT_SOCKET, OPT_UPDATE_LOG,
- OPT_BIN_LOG, OPT_SKIP_RESOLVE,
- OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX,
- OPT_BIND_ADDRESS, OPT_PID_FILE,
- OPT_SKIP_PRIOR, OPT_BIG_TABLES,
- OPT_STANDALONE, OPT_ONE_THREAD,
- OPT_CONSOLE, OPT_LOW_PRIORITY_UPDATES,
- OPT_SKIP_HOST_CACHE, OPT_LONG_FORMAT,
- OPT_FLUSH, OPT_SAFE,
- OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB,
- OPT_TABLE_TYPE, OPT_INIT_FILE,
- OPT_DELAY_KEY_WRITE, OPT_SLOW_QUERY_LOG,
- OPT_SKIP_DELAY_KEY_WRITE, OPT_CHARSETS_DIR,
- OPT_BDB_HOME, OPT_BDB_LOG,
- OPT_BDB_TMP, OPT_BDB_NOSYNC,
- OPT_BDB_LOCK, OPT_BDB_SKIP,
- OPT_BDB_NO_RECOVER, OPT_BDB_SHARED,
- OPT_MASTER_HOST, OPT_MASTER_USER,
- OPT_MASTER_PASSWORD, OPT_MASTER_PORT,
- OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY,
- OPT_MASTER_RETRY_COUNT,
- OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
- OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
- OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
- OPT_WANT_CORE, OPT_SKIP_CONCURRENT_INSERT,
- OPT_MEMLOCK, OPT_MYISAM_RECOVER,
- OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID,
- OPT_SKIP_SLAVE_START, OPT_SKIP_INNOBASE,
- OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE,
- OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE,
- OPT_REPLICATE_WILD_IGNORE_TABLE,
- OPT_DISCONNECT_SLAVE_EVENT_COUNT,
- OPT_ABORT_SLAVE_EVENT_COUNT,
- OPT_INNODB_DATA_HOME_DIR,
- OPT_INNODB_DATA_FILE_PATH,
- OPT_INNODB_LOG_GROUP_HOME_DIR,
- OPT_INNODB_LOG_ARCH_DIR,
- OPT_INNODB_LOG_ARCHIVE,
- OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
- OPT_INNODB_FAST_SHUTDOWN,
- OPT_INNODB_UNIX_FILE_FLUSH_METHOD,
- OPT_SAFE_SHOW_DB,
- OPT_GEMINI_SKIP, OPT_INNODB_SKIP,
- OPT_TEMP_POOL, OPT_TX_ISOLATION,
- OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER,
- OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC,
- OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
- OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
- OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
- OPT_HAVE_NAMED_PIPE,
- OPT_SLAVE_SKIP_ERRORS, OPT_LOCAL_INFILE
+enum options_mysqld {
+ OPT_ISAM_LOG=256, OPT_SKIP_NEW,
+ OPT_SKIP_GRANT, OPT_SKIP_LOCK,
+ OPT_ENABLE_LOCK, OPT_USE_LOCKING,
+ OPT_SOCKET, OPT_UPDATE_LOG,
+ OPT_BIN_LOG, OPT_SKIP_RESOLVE,
+ OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX,
+ OPT_BIND_ADDRESS, OPT_PID_FILE,
+ OPT_SKIP_PRIOR, OPT_BIG_TABLES,
+ OPT_STANDALONE, OPT_ONE_THREAD,
+ OPT_CONSOLE, OPT_LOW_PRIORITY_UPDATES,
+ OPT_SKIP_HOST_CACHE, OPT_LONG_FORMAT,
+ OPT_FLUSH, OPT_SAFE,
+ OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB,
+ OPT_TABLE_TYPE, OPT_INIT_FILE,
+ OPT_DELAY_KEY_WRITE_ALL, OPT_SLOW_QUERY_LOG,
+ OPT_DELAY_KEY_WRITE, OPT_CHARSETS_DIR,
+ OPT_BDB_HOME, OPT_BDB_LOG,
+ OPT_BDB_TMP, OPT_BDB_SYNC,
+ OPT_BDB_LOCK, OPT_BDB_SKIP,
+ OPT_BDB_NO_RECOVER, OPT_BDB_SHARED,
+ OPT_MASTER_HOST, OPT_MASTER_USER,
+ OPT_MASTER_PASSWORD, OPT_MASTER_PORT,
+ OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY,
+ OPT_MASTER_RETRY_COUNT,
+ OPT_MASTER_SSL, OPT_MASTER_SSL_KEY,
+ OPT_MASTER_SSL_CERT, OPT_MASTER_SSL_CAPATH,
+ OPT_MASTER_SSL_CIPHER,
+ OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
+ OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
+ OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
+ OPT_WANT_CORE, OPT_CONCURRENT_INSERT,
+ OPT_MEMLOCK, OPT_MYISAM_RECOVER,
+ OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID,
+ OPT_SKIP_SLAVE_START, OPT_SKIP_INNOBASE,
+ OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE,
+ OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE,
+ OPT_REPLICATE_WILD_IGNORE_TABLE,
+ OPT_DISCONNECT_SLAVE_EVENT_COUNT,
+ OPT_ABORT_SLAVE_EVENT_COUNT,
+ OPT_INNODB_DATA_HOME_DIR,
+ OPT_INNODB_DATA_FILE_PATH,
+ OPT_INNODB_LOG_GROUP_HOME_DIR,
+ OPT_INNODB_LOG_ARCH_DIR,
+ OPT_INNODB_LOG_ARCHIVE,
+ OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
+ OPT_INNODB_FLUSH_METHOD,
+ OPT_INNODB_FAST_SHUTDOWN,
+ OPT_SAFE_SHOW_DB,
+ OPT_INNODB_SKIP, OPT_SKIP_SAFEMALLOC,
+ OPT_TEMP_POOL, OPT_TX_ISOLATION,
+ OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
+ OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
+ OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
+ OPT_HAVE_NAMED_PIPE,
+ OPT_DO_PSTACK, OPT_REPORT_HOST,
+ OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
+ OPT_SHOW_SLAVE_AUTH_INFO,
+ OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
+ OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
+ OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
+ OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE,
+ OPT_RECKLESS_SLAVE,
+ OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA,
+ OPT_SSL_CAPATH, OPT_SSL_CIPHER,
+ OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
+ OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT,
+ OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE,
+ OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN,
+ OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT, OPT_FT_STOPWORD_FILE,
+ OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
+ OPT_KEY_BUFFER_SIZE, OPT_LONG_QUERY_TIME,
+ OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
+ OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
+ OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
+ OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE,
+ OPT_MAX_JOIN_SIZE, OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH,
+ OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
+ OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
+ OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
+ OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
+ OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
+ OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
+ OPT_OPEN_FILES_LIMIT,
+ OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_SIZE,
+ OPT_QUERY_CACHE_TYPE, OPT_RECORD_BUFFER,
+ OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT,
+ OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME,
+ OPT_READONLY, OPT_DEBUGGING,
+ OPT_SORT_BUFFER, OPT_TABLE_CACHE,
+ OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
+ OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
+ OPT_WAIT_TIMEOUT, OPT_MYISAM_REPAIR_THREADS,
+ OPT_INNODB_MIRRORED_LOG_GROUPS,
+ OPT_INNODB_LOG_FILES_IN_GROUP,
+ OPT_INNODB_LOG_FILE_SIZE,
+ OPT_INNODB_LOG_BUFFER_SIZE,
+ OPT_INNODB_BUFFER_POOL_SIZE,
+ OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE,
+ OPT_INNODB_FILE_IO_THREADS,
+ OPT_INNODB_LOCK_WAIT_TIMEOUT,
+ OPT_INNODB_THREAD_CONCURRENCY,
+ OPT_INNODB_FORCE_RECOVERY,
+ OPT_INNODB_MAX_DIRTY_PAGES_PCT,
+ OPT_BDB_CACHE_SIZE,
+ OPT_BDB_LOG_BUFFER_SIZE,
+ OPT_BDB_MAX_LOCK,
+ OPT_ERROR_LOG_FILE,
+ OPT_DEFAULT_WEEK_FORMAT,
+ OPT_RANGE_ALLOC_BLOCK_SIZE,
+ OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
+ OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
+ OPT_SYNC_FRM, OPT_BDB_NOSYNC
};
-static struct option long_options[] = {
- {"ansi", no_argument, 0, 'a'},
- {"basedir", required_argument, 0, 'b'},
+
+#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
+
+struct my_option my_long_options[] =
+{
+ {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"basedir", 'b',
+ "Path to installation directory. All paths are usually resolved relative to this.",
+ (gptr*) &mysql_home_ptr, (gptr*) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
#ifdef HAVE_BERKELEY_DB
- {"bdb-home", required_argument, 0, (int) OPT_BDB_HOME},
- {"bdb-lock-detect", required_argument, 0, (int) OPT_BDB_LOCK},
- {"bdb-logdir", required_argument, 0, (int) OPT_BDB_LOG},
- {"bdb-no-recover", no_argument, 0, (int) OPT_BDB_NO_RECOVER},
- {"bdb-no-sync", no_argument, 0, (int) OPT_BDB_NOSYNC},
- {"bdb-shared-data", no_argument, 0, (int) OPT_BDB_SHARED},
- {"bdb-tmpdir", required_argument, 0, (int) OPT_BDB_TMP},
-#endif
- {"big-tables", no_argument, 0, (int) OPT_BIG_TABLES},
- {"binlog-do-db", required_argument, 0, (int) OPT_BINLOG_DO_DB},
- {"binlog-ignore-db", required_argument, 0, (int) OPT_BINLOG_IGNORE_DB},
- {"bind-address", required_argument, 0, (int) OPT_BIND_ADDRESS},
- {"bootstrap", no_argument, 0, (int) OPT_BOOTSTRAP},
+ {"bdb-home", OPT_BDB_HOME, "Berkeley home directory", (gptr*) &berkeley_home,
+ (gptr*) &berkeley_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bdb-lock-detect", OPT_BDB_LOCK,
+ "Berkeley lock detect (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec)",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bdb-logdir", OPT_BDB_LOG, "Berkeley DB log file directory",
+ (gptr*) &berkeley_logdir, (gptr*) &berkeley_logdir, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bdb-no-recover", OPT_BDB_NO_RECOVER,
+ "Don't try to recover Berkeley DB tables on start", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"bdb-no-sync", OPT_BDB_NOSYNC,
+ "Disable synchronously flushing logs. This option is deprecated, use --skip-sync-bdb-logs or sync-bdb-logs=0 instead",
+ // (gptr*) &opt_sync_bdb_logs, (gptr*) &opt_sync_bdb_logs, 0, GET_BOOL,
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sync-bdb-logs", OPT_BDB_SYNC,
+ "Synchronously flush logs. Enabled by default",
+ (gptr*) &opt_sync_bdb_logs, (gptr*) &opt_sync_bdb_logs, 0, GET_BOOL,
+ NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"bdb-shared-data", OPT_BDB_SHARED,
+ "Start Berkeley DB in multi-process mode", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"bdb-tmpdir", OPT_BDB_TMP, "Berkeley DB tempfile name",
+ (gptr*) &berkeley_tmpdir, (gptr*) &berkeley_tmpdir, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif /* HAVE_BERKELEY_DB */
+ {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default",
+ (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
+ 0, 0, 0, 0},
+ {"skip-bdb", OPT_BDB_SKIP, "Don't use berkeley db (will save memory)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"big-tables", OPT_BIG_TABLES,
+ "Allow big result sets by saving all temporary sets on file (Solves most 'table full' errors)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"binlog-do-db", OPT_BINLOG_DO_DB,
+ "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
+ "Tells the master that updates to the given database should not be logged tothe binary log",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to",
+ (gptr*) &my_bind_addr_str, (gptr*) &my_bind_addr_str, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"console", OPT_CONSOLE, "Write error output on screen; Don't remove the console window on windows",
+ (gptr*) &opt_console, (gptr*) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
#ifdef __WIN__
- {"console", no_argument, 0, (int) OPT_CONSOLE},
-#endif
- {"core-file", no_argument, 0, (int) OPT_WANT_CORE},
- {"chroot", required_argument, 0, 'r'},
- {"character-sets-dir", required_argument, 0, (int) OPT_CHARSETS_DIR},
- {"datadir", required_argument, 0, 'h'},
- {"debug", optional_argument, 0, '#'},
- {"default-character-set", required_argument, 0, 'C'},
- {"default-table-type", required_argument, 0, (int) OPT_TABLE_TYPE},
- {"delay-key-write-for-all-tables",
- no_argument, 0, (int) OPT_DELAY_KEY_WRITE},
- {"enable-locking", no_argument, 0, (int) OPT_ENABLE_LOCK},
- {"enable-named-pipe", no_argument, 0, (int) OPT_HAVE_NAMED_PIPE},
- {"exit-info", optional_argument, 0, 'T'},
- {"flush", no_argument, 0, (int) OPT_FLUSH},
-#ifdef HAVE_GEMINI_DB
- {"gemini-flush-log-at-commit",no_argument, 0, (int) OPT_GEMINI_FLUSH_LOG},
- {"gemini-recovery", required_argument, 0, (int) OPT_GEMINI_RECOVER},
- {"gemini-unbuffered-io", no_argument, 0, (int) OPT_GEMINI_UNBUFFERED_IO},
-#endif
- /* We must always support this option to make scripts like mysqltest easier
- to do */
- {"innodb_data_file_path", required_argument, 0,
- OPT_INNODB_DATA_FILE_PATH},
+ {"standalone", OPT_STANDALONE,
+ "Dummy option to start as a standalone program (NT)", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"core-file", OPT_WANT_CORE, "Write core on errors", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"chroot", 'r', "Chroot mysqld daemon during startup.",
+ (gptr*) &mysqld_chroot, (gptr*) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"character-sets-dir", OPT_CHARSETS_DIR,
+ "Directory where character sets are", (gptr*) &charsets_dir,
+ (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"datadir", 'h', "Path to the database root", (gptr*) &mysql_data_home,
+ (gptr*) &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef DBUG_OFF
+ {"debug", '#', "Debug log.", (gptr*) &default_dbug_option,
+ (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef SAFEMALLOC
+ {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
+ "Don't use the memory allocation checking", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
+#endif
+#ifdef HAVE_OPENSSL
+ {"des-key-file", OPT_DES_KEY_FILE,
+ "Load keys for des_encrypt() and des_encrypt from given file",
+ (gptr*) &des_key_file, (gptr*) &des_key_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif /* HAVE_OPENSSL */
+ {"default-character-set", 'C', "Set the default character set",
+ (gptr*) &sys_charset.value, (gptr*) &sys_charset.value, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ {"default-table-type", OPT_TABLE_TYPE,
+ "Set the default table type for tables", 0, 0,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"delay-key-write", OPT_DELAY_KEY_WRITE, "Type of DELAY_KEY_WRITE",
+ 0,0,0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE_ALL,
+ "Don't flush key buffers between writes for any MyISAM table (Deprecated option, use --delay-key-write=all instead)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"enable-locking", OPT_ENABLE_LOCK,
+ "Deprecated option, use --external-locking instead",
+ (gptr*) &opt_external_locking, (gptr*) &opt_external_locking,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef __NT__
+ {"enable-named-pipe", OPT_HAVE_NAMED_PIPE, "Enable the named pipe (NT)",
+ (gptr*) &opt_enable_named_pipe, (gptr*) &opt_enable_named_pipe, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure",
+ (gptr*) &opt_do_pstack, (gptr*) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0,
+ GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ /* We must always support the next option to make scripts like mysqltest
+ easier to do */
+ {"gdb", OPT_DEBUGGING,
+ "Set up signals usable for debugging",
+ (gptr*) &opt_debugging, (gptr*) &opt_debugging,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role", 0, 0, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH,
+ "Path to individual files and their sizes",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_INNOBASE_DB
- {"innodb_data_home_dir", required_argument, 0,
- OPT_INNODB_DATA_HOME_DIR},
- {"innodb_log_group_home_dir", required_argument, 0,
- OPT_INNODB_LOG_GROUP_HOME_DIR},
- {"innodb_log_arch_dir", required_argument, 0,
- OPT_INNODB_LOG_ARCH_DIR},
- {"innodb_log_archive", optional_argument, 0,
- OPT_INNODB_LOG_ARCHIVE},
- {"innodb_flush_log_at_trx_commit", optional_argument, 0,
- OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT},
- {"innodb_fast_shutdown", optional_argument, 0,
- OPT_INNODB_FAST_SHUTDOWN},
- {"innodb_flush_method", required_argument, 0,
- OPT_INNODB_UNIX_FILE_FLUSH_METHOD},
-#endif
- {"help", no_argument, 0, '?'},
- {"init-file", required_argument, 0, (int) OPT_INIT_FILE},
- {"log", optional_argument, 0, 'l'},
- {"language", required_argument, 0, 'L'},
- {"local-infile", optional_argument, 0, (int) OPT_LOCAL_INFILE},
- {"log-bin", optional_argument, 0, (int) OPT_BIN_LOG},
- {"log-bin-index", required_argument, 0, (int) OPT_BIN_LOG_INDEX},
- {"log-isam", optional_argument, 0, (int) OPT_ISAM_LOG},
- {"log-update", optional_argument, 0, (int) OPT_UPDATE_LOG},
- {"log-slow-queries", optional_argument, 0, (int) OPT_SLOW_QUERY_LOG},
- {"log-long-format", no_argument, 0, (int) OPT_LONG_FORMAT},
- {"log-slave-updates", no_argument, 0, (int) OPT_LOG_SLAVE_UPDATES},
- {"low-priority-updates", no_argument, 0, (int) OPT_LOW_PRIORITY_UPDATES},
- {"master-host", required_argument, 0, (int) OPT_MASTER_HOST},
- {"master-user", required_argument, 0, (int) OPT_MASTER_USER},
- {"master-password", required_argument, 0, (int) OPT_MASTER_PASSWORD},
- {"master-port", required_argument, 0, (int) OPT_MASTER_PORT},
- {"master-connect-retry", required_argument, 0, (int) OPT_MASTER_CONNECT_RETRY},
- {"master-retry-count", required_argument, 0, (int) OPT_MASTER_RETRY_COUNT},
- {"master-info-file", required_argument, 0, (int) OPT_MASTER_INFO_FILE},
- {"myisam-recover", optional_argument, 0, (int) OPT_MYISAM_RECOVER},
- {"memlock", no_argument, 0, (int) OPT_MEMLOCK},
- // needs to be available for the test case to pass in non-debugging mode
- // is a no-op
- {"disconnect-slave-event-count", required_argument, 0,
- (int) OPT_DISCONNECT_SLAVE_EVENT_COUNT},
- {"abort-slave-event-count", required_argument, 0,
- (int) OPT_ABORT_SLAVE_EVENT_COUNT},
- {"max-binlog-dump-events", required_argument, 0,
- (int) OPT_MAX_BINLOG_DUMP_EVENTS},
- {"sporadic-binlog-dump-fail", no_argument, 0,
- (int) OPT_SPORADIC_BINLOG_DUMP_FAIL},
- {"safemalloc-mem-limit", required_argument, 0, (int)
- OPT_SAFEMALLOC_MEM_LIMIT},
- {"new", no_argument, 0, 'n'},
- {"old-protocol", no_argument, 0, 'o'},
+ {"innodb_data_home_dir", OPT_INNODB_DATA_HOME_DIR,
+ "The common part for Innodb table spaces", (gptr*) &innobase_data_home_dir,
+ (gptr*) &innobase_data_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"innodb_log_group_home_dir", OPT_INNODB_LOG_GROUP_HOME_DIR,
+ "Path to innodb log files.", (gptr*) &innobase_log_group_home_dir,
+ (gptr*) &innobase_log_group_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR,
+ "Where full logs should be archived", (gptr*) &innobase_log_arch_dir,
+ (gptr*) &innobase_log_arch_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"innodb_log_archive", OPT_INNODB_LOG_ARCHIVE,
+ "Set to 1 if you want to have logs archived", 0, 0, 0, GET_LONG, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"innodb_flush_log_at_trx_commit", OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
+ "Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second)",
+ (gptr*) &innobase_flush_log_at_trx_commit,
+ (gptr*) &innobase_flush_log_at_trx_commit,
+ 0, GET_UINT, OPT_ARG, 1, 0, 2, 0, 0, 0},
+ {"innodb_flush_method", OPT_INNODB_FLUSH_METHOD,
+ "With which method to flush data", (gptr*) &innobase_unix_file_flush_method,
+ (gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"innodb_fast_shutdown", OPT_INNODB_FAST_SHUTDOWN,
+ "Speeds up server shutdown process", (gptr*) &innobase_fast_shutdown,
+ (gptr*) &innobase_fast_shutdown, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
+ {"innodb_max_dirty_pages_pct", OPT_INNODB_MAX_DIRTY_PAGES_PCT,
+ "Percentage of dirty pages allowed in bufferpool", (gptr*) &srv_max_buf_pool_modified_pct,
+ (gptr*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0},
+
+#endif /* End HAVE_INNOBASE_DB */
+ {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup",
+ (gptr*) &opt_init_file, (gptr*) &opt_init_file, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"log", 'l', "Log connections and queries to file", (gptr*) &opt_logname,
+ (gptr*) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"language", 'L',
+ "Client error messages in given language. May be given as a full path",
+ (gptr*) &language_ptr, (gptr*) &language_ptr, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"local-infile", OPT_LOCAL_INFILE,
+ "Enable/disable LOAD DATA LOCAL INFILE (takes values 1|0)",
+ (gptr*) &opt_local_infile,
+ (gptr*) &opt_local_infile, 0, GET_BOOL, OPT_ARG,
+ 1, 0, 0, 0, 0, 0},
+ {"log-bin", OPT_BIN_LOG,
+ "Log update queries in binary format",
+ (gptr*) &opt_bin_logname, (gptr*) &opt_bin_logname, 0, GET_STR_ALLOC,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-bin-index", OPT_BIN_LOG_INDEX,
+ "File that holds the names for last binary log files",
+ (gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file",
+ (gptr*) &myisam_log_filename, (gptr*) &myisam_log_filename, 0, GET_STR,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-update", OPT_UPDATE_LOG,
+ "Log updates to file.# where # is a unique number if not given.",
+ (gptr*) &opt_update_logname, (gptr*) &opt_update_logname, 0, GET_STR,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-slow-queries", OPT_SLOW_QUERY_LOG,
+ "Log slow queries to this log file. Defaults logging to hostname-slow.log",
+ (gptr*) &opt_slow_logname, (gptr*) &opt_slow_logname, 0, GET_STR, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"log-long-format", OPT_LONG_FORMAT,
+ "Log some extra information to update log", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"log-slave-updates", OPT_LOG_SLAVE_UPDATES,
+ "Tells the slave to log the updates from the slave thread to the binary log. You will need to turn it on if you plan to daisy-chain the slaves.",
+ (gptr*) &opt_log_slave_updates, (gptr*) &opt_log_slave_updates, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES,
+ "INSERT/DELETE/UPDATE has lower priority than selects",
+ (gptr*) &global_system_variables.low_priority_updates,
+ (gptr*) &max_system_variables.low_priority_updates,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"master-host", OPT_MASTER_HOST,
+ "Master hostname or IP address for replication. If not set, the slave thread will not be started. Note that the setting of master-host will be ignored if there exists a valid master.info file.",
+ (gptr*) &master_host, (gptr*) &master_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"master-user", OPT_MASTER_USER,
+ "The username the slave thread will use for authentication when connecting to the master. The user must have FILE privilege. If the master user is not set, user test is assumed. The value in master.info will take precedence if it can be read.",
+ (gptr*) &master_user, (gptr*) &master_user, 0, GET_STR, REQUIRED_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"master-password", OPT_MASTER_PASSWORD,
+ "The password the slave thread will authenticate with when connecting to the master. If not set, an empty password is assumed.The value in master.info will take precedence if it can be read.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"master-port", OPT_MASTER_PORT,
+ "The port the master is listening on. If not set, the compiled setting of MYSQL_PORT is assumed. If you have not tinkered with configure options, this should be 3306. The value in master.info will take precedence if it can be read",
+ (gptr*) &master_port, (gptr*) &master_port, 0, GET_UINT, REQUIRED_ARG,
+ MYSQL_PORT, 0, 0, 0, 0, 0},
+ {"master-connect-retry", OPT_MASTER_CONNECT_RETRY,
+ "The number of seconds the slave thread will sleep before retrying to connect to the master in case the master goes down or the connection is lost.",
+ (gptr*) &master_connect_retry, (gptr*) &master_connect_retry, 0, GET_UINT,
+ REQUIRED_ARG, 60, 0, 0, 0, 0, 0},
+ {"master-retry-count", OPT_MASTER_RETRY_COUNT,
+ "The number of tries the slave will make to connect to the master before giving up.",
+ (gptr*) &master_retry_count, (gptr*) &master_retry_count, 0, GET_ULONG,
+ REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
+ {"master-info-file", OPT_MASTER_INFO_FILE,
+ "The location and name of the file that remembers the master and where the I/O replication \
+thread is in the master's binlogs.",
+ (gptr*) &master_info_file, (gptr*) &master_info_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"master-ssl", OPT_MASTER_SSL,
+ "Planned to enable the slave to connect to the master using SSL. Does nothing yet.",
+ (gptr*) &master_ssl, (gptr*) &master_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"master-ssl-key", OPT_MASTER_SSL_KEY,
+ "Master SSL keyfile name. Only applies if you have enabled master-ssl. Does \
+nothing yet.",
+ (gptr*) &master_ssl_key, (gptr*) &master_ssl_key, 0, GET_STR, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"master-ssl-cert", OPT_MASTER_SSL_CERT,
+ "Master SSL certificate file name. Only applies if you have enabled \
+master-ssl. Does nothing yet.",
+ (gptr*) &master_ssl_cert, (gptr*) &master_ssl_cert, 0, GET_STR, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"master-ssl-capath", OPT_MASTER_SSL_CAPATH,
+ "Master SSL CA path. Only applies if you have enabled master-ssl. \
+Does nothing yet.",
+ (gptr*) &master_ssl_capath, (gptr*) &master_ssl_capath, 0, GET_STR, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"master-ssl-cipher", OPT_MASTER_SSL_CIPHER,
+ "Master SSL cipher. Only applies if you have enabled master-ssl. \
+Does nothing yet.",
+ (gptr*) &master_ssl_cipher, (gptr*) &master_ssl_capath, 0, GET_STR, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"myisam-recover", OPT_MYISAM_RECOVER,
+ "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
+ (gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0,
+ GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"memlock", OPT_MEMLOCK, "Lock mysqld in memory", (gptr*) &locked_in_memory,
+ (gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT,
+ "Option used by mysql-test for debugging and testing of replication",
+ (gptr*) &disconnect_slave_event_count,
+ (gptr*) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT,
+ "Option used by mysql-test for debugging and testing of replication",
+ (gptr*) &abort_slave_event_count, (gptr*) &abort_slave_event_count,
+ 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS,
+ "Option used by mysql-test for debugging and testing of replication",
+ (gptr*) &max_binlog_dump_events, (gptr*) &max_binlog_dump_events, 0,
+ GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL,
+ "Option used by mysql-test for debugging and testing of replication",
+ (gptr*) &opt_sporadic_binlog_dump_fail,
+ (gptr*) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"safemalloc-mem-limit", OPT_SAFEMALLOC_MEM_LIMIT,
+ "Simulate memory shortage when compiled with the --with-debug=full option",
+ 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"new", 'n', "Use some 4.1 features and syntax (4.1 compatibility mode)",
+ (gptr*) &global_system_variables.new_mode,
+ (gptr*) &max_system_variables.new_mode,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef NOT_YET
+ {"no-mix-table-types", OPT_NO_MIX_TYPE, "Don't allow commands with uses two different table types",
+ (gptr*) &opt_no_mix_types, (gptr*) &opt_no_mix_types, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
+ {"old-protocol", 'o', "Use the old (3.20) protocol client/server protocol",
+ (gptr*) &protocol_version, (gptr*) &protocol_version, 0, GET_UINT, NO_ARG,
+ PROTOCOL_VERSION, 0, 0, 0, 0, 0},
#ifdef ONE_THREAD
- {"one-thread", no_argument, 0, (int) OPT_ONE_THREAD},
-#endif
- {"pid-file", required_argument, 0, (int) OPT_PID_FILE},
- {"port", required_argument, 0, 'P'},
- {"replicate-do-db", required_argument, 0, (int) OPT_REPLICATE_DO_DB},
- {"replicate-do-table", required_argument, 0,
- (int) OPT_REPLICATE_DO_TABLE},
- {"replicate-wild-do-table", required_argument, 0,
- (int) OPT_REPLICATE_WILD_DO_TABLE},
- {"replicate-ignore-db", required_argument, 0,
- (int) OPT_REPLICATE_IGNORE_DB},
- {"replicate-ignore-table", required_argument, 0,
- (int) OPT_REPLICATE_IGNORE_TABLE},
- {"replicate-wild-ignore-table", required_argument, 0,
- (int) OPT_REPLICATE_WILD_IGNORE_TABLE},
- {"replicate-rewrite-db", required_argument, 0,
- (int) OPT_REPLICATE_REWRITE_DB},
- {"safe-mode", no_argument, 0, (int) OPT_SAFE},
- {"safe-show-database", no_argument, 0, (int) OPT_SAFE_SHOW_DB},
- {"safe-user-create", no_argument, 0, (int) OPT_SAFE_USER_CREATE},
- {"server-id", required_argument, 0, (int) OPT_SERVER_ID},
- {"set-variable", required_argument, 0, 'O'},
- {"skip-bdb", no_argument, 0, (int) OPT_BDB_SKIP},
- {"skip-innodb", no_argument, 0, (int) OPT_INNODB_SKIP},
- {"skip-gemini", no_argument, 0, (int) OPT_GEMINI_SKIP},
- {"skip-concurrent-insert", no_argument, 0, (int) OPT_SKIP_CONCURRENT_INSERT},
- {"skip-delay-key-write", no_argument, 0, (int) OPT_SKIP_DELAY_KEY_WRITE},
- {"skip-grant-tables", no_argument, 0, (int) OPT_SKIP_GRANT},
- {"skip-locking", no_argument, 0, (int) OPT_SKIP_LOCK},
- {"skip-host-cache", no_argument, 0, (int) OPT_SKIP_HOST_CACHE},
- {"skip-name-resolve", no_argument, 0, (int) OPT_SKIP_RESOLVE},
- {"skip-networking", no_argument, 0, (int) OPT_SKIP_NETWORKING},
- {"skip-new", no_argument, 0, (int) OPT_SKIP_NEW},
- {"skip-safemalloc", no_argument, 0, (int) OPT_SKIP_SAFEMALLOC},
- {"skip-show-database", no_argument, 0, (int) OPT_SKIP_SHOW_DB},
- {"skip-slave-start", no_argument, 0, (int) OPT_SKIP_SLAVE_START},
- {"skip-stack-trace", no_argument, 0, (int) OPT_SKIP_STACK_TRACE},
- {"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS},
- {"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR},
- {"slave-skip-errors", required_argument,0,
- (int) OPT_SLAVE_SKIP_ERRORS},
- {"socket", required_argument, 0, (int) OPT_SOCKET},
- {"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME},
- {"sql-mode", required_argument, 0, (int) OPT_SQL_MODE},
+ {"one-thread", OPT_ONE_THREAD,
+ "Only use one thread (for debugging under Linux)", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld",
+ (gptr*) &pidfile_name_ptr, (gptr*) &pidfile_name_ptr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-error", OPT_ERROR_LOG_FILE, "Log error file",
+ (gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection.", (gptr*) &mysql_port,
+ (gptr*) &mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-do-db", OPT_REPLICATE_DO_DB,
+ "Tells the slave thread to restrict replication to the specified database. To specify more than one database, use the directive multiple times, once for each database. Note that this will only work if you do not use cross-database queries such as UPDATE some_db.some_table SET foo='bar' while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-do-table=db_name.%.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
+ "Tells the slave thread to restrict replication to the specified table. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates, in contrast to replicate-do-db.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
+ "Tells the slave thread to restrict replication to the tables that match the specified wildcard pattern. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-do-table=foo%.bar% will replicate only updates to tables in all databases that start with foo and whose table names start with bar",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
+ "Tells the slave thread to not replicate to the specified database. To specify more than one database to ignore, use the directive multiple times, once for each database. This option will not work if you use cross database updates. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-ignore-table=db_name.%. ",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
+ "Tells the slave thread to not replicate to the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-datbase updates, in contrast to replicate-ignore-db.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
+ "Tells the slave thread to not replicate to the tables that match the given wildcard pattern. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% will not do updates to tables in databases that start with foo and whose table names start with bar.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
+ "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ // In replication, we may need to tell the other servers how to connect
+ {"report-host", OPT_REPORT_HOST,
+ "Hostname or IP of the slave to be reported to to the master during slave registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset if you do not want the slave to register itself with the master. Note that it is not sufficient for the master to simply read the IP of the slave off the socket once the slave connects. Due to NAT and other routing issues, that IP may not be valid for connecting to the slave from the master or other hosts.",
+ (gptr*) &report_host, (gptr*) &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"report-user", OPT_REPORT_USER, "Undocumented", (gptr*) &report_user,
+ (gptr*) &report_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"report-password", OPT_REPORT_PASSWORD, "Undocumented",
+ (gptr*) &report_password, (gptr*) &report_password, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"report-port", OPT_REPORT_PORT,
+ "Port for connecting to slave reported to the master during slave registration. Set it only if the slave is listening on a non-default port or if you have a special tunnel from the master or other clients to the slave. If not sure, leave this option unset.",
+ (gptr*) &report_port, (gptr*) &report_port, 0, GET_UINT, REQUIRED_ARG,
+ MYSQL_PORT, 0, 0, 0, 0, 0},
+ {"rpl-recovery-rank", OPT_RPL_RECOVERY_RANK, "Undocumented",
+ (gptr*) &rpl_recovery_rank, (gptr*) &rpl_recovery_rank, 0, GET_ULONG,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"relay-log", OPT_RELAY_LOG,
+ "The location and name to use for relay logs",
+ (gptr*) &opt_relay_logname, (gptr*) &opt_relay_logname, 0,
+ GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"relay-log-index", OPT_RELAY_LOG_INDEX,
+ "The location and name to use for the file that keeps a list of the last \
+relay logs",
+ (gptr*) &opt_relaylog_index_name, (gptr*) &opt_relaylog_index_name, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef TO_BE_DELETED
+ {"safe-show-database", OPT_SAFE_SHOW_DB,
+ "Deprecated option; One should use GRANT SHOW DATABASES instead...",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"safe-user-create", OPT_SAFE_USER_CREATE,
+ "Don't allow new user creation by the user who has no write privileges to the mysql.user table",
+ (gptr*) &opt_safe_user_create, (gptr*) &opt_safe_user_create, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"server-id", OPT_SERVER_ID,
+ "Uniquely identifies the server instance in the community of replication partners",
+ (gptr*) &server_id, (gptr*) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"set-variable", 'O',
+ "Change the value of a variable. Please note that this option is deprecated;you can set variables directly with --variable-name=value.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO,
+ "Show user and password in SHOW SLAVE STATUS",
+ (gptr*) &opt_show_slave_auth_info, (gptr*) &opt_show_slave_auth_info, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"concurrent-insert", OPT_CONCURRENT_INSERT,
+ "Use concurrent insert with MyISAM. Disable with prefix --skip-",
+ (gptr*) &myisam_concurrent_insert, (gptr*) &myisam_concurrent_insert,
+ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"skip-grant-tables", OPT_SKIP_GRANT,
+ "Start without grant tables. This gives all users FULL ACCESS to all tables!",
+ (gptr*) &opt_noacl, (gptr*) &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
+ 0},
+ {"skip-innodb", OPT_INNODB_SKIP, "Don't use Innodb (will save memory)",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-locking", OPT_SKIP_LOCK,
+ "Deprecated option, use --skip-external-locking instead",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-name-resolve", OPT_SKIP_RESOLVE,
+ "Don't resolve hostnames. All hostnames are IP's or 'localhost'",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-networking", OPT_SKIP_NETWORKING,
+ "Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"skip-new", OPT_SKIP_NEW, "Don't use new, possible wrong routines.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-show-database", OPT_SKIP_SHOW_DB,
+ "Don't allow 'SHOW DATABASE' commands", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"skip-slave-start", OPT_SKIP_SLAVE_START,
+ "If set, slave is not autostarted.", (gptr*) &opt_skip_slave_start,
+ (gptr*) &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
+ "Don't print a stack trace on failure", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Deprecated option. Use --skip-symbolic-links instead",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-thread-priority", OPT_SKIP_PRIOR,
+ "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE,
+ "The location and name of the file that remembers where the SQL replication \
+thread is in the relay logs",
+ (gptr*) &relay_log_info_file, (gptr*) &relay_log_info_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR,
+ "The location where the slave should put its temporary files when \
+replicating a LOAD DATA INFILE command",
+ (gptr*) &slave_load_tmpdir, (gptr*) &slave_load_tmpdir, 0, GET_STR_ALLOC,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS,
+ "Tells the slave thread to continue replication when a query returns an error from the provided list",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", OPT_SOCKET, "Socket file to use for connection",
+ (gptr*) &mysql_unix_port, (gptr*) &mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
+ "If set, setting SQL_LOG_BIN to a value will automatically set SQL_LOG_UPDATE to the same value and vice versa.",
+ (gptr*) &opt_sql_bin_update, (gptr*) &opt_sql_bin_update, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"sql-mode", OPT_SQL_MODE,
+ "Syntax: sql-mode=option[,option[,option...]] where option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.",
+ (gptr*) &sql_mode_str, (gptr*) &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0,
+ 0, 0, 0, 0, 0},
+#ifdef HAVE_OPENSSL
#include "sslopt-longopts.h"
-#ifdef __WIN__
- {"standalone", no_argument, 0, (int) OPT_STANDALONE},
-#endif
- {"transaction-isolation", required_argument, 0, (int) OPT_TX_ISOLATION},
- {"temp-pool", no_argument, 0, (int) OPT_TEMP_POOL},
- {"tmpdir", required_argument, 0, 't'},
- {"use-locking", no_argument, 0, (int) OPT_USE_LOCKING},
-#ifdef USE_SYMDIR
- {"use-symbolic-links", no_argument, 0, 's'},
-#endif
- {"user", required_argument, 0, 'u'},
- {"version", no_argument, 0, 'V'},
- {"warnings", no_argument, 0, 'W'},
- {0, 0, 0, 0}
-};
-
-#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
-
-CHANGEABLE_VAR changeable_vars[] = {
- { "back_log", (long*) &back_log,
- 50, 1, 65535, 0, 1 },
-#ifdef HAVE_BERKELEY_DB
- { "bdb_cache_size", (long*) &berkeley_cache_size,
- KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE },
- {"bdb_log_buffer_size", (long*) &berkeley_log_buffer_size, 0, 256*1024L,
- ~0L, 0, 1024},
- { "bdb_max_lock", (long*) &berkeley_max_lock,
- 10000, 0, (long) ~0, 0, 1 },
- /* QQ: The following should be removed soon! */
- { "bdb_lock_max", (long*) &berkeley_max_lock,
- 10000, 0, (long) ~0, 0, 1 },
-#endif
- { "binlog_cache_size", (long*) &binlog_cache_size,
- 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE },
- { "connect_timeout", (long*) &connect_timeout,
- CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1 },
- { "delayed_insert_timeout", (long*) &delayed_insert_timeout,
- DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { "delayed_insert_limit", (long*) &delayed_insert_limit,
- DELAYED_LIMIT, 1, ~0L, 0, 1 },
- { "delayed_queue_size", (long*) &delayed_queue_size,
- DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1 },
- { "flush_time", (long*) &flush_time,
- FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1 },
-#ifdef HAVE_GEMINI_DB
- { "gemini_buffer_cache", (long*) &gemini_buffer_cache,
- 128 * 8192, 16, LONG_MAX, 0, 1 },
- { "gemini_connection_limit", (long*) &gemini_connection_limit,
- 100, 10, LONG_MAX, 0, 1 },
- { "gemini_io_threads", (long*) &gemini_io_threads,
- 2, 0, 256, 0, 1 },
- { "gemini_log_cluster_size", (long*) &gemini_log_cluster_size,
- 256 * 1024, 16 * 1024, LONG_MAX, 0, 1 },
- { "gemini_lock_table_size", (long*) &gemini_locktablesize,
- 4096, 1024, LONG_MAX, 0, 1 },
- { "gemini_lock_wait_timeout",(long*) &gemini_lock_wait_timeout,
- 10, 1, LONG_MAX, 0, 1 },
- { "gemini_spin_retries", (long*) &gemini_spin_retries,
- 1, 0, LONG_MAX, 0, 1 },
#endif
+ {"temp-pool", OPT_TEMP_POOL,
+ "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.",
+ (gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
+ 0, 0, 0, 0, 0},
+ {"tmpdir", 't', "Path for temporary files", (gptr*) &opt_mysql_tmpdir,
+ (gptr*) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"transaction-isolation", OPT_TX_ISOLATION,
+ "Default transaction isolation level", 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running",
+ (gptr*) &opt_external_locking, (gptr*) &opt_external_locking,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; Use --symbolic-links instead",
+ (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG,
+ IF_PURIFY(0,1), 0, 0, 0, 0, 0},
+ {"symbolic-links", 's', "Enable symbolic link support",
+ (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG,
+ IF_PURIFY(0,1), 0, 0, 0, 0, 0},
+ {"user", 'u', "Run mysqld daemon as user", 0, 0, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'v', "Synonym for option -v", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
+ 0, 0, 0, 0},
+ {"log-warnings", 'W', "Log some not critical warnings to the log file",
+ (gptr*) &global_system_variables.log_warnings,
+ (gptr*) &max_system_variables.log_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"warnings", 'W', "Deprecated ; Use --log-warnings instead",
+ (gptr*) &global_system_variables.log_warnings,
+ (gptr*) &max_system_variables.log_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ { "back_log", OPT_BACK_LOG,
+ "The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.",
+ (gptr*) &back_log, (gptr*) &back_log, 0, GET_ULONG,
+ REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
+#ifdef HAVE_BERKELEY_DB
+ { "bdb_cache_size", OPT_BDB_CACHE_SIZE,
+ "The buffer that is allocated to cache index and rows for BDB tables.",
+ (gptr*) &berkeley_cache_size, (gptr*) &berkeley_cache_size, 0, GET_ULONG,
+ REQUIRED_ARG, KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE, 0},
+ {"bdb_log_buffer_size", OPT_BDB_LOG_BUFFER_SIZE,
+ "The buffer that is allocated to cache index and rows for BDB tables.",
+ (gptr*) &berkeley_log_buffer_size, (gptr*) &berkeley_log_buffer_size, 0,
+ GET_ULONG, REQUIRED_ARG, 0, 256*1024L, ~0L, 0, 1024, 0},
+ {"bdb_max_lock", OPT_BDB_MAX_LOCK,
+ "The maximum number of locks you can have active on a BDB table.",
+ (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG,
+ REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0},
+ /* QQ: The following should be removed soon! */
+ {"bdb_lock_max", OPT_BDB_MAX_LOCK, "Synonym for bdb_max_lock",
+ (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG,
+ REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0},
+#endif /* HAVE_BERKELEY_DB */
+ {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE,
+ "The size of the cache to hold the SQL statements for the binary log during a transaction. If you often use big, multi-statement transactions you can increase this to get more performance.",
+ (gptr*) &binlog_cache_size, (gptr*) &binlog_cache_size, 0, GET_ULONG,
+ REQUIRED_ARG, 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE, 0},
+ {"connect_timeout", OPT_CONNECT_TIMEOUT,
+ "The number of seconds the mysqld server is waiting for a connect packet before responding with Bad handshake",
+ (gptr*) &connect_timeout, (gptr*) &connect_timeout,
+ 0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
+ {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT,
+ "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.",
+ (gptr*) &delayed_insert_timeout, (gptr*) &delayed_insert_timeout, 0,
+ GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT,
+ "After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing.",
+ (gptr*) &delayed_insert_limit, (gptr*) &delayed_insert_limit, 0, GET_ULONG,
+ REQUIRED_ARG, DELAYED_LIMIT, 1, ~0L, 0, 1, 0},
+ { "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE,
+ "What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.",
+ (gptr*) &delayed_queue_size, (gptr*) &delayed_queue_size, 0, GET_ULONG,
+ REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1, 0},
+ { "flush_time", OPT_FLUSH_TIME,
+ "A dedicated thread is created to flush all tables at the given interval.",
+ (gptr*) &flush_time, (gptr*) &flush_time, 0, GET_ULONG, REQUIRED_ARG,
+ FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
+ { "ft_min_word_len", OPT_FT_MIN_WORD_LEN,
+ "The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
+ (gptr*) &ft_min_word_len, (gptr*) &ft_min_word_len, 0, GET_ULONG,
+ REQUIRED_ARG, 4, 1, HA_FT_MAXLEN, 0, 1, 0},
+ { "ft_max_word_len", OPT_FT_MAX_WORD_LEN,
+ "The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
+ (gptr*) &ft_max_word_len, (gptr*) &ft_max_word_len, 0, GET_ULONG,
+ REQUIRED_ARG, HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1, 0},
+ { "ft_max_word_len_for_sort", OPT_FT_MAX_WORD_LEN_FOR_SORT,
+ "The maximum length of the word for repair_by_sorting. Longer words are included the slow way. The lower this value, the more words will be put in one sort bucket.",
+ (gptr*) &ft_max_word_len_for_sort, (gptr*) &ft_max_word_len_for_sort, 0, GET_ULONG,
+ REQUIRED_ARG, 20, 4, HA_FT_MAXLEN, 0, 1, 0},
+ { "ft_stopword_file", OPT_FT_STOPWORD_FILE,
+ "Use stopwords from this file instead of built-in list.",
+ (gptr*) &ft_stopword_file, (gptr*) &ft_stopword_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_INNOBASE_DB
- {"innodb_mirrored_log_groups",
- (long*) &innobase_mirrored_log_groups, 1, 1, 10, 0, 1},
- {"innodb_log_files_in_group",
- (long*) &innobase_log_files_in_group, 2, 2, 100, 0, 1},
- {"innodb_log_file_size",
- (long*) &innobase_log_file_size, 5*1024*1024L, 1*1024*1024L,
- ~0L, 0, 1024*1024L},
- {"innodb_log_buffer_size",
- (long*) &innobase_log_buffer_size, 1024*1024L, 256*1024L,
- ~0L, 0, 1024},
- {"innodb_buffer_pool_size",
- (long*) &innobase_buffer_pool_size, 8*1024*1024L, 1024*1024L,
- ~0L, 0, 1024*1024L},
- {"innodb_additional_mem_pool_size",
- (long*) &innobase_additional_mem_pool_size, 1*1024*1024L, 512*1024L,
- ~0L, 0, 1024},
- {"innodb_file_io_threads",
- (long*) &innobase_file_io_threads, 4, 4, 64, 0, 1},
- {"innodb_lock_wait_timeout",
- (long*) &innobase_lock_wait_timeout, 50, 1,
- 1024 * 1024 * 1024, 0, 1},
- {"innodb_thread_concurrency",
- (long*) &innobase_thread_concurrency, 8, 1, 1000, 0, 1},
- {"innodb_force_recovery",
- (long*) &innobase_force_recovery, 0, 0, 6, 0, 1},
-#endif
- { "interactive_timeout", (long*) &net_interactive_timeout,
- NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { "join_buffer_size", (long*) &join_buff_size,
- 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
- { "key_buffer_size", (long*) &keybuff_size,
- KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE },
- { "long_query_time", (long*) &long_query_time,
- 10, 1, LONG_TIMEOUT, 0, 1 },
- { "lower_case_table_names", (long*) &lower_case_table_names,
+ {"innodb_mirrored_log_groups", OPT_INNODB_MIRRORED_LOG_GROUPS,
+ "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
+ (gptr*) &innobase_mirrored_log_groups,
+ (gptr*) &innobase_mirrored_log_groups, 0, GET_LONG, REQUIRED_ARG, 1, 1, 10,
+ 0, 1, 0},
+ {"innodb_log_files_in_group", OPT_INNODB_LOG_FILES_IN_GROUP,
+ "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
+ (gptr*) &innobase_log_files_in_group, (gptr*) &innobase_log_files_in_group,
+ 0, GET_LONG, REQUIRED_ARG, 2, 2, 100, 0, 1, 0},
+ {"innodb_log_file_size", OPT_INNODB_LOG_FILE_SIZE,
+ "Size of each log file in a log group in megabytes.",
+ (gptr*) &innobase_log_file_size, (gptr*) &innobase_log_file_size, 0,
+ GET_LONG, REQUIRED_ARG, 5*1024*1024L, 1*1024*1024L, ~0L, 0, 1024*1024L, 0},
+ {"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE,
+ "The size of the buffer which InnoDB uses to write log to the log files on disk.",
+ (gptr*) &innobase_log_buffer_size, (gptr*) &innobase_log_buffer_size, 0,
+ GET_LONG, REQUIRED_ARG, 1024*1024L, 256*1024L, ~0L, 0, 1024, 0},
+ {"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE,
+ "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
+ (gptr*) &innobase_buffer_pool_size, (gptr*) &innobase_buffer_pool_size, 0,
+ GET_LONG, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, ~0L, 0, 1024*1024L, 0},
+ {"innodb_additional_mem_pool_size", OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE,
+ "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
+ (gptr*) &innobase_additional_mem_pool_size,
+ (gptr*) &innobase_additional_mem_pool_size, 0, GET_LONG, REQUIRED_ARG,
+ 1*1024*1024L, 512*1024L, ~0L, 0, 1024, 0},
+ {"innodb_file_io_threads", OPT_INNODB_FILE_IO_THREADS,
+ "Number of file I/O threads in InnoDB.", (gptr*) &innobase_file_io_threads,
+ (gptr*) &innobase_file_io_threads, 0, GET_LONG, REQUIRED_ARG, 4, 4, 64, 0,
+ 1, 0},
+ {"innodb_lock_wait_timeout", OPT_INNODB_LOCK_WAIT_TIMEOUT,
+ "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back.",
+ (gptr*) &innobase_lock_wait_timeout, (gptr*) &innobase_lock_wait_timeout,
+ 0, GET_LONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
+ {"innodb_thread_concurrency", OPT_INNODB_THREAD_CONCURRENCY,
+ "Helps in performance tuning in heavily concurrent environments.",
+ (gptr*) &innobase_thread_concurrency, (gptr*) &innobase_thread_concurrency,
+ 0, GET_LONG, REQUIRED_ARG, 8, 1, 1000, 0, 1, 0},
+ {"innodb_force_recovery", OPT_INNODB_FORCE_RECOVERY,
+ "Helps to save your data in case the disk image of the database becomes corrupt.",
+ (gptr*) &innobase_force_recovery, (gptr*) &innobase_force_recovery, 0,
+ GET_LONG, REQUIRED_ARG, 0, 0, 6, 0, 1, 0},
+#endif /* HAVE_INNOBASE_DB */
+ {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
+ "The number of seconds the server waits for activity on an interactive connection before closing it.",
+ (gptr*) &global_system_variables.net_interactive_timeout,
+ (gptr*) &max_system_variables.net_interactive_timeout, 0,
+ GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"join_buffer_size", OPT_JOIN_BUFF_SIZE,
+ "The size of the buffer that is used for full joins.",
+ (gptr*) &global_system_variables.join_buff_size,
+ (gptr*) &max_system_variables.join_buff_size, 0, GET_ULONG,
+ REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD,
+ IO_SIZE, 0},
+ {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
+ "The size of the buffer used for index blocks. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
+ (gptr*) &keybuff_size, (gptr*) &keybuff_size, 0, GET_ULL,
+ REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD,
+ IO_SIZE, 0},
+ {"long_query_time", OPT_LONG_QUERY_TIME,
+ "Log all queries that have taken more than long_query_time seconds to execute to file.",
+ (gptr*) &global_system_variables.long_query_time,
+ (gptr*) &max_system_variables.long_query_time, 0, GET_ULONG,
+ REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
+ "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system",
+ (gptr*) &lower_case_table_names,
+ (gptr*) &lower_case_table_names, 0, GET_UINT, OPT_ARG,
#ifdef FN_NO_CASE_SENCE
1
#else
0
#endif
- ,0, 1, 0, 1 },
- { "max_allowed_packet", (long*) &max_allowed_packet,
- 1024*1024L, 80, 16*1024*1024L, MALLOC_OVERHEAD, 1024 },
- { "max_binlog_cache_size", (long*) &max_binlog_cache_size,
- ~0L, IO_SIZE, ~0L, 0, IO_SIZE },
- { "max_binlog_size", (long*) &max_binlog_size,
- 1024*1024L*1024L, 1024, 1024*1024L*1024L, 0, 1 },
- { "max_connections", (long*) &max_connections,
- 100, 1, 16384, 0, 1 },
- { "max_connect_errors", (long*) &max_connect_errors,
- MAX_CONNECT_ERRORS, 1, ~0L, 0, 1 },
- { "max_delayed_threads", (long*) &max_insert_delayed_threads,
- 20, 1, 16384, 0, 1 },
- { "max_heap_table_size", (long*) &max_heap_table_size,
- 16*1024*1024L, 16384, ~0L, MALLOC_OVERHEAD, 1024 },
- { "max_join_size", (long*) &max_join_size,
- ~0L, 1, ~0L, 0, 1 },
- { "max_sort_length", (long*) &max_item_sort_length,
- 1024, 4, 8192*1024L, 0, 1 },
- { "max_tmp_tables", (long*) &max_tmp_tables,
- 32, 1, ~0L, 0, 1 },
- { "max_user_connections", (long*) &max_user_connections,
- 0, 1, ~0L, 0, 1 },
- { "max_write_lock_count", (long*) &max_write_lock_count,
- ~0L, 1, ~0L, 0, 1 },
- { "myisam_max_extra_sort_file_size",
- (long*) &myisam_max_extra_sort_file_size,
- (long) (MI_MAX_TEMP_LENGTH/(1024L*1024L)), 0, ~0L, 0, 1 },
- { "myisam_max_sort_file_size", (long*) &myisam_max_sort_file_size,
- (long) (LONG_MAX/(1024L*1024L)), 0, ~0L, 0, 1 },
- { "myisam_sort_buffer_size", (long*) &myisam_sort_buffer_size,
- 8192*1024, 4, ~0L, 0, 1 },
- { "net_buffer_length", (long*) &net_buffer_length,
- 16384, 1024, 1024*1024L, MALLOC_OVERHEAD, 1024 },
- { "net_retry_count", (long*) &mysqld_net_retry_count,
- MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1 },
- { "net_read_timeout", (long*) &net_read_timeout,
- NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { "net_write_timeout", (long*) &net_write_timeout,
- NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { "open_files_limit", (long*) &open_files_limit,
- 0, 0, 65535, 0, 1},
- { "query_buffer_size", (long*) &query_buff_size,
- 0, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE },
- { "record_buffer", (long*) &my_default_record_cache_size,
- 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
- { "record_rnd_buffer", (long*) &record_rnd_cache_size,
- 0, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
- { "slave_net_timeout", (long*) &slave_net_timeout,
- SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { "slow_launch_time", (long*) &slow_launch_time,
- 2L, 0L, LONG_TIMEOUT, 0, 1 },
- { "sort_buffer", (long*) &sortbuff_size,
- MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, 1 },
- { "table_cache", (long*) &table_cache_size,
- 64, 1, 16384, 0, 1 },
- { "thread_concurrency", (long*) &concurrency,
- DEFAULT_CONCURRENCY, 1, 512, 0, 1 },
- { "thread_cache_size", (long*) &thread_cache_size,
- 0, 0, 16384, 0, 1 },
- { "tmp_table_size", (long*) &tmp_table_size,
- 32*1024*1024L, 1024, ~0L, 0, 1 },
- { "thread_stack", (long*) &thread_stack,
- DEFAULT_THREAD_STACK, 1024*32, ~0L, 0, 1024 },
- { "wait_timeout", (long*) &net_wait_timeout,
- NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 },
- { NullS, (long*) 0, 0, 0, 0, 0, 0}
+ , 0, 2, 0, 1, 0},
+ {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
+ "Max packetlength to send/receive from to server.",
+ (gptr*) &global_system_variables.max_allowed_packet,
+ (gptr*) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
+ REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
+ {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
+ "Can be used to restrict the total size used to cache a multi-transaction query.",
+ (gptr*) &max_binlog_cache_size, (gptr*) &max_binlog_cache_size, 0,
+ GET_ULONG, REQUIRED_ARG, ~0L, IO_SIZE, ~0L, 0, IO_SIZE, 0},
+ {"max_binlog_size", OPT_MAX_BINLOG_SIZE,
+ "Binary log will be rotated automatically when the size exceeds this \
+value. Will also apply to relay logs if max_relay_log_size is 0. \
+The minimum value for this variable is 4096.",
+ (gptr*) &max_binlog_size, (gptr*) &max_binlog_size, 0, GET_ULONG,
+ REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0},
+ {"max_connections", OPT_MAX_CONNECTIONS,
+ "The number of simultaneous clients allowed.", (gptr*) &max_connections,
+ (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1,
+ 0},
+ {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
+ "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.",
+ (gptr*) &max_connect_errors, (gptr*) &max_connect_errors, 0, GET_ULONG,
+ REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ~0L, 0, 1, 0},
+ {"max_delayed_threads", OPT_MAX_DELAYED_THREADS,
+ "Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero, which means INSERT DELAYED is not used.",
+ (gptr*) &max_insert_delayed_threads, (gptr*) &max_insert_delayed_threads,
+ 0, GET_ULONG, REQUIRED_ARG, 20, 0, 16384, 0, 1, 0},
+ {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
+ "Don't allow creation of heap tables bigger than this.",
+ (gptr*) &global_system_variables.max_heap_table_size,
+ (gptr*) &max_system_variables.max_heap_table_size, 0, GET_ULONG,
+ REQUIRED_ARG, 16*1024*1024L, 16384, ~0L, MALLOC_OVERHEAD, 1024, 0},
+ {"max_join_size", OPT_MAX_JOIN_SIZE,
+ "Joins that are probably going to read more than max_join_size records return an error.",
+ (gptr*) &global_system_variables.max_join_size,
+ (gptr*) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
+ ~0L, 1, ~0L, 0, 1, 0},
+ {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE,
+ "If non-zero: relay log will be rotated automatically when the size exceeds \
+this value; if zero (the default): when the size exceeds max_binlog_size. \
+0 expected, the minimum value for this variable is 4096.",
+ (gptr*) &max_relay_log_size, (gptr*) &max_relay_log_size, 0, GET_ULONG,
+ REQUIRED_ARG, 0L, 0L, 1024*1024L*1024L, 0, IO_SIZE, 0},
+ { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
+ "Limit assumed max number of seeks when looking up rows based on a key",
+ (gptr*) &global_system_variables.max_seeks_for_key,
+ (gptr*) &max_system_variables.max_seeks_for_key, 0, GET_ULONG,
+ REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0 },
+ {"max_sort_length", OPT_MAX_SORT_LENGTH,
+ "The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).",
+ (gptr*) &global_system_variables.max_sort_length,
+ (gptr*) &max_system_variables.max_sort_length, 0, GET_ULONG,
+ REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
+ {"max_tmp_tables", OPT_MAX_TMP_TABLES,
+ "Maximum number of temporary tables a client can keep open at a time.",
+ (gptr*) &global_system_variables.max_tmp_tables,
+ (gptr*) &max_system_variables.max_tmp_tables, 0, GET_ULONG,
+ REQUIRED_ARG, 32, 1, ~0L, 0, 1, 0},
+ {"max_user_connections", OPT_MAX_USER_CONNECTIONS,
+ "The maximum number of active connections for a single user (0 = no limit).",
+ (gptr*) &max_user_connections, (gptr*) &max_user_connections, 0, GET_ULONG,
+ REQUIRED_ARG, 0, 1, ~0L, 0, 1, 0},
+ {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
+ "After this many write locks, allow some read locks to run in between.",
+ (gptr*) &max_write_lock_count, (gptr*) &max_write_lock_count, 0, GET_ULONG,
+ REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0},
+ {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
+ "Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!",
+ (gptr*) &global_system_variables.bulk_insert_buff_size,
+ (gptr*) &max_system_variables.bulk_insert_buff_size,
+ 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ~0L, 0, 1, 0},
+ {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
+ "Block size to be used for MyISAM index pages",
+ (gptr*) &opt_myisam_block_size,
+ (gptr*) &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
+ MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
+ 0, MI_MIN_KEY_BLOCK_LENGTH, 0},
+ {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
+ "Used to help MySQL to decide when to use the slow but safe key cache index create method",
+ (gptr*) &global_system_variables.myisam_max_extra_sort_file_size,
+ (gptr*) &max_system_variables.myisam_max_extra_sort_file_size,
+ 0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH,
+ 0, (ulonglong) MAX_FILE_SIZE, 0, 1, 0},
+ {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE,
+ "Don't use the fast sort index method to created index if the temporary file would get bigger than this!",
+ (gptr*) &global_system_variables.myisam_max_sort_file_size,
+ (gptr*) &max_system_variables.myisam_max_sort_file_size, 0,
+ GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, (ulonglong) MAX_FILE_SIZE,
+ 0, 1024*1024, 0},
+ {"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS,
+ "Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.",
+ (gptr*) &global_system_variables.myisam_repair_threads,
+ (gptr*) &max_system_variables.myisam_repair_threads, 0,
+ GET_ULONG, REQUIRED_ARG, 1, 1, ~0L, 0, 1, 0},
+ {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
+ "The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
+ (gptr*) &global_system_variables.myisam_sort_buff_size,
+ (gptr*) &max_system_variables.myisam_sort_buff_size, 0,
+ GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
+ {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
+ "Buffer length for TCP/IP and socket communication.",
+ (gptr*) &global_system_variables.net_buffer_length,
+ (gptr*) &max_system_variables.net_buffer_length, 0, GET_ULONG,
+ REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
+ {"net_retry_count", OPT_NET_RETRY_COUNT,
+ "If a read on a communication port is interrupted, retry this many times before giving up.",
+ (gptr*) &global_system_variables.net_retry_count,
+ (gptr*) &max_system_variables.net_retry_count,0,
+ GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1, 0},
+ {"net_read_timeout", OPT_NET_READ_TIMEOUT,
+ "Number of seconds to wait for more data from a connection before aborting the read.",
+ (gptr*) &global_system_variables.net_read_timeout,
+ (gptr*) &max_system_variables.net_read_timeout, 0, GET_ULONG,
+ REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
+ "Number of seconds to wait for a block to be written to a connection before aborting the write.",
+ (gptr*) &global_system_variables.net_write_timeout,
+ (gptr*) &max_system_variables.net_write_timeout, 0, GET_ULONG,
+ REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"open_files_limit", OPT_OPEN_FILES_LIMIT,
+ "If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.",
+ (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
+ REQUIRED_ARG, 0, 0, 65535, 0, 1, 0},
+ {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
+ "Allocation block size for query parsing and execution",
+ (gptr*) &global_system_variables.query_alloc_block_size,
+ (gptr*) &max_system_variables.query_alloc_block_size, 0, GET_ULONG,
+ REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0},
+#ifdef HAVE_QUERY_CACHE
+ {"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
+ "Don't cache results that are bigger than this.",
+ (gptr*) &query_cache_limit, (gptr*) &query_cache_limit, 0, GET_ULONG,
+ REQUIRED_ARG, 1024*1024L, 0, (longlong) ULONG_MAX, 0, 1, 0},
+#endif /*HAVE_QUERY_CACHE*/
+ {"query_cache_size", OPT_QUERY_CACHE_SIZE,
+ "The memory allocated to store results from old queries.",
+ (gptr*) &query_cache_size, (gptr*) &query_cache_size, 0, GET_ULONG,
+ REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1024, 0},
+#ifdef HAVE_QUERY_CACHE
+ {"query_cache_type", OPT_QUERY_CACHE_TYPE,
+ "0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT SQL_CACHE ... queries.",
+ (gptr*) &global_system_variables.query_cache_type,
+ (gptr*) &max_system_variables.query_cache_type,
+ 0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0},
+ {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
+ "Persistent buffer for query parsing and execution",
+ (gptr*) &global_system_variables.query_prealloc_size,
+ (gptr*) &max_system_variables.query_prealloc_size, 0, GET_ULONG,
+ REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0},
+#endif /*HAVE_QUERY_CACHE*/
+ {"read_buffer_size", OPT_RECORD_BUFFER,
+ "Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.",
+ (gptr*) &global_system_variables.read_buff_size,
+ (gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
+ 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
+ {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
+ "When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks. If not set, then it's set to the value of record_buffer.",
+ (gptr*) &global_system_variables.read_rnd_buff_size,
+ (gptr*) &max_system_variables.read_rnd_buff_size, 0,
+ GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
+ ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
+ {"record_buffer", OPT_RECORD_BUFFER,
+ "Alias for read_buffer_size",
+ (gptr*) &global_system_variables.read_buff_size,
+ (gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
+ 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
+ {"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT,
+ "Maximum space to use for all relay logs",
+ (gptr*) &relay_log_space_limit,
+ (gptr*) &relay_log_space_limit, 0, GET_ULL, REQUIRED_ARG, 0L, 0L,
+ (longlong) ULONG_MAX, 0, 1, 0},
+ {"slave_compressed_protocol", OPT_SLAVE_COMPRESSED_PROTOCOL,
+ "Use compression on master/slave protocol",
+ (gptr*) &opt_slave_compressed_protocol,
+ (gptr*) &opt_slave_compressed_protocol,
+ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
+ {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT,
+ "Number of seconds to wait for more data from a master/slave connection before aborting the read.",
+ (gptr*) &slave_net_timeout, (gptr*) &slave_net_timeout, 0,
+ GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
+ {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
+ "Allocation block size for storing ranges during optimization",
+ (gptr*) &global_system_variables.range_alloc_block_size,
+ (gptr*) &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
+ REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0},
+ {"read-only", OPT_READONLY,
+ "Make all tables readonly, with the exception for replication (slave) threads and users with the SUPER privilege",
+ (gptr*) &opt_readonly,
+ (gptr*) &opt_readonly,
+ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
+ {"slow_launch_time", OPT_SLOW_LAUNCH_TIME,
+ "If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented.",
+ (gptr*) &slow_launch_time, (gptr*) &slow_launch_time, 0, GET_ULONG,
+ REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0},
+ {"sort_buffer_size", OPT_SORT_BUFFER,
+ "Each thread that needs to do a sort allocates a buffer of this size.",
+ (gptr*) &global_system_variables.sortbuff_size,
+ (gptr*) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
+ MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD,
+ 1, 0},
+ {"table_cache", OPT_TABLE_CACHE,
+ "The number of open tables for all threads.", (gptr*) &table_cache_size,
+ (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, ~0L, 0, 1,
+ 0},
+ {"thread_concurrency", OPT_THREAD_CONCURRENCY,
+ "Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.",
+ (gptr*) &concurrency, (gptr*) &concurrency, 0, GET_ULONG, REQUIRED_ARG,
+ DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0},
+ {"thread_cache_size", OPT_THREAD_CACHE_SIZE,
+ "How many threads we should keep in a cache for reuse.",
+ (gptr*) &thread_cache_size, (gptr*) &thread_cache_size, 0, GET_ULONG,
+ REQUIRED_ARG, 0, 0, 16384, 0, 1, 0},
+ {"tmp_table_size", OPT_TMP_TABLE_SIZE,
+ "If an in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM table.",
+ (gptr*) &global_system_variables.tmp_table_size,
+ (gptr*) &max_system_variables.tmp_table_size, 0, GET_ULONG,
+ REQUIRED_ARG, 32*1024*1024L, 1024, ~0L, 0, 1, 0},
+ {"thread_stack", OPT_THREAD_STACK,
+ "The stack size for each thread.", (gptr*) &thread_stack,
+ (gptr*) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
+ 1024*32, ~0L, 0, 1024, 0},
+ {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
+ "Allocation block size for transactions to be stored in binary log",
+ (gptr*) &global_system_variables.trans_alloc_block_size,
+ (gptr*) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
+ REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0},
+ {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
+ "Persistent buffer for transactions to be stored in binary log",
+ (gptr*) &global_system_variables.trans_prealloc_size,
+ (gptr*) &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
+ REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0},
+ {"wait_timeout", OPT_WAIT_TIMEOUT,
+ "The number of seconds the server waits for activity on a connection before closing it",
+ (gptr*) &global_system_variables.net_wait_timeout,
+ (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
+ REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
+ 0, 1, 0},
+ { "default-week-format", OPT_DEFAULT_WEEK_FORMAT,
+ "The default week format used by WEEK() functions.",
+ (gptr*) &global_system_variables.default_week_format,
+ (gptr*) &max_system_variables.default_week_format,
+ 0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-struct show_var_st init_vars[]= {
- {"back_log", (char*) &back_log, SHOW_LONG},
- {"basedir", mysql_home, SHOW_CHAR},
-#ifdef HAVE_BERKELEY_DB
- {"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
- {"bdb_log_buffer_size", (char*) &berkeley_log_buffer_size, SHOW_LONG},
- {"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
- {"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG},
- {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR},
- {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL},
- {"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR},
- {"bdb_version", (char*) DB_VERSION_STRING, SHOW_CHAR},
-#endif
- {"binlog_cache_size", (char*) &binlog_cache_size, SHOW_LONG},
- {"character_set", default_charset, SHOW_CHAR},
- {"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
- {"concurrent_insert", (char*) &myisam_concurrent_insert, SHOW_MY_BOOL},
- {"connect_timeout", (char*) &connect_timeout, SHOW_LONG},
- {"datadir", mysql_real_data_home, SHOW_CHAR},
- {"delay_key_write", (char*) &myisam_delay_key_write, SHOW_MY_BOOL},
- {"delayed_insert_limit", (char*) &delayed_insert_limit, SHOW_LONG},
- {"delayed_insert_timeout", (char*) &delayed_insert_timeout, SHOW_LONG},
- {"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG},
- {"flush", (char*) &myisam_flush, SHOW_MY_BOOL},
- {"flush_time", (char*) &flush_time, SHOW_LONG},
-#ifdef HAVE_GEMINI_DB
- {"gemini_buffer_cache", (char*) &gemini_buffer_cache, SHOW_LONG},
- {"gemini_connection_limit", (char*) &gemini_connection_limit, SHOW_LONG},
- {"gemini_io_threads", (char*) &gemini_io_threads, SHOW_LONG},
- {"gemini_log_cluster_size", (char*) &gemini_log_cluster_size, SHOW_LONG},
- {"gemini_lock_table_size", (char*) &gemini_locktablesize, SHOW_LONG},
- {"gemini_lock_wait_timeout",(char*) &gemini_lock_wait_timeout, SHOW_LONG},
- {"gemini_recovery_options", (char*) &gemini_recovery_options_str, SHOW_CHAR_PTR},
- {"gemini_spin_retries", (char*) &gemini_spin_retries, SHOW_LONG},
-#endif
- {"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
- {"have_gemini", (char*) &have_gemini, SHOW_HAVE},
- {"have_innodb", (char*) &have_innodb, SHOW_HAVE},
- {"have_isam", (char*) &have_isam, SHOW_HAVE},
- {"have_raid", (char*) &have_raid, SHOW_HAVE},
- {"have_openssl", (char*) &have_ssl, SHOW_HAVE},
- {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
-#ifdef HAVE_INNOBASE_DB
- {"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
- {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONG },
- {"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR},
- {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR},
- {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG },
- {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
- {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG },
- {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_LONG},
- {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL},
- {"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
- {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
- {"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR},
- {"innodb_log_archive", (char*) &innobase_log_archive, SHOW_MY_BOOL},
- {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG },
- {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONG},
- {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group, SHOW_LONG},
- {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR},
- {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
-#endif
- {"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG},
- {"join_buffer_size", (char*) &join_buff_size, SHOW_LONG},
- {"key_buffer_size", (char*) &keybuff_size, SHOW_LONG_AS_LONGLONG},
- {"language", language, SHOW_CHAR},
- {"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
-#ifdef HAVE_MLOCKALL
- {"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
-#endif
- {"log", (char*) &opt_log, SHOW_BOOL},
- {"log_update", (char*) &opt_update_log, SHOW_BOOL},
- {"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
- {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_BOOL},
- {"log_long_queries", (char*) &opt_slow_log, SHOW_BOOL},
- {"long_query_time", (char*) &long_query_time, SHOW_LONG},
- {"low_priority_updates", (char*) &low_priority_updates, SHOW_BOOL},
- {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_LONG},
- {"max_allowed_packet", (char*) &max_allowed_packet, SHOW_LONG},
- {"max_binlog_cache_size", (char*) &max_binlog_cache_size, SHOW_LONG},
- {"max_binlog_size", (char*) &max_binlog_size, SHOW_LONG},
- {"max_connections", (char*) &max_connections, SHOW_LONG},
- {"max_connect_errors", (char*) &max_connect_errors, SHOW_LONG},
- {"max_delayed_threads", (char*) &max_insert_delayed_threads, SHOW_LONG},
- {"max_heap_table_size", (char*) &max_heap_table_size, SHOW_LONG},
- {"max_join_size", (char*) &max_join_size, SHOW_LONG},
- {"max_sort_length", (char*) &max_item_sort_length, SHOW_LONG},
- {"max_user_connections", (char*) &max_user_connections, SHOW_LONG},
- {"max_tmp_tables", (char*) &max_tmp_tables, SHOW_LONG},
- {"max_write_lock_count", (char*) &max_write_lock_count, SHOW_LONG},
- {"myisam_max_extra_sort_file_size", (char*) &myisam_max_extra_sort_file_size,
- SHOW_LONG},
- {"myisam_max_sort_file_size",(char*) &myisam_max_sort_file_size, SHOW_LONG},
- {"myisam_recover_options", (char*) &myisam_recover_options, SHOW_LONG},
- {"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG},
-#ifdef __NT__
- {"named_pipe", (char*) &opt_enable_named_pipe, SHOW_BOOL},
-#endif
- {"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG},
- {"net_read_timeout", (char*) &net_read_timeout, SHOW_LONG},
- {"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG},
- {"net_write_timeout", (char*) &net_write_timeout, SHOW_LONG},
- {"open_files_limit", (char*) &open_files_limit, SHOW_LONG},
- {"pid_file", (char*) pidfile_name, SHOW_CHAR},
- {"port", (char*) &mysql_port, SHOW_INT},
- {"protocol_version", (char*) &protocol_version, SHOW_INT},
- {"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG},
- {"record_rnd_buffer", (char*) &record_rnd_cache_size, SHOW_LONG},
- {"query_buffer_size", (char*) &query_buff_size, SHOW_LONG},
- {"safe_show_database", (char*) &opt_safe_show_db, SHOW_BOOL},
- {"server_id", (char*) &server_id, SHOW_LONG},
- {"slave_net_timeout", (char*) &slave_net_timeout, SHOW_LONG},
- {"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
- {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
- {"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL},
- {"slow_launch_time", (char*) &slow_launch_time, SHOW_LONG},
- {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR},
- {"sort_buffer", (char*) &sortbuff_size, SHOW_LONG},
- {"sql_mode", (char*) &opt_sql_mode, SHOW_LONG},
- {"table_cache", (char*) &table_cache_size, SHOW_LONG},
- {"table_type", (char*) &default_table_type_name, SHOW_CHAR_PTR},
- {"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG},
-#ifdef HAVE_THR_SETCONCURRENCY
- {"thread_concurrency", (char*) &concurrency, SHOW_LONG},
-#endif
- {"thread_stack", (char*) &thread_stack, SHOW_LONG},
- {"transaction_isolation", (char*) &default_tx_isolation_name, SHOW_CHAR_PTR},
-#ifdef HAVE_TZNAME
- {"timezone", time_zone, SHOW_CHAR},
-#endif
- {"tmp_table_size", (char*) &tmp_table_size, SHOW_LONG},
- {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR},
- {"version", server_version, SHOW_CHAR},
- {"wait_timeout", (char*) &net_wait_timeout, SHOW_LONG},
- {NullS, NullS, SHOW_LONG}
-};
-
struct show_var_st status_vars[]= {
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
@@ -3222,16 +4133,21 @@ struct show_var_st status_vars[]= {
{"Com_create_index", (char*) (com_stat+(uint) SQLCOM_CREATE_INDEX),SHOW_LONG},
{"Com_create_table", (char*) (com_stat+(uint) SQLCOM_CREATE_TABLE),SHOW_LONG},
{"Com_delete", (char*) (com_stat+(uint) SQLCOM_DELETE),SHOW_LONG},
+ {"Com_delete_multi", (char*) (com_stat+(uint) SQLCOM_DELETE_MULTI),SHOW_LONG},
{"Com_drop_db", (char*) (com_stat+(uint) SQLCOM_DROP_DB),SHOW_LONG},
{"Com_drop_function", (char*) (com_stat+(uint) SQLCOM_DROP_FUNCTION),SHOW_LONG},
{"Com_drop_index", (char*) (com_stat+(uint) SQLCOM_DROP_INDEX),SHOW_LONG},
{"Com_drop_table", (char*) (com_stat+(uint) SQLCOM_DROP_TABLE),SHOW_LONG},
{"Com_flush", (char*) (com_stat+(uint) SQLCOM_FLUSH),SHOW_LONG},
{"Com_grant", (char*) (com_stat+(uint) SQLCOM_GRANT),SHOW_LONG},
+ {"Com_ha_close", (char*) (com_stat+(uint) SQLCOM_HA_CLOSE),SHOW_LONG},
+ {"Com_ha_open", (char*) (com_stat+(uint) SQLCOM_HA_OPEN),SHOW_LONG},
+ {"Com_ha_read", (char*) (com_stat+(uint) SQLCOM_HA_READ),SHOW_LONG},
{"Com_insert", (char*) (com_stat+(uint) SQLCOM_INSERT),SHOW_LONG},
{"Com_insert_select", (char*) (com_stat+(uint) SQLCOM_INSERT_SELECT),SHOW_LONG},
{"Com_kill", (char*) (com_stat+(uint) SQLCOM_KILL),SHOW_LONG},
{"Com_load", (char*) (com_stat+(uint) SQLCOM_LOAD),SHOW_LONG},
+ {"Com_load_master_data", (char*) (com_stat+(uint) SQLCOM_LOAD_MASTER_DATA),SHOW_LONG},
{"Com_load_master_table", (char*) (com_stat+(uint) SQLCOM_LOAD_MASTER_TABLE),SHOW_LONG},
{"Com_lock_tables", (char*) (com_stat+(uint) SQLCOM_LOCK_TABLES),SHOW_LONG},
{"Com_optimize", (char*) (com_stat+(uint) SQLCOM_OPTIMIZE),SHOW_LONG},
@@ -3244,8 +4160,10 @@ struct show_var_st status_vars[]= {
{"Com_restore_table", (char*) (com_stat+(uint) SQLCOM_RESTORE_TABLE),SHOW_LONG},
{"Com_revoke", (char*) (com_stat+(uint) SQLCOM_REVOKE),SHOW_LONG},
{"Com_rollback", (char*) (com_stat+(uint) SQLCOM_ROLLBACK),SHOW_LONG},
+ {"Com_savepoint", (char*) (com_stat+(uint) SQLCOM_SAVEPOINT),SHOW_LONG},
{"Com_select", (char*) (com_stat+(uint) SQLCOM_SELECT),SHOW_LONG},
{"Com_set_option", (char*) (com_stat+(uint) SQLCOM_SET_OPTION),SHOW_LONG},
+ {"Com_show_binlog_events", (char*) (com_stat+(uint) SQLCOM_SHOW_BINLOG_EVENTS),SHOW_LONG},
{"Com_show_binlogs", (char*) (com_stat+(uint) SQLCOM_SHOW_BINLOGS),SHOW_LONG},
{"Com_show_create", (char*) (com_stat+(uint) SQLCOM_SHOW_CREATE),SHOW_LONG},
{"Com_show_databases", (char*) (com_stat+(uint) SQLCOM_SHOW_DATABASES),SHOW_LONG},
@@ -3254,8 +4172,10 @@ struct show_var_st status_vars[]= {
{"Com_show_keys", (char*) (com_stat+(uint) SQLCOM_SHOW_KEYS),SHOW_LONG},
{"Com_show_logs", (char*) (com_stat+(uint) SQLCOM_SHOW_LOGS),SHOW_LONG},
{"Com_show_master_status", (char*) (com_stat+(uint) SQLCOM_SHOW_MASTER_STAT),SHOW_LONG},
+ {"Com_show_new_master", (char*) (com_stat+(uint) SQLCOM_SHOW_NEW_MASTER),SHOW_LONG},
{"Com_show_open_tables", (char*) (com_stat+(uint) SQLCOM_SHOW_OPEN_TABLES),SHOW_LONG},
{"Com_show_processlist", (char*) (com_stat+(uint) SQLCOM_SHOW_PROCESSLIST),SHOW_LONG},
+ {"Com_show_slave_hosts", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_HOSTS),SHOW_LONG},
{"Com_show_slave_status", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_STAT),SHOW_LONG},
{"Com_show_status", (char*) (com_stat+(uint) SQLCOM_SHOW_STATUS),SHOW_LONG},
{"Com_show_innodb_status", (char*) (com_stat+(uint) SQLCOM_SHOW_INNODB_STATUS),SHOW_LONG},
@@ -3274,6 +4194,7 @@ struct show_var_st status_vars[]= {
{"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG},
{"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG},
{"Flush_commands", (char*) &refresh_version, SHOW_LONG_CONST},
+ {"Handler_commit", (char*) &ha_commit_count, SHOW_LONG},
{"Handler_delete", (char*) &ha_delete_count, SHOW_LONG},
{"Handler_read_first", (char*) &ha_read_first_count, SHOW_LONG},
{"Handler_read_key", (char*) &ha_read_key_count, SHOW_LONG},
@@ -3281,6 +4202,7 @@ struct show_var_st status_vars[]= {
{"Handler_read_prev", (char*) &ha_read_prev_count, SHOW_LONG},
{"Handler_read_rnd", (char*) &ha_read_rnd_count, SHOW_LONG},
{"Handler_read_rnd_next", (char*) &ha_read_rnd_next_count, SHOW_LONG},
+ {"Handler_rollback", (char*) &ha_rollback_count, SHOW_LONG},
{"Handler_update", (char*) &ha_update_count, SHOW_LONG},
{"Handler_write", (char*) &ha_write_count, SHOW_LONG},
{"Key_blocks_used", (char*) &_my_blocks_used, SHOW_LONG_CONST},
@@ -3296,19 +4218,58 @@ struct show_var_st status_vars[]= {
{"Open_streams", (char*) &my_stream_opened, SHOW_LONG_CONST},
{"Opened_tables", (char*) &opened_tables, SHOW_LONG},
{"Questions", (char*) 0, SHOW_QUESTION},
+#ifdef HAVE_QUERY_CACHE
+ {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST},
+ {"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
+ {"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG},
+ {"Qcache_lowmem_prunes", (char*) &query_cache.lowmem_prunes, SHOW_LONG},
+ {"Qcache_not_cached", (char*) &query_cache.refused, SHOW_LONG},
+ {"Qcache_free_memory", (char*) &query_cache.free_memory,
+ SHOW_LONG_CONST},
+ {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks,
+ SHOW_LONG_CONST},
+ {"Qcache_total_blocks", (char*) &query_cache.total_blocks,
+ SHOW_LONG_CONST},
+#endif /*HAVE_QUERY_CACHE*/
+ {"Rpl_status", (char*) 0, SHOW_RPL_STATUS},
{"Select_full_join", (char*) &select_full_join_count, SHOW_LONG},
{"Select_full_range_join", (char*) &select_full_range_join_count, SHOW_LONG},
{"Select_range", (char*) &select_range_count, SHOW_LONG},
{"Select_range_check", (char*) &select_range_check_count, SHOW_LONG},
{"Select_scan", (char*) &select_scan_count, SHOW_LONG},
- {"Slave_running", (char*) &slave_running, SHOW_BOOL},
{"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
+ {"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING},
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
{"Slow_queries", (char*) &long_query_count, SHOW_LONG},
{"Sort_merge_passes", (char*) &filesort_merge_passes, SHOW_LONG},
{"Sort_range", (char*) &filesort_range_count, SHOW_LONG},
{"Sort_rows", (char*) &filesort_rows, SHOW_LONG},
{"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG},
+#ifdef HAVE_OPENSSL
+ {"Ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT},
+ {"Ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD},
+ {"Ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD},
+ {"Ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE},
+ {"Ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE},
+ {"Ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS},
+ {"Ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS},
+ {"Ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES},
+ {"Ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS},
+ {"Ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER},
+ {"Ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT},
+ {"Ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL},
+ {"Ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE},
+ {"Ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE},
+ {"Ssl_sessions_reused", (char*) 0, SHOW_SSL_SESSION_REUSED},
+ {"Ssl_ctx_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE},
+ {"Ssl_ctx_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH},
+ {"Ssl_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE},
+ {"Ssl_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH},
+ {"Ssl_version", (char*) 0, SHOW_SSL_GET_VERSION},
+ {"Ssl_cipher", (char*) 0, SHOW_SSL_GET_CIPHER},
+ {"Ssl_cipher_list", (char*) 0, SHOW_SSL_GET_CIPHER_LIST},
+ {"Ssl_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT},
+#endif /* HAVE_OPENSSL */
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
{"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
{"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_CONST},
@@ -3321,15 +4282,15 @@ struct show_var_st status_vars[]= {
static void print_version(void)
{
- printf("%s Ver %s for %s on %s\n",my_progname,
- server_version,SYSTEM_TYPE,MACHINE_TYPE);
+ printf("%s Ver %s for %s on %s (%s)\n",my_progname,
+ server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
}
static void use_help(void)
{
print_version();
printf("Use '--help' or '--no-defaults --help' for a list of available options\n");
-}
+}
static void usage(void)
{
@@ -3337,220 +4298,58 @@ static void usage(void)
puts("\
Copyright (C) 2000 MySQL AB, by Monty and others\n\
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
-and you are welcome to modify and redistribute it under the GPL license\n\
-Starts the MySQL server\n");
+and you are welcome to modify and redistribute it under the GPL license\n\n\
+Starts the MySQL database server\n");
printf("Usage: %s [OPTIONS]\n", my_progname);
- puts("\n\
- --ansi Use ANSI SQL syntax instead of MySQL syntax\n\
- -b, --basedir=path Path to installation directory. All paths are\n\
- usually resolved relative to this\n\
- --big-tables Allow big result sets by saving all temporary sets\n\
- on file (Solves most 'table full' errors)\n\
- --bind-address=IP Ip address to bind to\n\
- --bootstrap Used by mysql installation scripts\n\
- --character-sets-dir=...\n\
- Directory where character sets are\n\
- --chroot=path Chroot mysqld daemon during startup\n\
- --core-file Write core on errors\n\
- -h, --datadir=path Path to the database root");
-#ifndef DBUG_OFF
- printf("\
- -#, --debug[=...] Debug log. Default is '%s'\n",default_dbug_option);
-#ifdef SAFEMALLOC
- puts("\
- --skip-safemalloc Don't use the memory allocation checking");
-#endif
-#endif
- puts("\
- --default-character-set=charset\n\
- Set the default character set\n\
- --default-table-type=type\n\
- Set the default table type for tables\n\
- --delay-key-write-for-all-tables\n\
- Don't flush key buffers between writes for any MyISAM\n\
- table\n\
- --enable-locking Enable system locking\n\
- -T, --exit-info Used for debugging; Use at your own risk!\n\
- --flush Flush tables to disk between SQL commands\n\
- -?, --help Display this help and exit\n\
- --init-file=file Read SQL commands from this file at startup\n\
- -L, --language=... Client error messages in given language. May be\n\
- given as a full path\n\
- --local-infile=[1|0] Enable/disable LOAD DATA LOCAL INFILE\n\
- -l, --log[=file] Log connections and queries to file\n\
- --log-bin[=file] Log queries in new binary format (for replication)\n\
- --log-bin-index=file File that holds the names for last binary log files\n\
- --log-update[=file] Log updates to file.# where # is a unique number\n\
- if not given.\n\
- --log-isam[=file] Log all MyISAM changes to file\n\
- --log-long-format Log some extra information to update log\n\
- --low-priority-updates INSERT/DELETE/UPDATE has lower priority than selects\n\
- --log-slow-queries=[file]\n\
- Log slow queries to this log file. Defaults logging\n\
- to hostname-slow.log\n\
- --pid-file=path Pid file used by safe_mysqld\n\
- --myisam-recover[=option[,option...]] where options is one of DEAULT,\n\
- BACKUP or FORCE.\n\
- --memlock Lock mysqld in memory\n\
- -n, --new Use very new possible 'unsafe' functions\n\
- -o, --old-protocol Use the old (3.20) protocol\n\
- -P, --port=... Port number to use for connection\n");
-#ifdef ONE_THREAD
- puts("\
- --one-thread Only use one thread (for debugging under Linux)\n");
-#endif
- puts("\
- -O, --set-variable var=option\n\
- Give a variable an value. --help lists variables\n\
- -Sg, --skip-grant-tables\n\
- Start without grant tables. This gives all users\n\
- FULL ACCESS to all tables!\n\
- --safe-mode Skip some optimize stages (for testing)\n\
- --safe-show-database Don't show databases for which the user has no\n\
- privileges\n\
- --safe-user-create Don't new users cretaion without privileges to the\n\
- mysql.user table\n\
- --skip-concurrent-insert\n\
- Don't use concurrent insert with MyISAM\n\
- --skip-delay-key-write\n\
- Ignore the delay_key_write option for all tables\n\
- --skip-host-cache Don't cache host names\n\
- --skip-locking Don't use system locking. To use isamchk one has\n\
- to shut down the server.\n\
- --skip-name-resolve Don't resolve hostnames.\n\
- All hostnames are IP's or 'localhost'\n\
- --skip-networking Don't allow connection with TCP/IP.\n\
- --skip-new Don't use new, possible wrong routines.\n");
- /* We have to break the string here because of VC++ limits */
- puts("\
- --skip-stack-trace Don't print a stack trace on failure\n\
- --skip-show-database Don't allow 'SHOW DATABASE' commands\n\
- --skip-thread-priority\n\
- Don't give threads different priorities.\n\
- --socket=... Socket file to use for connection\n\
- -t, --tmpdir=path Path for temporary files\n\
- --sql-mode=option[,option[,option...]] where option can be one of:\n\
- REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES,\n\
- IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY.\n\
- --transaction-isolation\n\
- Default transaction isolation level\n\
- --temp-pool Use a pool of temporary files\n\
- -u, --user=user_name Run mysqld daemon as user\n\
- -V, --version output version information and exit\n\
- -W, --warnings Log some not critical warnings to the log file\n");
#ifdef __WIN__
puts("NT and Win32 specific options:\n\
- --console Don't remove the console window\n\
--install Install the default service (NT)\n\
--install-manual Install the default service started manually (NT)\n\
+ --install service_name Install an optional service (NT)\n\
+ --install-manual service_name Install an optional service started manually (NT)\n\
--remove Remove the default service from the service list (NT)\n\
- --enable-named-pipe Enable the named pipe (NT)\n\
- --standalone Dummy option to start as a standalone program (NT)\
+ --remove service_name Remove the service_name from the service list (NT)\n\
+ --enable-named-pipe Only to be used for the default server (NT)\n\
+ --standalone Dummy option to start as a standalone server (NT)\
");
-#ifdef USE_SYMDIR
- puts("--use-symbolic-links Enable symbolic link support");
-#endif
puts("");
#endif
-#ifdef HAVE_BERKELEY_DB
- puts("\
- --bdb-home= directory Berkeley home direcory\n\
- --bdb-lock-detect=# Berkeley lock detect\n\
- (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec)\n\
- --bdb-logdir=directory Berkeley DB log file directory\n\
- --bdb-no-sync Don't synchronously flush logs\n\
- --bdb-no-recover Don't try to recover Berkeley DB tables on start\n\
- --bdb-shared-data Start Berkeley DB in multi-process mode\n\
- --bdb-tmpdir=directory Berkeley DB tempfile name\n\
- --skip-bdb Don't use berkeley db (will save memory)\n\
-");
-#endif /* HAVE_BERKELEY_DB */
-#ifdef HAVE_GEMINI_DB
- puts("\
- --gemini-recovery=mode Set Crash Recovery operating mode\n\
- (FULL, NONE, FORCE - default FULL)\n\
- --gemini-flush-log-at-commit\n\
- Every commit forces a write to the reovery log\n\
- --gemini-unbuffered-io Use unbuffered i/o\n\
- --skip-gemini Don't use gemini (will save memory)\n\
-");
-#endif
-#ifdef HAVE_INNOBASE_DB
- puts("\
- --innodb_data_home_dir=dir The common part for Innodb table spaces\n\
- --innodb_data_file_path=dir Path to individual files and their sizes\n\
- --innodb_flush_method=# With which method to flush data\n\
- --innodb_flush_log_at_trx_commit[=#]\n\
- Value 0: write and flush once per second\n\
- Value 1: write and flush at each commit\n\
- Value 2: write at commit, flush once per second\n\
- --innodb_log_arch_dir=dir Where full logs should be archived\n\
- --innodb_log_archive[=#] Set to 1 if you want to have logs archived\n\
- --innodb_log_group_home_dir=dir Path to innodb log files.\n\
- --skip-innodb Don't use Innodb (will save memory)\n\
-");
-#endif /* HAVE_INNOBASE_DB */
print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
puts("");
-
-#include "sslopt-usage.h"
-
fix_paths();
set_ports();
- printf("\
-To see what values a running MySQL server is using, type\n\
-'mysqladmin variables' instead of 'mysqld --help'.\n\
-The default values (after parsing the command line arguments) are:\n\n");
- printf("basedir: %s\n",mysql_home);
- printf("datadir: %s\n",mysql_real_data_home);
- printf("tmpdir: %s\n",mysql_tmpdir);
- printf("language: %s\n",language);
-#ifndef __WIN__
- printf("pid file: %s\n",pidfile_name);
-#endif
- if (opt_logname)
- printf("logfile: %s\n",opt_logname);
- if (opt_update_logname)
- printf("update log: %s\n",opt_update_logname);
- if (opt_bin_log)
- {
- printf("binary log: %s\n",opt_bin_logname ? opt_bin_logname : "");
- printf("binary log index: %s\n",
- opt_binlog_index_name ? opt_binlog_index_name : "");
- }
- if (opt_slow_logname)
- printf("update log: %s\n",opt_slow_logname);
- printf("TCP port: %d\n",mysql_port);
-#if defined(HAVE_SYS_UN_H)
- printf("Unix socket: %s\n",mysql_unix_port);
-#endif
- if (my_disable_locking)
- puts("\nsystem locking is not in use");
- if (opt_noacl)
- puts("\nGrant tables are not used. All users have full access rights");
- printf("\nPossible variables for option --set-variable (-O) are:\n");
- for (uint i=0 ; changeable_vars[i].name ; i++)
- printf("%-20s current value: %lu\n",
- changeable_vars[i].name,
- (ulong) *changeable_vars[i].varptr);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+
+ puts("\n\
+To see what values a running MySQL server is using, type\n\
+'mysqladmin variables' instead of 'mysqld --help'.");
}
static void set_options(void)
{
- set_all_changeable_vars( changeable_vars );
#if !defined( my_pthread_setprio ) && !defined( HAVE_PTHREAD_SETSCHEDPARAM )
opt_specialflag |= SPECIAL_NO_PRIOR;
#endif
- (void) strmake(default_charset, MYSQL_CHARSET, sizeof(default_charset)-1);
+ sys_charset.value= (char*) MYSQL_CHARSET;
(void) strmake(language, LANGUAGE, sizeof(language)-1);
(void) strmake(mysql_real_data_home, get_relative_path(DATADIR),
sizeof(mysql_real_data_home)-1);
-#ifdef __WIN__
- /* Allow Win32 users to move MySQL anywhere */
+
+ /* Set default values for some variables */
+ global_system_variables.table_type=DB_TYPE_MYISAM;
+ global_system_variables.tx_isolation=ISO_REPEATABLE_READ;
+ global_system_variables.select_limit= HA_POS_ERROR;
+ max_system_variables.select_limit= HA_POS_ERROR;
+ global_system_variables.max_join_size= HA_POS_ERROR;
+ max_system_variables.max_join_size= HA_POS_ERROR;
+
+#if defined(__WIN__) || defined(__NETWARE__)
+ /* Allow Win32 and NetWare users to move MySQL anywhere */
{
char prg_dev[LIBLEN];
my_path(prg_dev,my_progname,"mysql/bin");
@@ -3564,640 +4363,535 @@ static void set_options(void)
(void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
#endif
-#if defined( HAVE_mit_thread ) || defined( __WIN__ ) || defined( HAVE_LINUXTHREADS )
- my_disable_locking = 1;
-#endif
+ my_disable_locking=myisam_single_user= 1;
+ opt_external_locking=0;
my_bind_addr = htonl( INADDR_ANY );
}
- /* Initiates DEBUG - but no debugging here ! */
-static void get_options(int argc,char **argv)
-{
- int c,option_index=0;
- myisam_delay_key_write=1; // Allow use of this
- while ((c=getopt_long(argc,argv,"ab:C:h:#::T::?l::L:O:P:sS::t:u:noVvWI?",
- long_options, &option_index)) != EOF)
- {
- switch(c) {
- case '#':
+extern "C" my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case '#':
#ifndef DBUG_OFF
- DBUG_PUSH(optarg ? optarg : default_dbug_option);
-#endif
- opt_endinfo=1; /* unireg: memory allocation */
- break;
- case 'W':
- opt_warnings=1;
- break;
- case 'a':
- opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT |
- MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE
- | MODE_ONLY_FULL_GROUP_BY);
- default_tx_isolation= ISO_SERIALIZABLE;
- break;
- case 'b':
- strmake(mysql_home,optarg,sizeof(mysql_home)-1);
- break;
- case 'l':
- opt_log=1;
- opt_logname=optarg; // Use hostname.log if null
- break;
- case 'h':
- strmake(mysql_real_data_home,optarg, sizeof(mysql_real_data_home)-1);
- break;
- case 'L':
- strmake(language, optarg, sizeof(language)-1);
- break;
- case 'n':
- opt_specialflag|= SPECIAL_NEW_FUNC;
- break;
- case 'o':
- protocol_version=PROTOCOL_VERSION-1;
- break;
- case 'O':
- if (set_changeable_var(optarg, changeable_vars))
- {
- use_help();
- exit(1);
- }
- break;
- case 'P':
- mysql_port= (unsigned int) atoi(optarg);
- break;
- case OPT_LOCAL_INFILE:
- opt_local_infile= test(!optarg || atoi(optarg) != 0);
- break;
- case OPT_SLAVE_SKIP_ERRORS:
- init_slave_skip_errors(optarg);
- break;
- case OPT_SAFEMALLOC_MEM_LIMIT:
-#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
- safemalloc_mem_limit = atoi(optarg);
-#endif
- break;
- case OPT_SOCKET:
- mysql_unix_port= optarg;
- break;
- case 'r':
- mysqld_chroot=optarg;
- break;
-#ifdef USE_SYMDIR
- case 's':
- my_use_symdir=1; /* Use internal symbolic links */
- break;
-#endif
- case 't':
- mysql_tmpdir=optarg;
- break;
- case OPT_TEMP_POOL:
- use_temp_pool=1;
- break;
- case 'u':
- if (!mysqld_user)
- mysqld_user=optarg;
- else
- fprintf(stderr, "Warning: Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", optarg, mysqld_user);
- break;
- case 'v':
- case 'V':
- print_version();
- exit(0);
- case 'I':
- case '?':
- usage();
- exit(0);
- case 'T':
- test_flags= optarg ? (uint) atoi(optarg) : 0;
- opt_endinfo=1;
- break;
- case 'S':
- if (!optarg)
- opt_specialflag|= SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE;
- else if (!strcmp(optarg,"l"))
- my_disable_locking=1;
- else if (!strcmp(optarg,"g"))
- opt_noacl=1;
- else
- {
- fprintf(stderr,"%s: Unrecognized option: %s\n",my_progname,optarg);
- use_help();
- exit(1);
- }
- break;
- case (int) OPT_BIG_TABLES:
- thd_startup_options|=OPTION_BIG_TABLES;
- break;
- case (int) OPT_ISAM_LOG:
- opt_myisam_log=1;
- if (optarg)
- myisam_log_filename=optarg;
- break;
- case (int) OPT_UPDATE_LOG:
- opt_update_log=1;
- opt_update_logname=optarg; // Use hostname.# if null
- break;
- case (int) OPT_BIN_LOG_INDEX:
- opt_binlog_index_name = optarg;
- break;
- case (int) OPT_BIN_LOG:
- opt_bin_log=1;
- x_free(opt_bin_logname);
- if (optarg && optarg[0])
- opt_bin_logname=my_strdup(optarg,MYF(0));
- break;
- // needs to be handled (as no-op) in non-debugging mode for test suite
- case (int)OPT_DISCONNECT_SLAVE_EVENT_COUNT:
-#ifndef DBUG_OFF
- disconnect_slave_event_count = atoi(optarg);
-#endif
- break;
- case (int)OPT_ABORT_SLAVE_EVENT_COUNT:
-#ifndef DBUG_OFF
- abort_slave_event_count = atoi(optarg);
-#endif
- break;
- case (int)OPT_SPORADIC_BINLOG_DUMP_FAIL:
-#ifndef DBUG_OFF
- opt_sporadic_binlog_dump_fail = 1;
-#endif
- break;
- case (int)OPT_MAX_BINLOG_DUMP_EVENTS:
-#ifndef DBUG_OFF
- max_binlog_dump_events = atoi(optarg);
-#endif
- break;
-
- case (int) OPT_LOG_SLAVE_UPDATES:
- opt_log_slave_updates = 1;
- break;
+ DBUG_PUSH(argument ? argument : default_dbug_option);
+#endif
+ opt_endinfo=1; /* unireg: memory allocation */
+ break;
+ case 'a':
+ opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT |
+ MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE
+ | MODE_ONLY_FULL_GROUP_BY);
+ global_system_variables.tx_isolation= ISO_SERIALIZABLE;
+ break;
+ case 'b':
+ strmake(mysql_home,argument,sizeof(mysql_home)-1);
+ break;
+ case 'l':
+ opt_log=1;
+ break;
+ case 'h':
+ strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
+ /* Correct pointer set by my_getopt (for embedded library) */
+ mysql_data_home= mysql_real_data_home;
+ break;
+ case 'u':
+ if (!mysqld_user)
+ mysqld_user= argument;
+ else
+ fprintf(stderr, "Warning: Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
+ break;
+ case 'L':
+ strmake(language, argument, sizeof(language)-1);
+ break;
+ case 'o':
+ protocol_version=PROTOCOL_VERSION-1;
+ break;
+ case OPT_SLAVE_SKIP_ERRORS:
+ init_slave_skip_errors(argument);
+ break;
+ case OPT_SAFEMALLOC_MEM_LIMIT:
+#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
+ sf_malloc_mem_limit = atoi(argument);
+#endif
+ break;
+#ifdef EMBEDDED_LIBRARY
+ case OPT_MAX_ALLOWED_PACKET:
+ max_allowed_packet= atoi(argument);
+ break;
+ case OPT_NET_BUFFER_LENGTH:
+ net_buffer_length= atoi(argument);
+ break;
+#endif
+#include <sslopt-case.h>
+ case 'v':
+ case 'V':
+ print_version();
+ exit(0);
+ case 'I':
+ case '?':
+ usage();
+ exit(0);
+ case 'T':
+ test_flags= argument ? (uint) atoi(argument) : 0;
+ test_flags&= ~TEST_NO_THREADS;
+ opt_endinfo=1;
+ break;
+ case (int) OPT_BIG_TABLES:
+ thd_startup_options|=OPTION_BIG_TABLES;
+ break;
+ case (int) OPT_ISAM_LOG:
+ opt_myisam_log=1;
+ break;
+ case (int) OPT_UPDATE_LOG:
+ opt_update_log=1;
+ break;
+ case (int) OPT_BIN_LOG:
+ opt_bin_log=1;
+ break;
+ case (int) OPT_ERROR_LOG_FILE:
+ opt_error_log= 1;
+ break;
+ case (int) OPT_INIT_RPL_ROLE:
+ {
+ int role;
+ if ((role=find_type(argument, &rpl_role_typelib, 2)) <= 0)
+ {
+ fprintf(stderr, "Unknown replication role: %s\n", argument);
+ exit(1);
+ }
+ rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
+ break;
+ }
+ case (int)OPT_REPLICATE_IGNORE_DB:
+ {
+ i_string *db = new i_string(argument);
+ replicate_ignore_db.push_back(db);
+ break;
+ }
+ case (int)OPT_REPLICATE_DO_DB:
+ {
+ i_string *db = new i_string(argument);
+ replicate_do_db.push_back(db);
+ break;
+ }
+ case (int)OPT_REPLICATE_REWRITE_DB:
+ {
+ char* key = argument,*p, *val;
+
+ if (!(p= strstr(argument, "->")))
+ {
+ fprintf(stderr,
+ "Bad syntax in replicate-rewrite-db - missing '->'!\n");
+ exit(1);
+ }
+ val= p--;
+ while (isspace(*p) && p > argument)
+ *p-- = 0;
+ if (p == argument)
+ {
+ fprintf(stderr,
+ "Bad syntax in replicate-rewrite-db - empty FROM db!\n");
+ exit(1);
+ }
+ *val= 0;
+ val+= 2;
+ while (*val && isspace(*val))
+ *val++;
+ if (!*val)
+ {
+ fprintf(stderr,
+ "Bad syntax in replicate-rewrite-db - empty TO db!\n");
+ exit(1);
+ }
- case (int)OPT_REPLICATE_IGNORE_DB:
- {
- i_string *db = new i_string(optarg);
- replicate_ignore_db.push_back(db);
- break;
- }
- case (int)OPT_REPLICATE_DO_DB:
- {
- i_string *db = new i_string(optarg);
- replicate_do_db.push_back(db);
- break;
- }
- case (int)OPT_REPLICATE_REWRITE_DB:
- {
- char* key = optarg,*p, *val;
- p = strstr(optarg, "->");
- if (!p)
- {
- fprintf(stderr,
- "Bad syntax in replicate-rewrite-db - missing '->'!\n");
- exit(1);
- }
- val = p--;
- while(isspace(*p) && p > optarg) *p-- = 0;
- if(p == optarg)
- {
- fprintf(stderr,
- "Bad syntax in replicate-rewrite-db - empty FROM db!\n");
- exit(1);
- }
- *val = 0;
- val += 2;
- while(*val && isspace(*val)) *val++;
- if (!*val)
- {
- fprintf(stderr,
- "Bad syntax in replicate-rewrite-db - empty TO db!\n");
- exit(1);
- }
-
- i_string_pair* db_pair = new i_string_pair(key, val);
- replicate_rewrite_db.push_back(db_pair);
- break;
- }
+ i_string_pair *db_pair = new i_string_pair(key, val);
+ replicate_rewrite_db.push_back(db_pair);
+ break;
+ }
- case (int)OPT_BINLOG_IGNORE_DB:
- {
- i_string *db = new i_string(optarg);
- binlog_ignore_db.push_back(db);
- break;
- }
- case (int)OPT_BINLOG_DO_DB:
- {
- i_string *db = new i_string(optarg);
- binlog_do_db.push_back(db);
- break;
- }
- case (int)OPT_REPLICATE_DO_TABLE:
- {
- if (!do_table_inited)
- init_table_rule_hash(&replicate_do_table, &do_table_inited);
- if(add_table_rule(&replicate_do_table, optarg))
- {
- fprintf(stderr, "Could not add do table rule '%s'!\n", optarg);
- exit(1);
- }
- table_rules_on = 1;
- break;
- }
- case (int)OPT_REPLICATE_WILD_DO_TABLE:
- {
- if (!wild_do_table_inited)
- init_table_rule_array(&replicate_wild_do_table,
- &wild_do_table_inited);
- if(add_wild_table_rule(&replicate_wild_do_table, optarg))
- {
- fprintf(stderr, "Could not add do table rule '%s'!\n", optarg);
- exit(1);
- }
- table_rules_on = 1;
- break;
- }
- case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
- {
- if (!wild_ignore_table_inited)
- init_table_rule_array(&replicate_wild_ignore_table,
- &wild_ignore_table_inited);
- if(add_wild_table_rule(&replicate_wild_ignore_table, optarg))
- {
- fprintf(stderr, "Could not add ignore table rule '%s'!\n", optarg);
- exit(1);
- }
- table_rules_on = 1;
- break;
- }
- case (int)OPT_REPLICATE_IGNORE_TABLE:
- {
- if (!ignore_table_inited)
- init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited);
- if(add_table_rule(&replicate_ignore_table, optarg))
- {
- fprintf(stderr, "Could not add ignore table rule '%s'!\n", optarg);
- exit(1);
- }
- table_rules_on = 1;
- break;
- }
- case (int) OPT_SQL_BIN_UPDATE_SAME:
- opt_sql_bin_update = 1;
- break;
- case (int) OPT_SLOW_QUERY_LOG:
- opt_slow_log=1;
- opt_slow_logname=optarg;
- break;
- case (int)OPT_SKIP_SLAVE_START:
- opt_skip_slave_start = 1;
- break;
- case (int) OPT_SKIP_NEW:
- opt_specialflag|= SPECIAL_NO_NEW_FUNC;
- default_table_type=DB_TYPE_ISAM;
- myisam_delay_key_write=0;
- myisam_concurrent_insert=0;
- myisam_recover_options= HA_RECOVER_NONE;
- my_disable_symlinks=1;
- ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
- break;
- case (int) OPT_SAFE:
- opt_specialflag|= SPECIAL_SAFE_MODE;
- myisam_delay_key_write=0;
- myisam_recover_options= HA_RECOVER_NONE; // To be changed
- ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
- break;
- case (int) OPT_SKIP_CONCURRENT_INSERT:
- myisam_concurrent_insert=0;
- break;
- case (int) OPT_SKIP_PRIOR:
- opt_specialflag|= SPECIAL_NO_PRIOR;
- break;
- case (int) OPT_SKIP_GRANT:
- opt_noacl=1;
- break;
- case (int) OPT_SKIP_LOCK:
- my_disable_locking=1;
- break;
- case (int) OPT_SKIP_HOST_CACHE:
- opt_specialflag|= SPECIAL_NO_HOST_CACHE;
- break;
- case (int) OPT_ENABLE_LOCK:
- my_disable_locking=0;
- break;
- case (int) OPT_USE_LOCKING:
- my_disable_locking=0;
- break;
- case (int) OPT_SKIP_RESOLVE:
- opt_specialflag|=SPECIAL_NO_RESOLVE;
- break;
- case (int) OPT_LONG_FORMAT:
- opt_specialflag|=SPECIAL_LONG_LOG_FORMAT;
- break;
- case (int) OPT_SKIP_NETWORKING:
- opt_disable_networking=1;
- mysql_port=0;
- break;
- case (int) OPT_SKIP_SHOW_DB:
- opt_skip_show_db=1;
- opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
- break;
- case (int) OPT_MEMLOCK:
- locked_in_memory=1;
- break;
- case (int) OPT_ONE_THREAD:
- test_flags |= TEST_NO_THREADS;
- break;
- case (int) OPT_WANT_CORE:
- test_flags |= TEST_CORE_ON_SIGNAL;
- break;
- case (int) OPT_SKIP_STACK_TRACE:
- test_flags|=TEST_NO_STACKTRACE;
- break;
- case (int) OPT_SKIP_SYMLINKS:
- my_disable_symlinks=1;
- break;
- case (int) OPT_BIND_ADDRESS:
- if (optarg && isdigit(optarg[0]))
- {
- my_bind_addr = (ulong) inet_addr(optarg);
- }
+ case (int)OPT_BINLOG_IGNORE_DB:
+ {
+ i_string *db = new i_string(argument);
+ binlog_ignore_db.push_back(db);
+ break;
+ }
+ case (int)OPT_BINLOG_DO_DB:
+ {
+ i_string *db = new i_string(argument);
+ binlog_do_db.push_back(db);
+ break;
+ }
+ case (int)OPT_REPLICATE_DO_TABLE:
+ {
+ if (!do_table_inited)
+ init_table_rule_hash(&replicate_do_table, &do_table_inited);
+ if (add_table_rule(&replicate_do_table, argument))
+ {
+ fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
+ exit(1);
+ }
+ table_rules_on = 1;
+ break;
+ }
+ case (int)OPT_REPLICATE_WILD_DO_TABLE:
+ {
+ if (!wild_do_table_inited)
+ init_table_rule_array(&replicate_wild_do_table,
+ &wild_do_table_inited);
+ if (add_wild_table_rule(&replicate_wild_do_table, argument))
+ {
+ fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
+ exit(1);
+ }
+ table_rules_on = 1;
+ break;
+ }
+ case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
+ {
+ if (!wild_ignore_table_inited)
+ init_table_rule_array(&replicate_wild_ignore_table,
+ &wild_ignore_table_inited);
+ if (add_wild_table_rule(&replicate_wild_ignore_table, argument))
+ {
+ fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
+ exit(1);
+ }
+ table_rules_on = 1;
+ break;
+ }
+ case (int)OPT_REPLICATE_IGNORE_TABLE:
+ {
+ if (!ignore_table_inited)
+ init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited);
+ if (add_table_rule(&replicate_ignore_table, argument))
+ {
+ fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
+ exit(1);
+ }
+ table_rules_on = 1;
+ break;
+ }
+ case (int) OPT_SLOW_QUERY_LOG:
+ opt_slow_log=1;
+ break;
+ case (int)OPT_RECKLESS_SLAVE:
+ opt_reckless_slave = 1;
+ init_slave_skip_errors("all");
+ break;
+ case (int) OPT_SKIP_NEW:
+ opt_specialflag|= SPECIAL_NO_NEW_FUNC;
+ delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
+ myisam_concurrent_insert=0;
+ myisam_recover_options= HA_RECOVER_NONE;
+ my_use_symdir=0;
+ ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
+#ifdef HAVE_QUERY_CACHE
+ query_cache_size=0;
+#endif
+ break;
+ case (int) OPT_SAFE:
+ opt_specialflag|= SPECIAL_SAFE_MODE;
+ delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
+ myisam_recover_options= HA_RECOVER_DEFAULT;
+ ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
+ break;
+ case (int) OPT_SKIP_PRIOR:
+ opt_specialflag|= SPECIAL_NO_PRIOR;
+ break;
+ case (int) OPT_SKIP_LOCK:
+ opt_external_locking=0;
+ break;
+ case (int) OPT_SKIP_HOST_CACHE:
+ opt_specialflag|= SPECIAL_NO_HOST_CACHE;
+ break;
+ case (int) OPT_SKIP_RESOLVE:
+ opt_specialflag|=SPECIAL_NO_RESOLVE;
+ break;
+ case (int) OPT_LONG_FORMAT:
+ opt_specialflag|=SPECIAL_LONG_LOG_FORMAT;
+ break;
+ case (int) OPT_SKIP_NETWORKING:
+ opt_disable_networking=1;
+ mysql_port=0;
+ break;
+ case (int) OPT_SKIP_SHOW_DB:
+ opt_skip_show_db=1;
+ opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
+ break;
+#ifdef ONE_THREAD
+ case (int) OPT_ONE_THREAD:
+ test_flags |= TEST_NO_THREADS;
+#endif
+ break;
+ case (int) OPT_WANT_CORE:
+ test_flags |= TEST_CORE_ON_SIGNAL;
+ break;
+ case (int) OPT_SKIP_STACK_TRACE:
+ test_flags|=TEST_NO_STACKTRACE;
+ break;
+ case (int) OPT_SKIP_SYMLINKS:
+ my_use_symdir=0;
+ break;
+ case (int) OPT_BIND_ADDRESS:
+ if (isdigit(argument[0]))
+ {
+ my_bind_addr = (ulong) inet_addr(argument);
+ }
+ else
+ {
+ struct hostent *ent;
+ if (argument[0])
+ ent=gethostbyname(argument);
else
{
- struct hostent *ent;
- if (optarg && optarg[0])
- ent=gethostbyname(optarg);
- else
+ char myhostname[255];
+ if (gethostname(myhostname,sizeof(myhostname)) < 0)
{
- char myhostname[255];
- if (gethostname(myhostname,sizeof(myhostname)) < 0)
- {
- sql_perror("Can't start server: cannot get my own hostname!");
- exit(1);
- }
- ent=gethostbyname(myhostname);
- }
- if (!ent)
- {
- sql_perror("Can't start server: cannot resolve hostname!");
+ sql_perror("Can't start server: cannot get my own hostname!");
exit(1);
}
- my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr;
+ ent=gethostbyname(myhostname);
}
- break;
- case (int) OPT_PID_FILE:
- strmake(pidfile_name, optarg, sizeof(pidfile_name)-1);
- break;
- case (int) OPT_INIT_FILE:
- opt_init_file=optarg;
- break;
- case (int) OPT_HAVE_NAMED_PIPE:
-#if __NT__
- opt_enable_named_pipe=1;
-#endif
- break;
-#ifdef __WIN__
- case (int) OPT_STANDALONE: /* Dummy option for NT */
- break;
- case (int) OPT_CONSOLE:
- opt_console=1;
- break;
-#endif
- case (int) OPT_FLUSH:
- nisam_flush=myisam_flush=1;
- flush_time=0; // No auto flush
- break;
- case OPT_LOW_PRIORITY_UPDATES:
- thd_startup_options|=OPTION_LOW_PRIORITY_UPDATES;
- thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
- low_priority_updates=1;
- break;
- case OPT_BOOTSTRAP:
- opt_noacl=opt_bootstrap=1;
- break;
- case OPT_TABLE_TYPE:
- {
- int type;
- if ((type=find_type(optarg, &ha_table_typelib, 2)) <= 0)
+ if (!ent)
{
- fprintf(stderr,"Unknown table type: %s\n",optarg);
+ sql_perror("Can't start server: cannot resolve hostname!");
exit(1);
}
- default_table_type= (enum db_type) type;
- break;
+ my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr;
}
- case OPT_SERVER_ID:
- server_id = atol(optarg);
- server_id_supplied = 1;
- break;
- case OPT_DELAY_KEY_WRITE:
- ha_open_options|=HA_OPEN_DELAY_KEY_WRITE;
- myisam_delay_key_write=1;
- break;
- case OPT_SKIP_DELAY_KEY_WRITE:
- myisam_delay_key_write=0;
- break;
- case 'C':
- strmake(default_charset, optarg, sizeof(default_charset)-1);
- break;
- case OPT_CHARSETS_DIR:
- strmake(mysql_charsets_dir, optarg, sizeof(mysql_charsets_dir)-1);
- charsets_dir = mysql_charsets_dir;
- break;
-#include "sslopt-case.h"
- case OPT_TX_ISOLATION:
+ break;
+ case (int) OPT_PID_FILE:
+ strmake(pidfile_name, argument, sizeof(pidfile_name)-1);
+ break;
+#ifdef __WIN__
+ case (int) OPT_STANDALONE: /* Dummy option for NT */
+ break;
+#endif
+ case OPT_CONSOLE:
+ if (opt_console)
+ opt_error_log= 0; // Force logs to stdout
+ break;
+ case (int) OPT_FLUSH:
+#ifdef HAVE_ISAM
+ nisam_flush=1;
+#endif
+ myisam_flush=1;
+ flush_time=0; // No auto flush
+ break;
+ case OPT_LOW_PRIORITY_UPDATES:
+ thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
+ global_system_variables.low_priority_updates=1;
+ break;
+ case OPT_BOOTSTRAP:
+ opt_noacl=opt_bootstrap=1;
+ break;
+ case OPT_TABLE_TYPE:
+ {
+ int type;
+ if ((type=find_type(argument, &ha_table_typelib, 2)) <= 0)
+ {
+ fprintf(stderr,"Unknown table type: %s\n",argument);
+ exit(1);
+ }
+ global_system_variables.table_type= type-1;
+ break;
+ }
+ case OPT_SERVER_ID:
+ server_id_supplied = 1;
+ break;
+ case OPT_DELAY_KEY_WRITE_ALL:
+ if (argument != disabled_my_option)
+ argument= (char*) "ALL";
+ /* Fall through */
+ case OPT_DELAY_KEY_WRITE:
+ if (argument == disabled_my_option)
+ delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
+ else if (! argument)
+ delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
+ else
{
int type;
- if ((type=find_type(optarg, &tx_isolation_typelib, 2)) <= 0)
+ if ((type=find_type(argument, &delay_key_write_typelib, 2)) <= 0)
{
- fprintf(stderr,"Unknown transaction isolation type: %s\n",optarg);
+ fprintf(stderr,"Unknown delay_key_write type: %s\n",argument);
exit(1);
}
- default_tx_isolation= (enum_tx_isolation) (type-1);
- break;
+ delay_key_write_options= (uint) type-1;
+ }
+ break;
+ case OPT_CHARSETS_DIR:
+ strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
+ charsets_dir = mysql_charsets_dir;
+ break;
+ case OPT_TX_ISOLATION:
+ {
+ int type;
+ if ((type=find_type(argument, &tx_isolation_typelib, 2)) <= 0)
+ {
+ fprintf(stderr,"Unknown transaction isolation type: %s\n",argument);
+ exit(1);
}
+ global_system_variables.tx_isolation= (type-1);
+ break;
+ }
#ifdef HAVE_BERKELEY_DB
- case OPT_BDB_LOG:
- berkeley_logdir=optarg;
- break;
- case OPT_BDB_HOME:
- berkeley_home=optarg;
- break;
- case OPT_BDB_NOSYNC:
- berkeley_env_flags|=DB_TXN_NOSYNC;
- break;
- case OPT_BDB_NO_RECOVER:
- berkeley_init_flags&= ~(DB_RECOVER);
- break;
- case OPT_BDB_TMP:
- berkeley_tmpdir=optarg;
- break;
- case OPT_BDB_LOCK:
+ case OPT_BDB_NOSYNC:
+ /* Deprecated option */
+ opt_sync_bdb_logs= 0;
+ /* Fall through */
+ case OPT_BDB_SYNC:
+ if (!opt_sync_bdb_logs)
+ berkeley_env_flags|= DB_TXN_NOSYNC;
+ else
+ berkeley_env_flags&= ~DB_TXN_NOSYNC;
+ break;
+ case OPT_BDB_NO_RECOVER:
+ berkeley_init_flags&= ~(DB_RECOVER);
+ break;
+ case OPT_BDB_LOCK:
+ {
+ int type;
+ if ((type=find_type(argument, &berkeley_lock_typelib, 2)) > 0)
+ berkeley_lock_type=berkeley_lock_types[type-1];
+ else
{
- int type;
- if ((type=find_type(optarg, &berkeley_lock_typelib, 2)) > 0)
- berkeley_lock_type=berkeley_lock_types[type-1];
+ if (test_if_int(argument,(uint) strlen(argument)))
+ berkeley_lock_scan_time=atoi(argument);
else
{
- if (test_if_int(optarg,(uint) strlen(optarg)))
- berkeley_lock_scan_time=atoi(optarg);
- else
- {
- fprintf(stderr,"Unknown lock type: %s\n",optarg);
- exit(1);
- }
+ fprintf(stderr,"Unknown lock type: %s\n",argument);
+ exit(1);
}
- break;
}
- case OPT_BDB_SHARED:
- berkeley_init_flags&= ~(DB_PRIVATE);
- berkeley_shared_data=1;
- break;
+ break;
+ }
+ case OPT_BDB_SHARED:
+ berkeley_init_flags&= ~(DB_PRIVATE);
+ berkeley_shared_data=1;
+ break;
#endif /* HAVE_BERKELEY_DB */
- case OPT_BDB_SKIP:
+ case OPT_BDB_SKIP:
#ifdef HAVE_BERKELEY_DB
- berkeley_skip=1;
- have_berkeley_db=SHOW_OPTION_DISABLED;
+ berkeley_skip=1;
+ have_berkeley_db=SHOW_OPTION_DISABLED;
#endif
- break;
- case OPT_GEMINI_SKIP:
-#ifdef HAVE_GEMINI_DB
- gemini_skip=1;
- have_gemini=SHOW_OPTION_DISABLED;
- break;
- case OPT_GEMINI_RECOVER:
- gemini_recovery_options_str=optarg;
- if ((gemini_recovery_options=
- find_bit_type(optarg, &gemini_recovery_typelib)) == ~(ulong) 0)
- {
- fprintf(stderr, "Unknown option to gemini-recovery: %s\n",optarg);
- exit(1);
- }
- break;
- case OPT_GEMINI_FLUSH_LOG:
- gemini_options |= GEMOPT_FLUSH_LOG;
- break;
- case OPT_GEMINI_UNBUFFERED_IO:
- gemini_options |= GEMOPT_UNBUFFERED_IO;
-#endif
- break;
- case OPT_INNODB_SKIP:
+ break;
+ case OPT_INNODB_SKIP:
#ifdef HAVE_INNOBASE_DB
- innodb_skip=1;
- have_innodb=SHOW_OPTION_DISABLED;
+ innodb_skip=1;
+ have_innodb=SHOW_OPTION_DISABLED;
#endif
- break;
- case OPT_INNODB_DATA_FILE_PATH:
+ break;
+ case OPT_INNODB_DATA_FILE_PATH:
#ifdef HAVE_INNOBASE_DB
- innobase_data_file_path=optarg;
+ innobase_data_file_path=argument;
#endif
- break;
+ break;
#ifdef HAVE_INNOBASE_DB
- case OPT_INNODB_DATA_HOME_DIR:
- innobase_data_home_dir=optarg;
- break;
- case OPT_INNODB_LOG_GROUP_HOME_DIR:
- innobase_log_group_home_dir=optarg;
- break;
- case OPT_INNODB_LOG_ARCH_DIR:
- innobase_log_arch_dir=optarg;
- break;
- case OPT_INNODB_LOG_ARCHIVE:
- innobase_log_archive= optarg ? test(atoi(optarg)) : 1;
- break;
- case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT:
- innobase_flush_log_at_trx_commit= optarg ? atoi(optarg) : 1;
- break;
- case OPT_INNODB_FAST_SHUTDOWN:
- innobase_fast_shutdown= optarg ? test(atoi(optarg)) : 1;
- break;
- case OPT_INNODB_UNIX_FILE_FLUSH_METHOD:
- innobase_unix_file_flush_method=optarg;
- break;
+ case OPT_INNODB_LOG_ARCHIVE:
+ innobase_log_archive= argument ? test(atoi(argument)) : 1;
+ break;
+ case OPT_INNODB_FAST_SHUTDOWN:
+ innobase_fast_shutdown= argument ? test(atoi(argument)) : 1;
+ break;
#endif /* HAVE_INNOBASE_DB */
- case OPT_MYISAM_RECOVER:
+ case OPT_MYISAM_RECOVER:
+ {
+ if (!argument || !argument[0])
{
- if (!optarg)
- {
- myisam_recover_options= HA_RECOVER_DEFAULT;
- myisam_recover_options_str= myisam_recover_typelib.type_names[0];
- }
- else
- {
- myisam_recover_options_str=optarg;
- if ((myisam_recover_options=
- find_bit_type(optarg, &myisam_recover_typelib)) == ~(ulong) 0)
- {
- fprintf(stderr, "Unknown option to myisam-recover: %s\n",optarg);
- exit(1);
- }
- }
- ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
- break;
+ myisam_recover_options= HA_RECOVER_DEFAULT;
+ myisam_recover_options_str= myisam_recover_typelib.type_names[0];
}
- case OPT_SQL_MODE:
+ else
{
- sql_mode_str = optarg;
- if ((opt_sql_mode =
- find_bit_type(optarg, &sql_mode_typelib)) == ~(ulong) 0)
+ myisam_recover_options_str=argument;
+ if ((myisam_recover_options=
+ find_bit_type(argument, &myisam_recover_typelib)) == ~(ulong) 0)
{
- fprintf(stderr, "Unknown option to sql-mode: %s\n", optarg);
+ fprintf(stderr, "Unknown option to myisam-recover: %s\n",argument);
exit(1);
}
- default_tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ?
- ISO_SERIALIZABLE :
- ISO_READ_COMMITTED);
- break;
}
- case OPT_MASTER_HOST:
- master_host=optarg;
- break;
- case OPT_MASTER_USER:
- master_user=optarg;
- break;
- case OPT_MASTER_PASSWORD:
- master_password=optarg;
- break;
- case OPT_MASTER_INFO_FILE:
- master_info_file=optarg;
- break;
- case OPT_MASTER_PORT:
- master_port= atoi(optarg);
- break;
- case OPT_MASTER_CONNECT_RETRY:
- master_connect_retry= atoi(optarg);
- break;
- case OPT_MASTER_RETRY_COUNT:
- master_retry_count= atoi(optarg);
- break;
- case OPT_SAFE_SHOW_DB:
- opt_safe_show_db=1;
- break;
- case OPT_SAFE_USER_CREATE:
- opt_safe_user_create=1;
- break;
- case OPT_SKIP_SAFEMALLOC:
-#ifdef SAFEMALLOC
- sf_malloc_quick=1;
-#endif
- break;
- default:
- fprintf(stderr,"%s: Unrecognized option: %c\n",my_progname,c);
- use_help();
+ ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
+ break;
+ }
+ case OPT_SQL_MODE:
+ {
+ sql_mode_str = argument;
+ if ((opt_sql_mode =
+ find_bit_type(argument, &sql_mode_typelib)) == ~(ulong) 0)
+ {
+ fprintf(stderr, "Unknown option to sql-mode: %s\n", argument);
exit(1);
}
+ global_system_variables.tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ?
+ ISO_SERIALIZABLE :
+ ISO_REPEATABLE_READ);
+ break;
+ }
+ case OPT_MASTER_PASSWORD:
+ master_password=argument;
+ break;
+ case OPT_SKIP_SAFEMALLOC:
+#ifdef SAFEMALLOC
+ sf_malloc_quick=1;
+#endif
+ break;
+ case OPT_LOWER_CASE_TABLE_NAMES:
+ lower_case_table_names= argument ? atoi(argument) : 1;
+ break;
}
- // Skipp empty arguments (from shell)
- while (argc != optind && !argv[optind][0])
- optind++;
- if (argc != optind)
+ return 0;
+}
+ /* Initiates DEBUG - but no debugging here ! */
+
+static void get_options(int argc,char **argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+#if defined(HAVE_BROKEN_REALPATH)
+ my_use_symdir=0;
+ my_disable_symlinks=1;
+ have_symlink=SHOW_OPTION_NO;
+#else
+ if (!my_use_symdir)
{
- fprintf(stderr,"%s: Too many parameters\n",my_progname);
- use_help();
- exit(1);
+ my_disable_symlinks=1;
+ have_symlink=SHOW_OPTION_DISABLED;
}
+#endif
+ if (opt_debugging)
+ {
+ /* Allow break with SIGINT, no core or stack trace */
+ test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
+ test_flags&= ~TEST_CORE_ON_SIGNAL;
+ }
+ /* Set global MyISAM variables from delay_key_write_options */
+ fix_delay_key_write((THD*) 0, OPT_GLOBAL);
+
+ if (mysqld_chroot)
+ set_root(mysqld_chroot);
fix_paths();
- default_table_type_name=ha_table_typelib.type_names[default_table_type-1];
- default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
- /* To be deleted in MySQL 4.0 */
- if (!record_rnd_cache_size)
- record_rnd_cache_size=my_default_record_cache_size;
+
+ /*
+ Set some global variables from the global_system_variables
+ In most cases the global variables will not be used
+ */
+ my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
+ my_default_record_cache_size=global_system_variables.read_buff_size;
+ myisam_max_temp_length=
+ (my_off_t) global_system_variables.myisam_max_sort_file_size;
+ myisam_max_extra_temp_length=
+ (my_off_t) global_system_variables.myisam_max_extra_sort_file_size;
+
+ /* Set global variables based on startup options */
+ myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
}
@@ -4215,22 +4909,53 @@ static char *get_relative_path(const char *path)
}
+/*
+ Fix filename and replace extension where 'dir' is relative to
+ mysql_real_data_home.
+ Return 1 if len(path) > FN_REFLEN
+*/
+
+bool
+fn_format_relative_to_data_home(my_string to, const char *name,
+ const char *dir, const char *extension)
+{
+ char tmp_path[FN_REFLEN];
+ if (!test_if_hard_path(dir))
+ {
+ strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
+ dir, NullS);
+ dir=tmp_path;
+ }
+ return !fn_format(to, name, dir, extension,
+ MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
+}
+
+
static void fix_paths(void)
{
- (void) fn_format(mysql_home,mysql_home,"","",16); // Remove symlinks
- convert_dirname(mysql_home);
- convert_dirname(mysql_real_data_home);
- convert_dirname(language);
+ char buff[FN_REFLEN],*pos;
+ convert_dirname(mysql_home,mysql_home,NullS);
+ /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
+ my_realpath(mysql_home,mysql_home,MYF(0));
+ /* Ensure that mysql_home ends in FN_LIBCHAR */
+ pos=strend(mysql_home);
+ if (pos[-1] != FN_LIBCHAR)
+ {
+ pos[0]= FN_LIBCHAR;
+ pos[1]= 0;
+ }
+ convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
+ convert_dirname(language,language,NullS);
(void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
(void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
(void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
- char buff[FN_REFLEN],*sharedir=get_relative_path(SHAREDIR);
+ char *sharedir=get_relative_path(SHAREDIR);
if (test_if_hard_path(sharedir))
strmake(buff,sharedir,sizeof(buff)-1); /* purecov: tested */
else
strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
- convert_dirname(buff);
+ convert_dirname(buff,buff,NullS);
(void) my_load_path(language,language,buff);
/* If --character-sets-dir isn't given, use shared library dir */
@@ -4241,19 +4966,32 @@ static void fix_paths(void)
charsets_dir=mysql_charsets_dir;
}
- /* Add '/' to TMPDIR if needed */
- char *tmp= (char*) my_malloc(FN_REFLEN,MYF(MY_FAE));
- if (tmp)
+ char *end=convert_dirname(buff, opt_mysql_tmpdir, NullS);
+ if (!(mysql_tmpdir= my_memdup((byte*) buff,(uint) (end-buff)+1,
+ MYF(MY_FAE))))
+ exit(1);
+ if (!slave_load_tmpdir)
{
- strmake(tmp, mysql_tmpdir, FN_REFLEN-1);
- mysql_tmpdir=tmp;
- convert_dirname(mysql_tmpdir);
- mysql_tmpdir=(char*) my_realloc(mysql_tmpdir,(uint) strlen(mysql_tmpdir)+1,
- MYF(MY_HOLD_ON_ERROR));
+ if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
+ exit(1);
}
}
+/*
+ set how many open files we want to be able to handle
+
+ SYNOPSIS
+ set_maximum_open_files()
+ max_file_limit Files to open
+
+ NOTES
+ The request may not fulfilled becasue of system limitations
+
+ RETURN
+ Files available to open
+*/
+
#ifdef SET_RLIMIT_NOFILE
static uint set_maximum_open_files(uint max_file_limit)
{
@@ -4268,16 +5006,17 @@ static uint set_maximum_open_files(uint max_file_limit)
rlimit.rlim_cur=rlimit.rlim_max=max_file_limit;
if (setrlimit(RLIMIT_NOFILE,&rlimit))
{
- sql_print_error("Warning: setrlimit couldn't increase number of open files to more than %ld",
- old_cur); /* purecov: inspected */
+ sql_print_error("Warning: setrlimit couldn't increase number of open files to more than %lu (request: %u)",
+ old_cur, max_file_limit); /* purecov: inspected */
max_file_limit=old_cur;
}
else
{
(void) getrlimit(RLIMIT_NOFILE,&rlimit);
if ((uint) rlimit.rlim_cur != max_file_limit)
- sql_print_error("Warning: setrlimit returned ok, but didn't change limits. Max open files is %ld",
- (ulong) rlimit.rlim_cur); /* purecov: inspected */
+ sql_print_error("Warning: setrlimit returned ok, but didn't change limits. Max open files is %ld (request: %u)",
+ (ulong) rlimit.rlim_cur,
+ max_file_limit); /* purecov: inspected */
max_file_limit=rlimit.rlim_cur;
}
}
@@ -4309,10 +5048,10 @@ static uint set_maximum_open_files(uint max_file_limit)
}
#endif
- /*
- Return a bitfield from a string of substrings separated by ','
- returns ~(ulong) 0 on error.
- */
+/*
+ Return a bitfield from a string of substrings separated by ','
+ returns ~(ulong) 0 on error.
+*/
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
{
@@ -4325,6 +5064,7 @@ static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
DBUG_PRINT("enter",("x: '%s'",x));
found=0;
+ found_end= 0;
pos=(my_string) x;
while (*pos == ' ') pos++;
found_end= *pos == 0;
@@ -4333,7 +5073,7 @@ static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
if (!*(end=strcend(pos,','))) /* Let end point at fieldend */
{
while (end > pos && end[-1] == ' ')
- end--; /* Skipp end-space */
+ end--; /* Skip end-space */
found_end=1;
}
found_int=0; found_count=0;
@@ -4368,8 +5108,63 @@ skipp: ;
} /* find_bit_type */
+/*
+ Check if file system used for databases is case insensitive
+
+ SYNOPSIS
+ test_if_case_sensitive()
+ dir_name Directory to test
+
+ RETURN
+ -1 Don't know (Test failed)
+ 0 File system is case sensitive
+ 1 File system is case insensitive
+*/
+
+static int test_if_case_insensitive(const char *dir_name)
+{
+ int result= 0;
+ File file;
+ char buff[FN_REFLEN], buff2[FN_REFLEN];
+ MY_STAT stat_info;
+
+ fn_format(buff, glob_hostname, dir_name, ".lower-test",
+ MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
+ fn_format(buff2, glob_hostname, dir_name, ".LOWER-TEST",
+ MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
+ (void) my_delete(buff2, MYF(0));
+ if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0)
+ {
+ sql_print_error("Warning: Can't create test file %s", buff);
+ return -1;
+ }
+ my_close(file, MYF(0));
+ if (my_stat(buff2, &stat_info, MYF(0)))
+ result= 1; // Can access file
+ (void) my_delete(buff, MYF(MY_WME));
+ return result;
+}
+
+
+/* Create file to store pid number */
+
+static void create_pid_file()
+{
+ File file;
+ if ((file = my_create(pidfile_name,0664,
+ O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
+ {
+ char buff[21], *end;
+ end= int2str((long) getpid(), buff, 10);
+ *end++= '\n';
+ (void) my_write(file, (byte*) buff, (uint) (end-buff),MYF(MY_WME));
+ (void) my_close(file, MYF(0));
+ }
+}
+
+
/*****************************************************************************
-** Instantiate templates
+ Instantiate templates
*****************************************************************************/
#ifdef __GNUC__
diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc
index 381e0ded3f4..315cad5ca6d 100644
--- a/sql/net_pkg.cc
+++ b/sql/net_pkg.cc
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000-2003 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -30,13 +30,14 @@ void send_error(NET *net, uint sql_errno, const char *err)
err ? err : net->last_error[0] ?
net->last_error : "NULL"));
+ query_cache_abort(net);
if (thd)
thd->query_error = 1; // needed to catch query errors during replication
if (!err)
{
if (sql_errno)
err=ER(sql_errno);
- else if (!err)
+ else
{
if ((err=net->last_error)[0])
sql_errno=net->last_errno;
@@ -51,6 +52,7 @@ void send_error(NET *net, uint sql_errno, const char *err)
{
if (thd && thd->bootstrap)
{
+ /* In bootstrap it's ok to print on stderr */
fprintf(stderr,"ERROR: %d %s\n",sql_errno,err);
}
DBUG_VOID_RETURN;
@@ -85,9 +87,10 @@ void send_warning(NET *net, uint sql_errno, const char *err)
DBUG_VOID_RETURN;
}
-/**
-** write error package and flush to client
-** It's a little too low level, but I don't want to allow another buffer
+
+/*
+ Write error package and flush to client
+ It's a little too low level, but I don't want to allow another buffer
*/
/* VARARGS3 */
@@ -102,11 +105,23 @@ net_printf(NET *net, uint errcode, ...)
DBUG_ENTER("net_printf");
DBUG_PRINT("enter",("message: %u",errcode));
- if(thd) thd->query_error = 1;
- // if we are here, something is wrong :-)
-
+ if (thd)
+ thd->query_error = 1; // if we are here, something is wrong :-)
+ query_cache_abort(net); // Safety
va_start(args,errcode);
- format=ER(errcode);
+ /*
+ The following is needed to make net_printf() work with 0 argument for
+ errorcode and use the argument after that as the format string. This
+ is useful for rare errors that are not worth the hassle to put in
+ errmsg.sys, but at the same time, the message is not fixed text
+ */
+ if (errcode)
+ format= ER(errcode);
+ else
+ {
+ format=va_arg(args,char*);
+ errcode= ER_UNKNOWN_ERROR;
+ }
offset= net->return_errno ? 2 : 0;
text_pos=(char*) net->buff+head_length+offset+1;
(void) vsprintf(my_const_cast(char*) (text_pos),format,args);
@@ -119,6 +134,10 @@ net_printf(NET *net, uint errcode, ...)
{
if (thd && thd->bootstrap)
{
+ /*
+ In bootstrap it's ok to print on stderr
+ This may also happen when we get an error from a slave thread
+ */
fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos);
thd->fatal_error=1;
}
@@ -142,7 +161,7 @@ send_ok(NET *net,ha_rows affected_rows,ulonglong id,const char *message)
{
if (net->no_send_ok) // hack for re-parsing queries
return;
-
+
char buff[MYSQL_ERRMSG_SIZE+10],*pos;
DBUG_ENTER("send_ok");
buff[0]=0; // No fields
@@ -264,8 +283,8 @@ bool
net_store_data(String *packet,const char *from,uint length)
{
ulong packet_length=packet->length();
- if (packet_length+5+length > packet->alloced_length() &&
- packet->realloc(packet_length+5+length))
+ if (packet_length+9+length > packet->alloced_length() &&
+ packet->realloc(packet_length+9+length))
return 1;
char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
(ulonglong) length);
@@ -281,6 +300,10 @@ net_store_data(String *packet,const char *from)
{
uint length=(uint) strlen(from);
uint packet_length=packet->length();
+ /*
+ 3 is the longest coding for storing a string with the used
+ net_store_length() function. We use 5 here 'just in case'
+ */
if (packet_length+5+length > packet->alloced_length() &&
packet->realloc(packet_length+5+length))
return 1;
@@ -330,9 +353,9 @@ bool net_store_data(String* packet, I_List<i_string>* str_list)
I_List_iterator<i_string> it(*str_list);
i_string* s;
- while((s=it++))
+ while ((s=it++))
{
- if(tmp.length())
+ if (tmp.length())
tmp.append(',');
tmp.append(s->ptr);
}
@@ -360,3 +383,19 @@ net_store_data(String *packet, CONVERT *convert, const char *from)
return convert->store(packet, from, length);
return net_store_data(packet,from,length);
}
+
+/*
+ Function called by my_net_init() to set some check variables
+*/
+
+extern "C" {
+void my_net_local_init(NET *net)
+{
+ net->max_packet= (uint) global_system_variables.net_buffer_length;
+ net->read_timeout= (uint) global_system_variables.net_read_timeout;
+ net->write_timeout=(uint) global_system_variables.net_write_timeout;
+ net->retry_count= (uint) global_system_variables.net_retry_count;
+ net->max_packet_size= max(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+}
+}
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 23a23dbde7b..18dadf24efa 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -1,202 +1,194 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* Write and read of logical packets to/from socket
-** Writes are cached into net_buffer_length big packets.
-** Read packets are reallocated dynamicly when reading big packets.
-** Each logical packet has the following pre-info:
-** 3 byte length & 1 byte package-number.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Write and read of logical packets to/from socket
+
+ Writes are cached into net_buffer_length big packets.
+ Read packets are reallocated dynamicly when reading big packets.
+ Each logical packet has the following pre-info:
+ 3 byte length & 1 byte package-number.
+
+ This file needs to be written in C as it's used by the libmysql client as a
+ C file.
*/
#ifdef __WIN__
#include <winsock.h>
#endif
-#include <global.h>
-#include <violite.h>
+#include <my_global.h>
+#include <mysql.h>
+#include <mysql_embed.h>
+#include <mysql_com.h>
+#include <mysqld_error.h>
#include <my_sys.h>
#include <m_string.h>
-#include "mysql.h"
-#include "mysqld_error.h"
+#include <my_net.h>
+#include <violite.h>
#include <signal.h>
#include <errno.h>
-#include <sys/types.h>
-#ifdef MYSQL_SERVER
-#include <violite.h>
-#endif
-#define MAX_PACKET_LENGTH (256L*256L*256L-1)
+/*
+ The following handles the differences when this is linked between the
+ client and the server.
-#ifdef MYSQL_SERVER
-ulong max_allowed_packet=65536;
-extern ulong net_read_timeout,net_write_timeout;
-extern uint test_flags;
-#else
-ulong max_allowed_packet=MAX_PACKET_LENGTH;
-ulong net_read_timeout= NET_READ_TIMEOUT;
-ulong net_write_timeout= NET_WRITE_TIMEOUT;
-#endif
-ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */
+ This gives an error if a too big packet is found
+ The server can change this with the -O switch, but because the client
+ can't normally do this the client should have a bigger max_allowed_packet.
+*/
-#if !defined(__WIN__) && !defined(MSDOS)
-#include <sys/socket.h>
-#else
-#undef MYSQL_SERVER /* Win32 can't handle interrupts */
-#endif
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__)
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#if !defined(alpha_linux_port)
-#include <netinet/tcp.h>
+#if defined(__WIN__) || !defined(MYSQL_SERVER)
+ /* The following is because alarms doesn't work on windows. */
+#define NO_ALARM
#endif
-#endif
-#include "mysqld_error.h"
-#ifdef MYSQL_SERVER
+
+#ifndef NO_ALARM
#include "my_pthread.h"
-#include "thr_alarm.h"
void sql_print_error(const char *format,...);
-#define RETRY_COUNT mysqld_net_retry_count
-extern ulong mysqld_net_retry_count;
#else
+#define DONT_USE_THR_ALARM
+#endif /* NO_ALARM */
-#ifdef OS2 /* avoid name conflict */
-#define thr_alarm_t thr_alarm_t_net
-#define ALARM ALARM_net
-#endif
-
-typedef my_bool thr_alarm_t;
-typedef my_bool ALARM;
-#define thr_alarm_init(A) (*(A))=0
-#define thr_alarm_in_use(A) (*(A))
-#define thr_end_alarm(A)
-#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C))
-inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused)))
-{
- *A=1;
- return 0;
-}
-#define thr_got_alarm(A) 0
-#define RETRY_COUNT 1
-#endif
+#include "thr_alarm.h"
#ifdef MYSQL_SERVER
-extern ulong bytes_sent, bytes_received;
+#define USE_QUERY_CACHE
+extern uint test_flags;
+extern void query_cache_insert(NET *net, const char *packet, ulong length);
+extern ulong bytes_sent, bytes_received, net_big_packet_count;
extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
#else
#undef statistic_add
+#undef statistic_increment
#define statistic_add(A,B,C)
+#define statistic_increment(A,B)
#endif
-/*
-** Give error if a too big packet is found
-** The server can change this with the -O switch, but because the client
-** can't normally do this the client should have a bigger max-buffer.
-*/
-
#define TEST_BLOCKING 8
-static int net_write_buff(NET *net,const char *packet,uint len);
+#define MAX_PACKET_LENGTH (256L*256L*256L-1)
+
+static my_bool net_write_buff(NET *net,const char *packet,ulong len);
/* Init with packet info */
int my_net_init(NET *net, Vio* vio)
{
- if (!(net->buff=(uchar*) my_malloc(net_buffer_length,MYF(MY_WME))))
- return 1;
- if (net_buffer_length > max_allowed_packet)
- max_allowed_packet=net_buffer_length;
- net->buff_end=net->buff+(net->max_packet=net_buffer_length);
+ DBUG_ENTER("my_net_init");
+ my_net_local_init(net); /* Set some limits */
+ if (!(net->buff=(uchar*) my_malloc((uint32) net->max_packet+
+ NET_HEADER_SIZE + COMP_HEADER_SIZE,
+ MYF(MY_WME))))
+ DBUG_RETURN(1);
+ net->buff_end=net->buff+net->max_packet;
net->vio = vio;
net->no_send_ok = 0;
net->error=0; net->return_errno=0; net->return_status=0;
- net->timeout=(uint) net_read_timeout; /* Timeout for read */
- net->pkt_nr=0;
+ net->pkt_nr=net->compress_pkt_nr=0;
net->write_pos=net->read_pos = net->buff;
net->last_error[0]=0;
net->compress=0; net->reading_or_writing=0;
net->where_b = net->remain_in_buf=0;
net->last_errno=0;
+ net->query_cache_query=0;
if (vio != 0) /* If real connection */
{
net->fd = vio_fd(vio); /* For perl DBI/DBD */
#if defined(MYSQL_SERVER) && !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
if (!(test_flags & TEST_BLOCKING))
- vio_blocking(vio, FALSE);
+ {
+ my_bool old_mode;
+ vio_blocking(vio, FALSE, &old_mode);
+ }
#endif
vio_fastsend(vio);
}
- return 0;
+ DBUG_RETURN(0);
}
+
void net_end(NET *net)
{
+ DBUG_ENTER("net_end");
my_free((gptr) net->buff,MYF(MY_ALLOW_ZERO_PTR));
net->buff=0;
+ DBUG_VOID_RETURN;
}
+
/* Realloc the packet buffer */
static my_bool net_realloc(NET *net, ulong length)
{
uchar *buff;
ulong pkt_length;
- if (length >= max_allowed_packet)
+ DBUG_ENTER("net_realloc");
+ DBUG_PRINT("enter",("length: %lu", length));
+
+ if (length >= net->max_packet_size)
{
- DBUG_PRINT("error",("Packet too large (%lu)", length));
+ DBUG_PRINT("error",("Packet too large. Max sixe: %lu",
+ net->max_packet_size));
net->error=1;
net->last_errno=ER_NET_PACKET_TOO_LARGE;
- return 1;
+ DBUG_RETURN(1);
}
- pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
- if (!(buff=(uchar*) my_realloc((char*) net->buff, pkt_length, MYF(MY_WME))))
+ pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
+ /*
+ We must allocate some extra bytes for the end 0 and to be able to
+ read big compressed blocks
+ */
+ if (!(buff=(uchar*) my_realloc((char*) net->buff, (uint32) pkt_length +
+ NET_HEADER_SIZE + COMP_HEADER_SIZE,
+ MYF(MY_WME))))
{
net->error=1;
#ifdef MYSQL_SERVER
net->last_errno=ER_OUT_OF_RESOURCES;
#endif
- return 1;
+ DBUG_RETURN(1);
}
net->buff=net->write_pos=buff;
net->buff_end=buff+(net->max_packet=pkt_length);
- return 0;
+ DBUG_RETURN(0);
}
/* Remove unwanted characters from connection */
void net_clear(NET *net)
{
-#ifndef EXTRA_DEBUG
- int count; /* One may get 'unused' warning */
- bool is_blocking=vio_is_blocking(net->vio);
- if (is_blocking)
- vio_blocking(net->vio, FALSE);
- if (!vio_is_blocking(net->vio)) /* Safety if SSL */
+ DBUG_ENTER("net_clear");
+#if !defined(EXTRA_DEBUG) && !defined(EMBEDDED_LIBRARY)
{
- while ( (count = vio_read(net->vio, (char*) (net->buff),
- net->max_packet)) > 0)
- DBUG_PRINT("info",("skipped %d bytes from file: %s",
- count,vio_description(net->vio)));
- if (is_blocking)
- vio_blocking(net->vio, TRUE);
+ int count; /* One may get 'unused' warn */
+ my_bool old_mode;
+ if (!vio_blocking(net->vio, FALSE, &old_mode))
+ {
+ while ((count = vio_read(net->vio, (char*) (net->buff),
+ (uint32) net->max_packet)) > 0)
+ DBUG_PRINT("info",("skipped %d bytes from file: %s",
+ count, vio_description(net->vio)));
+ vio_blocking(net->vio, TRUE, &old_mode);
+ }
}
#endif /* EXTRA_DEBUG */
- net->pkt_nr=0; /* Ready for new command */
+ net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */
net->write_pos=net->buff;
+ DBUG_VOID_RETURN;
}
/* Flush write_buffer if not empty. */
@@ -208,9 +200,12 @@ int net_flush(NET *net)
if (net->buff != net->write_pos)
{
error=net_real_write(net,(char*) net->buff,
- (uint) (net->write_pos - net->buff));
+ (ulong) (net->write_pos - net->buff));
net->write_pos=net->buff;
}
+ /* Sync packet number if using compression */
+ if (net->compress)
+ net->pkt_nr=net->compress_pkt_nr;
DBUG_RETURN(error);
}
@@ -219,86 +214,187 @@ int net_flush(NET *net)
** Write something to server/client buffer
*****************************************************************************/
-
/*
-** Write a logical packet with packet header
-** Format: Packet length (3 bytes), packet number(1 byte)
-** When compression is used a 3 byte compression length is added
-** NOTE: If compression is used the original package is destroyed!
+ Write a logical packet with packet header
+ Format: Packet length (3 bytes), packet number(1 byte)
+ When compression is used a 3 byte compression length is added
+
+ NOTE
+ If compression is used the original package is modified!
*/
int
my_net_write(NET *net,const char *packet,ulong len)
{
uchar buff[NET_HEADER_SIZE];
- if (len >= MAX_PACKET_LENGTH)
+ /*
+ Big packets are handled by splitting them in packets of MAX_PACKET_LENGTH
+ length. The last packet is always a packet that is < MAX_PACKET_LENGTH.
+ (The last packet may even have a length of 0)
+ */
+ while (len >= MAX_PACKET_LENGTH)
{
- net->error=1;
- net->last_errno=ER_NET_PACKET_TOO_LARGE;
- return 1;
+ const ulong z_size = MAX_PACKET_LENGTH;
+ int3store(buff, z_size);
+ buff[3]= (uchar) net->pkt_nr++;
+ if (net_write_buff(net, (char*) buff, NET_HEADER_SIZE) ||
+ net_write_buff(net, packet, z_size))
+ return 1;
+ packet += z_size;
+ len-= z_size;
}
+ /* Write last packet */
int3store(buff,len);
- buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
+ buff[3]= (uchar) net->pkt_nr++;
if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE))
return 1;
- return net_write_buff(net,packet,len);
+ DBUG_DUMP("packet_header",(char*) buff,NET_HEADER_SIZE);
+ return test(net_write_buff(net,packet,len));
}
+/*
+ Send a command to the server.
+ As the command is part of the first data packet, we have to do some data
+ juggling to put the command in there, without having to create a new
+ packet.
+ This function will split big packets into sub-packets if needed.
+ (Each sub packet can only be 2^24 bytes)
+*/
+
int
net_write_command(NET *net,uchar command,const char *packet,ulong len)
{
+ ulong length=len+1; /* 1 extra byte for command */
uchar buff[NET_HEADER_SIZE+1];
- uint length=len+1; /* 1 extra byte for command */
+ uint header_size=NET_HEADER_SIZE+1;
+ DBUG_ENTER("net_write_command");
+ DBUG_PRINT("enter",("length: %lu", len));
+
+ buff[4]=command; /* For first packet */
+
if (length >= MAX_PACKET_LENGTH)
{
- net->error=1;
- net->last_errno=ER_NET_PACKET_TOO_LARGE;
- return 1;
+ /* Take into account that we have the command in the first header */
+ len= MAX_PACKET_LENGTH -1;
+ do
+ {
+ int3store(buff, MAX_PACKET_LENGTH);
+ buff[3]= (uchar) net->pkt_nr++;
+ if (net_write_buff(net,(char*) buff, header_size) ||
+ net_write_buff(net,packet,len))
+ DBUG_RETURN(1);
+ packet+= len;
+ length-= MAX_PACKET_LENGTH;
+ len= MAX_PACKET_LENGTH;
+ header_size= NET_HEADER_SIZE;
+ } while (length >= MAX_PACKET_LENGTH);
+ len=length; /* Data left to be written */
}
int3store(buff,length);
- buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
- buff[4]=command;
- if (net_write_buff(net,(char*) buff,5))
- return 1;
- return test(net_write_buff(net,packet,len) || net_flush(net));
+ buff[3]= (uchar) net->pkt_nr++;
+ DBUG_RETURN(test(net_write_buff(net,(char*) buff,header_size) ||
+ net_write_buff(net,packet,len) || net_flush(net)));
}
+/*
+ Caching the data in a local buffer before sending it.
+
+ SYNOPSIS
+ net_write_buff()
+ net Network handler
+ packet Packet to send
+ len Length of packet
+
+ DESCRIPTION
+ Fill up net->buffer and send it to the client when full.
+
+ If the rest of the to-be-sent-packet is bigger than buffer,
+ send it in one big block (to avoid copying to internal buffer).
+ If not, copy the rest of the data to the buffer and return without
+ sending data.
-static int
-net_write_buff(NET *net,const char *packet,uint len)
+ NOTES
+ The cached buffer can be sent as it is with 'net_flush()'.
+
+ In this code we have to be careful to not send a packet longer than
+ MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
+ protocol as we store the length of the compressed packet in 3 bytes.
+
+ RETURN
+ 0 ok
+ 1
+*/
+
+static my_bool
+net_write_buff(NET *net,const char *packet,ulong len)
{
- uint left_length=(uint) (net->buff_end - net->write_pos);
+ ulong left_length;
+ if (net->compress && net->max_packet > MAX_PACKET_LENGTH)
+ left_length= MAX_PACKET_LENGTH - (net->write_pos - net->buff);
+ else
+ left_length= (ulong) (net->buff_end - net->write_pos);
- while (len > left_length)
+ if (len > left_length)
{
- memcpy((char*) net->write_pos,packet,left_length);
- if (net_real_write(net,(char*) net->buff,net->max_packet))
- return 1;
- net->write_pos=net->buff;
- packet+=left_length;
- len-=left_length;
- left_length=net->max_packet;
+ if (net->write_pos != net->buff)
+ {
+ /* Fill up already used packet and write it */
+ memcpy((char*) net->write_pos,packet,left_length);
+ if (net_real_write(net,(char*) net->buff,
+ (ulong) (net->write_pos - net->buff) + left_length))
+ return 1;
+ net->write_pos= net->buff;
+ packet+= left_length;
+ len-= left_length;
+ }
+ if (net->compress)
+ {
+ /*
+ We can't have bigger packets than 16M with compression
+ Because the uncompressed length is stored in 3 bytes
+ */
+ left_length= MAX_PACKET_LENGTH;
+ while (len > left_length)
+ {
+ if (net_real_write(net, packet, left_length))
+ return 1;
+ packet+= left_length;
+ len-= left_length;
+ }
+ }
+ if (len > net->max_packet)
+ return net_real_write(net, packet, len) ? 1 : 0;
+ /* Send out rest of the blocks as full sized blocks */
}
memcpy((char*) net->write_pos,packet,len);
- net->write_pos+=len;
+ net->write_pos+= len;
return 0;
}
-/* Read and write using timeouts */
+
+/*
+ Read and write one packet using timeouts.
+ If needed, the packet is compressed before sending.
+*/
int
net_real_write(NET *net,const char *packet,ulong len)
{
- int length;
+ long int length;
char *pos,*end;
thr_alarm_t alarmed;
-#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
+#ifndef NO_ALARM
ALARM alarm_buff;
#endif
uint retry_count=0;
my_bool net_blocking = vio_is_blocking(net->vio);
DBUG_ENTER("net_real_write");
+#if defined(MYSQL_SERVER) && defined(HAVE_QUERY_CACHE)
+ if (net->query_cache_query != 0)
+ query_cache_insert(net, packet, len);
+#endif
+
if (net->error == 2)
DBUG_RETURN(-1); /* socket can't be used */
@@ -309,8 +405,8 @@ net_real_write(NET *net,const char *packet,ulong len)
ulong complen;
uchar *b;
uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
- if (!(b=(uchar*) my_malloc(len + NET_HEADER_SIZE + COMP_HEADER_SIZE,
- MYF(MY_WME))))
+ if (!(b=(uchar*) my_malloc((uint32) len + NET_HEADER_SIZE +
+ COMP_HEADER_SIZE, MYF(MY_WME))))
{
#ifdef MYSQL_SERVER
net->last_errno=ER_OUT_OF_RESOURCES;
@@ -322,53 +418,51 @@ net_real_write(NET *net,const char *packet,ulong len)
memcpy(b+header_length,packet,len);
if (my_compress((byte*) b+header_length,&len,&complen))
- {
- DBUG_PRINT("warning",
- ("Compression error; Continuing without compression"));
complen=0;
- }
int3store(&b[NET_HEADER_SIZE],complen);
int3store(b,len);
- b[3]=(uchar) (net->pkt_nr++);
+ b[3]=(uchar) (net->compress_pkt_nr++);
len+= header_length;
packet= (char*) b;
}
#endif /* HAVE_COMPRESS */
/* DBUG_DUMP("net",packet,len); */
-#ifdef MYSQL_SERVER
+#ifndef NO_ALARM
thr_alarm_init(&alarmed);
if (net_blocking)
- thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff);
+ thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff);
#else
alarmed=0;
-#endif /* MYSQL_SERVER */
+ vio_timeout(net->vio, net->write_timeout);
+#endif /* NO_ALARM */
pos=(char*) packet; end=pos+len;
while (pos != end)
{
- if ((int) (length=vio_write(net->vio,pos,(int) (end-pos))) <= 0)
+ if ((long) (length=vio_write(net->vio,pos,(uint32) (end-pos))) <= 0)
{
my_bool interrupted = vio_should_retry(net->vio);
#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2))
if ((interrupted || length==0) && !thr_alarm_in_use(&alarmed))
{
- if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff))
+ if (!thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff))
{ /* Always true for client */
- if (!vio_is_blocking(net->vio))
+ my_bool old_mode;
+ while (vio_blocking(net->vio, TRUE, &old_mode) < 0)
{
- while (vio_blocking(net->vio, TRUE) < 0)
- {
- if (vio_should_retry(net->vio) && retry_count++ < RETRY_COUNT)
- continue;
+ if (vio_should_retry(net->vio) && retry_count++ < net->retry_count)
+ continue;
#ifdef EXTRA_DEBUG
- fprintf(stderr,
- "%s: my_net_write: fcntl returned error %d, aborting thread\n",
- my_progname,vio_errno(net->vio));
+ fprintf(stderr,
+ "%s: my_net_write: fcntl returned error %d, aborting thread\n",
+ my_progname,vio_errno(net->vio));
#endif /* EXTRA_DEBUG */
- net->error=2; /* Close socket */
- goto end;
- }
+#ifdef MYSQL_SERVER
+ net->last_errno=ER_NET_ERROR_ON_WRITE;
+#endif
+ net->error=2; /* Close socket */
+ goto end;
}
retry_count=0;
continue;
@@ -379,7 +473,7 @@ net_real_write(NET *net,const char *packet,ulong len)
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
interrupted)
{
- if (retry_count++ < RETRY_COUNT)
+ if (retry_count++ < net->retry_count)
continue;
#ifdef EXTRA_DEBUG
fprintf(stderr, "%s: write looped, aborting thread\n",
@@ -412,8 +506,9 @@ net_real_write(NET *net,const char *packet,ulong len)
#endif
if (thr_alarm_in_use(&alarmed))
{
+ my_bool old_mode;
thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking);
+ vio_blocking(net->vio, net_blocking, &old_mode);
}
net->reading_or_writing=0;
DBUG_RETURN(((int) (pos != end)));
@@ -424,44 +519,91 @@ net_real_write(NET *net,const char *packet,ulong len)
** Read something from server/clinet
*****************************************************************************/
-#ifdef MYSQL_SERVER
-
-/*
- Help function to clear the commuication buffer when we get a too
- big packet
-*/
+#ifndef NO_ALARM
-static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed,
- ALARM *alarm_buff)
+static my_bool net_safe_read(NET *net, char *buff, uint32 length,
+ thr_alarm_t *alarmed)
{
uint retry_count=0;
- if (!thr_alarm_in_use(alarmed))
- {
- if (thr_alarm(alarmed,net->timeout,alarm_buff) ||
- (!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE) < 0))
- return; /* Can't setup, abort */
- }
- while (remain > 0)
+ while (length > 0)
{
- ulong length;
- if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L)
+ int tmp;
+ if ((tmp=vio_read(net->vio,(char*) net->buff, length)) <= 0)
{
my_bool interrupted = vio_should_retry(net->vio);
if (!thr_got_alarm(alarmed) && interrupted)
{ /* Probably in MIT threads */
- if (retry_count++ < RETRY_COUNT)
+ if (retry_count++ < net->retry_count)
continue;
}
- return;
+ return 1;
}
- remain -=(ulong) length;
- statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
+ length-= tmp;
}
+ return 0;
}
-#endif /* MYSQL_SERVER */
+/*
+ Help function to clear the commuication buffer when we get a too big packet.
+
+ SYNOPSIS
+ my_net_skip_rest()
+ net Communication handle
+ remain Bytes to read
+ alarmed Parameter for thr_alarm()
+ alarm_buff Parameter for thr_alarm()
+
+ RETURN VALUES
+ 0 Was able to read the whole packet
+ 1 Got mailformed packet from client
+*/
+
+static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
+ ALARM *alarm_buff)
+{
+ uint32 old=remain;
+ DBUG_ENTER("my_net_skip_rest");
+ DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain));
+
+ /* The following is good for debugging */
+ statistic_increment(net_big_packet_count,&LOCK_bytes_received);
-static uint
+ if (!thr_alarm_in_use(alarmed))
+ {
+ my_bool old_mode;
+ if (thr_alarm(alarmed,net->read_timeout, alarm_buff) ||
+ vio_blocking(net->vio, TRUE, &old_mode) < 0)
+ DBUG_RETURN(1); /* Can't setup, abort */
+ }
+ for (;;)
+ {
+ while (remain > 0)
+ {
+ uint length= min(remain, net->max_packet);
+ if (net_safe_read(net, (char*) net->buff, length, alarmed))
+ DBUG_RETURN(1);
+ statistic_add(bytes_received, length, &LOCK_bytes_received);
+ remain -= (uint32) length;
+ }
+ if (old != MAX_PACKET_LENGTH)
+ break;
+ if (net_safe_read(net, (char*) net->buff, NET_HEADER_SIZE, alarmed))
+ DBUG_RETURN(1);
+ old=remain= uint3korr(net->buff);
+ net->pkt_nr++;
+ }
+ DBUG_RETURN(0);
+}
+#endif /* NO_ALARM */
+
+
+/*
+ Reads one packet to net->buff + net->where_b
+ Returns length of packet. Long packets are handled by my_net_read().
+ This function reallocates the net->buff buffer if necessary.
+*/
+
+static ulong
my_real_read(NET *net, ulong *complen)
{
uchar *pos;
@@ -469,20 +611,22 @@ my_real_read(NET *net, ulong *complen)
uint i,retry_count=0;
ulong len=packet_error;
thr_alarm_t alarmed;
-#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
+#ifndef NO_ALARM
ALARM alarm_buff;
#endif
my_bool net_blocking=vio_is_blocking(net->vio);
- ulong remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
- NET_HEADER_SIZE);
+ uint32 remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
+ NET_HEADER_SIZE);
*complen = 0;
net->reading_or_writing=1;
thr_alarm_init(&alarmed);
-#ifdef MYSQL_SERVER
+#ifndef NO_ALARM
if (net_blocking)
- thr_alarm(&alarmed,net->timeout,&alarm_buff);
-#endif /* MYSQL_SERVER */
+ thr_alarm(&alarmed,net->read_timeout,&alarm_buff);
+#else
+ vio_timeout(net->vio, net->read_timeout);
+#endif /* NO_ALARM */
pos = net->buff + net->where_b; /* net->packet -4 */
for (i=0 ; i < 2 ; i++)
@@ -504,31 +648,29 @@ my_real_read(NET *net, ulong *complen)
*/
if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
{
- if (!thr_alarm(&alarmed,net->timeout,&alarm_buff)) /* Don't wait too long */
+ if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */
{
- if (!vio_is_blocking(net->vio))
- {
- while (vio_blocking(net->vio,TRUE) < 0)
- {
- if (vio_should_retry(net->vio) &&
- retry_count++ < RETRY_COUNT)
- continue;
- DBUG_PRINT("error",
- ("fcntl returned error %d, aborting thread",
- vio_errno(net->vio)));
+ my_bool old_mode;
+ while (vio_blocking(net->vio, TRUE, &old_mode) < 0)
+ {
+ if (vio_should_retry(net->vio) &&
+ retry_count++ < net->retry_count)
+ continue;
+ DBUG_PRINT("error",
+ ("fcntl returned error %d, aborting thread",
+ vio_errno(net->vio)));
#ifdef EXTRA_DEBUG
- fprintf(stderr,
- "%s: read: fcntl returned error %d, aborting thread\n",
- my_progname,vio_errno(net->vio));
+ fprintf(stderr,
+ "%s: read: fcntl returned error %d, aborting thread\n",
+ my_progname,vio_errno(net->vio));
#endif /* EXTRA_DEBUG */
- len= packet_error;
- net->error=2; /* Close socket */
+ len= packet_error;
+ net->error=2; /* Close socket */
#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_FCNTL_ERROR;
+ net->last_errno=ER_NET_FCNTL_ERROR;
#endif
- goto end;
- }
- }
+ goto end;
+ }
retry_count=0;
continue;
}
@@ -537,7 +679,7 @@ my_real_read(NET *net, ulong *complen)
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
interrupted)
{ /* Probably in MIT threads */
- if (retry_count++ < RETRY_COUNT)
+ if (retry_count++ < net->retry_count)
continue;
#ifdef EXTRA_DEBUG
fprintf(stderr, "%s: read looped with error %d, aborting thread\n",
@@ -551,7 +693,8 @@ my_real_read(NET *net, ulong *complen)
continue;
}
#endif
- DBUG_PRINT("error",("Couldn't read packet: remain: %d errno: %d length: %d alarmed: %d", remain,vio_errno(net->vio),length,alarmed));
+ DBUG_PRINT("error",("Couldn't read packet: remain: %u errno: %d length: %ld",
+ remain, vio_errno(net->vio), length));
len= packet_error;
net->error=2; /* Close socket */
#ifdef MYSQL_SERVER
@@ -560,7 +703,7 @@ my_real_read(NET *net, ulong *complen)
#endif
goto end;
}
- remain -= (ulong) length;
+ remain -= (uint32) length;
pos+= (ulong) length;
statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
}
@@ -572,9 +715,10 @@ my_real_read(NET *net, ulong *complen)
if (net->buff[net->where_b] != (uchar) 255)
{
DBUG_PRINT("error",
- ("Packets out of order (Found: %d, expected %d)",
+ ("Packets out of order (Found: %d, expected %u)",
(int) net->buff[net->where_b + 3],
- (uint) (uchar) net->pkt_nr));
+ net->pkt_nr));
+ DBUG_DUMP("packet_header",(char*) net->buff+net->where_b, 4);
#ifdef EXTRA_DEBUG
fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n",
(int) net->buff[net->where_b + 3],
@@ -587,47 +731,67 @@ my_real_read(NET *net, ulong *complen)
#endif
goto end;
}
- net->pkt_nr++;
+ net->compress_pkt_nr= ++net->pkt_nr;
#ifdef HAVE_COMPRESS
if (net->compress)
{
- /* complen is > 0 if package is really compressed */
+ /*
+ If the packet is compressed then complen > 0 and contains the
+ number of bytes in the uncompressed packet
+ */
*complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
}
#endif
len=uint3korr(net->buff+net->where_b);
+ if (!len) /* End of big multi-packet */
+ goto end;
helping = max(len,*complen) + net->where_b;
/* The necessary size of net->buff */
if (helping >= net->max_packet)
{
- /* We must allocate one extra byte for the end null */
- if (net_realloc(net,helping+1))
+ if (net_realloc(net,helping))
{
-#ifdef MYSQL_SERVER
- if (i == 1)
- my_net_skip_rest(net, len, &alarmed, &alarm_buff);
+#if defined(MYSQL_SERVER) && !defined(NO_ALARM)
+ if (!net->compress &&
+ !my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
+ net->error= 3; /* Successfully skiped packet */
#endif
- len= packet_error; /* Return error */
+ len= packet_error; /* Return error and close connection */
goto end;
}
}
pos=net->buff + net->where_b;
- remain = len;
+ remain = (uint32) len;
}
}
end:
if (thr_alarm_in_use(&alarmed))
{
+ my_bool old_mode;
thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking);
+ vio_blocking(net->vio, net_blocking, &old_mode);
}
net->reading_or_writing=0;
return(len);
}
-uint
+
+/*
+ Read a packet from the client/server and return it without the internal
+ package header.
+ If the packet is the first packet of a multi-packet packet
+ (which is indicated by the length of the packet = 0xffffff) then
+ all sub packets are read and concatenated.
+ If the packet was compressed, its uncompressed and the length of the
+ uncompressed packet is returned.
+
+ The function returns the length of the found packet or packet_error.
+ net->read_pos points to the read data.
+*/
+
+ulong
my_net_read(NET *net)
{
ulong len,complen;
@@ -636,65 +800,139 @@ my_net_read(NET *net)
if (!net->compress)
{
#endif
- len = my_real_read (net,&complen);
+ len = my_real_read(net,&complen);
+ if (len == MAX_PACKET_LENGTH)
+ {
+ /* First packet of a multi-packet. Concatenate the packets */
+ ulong save_pos = net->where_b;
+ ulong total_length=0;
+ do
+ {
+ net->where_b += len;
+ total_length += len;
+ len = my_real_read(net,&complen);
+ } while (len == MAX_PACKET_LENGTH);
+ if (len != packet_error)
+ len+= total_length;
+ net->where_b = save_pos;
+ }
net->read_pos = net->buff + net->where_b;
if (len != packet_error)
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
return len;
#ifdef HAVE_COMPRESS
}
- if (net->remain_in_buf)
- net->buff[net->buf_length - net->remain_in_buf]=net->save_char;
- for (;;)
+ else
{
+ /* We are using the compressed protocol */
+
+ ulong buf_length;
+ ulong start_of_packet;
+ ulong first_packet_offset;
+ uint read_length, multi_byte_packet=0;
+
if (net->remain_in_buf)
{
- uchar *pos = net->buff + net->buf_length - net->remain_in_buf;
- if (net->remain_in_buf >= 4)
+ buf_length= net->buf_length; // Data left in old packet
+ first_packet_offset= start_of_packet= (net->buf_length -
+ net->remain_in_buf);
+ /* Restore the character that was overwritten by the end 0 */
+ net->buff[start_of_packet]= net->save_char;
+ }
+ else
+ {
+ /* reuse buffer, as there is nothing in it that we need */
+ buf_length= start_of_packet= first_packet_offset= 0;
+ }
+ for (;;)
+ {
+ ulong packet_len;
+
+ if (buf_length - start_of_packet >= NET_HEADER_SIZE)
{
- net->length = uint3korr(pos);
- if (net->length <= net->remain_in_buf - 4)
+ read_length = uint3korr(net->buff+start_of_packet);
+ if (!read_length)
+ {
+ /* End of multi-byte packet */
+ start_of_packet += NET_HEADER_SIZE;
+ break;
+ }
+ if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
{
- /* We have a full packet */
- len=net->length;
- net->remain_in_buf -= net->length + 4;
- net->read_pos=pos + 4;
- break; /* We have a full packet */
+ if (multi_byte_packet)
+ {
+ /* Remove packet header for second packet */
+ memmove(net->buff + first_packet_offset + start_of_packet,
+ net->buff + first_packet_offset + start_of_packet +
+ NET_HEADER_SIZE,
+ buf_length - start_of_packet);
+ start_of_packet += read_length;
+ buf_length -= NET_HEADER_SIZE;
+ }
+ else
+ start_of_packet+= read_length + NET_HEADER_SIZE;
+
+ if (read_length != MAX_PACKET_LENGTH) /* last package */
+ {
+ multi_byte_packet= 0; /* No last zero len packet */
+ break;
+ }
+ multi_byte_packet= NET_HEADER_SIZE;
+ /* Move data down to read next data packet after current one */
+ if (first_packet_offset)
+ {
+ memmove(net->buff,net->buff+first_packet_offset,
+ buf_length-first_packet_offset);
+ buf_length-=first_packet_offset;
+ start_of_packet -= first_packet_offset;
+ first_packet_offset=0;
+ }
+ continue;
}
}
/* Move data down to read next data packet after current one */
- if (net->buf_length != net->remain_in_buf)
+ if (first_packet_offset)
{
- memmove(net->buff,pos,net->remain_in_buf);
- net->buf_length=net->remain_in_buf;
+ memmove(net->buff,net->buff+first_packet_offset,
+ buf_length-first_packet_offset);
+ buf_length-=first_packet_offset;
+ start_of_packet -= first_packet_offset;
+ first_packet_offset=0;
}
- net->where_b=net->buf_length;
- }
- else
- {
- net->where_b=0;
- net->buf_length=0;
- }
- if ((len = my_real_read(net,&complen)) == packet_error)
- break;
- if (my_uncompress((byte*) net->buff + net->where_b, &len, &complen))
- {
- len= packet_error;
- net->error=2; /* caller will close socket */
+ net->where_b=buf_length;
+ if ((packet_len = my_real_read(net,&complen)) == packet_error)
+ return packet_error;
+ if (my_uncompress((byte*) net->buff + net->where_b, &packet_len,
+ &complen))
+ {
+ net->error=2; /* caller will close socket */
#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_UNCOMPRESS_ERROR;
+ net->last_errno=ER_NET_UNCOMPRESS_ERROR;
#endif
- break;
+ return packet_error;
+ }
+ buf_length+=packet_len;
}
- net->buf_length+=len;
- net->remain_in_buf+=len;
- }
- if (len != packet_error)
- {
+
+ net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE;
+ net->buf_length= buf_length;
+ net->remain_in_buf= (ulong) (buf_length - start_of_packet);
+ len = ((ulong) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
+ multi_byte_packet);
net->save_char= net->read_pos[len]; /* Must be saved */
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
}
+#endif /* HAVE_COMPRESS */
return len;
-#endif
+}
+
+bool net_request_file(NET* net, const char* fname)
+{
+ char tmp [FN_REFLEN+1],*end;
+ DBUG_ENTER("net_request_file");
+ tmp[0] = (char) 251; /* NULL_LENGTH */
+ end=strnmov(tmp+1,fname,sizeof(tmp)-2);
+ DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) ||
+ net_flush(net));
}
diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc
index b18d3d00d88..8a3757a9768 100644
--- a/sql/nt_servc.cc
+++ b/sql/nt_servc.cc
@@ -496,9 +496,9 @@ BOOL NTService::IsService(LPCSTR ServiceName)
BOOL ret_value=FALSE;
SC_HANDLE service, scm;
- if (scm = OpenSCManager(0, 0,SC_MANAGER_ENUMERATE_SERVICE))
+ if ((scm= OpenSCManager(0, 0,SC_MANAGER_ENUMERATE_SERVICE)))
{
- if ((service = OpenService(scm,ServiceName, SERVICE_ALL_ACCESS )))
+ if ((service = OpenService(scm,ServiceName, SERVICE_QUERY_STATUS )))
{
ret_value=TRUE;
CloseServiceHandle(service);
diff --git a/sql/opt_ft.cc b/sql/opt_ft.cc
index b35b3230a39..74349819937 100644
--- a/sql/opt_ft.cc
+++ b/sql/opt_ft.cc
@@ -26,11 +26,11 @@
** Create a FT or QUICK RANGE based on a key
****************************************************************************/
-QUICK_SELECT *get_ft_or_quick_select_for_ref(TABLE *table, JOIN_TAB *tab)
+QUICK_SELECT *get_ft_or_quick_select_for_ref(THD *thd, TABLE *table,
+ JOIN_TAB *tab)
{
if (tab->type == JT_FT)
- return new FT_SELECT(table, &tab->ref);
- else
- return get_quick_select_for_ref(table, &tab->ref);
+ return new FT_SELECT(thd, table, &tab->ref);
+ return get_quick_select_for_ref(thd, table, &tab->ref);
}
diff --git a/sql/opt_ft.h b/sql/opt_ft.h
index dcbbb8abcec..69b6b72f3fc 100644
--- a/sql/opt_ft.h
+++ b/sql/opt_ft.h
@@ -28,13 +28,14 @@ class FT_SELECT: public QUICK_SELECT {
public:
TABLE_REF *ref;
- FT_SELECT(TABLE *table, TABLE_REF *tref) :
- QUICK_SELECT (table,tref->key,1), ref(tref) {}
+ FT_SELECT(THD *thd, TABLE *table, TABLE_REF *tref) :
+ QUICK_SELECT (thd, table, tref->key, 1), ref(tref) { init(); }
int init() { return error=file->ft_init(); }
int get_next() { return error=file->ft_read(record); }
};
-QUICK_SELECT *get_ft_or_quick_select_for_ref(TABLE *table, JOIN_TAB *tab);
+QUICK_SELECT *get_ft_or_quick_select_for_ref(THD *thd, TABLE *table,
+ JOIN_TAB *tab);
#endif
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 931093d548a..188d503b767 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -23,8 +23,6 @@
*/
-
-
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
@@ -33,6 +31,7 @@
#include <m_ctype.h>
#include <nisam.h>
#include "sql_select.h"
+#include <assert.h>
#ifndef EXTRA_DEBUG
@@ -66,10 +65,12 @@ public:
SEL_ARG(Field *field, uint8 part, char *min_value, char *max_value,
uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
SEL_ARG(enum Type type_arg)
- :elements(1),use_count(1),left(0),next_key_part(0),type(type_arg) {}
+ :elements(1),use_count(1),left(0),next_key_part(0),color(BLACK),
+ type(type_arg)
+ {}
inline bool is_same(SEL_ARG *arg)
{
- if (type != arg->type)
+ if (type != arg->type || part != arg->part)
return 0;
if (type != KEY_RANGE)
return 1;
@@ -279,21 +280,23 @@ public:
typedef struct st_qsel_param {
- uint baseflag,keys,max_key_part;
- table_map prev_tables,read_tables,current_table;
+ THD *thd;
TABLE *table;
- bool quick; // Don't calulate possible keys
KEY_PART *key_parts,*key_parts_end,*key[MAX_KEY];
+ MEM_ROOT *mem_root;
+ table_map prev_tables,read_tables,current_table;
+ uint baseflag, keys, max_key_part, range_count;
uint real_keynr[MAX_KEY];
char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
+ bool quick; // Don't calulate possible keys
+ COND *cond;
} PARAM;
-
static SEL_TREE * get_mm_parts(PARAM *param,Field *field,
Item_func::Functype type,Item *value,
Item_result cmp_type);
-static SEL_ARG *get_mm_leaf(Field *field,KEY_PART *key_part,
+static SEL_ARG *get_mm_leaf(PARAM *param,Field *field,KEY_PART *key_part,
Item_func::Functype type,Item *value);
static bool like_range(const char *ptr,uint length,char wild_prefix,
uint field_length, char *min_str,char *max_str,
@@ -344,8 +347,8 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
DBUG_RETURN(0);
if (!(select= new SQL_SELECT))
{
- *error= 1;
- DBUG_RETURN(0); /* purecov: inspected */
+ *error= 1; // out of memory
+ DBUG_RETURN(0); /* purecov: inspected */
}
select->read_tables=read_tables;
select->const_tables=const_tables;
@@ -381,13 +384,14 @@ SQL_SELECT::~SQL_SELECT()
#undef index // Fix for Unixware 7
-QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc)
- :error(0),index(key_nr),max_used_key_length(0),head(table),
+QUICK_SELECT::QUICK_SELECT(THD *thd, TABLE *table, uint key_nr, bool no_alloc)
+ :dont_free(0),error(0),index(key_nr),max_used_key_length(0),head(table),
it(ranges),range(0)
{
if (!no_alloc)
{
- init_sql_alloc(&alloc,1024,0); // Allocates everything here
+ // Allocates everything through the internal memroot
+ init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
my_pthread_setspecific_ptr(THR_MALLOC,&alloc);
}
else
@@ -399,13 +403,11 @@ QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc)
QUICK_SELECT::~QUICK_SELECT()
{
- file->index_end();
- free_root(&alloc,MYF(0));
-}
-
-int QUICK_SELECT::init()
-{
- return error=file->index_init(index);
+ if (!dont_free)
+ {
+ file->index_end();
+ free_root(&alloc,MYF(0));
+ }
}
QUICK_RANGE::QUICK_RANGE()
@@ -461,15 +463,17 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
SEL_ARG *tmp;
if (type != KEY_RANGE)
{
- tmp=new SEL_ARG(type);
+ if (!(tmp= new SEL_ARG(type)))
+ return 0; // out of memory
tmp->prev= *next_arg; // Link into next/prev chain
(*next_arg)->next=tmp;
(*next_arg)= tmp;
}
else
{
- tmp=new SEL_ARG(field,part, min_value,max_value,
- min_flag, max_flag, maybe_flag);
+ if (!(tmp= new SEL_ARG(field,part, min_value,max_value,
+ min_flag, max_flag, maybe_flag)))
+ return 0; // OOM
tmp->parent=new_parent;
tmp->next_key_part=next_key_part;
if (left != &null_element)
@@ -480,7 +484,8 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
(*next_arg)= tmp;
if (right != &null_element)
- tmp->right=right->clone(tmp,next_arg);
+ if (!(tmp->right= right->clone(tmp,next_arg)))
+ return 0; // OOM
}
increment_use_count(1);
return tmp;
@@ -506,10 +511,11 @@ SEL_ARG *SEL_ARG::last()
return next_arg;
}
+
/*
Check if a compare is ok, when one takes ranges in account
Returns -2 or 2 if the ranges where 'joined' like < 2 and >= 2
- */
+*/
static int sel_cmp(Field *field, char *a,char *b,uint8 a_flag,uint8 b_flag)
{
@@ -533,7 +539,7 @@ static int sel_cmp(Field *field, char *a,char *b,uint8 a_flag,uint8 b_flag)
}
if (*a)
goto end; // NULL where equal
- a++; b++; // Skipp NULL marker
+ a++; b++; // Skip NULL marker
}
cmp=field->key_cmp((byte*) a,(byte*) b);
if (cmp) return cmp < 0 ? -1 : 1; // The values differed
@@ -558,10 +564,11 @@ SEL_ARG *SEL_ARG::clone_tree()
{
SEL_ARG tmp_link,*next_arg,*root;
next_arg= &tmp_link;
- root=clone((SEL_ARG *) 0, &next_arg);
+ root= clone((SEL_ARG *) 0, &next_arg);
next_arg->next=0; // Fix last link
tmp_link.next->prev=0; // Fix first link
- root->use_count=0;
+ if (root) // If not OOM
+ root->use_count= 0;
return root;
}
@@ -579,13 +586,17 @@ SEL_ARG *SEL_ARG::clone_tree()
** quick_rows ; How many rows the key matches
*****************************************************************************/
-int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
+int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
+ table_map prev_tables,
ha_rows limit, bool force_quick_range)
{
uint basflag;
uint idx;
double scan_time;
DBUG_ENTER("test_quick_select");
+ DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu",
+ (ulong) keys_to_use, (ulong) prev_tables,
+ (ulong) const_tables));
delete quick;
quick=0;
@@ -593,7 +604,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
if (!cond || (specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range ||
!limit)
DBUG_RETURN(0); /* purecov: inspected */
- if (!((basflag= head->file->option_flag()) & HA_KEYPOS_TO_RNDPOS) &&
+ if (!((basflag= head->file->table_flags()) & HA_KEYPOS_TO_RNDPOS) &&
keys_to_use == (uint) ~0 || !keys_to_use)
DBUG_RETURN(0); /* Not smart database */
records=head->file->records;
@@ -601,12 +612,14 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
records++; /* purecov: inspected */
scan_time=(double) records / TIME_FOR_COMPARE+1;
read_time=(double) head->file->scan_time()+ scan_time + 1.0;
+ if (head->force_index)
+ scan_time= read_time= DBL_MAX;
if (limit < records)
read_time=(double) records+scan_time+1; // Force to use index
else if (read_time <= 2.0 && !force_quick_range)
- DBUG_RETURN(0); /* No nead for quick select */
+ DBUG_RETURN(0); /* No need for quick select */
- DBUG_PRINT("info",("Time to scan table: %ld",(long) read_time));
+ DBUG_PRINT("info",("Time to scan table: %g", read_time));
keys_to_use&=head->keys_in_use_for_query;
if (keys_to_use)
@@ -617,20 +630,21 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
PARAM param;
/* set up parameter that is passed to all functions */
+ param.thd= thd;
param.baseflag=basflag;
param.prev_tables=prev_tables | const_tables;
param.read_tables=read_tables;
param.current_table= head->map;
param.table=head;
param.keys=0;
-
- current_thd->no_errors=1; // Don't warn about NULL
- init_sql_alloc(&alloc,2048,0);
+ param.mem_root= &alloc;
+ param.thd->no_errors=1; // Don't warn about NULL
+ init_sql_alloc(&alloc, param.thd->variables.range_alloc_block_size, 0);
if (!(param.key_parts = (KEY_PART*) alloc_root(&alloc,
sizeof(KEY_PART)*
head->key_parts)))
{
- current_thd->no_errors=0;
+ param.thd->no_errors=0;
free_root(&alloc,MYF(0)); // Return memory & allocator
DBUG_RETURN(0); // Can't use range
}
@@ -679,34 +693,36 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
{
ha_rows found_records;
double found_read_time;
-
if (*key)
{
+ uint keynr= param.real_keynr[idx];
if ((*key)->type == SEL_ARG::MAYBE_KEY ||
(*key)->maybe_flag)
- needed_reg|= (key_map) 1 << param.real_keynr[idx];
+ needed_reg|= (key_map) 1 << keynr;
- found_records=check_quick_select(&param,idx, *key);
+ found_records=check_quick_select(&param, idx, *key);
if (found_records != HA_POS_ERROR && found_records > 2 &&
- head->used_keys & ((table_map) 1 << param.real_keynr[idx]) &&
- (head->file->option_flag() & HA_HAVE_KEY_READ_ONLY))
+ head->used_keys & ((table_map) 1 << keynr) &&
+ (head->file->index_flags(keynr) & HA_KEY_READ_ONLY))
{
/*
- ** We can resolve this by only reading through this key
- ** Assume that we will read trough the whole key range
- ** and that all key blocks are half full (normally things are
- ** much better)
+ We can resolve this by only reading through this key.
+ Assume that we will read trough the whole key range
+ and that all key blocks are half full (normally things are
+ much better).
*/
- uint keys_per_block= head->file->block_size/2/
- (head->key_info[param.real_keynr[idx]].key_length+
- head->file->ref_length) + 1;
+ uint keys_per_block= (head->file->block_size/2/
+ (head->key_info[keynr].key_length+
+ head->file->ref_length) + 1);
found_read_time=((double) (found_records+keys_per_block-1)/
(double) keys_per_block);
}
else
- found_read_time= head->file->read_time(found_records)+
- (double) found_records / TIME_FOR_COMPARE;
- if (read_time > found_read_time)
+ found_read_time= (head->file->read_time(keynr,
+ param.range_count,
+ found_records)+
+ (double) found_records / TIME_FOR_COMPARE);
+ if (read_time > found_read_time && found_records != HA_POS_ERROR)
{
read_time=found_read_time;
records=found_records;
@@ -727,7 +743,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
}
free_root(&alloc,MYF(0)); // Return memory & allocator
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
- current_thd->no_errors=0;
+ param.thd->no_errors=0;
}
DBUG_EXECUTE("info",print_quick(quick,needed_reg););
/*
@@ -755,6 +771,8 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
while ((item=li++))
{
SEL_TREE *new_tree=get_mm_tree(param,item);
+ if (param->thd->fatal_error)
+ DBUG_RETURN(0); // out of memory
tree=tree_and(param,tree,new_tree);
if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
break;
@@ -770,7 +788,7 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
{
SEL_TREE *new_tree=get_mm_tree(param,item);
if (!new_tree)
- DBUG_RETURN(0);
+ DBUG_RETURN(0); // out of memory
tree=tree_or(param,tree,new_tree);
if (!tree || tree->type == SEL_TREE::ALWAYS)
break;
@@ -786,34 +804,35 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
DBUG_RETURN(new SEL_TREE(SEL_TREE::IMPOSSIBLE));
}
+
table_map ref_tables=cond->used_tables();
- if (ref_tables & ~(param->prev_tables | param->read_tables |
- param->current_table))
- DBUG_RETURN(0); // Can't be calculated yet
if (cond->type() != Item::FUNC_ITEM)
{ // Should be a field
- if (ref_tables & param->current_table)
+ if ((ref_tables & param->current_table) ||
+ (ref_tables & ~(param->prev_tables | param->read_tables)))
DBUG_RETURN(0);
DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE));
}
- if (!(ref_tables & param->current_table))
- DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); // This may be false or true
+
Item_func *cond_func= (Item_func*) cond;
if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
DBUG_RETURN(0); // Can't be calculated
+ param->cond= cond;
+
if (cond_func->functype() == Item_func::BETWEEN)
{
if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
{
Field *field=((Item_field*) (cond_func->arguments()[0]))->field;
Item_result cmp_type=field->cmp_type();
- tree= get_mm_parts(param,field,Item_func::GE_FUNC,
- cond_func->arguments()[1],cmp_type);
- DBUG_RETURN(tree_and(param,tree,
+ DBUG_RETURN(tree_and(param,
+ get_mm_parts(param, field,
+ Item_func::GE_FUNC,
+ cond_func->arguments()[1], cmp_type),
get_mm_parts(param, field,
Item_func::LE_FUNC,
- cond_func->arguments()[2],cmp_type)));
+ cond_func->arguments()[2], cmp_type)));
}
DBUG_RETURN(0);
}
@@ -839,6 +858,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
DBUG_RETURN(0); // Can't optimize this IN
}
+ if (ref_tables & ~(param->prev_tables | param->read_tables |
+ param->current_table))
+ DBUG_RETURN(0); // Can't be calculated yet
+ if (!(ref_tables & param->current_table))
+ DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); // This may be false or true
+
/* check field op const */
/* btw, ft_func's arguments()[0] isn't FIELD_ITEM. SerG*/
if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
@@ -870,28 +895,29 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
static SEL_TREE *
-get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
- Item_result cmp_type)
+get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
+ Item *value, Item_result cmp_type)
{
DBUG_ENTER("get_mm_parts");
if (field->table != param->table)
DBUG_RETURN(0);
- KEY_PART *key_part = param->key_parts,*end=param->key_parts_end;
+ KEY_PART *key_part = param->key_parts;
+ KEY_PART *end = param->key_parts_end;
SEL_TREE *tree=0;
if (value &&
value->used_tables() & ~(param->prev_tables | param->read_tables))
DBUG_RETURN(0);
- for ( ; key_part != end ; key_part++)
+ for (; key_part != end ; key_part++)
{
if (field->eq(key_part->field))
{
SEL_ARG *sel_arg=0;
- if (!tree)
- tree=new SEL_TREE();
+ if (!tree && !(tree=new SEL_TREE()))
+ DBUG_RETURN(0); // OOM
if (!value || !(value->used_tables() & ~param->read_tables))
{
- sel_arg=get_mm_leaf(key_part->field,key_part,type,value);
+ sel_arg=get_mm_leaf(param,key_part->field,key_part,type,value);
if (!sel_arg)
continue;
if (sel_arg->type == SEL_ARG::IMPOSSIBLE)
@@ -901,7 +927,11 @@ get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
}
}
else
- sel_arg=new SEL_ARG(SEL_ARG::MAYBE_KEY);// This key may be used later
+ {
+ // This key may be used later
+ if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
+ DBUG_RETURN(0); // OOM
+ }
sel_arg->part=(uchar) key_part->part;
tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
}
@@ -911,12 +941,13 @@ get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
static SEL_ARG *
-get_mm_leaf(Field *field,KEY_PART *key_part,
+get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
Item_func::Functype type,Item *value)
{
- uint maybe_null=(uint) field->real_maybe_null();
+ uint maybe_null=(uint) field->real_maybe_null(), copies;
uint field_length=field->pack_length()+maybe_null;
SEL_ARG *tree;
+ char *str, *str2;
DBUG_ENTER("get_mm_leaf");
if (type == Item_func::LIKE_FUNC)
@@ -926,7 +957,7 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
String tmp(buff1,sizeof(buff1)),*res;
uint length,offset,min_length,max_length;
- if (!field->optimize_range())
+ if (!field->optimize_range((uint) key_part->key))
DBUG_RETURN(0); // Can't optimize this
if (!(res= value->val_str(&tmp)))
DBUG_RETURN(&null_element);
@@ -959,29 +990,32 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
field_length=length;
}
length+=offset;
- if (!(min_str= (char*) sql_alloc(length*2)))
+ if (!(min_str= (char*) alloc_root(param->mem_root, length*2)))
DBUG_RETURN(0);
max_str=min_str+length;
if (maybe_null)
max_str[0]= min_str[0]=0;
if (field->binary())
- like_error=like_range(res->ptr(),res->length(),wild_prefix,field_length,
- min_str+offset,max_str+offset,(char) 255,
- &min_length,&max_length);
+ like_error=like_range(res->ptr(), res->length(),
+ ((Item_func_like*)(param->cond))->escape,
+ field_length, min_str + offset, max_str + offset,
+ (char) 255, &min_length, &max_length);
else
{
#ifdef USE_STRCOLL
if (use_strcoll(default_charset_info))
- like_error= my_like_range(default_charset_info,
- res->ptr(),res->length(),wild_prefix,
- field_length, min_str+maybe_null,
- max_str+maybe_null,&min_length,&max_length);
+ like_error= my_like_range(default_charset_info, res->ptr(),
+ res->length(),
+ ((Item_func_like*)(param->cond))->escape,
+ field_length, min_str + maybe_null,
+ max_str + maybe_null, &min_length,
+ &max_length);
else
#endif
- like_error=like_range(res->ptr(),res->length(),wild_prefix,
- field_length,
- min_str+offset,max_str+offset,
- max_sort_char,&min_length,&max_length);
+ like_error=like_range(res->ptr(), res->length(),
+ ((Item_func_like*)(param->cond))->escape,
+ field_length, min_str + offset, max_str + offset,
+ max_sort_char, &min_length, &max_length);
}
if (like_error) // Can't optimize with LIKE
DBUG_RETURN(0);
@@ -999,9 +1033,8 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
DBUG_RETURN(0);
if (!maybe_null) // Not null field
DBUG_RETURN(type == Item_func::ISNULL_FUNC ? &null_element : 0);
- tree=new SEL_ARG(field,is_null_string,is_null_string);
- if (!tree)
- DBUG_RETURN(0);
+ if (!(tree=new SEL_ARG(field,is_null_string,is_null_string)))
+ DBUG_RETURN(0); // out of memory
if (type == Item_func::ISNOTNULL_FUNC)
{
tree->min_flag=NEAR_MIN; /* IS NOT NULL -> X > NULL */
@@ -1010,7 +1043,8 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
DBUG_RETURN(tree);
}
- if (!field->optimize_range() && type != Item_func::EQ_FUNC &&
+ if (!field->optimize_range((uint) key_part->key) &&
+ type != Item_func::EQ_FUNC &&
type != Item_func::EQUAL_FUNC)
DBUG_RETURN(0); // Can't optimize this
@@ -1023,29 +1057,43 @@ get_mm_leaf(Field *field,KEY_PART *key_part,
field->cmp_type() != value->result_type())
DBUG_RETURN(0);
- if (value->save_in_field(field))
+ if (value->save_in_field(field, 1))
{
/* This happens when we try to insert a NULL field in a not null column */
- if (type == Item_func::EQUAL_FUNC)
- {
- /* convert column_name <=> NULL -> column_name IS NULL */
- char *str= (char*) sql_alloc(1); // Get local copy of key
- if (!str)
- DBUG_RETURN(0);
- *str = 1;
- DBUG_RETURN(new SEL_ARG(field,str,str));
- }
DBUG_RETURN(&null_element); // cmp with NULL is never true
}
- // Get local copy of key
- char *str= (char*) sql_alloc(key_part->part_length+maybe_null);
+ /* Get local copy of key */
+ copies= 1;
+ if (field->key_type() == HA_KEYTYPE_VARTEXT)
+ copies= 2;
+ str= str2= (char*) alloc_root(param->mem_root,
+ (key_part->part_length+maybe_null)*copies+1);
if (!str)
DBUG_RETURN(0);
if (maybe_null)
*str= (char) field->is_real_null(); // Set to 1 if null
field->get_key_image(str+maybe_null,key_part->part_length);
- if (!(tree=new SEL_ARG(field,str,str)))
- DBUG_RETURN(0);
+ if (copies == 2)
+ {
+ /*
+ The key is stored as 2 byte length + key
+ key doesn't match end space. In other words, a key 'X ' should match
+ all rows between 'X' and 'X ...'
+ */
+ uint length= uint2korr(str+maybe_null);
+ str2= str+ key_part->part_length + maybe_null;
+ /* remove end space */
+ while (length > 0 && str[length+HA_KEY_BLOB_LENGTH+maybe_null-1] == ' ')
+ length--;
+ int2store(str+maybe_null, length);
+ /* Create key that is space filled */
+ memcpy(str2, str, length + HA_KEY_BLOB_LENGTH + maybe_null);
+ bfill(str2+ length+ HA_KEY_BLOB_LENGTH +maybe_null,
+ key_part->part_length-length - HA_KEY_BLOB_LENGTH, ' ');
+ int2store(str2+maybe_null, key_part->part_length - HA_KEY_BLOB_LENGTH);
+ }
+ if (!(tree=new SEL_ARG(field,str,str2)))
+ DBUG_RETURN(0); // out of memory
switch (type) {
case Item_func::LT_FUNC:
@@ -1104,7 +1152,7 @@ static bool like_range(const char *ptr,uint ptr_length,char escape,
{
if (*ptr == escape && ptr+1 != end)
{
- ptr++; // Skipp escape
+ ptr++; // Skip escape
*min_str++= *max_str++ = *ptr;
continue;
}
@@ -1151,8 +1199,8 @@ static bool like_range(const char *ptr,uint ptr_length,char escape,
******************************************************************************/
/*
-** Add a new key test to a key when scanning through all keys
-** This will never be called for same key parts.
+ Add a new key test to a key when scanning through all keys
+ This will never be called for same key parts.
*/
static SEL_ARG *
@@ -1336,7 +1384,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
// key1->part < key2->part
key1->use_count--;
if (key1->use_count > 0)
- key1=key1->clone_tree();
+ if (!(key1= key1->clone_tree()))
+ return 0; // OOM
return and_all_keys(key1,key2,clone_flag);
}
@@ -1355,7 +1404,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
if (key1->use_count > 1)
{
key1->use_count--;
- key1=key1->clone_tree();
+ if (!(key1=key1->clone_tree()))
+ return 0; // OOM
key1->use_count++;
}
if (key1->type == SEL_ARG::MAYBE_KEY)
@@ -1399,6 +1449,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
if (!next || next->type != SEL_ARG::IMPOSSIBLE)
{
SEL_ARG *new_arg= e1->clone_and(e2);
+ if (!new_arg)
+ return &null_element; // End of memory
new_arg->next_key_part=next;
if (!new_tree)
{
@@ -1450,7 +1502,7 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
}
return 0;
}
- else if (!key2)
+ if (!key2)
{
key1->use_count--;
key1->free_tree();
@@ -1486,8 +1538,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
{
swap(SEL_ARG *,key1,key2);
}
- else
- key1=key1->clone_tree();
+ else if (!(key1=key1->clone_tree()))
+ return 0; // OOM
}
// Add tree at key2 to tree at key1
@@ -1513,7 +1565,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
SEL_ARG *key2_next=key2->next;
if (key2_shared)
{
- key2=new SEL_ARG(*key2);
+ if (!(key2=new SEL_ARG(*key2)))
+ return 0; // out of memory
key2->increment_use_count(key1->use_count+1);
key2->next=key2_next; // New copy of key2
}
@@ -1554,7 +1607,10 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
SEL_ARG *next=key2->next; // Keys are not overlapping
if (key2_shared)
{
- key1=key1->insert(new SEL_ARG(*key2)); // Must make copy
+ SEL_ARG *tmp= new SEL_ARG(*key2); // Must make copy
+ if (!tmp)
+ return 0; // OOM
+ key1=key1->insert(tmp);
key2->increment_use_count(key1->use_count+1);
}
else
@@ -1600,6 +1656,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
{ // tmp.min <= x < key2.min
SEL_ARG *new_arg=tmp->clone_first(key2);
+ if (!new_arg)
+ return 0; // OOM
if ((new_arg->next_key_part= key1->next_key_part))
new_arg->increment_use_count(key1->use_count+1);
tmp->copy_min_to_min(key2);
@@ -1613,6 +1671,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
if (tmp->cmp_min_to_min(&key) > 0)
{ // key.min <= x < tmp.min
SEL_ARG *new_arg=key.clone_first(tmp);
+ if (!new_arg)
+ return 0; // OOM
if ((new_arg->next_key_part=key.next_key_part))
new_arg->increment_use_count(key1->use_count+1);
key1=key1->insert(new_arg);
@@ -1627,21 +1687,31 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
key.copy_max_to_min(tmp);
if (!(tmp=tmp->next))
{
- key1=key1->insert(new SEL_ARG(key));
+ SEL_ARG *tmp2= new SEL_ARG(key);
+ if (!tmp2)
+ return 0; // OOM
+ key1=key1->insert(tmp2);
key2=key2->next;
goto end;
}
if (tmp->cmp_min_to_max(&key) > 0)
{
- key1=key1->insert(new SEL_ARG(key));
+ SEL_ARG *tmp2= new SEL_ARG(key);
+ if (!tmp2)
+ return 0; // OOM
+ key1=key1->insert(tmp2);
break;
}
}
else
{
SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max
+ if (!new_arg)
+ return 0; // OOM
tmp->copy_max_to_min(&key);
tmp->increment_use_count(key1->use_count+1);
+ /* Increment key count as it may be used for next loop */
+ key.increment_use_count(1);
new_arg->next_key_part=key_or(tmp->next_key_part,key.next_key_part);
key1=key1->insert(new_arg);
break;
@@ -1656,8 +1726,11 @@ end:
SEL_ARG *next=key2->next;
if (key2_shared)
{
+ SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy
+ if (!tmp)
+ return 0;
key2->increment_use_count(key1->use_count+1);
- key1=key1->insert(new SEL_ARG(*key2)); // Must make copy
+ key1=key1->insert(tmp);
}
else
key1=key1->insert(key2); // Will destroy key2_root
@@ -2114,11 +2187,12 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
if (!tree)
DBUG_RETURN(HA_POS_ERROR); // Can't use it
+ param->max_key_part=0;
+ param->range_count=0;
if (tree->type == SEL_ARG::IMPOSSIBLE)
DBUG_RETURN(0L); // Impossible select. return
if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
DBUG_RETURN(HA_POS_ERROR); // Don't use tree
- param->max_key_part=0;
records=check_quick_keys(param,idx,tree,param->min_key,0,param->max_key,0);
if (records != HA_POS_ERROR)
{
@@ -2186,9 +2260,11 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
}
keynr=param->real_keynr[idx];
+ param->range_count++;
if (!tmp_min_flag && ! tmp_max_flag &&
(uint) key_tree->part+1 == param->table->key_info[keynr].key_parts &&
- (param->table->key_info[keynr].flags & HA_NOSAME) &&
+ (param->table->key_info[keynr].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
+ HA_NOSAME &&
min_key_length == max_key_length &&
!memcmp(param->min_key,param->max_key,min_key_length))
tmp=1; // Max one record
@@ -2231,7 +2307,8 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree)
{
QUICK_SELECT *quick;
DBUG_ENTER("get_quick_select");
- if ((quick=new QUICK_SELECT(param->table,param->real_keynr[idx])))
+ if ((quick=new QUICK_SELECT(param->thd, param->table,
+ param->real_keynr[idx])))
{
if (quick->error ||
get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0,
@@ -2243,7 +2320,7 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree)
else
{
quick->key_parts=(KEY_PART*)
- sql_memdup(param->key[idx],
+ memdup_root(&quick->alloc,(char*) param->key[idx],
sizeof(KEY_PART)*
param->table->key_info[param->real_keynr[idx]].key_parts);
}
@@ -2321,7 +2398,8 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key,
{
KEY *table_key=quick->head->key_info+quick->index;
flag=EQ_RANGE;
- if (table_key->flags & HA_NOSAME && key->part == table_key->key_parts-1)
+ if ((table_key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME &&
+ key->part == table_key->key_parts-1)
{
if (!(table_key->flags & HA_NULL_PART_KEY) ||
!null_part_in_key(key,
@@ -2335,15 +2413,15 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key,
}
/* Get range for retrieving rows in QUICK_SELECT::get_next */
- range= new QUICK_RANGE(param->min_key,
- (uint) (tmp_min_key - param->min_key),
- param->max_key,
- (uint) (tmp_max_key - param->max_key),
- flag);
+ if (!(range= new QUICK_RANGE(param->min_key,
+ (uint) (tmp_min_key - param->min_key),
+ param->max_key,
+ (uint) (tmp_max_key - param->max_key),
+ flag)))
+ return 1; // out of memory
+
set_if_bigger(quick->max_used_key_length,range->min_length);
set_if_bigger(quick->max_used_key_length,range->max_length);
- if (!range) // Not enough memory
- return 1;
quick->ranges.push_back(range);
end:
@@ -2366,7 +2444,7 @@ bool QUICK_SELECT::unique_key_range()
if (((tmp=ranges.head())->flag & (EQ_RANGE | NULL_RANGE)) == EQ_RANGE)
{
KEY *key=head->key_info+index;
- return ((key->flags & HA_NOSAME) &&
+ return ((key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME &&
key->key_length == tmp->min_length);
}
}
@@ -2395,26 +2473,35 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length)
** Create a QUICK RANGE based on a key
****************************************************************************/
-QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref)
+QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref)
{
table->file->index_end(); // Remove old cursor
- QUICK_SELECT *quick=new QUICK_SELECT(table, ref->key, 1);
+ QUICK_SELECT *quick=new QUICK_SELECT(thd, table, ref->key, 1);
KEY *key_info = &table->key_info[ref->key];
KEY_PART *key_part;
+ QUICK_RANGE *range;
uint part;
if (!quick)
- return 0;
- QUICK_RANGE *range= new QUICK_RANGE();
- if (!range || cp_buffer_from_ref(ref))
- goto err;
+ return 0; /* no ranges found */
+ if (cp_buffer_from_ref(ref))
+ {
+ if (thd->fatal_error)
+ goto err; // out of memory
+ return quick; // empty range
+ }
+
+ if (!(range= new QUICK_RANGE()))
+ goto err; // out of memory
+
range->min_key=range->max_key=(char*) ref->key_buff;
range->min_length=range->max_length=ref->key_length;
range->flag= ((ref->key_length == key_info->key_length &&
- (key_info->flags & HA_NOSAME)) ? EQ_RANGE : 0);
+ (key_info->flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
+ HA_NOSAME) ? EQ_RANGE : 0);
if (!(quick->key_parts=key_part=(KEY_PART *)
- sql_alloc(sizeof(KEY_PART)*ref->key_parts)))
+ alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
goto err;
for (part=0 ; part < ref->key_parts ;part++,key_part++)
@@ -2462,12 +2549,12 @@ int QUICK_SELECT::get_next()
DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
if (range->flag & NO_MIN_RANGE) // Read first record
{
- int error;
- if ((error=file->index_first(record)))
- DBUG_RETURN(error); // Empty table
+ int local_error;
+ if ((local_error=file->index_first(record)))
+ DBUG_RETURN(local_error); // Empty table
if (cmp_next(range) == 0)
- DBUG_RETURN(0); // No matching records
- range=0; // To next range
+ DBUG_RETURN(0);
+ range=0; // No matching records; go to next range
continue;
}
if ((result = file->index_read(record,(byte*) range->min_key,
@@ -2497,13 +2584,13 @@ int QUICK_SELECT::get_next()
/* compare if found key is over max-value */
/* Returns 0 if key <= range->max_key */
-int QUICK_SELECT::cmp_next(QUICK_RANGE *range)
+int QUICK_SELECT::cmp_next(QUICK_RANGE *range_arg)
{
- if (range->flag & NO_MAX_RANGE)
- return (0); /* key can't be to large */
+ if (range_arg->flag & NO_MAX_RANGE)
+ return 0; /* key can't be to large */
KEY_PART *key_part=key_parts;
- for (char *key=range->max_key, *end=key+range->max_length;
+ for (char *key=range_arg->max_key, *end=key+range_arg->max_length;
key < end;
key+= key_part++->part_length)
{
@@ -2524,9 +2611,243 @@ int QUICK_SELECT::cmp_next(QUICK_RANGE *range)
if (cmp > 0)
return 1;
}
- return (range->flag & NEAR_MAX) ? 1 : 0; // Exact match
+ return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match
}
+
+/*
+ This is a hack: we inherit from QUICK_SELECT so that we can use the
+ get_next() interface, but we have to hold a pointer to the original
+ QUICK_SELECT because its data are used all over the place. What
+ should be done is to factor out the data that is needed into a base
+ class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC)
+ which handle the ranges and implement the get_next() function. But
+ for now, this seems to work right at least.
+ */
+
+QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_SELECT *q, uint used_key_parts)
+ : QUICK_SELECT(*q), rev_it(rev_ranges)
+{
+ bool not_read_after_key = file->table_flags() & HA_NOT_READ_AFTER_KEY;
+ QUICK_RANGE *r;
+
+ it.rewind();
+ for (r = it++; r; r = it++)
+ {
+ rev_ranges.push_front(r);
+ if (not_read_after_key && range_reads_after_key(r))
+ {
+ it.rewind(); // Reset range
+ error = HA_ERR_UNSUPPORTED;
+ dont_free=1; // Don't free memory from 'q'
+ return;
+ }
+ }
+ /* Remove EQ_RANGE flag for keys that are not using the full key */
+ for (r = rev_it++; r; r = rev_it++)
+ {
+ if ((r->flag & EQ_RANGE) &&
+ head->key_info[index].key_length != r->max_length)
+ r->flag&= ~EQ_RANGE;
+ }
+ rev_it.rewind();
+ q->dont_free=1; // Don't free shared mem
+ delete q;
+}
+
+
+int QUICK_SELECT_DESC::get_next()
+{
+ DBUG_ENTER("QUICK_SELECT_DESC::get_next");
+
+ /* The max key is handled as follows:
+ * - if there is NO_MAX_RANGE, start at the end and move backwards
+ * - if it is an EQ_RANGE, which means that max key covers the entire
+ * key, go directly to the key and read through it (sorting backwards is
+ * same as sorting forwards)
+ * - if it is NEAR_MAX, go to the key or next, step back once, and
+ * move backwards
+ * - otherwise (not NEAR_MAX == include the key), go after the key,
+ * step back once, and move backwards
+ */
+
+ for (;;)
+ {
+ int result;
+ if (range)
+ { // Already read through key
+ result = ((range->flag & EQ_RANGE)
+ ? file->index_next_same(record, (byte*) range->min_key,
+ range->min_length) :
+ file->index_prev(record));
+ if (!result)
+ {
+ if (cmp_prev(*rev_it.ref()) == 0)
+ DBUG_RETURN(0);
+ }
+ else if (result != HA_ERR_END_OF_FILE)
+ DBUG_RETURN(result);
+ }
+
+ if (!(range=rev_it++))
+ DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
+
+ if (range->flag & NO_MAX_RANGE) // Read last record
+ {
+ int local_error;
+ if ((local_error=file->index_last(record)))
+ DBUG_RETURN(local_error); // Empty table
+ if (cmp_prev(range) == 0)
+ DBUG_RETURN(0);
+ range=0; // No matching records; go to next range
+ continue;
+ }
+
+ if (range->flag & EQ_RANGE)
+ {
+ result = file->index_read(record, (byte*) range->max_key,
+ range->max_length, HA_READ_KEY_EXACT);
+ }
+ else
+ {
+ /*
+ Heikki changed Sept 11, 2002: since InnoDB does not store the cursor
+ position if READ_KEY_EXACT is used to a primary key with all
+ key columns specified, we must use below HA_READ_KEY_OR_NEXT,
+ so that InnoDB stores the cursor position and is able to move
+ the cursor one step backward after the search. */
+
+ DBUG_ASSERT(range->flag & NEAR_MAX || range_reads_after_key(range));
+ /*
+ Note: even if max_key is only a prefix, HA_READ_AFTER_KEY will
+ do the right thing - go past all keys which match the prefix
+ */
+ result=file->index_read(record, (byte*) range->max_key,
+ range->max_length,
+ ((range->flag & NEAR_MAX) ?
+ HA_READ_KEY_OR_NEXT : HA_READ_AFTER_KEY));
+ result = file->index_prev(record);
+ }
+ if (result)
+ {
+ if (result != HA_ERR_KEY_NOT_FOUND)
+ DBUG_RETURN(result);
+ range=0; // Not found, to next range
+ continue;
+ }
+ if (cmp_prev(range) == 0)
+ {
+ if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
+ range = 0; // Stop searching
+ DBUG_RETURN(0); // Found key is in range
+ }
+ range = 0; // To next range
+ }
+}
+
+
+/*
+ Returns 0 if found key is inside range (found key >= range->min_key).
+*/
+
+int QUICK_SELECT_DESC::cmp_prev(QUICK_RANGE *range_arg)
+{
+ if (range_arg->flag & NO_MIN_RANGE)
+ return 0; /* key can't be to small */
+
+ KEY_PART *key_part = key_parts;
+ for (char *key = range_arg->min_key, *end = key + range_arg->min_length;
+ key < end;
+ key += key_part++->part_length)
+ {
+ int cmp;
+ if (key_part->null_bit)
+ {
+ // this key part allows null values; NULL is lower than everything else
+ if (*key++)
+ {
+ // the range is expecting a null value
+ if (!key_part->field->is_null())
+ return 0; // not null -- still inside the range
+ continue; // null -- exact match, go to next key part
+ }
+ else if (key_part->field->is_null())
+ return 1; // null -- outside the range
+ }
+ if ((cmp = key_part->field->key_cmp((byte*) key,
+ key_part->part_length)) > 0)
+ return 0;
+ if (cmp < 0)
+ return 1;
+ }
+ return (range_arg->flag & NEAR_MIN) ? 1 : 0; // Exact match
+}
+
+
+/*
+ * True if this range will require using HA_READ_AFTER_KEY
+ See comment in get_next() about this
+ */
+
+bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
+{
+ return ((range_arg->flag & (NO_MAX_RANGE | NEAR_MAX)) ||
+ !(range_arg->flag & EQ_RANGE) ||
+ head->key_info[index].key_length != range_arg->max_length) ? 1 : 0;
+}
+
+
+/* True if we are reading over a key that may have a NULL value */
+
+#ifdef NOT_USED
+bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
+ uint used_key_parts)
+{
+ uint offset,end;
+ KEY_PART *key_part = key_parts,
+ *key_part_end= key_part+used_key_parts;
+
+ for (offset= 0, end = min(range_arg->min_length, range_arg->max_length) ;
+ offset < end && key_part != key_part_end ;
+ offset += key_part++->part_length)
+ {
+ uint null_length=test(key_part->null_bit);
+ if (!memcmp((char*) range_arg->min_key+offset,
+ (char*) range_arg->max_key+offset,
+ key_part->part_length + null_length))
+ {
+ offset+=null_length;
+ continue;
+ }
+ if (null_length && range_arg->min_key[offset])
+ return 1; // min_key is null and max_key isn't
+ // Range doesn't cover NULL. This is ok if there is no more null parts
+ break;
+ }
+ /*
+ If the next min_range is > NULL, then we can use this, even if
+ it's a NULL key
+ Example: SELECT * FROM t1 WHERE a = 2 AND b >0 ORDER BY a DESC,b DESC;
+
+ */
+ if (key_part != key_part_end && key_part->null_bit)
+ {
+ if (offset >= range_arg->min_length || range_arg->min_key[offset])
+ return 1; // Could be null
+ key_part++;
+ }
+ /*
+ If any of the key parts used in the ORDER BY could be NULL, we can't
+ use the key to sort the data.
+ */
+ for (; key_part != key_part_end ; key_part++)
+ if (key_part->null_bit)
+ return 1; // Covers null part
+ return 0;
+}
+#endif
+
+
/*****************************************************************************
** Print a quick range for debugging
** TODO:
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 247dd260817..cda8ad51c3f 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -38,25 +38,34 @@ typedef struct st_key_part {
Field *field;
} KEY_PART;
+
class QUICK_RANGE :public Sql_alloc {
public:
char *min_key,*max_key;
uint16 min_length,max_length,flag;
+#ifdef HAVE_purify
+ uint16 dummy; /* Avoid warnings on 'flag' */
+#endif
QUICK_RANGE(); /* Full range */
QUICK_RANGE(const char *min_key_arg,uint min_length_arg,
const char *max_key_arg,uint max_length_arg,
uint flag_arg)
: min_key((char*) sql_memdup(min_key_arg,min_length_arg+1)),
max_key((char*) sql_memdup(max_key_arg,max_length_arg+1)),
- min_length(min_length_arg),
- max_length(max_length_arg),
- flag(flag_arg)
- {}
+ min_length((uint16) min_length_arg),
+ max_length((uint16) max_length_arg),
+ flag((uint16) flag_arg)
+ {
+#ifdef HAVE_purify
+ dummy=0;
+#endif
+ }
};
+
class QUICK_SELECT {
public:
- bool next;
+ bool next,dont_free;
int error;
uint index,max_used_key_length;
TABLE *head;
@@ -71,15 +80,35 @@ public:
ha_rows records;
double read_time;
- QUICK_SELECT(TABLE *table,uint index_arg,bool no_alloc=0);
+ QUICK_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0);
virtual ~QUICK_SELECT();
void reset(void) { next=0; it.rewind(); }
- virtual int init();
+ int init() { return error=file->index_init(index); }
virtual int get_next();
+ virtual bool reverse_sorted() { return 0; }
int cmp_next(QUICK_RANGE *range);
bool unique_key_range();
};
+
+class QUICK_SELECT_DESC: public QUICK_SELECT
+{
+public:
+ QUICK_SELECT_DESC(QUICK_SELECT *q, uint used_key_parts);
+ int get_next();
+ bool reverse_sorted() { return 1; }
+private:
+ int cmp_prev(QUICK_RANGE *range);
+ bool range_reads_after_key(QUICK_RANGE *range);
+#ifdef NOT_USED
+ bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);
+#endif
+ void reset(void) { next=0; rev_it.rewind(); }
+ List<QUICK_RANGE> rev_ranges;
+ List_iterator<QUICK_RANGE> rev_it;
+};
+
+
class SQL_SELECT :public Sql_alloc {
public:
QUICK_SELECT *quick; // If quick-select used
@@ -95,13 +124,15 @@ class SQL_SELECT :public Sql_alloc {
SQL_SELECT();
~SQL_SELECT();
- bool check_quick(bool force_quick_range=0, ha_rows limit = HA_POS_ERROR)
- { return test_quick_select(~0L,0,limit, force_quick_range) < 0; }
+ bool check_quick(THD *thd, bool force_quick_range= 0,
+ ha_rows limit= HA_POS_ERROR)
+ { return test_quick_select(thd, ~0L,0,limit, force_quick_range) < 0; }
inline bool skipp_record() { return cond ? cond->val_int() == 0 : 0; }
- int test_quick_select(key_map keys,table_map prev_tables,ha_rows limit,
- bool force_quick_range=0);
+ int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
+ ha_rows limit, bool force_quick_range=0);
};
-QUICK_SELECT *get_quick_select_for_ref(TABLE *table, struct st_table_ref *ref);
+QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
+ struct st_table_ref *ref);
#endif
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 9385e993859..b5eec2d5dd4 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000-2003 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -22,28 +22,59 @@
static bool find_range_key(TABLE_REF *ref, Field* field,COND *cond);
-/*****************************************************************************
-** This function is only called for queries with sum functions and no
-** GROUP BY part.
-** This substitutes constants for some COUNT(), MIN() and MAX() functions.
-** The function returns 1 if all items was resolved and -1 on impossible
-** conditions
-****************************************************************************/
+/*
+ Substitutes constants for some COUNT(), MIN() and MAX() functions.
+
+ SYNOPSIS
+ opt_sum_query()
+ tables Tables in query
+ all_fields All fields to be returned
+ conds WHERE clause
+
+ NOTE:
+ This function is only called for queries with sum functions and no
+ GROUP BY part.
+
+ RETURN VALUES
+ 0 No errors
+ 1 if all items were resolved
+ -1 on impossible conditions
+ OR an error number from my_base.h HA_ERR_... if a deadlock or a lock
+ wait timeout happens, for example
+*/
int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
{
- List_iterator<Item> it(all_fields);
- int const_result=1;
- bool recalc_const_item=0;
- table_map removed_tables=0;
+ List_iterator_fast<Item> it(all_fields);
+ int const_result= 1;
+ bool recalc_const_item= 0;
+ table_map removed_tables= 0, outer_tables= 0, used_tables= 0;
+ table_map where_tables= 0;
Item *item;
COND *org_conds= conds;
-
- /* Add all ON conditions to WHERE condition */
+ int error;
+
+ if (conds)
+ where_tables= conds->used_tables();
+
+ /* Don't replace expression on a table that is part of an outer join */
for (TABLE_LIST *tl=tables; tl ; tl= tl->next)
{
if (tl->on_expr)
- conds= and_expressions(conds, tl->on_expr, &org_conds);
+ {
+ outer_tables|= tl->table->map;
+
+ /*
+ We can't optimise LEFT JOIN in cases where the WHERE condition
+ restricts the table that is used, like in:
+ SELECT MAX(t1.a) FROM t1 LEFT JOIN t2 join-condition
+ WHERE t2.field IS NULL;
+ */
+ if (tl->table->map & where_tables)
+ return 0;
+ }
+ else
+ used_tables|= tl->table->map;
}
/*
@@ -68,8 +99,8 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
TABLE_LIST *table;
for (table=tables; table ; table=table->next)
{
- if (table->on_expr || (table->table->file->option_flag() &
- HA_NOT_EXACT_COUNT))
+ if (outer_tables || (table->table->file->table_flags() &
+ HA_NOT_EXACT_COUNT))
{
const_result=0; // Can't optimize left join
break;
@@ -99,21 +130,40 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
byte key_buff[MAX_KEY_LENGTH];
TABLE_REF ref;
ref.key_buff=key_buff;
+ Item_field *item_field= ((Item_field*) expr);
+ TABLE *table= item_field->field->table;
- if (!find_range_key(&ref, ((Item_field*) expr)->field,conds))
+ if ((outer_tables & table->map) ||
+ (!find_range_key(&ref, item_field->field,conds)))
{
const_result=0;
break;
}
- TABLE *table=((Item_field*) expr)->field->table;
- bool error=table->file->index_init((uint) ref.key);
+ error= table->file->index_init((uint) ref.key);
+ enum ha_rkey_function find_flag= HA_READ_KEY_OR_NEXT;
+ uint prefix_len= ref.key_length;
+ /*
+ If we are doing MIN() on a column with NULL fields
+ we must read the key after the NULL column
+ */
+ if (item_field->field->null_bit)
+ {
+ ref.key_buff[ref.key_length++]=1;
+ find_flag= HA_READ_AFTER_KEY;
+ }
+
if (!ref.key_length)
- error=table->file->index_first(table->record[0]) !=0;
+ {
+ error=table->file->index_first(table->record[0]);
+ }
else
+ {
error=table->file->index_read(table->record[0],key_buff,
ref.key_length,
- HA_READ_KEY_OR_NEXT) ||
- key_cmp(table, key_buff, ref.key, ref.key_length);
+ find_flag);
+ if (!error && key_cmp(table, key_buff, ref.key, prefix_len))
+ error = HA_ERR_KEY_NOT_FOUND;
+ }
if (table->key_read)
{
table->key_read=0;
@@ -121,7 +171,14 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
}
table->file->index_end();
if (error)
- return -1; // Impossible query
+ {
+ if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
+ return -1; // No rows matching WHERE
+
+ table->file->print_error(error, MYF(0));
+ return(error); // HA_ERR_LOCK_DEADLOCK or
+ // some other error
+ }
removed_tables|= table->map;
}
else if (!expr->const_item()) // This is VERY seldom false
@@ -147,28 +204,32 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
byte key_buff[MAX_KEY_LENGTH];
TABLE_REF ref;
ref.key_buff=key_buff;
+ TABLE *table=((Item_field*) expr)->field->table;
- if (!find_range_key(&ref, ((Item_field*) expr)->field,conds))
+ if ((table->file->table_flags() & HA_NOT_READ_AFTER_KEY))
{
const_result=0;
break;
}
- TABLE *table=((Item_field*) expr)->field->table;
- if ((table->file->option_flag() & HA_NOT_READ_AFTER_KEY))
+ if ((outer_tables & table->map) ||
+ !find_range_key(&ref, ((Item_field*) expr)->field,conds))
{
const_result=0;
break;
}
- bool error=table->file->index_init((uint) ref.key);
+ error=table->file->index_init((uint) ref.key);
if (!ref.key_length)
- error=table->file->index_last(table->record[0]) !=0;
+ {
+ error=table->file->index_last(table->record[0]);
+ }
else
{
- error = table->file->index_read(table->record[0], key_buff,
- ref.key_length,
- HA_READ_PREFIX_LAST) ||
- key_cmp(table,key_buff,ref.key,ref.key_length);
+ error=table->file->index_read(table->record[0], key_buff,
+ ref.key_length,
+ HA_READ_PREFIX_LAST);
+ if (!error && key_cmp(table,key_buff,ref.key,ref.key_length))
+ error = HA_ERR_KEY_NOT_FOUND;
}
if (table->key_read)
{
@@ -177,7 +238,13 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
}
table->file->index_end();
if (error)
- return -1; // Impossible query
+ {
+ if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
+ return -1; // Impossible query
+
+ table->file->print_error(error, MYF(0));
+ return error; // Deadlock or some other error
+ }
removed_tables|= table->map;
}
else if (!expr->const_item()) // This is VERY seldom false
@@ -203,8 +270,15 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
const_result=0;
}
}
- if (conds && (conds->used_tables() & ~ removed_tables))
- const_result=0;
+ /*
+ If we have a where clause, we can only ignore searching in the
+ tables if MIN/MAX optimisation replaced all used tables
+ This is to not to use replaced values in case of:
+ SELECT MIN(key) FROM table_1, empty_table
+ removed_tables is != 0 if we have used MIN() or MAX().
+ */
+ if (removed_tables && used_tables != removed_tables)
+ const_result= 0; // We didn't remove all tables
return const_result;
}
@@ -217,7 +291,7 @@ uint count_table_entries(COND *cond,TABLE *table)
if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
return (cond->used_tables() & table->map) ? MAX_REF_PARTS+1 : 0;
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
uint count=0;
while ((item=li++))
@@ -262,7 +336,7 @@ bool part_of_cond(COND *cond,Field *field)
if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
return 0; // Already checked
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
while ((item=li++))
{
@@ -298,26 +372,39 @@ bool part_of_cond(COND *cond,Field *field)
}
-/* Check if we can get value for field by using a key */
+/*
+ Check if we can get value for field by using a key
+
+ NOTES
+ This function may set table->key_read to 1, which must be reset after
+ index is used! (This can only happen when function returns 1)
+*/
static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond)
{
if (!(field->flags & PART_KEY_FLAG))
- return 0; // Not part of a key. Skipp it
+ return 0; // Not part of a key. Skip it
TABLE *table=field->table;
- if (table->file->option_flag() & HA_WRONG_ASCII_ORDER)
- return(0); // Can't use key to find last row
uint idx=0;
/* Check if some key has field as first key part */
- if (field->key_start && (! cond || ! (cond->used_tables() & table->map)))
+ if ((field->key_start & field->table->keys_in_use_for_query) &&
+ (! cond || ! (cond->used_tables() & table->map)))
{
- for (key_map key=field->key_start ; !(key & 1) ; idx++)
- key>>=1;
+ for (key_map key=field->key_start ;;)
+ {
+ for (; !(key & 1) ; idx++)
+ key>>=1;
+ if (!(table->file->index_flags(idx) & HA_WRONG_ASCII_ORDER))
+ break; // Key is ok
+ /* Can't use this key, for looking up min() or max(), end if last one */
+ if (key == 1)
+ return 0;
+ }
ref->key_length=0;
ref->key=idx;
- if (field->part_of_key & ((table_map) 1 << idx))
+ if (field->part_of_key & ((key_map) 1 << idx))
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
@@ -334,6 +421,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond)
return 0;
KEY *keyinfo,*keyinfo_end;
+ idx=0;
for (keyinfo=table->key_info, keyinfo_end=keyinfo+table->keys ;
keyinfo != keyinfo_end;
keyinfo++,idx++)
@@ -349,20 +437,25 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond)
part++)
{
if (!part_of_cond(cond,part->field) ||
- left_length < part->store_length)
+ left_length < part->store_length ||
+ (table->file->index_flags(idx) & HA_WRONG_ASCII_ORDER))
break;
+ uint store_length= part->store_length;
// Save found constant
if (part->null_bit)
+ {
*key_ptr++= (byte) test(part->field->is_null());
- part->field->get_key_image((char*) key_ptr,part->length);
- key_ptr+=part->store_length - test(part->null_bit);
- left_length-=part->store_length;
+ store_length--;
+ }
+ part->field->get_key_image((char*) key_ptr, store_length);
+ key_ptr+= store_length;
+ left_length-= part->store_length;
}
if (part == part_end && part->field == field)
{
ref->key_length= (uint) (key_ptr-ref->key_buff);
ref->key=idx;
- if (field->part_of_key & ((table_map) 1 << idx))
+ if (field->part_of_key & ((key_map) 1 << idx))
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
diff --git a/sql/password.c b/sql/password.c
index 1c88aabcce2..575e837ceb8 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -34,7 +34,7 @@
This saves a hashed number as a string in the password field.
*****************************************************************************/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include "mysql.h"
@@ -43,7 +43,7 @@
void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2)
{ /* For mysql 3.21.# */
#ifdef HAVE_purify
- bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
+ bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
#endif
rand_st->max_value= 0x3FFFFFFFL;
rand_st->max_value_dbl=(double) rand_st->max_value;
@@ -59,7 +59,7 @@ static void old_randominit(struct rand_struct *rand_st,ulong seed1)
rand_st->seed1=seed1 ; rand_st->seed2=seed1/2;
}
-double rnd(struct rand_struct *rand_st)
+double my_rnd(struct rand_struct *rand_st)
{
rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
@@ -91,7 +91,7 @@ void make_scrambled_password(char *to,const char *password)
sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]);
}
-inline uint char_val(char X)
+static inline unsigned int char_val(char X)
{
return (uint) (X >= '0' && X <= '9' ? X-'0' :
X >= 'A' && X <= 'Z' ? X-'A'+10 :
@@ -147,10 +147,10 @@ char *scramble(char *to,const char *message,const char *password,
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
hash_pass[1] ^ hash_message[1]);
while (*message++)
- *to++= (char) (floor(rnd(&rand_st)*31)+64);
+ *to++= (char) (floor(my_rnd(&rand_st)*31)+64);
if (!old_ver)
{ /* Make it harder to break */
- char extra=(char) (floor(rnd(&rand_st)*31));
+ char extra=(char) (floor(my_rnd(&rand_st)*31));
while (to_start != to)
*(to_start++)^=extra;
}
@@ -176,11 +176,11 @@ my_bool check_scramble(const char *scrambled, const char *message,
hash_pass[1] ^ hash_message[1]);
to=buff;
for (pos=scrambled ; *pos ; pos++)
- *to++=(char) (floor(rnd(&rand_st)*31)+64);
+ *to++=(char) (floor(my_rnd(&rand_st)*31)+64);
if (old_ver)
extra=0;
else
- extra=(char) (floor(rnd(&rand_st)*31));
+ extra=(char) (floor(my_rnd(&rand_st)*31));
to=buff;
while (*scrambled)
{
diff --git a/sql/procedure.cc b/sql/procedure.cc
index 526bbe0feab..437bd82d6e5 100644
--- a/sql/procedure.cc
+++ b/sql/procedure.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/procedure.h b/sql/procedure.h
index 1583f1169ce..349908a8d84 100644
--- a/sql/procedure.h
+++ b/sql/procedure.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -43,6 +43,7 @@ public:
{
init_make_field(tmp_field,field_type());
}
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_proc_real :public Item_proc
@@ -62,6 +63,7 @@ public:
double val() { return value; }
longlong val_int() { return (longlong) value; }
String *val_str(String *s) { s->set(value,decimals); return s; }
+ unsigned int size_of() { return sizeof(*this);}
};
class Item_proc_int :public Item_proc
@@ -79,6 +81,7 @@ public:
double val() { return (double) value; }
longlong val_int() { return value; }
String *val_str(String *s) { s->set(value); return s; }
+ unsigned int size_of() { return sizeof(*this);}
};
@@ -98,6 +101,7 @@ public:
{
return null_value ? (String*) 0 : (String*) &str_value;
}
+ unsigned int size_of() { return sizeof(*this);}
};
/* The procedure class definitions */
diff --git a/sql/records.cc b/sql/records.cc
index d436f4f58fe..415e75a467b 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -1,21 +1,21 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Functions to read, write and lock records */
+/* Functions for easy reading of records, possible through a cache */
#include "mysql_priv.h"
@@ -45,18 +45,14 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
info->ref_length=table->file->ref_length;
info->select=select;
info->print_error=print_error;
- table->status=0; /* And it's allways found */
+ info->ignore_not_found_rows= 0;
+ table->status=0; /* And it's always found */
if (select && my_b_inited(&select->file))
tempfile= &select->file;
else
tempfile= table->io_cache;
- if (select && select->quick && (! tempfile || !tempfile->buffer))
- {
- DBUG_PRINT("info",("using rr_quick"));
- info->read_record=rr_quick;
- }
- else if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
+ if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
{
DBUG_PRINT("info",("using rr_from_tempfile"));
info->read_record=rr_from_tempfile;
@@ -66,7 +62,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
table->file->rnd_init(0);
if (! (specialflag & SPECIAL_SAFE_MODE) &&
- record_rnd_cache_size &&
+ thd->variables.read_rnd_buff_size &&
!table->file->fast_key_read() &&
(table->db_stat & HA_READ_ONLY ||
table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
@@ -84,8 +80,14 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
}
}
}
+ else if (select && select->quick)
+ {
+ DBUG_PRINT("info",("using rr_quick"));
+ info->read_record=rr_quick;
+ }
else if (table->record_pointers)
{
+ DBUG_PRINT("info",("using record_pointers"));
table->file->rnd_init(0);
info->cache_pos=table->record_pointers;
info->cache_end=info->cache_pos+ table->found_records*info->ref_length;
@@ -97,12 +99,14 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
info->read_record=rr_sequential;
table->file->rnd_init();
/* We can use record cache if we don't update dynamic length tables */
- if (use_record_cache > 0 ||
- (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY ||
- !(table->db_options_in_use & HA_OPTION_PACK_RECORD) ||
- (use_record_cache < 0 &&
- !(table->file->option_flag() & HA_NOT_DELETE_WITH_CACHE)))
- VOID(table->file->extra(HA_EXTRA_CACHE)); // Cache reads
+ if (!table->no_cache &&
+ (use_record_cache > 0 ||
+ (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY ||
+ !(table->db_options_in_use & HA_OPTION_PACK_RECORD) ||
+ (use_record_cache < 0 &&
+ !(table->file->table_flags() & HA_NOT_DELETE_WITH_CACHE))))
+ VOID(table->file->extra_opt(HA_EXTRA_CACHE,
+ thd->variables.read_buff_size));
}
DBUG_VOID_RETURN;
} /* init_read_record */
@@ -182,7 +186,8 @@ tryNext:
{
if (tmp == HA_ERR_END_OF_FILE)
tmp= -1;
- else if (tmp == HA_ERR_RECORD_DELETED)
+ else if (tmp == HA_ERR_RECORD_DELETED ||
+ (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
goto tryNext;
else
{
@@ -210,7 +215,8 @@ tryNext:
{
if (tmp == HA_ERR_END_OF_FILE)
tmp= -1;
- else if (tmp == HA_ERR_RECORD_DELETED)
+ else if (tmp == HA_ERR_RECORD_DELETED ||
+ (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
goto tryNext;
else
{
@@ -228,6 +234,8 @@ tryNext:
static int init_rr_cache(READ_RECORD *info)
{
uint rec_cache_size;
+ THD *thd= current_thd;
+
DBUG_ENTER("init_rr_cache");
info->struct_length=3+MAX_REFLENGTH;
@@ -236,7 +244,7 @@ static int init_rr_cache(READ_RECORD *info)
info->reclength=ALIGN_SIZE(info->struct_length);
info->error_offset=info->table->reclength;
- info->cache_records=record_rnd_cache_size/
+ info->cache_records= thd->variables.read_rnd_buff_size /
(info->reclength+info->struct_length);
rec_cache_size=info->cache_records*info->reclength;
info->rec_cache_size=info->cache_records*info->ref_length;
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
new file mode 100644
index 00000000000..6599516044a
--- /dev/null
+++ b/sql/repl_failsafe.cc
@@ -0,0 +1,945 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB & Sasha
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+// Sasha Pachev <sasha@mysql.com> is currently in charge of this file
+
+#include "mysql_priv.h"
+#include "repl_failsafe.h"
+#include "sql_repl.h"
+#include "slave.h"
+#include "sql_acl.h"
+#include "mini_client.h"
+#include "log_event.h"
+#include <mysql.h>
+
+#define SLAVE_LIST_CHUNK 128
+#define SLAVE_ERRMSG_SIZE (FN_REFLEN+64)
+
+
+RPL_STATUS rpl_status=RPL_NULL;
+pthread_mutex_t LOCK_rpl_status;
+pthread_cond_t COND_rpl_status;
+HASH slave_list;
+extern const char* any_db;
+
+const char *rpl_role_type[] = {"MASTER","SLAVE",NullS};
+TYPELIB rpl_role_typelib = {array_elements(rpl_role_type)-1,"",
+ rpl_role_type};
+
+const char* rpl_status_type[]=
+{
+ "AUTH_MASTER","ACTIVE_SLAVE","IDLE_SLAVE", "LOST_SOLDIER","TROOP_SOLDIER",
+ "RECOVERY_CAPTAIN","NULL",NullS
+};
+TYPELIB rpl_status_typelib= {array_elements(rpl_status_type)-1,"",
+ rpl_status_type};
+
+
+static Slave_log_event* find_slave_event(IO_CACHE* log,
+ const char* log_file_name,
+ char* errmsg);
+
+/*
+ All of the functions defined in this file which are not used (the ones to
+ handle failsafe) are not used; their code has not been updated for more than
+ one year now so should be considered as BADLY BROKEN. Do not enable it.
+ The used functions (to handle LOAD DATA FROM MASTER, plus some small
+ functions like register_slave()) are working.
+*/
+
+static int init_failsafe_rpl_thread(THD* thd)
+{
+ DBUG_ENTER("init_failsafe_rpl_thread");
+ thd->system_thread = thd->bootstrap = 1;
+ thd->host_or_ip= "";
+ thd->client_capabilities = 0;
+ my_net_init(&thd->net, 0);
+ thd->net.read_timeout = slave_net_timeout;
+ thd->max_client_packet_length=thd->net.max_packet;
+ thd->master_access= ~0;
+ thd->priv_user = 0;
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->thread_id = thread_id++;
+ pthread_mutex_unlock(&LOCK_thread_count);
+
+ if (init_thr_lock() || thd->store_globals())
+ {
+ close_connection(&thd->net,ER_OUT_OF_RESOURCES); // is this needed?
+ statistic_increment(aborted_connects,&LOCK_status);
+ end_thread(thd,0);
+ DBUG_RETURN(-1);
+ }
+
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
+ sigset_t set;
+ VOID(sigemptyset(&set)); // Get mask in use
+ VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
+#endif
+
+ thd->mem_root.free=thd->mem_root.used=0;
+ if (thd->variables.max_join_size == HA_POS_ERROR)
+ thd->options|= OPTION_BIG_SELECTS;
+
+ thd->proc_info="Thread initialized";
+ thd->version=refresh_version;
+ thd->set_time();
+ DBUG_RETURN(0);
+}
+
+
+void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status)
+{
+ pthread_mutex_lock(&LOCK_rpl_status);
+ if (rpl_status == from_status || rpl_status == RPL_ANY)
+ rpl_status = to_status;
+ pthread_cond_signal(&COND_rpl_status);
+ pthread_mutex_unlock(&LOCK_rpl_status);
+}
+
+
+#define get_object(p, obj) \
+{\
+ uint len = (uint)*p++; \
+ if (p + len > p_end || len >= sizeof(obj)) \
+ goto err; \
+ strmake(obj,(char*) p,len); \
+ p+= len; \
+}\
+
+
+static inline int cmp_master_pos(Slave_log_event* sev, LEX_MASTER_INFO* mi)
+{
+ return cmp_master_pos(sev->master_log, sev->master_pos, mi->log_file_name,
+ mi->pos);
+}
+
+
+void unregister_slave(THD* thd, bool only_mine, bool need_mutex)
+{
+ if (thd->server_id)
+ {
+ if (need_mutex)
+ pthread_mutex_lock(&LOCK_slave_list);
+
+ SLAVE_INFO* old_si;
+ if ((old_si = (SLAVE_INFO*)hash_search(&slave_list,
+ (byte*)&thd->server_id, 4)) &&
+ (!only_mine || old_si->thd == thd))
+ hash_delete(&slave_list, (byte*)old_si);
+
+ if (need_mutex)
+ pthread_mutex_unlock(&LOCK_slave_list);
+ }
+}
+
+
+/*
+ Register slave in 'slave_list' hash table
+
+ RETURN VALUES
+ 0 ok
+ 1 Error. Error message sent to client
+*/
+
+int register_slave(THD* thd, uchar* packet, uint packet_length)
+{
+ int res;
+ SLAVE_INFO *si;
+ uchar *p= packet, *p_end= packet + packet_length;
+
+ if (check_access(thd, REPL_SLAVE_ACL, any_db))
+ return 1;
+
+ if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME))))
+ goto err2;
+
+ thd->server_id= si->server_id= uint4korr(p);
+ p+= 4;
+ get_object(p,si->host);
+ get_object(p,si->user);
+ get_object(p,si->password);
+ if (p+10 > p_end)
+ goto err;
+ si->port= uint2korr(p);
+ p += 2;
+ si->rpl_recovery_rank= uint4korr(p);
+ p += 4;
+ if (!(si->master_id= uint4korr(p)))
+ si->master_id= server_id;
+ si->thd= thd;
+
+ pthread_mutex_lock(&LOCK_slave_list);
+ unregister_slave(thd,0,0);
+ res= hash_insert(&slave_list, (byte*) si);
+ pthread_mutex_unlock(&LOCK_slave_list);
+ return res;
+
+err:
+ my_free((gptr) si, MYF(MY_WME));
+ my_message(ER_UNKNOWN_ERROR, "Wrong parameters to function register_slave",
+ MYF(0));
+err2:
+ send_error(&thd->net);
+ return 1;
+}
+
+extern "C" uint32
+*slave_list_key(SLAVE_INFO* si, uint* len,
+ my_bool not_used __attribute__((unused)))
+{
+ *len = 4;
+ return &si->server_id;
+}
+
+extern "C" void slave_info_free(void *s)
+{
+ my_free((gptr) s, MYF(MY_WME));
+}
+
+void init_slave_list()
+{
+ hash_init(&slave_list, SLAVE_LIST_CHUNK, 0, 0,
+ (hash_get_key) slave_list_key, (hash_free_key) slave_info_free, 0);
+ pthread_mutex_init(&LOCK_slave_list, MY_MUTEX_INIT_FAST);
+}
+
+void end_slave_list()
+{
+ /* No protection by a mutex needed as we are only called at shutdown */
+ if (hash_inited(&slave_list))
+ {
+ hash_free(&slave_list);
+ pthread_mutex_destroy(&LOCK_slave_list);
+ }
+}
+
+static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg)
+{
+ my_off_t log_pos = (my_off_t) mi->pos;
+ uint32 target_server_id = mi->server_id;
+
+ for (;;)
+ {
+ Log_event* ev;
+ if (!(ev = Log_event::read_log_event(log, (pthread_mutex_t*) 0, 0)))
+ {
+ if (log->error > 0)
+ strmov(errmsg, "Binary log truncated in the middle of event");
+ else if (log->error < 0)
+ strmov(errmsg, "I/O error reading binary log");
+ else
+ strmov(errmsg, "Could not find target event in the binary log");
+ return 1;
+ }
+
+ if (ev->log_pos >= log_pos && ev->server_id == target_server_id)
+ {
+ delete ev;
+ mi->pos = my_b_tell(log);
+ return 0;
+ }
+ delete ev;
+ }
+ /* Impossible */
+}
+
+/*
+ Before 4.0.15 we had a member of THD called log_pos, it was meant for
+ failsafe replication code in repl_failsafe.cc which is disabled until
+ it is reworked. Event's log_pos used to be preserved through
+ log-slave-updates to make code in repl_failsafe.cc work (this
+ function, SHOW NEW MASTER); but on the other side it caused unexpected
+ values in Exec_master_log_pos in A->B->C replication setup,
+ synchronization problems in master_pos_wait(), ... So we
+ (Dmitri & Guilhem) removed it.
+
+ So for now this function is broken.
+*/
+
+int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg)
+{
+ LOG_INFO linfo;
+ char last_log_name[FN_REFLEN];
+ IO_CACHE log;
+ File file = -1, last_file = -1;
+ pthread_mutex_t *log_lock;
+ const char* errmsg_p;
+ Slave_log_event* sev = 0;
+ my_off_t last_pos = 0;
+ int error = 1;
+ int cmp_res;
+ LINT_INIT(cmp_res);
+ DBUG_ENTER("translate_master");
+
+ if (!mysql_bin_log.is_open())
+ {
+ strmov(errmsg,"Binary log is not open");
+ DBUG_RETURN(1);
+ }
+
+ if (!server_id_supplied)
+ {
+ strmov(errmsg, "Misconfigured master - server id was not set");
+ DBUG_RETURN(1);
+ }
+
+ if (mysql_bin_log.find_log_pos(&linfo, NullS, 1))
+ {
+ strmov(errmsg,"Could not find first log");
+ DBUG_RETURN(1);
+ }
+ thd->current_linfo = &linfo;
+
+ bzero((char*) &log,sizeof(log));
+ log_lock = mysql_bin_log.get_log_lock();
+ pthread_mutex_lock(log_lock);
+
+ for (;;)
+ {
+ if ((file=open_binlog(&log, linfo.log_file_name, &errmsg_p)) < 0)
+ {
+ strmov(errmsg, errmsg_p);
+ goto err;
+ }
+
+ if (!(sev = find_slave_event(&log, linfo.log_file_name, errmsg)))
+ goto err;
+
+ cmp_res = cmp_master_pos(sev, mi);
+ delete sev;
+
+ if (!cmp_res)
+ {
+ /* Copy basename */
+ fn_format(mi->log_file_name, linfo.log_file_name, "","",1);
+ mi->pos = my_b_tell(&log);
+ goto mi_inited;
+ }
+ else if (cmp_res > 0)
+ {
+ if (!last_pos)
+ {
+ strmov(errmsg,
+ "Slave event in first log points past the target position");
+ goto err;
+ }
+ end_io_cache(&log);
+ (void) my_close(file, MYF(MY_WME));
+ if (init_io_cache(&log, (file = last_file), IO_SIZE, READ_CACHE, 0, 0,
+ MYF(MY_WME)))
+ {
+ errmsg[0] = 0;
+ goto err;
+ }
+ break;
+ }
+
+ strmov(last_log_name, linfo.log_file_name);
+ last_pos = my_b_tell(&log);
+
+ switch (mysql_bin_log.find_next_log(&linfo, 1)) {
+ case LOG_INFO_EOF:
+ if (last_file >= 0)
+ (void)my_close(last_file, MYF(MY_WME));
+ last_file = -1;
+ goto found_log;
+ case 0:
+ break;
+ default:
+ strmov(errmsg, "Error reading log index");
+ goto err;
+ }
+
+ end_io_cache(&log);
+ if (last_file >= 0)
+ (void) my_close(last_file, MYF(MY_WME));
+ last_file = file;
+ }
+
+found_log:
+ my_b_seek(&log, last_pos);
+ if (find_target_pos(mi,&log,errmsg))
+ goto err;
+ fn_format(mi->log_file_name, last_log_name, "","",1); /* Copy basename */
+
+mi_inited:
+ error = 0;
+err:
+ pthread_mutex_unlock(log_lock);
+ end_io_cache(&log);
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->current_linfo = 0;
+ pthread_mutex_unlock(&LOCK_thread_count);
+ if (file >= 0)
+ (void) my_close(file, MYF(MY_WME));
+ if (last_file >= 0 && last_file != file)
+ (void) my_close(last_file, MYF(MY_WME));
+
+ DBUG_RETURN(error);
+}
+
+
+/*
+ Caller must delete result when done
+*/
+
+static Slave_log_event* find_slave_event(IO_CACHE* log,
+ const char* log_file_name,
+ char* errmsg)
+{
+ Log_event* ev;
+ int i;
+ bool slave_event_found = 0;
+ LINT_INIT(ev);
+
+ for (i = 0; i < 2; i++)
+ {
+ if (!(ev = Log_event::read_log_event(log, (pthread_mutex_t*)0, 0)))
+ {
+ my_snprintf(errmsg, SLAVE_ERRMSG_SIZE,
+ "Error reading event in log '%s'",
+ (char*)log_file_name);
+ return 0;
+ }
+ if (ev->get_type_code() == SLAVE_EVENT)
+ {
+ slave_event_found = 1;
+ break;
+ }
+ delete ev;
+ }
+ if (!slave_event_found)
+ {
+ my_snprintf(errmsg, SLAVE_ERRMSG_SIZE,
+ "Could not find slave event in log '%s'",
+ (char*)log_file_name);
+ return 0;
+ }
+
+ return (Slave_log_event*)ev;
+}
+
+/*
+ This function is broken now. See comment for translate_master().
+ */
+
+int show_new_master(THD* thd)
+{
+ DBUG_ENTER("show_new_master");
+ List<Item> field_list;
+ char errmsg[SLAVE_ERRMSG_SIZE];
+ LEX_MASTER_INFO* lex_mi = &thd->lex.mi;
+
+ errmsg[0]=0; // Safety
+ if (translate_master(thd, lex_mi, errmsg))
+ {
+ if (errmsg[0])
+ my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
+ "SHOW NEW MASTER", errmsg);
+ DBUG_RETURN(-1);
+ }
+ else
+ {
+ String* packet = &thd->packet;
+ field_list.push_back(new Item_empty_string("Log_name", 20));
+ field_list.push_back(new Item_empty_string("Log_pos", 20));
+ if (send_fields(thd, field_list, 1))
+ DBUG_RETURN(-1);
+ packet->length(0);
+ net_store_data(packet, lex_mi->log_file_name);
+ net_store_data(packet, (longlong)lex_mi->pos);
+ if (my_net_write(&thd->net, packet->ptr(), packet->length()))
+ DBUG_RETURN(-1);
+ send_eof(&thd->net);
+ DBUG_RETURN(0);
+ }
+}
+
+/*
+ Asks the master for the list of its other connected slaves.
+ This is for failsafe replication :
+ in order for failsafe replication to work, the servers involved in replication
+ must know of each other. We accomplish this by having each slave report to the
+ master how to reach it, and on connection, each slave receives information
+ about where the other slaves are.
+
+ SYNOPSIS
+ update_slave_list()
+ mysql pre-existing connection to the master
+ mi master info
+
+ NOTES
+ mi is used only to give detailed error messages which include the
+ hostname/port of the master, the username used by the slave to connect to
+ the master.
+ If the user used by the slave to connect to the master does not have the
+ REPLICATION SLAVE privilege, it will pop in this function because SHOW SLAVE
+ HOSTS will fail on the master.
+
+ RETURN VALUES
+ 1 error
+ 0 success
+ */
+
+int update_slave_list(MYSQL* mysql, MASTER_INFO* mi)
+{
+ MYSQL_RES* res=0;
+ MYSQL_ROW row;
+ const char* error=0;
+ bool have_auth_info;
+ int port_ind;
+ DBUG_ENTER("update_slave_list");
+
+ if (mc_mysql_query(mysql,"SHOW SLAVE HOSTS",0) ||
+ !(res = mc_mysql_store_result(mysql)))
+ {
+ error= mc_mysql_error(mysql);
+ goto err;
+ }
+
+ switch (mc_mysql_num_fields(res)) {
+ case 5:
+ have_auth_info = 0;
+ port_ind=2;
+ break;
+ case 7:
+ have_auth_info = 1;
+ port_ind=4;
+ break;
+ default:
+ error= "the master returned an invalid number of fields for SHOW SLAVE \
+HOSTS";
+ goto err;
+ }
+
+ pthread_mutex_lock(&LOCK_slave_list);
+
+ while ((row= mc_mysql_fetch_row(res)))
+ {
+ uint32 server_id;
+ SLAVE_INFO* si, *old_si;
+ server_id = atoi(row[0]);
+ if ((old_si= (SLAVE_INFO*)hash_search(&slave_list,
+ (byte*)&server_id,4)))
+ si = old_si;
+ else
+ {
+ if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME))))
+ {
+ error= "the slave is out of memory";
+ pthread_mutex_unlock(&LOCK_slave_list);
+ goto err;
+ }
+ si->server_id = server_id;
+ hash_insert(&slave_list, (byte*)si);
+ }
+ strmake(si->host, row[1], sizeof(si->host)-1);
+ si->port = atoi(row[port_ind]);
+ si->rpl_recovery_rank = atoi(row[port_ind+1]);
+ si->master_id = atoi(row[port_ind+2]);
+ if (have_auth_info)
+ {
+ strmake(si->user, row[2], sizeof(si->user)-1);
+ strmake(si->password, row[3], sizeof(si->password)-1);
+ }
+ }
+ pthread_mutex_unlock(&LOCK_slave_list);
+
+err:
+ if (res)
+ mc_mysql_free_result(res);
+ if (error)
+ {
+ sql_print_error("While trying to obtain the list of slaves from the master \
+'%s:%d', user '%s' got the following error: '%s'",
+ mi->host, mi->port, mi->user, error);
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+}
+
+
+int find_recovery_captain(THD* thd, MYSQL* mysql)
+{
+ return 0;
+}
+
+
+pthread_handler_decl(handle_failsafe_rpl,arg)
+{
+ DBUG_ENTER("handle_failsafe_rpl");
+ THD *thd = new THD;
+ thd->thread_stack = (char*)&thd;
+ MYSQL* recovery_captain = 0;
+ pthread_detach_this_thread();
+ if (init_failsafe_rpl_thread(thd) || !(recovery_captain=mc_mysql_init(0)))
+ {
+ sql_print_error("Could not initialize failsafe replication thread");
+ goto err;
+ }
+ pthread_mutex_lock(&LOCK_rpl_status);
+ while (!thd->killed && !abort_loop)
+ {
+ bool break_req_chain = 0;
+ const char* msg = thd->enter_cond(&COND_rpl_status,
+ &LOCK_rpl_status, "Waiting for request");
+ pthread_cond_wait(&COND_rpl_status, &LOCK_rpl_status);
+ thd->proc_info="Processing request";
+ while (!break_req_chain)
+ {
+ switch (rpl_status) {
+ case RPL_LOST_SOLDIER:
+ if (find_recovery_captain(thd, recovery_captain))
+ rpl_status=RPL_TROOP_SOLDIER;
+ else
+ rpl_status=RPL_RECOVERY_CAPTAIN;
+ break_req_chain=1; /* for now until other states are implemented */
+ break;
+ default:
+ break_req_chain=1;
+ break;
+ }
+ }
+ thd->exit_cond(msg);
+ }
+ pthread_mutex_unlock(&LOCK_rpl_status);
+err:
+ if (recovery_captain)
+ mc_mysql_close(recovery_captain);
+ delete thd;
+ my_thread_end();
+ pthread_exit(0);
+ DBUG_RETURN(0);
+}
+
+
+int show_slave_hosts(THD* thd)
+{
+ List<Item> field_list;
+ NET* net = &thd->net;
+ String* packet = &thd->packet;
+ DBUG_ENTER("show_slave_hosts");
+
+ field_list.push_back(new Item_empty_string("Server_id", 20));
+ field_list.push_back(new Item_empty_string("Host", 20));
+ if (opt_show_slave_auth_info)
+ {
+ field_list.push_back(new Item_empty_string("User",20));
+ field_list.push_back(new Item_empty_string("Password",20));
+ }
+ field_list.push_back(new Item_empty_string("Port",20));
+ field_list.push_back(new Item_empty_string("Rpl_recovery_rank", 20));
+ field_list.push_back(new Item_empty_string("Master_id", 20));
+
+ if (send_fields(thd, field_list, 1))
+ DBUG_RETURN(-1);
+
+ pthread_mutex_lock(&LOCK_slave_list);
+
+ for (uint i = 0; i < slave_list.records; ++i)
+ {
+ SLAVE_INFO* si = (SLAVE_INFO*) hash_element(&slave_list, i);
+ packet->length(0);
+ net_store_data(packet, si->server_id);
+ net_store_data(packet, si->host);
+ if (opt_show_slave_auth_info)
+ {
+ net_store_data(packet, si->user);
+ net_store_data(packet, si->password);
+ }
+ net_store_data(packet, (uint32) si->port);
+ net_store_data(packet, si->rpl_recovery_rank);
+ net_store_data(packet, si->master_id);
+ if (my_net_write(net, (char*)packet->ptr(), packet->length()))
+ {
+ pthread_mutex_unlock(&LOCK_slave_list);
+ DBUG_RETURN(-1);
+ }
+ }
+ pthread_mutex_unlock(&LOCK_slave_list);
+ send_eof(net);
+ DBUG_RETURN(0);
+}
+
+
+int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi)
+{
+ DBUG_ENTER("connect_to_master");
+
+ if (!mi->host || !*mi->host) /* empty host */
+ {
+ strmov(mysql->net.last_error, "Master is not configured");
+ DBUG_RETURN(1);
+ }
+ if (!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
+ mi->port, 0, 0,
+ slave_net_timeout))
+ DBUG_RETURN(1);
+ DBUG_RETURN(0);
+}
+
+
+static inline void cleanup_mysql_results(MYSQL_RES* db_res,
+ MYSQL_RES** cur, MYSQL_RES** start)
+{
+ for (; cur >= start; --cur)
+ {
+ if (*cur)
+ mc_mysql_free_result(*cur);
+ }
+ mc_mysql_free_result(db_res);
+}
+
+
+static int fetch_db_tables(THD *thd, MYSQL *mysql, const char *db,
+ MYSQL_RES *table_res, MASTER_INFO *mi)
+{
+ MYSQL_ROW row;
+ for (row = mc_mysql_fetch_row(table_res); row;
+ row = mc_mysql_fetch_row(table_res))
+ {
+ TABLE_LIST table;
+ const char* table_name= row[0];
+ int error;
+ if (table_rules_on)
+ {
+ table.next= 0;
+ table.db= (char*) db;
+ table.real_name= (char*) table_name;
+ table.updating= 1;
+ if (!tables_ok(thd, &table))
+ continue;
+ }
+ /* download master's table and overwrite slave's table */
+ if ((error= fetch_master_table(thd, db, table_name, mi, mysql, 1)))
+ return error;
+ }
+ return 0;
+}
+
+/*
+ Load all MyISAM tables from master to this slave.
+
+ REQUIREMENTS
+ - No active transaction (flush_relay_log_info would not work in this case)
+*/
+
+int load_master_data(THD* thd)
+{
+ MYSQL mysql;
+ MYSQL_RES* master_status_res = 0;
+ int error = 0;
+ const char* errmsg=0;
+ int restart_thread_mask;
+ mc_mysql_init(&mysql);
+
+ /*
+ We do not want anyone messing with the slave at all for the entire
+ duration of the data load.
+ */
+ LOCK_ACTIVE_MI;
+ lock_slave_threads(active_mi);
+ init_thread_mask(&restart_thread_mask,active_mi,0 /*not inverse*/);
+ if (restart_thread_mask &&
+ (error=terminate_slave_threads(active_mi,restart_thread_mask,
+ 1 /*skip lock*/)))
+ {
+ send_error(&thd->net,error);
+ unlock_slave_threads(active_mi);
+ UNLOCK_ACTIVE_MI;
+ return 1;
+ }
+
+ if (connect_to_master(thd, &mysql, active_mi))
+ {
+ net_printf(&thd->net, error= ER_CONNECT_TO_MASTER,
+ mc_mysql_error(&mysql));
+ goto err;
+ }
+
+ // now that we are connected, get all database and tables in each
+ {
+ MYSQL_RES *db_res, **table_res, **table_res_end, **cur_table_res;
+ uint num_dbs;
+
+ if (mc_mysql_query(&mysql, "show databases", 0) ||
+ !(db_res = mc_mysql_store_result(&mysql)))
+ {
+ net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
+ mc_mysql_error(&mysql));
+ goto err;
+ }
+
+ if (!(num_dbs = (uint) mc_mysql_num_rows(db_res)))
+ goto err;
+ /*
+ In theory, the master could have no databases at all
+ and run with skip-grant
+ */
+
+ if (!(table_res = (MYSQL_RES**)thd->alloc(num_dbs * sizeof(MYSQL_RES*))))
+ {
+ net_printf(&thd->net, error = ER_OUTOFMEMORY);
+ goto err;
+ }
+
+ /*
+ This is a temporary solution until we have online backup
+ capabilities - to be replaced once online backup is working
+ we wait to issue FLUSH TABLES WITH READ LOCK for as long as we
+ can to minimize the lock time.
+ */
+ if (mc_mysql_query(&mysql, "FLUSH TABLES WITH READ LOCK", 0) ||
+ mc_mysql_query(&mysql, "SHOW MASTER STATUS",0) ||
+ !(master_status_res = mc_mysql_store_result(&mysql)))
+ {
+ net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
+ mc_mysql_error(&mysql));
+ goto err;
+ }
+
+ /*
+ Go through every table in every database, and if the replication
+ rules allow replicating it, get it
+ */
+
+ table_res_end = table_res + num_dbs;
+
+ for (cur_table_res = table_res; cur_table_res < table_res_end;
+ cur_table_res++)
+ {
+ // since we know how many rows we have, this can never be NULL
+ MYSQL_ROW row = mc_mysql_fetch_row(db_res);
+ char* db = row[0];
+
+ /*
+ Do not replicate databases excluded by rules. We also test
+ replicate_wild_*_table rules (replicate_wild_ignore_table='db1.%' will
+ be considered as "ignore the 'db1' database as a whole, as it already
+ works for CREATE DATABASE and DROP DATABASE).
+ Also skip 'mysql' database - in most cases the user will
+ mess up and not exclude mysql database with the rules when
+ he actually means to - in this case, he is up for a surprise if
+ his priv tables get dropped and downloaded from master
+ TODO - add special option, not enabled
+ by default, to allow inclusion of mysql database into load
+ data from master
+ */
+
+ if (!db_ok(db, replicate_do_db, replicate_ignore_db) ||
+ !db_ok_with_wild_table(db) ||
+ !strcmp(db,"mysql"))
+ {
+ *cur_table_res = 0;
+ continue;
+ }
+
+ if (mysql_create_db(thd, db, HA_LEX_CREATE_IF_NOT_EXISTS, 1))
+ {
+ send_error(&thd->net, 0, 0);
+ cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
+ goto err;
+ }
+
+ if (mc_mysql_select_db(&mysql, db) ||
+ mc_mysql_query(&mysql, "show tables", 0) ||
+ !(*cur_table_res = mc_mysql_store_result(&mysql)))
+ {
+ net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
+ mc_mysql_error(&mysql));
+ cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
+ goto err;
+ }
+
+ if ((error = fetch_db_tables(thd,&mysql,db,*cur_table_res,active_mi)))
+ {
+ // we do not report the error - fetch_db_tables handles it
+ cleanup_mysql_results(db_res, cur_table_res, table_res);
+ goto err;
+ }
+ }
+
+ cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
+
+ // adjust position in the master
+ if (master_status_res)
+ {
+ MYSQL_ROW row = mc_mysql_fetch_row(master_status_res);
+
+ /*
+ We need this check because the master may not be running with
+ log-bin, but it will still allow us to do all the steps
+ of LOAD DATA FROM MASTER - no reason to forbid it, really,
+ although it does not make much sense for the user to do it
+ */
+ if (row && row[0] && row[1])
+ {
+ strmake(active_mi->master_log_name, row[0],
+ sizeof(active_mi->master_log_name));
+ active_mi->master_log_pos = strtoull(row[1], (char**) 0, 10);
+ // don't hit the magic number
+ if (active_mi->master_log_pos < BIN_LOG_HEADER_SIZE)
+ active_mi->master_log_pos = BIN_LOG_HEADER_SIZE;
+ active_mi->rli.pending = 0;
+ flush_master_info(active_mi);
+ }
+ mc_mysql_free_result(master_status_res);
+ }
+
+ if (mc_mysql_query(&mysql, "UNLOCK TABLES", 0))
+ {
+ net_printf(&thd->net, error = ER_QUERY_ON_MASTER,
+ mc_mysql_error(&mysql));
+ goto err;
+ }
+ }
+ thd->proc_info="purging old relay logs";
+ if (purge_relay_logs(&active_mi->rli,thd,
+ 0 /* not only reset, but also reinit */,
+ &errmsg))
+ {
+ send_error(&thd->net, 0, "Failed purging old relay logs");
+ unlock_slave_threads(active_mi);
+ UNLOCK_ACTIVE_MI;
+ return 1;
+ }
+ pthread_mutex_lock(&active_mi->rli.data_lock);
+ active_mi->rli.master_log_pos = active_mi->master_log_pos;
+ strmake(active_mi->rli.master_log_name,active_mi->master_log_name,
+ sizeof(active_mi->rli.master_log_name)-1);
+ flush_relay_log_info(&active_mi->rli);
+ pthread_cond_broadcast(&active_mi->rli.data_cond);
+ pthread_mutex_unlock(&active_mi->rli.data_lock);
+ thd->proc_info = "starting slave";
+ if (restart_thread_mask)
+ {
+ error=start_slave_threads(0 /* mutex not needed */,
+ 1 /* wait for start */,
+ active_mi,master_info_file,relay_log_info_file,
+ restart_thread_mask);
+ }
+
+err:
+ unlock_slave_threads(active_mi);
+ UNLOCK_ACTIVE_MI;
+ thd->proc_info = 0;
+
+ mc_mysql_close(&mysql); // safe to call since we always do mc_mysql_init()
+ if (!error)
+ send_ok(&thd->net);
+
+ return error;
+}
diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h
new file mode 100644
index 00000000000..ae8bb2bc4d5
--- /dev/null
+++ b/sql/repl_failsafe.h
@@ -0,0 +1,37 @@
+#ifndef REPL_FAILSAFE_H
+#define REPL_FAILSAFE_H
+
+#include "mysql.h"
+#include "my_sys.h"
+#include "slave.h"
+
+typedef enum {RPL_AUTH_MASTER=0,RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE,
+ RPL_LOST_SOLDIER,RPL_TROOP_SOLDIER,
+ RPL_RECOVERY_CAPTAIN,RPL_NULL /* inactive */,
+ RPL_ANY /* wild card used by change_rpl_status */ } RPL_STATUS;
+extern RPL_STATUS rpl_status;
+
+extern pthread_mutex_t LOCK_rpl_status;
+extern pthread_cond_t COND_rpl_status;
+extern TYPELIB rpl_role_typelib, rpl_status_typelib;
+extern const char* rpl_role_type[], *rpl_status_type[];
+
+pthread_handler_decl(handle_failsafe_rpl,arg);
+void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status);
+int find_recovery_captain(THD* thd, MYSQL* mysql);
+int update_slave_list(MYSQL* mysql, MASTER_INFO* mi);
+
+extern HASH slave_list;
+
+int load_master_data(THD* thd);
+int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi);
+
+int show_new_master(THD* thd);
+int show_slave_hosts(THD* thd);
+int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg);
+void init_slave_list();
+void end_slave_list();
+int register_slave(THD* thd, uchar* packet, uint packet_length);
+void unregister_slave(THD* thd, bool only_mine, bool need_mutex);
+
+#endif
diff --git a/sql/set_var.cc b/sql/set_var.cc
new file mode 100644
index 00000000000..475beb798e6
--- /dev/null
+++ b/sql/set_var.cc
@@ -0,0 +1,1607 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Handling of MySQL SQL variables
+
+ To add a new variable, one has to do the following:
+
+ - If the variable is thread specific, add it to 'system_variables' struct.
+ If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
+ - Use one of the 'sys_var... classes from set_var.h or write a specific
+ one for the variable type.
+ - Define it in the 'variable definition list' in this file.
+ - If the variable should be changeable, it should be added to the
+ 'list of all variables' list in this file.
+ - If the variable should be changed from the command line, add a definition
+ of it in the my_option structure list in mysqld.dcc
+ - If the variable should show up in 'show variables' add it to the
+ init_vars[] struct in this file
+
+ TODO:
+ - Add full support for the variable character_set (for 4.1)
+
+ - When updating myisam_delay_key_write, we should do a 'flush tables'
+ of all MyISAM tables to ensure that they are reopen with the
+ new attribute.
+*/
+
+#ifdef __GNUC__
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "slave.h"
+#include "sql_acl.h"
+#include <my_getopt.h>
+#include <thr_alarm.h>
+#include <myisam.h>
+#ifdef HAVE_BERKELEY_DB
+#include "ha_berkeley.h"
+#endif
+#ifdef HAVE_INNOBASE_DB
+#include "ha_innodb.h"
+#endif
+
+static HASH system_variable_hash;
+const char *bool_type_names[]= { "OFF", "ON", NullS };
+TYPELIB bool_typelib=
+{
+ array_elements(bool_type_names)-1, "", bool_type_names
+};
+
+const char *delay_key_write_type_names[]= { "OFF", "ON", "ALL", NullS };
+TYPELIB delay_key_write_typelib=
+{
+ array_elements(delay_key_write_type_names)-1, "", delay_key_write_type_names
+};
+
+static bool sys_check_charset(THD *thd, set_var *var);
+static bool sys_update_charset(THD *thd, set_var *var);
+static void sys_set_default_charset(THD *thd, enum_var_type type);
+static bool set_option_bit(THD *thd, set_var *var);
+static bool set_option_autocommit(THD *thd, set_var *var);
+static bool set_log_update(THD *thd, set_var *var);
+static void fix_low_priority_updates(THD *thd, enum_var_type type);
+static void fix_tx_isolation(THD *thd, enum_var_type type);
+static void fix_net_read_timeout(THD *thd, enum_var_type type);
+static void fix_net_write_timeout(THD *thd, enum_var_type type);
+static void fix_net_retry_count(THD *thd, enum_var_type type);
+static void fix_max_join_size(THD *thd, enum_var_type type);
+static void fix_query_cache_size(THD *thd, enum_var_type type);
+static void fix_key_buffer_size(THD *thd, enum_var_type type);
+static void fix_myisam_max_extra_sort_file_size(THD *thd, enum_var_type type);
+static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type);
+static void fix_max_binlog_size(THD *thd, enum_var_type type);
+static void fix_max_relay_log_size(THD *thd, enum_var_type type);
+static void fix_max_connections(THD *thd, enum_var_type type);
+static void fix_thd_mem_root(THD *thd, enum_var_type type);
+static void fix_trans_mem_root(THD *thd, enum_var_type type);
+
+/*
+ Variable definition list
+
+ These are variables that can be set from the command line, in
+ alphabetic order
+*/
+
+sys_var_long_ptr sys_binlog_cache_size("binlog_cache_size",
+ &binlog_cache_size);
+sys_var_thd_ulong sys_bulk_insert_buff_size("bulk_insert_buffer_size",
+ &SV::bulk_insert_buff_size);
+sys_var_str sys_charset("character_set",
+ sys_check_charset,
+ sys_update_charset,
+ sys_set_default_charset);
+sys_var_thd_conv_charset sys_convert_charset("convert_character_set");
+sys_var_bool_ptr sys_concurrent_insert("concurrent_insert",
+ &myisam_concurrent_insert);
+sys_var_long_ptr sys_connect_timeout("connect_timeout",
+ &connect_timeout);
+sys_var_enum sys_delay_key_write("delay_key_write",
+ &delay_key_write_options,
+ &delay_key_write_typelib,
+ fix_delay_key_write);
+sys_var_long_ptr sys_delayed_insert_limit("delayed_insert_limit",
+ &delayed_insert_limit);
+sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout",
+ &delayed_insert_timeout);
+sys_var_long_ptr sys_delayed_queue_size("delayed_queue_size",
+ &delayed_queue_size);
+sys_var_bool_ptr sys_flush("flush", &myisam_flush);
+sys_var_long_ptr sys_flush_time("flush_time", &flush_time);
+sys_var_thd_ulong sys_interactive_timeout("interactive_timeout",
+ &SV::net_interactive_timeout);
+sys_var_thd_ulong sys_join_buffer_size("join_buffer_size",
+ &SV::join_buff_size);
+sys_var_ulonglong_ptr sys_key_buffer_size("key_buffer_size",
+ &keybuff_size,
+ fix_key_buffer_size);
+sys_var_bool_ptr sys_local_infile("local_infile",
+ &opt_local_infile);
+sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings);
+sys_var_thd_ulong sys_long_query_time("long_query_time",
+ &SV::long_query_time);
+sys_var_thd_bool sys_low_priority_updates("low_priority_updates",
+ &SV::low_priority_updates,
+ fix_low_priority_updates);
+#ifndef TO_BE_DELETED /* Alias for the low_priority_updates */
+sys_var_thd_bool sys_sql_low_priority_updates("sql_low_priority_updates",
+ &SV::low_priority_updates,
+ fix_low_priority_updates);
+#endif
+sys_var_thd_ulong sys_max_allowed_packet("max_allowed_packet",
+ &SV::max_allowed_packet);
+sys_var_long_ptr sys_max_binlog_cache_size("max_binlog_cache_size",
+ &max_binlog_cache_size);
+sys_var_long_ptr sys_max_binlog_size("max_binlog_size",
+ &max_binlog_size,
+ fix_max_binlog_size);
+sys_var_long_ptr sys_max_connections("max_connections",
+ &max_connections,
+ fix_max_connections);
+sys_var_long_ptr sys_max_connect_errors("max_connect_errors",
+ &max_connect_errors);
+sys_var_long_ptr sys_max_delayed_threads("max_delayed_threads",
+ &max_insert_delayed_threads,
+ fix_max_connections);
+sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size",
+ &SV::max_heap_table_size);
+sys_var_thd_ha_rows sys_max_join_size("max_join_size",
+ &SV::max_join_size,
+ fix_max_join_size);
+sys_var_thd_ulong sys_max_seeks_for_key("max_seeks_for_key",
+ &SV::max_seeks_for_key);
+#ifndef TO_BE_DELETED /* Alias for max_join_size */
+sys_var_thd_ha_rows sys_sql_max_join_size("sql_max_join_size",
+ &SV::max_join_size,
+ fix_max_join_size);
+#endif
+sys_var_long_ptr sys_max_relay_log_size("max_relay_log_size",
+ &max_relay_log_size,
+ fix_max_relay_log_size);
+sys_var_thd_ulong sys_max_sort_length("max_sort_length",
+ &SV::max_sort_length);
+sys_var_long_ptr sys_max_user_connections("max_user_connections",
+ &max_user_connections);
+sys_var_thd_ulong sys_max_tmp_tables("max_tmp_tables",
+ &SV::max_tmp_tables);
+sys_var_long_ptr sys_max_write_lock_count("max_write_lock_count",
+ &max_write_lock_count);
+sys_var_thd_ulonglong sys_myisam_max_extra_sort_file_size("myisam_max_extra_sort_file_size", &SV::myisam_max_extra_sort_file_size, fix_myisam_max_extra_sort_file_size, 1);
+sys_var_thd_ulonglong sys_myisam_max_sort_file_size("myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
+sys_var_thd_ulong sys_myisam_repair_threads("myisam_repair_threads", &SV::myisam_repair_threads);
+sys_var_thd_ulong sys_myisam_sort_buffer_size("myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
+sys_var_thd_ulong sys_net_buffer_length("net_buffer_length",
+ &SV::net_buffer_length);
+sys_var_thd_ulong sys_net_read_timeout("net_read_timeout",
+ &SV::net_read_timeout,
+ fix_net_read_timeout);
+sys_var_thd_ulong sys_net_write_timeout("net_write_timeout",
+ &SV::net_write_timeout,
+ fix_net_write_timeout);
+sys_var_thd_ulong sys_net_retry_count("net_retry_count",
+ &SV::net_retry_count,
+ fix_net_retry_count);
+sys_var_thd_bool sys_new_mode("new", &SV::new_mode);
+sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
+ &SV::read_buff_size);
+sys_var_bool_ptr sys_readonly("read_only", &opt_readonly);
+sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size",
+ &SV::read_rnd_buff_size);
+sys_var_long_ptr sys_rpl_recovery_rank("rpl_recovery_rank",
+ &rpl_recovery_rank);
+sys_var_long_ptr sys_query_cache_size("query_cache_size",
+ &query_cache_size,
+ fix_query_cache_size);
+
+sys_var_thd_ulong sys_range_alloc_block_size("range_alloc_block_size",
+ &SV::range_alloc_block_size);
+sys_var_thd_ulong sys_query_alloc_block_size("query_alloc_block_size",
+ &SV::query_alloc_block_size,
+ fix_thd_mem_root);
+sys_var_thd_ulong sys_query_prealloc_size("query_prealloc_size",
+ &SV::query_prealloc_size,
+ fix_thd_mem_root);
+sys_var_thd_ulong sys_trans_alloc_block_size("transaction_alloc_block_size",
+ &SV::trans_alloc_block_size,
+ fix_trans_mem_root);
+sys_var_thd_ulong sys_trans_prealloc_size("transaction_prealloc_size",
+ &SV::trans_prealloc_size,
+ fix_trans_mem_root);
+
+#ifdef HAVE_QUERY_CACHE
+sys_var_long_ptr sys_query_cache_limit("query_cache_limit",
+ &query_cache.query_cache_limit);
+sys_var_thd_enum sys_query_cache_type("query_cache_type",
+ &SV::query_cache_type,
+ &query_cache_type_typelib);
+#endif /* HAVE_QUERY_CACHE */
+sys_var_long_ptr sys_server_id("server_id",&server_id);
+sys_var_bool_ptr sys_slave_compressed_protocol("slave_compressed_protocol",
+ &opt_slave_compressed_protocol);
+sys_var_long_ptr sys_slave_net_timeout("slave_net_timeout",
+ &slave_net_timeout);
+sys_var_long_ptr sys_slow_launch_time("slow_launch_time",
+ &slow_launch_time);
+sys_var_thd_ulong sys_sort_buffer("sort_buffer_size",
+ &SV::sortbuff_size);
+sys_var_thd_enum sys_table_type("table_type", &SV::table_type,
+ &ha_table_typelib);
+sys_var_long_ptr sys_table_cache_size("table_cache",
+ &table_cache_size);
+sys_var_long_ptr sys_thread_cache_size("thread_cache_size",
+ &thread_cache_size);
+sys_var_thd_enum sys_tx_isolation("tx_isolation",
+ &SV::tx_isolation,
+ &tx_isolation_typelib,
+ fix_tx_isolation);
+sys_var_thd_ulong sys_tmp_table_size("tmp_table_size",
+ &SV::tmp_table_size);
+sys_var_thd_ulong sys_net_wait_timeout("wait_timeout",
+ &SV::net_wait_timeout);
+
+#ifdef HAVE_INNOBASE_DB
+sys_var_long_ptr sys_innodb_max_dirty_pages_pct("innodb_max_dirty_pages_pct",
+ &srv_max_buf_pool_modified_pct);
+#endif
+
+
+/*
+ Variables that are bits in THD
+*/
+
+static sys_var_thd_bit sys_autocommit("autocommit",
+ set_option_autocommit,
+ OPTION_NOT_AUTOCOMMIT,
+ 1);
+static sys_var_thd_bit sys_big_tables("big_tables",
+ set_option_bit,
+ OPTION_BIG_TABLES);
+#ifndef TO_BE_DELETED /* Alias for big_tables */
+static sys_var_thd_bit sys_sql_big_tables("sql_big_tables",
+ set_option_bit,
+ OPTION_BIG_TABLES);
+#endif
+static sys_var_thd_bit sys_big_selects("sql_big_selects",
+ set_option_bit,
+ OPTION_BIG_SELECTS);
+static sys_var_thd_bit sys_log_off("sql_log_off",
+ set_option_bit,
+ OPTION_LOG_OFF);
+static sys_var_thd_bit sys_log_update("sql_log_update",
+ set_log_update,
+ OPTION_UPDATE_LOG);
+static sys_var_thd_bit sys_log_binlog("sql_log_bin",
+ set_log_update,
+ OPTION_BIN_LOG);
+static sys_var_thd_bit sys_sql_warnings("sql_warnings",
+ set_option_bit,
+ OPTION_WARNINGS);
+static sys_var_thd_bit sys_auto_is_null("sql_auto_is_null",
+ set_option_bit,
+ OPTION_AUTO_IS_NULL);
+static sys_var_thd_bit sys_safe_updates("sql_safe_updates",
+ set_option_bit,
+ OPTION_SAFE_UPDATES);
+static sys_var_thd_bit sys_buffer_results("sql_buffer_result",
+ set_option_bit,
+ OPTION_BUFFER_RESULT);
+static sys_var_thd_bit sys_quote_show_create("sql_quote_show_create",
+ set_option_bit,
+ OPTION_QUOTE_SHOW_CREATE);
+static sys_var_thd_bit sys_foreign_key_checks("foreign_key_checks",
+ set_option_bit,
+ OPTION_NO_FOREIGN_KEY_CHECKS,
+ 1);
+static sys_var_thd_bit sys_unique_checks("unique_checks",
+ set_option_bit,
+ OPTION_RELAXED_UNIQUE_CHECKS,
+ 1);
+
+
+/* Local state variables */
+
+static sys_var_thd_ha_rows sys_select_limit("sql_select_limit",
+ &SV::select_limit);
+static sys_var_timestamp sys_timestamp("timestamp");
+static sys_var_last_insert_id sys_last_insert_id("last_insert_id");
+static sys_var_last_insert_id sys_identity("identity");
+static sys_var_insert_id sys_insert_id("insert_id");
+/* alias for last_insert_id() to be compatible with Sybase */
+static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter");
+static sys_var_rand_seed1 sys_rand_seed1("rand_seed1");
+static sys_var_rand_seed2 sys_rand_seed2("rand_seed2");
+
+static sys_var_thd_ulong sys_default_week_format("default_week_format",
+ &SV::default_week_format);
+
+/*
+ List of all variables for initialisation and storage in hash
+ This is sorted in alphabetical order to make it easy to add new variables
+
+ If the variable is not in this list, it can't be changed with
+ SET variable_name=
+*/
+
+sys_var *sys_variables[]=
+{
+ &sys_auto_is_null,
+ &sys_autocommit,
+ &sys_big_tables,
+ &sys_big_selects,
+ &sys_binlog_cache_size,
+ &sys_buffer_results,
+ &sys_bulk_insert_buff_size,
+ &sys_concurrent_insert,
+ &sys_connect_timeout,
+ &sys_default_week_format,
+ &sys_convert_charset,
+ &sys_delay_key_write,
+ &sys_delayed_insert_limit,
+ &sys_delayed_insert_timeout,
+ &sys_delayed_queue_size,
+ &sys_flush,
+ &sys_flush_time,
+ &sys_foreign_key_checks,
+ &sys_identity,
+ &sys_insert_id,
+ &sys_interactive_timeout,
+ &sys_join_buffer_size,
+ &sys_key_buffer_size,
+ &sys_last_insert_id,
+ &sys_local_infile,
+ &sys_log_binlog,
+ &sys_log_off,
+ &sys_log_update,
+ &sys_log_warnings,
+ &sys_long_query_time,
+ &sys_low_priority_updates,
+ &sys_max_allowed_packet,
+ &sys_max_binlog_cache_size,
+ &sys_max_binlog_size,
+ &sys_max_connect_errors,
+ &sys_max_connections,
+ &sys_max_delayed_threads,
+ &sys_max_heap_table_size,
+ &sys_max_join_size,
+ &sys_max_relay_log_size,
+ &sys_max_seeks_for_key,
+ &sys_max_sort_length,
+ &sys_max_tmp_tables,
+ &sys_max_user_connections,
+ &sys_max_write_lock_count,
+ &sys_myisam_max_extra_sort_file_size,
+ &sys_myisam_max_sort_file_size,
+ &sys_myisam_repair_threads,
+ &sys_myisam_sort_buffer_size,
+ &sys_net_buffer_length,
+ &sys_net_read_timeout,
+ &sys_net_retry_count,
+ &sys_net_wait_timeout,
+ &sys_net_write_timeout,
+ &sys_new_mode,
+ &sys_query_alloc_block_size,
+ &sys_query_cache_size,
+ &sys_query_prealloc_size,
+#ifdef HAVE_QUERY_CACHE
+ &sys_query_cache_limit,
+ &sys_query_cache_type,
+#endif /* HAVE_QUERY_CACHE */
+ &sys_quote_show_create,
+ &sys_rand_seed1,
+ &sys_rand_seed2,
+ &sys_range_alloc_block_size,
+ &sys_read_buff_size,
+ &sys_read_rnd_buff_size,
+ &sys_rpl_recovery_rank,
+ &sys_safe_updates,
+ &sys_select_limit,
+ &sys_server_id,
+ &sys_slave_compressed_protocol,
+ &sys_slave_net_timeout,
+ &sys_slave_skip_counter,
+ &sys_readonly,
+ &sys_slow_launch_time,
+ &sys_sort_buffer,
+ &sys_sql_big_tables,
+ &sys_sql_low_priority_updates,
+ &sys_sql_max_join_size,
+ &sys_sql_warnings,
+ &sys_table_cache_size,
+ &sys_table_type,
+ &sys_thread_cache_size,
+ &sys_timestamp,
+ &sys_tmp_table_size,
+ &sys_trans_alloc_block_size,
+ &sys_trans_prealloc_size,
+ &sys_tx_isolation,
+#ifdef HAVE_INNOBASE_DB
+ &sys_innodb_max_dirty_pages_pct,
+#endif
+ &sys_unique_checks
+};
+
+
+/*
+ Variables shown by SHOW variables in alphabetical order
+*/
+
+struct show_var_st init_vars[]= {
+ {"back_log", (char*) &back_log, SHOW_LONG},
+ {"basedir", mysql_home, SHOW_CHAR},
+#ifdef HAVE_BERKELEY_DB
+ {"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
+ {"bdb_log_buffer_size", (char*) &berkeley_log_buffer_size, SHOW_LONG},
+ {"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
+ {"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG},
+ {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR},
+ {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL},
+ {"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR},
+ {"bdb_version", (char*) DB_VERSION_STRING, SHOW_CHAR},
+#endif
+ {sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size, SHOW_SYS},
+ {sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS},
+ {sys_charset.name, (char*) &sys_charset, SHOW_SYS},
+ {"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
+ {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS},
+ {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS},
+ {sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS},
+ {"datadir", mysql_real_data_home, SHOW_CHAR},
+ {"default_week_format", (char*) &sys_default_week_format, SHOW_SYS},
+ {sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS},
+ {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS},
+ {sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS},
+ {sys_delayed_queue_size.name,(char*) &sys_delayed_queue_size, SHOW_SYS},
+ {sys_flush.name, (char*) &sys_flush, SHOW_SYS},
+ {sys_flush_time.name, (char*) &sys_flush_time, SHOW_SYS},
+ {"ft_boolean_syntax", (char*) ft_boolean_syntax, SHOW_CHAR},
+ {"ft_min_word_len", (char*) &ft_min_word_len, SHOW_LONG},
+ {"ft_max_word_len", (char*) &ft_max_word_len, SHOW_LONG},
+ {"ft_max_word_len_for_sort",(char*) &ft_max_word_len_for_sort, SHOW_LONG},
+ {"ft_stopword_file", (char*) &ft_stopword_file, SHOW_CHAR_PTR},
+ {"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
+ {"have_crypt", (char*) &have_crypt, SHOW_HAVE},
+ {"have_innodb", (char*) &have_innodb, SHOW_HAVE},
+ {"have_isam", (char*) &have_isam, SHOW_HAVE},
+ {"have_raid", (char*) &have_raid, SHOW_HAVE},
+ {"have_symlink", (char*) &have_symlink, SHOW_HAVE},
+ {"have_openssl", (char*) &have_openssl, SHOW_HAVE},
+ {"have_query_cache", (char*) &have_query_cache, SHOW_HAVE},
+ {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
+#ifdef HAVE_INNOBASE_DB
+ {"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
+ {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONG },
+ {"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR},
+ {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR},
+ {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG },
+ {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
+ {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG },
+ {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_INT},
+ {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL},
+ {"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
+ {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
+ {"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR},
+ {"innodb_log_archive", (char*) &innobase_log_archive, SHOW_MY_BOOL},
+ {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG },
+ {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONG},
+ {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group, SHOW_LONG},
+ {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR},
+ {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
+ {sys_innodb_max_dirty_pages_pct.name, (char*) &sys_innodb_max_dirty_pages_pct, SHOW_SYS},
+#endif
+ {sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS},
+ {sys_join_buffer_size.name, (char*) &sys_join_buffer_size, SHOW_SYS},
+ {sys_key_buffer_size.name, (char*) &sys_key_buffer_size, SHOW_SYS},
+ {"language", language, SHOW_CHAR},
+ {"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
+ {sys_local_infile.name, (char*) &sys_local_infile, SHOW_SYS},
+#ifdef HAVE_MLOCKALL
+ {"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
+#endif
+ {"log", (char*) &opt_log, SHOW_BOOL},
+ {"log_update", (char*) &opt_update_log, SHOW_BOOL},
+ {"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
+ {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL},
+ {"log_slow_queries", (char*) &opt_slow_log, SHOW_BOOL},
+ {sys_log_warnings.name, (char*) &sys_log_warnings, SHOW_SYS},
+ {sys_long_query_time.name, (char*) &sys_long_query_time, SHOW_SYS},
+ {sys_low_priority_updates.name, (char*) &sys_low_priority_updates, SHOW_SYS},
+ {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_INT},
+ {sys_max_allowed_packet.name,(char*) &sys_max_allowed_packet, SHOW_SYS},
+ {sys_max_binlog_cache_size.name,(char*) &sys_max_binlog_cache_size, SHOW_SYS},
+ {sys_max_binlog_size.name, (char*) &sys_max_binlog_size, SHOW_SYS},
+ {sys_max_connections.name, (char*) &sys_max_connections, SHOW_SYS},
+ {sys_max_connect_errors.name, (char*) &sys_max_connect_errors, SHOW_SYS},
+ {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS},
+ {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS},
+ {sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS},
+ {sys_max_relay_log_size.name, (char*) &sys_max_relay_log_size, SHOW_SYS},
+ {sys_max_seeks_for_key.name, (char*) &sys_max_seeks_for_key, SHOW_SYS},
+ {sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS},
+ {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS},
+ {sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS},
+ {sys_max_write_lock_count.name, (char*) &sys_max_write_lock_count,SHOW_SYS},
+ {sys_myisam_max_extra_sort_file_size.name,
+ (char*) &sys_myisam_max_extra_sort_file_size,
+ SHOW_SYS},
+ {sys_myisam_max_sort_file_size.name, (char*) &sys_myisam_max_sort_file_size,
+ SHOW_SYS},
+ {sys_myisam_repair_threads.name, (char*) &sys_myisam_repair_threads,
+ SHOW_SYS},
+ {"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR},
+ {sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
+#ifdef __NT__
+ {"named_pipe", (char*) &opt_enable_named_pipe, SHOW_MY_BOOL},
+#endif
+ {sys_net_buffer_length.name,(char*) &sys_net_buffer_length, SHOW_SYS},
+ {sys_net_read_timeout.name, (char*) &sys_net_read_timeout, SHOW_SYS},
+ {sys_net_retry_count.name, (char*) &sys_net_retry_count, SHOW_SYS},
+ {sys_net_write_timeout.name,(char*) &sys_net_write_timeout, SHOW_SYS},
+ {sys_new_mode.name, (char*) &sys_new_mode, SHOW_SYS},
+ {"open_files_limit", (char*) &open_files_limit, SHOW_LONG},
+ {"pid_file", (char*) pidfile_name, SHOW_CHAR},
+ {"log_error", (char*) log_error_file, SHOW_CHAR},
+ {"port", (char*) &mysql_port, SHOW_INT},
+ {"protocol_version", (char*) &protocol_version, SHOW_INT},
+ {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size,
+ SHOW_SYS},
+#ifdef HAVE_QUERY_CACHE
+ {sys_query_cache_limit.name,(char*) &sys_query_cache_limit, SHOW_SYS},
+ {sys_query_cache_size.name, (char*) &sys_query_cache_size, SHOW_SYS},
+ {sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS},
+#endif /* HAVE_QUERY_CACHE */
+ {sys_query_prealloc_size.name, (char*) &sys_query_prealloc_size, SHOW_SYS},
+ {sys_range_alloc_block_size.name, (char*) &sys_range_alloc_block_size,
+ SHOW_SYS},
+ {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS},
+ {sys_readonly.name, (char*) &sys_readonly, SHOW_SYS},
+ {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS},
+ {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank, SHOW_SYS},
+ {sys_server_id.name, (char*) &sys_server_id, SHOW_SYS},
+ {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS},
+ {"skip_external_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
+ {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
+ {"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL},
+ {sys_slow_launch_time.name, (char*) &sys_slow_launch_time, SHOW_SYS},
+#ifdef HAVE_SYS_UN_H
+ {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR},
+#endif
+ {sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS},
+ {"sql_mode", (char*) &opt_sql_mode, SHOW_LONG},
+ {"table_cache", (char*) &table_cache_size, SHOW_LONG},
+ {sys_table_type.name, (char*) &sys_table_type, SHOW_SYS},
+ {sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS},
+#ifdef HAVE_THR_SETCONCURRENCY
+ {"thread_concurrency", (char*) &concurrency, SHOW_LONG},
+#endif
+ {"thread_stack", (char*) &thread_stack, SHOW_LONG},
+ {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS},
+#ifdef HAVE_TZNAME
+ {"timezone", time_zone, SHOW_CHAR},
+#endif
+ {sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS},
+ {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR},
+ {sys_trans_alloc_block_size.name, (char*) &sys_trans_alloc_block_size,
+ SHOW_SYS},
+ {sys_trans_prealloc_size.name, (char*) &sys_trans_prealloc_size, SHOW_SYS},
+ {"version", server_version, SHOW_CHAR},
+ {"version_comment", (char*) MYSQL_COMPILATION_COMMENT, SHOW_CHAR},
+ {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout, SHOW_SYS},
+ {NullS, NullS, SHOW_LONG}
+};
+
+/*
+ Functions to check and update variables
+*/
+
+/*
+ The following 3 functions need to be changed in 4.1 when we allow
+ one to change character sets
+*/
+
+static bool sys_check_charset(THD *thd, set_var *var)
+{
+ return 0;
+}
+
+
+static bool sys_update_charset(THD *thd, set_var *var)
+{
+ return 0;
+}
+
+
+static void sys_set_default_charset(THD *thd, enum_var_type type)
+{
+}
+
+
+/*
+ If one sets the LOW_PRIORIY UPDATES flag, we also must change the
+ used lock type
+*/
+
+static void fix_low_priority_updates(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->update_lock_default= (thd->variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY : TL_WRITE);
+}
+
+
+static void
+fix_myisam_max_extra_sort_file_size(THD *thd, enum_var_type type)
+{
+ myisam_max_extra_temp_length=
+ (my_off_t) global_system_variables.myisam_max_extra_sort_file_size;
+}
+
+
+static void
+fix_myisam_max_sort_file_size(THD *thd, enum_var_type type)
+{
+ myisam_max_temp_length=
+ (my_off_t) global_system_variables.myisam_max_sort_file_size;
+}
+
+/*
+ Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR
+*/
+
+static void fix_max_join_size(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ {
+ if (thd->variables.max_join_size == HA_POS_ERROR)
+ thd->options|= OPTION_BIG_SELECTS;
+ else
+ thd->options&= ~OPTION_BIG_SELECTS;
+ }
+}
+
+
+/*
+ If one doesn't use the SESSION modifier, the isolation level
+ is only active for the next command
+*/
+
+static void fix_tx_isolation(THD *thd, enum_var_type type)
+{
+ if (type == OPT_SESSION)
+ thd->session_tx_isolation= ((enum_tx_isolation)
+ thd->variables.tx_isolation);
+}
+
+
+/*
+ If we are changing the thread variable, we have to copy it to NET too
+*/
+
+static void fix_net_read_timeout(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->net.read_timeout=thd->variables.net_read_timeout;
+}
+
+
+static void fix_net_write_timeout(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->net.write_timeout=thd->variables.net_write_timeout;
+}
+
+static void fix_net_retry_count(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->net.retry_count=thd->variables.net_retry_count;
+}
+
+
+static void fix_query_cache_size(THD *thd, enum_var_type type)
+{
+#ifdef HAVE_QUERY_CACHE
+ query_cache.resize(query_cache_size);
+#endif
+}
+
+
+static void fix_key_buffer_size(THD *thd, enum_var_type type)
+{
+ ha_resize_key_cache();
+}
+
+
+extern void fix_delay_key_write(THD *thd, enum_var_type type)
+{
+ switch ((enum_delay_key_write) delay_key_write_options) {
+ case DELAY_KEY_WRITE_NONE:
+ myisam_delay_key_write=0;
+ break;
+ case DELAY_KEY_WRITE_ON:
+ myisam_delay_key_write=1;
+ break;
+ case DELAY_KEY_WRITE_ALL:
+ myisam_delay_key_write=1;
+ ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
+ break;
+ }
+}
+
+static void fix_max_binlog_size(THD *thd, enum_var_type type)
+{
+ DBUG_ENTER("fix_max_binlog_size");
+ DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu",
+ max_binlog_size, max_relay_log_size));
+ mysql_bin_log.set_max_size(max_binlog_size);
+ if (!max_relay_log_size)
+ active_mi->rli.relay_log.set_max_size(max_binlog_size);
+ DBUG_VOID_RETURN;
+}
+
+static void fix_max_relay_log_size(THD *thd, enum_var_type type)
+{
+ DBUG_ENTER("fix_max_relay_log_size");
+ DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu",
+ max_binlog_size, max_relay_log_size));
+ active_mi->rli.relay_log.set_max_size(max_relay_log_size ?
+ max_relay_log_size: max_binlog_size);
+ DBUG_VOID_RETURN;
+}
+
+
+static void fix_max_connections(THD *thd, enum_var_type type)
+{
+ resize_thr_alarm(max_connections + max_insert_delayed_threads + 10);
+}
+
+
+static void fix_thd_mem_root(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ reset_root_defaults(&thd->mem_root,
+ thd->variables.query_alloc_block_size,
+ thd->variables.query_prealloc_size);
+}
+
+
+static void fix_trans_mem_root(THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ reset_root_defaults(&thd->transaction.mem_root,
+ thd->variables.trans_alloc_block_size,
+ thd->variables.trans_prealloc_size);
+}
+
+
+bool sys_var_long_ptr::update(THD *thd, set_var *var)
+{
+ ulonglong tmp= var->value->val_int();
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ if (option_limits)
+ *value= (ulong) getopt_ull_limit_value(tmp, option_limits);
+ else
+ *value= (ulong) tmp;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ return 0;
+}
+
+
+void sys_var_long_ptr::set_default(THD *thd, enum_var_type type)
+{
+ *value= (ulong) option_limits->def_value;
+}
+
+
+bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
+{
+ ulonglong tmp= var->value->val_int();
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ if (option_limits)
+ *value= (ulonglong) getopt_ull_limit_value(tmp, option_limits);
+ else
+ *value= (ulonglong) tmp;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ return 0;
+}
+
+
+void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
+{
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ *value= (ulonglong) option_limits->def_value;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+}
+
+
+bool sys_var_bool_ptr::update(THD *thd, set_var *var)
+{
+ *value= (my_bool) var->save_result.ulong_value;
+ return 0;
+}
+
+
+void sys_var_bool_ptr::set_default(THD *thd, enum_var_type type)
+{
+ *value= (my_bool) option_limits->def_value;
+}
+
+
+bool sys_var_enum::update(THD *thd, set_var *var)
+{
+ *value= (uint) var->save_result.ulong_value;
+ return 0;
+}
+
+
+byte *sys_var_enum::value_ptr(THD *thd, enum_var_type type)
+{
+ return (byte*) enum_names->type_names[*value];
+}
+
+
+bool sys_var_thd_ulong::update(THD *thd, set_var *var)
+{
+ ulonglong tmp= var->value->val_int();
+
+ /* Don't use bigger value than given with --maximum-variable-name=.. */
+ if ((ulong) tmp > max_system_variables.*offset)
+ tmp= max_system_variables.*offset;
+
+ if (option_limits)
+ tmp= (ulong) getopt_ull_limit_value(tmp, option_limits);
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.*offset= (ulong) tmp;
+ else
+ thd->variables.*offset= (ulong) tmp;
+ return 0;
+}
+
+
+void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ {
+ /* We will not come here if option_limits is not set */
+ global_system_variables.*offset= (ulong) option_limits->def_value;
+ }
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return (byte*) &(global_system_variables.*offset);
+ return (byte*) &(thd->variables.*offset);
+}
+
+
+bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
+{
+ ulonglong tmp= var->value->val_int();
+
+ /* Don't use bigger value than given with --maximum-variable-name=.. */
+ if ((ha_rows) tmp > max_system_variables.*offset)
+ tmp= max_system_variables.*offset;
+
+ if (option_limits)
+ tmp= (ha_rows) getopt_ull_limit_value(tmp, option_limits);
+ if (var->type == OPT_GLOBAL)
+ {
+ /* Lock is needed to make things safe on 32 bit systems */
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ global_system_variables.*offset= (ha_rows) tmp;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ }
+ else
+ thd->variables.*offset= (ha_rows) tmp;
+ return 0;
+}
+
+
+void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ {
+ /* We will not come here if option_limits is not set */
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ global_system_variables.*offset= (ha_rows) option_limits->def_value;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ }
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return (byte*) &(global_system_variables.*offset);
+ return (byte*) &(thd->variables.*offset);
+}
+
+
+bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
+{
+ ulonglong tmp= var->value->val_int();
+
+ if ((ulonglong) tmp > max_system_variables.*offset)
+ tmp= max_system_variables.*offset;
+
+ if (option_limits)
+ tmp= (ulong) getopt_ull_limit_value(tmp, option_limits);
+ if (var->type == OPT_GLOBAL)
+ {
+ /* Lock is needed to make things safe on 32 bit systems */
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ global_system_variables.*offset= (ulonglong) tmp;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ }
+ else
+ thd->variables.*offset= (ulonglong) tmp;
+ return 0;
+}
+
+
+void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ {
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ global_system_variables.*offset= (ulong) option_limits->def_value;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ }
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return (byte*) &(global_system_variables.*offset);
+ return (byte*) &(thd->variables.*offset);
+}
+
+
+bool sys_var_thd_bool::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.*offset= (my_bool) var->save_result.ulong_value;
+ else
+ thd->variables.*offset= (my_bool) var->save_result.ulong_value;
+ return 0;
+}
+
+
+void sys_var_thd_bool::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.*offset= (my_bool) option_limits->def_value;
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ return (byte*) &(global_system_variables.*offset);
+ return (byte*) &(thd->variables.*offset);
+}
+
+
+bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names)
+{
+ char buff[80];
+ const char *value;
+ String str(buff,sizeof(buff)), *res;
+
+ if (var->value->result_type() == STRING_RESULT)
+ {
+ if (!(res=var->value->val_str(&str)) ||
+ ((long) (var->save_result.ulong_value=
+ (ulong) find_type(res->c_ptr(), enum_names, 3)-1))
+ < 0)
+ {
+ value= res ? res->c_ptr() : "NULL";
+ goto err;
+ }
+ }
+ else
+ {
+ ulonglong tmp=var->value->val_int();
+ if (tmp >= enum_names->count)
+ {
+ llstr(tmp,buff);
+ value=buff; // Wrong value is here
+ goto err;
+ }
+ var->save_result.ulong_value= (ulong) tmp; // Save for update
+ }
+ return 0;
+
+err:
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value);
+ return 1;
+}
+
+/*
+ Return an Item for a variable. Used with @@[global.]variable_name
+
+ If type is not given, return local value if exists, else global
+
+ We have to use netprintf() instead of my_error() here as this is
+ called on the parsing stage.
+*/
+
+Item *sys_var::item(THD *thd, enum_var_type var_type)
+{
+ if (check_type(var_type))
+ {
+ if (var_type != OPT_DEFAULT)
+ {
+ net_printf(&thd->net,ER_INCORRECT_GLOBAL_LOCAL_VAR,
+ name, var_type == OPT_GLOBAL ? "LOCAL" : "GLOBAL");
+ return 0;
+ }
+ /* As there was no local variable, return the global value */
+ var_type= OPT_GLOBAL;
+ }
+ switch (type()) {
+ case SHOW_LONG:
+ return new Item_uint((int32) *(ulong*) value_ptr(thd, var_type));
+ case SHOW_LONGLONG:
+ {
+ longlong value;
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ value= *(longlong*) value_ptr(thd, var_type);
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ return new Item_int(value);
+ }
+ case SHOW_HA_ROWS:
+ {
+ ha_rows value;
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ value= *(ha_rows*) value_ptr(thd, var_type);
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ return new Item_int((longlong) value);
+ }
+ case SHOW_MY_BOOL:
+ return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type),1);
+ case SHOW_CHAR:
+ {
+ char *str= (char*) value_ptr(thd, var_type);
+ return new Item_string(str,strlen(str));
+ }
+ default:
+ net_printf(&thd->net, ER_VAR_CANT_BE_READ, name);
+ }
+ return 0;
+}
+
+
+bool sys_var_thd_enum::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.*offset= var->save_result.ulong_value;
+ else
+ thd->variables.*offset= var->save_result.ulong_value;
+ return 0;
+}
+
+
+void sys_var_thd_enum::set_default(THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.*offset= (ulong) option_limits->def_value;
+ else
+ thd->variables.*offset= global_system_variables.*offset;
+}
+
+
+byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type)
+{
+ ulong tmp= ((type == OPT_GLOBAL) ?
+ global_system_variables.*offset :
+ thd->variables.*offset);
+ return (byte*) enum_names->type_names[tmp];
+}
+
+
+bool sys_var_thd_bit::update(THD *thd, set_var *var)
+{
+ int res= (*update_func)(thd, var);
+ thd->lex.select_lex.options=thd->options;
+ return res;
+}
+
+
+byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type)
+{
+ /*
+ If reverse is 0 (default) return 1 if bit is set.
+ If reverse is 1, return 0 if bit is set
+ */
+ thd->sys_var_tmp.my_bool_value= ((thd->options & bit_flag) ?
+ !reverse : reverse);
+ return (byte*) &thd->sys_var_tmp.my_bool_value;
+}
+
+
+bool sys_var_thd_conv_charset::check(THD *thd, set_var *var)
+{
+ CONVERT *tmp;
+ char buff[80];
+ String str(buff,sizeof(buff)), *res;
+
+ if (!var->value) // Default value
+ {
+ var->save_result.convert= (var->type != OPT_GLOBAL ?
+ global_system_variables.convert_set
+ : (CONVERT*) 0);
+ return 0;
+ }
+ if (!(res=var->value->val_str(&str)))
+ res= &empty_string;
+
+ if (!(tmp=get_convert_set(res->c_ptr())))
+ {
+ my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
+ return 1;
+ }
+ var->save_result.convert=tmp; // Save for update
+ return 0;
+}
+
+
+bool sys_var_thd_conv_charset::update(THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ global_system_variables.convert_set= var->save_result.convert;
+ else
+ thd->lex.convert_set= thd->variables.convert_set=
+ var->save_result.convert;
+ return 0;
+}
+
+
+byte *sys_var_thd_conv_charset::value_ptr(THD *thd, enum_var_type type)
+{
+ CONVERT *conv= ((type == OPT_GLOBAL) ?
+ global_system_variables.convert_set :
+ thd->variables.convert_set);
+ return conv ? (byte*) conv->name : (byte*) "";
+}
+
+
+void sys_var_thd_conv_charset::set_default(THD *thd, enum_var_type type)
+{
+ thd->variables.convert_set= global_system_variables.convert_set;
+}
+
+
+bool sys_var_timestamp::update(THD *thd, set_var *var)
+{
+ thd->set_time((time_t) var->value->val_int());
+ return 0;
+}
+
+
+void sys_var_timestamp::set_default(THD *thd, enum_var_type type)
+{
+ thd->user_time=0;
+}
+
+
+byte *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type)
+{
+ thd->sys_var_tmp.long_value= (long) thd->start_time;
+ return (byte*) &thd->sys_var_tmp.long_value;
+}
+
+
+bool sys_var_last_insert_id::update(THD *thd, set_var *var)
+{
+ thd->insert_id(var->value->val_int());
+ return 0;
+}
+
+
+byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type)
+{
+ thd->sys_var_tmp.long_value= (long) thd->insert_id();
+ return (byte*) &thd->last_insert_id;
+}
+
+
+bool sys_var_insert_id::update(THD *thd, set_var *var)
+{
+ thd->next_insert_id=var->value->val_int();
+ return 0;
+}
+
+
+byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type)
+{
+ return (byte*) &thd->current_insert_id;
+}
+
+
+bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
+{
+ int result= 0;
+ LOCK_ACTIVE_MI;
+ pthread_mutex_lock(&active_mi->rli.run_lock);
+ if (active_mi->rli.slave_running)
+ {
+ my_error(ER_SLAVE_MUST_STOP, MYF(0));
+ result=1;
+ }
+ pthread_mutex_unlock(&active_mi->rli.run_lock);
+ UNLOCK_ACTIVE_MI;
+ return result;
+}
+
+
+bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
+{
+ LOCK_ACTIVE_MI;
+ pthread_mutex_lock(&active_mi->rli.run_lock);
+ /*
+ The following test should normally never be true as we test this
+ in the check function; To be safe against multiple
+ SQL_SLAVE_SKIP_COUNTER request, we do the check anyway
+ */
+ if (!active_mi->rli.slave_running)
+ {
+ pthread_mutex_lock(&active_mi->rli.data_lock);
+ active_mi->rli.slave_skip_counter= (ulong) var->value->val_int();
+ pthread_mutex_unlock(&active_mi->rli.data_lock);
+ }
+ pthread_mutex_unlock(&active_mi->rli.run_lock);
+ UNLOCK_ACTIVE_MI;
+ return 0;
+}
+
+
+bool sys_var_rand_seed1::update(THD *thd, set_var *var)
+{
+ thd->rand.seed1= (ulong) var->value->val_int();
+ return 0;
+}
+
+bool sys_var_rand_seed2::update(THD *thd, set_var *var)
+{
+ thd->rand.seed2= (ulong) var->value->val_int();
+ return 0;
+}
+
+
+/*
+ Functions to update thd->options bits
+*/
+
+static bool set_option_bit(THD *thd, set_var *var)
+{
+ sys_var_thd_bit *sys_var= ((sys_var_thd_bit*) var->var);
+ if ((var->save_result.ulong_value != 0) == sys_var->reverse)
+ thd->options&= ~sys_var->bit_flag;
+ else
+ thd->options|= sys_var->bit_flag;
+ return 0;
+}
+
+
+static bool set_option_autocommit(THD *thd, set_var *var)
+{
+ /* The test is negative as the flag we use is NOT autocommit */
+
+ ulong org_options=thd->options;
+
+ if (var->save_result.ulong_value != 0)
+ thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
+ else
+ thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
+
+ if ((org_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
+ {
+ if ((org_options & OPTION_NOT_AUTOCOMMIT))
+ {
+ /* We changed to auto_commit mode */
+ thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
+ thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
+ if (ha_commit(thd))
+ return 1;
+ }
+ else
+ {
+ thd->options&= ~(ulong) (OPTION_STATUS_NO_TRANS_UPDATE);
+ thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
+ }
+ }
+ return 0;
+}
+
+
+static bool set_log_update(THD *thd, set_var *var)
+{
+ if (opt_sql_bin_update)
+ ((sys_var_thd_bit*) var->var)->bit_flag|= (OPTION_BIN_LOG |
+ OPTION_UPDATE_LOG);
+ set_option_bit(thd, var);
+ return 0;
+}
+
+
+/****************************************************************************
+ Main handling of variables:
+ - Initialisation
+ - Searching during parsing
+ - Update loop
+****************************************************************************/
+
+/*
+ Find variable name in option my_getopt structure used for command line args
+
+ SYNOPSIS
+ find_option()
+ opt option structure array to search in
+ name variable name
+
+ RETURN VALUES
+ 0 Error
+ ptr pointer to option structure
+*/
+
+static struct my_option *find_option(struct my_option *opt, const char *name)
+{
+ uint length=strlen(name);
+ for (; opt->name; opt++)
+ {
+ if (!getopt_compare_strings(opt->name, name, length) &&
+ !opt->name[length])
+ {
+ /*
+ Only accept the option if one can set values through it.
+ If not, there is no default value or limits in the option.
+ */
+ return (opt->value) ? opt : 0;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ Return variable name and length for hashing of variables
+*/
+
+static byte *get_sys_var_length(const sys_var *var, uint *length,
+ my_bool first)
+{
+ *length= var->name_length;
+ return (byte*) var->name;
+}
+
+
+/*
+ Initialises sys variables and put them in system_variable_hash
+*/
+
+
+void set_var_init()
+{
+ extern struct my_option my_long_options[]; // From mysqld
+
+ hash_init(&system_variable_hash,array_elements(sys_variables),0,0,
+ (hash_get_key) get_sys_var_length,0, HASH_CASE_INSENSITIVE);
+ sys_var **var, **end;
+ for (var= sys_variables, end= sys_variables+array_elements(sys_variables) ;
+ var < end;
+ var++)
+ {
+ (*var)->name_length= strlen((*var)->name);
+ (*var)->option_limits= find_option(my_long_options, (*var)->name);
+ hash_insert(&system_variable_hash, (byte*) *var);
+ }
+
+ /*
+ Special cases
+ Needed because MySQL can't find the limits for a variable it it has
+ a different name than the command line option.
+ As these variables are deprecated, this code will disappear soon...
+ */
+ sys_sql_max_join_size.option_limits= sys_max_join_size.option_limits;
+}
+
+
+void set_var_free()
+{
+ hash_free(&system_variable_hash);
+}
+
+
+/*
+ Find a user set-table variable
+
+ SYNOPSIS
+ find_sys_var()
+ str Name of system variable to find
+ length Length of variable. zero means that we should use strlen()
+ on the variable
+
+ NOTE
+ We have to use net_printf() as this is called during the parsing stage
+
+ RETURN VALUES
+ pointer pointer to variable definitions
+ 0 Unknown variable (error message is given)
+*/
+
+sys_var *find_sys_var(const char *str, uint length)
+{
+ sys_var *var= (sys_var*) hash_search(&system_variable_hash,
+ (byte*) str,
+ length ? length :
+ strlen(str));
+ if (!var)
+ net_printf(&current_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str);
+ return var;
+}
+
+
+/*
+ Execute update of all variables
+
+ SYNOPSIS
+
+ sql_set
+ THD Thread id
+ set_var List of variables to update
+
+ DESCRIPTION
+ First run a check of all variables that all updates will go ok.
+ If yes, then execute all updates, returning an error if any one failed.
+
+ This should ensure that in all normal cases none all or variables are
+ updated
+
+ RETURN VALUE
+ 0 ok
+ 1 ERROR, message sent (normally no variables was updated)
+ -1 ERROR, message not sent
+*/
+
+int sql_set_variables(THD *thd, List<set_var_base> *var_list)
+{
+ int error= 0;
+ List_iterator<set_var_base> it(*var_list);
+
+ set_var_base *var;
+ while ((var=it++))
+ {
+ if ((error=var->check(thd)))
+ return error;
+ }
+ it.rewind();
+ while ((var=it++))
+ error|= var->update(thd); // Returns 0, -1 or 1
+ return error;
+}
+
+
+/*****************************************************************************
+ Functions to handle SET mysql_internal_variable=const_expr
+*****************************************************************************/
+
+int set_var::check(THD *thd)
+{
+ if (var->check_type(type))
+ {
+ my_error(type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE,
+ MYF(0),
+ var->name);
+ return -1;
+ }
+ if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)))
+ return 1;
+
+ /* value is a NULL pointer if we are using SET ... = DEFAULT */
+ if (!value)
+ {
+ if (var->check_default(type))
+ {
+ my_error(ER_NO_DEFAULT, MYF(0), var->name);
+ return -1;
+ }
+ return 0;
+ }
+
+ if (value->fix_fields(thd,0))
+ return -1;
+ if (var->check_update_type(value->result_type()))
+ {
+ my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
+ return -1;
+ }
+ return var->check(thd, this) ? -1 : 0;
+}
+
+
+int set_var::update(THD *thd)
+{
+ if (!value)
+ var->set_default(thd, type);
+ else if (var->update(thd, this))
+ return -1; // should never happen
+ if (var->after_update)
+ (*var->after_update)(thd, type);
+ return 0;
+}
+
+
+/*****************************************************************************
+ Functions to handle SET @user_variable=const_expr
+*****************************************************************************/
+
+int set_var_user::check(THD *thd)
+{
+ return user_var_item->fix_fields(thd,0) ? -1 : 0;
+}
+
+
+int set_var_user::update(THD *thd)
+{
+ if (user_var_item->update())
+ {
+ /* Give an error if it's not given already */
+ my_error(ER_SET_CONSTANTS_ONLY, MYF(0));
+ return -1;
+ }
+ return 0;
+}
+
+
+/*****************************************************************************
+ Functions to handle SET PASSWORD
+*****************************************************************************/
+
+int set_var_password::check(THD *thd)
+{
+ if (!user->host.str)
+ user->host.str= (char*) thd->host_or_ip;
+ /* Returns 1 as the function sends error to client */
+ return check_change_password(thd, user->host.str, user->user.str) ? 1 : 0;
+}
+
+int set_var_password::update(THD *thd)
+{
+ /* Returns 1 as the function sends error to client */
+ return (change_password(thd, user->host.str, user->user.str, password) ?
+ 1 : 0);
+}
+
+/****************************************************************************
+ Used templates
+****************************************************************************/
+
+#ifdef __GNUC__
+template class List<set_var_base>;
+template class List_iterator<set_var_base>;
+#endif
diff --git a/sql/set_var.h b/sql/set_var.h
new file mode 100644
index 00000000000..e22c55276a7
--- /dev/null
+++ b/sql/set_var.h
@@ -0,0 +1,506 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Classes to support the SET command */
+
+#ifdef __GNUC__
+#pragma interface /* gcc class implementation */
+#endif
+
+/****************************************************************************
+ Variables that are changable runtime are declared using the
+ following classes
+****************************************************************************/
+
+class sys_var;
+class set_var;
+typedef struct system_variables SV;
+extern TYPELIB bool_typelib, delay_key_write_typelib;
+
+enum enum_var_type
+{
+ OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL
+};
+
+typedef bool (*sys_check_func)(THD *, set_var *);
+typedef bool (*sys_update_func)(THD *, set_var *);
+typedef void (*sys_after_update_func)(THD *,enum_var_type);
+typedef void (*sys_set_default_func)(THD *, enum_var_type);
+
+class sys_var
+{
+public:
+ struct my_option *option_limits; /* Updated by by set_var_init() */
+ uint name_length; /* Updated by by set_var_init() */
+ const char *name;
+ sys_after_update_func after_update;
+ sys_var(const char *name_arg) :name(name_arg),after_update(0)
+ {}
+ sys_var(const char *name_arg,sys_after_update_func func)
+ :name(name_arg),after_update(func)
+ {}
+ virtual ~sys_var() {}
+ virtual bool check(THD *thd, set_var *var) { return 0; }
+ bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names);
+ virtual bool update(THD *thd, set_var *var)=0;
+ virtual void set_default(THD *thd, enum_var_type type) {}
+ virtual SHOW_TYPE type() { return SHOW_UNDEF; }
+ virtual byte *value_ptr(THD *thd, enum_var_type type) { return 0; }
+ virtual bool check_type(enum_var_type type)
+ { return type != OPT_GLOBAL; } /* Error if not GLOBAL */
+ virtual bool check_update_type(Item_result type)
+ { return type != INT_RESULT; } /* Assume INT */
+ virtual bool check_default(enum_var_type type)
+ { return option_limits == 0; }
+ Item *item(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_long_ptr :public sys_var
+{
+public:
+ ulong *value;
+ sys_var_long_ptr(const char *name_arg, ulong *value_ptr)
+ :sys_var(name_arg),value(value_ptr) {}
+ sys_var_long_ptr(const char *name_arg, ulong *value_ptr,
+ sys_after_update_func func)
+ :sys_var(name_arg,func), value(value_ptr) {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONG; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+};
+
+
+class sys_var_ulonglong_ptr :public sys_var
+{
+public:
+ ulonglong *value;
+ sys_var_ulonglong_ptr(const char *name_arg, ulonglong *value_ptr)
+ :sys_var(name_arg),value(value_ptr) {}
+ sys_var_ulonglong_ptr(const char *name_arg, ulonglong *value_ptr,
+ sys_after_update_func func)
+ :sys_var(name_arg,func), value(value_ptr) {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+};
+
+
+class sys_var_bool_ptr :public sys_var
+{
+public:
+ my_bool *value;
+ sys_var_bool_ptr(const char *name_arg, my_bool *value_arg)
+ :sys_var(name_arg),value(value_arg)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, &bool_typelib);
+ }
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_MY_BOOL; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+ bool check_update_type(Item_result type) { return 0; }
+};
+
+
+class sys_var_str :public sys_var
+{
+public:
+ char *value; // Pointer to allocated string
+ sys_check_func check_func;
+ sys_update_func update_func;
+ sys_set_default_func set_default_func;
+ sys_var_str(const char *name_arg,
+ sys_check_func check_func_arg,
+ sys_update_func update_func_arg,
+ sys_set_default_func set_default_func_arg)
+ :sys_var(name_arg), check_func(check_func_arg),
+ update_func(update_func_arg),set_default_func(set_default_func_arg)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_func ? (*check_func)(thd, var) : 0;
+ }
+ bool update(THD *thd, set_var *var)
+ {
+ return (*update_func)(thd, var);
+ }
+ void set_default(THD *thd, enum_var_type type)
+ {
+ (*set_default_func)(thd, type);
+ }
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type) { return (byte*) value; }
+ bool check_update_type(Item_result type)
+ {
+ return type != STRING_RESULT; /* Only accept strings */
+ }
+ bool check_default(enum_var_type type) { return 0; }
+};
+
+
+class sys_var_enum :public sys_var
+{
+ uint *value;
+ TYPELIB *enum_names;
+public:
+ sys_var_enum(const char *name_arg, uint *value_arg,
+ TYPELIB *typelib, sys_after_update_func func)
+ :sys_var(name_arg,func), value(value_arg), enum_names(typelib)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, enum_names);
+ }
+ bool update(THD *thd, set_var *var);
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check_update_type(Item_result type) { return 0; }
+};
+
+
+class sys_var_thd :public sys_var
+{
+public:
+ sys_var_thd(const char *name_arg)
+ :sys_var(name_arg)
+ {}
+ sys_var_thd(const char *name_arg, sys_after_update_func func)
+ :sys_var(name_arg,func)
+ {}
+ bool check_type(enum_var_type type) { return 0; }
+ bool check_default(enum_var_type type)
+ {
+ return type == OPT_GLOBAL && !option_limits;
+ }
+};
+
+
+class sys_var_thd_ulong :public sys_var_thd
+{
+public:
+ ulong SV::*offset;
+ sys_var_thd_ulong(const char *name_arg, ulong SV::*offset_arg)
+ :sys_var_thd(name_arg), offset(offset_arg)
+ {}
+ sys_var_thd_ulong(const char *name_arg, ulong SV::*offset_arg,
+ sys_after_update_func func)
+ :sys_var_thd(name_arg,func), offset(offset_arg)
+ {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_thd_ha_rows :public sys_var_thd
+{
+public:
+ ha_rows SV::*offset;
+ sys_var_thd_ha_rows(const char *name_arg, ha_rows SV::*offset_arg)
+ :sys_var_thd(name_arg), offset(offset_arg)
+ {}
+ sys_var_thd_ha_rows(const char *name_arg, ha_rows SV::*offset_arg,
+ sys_after_update_func func)
+ :sys_var_thd(name_arg,func), offset(offset_arg)
+ {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_HA_ROWS; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_thd_ulonglong :public sys_var_thd
+{
+public:
+ ulonglong SV::*offset;
+ bool only_global;
+ sys_var_thd_ulonglong(const char *name_arg, ulonglong SV::*offset_arg)
+ :sys_var_thd(name_arg), offset(offset_arg)
+ {}
+ sys_var_thd_ulonglong(const char *name_arg, ulonglong SV::*offset_arg,
+ sys_after_update_func func, bool only_global_arg)
+ :sys_var_thd(name_arg, func), offset(offset_arg),
+ only_global(only_global_arg)
+ {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check_default(enum_var_type type)
+ {
+ return type == OPT_GLOBAL && !option_limits;
+ }
+ bool check_type(enum_var_type type)
+ {
+ return (only_global && type != OPT_GLOBAL);
+ }
+};
+
+
+class sys_var_thd_bool :public sys_var_thd
+{
+public:
+ my_bool SV::*offset;
+ sys_var_thd_bool(const char *name_arg, my_bool SV::*offset_arg)
+ :sys_var_thd(name_arg), offset(offset_arg)
+ {}
+ sys_var_thd_bool(const char *name_arg, my_bool SV::*offset_arg,
+ sys_after_update_func func)
+ :sys_var_thd(name_arg,func), offset(offset_arg)
+ {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_MY_BOOL; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, &bool_typelib);
+ }
+ bool check_update_type(Item_result type) { return 0; }
+};
+
+
+class sys_var_thd_enum :public sys_var_thd
+{
+ ulong SV::*offset;
+ TYPELIB *enum_names;
+public:
+ sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+ TYPELIB *typelib)
+ :sys_var_thd(name_arg), offset(offset_arg), enum_names(typelib)
+ {}
+ sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+ TYPELIB *typelib,
+ sys_after_update_func func)
+ :sys_var_thd(name_arg,func), offset(offset_arg), enum_names(typelib)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, enum_names);
+ }
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check_update_type(Item_result type) { return 0; }
+};
+
+
+class sys_var_thd_bit :public sys_var_thd
+{
+ sys_update_func update_func;
+public:
+ ulong bit_flag;
+ bool reverse;
+ sys_var_thd_bit(const char *name_arg, sys_update_func func, ulong bit,
+ bool reverse_arg=0)
+ :sys_var_thd(name_arg), update_func(func), bit_flag(bit),
+ reverse(reverse_arg)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_enum(thd, var, &bool_typelib);
+ }
+ bool update(THD *thd, set_var *var);
+ bool check_update_type(Item_result type) { return 0; }
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE type() { return SHOW_MY_BOOL; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+/* some variables that require special handling */
+
+class sys_var_timestamp :public sys_var
+{
+public:
+ sys_var_timestamp(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ bool check_default(enum_var_type type) { return 0; }
+ SHOW_TYPE type() { return SHOW_LONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_last_insert_id :public sys_var
+{
+public:
+ sys_var_last_insert_id(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_insert_id :public sys_var
+{
+public:
+ sys_var_insert_id(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+ SHOW_TYPE type() { return SHOW_LONGLONG; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_slave_skip_counter :public sys_var
+{
+public:
+ sys_var_slave_skip_counter(const char *name_arg) :sys_var(name_arg) {}
+ bool check(THD *thd, set_var *var);
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type != OPT_GLOBAL; }
+ /*
+ We can't retrieve the value of this, so we don't have to define
+ type() or value_ptr()
+ */
+};
+
+
+class sys_var_rand_seed1 :public sys_var
+{
+public:
+ sys_var_rand_seed1(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+};
+
+class sys_var_rand_seed2 :public sys_var
+{
+public:
+ sys_var_rand_seed2(const char *name_arg) :sys_var(name_arg) {}
+ bool update(THD *thd, set_var *var);
+ bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
+};
+
+
+class sys_var_thd_conv_charset :public sys_var_thd
+{
+public:
+ sys_var_thd_conv_charset(const char *name_arg)
+ :sys_var_thd(name_arg)
+ {}
+ bool check(THD *thd, set_var *var);
+ bool update(THD *thd, set_var *var);
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type);
+ bool check_update_type(Item_result type)
+ {
+ return type != STRING_RESULT; /* Only accept strings */
+ }
+ bool check_default(enum_var_type type) { return 0; }
+ void set_default(THD *thd, enum_var_type type);
+};
+
+
+/****************************************************************************
+ Classes for parsing of the SET command
+****************************************************************************/
+
+class set_var_base :public Sql_alloc
+{
+public:
+ set_var_base() {}
+ virtual ~set_var_base() {}
+ virtual int check(THD *thd)=0; /* To check privileges etc. */
+ virtual int update(THD *thd)=0; /* To set the value */
+};
+
+
+/* MySQL internal variables, like query_cache_size */
+
+class set_var :public set_var_base
+{
+public:
+ sys_var *var;
+ Item *value;
+ enum_var_type type;
+ union
+ {
+ CONVERT *convert;
+ ulong ulong_value;
+ } save_result;
+
+ set_var(enum_var_type type_arg, sys_var *var_arg, Item *value_arg)
+ :var(var_arg), type(type_arg)
+ {
+ /*
+ If the set value is a field, change it to a string to allow things like
+ SET table_type=MYISAM;
+ */
+ if (value_arg && value_arg->type() == Item::FIELD_ITEM)
+ {
+ Item_field *item= (Item_field*) value_arg;
+ if (!(value=new Item_string(item->field_name, strlen(item->field_name))))
+ value=value_arg; /* Give error message later */
+ }
+ else
+ value=value_arg;
+ }
+ int check(THD *thd);
+ int update(THD *thd);
+};
+
+
+/* User variables like @my_own_variable */
+
+class set_var_user: public set_var_base
+{
+ Item_func_set_user_var *user_var_item;
+public:
+ set_var_user(Item_func_set_user_var *item)
+ :user_var_item(item)
+ {}
+ int check(THD *thd);
+ int update(THD *thd);
+};
+
+/* For SET PASSWORD */
+
+class set_var_password: public set_var_base
+{
+ LEX_USER *user;
+ char *password;
+public:
+ set_var_password(LEX_USER *user_arg,char *password_arg)
+ :user(user_arg), password(password_arg)
+ {}
+ int check(THD *thd);
+ int update(THD *thd);
+};
+
+
+/*
+ Prototypes for helper functions
+*/
+
+void set_var_init();
+void set_var_free();
+sys_var *find_sys_var(const char *str, uint length=0);
+int sql_set_variables(THD *thd, List<set_var_base> *var_list);
+void fix_delay_key_write(THD *thd, enum_var_type type);
+
+extern sys_var_str sys_charset;
diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am
index b72f7493e20..c70ac9ccf57 100644
--- a/sql/share/Makefile.am
+++ b/sql/share/Makefile.am
@@ -28,5 +28,11 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/charsets/Index $(DESTDIR)$(pkgdatadir)/charsets/Index
$(INSTALL_DATA) $(srcdir)/charsets/*.conf $(DESTDIR)$(pkgdatadir)/charsets
+fix_errors:
+ for lang in @AVAILABLE_LANGUAGES@; \
+ do \
+ ../../extra/comp_err $(srcdir)/$$lang/errmsg.txt $(srcdir)/$$lang/errmsg.sys; \
+ done
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/sql/share/charsets/Index b/sql/share/charsets/Index
index b91e27e7c02..5cf30682cc0 100644
--- a/sql/share/charsets/Index
+++ b/sql/share/charsets/Index
@@ -1,6 +1,7 @@
# sql/share/charsets/Index
#
-# This file lists all of the available character sets.
+# This file lists all of the available character sets. Please keep this
+# file sorted by character set number.
big5 1
@@ -34,3 +35,4 @@ croat 27
gbk 28
cp1257 29
latin5 30
+latin1_de 31
diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt
index 27825baa031..e36475d7803 100644
--- a/sql/share/czech/errmsg.txt
+++ b/sql/share/czech/errmsg.txt
@@ -114,7 +114,7 @@
"Blob polo-B¾ka '%-.64s' nemù¾e mít defaultní hodnotu",
"Nep-Bøípustné jméno databáze '%-.64s'",
"Nep-Bøípustné jméno tabulky '%-.64s'",
-"Zadan-Bý SELECT by procházel pøíli¹ mnoho záznamù a trval velmi dlouho. Zkontrolujte tvar WHERE a je-li SELECT v poøádku, pou¾ijte SET OPTION SQL_BIG_SELECTS=1",
+"Zadan-Bý SELECT by procházel pøíli¹ mnoho záznamù a trval velmi dlouho. Zkontrolujte tvar WHERE a je-li SELECT v poøádku, pou¾ijte SET SQL_BIG_SELECTS=1",
"Nezn-Bámá chyba",
"Nezn-Bámá procedura %s",
"Chybn-Bý poèet parametrù procedury %s",
@@ -156,7 +156,7 @@
"%-.16s p-Bøíkaz nepøístupný pro u¾ivatele: '%-.32s@%-.64s' pro sloupec '%-.64s' v tabulce '%-.64s'",
"Neplatn-Bý pøíkaz GRANT/REVOKE. Prosím, pøeètìte si v manuálu, jaká privilegia je mo¾né pou¾ít.",
"Argument p-Bøíkazu GRANT u¾ivatel nebo stroj je pøíli¹ dlouhý",
-"Tabulka '%-64s.%s' neexistuje",
+"Tabulka '%-.64s.%s' neexistuje",
"Neexistuje odpov-Bídající grant pro u¾ivatele '%-.32s' na stroji '%-.64s' pro tabulku '%-.64s'",
"Pou-B¾itý pøíkaz není v této verzi MySQL povolen",
"Va-B¹e syntaxe je nìjaká divná",
@@ -188,7 +188,7 @@
"Update tabulky bez WHERE s kl-Bíèem není v módu bezpeèných update dovoleno",
"Kl-Bíè '%-.64s' v tabulce '%-.64s' neexistuje",
"Nemohu otev-Bøít tabulku",
-"Handler tabulky nepodporuje check/repair",
+"Handler tabulky nepodporuje %s",
"Proveden-Bí tohoto pøíkazu není v transakci dovoleno",
"Chyba %d p-Bøi COMMIT",
"Chyba %d p-Bøi ROLLBACK",
@@ -211,7 +211,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -228,3 +228,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt
index fcf39f9b3ce..4e612c599ec 100644
--- a/sql/share/danish/errmsg.txt
+++ b/sql/share/danish/errmsg.txt
@@ -108,7 +108,7 @@
"BLOB feltet '%-.64s' kan ikke have en standard værdi",
"Ugyldigt database navn '%-.64s'",
"Ugyldigt tabel navn '%-.64s'",
-"SELECT ville undersøge for mange poster og ville sandsynligvis tage meget lang tid. Undersøg WHERE delen og brug SET OPTION SQL_BIG_SELECTS=1 hvis udtrykket er korrekt",
+"SELECT ville undersøge for mange poster og ville sandsynligvis tage meget lang tid. Undersøg WHERE delen og brug SET SQL_BIG_SELECTS=1 hvis udtrykket er korrekt",
"Ukendt fejl",
"Ukendt procedure %s",
"Forkert antal parametre til proceduren %s",
@@ -182,7 +182,7 @@
"Du bruger sikker opdaterings modus ('safe update mode') og du forsøgte at opdatere en tabel uden en WHERE klausul, der gør brug af et KEY felt",
"Nøglen '%-.64s' eksisterer ikke i tabellen '%-.64s'",
"Kan ikke åbne tabellen",
-"Denne tabeltype understøtter ikke CHECK/REPAIR",
+"Denne tabeltype understøtter ikke %s",
"Du må ikke bruge denne kommando i en transaktion",
"Modtog fejl %d mens kommandoen COMMIT blev udført",
"Modtog fejl %d mens kommandoen ROLLBACK blev udført",
@@ -205,7 +205,7 @@
"Denne handling kunne ikke udføres med kørende slave, brug først kommandoen SLAVE STOP",
"Denne handling kræver en kørende slave. Konfigurer en slave og brug kommandoen SLAVE START",
"Denne server er ikke konfigureret som slave. Ret in config-filen eller brug kommandoen CHANGE MASTER TO",
-"Kunne ikke initialisere master info-struktur. Check om rettigheder i master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Kunne ikke danne en slave-tråd. Check systemressourcerne",
"Brugeren %-.64s har allerede mere end 'max_user_connections' aktive forbindelser",
"Du må kun bruge konstantudtryk med SET",
@@ -222,3 +222,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt
index 79768450cae..4aafa51e856 100644
--- a/sql/share/dutch/errmsg.txt
+++ b/sql/share/dutch/errmsg.txt
@@ -2,9 +2,14 @@
This file is public domain and comes with NO WARRANTY of any kind
Dutch error messages (share/dutch/errmsg.txt)
- Arjen G. Lentz (agl@bitbike.com)
+ 2001-08-02 - Arjen Lentz (agl@bitbike.com)
Completed earlier partial translation; worked on consistency and spelling.
- Version: 02-08-2001
+ 2002-01-29 - Arjen Lentz (arjen@mysql.com)
+ 2002-04-11 - Arjen Lentz (arjen@mysql.com)
+ 2002-06-13 - Arjen Lentz (arjen@mysql.com)
+ 2002-08-08 - Arjen Lentz (arjen@mysql.com)
+ 2002-08-22 - Arjen Lentz (arjen@mysql.com)
+ Translated new error messages.
*/
"hashchk",
@@ -16,9 +21,9 @@
"Kan database '%-.64s' niet aanmaken (Errcode: %d)",
"Kan database '%-.64s' niet aanmaken. Database bestaat reeds",
"Kan database '%-.64s' niet verwijderen. Database bestaat niet",
-"Error verwijderen database (kan '%-.64s' niet verwijderen, Errcode: %d)",
-"Error verwijderen database (kan rmdir '%-.64s' niet uitvoeren, Errcode: %d)",
-"Error bij het verwijderen van '%-.64s' (Errcode: %d)",
+"Fout bij verwijderen database (kan '%-.64s' niet verwijderen, Errcode: %d)",
+"Fout bij verwijderen database (kan rmdir '%-.64s' niet uitvoeren, Errcode: %d)",
+"Fout bij het verwijderen van '%-.64s' (Errcode: %d)",
"Kan record niet lezen in de systeem tabel",
"Kan de status niet krijgen van '%-.64s' (Errcode: %d)",
"Kan de werkdirectory niet krijgen (Errcode: %d)",
@@ -111,7 +116,7 @@
"Blob veld '%-.64s' can geen standaardwaarde bevatten",
"Databasenaam '%-.64s' is niet getoegestaan",
"Niet toegestane tabelnaam '%-.64s'",
-"Het SELECT-statement zou te veel records analyseren en dus veel tijd in beslagnemen. Kijk het WHERE-gedeelte van de query na en kies SET OPTION SQL_BIG_SELECTS=1 als het stament in orde is.",
+"Het SELECT-statement zou te veel records analyseren en dus veel tijd in beslagnemen. Kijk het WHERE-gedeelte van de query na en kies SET SQL_BIG_SELECTS=1 als het stament in orde is.",
"Onbekende Fout",
"Onbekende procedure %s",
"Foutief aantal parameters doorgegeven aan procedure %s",
@@ -153,7 +158,7 @@
"%-.16s commando geweigerd voor gebruiker: '%-.32s@%-.64s' voor kolom '%-.64s' in tabel '%-.64s'",
"Foutief GRANT/REVOKE commando. Raadpleeg de handleiding welke priveleges gebruikt kunnen worden.",
"De host of gebruiker parameter voor GRANT is te lang",
-"Tabel '%-64s.%s' bestaat niet",
+"Tabel '%-.64s.%s' bestaat niet",
"Deze toegang (GRANT) is niet toegekend voor gebruiker '%-.32s' op host '%-.64s' op tabel '%-.64s'",
"Het used commando is niet toegestaan in deze MySQL versie",
"Er is iets fout in de gebruikte syntax",
@@ -167,8 +172,8 @@
"Communicatiepakket kon niet worden gedecomprimeerd",
"Fout bij het lezen van communicatiepakketten",
"Timeout bij het lezen van communicatiepakketten",
-"Got an error writing communication packets",
-"Got timeout writing communication packets",
+"Fout bij het schrijven van communicatiepakketten",
+"Timeout bij het schrijven van communicatiepakketten",
"Resultaat string is langer dan max_allowed_packet",
"Het gebruikte tabel type ondersteunt geen BLOB/TEXT kolommen",
"Het gebruikte tabel type ondersteunt geen AUTO_INCREMENT kolommen",
@@ -185,7 +190,7 @@
"U gebruikt 'safe update mode' en u probeerde een tabel te updaten zonder een WHERE met een KEY kolom",
"Zoeksleutel '%-.64s' bestaat niet in tabel '%-.64s'",
"Kan tabel niet openen",
-"De 'handler' voor de tabel ondersteund geen check/repair",
+"De 'handler' voor de tabel ondersteund geen %s",
"Het is u niet toegestaan dit commando uit te voeren binnen een transactie",
"Kreeg fout %d tijdens COMMIT",
"Kreeg fout %d tijdens ROLLBACK",
@@ -208,7 +213,7 @@
"Deze operatie kan niet worden uitgevoerd met een actieve slave, doe eerst SLAVE STOP",
"Deze operatie vereist een actieve slave, configureer slave en doe dan SLAVE START",
"De server is niet geconfigureerd als slave, fix in configuratie bestand of met CHANGE MASTER TO",
-"Kon master info structuur niet initialiseren, controleer permissies in master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Kon slave thread niet aanmaken, controleer systeem resources",
"Gebruiker %-.64s heeft reeds meer dan 'max_user_connections' actieve verbindingen",
"U mag alleen constante expressies gebruiken bij SET",
@@ -218,10 +223,31 @@
"DROP DATABASE niet toegestaan terwijl thread een globale 'read lock' bezit",
"CREATE DATABASE niet toegestaan terwijl thread een globale 'read lock' bezit",
"Foutieve parameters voor %s",
-"%-.32s@%-.64s is not allowed to create new users",
-"Incorrect table definition; All MERGE tables must be in the same database",
-"Deadlock found when trying to get lock; Try restarting transaction",
-"The used table type doesn't support FULLTEXT indexes",
-"Cannot add foreign key constraint",
-"Cannot add a child row: a foreign key constraint fails",
-"Cannot delete a parent row: a foreign key constraint fails",
+"%-.32s@%-.64s mag geen nieuwe gebruikers creeren",
+"Incorrecte tabel definitie; Alle MERGE tabellen moeten tot dezelfde database behoren",
+"Deadlock gevonden tijdens lock-aanvraag poging; Probeer herstart van de transactie",
+"Het gebruikte tabel type ondersteund geen FULLTEXT indexen",
+"Kan foreign key beperking niet toevoegen",
+"Kan onderliggende rij niet toevoegen: foreign key beperking gefaald",
+"Kan bovenliggende rij nite verwijderen: foreign key beperking gefaald",
+"Fout bij opbouwen verbinding naar master: %-.128s",
+"Fout bij uitvoeren query op master: %-.128s",
+"Fout tijdens uitvoeren van commando %s: %-.128s",
+"Foutief gebruik van %s en %s",
+"De gebruikte SELECT commando's hebben een verschillend aantal kolommen",
+"Kan de query niet uitvoeren vanwege een conflicterende read lock",
+"Het combineren van transactionele en niet-transactionele tabellen is uitgeschakeld.",
+"Optie '%s' tweemaal gebruikt in opdracht",
+"Gebruiker '%-.64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)",
+"Toegang geweigerd. U moet het %-.128s privilege hebben voor deze operatie",
+"Variabele '%-.64s' is LOCAL en kan niet worden gebruikt met SET GLOBAL",
+"Variabele '%-.64s' is GLOBAL en dient te worden gewijzigd met SET GLOBAL",
+"Variabele '%-.64s' heeft geen standaard waarde",
+"Variabele '%-.64s' kan niet worden gewijzigd naar de waarde '%-.64s'",
+"Foutief argumenttype voor variabele '%-.64s'",
+"Variabele '%-.64s' kan alleen worden gewijzigd, niet gelezen",
+"Foutieve toepassing/plaatsing van '%s'",
+"Deze versie van MySQL ondersteunt nog geen '%s'",
+"Kreeg fatale fout %d: '%-.128s' van master tijdens lezen van data uit binaire log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt
index b30ac87b5b6..7104eb64d56 100644
--- a/sql/share/english/errmsg.txt
+++ b/sql/share/english/errmsg.txt
@@ -77,7 +77,7 @@
"BLOB column '%-.64s' can't be used in key specification with the used table type",
"Too big column length for column '%-.64s' (max = %d). Use BLOB instead",
"Incorrect table definition; There can only be one auto column and it must be defined as a key",
-"%s: ready for connections\n",
+"%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d\n",
"%s: Normal shutdown\n",
"%s: Got signal %d. Aborting!\n",
"%s: Shutdown Complete\n",
@@ -105,7 +105,7 @@
"BLOB column '%-.64s' can't have a default value",
"Incorrect database name '%-.100s'",
"Incorrect table name '%-.100s'",
-"The SELECT would examine too many records and probably take a very long time. Check your WHERE and use SET OPTION SQL_BIG_SELECTS=1 if the SELECT is ok",
+"The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok",
"Unknown error",
"Unknown procedure '%-.64s'",
"Incorrect parameter count to procedure '%-.64s'",
@@ -119,7 +119,7 @@
"Unknown character set: '%-.64s'",
"Too many tables. MySQL can only use %d tables in a join",
"Too many columns",
-"Too big row size. The maximum row size, not counting BLOBs, is %d. You have to change some fields to BLOBs",
+"Too big row size. The maximum row size, not counting BLOBs, is %d (can be lower for some table types). You have to change some fields to BLOBs",
"Thread stack overrun: Used: %ld of a %ld stack. Use 'mysqld -O thread_stack=#' to specify a bigger stack if needed",
"Cross dependency found in OUTER JOIN. Examine your ON conditions",
"Column '%-.64s' is used with UNIQUE or INDEX but is not defined as NOT NULL",
@@ -150,7 +150,7 @@
"Table '%-.64s.%-.64s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
-"You have an error in your SQL syntax",
+"You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use",
"Delayed insert thread couldn't get requested lock for table %-.64s",
"Too many delayed threads in use",
"Aborted connection %ld to db: '%-.64s' user: '%-.32s' (%-.64s)",
@@ -179,7 +179,7 @@
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
"Key '%-.64s' doesn't exist in table '%-.64s'",
"Can't open table",
-"The handler for the table doesn't support check/repair",
+"The handler for the table doesn't support %s",
"You are not allowed to execute this command in a transaction",
"Got error %d during COMMIT",
"Got error %d during ROLLBACK",
@@ -202,7 +202,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -217,5 +217,26 @@
"Deadlock found when trying to get lock; Try restarting transaction",
"The used table type doesn't support FULLTEXT indexes",
"Cannot add foreign key constraint",
-"Cannot add a child row: a foreign key constraint fails",
-"Cannot delete a parent row: a foreign key constraint fails",
+"Cannot add or update a child row: a foreign key constraint fails",
+"Cannot delete or update a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt
index 88cded9e19b..f583568193f 100644
--- a/sql/share/estonian/errmsg.txt
+++ b/sql/share/estonian/errmsg.txt
@@ -1,225 +1,247 @@
-/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB
- This file is public domain and comes with NO WARRANTY of any kind
+/*
+ Copyright Abandoned 1997 MySQL AB
+ This file is public domain and comes with NO WARRANTY of any kind
+ Esialgne tõlge: Tõnu Samuel (tonu@spam.ee)
+ Parandanud ja täiendanud: Indrek Siitan (tfr@mysql.com)
- Translated into estonian language by Tonu Samuel
- email: tonu@spam.ee
*/
"hashchk",
"isamchk",
"EI",
"JAH",
-"Ei saa luua tabelit '%-.64s' (vea kood: %d)",
-"Ei saa luua tabelit '%-.64s' (vea kood: %d)",
-"Ei saa luua andmebaasi '%-.64s'. (vea kood: %d)",
-"Ei saa luua andmebaasi '%-.64s'. Andmebaas on juba olemas",
-"Ei saa kustutada andmebaasi '%-.64s'. Andmebaasi ei eksisteeri",
-"Ei saa kustutada andmebaasi (Ei saa kustutada faili '%-.64s', vea kood: %d)",
-"Ei saa kustutada andmebaasi (Ei saa kustutada kataloogi '%-.64s', vea kood: %d)",
-"Viga '%-.64s' kustutamisel (vea kood: %d)",
-"Ei saa lugeda kirjet in süsteemsest tabelist",
-"Ei saa lugeda '%-.64s' olekut (vea kood: %d)",
-"Ei saa teada jooksva kataloogi nime (vea kood: %d)",
-"Ei saa avada lukustusfaili (vea kood: %d)",
-"Ei saa avada faili: '%-.64s'. (vea kood: %d)",
-"Ei leia faili: '%-.64s' (vea kood: %d)",
-"Ei saa lugeda kataloogi '%-.64s' (vea kood: %d)",
-"Ei saa siseneda kataloogi '%-.64s' (vea kood: %d)",
-"Kirje on muutunud võrreldes eelmise lugemisega tabelis '%-.64s'",
-"Ketas on täis (%s). Ootame kuni tekib vaba ruumi....",
-"Ei saa kirjutada, Korduv võti tabelis '%-.64s'",
-"Viga faili '%-.64s' sulgemisel (vea kood: %d)",
-"Viga faili '%-.64s' lugemisel (vea kood: %d)",
-"Viga faili '%-.64s' ringi nimetamisel '%-.64s'-ks (vea kood: %d)",
-"Viga faili '%-.64s' kirjutamisel (vea kood: %d)",
+"Ei suuda luua faili '%-.64s' (veakood: %d)",
+"Ei suuda luua tabelit '%-.64s' (veakood: %d)",
+"Ei suuda luua andmebaasi '%-.64s'. (veakood: %d)",
+"Ei suuda luua andmebaasi '%-.64s': andmebaas juba eksisteerib",
+"Ei suuda kustutada andmebaasi '%-.64s': andmebaasi ei eksisteeri",
+"Viga andmebaasi kustutamisel (ei suuda kustutada faili '%-.64s', veakood: %d)",
+"Viga andmebaasi kustutamisel (ei suuda kustutada kataloogi '%-.64s', veakood: %d)",
+"Viga '%-.64s' kustutamisel (veakood: %d)",
+"Ei suuda lugeda kirjet süsteemsest tabelist",
+"Ei suuda lugeda '%-.64s' olekut (veakood: %d)",
+"Ei suuda identifitseerida jooksvat kataloogi (veakood: %d)",
+"Ei suuda lukustada faili (veakood: %d)",
+"Ei suuda avada faili '%-.64s'. (veakood: %d)",
+"Ei suuda leida faili '%-.64s' (veakood: %d)",
+"Ei suuda lugeda kataloogi '%-.64s' (veakood: %d)",
+"Ei suuda siseneda kataloogi '%-.64s' (veakood: %d)",
+"Kirje tabelis '%-.64s' on muutunud viimasest lugemisest saadik",
+"Ketas täis (%s). Ootame kuni tekib vaba ruumi...",
+"Ei saa kirjutada, korduv võti tabelis '%-.64s'",
+"Viga faili '%-.64s' sulgemisel (veakood: %d)",
+"Viga faili '%-.64s' lugemisel (veakood: %d)",
+"Viga faili '%-.64s' ümbernimetamisel '%-.64s'-ks (veakood: %d)",
+"Viga faili '%-.64s' kirjutamisel (veakood: %d)",
"'%-.64s' on lukustatud muudatuste vastu",
"Sorteerimine katkestatud",
-"Vaade '%-.64s' puudub '%-.64s' jaoks",
-"Viga %d tabelitöötluses",
-"Table handler for '%-.64s' doesn't have this option",
+"Vaade '%-.64s' ei eksisteeri '%-.64s' jaoks",
+"Tabeli handler tagastas vea %d",
+"Tabeli '%-.64s' handler ei toeta antud operatsiooni",
"Ei suuda leida kirjet '%-.64s'-s",
-"Väär informatsiion failis '%-.64s'",
-"Vigastatud võtmefail tabelile '%-.64s'",
-"Vana võtmefail tabelile '%-.64s'. Proovi teda parandada",
-"Tabel '%-.64s' on ainult lugemise õigusega",
-"Mälu sai otsa. Proovi MySQL uuesti käivitada (Puudu jäi %d baiti)",
-"Mälu sai sorteerimie ajal otsa. Suurenda MySQL-i sorteerimispuhvrit",
-"Ootamatu faili lõpp leitud faili '%-.64s' lugemisel (vea kood: %d)",
+"Vigane informatsioon failis '%-.64s'",
+"Tabeli '%-.64s' võtmefail on vigane; Proovi seda parandada",
+"Tabeli '%-.64s' võtmefail on aegunud; Paranda see!",
+"Tabel '%-.64s' on ainult lugemiseks",
+"Mälu sai otsa. Proovi MySQL uuesti käivitada (puudu jäi %d baiti)",
+"Mälu sai sorteerimisel otsa. Suurenda MySQL-i sorteerimispuhvrit",
+"Ootamatu faililõpumärgend faili '%-.64s' lugemisel (veakood: %d)",
"Liiga palju samaaegseid ühendusi",
-"Mälu sai otsa. Võimalik, et aitab swap-i lisamine või käsu 'ulimit' abil MySQL-le rohkema mälu kasutamise lubamine.",
+"Mälu sai otsa. Võimalik, et aitab swap-i lisamine või käsu 'ulimit' abil MySQL-le rohkema mälu kasutamise lubamine",
"Ei suuda lahendada IP aadressi masina nimeks",
"Väär handshake",
-"Ligipääs piiratud kasutajale: '%-.32s@%-.64s' andmebaasi '%-.64s'",
-"Ligipääs piiratud kasutajale: '%-.32s@%-.64s' (Kasutab parooli: %s)",
-"Andmebaas pole valitud",
+"Ligipääs keelatud kasutajale '%-.32s@%-.64s' andmebaasile '%-.64s'",
+"Ligipääs keelatud kasutajale '%-.32s@%-.64s' (kasutab parooli: %s)",
+"Andmebaasi ei ole valitud",
"Tundmatu käsk",
-"Tulp '%-.64s' ei saa olla null",
+"Tulp '%-.64s' ei saa omada nullväärtust",
"Tundmatu andmebaas '%-.64s'",
-"Tabel '%-.64s' on juba olemas",
+"Tabel '%-.64s' juba eksisteerib",
"Tundmatu tabel '%-.64s'",
-"Tulp: '%-.64s' in %-.64s on väär",
+"Väli '%-.64s' %-.64s-s ei ole ühene",
"Serveri seiskamine käib",
-"Tundmatu tulp '%-.64s' in '%-.64s'",
-"'%-.64s' puudub GROUP BY-s",
+"Tundmatu tulp '%-.64s' '%-.64s'-s",
+"'%-.64s' puudub GROUP BY klauslis",
"Ei saa grupeerida '%-.64s' järgi",
-"Lauses on korraga nii tulbad kui summad",
-"Tuplade arv tabelis erineb antud väärtuste arvust",
+"Lauses on korraga nii tulbad kui summeerimisfunktsioonid",
+"Tulpade arv erineb väärtuste arvust",
"Identifikaatori '%-.100s' nimi on liiga pikk",
"Kattuv tulba nimi '%-.64s'",
"Kattuv võtme nimi '%-.64s'",
-"Kattuv nimi '%-.64s' võtmele %d",
-"Väär tulba kirjeldus tulbale '%-.64s'",
-"%s '%-.80s' ligidal reas %d",
+"Kattuv väärtus '%-.64s' võtmele %d",
+"Vigane tulba kirjeldus tulbale '%-.64s'",
+"%s '%-.80s' ligidal real %d",
"Tühi päring",
-"Pole unikaalne tabel/alias '%-.64s'",
-"Vale vaikeväärtus '%-.64s'",
-"Mitut põhivõtit (PRIMARY KEY) ei saa olla",
-"Liiga palju võtmeid määratletud. Maksimaalselt võib olla %d võtit",
+"Ei ole unikaalne tabel/alias '%-.64s'",
+"Vigane vaikeväärtus '%-.64s' jaoks",
+"Mitut primaarset võtit ei saa olla",
+"Liiga palju võtmeid. Maksimaalselt võib olla %d võtit",
"Võti koosneb liiga paljudest osadest. Maksimaalselt võib olla %d osa",
-"Määratletud võti sai liiga pikk. Maksimaalne lubatud pikkus on %d",
-"Võtme tulp '%-.64s' puudub antud tabelis",
-"BLOB tulpa '%-.64s' ei saa kasutada võtmena",
-"Tulba '%-.64s' pikkus on liiga pikk (maksimaalne = %d).",
-"Tabeli kohta saab olla ainult üks auto_increment tulp ja see peab olema samas ka võtmena",
+"Võti on liiga pikk. Maksimaalne võtmepikkus on %d",
+"Võtme tulp '%-.64s' puudub tabelis",
+"BLOB-tüüpi tulpa '%-.64s' ei saa kasutada võtmena",
+"Tulba '%-.64s' pikkus on liiga pikk (maksimaalne pikkus: %d). Kasuta BLOB väljatüüpi",
+"Vigane tabelikirjeldus; Tabelis tohib olla üks auto_increment tüüpi tulp ning see peab olema defineeritud võtmena",
"%s: ootab ühendusi\n",
"%s: MySQL lõpetas\n",
-"%s: Sain signaali %d. Lõpetan!\n",
+"%s: sain signaali %d. Lõpetan!\n",
"%s: Lõpp\n",
-"%s: Sulgen jõuga threadi %ld kasutaja: '%-.64s'\n",
-"Ei saa luua IP pesa",
+"%s: Sulgen jõuga lõime %ld kasutaja: '%-.32s'\n",
+"Ei suuda luua IP socketit",
"Tabelil '%-.64s' puuduvad võtmed. Loo tabel uuesti",
-"Väljade eraldaja on väär. Vaata kasutamisjuhendisse",
-"BLOB väljadega ei saa kasutada fikseeritud väljapikkust. Seetõttu on vajalik lisaklausel 'fields terminated by'.",
-"Fail '%-.64s' peab asuma andmebaasi kataloogis ning olema loetav",
-"Fail '%-.64s' on juba olemas",
-"Kirjed: %ld Kustutatud: %ld Vahele jäetud: %ld Hoiatusi: %ld",
-"Kirjed: %ld Topelt: %ld",
-"Väär võtme osa. Kasutatud võtme osa ei ole string või on pikkus pikem kui võtme osa",
-"ALTER TABLE abil ei saa koiki tulpasid kustutada. DROP TABLE kustutab terve tabeli",
-"Ei saa kustutada '%-.64s'. On selline tulp või võti üldse olemas?",
-"Kirjed: %ld Topelt: %ld Hoiatusi: %ld",
-"INSERT TABLE '%-.64s' pole lubatud FROM tabelite nimekirjas",
-"Tundmatu threadi id: %lu",
-"Pole threadi %lu omanik",
-"Pole kasutatud tabeleid",
-"Liiga palju stringe tulbale %-.64s ja tüübile SET",
-"Ei saa luua ainulaadset failinime %-.64s.(1-999)\n",
-"Tabel '%-.64s' on lukustatud ainult lugemiseks ja sinna kirjutada ei saa",
-"Tabel '%-.64s' pole lukustatud käsuga LOCK TABLES",
-"BLOB tüüpi tulbal '%-.64s' ei saa olla vaikeväärtust",
-"Väär andmebaasi nimi '%-.100s'",
-"Väär tabeli nimi '%-.100s'",
-"SELECT lause peab läbi vaatama suure hulga kirjeid ja võtaks tõenäoliselt liiga kaua aega. Tasub kontrollide WHERE klauslit ja vajadusel kasutada käsku SET OPTION SQL_BIG_SELECTS=1",
+"Väljade eraldaja erineb oodatust. Tutvu kasutajajuhendiga",
+"BLOB-tüüpi väljade olemasolul ei saa kasutada fikseeritud väljapikkust. Vajalik 'fields terminated by' määrang.",
+"Fail '%-.64s' peab asuma andmebaasi kataloogis või olema kõigile loetav",
+"Fail '%-.80s' juba eksisteerib",
+"Kirjeid: %ld Kustutatud: %ld Vahele jäetud: %ld Hoiatusi: %ld",
+"Kirjeid: %ld Kattuvaid: %ld",
+"Vigane võtme osa. Kasutatud võtmeosa ei ole string tüüpi, määratud pikkus on pikem kui võtmeosa või tabelihandler ei toeta seda tüüpi võtmeid",
+"ALTER TABLE kasutades ei saa kustutada kõiki tulpasid. Kustuta tabel DROP TABLE abil",
+"Ei suuda kustutada '%-.64s'. Kontrolli kas tulp/võti eksisteerib",
+"Kirjeid: %ld Kattuvaid: %ld Hoiatusi: %ld",
+"INSERT TABLE '%-.64s' ei ole lubatud FROM tabelite nimekirjas",
+"Tundmatu lõim: %lu",
+"Ei ole lõime %lu omanik",
+"Ühtegi tabelit pole kasutusel",
+"Liiga palju string tulbale %-.64s tüübile SET",
+"Ei suuda luua unikaalset logifaili nime %-.64s.(1-999)\n",
+"Tabel '%-.64s' on lukustatud READ lukuga ning ei ole muudetav",
+"Tabel '%-.64s' ei ole lukustatud käsuga LOCK TABLES",
+"BLOB-tüüpi tulp '%-.64s' ei saa omada vaikeväärtust",
+"Vigane andmebaasi nimi '%-.100s'",
+"Vigane tabeli nimi '%-.100s'",
+"SELECT lause peab läbi vaatama suure hulga kirjeid ja võtaks tõenäoliselt liiga kaua aega. Tasub kontrollida WHERE klauslit ja vajadusel kasutada käsku SET SQL_BIG_SELECTS=1",
"Tundmatu viga",
"Tundmatu protseduur '%-.64s'",
-"Väär parameetrite hulk protseduurile '%-.64s'",
-"Valed parameetrid protseduurile '%-.64s'",
-"Tundmatu tabel '%-.64s' %s-s",
+"Vale parameetrite hulk protseduurile '%-.64s'",
+"Vigased parameetrid protseduurile '%-.64s'",
+"Tundmatu tabel '%-.64s' %-.32s-s",
"Tulp '%-.64s' on määratletud topelt",
-"GROUP BY funktsiooni väärkasutamine",
-"Tabel '%-.64s' kasutab laiendit, mis on tundmatu sellele MySQL versioonile",
-"Tabelil peab olema vähemalt üks tulp",
+"Vigane grupeerimisfunktsiooni kasutus",
+"Tabel '%-.64s' kasutab laiendust, mis ei eksisteeri antud MySQL versioonis",
+"Tabelis peab olema vähemalt üks tulp",
"Tabel '%-.64s' on täis",
-"Tundmatu kooditabel: '%-.64s'",
-"Liiga palju tabeleid. MySQL oskab kasutada kuni %d tabelit JOINi puhul",
+"Vigane kooditabel '%-.64s'",
+"Liiga palju tabeleid. MySQL suudab JOINiga ühendada kuni %d tabelit",
"Liiga palju tulpasid",
-"Liiga pikk kirje. Maksimaalne kirje pikkus arvestamata BLOB tüüpi on %d. Võib-olla aitab mõnede väljade muutmine BLOB tüübiks",
-"Threadi stack overrun: Used: %ld of a %ld stack. Use 'mysqld -O thlugeda_stack=#' to specify a bigger stack if needed",
-"Ristsõltuvus OUTER JOIN-s. ON tingimused tuleks üle kontrollida",
-"Tulp '%-.64s' on kasutused indeksis kui pole defineeritud tüübiga NOT NULL",
-"Ei saa avada funktsiooni '%-.64s'",
-"Ei saa algväärtustada funktsiooni '%-.64s'; %-.80s",
+"Liiga pikk kirje. Kirje maksimumpikkus arvestamata BLOB-tüüpi välju on %d. Muuda mõned väljad BLOB-tüüpi väljadeks",
+"Thread stack overrun: Used: %ld of a %ld stack. Use 'mysqld -O thread_stack=#' to specify a bigger stack if needed",
+"Ristsõltuvus OUTER JOIN klauslis. Kontrolli oma ON tingimusi",
+"Tulp '%-.64s' on kasutusel indeksina, kuid ei ole määratletud kui NOT NULL",
+"Ei suuda avada funktsiooni '%-.64s'",
+"Ei suuda algväärtustada funktsiooni '%-.64s'; %-.80s",
"Teegi nimes ei tohi olla kataloogi",
-"Funktsioon '%-.64s' on juba olemas",
-"Ei saa avada teeki '%-.64s' (vea kood: %d %s)",
-"Ei leia funktsiooni '%-.64s' selles teegis'",
-"Funktsiooni '%-.64s' pole defineeritud",
-"Masin '%-.64s' blokeeritud hulgaliste ühendusvigade pärast. Blokeeringu saab eemaldada käsuga 'mysqladmin flush-hosts'",
-"Masinale '%-.64s' pole lubatud ligipääsu sellele MySQL serverile",
+"Funktsioon '%-.64s' juba eksisteerib",
+"Ei suuda avada jagatud teeki '%-.64s' (veakood: %d %-.64s)",
+"Ei leia funktsiooni '%-.64s' antud teegis",
+"Funktsioon '%-.64s' ei ole defineeritud",
+"Masin '%-.64s' on blokeeritud hulgaliste ühendusvigade tõttu. Blokeeringu saab tühistada 'mysqladmin flush-hosts' käsuga",
+"Masinal '%-.64s' puudub ligipääs sellele MySQL serverile",
"Te kasutate MySQL-i anonüümse kasutajana, kelledel pole parooli muutmise õigust",
-"Teil peab olema tabelite muutmise õigus muutmaks teiste paroole",
-"Ei leia kirjet kasutajate tabelis",
-"Sobinud kirjed: %ld Muudetud: %ld Hoiatusi: %ld",
-"Ei saa luua threadi (vea kood %d). Kui mälu pole otsas, tasub operatsioonisüsteemi spetsiifilist viga",
-"Tulpade arv ei vasta väärtuste hulgale reas %ld",
-"Ei saa avada tabelit: '%-.64s",
+"Teiste paroolide muutmiseks on nõutav tabelite muutmisõigus 'mysql' andmebaasis",
+"Ei leia vastavat kirjet kasutajate tabelis",
+"Sobinud kirjeid: %ld Muudetud: %ld Hoiatusi: %ld",
+"Ei suuda luua uut lõime (veakood %d). Kui mälu ei ole otsas, on tõenäoliselt tegemist operatsioonisüsteemispetsiifilise veaga",
+"Tulpade hulk erineb väärtuste hulgast real %ld",
+"Ei suuda taasavada tabelit '%-.64s'",
"NULL väärtuse väärkasutus",
-"Viga '%-.64s' regexp-i käest",
-"GROUP tulpade segamine (MIN(),MAX(),COUNT()...) on väär kui ei kasutata GROUP BY klauslit",
-"Sellist õigust ei ole kasutajale '%-.32s' masinast '%-.64s'",
-"%-.16s käsk pole lubatud kasutajale '%-.32s@%-.64s' tabelile '%-.64s'",
-"%-.16s käsk pole lubatud kasutajale '%-.32s@%-.64s' tulbale '%-.64s' tabelis '%-.64s'",
-"Väär GRANT/REVOKE kasutus",
-"Masina või kasutaja nimi on liiga pikk GRANT lauses",
-"Tabelit '%-64s.%s' ei leitud",
-"Sellist õigust pole kasutajale '%-.32s' masinast '%-.64s' tabelile '%-.64s'",
-"Antud käsk pole lubatud selle MySQL-i versiooniga",
+"regexp tagastas vea '%-.64s'",
+"GROUP tulpade (MIN(),MAX(),COUNT()...) kooskasutamine tavaliste tulpadega ilma GROUP BY klauslita ei ole lubatud",
+"Sellist õigust ei ole defineeritud kasutajale '%-.32s' masinast '%-.64s'",
+"%-.16s käsk ei ole lubatud kasutajale '%-.32s@%-.64s' tabelis '%-.64s'",
+"%-.16s käsk ei ole lubatud kasutajale '%-.32s@%-.64s' tulbale '%-.64s' tabelis '%-.64s'",
+"Vigane GRANT/REVOKE käsk. Tutvu kasutajajuhendiga",
+"Masina või kasutaja nimi GRANT lauses on liiga pikk",
+"Tabelit '%-.64s.%-.64s' ei eksisteeri",
+"Sellist õigust ei ole defineeritud kasutajale '%-.32s' masinast '%-.64s' tabelile '%-.64s'",
+"Antud käsk ei ole lubatud käesolevas MySQL versioonis",
"Viga SQL süntaksis",
-"INSERT DELAYED thread ei saanud nõutavat lukku tabelile %-.64s",
-"Liiga palju DELAYED threade on kasutusel",
-"Ühendus katkestatud %ld andmebaasile '%-.64s' kasutaja '%-.64s' (%s)",
-"Sain lubatust suurema paketi (max_allowed_packet)",
-"Got a read error from the connection pipe",
-"Got an error from fcntl()",
-"Got packets out of order",
-"Ei suuda ühendust lahti pakkida",
-"Viga ühenduse lugemisel",
-"Aeg sai otsa ühenduse lugemisel",
-"Viga ühenduse kirjutamisel",
-"Aeg sai otsa ühenduse kirjutamisel",
-"Tulemuseks saadud string on pikem kui max_allowed_packet väärtus",
-"Kasutatud tabeli tüüp ei toeta BLOB/TEXT tulpasid",
-"Kasutatud tabeli tüüp ei toeta AUTO_INCREMENT tulpasid",
-"INSERT DELAYED käsku ei saa kasutada tabeliga '%-.64s', kuna see on lukus käsuga LOCK TABLES",
-"Väär tulba nimi '%-.100s'",
-"Kasutusel olev tabelite haldur ei oska indekseerida tulpa '%-.64s'",
-"All tables in the MERGE table are not identically defined",
-"Can't write, because of unique constraint, to table '%-.64s'",
-"BLOB column '%-.64s' used in key specification without a key length",
-"All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead",
-"Tulemis on rohkem kui üks kirje",
-"This table type requires a primary key",
-"Antud MySQL ei ole kompileeritud RAID-i toega",
-"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
-"Key '%-.64s' doesn't exist in table '%-.64s'",
-"Ei suuda tabelit avada",
-"See tabelitüüp ei toeta käske CHECK/REPAIR",
-"Puudub õigus selle transaktsioonikäsu andmiseks",
-"Sain vea %d COMMIT käsu täitmisel",
-"Sain vea %d ROLLBACK käsu täitmisel",
-"Sain vea %d FLUSH_LOGS käsu täitmisel",
-"Sain vea %d CHECKPOINT käsu täitmisel",
-"Ühendus %ld katkestatud andmebaas: '%-.64s' kasutaja: '%-.32s' masin: `%-.64s' (%-.64s)",
+"INSERT DELAYED lõim ei suutnud saada soovitud lukku tabelile %-.64s",
+"Liiga palju DELAYED lõimesid kasutusel",
+"Ühendus katkestatud %ld andmebaasile: '%-.64s' kasutajale: '%-.32s' (%-.64s)",
+"Saabus suurem pakett kui lubatud 'max_allowed_packet' muutujaga",
+"Viga ühendustoru lugemisel",
+"fcntl() tagastas vea",
+"Paketid saabusid vales järjekorras",
+"Viga andmepaketi lahtipakkimisel",
+"Viga andmepaketi lugemisel",
+"Kontrollaja ületamine andmepakettide lugemisel",
+"Viga andmepaketi kirjutamisel",
+"Kontrollaja ületamine andmepakettide kirjutamisel",
+"Tulemus on pikem kui lubatud 'max_allowed_packet' muutujaga",
+"Valitud tabelitüüp ei toeta BLOB/TEXT tüüpi välju",
+"Valitud tabelitüüp ei toeta AUTO_INCREMENT tüüpi välju",
+"INSERT DELAYED ei saa kasutada tabeli '%-.64s' peal, kuna see on lukustatud LOCK TABLES käsuga",
+"Vigane tulba nimi '%-.100s'",
+"Tabelihandler ei oska indekseerida tulpa '%-.64s'",
+"Kõik tabelid MERGE tabeli määratluses ei ole identsed",
+"Ei suuda kirjutada tabelisse '%-.64s', kuna see rikub ühesuse kitsendust",
+"BLOB-tüüpi tulp '%-.64s' on kasutusel võtmes ilma pikkust määratlemata",
+"Kõik PRIMARY KEY peavad olema määratletud NOT NULL piiranguga; vajadusel kasuta UNIQUE tüüpi võtit",
+"Tulemis oli rohkem kui üks kirje",
+"Antud tabelitüüp nõuab primaarset võtit",
+"Antud MySQL versioon on kompileeritud ilma RAID toeta",
+"Katse muuta tabelit turvalises rezhiimis ilma WHERE klauslita",
+"Võti '%-.64s' ei eksisteeri tabelis '%-.64s'",
+"Ei suuda avada tabelit",
+"Antud tabelitüüp ei toeta %s käske",
+"Seda käsku ei saa kasutada transaktsiooni sees",
+"Viga %d käsu COMMIT täitmisel",
+"Viga %d käsu ROLLBACK täitmisel",
+"Viga %d käsu FLUSH_LOGS täitmisel",
+"Viga %d käsu CHECKPOINT täitmisel",
+"Ühendus katkestatud %ld andmebaas: '%-.64s' kasutaja: '%-.32s' masin: `%-.64s' (%-.64s)",
"The handler for the table does not support binary table dump",
"Binlog closed while trying to FLUSH MASTER",
"Failed rebuilding the index of dumped table '%-.64s'",
"Error from master: '%-.64s'",
"Net error reading from master",
"Net error writing to master",
-"Can't find FULLTEXT index matching the column list",
-"Can't execute the given command because you have active locked tables or an active transaction",
-"Tundmatu süsteemne muutja '%-.64s'",
+"Ei suutnud leida FULLTEXT indeksit, mis kattuks kasutatud tulpadega",
+"Ei suuda täita antud käsku kuna on aktiivseid lukke või käimasolev transaktsioon",
+"Tundmatu süsteemne muutuja '%-.64s'",
"Tabel '%-.64s' on märgitud vigaseks ja tuleb parandada",
-"Tabel '%-.64s' on märgitud vigaseks ja viimane (automaatne?) parandamiskatse ebaõnnestus",
-"Warning: Some non-transactional changed tables couldn't be rolled back",
-"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again",
+"Tabel '%-.64s' on märgitud vigaseks ja viimane (automaatne?) parandus ebaõnnestus",
+"Hoiatus: mõnesid transaktsioone mittetoetavaid tabeleid ei suudetud tagasi kerida",
+"Mitme lausendiga transaktsioon nõudis rohkem ruumi kui lubatud 'max_binlog_cache_size' muutujaga. Suurenda muutuja väärtust ja proovi uuesti",
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
-"User %-.64s has already more than 'max_user_connections' active connections",
-"You may only use constant expressions with SET",
-"Lock wait timeout exceeded",
-"The total number of locks exceeds the lock table size",
-"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
-"DROP DATABASE not allowed while thread is holding global read lock",
-"CREATE DATABASE not allowed while thread is holding global read lock",
-"Wrong arguments to %s",
-"%-.32s@%-.64s is not allowed to create new users",
-"Incorrect table definition; All MERGE tables must be in the same database",
-"Deadlock found when trying to get lock; Try restarting transaction",
-"The used table type doesn't support FULLTEXT indexes",
+"Kasutajal %-.64s on juba rohkem ühendusi kui lubatud 'max_user_connections' muutujaga",
+"Ainult konstantsed suurused on lubatud SET klauslis",
+"Kontrollaeg ületatud luku järel ootamisel; Proovi transaktsiooni otsast alata",
+"Lukkude koguarv ületab lukutabeli suuruse",
+"Uuenduslukke ei saa kasutada READ UNCOMMITTED transaktsiooni käigus",
+"DROP DATABASE ei ole lubatud kui lõim omab globaalset READ lukku",
+"CREATE DATABASE ei ole lubatud kui lõim omab globaalset READ lukku",
+"Vigased parameetrid %s-le",
+"Kasutajal %-.32s@%-.64s ei ole lubatud luua uusi kasutajaid",
+"Vigane tabelimääratlus; kõik MERGE tabeli liikmed peavad asuma samas andmebaasis",
+"Lukustamisel tekkis tupik (deadlock); alusta transaktsiooni otsast",
+"Antud tabelitüüp ei toeta FULLTEXT indekseid",
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Viga käsu %s täitmisel: %-.128s",
+"Vigane %s ja %s kasutus",
+"Tulpade arv kasutatud SELECT lausetes ei kattu",
+"Ei suuda täita päringut konfliktse luku tõttu",
+"Transaktsioone toetavate ning mittetoetavate tabelite kooskasutamine ei ole lubatud",
+"Määrangut '%s' on lauses kasutatud topelt",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt
index 594fcf900b4..cabb22a6494 100644
--- a/sql/share/french/errmsg.txt
+++ b/sql/share/french/errmsg.txt
@@ -105,7 +105,7 @@
"BLOB '%-.64s' ne peut avoir de valeur par défaut",
"Nom de base de donnée illégal: '%-.64s'",
"Nom de table illégal: '%-.64s'",
-"SELECT va devoir examiner beaucoup d'enregistrements ce qui va prendre du temps. Vérifiez la clause WHERE et utilisez SET OPTION SQL_BIG_SELECTS=1 si SELECT se passe bien",
+"SELECT va devoir examiner beaucoup d'enregistrements ce qui va prendre du temps. Vérifiez la clause WHERE et utilisez SET SQL_BIG_SELECTS=1 si SELECT se passe bien",
"Erreur inconnue",
"Procédure %s inconnue",
"Mauvais nombre de paramètres pour la procedure %s",
@@ -147,7 +147,7 @@
"La commande '%-.16s' est interdite à l'utilisateur: '%-.32s@%-.64s' sur la colonne '%-.64s' de la table '%-.64s'",
"Commande GRANT/REVOKE incorrecte. Consultez le manuel.",
"L'hôte ou l'utilisateur donné en argument à GRANT est trop long",
-"La table '%-64s.%s' n'existe pas",
+"La table '%-.64s.%s' n'existe pas",
"Un tel droit n'est pas défini pour l'utilisateur '%-.32s' sur l'hôte '%-.64s' sur la table '%-.64s'",
"Cette commande n'existe pas dans cette version de MySQL",
"Erreur de syntaxe",
@@ -179,7 +179,7 @@
"Vous êtes en mode 'safe update' et vous essayez de faire un UPDATE sans clause WHERE utilisant un index",
"L'index '%-.64s' n'existe pas sur la table '%-.64s'",
"Impossible d'ouvrir la table",
-"Ce type de table ne supporte pas les check/repair",
+"Ce type de table ne supporte pas les %s",
"Vous n'êtes pas autorisé à exécute cette commande dans une transaction",
"Erreur %d lors du COMMIT",
"Erreur %d lors du ROLLBACK",
@@ -202,7 +202,7 @@
"Cette opération ne peut être réalisée avec un esclave actif, faites SLAVE STOP d'abord",
"Cette opération nécessite un esclave actif, configurez les esclaves et faites SLAVE START",
"Le server n'est pas configuré comme un esclave, changez le fichier de configuration ou utilisez CHANGE MASTER TO",
-"Impossible d'initialiser les structures d'information de maître, vérifiez les permissions sur master.info",
+"Impossible d'initialiser les structures d'information de maître, vous trouverez des messages d'erreur supplémentaires dans le journal des erreurs de MySQL",
"Impossible de créer une tâche esclave, vérifiez les ressources système",
"L'utilisateur %-.64s possède déjà plus de 'max_user_connections' connections actives",
"Seules les expressions constantes sont autorisées avec SET",
@@ -219,3 +219,24 @@
"Impossible d'ajouter des contraintes d'index externe",
"Impossible d'ajouter un enregistrement fils : une constrainte externe l'empèche",
"Impossible de supprimer un enregistrement père : une constrainte externe l'empèche",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt
index 4171b9b476e..518cb507466 100644
--- a/sql/share/german/errmsg.txt
+++ b/sql/share/german/errmsg.txt
@@ -108,7 +108,7 @@
"BLOB-Feld '%-.64s' kann keinen Vorgabewert (Default-Value) besitzen.",
"Unerlaubter Datenbankname '%-.64s'.",
"Unerlaubter Tabellenname '%-.64s'.",
-"Die Ausführung des SELECT würde zu viele Datensätze untersuchen und wahrscheinlich sehr lange daueren. Bitte WHERE überprüfen und SET OPTION SQL_BIG_SELECTS=1 verwenden, sofern SELECT ok ist.",
+"Die Ausführung des SELECT würde zu viele Datensätze untersuchen und wahrscheinlich sehr lange daueren. Bitte WHERE überprüfen und SET SQL_BIG_SELECTS=1 verwenden, sofern SELECT ok ist.",
"Unbekannter Fehler.",
"Unbekannte Procedure %-.64s.",
"Falsche Parameterzahl für Procedure %-.64s.",
@@ -182,7 +182,7 @@
"Unter Verwendung des Sicheren Updatemodes wurde versucht eine Tabelle zu updaten ohne eine KEY-Spalte in der WHERE-Klausel",
"Schlüssel '%-.64s' existiert nicht in der Tabelle '%-.64s'",
"Kann Tabelle nicht öffnen",
-"Der Tabellen-Handler für diese Tabelle unterstützt kein check/repair",
+"Der Tabellen-Handler für diese Tabelle unterstützt kein %s",
"Keine Berechtigung dieses Kommando in einer Transaktion auszuführen",
"Fehler %d wärend COMMIT",
"Fehler %d wärend ROLLBACK",
@@ -205,7 +205,7 @@
"Diese Operation kann nicht bei einem aktiven Slave durchgeführt werden. Das Kommand SLAVE STOP muss zuerst ausgeführt werden.",
"Diese Operationbenötigt einen aktiven Slave. Slave konfigurieren und mittels SLAVE START aktivieren.",
"Der Server ist nicht als Slave konfigiriert. Im Konfigurations-File oder mittel CHANGE MASTER TO beheben.",
-"Konnte Master-Info-Struktur nicht initialisieren; Berechtigungen von master.info prüfen.",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Konnte keinen Slave-Thread starten. System-Resourcen überprüfen.",
"Benutzer %-.64s hat mehr als 'max_user_connections' aktive Verbindungen",
"Bei der Verwendung mit SET dürfen nur Constante Ausdrücke verwendet werden",
@@ -222,3 +222,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt
index bc9e42c7690..d993d80dcc1 100644
--- a/sql/share/greek/errmsg.txt
+++ b/sql/share/greek/errmsg.txt
@@ -105,7 +105,7 @@
"Ôá Blob ðåäßá '%-.64s' äåí ìðïñïýí íá Ý÷ïõí ðñïêáèïñéóìÝíåò ôéìÝò (default value)",
"ËÜèïò üíïìá âÜóçò äåäïìÝíùí '%-.100s'",
"ËÜèïò üíïìá ðßíáêá '%-.100s'",
-"Ôï SELECT èá åîåôÜóåé ìåãÜëï áñéèìü åããñáöþí êáé ðéèáíþò èá êáèõóôåñÞóåé. Ðáñáêáëþ åîåôÜóôå ôéò ðáñáìÝôñïõò ôïõ WHERE êáé ÷ñçóéìïðïéåßóôå SET OPTION SQL_BIG_SELECTS=1 áí ôï SELECT åßíáé óùóôü",
+"Ôï SELECT èá åîåôÜóåé ìåãÜëï áñéèìü åããñáöþí êáé ðéèáíþò èá êáèõóôåñÞóåé. Ðáñáêáëþ åîåôÜóôå ôéò ðáñáìÝôñïõò ôïõ WHERE êáé ÷ñçóéìïðïéåßóôå SET SQL_BIG_SELECTS=1 áí ôï SELECT åßíáé óùóôü",
"ÐñïÝêõøå Üãíùóôï ëÜèïò",
"Áãíùóôç äéáäéêáóßá '%-.64s'",
"ËÜèïò áñéèìüò ðáñáìÝôñùí óôç äéáäéêáóßá '%-.64s'",
@@ -179,7 +179,7 @@
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
"Key '%-.64s' doesn't exist in table '%-.64s'",
"Can't open table",
-"The handler for the table doesn't support check/repair",
+"The handler for the table doesn't support %s",
"You are not allowed to execute this command in a transaction",
"Got error %d during COMMIT",
"Got error %d during ROLLBACK",
@@ -202,7 +202,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -219,3 +219,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt
index 29b75030d22..4a65e735ef9 100644
--- a/sql/share/hungarian/errmsg.txt
+++ b/sql/share/hungarian/errmsg.txt
@@ -107,7 +107,7 @@
"A(z) '%-.64s' blob objektumnak nem lehet alapertelmezett erteke",
"Hibas adatbazisnev: '%-.100s'",
"Hibas tablanev: '%-.100s'",
-"A SELECT tul sok rekordot fog megvizsgalni es nagyon sokaig fog tartani. Ellenorizze a WHERE-t es hasznalja a SET OPTION SQL_BIG_SELECTS=1 beallitast, ha a SELECT ok",
+"A SELECT tul sok rekordot fog megvizsgalni es nagyon sokaig fog tartani. Ellenorizze a WHERE-t es hasznalja a SET SQL_BIG_SELECTS=1 beallitast, ha a SELECT ok",
"Ismeretlen hiba",
"Ismeretlen eljaras: '%-.64s'",
"Rossz parameter a(z) '%-.64s'eljaras szamitasanal",
@@ -149,7 +149,7 @@
"%-.16s parancs a '%-.32s@%-.64s' felhasznalo szamara nem engedelyezett a '%-.64s' mezo eseten a '%-.64s' tablaban",
"Ervenytelen GRANT/REVOKE parancs. Kerem, nezze meg a kezikonyvben, milyen jogok lehetsegesek",
"A host vagy felhasznalo argumentuma tul hosszu a GRANT parancsban",
-"A '%-64s.%s' tabla nem letezik",
+"A '%-.64s.%s' tabla nem letezik",
"A '%-.32s' felhasznalo szamara a '%-.64s' host '%-.64s' tablajaban ez a parancs nem engedelyezett",
"A hasznalt parancs nem engedelyezett ebben a MySQL verzioban",
"Szintaktikai hiba",
@@ -181,7 +181,7 @@
"On a biztonsagos update modot hasznalja, es WHERE that uses a KEY column",
"A '%-.64s' kulcs nem letezik a '%-.64s' tablaban",
"Nem tudom megnyitni a tablat",
-"A tabla kezeloje (handler) nem tamogatja az ellenorzest/helyreallitast",
+"A tabla kezeloje (handler) nem tamogatja az %s",
"Az On szamara nem engedelyezett a parancs vegrehajtasa a tranzakcioban",
"%d hiba a COMMIT vegrehajtasa soran",
"%d hiba a ROLLBACK vegrehajtasa soran",
@@ -204,7 +204,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -221,3 +221,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt
index 6d0c7bcdc73..30dff93ebef 100644
--- a/sql/share/italian/errmsg.txt
+++ b/sql/share/italian/errmsg.txt
@@ -105,7 +105,7 @@
"Il campo BLOB '%-.64s' non puo` avere un valore di default",
"Nome database errato '%-.100s'",
"Nome tabella errato '%-.100s'",
-"La SELECT dovrebbe esaminare troppi record e usare troppo tempo. Controllare la WHERE e usa SET OPTION SQL_BIG_SELECTS=1 se e` tutto a posto.",
+"La SELECT dovrebbe esaminare troppi record e usare troppo tempo. Controllare la WHERE e usa SET SQL_BIG_SELECTS=1 se e` tutto a posto.",
"Errore sconosciuto",
"Procedura '%-.64s' sconosciuta",
"Numero di parametri errato per la procedura '%-.64s'",
@@ -147,7 +147,7 @@
"Comando %-.16s negato per l'utente: '%-.32s@%-.64s' sulla colonna '%-.64s' della tabella '%-.64s'",
"Comando GRANT/REVOKE illegale. Prego consultare il manuale per sapere quali privilegi possono essere usati.",
"L'argomento host o utente per la GRANT e` troppo lungo",
-"La tabella '%-64s.%s' non esiste",
+"La tabella '%-.64s.%s' non esiste",
"GRANT non definita per l'utente '%-.32s' dalla macchina '%-.64s' sulla tabella '%-.64s'",
"Il comando utilizzato non e` supportato in questa versione di MySQL",
"Errore di sintassi nella query SQL",
@@ -179,7 +179,7 @@
"In modalita` 'safe update' si e` cercato di aggiornare una tabella senza clausola WHERE su una chiave",
"La chiave '%-.64s' non esiste nella tabella '%-.64s'",
"Impossibile aprire la tabella",
-"Il gestore per la tabella non supporta il controllo/riparazione",
+"Il gestore per la tabella non supporta il %s",
"Non puoi eseguire questo comando in una transazione",
"Rilevato l'errore %d durante il COMMIT",
"Rilevato l'errore %d durante il ROLLBACK",
@@ -202,7 +202,7 @@
"Questa operazione non puo' essere eseguita con un database 'slave' che gira, lanciare prima SLAVE STOP",
"Questa operaione richiede un database 'slave', configurarlo ed eseguire SLAVE START",
"Il server non e' configurato come 'slave', correggere il file di configurazione cambiando CHANGE MASTER TO",
-"Impossibile inizializzare la struttura 'master info', controllare i permessi sul file master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Impossibile creare il thread 'slave', controllare le risorse di sistema",
"L'utente %-.64s ha gia' piu' di 'max_user_connections' connessioni attive",
"Si possono usare solo espressioni costanti con SET",
@@ -219,3 +219,24 @@
"Impossibile aggiungere il vincolo di integrita' referenziale (foreign key constraint)",
"Impossibile aggiungere la riga: un vincolo d'integrita' referenziale non e' soddisfatto",
"Impossibile cancellare la riga: un vincolo d'integrita' referenziale non e' soddisfatto",
+"Errore durante la connessione al master: %-.128s",
+"Errore eseguendo una query sul master: %-.128s",
+"Errore durante l'esecuzione del comando %s: %-.128s",
+"Uso errato di %s e %s",
+"La SELECT utilizzata ha un numero di colonne differente",
+"Impossibile eseguire la query perche' c'e' un conflitto con in lock di lettura",
+"E' disabilitata la possibilita' di mischiare tabelle transazionali e non-transazionali",
+"L'opzione '%s' e' stata usata due volte nel comando",
+"L'utente '%-.64s' ha ecceduto la risorsa '%s' (valore corrente: %ld)",
+"Accesso non consentito. Serve il privilegio %-.128s per questa operazione",
+"La variabile '%-.64s' e' una variabile locale ( LOCAL ) e non puo' essere cambiata usando SET GLOBAL",
+"La variabile '%-.64s' e' una variabile globale ( GLOBAL ) e deve essere cambiata usando SET GLOBAL",
+"La variabile '%-.64s' non ha un valore di default",
+"Alla variabile '%-.64s' non puo' essere assegato il valore '%-.64s'",
+"Tipo di valore errato per la variabile '%-.64s'",
+"Alla variabile '%-.64s' e' di sola scrittura quindi puo' essere solo assegnato un valore, non letto",
+"Uso/posizione di '%s' sbagliato",
+"Questa versione di MySQL non supporta ancora '%s'",
+"Errore fatale %d: '%-.128s' dal master leggendo i dati dal log binario",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt
index 4b091bc20ba..c384c4bded4 100644
--- a/sql/share/japanese/errmsg.txt
+++ b/sql/share/japanese/errmsg.txt
@@ -107,7 +107,7 @@
"BLOB column '%-.64s' can't have a default value",
"»ØÄꤷ¤¿ database ̾ '%-.100s' ¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹",
"»ØÄꤷ¤¿ table ̾ '%-.100s' ¤Ï¤Þ¤Á¤¬¤Ã¤Æ¤¤¤Þ¤¹",
-"The SELECT would examine too many records and probably take a very long time. Check your WHERE and use SET OPTION SQL_BIG_SELECTS=1 if the SELECT is ok",
+"The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok",
"Unknown error",
"Unknown procedure '%-.64s'",
"Incorrect parameter count to procedure '%-.64s'",
@@ -149,7 +149,7 @@
"¥³¥Þ¥ó¥É %-.16s ¤Ï ¥æ¡¼¥¶¡¼ '%-.32s@%-.64s'\n ¥«¥é¥à '%-.64s' ¥Æ¡¼¥Ö¥ë '%-.64s' ¤ËÂФ·¤Æµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -181,7 +181,7 @@
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
"Key '%-.64s' doesn't exist in table '%-.64s'",
"Can't open table",
-"The handler for the table doesn't support check/repair",
+"The handler for the table doesn't support %s",
"You are not allowed to execute this command in a transaction",
"Got error %d during COMMIT",
"Got error %d during ROLLBACK",
@@ -204,7 +204,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -221,3 +221,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt
index 871d67ff21e..b706069b495 100644
--- a/sql/share/korean/errmsg.txt
+++ b/sql/share/korean/errmsg.txt
@@ -105,7 +105,7 @@
"BLOB Ä®·³ '%-.64s' ´Â µðÆúÆ® °ªÀ» °¡Áú ¼ö ¾ø½À´Ï´Ù.",
"'%-.100s' µ¥ÀÌŸº£À̽ºÀÇ À̸§ÀÌ ºÎÁ¤È®ÇÕ´Ï´Ù.",
"'%-.100s' Å×À̺í À̸§ÀÌ ºÎÁ¤È®ÇÕ´Ï´Ù.",
-"SELECT ¸í·É¿¡¼­ ³Ê¹« ¸¹Àº ·¹Äڵ带 ã±â ¶§¹®¿¡ ¸¹Àº ½Ã°£ÀÌ ¼Ò¿äµË´Ï´Ù. µû¶ó¼­ WHERE ¹®À» Á¡°ËÇϰųª, ¸¸¾à SELECT°¡ okµÇ¸é SET OPTION SQL_BIG_SELECTS=1 ¿É¼ÇÀ» »ç¿ëÇϼ¼¿ä.",
+"SELECT ¸í·É¿¡¼­ ³Ê¹« ¸¹Àº ·¹Äڵ带 ã±â ¶§¹®¿¡ ¸¹Àº ½Ã°£ÀÌ ¼Ò¿äµË´Ï´Ù. µû¶ó¼­ WHERE ¹®À» Á¡°ËÇϰųª, ¸¸¾à SELECT°¡ okµÇ¸é SET SQL_BIG_SELECTS=1 ¿É¼ÇÀ» »ç¿ëÇϼ¼¿ä.",
"¾Ë¼ö ¾ø´Â ¿¡·¯ÀÔ´Ï´Ù.",
"¾Ë¼ö ¾ø´Â ¼öÇ๮ : '%-.64s'",
"'%-.64s' ¼öÇ๮¿¡ ´ëÇÑ ºÎÁ¤È®ÇÑ ÆĶó¸ÞÅÍ",
@@ -147,7 +147,7 @@
"'%-.16s' ¸í·ÉÀº ´ÙÀ½ »ç¿ëÀÚ¿¡°Ô °ÅºÎµÇ¾ú½À´Ï´Ù. : '%-.32s@%-.64s' for Ä®·³ '%-.64s' in Å×À̺í '%-.64s'",
"À߸øµÈ GRANT/REVOKE ¸í·É. ¾î¶² ±Ç¸®¿Í ½ÂÀÎÀÌ »ç¿ëµÇ¾î Áú ¼ö ÀÖ´ÂÁö ¸Þ´º¾óÀ» º¸½Ã¿À.",
"½ÂÀÎ(GRANT)À» À§ÇÏ¿© »ç¿ëÇÑ »ç¿ëÀÚ³ª È£½ºÆ®ÀÇ °ªµéÀÌ ³Ê¹« ±é´Ï´Ù.",
-"Å×À̺í '%-64s.%s' ´Â Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.",
+"Å×À̺í '%-.64s.%s' ´Â Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.",
"»ç¿ëÀÚ '%-.32s'(È£½ºÆ® '%-.64s')´Â Å×À̺í '%-.64s'¸¦ »ç¿ëÇϱâ À§ÇÏ¿© Á¤ÀÇµÈ ½ÂÀÎÀº ¾ø½À´Ï´Ù. ",
"»ç¿ëµÈ ¸í·ÉÀº ÇöÀçÀÇ MySQL ¹öÁ¯¿¡¼­´Â ÀÌ¿ëµÇÁö ¾Ê½À´Ï´Ù.",
"SQL ±¸¹®¿¡ ¿À·ù°¡ ÀÖ½À´Ï´Ù.",
@@ -179,7 +179,7 @@
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
"Key '%-.64s' doesn't exist in table '%-.64s'",
"Can't open table",
-"The handler for the table doesn't support check/repair",
+"The handler for the table doesn't support %s",
"You are not allowed to execute this command in a transaction",
"Got error %d during COMMIT",
"Got error %d during ROLLBACK",
@@ -202,7 +202,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -219,3 +219,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt
index 6b42418c917..2c1deead312 100644
--- a/sql/share/norwegian-ny/errmsg.txt
+++ b/sql/share/norwegian-ny/errmsg.txt
@@ -107,7 +107,7 @@
"Blob feltet '%-.64s' kan ikkje ha ein standard verdi",
"Ugyldig database namn '%-.64s'",
"Ugyldig tabell namn '%-.64s'",
-"SELECT ville undersøkje for mange postar og ville sannsynligvis ta veldig lang tid. Undersøk WHERE klausulen og bruk SET OPTION SQL_BIG_SELECTS=1 om SELECTen er korrekt",
+"SELECT ville undersøkje for mange postar og ville sannsynligvis ta veldig lang tid. Undersøk WHERE klausulen og bruk SET SQL_BIG_SELECTS=1 om SELECTen er korrekt",
"Ukjend feil",
"Ukjend prosedyre %s",
"Feil parameter tal til prosedyra %s",
@@ -149,7 +149,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -181,7 +181,7 @@
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
"Key '%-.64s' doesn't exist in table '%-.64s'",
"Can't open table",
-"The handler for the table doesn't support check/repair",
+"The handler for the table doesn't support %s",
"You are not allowed to execute this command in a transaction",
"Got error %d during COMMIT",
"Got error %d during ROLLBACK",
@@ -204,7 +204,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -221,3 +221,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt
index 0e9ead25986..42b35c18cfc 100644
--- a/sql/share/norwegian/errmsg.txt
+++ b/sql/share/norwegian/errmsg.txt
@@ -107,7 +107,7 @@
"Blob feltet '%-.64s' kan ikke ha en standard verdi",
"Ugyldig database navn '%-.64s'",
"Ugyldig tabell navn '%-.64s'",
-"SELECT ville undersøke for mange poster og ville sannsynligvis ta veldig lang tid. Undersøk WHERE klausulen og bruk SET OPTION SQL_BIG_SELECTS=1 om SELECTen er korrekt",
+"SELECT ville undersøke for mange poster og ville sannsynligvis ta veldig lang tid. Undersøk WHERE klausulen og bruk SET SQL_BIG_SELECTS=1 om SELECTen er korrekt",
"Ukjent feil",
"Ukjent prosedyre %s",
"Feil parameter antall til prosedyren %s",
@@ -149,7 +149,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -181,7 +181,7 @@
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
"Key '%-.64s' doesn't exist in table '%-.64s'",
"Can't open table",
-"The handler for the table doesn't support check/repair",
+"The handler for the table doesn't support %s",
"You are not allowed to execute this command in a transaction",
"Got error %d during COMMIT",
"Got error %d during ROLLBACK",
@@ -204,7 +204,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -221,3 +221,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt
index 7bb05ba175f..d8e84b08a9a 100644
--- a/sql/share/polish/errmsg.txt
+++ b/sql/share/polish/errmsg.txt
@@ -151,7 +151,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -183,7 +183,7 @@
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
"Key '%-.64s' doesn't exist in table '%-.64s'",
"Can't open table",
-"The handler for the table doesn't support check/repair",
+"The handler for the table doesn't support %s",
"You are not allowed to execute this command in a transaction",
"Got error %d during COMMIT",
"Got error %d during ROLLBACK",
@@ -206,7 +206,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -223,3 +223,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt
index f3861bc945e..a1b5e87a52d 100644
--- a/sql/share/portuguese/errmsg.txt
+++ b/sql/share/portuguese/errmsg.txt
@@ -105,7 +105,7 @@
"Coluna BLOB '%-.64s' não pode ter um valor padrão (default)",
"Nome de banco de dados '%-.100s' incorreto",
"Nome de tabela '%-.100s' incorreto",
-"O SELECT examinaria registros demais e provavelmente levaria muito tempo. Cheque sua cláusula WHERE e use SET OPTION SQL_BIG_SELECTS=1, se o SELECT estiver correto",
+"O SELECT examinaria registros demais e provavelmente levaria muito tempo. Cheque sua cláusula WHERE e use SET SQL_BIG_SELECTS=1, se o SELECT estiver correto",
"Erro desconhecido",
"'Procedure' '%-.64s' desconhecida",
"Número de parâmetros incorreto para a 'procedure' '%-.64s'",
@@ -179,7 +179,7 @@
"Você está usando modo de atualização seguro e tentou atualizar uma tabela sem uma cláusula WHERE que use uma coluna chave",
"Chave '%-.64s' não existe na tabela '%-.64s'",
"Não pode abrir a tabela",
-"O manipulador de tabela não suporta checagem/reparação (check/repair)",
+"O manipulador de tabela não suporta %s",
"Não lhe é permitido executar este comando em uma transação",
"Obteve erro %d durante COMMIT",
"Obteve erro %d durante ROLLBACK",
@@ -202,7 +202,7 @@
"Esta operação não pode ser realizada com um 'slave' em execução. Execute SLAVE STOP primeiro",
"Esta operação requer um 'slave' em execução. Configure o 'slave' e execute SLAVE START",
"O servidor não está configurado como 'slave'. Acerte o arquivo de configuração ou use CHANGE MASTER TO",
-"Não pode inicializar a estrutura de informação do 'master'. Verifique as permissões em 'master.info'",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Não conseguiu criar 'thread' de 'slave'. Verifique os recursos do sistema",
"Usuário '%-.64s' já possui mais que o valor máximo de conexões (max_user_connections) ativas",
"Você pode usar apenas expressões constantes com SET",
@@ -219,3 +219,24 @@
"Não pode acrescentar uma restrição de chave estrangeira",
"Não pode acrescentar uma linha filha: uma restrição de chave estrangeira falhou",
"Não pode apagar uma linha pai: uma restrição de chave estrangeira falhou",
+"Erro conectando com o master: %-.128s",
+"Erro rodando consulta no master: %-.128s",
+"Erro quando executando comando %s: %-.128s",
+"Uso errado de %s e %s",
+"Os comandos SELECT usados têm diferente número de colunas",
+"Não posso executar a consulta porque você tem um conflito de travamento de leitura",
+"Mistura de tabelas transacional e não-transacional está desabilitada",
+"Opção '%s' usada duas vezes no comando",
+"Usuário '%-.64s' tem excedido o '%s' recurso (atual valor: %ld)",
+"Acesso negado. Você precisa o privilégio %-.128s para essa operação",
+"Variável '%-.64s' é uma LOCAL variável e não pode ser usada com SET GLOBAL",
+"Variável '%-.64s' é uma GLOBAL variável e deve ser configurada com SET GLOBAL",
+"Variável '%-.64s' não tem um valor padrão",
+"Variável '%-.64s' não pode ser configurada para o valor de '%-.64s'",
+"Tipo errado de argumento para variável '%-.64s'",
+"Variável '%-.64s' somente pode ser configurada, não lida",
+"Errado uso/colocação de '%s'",
+"Esta versão de MySQL não suporta ainda '%s'",
+"Obteve fatal erro %d: '%-.128s' do master quando lendo dados do binary log",
+"Slave SQL thread ignorado a consulta devido às normas de replicação-*-tabela"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt
index 9ddb06a2c24..44e8b9fa8de 100644
--- a/sql/share/romanian/errmsg.txt
+++ b/sql/share/romanian/errmsg.txt
@@ -109,7 +109,7 @@
"Coloana BLOB '%-.64s' nu poate avea o valoare default",
"Numele bazei de date este incorect '%-.100s'",
"Numele tabelei este incorect '%-.100s'",
-"SELECT-ul ar examina prea multe cimpuri si probabil ar lua prea mult timp. Verifica clauza WHERE si foloseste SET OPTION SQL_BIG_SELECTS=1 daca SELECT-ul e ok",
+"SELECT-ul ar examina prea multe cimpuri si probabil ar lua prea mult timp. Verifica clauza WHERE si foloseste SET SQL_BIG_SELECTS=1 daca SELECT-ul e ok",
"Eroare unknown",
"Procedura unknown '%-.64s'",
"Procedura '%-.64s' are un numar incorect de parametri",
@@ -183,7 +183,7 @@
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
"Key '%-.64s' doesn't exist in table '%-.64s'",
"Can't open table",
-"The handler for the table doesn't support check/repair",
+"The handler for the table doesn't support %s",
"You are not allowed to execute this command in a transaction",
"Got error %d during COMMIT",
"Got error %d during ROLLBACK",
@@ -206,7 +206,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -223,3 +223,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt
index d6d878fef8b..472031c6300 100644
--- a/sql/share/russian/errmsg.txt
+++ b/sql/share/russian/errmsg.txt
@@ -1,224 +1,244 @@
-/* Copyright Abandoned 1998.
+/* Copyright 2003 MySQL AB;
+ Translation done in 2003 by Egor Egorov; Ensita.NET, http://www.ensita.net/
This file is public domain and comes with NO WARRANTY of any kind */
-/* Primary translation was done by "Timur I. Bakeyev" <translate@bat.ru> */
-/* Additional translation by "Alexander I. Barkov" <bar@izhcom.ru> */
/* charset: KOI8-R */
"hashchk",
"isamchk",
"îåô",
"äá",
-"îÅ ÍÏÇÕ ÓÏÚÄÁÔØ ÆÁÊÌ '%-.64s' (ïÛÉÂËÁ: %d)",
-"îÅ ÍÏÇÕ ÓÏÚÄÁÔØ ÔÁÂÌÉÃÕ '%-.64s' (ïÛÉÂËÁ: %d)",
-"îÅ ÍÏÇÕ ÓÏÚÄÁÔØ ÂÁÚÕ '%-.64s'. ïÛÉÂËÁ: %d",
-"îÅ ÍÏÇÕ ÓÏÚÄÁÔØ ÂÁÚÕ '%-.64s'. âÁÚÁ ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ",
-"îÅ ÍÏÇÕ ÕÄÁÌÉÔØ ÂÁÚÕ '%-.64s'. âÁÚÁ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ",
-"ïÛÉÂËÁ ÐÒÉ ÕÄÁÌÅÎÉÉ ÂÁÚÙ (îÅ ÍÏÇÕ ÕÄÁÌÉÔØ '%-.64s', ÏÛÉÂËÁ %d)",
-"ïÛÉÂËÁ ÐÒÉ ÕÄÁÌÅÎÉÉ ÂÁÚÙ (îÅ ÍÏÇÕ ÕÄÁÌÉÔØ ËÁÔÁÌÏÇ '%-.64s', ÏÛÉÂËÁ %d)",
-"ïÛÉÂËÁ ÐÒÉ ÕÄÁÌÅÎÉÉ '%-.64s' (ïÛÉÂËÁ: %d)",
-"îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ ÚÁÐÉÓØ × ÓÉÓÔÅÍÎÏÊ ÔÁÂÌÉÃÅ",
-"îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÓÔÁÔÕÓ '%-.64s' (ïÛÉÂËÁ: %d)",
-"îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÒÁÂÏÞÉÊ ËÁÔÁÌÏÇ (ïÛÉÂËÁ: %d)",
-"îÅ ÍÏÇÕ ÂÌÏËÉÒÏ×ÁÔØ ÆÁÊÌ (ïÛÉÂËÁ: %d)",
-"îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÆÁÊÌ: '%-.64s'. (ïÛÉÂËÁ: %d)",
-"îÅ ÍÏÇÕ ÎÁÊÔÉ ÆÁÊÌ: '%-.64s' (ïÛÉÂËÁ: %d)",
-"îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ ËÁÔÁÌÏÇ '%-.64s' (ïÛÉÂËÁ: %d)",
-"îÅ ÍÏÇÕ ÐÅÒÅÊÔÉ × ËÁÔÁÌÏÇ '%-.64s' (ïÛÉÂËÁ: %d)",
-"úÁÐÉÓØ ÂÙÌÁ ÉÚÍÅÎÅÎÁ ÓÏ ×ÒÅÍÅÎÉ ÐÏÓÌÅÄÎÅÇÏ ÞÔÅÎÉÑ ÔÁÂÌÉÃÙ '%-.64s'",
-"ðÅÒÅÐÏÌÎÅÎ ÄÉÓË (%-.64s). íÏÖÅÔ, ËÔÏ-ÎÉÂÕÄØ ÕÂÅÒÅÔ ÚÁ ÓÏÂÏÊ ÍÕÓÏÒ....",
-"îÅ ÍÏÇÕ ÐÒÏÉÚ×ÅÓÔÉ ÚÁÐÉÓØ, ËÌÀÞ ÄÕÂÌÉÒÕÅÔÓÑ × ÔÁÂÌÉÃÅ '%-.64s'",
-"ïÛÉÂËÁ ÐÒÉ ÚÁËÒÙÔÉÉ '%-.64s' (ïÛÉÂËÁ: %d)",
-"ïÛÉÂËÁ ÞÔÅÎÉÑ ÆÁÊÌÁ '%-.64s' (ïÛÉÂËÁ: %d)",
-"ïÛÉÂËÁ ÐÒÉ ÐÅÒÅÉÍÅÎÏ×ÁÎÉÉ '%-.64s' × '%-.64s' (ïÛÉÂËÁ: %d)",
-"ïÛÉÂËÁ ÚÁÐÉÓÉ × ÆÁÊÌ '%-.64s' (ïÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÓÏÚÄÁÔØ ÆÁÊÌ '%-.64s' (ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÓÏÚÄÁÔØ ÔÁÂÌÉÃÕ '%-.64s' (ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÓÏÚÄÁÔØ ÂÁÚÕ ÄÁÎÎÙÈ '%-.64s'. (ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÓÏÚÄÁÔØ ÂÁÚÕ ÄÁÎÎÙÈ '%-.64s'. âÁÚÁ ÄÁÎÎÙÈ ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ",
+"îÅ×ÏÚÍÏÖÎÏ ÕÄÁÌÉÔØ ÂÁÚÕ ÄÁÎÎÙÈ '%-.64s'. ôÁËÏÊ ÂÁÚÙ ÄÁÎÎÙÈ ÎÅÔ",
+"ïÛÉÂËÁ ÐÒÉ ÕÄÁÌÅÎÉÉ ÂÁÚÙ ÄÁÎÎÙÈ (ÎÅ×ÏÚÍÏÖÎÏ ÕÄÁÌÉÔØ '%-.64s', ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÕÄÁÌÉÔØ ÂÁÚÕ ÄÁÎÎÙÈ (ÎÅ×ÏÚÍÏÖÎÏ ÕÄÁÌÉÔØ ËÁÔÁÌÏÇ '%-.64s', ÏÛÉÂËÁ: %d)",
+"ïÛÉÂËÁ ÐÒÉ ÕÄÁÌÅÎÉÉ '%-.64s' (ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÐÒÏÞÉÔÁÔØ ÚÁÐÉÓØ × ÓÉÓÔÅÍÎÏÊ ÔÁÂÌÉÃÅ",
+"îÅ×ÏÚÍÏÖÎÏ ÐÏÌÕÞÉÔØ ÓÔÁÔÕÓÎÕÀ ÉÎÆÏÒÍÁÃÉÀ Ï '%-.64s' (ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÏÐÒÅÄÅÌÉÔØ ÒÁÂÏÞÉÊ ËÁÔÁÌÏÇ (ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÐÏÓÔÁ×ÉÔØ ÂÌÏËÉÒÏ×ËÕ ÎÁ ÆÁÊÌÅ (ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÏÔËÒÙÔØ ÆÁÊÌ: '%-.64s'. (ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÎÁÊÔÉ ÆÁÊÌ: '%-.64s' (ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÐÒÏÞÉÔÁÔØ ËÁÔÁÌÏÇ '%-.64s' (ÏÛÉÂËÁ: %d)",
+"îÅ×ÏÚÍÏÖÎÏ ÐÅÒÅÊÔÉ × ËÁÔÁÌÏÇ '%-.64s' (ÏÛÉÂËÁ: %d)",
+"úÁÐÉÓØ ÉÚÍÅÎÉÌÁÓØ Ó ÍÏÍÅÎÔÁ ÐÏÓÌÅÄÎÅÊ ×ÙÂÏÒËÉ × ÔÁÂÌÉÃÅ '%-.64s'",
+"äÉÓË ÚÁÐÏÌÎÅÎ. (%s). ïÖÉÄÁÅÍ, ÐÏËÁ ËÔÏ-ÔÏ ÎÅ ÕÂÅÒÅÔ ÐÏÓÌÅ ÓÅÂÑ ÍÕÓÏÒ....",
+"îÅ×ÏÚÍÏÖÎÏ ÐÒÏÉÚ×ÅÓÔÉ ÚÁÐÉÓØ, ÄÕÂÌÉÒÕÀÝÉÊÓÑ ËÌÀÞ × ÔÁÂÌÉÃÅ '%-.64s'",
+"ïÛÉÂËÁ ÐÒÉ ÚÁËÒÙÔÉÉ '%-.64s' (ÏÛÉÂËÁ: %d)",
+"ïÛÉÂËÁ ÞÔÅÎÉÑ ÆÁÊÌÁ '%-.64s' (ÏÛÉÂËÁ: %d)",
+"ïÛÉÂËÁ ÐÒÉ ÐÅÒÅÉÍÅÎÏ×ÁÎÉÉ '%-.64s' × '%-.64s' (ÏÛÉÂËÁ: %d)",
+"ïÛÉÂËÁ ÚÁÐÉÓÉ × ÆÁÊÌ '%-.64s' (ÏÛÉÂËÁ: %d)",
"'%-.64s' ÚÁÂÌÏËÉÒÏ×ÁÎ ÄÌÑ ÉÚÍÅÎÅÎÉÊ",
"óÏÒÔÉÒÏ×ËÁ ÐÒÅÒ×ÁÎÁ",
-"View '%-.64s' ÎÅ ÓÕÝÅÓÔ×ÕÅÔ ÄÌÑ '%-.64s'",
-"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ %d ÏÔ ÄÅÓËÒÉÐÔÏÒÁ ÔÁÂÌÉÃÙ",
-"äÅÓËÒÉÐÔÏÒ ÔÁÂÌÉÃÙ '%-.64s' ÎÅ ÉÍÅÅÔ ÔÁËÏÇÏ Ó×ÏÊÓÔ×Á",
-"îÅ ÍÏÇÕ ÎÁÊÔÉ ÚÁÐÉÓØ × '%-.64s'",
-"îÅ×ÅÒÎÁÑ ÉÎÆÏÒÍÁÃÉÑ × ÆÁÊÌÅ: '%-.64s'",
-"îÅ×ÅÒÎÙÊ ÉÎÄÅËÓÎÙÊ ÆÁÊÌ ÄÌÑ ÔÁÂÌÉÃÙ: '%-.64s'. ðÏÐÒÏÂÕÊÔÅ ÅÇÏ ×ÏÓÓÏÚÄÁÔØ",
-"óÔÁÒÙÊ ÉÎÄÅËÓÎÙÊ ÆÁÊÌ ÄÌÑ ÔÁÂÌÉÃÙ '%-.64s'; òÅÉÎÄÅËÓÉÒÕÊÔÅ ÅÅ!",
-"'%-.64s' ÔÏÌØËÏ ÄÌÑ ÞÔÅÎÉÑ",
-"îÅ È×ÁÔÁÅÔ ÐÁÍÑÔÉ. ðÅÒÅÇÒÕÚÉÔÅ ÓÅÒ×ÅÒ É ÐÏÐÒÏÂÕÊÔÅ ÓÎÏ×Á (ÎÕÖÎÏ %d ÂÁÊÔ)",
-"îÅ È×ÁÔÁÅÔ ÐÁÍÑÔÉ ÄÌÑ ÓÏÒÔÉÒÏ×ËÉ. õ×ÅÌÉÞØÔÅ ÒÁÚÍÅÒ ÂÕÆÅÒÁ ÓÏÒÔÉÒÏ×ËÉ Õ ÓÅÒ×ÅÒÁ",
-"îÅÏÖÉÄÁÎÎÙÊ ËÏÎÅà ÆÁÊÌÁ '%-.64s' (ïÛÉÂËÁ: %d)",
+"ðÒÅÄÓÔÁ×ÌÅÎÉÅ '%-.64s' ÎÅ ÓÕÝÅÓÔ×ÕÅÔ ÄÌÑ '%-.64s'",
+"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ %d ÏÔ ÏÂÒÁÂÏÔÞÉËÁ ÔÁÂÌÉÃ",
+"ïÂÒÁÂÏÔÞÉË ÔÁÂÌÉÃÙ '%-.64s' ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÜÔÕ ×ÏÚÍÏÖÎÏÓÔØ",
+"îÅ×ÏÚÍÏÖÎÏ ÎÁÊÔÉ ÚÁÐÉÓØ × '%-.64s'",
+"îÅËÏÒÒÅËÔÎÁÑ ÉÎÆÏÒÍÁÃÉÑ × ÆÁÊÌÅ '%-.64s'",
+"îÅËÏÒÒÅËÔÎÙÊ ÉÎÄÅËÓÎÙÊ ÆÁÊÌ ÄÌÑ ÔÁÂÌÉÃÙ: '%-.64s'. ðÏÐÒÏÂÕÊÔÅ ×ÏÓÓÔÁÎÏ×ÉÔØ ÅÇÏ",
+"óÔÁÒÙÊ ÉÎÄÅËÓÎÙÊ ÆÁÊÌ ÄÌÑ ÔÁÂÌÉÃÙ '%-.64s'; ÏÔÒÅÍÏÎÔÉÒÕÊÔÅ ÅÇÏ!",
+"ôÁÂÌÉÃÁ '%-.64s' ÐÒÅÄÎÁÚÎÁÞÅÎÁ ÔÏÌØËÏ ÄÌÑ ÞÔÅÎÉÑ",
+"îÅÄÏÓÔÁÔÏÞÎÏ ÐÁÍÑÔÉ. ðÅÒÅÚÁÐÕÓÔÉÔÅ ÓÅÒ×ÅÒ É ÐÏÐÒÏÂÕÊÔÅ ÅÝÅ ÒÁÚ (ÎÕÖÎÏ %d ÂÁÊÔ)",
+"îÅÄÏÓÔÁÔÏÞÎÏ ÐÁÍÑÔÉ ÄÌÑ ÓÏÒÔÉÒÏ×ËÉ. õ×ÅÌÉÞØÔÅ ÒÁÚÍÅÒ ÂÕÆÅÒÁ ÓÏÒÔÉÒÏ×ËÉ ÎÁ ÓÅÒ×ÅÒÅ",
+"îÅÏÖÉÄÁÎÎÙÊ ËÏÎÅà ÆÁÊÌÁ '%-.64s' (ÏÛÉÂËÁ: %d)",
"óÌÉÛËÏÍ ÍÎÏÇÏ ÓÏÅÄÉÎÅÎÉÊ",
-"îÅÄÏÓÔÁÔÏË ÍÅÓÔÁ/ÐÁÍÑÔÉ ÄÌÑ ÎÉÔÉ",
-"îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÉÍÑ ÈÏÓÔÁ ÐÏ ÷ÁÛÅÍÕ ÁÄÒÅÓÕ",
-"îÅËÏÒÒÅËÔÎÁÑ ÉÎÉÃÉÁÌÉÚÁÃÉÑ Ó×ÑÚÉ",
-"äÏÓÔÕÐ ÚÁËÒÙÔ ÄÌÑ ÐÏÌØÚÏ×ÁÔÅÌÑ: '%-.32s@%-.64s' Ë ÂÁÚÅ '%-.64s'",
-"äÏÓÔÕÐ ÚÁËÒÙÔ ÄÌÑ ÐÏÌØÚÏ×ÁÔÅÌÑ: '%-.32s@%-.64s' (âÙÌ ÉÓÐÏÌØÚÏ×ÁÎ ÐÁÒÏÌØ: %-.64s)",
-"îÅ ×ÙÂÒÁÎÁ ÂÁÚÁ",
-"îÅÉÚ×ÅÓÔÎÁÑ ËÏÍÁÎÄÁ",
-"óÔÏÌÂÅà '%-.64s' ÎÅ ÍÏÖÅÔ ÂÙÔØ ÐÕÓÔÙÍ/ÎÕÌÅ×ÙÍ",
-"îÅÉÚ×ÅÓÔÎÁÑ ÂÁÚÁ '%-.64s'",
-"ôÁÂÌÉÃÁ '%-.64s' ÕÖÅ ÅÓÔØ",
+"îÅÄÏÓÔÁÔÏÞÎÏ ÐÁÍÑÔÉ; ÕÄÏÓÔÏ×ÅÒØÔÅÓØ, ÞÔÏ mysqld ÉÌÉ ËÁËÏÊ-ÌÉÂÏ ÄÒÕÇÏÊ ÐÒÏÃÅÓÓ ÎÅ ÚÁÎÉÍÁÅÔ ×ÓÀ ÄÏÓÔÕÐÎÕÀ ÐÁÍÑÔØ. åÓÌÉ ÎÅÔ, ÔÏ ×Ù ÍÏÖÅÔÅ ÉÓÐÏÌØÚÏ×ÁÔØ ulimit, ÞÔÏÂÙ ×ÙÄÅÌÉÔØ ÄÌÑ mysqld ÂÏÌØÛÅ ÐÁÍÑÔÉ, ÉÌÉ Õ×ÅÌÉÞÉÔØ ÏÂßÅÍ ÆÁÊÌÁ ÐÏÄËÁÞËÉ",
+"îÅ×ÏÚÍÏÖÎÏ ÐÏÌÕÞÉÔØ ÉÍÑ ÈÏÓÔÁ ÄÌÑ ×ÁÛÅÇÏ ÁÄÒÅÓÁ",
+"îÅËÏÒÒÅËÔÎÏÅ ÐÒÉ×ÅÔÓÔ×ÉÅ",
+"äÌÑ ÐÏÌØÚÏ×ÁÔÅÌÑ '%-.32s@%-.64s' ÄÏÓÔÕÐ Ë ÂÁÚÅ ÄÁÎÎÙÈ '%-.64s' ÚÁËÒÙÔ",
+"äÏÓÔÕÐ ÚÁËÒÙÔ ÄÌÑ ÐÏÌØÚÏ×ÁÔÅÌÑ '%-.32s@%-.64s' (ÂÙÌ ÉÓÐÏÌØÚÏ×ÁÎ ÐÁÒÏÌØ: %s)",
+"âÁÚÁ ÄÁÎÎÙÈ ÎÅ ×ÙÂÒÁÎÁ",
+"îÅÉÚ×ÅÓÔÎÁÑ ËÏÍÁÎÄÁ ËÏÍÍÕÎÉËÁÃÉÏÎÎÏÇÏ ÐÒÏÔÏËÏÌÁ",
+"óÔÏÌÂÅà '%-.64s' ÎÅ ÍÏÖÅÔ ÐÒÉÎÉÍÁÔØ ×ÅÌÉÞÉÎÕ NULL",
+"îÅÉÚ×ÅÓÔÎÁÑ ÂÁÚÁ ÄÁÎÎÙÈ '%-.64s'",
+"ôÁÂÌÉÃÁ '%-.64s' ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ",
"îÅÉÚ×ÅÓÔÎÁÑ ÔÁÂÌÉÃÁ '%-.64s'",
-"ðÏÌÅ '%-.64s' × %-.64s ÎÅ ÏÄÎÏÚÎÁÞÎÏ",
-"ðÒÏÉÓÈÏÄÉÔ ×ÙËÌÀÞÅÎÉÅ ÓÅÒ×ÅÒÁ",
-"îÅÉÚ×ÅÓÔÎÏÅ ÐÏÌÅ '%-.64s' × %-.64s",
-" '%-.64s' ÉÓÐÏÌØÚÏ×ÁÎÏ ×ÎÅ ×ÙÒÁÖÅÎÉÑ GROUP BY",
-"îÅ ÍÏÇÕ ÐÒÏÉÚ×ÅÓÔÉ ÇÒÕÐÐÉÒÏ×ËÕ ÐÏ '%-.64s'",
-"÷ ÏÄÎÏÍ ×ÙÒÁÖÅÎÉÉ ÓÏÄÅÒÖÁÔØÓÑ É ÉÍÅÎÁ ÐÏÌÅÊ, É ÓÕÍÍÉÒÕÀÝÉÅ ÆÕÎËÃÉÉ",
-"þÉÓÌÏ ÓÔÏÌÂÃÏ× ÎÅ ÓÏÏÔ×ÅÔÓÔ×ÕÅÔ ÞÉÓÌÕ ÚÎÁÞÅÎÉÊ",
-"óÌÉÛËÏÍ ÄÌÉÎÎÙÊ ÉÄÅÎÔÉÆÉËÁÔÏÒ: '%-.64s'",
-"äÕÂÌÉÒÏ×ÁÎÎÏÅ ÉÍÑ ÐÏÌÑ '%-.64s'",
-"äÕÂÌÉÒÏ×ÁÎÎÏÅ ÉÍÑ ËÌÀÞÁ '%-.64s'",
-"ðÏ×ÔÏÒÑÀÝÅÅÓÑ ÚÎÁÞÅÎÉÅ '%-.64s' ÄÌÑ ËÌÀÞÁ %d",
-"îÅ×ÅÒÎÙÊ ÓÐÅÃÉÆÉËÁÔÏÒ ÐÏÌÑ: '%-.64s'",
-"%-.64s ÏËÏÌÏ '%-.64s', × ÓÔÒÏËÅ %d",
-"ðÕÓÔÏÊ ÚÁÐÒÏÓ",
-"îÅ ÕÎÉËÁÌØÎÁÑ ÔÁÂÌÉÃÁ/ÐÓÅ×ÄÏÎÉÍ: '%-.64s'",
-"îÅ×ÅÒÎÏÅ ÚÎÁÞÅÎÉÅ ÐÏ ÕÍÏÌÞÁÎÉÀ '%-.64s'",
-"ðÅÒ×ÉÞÎÙÊ ËÌÀÞ ÏÐÒÅÄÅÌÅÎ ÎÅÓËÏÌØËÏ ÒÁÚ",
-"ïÐÒÅÄÅÌÅÎÎÏ ÓÌÉÛËÏÍ ÍÎÏÇÏ ËÌÀÞÅÊ. ÷ÏÚÍÏÖÎÏ ÍÁËÓÉÍÁÌØÎÏ %d ËÌÀÞÅÊ",
-"ïÐÒÅÄÅÌÅÎÎÏ ÓÌÉÛËÏÍ ÍÎÏÇÏ ÓÏÓÔÁ×ÌÑÀÝÉÈ ËÌÀÞÁ. ÷ÏÚÍÏÖÎÏ ÍÁËÓÉÍÁÌØÎÏ %d ÓÏÓÔÁ×ÌÑÀÝÉÈ",
-"ëÌÀÞ ÓÌÉÛËÏÍ ÂÏÌØÛÏÊ. íÁËÓÉÍÁÌØÎÁÑ ÄÌÉÎÁ %d",
-"ëÌÀÞÅ×ÏÅ ÐÏÌÅ '%-.64s' ÎÅ ÓÏÄÅÒÖÉÔÓÑ × ÔÁÂÌÉÃÅ",
-"ïÂßÅËÔ BLOB '%-.64s' ÎÅ ÍÏÖÅÔ ÐÒÉÓÕÔÓÔ×Ï×ÁÔØ × ÏÐÒÅÄÅÌÅÎÉÉ ËÌÀÞÁ",
-"óÌÉÛËÏÍ ×ÅÌÉË ÒÁÚÍÅÒ ÐÏÌÑ '%-.64s' (max = %d). ÷ÏÓÐÏÌØÚÕÊÔÅÓØ ÏÂßÅËÔÏÍ BLOB",
-"á×ÔÏÍÁÔÉÞÅÓËÏÅ ÐÏÌÅ ÍÏÖÅÔ ÂÙÔØ ÔÏÌØËÏ ÏÄÎÏ É ÄÏÌÖÎÏ ÂÙÔØ ËÌÀÞÏÍ",
-"%-.64s: îÁ Ó×ÑÚÉ!\n",
-"%-.64s: îÏÒÍÁÌØÎÏÅ ÚÁ×ÅÒÛÅÎÉÅ\n",
-"%-.64s: ðÏÌÕÞÅÎ ÓÉÇÎÁÌ %d. õÍÙ×ÁÀ ÒÕËÉ!\n",
-"%-.64s: ïÔËÌÀÞÅÎÉÅ ×ÙÐÏÌÎÅÎÏ\n",
-"%-.64s: ðÒÉÎÕÄÉÔÅÌØÎÏÅ ÐÒÅËÒÁÝÅÎÉÅ ÎÉÔÉ %ld ÐÏÌØÚÏ×ÁÔÅÌÑ: '%-.64s'\n",
-"îÅ ÍÏÇÕ ÓÏÚÄÁÔØ IP socket",
-"ôÁÂÌÉÃÁ '%-.64s' ÉÍÅÅÔ ÉÎÄÅËÓ, ÎÅ ÓÏ×ÐÁÄÁÀÝÉÊ Ó ÕËÁÚÁÎÎÙÍ × CREATE INDEX. óÏÚÄÁÊÔÅ ÔÁÂÌÉÃÕ ÅÝÅ ÒÁÚ",
-"òÁÚÄÅÌÉÔÅÌÉ ÐÏÌÅÊ ÎÅ ÓÏ×ÐÁÄÁÀÔ Ó ÏÖÉÄÁÅÍÙÍÉ. ðÒÏÞÔÉÔÅ ÎÁËÏÎÅà ÉÎÓÔÒÕËÃÉÀ!",
-"îÅÌØÚÑ ÓÓÙÌÁÔØÓÑ ÎÁ ÆÉËÓÉÒÏ×ÁÎÎÕÀ ÄÌÉÎÕ ÓÔÒÏËÉ × BLOB. éÓÐÏÌØÚÕÊÔÅ 'fields terminated by'.",
-"æÁÊÌ '%-.64s' ÄÏÌÖÅÎ ÂÙÔØ × ËÁÔÁÌÏÇÅ ÂÁÚ ÌÉÂÏ ÄÏÓÔÕÐÅÎ ×ÓÅÍ ÄÌÑ ÞÔÅÎÉÑ",
-"æÁÊÌ '%-.64s' ÕÖÅ ÅÓÔØ",
+"óÔÏÌÂÅÃ '%-.64s' × %-.64s ÚÁÄÁÎ ÎÅÏÄÎÏÚÎÁÞÎÏ",
+"óÅÒ×ÅÒ ÎÁÈÏÄÉÔÓÑ × ÐÒÏÃÅÓÓÅ ÏÓÔÁÎÏ×ËÉ",
+"îÅÉÚ×ÅÓÔÎÙÊ ÓÔÏÌÂÅà '%-.64s' × '%-.64s'",
+"'%-.64s' ÎÅ ÐÒÉÓÕÔÓÔ×ÕÅÔ × GROUP BY",
+"îÅ×ÏÚÍÏÖÎÏ ÐÒÏÉÚ×ÅÓÔÉ ÇÒÕÐÐÉÒÏ×ËÕ ÐÏ '%-.64s'",
+"÷ÙÒÁÖÅÎÉÅ ÓÏÄÅÒÖÉÔ ÇÒÕÐÐÏ×ÙÅ ÆÕÎËÃÉÉ É ÓÔÏÌÂÃÙ, ÎÏ ÎÅ ×ËÌÀÞÁÅÔ GROUP BY. á ËÁË ×Ù ÕÍÕÄÒÉÌÉÓØ ÐÏÌÕÞÉÔØ ÜÔÏ ÓÏÏÂÝÅÎÉÅ Ï ÏÛÉÂËÅ?",
+"ëÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ× ÎÅ ÓÏ×ÐÁÄÁÅÔ Ó ËÏÌÉÞÅÓÔ×ÏÍ ÚÎÁÞÅÎÉÊ",
+"óÌÉÛËÏÍ ÄÌÉÎÎÙÊ ÉÄÅÎÔÉÆÉËÁÔÏÒ '%-.100s'",
+"äÕÂÌÉÒÕÀÝÅÅÓÑ ÉÍÑ ÓÔÏÌÂÃÁ '%-.64s'",
+"äÕÂÌÉÒÕÀÝÅÅÓÑ ÉÍÑ ËÌÀÞÁ '%-.64s'",
+"äÕÂÌÉÒÕÀÝÁÑÓÑ ÚÁÐÉÓØ '%-.64s' ÐÏ ËÌÀÞÕ %d",
+"îÅËÏÒÒÅËÔÎÙÊ ÏÐÒÅÄÅÌÉÔÅÌØ ÓÔÏÌÂÃÁ ÄÌÑ ÓÔÏÌÂÃÁ '%-.64s'",
+"%s ÏËÏÌÏ '%-.80s' ÎÁ ÓÔÒÏËÅ %d",
+"úÁÐÒÏÓ ÏËÁÚÁÌÓÑ ÐÕÓÔÙÍ",
+"ðÏ×ÔÏÒÑÀÝÁÑÓÑ ÔÁÂÌÉÃÁ/ÐÓÅ×ÄÏÎÉÍ '%-.64s'",
+"îÅËÏÒÒÅËÔÎÏÅ ÚÎÁÞÅÎÉÅ ÐÏ ÕÍÏÌÞÁÎÉÀ ÄÌÑ '%-.64s'",
+"õËÁÚÁÎÏ ÎÅÓËÏÌØËÏ ÐÅÒ×ÉÞÎÙÈ ËÌÀÞÅÊ",
+"õËÁÚÁÎÏ ÓÌÉÛËÏÍ ÍÎÏÇÏ ËÌÀÞÅÊ. òÁÚÒÅÛÁÅÔÓÑ ÕËÁÚÙ×ÁÔØ ÎÅ ÂÏÌÅÅ %d ËÌÀÞÅÊ",
+"õËÁÚÁÎÏ ÓÌÉÛËÏÍ ÍÎÏÇÏ ÞÁÓÔÅÊ ÓÏÓÔÁ×ÎÏÇÏ ËÌÀÞÁ. òÁÚÒÅÛÁÅÔÓÑ ÕËÁÚÙ×ÁÔØ ÎÅ ÂÏÌÅÅ %d ÞÁÓÔÅÊ",
+"õËÁÚÁÎ ÓÌÉÛËÏÍ ÄÌÉÎÎÙÊ ËÌÀÞ. íÁËÓÉÍÁÌØÎÁÑ ÄÌÉÎÁ ËÌÀÞÁ ÓÏÓÔÁ×ÌÑÅÔ %d",
+"ëÌÀÞÅ×ÏÊ ÓÔÏÌÂÅà '%-.64s' × ÔÁÂÌÉÃÅ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ",
+"óÔÏÌÂÅà ÔÉÐÁ BLOB '%-.64s' ÎÅ ÍÏÖÅÔ ÂÙÔØ ÉÓÐÏÌØÚÏ×ÁÎ ËÁË ÚÎÁÞÅÎÉÅ ËÌÀÞÁ × ÔÁÂÌÉÃÅ ÔÁËÏÇÏ ÔÉÐÁ",
+"óÌÉÛËÏÍ ÂÏÌØÛÁÑ ÄÌÉÎÁ ÓÔÏÌÂÃÁ '%-.64s' (ÍÁËÓÉÍÕÍ = %d). éÓÐÏÌØÚÕÊÔÅ ÔÉÐ BLOB ×ÍÅÓÔÏ ÔÅËÕÝÅÇÏ",
+"îÅËÏÒÒÅËÔÎÏÅ ÏÐÒÅÄÅÌÅÎÉÅ ÔÁÂÌÉÃÙ: ÍÏÖÅÔ ÓÕÝÅÓÔ×Ï×ÁÔØ ÔÏÌØËÏ ÏÄÉÎ Á×ÔÏÉÎËÒÅÍÅÎÔÎÙÊ ÓÔÏÌÂÅÃ, É ÏÎ ÄÏÌÖÅÎ ÂÙÔØ ÏÐÒÅÄÅÌÅÎ ËÁË ËÌÀÞ",
+"%s: çÏÔÏ× ÐÒÉÎÉÍÁÔØ ÓÏÅÄÉÎÅÎÉÑ.\n÷ÅÒÓÉÑ: '%s' ÓÏËÅÔ: '%s' ÐÏÒÔ: %d\n",
+"%s: ëÏÒÒÅËÔÎÁÑ ÏÓÔÁÎÏ×ËÁ\n",
+"%s: ðÏÌÕÞÅÎ ÓÉÇÎÁÌ %d. ðÒÅËÒÁÝÁÅÍ!\n",
+"%s: ïÓÔÁÎÏ×ËÁ ÚÁ×ÅÒÛÅÎÁ\n",
+"%s: ðÒÉÎÕÄÉÔÅÌØÎÏ ÚÁËÒÙ×ÁÅÍ ÐÏÔÏË %ld ÐÏÌØÚÏ×ÁÔÅÌÑ: '%-.32s'\n",
+"îÅ×ÏÚÍÏÖÎÏ ÓÏÚÄÁÔØ IP-ÓÏËÅÔ",
+"÷ ÔÁÂÌÉÃÅ '%-.64s' ÎÅÔ ÔÁËÏÇÏ ÉÎÄÅËÓÁ, ËÁË × CREATE INDEX. óÏÚÄÁÊÔÅ ÔÁÂÌÉÃÕ ÚÁÎÏ×Ï",
+"áÒÇÕÍÅÎÔ ÒÁÚÄÅÌÉÔÅÌÑ ÐÏÌÅÊ - ÎÅ ÔÏÔ, ËÏÔÏÒÙÊ ÏÖÉÄÁÌÓÑ. ïÂÒÁÝÁÊÔÅÓØ Ë ÄÏËÕÍÅÎÔÁÃÉÉ",
+"æÉËÓÉÒÏ×ÁÎÎÙÊ ÒÁÚÍÅÒ ÚÁÐÉÓÉ Ó ÐÏÌÑÍÉ ÔÉÐÁ BLOB ÉÓÐÏÌØÚÏ×ÁÔØ ÎÅÌØÚÑ. ðÒÉÍÅÎÑÊÔÅ 'fields terminated by'.",
+"æÁÊÌ '%-.64s' ÄÏÌÖÅÎ ÎÁÈÏÄÉÔØÓÑ × ÔÏÍ ÖÅ ËÁÔÁÌÏÇÅ, ÞÔÏ É ÂÁÚÁ ÄÁÎÎÙÈ, ÉÌÉ ÂÙÔØ ÏÂÝÅÄÏÓÔÕÐÎÙÍ ÄÌÑ ÞÔÅÎÉÑ",
+"æÁÊÌ '%-.80s' ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ",
"úÁÐÉÓÅÊ: %ld õÄÁÌÅÎÏ: %ld ðÒÏÐÕÝÅÎÏ: %ld ðÒÅÄÕÐÒÅÖÄÅÎÉÊ: %ld",
-"úÁÐÉÓÅÊ: %ld äÕÂÌÅÊ: %ld",
-"îÅ×ÅÒÎÁÑ ÓÏÓÔÁ×ÌÑÀÝÁÑ ËÌÀÞÁ. äÁÎÎÁÑ ÓÏÓÔÁ×ÌÑÀÝÁÑ ÌÉÂÏ ÎÅ ÓÔÒÏËÏ×ÁÑ, ÌÉÂÏ ÂÏÌØÛÅ, ÞÅÍ ÍÏÖÅÔ ÂÙÔØ",
-"îÅÌØÚÑ ÕÄÁÌÉÔØ ×ÓÅ ÐÏÌÑ ÞÅÒÅÚ ALTER TABLE. ÷ÏÓÐÏÌØÚÕÊÔÅÓØ DROP TABLE",
-"îÅ ÍÏÇÕ ÓÂÒÏÓÉÔØ '%-.64s'. ðÒÏ×ÅÒØÔÅ, ÞÔÏ ÜÔÏ ÐÏÌÅ/ËÌÀÞ ÓÕÝÅÓÔ×ÕÀÔ",
-"úÁÐÉÓÅÊ: %ld äÕÂÌÅÊ: %ld ðÒÅÄÕÐÒÅÖÄÅÎÉÊ: %ld",
-"INSERT TABLE '%-.64s' ÎÅ ÒÁÚÒÅÛÅÎÏ × ÓÐÉÓËÅ FROM TABLE",
-"îÅÉÚ×ÅÓÔÎÁÑ ÎÉÔØ: %lu",
-"÷Ù ÎÅ ×ÌÁÄÅÌÅà ÎÉÔÉ %lu",
-"ôÁÂÌÉÃÙ ÎÅ ÉÓÐÏÌØÚÏ×ÁÎÙ",
-"ïÞÅÎØ ÍÎÏÇÏ ÓÔÒÏË ÄÌÑ ÐÏÌÑ %-.64s É SET",
-"îÅ ÍÏÇÕ ÓÏÚÄÁÔØ ÕÎÉËÁÌØÎÙÊ ÌÏÇ-ÆÁÊÌ %-.64s.(1-999)\n",
-"ôÁÂÌÉÃÁ '%-.64s' ÚÁÂÌÏËÉÒÏ×ÁÎÁ READ É ÎÅ ÍÏÖÅÔ ÂÙÔØ ÏÂÎÏ×ÌÅÎÁ",
-"ôÁÂÌÉÃÁ '%-.64s' ÎÅ ÂÙÌÁ ÂÌÏËÉÒÏ×ÁÎÁ LOCK TABLES",
-"ïÂßÅËÔ BLOB '%-.64s' ÎÅ ÍÏÖÅÔ ÉÍÅÅÔ ÚÎÁÞÅÎÉÊ ÐÏ ÕÍÏÌÞÁÎÉÀ",
-"îÅÄÏÐÕÓÔÉÍÏÅ ÉÍÑ ÂÁÚÙ '%-.64s'",
-"îÅÄÏÐÕÓÔÉÍÏÅ ÉÍÑ ÔÁÂÌÉÃÙ '%-.64s'",
-"SELECT ÏÂÒÁÂÏÔÁÅÔ ÏÞÅÎØ ÍÎÏÇÏ ÚÁÐÉÓÅÊ É ÜÔÏ îáäïìçï. ðÒÏ×ÅÒØÔÅ ÕÓÌÏ×ÉÅ WHERE É ×ÏÓÐÏÌØÚÕÊÔÅÓØ SQL_OPTION BIG_SELECTS=1 ÅÓÌÉ SELECT ËÏÒÒÅËÔÅÎ",
+"úÁÐÉÓÅÊ: %ld äÕÂÌÉËÁÔÏ×: %ld",
+"îÅËÏÒÒÅËÔÎÁÑ ÞÁÓÔØ ËÌÀÞÁ. éÓÐÏÌØÚÕÅÍÁÑ ÞÁÓÔØ ËÌÀÞÁ ÎÅ Ñ×ÌÑÅÔÓÑ ÓÔÒÏËÏÊ, ÕËÁÚÁÎÎÁÑ ÄÌÉÎÁ ÂÏÌØÛÅ, ÞÅÍ ÄÌÉÎÁ ÞÁÓÔÉ ËÌÀÞÁ, ÉÌÉ ÏÂÒÁÂÏÔÞÉË ÔÁÂÌÉÃÙ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÕÎÉËÁÌØÎÙÅ ÞÁÓÔÉ ËÌÀÞÁ",
+"îÅÌØÚÑ ÕÄÁÌÉÔØ ×ÓÅ ÓÔÏÌÂÃÙ Ó ÐÏÍÏÝØÀ ALTER TABLE. éÓÐÏÌØÚÕÊÔÅ DROP TABLE",
+"îÅ×ÏÚÍÏÖÎÏ ÕÄÁÌÉÔØ (DROP) '%-.64s'. õÂÅÄÉÔÅÓØ ÞÔÏ ÓÔÏÌÂÅÃ/ËÌÀÞ ÄÅÊÓÔ×ÉÔÅÌØÎÏ ÓÕÝÅÓÔ×ÕÅÔ",
+"úÁÐÉÓÅÊ: %ld äÕÂÌÉËÁÔÏ×: %ld ðÒÅÄÕÐÒÅÖÄÅÎÉÊ: %ld",
+"îÅ ÄÏÐÕÓËÁÅÔÓÑ ÕËÁÚÁÎÉÅ ÔÁÂÌÉÃÙ '%-.64s' × ÓÐÉÓËÅ ÔÁÂÌÉà FROM ÄÌÑ ×ÎÅÓÅÎÉÑ × ÎÅÅ ÉÚÍÅÎÅÎÉÊ",
+"îÅÉÚ×ÅÓÔÎÙÊ ÎÏÍÅÒ ÐÏÔÏËÁ: %lu",
+"÷Ù ÎÅ Ñ×ÌÑÅÔÅÓØ ×ÌÁÄÅÌØÃÅÍ ÐÏÔÏËÁ %lu",
+"îÉËÁËÉÅ ÔÁÂÌÉÃÙ ÎÅ ÉÓÐÏÌØÚÏ×ÁÎÙ",
+"óÌÉÛËÏÍ ÍÎÏÇÏ ÚÎÁÞÅÎÉÊ ÄÌÑ ÓÔÏÌÂÃÁ %-.64s × SET",
+"îÅ×ÏÚÍÏÖÎÏ ÓÏÚÄÁÔØ ÕÎÉËÁÌØÎÏÅ ÉÍÑ ÆÁÊÌÁ ÖÕÒÎÁÌÁ %-.64s.(1-999)\n",
+"ôÁÂÌÉÃÁ '%-.64s' ÚÁÂÌÏËÉÒÏ×ÁÎÁ ÕÒÏ×ÎÅÍ READ lock É ÎÅ ÍÏÖÅÔ ÂÙÔØ ÉÚÍÅÎÅÎÁ",
+"ôÁÂÌÉÃÁ '%-.64s' ÎÅ ÂÙÌÁ ÚÁÂÌÏËÉÒÏ×ÁÎÁ Ó ÐÏÍÏÝØÀ LOCK TABLES",
+"îÅ×ÏÚÍÏÖÎÏ ÕËÁÚÙ×ÁÔØ ÚÎÁÞÅÎÉÅ ÐÏ ÕÍÏÌÞÁÎÉÀ ÄÌÑ ÓÔÏÌÂÃÁ BLOB '%-.64s'",
+"îÅËÏÒÒÅËÔÎÏÅ ÉÍÑ ÂÁÚÙ ÄÁÎÎÙÈ '%-.100s'",
+"îÅËÏÒÒÅËÔÎÏÅ ÉÍÑ ÔÁÂÌÉÃÙ '%-.100s'",
+"äÌÑ ÔÁËÏÊ ×ÙÂÏÒËÉ SELECT ÄÏÌÖÅÎ ÂÕÄÅÔ ÐÒÏÓÍÏÔÒÅÔØ ÓÌÉÛËÏÍ ÍÎÏÇÏ ÚÁÐÉÓÅÊ É, ×ÉÄÉÍÏ, ÜÔÏ ÚÁÊÍÅÔ ÏÞÅÎØ ÍÎÏÇÏ ×ÒÅÍÅÎÉ. ðÒÏ×ÅÒØÔÅ ×ÁÛÅ ÕËÁÚÁÎÉÅ WHERE, É, ÅÓÌÉ × ÎÅÍ ×ÓÅ × ÐÏÒÑÄËÅ, ÕËÁÖÉÔÅ SET SQL_BIG_SELECTS=1",
"îÅÉÚ×ÅÓÔÎÁÑ ÏÛÉÂËÁ",
-"îÅÉÚ×ÅÓÔÎÁÑ ÐÒÏÃÅÄÕÒÁ %-.64s",
-"îÅ×ÅÒÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÐÁÒÁÍÅÔÒÏ× × ×ÙÚÏ×Å %-.64s",
-"îÅ×ÅÒÎÙÅ ÐÁÒÁÍÅÔÒÙ × ÐÒÏÃÅÄÕÒÅ %-.64s",
-"îÅÉÚ×ÅÓÔÎÁÑ ÔÁÂÌÉÃÁ '%-.64s' × %-.64s",
-"ðÏÌÅ '%-.64s' ÏÂßÑ×ÌÅÎÎÏ Ä×ÁÖÄÙ",
-"îÅ×ÅÒÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ ÇÒÕÐÐÏ×ÏÊ ÆÕÎËÃÉÉ",
-"ôÁÂÌÉÃÁ '%-.64s' ÉÓÐÏÌØÚÕÅÔ ÒÁÓÛÉÒÅÎÉÅ, ÎÅ ÓÕÝÅÓÔ×ÕÀÝÅÅ × ÄÁÎÎÏÊ ×ÅÒÓÉÉ MySQL",
-"÷ ÔÁÂÌÉÃÅ ÄÏÌÖÎÏ ÂÙÔØ ÈÏÔÑ ÂÙ ÏÄÎÏ ÐÏÌÅ",
+"îÅÉÚ×ÅÓÔÎÁÑ ÐÒÏÃÅÄÕÒÁ '%-.64s'",
+"îÅËÏÒÒÅËÔÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÐÁÒÁÍÅÔÒÏ× ÄÌÑ ÐÒÏÃÅÄÕÒÙ '%-.64s'",
+"îÅËÏÒÒÅËÔÎÙÅ ÐÁÒÁÍÅÔÒÙ ÄÌÑ ÐÒÏÃÅÄÕÒÙ '%-.64s'",
+"îÅÉÚ×ÅÓÔÎÁÑ ÔÁÂÌÉÃÁ '%-.64s' × %-.32s",
+"óÔÏÌÂÅà '%-.64s' ÕËÁÚÁÎ Ä×ÁÖÄÙ",
+"îÅÐÒÁ×ÉÌØÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ ÇÒÕÐÐÏ×ÙÈ ÆÕÎËÃÉÊ",
+"÷ ÔÁÂÌÉÃÅ '%-.64s' ÉÓÐÏÌØÚÕÀÔÓÑ ×ÏÚÍÏÖÎÏÓÔÉ, ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÍÙÅ × ÜÔÏÊ ×ÅÒÓÉÉ MySQL",
+"÷ ÔÁÂÌÉÃÅ ÄÏÌÖÅÎ ÂÙÔØ ËÁË ÍÉÎÉÍÕÍ ÏÄÉÎ ÓÔÏÌÂÅÃ",
"ôÁÂÌÉÃÁ '%-.64s' ÐÅÒÅÐÏÌÎÅÎÁ",
-"îÅÉÚ×ÅÓÔÎÙÊ ÎÁÂÏÒ ÓÉÍ×ÏÌÏ×: '%-.64s'",
-"óÌÉÛËÏÍ ÍÎÏÇÏ ÔÁÂÌÉÃ. MySQL ÍÏÖÅÔ ÉÓÐÏÌØÚÏ×ÁÔØ ÔÏÌØËÏ %d ÔÁÂÌÉÃ × ÏÂßÅÄÉÎÅÎÉÉ",
-"óÌÉÛËÏÍ ÍÎÏÇÏ ÐÏÌÅÊ",
-"óÌÉÛËÏÍ ÂÏÌØÛÏÊ ÒÁÚÍÅÒ ÚÁÐÉÓÉ. íÁËÓÉÍÁÌØÎÙÊ ÒÁÚÍÅÒ ÚÁÐÉÓÉ - %d, ÎÅ ÓÞÉÔÁÑ blob. úÁÍÅÎÉÔÅ ÎÅËÏÔÏÒÙÅ ÐÏÌÑ ÎÁ blob",
-"ðÅÒÅÐÏÌÎÅÎÉÅ ÎÉÔÅ×ÏÇÏ ÓÔÅËÁ: éÓÐÏÌØÚÏ×ÁÎÏ %ld ÉÚ %ld. åÓÌÉ ÎÅÏÂÈÏÄÉÍÏ, ÉÓÐÏÌØÚÕÊÔÅ 'mysqld -O thread_stack=#' ÞÔÏÂÙ Õ×ÅÌÉÞÉÔØ ÒÁÚÍÅÒ ÓÔÅËÁ",
-"ðÅÒÅËÒÅÓÔÎÁÑ ÚÁ×ÉÓÉÍÏÓÔØ × OUTER JOIN. ðÒÏ×ÅÒØÔÅ ÕÓÌÏ×ÉÑ ON",
-"ðÏÌÅ '%-.32s' ÉÓÐÏÌØÚÕÅÔÓÑ ËÁË UNIQUE ÉÌÉ INDEX ÎÏ ÎÅ ÏÐÒÅÄÅÌÅÎÏ ËÁË NOT NULL",
-"îÅ ÍÏÇÕ ÚÁÇÒÕÚÉÔØ ÆÕÎËÃÉÀ '%-.64s'",
-"îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÆÕÎËÃÉÀ '%-.64s'; %-.80s",
-"îÅÌØÚÑ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÕÔÉ ÄÌÑ ÒÁÚÄÅÌÑÅÍÙÈ ÂÉÂÌÉÏÔÅË",
+"îÅÉÚ×ÅÓÔÎÁÑ ËÏÄÉÒÏ×ËÁ '%-.64s'",
+"óÌÉÛËÏÍ ÍÎÏÇÏ ÔÁÂÌÉÃ. MySQL ÍÏÖÅÔ ÉÓÐÏÌØÚÏ×ÁÔØ ÔÏÌØËÏ %d ÔÁÂÌÉÃ × ÓÏÅÄÉÎÅÎÉÉ",
+"óÌÉÛËÏÍ ÍÎÏÇÏ ÓÔÏÌÂÃÏ×",
+"óÌÉÛËÏÍ ÂÏÌØÛÏÊ ÒÁÚÍÅÒ ÚÁÐÉÓÉ. íÁËÓÉÍÁÌØÎÙÊ ÒÁÚÍÅÒ ÓÔÒÏËÉ, ÉÓËÌÀÞÁÑ ÐÏÌÑ BLOB, - %d. ÷ÏÚÍÏÖÎÏ, ×ÁÍ ÓÌÅÄÕÅÔ ÉÚÍÅÎÉÔØ ÔÉÐ ÎÅËÏÔÏÒÙÈ ÐÏÌÅÊ ÎÁ BLOB",
+"óÔÅË ÐÏÔÏËÏ× ÐÅÒÅÐÏÌÎÅÎ: ÉÓÐÏÌØÚÏ×ÁÎÏ: %ld ÉÚ %ld ÓÔÅËÁ. ðÒÉÍÅÎÑÊÔÅ 'mysqld -O thread_stack=#' ÄÌÑ ÕËÁÚÁÎÉÑ ÂÏÌØÛÅÇÏ ÒÁÚÍÅÒÁ ÓÔÅËÁ, ÅÓÌÉ ÎÅÏÂÈÏÄÉÍÏ",
+"÷ OUTER JOIN ÏÂÎÁÒÕÖÅÎÁ ÐÅÒÅËÒÅÓÔÎÁÑ ÚÁ×ÉÓÉÍÏÓÔØ. ÷ÎÉÍÁÔÅÌØÎÏ ÐÒÏÁÎÁÌÉÚÉÒÕÊÔÅ Ó×ÏÉ ÕÓÌÏ×ÉÑ ON",
+"óÔÏÌÂÅÃ '%-.64s' ÉÓÐÏÌØÚÕÅÔÓÑ × UNIQUE ÉÌÉ × INDEX, ÎÏ ÎÅ ÏÐÒÅÄÅÌÅÎ ËÁË NOT NULL",
+"îÅ×ÏÚÍÏÖÎÏ ÚÁÇÒÕÚÉÔØ ÆÕÎËÃÉÀ '%-.64s'",
+"îÅ×ÏÚÍÏÖÎÏ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÆÕÎËÃÉÀ '%-.64s'; %-.80s",
+"îÅÄÏÐÕÓÔÉÍÏ ÕËÁÚÙ×ÁÔØ ÐÕÔÉ ÄÌÑ ÄÉÎÁÍÉÞÅÓËÉÈ ÂÉÂÌÉÏÔÅË",
"æÕÎËÃÉÑ '%-.64s' ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ",
-"îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÒÁÚÄÅÌÑÅÍÕÀ ÂÉÂÌÉÏÔÅËÕ '%-.64s' (ïÛÉÂËÁ: %d %-.64s)",
-"îÅ ÍÏÇÕ ÎÁÊÔÉ ÆÕÎËÃÉÀ '%-.64s' × ÂÉÂÌÉÏÔÅËÅ'",
+"îÅ×ÏÚÍÏÖÎÏ ÏÔËÒÙÔØ ÄÉÎÁÍÉÞÅÓËÕÀ ÂÉÂÌÉÏÔÅËÕ '%-.64s' (ÏÛÉÂËÁ: %d %-.64s)",
+"îÅ×ÏÚÍÏÖÎÏ ÏÔÙÓËÁÔØ ÆÕÎËÃÉÀ '%-.64s' × ÂÉÂÌÉÏÔÅËÅ",
"æÕÎËÃÉÑ '%-.64s' ÎÅ ÏÐÒÅÄÅÌÅÎÁ",
-"èÏÓÔ '%-.64s' ÚÁÂÌÏËÉÒÏ×ÁÎ ÉÚ-ÚÁ ÏÂÉÌÉÑ ÏÛÉÂÏË ÓÏÅÄÉÎÅÎÉÑ. òÁÚÂÌÏËÉÒÏ×ÁÔØ ÍÏÖÎÏ Ó ÐÏÍÏÝØÀ 'mysqladmin flush-hosts'",
-"èÏÓÔÕ '%-.64s' ÎÅ ÒÁÚÒÅÛÅÎÏ ÓÏÅÄÉÎÑÔØÓÑ Ó ÄÁÎÎÙÍ ÓÅÒ×ÅÒÏÍ MySQL",
-"÷Ù ÐÏÄËÌÀÞÅÎÙ Ë MySQL ËÁË ÁÎÏÎÉÍÎÙÊ ÐÏÌØÚÏ×ÁÔÅÌØ É ÷ÁÍ ÎÅ ÒÁÚÒÅÛÅÎÏ ÉÚÍÅÎÑÔØ ÐÁÒÏÌÉ",
-"÷Ù ÄÏÌÖÎÙ ÉÍÅÔØ ÐÒÁ×Á ÎÁ ÏÂÎÏ×ÌÅÎÉÅ ÔÁÂÌÉÃ × ÂÁÚÅ, ÞÔÏÂÙ ÉÚÍÅÎÉÔØ ÐÁÒÏÌØ ÄÒÕÇÉÍ ÐÏÌØÚÏ×ÁÔÅÌÑÍ",
-"îÅ ÍÏÇÕ ÎÁÊÔÉ ÎÉ ÏÄÎÏÇÏ ÓÏÏÔ×ÅÔÓÔ×ÉÑ × ÔÁÂÌÉÃÅ ÐÏÌØÚÏ×ÁÔÅÌÅÊ",
-"óÏÏÔ×ÅÔÓÔ×ÕÀÝÉÈ ÚÁÐÉÓÅÊ: %ld éÚÍÅÎÅÎÏ: %ld ðÒÅÄÕÐÒÅÖÄÅÎÉÊ: %ld",
-"îÅ ÍÏÇÕ ÓÏÚÄÁÔØ ÎÏ×ÕÀ ÎÉÔØ (ÏÛÉÂËÁ %d). åÓÌÉ ÜÔÏ ÎÅ ÉÚ-ÚÁ ÎÅÈ×ÁÔËÉ ÐÁÍÑÔÉ, ÐÏÓÍÏÔÒÉÔÅ × ÒÕËÏ×ÏÄÓÔ×Å ×ÏÚÍÏÖÎÙÅ OS-ÚÁ×ÉÓÉÍÙÅ ÇÌÀËÉ",
-"þÉÓÌÏ ÓÔÏÌÂÃÏ× ÎÅ ÓÏÏÔ×ÅÔÓÔ×ÕÅÔ ÞÉÓÌÕ ÚÎÁÞÅÎÉÊ × ÓÔÒÏËÅ %ld",
-"îÅ ÍÏÇÕ ÚÁÎÏ×Ï ÏÔËÒÙÔØ ÔÁÂÌÉÃÕ: '%-.64s",
-"îÅÐÒÁ×ÉÌØÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ ÚÎÁÞÅÎÉÑ NULL",
-"REGEXP ×ÅÒÎÕÌ ÏÛÉÂËÕ '%-.64s'",
-"éÓÐÏÌØÚÏ×ÁÎÉÅ ÁÇÒÅÇÁÔÎÙÈ ÆÕÎËÃÉÊ (MIN(),MAX(),COUNT()...) ÓÏ×ÍÅÓÔÎÏ Ó ÏÂÙÞÎÙÍÉ ÚÎÁÞÅÎÉÑÍÉ ×ÏÚÍÏÖÎÏ ÔÏÌØËÏ ÐÒÉ ÎÁÌÉÞÉÉ ÒÁÚÄÅÌÁ GROUP BY",
-"äÌÑ ÐÏÌØÚÏ×ÁÔÅÌÑ '%-.32s' Ó ÈÏÓÔÁ '%-.64s' ÐÒÉ×ÉÌÅÇÉÉ ÎÅ ÏÐÒÅÄÅÌÅÎÙ",
-"%-.16s ËÏÍÁÎÄÁ ÎÅ ÒÁÚÒÅÛÅÎÁ ÐÏÌØÚÏ×ÁÔÅÌÀ: '%-.32s@%-.64s' ÄÌÑ ÔÁÂÌÉÃÙ '%-.64s'",
-"%-.16s ËÏÍÁÎÄÁ ÎÅ ÒÁÚÒÅÛÅÎÁ ÐÏÌØÚÏ×ÁÔÅÌÀ: '%-.32s@%-.64s'\n ÄÌÑ ÐÏÌÑ '%-.64s' ÉÚ ÔÁÂÌÉÃÙ '%-.64s'",
-"úÁÄÁÎÙ ÎÅ×ÅÒÎÙÅ ÐÒÉ×ÉÌÅÇÉÉ ÄÌÑ ÔÁÂÌÉÃÙ",
-"éÍÑ ÈÏÓÔÁ ÉÌÉ ÐÏÌØÚÏ×ÁÔÅÌÑ ÓÌÉÛËÏÍ ×ÅÌÉËÏ ÄÌÑ ÔÁÂÌÉÃÙ ÐÒÉ×ÉÌÅÇÉÊ",
+"èÏÓÔ '%-.64s' ÚÁÂÌÏËÉÒÏ×ÁÎ ÉÚ-ÚÁ ÓÌÉÛËÏÍ ÂÏÌØÛÏÇÏ ËÏÌÉÞÅÓÔ×Á ÏÛÉÂÏË ÓÏÅÄÉÎÅÎÉÑ. òÁÚÂÌÏËÉÒÏ×ÁÔØ ÅÇÏ ÍÏÖÎÏ Ó ÐÏÍÏÝØÀ 'mysqladmin flush-hosts'",
+"èÏÓÔÕ '%-.64s' ÎÅ ÒÁÚÒÅÛÁÅÔÓÑ ÐÏÄËÌÀÞÁÔØÓÑ Ë ÜÔÏÍÕ ÓÅÒ×ÅÒÕ MySQL",
+"÷Ù ÉÓÐÏÌØÚÕÅÔÅ MySQL ÏÔ ÉÍÅÎÉ ÁÎÏÎÉÍÎÏÇÏ ÐÏÌØÚÏ×ÁÔÅÌÑ, Á ÁÎÏÎÉÍÎÙÍ ÐÏÌØÚÏ×ÁÔÅÌÑÍ ÎÅ ÒÁÚÒÅÛÁÅÔÓÑ ÍÅÎÑÔØ ÐÁÒÏÌÉ",
+"äÌÑ ÔÏÇÏ ÞÔÏÂÙ ÉÚÍÅÎÑÔØ ÐÁÒÏÌÉ ÄÒÕÇÉÈ ÐÏÌØÚÏ×ÁÔÅÌÅÊ, Õ ×ÁÓ ÄÏÌÖÎÙ ÂÙÔØ ÐÒÉ×ÉÌÅÇÉÉ ÎÁ ÉÚÍÅÎÅÎÉÅ ÔÁÂÌÉÃ × ÂÁÚÅ ÄÁÎÎÙÈ mysql",
+"îÅ×ÏÚÍÏÖÎÏ ÏÔÙÓËÁÔØ ÐÏÄÈÏÄÑÝÕÀ ÚÁÐÉÓØ × ÔÁÂÌÉÃÅ ÐÏÌØÚÏ×ÁÔÅÌÅÊ",
+"óÏ×ÐÁÌÏ ÚÁÐÉÓÅÊ: %ld éÚÍÅÎÅÎÏ: %ld ðÒÅÄÕÐÒÅÖÄÅÎÉÊ: %ld",
+"îÅ×ÏÚÍÏÖÎÏ ÓÏÚÄÁÔØ ÎÏ×ÙÊ ÐÏÔÏË (ÏÛÉÂËÁ %d). åÓÌÉ ÜÔÏ ÎÅ ÓÉÔÕÁÃÉÑ, Ó×ÑÚÁÎÎÁÑ Ó ÎÅÈ×ÁÔËÏÊ ÐÁÍÑÔÉ, ÔÏ ×ÁÍ ÓÌÅÄÕÅÔ ÉÚÕÞÉÔØ ÄÏËÕÍÅÎÔÁÃÉÀ ÎÁ ÐÒÅÄÍÅÔ ÏÐÉÓÁÎÉÑ ×ÏÚÍÏÖÎÏÊ ÏÛÉÂËÉ ÒÁÂÏÔÙ × ËÏÎËÒÅÔÎÏÊ ïó",
+"ëÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ× ÎÅ ÓÏ×ÐÁÄÁÅÔ Ó ËÏÌÉÞÅÓÔ×ÏÍ ÚÎÁÞÅÎÉÊ × ÚÁÐÉÓÉ %ld",
+"îÅ×ÏÚÍÏÖÎÏ ÚÁÎÏ×Ï ÏÔËÒÙÔØ ÔÁÂÌÉÃÕ '%-.64s'",
+"îÅÐÒÁ×ÉÌØÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ ×ÅÌÉÞÉÎÙ NULL",
+"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ '%-.64s' ÏÔ ÒÅÇÕÌÑÒÎÏÇÏ ×ÙÒÁÖÅÎÉÑ",
+"ïÄÎÏ×ÒÅÍÅÎÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ ÓÇÒÕÐÐÉÒÏ×ÁÎÎÙÈ (GROUP) ÓÔÏÌÂÃÏ× (MIN(),MAX(),COUNT(),...) Ó ÎÅÓÇÒÕÐÐÉÒÏ×ÁÎÎÙÍÉ ÓÔÏÌÂÃÁÍÉ Ñ×ÌÑÅÔÓÑ ÎÅËÏÒÒÅËÔÎÙÍ, ÅÓÌÉ × ×ÙÒÁÖÅÎÉÉ ÅÓÔØ GROUP BY",
+"ôÁËÉÅ ÐÒÁ×Á ÎÅ ÏÐÒÅÄÅÌÅÎÙ ÄÌÑ ÐÏÌØÚÏ×ÁÔÅÌÑ '%-.32s' ÎÁ ÈÏÓÔÅ '%-.64s'",
+"ëÏÍÁÎÄÁ %-.16s ÚÁÐÒÅÝÅÎÁ ÐÏÌØÚÏ×ÁÔÅÌÀ '%-.32s@%-.64s' ÄÌÑ ÔÁÂÌÉÃÙ '%-.64s'",
+"ëÏÍÁÎÄÁ %-.16s ÚÁÐÒÅÝÅÎÁ ÐÏÌØÚÏ×ÁÔÅÌÀ '%-.32s@%-.64s' ÄÌÑ ÓÔÏÌÂÃÁ '%-.64s' × ÔÁÂÌÉÃÅ '%-.64s'",
+"îÅ×ÅÒÎÁÑ ËÏÍÁÎÄÁ GRANT ÉÌÉ REVOKE. ïÂÒÁÔÉÔÅÓØ Ë ÄÏËÕÍÅÎÔÁÃÉÉ, ÞÔÏÂÙ ×ÙÑÓÎÉÔØ, ËÁËÉÅ ÐÒÉ×ÉÌÅÇÉÉ ÍÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ",
+"óÌÉÛËÏÍ ÄÌÉÎÎÏÅ ÉÍÑ ÐÏÌØÚÏ×ÁÔÅÌÑ/ÈÏÓÔÁ ÄÌÑ GRANT",
"ôÁÂÌÉÃÁ '%-.64s.%-.64s' ÎÅ ÓÕÝÅÓÔ×ÕÅÔ",
-"ðÒÉ×ÉÌÅÇÉÉ ÐÏÌØÚÏ×ÁÔÅÌÑ '%-.32s' Ó ÈÏÓÔÁ '%-.64s' ÄÌÑ ÔÁÂÌÉÃÙ '%-.64s' ÎÅ ÏÐÒÅÄÅÌÅÎÙ",
-"äÁÎÎÁÑ ËÏÍÁÎÄÁ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ ÜÔÏÊ ×ÅÒÓÉÅÊ MySQL",
-"ëÁËÁÑ-ÔÏ ÓÉÎÔÁËÓÉÞÅÓËÁÑ ÏÛÉÂËÁ",
-"ðÏÔÏË ÄÌÑ delayed insert ÎÅ ÍÏÖÅÔ ÐÏÌÕÞÉÔØ ÂÌÏËÉÒÏ×ËÕ ÄÌÑ ÔÁÂÌÉÃÙ %-.64s",
-"éÓÐÏÌØÚÕÅÔÓÑ ÓÌÉÛËÏÍ ÍÎÏÇÏ delayed ÐÏÔÏËÏ×",
-"ðÒÅÒ×ÁÎÎÁÑ Ó×ÑÚØ %ld Ó ÂÁÚÏÊ ÄÁÎÎÙÈ: '%-.64s' ÐÏÌØÚÏ×ÁÔÅÌØ: '%-.64s' (%-.64s)",
-"ðÁËÅÔ ÂÏÌØÛÅ ÞÅÍ 'max_allowed_packet'",
-"ïÛÉÂËÁ ÞÔÅÎÉÑ ÉÚ ÔÒÕÂÙ ËÏÎÎÅËÔÁ",
-"fcntl() ×ÅÒÎÕÌ ÏÛÉÂËÕ",
-"ðÏÌÕÞÅÎ ÐÁËÅÔ × ÎÅÐÒÁ×ÉÌØÎÏÍ ÐÏÒÑÄËÅ",
-"îÅ ÍÏÇÕ ÒÁÓÐÁËÏ×ÁÔØ ÐÁËÅÔ",
-"ïÛÉÂËÁ ÐÒÉ ÞÔÅÎÉÉ ÐÁËÅÔÏ×",
-"ôÁÊÍÁÕÔ ÐÒÉ ÞÔÅÎÉÉ ÐÁËÅÔÏ×",
-"ïÛÉÂËÁ ÐÒÉ ÏÔÐÒÁ×ËÅ ÐÁËÅÔÏ×",
-"ïÛÉÂËÁ ÐÒÉ ÏÔÐÒÁ×ËÅ ÐÁËÅÔÏ×",
-"òÅÚÕÌØÔÉÒÕÀÝÁÑ ÓÔÒÏËÁ ÂÏÌØÛÅ ÞÅÍ max_allowed_packet",
-"éÓÐÏÌØÚÕÅÍÁÑ ÔÁÂÌÉÃÁ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÐÏÌÑ BLOB/TEXT",
-"éÓÐÏÌØÚÕÅÍÁÑ ÔÁÂÌÉÃÁ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÐÏÌÑ AUTO_INCREMENT",
-"INSERT DELAYED ÎÅ ÍÏÖÅÔ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ Ó ÔÁÂÌÉÃÅÊ '%-.64s', ÏÎÁ ÚÁÎÑÔÁ ÉÓÐÏÌØÚÏ×ÁÎÉÅÍ LOCK TABLES",
-"îÅ×ÅÒÎÏÅ ÉÍÑ ÐÏÌÑ '%-.100s'",
-"ôÁÂÌÉÃÁ ÉÓÐÏÌØÚÕÅÍÏÇÏ ÔÉÐÁ ÎÅ ÍÏÖÅÔ ÉÎÄÅËÓÉÒÏ×ÁÔØ ÐÏÌÅ '%-.64s'",
+"ôÁËÉÅ ÐÒÁ×Á ÎÅ ÏÐÒÅÄÅÌÅÎÙ ÄÌÑ ÐÏÌØÚÏ×ÁÔÅÌÑ '%-.32s' ÎÁ ËÏÍÐØÀÔÅÒÅ '%-.64s' ÄÌÑ ÔÁÂÌÉÃÙ '%-.64s'",
+"üÔÁ ËÏÍÁÎÄÁ ÎÅ ÄÏÐÕÓËÁÅÔÓÑ × ÄÁÎÎÏÊ ×ÅÒÓÉÉ MySQL",
+"õ ×ÁÓ ÏÛÉÂËÁ × ÚÁÐÒÏÓÅ. éÚÕÞÉÔÅ ÄÏËÕÍÅÎÔÁÃÉÀ ÐÏ ÉÓÐÏÌØÚÕÅÍÏÊ ×ÅÒÓÉÉ MySQL ÎÁ ÐÒÅÄÍÅÔ ËÏÒÒÅËÔÎÏÇÏ ÓÉÎÔÁËÓÉÓÁ",
+"ðÏÔÏË, ÏÂÓÌÕÖÉ×ÁÀÝÉÊ ÏÔÌÏÖÅÎÎÕÀ ×ÓÔÁ×ËÕ (delayed insert), ÎÅ ÓÍÏÇ ÐÏÌÕÞÉÔØ ÚÁÐÒÁÛÉ×ÁÅÍÕÀ ÂÌÏËÉÒÏ×ËÕ ÎÁ ÔÁÂÌÉÃÕ %-.64s",
+"óÌÉÛËÏÍ ÍÎÏÇÏ ÐÏÔÏËÏ×, ÏÂÓÌÕÖÉ×ÁÀÝÉÈ ÏÔÌÏÖÅÎÎÕÀ ×ÓÔÁ×ËÕ (delayed insert)",
+"ðÒÅÒ×ÁÎÏ ÓÏÅÄÉÎÅÎÉÅ %ld Ë ÂÁÚÅ ÄÁÎÎÙÈ '%-.64s' ÐÏÌØÚÏ×ÁÔÅÌÑ '%-.32s' (%-.64s)",
+"ðÏÌÕÞÅÎÎÙÊ ÐÁËÅÔ ÂÏÌØÛÅ, ÞÅÍ 'max_allowed_packet'",
+"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ ÞÔÅÎÉÑ ÏÔ ÐÏÔÏËÁ ÓÏÅÄÉÎÅÎÉÑ (connection pipe)",
+"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ ÏÔ fcntl()",
+"ðÁËÅÔÙ ÐÏÌÕÞÅÎÙ × ÎÅ×ÅÒÎÏÍ ÐÏÒÑÄËÅ",
+"îÅ×ÏÚÍÏÖÎÏ ÒÁÓÐÁËÏ×ÁÔØ ÐÁËÅÔ, ÐÏÌÕÞÅÎÎÙÊ ÞÅÒÅÚ ËÏÍÍÕÎÉËÁÃÉÏÎÎÙÊ ÐÒÏÔÏËÏÌ",
+"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ × ÐÒÏÃÅÓÓÅ ÐÏÌÕÞÅÎÉÑ ÐÁËÅÔÁ ÞÅÒÅÚ ËÏÍÍÕÎÉËÁÃÉÏÎÎÙÊ ÐÒÏÔÏËÏÌ ",
+"ðÏÌÕÞÅÎ ÔÁÊÍÁÕÔ ÏÖÉÄÁÎÉÑ ÐÁËÅÔÁ ÞÅÒÅÚ ËÏÍÍÕÎÉËÁÃÉÏÎÎÙÊ ÐÒÏÔÏËÏÌ ",
+"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ ÐÒÉ ÐÅÒÅÄÁÞÅ ÐÁËÅÔÁ ÞÅÒÅÚ ËÏÍÍÕÎÉËÁÃÉÏÎÎÙÊ ÐÒÏÔÏËÏÌ ",
+"ðÏÌÕÞÅÎ ÔÁÊÍÁÕÔ × ÐÒÏÃÅÓÓÅ ÐÅÒÅÄÁÞÉ ÐÁËÅÔÁ ÞÅÒÅÚ ËÏÍÍÕÎÉËÁÃÉÏÎÎÙÊ ÐÒÏÔÏËÏÌ ",
+"òÅÚÕÌØÔÉÒÕÀÝÁÑ ÓÔÒÏËÁ ÂÏÌØÛÅ, ÞÅÍ 'max_allowed_packet'",
+"éÓÐÏÌØÚÕÅÍÁÑ ÔÁÂÌÉÃÁ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÔÉÐÙ BLOB/TEXT",
+"éÓÐÏÌØÚÕÅÍÁÑ ÔÁÂÌÉÃÁ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ Á×ÔÏÉÎËÒÅÍÅÎÔÎÙÅ ÓÔÏÌÂÃÙ",
+"îÅÌØÚÑ ÉÓÐÏÌØÚÏ×ÁÔØ INSERT DELAYED ÄÌÑ ÔÁÂÌÉÃÙ '%-.64s', ÐÏÔÏÍÕ ÞÔÏ ÏÎÁ ÚÁÂÌÏËÉÒÏ×ÁÎÁ Ó ÐÏÍÏÝØÀ LOCK TABLES",
+"îÅ×ÅÒÎÏÅ ÉÍÑ ÓÔÏÌÂÃÁ '%-.100s'",
+"éÓÐÏÌØÚÏ×ÁÎÎÙÊ ÏÂÒÁÂÏÔÞÉË ÔÁÂÌÉÃÙ ÎÅ ÍÏÖÅÔ ÐÒÏÉÎÄÅËÓÉÒÏ×ÁÔØ ÓÔÏÌÂÅà '%-.64s'",
"îÅ ×ÓÅ ÔÁÂÌÉÃÙ × MERGE ÏÐÒÅÄÅÌÅÎÙ ÏÄÉÎÁËÏ×Ï",
-"îÅ ÍÏÇÕ ÐÉÓÁÔØ × ÔÁÂÌÉÃÕ '%-.64s' ÉÚ-ÚÁ UNIQUE ÕÓÌÏ×ÉÊ",
-"ðÏÌÅ ÔÉÐÁ BLOB '%-.64s' × ÏÐÒÅÄÅÌÅÎÉÉ ÉÎÄÅËÓÁ ÂÅÚ ÕËÁÚÁÎÉÑ ÄÌÉÎÙ",
-"÷ÓÅ ÞÁÓÔÉ PRIMARY KEY ÄÏÌÖÎÙ ÂÙÔØ NOT NULL; ÅÓÌÉ NULL × ÉÎÄÅËÓÅ ÎÅÏÂÈÏÄÉÍ, ÉÓÐÏÌØÚÕÊÔÅ UNIQUE",
-"òÅÚÕÌØÔÁÔ ÓÏÄÅÒÖÉÔ ÂÏÌØÛÅ ÏÄÎÏÊ ÓÔÒÏËÉ",
-"ôÁÂÌÉÃÁ ÜÔÏÇÏ ÔÉÐÁ ÏÂÑÚÁÎÁ ÉÍÅÔØ PRIMARY KEY",
-"üÔÁ ËÏÐÉÑ MySQL ÓËÏÍÐÉÌÉÒÏ×ÁÎÁ ÂÅÚ ÐÏÄÄÅÒÖËÉ RAID",
-"MySQL ÒÁÂÏÔÁÅÔ × ÒÅÖÉÍÅ ÚÁÝÉÔÙ ÏÔ ÄÕÒÁËÏ× (safe_mode) - ÎÅ ÍÏÇÕ UPDATE ÂÅÚ WHERE Ó ËÁËÉÍ-ÎÅÂÕÄØ KEY",
-"éÎÄÅËÓ '%-.64s' ÎÅ ÎÁÊÄÅÎ × ÔÁÂÌÉÃÅ '%-.64s'",
-"îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÔÁÂÌÉÃÕ",
-"äÁÎÎÙÊ ÔÉÐ ÔÁÂÌÉà ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ check/repair",
-"üÔÁ ËÏÍÁÎÄÁ ×ÎÕÔÒÉ ÔÒÁÎÚÁËÃÉÉ ÚÁÐÒÅÝÅÎÁ",
-"ïÛÉÂËÁ %d ×Ï ×ÒÅÍÑ COMMIT",
-"ïÛÉÂËÁ %d ×Ï ×ÒÅÍÑ ROLLBACK",
-"ïÛÉÂËÁ %d ×Ï ×ÒÅÍÑ FLUSH_LOGS",
-"ïÛÉÂËÁ %d ×Ï ×ÒÅÍÑ CHECKPOINT",
-"ðÒÅÒ×ÁÎÎÏÅ ÓÏÅÄÉÎÅÎÉÅ %ld Ë ÂÁÚÅ ÄÁÎÎÙÈ: '%-.64s' ÐÏÌØÚÏ×ÁÔÅÌØ: '%-.32s' ÈÏÓÔ: `%-.64s' (%-.64s)",
-"üÔÏÔ ÔÉÐ ÔÁÂÌÉà ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ binary table dump",
-"òÅÐÌÉËÁÃÉÏÎÎÙÊ ÌÏÇ ÚÁËÒÙÔ, ÎÅ ÍÏÇÕ ÓÄÅÌÁÔØ RESET MASTER",
-"ïÛÉÂËÁ ÐÒÉ ×ÏÓÓÔÁÎÏ×ÌÅÎÉÉ ÉÎÄÅËÓÁ ÐÅÒÅËÁÞÁÎÎÏÊ ÔÁÂÌÉÃÙ '%-.64s'",
-"ïÛÉÂËÁ ÎÁ ÍÁÓÔÅÒÅ: '%-.64s'",
-"óÅÔÅ×ÁÑ ÏÛÉÂËÁ ÐÒÉ ÞÔÅÎÉÉ Ó ÍÁÓÔÅÒÁ",
-"óÅÔÅ×ÁÑ ÏÛÉÂËÁ ÐÒÉ ÐÉÓÁÎÉÉ ÍÁÓÔÅÒÕ",
-"FULLTEXT ÉÎÄÅËÓ, ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÊ ÚÁÄÁÎÎÏÍÕ ÓÐÉÓËÕ ÓÔÏÌÂÃÏ×, ÎÅ ÎÁÊÄÅÎ",
-"îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÍÁÎÄÕ ÉÚ-ÚÁ ÁËÔÉ×ÎÙÈ locked ÔÁÂÌÉà ÉÌÉ ÁËÔÉ×ÎÏÊ ÔÒÁÎÚÁËÃÉÉ",
+"îÅ×ÏÚÍÏÖÎÏ ÚÁÐÉÓÁÔØ × ÔÁÂÌÉÃÕ '%-.64s' ÉÚ-ÚÁ ÏÇÒÁÎÉÞÅÎÉÊ ÕÎÉËÁÌØÎÏÇÏ ËÌÀÞÁ",
+"óÔÏÌÂÅÃ ÔÉÐÁ BLOB '%-.64s' ÂÙÌ ÕËÁÚÁÎ × ÏÐÒÅÄÅÌÅÎÉÉ ËÌÀÞÁ ÂÅÚ ÕËÁÚÁÎÉÑ ÄÌÉÎÙ ËÌÀÞÁ",
+"÷ÓÅ ÞÁÓÔÉ ÐÅÒ×ÉÞÎÏÇÏ ËÌÀÞÁ (PRIMARY KEY) ÄÏÌÖÎÙ ÂÙÔØ ÏÐÒÅÄÅÌÅÎÙ ËÁË NOT NULL; åÓÌÉ ×ÁÍ ÎÕÖÎÁ ÐÏÄÄÅÒÖËÁ ×ÅÌÉÞÉÎ NULL × ËÌÀÞÅ, ×ÏÓÐÏÌØÚÕÊÔÅÓØ ÉÎÄÅËÓÏÍ UNIQUE",
+"÷ ÒÅÚÕÌØÔÁÔÅ ×ÏÚ×ÒÁÝÅÎÁ ÂÏÌÅÅ ÞÅÍ ÏÄÎÁ ÓÔÒÏËÁ",
+"üÔÏÔ ÔÉÐ ÔÁÂÌÉÃÙ ÔÒÅÂÕÅÔ ÏÐÒÅÄÅÌÅÎÉÑ ÐÅÒ×ÉÞÎÏÇÏ ËÌÀÞÁ",
+"üÔÁ ×ÅÒÓÉÑ MySQL ÓËÏÍÐÉÌÉÒÏ×ÁÎÁ ÂÅÚ ÐÏÄÄÅÒÖËÉ RAID",
+"÷Ù ÒÁÂÏÔÁÅÔÅ × ÒÅÖÉÍÅ ÂÅÚÏÐÁÓÎÙÈ ÏÂÎÏ×ÌÅÎÉÊ (safe update mode) É ÐÏÐÒÏÂÏ×ÁÌÉ ÉÚÍÅÎÉÔØ ÔÁÂÌÉÃÕ ÂÅÚ ÉÓÐÏÌØÚÏ×ÁÎÉÑ ËÌÀÞÅ×ÏÇÏ ÓÔÏÌÂÃÁ × ÞÁÓÔÉ WHERE",
+"ëÌÀÞ '%-.64s' ÎÅ ÓÕÝÅÓÔ×ÕÅÔ × ÔÁÂÌÉÃÅ '%-.64s'",
+"îÅ×ÏÚÍÏÖÎÏ ÏÔËÒÙÔØ ÔÁÂÌÉÃÕ",
+"ïÂÒÁÂÏÔÞÉË ÔÁÂÌÉÃÙ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÜÔÏÇÏ: %s",
+"÷ÁÍ ÎÅ ÒÁÚÒÅÛÅÎÏ ×ÙÐÏÌÎÑÔØ ÜÔÕ ËÏÍÁÎÄÕ × ÔÒÁÎÚÁËÃÉÉ",
+"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ %d × ÐÒÏÃÅÓÓÅ COMMIT",
+"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ %d × ÐÒÏÃÅÓÓÅ ROLLBACK",
+"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ %d × ÐÒÏÃÅÓÓÅ FLUSH_LOGS",
+"ðÏÌÕÞÅÎÁ ÏÛÉÂËÁ %d × ÐÒÏÃÅÓÓÅ CHECKPOINT",
+"ðÒÅÒ×ÁÎÏ ÓÏÅÄÉÎÅÎÉÅ %ld Ë ÂÁÚÅ ÄÁÎÎÙÈ '%-.64s' ÐÏÌØÚÏ×ÁÔÅÌÑ '%-.32s' Ó ÈÏÓÔÁ `%-.64s' (%-.64s)",
+"ïÂÒÁÂÏÔÞÉË ÜÔÏÊ ÔÁÂÌÉÃÙ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ Ä×ÏÉÞÎÏÇÏ ÓÏÈÒÁÎÅÎÉÑ ÏÂÒÁÚÁ ÔÁÂÌÉÃÙ (dump)",
+"ä×ÏÉÞÎÙÊ ÖÕÒÎÁÌ ÏÂÎÏ×ÌÅÎÉÑ ÚÁËÒÙÔ, ÎÅ×ÏÚÍÏÖÎÏ ×ÙÐÏÌÎÉÔØ RESET MASTER",
+"ïÛÉÂËÁ ÐÅÒÅÓÔÒÏÊËÉ ÉÎÄÅËÓÁ ÓÏÈÒÁÎÅÎÎÏÊ ÔÁÂÌÉÃÙ '%-.64s'",
+"ïÛÉÂËÁ ÏÔ ÇÏÌÏ×ÎÏÇÏ ÓÅÒ×ÅÒÁ: '%-.64s'",
+"÷ÏÚÎÉËÌÁ ÏÛÉÂËÁ ÞÔÅÎÉÑ × ÐÒÏÃÅÓÓÅ ËÏÍÍÕÎÉËÁÃÉÉ Ó ÇÏÌÏ×ÎÙÍ ÓÅÒ×ÅÒÏÍ",
+"÷ÏÚÎÉËÌÁ ÏÛÉÂËÁ ÚÁÐÉÓÉ × ÐÒÏÃÅÓÓÅ ËÏÍÍÕÎÉËÁÃÉÉ Ó ÇÏÌÏ×ÎÙÍ ÓÅÒ×ÅÒÏÍ",
+"îÅ×ÏÚÍÏÖÎÏ ÏÔÙÓËÁÔØ ÐÏÌÎÏÔÅËÓÔÏ×ÙÊ (FULLTEXT) ÉÎÄÅËÓ, ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÊ ÓÐÉÓËÕ ÓÔÏÌÂÃÏ×",
+"îÅ×ÏÚÍÏÖÎÏ ×ÙÐÏÌÎÉÔØ ÕËÁÚÁÎÎÕÀ ËÏÍÁÎÄÕ, ÐÏÓËÏÌØËÕ Õ ×ÁÓ ÐÒÉÓÕÔÓÔ×ÕÀÔ ÁËÔÉ×ÎÏ ÚÁÂÌÏËÉÒÏ×ÁÎÎÙÅ ÔÁÂÌÉÃÁ ÉÌÉ ÏÔËÒÙÔÁÑ ÔÒÁÎÚÁËÃÉÑ",
"îÅÉÚ×ÅÓÔÎÁÑ ÓÉÓÔÅÍÎÁÑ ÐÅÒÅÍÅÎÎÁÑ '%-.64s'",
-"ôÁÂÌÉÃÁ '%-.64s' ÐÏÍÅÞÅÎÁ ËÁË ÉÓÐÏÒÞÅÎÎÁÑ É ÄÏÌÖÎÁ ÂÙÔØ ÉÓÐÒÁ×ÌÅÎÁ",
-"ôÁÂÌÉÃÁ '%-.64s' ÐÏÍÅÞÅÎÁ ËÁË ÉÓÐÏÒÞÅÎÎÁÑ É ÐÏÓÌÅÄÎÑÑ ÐÏÐÙÔËÁ ÉÓÐÒÁ×ÌÅÎÉÑ (Á×ÔÏÍÁÔÉÞÅÓËÁÑ?) ÎÅ ÕÄÁÌÁÓØ",
-"ðÒÅÄÕÐÒÅÖÄÅÎÉÅ: ÎÅËÏÔÏÒÙÅ ÎÅÔÒÁÎÚÁËÃÉÏÎÎÙÅ ÔÁÂÌÉÃÙ ÎÅ ÐÏÄÞÉÎÑÀÔÓÑ ROLLBACK",
-"íÎÏÇÏÚÁÐÒÏÓÎÁÑ ÔÒÁÎÚÁËÃÉÑ ÔÒÅÂÕÅÔ Õ×ÅÌÉÞÅÎÉÑ 'max_binlog_cache_size' - Õ×ÅÌÉÞÔÅ ÜÔÕ ÐÅÒÅÍÅÎÎÕÀ É ÐÏÐÒÏÂÕÊÔÅ ÅÝÅ ÒÁÚ",
-"üÔÁ ÏÐÅÒÁÃÉÑ ÎÅ×ÏÚÍÏÖÎÁ Ó ÁËÔÉ×ÎÙÍ slave, ÎÁÄÏ SLAVE STOP",
-"üÔÁ ÏÐÅÒÁÃÉÑ ÎÅ×ÏÚÍÏÖÎÁ Ó ÐÁÓÓÉ×ÎÙÍ slave, ÎÁÄÏ SLAVE START",
-"üÔÏÔ ÓÅÒ×ÅÒ ÎÅ slave, ÉÓÐÒÁ×ØÔÅ × ËÏÎÆÉÇÕÒÁÃÉÏÎÎÏÍ ÆÁÊÌÅ ÉÌÉ ËÏÍÍÁÎÄÏÊ CHANGE MASTER TO",
-"îÅ ÐÏÌÕÞÉÌÏÓØ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÓÔÒÕËÔÕÒÕ master info, ÐÒÏ×ÅÒÔÅ persmissions ÎÁ ÆÁÊÌÅ master.info",
-"îÅ ÍÏÇÕ ÓÏÚÄÁÔØ ÐÒÏÃÅÓÓ SLAVE, ÐÒÏ×ÅÒØÔÅ ÓÉÓÔÅÍÎÙÅ ÒÅÓÕÒÓÙ",
+"ôÁÂÌÉÃÁ '%-.64s' ÐÏÍÅÞÅÎÁ ËÁË ÉÓÐÏÒÞÅÎÎÁÑ É ÄÏÌÖÎÁ ÐÒÏÊÔÉ ÐÒÏ×ÅÒËÕ É ÒÅÍÏÎÔ",
+"ôÁÂÌÉÃÁ '%-.64s' ÐÏÍÅÞÅÎÁ ËÁË ÉÓÐÏÒÞÅÎÎÁÑ É ÐÏÓÌÅÄÎÉÊ (Á×ÔÏÍÁÔÉÞÅÓËÉÊ?) ÒÅÍÏÎÔ ÎÅ ÂÙÌ ÕÓÐÅÛÎÙÍ",
+"÷ÎÉÍÁÎÉÅ: ÐÏ ÎÅËÏÔÏÒÙÍ ÉÚÍÅÎÅÎÎÙÍ ÎÅÔÒÁÎÚÁËÃÉÏÎÎÙÍ ÔÁÂÌÉÃÁÍ ÎÅ×ÏÚÍÏÖÎÏ ÂÕÄÅÔ ÐÒÏÉÚ×ÅÓÔÉ ÏÔËÁÔ ÔÒÁÎÚÁËÃÉÉ",
+"ôÒÁÎÚÁËÃÉÉ, ×ËÌÀÞÁÀÝÅÊ ÂÏÌØÛÏÅ ËÏÌÉÞÅÓÔ×Ï ËÏÍÁÎÄ, ÐÏÔÒÅÂÏ×ÁÌÏÓØ ÂÏÌÅÅ ÞÅÍ 'max_binlog_cache_size' ÂÁÊÔ. õ×ÅÌÉÞØÔÅ ÜÔÕ ÐÅÒÅÍÅÎÎÕÀ ÓÅÒ×ÅÒÁ mysqld É ÐÏÐÒÏÂÕÊÔÅ ÅÝÅ ÒÁÚ",
+"üÔÕ ÏÐÅÒÁÃÉÀ ÎÅ×ÏÚÍÏÖÎÏ ×ÙÐÏÌÎÉÔØ ÐÒÉ ÒÁÂÏÔÁÀÝÅÍ ÐÏÔÏËÅ ÐÏÄÞÉÎÅÎÎÏÇÏ ÓÅÒ×ÅÒÁ. óÎÁÞÁÌÁ ×ÙÐÏÌÎÉÔÅ STOP SLAVE",
+"äÌÑ ÜÔÏÊ ÏÐÅÒÁÃÉÉ ÔÒÅÂÕÅÔÓÑ ÒÁÂÏÔÁÀÝÉÊ ÐÏÄÞÉÎÅÎÎÙÊ ÓÅÒ×ÅÒ. óÎÁÞÁÌÁ ×ÙÐÏÌÎÉÔÅ START SLAVE",
+"üÔÏÔ ÓÅÒ×ÅÒ ÎÅ ÎÁÓÔÒÏÅÎ ËÁË ÐÏÄÞÉÎÅÎÎÙÊ. ÷ÎÅÓÉÔÅ ÉÓÐÒÁ×ÌÅÎÉÑ × ËÏÎÆÉÇÕÒÁÃÉÏÎÎÏÍ ÆÁÊÌÅ ÉÌÉ Ó ÐÏÍÏÝØÀ CHANGE MASTER TO",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
+"îÅ×ÏÚÍÏÖÎÏ ÓÏÚÄÁÔØ ÐÏÔÏË ÐÏÄÞÉÎÅÎÎÏÇÏ ÓÅÒ×ÅÒÁ. ðÒÏ×ÅÒØÔÅ ÓÉÓÔÅÍÎÙÅ ÒÅÓÕÒÓÙ",
"õ ÐÏÌØÚÏ×ÁÔÅÌÑ %-.64s ÕÖÅ ÂÏÌØÛÅ ÞÅÍ 'max_user_connections' ÁËÔÉ×ÎÙÈ ÓÏÅÄÉÎÅÎÉÊ",
-"íÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔØ ÔÏÌØËÏ ×ÙÒÁÖÅÎÉÅ-ËÏÎÓÔÁÎÔÕ ÓÏ×ÍÅÓÔÎÏ Ó SET",
-"ôÁÊÍÁÕÔ ÏÖÉÄÁÎÉÑ ÂÌÏËÉÒÏ×ËÉ",
-"ïÂÝÅÅ ËÏÌÉÞÅÓÔ×Ï ÂÌÏËÉÒÏ×ÏË ÐÒÅ×ÙÓÉÌÏ ÒÁÚÍÅÒ ÔÁÂÌÉÃÙ ÂÌÏËÉÒÏ×ÏË",
-"âÌÏËÉÒÏ×ËÁ ÉÚÍÅÎÅÎÉÑ ÎÅ ÍÏÖÅÔ ÂÙÔØ ÐÏÌÕÞÅÎÁ ×Ï ×ÒÅÍÑ READ UNCOMMITTED ÔÒÁÎÚÁËÃÉÉ",
-"DROP DATABASE ÚÁÐÒÅÝÅÎ ×Ï ×ÒÅÍÑ ÇÌÏÂÁÌØÎÏÊ ÂÌÏËÉÒÏ×ËÉ ÞÔÅÎÉÑ",
-"CREATE DATABASE ÚÁÐÒÅÝÅÎ ×Ï ×ÒÅÍÑ ÇÌÏÂÁÌØÎÏÊ ÂÌÏËÉÒÏ×ËÉ ÞÔÅÎÉÑ",
-"îÅÐÒÁ×ÉÌØÎÙÅ ÁÒÇÕÍÅÔÎÙ Õ %s",
-"%-.32s@%-.64s ÎÅ ÉÍÅÅÔ ÐÒÉ×ÉÌÅÇÉÊ ÓÏÚÄÁ×ÁÔØ ÎÏ×ÙÈ ÐÏÌØÚÏ×ÁÔÅÌÅÊ",
-"îÅ×ÅÒÎÏÅ ÏÐÒÅÄÅÌÅÎÉÅ ÔÁÂÌÉÃÙ; ÷ÓÅ MERGE-ÔÁÂÌÉÃÙ ÄÏÌÖÎÙ ÂÙÔØ × ÏÄÎÏÊ ÂÁÚÅ ÄÁÎÎÙÈ",
-"ïÂÎÁÒÕÖÅÎ deadlock ×Ï ×ÒÅÍÑ ÐÏÌÕÞÅÎÉÑ ÂÌÏËÉÒÏ×ËÉ; ðÏÐÒÏÂÕÊÔÅ ÐÅÒÅÚÁÐÕÓÔÉÔØ ÔÒÁÎÚÁËÃÉÀ",
-"ôÁÂÌÉÃÁ ÄÁÎÎÏÇÏ ÔÉÐÁ ÎÅ ÍÏÖÅÔ ÉÍÅÔØ FULLTEXT ÉÎÄÅËÓÁ",
-"Cannot add foreign key constraint",
-"Cannot add a child row: a foreign key constraint fails",
-"Cannot delete a parent row: a foreign key constraint fails",
+"÷Ù ÍÏÖÅÔÅ ÉÓÐÏÌØÚÏ×ÁÔØ × SET ÔÏÌØËÏ ËÏÎÓÔÁÎÔÎÙÅ ×ÙÒÁÖÅÎÉÑ",
+"ôÁÊÍÁÕÔ ÏÖÉÄÁÎÉÑ ÂÌÏËÉÒÏ×ËÉ ÉÓÔÅË; ÐÏÐÒÏÂÕÊÔÅ ÐÅÒÅÚÁÐÕÓÔÉÔØ ÔÒÁÎÚÁËÃÉÀ",
+"ïÂÝÅÅ ËÏÌÉÞÅÓÔ×Ï ÂÌÏËÉÒÏ×ÏË ÐÒÅ×ÙÓÉÌÏ ÒÁÚÍÅÒÙ ÔÁÂÌÉÃÙ ÂÌÏËÉÒÏ×ÏË",
+"âÌÏËÉÒÏ×ËÉ ÏÂÎÏ×ÌÅÎÉÊ ÎÅÌØÚÑ ÐÏÌÕÞÉÔØ × ÐÒÏÃÅÓÓÅ ÞÔÅÎÉÑ ÎÅ ÐÒÉÎÑÔÏÊ (× ÒÅÖÉÍÅ READ UNCOMMITTED) ÔÒÁÎÚÁËÃÉÉ",
+"îÅ ÄÏÐÕÓËÁÅÔÓÑ DROP DATABASE, ÐÏËÁ ÐÏÔÏË ÄÅÒÖÉÔ ÇÌÏÂÁÌØÎÕÀ ÂÌÏËÉÒÏ×ËÕ ÞÔÅÎÉÑ",
+"îÅ ÄÏÐÕÓËÁÅÔÓÑ CREATE DATABASE, ÐÏËÁ ÐÏÔÏË ÄÅÒÖÉÔ ÇÌÏÂÁÌØÎÕÀ ÂÌÏËÉÒÏ×ËÕ ÞÔÅÎÉÑ",
+"îÅ×ÅÒÎÙÅ ÐÁÒÁÍÅÔÒÙ ÄÌÑ %s",
+"%-.32s@%-.64s ÎÅ ÒÁÚÒÅÛÁÅÔÓÑ ÓÏÚÄÁ×ÁÔØ ÎÏ×ÙÈ ÐÏÌØÚÏ×ÁÔÅÌÅÊ",
+"îÅ×ÅÒÎÏÅ ÏÐÒÅÄÅÌÅÎÉÅ ÔÁÂÌÉÃÙ; ÷ÓÅ ÔÁÂÌÉÃÙ × MERGE ÄÏÌÖÎÙ ÐÒÉÎÁÄÌÅÖÁÔØ ÏÄÎÏÊ É ÔÏÊ ÖÅ ÂÁÚÅ ÄÁÎÎÙÈ",
+"÷ÏÚÎÉËÌÁ ÔÕÐÉËÏ×ÁÑ ÓÉÔÕÁÃÉÑ × ÐÒÏÃÅÓÓÅ ÐÏÌÕÞÅÎÉÑ ÂÌÏËÉÒÏ×ËÉ; ðÏÐÒÏÂÕÊÔÅ ÐÅÒÅÚÁÐÕÓÔÉÔØ ÔÒÁÎÚÁËÃÉÀ",
+"éÓÐÏÌØÚÕÅÍÙÊ ÔÉÐ ÔÁÂÌÉà ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÐÏÌÎÏÔÅËÓÔÏ×ÙÈ ÉÎÄÅËÓÏ×",
+"îÅ×ÏÚÍÏÖÎÏ ÄÏÂÁ×ÉÔØ ÏÇÒÁÎÉÞÅÎÉÑ ×ÎÅÛÎÅÇÏ ËÌÀÞÁ",
+"îÅ×ÏÚÍÏÖÎÏ ÄÏÂÁ×ÉÔØ ÉÌÉ ÏÂÎÏ×ÉÔØ ÄÏÞÅÒÎÀÀ ÓÔÒÏËÕ: ÐÒÏ×ÅÒËÁ ÏÇÒÁÎÉÞÅÎÉÊ ×ÎÅÛÎÅÇÏ ËÌÀÞÁ ÎÅ ×ÙÐÏÌÎÑÅÔÓÑ",
+"îÅ×ÏÚÍÏÖÎÏ ÕÄÁÌÉÔØ ÉÌÉ ÏÂÎÏ×ÉÔØ ÒÏÄÉÔÅÌØÓËÕÀ ÓÔÒÏËÕ: ÐÒÏ×ÅÒËÁ ÏÇÒÁÎÉÞÅÎÉÊ ×ÎÅÛÎÅÇÏ ËÌÀÞÁ ÎÅ ×ÙÐÏÌÎÑÅÔÓÑ",
+"ïÛÉÂËÁ ÓÏÅÄÉÎÅÎÉÑ Ó ÇÏÌÏ×ÎÙÍ ÓÅÒ×ÅÒÏÍ: %-.128s",
+"ïÛÉÂËÁ ×ÙÐÏÌÎÅÎÉÑ ÚÁÐÒÏÓÁ ÎÁ ÇÏÌÏ×ÎÏÍ ÓÅÒ×ÅÒÅ: %-.128s",
+"ïÛÉÂËÁ ÐÒÉ ×ÙÐÏÌÎÅÎÉÉ ËÏÍÁÎÄÙ %s: %-.128s",
+"îÅ×ÅÒÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ %s É %s",
+"éÓÐÏÌØÚÏ×ÁÎÎÙÅ ÏÐÅÒÁÔÏÒÙ ×ÙÂÏÒËÉ (SELECT) ÄÁÀÔ ÒÁÚÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ×",
+"îÅ×ÏÚÍÏÖÎÏ ÉÓÐÏÌÎÉÔØ ÚÁÐÒÏÓ, ÐÏÓËÏÌØËÕ Õ ×ÁÓ ÕÓÔÁÎÏ×ÌÅÎÙ ËÏÎÆÌÉËÔÕÀÝÉÅ ÂÌÏËÉÒÏ×ËÉ ÞÔÅÎÉÑ",
+"éÓÐÏÌØÚÏ×ÁÎÉÅ ÔÒÁÎÚÁËÃÉÏÎÎÙÈ ÔÁÂÌÉà ÎÁÒÑÄÕ Ó ÎÅÔÒÁÎÚÁËÃÉÏÎÎÙÍÉ ÚÁÐÒÅÝÅÎÏ",
+"ïÐÃÉÑ '%s' Ä×ÁÖÄÙ ÉÓÐÏÌØÚÏ×ÁÎÁ × ×ÙÒÁÖÅÎÉÉ",
+"ðÏÌØÚÏ×ÁÔÅÌØ '%-.64s' ÐÒÅ×ÙÓÉÌ ÉÓÐÏÌØÚÏ×ÁÎÉÅ ÒÅÓÕÒÓÁ '%s' (ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ: %ld)",
+"÷ ÄÏÓÔÕÐÅ ÏÔËÁÚÁÎÏ. ÷ÁÍ ÎÕÖÎÙ ÐÒÉ×ÉÌÅÇÉÉ %-.128s ÄÌÑ ÜÔÏÊ ÏÐÅÒÁÃÉÉ",
+"ðÅÒÅÍÅÎÎÁÑ '%-.64s' Ñ×ÌÑÅÔÓÑ ÐÏÔÏËÏ×ÏÊ (LOCAL) ÐÅÒÅÍÅÎÎÏÊ É ÎÅ ÍÏÖÅÔ ÂÙÔØ ÉÚÍÅÎÅÎÁ Ó ÐÏÍÏÝØÀ SET GLOBAL",
+"ðÅÒÅÍÅÎÎÁÑ '%-.64s' Ñ×ÌÑÅÔÓÑ ÇÌÏÂÁÌØÎÏÊ (GLOBAL) ÐÅÒÅÍÅÎÎÏÊ, É ÅÅ ÓÌÅÄÕÅÔ ÉÚÍÅÎÑÔØ Ó ÐÏÍÏÝØÀ SET GLOBAL",
+"ðÅÒÅÍÅÎÎÁÑ '%-.64s' ÎÅ ÉÍÅÅÔ ÚÎÁÞÅÎÉÑ ÐÏ ÕÍÏÌÞÁÎÉÀ",
+"ðÅÒÅÍÅÎÎÁÑ '%-.64s' ÎÅ ÍÏÖÅÔ ÂÙÔØ ÕÓÔÁÎÏ×ÌÅÎÁ × ÚÎÁÞÅÎÉÅ '%-.64s'",
+"îÅ×ÅÒÎÙÊ ÔÉÐ ÁÒÇÕÍÅÎÔÁ ÄÌÑ ÐÅÒÅÍÅÎÎÏÊ '%-.64s'",
+"ðÅÒÅÍÅÎÎÁÑ '%-.64s' ÍÏÖÅÔ ÂÙÔØ ÔÏÌØËÏ ÕÓÔÁÎÏ×ÌÅÎÁ, ÎÏ ÎÅ ÓÞÉÔÁÎÁ",
+"îÅ×ÅÒÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ ÉÌÉ × ÎÅ×ÅÒÎÏÍ ÍÅÓÔÅ ÕËÁÚÁÎ '%s'",
+"üÔÁ ×ÅÒÓÉÑ MySQL ÐÏËÁ ÅÝÅ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ '%s'",
+"ðÏÌÕÞÅÎÁ ÎÅÉÓÐÒÁ×ÉÍÁÑ ÏÛÉÂËÁ %d: '%-.128s' ÏÔ ÇÏÌÏ×ÎÏÇÏ ÓÅÒ×ÅÒÁ × ÐÒÏÃÅÓÓÅ ×ÙÂÏÒËÉ ÄÁÎÎÙÈ ÉÚ Ä×ÏÉÞÎÏÇÏ ÖÕÒÎÁÌÁ",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt
index 8b06ec7e98f..411f93b97da 100644
--- a/sql/share/slovak/errmsg.txt
+++ b/sql/share/slovak/errmsg.txt
@@ -113,7 +113,7 @@
"Pole BLOB '%-.64s' nemô¾e ma» implicitnú hodnotu",
"Neprípustné meno databázy '%-.100s'",
"Neprípustné meno tabuµky '%-.100s'",
-"Zadaná po¾iadavka SELECT by prechádzala príli¹ mnoho záznamov a trvala by príli¹ dlho. Skontrolujte tvar WHERE a ak je v poriadku, pou¾ite SET OPTION SQL_BIG_SELECTS=1",
+"Zadaná po¾iadavka SELECT by prechádzala príli¹ mnoho záznamov a trvala by príli¹ dlho. Skontrolujte tvar WHERE a ak je v poriadku, pou¾ite SET SQL_BIG_SELECTS=1",
"Neznámá chyba",
"Neznámá procedúra '%-.64s'",
"Chybný poèet parametrov procedúry '%-.64s'",
@@ -155,7 +155,7 @@
"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'",
"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.",
"The host or user argument to GRANT is too long",
-"Table '%-64s.%s' doesn't exist",
+"Table '%-.64s.%s' doesn't exist",
"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'",
"The used command is not allowed with this MySQL version",
"Something is wrong in your syntax",
@@ -187,7 +187,7 @@
"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column",
"Key '%-.64s' doesn't exist in table '%-.64s'",
"Can't open table",
-"The handler for the table doesn't support check/repair",
+"The handler for the table doesn't support %s",
"You are not allowed to execute this command in a transaction",
"Got error %d during COMMIT",
"Got error %d during ROLLBACK",
@@ -210,7 +210,7 @@
"This operation cannot be performed with a running slave, run SLAVE STOP first",
"This operation requires a running slave, configure slave and do SLAVE START",
"The server is not configured as slave, fix in config file or with CHANGE MASTER TO",
-"Could not initialize master info structure, check permisions on master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
@@ -227,3 +227,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt
index 089bc13e8d3..0010769aa4f 100644
--- a/sql/share/spanish/errmsg.txt
+++ b/sql/share/spanish/errmsg.txt
@@ -106,7 +106,7 @@
"Campo Blob '%-.64s' no puede tener valores patron",
"Nombre de base de datos ilegal '%-.64s'",
"Nombre de tabla ilegal '%-.64s'",
-"El SELECT puede examinar muchos registros y probablemente con mucho tiempo. Verifique tu WHERE y usa SET OPTION SQL_BIG_SELECTS=1 si el SELECT esta correcto",
+"El SELECT puede examinar muchos registros y probablemente con mucho tiempo. Verifique tu WHERE y usa SET SQL_BIG_SELECTS=1 si el SELECT esta correcto",
"Error desconocido",
"Procedimiento desconocido %s",
"Equivocado parametro count para procedimiento %s",
@@ -148,7 +148,7 @@
"%-.16s comando negado para usuario: '%-.32s@%-.64s' para columna '%-.64s' en la tabla '%-.64s'",
"Ilegal comando GRANT/REVOKE. Por favor consulte el manual para cuales permisos pueden ser usados.",
"El argumento para servidor o usuario para GRANT es demasiado grande",
-"Tabla '%-64s.%s' no existe",
+"Tabla '%-.64s.%s' no existe",
"No existe tal permiso definido para usuario '%-.32s' en el servidor '%-.64s' en la tabla '%-.64s'",
"El comando usado no es permitido con esta versión de MySQL",
"Algo está equivocado en su sintax",
@@ -180,7 +180,7 @@
"Tu estás usando modo de actualización segura y tentado actualizar una tabla sin un WHERE que usa una KEY columna",
"Clave '%-.64s' no existe en la tabla '%-.64s'",
"No puedo abrir tabla",
-"El manipulador de la tabla no permite soporte para check/repair",
+"El manipulador de la tabla no permite soporte para %s",
"No tienes el permiso para ejecutar este comando en una transición",
"Obtenido error %d durante COMMIT",
"Obtenido error %d durante ROLLBACK",
@@ -203,7 +203,7 @@
"Esta operación no puede ser hecha con el esclavo funcionando, primero use SLAVE STOP",
"Esta operación necesita el esclavo funcionando, configure esclavo y haga el SLAVE START",
"El servidor no está configurado como esclavo, edite el archivo config file o con CHANGE MASTER TO",
-"No puedo inicializar la estructura info del master, verifique permisiones en el master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"No puedo crear el thread esclavo, verifique recursos del sistema",
"Usario %-.64s ya tiene mas que 'max_user_connections' conexiones activas",
"Tu solo debes usar expresiones constantes con SET",
@@ -220,3 +220,24 @@
"No puede adicionar clave extranjera constraint",
"No puede adicionar una línea hijo: falla de clave extranjera constraint",
"No puede deletar una línea padre: falla de clave extranjera constraint",
+"Error de coneccion a master: %-128s",
+"Error executando el query en master: %-128%",
+"Error de %s: %-128%",
+"Equivocado uso de %s y %s",
+"El comando SELECT usado tiene diferente número de columnas",
+"No puedo ejecutar el query porque usted tiene conflicto de traba de lectura",
+"Mezla de transancional y no-transancional tablas está deshabilitada",
+"Opción '%s' usada dos veces en el comando",
+"Usuario '%-.64s' ha excedido el recurso '%s' (actual valor: %ld)",
+"Acceso negado. Usted necesita el privilegio %-.128s para esta operación",
+"Variable '%-.64s' es una LOCAL variable y no puede ser usada con SET GLOBAL",
+"Variable '%-.64s' es una GLOBAL variable y no puede ser configurada con SET GLOBAL",
+"Variable '%-.64s' no tiene un valor patrón",
+"Variable '%-.64s' no puede ser configurada para el valor de '%-.64s'",
+"Tipo de argumento equivocado para variable '%-.64s'",
+"Variable '%-.64s' solamente puede ser configurada, no leída",
+"Equivocado uso/colocación de '%s'",
+"Esta versión de MySQL no soporta todavia '%s'",
+"Recibió fatal error %d: '%-.128s' del master cuando leyendo datos del binary log",
+"Slave SQL thread ignorado el query debido a las reglas de replicación-*-tabla"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/swedish/errmsg.OLD b/sql/share/swedish/errmsg.OLD
index cc54e051e63..3dd14c8b613 100644
--- a/sql/share/swedish/errmsg.OLD
+++ b/sql/share/swedish/errmsg.OLD
@@ -205,11 +205,17 @@
"Kunde inte initializera replications-strukturerna. Kontrollera privilegerna för 'master.info'",
"Kunde inte starta en tråd för replikering",
"Användare '%-.64s' har redan 'max_user_connections' aktiva inloggningar",
-"Du kan endast använda konstant-uttryck med SET",
-"Lock wait timeout exceeded",
-"The total number of locks exceeds the lock table size",
-"Update locks cannot be acquired during a READ UNCOMMITTED transaction",
-"DROP DATABASE not allowed while thread is holding global read lock",
-"CREATE DATABASE not allowed while thread is holding global read lock",
-#ER_WRONG_ARGUMENTS
+"Man kan endast använda konstant-uttryck med SET",
+"Fick inte ett lås i tid",
+"Antal lås överskrider antalet reserverade lås",
+"Updaterings-lås kan inte göras när man använder READ UNCOMMITTED",
+"DROP DATABASE är inte tillåtet när man har ett globalt läs-lås",
+"CREATE DATABASE är inte tillåtet när man har ett globalt läs-lås",
"Felaktiga argument till %s",
+"%-.32s@%-.64s har inte rättigheter att skapa nya användare",
+"Fick fel vid anslutning till master: %-.128s",
+"Fick fel vid utförande av command på mastern: %-.128s",
+"Fick fel vid utförande av %s: %-.128s",
+"Felaktig använding av %s and %s",
+"SELECT kommandona har olika antal kolumner"
+"Kan inte utföra kommandot emedan du har ett READ lås",
diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt
index 3bdc5842cb1..508737dde2f 100644
--- a/sql/share/swedish/errmsg.txt
+++ b/sql/share/swedish/errmsg.txt
@@ -5,22 +5,22 @@
"isamchk",
"NO",
"YES",
-"Kan inte skapa filen: '%-.64s' (Felkod: %d)",
-"Kan inte skapa tabellen: '%-.64s' (Felkod: %d)",
+"Kan inte skapa filen '%-.64s' (Felkod: %d)",
+"Kan inte skapa tabellen '%-.64s' (Felkod: %d)",
"Kan inte skapa databasen '%-.64s'. (Felkod: %d)",
"Databasen '%-.64s' existerar redan",
"Kan inte radera databasen '%-.64s'. Databasen finns inte",
"Fel vid radering av databasen (Kan inte radera '%-.64s'. Felkod: %d)",
"Fel vid radering av databasen (Kan inte radera biblioteket '%-.64s'. Felkod: %d)",
-"Kan inte radera filen: '%-.64s' (Felkod: %d)",
+"Kan inte radera filen '%-.64s' (Felkod: %d)",
"Hittar inte posten i systemregistret",
"Kan inte läsa filinformationen (stat) från '%-.64s' (Felkod: %d)",
"Kan inte inte läsa aktivt bibliotek. (Felkod: %d)",
"Kan inte låsa filen. (Felkod: %d)",
-"Kan inte använda: '%-.64s'. (Felkod: %d)",
-"Hittar inte filen: '%-.64s'. (Felkod: %d)",
+"Kan inte använda '%-.64s'. (Felkod: %d)",
+"Hittar inte filen '%-.64s'. (Felkod: %d)",
"Kan inte läsa från bibliotek '%-.64s'. (Felkod: %d)",
-"Kan inte byta till: '%-.64s'. (Felkod: %d)",
+"Kan inte byta till '%-.64s'. (Felkod: %d)",
"Posten har förändrats sedan den lästes i register '%-.64s'",
"Disken är full (%s). Väntar tills det finns ledigt utrymme....",
"Kan inte skriva, dubbel söknyckel i register '%-.64s'",
@@ -36,13 +36,13 @@
"Hittar inte posten",
"Felaktig fil: '%-.64s'",
"Fatalt fel vid hantering av register '%-.64s'. Kör en reparation",
-"Gammal nyckelfil '%-.64s'; Reparera registret",
+"Gammal nyckelfil '%-.64s'. Reparera registret",
"'%-.64s' är skyddad mot förändring",
"Oväntat slut på minnet, starta om programmet och försök på nytt (Behövde %d bytes)",
"Sorteringsbufferten räcker inte till. Kontrollera startparametrarna",
"Oväntat filslut vid läsning från '%-.64s' (Felkod: %d)",
"För många anslutningar",
-"Fick slut på minnet. Kontrollera ifall mysqld eller någon annan process använder allt tillgängligt minne. Ifall inte, försök använda 'ulimit' eller allokera mera swap",
+"Fick slut på minnet. Kontrollera om mysqld eller någon annan process använder allt tillgängligt minne. Om inte, försök använda 'ulimit' eller allokera mera swap",
"Kan inte hitta 'hostname' för din adress",
"Fel vid initiering av kommunikationen med klienten",
"Användare '%-.32s@%-.64s' är ej berättigad att använda databasen %-.64s",
@@ -50,43 +50,43 @@
"Ingen databas i användning",
"Okänt commando",
"Kolumn '%-.64s' får inte vara NULL",
-"Okänd database '%-.64s'",
+"Okänd databas: '%-.64s'",
"Tabellen '%-.64s' finns redan",
"Okänd tabell '%-.64s'",
-"Kolumn: '%-.64s' i %s är inte unik",
+"Kolumn '%-.64s' i %s är inte unik",
"Servern går nu ned",
"Okänd kolumn '%-.64s' i %s",
"'%-.64s' finns inte i GROUP BY",
"Kan inte använda GROUP BY med '%-.64s'",
"Kommandot har både sum functions och enkla funktioner",
"Antalet kolumner motsvarar inte antalet värden",
-"Kolumn namn '%-.64s' är för långt",
-"Kolumn namn '%-64s finns flera gånger",
-"Nyckel namn '%-.64s' finns flera gånger",
-"Dubbel nyckel '%-.64s' för nyckel: %d",
-"Felaktigt kolumn typ för kolumn: '%-.64s'",
+"Kolumnnamn '%-.64s' är för långt",
+"Kolumnnamn '%-.64s finns flera gånger",
+"Nyckelnamn '%-.64s' finns flera gånger",
+"Dubbel nyckel '%-.64s' för nyckel %d",
+"Felaktigt kolumntyp för kolumn '%-.64s'",
"%s nära '%-.64s' på rad %d",
"Frågan var tom",
"Icke unikt tabell/alias: '%-.64s'",
"Ogiltigt DEFAULT värde för '%-.64s'",
"Flera PRIMARY KEY använda",
"För många nycklar använda. Man får ha högst %d nycklar",
-"För många nyckel delar använda. Man får ha högst %d nyckeldelar",
+"För många nyckeldelar använda. Man får ha högst %d nyckeldelar",
"För lång nyckel. Högsta tillåtna nyckellängd är %d",
-"Nyckel kolumn '%-.64s' finns inte",
-"En BLOB '%-.64s' kan inte vara nyckel med den använda tabellen typen",
+"Nyckelkolumn '%-.64s' finns inte",
+"En BLOB '%-.64s' kan inte vara nyckel med den använda tabelltypen",
"För stor kolumnlängd angiven för '%-.64s' (max= %d). Använd en BLOB instället",
-"Det får finnas endast ett AUTO_INCREMENT fält och detta måste vara en nyckel",
+"Det får finnas endast ett AUTO_INCREMENT-fält och detta måste vara en nyckel",
"%s: klar att ta emot klienter\n",
"%s: Normal avslutning\n",
"%s: Fick signal %d. Avslutar!\n",
"%s: Avslutning klar\n",
-"%s: Stänger av tråd %ld användare: '%-.64s'\n",
-"Kan inte skapa IP socket",
+"%s: Stänger av tråd %ld; användare: '%-.64s'\n",
+"Kan inte skapa IP-socket",
"Tabellen '%-.64s' har inget index som motsvarar det angivna i CREATE INDEX. Skapa om tabellen",
-"Fält separatorerna är inte emotsägande eller för långa. Kontrollera mot manualen",
+"Fältseparatorerna är vad som förväntades. Kontrollera mot manualen",
"Man kan inte använda fast radlängd med blobs. Använd 'fields terminated by'",
-"Textfilen '%' måste finnas i databas biblioteket eller vara läsbar för alla",
+"Textfilen '%' måste finnas i databasbiblioteket eller vara läsbar för alla",
"Filen '%-.64s' existerar redan",
"Rader: %ld Bortagna: %ld Dubletter: %ld Varningar: %ld",
"Rader: %ld Dubletter: %ld",
@@ -94,18 +94,18 @@
"Man kan inte radera alla fält med ALTER TABLE. Använd DROP TABLE istället",
"Kan inte ta bort '%-.64s'. Kontrollera att fältet/nyckel finns",
"Rader: %ld Dubletter: %ld Varningar: %ld",
-"INSERT table '%-.64s' får inte finnas i FROM tabell-listan",
-"Finns inget thread med id %lu",
-"Du är inte ägare till thread %lu",
+"INSERT-table '%-.64s' får inte finnas i FROM tabell-listan",
+"Finns ingen tråd med id %lu",
+"Du är inte ägare till tråd %lu",
"Inga tabeller angivna",
"För många alternativ till kolumn %s för SET",
"Kan inte generera ett unikt filnamn %s.(1-999)\n",
"Tabell '%-.64s' kan inte uppdateras emedan den är låst för läsning",
"Tabell '%-.64s' är inte låst med LOCK TABLES",
-"BLOB fält '%-.64s' kan inte ha ett DEFAULT värde",
-"Felaktigt databas namn '%-.64s'",
-"Felaktigt tabell namn '%-.64s'",
-"Den angivna frågan skulle troligen ta mycket long tid! Kontrollar din WHERE och använd SET OPTION SQL_BIG_SELECTS=1 ifall du vill hantera stora joins",
+"BLOB fält '%-.64s' kan inte ha ett DEFAULT-värde",
+"Felaktigt databasnamn '%-.64s'",
+"Felaktigt tabellnamn '%-.64s'",
+"Den angivna frågan skulle läsa mer än MAX_JOIN_SIZE rader. Kontrollera din WHERE och använd SET SQL_BIG_SELECTS=1 eller SET MAX_JOIN_SIZE=# ifall du vill hantera stora joins",
"Oidentifierat fel",
"Okänd procedur: %s",
"Felaktigt antal parametrar till procedur %s",
@@ -116,12 +116,12 @@
"Tabell '%-.64s' har en extension som inte finns i denna version av MySQL",
"Tabeller måste ha minst 1 kolumn",
"Tabellen '%-.64s' är full",
-"Okänt karaktärset: '%-.64s'",
+"Okänd teckenuppsättning: '%-.64s'",
"För många tabeller. MySQL can ha högst %d tabeller i en och samma join",
"För många fält",
-"För stor total rad längd. Den högst tillåtna rad-längden, förutom BLOBs, är %d. Ändra några av dina fält till BLOB",
-"Tråd-stacken tog slut: Har använt %ld av %ld bytes. Använd 'mysqld -O thread_stack=#' ifall du behöver en större stack",
-"Felaktigt referens i OUTER JOIN. Kontrollera ON uttrycket",
+"För stor total radlängd. Den högst tillåtna radlängden, förutom BLOBs, är %d. Ändra några av dina fält till BLOB",
+"Trådstacken tog slut: Har använt %ld av %ld bytes. Använd 'mysqld -O thread_stack=#' ifall du behöver en större stack",
+"Felaktigt referens i OUTER JOIN. Kontrollera ON-uttrycket",
"Kolumn '%-.32s' är använd med UNIQUE eller INDEX men är inte definerad med NOT NULL",
"Kan inte ladda funktionen '%-.64s'",
"Kan inte initialisera funktionen '%-.64s'; '%-.80s'",
@@ -130,30 +130,30 @@
"Kan inte öppna det dynamiska biblioteket '%-.64s' (Felkod: %d %s)",
"Hittar inte funktionen '%-.64s' in det dynamiska biblioteket",
"Funktionen '%-.64s' är inte definierad",
-"Denna dator '%-.64s' är blockerad pga många felaktig paket. Gör 'mysqladmin flush-hosts' för att ta bort alla blockeringarna",
-"Denna dator '%-.64s' har inte privileger att använda denna MySQL server",
+"Denna dator, '%-.64s', är blockerad pga många felaktig paket. Gör 'mysqladmin flush-hosts' för att ta bort alla blockeringarna",
+"Denna dator, '%-.64s', har inte privileger att använda denna MySQL server",
"Du använder MySQL som en anonym användare och som sådan får du inte ändra ditt lösenord",
-"För att ändra lösenord för andra måste du ha rättigheter att uppdatera mysql databasen",
-"Hittade inte användaren i 'user' tabellen",
+"För att ändra lösenord för andra måste du ha rättigheter att uppdatera mysql-databasen",
+"Hittade inte användaren i 'user'-tabellen",
"Rader: %ld Uppdaterade: %ld Varningar: %ld",
"Kan inte skapa en ny tråd (errno %d)",
"Antalet kolumner motsvarar inte antalet värden på rad: %ld",
-"Kunde inte stänga och öppna tabell: '%-.64s",
+"Kunde inte stänga och öppna tabell '%-.64s",
"Felaktig använding av NULL",
-"Fix fel '%-.64s' från REGEXP",
-"Man får ha både GROUP kolumner (MIN(),MAX(),COUNT()...) och fält i en fråga om man inte har en GROUP BY del",
+"Fick fel '%-.64s' från REGEXP",
+"Man får ha både GROUP-kolumner (MIN(),MAX(),COUNT()...) och fält i en fråga om man inte har en GROUP BY-del",
"Det finns inget privilegium definierat för användare '%-.32s' på '%-.64s'",
"%-.16s ej tillåtet för '%-.32s@%-.64s' för tabell '%-.64s'",
-"%-.16s ej tillåtet för '%-.32s@%-.64s'\n för kolumn '%-.64s' i tabell '%-.64s'",
-"Felaktigt GRANT privilegium använt",
+"%-.16s ej tillåtet för '%-.32s@%-.64s' för kolumn '%-.64s' i tabell '%-.64s'",
+"Felaktigt GRANT-privilegium använt",
"Felaktigt maskinnamn eller användarnamn använt med GRANT",
-"Det finns ingen tabell som heter '%-64s.%s'",
+"Det finns ingen tabell som heter '%-.64s.%s'",
"Det finns inget privilegium definierat för användare '%-.32s' på '%-.64s' för tabell '%-.64s'",
"Du kan inte använda detta kommando med denna MySQL version",
"Du har något fel i din syntax",
-"DELAYED INSERT tråden kunde inte låsa tabell '%-.64s'",
+"DELAYED INSERT-tråden kunde inte låsa tabell '%-.64s'",
"Det finns redan 'max_delayed_threads' trådar i använding",
-"Avbröt länken för tråd %ld till db: '%-.64s' användare: '%-.64s' (%s)",
+"Avbröt länken för tråd %ld till db '%-.64s', användare '%-.64s' (%s)",
"Kommunkationspaketet är större än 'max_allowed_packet'",
"Fick läsfel från klienten vid läsning från 'PIPE'",
"Fick fatalt fel från 'fcntl()'",
@@ -163,59 +163,80 @@
"Fick 'timeout' vid läsning från klienten",
"Fick ett fel vid skrivning till klienten",
"Fick 'timeout' vid skrivning till klienten",
-"Resultat strängen är längre än max_allowed_packet",
-"Den använda tabell typen kan inte hantera BLOB/TEXT kolumner",
-"Den använda tabell typen kan inte hantera AUTO_INCREMENT kolumner",
+"Resultatsträngen är längre än max_allowed_packet",
+"Den använda tabelltypen kan inte hantera BLOB/TEXT-kolumner",
+"Den använda tabelltypen kan inte hantera AUTO_INCREMENT-kolumner",
"INSERT DELAYED kan inte användas med tabell '%-.64s', emedan den är låst med LOCK TABLES",
-"Felaktigt column namn '%-.100s'",
-"Den använda tabell typen kan inte indexera kolumn '%-.64s'",
-"Tabellerna i MERGE tabellen är inte identiskt definierade",
-"Kan inte skriva till tabell '%-.64s'; UNIQUE test",
-"Du har inte angett en nyckel längd för BLOB '%-.64s'",
+"Felaktigt kolumnnamn '%-.100s'",
+"Den använda tabelltypen kan inte indexera kolumn '%-.64s'",
+"Tabellerna i MERGE-tabellen är inte identiskt definierade",
+"Kan inte skriva till tabell '%-.64s'; UNIQUE-test",
+"Du har inte angett någon nyckellängd för BLOB '%-.64s'",
"Alla delar av en PRIMARY KEY måste vara NOT NULL; Om du vill ha en nyckel med NULL, använd UNIQUE istället",
"Resultet bestod av mera än en rad",
-"Denna tabell typ kräver en PRIMARY KEY",
+"Denna tabelltyp kräver en PRIMARY KEY",
"Denna version av MySQL är inte kompilerad med RAID",
-"Du använder 'säker uppdaterings mod' och försökte uppdatera en table utan en WHERE sats som använder sig av en nyckel",
+"Du använder 'säker uppdateringsmod' och försökte uppdatera en tabell utan en WHERE-sats som använder sig av en nyckel",
"Nyckel '%-.64s' finns inte in tabell '%-.64s'",
"Kan inte öppna tabellen",
-"Tabellhanteraren för denna tabell kan inte göra check/repair",
+"Tabellhanteraren för denna tabell kan inte göra %s",
"Du får inte utföra detta kommando i en transaktion",
"Fick fel %d vid COMMIT",
"Fick fel %d vid ROLLBACK",
"Fick fel %d vid FLUSH_LOGS",
"Fick fel %d vid CHECKPOINT",
-"Avbröt länken för tråd %ld till db: '%-.64s' användare: '%-.32s' Host: '%-.64s' (%.-64s)",
+"Avbröt länken för tråd %ld till db '%-.64s', användare '%-.32s', host '%-.64s' (%.-64s)",
"Tabellhanteraren klarar inte en binär kopiering av tabellen",
-"Binärloggen stängdes medan vi gjorde FLUSH MASTER",
+"Binärloggen stängdes medan FLUSH MASTER utfördes",
"Failed rebuilding the index of dumped table '%-.64s'",
"Fick en master: '%-.64s'",
"Fick nätverksfel vid läsning från master",
"Fick nätverksfel vid skrivning till master",
-"Hittar inte ett FULLTEXT index i kolumnlistan",
-"Kan inte exekvera kommandot emedan du har en låst tabell eller an aktiv transaktion",
-"Okänd system variabel '%-.64s'",
-"Tabell '%-.64s' är crashad och bör repareras med REPAIR TABLE",
-"Tabell '%-.64s' är crashad och senast (automatiska?) reparation misslyckades",
+"Hittar inte ett FULLTEXT-index i kolumnlistan",
+"Kan inte utföra kommandot emedan du har en låst tabell eller an aktiv transaktion",
+"Okänd systemvariabel: '%-.64s'",
+"Tabell '%-.64s' är trasig och bör repareras med REPAIR TABLE",
+"Tabell '%-.64s' är trasig och senast (automatiska?) reparation misslyckades",
"Warning: Några icke transaktionella tabeller kunde inte återställas vid ROLLBACK",
-"Transaktionen krävde mera än 'max_binlog_cache_size' minne. Utöka denna mysqld variabel och försök på nytt",
+"Transaktionen krävde mera än 'max_binlog_cache_size' minne. Öka denna mysqld-variabel och försök på nytt",
"Denna operation kan inte göras under replikering; Gör SLAVE STOP först",
"Denna operation kan endast göras under replikering; Konfigurera slaven och gör SLAVE START",
-"Servern är inte konfigurerade som en replikations slav. Ändra konfigurationsfilen eller gör CHANGE MASTER TO",
-"Kunde inte initializera replications-strukturerna. Kontrollera privilegerna för 'master.info'",
+"Servern är inte konfigurerade som en replikationsslav. Ändra konfigurationsfilen eller gör CHANGE MASTER TO",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"Kunde inte starta en tråd för replikering",
"Användare '%-.64s' har redan 'max_user_connections' aktiva inloggningar",
-"Man kan endast använda konstant-uttryck med SET",
+"Man kan endast använda konstantuttryck med SET",
"Fick inte ett lås i tid ; Försök att starta om transaktionen",
"Antal lås överskrider antalet reserverade lås",
-"Updaterings-lås kan inte göras när man använder READ UNCOMMITTED",
-"DROP DATABASE är inte tillåtet när man har ett globalt läs-lås",
-"CREATE DATABASE är inte tillåtet när man har ett globalt läs-lås",
+"Updateringslås kan inte göras när man använder READ UNCOMMITTED",
+"DROP DATABASE är inte tillåtet när man har ett globalt läslås",
+"CREATE DATABASE är inte tillåtet när man har ett globalt läslås",
"Felaktiga argument till %s",
"%-.32s@%-.64s har inte rättighet att skapa nya användare",
-"Felaktig tabell definition: Alla tabeller i en MERGE tabell måste vara i samma databas",
-"Fick 'DEADLOCK' vid låsförsök av block/rad; Försök att starta om transaktionen",
-"Tabelltypen har inte hantering av FULLTEXT index",
+"Felaktig tabelldefinition. Alla tabeller i en MERGE-tabell måste vara i samma databas",
+"Fick 'DEADLOCK' vid låsförsök av block/rad. Försök att starta om transaktionen",
+"Tabelltypen har inte hantering av FULLTEXT-index",
"Kan inte lägga till 'FOREIGN KEY constraint'",
-"FOREIGN KEY konflikt: Kan inte skriva barn",
-"FOREIGN KEY konflikt: Kan inte radera fader",
+"FOREIGN KEY-konflikt: Kan inte skriva barn",
+"FOREIGN KEY-konflikt: Kan inte radera fader",
+"Fick fel vid anslutning till master: %-.128s",
+"Fick fel vid utförande av command på mastern: %-.128s",
+"Fick fel vid utförande av %s: %-.128s",
+"Felaktig använding av %s and %s",
+"SELECT-kommandona har olika antal kolumner"
+"Kan inte utföra kommandot emedan du har ett READ-lås",
+"Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat",
+"Option '%s' användes två gånger",
+"Användare '%-.64s' har överskridit '%s' (nuvarande värde: %ld)",
+"Du har inte privlegiet '%-.128s' som behövs för denna operation",
+"Variabel '%-.64s' är en LOCAL variabel och kan inte ändrad med SET GLOBAL",
+"Variabel '%-.64s' är en GLOBAL variabel och bör sättas med SET GLOBAL",
+"Variabel '%-.64s' har inte ett DEFAULT-värde",
+"Variabel '%-.64s' kan inte sättas till '%-.64s'",
+"Fel typ av argument till variabel '%-.64s'",
+"Variabeln '%-.64s' kan endast sättas, inte läsas",
+"Fel använding/placering av '%s'",
+"Denna version av MySQL kan ännu inte utföra '%s'",
+"Fick fatalt fel %d: '%-.128s' från master vid läsning av binärloggen"
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt
index 7772f54d483..372cfa78dff 100644
--- a/sql/share/ukrainian/errmsg.txt
+++ b/sql/share/ukrainian/errmsg.txt
@@ -110,7 +110,7 @@
"óÔÏ×ÂÅÃØ BLOB '%-.64s' ÎÅ ÍÏÖÅ ÍÁÔÉ ÚÎÁÞÅÎÎÑ ÐÏ ÚÁÍÏ×ÞÕ×ÁÎÎÀ",
"îÅצÒÎÅ ¦Í'Ñ ÂÁÚÉ ÄÁÎÎÉÈ '%-.100s'",
"îÅצÒÎÅ ¦Í'Ñ ÔÁÂÌÉæ '%-.100s'",
-"úÁÐÉÔÕ SELECT ÐÏÔÒ¦ÂÎÏ ÏÂÒÏÂÉÔÉ ÂÁÇÁÔÏ ÚÁÐÉÓ¦×, ÝÏ, ÐÅ×ÎÅ, ÚÁÊÍÅ ÄÕÖÅ ÂÁÇÁÔÏ ÞÁÓÕ. ðÅÒÅצÒÔÅ ×ÁÛÅ WHERE ÔÁ ×ÉËÏÒÉÓÔÏ×ÕÊÔÅ SET OPTION SQL_BIG_SELECTS=1, ÑËÝÏ ÃÅÊ ÚÁÐÉÔ SELECT ¤ צÒÎÉÍ",
+"úÁÐÉÔÕ SELECT ÐÏÔÒ¦ÂÎÏ ÏÂÒÏÂÉÔÉ ÂÁÇÁÔÏ ÚÁÐÉÓ¦×, ÝÏ, ÐÅ×ÎÅ, ÚÁÊÍÅ ÄÕÖÅ ÂÁÇÁÔÏ ÞÁÓÕ. ðÅÒÅצÒÔÅ ×ÁÛÅ WHERE ÔÁ ×ÉËÏÒÉÓÔÏ×ÕÊÔÅ SET SQL_BIG_SELECTS=1, ÑËÝÏ ÃÅÊ ÚÁÐÉÔ SELECT ¤ צÒÎÉÍ",
"îÅצÄÏÍÁ ÐÏÍÉÌËÁ",
"îÅצÄÏÍÁ ÐÒÏÃÅÄÕÒÁ '%-.64s'",
"èÉÂÎÁ ˦ÌØ˦ÓÔØ ÐÁÒÁÍÅÔÒ¦× ÐÒÏÃÅÄÕÒÉ '%-.64s'",
@@ -184,7 +184,7 @@
"÷É Õ ÒÅÖÉͦ ÂÅÚÐÅÞÎÏÇÏ ÏÎÏ×ÌÅÎÎÑ ÔÁ ÎÁÍÁÇÁ¤ÔÅÓØ ÏÎÏ×ÉÔÉ ÔÁÂÌÉÃÀ ÂÅÚ ÏÐÅÒÁÔÏÒÁ WHERE, ÝÏ ×ÉËÏÒÉÓÔÏ×Õ¤ KEY ÓÔÏ×ÂÅÃØ",
"ëÌÀÞ '%-.64s' ÎÅ ¦ÓÎÕ¤ × ÔÁÂÌÉæ '%-.64s'",
"îÅ ÍÏÖÕ ×¦ÄËÒÉÔÉ ÔÁÂÌÉÃÀ",
-"÷ËÁÚ¦×ÎÉË ÔÁÂÌÉæ ΊЦÄÔÒÉÍÕÅ ÐÅÒÅצÒËÕ/צÄÎÏ×ÌÅÎÎÑ",
+"÷ËÁÚ¦×ÎÉË ÔÁÂÌÉæ ΊЦÄÔÒÉÍÕÅ %s",
"÷ÁÍ ÎÅ ÄÏÚ×ÏÌÅÎÏ ×ÉËÏÎÕ×ÁÔÉ ÃÀ ËÏÍÁÎÄÕ × ÔÒÁÎÚÁËæ§",
"ïÔÒÉÍÁÎÏ ÐÏÍÉÌËÕ %d Ð¦Ä ÞÁÓ COMMIT",
"ïÔÒÉÍÁÎÏ ÐÏÍÉÌËÕ %d Ð¦Ä ÞÁÓ ROLLBACK",
@@ -207,7 +207,7 @@
"ïÐÅÒÁÃ¦Ñ ÎÅ ÍÏÖÅ ÂÕÔÉ ×ÉËÏÎÁÎÁ Ú ÚÁÐÕÝÅÎÉÍ Ð¦ÄÌÅÇÌÉÍ, ÓÐÏÞÁÔËÕ ×ÉËÏÎÁÊÔÅ SLAVE STOP",
"ïÐÅÒÁÃ¦Ñ ×ÉÍÁÇÁ¤ ÚÁÐÕÝÅÎÏÇÏ Ð¦ÄÌÅÇÌÏÇÏ, ÚËÏÎƦÇÕÒÕÊÔŠЦÄÌÅÇÌÏÇÏ ÔÁ ×ÉËÏÎÁÊÔÅ SLAVE START",
"óÅÒ×ÅÒ ÎÅ ÚËÏÎƦÇÕÒÏ×ÁÎÏ ÑË Ð¦ÄÌÅÇÌÉÊ, ×ÉÐÒÁ×ÔÅ ÃÅ Õ ÆÁÊ̦ ËÏÎƦÇÕÒÁæ§ ÁÂÏ Ú CHANGE MASTER TO",
-"îÅ ÍÏÖÕ ¦Î¦Ã¦Á̦ÚÕ×ÁÔÉ ÓÔÒÕËÔÕÒÕ ÉÎÆÏÒÍÁæ§ ÇÏÌÏ×ÎÏÇÏ, ÐÅÒÅצÒÔÅ ÐÒÁ×Á ÄÏÓÔÕÐÕ ÎÁ master.info",
+"Could not initialize master info structure, more error messages can be found in the MySQL error log",
"îÅ ÍÏÖÕ ÓÔ×ÏÒÉÔÉ Ð¦ÄÌÅÇÌÕ Ç¦ÌËÕ, ÐÅÒÅצÒÔÅ ÓÉÓÔÅÍΦ ÒÅÓÕÒÓÉ",
"ëÏÒÉÓÔÕ×ÁÞ %-.64s ×ÖÅ ÍÁ¤ ¦ÌØÛÅ Î¦Ö 'max_user_connections' ÁËÔÉ×ÎÉÈ Ú'¤ÄÎÁÎØ",
"íÏÖÎÁ ×ÉËÏÒÉÓÔÏ×Õ×ÁÔÉ ÌÉÛÅ ×ÉÒÁÚÉ Ú¦ ÓÔÁÌÉÍÉ Õ SET",
@@ -224,3 +224,24 @@
"Cannot add foreign key constraint",
"Cannot add a child row: a foreign key constraint fails",
"Cannot delete a parent row: a foreign key constraint fails",
+"Error connecting to master: %-.128s",
+"Error running query on master: %-.128s",
+"Error when executing command %s: %-.128s",
+"Wrong usage of %s and %s",
+"The used SELECT statements have a different number of columns",
+"Can't execute the query because you have a conflicting read lock",
+"Mixing of transactional and non-transactional tables is disabled",
+"Option '%s' used twice in statement",
+"User '%-.64s' has exceeded the '%s' resource (current value: %ld)",
+"Access denied. You need the %-.128s privilege for this operation",
+"Variable '%-.64s' is a LOCAL variable and can't be used with SET GLOBAL",
+"Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL",
+"Variable '%-.64s' doesn't have a default value",
+"Variable '%-.64s' can't be set to the value of '%-.64s'",
+"Wrong argument type to variable '%-.64s'",
+"Variable '%-.64s' can only be set, not read",
+"Wrong usage/placement of '%s'",
+"This version of MySQL doesn't yet support '%s'",
+"Got fatal error %d: '%-.128s' from master when reading data from binary log",
+"Slave SQL thread ignored the query because of replicate-*-table rules"
+"Variable '%-.64s' is a %s variable"
diff --git a/sql/slave.cc b/sql/slave.cc
index a51db52cc7f..d6510b26271 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,49 +20,152 @@
#include <myisam.h>
#include "mini_client.h"
#include "slave.h"
+#include "sql_repl.h"
+#include "repl_failsafe.h"
#include <thr_alarm.h>
#include <my_dir.h>
#include <assert.h>
-#define RPL_LOG_NAME (glob_mi.log_file_name[0] ? glob_mi.log_file_name :\
- "FIRST")
-
-volatile bool slave_running = 0;
-pthread_t slave_real_id;
-MASTER_INFO glob_mi;
-MY_BITMAP slave_error_mask;
bool use_slave_mask = 0;
+MY_BITMAP slave_error_mask;
+
+typedef bool (*CHECK_KILLED_FUNC)(THD*,void*);
+
+volatile bool slave_sql_running = 0, slave_io_running = 0;
+char* slave_load_tmpdir = 0;
+MASTER_INFO *active_mi;
+volatile int active_mi_in_use = 0;
HASH replicate_do_table, replicate_ignore_table;
DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table;
bool do_table_inited = 0, ignore_table_inited = 0;
bool wild_do_table_inited = 0, wild_ignore_table_inited = 0;
bool table_rules_on = 0;
-uint32 slave_skip_counter = 0;
-static TABLE* save_temporary_tables = 0;
-THD* slave_thd = 0;
-// when slave thread exits, we need to remember the temporary tables so we
-// can re-use them on slave start
-
-static int last_slave_errno = 0;
-static char last_slave_error[1024] = "";
-#ifndef DBUG_OFF
-int disconnect_slave_event_count = 0, abort_slave_event_count = 0;
-static int events_till_disconnect = -1, events_till_abort = -1;
-static int stuck_count = 0;
-#endif
+ulonglong relay_log_space_limit = 0;
-inline void skip_load_data_infile(NET* net);
-inline bool slave_killed(THD* thd);
-static int init_slave_thread(THD* thd);
+/*
+ When slave thread exits, we need to remember the temporary tables so we
+ can re-use them on slave start.
+
+ TODO: move the vars below under MASTER_INFO
+*/
+
+int disconnect_slave_event_count = 0, abort_slave_event_count = 0;
+int events_till_abort = -1;
+static int events_till_disconnect = -1;
+
+typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
+
+void skip_load_data_infile(NET* net);
+static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev);
+static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev);
+static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli);
+static inline bool io_slave_killed(THD* thd,MASTER_INFO* mi);
+static inline bool sql_slave_killed(THD* thd,RELAY_LOG_INFO* rli);
+static int count_relay_log_space(RELAY_LOG_INFO* rli);
+static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi);
static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
bool suppress_warnings);
-static int safe_sleep(THD* thd, int sec);
-static int request_table_dump(MYSQL* mysql, char* db, char* table);
+static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
+ bool reconnect, bool suppress_warnings);
+static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
+ void* thread_killed_arg);
+static int request_table_dump(MYSQL* mysql, const char* db, const char* table);
static int create_table_from_dump(THD* thd, NET* net, const char* db,
- const char* table_name);
-inline char* rewrite_db(char* db);
-static int check_expected_error(THD* thd, int expected_error);
+ const char* table_name, bool overwrite);
+static int check_master_version(MYSQL* mysql, MASTER_INFO* mi);
+
+
+/*
+ Get a bit mask for which threads are running so that we later can
+ restart these threads
+*/
+
+void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse)
+{
+ bool set_io = mi->slave_running, set_sql = mi->rli.slave_running;
+ register int tmp_mask=0;
+ if (set_io)
+ tmp_mask |= SLAVE_IO;
+ if (set_sql)
+ tmp_mask |= SLAVE_SQL;
+ if (inverse)
+ tmp_mask^= (SLAVE_IO | SLAVE_SQL);
+ *mask = tmp_mask;
+}
+
+
+void lock_slave_threads(MASTER_INFO* mi)
+{
+ //TODO: see if we can do this without dual mutex
+ pthread_mutex_lock(&mi->run_lock);
+ pthread_mutex_lock(&mi->rli.run_lock);
+}
+
+void unlock_slave_threads(MASTER_INFO* mi)
+{
+ //TODO: see if we can do this without dual mutex
+ pthread_mutex_unlock(&mi->rli.run_lock);
+ pthread_mutex_unlock(&mi->run_lock);
+}
+
+
+int init_slave()
+{
+ DBUG_ENTER("init_slave");
+
+ /* This is called when mysqld starts */
+
+ /*
+ TODO: re-write this to interate through the list of files
+ for multi-master
+ */
+ active_mi= new MASTER_INFO;
+
+ /*
+ If master_host is not specified, try to read it from the master_info file.
+ If master_host is specified, create the master_info file if it doesn't
+ exists.
+ */
+ if (!active_mi)
+ {
+ sql_print_error("Failed to allocate memory for the master info structure");
+ goto err;
+ }
+
+ if (init_master_info(active_mi,master_info_file,relay_log_info_file,
+ !master_host))
+ {
+ sql_print_error("Failed to initialize the master info structure");
+ goto err;
+ }
+
+ /*
+ make sure slave thread gets started if server_id is set,
+ valid master.info is present, and master_host has not been specified
+ */
+ if (server_id && !master_host && active_mi->host[0])
+ master_host= active_mi->host;
+
+ if (master_host && !opt_skip_slave_start)
+ {
+ if (start_slave_threads(1 /* need mutex */,
+ 0 /* no wait for start*/,
+ active_mi,
+ master_info_file,
+ relay_log_info_file,
+ SLAVE_IO | SLAVE_SQL))
+ {
+ sql_print_error("Failed to create slave threads");
+ goto err;
+ }
+ }
+ DBUG_RETURN(0);
+
+err:
+ DBUG_RETURN(1);
+}
+
static void free_table_ent(TABLE_RULE_ENT* e)
{
@@ -76,10 +179,126 @@ static byte* get_table_key(TABLE_RULE_ENT* e, uint* len,
return (byte*)e->db;
}
+
+/*
+ Open the given relay log
+
+ SYNOPSIS
+ init_relay_log_pos()
+ rli Relay information (will be initialized)
+ log Name of relay log file to read from. NULL = First log
+ pos Position in relay log file
+ need_data_lock Set to 1 if this functions should do mutex locks
+ errmsg Store pointer to error message here
+
+ DESCRIPTION
+ - Close old open relay log files.
+ - If we are using the same relay log as the running IO-thread, then set
+ rli->cur_log to point to the same IO_CACHE entry.
+ - If not, open the 'log' binary file.
+
+ TODO
+ - check proper initialization of master_log_name/master_log_pos
+ - We may always want to delete all logs before 'log'.
+ Currently if we are not calling this with 'log' as NULL or the first
+ log we will never delete relay logs.
+ If we want this we should not set skip_log_purge to 1.
+
+ RETURN VALUES
+ 0 ok
+ 1 error. errmsg is set to point to the error message
+*/
+
+int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
+ ulonglong pos, bool need_data_lock,
+ const char** errmsg)
+{
+ DBUG_ENTER("init_relay_log_pos");
+
+ *errmsg=0;
+ pthread_mutex_t *log_lock=rli->relay_log.get_log_lock();
+ pthread_mutex_lock(log_lock);
+ if (need_data_lock)
+ pthread_mutex_lock(&rli->data_lock);
+
+ /* Close log file and free buffers if it's already open */
+ if (rli->cur_log_fd >= 0)
+ {
+ end_io_cache(&rli->cache_buf);
+ my_close(rli->cur_log_fd, MYF(MY_WME));
+ rli->cur_log_fd = -1;
+ }
+
+ rli->relay_log_pos = pos;
+
+ /*
+ Test to see if the previous run was with the skip of purging
+ If yes, we do not purge when we restart
+ */
+ if (rli->relay_log.find_log_pos(&rli->linfo, NullS, 1))
+ {
+ *errmsg="Could not find first log during relay log initialization";
+ goto err;
+ }
+
+ if (log) // If not first log
+ {
+ if (strcmp(log, rli->linfo.log_file_name))
+ rli->skip_log_purge= 1; // Different name; Don't purge
+ if (rli->relay_log.find_log_pos(&rli->linfo, log, 1))
+ {
+ *errmsg="Could not find target log during relay log initialization";
+ goto err;
+ }
+ }
+ strmake(rli->relay_log_name,rli->linfo.log_file_name,
+ sizeof(rli->relay_log_name)-1);
+ if (rli->relay_log.is_active(rli->linfo.log_file_name))
+ {
+ /*
+ The IO thread is using this log file.
+ In this case, we will use the same IO_CACHE pointer to
+ read data as the IO thread is using to write data.
+ */
+ if (my_b_tell((rli->cur_log=rli->relay_log.get_log_file())) == 0 &&
+ check_binlog_magic(rli->cur_log,errmsg))
+ goto err;
+ rli->cur_log_old_open_count=rli->relay_log.get_open_count();
+ }
+ else
+ {
+ /*
+ Open the relay log and set rli->cur_log to point at this one
+ */
+ if ((rli->cur_log_fd=open_binlog(&rli->cache_buf,
+ rli->linfo.log_file_name,errmsg)) < 0)
+ goto err;
+ rli->cur_log = &rli->cache_buf;
+ }
+ if (pos >= BIN_LOG_HEADER_SIZE)
+ my_b_seek(rli->cur_log,(off_t)pos);
+
+err:
+ /*
+ If we don't purge, we can't honour relay_log_space_limit ;
+ silently discard it
+ */
+ if (rli->skip_log_purge)
+ rli->log_space_limit= 0;
+ pthread_cond_broadcast(&rli->data_cond);
+ if (need_data_lock)
+ pthread_mutex_unlock(&rli->data_lock);
+
+ pthread_mutex_unlock(log_lock);
+ DBUG_RETURN ((*errmsg) ? 1 : 0);
+}
+
+
/* called from get_options() in mysqld.cc on start-up */
-void init_slave_skip_errors(char* arg)
+
+void init_slave_skip_errors(const char* arg)
{
- char* p;
+ const char *p;
if (bitmap_init(&slave_error_mask,MAX_SLAVE_ERROR,0))
{
fprintf(stderr, "Badly out of memory, please check your system status\n");
@@ -105,11 +324,289 @@ void init_slave_skip_errors(char* arg)
}
}
+void st_relay_log_info::close_temporary_tables()
+{
+ TABLE *table,*next;
+
+ for (table=save_temporary_tables ; table ; table=next)
+ {
+ next=table->next;
+ /*
+ Don't ask for disk deletion. For now, anyway they will be deleted when
+ slave restarts, but it is a better intention to not delete them.
+ */
+ close_temporary(table, 0);
+ }
+ save_temporary_tables= 0;
+ slave_open_temp_tables= 0;
+}
+
+/*
+ We assume we have a run lock on rli and that both slave thread
+ are not running
+*/
+
+int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
+ const char** errmsg)
+{
+ int error=0;
+ DBUG_ENTER("purge_relay_logs");
+
+ /*
+ Even if rli->inited==0, we still try to empty rli->master_log_* variables.
+ Indeed, rli->inited==0 does not imply that they already are empty.
+ It could be that slave's info initialization partly succeeded :
+ for example if relay-log.info existed but *relay-bin*.*
+ have been manually removed, init_relay_log_info reads the old
+ relay-log.info and fills rli->master_log_*, then init_relay_log_info
+ checks for the existence of the relay log, this fails and
+ init_relay_log_info leaves rli->inited to 0.
+ In that pathological case, rli->master_log_pos* will be properly reinited
+ at the next START SLAVE (as RESET SLAVE or CHANGE
+ MASTER, the callers of purge_relay_logs, will delete bogus *.info files
+ or replace them with correct files), however if the user does SHOW SLAVE
+ STATUS before START SLAVE, he will see old, confusing rli->master_log_*.
+ In other words, we reinit rli->master_log_* for SHOW SLAVE STATUS
+ to display fine in any case.
+ */
+
+ rli->master_log_name[0]= 0;
+ rli->master_log_pos= 0;
+ rli->pending= 0;
+
+ if (!rli->inited)
+ {
+ DBUG_PRINT("info", ("rli->inited == 0"));
+ DBUG_RETURN(0);
+ }
+
+ DBUG_ASSERT(rli->slave_running == 0);
+ DBUG_ASSERT(rli->mi->slave_running == 0);
+
+ rli->slave_skip_counter=0;
+ pthread_mutex_lock(&rli->data_lock);
+ if (rli->relay_log.reset_logs(thd))
+ {
+ *errmsg = "Failed during log reset";
+ error=1;
+ goto err;
+ }
+ /* Save name of used relay log file */
+ strmake(rli->relay_log_name, rli->relay_log.get_log_fname(),
+ sizeof(rli->relay_log_name)-1);
+ // Just first log with magic number and nothing else
+ rli->log_space_total= BIN_LOG_HEADER_SIZE;
+ rli->relay_log_pos= BIN_LOG_HEADER_SIZE;
+ rli->relay_log.reset_bytes_written();
+ if (!just_reset)
+ error= init_relay_log_pos(rli, rli->relay_log_name, rli->relay_log_pos,
+ 0 /* do not need data lock */, errmsg);
+
+err:
+#ifndef DBUG_OFF
+ char buf[22];
+#endif
+ DBUG_PRINT("info",("log_space_total: %s",llstr(rli->log_space_total,buf)));
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(error);
+}
+
+
+int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock)
+{
+ if (!mi->inited)
+ return 0; /* successfully do nothing */
+ int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
+ pthread_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock;
+ pthread_mutex_t *sql_cond_lock,*io_cond_lock;
+ DBUG_ENTER("terminate_slave_threads");
+
+ sql_cond_lock=sql_lock;
+ io_cond_lock=io_lock;
+
+ if (skip_lock)
+ {
+ sql_lock = io_lock = 0;
+ }
+ if ((thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) && mi->slave_running)
+ {
+ DBUG_PRINT("info",("Terminating IO thread"));
+ mi->abort_slave=1;
+ if ((error=terminate_slave_thread(mi->io_thd,io_lock,
+ io_cond_lock,
+ &mi->stop_cond,
+ &mi->slave_running)) &&
+ !force_all)
+ DBUG_RETURN(error);
+ }
+ if ((thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL)) && mi->rli.slave_running)
+ {
+ DBUG_PRINT("info",("Terminating SQL thread"));
+ DBUG_ASSERT(mi->rli.sql_thd != 0) ;
+ mi->rli.abort_slave=1;
+ if ((error=terminate_slave_thread(mi->rli.sql_thd,sql_lock,
+ sql_cond_lock,
+ &mi->rli.stop_cond,
+ &mi->rli.slave_running)) &&
+ !force_all)
+ DBUG_RETURN(error);
+ }
+ DBUG_RETURN(0);
+}
+
+
+int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
+ pthread_mutex_t *cond_lock,
+ pthread_cond_t* term_cond,
+ volatile bool* slave_running)
+{
+ if (term_lock)
+ {
+ pthread_mutex_lock(term_lock);
+ if (!*slave_running)
+ {
+ pthread_mutex_unlock(term_lock);
+ return ER_SLAVE_NOT_RUNNING;
+ }
+ }
+ DBUG_ASSERT(thd != 0);
+ /*
+ Is is criticate to test if the slave is running. Otherwise, we might
+ be referening freed memory trying to kick it
+ */
+ THD_CHECK_SENTRY(thd);
+
+ while (*slave_running) // Should always be true
+ {
+ KICK_SLAVE(thd);
+ /*
+ There is a small chance that slave thread might miss the first
+ alarm. To protect againts it, resend the signal until it reacts
+ */
+ struct timespec abstime;
+ set_timespec(abstime,2);
+ pthread_cond_timedwait(term_cond, cond_lock, &abstime);
+ }
+ if (term_lock)
+ pthread_mutex_unlock(term_lock);
+ return 0;
+}
+
+
+int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock,
+ pthread_mutex_t *cond_lock,
+ pthread_cond_t *start_cond,
+ volatile bool *slave_running,
+ volatile ulong *slave_run_id,
+ MASTER_INFO* mi)
+{
+ pthread_t th;
+ ulong start_id;
+ DBUG_ASSERT(mi->inited);
+ DBUG_ENTER("start_slave_thread");
+
+ if (start_lock)
+ pthread_mutex_lock(start_lock);
+ if (!server_id)
+ {
+ if (start_cond)
+ pthread_cond_broadcast(start_cond);
+ if (start_lock)
+ pthread_mutex_unlock(start_lock);
+ sql_print_error("Server id not set, will not start slave");
+ DBUG_RETURN(ER_BAD_SLAVE);
+ }
+
+ if (*slave_running)
+ {
+ if (start_cond)
+ pthread_cond_broadcast(start_cond);
+ if (start_lock)
+ pthread_mutex_unlock(start_lock);
+ DBUG_RETURN(ER_SLAVE_MUST_STOP);
+ }
+ start_id= *slave_run_id;
+ DBUG_PRINT("info",("Creating new slave thread"));
+ if (pthread_create(&th, &connection_attrib, h_func, (void*)mi))
+ {
+ if (start_lock)
+ pthread_mutex_unlock(start_lock);
+ DBUG_RETURN(ER_SLAVE_THREAD);
+ }
+ if (start_cond && cond_lock)
+ {
+ THD* thd = current_thd;
+ while (start_id == *slave_run_id)
+ {
+ DBUG_PRINT("sleep",("Waiting for slave thread to start"));
+ const char* old_msg = thd->enter_cond(start_cond,cond_lock,
+ "Waiting for slave thread to start");
+ pthread_cond_wait(start_cond,cond_lock);
+ thd->exit_cond(old_msg);
+ if (thd->killed)
+ {
+ pthread_mutex_unlock(cond_lock);
+ DBUG_RETURN(ER_SERVER_SHUTDOWN);
+ }
+ }
+ }
+ if (start_lock)
+ pthread_mutex_unlock(start_lock);
+ DBUG_RETURN(0);
+}
+
+
+/*
+ SLAVE_FORCE_ALL is not implemented here on purpose since it does not make
+ sense to do that for starting a slave - we always care if it actually
+ started the threads that were not previously running
+*/
+
+int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
+ MASTER_INFO* mi, const char* master_info_fname,
+ const char* slave_info_fname, int thread_mask)
+{
+ pthread_mutex_t *lock_io=0,*lock_sql=0,*lock_cond_io=0,*lock_cond_sql=0;
+ pthread_cond_t* cond_io=0,*cond_sql=0;
+ int error=0;
+ DBUG_ENTER("start_slave_threads");
+
+ if (need_slave_mutex)
+ {
+ lock_io = &mi->run_lock;
+ lock_sql = &mi->rli.run_lock;
+ }
+ if (wait_for_start)
+ {
+ cond_io = &mi->start_cond;
+ cond_sql = &mi->rli.start_cond;
+ lock_cond_io = &mi->run_lock;
+ lock_cond_sql = &mi->rli.run_lock;
+ }
+
+ if (thread_mask & SLAVE_IO)
+ error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io,
+ cond_io,
+ &mi->slave_running, &mi->slave_run_id,
+ mi);
+ if (!error && (thread_mask & SLAVE_SQL))
+ {
+ error=start_slave_thread(handle_slave_sql,lock_sql,lock_cond_sql,
+ cond_sql,
+ &mi->rli.slave_running, &mi->rli.slave_run_id,
+ mi);
+ if (error)
+ terminate_slave_threads(mi, thread_mask & SLAVE_IO, 0);
+ }
+ DBUG_RETURN(error);
+}
+
+
void init_table_rule_hash(HASH* h, bool* h_inited)
{
hash_init(h, TABLE_RULE_HASH_SIZE,0,0,
(hash_get_key) get_table_key,
- (void (*)(void*)) free_table_ent, 0);
+ (hash_free_key) free_table_ent, 0);
*h_inited = 1;
}
@@ -125,11 +622,11 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len)
uint i;
const char* key_end = key + len;
- for(i = 0; i < a->elements; i++)
+ for (i = 0; i < a->elements; i++)
{
TABLE_RULE_ENT* e ;
get_dynamic(a, (gptr)&e, i);
- if(!wild_case_compare(key, key_end, (const char*)e->db,
+ if (!wild_case_compare(key, key_end, (const char*)e->db,
(const char*)(e->db + e->key_len),'\\'))
return e;
}
@@ -137,51 +634,130 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len)
return 0;
}
+
+/*
+ Checks whether tables match some (wild_)do_table and (wild_)ignore_table
+ rules (for replication)
+
+ SYNOPSIS
+ tables_ok()
+ thd thread (SQL slave thread normally)
+ tables list of tables to check
+
+ NOTES
+ Note that changing the order of the tables in the list can lead to
+ different results. Note also the order of precedence of the do/ignore
+ rules (see code below). For that reason, users should not set conflicting
+ rules because they may get unpredicted results.
+
+ RETURN VALUES
+ 0 should not be logged/replicated
+ 1 should be logged/replicated
+*/
+
int tables_ok(THD* thd, TABLE_LIST* tables)
{
+ DBUG_ENTER("tables_ok");
+
for (; tables; tables = tables->next)
{
+ char hash_key[2*NAME_LEN+2];
+ char *end;
+ uint len;
+
if (!tables->updating)
continue;
- char hash_key[2*NAME_LEN+2];
- char* p;
- p = strmov(hash_key, tables->db ? tables->db : thd->db);
- *p++ = '.';
- uint len = strmov(p, tables->real_name) - hash_key ;
+ end= strmov(hash_key, tables->db ? tables->db : thd->db);
+ *end++= '.';
+ len= (uint) (strmov(end, tables->real_name) - hash_key);
if (do_table_inited) // if there are any do's
{
if (hash_search(&replicate_do_table, (byte*) hash_key, len))
- return 1;
+ DBUG_RETURN(1);
}
- if (ignore_table_inited) // if there are any do's
+ if (ignore_table_inited) // if there are any ignores
{
if (hash_search(&replicate_ignore_table, (byte*) hash_key, len))
- return 0;
+ DBUG_RETURN(0);
}
if (wild_do_table_inited && find_wild(&replicate_wild_do_table,
hash_key, len))
- return 1;
+ DBUG_RETURN(1);
if (wild_ignore_table_inited && find_wild(&replicate_wild_ignore_table,
hash_key, len))
- return 0;
+ DBUG_RETURN(0);
}
- // if no explicit rule found
- // and there was a do list, do not replicate. If there was
- // no do list, go ahead
- return !do_table_inited && !wild_do_table_inited;
+ /*
+ If no explicit rule found and there was a do list, do not replicate.
+ If there was no do list, go ahead
+ */
+ DBUG_RETURN(!do_table_inited && !wild_do_table_inited);
+}
+
+
+/*
+ Checks whether a db matches wild_do_table and wild_ignore_table
+ rules (for replication)
+
+ SYNOPSIS
+ db_ok_with_wild_table()
+ db name of the db to check.
+ Is tested with check_db_name() before calling this function.
+
+ NOTES
+ Here is the reason for this function.
+ We advise users who want to exclude a database 'db1' safely to do it
+ with replicate_wild_ignore_table='db1.%' instead of binlog_ignore_db or
+ replicate_ignore_db because the two lasts only check for the selected db,
+ which won't work in that case:
+ USE db2;
+ UPDATE db1.t SET ... #this will be replicated and should not
+ whereas replicate_wild_ignore_table will work in all cases.
+ With replicate_wild_ignore_table, we only check tables. When
+ one does 'DROP DATABASE db1', tables are not involved and the
+ statement will be replicated, while users could expect it would not (as it
+ rougly means 'DROP db1.first_table, DROP db1.second_table...').
+ In other words, we want to interpret 'db1.%' as "everything touching db1".
+ That is why we want to match 'db1' against 'db1.%' wild table rules.
+
+ RETURN VALUES
+ 0 should not be logged/replicated
+ 1 should be logged/replicated
+ */
+
+int db_ok_with_wild_table(const char *db)
+{
+ char hash_key[NAME_LEN+2];
+ char *end;
+ int len;
+ end= strmov(hash_key, db);
+ *end++= '.';
+ len= end - hash_key ;
+ if (wild_do_table_inited && find_wild(&replicate_wild_do_table,
+ hash_key, len))
+ return 1;
+ if (wild_ignore_table_inited && find_wild(&replicate_wild_ignore_table,
+ hash_key, len))
+ return 0;
+
+ /*
+ If no explicit rule found and there was a do list, do not replicate.
+ If there was no do list, go ahead
+ */
+ return !wild_do_table_inited;
}
int add_table_rule(HASH* h, const char* table_spec)
{
const char* dot = strchr(table_spec, '.');
- if(!dot) return 1;
+ if (!dot) return 1;
// len is always > 0 because we know the there exists a '.'
uint len = (uint)strlen(table_spec);
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
+ len, MYF(MY_WME));
- if(!e) return 1;
+ if (!e) return 1;
e->db = (char*)e + sizeof(TABLE_RULE_ENT);
e->tbl_name = e->db + (dot - table_spec) + 1;
e->key_len = len;
@@ -193,11 +769,11 @@ int add_table_rule(HASH* h, const char* table_spec)
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
{
const char* dot = strchr(table_spec, '.');
- if(!dot) return 1;
+ if (!dot) return 1;
uint len = (uint)strlen(table_spec);
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
+ len, MYF(MY_WME));
- if(!e) return 1;
+ if (!e) return 1;
e->db = (char*)e + sizeof(TABLE_RULE_ENT);
e->tbl_name = e->db + (dot - table_spec) + 1;
e->key_len = len;
@@ -209,7 +785,7 @@ int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
static void free_string_array(DYNAMIC_ARRAY *a)
{
uint i;
- for(i = 0; i < a->elements; i++)
+ for (i = 0; i < a->elements; i++)
{
char* p;
get_dynamic(a, (gptr) &p, i);
@@ -218,100 +794,186 @@ static void free_string_array(DYNAMIC_ARRAY *a)
delete_dynamic(a);
}
+#ifdef NOT_USED_YET
+
+static int end_slave_on_walk(MASTER_INFO* mi, gptr /*unused*/)
+{
+ end_master_info(mi);
+ return 0;
+}
+#endif
+
+
void end_slave()
{
- pthread_mutex_lock(&LOCK_slave);
- if (slave_running)
+ /* This is called when the server terminates, in close_connections(). */
+ if (active_mi)
{
- abort_slave = 1;
- thr_alarm_kill(slave_real_id);
-#ifdef SIGNAL_WITH_VIO_CLOSE
- slave_thd->close_active_vio();
-#endif
- while (slave_running)
- pthread_cond_wait(&COND_slave_stopped, &LOCK_slave);
+ /*
+ TODO: replace the line below with
+ list_walk(&master_list, (list_walk_action)end_slave_on_walk,0);
+ once multi-master code is ready.
+ */
+ terminate_slave_threads(active_mi,SLAVE_FORCE_ALL);
+ end_master_info(active_mi);
+ if (do_table_inited)
+ hash_free(&replicate_do_table);
+ if (ignore_table_inited)
+ hash_free(&replicate_ignore_table);
+ if (wild_do_table_inited)
+ free_string_array(&replicate_wild_do_table);
+ if (wild_ignore_table_inited)
+ free_string_array(&replicate_wild_ignore_table);
+ delete active_mi;
+ active_mi= 0;
}
- pthread_mutex_unlock(&LOCK_slave);
-
- end_master_info(&glob_mi);
- if(do_table_inited)
- hash_free(&replicate_do_table);
- if(ignore_table_inited)
- hash_free(&replicate_ignore_table);
- if(wild_do_table_inited)
- free_string_array(&replicate_wild_do_table);
- if(wild_ignore_table_inited)
- free_string_array(&replicate_wild_ignore_table);
}
-inline bool slave_killed(THD* thd)
+
+static bool io_slave_killed(THD* thd, MASTER_INFO* mi)
{
- return abort_slave || abort_loop || thd->killed;
+ DBUG_ASSERT(mi->io_thd == thd);
+ DBUG_ASSERT(mi->slave_running == 1); // tracking buffer overrun
+ return mi->abort_slave || abort_loop || thd->killed;
}
-inline void skip_load_data_infile(NET* net)
+
+static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli)
+{
+ DBUG_ASSERT(rli->sql_thd == thd);
+ DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun
+ return rli->abort_slave || abort_loop || thd->killed;
+}
+
+
+/*
+ Writes an error message to rli->last_slave_error and rli->last_slave_errno
+ (which will be displayed by SHOW SLAVE STATUS), and prints it to stderr.
+
+ SYNOPSIS
+ slave_print_error()
+ rli
+ err_code The error code
+ msg The error message (usually related to the error code, but can
+ contain more information).
+ ... (this is printf-like format, with % symbols in msg)
+
+ RETURN VALUES
+ void
+*/
+
+void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...)
+{
+ va_list args;
+ va_start(args,msg);
+ my_vsnprintf(rli->last_slave_error,
+ sizeof(rli->last_slave_error), msg, args);
+ rli->last_slave_errno = err_code;
+ /* If the error string ends with '.', do not add a ',' it would be ugly */
+ if (rli->last_slave_error[0] &&
+ (*(strend(rli->last_slave_error)-1) == '.'))
+ sql_print_error("Slave: %s Error_code: %d", rli->last_slave_error,
+ err_code);
+ else
+ sql_print_error("Slave: %s, Error_code: %d", rli->last_slave_error,
+ err_code);
+
+}
+
+
+void skip_load_data_infile(NET* net)
{
(void)my_net_write(net, "\xfb/dev/null", 10);
(void)net_flush(net);
- (void)my_net_read(net); // discard response
- send_ok(net); // the master expects it
+ (void)my_net_read(net); // discard response
+ send_ok(net); // the master expects it
}
-inline char* rewrite_db(char* db)
+
+const char *rewrite_db(const char* db)
{
- if(replicate_rewrite_db.is_empty() || !db) return db;
+ if (replicate_rewrite_db.is_empty() || !db)
+ return db;
I_List_iterator<i_string_pair> it(replicate_rewrite_db);
i_string_pair* tmp;
- while((tmp=it++))
- {
- if(!strcmp(tmp->key, db))
- return tmp->val;
- }
-
+ while ((tmp=it++))
+ {
+ if (!strcmp(tmp->key, db))
+ return tmp->val;
+ }
return db;
}
+/*
+ From other comments and tests in code, it looks like
+ sometimes Query_log_event and Load_log_event can have db == 0
+ (see rewrite_db() above for example)
+ (cases where this happens are unclear; it may be when the master is 3.23).
+*/
+
+const char *print_slave_db_safe(const char* db)
+{
+ return (db ? rewrite_db(db) : "");
+}
+
+/*
+ Checks whether a db matches some do_db and ignore_db rules
+ (for logging or replication)
+
+ SYNOPSIS
+ db_ok()
+ db name of the db to check
+ do_list either binlog_do_db or replicate_do_db
+ ignore_list either binlog_ignore_db or replicate_ignore_db
+
+ RETURN VALUES
+ 0 should not be logged/replicated
+ 1 should be logged/replicated
+*/
+
int db_ok(const char* db, I_List<i_string> &do_list,
I_List<i_string> &ignore_list )
{
- if(do_list.is_empty() && ignore_list.is_empty())
+ if (do_list.is_empty() && ignore_list.is_empty())
return 1; // ok to replicate if the user puts no constraints
- // if the user has specified restrictions on which databases to replicate
- // and db was not selected, do not replicate
- if(!db)
+ /*
+ If the user has specified restrictions on which databases to replicate
+ and db was not selected, do not replicate.
+ */
+ if (!db)
return 0;
- if(!do_list.is_empty()) // if the do's are not empty
- {
- I_List_iterator<i_string> it(do_list);
- i_string* tmp;
+ if (!do_list.is_empty()) // if the do's are not empty
+ {
+ I_List_iterator<i_string> it(do_list);
+ i_string* tmp;
- while((tmp=it++))
- {
- if(!strcmp(tmp->ptr, db))
- return 1; // match
- }
- return 0;
+ while ((tmp=it++))
+ {
+ if (!strcmp(tmp->ptr, db))
+ return 1; // match
}
+ return 0;
+ }
else // there are some elements in the don't, otherwise we cannot get here
- {
- I_List_iterator<i_string> it(ignore_list);
- i_string* tmp;
+ {
+ I_List_iterator<i_string> it(ignore_list);
+ i_string* tmp;
- while((tmp=it++))
- {
- if(!strcmp(tmp->ptr, db))
- return 0; // match
- }
-
- return 1;
+ while ((tmp=it++))
+ {
+ if (!strcmp(tmp->ptr, db))
+ return 0; // match
}
+ return 1;
+ }
}
-static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f,
- char* default_val)
+
+static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
+ const char *default_val)
{
uint length;
if ((length=my_b_gets(f,var, max_size)))
@@ -321,10 +983,12 @@ static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f,
*last_p = 0; // if we stopped on newline, kill it
else
{
- // if we truncated a line or stopped on last char, remove all chars
- // up to and including newline
+ /*
+ If we truncated a line or stopped on last char, remove all chars
+ up to and including newline.
+ */
int c;
- while( ((c=my_b_get(f)) != '\n' && c != my_b_EOF));
+ while (((c=my_b_get(f)) != '\n' && c != my_b_EOF));
}
return 0;
}
@@ -336,6 +1000,7 @@ static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f,
return 1;
}
+
static int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
{
char buf[32];
@@ -345,7 +1010,7 @@ static int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
*var = atoi(buf);
return 0;
}
- else if(default_val)
+ else if (default_val)
{
*var = default_val;
return 0;
@@ -354,16 +1019,60 @@ static int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
}
+static int check_master_version(MYSQL* mysql, MASTER_INFO* mi)
+{
+ const char* errmsg= 0;
+
+ /*
+ Note the following switch will bug when we have MySQL branch 30 ;)
+ */
+ switch (*mysql->server_version) {
+ case '3':
+ mi->old_format =
+ (strncmp(mysql->server_version, "3.23.57", 7) < 0) /* < .57 */ ?
+ BINLOG_FORMAT_323_LESS_57 :
+ BINLOG_FORMAT_323_GEQ_57 ;
+ break;
+ case '4':
+ mi->old_format = BINLOG_FORMAT_CURRENT;
+ break;
+ default:
+ /* 5.0 is not supported */
+ errmsg = "Master reported an unrecognized MySQL version. Note that 4.0 \
+slaves can't replicate a 5.0 or newer master.";
+ break;
+ }
+
+ if (errmsg)
+ {
+ sql_print_error(errmsg);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ Used by fetch_master_table (used by LOAD TABLE tblname FROM MASTER and LOAD
+ DATA FROM MASTER). Drops the table (if 'overwrite' is true) and recreates it
+ from the dump. Honours replication inclusion/exclusion rules.
+
+ RETURN VALUES
+ 0 success
+ 1 error
+*/
+
static int create_table_from_dump(THD* thd, NET* net, const char* db,
- const char* table_name)
+ const char* table_name, bool overwrite)
{
- uint packet_len = my_net_read(net); // read create table statement
+ ulong packet_len = my_net_read(net); // read create table statement
+ char *query;
+ char* save_db;
Vio* save_vio;
HA_CHECK_OPT check_opt;
TABLE_LIST tables;
int error= 1;
handler *file;
- char *query;
+ ulong save_options;
if (packet_len == packet_error)
{
@@ -397,21 +1106,34 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
thd->current_tablenr = 0;
thd->query_error = 0;
thd->net.no_send_ok = 1;
+
+ bzero((char*) &tables,sizeof(tables));
+ tables.db = (char*)db;
+ tables.alias= tables.real_name= (char*)table_name;
+ /* Drop the table if 'overwrite' is true */
+ if (overwrite && mysql_rm_table(thd,&tables,1)) /* drop if exists */
+ {
+ send_error(&thd->net);
+ sql_print_error("create_table_from_dump: failed to drop the table");
+ goto err;
+ }
+
+ /* Create the table. We do not want to log the "create table" statement */
+ save_options = thd->options;
+ thd->options &= ~(ulong) (OPTION_BIN_LOG);
thd->proc_info = "Creating table from master dump";
// save old db in case we are creating in a different database
- char* save_db = thd->db;
- thd->db = thd->last_nx_db;
+ save_db = thd->db;
+ thd->db = (char*)db;
mysql_parse(thd, thd->query, packet_len); // run create table
thd->db = save_db; // leave things the way the were before
+ thd->options = save_options;
if (thd->query_error)
goto err; // mysql_parse took care of the error send
- bzero((char*) &tables,sizeof(tables));
- tables.db = (char*)db;
- tables.alias= tables.real_name= (char*)table_name;
- tables.lock_type = TL_WRITE;
thd->proc_info = "Opening master dump table";
+ tables.lock_type = TL_WRITE;
if (!open_ltable(thd, &tables, TL_WRITE))
{
send_error(&thd->net,0,0); // Send error from open_ltable
@@ -421,23 +1143,26 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
file = tables.table->file;
thd->proc_info = "Reading master dump table data";
+ /* Copy the data file */
if (file->net_read_dump(net))
{
net_printf(&thd->net, ER_MASTER_NET_READ);
- sql_print_error("create_table_from_dump::failed in\
+ sql_print_error("create_table_from_dump: failed in\
handler::net_read_dump()");
goto err;
}
check_opt.init();
- check_opt.flags|= T_VERY_SILENT | T_CALC_CHECKSUM;
- check_opt.quick = 1;
+ check_opt.flags|= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK;
thd->proc_info = "Rebuilding the index on master dump table";
- // we do not want repair() to spam us with messages
- // just send them to the error log, and report the failure in case of
- // problems
+ /*
+ We do not want repair() to spam us with messages
+ just send them to the error log, and report the failure in case of
+ problems.
+ */
save_vio = thd->net.vio;
thd->net.vio = 0;
+ /* Rebuild the index file from the copied data file (with REPAIR) */
error=file->repair(thd,&check_opt) != 0;
thd->net.vio = save_vio;
if (error)
@@ -449,344 +1174,922 @@ err:
return error;
}
-int fetch_nx_table(THD* thd, MASTER_INFO* mi)
+int fetch_master_table(THD *thd, const char *db_name, const char *table_name,
+ MASTER_INFO *mi, MYSQL *mysql, bool overwrite)
{
- MYSQL* mysql = mc_mysql_init(NULL);
- int error = 1;
- int nx_errno = 0;
- if (!mysql)
+ int error= 1;
+ const char *errmsg=0;
+ bool called_connected= (mysql != NULL);
+ DBUG_ENTER("fetch_master_table");
+ DBUG_PRINT("enter", ("db_name: '%s' table_name: '%s'",
+ db_name,table_name));
+
+ if (!called_connected)
+ {
+ if (!(mysql = mc_mysql_init(NULL)))
+ {
+ send_error(&thd->net); // EOM
+ DBUG_RETURN(1);
+ }
+ if (connect_to_master(thd, mysql, mi))
+ {
+ net_printf(&thd->net, ER_CONNECT_TO_MASTER, mc_mysql_error(mysql));
+ mc_mysql_close(mysql);
+ DBUG_RETURN(1);
+ }
+ if (thd->killed)
+ goto err;
+ }
+
+ if (request_table_dump(mysql, db_name, table_name))
{
- sql_print_error("fetch_nx_table: Error in mysql_init()");
- nx_errno = ER_GET_ERRNO;
+ error= ER_UNKNOWN_ERROR;
+ errmsg= "Failed on table dump request";
goto err;
}
- if (!mi->host || !*mi->host)
+ if (create_table_from_dump(thd, &mysql->net, db_name,
+ table_name, overwrite))
+ goto err; // create_table_from_dump will have send_error already
+ error = 0;
+
+ err:
+ thd->net.no_send_ok = 0; // Clear up garbage after create_table_from_dump
+ if (!called_connected)
+ mc_mysql_close(mysql);
+ if (errmsg && thd->net.vio)
+ send_error(&thd->net, error, errmsg);
+ DBUG_RETURN(test(error)); // Return 1 on error
+}
+
+
+void end_master_info(MASTER_INFO* mi)
+{
+ DBUG_ENTER("end_master_info");
+
+ if (!mi->inited)
+ DBUG_VOID_RETURN;
+ end_relay_log_info(&mi->rli);
+ if (mi->fd >= 0)
+ {
+ end_io_cache(&mi->file);
+ (void)my_close(mi->fd, MYF(MY_WME));
+ mi->fd = -1;
+ }
+ mi->inited = 0;
+
+ DBUG_VOID_RETURN;
+}
+
+
+int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
+{
+ char fname[FN_REFLEN+128];
+ int info_fd;
+ const char* msg = 0;
+ int error = 0;
+ DBUG_ENTER("init_relay_log_info");
+
+ if (rli->inited) // Set if this function called
+ DBUG_RETURN(0);
+ fn_format(fname, info_fname, mysql_data_home, "", 4+32);
+ pthread_mutex_lock(&rli->data_lock);
+ info_fd = rli->info_fd;
+ rli->pending = 0;
+ rli->cur_log_fd = -1;
+ rli->slave_skip_counter=0;
+ rli->abort_pos_wait=0;
+ rli->skip_log_purge=0;
+ rli->log_space_limit = relay_log_space_limit;
+ rli->log_space_total = 0;
+
+ // TODO: make this work with multi-master
+ if (!opt_relay_logname)
{
- nx_errno = ER_BAD_HOST_ERROR;
- goto err;
+ char tmp[FN_REFLEN];
+ /*
+ TODO: The following should be using fn_format(); We just need to
+ first change fn_format() to cut the file name if it's too long.
+ */
+ strmake(tmp,glob_hostname,FN_REFLEN-5);
+ strmov(strcend(tmp,'.'),"-relay-bin");
+ opt_relay_logname=my_strdup(tmp,MYF(MY_WME));
}
- safe_connect(thd, mysql, mi);
- if (slave_killed(thd))
- goto err;
+ /*
+ The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE. It is
+ notable that the last kilobytes of it (8 kB for example) may live in
+ memory, not on disk (depending on what the thread using it does). While
+ this is efficient, it has a side-effect one must know:
+ The size of the relay log on disk (displayed by 'ls -l' on Unix) can be a
+ few kilobytes less than one would expect by doing SHOW SLAVE STATUS; this
+ happens when only the IO thread is started (not the SQL thread). The
+ "missing" kilobytes are in memory, are preserved during 'STOP SLAVE; START
+ SLAVE IO_THREAD', and are flushed to disk when the slave's mysqld stops. So
+ this does not cause any bug. Example of how disk size grows by leaps:
+
+ Read_Master_Log_Pos: 7811 -rw-rw---- 1 guilhem qq 4 Jun 5 16:19 gbichot2-relay-bin.002
+ ...later...
+ Read_Master_Log_Pos: 9744 -rw-rw---- 1 guilhem qq 8192 Jun 5 16:27 gbichot2-relay-bin.002
+
+ See how 4 is less than 7811 and 8192 is less than 9744.
+
+ WARNING: this is risky because the slave can stay like this for a long
+ time; then if it has a power failure, master.info says the I/O thread has
+ read until 9744 while the relay-log contains only until 8192 (the
+ in-memory part from 8192 to 9744 has been lost), so the SQL slave thread
+ will miss some events, silently breaking replication.
+ Ideally we would like to flush master.info only when we know that the relay
+ log has no in-memory tail.
+ Note that the above problem may arise only when only the IO thread is
+ started, which is unlikely.
+ */
- if (request_table_dump(mysql, thd->last_nx_db, thd->last_nx_table))
+ /*
+ For the maximum log size, we choose max_relay_log_size if it is
+ non-zero, max_binlog_size otherwise. If later the user does SET
+ GLOBAL on one of these variables, fix_max_binlog_size and
+ fix_max_relay_log_size will reconsider the choice (for example
+ if the user changes max_relay_log_size to zero, we have to
+ switch to using max_binlog_size for the relay log) and update
+ rli->relay_log.max_size (and mysql_bin_log.max_size).
+ */
+
+ if (open_log(&rli->relay_log, glob_hostname, opt_relay_logname,
+ "-relay-bin", opt_relaylog_index_name,
+ LOG_BIN, 1 /* read_append cache */,
+ 1 /* no auto events */,
+ max_relay_log_size ? max_relay_log_size : max_binlog_size))
{
- nx_errno = ER_GET_ERRNO;
- sql_print_error("fetch_nx_table: failed on table dump request ");
- goto err;
+ pthread_mutex_unlock(&rli->data_lock);
+ sql_print_error("Failed in open_log() called from init_relay_log_info()");
+ DBUG_RETURN(1);
}
- if (create_table_from_dump(thd, &mysql->net, thd->last_nx_db,
- thd->last_nx_table))
+ /* if file does not exist */
+ if (access(fname,F_OK))
{
- // create_table_from_dump will have sent the error alread
- sql_print_error("fetch_nx_table: failed on create table ");
+ /*
+ If someone removed the file from underneath our feet, just close
+ the old descriptor and re-create the old file
+ */
+ if (info_fd >= 0)
+ my_close(info_fd, MYF(MY_WME));
+ if ((info_fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0)
+ {
+ sql_print_error("Failed to create a new relay log info file (\
+file '%s', errno %d)", fname, my_errno);
+ msg= current_thd->net.last_error;
+ goto err;
+ }
+ if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0,
+ MYF(MY_WME)))
+ {
+ sql_print_error("Failed to create a cache on relay log info file '%s'",
+ fname);
+ msg= current_thd->net.last_error;
+ goto err;
+ }
+
+ /* Init relay log with first entry in the relay index file */
+ if (init_relay_log_pos(rli,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */,
+ &msg))
+ {
+ sql_print_error("Failed to open the relay log 'FIRST' (relay_log_pos 4)");
+ goto err;
+ }
+ rli->master_log_name[0]= 0;
+ rli->master_log_pos= 0;
+ rli->info_fd= info_fd;
+ }
+ else // file exists
+ {
+ if (info_fd >= 0)
+ reinit_io_cache(&rli->info_file, READ_CACHE, 0L,0,0);
+ else
+ {
+ int error=0;
+ if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0)
+ {
+ sql_print_error("\
+Failed to open the existing relay log info file '%s' (errno %d)",
+ fname, my_errno);
+ error= 1;
+ }
+ else if (init_io_cache(&rli->info_file, info_fd,
+ IO_SIZE*2, READ_CACHE, 0L, 0, MYF(MY_WME)))
+ {
+ sql_print_error("Failed to create a cache on relay log info file '%s'",
+ fname);
+ error= 1;
+ }
+ if (error)
+ {
+ if (info_fd >= 0)
+ my_close(info_fd, MYF(0));
+ rli->info_fd= -1;
+ rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(1);
+ }
+ }
+
+ rli->info_fd = info_fd;
+ int relay_log_pos, master_log_pos;
+ if (init_strvar_from_file(rli->relay_log_name,
+ sizeof(rli->relay_log_name), &rli->info_file,
+ "") ||
+ init_intvar_from_file(&relay_log_pos,
+ &rli->info_file, BIN_LOG_HEADER_SIZE) ||
+ init_strvar_from_file(rli->master_log_name,
+ sizeof(rli->master_log_name), &rli->info_file,
+ "") ||
+ init_intvar_from_file(&master_log_pos, &rli->info_file, 0))
+ {
+ msg="Error reading slave log configuration";
+ goto err;
+ }
+ rli->relay_log_pos= relay_log_pos;
+ rli->master_log_pos= master_log_pos;
+
+ if (init_relay_log_pos(rli,
+ rli->relay_log_name,
+ rli->relay_log_pos,
+ 0 /* no data lock*/,
+ &msg))
+ {
+ char llbuf[22];
+ sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s)",
+ rli->relay_log_name, llstr(rli->relay_log_pos, llbuf));
+ goto err;
+ }
+ }
+ DBUG_ASSERT(rli->relay_log_pos >= BIN_LOG_HEADER_SIZE);
+ DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->relay_log_pos);
+ /*
+ Now change the cache from READ to WRITE - must do this
+ before flush_relay_log_info
+ */
+ reinit_io_cache(&rli->info_file, WRITE_CACHE,0L,0,1);
+ if ((error= flush_relay_log_info(rli)))
+ sql_print_error("Failed to flush relay log info file");
+ if (count_relay_log_space(rli))
+ {
+ msg="Error counting relay log space";
goto err;
}
-
- error = 0;
+ rli->inited= 1;
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(error);
- err:
- if (mysql)
- mc_mysql_close(mysql);
- if (nx_errno && thd->net.vio)
- send_error(&thd->net, nx_errno, "Error in fetch_nx_table");
- thd->net.no_send_ok = 0; // Clear up garbage after create_table_from_dump
- return error;
+err:
+ sql_print_error(msg);
+ end_io_cache(&rli->info_file);
+ if (info_fd >= 0)
+ my_close(info_fd, MYF(0));
+ rli->info_fd= -1;
+ rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(1);
}
-void end_master_info(MASTER_INFO* mi)
+
+static inline int add_relay_log(RELAY_LOG_INFO* rli,LOG_INFO* linfo)
{
- if(mi->fd >= 0)
- {
- end_io_cache(&mi->file);
- (void)my_close(mi->fd, MYF(MY_WME));
- mi->fd = -1;
- }
- mi->inited = 0;
+ MY_STAT s;
+ DBUG_ENTER("add_relay_log");
+ if (!my_stat(linfo->log_file_name,&s,MYF(0)))
+ {
+ sql_print_error("log %s listed in the index, but failed to stat",
+ linfo->log_file_name);
+ DBUG_RETURN(1);
+ }
+ rli->log_space_total += s.st_size;
+#ifndef DBUG_OFF
+ char buf[22];
+ DBUG_PRINT("info",("log_space_total: %s", llstr(rli->log_space_total,buf)));
+#endif
+ DBUG_RETURN(0);
}
-int init_master_info(MASTER_INFO* mi)
+
+static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli)
{
- if (mi->inited)
- return 0;
- int fd,length,error;
- MY_STAT stat_area;
+ bool slave_killed=0;
+ MASTER_INFO* mi = rli->mi;
+ THD* thd = mi->io_thd;
+
+ DBUG_ENTER("wait_for_relay_log_space");
+ pthread_mutex_lock(&rli->log_space_lock);
+ const char* save_proc_info= thd->enter_cond(&rli->log_space_cond,
+ &rli->log_space_lock,
+ "Waiting for the SQL slave \
+thread to free enough relay log space");
+ while (rli->log_space_limit < rli->log_space_total &&
+ !(slave_killed=io_slave_killed(thd,mi)) &&
+ !rli->ignore_log_space_limit)
+ pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
+ thd->exit_cond(save_proc_info);
+ pthread_mutex_unlock(&rli->log_space_lock);
+ DBUG_RETURN(slave_killed);
+}
+
+
+static int count_relay_log_space(RELAY_LOG_INFO* rli)
+{
+ LOG_INFO linfo;
+ DBUG_ENTER("count_relay_log_space");
+ rli->log_space_total = 0;
+ if (rli->relay_log.find_log_pos(&linfo, NullS, 1))
+ {
+ sql_print_error("Could not find first log while counting relay log space");
+ DBUG_RETURN(1);
+ }
+ do
+ {
+ if (add_relay_log(rli,&linfo))
+ DBUG_RETURN(1);
+ } while (!rli->relay_log.find_next_log(&linfo, 1));
+ /*
+ As we have counted everything, including what may have written in a
+ preceding write, we must reset bytes_written, or we may count some space
+ twice.
+ */
+ rli->relay_log.reset_bytes_written();
+ DBUG_RETURN(0);
+}
+
+void init_master_info_with_options(MASTER_INFO* mi)
+{
+ mi->master_log_name[0] = 0;
+ mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number
+
+ if (master_host)
+ strmake(mi->host, master_host, sizeof(mi->host) - 1);
+ if (master_user)
+ strmake(mi->user, master_user, sizeof(mi->user) - 1);
+ if (master_password)
+ strmake(mi->password, master_password, HASH_PASSWORD_LENGTH);
+ mi->port = master_port;
+ mi->connect_retry = master_connect_retry;
+}
+
+void clear_last_slave_error(RELAY_LOG_INFO* rli)
+{
+ //Clear the errors displayed by SHOW SLAVE STATUS
+ rli->last_slave_error[0]=0;
+ rli->last_slave_errno=0;
+}
+
+int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
+ const char* slave_info_fname,
+ bool abort_if_no_master_info_file)
+{
+ int fd,error;
char fname[FN_REFLEN+128];
- const char *msg;
- fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
+ DBUG_ENTER("init_master_info");
+
+ if (mi->inited)
+ DBUG_RETURN(0);
+ mi->mysql=0;
+ mi->file_id=1;
+ mi->ignore_stop_event=0;
+ fn_format(fname, master_info_fname, mysql_data_home, "", 4+32);
- // we need a mutex while we are changing master info parameters to
- // keep other threads from reading bogus info
+ /*
+ We need a mutex while we are changing master info parameters to
+ keep other threads from reading bogus info
+ */
- pthread_mutex_lock(&mi->lock);
- mi->pending = 0;
+ pthread_mutex_lock(&mi->data_lock);
fd = mi->fd;
+
+ /* does master.info exist ? */
- // we do not want any messages if the file does not exist
- if (!my_stat(fname, &stat_area, MYF(0)))
+ if (access(fname,F_OK))
{
- // if someone removed the file from underneath our feet, just close
- // the old descriptor and re-create the old file
+ if (abort_if_no_master_info_file)
+ {
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(0);
+ }
+ /*
+ if someone removed the file from underneath our feet, just close
+ the old descriptor and re-create the old file
+ */
if (fd >= 0)
my_close(fd, MYF(MY_WME));
- if ((fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0
- || init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
- MYF(MY_WME)))
+ if ((fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
{
- if(fd >= 0)
- my_close(fd, MYF(0));
- pthread_mutex_unlock(&mi->lock);
- return 1;
+ sql_print_error("Failed to create a new master info file (\
+file '%s', errno %d)", fname, my_errno);
+ goto err;
}
- mi->log_file_name[0] = 0;
- mi->pos = 4; // skip magic number
+ if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
+ MYF(MY_WME)))
+ {
+ sql_print_error("Failed to create a cache on master info file (\
+file '%s')", fname);
+ goto err;
+ }
+
mi->fd = fd;
-
- if (master_host)
- strmake(mi->host, master_host, sizeof(mi->host) - 1);
- if (master_user)
- strmake(mi->user, master_user, sizeof(mi->user) - 1);
- if (master_password)
- strmake(mi->password, master_password, HASH_PASSWORD_LENGTH);
- mi->port = master_port;
- mi->connect_retry = master_connect_retry;
+ init_master_info_with_options(mi);
+
}
else // file exists
{
- if(fd >= 0)
+ if (fd >= 0)
reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0);
- else if((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0
- || init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
- 0, MYF(MY_WME)))
- {
- if(fd >= 0)
- my_close(fd, MYF(0));
- pthread_mutex_unlock(&mi->lock);
- return 1;
- }
-
- if ((length=my_b_gets(&mi->file, mi->log_file_name,
- sizeof(mi->log_file_name))) < 1)
- {
- msg="Error reading log file name from master info file ";
- goto error;
- }
-
- mi->log_file_name[length-1]= 0; // kill \n
- /* Reuse fname buffer */
- if(!my_b_gets(&mi->file, fname, sizeof(fname)))
+ else
{
- msg="Error reading log file position from master info file";
- goto error;
+ if ((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
+ {
+ sql_print_error("Failed to open the existing master info file (\
+file '%s', errno %d)", fname, my_errno);
+ goto err;
+ }
+ if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
+ 0, MYF(MY_WME)))
+ {
+ sql_print_error("Failed to create a cache on master info file (\
+file '%s')", fname);
+ goto err;
+ }
}
- mi->pos = strtoull(fname,(char**) 0, 10);
mi->fd = fd;
- if(init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
- master_host) ||
- init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
- master_user) ||
- init_strvar_from_file(mi->password, HASH_PASSWORD_LENGTH+1, &mi->file,
- master_password) ||
- init_intvar_from_file((int*)&mi->port, &mi->file, master_port) ||
- init_intvar_from_file((int*)&mi->connect_retry, &mi->file,
- master_connect_retry))
+ int port, connect_retry, master_log_pos;
+
+ if (init_strvar_from_file(mi->master_log_name,
+ sizeof(mi->master_log_name), &mi->file,
+ "") ||
+ init_intvar_from_file(&master_log_pos, &mi->file, 4) ||
+ init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
+ master_host) ||
+ init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
+ master_user) ||
+ init_strvar_from_file(mi->password, HASH_PASSWORD_LENGTH+1, &mi->file,
+ master_password) ||
+ init_intvar_from_file(&port, &mi->file, master_port) ||
+ init_intvar_from_file(&connect_retry, &mi->file,
+ master_connect_retry))
{
- msg="Error reading master configuration";
- goto error;
+ sql_print_error("Error reading master configuration");
+ goto err;
}
+ /*
+ This has to be handled here as init_intvar_from_file can't handle
+ my_off_t types
+ */
+ mi->master_log_pos= (my_off_t) master_log_pos;
+ mi->port= (uint) port;
+ mi->connect_retry= (uint) connect_retry;
}
-
+ DBUG_PRINT("master_info",("log_file_name: %s position: %ld",
+ mi->master_log_name,
+ (ulong) mi->master_log_pos));
+
+ if (init_relay_log_info(&mi->rli, slave_info_fname))
+ goto err;
+ mi->rli.mi = mi;
+
mi->inited = 1;
- // now change the cache from READ to WRITE - must do this
- // before flush_master_info
- reinit_io_cache(&mi->file, WRITE_CACHE, 0L,0,1);
- error=test(flush_master_info(mi));
- pthread_mutex_unlock(&mi->lock);
- return error;
+ // now change cache READ -> WRITE - must do this before flush_master_info
+ reinit_io_cache(&mi->file, WRITE_CACHE,0L,0,1);
+ if ((error=test(flush_master_info(mi))))
+ sql_print_error("Failed to flush master info file");
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(error);
-error:
- sql_print_error(msg);
- end_io_cache(&mi->file);
- my_close(fd, MYF(0));
- pthread_mutex_unlock(&mi->lock);
- return 1;
+err:
+ if (fd >= 0)
+ {
+ my_close(fd, MYF(0));
+ end_io_cache(&mi->file);
+ }
+ mi->fd= -1;
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(1);
}
-int show_master_info(THD* thd)
+
+int register_slave_on_master(MYSQL* mysql)
{
+ String packet;
+ char buf[4];
+
+ if (!report_host)
+ return 0;
+
+ int4store(buf, server_id);
+ packet.append(buf, 4);
+
+ net_store_data(&packet, report_host);
+ if (report_user)
+ net_store_data(&packet, report_user);
+ else
+ packet.append((char)0);
+
+ if (report_password)
+ net_store_data(&packet, report_user);
+ else
+ packet.append((char)0);
+
+ int2store(buf, (uint16)report_port);
+ packet.append(buf, 2);
+ int4store(buf, rpl_recovery_rank);
+ packet.append(buf, 4);
+ int4store(buf, 0); /* tell the master will fill in master_id */
+ packet.append(buf, 4);
+
+ if (mc_simple_command(mysql, COM_REGISTER_SLAVE, (char*)packet.ptr(),
+ packet.length(), 0))
+ {
+ sql_print_error("Error on COM_REGISTER_SLAVE: %d '%s'",
+ mc_mysql_errno(mysql),
+ mc_mysql_error(mysql));
+ return 1;
+ }
+
+ return 0;
+}
+
+int show_master_info(THD* thd, MASTER_INFO* mi)
+{
+ // TODO: fix this for multi-master
DBUG_ENTER("show_master_info");
List<Item> field_list;
field_list.push_back(new Item_empty_string("Master_Host",
- sizeof(glob_mi.host)));
+ sizeof(mi->host)));
field_list.push_back(new Item_empty_string("Master_User",
- sizeof(glob_mi.user)));
+ sizeof(mi->user)));
field_list.push_back(new Item_empty_string("Master_Port", 6));
field_list.push_back(new Item_empty_string("Connect_retry", 6));
- field_list.push_back( new Item_empty_string("Log_File",
+ field_list.push_back(new Item_empty_string("Master_Log_File",
+ FN_REFLEN));
+ field_list.push_back(new Item_empty_string("Read_Master_Log_Pos", 12));
+ field_list.push_back(new Item_empty_string("Relay_Log_File",
+ FN_REFLEN));
+ field_list.push_back(new Item_empty_string("Relay_Log_Pos", 12));
+ field_list.push_back(new Item_empty_string("Relay_Master_Log_File",
FN_REFLEN));
- field_list.push_back(new Item_empty_string("Pos", 12));
- field_list.push_back(new Item_empty_string("Slave_Running", 3));
+ field_list.push_back(new Item_empty_string("Slave_IO_Running", 3));
+ field_list.push_back(new Item_empty_string("Slave_SQL_Running", 3));
field_list.push_back(new Item_empty_string("Replicate_do_db", 20));
field_list.push_back(new Item_empty_string("Replicate_ignore_db", 20));
field_list.push_back(new Item_empty_string("Last_errno", 4));
field_list.push_back(new Item_empty_string("Last_error", 20));
field_list.push_back(new Item_empty_string("Skip_counter", 12));
- if(send_fields(thd, field_list, 1))
+ field_list.push_back(new Item_empty_string("Exec_master_log_pos", 12));
+ field_list.push_back(new Item_empty_string("Relay_log_space", 12));
+ if (send_fields(thd, field_list, 1))
DBUG_RETURN(-1);
- String* packet = &thd->packet;
- packet->length(0);
+ if (mi->host[0])
+ {
+ DBUG_PRINT("info",("host is set: '%s'", mi->host));
+ String *packet= &thd->packet;
+ packet->length(0);
- pthread_mutex_lock(&glob_mi.lock);
- net_store_data(packet, glob_mi.host);
- net_store_data(packet, glob_mi.user);
- net_store_data(packet, (uint32) glob_mi.port);
- net_store_data(packet, (uint32) glob_mi.connect_retry);
- net_store_data(packet, glob_mi.log_file_name);
- net_store_data(packet, (uint32) glob_mi.pos); // QQ: Should be fixed
- pthread_mutex_unlock(&glob_mi.lock);
- pthread_mutex_lock(&LOCK_slave);
- net_store_data(packet, slave_running ? "Yes":"No");
- pthread_mutex_unlock(&LOCK_slave);
- net_store_data(packet, &replicate_do_db);
- net_store_data(packet, &replicate_ignore_db);
- net_store_data(packet, (uint32)last_slave_errno);
- net_store_data(packet, last_slave_error);
- net_store_data(packet, slave_skip_counter);
+ pthread_mutex_lock(&mi->data_lock);
+ pthread_mutex_lock(&mi->rli.data_lock);
+ net_store_data(packet, mi->host);
+ net_store_data(packet, mi->user);
+ net_store_data(packet, (uint32) mi->port);
+ net_store_data(packet, (uint32) mi->connect_retry);
+ net_store_data(packet, mi->master_log_name);
+ net_store_data(packet, (longlong) mi->master_log_pos);
+ net_store_data(packet, mi->rli.relay_log_name +
+ dirname_length(mi->rli.relay_log_name));
+ net_store_data(packet, (longlong) mi->rli.relay_log_pos);
+ net_store_data(packet, mi->rli.master_log_name);
+ net_store_data(packet, mi->slave_running ? "Yes":"No");
+ net_store_data(packet, mi->rli.slave_running ? "Yes":"No");
+ net_store_data(packet, &replicate_do_db);
+ net_store_data(packet, &replicate_ignore_db);
+ net_store_data(packet, (uint32)mi->rli.last_slave_errno);
+ net_store_data(packet, mi->rli.last_slave_error);
+ net_store_data(packet, mi->rli.slave_skip_counter);
+ net_store_data(packet, (longlong) mi->rli.master_log_pos);
+ net_store_data(packet, (longlong) mi->rli.log_space_total);
+ pthread_mutex_unlock(&mi->rli.data_lock);
+ pthread_mutex_unlock(&mi->data_lock);
- if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
- DBUG_RETURN(-1);
-
+ if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
+ DBUG_RETURN(-1);
+ }
send_eof(&thd->net);
DBUG_RETURN(0);
}
-int flush_master_info(MASTER_INFO* mi)
+
+bool flush_master_info(MASTER_INFO* mi)
{
IO_CACHE* file = &mi->file;
char lbuf[22];
-
+ DBUG_ENTER("flush_master_info");
+ DBUG_PRINT("enter",("master_pos: %ld", (long) mi->master_log_pos));
+
my_b_seek(file, 0L);
my_b_printf(file, "%s\n%s\n%s\n%s\n%s\n%d\n%d\n",
- mi->log_file_name, llstr(mi->pos, lbuf), mi->host, mi->user,
- mi->password, mi->port, mi->connect_retry);
+ mi->master_log_name, llstr(mi->master_log_pos, lbuf),
+ mi->host, mi->user,
+ mi->password, mi->port, mi->connect_retry
+ );
flush_io_cache(file);
- return 0;
+ DBUG_RETURN(0);
+}
+
+
+st_relay_log_info::st_relay_log_info()
+ :info_fd(-1), cur_log_fd(-1), master_log_pos(0), save_temporary_tables(0),
+ cur_log_old_open_count(0), log_space_total(0), ignore_log_space_limit(0),
+ slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0),
+ sql_thd(0), last_slave_errno(0), inited(0), abort_slave(0),
+ slave_running(0), skip_log_purge(0),
+ inside_transaction(0) /* the default is autocommit=1 */
+{
+ relay_log_name[0] = master_log_name[0] = 0;
+ last_slave_error[0]=0;
+
+
+ bzero((char *)&info_file,sizeof(info_file));
+ bzero((char *)&cache_buf, sizeof(cache_buf));
+ pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&log_space_lock, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&data_cond, NULL);
+ pthread_cond_init(&start_cond, NULL);
+ pthread_cond_init(&stop_cond, NULL);
+ pthread_cond_init(&log_space_cond, NULL);
+ relay_log.init_pthread_objects();
+}
+
+
+st_relay_log_info::~st_relay_log_info()
+{
+ pthread_mutex_destroy(&run_lock);
+ pthread_mutex_destroy(&data_lock);
+ pthread_mutex_destroy(&log_space_lock);
+ pthread_cond_destroy(&data_cond);
+ pthread_cond_destroy(&start_cond);
+ pthread_cond_destroy(&stop_cond);
+ pthread_cond_destroy(&log_space_cond);
}
-int st_master_info::wait_for_pos(THD* thd, String* log_name, ulonglong log_pos)
+/*
+ Waits until the SQL thread reaches (has executed up to) the
+ log/position or timed out.
+
+ SYNOPSIS
+ wait_for_pos()
+ thd client thread that sent SELECT MASTER_POS_WAIT
+ log_name log name to wait for
+ log_pos position to wait for
+ timeout timeout in seconds before giving up waiting
+
+ NOTES
+ timeout is longlong whereas it should be ulong ; but this is
+ to catch if the user submitted a negative timeout.
+
+ RETURN VALUES
+ -2 improper arguments (log_pos<0)
+ or slave not running, or master info changed
+ during the function's execution,
+ or client thread killed. -2 is translated to NULL by caller
+ -1 timed out
+ >=0 number of log events the function had to wait
+ before reaching the desired log/position
+ */
+
+int st_relay_log_info::wait_for_pos(THD* thd, String* log_name,
+ longlong log_pos,
+ longlong timeout)
{
- if (!inited) return -1;
- bool pos_reached;
+ if (!inited)
+ return -1;
int event_count = 0;
- pthread_mutex_lock(&lock);
- while(!thd->killed)
+ ulong init_abort_pos_wait;
+ int error=0;
+ struct timespec abstime; // for timeout checking
+ set_timespec(abstime,timeout);
+
+ DBUG_ENTER("wait_for_pos");
+ DBUG_PRINT("enter",("master_log_name: '%s' pos: %lu timeout: %ld",
+ master_log_name, (ulong) master_log_pos,
+ (long) timeout));
+
+ pthread_mutex_lock(&data_lock);
+ /*
+ This function will abort when it notices that some CHANGE MASTER or
+ RESET MASTER has changed the master info.
+ To catch this, these commands modify abort_pos_wait ; We just monitor
+ abort_pos_wait and see if it has changed.
+ Why do we have this mechanism instead of simply monitoring slave_running
+ in the loop (we do this too), as CHANGE MASTER/RESET SLAVE require that
+ the SQL thread be stopped?
+ This is becasue if someones does:
+ STOP SLAVE;CHANGE MASTER/RESET SLAVE; START SLAVE;
+ the change may happen very quickly and we may not notice that
+ slave_running briefly switches between 1/0/1.
+ */
+ init_abort_pos_wait= abort_pos_wait;
+
+ /*
+ We'll need to
+ handle all possible log names comparisons (e.g. 999 vs 1000).
+ We use ulong for string->number conversion ; this is no
+ stronger limitation than in find_uniq_filename in sql/log.cc
+ */
+ ulong log_name_extension;
+ char log_name_tmp[FN_REFLEN]; //make a char[] from String
+ char *end= strmake(log_name_tmp, log_name->ptr(), min(log_name->length(),
+ FN_REFLEN-1));
+ char *p= fn_ext(log_name_tmp);
+ char *p_end;
+ if (!*p || log_pos<0)
+ {
+ error= -2; //means improper arguments
+ goto err;
+ }
+ /* p points to '.' */
+ log_name_extension= strtoul(++p, &p_end, 10);
+ /*
+ p_end points to the first invalid character.
+ If it equals to p, no digits were found, error.
+ If it contains '\0' it means conversion went ok.
+ */
+ if (p_end==p || *p_end)
+ {
+ error= -2;
+ goto err;
+ }
+
+ /* The "compare and wait" main loop */
+ while (!thd->killed &&
+ init_abort_pos_wait == abort_pos_wait &&
+ slave_running)
{
- int cmp_result;
- if (*log_file_name)
+ bool pos_reached;
+ int cmp_result= 0;
+ DBUG_ASSERT(*master_log_name || master_log_pos == 0);
+ if (*master_log_name)
{
+ char *basename= master_log_name + dirname_length(master_log_name);
/*
- We should use dirname_length() here when we have a version of
- this that doesn't modify the argument */
- char *basename = strrchr(log_file_name, FN_LIBCHAR);
- if (basename)
- ++basename;
+ First compare the parts before the extension.
+ Find the dot in the master's log basename,
+ and protect against user's input error :
+ if the names do not match up to '.' included, return error
+ */
+ char *q= (char*)(fn_ext(basename)+1);
+ if (strncmp(basename, log_name_tmp, (int)(q-basename)))
+ {
+ error= -2;
+ break;
+ }
+ // Now compare extensions.
+ char *q_end;
+ ulong master_log_name_extension= strtoul(q, &q_end, 10);
+ if (master_log_name_extension < log_name_extension)
+ cmp_result = -1 ;
else
- basename = log_file_name;
- cmp_result = strncmp(basename, log_name->ptr(),
- log_name->length());
+ cmp_result= (master_log_name_extension > log_name_extension) ? 1 : 0 ;
}
- else
- cmp_result = 0;
-
- pos_reached = ((!cmp_result && pos >= log_pos) || cmp_result > 0);
+ pos_reached = ((!cmp_result && master_log_pos >= (ulonglong)log_pos) ||
+ cmp_result > 0);
if (pos_reached || thd->killed)
break;
+
+ //wait for master update, with optional timeout.
- const char* msg = thd->enter_cond(&cond, &lock,
- "Waiting for master update");
- pthread_cond_wait(&cond, &lock);
+ DBUG_PRINT("info",("Waiting for master update"));
+ const char* msg = thd->enter_cond(&data_cond, &data_lock,
+ "Waiting for the SQL slave thread to \
+advance position");
+ /*
+ We are going to pthread_cond_(timed)wait(); if the SQL thread stops it
+ will wake us up.
+ */
+ if (timeout > 0)
+ {
+ /*
+ Note that pthread_cond_timedwait checks for the timeout
+ before for the condition ; i.e. it returns ETIMEDOUT
+ if the system time equals or exceeds the time specified by abstime
+ before the condition variable is signaled or broadcast, _or_ if
+ the absolute time specified by abstime has already passed at the time
+ of the call.
+ For that reason, pthread_cond_timedwait will do the "timeoutting" job
+ even if its condition is always immediately signaled (case of a loaded
+ master).
+ */
+ error=pthread_cond_timedwait(&data_cond, &data_lock, &abstime);
+ }
+ else
+ pthread_cond_wait(&data_cond, &data_lock);
+ DBUG_PRINT("info",("Got signal of master update"));
thd->exit_cond(msg);
+ if (error == ETIMEDOUT || error == ETIME)
+ {
+ error= -1;
+ break;
+ }
+ error=0;
event_count++;
+ DBUG_PRINT("info",("Testing if killed or SQL thread not running"));
+ }
+
+err:
+ pthread_mutex_unlock(&data_lock);
+ DBUG_PRINT("exit",("killed: %d abort: %d slave_running: %d \
+improper_arguments: %d timed_out: %d",
+ (int) thd->killed,
+ (int) (init_abort_pos_wait != abort_pos_wait),
+ (int) slave_running,
+ (int) (error == -2),
+ (int) (error == -1)));
+ if (thd->killed || init_abort_pos_wait != abort_pos_wait ||
+ !slave_running)
+ {
+ error= -2;
}
- pthread_mutex_unlock(&lock);
- return thd->killed ? -1 : event_count;
+ DBUG_RETURN( error ? error : event_count );
}
-static int init_slave_thread(THD* thd)
+static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
{
DBUG_ENTER("init_slave_thread");
- thd->system_thread = thd->bootstrap = 1;
+ thd->system_thread = (thd_type == SLAVE_THD_SQL) ?
+ SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO;
+ thd->bootstrap= 1;
+ thd->host_or_ip= "";
thd->client_capabilities = 0;
my_net_init(&thd->net, 0);
- thd->net.timeout = slave_net_timeout;
- thd->max_packet_length=thd->net.max_packet;
+ thd->net.read_timeout = slave_net_timeout;
thd->master_access= ~0;
thd->priv_user = 0;
thd->slave_thread = 1;
- thd->options = (((opt_log_slave_updates) ? OPTION_BIN_LOG:0) | OPTION_AUTO_IS_NULL) ;
- thd->system_thread = 1;
+ thd->options = ((opt_log_slave_updates) ? OPTION_BIN_LOG:0) |
+ OPTION_AUTO_IS_NULL;
+ /*
+ It's nonsense to constraint the slave threads with max_join_size; if a
+ query succeeded on master, we HAVE to execute it.
+ */
+ thd->variables.max_join_size= HA_POS_ERROR;
thd->client_capabilities = CLIENT_LOCAL_FILES;
- slave_real_id=thd->real_id=pthread_self();
+ thd->real_id=pthread_self();
pthread_mutex_lock(&LOCK_thread_count);
thd->thread_id = thread_id++;
pthread_mutex_unlock(&LOCK_thread_count);
- if (init_thr_lock() ||
- my_pthread_setspecific_ptr(THR_THD, thd) ||
- my_pthread_setspecific_ptr(THR_MALLOC, &thd->mem_root) ||
- my_pthread_setspecific_ptr(THR_NET, &thd->net))
+ if (init_thr_lock() || thd->store_globals())
{
- close_connection(&thd->net,ER_OUT_OF_RESOURCES); // is this needed?
- end_thread(thd,0);
+ thd->cleanup();
+ delete thd;
DBUG_RETURN(-1);
}
- thd->mysys_var=my_thread_var;
- thd->dbug_thread_id=my_thread_id();
-#if !defined(__WIN__) && !defined(OS2)
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
sigset_t set;
VOID(sigemptyset(&set)); // Get mask in use
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
#endif
- thd->mem_root.free=thd->mem_root.used=0; // Probably not needed
- if (thd->max_join_size == (ulong) ~0L)
- thd->options |= OPTION_BIG_SELECTS;
-
- thd->proc_info="Waiting for master update";
+ if (thd_type == SLAVE_THD_SQL)
+ thd->proc_info= "Waiting for the next event in relay log";
+ else
+ thd->proc_info= "Waiting for master update";
thd->version=refresh_version;
thd->set_time();
-
DBUG_RETURN(0);
}
-static int safe_sleep(THD* thd, int sec)
+
+static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
+ void* thread_killed_arg)
{
+ int nap_time;
thr_alarm_t alarmed;
thr_alarm_init(&alarmed);
time_t start_time= time((time_t*) 0);
time_t end_time= start_time+sec;
- ALARM alarm_buff;
- while (start_time < end_time)
+ while ((nap_time= (int) (end_time - start_time)) > 0)
{
- int nap_time = (int) (end_time - start_time);
+ ALARM alarm_buff;
/*
- the only reason we are asking for alarm is so that
+ The only reason we are asking for alarm is so that
we will be woken up in case of murder, so if we do not get killed,
set the alarm so it goes off after we wake up naturally
*/
- thr_alarm(&alarmed, 2 * nap_time,&alarm_buff);
+ thr_alarm(&alarmed, 2 * nap_time, &alarm_buff);
sleep(nap_time);
thr_end_alarm(&alarmed);
- if (slave_killed(thd))
+ if ((*thread_killed)(thd,thread_killed_arg))
return 1;
start_time=time((time_t*) 0);
}
@@ -794,41 +2097,52 @@ static int safe_sleep(THD* thd, int sec)
}
-static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
+static int request_dump(MYSQL* mysql, MASTER_INFO* mi,
+ bool *suppress_warnings)
{
char buf[FN_REFLEN + 10];
int len;
int binlog_flags = 0; // for now
- char* logname = mi->log_file_name;
- int4store(buf, mi->pos);
+ char* logname = mi->master_log_name;
+ DBUG_ENTER("request_dump");
+
+ // TODO if big log files: Change next to int8store()
+ int4store(buf, (longlong) mi->master_log_pos);
int2store(buf + 4, binlog_flags);
int4store(buf + 6, server_id);
len = (uint) strlen(logname);
memcpy(buf + 10, logname,len);
if (mc_simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1))
{
- // something went wrong, so we will just reconnect and retry later
- // in the future, we should do a better error analysis, but for
- // now we just fill up the error log :-)
- sql_print_error("Error on COM_BINLOG_DUMP: %s, will retry in %d secs",
- mc_mysql_error(mysql), master_connect_retry);
- return 1;
+ /*
+ Something went wrong, so we will just reconnect and retry later
+ in the future, we should do a better error analysis, but for
+ now we just fill up the error log :-)
+ */
+ if (mc_mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
+ *suppress_warnings= 1; // Suppress reconnect warning
+ else
+ sql_print_error("Error on COM_BINLOG_DUMP: %d %s, will retry in %d secs",
+ mc_mysql_errno(mysql), mc_mysql_error(mysql),
+ master_connect_retry);
+ DBUG_RETURN(1);
}
- return 0;
+ DBUG_RETURN(0);
}
-static int request_table_dump(MYSQL* mysql, char* db, char* table)
+
+static int request_table_dump(MYSQL* mysql, const char* db, const char* table)
{
char buf[1024];
char * p = buf;
uint table_len = (uint) strlen(table);
uint db_len = (uint) strlen(db);
- if(table_len + db_len > sizeof(buf) - 2)
- {
- sql_print_error("request_table_dump: Buffer overrun");
- return 1;
- }
+ if (table_len + db_len > sizeof(buf) - 2)
+ {
+ sql_print_error("request_table_dump: Buffer overrun");
+ return 1;
+ }
*p++ = db_len;
memcpy(p, db, db_len);
@@ -848,26 +2162,40 @@ command");
/*
- We set suppress_warnings TRUE when a normal net read timeout has
- caused us to try a reconnect. We do not want to print anything to
- the error log in this case because this a anormal event in an idle
- server.
+ read one event from the master
+
+ SYNOPSIS
+ read_event()
+ mysql MySQL connection
+ mi Master connection information
+ suppress_warnings TRUE when a normal net read timeout has caused us to
+ try a reconnect. We do not want to print anything to
+ the error log in this case because this a anormal
+ event in an idle server.
+
+ RETURN VALUES
+ 'packet_error' Error
+ number Length of packet
+
*/
-static uint read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
+static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
{
- uint len = packet_error;
+ ulong len;
+
+ *suppress_warnings= 0;
+ /*
+ my_real_read() will time us out
+ We check if we were told to die, and if not, try reading again
- // my_real_read() will time us out
- // we check if we were told to die, and if not, try reading again
+ TODO: Move 'events_till_disconnect' to the MASTER_INFO structure
+ */
#ifndef DBUG_OFF
if (disconnect_slave_event_count && !(events_till_disconnect--))
return packet_error;
#endif
- *suppress_warnings= 0;
-
+
len = mc_net_safe_read(mysql);
-
if (len == packet_error || (long) len < 1)
{
if (mc_mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
@@ -899,656 +2227,395 @@ server_errno=%d)",
return len - 1;
}
-static int check_expected_error(THD* thd, int expected_error)
+
+int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int expected_error)
{
- switch(expected_error)
- {
- case ER_NET_READ_ERROR:
- case ER_NET_ERROR_ON_WRITE:
- case ER_SERVER_SHUTDOWN:
- case ER_NEW_ABORTING_CONNECTION:
- my_snprintf(last_slave_error, sizeof(last_slave_error),
- "Slave: query '%s' partially completed on the master \
+ switch (expected_error) {
+ case ER_NET_READ_ERROR:
+ case ER_NET_ERROR_ON_WRITE:
+ case ER_SERVER_SHUTDOWN:
+ case ER_NEW_ABORTING_CONNECTION:
+ slave_print_error(rli,expected_error,
+ "query '%s' partially completed on the master \
and was aborted. There is a chance that your master is inconsistent at this \
point. If you are sure that your master is ok, run this query manually on the\
- slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1;\
- SLAVE START;", thd->query);
- last_slave_errno = expected_error;
- sql_print_error("%s",last_slave_error);
- return 1;
- default:
- return 0;
- }
+ slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;\
+ SLAVE START; .", thd->query);
+ thd->query_error= 1;
+ return 1;
+ default:
+ return 0;
+ }
}
-inline int ignored_error_code(int err_code)
-{
- return ((err_code == ER_EMPTY_QUERY) ||
- (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
-}
-static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
+static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
{
- Log_event * ev = Log_event::read_log_event((const char*)net->read_pos + 1,
- event_len);
- char llbuff[22];
-
- mi->event_len = event_len; /* Added by Heikki: InnoDB internally stores the
- master log position it has processed so far;
- position to store is really
- mi->pos + mi->pending + mi->event_len
- since we must store the pos of the END of the
- current log event */
+ DBUG_ASSERT(rli->sql_thd==thd);
+ Log_event * ev = next_event(rli);
+ DBUG_ASSERT(rli->sql_thd==thd);
+ if (sql_slave_killed(thd,rli))
+ {
+ delete ev;
+ return 1;
+ }
if (ev)
{
int type_code = ev->get_type_code();
- if (ev->server_id == ::server_id || slave_skip_counter)
+ int exec_res;
+ pthread_mutex_lock(&rli->data_lock);
+
+ /*
+ Skip queries originating from this server or number of
+ queries specified by the user in slave_skip_counter
+ We can't however skip event's that has something to do with the
+ log files themselves.
+ */
+
+ if (ev->server_id == (uint32) ::server_id ||
+ (rli->slave_skip_counter && type_code != ROTATE_EVENT))
{
- if(type_code == LOAD_EVENT)
- skip_load_data_infile(net);
-
- mi->inc_pos(event_len);
- flush_master_info(mi);
- if(slave_skip_counter && /* protect against common user error of
- setting the counter to 1 instead of 2
- while recovering from an failed
- auto-increment insert */
- !(type_code == INTVAR_EVENT &&
- slave_skip_counter == 1))
- --slave_skip_counter;
+ /* TODO: I/O thread should not even log events with the same server id */
+ rli->inc_pos(ev->get_event_len(),
+ type_code != STOP_EVENT ? ev->log_pos : LL(0),
+ 1/* skip lock*/);
+ flush_relay_log_info(rli);
+
+ /*
+ Protect against common user error of setting the counter to 1
+ instead of 2 while recovering from an failed auto-increment insert
+ */
+ if (rli->slave_skip_counter &&
+ !((type_code == INTVAR_EVENT || type_code == STOP_EVENT) &&
+ rli->slave_skip_counter == 1))
+ --rli->slave_skip_counter;
+ pthread_mutex_unlock(&rli->data_lock);
delete ev;
return 0; // avoid infinite update loops
}
+ pthread_mutex_unlock(&rli->data_lock);
thd->server_id = ev->server_id; // use the original server id for logging
thd->set_time(); // time the query
- if(!ev->when)
+ if (!ev->when)
ev->when = time(NULL);
-
- switch(type_code) {
- case QUERY_EVENT:
- {
- Query_log_event* qev = (Query_log_event*)ev;
- int q_len = qev->q_len;
- int expected_error,actual_error = 0;
- init_sql_alloc(&thd->mem_root, 8192,0);
- thd->db = rewrite_db((char*)qev->db);
- if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
- {
- thd->query_length= q_len;
- thd->set_time((time_t)qev->when);
- thd->current_tablenr = 0;
- VOID(pthread_mutex_lock(&LOCK_thread_count));
- thd->query = (char*)qev->query;
- thd->query_id = query_id++;
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->last_nx_table = thd->last_nx_db = 0;
- thd->query_error = 0; // clear error
- thd->net.last_errno = 0;
- thd->net.last_error[0] = 0;
- thd->slave_proxy_id = qev->thread_id; // for temp tables
-
- // sanity check to make sure the master did not get a really bad
- // error on the query
- if (ignored_error_code((expected_error=qev->error_code)) ||
- !check_expected_error(thd, expected_error))
- {
- mysql_parse(thd, thd->query, q_len);
- if (expected_error !=
- (actual_error = thd->net.last_errno) && expected_error &&
- !ignored_error_code(actual_error))
- {
- const char* errmsg = "Slave: did not get the expected error\
- running query from master - expected: '%s' (%d), got '%s' (%d)";
- sql_print_error(errmsg, ER_SAFE(expected_error),
- expected_error,
- actual_error ? thd->net.last_error:"no error",
- actual_error);
- thd->query_error = 1;
- }
- else if (expected_error == actual_error ||
- ignored_error_code(actual_error))
- {
- thd->query_error = 0;
- *last_slave_error = 0;
- last_slave_errno = 0;
- }
- }
- else
- {
- // master could be inconsistent, abort and tell DBA to check/fix it
- VOID(pthread_mutex_lock(&LOCK_thread_count));
- thd->db = thd->query = 0;
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->convert_set = 0;
- close_thread_tables(thd);
- free_root(&thd->mem_root,0);
- delete ev;
- return 1;
- }
- }
- thd->db = 0; // prevent db from being freed
- VOID(pthread_mutex_lock(&LOCK_thread_count));
- thd->query = 0; // just to be sure
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
- // assume no convert for next query unless set explictly
- thd->convert_set = 0;
- close_thread_tables(thd);
-
- if (thd->query_error || thd->fatal_error)
- {
- sql_print_error("Slave: error running query '%s' ",
- qev->query);
- last_slave_errno = actual_error ? actual_error : -1;
- my_snprintf(last_slave_error, sizeof(last_slave_error),
- "error '%s' on query '%s'",
- actual_error ? thd->net.last_error :
- "unexpected success or fatal error",
- qev->query
- );
- free_root(&thd->mem_root,0);
- delete ev;
- return 1;
- }
- free_root(&thd->mem_root,0);
- delete ev;
-
- mi->inc_pos(event_len);
-
- if (!(thd->options & OPTION_BEGIN)) {
-
- /* We only flush the master info position to the master.info file if
- the transaction is not open any more: an incomplete transaction will
- be rolled back automatically in crash recovery in transactional
- table handlers */
-
- flush_master_info(mi);
- }
- break;
- }
-
- case LOAD_EVENT:
- {
- Load_log_event* lev = (Load_log_event*)ev;
- init_sql_alloc(&thd->mem_root, 8192,0);
- thd->db = rewrite_db((char*)lev->db);
- DBUG_ASSERT(thd->query == 0);
- thd->query = 0;
- thd->query_error = 0;
-
- if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
- {
- thd->set_time((time_t)lev->when);
- thd->current_tablenr = 0;
- VOID(pthread_mutex_lock(&LOCK_thread_count));
- thd->query_id = query_id++;
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
-
- TABLE_LIST tables;
- bzero((char*) &tables,sizeof(tables));
- tables.db = thd->db;
- tables.alias= tables.real_name= (char*)lev->table_name;
- tables.lock_type = TL_WRITE;
- tables.updating= 1;
- // the table will be opened in mysql_load
- if(table_rules_on && !tables_ok(thd, &tables))
- {
- skip_load_data_infile(net);
- }
- else
- {
- enum enum_duplicates handle_dup = DUP_IGNORE;
- if(lev->sql_ex.opt_flags & REPLACE_FLAG)
- handle_dup = DUP_REPLACE;
- sql_exchange ex((char*)lev->fname, lev->sql_ex.opt_flags &
- DUMPFILE_FLAG );
- String field_term(&lev->sql_ex.field_term, 1),
- enclosed(&lev->sql_ex.enclosed, 1),
- line_term(&lev->sql_ex.line_term,1),
- escaped(&lev->sql_ex.escaped, 1),
- line_start(&lev->sql_ex.line_start, 1);
-
- ex.field_term = &field_term;
- if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY)
- ex.field_term->length(0);
-
- ex.enclosed = &enclosed;
- if(lev->sql_ex.empty_flags & ENCLOSED_EMPTY)
- ex.enclosed->length(0);
-
- ex.line_term = &line_term;
- if(lev->sql_ex.empty_flags & LINE_TERM_EMPTY)
- ex.line_term->length(0);
-
- ex.line_start = &line_start;
- if(lev->sql_ex.empty_flags & LINE_START_EMPTY)
- ex.line_start->length(0);
-
- ex.escaped = &escaped;
- if(lev->sql_ex.empty_flags & ESCAPED_EMPTY)
- ex.escaped->length(0);
-
- ex.opt_enclosed = (lev->sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
- if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY)
- ex.field_term->length(0);
-
- ex.skip_lines = lev->skip_lines;
-
-
- List<Item> fields;
- lev->set_fields(fields);
- thd->slave_proxy_id = thread_id;
- thd->net.vio = net->vio;
- // mysql_load will use thd->net to read the file
- thd->net.pkt_nr = net->pkt_nr;
- // make sure the client does not get confused
- // about the packet sequence
- if(mysql_load(thd, &ex, &tables, fields, handle_dup, 1,
- TL_WRITE))
- thd->query_error = 1;
- if(thd->cuted_fields)
- sql_print_error("Slave: load data infile at position %s in log \
-'%s' produced %d warning(s)", llstr(glob_mi.pos,llbuff), RPL_LOG_NAME,
- thd->cuted_fields );
- net->pkt_nr = thd->net.pkt_nr;
- }
- }
- else
- {
- // we will just ask the master to send us /dev/null if we do not
- // want to load the data :-)
- skip_load_data_infile(net);
- }
-
- thd->net.vio = 0;
- thd->db = 0;// prevent db from being freed
- close_thread_tables(thd);
- if(thd->query_error)
- {
- int sql_error = thd->net.last_errno;
- if(!sql_error)
- sql_error = ER_UNKNOWN_ERROR;
-
- sql_print_error("Slave: Error '%s' running load data infile ",
- ER(sql_error));
- delete ev;
- free_root(&thd->mem_root,0);
- return 1;
- }
-
- delete ev;
- free_root(&thd->mem_root,0);
-
- if(thd->fatal_error)
- {
- sql_print_error("Slave: Fatal error running query '%s' ",
- thd->query);
- return 1;
- }
-
- mi->inc_pos(event_len);
-
- if (!(thd->options & OPTION_BEGIN))
- flush_master_info(mi);
-
- break;
- }
-
- /* Question: in a START or STOP event, what happens if we have transaction
- open? */
-
- case START_EVENT:
- mi->inc_pos(event_len);
- flush_master_info(mi);
- delete ev;
- break;
-
- case STOP_EVENT:
- if(mi->pos > 4) // stop event should be ignored after rotate event
- {
- close_temporary_tables(thd);
- mi->inc_pos(event_len);
- flush_master_info(mi);
- }
- delete ev;
- break;
- case ROTATE_EVENT:
- {
- Rotate_log_event* rev = (Rotate_log_event*)ev;
- int ident_len = rev->ident_len;
- pthread_mutex_lock(&mi->lock);
- /*
- If the master is 4.0, he has an incompatible binlog format, which we
- cannot read. We always can detect this in _fake_ Rotate events, where we
- see zeros at the beginning of the expected binlog's filename (this is
- because 4.0 _fake_ Rotate events have zeros in the 'log_pos' and 'flags'
- parts of the event header).
- Consider the following test as a sanity check, which must always pass,
- and which has the good side effect of catching 4.0 masters.
- Masters >= 4.0.14 will always send a fake Rotate event (even if the slave
- asked for a position >4) so we are 100% sure to catch the problem.
- */
- if (!ident_len || !(rev->new_log_ident[0]))
- {
- sql_print_error("Slave: could not parse Rotate event; it *might* be \
-that your master's version is 4.0 or newer, which cannot be replicated by \
-3.23 slaves (in that case you need to upgrade your slave to 4.0 or newer)");
- delete ev;
- pthread_cond_broadcast(&mi->cond);
- pthread_mutex_unlock(&mi->lock);
- return 1;
- }
-
- memcpy(mi->log_file_name, rev->new_log_ident,ident_len );
- mi->log_file_name[ident_len] = 0;
- mi->pos = 4; // skip magic number
- pthread_cond_broadcast(&mi->cond);
- pthread_mutex_unlock(&mi->lock);
-
- if (!(thd->options & OPTION_BEGIN))
- flush_master_info(mi);
-#ifndef DBUG_OFF
- if(abort_slave_event_count)
- ++events_till_abort;
-#endif
- delete ev;
- break;
- }
-
- case INTVAR_EVENT:
- {
- Intvar_log_event* iev = (Intvar_log_event*)ev;
- switch(iev->type)
- {
- case LAST_INSERT_ID_EVENT:
- thd->last_insert_id_used = 1;
- thd->last_insert_id = iev->val;
- break;
- case INSERT_ID_EVENT:
- thd->next_insert_id = iev->val;
- break;
-
- }
- mi->inc_pending(event_len);
- delete ev;
- break;
- }
- }
+ ev->thd = thd;
+ exec_res = ev->exec_event(rli);
+ DBUG_ASSERT(rli->sql_thd==thd);
+ delete ev;
+ return exec_res;
}
else
{
- sql_print_error("\
-Could not parse log event entry, check the master for binlog corruption\n\
-This may also be a network problem, or just a bug in the master or slave code.\
+ slave_print_error(rli, 0, "\
+Could not parse relay log event entry. The possible reasons are: the master's \
+binary log is corrupted (you can check this by running 'mysqlbinlog' on the \
+binary log), the slave's relay log is corrupted (you can check this by running \
+'mysqlbinlog' on the relay log), a network problem, or a bug in the master's \
+or slave's MySQL code. If you want to check the master's binary log or slave's \
+relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' \
+on this slave.\
");
return 1;
}
- return 0;
}
-
-// slave thread
-pthread_handler_decl(handle_slave,arg __attribute__((unused)))
+
+/* slave I/O thread */
+extern "C" pthread_handler_decl(handle_slave_io,arg)
{
+ THD *thd; // needs to be first for thread_stack
+ MYSQL *mysql;
+ MASTER_INFO *mi = (MASTER_INFO*)arg;
+ char llbuff[22];
+ uint retry_count;
+
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
my_thread_init();
- if (!server_id)
- {
- pthread_cond_broadcast(&COND_slave_start);
- sql_print_error("Server id not set, will not start slave");
- my_thread_end();
- pthread_exit((void*)1);
- }
- DBUG_ENTER("handle_slave");
+ DBUG_ENTER("handle_slave_io");
#ifndef DBUG_OFF
- slave_begin:
+slave_begin:
#endif
- THD *thd; // needs to be first for thread_stack
- MYSQL *mysql = NULL ;
- char llbuff[22];
+ DBUG_ASSERT(mi->inited);
+ mysql= NULL ;
+ retry_count= 0;
+
+ pthread_mutex_lock(&mi->run_lock);
+ /* Inform waiting threads that slave has started */
+ mi->slave_run_id++;
- pthread_mutex_lock(&LOCK_slave);
-
- if (slave_running)
- {
- pthread_cond_broadcast(&COND_slave_start);
- pthread_mutex_unlock(&LOCK_slave);
- my_thread_end();
- pthread_exit((void*)1); // safety just in case
- }
- slave_running = 1;
- abort_slave = 0;
#ifndef DBUG_OFF
- events_till_abort = abort_slave_event_count;
+ mi->events_till_abort = abort_slave_event_count;
#endif
- pthread_cond_broadcast(&COND_slave_start);
- pthread_mutex_unlock(&LOCK_slave);
- // int error = 1;
- bool retried_once = 0;
- ulonglong last_failed_pos = 0;
-
- slave_thd = thd = new THD; // note that contructor of THD uses DBUG_ !
- thd->set_time();
+ thd= new THD; // note that contructor of THD uses DBUG_ !
+ THD_CHECK_SENTRY(thd);
pthread_detach_this_thread();
- if (init_slave_thread(thd) || init_master_info(&glob_mi))
- {
- sql_print_error("Failed during slave thread initialization");
- goto err;
- }
+ if (init_slave_thread(thd, SLAVE_THD_IO))
+ {
+ pthread_cond_broadcast(&mi->start_cond);
+ pthread_mutex_unlock(&mi->run_lock);
+ sql_print_error("Failed during slave I/O thread initialization");
+ goto err;
+ }
+ mi->io_thd = thd;
thd->thread_stack = (char*)&thd; // remember where our stack is
- thd->temporary_tables = save_temporary_tables; // restore temp tables
- (void) pthread_mutex_lock(&LOCK_thread_count);
+ pthread_mutex_lock(&LOCK_thread_count);
threads.append(thd);
- (void) pthread_mutex_unlock(&LOCK_thread_count);
- glob_mi.pending = 0; //this should always be set to 0 when the slave thread
- // is started
+ pthread_mutex_unlock(&LOCK_thread_count);
+ mi->slave_running = 1;
+ mi->abort_slave = 0;
+ pthread_mutex_unlock(&mi->run_lock);
+ pthread_cond_broadcast(&mi->start_cond);
- DBUG_PRINT("info",("master info: log_file_name=%s, position=%s",
- glob_mi.log_file_name, llstr(glob_mi.pos,llbuff)));
-
+ DBUG_PRINT("master_info",("log_file_name: '%s' position: %s",
+ mi->master_log_name,
+ llstr(mi->master_log_pos,llbuff)));
- if (!(mysql = mc_mysql_init(NULL)))
+ if (!(mi->mysql = mysql = mc_mysql_init(NULL)))
{
- sql_print_error("Slave thread: error in mc_mysql_init()");
+ sql_print_error("Slave I/O thread: error in mc_mysql_init()");
goto err;
}
- thd->proc_info = "connecting to master";
-#ifndef DBUG_OFF
- sql_print_error("Slave thread initialized");
-#endif
+ thd->proc_info = "Connecting to master";
// we can get killed during safe_connect
- if (!safe_connect(thd, mysql, &glob_mi))
- sql_print_error("Slave: connected to master '%s@%s:%d',\
- replication started in log '%s' at position %s", glob_mi.user,
- glob_mi.host, glob_mi.port,
- RPL_LOG_NAME,
- llstr(glob_mi.pos,llbuff));
+ if (!safe_connect(thd, mysql, mi))
+ sql_print_error("Slave I/O thread: connected to master '%s@%s:%d',\
+ replication started in log '%s' at position %s", mi->user,
+ mi->host, mi->port,
+ IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
else
{
- sql_print_error("Slave thread killed while connecting to master");
+ sql_print_error("Slave I/O thread killed while connecting to master");
goto err;
}
-
+
connected:
- mysql->net.timeout=slave_net_timeout;
- while (!slave_killed(thd))
+ thd->slave_net = &mysql->net;
+ thd->proc_info = "Checking master version";
+ if (check_master_version(mysql, mi))
+ goto err;
+ if (!mi->old_format)
{
- thd->proc_info = "Requesting binlog dump";
- if(request_dump(mysql, &glob_mi))
- {
- sql_print_error("Failed on request_dump()");
- if(slave_killed(thd))
- {
- sql_print_error("Slave thread killed while requesting master \
+ /*
+ Register ourselves with the master.
+ If fails, this is not fatal - we just print the error message and go
+ on with life.
+ */
+ thd->proc_info = "Registering slave on master";
+ if (register_slave_on_master(mysql) || update_slave_list(mysql, mi))
+ goto err;
+ }
+
+ DBUG_PRINT("info",("Starting reading binary log from master"));
+ while (!io_slave_killed(thd,mi))
+ {
+ bool suppress_warnings= 0;
+ thd->proc_info = "Requesting binlog dump";
+ if (request_dump(mysql, mi, &suppress_warnings))
+ {
+ sql_print_error("Failed on request_dump()");
+ if (io_slave_killed(thd,mi))
+ {
+ sql_print_error("Slave I/O thread killed while requesting master \
dump");
- goto err;
- }
-
- thd->proc_info = "Waiiting to reconnect after a failed dump request";
- if(mysql->net.vio)
- vio_close(mysql->net.vio);
- // first time retry immediately, assuming that we can recover
- // right away - if first time fails, sleep between re-tries
- // hopefuly the admin can fix the problem sometime
- if(retried_once)
- safe_sleep(thd, glob_mi.connect_retry);
- else
- retried_once = 1;
+ goto err;
+ }
- if(slave_killed(thd))
- {
- sql_print_error("Slave thread killed while retrying master \
+ thd->proc_info= "Waiting to reconnect after a failed binlog dump request";
+ mc_end_server(mysql);
+ /*
+ First time retry immediately, assuming that we can recover
+ right away - if first time fails, sleep between re-tries
+ hopefuly the admin can fix the problem sometime
+ */
+ if (retry_count++)
+ {
+ if (retry_count > master_retry_count)
+ goto err; // Don't retry forever
+ safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
+ (void*)mi);
+ }
+ if (io_slave_killed(thd,mi))
+ {
+ sql_print_error("Slave I/O thread killed while retrying master \
dump");
- goto err;
- }
-
- thd->proc_info = "Reconnecting after a failed dump request";
- last_failed_pos=glob_mi.pos;
- sql_print_error("Slave: failed dump request, reconnecting to \
-try again, log '%s' at postion %s", RPL_LOG_NAME,
- llstr(last_failed_pos,llbuff));
- if(safe_reconnect(thd, mysql, &glob_mi, 0) || slave_killed(thd))
- {
- sql_print_error("Slave thread killed during or after reconnect");
- goto err;
- }
-
- goto connected;
- }
+ goto err;
+ }
- while(!slave_killed(thd))
- {
- bool suppress_warnings= 0;
-
- thd->proc_info = "Reading master update";
- uint event_len = read_event(mysql, &glob_mi, &suppress_warnings);
-
- if(slave_killed(thd))
- {
- sql_print_error("Slave thread killed while reading event");
- goto err;
- }
+ thd->proc_info = "Reconnecting after a failed binlog dump request";
+ if (!suppress_warnings)
+ sql_print_error("Slave I/O thread: failed dump request, \
+reconnecting to try again, log '%s' at postion %s", IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
+ if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
+ io_slave_killed(thd,mi))
+ {
+ sql_print_error("Slave I/O thread killed during or \
+after reconnect");
+ goto err;
+ }
+
+ goto connected;
+ }
+
+ while (!io_slave_killed(thd,mi))
+ {
+ bool suppress_warnings= 0;
+ /*
+ We say "waiting" because read_event() will wait if there's nothing to
+ read. But if there's something to read, it will not wait. The important
+ thing is to not confuse users by saying "reading" whereas we're in fact
+ receiving nothing.
+ */
+ thd->proc_info = "Waiting for master to send event";
+ ulong event_len = read_event(mysql, mi, &suppress_warnings);
+ if (io_slave_killed(thd,mi))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_error("Slave I/O thread killed while reading event");
+ goto err;
+ }
- if (event_len == packet_error)
- {
- if(mc_mysql_errno(mysql) == ER_NET_PACKET_TOO_LARGE)
- {
- sql_print_error("Log entry on master is longer than \
-max_allowed_packet on slave. Slave thread will be aborted. If the entry is \
-really supposed to be that long, restart the server with a higher value of \
-max_allowed_packet. The current value is %ld", max_allowed_packet);
- goto err;
- }
-
- thd->proc_info = "Waiting to reconnect after a failed read";
- if(mysql->net.vio)
- vio_close(mysql->net.vio);
- if(retried_once) // punish repeat offender with sleep
- safe_sleep(thd, glob_mi.connect_retry);
- else
- retried_once = 1;
-
- if(slave_killed(thd))
- {
- sql_print_error("Slave thread killed while waiting to \
+ if (event_len == packet_error)
+ {
+ uint mysql_error_number= mc_mysql_errno(mysql);
+ if (mysql_error_number == ER_NET_PACKET_TOO_LARGE)
+ {
+ sql_print_error("\
+Log entry on master is longer than max_allowed_packet (%ld) on \
+slave. If the entry is correct, restart the server with a higher value of \
+max_allowed_packet",
+ thd->variables.max_allowed_packet);
+ goto err;
+ }
+ if (mysql_error_number == ER_MASTER_FATAL_ERROR_READING_BINLOG)
+ {
+ sql_print_error(ER(mysql_error_number), mysql_error_number,
+ mc_mysql_error(mysql));
+ goto err;
+ }
+ thd->proc_info = "Waiting to reconnect after a failed master event \
+read";
+ mc_end_server(mysql);
+ if (retry_count++)
+ {
+ if (retry_count > master_retry_count)
+ goto err; // Don't retry forever
+ safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
+ (void*) mi);
+ }
+ if (io_slave_killed(thd,mi))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_error("Slave I/O thread killed while waiting to \
reconnect after a failed read");
- goto err;
- }
- thd->proc_info = "Reconnecting after a failed read";
- last_failed_pos= glob_mi.pos;
-
- if (!suppress_warnings)
- sql_print_error("Slave: Failed reading log event, \
-reconnecting to retry, log '%s' position %s", RPL_LOG_NAME,
- llstr(last_failed_pos, llbuff));
- if(safe_reconnect(thd, mysql, &glob_mi,
- suppress_warnings)
- || slave_killed(thd))
- {
- sql_print_error("Slave thread killed during or after a \
+ goto err;
+ }
+ thd->proc_info = "Reconnecting after a failed master event read";
+ if (!suppress_warnings)
+ sql_print_error("Slave I/O thread: Failed reading log event, \
+reconnecting to retry, log '%s' position %s", IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos, llbuff));
+ if (safe_reconnect(thd, mysql, mi, suppress_warnings) ||
+ io_slave_killed(thd,mi))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_error("Slave I/O thread killed during or after a \
reconnect done to recover from failed read");
- goto err;
- }
-
- goto connected;
- } // if(event_len == packet_error)
-
- thd->proc_info = "Processing master log event";
- if(exec_event(thd, &mysql->net, &glob_mi, event_len))
- {
- sql_print_error("\
-Error running query, slave aborted. Fix the problem, and re-start \
-the slave thread with \"mysqladmin start-slave\". We stopped at log \
-'%s' position %s",
- RPL_LOG_NAME, llstr(glob_mi.pos, llbuff));
- goto err;
- // there was an error running the query
- // abort the slave thread, when the problem is fixed, the user
- // should restart the slave with mysqladmin start-slave
- }
-#ifndef DBUG_OFF
- if(abort_slave_event_count && !--events_till_abort)
- {
- sql_print_error("Slave: debugging abort");
- goto err;
- }
-#endif
+ goto err;
+ }
+ goto connected;
+ } // if (event_len == packet_error)
- // successful exec with offset advance,
- // the slave repents and his sins are forgiven!
- if(glob_mi.pos > last_failed_pos)
- {
- retried_once = 0;
+ retry_count=0; // ok event, reset retry counter
+ thd->proc_info = "Queueing master event to the relay log";
+ if (queue_event(mi,(const char*)mysql->net.read_pos + 1,
+ event_len))
+ {
+ sql_print_error("Slave I/O thread could not queue event from master");
+ goto err;
+ }
+ flush_master_info(mi);
+ /*
+ See if the relay logs take too much space.
+ We don't lock mi->rli.log_space_lock here; this dirty read saves time
+ and does not introduce any problem:
+ - if mi->rli.ignore_log_space_limit is 1 but becomes 0 just after (so
+ the clean value is 0), then we are reading only one more event as we
+ should, and we'll block only at the next event. No big deal.
+ - if mi->rli.ignore_log_space_limit is 0 but becomes 1 just after (so
+ the clean value is 1), then we are going into wait_for_relay_log_space()
+ for no reason, but this function will do a clean read, notice the clean
+ value and exit immediately.
+ */
#ifndef DBUG_OFF
- stuck_count = 0;
+ {
+ char llbuf1[22], llbuf2[22];
+ DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \
+ignore_log_space_limit=%d",
+ llstr(mi->rli.log_space_limit,llbuf1),
+ llstr(mi->rli.log_space_total,llbuf2),
+ (int) mi->rli.ignore_log_space_limit));
+ }
#endif
- }
+
+ if (mi->rli.log_space_limit && mi->rli.log_space_limit <
+ mi->rli.log_space_total &&
+ !mi->rli.ignore_log_space_limit)
+ if (wait_for_relay_log_space(&mi->rli))
+ {
+ sql_print_error("Slave I/O thread aborted while waiting for relay \
+log space");
+ goto err;
+ }
+ // TODO: check debugging abort code
#ifndef DBUG_OFF
- else
- {
- // show a little mercy, allow slave to read one more event
- // before cutting him off - otherwise he gets stuck
- // on Intvar events, since they do not advance the offset
- // immediately
- if (++stuck_count > 2)
- events_till_disconnect++;
- }
-#endif
- } // while(!slave_killed(thd)) - read/exec loop
- } // while(!slave_killed(thd)) - slave loop
+ if (abort_slave_event_count && !--events_till_abort)
+ {
+ sql_print_error("Slave I/O thread: debugging abort");
+ goto err;
+ }
+#endif
+ }
+ }
// error = 0;
- err:
- // print the current replication position
- sql_print_error("Slave thread exiting, replication stopped in log '%s' at \
-position %s",
- RPL_LOG_NAME, llstr(glob_mi.pos,llbuff));
+err:
+ // print the current replication position
+ sql_print_error("Slave I/O thread exiting, read up to log '%s', position %s",
+ IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query = thd->db = 0; // extra safety
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (mysql)
+ {
mc_mysql_close(mysql);
+ mi->mysql=0;
+ }
thd->proc_info = "Waiting for slave mutex on exit";
- pthread_mutex_lock(&LOCK_slave);
- slave_running = 0;
- abort_slave = 0;
- save_temporary_tables = thd->temporary_tables;
- thd->temporary_tables = 0; // remove tempation from destructor to close them
- net_end(&thd->net); // destructor will not free it, because we are weird
- slave_thd = 0;
- (void) pthread_mutex_lock(&LOCK_thread_count);
+ pthread_mutex_lock(&mi->run_lock);
+ mi->slave_running = 0;
+ mi->io_thd = 0;
+ // TODO: make rpl_status part of MASTER_INFO
+ change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
+ mi->abort_slave = 0; // TODO: check if this is needed
+ DBUG_ASSERT(thd->net.buff != 0);
+ net_end(&thd->net); // destructor will not free it, because net.vio is 0
+ pthread_mutex_lock(&LOCK_thread_count);
+ THD_CHECK_SENTRY(thd);
delete thd;
- (void) pthread_mutex_unlock(&LOCK_thread_count);
- pthread_mutex_unlock(&LOCK_slave);
- pthread_cond_broadcast(&COND_slave_stopped); // tell the world we are done
+ pthread_mutex_unlock(&LOCK_thread_count);
+ pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done
+ pthread_mutex_unlock(&mi->run_lock);
#ifndef DBUG_OFF
- if(abort_slave_event_count && !events_till_abort)
+ if (abort_slave_event_count && !events_till_abort)
goto slave_begin;
#endif
my_thread_end();
@@ -1557,92 +2624,1020 @@ position %s",
}
-/* try to connect until successful or slave killed */
+/* slave SQL logic thread */
-static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
+extern "C" pthread_handler_decl(handle_slave_sql,arg)
{
- int slave_was_killed;
+ THD *thd; /* needs to be first for thread_stack */
+ char llbuff[22],llbuff1[22];
+ RELAY_LOG_INFO* rli = &((MASTER_INFO*)arg)->rli;
+ const char *errmsg;
+
+ // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
+ my_thread_init();
+ DBUG_ENTER("handle_slave_sql");
+
#ifndef DBUG_OFF
- events_till_disconnect = disconnect_slave_event_count;
+slave_begin:
+#endif
+
+ DBUG_ASSERT(rli->inited);
+ pthread_mutex_lock(&rli->run_lock);
+ DBUG_ASSERT(!rli->slave_running);
+ errmsg= 0;
+#ifndef DBUG_OFF
+ rli->events_till_abort = abort_slave_event_count;
+#endif
+
+ thd = new THD; // note that contructor of THD uses DBUG_ !
+ THD_CHECK_SENTRY(thd);
+ /* Inform waiting threads that slave has started */
+ rli->slave_run_id++;
+
+ pthread_detach_this_thread();
+ if (init_slave_thread(thd, SLAVE_THD_SQL))
+ {
+ /*
+ TODO: this is currently broken - slave start and change master
+ will be stuck if we fail here
+ */
+ pthread_cond_broadcast(&rli->start_cond);
+ pthread_mutex_unlock(&rli->run_lock);
+ sql_print_error("Failed during slave thread initialization");
+ goto err;
+ }
+ rli->sql_thd= thd;
+ thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
+ thd->thread_stack = (char*)&thd; // remember where our stack is
+ pthread_mutex_lock(&LOCK_thread_count);
+ threads.append(thd);
+ pthread_mutex_unlock(&LOCK_thread_count);
+ rli->slave_running = 1;
+ rli->abort_slave = 0;
+ pthread_mutex_unlock(&rli->run_lock);
+ pthread_cond_broadcast(&rli->start_cond);
+ // This should always be set to 0 when the slave thread is started
+ rli->pending = 0;
+ /*
+ Reset errors for a clean start (otherwise, if the master is idle, the SQL
+ thread may execute no Query_log_event, so the error will remain even
+ though there's no problem anymore).
+ */
+ clear_last_slave_error(rli);
+
+ //tell the I/O thread to take relay_log_space_limit into account from now on
+ pthread_mutex_lock(&rli->log_space_lock);
+ rli->ignore_log_space_limit= 0;
+ pthread_mutex_unlock(&rli->log_space_lock);
+
+ if (init_relay_log_pos(rli,
+ rli->relay_log_name,
+ rli->relay_log_pos,
+ 1 /*need data lock*/, &errmsg))
+ {
+ sql_print_error("Error initializing relay log position: %s",
+ errmsg);
+ goto err;
+ }
+ THD_CHECK_SENTRY(thd);
+ DBUG_ASSERT(rli->relay_log_pos >= BIN_LOG_HEADER_SIZE);
+ DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->relay_log_pos);
+ DBUG_ASSERT(rli->sql_thd == thd);
+
+ DBUG_PRINT("master_info",("log_file_name: %s position: %s",
+ rli->master_log_name,
+ llstr(rli->master_log_pos,llbuff)));
+ if (global_system_variables.log_warnings)
+ sql_print_error("Slave SQL thread initialized, starting replication in \
+log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
+ llstr(rli->master_log_pos,llbuff),rli->relay_log_name,
+ llstr(rli->relay_log_pos,llbuff1));
+
+ /* Read queries from the IO/THREAD until this thread is killed */
+
+ while (!sql_slave_killed(thd,rli))
+ {
+ thd->proc_info = "Reading event from the relay log";
+ DBUG_ASSERT(rli->sql_thd == thd);
+ THD_CHECK_SENTRY(thd);
+ if (exec_relay_log_event(thd,rli))
+ {
+ // do not scare the user if SQL thread was simply killed or stopped
+ if (!sql_slave_killed(thd,rli))
+ sql_print_error("\
+Error running query, slave SQL thread aborted. Fix the problem, and restart \
+the slave SQL thread with \"SLAVE START\". We stopped at log \
+'%s' position %s",
+ RPL_LOG_NAME, llstr(rli->master_log_pos, llbuff));
+ goto err;
+ }
+ }
+
+ /* Thread stopped. Print the current replication position to the log */
+ sql_print_error("Slave SQL thread exiting, replication stopped in log \
+ '%s' at position %s",
+ RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff));
+
+ err:
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ thd->query = thd->db = 0; // extra safety
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ thd->proc_info = "Waiting for slave mutex on exit";
+ pthread_mutex_lock(&rli->run_lock);
+ /* We need data_lock, at least to wake up any waiting master_pos_wait() */
+ pthread_mutex_lock(&rli->data_lock);
+ DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun
+ /* When master_pos_wait() wakes up it will check this and terminate */
+ rli->slave_running= 0;
+ /*
+ Going out of the transaction. Necessary to mark it, in case the user
+ restarts replication from a non-transactional statement (with CHANGE
+ MASTER).
+ */
+ rli->inside_transaction= 0;
+ /* Wake up master_pos_wait() */
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions"));
+ pthread_cond_broadcast(&rli->data_cond);
+ rli->ignore_log_space_limit= 0; /* don't need any lock */
+ rli->save_temporary_tables = thd->temporary_tables;
+
+ /*
+ TODO: see if we can do this conditionally in next_event() instead
+ to avoid unneeded position re-init
+ */
+ thd->temporary_tables = 0; // remove tempation from destructor to close them
+ DBUG_ASSERT(thd->net.buff != 0);
+ net_end(&thd->net); // destructor will not free it, because we are weird
+ DBUG_ASSERT(rli->sql_thd == thd);
+ THD_CHECK_SENTRY(thd);
+ rli->sql_thd= 0;
+ pthread_mutex_lock(&LOCK_thread_count);
+ THD_CHECK_SENTRY(thd);
+ delete thd;
+ pthread_mutex_unlock(&LOCK_thread_count);
+ pthread_cond_broadcast(&rli->stop_cond);
+ // tell the world we are done
+ pthread_mutex_unlock(&rli->run_lock);
+#ifndef DBUG_OFF // TODO: reconsider the code below
+ if (abort_slave_event_count && !rli->events_till_abort)
+ goto slave_begin;
#endif
- while(!(slave_was_killed = slave_killed(thd)) &&
- !mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
- mi->port, 0, 0))
+ my_thread_end(); // clean-up before broadcasting termination
+ pthread_exit(0);
+ DBUG_RETURN(0); // Can't return anything here
+}
+
+
+static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev)
+{
+ int error = 1;
+ ulong num_bytes;
+ bool cev_not_written;
+ THD* thd;
+ NET* net = &mi->mysql->net;
+ DBUG_ENTER("process_io_create_file");
+
+ if (unlikely(!cev->is_valid()))
+ DBUG_RETURN(1);
+ /*
+ TODO: fix to honor table rules, not only db rules
+ */
+ if (!db_ok(cev->db, replicate_do_db, replicate_ignore_db))
{
- sql_print_error("Slave thread: error connecting to master: %s (%d),\
- retry in %d sec", mc_mysql_error(mysql), errno, mi->connect_retry);
- safe_sleep(thd, mi->connect_retry);
+ skip_load_data_infile(net);
+ DBUG_RETURN(0);
}
+ DBUG_ASSERT(cev->inited_from_old);
+ thd = mi->io_thd;
+ thd->file_id = cev->file_id = mi->file_id++;
+ thd->server_id = cev->server_id;
+ cev_not_written = 1;
- if(!slave_was_killed)
+ if (unlikely(net_request_file(net,cev->fname)))
+ {
+ sql_print_error("Slave I/O: failed requesting download of '%s'",
+ cev->fname);
+ goto err;
+ }
+
+ /*
+ This dummy block is so we could instantiate Append_block_log_event
+ once and then modify it slightly instead of doing it multiple times
+ in the loop
+ */
+ {
+ Append_block_log_event aev(thd,0,0,0,0);
+
+ for (;;)
{
- mysql_log.write(thd, COM_CONNECT_OUT, "%s@%s:%d",
- mi->user, mi->host, mi->port);
-#ifdef SIGNAL_WITH_VIO_CLOSE
- thd->set_active_vio(mysql->net.vio);
-#endif
+ if (unlikely((num_bytes=my_net_read(net)) == packet_error))
+ {
+ sql_print_error("Network read error downloading '%s' from master",
+ cev->fname);
+ goto err;
+ }
+ if (unlikely(!num_bytes)) /* eof */
+ {
+ send_ok(net); /* 3.23 master wants it */
+ /*
+ If we wrote Create_file_log_event, then we need to write
+ Execute_load_log_event. If we did not write Create_file_log_event,
+ then this is an empty file and we can just do as if the LOAD DATA
+ INFILE had not existed, i.e. write nothing.
+ */
+ if (unlikely(cev_not_written))
+ break;
+ Execute_load_log_event xev(thd,0,0);
+ xev.log_pos = mi->master_log_pos;
+ if (unlikely(mi->rli.relay_log.append(&xev)))
+ {
+ sql_print_error("Slave I/O: error writing Exec_load event to \
+relay log");
+ goto err;
+ }
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ break;
+ }
+ if (unlikely(cev_not_written))
+ {
+ cev->block = (char*)net->read_pos;
+ cev->block_len = num_bytes;
+ cev->log_pos = mi->master_log_pos;
+ if (unlikely(mi->rli.relay_log.append(cev)))
+ {
+ sql_print_error("Slave I/O: error writing Create_file event to \
+relay log");
+ goto err;
+ }
+ cev_not_written=0;
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ }
+ else
+ {
+ aev.block = (char*)net->read_pos;
+ aev.block_len = num_bytes;
+ aev.log_pos = mi->master_log_pos;
+ if (unlikely(mi->rli.relay_log.append(&aev)))
+ {
+ sql_print_error("Slave I/O: error writing Append_block event to \
+relay log");
+ goto err;
+ }
+ mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ;
+ }
+ }
+ }
+ error=0;
+err:
+ DBUG_RETURN(error);
+}
+
+/*
+ Start using a new binary log on the master
+
+ SYNOPSIS
+ process_io_rotate()
+ mi master_info for the slave
+ rev The rotate log event read from the binary log
+
+ DESCRIPTION
+ Updates the master info and relay data with the place in the next binary
+ log where we should start reading.
+
+ NOTES
+ We assume we already locked mi->data_lock
+
+ RETURN VALUES
+ 0 ok
+ 1 Log event is illegal
+*/
+
+static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev)
+{
+ int return_val= 1;
+ DBUG_ENTER("process_io_rotate");
+ safe_mutex_assert_owner(&mi->data_lock);
+
+ if (unlikely(!rev->is_valid()))
+ DBUG_RETURN(1);
+
+ memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
+ mi->master_log_pos= rev->pos;
+ DBUG_PRINT("info", ("master_log_pos: '%s' %d",
+ mi->master_log_name, (ulong) mi->master_log_pos));
+#ifndef DBUG_OFF
+ /*
+ If we do not do this, we will be getting the first
+ rotate event forever, so we need to not disconnect after one.
+ */
+ if (disconnect_slave_event_count)
+ events_till_disconnect++;
+#endif
+ DBUG_RETURN(0);
+}
+
+/*
+ TODO:
+ Test this code before release - it has to be tested on a separate
+ setup with 3.23 master
+*/
+
+static int queue_old_event(MASTER_INFO *mi, const char *buf,
+ ulong event_len)
+{
+ const char *errmsg = 0;
+ ulong inc_pos;
+ bool ignore_event= 0;
+ char *tmp_buf = 0;
+ RELAY_LOG_INFO *rli= &mi->rli;
+ DBUG_ENTER("queue_old_event");
+
+ /*
+ If we get Load event, we need to pass a non-reusable buffer
+ to read_log_event, so we do a trick
+ */
+ if (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT)
+ {
+ if (unlikely(!(tmp_buf=(char*)my_malloc(event_len+1,MYF(MY_WME)))))
+ {
+ sql_print_error("Slave I/O: out of memory for Load event");
+ DBUG_RETURN(1);
+ }
+ memcpy(tmp_buf,buf,event_len);
+ tmp_buf[event_len]=0; // Create_file constructor wants null-term buffer
+ buf = (const char*)tmp_buf;
+ }
+ /*
+ This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to
+ send the loaded file, and write it to the relay log in the form of
+ Append_block/Exec_load (the SQL thread needs the data, as that thread is not
+ connected to the master).
+ */
+ Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
+ 1 /*old format*/ );
+ if (unlikely(!ev))
+ {
+ sql_print_error("Read invalid event from master: '%s',\
+ master could be corrupt but a more likely cause of this is a bug",
+ errmsg);
+ my_free((char*) tmp_buf, MYF(MY_ALLOW_ZERO_PTR));
+ DBUG_RETURN(1);
+ }
+ pthread_mutex_lock(&mi->data_lock);
+ ev->log_pos = mi->master_log_pos;
+ switch (ev->get_type_code()) {
+ case STOP_EVENT:
+ ignore_event= mi->ignore_stop_event;
+ mi->ignore_stop_event=0;
+ inc_pos= event_len;
+ break;
+ case ROTATE_EVENT:
+ if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
+ {
+ delete ev;
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(1);
+ }
+ mi->ignore_stop_event=1;
+ inc_pos= 0;
+ break;
+ case CREATE_FILE_EVENT:
+ /*
+ Yes it's possible to have CREATE_FILE_EVENT here, even if we're in
+ queue_old_event() which is for 3.23 events which don't comprise
+ CREATE_FILE_EVENT. This is because read_log_event() above has just
+ transformed LOAD_EVENT into CREATE_FILE_EVENT.
+ */
+ {
+ /* We come here when and only when tmp_buf != 0 */
+ DBUG_ASSERT(tmp_buf);
+ int error = process_io_create_file(mi,(Create_file_log_event*)ev);
+ delete ev;
+ mi->master_log_pos += event_len;
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ pthread_mutex_unlock(&mi->data_lock);
+ my_free((char*)tmp_buf, MYF(0));
+ DBUG_RETURN(error);
+ }
+ default:
+ mi->ignore_stop_event=0;
+ inc_pos= event_len;
+ break;
+ }
+ if (likely(!ignore_event))
+ {
+ if (unlikely(rli->relay_log.append(ev)))
+ {
+ delete ev;
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(1);
}
+ rli->relay_log.harvest_bytes_written(&rli->log_space_total);
+ }
+ delete ev;
+ mi->master_log_pos+= inc_pos;
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(0);
+}
+
+/*
+ TODO: verify the issue with stop events, see if we need them at all
+ in the relay log
+*/
+
+int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
+{
+ int error= 0;
+ ulong inc_pos;
+ bool ignore_event= 0;
+ RELAY_LOG_INFO *rli= &mi->rli;
+ DBUG_ENTER("queue_event");
+
+ if (mi->old_format)
+ DBUG_RETURN(queue_old_event(mi,buf,event_len));
+
+ pthread_mutex_lock(&mi->data_lock);
+
+ /*
+ TODO: figure out if other events in addition to Rotate
+ require special processing
+ */
+ switch (buf[EVENT_TYPE_OFFSET]) {
+ case STOP_EVENT:
+ ignore_event= mi->ignore_stop_event;
+ mi->ignore_stop_event= 0;
+ inc_pos= event_len;
+ break;
+ case ROTATE_EVENT:
+ {
+ Rotate_log_event rev(buf,event_len,0);
+ if (unlikely(process_io_rotate(mi,&rev)))
+ {
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(1);
+ }
+ mi->ignore_stop_event= 1;
+ inc_pos= 0;
+ break;
+ }
+ default:
+ mi->ignore_stop_event= 0;
+ inc_pos= event_len;
+ break;
+ }
- return slave_was_killed;
+ if (likely(!ignore_event &&
+ !(error= rli->relay_log.appendv(buf,event_len,0))))
+ {
+ mi->master_log_pos+= inc_pos;
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ rli->relay_log.harvest_bytes_written(&rli->log_space_total);
+ }
+ pthread_mutex_unlock(&mi->data_lock);
+ DBUG_RETURN(error);
+}
+
+
+void end_relay_log_info(RELAY_LOG_INFO* rli)
+{
+ DBUG_ENTER("end_relay_log_info");
+
+ if (!rli->inited)
+ DBUG_VOID_RETURN;
+ if (rli->info_fd >= 0)
+ {
+ end_io_cache(&rli->info_file);
+ (void) my_close(rli->info_fd, MYF(MY_WME));
+ rli->info_fd = -1;
+ }
+ if (rli->cur_log_fd >= 0)
+ {
+ end_io_cache(&rli->cache_buf);
+ (void)my_close(rli->cur_log_fd, MYF(MY_WME));
+ rli->cur_log_fd = -1;
+ }
+ rli->inited = 0;
+ rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
+ /*
+ Delete the slave's temporary tables from memory.
+ In the future there will be other actions than this, to ensure persistance
+ of slave's temp tables after shutdown.
+ */
+ rli->close_temporary_tables();
+ DBUG_VOID_RETURN;
+}
+
+/* try to connect until successful or slave killed */
+static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
+{
+ return connect_to_master(thd, mysql, mi, 0, 0);
}
+
/*
Try to connect until successful or slave killed or we have retried
master_retry_count times
*/
-static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
- bool suppress_warnings)
+static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
+ bool reconnect, bool suppress_warnings)
{
int slave_was_killed;
int last_errno= -2; // impossible error
ulong err_count=0;
char llbuff[22];
+ DBUG_ENTER("connect_to_master");
- /*
- If we lost connection after reading a state set event
- we will be re-reading it, so pending needs to be cleared
- */
- mi->pending = 0;
#ifndef DBUG_OFF
events_till_disconnect = disconnect_slave_event_count;
#endif
- while (!(slave_was_killed = slave_killed(thd)) && mc_mysql_reconnect(mysql))
+ uint client_flag=0;
+ if (opt_slave_compressed_protocol)
+ client_flag=CLIENT_COMPRESS; /* We will use compression */
+
+ while (!(slave_was_killed = io_slave_killed(thd,mi)) &&
+ (reconnect ? mc_mysql_reconnect(mysql) != 0:
+ !mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
+ mi->port, 0, client_flag,
+ thd->variables.net_read_timeout)))
{
/* Don't repeat last error */
if (mc_mysql_errno(mysql) != last_errno)
{
+ last_errno=mc_mysql_errno(mysql);
suppress_warnings= 0;
- sql_print_error("Slave thread: error re-connecting to master: \
-%s, last_errno=%d, retry in %d sec",
- mc_mysql_error(mysql), last_errno=mc_mysql_errno(mysql),
- mi->connect_retry);
+ sql_print_error("Slave I/O thread: error %s to master \
+'%s@%s:%d': \
+Error: '%s' errno: %d retry-time: %d retries: %d",
+ (reconnect ? "reconnecting" : "connecting"),
+ mi->user,mi->host,mi->port,
+ mc_mysql_error(mysql), last_errno,
+ mi->connect_retry,
+ master_retry_count);
}
- safe_sleep(thd, mi->connect_retry);
- /* if master_retry_count is not set, keep trying until success */
- if (master_retry_count && err_count++ == master_retry_count)
+ /*
+ By default we try forever. The reason is that failure will trigger
+ master election, so if the user did not set master_retry_count we
+ do not want to have election triggered on the first failure to
+ connect
+ */
+ if (++err_count == master_retry_count)
{
slave_was_killed=1;
+ if (reconnect)
+ change_rpl_status(RPL_ACTIVE_SLAVE,RPL_LOST_SOLDIER);
break;
}
+ safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
+ (void*)mi);
}
if (!slave_was_killed)
{
- if (!suppress_warnings)
- sql_print_error("Slave: reconnected to master '%s@%s:%d',\
-replication resumed in log '%s' at position %s", glob_mi.user,
- glob_mi.host, glob_mi.port,
- RPL_LOG_NAME,
- llstr(glob_mi.pos,llbuff));
+ if (reconnect)
+ {
+ if (!suppress_warnings && global_system_variables.log_warnings)
+ sql_print_error("Slave: connected to master '%s@%s:%d',\
+replication resumed in log '%s' at position %s", mi->user,
+ mi->host, mi->port,
+ IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
+ }
+ else
+ {
+ change_rpl_status(RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE);
+ mysql_log.write(thd, COM_CONNECT_OUT, "%s@%s:%d",
+ mi->user, mi->host, mi->port);
+ }
#ifdef SIGNAL_WITH_VIO_CLOSE
thd->set_active_vio(mysql->net.vio);
#endif
}
+ DBUG_PRINT("exit",("slave_was_killed: %d", slave_was_killed));
+ DBUG_RETURN(slave_was_killed);
+}
+
+
+/*
+ Try to connect until successful or slave killed or we have retried
+ master_retry_count times
+*/
+
+static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
+ bool suppress_warnings)
+{
+ return connect_to_master(thd, mysql, mi, 1, suppress_warnings);
+}
+
+
+/*
+ Store the file and position where the execute-slave thread are in the
+ relay log.
+
+ SYNOPSIS
+ flush_relay_log_info()
+ rli Relay log information
+
+ NOTES
+ - As this is only called by the slave thread, we don't need to
+ have a lock on this.
+ - If there is an active transaction, then we don't update the position
+ in the relay log. This is to ensure that we re-execute statements
+ if we die in the middle of an transaction that was rolled back.
+ - As a transaction never spans binary logs, we don't have to handle the
+ case where we do a relay-log-rotation in the middle of the transaction.
+ If this would not be the case, we would have to ensure that we
+ don't delete the relay log file where the transaction started when
+ we switch to a new relay log file.
+
+ TODO
+ - Change the log file information to a binary format to avoid calling
+ longlong2str.
+
+ RETURN VALUES
+ 0 ok
+ 1 write error
+*/
+
+bool flush_relay_log_info(RELAY_LOG_INFO* rli)
+{
+ bool error=0;
+ IO_CACHE *file = &rli->info_file;
+ char buff[FN_REFLEN*2+22*2+4], *pos;
+
+ /* sql_thd is not set when calling from init_slave() */
+ if ((rli->sql_thd && rli->sql_thd->options & OPTION_BEGIN))
+ return 0; // Wait for COMMIT
+
+ my_b_seek(file, 0L);
+ pos=strmov(buff, rli->relay_log_name);
+ *pos++='\n';
+ pos=longlong2str(rli->relay_log_pos, pos, 10);
+ *pos++='\n';
+ pos=strmov(pos, rli->master_log_name);
+ *pos++='\n';
+ pos=longlong2str(rli->master_log_pos, pos, 10);
+ *pos='\n';
+ if (my_b_write(file, (byte*) buff, (ulong) (pos-buff)+1))
+ error=1;
+ if (flush_io_cache(file))
+ error=1;
+ if (flush_io_cache(rli->cur_log)) // QQ Why this call ?
+ error=1;
+ return error;
+}
+
+
+/*
+ This function is called when we notice that the current "hot" log
+ got rotated under our feet.
+*/
+
+static IO_CACHE *reopen_relay_log(RELAY_LOG_INFO *rli, const char **errmsg)
+{
+ DBUG_ASSERT(rli->cur_log != &rli->cache_buf);
+ DBUG_ASSERT(rli->cur_log_fd == -1);
+ DBUG_ENTER("reopen_relay_log");
+
+ IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
+ if ((rli->cur_log_fd=open_binlog(cur_log,rli->relay_log_name,
+ errmsg)) <0)
+ DBUG_RETURN(0);
+ /*
+ We want to start exactly where we was before:
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
+ */
+ my_b_seek(cur_log,rli->relay_log_pos + rli->pending);
+ DBUG_RETURN(cur_log);
+}
+
+
+Log_event* next_event(RELAY_LOG_INFO* rli)
+{
+ Log_event* ev;
+ IO_CACHE* cur_log = rli->cur_log;
+ pthread_mutex_t *log_lock = rli->relay_log.get_log_lock();
+ const char* errmsg=0;
+ THD* thd = rli->sql_thd;
+ DBUG_ENTER("next_event");
+ DBUG_ASSERT(thd != 0);
+
+ /*
+ For most operations we need to protect rli members with data_lock,
+ so we will hold it for the most of the loop below
+ However, we will release it whenever it is worth the hassle,
+ and in the cases when we go into a pthread_cond_wait() with the
+ non-data_lock mutex
+ */
+ pthread_mutex_lock(&rli->data_lock);
+
+ while (!sql_slave_killed(thd,rli))
+ {
+ /*
+ We can have two kinds of log reading:
+ hot_log:
+ rli->cur_log points at the IO_CACHE of relay_log, which
+ is actively being updated by the I/O thread. We need to be careful
+ in this case and make sure that we are not looking at a stale log that
+ has already been rotated. If it has been, we reopen the log.
+
+ The other case is much simpler:
+ We just have a read only log that nobody else will be updating.
+ */
+ bool hot_log;
+ if ((hot_log = (cur_log != &rli->cache_buf)))
+ {
+ DBUG_ASSERT(rli->cur_log_fd == -1); // foreign descriptor
+ pthread_mutex_lock(log_lock);
+
+ /*
+ Reading xxx_file_id is safe because the log will only
+ be rotated when we hold relay_log.LOCK_log
+ */
+ if (rli->relay_log.get_open_count() != rli->cur_log_old_open_count)
+ {
+ // The master has switched to a new log file; Reopen the old log file
+ cur_log=reopen_relay_log(rli, &errmsg);
+ pthread_mutex_unlock(log_lock);
+ if (!cur_log) // No more log files
+ goto err;
+ hot_log=0; // Using old binary log
+ }
+ }
+#ifndef DBUG_OFF
+ {
+ DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE);
+ /* The next assertion sometimes (very rarely) fails, let's try to track it */
+ char llbuf1[22], llbuf2[22];
+ /* Merging man, please be careful with this; in 4.1, the assertion below is
+ replaced by
+ DBUG_ASSERT(my_b_tell(cur_log) == rli->event_relay_log_pos);
+ so you should not merge blindly (fortunately it won't build then), and
+ instead modify the merged code. Thanks. */
+ DBUG_PRINT("info", ("Before assert, my_b_tell(cur_log)=%s \
+rli->relay_log_pos=%s rli->pending=%lu",
+ llstr(my_b_tell(cur_log),llbuf1),
+ llstr(rli->relay_log_pos,llbuf2),
+ rli->pending));
+ DBUG_ASSERT(my_b_tell(cur_log) == rli->relay_log_pos + rli->pending);
+ }
+#endif
+
+ /*
+ Relay log is always in new format - if the master is 3.23, the
+ I/O thread will convert the format for us
+ */
+ if ((ev=Log_event::read_log_event(cur_log,0,(bool)0 /* new format */)))
+ {
+ DBUG_ASSERT(thd==rli->sql_thd);
+ if (hot_log)
+ pthread_mutex_unlock(log_lock);
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_RETURN(ev);
+ }
+ DBUG_ASSERT(thd==rli->sql_thd);
+ if (opt_reckless_slave) // For mysql-test
+ cur_log->error = 0;
+ if (cur_log->error < 0)
+ {
+ errmsg = "slave SQL thread aborted because of I/O error";
+ if (hot_log)
+ pthread_mutex_unlock(log_lock);
+ goto err;
+ }
+ if (!cur_log->error) /* EOF */
+ {
+ /*
+ On a hot log, EOF means that there are no more updates to
+ process and we must block until I/O thread adds some and
+ signals us to continue
+ */
+ if (hot_log)
+ {
+ DBUG_ASSERT(rli->relay_log.get_open_count() == rli->cur_log_old_open_count);
+ /*
+ We can, and should release data_lock while we are waiting for
+ update. If we do not, show slave status will block
+ */
+ pthread_mutex_unlock(&rli->data_lock);
+
+ /*
+ Possible deadlock :
+ - the I/O thread has reached log_space_limit
+ - the SQL thread has read all relay logs, but cannot purge for some
+ reason:
+ * it has already purged all logs except the current one
+ * there are other logs than the current one but they're involved in
+ a transaction that finishes in the current one (or is not finished)
+ Solution :
+ Wake up the possibly waiting I/O thread, and set a boolean asking
+ the I/O thread to temporarily ignore the log_space_limit
+ constraint, because we do not want the I/O thread to block because of
+ space (it's ok if it blocks for any other reason (e.g. because the
+ master does not send anything). Then the I/O thread stops waiting
+ and reads more events.
+ The SQL thread decides when the I/O thread should take log_space_limit
+ into account again : ignore_log_space_limit is reset to 0
+ in purge_first_log (when the SQL thread purges the just-read relay
+ log), and also when the SQL thread starts. We should also reset
+ ignore_log_space_limit to 0 when the user does RESET SLAVE, but in
+ fact, no need as RESET SLAVE requires that the slave
+ be stopped, and the SQL thread sets ignore_log_space_limit to 0 when
+ it stops.
+ */
+ pthread_mutex_lock(&rli->log_space_lock);
+ // prevent the I/O thread from blocking next times
+ rli->ignore_log_space_limit= 1;
+ /*
+ If the I/O thread is blocked, unblock it.
+ Ok to broadcast after unlock, because the mutex is only destroyed in
+ ~st_relay_log_info(), i.e. when rli is destroyed, and rli will not be
+ destroyed before we exit the present function.
+ */
+ pthread_mutex_unlock(&rli->log_space_lock);
+ pthread_cond_broadcast(&rli->log_space_cond);
+ // Note that wait_for_update unlocks lock_log !
+ rli->relay_log.wait_for_update(rli->sql_thd, 1);
+ // re-acquire data lock since we released it earlier
+ pthread_mutex_lock(&rli->data_lock);
+ continue;
+ }
+ /*
+ If the log was not hot, we need to move to the next log in
+ sequence. The next log could be hot or cold, we deal with both
+ cases separately after doing some common initialization
+ */
+ end_io_cache(cur_log);
+ DBUG_ASSERT(rli->cur_log_fd >= 0);
+ my_close(rli->cur_log_fd, MYF(MY_WME));
+ rli->cur_log_fd = -1;
+
+ /*
+ TODO: make skip_log_purge a start-up option. At this point this
+ is not critical priority
+ */
+ if (!rli->skip_log_purge)
+ {
+ // purge_first_log will properly set up relay log coordinates in rli
+ if (rli->relay_log.purge_first_log(rli))
+ {
+ errmsg = "Error purging processed log";
+ goto err;
+ }
+ }
+ else
+ {
+ /*
+ If hot_log is set, then we already have a lock on
+ LOCK_log. If not, we have to get the lock.
+
+ According to Sasha, the only time this code will ever be executed
+ is if we are recovering from a bug.
+ */
+ if (rli->relay_log.find_next_log(&rli->linfo, !hot_log))
+ {
+ errmsg = "error switching to the next log";
+ goto err;
+ }
+ rli->relay_log_pos = BIN_LOG_HEADER_SIZE;
+ rli->pending=0;
+ strmake(rli->relay_log_name,rli->linfo.log_file_name,
+ sizeof(rli->relay_log_name)-1);
+ flush_relay_log_info(rli);
+ }
+
+ /*
+ Now we want to open this next log. To know if it's a hot log (the one
+ being written by the I/O thread now) or a cold log, we can use
+ is_active(); if it is hot, we use the I/O cache; if it's cold we open
+ the file normally. But if is_active() reports that the log is hot, this
+ may change between the test and the consequence of the test. So we may
+ open the I/O cache whereas the log is now cold, which is nonsense.
+ To guard against this, we need to have LOCK_log.
+ */
+
+ DBUG_PRINT("info",("hot_log: %d",hot_log));
+ if (!hot_log) /* if hot_log, we already have this mutex */
+ pthread_mutex_lock(log_lock);
+ if (rli->relay_log.is_active(rli->linfo.log_file_name))
+ {
+#ifdef EXTRA_DEBUG
+ sql_print_error("next log '%s' is currently active",
+ rli->linfo.log_file_name);
+#endif
+ rli->cur_log= cur_log= rli->relay_log.get_log_file();
+ rli->cur_log_old_open_count= rli->relay_log.get_open_count();
+ DBUG_ASSERT(rli->cur_log_fd == -1);
+
+ /*
+ Read pointer has to be at the start since we are the only
+ reader.
+ We must keep the LOCK_log to read the 4 first bytes, as this is a hot
+ log (same as when we call read_log_event() above: for a hot log we
+ take the mutex).
+ */
+ if (check_binlog_magic(cur_log,&errmsg))
+ {
+ if (!hot_log) pthread_mutex_unlock(log_lock);
+ goto err;
+ }
+ if (!hot_log) pthread_mutex_unlock(log_lock);
+ continue;
+ }
+ if (!hot_log) pthread_mutex_unlock(log_lock);
+ /*
+ if we get here, the log was not hot, so we will have to open it
+ ourselves. We are sure that the log is still not hot now (a log can get
+ from hot to cold, but not from cold to hot). No need for LOCK_log.
+ */
+#ifdef EXTRA_DEBUG
+ sql_print_error("next log '%s' is not active",
+ rli->linfo.log_file_name);
+#endif
+ // open_binlog() will check the magic header
+ if ((rli->cur_log_fd=open_binlog(cur_log,rli->linfo.log_file_name,
+ &errmsg)) <0)
+ goto err;
+ }
+ else
+ {
+ /*
+ Read failed with a non-EOF error.
+ TODO: come up with something better to handle this error
+ */
+ if (hot_log)
+ pthread_mutex_unlock(log_lock);
+ sql_print_error("Slave SQL thread: I/O error reading \
+event(errno: %d cur_log->error: %d)",
+ my_errno,cur_log->error);
+ // set read position to the beginning of the event
+ my_b_seek(cur_log,rli->relay_log_pos+rli->pending);
+ /* otherwise, we have had a partial read */
+ errmsg = "Aborting slave SQL thread because of partial event read";
+ break; // To end of function
+ }
+ }
+ if (!errmsg && global_system_variables.log_warnings)
+ errmsg = "slave SQL thread was killed";
- return slave_was_killed;
+err:
+ pthread_mutex_unlock(&rli->data_lock);
+ if (errmsg)
+ sql_print_error("Error reading relay log event: %s", errmsg);
+ DBUG_RETURN(0);
+}
+
+/*
+ Rotate a relay log (this is used only by FLUSH LOGS; the automatic rotation
+ because of size is simpler because when we do it we already have all relevant
+ locks; here we don't, so this function is mainly taking locks).
+ Returns nothing as we cannot catch any error (MYSQL_LOG::new_file() is void).
+*/
+
+void rotate_relay_log(MASTER_INFO* mi)
+{
+ DBUG_ENTER("rotate_relay_log");
+ RELAY_LOG_INFO* rli= &mi->rli;
+
+ lock_slave_threads(mi);
+ pthread_mutex_lock(&rli->data_lock);
+ /*
+ We need to test inited because otherwise, new_file() will attempt to lock
+ LOCK_log, which may not be inited (if we're not a slave).
+ */
+ if (!rli->inited)
+ {
+ DBUG_PRINT("info", ("rli->inited == 0"));
+ goto end;
+ }
+
+ /* If the relay log is closed, new_file() will do nothing. */
+ rli->relay_log.new_file(1);
+
+ /*
+ We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately
+ be counted, so imagine a succession of FLUSH LOGS and assume the slave
+ threads are started:
+ relay_log_space decreases by the size of the deleted relay log, but does
+ not increase, so flush-after-flush we may become negative, which is wrong.
+ Even if this will be corrected as soon as a query is replicated on the
+ slave (because the I/O thread will then call harvest_bytes_written() which
+ will harvest all these BIN_LOG_HEADER_SIZE we forgot), it may give strange
+ output in SHOW SLAVE STATUS meanwhile. So we harvest now.
+ If the log is closed, then this will just harvest the last writes, probably
+ 0 as they probably have been harvested.
+ */
+ rli->relay_log.harvest_bytes_written(&rli->log_space_total);
+end:
+ pthread_mutex_unlock(&rli->data_lock);
+ unlock_slave_threads(mi);
+ DBUG_VOID_RETURN;
}
+
#ifdef __GNUC__
template class I_List_iterator<i_string>;
template class I_List_iterator<i_string_pair>;
diff --git a/sql/slave.h b/sql/slave.h
index 769689ebfa2..ed34c12985a 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -1,71 +1,334 @@
#ifndef SLAVE_H
#define SLAVE_H
+#include "mysql.h"
+#include "my_list.h"
#define SLAVE_NET_TIMEOUT 3600
+#define MAX_SLAVE_ERRMSG 1024
#define MAX_SLAVE_ERROR 2000
+/*
+ The replication is accomplished by starting two threads - I/O
+ thread, and SQL thread. I/O thread is associated with its
+ MASTER_INFO struct, so MASTER_INFO can be viewed as I/O thread
+ descriptor. SQL thread is associated with RELAY_LOG_INFO struct.
+
+ I/O thread reads maintains a connection to the master, and reads log
+ events from the master as they arrive, queueing them by writing them
+ out into the temporary slave binary log (relay log). The SQL thread,
+ in turn, reads the slave binary log executing each event.
+
+ Relay log is needed to be able to handle situations when there is a large
+ backlog of unprocessed events from the master (eg. one particular update
+ takes a day to finish), and to be able to restart the slave server without
+ having to re-read the master updates.
+ */
+
+/*
+ MUTEXES in replication:
+
+ LOCK_active_mi: this is meant for multimaster, when we can switch from a
+ master to another. It protects active_mi. We don't care of it for the moment,
+ as active_mi never moves (it's created at startup and deleted at shutdown, and
+ not changed: it always points to the same MASTER_INFO struct), because we
+ don't have multimaster. So for the moment, mi does not move, and mi->rli does
+ not either.
+
+ In MASTER_INFO: run_lock, data_lock
+ run_lock protects all information about the run state: slave_running, and the
+ existence of the I/O thread (to stop/start it, you need this mutex).
+ data_lock protects some moving members of the struct: counters (log name,
+ position) and relay log (MYSQL_LOG object).
+
+ In RELAY_LOG_INFO: run_lock, data_lock
+ see MASTER_INFO
+
+ In MYSQL_LOG: LOCK_log, LOCK_index of the binlog and the relay log
+ LOCK_log: when you write to it. LOCK_index: when you create/delete a binlog
+ (so that you have to update the .index file).
+*/
+
extern ulong slave_net_timeout, master_retry_count;
extern MY_BITMAP slave_error_mask;
extern bool use_slave_mask;
+extern char* slave_load_tmpdir;
+extern my_string master_info_file,relay_log_info_file;
+extern my_string opt_relay_logname, opt_relaylog_index_name;
+extern my_bool opt_skip_slave_start, opt_reckless_slave;
+extern my_bool opt_log_slave_updates;
+extern ulonglong relay_log_space_limit;
+struct st_master_info;
+
+enum enum_binlog_formats {
+ BINLOG_FORMAT_CURRENT=0, /* 0 is important for easy 'if (mi->old_format)' */
+ BINLOG_FORMAT_323_LESS_57,
+ BINLOG_FORMAT_323_GEQ_57 };
+
+/*
+ TODO: this needs to be redone, but for now it does not matter since
+ we do not have multi-master yet.
+*/
+
+#define LOCK_ACTIVE_MI { pthread_mutex_lock(&LOCK_active_mi); \
+ ++active_mi_in_use; \
+ pthread_mutex_unlock(&LOCK_active_mi);}
+
+#define UNLOCK_ACTIVE_MI { pthread_mutex_lock(&LOCK_active_mi); \
+ --active_mi_in_use; \
+ pthread_mutex_unlock(&LOCK_active_mi); }
+
+/*
+ st_relay_log_info contains information on the current relay log and
+ relay log offset, and master log name and log sequence corresponding to the
+ last update. Additionally, misc information specific to the SQL thread is
+ included.
+
+ st_relay_log_info is initialized from the slave.info file if such exists.
+ Otherwise, data members are intialized with defaults. The initialization is
+ done with init_relay_log_info() call.
+
+ The format of slave.info file:
+
+ relay_log_name
+ relay_log_pos
+ master_log_name
+ master_log_pos
+
+ To clean up, call end_relay_log_info()
+ */
+
+typedef struct st_relay_log_info
+{
+ /*** The following variables can only be read when protect by data lock ****/
+
+ /*
+ info_fd - file descriptor of the info file. set only during
+ initialization or clean up - safe to read anytime
+ cur_log_fd - file descriptor of the current read relay log
+ */
+ File info_fd,cur_log_fd;
+ /* name of current read relay log */
+ char relay_log_name[FN_REFLEN];
+ /* master log name corresponding to current read position */
+ char master_log_name[FN_REFLEN];
+ /* original log position of last processed event */
+ volatile my_off_t master_log_pos;
+
+ /*
+ Protected with internal locks.
+ Must get data_lock when resetting the logs.
+ */
+ MYSQL_LOG relay_log;
+ LOG_INFO linfo;
+ IO_CACHE cache_buf,*cur_log;
+
+ /* The following variables are safe to read any time */
+
+ /* IO_CACHE of the info file - set only during init or end */
+ IO_CACHE info_file;
+
+ /*
+ When we restart slave thread we need to have access to the previously
+ created temporary tables. Modified only on init/end and by the SQL
+ thread, read only by SQL thread.
+ */
+ TABLE *save_temporary_tables;
+
+ /*
+ standard lock acquistion order to avoid deadlocks:
+ run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index
+ */
+ pthread_mutex_t data_lock,run_lock;
+
+ /*
+ start_cond is broadcast when SQL thread is started
+ stop_cond - when stopped
+ data_cond - when data protected by data_lock changes
+ */
+ pthread_cond_t start_cond, stop_cond, data_cond;
+
+ /* parent master info structure */
+ struct st_master_info *mi;
+
+ /*
+ Needed to deal properly with cur_log getting closed and re-opened with
+ a different log under our feet
+ */
+ uint32 cur_log_old_open_count;
+
+ /*
+ Current offset in the relay log.
+ pending - in some cases we do not increment offset immediately after
+ processing an event, because the following event needs to be processed
+ atomically together with this one ( so far, there is only one type of
+ such event - Intvar_event that sets auto_increment value). However, once
+ both events have been processed, we need to increment by the cumulative
+ offset. pending stored the extra offset to be added to the position.
+ */
+ ulonglong relay_log_pos, pending;
+
+ /*
+ Handling of the relay_log_space_limit optional constraint.
+ ignore_log_space_limit is used to resolve a deadlock between I/O and SQL
+ threads, the SQL thread sets it to unblock the I/O thread and make it
+ temporarily forget about the constraint.
+ */
+ ulonglong log_space_limit,log_space_total;
+ bool ignore_log_space_limit;
+
+ /*
+ InnoDB internally stores the master log position it has processed
+ so far; the position to store is really the sum of
+ pos + pending + event_len here since we must store the pos of the
+ END of the current log event
+ */
+ int event_len;
+
+ /*
+ Needed for problems when slave stops and we want to restart it
+ skipping one or more events in the master log that have caused
+ errors, and have been manually applied by DBA already.
+ */
+ volatile uint32 slave_skip_counter;
+ volatile ulong abort_pos_wait; /* Incremented on change master */
+ volatile ulong slave_run_id; /* Incremented on slave start */
+ pthread_mutex_t log_space_lock;
+ pthread_cond_t log_space_cond;
+ THD * sql_thd;
+ int last_slave_errno;
+#ifndef DBUG_OFF
+ int events_till_abort;
+#endif
+ char last_slave_error[MAX_SLAVE_ERRMSG];
+
+ /* if not set, the value of other members of the structure are undefined */
+ bool inited;
+ volatile bool abort_slave, slave_running;
+ bool skip_log_purge;
+ bool inside_transaction;
+
+ st_relay_log_info();
+ ~st_relay_log_info();
+ inline void inc_pending(ulonglong val)
+ {
+ pending += val;
+ }
+ /* TODO: this probably needs to be fixed */
+ inline void inc_pos(ulonglong val, ulonglong log_pos, bool skip_lock=0)
+ {
+ if (!skip_lock)
+ pthread_mutex_lock(&data_lock);
+ relay_log_pos += val+pending;
+ pending = 0;
+ if (log_pos)
+ master_log_pos = log_pos+ val;
+ pthread_cond_broadcast(&data_cond);
+ if (!skip_lock)
+ pthread_mutex_unlock(&data_lock);
+ }
+ /*
+ thread safe read of position - not needed if we are in the slave thread,
+ but required otherwise as var is a longlong
+ */
+ inline void read_pos(ulonglong& var)
+ {
+ pthread_mutex_lock(&data_lock);
+ var = relay_log_pos;
+ pthread_mutex_unlock(&data_lock);
+ }
+
+ int wait_for_pos(THD* thd, String* log_name, longlong log_pos,
+ longlong timeout);
+ void close_temporary_tables();
+} RELAY_LOG_INFO;
+
+
+Log_event* next_event(RELAY_LOG_INFO* rli);
+
+/*
+ st_master_info contains information about how to connect to a master,
+ current master log name, and current log offset, as well as misc
+ control variables
+
+ st_master_info is initialized once from the master.info file if such
+ exists. Otherwise, data members corresponding to master.info fields
+ are initialized with defaults specified by master-* options. The
+ initialization is done through init_master_info() call.
+
+ The format of master.info file:
+
+ log_name
+ log_pos
+ master_host
+ master_user
+ master_pass
+ master_port
+ master_connect_retry
+
+ To write out the contents of master.info file to disk ( needed every
+ time we read and queue data from the master ), a call to
+ flush_master_info() is required.
+ To clean up, call end_master_info()
+*/
+
+
typedef struct st_master_info
{
- char log_file_name[FN_REFLEN];
- ulonglong pos,pending;
- int event_len; /* Added by Heikki: InnoDB internally stores the
- master log position it has processed so far; the
- position to store is really the sum
- pos + pending + event_len
- here since we must store the pos of the END of the
- current log event */
- File fd; // we keep the file open, so we need to remember the file pointer
- IO_CACHE file;
- // the variables below are needed because we can change masters on the fly
+ char master_log_name[FN_REFLEN];
char host[HOSTNAME_LENGTH+1];
char user[USERNAME_LENGTH+1];
- char password[HASH_PASSWORD_LENGTH+1];
+ char password[MAX_PASSWORD_LENGTH+1];
+
+ my_off_t master_log_pos;
+ File fd; // we keep the file open, so we need to remember the file pointer
+ IO_CACHE file;
+
+ /* the variables below are needed because we can change masters on the fly */
+ pthread_mutex_t data_lock,run_lock;
+ pthread_cond_t data_cond,start_cond,stop_cond;
+ THD *io_thd;
+ MYSQL* mysql;
+ uint32 file_id; /* for 3.23 load data infile */
+ RELAY_LOG_INFO rli;
uint port;
uint connect_retry;
- pthread_mutex_t lock;
- pthread_cond_t cond;
+#ifndef DBUG_OFF
+ int events_till_abort;
+#endif
bool inited;
+ enum enum_binlog_formats old_format; /* binlog is in 3.23 format */
+ volatile bool abort_slave, slave_running;
+ volatile ulong slave_run_id;
+ bool ignore_stop_event;
- st_master_info():pending(0),fd(-1),inited(0)
+ st_master_info()
+ :fd(-1), io_thd(0), inited(0), old_format(BINLOG_FORMAT_CURRENT),
+ abort_slave(0),slave_running(0), slave_run_id(0)
{
host[0] = 0; user[0] = 0; password[0] = 0;
- pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
- pthread_cond_init(&cond, NULL);
+ bzero((char *)&file, sizeof(file));
+ pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&data_cond, NULL);
+ pthread_cond_init(&start_cond, NULL);
+ pthread_cond_init(&stop_cond, NULL);
}
~st_master_info()
{
- pthread_mutex_destroy(&lock);
- pthread_cond_destroy(&cond);
- }
- inline void inc_pending(ulonglong val)
- {
- pending += val;
- }
- inline void inc_pos(ulonglong val)
- {
- pthread_mutex_lock(&lock);
- pos += val + pending;
- pending = 0;
- pthread_cond_broadcast(&cond);
- pthread_mutex_unlock(&lock);
- }
- // thread safe read of position - not needed if we are in the slave thread,
- // but required otherwise
- inline void read_pos(ulonglong& var)
- {
- pthread_mutex_lock(&lock);
- var = pos;
- pthread_mutex_unlock(&lock);
+ pthread_mutex_destroy(&run_lock);
+ pthread_mutex_destroy(&data_lock);
+ pthread_cond_destroy(&data_cond);
+ pthread_cond_destroy(&start_cond);
+ pthread_cond_destroy(&stop_cond);
}
- int wait_for_pos(THD* thd, String* log_name, ulonglong log_pos);
} MASTER_INFO;
+
+int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len);
+
typedef struct st_table_rule_ent
{
char* db;
@@ -75,64 +338,123 @@ typedef struct st_table_rule_ent
#define TABLE_RULE_HASH_SIZE 16
#define TABLE_RULE_ARR_SIZE 16
+#define MAX_SLAVE_ERRMSG 1024
+
+#define RPL_LOG_NAME (rli->master_log_name[0] ? rli->master_log_name :\
+ "FIRST")
+#define IO_RPL_LOG_NAME (mi->master_log_name[0] ? mi->master_log_name :\
+ "FIRST")
-int flush_master_info(MASTER_INFO* mi);
+/* masks for start/stop operations on io and sql slave threads */
+#define SLAVE_IO 1
+#define SLAVE_SQL 2
-int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd = -1);
-// if fd is -1, dump to NET
-int fetch_nx_table(THD* thd, MASTER_INFO* mi);
-// retrieve non-exitent table from master
-// the caller must set thd->last_nx_table and thd->last_nx_db first
-int show_master_info(THD* thd);
+/*
+ If the following is set, if first gives an error, second will be
+ tried. Otherwise, if first fails, we fail.
+*/
+#define SLAVE_FORCE_ALL 4
+
+int init_slave();
+void init_slave_skip_errors(const char* arg);
+bool flush_master_info(MASTER_INFO* mi);
+bool flush_relay_log_info(RELAY_LOG_INFO* rli);
+int register_slave_on_master(MYSQL* mysql);
+int terminate_slave_threads(MASTER_INFO* mi, int thread_mask,
+ bool skip_lock = 0);
+int terminate_slave_thread(THD* thd, pthread_mutex_t* term_mutex,
+ pthread_mutex_t* cond_lock,
+ pthread_cond_t* term_cond,
+ volatile bool* slave_running);
+int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
+ MASTER_INFO* mi, const char* master_info_fname,
+ const char* slave_info_fname, int thread_mask);
+/*
+ cond_lock is usually same as start_lock. It is needed for the case when
+ start_lock is 0 which happens if start_slave_thread() is called already
+ inside the start_lock section, but at the same time we want a
+ pthread_cond_wait() on start_cond,start_lock
+*/
+int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock,
+ pthread_mutex_t *cond_lock,
+ pthread_cond_t* start_cond,
+ volatile bool *slave_running,
+ volatile ulong *slave_run_id,
+ MASTER_INFO* mi);
+
+/* If fd is -1, dump to NET */
+int mysql_table_dump(THD* thd, const char* db,
+ const char* tbl_name, int fd = -1);
+
+/* retrieve table from master and copy to slave*/
+int fetch_master_table(THD* thd, const char* db_name, const char* table_name,
+ MASTER_INFO* mi, MYSQL* mysql, bool overwrite);
+
+int show_master_info(THD* thd, MASTER_INFO* mi);
int show_binlog_info(THD* thd);
+/* See if the query uses any tables that should not be replicated */
int tables_ok(THD* thd, TABLE_LIST* tables);
-// see if the query uses any tables that should not be replicated
+/*
+ Check to see if the database is ok to operate on with respect to the
+ do and ignore lists - used in replication
+*/
int db_ok(const char* db, I_List<i_string> &do_list,
I_List<i_string> &ignore_list );
-// check to see if the database is ok to operate on with respect to the
-// do and ignore lists - used in replication
+int db_ok_with_wild_table(const char *db);
int add_table_rule(HASH* h, const char* table_spec);
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
void init_table_rule_hash(HASH* h, bool* h_inited);
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
-void init_slave_skip_errors(char* arg);
+const char *rewrite_db(const char* db);
+const char *print_slave_db_safe(const char* db);
+int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
+void skip_load_data_infile(NET* net);
+void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...);
-void end_slave(); // clean up
-int init_master_info(MASTER_INFO* mi);
+void end_slave(); /* clean up */
+void init_master_info_with_options(MASTER_INFO* mi);
+void clear_last_slave_error(RELAY_LOG_INFO* rli);
+int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
+ const char* slave_info_fname,
+ bool abort_if_no_master_info_file);
void end_master_info(MASTER_INFO* mi);
-extern bool opt_log_slave_updates ;
-pthread_handler_decl(handle_slave,arg);
-extern bool volatile abort_loop, abort_slave, slave_running;
-extern uint32 slave_skip_counter;
-// needed for problems when slave stops and
-// we want to restart it skipping one or more events in the master log that
-// have caused errors, and have been manually applied by DBA already
-
-extern pthread_t slave_real_id;
-extern THD* slave_thd;
-extern MASTER_INFO glob_mi;
+int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname);
+void end_relay_log_info(RELAY_LOG_INFO* rli);
+void lock_slave_threads(MASTER_INFO* mi);
+void unlock_slave_threads(MASTER_INFO* mi);
+void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse);
+int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos,
+ bool need_data_lock, const char** errmsg);
+
+int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
+ const char** errmsg);
+void rotate_relay_log(MASTER_INFO* mi);
+
+extern "C" pthread_handler_decl(handle_slave_io,arg);
+extern "C" pthread_handler_decl(handle_slave_sql,arg);
+extern bool volatile abort_loop;
+extern MASTER_INFO main_mi, *active_mi; /* active_mi for multi-master */
+extern volatile int active_mi_in_use;
+extern LIST master_list;
extern HASH replicate_do_table, replicate_ignore_table;
extern DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table;
extern bool do_table_inited, ignore_table_inited,
wild_do_table_inited, wild_ignore_table_inited;
extern bool table_rules_on;
-#ifndef DBUG_OFF
extern int disconnect_slave_event_count, abort_slave_event_count ;
-#endif
-// the master variables are defaults read from my.cnf or command line
-extern uint master_port, master_connect_retry;
+/* the master variables are defaults read from my.cnf or command line */
+extern uint master_port, master_connect_retry, report_port;
extern my_string master_user, master_password, master_host,
- master_info_file;
+ master_info_file, relay_log_info_file, report_user, report_host,
+ report_password;
extern I_List<i_string> replicate_do_db, replicate_ignore_db;
extern I_List<i_string_pair> replicate_rewrite_db;
extern I_List<THD> threads;
#endif
-
-
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 56884ad9dd1..596619b3955 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000-2003 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -28,25 +28,29 @@
#include "mysql_priv.h"
#include "sql_acl.h"
#include "hash_filo.h"
+#ifdef HAVE_REPLICATION
+#include "sql_repl.h" //for tables_ok()
+#endif
#include <m_ctype.h>
+#include <assert.h>
#include <stdarg.h>
-/*
- ACL_HOST is used if no host is specified
- */
-
struct acl_host_and_ip
{
char *hostname;
long ip,ip_mask; // Used with masked ip:s
};
+
class ACL_ACCESS {
public:
ulong sort;
- uint access;
+ ulong access;
};
+
+/* ACL_HOST is used if no host is specified */
+
class ACL_HOST :public ACL_ACCESS
{
public:
@@ -54,15 +58,20 @@ public:
char *db;
};
+
class ACL_USER :public ACL_ACCESS
{
public:
acl_host_and_ip host;
uint hostname_length;
+ USER_RESOURCES user_resource;
char *user,*password;
ulong salt[2];
+ enum SSL_type ssl_type;
+ const char *ssl_cipher, *x509_issuer, *x509_subject;
};
+
class ACL_DB :public ACL_ACCESS
{
public:
@@ -70,14 +79,16 @@ public:
char *user,*db;
};
+
class acl_entry :public hash_filo_element
{
public:
- uint access;
+ ulong access;
uint16 length;
char key[1]; // Key will be stored here
};
+
static byte* acl_entry_get_key(acl_entry *entry,uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -95,7 +106,7 @@ static HASH acl_check_hosts, hash_tables;
static DYNAMIC_ARRAY acl_wild_hosts;
static hash_filo *acl_cache;
static uint grant_version=0;
-static uint get_access(TABLE *form,uint fieldnr);
+static ulong get_access(TABLE *form,uint fieldnr);
static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b);
static ulong get_sort(uint count,...);
static void init_check_host(void);
@@ -103,32 +114,50 @@ static ACL_USER *find_acl_user(const char *host, const char *user);
static bool update_user_table(THD *thd, const char *host, const char *user,
const char *new_password);
static void update_hostname(acl_host_and_ip *host, const char *hostname);
-static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
+static bool compare_hostname(const acl_host_and_ip *host,const char *hostname,
const char *ip);
-int acl_init(bool dont_read_acl_tables)
+/*
+ Read grant privileges from the privilege tables in the 'mysql' database.
+
+ SYNOPSIS
+ acl_init()
+ thd Thread handler
+ dont_read_acl_tables Set to 1 if run with --skip-grant
+
+ RETURN VALUES
+ 0 ok
+ 1 Could not initialize grant's
+*/
+
+
+my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
{
THD *thd;
TABLE_LIST tables[3];
TABLE *table;
READ_RECORD read_record_info;
+ MYSQL_LOCK *lock;
+ my_bool return_val=1;
DBUG_ENTER("acl_init");
if (!acl_cache)
acl_cache=new hash_filo(ACL_CACHE_SIZE,0,0,
(hash_get_key) acl_entry_get_key,
- (void (*)(void*)) free);
+ (hash_free_key) free);
if (dont_read_acl_tables)
DBUG_RETURN(0); /* purecov: tested */
+ /*
+ To be able to run this from boot, we allocate a temporary THD
+ */
if (!(thd=new THD))
DBUG_RETURN(1); /* purecov: inspected */
+ thd->store_globals();
+
acl_cache->clear(1); // Clear locked hostname cache
- thd->version=refresh_version;
- thd->mysys_var=my_thread_var;
- thd->current_tablenr=0;
- thd->open_tables=0;
- thd->db=my_strdup("mysql",MYF(0));
+ thd->db= my_strdup("mysql",MYF(0));
+ thd->db_length=5; // Safety
bzero((char*) &tables,sizeof(tables));
tables[0].alias=tables[0].real_name=(char*) "host";
tables[1].alias=tables[1].real_name=(char*) "user";
@@ -140,38 +169,36 @@ int acl_init(bool dont_read_acl_tables)
if (open_tables(thd,tables))
{
- close_thread_tables(thd); /* purecov: inspected */
- delete thd; /* purecov: inspected */
- DBUG_RETURN(1); /* purecov: inspected */
+ sql_print_error("Fatal error: Can't open privilege tables: %s",
+ thd->net.last_error);
+ goto end;
}
TABLE *ptr[3]; // Lock tables for quick update
ptr[0]= tables[0].table;
ptr[1]= tables[1].table;
ptr[2]= tables[2].table;
- MYSQL_LOCK *lock=mysql_lock_tables(thd,ptr,3);
- if (!lock)
+ if (!(lock=mysql_lock_tables(thd,ptr,3)))
{
- close_thread_tables(thd); /* purecov: inspected */
- delete thd; /* purecov: inspected */
- DBUG_RETURN(1); /* purecov: inspected */
+ sql_print_error("Fatal error: Can't lock privilege tables: %s",
+ thd->net.last_error);
+ goto end;
}
-
- init_sql_alloc(&mem,1024,0);
+ init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0);
VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50));
while (!(read_record_info.read_record(&read_record_info)))
{
ACL_HOST host;
update_hostname(&host.host,get_field(&mem, table,0));
- host.db=get_field(&mem, table,1);
- host.access=get_access(table,2);
- host.access=fix_rights_for_db(host.access);
- host.sort=get_sort(2,host.host.hostname,host.db);
+ host.db= get_field(&mem, table,1);
+ host.access= get_access(table,2);
+ host.access= fix_rights_for_db(host.access);
+ host.sort= get_sort(2,host.host.hostname,host.db);
#ifndef TO_BE_REMOVED
if (table->fields == 8)
{ // Without grant
if (host.access & CREATE_ACL)
- host.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
+ host.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL;
}
#endif
VOID(push_dynamic(&acl_hosts,(gptr) &host));
@@ -186,11 +213,11 @@ int acl_init(bool dont_read_acl_tables)
if (table->field[2]->field_length == 8 &&
protocol_version == PROTOCOL_VERSION)
{
- sql_print_error(
- "Old 'user' table. (Check README or the Reference manual). Continuing --old-protocol"); /* purecov: tested */
+ sql_print_error("Old 'user' table. (Check README or the Reference manual). Continuing --old-protocol"); /* purecov: tested */
protocol_version=9; /* purecov: tested */
}
+ DBUG_PRINT("info",("user table fields: %d",table->fields));
allow_all_hosts=0;
while (!(read_record_info.read_record(&read_record_info)))
{
@@ -203,7 +230,7 @@ int acl_init(bool dont_read_acl_tables)
protocol_version == PROTOCOL_VERSION)
{
sql_print_error(
- "Found old style password for user '%s'. Ignoring user. (You may want to restart using --old-protocol)",
+ "Found old style password for user '%s'. Ignoring user. (You may want to restart mysqld using --old-protocol)",
user.user ? user.user : ""); /* purecov: tested */
}
else if (length % 8 || length > 16)
@@ -212,19 +239,57 @@ int acl_init(bool dont_read_acl_tables)
"Found invalid password for user: '%s'@'%s'; Ignoring user",
user.user ? user.user : "",
user.host.hostname ? user.host.hostname : ""); /* purecov: tested */
- continue; /* purecov: tested */
+ continue; /* purecov: tested */
}
get_salt_from_password(user.salt,user.password);
user.access=get_access(table,3) & GLOBAL_ACLS;
user.sort=get_sort(2,user.host.hostname,user.user);
- user.hostname_length=user.host.hostname ? (uint) strlen(user.host.hostname) : 0;
-#ifndef TO_BE_REMOVED
- if (table->fields <= 13)
- { // Without grant
- if (user.access & CREATE_ACL)
- user.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
+ user.hostname_length= (user.host.hostname ?
+ (uint) strlen(user.host.hostname) : 0);
+ if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
+ {
+ char *ssl_type=get_field(&mem, table, 24);
+ if (!ssl_type)
+ user.ssl_type=SSL_TYPE_NONE;
+ else if (!strcmp(ssl_type, "ANY"))
+ user.ssl_type=SSL_TYPE_ANY;
+ else if (!strcmp(ssl_type, "X509"))
+ user.ssl_type=SSL_TYPE_X509;
+ else /* !strcmp(ssl_type, "SPECIFIED") */
+ user.ssl_type=SSL_TYPE_SPECIFIED;
+
+ user.ssl_cipher= get_field(&mem, table, 25);
+ user.x509_issuer= get_field(&mem, table, 26);
+ user.x509_subject= get_field(&mem, table, 27);
+
+ char *ptr = get_field(&mem, table, 28);
+ user.user_resource.questions=atoi(ptr);
+ ptr = get_field(&mem, table, 29);
+ user.user_resource.updates=atoi(ptr);
+ ptr = get_field(&mem, table, 30);
+ user.user_resource.connections=atoi(ptr);
+ if (user.user_resource.questions || user.user_resource.updates ||
+ user.user_resource.connections)
+ mqh_used=1;
}
+ else
+ {
+ user.ssl_type=SSL_TYPE_NONE;
+ bzero((char *)&(user.user_resource),sizeof(user.user_resource));
+#ifndef TO_BE_REMOVED
+ if (table->fields <= 13)
+ { // Without grant
+ if (user.access & CREATE_ACL)
+ user.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
+ }
+ /* Convert old privileges */
+ user.access|= LOCK_TABLES_ACL | CREATE_TMP_ACL | SHOW_DB_ACL;
+ if (user.access & FILE_ACL)
+ user.access|= REPL_CLIENT_ACL | REPL_SLAVE_ACL;
+ if (user.access & PROCESS_ACL)
+ user.access|= SUPER_ACL | EXECUTE_ACL;
#endif
+ }
VOID(push_dynamic(&acl_users,(gptr) &user));
if (!user.host.hostname || user.host.hostname[0] == wild_many &&
!user.host.hostname[1])
@@ -267,11 +332,21 @@ int acl_init(bool dont_read_acl_tables)
init_check_host();
mysql_unlock_tables(thd, lock);
+ initialized=1;
thd->version--; // Force close to free memory
+ return_val=0;
+
+end:
close_thread_tables(thd);
delete thd;
- initialized=1;
- DBUG_RETURN(0);
+ if (org_thd)
+ org_thd->store_globals(); /* purecov: inspected */
+ else
+ {
+ /* Remember that we don't have a THD */
+ my_pthread_setspecific_ptr(THR_THD, 0);
+ }
+ DBUG_RETURN(return_val);
}
@@ -292,20 +367,27 @@ void acl_free(bool end)
}
}
- /* Reload acl list if possible */
-void acl_reload(void)
+/*
+ Forget current privileges and read new privileges from the privilege tables
+
+ SYNOPSIS
+ acl_reload()
+ thd Thread handle
+*/
+
+void acl_reload(THD *thd)
{
DYNAMIC_ARRAY old_acl_hosts,old_acl_users,old_acl_dbs;
MEM_ROOT old_mem;
bool old_initialized;
DBUG_ENTER("acl_reload");
- if (current_thd && current_thd->locked_tables)
+ if (thd && thd->locked_tables)
{ // Can't have locked tables here
- current_thd->lock=current_thd->locked_tables;
- current_thd->locked_tables=0;
- close_thread_tables(current_thd);
+ thd->lock=thd->locked_tables;
+ thd->locked_tables=0;
+ close_thread_tables(thd);
}
if ((old_initialized=initialized))
VOID(pthread_mutex_lock(&acl_cache->lock));
@@ -317,9 +399,9 @@ void acl_reload(void)
delete_dynamic(&acl_wild_hosts);
hash_free(&acl_check_hosts);
- if (acl_init(0))
+ if (acl_init(thd, 0))
{ // Error. Revert to old list
- acl_free(); /* purecov: inspected */
+ acl_free(); /* purecov: inspected */
acl_hosts=old_acl_hosts;
acl_users=old_acl_users;
acl_dbs=old_acl_dbs;
@@ -339,31 +421,38 @@ void acl_reload(void)
}
-/* Get all access bits from table after fieldnr */
+/*
+ Get all access bits from table after fieldnr
+ We know that the access privileges ends when there is no more fields
+ or the field is not an enum with two elements.
+*/
-static uint get_access(TABLE *form,uint fieldnr)
+static ulong get_access(TABLE *form, uint fieldnr)
{
- uint access_bits=0,bit;
+ ulong access_bits=0,bit;
char buff[2];
String res(buff,sizeof(buff));
Field **pos;
- for (pos=form->field+fieldnr,bit=1 ; *pos ; pos++ , bit<<=1)
+ for (pos=form->field+fieldnr, bit=1;
+ *pos && (*pos)->real_type() == FIELD_TYPE_ENUM &&
+ ((Field_enum*) (*pos))->typelib->count == 2 ;
+ pos++ , bit<<=1)
{
(*pos)->val_str(&res,&res);
if (toupper(res[0]) == 'Y')
- access_bits|=bit;
+ access_bits|= bit;
}
return access_bits;
}
/*
- return a number which, if sorted 'desc', puts strings in this order:
- no wildcards
- wildcards
- empty string
- */
+ Return a number which, if sorted 'desc', puts strings in this order:
+ no wildcards
+ wildcards
+ empty string
+*/
static ulong get_sort(uint count,...)
{
@@ -403,18 +492,26 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
}
-/* Get master privilges for user (priviliges for all tables) */
-
+/*
+ Get master privilges for user (priviliges for all tables).
+ Required before connecting to MySQL
+*/
-uint acl_getroot(const char *host, const char *ip, const char *user,
- const char *password,const char *message,char **priv_user,
- bool old_ver)
+ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
+ const char *password,const char *message,
+ char **priv_user, char *priv_host,
+ bool old_ver, USER_RESOURCES *mqh)
{
- uint user_access=NO_ACCESS;
+ ulong user_access=NO_ACCESS;
*priv_user=(char*) user;
+ DBUG_ENTER("acl_getroot");
+ bzero((char *)mqh,sizeof(USER_RESOURCES));
if (!initialized)
- return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */
+ {
+ // If no data allow anything
+ DBUG_RETURN((ulong) ~NO_ACCESS); /* purecov: tested */
+ }
VOID(pthread_mutex_lock(&acl_cache->lock));
/*
@@ -433,9 +530,126 @@ uint acl_getroot(const char *host, const char *ip, const char *user,
!check_scramble(password,message,acl_user->salt,
(my_bool) old_ver)))
{
- user_access=acl_user->access;
+ Vio *vio=thd->net.vio;
+#ifdef HAVE_OPENSSL
+ SSL *ssl= (SSL*) vio->ssl_arg;
+#endif
+ /*
+ In this point we know that user is allowed to connect
+ from given host by given username/password pair. Now
+ we check if SSL is required, if user is using SSL and
+ if X509 certificate attributes are OK
+ */
+ switch (acl_user->ssl_type) {
+ case SSL_TYPE_NOT_SPECIFIED: // Impossible
+ case SSL_TYPE_NONE: /* SSL is not required to connect */
+ user_access=acl_user->access;
+ break;
+#ifdef HAVE_OPENSSL
+ case SSL_TYPE_ANY: /* Any kind of SSL is good enough */
+ if (vio_type(vio) == VIO_TYPE_SSL)
+ user_access=acl_user->access;
+ break;
+ case SSL_TYPE_X509: /* Client should have any valid certificate. */
+ /*
+ We need to check for absence of SSL because without SSL
+ we should reject connection.
+ */
+ if (vio_type(vio) == VIO_TYPE_SSL &&
+ SSL_get_verify_result(ssl) == X509_V_OK &&
+ SSL_get_peer_certificate(ssl))
+ user_access=acl_user->access;
+ break;
+ case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */
+ /*
+ We need to check for absence of SSL because without SSL
+ we should reject connection.
+ */
+ if (vio_type(vio) == VIO_TYPE_SSL &&
+ SSL_get_verify_result(ssl) == X509_V_OK)
+ {
+ if (acl_user->ssl_cipher)
+ {
+ DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'",
+ acl_user->ssl_cipher,
+ SSL_get_cipher(ssl)));
+ if (!strcmp(acl_user->ssl_cipher,SSL_get_cipher(ssl)))
+ user_access=acl_user->access;
+ else
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_error("X509 ciphers mismatch: should be '%s' but is '%s'",
+ acl_user->ssl_cipher,
+ SSL_get_cipher(ssl));
+ user_access=NO_ACCESS;
+ break;
+ }
+ }
+ /* Prepare certificate (if exists) */
+ DBUG_PRINT("info",("checkpoint 1"));
+ X509* cert=SSL_get_peer_certificate(ssl);
+ if (!cert)
+ {
+ user_access=NO_ACCESS;
+ break;
+ }
+ DBUG_PRINT("info",("checkpoint 2"));
+ /* If X509 issuer is speified, we check it... */
+ if (acl_user->x509_issuer)
+ {
+ DBUG_PRINT("info",("checkpoint 3"));
+ char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
+ DBUG_PRINT("info",("comparing issuers: '%s' and '%s'",
+ acl_user->x509_issuer, ptr));
+ if (strcmp(acl_user->x509_issuer, ptr))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_error("X509 issuer mismatch: should be '%s' but is '%s'",
+ acl_user->x509_issuer, ptr);
+ user_access=NO_ACCESS;
+ free(ptr);
+ break;
+ }
+ user_access=acl_user->access;
+ free(ptr);
+ }
+ DBUG_PRINT("info",("checkpoint 4"));
+ /* X509 subject is specified, we check it .. */
+ if (acl_user->x509_subject)
+ {
+ char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
+ DBUG_PRINT("info",("comparing subjects: '%s' and '%s'",
+ acl_user->x509_subject, ptr));
+ if (strcmp(acl_user->x509_subject,ptr))
+ {
+ if (global_system_variables.log_warnings)
+ sql_print_error("X509 subject mismatch: '%s' vs '%s'",
+ acl_user->x509_subject, ptr);
+ user_access=NO_ACCESS;
+ }
+ else
+ user_access=acl_user->access;
+ free(ptr);
+ }
+ break;
+ }
+#else /* HAVE_OPENSSL */
+ default:
+ /*
+ If we don't have SSL but SSL is required for this user the
+ authentication should fail.
+ */
+ break;
+#endif /* HAVE_OPENSSL */
+ }
+
+ *mqh=acl_user->user_resource;
if (!acl_user->user)
*priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */
+ if (acl_user->host.hostname)
+ strmake(priv_host, acl_user->host.hostname, MAX_HOSTNAME);
+ else
+ *priv_host= 0;
break;
}
#ifndef ALLOW_DOWNGRADE_OF_USERS
@@ -445,7 +659,7 @@ uint acl_getroot(const char *host, const char *ip, const char *user,
}
}
VOID(pthread_mutex_unlock(&acl_cache->lock));
- return user_access;
+ DBUG_RETURN(user_access);
}
@@ -462,7 +676,13 @@ static byte* check_get_key(ACL_USER *buff,uint *length,
}
static void acl_update_user(const char *user, const char *host,
- const char *password, uint privileges)
+ const char *password,
+ enum SSL_type ssl_type,
+ const char *ssl_cipher,
+ const char *x509_issuer,
+ const char *x509_subject,
+ USER_RESOURCES *mqh,
+ ulong privileges)
{
for (uint i=0 ; i < acl_users.elements ; i++)
{
@@ -472,9 +692,26 @@ static void acl_update_user(const char *user, const char *host,
!strcmp(user,acl_user->user))
{
if (!acl_user->host.hostname && !host[0] ||
- acl_user->host.hostname && !strcmp(host,acl_user->host.hostname))
+ acl_user->host.hostname &&
+ !my_strcasecmp(host,acl_user->host.hostname))
{
acl_user->access=privileges;
+ if (mqh->bits & 1)
+ acl_user->user_resource.questions=mqh->questions;
+ if (mqh->bits & 2)
+ acl_user->user_resource.updates=mqh->updates;
+ if (mqh->bits & 4)
+ acl_user->user_resource.connections=mqh->connections;
+ if (ssl_type != SSL_TYPE_NOT_SPECIFIED)
+ {
+ acl_user->ssl_type= ssl_type;
+ acl_user->ssl_cipher= (ssl_cipher ? strdup_root(&mem,ssl_cipher) :
+ 0);
+ acl_user->x509_issuer= (x509_issuer ? strdup_root(&mem,x509_issuer) :
+ 0);
+ acl_user->x509_subject= (x509_subject ?
+ strdup_root(&mem,x509_subject) : 0);
+ }
if (password)
{
if (!password[0])
@@ -494,15 +731,26 @@ static void acl_update_user(const char *user, const char *host,
static void acl_insert_user(const char *user, const char *host,
const char *password,
- uint privileges)
+ enum SSL_type ssl_type,
+ const char *ssl_cipher,
+ const char *x509_issuer,
+ const char *x509_subject,
+ USER_RESOURCES *mqh,
+ ulong privileges)
{
ACL_USER acl_user;
- acl_user.user=strdup_root(&mem,user);
+ acl_user.user=*user ? strdup_root(&mem,user) : 0;
update_hostname(&acl_user.host,strdup_root(&mem,host));
acl_user.password=0;
acl_user.access=privileges;
+ acl_user.user_resource = *mqh;
acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user);
acl_user.hostname_length=(uint) strlen(acl_user.host.hostname);
+ acl_user.ssl_type= (ssl_type != SSL_TYPE_NOT_SPECIFIED ?
+ ssl_type : SSL_TYPE_NONE);
+ acl_user.ssl_cipher= ssl_cipher ? strdup_root(&mem,ssl_cipher) : 0;
+ acl_user.x509_issuer= x509_issuer ? strdup_root(&mem,x509_issuer) : 0;
+ acl_user.x509_subject=x509_subject ? strdup_root(&mem,x509_subject) : 0;
if (password)
{
acl_user.password=(char*) ""; // Just point at something
@@ -524,7 +772,7 @@ static void acl_insert_user(const char *user, const char *host,
static void acl_update_db(const char *user, const char *host, const char *db,
- uint privileges)
+ ulong privileges)
{
for (uint i=0 ; i < acl_dbs.elements ; i++)
{
@@ -534,7 +782,7 @@ static void acl_update_db(const char *user, const char *host, const char *db,
!strcmp(user,acl_db->user))
{
if (!acl_db->host.hostname && !host[0] ||
- acl_db->host.hostname && !strcmp(host,acl_db->host.hostname))
+ acl_db->host.hostname && !my_strcasecmp(host,acl_db->host.hostname))
{
if (!acl_db->db && !db[0] ||
acl_db->db && !strcmp(db,acl_db->db))
@@ -550,11 +798,25 @@ static void acl_update_db(const char *user, const char *host, const char *db,
}
+/*
+ Insert a user/db/host combination into the global acl_cache
+
+ SYNOPSIS
+ acl_insert_db()
+ user User name
+ host Host name
+ db Database name
+ privileges Bitmap of privileges
+
+ NOTES
+ acl_cache->lock must be locked when calling this
+*/
+
static void acl_insert_db(const char *user, const char *host, const char *db,
- uint privileges)
+ ulong privileges)
{
ACL_DB acl_db;
- /* The acl_cache mutex is locked by mysql_grant */
+ safe_mutex_assert_owner(&acl_cache->lock);
acl_db.user=strdup_root(&mem,user);
update_hostname(&acl_db.host,strdup_root(&mem,host));
acl_db.db=strdup_root(&mem,db);
@@ -566,21 +828,28 @@ static void acl_insert_db(const char *user, const char *host, const char *db,
}
-/*****************************************************************************
-** Get privilege for a host, user and db combination
-*****************************************************************************/
-uint acl_get(const char *host, const char *ip, const char *bin_ip,
+/*
+ Get privilege for a host, user and db combination
+*/
+
+ulong acl_get(const char *host, const char *ip, const char *bin_ip,
const char *user, const char *db)
{
- uint host_access,db_access,i,key_length;
+ ulong host_access,db_access;
+ uint i,key_length;
db_access=0; host_access= ~0;
- char key[ACL_KEY_LENGTH],*end;
+ char key[ACL_KEY_LENGTH],*tmp_db,*end;
acl_entry *entry;
VOID(pthread_mutex_lock(&acl_cache->lock));
memcpy_fixed(&key,bin_ip,sizeof(struct in_addr));
- end=strmov(strmov(key+sizeof(struct in_addr),user)+1,db);
+ end=strmov((tmp_db=strmov(key+sizeof(struct in_addr),user)+1),db);
+ if (lower_case_table_names)
+ {
+ casedn_str(tmp_db);
+ db=tmp_db;
+ }
key_length=(uint) (end-key);
if ((entry=(acl_entry*) acl_cache->search(key,key_length)))
{
@@ -646,7 +915,7 @@ int wild_case_compare(const char *str,const char *wildstr)
{
reg3 int flag;
DBUG_ENTER("wild_case_compare");
-
+ DBUG_PRINT("enter",("str: '%s' wildstr: '%s'",str,wildstr));
while (*wildstr)
{
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
@@ -658,7 +927,7 @@ int wild_case_compare(const char *str,const char *wildstr)
if (! *wildstr ) DBUG_RETURN (*str != 0);
if (*wildstr++ == wild_one)
{
- if (! *str++) DBUG_RETURN (1); /* One char; skipp */
+ if (! *str++) DBUG_RETURN (1); /* One char; skip */
}
else
{ /* Found '*' */
@@ -684,11 +953,14 @@ int wild_case_compare(const char *str,const char *wildstr)
DBUG_RETURN (*str != '\0');
}
-/*****************************************************************************
-** check if there are any possible matching entries for this host
-** All host names without wild cards are stored in a hash table,
-** entries with wildcards are stored in a dynamic array
-*****************************************************************************/
+
+/*
+ Check if there are any possible matching entries for this host
+
+ NOTES
+ All host names without wild cards are stored in a hash table,
+ entries with wildcards are stored in a dynamic array
+*/
static void init_check_host(void)
{
@@ -761,45 +1033,78 @@ bool acl_check_host(const char *host, const char *ip)
return 1; // Host is not allowed
}
-/*****************************************************************************
-** Change password for the user if it's not an anonymous user
-** Note: This should write the error directly to the client!
-*****************************************************************************/
-bool change_password(THD *thd, const char *host, const char *user,
- char *new_password)
+/*
+ Check if the user is allowed to change password
+
+ SYNOPSIS:
+ check_change_password()
+ thd THD
+ host hostname for the user
+ user user name
+
+ RETURN VALUE
+ 0 OK
+ 1 ERROR ; In this case the error is sent to the client.
+*/
+
+bool check_change_password(THD *thd, const char *host, const char *user)
{
- uint length=0;
if (!initialized)
{
send_error(&thd->net, ER_PASSWORD_NOT_ALLOWED); /* purecov: inspected */
- return 1; /* purecov: inspected */
+ return(1); /* purecov: inspected */
}
- if (!host)
- host=thd->ip; /* purecov: tested */
- /* password should always be 0 or 16 chars; simple hack to avoid cracking */
- length=(uint) strlen(new_password);
- new_password[length & 16]=0;
-
if (!thd->slave_thread &&
(strcmp(thd->user,user) ||
- my_strcasecmp(host,thd->host ? thd->host : thd->ip)))
+ my_strcasecmp(host,thd->host_or_ip)))
{
if (check_access(thd, UPDATE_ACL, "mysql",0,1))
- return 1;
+ return(1);
}
if (!thd->slave_thread && !thd->user[0])
{
send_error(&thd->net, ER_PASSWORD_ANONYMOUS_USER);
- return 1;
+ return(1);
}
+ return(0);
+}
+
+
+/*
+ Change a password for a user
+
+ SYNOPSIS
+ change_password()
+ thd Thread handle
+ host Hostname
+ user User name
+ new_password New password for host@user
+
+ RETURN VALUES
+ 0 ok
+ 1 ERROR; In this case the error is sent to the client.
+*/
+
+bool change_password(THD *thd, const char *host, const char *user,
+ char *new_password)
+{
+ uint length=0;
+ DBUG_ENTER("change_password");
+ DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'",
+ host,user,new_password));
+ DBUG_ASSERT(host != 0); // Ensured by parent
+
+ length=(uint) strlen(new_password);
+ new_password[length & 16]=0;
+
VOID(pthread_mutex_lock(&acl_cache->lock));
ACL_USER *acl_user;
if (!(acl_user= find_acl_user(host,user)))
{
send_error(&thd->net, ER_PASSWORD_NO_MATCH);
VOID(pthread_mutex_unlock(&acl_cache->lock));
- return 1;
+ DBUG_RETURN(1);
}
if (update_user_table(thd,
acl_user->host.hostname ? acl_user->host.hostname : "",
@@ -808,7 +1113,7 @@ bool change_password(THD *thd, const char *host, const char *user,
{
VOID(pthread_mutex_unlock(&acl_cache->lock)); /* purecov: deadcode */
send_error(&thd->net,0); /* purecov: deadcode */
- return 1; /* purecov: deadcode */
+ DBUG_RETURN(1); /* purecov: deadcode */
}
get_salt_from_password(acl_user->salt,new_password);
if (!new_password[0])
@@ -819,17 +1124,17 @@ bool change_password(THD *thd, const char *host, const char *user,
VOID(pthread_mutex_unlock(&acl_cache->lock));
char buff[460];
-
- Query_log_event qinfo(thd, buff);
- qinfo.q_len =
+ ulong query_length=
my_sprintf(buff,
(buff,"SET PASSWORD FOR \"%-.120s\"@\"%-.120s\"=\"%-.120s\"",
acl_user->user ? acl_user->user : "",
acl_user->host.hostname ? acl_user->host.hostname : "",
new_password));
- mysql_update_log.write(thd,buff,qinfo.q_len);
+ thd->clear_error();
+ mysql_update_log.write(thd, buff, query_length);
+ Query_log_event qinfo(thd, buff, query_length, 0);
mysql_bin_log.write(&qinfo);
- return 0;
+ DBUG_RETURN(0);
}
@@ -840,28 +1145,41 @@ bool change_password(THD *thd, const char *host, const char *user,
static ACL_USER *
find_acl_user(const char *host, const char *user)
{
+ DBUG_ENTER("find_acl_user");
+ DBUG_PRINT("enter",("host: '%s' user: '%s'",host,user));
for (uint i=0 ; i < acl_users.elements ; i++)
{
ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*);
+ DBUG_PRINT("info",("strcmp('%s','%s'), compare_hostname('%s','%s'),",
+ user,
+ acl_user->user ? acl_user->user : "",
+ host,
+ acl_user->host.hostname ? acl_user->host.hostname :
+ ""));
if (!acl_user->user && !user[0] ||
acl_user->user && !strcmp(user,acl_user->user))
{
- if (compare_hostname(&acl_user->host,host,host))
- return acl_user;
+ if (compare_hostname(&(acl_user->host),host,host))
+ {
+ DBUG_RETURN(acl_user);
+ }
}
}
- return 0;
+ DBUG_RETURN(0);
}
-/*****************************************************************************
- Handle comparing of hostname
- A hostname may be of type:
- hostname (May include wildcards); monty.pp.sci.fi
- ip (May include wildcards); 192.168.0.0
- ip/netmask 192.168.0.0/255.255.255.0
- A net mask of 0.0.0.0 is not allowed.
-*****************************************************************************/
+/*
+ Comparing of hostnames
+
+ NOTES
+ A hostname may be of type:
+ hostname (May include wildcards); monty.pp.sci.fi
+ ip (May include wildcards); 192.168.0.0
+ ip/netmask 192.168.0.0/255.255.255.0
+
+ A net mask of 0.0.0.0 is not allowed.
+*/
static const char *calc_ip(const char *ip, long *val, char end)
{
@@ -885,11 +1203,11 @@ static const char *calc_ip(const char *ip, long *val, char end)
static void update_hostname(acl_host_and_ip *host, const char *hostname)
{
host->hostname=(char*) hostname; // This will not be modified!
- if (hostname &&
+ if (!hostname ||
(!(hostname=calc_ip(hostname,&host->ip,'/')) ||
!(hostname=calc_ip(hostname+1,&host->ip_mask,'\0'))))
{
- host->ip=host->ip_mask=0; // Not a masked ip
+ host->ip= host->ip_mask=0; // Not a masked ip
}
}
@@ -908,9 +1226,9 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
}
-/****************************************************************************
-** Code to update grants in the user and database privilege tables
-****************************************************************************/
+/*
+ Update grants in the user and database privilege tables
+*/
static bool update_user_table(THD *thd, const char *host, const char *user,
const char *new_password)
@@ -924,6 +1242,24 @@ static bool update_user_table(THD *thd, const char *host, const char *user,
bzero((char*) &tables,sizeof(tables));
tables.alias=tables.real_name=(char*) "user";
tables.db=(char*) "mysql";
+#ifdef HAVE_REPLICATION
+ /*
+ GRANT and REVOKE are applied the slave in/exclusion rules as they are
+ some kind of updates to the mysql.% tables.
+ */
+ if (thd->slave_thread && table_rules_on)
+ {
+ /*
+ The tables must be marked "updating" so that tables_ok() takes them into
+ account in tests. It's ok to leave 'updating' set after tables_ok.
+ */
+ tables.updating= 1;
+ /* Thanks to bzero, tables.next==0 */
+ if (!tables_ok(0, &tables))
+ DBUG_RETURN(0);
+ }
+#endif
+
if (!(table=open_ltable(thd,&tables,TL_WRITE)))
DBUG_RETURN(1); /* purecov: deadcode */
table->field[0]->store(host,(uint) strlen(host));
@@ -959,10 +1295,10 @@ static bool test_if_create_new_users(THD *thd)
if (opt_safe_user_create && !(thd->master_access & INSERT_ACL))
{
TABLE_LIST tl;
- uint db_access;
+ ulong db_access;
bzero((char*) &tl,sizeof(tl));
tl.db= (char*) "mysql";
- tl.real_name= (char*) "user";
+ tl.real_name= (char*) "user";
db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, tl.db);
if (!(db_access & INSERT_ACL))
@@ -976,17 +1312,19 @@ static bool test_if_create_new_users(THD *thd)
/****************************************************************************
-** Handle GRANT commands
+ Handle GRANT commands
****************************************************************************/
-static int replace_user_table(TABLE *table, const LEX_USER &combo,
- uint rights, char what, bool create_user)
+static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
+ ulong rights, bool revoke_grant,
+ bool create_user)
{
int error = -1;
- uint i,j;
bool old_row_exists=0;
char *password,empty_string[1];
+ char what= (revoke_grant) ? 'N' : 'Y';
DBUG_ENTER("replace_user_table");
+ safe_mutex_assert_owner(&acl_cache->lock);
password=empty_string;
empty_string[0]=0;
@@ -996,8 +1334,8 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
if (combo.password.length != HASH_PASSWORD_LENGTH)
{
my_printf_error(ER_PASSWORD_NO_MATCH,
- "Password hash should be a %d-digit hexadecimal number",
- MYF(0),HASH_PASSWORD_LENGTH);
+ "Password hash should be a %d-digit hexadecimal number",
+ MYF(0),HASH_PASSWORD_LENGTH);
DBUG_RETURN(-1);
}
password=combo.password.str;
@@ -1012,7 +1350,6 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
{
if (!create_user)
{
- THD *thd=current_thd;
if (what == 'N')
my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
MYF(0),combo.user.str,combo.host.str);
@@ -1020,7 +1357,7 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
my_printf_error(ER_NO_PERMISSION_TO_CREATE_USER,
ER(ER_NO_PERMISSION_TO_CREATE_USER),
MYF(0),thd->user,
- thd->host ? thd->host : thd->ip ? thd->ip: "");
+ thd->host_or_ip);
error= -1;
goto end;
}
@@ -1038,15 +1375,70 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
table->field[2]->store(password,(uint) strlen(password));
}
- for (i = 3, j = SELECT_ACL; // starting from reload
- i < table->fields;
- i++, j <<= 1)
+ /* Update table columns with new privileges */
+
+ Field **tmp_field;
+ ulong priv;
+ for (tmp_field= table->field+3, priv = SELECT_ACL;
+ *tmp_field && (*tmp_field)->real_type() == FIELD_TYPE_ENUM &&
+ ((Field_enum*) (*tmp_field))->typelib->count == 2 ;
+ tmp_field++, priv <<= 1)
{
- if (j & rights) // set requested privileges
- table->field[i]->store(&what,1);
+ if (priv & rights) // set requested privileges
+ (*tmp_field)->store(&what,1);
}
rights=get_access(table,3);
+ DBUG_PRINT("info",("table->fields: %d",table->fields));
+ if (table->fields >= 31) /* From 4.0.0 we have more fields */
+ {
+ /* We write down SSL related ACL stuff */
+ switch (thd->lex.ssl_type) {
+ case SSL_TYPE_ANY:
+ table->field[24]->store("ANY",3);
+ table->field[25]->store("",0);
+ table->field[26]->store("",0);
+ table->field[27]->store("",0);
+ break;
+ case SSL_TYPE_X509:
+ table->field[24]->store("X509",4);
+ table->field[25]->store("",0);
+ table->field[26]->store("",0);
+ table->field[27]->store("",0);
+ break;
+ case SSL_TYPE_SPECIFIED:
+ table->field[24]->store("SPECIFIED",9);
+ table->field[25]->store("",0);
+ table->field[26]->store("",0);
+ table->field[27]->store("",0);
+ if (thd->lex.ssl_cipher)
+ table->field[25]->store(thd->lex.ssl_cipher,
+ strlen(thd->lex.ssl_cipher));
+ if (thd->lex.x509_issuer)
+ table->field[26]->store(thd->lex.x509_issuer,
+ strlen(thd->lex.x509_issuer));
+ if (thd->lex.x509_subject)
+ table->field[27]->store(thd->lex.x509_subject,
+ strlen(thd->lex.x509_subject));
+ break;
+ case SSL_TYPE_NOT_SPECIFIED:
+ break;
+ case SSL_TYPE_NONE:
+ table->field[24]->store("",0);
+ table->field[25]->store("",0);
+ table->field[26]->store("",0);
+ table->field[27]->store("",0);
+ break;
+ }
+ USER_RESOURCES mqh = thd->lex.mqh;
+ if (mqh.bits & 1)
+ table->field[28]->store((longlong) mqh.questions);
+ if (mqh.bits & 2)
+ table->field[29]->store((longlong) mqh.updates);
+ if (mqh.bits & 4)
+ table->field[30]->store((longlong) mqh.connections);
+ mqh_used = mqh_used || mqh.questions || mqh.updates || mqh.connections;
+ }
if (old_row_exists)
{
/*
@@ -1073,16 +1465,28 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
}
error=0; // Privileges granted / revoked
- end:
+end:
if (!error)
{
acl_cache->clear(1); // Clear privilege cache
if (!combo.password.str)
password=0; // No password given on command
if (old_row_exists)
- acl_update_user(combo.user.str,combo.host.str,password,rights);
+ acl_update_user(combo.user.str,combo.host.str,password,
+ thd->lex.ssl_type,
+ thd->lex.ssl_cipher,
+ thd->lex.x509_issuer,
+ thd->lex.x509_subject,
+ &thd->lex.mqh,
+ rights);
else
- acl_insert_user(combo.user.str,combo.host.str,password,rights);
+ acl_insert_user(combo.user.str,combo.host.str,password,
+ thd->lex.ssl_type,
+ thd->lex.ssl_cipher,
+ thd->lex.x509_issuer,
+ thd->lex.x509_subject,
+ &thd->lex.mqh,
+ rights);
}
table->file->index_end();
DBUG_RETURN(error);
@@ -1090,19 +1494,21 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
/*
-** change grants in the mysql.db table
+ change grants in the mysql.db table
*/
static int replace_db_table(TABLE *table, const char *db,
const LEX_USER &combo,
- uint rights, char what)
+ ulong rights, bool revoke_grant)
{
- uint i,j,store_rights;
+ uint i;
+ ulong priv,store_rights;
bool old_row_exists=0;
int error;
+ char what= (revoke_grant) ? 'N' : 'Y';
DBUG_ENTER("replace_db_table");
- // is there such a user in user table in memory ????
+ /* Check if there is such a user in user table in memory? */
if (!initialized || !find_acl_user(combo.host.str,combo.user.str))
{
my_error(ER_PASSWORD_NO_MATCH,MYF(0));
@@ -1114,7 +1520,7 @@ static int replace_db_table(TABLE *table, const char *db,
table->field[2]->store(combo.user.str,combo.user.length);
table->file->index_init(0);
if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,0,
- HA_READ_KEY_EXACT))
+ HA_READ_KEY_EXACT))
{
if (what == 'N')
{ // no row, no revoke
@@ -1135,9 +1541,9 @@ static int replace_db_table(TABLE *table, const char *db,
}
store_rights=get_rights_for_db(rights);
- for (i = 3, j = 1; i < table->fields; i++, j <<= 1)
+ for (i= 3, priv= 1; i < table->fields; i++, priv <<= 1)
{
- if (j & store_rights) // do it if priv is chosen
+ if (priv & store_rights) // do it if priv is chosen
table->field [i]->store(&what,1); // set requested privileges
}
rights=get_access(table,3);
@@ -1145,7 +1551,7 @@ static int replace_db_table(TABLE *table, const char *db,
if (old_row_exists)
{
- // update old existing row
+ /* update old existing row */
if (rights)
{
if ((error=table->file->update_row(table->record[1],table->record[0])))
@@ -1172,11 +1578,11 @@ static int replace_db_table(TABLE *table, const char *db,
DBUG_RETURN(0);
/* This could only happen if the grant tables got corrupted */
- table_error:
+table_error:
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
table->file->index_end();
- abort:
+abort:
DBUG_RETURN(-1);
}
@@ -1185,13 +1591,15 @@ class GRANT_COLUMN :public Sql_alloc
{
public:
char *column;
- uint rights, key_length;
- GRANT_COLUMN(String &c, uint y) :rights (y)
+ ulong rights;
+ uint key_length;
+ GRANT_COLUMN(String &c, ulong y) :rights (y)
{
- column= memdup_root(&memex,c.ptr(),key_length=c.length());
+ column= memdup_root(&memex,c.ptr(), key_length=c.length());
}
};
+
static byte* get_key_column(GRANT_COLUMN *buff,uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -1199,15 +1607,17 @@ static byte* get_key_column(GRANT_COLUMN *buff,uint *length,
return (byte*) buff->column;
}
+
class GRANT_TABLE :public Sql_alloc
{
public:
char *host,*db,*user,*tname, *hash_key;
- uint privs, cols, key_length;
+ ulong privs, cols;
ulong sort;
+ uint key_length;
HASH hash_columns;
GRANT_TABLE (const char *h, const char *d,const char *u, const char *t,
- uint p,uint c)
+ ulong p, ulong c)
: privs(p), cols(c)
{
host = strdup_root(&memex,h);
@@ -1215,6 +1625,11 @@ public:
user = strdup_root(&memex,u);
sort= get_sort(3,host,db,user);
tname= strdup_root(&memex,t);
+ if (lower_case_table_names)
+ {
+ casedn_str(db);
+ casedn_str(tname);
+ }
key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3;
hash_key = (char*) alloc_root(&memex,key_length);
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
@@ -1228,7 +1643,9 @@ public:
host = get_field(&memex,form,0);
db = get_field(&memex,form,1);
- user = get_field(&memex,form,2); if (!user) user=(char*) "";
+ user = get_field(&memex,form,2);
+ if (!user)
+ user=(char*) "";
sort= get_sort(3,host,db,user);
tname = get_field(&memex,form,3);
if (!host || !db || !tname)
@@ -1237,11 +1654,17 @@ public:
privs = cols = 0; /* purecov: inspected */
return; /* purecov: inspected */
}
- key_length = (uint) strlen(db) + (uint) strlen(user) + (uint) strlen (tname) + 3;
+ if (lower_case_table_names)
+ {
+ casedn_str(db);
+ casedn_str(tname);
+ }
+ key_length = ((uint) strlen(db) + (uint) strlen(user) +
+ (uint) strlen(tname) + 3);
hash_key = (char*) alloc_root(&memex,key_length);
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
- privs = (uint) form->field[6]->val_int();
- cols = (uint) form->field[7]->val_int();
+ privs = (ulong) form->field[6]->val_int();
+ cols = (ulong) form->field[7]->val_int();
privs = fix_rights_for_table(privs);
cols = fix_rights_for_column(cols);
@@ -1274,11 +1697,11 @@ public:
GRANT_COLUMN *mem_check;
/* As column name is a string, we don't have to supply a buffer */
res=col_privs->field[4]->val_str(&column_name,&column_name);
- uint priv= (uint) col_privs->field[6]->val_int();
+ ulong priv= (ulong) col_privs->field[6]->val_int();
if (!(mem_check = new GRANT_COLUMN(*res,
fix_rights_for_column(priv))))
{
- // Don't use this entry
+ /* Don't use this entry */
privs = cols = 0; /* purecov: deadcode */
return; /* purecov: deadcode */
}
@@ -1290,6 +1713,7 @@ public:
bool ok() { return privs != 0 || cols != 0; }
};
+
static byte* get_grant_table(GRANT_TABLE *buff,uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -1297,11 +1721,13 @@ static byte* get_grant_table(GRANT_TABLE *buff,uint *length,
return (byte*) buff->hash_key;
}
+
void free_grant_table(GRANT_TABLE *grant_table)
{
hash_free(&grant_table->hash_columns);
}
+
/* Search after a matching grant. Prefer exact grants before not exact ones */
static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
@@ -1312,6 +1738,7 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
char helping [NAME_LEN*2+USERNAME_LENGTH+3];
uint len;
GRANT_TABLE *grant_table,*found=0;
+ safe_mutex_assert_owner(&LOCK_grant);
len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1;
for (grant_table=(GRANT_TABLE*) hash_search(&hash_tables,(byte*) helping,
@@ -1321,7 +1748,7 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
{
if (exact)
{
- if ((host && !strcmp(host,grant_table->host)) ||
+ if ((host && !my_strcasecmp(host,grant_table->host)) ||
(ip && !strcmp(ip,grant_table->host)))
return grant_table;
}
@@ -1339,8 +1766,7 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
inline GRANT_COLUMN *
-column_hash_search(GRANT_TABLE *t, const char *cname,
- uint length)
+column_hash_search(GRANT_TABLE *t, const char *cname, uint length)
{
return (GRANT_COLUMN*) hash_search(&t->hash_columns, (byte*) cname,length);
}
@@ -1350,7 +1776,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
TABLE *table, const LEX_USER &combo,
List <LEX_COLUMN> &columns,
const char *db, const char *table_name,
- uint rights, bool revoke_grant)
+ ulong rights, bool revoke_grant)
{
int error=0,result=0;
uint key_length;
@@ -1374,7 +1800,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
table->file->index_init(0);
while ((xx=iter++))
{
- uint privileges = xx->rights;
+ ulong privileges = xx->rights;
bool old_row_exists=0;
key_restore(table,key,0,key_length);
table->field[4]->store(xx->column.ptr(),xx->column.length());
@@ -1397,7 +1823,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
}
else
{
- uint tmp= (uint) table->field[6]->val_int();
+ ulong tmp= (ulong) table->field[6]->val_int();
tmp=fix_rights_for_column(tmp);
if (revoke_grant)
@@ -1454,10 +1880,10 @@ static int replace_column_table(GRANT_TABLE *g_t,
key_length, HA_READ_KEY_EXACT))
goto end;
- // Scan trough all rows with the same host,db,user and table
+ /* Scan through all rows with the same host,db,user and table */
do
{
- uint privileges = (uint) table->field[6]->val_int();
+ ulong privileges = (ulong) table->field[6]->val_int();
privileges=fix_rights_for_column(privileges);
store_record(table,1);
@@ -1504,7 +1930,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
!key_cmp(table,key,0,key_length));
}
- end:
+end:
table->file->index_end();
DBUG_RETURN(result);
}
@@ -1513,19 +1939,22 @@ static int replace_column_table(GRANT_TABLE *g_t,
static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
TABLE *table, const LEX_USER &combo,
const char *db, const char *table_name,
- uint rights, uint kolone, bool revoke_grant)
+ ulong rights, ulong col_rights,
+ bool revoke_grant)
{
- char grantor[HOSTNAME_LENGTH+1+USERNAME_LENGTH];
+ char grantor[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
int old_row_exists = 1;
int error=0;
- uint store_table_rights,store_col_rights;
+ ulong store_table_rights, store_col_rights;
DBUG_ENTER("replace_table_table");
+ safe_mutex_assert_owner(&LOCK_grant);
- strxmov(grantor,thd->user,"@",thd->host ? thd->host : thd->ip ? thd->ip :"",
- NullS);
+ strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS);
- // The following should always succeed as new users are created before
- // this function is called!
+ /*
+ The following should always succeed as new users are created before
+ this function is called!
+ */
if (!find_acl_user(combo.host.str,combo.user.str))
{
my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */
@@ -1560,24 +1989,24 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
restore_record(table,1); // Get saved record
}
- store_table_rights=get_rights_for_table(rights);
- store_col_rights=get_rights_for_column(kolone);
+ store_table_rights= get_rights_for_table(rights);
+ store_col_rights= get_rights_for_column(col_rights);
if (old_row_exists)
{
- uint j,k;
+ ulong j,k;
store_record(table,1);
- j = (uint) table->field[6]->val_int();
- k = (uint) table->field[7]->val_int();
+ j = (ulong) table->field[6]->val_int();
+ k = (ulong) table->field[7]->val_int();
if (revoke_grant)
{
- // column rights are already fixed in mysql_table_grant !
+ /* column rights are already fixed in mysql_table_grant */
store_table_rights=j & ~store_table_rights;
}
else
{
- store_table_rights|=j;
- store_col_rights|=k;
+ store_table_rights|= j;
+ store_col_rights|= k;
}
}
@@ -1585,7 +2014,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
table->field[6]->store((longlong) store_table_rights);
table->field[7]->store((longlong) store_col_rights);
rights=fix_rights_for_table(store_table_rights);
- kolone=fix_rights_for_column(store_col_rights);
+ col_rights=fix_rights_for_column(store_col_rights);
if (old_row_exists)
{
@@ -1604,10 +2033,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
goto table_error; /* purecov: deadcode */
}
- if (rights | kolone)
+ if (rights | col_rights)
{
- grant_table->privs = rights;
- grant_table->cols = kolone;
+ grant_table->privs= rights;
+ grant_table->cols= col_rights;
}
else
{
@@ -1615,19 +2044,36 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
}
DBUG_RETURN(0);
- /* This should never happen */
- table_error:
+ /* This should never happen */
+table_error:
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
DBUG_RETURN(-1); /* purecov: deadcode */
}
-int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
- List <LEX_USER> &user_list,
- List <LEX_COLUMN> &columns, uint rights,
- bool revoke_grant)
+/*
+ Store table level and column level grants in the privilege tables
+
+ SYNOPSIS
+ mysql_table_grant()
+ thd Thread handle
+ table_list List of tables to give grant
+ user_list List of users to give grant
+ columns List of columns to give grant
+ rights Table level grant
+ revoke_grant Set to 1 if this is a REVOKE command
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
+ List <LEX_USER> &user_list,
+ List <LEX_COLUMN> &columns, ulong rights,
+ bool revoke_grant)
{
- uint column_priv = 0;
+ ulong column_priv= 0;
List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str;
TABLE_LIST tables[3];
@@ -1648,33 +2094,33 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
if (columns.elements && !revoke_grant)
{
TABLE *table;
- class LEX_COLUMN *check;
- List_iterator <LEX_COLUMN> iter(columns);
+ class LEX_COLUMN *column;
+ List_iterator <LEX_COLUMN> column_iter(columns);
if (!(table=open_ltable(thd,table_list,TL_READ)))
DBUG_RETURN(-1);
- while ((check = iter++))
+ while ((column = column_iter++))
{
- if (!find_field_in_table(thd,table,check->column.ptr(),
- check->column.length(),0,0))
+ if (!find_field_in_table(thd,table,column->column.ptr(),
+ column->column.length(),0,0))
{
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
- check->column.c_ptr(),table_list->alias);
+ column->column.c_ptr(), table_list->alias);
DBUG_RETURN(-1);
}
- column_priv |= check->rights | (rights & COL_ACLS);
+ column_priv|= column->rights;
}
close_thread_tables(thd);
}
else if (!(rights & CREATE_ACL) && !revoke_grant)
{
char buf[FN_REFLEN];
- sprintf(buf,"%s/%s/%s.frm",mysql_data_home,table_list->db,
+ sprintf(buf,"%s/%s/%s.frm",mysql_data_home, table_list->db,
table_list->real_name);
fn_format(buf,buf,"","",4+16+32);
if (access(buf,F_OK))
{
- my_error(ER_NO_SUCH_TABLE,MYF(0),table_list->db,table_list->real_name);
+ my_error(ER_NO_SUCH_TABLE,MYF(0),table_list->db, table_list->alias);
DBUG_RETURN(-1);
}
}
@@ -1693,6 +2139,23 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_WRITE;
tables[0].db=tables[1].db=tables[2].db=(char*) "mysql";
+#ifdef HAVE_REPLICATION
+ /*
+ GRANT and REVOKE are applied the slave in/exclusion rules as they are
+ some kind of updates to the mysql.% tables.
+ */
+ if (thd->slave_thread && table_rules_on)
+ {
+ /*
+ The tables must be marked "updating" so that tables_ok() takes them into
+ account in tests.
+ */
+ tables[0].updating= tables[1].updating= tables[2].updating= 1;
+ if (!tables_ok(0, tables))
+ DBUG_RETURN(0);
+ }
+#endif
+
if (open_and_lock_tables(thd,tables))
{ // Should never happen
close_thread_tables(thd); /* purecov: deadcode */
@@ -1724,11 +2187,8 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
}
/* Create user if needed */
pthread_mutex_lock(&acl_cache->lock);
- error=replace_user_table(tables[0].table,
- *Str,
- 0,
- revoke_grant ? 'N' : 'Y',
- create_new_users);
+ error=replace_user_table(thd, tables[0].table, *Str,
+ 0, revoke_grant, create_new_users);
pthread_mutex_unlock(&acl_cache->lock);
if (error)
{
@@ -1766,21 +2226,21 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
/* If revoke_grant, calculate the new column privilege for tables_priv */
if (revoke_grant)
{
- class LEX_COLUMN *check;
- List_iterator <LEX_COLUMN> iter(columns);
+ class LEX_COLUMN *column;
+ List_iterator <LEX_COLUMN> column_iter(columns);
GRANT_COLUMN *grant_column;
/* Fix old grants */
- while ((check = iter++))
+ while ((column = column_iter++))
{
grant_column = column_hash_search(grant_table,
- check->column.ptr(),
- check->column.length());
+ column->column.ptr(),
+ column->column.length());
if (grant_column)
- grant_column->rights&= ~(check->rights | rights);
+ grant_column->rights&= ~(column->rights | rights);
}
/* scan trough all columns to get new column grant */
- column_priv=0;
+ column_priv= 0;
for (uint idx=0 ; idx < grant_table->hash_columns.records ; idx++)
{
grant_column= (GRANT_COLUMN*) hash_element(&grant_table->hash_columns,
@@ -1821,17 +2281,17 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
pthread_mutex_unlock(&LOCK_grant);
if (!result)
send_ok(&thd->net);
- /* Tables are automaticly closed */
+ /* Tables are automatically closed */
DBUG_RETURN(result);
}
-int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
- bool revoke_grant)
+int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
+ ulong rights, bool revoke_grant)
{
List_iterator <LEX_USER> str_list (list);
LEX_USER *Str;
- char what;
+ char tmp_db[NAME_LEN+1];
bool create_new_users=0;
TABLE_LIST tables[2];
DBUG_ENTER("mysql_grant");
@@ -1839,10 +2299,15 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
if (!initialized)
{
send_error(&(thd->net), ER_UNKNOWN_COM_ERROR); /* purecov: tested */
- return 1; /* purecov: tested */
+ DBUG_RETURN(1); /* purecov: tested */
}
- what = (revoke_grant) ? 'N' : 'Y';
+ if (lower_case_table_names && db)
+ {
+ strmov(tmp_db,db);
+ casedn_str(tmp_db);
+ db=tmp_db;
+ }
/* open the mysql.user and mysql.db tables */
@@ -1853,6 +2318,24 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
tables[0].lock_type=tables[1].lock_type=TL_WRITE;
tables[0].db=tables[1].db=(char*) "mysql";
tables[0].table=tables[1].table=0;
+
+#ifdef HAVE_REPLICATION
+ /*
+ GRANT and REVOKE are applied the slave in/exclusion rules as they are
+ some kind of updates to the mysql.% tables.
+ */
+ if (thd->slave_thread && table_rules_on)
+ {
+ /*
+ The tables must be marked "updating" so that tables_ok() takes them into
+ account in tests.
+ */
+ tables[0].updating= tables[1].updating= 1;
+ if (!tables_ok(0, tables))
+ DBUG_RETURN(0);
+ }
+#endif
+
if (open_and_lock_tables(thd,tables))
{ // This should never happen
close_thread_tables(thd); /* purecov: deadcode */
@@ -1862,7 +2345,7 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
if (!revoke_grant)
create_new_users= test_if_create_new_users(thd);
- // go through users in user_list
+ /* go through users in user_list */
pthread_mutex_lock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
grant_version++;
@@ -1882,15 +2365,26 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
result= -1;
continue;
}
- if ((replace_user_table(tables[0].table,
+ if ((replace_user_table(thd,
+ tables[0].table,
*Str,
- (!db ? rights : 0), what, create_new_users)))
+ (!db ? rights : 0), revoke_grant,
+ create_new_users)))
result= -1;
- else
+ else if (db)
{
- if (db && replace_db_table(tables[1].table, db, *Str, rights & DB_ACLS,
- what))
- result= -1;
+ ulong db_rights= rights & DB_ACLS;
+ if (db_rights == rights)
+ {
+ if (replace_db_table(tables[1].table, db, *Str, db_rights,
+ revoke_grant))
+ result= -1;
+ }
+ else
+ {
+ net_printf(&thd->net,ER_WRONG_USAGE,"DB GRANT","GLOBAL PRIVILEGES");
+ result= 1;
+ }
}
}
VOID(pthread_mutex_unlock(&acl_cache->lock));
@@ -1902,7 +2396,8 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
DBUG_RETURN(result);
}
- /* Free grant array if possible */
+
+/* Free grant array if possible */
void grant_free(void)
{
@@ -1916,29 +2411,29 @@ void grant_free(void)
/* Init grant array if possible */
-int grant_init (void)
+my_bool grant_init(THD *org_thd)
{
THD *thd;
TABLE_LIST tables[2];
- int error = 0;
+ MYSQL_LOCK *lock;
+ my_bool return_val= 1;
TABLE *t_table, *c_table;
DBUG_ENTER("grant_init");
grant_option = FALSE;
(void) hash_init(&hash_tables,0,0,0, (hash_get_key) get_grant_table,
(hash_free_key) free_grant_table,0);
- init_sql_alloc(&memex,1024,0);
+ init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0);
+ /* Don't do anything if running with --skip-grant */
if (!initialized)
DBUG_RETURN(0); /* purecov: tested */
+
if (!(thd=new THD))
DBUG_RETURN(1); /* purecov: deadcode */
-
- thd->version=refresh_version;
- thd->mysys_var=my_thread_var;
- thd->current_tablenr=0;
- thd->open_tables=0;
- thd->db=my_strdup("mysql",MYF(0));
+ thd->store_globals();
+ thd->db= my_strdup("mysql",MYF(0));
+ thd->db_length=5; // Safety
bzero((char*) &tables,sizeof(tables));
tables[0].alias=tables[0].real_name= (char*) "tables_priv";
tables[1].alias=tables[1].real_name= (char*) "columns_priv";
@@ -1947,84 +2442,89 @@ int grant_init (void)
tables[0].db=tables[1].db=thd->db;
if (open_tables(thd,tables))
- { // No grant tables
- close_thread_tables(thd); /* purecov: deadcode */
- delete thd; /* purecov: deadcode */
- DBUG_RETURN(1); /* purecov: deadcode */
- }
+ goto end;
+
TABLE *ptr[2]; // Lock tables for quick update
ptr[0]= tables[0].table;
ptr[1]= tables[1].table;
- MYSQL_LOCK *lock=mysql_lock_tables(thd,ptr,2);
- if (!lock)
- {
- close_thread_tables(thd); /* purecov: deadcode */
- delete thd; /* purecov: deadcode */
- DBUG_RETURN(1); /* purecov: deadcode */
- }
+ if (!(lock=mysql_lock_tables(thd,ptr,2)))
+ goto end;
t_table = tables[0].table; c_table = tables[1].table;
t_table->file->index_init(0);
if (t_table->file->index_first(t_table->record[0]))
{
t_table->file->index_end();
- mysql_unlock_tables(thd, lock);
- thd->version--; // Force close to free memory
- close_thread_tables(thd);
- delete thd;
- DBUG_RETURN(0); // Empty table is ok!
+ return_val= 0;
+ goto end_unlock;
}
- grant_option = TRUE;
+ grant_option= TRUE;
t_table->file->index_end();
- MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
+ /* Will be restored by org_thd->store_globals() */
my_pthread_setspecific_ptr(THR_MALLOC,&memex);
- while (!error)
+ do
{
GRANT_TABLE *mem_check;
if (!(mem_check=new GRANT_TABLE(t_table,c_table)) ||
mem_check->ok() && hash_insert(&hash_tables,(byte*) mem_check))
{
/* This could only happen if we are out memory */
- my_pthread_setspecific_ptr(THR_MALLOC,old_root); /* purecov: deadcode */
- grant_option = FALSE; /* purecov: deadcode */
- mysql_unlock_tables(thd, lock); /* purecov: deadcode */
- close_thread_tables(thd); /* purecov: deadcode */
- delete thd; /* purecov: deadcode */
- DBUG_RETURN(1); /* purecov: deadcode */
+ grant_option= FALSE; /* purecov: deadcode */
+ goto end_unlock;
}
- error = t_table->file->index_next(t_table->record[0]);
}
- my_pthread_setspecific_ptr(THR_MALLOC,old_root);
+ while (!t_table->file->index_next(t_table->record[0]));
+
+ return_val=0; // Return ok
+
+end_unlock:
mysql_unlock_tables(thd, lock);
thd->version--; // Force close to free memory
+
+end:
close_thread_tables(thd);
delete thd;
- DBUG_RETURN(0);
+ if (org_thd)
+ org_thd->store_globals();
+ else
+ {
+ /* Remember that we don't have a THD */
+ my_pthread_setspecific_ptr(THR_THD, 0);
+ }
+ DBUG_RETURN(return_val);
}
-/* Reload grant array if possible */
+/*
+ Reload grant array if possible
+
+ SYNOPSIS
+ grant_reload()
+ thd Thread handler
-void grant_reload(void)
+ NOTES
+ Locked tables are checked by acl_init and doesn't have to be checked here
+*/
+
+void grant_reload(THD *thd)
{
- HASH old_hash_tables;bool old_grant_option;
+ HASH old_hash_tables;
+ bool old_grant_option;
MEM_ROOT old_mem;
DBUG_ENTER("grant_reload");
- // Locked tables are checked by acl_init and doesn't have to be checked here
-
pthread_mutex_lock(&LOCK_grant);
grant_version++;
old_hash_tables=hash_tables;
- old_grant_option = grant_option;
+ old_grant_option= grant_option;
old_mem = memex;
- if (grant_init())
+ if (grant_init(thd))
{ // Error. Revert to old hash
grant_free(); /* purecov: deadcode */
hash_tables=old_hash_tables; /* purecov: deadcode */
- grant_option = old_grant_option; /* purecov: deadcode */
+ grant_option= old_grant_option; /* purecov: deadcode */
memex = old_mem; /* purecov: deadcode */
}
else
@@ -2038,11 +2538,11 @@ void grant_reload(void)
/****************************************************************************
-** Check grants
-** All errors are written directly to the client if command name is given !
+ Check grants
+ All errors are written directly to the client if no_errors is given !
****************************************************************************/
-bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
+bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
uint show_table, bool no_errors)
{
TABLE_LIST *table;
@@ -2060,8 +2560,8 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
table->grant.want_privilege=0;
continue; // Already checked
}
- const char *db = table->db ? table->db : thd->db;
- GRANT_TABLE *grant_table = table_hash_search(thd->host,thd->ip,db,user,
+ GRANT_TABLE *grant_table = table_hash_search(thd->host,thd->ip,
+ table->db,user,
table->real_name,0);
if (!grant_table)
{
@@ -2089,13 +2589,13 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
pthread_mutex_unlock(&LOCK_grant);
return 0;
- err:
+err:
pthread_mutex_unlock(&LOCK_grant);
if (!no_errors) // Not a silent skip of table
{
const char *command="";
if (want_access & SELECT_ACL)
- command ="select";
+ command ="select";
else if (want_access & INSERT_ACL)
command = "insert";
else if (want_access & UPDATE_ACL)
@@ -2115,7 +2615,7 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
net_printf(&thd->net,ER_TABLEACCESS_DENIED_ERROR,
command,
thd->priv_user,
- thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
+ thd->host_or_ip,
table ? table->real_name : "unknown");
}
return 1;
@@ -2128,7 +2628,7 @@ bool check_grant_column(THD *thd,TABLE *table, const char *name,
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
- uint want_access=table->grant.want_privilege;
+ ulong want_access=table->grant.want_privilege;
if (!want_access)
return 0; // Already checked
if (!grant_option)
@@ -2136,7 +2636,7 @@ bool check_grant_column(THD *thd,TABLE *table, const char *name,
pthread_mutex_lock(&LOCK_grant);
- // reload table if someone has modified any grants
+ /* reload table if someone has modified any grants */
if (table->grant.version != grant_version)
{
@@ -2169,19 +2669,14 @@ err:
err2:
if (!show_tables)
{
- const char *command="";
- if (want_access & SELECT_ACL)
- command ="select";
- else if (want_access & INSERT_ACL)
- command = "insert";
- else if (want_access & UPDATE_ACL)
- command = "update";
+ char command[128];
+ get_privilege_desc(command, sizeof(command), want_access);
my_printf_error(ER_COLUMNACCESS_DENIED_ERROR,
ER(ER_COLUMNACCESS_DENIED_ERROR),
MYF(0),
command,
thd->priv_user,
- thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
+ thd->host_or_ip,
name,
table ? table->real_name : "unknown");
}
@@ -2189,7 +2684,7 @@ err2:
}
-bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
+bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
{
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
@@ -2201,7 +2696,7 @@ bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
pthread_mutex_lock(&LOCK_grant);
- // reload table if someone has modified any grants
+ /* reload table if someone has modified any grants */
if (table->grant.version != grant_version)
{
@@ -2211,7 +2706,7 @@ bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
table->real_name,0); /* purecov: inspected */
table->grant.version=grant_version; /* purecov: inspected */
}
- // The following should always be true
+ /* The following should always be true */
if (!(grant_table=table->grant.grant_table))
goto err; /* purecov: inspected */
@@ -2226,7 +2721,7 @@ bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
return 0;
/* We must use my_printf_error() here! */
- err:
+err:
pthread_mutex_unlock(&LOCK_grant);
const char *command="";
@@ -2239,18 +2734,18 @@ bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
MYF(0),
command,
thd->priv_user,
- thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
+ thd->host_or_ip,
field ? field->field_name : "unknown",
table->real_name);
return 1;
}
-/****************************************************************************
-** Check if a user has the right to access a database
-** Access is accepted if he has a grant for any table in the database
-** Return 1 if access is denied
-****************************************************************************/
+/*
+ Check if a user has the right to access a database
+ Access is accepted if he has a grant for any table in the database
+ Return 1 if access is denied
+*/
bool check_grant_db(THD *thd,const char *db)
{
@@ -2278,10 +2773,10 @@ bool check_grant_db(THD *thd,const char *db)
}
/*****************************************************************************
-** Functions to retrieve the grant for a table/column (for SHOW functions)
+ Functions to retrieve the grant for a table/column (for SHOW functions)
*****************************************************************************/
-uint get_table_grant(THD *thd, TABLE_LIST *table)
+ulong get_table_grant(THD *thd, TABLE_LIST *table)
{
uint privilege;
char *user = thd->priv_user;
@@ -2290,7 +2785,7 @@ uint get_table_grant(THD *thd, TABLE_LIST *table)
pthread_mutex_lock(&LOCK_grant);
grant_table = table_hash_search(thd->host,thd->ip,db,user,
- table->real_name,0);
+ table->real_name, 0);
table->grant.grant_table=grant_table; // Remember for column test
table->grant.version=grant_version;
if (grant_table)
@@ -2301,14 +2796,14 @@ uint get_table_grant(THD *thd, TABLE_LIST *table)
}
-uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
+ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
{
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
- uint priv;
+ ulong priv;
pthread_mutex_lock(&LOCK_grant);
- // reload table if someone has modified any grants
+ /* reload table if someone has modified any grants */
if (table->grant.version != grant_version)
{
table->grant.grant_table=
@@ -2333,20 +2828,46 @@ uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
return priv;
}
+/* Help function for mysql_show_grants */
-/*****************************************************************************
-** SHOW GRANTS : send to client grant-like strings depicting user@host
-** privileges
-*****************************************************************************/
+static void add_user_option(String *grant, ulong value, const char *name)
+{
+ if (value)
+ {
+ char buff[22], *p; // just as in int2str
+ grant->append(' ');
+ grant->append(name, strlen(name));
+ grant->append(' ');
+ p=int10_to_str(value, buff, 10);
+ grant->append(buff,p-buff);
+ }
+}
static const char *command_array[]=
-{"SELECT", "INSERT","UPDATE","DELETE","CREATE", "DROP","RELOAD","SHUTDOWN",
- "PROCESS","FILE","GRANT","REFERENCES","INDEX","ALTER"};
-static int command_lengths[]={6,6,6,6,6,4,6,8,7,4,5,10,5,5};
+{
+ "SELECT", "INSERT","UPDATE","DELETE","CREATE", "DROP", "RELOAD","SHUTDOWN",
+ "PROCESS","FILE","GRANT","REFERENCES","INDEX", "ALTER", "SHOW DATABASES",
+ "SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE",
+ "REPLICATION SLAVE", "REPLICATION CLIENT",
+};
+
+static uint command_lengths[]=
+{
+ 6,6,6,6,6,4,6,8,7,4,5,10,5,5,14,5,23,11,7,17,18
+};
-int mysql_show_grants(THD *thd,LEX_USER *lex_user)
+
+/*
+ SHOW GRANTS; Send grants for a user to the client
+
+ IMPLEMENTATION
+ Send to client grant-like strings depicting user@host privileges
+*/
+
+int mysql_show_grants(THD *thd,LEX_USER *lex_user)
{
- uint counter, want_access,index;
+ ulong want_access;
+ uint counter,index;
int error = 0;
ACL_USER *acl_user; ACL_DB *acl_db;
char buff[1024];
@@ -2379,10 +2900,10 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (!(host=acl_user->host.hostname))
host="%";
if (!strcmp(lex_user->user.str,user) &&
- !strcmp(lex_user->host.str,host))
+ !my_strcasecmp(lex_user->host.str,host))
break;
}
- if (counter == acl_users.elements)
+ if (counter == acl_users.elements)
{
my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
MYF(0),lex_user->user.str,lex_user->host.str);
@@ -2403,7 +2924,6 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
VOID(pthread_mutex_lock(&acl_cache->lock));
/* Add first global access grants */
- if (acl_user->access || acl_user->password)
{
want_access=acl_user->access;
String global(buff,sizeof(buff));
@@ -2414,13 +2934,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
global.append("ALL PRIVILEGES",14);
else if (!(want_access & ~GRANT_ACL))
global.append("USAGE",5);
- else
+ else
{
bool found=0;
- uint j,test_access= want_access & ~GRANT_ACL;
+ ulong j,test_access= want_access & ~GRANT_ACL;
for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
{
- if (test_access & j)
+ if (test_access & j)
{
if (found)
global.append(", ",2);
@@ -2430,7 +2950,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
}
global.append (" ON *.* TO '",12);
- global.append(lex_user->user.str,lex_user->user.length);
+ global.append(lex_user->user.str,lex_user->user.length);
global.append ("'@'",3);
global.append(lex_user->host.str,lex_user->host.length);
global.append ('\'');
@@ -2442,8 +2962,53 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
global.append(passd_buff);
global.append('\'');
}
- if (want_access & GRANT_ACL)
- global.append(" WITH GRANT OPTION",18);
+ /* "show grants" SSL related stuff */
+ if (acl_user->ssl_type == SSL_TYPE_ANY)
+ global.append(" REQUIRE SSL",12);
+ else if (acl_user->ssl_type == SSL_TYPE_X509)
+ global.append(" REQUIRE X509",13);
+ else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED)
+ {
+ int ssl_options = 0;
+ global.append(" REQUIRE ",9);
+ if (acl_user->x509_issuer)
+ {
+ ssl_options++;
+ global.append("ISSUER \'",8);
+ global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
+ global.append('\'');
+ }
+ if (acl_user->x509_subject)
+ {
+ if (ssl_options++)
+ global.append(' ');
+ global.append("SUBJECT \'",9);
+ global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
+ global.append('\'');
+ }
+ if (acl_user->ssl_cipher)
+ {
+ if (ssl_options++)
+ global.append(' ');
+ global.append("CIPHER '",8);
+ global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
+ global.append('\'');
+ }
+ }
+ if ((want_access & GRANT_ACL) ||
+ (acl_user->user_resource.questions | acl_user->user_resource.updates |
+ acl_user->user_resource.connections))
+ {
+ global.append(" WITH",5);
+ if (want_access & GRANT_ACL)
+ global.append(" GRANT OPTION",13);
+ add_user_option(&global, acl_user->user_resource.questions,
+ "MAX_QUERIES_PER_HOUR");
+ add_user_option(&global, acl_user->user_resource.updates,
+ "MAX_UPDATES_PER_HOUR");
+ add_user_option(&global, acl_user->user_resource.connections,
+ "MAX_CONNECTIONS_PER_HOUR");
+ }
thd->packet.length(0);
net_store_data(&thd->packet,global.ptr(),global.length());
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
@@ -2465,10 +3030,10 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
host="";
if (!strcmp(lex_user->user.str,user) &&
- !strcmp(lex_user->host.str,host))
+ !my_strcasecmp(lex_user->host.str,host))
{
want_access=acl_db->access;
- if (want_access)
+ if (want_access)
{
String db(buff,sizeof(buff));
db.length(0);
@@ -2476,10 +3041,12 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (test_all_bits(want_access,(DB_ACLS & ~GRANT_ACL)))
db.append("ALL PRIVILEGES",14);
+ else if (!(want_access & ~GRANT_ACL))
+ db.append("USAGE",5);
else
{
int found=0, cnt;
- uint j,test_access= want_access & ~GRANT_ACL;
+ ulong j,test_access= want_access & ~GRANT_ACL;
for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
{
if (test_access & j)
@@ -2491,15 +3058,15 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
}
}
- db.append (" ON `",5);
+ db.append(" ON `",5);
db.append(acl_db->db);
- db.append ("`.* TO '",8);
- db.append(lex_user->user.str,lex_user->user.length);
- db.append ("'@'",3);
+ db.append("`.* TO '",8);
+ db.append(lex_user->user.str,lex_user->user.length);
+ db.append("'@'",3);
db.append(lex_user->host.str, lex_user->host.length);
- db.append ('\'');
+ db.append('\'');
if (want_access & GRANT_ACL)
- db.append(" WITH GRANT OPTION",18);
+ db.append(" WITH GRANT OPTION",18);
thd->packet.length(0);
net_store_data(&thd->packet,db.ptr(),db.length());
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
@@ -2516,7 +3083,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
for (index=0 ; index < hash_tables.records ; index++)
{
const char *user,*host;
- GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index);
+ GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index);
if (!(user=grant_table->user))
user="";
@@ -2524,46 +3091,60 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
host="";
if (!strcmp(lex_user->user.str,user) &&
- !strcmp(lex_user->host.str,host))
+ !my_strcasecmp(lex_user->host.str,host))
{
- want_access=grant_table->privs;
- if ((want_access | grant_table->cols) != 0)
+ ulong table_access= grant_table->privs;
+ if ((table_access | grant_table->cols) != 0)
{
String global(buff,sizeof(buff));
+ ulong test_access= (table_access | grant_table->cols) & ~GRANT_ACL;
+
global.length(0);
global.append("GRANT ",6);
- if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL)))
+ if (test_all_bits(table_access, (TABLE_ACLS & ~GRANT_ACL)))
global.append("ALL PRIVILEGES",14);
- else
+ else if (!test_access)
+ global.append("USAGE",5);
+ else
{
- int found=0;
- uint j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
+ int found= 0;
+ ulong j;
- for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1)
+ for (counter= 0, j= SELECT_ACL; j <= TABLE_ACLS; counter++, j<<= 1)
{
- if (test_access & j)
+ if (test_access & j)
{
if (found)
global.append(", ",2);
- found = 1;
+ found= 1;
global.append(command_array[counter],command_lengths[counter]);
- if (grant_table->cols)
+ if (grant_table->cols)
{
- uint found_col=0;
+ uint found_col= 0;
for (uint col_index=0 ;
col_index < grant_table->hash_columns.records ;
col_index++)
{
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
hash_element(&grant_table->hash_columns,col_index);
- if (grant_column->rights & j)
+ if (grant_column->rights & j)
{
- if (!found_col)
+ if (!found_col)
{
+ found_col= 1;
+ /*
+ If we have a duplicated table level privilege, we
+ must write the access privilege name again.
+ */
+ if (table_access & j)
+ {
+ global.append(", ", 2);
+ global.append(command_array[counter],
+ command_lengths[counter]);
+ }
global.append(" (",2);
- found_col=1;
}
else
global.append(", ",2);
@@ -2577,17 +3158,17 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
}
}
- global.append(" ON ",4);
+ global.append(" ON `",5);
global.append(grant_table->db);
- global.append(".",1);
+ global.append("`.`",3);
global.append(grant_table->tname);
- global.append(" TO '",5);
- global.append(lex_user->user.str,lex_user->user.length);
+ global.append("` TO '",6);
+ global.append(lex_user->user.str,lex_user->user.length);
global.append("'@'",3);
- global.append(lex_user->host.str,lex_user->host.length);
+ global.append(lex_user->host.str,lex_user->host.length);
global.append('\'');
- if (want_access & GRANT_ACL)
- global.append(" WITH GRANT OPTION",18);
+ if (table_access & GRANT_ACL)
+ global.append(" WITH GRANT OPTION",18);
thd->packet.length(0);
net_store_data(&thd->packet,global.ptr(),global.length());
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
@@ -2600,7 +3181,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
}
- end:
+end:
VOID(pthread_mutex_unlock(&acl_cache->lock));
pthread_mutex_unlock(&LOCK_grant);
@@ -2609,8 +3190,47 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
+/*
+ Make a clear-text version of the requested privilege.
+*/
+
+void get_privilege_desc(char *to, uint max_length, ulong access)
+{
+ uint pos;
+ char *start=to;
+ DBUG_ASSERT(max_length >= 30); // For end ',' removal
+
+ if (access)
+ {
+ max_length--; // Reserve place for end-zero
+ for (pos=0 ; access ; pos++, access>>=1)
+ {
+ if ((access & 1) &&
+ command_lengths[pos] + (uint) (to-start) < max_length)
+ {
+ to= strmov(to, command_array[pos]);
+ *to++=',';
+ }
+ }
+ to--; // Remove end ','
+ }
+ *to=0;
+}
+
+
+void get_mqh(const char *user, const char *host, USER_CONN *uc)
+{
+ ACL_USER *acl_user;
+ if (initialized && (acl_user= find_acl_user(host,user)))
+ uc->user_resources= acl_user->user_resource;
+ else
+ bzero((char*) &uc->user_resources, sizeof(uc->user_resources));
+}
+
+
+
/*****************************************************************************
-** Instantiate used templates
+ Instantiate used templates
*****************************************************************************/
#ifdef __GNUC__
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index cf9696d51e7..bf269e5a7e3 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -1,84 +1,115 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define SELECT_ACL 1
-#define INSERT_ACL 2
-#define UPDATE_ACL 4
-#define DELETE_ACL 8
-#define CREATE_ACL 16
-#define DROP_ACL 32
-#define RELOAD_ACL 64
-#define SHUTDOWN_ACL 128
-#define PROCESS_ACL 256
-#define FILE_ACL 512
-#define GRANT_ACL 1024
-#define REFERENCES_ACL 2048
-#define INDEX_ACL 4096
-#define ALTER_ACL 8192
-#define EXTRA_ACL 16384
-#define DB_ACLS (UPDATE_ACL | SELECT_ACL | INSERT_ACL | \
- DELETE_ACL | CREATE_ACL | DROP_ACL | GRANT_ACL | \
- REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
-#define TABLE_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | \
- DELETE_ACL | CREATE_ACL | DROP_ACL | GRANT_ACL | \
- REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
-#define COL_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL)
-#define GLOBAL_ACLS (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL |\
- CREATE_ACL | DROP_ACL | RELOAD_ACL | SHUTDOWN_ACL |\
- PROCESS_ACL | FILE_ACL | GRANT_ACL | REFERENCES_ACL |\
- INDEX_ACL | ALTER_ACL)
-#define NO_ACCESS 32768
-
-/* defines to change the above bits to how things are stored in tables */
-
-#define fix_rights_for_db(A) (((A) & 63) | (((A) & ~63) << 4))
-#define get_rights_for_db(A) (((A) & 63) | (((A) & ~63) >> 4))
+#define SELECT_ACL (1L << 0)
+#define INSERT_ACL (1L << 1)
+#define UPDATE_ACL (1L << 2)
+#define DELETE_ACL (1L << 3)
+#define CREATE_ACL (1L << 4)
+#define DROP_ACL (1L << 5)
+#define RELOAD_ACL (1L << 6)
+#define SHUTDOWN_ACL (1L << 7)
+#define PROCESS_ACL (1L << 8)
+#define FILE_ACL (1L << 9)
+#define GRANT_ACL (1L << 10)
+#define REFERENCES_ACL (1L << 11)
+#define INDEX_ACL (1L << 12)
+#define ALTER_ACL (1L << 13)
+#define SHOW_DB_ACL (1L << 14)
+#define SUPER_ACL (1L << 15)
+#define CREATE_TMP_ACL (1L << 16)
+#define LOCK_TABLES_ACL (1L << 17)
+#define EXECUTE_ACL (1L << 18)
+#define REPL_SLAVE_ACL (1L << 19)
+#define REPL_CLIENT_ACL (1L << 20)
+
+
+#define DB_ACLS \
+(UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
+ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | LOCK_TABLES_ACL)
+
+#define TABLE_ACLS \
+(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
+ GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
+
+#define COL_ACLS \
+(SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL)
+
+#define GLOBAL_ACLS \
+(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
+ RELOAD_ACL | SHUTDOWN_ACL | PROCESS_ACL | FILE_ACL | GRANT_ACL | \
+ REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \
+ CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \
+ EXECUTE_ACL)
+
+#define EXTRA_ACL (1L << 29)
+#define NO_ACCESS (1L << 30)
+
+/*
+ Defines to change the above bits to how things are stored in tables
+ This is needed as the 'host' and 'db' table is missing a few privileges
+*/
+
+/* Continius bit-segments that needs to be shifted */
+#define DB_REL1 (RELOAD_ACL | SHUTDOWN_ACL | PROCESS_ACL | FILE_ACL)
+#define DB_REL2 (GRANT_ACL | REFERENCES_ACL)
+
+/* Privileges that needs to be reallocated (in continous chunks) */
+#define DB_CHUNK1 (GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
+#define DB_CHUNK2 (CREATE_TMP_ACL | LOCK_TABLES_ACL)
+
+#define fix_rights_for_db(A) (((A) & 63) | (((A) & DB_REL1) << 4) | (((A) & DB_REL2) << 6))
+#define get_rights_for_db(A) (((A) & 63) | (((A) & DB_CHUNK1) >> 4) | (((A) & DB_CHUNK2) >> 6))
#define fix_rights_for_table(A) (((A) & 63) | (((A) & ~63) << 4))
#define get_rights_for_table(A) (((A) & 63) | (((A) & ~63) >> 4))
-#define fix_rights_for_column(A) (((A) & COL_ACLS) | ((A & ~COL_ACLS) << 7))
-#define get_rights_for_column(A) (((A) & COL_ACLS) | ((A & ~COL_ACLS) >> 7))
+#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8))
+#define get_rights_for_column(A) (((A) & 7) | ((A) >> 8))
/* prototypes */
-int acl_init(bool dont_read_acl_tables);
-void acl_reload(void);
+my_bool acl_init(THD *thd, bool dont_read_acl_tables);
+void acl_reload(THD *thd);
void acl_free(bool end=0);
-uint acl_get(const char *host, const char *ip, const char *bin_ip,
- const char *user, const char *db);
-uint acl_getroot(const char *host, const char *ip, const char *user,
- const char *password,const char *scramble,char **priv_user,
- bool old_ver);
+ulong acl_get(const char *host, const char *ip, const char *bin_ip,
+ const char *user, const char *db);
+ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
+ const char *password,const char *scramble,
+ char **priv_user, char *priv_host,
+ bool old_ver, USER_RESOURCES *max);
bool acl_check_host(const char *host, const char *ip);
+bool check_change_password(THD *thd, const char *host, const char *user);
bool change_password(THD *thd, const char *host, const char *user,
char *password);
int mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
- uint rights, bool revoke);
+ ulong rights, bool revoke);
int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
- List <LEX_COLUMN> &column_list, uint rights,
+ List <LEX_COLUMN> &column_list, ulong rights,
bool revoke);
-int grant_init(void);
+my_bool grant_init(THD *thd);
void grant_free(void);
-void grant_reload(void);
-bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
+void grant_reload(THD *thd);
+bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
uint show_command=0, bool dont_print_error=0);
-bool check_grant_column (THD *thd,TABLE *table, const char *name,uint length,
+bool check_grant_column (THD *thd,TABLE *table, const char *name, uint length,
uint show_command=0);
-bool check_grant_all_columns(THD *thd, uint want_access, TABLE *table);
+bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table);
bool check_grant_db(THD *thd,const char *db);
-uint get_table_grant(THD *thd, TABLE_LIST *table);
-uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field);
+ulong get_table_grant(THD *thd, TABLE_LIST *table);
+ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field);
int mysql_show_grants(THD *thd, LEX_USER *user);
+void get_privilege_desc(char *to, uint max_length, ulong access);
+void get_mqh(const char *user, const char *host, USER_CONN *uc);
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 80a35120f45..bd8c0e5ba87 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -38,6 +38,37 @@
#define UINT_MAX24 0xffffff
#define UINT_MAX32 0xffffffff
+int sortcmp2(void* cmp_arg __attribute__((unused)),
+ const String *a,const String *b)
+{
+ return sortcmp(a,b);
+}
+
+int stringcmp2(void* cmp_arg __attribute__((unused)),
+ const String *a,const String *b)
+{
+ return stringcmp(a,b);
+}
+
+int compare_double2(void* cmp_arg __attribute__((unused)),
+ const double *s, const double *t)
+{
+ return compare_double(s,t);
+}
+
+int compare_longlong2(void* cmp_arg __attribute__((unused)),
+ const longlong *s, const longlong *t)
+{
+ return compare_longlong(s,t);
+}
+
+int compare_ulonglong2(void* cmp_arg __attribute__((unused)),
+ const ulonglong *s, const ulonglong *t)
+{
+ return compare_ulonglong(s,t);
+}
+
+
Procedure *
proc_analyse_init(THD *thd, ORDER *param, select_result *result,
List<Item> &field_list)
@@ -60,7 +91,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
{
delete pc;
net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
- return 0;
+ DBUG_RETURN(0);
}
pc->max_tree_elements = (uint) (*param->item)->val_int();
param = param->next;
@@ -68,7 +99,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
{
delete pc;
net_printf(&thd->net, ER_WRONG_PARAMCOUNT_TO_PROCEDURE, proc_name);
- return 0;
+ DBUG_RETURN(0);
}
// second parameter
if ((*param->item)->type() != Item::INT_ITEM ||
@@ -76,7 +107,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
{
delete pc;
net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
- return 0;
+ DBUG_RETURN(0);
}
pc->max_treemem = (uint) (*param->item)->val_int();
}
@@ -85,7 +116,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
{
delete pc;
net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name);
- return 0;
+ DBUG_RETURN(0);
}
// if only one parameter was given, it will be the value of max_tree_elements
else
@@ -100,7 +131,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
pc->f_end = pc->f_info + field_list.elements;
pc->fields = field_list;
- List_iterator<Item> it(pc->fields);
+ List_iterator_fast<Item> it(pc->fields);
f_info = pc->f_info;
Item *item;
@@ -121,7 +152,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
if (item->result_type() == STRING_RESULT)
*f_info++ = new field_str(item, pc);
}
- return pc;
+ DBUG_RETURN(pc);
}
@@ -137,8 +168,10 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
DBUG_ENTER("test_if_number");
- // MySQL removes any endspaces of a string, so we must take care only of
- // spaces in front of a string
+ /*
+ MySQL removes any endspaces of a string, so we must take care only of
+ spaces in front of a string
+ */
for (; str != end && isspace(*str); str++) ;
if (str == end)
return 0;
@@ -187,8 +220,7 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
info->is_float = 1; // we can't use variable decimals here
return 1;
}
- else
- return 0;
+ return 0;
}
for (str++; *(end - 1) == '0'; end--); // jump over zeros at the end
if (str == end) // number was something like '123.000'
@@ -203,11 +235,8 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
info->dval = atod(begin);
return 1;
}
- else
- return 0;
}
- else
- return 0;
+ return 0;
}
@@ -251,7 +280,6 @@ void field_str::add()
char buff[MAX_FIELD_WIDTH], *ptr;
String s(buff, sizeof(buff)), *res;
ulong length;
- TREE_ELEMENT *element;
if (!(res = item->val_str(&s)))
{
@@ -285,32 +313,6 @@ void field_str::add()
was_maybe_zerofill = num_info.maybe_zerofill;
}
- if (room_in_tree)
- {
- if (res != &s)
- s.copy(*res);
- if (!tree_search(&tree, (void*) &s)) // If not in tree
- {
- s.copy(); // slow, when SAFE_MALLOC is in use
- if (!(element=tree_insert(&tree, (void*) &s, 0)))
- {
- room_in_tree = 0; // Remove tree, out of RAM ?
- delete_tree(&tree);
- }
- else
- {
- bzero((char*) &s, sizeof(s)); // Let tree handle free of this
- if ((treemem += length) > pc->max_treemem ||
- (element->count == 1 &&
- (tree_elements++) >= pc->max_tree_elements))
- {
- room_in_tree = 0; // Remove tree, too big tree
- delete_tree(&tree);
- }
- }
- }
- }
-
if (!found)
{
found = 1;
@@ -341,6 +343,31 @@ void field_str::add()
max_arg.copy(*res);
}
}
+
+ if (room_in_tree)
+ {
+ if (res != &s)
+ s.copy(*res);
+ if (!tree_search(&tree, (void*) &s)) // If not in tree
+ {
+ s.copy(); // slow, when SAFE_MALLOC is in use
+ if (!tree_insert(&tree, (void*) &s, 0))
+ {
+ room_in_tree = 0; // Remove tree, out of RAM ?
+ delete_tree(&tree);
+ }
+ else
+ {
+ bzero((char*) &s, sizeof(s)); // Let tree handle free of this
+ if ((treemem += length) > pc->max_treemem)
+ {
+ room_in_tree = 0; // Remove tree, too big tree
+ delete_tree(&tree);
+ }
+ }
+ }
+ }
+
if ((num_info.zerofill && (max_length != min_length)) ||
(was_zero_fill && (max_length != min_length)))
can_be_still_num = 0; // zerofilled numbers must be of same length
@@ -879,7 +906,7 @@ int collect_string(String *element,
int collect_real(double *element, element_count count __attribute__((unused)),
TREE_INFO *info)
{
- char buff[255];
+ char buff[MAX_FIELD_WIDTH];
String s(buff, sizeof(buff));
if (info->found)
@@ -898,7 +925,7 @@ int collect_longlong(longlong *element,
element_count count __attribute__((unused)),
TREE_INFO *info)
{
- char buff[255];
+ char buff[MAX_FIELD_WIDTH];
String s(buff, sizeof(buff));
if (info->found)
@@ -917,7 +944,7 @@ int collect_ulonglong(ulonglong *element,
element_count count __attribute__((unused)),
TREE_INFO *info)
{
- char buff[255];
+ char buff[MAX_FIELD_WIDTH];
String s(buff, sizeof(buff));
if (info->found)
diff --git a/sql/sql_analyse.h b/sql/sql_analyse.h
index faf79508f60..aa6d0dbb2d1 100644
--- a/sql/sql_analyse.h
+++ b/sql/sql_analyse.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,8 +21,6 @@
#pragma interface /* gcc class implementation */
#endif
-#include <my_tree.h>
-
#define DEC_IN_AVG 4
typedef struct st_number_info
@@ -53,8 +51,14 @@ uint check_ulonglong(const char *str, uint length);
bool get_ev_num_info(EV_NUM_INFO *ev_info, NUM_INFO *info, const char *num);
bool test_if_number(NUM_INFO *info, const char *str, uint str_len);
int compare_double(const double *s, const double *t);
+int compare_double2(void* cmp_arg __attribute__((unused)),
+ const double *s, const double *t);
int compare_longlong(const longlong *s, const longlong *t);
+int compare_longlong2(void* cmp_arg __attribute__((unused)),
+ const longlong *s, const longlong *t);
int compare_ulonglong(const ulonglong *s, const ulonglong *t);
+int compare_ulonglong2(void* cmp_arg __attribute__((unused)),
+ const ulonglong *s, const ulonglong *t);
Procedure *proc_analyse_init(THD *thd, ORDER *param, select_result *result,
List<Item> &field_list);
void free_string(String*);
@@ -91,6 +95,11 @@ public:
int collect_string(String *element, element_count count,
TREE_INFO *info);
+int sortcmp2(void* cmp_arg __attribute__((unused)),
+ const String *a,const String *b);
+int stringcmp2(void* cmp_arg __attribute__((unused)),
+ const String *a,const String *b);
+
class field_str :public field_info
{
String min_arg, max_arg;
@@ -105,9 +114,9 @@ public:
max_arg(""), sum(0),
must_be_blob(0), was_zero_fill(0),
was_maybe_zerofill(0), can_be_still_num(1)
- { init_tree(&tree, 0, sizeof(String), a->binary ?
- (qsort_cmp) stringcmp : (qsort_cmp) sortcmp,
- 0, (void (*)(void*)) free_string); };
+ { init_tree(&tree, 0, 0, sizeof(String), a->binary ?
+ (qsort_cmp2) stringcmp2 : (qsort_cmp2) sortcmp2,
+ 0, (tree_element_free) free_string, NULL); };
void add();
void get_opt_type(String*, ha_rows);
@@ -145,8 +154,8 @@ class field_real: public field_info
public:
field_real(Item* a, analyse* b) :field_info(a,b),
min_arg(0), max_arg(0), sum(0), sum_sqr(0), max_notzero_dec_len(0)
- { init_tree(&tree, 0, sizeof(double),
- (qsort_cmp) compare_double, 0, NULL); }
+ { init_tree(&tree, 0, 0, sizeof(double),
+ (qsort_cmp2) compare_double2, 0, NULL, NULL); }
void add();
void get_opt_type(String*, ha_rows);
@@ -191,8 +200,8 @@ class field_longlong: public field_info
public:
field_longlong(Item* a, analyse* b) :field_info(a,b),
min_arg(0), max_arg(0), sum(0), sum_sqr(0)
- { init_tree(&tree, 0, sizeof(longlong),
- (qsort_cmp) compare_longlong, 0, NULL); }
+ { init_tree(&tree, 0, 0, sizeof(longlong),
+ (qsort_cmp2) compare_longlong2, 0, NULL, NULL); }
void add();
void get_opt_type(String*, ha_rows);
@@ -236,8 +245,8 @@ class field_ulonglong: public field_info
public:
field_ulonglong(Item* a, analyse * b) :field_info(a,b),
min_arg(0), max_arg(0), sum(0),sum_sqr(0)
- { init_tree(&tree, 0, sizeof(ulonglong),
- (qsort_cmp) compare_ulonglong, 0, NULL); }
+ { init_tree(&tree, 0, 0, sizeof(ulonglong),
+ (qsort_cmp2) compare_ulonglong2, 0, NULL, NULL); }
void add();
void get_opt_type(String*, ha_rows);
String *get_min_arg(String *s) { s->set(min_arg); return s; }
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 3f8a59613b4..efb008f4a6e 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -15,11 +15,10 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Basic functions neaded by many modules */
+/* Basic functions needed by many modules */
#include "mysql_priv.h"
#include "sql_acl.h"
-#include <thr_alarm.h>
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
@@ -34,16 +33,14 @@ HASH open_cache; /* Used by mysql_test */
static int open_unireg_entry(THD *thd,TABLE *entry,const char *db,
const char *name, const char *alias);
-static bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
- const char *table_name, List_iterator<Item> *it);
static void free_cache_entry(TABLE *entry);
static void mysql_rm_tmp_tables(void);
static key_map get_key_map_from_key_list(TABLE *table,
List<String> *index_list);
-static byte *cache_key(const byte *record,uint *length,
- my_bool not_used __attribute__((unused)))
+extern "C" byte *table_cache_key(const byte *record,uint *length,
+ my_bool not_used __attribute__((unused)))
{
TABLE *entry=(TABLE*) record;
*length=entry->key_length;
@@ -52,8 +49,8 @@ static byte *cache_key(const byte *record,uint *length,
void table_cache_init(void)
{
- VOID(hash_init(&open_cache,table_cache_size+16,0,0,cache_key,
- (void (*)(void*)) free_cache_entry,0));
+ VOID(hash_init(&open_cache,table_cache_size+16,0,0,table_cache_key,
+ (hash_free_key) free_cache_entry,0));
mysql_rm_tmp_tables();
}
@@ -111,75 +108,90 @@ static void check_unused(void)
#define check_unused()
#endif
-int list_open_tables(THD *thd,List<char> *tables, const char *db,
- const char *wild)
+/*
+ Create a list for all open tables matching SQL expression
+
+ SYNOPSIS
+ list_open_tables()
+ thd Thread THD
+ wild SQL like expression
+
+ NOTES
+ One gets only a list of tables for which one has any kind of privilege.
+ db and table names are allocated in result struct, so one doesn't need
+ a lock on LOCK_open when traversing the return list.
+
+ RETURN VALUES
+ NULL Error (Probably OOM)
+ # Pointer to list of names of open tables.
+*/
+
+OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild)
{
int result = 0;
- uint col_access=thd->col_access;
+ OPEN_TABLE_LIST **start_list, *open_list;
TABLE_LIST table_list;
+ char name[NAME_LEN*2];
DBUG_ENTER("list_open_tables");
+
VOID(pthread_mutex_lock(&LOCK_open));
bzero((char*) &table_list,sizeof(table_list));
+ start_list= &open_list;
+ open_list=0;
- for (uint idx=0 ; idx < open_cache.records; idx++)
+ for (uint idx=0 ; result == 0 && idx < open_cache.records; idx++)
{
+ OPEN_TABLE_LIST *table;
TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
- if ((!entry->real_name) || strcmp(entry->table_cache_key,db))
- continue;
- if (wild && wild[0] && wild_compare(entry->real_name,wild))
- continue;
- if (db && !(col_access & TABLE_ACLS))
+
+ if ((!entry->real_name))
+ continue; // Shouldn't happen
+ if (wild)
{
- table_list.db= (char*) db;
- table_list.real_name= entry->real_name;/*real name*/
- table_list.grant.privilege=col_access;
- if (check_grant(thd,TABLE_ACLS,&table_list,1,1))
- continue;
+ strxmov(name,entry->table_cache_key,".",entry->real_name,NullS);
+ if (wild_compare(name,wild))
+ continue;
}
- /* need to check if he have't already listed it */
- List_iterator<char> it(*tables);
- char *table_name;
- int check = 0;
- while (check == 0 && (table_name=it++))
+ /* Check if user has SELECT privilege for any column in the table */
+ table_list.db= (char*) entry->table_cache_key;
+ table_list.real_name= entry->real_name;
+ table_list.grant.privilege=0;
+ if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list,1))
+ continue;
+
+ /* need to check if we haven't already listed it */
+ for (table= open_list ; table ; table=table->next)
{
- if (!strcmp(table_name,entry->real_name))
- check++;
+ if (!strcmp(table->table,entry->real_name) &&
+ !strcmp(table->db,entry->table_cache_key))
+ {
+ if (entry->in_use)
+ table->in_use++;
+ if (entry->locked_by_name)
+ table->locked++;
+ break;
+ }
}
- if (check)
+ if (table)
continue;
-
- if (tables->push_back(thd->strdup(entry->real_name)))
+ if (!(*start_list = (OPEN_TABLE_LIST *)
+ sql_alloc(sizeof(**start_list)+entry->key_length)))
{
- result = -1;
+ open_list=0; // Out of memory
break;
}
+ strmov((*start_list)->table=
+ strmov(((*start_list)->db= (char*) ((*start_list)+1)),
+ entry->table_cache_key)+1,
+ entry->real_name);
+ (*start_list)->in_use= entry->in_use ? 1 : 0;
+ (*start_list)->locked= entry->locked_by_name ? 1 : 0;
+ start_list= &(*start_list)->next;
+ *start_list=0;
}
-
VOID(pthread_mutex_unlock(&LOCK_open));
- DBUG_RETURN(result);
-}
-
-char*
-query_table_status(THD *thd,const char *db,const char *table_name)
-{
- int cached = 0, in_use = 0;
- char info[256];
-
- for (uint idx=0 ; idx < open_cache.records; idx++)
- {
- TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
- if (strcmp(entry->table_cache_key,db) ||
- strcmp(entry->real_name,table_name))
- continue;
-
- cached++;
- if (entry->in_use)
- in_use++;
- }
-
- sprintf(info, "cached=%d, in_use=%d", cached, in_use);
- return thd->strdup(info);
+ DBUG_RETURN(open_list);
}
@@ -195,10 +207,11 @@ query_table_status(THD *thd,const char *db,const char *table_name)
bool
send_fields(THD *thd,List<Item> &list,uint flag)
{
- List_iterator<Item> it(list);
+ List_iterator_fast<Item> it(list);
Item *item;
char buff[80];
- CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set;
+ CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->variables.convert_set;
+ DBUG_ENTER("send_fields");
String tmp((char*) buff,sizeof(buff)),*res,*packet= &thd->packet;
@@ -259,11 +272,11 @@ send_fields(THD *thd,List<Item> &list,uint flag)
if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length()))
break; /* purecov: inspected */
}
- send_eof(&thd->net,(test_flags & TEST_MIT_THREAD) ? 0: 1);
- return 0;
+ send_eof(&thd->net,1);
+ DBUG_RETURN(0);
err:
send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */
- return 1; /* purecov: inspected */
+ DBUG_RETURN(1); /* purecov: inspected */
}
@@ -293,6 +306,7 @@ void intern_close_table(TABLE *table)
static void free_cache_entry(TABLE *table)
{
DBUG_ENTER("free_cache_entry");
+ safe_mutex_assert_owner(&LOCK_open);
intern_close_table(table);
if (!table->in_use)
@@ -314,6 +328,7 @@ static void free_cache_entry(TABLE *table)
void free_io_cache(TABLE *table)
{
+ DBUG_ENTER("free_io_cache");
if (table->io_cache)
{
close_cached_file(table->io_cache);
@@ -325,6 +340,7 @@ void free_io_cache(TABLE *table)
my_free((gptr) table->record_pointers,MYF(0));
table->record_pointers=0;
}
+ DBUG_VOID_RETURN;
}
/* Close all tables which aren't in use by any thread */
@@ -360,14 +376,14 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
if (!found)
if_wait_for_refresh=0; // Nothing to wait for
}
+ if (!tables)
+ kill_delayed_threads();
if (if_wait_for_refresh)
{
/*
If there is any table that has a lower refresh_version, wait until
this is closed (or this thread is killed) before returning
*/
- if (!tables)
- kill_delayed_threads();
thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh;
thd->proc_info="Flushing tables";
@@ -437,6 +453,7 @@ void close_thread_tables(THD *thd, bool locked)
/* VOID(pthread_sigmask(SIG_SETMASK,&thd->block_signals,NULL)); */
if (!locked)
VOID(pthread_mutex_lock(&LOCK_open));
+ safe_mutex_assert_owner(&LOCK_open);
DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables));
@@ -465,8 +482,9 @@ bool close_thread_table(THD *thd, TABLE **table_ptr)
{
DBUG_ENTER("close_thread_table");
- bool found_old_table=0;
- TABLE *table=*table_ptr;
+ bool found_old_table= 0;
+ TABLE *table= *table_ptr;
+ DBUG_ASSERT(table->key_read == 0);
*table_ptr=table->next;
if (table->version != refresh_version ||
@@ -524,17 +542,23 @@ void close_temporary_tables(THD *thd)
char *query, *end;
uint query_buf_size;
bool found_user_tables = 0;
- LINT_INIT(end);
if (!thd->temporary_tables)
- return; // no tables to close
+ return;
+
+ LINT_INIT(end);
+ query_buf_size= 50; // Enough for DROP ... TABLE
- query_buf_size= 11; // "drop table "
for (table=thd->temporary_tables ; table ; table=table->next)
- query_buf_size+= table->key_length +1;
+ /*
+ We are going to add 4 ` around the db/table names, so 1 does not look
+ enough; indeed it is enough, because table->key_length is greater (by 8,
+ because of server_id and thread_id) than db||table.
+ */
+ query_buf_size+= table->key_length+1;
if ((query = alloc_root(&thd->mem_root, query_buf_size)))
- end= strmov(query, "drop table ");
+ end=strmov(query, "DROP /*!40005 TEMPORARY */ TABLE ");
for (table=thd->temporary_tables ; table ; table=next)
{
@@ -542,26 +566,23 @@ void close_temporary_tables(THD *thd)
{
// skip temporary tables not created directly by the user
if (table->real_name[0] != '#')
- {
- end = strxmov(end,table->table_cache_key,".",
- table->real_name,",", NullS);
- // here we assume table_cache_key always starts
- // with \0 terminated db name
found_user_tables = 1;
- }
+ /*
+ Here we assume table_cache_key always starts
+ with \0 terminated db name
+ */
+ end = strxmov(end,"`",table->table_cache_key,"`.`",
+ table->real_name,"`,", NullS);
}
next=table->next;
close_temporary(table);
}
if (query && found_user_tables && mysql_bin_log.is_open())
{
- uint save_query_len = thd->query_length;
- *--end = 0; // Remove last ','
- thd->query_length = (uint)(end-query);
- Query_log_event qinfo(thd, query);
- qinfo.error_code=0;
+ /* The -1 is to remove last ',' */
+ thd->clear_error();
+ Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0);
mysql_bin_log.write(&qinfo);
- thd->query_length = save_query_len;
}
thd->temporary_tables=0;
}
@@ -573,6 +594,8 @@ TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name)
uint key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
TABLE *table,**prev;
+ int4store(key+key_length,thd->server_id);
+ key_length += 4;
int4store(key+key_length,thd->slave_proxy_id);
key_length += 4;
@@ -596,31 +619,38 @@ bool close_temporary_table(THD *thd, const char *db, const char *table_name)
table= *prev;
*prev= table->next;
close_temporary(table);
- if(thd->slave_thread)
+ if (thd->slave_thread)
--slave_open_temp_tables;
return 0;
}
+/*
+ Used by ALTER TABLE when the table is a temporary one. It changes something
+ only if the ALTER contained a RENAME clause (otherwise, table_name is the old
+ name).
+ Prepares a table cache key, which is the concatenation of db, table_name and
+ thd->slave_proxy_id, separated by '\0'.
+*/
bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
const char *table_name)
{
char *key;
if (!(key=(char*) alloc_root(&table->mem_root,
(uint) strlen(db)+
- (uint) strlen(table_name)+6)))
+ (uint) strlen(table_name)+6+4)))
return 1; /* purecov: inspected */
table->key_length=(uint)
(strmov((table->real_name=strmov(table->table_cache_key=key,
db)+1),
table_name) - table->table_cache_key)+1;
+ int4store(key+table->key_length,thd->server_id);
+ table->key_length += 4;
int4store(key+table->key_length,thd->slave_proxy_id);
table->key_length += 4;
return 0;
}
-
-
/* move table first in unused links */
static void relink_unused(TABLE *table)
@@ -676,11 +706,13 @@ TABLE *unlink_open_table(THD *thd, TABLE *list, TABLE *find)
/*
When we call the following function we must have a lock on
- LOCK_OPEN ; This lock will be unlocked on return.
+ LOCK_open ; This lock will be unlocked on return.
*/
void wait_for_refresh(THD *thd)
{
+ safe_mutex_assert_owner(&LOCK_open);
+
/* Wait until the current table is up to date */
const char *proc_info;
thd->mysys_var->current_mutex= &LOCK_open;
@@ -698,13 +730,14 @@ void wait_for_refresh(THD *thd)
pthread_mutex_unlock(&thd->mysys_var->mutex);
}
+
TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
{
DBUG_ENTER("reopen_name_locked_table");
if (thd->killed)
DBUG_RETURN(0);
TABLE* table;
- if(!(table = table_list->table))
+ if (!(table = table_list->table))
DBUG_RETURN(0);
char* db = thd->db ? thd->db : table_list->db;
@@ -717,11 +750,11 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
if (open_unireg_entry(thd, table, db, table_name, table_name) ||
!(table->table_cache_key =memdup_root(&table->mem_root,(char*) key,
key_length)))
- {
- closefrm(table);
- pthread_mutex_unlock(&LOCK_open);
- DBUG_RETURN(0);
- }
+ {
+ closefrm(table);
+ pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(0);
+ }
table->key_length=key_length;
table->version=0;
@@ -734,9 +767,10 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
- table->outer_join=table->null_row=table->maybe_null=0;
+ table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
table->status=STATUS_NO_RECORD;
- table->keys_in_use_for_query=table->used_keys= table->keys_in_use;
+ table->keys_in_use_for_query= table->keys_in_use;
+ table->used_keys= table->keys_for_keyread;
DBUG_RETURN(table);
}
@@ -765,12 +799,13 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
if (thd->killed)
DBUG_RETURN(0);
key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
- int4store(key + key_length, thd->slave_proxy_id);
+ int4store(key + key_length, thd->server_id);
+ int4store(key + key_length + 4, thd->slave_proxy_id);
for (table=thd->temporary_tables; table ; table=table->next)
{
- if (table->key_length == key_length+4 &&
- !memcmp(table->table_cache_key,key,key_length+4))
+ if (table->key_length == key_length+8 &&
+ !memcmp(table->table_cache_key,key,key_length+8))
{
if (table->query_id == thd->query_id)
{
@@ -789,8 +824,12 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
{
if (table->key_length == key_length &&
!memcmp(table->table_cache_key,key,key_length) &&
- !my_strcasecmp(table->table_name,alias))
+ !my_strcasecmp(table->table_name,alias) &&
+ table->query_id != thd->query_id)
+ {
+ table->query_id=thd->query_id;
goto reset;
+ }
}
my_printf_error(ER_TABLE_NOT_LOCKED,ER(ER_TABLE_NOT_LOCKED),MYF(0),alias);
DBUG_RETURN(0);
@@ -854,25 +893,6 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
key_length)))
{
- MEM_ROOT* glob_alloc;
- LINT_INIT(glob_alloc);
-
- if (errno == ENOENT &&
- (glob_alloc = my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC)))
- // Sasha: needed for replication
- // remember the name of the non-existent table
- // so we can try to download it from the master
- {
- int table_name_len = (uint) strlen(table_name);
- int db_len = (uint) strlen(db);
- thd->last_nx_db = alloc_root(glob_alloc,db_len + table_name_len + 2);
- if(thd->last_nx_db)
- {
- thd->last_nx_table = thd->last_nx_db + db_len + 1;
- memcpy(thd->last_nx_table, table_name, table_name_len + 1);
- memcpy(thd->last_nx_db, db, db_len + 1);
- }
- }
table->next=table->prev=table;
free_cache_entry(table);
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -910,10 +930,11 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
- table->outer_join=table->null_row=table->maybe_null=0;
+ table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
table->status=STATUS_NO_RECORD;
- table->keys_in_use_for_query=table->used_keys= table->keys_in_use;
- dbug_assert(table->key_read == 0);
+ table->keys_in_use_for_query= table->keys_in_use;
+ table->used_keys= table->keys_for_keyread;
+ DBUG_ASSERT(table->key_read == 0);
DBUG_RETURN(table);
}
@@ -957,6 +978,7 @@ bool reopen_table(TABLE *table,bool locked)
#endif
if (!locked)
VOID(pthread_mutex_lock(&LOCK_open));
+ safe_mutex_assert_owner(&LOCK_open);
if (open_unireg_entry(current_thd,&tmp,db,table_name,table->table_name))
goto end;
@@ -977,7 +999,9 @@ bool reopen_table(TABLE *table,bool locked)
tmp.null_row= table->null_row;
tmp.maybe_null= table->maybe_null;
tmp.status= table->status;
- tmp.keys_in_use_for_query=tmp.used_keys=tmp.keys_in_use;
+ tmp.keys_in_use_for_query= tmp.keys_in_use;
+ tmp.used_keys= tmp.keys_for_keyread;
+ tmp.force_index= tmp.force_index;
/* Get state */
tmp.key_length= table->key_length;
@@ -1046,6 +1070,8 @@ bool close_data_tables(THD *thd,const char *db, const char *table_name)
bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
{
DBUG_ENTER("reopen_tables");
+ safe_mutex_assert_owner(&LOCK_open);
+
if (!thd->open_tables)
DBUG_RETURN(0);
@@ -1238,25 +1264,44 @@ bool drop_locked_tables(THD *thd,const char *db, const char *table_name)
}
-/* lock table to force abort of any threads trying to use table */
+/*
+ If we have the table open, which only happens when a LOCK TABLE has been
+ done on the table, change the lock type to a lock that will abort all
+ other threads trying to get the lock.
+*/
void abort_locked_tables(THD *thd,const char *db, const char *table_name)
{
TABLE *table;
- for (table=thd->open_tables; table ; table=table->next)
+ for (table= thd->open_tables; table ; table= table->next)
{
if (!strcmp(table->real_name,table_name) &&
!strcmp(table->table_cache_key,db))
+ {
mysql_lock_abort(thd,table);
+ break;
+ }
}
}
-/****************************************************************************
-** open_unireg_entry
-** Purpose : Load a table definition from file and open unireg table
-** Args : entry with DB and table given
-** Returns : 0 if ok
-** Note that the extra argument for open is taken from thd->open_options
+
+/*
+ Load a table definition from file and open unireg table
+
+ SYNOPSIS
+ open_unireg_entry()
+ thd Thread handle
+ entry Store open table definition here
+ db Database name
+ name Table name
+ alias Alias name
+
+ NOTES
+ Extra argument for open is taken from thd->open_options
+
+ RETURN
+ 0 ok
+ # Error
*/
static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
@@ -1266,7 +1311,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
int error;
DBUG_ENTER("open_unireg_entry");
- (void) sprintf(path,"%s/%s/%s",mysql_data_home,db,name);
+ strxmov(path, mysql_data_home, "/", db, "/", name, NullS);
if (openfrm(path,alias,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
HA_TRY_READ_ONLY),
@@ -1280,6 +1325,8 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
table_list.db=(char*) db;
table_list.real_name=(char*) name;
table_list.next=0;
+ safe_mutex_assert_owner(&LOCK_open);
+
if ((error=lock_table_name(thd,&table_list)))
{
if (error < 0)
@@ -1293,8 +1340,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
}
}
pthread_mutex_unlock(&LOCK_open);
- thd->net.last_error[0]=0; // Clear error message
- thd->net.last_errno=0;
+ thd->clear_error();
error=0;
if (openfrm(path,alias,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
@@ -1305,8 +1351,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
(entry->file->is_crashed() && entry->file->check_and_repair(thd)))
{
/* Give right error message */
- thd->net.last_error[0]=0;
- thd->net.last_errno=0;
+ thd->clear_error();
my_error(ER_NOT_KEYFILE, MYF(0), name, my_errno);
sql_print_error("Error: Couldn't repair table: %s.%s",db,name);
if (entry->file)
@@ -1314,17 +1359,47 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
error=1;
}
else
- {
- thd->net.last_error[0]=0; // Clear error message
- thd->net.last_errno=0;
- }
+ thd->clear_error();
pthread_mutex_lock(&LOCK_open);
unlock_table_name(thd,&table_list);
if (error)
goto err;
}
- (void) entry->file->extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
+ /*
+ If we are here, there was no fatal error (but error may be still
+ unitialized).
+ */
+ if (unlikely(entry->file->implicit_emptied))
+ {
+ entry->file->implicit_emptied= 0;
+ if (mysql_bin_log.is_open())
+ {
+ char *query, *end;
+ uint query_buf_size= 20 + 2*NAME_LEN + 1;
+ if ((query= (char*)my_malloc(query_buf_size,MYF(MY_WME))))
+ {
+ end = strxmov(strmov(query, "DELETE FROM `"),
+ db,"`.`",name,"`", NullS);
+ Query_log_event qinfo(thd, query, (ulong)(end-query), 0);
+ mysql_bin_log.write(&qinfo);
+ my_free(query, MYF(0));
+ }
+ else
+ {
+ /*
+ As replication is maybe going to be corrupted, we need to warn the
+ DBA on top of warning the client (which will automatically be done
+ because of MYF(MY_WME) in my_malloc() above).
+ */
+ sql_print_error("Error: when opening HEAP table, could not allocate \
+memory to write 'DELETE FROM `%s`.`%s`' to the binary log",db,name);
+ if (entry->file)
+ closefrm(entry);
+ goto err;
+ }
+ }
+ }
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
@@ -1347,7 +1422,7 @@ int open_tables(THD *thd,TABLE_LIST *start)
{
if (!tables->table &&
!(tables->table=open_table(thd,
- tables->db ? tables->db : thd->db,
+ tables->db,
tables->real_name,
tables->alias, &refresh)))
{
@@ -1397,6 +1472,61 @@ int open_tables(THD *thd,TABLE_LIST *start)
}
+/*
+ Check that lock is ok for tables; Call start stmt if ok
+
+ SYNOPSIS
+ check_lock_and_start_stmt()
+ thd Thread handle
+ table_list Table to check
+ lock_type Lock used for table
+
+ RETURN VALUES
+ 0 ok
+ 1 error
+*/
+
+static bool check_lock_and_start_stmt(THD *thd, TABLE *table,
+ thr_lock_type lock_type)
+{
+ int error;
+ DBUG_ENTER("check_lock_and_start_stmt");
+
+ if ((int) lock_type >= (int) TL_WRITE_ALLOW_READ &&
+ (int) table->reginfo.lock_type < (int) TL_WRITE_ALLOW_READ)
+ {
+ my_printf_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,
+ ER(ER_TABLE_NOT_LOCKED_FOR_WRITE),
+ MYF(0),table->table_name);
+ DBUG_RETURN(1);
+ }
+ if ((error=table->file->start_stmt(thd)))
+ {
+ table->file->print_error(error,MYF(0));
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Open and lock one table
+
+ SYNOPSIS
+ open_ltable()
+ thd Thread handler
+ table_list Table to open is first table in this list
+ lock_type Lock to use for open
+
+ RETURN VALUES
+ table Opened table
+ 0 Error
+
+ If ok, the following are also set:
+ table_list->lock_type lock_type
+ table_list->table table
+*/
+
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
{
TABLE *table;
@@ -1404,57 +1534,41 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
DBUG_ENTER("open_ltable");
thd->proc_info="Opening table";
- while (!(table=open_table(thd,table_list->db ? table_list->db : thd->db,
- table_list->real_name, table_list->alias,
+ while (!(table=open_table(thd,table_list->db,
+ table_list->real_name,table_list->alias,
&refresh)) && refresh) ;
if (table)
{
- int error;
-
#if defined( __WIN__) || defined(OS2)
/* Win32 can't drop a file that is open */
- if (lock_type == TL_WRITE_ALLOW_READ
-#ifdef HAVE_GEMINI_DB
- && table->db_type != DB_TYPE_GEMINI
-#endif /* HAVE_GEMINI_DB */
- )
+ if (lock_type == TL_WRITE_ALLOW_READ)
{
lock_type= TL_WRITE;
}
#endif /* __WIN__ || OS2 */
-
- table_list->table=table;
+ table_list->lock_type= lock_type;
+ table_list->table= table;
table->grant= table_list->grant;
if (thd->locked_tables)
{
- thd->proc_info=0;
- if ((int) lock_type >= (int) TL_WRITE_ALLOW_READ &&
- (int) table->reginfo.lock_type < (int) TL_WRITE_ALLOW_READ)
- {
- my_printf_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,
- ER(ER_TABLE_NOT_LOCKED_FOR_WRITE),
- MYF(0),table_list->alias);
- table=0;
- }
- else if ((error=table->file->start_stmt(thd)))
- {
- table->file->print_error(error,MYF(0));
- table=0;
- }
- thd->proc_info=0;
- DBUG_RETURN(table);
+ if (check_lock_and_start_stmt(thd, table, lock_type))
+ table= 0;
+ }
+ else
+ {
+ if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
+ if (!(thd->lock=mysql_lock_tables(thd,&table_list->table,1)))
+ table= 0;
}
- if ((table->reginfo.lock_type=lock_type) != TL_UNLOCK)
- if (!(thd->lock=mysql_lock_tables(thd,&table_list->table,1)))
- DBUG_RETURN(0);
}
thd->proc_info=0;
DBUG_RETURN(table);
}
+
/*
-** Open all tables in list and locks them for read.
-** The lock will automaticly be freed by the close_thread_tables
+ Open all tables in list and locks them for read.
+ The lock will automaticly be freed by close_thread_tables()
*/
int open_and_lock_tables(THD *thd,TABLE_LIST *tables)
@@ -1464,10 +1578,27 @@ int open_and_lock_tables(THD *thd,TABLE_LIST *tables)
return 0;
}
+
+/*
+ Lock all tables in list
+
+ SYNOPSIS
+ lock_tables()
+ thd Thread handler
+ tables Tables to lock
+
+ RETURN VALUES
+ 0 ok
+ -1 Error
+*/
+
int lock_tables(THD *thd,TABLE_LIST *tables)
{
TABLE_LIST *table;
- if (tables && !thd->locked_tables)
+ if (!tables)
+ return 0;
+
+ if (!thd->locked_tables)
{
uint count=0;
for (table = tables ; table ; table=table->next)
@@ -1484,10 +1615,9 @@ int lock_tables(THD *thd,TABLE_LIST *tables)
{
for (table = tables ; table ; table=table->next)
{
- int error;
- if ((error=table->table->file->start_stmt(thd)))
+ if (check_lock_and_start_stmt(thd, table->table, table->lock_type))
{
- table->table->file->print_error(error,MYF(0));
+ ha_rollback_stmt(thd);
return -1;
}
}
@@ -1495,10 +1625,11 @@ int lock_tables(THD *thd,TABLE_LIST *tables)
return 0;
}
+
/*
-** Open a single table without table caching and don't set it in open_list
-** Used by alter_table to open a temporary table and when creating
-** a temporary table with CREATE TEMPORARY ...
+ Open a single table without table caching and don't set it in open_list
+ Used by alter_table to open a temporary table and when creating
+ a temporary table with CREATE TEMPORARY ...
*/
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
@@ -1507,13 +1638,15 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
TABLE *tmp_table;
DBUG_ENTER("open_temporary_table");
- // the extra size in my_malloc() is for table_cache_key
- // 4 bytes for master thread id if we are in the slave
- // 1 byte to terminate db
- // 1 byte to terminate table_name
- // total of 6 extra bytes in my_malloc in addition to table/db stuff
+ /*
+ The extra size in my_malloc() is for table_cache_key
+ 4 bytes for master thread id if we are in the slave
+ 1 byte to terminate db
+ 1 byte to terminate table_name
+ total of 6 extra bytes in my_malloc in addition to table/db stuff
+ */
if (!(tmp_table=(TABLE*) my_malloc(sizeof(*tmp_table)+(uint) strlen(db)+
- (uint) strlen(table_name)+6,
+ (uint) strlen(table_name)+6+4,
MYF(MY_WME))))
DBUG_RETURN(0); /* purecov: inspected */
@@ -1527,7 +1660,6 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
DBUG_RETURN(0);
}
- tmp_table->file->extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
tmp_table->reginfo.lock_type=TL_WRITE; // Simulate locked
tmp_table->tmp_table = (tmp_table->file->has_transactions() ?
TRANSACTIONAL_TMP_TABLE : TMP_TABLE);
@@ -1537,6 +1669,9 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
+1), table_name)
- tmp_table->table_cache_key)+1;
int4store(tmp_table->table_cache_key + tmp_table->key_length,
+ thd->server_id);
+ tmp_table->key_length += 4;
+ int4store(tmp_table->table_cache_key + tmp_table->key_length,
thd->slave_proxy_id);
tmp_table->key_length += 4;
@@ -1544,8 +1679,8 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
{
tmp_table->next=thd->temporary_tables;
thd->temporary_tables=tmp_table;
- if(thd->slave_thread)
- ++slave_open_temp_tables;
+ if (thd->slave_thread)
+ slave_open_temp_tables++;
}
DBUG_RETURN(tmp_table);
}
@@ -1605,13 +1740,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
{
field->query_id=thd->query_id;
table->used_fields++;
- if (field->part_of_key)
- {
- if (!(field->part_of_key & table->ref_primary_key))
- table->used_keys&=field->part_of_key;
- }
- else
- table->used_keys=0;
+ table->used_keys&= field->part_of_key;
}
else
thd->dupp_field=field;
@@ -1630,6 +1759,19 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables)
const char *table_name=item->table_name;
const char *name=item->field_name;
uint length=(uint) strlen(name);
+ char name_buff[NAME_LEN+1];
+
+ if (db && lower_case_table_names)
+ {
+ /*
+ convert database to lower case for comparision.
+ We can't do this in Item_field as this would change the
+ 'name' of the item which may be used in the select list
+ */
+ strmake(name_buff, db, sizeof(name_buff)-1);
+ casedn_str(name_buff);
+ db= name_buff;
+ }
if (table_name)
{ /* Qualified field */
@@ -1637,9 +1779,7 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables)
for (; tables ; tables=tables->next)
{
if (!strcmp(tables->alias,table_name) &&
- (!db ||
- (tables->db && !strcmp(db,tables->db)) ||
- (!tables->db && !strcmp(db,thd->db))))
+ (!db || !strcmp(db,tables->db)))
{
found_table=1;
Field *find=find_field_in_table(thd,tables->table,name,length,
@@ -1748,7 +1888,7 @@ find_item_in_list(Item *find,List<Item> &items)
}
}
else if (!table_name && (item->eq(find,0) ||
- find->name &&
+ find->name && item->name &&
!my_strcasecmp(item->name,find->name)))
{
found=li.ref();
@@ -1766,30 +1906,47 @@ find_item_in_list(Item *find,List<Item> &items)
****************************************************************************/
int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
- bool set_query_id, List<Item> *sum_func_list)
+ bool set_query_id, List<Item> *sum_func_list,
+ bool allow_sum_func)
{
reg2 Item *item;
List_iterator<Item> it(fields);
DBUG_ENTER("setup_fields");
thd->set_query_id=set_query_id;
- thd->allow_sum_func= test(sum_func_list);
+ thd->allow_sum_func= allow_sum_func;
thd->where="field list";
while ((item=it++))
{
+ /*
+ Expand * to all fields if this is not the temporary table for an
+ a UNION result
+ */
if (item->type() == Item::FIELD_ITEM &&
- ((Item_field*) item)->field_name[0] == '*')
+ ((Item_field*) item)->field_name[0] == '*' &&
+ !((Item_field*) item)->field)
{
+ uint elem=fields.elements;
if (insert_fields(thd,tables,((Item_field*) item)->db_name,
((Item_field*) item)->table_name,&it))
DBUG_RETURN(-1); /* purecov: inspected */
+ if (sum_func_list)
+ {
+ /*
+ sum_func_list is a list that has the fields list as a tail.
+ Because of this we have to update the element count also for this
+ list after expanding the '*' entry.
+ */
+ sum_func_list->elements+= fields.elements - elem;
+ }
}
else
{
if (item->fix_fields(thd,tables))
DBUG_RETURN(-1); /* purecov: inspected */
- if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
+ if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
+ sum_func_list)
item->split_sum_func(*sum_func_list);
thd->used_tables|=item->used_tables();
}
@@ -1808,29 +1965,44 @@ bool setup_tables(TABLE_LIST *tables)
{
DBUG_ENTER("setup_tables");
uint tablenr=0;
- for (TABLE_LIST *table=tables ; table ; table=table->next,tablenr++)
- {
- table->table->tablenr=tablenr;
- table->table->map= (table_map) 1 << tablenr;
- if ((table->table->outer_join=table->outer_join))
- table->table->maybe_null=1; // LEFT OUTER JOIN ...
- if (table->use_index)
+ for (TABLE_LIST *table_list=tables ; table_list ;
+ table_list=table_list->next,tablenr++)
+ {
+ TABLE *table=table_list->table;
+
+ table->used_fields=0;
+ table->const_table=0;
+ table->null_row=0;
+ table->status=STATUS_NO_RECORD;
+ table->keys_in_use_for_query= table->keys_in_use;
+ table->used_keys= table->keys_for_keyread;
+ table->maybe_null=test(table->outer_join= table_list->outer_join);
+ table->tablenr=tablenr;
+ table->map= (table_map) 1 << tablenr;
+ table->force_index= table_list->force_index;
+ if (table_list->use_index)
{
- key_map map= get_key_map_from_key_list(table->table,
- table->use_index);
+ key_map map= get_key_map_from_key_list(table,
+ table_list->use_index);
if (map == ~(key_map) 0)
DBUG_RETURN(1);
- table->table->keys_in_use_for_query=map;
+ table->keys_in_use_for_query=map;
}
- if (table->ignore_index)
+ if (table_list->ignore_index)
{
- key_map map= get_key_map_from_key_list(table->table,
- table->ignore_index);
+ key_map map= get_key_map_from_key_list(table,
+ table_list->ignore_index);
if (map == ~(key_map) 0)
DBUG_RETURN(1);
- table->table->keys_in_use_for_query &= ~map;
+ table->keys_in_use_for_query &= ~map;
+ }
+ table->used_keys &= table->keys_in_use_for_query;
+ if (table_list->shared)
+ {
+ /* Clear query_id that may have been set by previous select */
+ for (Field **ptr=table->field ; *ptr ; ptr++)
+ (*ptr)->query_id=0;
}
- table->table->used_keys &= table->table->keys_in_use_for_query;
}
if (tablenr > MAX_TABLES)
{
@@ -1845,7 +2017,7 @@ static key_map get_key_map_from_key_list(TABLE *table,
List<String> *index_list)
{
key_map map=0;
- List_iterator<String> it(*index_list);
+ List_iterator_fast<String> it(*index_list);
String *name;
uint pos;
while ((name=it++))
@@ -1862,11 +2034,11 @@ static key_map get_key_map_from_key_list(TABLE *table,
}
/****************************************************************************
-** This just drops in all fields instead of current '*' field
-** Returns pointer to last inserted field if ok
+ This just drops in all fields instead of current '*' field
+ Returns pointer to last inserted field if ok
****************************************************************************/
-static bool
+bool
insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
const char *table_name, List_iterator<Item> *it)
{
@@ -1878,9 +2050,9 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
{
TABLE *table=tables->table;
if (!table_name || (!strcmp(table_name,tables->alias) &&
- (!db_name || !tables->db ||
- !strcmp(tables->db,db_name))))
+ (!db_name || !strcmp(tables->db,db_name))))
{
+ /* Ensure that we have access right to all columns */
if (!(table->grant.privilege & SELECT_ACL) &&
check_grant_all_columns(thd,SELECT_ACL,table))
DBUG_RETURN(-1);
@@ -1891,20 +2063,17 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
{
Item_field *item= new Item_field(field);
if (!found++)
- (void) it->replace(item);
+ (void) it->replace(item); // Replace '*'
else
it->after(item);
+ /*
+ Mark if field used before in this select.
+ Used by 'insert' to verify if a field name is used twice
+ */
if (field->query_id == thd->query_id)
thd->dupp_field=field;
field->query_id=thd->query_id;
-
- if (field->part_of_key)
- {
- if (!(field->part_of_key & table->ref_primary_key))
- table->used_keys&=field->part_of_key;
- }
- else
- table->used_keys=0;
+ table->used_keys&= field->part_of_key;
}
/* All fields are used */
table->used_fields=table->fields;
@@ -1927,6 +2096,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
+ table_map not_null_tables= 0;
DBUG_ENTER("setup_conds");
thd->set_query_id=1;
thd->cond_count=0;
@@ -1936,6 +2106,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
thd->where="where clause";
if ((*conds)->fix_fields(thd,tables))
DBUG_RETURN(1);
+ not_null_tables= (*conds)->not_null_tables();
}
/* Check if we are using outer joins */
@@ -1949,9 +2120,15 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
DBUG_RETURN(1);
thd->cond_count++;
- /* If it's a normal join, add the ON/USING expression to the WHERE */
- if (!table->outer_join)
+ /*
+ If it's a normal join or a LEFT JOIN which can be optimized away
+ add the ON/USING expression to the WHERE
+ */
+ if (!table->outer_join ||
+ ((table->table->map & not_null_tables) &&
+ !(specialflag & SPECIAL_NO_NEW_FUNC)))
{
+ table->outer_join= 0;
if (!(*conds=and_conds(*conds, table->on_expr)))
DBUG_RETURN(1);
table->on_expr=0;
@@ -1965,6 +2142,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
Item_cond_and *cond_and=new Item_cond_and();
if (!cond_and) // If not out of memory
DBUG_RETURN(1);
+ cond_and->top_level_item();
uint i,j;
for (i=0 ; i < t1->fields ; i++)
@@ -1972,7 +2150,6 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
// TODO: This could be optimized to use hashed names if t2 had a hash
for (j=0 ; j < t2->fields ; j++)
{
- key_map tmp_map;
if (!my_strcasecmp(t1->field[i]->field_name,
t2->field[j]->field_name))
{
@@ -1985,20 +2162,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
/* Mark field used for table cache */
t1->field[i]->query_id=t2->field[j]->query_id=thd->query_id;
cond_and->list.push_back(tmp);
- if ((tmp_map=t1->field[i]->part_of_key))
- {
- if (!(tmp_map & t1->ref_primary_key))
- t1->used_keys&=tmp_map;
- }
- else
- t1->used_keys=0;
- if ((tmp_map=t2->field[j]->part_of_key))
- {
- if (!(tmp_map & t2->ref_primary_key))
- t2->used_keys&=tmp_map;
- }
- else
- t2->used_keys=0;
+ t1->used_keys&= t1->field[i]->part_of_key;
+ t2->used_keys&= t2->field[j]->part_of_key;
break;
}
}
@@ -2024,9 +2189,9 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
******************************************************************************/
int
-fill_record(List<Item> &fields,List<Item> &values)
+fill_record(List<Item> &fields,List<Item> &values, bool ignore_errors)
{
- List_iterator<Item> f(fields),v(values);
+ List_iterator_fast<Item> f(fields),v(values);
Item *value;
Item_field *field;
DBUG_ENTER("fill_record");
@@ -2034,7 +2199,7 @@ fill_record(List<Item> &fields,List<Item> &values)
while ((field=(Item_field*) f++))
{
value=v++;
- if (value->save_in_field(field->field))
+ if (value->save_in_field(field->field, 0) && !ignore_errors)
DBUG_RETURN(1);
}
DBUG_RETURN(0);
@@ -2042,9 +2207,9 @@ fill_record(List<Item> &fields,List<Item> &values)
int
-fill_record(Field **ptr,List<Item> &values)
+fill_record(Field **ptr,List<Item> &values, bool ignore_errors)
{
- List_iterator<Item> v(values);
+ List_iterator_fast<Item> v(values);
Item *value;
DBUG_ENTER("fill_record");
@@ -2052,7 +2217,7 @@ fill_record(Field **ptr,List<Item> &values)
while ((field = *ptr++))
{
value=v++;
- if (value->save_in_field(field))
+ if (value->save_in_field(field, 0) && !ignore_errors)
DBUG_RETURN(1);
}
DBUG_RETURN(0);
@@ -2107,7 +2272,8 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
create_info.db_type=DB_TYPE_DEFAULT;
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list,
- fields, keys, drop, alter, (ORDER*)0, FALSE, DUP_ERROR));
+ fields, keys, drop, alter, (ORDER*)0, FALSE,
+ DUP_ERROR));
}
@@ -2122,7 +2288,8 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
create_info.db_type=DB_TYPE_DEFAULT;
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list,
- fields, keys, drop, alter, (ORDER*)0, FALSE, DUP_ERROR));
+ fields, keys, drop, alter, (ORDER*)0, FALSE,
+ DUP_ERROR));
}
/*****************************************************************************
@@ -2187,7 +2354,10 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
THD *in_use;
table->version=0L; /* Free when thread is ready */
if (!(in_use=table->in_use))
+ {
+ DBUG_PRINT("info",("Table was not in use"));
relink_unused(table);
+ }
else if (in_use != thd)
{
in_use->some_tables_deleted=1;
@@ -2206,6 +2376,17 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
}
pthread_mutex_unlock(&in_use->mysys_var->mutex);
}
+ /*
+ Now we must abort all tables locks used by this thread
+ as the thread may be waiting to get a lock for another table
+ */
+ for (TABLE *thd_table= in_use->open_tables;
+ thd_table ;
+ thd_table= thd_table->next)
+ {
+ if (thd_table->db_stat) // If table is open
+ mysql_lock_abort_for_thread(thd, thd_table);
+ }
}
else
result= result || return_if_owned_by_thd;
@@ -2217,8 +2398,8 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
int setup_ftfuncs(THD *thd)
{
- List_iterator<Item_func_match> li(thd->lex.ftfunc_list),
- lj(thd->lex.ftfunc_list);
+ List_iterator<Item_func_match> li(thd->lex.select->ftfunc_list),
+ lj(thd->lex.select->ftfunc_list);
Item_func_match *ftf, *ftf2;
while ((ftf=li++))
@@ -2239,9 +2420,9 @@ int setup_ftfuncs(THD *thd)
int init_ftfuncs(THD *thd, bool no_order)
{
- if (thd->lex.ftfunc_list.elements)
+ if (thd->lex.select->ftfunc_list.elements)
{
- List_iterator<Item_func_match> li(thd->lex.ftfunc_list);
+ List_iterator<Item_func_match> li(thd->lex.select->ftfunc_list);
Item_func_match *ifm;
DBUG_PRINT("info",("Performing FULLTEXT search"));
thd->proc_info="FULLTEXT initialization";
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 09d436c0c9c..63d4e4222b4 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1,98 +1,3584 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/*
+ Description of the query cache:
+
+1. Query_cache object consists of
+ - query cache memory pool (cache)
+ - queries hash (queries)
+ - tables hash (tables)
+ - list of blocks ordered as they allocated in memory
+(first_block)
+ - list of queries block (queries_blocks)
+ - list of used tables (tables_blocks)
+
+2. Query cache memory pool (cache) consists of
+ - table of steps of memory bins allocation
+ - table of free memory bins
+ - blocks of memory
+
+3. Memory blocks
+
+Every memory block has the following structure:
+
++----------------------------------------------------------+
+| Block header (Query_cache_block structure) |
++----------------------------------------------------------+
+|Table of database table lists (used for queries & tables) |
++----------------------------------------------------------+
+| Type depended header |
+|(Query_cache_query, Query_cache_table, Query_cache_result)|
++----------------------------------------------------------+
+| Data ... |
++----------------------------------------------------------+
+
+Block header consists of:
+- type:
+ FREE Free memory block
+ QUERY Query block
+ RESULT Ready to send result
+ RES_CONT Result's continuation
+ RES_BEG First block of results, that is not yet complete,
+ written to cache
+ RES_INCOMPLETE Allocated for results data block
+ TABLE Block with database table description
+ INCOMPLETE The destroyed block
+- length of block (length)
+- length of data & headers (used)
+- physical list links (pnext/pprev) - used for the list of
+ blocks ordered as they are allocated in physical memory
+- logical list links (next/prev) - used for queries block list, tables block
+ list, free memory block lists and list of results block in query
+- number of elements in table of database table list (n_tables)
+
+4. Query & results blocks
+
+Query stored in cache consists of following blocks:
+
+more more
+recent+-------------+ old
+<-----|Query block 1|------> double linked list of queries block
+ prev | | next
+ +-------------+
+ <-| table 0 |-> (see "Table of database table lists" description)
+ <-| table 1 |->
+ | ... | +--------------------------+
+ +-------------+ +-------------------------+ |
+NET | | | V V |
+struct| | +-+------------+ +------------+ |
+<-----|query header |----->|Result block|-->|Result block|-+ doublelinked
+writer| |result| |<--| | list of results
+ +-------------+ +------------+ +------------+
+ |charset | +------------+ +------------+ no table of dbtables
+ |encoding + | | result | | result |
+ |query text |<-----| header | | header |------+
+ +-------------+parent| | | |parent|
+ ^ +------------+ +------------+ |
+ | |result data | |result data | |
+ | +------------+ +------------+ |
+ +---------------------------------------------------+
+
+First query is registered. During the registration query block is
+allocated. This query block is included in query hash and is linked
+with appropriate database tables lists (if there is no appropriate
+list exists it will be created).
+
+Later when query has performed results is written into the result blocks.
+A result block cannot be smaller then QUERY_CACHE_MIN_RESULT_DATA_SIZE.
+
+When new result is written to cache it is appended to the last result
+block, if no more free space left in the last block, new block is
+allocated.
+
+5. Table of database table lists.
+
+For quick invalidation of queries all query are linked in lists on used
+database tables basis (when table will be changed (insert/delete/...)
+this queries will be removed from cache).
+
+Root of such list is table block:
+
+ +------------+ list of used tables (used while invalidation of
+<----| Table |-----> whole database)
+ prev| block |next +-----------+
+ | | +-----------+ |Query block|
+ | | |Query block| +-----------+
+ +------------+ +-----------+ | ... |
+ +->| table 0 |------>|table 0 |----->| table N |---+
+ |+-| |<------| |<-----| |<-+|
+ || +------------+ | ... | | ... | ||
+ || |table header| +-----------+ +-----------+ ||
+ || +------------+ | ... | | ... | ||
+ || |db name + | +-----------+ +-----------+ ||
+ || |table name | ||
+ || +------------+ ||
+ |+--------------------------------------------------------+|
+ +----------------------------------------------------------+
+
+Table block is included into the tables hash (tables).
+
+6. Free blocks, free blocks bins & steps of freeblock bins.
+
+When we just started only one free memory block existed. All query
+cache memory (that will be used for block allocation) were
+containing in this block.
+When a new block is allocated we find most suitable memory block
+(minimal of >= required size). If such a block can not be found, we try
+to find max block < required size (if we allocate block for results).
+If there is no free memory, oldest query is removed from cache, and then
+we try to allocate memory. Last step should be repeated until we find
+suitable block or until there is no unlocked query found.
+
+If the block is found and its length more then we need, it should be
+split into 2 blocks.
+New blocks cannot be smaller then min_allocation_unit_bytes.
+
+When a block becomes free, its neighbor-blocks should be tested and if
+there are free blocks among them, they should be joined into one block.
+
+Free memory blocks are stored in bins according to their sizes.
+The bins are stored in size-descending order.
+These bins are distributed (by size) approximately logarithmically.
+
+First bin (number 0) stores free blocks with
+size <= query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2.
+It is first (number 0) step.
+On the next step distributed (1 + QUERY_CACHE_MEM_BIN_PARTS_INC) *
+QUERY_CACHE_MEM_BIN_PARTS_MUL bins. This bins allocated in interval from
+query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 to
+query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 >>
+QUERY_CACHE_MEM_BIN_STEP_PWR2
+...
+On each step interval decreases in 2 power of
+QUERY_CACHE_MEM_BIN_STEP_PWR2
+times, number of bins (that distributed on this step) increases. If on
+the previous step there were N bins distributed , on the current there
+would be distributed
+(N + QUERY_CACHE_MEM_BIN_PARTS_INC) * QUERY_CACHE_MEM_BIN_PARTS_MUL
+bins.
+Last distributed bin stores blocks with size near min_allocation_unit
+bytes.
+
+For example:
+ query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 = 100,
+ min_allocation_unit = 17,
+ QUERY_CACHE_MEM_BIN_STEP_PWR2 = 1,
+ QUERY_CACHE_MEM_BIN_PARTS_INC = 1,
+ QUERY_CACHE_MEM_BIN_PARTS_MUL = 1
+ (in followed picture showed right (low) bound of bin):
+
+ | 100>>1 50>>1 |25>>1|
+ | | | | | |
+ | 100 75 50 41 33 25 21 18 15| 12 | - bins right (low) bounds
+
+ |\---/\-----/\--------/\--------|---/ |
+ | 0 1 2 3 | | - steps
+ \-----------------------------/ \---/
+ bins that we store in cache this bin showed for example only
+
+
+Calculation of steps/bins distribution is performed only when query cache
+is resized.
+
+When we need to find appropriate bin, first we should find appropriate
+step, then we should calculate number of bins that are using data
+stored in Query_cache_memory_bin_step structure.
+
+Free memory blocks are sorted in bins in lists with size-ascending order
+(more small blocks needed frequently then bigger one).
+
+7. Packing cache.
+
+Query cache packing is divided into two operation:
+ - pack_cache
+ - join_results
+
+pack_cache moved all blocks to "top" of cache and create one block of free
+space at the "bottom":
+
+ before pack_cache after pack_cache
+ +-------------+ +-------------+
+ | query 1 | | query 1 |
+ +-------------+ +-------------+
+ | table 1 | | table 1 |
+ +-------------+ +-------------+
+ | results 1.1 | | results 1.1 |
+ +-------------+ +-------------+
+ | free | | query 2 |
+ +-------------+ +-------------+
+ | query 2 | | table 2 |
+ +-------------+ ---> +-------------+
+ | table 2 | | results 1.2 |
+ +-------------+ +-------------+
+ | results 1.2 | | results 2 |
+ +-------------+ +-------------+
+ | free | | free |
+ +-------------+ | |
+ | results 2 | | |
+ +-------------+ | |
+ | free | | |
+ +-------------+ +-------------+
+
+pack_cache scan blocks in physical address order and move every non-free
+block "higher".
+
+pack_cach remove every free block it finds. The length of the deleted block
+is accumulated to the "gap". All non free blocks should be shifted with the
+"gap" step.
+
+join_results scans all complete queries. If the results of query are not
+stored in the same block, join_results tries to move results so, that they
+are stored in one block.
+
+ before join_results after join_results
+ +-------------+ +-------------+
+ | query 1 | | query 1 |
+ +-------------+ +-------------+
+ | table 1 | | table 1 |
+ +-------------+ +-------------+
+ | results 1.1 | | free |
+ +-------------+ +-------------+
+ | query 2 | | query 2 |
+ +-------------+ +-------------+
+ | table 2 | | table 2 |
+ +-------------+ ---> +-------------+
+ | results 1.2 | | free |
+ +-------------+ +-------------+
+ | results 2 | | results 2 |
+ +-------------+ +-------------+
+ | free | | results 1 |
+ | | | |
+ | | +-------------+
+ | | | free |
+ | | | |
+ +-------------+ +-------------+
+
+If join_results allocated new block(s) then we need call pack_cache again.
+
+TODO list:
+
+ - Delayed till after-parsing qache answer (for column rights processing)
+ - Optimize cache resizing
+ - if new_size < old_size then pack & shrink
+ - if new_size > old_size copy cached query to new cache
+ - Move MRG_MYISAM table type processing to handlers, something like:
+ tables_used->table->file->register_used_filenames(callback,
+ first_argument);
+*/
+
#include "mysql_priv.h"
+#ifdef HAVE_QUERY_CACHE
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
+#include "sql_acl.h"
+#include "ha_myisammrg.h"
+#ifndef MASTER
+#include "../srclib/myisammrg/myrg_def.h"
+#else
+#include "../myisammrg/myrg_def.h"
+#endif
+#include <assert.h>
-#define SQL_CACHE_LENGTH 30 // 300 crashes apple gcc.
+#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
+#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
+ pthread_mutex_lock(M);}
+#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
+ (ulong)(M))); pthread_mutex_unlock(M);}
+#define RW_WLOCK(M) {DBUG_PRINT("lock", ("rwlock wlock 0x%lx",(ulong)(M))); \
+ if (!rw_wrlock(M)) DBUG_PRINT("lock", ("rwlock wlock ok")) \
+ else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); }
+#define RW_RLOCK(M) {DBUG_PRINT("lock", ("rwlock rlock 0x%lx", (ulong)(M))); \
+ if (!rw_rdlock(M)) DBUG_PRINT("lock", ("rwlock rlock ok")) \
+ else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); }
+#define RW_UNLOCK(M) {DBUG_PRINT("lock", ("rwlock unlock 0x%lx",(ulong)(M))); \
+ if (!rw_unlock(M)) DBUG_PRINT("lock", ("rwlock unlock ok")) \
+ else DBUG_PRINT("lock", ("rwlock unlock FAILED %d", errno)); }
+#define STRUCT_LOCK(M) {DBUG_PRINT("lock", ("%d struct lock...",__LINE__)); \
+ pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));}
+#define STRUCT_UNLOCK(M) { \
+ DBUG_PRINT("lock", ("%d struct unlock...",__LINE__)); \
+ pthread_mutex_unlock(M);DBUG_PRINT("lock", ("struct unlock OK"));}
+#define BLOCK_LOCK_WR(B) {DBUG_PRINT("lock", ("%d LOCK_WR 0x%lx",\
+ __LINE__,(ulong)(B))); \
+ B->query()->lock_writing();}
+#define BLOCK_LOCK_RD(B) {DBUG_PRINT("lock", ("%d LOCK_RD 0x%lx",\
+ __LINE__,(ulong)(B))); \
+ B->query()->lock_reading();}
+#define BLOCK_UNLOCK_WR(B) { \
+ DBUG_PRINT("lock", ("%d UNLOCK_WR 0x%lx",\
+ __LINE__,(ulong)(B)));B->query()->unlock_writing();}
+#define BLOCK_UNLOCK_RD(B) { \
+ DBUG_PRINT("lock", ("%d UNLOCK_RD 0x%lx",\
+ __LINE__,(ulong)(B)));B->query()->unlock_reading();}
+#define DUMP(C) DBUG_EXECUTE("qcache", {\
+ (C)->cache_dump(); (C)->queries_dump();(C)->tables_dump();})
+#else
+#define MUTEX_LOCK(M) pthread_mutex_lock(M)
+#define MUTEX_UNLOCK(M) pthread_mutex_unlock(M)
+#define RW_WLOCK(M) rw_wrlock(M)
+#define RW_RLOCK(M) rw_rdlock(M)
+#define RW_UNLOCK(M) rw_unlock(M)
+#define STRUCT_LOCK(M) pthread_mutex_lock(M)
+#define STRUCT_UNLOCK(M) pthread_mutex_unlock(M)
+#define BLOCK_LOCK_WR(B) B->query()->lock_writing()
+#define BLOCK_LOCK_RD(B) B->query()->lock_reading()
+#define BLOCK_UNLOCK_WR(B) B->query()->unlock_writing()
+#define BLOCK_UNLOCK_RD(B) B->query()->unlock_reading()
+#define DUMP(C)
+#endif
-HASH sql_cache;
-static LEX lex_array_static[SQL_CACHE_LENGTH];
-LEX * lex_array = lex_array_static;
-int last_lex_array_item = SQL_CACHE_LENGTH - 1;
+#ifdef FN_NO_CASE_SENCE
+#define DB_NAME_PREPROCESS(C) tolower(C)
+#else
+#define DB_NAME_PREPROCESS(C) (C)
+#endif
-/* Function to return a text string from a LEX struct */
-static byte *cache_key(const byte *record, uint *length, my_bool not_used)
+const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND",NullS };
+TYPELIB query_cache_type_typelib=
{
-#ifdef QQ
- LEX *lex=(LEX*) record;
- *length = lex->sql_query_length;
- // *length = strlen(lex->ptr);
- return (byte*) lex->sql_query_text;
- // return (byte*) lex->ptr;
+ array_elements(query_cache_type_names)-1,"", query_cache_type_names
+};
+
+/*****************************************************************************
+ Query_cache_block_table method(s)
+*****************************************************************************/
+
+inline Query_cache_block * Query_cache_block_table::block()
+{
+ return (Query_cache_block *)(((byte*)this) -
+ ALIGN_SIZE(sizeof(Query_cache_block_table)*n) -
+ ALIGN_SIZE(sizeof(Query_cache_block)));
+};
+
+/*****************************************************************************
+ Query_cache_block method(s)
+*****************************************************************************/
+
+void Query_cache_block::init(ulong block_length)
+{
+ DBUG_ENTER("Query_cache_block::init");
+ DBUG_PRINT("qcache", ("init block 0x%lx length: %lu", (ulong) this,
+ block_length));
+ length = block_length;
+ used = 0;
+ type = Query_cache_block::FREE;
+ n_tables = 0;
+ DBUG_VOID_RETURN;
+}
+
+void Query_cache_block::destroy()
+{
+ DBUG_ENTER("Query_cache_block::destroy");
+ DBUG_PRINT("qcache", ("destroy block 0x%lx, type %d",
+ (ulong) this, type));
+ type = INCOMPLETE;
+ DBUG_VOID_RETURN;
+}
+
+inline uint Query_cache_block::headers_len()
+{
+ return (ALIGN_SIZE(sizeof(Query_cache_block_table)*n_tables) +
+ ALIGN_SIZE(sizeof(Query_cache_block)));
+}
+
+inline gptr Query_cache_block::data(void)
+{
+ return (gptr)( ((byte*)this) + headers_len() );
+}
+
+inline Query_cache_query * Query_cache_block::query()
+{
+#ifndef DBUG_OFF
+ if (type != QUERY)
+ query_cache.wreck(__LINE__, "incorrect block type");
+#endif
+ return (Query_cache_query *) data();
+}
+
+inline Query_cache_table * Query_cache_block::table()
+{
+#ifndef DBUG_OFF
+ if (type != TABLE)
+ query_cache.wreck(__LINE__, "incorrect block type");
+#endif
+ return (Query_cache_table *) data();
+}
+
+inline Query_cache_result * Query_cache_block::result()
+{
+#ifndef DBUG_OFF
+ if (type != RESULT && type != RES_CONT && type != RES_BEG &&
+ type != RES_INCOMPLETE)
+ query_cache.wreck(__LINE__, "incorrect block type");
#endif
- return 0;
+ return (Query_cache_result *) data();
+}
+
+inline Query_cache_block_table * Query_cache_block::table(TABLE_COUNTER_TYPE n)
+{
+ return ((Query_cache_block_table *)
+ (((byte*)this)+ALIGN_SIZE(sizeof(Query_cache_block)) +
+ n*sizeof(Query_cache_block_table)));
+}
+
+
+/*****************************************************************************
+ * Query_cache_table method(s)
+ *****************************************************************************/
+
+extern "C"
+{
+byte *query_cache_table_get_key(const byte *record, uint *length,
+ my_bool not_used __attribute__((unused)))
+{
+ Query_cache_block* table_block = (Query_cache_block*) record;
+ *length = (table_block->used - table_block->headers_len() -
+ ALIGN_SIZE(sizeof(Query_cache_table)));
+ return (((byte *) table_block->data()) +
+ ALIGN_SIZE(sizeof(Query_cache_table)));
+}
+}
+
+/*****************************************************************************
+ Query_cache_query methods
+*****************************************************************************/
+
+/*
+ Following methods work for block read/write locking only in this
+ particular case and in interaction with structure_guard_mutex.
+
+ Lock for write prevents any other locking. (exclusive use)
+ Lock for read prevents only locking for write.
+*/
+
+inline void Query_cache_query::lock_writing()
+{
+ RW_WLOCK(&lock);
+}
+
+
+/*
+ Needed for finding queries, that we may delete from cache.
+ We don't want to wait while block become unlocked. In addition,
+ block locking means that query is now used and we don't need to
+ remove it.
+*/
+
+my_bool Query_cache_query::try_lock_writing()
+{
+ DBUG_ENTER("Query_cache_block::try_lock_writing");
+ if (rw_trywrlock(&lock)!=0)
+ {
+ DBUG_PRINT("info", ("can't lock rwlock"));
+ DBUG_RETURN(0);
+ }
+ DBUG_PRINT("info", ("rwlock 0x%lx locked", (ulong) &lock));
+ DBUG_RETURN(1);
+}
+
+
+inline void Query_cache_query::lock_reading()
+{
+ RW_RLOCK(&lock);
+}
+
+
+inline void Query_cache_query::unlock_writing()
+{
+ RW_UNLOCK(&lock);
+}
+
+
+inline void Query_cache_query::unlock_reading()
+{
+ RW_UNLOCK(&lock);
+}
+
+
+void Query_cache_query::init_n_lock()
+{
+ DBUG_ENTER("Query_cache_query::init_n_lock");
+ res=0; wri = 0; len = 0;
+ my_rwlock_init(&lock, NULL);
+ lock_writing();
+ DBUG_PRINT("qcache", ("inited & locked query for block 0x%lx",
+ ((byte*) this)-ALIGN_SIZE(sizeof(Query_cache_block))));
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache_query::unlock_n_destroy()
+{
+ DBUG_ENTER("Query_cache_query::unlock_n_destroy");
+ DBUG_PRINT("qcache", ("destroyed & unlocked query for block 0x%lx",
+ ((byte*)this)-ALIGN_SIZE(sizeof(Query_cache_block))));
+ /*
+ The following call is not needed on system where one can destroy an
+ active semaphore
+ */
+ this->unlock_writing();
+ rwlock_destroy(&lock);
+ DBUG_VOID_RETURN;
+}
+
+
+extern "C"
+{
+byte *query_cache_query_get_key(const byte *record, uint *length,
+ my_bool not_used)
+{
+ Query_cache_block *query_block = (Query_cache_block*) record;
+ *length = (query_block->used - query_block->headers_len() -
+ ALIGN_SIZE(sizeof(Query_cache_query)));
+ return (((byte *) query_block->data()) +
+ ALIGN_SIZE(sizeof(Query_cache_query)));
+}
+}
+
+/*****************************************************************************
+ Functions to store things into the query cache
+*****************************************************************************/
+
+/*
+ Insert the packet into the query cache.
+ This should only be called if net->query_cache_query != 0
+*/
+
+void query_cache_insert(NET *net, const char *packet, ulong length)
+{
+ DBUG_ENTER("query_cache_insert");
+
+#ifndef DBUG_OFF
+ // Check if we have called query_cache.wreck() (which disables the cache)
+ if (query_cache.query_cache_size == 0)
+ DBUG_VOID_RETURN;
+#endif
+
+ STRUCT_LOCK(&query_cache.structure_guard_mutex);
+ Query_cache_block *query_block = ((Query_cache_block*)
+ net->query_cache_query);
+ if (query_block)
+ {
+ Query_cache_query *header = query_block->query();
+ Query_cache_block *result = header->result();
+
+ DUMP(&query_cache);
+ BLOCK_LOCK_WR(query_block);
+ DBUG_PRINT("qcache", ("insert packet %lu bytes long",length));
+
+ /*
+ On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be
+ done by query_cache.append_result_data if success (if not we need
+ query_cache.structure_guard_mutex locked to free query)
+ */
+ if (!query_cache.append_result_data(&result, length, (gptr) packet,
+ query_block))
+ {
+ query_cache.refused++;
+ DBUG_PRINT("warning", ("Can't append data"));
+ header->result(result);
+ DBUG_PRINT("qcache", ("free query 0x%lx", (ulong) query_block));
+ // The following call will remove the lock on query_block
+ query_cache.free_query(query_block);
+ // append_result_data no success => we need unlock
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ DBUG_VOID_RETURN;
+ }
+ header->result(result);
+ BLOCK_UNLOCK_WR(query_block);
+ }
+ else
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
+ DBUG_VOID_RETURN;
+}
+
+
+void query_cache_abort(NET *net)
+{
+ DBUG_ENTER("query_cache_abort");
+
+#ifndef DBUG_OFF
+ // Check if we have called query_cache.wreck() (which disables the cache)
+ if (query_cache.query_cache_size == 0)
+ DBUG_VOID_RETURN;
+#endif
+ if (net->query_cache_query != 0) // Quick check on unlocked structure
+ {
+ STRUCT_LOCK(&query_cache.structure_guard_mutex);
+ Query_cache_block *query_block = ((Query_cache_block*)
+ net->query_cache_query);
+ if (query_block) // Test if changed by other thread
+ {
+ DUMP(&query_cache);
+ BLOCK_LOCK_WR(query_block);
+ // The following call will remove the lock on query_block
+ query_cache.free_query(query_block);
+ }
+ net->query_cache_query=0;
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void query_cache_end_of_result(NET *net)
+{
+ DBUG_ENTER("query_cache_end_of_result");
+
+#ifndef DBUG_OFF
+ // Check if we have called query_cache.wreck() (which disables the cache)
+ if (query_cache.query_cache_size == 0) DBUG_VOID_RETURN;
+#endif
+
+ if (net->query_cache_query != 0) // Quick check on unlocked structure
+ {
+ STRUCT_LOCK(&query_cache.structure_guard_mutex);
+ Query_cache_block *query_block = ((Query_cache_block*)
+ net->query_cache_query);
+ if (query_block)
+ {
+ DUMP(&query_cache);
+ BLOCK_LOCK_WR(query_block);
+ Query_cache_query *header = query_block->query();
+ Query_cache_block *last_result_block = header->result()->prev;
+ ulong allign_size = ALIGN_SIZE(last_result_block->used);
+ ulong len = max(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+
+#ifndef DBUG_OFF
+ if (header->result() == 0)
+ {
+ DBUG_PRINT("error", ("end of data whith no result. query '%s'",
+ header->query()));
+ query_cache.wreck(__LINE__, "");
+ DBUG_VOID_RETURN;
+ }
+#endif
+ header->found_rows(current_thd->limit_found_rows);
+ header->result()->type = Query_cache_block::RESULT;
+ header->writer(0);
+ BLOCK_UNLOCK_WR(query_block);
+ }
+ else
+ {
+ // Cache was flushed or resized and query was deleted => do nothing
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ }
+ net->query_cache_query=0;
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
+ }
+ DBUG_VOID_RETURN;
+}
+
+void query_cache_invalidate_by_MyISAM_filename(const char *filename)
+{
+ query_cache.invalidate_by_MyISAM_filename(filename);
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
+}
+
+
+/*****************************************************************************
+ Query_cache methods
+*****************************************************************************/
+
+Query_cache::Query_cache(ulong query_cache_limit_arg,
+ ulong min_allocation_unit_arg,
+ ulong min_result_data_size_arg,
+ uint def_query_hash_size_arg,
+ uint def_table_hash_size_arg)
+ :query_cache_size(0),
+ query_cache_limit(query_cache_limit_arg),
+ queries_in_cache(0), hits(0), inserts(0), refused(0),
+ total_blocks(0), lowmem_prunes(0),
+ min_allocation_unit(ALIGN_SIZE(min_allocation_unit_arg)),
+ min_result_data_size(ALIGN_SIZE(min_result_data_size_arg)),
+ def_query_hash_size(ALIGN_SIZE(def_query_hash_size_arg)),
+ def_table_hash_size(ALIGN_SIZE(def_table_hash_size_arg)),
+ initialized(0)
+{
+ ulong min_needed= (ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(sizeof(Query_cache_block_table)) +
+ ALIGN_SIZE(sizeof(Query_cache_query)) + 3);
+ set_if_bigger(min_allocation_unit,min_needed);
+ this->min_allocation_unit= ALIGN_SIZE(min_allocation_unit);
+ set_if_bigger(this->min_result_data_size,min_allocation_unit);
+}
+
+
+ulong Query_cache::resize(ulong query_cache_size_arg)
+{
+ DBUG_ENTER("Query_cache::resize");
+ DBUG_PRINT("qcache", ("from %lu to %lu",query_cache_size,
+ query_cache_size_arg));
+ free_cache(0);
+ query_cache_size= query_cache_size_arg;
+ DBUG_RETURN(::query_cache_size= init_cache());
+}
+
+
+void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
+{
+ TABLE_COUNTER_TYPE local_tables;
+ ulong tot_length;
+ DBUG_ENTER("Query_cache::store_query");
+ if (query_cache_size == 0)
+ DBUG_VOID_RETURN;
+
+ if ((local_tables= is_cacheable(thd, thd->query_length,
+ thd->query, &thd->lex, tables_used)))
+ {
+ NET *net= &thd->net;
+ byte flags= (thd->client_capabilities & CLIENT_LONG_FLAG ? 0x80 : 0);
+ STRUCT_LOCK(&structure_guard_mutex);
+
+ if (query_cache_size == 0)
+ DBUG_VOID_RETURN;
+ DUMP(this);
+
+ /* Key is query + database + flag */
+ if (thd->db_length)
+ {
+ memcpy(thd->query+thd->query_length+1, thd->db, thd->db_length);
+ DBUG_PRINT("qcache", ("database : %s length %u",
+ thd->db, thd->db_length));
+ }
+ else
+ {
+ DBUG_PRINT("qcache", ("No active database"));
+ }
+ /*
+ Prepare flags:
+ most significant bit - CLIENT_LONG_FLAG,
+ other - charset number (0 no charset convertion)
+ */
+ if (thd->variables.convert_set != 0)
+ {
+ flags|= (byte) thd->variables.convert_set->number();
+ DBUG_ASSERT(thd->variables.convert_set->number() < 128);
+ }
+ tot_length= thd->query_length+thd->db_length+2+sizeof(ha_rows);
+ thd->query[tot_length-1]= (char) flags;
+ memcpy((void *)(thd->query + (tot_length-sizeof(ha_rows)-1)),
+ (const void *)&thd->variables.select_limit, sizeof(ha_rows));
+
+ /* Check if another thread is processing the same query? */
+ Query_cache_block *competitor = (Query_cache_block *)
+ hash_search(&queries, (byte*) thd->query, tot_length);
+ DBUG_PRINT("qcache", ("competitor 0x%lx, flags %x", (ulong) competitor,
+ flags));
+ if (competitor == 0)
+ {
+ /* Query is not in cache and no one is working with it; Store it */
+ Query_cache_block *query_block;
+ query_block= write_block_data(tot_length, (gptr) thd->query,
+ ALIGN_SIZE(sizeof(Query_cache_query)),
+ Query_cache_block::QUERY, local_tables, 1);
+ if (query_block != 0)
+ {
+ DBUG_PRINT("qcache", ("query block 0x%lx allocated, %lu",
+ (ulong) query_block, query_block->used));
+
+ Query_cache_query *header = query_block->query();
+ header->init_n_lock();
+ if (hash_insert(&queries, (byte*) query_block))
+ {
+ refused++;
+ DBUG_PRINT("qcache", ("insertion in query hash"));
+ header->unlock_n_destroy();
+ free_memory_block(query_block);
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ goto end;
+ }
+ if (!register_all_tables(query_block, tables_used, local_tables))
+ {
+ refused++;
+ DBUG_PRINT("warning", ("tables list including failed"));
+ hash_delete(&queries, (byte *) query_block);
+ header->unlock_n_destroy();
+ free_memory_block(query_block);
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ goto end;
+ }
+ double_linked_list_simple_include(query_block, &queries_blocks);
+ inserts++;
+ queries_in_cache++;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
+ net->query_cache_query= (gptr) query_block;
+ header->writer(net);
+ // init_n_lock make query block locked
+ BLOCK_UNLOCK_WR(query_block);
+ }
+ else
+ {
+ // We have not enough memory to store query => do nothing
+ refused++;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_PRINT("warning", ("Can't allocate query"));
+ }
+ }
+ else
+ {
+ // Another thread is processing the same query => do nothing
+ refused++;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_PRINT("qcache", ("Another thread process same query"));
+ }
+ }
+ else
+ statistic_increment(refused, &structure_guard_mutex);
+
+end:
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Check if the query is in the cache. If it was cached, send it
+ to the user.
+
+ RESULTS
+ 1 Query was not cached.
+ 0 The query was cached and user was sent the result.
+ -1 The query was cached but we didn't have rights to use it.
+ No error is sent to the client yet.
+*/
+
+
+
+int
+Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
+{
+ Query_cache_query *query;
+ Query_cache_block *first_result_block, *result_block;
+ Query_cache_block_table *block_table, *block_table_end;
+ ulong tot_length;
+ byte flags;
+ DBUG_ENTER("Query_cache::send_result_to_client");
+
+ if (query_cache_size == 0 ||
+ /*
+ it is not possible to check has_transactions() function of handler
+ because tables not opened yet
+ */
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
+ thd->variables.query_cache_type == 0)
+
+ goto err;
+
+ /* Check that we haven't forgot to reset the query cache variables */
+ DBUG_ASSERT(thd->net.query_cache_query == 0);
+
+ if (!thd->safe_to_cache_query)
+ {
+ DBUG_PRINT("qcache", ("SELECT is non-cacheable"));
+ goto err;
+ }
+
+ /*
+ Test if the query is a SELECT
+ (pre-space is removed in dispatch_command)
+ */
+ if (toupper(sql[0]) != 'S' || toupper(sql[1]) != 'E' ||
+ toupper(sql[2]) !='L')
+ {
+ DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
+ goto err;
+ }
+
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size == 0)
+ {
+ DBUG_PRINT("qcache", ("query cache disabled"));
+ goto err_unlock;
+ }
+ Query_cache_block *query_block;
+
+ tot_length= query_length+thd->db_length+2+sizeof(ha_rows);
+ if (thd->db_length)
+ {
+ memcpy(sql+query_length+1, thd->db, thd->db_length);
+ DBUG_PRINT("qcache", ("database: '%s' length %u",
+ thd->db, thd->db_length));
+ }
+ else
+ {
+ DBUG_PRINT("qcache", ("No active database"));
+ }
+ /*
+ prepare flags:
+ Most significant bit - CLIENT_LONG_FLAG,
+ Other - charset number (0 no charset convertion)
+ */
+ flags= (thd->client_capabilities & CLIENT_LONG_FLAG ? 0x80 : 0);
+ if (thd->variables.convert_set != 0)
+ {
+ flags|= (byte) thd->variables.convert_set->number();
+ DBUG_ASSERT(thd->variables.convert_set->number() < 128);
+ }
+ sql[tot_length-1]= (char) flags;
+ memcpy((void *)(sql + (tot_length-sizeof(ha_rows)-1)),
+ (const void *)&thd->variables.select_limit, sizeof(ha_rows));
+ query_block= (Query_cache_block *) hash_search(&queries, (byte*) sql,
+ tot_length);
+
+ /* Quick abort on unlocked data */
+ if (query_block == 0 ||
+ query_block->query()->result() == 0 ||
+ query_block->query()->result()->type != Query_cache_block::RESULT)
+ {
+ DBUG_PRINT("qcache", ("No query in query hash or no results"));
+ goto err_unlock;
+ }
+ DBUG_PRINT("qcache", ("Query in query hash 0x%lx", (ulong)query_block));
+
+ /* Now lock and test that nothing changed while blocks was unlocked */
+ BLOCK_LOCK_RD(query_block);
+
+ query = query_block->query();
+ result_block= first_result_block= query->result();
+
+ if (result_block == 0 || result_block->type != Query_cache_block::RESULT)
+ {
+ /* The query is probably yet processed */
+ DBUG_PRINT("qcache", ("query found, but no data or data incomplete"));
+ BLOCK_UNLOCK_RD(query_block);
+ goto err_unlock;
+ }
+ DBUG_PRINT("qcache", ("Query have result 0x%lx", (ulong) query));
+
+ // Check access;
+ block_table= query_block->table(0);
+ block_table_end= block_table+query_block->n_tables;
+ for (; block_table != block_table_end; block_table++)
+ {
+ TABLE_LIST table_list;
+ bzero((char*) &table_list,sizeof(table_list));
+
+ Query_cache_table *table = block_table->parent;
+ table_list.db = table->db();
+ table_list.alias= table_list.real_name= table->table();
+ if (check_table_access(thd,SELECT_ACL,&table_list,1))
+ {
+ DBUG_PRINT("qcache",
+ ("probably no SELECT access to %s.%s => return to normal processing",
+ table_list.db, table_list.alias));
+ refused++; // This is actually a hit
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ thd->safe_to_cache_query=0; // Don't try to cache this
+ BLOCK_UNLOCK_RD(query_block);
+ DBUG_RETURN(-1); // Privilege error
+ }
+ if (table_list.grant.want_privilege)
+ {
+ DBUG_PRINT("qcache", ("Need to check column privileges for %s.%s",
+ table_list.db, table_list.alias));
+ BLOCK_UNLOCK_RD(query_block);
+ thd->safe_to_cache_query=0; // Don't try to cache this
+ goto err_unlock; // Parse query
+ }
+ }
+ move_to_query_list_end(query_block);
+ hits++;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
+ /*
+ Send cached result to client
+ */
+ do
+ {
+ DBUG_PRINT("qcache", ("Results (len %lu, used %lu, headers %lu)",
+ result_block->length, result_block->used,
+ result_block->headers_len()+
+ ALIGN_SIZE(sizeof(Query_cache_result))));
+
+ Query_cache_result *result = result_block->result();
+ if (net_real_write(&thd->net, result->data(),
+ result_block->used -
+ result_block->headers_len() -
+ ALIGN_SIZE(sizeof(Query_cache_result))))
+ break; // Client aborted
+ result_block = result_block->next;
+ } while (result_block != first_result_block);
+
+ thd->limit_found_rows = query->found_rows();
+
+ BLOCK_UNLOCK_RD(query_block);
+ DBUG_RETURN(1); // Result sent to client
+
+err_unlock:
+ STRUCT_UNLOCK(&structure_guard_mutex);
+err:
+ DBUG_RETURN(0); // Query was not cached
+}
+
+
+/*
+ Remove all cached queries that uses any of the tables in the list
+*/
+
+void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
+ my_bool using_transactions)
+{
+ DBUG_ENTER("Query_cache::invalidate (table list)");
+ if (query_cache_size > 0)
+ {
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ {
+ DUMP(this);
+
+ using_transactions = using_transactions &&
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ for (; tables_used; tables_used=tables_used->next)
+ {
+ DBUG_ASSERT(!using_transactions || tables_used->table!=0);
+ if (using_transactions &&
+ tables_used->table->file->has_transactions())
+ /*
+ Tables_used->table can't be 0 in transaction.
+ Only 'drop' invalidate not opened table, but 'drop'
+ force transaction finish.
+ */
+ thd->add_changed_table(tables_used->table);
+ else
+ invalidate_table(tables_used);
+ }
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
+{
+ DBUG_ENTER("Query_cache::invalidate (changed table list)");
+ if (query_cache_size > 0 && tables_used)
+ {
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ {
+ DUMP(this);
+ for (; tables_used; tables_used=tables_used->next)
+ {
+ invalidate_table((byte*) tables_used->key, tables_used->key_length);
+ DBUG_PRINT("qcache", (" db %s, table %s", tables_used->key,
+ tables_used->key+
+ strlen(tables_used->key)+1));
+ }
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Remove all cached queries that uses the given table
+*/
+
+void Query_cache::invalidate(THD *thd, TABLE *table,
+ my_bool using_transactions)
+{
+ DBUG_ENTER("Query_cache::invalidate (table)");
+
+ if (query_cache_size > 0)
+ {
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ {
+ using_transactions = using_transactions &&
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ if (using_transactions && table->file->has_transactions())
+ thd->add_changed_table(table);
+ else
+ invalidate_table(table);
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
+ my_bool using_transactions)
+{
+ DBUG_ENTER("Query_cache::invalidate (key)");
+
+ if (query_cache_size > 0)
+ {
+ using_transactions = using_transactions &&
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ if (using_transactions) // used for innodb => has_transactions() is TRUE
+ thd->add_changed_table(key, key_length);
+ else
+ {
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ invalidate_table((byte*)key, key_length);
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Remove all cached queries that uses the given database
+*/
+
+void Query_cache::invalidate(char *db)
+{
+ DBUG_ENTER("Query_cache::invalidate (db)");
+ if (query_cache_size > 0)
+ {
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ {
+ DUMP(this);
+ restart_search:
+ if (tables_blocks)
+ {
+ Query_cache_block *curr= tables_blocks;
+ Query_cache_block *next;
+ do
+ {
+ next= curr->next;
+ if (strcmp(db, (char*)(curr->table()->db())) == 0)
+ invalidate_table(curr);
+ /*
+ invalidate_table can freed block on which point 'next' (if
+ table of this block used only in queries which was deleted
+ by invalidate_table). As far as we do not allocate new blocks
+ and mark all headers of freed blocks as 'FREE' (even if they are
+ merged with other blocks) we can just test type of block
+ to be sure that block is not deleted
+ */
+ if (next->type == Query_cache_block::FREE)
+ goto restart_search;
+ curr= next;
+ } while (curr != tables_blocks);
+ }
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::invalidate_by_MyISAM_filename(const char *filename)
+{
+ DBUG_ENTER("Query_cache::invalidate_by_MyISAM_filename");
+ if (query_cache_size > 0)
+ {
+ /* Calculate the key outside the lock to make the lock shorter */
+ char key[MAX_DBKEY_LENGTH];
+ uint32 db_length;
+ uint key_length= filename_2_table_key(key, filename, &db_length);
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0) // Safety if cache removed
+ {
+ Query_cache_block *table_block;
+ if ((table_block = (Query_cache_block*) hash_search(&tables,
+ (byte*) key,
+ key_length)))
+ invalidate_table(table_block);
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+ /* Remove all queries from cache */
+
+void Query_cache::flush()
+{
+ DBUG_ENTER("Query_cache::flush");
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0)
+ {
+ DUMP(this);
+ flush_cache();
+ DUMP(this);
+ }
+
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_VOID_RETURN;
+}
+
+ /* Join result in cache in 1 block (if result length > join_limit) */
+
+void Query_cache::pack(ulong join_limit, uint iteration_limit)
+{
+ DBUG_ENTER("Query_cache::pack");
+ uint i = 0;
+ do
+ {
+ pack_cache();
+ } while ((++i < iteration_limit) && join_results(join_limit));
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::destroy()
+{
+ DBUG_ENTER("Query_cache::destroy");
+ if (!initialized)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ }
+ else
+ {
+ free_cache(1);
+ pthread_mutex_destroy(&structure_guard_mutex);
+ initialized = 0;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/*****************************************************************************
+ init/destroy
+*****************************************************************************/
+
+void Query_cache::init()
+{
+ DBUG_ENTER("Query_cache::init");
+ pthread_mutex_init(&structure_guard_mutex,MY_MUTEX_INIT_FAST);
+ initialized = 1;
+ DBUG_VOID_RETURN;
+}
+
+
+ulong Query_cache::init_cache()
+{
+ uint mem_bin_count, num, step;
+ ulong mem_bin_size, prev_size, inc;
+ ulong additional_data_size, max_mem_bin_size, approx_additional_data_size;
+ int align;
+
+ DBUG_ENTER("Query_cache::init_cache");
+ if (!initialized)
+ init();
+ approx_additional_data_size = (sizeof(Query_cache) +
+ sizeof(gptr)*(def_query_hash_size+
+ def_query_hash_size));
+ if (query_cache_size < approx_additional_data_size)
+ goto err;
+
+ query_cache_size-= approx_additional_data_size;
+ align= query_cache_size % ALIGN_SIZE(1);
+ if (align)
+ {
+ query_cache_size-= align;
+ approx_additional_data_size+= align;
+ }
+
+ /*
+ Count memory bins number.
+ Check section 6. in start comment for the used algorithm.
+ */
+
+ max_mem_bin_size = query_cache_size >> QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2;
+ mem_bin_count = (uint) ((1 + QUERY_CACHE_MEM_BIN_PARTS_INC) *
+ QUERY_CACHE_MEM_BIN_PARTS_MUL);
+ mem_bin_num = 1;
+ mem_bin_steps = 1;
+ mem_bin_size = max_mem_bin_size >> QUERY_CACHE_MEM_BIN_STEP_PWR2;
+ prev_size = 0;
+ if (mem_bin_size <= min_allocation_unit)
+ {
+ DBUG_PRINT("qcache", ("too small query cache => query cache disabled"));
+ // TODO here (and above) should be warning in 4.1
+ goto err;
+ }
+ while (mem_bin_size > min_allocation_unit)
+ {
+ mem_bin_num += mem_bin_count;
+ prev_size = mem_bin_size;
+ mem_bin_size >>= QUERY_CACHE_MEM_BIN_STEP_PWR2;
+ mem_bin_steps++;
+ mem_bin_count += QUERY_CACHE_MEM_BIN_PARTS_INC;
+ mem_bin_count = (uint) (mem_bin_count * QUERY_CACHE_MEM_BIN_PARTS_MUL);
+
+ // Prevent too small bins spacing
+ if (mem_bin_count > (mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2))
+ mem_bin_count= (mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2);
+ }
+ inc = (prev_size - mem_bin_size) / mem_bin_count;
+ mem_bin_num += (mem_bin_count - (min_allocation_unit - mem_bin_size)/inc);
+ mem_bin_steps++;
+ additional_data_size = ((mem_bin_num+1) *
+ ALIGN_SIZE(sizeof(Query_cache_memory_bin))+
+ (mem_bin_steps *
+ ALIGN_SIZE(sizeof(Query_cache_memory_bin_step))));
+
+ if (query_cache_size < additional_data_size)
+ goto err;
+ query_cache_size -= additional_data_size;
+
+ STRUCT_LOCK(&structure_guard_mutex);
+
+ if (!(cache = (byte *)
+ my_malloc_lock(query_cache_size+additional_data_size, MYF(0))))
+ {
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ goto err;
+ }
+
+ DBUG_PRINT("qcache", ("cache length %lu, min unit %lu, %u bins",
+ query_cache_size, min_allocation_unit, mem_bin_num));
+
+ steps = (Query_cache_memory_bin_step *) cache;
+ bins = ((Query_cache_memory_bin *)
+ (cache + mem_bin_steps *
+ ALIGN_SIZE(sizeof(Query_cache_memory_bin_step))));
+
+ first_block = (Query_cache_block *) (cache + additional_data_size);
+ first_block->init(query_cache_size);
+ total_blocks++;
+ first_block->pnext=first_block->pprev=first_block;
+ first_block->next=first_block->prev=first_block;
+
+ /* Prepare bins */
+
+ bins[0].init(max_mem_bin_size);
+ steps[0].init(max_mem_bin_size,0,0);
+ mem_bin_count = (uint) ((1 + QUERY_CACHE_MEM_BIN_PARTS_INC) *
+ QUERY_CACHE_MEM_BIN_PARTS_MUL);
+ num= step= 1;
+ mem_bin_size = max_mem_bin_size >> QUERY_CACHE_MEM_BIN_STEP_PWR2;
+ while (mem_bin_size > min_allocation_unit)
+ {
+ ulong incr = (steps[step-1].size - mem_bin_size) / mem_bin_count;
+ unsigned long size = mem_bin_size;
+ for (uint i= mem_bin_count; i > 0; i--)
+ {
+ bins[num+i-1].init(size);
+ size += incr;
+ }
+ num += mem_bin_count;
+ steps[step].init(mem_bin_size, num-1, incr);
+ mem_bin_size >>= QUERY_CACHE_MEM_BIN_STEP_PWR2;
+ step++;
+ mem_bin_count += QUERY_CACHE_MEM_BIN_PARTS_INC;
+ mem_bin_count = (uint) (mem_bin_count * QUERY_CACHE_MEM_BIN_PARTS_MUL);
+ if (mem_bin_count > (mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2))
+ mem_bin_count=(mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2);
+ }
+ inc = (steps[step-1].size - mem_bin_size) / mem_bin_count;
+
+ /*
+ num + mem_bin_count > mem_bin_num, but index never be > mem_bin_num
+ because block with size < min_allocated_unit never will be requested
+ */
+
+ steps[step].init(mem_bin_size, num + mem_bin_count - 1, inc);
+ {
+ uint skiped = (min_allocation_unit - mem_bin_size)/inc;
+ ulong size = mem_bin_size + inc*skiped;
+ uint i = mem_bin_count - skiped;
+ while (i-- > 0)
+ {
+ bins[num+i].init(size);
+ size += inc;
+ }
+ }
+ bins[mem_bin_num].number = 1; // For easy end test in get_free_block
+ free_memory = free_memory_blocks = 0;
+ insert_into_free_memory_list(first_block);
+
+ DUMP(this);
+
+ VOID(hash_init(&queries,def_query_hash_size, 0, 0,
+ query_cache_query_get_key, 0, 0));
+#ifndef FN_NO_CASE_SENCE
+ VOID(hash_init(&tables,def_table_hash_size, 0, 0,
+ query_cache_table_get_key, 0, 0));
+#else
+ // windows, OS/2 or other case insensitive file names work around
+ VOID(hash_init(&tables,def_table_hash_size, 0, 0,
+ query_cache_table_get_key, 0,
+ (lower_case_table_names?0:HASH_CASE_INSENSITIVE)));
+#endif
+
+ queries_in_cache = 0;
+ queries_blocks = 0;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_RETURN(query_cache_size +
+ additional_data_size + approx_additional_data_size);
+
+err:
+ make_disabled();
+ DBUG_RETURN(0);
+}
+
+
+/* Disable the use of the query cache */
+
+void Query_cache::make_disabled()
+{
+ DBUG_ENTER("Query_cache::make_disabled");
+ query_cache_size= 0;
+ free_memory= 0;
+ bins= 0;
+ steps= 0;
+ cache= 0;
+ mem_bin_num= mem_bin_steps= 0;
+ queries_in_cache= 0;
+ first_block= 0;
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::free_cache(my_bool destruction)
+{
+ DBUG_ENTER("Query_cache::free_cache");
+ if (query_cache_size > 0)
+ {
+ if (!destruction)
+ STRUCT_LOCK(&structure_guard_mutex);
+
+ flush_cache();
+#ifndef DBUG_OFF
+ if (bins[0].free_blocks == 0)
+ {
+ wreck(__LINE__,"no free memory found in (bins[0].free_blocks");
+ DBUG_VOID_RETURN;
+ }
+#endif
+
+ /* Becasue we did a flush, all cache memory must be in one this block */
+ bins[0].free_blocks->destroy();
+ total_blocks--;
+#ifndef DBUG_OFF
+ if (free_memory != query_cache_size)
+ DBUG_PRINT("qcache", ("free memory %lu (should be %lu)",
+ free_memory , query_cache_size));
+#endif
+ my_free((gptr) cache, MYF(MY_ALLOW_ZERO_PTR));
+ make_disabled();
+ hash_free(&queries);
+ hash_free(&tables);
+ if (!destruction)
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*****************************************************************************
+ Free block data
+*****************************************************************************/
+
+/*
+ The following assumes we have a lock on the cache
+*/
+
+void Query_cache::flush_cache()
+{
+ while (queries_blocks != 0)
+ {
+ BLOCK_LOCK_WR(queries_blocks);
+ free_query(queries_blocks);
+ }
+}
+
+/*
+ Free oldest query that is not in use by another thread.
+ Returns 1 if we couldn't remove anything
+*/
+
+my_bool Query_cache::free_old_query()
+{
+ DBUG_ENTER("Query_cache::free_old_query");
+ if (queries_blocks)
+ {
+ /*
+ try_lock_writing used to prevent client because here lock
+ sequence is breached.
+ Also we don't need remove locked queries at this point.
+ */
+ Query_cache_block *query_block = 0;
+ if (queries_blocks != 0)
+ {
+ Query_cache_block *block = queries_blocks;
+ /* Search until we find first query that we can remove */
+ do
+ {
+ Query_cache_query *header = block->query();
+ if (header->result() != 0 &&
+ header->result()->type == Query_cache_block::RESULT &&
+ block->query()->try_lock_writing())
+ {
+ query_block = block;
+ break;
+ }
+ } while ((block=block->next) != queries_blocks );
+ }
+
+ if (query_block != 0)
+ {
+ free_query(query_block);
+ lowmem_prunes++;
+ DBUG_RETURN(0);
+ }
+ }
+ DBUG_RETURN(1); // Nothing to remove
+}
+
+/*
+ Free query from query cache.
+ query_block must be locked for writing.
+ This function will remove (and destroy) the lock for the query.
+*/
+
+void Query_cache::free_query(Query_cache_block *query_block)
+{
+ DBUG_ENTER("Query_cache::free_query");
+ DBUG_PRINT("qcache", ("free query 0x%lx %lu bytes result",
+ (ulong) query_block,
+ query_block->query()->length() ));
+
+ queries_in_cache--;
+ hash_delete(&queries,(byte *) query_block);
+
+ Query_cache_query *query = query_block->query();
+
+ if (query->writer() != 0)
+ {
+ /* Tell MySQL that this query should not be cached anymore */
+ query->writer()->query_cache_query = 0;
+ query->writer(0);
+ }
+ double_linked_list_exclude(query_block, &queries_blocks);
+ Query_cache_block_table *table=query_block->table(0);
+
+ for (TABLE_COUNTER_TYPE i=0; i < query_block->n_tables; i++)
+ unlink_table(table++);
+ Query_cache_block *result_block = query->result();
+
+ /*
+ The following is true when query destruction was called and no results
+ in query . (query just registered and then abort/pack/flush called)
+ */
+ if (result_block != 0)
+ {
+ Query_cache_block *block = result_block;
+ do
+ {
+ Query_cache_block *current = block;
+ block = block->next;
+ free_memory_block(current);
+ } while (block != result_block);
+ }
+
+ query->unlock_n_destroy();
+ free_memory_block(query_block);
+
+ DBUG_VOID_RETURN;
}
-/* At the moment we do not really want to do anything upon delete */
-static void free_cache_entry(void *entry)
+/*****************************************************************************
+ Query data creation
+*****************************************************************************/
+
+Query_cache_block *
+Query_cache::write_block_data(ulong data_len, gptr data,
+ ulong header_len,
+ Query_cache_block::block_type type,
+ TABLE_COUNTER_TYPE ntab,
+ my_bool under_guard)
{
+ ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(ntab*sizeof(Query_cache_block_table)) +
+ header_len);
+ ulong len = data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+ DBUG_ENTER("Query_cache::write_block_data");
+ DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ data_len, header_len, all_headers_len));
+ Query_cache_block *block = allocate_block(max(align_len,
+ min_allocation_unit),
+ 1, 0, under_guard);
+ if (block != 0)
+ {
+ block->type = type;
+ block->n_tables = ntab;
+ block->used = len;
+
+ memcpy((void*) (((byte *) block)+ all_headers_len),
+ (void*) data, data_len);
+ }
+ DBUG_RETURN(block);
}
-/* Initialization of the SQL cache hash -- should be called during
- the bootstrap stage */
-bool sql_cache_init(void)
+
+/*
+ On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be done.
+*/
+
+my_bool
+Query_cache::append_result_data(Query_cache_block **current_block,
+ ulong data_len, gptr data,
+ Query_cache_block *query_block)
{
- if (query_buff_size)
+ DBUG_ENTER("Query_cache::append_result_data");
+ DBUG_PRINT("qcache", ("append %lu bytes to 0x%lx query",
+ data_len, query_block));
+
+ if (query_block->query()->add(data_len) > query_cache_limit)
{
- VOID(hash_init(&sql_cache, 4096, 0, 0,
- cache_key,
- (void (*)(void*)) free_cache_entry,
- 0));
+ DBUG_PRINT("qcache", ("size limit reached %lu > %lu",
+ query_block->query()->length(),
+ query_cache_limit));
+ DBUG_RETURN(0);
}
- return 0;
+ if (*current_block == 0)
+ {
+ DBUG_PRINT("qcache", ("allocated first result data block %lu", data_len));
+ /*
+ STRUCT_UNLOCK(&structure_guard_mutex) Will be done by
+ write_result_data if success;
+ */
+ DBUG_RETURN(write_result_data(current_block, data_len, data, query_block,
+ Query_cache_block::RES_BEG));
+ }
+ Query_cache_block *last_block = (*current_block)->prev;
+
+ DBUG_PRINT("qcache", ("lastblock 0x%lx len %lu used %lu",
+ (ulong) last_block, last_block->length,
+ last_block->used));
+ my_bool success = 1;
+ ulong last_block_free_space= last_block->length - last_block->used;
+
+ /*
+ We will first allocate and write the 'tail' of data, that doesn't fit
+ in the 'last_block'. Only if this succeeds, we will fill the last_block.
+ This saves us a memcpy if the query doesn't fit in the query cache.
+ */
+
+ // Try join blocks if physically next block is free...
+ ulong tail = data_len - last_block_free_space;
+ ulong append_min = get_min_append_result_data_size();
+ if (last_block_free_space < data_len &&
+ append_next_free_block(last_block,
+ max(tail, append_min)))
+ last_block_free_space = last_block->length - last_block->used;
+ // If no space in last block (even after join) allocate new block
+ if (last_block_free_space < data_len)
+ {
+ DBUG_PRINT("qcache", ("allocate new block for %lu bytes",
+ data_len-last_block_free_space));
+ Query_cache_block *new_block = 0;
+ /*
+ On success STRUCT_UNLOCK(&structure_guard_mutex) will be done
+ by the next call
+ */
+ success = write_result_data(&new_block, data_len-last_block_free_space,
+ (gptr)(((byte*)data)+last_block_free_space),
+ query_block,
+ Query_cache_block::RES_CONT);
+ /*
+ new_block may be != 0 even !success (if write_result_data
+ allocate a small block but failed to allocate continue)
+ */
+ if (new_block != 0)
+ double_linked_list_join(last_block, new_block);
+ }
+ else
+ {
+ // It is success (nobody can prevent us write data)
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ }
+
+ // Now finally write data to the last block
+ if (success && last_block_free_space > 0)
+ {
+ ulong to_copy = min(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %lub at block 0x%lx to copy %lub",
+ last_block_free_space, (ulong)last_block, to_copy));
+ memcpy((void*) (((byte*) last_block) + last_block->used), (void*) data,
+ to_copy);
+ last_block->used+=to_copy;
+ }
+ DBUG_RETURN(success);
}
-/* Clearing the SQL cache hash -- during shutdown */
-void sql_cache_free(void)
+
+my_bool Query_cache::write_result_data(Query_cache_block **result_block,
+ ulong data_len, gptr data,
+ Query_cache_block *query_block,
+ Query_cache_block::block_type type)
{
- hash_free(&sql_cache);
+ DBUG_ENTER("Query_cache::write_result_data");
+ DBUG_PRINT("qcache", ("data_len %lu",data_len));
+
+ /*
+ Reserve block(s) for filling
+ During data allocation we must have structure_guard_mutex locked.
+ As data copy is not a fast operation, it's better if we don't have
+ structure_guard_mutex locked during data coping.
+ Thus we first allocate space and lock query, then unlock
+ structure_guard_mutex and copy data.
+ */
+
+ my_bool success = allocate_data_chain(result_block, data_len, query_block,
+ type == Query_cache_block::RES_BEG);
+ if (success)
+ {
+ // It is success (nobody can prevent us write data)
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ byte *rest = (byte*) data;
+ Query_cache_block *block = *result_block;
+ uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ // Now fill list of blocks that created by allocate_data_chain
+ do
+ {
+ block->type = type;
+ ulong length = block->used - headers_len;
+ DBUG_PRINT("qcache", ("write %lu byte in block 0x%lx",length,
+ (ulong)block));
+ memcpy((void*)(((byte*) block)+headers_len), (void*) rest, length);
+ rest += length;
+ block = block->next;
+ type = Query_cache_block::RES_CONT;
+ } while (block != *result_block);
+ }
+ else
+ {
+ if (*result_block != 0)
+ {
+ // Destroy list of blocks that was created & locked by lock_result_data
+ Query_cache_block *block = *result_block;
+ do
+ {
+ Query_cache_block *current = block;
+ block = block->next;
+ free_memory_block(current);
+ } while (block != *result_block);
+ *result_block = 0;
+ /*
+ It is not success => not unlock structure_guard_mutex (we need it to
+ free query)
+ */
+ }
+ }
+ DBUG_PRINT("qcache", ("success %d", (int) success));
+ DBUG_RETURN(success);
+}
+
+inline ulong Query_cache::get_min_first_result_data_size()
+{
+ if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
+ return min_result_data_size;
+ ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
+ avg_result = min(avg_result, query_cache_limit);
+ return max(min_result_data_size, avg_result);
+}
+
+inline ulong Query_cache::get_min_append_result_data_size()
+{
+ return min_result_data_size;
}
-/* Finds whether the SQL command is already in the cache, at any case
- establishes correct LEX structure in the THD (either from
- cache or a new one) */
+/*
+ Allocate one or more blocks to hold data
+*/
-int sql_cache_hit(THD *thd, char *sql, uint length)
+my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
+ ulong data_len,
+ Query_cache_block *query_block,
+ my_bool first_block_arg)
{
-#ifdef QQ
- LEX *ptr;
- ptr = (LEX *)hash_search(&sql_cache, sql, length);
- if (ptr) {
- fprintf(stderr, "Query `%s' -- hit in the cache (%p)\n", ptr->sql_query_text, ptr);
- thd->lex_ptr = ptr;
- ptr->thd = thd;
- } else {
- thd->lex_ptr = ptr = lex_array + last_lex_array_item--;
+ ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ ulong len= data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+ DBUG_ENTER("Query_cache::allocate_data_chain");
+ DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu",
+ data_len, all_headers_len));
- lex_start(thd, (uchar *)sql, length);
+ ulong min_size = (first_block_arg ?
+ get_min_first_result_data_size():
+ get_min_append_result_data_size());
+ *result_block = allocate_block(max(min_size, align_len),
+ min_result_data_size == 0,
+ all_headers_len + min_result_data_size,
+ 1);
+ my_bool success = (*result_block != 0);
+ if (success)
+ {
+ Query_cache_block *new_block= *result_block;
+ new_block->n_tables = 0;
+ new_block->used = 0;
+ new_block->type = Query_cache_block::RES_INCOMPLETE;
+ new_block->next = new_block->prev = new_block;
+ Query_cache_result *header = new_block->result();
+ header->parent(query_block);
- if (hash_insert(&sql_cache, (const byte *)ptr)) {
- fprintf(stderr, "Out of memory during hash_insert?\n");
+ if (new_block->length < len)
+ {
+ /*
+ We got less memory then we need (no big memory blocks) =>
+ Continue to allocated more blocks until we got everything we need.
+ */
+ Query_cache_block *next_block;
+ if ((success = allocate_data_chain(&next_block,
+ len - new_block->length,
+ query_block, first_block_arg)))
+ double_linked_list_join(new_block, next_block);
}
- fprintf(stderr, "Query `%s' not found in the cache -- insert %p from slot %d\n", thd->lex_ptr->ptr, ptr, last_lex_array_item+1);
- if (!hash_search(&sql_cache, sql, length)) {
- fprintf(stderr, "I just enterred a hash key but it's not where -- what's that?\n");
- } else {
- fprintf(stderr, "Inserted to cache\n");
+ if (success)
+ {
+ new_block->used = min(len, new_block->length);
+
+ DBUG_PRINT("qcache", ("Block len %lu used %lu",
+ new_block->length, new_block->used));
}
- return 0;
+ else
+ DBUG_PRINT("warning", ("Can't allocate block for continue"));
+ }
+ else
+ DBUG_PRINT("warning", ("Can't allocate block for results"));
+ DBUG_RETURN(success);
+}
+
+/*****************************************************************************
+ Tables management
+*****************************************************************************/
+
+/*
+ Invalidate the first table in the table_list
+*/
+
+void Query_cache::invalidate_table(TABLE_LIST *table_list)
+{
+ if (table_list->table != 0)
+ invalidate_table(table_list->table); // Table is open
+ else
+ {
+ char key[MAX_DBKEY_LENGTH];
+ uint key_length;
+ Query_cache_block *table_block;
+ key_length=(uint) (strmov(strmov(key,table_list->db)+1,
+ table_list->real_name) -key)+ 1;
+
+ // We don't store temporary tables => no key_length+=4 ...
+ if ((table_block = (Query_cache_block*)
+ hash_search(&tables,(byte*) key,key_length)))
+ invalidate_table(table_block);
}
+}
+
+void Query_cache::invalidate_table(TABLE *table)
+{
+ invalidate_table((byte*) table->table_cache_key, table->key_length);
+}
+
+void Query_cache::invalidate_table(byte * key, uint32 key_length)
+{
+ Query_cache_block *table_block;
+ if ((table_block = ((Query_cache_block*)
+ hash_search(&tables, key, key_length))))
+ invalidate_table(table_block);
+}
+
+void Query_cache::invalidate_table(Query_cache_block *table_block)
+{
+ Query_cache_block_table *list_root = table_block->table(0);
+ while (list_root->next != list_root)
+ {
+ Query_cache_block *query_block = list_root->next->block();
+ BLOCK_LOCK_WR(query_block);
+ free_query(query_block);
+ }
+}
+
+/*
+ Store all used tables
+
+ SYNOPSIS
+ register_all_tables()
+ block Store tables in this block
+ tables_used List if used tables
+ tables_arg Not used ?
+*/
+
+my_bool Query_cache::register_all_tables(Query_cache_block *block,
+ TABLE_LIST *tables_used,
+ TABLE_COUNTER_TYPE tables_arg)
+{
+ TABLE_COUNTER_TYPE n;
+ DBUG_PRINT("qcache", ("register tables block 0x%lx, n %d, header %x",
+ (ulong) block, (int) tables_arg,
+ (int) ALIGN_SIZE(sizeof(Query_cache_block))));
+
+ Query_cache_block_table *block_table = block->table(0);
+
+ for (n=0; tables_used; tables_used=tables_used->next, n++, block_table++)
+ {
+ DBUG_PRINT("qcache",
+ ("table %s, db %s, openinfo at 0x%lx, keylen %u, key at 0x%lx",
+ tables_used->real_name, tables_used->db,
+ (ulong) tables_used->table,
+ tables_used->table->key_length,
+ (ulong) tables_used->table->table_cache_key));
+ block_table->n=n;
+ if (!insert_table(tables_used->table->key_length,
+ tables_used->table->table_cache_key, block_table,
+ tables_used->db_length))
+ break;
+
+ if (tables_used->table->db_type == DB_TYPE_MRG_MYISAM)
+ {
+ ha_myisammrg *handler = (ha_myisammrg *) tables_used->table->file;
+ MYRG_INFO *file = handler->myrg_info();
+ for (MYRG_TABLE *table = file->open_tables;
+ table != file->end_table ;
+ table++)
+ {
+ char key[MAX_DBKEY_LENGTH];
+ uint32 db_length;
+ uint key_length =filename_2_table_key(key, table->table->filename,
+ &db_length);
+ (++block_table)->n= ++n;
+ if (!insert_table(key_length, key, block_table,
+ db_length))
+ goto err;
+ }
+ }
+ }
+
+err:
+ if (tables_used)
+ {
+ DBUG_PRINT("qcache", ("failed at table %d", (int) n));
+ /* Unlink the tables we allocated above */
+ for (Query_cache_block_table *tmp = block->table(0) ;
+ tmp != block_table;
+ tmp++)
+ unlink_table(tmp);
+ }
+ return (tables_used == 0);
+}
+
+/*
+ Insert used tablename in cache
+ Returns 0 on error
+*/
+
+my_bool
+Query_cache::insert_table(uint key_len, char *key,
+ Query_cache_block_table *node,
+ uint32 db_length)
+{
+ DBUG_ENTER("Query_cache::insert_table");
+ DBUG_PRINT("qcache", ("insert table node 0x%lx, len %d",
+ (ulong)node, key_len));
+
+ Query_cache_block *table_block = ((Query_cache_block *)
+ hash_search(&tables, (byte*) key,
+ key_len));
+
+ if (table_block == 0)
+ {
+ DBUG_PRINT("qcache", ("new table block from 0x%lx (%u)",
+ (ulong) key, (int) key_len));
+ table_block = write_block_data(key_len, (gptr) key,
+ ALIGN_SIZE(sizeof(Query_cache_table)),
+ Query_cache_block::TABLE,
+ 1, 1);
+ if (table_block == 0)
+ {
+ DBUG_PRINT("qcache", ("Can't write table name to cache"));
+ DBUG_RETURN(0);
+ }
+ Query_cache_table *header = table_block->table();
+ double_linked_list_simple_include(table_block,
+ &tables_blocks);
+ Query_cache_block_table *list_root = table_block->table(0);
+ list_root->n = 0;
+ list_root->next = list_root->prev = list_root;
+ if (hash_insert(&tables, (const byte *) table_block))
+ {
+ DBUG_PRINT("qcache", ("Can't insert table to hash"));
+ // write_block_data return locked block
+ free_memory_block(table_block);
+ DBUG_RETURN(0);
+ }
+ char *db = header->db();
+ header->table(db + db_length + 1);
+ }
+
+ Query_cache_block_table *list_root = table_block->table(0);
+ node->next = list_root->next;
+ list_root->next = node;
+ node->next->prev = node;
+ node->prev = list_root;
+ node->parent = table_block->table();
+ DBUG_RETURN(1);
+}
+
+
+void Query_cache::unlink_table(Query_cache_block_table *node)
+{
+ DBUG_ENTER("Query_cache::unlink_table");
+ node->prev->next = node->next;
+ node->next->prev = node->prev;
+ Query_cache_block_table *neighbour = node->next;
+ if (neighbour->next == neighbour)
+ {
+ // list is empty (neighbor is root of list)
+ Query_cache_block *table_block = neighbour->block();
+ double_linked_list_exclude(table_block,
+ &tables_blocks);
+ hash_delete(&tables,(byte *) table_block);
+ free_memory_block(table_block);
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*****************************************************************************
+ Free memory management
+*****************************************************************************/
+
+Query_cache_block *
+Query_cache::allocate_block(ulong len, my_bool not_less, ulong min,
+ my_bool under_guard)
+{
+ DBUG_ENTER("Query_cache::allocate_block");
+ DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu, uder_guard %d",
+ len, not_less,min,under_guard));
+
+ if (len >= min(query_cache_size, query_cache_limit))
+ {
+ DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ query_cache_size, query_cache_limit));
+ DBUG_RETURN(0); // in any case we don't have such piece of memory
+ }
+
+ if (!under_guard)
+ STRUCT_LOCK(&structure_guard_mutex);
+
+ /* Free old queries until we have enough memory to store this block */
+ Query_cache_block *block;
+ do
+ {
+ block= get_free_block(len, not_less, min);
+ }
+ while (block == 0 && !free_old_query());
+
+ if (block != 0) // If we found a suitable block
+ {
+ if (block->length >= ALIGN_SIZE(len) + min_allocation_unit)
+ split_block(block,ALIGN_SIZE(len));
+ }
+
+ if (!under_guard)
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_RETURN(block);
+}
+
+
+Query_cache_block *
+Query_cache::get_free_block(ulong len, my_bool not_less, ulong min)
+{
+ Query_cache_block *block = 0, *first = 0;
+ DBUG_ENTER("Query_cache::get_free_block");
+ DBUG_PRINT("qcache",("length %lu, not_less %d, min %lu", len,
+ (int)not_less, min));
+
+ /* Find block with minimal size > len */
+ uint start = find_bin(len);
+ // try matching bin
+ if (bins[start].number != 0)
+ {
+ Query_cache_block *list = bins[start].free_blocks;
+ if (list->prev->length >= len) // check block with max size
+ {
+ first = list;
+ uint n = 0;
+ while ( n < QUERY_CACHE_MEM_BIN_TRY &&
+ first->length < len) //we don't need irst->next != list
+ {
+ first=first->next;
+ n++;
+ }
+ if (first->length >= len)
+ block=first;
+ else // we don't need if (first->next != list)
+ {
+ n = 0;
+ block = list->prev;
+ while (n < QUERY_CACHE_MEM_BIN_TRY &&
+ block->length > len)
+ {
+ block=block->prev;
+ n++;
+ }
+ if (block->length < len)
+ block=block->next;
+ }
+ }
+ else
+ first = list->prev;
+ }
+ if (block == 0 && start > 0)
+ {
+ DBUG_PRINT("qcache",("Try bins with bigger block size"));
+ // Try more big bins
+ int i = start - 1;
+ while (i > 0 && bins[i].number == 0)
+ i--;
+ if (bins[i].number > 0)
+ block = bins[i].free_blocks;
+ }
+
+ // If no big blocks => try less size (if it is possible)
+ if (block == 0 && ! not_less)
+ {
+ DBUG_PRINT("qcache",("Try to allocate a smaller block"));
+ if (first != 0 && first->length > min)
+ block = first;
+ else
+ {
+ uint i = start + 1;
+ /* bins[mem_bin_num].number contains 1 for easy end test */
+ for (i= start+1 ; bins[i].number == 0 ; i++) ;
+ if (i < mem_bin_num && bins[i].free_blocks->prev->length >= min)
+ block = bins[i].free_blocks->prev;
+ }
+ }
+ if (block != 0)
+ exclude_from_free_memory_list(block);
+
+ DBUG_PRINT("qcache",("getting block 0x%lx", (ulong) block));
+ DBUG_RETURN(block);
+}
+
+
+void Query_cache::free_memory_block(Query_cache_block *block)
+{
+ DBUG_ENTER("Query_cache::free_memory_block");
+ block->used=0;
+ block->type= Query_cache_block::FREE; // mark block as free in any case
+ DBUG_PRINT("qcache",
+ ("first_block 0x%lx, block 0x%lx, pnext 0x%lx pprev 0x%lx",
+ (ulong) first_block, (ulong) block, (ulong) block->pnext,
+ (ulong) block->pprev));
+
+ if (block->pnext != first_block && block->pnext->is_free())
+ block = join_free_blocks(block, block->pnext);
+ if (block != first_block && block->pprev->is_free())
+ block = join_free_blocks(block->pprev, block->pprev);
+ insert_into_free_memory_list(block);
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::split_block(Query_cache_block *block, ulong len)
+{
+ DBUG_ENTER("Query_cache::split_block");
+ Query_cache_block *new_block = (Query_cache_block*)(((byte*) block)+len);
+
+ new_block->init(block->length - len);
+ total_blocks++;
+ block->length=len;
+ new_block->pnext = block->pnext;
+ block->pnext = new_block;
+ new_block->pprev = block;
+ new_block->pnext->pprev = new_block;
+
+ if (block->type == Query_cache_block::FREE)
+ {
+ // if block was free then it already joined with all free neighbours
+ insert_into_free_memory_list(new_block);
+ }
+ else
+ free_memory_block(new_block);
+
+ DBUG_PRINT("qcache", ("split 0x%lx (%lu) new 0x%lx",
+ (ulong) block, len, (ulong) new_block));
+ DBUG_VOID_RETURN;
+}
+
+
+Query_cache_block *
+Query_cache::join_free_blocks(Query_cache_block *first_block_arg,
+ Query_cache_block *block_in_list)
+{
+ Query_cache_block *second_block;
+ DBUG_ENTER("Query_cache::join_free_blocks");
+ DBUG_PRINT("qcache",
+ ("join first 0x%lx, pnext 0x%lx, in list 0x%lx",
+ (ulong) first_block_arg, (ulong) first_block_arg->pnext,
+ (ulong) block_in_list));
+
+ exclude_from_free_memory_list(block_in_list);
+ second_block = first_block_arg->pnext;
+ // May be was not free block
+ second_block->used=0;
+ second_block->destroy();
+ total_blocks--;
+
+ first_block_arg->length += second_block->length;
+ first_block_arg->pnext = second_block->pnext;
+ second_block->pnext->pprev = first_block_arg;
+
+ DBUG_RETURN(first_block_arg);
+}
+
+
+my_bool Query_cache::append_next_free_block(Query_cache_block *block,
+ ulong add_size)
+{
+ Query_cache_block *next_block = block->pnext;
+ DBUG_ENTER("Query_cache::append_next_free_block");
+ DBUG_PRINT("enter", ("block 0x%lx, add_size %lu", (ulong) block,
+ add_size));
+
+ if (next_block != first_block && next_block->is_free())
+ {
+ ulong old_len = block->length;
+ exclude_from_free_memory_list(next_block);
+ next_block->destroy();
+ total_blocks--;
+
+ block->length += next_block->length;
+ block->pnext = next_block->pnext;
+ next_block->pnext->pprev = block;
+
+ if (block->length > ALIGN_SIZE(old_len + add_size) + min_allocation_unit)
+ split_block(block,ALIGN_SIZE(old_len + add_size));
+ DBUG_PRINT("exit", ("block was appended"));
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+}
+
+
+void Query_cache::exclude_from_free_memory_list(Query_cache_block *free_block)
+{
+ DBUG_ENTER("Query_cache::exclude_from_free_memory_list");
+ Query_cache_memory_bin *bin = *((Query_cache_memory_bin **)
+ free_block->data());
+ double_linked_list_exclude(free_block, &bin->free_blocks);
+ bin->number--;
+ free_memory-=free_block->length;
+ free_memory_blocks--;
+ DBUG_PRINT("qcache",("exclude block 0x%lx, bin 0x%lx", (ulong) free_block,
+ (ulong) bin));
+ DBUG_VOID_RETURN;
+}
+
+void Query_cache::insert_into_free_memory_list(Query_cache_block *free_block)
+{
+ DBUG_ENTER("Query_cache::insert_into_free_memory_list");
+ uint idx = find_bin(free_block->length);
+ insert_into_free_memory_sorted_list(free_block, &bins[idx].free_blocks);
+ /*
+ We have enough memory in block for storing bin reference due to
+ min_allocation_unit choice
+ */
+ Query_cache_memory_bin **bin_ptr = ((Query_cache_memory_bin**)
+ free_block->data());
+ *bin_ptr = bins+idx;
+ (*bin_ptr)->number++;
+ DBUG_PRINT("qcache",("insert block 0x%lx, bin[%d] 0x%lx",
+ (ulong) free_block, idx, (ulong) *bin_ptr));
+ DBUG_VOID_RETURN;
+}
+
+uint Query_cache::find_bin(ulong size)
+{
+ DBUG_ENTER("Query_cache::find_bin");
+ // Binary search
+ int left = 0, right = mem_bin_steps;
+ do
+ {
+ int middle = (left + right) / 2;
+ if (steps[middle].size > size)
+ left = middle+1;
+ else
+ right = middle;
+ } while (left < right);
+ if (left == 0)
+ {
+ // first bin not subordinate of common rules
+ DBUG_PRINT("qcache", ("first bin (# 0), size %lu",size));
+ DBUG_RETURN(0);
+ }
+ uint bin = steps[left].idx -
+ (uint)((size - steps[left].size)/steps[left].increment);
+#ifndef DBUG_OFF
+ bins_dump();
#endif
- return 1;
+ DBUG_PRINT("qcache", ("bin %u step %u, size %lu step size %lu",
+ bin, left, size, steps[left].size));
+ DBUG_RETURN(bin);
+}
+
+
+/*****************************************************************************
+ Lists management
+*****************************************************************************/
+
+void Query_cache::move_to_query_list_end(Query_cache_block *query_block)
+{
+ DBUG_ENTER("Query_cache::move_to_query_list_end");
+ double_linked_list_exclude(query_block, &queries_blocks);
+ double_linked_list_simple_include(query_block, &queries_blocks);
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::insert_into_free_memory_sorted_list(Query_cache_block *
+ new_block,
+ Query_cache_block **
+ list)
+{
+ DBUG_ENTER("Query_cache::insert_into_free_memory_sorted_list");
+ /*
+ list sorted by size in ascendant order, because we need small blocks
+ more frequently than bigger ones
+ */
+
+ new_block->used = 0;
+ new_block->n_tables = 0;
+ new_block->type = Query_cache_block::FREE;
+
+ if (*list == 0)
+ {
+ *list = new_block->next=new_block->prev=new_block;
+ DBUG_PRINT("qcache", ("inserted into empty list"));
+ }
+ else
+ {
+ Query_cache_block *point = *list;
+ if (point->length >= new_block->length)
+ {
+ point = point->prev;
+ *list = new_block;
+ }
+ else
+ {
+ /* Find right position in sorted list to put block */
+ while (point->next != *list &&
+ point->next->length < new_block->length)
+ point=point->next;
+ }
+ new_block->prev = point;
+ new_block->next = point->next;
+ new_block->next->prev = new_block;
+ point->next = new_block;
+ }
+ free_memory+=new_block->length;
+ free_memory_blocks++;
+ DBUG_VOID_RETURN;
+}
+
+
+void
+Query_cache::double_linked_list_simple_include(Query_cache_block *point,
+ Query_cache_block **
+ list_pointer)
+{
+ DBUG_ENTER("Query_cache::double_linked_list_simple_include");
+ DBUG_PRINT("qcache", ("including block 0x%lx", (ulong) point));
+ if (*list_pointer == 0)
+ *list_pointer=point->next=point->prev=point;
+ else
+ {
+ // insert to the end of list
+ point->next = (*list_pointer);
+ point->prev = (*list_pointer)->prev;
+ point->prev->next = point;
+ (*list_pointer)->prev = point;
+ }
+ DBUG_VOID_RETURN;
}
+
+void
+Query_cache::double_linked_list_exclude(Query_cache_block *point,
+ Query_cache_block **list_pointer)
+{
+ DBUG_ENTER("Query_cache::double_linked_list_exclude");
+ DBUG_PRINT("qcache", ("excluding block 0x%lx, list 0x%lx",
+ (ulong) point, (ulong) list_pointer));
+ if (point->next == point)
+ *list_pointer = 0; // empty list
+ else
+ {
+ point->next->prev = point->prev;
+ point->prev->next = point->next;
+ if (point == *list_pointer)
+ *list_pointer = point->next;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::double_linked_list_join(Query_cache_block *head_tail,
+ Query_cache_block *tail_head)
+{
+ Query_cache_block *head_head = head_tail->next,
+ *tail_tail = tail_head->prev;
+ head_head->prev = tail_tail;
+ head_tail->next = tail_head;
+ tail_head->prev = head_tail;
+ tail_tail->next = head_head;
+}
+
+/*****************************************************************************
+ Query
+*****************************************************************************/
+
+/*
+ If query is cacheable return number tables in query
+ (query without tables are not cached)
+*/
+
+TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
+ char *query,
+ LEX *lex, TABLE_LIST *tables_used)
+{
+ TABLE_COUNTER_TYPE table_count = 0;
+ DBUG_ENTER("Query_cache::is_cacheable");
+
+ if (lex->sql_command == SQLCOM_SELECT &&
+ (thd->variables.query_cache_type == 1 ||
+ (thd->variables.query_cache_type == 2 && (lex->select_lex.options &
+ OPTION_TO_QUERY_CACHE))) &&
+ thd->safe_to_cache_query)
+ {
+ my_bool has_transactions = 0;
+ DBUG_PRINT("qcache", ("options %lx %lx, type %u",
+ OPTION_TO_QUERY_CACHE,
+ lex->select->options,
+ (int) thd->variables.query_cache_type));
+
+ for (; tables_used; tables_used= tables_used->next)
+ {
+ table_count++;
+ DBUG_PRINT("qcache", ("table %s, db %s, type %u",
+ tables_used->real_name,
+ tables_used->db, tables_used->table->db_type));
+ has_transactions = (has_transactions ||
+ tables_used->table->file->has_transactions());
+
+ if (tables_used->table->db_type == DB_TYPE_MRG_ISAM ||
+ tables_used->table->tmp_table != NO_TMP_TABLE ||
+ (tables_used->db_length == 5 &&
+ DB_NAME_PREPROCESS(tables_used->db[0])=='m' &&
+ DB_NAME_PREPROCESS(tables_used->db[1])=='y' &&
+ DB_NAME_PREPROCESS(tables_used->db[2])=='s' &&
+ DB_NAME_PREPROCESS(tables_used->db[3])=='q' &&
+ DB_NAME_PREPROCESS(tables_used->db[4])=='l'))
+ {
+ DBUG_PRINT("qcache",
+ ("select not cacheable: used MRG_ISAM, temporary or system table(s)"));
+ DBUG_RETURN(0);
+ }
+ if (tables_used->table->db_type == DB_TYPE_MRG_MYISAM)
+ {
+ ha_myisammrg *handler = (ha_myisammrg *)tables_used->table->file;
+ MYRG_INFO *file = handler->myrg_info();
+ table_count+= (file->end_table - file->open_tables);
+ }
+ }
+
+ if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
+ has_transactions)
+ {
+ DBUG_PRINT("qcache", ("not in autocommin mode"));
+ DBUG_RETURN(0);
+ }
+ DBUG_PRINT("qcache", ("select is using %d tables", table_count));
+ DBUG_RETURN(table_count);
+ }
+
+ DBUG_PRINT("qcache",
+ ("not interesting query: %d or not cacheable, options %lx %lx, type %u",
+ (int) lex->sql_command,
+ OPTION_TO_QUERY_CACHE,
+ lex->select->options,
+ (int) thd->variables.query_cache_type));
+ DBUG_RETURN(0);
+}
+
+
+/*****************************************************************************
+ Packing
+*****************************************************************************/
+
+void Query_cache::pack_cache()
+{
+ DBUG_ENTER("Query_cache::pack_cache");
+ STRUCT_LOCK(&structure_guard_mutex);
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
+
+ byte *border = 0;
+ Query_cache_block *before = 0;
+ ulong gap = 0;
+ my_bool ok = 1;
+ Query_cache_block *block = first_block;
+ DUMP(this);
+
+ if (first_block)
+ {
+ do
+ {
+ Query_cache_block *next=block->pnext;
+ ok = move_by_type(&border, &before, &gap, block);
+ block = next;
+ } while (ok && block != first_block);
+
+ if (border != 0)
+ {
+ Query_cache_block *new_block = (Query_cache_block *) border;
+ new_block->init(gap);
+ total_blocks++;
+ new_block->pnext = before->pnext;
+ before->pnext = new_block;
+ new_block->pprev = before;
+ new_block->pnext->pprev = new_block;
+ insert_into_free_memory_list(new_block);
+ }
+ DUMP(this);
+ }
+
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_VOID_RETURN;
+}
+
+
+my_bool Query_cache::move_by_type(byte **border,
+ Query_cache_block **before, ulong *gap,
+ Query_cache_block *block)
+{
+ DBUG_ENTER("Query_cache::move_by_type");
+
+ my_bool ok = 1;
+ switch (block->type) {
+ case Query_cache_block::FREE:
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx FREE", (ulong) block));
+ if (*border == 0)
+ {
+ *border = (byte *) block;
+ *before = block->pprev;
+ DBUG_PRINT("qcache", ("gap beginning here"));
+ }
+ exclude_from_free_memory_list(block);
+ *gap +=block->length;
+ block->pprev->pnext=block->pnext;
+ block->pnext->pprev=block->pprev;
+ block->destroy();
+ total_blocks--;
+ DBUG_PRINT("qcache", ("added to gap (%lu)", *gap));
+ break;
+ }
+ case Query_cache_block::TABLE:
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx TABLE", (ulong) block));
+ if (*border == 0)
+ break;
+ ulong len = block->length, used = block->used;
+ Query_cache_block_table *list_root = block->table(0);
+ Query_cache_block_table *tprev = list_root->prev,
+ *tnext = list_root->next;
+ Query_cache_block *prev = block->prev,
+ *next = block->next,
+ *pprev = block->pprev,
+ *pnext = block->pnext,
+ *new_block =(Query_cache_block *) *border;
+ uint tablename_offset = block->table()->table() - block->table()->db();
+ char *data = (char*) block->data();
+ byte *key;
+ uint key_length;
+ key=query_cache_table_get_key((byte*) block, &key_length, 0);
+ hash_search(&tables, (byte*) key, key_length);
+
+ block->destroy();
+ new_block->init(len);
+ new_block->type=Query_cache_block::TABLE;
+ new_block->used=used;
+ new_block->n_tables=1;
+ memmove((char*) new_block->data(), data, len-new_block->headers_len());
+ relink(block, new_block, next, prev, pnext, pprev);
+ if (tables_blocks == block)
+ tables_blocks = new_block;
+
+ Query_cache_block_table *nlist_root = new_block->table(0);
+ nlist_root->n = 0;
+ nlist_root->next = tnext;
+ tnext->prev = nlist_root;
+ nlist_root->prev = tprev;
+ tprev->next = nlist_root;
+ DBUG_PRINT("qcache",
+ ("list_root: 0x%lx tnext 0x%lx tprev 0x%lx tprev->next 0x%lx tnext->prev 0x%lx",
+ (ulong) list_root, (ulong) tnext, (ulong) tprev,
+ (ulong)tprev->next, (ulong)tnext->prev));
+ /*
+ Go through all queries that uses this table and change them to
+ point to the new table object
+ */
+ Query_cache_table *new_block_table=new_block->table();
+ for (;tnext != nlist_root; tnext=tnext->next)
+ tnext->parent= new_block_table;
+ *border += len;
+ *before = new_block;
+ /* Fix pointer to table name */
+ new_block->table()->table(new_block->table()->db() + tablename_offset);
+ /* Fix hash to point at moved block */
+ hash_replace(&tables, tables.current_record, (byte*) new_block);
+
+ DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
+ len, (ulong) new_block, (ulong) *border));
+ break;
+ }
+ case Query_cache_block::QUERY:
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx QUERY", (ulong) block));
+ if (*border == 0)
+ break;
+ BLOCK_LOCK_WR(block);
+ ulong len = block->length, used = block->used;
+ TABLE_COUNTER_TYPE n_tables = block->n_tables;
+ Query_cache_block *prev = block->prev,
+ *next = block->next,
+ *pprev = block->pprev,
+ *pnext = block->pnext,
+ *new_block =(Query_cache_block*) *border;
+ char *data = (char*) block->data();
+ Query_cache_block *first_result_block = ((Query_cache_query *)
+ block->data())->result();
+ byte *key;
+ uint key_length;
+ key=query_cache_query_get_key((byte*) block, &key_length, 0);
+ hash_search(&queries, (byte*) key, key_length);
+ // Move table of used tables
+ memmove((char*) new_block->table(0), (char*) block->table(0),
+ ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table)));
+ block->query()->unlock_n_destroy();
+ block->destroy();
+ new_block->init(len);
+ new_block->type=Query_cache_block::QUERY;
+ new_block->used=used;
+ new_block->n_tables=n_tables;
+ memmove((char*) new_block->data(), data, len - new_block->headers_len());
+ relink(block, new_block, next, prev, pnext, pprev);
+ if (queries_blocks == block)
+ queries_blocks = new_block;
+ Query_cache_block_table *beg_of_table_table= block->table(0),
+ *end_of_table_table= block->table(n_tables);
+ byte *beg_of_new_table_table= (byte*) new_block->table(0);
+
+ for (TABLE_COUNTER_TYPE j=0; j < n_tables; j++)
+ {
+ Query_cache_block_table *block_table = new_block->table(j);
+
+ // use aligment from begining of table if 'next' is in same block
+ if ((beg_of_table_table <= block_table->next) &&
+ (block_table->next < end_of_table_table))
+ ((Query_cache_block_table *)(beg_of_new_table_table +
+ (((byte*)block_table->next) -
+ ((byte*)beg_of_table_table))))->prev=
+ block_table;
+ else
+ block_table->next->prev= block_table;
+
+ // use aligment from begining of table if 'prev' is in same block
+ if ((beg_of_table_table <= block_table->prev) &&
+ (block_table->prev < end_of_table_table))
+ ((Query_cache_block_table *)(beg_of_new_table_table +
+ (((byte*)block_table->prev) -
+ ((byte*)beg_of_table_table))))->next=
+ block_table;
+ else
+ block_table->prev->next = block_table;
+ }
+ DBUG_PRINT("qcache", ("after circle tt"));
+ *border += len;
+ *before = new_block;
+ new_block->query()->result(first_result_block);
+ if (first_result_block != 0)
+ {
+ Query_cache_block *result_block = first_result_block;
+ do
+ {
+ result_block->result()->parent(new_block);
+ result_block = result_block->next;
+ } while ( result_block != first_result_block );
+ }
+ Query_cache_query *new_query= ((Query_cache_query *) new_block->data());
+ my_rwlock_init(&new_query->lock, NULL);
+
+ /*
+ If someone is writing to this block, inform the writer that the block
+ has been moved.
+ */
+ NET *net = new_block->query()->writer();
+ if (net != 0)
+ {
+ net->query_cache_query= (gptr) new_block;
+ }
+ /* Fix hash to point at moved block */
+ hash_replace(&queries, queries.current_record, (byte*) new_block);
+ DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
+ len, (ulong) new_block, (ulong) *border));
+ break;
+ }
+ case Query_cache_block::RES_INCOMPLETE:
+ case Query_cache_block::RES_BEG:
+ case Query_cache_block::RES_CONT:
+ case Query_cache_block::RESULT:
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx RES* (%d)", (ulong) block,
+ (int) block->type));
+ if (*border == 0)
+ break;
+ Query_cache_block *query_block = block->result()->parent(),
+ *next = block->next,
+ *prev = block->prev;
+ Query_cache_block::block_type type = block->type;
+ BLOCK_LOCK_WR(query_block);
+ ulong len = block->length, used = block->used;
+ Query_cache_block *pprev = block->pprev,
+ *pnext = block->pnext,
+ *new_block =(Query_cache_block*) *border;
+ char *data = (char*) block->data();
+ block->destroy();
+ new_block->init(len);
+ new_block->type=type;
+ new_block->used=used;
+ memmove((char*) new_block->data(), data, len - new_block->headers_len());
+ relink(block, new_block, next, prev, pnext, pprev);
+ new_block->result()->parent(query_block);
+ Query_cache_query *query = query_block->query();
+ if (query->result() == block)
+ query->result(new_block);
+ *border += len;
+ *before = new_block;
+ /* If result writing complete && we have free space in block */
+ ulong free_space= new_block->length - new_block->used;
+ free_space-= free_space % ALIGN_SIZE(1);
+ if (query->result()->type == Query_cache_block::RESULT &&
+ new_block->length > new_block->used &&
+ *gap + free_space > min_allocation_unit &&
+ new_block->length - free_space > min_allocation_unit)
+ {
+ *border-= free_space;
+ *gap+= free_space;
+ DBUG_PRINT("qcache",
+ ("rest of result free space added to gap (%lu)", *gap));
+ new_block->length -= free_space;
+ }
+ BLOCK_UNLOCK_WR(query_block);
+ DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
+ len, (ulong) new_block, (ulong) *border));
+ break;
+ }
+ default:
+ DBUG_PRINT("error", ("unexpected block type %d, block 0x%lx",
+ (int)block->type, (ulong) block));
+ ok = 0;
+ }
+ DBUG_RETURN(ok);
+}
+
+
+void Query_cache::relink(Query_cache_block *oblock,
+ Query_cache_block *nblock,
+ Query_cache_block *next, Query_cache_block *prev,
+ Query_cache_block *pnext, Query_cache_block *pprev)
+{
+ if (prev == oblock) //check pointer to himself
+ {
+ nblock->prev = nblock;
+ nblock->next = nblock;
+ }
+ else
+ {
+ nblock->prev = prev;
+ prev->next=nblock;
+ }
+ if (next != oblock)
+ {
+ nblock->next = next;
+ next->prev=nblock;
+ }
+ nblock->pprev = pprev; // Physical pointer to himself have only 1 free block
+ nblock->pnext = pnext;
+ pprev->pnext=nblock;
+ pnext->pprev=nblock;
+}
+
+
+my_bool Query_cache::join_results(ulong join_limit)
+{
+ my_bool has_moving = 0;
+ DBUG_ENTER("Query_cache::join_results");
+
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (queries_blocks != 0)
+ {
+ Query_cache_block *block = queries_blocks;
+ do
+ {
+ Query_cache_query *header = block->query();
+ if (header->result() != 0 &&
+ header->result()->type == Query_cache_block::RESULT &&
+ header->length() > join_limit)
+ {
+ Query_cache_block *new_result_block =
+ get_free_block(ALIGN_SIZE(header->length()) +
+ ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(sizeof(Query_cache_result)), 1, 0);
+ if (new_result_block != 0)
+ {
+ has_moving = 1;
+ Query_cache_block *first_result = header->result();
+ ulong new_len = (header->length() +
+ ALIGN_SIZE(sizeof(Query_cache_block)) +
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ if (new_result_block->length >
+ ALIGN_SIZE(new_len) + min_allocation_unit)
+ split_block(new_result_block, ALIGN_SIZE(new_len));
+ BLOCK_LOCK_WR(block);
+ header->result(new_result_block);
+ new_result_block->type = Query_cache_block::RESULT;
+ new_result_block->n_tables = 0;
+ new_result_block->used = new_len;
+
+ new_result_block->next = new_result_block->prev = new_result_block;
+ DBUG_PRINT("qcache", ("new block %lu/%lu (%lu)",
+ new_result_block->length,
+ new_result_block->used,
+ header->length()));
+
+ Query_cache_result *new_result = new_result_block->result();
+ new_result->parent(block);
+ byte *write_to = (byte*) new_result->data();
+ Query_cache_block *result_block = first_result;
+ do
+ {
+ ulong len = (result_block->used - result_block->headers_len() -
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ DBUG_PRINT("loop", ("add block %lu/%lu (%lu)",
+ result_block->length,
+ result_block->used,
+ len));
+ memcpy((char *) write_to,
+ (char*) result_block->result()->data(),
+ len);
+ write_to += len;
+ Query_cache_block *old_result_block = result_block;
+ result_block = result_block->next;
+ free_memory_block(old_result_block);
+ } while (result_block != first_result);
+ BLOCK_UNLOCK_WR(block);
+ }
+ }
+ block = block->next;
+ } while ( block != queries_blocks );
+ }
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_RETURN(has_moving);
+}
+
+
+uint Query_cache::filename_2_table_key (char *key, const char *path,
+ uint32 *db_length)
+{
+ char tablename[FN_REFLEN+2], *filename, *dbname;
+ DBUG_ENTER("Query_cache::filename_2_table_key");
+
+ /* Safety if filename didn't have a directory name */
+ tablename[0]= FN_LIBCHAR;
+ tablename[1]= FN_LIBCHAR;
+ /* Convert filename to this OS's format in tablename */
+ fn_format(tablename + 2, path, "", "", MY_REPLACE_EXT);
+ filename= tablename + dirname_length(tablename + 2) + 2;
+ /* Find start of databasename */
+ for (dbname= filename - 2 ; dbname[-1] != FN_LIBCHAR ; dbname--) ;
+ *db_length= (filename - dbname) - 1;
+ DBUG_PRINT("qcache", ("table '%-.*s.%s'", *db_length, dbname, filename));
+
+ DBUG_RETURN((uint) (strmov(strmake(key, dbname, *db_length) + 1,
+ filename) -key) + 1);
+}
+
+/****************************************************************************
+ Functions to be used when debugging
+****************************************************************************/
+
+#if defined(DBUG_OFF) && !defined(USE_QUERY_CACHE_INTEGRITY_CHECK)
+
+void wreck(uint line, const char *message) {}
+void bins_dump() {}
+void cache_dump() {}
+void queries_dump() {}
+void tables_dump() {}
+my_bool check_integrity(bool not_locked) { return 0; }
+my_bool in_list(Query_cache_block * root, Query_cache_block * point,
+ const char *name) { return 0;}
+my_bool in_blocks(Query_cache_block * point) { return 0; }
+
+#else
+
+void Query_cache::wreck(uint line, const char *message)
+{
+ THD *thd=current_thd;
+ DBUG_ENTER("Query_cache::wreck");
+ query_cache_size = 0;
+ if (*message)
+ DBUG_PRINT("error", (" %s", message));
+ DBUG_PRINT("warning", ("=================================="));
+ DBUG_PRINT("warning", ("%5d QUERY CACHE WRECK => DISABLED",line));
+ DBUG_PRINT("warning", ("=================================="));
+ if (thd)
+ thd->killed = 1;
+ cache_dump();
+ /* check_integrity(0); */ /* Can't call it here because of locks */
+ bins_dump();
+ DBUG_VOID_RETURN;
+}
+
+
+void Query_cache::bins_dump()
+{
+ uint i;
+
+ if (!initialized)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ return;
+ }
+
+ DBUG_PRINT("qcache", ("mem_bin_num=%u, mem_bin_steps=%u",
+ mem_bin_num, mem_bin_steps));
+ DBUG_PRINT("qcache", ("-------------------------"));
+ DBUG_PRINT("qcache", (" size idx step"));
+ DBUG_PRINT("qcache", ("-------------------------"));
+ for (i=0; i < mem_bin_steps; i++)
+ {
+ DBUG_PRINT("qcache", ("%10lu %3d %10lu", steps[i].size, steps[i].idx,
+ steps[i].increment));
+ }
+ DBUG_PRINT("qcache", ("-------------------------"));
+ DBUG_PRINT("qcache", (" size num"));
+ DBUG_PRINT("qcache", ("-------------------------"));
+ for (i=0; i < mem_bin_num; i++)
+ {
+ DBUG_PRINT("qcache", ("%10lu %3d 0x%lx", bins[i].size, bins[i].number,
+ (ulong)&(bins[i])));
+ if (bins[i].free_blocks)
+ {
+ Query_cache_block *block = bins[i].free_blocks;
+ do{
+ DBUG_PRINT("qcache", ("\\-- %lu 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx",
+ block->length, (ulong)block,
+ (ulong)block->next, (ulong)block->prev,
+ (ulong)block->pnext, (ulong)block->pprev));
+ block = block->next;
+ } while ( block != bins[i].free_blocks );
+ }
+ }
+ DBUG_PRINT("qcache", ("-------------------------"));
+}
+
+
+void Query_cache::cache_dump()
+{
+ if (!initialized)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ return;
+ }
+
+ DBUG_PRINT("qcache", ("-------------------------------------"));
+ DBUG_PRINT("qcache", (" length used t nt"));
+ DBUG_PRINT("qcache", ("-------------------------------------"));
+ Query_cache_block *i = first_block;
+ do
+ {
+ DBUG_PRINT("qcache",
+ ("%10lu %10lu %1d %2d 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx",
+ i->length, i->used, (int)i->type,
+ i->n_tables, (ulong)i,
+ (ulong)i->next, (ulong)i->prev, (ulong)i->pnext,
+ (ulong)i->pprev));
+ i = i->pnext;
+ } while ( i != first_block );
+ DBUG_PRINT("qcache", ("-------------------------------------"));
+}
+
+
+void Query_cache::queries_dump()
+{
+
+ if (!initialized)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ return;
+ }
+
+ DBUG_PRINT("qcache", ("------------------"));
+ DBUG_PRINT("qcache", (" QUERIES"));
+ DBUG_PRINT("qcache", ("------------------"));
+ if (queries_blocks != 0)
+ {
+ Query_cache_block *block = queries_blocks;
+ do
+ {
+ uint len;
+ char *str = (char*) query_cache_query_get_key((byte*) block, &len, 0);
+ len--; // Point at flags
+ uint flags = (uint) (uchar) str[len];
+ str[len]=0;
+ DBUG_PRINT("qcache", ("%u (%u,%u) '%s' '%s'",
+ ((flags & QUERY_CACHE_CLIENT_LONG_FLAG_MASK)? 1:0),
+ (flags & QUERY_CACHE_CHARSET_CONVERT_MASK), len,
+ str,strend(str)+1));
+ DBUG_PRINT("qcache", ("-b- 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", (ulong) block,
+ (ulong) block->next, (ulong) block->prev,
+ (ulong)block->pnext, (ulong)block->pprev));
+ str[len]=(char) flags;
+ for (TABLE_COUNTER_TYPE t = 0; t < block->n_tables; t++)
+ {
+ Query_cache_table *table = block->table(t)->parent;
+ DBUG_PRINT("qcache", ("-t- '%s' '%s'", table->db(), table->table()));
+ }
+ Query_cache_query *header = block->query();
+ if (header->result())
+ {
+ Query_cache_block *result_block = header->result();
+ Query_cache_block *result_beg = result_block;
+ do
+ {
+ DBUG_PRINT("qcache", ("-r- %u %lu/%lu 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx",
+ (uint) result_block->type,
+ result_block->length, result_block->used,
+ (ulong) result_block,
+ (ulong) result_block->next,
+ (ulong) result_block->prev,
+ (ulong) result_block->pnext,
+ (ulong) result_block->pprev));
+ result_block = result_block->next;
+ } while ( result_block != result_beg );
+ }
+ } while ((block=block->next) != queries_blocks);
+ }
+ else
+ {
+ DBUG_PRINT("qcache", ("no queries in list"));
+ }
+ DBUG_PRINT("qcache", ("------------------"));
+}
+
+
+void Query_cache::tables_dump()
+{
+ if (!initialized)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ return;
+ }
+
+ DBUG_PRINT("qcache", ("--------------------"));
+ DBUG_PRINT("qcache", ("TABLES"));
+ DBUG_PRINT("qcache", ("--------------------"));
+ if (tables_blocks != 0)
+ {
+ Query_cache_block *table_block = tables_blocks;
+ do
+ {
+ Query_cache_table *table = table_block->table();
+ DBUG_PRINT("qcache", ("'%s' '%s'", table->db(), table->table()));
+ table_block = table_block->next;
+ } while ( table_block != tables_blocks);
+ }
+ else
+ DBUG_PRINT("qcache", ("no tables in list"));
+ DBUG_PRINT("qcache", ("--------------------"));
+}
+
+
+my_bool Query_cache::check_integrity(bool not_locked)
+{
+ my_bool result = 0;
+ uint i;
+ DBUG_ENTER("check_integrity");
+
+ if (query_cache_size == 0)
+ {
+ DBUG_PRINT("qcache", ("Query Cache not initialized"));
+ DBUG_RETURN(0);
+ }
+ if (!not_locked)
+ STRUCT_LOCK(&structure_guard_mutex);
+
+ if (hash_check(&queries))
+ {
+ DBUG_PRINT("error", ("queries hash is damaged"));
+ result = 1;
+ }
+
+ if (hash_check(&tables))
+ {
+ DBUG_PRINT("error", ("tables hash is damaged"));
+ result = 1;
+ }
+
+ DBUG_PRINT("qcache", ("physical address check ..."));
+ ulong free=0, used=0;
+ Query_cache_block * block = first_block;
+ do
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
+ (ulong) block, (uint) block->type));
+ // Check allignment
+ if ((((long)block) % (long) ALIGN_SIZE(1)) !=
+ (((long)first_block) % (long)ALIGN_SIZE(1)))
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx do not aligned by %d", (ulong) block,
+ ALIGN_SIZE(1)));
+ result = 1;
+ }
+ // Check memory allocation
+ if (block->pnext == first_block) // Is it last block?
+ {
+ if (((byte*)block) + block->length !=
+ ((byte*)first_block) + query_cache_size)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx, type %u, ended at 0x%lx, but cache ended at 0x%lx",
+ (ulong) block, (uint) block->type,
+ (ulong) (((byte*)block) + block->length),
+ (ulong) (((byte*)first_block) + query_cache_size)));
+ result = 1;
+ }
+ }
+ else
+ if (((byte*)block) + block->length != ((byte*)block->pnext))
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx, type %u, ended at 0x%lx, but next block begining at 0x%lx",
+ (ulong) block, (uint) block->type,
+ (ulong) (((byte*)block) + block->length),
+ (ulong) ((byte*)block->pnext)));
+ }
+ if (block->type == Query_cache_block::FREE)
+ free+= block->length;
+ else
+ used+= block->length;
+ switch(block->type) {
+ case Query_cache_block::FREE:
+ {
+ Query_cache_memory_bin *bin = *((Query_cache_memory_bin **)
+ block->data());
+ //is it correct pointer?
+ if (((byte*)bin) < ((byte*)bins) ||
+ ((byte*)bin) >= ((byte*)first_block))
+ {
+ DBUG_PRINT("error",
+ ("free block 0x%lx have bin pointer 0x%lx beyaond of bins array bounds [0x%lx,0x%lx]",
+ (ulong) block,
+ (ulong) bin,
+ (ulong) bins,
+ (ulong) first_block));
+ result = 1;
+ }
+ else
+ {
+ int idx = (((byte*)bin) - ((byte*)bins)) /
+ sizeof(Query_cache_memory_bin);
+ if (in_list(bins[idx].free_blocks, block, "free memory"))
+ result = 1;
+ }
+ break;
+ }
+ case Query_cache_block::TABLE:
+ if (in_list(tables_blocks, block, "tables"))
+ result = 1;
+ if (in_table_list(block->table(0), block->table(0), "table list root"))
+ result = 1;
+ break;
+ case Query_cache_block::QUERY:
+ {
+ if (in_list(queries_blocks, block, "query"))
+ result = 1;
+ for (TABLE_COUNTER_TYPE j=0; j < block->n_tables; j++)
+ {
+ Query_cache_block_table *block_table = block->table(j);
+ Query_cache_block_table *block_table_root =
+ (Query_cache_block_table *)
+ (((byte*)block_table->parent) -
+ ALIGN_SIZE(sizeof(Query_cache_block_table)));
+
+ if (in_table_list(block_table, block_table_root, "table list"))
+ result = 1;
+ }
+ break;
+ }
+ case Query_cache_block::RES_INCOMPLETE:
+ // This type of block can be not lincked yet (in multithread environment)
+ break;
+ case Query_cache_block::RES_BEG:
+ case Query_cache_block::RES_CONT:
+ case Query_cache_block::RESULT:
+ {
+ Query_cache_block * query_block = block->result()->parent();
+ if (((byte*)query_block) < ((byte*)first_block) ||
+ ((byte*)query_block) >= (((byte*)first_block) + query_cache_size))
+ {
+ DBUG_PRINT("error",
+ ("result block 0x%lx have query block pointer 0x%lx beyaond of block pool bounds [0x%lx,0x%lx]",
+ (ulong) block,
+ (ulong) query_block,
+ (ulong) first_block,
+ (ulong) (((byte*)first_block) + query_cache_size)));
+ result = 1;
+ }
+ else
+ {
+ BLOCK_LOCK_RD(query_block);
+ if (in_list(queries_blocks, query_block, "query from results"))
+ result = 1;
+ if (in_list(query_block->query()->result(), block,
+ "results"))
+ result = 1;
+ BLOCK_UNLOCK_RD(query_block);
+ }
+ break;
+ }
+ default:
+ DBUG_PRINT("error",
+ ("block 0x%lx have incorrect type %u",
+ block, block->type));
+ result = 1;
+ }
+
+ block = block->pnext;
+ } while (block != first_block);
+
+ if (used + free != query_cache_size)
+ {
+ DBUG_PRINT("error",
+ ("used memory (%lu) + free memory (%lu) != query_cache_size (%lu)",
+ used, free, query_cache_size));
+ result = 1;
+ }
+
+ if (free != free_memory)
+ {
+ DBUG_PRINT("error",
+ ("free memory (%lu) != free_memory (%lu)",
+ free, free_memory));
+ result = 1;
+ }
+
+ DBUG_PRINT("qcache", ("check queries ..."));
+ if ((block = queries_blocks))
+ {
+ do
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
+ (ulong) block, (uint) block->type));
+ uint length;
+ byte *key = query_cache_query_get_key((byte*) block, &length, 0);
+ gptr val = hash_search(&queries, key, length);
+ if (((gptr)block) != val)
+ {
+ DBUG_PRINT("error", ("block 0x%lx found in queries hash like 0x%lx",
+ (ulong) block, (ulong) val));
+ }
+ if (in_blocks(block))
+ result = 1;
+ Query_cache_block * results = block->query()->result();
+ if (results)
+ {
+ Query_cache_block * result_block = results;
+ do
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
+ (ulong) block, (uint) block->type));
+ if (in_blocks(result_block))
+ result = 1;
+
+ result_block = result_block->next;
+ } while (result_block != results);
+ }
+ block = block->next;
+ } while (block != queries_blocks);
+ }
+
+ DBUG_PRINT("qcache", ("check tables ..."));
+ if ((block = tables_blocks))
+ {
+ do
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
+ (ulong) block, (uint) block->type));
+ uint length;
+ byte *key = query_cache_table_get_key((byte*) block, &length, 0);
+ gptr val = hash_search(&tables, key, length);
+ if (((gptr)block) != val)
+ {
+ DBUG_PRINT("error", ("block 0x%lx found in tables hash like 0x%lx",
+ (ulong) block, (ulong) val));
+ }
+
+ if (in_blocks(block))
+ result = 1;
+ block=block->next;
+ } while (block != tables_blocks);
+ }
+
+ DBUG_PRINT("qcache", ("check free blocks"));
+ for (i = 0; i < mem_bin_num; i++)
+ {
+ if ((block = bins[i].free_blocks))
+ {
+ uint count = 0;
+ do
+ {
+ DBUG_PRINT("qcache", ("block 0x%lx, type %u...",
+ (ulong) block, (uint) block->type));
+ if (in_blocks(block))
+ result = 1;
+
+ count++;
+ block=block->next;
+ } while (block != bins[i].free_blocks);
+ if (count != bins[i].number)
+ {
+ DBUG_PRINT("error", ("bin[%d].number is %d, but bin have %d blocks",
+ bins[i].number, count));
+ result = 1;
+ }
+ }
+ }
+ DBUG_ASSERT(result == 0);
+ if (!not_locked)
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ DBUG_RETURN(result);
+}
+
+
+my_bool Query_cache::in_blocks(Query_cache_block * point)
+{
+ my_bool result = 0;
+ Query_cache_block *block = point;
+ //back
+ do
+ {
+ if (block->pprev->pnext != block)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx in physical list is incorrect linked, prev block 0x%lx refered as next to 0x%lx (check from 0x%lx)",
+ (ulong) block, (ulong) block->pprev,
+ (ulong) block->pprev->pnext,
+ (ulong) point));
+ //back trace
+ for (; block != point; block = block->pnext)
+ DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
+ result = 1;
+ goto err1;
+ }
+ block = block->pprev;
+ } while (block != first_block && block != point);
+ if (block != first_block)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx (0x%lx<-->0x%lx) not owned by pysical list",
+ (ulong) block, (ulong) block->pprev, (ulong )block->pnext));
+ return 1;
+ }
+
+err1:
+ //forward
+ block = point;
+ do
+ {
+ if (block->pnext->pprev != block)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx in physicel list is incorrect linked, next block 0x%lx refered as prev to 0x%lx (check from 0x%lx)",
+ (ulong) block, (ulong) block->pnext,
+ (ulong) block->pnext->pprev,
+ (ulong) point));
+ //back trace
+ for (; block != point; block = block->pprev)
+ DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
+ result = 1;
+ goto err2;
+ }
+ block = block->pnext;
+ } while (block != first_block);
+err2:
+ return result;
+}
+
+
+my_bool Query_cache::in_list(Query_cache_block * root,
+ Query_cache_block * point,
+ const char *name)
+{
+ my_bool result = 0;
+ Query_cache_block *block = point;
+ //back
+ do
+ {
+ if (block->prev->next != block)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx in list '%s' 0x%lx is incorrect linked, prev block 0x%lx refered as next to 0x%lx (check from 0x%lx)",
+ (ulong) block, name, (ulong) root, (ulong) block->prev,
+ (ulong) block->prev->next,
+ (ulong) point));
+ //back trace
+ for (; block != point; block = block->next)
+ DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
+ result = 1;
+ goto err1;
+ }
+ block = block->prev;
+ } while (block != root && block != point);
+ if (block != root)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx (0x%lx<-->0x%lx) not owned by list '%s' 0x%lx",
+ (ulong) block,
+ (ulong) block->prev, (ulong) block->next,
+ name, (ulong) root));
+ return 1;
+ }
+err1:
+ // forward
+ block = point;
+ do
+ {
+ if (block->next->prev != block)
+ {
+ DBUG_PRINT("error",
+ ("block 0x%lx in list '%s' 0x%lx is incorrect linked, next block 0x%lx refered as prev to 0x%lx (check from 0x%lx)",
+ (ulong) block, name, (ulong) root, (ulong) block->next,
+ (ulong) block->next->prev,
+ (ulong) point));
+ //back trace
+ for (; block != point; block = block->prev)
+ DBUG_PRINT("error", ("back trace 0x%lx", (ulong) block));
+ result = 1;
+ goto err2;
+ }
+ block = block->next;
+ } while (block != root);
+err2:
+ return result;
+}
+
+void dump_node(Query_cache_block_table * node,
+ const char * call, const char * descr)
+{
+ DBUG_PRINT("qcache", ("%s: %s: node: 0x%lx", call, descr, (ulong) node));
+ DBUG_PRINT("qcache", ("%s: %s: node block: 0x%lx",
+ call, descr, (ulong) node->block()));
+ DBUG_PRINT("qcache", ("%s: %s: next: 0x%lx", call, descr,
+ (ulong) node->next));
+ DBUG_PRINT("qcache", ("%s: %s: prev: 0x%lx", call, descr,
+ (ulong) node->prev));
+}
+
+my_bool Query_cache::in_table_list(Query_cache_block_table * root,
+ Query_cache_block_table * point,
+ const char *name)
+{
+ my_bool result = 0;
+ Query_cache_block_table *table = point;
+ dump_node(root, name, "parameter root");
+ //back
+ do
+ {
+ dump_node(table, name, "list element << ");
+ if (table->prev->next != table)
+ {
+ DBUG_PRINT("error",
+ ("table 0x%lx(0x%lx) in list '%s' 0x%lx(0x%lx) is incorrect linked, prev table 0x%lx(0x%lx) refered as next to 0x%lx(0x%lx) (check from 0x%lx(0x%lx))",
+ (ulong) table, (ulong) table->block(), name,
+ (ulong) root, (ulong) root->block(),
+ (ulong) table->prev, (ulong) table->prev->block(),
+ (ulong) table->prev->next,
+ (ulong) table->prev->next->block(),
+ (ulong) point, (ulong) point->block()));
+ //back trace
+ for (; table != point; table = table->next)
+ DBUG_PRINT("error", ("back trace 0x%lx(0x%lx)",
+ (ulong) table, (ulong) table->block()));
+ result = 1;
+ goto err1;
+ }
+ table = table->prev;
+ } while (table != root && table != point);
+ if (table != root)
+ {
+ DBUG_PRINT("error",
+ ("table 0x%lx(0x%lx) (0x%lx(0x%lx)<-->0x%lx(0x%lx)) not owned by list '%s' 0x%lx(0x%lx)",
+ (ulong) table, (ulong) table->block(),
+ (ulong) table->prev, (ulong) table->prev->block(),
+ (ulong) table->next, (ulong) table->next->block(),
+ name, (ulong) root, (ulong) root->block()));
+ return 1;
+ }
+err1:
+ // forward
+ table = point;
+ do
+ {
+ dump_node(table, name, "list element >> ");
+ if (table->next->prev != table)
+ {
+ DBUG_PRINT("error",
+ ("table 0x%lx(0x%lx) in list '%s' 0x%lx(0x%lx) is incorrect linked, next table 0x%lx(0x%lx) refered as prev to 0x%lx(0x%lx) (check from 0x%lx(0x%lx))",
+ (ulong) table, (ulong) table->block(),
+ name, (ulong) root, (ulong) root->block(),
+ (ulong) table->next, (ulong) table->next->block(),
+ (ulong) table->next->prev,
+ (ulong) table->next->prev->block(),
+ (ulong) point, (ulong) point->block()));
+ //back trace
+ for (; table != point; table = table->prev)
+ DBUG_PRINT("error", ("back trace 0x%lx(0x%lx)",
+ (ulong) table, (ulong) table->block()));
+ result = 1;
+ goto err2;
+ }
+ table = table->next;
+ } while (table != root);
+err2:
+ return result;
+}
+
+#endif /* DBUG_OFF */
+
+#endif /*HAVE_QUERY_CACHE*/
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
new file mode 100644
index 00000000000..74b1a6cee96
--- /dev/null
+++ b/sql/sql_cache.h
@@ -0,0 +1,407 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef _SQL_CACHE_H
+#define _SQL_CACHE_H
+
+/* Query cache */
+
+/*
+ Can't create new free memory block if unused memory in block less
+ then QUERY_CACHE_MIN_ALLOCATION_UNIT.
+ if QUERY_CACHE_MIN_ALLOCATION_UNIT == 0 then
+ QUERY_CACHE_MIN_ALLOCATION_UNIT choosed automaticaly
+*/
+#define QUERY_CACHE_MIN_ALLOCATION_UNIT 512
+
+/* inittial size of hashes */
+#define QUERY_CACHE_DEF_QUERY_HASH_SIZE 1024
+#define QUERY_CACHE_DEF_TABLE_HASH_SIZE 1024
+
+/* minimal result data size when data allocated */
+#define QUERY_CACHE_MIN_RESULT_DATA_SIZE 1024*4
+
+/*
+ start estimation of first result block size only when number of queries
+ bigger then:
+*/
+#define QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER 3
+
+
+
+/* memory bins size spacing (see at Query_cache::init_cache (sql_cache.cc)) */
+#define QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 4
+#define QUERY_CACHE_MEM_BIN_STEP_PWR2 2
+#define QUERY_CACHE_MEM_BIN_PARTS_INC 1
+#define QUERY_CACHE_MEM_BIN_PARTS_MUL 1.2
+#define QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2 3
+
+/* how many free blocks check when finding most suitable before other 'end'
+ of list of free blocks */
+#define QUERY_CACHE_MEM_BIN_TRY 5
+
+/* query flags masks */
+#define QUERY_CACHE_CLIENT_LONG_FLAG_MASK 0x80
+#define QUERY_CACHE_CHARSET_CONVERT_MASK 0x7F
+
+/* packing parameters */
+#define QUERY_CACHE_PACK_ITERATION 2
+#define QUERY_CACHE_PACK_LIMIT (512*1024L)
+
+#define TABLE_COUNTER_TYPE uint
+
+struct Query_cache_block;
+struct Query_cache_block_table;
+struct Query_cache_table;
+struct Query_cache_query;
+struct Query_cache_result;
+class Query_cache;
+
+
+struct Query_cache_block_table
+{
+ TABLE_COUNTER_TYPE n; // numbr in table (from 0)
+ Query_cache_block_table *next, *prev;
+ Query_cache_table *parent;
+ inline Query_cache_block *block();
+};
+
+
+struct Query_cache_block
+{
+ enum block_type {FREE, QUERY, RESULT, RES_CONT, RES_BEG,
+ RES_INCOMPLETE, TABLE, INCOMPLETE};
+
+ ulong length; // length of all block
+ ulong used; // length of data
+ /*
+ Not used **pprev, **prev because really needed access to pervious block:
+ *pprev to join free blocks
+ *prev to access to opposite side of list in cyclic sorted list
+ */
+ Query_cache_block *pnext,*pprev, // physical next/previous block
+ *next,*prev; // logical next/previous block
+ block_type type;
+ TABLE_COUNTER_TYPE n_tables; // number of tables in query
+
+ inline my_bool is_free(void) { return type == FREE; }
+ void init(ulong length);
+ void destroy();
+ inline uint headers_len();
+ inline gptr data(void);
+ inline Query_cache_query *query();
+ inline Query_cache_table *table();
+ inline Query_cache_result *result();
+ inline Query_cache_block_table *table(TABLE_COUNTER_TYPE n);
+};
+
+struct Query_cache_query
+{
+ ulonglong limit_found_rows;
+ rw_lock_t lock;
+ Query_cache_block *res;
+ NET *wri;
+ ulong len;
+
+ inline void init_n_lock();
+ void unlock_n_destroy();
+ inline ulonglong found_rows() { return limit_found_rows; }
+ inline void found_rows(ulonglong rows) { limit_found_rows = rows; }
+ inline Query_cache_block *result() { return res; }
+ inline void result(Query_cache_block *p) { res=p; }
+ inline NET *writer() { return wri; }
+ inline void writer(NET *p) { wri=p; }
+ inline ulong length() { return len; }
+ inline ulong add(ulong packet_len) { return(len += packet_len); }
+ inline void length(ulong length) { len = length; }
+ inline gptr query()
+ {
+ return (gptr)(((byte*)this)+
+ ALIGN_SIZE(sizeof(Query_cache_query)));
+ }
+ void lock_writing();
+ void lock_reading();
+ my_bool try_lock_writing();
+ void unlock_writing();
+ void unlock_reading();
+ static byte *cache_key(const byte *record, uint *length, my_bool not_used);
+};
+
+
+struct Query_cache_table
+{
+ char *tbl;
+
+ inline char *db() { return (char *) data(); }
+ inline char *table() { return tbl; }
+ inline void table(char *table) { tbl = table; }
+ inline gptr data()
+ {
+ return (gptr)(((byte*)this)+
+ ALIGN_SIZE(sizeof(Query_cache_table)));
+ }
+};
+
+struct Query_cache_result
+{
+ Query_cache_block *query;
+
+ inline gptr data()
+ {
+ return (gptr)(((byte*) this)+
+ ALIGN_SIZE(sizeof(Query_cache_result)));
+ }
+ /* data_continue (if not whole packet contained by this block) */
+ inline Query_cache_block *parent() { return query; }
+ inline void parent (Query_cache_block *p) { query=p; }
+};
+
+
+extern "C"
+{
+ byte *query_cache_query_get_key(const byte *record, uint *length,
+ my_bool not_used);
+ byte *query_cache_table_get_key(const byte *record, uint *length,
+ my_bool not_used);
+}
+void query_cache_insert(NET *thd, const char *packet, ulong length);
+extern "C" void query_cache_invalidate_by_MyISAM_filename(const char* filename);
+
+
+struct Query_cache_memory_bin
+{
+#ifndef DBUG_OFF
+ ulong size;
+#endif
+ uint number;
+ Query_cache_block *free_blocks;
+
+ inline void init(ulong size_arg)
+ {
+#ifndef DBUG_OFF
+ size = size_arg;
+#endif
+ number = 0;
+ free_blocks = 0;
+ }
+};
+
+struct Query_cache_memory_bin_step
+{
+ ulong size;
+ ulong increment;
+ uint idx;
+ inline void init(ulong size_arg, uint idx_arg, ulong increment_arg)
+ {
+ size = size_arg;
+ idx = idx_arg;
+ increment = increment_arg;
+ }
+};
+
+class Query_cache
+{
+public:
+ /* Info */
+ ulong query_cache_size, query_cache_limit;
+ /* statistics */
+ ulong free_memory, queries_in_cache, hits, inserts, refused,
+ free_memory_blocks, total_blocks, lowmem_prunes;
+
+protected:
+ /*
+ The following mutex is locked when searching or changing global
+ query, tables lists or hashes. When we are operating inside the
+ query structure we locked an internal query block mutex.
+ LOCK SEQUENCE (to prevent deadlocks):
+ 1. structure_guard_mutex
+ 2. query block (for operation inside query (query block/results))
+ */
+ pthread_mutex_t structure_guard_mutex;
+ byte *cache; // cache memory
+ Query_cache_block *first_block; // physical location block list
+ Query_cache_block *queries_blocks; // query list (LIFO)
+ Query_cache_block *tables_blocks;
+
+ Query_cache_memory_bin *bins; // free block lists
+ Query_cache_memory_bin_step *steps; // bins spacing info
+ HASH queries, tables;
+ /* options */
+ ulong min_allocation_unit, min_result_data_size;
+ uint def_query_hash_size, def_table_hash_size;
+ uint mem_bin_num, mem_bin_steps; // See at init_cache & find_bin
+
+ my_bool initialized;
+
+ /* Exclude/include from cyclic double linked list */
+ static void double_linked_list_exclude(Query_cache_block *point,
+ Query_cache_block **list_pointer);
+ static void double_linked_list_simple_include(Query_cache_block *point,
+ Query_cache_block **
+ list_pointer);
+ static void double_linked_list_join(Query_cache_block *head_tail,
+ Query_cache_block *tail_head);
+
+ /* Table key generation */
+ static uint filename_2_table_key (char *key, const char *filename,
+ uint32 *db_langth);
+
+ /* The following functions require that structure_guard_mutex is locked */
+ void flush_cache();
+ my_bool free_old_query();
+ void free_query(Query_cache_block *point);
+ my_bool allocate_data_chain(Query_cache_block **result_block,
+ ulong data_len,
+ Query_cache_block *query_block,
+ my_bool first_block);
+ void invalidate_table(TABLE_LIST *table);
+ void invalidate_table(TABLE *table);
+ void invalidate_table(byte *key, uint32 key_length);
+ void invalidate_table(Query_cache_block *table_block);
+ my_bool register_all_tables(Query_cache_block *block,
+ TABLE_LIST *tables_used,
+ TABLE_COUNTER_TYPE tables);
+ my_bool insert_table(uint key_len, char *key,
+ Query_cache_block_table *node,
+ uint32 db_length);
+ void unlink_table(Query_cache_block_table *node);
+ Query_cache_block *get_free_block (ulong len, my_bool not_less,
+ ulong min);
+ void free_memory_block(Query_cache_block *point);
+ void split_block(Query_cache_block *block, ulong len);
+ Query_cache_block *join_free_blocks(Query_cache_block *first_block,
+ Query_cache_block *block_in_list);
+ my_bool append_next_free_block(Query_cache_block *block,
+ ulong add_size);
+ void exclude_from_free_memory_list(Query_cache_block *free_block);
+ void insert_into_free_memory_list(Query_cache_block *new_block);
+ my_bool move_by_type(byte **border, Query_cache_block **before,
+ ulong *gap, Query_cache_block *i);
+ uint find_bin(ulong size);
+ void move_to_query_list_end(Query_cache_block *block);
+ void insert_into_free_memory_sorted_list(Query_cache_block *new_block,
+ Query_cache_block **list);
+ void pack_cache();
+ void relink(Query_cache_block *oblock,
+ Query_cache_block *nblock,
+ Query_cache_block *next,
+ Query_cache_block *prev,
+ Query_cache_block *pnext,
+ Query_cache_block *pprev);
+ my_bool join_results(ulong join_limit);
+
+ /*
+ Following function control structure_guard_mutex
+ by themself or don't need structure_guard_mutex
+ */
+ void init();
+ ulong init_cache();
+ void make_disabled();
+ void free_cache(my_bool destruction);
+ Query_cache_block *write_block_data(ulong data_len, gptr data,
+ ulong header_len,
+ Query_cache_block::block_type type,
+ TABLE_COUNTER_TYPE ntab = 0,
+ my_bool under_guard=0);
+ my_bool append_result_data(Query_cache_block **result,
+ ulong data_len, gptr data,
+ Query_cache_block *parent);
+ my_bool write_result_data(Query_cache_block **result,
+ ulong data_len, gptr data,
+ Query_cache_block *parent,
+ Query_cache_block::block_type
+ type=Query_cache_block::RESULT);
+ inline ulong get_min_first_result_data_size();
+ inline ulong get_min_append_result_data_size();
+ Query_cache_block *allocate_block(ulong len, my_bool not_less,
+ ulong min,
+ my_bool under_guard=0);
+ /*
+ If query is cacheable return number tables in query
+ (query without tables not cached)
+ */
+ TABLE_COUNTER_TYPE is_cacheable(THD *thd, uint32 query_len, char *query,
+ LEX *lex, TABLE_LIST *tables_used);
+ public:
+
+ Query_cache(ulong query_cache_limit = ULONG_MAX,
+ ulong min_allocation_unit = QUERY_CACHE_MIN_ALLOCATION_UNIT,
+ ulong min_result_data_size = QUERY_CACHE_MIN_RESULT_DATA_SIZE,
+ uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE,
+ uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE);
+
+ /* resize query cache (return real query size, 0 if disabled) */
+ ulong resize(ulong query_cache_size);
+ inline void result_size_limit(ulong limit){query_cache_limit=limit;}
+
+ /* register query in cache */
+ void store_query(THD *thd, TABLE_LIST *used_tables);
+
+ /*
+ Check if the query is in the cache and if this is true send the
+ data to client.
+ */
+ int send_result_to_client(THD *thd, char *query, uint query_length);
+
+ /* Remove all queries that uses any of the listed following tables */
+ void invalidate(THD* thd, TABLE_LIST *tables_used,
+ my_bool using_transactions);
+ void invalidate(CHANGED_TABLE_LIST *tables_used);
+ void invalidate(THD* thd, TABLE *table, my_bool using_transactions);
+ void invalidate(THD *thd, const char *key, uint32 key_length,
+ my_bool using_transactions);
+
+ /* Remove all queries that uses any of the tables in following database */
+ void invalidate(char *db);
+
+ /* Remove all queries that uses any of the listed following table */
+ void invalidate_by_MyISAM_filename(const char *filename);
+
+ void flush();
+ void pack(ulong join_limit = QUERY_CACHE_PACK_LIMIT,
+ uint iteration_limit = QUERY_CACHE_PACK_ITERATION);
+
+ void destroy();
+
+ friend void query_cache_insert(NET *net, const char *packet, ulong length);
+ friend void query_cache_end_of_result(NET *net);
+ friend void query_cache_abort(NET *net);
+
+ /*
+ The following functions are only used when debugging
+ We don't protect these with ifndef DEBUG_OFF to not have to recompile
+ everything if we want to add checks of the cache at some places.
+ */
+ void wreck(uint line, const char *message);
+ void bins_dump();
+ void cache_dump();
+ void queries_dump();
+ void tables_dump();
+ my_bool check_integrity(bool not_locked);
+ my_bool in_list(Query_cache_block * root, Query_cache_block * point,
+ const char *name);
+ my_bool in_table_list(Query_cache_block_table * root,
+ Query_cache_block_table * point,
+ const char *name);
+ my_bool in_blocks(Query_cache_block * point);
+};
+
+extern Query_cache query_cache;
+extern TYPELIB query_cache_type_typelib;
+void query_cache_end_of_result(NET *net);
+void query_cache_abort(NET *net);
+
+#endif
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 316c544ba78..44faa3d6963 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -34,8 +34,9 @@
#ifdef __WIN__
#include <io.h>
#endif
+#include <mysys_err.h>
+#include <assert.h>
-extern struct rand_struct sql_rand;
/*****************************************************************************
** Instansiate templates
@@ -57,14 +58,14 @@ template class List_iterator<Alter_column>;
** User variables
****************************************************************************/
-static byte* get_var_key(user_var_entry *entry, uint *length,
- my_bool not_used __attribute__((unused)))
+extern "C" byte *get_var_key(user_var_entry *entry, uint *length,
+ my_bool not_used __attribute__((unused)))
{
*length=(uint) entry->name.length;
return (byte*) entry->name.str;
}
-static void free_var(user_var_entry *entry)
+extern "C" void free_user_var(user_var_entry *entry)
{
char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
if (entry->value && entry->value != pos)
@@ -78,66 +79,65 @@ static void free_var(user_var_entry *entry)
****************************************************************************/
THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
- insert_id_used(0),in_lock_tables(0),
+ insert_id_used(0),rand_used(0),in_lock_tables(0),
global_read_lock(0),bootstrap(0)
{
host=user=priv_user=db=query=ip=0;
+ host_or_ip= "connecting host";
locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password=
- query_start_used=0;
- query_length=col_access=0;
+ query_start_used=safe_to_cache_query=0;
+ db_length=query_length=col_access=0;
query_error=0;
next_insert_id=last_insert_id=0;
- open_tables=temporary_tables=0;
+ open_tables=temporary_tables=handler_tables=0;
+ current_tablenr=0;
+ handler_items=0;
tmp_table=0;
lock=locked_tables=0;
used_tables=0;
- gemini_spin_retries=0;
cuted_fields=sent_row_count=0L;
start_time=(time_t) 0;
current_linfo = 0;
slave_thread = 0;
slave_proxy_id = 0;
- last_nx_table = last_nx_db = 0;
+ file_id = 0;
cond_count=0;
- convert_set=0;
mysys_var=0;
+#ifndef DBUG_OFF
+ dbug_sentry=THD_SENTRY_MAGIC;
+#endif
net.vio=0;
+ net.last_error[0]=0; // If error on boot
ull=0;
system_thread=cleanup_done=0;
+ peer_port= 0; // For SHOW PROCESSLIST
+ transaction.changed_tables = 0;
#ifdef __WIN__
real_id = 0;
#endif
-#ifdef HAVE_GEMINI_DB
- bzero((char *)&gemini, sizeof(gemini));
-#endif
#ifdef SIGNAL_WITH_VIO_CLOSE
active_vio = 0;
- pthread_mutex_init(&active_vio_lock, MY_MUTEX_INIT_FAST);
#endif
+ pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
/* Variables with default values */
proc_info="login";
where="field list";
server_id = ::server_id;
- server_status=SERVER_STATUS_AUTOCOMMIT;
- update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
- options=thd_startup_options;
- sql_mode=(uint) opt_sql_mode;
- inactive_timeout=net_wait_timeout;
- open_options=ha_open_options;
- tx_isolation=session_tx_isolation=default_tx_isolation;
+ slave_net = 0;
command=COM_CONNECT;
set_query_id=1;
- default_select_limit= HA_POS_ERROR;
- max_join_size= ((::max_join_size != ~ (ulong) 0L) ? ::max_join_size :
- HA_POS_ERROR);
db_access=NO_ACCESS;
+ version=refresh_version; // For boot
+ init();
/* Initialize sub structures */
bzero((char*) &mem_root,sizeof(mem_root));
+ bzero((char*) &transaction.mem_root,sizeof(transaction.mem_root));
+ user_connect=(USER_CONN *)0;
hash_init(&user_vars, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
- (void (*)(void*)) free_var,0);
+ (hash_free_key) free_user_var,0);
#ifdef USING_TRANSACTIONS
bzero((char*) &transaction,sizeof(transaction));
if (opt_using_transactions)
@@ -150,19 +150,60 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
}
#endif
- /*
- We need good random number initialization for new thread
- Just coping global one will not work
+ /*
+ We need good random number initialization for new thread
+ Just coping global one will not work
*/
{
pthread_mutex_lock(&LOCK_thread_count);
- ulong tmp=(ulong) (rnd(&sql_rand) * ((ulong)0xffffffff));
- randominit(&rand, tmp + (ulong) start_time,
- tmp + (ulong) thread_id);
+ ulong tmp=(ulong) (my_rnd(&sql_rand) * 0xffffffff); /* make all bits random */
pthread_mutex_unlock(&LOCK_thread_count);
+ randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id);
}
}
+
+/*
+ Init common variables that has to be reset on start and on change_user
+*/
+
+void THD::init(void)
+{
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ variables= global_system_variables;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ server_status= SERVER_STATUS_AUTOCOMMIT;
+ options= thd_startup_options;
+ sql_mode=(uint) opt_sql_mode;
+ open_options=ha_open_options;
+ update_lock_default= (variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY :
+ TL_WRITE);
+ session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
+}
+
+/*
+ Do what's needed when one invokes change user
+
+ SYNOPSIS
+ change_user()
+
+ IMPLEMENTATION
+ Reset all resources that are connection specific
+*/
+
+
+void THD::change_user(void)
+{
+ cleanup();
+ cleanup_done=0;
+ init();
+ hash_init(&user_vars, USER_VARS_HASH_SIZE, 0, 0,
+ (hash_get_key) get_var_key,
+ (hash_free_key) free_user_var,0);
+}
+
+
/* Do operations that may take a long time */
void THD::cleanup(void)
@@ -174,21 +215,35 @@ void THD::cleanup(void)
lock=locked_tables; locked_tables=0;
close_thread_tables(this);
}
+ if (handler_tables)
+ {
+ open_tables=handler_tables; handler_tables=0;
+ close_thread_tables(this);
+ }
close_temporary_tables(this);
-#ifdef USING_TRANSACTIONS
- if (opt_using_transactions)
+ hash_free(&user_vars);
+ if (global_read_lock)
+ unlock_global_read_lock(this);
+ if (ull)
{
- close_cached_file(&transaction.trans_log);
- ha_close_connection(this);
+ pthread_mutex_lock(&LOCK_user_locks);
+ item_user_lock_release(ull);
+ pthread_mutex_unlock(&LOCK_user_locks);
+ ull= 0;
}
-#endif
cleanup_done=1;
DBUG_VOID_RETURN;
}
+
THD::~THD()
{
+ THD_CHECK_SENTRY(this);
DBUG_ENTER("~THD()");
+ /* Ensure that no one is using THD */
+ pthread_mutex_lock(&LOCK_delete);
+ pthread_mutex_unlock(&LOCK_delete);
+
/* Close connection */
if (net.vio)
{
@@ -197,23 +252,15 @@ THD::~THD()
}
if (!cleanup_done)
cleanup();
- if (global_read_lock)
- {
- pthread_mutex_lock(&LOCK_open);
- ::global_read_lock--;
- pthread_cond_broadcast(&COND_refresh);
- pthread_mutex_unlock(&LOCK_open);
- }
- if (ull)
+#ifdef USING_TRANSACTIONS
+ if (opt_using_transactions)
{
- pthread_mutex_lock(&LOCK_user_locks);
- item_user_lock_release(ull);
- pthread_mutex_unlock(&LOCK_user_locks);
+ close_cached_file(&transaction.trans_log);
+ ha_close_connection(this);
}
- hash_free(&user_vars);
+#endif
DBUG_PRINT("info", ("freeing host"));
-
if (host != localhost) // If not pointer to constant
safeFree(host);
if (user != delayed_user)
@@ -221,44 +268,172 @@ THD::~THD()
safeFree(db);
safeFree(ip);
free_root(&mem_root,MYF(0));
+ free_root(&transaction.mem_root,MYF(0));
mysys_var=0; // Safety (shouldn't be needed)
-#ifdef SIGNAL_WITH_VIO_CLOSE
- pthread_mutex_destroy(&active_vio_lock);
+ pthread_mutex_destroy(&LOCK_delete);
+#ifndef DBUG_OFF
+ dbug_sentry = THD_SENTRY_GONE;
#endif
DBUG_VOID_RETURN;
}
-void THD::prepare_to_die()
+
+void THD::awake(bool prepare_to_die)
{
+ THD_CHECK_SENTRY(this);
+ safe_mutex_assert_owner(&LOCK_delete);
+
+ if (prepare_to_die)
+ killed = 1;
thr_alarm_kill(real_id);
- killed = 1;
#ifdef SIGNAL_WITH_VIO_CLOSE
close_active_vio();
#endif
if (mysys_var)
+ {
+ pthread_mutex_lock(&mysys_var->mutex);
+ if (!system_thread) // Don't abort locks
+ mysys_var->abort=1;
+ /*
+ This broadcast could be up in the air if the victim thread
+ exits the cond in the time between read and broadcast, but that is
+ ok since all we want to do is to make the victim thread get out
+ of waiting on current_cond.
+ */
+ if (mysys_var->current_cond)
+ {
+ pthread_mutex_lock(mysys_var->current_mutex);
+ pthread_cond_broadcast(mysys_var->current_cond);
+ pthread_mutex_unlock(mysys_var->current_mutex);
+ }
+ pthread_mutex_unlock(&mysys_var->mutex);
+ }
+}
+
+/*
+ Remember the location of thread info, the structure needed for
+ sql_alloc() and the structure for the net buffer
+*/
+
+bool THD::store_globals()
+{
+ if (my_pthread_setspecific_ptr(THR_THD, this) ||
+ my_pthread_setspecific_ptr(THR_MALLOC, &mem_root) ||
+ my_pthread_setspecific_ptr(THR_NET, &net))
+ return 1;
+ mysys_var=my_thread_var;
+ dbug_thread_id=my_thread_id();
+ /*
+ By default 'slave_proxy_id' is 'thread_id'. They may later become different
+ if this is the slave SQL thread.
+ */
+ slave_proxy_id= thread_id;
+ return 0;
+}
+
+
+/* routings to adding tables to list of changed in transaction tables */
+
+inline static void list_include(CHANGED_TABLE_LIST** prev,
+ CHANGED_TABLE_LIST* curr,
+ CHANGED_TABLE_LIST* new_table)
+{
+ if (new_table)
+ {
+ *prev = new_table;
+ (*prev)->next = curr;
+ }
+}
+
+/* add table to list of changed in transaction tables */
+
+void THD::add_changed_table(TABLE *table)
+{
+ DBUG_ENTER("THD::add_changed_table(table)");
+
+ DBUG_ASSERT((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
+ table->file->has_transactions());
+ add_changed_table(table->table_cache_key, table->key_length);
+ DBUG_VOID_RETURN;
+}
+
+
+void THD::add_changed_table(const char *key, long key_length)
+{
+ DBUG_ENTER("THD::add_changed_table(key)");
+ CHANGED_TABLE_LIST **prev_changed = &transaction.changed_tables;
+ CHANGED_TABLE_LIST *curr = transaction.changed_tables;
+
+ for (; curr; prev_changed = &(curr->next), curr = curr->next)
+ {
+ int cmp = (long)curr->key_length - (long)key_length;
+ if (cmp < 0)
+ {
+ list_include(prev_changed, curr, changed_table_dup(key, key_length));
+ DBUG_PRINT("info",
+ ("key_length %u %u", key_length, (*prev_changed)->key_length));
+ DBUG_VOID_RETURN;
+ }
+ else if (cmp == 0)
{
- pthread_mutex_lock(&mysys_var->mutex);
- if (!system_thread) // Don't abort locks
- mysys_var->abort=1;
- if (mysys_var->current_cond)
+ cmp = memcmp(curr->key, key, curr->key_length);
+ if (cmp < 0)
+ {
+ list_include(prev_changed, curr, changed_table_dup(key, key_length));
+ DBUG_PRINT("info",
+ ("key_length %u %u", key_length,
+ (*prev_changed)->key_length));
+ DBUG_VOID_RETURN;
+ }
+ else if (cmp == 0)
{
- pthread_mutex_lock(mysys_var->current_mutex);
- pthread_cond_broadcast(mysys_var->current_cond);
- pthread_mutex_unlock(mysys_var->current_mutex);
+ DBUG_PRINT("info", ("already in list"));
+ DBUG_VOID_RETURN;
}
- pthread_mutex_unlock(&mysys_var->mutex);
}
+ }
+ *prev_changed = changed_table_dup(key, key_length);
+ DBUG_PRINT("info", ("key_length %u %u", key_length,
+ (*prev_changed)->key_length));
+ DBUG_VOID_RETURN;
}
-// remember the location of thread info, the structure needed for
-// sql_alloc() and the structure for the net buffer
-bool THD::store_globals()
+CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
+{
+ CHANGED_TABLE_LIST* new_table =
+ (CHANGED_TABLE_LIST*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST))+
+ key_length + 1);
+ if (!new_table)
+ {
+ my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
+ ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
+ killed= 1;
+ return 0;
+ }
+
+ new_table->key = (char *) (((byte*)new_table)+
+ ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST)));
+ new_table->next = 0;
+ new_table->key_length = key_length;
+ ::memcpy(new_table->key, key, key_length);
+ return new_table;
+}
+
+
+#ifdef SIGNAL_WITH_VIO_CLOSE
+void THD::close_active_vio()
{
- return (my_pthread_setspecific_ptr(THR_THD, this) ||
- my_pthread_setspecific_ptr(THR_MALLOC, &mem_root) ||
- my_pthread_setspecific_ptr(THR_NET, &net));
+ DBUG_ENTER("close_active_vio");
+ safe_mutex_assert_owner(&LOCK_delete);
+ if (active_vio)
+ {
+ vio_close(active_vio);
+ active_vio = 0;
+ }
+ DBUG_VOID_RETURN;
}
+#endif
/*****************************************************************************
** Functions to provide a interface to select results
@@ -291,10 +466,18 @@ bool select_send::send_fields(List<Item> &list,uint flag)
bool select_send::send_data(List<Item> &items)
{
- List_iterator<Item> li(items);
+ List_iterator_fast<Item> li(items);
String *packet= &thd->packet;
DBUG_ENTER("send_data");
+#ifdef HAVE_INNOBASE_DB
+ /* We may be passing the control from mysqld to the client: release the
+ InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
+ by thd */
+ if (thd->transaction.all.innobase_tid)
+ ha_release_temporary_latches(thd);
+#endif
+
if (thd->offset_limit)
{ // using limit offset,count
thd->offset_limit--;
@@ -304,7 +487,7 @@ bool select_send::send_data(List<Item> &items)
Item *item;
while ((item=li++))
{
- if (item->send(packet))
+ if (item->send(thd, packet))
{
packet->free(); // Free used
my_error(ER_OUT_OF_RESOURCES,MYF(0));
@@ -312,18 +495,22 @@ bool select_send::send_data(List<Item> &items)
}
}
thd->sent_row_count++;
+ if (!thd->net.vio)
+ DBUG_RETURN(0);
bool error=my_net_write(&thd->net,(char*) packet->ptr(),packet->length());
DBUG_RETURN(error);
}
-
-void select_send::send_error(uint errcode,const char *err)
-{
- ::send_error(&thd->net,errcode,err);
-}
-
bool select_send::send_eof()
{
+#ifdef HAVE_INNOBASE_DB
+ /* We may be passing the control from mysqld to the client: release the
+ InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
+ by thd */
+ if (thd->transaction.all.innobase_tid)
+ ha_release_temporary_latches(thd);
+#endif
+
/* Unlock tables before sending packet to gain some speed */
if (thd->lock)
{
@@ -353,7 +540,6 @@ select_export::~select_export()
int
select_export::prepare(List<Item> &list)
{
- char path[FN_REFLEN];
uint option=4;
bool blob_flag=0;
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
@@ -384,7 +570,7 @@ select_export::prepare(List<Item> &list)
}
/* Check if there is any blobs in data */
{
- List_iterator<Item> li(list);
+ List_iterator_fast<Item> li(list);
Item *item;
while ((item=li++))
{
@@ -431,7 +617,7 @@ bool select_export::send_data(List<Item> &items)
Item *item;
char *buff_ptr=buff;
uint used_length=0,items_left=items.elements;
- List_iterator<Item> li(items);
+ List_iterator_fast<Item> li(items);
if (my_b_write(&cache,(byte*) exchange->line_start->ptr(),
exchange->line_start->length()))
@@ -519,7 +705,7 @@ bool select_export::send_data(List<Item> &items)
bfill(space,sizeof(space),' ');
}
uint length=item->max_length-used_length;
- for ( ; length > sizeof(space) ; length-=sizeof(space))
+ for (; length > sizeof(space) ; length-=sizeof(space))
{
if (my_b_write(&cache,(byte*) space,sizeof(space)))
goto err;
@@ -554,9 +740,13 @@ err:
void select_export::send_error(uint errcode,const char *err)
{
::send_error(&thd->net,errcode,err);
- (void) end_io_cache(&cache);
- (void) my_close(file,MYF(0));
- file= -1;
+ if (file > 0)
+ {
+ (void) end_io_cache(&cache);
+ (void) my_close(file,MYF(0));
+ (void) my_delete(path,MYF(0)); // Delete file on error
+ file= -1;
+ }
}
@@ -624,7 +814,7 @@ select_dump::prepare(List<Item> &list __attribute__((unused)))
bool select_dump::send_data(List<Item> &items)
{
- List_iterator<Item> li(items);
+ List_iterator_fast<Item> li(items);
char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff)),*res;
tmp.length(0);
@@ -664,10 +854,13 @@ err:
void select_dump::send_error(uint errcode,const char *err)
{
::send_error(&thd->net,errcode,err);
- (void) end_io_cache(&cache);
- (void) my_close(file,MYF(0));
- (void) my_delete(path,MYF(0)); // Delete file on error
- file= -1;
+ if (file > 0)
+ {
+ (void) end_io_cache(&cache);
+ (void) my_close(file,MYF(0));
+ (void) my_delete(path,MYF(0)); // Delete file on error
+ file= -1;
+ }
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 8abf87c4cda..d96c6bb53cc 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,27 +21,39 @@
#pragma interface /* gcc class implementation */
#endif
+// TODO: create log.h and move all the log header stuff there
+
class Query_log_event;
class Load_log_event;
+class Slave_log_event;
-
+enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
+enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY };
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE };
-enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
+enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN};
+enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
+ DELAY_KEY_WRITE_ALL };
-// log info errors
+/* log info errors */
#define LOG_INFO_EOF -1
#define LOG_INFO_IO -2
#define LOG_INFO_INVALID -3
#define LOG_INFO_SEEK -4
-#define LOG_INFO_PURGE_NO_ROTATE -5
#define LOG_INFO_MEM -6
#define LOG_INFO_FATAL -7
#define LOG_INFO_IN_USE -8
+/* bitmap to SQL_LOG::close() */
+#define LOG_CLOSE_INDEX 1
+#define LOG_CLOSE_TO_BE_OPENED 2
+#define LOG_CLOSE_STOP_EVENT 4
+
+struct st_relay_log_info;
+
typedef struct st_log_info
{
char log_file_name[FN_REFLEN];
- my_off_t index_file_offset;
+ my_off_t index_file_offset, index_file_start_offset;
my_off_t pos;
bool fatal; // if the purge happens to give us a negative offset
pthread_mutex_t lock;
@@ -49,58 +61,118 @@ typedef struct st_log_info
~st_log_info() { pthread_mutex_destroy(&lock);}
} LOG_INFO;
+class Log_event;
-class MYSQL_LOG {
+class MYSQL_LOG
+ {
private:
+ /* LOCK_log and LOCK_index are inited by init_pthread_objects() */
pthread_mutex_t LOCK_log, LOCK_index;
+ pthread_cond_t update_cond;
+ ulonglong bytes_written;
time_t last_time,query_start;
IO_CACHE log_file;
- File index_file;
+ IO_CACHE index_file;
char *name;
- volatile enum_log_type log_type;
char time_buff[20],db[NAME_LEN+1];
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
- bool write_error,inited;
- bool no_rotate; // for binlog - if log name can never change
- // we should not try to rotate it or write any rotation events
- // the user should use FLUSH MASTER instead of FLUSH LOGS for
- // purging
+ // current file sequence number for load data infile binary logging
+ uint file_id;
+ uint open_count; // For replication
+ /*
+ For binlog - if log name can never change we should not try to rotate it
+ or write any rotation events. The user should use FLUSH MASTER instead
+ of FLUSH LOGS for purging.
+ */
+ volatile enum_log_type log_type;
+ enum cache_type io_cache_type;
+ bool write_error, inited;
+ bool need_start_event;
+ bool no_auto_events; // for relay binlog
+ /*
+ The max size before rotation (usable only if log_type == LOG_BIN: binary
+ logs and relay logs).
+ For a binlog, max_size should be max_binlog_size.
+ For a relay log, it should be max_relay_log_size if this is non-zero,
+ max_binlog_size otherwise.
+ max_size is set in init(), and dynamically changed (when one does SET
+ GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and
+ fix_max_relay_log_size).
+ */
+ ulong max_size;
+ friend class Log_event;
public:
MYSQL_LOG();
~MYSQL_LOG();
- pthread_mutex_t* get_log_lock() { return &LOCK_log; }
- void set_index_file_name(const char* index_file_name = 0);
- void init(enum_log_type log_type_arg);
- void open(const char *log_name,enum_log_type log_type,
- const char *new_name=0, bool null_created= 0);
- void new_file(bool inside_mutex = 0);
- bool open_index(int options);
- void close_index();
- bool write(THD *thd, enum enum_server_command command,const char *format,...);
+ void reset_bytes_written()
+ {
+ bytes_written = 0;
+ }
+ void harvest_bytes_written(ulonglong* counter)
+ {
+#ifndef DBUG_OFF
+ char buf1[22],buf2[22];
+#endif
+ DBUG_ENTER("harvest_bytes_written");
+ (*counter)+=bytes_written;
+ DBUG_PRINT("info",("counter: %s bytes_written: %s", llstr(*counter,buf1),
+ llstr(bytes_written,buf2)));
+ bytes_written=0;
+ DBUG_VOID_RETURN;
+ }
+ void set_max_size(ulong max_size_arg);
+ void signal_update() { pthread_cond_broadcast(&update_cond);}
+ void wait_for_update(THD* thd, bool master_or_slave);
+ void set_need_start_event() { need_start_event = 1; }
+ void init(enum_log_type log_type_arg,
+ enum cache_type io_cache_type_arg,
+ bool no_auto_events_arg, ulong max_size);
+ void init_pthread_objects();
+ void cleanup();
+ bool open(const char *log_name,enum_log_type log_type,
+ const char *new_name, const char *index_file_name_arg,
+ enum cache_type io_cache_type_arg,
+ bool no_auto_events_arg, ulong max_size);
+ void new_file(bool need_lock= 1);
+ bool write(THD *thd, enum enum_server_command command,
+ const char *format,...);
bool write(THD *thd, const char *query, uint query_length,
time_t query_start=0);
- bool write(Query_log_event* event_info); // binary log write
- bool write(Load_log_event* event_info);
- bool write(THD *thd, IO_CACHE *cache);
+ bool write(Log_event* event_info); // binary log write
+ bool write(THD *thd, IO_CACHE *cache, bool commit_or_rollback);
+
+ /*
+ v stands for vector
+ invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
+ */
+ bool appendv(const char* buf,uint len,...);
+ bool append(Log_event* ev);
+
int generate_new_name(char *new_name,const char *old_name);
void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name);
int purge_logs(THD* thd, const char* to_log);
- void close(bool exiting = 0); // if we are exiting, we also want to close the
- // index file
+ int purge_first_log(struct st_relay_log_info* rli);
+ bool reset_logs(THD* thd);
+ void close(uint exiting);
// iterating through the log index file
- int find_first_log(LOG_INFO* linfo, const char* log_name);
- int find_next_log(LOG_INFO* linfo);
+ int find_log_pos(LOG_INFO* linfo, const char* log_name,
+ bool need_mutex);
+ int find_next_log(LOG_INFO* linfo, bool need_mutex);
int get_current_log(LOG_INFO* linfo);
-
+ uint next_file_id();
inline bool is_open() { return log_type != LOG_CLOSED; }
- char* get_index_fname() { return index_file_name;}
- char* get_log_fname() { return log_file_name; }
- void lock_index() { pthread_mutex_lock(&LOCK_index);}
- void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
- File get_index_file() { return index_file;}
+ inline char* get_index_fname() { return index_file_name;}
+ inline char* get_log_fname() { return log_file_name; }
+ inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
+ inline IO_CACHE* get_log_file() { return &log_file; }
+
+ inline void lock_index() { pthread_mutex_lock(&LOCK_index);}
+ inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
+ inline IO_CACHE *get_index_file() { return &index_file;}
+ inline uint32 get_open_count() { return open_count; }
};
/* character conversion tables */
@@ -114,23 +186,25 @@ class CONVERT
void convert_array(const uchar *mapping,uchar *buff,uint length);
public:
const char *name;
- CONVERT(const char *name_par,uchar *from_par,uchar *to_par)
- :from_map(from_par),to_map(to_par),name(name_par) {}
+ uint numb;
+ CONVERT(const char *name_par,uchar *from_par,uchar *to_par, uint number)
+ :from_map(from_par),to_map(to_par),name(name_par),numb(number) {}
friend CONVERT *get_convert_set(const char *name_ptr);
inline void convert(char *a,uint length)
{
convert_array(from_map, (uchar*) a,length);
}
bool store(String *, const char *,uint);
+ inline uint number() { return numb; }
};
typedef struct st_copy_info {
ha_rows records;
ha_rows deleted;
ha_rows copied;
- ha_rows error;
+ ha_rows error_count;
enum enum_duplicates handle_duplicates;
- int escape_char;
+ int escape_char, last_errno;
} COPY_INFO;
@@ -165,11 +239,13 @@ class Key :public Sql_alloc {
public:
enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT };
enum Keytype type;
+ enum ha_key_alg algorithm;
List<key_part_spec> columns;
const char *Name;
Key(enum Keytype type_par,const char *name_arg,List<key_part_spec> &cols)
- :type(type_par), columns(cols),Name(name_arg) {}
+ :type(type_par), algorithm(HA_KEY_ALG_UNDEF), columns(cols), Name(name_arg)
+ {}
~Key() {}
const char *name() { return Name; }
};
@@ -214,114 +290,232 @@ public:
};
-/****************************************************************************
-** every connection is handle by a thread with a THD
-****************************************************************************/
-
class delayed_insert;
-class THD :public ilink {
+#define THD_SENTRY_MAGIC 0xfeedd1ff
+#define THD_SENTRY_GONE 0xdeadbeef
+
+#define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC)
+
+struct system_variables
+{
+ ulonglong myisam_max_extra_sort_file_size;
+ ulonglong myisam_max_sort_file_size;
+ ha_rows select_limit;
+ ha_rows max_join_size;
+ ulong bulk_insert_buff_size;
+ ulong join_buff_size;
+ ulong long_query_time;
+ ulong max_allowed_packet;
+ ulong max_heap_table_size;
+ ulong max_sort_length;
+ ulong max_tmp_tables;
+ ulong myisam_repair_threads;
+ ulong myisam_sort_buff_size;
+ ulong net_buffer_length;
+ ulong net_interactive_timeout;
+ ulong net_read_timeout;
+ ulong net_wait_timeout;
+ ulong net_write_timeout;
+ ulong net_retry_count;
+ ulong query_cache_type;
+ ulong read_buff_size;
+ ulong read_rnd_buff_size;
+ ulong sortbuff_size;
+ ulong tmp_table_size;
+ ulong tx_isolation;
+ ulong table_type;
+ ulong default_week_format;
+ ulong max_seeks_for_key;
+ ulong range_alloc_block_size;
+ ulong query_alloc_block_size;
+ ulong query_prealloc_size;
+ ulong trans_alloc_block_size;
+ ulong trans_prealloc_size;
+
+ my_bool log_warnings;
+ my_bool low_priority_updates;
+ my_bool new_mode;
+
+ CONVERT *convert_set;
+};
+
+
+/*
+ For each client connection we create a separate thread with THD serving as
+ a thread/connection descriptor
+*/
+
+class THD :public ilink
+{
public:
- NET net;
- LEX lex;
- MEM_ROOT mem_root;
- HASH user_vars;
- String packet; /* Room for 1 row */
- struct sockaddr_in remote;
- struct rand_struct rand;
- char *query,*thread_stack;
+ NET net; // client connection descriptor
+ LEX lex; // parse tree descriptor
+ MEM_ROOT mem_root; // 1 command-life memory pool
+ HASH user_vars; // hash for user variables
+ String packet; // dynamic buffer for network I/O
+ struct sockaddr_in remote; // client socket address
+ struct rand_struct rand; // used for authentication
+ struct system_variables variables; // Changeable local variables
+ pthread_mutex_t LOCK_delete; // Locked before thd is deleted
+
+ char *query; // Points to the current query,
+ /*
+ A pointer to the stack frame of handle_one_connection(),
+ which is called first in the thread for handling a client
+ */
+ char *thread_stack;
+
+ /*
+ host - host of the client
+ user - user of the client, set to NULL until the user has been read from
+ the connection
+ priv_user - not sure why we have it, but it is set to "boot" when we run
+ with --bootstrap
+ db - currently selected database
+ ip - client IP
+ */
char *host,*user,*priv_user,*db,*ip;
- const char *proc_info;
- uint client_capabilities,sql_mode,max_packet_length;
- uint master_access,db_access;
- TABLE *open_tables,*temporary_tables;
+ char priv_host[MAX_HOSTNAME];
+ /* remote (peer) port */
+ uint16 peer_port;
+ /*
+ Points to info-string that we show in SHOW PROCESSLIST
+ You are supposed to update thd->proc_info only if you have coded
+ a time-consuming piece that MySQL can get stuck in for a long time.
+ */
+ const char *proc_info;
+ /* points to host if host is available, otherwise points to ip */
+ const char *host_or_ip;
+
+ uint client_capabilities; /* What the client supports */
+ /* Determines if which non-standard SQL behaviour should be enabled */
+ uint sql_mode;
+ ulong max_client_packet_length;
+ ulong master_access; /* Global privileges from mysql.user */
+ ulong db_access; /* Privileges for current db */
+
+ /*
+ open_tables - list of regular tables in use by this thread
+ temporary_tables - list of temp tables in use by this thread
+ handler_tables - list of tables that were opened with HANDLER OPEN
+ and are still in use by this thread
+ */
+ TABLE *open_tables,*temporary_tables, *handler_tables;
+ // TODO: document the variables below
MYSQL_LOCK *lock,*locked_tables;
ULL *ull;
+#ifndef DBUG_OFF
+ uint dbug_sentry; // watch out for memory corruption
+#endif
struct st_my_thread_var *mysys_var;
enum enum_server_command command;
- uint32 server_id;
+ uint32 server_id;
+ uint32 file_id; // for LOAD DATA INFILE
+ /*
+ Used in error messages to tell user in what part of MySQL we found an
+ error. E. g. when where= "having clause", if fix_fields() fails, user
+ will know that the error was in having clause.
+ */
const char *where;
- char* last_nx_table; // last non-existent table, we need this for replication
- char* last_nx_db; // database of the last nx table
- time_t start_time,time_after_lock,user_time;
- time_t connect_time,thr_create_time; // track down slow pthread_create
+ time_t start_time,time_after_lock,user_time;
+ time_t connect_time,thr_create_time; // track down slow pthread_create
thr_lock_type update_lock_default;
delayed_insert *di;
struct st_transactions {
IO_CACHE trans_log;
- THD_TRANS all; /* Trans since BEGIN WORK */
- THD_TRANS stmt; /* Trans for current statement */
+ THD_TRANS all; // Trans since BEGIN WORK
+ THD_TRANS stmt; // Trans for current statement
uint bdb_lock_count;
+
+ /*
+ Tables changed in transaction (that must be invalidated in query cache).
+ List contain only transactional tables, that not invalidated in query
+ cache (instead of full list of changed in transaction tables).
+ */
+ CHANGED_TABLE_LIST* changed_tables;
+ MEM_ROOT mem_root; // Transaction-life memory allocation pool
+ void cleanup()
+ {
+ changed_tables = 0;
+ free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
+ }
} transaction;
-#ifdef HAVE_GEMINI_DB
- struct st_gemini gemini;
-#endif
- Item *free_list;
- CONVERT *convert_set;
+ Item *free_list, *handler_items;
Field *dupp_field;
#ifndef __WIN__
sigset_t signals,block_signals;
#endif
#ifdef SIGNAL_WITH_VIO_CLOSE
Vio* active_vio;
- pthread_mutex_t active_vio_lock;
#endif
- ulonglong next_insert_id,last_insert_id,current_insert_id;
- ha_rows select_limit,offset_limit,default_select_limit,cuted_fields,
- max_join_size, sent_row_count, examined_row_count;
- table_map used_tables;
- ulong query_id,version, inactive_timeout,options,thread_id;
- ulong gemini_spin_retries;
- long dbug_thread_id;
+ ulonglong next_insert_id,last_insert_id,current_insert_id,
+ limit_found_rows;
+ ha_rows select_limit, offset_limit, cuted_fields,
+ sent_row_count, examined_row_count;
+ table_map used_tables;
+ USER_CONN *user_connect;
+ ulong query_id,version, options,thread_id, col_access;
+ ulong rand_saved_seed1, rand_saved_seed2;
+ long dbug_thread_id;
pthread_t real_id;
- uint current_tablenr,tmp_table,cond_count,col_access,query_length;
- uint server_status,open_options;
- enum_tx_isolation tx_isolation, session_tx_isolation;
+ uint current_tablenr,tmp_table,cond_count;
+ uint server_status,open_options,system_thread;
+ uint32 query_length;
+ uint32 db_length;
+ /* variables.transaction_isolation is reset to this after each commit */
+ enum_tx_isolation session_tx_isolation;
char scramble[9];
bool slave_thread;
bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
bool no_errors, allow_sum_func, password, fatal_error;
- bool query_start_used,last_insert_id_used,insert_id_used;
- bool system_thread,in_lock_tables,global_read_lock;
+ bool query_start_used,last_insert_id_used,insert_id_used,rand_used;
+ bool in_lock_tables,global_read_lock;
bool query_error, bootstrap, cleanup_done;
+ bool safe_to_cache_query;
bool volatile killed;
+ /*
+ If we do a purge of binary logs, log index info of the threads
+ that are currently reading it needs to be adjusted. To do that
+ each thread that is using LOG_INFO needs to adjust the pointer to it
+ */
LOG_INFO* current_linfo;
- // if we do a purge of binary logs, log index info of the threads
- // that are currently reading it needs to be adjusted. To do that
- // each thread that is using LOG_INFO needs to adjust the pointer to it
-
- ulong slave_proxy_id; // in slave thread we need to know in behalf of which
- // thread the query is being run to replicate temp tables properly
+ /*
+ In slave thread we need to know in behalf of which
+ thread the query is being run to replicate temp tables properly
+ */
+ ulong slave_proxy_id;
+ NET* slave_net; // network connection from slave -> m.
+
+ /* Used by the sys_var class to store temporary values */
+ union
+ {
+ my_bool my_bool_value;
+ long long_value;
+ } sys_var_tmp;
THD();
~THD();
+ void init(void);
+ void change_user(void);
void cleanup(void);
bool store_globals();
#ifdef SIGNAL_WITH_VIO_CLOSE
inline void set_active_vio(Vio* vio)
{
- pthread_mutex_lock(&active_vio_lock);
+ pthread_mutex_lock(&LOCK_delete);
active_vio = vio;
- pthread_mutex_unlock(&active_vio_lock);
+ pthread_mutex_unlock(&LOCK_delete);
}
inline void clear_active_vio()
{
- pthread_mutex_lock(&active_vio_lock);
+ pthread_mutex_lock(&LOCK_delete);
active_vio = 0;
- pthread_mutex_unlock(&active_vio_lock);
- }
- inline void close_active_vio()
- {
- pthread_mutex_lock(&active_vio_lock);
- if(active_vio)
- {
- vio_close(active_vio);
- active_vio = 0;
- }
- pthread_mutex_unlock(&active_vio_lock);
+ pthread_mutex_unlock(&LOCK_delete);
}
+ void close_active_vio();
#endif
- void prepare_to_die();
+ void awake(bool prepare_to_die);
inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex,
const char* msg)
{
@@ -355,16 +549,18 @@ public:
}
return last_insert_id;
}
+ inline ulonglong found_rows(void)
+ {
+ return limit_found_rows;
+ }
inline bool active_transaction()
{
#ifdef USING_TRANSACTIONS
return (transaction.all.bdb_tid != 0 ||
- transaction.all.innodb_active_trans != 0 ||
- transaction.all.gemini_tid != 0);
+ transaction.all.innodb_active_trans != 0);
#else
return 0;
#endif
-
}
inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); }
inline gptr calloc(unsigned int size)
@@ -376,11 +572,44 @@ public:
}
inline char *strdup(const char *str)
{ return strdup_root(&mem_root,str); }
- inline char *memdup(const char *str, unsigned int size)
+ inline char *strmake(const char *str, uint size)
+ { return strmake_root(&mem_root,str,size); }
+ inline char *memdup(const char *str, uint size)
{ return memdup_root(&mem_root,str,size); }
+ inline char *memdup_w_gap(const char *str, uint size, uint gap)
+ {
+ gptr ptr;
+ if ((ptr=alloc_root(&mem_root,size+gap)))
+ memcpy(ptr,str,size);
+ return ptr;
+ }
+ inline gptr trans_alloc(unsigned int size)
+ {
+ return alloc_root(&transaction.mem_root,size);
+ }
+ void add_changed_table(TABLE *table);
+ void add_changed_table(const char *key, long key_length);
+ CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length);
+#ifndef EMBEDDED_LIBRARY
+ inline void clear_error()
+ {
+ net.last_error[0]= 0;
+ net.last_errno= 0;
+ }
+#else
+ void clear_error();
+#endif
};
+/* Flags for the THD::system_thread (bitmap) variable */
+#define SYSTEM_THREAD_DELAYED_INSERT 1
+#define SYSTEM_THREAD_SLAVE_IO 2
+#define SYSTEM_THREAD_SLAVE_SQL 4
+/*
+ Used to hold information about file and file structure in exchainge
+ via non-DB file (...INTO OUTFILE..., ...LOAD DATA...)
+*/
class sql_exchange :public Sql_alloc
{
public:
@@ -388,7 +617,7 @@ public:
String *field_term,*enclosed,*line_term,*line_start,*escaped;
bool opt_enclosed;
bool dumpfile;
- uint skip_lines;
+ ulong skip_lines;
sql_exchange(char *name,bool dumpfile_flag);
~sql_exchange() {}
};
@@ -399,6 +628,10 @@ public:
** This is used to get result from a select
*/
+class JOIN;
+
+void send_error(NET *net,uint sql_errno=0, const char *err=0);
+
class select_result :public Sql_alloc {
protected:
THD *thd;
@@ -408,7 +641,11 @@ public:
virtual int prepare(List<Item> &list) { return 0; }
virtual bool send_fields(List<Item> &list,uint flag)=0;
virtual bool send_data(List<Item> &items)=0;
- virtual void send_error(uint errcode,const char *err)=0;
+ virtual bool initialize_tables (JOIN *join=0) { return 0; }
+ virtual void send_error(uint errcode,const char *err)
+ {
+ ::send_error(&thd->net,errcode,err);
+ }
virtual bool send_eof()=0;
virtual void abort() {}
};
@@ -419,7 +656,6 @@ public:
select_send() {}
bool send_fields(List<Item> &list,uint flag);
bool send_data(List<Item> &items);
- void send_error(uint errcode,const char *err);
bool send_eof();
};
@@ -429,11 +665,13 @@ class select_export :public select_result {
File file;
IO_CACHE cache;
ha_rows row_count;
+ char path[FN_REFLEN];
uint field_term_length;
int field_sep_char,escape_char,line_sep_char;
bool fixed_row_size;
public:
- select_export(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) {}
+ select_export(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L)
+ { path[0]=0; }
~select_export();
int prepare(List<Item> &list);
bool send_fields(List<Item> &list,
@@ -443,6 +681,7 @@ public:
bool send_eof();
};
+
class select_dump :public select_result {
sql_exchange *exchange;
File file;
@@ -463,29 +702,28 @@ public:
class select_insert :public select_result {
- protected:
+ public:
TABLE *table;
List<Item> *fields;
- uint save_time_stamp;
ulonglong last_insert_id;
COPY_INFO info;
-public:
select_insert(TABLE *table_par,List<Item> *fields_par,enum_duplicates duplic)
- :table(table_par),fields(fields_par), save_time_stamp(0),last_insert_id(0)
- {
- bzero((char*) &info,sizeof(info));
- info.handle_duplicates=duplic;
- }
+ :table(table_par),fields(fields_par), last_insert_id(0)
+ {
+ bzero((char*) &info,sizeof(info));
+ info.handle_duplicates=duplic;
+ }
~select_insert();
int prepare(List<Item> &list);
- bool send_fields(List<Item> &list,
- uint flag) { return 0; }
+ bool send_fields(List<Item> &list, uint flag)
+ { return 0; }
bool send_data(List<Item> &items);
void send_error(uint errcode,const char *err);
bool send_eof();
};
+
class select_create: public select_insert {
ORDER *group;
const char *db;
@@ -496,15 +734,14 @@ class select_create: public select_insert {
MYSQL_LOCK *lock;
Field **field;
public:
- select_create (const char *db_name, const char *table_name,
- HA_CREATE_INFO *create_info_par,
- List<create_field> &fields_par,
- List<Key> &keys_par,
- List<Item> &select_fields,enum_duplicates duplic)
+ select_create(const char *db_name, const char *table_name,
+ HA_CREATE_INFO *create_info_par,
+ List<create_field> &fields_par,
+ List<Key> &keys_par,
+ List<Item> &select_fields,enum_duplicates duplic)
:select_insert (NULL, &select_fields, duplic), db(db_name),
name(table_name), extra_fields(&fields_par),keys(&keys_par),
- create_info(create_info_par),
- lock(0)
+ create_info(create_info_par), lock(0)
{}
int prepare(List<Item> &list);
bool send_data(List<Item> &values);
@@ -512,6 +749,24 @@ public:
void abort();
};
+
+class select_union :public select_result {
+ public:
+ TABLE *table;
+ COPY_INFO info;
+ TMP_TABLE_PARAM *tmp_table_param;
+ bool not_describe;
+
+ select_union(TABLE *table_par);
+ ~select_union();
+ int prepare(List<Item> &list);
+ bool send_fields(List<Item> &list, uint flag)
+ { return 0; }
+ bool send_data(List<Item> &items);
+ bool send_eof();
+ bool flush();
+};
+
/* Structs used when sorting */
typedef struct st_sort_field {
@@ -531,7 +786,6 @@ typedef struct st_sort_buffer {
SORT_FIELD *sortorder;
} SORT_BUFFER;
-
/* Structure for db & table in sql_yacc */
class Table_ident :public Sql_alloc {
@@ -559,5 +813,90 @@ class user_var_entry
char *value;
ulong length, update_query_id;
Item_result type;
+
+ double val(my_bool *null_value);
+ longlong val_int(my_bool *null_value);
+ String *val_str(my_bool *null_value, String *str, uint decimals);
+};
+
+
+/* Class for unique (removing of duplicates) */
+
+class Unique :public Sql_alloc
+{
+ DYNAMIC_ARRAY file_ptrs;
+ ulong max_elements, max_in_memory_size;
+ IO_CACHE file;
+ TREE tree;
+ byte *record_pointers;
+ bool flush();
+ uint size;
+
+public:
+ ulong elements;
+ Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
+ uint size_arg, ulong max_in_memory_size_arg);
+ ~Unique();
+ inline bool unique_add(gptr ptr)
+ {
+ if (tree.elements_in_tree > max_elements && flush())
+ return 1;
+ return !tree_insert(&tree,ptr,0);
+ }
+
+ bool get(TABLE *table);
+
+ friend int unique_write_to_file(gptr key, element_count count, Unique *unique);
+ friend int unique_write_to_ptrs(gptr key, element_count count, Unique *unique);
+};
+
+class multi_delete : public select_result
+{
+ TABLE_LIST *delete_tables, *table_being_deleted;
+ Unique **tempfiles;
+ THD *thd;
+ ha_rows deleted, found;
+ uint num_of_tables;
+ int error;
+ bool do_delete, transactional_tables, log_delayed, normal_tables;
+
+public:
+ multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables);
+ ~multi_delete();
+ int prepare(List<Item> &list);
+ bool send_fields(List<Item> &list,
+ uint flag) { return 0; }
+ bool send_data(List<Item> &items);
+ bool initialize_tables (JOIN *join);
+ void send_error(uint errcode,const char *err);
+ int do_deletes (bool from_send_error);
+ bool send_eof();
+};
+
+class multi_update : public select_result
+{
+ TABLE_LIST *all_tables, *update_tables, *table_being_updated;
+ THD *thd;
+ TABLE **tmp_tables, *main_table, *table_to_update;
+ TMP_TABLE_PARAM *tmp_table_param;
+ ha_rows updated, found;
+ List <Item> *fields, *values;
+ List <Item> **fields_for_table, **values_for_table;
+ uint table_count;
+ Copy_field *copy_field;
+ enum enum_duplicates handle_duplicates;
+ bool do_update, trans_safe, transactional_tables, log_delayed;
+
+public:
+ multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> *fields,
+ List<Item> *values, enum_duplicates handle_duplicates);
+ ~multi_update();
+ int prepare(List<Item> &list);
+ bool send_fields(List<Item> &list, uint flag) { return 0; }
+ bool send_data(List<Item> &items);
+ bool initialize_tables (JOIN *join);
+ void send_error(uint errcode,const char *err);
+ int do_updates (bool from_send_error);
+ bool send_eof();
};
diff --git a/sql/sql_crypt.cc b/sql/sql_crypt.cc
index 371d63f8c73..930ecfffef7 100644
--- a/sql/sql_crypt.cc
+++ b/sql/sql_crypt.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -46,7 +46,7 @@ void SQL_CRYPT::crypt_init(ulong *rand_nr)
for (i=0 ; i<= 255 ; i++)
{
- int idx= (uint) (rnd(&rand)*255.0);
+ int idx= (uint) (my_rnd(&rand)*255.0);
char a= decode_buff[idx];
decode_buff[idx]= decode_buff[i];
decode_buff[+i]=a;
@@ -62,7 +62,7 @@ void SQL_CRYPT::encode(char *str,uint length)
{
for (uint i=0; i < length; i++)
{
- shift^=(uint) (rnd(&rand)*255.0);
+ shift^=(uint) (my_rnd(&rand)*255.0);
uint idx= (uint) (uchar) str[0];
*str++ = (char) ((uchar) encode_buff[idx] ^ shift);
shift^= idx;
@@ -74,7 +74,7 @@ void SQL_CRYPT::decode(char *str,uint length)
{
for (uint i=0; i < length; i++)
{
- shift^=(uint) (rnd(&rand)*255.0);
+ shift^=(uint) (my_rnd(&rand)*255.0);
uint idx= (uint) ((unsigned char) str[0] ^ shift);
*str = decode_buff[idx];
shift^= (uint) (uchar) *str++;
diff --git a/sql/sql_crypt.h b/sql/sql_crypt.h
index b3a9d54133f..1b27f0a4d27 100644
--- a/sql/sql_crypt.h
+++ b/sql/sql_crypt.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 60eeb3777c4..ca9989d986c 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -25,45 +25,28 @@
#include <direct.h>
#endif
-static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
+static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
+ const char *db, const char *path,
uint level);
/* db-name is already validated when we come here */
-void mysql_create_db(THD *thd, char *db, uint create_options)
+int mysql_create_db(THD *thd, char *db, uint create_options, bool silent)
{
char path[FN_REFLEN+16];
MY_DIR *dirp;
long result=1;
+ int error = 0;
DBUG_ENTER("mysql_create_db");
-
+
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
- VOID(pthread_mutex_lock(&LOCK_open));
// do not create database if another thread is holding read lock
- if (global_read_lock)
+ if (wait_if_global_read_lock(thd,0))
{
- if (thd->global_read_lock)
- {
- net_printf(&thd->net, ER_CREATE_DB_WITH_READ_LOCK);
- VOID(pthread_mutex_unlock(&LOCK_open));
- goto exit;
- }
- while (global_read_lock && ! thd->killed)
- {
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- }
-
- if (thd->killed)
- {
- net_printf(&thd->net, ER_SERVER_SHUTDOWN);
- VOID(pthread_mutex_unlock(&LOCK_open));
- goto exit;
- }
-
+ error= -1;
+ goto exit2;
}
-
- VOID(pthread_mutex_unlock(&LOCK_open));
/* Check directory */
(void)sprintf(path,"%s/%s", mysql_data_home, db);
@@ -73,7 +56,8 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
my_dirend(dirp);
if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
{
- net_printf(&thd->net,ER_DB_CREATE_EXISTS,db);
+ my_error(ER_DB_CREATE_EXISTS,MYF(0),db);
+ error = -1;
goto exit;
}
result = 0;
@@ -83,142 +67,175 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
strend(path)[-1]=0; // Remove last '/' from path
if (my_mkdir(path,0777,MYF(0)) < 0)
{
- net_printf(&thd->net,ER_CANT_CREATE_DB,db,my_errno);
+ my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
+ error = -1;
goto exit;
}
}
- if (!thd->query)
- {
- thd->query_length = (uint) (strxmov(path,"create database ", db, NullS)-
- path);
- thd->query = path;
- }
+
+ if (!silent)
{
- mysql_update_log.write(thd,thd->query, thd->query_length);
- if (mysql_bin_log.is_open())
+ if (!thd->query)
{
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
+ /* The client used the old obsolete mysql_create_db() call */
+ thd->query_length= (uint) (strxmov(path,"create database `", db, "`",
+ NullS) - path);
+ thd->query= path;
}
+ {
+ mysql_update_log.write(thd,thd->query, thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
+ mysql_bin_log.write(&qinfo);
+ }
+ }
+ if (thd->query == path)
+ {
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ thd->query= 0;
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ }
+ send_ok(&thd->net, result);
}
- if (thd->query == path)
- {
- VOID(pthread_mutex_lock(&LOCK_thread_count));
- thd->query = 0; // just in case
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
- }
- send_ok(&thd->net, result);
exit:
+ start_waiting_global_read_lock(thd);
+exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(error);
}
-const char *del_exts[]=
-{".frm",".ISM",".ISD",".ISM",".HSH",".DAT",".MRG",".MYI",".MYD", ".db", ".BAK", NullS};
+const char *del_exts[]= {".frm", ".BAK", ".TMD", NullS};
static TYPELIB deletable_extentions=
{array_elements(del_exts)-1,"del_exts", del_exts};
+const char *known_exts[]=
+{".ISM",".ISD",".ISM",".MRG",".MYI",".MYD",".db",NullS};
+static TYPELIB known_extentions=
+{array_elements(known_exts)-1,"known_exts", known_exts};
-/* db-name is already validated when we come here */
-void mysql_rm_db(THD *thd,char *db,bool if_exists)
+/*
+ Drop all tables in a database and the database itself
+
+ SYNOPSIS
+ mysql_rm_db()
+ thd Thread handle
+ db Database name in the case given by user
+ It's already validated when we come here
+ if_exists Don't give error if database doesn't exists
+ silent Don't generate errors
+
+ RETURN
+ 0 ok (Database dropped)
+ -1 Error generated
+*/
+
+
+int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
{
long deleted=0;
- char path[FN_REFLEN+16];
+ int error = 0;
+ char path[FN_REFLEN+16], tmp_db[NAME_LEN+1];
MY_DIR *dirp;
DBUG_ENTER("mysql_rm_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
- VOID(pthread_mutex_lock(&LOCK_open));
// do not drop database if another thread is holding read lock
- if (global_read_lock)
+ if (wait_if_global_read_lock(thd,0))
{
- if (thd->global_read_lock)
- {
- net_printf(&thd->net, ER_DROP_DB_WITH_READ_LOCK);
- goto exit;
- }
- while (global_read_lock && ! thd->killed)
- {
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- }
-
- if (thd->killed)
- {
- net_printf(&thd->net, ER_SERVER_SHUTDOWN);
- goto exit;
- }
+ error= -1;
+ goto exit2;
}
(void) sprintf(path,"%s/%s",mysql_data_home,db);
unpack_dirname(path,path); // Convert if not unix
/* See if the directory exists */
- if (!(dirp = my_dir(path,MYF(MY_WME | MY_DONT_SORT))))
+ if (!(dirp = my_dir(path,MYF(MY_DONT_SORT))))
{
if (!if_exists)
- net_printf(&thd->net,ER_DB_DROP_EXISTS,db);
- else
+ {
+ error= -1;
+ my_error(ER_DB_DROP_EXISTS,MYF(0),db);
+ }
+ else if (!silent)
send_ok(&thd->net,0);
goto exit;
}
+ if (lower_case_table_names)
+ {
+ /* Convert database to lower case */
+ strmov(tmp_db, db);
+ casedn_str(tmp_db);
+ db= tmp_db;
+ }
+
+ pthread_mutex_lock(&LOCK_open);
remove_db_from_cache(db);
+ pthread_mutex_unlock(&LOCK_open);
- if ((deleted=mysql_rm_known_files(thd, dirp, path,0)) >= 0)
+ error = -1;
+ if ((deleted=mysql_rm_known_files(thd, dirp, db, path,0)) >= 0 && thd)
{
- /*
- If there are running queries on the tables, MySQL needs to get
- access to LOCK_open to end them. InnoDB on the other hand waits
- for the queries to end before dropping the database. That is why we
- must do the dropping with LOCK_open released.
- */
- VOID(pthread_mutex_unlock(&LOCK_open));
ha_drop_database(path);
- VOID(pthread_mutex_lock(&LOCK_open));
-
- if (!thd->query)
- {
- thd->query_length = (uint) (strxmov(path,"drop database ", db, NullS)-
- path);
- thd->query = path;
- }
- mysql_update_log.write(thd, thd->query, thd->query_length);
- if (mysql_bin_log.is_open())
- {
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
- }
- if (thd->query == path)
+ query_cache_invalidate1(db);
+ if (!silent)
{
- VOID(pthread_mutex_lock(&LOCK_thread_count));
- thd->query = 0; // just in case
- VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ if (!thd->query)
+ {
+ thd->query_length= (uint) (strxmov(path,"drop database `", db, "`",
+ NullS)-
+ path);
+ thd->query= path;
+ }
+ mysql_update_log.write(thd, thd->query, thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
+ mysql_bin_log.write(&qinfo);
+ }
+ if (thd->query == path)
+ {
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+ thd->query= 0;
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ }
+ send_ok(&thd->net,(ulong) deleted);
}
- send_ok(&thd->net,(ulong) deleted);
+ error = 0;
}
exit:
- VOID(pthread_mutex_unlock(&LOCK_open));
+ start_waiting_global_read_lock(thd);
+exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(error);
}
/*
Removes files with known extensions plus all found subdirectories that
- are 2 digits (raid directories).
+ are 2 hex digits (raid directories).
+ thd MUST be set when calling this function!
*/
-static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
- uint level)
+static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
+ const char *org_path, uint level)
{
long deleted=0;
ulong found_other_files=0;
char filePath[FN_REFLEN];
+ TABLE_LIST *tot_list=0, **tot_list_next;
+ List<String> raid_dirs;
+
DBUG_ENTER("mysql_rm_known_files");
DBUG_PRINT("enter",("path: %s", org_path));
- /* remove all files with known extensions */
+
+ tot_list_next= &tot_list;
for (uint idx=2 ;
idx < (uint) dirp->number_off_files && !thd->killed ;
@@ -228,48 +245,82 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
DBUG_PRINT("info",("Examining: %s", file->name));
/* Check if file is a raid directory */
- if (isdigit(file->name[0]) && isdigit(file->name[1]) &&
+ if ((isdigit(file->name[0]) ||
+ (file->name[0] >= 'a' && file->name[0] <= 'f')) &&
+ (isdigit(file->name[1]) ||
+ (file->name[1] >= 'a' && file->name[1] <= 'f')) &&
!file->name[2] && !level)
{
char newpath[FN_REFLEN];
MY_DIR *new_dirp;
+ String *dir;
+
strxmov(newpath,org_path,"/",file->name,NullS);
unpack_filename(newpath,newpath);
if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT))))
{
DBUG_PRINT("my",("New subdir found: %s", newpath));
- if ((mysql_rm_known_files(thd,new_dirp,newpath,1)) < 0)
+ if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1)) < 0)
{
my_dirend(dirp);
DBUG_RETURN(-1);
}
+ raid_dirs.push_back(dir=new String(newpath));
+ dir->copy();
+ continue;
}
+ found_other_files++;
continue;
}
if (find_type(fn_ext(file->name),&deletable_extentions,1+2) <= 0)
{
- found_other_files++;
+ if (find_type(fn_ext(file->name),&known_extentions,1+2) <= 0)
+ found_other_files++;
continue;
}
strxmov(filePath,org_path,"/",file->name,NullS);
- unpack_filename(filePath,filePath);
- if (my_delete(filePath,MYF(MY_WME)))
+ if (db && !my_strcasecmp(fn_ext(file->name), reg_ext))
{
- net_printf(&thd->net,ER_DB_DROP_DELETE,filePath,my_error);
- my_dirend(dirp);
- DBUG_RETURN(-1);
+ /* Drop the table nicely */
+ *fn_ext(file->name)=0; // Remove extension
+ TABLE_LIST *table_list=(TABLE_LIST*)
+ thd->calloc(sizeof(*table_list)+ strlen(db)+strlen(file->name)+2);
+ if (!table_list)
+ {
+ my_dirend(dirp);
+ DBUG_RETURN(-1);
+ }
+ table_list->db= (char*) (table_list+1);
+ strmov(table_list->real_name=strmov(table_list->db,db)+1,
+ file->name);
+ /* Link into list */
+ (*tot_list_next)= table_list;
+ tot_list_next= &table_list->next;
}
- deleted++;
- }
-
- my_dirend(dirp);
+ else
+ {
- if (thd->killed)
+ if (my_delete_with_symlink(filePath,MYF(MY_WME)))
+ {
+ my_dirend(dirp);
+ DBUG_RETURN(-1);
+ }
+ deleted++;
+ }
+ }
+ if (thd->killed ||
+ (tot_list && mysql_rm_table_part2_with_lock(thd, tot_list, 1, 1)))
{
- send_error(&thd->net,ER_SERVER_SHUTDOWN);
+ my_dirend(dirp);
DBUG_RETURN(-1);
}
-
+ List_iterator<String> it(raid_dirs);
+ String *dir;
+ while ((dir= it++))
+ if (rmdir(dir->c_ptr()) < 0)
+ found_other_files++;
+ my_dirend(dirp);
+
/*
If the directory is a symbolic link, remove the link first, then
remove the directory the symbolic link pointed at
@@ -280,7 +331,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
char *path=unpack_filename(tmp_path,org_path);
#ifdef HAVE_READLINK
int error;
-
+
/* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
pos=strend(path);
if (pos > path && pos[-1] == FN_LIBCHAR)
@@ -295,21 +346,21 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
/* Don't give errors if we can't delete 'RAID' directory */
if (level)
DBUG_RETURN(deleted);
- send_error(&thd->net);
DBUG_RETURN(-1);
}
/* Delete directory symbolic link pointed at */
path= filePath;
}
#endif
- /* Remove last FN_LIBCHAR to not cause a probelm on OS/2 */
+ /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
pos=strend(path);
+
if (pos > path && pos[-1] == FN_LIBCHAR)
*--pos=0;
/* Don't give errors if we can't delete 'RAID' directory */
if (rmdir(path) < 0 && !level)
{
- net_printf(&thd->net,ER_DB_DROP_RMDIR, path,errno);
+ my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
DBUG_RETURN(-1);
}
}
@@ -319,25 +370,25 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
bool mysql_change_db(THD *thd,const char *name)
{
- int length;
+ int length, db_length;
char *dbname=my_strdup((char*) name,MYF(MY_WME));
char path[FN_REFLEN];
- uint db_access;
+ ulong db_access;
DBUG_ENTER("mysql_change_db");
- if (!dbname || !(length=strip_sp(dbname)))
+ if (!dbname || !(db_length=strip_sp(dbname)))
{
x_free(dbname); /* purecov: inspected */
send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */
}
- if ((length > NAME_LEN) || check_db_name(dbname))
+ if ((db_length > NAME_LEN) || check_db_name(dbname))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, dbname);
x_free(dbname);
DBUG_RETURN(1);
}
- DBUG_PRINT("general",("Use database: %s", dbname));
+ DBUG_PRINT("info",("Use database: %s", dbname));
if (test_all_bits(thd->master_access,DB_ACLS))
db_access=DB_ACLS;
else
@@ -348,11 +399,11 @@ bool mysql_change_db(THD *thd,const char *name)
{
net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
thd->priv_user,
- thd->host ? thd->host : thd->ip ? thd->ip : "unknown",
+ thd->priv_host,
dbname);
mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
thd->priv_user,
- thd->host ? thd->host : thd->ip ? thd->ip : "unknown",
+ thd->priv_host,
dbname);
my_free(dbname,MYF(0));
DBUG_RETURN(1);
@@ -371,6 +422,7 @@ bool mysql_change_db(THD *thd,const char *name)
send_ok(&thd->net);
x_free(thd->db);
thd->db=dbname;
+ thd->db_length=db_length;
thd->db_access=db_access;
DBUG_RETURN(0);
}
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 2372e908152..7ca259425aa 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,164 +15,69 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Delete of records */
-
-#include "mysql_priv.h"
-#include "ha_innobase.h"
-
/*
- Optimize delete of all rows by doing a full generate of the table
- This will work even if the .ISM and .ISD tables are destroyed
+ Delete of records and truncate of tables.
+
+ Multi-table deletes were introduced by Monty and Sinisa
*/
-int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table)
-{
- char path[FN_REFLEN];
- int error;
- TABLE **table_ptr;
- my_bool lock_open_locked= 0;
- DBUG_ENTER("generate_table");
- thd->proc_info="generate_table";
-
- if (global_read_lock)
- {
- if(thd->global_read_lock)
- {
- my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
- table_list->real_name);
- DBUG_RETURN(-1);
- }
- pthread_mutex_lock(&LOCK_open);
- while (global_read_lock && ! thd->killed ||
- thd->version != refresh_version)
- {
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- }
- pthread_mutex_unlock(&LOCK_open);
- }
-
- /* If it is a temporary table, close and regenerate it */
- if ((table_ptr=find_temporary_table(thd,table_list->db,
- table_list->real_name)))
- {
- TABLE *table= *table_ptr;
- HA_CREATE_INFO create_info;
- table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
- bzero((char*) &create_info,sizeof(create_info));
- create_info.auto_increment_value= table->file->auto_increment_value;
- db_type table_type=table->db_type;
-
- strmov(path,table->path);
- *table_ptr= table->next; // Unlink table from list
- close_temporary(table,0);
- *fn_ext(path)=0; // Remove the .frm extension
- ha_create_table(path, &create_info,1);
- if ((error= (int) !(open_temporary_table(thd, path, table_list->db,
- table_list->real_name, 1))))
- {
- (void) rm_temporary_table(table_type, path);
- }
- }
- else
- {
- (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,table_list->db,
- table_list->real_name,reg_ext);
- fn_format(path,path,"","",4);
- VOID(pthread_mutex_lock(&LOCK_open));
- if (locked_table)
- mysql_lock_abort(thd,locked_table); // end threads waiting on lock
- // close all copies in use
- if (remove_table_from_cache(thd,table_list->db,table_list->real_name))
- {
- if (!locked_table)
- {
- VOID(pthread_mutex_unlock(&LOCK_open));
- DBUG_RETURN(1); // We must get a lock on table
- }
- }
- if (locked_table)
- locked_table->file->extra(HA_EXTRA_FORCE_REOPEN);
- if (thd->locked_tables)
- close_data_tables(thd,table_list->db,table_list->real_name);
- else
- close_thread_tables(thd,1);
- HA_CREATE_INFO create_info;
- bzero((char*) &create_info,sizeof(create_info));
- *fn_ext(path)=0; // Remove the .frm extension
- error= ha_create_table(path,&create_info,1) ? -1 : 0;
- if (thd->locked_tables && reopen_tables(thd,1,0))
- error= -1;
- lock_open_locked= 1; // Unlock mutex before return
- }
- if (!error)
- {
- mysql_update_log.write(thd,thd->query,thd->query_length);
- if (mysql_bin_log.is_open())
- {
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
- }
- send_ok(&thd->net); // This should return record count
- }
- if (lock_open_locked)
- VOID(pthread_mutex_unlock(&LOCK_open));
- DBUG_RETURN(error ? -1 : 0);
-}
+#include "mysql_priv.h"
+#include "ha_innodb.h"
+#include "sql_select.h"
-int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
- thr_lock_type lock_type, ulong options)
+int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
+ ha_rows limit, ulong options)
{
int error;
TABLE *table;
- SQL_SELECT *select;
+ SQL_SELECT *select=0;
READ_RECORD info;
- bool using_limit=limit != HA_POS_ERROR;
- bool use_generate_table,using_transactions;
+ bool using_limit=limit != HA_POS_ERROR;
+ bool transactional_table, log_delayed, safe_update;
+ ha_rows deleted;
DBUG_ENTER("mysql_delete");
- if (!table_list->db)
- table_list->db=thd->db;
- if ((thd->options & OPTION_SAFE_UPDATES) && !conds)
+ if (((safe_update=thd->options & OPTION_SAFE_UPDATES)) && !conds)
{
send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
DBUG_RETURN(1);
}
- use_generate_table= (!using_limit && !conds &&
- !(specialflag &
- (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
- !(thd->options &
- (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)));
-#ifdef HAVE_INNOBASE_DB
- /* We need to add code to not generate table based on the table type */
- if (!innodb_skip)
- use_generate_table=0; // Innodb can't use re-generate table
-#endif
- if (use_generate_table && ! thd->open_tables)
- {
- error=generate_table(thd,table_list,(TABLE*) 0);
- if (error <= 0)
- DBUG_RETURN(error); // Error or ok
- }
- if (!(table = open_ltable(thd,table_list,
- limit != HA_POS_ERROR ? TL_WRITE_LOW_PRIORITY :
- lock_type)))
+ if (!(table = open_ltable(thd, table_list, table_list->lock_type)))
DBUG_RETURN(-1);
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
thd->proc_info="init";
- if (use_generate_table)
- DBUG_RETURN(generate_table(thd,table_list,table));
table->map=1;
if (setup_conds(thd,table_list,&conds) || setup_ftfuncs(thd))
DBUG_RETURN(-1);
+ /* Test if the user wants to delete all rows */
+ if (!using_limit && (!conds || (conds->const_item() && conds->val_int())) &&
+ !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && !safe_update)
+ {
+ deleted= table->file->records;
+ if (!(error=table->file->delete_all_rows()))
+ {
+ error= -1; // ok
+ goto cleanup;
+ }
+ if (error != HA_ERR_WRONG_COMMAND)
+ {
+ table->file->print_error(error,MYF(0));
+ error=0;
+ goto cleanup;
+ }
+ /* Handler didn't support fast delete; Delete rows one by one */
+ }
+
table->used_keys=table->quick_keys=0; // Can't use 'only index'
select=make_select(table,0,0,conds,&error);
if (error)
DBUG_RETURN(-1);
- if ((select && select->check_quick(test(thd->options & OPTION_SAFE_UPDATES),
+ if ((select && select->check_quick(thd,
+ test(thd->options & OPTION_SAFE_UPDATES),
limit)) ||
!limit)
{
@@ -184,19 +89,51 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
/* If running in safe sql mode, don't allow updates without keys */
if (!table->quick_keys)
{
- thd->lex.options|=QUERY_NO_INDEX_USED;
- if ((thd->options & OPTION_SAFE_UPDATES) && limit == HA_POS_ERROR)
+ thd->lex.select_lex.options|=QUERY_NO_INDEX_USED;
+ if (safe_update && !using_limit)
{
delete select;
send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
DBUG_RETURN(1);
}
}
- (void) table->file->extra(HA_EXTRA_NO_READCHECK);
if (options & OPTION_QUICK)
(void) table->file->extra(HA_EXTRA_QUICK);
- init_read_record(&info,thd,table,select,-1,1);
- ulong deleted=0L;
+
+ if (order)
+ {
+ uint length;
+ SORT_FIELD *sortorder;
+ TABLE_LIST tables;
+ List<Item> fields;
+ List<Item> all_fields;
+ ha_rows examined_rows;
+
+ bzero((char*) &tables,sizeof(tables));
+ tables.table = table;
+
+ table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
+ MYF(MY_FAE | MY_ZEROFILL));
+ if (setup_order(thd, &tables, fields, all_fields, order) ||
+ !(sortorder=make_unireg_sortorder(order, &length)) ||
+ (table->found_records = filesort(table, sortorder, length,
+ select, 0L, HA_POS_ERROR,
+ &examined_rows))
+ == HA_POS_ERROR)
+ {
+ delete select;
+ DBUG_RETURN(-1); // This will force out message
+ }
+ /*
+ Filesort has already found and selected the rows we want to delete,
+ so we don't need the where clause
+ */
+ delete select;
+ select= 0;
+ }
+
+ init_read_record(&info,thd,table,select,1,1);
+ deleted=0L;
init_ftfuncs(thd,1);
thd->proc_info="updating";
while (!(error=info.read_record(&info)) && !thd->killed)
@@ -215,7 +152,15 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
else
{
table->file->print_error(error,MYF(0));
- error=0;
+ /*
+ In < 4.0.14 we set the error number to 0 here, but that
+ was not sensible, because then MySQL would not roll back the
+ failed DELETE, and also wrote it to the binlog. For MyISAM
+ tables a DELETE probably never should fail (?), but for
+ InnoDB it can fail in a FOREIGN KEY error or an
+ out-of-tablespace error.
+ */
+ error= 1;
break;
}
}
@@ -224,24 +169,42 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
}
thd->proc_info="end";
end_read_record(&info);
- (void) table->file->extra(HA_EXTRA_READCHECK);
+ free_io_cache(table); // Will not do any harm
if (options & OPTION_QUICK)
(void) table->file->extra(HA_EXTRA_NORMAL);
- using_transactions=table->file->has_transactions();
- if (deleted && (error <= 0 || !using_transactions))
+
+cleanup:
+ transactional_table= table->file->has_transactions();
+ log_delayed= (transactional_table || table->tmp_table);
+ if (deleted && (error <= 0 || !transactional_table))
{
mysql_update_log.write(thd,thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, using_transactions);
- if (mysql_bin_log.write(&qinfo) && using_transactions)
+ if (error <= 0)
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ log_delayed);
+ if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1;
}
- if (!using_transactions)
+ if (!log_delayed)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (using_transactions && ha_autocommit_or_rollback(thd,error >= 0))
- error=1;
+ if (transactional_table)
+ {
+ if (ha_autocommit_or_rollback(thd,error >= 0))
+ error=1;
+ }
+
+ /*
+ Store table for future invalidation or invalidate it in
+ the query cache if something changed
+ */
+ if (deleted)
+ {
+ query_cache_invalidate3(thd, table_list, 1);
+ }
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
@@ -258,3 +221,405 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit,
DBUG_RETURN(0);
}
+
+/***************************************************************************
+ Delete multiple tables from join
+***************************************************************************/
+
+#define MEM_STRIP_BUF_SIZE current_thd->variables.sortbuff_size
+
+extern "C" int refposcmp2(void* arg, const void *a,const void *b)
+{
+ /* arg is a pointer to file->ref_length */
+ return memcmp(a,b, *(int*) arg);
+}
+
+multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
+ uint num_of_tables_arg)
+ : delete_tables(dt), thd(thd_arg), deleted(0), found(0),
+ num_of_tables(num_of_tables_arg), error(0),
+ do_delete(0), transactional_tables(0), log_delayed(0), normal_tables(0)
+{
+ tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1));
+}
+
+
+int
+multi_delete::prepare(List<Item> &values)
+{
+ DBUG_ENTER("multi_delete::prepare");
+ do_delete= 1;
+ thd->proc_info="deleting from main table";
+ DBUG_RETURN(0);
+}
+
+
+bool
+multi_delete::initialize_tables(JOIN *join)
+{
+ TABLE_LIST *walk;
+ Unique **tempfiles_ptr;
+ DBUG_ENTER("initialize_tables");
+
+ if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
+ DBUG_RETURN(1);
+
+ table_map tables_to_delete_from=0;
+ for (walk= delete_tables ; walk ; walk=walk->next)
+ tables_to_delete_from|= walk->table->map;
+
+ walk= delete_tables;
+ for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
+ tab < end;
+ tab++)
+ {
+ if (tab->table->map & tables_to_delete_from)
+ {
+ /* We are going to delete from this table */
+ TABLE *tbl=walk->table=tab->table;
+ walk=walk->next;
+ /* Don't use KEYREAD optimization on this table */
+ tbl->no_keyread=1;
+ tbl->used_keys= 0;
+ if (tbl->file->has_transactions())
+ log_delayed= transactional_tables= 1;
+ else if (tbl->tmp_table != NO_TMP_TABLE)
+ log_delayed= 1;
+ else
+ normal_tables= 1;
+ }
+ }
+ walk= delete_tables;
+ tempfiles_ptr= tempfiles;
+ for (walk=walk->next ; walk ; walk=walk->next)
+ {
+ TABLE *table=walk->table;
+ *tempfiles_ptr++= new Unique (refposcmp2,
+ (void *) &table->file->ref_length,
+ table->file->ref_length,
+ MEM_STRIP_BUF_SIZE);
+ }
+ init_ftfuncs(thd,1);
+ DBUG_RETURN(thd->fatal_error != 0);
+}
+
+
+multi_delete::~multi_delete()
+{
+ for (table_being_deleted=delete_tables ;
+ table_being_deleted ;
+ table_being_deleted=table_being_deleted->next)
+ {
+ TABLE *t=table_being_deleted->table;
+ free_io_cache(t); // Alloced by unique
+ t->no_keyread=0;
+ }
+
+ for (uint counter= 0; counter < num_of_tables-1; counter++)
+ {
+ if (tempfiles[counter])
+ delete tempfiles[counter];
+ }
+}
+
+
+bool multi_delete::send_data(List<Item> &values)
+{
+ int secure_counter= -1;
+ DBUG_ENTER("multi_delete::send_data");
+
+ for (table_being_deleted=delete_tables ;
+ table_being_deleted ;
+ table_being_deleted=table_being_deleted->next, secure_counter++)
+ {
+ TABLE *table=table_being_deleted->table;
+
+ /* Check if we are using outer join and we didn't find the row */
+ if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
+ continue;
+
+ table->file->position(table->record[0]);
+ found++;
+
+ if (secure_counter < 0)
+ {
+ /* If this is the table we are scanning */
+ table->status|= STATUS_DELETED;
+ if (!(error=table->file->delete_row(table->record[0])))
+ deleted++;
+ else if (!table_being_deleted->next)
+ {
+ table->file->print_error(error,MYF(0));
+ DBUG_RETURN(1);
+ }
+ }
+ else
+ {
+ error=tempfiles[secure_counter]->unique_add((char*) table->file->ref);
+ if (error)
+ {
+ error=-1;
+ DBUG_RETURN(1);
+ }
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+void multi_delete::send_error(uint errcode,const char *err)
+{
+ DBUG_ENTER("multi_delete::send_error");
+
+ /* First send error what ever it is ... */
+ ::send_error(&thd->net,errcode,err);
+
+ /* If nothing deleted return */
+ if (!deleted)
+ DBUG_VOID_RETURN;
+
+ /* Something already deleted so we have to invalidate cache */
+ query_cache_invalidate3(thd, delete_tables, 1);
+
+ /* Below can happen when thread is killed early ... */
+ if (!table_being_deleted)
+ table_being_deleted=delete_tables;
+
+ /*
+ If rows from the first table only has been deleted and it is
+ transactional, just do rollback.
+ The same if all tables are transactional, regardless of where we are.
+ In all other cases do attempt deletes ...
+ */
+ if ((table_being_deleted->table->file->has_transactions() &&
+ table_being_deleted == delete_tables) || !normal_tables)
+ ha_rollback_stmt(thd);
+ else if (do_delete)
+ {
+ VOID(do_deletes(1));
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Do delete from other tables.
+ Returns values:
+ 0 ok
+ 1 error
+*/
+
+int multi_delete::do_deletes(bool from_send_error)
+{
+ int local_error= 0, counter= 0;
+ DBUG_ENTER("do_deletes");
+
+ if (from_send_error)
+ {
+ /* Found out table number for 'table_being_deleted*/
+ for (TABLE_LIST *aux=delete_tables;
+ aux != table_being_deleted;
+ aux=aux->next)
+ counter++;
+ }
+ else
+ table_being_deleted = delete_tables;
+
+ do_delete= 0;
+ if (!found)
+ DBUG_RETURN(0);
+ for (table_being_deleted=table_being_deleted->next;
+ table_being_deleted ;
+ table_being_deleted=table_being_deleted->next, counter++)
+ {
+ TABLE *table = table_being_deleted->table;
+ if (tempfiles[counter]->get(table))
+ {
+ local_error=1;
+ break;
+ }
+
+ READ_RECORD info;
+ init_read_record(&info,thd,table,NULL,0,1);
+ /*
+ Ignore any rows not found in reference tables as they may already have
+ been deleted by foreign key handling
+ */
+ info.ignore_not_found_rows= 1;
+ while (!(local_error=info.read_record(&info)) && !thd->killed)
+ {
+ if ((local_error=table->file->delete_row(table->record[0])))
+ {
+ table->file->print_error(local_error,MYF(0));
+ break;
+ }
+ deleted++;
+ }
+ end_read_record(&info);
+ if (local_error == -1) // End of file
+ local_error = 0;
+ }
+ DBUG_RETURN(local_error);
+}
+
+
+/*
+ Send ok to the client
+
+ return: 0 sucess
+ 1 error
+*/
+
+bool multi_delete::send_eof()
+{
+ thd->proc_info="deleting from reference tables";
+
+ /* Does deletes for the last n - 1 tables, returns 0 if ok */
+ int local_error= do_deletes(0); // returns 0 if success
+
+ /* reset used flags */
+ thd->proc_info="end";
+
+ /*
+ Write the SQL statement to the binlog if we deleted
+ rows and we succeeded, or also in an error case when there
+ was a non-transaction-safe table involved, since
+ modifications in it cannot be rolled back.
+ */
+ if (deleted && (error <= 0 || normal_tables))
+ {
+ mysql_update_log.write(thd,thd->query,thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ if (error <= 0)
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ log_delayed);
+ if (mysql_bin_log.write(&qinfo) && !normal_tables)
+ local_error=1; // Log write failed: roll back the SQL statement
+ }
+ if (!log_delayed)
+ thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+ }
+ /* Commit or rollback the current SQL statement */
+ if (transactional_tables)
+ if (ha_autocommit_or_rollback(thd,local_error > 0))
+ local_error=1;
+
+ if (deleted)
+ query_cache_invalidate3(thd, delete_tables, 1);
+
+ if (local_error)
+ ::send_error(&thd->net);
+ else
+ ::send_ok(&thd->net,deleted);
+ return 0;
+}
+
+
+/***************************************************************************
+ TRUNCATE TABLE
+****************************************************************************/
+
+/*
+ Optimize delete of all rows by doing a full generate of the table
+ This will work even if the .ISM and .ISD tables are destroyed
+
+ dont_send_ok should be set if:
+ - We should always wants to generate the table (even if the table type
+ normally can't safely do this.
+ - We don't want an ok to be sent to the end user.
+ - We don't want to log the truncate command
+ - If we want to have a name lock on the table on exit without errors.
+*/
+
+int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
+{
+ HA_CREATE_INFO create_info;
+ char path[FN_REFLEN];
+ TABLE **table_ptr;
+ int error;
+ DBUG_ENTER("mysql_truncate");
+
+ /* If it is a temporary table, close and regenerate it */
+ if (!dont_send_ok && (table_ptr=find_temporary_table(thd,table_list->db,
+ table_list->real_name)))
+ {
+ TABLE *table= *table_ptr;
+ HA_CREATE_INFO create_info;
+ table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
+ bzero((char*) &create_info,sizeof(create_info));
+ create_info.auto_increment_value= table->file->auto_increment_value;
+ db_type table_type=table->db_type;
+
+ strmov(path,table->path);
+ *table_ptr= table->next; // Unlink table from list
+ close_temporary(table,0);
+ *fn_ext(path)=0; // Remove the .frm extension
+ ha_create_table(path, &create_info,1);
+ // We don't need to call invalidate() because this table is not in cache
+ if ((error= (int) !(open_temporary_table(thd, path, table_list->db,
+ table_list->real_name, 1))))
+ (void) rm_temporary_table(table_type, path);
+ /*
+ Sasha: if we return here we will not have binloged the truncation and
+ we will not send_ok() to the client.
+ */
+ goto end;
+ }
+
+ (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,table_list->db,
+ table_list->real_name,reg_ext);
+ fn_format(path,path,"","",4);
+
+ if (!dont_send_ok)
+ {
+ db_type table_type;
+ if ((table_type=get_table_type(path)) == DB_TYPE_UNKNOWN)
+ {
+ my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db,
+ table_list->real_name);
+ DBUG_RETURN(-1);
+ }
+ if (!ha_supports_generate(table_type))
+ {
+ /* Probably InnoDB table */
+ table_list->lock_type= TL_WRITE;
+ DBUG_RETURN(mysql_delete(thd, table_list, (COND*) 0, (ORDER*) 0,
+ HA_POS_ERROR, 0));
+ }
+ if (lock_and_wait_for_table_name(thd, table_list))
+ DBUG_RETURN(-1);
+ }
+
+ bzero((char*) &create_info,sizeof(create_info));
+ *fn_ext(path)=0; // Remove the .frm extension
+ error= ha_create_table(path,&create_info,1) ? -1 : 0;
+ query_cache_invalidate3(thd, table_list, 0);
+
+end:
+ if (!dont_send_ok)
+ {
+ if (!error)
+ {
+ mysql_update_log.write(thd,thd->query,thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ thd->tmp_table);
+ mysql_bin_log.write(&qinfo);
+ }
+ send_ok(&thd->net); // This should return record count
+ }
+ VOID(pthread_mutex_lock(&LOCK_open));
+ unlock_table_name(thd, table_list);
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ }
+ else if (error)
+ {
+ VOID(pthread_mutex_lock(&LOCK_open));
+ unlock_table_name(thd, table_list);
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ }
+ DBUG_RETURN(error ? -1 : 0);
+}
diff --git a/sql/sql_do.cc b/sql/sql_do.cc
index 57a6f88ed63..70124c2d796 100644
--- a/sql/sql_do.cc
+++ b/sql/sql_do.cc
@@ -25,7 +25,7 @@ int mysql_do(THD *thd, List<Item> &values)
List_iterator<Item> li(values);
Item *value;
DBUG_ENTER("mysql_do");
- if (setup_fields(thd,0, values, 0, 0))
+ if (setup_fields(thd,0, values, 0, 0, 0))
DBUG_RETURN(-1);
while ((value = li++))
value->val_int();
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
new file mode 100644
index 00000000000..963111015da
--- /dev/null
+++ b/sql/sql_handler.cc
@@ -0,0 +1,305 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/* HANDLER ... commands - direct access to ISAM */
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+#include <assert.h>
+
+/* TODO:
+ HANDLER blabla OPEN [ AS foobar ] [ (column-list) ]
+
+ the most natural (easiest, fastest) way to do it is to
+ compute List<Item> field_list not in mysql_ha_read
+ but in mysql_ha_open, and then store it in TABLE structure.
+
+ The problem here is that mysql_parse calls free_item to free all the
+ items allocated at the end of every query. The workaround would to
+ keep two item lists per THD - normal free_list and handler_items.
+ The second is to be freeed only on thread end. mysql_ha_open should
+ then do { handler_items=concat(handler_items, free_list); free_list=0; }
+
+ But !!! do_command calls free_root at the end of every query and frees up
+ all the sql_alloc'ed memory. It's harder to work around...
+ */
+
+#define HANDLER_TABLES_HACK(thd) { \
+ TABLE *tmp=thd->open_tables; \
+ thd->open_tables=thd->handler_tables; \
+ thd->handler_tables=tmp; }
+
+static TABLE **find_table_ptr_by_name(THD *thd,const char *db,
+ const char *table_name, bool is_alias);
+
+int mysql_ha_open(THD *thd, TABLE_LIST *tables)
+{
+ HANDLER_TABLES_HACK(thd);
+ int err=open_tables(thd,tables);
+ HANDLER_TABLES_HACK(thd);
+ if (err)
+ return -1;
+
+ // there can be only one table in *tables
+ if (!(tables->table->file->table_flags() & HA_CAN_SQL_HANDLER))
+ {
+ my_printf_error(ER_ILLEGAL_HA,ER(ER_ILLEGAL_HA),MYF(0), tables->alias);
+ mysql_ha_close(thd, tables,1);
+ return -1;
+ }
+
+ send_ok(&thd->net);
+ return 0;
+}
+
+int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok)
+{
+ TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->alias, 1);
+
+ if (*ptr)
+ {
+ VOID(pthread_mutex_lock(&LOCK_open));
+ if (close_thread_table(thd, ptr))
+ {
+ /* Tell threads waiting for refresh that something has happened */
+ VOID(pthread_cond_broadcast(&COND_refresh));
+ }
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ }
+ else
+ {
+ my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0),
+ tables->alias, "HANDLER");
+ return -1;
+ }
+ if (!dont_send_ok)
+ send_ok(&thd->net);
+ return 0;
+}
+
+int mysql_ha_closeall(THD *thd, TABLE_LIST *tables)
+{
+ TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->real_name, 0);
+ if (*ptr && close_thread_table(thd, ptr))
+ {
+ /* Tell threads waiting for refresh that something has happened */
+ VOID(pthread_cond_broadcast(&COND_refresh));
+ }
+ return 0;
+}
+
+static enum enum_ha_read_modes rkey_to_rnext[]=
+ { RNEXT, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV };
+
+
+int mysql_ha_read(THD *thd, TABLE_LIST *tables,
+ enum enum_ha_read_modes mode, char *keyname, List<Item> *key_expr,
+ enum ha_rkey_function ha_rkey_mode, Item *cond,
+ ha_rows select_limit,ha_rows offset_limit)
+{
+ int err, keyno=-1;
+ TABLE *table=*find_table_ptr_by_name(thd, tables->db, tables->alias, 1);
+ if (!table)
+ {
+ my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0),
+ tables->alias,"HANDLER");
+ return -1;
+ }
+ tables->table=table;
+
+ if (cond && cond->fix_fields(thd,tables))
+ return -1;
+
+ table->file->init_table_handle_for_HANDLER(); // Only InnoDB requires it
+
+ if (keyname)
+ {
+ if ((keyno=find_type(keyname, &table->keynames, 1+2)-1)<0)
+ {
+ my_printf_error(ER_KEY_DOES_NOT_EXITS,ER(ER_KEY_DOES_NOT_EXITS),MYF(0),
+ keyname,tables->alias);
+ return -1;
+ }
+ table->file->index_init(keyno);
+ }
+
+ List<Item> list;
+ list.push_front(new Item_field(NULL,NULL,"*"));
+ List_iterator<Item> it(list);
+ uint num_rows;
+ it++;
+
+ insert_fields(thd,tables,tables->db,tables->alias,&it);
+
+ select_limit+=offset_limit;
+ send_fields(thd,list,1);
+
+ HANDLER_TABLES_HACK(thd);
+ MYSQL_LOCK *lock=mysql_lock_tables(thd,&tables->table,1);
+ HANDLER_TABLES_HACK(thd);
+ if (!lock)
+ goto err0; // mysql_lock_tables() printed error message already
+
+ table->file->init_table_handle_for_HANDLER(); // Only InnoDB requires it
+
+ for (num_rows=0; num_rows < select_limit; )
+ {
+ switch(mode) {
+ case RFIRST:
+ if (keyname)
+ err=table->file->index_first(table->record[0]);
+ else
+ {
+ if (!(err=table->file->rnd_init(1)))
+ err=table->file->rnd_next(table->record[0]);
+ }
+ mode=RNEXT;
+ break;
+ case RLAST:
+ DBUG_ASSERT(keyname != 0);
+ err=table->file->index_last(table->record[0]);
+ mode=RPREV;
+ break;
+ case RNEXT:
+ err=keyname ?
+ table->file->index_next(table->record[0]) :
+ table->file->rnd_next(table->record[0]);
+ break;
+ case RPREV:
+ DBUG_ASSERT(keyname != 0);
+ err=table->file->index_prev(table->record[0]);
+ break;
+ case RKEY:
+ {
+ DBUG_ASSERT(keyname != 0);
+ KEY *keyinfo=table->key_info+keyno;
+ KEY_PART_INFO *key_part=keyinfo->key_part;
+ uint key_len;
+ byte *key;
+ if (key_expr->elements > keyinfo->key_parts)
+ {
+ my_printf_error(ER_TOO_MANY_KEY_PARTS,ER(ER_TOO_MANY_KEY_PARTS),
+ MYF(0),keyinfo->key_parts);
+ goto err;
+ }
+ List_iterator_fast<Item> it_ke(*key_expr);
+ Item *item;
+ for (key_len=0 ; (item=it_ke++) ; key_part++)
+ {
+ if (item->fix_fields(thd, tables))
+ goto err;
+ if (item->used_tables() & ~RAND_TABLE_BIT)
+ {
+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"HANDLER ... READ");
+ goto err;
+ }
+ item->save_in_field(key_part->field, 1);
+ key_len+=key_part->store_length;
+ }
+ if (!(key= (byte*) thd->calloc(ALIGN_SIZE(key_len))))
+ {
+ send_error(&thd->net,ER_OUTOFMEMORY);
+ goto err;
+ }
+ key_copy(key, table, keyno, key_len);
+ err=table->file->index_read(table->record[0],
+ key,key_len,ha_rkey_mode);
+ mode=rkey_to_rnext[(int)ha_rkey_mode];
+ break;
+ }
+ default:
+ send_error(&thd->net,ER_ILLEGAL_HA);
+ goto err;
+ }
+
+ if (err == HA_ERR_RECORD_DELETED)
+ continue;
+ if (err)
+ {
+ if (err != HA_ERR_KEY_NOT_FOUND && err != HA_ERR_END_OF_FILE)
+ {
+ sql_print_error("mysql_ha_read: Got error %d when reading table '%s'",
+ err, tables->real_name);
+ table->file->print_error(err,MYF(0));
+ goto err;
+ }
+ goto ok;
+ }
+ if (cond && !cond->val_int())
+ continue;
+ if (num_rows >= offset_limit)
+ {
+ String *packet = &thd->packet;
+ Item *item;
+ packet->length(0);
+ it.rewind();
+ while ((item=it++))
+ {
+ if (item->send(thd,packet))
+ {
+ packet->free(); // Free used
+ my_error(ER_OUT_OF_RESOURCES,MYF(0));
+ goto err;
+ }
+ }
+ my_net_write(&thd->net, (char*)packet->ptr(), packet->length());
+ }
+ num_rows++;
+ }
+ok:
+ mysql_unlock_tables(thd,lock);
+ send_eof(&thd->net);
+ return 0;
+err:
+ mysql_unlock_tables(thd,lock);
+err0:
+ return -1;
+}
+
+static TABLE **find_table_ptr_by_name(THD *thd, const char *db,
+ const char *table_name, bool is_alias)
+{
+ int dblen;
+ TABLE **ptr;
+
+ DBUG_ASSERT(db);
+ dblen=*db ? strlen(db)+1 : 0;
+ ptr=&(thd->handler_tables);
+
+ for (TABLE *table=*ptr; table ; table=*ptr)
+ {
+ if ((!dblen || !memcmp(table->table_cache_key, db, dblen)) &&
+ !my_strcasecmp((is_alias ? table->table_name : table->real_name),table_name))
+ {
+ if (table->version != refresh_version)
+ {
+ VOID(pthread_mutex_lock(&LOCK_open));
+ if (close_thread_table(thd, ptr))
+ {
+ /* Tell threads waiting for refresh that something has happened */
+ VOID(pthread_cond_broadcast(&COND_refresh));
+ }
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ continue;
+ }
+ break;
+ }
+ ptr=&(table->next);
+ }
+ return ptr;
+}
+
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 42c6d02576b..97b7c1db03d 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -23,9 +23,9 @@
static int check_null_fields(THD *thd,TABLE *entry);
static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list);
static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup,
- char *query, uint query_length, bool log_on);
+ char *query, uint query_length, int log_on);
static void end_delayed_insert(THD *thd);
-static pthread_handler_decl(handle_delayed_insert,arg);
+extern "C" pthread_handler_decl(handle_delayed_insert,arg);
static void unlink_blobs(register TABLE *table);
/* Define to force use of my_malloc() if the allocated memory block is big */
@@ -38,10 +38,13 @@ static void unlink_blobs(register TABLE *table);
#define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0))
#endif
+#define DELAYED_LOG_UPDATE 1
+#define DELAYED_LOG_BIN 2
/*
Check if insert fields are correct
- Resets form->time_stamp if a timestamp value is set
+ Updates table->time_stamp to point to timestamp field or 0, depending on
+ if timestamp should be updated or not.
*/
static int
@@ -60,7 +63,7 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
if (grant_option &&
check_grant_all_columns(thd,INSERT_ACL,table))
return -1;
- table->time_stamp=0; // This should be saved
+ table->time_stamp=0; // This is saved by caller
}
else
{ // Part field list
@@ -73,47 +76,62 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
}
TABLE_LIST table_list;
bzero((char*) &table_list,sizeof(table_list));
- table_list.alias= table_list.real_name= table->table_name;
+ table_list.db= table->table_cache_key;
+ table_list.real_name= table_list.alias= table->table_name;
table_list.table=table;
table_list.grant=table->grant;
thd->dupp_field=0;
- if (setup_tables(&table_list) || setup_fields(thd,&table_list,fields,1,0))
+ if (setup_tables(&table_list) ||
+ setup_fields(thd,&table_list,fields,1,0,0))
return -1;
if (thd->dupp_field)
{
my_error(ER_FIELD_SPECIFIED_TWICE,MYF(0), thd->dupp_field->field_name);
return -1;
}
+ table->time_stamp=0;
if (table->timestamp_field && // Don't set timestamp if used
- table->timestamp_field->query_id == thd->query_id)
- table->time_stamp=0; // This should be saved
+ table->timestamp_field->query_id != thd->query_id)
+ table->time_stamp= table->timestamp_field->offset()+1;
}
- // For the values we need select_priv
+ // For the values we need select_priv
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
return 0;
}
int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
- List<List_item> &values_list,enum_duplicates duplic,
- thr_lock_type lock_type)
+ List<List_item> &values_list,enum_duplicates duplic)
{
int error;
- bool log_on= ((thd->options & OPTION_UPDATE_LOG) ||
- !(thd->master_access & PROCESS_ACL));
- bool using_transactions;
+ /*
+ log_on is about delayed inserts only.
+ By default, both logs are enabled (this won't cause problems if the server
+ runs without --log-update or --log-bin).
+ */
+ int log_on= DELAYED_LOG_UPDATE | DELAYED_LOG_BIN ;
+
+ bool transactional_table, log_delayed, bulk_insert;
uint value_count;
- uint save_time_stamp;
ulong counter = 1;
ulonglong id;
COPY_INFO info;
TABLE *table;
- List_iterator<List_item> its(values_list);
+ List_iterator_fast<List_item> its(values_list);
List_item *values;
char *query=thd->query;
+ thr_lock_type lock_type = table_list->lock_type;
DBUG_ENTER("mysql_insert");
+ if (thd->master_access & SUPER_ACL)
+ {
+ if (!(thd->options & OPTION_UPDATE_LOG))
+ log_on&= ~(int) DELAYED_LOG_UPDATE;
+ if (!(thd->options & OPTION_BIN_LOG))
+ log_on&= ~(int) DELAYED_LOG_BIN;
+ }
+
/*
in safe mode or with skip-new change delayed insert to be regular
if we are told to replace duplicates, the insert cannot be concurrent
@@ -121,7 +139,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
*/
if ((lock_type == TL_WRITE_DELAYED &&
((specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) ||
- thd->slave_thread)) ||
+ thd->slave_thread || !max_insert_delayed_threads)) ||
(lock_type == TL_WRITE_CONCURRENT_INSERT && duplic == DUP_REPLACE))
lock_type=TL_WRITE;
@@ -148,14 +166,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
DBUG_RETURN(-1);
thd->proc_info="init";
thd->used_tables=0;
- save_time_stamp=table->time_stamp;
values= its++;
if (check_insert_fields(thd,table,fields,*values,1) ||
- setup_tables(table_list) || setup_fields(thd,table_list,*values,0,0))
- {
- table->time_stamp=save_time_stamp;
+ setup_tables(table_list) || setup_fields(thd,table_list,*values,0,0,0))
goto abort;
- }
value_count= values->elements;
while ((values = its++))
{
@@ -165,18 +179,14 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW,
ER(ER_WRONG_VALUE_COUNT_ON_ROW),
MYF(0),counter);
- table->time_stamp=save_time_stamp;
goto abort;
}
- if (setup_fields(thd,table_list,*values,0,0))
- {
- table->time_stamp=save_time_stamp;
+ if (setup_fields(thd,table_list,*values,0,0,0))
goto abort;
- }
}
its.rewind ();
/*
- ** Fill in the given fields and dump it to the table file
+ Fill in the given fields and dump it to the table file
*/
info.records=info.deleted=info.copied=0;
@@ -192,12 +202,24 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
thd->proc_info="update";
if (duplic == DUP_IGNORE || duplic == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
- while ((values = its++))
+ if ((lock_type != TL_WRITE_DELAYED && !(specialflag & SPECIAL_SAFE_MODE)) &&
+ values_list.elements >= MIN_ROWS_TO_USE_BULK_INSERT)
+ {
+ table->file->extra_opt(HA_EXTRA_WRITE_CACHE,
+ min(thd->variables.read_buff_size,
+ table->avg_row_length*values_list.elements));
+ table->file->deactivate_non_unique_index(values_list.elements);
+ bulk_insert=1;
+ }
+ else
+ bulk_insert=0;
+
+ while ((values= its++))
{
if (fields.elements || !value_count)
{
restore_record(table,2); // Get empty record
- if (fill_record(fields,*values) || check_null_fields(thd,table))
+ if (fill_record(fields, *values, 0) || check_null_fields(thd,table))
{
if (values_list.elements != 1)
{
@@ -214,7 +236,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
restore_record(table,2); // Get empty record
else
table->record[0][0]=table->record[2][0]; // Fix delete marker
- if (fill_record(table->field,*values))
+ if (fill_record(table->field, *values, 0))
{
if (values_list.elements != 1)
{
@@ -253,28 +275,62 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
info.copied=values_list.elements;
end_delayed_insert(thd);
}
+ query_cache_invalidate3(thd, table_list, 1);
}
else
{
+ if (bulk_insert)
+ {
+ if (table->file->extra(HA_EXTRA_NO_CACHE))
+ {
+ if (!error)
+ {
+ table->file->print_error(my_errno,MYF(0));
+ error=1;
+ }
+ }
+ if (table->file->activate_all_index(thd))
+ {
+ if (!error)
+ {
+ table->file->print_error(my_errno,MYF(0));
+ error=1;
+ }
+ }
+ }
if (id && values_list.elements != 1)
thd->insert_id(id); // For update log
else if (table->next_number_field)
id=table->next_number_field->val_int(); // Return auto_increment value
- using_transactions=table->file->has_transactions();
- if ((info.copied || info.deleted) && (error <= 0 || !using_transactions))
+
+ transactional_table= table->file->has_transactions();
+ log_delayed= (transactional_table || table->tmp_table);
+ if ((info.copied || info.deleted) && (error <= 0 || !transactional_table))
{
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, using_transactions);
- if (mysql_bin_log.write(&qinfo) && using_transactions)
+ if (error <= 0)
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ log_delayed);
+ if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1;
}
- if (!using_transactions)
+ if (!log_delayed)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (using_transactions)
+ if (transactional_table)
error=ha_autocommit_or_rollback(thd,error);
+
+ /*
+ Store table for future invalidation or invalidate it in
+ the query cache if something changed
+ */
+ if (info.copied || info.deleted)
+ {
+ query_cache_invalidate3(thd, table_list, 1);
+ }
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
@@ -282,13 +338,11 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
}
}
thd->proc_info="end";
- table->time_stamp=save_time_stamp; // Restore auto timestamp ptr
table->next_number_field=0;
thd->count_cuted_fields=0;
thd->next_insert_id=0; // Reset this if wrongly used
if (duplic == DUP_IGNORE || duplic == DUP_REPLACE)
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
-
if (error)
goto abort;
@@ -329,7 +383,7 @@ static int last_uniq_key(TABLE *table,uint keynr)
/*
-** Write a record to table with optional deleting of conflicting records
+ Write a record to table with optional deleting of conflicting records
*/
@@ -337,18 +391,18 @@ int write_record(TABLE *table,COPY_INFO *info)
{
int error;
char *key=0;
-
+
info->records++;
if (info->handle_duplicates == DUP_REPLACE)
{
while ((error=table->file->write_row(table->record[0])))
{
- if (error != HA_WRITE_SKIPP)
+ if (error != HA_WRITE_SKIP)
goto err;
uint key_nr;
if ((int) (key_nr = table->file->get_dup_key(error)) < 0)
{
- error=HA_WRITE_SKIPP; /* Database can't find key */
+ error=HA_WRITE_SKIP; /* Database can't find key */
goto err;
}
/*
@@ -359,19 +413,19 @@ int write_record(TABLE *table,COPY_INFO *info)
if (table->next_number_field && key_nr == table->next_number_index &&
table->file->auto_increment_column_changed)
goto err;
- if (table->file->option_flag() & HA_DUPP_POS)
+ if (table->file->table_flags() & HA_DUPP_POS)
{
if (table->file->rnd_pos(table->record[1],table->file->dupp_ref))
goto err;
}
else
{
- if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not neaded with NISAM */
+ if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not needed with NISAM */
{
error=my_errno;
goto err;
}
-
+
if (!key)
{
if (!(key=(char*) my_safe_alloca(table->max_unique_length,
@@ -416,15 +470,16 @@ int write_record(TABLE *table,COPY_INFO *info)
err:
if (key)
my_afree(key);
+ info->last_errno= error;
table->file->print_error(error,MYF(0));
return 1;
}
/******************************************************************************
- Check that all fields with arn't null_fields are used
- if DONT_USE_DEFAULT_FIELDS isn't defined use default value for not
- set fields.
+ Check that all fields with arn't null_fields are used
+ If DONT_USE_DEFAULT_FIELDS isn't defined use default value for not set
+ fields.
******************************************************************************/
static int check_null_fields(THD *thd __attribute__((unused)),
@@ -447,10 +502,8 @@ static int check_null_fields(THD *thd __attribute__((unused)),
}
/*****************************************************************************
-** Handling of delayed inserts
-**
-** A thread is created for each table that one uses with the DELAYED
-** attribute.
+ Handling of delayed inserts
+ A thread is created for each table that one uses with the DELAYED attribute.
*****************************************************************************/
class delayed_row :public ilink {
@@ -458,12 +511,13 @@ public:
char *record,*query;
enum_duplicates dup;
time_t start_time;
- bool query_start_used,last_insert_id_used,insert_id_used,log_query;
+ bool query_start_used,last_insert_id_used,insert_id_used;
+ int log_query;
ulonglong last_insert_id;
ulong time_stamp;
uint query_length;
- delayed_row(enum_duplicates dup_arg, bool log_query_arg)
+ delayed_row(enum_duplicates dup_arg, int log_query_arg)
:record(0),query(0),dup(dup_arg),log_query(log_query_arg) {}
~delayed_row()
{
@@ -498,7 +552,8 @@ public:
thd.command=COM_DELAYED_INSERT;
bzero((char*) &thd.net,sizeof(thd.net)); // Safety
- thd.system_thread=1;
+ thd.system_thread= SYSTEM_THREAD_DELAYED_INSERT;
+ thd.host_or_ip= "";
bzero((char*) &info,sizeof(info));
pthread_mutex_init(&mutex,MY_MUTEX_INIT_FAST);
pthread_cond_init(&cond,NULL);
@@ -509,7 +564,7 @@ public:
}
~delayed_insert()
{
- /* The following is not really neaded, but just for safety */
+ /* The following is not really needed, but just for safety */
delayed_row *row;
while ((row=rows.get()))
delete row;
@@ -524,8 +579,8 @@ public:
thd.user=thd.host=0;
thread_count--;
delayed_insert_threads--;
- VOID(pthread_cond_broadcast(&COND_thread_count)); /* Tell main we are ready */
VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ VOID(pthread_cond_broadcast(&COND_thread_count)); /* Tell main we are ready */
}
/* The following is for checking when we can delete ourselves */
@@ -590,6 +645,9 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
/* no match; create a new thread to handle the table */
if (!(tmp=find_handler(thd,table_list)))
{
+ /* Don't create more than max_insert_delayed_threads */
+ if (delayed_insert_threads >= max_insert_delayed_threads)
+ DBUG_RETURN(0);
thd->proc_info="Creating delayed handler";
pthread_mutex_lock(&LOCK_delayed_create);
if (!(tmp=find_handler(thd,table_list))) // Was just created
@@ -615,7 +673,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
}
tmp->table_list= *table_list; // Needed to open table
tmp->table_list.db= tmp->thd.db;
- tmp->table_list.alias= tmp->table_list.real_name= tmp->thd.query;
+ tmp->table_list.alias= tmp->table_list.real_name=tmp->thd.query;
tmp->lock();
pthread_mutex_lock(&tmp->mutex);
if ((error=pthread_create(&tmp->thd.real_id,&connection_attrib,
@@ -648,7 +706,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
/* Copy error message and abort */
thd->fatal_error=1;
strmov(thd->net.last_error,tmp->thd.net.last_error);
- thd->net.last_errno=thd->net.last_errno;
+ thd->net.last_errno=tmp->thd.net.last_errno;
}
tmp->unlock();
pthread_mutex_unlock(&LOCK_delayed_create);
@@ -712,9 +770,9 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
}
client_thd->proc_info="allocating local table";
- copy= (TABLE*) sql_alloc(sizeof(*copy)+
- (table->fields+1)*sizeof(Field**)+
- table->reclength);
+ copy= (TABLE*) client_thd->alloc(sizeof(*copy)+
+ (table->fields+1)*sizeof(Field**)+
+ table->reclength);
if (!copy)
goto error;
*copy= *table;
@@ -732,7 +790,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
found_next_number_field=table->found_next_number_field;
for (org_field=table->field ; *org_field ; org_field++,field++)
{
- if (!(*field= (*org_field)->new_field(copy)))
+ if (!(*field= (*org_field)->new_field(&client_thd->mem_root,copy)))
return 0;
(*field)->move_field(adjust_ptrs); // Point at copy->record[0]
if (*org_field == found_next_number_field)
@@ -765,7 +823,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
/* Put a question in queue */
static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic,
- char *query, uint query_length, bool log_on)
+ char *query, uint query_length, int log_on)
{
delayed_row *row=0;
delayed_insert *di=thd->di;
@@ -873,7 +931,7 @@ void kill_delayed_threads(void)
* Create a new delayed insert thread
*/
-static pthread_handler_decl(handle_delayed_insert,arg)
+extern "C" pthread_handler_decl(handle_delayed_insert,arg)
{
delayed_insert *di=(delayed_insert*) arg;
THD *thd= &di->thd;
@@ -897,17 +955,13 @@ static pthread_handler_decl(handle_delayed_insert,arg)
#endif
DBUG_ENTER("handle_delayed_insert");
- if (init_thr_lock() ||
- my_pthread_setspecific_ptr(THR_THD, thd) ||
- my_pthread_setspecific_ptr(THR_NET, &thd->net))
+ if (init_thr_lock() || thd->store_globals())
{
thd->fatal_error=1;
strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
goto end;
}
- thd->mysys_var=my_thread_var;
- thd->dbug_thread_id=my_thread_id();
-#if !defined(__WIN__) && !defined(OS2)
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
sigset_t set;
VOID(sigemptyset(&set)); // Get mask in use
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
@@ -961,34 +1015,23 @@ static pthread_handler_decl(handle_delayed_insert,arg)
if (!di->status && !di->stacked_inserts)
{
struct timespec abstime;
-#if defined(HAVE_TIMESPEC_TS_SEC)
- abstime.ts_sec=time((time_t*) 0)+(time_t) delayed_insert_timeout;
- abstime.ts_nsec=0;
-#elif defined(__WIN__)
- abstime.tv_sec=time((time_t*) 0)+(time_t) delayed_insert_timeout;
- abstime.tv_nsec=0;
-#else
- struct timeval tv;
- gettimeofday(&tv,0);
- abstime.tv_sec=tv.tv_sec+(time_t) delayed_insert_timeout;
- abstime.tv_nsec=tv.tv_usec*1000;
-#endif
+ set_timespec(abstime, delayed_insert_timeout);
/* Information for pthread_kill */
di->thd.mysys_var->current_mutex= &di->mutex;
di->thd.mysys_var->current_cond= &di->cond;
- di->thd.proc_info=0;
+ di->thd.proc_info="Waiting for INSERT";
DBUG_PRINT("info",("Waiting for someone to insert rows"));
while (!thd->killed)
{
int error;
-#if (defined(HAVE_BROKEN_COND_TIMEDWAIT) || defined(HAVE_LINUXTHREADS))
+#if defined(HAVE_BROKEN_COND_TIMEDWAIT)
error=pthread_cond_wait(&di->cond,&di->mutex);
#else
error=pthread_cond_timedwait(&di->cond,&di->mutex,&abstime);
#ifdef EXTRA_DEBUG
- if (error && error != EINTR)
+ if (error && error != EINTR && error != ETIMEDOUT)
{
fprintf(stderr, "Got error %d from pthread_cond_timedwait\n",error);
DBUG_PRINT("error",("Got error %d from pthread_cond_timedwait",
@@ -1012,6 +1055,7 @@ static pthread_handler_decl(handle_delayed_insert,arg)
pthread_mutex_unlock(&di->thd.mysys_var->mutex);
pthread_mutex_lock(&di->mutex);
}
+ di->thd.proc_info=0;
if (di->tables_in_use && ! thd->lock)
{
@@ -1154,10 +1198,10 @@ bool delayed_insert::handle_inserts(void)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
using_ignore=1;
}
- thd.net.last_errno = 0; // reset error for binlog
+ thd.clear_error(); // reset error for binlog
if (write_record(table,&info))
{
- info.error++; // Ignore errors
+ info.error_count++; // Ignore errors
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
row->log_query = 0;
}
@@ -1166,14 +1210,14 @@ bool delayed_insert::handle_inserts(void)
using_ignore=0;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
}
- if (row->query && row->log_query)
+ if (row->query)
{
- mysql_update_log.write(&thd,row->query, row->query_length);
- if (using_bin_log)
+ if (row->log_query & DELAYED_LOG_UPDATE)
+ mysql_update_log.write(&thd,row->query, row->query_length);
+ if (row->log_query & DELAYED_LOG_BIN && using_bin_log)
{
- thd.query_length = row->query_length;
- Query_log_event qinfo(&thd, row->query);
- mysql_bin_log.write(&qinfo);
+ Query_log_event qinfo(&thd, row->query, row->query_length,0);
+ mysql_bin_log.write(&qinfo);
}
}
if (table->blob_fields)
@@ -1200,6 +1244,7 @@ bool delayed_insert::handle_inserts(void)
sql_print_error("%s",thd.net.last_error);
goto err;
}
+ query_cache_invalidate3(&thd, table, 1);
if (thr_reschedule_write_lock(*thd.lock->locks))
{
/* This should never happen */
@@ -1224,6 +1269,7 @@ bool delayed_insert::handle_inserts(void)
sql_print_error("%s",thd.net.last_error);
goto err;
}
+ query_cache_invalidate3(&thd, table, 1);
pthread_mutex_lock(&mutex);
DBUG_RETURN(0);
@@ -1243,7 +1289,7 @@ bool delayed_insert::handle_inserts(void)
/***************************************************************************
-** store records in INSERT ... SELECT *
+ Store records in INSERT ... SELECT *
***************************************************************************/
int
@@ -1251,13 +1297,12 @@ select_insert::prepare(List<Item> &values)
{
DBUG_ENTER("select_insert::prepare");
- save_time_stamp=table->time_stamp;
if (check_insert_fields(thd,table,*fields,values,1))
DBUG_RETURN(1);
restore_record(table,2); // Get empty record
table->next_number_field=table->found_next_number_field;
- thd->count_cuted_fields=1; /* calc cuted fields */
+ thd->count_cuted_fields=1; // calc cuted fields
thd->cuted_fields=0;
if (info.handle_duplicates != DUP_REPLACE)
table->file->extra(HA_EXTRA_WRITE_CACHE);
@@ -1272,8 +1317,6 @@ select_insert::~select_insert()
{
if (table)
{
- if (save_time_stamp)
- table->time_stamp=save_time_stamp;
table->next_number_field=0;
table->file->extra(HA_EXTRA_RESET);
}
@@ -1289,9 +1332,9 @@ bool select_insert::send_data(List<Item> &values)
return 0;
}
if (fields->elements)
- fill_record(*fields,values);
+ fill_record(*fields, values, 1);
else
- fill_record(table->field,values);
+ fill_record(table->field, values, 1);
if (write_record(table,&info))
return 1;
if (table->next_number_field) // Clear for next record
@@ -1309,7 +1352,31 @@ void select_insert::send_error(uint errcode,const char *err)
::send_error(&thd->net,errcode,err);
table->file->extra(HA_EXTRA_NO_CACHE);
table->file->activate_all_index(thd);
- ha_rollback(thd);
+ /*
+ If at least one row has been inserted/modified and will stay in the table
+ (the table doesn't have transactions) (example: we got a duplicate key
+ error while inserting into a MyISAM table) we must write to the binlog (and
+ the error code will make the slave stop).
+ */
+ if ((info.copied || info.deleted) && !table->file->has_transactions())
+ {
+ if (last_insert_id)
+ thd->insert_id(last_insert_id); // For binary log
+ mysql_update_log.write(thd,thd->query,thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ table->file->has_transactions());
+ mysql_bin_log.write(&qinfo);
+ }
+ if (!table->tmp_table)
+ thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+ }
+ ha_rollback_stmt(thd);
+ if (info.copied || info.deleted)
+ {
+ query_cache_invalidate3(thd, table, 1);
+ }
}
@@ -1319,41 +1386,47 @@ bool select_insert::send_eof()
if (!(error=table->file->extra(HA_EXTRA_NO_CACHE)))
error=table->file->activate_all_index(thd);
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
+
+ if (last_insert_id)
+ thd->insert_id(last_insert_id); // For binary log
+ /* Write to binlog before commiting transaction */
+ mysql_update_log.write(thd,thd->query,thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ if (!error)
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ table->file->has_transactions());
+ mysql_bin_log.write(&qinfo);
+ }
if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)
error=error2;
-
+ if (info.copied || info.deleted)
+ {
+ query_cache_invalidate3(thd, table, 1);
+ if (!(table->file->has_transactions() || table->tmp_table))
+ thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+ }
if (error)
{
table->file->print_error(error,MYF(0));
::send_error(&thd->net);
return 1;
}
+ char buff[160];
+ if (info.handle_duplicates == DUP_IGNORE)
+ sprintf(buff,ER(ER_INSERT_INFO),info.records,info.records-info.copied,
+ thd->cuted_fields);
else
- {
- char buff[160];
- if (info.handle_duplicates == DUP_IGNORE)
- sprintf(buff,ER(ER_INSERT_INFO),info.records,info.records-info.copied,
- thd->cuted_fields);
- else
- sprintf(buff,ER(ER_INSERT_INFO),info.records,info.deleted,
- thd->cuted_fields);
- if (last_insert_id)
- thd->insert_id(last_insert_id); // For update log
- ::send_ok(&thd->net,info.copied,last_insert_id,buff);
- mysql_update_log.write(thd,thd->query,thd->query_length);
- if (mysql_bin_log.is_open())
- {
- Query_log_event qinfo(thd, thd->query,
- table->file->has_transactions());
- mysql_bin_log.write(&qinfo);
- }
- return 0;
- }
+ sprintf(buff,ER(ER_INSERT_INFO),info.records,info.deleted,
+ thd->cuted_fields);
+ ::send_ok(&thd->net,info.copied+info.deleted,last_insert_id,buff);
+ return 0;
}
/***************************************************************************
-** CREATE TABLE (SELECT) ...
+ CREATE TABLE (SELECT) ...
***************************************************************************/
int
@@ -1361,15 +1434,22 @@ select_create::prepare(List<Item> &values)
{
DBUG_ENTER("select_create::prepare");
- table=create_table_from_items(thd, create_info, db, name,
- extra_fields, keys, &values, &lock);
+ table= create_table_from_items(thd, create_info, db, name,
+ extra_fields, keys, &values, &lock);
if (!table)
DBUG_RETURN(-1); // abort() deletes table
+ if (table->fields < values.elements)
+ {
+ my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW,
+ ER(ER_WRONG_VALUE_COUNT_ON_ROW),
+ MYF(0),1);
+ DBUG_RETURN(-1);
+ }
+
/* First field to copy */
field=table->field+table->fields - values.elements;
- save_time_stamp=table->time_stamp;
if (table->timestamp_field) // Don't set timestamp if used
{
table->timestamp_field->set_time();
@@ -1395,7 +1475,7 @@ bool select_create::send_data(List<Item> &values)
thd->offset_limit--;
return 0;
}
- fill_record(field,values);
+ fill_record(field, values, 1);
if (write_record(table,&info))
return 1;
if (table->next_number_field) // Clear for next record
@@ -1409,6 +1489,7 @@ bool select_create::send_data(List<Item> &values)
extern HASH open_cache;
+
bool select_create::send_eof()
{
bool tmp=select_insert::send_eof();
@@ -1426,7 +1507,8 @@ bool select_create::send_eof()
*/
if (!table->tmp_table)
hash_delete(&open_cache,(byte*) table);
- lock=0; table=0;
+ lock=0;
+ table=0;
VOID(pthread_mutex_unlock(&LOCK_open));
}
return tmp;
@@ -1446,7 +1528,8 @@ void select_create::abort()
enum db_type table_type=table->db_type;
if (!table->tmp_table)
hash_delete(&open_cache,(byte*) table);
- quick_rm_table(table_type,db,name);
+ if (!create_info->table_existed)
+ quick_rm_table(table_type,db,name);
table=0;
}
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -1454,11 +1537,11 @@ void select_create::abort()
/*****************************************************************************
-** Instansiate templates
+ Instansiate templates
*****************************************************************************/
#ifdef __GNUC__
-template class List_iterator<List_item>;
+template class List_iterator_fast<List_item>;
template class I_List<delayed_insert>;
template class I_List_iterator<delayed_insert>;
template class I_List<delayed_row>;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index a3c3db8947e..d62edf83c11 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -142,20 +142,23 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->next_state=STATE_START;
lex->end_of_query=(lex->ptr=buf)+length;
lex->yylineno = 1;
- lex->create_refs=lex->in_comment=0;
+ lex->select->create_refs=lex->in_comment=0;
lex->length=0;
- lex->in_sum_expr=0;
- lex->expr_list.empty();
- lex->ftfunc_list.empty();
- lex->convert_set=thd->convert_set;
+ lex->select->in_sum_expr=0;
+ lex->select->expr_list.empty();
+ lex->select->ftfunc_list.empty();
+ lex->convert_set=(lex->thd=thd)->variables.convert_set;
lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE);
+ lex->slave_thd_opt=0;
+ lex->sql_command=SQLCOM_END;
+ bzero((char *)&lex->mi,sizeof(lex->mi));
return lex;
}
void lex_end(LEX *lex)
{
- lex->expr_list.delete_elements(); // If error when parsing sql-varargs
+ lex->select->expr_list.delete_elements(); // If error when parsing sql-varargs
x_free(lex->yacc_yyss);
x_free(lex->yacc_yyvs);
}
@@ -177,15 +180,14 @@ static int find_keyword(LEX *lex, uint len, bool function)
udf_func *udf;
if (function && using_udf_functions && (udf=find_udf((char*) tok, len)))
{
+ lex->thd->safe_to_cache_query=0;
+ lex->yylval->udf=udf;
switch (udf->returns) {
case STRING_RESULT:
- lex->yylval->udf=udf;
return (udf->type == UDFTYPE_FUNCTION) ? UDF_CHAR_FUNC : UDA_CHAR_SUM;
case REAL_RESULT:
- lex->yylval->udf=udf;
return (udf->type == UDFTYPE_FUNCTION) ? UDF_FLOAT_FUNC : UDA_FLOAT_SUM;
case INT_RESULT:
- lex->yylval->udf=udf;
return (udf->type == UDFTYPE_FUNCTION) ? UDF_INT_FUNC : UDA_INT_SUM;
}
}
@@ -196,12 +198,12 @@ static int find_keyword(LEX *lex, uint len, bool function)
/* make a copy of token before ptr and set yytoklen */
-static inline LEX_STRING get_token(LEX *lex,uint length)
+LEX_STRING get_token(LEX *lex,uint length)
{
LEX_STRING tmp;
yyUnget(); // ptr points now after last token char
tmp.length=lex->yytoklen=length;
- tmp.str=(char*) sql_strmake((char*) lex->tok_start,tmp.length);
+ tmp.str=(char*) lex->thd->strmake((char*) lex->tok_start,tmp.length);
return tmp;
}
@@ -250,7 +252,7 @@ static char *get_text(LEX *lex)
str=lex->tok_start+1;
end=lex->ptr-1;
- if (!(start=(uchar*) sql_alloc((uint) (end-str)+1)))
+ if (!(start=(uchar*) lex->thd->alloc((uint) (end-str)+1)))
return (char*) ""; // Sql_alloc has set error flag
if (!found_escape)
{
@@ -337,7 +339,8 @@ static const char *longlong_str="9223372036854775807";
static const uint longlong_len=19;
static const char *signed_longlong_str="-9223372036854775808";
static const uint signed_longlong_len=19;
-
+static const char *unsigned_longlong_str="18446744073709551615";
+static const uint unsigned_longlong_len=20;
inline static uint int_token(const char *str,uint length)
{
@@ -393,12 +396,18 @@ inline static uint int_token(const char *str,uint length)
else if (length < longlong_len)
return LONG_NUM;
else if (length > longlong_len)
- return REAL_NUM;
+ {
+ if (length > unsigned_longlong_len)
+ return REAL_NUM;
+ cmp=unsigned_longlong_str;
+ smaller=ULONGLONG_NUM;
+ bigger=REAL_NUM;
+ }
else
{
cmp=longlong_str;
smaller=LONG_NUM;
- bigger=REAL_NUM;
+ bigger= ULONGLONG_NUM;
}
}
while (*cmp && *cmp++ == *str++) ;
@@ -430,7 +439,7 @@ int yylex(void *arg)
switch(state) {
case STATE_OPERATOR_OR_IDENT: // Next is operator or keyword
case STATE_START: // Start of token
- // Skipp startspace
+ // Skip startspace
for (c=yyGet() ; (state_map[c] == STATE_SKIP) ; c= yyGet())
{
if (c == '\n')
@@ -458,6 +467,11 @@ int yylex(void *arg)
return((int) c);
case STATE_IDENT: // Incomplete keyword or ident
+ if ((c == 'x' || c == 'X') && yyPeek() == '\'')
+ { // Found x'hex-number'
+ state=STATE_HEX_NUMBER;
+ break;
+ }
#if defined(USE_MB) && defined(USE_MB_IDENT)
if (use_mb(default_charset_info))
{
@@ -493,7 +507,7 @@ int yylex(void *arg)
length= (uint) (lex->ptr - lex->tok_start)-1;
if (lex->ignore_space)
{
- for ( ; state_map[c] == STATE_SKIP ; c= yyGet());
+ for (; state_map[c] == STATE_SKIP ; c= yyGet());
}
if (c == '.' && (state_map[yyPeek()] == STATE_IDENT ||
state_map[yyPeek()] == STATE_NUMBER_IDENT))
@@ -509,6 +523,8 @@ int yylex(void *arg)
yySkip(); // next state does a unget
}
yylval->lex_str=get_token(lex,length);
+ if (lex->convert_set)
+ lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
return(IDENT);
case STATE_IDENT_SEP: // Found ident and now '.'
@@ -518,7 +534,7 @@ int yylex(void *arg)
c=yyGet(); // should be '.'
return((int) c);
- case STATE_NUMBER_IDENT: // number or ident which starts with num
+ case STATE_NUMBER_IDENT: // number or ident which num-start
while (isdigit((c = yyGet()))) ;
if (state_map[c] != STATE_IDENT)
{ // Can't be identifier
@@ -544,10 +560,10 @@ int yylex(void *arg)
lex->tok_start[0] == '0' )
{ // Varbinary
while (isxdigit((c = yyGet()))) ;
- if ((lex->ptr - lex->tok_start) >= 4)
+ if ((lex->ptr - lex->tok_start) >= 4 && state_map[c] != STATE_IDENT)
{
yylval->lex_str=get_token(lex,yyLength());
- yylval->lex_str.str+=2; // Skipp 0x
+ yylval->lex_str.str+=2; // Skip 0x
yylval->lex_str.length-=2;
lex->yytoklen-=2;
return (HEX_NUM);
@@ -597,10 +613,12 @@ int yylex(void *arg)
case STATE_FOUND_IDENT: // Complete ident
yylval->lex_str=get_token(lex,yyLength());
+ if (lex->convert_set)
+ lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
return(IDENT);
case STATE_USER_VARIABLE_DELIMITER:
- lex->tok_start=lex->ptr; // Skipp first `
+ lex->tok_start=lex->ptr; // Skip first `
#ifdef USE_MB
if (use_mb(default_charset_info))
{
@@ -625,14 +643,17 @@ int yylex(void *arg)
c != (uchar) NAMES_SEP_CHAR) ;
}
yylval->lex_str=get_token(lex,yyLength());
+ if (lex->convert_set)
+ lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
if (state_map[c] == STATE_USER_VARIABLE_DELIMITER)
- yySkip(); // Skipp end `
+ yySkip(); // Skip end `
return(IDENT);
case STATE_SIGNED_NUMBER: // Incomplete signed number
if (prev_state == STATE_OPERATOR_OR_IDENT)
{
- if (c == '-' && yyPeek() == '-' && isspace(yyPeek2()))
+ if (c == '-' && yyPeek() == '-' &&
+ (isspace(yyPeek2()) || iscntrl(yyPeek2())))
state=STATE_COMMENT;
else
state= STATE_CHAR; // Must be operator
@@ -672,7 +693,7 @@ int yylex(void *arg)
{
c = yyGet();
if (c == '-' || c == '+')
- c = yyGet(); // Skipp sign
+ c = yyGet(); // Skip sign
if (!isdigit(c))
{ // No digit after sign
state= STATE_CHAR;
@@ -685,6 +706,21 @@ int yylex(void *arg)
yylval->lex_str=get_token(lex,yyLength());
return(REAL_NUM);
+ case STATE_HEX_NUMBER: // Found x'hexstring'
+ yyGet(); // Skip '
+ while (isxdigit((c = yyGet()))) ;
+ length=(lex->ptr - lex->tok_start); // Length of hexnum+3
+ if (!(length & 1) || c != '\'')
+ {
+ return(ABORT_SYM); // Illegal hex constant
+ }
+ yyGet(); // get_token makes an unget
+ yylval->lex_str=get_token(lex,length);
+ yylval->lex_str.str+=2; // Skip x'
+ yylval->lex_str.length-=3; // Don't count x' and last '
+ lex->yytoklen-=3;
+ return (HEX_NUM);
+
case STATE_CMP_OP: // Incomplete comparison operator
if (state_map[yyPeek()] == STATE_CMP_OP ||
state_map[yyPeek()] == STATE_LONG_CMP_OP)
@@ -734,7 +770,7 @@ int yylex(void *arg)
return(TEXT_STRING);
case STATE_COMMENT: // Comment
- lex->options|= OPTION_FOUND_COMMENT;
+ lex->select_lex.options|= OPTION_FOUND_COMMENT;
while ((c = yyGet()) != '\n' && c) ;
yyUnget(); // Safety against eof
state = STATE_START; // Try again
@@ -746,7 +782,7 @@ int yylex(void *arg)
break;
}
yySkip(); // Skip '*'
- lex->options|= OPTION_FOUND_COMMENT;
+ lex->select_lex.options|= OPTION_FOUND_COMMENT;
if (yyPeek() == '!') // MySQL command in comment
{
ulong version=MYSQL_VERSION_ID;
@@ -816,14 +852,12 @@ int yylex(void *arg)
}
break;
case STATE_USER_END: // end '@' of user@hostname
- switch (state_map[yyPeek()])
- {
+ switch (state_map[yyPeek()]) {
case STATE_STRING:
case STATE_USER_VARIABLE_DELIMITER:
break;
case STATE_USER_END:
- lex->next_state=STATE_USER_END;
- yySkip();
+ lex->next_state=STATE_SYSTEM_VAR;
break;
default:
lex->next_state=STATE_HOSTNAME;
@@ -838,6 +872,33 @@ int yylex(void *arg)
c= yyGet()) ;
yylval->lex_str=get_token(lex,yyLength());
return(LEX_HOSTNAME);
+ case STATE_SYSTEM_VAR:
+ yylval->lex_str.str=(char*) lex->ptr;
+ yylval->lex_str.length=1;
+ lex->next_state=STATE_IDENT_OR_KEYWORD;
+ yySkip(); // Skip '@'
+ return((int) '@');
+ case STATE_IDENT_OR_KEYWORD:
+ /*
+ We come here when we have found two '@' in a row.
+ We should now be able to handle:
+ [(global | local | session) .]variable_name
+ */
+
+ while (state_map[c=yyGet()] == STATE_IDENT ||
+ state_map[c] == STATE_NUMBER_IDENT) ;
+ if (c == '.')
+ lex->next_state=STATE_IDENT_SEP;
+ length= (uint) (lex->ptr - lex->tok_start)-1;
+ if ((tokval= find_keyword(lex,length,0)))
+ {
+ yyUnget(); // Put back 'c'
+ return(tokval); // Was keyword
+ }
+ yylval->lex_str=get_token(lex,length);
+ if (lex->convert_set)
+ lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
+ return(IDENT);
}
}
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 7d1df04b852..ab78555262f 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -22,8 +22,12 @@ class Table_ident;
class sql_exchange;
class LEX_COLUMN;
-// The following hack is neaded because mysql_yacc.cc does not define
-// YYSTYPE before including this file
+/*
+ The following hack is needed because mysql_yacc.cc does not define
+ YYSTYPE before including this file
+*/
+
+#include "set_var.h"
#ifdef MYSQL_YACC
#define LEX_YYSTYPE void *
@@ -49,104 +53,135 @@ enum enum_sql_command {
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
- SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
- SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
+ SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
+ SQLCOM_ROLLBACK, SQLCOM_ROLLBACK_TO_SAVEPOINT,
+ SQLCOM_COMMIT, SQLCOM_SAVEPOINT,
+ SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE,
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS,
- SQLCOM_SHOW_OPEN_TABLES, SQLCOM_DO, SQLCOM_EMPTY_QUERY,
+ SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA,
+ SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
+ SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_DELETE_MULTI, SQLCOM_MULTI_UPDATE,
+ SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, SQLCOM_DO,
+ SQLCOM_EMPTY_QUERY,
SQLCOM_END
};
-enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
- STATE_IDENT_SEP,
- STATE_IDENT_START,
- STATE_FOUND_IDENT,
- STATE_SIGNED_NUMBER,
- STATE_REAL,
- STATE_CMP_OP,
- STATE_LONG_CMP_OP,
- STATE_STRING,
- STATE_COMMENT,
- STATE_END,
- STATE_OPERATOR_OR_IDENT,
- STATE_NUMBER_IDENT,
- STATE_INT_OR_REAL,
- STATE_REAL_OR_POINT,
- STATE_BOOL,
- STATE_EOL,
- STATE_ESCAPE,
- STATE_LONG_COMMENT,
- STATE_END_LONG_COMMENT,
- STATE_COLON,
- STATE_SET_VAR,
- STATE_USER_END,
- STATE_HOSTNAME,
- STATE_SKIP,
- STATE_USER_VARIABLE_DELIMITER
+enum lex_states
+{
+ STATE_START, STATE_CHAR, STATE_IDENT, STATE_IDENT_SEP, STATE_IDENT_START,
+ STATE_FOUND_IDENT, STATE_SIGNED_NUMBER, STATE_REAL, STATE_HEX_NUMBER,
+ STATE_CMP_OP, STATE_LONG_CMP_OP, STATE_STRING, STATE_COMMENT, STATE_END,
+ STATE_OPERATOR_OR_IDENT, STATE_NUMBER_IDENT, STATE_INT_OR_REAL,
+ STATE_REAL_OR_POINT, STATE_BOOL, STATE_EOL, STATE_ESCAPE, STATE_LONG_COMMENT,
+ STATE_END_LONG_COMMENT, STATE_COLON, STATE_SET_VAR, STATE_USER_END,
+ STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER, STATE_SYSTEM_VAR,
+ STATE_IDENT_OR_KEYWORD
};
typedef List<Item> List_item;
typedef struct st_lex_master_info
{
- char* host, *user, *password,*log_file_name;
+ char *host, *user, *password, *log_file_name;
uint port, connect_retry;
ulonglong pos;
+ ulong server_id;
+ char *relay_log_name;
+ ulong relay_log_pos;
} LEX_MASTER_INFO;
+
+enum sub_select_type
+{
+ UNSPECIFIED_TYPE, UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, OLAP_TYPE, NOT_A_SELECT
+};
+
+enum olap_type
+{
+ UNSPECIFIED_OLAP_TYPE, CUBE_TYPE, ROLLUP_TYPE
+};
+
+/* The state of the lex parsing for selects */
+
+typedef struct st_select_lex
+{
+ enum sub_select_type linkage;
+ enum olap_type olap;
+ char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
+ Item *where,*having;
+ ha_rows select_limit,offset_limit;
+ ulong options, table_join_options;
+ List<List_item> expr_list;
+ List<List_item> when_list;
+ SQL_LIST order_list,table_list,group_list;
+ List<Item> item_list;
+ List<String> interval_list,use_index, *use_index_ptr,
+ ignore_index, *ignore_index_ptr;
+ List<Item_func_match> ftfunc_list;
+ uint in_sum_expr, sort_default;
+ bool create_refs, braces;
+ st_select_lex *next;
+} SELECT_LEX;
+
+
/* The state of the lex parsing. This is saved in the THD struct */
-typedef struct st_lex {
+typedef struct st_lex
+{
uint yylineno,yytoklen; /* Simulate lex */
LEX_YYSTYPE yylval;
+ SELECT_LEX select_lex, *select, *last_selects;
uchar *ptr,*tok_start,*tok_end,*end_of_query;
char *length,*dec,*change,*name;
- char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
char *backup_dir; /* For RESTORE/BACKUP */
char* to_log; /* For PURGE MASTER LOGS TO */
+ char* x509_subject,*x509_issuer,*ssl_cipher;
+ enum SSL_type ssl_type; /* defined in violite.h */
String *wild;
sql_exchange *exchange;
- ha_rows select_limit,offset_limit;
- List<List_item> expr_list;
- List<List_item> when_list;
- List<List_item> many_values;
List<key_part_spec> col_list;
List<Alter_drop> drop_list;
List<Alter_column> alter_list;
- List<String> interval_list,use_index,*use_index_ptr,
- ignore_index, *ignore_index_ptr;
- List<st_lex_user> users_list;
+ List<String> interval_list;
+ List<LEX_USER> users_list;
List<LEX_COLUMN> columns;
List<Key> key_list;
List<create_field> create_list;
- List<Item> item_list,*insert_list,field_list,value_list;
- List<Item_func_match> ftfunc_list;
- SQL_LIST order_list,table_list,group_list,proc_list;
+ List<Item> *insert_list,field_list,value_list;
+ List<List_item> many_values;
+ List<set_var_base> var_list;
+ SQL_LIST proc_list, auxilliary_table_list, save_list;
TYPELIB *interval;
create_field *last_field;
-
- Item *where,*having,*default_value;
+ char* savepoint_name; // Transaction savepoint id
+ Item *default_value;
CONVERT *convert_set;
+ CONVERT *thd_convert_set; // Set with SET CHAR SET
LEX_USER *grant_user;
gptr yacc_yyss,yacc_yyvs;
+ THD *thd;
udf_func udf;
HA_CHECK_OPT check_opt; // check/repair options
HA_CREATE_INFO create_info;
LEX_MASTER_INFO mi; // used by CHANGE MASTER
+ USER_RESOURCES mqh;
ulong thread_id,type;
- ulong options;
- ulong gemini_spin_retries;
enum_sql_command sql_command;
enum lex_states next_state;
enum enum_duplicates duplicates;
enum enum_tx_isolation tx_isolation;
- uint in_sum_expr,grant,grant_tot_col,which_columns;
+ enum enum_ha_read_modes ha_read_mode;
+ enum ha_rkey_function ha_rkey_mode;
+ enum enum_enable_or_disable alter_keys_onoff;
+ enum enum_var_type option_type;
+ uint grant,grant_tot_col,which_columns, union_option;
thr_lock_type lock_option;
- bool create_refs,drop_primary,drop_if_exists,local_file;
- bool in_comment,ignore_space,verbose;
-
+ bool drop_primary, drop_if_exists, drop_temporary, local_file, olap;
+ bool in_comment,ignore_space,verbose,simple_alter;
+ uint slave_thd_opt;
} LEX;
diff --git a/sql/sql_list.cc b/sql/sql_list.cc
index 7d5fc442121..c99cfb8c918 100644
--- a/sql/sql_list.cc
+++ b/sql/sql_list.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,3 +20,20 @@
#endif
#include "mysql_priv.h"
+
+list_node end_of_list;
+
+void free_list(I_List <i_string_pair> *list)
+{
+ i_string_pair *tmp;
+ while ((tmp= list->get()))
+ delete tmp;
+}
+
+
+void free_list(I_List <i_string> *list)
+{
+ i_string *tmp;
+ while ((tmp= list->get()))
+ delete tmp;
+}
diff --git a/sql/sql_list.h b/sql/sql_list.h
index f6851385f80..102fbe8eb93 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -1,26 +1,25 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000-2003 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* mysql standard open memoryallocator */
-
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
+/* mysql standard class memoryallocator */
class Sql_alloc
{
@@ -38,28 +37,46 @@ public:
};
+
/*
-** basic single linked list
-** Used for item and item_buffs.
+ Basic single linked list
+ Used for item and item_buffs.
+ All list ends with a pointer to the 'end_of_list' element, which
+ data pointer is a null pointer and the next pointer points to itself.
+ This makes it very fast to traverse lists as we don't have to
+ test for a specialend condition for list that can't contain a null
+ pointer.
*/
-class base_list :public Sql_alloc {
+class list_node :public Sql_alloc
+{
+public:
+ list_node *next;
+ void *info;
+ list_node(void *info_par,list_node *next_par)
+ :next(next_par),info(info_par)
+ {}
+ list_node() /* For end_of_list */
+ {
+ info=0;
+ next= this;
+ }
+ friend class base_list;
+ friend class base_list_iterator;
+};
+
+
+extern list_node end_of_list;
+
+class base_list :public Sql_alloc
+{
protected:
- class list_node :public Sql_alloc
- {
- public:
- list_node *next;
- void *info;
- list_node(void *info_par,list_node *next_par) : next(next_par),info(info_par) {}
- friend class base_list;
- friend class base_list_iterator;
- };
list_node *first,**last;
public:
uint elements;
- inline void empty() { elements=0; first=0; last=&first;}
+ inline void empty() { elements=0; first= &end_of_list; last=&first;}
inline base_list() { empty(); }
inline base_list(const base_list &tmp) :Sql_alloc()
{
@@ -69,7 +86,7 @@ public:
}
inline bool push_back(void *info)
{
- if (((*last)=new list_node(info,0)))
+ if (((*last)=new list_node(info, &end_of_list)))
{
last= &(*last)->next;
elements++;
@@ -82,7 +99,7 @@ public:
list_node *node=new list_node(info,first);
if (node)
{
- if (!first)
+ if (last == &first)
last= &node->next;
first=node;
elements++;
@@ -96,22 +113,21 @@ public:
delete *prev;
*prev=node;
if (!--elements)
- {
last= &first;
- first=0;
- }
}
inline void *pop(void)
{
- if (!first) return 0;
+ if (first == &end_of_list) return 0;
list_node *tmp=first;
first=first->next;
if (!--elements)
last= &first;
return tmp->info;
}
- inline void *head() { return first ? first->info : 0; }
- inline void **head_ref() { return first ? &first->info : 0; }
+ inline void *head() { return first->info; }
+ inline void **head_ref() { return first != &end_of_list ? &first->info : 0; }
+ inline bool is_empty() { return first == &end_of_list ; }
+ inline list_node *last_ref() { return &end_of_list; }
friend class base_list_iterator;
protected:
@@ -129,7 +145,7 @@ protected:
class base_list_iterator
{
base_list *list;
- base_list::list_node **el,**prev,*current;
+ list_node **el,**prev,*current;
public:
base_list_iterator(base_list &list_par) :list(&list_par),el(&list_par.first),
prev(0),current(0)
@@ -137,16 +153,22 @@ public:
inline void *next(void)
{
prev=el;
- if (!(current= *el))
- return 0;
+ current= *el;
el= &current->next;
return current->info;
}
+ inline void *next_fast(void)
+ {
+ list_node *tmp;
+ tmp= *el;
+ el= &tmp->next;
+ return tmp->info;
+ }
inline void rewind(void)
{
el= &list->first;
}
- void *replace(void *element)
+ inline void *replace(void *element)
{ // Return old element
void *tmp=current->info;
current->info=element;
@@ -155,12 +177,12 @@ public:
void *replace(base_list &new_list)
{
void *ret_value=current->info;
- if (new_list.first)
+ if (!new_list.is_empty())
{
*new_list.last=current->next;
current->info=new_list.first->info;
current->next=new_list.first->next;
- if (list->last == &current->next && new_list.elements > 1)
+ if ((list->last == &current->next) && (new_list.elements > 1))
list->last= new_list.last;
list->elements+=new_list.elements-1;
}
@@ -184,7 +206,7 @@ public:
}
inline bool is_last(void)
{
- return *el == 0;
+ return el == &list->last_ref()->next;
}
};
@@ -202,7 +224,7 @@ public:
void delete_elements(void)
{
list_node *element,*next;
- for (element=first; element ; element=next)
+ for (element=first; element != &end_of_list; element=next)
{
next=element->next;
delete (T*) element->info;
@@ -217,22 +239,36 @@ template <class T> class List_iterator :public base_list_iterator
public:
List_iterator(List<T> &a) : base_list_iterator(a) {}
inline T* operator++(int) { return (T*) base_list_iterator::next(); }
- inline void rewind(void) { base_list_iterator::rewind(); }
inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); }
inline T *replace(List<T> &a) { return (T*) base_list_iterator::replace(a); }
- inline void remove(void) { base_list_iterator::remove(); }
inline void after(T *a) { base_list_iterator::after(a); }
inline T** ref(void) { return (T**) base_list_iterator::ref(); }
- inline bool is_last(void) { return base_list_iterator::is_last(); }
+};
+
+
+template <class T> class List_iterator_fast :public base_list_iterator
+{
+protected:
+ inline T *replace(T *a) { return (T*) 0; }
+ inline T *replace(List<T> &a) { return (T*) 0; }
+ inline void remove(void) { }
+ inline void after(T *a) { }
+ inline T** ref(void) { return (T**) 0; }
+
+public:
+ List_iterator_fast(List<T> &a) : base_list_iterator(a) {}
+ inline T* operator++(int) { return (T*) base_list_iterator::next_fast(); }
+ inline void rewind(void) { base_list_iterator::rewind(); }
};
/*
-** An simple intrusive list with automaticly removes element from list
-** on delete (for THD element)
+ A simple intrusive list which automaticly removes element from list
+ on delete (for THD element)
*/
-struct ilink {
+struct ilink
+{
struct ilink **prev,*next;
static void *operator new(size_t size)
{
@@ -257,9 +293,11 @@ struct ilink {
virtual ~ilink() { unlink(); } /*lint -e1740 */
};
+
template <class T> class I_List_iterator;
-class base_ilist {
+class base_ilist
+{
public:
struct ilink *first,last;
base_ilist() { first= &last; last.prev= &first; }
@@ -307,7 +345,8 @@ public:
template <class T>
-class I_List :private base_ilist {
+class I_List :private base_ilist
+{
public:
I_List() :base_ilist() {}
inline bool is_empty() { return base_ilist::is_empty(); }
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 1dcc8c2130e..93dfcd84caf 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,6 +20,7 @@
#include "mysql_priv.h"
#include <my_dir.h>
#include <m_ctype.h>
+#include "sql_repl.h"
class READ_INFO {
File file;
@@ -32,6 +33,7 @@ class READ_INFO {
int field_term_char,line_term_char,enclosed_char,escape_char;
int *stack,*stack_pos;
bool found_end_of_line,start_of_line,eof;
+ bool need_end_io_cache;
IO_CACHE cache;
NET *io_net;
@@ -50,13 +52,30 @@ public:
char unescape(char chr);
int terminator(char *ptr,uint length);
bool find_start_of_fields();
+ /*
+ We need to force cache close before destructor is invoked to log
+ the last read block
+ */
+ void end_io_cache()
+ {
+ ::end_io_cache(&cache);
+ need_end_io_cache = 0;
+ }
+
+ /*
+ Either this method, or we need to make cache public
+ Arg must be set from mysql_load() since constructor does not see
+ either the table or THD value
+ */
+ void set_io_cache_arg(void* arg) { cache.arg = arg; }
};
static int read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,
- List<Item> &fields, READ_INFO &read_info);
+ List<Item> &fields, READ_INFO &read_info,
+ ulong skip_lines);
static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
List<Item> &fields, READ_INFO &read_info,
- String &enclosed);
+ String &enclosed, ulong skip_lines);
int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
@@ -67,22 +86,32 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
File file;
TABLE *table;
int error;
- uint save_skip_lines = ex->skip_lines;
- String *field_term=ex->field_term,*escaped=ex->escaped,
- *enclosed=ex->enclosed;
+ String *field_term=ex->field_term,*escaped=ex->escaped;
+ String *enclosed=ex->enclosed;
bool is_fifo=0;
- bool using_transactions;
+ LOAD_FILE_INFO lf_info;
+ char *db = table_list->db; // This is never null
+ /* If no current database, use database where table is located */
+ char *tdb= thd->db ? thd->db : db;
+ bool transactional_table, log_delayed;
+ ulong skip_lines= ex->skip_lines;
DBUG_ENTER("mysql_load");
+#ifdef EMBEDDED_LIBRARY
+ read_file_from_client = 0; //server is always in the same process
+#endif
+
if (escaped->length() > 1 || enclosed->length() > 1)
{
my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS),
MYF(0));
DBUG_RETURN(-1);
}
-
if (!(table = open_ltable(thd,table_list,lock_type)))
DBUG_RETURN(-1);
+ transactional_table= table->file->has_transactions();
+ log_delayed= (transactional_table || table->tmp_table);
+
if (!fields.elements)
{
Field **field;
@@ -92,7 +121,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
else
{ // Part field list
thd->dupp_field=0;
- if (setup_tables(table_list) || setup_fields(thd,table_list,fields,1,0))
+ if (setup_tables(table_list) || setup_fields(thd,table_list,fields,1,0,0))
DBUG_RETURN(-1);
if (thd->dupp_field)
{
@@ -103,7 +132,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
uint tot_length=0;
bool use_blobs=0,use_timestamp=0;
- List_iterator<Item> it(fields);
+ List_iterator_fast<Item> it(fields);
Item_field *field;
while ((field=(Item_field*) it++))
@@ -133,37 +162,32 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (read_file_from_client)
{
- char tmp [FN_REFLEN+1],*end;
- DBUG_PRINT("info",("reading local file"));
- tmp[0] = (char) 251; /* NULL_LENGTH */
- end=strnmov(tmp+1,ex->file_name,sizeof(tmp)-2);
- (void) my_net_write(&thd->net,tmp,(uint) (end-tmp));
- (void) net_flush(&thd->net);
+ (void)net_request_file(&thd->net,ex->file_name);
file = -1;
}
else
{
- read_file_from_client=0;
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
ex->file_name+=dirname_length(ex->file_name);
#endif
if (!dirname_length(ex->file_name) &&
- strlen(ex->file_name)+strlen(mysql_data_home)+strlen(thd->db)+3 <
+ strlen(ex->file_name)+strlen(mysql_data_home)+strlen(tdb)+3 <
FN_REFLEN)
{
- (void) sprintf(name,"%s/%s/%s",mysql_data_home,thd->db,ex->file_name);
+ (void) sprintf(name,"%s/%s/%s",mysql_data_home,tdb,ex->file_name);
unpack_filename(name,name); /* Convert to system format */
}
else
{
unpack_filename(name,ex->file_name);
-#if !defined(__WIN__) && !defined(OS2)
+#if !defined(__WIN__) && !defined(OS2) && ! defined(__NETWARE__)
MY_STAT stat_info;
if (!my_stat(name,&stat_info,MYF(MY_WME)))
DBUG_RETURN(-1);
-
- // the file must be:
- if (!((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
+
+ // if we are not in slave thread, the file must be:
+ if (!thd->slave_thread &&
+ !((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
#ifndef __EMX__
(stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
#endif
@@ -196,75 +220,140 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
DBUG_RETURN(-1); // Can't allocate buffers
}
+ if (mysql_bin_log.is_open())
+ {
+ lf_info.thd = thd;
+ lf_info.ex = ex;
+ lf_info.db = db;
+ lf_info.table_name = table_list->real_name;
+ lf_info.fields = &fields;
+ lf_info.handle_dup = handle_duplicates;
+ lf_info.wrote_create_file = 0;
+ lf_info.last_pos_in_file = HA_POS_ERROR;
+ lf_info.log_delayed= log_delayed;
+ read_info.set_io_cache_arg((void*) &lf_info);
+ }
restore_record(table,2);
thd->count_cuted_fields=1; /* calc cuted fields */
thd->cuted_fields=0L;
- if (ex->line_term->length() && field_term->length())
+ /* Skip lines if there is a line terminator */
+ if (ex->line_term->length())
{
- while (ex->skip_lines--)
+ /* ex->skip_lines needs to be preserved for logging */
+ while (skip_lines > 0)
{
+ skip_lines--;
if (read_info.next_line())
break;
}
}
+
if (!(error=test(read_info.error)))
{
uint save_time_stamp=table->time_stamp;
if (use_timestamp)
table->time_stamp=0;
table->next_number_field=table->found_next_number_field;
- VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
+ VOID(table->file->extra_opt(HA_EXTRA_WRITE_CACHE,
+ thd->variables.read_buff_size));
+ table->bulk_insert= 1;
if (handle_duplicates == DUP_IGNORE ||
handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
table->file->deactivate_non_unique_index((ha_rows) 0);
table->copy_blobs=1;
if (!field_term->length() && !enclosed->length())
- error=read_fixed_length(thd,info,table,fields,read_info);
+ error=read_fixed_length(thd,info,table,fields,read_info,
+ skip_lines);
else
- error=read_sep_field(thd,info,table,fields,read_info,*enclosed);
- if (table->file->extra(HA_EXTRA_NO_CACHE) ||
- table->file->activate_all_index(thd))
- error=1; /* purecov: inspected */
+ error=read_sep_field(thd,info,table,fields,read_info,*enclosed,
+ skip_lines);
+ if (table->file->extra(HA_EXTRA_NO_CACHE))
+ error=1; /* purecov: inspected */
+ if (table->file->activate_all_index(thd))
+ error=1; /* purecov: inspected */
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->time_stamp=save_time_stamp;
table->next_number_field=0;
- if (thd->lock)
- {
- mysql_unlock_tables(thd, thd->lock);
- thd->lock=0;
- }
}
- if (file >= 0) my_close(file,MYF(0));
+ if (file >= 0)
+ my_close(file,MYF(0));
free_blobs(table); /* if pack_blob was used */
table->copy_blobs=0;
thd->count_cuted_fields=0; /* Don`t calc cuted fields */
- using_transactions = table->file->has_transactions();
+
if (error)
{
- if (using_transactions)
+ if (transactional_table)
ha_autocommit_or_rollback(thd,error);
- DBUG_RETURN(-1); // Error on read
+ if (mysql_bin_log.is_open())
+ {
+ /*
+ Make sure last block (the one which caused the error) gets logged.
+ This is needed because otherwise after write of
+ (to the binlog, not to read_info (which is a cache))
+ Delete_file_log_event the bad block will remain in read_info (because
+ pre_read is not called at the end of the last block; remember pre_read
+ is called whenever a new block is read from disk).
+ At the end of mysql_load(), the destructor of read_info will call
+ end_io_cache() which will flush read_info, so we will finally have
+ this in the binlog:
+ Append_block # The last successfull block
+ Delete_file
+ Append_block # The failing block
+ which is nonsense.
+ Or could also be (for a small file)
+ Create_file # The failing block
+ which is nonsense (Delete_file is not written in this case, because:
+ Create_file has not been written, so Delete_file is not written, then
+ when read_info is destroyed end_io_cache() is called which writes
+ Create_file.
+ */
+ read_info.end_io_cache();
+ /* If the file was not empty, wrote_create_file is true */
+ if (lf_info.wrote_create_file)
+ {
+ Delete_file_log_event d(thd, db, log_delayed);
+ mysql_bin_log.write(&d);
+ }
+ }
+ error= -1; // Error on read
+ goto err;
}
sprintf(name,ER(ER_LOAD_INFO),info.records,info.deleted,
info.records-info.copied,thd->cuted_fields);
send_ok(&thd->net,info.copied+info.deleted,0L,name);
// on the slave thd->query is never initialized
- if(!thd->slave_thread)
+ if (!thd->slave_thread)
mysql_update_log.write(thd,thd->query,thd->query_length);
-
- if (!using_transactions)
+
+ if (!log_delayed)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
- if (!read_file_from_client && mysql_bin_log.is_open())
+ if (mysql_bin_log.is_open())
{
- ex->skip_lines = save_skip_lines;
- Load_log_event qinfo(thd, ex, table->table_cache_key, table->table_name,
- fields, handle_duplicates);
- mysql_bin_log.write(&qinfo);
+ /*
+ As already explained above, we need to call end_io_cache() or the last
+ block will be logged only after Execute_load_log_event (which is wrong),
+ when read_info is destroyed.
+ */
+ read_info.end_io_cache();
+ if (lf_info.wrote_create_file)
+ {
+ Execute_load_log_event e(thd, db, log_delayed);
+ mysql_bin_log.write(&e);
+ }
}
- if (using_transactions)
+ if (transactional_table)
error=ha_autocommit_or_rollback(thd,error);
+ query_cache_invalidate3(thd, table_list, 0);
+
+err:
+ if (thd->lock)
+ {
+ mysql_unlock_tables(thd, thd->lock);
+ thd->lock=0;
+ }
DBUG_RETURN(error);
}
@@ -275,12 +364,14 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
static int
read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
- READ_INFO &read_info)
+ READ_INFO &read_info, ulong skip_lines)
{
- List_iterator<Item> it(fields);
+ List_iterator_fast<Item> it(fields);
Item_field *sql_field;
+ ulonglong id;
DBUG_ENTER("read_fixed_length");
+ id=0;
/* No fields can be null in this format. mark all fields as not null */
while ((sql_field= (Item_field*) it++))
sql_field->field->set_notnull();
@@ -292,6 +383,17 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
my_error(ER_SERVER_SHUTDOWN,MYF(0));
DBUG_RETURN(1);
}
+ if (skip_lines)
+ {
+ /*
+ We could implement this with a simple seek if:
+ - We are not using DATA INFILE LOCAL
+ - escape character is ""
+ - line starting prefix is ""
+ */
+ skip_lines--;
+ continue;
+ }
it.rewind();
byte *pos=read_info.row_start;
#ifdef HAVE_purify
@@ -323,13 +425,23 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
thd->cuted_fields++; /* To long row */
if (write_record(table,&info))
DBUG_RETURN(1);
+ /*
+ If auto_increment values are used, save the first one
+ for LAST_INSERT_ID() and for the binary/update log.
+ We can't use insert_id() as we don't want to touch the
+ last_insert_id_used flag.
+ */
+ if (!id && thd->insert_id_used)
+ id= thd->last_insert_id;
if (table->next_number_field)
table->next_number_field->reset(); // Clear for next record
- if (read_info.next_line()) // Skipp to next line
+ if (read_info.next_line()) // Skip to next line
break;
if (read_info.line_cuted)
thd->cuted_fields++; /* To long row */
}
+ if (id && !read_info.error)
+ thd->insert_id(id); // For binary/update log
DBUG_RETURN(test(read_info.error));
}
@@ -338,15 +450,17 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
static int
read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
List<Item> &fields, READ_INFO &read_info,
- String &enclosed)
+ String &enclosed, ulong skip_lines)
{
- List_iterator<Item> it(fields);
+ List_iterator_fast<Item> it(fields);
Item_field *sql_field;
uint enclosed_length;
+ ulonglong id;
DBUG_ENTER("read_sep_field");
enclosed_length=enclosed.length();
-
+ id=0;
+
for (;;it.rewind())
{
if (thd->killed)
@@ -375,7 +489,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
{
if (field->type() == FIELD_TYPE_TIMESTAMP)
((Field_timestamp*) field)->set_time();
- else
+ else if (field != table->next_number_field)
thd->cuted_fields++;
}
continue;
@@ -386,11 +500,17 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
}
if (read_info.error)
break;
+ if (skip_lines)
+ {
+ if (!--skip_lines)
+ thd->cuted_fields= 0L; // Reset warnings
+ continue;
+ }
if (sql_field)
{ // Last record
if (sql_field == (Item_field*) fields.head())
break;
- for ( ; sql_field ; sql_field=(Item_field*) it++)
+ for (; sql_field ; sql_field=(Item_field*) it++)
{
sql_field->field->set_null();
sql_field->field->reset();
@@ -399,13 +519,23 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
}
if (write_record(table,&info))
DBUG_RETURN(1);
+ /*
+ If auto_increment values are used, save the first one
+ for LAST_INSERT_ID() and for the binary/update log.
+ We can't use insert_id() as we don't want to touch the
+ last_insert_id_used flag.
+ */
+ if (!id && thd->insert_id_used)
+ id= thd->last_insert_id;
if (table->next_number_field)
table->next_number_field->reset(); // Clear for next record
- if (read_info.next_line()) // Skipp to next line
+ if (read_info.next_line()) // Skip to next line
break;
if (read_info.line_cuted)
thd->cuted_fields++; /* To long row */
}
+ if (id && !read_info.error)
+ thd->insert_id(id); // For binary/update log
DBUG_RETURN(test(read_info.error));
}
@@ -430,8 +560,10 @@ READ_INFO::unescape(char chr)
}
- /* Read a line using buffering */
- /* If last line is empty (in line mode) then it isn't outputed */
+/*
+ Read a line using buffering
+ If last line is empty (in line mode) then it isn't outputed
+*/
READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term,
@@ -488,6 +620,22 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term,
my_free((gptr) buffer,MYF(0)); /* purecov: inspected */
error=1;
}
+ else
+ {
+ /*
+ init_io_cache() will not initialize read_function member
+ if the cache is READ_NET. The reason is explained in
+ mysys/mf_iocache.c. So we work around the problem with a
+ manual assignment
+ */
+ if (get_it_from_net)
+ cache.read_function = _my_b_net_read;
+
+ need_end_io_cache = 1;
+ if (mysql_bin_log.is_open())
+ cache.pre_read = cache.pre_close =
+ (IO_CACHE_CALLBACK) log_loaded_block;
+ }
}
}
@@ -496,7 +644,8 @@ READ_INFO::~READ_INFO()
{
if (!error)
{
- end_io_cache(&cache);
+ if (need_end_io_cache)
+ ::end_io_cache(&cache);
my_free((gptr) buffer,MYF(0));
error=1;
}
@@ -536,10 +685,10 @@ int READ_INFO::read_field()
if (found_end_of_line)
return 1; // One have to call next_line
- /* Skipp until we find 'line_start' */
+ /* Skip until we find 'line_start' */
if (start_of_line)
- { // Skipp until line_start
+ { // Skip until line_start
start_of_line=0;
if (find_start_of_fields())
return 1;
@@ -643,9 +792,13 @@ int READ_INFO::read_field()
row_end= to;
return 0;
}
- /* Copy the found '"' character */
+ /*
+ The string didn't terminate yet.
+ Store back next character for the loop
+ */
PUSH(chr);
- chr='"';
+ /* copy the found term character to 'to' */
+ chr= found_enclosed_char;
}
else if (chr == field_term_char && found_enclosed_char == INT_MAX)
{
@@ -680,9 +833,20 @@ found_eof:
}
/*
-** One can't use fixed length with multi-byte charset **
+ Read a row with fixed length.
+
+ NOTES
+ The row may not be fixed size on disk if there are escape
+ characters in the file.
+
+ IMPLEMENTATION NOTE
+ One can't use fixed length with multi-byte charset **
+
+ RETURN
+ 0 ok
+ 1 error
*/
-
+
int READ_INFO::read_fixed_length()
{
int chr;
@@ -691,7 +855,7 @@ int READ_INFO::read_fixed_length()
return 1; // One have to call next_line
if (start_of_line)
- { // Skipp until line_start
+ { // Skip until line_start
start_of_line=0;
if (find_start_of_fields())
return 1;
diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc
index 53953c96d0b..0af6a80d4c2 100644
--- a/sql/sql_manager.cc
+++ b/sql/sql_manager.cc
@@ -32,7 +32,7 @@ pthread_t manager_thread;
pthread_mutex_t LOCK_manager;
pthread_cond_t COND_manager;
-pthread_handler_decl(handle_manager,arg __attribute__((unused)))
+extern "C" pthread_handler_decl(handle_manager,arg __attribute__((unused)))
{
int error = 0;
ulong status;
@@ -55,13 +55,7 @@ pthread_handler_decl(handle_manager,arg __attribute__((unused)))
{
if (reset_flush_time)
{
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec = time(NULL)+flush_time; // Bsd 2.1
- abstime.ts_nsec = 0;
-#else
- abstime.tv_sec = time(NULL)+flush_time; // Linux or Solairs
- abstime.tv_nsec = 0;
-#endif
+ set_timespec(abstime, flush_time);
reset_flush_time = FALSE;
}
while (!manager_status && !error && !abort_loop)
diff --git a/sql/sql_map.cc b/sql/sql_map.cc
index 4578b85d10a..e7e24f957c6 100644
--- a/sql/sql_map.cc
+++ b/sql/sql_map.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/sql_map.h b/sql/sql_map.h
index 34f2f755b43..632eb6e4f64 100644
--- a/sql/sql_map.h
+++ b/sql/sql_map.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc
new file mode 100644
index 00000000000..6eb4fbcaaf6
--- /dev/null
+++ b/sql/sql_olap.cc
@@ -0,0 +1,194 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ OLAP implementation by Sinisa Milivojevic <sinisa@mysql.com>
+ Inspired by code submitted by Srilakshmi <lakshmi@gdit.iiit.net>
+
+ The ROLLUP code in this file has to be complitely rewritten as it's
+ not good enough to satisfy the goals of MySQL.
+
+ In 4.1 we will replace this with a working, superior implementation
+ of ROLLUP.
+*/
+
+#ifdef DISABLED_UNTIL_REWRITTEN_IN_4_1
+
+#ifdef __GNUC__
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+
+
+/****************************************************************************
+ Functions that recursively actually creates new SELECT's
+ Returns 0 if OK, 1 if error, -1 if error already printed to client
+****************************************************************************/
+
+
+static int make_new_olap_select(LEX *lex, SELECT_LEX *select_lex, List<Item> new_fields)
+{
+ THD *thd=current_thd;
+ Item *item, *new_item;
+ Item_null *constant= new Item_null("ALL");
+
+ SELECT_LEX *new_select = (SELECT_LEX *) thd->memdup((char*) select_lex, sizeof(*select_lex));
+ if (!new_select)
+ return 1;
+ lex->last_selects->next=new_select;
+ new_select->linkage=OLAP_TYPE;
+ new_select->olap=NON_EXISTING_ONE;
+ new_select->group_list.elements=0;
+ new_select->group_list.first=(byte *)0;
+ new_select->group_list.next=(byte **)&new_select->group_list.first;
+ List<Item> privlist;
+
+ List_iterator<Item> list_it(select_lex->item_list);
+ List_iterator<Item> new_it(new_fields);
+
+ while((item=list_it++))
+ {
+ bool not_found=true;
+ if (item->type()==Item::FIELD_ITEM)
+ {
+ Item_field *iif = (Item_field *)item;
+ new_it.rewind();
+ while ((new_item=new_it++))
+ {
+ if (new_item->type()==Item::FIELD_ITEM &&
+ !strcmp(((Item_field*)new_item)->table_name,iif->table_name) &&
+ !strcmp(((Item_field*)new_item)->field_name,iif->field_name))
+ {
+ not_found= 0;
+ ((Item_field*)new_item)->db_name=iif->db_name;
+ Item_field *new_one=new Item_field(iif->db_name, iif->table_name, iif->field_name);
+ privlist.push_back(new_one);
+ if (add_to_list(new_select->group_list,new_one,1))
+ return 1;
+ break;
+ }
+ }
+ }
+ if (not_found)
+ {
+ if (item->type() == Item::FIELD_ITEM)
+ privlist.push_back(constant);
+ else
+ privlist.push_back((Item*)thd->memdup((char *)item,item->size_of()));
+ }
+ }
+ new_select->item_list=privlist;
+
+ lex->last_selects = new_select;
+ return 0;
+}
+
+/****************************************************************************
+ Functions that recursively creates combinations of queries for OLAP
+ Returns 0 if OK, 1 if error, -1 if error already printed to client
+****************************************************************************/
+
+static int olap_combos(List<Item> old_fields, List<Item> new_fields, Item *item, LEX *lex,
+ SELECT_LEX *select_lex, int position, int selection, int num_fields,
+ int num_new_fields)
+{
+ int sl_return = 0;
+ if(position == num_new_fields)
+ {
+ if(item)
+ new_fields.push_front(item);
+ sl_return = make_new_olap_select(lex, select_lex, new_fields);
+ }
+ else
+ {
+ if(item)
+ new_fields.push_front(item);
+ while ((num_fields - num_new_fields >= selection - position) && !sl_return)
+ {
+ item = old_fields.pop();
+ sl_return = olap_combos(old_fields, new_fields, item, lex, select_lex, position+1, ++selection, num_fields, num_new_fields);
+ }
+ }
+ return sl_return;
+}
+
+
+/****************************************************************************
+ Top level function for converting OLAP clauses to multiple selects
+ This is also a place where clauses treatment depends on OLAP type
+ Returns 0 if OK, 1 if error, -1 if error already printed to client
+****************************************************************************/
+
+int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
+{
+ List<Item> item_list_copy, new_item_list;
+ item_list_copy.empty();
+ new_item_list.empty();
+ int count=select_lex->group_list.elements;
+ int sl_return=0;
+
+// a fix for UNION's
+ for (TABLE_LIST *cursor= (TABLE_LIST *)select_lex->table_list.first;
+ cursor;
+ cursor=cursor->next)
+ {
+ if (cursor->do_redirect)
+ {
+ cursor->table= ((TABLE_LIST*) cursor->table)->table;
+ cursor->do_redirect= 0;
+ }
+ }
+
+ lex->last_selects=select_lex;
+
+ for (ORDER *order=(ORDER *)select_lex->group_list.first ; order ; order=order->next)
+ item_list_copy.push_back(*(order->item));
+
+ List<Item> all_fields(select_lex->item_list);
+
+
+ if (setup_tables((TABLE_LIST *)select_lex->table_list.first) ||
+ setup_fields(lex->thd,(TABLE_LIST *)select_lex->table_list.first,select_lex->item_list,1,&all_fields,1) ||
+ setup_fields(lex->thd,(TABLE_LIST *)select_lex->table_list.first,item_list_copy,1,&all_fields,1))
+ return -1;
+
+ if (select_lex->olap == CUBE_TYPE)
+ {
+ for( int i=count-1; i>=0 && !sl_return; i--)
+ sl_return=olap_combos(item_list_copy, new_item_list, (Item *)0, lex, select_lex, 0, 0, count, i);
+ }
+ else if (select_lex->olap == ROLLUP_TYPE)
+ {
+ for( int i=count-1; i>=0 && !sl_return; i--)
+ {
+ Item *item;
+ item_list_copy.pop();
+ List_iterator<Item> it(item_list_copy);
+ new_item_list.empty();
+ while ((item = it++))
+ new_item_list.push_front(item);
+ sl_return=make_new_olap_select(lex, select_lex, new_item_list);
+ }
+ }
+ else
+ sl_return=1; // impossible
+ return sl_return;
+}
+
+#endif /* DISABLED_UNTIL_REWRITTEN_IN_4_1 */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 3f6fa8d24ad..ac3ccd4fc62 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -14,39 +14,57 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
#include "mysql_priv.h"
#include "sql_acl.h"
#include "sql_repl.h"
+#include "repl_failsafe.h"
#include <m_ctype.h>
-#include <thr_alarm.h>
#include <myisam.h>
#include <my_dir.h>
#include <assert.h>
#ifdef HAVE_INNOBASE_DB
-#include "ha_innobase.h"
+#include "ha_innodb.h"
#endif
+#ifdef HAVE_OPENSSL
+/*
+ Without SSL the handshake consists of one packet. This packet
+ has both client capabilites and scrambled password.
+ With SSL the handshake might consist of two packets. If the first
+ packet (client capabilities) has CLIENT_SSL flag set, we have to
+ switch to SSL and read the second packet. The scrambled password
+ is in the second packet and client_capabilites field will be ignored.
+ Maybe it is better to accept flags other than CLIENT_SSL from the
+ second packet?
+*/
+#define SSL_HANDSHAKE_SIZE 2
+#define NORMAL_HANDSHAKE_SIZE 6
+#define MIN_HANDSHAKE_SIZE 2
+#else
+#define MIN_HANDSHAKE_SIZE 6
+#endif /* HAVE_OPENSSL */
#define SCRAMBLE_LENGTH 8
-
extern int yyparse(void);
extern "C" pthread_mutex_t THR_LOCK_keycache;
#ifdef SOLARIS
extern "C" int gethostname(char *name, int namelen);
#endif
-static int check_for_max_user_connections(const char *user, int u_length,
- const char *host);
-static void decrease_user_connections(const char *user, const char *host);
+static int check_for_max_user_connections(USER_CONN *uc);
+static void decrease_user_connections(USER_CONN *uc);
static bool check_db_used(THD *thd,TABLE_LIST *tables);
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
-static bool check_dup(THD *thd,const char *db,const char *name,
- TABLE_LIST *tables);
static void mysql_init_query(THD *thd);
static void remove_escape(char *name);
static void refresh_status(void);
+static bool append_file_to_dir(THD *thd, const char **filename_ptr,
+ const char *table_name);
+static bool create_total_list(THD *thd, LEX *lex,
+ TABLE_LIST **result, bool skip_first);
+static bool check_one_table_access(THD *thd, ulong want_access,
+ TABLE_LIST *table, bool no_errors);
const char *any_db="*any*"; // Special symbol for check_access
@@ -54,15 +72,12 @@ const char *command_name[]={
"Sleep", "Quit", "Init DB", "Query", "Field List", "Create DB",
"Drop DB", "Refresh", "Shutdown", "Statistics", "Processlist",
"Connect","Kill","Debug","Ping","Time","Delayed_insert","Change user",
- "Binlog Dump","Table Dump", "Connect Out"
+ "Binlog Dump","Table Dump", "Connect Out", "Register Slave",
+ "Error" // Last command number
};
bool volatile abort_slave = 0;
-#ifdef HAVE_OPENSSL
-extern VioSSLAcceptorFd* ssl_acceptor_fd;
-#endif /* HAVE_OPENSSL */
-
#ifdef __WIN__
static void test_signal(int sig_ptr)
{
@@ -70,22 +85,32 @@ static void test_signal(int sig_ptr)
MessageBox(NULL,"Test signal","DBUG",MB_OK);
#endif
#if defined(OS2)
- fprintf( stderr, "Test signal %d\n", sig_ptr);
- fflush( stderr);
+ fprintf(stderr, "Test signal %d\n", sig_ptr);
+ fflush(stderr);
#endif
}
static void init_signals(void)
{
int signals[7] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGBREAK,SIGABRT } ;
- for(int i=0 ; i < 7 ; i++)
+ for (int i=0 ; i < 7 ; i++)
signal( signals[i], test_signal) ;
}
#endif
-inline bool end_active_trans(THD *thd)
+static void unlock_locked_tables(THD *thd)
+{
+ if (thd->locked_tables)
+ {
+ thd->lock=thd->locked_tables;
+ thd->locked_tables=0; // Will be automaticly closed
+ close_thread_tables(thd); // Free tables
+ }
+}
+
+static bool end_active_trans(THD *thd)
{
int error=0;
- if (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN |
+ if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK))
{
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
@@ -97,10 +122,69 @@ inline bool end_active_trans(THD *thd)
}
+static HASH hash_user_connections;
+extern pthread_mutex_t LOCK_user_conn;
+
+static int get_or_create_user_conn(THD *thd, const char *user,
+ const char *host,
+ USER_RESOURCES *mqh)
+{
+ int return_val=0;
+ uint temp_len, user_len, host_len;
+ char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
+ struct user_conn *uc;
+
+ DBUG_ASSERT(user != 0);
+ DBUG_ASSERT(host != 0);
+
+ user_len=strlen(user);
+ host_len=strlen(host);
+ temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1;
+ (void) pthread_mutex_lock(&LOCK_user_conn);
+ if (!(uc = (struct user_conn *) hash_search(&hash_user_connections,
+ (byte*) temp_user, temp_len)))
+ {
+ /* First connection for user; Create a user connection object */
+ if (!(uc= ((struct user_conn*)
+ my_malloc(sizeof(struct user_conn) + temp_len+1,
+ MYF(MY_WME)))))
+ {
+ send_error(&current_thd->net, 0, NullS); // Out of memory
+ return_val=1;
+ goto end;
+ }
+ uc->user=(char*) (uc+1);
+ memcpy(uc->user,temp_user,temp_len+1);
+ uc->user_len= user_len;
+ uc->host=uc->user + uc->user_len + 1;
+ uc->len = temp_len;
+ uc->connections = 0;
+ uc->questions=uc->updates=uc->conn_per_hour=0;
+ uc->user_resources=*mqh;
+ if (max_user_connections && mqh->connections > max_user_connections)
+ uc->user_resources.connections = max_user_connections;
+ uc->intime=thd->thr_create_time;
+ if (hash_insert(&hash_user_connections, (byte*) uc))
+ {
+ my_free((char*) uc,0);
+ send_error(&current_thd->net, 0, NullS); // Out of memory
+ return_val=1;
+ goto end;
+ }
+ }
+ thd->user_connect=uc;
+ uc->connections++;
+end:
+ (void) pthread_mutex_unlock(&LOCK_user_conn);
+ return return_val;
+
+}
+
+
/*
-** Check if user is ok
-** Updates:
-** thd->user, thd->master_access, thd->priv_user, thd->db, thd->db_access
+ Check if user is ok
+ Updates:
+ thd->{user,master_access,priv_user,priv_host,db,db_access}
*/
static bool check_user(THD *thd,enum_server_command command, const char *user,
@@ -108,34 +192,45 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
{
NET *net= &thd->net;
thd->db=0;
+ thd->db_length=0;
+ USER_RESOURCES ur;
+ char tmp_passwd[SCRAMBLE_LENGTH + 1];
if (passwd[0] && strlen(passwd) != SCRAMBLE_LENGTH)
return 1;
+ /*
+ Move password to temporary buffer as it may be stored in communication
+ buffer
+ */
+ strmov(tmp_passwd, passwd);
+ passwd= tmp_passwd; // Use local copy
+
if (!(thd->user = my_strdup(user, MYF(0))))
{
send_error(net,ER_OUT_OF_RESOURCES);
return 1;
}
- thd->master_access=acl_getroot(thd->host, thd->ip, thd->user,
- passwd, thd->scramble, &thd->priv_user,
+ thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user,
+ passwd, thd->scramble,
+ &thd->priv_user, thd->priv_host,
protocol_version == 9 ||
!(thd->client_capabilities &
- CLIENT_LONG_PASSWORD));
- DBUG_PRINT("general",
- ("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
- thd->client_capabilities, thd->max_packet_length,
- thd->host ? thd->host : thd->ip, thd->priv_user,
+ CLIENT_LONG_PASSWORD),&ur);
+ DBUG_PRINT("info",
+ ("Capabilities: %d packet_length: %ld Host: '%s' Login user: '%s' Priv_user: '%s' Using password: %s Access: %u db: '%s'",
+ thd->client_capabilities, thd->max_client_packet_length,
+ thd->host_or_ip, thd->user, thd->priv_user,
passwd[0] ? "yes": "no",
thd->master_access, thd->db ? thd->db : "*none*"));
if (thd->master_access & NO_ACCESS)
{
net_printf(net, ER_ACCESS_DENIED_ERROR,
thd->user,
- thd->host ? thd->host : thd->ip,
+ thd->host_or_ip,
passwd[0] ? ER(ER_YES) : ER(ER_NO));
mysql_log.write(thd,COM_CONNECT,ER(ER_ACCESS_DENIED_ERROR),
thd->user,
- thd->host ? thd->host : thd->ip ? thd->ip : "unknown ip",
+ thd->host_or_ip,
passwd[0] ? ER(ER_YES) : ER(ER_NO));
return(1); // Error already given
}
@@ -143,7 +238,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
{
VOID(pthread_mutex_lock(&LOCK_thread_count));
bool tmp=(thread_count - delayed_insert_threads >= max_connections &&
- !(thd->master_access & PROCESS_ACL));
+ !(thd->master_access & SUPER_ACL));
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (tmp)
{ // Too many connections
@@ -156,147 +251,96 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
(char*) "%s@%s on %s" :
(char*) "%s@%s as anonymous on %s"),
user,
- thd->host ? thd->host : thd->ip ? thd->ip : "unknown ip",
+ thd->host_or_ip,
db ? db : (char*) "");
thd->db_access=0;
- if (max_user_connections &&
- check_for_max_user_connections(user, strlen(user), thd->host))
+ /* Don't allow user to connect if he has done too many queries */
+ if ((ur.questions || ur.updates || ur.connections || max_user_connections) &&
+ get_or_create_user_conn(thd,user,thd->host_or_ip,&ur))
+ return -1;
+ if (thd->user_connect && (thd->user_connect->user_resources.connections ||
+ max_user_connections) &&
+ check_for_max_user_connections(thd->user_connect))
return -1;
if (db && db[0])
{
bool error=test(mysql_change_db(thd,db));
- if (error)
- decrease_user_connections(thd->user,thd->host);
+ if (error && thd->user_connect)
+ decrease_user_connections(thd->user_connect);
return error;
}
- else
- send_ok(net); // Ready to handle questions
+ send_ok(net); // Ready to handle questions
+ thd->password= test(passwd[0]); // Remember for error messages
return 0; // ok
}
+
/*
-** check for maximum allowable user connections
-** if mysql server is started with corresponding
-** variable that is greater then 0
+ Check for maximum allowable user connections, if the mysqld server is
+ started with corresponding variable that is greater then 0.
*/
-static HASH hash_user_connections;
-extern pthread_mutex_t LOCK_user_conn;
-
-struct user_conn {
- char *user;
- uint len, connections;
-};
-
-static byte* get_key_conn(user_conn *buff, uint *length,
- my_bool not_used __attribute__((unused)))
+extern "C" byte *get_key_conn(user_conn *buff, uint *length,
+ my_bool not_used __attribute__((unused)))
{
*length=buff->len;
return (byte*) buff->user;
}
-#define DEF_USER_COUNT 50
-
-static void free_user(struct user_conn *uc)
+extern "C" void free_user(struct user_conn *uc)
{
my_free((char*) uc,MYF(0));
}
void init_max_user_conn(void)
{
- (void) hash_init(&hash_user_connections,DEF_USER_COUNT,0,0,
- (hash_get_key) get_key_conn, (void (*)(void*)) free_user,
+ (void) hash_init(&hash_user_connections,max_connections,0,0,
+ (hash_get_key) get_key_conn, (hash_free_key) free_user,
0);
}
-static int check_for_max_user_connections(const char *user, int u_length,
- const char *host)
+static int check_for_max_user_connections(USER_CONN *uc)
{
- int error=1;
- uint temp_len;
- char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
- struct user_conn *uc;
- if (!user)
- user="";
- if (!host)
- host="";
+ int error=0;
DBUG_ENTER("check_for_max_user_connections");
- DBUG_PRINT("enter",("user: '%s' host: '%s'", user, host));
- temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host,
- NullS) - temp_user);
(void) pthread_mutex_lock(&LOCK_user_conn);
- uc = (struct user_conn *) hash_search(&hash_user_connections,
- (byte*) temp_user, temp_len);
- if (uc) /* user found ; check for no. of connections */
+ if (max_user_connections &&
+ max_user_connections < uc->connections)
{
- if (max_user_connections == (uint) uc->connections)
- {
- net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, temp_user);
- goto end;
- }
- uc->connections++;
+ net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, uc->user);
+ error=1;
+ goto end;
}
- else
+ if (uc->user_resources.connections &&
+ uc->user_resources.connections <= uc->conn_per_hour)
{
- /* the user is not found in the cache; Insert it */
- struct user_conn *uc= ((struct user_conn*)
- my_malloc(sizeof(struct user_conn) + temp_len+1,
- MYF(MY_WME)));
- if (!uc)
- {
- send_error(&current_thd->net, 0, NullS); // Out of memory
- goto end;
- }
- uc->user=(char*) (uc+1);
- memcpy(uc->user,temp_user,temp_len+1);
- uc->len = temp_len;
- uc->connections = 1;
- if (hash_insert(&hash_user_connections, (byte*) uc))
- {
- my_free((char*) uc,0);
- send_error(&current_thd->net, 0, NullS); // Out of memory
- goto end;
- }
+ net_printf(&current_thd->net, ER_USER_LIMIT_REACHED, uc->user,
+ "max_connections",
+ (long) uc->user_resources.connections);
+ error=1;
+ goto end;
}
- error=0;
-
+ uc->conn_per_hour++;
end:
+ if (error)
+ uc->connections--; // no need for decrease_user_connections() here
(void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_RETURN(error);
}
-static void decrease_user_connections(const char *user, const char *host)
+static void decrease_user_connections(USER_CONN *uc)
{
- char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
- int temp_len;
- struct user_conn *uc;
- if (!max_user_connections)
- return;
- if (!user)
- user="";
- if (!host)
- host="";
DBUG_ENTER("decrease_user_connections");
- DBUG_PRINT("enter",("user: '%s' host: '%s'", user, host));
-
- temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host,
- NullS) - temp_user);
(void) pthread_mutex_lock(&LOCK_user_conn);
-
- uc = (struct user_conn *) hash_search(&hash_user_connections,
- (byte*) temp_user, temp_len);
- dbug_assert(uc != 0); // We should always find the user
- if (!uc)
- goto end; // Safety; Something went wrong
- if (! --uc->connections)
+ DBUG_ASSERT(uc->connections);
+ if (!--uc->connections && !mqh_used)
{
/* Last connection for user; Delete it */
(void) hash_delete(&hash_user_connections,(byte*) uc);
}
-end:
(void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_VOID_RETURN;
}
@@ -309,103 +353,219 @@ void free_max_user_conn(void)
/*
-** check connnetion and get priviliges
-** returns 0 on ok, -1 < if error is given > 0 on error.
+ Mark all commands that somehow changes a table
+ This is used to check number of updates / hour
*/
+char uc_update_queries[SQLCOM_END];
+
+void init_update_queries(void)
+{
+ uc_update_queries[SQLCOM_CREATE_TABLE]=1;
+ uc_update_queries[SQLCOM_CREATE_INDEX]=1;
+ uc_update_queries[SQLCOM_ALTER_TABLE]=1;
+ uc_update_queries[SQLCOM_UPDATE]=1;
+ uc_update_queries[SQLCOM_INSERT]=1;
+ uc_update_queries[SQLCOM_INSERT_SELECT]=1;
+ uc_update_queries[SQLCOM_DELETE]=1;
+ uc_update_queries[SQLCOM_TRUNCATE]=1;
+ uc_update_queries[SQLCOM_DROP_TABLE]=1;
+ uc_update_queries[SQLCOM_LOAD]=1;
+ uc_update_queries[SQLCOM_CREATE_DB]=1;
+ uc_update_queries[SQLCOM_DROP_DB]=1;
+ uc_update_queries[SQLCOM_REPLACE]=1;
+ uc_update_queries[SQLCOM_REPLACE_SELECT]=1;
+ uc_update_queries[SQLCOM_RENAME_TABLE]=1;
+ uc_update_queries[SQLCOM_BACKUP_TABLE]=1;
+ uc_update_queries[SQLCOM_RESTORE_TABLE]=1;
+ uc_update_queries[SQLCOM_DELETE_MULTI]=1;
+ uc_update_queries[SQLCOM_DROP_INDEX]=1;
+ uc_update_queries[SQLCOM_MULTI_UPDATE]=1;
+}
+
+
+/*
+ Check if maximum queries per hour limit has been reached
+ returns 0 if OK.
+
+ In theory we would need a mutex in the USER_CONN structure for this to
+ be 100 % safe, but as the worst scenario is that we would miss counting
+ a couple of queries, this isn't critical.
+*/
+
+
+static bool check_mqh(THD *thd, uint check_command)
+{
+ bool error=0;
+ time_t check_time = thd->start_time ? thd->start_time : time(NULL);
+ USER_CONN *uc=thd->user_connect;
+ DBUG_ENTER("check_mqh");
+ DBUG_ASSERT(uc != 0);
+
+ /* If more than a hour since last check, reset resource checking */
+ if (check_time - uc->intime >= 3600)
+ {
+ (void) pthread_mutex_lock(&LOCK_user_conn);
+ uc->questions=1;
+ uc->updates=0;
+ uc->conn_per_hour=0;
+ uc->intime=check_time;
+ (void) pthread_mutex_unlock(&LOCK_user_conn);
+ }
+ /* Check that we have not done too many questions / hour */
+ if (uc->user_resources.questions &&
+ uc->questions++ >= uc->user_resources.questions)
+ {
+ net_printf(&thd->net, ER_USER_LIMIT_REACHED, uc->user, "max_questions",
+ (long) uc->user_resources.questions);
+ error=1;
+ goto end;
+ }
+ if (check_command < (uint) SQLCOM_END)
+ {
+ /* Check that we have not done too many updates / hour */
+ if (uc->user_resources.updates && uc_update_queries[check_command] &&
+ uc->updates++ >= uc->user_resources.updates)
+ {
+ net_printf(&thd->net, ER_USER_LIMIT_REACHED, uc->user, "max_updates",
+ (long) uc->user_resources.updates);
+ error=1;
+ goto end;
+ }
+ }
+end:
+ DBUG_RETURN(error);
+}
+
+
+static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0)
+{
+
+ (void) pthread_mutex_lock(&LOCK_user_conn);
+ if (lu) // for GRANT
+ {
+ USER_CONN *uc;
+ uint temp_len=lu->user.length+lu->host.length+2;
+ char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
+
+ memcpy(temp_user,lu->user.str,lu->user.length);
+ memcpy(temp_user+lu->user.length+1,lu->host.str,lu->host.length);
+ temp_user[lu->user.length]='\0'; temp_user[temp_len-1]=0;
+ if ((uc = (struct user_conn *) hash_search(&hash_user_connections,
+ (byte*) temp_user, temp_len)))
+ {
+ uc->questions=0;
+ get_mqh(temp_user,&temp_user[lu->user.length+1],uc);
+ uc->updates=0;
+ uc->conn_per_hour=0;
+ }
+ }
+ else // for FLUSH PRIVILEGES and FLUSH USER_RESOURCES
+ {
+ for (uint idx=0;idx < hash_user_connections.records; idx++)
+ {
+ USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections, idx);
+ if (get_them)
+ get_mqh(uc->user,uc->host,uc);
+ uc->questions=0;
+ uc->updates=0;
+ uc->conn_per_hour=0;
+ }
+ }
+ (void) pthread_mutex_unlock(&LOCK_user_conn);
+}
+
+
+/*
+ Check connnetion and get priviliges
+ Returns 0 on ok, -1 < if error is given > 0 on error.
+*/
static int
check_connections(THD *thd)
{
uint connect_errors=0;
NET *net= &thd->net;
- /*
- ** store the connection details
- */
+ /* Store the connection details */
DBUG_PRINT("info", (("check_connections called by thread %d"),
thd->thread_id));
- DBUG_PRINT("general",("New connection received on %s",
+ DBUG_PRINT("info",("New connection received on %s",
vio_description(net->vio)));
if (!thd->host) // If TCP/IP connection
{
char ip[30];
- if (vio_peer_addr(net->vio,ip))
+ if (vio_peer_addr(net->vio, ip, &thd->peer_port))
return (ER_BAD_HOST_ERROR);
if (!(thd->ip = my_strdup(ip,MYF(0))))
return (ER_OUT_OF_RESOURCES);
+ thd->host_or_ip=thd->ip;
#if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread)
/* Fast local hostname resolve for Win32 */
if (!strcmp(thd->ip,"127.0.0.1"))
- thd->host=(char*) localhost;
+ {
+ thd->host= (char*) localhost;
+ thd->host_or_ip= localhost;
+ }
else
#endif
if (!(specialflag & SPECIAL_NO_RESOLVE))
{
vio_in_addr(net->vio,&thd->remote.sin_addr);
thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
+ /* Cut very long hostnames to avoid possible overflows */
+ if (thd->host)
+ {
+ thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
+ thd->host_or_ip= thd->host;
+ }
if (connect_errors > max_connect_errors)
return(ER_HOST_IS_BLOCKED);
}
- DBUG_PRINT("general",("Host: %s ip: %s",
- thd->host ? thd->host : "unknown host",
- thd->ip ? thd->ip : "unknown ip"));
+ DBUG_PRINT("info",("Host: %s ip: %s",
+ thd->host ? thd->host : "unknown host",
+ thd->ip ? thd->ip : "unknown ip"));
if (acl_check_host(thd->host,thd->ip))
return(ER_HOST_NOT_PRIVILEGED);
}
else /* Hostname given means that the connection was on a socket */
{
- DBUG_PRINT("general",("Host: %s",thd->host));
- thd->ip=0;
+ DBUG_PRINT("info",("Host: %s",thd->host));
+ thd->host_or_ip= thd->host;
+ thd->ip= 0;
bzero((char*) &thd->remote,sizeof(struct sockaddr));
}
vio_keepalive(net->vio, TRUE);
- /* nasty, but any other way? */
- uint pkt_len = 0;
+ ulong pkt_len=0;
{
/* buff[] needs to big enough to hold the server_version variable */
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+32],*end;
int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB;
+
if (opt_using_transactions)
client_flags|=CLIENT_TRANSACTIONS;
#ifdef HAVE_COMPRESS
client_flags |= CLIENT_COMPRESS;
#endif /* HAVE_COMPRESS */
+#ifdef HAVE_OPENSSL
+ if (ssl_acceptor_fd)
+ client_flags |= CLIENT_SSL; /* Wow, SSL is avalaible! */
+#endif /* HAVE_OPENSSL */
- end=strmov(buff,server_version)+1;
+ end=strnmov(buff,server_version,SERVER_VERSION_LENGTH)+1;
int4store((uchar*) end,thd->thread_id);
end+=4;
memcpy(end,thd->scramble,SCRAMBLE_LENGTH+1);
end+=SCRAMBLE_LENGTH +1;
-#ifdef HAVE_OPENSSL
- if (ssl_acceptor_fd)
- client_flags |= CLIENT_SSL; /* Wow, SSL is avalaible! */
- /*
- * Without SSL the handshake consists of one packet. This packet
- * has both client capabilites and scrambled password.
- * With SSL the handshake might consist of two packets. If the first
- * packet (client capabilities) has CLIENT_SSL flag set, we have to
- * switch to SSL and read the second packet. The scrambled password
- * is in the second packet and client_capabilites field will be ignored.
- * Maybe it is better to accept flags other than CLIENT_SSL from the
- * second packet?
- */
-#define SSL_HANDSHAKE_SIZE 2
-#define NORMAL_HANDSHAKE_SIZE 6
-#define MIN_HANDSHAKE_SIZE 2
-
-#else
-#define MIN_HANDSHAKE_SIZE 6
-#endif /* HAVE_OPENSSL */
int2store(end,client_flags);
- end[2]=MY_CHARSET_CURRENT;
+ end[2]=(char) MY_CHARSET_CURRENT;
int2store(end+3,thd->server_status);
bzero(end+5,13);
end+=18;
- if (net_write_command(net,protocol_version, buff,
+ if (net_write_command(net,(uchar) protocol_version, buff,
(uint) (end-buff)) ||
- (pkt_len=my_net_read(net)) == packet_error ||
+ (pkt_len= my_net_read(net)) == packet_error ||
pkt_len < MIN_HANDSHAKE_SIZE)
{
inc_host_errors(&thd->remote.sin_addr);
@@ -417,30 +577,36 @@ check_connections(THD *thd)
#endif
if (connect_errors)
reset_host_errors(&thd->remote.sin_addr);
- if (thd->packet.alloc(net_buffer_length))
+ if (thd->packet.alloc(thd->variables.net_buffer_length))
return(ER_OUT_OF_RESOURCES);
thd->client_capabilities=uint2korr(net->read_pos);
if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
thd->sql_mode|= MODE_IGNORE_SPACE;
#ifdef HAVE_OPENSSL
- DBUG_PRINT("info",
- ("pkt_len:%d, client capabilities: %d",
- pkt_len, thd->client_capabilities) );
+ DBUG_PRINT("info", ("client capabilities: %d", thd->client_capabilities));
if (thd->client_capabilities & CLIENT_SSL)
{
- DBUG_PRINT("info", ("Agreed to change IO layer to SSL") );
/* Do the SSL layering. */
+ if (!ssl_acceptor_fd)
+ {
+ inc_host_errors(&thd->remote.sin_addr);
+ return(ER_HANDSHAKE_ERROR);
+ }
DBUG_PRINT("info", ("IO layer change in progress..."));
- VioSocket* vio_socket = my_reinterpret_cast(VioSocket*)(net->vio);
- VioSSL* vio_ssl = ssl_acceptor_fd->accept(vio_socket);
- net->vio = my_reinterpret_cast(NetVio*) (vio_ssl);
+ if (sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout))
+ {
+ DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
+ pkt_len));
+ inc_host_errors(&thd->remote.sin_addr);
+ return(ER_HANDSHAKE_ERROR);
+ }
DBUG_PRINT("info", ("Reading user information over SSL layer"));
if ((pkt_len=my_net_read(net)) == packet_error ||
pkt_len < NORMAL_HANDSHAKE_SIZE)
{
- DBUG_PRINT("info", ("pkt_len:%d", pkt_len));
- DBUG_PRINT("error", ("Failed to read user information"));
+ DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
+ pkt_len));
inc_host_errors(&thd->remote.sin_addr);
return(ER_HANDSHAKE_ERROR);
}
@@ -456,21 +622,20 @@ check_connections(THD *thd)
}
#endif
- thd->max_packet_length=uint3korr(net->read_pos+2);
+ thd->max_client_packet_length=uint3korr(net->read_pos+2);
char *user= (char*) net->read_pos+5;
char *passwd= strend(user)+1;
char *db=0;
if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
db=strend(passwd)+1;
if (thd->client_capabilities & CLIENT_INTERACTIVE)
- thd->inactive_timeout=net_interactive_timeout;
+ thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
opt_using_transactions)
thd->net.return_status= &thd->server_status;
- net->timeout=net_read_timeout;
+ net->read_timeout=(uint) thd->variables.net_read_timeout;
if (check_user(thd,COM_CONNECT, user, passwd, db, 1))
return (-1);
- thd->password=test(passwd[0]);
return 0;
}
@@ -485,31 +650,31 @@ pthread_handler_decl(handle_one_connection,arg)
pthread_detach_this_thread();
-#if !defined( __WIN__) && !defined(OS2) /* Win32 calls this in pthread_create */
- if (my_thread_init()) // needed to be called first before we call
- // DBUG_ macros
+#if !defined( __WIN__) && !defined(OS2) // Win32 calls this in pthread_create
+ // The following calls needs to be done before we call DBUG_ macros
+ if (!(test_flags & TEST_NO_THREADS) & my_thread_init())
{
close_connection(&thd->net,ER_OUT_OF_RESOURCES);
- statistic_increment(aborted_connects,&LOCK_thread_count);
+ statistic_increment(aborted_connects,&LOCK_status);
end_thread(thd,0);
return 0;
}
#endif
- // handle_one_connection() is the only way a thread would start
- // and would always be on top of the stack
- // therefore, the thread stack always starts at the address of the first
- // local variable of handle_one_connection, which is thd
- // we need to know the start of the stack so that we could check for
- // stack overruns
-
+ /*
+ handle_one_connection() is the only way a thread would start
+ and would always be on top of the stack, therefore, the thread
+ stack always starts at the address of the first local variable
+ of handle_one_connection, which is thd. We need to know the
+ start of the stack so that we could check for stack overruns.
+ */
DBUG_PRINT("info", ("handle_one_connection called by thread %d\n",
thd->thread_id));
// now that we've called my_thread_init(), it is safe to call DBUG_*
#if defined(__WIN__)
init_signals(); // IRENA; testing ?
-#elif !defined(OS2)
+#elif !defined(OS2) && !defined(__NETWARE__)
sigset_t set;
VOID(sigemptyset(&set)); // Get mask in use
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
@@ -517,7 +682,7 @@ pthread_handler_decl(handle_one_connection,arg)
if (thd->store_globals())
{
close_connection(&thd->net,ER_OUT_OF_RESOURCES);
- statistic_increment(aborted_connects,&LOCK_thread_count);
+ statistic_increment(aborted_connects,&LOCK_status);
end_thread(thd,0);
return 0;
}
@@ -526,24 +691,23 @@ pthread_handler_decl(handle_one_connection,arg)
{
int error;
NET *net= &thd->net;
-
- thd->mysys_var=my_thread_var;
- thd->dbug_thread_id=my_thread_id();
thd->thread_stack= (char*) &thd;
if ((error=check_connections(thd)))
{ // Wrong permissions
if (error > 0)
- net_printf(net,error,thd->host ? thd->host : (thd->ip ? thd->ip : ""));
+ net_printf(net,error,thd->host_or_ip);
#ifdef __NT__
if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
sleep(1); /* must wait after eof() */
#endif
- statistic_increment(aborted_connects,&LOCK_thread_count);
+ statistic_increment(aborted_connects,&LOCK_status);
goto end_thread;
}
-
- if (thd->max_join_size == HA_POS_ERROR)
+#ifdef __NETWARE__
+ netware_reg_user(thd->ip, thd->user, "MySQL");
+#endif
+ if (thd->variables.max_join_size == HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
if (thd->client_capabilities & CLIENT_COMPRESS)
net->compress=1; // Use compression
@@ -552,27 +716,37 @@ pthread_handler_decl(handle_one_connection,arg)
thd->command=COM_SLEEP;
thd->version=refresh_version;
thd->set_time();
- init_sql_alloc(&thd->mem_root,8192,8192);
+ init_sql_alloc(&thd->mem_root, thd->variables.query_alloc_block_size,
+ thd->variables.query_prealloc_size);
+ init_sql_alloc(&thd->transaction.mem_root,
+ thd->variables.trans_alloc_block_size,
+ thd->variables.trans_prealloc_size);
+
while (!net->error && net->vio != 0 && !thd->killed)
{
if (do_command(thd))
break;
}
+ if (thd->user_connect)
+ decrease_user_connections(thd->user_connect);
free_root(&thd->mem_root,MYF(0));
if (net->error && net->vio != 0)
{
- if (!thd->killed && opt_warnings)
- sql_print_error(ER(ER_NEW_ABORTING_CONNECTION),
- thd->thread_id,(thd->db ? thd->db : "unconnected"),
- thd->user ? thd->user : "unauthenticated",
- (thd->host ? thd->host : thd->ip ? thd->ip : "unknown"),
- (net->last_errno ? ER(net->last_errno) :
- ER(ER_UNKNOWN_ERROR)));
+ if (!thd->killed && thd->variables.log_warnings)
+ sql_print_error(ER(ER_NEW_ABORTING_CONNECTION),
+ thd->thread_id,(thd->db ? thd->db : "unconnected"),
+ thd->user ? thd->user : "unauthenticated",
+ thd->host_or_ip,
+ (net->last_errno ? ER(net->last_errno) :
+ ER(ER_UNKNOWN_ERROR)));
send_error(net,net->last_errno,NullS);
- thread_safe_increment(aborted_threads,&LOCK_thread_count);
+ statistic_increment(aborted_threads,&LOCK_status);
}
-
- decrease_user_connections(thd->user,thd->host);
+ else if (thd->killed)
+ {
+ statistic_increment(aborted_threads,&LOCK_status);
+ }
+
end_thread:
close_connection(net);
end_thread(thd,1);
@@ -591,7 +765,7 @@ end_thread:
Used when creating the initial grant tables
*/
-pthread_handler_decl(handle_bootstrap,arg)
+extern "C" pthread_handler_decl(handle_bootstrap,arg)
{
THD *thd=(THD*) arg;
FILE *file=bootstrap_file;
@@ -608,23 +782,25 @@ pthread_handler_decl(handle_bootstrap,arg)
pthread_detach_this_thread();
thd->thread_stack= (char*) &thd;
- thd->mysys_var=my_thread_var;
- thd->dbug_thread_id=my_thread_id();
-#if !defined(__WIN__) && !defined(OS2)
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
sigset_t set;
VOID(sigemptyset(&set)); // Get mask in use
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
#endif
- if (thd->max_join_size == (ulong) ~0L)
+ if (thd->variables.max_join_size == HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
thd->proc_info=0;
thd->version=refresh_version;
- thd->priv_user=thd->user=(char*)"boot";
+ thd->priv_user=thd->user=(char*) my_strdup("boot", MYF(MY_WME));
buff= (char*) thd->net.buff;
- init_sql_alloc(&thd->mem_root,8192,8192);
+ init_sql_alloc(&thd->mem_root, thd->variables.query_alloc_block_size,
+ thd->variables.query_prealloc_size);
+ init_sql_alloc(&thd->transaction.mem_root,
+ thd->variables.trans_alloc_block_size,
+ thd->variables.trans_prealloc_size);
while (fgets(buff, thd->net.max_packet, file))
{
uint length=(uint) strlen(buff);
@@ -632,22 +808,31 @@ pthread_handler_decl(handle_bootstrap,arg)
length--;
buff[length]=0;
thd->current_tablenr=0;
- thd->query= thd->memdup(buff,length+1);
+ thd->query_length=length;
+ thd->query= thd->memdup_w_gap(buff, length+1, thd->db_length+1);
+ thd->query[length] = '\0';
thd->query_id=query_id++;
+ if (mqh_used && thd->user_connect && check_mqh(thd, SQLCOM_END))
+ {
+ thd->net.error = 0;
+ close_thread_tables(thd); // Free tables
+ free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
+ break;
+ }
mysql_parse(thd,thd->query,length);
close_thread_tables(thd); // Free tables
if (thd->fatal_error)
break;
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
+ free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
}
- thd->priv_user=thd->user=0;
/* thd->fatal_error should be set in case something went wrong */
end:
(void) pthread_mutex_lock(&LOCK_thread_count);
thread_count--;
- (void) pthread_cond_broadcast(&COND_thread_count);
(void) pthread_mutex_unlock(&LOCK_thread_count);
+ (void) pthread_cond_broadcast(&COND_thread_count);
my_thread_end();
pthread_exit(0);
DBUG_RETURN(0); // Never reached
@@ -668,7 +853,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
int error = 0;
DBUG_ENTER("mysql_table_dump");
db = (db && db[0]) ? db : thd->db;
- if (!(table_list = (TABLE_LIST*) sql_calloc(sizeof(TABLE_LIST))))
+ if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
DBUG_RETURN(1); // out of memory
table_list->db = db;
table_list->real_name = table_list->alias = tbl_name;
@@ -687,12 +872,10 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT)))
DBUG_RETURN(1);
- if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege))
- goto err;
- if (grant_option && check_grant(thd, SELECT_ACL, table_list))
+ if (check_one_table_access(thd, SELECT_ACL, table_list, 0))
goto err;
-
thd->free_list = 0;
+ thd->query_length=(uint) strlen(tbl_name);
thd->query = tbl_name;
if ((error = mysqld_dump_create_info(thd, table, -1)))
{
@@ -700,14 +883,11 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
goto err;
}
net_flush(&thd->net);
- error = table->file->dump(thd,fd);
- if (error)
+ if ((error= table->file->dump(thd,fd)))
my_error(ER_GET_ERRNO, MYF(0));
err:
-
close_thread_tables(thd);
-
DBUG_RETURN(error);
}
@@ -717,67 +897,98 @@ err:
bool do_command(THD *thd)
{
char *packet;
- uint old_timeout,packet_length;
- bool error=0;
+ uint old_timeout;
+ ulong packet_length;
NET *net;
enum enum_server_command command;
- // commands which will always take a long time should be marked with
- // this so that they will not get logged to the slow query log
- bool slow_command=FALSE;
DBUG_ENTER("do_command");
net= &thd->net;
thd->current_tablenr=0;
packet=0;
- old_timeout=net->timeout;
- net->timeout=thd->inactive_timeout; /* Wait max for 8 hours */
+ old_timeout=net->read_timeout;
+ // Wait max for 8 hours
+ net->read_timeout=(uint) thd->variables.net_wait_timeout;
net->last_error[0]=0; // Clear error message
net->last_errno=0;
net_new_transaction(net);
if ((packet_length=my_net_read(net)) == packet_error)
{
- DBUG_PRINT("general",("Got error reading command from socket %s",
- vio_description(net->vio) ));
- return TRUE;
+ DBUG_PRINT("info",("Got error %d reading command from socket %s",
+ net->error,
+ vio_description(net->vio)));
+ /* Check if we can continue without closing the connection */
+ if (net->error != 3)
+ {
+ statistic_increment(aborted_threads,&LOCK_status);
+ DBUG_RETURN(TRUE); // We have to close it.
+ }
+ send_error(net,net->last_errno,NullS);
+ net->error= 0;
+ DBUG_RETURN(FALSE);
}
else
{
packet=(char*) net->read_pos;
command = (enum enum_server_command) (uchar) packet[0];
- DBUG_PRINT("general",("Command on %s = %d (%s)",
- vio_description(net->vio), command,
- command_name[command]));
- }
- net->timeout=old_timeout; /* Timeout */
+ if (command >= COM_END)
+ command= COM_END; // Wrong command
+ DBUG_PRINT("info",("Command on %s = %d (%s)",
+ vio_description(net->vio), command,
+ command_name[command]));
+ }
+ net->read_timeout=old_timeout; // restore it
+ DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
+}
+
+
+bool dispatch_command(enum enum_server_command command, THD *thd,
+ char* packet, uint packet_length)
+{
+ NET *net= &thd->net;
+ bool error=0;
+ /*
+ Commands which will always take a long time should be marked with
+ this so that they will not get logged to the slow query log
+ */
+ bool slow_command=FALSE;
+ DBUG_ENTER("dispatch_command");
+
thd->command=command;
+ thd->set_time();
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id=query_id;
if (command != COM_STATISTICS && command != COM_PING)
query_id++;
thread_running++;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->set_time();
- thd->lex.options=0; // We store status here
- switch(command) {
+
+ thd->lex.select_lex.options=0; // We store status here
+ switch (command) {
case COM_INIT_DB:
- thread_safe_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_thread_count);
- if (!mysql_change_db(thd,packet+1))
+ statistic_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_status);
+ if (!mysql_change_db(thd,packet))
mysql_log.write(thd,command,"%s",thd->db);
break;
+ case COM_REGISTER_SLAVE:
+ {
+ if (!register_slave(thd, (uchar*)packet, packet_length))
+ send_ok(&thd->net);
+ break;
+ }
case COM_TABLE_DUMP:
{
- thread_safe_increment(com_other,&LOCK_thread_count);
+ statistic_increment(com_other, &LOCK_status);
slow_command = TRUE;
- char* data = packet + 1;
- uint db_len = *(uchar *)data;
- uint tbl_len = *(uchar *)(data + db_len + 1);
- char* db = sql_alloc(db_len + tbl_len + 2);
- memcpy(db, data + 1, db_len);
+ uint db_len = *(uchar*)packet;
+ uint tbl_len = *(uchar*)(packet + db_len + 1);
+ char* db = thd->alloc(db_len + tbl_len + 2);
+ memcpy(db, packet + 1, db_len);
char* tbl_name = db + db_len;
*tbl_name++ = 0;
- memcpy(tbl_name, data + db_len + 2, tbl_len);
+ memcpy(tbl_name, packet + db_len + 2, tbl_len);
tbl_name[tbl_len] = 0;
if (mysql_table_dump(thd, db, tbl_name, -1))
send_error(&thd->net); // dump to NET
@@ -785,65 +996,86 @@ bool do_command(THD *thd)
}
case COM_CHANGE_USER:
{
- thread_safe_increment(com_other,&LOCK_thread_count);
- char *user= (char*) packet+1;
+ thd->change_user();
+ clear_error_message(thd); // If errors from rollback
+
+ statistic_increment(com_other,&LOCK_status);
+ char *user= (char*) packet;
char *passwd= strend(user)+1;
char *db= strend(passwd)+1;
/* Save user and privileges */
uint save_master_access=thd->master_access;
uint save_db_access= thd->db_access;
+ uint save_db_length= thd->db_length;
char *save_user= thd->user;
char *save_priv_user= thd->priv_user;
char *save_db= thd->db;
- thd->user=0;
+ USER_CONN *save_user_connect= thd->user_connect;
if ((uint) ((uchar*) db - net->read_pos) > packet_length)
{ // Check if protocol is ok
send_error(net, ER_UNKNOWN_COM_ERROR);
break;
}
+
+ /* Clear variables that are allocated */
+ thd->user= 0;
+ thd->user_connect= 0;
if (check_user(thd, COM_CHANGE_USER, user, passwd, db, 0))
{ // Restore old user
x_free(thd->user);
thd->master_access=save_master_access;
thd->db_access=save_db_access;
thd->db=save_db;
+ thd->db_length=save_db_length;
thd->user=save_user;
thd->priv_user=save_priv_user;
+ thd->user_connect= save_user_connect;
break;
}
- decrease_user_connections (save_user, thd->host);
+ if (save_user_connect)
+ decrease_user_connections(save_user_connect);
x_free((gptr) save_db);
x_free((gptr) save_user);
- thd->password=test(passwd[0]);
break;
}
case COM_QUERY:
{
+ packet_length--; // Remove end null
+ /* Remove garage at start and end of query */
+ while (isspace(packet[0]) && packet_length > 0)
+ {
+ packet++;
+ packet_length--;
+ }
char *pos=packet+packet_length; // Point at end null
- /* Remove garage at end of query */
- while (packet_length > 0 && pos[-1] == ';')
+ while (packet_length > 0 && (pos[-1] == ';' || isspace(pos[-1])))
{
pos--;
packet_length--;
}
- *pos=0;
- if (!(thd->query= (char*) thd->memdup((gptr) (packet+1),packet_length)))
+ /* We must allocate some extra memory for query cache */
+ if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet),
+ packet_length,
+ thd->db_length+2+
+ sizeof(ha_rows))))
break;
- thd->packet.shrink(net_buffer_length); // Reclaim some memory
+ thd->query[packet_length]=0;
+ thd->packet.shrink(thd->variables.net_buffer_length);// Reclaim some memory
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
mysql_log.write(thd,command,"%s",thd->query);
- DBUG_PRINT("query",("%s",thd->query));
- mysql_parse(thd,thd->query,packet_length-1);
+ DBUG_PRINT("query",("%-.4096s",thd->query));
+ /* thd->query_length is set by mysql_parse() */
+ mysql_parse(thd,thd->query,packet_length);
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),WAIT_PRIOR);
DBUG_PRINT("info",("query ready"));
break;
}
- case COM_FIELD_LIST: // This isn't actually neaded
+ case COM_FIELD_LIST: // This isn't actually needed
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
break;
@@ -851,7 +1083,7 @@ bool do_command(THD *thd)
{
char *fields;
TABLE_LIST table_list;
- thread_safe_increment(com_stat[SQLCOM_SHOW_FIELDS],&LOCK_thread_count);
+ statistic_increment(com_stat[SQLCOM_SHOW_FIELDS],&LOCK_status);
bzero((char*) &table_list,sizeof(table_list));
if (!(table_list.db=thd->db))
{
@@ -859,16 +1091,18 @@ bool do_command(THD *thd)
break;
}
thd->free_list=0;
- table_list.alias= table_list.real_name= thd->strdup(packet+1);
- thd->query=fields=thd->strdup(strend(packet+1)+1);
+ table_list.alias= table_list.real_name= thd->strdup(packet);
+ packet=strend(packet)+1;
+ // command not cachable => no gap for data base name
+ if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1)))
+ break;
mysql_log.write(thd,command,"%s %s",table_list.real_name,fields);
if (lower_case_table_names)
casedn_str(table_list.real_name);
remove_escape(table_list.real_name); // This can't have wildcards
- if (check_access(thd,SELECT_ACL,table_list.db,&thd->col_access))
+ if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege))
break;
- table_list.grant.privilege=thd->col_access;
if (grant_option && check_grant(thd,SELECT_ACL,&table_list,2))
break;
mysqld_list_fields(thd,&table_list,fields);
@@ -883,57 +1117,66 @@ bool do_command(THD *thd)
error=TRUE; // End server
break;
- case COM_CREATE_DB:
+ case COM_CREATE_DB: // QQ: To be removed
{
- char *db=thd->strdup(packet+1);
- thread_safe_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_thread_count);
+ char *db=thd->strdup(packet), *alias;
+
+ statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status);
// null test to handle EOM
- if (!db || !strip_sp(db) || check_db_name(db))
+ if (!db || !strip_sp(db) || !(alias= thd->strdup(db)) ||
+ check_db_name(db))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
break;
}
if (check_access(thd,CREATE_ACL,db,0,1))
break;
- mysql_log.write(thd,command,packet+1);
- mysql_create_db(thd,db,0);
+ mysql_log.write(thd,command,packet);
+ mysql_create_db(thd,(lower_case_table_names == 2 ? alias : db),0,0);
break;
}
- case COM_DROP_DB:
+ case COM_DROP_DB: // QQ: To be removed
{
- char *db=thd->strdup(packet+1);
- thread_safe_increment(com_stat[SQLCOM_DROP_DB],&LOCK_thread_count);
+ statistic_increment(com_stat[SQLCOM_DROP_DB],&LOCK_status);
+ char *db=thd->strdup(packet), *alias;
// null test to handle EOM
- if (!db || !strip_sp(db) || check_db_name(db))
+ if (!db || !strip_sp(db) || !(alias= thd->strdup(db)) ||
+ check_db_name(db))
{
net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
break;
}
- if (check_access(thd,DROP_ACL,db,0,1) || end_active_trans(thd))
+ if (check_access(thd,DROP_ACL,db,0,1))
break;
+ if (thd->locked_tables || thd->active_transaction())
+ {
+ send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
+ break;
+ }
mysql_log.write(thd,command,db);
- mysql_rm_db(thd,db,0);
+ mysql_rm_db(thd,alias,0,0);
break;
}
case COM_BINLOG_DUMP:
{
- thread_safe_increment(com_other,&LOCK_thread_count);
+ statistic_increment(com_other,&LOCK_status);
slow_command = TRUE;
- if(check_access(thd, FILE_ACL, any_db))
+ if (check_global_access(thd, REPL_SLAVE_ACL))
break;
mysql_log.write(thd,command, 0);
ulong pos;
ushort flags;
uint32 slave_server_id;
- pos = uint4korr(packet + 1);
- flags = uint2korr(packet + 5);
- pthread_mutex_lock(&LOCK_server_id);
- if ((slave_server_id = uint4korr(packet+7)))
+ /* TODO: The following has to be changed to an 8 byte integer */
+ pos = uint4korr(packet);
+ flags = uint2korr(packet + 4);
+ thd->server_id=0; /* avoid suicide */
+ if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
kill_zombie_dump_threads(slave_server_id);
thd->server_id = slave_server_id;
- pthread_mutex_unlock(&LOCK_server_id);
- mysql_binlog_send(thd, thd->strdup(packet + 11), pos, flags);
+ mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
+ unregister_slave(thd,1,1);
// fake COM_QUIT -- if we get here, the thread needs to terminate
error = TRUE;
net->error = 0;
@@ -941,20 +1184,18 @@ bool do_command(THD *thd)
}
case COM_REFRESH:
{
- uint options=(uchar) packet[1];
- thread_safe_increment(com_stat[SQLCOM_FLUSH],&LOCK_thread_count);
- if (check_access(thd,RELOAD_ACL,any_db))
+ statistic_increment(com_stat[SQLCOM_FLUSH],&LOCK_status);
+ ulong options= (ulong) (uchar) packet[0];
+ if (check_global_access(thd,RELOAD_ACL))
break;
mysql_log.write(thd,command,NullS);
- if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0))
- send_error(net,0);
- else
- send_eof(net);
+ /* error sending is deferred to reload_acl_and_cache */
+ reload_acl_and_cache(thd, options, (TABLE_LIST*) 0) ;
break;
}
case COM_SHUTDOWN:
- thread_safe_increment(com_other,&LOCK_thread_count);
- if (check_access(thd,SHUTDOWN_ACL,any_db))
+ statistic_increment(com_other,&LOCK_status);
+ if (check_global_access(thd,SHUTDOWN_ACL))
break; /* purecov: inspected */
DBUG_PRINT("quit",("Got shutdown command"));
mysql_log.write(thd,command,NullS);
@@ -968,6 +1209,7 @@ bool do_command(THD *thd)
close_connection(net);
close_thread_tables(thd); // Free before kill
free_root(&thd->mem_root,MYF(0));
+ free_root(&thd->transaction.mem_root,MYF(0));
kill_mysql();
error=TRUE;
break;
@@ -975,31 +1217,32 @@ bool do_command(THD *thd)
case COM_STATISTICS:
{
mysql_log.write(thd,command,NullS);
- thread_safe_increment(com_stat[SQLCOM_SHOW_STATUS],&LOCK_thread_count);
+ statistic_increment(com_stat[SQLCOM_SHOW_STATUS],&LOCK_status);
char buff[200];
ulong uptime = (ulong) (thd->start_time - start_time);
sprintf((char*) buff,
- "Uptime: %ld Threads: %d Questions: %lu Slow queries: %ld Opens: %ld Flush tables: %ld Open tables: %d Queries per second avg: %.3f",
+ "Uptime: %ld Threads: %d Questions: %lu Slow queries: %ld Opens: %ld Flush tables: %ld Open tables: %u Queries per second avg: %.3f",
uptime,
(int) thread_count,thd->query_id,long_query_count,
opened_tables,refresh_version, cached_tables(),
uptime ? (float)thd->query_id/(float)uptime : 0);
#ifdef SAFEMALLOC
- if (lCurMemory) // Using SAFEMALLOC
+ if (sf_malloc_cur_memory) // Using SAFEMALLOC
sprintf(strend(buff), " Memory in use: %ldK Max memory used: %ldK",
- (lCurMemory+1023L)/1024L,(lMaxMemory+1023L)/1024L);
+ (sf_malloc_cur_memory+1023L)/1024L,
+ (sf_malloc_max_memory+1023L)/1024L);
#endif
VOID(my_net_write(net, buff,(uint) strlen(buff)));
VOID(net_flush(net));
break;
}
case COM_PING:
- thread_safe_increment(com_other,&LOCK_thread_count);
+ statistic_increment(com_other,&LOCK_status);
send_ok(net); // Tell client we are alive
break;
case COM_PROCESS_INFO:
- thread_safe_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_thread_count);
- if (!thd->priv_user[0] && check_process_priv(thd))
+ statistic_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_status);
+ if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
break;
mysql_log.write(thd,command,NullS);
mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS :
@@ -1007,14 +1250,14 @@ bool do_command(THD *thd)
break;
case COM_PROCESS_KILL:
{
- thread_safe_increment(com_stat[SQLCOM_KILL],&LOCK_thread_count);
- ulong id=(ulong) uint4korr(packet+1);
+ statistic_increment(com_stat[SQLCOM_KILL],&LOCK_status);
+ ulong id=(ulong) uint4korr(packet);
kill_one_thread(thd,id);
break;
}
case COM_DEBUG:
- thread_safe_increment(com_other,&LOCK_thread_count);
- if (check_process_priv(thd))
+ statistic_increment(com_other,&LOCK_status);
+ if (check_global_access(thd, SUPER_ACL))
break; /* purecov: inspected */
mysql_print_status(thd);
mysql_log.write(thd,command,NullS);
@@ -1024,6 +1267,7 @@ bool do_command(THD *thd)
case COM_CONNECT: // Impossible here
case COM_TIME: // Impossible from client
case COM_DELAYED_INSERT:
+ case COM_END:
default:
send_error(net, ER_UNKNOWN_COM_ERROR);
break;
@@ -1045,8 +1289,9 @@ bool do_command(THD *thd)
{
thd->proc_info="logging slow query";
- if ((ulong) (thd->start_time - thd->time_after_lock) > long_query_time ||
- ((thd->lex.options &
+ if ((ulong) (thd->start_time - thd->time_after_lock) >
+ thd->variables.long_query_time ||
+ ((thd->lex.select_lex.options &
(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED)) &&
(specialflag & SPECIAL_LONG_LOG_FORMAT)))
{
@@ -1061,7 +1306,7 @@ bool do_command(THD *thd)
thd->query=0;
thread_running--;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->packet.shrink(net_buffer_length); // Reclaim some memory
+ thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
DBUG_RETURN(error);
}
@@ -1077,45 +1322,61 @@ mysql_execute_command(void)
int res=0;
THD *thd=current_thd;
LEX *lex= &thd->lex;
- TABLE_LIST *tables=(TABLE_LIST*) lex->table_list.first;
+ TABLE_LIST *tables=(TABLE_LIST*) lex->select_lex.table_list.first;
+ SELECT_LEX *select_lex = lex->select;
DBUG_ENTER("mysql_execute_command");
if (thd->slave_thread)
{
- // skip if we are in the slave thread, some table
- // rules have been given and the table list says the query should not be
- // replicated
- if(table_rules_on && tables && !tables_ok(thd,tables))
- {
- /*
- We consider the query as empty and warn the slave thread which will
- consider ER_EMPTY_QUERY as an ignorable error. Note that this has a
- drawback: if the event is corrupted it could contain an empty query;
- then the slave thread will silently ignore it instead of warning. But
- such corruption is unlikely enough.
- In MySQL 4.0 we do it more properly using a new error code
- (ER_SLAVE_IGNORED_TABLE).
- */
- my_error(ER_EMPTY_QUERY, MYF(0));
+ /*
+ Skip if we are in the slave thread, some table rules have been
+ given and the table list says the query should not be replicated
+ */
+ if (table_rules_on && tables && !tables_ok(thd,tables) &&
+ ((lex->sql_command != SQLCOM_DELETE_MULTI) ||
+ !tables_ok(thd,(TABLE_LIST *)thd->lex.auxilliary_table_list.first)))
+ {
+ /* we warn the slave SQL thread */
+ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
DBUG_VOID_RETURN;
}
- // this is a workaround to deal with the shortcoming
- // in 3.23.44-3.23.46 masters
- // in RELEASE_LOCK() logging. We re-write SELECT RELEASE_LOCK() as
- // DO RELEASE_LOCK()
+#ifndef TO_BE_DELETED
+ /*
+ This is a workaround to deal with the shortcoming in 3.23.44-3.23.46
+ masters in RELEASE_LOCK() logging. We re-write SELECT RELEASE_LOCK()
+ as DO RELEASE_LOCK()
+ */
if (lex->sql_command == SQLCOM_SELECT)
{
lex->sql_command = SQLCOM_DO;
- lex->insert_list = &lex->item_list;
+ lex->insert_list = &select_lex->item_list;
}
+#endif
}
- thread_safe_increment(com_stat[lex->sql_command],&LOCK_thread_count);
+ if (lex->select_lex.next &&
+ create_total_list(thd,lex,&tables,
+ (lex->sql_command == SQLCOM_CREATE_TABLE)))
+ DBUG_VOID_RETURN;
+
+ /*
+ When option readonly is set deny operations which change tables.
+ Except for the replication thread and the 'super' users.
+ */
+ if (opt_readonly &&
+ !(thd->slave_thread || (thd->master_access & SUPER_ACL)) &&
+ (uc_update_queries[lex->sql_command] > 0))
+ {
+ send_error(&thd->net,ER_CANT_UPDATE_WITH_READLOCK);
+ DBUG_VOID_RETURN;
+ }
+
+ statistic_increment(com_stat[lex->sql_command],&LOCK_status);
switch (lex->sql_command) {
case SQLCOM_SELECT:
{
select_result *result;
- if (lex->options & SELECT_DESCRIBE)
+ if (select_lex->options & SELECT_DESCRIBE)
lex->exchange=0;
if (tables)
{
@@ -1133,10 +1394,12 @@ mysql_execute_command(void)
break; // Error message is given
}
- thd->offset_limit=lex->offset_limit;
- thd->select_limit=lex->select_limit+lex->offset_limit;
- if (thd->select_limit < lex->select_limit)
+ thd->offset_limit=select_lex->offset_limit;
+ thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
+ if (thd->select_limit < select_lex->select_limit)
thd->select_limit= HA_POS_ERROR; // no limit
+ if (thd->select_limit == HA_POS_ERROR)
+ select_lex->options&= ~OPTION_FOUND_ROWS;
if (lex->exchange)
{
@@ -1161,8 +1424,8 @@ mysql_execute_command(void)
{
res= -1;
#ifdef DELETE_ITEMS
- delete lex->having;
- delete lex->where;
+ delete select_lex->having;
+ delete select_lex->where;
#endif
break;
}
@@ -1172,6 +1435,8 @@ mysql_execute_command(void)
Normal select:
Change lock if we are using SELECT HIGH PRIORITY,
FOR UPDATE or IN SHARE MODE
+
+ TODO: Delete the following loop when locks is set by sql_yacc
*/
TABLE_LIST *table;
for (table = tables ; table ; table=table->next)
@@ -1180,22 +1445,11 @@ mysql_execute_command(void)
if (!(res=open_and_lock_tables(thd,tables)))
{
- res=mysql_select(thd,tables,lex->item_list,
- lex->where,
- (ORDER*) lex->order_list.first,
- (ORDER*) lex->group_list.first,
- lex->having,
- (ORDER*) lex->proc_list.first,
- lex->options | thd->options,
- result);
- if (res)
- result->abort();
+ query_cache_store_query(thd, tables);
+ res=handle_select(thd, lex, result);
}
- delete result;
-#ifdef DELETE_ITEMS
- delete lex->having;
- delete lex->where;
-#endif
+ else
+ delete result;
break;
}
case SQLCOM_DO:
@@ -1207,63 +1461,112 @@ mysql_execute_command(void)
break;
case SQLCOM_PURGE:
- {
- if (check_process_priv(thd))
- goto error;
- res = purge_master_logs(thd, lex->to_log);
- break;
- }
+ {
+ if (check_global_access(thd, SUPER_ACL))
+ goto error;
+ res = purge_master_logs(thd, lex->to_log);
+ break;
+ }
+ case SQLCOM_SHOW_NEW_MASTER:
+ {
+ if (check_global_access(thd, REPL_SLAVE_ACL))
+ goto error;
+ /* This query don't work now. See comment in repl_failsafe.cc */
+#ifndef WORKING_NEW_MASTER
+ net_printf(&thd->net, ER_NOT_SUPPORTED_YET, "SHOW NEW MASTER");
+ res= 1;
+#else
+ res = show_new_master(thd);
+#endif
+ break;
+ }
+ case SQLCOM_SHOW_SLAVE_HOSTS:
+ {
+ if (check_global_access(thd, REPL_SLAVE_ACL))
+ goto error;
+ res = show_slave_hosts(thd);
+ break;
+ }
+ case SQLCOM_SHOW_BINLOG_EVENTS:
+ {
+ if (check_global_access(thd, REPL_SLAVE_ACL))
+ goto error;
+ res = show_binlog_events(thd);
+ break;
+ }
case SQLCOM_BACKUP_TABLE:
- {
- if (check_db_used(thd,tables) ||
- check_table_access(thd,SELECT_ACL, tables) ||
- check_access(thd, FILE_ACL, any_db))
- goto error; /* purecov: inspected */
- res = mysql_backup_table(thd, tables);
+ {
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd,SELECT_ACL, tables) ||
+ check_global_access(thd, FILE_ACL))
+ goto error; /* purecov: inspected */
+ res = mysql_backup_table(thd, tables);
- break;
- }
+ break;
+ }
case SQLCOM_RESTORE_TABLE:
- {
- if (check_db_used(thd,tables) ||
- check_table_access(thd,INSERT_ACL, tables) ||
- check_access(thd, FILE_ACL, any_db))
- goto error; /* purecov: inspected */
- res = mysql_restore_table(thd, tables);
- break;
- }
+ {
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd, INSERT_ACL, tables) ||
+ check_global_access(thd, FILE_ACL))
+ goto error; /* purecov: inspected */
+ res = mysql_restore_table(thd, tables);
+ break;
+ }
+
+#ifdef HAVE_REPLICATION
case SQLCOM_CHANGE_MASTER:
- {
- if(check_access(thd, PROCESS_ACL, any_db))
- goto error;
- res = change_master(thd);
- break;
- }
+ {
+ if (check_global_access(thd, SUPER_ACL))
+ goto error;
+ LOCK_ACTIVE_MI;
+ res = change_master(thd,active_mi);
+ UNLOCK_ACTIVE_MI;
+ break;
+ }
case SQLCOM_SHOW_SLAVE_STAT:
- {
- if (check_process_priv(thd))
- goto error;
- res = show_master_info(thd);
- break;
- }
+ {
+ /* Accept one of two privileges */
+ if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
+ goto error;
+ LOCK_ACTIVE_MI;
+ res = show_master_info(thd,active_mi);
+ UNLOCK_ACTIVE_MI;
+ break;
+ }
case SQLCOM_SHOW_MASTER_STAT:
- {
- if (check_process_priv(thd))
- goto error;
- res = show_binlog_info(thd);
- break;
- }
+ {
+ /* Accept one of two privileges */
+ if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
+ goto error;
+ res = show_binlog_info(thd);
+ break;
+ }
+
+ case SQLCOM_LOAD_MASTER_DATA: // sync with master
+ if (check_global_access(thd, SUPER_ACL))
+ goto error;
+ if (end_active_trans(thd))
+ res= -1;
+ else
+ res = load_master_data(thd);
+ break;
+
+#endif /* HAVE_REPLICATION */
+
#ifdef HAVE_INNOBASE_DB
case SQLCOM_SHOW_INNODB_STATUS:
{
- if (check_process_priv(thd))
+ if (check_global_access(thd, SUPER_ACL))
goto error;
res = innodb_show_status(thd);
break;
}
#endif
- case SQLCOM_LOAD_MASTER_TABLE:
+#ifdef HAVE_REPLICATION
+ case SQLCOM_LOAD_MASTER_TABLE:
+ {
if (!tables->db)
tables->db=thd->db;
if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege))
@@ -1276,51 +1579,70 @@ mysql_execute_command(void)
bool error=check_grant(thd,CREATE_ACL,tables);
tables->next=tmp_table_list;
if (error)
- goto error;
+ goto error;
}
- if (strlen(tables->real_name) > NAME_LEN)
+ LOCK_ACTIVE_MI;
+ /*
+ fetch_master_table will send the error to the client on failure.
+ Give error if the table already exists.
+ */
+ if (!fetch_master_table(thd, tables->db, tables->real_name,
+ active_mi, 0, 0))
{
- net_printf(&thd->net,ER_WRONG_TABLE_NAME,tables->real_name);
- break;
+ send_ok(&thd->net);
}
-
- thd->last_nx_table = tables->real_name;
- thd->last_nx_db = tables->db;
- if (fetch_nx_table(thd, &glob_mi))
- break; // fetch_nx_table did send the error to the client
- send_ok(&thd->net);
+ UNLOCK_ACTIVE_MI;
break;
+ }
+#endif /* HAVE_REPLICATION */
case SQLCOM_CREATE_TABLE:
+ {
+ ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
+ CREATE_TMP_ACL : CREATE_ACL);
if (!tables->db)
tables->db=thd->db;
- if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege) ||
+ lex->create_info.alias= tables->alias;
+ if (check_access(thd,want_priv,tables->db,&tables->grant.privilege) ||
check_merge_table_access(thd, tables->db,
(TABLE_LIST *)
lex->create_info.merge_list.first))
goto error; /* purecov: inspected */
- if (grant_option)
+ if (grant_option && want_priv != CREATE_TMP_ACL)
{
/* Check that the first table has CREATE privilege */
TABLE_LIST *tmp_table_list=tables->next;
tables->next=0;
- bool error=check_grant(thd,CREATE_ACL,tables);
+ bool error=check_grant(thd, want_priv, tables);
tables->next=tmp_table_list;
if (error)
goto error;
}
if (strlen(tables->real_name) > NAME_LEN)
{
- net_printf(&thd->net,ER_WRONG_TABLE_NAME,tables->real_name);
+ net_printf(&thd->net, ER_WRONG_TABLE_NAME, tables->alias);
res=0;
break;
}
- if (lex->item_list.elements) // With select
+#ifndef HAVE_READLINK
+ lex->create_info.data_file_name=lex->create_info.index_file_name=0;
+#else
+ /* Fix names if symlinked tables */
+ if (append_file_to_dir(thd, &lex->create_info.data_file_name,
+ tables->real_name) ||
+ append_file_to_dir(thd,&lex->create_info.index_file_name,
+ tables->real_name))
+ {
+ res=-1;
+ break;
+ }
+#endif
+ if (select_lex->item_list.elements) // With select
{
select_result *result;
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
- check_dup(thd,tables->db,tables->real_name,tables->next))
+ check_dup(tables->db, tables->real_name, tables->next))
{
net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
DBUG_VOID_RETURN;
@@ -1330,34 +1652,28 @@ mysql_execute_command(void)
TABLE_LIST *table;
if (check_table_access(thd, SELECT_ACL, tables->next))
goto error; // Error message is given
+ /* TODO: Delete the following loop when locks is set by sql_yacc */
for (table = tables->next ; table ; table=table->next)
table->lock_type= lex->lock_option;
}
- thd->offset_limit=lex->offset_limit;
- thd->select_limit=lex->select_limit+lex->offset_limit;
- if (thd->select_limit < lex->select_limit)
+ select_lex->options|= SELECT_NO_UNLOCK;
+ thd->offset_limit=select_lex->offset_limit;
+ thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
+ if (thd->select_limit < select_lex->select_limit)
thd->select_limit= HA_POS_ERROR; // No limit
+ /* Skip first table, which is the table we are creating */
+ lex->select_lex.table_list.first=
+ (byte*) (((TABLE_LIST *) lex->select_lex.table_list.first)->next);
if (!(res=open_and_lock_tables(thd,tables->next)))
{
- if ((result=new select_create(tables->db ? tables->db : thd->db,
- tables->real_name, &lex->create_info,
- lex->create_list,
- lex->key_list,
- lex->item_list,lex->duplicates)))
- {
- res=mysql_select(thd,tables->next,lex->item_list,
- lex->where,
- (ORDER*) lex->order_list.first,
- (ORDER*) lex->group_list.first,
- lex->having,
- (ORDER*) lex->proc_list.first,
- lex->options | thd->options,
- result);
- if (res)
- result->abort();
- delete result;
- }
+ if ((result=new select_create(tables->db ? tables->db : thd->db,
+ tables->real_name,
+ &lex->create_info,
+ lex->create_list,
+ lex->key_list,
+ select_lex->item_list,lex->duplicates)))
+ res=handle_select(thd, lex, result);
else
res= -1;
}
@@ -1365,50 +1681,58 @@ mysql_execute_command(void)
else // regular create
{
res = mysql_create_table(thd,tables->db ? tables->db : thd->db,
- tables->real_name, &lex->create_info,
+ tables->real_name,
+ &lex->create_info,
lex->create_list,
lex->key_list,0, 0); // do logging
if (!res)
send_ok(&thd->net);
}
break;
+ }
case SQLCOM_CREATE_INDEX:
- if (!tables->db)
- tables->db=thd->db;
- if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege))
+ if (check_one_table_access(thd, INDEX_ACL, tables, 0))
goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,INDEX_ACL,tables))
- goto error;
if (end_active_trans(thd))
res= -1;
else
res = mysql_create_index(thd, tables, lex->key_list);
break;
+#ifdef HAVE_REPLICATION
case SQLCOM_SLAVE_START:
- start_slave(thd);
+ {
+ LOCK_ACTIVE_MI;
+ start_slave(thd,active_mi,1 /* net report*/);
+ UNLOCK_ACTIVE_MI;
break;
+ }
case SQLCOM_SLAVE_STOP:
- /*
- if the client thread has locked tables, a deadlock is possible.
- Assume that
- - the client thread does LOCK TABLE t READ.
- - then the master updates t.
- - then the SQL slave thread wants to update t,
+ /*
+ If the client thread has locked tables, a deadlock is possible.
+ Assume that
+ - the client thread does LOCK TABLE t READ.
+ - then the master updates t.
+ - then the SQL slave thread wants to update t,
so it waits for the client thread because t is locked by it.
- - then the client thread does SLAVE STOP.
+ - then the client thread does SLAVE STOP.
SLAVE STOP waits for the SQL slave thread to terminate its
update t, which waits for the client thread because t is locked by it.
- To prevent that, refuse SLAVE STOP if the
- client thread has locked tables
- */
- if (thd->locked_tables || thd->active_transaction())
- {
- send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
- break;
- }
- stop_slave(thd);
+ To prevent that, refuse SLAVE STOP if the
+ client thread has locked tables
+ */
+ if (thd->locked_tables || thd->active_transaction())
+ {
+ send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
+ break;
+ }
+ {
+ LOCK_ACTIVE_MI;
+ stop_slave(thd,active_mi,1/* net report*/);
+ UNLOCK_ACTIVE_MI;
break;
+ }
+#endif /* HAVE_REPLICATION */
case SQLCOM_ALTER_TABLE:
#if defined(DONT_ALLOW_SHOW_COMMANDS)
@@ -1416,25 +1740,21 @@ mysql_execute_command(void)
break;
#else
{
- uint priv=0;
- if (lex->name && strlen(lex->name) > NAME_LEN)
+ ulong priv=0;
+ if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
{
net_printf(&thd->net,ER_WRONG_TABLE_NAME,lex->name);
res=0;
break;
}
- if (!tables->db)
- tables->db=thd->db;
- if (!lex->db)
- lex->db=tables->db;
+ if (!select_lex->db)
+ select_lex->db=tables->db;
if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) ||
- check_access(thd,INSERT_ACL | CREATE_ACL,lex->db,&priv) ||
+ check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv) ||
check_merge_table_access(thd, tables->db,
(TABLE_LIST *)
lex->create_info.merge_list.first))
goto error; /* purecov: inspected */
- if (!tables->db)
- tables->db=thd->db;
if (grant_option)
{
if (check_grant(thd,ALTER_ACL,tables))
@@ -1444,22 +1764,27 @@ mysql_execute_command(void)
TABLE_LIST tmp_table;
bzero((char*) &tmp_table,sizeof(tmp_table));
tmp_table.real_name=lex->name;
- tmp_table.db=lex->db;
+ tmp_table.db=select_lex->db;
tmp_table.grant.privilege=priv;
if (check_grant(thd,INSERT_ACL | CREATE_ACL,tables))
goto error;
}
}
+ /* Don't yet allow changing of symlinks with ALTER TABLE */
+ lex->create_info.data_file_name=lex->create_info.index_file_name=0;
/* ALTER TABLE ends previous transaction */
if (end_active_trans(thd))
res= -1;
else
- res= mysql_alter_table(thd, lex->db, lex->name,
+ {
+ res= mysql_alter_table(thd, select_lex->db, lex->name,
&lex->create_info,
tables, lex->create_list,
lex->key_list, lex->drop_list, lex->alter_list,
- (ORDER *) lex->order_list.first,
- lex->drop_primary, lex->duplicates);
+ (ORDER *) select_lex->order_list.first,
+ lex->drop_primary, lex->duplicates,
+ lex->alter_keys_onoff, lex->simple_alter);
+ }
break;
}
#endif
@@ -1483,11 +1808,12 @@ mysql_execute_command(void)
old_list.next=new_list.next=0;
if (check_grant(thd,ALTER_ACL,&old_list) ||
(!test_all_bits(table->next->grant.privilege,
- INSERT_ACL | CREATE_ACL) &&
+ INSERT_ACL | CREATE_ACL) &&
check_grant(thd,INSERT_ACL | CREATE_ACL, &new_list)))
goto error;
}
}
+ query_cache_invalidate3(thd, tables, 0);
if (end_active_trans(thd))
res= -1;
else if (mysql_rename_tables(thd,tables))
@@ -1500,7 +1826,7 @@ mysql_execute_command(void)
DBUG_VOID_RETURN;
#else
{
- if (check_process_priv(thd))
+ if (check_global_access(thd, SUPER_ACL))
goto error;
res = show_binlogs(thd);
break;
@@ -1521,21 +1847,21 @@ mysql_execute_command(void)
}
#endif
case SQLCOM_REPAIR:
- {
- if (check_db_used(thd,tables) ||
- check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
- goto error; /* purecov: inspected */
- res = mysql_repair_table(thd, tables, &lex->check_opt);
- break;
- }
+ {
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
+ goto error; /* purecov: inspected */
+ res = mysql_repair_table(thd, tables, &lex->check_opt);
+ break;
+ }
case SQLCOM_CHECK:
- {
- if (check_db_used(thd,tables) ||
- check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables))
- goto error; /* purecov: inspected */
- res = mysql_check_table(thd, tables, &lex->check_opt);
- break;
- }
+ {
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables))
+ goto error; /* purecov: inspected */
+ res = mysql_check_table(thd, tables, &lex->check_opt);
+ break;
+ }
case SQLCOM_ANALYZE:
{
if (check_db_used(thd,tables) ||
@@ -1573,146 +1899,248 @@ mysql_execute_command(void)
break;
}
case SQLCOM_UPDATE:
- if (check_access(thd,UPDATE_ACL,tables->db,&tables->grant.privilege))
- goto error;
- if (grant_option && check_grant(thd,UPDATE_ACL,tables))
+ if (check_db_used(thd,tables))
goto error;
- if (lex->item_list.elements != lex->value_list.elements)
+ if (select_lex->item_list.elements != lex->value_list.elements)
{
send_error(&thd->net,ER_WRONG_VALUE_COUNT);
DBUG_VOID_RETURN;
}
- res = mysql_update(thd,tables,
- lex->item_list,
- lex->value_list,
- lex->where,
- lex->select_limit,
- lex->duplicates,
- lex->lock_option);
+ if (select_lex->table_list.elements == 1)
+ {
+ if (check_one_table_access(thd, UPDATE_ACL, tables, 0))
+ goto error; /* purecov: inspected */
-#ifdef DELETE_ITEMS
- delete lex->where;
-#endif
+
+ res= mysql_update(thd,tables,
+ select_lex->item_list,
+ lex->value_list,
+ select_lex->where,
+ (ORDER *) select_lex->order_list.first,
+ select_lex->select_limit,
+ lex->duplicates);
+ }
+ else
+ {
+ const char *msg= 0;
+ TABLE_LIST *table;
+ lex->sql_command= SQLCOM_MULTI_UPDATE;
+
+ /*
+ Ensure that we have UPDATE or SELECT privilege for each table
+ The exact privilege is checked in mysql_multi_update()
+ */
+ for (table= tables ; table ; table= table->next)
+ {
+ TABLE_LIST *save= table->next;
+ table->next= 0;
+ if (check_one_table_access(thd, UPDATE_ACL, table, 1) &&
+ check_one_table_access(thd, SELECT_ACL, table, 0))
+ goto error;
+ table->next= save;
+ }
+ if (select_lex->order_list.elements)
+ msg="ORDER BY";
+ else if (select_lex->select_limit && select_lex->select_limit !=
+ HA_POS_ERROR)
+ msg="LIMIT";
+ if (msg)
+ {
+ net_printf(&thd->net, ER_WRONG_USAGE, "UPDATE", msg);
+ res= 1;
+ break;
+ }
+ res= mysql_multi_update(thd,tables,
+ &select_lex->item_list,
+ &lex->value_list,
+ select_lex->where,
+ select_lex->options,
+ lex->duplicates);
+ }
break;
case SQLCOM_INSERT:
- if (check_access(thd,INSERT_ACL,tables->db,&tables->grant.privilege))
+ if (check_one_table_access(thd, INSERT_ACL, tables, 0))
goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,INSERT_ACL,tables))
- goto error;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
- lex->duplicates,
- lex->lock_option);
+ lex->duplicates);
break;
case SQLCOM_REPLACE:
- if (check_access(thd,INSERT_ACL | UPDATE_ACL | DELETE_ACL,
- tables->db,&tables->grant.privilege))
+ if (check_one_table_access(thd, INSERT_ACL | DELETE_ACL, tables, 0))
goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,INSERT_ACL | UPDATE_ACL | DELETE_ACL,
- tables))
-
- goto error;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
- DUP_REPLACE,
- lex->lock_option);
+ DUP_REPLACE);
break;
case SQLCOM_REPLACE_SELECT:
case SQLCOM_INSERT_SELECT:
{
- // Check that we have modify privileges for the first table and
- // select privileges for the rest
{
- uint privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ?
- INSERT_ACL : INSERT_ACL | UPDATE_ACL | DELETE_ACL);
+ /*
+ Check that we have modify privileges for the first table and
+ select privileges for the rest
+ */
+ ulong privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ?
+ INSERT_ACL : INSERT_ACL | DELETE_ACL);
TABLE_LIST *save_next=tables->next;
tables->next=0;
- if (check_access(thd, privilege,
- tables->db,&tables->grant.privilege) ||
- (grant_option && check_grant(thd, privilege, tables)))
+ if (check_one_table_access(thd, privilege, tables, 0))
goto error;
tables->next=save_next;
if ((res=check_table_access(thd, SELECT_ACL, save_next)))
goto error;
}
+ /* Fix lock for first table */
+ if (tables->lock_type == TL_WRITE_DELAYED)
+ tables->lock_type= TL_WRITE;
+
+ /* Don't unlock tables until command is written to binary log */
+ select_lex->options|= SELECT_NO_UNLOCK;
select_result *result;
- thd->offset_limit=lex->offset_limit;
- thd->select_limit=lex->select_limit+lex->offset_limit;
- if (thd->select_limit < lex->select_limit)
+ thd->offset_limit=select_lex->offset_limit;
+ thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
+ if (thd->select_limit < select_lex->select_limit)
thd->select_limit= HA_POS_ERROR; // No limit
- if (check_dup(thd,tables->db,tables->real_name,tables->next))
+ if (check_dup(tables->db, tables->real_name, tables->next))
{
- net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
- DBUG_VOID_RETURN;
+ /* Using same table for INSERT and SELECT */
+ select_lex->options |= OPTION_BUFFER_RESULT;
}
- tables->lock_type=TL_WRITE; // update first table
{
+ /* TODO: Delete the following loop when locks is set by sql_yacc */
TABLE_LIST *table;
for (table = tables->next ; table ; table=table->next)
table->lock_type= lex->lock_option;
}
- if (!(res=open_and_lock_tables(thd,tables)))
+
+ /* Skip first table, which is the table we are inserting in */
+ lex->select_lex.table_list.first=
+ (byte*) (((TABLE_LIST *) lex->select_lex.table_list.first)->next);
+ if (!(res=open_and_lock_tables(thd, tables)))
{
if ((result=new select_insert(tables->table,&lex->field_list,
- lex->sql_command == SQLCOM_REPLACE_SELECT ?
- DUP_REPLACE : DUP_IGNORE)))
- {
- res=mysql_select(thd,tables->next,lex->item_list,
- lex->where,
- (ORDER*) lex->order_list.first,
- (ORDER*) lex->group_list.first,
- lex->having,
- (ORDER*) lex->proc_list.first,
- lex->options | thd->options,
- result);
- delete result;
- }
- else
- res= -1;
+ lex->duplicates)))
+ res=handle_select(thd,lex,result);
}
-#ifdef DELETE_ITEMS
- delete lex->having;
- delete lex->where;
-#endif
+ else
+ res= -1;
break;
}
case SQLCOM_TRUNCATE:
- lex->where=0;
- lex->select_limit=HA_POS_ERROR;
- /* Fall through */
+ if (check_one_table_access(thd, DELETE_ACL, tables, 0))
+ goto error; /* purecov: inspected */
+ /*
+ Don't allow this within a transaction because we want to use
+ re-generate table
+ */
+ if (thd->locked_tables || thd->active_transaction())
+ {
+ send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION,NullS);
+ goto error;
+ }
+ res=mysql_truncate(thd,tables);
+ break;
case SQLCOM_DELETE:
{
- if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege))
- goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,DELETE_ACL,tables))
+ if (check_one_table_access(thd, DELETE_ACL, tables, 0))
goto error;
// Set privilege for the WHERE clause
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
- /* TRUNCATE ends previous transaction */
- if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd))
- res= -1;
- else
- res = mysql_delete(thd,tables,lex->where,lex->select_limit,
- lex->lock_option, lex->options);
+ res = mysql_delete(thd,tables, select_lex->where,
+ (ORDER*) select_lex->order_list.first,
+ select_lex->select_limit, select_lex->options);
break;
}
- case SQLCOM_DROP_TABLE:
+ case SQLCOM_DELETE_MULTI:
+ {
+ TABLE_LIST *aux_tables=(TABLE_LIST *)thd->lex.auxilliary_table_list.first;
+ TABLE_LIST *auxi;
+ uint table_count=0;
+ multi_delete *result;
+
+ /* sql_yacc guarantees that tables and aux_tables are not zero */
+ if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) ||
+ check_table_access(thd,SELECT_ACL, tables) ||
+ check_table_access(thd,DELETE_ACL, aux_tables))
+ goto error;
+ if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
+ {
+ send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
+ goto error;
+ }
+ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
{
- if (check_table_access(thd,DROP_ACL,tables))
- goto error; /* purecov: inspected */
- if (end_active_trans(thd))
- res= -1;
- else
- res = mysql_rm_table(thd,tables,lex->drop_if_exists);
+ table_count++;
+ /* All tables in aux_tables must be found in FROM PART */
+ TABLE_LIST *walk;
+ for (walk=(TABLE_LIST*) tables ; walk ; walk=walk->next)
+ {
+ if (!strcmp(auxi->real_name,walk->real_name) &&
+ !strcmp(walk->db,auxi->db))
+ break;
+ }
+ if (!walk)
+ {
+ net_printf(&thd->net,ER_NONUNIQ_TABLE,auxi->real_name);
+ goto error;
+ }
+ walk->lock_type= auxi->lock_type;
+ // Store address to table as we need it later
+ auxi->table= my_reinterpret_cast(TABLE *) (walk);
+ }
+ if (add_item_to_list(new Item_null()))
+ {
+ res= -1;
+ break;
}
+ tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
+ thd->proc_info="init";
+ if ((res=open_and_lock_tables(thd,tables)))
+ break;
+ /* Fix tables-to-be-deleted-from list to point at opened tables */
+ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
+ auxi->table= (my_reinterpret_cast(TABLE_LIST*) (auxi->table))->table;
+
+ if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables,
+ table_count)))
+ {
+ res=mysql_select(thd,tables,select_lex->item_list,
+ select_lex->where,
+ (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL,
+ (ORDER *)NULL,
+ select_lex->options | thd->options |
+ SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK,
+ result);
+ delete result;
+ }
+ else
+ res= -1; // Error is not sent
+ close_thread_tables(thd);
break;
- case SQLCOM_DROP_INDEX:
- if (!tables->db)
- tables->db=thd->db;
- if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege))
+ }
+ case SQLCOM_DROP_TABLE:
+ {
+ if (check_table_access(thd,DROP_ACL,tables))
goto error; /* purecov: inspected */
- if (grant_option && check_grant(thd,INDEX_ACL,tables))
- goto error;
+ /*
+ If this is a slave thread, we may sometimes execute some
+ DROP / * 40005 TEMPORARY * / TABLE
+ that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE
+ MASTER TO), while the temporary table has already been dropped.
+ To not generate such irrelevant "table does not exist errors",
+ we silently add IF EXISTS if TEMPORARY was used.
+ */
+ if (thd->slave_thread && lex->drop_temporary)
+ lex->drop_if_exists= 1;
+ if (end_active_trans(thd))
+ res= -1;
+ else
+ res = mysql_rm_table(thd,tables,lex->drop_if_exists);
+ }
+ break;
+ case SQLCOM_DROP_INDEX:
+ if (check_one_table_access(thd, INDEX_ACL, tables, 0))
+ goto error; /* purecov: inspected */
if (end_active_trans(thd))
res= -1;
else
@@ -1720,49 +2148,43 @@ mysql_execute_command(void)
break;
case SQLCOM_SHOW_DATABASES:
#if defined(DONT_ALLOW_SHOW_COMMANDS)
- send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
+ send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
DBUG_VOID_RETURN;
#else
if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
- check_process_priv(thd))
+ check_global_access(thd, SHOW_DB_ACL))
goto error;
res= mysqld_show_dbs(thd, (lex->wild ? lex->wild->ptr() : NullS));
break;
#endif
case SQLCOM_SHOW_PROCESSLIST:
- if (!thd->priv_user[0] && check_process_priv(thd))
+ if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
break;
mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS :
thd->priv_user,lex->verbose);
break;
case SQLCOM_SHOW_STATUS:
- res= mysqld_show(thd,(lex->wild ? lex->wild->ptr() : NullS),status_vars);
+ res= mysqld_show(thd,(lex->wild ? lex->wild->ptr() : NullS),status_vars,
+ OPT_GLOBAL, &LOCK_status);
break;
case SQLCOM_SHOW_VARIABLES:
res= mysqld_show(thd, (lex->wild ? lex->wild->ptr() : NullS),
- init_vars);
+ init_vars, lex->option_type,
+ &LOCK_global_system_variables);
break;
case SQLCOM_SHOW_LOGS:
-#ifdef DONT_ALLOW_SHOW_COMMANDS
- send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
- DBUG_VOID_RETURN;
-#else
- {
- if (grant_option && check_access(thd, FILE_ACL, any_db))
- goto error;
- res= mysqld_show_logs(thd);
- break;
- }
-#endif
+ {
+ res= mysqld_show_logs(thd);
+ break;
+ }
case SQLCOM_SHOW_TABLES:
/* FALL THROUGH */
- case SQLCOM_SHOW_OPEN_TABLES:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
DBUG_VOID_RETURN;
#else
{
- char *db=lex->db ? lex->db : thd->db;
+ char *db=select_lex->db ? select_lex->db : thd->db;
if (!db)
{
send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
@@ -1776,38 +2198,39 @@ mysql_execute_command(void)
}
if (check_access(thd,SELECT_ACL,db,&thd->col_access))
goto error; /* purecov: inspected */
+ if (!thd->col_access && check_grant_db(thd,db))
+ {
+ net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
+ thd->priv_user,
+ thd->priv_host,
+ db);
+ goto error;
+ }
/* grant is checked in mysqld_show_tables */
- if (lex->sql_command == SQLCOM_SHOW_OPEN_TABLES)
- res= mysqld_show_open_tables(thd,db,
- (lex->wild ? lex->wild->ptr() : NullS));
- else if (lex->options & SELECT_DESCRIBE)
+ if (select_lex->options & SELECT_DESCRIBE)
res= mysqld_extend_show_tables(thd,db,
- (lex->wild ? lex->wild->ptr() : NullS));
+ (lex->wild ? lex->wild->ptr() : NullS));
else
res= mysqld_show_tables(thd,db,
(lex->wild ? lex->wild->ptr() : NullS));
break;
}
#endif
+ case SQLCOM_SHOW_OPEN_TABLES:
+ res= mysqld_show_open_tables(thd,(lex->wild ? lex->wild->ptr() : NullS));
+ break;
case SQLCOM_SHOW_FIELDS:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
DBUG_VOID_RETURN;
#else
{
- char *db=tables->db ? tables->db : thd->db;
- if (!db)
- {
- send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
- goto error; /* purecov: inspected */
- }
+ char *db=tables->db;
remove_escape(db); // Fix escaped '_'
remove_escape(tables->real_name);
- if (!tables->db)
- tables->db=thd->db;
- if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,&thd->col_access))
+ if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,
+ &tables->grant.privilege))
goto error; /* purecov: inspected */
- tables->grant.privilege=thd->col_access;
if (grant_option && check_grant(thd,SELECT_ACL,tables,2))
goto error;
res= mysqld_show_fields(thd,tables,
@@ -1822,19 +2245,11 @@ mysql_execute_command(void)
DBUG_VOID_RETURN;
#else
{
- char *db=tables->db ? tables->db : thd->db;
- if (!db)
- {
- send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
- goto error; /* purecov: inspected */
- }
+ char *db=tables->db;
remove_escape(db); // Fix escaped '_'
remove_escape(tables->real_name);
- if (!tables->db)
- tables->db=thd->db;
- if (check_access(thd,SELECT_ACL,db,&thd->col_access))
+ if (check_access(thd,SELECT_ACL,db,&tables->grant.privilege))
goto error; /* purecov: inspected */
- tables->grant.privilege=thd->col_access;
if (grant_option && check_grant(thd,SELECT_ACL,tables,2))
goto error;
res= mysqld_show_keys(thd,tables);
@@ -1842,7 +2257,7 @@ mysql_execute_command(void)
}
#endif
case SQLCOM_CHANGE_DB:
- mysql_change_db(thd,lex->db);
+ mysql_change_db(thd,select_lex->db);
break;
case SQLCOM_LOAD:
{
@@ -1862,8 +2277,7 @@ mysql_execute_command(void)
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND);
goto error;
}
- if (check_access(thd,privilege,tables->db,&tables->grant.privilege) ||
- grant_option && check_grant(thd,privilege,tables))
+ if (check_one_table_access(thd, privilege, tables, 0))
goto error;
}
res=mysql_load(thd, lex->exchange, tables, lex->field_list,
@@ -1871,74 +2285,26 @@ mysql_execute_command(void)
break;
}
case SQLCOM_SET_OPTION:
- {
- uint org_options=thd->options;
- thd->options=lex->options;
- thd->update_lock_default= ((thd->options & OPTION_LOW_PRIORITY_UPDATES) ?
- TL_WRITE_LOW_PRIORITY : TL_WRITE);
- thd->default_select_limit=lex->select_limit;
- thd->tx_isolation=lex->tx_isolation;
- if (thd->gemini_spin_retries != lex->gemini_spin_retries)
- {
- thd->gemini_spin_retries= lex->gemini_spin_retries;
- ha_set_spin_retries(thd->gemini_spin_retries);
- }
- DBUG_PRINT("info",("options: %ld limit: %ld",
- thd->options,(long) thd->default_select_limit));
-
- /* Check if auto_commit mode changed */
- if ((org_options ^ lex->options) & OPTION_NOT_AUTO_COMMIT)
- {
- if ((org_options & OPTION_NOT_AUTO_COMMIT))
- {
- /* We changed to auto_commit mode */
- thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
- thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
- if (ha_commit(thd))
- {
- res= -1;
- break;
- }
- }
- else
- {
- thd->options&= ~(ulong) (OPTION_STATUS_NO_TRANS_UPDATE);
- thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
- }
- }
- send_ok(&thd->net);
+ if (!(res=sql_set_variables(thd, &lex->var_list)))
+ send_ok(&thd->net);
break;
- }
case SQLCOM_UNLOCK_TABLES:
- if (thd->locked_tables)
- {
- thd->lock=thd->locked_tables;
- thd->locked_tables=0; // Will be automaticly closed
- }
+ unlock_locked_tables(thd);
if (thd->options & OPTION_TABLE_LOCK)
{
end_active_trans(thd);
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
}
if (thd->global_read_lock)
- {
- thd->global_read_lock=0;
- pthread_mutex_lock(&LOCK_open);
- global_read_lock--;
- pthread_cond_broadcast(&COND_refresh);
- pthread_mutex_unlock(&LOCK_open);
- }
+ unlock_global_read_lock(thd);
send_ok(&thd->net);
break;
case SQLCOM_LOCK_TABLES:
- if (thd->locked_tables)
- {
- thd->lock=thd->locked_tables;
- thd->locked_tables=0; // Will be automaticly closed
- close_thread_tables(thd);
- }
+ unlock_locked_tables(thd);
if (check_db_used(thd,tables) || end_active_trans(thd))
goto error;
+ if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, tables))
+ goto error;
thd->in_lock_tables=1;
thd->options|= OPTION_TABLE_LOCK;
if (!(res=open_and_lock_tables(thd,tables)))
@@ -1952,30 +2318,68 @@ mysql_execute_command(void)
thd->in_lock_tables=0;
break;
case SQLCOM_CREATE_DB:
+ {
+ char *alias;
+ if (!strip_sp(lex->name) || !(alias=thd->strdup(lex->name)) ||
+ check_db_name(lex->name))
{
- if (!strip_sp(lex->name) || check_db_name(lex->name))
- {
- net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
- break;
- }
- if (check_access(thd,CREATE_ACL,lex->name,0,1))
- break;
- mysql_create_db(thd,lex->name,lex->create_info.options);
+ net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
break;
}
+ /*
+ If in a slave thread :
+ CREATE DATABASE DB was certainly not preceded by USE DB.
+ For that reason, db_ok() in sql/slave.cc did not check the
+ do_db/ignore_db. And as this query involves no tables, tables_ok()
+ above was not called. So we have to check rules again here.
+ */
+ if (thd->slave_thread &&
+ (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) ||
+ !db_ok_with_wild_table(lex->name)))
+ {
+ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
+ break;
+ }
+
+ if (check_access(thd,CREATE_ACL,lex->name,0,1))
+ break;
+ res=mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name),
+ lex->create_info.options,0);
+ break;
+ }
case SQLCOM_DROP_DB:
+ {
+ char *alias;
+ if (!strip_sp(lex->name) || !(alias=thd->strdup(lex->name)) ||
+ check_db_name(lex->name))
{
- if (!strip_sp(lex->name) || check_db_name(lex->name))
- {
- net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
- break;
- }
- if (check_access(thd,DROP_ACL,lex->name,0,1) ||
- end_active_trans(thd))
- break;
- mysql_rm_db(thd,lex->name,lex->drop_if_exists);
+ net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
+ break;
+ }
+ /*
+ If in a slave thread :
+ DROP DATABASE DB may not be preceded by USE DB.
+ For that reason, maybe db_ok() in sql/slave.cc did not check the
+ do_db/ignore_db. And as this query involves no tables, tables_ok()
+ above was not called. So we have to check rules again here.
+ */
+ if (thd->slave_thread &&
+ (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) ||
+ !db_ok_with_wild_table(lex->name)))
+ {
+ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
break;
}
+ if (check_access(thd,DROP_ACL,lex->name,0,1))
+ break;
+ if (thd->locked_tables || thd->active_transaction())
+ {
+ send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
+ goto error;
+ }
+ res=mysql_rm_db(thd,alias,lex->drop_if_exists,0);
+ break;
+ }
case SQLCOM_CREATE_FUNCTION:
if (check_access(thd,INSERT_ACL,"mysql",0,1))
break;
@@ -1996,99 +2400,137 @@ mysql_execute_command(void)
res= -1;
#endif
break;
- case SQLCOM_REVOKE:
- case SQLCOM_GRANT:
- {
- if (tables && !tables->db)
- tables->db=thd->db;
- if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
- tables && tables->db ? tables->db : lex->db,
- tables ? &tables->grant.privilege : 0,
- tables ? 0 : 1))
- goto error;
-
- /* Check that the user isn't trying to change a password for another
- user if he doesn't have UPDATE privilege to the MySQL database */
-
- if (thd->user) // If not replication
- {
- LEX_USER *user;
- List_iterator <LEX_USER> user_list(lex->users_list);
- while ((user=user_list++))
- {
- if (user->password.str &&
- (strcmp(thd->user,user->user.str) ||
- user->host.str &&
- my_strcasecmp(user->host.str, thd->host ? thd->host : thd->ip)))
- {
- if (check_access(thd, UPDATE_ACL, "mysql",0,1))
- goto error;
- break; // We are allowed to do changes
- }
- }
- }
- if (tables)
- {
- if (grant_option && check_grant(thd,
- (lex->grant | lex->grant_tot_col |
- GRANT_ACL),
- tables))
- goto error;
- res = mysql_table_grant(thd,tables,lex->users_list, lex->columns,
- lex->grant, lex->sql_command == SQLCOM_REVOKE);
- if(!res)
- {
- mysql_update_log.write(thd, thd->query,thd->query_length);
- if (mysql_bin_log.is_open())
- {
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
- }
- }
- }
- else
- {
- if (lex->columns.elements)
- {
- net_printf(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
- res=1;
- }
- else
- res = mysql_grant(thd, lex->db, lex->users_list, lex->grant,
- lex->sql_command == SQLCOM_REVOKE);
- if (!res)
- {
- mysql_update_log.write(thd, thd->query,thd->query_length);
- if (mysql_bin_log.is_open())
- {
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
- }
- }
- }
- break;
- }
+ case SQLCOM_REVOKE:
+ case SQLCOM_GRANT:
+ {
+ if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
+ tables && tables->db ? tables->db : select_lex->db,
+ tables ? &tables->grant.privilege : 0,
+ tables ? 0 : 1))
+ goto error;
+
+ /*
+ Check that the user isn't trying to change a password for another
+ user if he doesn't have UPDATE privilege to the MySQL database
+ */
+
+ if (thd->user) // If not replication
+ {
+ LEX_USER *user;
+ List_iterator <LEX_USER> user_list(lex->users_list);
+ while ((user=user_list++))
+ {
+ if (user->password.str &&
+ (strcmp(thd->user,user->user.str) ||
+ user->host.str &&
+ my_strcasecmp(user->host.str, thd->host_or_ip)))
+ {
+ if (check_access(thd, UPDATE_ACL, "mysql",0,1))
+ goto error;
+ break; // We are allowed to do changes
+ }
+ }
+ }
+ if (tables)
+ {
+ if (grant_option && check_grant(thd,
+ (lex->grant | lex->grant_tot_col |
+ GRANT_ACL),
+ tables))
+ goto error;
+ if (!(res = mysql_table_grant(thd,tables,lex->users_list, lex->columns,
+ lex->grant,
+ lex->sql_command == SQLCOM_REVOKE)))
+ {
+ mysql_update_log.write(thd, thd->query, thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
+ mysql_bin_log.write(&qinfo);
+ }
+ }
+ }
+ else
+ {
+ if (lex->columns.elements)
+ {
+ send_error(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
+ res=1;
+ }
+ else
+ res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
+ lex->sql_command == SQLCOM_REVOKE);
+ if (!res)
+ {
+ mysql_update_log.write(thd, thd->query, thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
+ mysql_bin_log.write(&qinfo);
+ }
+ if (mqh_used && lex->sql_command == SQLCOM_GRANT)
+ {
+ List_iterator <LEX_USER> str_list(lex->users_list);
+ LEX_USER *user;
+ while ((user=str_list++))
+ reset_mqh(thd,user);
+ }
+ }
+ }
+ break;
+ }
case SQLCOM_FLUSH:
case SQLCOM_RESET:
- if (check_access(thd,RELOAD_ACL,any_db) || check_db_used(thd, tables))
+ if (check_global_access(thd,RELOAD_ACL) || check_db_used(thd, tables))
goto error;
- if (reload_acl_and_cache(thd, lex->type, tables))
- send_error(&thd->net,0);
- else
- send_ok(&thd->net);
+ /* error sending is deferred to reload_acl_and_cache */
+ reload_acl_and_cache(thd, lex->type, tables) ;
break;
case SQLCOM_KILL:
kill_one_thread(thd,lex->thread_id);
break;
case SQLCOM_SHOW_GRANTS:
res=0;
- if ((thd->priv_user && !strcmp(thd->priv_user,lex->grant_user->user.str)) ||
+ if ((thd->priv_user &&
+ !strcmp(thd->priv_user,lex->grant_user->user.str)) ||
!check_access(thd, SELECT_ACL, "mysql",0,1))
{
res = mysql_show_grants(thd,lex->grant_user);
}
break;
+ case SQLCOM_HA_OPEN:
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd,SELECT_ACL, tables))
+ goto error;
+ res = mysql_ha_open(thd, tables);
+ break;
+ case SQLCOM_HA_CLOSE:
+ if (check_db_used(thd,tables))
+ goto error;
+ res = mysql_ha_close(thd, tables);
+ break;
+ case SQLCOM_HA_READ:
+ /*
+ There is no need to check for table permissions here, because
+ if a user has no permissions to read a table, he won't be
+ able to open it (with SQLCOM_HA_OPEN) in the first place.
+ */
+ if (check_db_used(thd,tables))
+ goto error;
+ res = mysql_ha_read(thd, tables, lex->ha_read_mode, lex->backup_dir,
+ lex->insert_list, lex->ha_rkey_mode, select_lex->where,
+ select_lex->select_limit, select_lex->offset_limit);
+ break;
+
case SQLCOM_BEGIN:
+ if (thd->locked_tables)
+ {
+ thd->lock=thd->locked_tables;
+ thd->locked_tables=0; // Will be automaticly closed
+ close_thread_tables(thd); // Free tables
+ }
if (end_active_trans(thd))
{
res= -1;
@@ -2107,18 +2549,31 @@ mysql_execute_command(void)
even if there is a problem with the OPTION_AUTO_COMMIT flag
(Which of course should never happen...)
*/
+ {
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_commit(thd))
+ {
send_ok(&thd->net);
+ }
else
res= -1;
break;
+ }
case SQLCOM_ROLLBACK:
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_rollback(thd))
{
- if (thd->options & OPTION_STATUS_NO_TRANS_UPDATE)
+ /*
+ If a non-transactional table was updated, warn; don't warn if this is a
+ slave thread (because when a slave thread executes a ROLLBACK, it has
+ been read from the binary log, so it's 100% sure and normal to produce
+ error ER_WARNING_NOT_COMPLETE_ROLLBACK. If we sent the warning to the
+ slave SQL thread, it would not stop the thread but just be printed in
+ the error log; but we don't want users to wonder why they have this
+ message in the error log, so we don't send it.
+ */
+ if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread)
send_warning(&thd->net,ER_WARNING_NOT_COMPLETE_ROLLBACK,0);
else
send_ok(&thd->net);
@@ -2127,6 +2582,23 @@ mysql_execute_command(void)
res= -1;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
break;
+ case SQLCOM_ROLLBACK_TO_SAVEPOINT:
+ if (!ha_rollback_to_savepoint(thd, lex->savepoint_name))
+ {
+ if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread)
+ send_warning(&thd->net,ER_WARNING_NOT_COMPLETE_ROLLBACK,0);
+ else
+ send_ok(&thd->net);
+ }
+ else
+ res= -1;
+ break;
+ case SQLCOM_SAVEPOINT:
+ if (!ha_savepoint(thd, lex->savepoint_name))
+ send_ok(&thd->net);
+ else
+ res= -1;
+ break;
default: /* Impossible */
send_ok(&thd->net);
break;
@@ -2141,29 +2613,42 @@ error:
/****************************************************************************
-** Get the user (global) and database privileges for all used tables
-** Returns true (error) if we can't get the privileges and we don't use
-** table/column grants.
-** The idea of EXTRA_ACL is that one will be granted access to the table if
-** one has the asked privilege on any column combination of the table; For
-** example to be able to check a table one needs to have SELECT privilege on
-** any column of the table.
+ Get the user (global) and database privileges for all used tables
+
+ NOTES
+ The idea of EXTRA_ACL is that one will be granted access to the table if
+ one has the asked privilege on any column combination of the table; For
+ example to be able to check a table one needs to have SELECT privilege on
+ any column of the table.
+
+ RETURN
+ 0 ok
+ 1 If we can't get the privileges and we don't use table/column grants.
+
+ save_priv In this we store global and db level grants for the table
+ Note that we don't store db level grants if the global grants
+ is enough to satisfy the request and the global grants contains
+ a SELECT grant.
****************************************************************************/
bool
-check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
- bool dont_check_global_grants)
+check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
+ bool dont_check_global_grants, bool no_errors)
{
- uint db_access,dummy;
+ DBUG_ENTER("check_access");
+ DBUG_PRINT("enter",("want_access: %lu master_access: %lu", want_access,
+ thd->master_access));
+ ulong db_access,dummy;
if (save_priv)
*save_priv=0;
else
save_priv= &dummy;
- if (!db && !thd->db && !dont_check_global_grants)
+ if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
{
- send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */
- return TRUE; /* purecov: tested */
+ if (!no_errors)
+ send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */
+ DBUG_RETURN(TRUE); /* purecov: tested */
}
if ((thd->master_access & want_access) == want_access)
@@ -2179,21 +2664,22 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, db); /* purecov: inspected */
*save_priv=thd->master_access | db_access;
- return FALSE;
+ DBUG_RETURN(FALSE);
}
- if ((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL) ||
+ if (((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
! db && dont_check_global_grants)
{ // We can never grant this
- net_printf(&thd->net,ER_ACCESS_DENIED_ERROR,
- thd->priv_user,
- thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
- thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */
- return TRUE; /* purecov: tested */
+ if (!no_errors)
+ net_printf(&thd->net,ER_ACCESS_DENIED_ERROR,
+ thd->priv_user,
+ thd->priv_host,
+ thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */
+ DBUG_RETURN(TRUE); /* purecov: tested */
}
if (db == any_db)
- return FALSE; // Allow select on anything
-
+ DBUG_RETURN(FALSE); // Allow select on anything
+
if (db && (!thd->db || strcmp(db,thd->db)))
db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, db); /* purecov: inspected */
@@ -2206,31 +2692,59 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
/* grant_option is set if there exists a single table or column grant */
if (db_access == want_access ||
((grant_option && !dont_check_global_grants) &&
- !(want_access & ~TABLE_ACLS)))
- return FALSE; /* Ok */
- net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
- thd->priv_user,
- thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
- db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */
- return TRUE; /* purecov: tested */
+ !(want_access & ~(db_access | TABLE_ACLS))))
+ DBUG_RETURN(FALSE); /* Ok */
+ if (!no_errors)
+ net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
+ thd->priv_user,
+ thd->priv_host,
+ db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */
+ DBUG_RETURN(TRUE); /* purecov: tested */
}
-bool check_process_priv(THD *thd)
+/*
+ check for global access and give descriptive error message if it fails
+
+ SYNOPSIS
+ check_global_access()
+ thd Thread handler
+ want_access Use should have any of these global rights
+
+ WARNING
+ One gets access rigth if one has ANY of the rights in want_access
+ This is useful as one in most cases only need one global right,
+ but in some case we want to check if the user has SUPER or
+ REPL_CLIENT_ACL rights.
+
+ RETURN
+ 0 ok
+ 1 Access denied. In this case an error is sent to the client
+*/
+
+bool check_global_access(THD *thd, ulong want_access)
{
- return (check_access(thd ? thd : current_thd,PROCESS_ACL,any_db));
+ char command[128];
+ if ((thd->master_access & want_access))
+ return 0;
+ get_privilege_desc(command, sizeof(command), want_access);
+ net_printf(&thd->net,ER_SPECIFIC_ACCESS_DENIED_ERROR,
+ command);
+ return 1;
}
/*
-** Check the privilege for all used tables. Table privileges are cached
-** in the table list for GRANT checking
+ Check the privilege for all used tables. Table privileges are cached
+ in the table list for GRANT checking
*/
bool
-check_table_access(THD *thd,uint want_access,TABLE_LIST *tables)
+check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
+ bool no_errors)
{
- uint found=0,found_access=0;
+ uint found=0;
+ ulong found_access=0;
TABLE_LIST *org_tables=tables;
for (; tables ; tables=tables->next)
{
@@ -2243,24 +2757,36 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables)
tables->grant.privilege=found_access;
else
{
- if (check_access(thd,want_access,tables->db,&tables->grant.privilege))
+ if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
+ 0, no_errors))
return TRUE; // Access denied
found_access=tables->grant.privilege;
found=1;
}
}
- else if (check_access(thd,want_access,tables->db,&tables->grant.privilege))
- return TRUE; // Access denied
+ else if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
+ 0, no_errors))
+ return TRUE;
}
if (grant_option)
- {
- want_access &= ~EXTRA_ACL; // Remove SHOW attribute
- return check_grant(thd,want_access,org_tables);
- }
+ return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
+ test(want_access & EXTRA_ACL), no_errors);
return FALSE;
}
+static bool
+check_one_table_access(THD *thd, ulong want_access, TABLE_LIST *table,
+ bool no_errors)
+{
+ if (check_access(thd, want_access, table->db, &table->grant.privilege, 0,
+ no_errors))
+ return 1;
+ return (grant_option && check_grant(thd, want_access, table, 0,
+ no_errors));
+}
+
+
static bool check_db_used(THD *thd,TABLE_LIST *tables)
{
for (; tables ; tables=tables->next)
@@ -2313,6 +2839,7 @@ static bool check_merge_table_access(THD *thd, char *db,
#define used_stack(A,B) (long) (B - A)
#endif
+#ifndef EMBEDDED_LIBRARY
bool check_stack_overrun(THD *thd,char *buf __attribute__((unused)))
{
long stack_used;
@@ -2326,6 +2853,7 @@ bool check_stack_overrun(THD *thd,char *buf __attribute__((unused)))
}
return 0;
}
+#endif /* EMBEDDED_LIBRARY */
#define MY_YACC_INIT 1000 // Start with big alloc
#define MY_YACC_MAX 32000 // Because of 'short'
@@ -2360,40 +2888,80 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize)
/****************************************************************************
- Initialize global thd variables neaded for query
+ Initialize global thd variables needed for query
****************************************************************************/
static void
mysql_init_query(THD *thd)
{
DBUG_ENTER("mysql_init_query");
- thd->lex.item_list.empty();
+ thd->lex.select_lex.item_list.empty();
thd->lex.value_list.empty();
- thd->lex.table_list.elements=0;
- thd->free_list=0;
-
- thd->lex.table_list.first=0;
- thd->lex.table_list.next= (byte**) &thd->lex.table_list.first;
+ thd->lex.select_lex.table_list.elements=0;
+ thd->free_list=0; thd->lex.union_option=0;
+ thd->lex.select = &thd->lex.select_lex;
+ thd->lex.select_lex.table_list.first=0;
+ thd->lex.select_lex.table_list.next= (byte**) &thd->lex.select_lex.table_list.first;
+ thd->lex.select_lex.next=0;
+ /*
+ select_lex.options is also inited in dispatch_command(), but for
+ replication (which bypasses dispatch_command() and calls mysql_parse()
+ directly) we must do it here.
+ */
+ thd->lex.select_lex.options=0;
+ thd->lex.olap=0;
+ thd->lex.select->olap= UNSPECIFIED_OLAP_TYPE;
thd->fatal_error=0; // Safety
thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
+ thd->rand_used=0;
thd->sent_row_count=thd->examined_row_count=0;
+ thd->safe_to_cache_query=1;
DBUG_VOID_RETURN;
}
void
mysql_init_select(LEX *lex)
{
- lex->where=lex->having=0;
- lex->select_limit=current_thd->default_select_limit;
- lex->offset_limit=0L;
- lex->options=0;
+ SELECT_LEX *select_lex = lex->select;
+ select_lex->where=select_lex->having=0;
+ select_lex->select_limit= lex->thd->variables.select_limit;
+ select_lex->offset_limit=0;
+ select_lex->options=0;
+ select_lex->linkage=UNSPECIFIED_TYPE;
+ select_lex->olap= UNSPECIFIED_OLAP_TYPE;
lex->exchange = 0;
lex->proc_list.first=0;
- lex->order_list.elements=lex->group_list.elements=0;
- lex->order_list.first=0;
- lex->order_list.next= (byte**) &lex->order_list.first;
- lex->group_list.first=0;
- lex->group_list.next= (byte**) &lex->group_list.first;
+ select_lex->order_list.empty();
+ select_lex->group_list.empty();
+ select_lex->next = (SELECT_LEX *)NULL;
+}
+
+
+bool
+mysql_new_select(LEX *lex)
+{
+ SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX));
+ if (!select_lex)
+ return 1;
+ lex->select->next=select_lex;
+ lex->select=select_lex;
+ select_lex->table_list.next= (byte**) &select_lex->table_list.first;
+ select_lex->item_list.empty();
+ select_lex->when_list.empty();
+ select_lex->expr_list.empty();
+ select_lex->interval_list.empty();
+ select_lex->use_index.empty();
+ select_lex->ftfunc_list.empty();
+ return 0;
+}
+
+
+void mysql_init_multi_delete(LEX *lex)
+{
+ lex->sql_command = SQLCOM_DELETE_MULTI;
+ mysql_init_select(lex);
+ lex->select->select_limit=lex->thd->select_limit=HA_POS_ERROR;
+ lex->select->table_list.save_and_clear(&lex->auxilliary_table_list);
}
@@ -2404,26 +2972,36 @@ mysql_parse(THD *thd,char *inBuf,uint length)
mysql_init_query(thd);
thd->query_length = length;
- LEX *lex=lex_start(thd, (uchar*) inBuf, length);
- if (!yyparse() && ! thd->fatal_error)
- mysql_execute_command();
- thd->proc_info="freeing items";
- free_items(thd); /* Free strings used by items */
- lex_end(lex);
+ if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
+ {
+ LEX *lex=lex_start(thd, (uchar*) inBuf, length);
+ if (!yyparse() && ! thd->fatal_error)
+ {
+ if (mqh_used && thd->user_connect &&
+ check_mqh(thd, thd->lex.sql_command))
+ {
+ thd->net.error = 0;
+ }
+ else
+ {
+ mysql_execute_command();
+ query_cache_end_of_result(&thd->net);
+ }
+ }
+ else
+ {
+ DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
+ thd->fatal_error));
+ query_cache_abort(&thd->net);
+ }
+ thd->proc_info="freeing items";
+ free_items(thd); /* Free strings used by items */
+ lex_end(lex);
+ }
DBUG_VOID_RETURN;
}
-inline static void
-link_in_list(SQL_LIST *list,byte *element,byte **next)
-{
- list->elements++;
- (*list->next)=element;
- list->next=next;
- *next=0;
-}
-
-
/*****************************************************************************
** Store field definition for create
** Return 0 if ok
@@ -2460,21 +3038,40 @@ bool add_field_to_list(char *field_name, enum_field_types type,
lex->col_list.empty();
}
- if (default_value && default_value->type() == Item::NULL_ITEM)
+ if (default_value)
{
- if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
- NOT_NULL_FLAG)
+ /*
+ We allow specifying value for first TIMESTAMP column
+ altough it is silently ignored. This should be fixed in 4.1
+ (by proper warning or real support for default values)
+ */
+ if (default_value->type() == Item::NULL_ITEM)
+ {
+ default_value=0;
+ if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
+ NOT_NULL_FLAG)
+ {
+ net_printf(&thd->net,ER_INVALID_DEFAULT,field_name);
+ DBUG_RETURN(1);
+ }
+ }
+#ifdef MYSQL41000
+ else if (type_modifier & AUTO_INCREMENT_FLAG)
{
- net_printf(&thd->net,ER_INVALID_DEFAULT,field_name);
+ net_printf(&thd->net, ER_INVALID_DEFAULT, field_name);
DBUG_RETURN(1);
}
- default_value=0;
+#endif
}
if (!(new_field=new create_field()))
DBUG_RETURN(1);
new_field->field=0;
new_field->field_name=field_name;
+#ifdef MYSQL41000
+ new_field->def= default_value;
+#else
new_field->def= (type_modifier & AUTO_INCREMENT_FLAG ? 0 : default_value);
+#endif
new_field->flags= type_modifier;
new_field->unireg_check= (type_modifier & AUTO_INCREMENT_FLAG ?
Field::NEXT_NUMBER : Field::NONE);
@@ -2485,9 +3082,8 @@ bool add_field_to_list(char *field_name, enum_field_types type,
new_field->change=change;
new_field->interval=0;
new_field->pack_length=0;
- if (length)
- if (!(new_field->length= (uint) atoi(length)))
- length=0; /* purecov: inspected */
+ if (length && !(new_field->length= (uint) atoi(length)))
+ length=0; /* purecov: inspected */
uint sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1;
if (new_field->length && new_field->decimals &&
@@ -2519,13 +3115,17 @@ bool add_field_to_list(char *field_name, enum_field_types type,
case FIELD_TYPE_STRING:
case FIELD_TYPE_VAR_STRING:
case FIELD_TYPE_NULL:
+ case FIELD_TYPE_GEOMETRY:
break;
case FIELD_TYPE_DECIMAL:
if (!length)
- new_field->length = 10; // Default length for DECIMAL
- new_field->length+=sign_len;
- if (new_field->decimals)
- new_field->length++;
+ new_field->length= 10; // Default length for DECIMAL
+ if (new_field->length < MAX_FIELD_WIDTH) // Skip wrong argument
+ {
+ new_field->length+=sign_len;
+ if (new_field->decimals)
+ new_field->length++;
+ }
break;
case FIELD_TYPE_BLOB:
case FIELD_TYPE_TINY_BLOB:
@@ -2666,7 +3266,7 @@ bool add_field_to_list(char *field_name, enum_field_types type,
if (new_field->length >= MAX_FIELD_WIDTH ||
(!new_field->length && !(new_field->flags & BLOB_FLAG) &&
- type != FIELD_TYPE_STRING))
+ type != FIELD_TYPE_STRING && type != FIELD_TYPE_VAR_STRING))
{
net_printf(&thd->net,ER_TOO_BIG_FIELDLENGTH,field_name,
MAX_FIELD_WIDTH-1); /* purecov: inspected */
@@ -2697,7 +3297,7 @@ void store_position_for_column(const char *name)
}
bool
-add_proc_to_list(Item *item)
+add_proc_to_list(THD* thd, Item *item)
{
ORDER *order;
Item **item_ptr;
@@ -2708,7 +3308,7 @@ add_proc_to_list(Item *item)
*item_ptr= item;
order->item=item_ptr;
order->free_me=0;
- link_in_list(&current_lex->proc_list,(byte*) order,(byte**) &order->next);
+ thd->lex.proc_list.link_in_list((byte*) order,(byte**) &order->next);
return 0;
}
@@ -2717,6 +3317,8 @@ add_proc_to_list(Item *item)
static void remove_escape(char *name)
{
+ if (!*name) // For empty DB names
+ return;
char *to;
#ifdef USE_MB
char *strend=name+(uint) strlen(name);
@@ -2736,7 +3338,7 @@ static void remove_escape(char *name)
}
#endif
if (*name == '\\' && name[1])
- name++; // Skipp '\\'
+ name++; // Skip '\\'
*to++= *name;
}
*to=0;
@@ -2760,22 +3362,39 @@ bool add_to_list(SQL_LIST &list,Item *item,bool asc)
order->asc = asc;
order->free_me=0;
order->used=0;
- link_in_list(&list,(byte*) order,(byte**) &order->next);
+ list.link_in_list((byte*) order,(byte**) &order->next);
DBUG_RETURN(0);
}
+/*
+ Add a table to list of used tables
+
+ SYNOPSIS
+ add_table_to_list()
+ table Table to add
+ alias alias for table (or null if no alias)
+ table_options A set of the following bits:
+ TL_OPTION_UPDATING Table will be updated
+ TL_OPTION_FORCE_INDEX Force usage of index
+ lock_type How table should be locked
+ use_index List of indexed used in USE INDEX
+ ignore_index List of indexed used in IGNORE INDEX
+
+ RETURN
+ 0 Error
+ # Pointer to TABLE_LIST element added to the total table list
+*/
+
TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
- bool updating,
- thr_lock_type flags,
+ ulong table_options,
+ thr_lock_type lock_type,
List<String> *use_index,
- List<String> *ignore_index
- )
+ List<String> *ignore_index)
{
register TABLE_LIST *ptr;
THD *thd=current_thd;
char *alias_str;
- const char *current_db;
DBUG_ENTER("add_table_to_list");
if (!table)
@@ -2789,17 +3408,34 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
}
if (!alias) /* Alias is case sensitive */
- if (!(alias_str=sql_strmake(alias_str,table->table.length)))
+ if (!(alias_str=thd->memdup(alias_str,table->table.length+1)))
DBUG_RETURN(0);
- if (lower_case_table_names)
- casedn_str(table->table.str);
+
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
DBUG_RETURN(0); /* purecov: inspected */
- ptr->db= table->db.str;
+ if (table->db.str)
+ {
+ ptr->db= table->db.str;
+ ptr->db_length= table->db.length;
+ }
+ else if (thd->db)
+ {
+ ptr->db= thd->db;
+ ptr->db_length= thd->db_length;
+ }
+ else
+ {
+ ptr->db= (char*) "";
+ ptr->db_length= 0;
+ }
+
+ ptr->alias= alias_str;
+ table_case_convert(table->table.str, table->table.length);
ptr->real_name=table->table.str;
- ptr->alias=alias_str;
- ptr->lock_type=flags;
- ptr->updating=updating;
+ ptr->real_name_length=table->table.length;
+ ptr->lock_type= lock_type;
+ ptr->updating= test(table_options & TL_OPTION_UPDATING);
+ ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
if (use_index)
ptr->use_index=(List<String> *) thd->memdup((gptr) use_index,
sizeof(*use_index));
@@ -2808,38 +3444,154 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
sizeof(*ignore_index));
/* check that used name is unique */
- current_db=thd->db ? thd->db : "";
-
- if (flags != TL_IGNORE)
+ if (lock_type != TL_IGNORE)
{
- for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.table_list.first ; tables ;
+ for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.select->table_list.first ;
+ tables ;
tables=tables->next)
{
- if (!strcmp(alias_str,tables->alias) &&
- !strcmp(ptr->db ? ptr->db : current_db,
- tables->db ? tables->db : current_db))
+ if (!strcmp(alias_str,tables->alias) && !strcmp(ptr->db, tables->db))
{
net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */
DBUG_RETURN(0); /* purecov: tested */
}
}
}
- link_in_list(&thd->lex.table_list,(byte*) ptr,(byte**) &ptr->next);
+ thd->lex.select->table_list.link_in_list((byte*) ptr,(byte**) &ptr->next);
DBUG_RETURN(ptr);
}
+/*
+ Set lock for all tables in current select level
+
+ SYNOPSIS:
+ set_lock_for_tables()
+ lock_type Lock to set for tables
+
+ NOTE:
+ If lock is a write lock, then tables->updating is set 1
+ This is to get tables_ok to know that the table is updated by the
+ query
+*/
+
+void set_lock_for_tables(thr_lock_type lock_type)
+{
+ THD *thd=current_thd;
+ bool for_update= lock_type >= TL_READ_NO_INSERT;
+ DBUG_ENTER("set_lock_for_tables");
+ DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
+ for_update));
+
+ for (TABLE_LIST *tables= (TABLE_LIST*) thd->lex.select->table_list.first ;
+ tables ;
+ tables=tables->next)
+ {
+ tables->lock_type= lock_type;
+ tables->updating= for_update;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+** This is used for UNION to create a new table list of all used tables
+** The table_list->table entry in all used tables are set to point
+** to the entries in this list.
+*/
+
+static bool create_total_list(THD *thd, LEX *lex,
+ TABLE_LIST **result, bool skip_first)
+{
+ /* Handle the case when we are not using union */
+ if (!lex->select_lex.next)
+ {
+ *result= (TABLE_LIST*) lex->select_lex.table_list.first;
+ return 0;
+ }
+
+ /* We should skip first table if SQL command is SQLCOM_CREATE_TABLE */
+ SELECT_LEX *sl;
+ TABLE_LIST **new_table_list= result, *aux;
+
+ *new_table_list=0; // end result list
+ for (sl= &lex->select_lex; sl; sl=sl->next)
+ {
+ if (sl->order_list.first && sl->next && !sl->braces)
+ {
+ net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY");
+ return 1;
+ }
+ if ((aux= (TABLE_LIST*) sl->table_list.first))
+ {
+ TABLE_LIST *next;
+ for (; aux; aux=next)
+ {
+ TABLE_LIST *cursor= *result;
+ if (skip_first && cursor)
+ cursor= cursor->next;
+ next= aux->next;
+ for ( ; cursor; cursor=cursor->next)
+ if (!strcmp(cursor->db,aux->db) &&
+ !strcmp(cursor->real_name,aux->real_name) &&
+ !strcmp(cursor->alias, aux->alias))
+ break;
+ if (!cursor)
+ {
+ /* Add not used table to the total table list */
+ if (!(cursor = (TABLE_LIST *) thd->memdup((char*) aux,
+ sizeof(*aux))))
+ {
+ send_error(&thd->net,0);
+ return 1;
+ }
+ *new_table_list= cursor;
+ new_table_list= &cursor->next;
+ *new_table_list=0; // end result list
+ }
+ else
+ aux->shared=1; // Mark that it's used twice
+ aux->table= my_reinterpret_cast(TABLE *) (cursor);
+ }
+ }
+ }
+ return 0;
+}
+
+
void add_join_on(TABLE_LIST *b,Item *expr)
{
- if (!b->on_expr)
- b->on_expr=expr;
- else
+ if (expr)
{
- // This only happens if you have both a right and left join
- b->on_expr=new Item_cond_and(b->on_expr,expr);
+ if (!b->on_expr)
+ b->on_expr=expr;
+ else
+ {
+ // This only happens if you have both a right and left join
+ b->on_expr=new Item_cond_and(b->on_expr,expr);
+ }
+ b->on_expr->top_level_item();
}
}
+/*
+ Mark that we have a NATURAL JOIN between two tables
+
+ SYNOPSIS
+ add_join_natural()
+ a Table to do normal join with
+ b Do normal join with this table
+
+ IMPLEMENTATION
+ This function just marks that table b should be joined with a.
+ The function setup_cond() will create in b->on_expr a list
+ of equal condition between all fields of the same name.
+
+ SELECT * FROM t1 NATURAL LEFT JOIN t2
+ <=>
+ SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
+*/
+
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b)
{
b->natural_join=a;
@@ -2847,43 +3599,67 @@ void add_join_natural(TABLE_LIST *a,TABLE_LIST *b)
/* Check if name is used in table list */
-static bool check_dup(THD *thd,const char *db,const char *name,
- TABLE_LIST *tables)
+bool check_dup(const char *db, const char *name, TABLE_LIST *tables)
{
- const char *thd_db=thd->db ? thd->db : any_db;
for (; tables ; tables=tables->next)
- if (!strcmp(name,tables->real_name) &&
- !strcmp(db ? db : thd_db, tables->db ? tables->db : thd_db))
+ if (!strcmp(name,tables->real_name) && !strcmp(db,tables->db))
return 1;
return 0;
}
-bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
+
+/*
+ Reload/resets privileges and the different caches
+*/
+
+bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
{
bool result=0;
-
+ bool error_already_sent=0;
select_errors=0; /* Write if more errors */
- // mysql_log.flush(); // Flush log
if (options & REFRESH_GRANT)
{
- acl_reload();
- grant_reload();
+ acl_reload(thd);
+ grant_reload(thd);
+ if (mqh_used)
+ reset_mqh(thd,(LEX_USER *) NULL,true);
}
if (options & REFRESH_LOG)
{
- mysql_log.new_file(0);
- mysql_update_log.new_file(0);
- mysql_bin_log.new_file(0);
- mysql_slow_log.new_file(0);
+ /*
+ Flush the normal query log, the update log, the binary log,
+ the slow query log, and the relay log (if it exists).
+ */
+ mysql_log.new_file(1);
+ mysql_update_log.new_file(1);
+ mysql_bin_log.new_file(1);
+ mysql_slow_log.new_file(1);
+ LOCK_ACTIVE_MI;
+ rotate_relay_log(active_mi);
+ UNLOCK_ACTIVE_MI;
+
if (ha_flush_logs())
result=1;
+ if (flush_error_log())
+ result=1;
+ }
+#ifdef HAVE_QUERY_CACHE
+ if (options & REFRESH_QUERY_CACHE_FREE)
+ {
+ query_cache.pack(); // FLUSH QUERY CACHE
+ options &= ~REFRESH_QUERY_CACHE; //don't flush all cache, just free memory
+ }
+ if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
+ {
+ query_cache.flush(); // RESET QUERY CACHE
}
+#endif /*HAVE_QUERY_CACHE*/
if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
{
- if ((options & REFRESH_READ_LOCK) && thd && ! thd->global_read_lock)
+ if ((options & REFRESH_READ_LOCK) && thd)
{
- thd->global_read_lock=1;
- thread_safe_increment(global_read_lock,&LOCK_open);
+ if (lock_global_read_lock(thd))
+ return 1;
}
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
}
@@ -2894,36 +3670,86 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
if (options & REFRESH_THREADS)
flush_thread_cache();
if (options & REFRESH_MASTER)
- reset_master();
- if (options & REFRESH_SLAVE)
- reset_slave();
-
- return result;
+ if (reset_master(thd))
+ result=1;
+#ifdef OPENSSL
+ if (options & REFRESH_DES_KEY_FILE)
+ {
+ if (des_key_file)
+ result=load_des_key_file(des_key_file);
+ }
+#endif
+ if (options & REFRESH_SLAVE)
+ {
+ LOCK_ACTIVE_MI;
+ if (reset_slave(thd, active_mi))
+ {
+ result=1;
+ /*
+ reset_slave() sends error itself.
+ If it didn't, one would either change reset_slave()'s prototype, to
+ pass *errorcode and *errmsg to it when it's called or
+ change reset_slave to use my_error() to register the error.
+ */
+ error_already_sent=1;
+ }
+ UNLOCK_ACTIVE_MI;
+ }
+ if (options & REFRESH_USER_RESOURCES)
+ reset_mqh(thd,(LEX_USER *) NULL);
+
+ if (thd && !error_already_sent)
+ {
+ if (result)
+ send_error(&thd->net,0);
+ else
+ send_ok(&thd->net);
+ }
+
+ return result;
}
+/*
+ kill on thread
+
+ SYNOPSIS
+ kill_one_thread()
+ thd Thread class
+ id Thread id
+
+ NOTES
+ This is written such that we have a short lock on LOCK_thread_count
+*/
+
void kill_one_thread(THD *thd, ulong id)
{
- VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
- I_List_iterator<THD> it(threads);
THD *tmp;
uint error=ER_NO_SUCH_THREAD;
+ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
+ I_List_iterator<THD> it(threads);
while ((tmp=it++))
{
if (tmp->thread_id == id)
{
- if ((thd->master_access & PROCESS_ACL) ||
- !strcmp(thd->user,tmp->user))
- {
- tmp->prepare_to_die();
- error=0;
- }
- else
- error=ER_KILL_DENIED_ERROR;
- break; // Found thread
+ pthread_mutex_lock(&tmp->LOCK_delete); // Lock from delete
+ break;
}
}
VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ if (tmp)
+ {
+ if ((thd->master_access & SUPER_ACL) ||
+ !strcmp(thd->user,tmp->user))
+ {
+ tmp->awake(1 /*prepare to die*/);
+ error=0;
+ }
+ else
+ error=ER_KILL_DENIED_ERROR;
+ pthread_mutex_unlock(&tmp->LOCK_delete);
+ }
+
if (!error)
send_ok(&thd->net);
else
@@ -2944,3 +3770,55 @@ static void refresh_status(void)
pthread_mutex_unlock(&LOCK_status);
pthread_mutex_unlock(&THR_LOCK_keycache);
}
+
+
+ /* If pointer is not a null pointer, append filename to it */
+
+static bool append_file_to_dir(THD *thd, const char **filename_ptr,
+ const char *table_name)
+{
+ char buff[FN_REFLEN],*ptr, *end;
+ if (!*filename_ptr)
+ return 0; // nothing to do
+
+ /* Check that the filename is not too long and it's a hard path */
+ if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
+ !test_if_hard_path(*filename_ptr))
+ {
+ my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
+ return 1;
+ }
+ /* Fix is using unix filename format on dos */
+ strmov(buff,*filename_ptr);
+ end=convert_dirname(buff, *filename_ptr, NullS);
+ if (!(ptr=thd->alloc((uint) (end-buff)+(uint) strlen(table_name)+1)))
+ return 1; // End of memory
+ *filename_ptr=ptr;
+ strxmov(ptr,buff,table_name,NullS);
+ return 0;
+}
+
+/*
+ Check if the select is a simple select (not an union)
+
+ SYNOPSIS
+ check_simple_select()
+
+ RETURN VALUES
+ 0 ok
+ 1 error ; In this case the error messege is sent to the client
+*/
+
+bool check_simple_select()
+{
+ THD *thd= current_thd;
+ if (thd->lex.select != &thd->lex.select_lex)
+ {
+ char command[80];
+ strmake(command, thd->lex.yylval->symbol.str,
+ min(thd->lex.yylval->symbol.length, sizeof(command)-1));
+ net_printf(&thd->net, ER_CANT_USE_OPTION_HERE, command);
+ return 1;
+ }
+ return 0;
+}
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index c4af966d145..c560b96a615 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -31,24 +31,26 @@ static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
{
- bool error=1, cerror;
+ bool error= 1;
TABLE_LIST *ren_table= 0;
DBUG_ENTER("mysql_rename_tables");
-
- /* Avoid problems with a rename on a table that we have locked or
- if the user is trying to to do this in a transcation context */
+
+ /*
+ Avoid problems with a rename on a table that we have locked or
+ if the user is trying to to do this in a transcation context
+ */
if (thd->locked_tables || thd->active_transaction())
{
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0));
DBUG_RETURN(1);
}
-
+
VOID(pthread_mutex_lock(&LOCK_open));
if (lock_table_names(thd, table_list))
goto err;
-
- error= 0;
+
+ error=0;
if ((ren_table=rename_tables(thd,table_list,0)))
{
/* Rename didn't succeed; rename back the tables in reverse order */
@@ -68,24 +70,20 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
for (table=table_list ;
table->next != ren_table ;
table=table->next->next) ;
- table=table->next->next; // Skipp error table
+ table=table->next->next; // Skip error table
/* Revert to old names */
rename_tables(thd, table, 1);
error= 1;
}
/* Lets hope this doesn't fail as the result will be messy */
- if ((cerror=ha_commit_rename(thd)))
- {
- my_error(ER_GET_ERRNO,MYF(0),cerror);
- error= 1;
- }
- else if (!error)
+ if (!error)
{
mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query);
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
send_ok(&thd->net);
@@ -114,19 +112,31 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
{
db_type table_type;
char name[FN_REFLEN];
- new_table=ren_table->next;
+ const char *new_alias, *old_alias;
+ new_table=ren_table->next;
+ if (lower_case_table_names == 2)
+ {
+ old_alias= ren_table->alias;
+ new_alias= new_table->alias;
+ }
+ else
+ {
+ old_alias= ren_table->real_name;
+ new_alias= new_table->real_name;
+ }
sprintf(name,"%s/%s/%s%s",mysql_data_home,
- new_table->db,new_table->real_name,
- reg_ext);
+ new_table->db, new_alias, reg_ext);
+ unpack_filename(name, name);
if (!access(name,F_OK))
{
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),name);
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_alias);
DBUG_RETURN(ren_table); // This can't be skipped
}
sprintf(name,"%s/%s/%s%s",mysql_data_home,
- ren_table->db,ren_table->real_name,
+ ren_table->db, old_alias,
reg_ext);
+ unpack_filename(name, name);
if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN)
{
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
@@ -134,8 +144,8 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
DBUG_RETURN(ren_table);
}
else if (mysql_rename_table(table_type,
- ren_table->db, ren_table->real_name,
- new_table->db, new_table->real_name))
+ ren_table->db, old_alias,
+ new_table->db, new_alias))
{
if (!skip_error)
DBUG_RETURN(ren_table);
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 2ffecf7f92a..c95cdc1b04e 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB & Sasha
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,52 +15,70 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
// Sasha Pachev <sasha@mysql.com> is currently in charge of this file
-// Do not mess with it without his permission!
#include "mysql_priv.h"
#include "sql_repl.h"
#include "sql_acl.h"
#include "log_event.h"
-#include <thr_alarm.h>
+#include "mini_client.h"
#include <my_dir.h>
+#include <assert.h>
extern const char* any_db;
-extern pthread_handler_decl(handle_slave,arg);
-#ifndef DBUG_OFF
int max_binlog_dump_events = 0; // unlimited
-bool opt_sporadic_binlog_dump_fail = 0;
+my_bool opt_sporadic_binlog_dump_fail = 0;
static int binlog_dump_count = 0;
-#endif
+
+int check_binlog_magic(IO_CACHE* log, const char** errmsg)
+{
+ char magic[4];
+ DBUG_ASSERT(my_b_tell(log) == 0);
+
+ if (my_b_read(log, (byte*) magic, sizeof(magic)))
+ {
+ *errmsg = "I/O error reading the header from the binary log";
+ sql_print_error("%s, errno=%d, io cache code=%d", *errmsg, my_errno,
+ log->error);
+ return 1;
+ }
+ if (memcmp(magic, BINLOG_MAGIC, sizeof(magic)))
+ {
+ *errmsg = "Binlog has bad magic number; It's not a binary log file that can be used by this version of MySQL";
+ return 1;
+ }
+ return 0;
+}
static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
- const char**errmsg)
+ ulonglong position, const char**errmsg)
{
- char header[LOG_EVENT_HEADER_LEN];
+ char header[LOG_EVENT_HEADER_LEN], buf[ROTATE_HEADER_LEN];
memset(header, 0, 4); // when does not matter
header[EVENT_TYPE_OFFSET] = ROTATE_EVENT;
- char* p = strrchr(log_file_name, FN_LIBCHAR);
- // find the last slash
- if(p)
- p++;
- else
- p = log_file_name;
+ char* p = log_file_name+dirname_length(log_file_name);
uint ident_len = (uint) strlen(p);
- ulong event_len = ident_len + sizeof(header);
- int4store(header + EVENT_TYPE_OFFSET + 1, server_id);
+ ulong event_len = ident_len + ROTATE_EVENT_OVERHEAD;
+ int4store(header + SERVER_ID_OFFSET, server_id);
int4store(header + EVENT_LEN_OFFSET, event_len);
+ int2store(header + FLAGS_OFFSET, 0);
+
+ // TODO: check what problems this may cause and fix them
+ int4store(header + LOG_POS_OFFSET, 0);
+
packet->append(header, sizeof(header));
+ int8store(buf+R_POS_OFFSET,position);
+ packet->append(buf, ROTATE_HEADER_LEN);
packet->append(p,ident_len);
- if(my_net_write(net, (char*)packet->ptr(), packet->length()))
- {
- *errmsg = "failed on my_net_write()";
- return -1;
- }
+ if (my_net_write(net, (char*)packet->ptr(), packet->length()))
+ {
+ *errmsg = "failed on my_net_write()";
+ return -1;
+ }
return 0;
}
-
static int send_file(THD *thd)
{
NET* net = &thd->net;
@@ -72,38 +90,41 @@ static int send_file(THD *thd)
char buf[IO_SIZE]; // It's safe to alloc this
DBUG_ENTER("send_file");
- // the client might be slow loading the data, give him wait_timeout to do
- // the job
- old_timeout = thd->net.timeout;
- thd->net.timeout = thd->inactive_timeout;
-
- // we need net_flush here because the client will not know it needs to send
- // us the file name until it has processed the load event entry
+ /*
+ The client might be slow loading the data, give him wait_timeout to do
+ the job
+ */
+ old_timeout = thd->net.read_timeout;
+ thd->net.read_timeout = thd->variables.net_wait_timeout;
+
+ /*
+ We need net_flush here because the client will not know it needs to send
+ us the file name until it has processed the load event entry
+ */
if (net_flush(net) || (packet_len = my_net_read(net)) == packet_error)
{
- errmsg = "Failed reading file name";
+ errmsg = "while reading file name";
goto err;
}
- *((char*)net->read_pos + packet_len) = 0; // terminate with \0
- //for fn_format
- fn_format(fname, (char*)net->read_pos + 1, "", "", 4);
+ // terminate with \0 for fn_format
+ *((char*)net->read_pos + packet_len) = 0;
+ fn_format(fname, (char*) net->read_pos + 1, "", "", 4);
// this is needed to make replicate-ignore-db
if (!strcmp(fname,"/dev/null"))
goto end;
- if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0)
+ if ((fd = my_open(fname, O_RDONLY, MYF(0))) < 0)
{
- errmsg = "Failed on my_open()";
+ errmsg = "on open of file";
goto err;
}
- while ((bytes = (int) my_read(fd, (byte*) buf, IO_SIZE,
- MYF(MY_WME))) > 0)
+ while ((bytes = (int) my_read(fd, (byte*) buf, IO_SIZE, MYF(0))) > 0)
{
if (my_net_write(net, buf, bytes))
{
- errmsg = "Failed on my_net_write()";
+ errmsg = "while writing data to client";
goto err;
}
}
@@ -112,18 +133,18 @@ static int send_file(THD *thd)
if (my_net_write(net, "", 0) || net_flush(net) ||
(my_net_read(net) == packet_error))
{
- errmsg = "failed negotiating file transfer close";
+ errmsg = "while negotiating file transfer close";
goto err;
}
error = 0;
err:
- thd->net.timeout = old_timeout;
- if(fd >= 0)
- (void) my_close(fd, MYF(MY_WME));
+ thd->net.read_timeout = old_timeout;
+ if (fd >= 0)
+ (void) my_close(fd, MYF(0));
if (errmsg)
{
- sql_print_error("failed in send_file() : %s", errmsg);
+ sql_print_error("Failed in send_file() %s", errmsg);
DBUG_PRINT("error", (errmsg));
}
DBUG_RETURN(error);
@@ -131,61 +152,86 @@ static int send_file(THD *thd)
File open_binlog(IO_CACHE *log, const char *log_file_name,
- const char **errmsg)
+ const char **errmsg)
{
File file;
- char magic[4];
- if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0 ||
- init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
- MYF(MY_WME)))
+ DBUG_ENTER("open_binlog");
+
+ if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0)
{
- *errmsg = "Could not open log file"; // This will not be sent
+ sql_print_error("Failed to open log (\
+file '%s', errno %d)", log_file_name, my_errno);
+ *errmsg = "Could not open log file"; // This will not be sent
goto err;
}
-
- if (my_b_read(log, (byte*) magic, sizeof(magic)))
+ if (init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
+ MYF(MY_WME | MY_DONT_CHECK_FILESIZE)))
{
- *errmsg = "I/O error reading binlog magic number";
+ sql_print_error("Failed to create a cache on log (\
+file '%s')", log_file_name);
+ *errmsg = "Could not open log file"; // This will not be sent
goto err;
}
- if (memcmp(magic, BINLOG_MAGIC, 4))
- {
- *errmsg = "Binlog has bad magic number, fire your magician";
+ if (check_binlog_magic(log,errmsg))
goto err;
- }
- return file;
+ DBUG_RETURN(file);
err:
- if (file > 0)
+ if (file >= 0)
+ {
my_close(file,MYF(0));
- end_io_cache(log);
- return -1;
+ end_io_cache(log);
+ }
+ DBUG_RETURN(-1);
}
+/*
+ Adjust the position pointer in the binary log file for all running slaves
+
+ SYNOPSIS
+ adjust_linfo_offsets()
+ purge_offset Number of bytes removed from start of log index file
+
+ NOTES
+ - This is called when doing a PURGE when we delete lines from the
+ index log file
+
+ REQUIREMENTS
+ - Before calling this function, we have to ensure that no threads are
+ using any binary log file before purge_offset.a
+
+ TODO
+ - Inform the slave threads that they should sync the position
+ in the binary log file with flush_relay_log_info.
+ Now they sync is done for next read.
+*/
+
void adjust_linfo_offsets(my_off_t purge_offset)
{
THD *tmp;
-
+
pthread_mutex_lock(&LOCK_thread_count);
I_List_iterator<THD> it(threads);
-
- while((tmp=it++))
- {
- LOG_INFO* linfo;
- if((linfo = tmp->current_linfo))
- {
- pthread_mutex_lock(&linfo->lock);
- // no big deal if we just started reading the log
- // nothing to adjust
- if(linfo->index_file_offset < purge_offset)
- linfo->fatal = (linfo->index_file_offset != 0);
- else
- linfo->index_file_offset -= purge_offset;
- pthread_mutex_unlock(&linfo->lock);
- }
- }
+ while ((tmp=it++))
+ {
+ LOG_INFO* linfo;
+ if ((linfo = tmp->current_linfo))
+ {
+ pthread_mutex_lock(&linfo->lock);
+ /*
+ Index file offset can be less that purge offset only if
+ we just started reading the index file. In that case
+ we have nothing to adjust
+ */
+ if (linfo->index_file_offset < purge_offset)
+ linfo->fatal = (linfo->index_file_offset != 0);
+ else
+ linfo->index_file_offset -= purge_offset;
+ pthread_mutex_unlock(&linfo->lock);
+ }
+ }
pthread_mutex_unlock(&LOCK_thread_count);
}
@@ -195,21 +241,22 @@ bool log_in_use(const char* log_name)
int log_name_len = strlen(log_name) + 1;
THD *tmp;
bool result = 0;
-
+
pthread_mutex_lock(&LOCK_thread_count);
I_List_iterator<THD> it(threads);
-
- while((tmp=it++))
+
+ while ((tmp=it++))
+ {
+ LOG_INFO* linfo;
+ if ((linfo = tmp->current_linfo))
{
- LOG_INFO* linfo;
- if((linfo = tmp->current_linfo))
- {
- pthread_mutex_lock(&linfo->lock);
- result = !memcmp(log_name, linfo->log_file_name, log_name_len);
- pthread_mutex_unlock(&linfo->lock);
- if(result) break;
- }
- }
+ pthread_mutex_lock(&linfo->lock);
+ result = !memcmp(log_name, linfo->log_file_name, log_name_len);
+ pthread_mutex_unlock(&linfo->lock);
+ if (result)
+ break;
+ }
+ }
pthread_mutex_unlock(&LOCK_thread_count);
return result;
@@ -219,44 +266,50 @@ bool log_in_use(const char* log_name)
int purge_master_logs(THD* thd, const char* to_log)
{
char search_file_name[FN_REFLEN];
- mysql_bin_log.make_log_name(search_file_name, to_log);
- int res = mysql_bin_log.purge_logs(thd, search_file_name);
const char* errmsg = 0;
- switch(res)
- {
- case 0: break;
- case LOG_INFO_EOF: errmsg = "Target log not found in binlog index"; break;
- case LOG_INFO_IO: errmsg = "I/O error reading log index file"; break;
- case LOG_INFO_INVALID: errmsg = "Server configuration does not permit \
+ int res;
+
+ if (!mysql_bin_log.is_open())
+ goto end;
+
+ mysql_bin_log.make_log_name(search_file_name, to_log);
+ res = mysql_bin_log.purge_logs(thd, search_file_name);
+
+ switch(res) {
+ case 0: break;
+ case LOG_INFO_EOF: errmsg = "Target log not found in binlog index"; break;
+ case LOG_INFO_IO: errmsg = "I/O error reading log index file"; break;
+ case LOG_INFO_INVALID: errmsg = "Server configuration does not permit \
binlog purge"; break;
- case LOG_INFO_SEEK: errmsg = "Failed on fseek()"; break;
- case LOG_INFO_PURGE_NO_ROTATE: errmsg = "Cannot purge unrotatable log";
- break;
- case LOG_INFO_MEM: errmsg = "Out of memory"; break;
- case LOG_INFO_FATAL: errmsg = "Fatal error during purge"; break;
- case LOG_INFO_IN_USE: errmsg = "A purgeable log is in use, will not purge";
- break;
- default:
- errmsg = "Unknown error during purge"; break;
- }
-
- if(errmsg)
- {
- send_error(&thd->net, 0, errmsg);
- return 1;
- }
- else
- send_ok(&thd->net);
-
+ case LOG_INFO_SEEK: errmsg = "Failed on fseek()"; break;
+ case LOG_INFO_MEM: errmsg = "Out of memory"; break;
+ case LOG_INFO_FATAL: errmsg = "Fatal error during purge"; break;
+ case LOG_INFO_IN_USE: errmsg = "A purgeable log is in use, will not purge";
+ break;
+ default: errmsg = "Unknown error during purge"; break;
+ }
+
+ if (errmsg)
+ {
+ send_error(&thd->net, 0, errmsg);
+ return 1;
+ }
+
+end:
+ send_ok(&thd->net);
return 0;
}
+/*
+ TODO: Clean up loop to only have one call to send_file()
+*/
-void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
+void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
+ ushort flags)
{
LOG_INFO linfo;
char *log_file_name = linfo.log_file_name;
- char search_file_name[FN_REFLEN];
+ char search_file_name[FN_REFLEN], *name;
IO_CACHE log;
File file = -1;
String* packet = &thd->packet;
@@ -265,112 +318,143 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
NET* net = &thd->net;
#ifndef DBUG_OFF
int left_events = max_binlog_dump_events;
-#endif
+#endif
DBUG_ENTER("mysql_binlog_send");
+ DBUG_PRINT("enter",("log_ident: '%s' pos: %ld", log_ident, (long) pos));
+
bzero((char*) &log,sizeof(log));
#ifndef DBUG_OFF
if (opt_sporadic_binlog_dump_fail && (binlog_dump_count++ % 2))
{
errmsg = "Master failed COM_BINLOG_DUMP to test if slave can recover";
+ my_errno= ER_UNKNOWN_ERROR;
goto err;
}
-#endif
-
+#endif
- if(!mysql_bin_log.is_open())
+ if (!mysql_bin_log.is_open())
{
errmsg = "Binary log is not open";
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
}
- if(!server_id_supplied)
- {
- errmsg = "Misconfigured master - server id was not set";
- goto err;
- }
-
+ if (!server_id_supplied)
+ {
+ errmsg = "Misconfigured master - server id was not set";
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
+ goto err;
+ }
+
+ name=search_file_name;
if (log_ident[0])
mysql_bin_log.make_log_name(search_file_name, log_ident);
else
- search_file_name[0] = 0;
-
+ name=0; // Find first log
+
linfo.index_file_offset = 0;
thd->current_linfo = &linfo;
- if (mysql_bin_log.find_first_log(&linfo, search_file_name))
+ if (mysql_bin_log.find_log_pos(&linfo, name, 1))
{
- errmsg = "Could not find first log";
+ errmsg = "Could not find first log file name in binary log index file";
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
}
if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0)
+ {
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
-
- if (pos < 4)
+ }
+ if (pos < BIN_LOG_HEADER_SIZE || pos > my_b_filelength(&log))
{
- errmsg = "Client requested master to start repliction from impossible position.\n";
+ errmsg= "Client requested master to start replication from \
+impossible position";
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
}
-
- my_b_seek(&log, pos); // Seek will done on next read
- packet->length(0);
- packet->append("\0", 1);
- // we need to start a packet with something other than 255
- // to distiquish it from error
- // tell the client log name with a fake rotate_event
- // if we are at the start of the log
- if(pos == 4)
+ my_b_seek(&log, pos); // Seek will done on next read
+ /*
+ We need to start a packet with something other than 255
+ to distiquish it from error
+ */
+ packet->set("\0", 1);
+
+ /*
+ Before 4.0.14 we called fake_rotate_event below only if
+ (pos == BIN_LOG_HEADER_SIZE), because if this is false then the slave
+ already knows the binlog's name.
+ Now we always call fake_rotate_event; if the slave already knew the log's
+ name (ex: CHANGE MASTER TO MASTER_LOG_FILE=...) this is useless but does not
+ harm much. It is nice for 3.23 (>=.58) slaves which test Rotate events
+ to see if the master is 4.0 (then they choose to stop because they can't
+ replicate 4.0); by always calling fake_rotate_event we are sure that 3.23.58
+ and newer will detect the problem as soon as replication starts (BUG#198).
+ Always calling fake_rotate_event makes sending of normal
+ (=from-binlog) Rotate events a priori unneeded, but it is not so simple: the
+ 2 Rotate events are not equivalent, the normal one is before the Stop event,
+ the fake one is after. If we don't send the normal one, then the Stop event
+ will be interpreted (by existing 4.0 slaves) as "the master stopped", which
+ is wrong. So for safety, given that we want minimum modification of 4.0, we
+ send the normal and fake Rotates.
+ */
+ if (fake_rotate_event(net, packet, log_file_name, pos, &errmsg))
{
- if (fake_rotate_event(net, packet, log_file_name, &errmsg))
- goto err;
- packet->length(0);
- packet->append("\0", 1);
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
+ goto err;
}
+ packet->set("\0", 1);
while (!net->error && net->vio != 0 && !thd->killed)
{
pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
-
+
while (!(error = Log_event::read_log_event(&log, packet, log_lock)))
{
#ifndef DBUG_OFF
- if(max_binlog_dump_events && !left_events--)
+ if (max_binlog_dump_events && !left_events--)
{
net_flush(net);
errmsg = "Debugging binlog dump abort";
+ my_errno= ER_UNKNOWN_ERROR;
goto err;
}
-#endif
+#endif
if (my_net_write(net, (char*)packet->ptr(), packet->length()) )
{
errmsg = "Failed on my_net_write()";
+ my_errno= ER_UNKNOWN_ERROR;
goto err;
}
DBUG_PRINT("info", ("log event code %d",
(*packet)[LOG_EVENT_OFFSET+1] ));
if ((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
{
- if(send_file(thd))
+ if (send_file(thd))
{
errmsg = "failed in send_file()";
+ my_errno= ER_UNKNOWN_ERROR;
goto err;
}
}
- packet->length(0);
- packet->append("\0",1);
+ packet->set("\0", 1);
}
-
+ /*
+ TODO: now that we are logging the offset, check to make sure
+ the recorded offset and the actual match
+ */
if (error != LOG_READ_EOF)
{
- switch(error)
- {
- case LOG_READ_BOGUS:
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
+ switch (error) {
+ case LOG_READ_BOGUS:
errmsg = "bogus data in log event";
break;
- case LOG_READ_TOO_LARGE:
- errmsg = "log event entry exceeded max_allowed_packet -\
- increase max_allowed_packet on master";
+ case LOG_READ_TOO_LARGE:
+ errmsg = "log event entry exceeded max_allowed_packet; \
+Increase max_allowed_packet on master";
break;
case LOG_READ_IO:
errmsg = "I/O error reading log event";
@@ -388,100 +472,109 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
goto err;
}
- if(!(flags & BINLOG_DUMP_NON_BLOCK) &&
+ if (!(flags & BINLOG_DUMP_NON_BLOCK) &&
mysql_bin_log.is_active(log_file_name))
- // block until there is more data in the log
- // unless non-blocking mode requested
{
- if(net_flush(net))
+ /*
+ Block until there is more data in the log
+ */
+ if (net_flush(net))
{
errmsg = "failed on net_flush()";
+ my_errno= ER_UNKNOWN_ERROR;
goto err;
}
- // we may have missed the update broadcast from the log
- // that has just happened, let's try to catch it if it did
- // if we did not miss anything, we just wait for other threads
- // to signal us
+ /*
+ We may have missed the update broadcast from the log
+ that has just happened, let's try to catch it if it did.
+ If we did not miss anything, we just wait for other threads
+ to signal us.
+ */
{
log.error=0;
-
- // tell the kill thread how to wake us up
- thd->mysys_var->current_mutex = log_lock;
- thd->mysys_var->current_cond = &COND_binlog_update;
- const char* proc_info = thd->proc_info;
- thd->proc_info = "Slave connection: waiting for binlog update";
-
bool read_packet = 0, fatal_error = 0;
#ifndef DBUG_OFF
- if(max_binlog_dump_events && !left_events--)
+ if (max_binlog_dump_events && !left_events--)
{
- net_flush(net);
errmsg = "Debugging binlog dump abort";
+ my_errno= ER_UNKNOWN_ERROR;
goto err;
}
-#endif
+#endif
+
+ /*
+ No one will update the log while we are reading
+ now, but we'll be quick and just read one record
+
+ TODO:
+ Add an counter that is incremented for each time we update
+ the binary log. We can avoid the following read if the counter
+ has not been updated since last read.
+ */
- // no one will update the log while we are reading
- // now, but we'll be quick and just read one record
pthread_mutex_lock(log_lock);
- switch (Log_event::read_log_event(&log, packet, (pthread_mutex_t*) 0))
- {
+ switch (Log_event::read_log_event(&log, packet, (pthread_mutex_t*)0)) {
case 0:
+ /* we read successfully, so we'll need to send it to the slave */
+ pthread_mutex_unlock(log_lock);
read_packet = 1;
- // we read successfully, so we'll need to send it to the
- // slave
break;
+
case LOG_READ_EOF:
- DBUG_PRINT("wait",("waiting for data on binary log"));
- if (thd->server_id==0)
+ DBUG_PRINT("wait",("waiting for data in binary log"));
+ if (thd->server_id==0) // for mysqlbinlog (mysqlbinlog.server_id==0)
{
pthread_mutex_unlock(log_lock);
goto end;
}
if (!thd->killed)
- pthread_cond_wait(&COND_binlog_update, log_lock);
+ {
+ /* Note that the following call unlocks lock_log */
+ mysql_bin_log.wait_for_update(thd, 0);
+ }
+ else
+ pthread_mutex_unlock(log_lock);
+ DBUG_PRINT("wait",("binary log received update"));
break;
default:
+ pthread_mutex_unlock(log_lock);
fatal_error = 1;
break;
}
- pthread_mutex_unlock(log_lock);
-
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- thd->proc_info= proc_info;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
- if(read_packet)
+ if (read_packet)
{
- thd->proc_info = "sending update to slave";
- if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
+ thd->proc_info = "Sending binlog event to slave";
+ if (my_net_write(net, (char*)packet->ptr(), packet->length()) )
{
errmsg = "Failed on my_net_write()";
+ my_errno= ER_UNKNOWN_ERROR;
goto err;
}
- if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
+ if ((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
{
- if(send_file(thd))
+ if (send_file(thd))
{
errmsg = "failed in send_file()";
+ my_errno= ER_UNKNOWN_ERROR;
goto err;
}
}
- packet->length(0);
- packet->append("\0",1);
- // no need to net_flush because we will get to flush later when
- // we hit EOF pretty quick
+ packet->set("\0", 1);
+ /*
+ No need to net_flush because we will get to flush later when
+ we hit EOF pretty quick
+ */
}
- if(fatal_error)
+ if (fatal_error)
{
errmsg = "error reading log entry";
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
}
log.error=0;
@@ -491,9 +584,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
{
bool loop_breaker = 0;
// need this to break out of the for loop from switch
- thd->proc_info = "switching to next log";
- switch(mysql_bin_log.find_next_log(&linfo))
- {
+ thd->proc_info = "Finished reading one binlog; switching to next binlog";
+ switch (mysql_bin_log.find_next_log(&linfo, 1)) {
case LOG_INFO_EOF:
loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
break;
@@ -501,21 +593,26 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
break;
default:
errmsg = "could not find next log";
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
}
- if(loop_breaker)
+ if (loop_breaker)
break;
end_io_cache(&log);
(void) my_close(file, MYF(MY_WME));
-
- // fake Rotate_log event just in case it did not make it to the log
- // otherwise the slave make get confused about the offset
+
+ /*
+ Even if the previous log contained a Rotate_log_event, we still fake
+ one.
+ */
if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 ||
- fake_rotate_event(net, packet, log_file_name, &errmsg))
+ fake_rotate_event(net, packet, log_file_name, BIN_LOG_HEADER_SIZE, &errmsg))
+ {
+ my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
-
+ }
packet->length(0);
packet->append("\0",1);
}
@@ -524,22 +621,25 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
end:
end_io_cache(&log);
(void)my_close(file, MYF(MY_WME));
-
+
send_eof(&thd->net);
- thd->proc_info = "waiting to finalize termination";
+ thd->proc_info = "Waiting to finalize termination";
pthread_mutex_lock(&LOCK_thread_count);
thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count);
DBUG_VOID_RETURN;
+
err:
- thd->proc_info = "waiting to finalize termination";
+ thd->proc_info = "Waiting to finalize termination";
end_io_cache(&log);
+ /*
+ Exclude iteration through thread list
+ this is needed for purge_logs() - it will iterate through
+ thread list and update thd->current_linfo->index_file_offset
+ this mutex will make sure that it never tried to update our linfo
+ after we return from this stack frame
+ */
pthread_mutex_lock(&LOCK_thread_count);
- // exclude iteration through thread list
- // this is needed for purge_logs() - it will iterate through
- // thread list and update thd->current_linfo->index_file_offset
- // this mutex will make sure that it never tried to update our linfo
- // after we return from this stack frame
thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count);
if (file >= 0)
@@ -548,251 +648,512 @@ err:
DBUG_VOID_RETURN;
}
-int start_slave(THD* thd , bool net_report)
+int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
{
- if(!thd) thd = current_thd;
- NET* net = &thd->net;
int slave_errno = 0;
- if (check_access(thd, PROCESS_ACL, any_db))
- return 1;
- pthread_mutex_lock(&LOCK_slave);
- if(!slave_running)
- {
- if(init_master_info(&glob_mi))
- slave_errno = ER_MASTER_INFO;
- else if(server_id_supplied && *glob_mi.host)
- {
- pthread_t hThread;
- if(pthread_create(&hThread, &connection_attrib, handle_slave, 0))
- {
- slave_errno = ER_SLAVE_THREAD;
- }
- while(!slave_running) // slave might already be running by now
- pthread_cond_wait(&COND_slave_start, &LOCK_slave);
- }
- else
- slave_errno = ER_BAD_SLAVE;
- }
+ if (!thd) thd = current_thd;
+ NET* net = &thd->net;
+ int thread_mask;
+ DBUG_ENTER("start_slave");
+
+ if (check_access(thd, SUPER_ACL, any_db))
+ DBUG_RETURN(1);
+ lock_slave_threads(mi); // this allows us to cleanly read slave_running
+ init_thread_mask(&thread_mask,mi,1 /* inverse */);
+ if (thd->lex.slave_thd_opt)
+ thread_mask &= thd->lex.slave_thd_opt;
+ if (thread_mask)
+ {
+ if (init_master_info(mi,master_info_file,relay_log_info_file, 0))
+ slave_errno=ER_MASTER_INFO;
+ else if (server_id_supplied && *mi->host)
+ slave_errno = start_slave_threads(0 /*no mutex */,
+ 1 /* wait for start */,
+ mi,
+ master_info_file,relay_log_info_file,
+ thread_mask);
+ else
+ slave_errno = ER_BAD_SLAVE;
+ }
else
slave_errno = ER_SLAVE_MUST_STOP;
-
- pthread_mutex_unlock(&LOCK_slave);
- if(slave_errno)
- {
- if(net_report) send_error(net, slave_errno);
- return 1;
- }
- else if(net_report)
+
+ unlock_slave_threads(mi);
+
+ if (slave_errno)
+ {
+ if (net_report)
+ send_error(net, slave_errno);
+ DBUG_RETURN(1);
+ }
+ else if (net_report)
send_ok(net);
- return 0;
+ DBUG_RETURN(0);
}
-int stop_slave(THD* thd, bool net_report )
+int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
{
- if(!thd) thd = current_thd;
- NET* net = &thd->net;
int slave_errno = 0;
-
- if (check_access(thd, PROCESS_ACL, any_db))
+ if (!thd) thd = current_thd;
+ NET* net = &thd->net;
+
+ if (check_access(thd, SUPER_ACL, any_db))
return 1;
+ thd->proc_info = "Killing slave";
+ int thread_mask;
+ lock_slave_threads(mi);
+ init_thread_mask(&thread_mask,mi,0 /* not inverse*/);
+ if (thd->lex.slave_thd_opt)
+ thread_mask &= thd->lex.slave_thd_opt;
+ slave_errno = (thread_mask) ?
+ terminate_slave_threads(mi,thread_mask,
+ 1 /*skip lock */) : ER_SLAVE_NOT_RUNNING;
+ unlock_slave_threads(mi);
+ thd->proc_info = 0;
- pthread_mutex_lock(&LOCK_slave);
- if (slave_running)
+ if (slave_errno)
{
- abort_slave = 1;
- KICK_SLAVE;
- // do not abort the slave in the middle of a query, so we do not set
- // thd->killed for the slave thread
- thd->proc_info = "waiting for slave to die";
- while(slave_running)
- {
- /* there is a small chance that slave thread might miss the first
- alarm. To protect againts it, resend the signal until it reacts
- */
-
- struct timespec abstime;
-#ifdef HAVE_TIMESPEC_TS_SEC
- abstime.ts_sec=time(NULL)+2;
- abstime.ts_nsec=0;
-#elif defined(__WIN__)
- abstime.tv_sec=time((time_t*) 0)+2;
- abstime.tv_nsec=0;
-#else
- struct timeval tv;
- gettimeofday(&tv,0);
- abstime.tv_sec=tv.tv_sec+2;
- abstime.tv_nsec=tv.tv_usec*1000;
-#endif
- pthread_cond_timedwait(&COND_slave_stopped, &LOCK_slave, &abstime);
- if (slave_running)
- KICK_SLAVE;
- }
+ if (net_report)
+ send_error(net, slave_errno);
+ return 1;
}
- else
- slave_errno = ER_SLAVE_NOT_RUNNING;
-
- pthread_mutex_unlock(&LOCK_slave);
- thd->proc_info = 0;
-
- if(slave_errno)
- {
- if(net_report) send_error(net, slave_errno);
- return 1;
- }
- else if(net_report)
+ else if (net_report)
send_ok(net);
return 0;
}
-void reset_slave()
+
+/*
+ Remove all relay logs and start replication from the start
+
+ SYNOPSIS
+ reset_slave()
+ thd Thread handler
+ mi Master info for the slave
+
+
+ NOTES
+ We don't send ok in this functions as this is called from
+ reload_acl_and_cache() which may have done other tasks, which may
+ have failed for which we want to send and error.
+
+ RETURN
+ 0 ok
+ 1 error
+ In this case error is sent to the client with send_error()
+*/
+
+
+int reset_slave(THD *thd, MASTER_INFO* mi)
{
MY_STAT stat_area;
char fname[FN_REFLEN];
- bool slave_was_running ;
-
- pthread_mutex_lock(&LOCK_slave);
- if((slave_was_running = slave_running))
- {
- pthread_mutex_unlock(&LOCK_slave);
- stop_slave(0,0);
- }
- else
- pthread_mutex_unlock(&LOCK_slave);
+ int thread_mask= 0, error= 0;
+ uint sql_errno=0;
+ const char* errmsg=0;
+ DBUG_ENTER("reset_slave");
+
+ lock_slave_threads(mi);
+ init_thread_mask(&thread_mask,mi,0 /* not inverse */);
+ if (thread_mask) // We refuse if any slave thread is running
+ {
+ sql_errno= ER_SLAVE_MUST_STOP;
+ error=1;
+ goto err;
+ }
+ //delete relay logs, clear relay log coordinates
+ if ((error= purge_relay_logs(&mi->rli, thd,
+ 1 /* just reset */,
+ &errmsg)))
+ goto err;
- end_master_info(&glob_mi);
- fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
- if(my_stat(fname, &stat_area, MYF(0)))
- if(my_delete(fname, MYF(MY_WME)))
- return;
- if(slave_was_running)
- start_slave(0,0);
+ /*
+ Clear master's log coordinates and reset host/user/etc to the values
+ specified in mysqld's options (only for good display of SHOW SLAVE STATUS;
+ next init_master_info() (in start_slave() for example) would have set them
+ the same way; but here this is for the case where the user does SHOW SLAVE
+ STATUS; before doing START SLAVE;
+ */
+ init_master_info_with_options(mi);
+ clear_last_slave_error(&mi->rli);
+ //close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0
+ end_master_info(mi);
+ //and delete these two files
+ fn_format(fname, master_info_file, mysql_data_home, "", 4+32);
+ if (my_stat(fname, &stat_area, MYF(0)) && my_delete(fname, MYF(MY_WME)))
+ {
+ error=1;
+ goto err;
+ }
+ fn_format(fname, relay_log_info_file, mysql_data_home, "", 4+32);
+ if (my_stat(fname, &stat_area, MYF(0)) && my_delete(fname, MYF(MY_WME)))
+ {
+ error=1;
+ goto err;
+ }
+
+err:
+ unlock_slave_threads(mi);
+ if (thd && error)
+ send_error(&thd->net, sql_errno, errmsg);
+ DBUG_RETURN(error);
}
+/*
+
+ Kill all Binlog_dump threads which previously talked to the same slave
+ ("same" means with the same server id). Indeed, if the slave stops, if the
+ Binlog_dump thread is waiting (pthread_cond_wait) for binlog update, then it
+ will keep existing until a query is written to the binlog. If the master is
+ idle, then this could last long, and if the slave reconnects, we could have 2
+ Binlog_dump threads in SHOW PROCESSLIST, until a query is written to the
+ binlog. To avoid this, when the slave reconnects and sends COM_BINLOG_DUMP,
+ the master kills any existing thread with the slave's server id (if this id is
+ not zero; it will be true for real slaves, but false for mysqlbinlog when it
+ sends COM_BINLOG_DUMP to get a remote binlog dump).
+
+ SYNOPSIS
+ kill_zombie_dump_threads()
+ slave_server_id the slave's server id
+
+*/
+
+
void kill_zombie_dump_threads(uint32 slave_server_id)
{
pthread_mutex_lock(&LOCK_thread_count);
I_List_iterator<THD> it(threads);
THD *tmp;
- while((tmp=it++))
+ while ((tmp=it++))
+ {
+ if (tmp->command == COM_BINLOG_DUMP &&
+ tmp->server_id == slave_server_id)
{
- if(tmp->command == COM_BINLOG_DUMP &&
- tmp->server_id == slave_server_id)
- {
- // here we do not call kill_one_thread()
- // it will be slow because it will iterate through the list
- // again. Plus it double-locks LOCK_thread_count, which
- // make safe_mutex complain and abort
- // so we just to our own thread murder
-
- thr_alarm_kill(tmp->real_id);
- tmp->killed = 1;
- tmp->mysys_var->abort = 1;
- pthread_mutex_lock(&tmp->mysys_var->mutex);
- if(tmp->mysys_var->current_cond)
- {
- pthread_mutex_lock(tmp->mysys_var->current_mutex);
- pthread_cond_broadcast(tmp->mysys_var->current_cond);
- pthread_mutex_unlock(tmp->mysys_var->current_mutex);
- }
- pthread_mutex_unlock(&tmp->mysys_var->mutex);
- }
- }
-
+ pthread_mutex_lock(&tmp->LOCK_delete); // Lock from delete
+ break;
+ }
+ }
pthread_mutex_unlock(&LOCK_thread_count);
+ if (tmp)
+ {
+ /*
+ Here we do not call kill_one_thread() as
+ it will be slow because it will iterate through the list
+ again. We just to do kill the thread ourselves.
+ */
+ tmp->awake(1/*prepare to die*/);
+ pthread_mutex_unlock(&tmp->LOCK_delete);
+ }
}
-int change_master(THD* thd)
+
+int change_master(THD* thd, MASTER_INFO* mi)
{
- bool slave_was_running;
- // kill slave thread
- pthread_mutex_lock(&LOCK_slave);
- if((slave_was_running = slave_running))
- {
- abort_slave = 1;
- KICK_SLAVE;
- thd->proc_info = "waiting for slave to die";
- while(slave_running)
- pthread_cond_wait(&COND_slave_stopped, &LOCK_slave); // wait until done
- }
- pthread_mutex_unlock(&LOCK_slave);
- thd->proc_info = "changing master";
+ int thread_mask;
+ const char* errmsg= 0;
+ bool need_relay_log_purge= 1;
+ DBUG_ENTER("change_master");
+
+ lock_slave_threads(mi);
+ init_thread_mask(&thread_mask,mi,0 /*not inverse*/);
+ if (thread_mask) // We refuse if any slave thread is running
+ {
+ net_printf(&thd->net,ER_SLAVE_MUST_STOP);
+ unlock_slave_threads(mi);
+ DBUG_RETURN(1);
+ }
+
+ thd->proc_info = "Changing master";
LEX_MASTER_INFO* lex_mi = &thd->lex.mi;
+ // TODO: see if needs re-write
+ if (init_master_info(mi, master_info_file, relay_log_info_file, 0))
+ {
+ send_error(&thd->net, ER_MASTER_INFO);
+ unlock_slave_threads(mi);
+ DBUG_RETURN(1);
+ }
- if(init_master_info(&glob_mi))
- {
- send_error(&thd->net, 0, "Could not initialize master info");
- return 1;
- }
-
- pthread_mutex_lock(&glob_mi.lock);
- if((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
- {
- // if we change host or port, we must reset the postion
- glob_mi.log_file_name[0] = 0;
- glob_mi.pos = 4; // skip magic number
- glob_mi.pending = 0;
- }
+ /*
+ Data lock not needed since we have already stopped the running threads,
+ and we have the hold on the run locks which will keep all threads that
+ could possibly modify the data structures from running
+ */
+
+ /*
+ If the user specified host or port without binlog or position,
+ reset binlog's name to FIRST and position to 4.
+ */
- if(lex_mi->log_file_name)
- strmake(glob_mi.log_file_name, lex_mi->log_file_name,
- sizeof(glob_mi.log_file_name));
- if(lex_mi->pos)
+ if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
{
- glob_mi.pos = lex_mi->pos;
- glob_mi.pending = 0;
+ mi->master_log_name[0] = 0;
+ mi->master_log_pos= BIN_LOG_HEADER_SIZE;
+ mi->rli.pending = 0;
}
-
- if(lex_mi->host)
+
+ if (lex_mi->log_file_name)
+ strmake(mi->master_log_name, lex_mi->log_file_name,
+ sizeof(mi->master_log_name)-1);
+ if (lex_mi->pos)
+ {
+ mi->master_log_pos= lex_mi->pos;
+ mi->rli.pending = 0;
+ }
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+
+ if (lex_mi->host)
+ strmake(mi->host, lex_mi->host, sizeof(mi->host)-1);
+ if (lex_mi->user)
+ strmake(mi->user, lex_mi->user, sizeof(mi->user)-1);
+ if (lex_mi->password)
+ strmake(mi->password, lex_mi->password, sizeof(mi->password)-1);
+ if (lex_mi->port)
+ mi->port = lex_mi->port;
+ if (lex_mi->connect_retry)
+ mi->connect_retry = lex_mi->connect_retry;
+
+ if (lex_mi->relay_log_name)
+ {
+ need_relay_log_purge= 0;
+ strmake(mi->rli.relay_log_name,lex_mi->relay_log_name,
+ sizeof(mi->rli.relay_log_name)-1);
+ }
+
+ if (lex_mi->relay_log_pos)
+ {
+ need_relay_log_purge= 0;
+ mi->rli.relay_log_pos=lex_mi->relay_log_pos;
+ }
+
+ /*
+ If user did specify neither host nor port nor any log name nor any log
+ pos, i.e. he specified only user/password/master_connect_retry, he probably
+ wants replication to resume from where it had left, i.e. from the
+ coordinates of the **SQL** thread (imagine the case where the I/O is ahead
+ of the SQL; restarting from the coordinates of the I/O would lose some
+ events which is probably unwanted when you are just doing minor changes
+ like changing master_connect_retry).
+ A side-effect is that if only the I/O thread was started, this thread may
+ restart from ''/4 after the CHANGE MASTER. That's a minor problem (it is a
+ much more unlikely situation than the one we are fixing here).
+ Note: coordinates of the SQL thread must be read here, before the
+ 'if (need_relay_log_purge)' block which resets them.
+ */
+ if (!lex_mi->host && !lex_mi->port &&
+ !lex_mi->log_file_name && !lex_mi->pos &&
+ need_relay_log_purge)
+ {
+ /*
+ Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is
+ not initialized), so we use a max().
+ What happens to mi->rli.master_log_pos during the initialization stages
+ of replication is not 100% clear, so we guard against problems using
+ max().
+ */
+ mi->master_log_pos = max(BIN_LOG_HEADER_SIZE, mi->rli.master_log_pos);
+ strmake(mi->master_log_name,mi->rli.master_log_name,
+ sizeof(mi->master_log_name)-1);
+ }
+
+ flush_master_info(mi);
+ if (need_relay_log_purge)
+ {
+ mi->rli.skip_log_purge= 0;
+ thd->proc_info="Purging old relay logs";
+ if (purge_relay_logs(&mi->rli, thd,
+ 0 /* not only reset, but also reinit */,
+ &errmsg))
{
- strmake(glob_mi.host, lex_mi->host, sizeof(glob_mi.host));
+ net_printf(&thd->net, 0, "Failed purging old relay logs: %s",errmsg);
+ unlock_slave_threads(mi);
+ DBUG_RETURN(1);
}
- if(lex_mi->user)
- strmake(glob_mi.user, lex_mi->user, sizeof(glob_mi.user));
- if(lex_mi->password)
- strmake(glob_mi.password, lex_mi->password, sizeof(glob_mi.password));
- if(lex_mi->port)
- glob_mi.port = lex_mi->port;
- if(lex_mi->connect_retry)
- glob_mi.connect_retry = lex_mi->connect_retry;
-
- flush_master_info(&glob_mi);
- pthread_mutex_unlock(&glob_mi.lock);
- thd->proc_info = "starting slave";
- if(slave_was_running)
- start_slave(0,0);
+ }
+ else
+ {
+ const char* msg;
+ mi->rli.skip_log_purge= 1;
+ /* Relay log is already initialized */
+ if (init_relay_log_pos(&mi->rli,
+ mi->rli.relay_log_name,
+ mi->rli.relay_log_pos,
+ 0 /*no data lock*/,
+ &msg))
+ {
+ net_printf(&thd->net,0,"Failed initializing relay log position: %s",msg);
+ unlock_slave_threads(mi);
+ DBUG_RETURN(1);
+ }
+ }
+ DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+
+ /*
+ Coordinates in rli were spoilt by the 'if (need_relay_log_purge)' block,
+ so restore them to good values. If we left them to ''/0, that would work;
+ but that would fail in the case of 2 successive CHANGE MASTER (without a
+ START SLAVE in between): because first one would set the coords in mi to
+ the good values of those in rli, the set those in rli to ''/0, then
+ second CHANGE MASTER would set the coords in mi to those of rli, i.e. to
+ ''/0: we have lost all copies of the original good coordinates.
+ That's why we always save good coords in rli.
+ */
+ mi->rli.master_log_pos = mi->master_log_pos;
+ strmake(mi->rli.master_log_name,mi->master_log_name,
+ sizeof(mi->rli.master_log_name)-1);
+
+ if (!mi->rli.master_log_name[0]) // uninitialized case
+ mi->rli.master_log_pos=0;
+
+ pthread_mutex_lock(&mi->rli.data_lock);
+ mi->rli.abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */
+ /* Clear the error, for a clean start. */
+ clear_last_slave_error(&mi->rli);
+ /*
+ If we don't write new coordinates to disk now, then old will remain in
+ relay-log.info until START SLAVE is issued; but if mysqld is shutdown
+ before START SLAVE, then old will remain in relay-log.info, and will be the
+ in-memory value at restart (thus causing errors, as the old relay log does
+ not exist anymore).
+ */
+ flush_relay_log_info(&mi->rli);
+ pthread_cond_broadcast(&mi->data_cond);
+ pthread_mutex_unlock(&mi->rli.data_lock);
+
+ unlock_slave_threads(mi);
thd->proc_info = 0;
-
send_ok(&thd->net);
- return 0;
+ DBUG_RETURN(0);
}
-void reset_master()
+int reset_master(THD* thd)
{
- if(!mysql_bin_log.is_open())
+ if (!mysql_bin_log.is_open())
{
my_error(ER_FLUSH_MASTER_BINLOG_CLOSED, MYF(ME_BELL+ME_WAITTANG));
- return;
+ return 1;
}
+ return mysql_bin_log.reset_logs(thd);
+}
- LOG_INFO linfo;
- if (mysql_bin_log.find_first_log(&linfo, ""))
- return;
+int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
+ const char* log_file_name2, ulonglong log_pos2)
+{
+ int res;
+ uint log_file_name1_len= strlen(log_file_name1);
+ uint log_file_name2_len= strlen(log_file_name2);
- for(;;)
+ // We assume that both log names match up to '.'
+ if (log_file_name1_len == log_file_name2_len)
{
- my_delete(linfo.log_file_name, MYF(MY_WME));
- if (mysql_bin_log.find_next_log(&linfo))
- break;
+ if ((res= strcmp(log_file_name1, log_file_name2)))
+ return res;
+ return (log_pos1 < log_pos2) ? -1 : (log_pos1 == log_pos2) ? 0 : 1;
+ }
+ return ((log_file_name1_len < log_file_name2_len) ? -1 : 1);
+}
+
+
+int show_binlog_events(THD* thd)
+{
+ DBUG_ENTER("show_binlog_events");
+ List<Item> field_list;
+ const char* errmsg = 0;
+ IO_CACHE log;
+ File file = -1;
+
+ Log_event::init_show_field_list(&field_list);
+ if (send_fields(thd, field_list, 1))
+ DBUG_RETURN(-1);
+
+ if (mysql_bin_log.is_open())
+ {
+ LEX_MASTER_INFO *lex_mi = &thd->lex.mi;
+ ha_rows event_count, limit_start, limit_end;
+ my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
+ char search_file_name[FN_REFLEN], *name;
+ const char *log_file_name = lex_mi->log_file_name;
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+ LOG_INFO linfo;
+ Log_event* ev;
+
+ limit_start = thd->lex.select->offset_limit;
+ limit_end = thd->lex.select->select_limit + limit_start;
+
+ name= search_file_name;
+ if (log_file_name)
+ mysql_bin_log.make_log_name(search_file_name, log_file_name);
+ else
+ name=0; // Find first log
+
+ linfo.index_file_offset = 0;
+ thd->current_linfo = &linfo;
+
+ if (mysql_bin_log.find_log_pos(&linfo, name, 1))
+ {
+ errmsg = "Could not find target log";
+ goto err;
+ }
+
+ if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0)
+ goto err;
+
+ pthread_mutex_lock(log_lock);
+ my_b_seek(&log, pos);
+
+ for (event_count = 0;
+ (ev = Log_event::read_log_event(&log,(pthread_mutex_t*)0,0)); )
+ {
+ if (event_count >= limit_start &&
+ ev->net_send(thd, linfo.log_file_name, pos))
+ {
+ errmsg = "Net error";
+ delete ev;
+ pthread_mutex_unlock(log_lock);
+ goto err;
+ }
+
+ pos = my_b_tell(&log);
+ delete ev;
+
+ if (++event_count >= limit_end)
+ break;
+ }
+
+ if (event_count < limit_end && log.error)
+ {
+ errmsg = "Wrong offset or I/O error";
+ pthread_mutex_unlock(log_lock);
+ goto err;
+ }
+
+ pthread_mutex_unlock(log_lock);
+ }
+
+err:
+ if (file >= 0)
+ {
+ end_io_cache(&log);
+ (void) my_close(file, MYF(MY_WME));
+ }
+
+ if (errmsg)
+ {
+ my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
+ "SHOW BINLOG EVENTS", errmsg);
+ DBUG_RETURN(-1);
}
- mysql_bin_log.close(1); // exiting close
- my_delete(mysql_bin_log.get_index_fname(), MYF(MY_WME));
- mysql_bin_log.open(opt_bin_logname,LOG_BIN);
+ send_eof(&thd->net);
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->current_linfo = 0;
+ pthread_mutex_unlock(&LOCK_thread_count);
+ DBUG_RETURN(0);
}
+
int show_binlog_info(THD* thd)
{
DBUG_ENTER("show_binlog_info");
@@ -802,100 +1163,113 @@ int show_binlog_info(THD* thd)
field_list.push_back(new Item_empty_string("Binlog_do_db",20));
field_list.push_back(new Item_empty_string("Binlog_ignore_db",20));
- if(send_fields(thd, field_list, 1))
+ if (send_fields(thd, field_list, 1))
DBUG_RETURN(-1);
String* packet = &thd->packet;
packet->length(0);
- if(mysql_bin_log.is_open())
- {
- LOG_INFO li;
- mysql_bin_log.get_current_log(&li);
- int dir_len = dirname_length(li.log_file_name);
- net_store_data(packet, li.log_file_name + dir_len);
- net_store_data(packet, (longlong)li.pos);
- net_store_data(packet, &binlog_do_db);
- net_store_data(packet, &binlog_ignore_db);
- }
- else
- {
- net_store_null(packet);
- net_store_null(packet);
- net_store_null(packet);
- net_store_null(packet);
- }
-
- if(my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
- DBUG_RETURN(-1);
-
+ if (mysql_bin_log.is_open())
+ {
+ LOG_INFO li;
+ mysql_bin_log.get_current_log(&li);
+ int dir_len = dirname_length(li.log_file_name);
+ net_store_data(packet, li.log_file_name + dir_len);
+ net_store_data(packet, (longlong)li.pos);
+ net_store_data(packet, &binlog_do_db);
+ net_store_data(packet, &binlog_ignore_db);
+ if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
+ DBUG_RETURN(-1);
+ }
send_eof(&thd->net);
DBUG_RETURN(0);
}
+
+/*
+ Send a list of all binary logs to client
+
+ SYNOPSIS
+ show_binlogs()
+ thd Thread specific variable
+
+ RETURN VALUES
+ 0 ok
+ 1 error (Error message sent to client)
+*/
+
int show_binlogs(THD* thd)
{
- const char* errmsg = 0;
- File index_file;
+ IO_CACHE *index_file;
char fname[FN_REFLEN];
NET* net = &thd->net;
List<Item> field_list;
- String* packet = &thd->packet;
- IO_CACHE io_cache;
+ String *packet = &thd->packet;
uint length;
-
- if(!mysql_bin_log.is_open())
- {
- errmsg = "binlog is not open";
- goto err;
- }
- field_list.push_back(new Item_empty_string("Log_name", 128));
- if(send_fields(thd, field_list, 1))
+ if (!mysql_bin_log.is_open())
{
- sql_print_error("Failed in send_fields");
+ //TODO: Replace with ER() error message
+ send_error(net, 0, "You are not using binary logging");
return 1;
}
-
+
+ field_list.push_back(new Item_empty_string("Log_name", 255));
+ if (send_fields(thd, field_list, 1))
+ return 1;
mysql_bin_log.lock_index();
- index_file = mysql_bin_log.get_index_file();
- if (index_file < 0)
- {
- errmsg = "Uninitialized index file pointer";
- goto err2;
- }
- if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, 0, 0,
- MYF(MY_WME)))
- {
- errmsg = "Failed on init_io_cache()";
- goto err2;
- }
- while ((length=my_b_gets(&io_cache, fname, sizeof(fname))))
+ index_file=mysql_bin_log.get_index_file();
+
+ reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 0);
+
+ /* The file ends with EOF or empty line */
+ while ((length=my_b_gets(index_file, fname, sizeof(fname))) > 1)
{
- fname[--length]=0;
int dir_len = dirname_length(fname);
packet->length(0);
- net_store_data(packet, fname + dir_len, length-dir_len);
- if(my_net_write(net, (char*) packet->ptr(), packet->length()))
- {
- sql_print_error("Failed in my_net_write");
- end_io_cache(&io_cache);
- mysql_bin_log.unlock_index();
- return 1;
- }
+ /* The -1 is for removing newline from fname */
+ net_store_data(packet, fname + dir_len, length-1-dir_len);
+ if (my_net_write(net, (char*) packet->ptr(), packet->length()))
+ goto err;
}
-
mysql_bin_log.unlock_index();
- end_io_cache(&io_cache);
- send_eof(net);
+ send_eof(net);
return 0;
-err2:
- mysql_bin_log.unlock_index();
- end_io_cache(&io_cache);
err:
- send_error(net, 0, errmsg);
+ mysql_bin_log.unlock_index();
return 1;
}
-
+int log_loaded_block(IO_CACHE* file)
+{
+ LOAD_FILE_INFO* lf_info;
+ uint block_len ;
+
+ /* file->request_pos contains position where we started last read */
+ char* buffer = (char*) file->request_pos;
+ if (!(block_len = (char*) file->read_end - (char*) buffer))
+ return 0;
+ lf_info = (LOAD_FILE_INFO*) file->arg;
+ if (lf_info->last_pos_in_file != HA_POS_ERROR &&
+ lf_info->last_pos_in_file >= file->pos_in_file)
+ return 0;
+ lf_info->last_pos_in_file = file->pos_in_file;
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, lf_info->db, buffer, block_len,
+ lf_info->log_delayed);
+ mysql_bin_log.write(&a);
+ }
+ else
+ {
+ Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db,
+ lf_info->table_name, *lf_info->fields,
+ lf_info->handle_dup, buffer,
+ block_len, lf_info->log_delayed);
+ mysql_bin_log.write(&c);
+ lf_info->wrote_create_file = 1;
+ DBUG_SYNC_POINT("debug_lock.created_file_event",10);
+ }
+ return 0;
+}
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index 3b8f161dcd0..570c41c98f7 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -1,39 +1,55 @@
-#ifndef SQL_REPL_H
-#define SQL_REPL_H
-
#include "slave.h"
-extern char* master_host;
-extern my_string opt_bin_logname, master_info_file;
-extern ulong server_id;
+typedef struct st_slave_info
+{
+ uint32 server_id;
+ uint32 rpl_recovery_rank, master_id;
+ char host[HOSTNAME_LENGTH+1];
+ char user[USERNAME_LENGTH+1];
+ char password[MAX_PASSWORD_LENGTH+1];
+ uint16 port;
+ THD* thd;
+} SLAVE_INFO;
+
+extern my_bool opt_show_slave_auth_info;
+extern char *master_host, *master_info_file;
extern bool server_id_supplied;
extern I_List<i_string> binlog_do_db, binlog_ignore_db;
-#ifndef DBUG_OFF
extern int max_binlog_dump_events;
-extern bool opt_sporadic_binlog_dump_fail;
-#endif
+extern my_bool opt_sporadic_binlog_dump_fail;
-#ifdef SIGNAL_WITH_VIO_CLOSE
-#define KICK_SLAVE { slave_thd->close_active_vio(); \
- thr_alarm_kill(slave_real_id); }
-#else
-#define KICK_SLAVE thr_alarm_kill(slave_real_id);
-#endif
+#define KICK_SLAVE(thd) { pthread_mutex_lock(&(thd)->LOCK_delete); (thd)->awake(0 /* do not prepare to die*/); pthread_mutex_unlock(&(thd)->LOCK_delete); }
File open_binlog(IO_CACHE *log, const char *log_file_name,
- const char **errmsg);
+ const char **errmsg);
-int start_slave(THD* thd = 0, bool net_report = 1);
-int stop_slave(THD* thd = 0, bool net_report = 1);
-int change_master(THD* thd);
-void reset_slave();
-void reset_master();
+int start_slave(THD* thd, MASTER_INFO* mi, bool net_report);
+int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report);
+int change_master(THD* thd, MASTER_INFO* mi);
+int show_binlog_events(THD* thd);
+int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
+ const char* log_file_name2, ulonglong log_pos2);
+int reset_slave(THD *thd, MASTER_INFO* mi);
+int reset_master(THD* thd);
int purge_master_logs(THD* thd, const char* to_log);
bool log_in_use(const char* log_name);
void adjust_linfo_offsets(my_off_t purge_offset);
int show_binlogs(THD* thd);
extern int init_master_info(MASTER_INFO* mi);
void kill_zombie_dump_threads(uint32 slave_server_id);
+int check_binlog_magic(IO_CACHE* log, const char** errmsg);
+
+typedef struct st_load_file_info
+{
+ THD* thd;
+ my_off_t last_pos_in_file;
+ sql_exchange* ex;
+ List <Item> *fields;
+ enum enum_duplicates handle_dup;
+ char* db;
+ char* table_name;
+ bool wrote_create_file, log_delayed;
+} LOAD_FILE_INFO;
-#endif
+int log_loaded_block(IO_CACHE* file);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 26b1966ffed..ae493c0cb16 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -41,13 +41,16 @@ static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
uint tables,COND *conds,table_map table_map);
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
+static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
+ table_map used_tables);
static void find_best_combination(JOIN *join,table_map rest_tables);
static void find_best(JOIN *join,table_map rest_tables,uint index,
double record_count,double read_time);
static uint cache_record_length(JOIN *join,uint index);
static double prev_record_reads(JOIN *join,table_map found_ref);
static bool get_best_combination(JOIN *join);
-static store_key *get_store_key(KEYUSE *keyuse, table_map used_tables,
+static store_key *get_store_key(THD *thd,
+ KEYUSE *keyuse, table_map used_tables,
KEY_PART_INFO *key_part, char *key_buff,
uint maybe_null);
static bool make_simple_join(JOIN *join,TABLE *tmp_table);
@@ -59,7 +62,7 @@ static void update_depend_map(JOIN *join);
static void update_depend_map(JOIN *join, ORDER *order);
static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
bool *simple_order);
-static int return_zero_rows(select_result *res,TABLE_LIST *tables,
+static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
List<Item> &fields, bool send_row,
uint select_options, const char *info,
Item *having, Procedure *proc);
@@ -68,7 +71,7 @@ static COND *remove_eq_conds(COND *cond,Item::cond_result *cond_value);
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- uint options);
+ ulong options);
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
Procedure *proc);
static int sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records);
@@ -83,20 +86,23 @@ static int end_unique_update(JOIN *join,JOIN_TAB *join_tab,
static int end_write_group(JOIN *join, JOIN_TAB *join_tab,
bool end_of_records);
static int test_if_group_changed(List<Item_buff> &list);
-static int join_read_const_tables(JOIN *join);
+static int join_read_const_table(JOIN_TAB *tab, POSITION *pos);
static int join_read_system(JOIN_TAB *tab);
static int join_read_const(JOIN_TAB *tab);
static int join_read_key(JOIN_TAB *tab);
static int join_read_always_key(JOIN_TAB *tab);
+static int join_read_last_key(JOIN_TAB *tab);
static int join_no_more_records(READ_RECORD *info);
static int join_read_next(READ_RECORD *info);
static int join_init_quick_read_record(JOIN_TAB *tab);
static int test_if_quick_select(JOIN_TAB *tab);
static int join_init_read_record(JOIN_TAB *tab);
-static int join_init_read_first_with_key(JOIN_TAB *tab);
-static int join_init_read_next_with_key(READ_RECORD *info);
-static int join_init_read_last_with_key(JOIN_TAB *tab);
-static int join_init_read_prev_with_key(READ_RECORD *info);
+static int join_read_first(JOIN_TAB *tab);
+static int join_read_next(READ_RECORD *info);
+static int join_read_next_same(READ_RECORD *info);
+static int join_read_last(JOIN_TAB *tab);
+static int join_read_prev_same(READ_RECORD *info);
+static int join_read_prev(READ_RECORD *info);
static int join_ft_read_first(JOIN_TAB *tab);
static int join_ft_read_next(READ_RECORD *info);
static COND *make_cond_for_table(COND *cond,table_map table,
@@ -104,9 +110,9 @@ static COND *make_cond_for_table(COND *cond,table_map table,
static Item* part_of_refkey(TABLE *form,Field *field);
static uint find_shortest_key(TABLE *table, key_map usable_keys);
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
- ha_rows select_limit);
-static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit);
-static bool fix_having(JOIN *join, Item **having);
+ ha_rows select_limit, bool no_changes);
+static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows filesort_limit,
+ ha_rows select_limit);
static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
Item *having);
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
@@ -124,7 +130,9 @@ static int setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &all_fields, ORDER *order, bool *hidden);
static bool setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &all_fields,ORDER *new_order);
-static ORDER *create_distinct_group(ORDER *order, List<Item> &fields);
+static ORDER *create_distinct_group(THD *thd, ORDER *order,
+ List<Item> &fields,
+ bool *all_order_by_fields_used);
static bool test_if_subpart(ORDER *a,ORDER *b);
static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
static void calc_group_buffer(JOIN *join,ORDER *group);
@@ -138,24 +146,84 @@ static void copy_sum_funcs(Item_sum **func_ptr);
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
static void init_sum_functions(Item_sum **func);
static bool update_sum_func(Item_sum **func);
-static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
- bool distinct);
-static void describe_info(THD *thd, const char *info);
+static void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
+ bool distinct, const char *message=NullS);
+static void describe_info(JOIN *join, const char *info);
+
+/*
+ This handles SELECT with and without UNION
+*/
+
+int handle_select(THD *thd, LEX *lex, select_result *result)
+{
+ int res;
+ register SELECT_LEX *select_lex = &lex->select_lex;
+
+#ifdef DISABLED_UNTIL_REWRITTEN_IN_4_1
+ if (lex->olap)
+ {
+ SELECT_LEX *sl, *sl_next;
+ int error;
+ for (sl= &select_lex; sl; sl=sl_next)
+ {
+ sl_next=sl->next; // Save if sl->next changes
+ if (sl->olap != UNSPECIFIED_OLAP_TYPE)
+ {
+ if ((error=handle_olaps(lex,sl)))
+ return error;
+ lex->last_selects->next=sl_next;
+ }
+ }
+ lex->select = select_lex;
+ }
+#endif /* DISABLED_UNTIL_REWRITTEN_IN_4_1 */
+ if (select_lex->next)
+ res=mysql_union(thd,lex,result);
+ else
+ res=mysql_select(thd,(TABLE_LIST*) select_lex->table_list.first,
+ select_lex->item_list,
+ select_lex->where,
+ (ORDER*) select_lex->order_list.first,
+ (ORDER*) select_lex->group_list.first,
+ select_lex->having,
+ (ORDER*) lex->proc_list.first,
+ select_lex->options | thd->options,
+ result);
+ if (res && result)
+ result->abort();
+ delete result;
+ return res;
+}
+
/*****************************************************************************
-** check fields, find best join, do the select and output fields.
-** mysql_select assumes that all tables are allready opened
+ Check fields, find best join, do the select and output fields.
+ mysql_select assumes that all tables are already opened
*****************************************************************************/
int
mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
ORDER *order, ORDER *group,Item *having,ORDER *proc_param,
- uint select_options,select_result *result)
+ ulong select_options,select_result *result)
{
TABLE *tmp_table;
int error, tmp_error;
- bool need_tmp,hidden_group_fields;
- bool simple_order,simple_group,no_order;
+ bool need_tmp;
+ bool hidden_group_fields;
+ /*
+ simple_xxxxx is set if ORDER/GROUP BY doesn't include any references
+ to other tables than the first non-constant table in the JOIN.
+ It's also set if ORDER/GROUP BY is empty.
+ */
+ bool simple_order, simple_group;
+ /*
+ Is set only in case if we have a GROUP BY clause
+ and no ORDER BY after constant elimination of 'order'.
+ */
+ bool no_order;
+ /* Is set if we have a GROUP BY and we have ORDER BY on a constant. */
+ bool skip_sort_order;
+ ha_rows select_limit;
Item::cond_result cond_value;
SQL_SELECT *select;
DYNAMIC_ARRAY keyuse;
@@ -163,6 +231,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
Procedure *procedure;
List<Item> all_fields(fields);
bool select_distinct;
+ SELECT_LEX *cur_sel = thd->lex.select;
DBUG_ENTER("mysql_select");
/* Check that all tables, fields, conds and order are ok */
@@ -170,13 +239,17 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
select_distinct=test(select_options & SELECT_DISTINCT);
tmp_table=0;
select=0;
- no_order=0;
+ no_order=skip_sort_order=0;
bzero((char*) &keyuse,sizeof(keyuse));
thd->proc_info="init";
thd->used_tables=0; // Updated by setup_fields
+ /* select_limit is used to decide if we are likely to scan the whole table */
+ select_limit= thd->select_limit;
+ if (having || (select_options & OPTION_FOUND_ROWS))
+ select_limit= HA_POS_ERROR;
if (setup_tables(tables) ||
- setup_fields(thd,tables,fields,1,&all_fields) ||
+ setup_fields(thd,tables,fields,1,&all_fields,1) ||
setup_conds(thd,tables,&conds) ||
setup_order(thd,tables,fields,all_fields,order) ||
setup_group(thd,tables,fields,all_fields,group,&hidden_group_fields))
@@ -198,14 +271,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
and no GROUP BY.
TODO: Add check of calculation of GROUP functions and fields:
SELECT COUNT(*)+table.col1 from table1;
- */
+ */
join.table=0;
join.tables=0;
{
if (!group)
{
uint flag=0;
- List_iterator<Item> it(fields);
+ List_iterator_fast<Item> it(fields);
Item *item;
while ((item= it++))
{
@@ -274,12 +347,15 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
count_field_types(&join.tmp_table_param,all_fields,0);
join.const_tables=0;
join.having=0;
+ join.do_send_rows = 1;
join.group= group != 0;
+ join.row_limit= ((select_distinct || order || group) ? HA_POS_ERROR :
+ thd->select_limit);
#ifdef RESTRICTED_GROUP
if (join.sum_func_count && !group && (join.func_count || join.field_count))
{
- my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT));
+ my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
delete procedure;
DBUG_RETURN(-1);
}
@@ -302,6 +378,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
{
conds->fix_fields(thd,tables);
conds->change_ref_to_fields(thd,tables);
+ conds->top_level_item();
having=0;
}
}
@@ -315,7 +392,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
}
if (cond_value == Item::COND_FALSE || !thd->select_limit)
{ /* Impossible cond */
- error=return_zero_rows(result, tables, fields,
+ error=return_zero_rows(&join, result, tables, fields,
join.tmp_table_param.sum_func_count != 0 && !group,
select_options,"Impossible WHERE",having,
procedure);
@@ -327,11 +404,20 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (tables && join.tmp_table_param.sum_func_count && ! group)
{
int res;
+ /*
+ opt_sum_query returns -1 if no rows match to the WHERE conditions,
+ or 1 if all items were resolved, or 0, or an error number HA_ERR_...
+ */
if ((res=opt_sum_query(tables, all_fields, conds)))
{
+ if (res > 1)
+ {
+ delete procedure;
+ DBUG_RETURN(-1);
+ }
if (res < 0)
{
- error=return_zero_rows(result, tables, fields, !group,
+ error=return_zero_rows(&join, result, tables, fields, !group,
select_options,"No matching min/max row",
having,procedure);
delete procedure;
@@ -339,9 +425,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
}
if (select_options & SELECT_DESCRIBE)
{
- describe_info(thd,"Select tables optimized away");
+ describe_info(&join, "Select tables optimized away");
delete procedure;
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
tables=0; // All tables resolved
}
@@ -350,13 +436,13 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
{ // Only test of functions
error=0;
if (select_options & SELECT_DESCRIBE)
- describe_info(thd,"No tables used");
+ describe_info(&join, "No tables used");
else
{
result->send_fields(fields,1);
if (!having || having->val_int())
{
- if (result->send_data(fields))
+ if (join.do_send_rows && result->send_data(fields))
{
result->send_error(0,NullS); /* purecov: inspected */
error=1;
@@ -368,7 +454,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
error=(int) result->send_eof();
}
delete procedure;
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
error = -1;
@@ -376,28 +462,34 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
/* Calculate how to do the join */
thd->proc_info="statistics";
- if (make_join_statistics(&join,tables,conds,&keyuse) ||
- thd->fatal_error)
+ if (make_join_statistics(&join,tables,conds,&keyuse) || thd->fatal_error)
goto err;
+
thd->proc_info="preparing";
- if ((tmp_error=join_read_const_tables(&join)) > 0)
+
+ select_distinct= select_distinct && (join.const_tables != join.tables);
+
+ if (result->initialize_tables(&join))
goto err;
- if (tmp_error && !(select_options & SELECT_DESCRIBE))
+ if (join.const_table_map != join.found_const_table_map &&
+ !(select_options & SELECT_DESCRIBE))
{
- error=return_zero_rows(result,tables,fields,
+ error=return_zero_rows(&join,result,tables,fields,
join.tmp_table_param.sum_func_count != 0 &&
- !group,0,"",having,procedure);
+ !group,0,"no matching row in const table",having,
+ procedure);
goto err;
}
if (!(thd->options & OPTION_BIG_SELECTS) &&
- join.best_read > (double) thd->max_join_size &&
+ join.best_read > (double) thd->variables.max_join_size &&
!(select_options & SELECT_DESCRIBE))
{ /* purecov: inspected */
result->send_error(ER_TOO_BIG_SELECT,ER(ER_TOO_BIG_SELECT)); /* purecov: inspected */
error= 1; /* purecov: inspected */
goto err; /* purecov: inspected */
}
- if (join.const_tables && !thd->locked_tables)
+ if (join.const_tables && !thd->locked_tables &&
+ !(select_options & SELECT_NO_UNLOCK))
{
TABLE **table, **end;
for (table=join.table, end=table + join.const_tables ;
@@ -428,7 +520,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
}
if (make_join_select(&join,select,conds))
{
- error=return_zero_rows(result,tables,fields,
+ error=return_zero_rows(&join, result, tables, fields,
join.tmp_table_param.sum_func_count != 0 && !group,
select_options,
"Impossible WHERE noticed after reading const tables",
@@ -439,22 +531,72 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
error= -1; /* if goto err */
/* Optimize distinct away if possible */
- order=remove_const(&join,order,conds,&simple_order);
+ {
+ ORDER *org_order= order;
+ order=remove_const(&join,order,conds,&simple_order);
+ /*
+ If we are using ORDER BY NULL or ORDER BY const_expression,
+ return result in any order (even if we are using a GROUP BY)
+ */
+ if (!order && org_order)
+ skip_sort_order= 1;
+ }
if (group || join.tmp_table_param.sum_func_count)
{
if (! hidden_group_fields)
select_distinct=0;
}
- else if (select_distinct && join.tables - join.const_tables == 1 &&
- (order || thd->select_limit == HA_POS_ERROR))
+ else if (select_distinct && join.tables - join.const_tables == 1)
{
- if ((group=create_distinct_group(order,fields)))
- {
- select_distinct=0;
- no_order= !order;
- join.group=1; // For end_write_group
- }
- else if (thd->fatal_error) // End of memory
+ /*
+ We are only using one table. In this case we change DISTINCT to a
+ GROUP BY query if:
+ - The GROUP BY can be done through indexes (no sort) and the ORDER
+ BY only uses selected fields.
+ (In this case we can later optimize away GROUP BY and ORDER BY)
+ - We are scanning the whole table without LIMIT
+ This can happen if:
+ - We are using CALC_FOUND_ROWS
+ - We are using an ORDER BY that can't be optimized away.
+
+ We don't want to use this optimization when we are using LIMIT
+ because in this case we can just create a temporary table that
+ holds LIMIT rows and stop when this table is full.
+ */
+ JOIN_TAB *tab= &join.join_tab[join.const_tables];
+ bool all_order_fields_used;
+ if (order)
+ skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1);
+ if ((group=create_distinct_group(thd, order, fields,
+ &all_order_fields_used)))
+ {
+ bool skip_group= (skip_sort_order &&
+ test_if_skip_sort_order(tab, group, select_limit,
+ 1) != 0);
+ if ((skip_group && all_order_fields_used) ||
+ select_limit == HA_POS_ERROR ||
+ (order && !skip_sort_order))
+ {
+ /* Change DISTINCT to GROUP BY */
+ select_distinct= 0;
+ no_order= !order;
+ if (all_order_fields_used)
+ {
+ if (order && skip_sort_order)
+ {
+ /*
+ Force MySQL to read the table in sorted order to get result in
+ ORDER BY order.
+ */
+ join.tmp_table_param.quick_group=0;
+ }
+ order=0;
+ }
+ join.group=1; // For end_write_group
+ }
+ else
+ group= 0;
+ } else if (thd->fatal_error) // End of memory
goto err;
}
group=remove_const(&join,group,conds,&simple_group);
@@ -477,7 +619,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
(!group && join.tmp_table_param.sum_func_count))
order=0;
- // Can't use sort on head table if using cache
+ // Can't use sort on head table if using row cache
if (join.full_join)
{
if (group)
@@ -486,19 +628,33 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
simple_order=0;
}
+ /*
+ Check if we need to create a temporary table.
+ This has to be done if all tables are not already read (const tables)
+ and one of the following conditions holds:
+ - We are using DISTINCT (simple distinct's are already optimized away)
+ - We are using an ORDER BY or GROUP BY on fields not in the first table
+ - We are using different ORDER BY and GROUP BY orders
+ - The user wants us to buffer the result.
+ */
need_tmp= (join.const_tables != join.tables &&
((select_distinct || !simple_order || !simple_group) ||
- (group && order) ||
+ (group && order) ||
test(select_options & OPTION_BUFFER_RESULT)));
- make_join_readinfo(&join, (select_options & SELECT_DESCRIBE) |
- (thd->lex.ftfunc_list.elements ? 0 : SELECT_USE_CACHE)); // No cache for MATCH
-
- /* Need to tell Innobase that to play it safe, it should fetch all
- columns of the tables: this is because MySQL
- may build row pointers for the rows, and for all columns of the primary
- key the field->query_id has not necessarily been set to thd->query_id
- by MySQL. */
+ // No cache for MATCH
+ make_join_readinfo(&join,
+ (select_options & (SELECT_DESCRIBE |
+ SELECT_NO_JOIN_CACHE)) |
+ (cur_sel->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE :
+ 0));
+ /*
+ Need to tell Innobase that to play it safe, it should fetch all
+ columns of the tables: this is because MySQL may build row
+ pointers for the rows, and for all columns of the primary key the
+ field->query_id has not necessarily been set to thd->query_id by
+ MySQL.
+ */
#ifdef HAVE_INNOBASE_DB
if (need_tmp || select_distinct || group || order)
@@ -506,7 +662,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
for (uint i_h = join.const_tables; i_h < join.tables; i_h++)
{
TABLE* table_h = join.join_tab[i_h].table;
- if (table_h->db_type == DB_TYPE_INNOBASE)
+ if (table_h->db_type == DB_TYPE_INNODB)
table_h->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE);
}
}
@@ -531,7 +687,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
((group && join.const_tables != join.tables &&
(!simple_group ||
!test_if_skip_sort_order(&join.join_tab[join.const_tables], group,
- HA_POS_ERROR))) ||
+ thd->select_limit,0))) ||
select_distinct) &&
join.tmp_table_param.quick_group && !procedure)
{
@@ -540,25 +696,33 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (select_options & SELECT_DESCRIBE)
{
- if (!order && !no_order)
- order=group;
+ /*
+ Check if we managed to optimize ORDER BY away and don't use temporary
+ table to resolve ORDER BY: in that case, we only may need to do
+ filesort for GROUP BY.
+ */
+ if (!order && !no_order && (!skip_sort_order || !need_tmp))
+ {
+ /* Reset 'order' to 'group' and reinit variables describing 'order' */
+ order= group;
+ simple_order= simple_group;
+ skip_sort_order= 0;
+ }
if (order &&
(join.const_tables == join.tables ||
- (simple_order &&
+ ((simple_order || skip_sort_order) &&
test_if_skip_sort_order(&join.join_tab[join.const_tables], order,
- (group ? HA_POS_ERROR :
- thd->select_limit)))))
+ select_limit, 0))))
order=0;
select_describe(&join,need_tmp,
- (order != 0 &&
- (!need_tmp || order != group || simple_group)),
+ order != 0 && !skip_sort_order,
select_distinct);
error=0;
goto err;
}
/* Perform FULLTEXT search before all regular searches */
- init_ftfuncs(thd, test(order));
+ init_ftfuncs(thd,test(order));
/* Create a tmp table if distinct or if the sort is too complicated */
if (need_tmp)
@@ -566,6 +730,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
DBUG_PRINT("info",("Creating tmp table"));
thd->proc_info="Creating tmp table";
+ join.tmp_table_param.hidden_field_count= (all_fields.elements -
+ fields.elements);
if (!(tmp_table =
create_tmp_table(thd,&join.tmp_table_param,all_fields,
((!simple_group && !procedure &&
@@ -573,7 +739,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
group : (ORDER*) 0),
group ? 0 : select_distinct,
group && simple_group,
- order == 0,
+ (order == 0 || skip_sort_order) &&
+ select_limit != HA_POS_ERROR,
join.select_options)))
goto err; /* purecov: inspected */
@@ -586,7 +753,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
DBUG_PRINT("info",("Sorting for group"));
thd->proc_info="Sorting for group";
if (create_sort_index(&join.join_tab[join.const_tables],group,
- HA_POS_ERROR) ||
+ HA_POS_ERROR, HA_POS_ERROR) ||
make_sum_func_list(&join,all_fields) ||
alloc_group_fields(&join,group))
goto err;
@@ -601,7 +768,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
DBUG_PRINT("info",("Sorting for order"));
thd->proc_info="Sorting for order";
if (create_sort_index(&join.join_tab[join.const_tables],order,
- HA_POS_ERROR))
+ HA_POS_ERROR, HA_POS_ERROR))
goto err; /* purecov: inspected */
order=0;
}
@@ -623,12 +790,23 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
break;
join_tab->not_used_in_distinct=1;
} while (join_tab-- != join.join_tab);
+ /* Optimize "select distinct b from t1 order by key_part_1 limit #" */
+ if (order && skip_sort_order)
+ {
+ /* Should always succeed */
+ if (test_if_skip_sort_order(&join.join_tab[join.const_tables],
+ order, thd->select_limit,0))
+ order=0;
+ }
}
/* Copy data to the temporary table */
thd->proc_info="Copying to tmp table";
- if (do_select(&join,(List<Item> *) 0,tmp_table,0))
+ if ((tmp_error=do_select(&join,(List<Item> *) 0,tmp_table,0)))
+ {
+ error=tmp_error;
goto err; /* purecov: inspected */
+ }
if (join.having)
join.having=having=0; // Allready done
@@ -652,17 +830,17 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
procedure->update_refs();
if (tmp_table->group)
{ // Already grouped
- if (!order && !no_order)
+ if (!order && !no_order && !skip_sort_order)
order=group; /* order by group */
group=0;
}
/*
- ** If we have different sort & group then we must sort the data by group
- ** and copy it to another tmp table
- ** This code is also used if we are using distinct something
- ** we haven't been able to store in the temporary table yet
- ** like SEC_TO_TIME(SUM(...)).
+ If we have different sort & group then we must sort the data by group
+ and copy it to another tmp table
+ This code is also used if we are using distinct something
+ we haven't been able to store in the temporary table yet
+ like SEC_TO_TIME(SUM(...)).
*/
if (group && (!test_if_subpart(group,order) || select_distinct) ||
@@ -692,7 +870,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (group)
{
thd->proc_info="Creating sort index";
- if (create_sort_index(join.join_tab,group,HA_POS_ERROR) ||
+ if (create_sort_index(join.join_tab,group,HA_POS_ERROR, HA_POS_ERROR) ||
alloc_group_fields(&join,group))
{
free_tmp_table(thd,tmp_table2); /* purecov: inspected */
@@ -751,9 +929,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (join.group || join.tmp_table_param.sum_func_count ||
(procedure && (procedure->flags & PROC_GROUP)))
{
- alloc_group_fields(&join,group);
- setup_copy_fields(&join.tmp_table_param,all_fields);
- if (make_sum_func_list(&join,all_fields) || thd->fatal_error)
+ if (alloc_group_fields(&join,group) ||
+ setup_copy_fields(thd, &join.tmp_table_param,all_fields) ||
+ make_sum_func_list(&join,all_fields) || thd->fatal_error)
goto err; /* purecov: inspected */
}
if (group || order)
@@ -763,22 +941,79 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
/* If we have already done the group, add HAVING to sorted table */
if (having && ! group && ! join.sort_and_group)
{
- if (fix_having(&join,&having))
- goto err;
+ having->update_used_tables(); // Some tables may have been const
+ JOIN_TAB *table=&join.join_tab[join.const_tables];
+ table_map used_tables= join.const_table_map | table->table->map;
+
+ Item* sort_table_cond=make_cond_for_table(having,used_tables,used_tables);
+ if (sort_table_cond)
+ {
+ if (!table->select)
+ if (!(table->select=new SQL_SELECT))
+ goto err;
+ if (!table->select->cond)
+ table->select->cond=sort_table_cond;
+ else // This should never happen
+ if (!(table->select->cond=new Item_cond_and(table->select->cond,
+ sort_table_cond)))
+ goto err;
+ table->select_cond=table->select->cond;
+ table->select_cond->top_level_item();
+ DBUG_EXECUTE("where",print_where(table->select->cond,
+ "select and having"););
+ having=make_cond_for_table(having,~ (table_map) 0,~used_tables);
+ DBUG_EXECUTE("where",print_where(conds,"having after sort"););
+ }
+ }
+ if (group)
+ select_limit= HA_POS_ERROR;
+ else
+ {
+ /*
+ We can abort sorting after thd->select_limit rows if we there is no
+ WHERE clause for any tables after the sorted one.
+ */
+ JOIN_TAB *table= &join.join_tab[join.const_tables+1];
+ JOIN_TAB *end_table= &join.join_tab[join.tables];
+ for (; table < end_table ; table++)
+ {
+ /*
+ table->keyuse is set in the case there was an original WHERE clause
+ on the table that was optimized away.
+ table->on_expr tells us that it was a LEFT JOIN and there will be
+ at least one row generated from the table.
+ */
+ if (table->select_cond || (table->keyuse && !table->on_expr))
+ {
+ /* We have to sort all rows */
+ select_limit= HA_POS_ERROR;
+ break;
+ }
+ }
}
+ /*
+ Here we sort rows for ORDER BY/GROUP BY clause, if the optimiser
+ chose FILESORT to be faster than INDEX SCAN or there is no
+ suitable index present.
+ Note, that create_sort_index calls test_if_skip_sort_order and may
+ finally replace sorting with index scan if there is a LIMIT clause in
+ the query. XXX: it's never shown in EXPLAIN!
+ OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
+ */
if (create_sort_index(&join.join_tab[join.const_tables],
group ? group : order,
- (having || group ||
- join.const_tables != join.tables - 1) ?
- HA_POS_ERROR : thd->select_limit))
- goto err; /* purecov: inspected */
+ select_limit,
+ join.select_options & OPTION_FOUND_ROWS ?
+ HA_POS_ERROR : thd->select_limit))
+ goto err;
}
join.having=having; // Actually a parameter
thd->proc_info="Sending data";
error=do_select(&join,&fields,NULL,procedure);
err:
- thd->examined_row_count=join.examined_rows;
+ thd->limit_found_rows = join.send_records;
+ thd->examined_row_count = join.examined_rows;
thd->proc_info="end";
join.lock=0; // It's faster to unlock later
join_free(&join);
@@ -794,12 +1029,13 @@ err:
}
/*****************************************************************************
-** Create JOIN_TABS, make a guess about the table types,
-** Approximate how many records will be used in each table
+ Create JOIN_TABS, make a guess about the table types,
+ Approximate how many records will be used in each table
*****************************************************************************/
-static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table,
- key_map keys)
+static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
+ TABLE *table,
+ key_map keys,ha_rows limit)
{
int error;
DBUG_ENTER("get_quick_record_count");
@@ -807,7 +1043,7 @@ static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table,
{
select->head=table;
table->reginfo.impossible_range=0;
- if ((error=select->test_quick_select(keys,(table_map) 0,HA_POS_ERROR))
+ if ((error=select->test_quick_select(thd, keys,(table_map) 0,limit))
== 1)
DBUG_RETURN(select->quick->records);
if (error == -1)
@@ -821,16 +1057,23 @@ static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table,
}
+/*
+ Calculate the best possible join and initialize the join structure
+
+ RETURN VALUES
+ 0 ok
+ 1 Fatal error
+*/
+
static bool
make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
DYNAMIC_ARRAY *keyuse_array)
{
int error;
uint i,table_count,const_count,found_ref,refs,key,const_ref,eq_part;
- table_map const_table_map,all_table_map;
+ table_map found_const_table_map,all_table_map;
TABLE **table_vector;
JOIN_TAB *stat,*stat_end,*s,**stat_ref;
- SQL_SELECT *select;
KEYUSE *keyuse,*start_keyuse;
table_map outer_join=0;
JOIN_TAB *stat_vector[MAX_TABLES+1];
@@ -842,12 +1085,11 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
if (!stat || !stat_ref || !table_vector)
DBUG_RETURN(1); // Eom /* purecov: inspected */
- select=0;
join->best_ref=stat_vector;
stat_end=stat+table_count;
- const_table_map=all_table_map=0;
+ found_const_table_map=all_table_map=0;
const_count=0;
for (s=stat,i=0 ; tables ; s++,tables=tables->next,i++)
@@ -862,13 +1104,13 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->keys);
all_table_map|= table->map;
s->join=join;
+ s->info=0; // For describe
if ((s->on_expr=tables->on_expr))
{
+ /* Left join */
if (!table->file->records)
{ // Empty table
- s->key_dependent=s->dependent=0;
- s->type=JT_SYSTEM;
- const_table_map|=table->map;
+ s->key_dependent=s->dependent=0; // Ignore LEFT JOIN depend.
set_position(join,const_count++,s,(KEYUSE*) 0);
continue;
}
@@ -887,11 +1129,9 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
s->dependent=(table_map) 0;
s->key_dependent=(table_map) 0;
if ((table->system || table->file->records <= 1) && ! s->dependent &&
- !(table->file->option_flag() & HA_NOT_EXACT_COUNT) &&
+ !(table->file->table_flags() & HA_NOT_EXACT_COUNT) &&
!table->fulltext_searched)
{
- s->type=JT_SYSTEM;
- const_table_map|=table->map;
set_position(join,const_count++,s,(KEYUSE*) 0);
}
}
@@ -899,10 +1139,10 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
join->outer_join=outer_join;
/*
- ** If outer join: Re-arrange tables in stat_vector so that outer join
- ** tables are after all tables it is dependent of.
- ** For example: SELECT * from A LEFT JOIN B ON B.c=C.c, C WHERE A.C=C.C
- ** Will shift table B after table C.
+ If outer join: Re-arrange tables in stat_vector so that outer join
+ tables are after all tables it is dependent of.
+ For example: SELECT * from A LEFT JOIN B ON B.c=C.c, C WHERE A.C=C.C
+ Will shift table B after table C.
*/
if (outer_join)
{
@@ -939,31 +1179,66 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
conds,~outer_join))
DBUG_RETURN(1);
+ /* Read tables with 0 or 1 rows (system tables) */
+ join->const_table_map= 0;
+
+ for (POSITION *p_pos=join->positions, *p_end=p_pos+const_count;
+ p_pos < p_end ;
+ p_pos++)
+ {
+ int tmp;
+ s= p_pos->table;
+ s->type=JT_SYSTEM;
+ join->const_table_map|=s->table->map;
+ if ((tmp=join_read_const_table(s, p_pos)))
+ {
+ if (tmp > 0)
+ DBUG_RETURN(1); // Fatal error
+ }
+ else
+ found_const_table_map|= s->table->map;
+ }
+
/* loop until no more const tables are found */
int ref_changed;
do
{
ref_changed = 0;
found_ref=0;
- for (JOIN_TAB **pos=stat_vector+const_count; (s= *pos) ; pos++)
+
+ /*
+ We only have to loop from stat_vector + const_count as
+ set_position() will move all const_tables first in stat_vector
+ */
+
+ for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++)
{
+ TABLE *table=s->table;
if (s->dependent) // If dependent on some table
{
- if (s->dependent & ~(const_table_map)) // All dep. must be constants
+ // All dep. must be constants
+ if (s->dependent & ~(found_const_table_map))
continue;
- if (s->table->file->records <= 1L &&
- !(s->table->file->option_flag() & HA_NOT_EXACT_COUNT))
+ if (table->file->records <= 1L &&
+ !(table->file->table_flags() & HA_NOT_EXACT_COUNT))
{ // system table
+ int tmp= 0;
s->type=JT_SYSTEM;
- const_table_map|=s->table->map;
+ join->const_table_map|=table->map;
set_position(join,const_count++,s,(KEYUSE*) 0);
+ if ((tmp= join_read_const_table(s,join->positions+const_count-1)))
+ {
+ if (tmp > 0)
+ DBUG_RETURN(1); // Fatal error
+ }
+ else
+ found_const_table_map|= table->map;
continue;
}
}
/* check if table can be read by key or table only uses const refs */
if ((keyuse=s->keyuse))
{
- TABLE *table=s->table;
s->type= JT_REF;
while (keyuse->table == table)
{
@@ -976,7 +1251,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
{
if (keyuse->val->type() != Item::NULL_ITEM)
{
- if (!((~const_table_map) & keyuse->used_tables))
+ if (!((~found_const_table_map) & keyuse->used_tables))
const_ref|= (key_map) 1 << keyuse->keypart;
else
refs|=keyuse->used_tables;
@@ -986,15 +1261,28 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
} while (keyuse->table == table && keyuse->key == key);
if (eq_part == PREV_BITS(uint,table->key_info[key].key_parts) &&
- (table->key_info[key].flags & HA_NOSAME) &&
+ ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
+ HA_NOSAME) &&
!table->fulltext_searched)
{
if (const_ref == eq_part)
{ // Found everything for ref.
- s->type=JT_CONST;
- const_table_map|=table->map;
- set_position(join,const_count++,s,start_keyuse);
+ int tmp;
ref_changed = 1;
+ s->type= JT_CONST;
+ join->const_table_map|=table->map;
+ set_position(join,const_count++,s,start_keyuse);
+ if (create_ref_for_key(join, s, start_keyuse,
+ found_const_table_map))
+ DBUG_RETURN(1);
+ if ((tmp=join_read_const_table(s,
+ join->positions+const_count-1)))
+ {
+ if (tmp > 0)
+ DBUG_RETURN(1); // Fatal error
+ }
+ else
+ found_const_table_map|= table->map;
break;
}
else
@@ -1003,7 +1291,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
}
}
}
- } while (const_table_map & found_ref && ref_changed);
+ } while (join->const_table_map & found_ref && ref_changed);
/* Calc how many (possible) matched records in each table */
@@ -1019,42 +1307,67 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
s->found_records=s->records=s->table->file->records;
s->read_time=(ha_rows) s->table->file->scan_time();
- /* Set a max range of how many seeks we can expect when using keys */
- s->worst_seeks= (double) (s->read_time*2);
+ /*
+ Set a max range of how many seeks we can expect when using keys
+ This is can't be to high as otherwise we are likely to use
+ table scan.
+ */
+ s->worst_seeks= min((double) s->found_records / 10,
+ (double) s->read_time*3);
if (s->worst_seeks < 2.0) // Fix for small tables
s->worst_seeks=2.0;
- /* if (s->type == JT_EQ_REF)
- continue; */
if (s->const_keys)
{
ha_rows records;
- if (!select)
- select=make_select(s->table,0,
- 0,
- and_conds(conds,s->on_expr),&error);
- records=get_quick_record_count(select,s->table, s->const_keys);
+ SQL_SELECT *select;
+ select= make_select(s->table, found_const_table_map,
+ found_const_table_map,
+ s->on_expr ? s->on_expr : conds,
+ &error);
+ records= get_quick_record_count(join->thd, select, s->table,
+ s->const_keys, join->row_limit);
s->quick=select->quick;
s->needed_reg=select->needed_reg;
select->quick=0;
+ if (records == 0 && s->table->reginfo.impossible_range)
+ {
+ /*
+ Impossible WHERE or ON expression
+ In case of ON, we mark that the we match one empty NULL row.
+ In case of WHERE, don't set found_const_table_map to get the
+ caller to abort with a zero row result.
+ */
+ join->const_table_map|= s->table->map;
+ set_position(join,const_count++,s,(KEYUSE*) 0);
+ s->type= JT_CONST;
+ if (s->on_expr)
+ {
+ /* Generate empty row */
+ s->info= "Impossible ON condition";
+ found_const_table_map|= s->table->map;
+ s->type= JT_CONST;
+ mark_as_null_row(s->table); // All fields are NULL
+ }
+ }
if (records != HA_POS_ERROR)
{
s->found_records=records;
s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0);
}
+ delete select;
}
}
- delete select;
/* Find best combination and return it */
join->join_tab=stat;
join->map2table=stat_ref;
join->table= join->all_tables=table_vector;
join->const_tables=const_count;
- join->const_table_map=const_table_map;
+ join->found_const_table_map=found_const_table_map;
if (join->const_tables != join->tables)
- find_best_combination(join,all_table_map & ~const_table_map);
+ find_best_combination(join,all_table_map & ~join->const_table_map);
else
{
memcpy((gptr) join->best_positions,(gptr) join->positions,
@@ -1066,11 +1379,11 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
/*****************************************************************************
-** check with keys are used and with tables references with tables
-** updates in stat:
-** keys Bitmap of all used keys
-** const_keys Bitmap of all keys with may be used with quick_select
-** keyuse Pointer to possible keys
+ Check with keys are used and with tables references with tables
+ Updates in stat:
+ keys Bitmap of all used keys
+ const_keys Bitmap of all keys with may be used with quick_select
+ keyuse Pointer to possible keys
*****************************************************************************/
typedef struct key_field_t { // Used when finding key fields
@@ -1091,7 +1404,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
if (start == new_fields)
return start; // Impossible or
if (new_fields == end)
- return start; // No new fields, skipp all
+ return start; // No new fields, skip all
KEY_FIELD *first_free=new_fields;
@@ -1144,41 +1457,43 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
static void
add_key_field(KEY_FIELD **key_fields,uint and_level,
- Field *field,bool eq_func,Item *value,
+ Field *field,bool eq_func,Item **value, uint num_values,
table_map usable_tables)
{
bool exists_optimize=0;
if (!(field->flags & PART_KEY_FLAG))
{
// Don't remove column IS NULL on a LEFT JOIN table
- if (!eq_func || !value || value->type() != Item::NULL_ITEM ||
- !field->table->maybe_null || field->null_ptr)
- return; // Not a key. Skipp it
+ if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
+ !field->table->maybe_null || field->null_ptr)
+ return; // Not a key. Skip it
exists_optimize=1;
}
else
{
table_map used_tables=0;
- if (value && (used_tables=value->used_tables()) &
- (field->table->map | RAND_TABLE_BIT))
+ bool optimizable=0;
+ for (uint i=0; i<num_values; i++)
+ {
+ used_tables|=(value[i])->used_tables();
+ if (!((value[i])->used_tables() & (field->table->map | RAND_TABLE_BIT)))
+ optimizable=1;
+ }
+ if (!optimizable)
return;
if (!(usable_tables & field->table->map))
{
- if (!eq_func || !value || value->type() != Item::NULL_ITEM ||
- !field->table->maybe_null || field->null_ptr)
+ if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
+ !field->table->maybe_null || field->null_ptr)
return; // Can't use left join optimize
exists_optimize=1;
}
else
{
JOIN_TAB *stat=field->table->reginfo.join_tab;
- stat[0].keys|=field->key_start; // Add possible keys
-
- if (!value)
- { // Probably BETWEEN or IN
- stat[0].const_keys |= field->key_start;
- return; // Can't be used as eq key
- }
+ key_map possible_keys= (field->key_start &
+ field->table->keys_in_use_for_query);
+ stat[0].keys|= possible_keys; // Add possible keys
/* Save the following cases:
Field op constant
@@ -1187,24 +1502,38 @@ add_key_field(KEY_FIELD **key_fields,uint and_level,
Field op formula
Field IS NULL
Field IS NOT NULL
+ Field BETWEEN ...
+ Field IN ...
*/
stat[0].key_dependent|=used_tables;
- if (value->const_item())
- stat[0].const_keys |= field->key_start;
+
+ bool is_const=1;
+ for (uint i=0; i<num_values; i++)
+ is_const&= (*value)->const_item();
+ if (is_const)
+ stat[0].const_keys |= possible_keys;
/* We can't always use indexes when comparing a string index to a
- number. cmp_type() is checked to allow compare of dates to numbers */
+ number. cmp_type() is checked to allow compare of dates to numbers
+ also eq_func is NEVER true when num_values > 1
+ */
if (!eq_func ||
field->result_type() == STRING_RESULT &&
- value->result_type() != STRING_RESULT &&
- field->cmp_type() != value->result_type())
+ (*value)->result_type() != STRING_RESULT &&
+ field->cmp_type() != (*value)->result_type())
return;
}
}
+ DBUG_ASSERT(num_values == 1);
+ /*
+ For the moment eq_func is always true. This slot is reserved for future
+ extensions where we want to remembers other things than just eq comparisons
+ */
+ DBUG_ASSERT(eq_func);
/* Store possible eq field */
(*key_fields)->field=field;
(*key_fields)->eq_func=eq_func;
- (*key_fields)->val=value;
+ (*key_fields)->val= *value;
(*key_fields)->level=(*key_fields)->const_level=and_level;
(*key_fields)->exists_optimize=exists_optimize;
(*key_fields)++;
@@ -1217,7 +1546,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
{
if (cond->type() == Item_func::COND_ITEM)
{
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
KEY_FIELD *org_key_fields= *key_fields;
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
@@ -1258,10 +1587,18 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
case Item_func::OPTIMIZE_NONE:
break;
case Item_func::OPTIMIZE_KEY:
+ // BETWEEN or IN
if (cond_func->key_item()->type() == Item::FIELD_ITEM)
add_key_field(key_fields,*and_level,
- ((Item_field*) (cond_func->key_item()))->field,
- 0,(Item*) 0,usable_tables);
+ ((Item_field*) (cond_func->key_item()))->field, 0,
+#ifndef TO_BE_REMOVED_IN_4_1
+ /* special treatment for IN. Not necessary in 4.1 */
+ cond_func->arguments() + (cond_func->functype() != Item_func::IN_FUNC),
+ cond_func->argument_count() - (cond_func->functype() != Item_func::IN_FUNC),
+#else
+ cond_func->arguments()+1, cond_func->argument_count()-1,
+#endif
+ usable_tables);
break;
case Item_func::OPTIMIZE_OP:
{
@@ -1273,7 +1610,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
add_key_field(key_fields,*and_level,
((Item_field*) (cond_func->arguments()[0]))->field,
equal_func,
- (cond_func->arguments()[1]),usable_tables);
+ cond_func->arguments()+1, 1, usable_tables);
}
if (cond_func->arguments()[1]->type() == Item::FIELD_ITEM &&
cond_func->functype() != Item_func::LIKE_FUNC)
@@ -1281,7 +1618,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
add_key_field(key_fields,*and_level,
((Item_field*) (cond_func->arguments()[1]))->field,
equal_func,
- (cond_func->arguments()[0]),usable_tables);
+ cond_func->arguments(),1,usable_tables);
}
break;
}
@@ -1289,10 +1626,13 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
/* column_name IS [NOT] NULL */
if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
{
+ Item *tmp=new Item_null;
+ if (!tmp) // Should never be true
+ return;
add_key_field(key_fields,*and_level,
((Item_field*) (cond_func->arguments()[0]))->field,
cond_func->functype() == Item_func::ISNULL_FUNC,
- new Item_null, usable_tables);
+ &tmp, 1, usable_tables);
}
break;
}
@@ -1300,8 +1640,8 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
}
/*
-** Add all keys with uses 'field' for some keypart
-** If field->and_level != and_level then only mark key_part as const_part
+ Add all keys with uses 'field' for some keypart
+ If field->and_level != and_level then only mark key_part as const_part
*/
static uint
@@ -1344,12 +1684,11 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
}
}
}
- /* Mark that we can optimize LEFT JOIN */
- if (key_field->val->type() == Item::NULL_ITEM &&
- !key_field->field->real_maybe_null())
- key_field->field->table->reginfo.not_exists_optimize=1;
}
+
+#define FT_KEYPART (MAX_REF_PARTS+10)
+
static void
add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
JOIN_TAB *stat,COND *cond,table_map usable_tables)
@@ -1369,55 +1708,41 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
{
Item_func *arg0=(Item_func *)(func->arguments()[0]),
*arg1=(Item_func *)(func->arguments()[1]);
- if ((functype == Item_func::GE_FUNC ||
- functype == Item_func::GT_FUNC) &&
- arg0->type() == Item::FUNC_ITEM &&
- arg0->functype() == Item_func::FT_FUNC &&
- arg1->const_item() && arg1->val()>0)
+ if (arg1->const_item() &&
+ ((functype == Item_func::GE_FUNC && arg1->val()> 0) ||
+ (functype == Item_func::GT_FUNC && arg1->val()>=0)) &&
+ arg0->type() == Item::FUNC_ITEM &&
+ arg0->functype() == Item_func::FT_FUNC)
cond_func=(Item_func_match *) arg0;
- else if ((functype == Item_func::LE_FUNC ||
- functype == Item_func::LT_FUNC) &&
+ else if (arg0->const_item() &&
+ ((functype == Item_func::LE_FUNC && arg0->val()> 0) ||
+ (functype == Item_func::LT_FUNC && arg0->val()>=0)) &&
arg1->type() == Item::FUNC_ITEM &&
- arg1->functype() == Item_func::FT_FUNC &&
- arg0->const_item() && arg0->val()>0)
+ arg1->functype() == Item_func::FT_FUNC)
cond_func=(Item_func_match *) arg1;
}
}
else if (cond->type() == Item::COND_ITEM)
{
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
{
Item *item;
- /*
- I', (Sergei) too lazy to implement proper recursive descent here,
- and anyway, nobody will use such a stupid queries
- that will require it :-)
- May be later...
- */
while ((item=li++))
- {
- if (item->type() == Item::FUNC_ITEM &&
- ((Item_func *)item)->functype() == Item_func::FT_FUNC)
- {
- cond_func=(Item_func_match *)item;
- break;
- }
- }
+ add_ft_keys(keyuse_array,stat,item,usable_tables);
}
}
- if(!cond_func)
+ if (!cond_func || cond_func->key == NO_SUCH_KEY ||
+ !(usable_tables & cond_func->table->map))
return;
KEYUSE keyuse;
-
keyuse.table= cond_func->table;
keyuse.val = cond_func;
keyuse.key = cond_func->key;
-#define FT_KEYPART (MAX_REF_PARTS+10)
- keyuse.keypart=FT_KEYPART;
+ keyuse.keypart= FT_KEYPART;
keyuse.used_tables=cond_func->key_item()->used_tables();
VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
}
@@ -1436,9 +1761,9 @@ sort_keyuse(KEYUSE *a,KEYUSE *b)
/*
-** Update keyuse array with all possible keys we can use to fetch rows
-** join_tab is a array in tablenr_order
-** stat is a reference array in 'prefered' order.
+ Update keyuse array with all possible keys we can use to fetch rows
+ join_tab is a array in tablenr_order
+ stat is a reference array in 'prefered' order.
*/
static bool
@@ -1446,40 +1771,47 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
uint tables, COND *cond, table_map normal_tables)
{
uint and_level,i,found_eq_constant;
+ KEY_FIELD *key_fields, *end, *field;
+ if (!(key_fields=(KEY_FIELD*)
+ thd->alloc(sizeof(key_fields[0])*(thd->cond_count+1)*2)))
+ return TRUE; /* purecov: inspected */
+ and_level=0; field=end=key_fields;
+ if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64))
+ return TRUE;
+ if (cond)
{
- KEY_FIELD *key_fields,*end;
-
- if (!(key_fields=(KEY_FIELD*)
- thd->alloc(sizeof(key_fields[0])*(thd->cond_count+1)*2)))
- return TRUE; /* purecov: inspected */
- and_level=0; end=key_fields;
- if (cond)
- add_key_fields(join_tab,&end,&and_level,cond,normal_tables);
- for (i=0 ; i < tables ; i++)
+ add_key_fields(join_tab,&end,&and_level,cond,normal_tables);
+ for (; field != end ; field++)
{
- if (join_tab[i].on_expr)
- {
- add_key_fields(join_tab,&end,&and_level,join_tab[i].on_expr,
- join_tab[i].table->map);
- }
- }
- if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64))
- return TRUE;
- /* fill keyuse with found key parts */
- for (KEY_FIELD *field=key_fields ; field != end ; field++)
add_key_part(keyuse,field);
+ /* Mark that we can optimize LEFT JOIN */
+ if (field->val->type() == Item::NULL_ITEM &&
+ !field->field->real_maybe_null())
+ field->field->table->reginfo.not_exists_optimize=1;
+ }
+ }
+ for (i=0 ; i < tables ; i++)
+ {
+ if (join_tab[i].on_expr)
+ {
+ add_key_fields(join_tab,&end,&and_level,join_tab[i].on_expr,
+ join_tab[i].table->map);
+ }
}
+ /* fill keyuse with found key parts */
+ for (; field != end ; field++)
+ add_key_part(keyuse,field);
- if (thd->lex.ftfunc_list.elements)
+ if (thd->lex.select->ftfunc_list.elements)
{
add_ft_keys(keyuse,join_tab,cond,normal_tables);
}
/*
- ** remove ref if there is a keypart which is a ref and a const.
- ** remove keyparts without previous keyparts.
- ** Special treatment for ft-keys. SerG.
+ Remove ref if there is a keypart which is a ref and a const.
+ Remove keyparts without previous keyparts.
+ Special treatment for ft-keys.
*/
if (keyuse->elements)
{
@@ -1529,8 +1861,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
/*****************************************************************************
-** Go through all combinations of not marked tables and find the one
-** which uses least records
+ Go through all combinations of not marked tables and find the one
+ which uses least records
*****************************************************************************/
/* Save const tables first as used tables */
@@ -1545,7 +1877,7 @@ set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
/* Move the const table as down as possible in best_ref */
JOIN_TAB **pos=join->best_ref+idx+1;
JOIN_TAB *next=join->best_ref[idx];
- for ( ;next != table ; pos++)
+ for (;next != table ; pos++)
{
JOIN_TAB *tmp=pos[0];
pos[0]=next;
@@ -1569,8 +1901,9 @@ static void
find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
double read_time)
{
- ulong rec;
+ ha_rows rec;
double tmp;
+ THD *thd= join->thd;
if (!rest_tables)
{
@@ -1579,7 +1912,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
read_time+=record_count/(double) TIME_FOR_COMPARE;
if (join->sort_by_table &&
- join->sort_by_table != join->positions[join->const_tables].table->table)
+ join->sort_by_table !=
+ join->positions[join->const_tables].table->table)
read_time+=record_count; // We have to make a temp table
if (read_time < join->best_read)
{
@@ -1603,6 +1937,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
best=best_time=records=DBL_MAX;
KEYUSE *best_key=0;
uint best_max_key_part=0;
+ my_bool found_constraint= 0;
if (s->keyuse)
{ /* Use key if possible */
@@ -1612,7 +1947,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
uint max_key_part=0;
/* Test how we can use keys */
- rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; /* Assumed records/key */
+ rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key
for (keyuse=s->keyuse ; keyuse->table == table ;)
{
key_map found_part=0;
@@ -1636,12 +1971,12 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
found_ref|= keyuse->used_tables;
}
/*
- ** If we find a ref, assume this table matches a proportional
- ** part of this table.
- ** For example 100 records matching a table with 5000 records
- ** gives 5000/100 = 50 records per key
- ** Constant tables are ignored and to avoid bad matches,
- ** we don't make rec less than 100.
+ If we find a ref, assume this table matches a proportional
+ part of this table.
+ For example 100 records matching a table with 5000 records
+ gives 5000/100 = 50 records per key
+ Constant tables are ignored and to avoid bad matches,
+ we don't make rec less than 100.
*/
if (keyuse->used_tables &
(map=(keyuse->used_tables & ~join->const_table_map)))
@@ -1662,7 +1997,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
} while (keyuse->table == table && keyuse->key == key);
/*
- ** Assume that that each key matches a proportional part of table.
+ Assume that that each key matches a proportional part of table.
*/
if (!found_part && !ft_key)
continue; // Nothing usable found
@@ -1670,26 +2005,28 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
rec=1L; // Fix for small tables
/*
- ** ft-keys require special treatment
+ ft-keys require special treatment
*/
if (ft_key)
{
/*
- ** Really, there should be records=0.0 (yes!)
- ** but 1.0 would be probably safer
+ Really, there should be records=0.0 (yes!)
+ but 1.0 would be probably safer
*/
tmp=prev_record_reads(join,found_ref);
records=1.0;
}
else
{
+ found_constraint= 1;
/*
- ** Check if we found full key
+ Check if we found full key
*/
if (found_part == PREV_BITS(uint,keyinfo->key_parts))
{ /* use eq key */
max_key_part= (uint) ~0;
- if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
+ if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
+ HA_END_SPACE_KEY)) == HA_NOSAME)
{
tmp=prev_record_reads(join,found_ref);
records=1.0;
@@ -1701,7 +2038,10 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
if (table->quick_keys & ((key_map) 1 << key))
records= (double) table->quick_rows[key];
else
- records= (double) s->records/rec; // quick_range couldn't use key!
+ {
+ /* quick_range couldn't use key! */
+ records= (double) s->records/rec;
+ }
}
else
{
@@ -1716,34 +2056,37 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
records=2.0; // Can't be as good as a unique
}
}
+ /* Limit the number of matched rows */
+ tmp= records;
+ set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
if (table->used_keys & ((key_map) 1 << key))
{
/* we can use only index tree */
uint keys_per_block= table->file->block_size/2/
- keyinfo->key_length+1;
- tmp=(record_count*(records+keys_per_block-1)/
- keys_per_block);
+ (keyinfo->key_length+table->file->ref_length)+1;
+ tmp=record_count*(tmp+keys_per_block-1)/keys_per_block;
}
else
- tmp=record_count*min(records,s->worst_seeks);
+ tmp=record_count*min(tmp,s->worst_seeks);
}
}
else
{
/*
- ** Use as much key-parts as possible and a uniq key is better
- ** than a not unique key
- ** Set tmp to (previous record count) * (records / combination)
+ Use as much key-parts as possible and a uniq key is better
+ than a not unique key
+ Set tmp to (previous record count) * (records / combination)
*/
if ((found_part & 1) &&
- !(table->file->option_flag() & HA_ONLY_WHOLE_INDEX))
+ !(table->file->index_flags(key) & HA_ONLY_WHOLE_INDEX))
{
max_key_part=max_part_bit(found_part);
- /* Check if quick_range could determinate how many rows we
- will match */
-
+ /*
+ Check if quick_range could determinate how many rows we
+ will match
+ */
if (table->quick_keys & ((key_map) 1 << key) &&
- table->quick_key_parts[key] <= max_key_part)
+ table->quick_key_parts[key] == max_key_part)
tmp=records= (double) table->quick_rows[key];
else
{
@@ -1753,18 +2096,18 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
else
{
/*
- ** Assume that the first key part matches 1% of the file
- ** and that the hole key matches 10 (dupplicates) or 1
- ** (unique) records.
- ** Assume also that more key matches proportionally more
- ** records
- ** This gives the formula:
- ** records= (x * (b-a) + a*c-b)/(c-1)
- **
- ** b = records matched by whole key
- ** a = records matched by first key part (10% of all records?)
- ** c = number of key parts in key
- ** x = used key parts (1 <= x <= c)
+ Assume that the first key part matches 1% of the file
+ and that the hole key matches 10 (duplicates) or 1
+ (unique) records.
+ Assume also that more key matches proportionally more
+ records
+ This gives the formula:
+ records= (x * (b-a) + a*c-b)/(c-1)
+
+ b = records matched by whole key
+ a = records matched by first key part (10% of all records?)
+ c = number of key parts in key
+ x = used key parts (1 <= x <= c)
*/
double rec_per_key;
if (!(rec_per_key=(double)
@@ -1785,12 +2128,22 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
}
records=(ulong) tmp;
}
+ /*
+ If quick_select was used on a part of this key, we know
+ the maximum number of rows that the key can match.
+ */
+ if (table->quick_keys & ((key_map) 1 << key) &&
+ table->quick_key_parts[key] <= max_key_part &&
+ records > (double) table->quick_rows[key])
+ tmp= records= (double) table->quick_rows[key];
}
+ /* Limit the number of matched rows */
+ set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
if (table->used_keys & ((key_map) 1 << key))
{
/* we can use only index tree */
uint keys_per_block= table->file->block_size/2/
- keyinfo->key_length+1;
+ (keyinfo->key_length+table->file->ref_length)+1;
tmp=record_count*(tmp+keys_per_block-1)/keys_per_block;
}
else
@@ -1815,24 +2168,84 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
/*
Don't test table scan if it can't be better.
Prefer key lookup if we would use the same key for scanning.
+
+ Don't do a table scan on InnoDB tables, if we can read the used
+ parts of the row from any of the used index.
+ This is because table scans uses index and we would not win
+ anything by using a table scan.
*/
if ((records >= s->found_records || best > s->read_time) &&
!(s->quick && best_key && s->quick->index == best_key->key &&
- best_max_key_part >= s->table->quick_key_parts[best_key->key]))
+ best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
+ !((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
+ s->table->used_keys && best_key) &&
+ !(s->table->force_index && best_key))
{ // Check full join
- if (s->on_expr)
- {
- tmp=s->found_records; // Can't use read cache
- }
- else
- {
- tmp=(double) s->read_time;
- /* Calculate time to read through cache */
- tmp*=(1.0+floor((double) cache_record_length(join,idx)*
- record_count/(double) join_buff_size));
- }
+ ha_rows rnd_records= s->found_records;
+ /*
+ If there is a restriction on the table, assume that 25% of the
+ rows can be skipped on next part.
+ This is to force tables that this table depends on before this
+ table
+ */
+ if (found_constraint)
+ rnd_records-= rnd_records/4;
+
+ /*
+ Range optimizer never proposes a RANGE if it isn't better
+ than FULL: so if RANGE is present, it's always preferred to FULL.
+ Here we estimate its cost.
+ */
+ if (s->quick)
+ {
+ /*
+ For each record we:
+ - read record range through 'quick'
+ - skip rows which does not satisfy WHERE constraints
+ */
+ tmp= record_count *
+ (s->quick->read_time +
+ (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE);
+ }
+ else
+ {
+ /* Estimate cost of reading table. */
+ tmp= s->table->file->scan_time();
+ if (s->on_expr) // Can't use join cache
+ {
+ /*
+ For each record we have to:
+ - read the whole table record
+ - skip rows which does not satisfy join condition
+ */
+ tmp= record_count *
+ (tmp +
+ (s->records - rnd_records)/(double) TIME_FOR_COMPARE);
+ }
+ else
+ {
+ /* We read the table as many times as join buffer becomes full. */
+ tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
+ record_count /
+ (double) thd->variables.join_buff_size));
+ /*
+ We don't make full cartesian product between rows in the scanned
+ table and existing records because we skip all rows from the
+ scanned table, which does not satisfy join condition when
+ we read the table (see flush_cached_records for details). Here we
+ take into account cost to read and skip these records.
+ */
+ tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
+ }
+ }
+
+ /*
+ We estimate the cost of evaluating WHERE clause for found records
+ as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus
+ tmp give us total cost of using TABLE SCAN
+ */
if (best == DBL_MAX ||
- (tmp + record_count/(double) TIME_FOR_COMPARE*s->found_records <
+ (tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records <
best + record_count/(double) TIME_FOR_COMPARE*records))
{
/*
@@ -1840,15 +2253,16 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
will ensure that this will be used
*/
best=tmp;
- records=s->found_records;
+ records= rows2double(rnd_records);
best_key=0;
}
}
- join->positions[idx].records_read=(double) records;
+ join->positions[idx].records_read= records;
join->positions[idx].key=best_key;
join->positions[idx].table= s;
if (!best_key && idx == join->const_tables &&
- s->table == join->sort_by_table)
+ s->table == join->sort_by_table &&
+ join->thd->select_limit >= records)
join->sort_by_table= (TABLE*) 1; // Must use temporary table
/*
@@ -1881,7 +2295,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
/*
-** Find how much space the prevous read not const tables takes in cache
+ Find how much space the prevous read not const tables takes in cache
*/
static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
@@ -1957,27 +2371,24 @@ prev_record_reads(JOIN *join,table_map found_ref)
/*****************************************************************************
-** Set up join struct according to best position.
+ Set up join struct according to best position.
*****************************************************************************/
static bool
get_best_combination(JOIN *join)
{
- uint i,key,tablenr;
+ uint i,tablenr;
table_map used_tables;
- TABLE *table;
JOIN_TAB *join_tab,*j;
KEYUSE *keyuse;
- KEY *keyinfo;
uint table_count;
+ THD *thd=join->thd;
table_count=join->tables;
if (!(join->join_tab=join_tab=
- (JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB)*table_count)))
+ (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
return TRUE;
- join->const_tables=0; /* for checking */
- join->const_table_map=0;
join->full_join=0;
used_tables=0;
@@ -1986,188 +2397,188 @@ get_best_combination(JOIN *join)
TABLE *form;
*j= *join->best_positions[tablenr].table;
form=join->table[tablenr]=j->table;
- j->ref.key = -1;
- j->ref.key_parts=0;
- j->info=0; // For describe
used_tables|= form->map;
form->reginfo.join_tab=j;
if (!j->on_expr)
form->reginfo.not_exists_optimize=0; // Only with LEFT JOIN
+ if (j->type == JT_CONST)
+ continue; // Handled in make_join_stat..
+
+ j->ref.key = -1;
+ j->ref.key_parts=0;
if (j->type == JT_SYSTEM)
- {
- j->table->const_table=1;
- if (join->const_tables == tablenr)
- {
- join->const_tables++;
- join->const_table_map|=form->map;
- }
continue;
- }
if (!j->keys || !(keyuse= join->best_positions[tablenr].key))
{
j->type=JT_ALL;
if (tablenr != join->const_tables)
join->full_join=1;
}
- else
- {
- uint keyparts,length;
- bool ftkey=(keyuse->keypart == FT_KEYPART);
- /*
- ** Use best key from find_best
- */
- table=j->table;
- key=keyuse->key;
+ else if (create_ref_for_key(join, j, keyuse, used_tables))
+ return TRUE; // Something went wrong
+ }
- keyinfo=table->key_info+key;
- if (ftkey)
- {
- Item_func_match *ifm=(Item_func_match *)keyuse->val;
+ for (i=0 ; i < table_count ; i++)
+ join->map2table[join->join_tab[i].table->tablenr]=join->join_tab+i;
+ update_depend_map(join);
+ return 0;
+}
- length=0;
- keyparts=1;
- ifm->join_key=1;
- }
- else
- {
- keyparts=length=0;
- do
- {
- if (!((~used_tables) & keyuse->used_tables))
- {
- if (keyparts == keyuse->keypart)
- {
- keyparts++;
- length+=keyinfo->key_part[keyuse->keypart].store_length;
- }
- }
- keyuse++;
- } while (keyuse->table == table && keyuse->key == key);
- } /* not ftkey */
-
- /* set up fieldref */
- keyinfo=table->key_info+key;
- j->ref.key_parts=keyparts;
- j->ref.key_length=length;
- j->ref.key=(int) key;
- if (!(j->ref.key_buff= (byte*) sql_calloc(ALIGN_SIZE(length)*2)) ||
- !(j->ref.key_copy= (store_key**) sql_alloc((sizeof(store_key*) *
- (keyparts+1)))) ||
- !(j->ref.items= (Item**) sql_alloc(sizeof(Item*)*keyparts)))
- {
- return TRUE;
- }
- j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
- j->ref.key_err=1;
- keyuse=join->best_positions[tablenr].key;
- store_key **ref_key=j->ref.key_copy;
- byte *key_buff=j->ref.key_buff;
- if (ftkey)
- {
- j->ref.items[0]=((Item_func*)(keyuse->val))->key_item();
- if (keyuse->used_tables)
- return TRUE; // not supported yet. SerG
+static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
+ table_map used_tables)
+{
+ KEYUSE *keyuse=org_keyuse;
+ bool ftkey=(keyuse->keypart == FT_KEYPART);
+ THD *thd= join->thd;
+ uint keyparts,length,key;
+ TABLE *table;
+ KEY *keyinfo;
- j->type=JT_FT;
- }
- else
- {
- THD *thd=join->thd;
- for (i=0 ; i < keyparts ; keyuse++,i++)
- {
- while (keyuse->keypart != i ||
- ((~used_tables) & keyuse->used_tables))
- keyuse++; /* Skipp other parts */
-
- uint maybe_null= test(keyinfo->key_part[i].null_bit);
- j->ref.items[i]=keyuse->val; // Save for cond removal
- if (!keyuse->used_tables &&
- !(join->select_options & SELECT_DESCRIBE))
- { // Compare against constant
- store_key_item *tmp=new store_key_item(keyinfo->key_part[i].field,
- (char*)key_buff +
- maybe_null,
- maybe_null ?
- (char*) key_buff : 0,
- keyinfo->key_part[i].length,
- keyuse->val);
- if (thd->fatal_error)
- {
- return TRUE;
- }
- tmp->copy();
- }
- else
- *ref_key++= get_store_key(keyuse,join->const_table_map,
- &keyinfo->key_part[i],
- (char*) key_buff,maybe_null);
- key_buff+=keyinfo->key_part[i].store_length;
- }
- } /* not ftkey */
- *ref_key=0; // end_marker
- if (j->type == JT_FT) /* no-op */;
- else if (j->type == JT_CONST)
+ /*
+ Use best key from find_best
+ */
+ table=j->table;
+ key=keyuse->key;
+ keyinfo=table->key_info+key;
+
+ if (ftkey)
+ {
+ Item_func_match *ifm=(Item_func_match *)keyuse->val;
+
+ length=0;
+ keyparts=1;
+ ifm->join_key=1;
+ }
+ else
+ {
+ keyparts=length=0;
+ do
+ {
+ if (!((~used_tables) & keyuse->used_tables))
{
- j->table->const_table=1;
- if (join->const_tables == tablenr)
+ if (keyparts == keyuse->keypart)
{
- join->const_tables++;
- join->const_table_map|=form->map;
+ keyparts++;
+ length+=keyinfo->key_part[keyuse->keypart].store_length;
}
}
- else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) != HA_NOSAME) ||
- keyparts != keyinfo->key_parts)
- j->type=JT_REF; /* Must read with repeat */
- else if (ref_key == j->ref.key_copy)
- { /* Should never be reached */
- /*
- This happen if we are using a constant expression in the ON part
- of an LEFT JOIN.
- SELECT * FROM a LEFT JOIN b ON b.key=30
- Here we should not mark the table as a 'const' as a field may
- have a 'normal' value or a NULL value.
- */
- j->type=JT_CONST;
- if (join->const_tables == tablenr && !form->fulltext_searched)
+ keyuse++;
+ } while (keyuse->table == table && keyuse->key == key);
+ } /* not ftkey */
+
+ /* set up fieldref */
+ keyinfo=table->key_info+key;
+ j->ref.key_parts=keyparts;
+ j->ref.key_length=length;
+ j->ref.key=(int) key;
+ if (!(j->ref.key_buff= (byte*) thd->calloc(ALIGN_SIZE(length)*2)) ||
+ !(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
+ (keyparts+1)))) ||
+ !(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts)))
+ {
+ return TRUE;
+ }
+ j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
+ j->ref.key_err=1;
+ keyuse=org_keyuse;
+
+ store_key **ref_key=j->ref.key_copy;
+ byte *key_buff=j->ref.key_buff;
+ if (ftkey)
+ {
+ j->ref.items[0]=((Item_func*)(keyuse->val))->key_item();
+ if (keyuse->used_tables)
+ return TRUE; // not supported yet. SerG
+
+ j->type=JT_FT;
+ }
+ else
+ {
+ uint i;
+ for (i=0 ; i < keyparts ; keyuse++,i++)
+ {
+ while (keyuse->keypart != i ||
+ ((~used_tables) & keyuse->used_tables))
+ keyuse++; /* Skip other parts */
+
+ uint maybe_null= test(keyinfo->key_part[i].null_bit);
+ j->ref.items[i]=keyuse->val; // Save for cond removal
+ if (!keyuse->used_tables &&
+ !(join->select_options & SELECT_DESCRIBE))
+ { // Compare against constant
+ store_key_item *tmp=new store_key_item(thd,
+ keyinfo->key_part[i].field,
+ (char*)key_buff +
+ maybe_null,
+ maybe_null ?
+ (char*) key_buff : 0,
+ keyinfo->key_part[i].length,
+ keyuse->val);
+ if (thd->fatal_error)
{
- join->const_tables++;
- join->const_table_map|=form->map;
+ return TRUE;
}
+ tmp->copy();
}
else
- j->type=JT_EQ_REF;
- }
+ *ref_key++= get_store_key(thd,
+ keyuse,join->const_table_map,
+ &keyinfo->key_part[i],
+ (char*) key_buff,maybe_null);
+ key_buff+=keyinfo->key_part[i].store_length;
+ }
+ } /* not ftkey */
+ *ref_key=0; // end_marker
+ if (j->type == JT_FT) /* no-op */;
+ else if (j->type == JT_CONST)
+ j->table->const_table=1;
+ else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
+ HA_END_SPACE_KEY)) != HA_NOSAME) ||
+ keyparts != keyinfo->key_parts)
+ j->type=JT_REF; /* Must read with repeat */
+ else if (ref_key == j->ref.key_copy)
+ {
+ /*
+ This happen if we are using a constant expression in the ON part
+ of an LEFT JOIN.
+ SELECT * FROM a LEFT JOIN b ON b.key=30
+ Here we should not mark the table as a 'const' as a field may
+ have a 'normal' value or a NULL value.
+ */
+ j->type=JT_CONST;
}
-
- for (i=0 ; i < table_count ; i++)
- join->map2table[join->join_tab[i].table->tablenr]=join->join_tab+i;
- update_depend_map(join);
+ else
+ j->type=JT_EQ_REF;
return 0;
}
+
static store_key *
-get_store_key(KEYUSE *keyuse, table_map used_tables, KEY_PART_INFO *key_part,
- char *key_buff, uint maybe_null)
+get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
+ KEY_PART_INFO *key_part, char *key_buff, uint maybe_null)
{
if (!((~used_tables) & keyuse->used_tables)) // if const item
{
- return new store_key_const_item(key_part->field,
+ return new store_key_const_item(thd,
+ key_part->field,
key_buff + maybe_null,
maybe_null ? key_buff : 0,
key_part->length,
keyuse->val);
}
else if (keyuse->val->type() == Item::FIELD_ITEM)
- return new store_key_field(key_part->field,
+ return new store_key_field(thd,
+ key_part->field,
key_buff + maybe_null,
maybe_null ? key_buff : 0,
key_part->length,
((Item_field*) keyuse->val)->field,
keyuse->val->full_name());
- return new store_key_item(key_part->field,
+ return new store_key_item(thd,
+ key_part->field,
key_buff + maybe_null,
maybe_null ? key_buff : 0,
key_part->length,
@@ -2175,15 +2586,16 @@ get_store_key(KEYUSE *keyuse, table_map used_tables, KEY_PART_INFO *key_part,
}
/*
-** This function is only called for const items on fields which are keys
-** returns 1 if there was some conversion made when the field was stored.
+ This function is only called for const items on fields which are keys
+ returns 1 if there was some conversion made when the field was stored.
*/
bool
store_val_in_field(Field *field,Item *item)
{
+ bool error;
THD *thd=current_thd;
- ulong cuted_fields=thd->cuted_fields;
+ ha_rows cuted_fields=thd->cuted_fields;
/*
we should restore old value of count_cuted_fields because
store_val_in_field can be called from mysql_insert
@@ -2191,9 +2603,9 @@ store_val_in_field(Field *field,Item *item)
*/
bool old_count_cuted_fields= thd->count_cuted_fields;
thd->count_cuted_fields=1;
- item->save_in_field(field);
+ error= item->save_in_field(field, 1);
thd->count_cuted_fields= old_count_cuted_fields;
- return cuted_fields != thd->cuted_fields;
+ return error || cuted_fields != thd->cuted_fields;
}
@@ -2211,13 +2623,15 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
join->tables=1;
join->const_tables=0;
join->const_table_map=0;
- join->tmp_table_param.copy_field_count=join->tmp_table_param.field_count=
- join->tmp_table_param.sum_func_count= join->tmp_table_param.func_count=0;
- join->tmp_table_param.copy_field=0;
+ join->tmp_table_param.field_count= join->tmp_table_param.sum_func_count=
+ join->tmp_table_param.func_count=0;
+ join->tmp_table_param.copy_field=join->tmp_table_param.copy_field_end=0;
join->first_record=join->sort_and_group=0;
join->sum_funcs=0;
join->send_records=(ha_rows) 0;
join->group=0;
+ join->do_send_rows = 1;
+ join->row_limit=join->thd->select_limit;
join_tab->cache.buff=0; /* No cacheing */
join_tab->table=tmp_table;
@@ -2248,6 +2662,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
table_map used_tables;
if (join->tables > 1)
cond->update_used_tables(); // Tablenr may have changed
+ if (join->const_tables == join->tables)
+ join->const_table_map|=RAND_TABLE_BIT;
{ // Check const tables
COND *const_cond=
make_cond_for_table(cond,join->const_table_map,(table_map) 0);
@@ -2281,7 +2697,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
use_quick_range=1;
tab->use_quick=1;
tab->ref.key_parts=0; // Don't use ref key.
- join->best_positions[i].records_read=tab->quick->records;
+ join->best_positions[i].records_read= rows2double(tab->quick->records);
}
COND *tmp=make_cond_for_table(cond,used_tables,current_map);
@@ -2297,7 +2713,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{
DBUG_EXECUTE("where",print_where(tmp,tab->table->table_name););
SQL_SELECT *sel=tab->select=(SQL_SELECT*)
- sql_memdup((gptr) select, sizeof(SQL_SELECT));
+ join->thd->memdup((gptr) select, sizeof(SQL_SELECT));
if (!sel)
DBUG_RETURN(1); // End of memory
tab->select_cond=sel->cond=tmp;
@@ -2339,17 +2755,37 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
*/
if ((tab->keys & ~ tab->const_keys && i > 0) ||
- tab->const_keys && i == join->const_tables &&
- join->thd->select_limit < join->best_positions[i].records_read)
+ (tab->const_keys && i == join->const_tables &&
+ join->thd->select_limit < join->best_positions[i].records_read &&
+ !(join->select_options & OPTION_FOUND_ROWS)))
{
/* Join with outer join condition */
COND *orig_cond=sel->cond;
sel->cond=and_conds(sel->cond,tab->on_expr);
- if (sel->test_quick_select(tab->keys,
+ if (sel->test_quick_select(join->thd, tab->keys,
used_tables & ~ current_map,
- join->thd->select_limit) < 0)
- DBUG_RETURN(1); // Impossible range
- sel->cond=orig_cond;
+ (join->select_options &
+ OPTION_FOUND_ROWS ?
+ HA_POS_ERROR :
+ join->thd->select_limit)) < 0)
+ { /* before reporting "Impossible WHERE" for the whole query
+ we have to check isn't it only "impossible ON" instead */
+ sel->cond=orig_cond;
+ if (!tab->on_expr ||
+ sel->test_quick_select(join->thd, tab->keys,
+ used_tables & ~ current_map,
+ (join->select_options &
+ OPTION_FOUND_ROWS ?
+ HA_POS_ERROR :
+ join->thd->select_limit)) < 0)
+ DBUG_RETURN(1); // Impossible WHERE
+ }
+ else
+ sel->cond=orig_cond;
+
+ /* Fix for EXPLAIN */
+ if (sel->quick)
+ join->best_positions[i].records_read= sel->quick->records;
}
else
{
@@ -2364,7 +2800,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
(select->quick &&
(select->quick->records >= 100L)))) ?
2 : 1;
- sel->read_tables= used_tables;
+ sel->read_tables= used_tables & ~current_map;
}
if (i != join->const_tables && tab->use_quick != 2)
{ /* Read with cache */
@@ -2374,8 +2810,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
current_map)))
{
DBUG_EXECUTE("where",print_where(tmp,"cache"););
- tab->cache.select=(SQL_SELECT*) sql_memdup((gptr) sel,
- sizeof(SQL_SELECT));
+ tab->cache.select=(SQL_SELECT*)
+ join->thd->memdup((gptr) sel, sizeof(SQL_SELECT));
tab->cache.select->cond=tmp;
tab->cache.select->read_tables=join->const_table_map;
}
@@ -2392,6 +2828,9 @@ static void
make_join_readinfo(JOIN *join,uint options)
{
uint i;
+ SELECT_LEX *select_lex = &(join->thd->lex.select_lex);
+ bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
+
DBUG_ENTER("make_join_readinfo");
for (i=join->const_tables ; i < join->tables ; i++)
@@ -2424,7 +2863,8 @@ make_join_readinfo(JOIN *join,uint options)
table->file->index_init(tab->ref.key);
tab->read_first_record= join_read_key;
tab->read_record.read_record= join_no_more_records;
- if (table->used_keys & ((key_map) 1 << tab->ref.key))
+ if (table->used_keys & ((key_map) 1 << tab->ref.key) &&
+ !table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
@@ -2441,8 +2881,9 @@ make_join_readinfo(JOIN *join,uint options)
tab->quick=0;
table->file->index_init(tab->ref.key);
tab->read_first_record= join_read_always_key;
- tab->read_record.read_record= join_read_next;
- if (table->used_keys & ((key_map) 1 << tab->ref.key))
+ tab->read_record.read_record= join_read_next_same;
+ if (table->used_keys & ((key_map) 1 << tab->ref.key) &&
+ !table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
@@ -2456,10 +2897,10 @@ make_join_readinfo(JOIN *join,uint options)
break;
case JT_ALL:
/*
- ** if previous table use cache
+ If previous table use cache
*/
table->status=STATUS_NO_RECORD;
- if (i != join->const_tables && (options & SELECT_USE_CACHE) &&
+ if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
tab->use_quick != 2 && !tab->on_expr)
{
if ((options & SELECT_DESCRIBE) ||
@@ -2472,9 +2913,10 @@ make_join_readinfo(JOIN *join,uint options)
/* These init changes read_record */
if (tab->use_quick == 2)
{
- join->thd->lex.options|=QUERY_NO_GOOD_INDEX_USED;
+ select_lex->options|=QUERY_NO_GOOD_INDEX_USED;
tab->read_first_record= join_init_quick_read_record;
- statistic_increment(select_range_check_count, &LOCK_status);
+ if (statistics)
+ statistic_increment(select_range_check_count, &LOCK_status);
}
else
{
@@ -2483,38 +2925,45 @@ make_join_readinfo(JOIN *join,uint options)
{
if (tab->select && tab->select->quick)
{
- statistic_increment(select_range_count, &LOCK_status);
+ if (statistics)
+ statistic_increment(select_range_count, &LOCK_status);
}
else
{
- join->thd->lex.options|=QUERY_NO_INDEX_USED;
- statistic_increment(select_scan_count, &LOCK_status);
+ select_lex->options|=QUERY_NO_INDEX_USED;
+ if (statistics)
+ statistic_increment(select_scan_count, &LOCK_status);
}
}
else
{
if (tab->select && tab->select->quick)
{
- statistic_increment(select_full_range_join_count, &LOCK_status);
+ if (statistics)
+ statistic_increment(select_full_range_join_count, &LOCK_status);
}
else
{
- join->thd->lex.options|=QUERY_NO_INDEX_USED;
- statistic_increment(select_full_join_count, &LOCK_status);
+ select_lex->options|=QUERY_NO_INDEX_USED;
+ if (statistics)
+ statistic_increment(select_full_join_count, &LOCK_status);
}
}
- if (tab->select && tab->select->quick &&
- table->used_keys & ((key_map) 1 << tab->select->quick->index))
+ if (!table->no_keyread)
{
- table->key_read=1;
- table->file->extra(HA_EXTRA_KEYREAD);
- }
- else if (table->used_keys && ! (tab->select && tab->select->quick))
- { // Only read index tree
- tab->index=find_shortest_key(table, table->used_keys);
- tab->table->file->index_init(tab->index);
- tab->read_first_record= join_init_read_first_with_key;
- tab->type=JT_NEXT; // Read with index_first / index_next
+ if (tab->select && tab->select->quick &&
+ table->used_keys & ((key_map) 1 << tab->select->quick->index))
+ {
+ table->key_read=1;
+ table->file->extra(HA_EXTRA_KEYREAD);
+ }
+ else if (table->used_keys && ! (tab->select && tab->select->quick))
+ { // Only read index tree
+ tab->index=find_shortest_key(table, table->used_keys);
+ tab->table->file->index_init(tab->index);
+ tab->read_first_record= join_read_first;
+ tab->type=JT_NEXT; // Read with index_first / index_next
+ }
}
}
break;
@@ -2531,6 +2980,38 @@ make_join_readinfo(JOIN *join,uint options)
}
+/*
+ Give error if we some tables are done with a full join
+
+ SYNOPSIS
+ error_if_full_join()
+ join Join condition
+
+ USAGE
+ This is used by multi_table_update and multi_table_delete when running
+ in safe mode
+
+ RETURN VALUES
+ 0 ok
+ 1 Error (full join used)
+*/
+
+bool error_if_full_join(JOIN *join)
+{
+ for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
+ tab < end;
+ tab++)
+ {
+ if (tab->type == JT_ALL && (!tab->select || !tab->select->quick))
+ {
+ my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,MYF(0));
+ return(1);
+ }
+ }
+ return(0);
+}
+
+
static void
join_free(JOIN *join)
{
@@ -2565,35 +3046,37 @@ join_free(JOIN *join)
}
join->table=0;
}
- // We are not using tables anymore
- // Unlock all tables. We may be in an INSERT .... SELECT statement.
- if (join->lock && join->thd->lock)
+ /*
+ We are not using tables anymore
+ Unlock all tables. We may be in an INSERT .... SELECT statement.
+ */
+ if (join->lock && join->thd->lock &&
+ !(join->select_options & SELECT_NO_UNLOCK))
{
mysql_unlock_read_tables(join->thd, join->lock);// Don't free join->lock
join->lock=0;
}
join->group_fields.delete_elements();
join->tmp_table_param.copy_funcs.delete_elements();
- delete [] join->tmp_table_param.copy_field;
- join->tmp_table_param.copy_field=0;
+ join->tmp_table_param.cleanup();
DBUG_VOID_RETURN;
}
/*****************************************************************************
-** Remove the following expressions from ORDER BY and GROUP BY:
-** Constant expressions
-** Expression that only uses tables that are of type EQ_REF and the reference
-** is in the ORDER list or if all refereed tables are of the above type.
-**
-** In the following, the X field can be removed:
-** SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
-** SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
-**
-** These can't be optimized:
-** SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
-** SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
-** SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
+ Remove the following expressions from ORDER BY and GROUP BY:
+ Constant expressions
+ Expression that only uses tables that are of type EQ_REF and the reference
+ is in the ORDER list or if all refereed tables are of the above type.
+
+ In the following, the X field can be removed:
+ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
+ SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
+
+ These can't be optimized:
+ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
+ SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
+ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
*****************************************************************************/
static bool
@@ -2624,7 +3107,7 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
if (order)
{
found++;
- dbug_assert(!(order->used & map));
+ DBUG_ASSERT(!(order->used & map));
order->used|=map;
continue; // Used in ORDER BY
}
@@ -2633,7 +3116,7 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
}
}
/* Check that there was no reference to table before sort order */
- for ( ; found && start_order ; start_order=start_order->next)
+ for (; found && start_order ; start_order=start_order->next)
{
if (start_order->used & map)
{
@@ -2651,7 +3134,7 @@ static bool
only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
{
if (specialflag & SPECIAL_SAFE_MODE)
- return 0; // skip this optimize /* purecov: inspected */
+ return 0; // skip this optimize /* purecov: inspected */
for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1)
{
if (tables & 1 && !eq_ref_table(join, order, *tab))
@@ -2667,7 +3150,7 @@ static void update_depend_map(JOIN *join)
{
JOIN_TAB *join_tab=join->join_tab, *end=join_tab+join->tables;
- for ( ; join_tab != end ; join_tab++)
+ for (; join_tab != end ; join_tab++)
{
TABLE_REF *ref= &join_tab->ref;
table_map depend_map=0;
@@ -2691,7 +3174,7 @@ static void update_depend_map(JOIN *join)
static void update_depend_map(JOIN *join, ORDER *order)
{
- for ( ; order ; order=order->next)
+ for (; order ; order=order->next)
{
table_map depend_map;
order->item[0]->update_used_tables();
@@ -2739,7 +3222,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order)
else if (!(order_tables & not_const_tables))
{
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
- continue; // skipp const item
+ continue; // skip const item
}
else
{
@@ -2774,16 +3257,17 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order)
DBUG_RETURN(first_order);
}
+
static int
-return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields,
- bool send_row, uint select_options,const char *info,
- Item *having, Procedure *procedure)
+return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
+ List<Item> &fields, bool send_row, uint select_options,
+ const char *info, Item *having, Procedure *procedure)
{
DBUG_ENTER("return_zero_rows");
if (select_options & SELECT_DESCRIBE)
{
- describe_info(current_thd, info);
+ describe_info(join, info);
DBUG_RETURN(0);
}
if (procedure)
@@ -2798,18 +3282,26 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields,
if (having && having->val_int() == 0)
send_row=0;
}
- if (!tables || !(result->send_fields(fields,1)))
+ if (!(result->send_fields(fields,1)))
{
if (send_row)
+ {
+ List_iterator_fast<Item> it(fields);
+ Item *item;
+ while ((item= it++))
+ item->no_rows_in_result();
result->send_data(fields);
- if (tables) // Not from do_select()
+ }
+ if (tables) // Not from do_select()
{
/* Close open cursors */
for (TABLE_LIST *table=tables; table ; table=table->next)
table->table->file->index_end();
- result->send_eof(); // Should be safe
}
+ result->send_eof(); // Should be safe
}
+ /* Update results for FOUND_ROWS */
+ join->thd->limit_found_rows= join->thd->examined_row_count= 0;
DBUG_RETURN(0);
}
@@ -2821,12 +3313,12 @@ static void clear_tables(JOIN *join)
}
/*****************************************************************************
-** Make som simple condition optimization:
-** If there is a test 'field = const' change all refs to 'field' to 'const'
-** Remove all dummy tests 'item = item', 'const op const'.
-** Remove all 'item is NULL', when item can never be null!
-** item->marker should be 0 for all items on entry
-** Return in cond_value FALSE if condition is impossible (1 = 2)
+ Make som simple condition optimization:
+ If there is a test 'field = const' change all refs to 'field' to 'const'
+ Remove all dummy tests 'item = item', 'const op const'.
+ Remove all 'item is NULL', when item can never be null!
+ item->marker should be 0 for all items on entry
+ Return in cond_value FALSE if condition is impossible (1 = 2)
*****************************************************************************/
class COND_CMP :public ilink {
@@ -2848,8 +3340,8 @@ template class List_iterator<Item_func_match>;
#endif
/*
-** change field = field to field = const for each found field = const in the
-** and_level
+ change field = field to field = const for each found field = const in the
+ and_level
*/
static void
@@ -2919,14 +3411,14 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
static void
-propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
+propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
COND *cond)
{
if (cond->type() == Item::COND_ITEM)
{
bool and_level= ((Item_cond*) cond)->functype() ==
Item_func::COND_AND_FUNC;
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
I_List<COND_CMP> save;
while ((item=li++))
@@ -2945,7 +3437,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
cond_cmp->cmp_func->arguments()[1]);
}
}
- else if (and_level != cond && !cond->marker) // In a AND group
+ else if (and_father != cond && !cond->marker) // In a AND group
{
if (cond->type() == Item::FUNC_ITEM &&
(((Item_func*) cond)->functype() == Item_func::EQ_FUNC ||
@@ -2963,7 +3455,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
func->arguments()[1]=resolve_const_item(func->arguments()[1],
func->arguments()[0]);
func->update_used_tables();
- change_cond_ref_to_const(save_list,and_level,and_level,
+ change_cond_ref_to_const(save_list,and_father,and_father,
func->arguments()[0],
func->arguments()[1]);
}
@@ -2972,7 +3464,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
func->arguments()[0]=resolve_const_item(func->arguments()[0],
func->arguments()[1]);
func->update_used_tables();
- change_cond_ref_to_const(save_list,and_level,and_level,
+ change_cond_ref_to_const(save_list,and_father,and_father,
func->arguments()[1],
func->arguments()[0]);
}
@@ -2994,8 +3486,8 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
DBUG_EXECUTE("where",print_where(conds,"original"););
propagate_cond_constants((I_List<COND_CMP> *) 0,conds,conds);
/*
- ** Remove all instances of item == item
- ** Remove all and-levels where CONST item != CONST item
+ Remove all instances of item == item
+ Remove all and-levels where CONST item != CONST item
*/
DBUG_EXECUTE("where",print_where(conds,"after const change"););
conds=remove_eq_conds(conds,cond_value) ;
@@ -3005,11 +3497,11 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
/*
-** remove const and eq items. Return new item, or NULL if no condition
-** cond_value is set to according:
-** COND_OK query is possible (field = constant)
-** COND_TRUE always true ( 1 = 1 )
-** COND_FALSE always false ( 1 = 2 )
+ Remove const and eq items. Return new item, or NULL if no condition
+ cond_value is set to according:
+ COND_OK query is possible (field = constant)
+ COND_TRUE always true ( 1 = 1 )
+ COND_FALSE always false ( 1 = 2 )
*/
static COND *
@@ -3085,13 +3577,13 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
{
/*
- ** Handles this special case for some ODBC applications:
- ** The are requesting the row that was just updated with a auto_increment
- ** value with this construct:
- **
- ** SELECT * from table_name where auto_increment_column IS NULL
- ** This will be changed to:
- ** SELECT * from table_name where auto_increment_column = LAST_INSERT_ID
+ Handles this special case for some ODBC applications:
+ The are requesting the row that was just updated with a auto_increment
+ value with this construct:
+
+ SELECT * from table_name where auto_increment_column IS NULL
+ This will be changed to:
+ SELECT * from table_name where auto_increment_column = LAST_INSERT_ID
*/
Item_func_isnull *func=(Item_func_isnull*) cond;
@@ -3104,6 +3596,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
(thd->options & OPTION_AUTO_IS_NULL) &&
thd->insert_id())
{
+ query_cache_abort(&thd->net);
COND *new_cond;
if ((new_cond= new Item_func_eq(args[0],
new Item_int("last_insert_id()",
@@ -3147,11 +3640,11 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
}
}
*cond_value=Item::COND_OK;
- return cond; /* Point at next and level */
+ return cond; // Point at next and level
}
/*
-** Return 1 if the item is a const value in all the WHERE clause
+ Return 1 if the item is a const value in all the WHERE clause
*/
static bool
@@ -3161,7 +3654,7 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
{
bool and_level= (((Item_cond*) cond)->functype()
== Item_func::COND_AND_FUNC);
- List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
while ((item=li++))
{
@@ -3210,14 +3703,36 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
/****************************************************************************
-** Create a temp table according to a field list.
-** Set distinct if duplicates could be removed
-** Given fields field pointers are changed to point at tmp_table
-** for send_fields
+ Create internal temporary table
****************************************************************************/
-Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
- Item_result_field ***copy_func, Field **from_field,
+/*
+ Create field for temporary table
+
+ SYNOPSIS
+ create_tmp_field()
+ thd Thread handler
+ table Temporary table
+ item Item to create a field for
+ type Type of item (normally item->type)
+ copy_func If set and item is a function, store copy of item
+ in this array
+ group 1 if we are going to do a relative group by on result
+ modify_item 1 if item->result_field should point to new item.
+ This is relevent for how fill_record() is going to
+ work:
+ If modify_item is 1 then fill_record() will update
+ the record in the original table.
+ If modify_item is 0 then fill_record() will update
+ the temporary table
+
+ RETURN
+ 0 on error
+ new_created field
+*/
+
+Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
+ Item ***copy_func, Field **from_field,
bool group, bool modify_item)
{
switch (type) {
@@ -3249,7 +3764,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
item->name,table,item_sum->decimals);
case INT_RESULT:
return new Field_longlong(item_sum->max_length,maybe_null,
- item->name,table);
+ item->name,table,item->unsigned_flag);
case STRING_RESULT:
if (item_sum->max_length > 255)
return new Field_blob(item_sum->max_length,maybe_null,
@@ -3258,7 +3773,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
item->name,table,item->binary);
}
}
- current_thd->fatal_error=1;
+ thd->fatal_error=1;
return 0; // Error
}
case Item::FIELD_ITEM:
@@ -3266,7 +3781,8 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
Field *org_field=((Item_field*) item)->field,*new_field;
*from_field=org_field;
- if ((new_field= org_field->new_field(table))) // Should always be true
+ // The following should always be true
+ if ((new_field= org_field->new_field(&thd->mem_root,table)))
{
if (modify_item)
((Item_field*) item)->result_field= new_field;
@@ -3274,20 +3790,23 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
new_field->field_name=item->name;
if (org_field->maybe_null())
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
+ if (org_field->type()==FIELD_TYPE_VAR_STRING)
+ table->db_create_options|= HA_OPTION_PACK_RECORD;
}
return new_field;
}
- case Item::PROC_ITEM:
case Item::FUNC_ITEM:
case Item::COND_ITEM:
case Item::FIELD_AVG_ITEM:
case Item::FIELD_STD_ITEM:
/* The following can only happen with 'CREATE TABLE ... SELECT' */
+ case Item::PROC_ITEM:
case Item::INT_ITEM:
case Item::REAL_ITEM:
case Item::STRING_ITEM:
case Item::REF_ITEM:
case Item::NULL_ITEM:
+ case Item::VARBIN_ITEM:
{
bool maybe_null=item->maybe_null;
Field *new_field;
@@ -3300,7 +3819,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
break;
case INT_RESULT:
new_field=new Field_longlong(item->max_length,maybe_null,
- item->name,table);
+ item->name,table, item->unsigned_flag);
break;
case STRING_RESULT:
if (item->max_length > 255)
@@ -3311,10 +3830,10 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
item->name,table,item->binary);
break;
}
- if (copy_func)
- *((*copy_func)++) = (Item_result_field*) item; // Save for copy_funcs
+ if (copy_func && item->is_result_field())
+ *((*copy_func)++) = item; // Save for copy_funcs
if (modify_item)
- ((Item_result_field*) item)->result_field=new_field;
+ item->set_result_field(new_field);
return new_field;
}
default: // Dosen't have to be stored
@@ -3323,16 +3842,24 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
}
+/*
+ Create a temp table according to a field list.
+ Set distinct if duplicates could be removed
+ Given fields field pointers are changed to point at tmp_table
+ for send_fields
+*/
+
TABLE *
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
- bool allow_distinct_limit, uint select_options)
+ bool allow_distinct_limit, ulong select_options)
{
TABLE *table;
uint i,field_count,reclength,null_count,null_pack_length,
hidden_null_count, hidden_null_pack_length, hidden_field_count,
blob_count,group_null_items;
bool using_unique_constraint=0;
+ bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
char *tmpname,path[FN_REFLEN];
byte *pos,*group_buff;
uchar *null_flags;
@@ -3340,7 +3867,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
Copy_field *copy=0;
KEY *keyinfo;
KEY_PART_INFO *key_part_info;
- Item_result_field **copy_func;
+ Item **copy_func;
MI_COLUMNDEF *recinfo;
uint temp_pool_slot=MY_BIT_NONE;
@@ -3355,7 +3882,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
temp_pool_slot = bitmap_set_next(&temp_pool);
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
- sprintf(path, "%s%s_%lx_%i", mysql_tmpdir, tmp_file_prefix,
+ sprintf(path, "%s%s_%lx_%i", mysql_tmpdir, tmp_file_prefix,
current_pid, temp_pool_slot);
else // if we run out of slots or we are not using tempool
sprintf(path,"%s%s%lx_%lx_%x",mysql_tmpdir,tmp_file_prefix,current_pid,
@@ -3396,15 +3923,15 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
NullS))
{
bitmap_clear_bit(&temp_pool, temp_pool_slot);
- DBUG_RETURN(NULL); /* purecov: inspected */
+ DBUG_RETURN(NULL); /* purecov: inspected */
}
if (!(param->copy_field=copy=new Copy_field[field_count]))
{
bitmap_clear_bit(&temp_pool, temp_pool_slot);
- my_free((gptr) table,MYF(0)); /* purecov: inspected */
- DBUG_RETURN(NULL); /* purecov: inspected */
+ my_free((gptr) table,MYF(0)); /* purecov: inspected */
+ DBUG_RETURN(NULL); /* purecov: inspected */
}
- param->funcs=copy_func;
+ param->items_to_copy= copy_func;
strmov(tmpname,path);
/* make table according to fields */
@@ -3432,24 +3959,27 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
reclength=blob_count=null_count=hidden_null_count=group_null_items=0;
param->using_indirect_summary_function=0;
- List_iterator<Item> li(fields);
+ List_iterator_fast<Item> li(fields);
Item *item;
Field **tmp_from_field=from_field;
while ((item=li++))
{
Item::Type type=item->type();
- if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
+ if (not_all_columns)
{
- /*
- Mark that the we have ignored an item that refers to a summary
- function. We need to know this if someone is going to use
- DISTINCT on the result.
- */
- param->using_indirect_summary_function=1;
- continue;
+ if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
+ {
+ /*
+ Mark that the we have ignored an item that refers to a summary
+ function. We need to know this if someone is going to use
+ DISTINCT on the result.
+ */
+ param->using_indirect_summary_function=1;
+ continue;
+ }
+ if (item->const_item() && (int) hidden_field_count <= 0)
+ continue; // We don't have to store this
}
- if (item->const_item()) // We don't have to store this
- continue;
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
{ /* Can't calc group yet */
((Item_sum*) item)->result_field=0;
@@ -3459,8 +3989,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!arg->const_item())
{
Field *new_field=
- create_tmp_field(table,arg,arg->type(),&copy_func,tmp_from_field,
- group != 0,1);
+ create_tmp_field(thd, table,arg,arg->type(),&copy_func,
+ tmp_from_field, group != 0,not_all_columns);
if (!new_field)
goto err; // Should be OOM
tmp_from_field++;
@@ -3479,8 +4009,19 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
else
{
- Field *new_field=create_tmp_field(table,item,type,&copy_func,
- tmp_from_field, group != 0,1);
+ /*
+ The last parameter to create_tmp_field() is a bit tricky:
+
+ We need to set it to 0 in union, to get fill_record() to modify the
+ temporary table.
+ We need to set it to 1 on multi-table-update and in select to
+ write rows to the temporary table.
+ We here distinguish between UNION and multi-table-updates by the fact
+ that in the later case group is set to the row pointer.
+ */
+ Field *new_field=create_tmp_field(thd, table, item,type, &copy_func,
+ tmp_from_field, group != 0,
+ not_all_columns || group !=0);
if (!new_field)
{
if (thd->fatal_error)
@@ -3508,11 +4049,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!--hidden_field_count)
hidden_null_count=null_count;
}
+ DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
field_count= (uint) (reg_field - table->field);
*blob_field= 0; // End marker
/* If result table is small; use a heap */
- if (blob_count || using_unique_constraint || group_null_items ||
+ if (blob_count || using_unique_constraint ||
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
OPTION_BIG_TABLES)
{
@@ -3580,6 +4122,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
{
if (field->flags & GROUP_FLAG && !using_unique_constraint)
{
+ /*
+ We have to reserve one byte here for NULL bits,
+ as this is updated by 'end_update()'
+ */
*pos++=0; // Null is stored here
recinfo->length=1;
recinfo->type=FIELD_NORMAL;
@@ -3614,23 +4160,24 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(field->type() == FIELD_TYPE_STRING ||
field->type() == FIELD_TYPE_VAR_STRING) &&
length >= 10 && blob_count)
- recinfo->type=FIELD_SKIPP_ENDSPACE;
+ recinfo->type=FIELD_SKIP_ENDSPACE;
else
recinfo->type=FIELD_NORMAL;
if (!--hidden_field_count)
null_count=(null_count+7) & ~7; // move to next byte
}
- param->copy_field_count=(uint) (copy - param->copy_field);
+ param->copy_field_end=copy;
param->recinfo=recinfo;
store_record(table,2); // Make empty default record
- if (tmp_table_size == ~(ulong) 0) // No limit
+ if (thd->variables.tmp_table_size == ~(ulong) 0) // No limit
table->max_rows= ~(ha_rows) 0;
else
table->max_rows=(((table->db_type == DB_TYPE_HEAP) ?
- min(tmp_table_size, max_heap_table_size) :
- tmp_table_size)/ table->reclength);
+ min(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size)/ table->reclength);
set_if_bigger(table->max_rows,1); // For dummy start options
keyinfo=param->keyinfo;
@@ -3663,7 +4210,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!using_unique_constraint)
{
group->buff=(char*) group_buff;
- if (!(group->field=field->new_field(table)))
+ if (!(group->field=field->new_field(&thd->mem_root,table)))
goto err; /* purecov: inspected */
if (maybe_null)
{
@@ -3696,6 +4243,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
'param->hidden_field_count' extra columns, whose null bits are stored
in the first 'hidden_null_pack_length' bytes of the row.
*/
+ DBUG_PRINT("info",("hidden_field_count: %d", param->hidden_field_count));
+
null_pack_length-=hidden_null_pack_length;
keyinfo->key_parts= ((field_count-param->hidden_field_count)+
test(null_pack_length));
@@ -3718,7 +4267,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
goto err;
table->key_info=keyinfo;
keyinfo->key_part=key_part_info;
- keyinfo->flags=HA_NOSAME;
+ keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
keyinfo->key_length=(uint16) reclength;
keyinfo->name=(char*) "tmp";
if (null_pack_length)
@@ -3786,15 +4335,13 @@ static bool open_tmp_table(TABLE *table)
table->db_stat=0;
return(1);
}
- /* VOID(ha_lock(table,F_WRLCK)); */ /* Single thread table */
- (void) table->file->extra(HA_EXTRA_NO_READCHECK); /* Not needed */
(void) table->file->extra(HA_EXTRA_QUICK); /* Faster */
return(0);
}
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- uint options)
+ ulong options)
{
int error;
MI_KEYDEF keydef;
@@ -3841,10 +4388,10 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
{
Field *field=keyinfo->key_part[i].field;
- seg->flag=0;
- seg->language=MY_CHARSET_CURRENT;
- seg->length=keyinfo->key_part[i].length;
- seg->start=keyinfo->key_part[i].offset;
+ seg->flag= 0;
+ seg->language= MY_CHARSET_CURRENT;
+ seg->length= keyinfo->key_part[i].length;
+ seg->start= keyinfo->key_part[i].offset;
if (field->flags & BLOB_FLAG)
{
seg->type=
@@ -3939,12 +4486,11 @@ free_tmp_table(THD *thd, TABLE *entry)
* If a HEAP table gets full, create a MyISAM table and copy all rows to this
*/
-bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error,
- bool ignore_last_dupp_key_error)
+bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
+ int error, bool ignore_last_dupp_key_error)
{
TABLE new_table;
const char *save_proc_info;
- THD *thd=current_thd;
int write_err;
DBUG_ENTER("create_myisam_from_heap");
@@ -3962,12 +4508,18 @@ bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error,
thd->proc_info="converting HEAP to MyISAM";
if (create_myisam_tmp_table(&new_table,param,
- thd->lex.options | thd->options))
+ thd->lex.select_lex.options | thd->options))
goto err2;
if (open_tmp_table(&new_table))
goto err1;
table->file->index_end();
table->file->rnd_init();
+ if (table->no_rows)
+ {
+ new_table.file->extra(HA_EXTRA_NO_ROWS);
+ new_table.no_rows=1;
+ }
+
/* copy all old rows */
while (!table->file->rnd_next(new_table.record[1]))
{
@@ -4008,9 +4560,12 @@ bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error,
}
-/*****************************************************************************
-** Make a join of all tables and write it on socket or to table
-*****************************************************************************/
+/****************************************************************************
+ Make a join of all tables and write it on socket or to table
+ Return: 0 if ok
+ 1 if error is sent
+ -1 if error should be sent
+****************************************************************************/
static int
do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
@@ -4022,7 +4577,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
join->procedure=procedure;
/*
- ** Tell the client how many fields there are in a row
+ Tell the client how many fields there are in a row
*/
if (!table)
join->result->send_fields(*fields,1);
@@ -4087,41 +4642,45 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
if (error == -3)
error=0; /* select_limit used */
}
- if (!table) /* If sending data to client */
+
+ /* Return 1 if error is sent; -1 if error should be sent */
+ if (error < 0)
{
- if (error < 0)
- join->result->send_error(0,NullS); /* purecov: inspected */
- else
+ join->result->send_error(0,NullS); /* purecov: inspected */
+ error=1; // Error sent
+ }
+ else
+ {
+ error=0;
+ if (!table) // If sending data to client
{
- join_free(join); // Unlock all cursors
+ /*
+ The following will unlock all cursors if the command wasn't an
+ update command
+ */
+ join_free(join);
if (join->result->send_eof())
- error= -1;
+ error= 1; // Don't send error
}
- }
- else if (error < 0)
- join->result->send_error(0,NullS); /* purecov: inspected */
-
- if (error >= 0)
- {
DBUG_PRINT("info",("%ld records output",join->send_records));
}
if (table)
{
- int old_error=error,tmp;
+ int tmp;
if ((tmp=table->file->extra(HA_EXTRA_NO_CACHE)))
{
my_errno=tmp;
error= -1;
}
- if (table->file->index_end())
+ if ((tmp=table->file->index_end()))
{
my_errno=tmp;
error= -1;
}
- if (error != old_error)
+ if (error == -1)
table->file->print_error(my_errno,MYF(0));
}
- DBUG_RETURN(error < 0);
+ DBUG_RETURN(error);
}
@@ -4190,6 +4749,11 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
{
if ((error=(*join_tab->next_select)(join,join_tab+1,0)) < 0)
return error;
+ /*
+ Test if this was a SELECT DISTINCT query on a table that
+ was not in the field list; In this case we can abort if
+ we found a row, as no new rows can be added to the result.
+ */
if (not_used_in_distinct && found_records != join->found_records)
return 0;
}
@@ -4197,10 +4761,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
info->file->unlock_row();
}
} while (!(error=info->read_record(info)));
- if (error > 0) // Fatal error
- return -1;
}
- else if (error > 0)
+ if (error > 0) // Fatal error
return -1;
if (!found && on_expr)
@@ -4286,50 +4848,48 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skipp_last)
/*****************************************************************************
-** The different ways to read a record
-** Returns -1 if row was not found, 0 if row was found and 1 on errors
+ The different ways to read a record
+ Returns -1 if row was not found, 0 if row was found and 1 on errors
*****************************************************************************/
-
static int
-join_read_const_tables(JOIN *join)
+join_read_const_table(JOIN_TAB *tab, POSITION *pos)
{
- uint i;
int error;
- DBUG_ENTER("join_read_const_tables");
- for (i=0 ; i < join->const_tables ; i++)
- {
- TABLE *form=join->table[i];
- form->null_row=0;
- form->status=STATUS_NO_RECORD;
-
- if (join->join_tab[i].type == JT_SYSTEM)
- {
- if ((error=join_read_system(join->join_tab+i)))
- { // Info for DESCRIBE
- join->join_tab[i].info="const row not found";
- join->best_positions[i].records_read=0.0;
- if (!form->outer_join || error > 0)
- DBUG_RETURN(error);
- }
- }
- else
- {
- if ((error=join_read_const(join->join_tab+i)))
- {
- join->join_tab[i].info="unique row not found";
- join->best_positions[i].records_read=0.0;
- if (!form->outer_join || error > 0)
- DBUG_RETURN(error);
- }
+ DBUG_ENTER("join_read_const_table");
+ TABLE *table=tab->table;
+ table->const_table=1;
+ table->null_row=0;
+ table->status=STATUS_NO_RECORD;
+
+ if (tab->type == JT_SYSTEM)
+ {
+ if ((error=join_read_system(tab)))
+ { // Info for DESCRIBE
+ tab->info="const row not found";
+ /* Mark for EXPLAIN that the row was not found */
+ pos->records_read=0.0;
+ if (!table->outer_join || error > 0)
+ DBUG_RETURN(error);
}
- if (join->join_tab[i].on_expr && !form->null_row)
+ }
+ else
+ {
+ if ((error=join_read_const(tab)))
{
- if ((form->null_row= test(join->join_tab[i].on_expr->val_int() == 0)))
- empty_record(form);
+ tab->info="unique row not found";
+ /* Mark for EXPLAIN that the row was not found */
+ pos->records_read=0.0;
+ if (!table->outer_join || error > 0)
+ DBUG_RETURN(error);
}
- if (!form->null_row)
- form->maybe_null=0;
}
+ if (tab->on_expr && !table->null_row)
+ {
+ if ((table->null_row= test(tab->on_expr->val_int() == 0)))
+ empty_record(table);
+ }
+ if (!table->null_row)
+ table->maybe_null=0;
DBUG_RETURN(0);
}
@@ -4341,7 +4901,8 @@ join_read_system(JOIN_TAB *tab)
int error;
if (table->status & STATUS_GARBAGE) // If first read
{
- if ((error=table->file->rnd_first(table->record[0])))
+ if ((error=table->file->read_first_row(table->record[0],
+ table->primary_key)))
{
if (error != HA_ERR_END_OF_FILE)
{
@@ -4382,7 +4943,10 @@ join_read_const(JOIN_TAB *tab)
empty_record(table);
if (error != HA_ERR_KEY_NOT_FOUND)
{
- sql_print_error("read_const: Got error %d when reading table %s",
+ /* Locking reads can legally return also these errors, do not
+ print them to the .err log */
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error("read_const: Got error %d when reading table %s",
error, table->path);
table->file->print_error(error,MYF(0));
return 1;
@@ -4445,7 +5009,38 @@ join_read_always_key(JOIN_TAB *tab)
{
if (error != HA_ERR_KEY_NOT_FOUND)
{
- sql_print_error("read_const: Got error %d when reading table %s",error,
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error("read_const: Got error %d when reading table %s",error,
+ table->path);
+ table->file->print_error(error,MYF(0));
+ return 1;
+ }
+ return -1; /* purecov: inspected */
+ }
+ return 0;
+}
+
+/*
+ This function is used when optimizing away ORDER BY in
+ SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
+*/
+
+static int
+join_read_last_key(JOIN_TAB *tab)
+{
+ int error;
+ TABLE *table= tab->table;
+
+ if (cp_buffer_from_ref(&tab->ref))
+ return -1;
+ if ((error=table->file->index_read_last(table->record[0],
+ tab->ref.key_buff,
+ tab->ref.key_length)))
+ {
+ if (error != HA_ERR_KEY_NOT_FOUND)
+ {
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error("read_const: Got error %d when reading table %s",error,
table->path);
table->file->print_error(error,MYF(0));
return 1;
@@ -4465,7 +5060,7 @@ join_no_more_records(READ_RECORD *info __attribute__((unused)))
static int
-join_read_next(READ_RECORD *info)
+join_read_next_same(READ_RECORD *info)
{
int error;
TABLE *table= info->table;
@@ -4477,7 +5072,8 @@ join_read_next(READ_RECORD *info)
{
if (error != HA_ERR_END_OF_FILE)
{
- sql_print_error("read_next: Got error %d when reading table %s",error,
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error("read_next: Got error %d when reading table %s",error,
table->path);
table->file->print_error(error,MYF(0));
return 1;
@@ -4488,6 +5084,38 @@ join_read_next(READ_RECORD *info)
return 0;
}
+static int
+join_read_prev_same(READ_RECORD *info)
+{
+ int error;
+ TABLE *table= info->table;
+ JOIN_TAB *tab=table->reginfo.join_tab;
+
+ if ((error=table->file->index_prev(table->record[0])))
+ {
+ if (error != HA_ERR_END_OF_FILE)
+ {
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error("read_next: Got error %d when reading table %s",error,
+ table->path);
+ table->file->print_error(error,MYF(0));
+ error= 1;
+ }
+ else
+ {
+ table->status= STATUS_GARBAGE;
+ error= -1;
+ }
+ }
+ else if (key_cmp(table, tab->ref.key_buff, tab->ref.key,
+ tab->ref.key_length))
+ {
+ table->status=STATUS_NOT_FOUND;
+ error= -1;
+ }
+ return error;
+}
+
static int
join_init_quick_read_record(JOIN_TAB *tab)
@@ -4503,7 +5131,8 @@ test_if_quick_select(JOIN_TAB *tab)
{
delete tab->select->quick;
tab->select->quick=0;
- return tab->select->test_quick_select(tab->keys,(table_map) 0,HA_POS_ERROR);
+ return tab->select->test_quick_select(tab->join->thd, tab->keys,
+ (table_map) 0, HA_POS_ERROR);
}
@@ -4518,17 +5147,18 @@ join_init_read_record(JOIN_TAB *tab)
}
static int
-join_init_read_first_with_key(JOIN_TAB *tab)
+join_read_first(JOIN_TAB *tab)
{
int error;
TABLE *table=tab->table;
- if (!table->key_read && (table->used_keys & ((key_map) 1 << tab->index)))
+ if (!table->key_read && (table->used_keys & ((key_map) 1 << tab->index)) &&
+ !table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
tab->table->status=0;
- tab->read_record.read_record=join_init_read_next_with_key;
+ tab->read_record.read_record=join_read_next;
tab->read_record.table=table;
tab->read_record.file=table->file;
tab->read_record.index=tab->index;
@@ -4538,7 +5168,8 @@ join_init_read_first_with_key(JOIN_TAB *tab)
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
{
- sql_print_error("read_first_with_key: Got error %d when reading table",
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error("read_first_with_key: Got error %d when reading table",
error);
table->file->print_error(error,MYF(0));
return 1;
@@ -4548,15 +5179,18 @@ join_init_read_first_with_key(JOIN_TAB *tab)
return 0;
}
+
static int
-join_init_read_next_with_key(READ_RECORD *info)
+join_read_next(READ_RECORD *info)
{
int error=info->file->index_next(info->record);
if (error)
{
if (error != HA_ERR_END_OF_FILE)
{
- sql_print_error("read_next_with_key: Got error %d when reading table %s",
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error(
+ "read_next_with_key: Got error %d when reading table %s",
error, info->table->path);
info->file->print_error(error,MYF(0));
return 1;
@@ -4566,19 +5200,19 @@ join_init_read_next_with_key(READ_RECORD *info)
return 0;
}
-
static int
-join_init_read_last_with_key(JOIN_TAB *tab)
+join_read_last(JOIN_TAB *tab)
{
TABLE *table=tab->table;
int error;
- if (!table->key_read && (table->used_keys & ((key_map) 1 << tab->index)))
+ if (!table->key_read && (table->used_keys & ((key_map) 1 << tab->index)) &&
+ !table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
tab->table->status=0;
- tab->read_record.read_record=join_init_read_prev_with_key;
+ tab->read_record.read_record=join_read_prev;
tab->read_record.table=table;
tab->read_record.file=table->file;
tab->read_record.index=tab->index;
@@ -4588,7 +5222,8 @@ join_init_read_last_with_key(JOIN_TAB *tab)
{
if (error != HA_ERR_END_OF_FILE)
{
- sql_print_error("read_last_with_key: Got error %d when reading table",
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error("read_last_with_key: Got error %d when reading table",
error, table->path);
table->file->print_error(error,MYF(0));
return 1;
@@ -4598,15 +5233,18 @@ join_init_read_last_with_key(JOIN_TAB *tab)
return 0;
}
+
static int
-join_init_read_prev_with_key(READ_RECORD *info)
+join_read_prev(READ_RECORD *info)
{
int error=info->file->index_prev(info->record);
if (error)
{
if (error != HA_ERR_END_OF_FILE)
{
- sql_print_error("read_prev_with_key: Got error %d when reading table: %s",
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error(
+ "read_prev_with_key: Got error %d when reading table: %s",
error,info->table->path);
info->file->print_error(error,MYF(0));
return 1;
@@ -4616,13 +5254,14 @@ join_init_read_prev_with_key(READ_RECORD *info)
return 0;
}
+
static int
join_ft_read_first(JOIN_TAB *tab)
{
int error;
TABLE *table= tab->table;
-#if 0
+#if NOT_USED_YET
if (cp_buffer_from_ref(&tab->ref)) // as ft-key doesn't use store_key's
return -1; // see also FT_SELECT::init()
#endif
@@ -4633,7 +5272,8 @@ join_ft_read_first(JOIN_TAB *tab)
{
if (error != HA_ERR_END_OF_FILE)
{
- sql_print_error("ft_read_first: Got error %d when reading table %s",
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error("ft_read_first: Got error %d when reading table %s",
error, table->path);
table->file->print_error(error,MYF(0));
return 1;
@@ -4651,7 +5291,8 @@ join_ft_read_next(READ_RECORD *info)
{
if (error != HA_ERR_END_OF_FILE)
{
- sql_print_error("ft_read_next: Got error %d when reading table %s",
+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
+ sql_print_error("ft_read_next: Got error %d when reading table %s",
error, info->table->path);
info->file->print_error(error,MYF(0));
return 1;
@@ -4663,12 +5304,12 @@ join_ft_read_next(READ_RECORD *info)
/*****************************************************************************
-** The different end of select functions
-** These functions returns < 0 when end is reached, 0 on ok and > 0 if a
-** fatal error (like table corruption) was detected
+ The different end of select functions
+ These functions returns < 0 when end is reached, 0 on ok and > 0 if a
+ fatal error (like table corruption) was detected
*****************************************************************************/
- /* ARGSUSED */
+/* ARGSUSED */
static int
end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
bool end_of_records)
@@ -4679,14 +5320,49 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
int error;
if (join->having && join->having->val_int() == 0)
DBUG_RETURN(0); // Didn't match having
+ error=0;
if (join->procedure)
error=join->procedure->send_row(*join->fields);
- else
+ else if (join->do_send_rows)
error=join->result->send_data(*join->fields);
if (error)
DBUG_RETURN(-1); /* purecov: inspected */
- if (++join->send_records >= join->thd->select_limit)
+ if (++join->send_records >= join->thd->select_limit &&
+ join->do_send_rows)
+ {
+ if (join->select_options & OPTION_FOUND_ROWS)
+ {
+ JOIN_TAB *jt=join->join_tab;
+ if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
+ && !join->send_group_parts && !join->having && !jt->select_cond &&
+ !(jt->select && jt->select->quick) &&
+ !(jt->table->file->table_flags() & HA_NOT_EXACT_COUNT))
+ {
+ /* Join over all rows in table; Return number of found rows */
+ TABLE *table=jt->table;
+
+ join->select_options ^= OPTION_FOUND_ROWS;
+ if (table->record_pointers ||
+ (table->io_cache && my_b_inited(table->io_cache)))
+ {
+ /* Using filesort */
+ join->send_records= table->found_records;
+ }
+ else
+ {
+ table->file->info(HA_STATUS_VARIABLE);
+ join->send_records = table->file->records;
+ }
+ }
+ else
+ {
+ join->do_send_rows=0;
+ join->thd->select_limit = HA_POS_ERROR;
+ DBUG_RETURN(0);
+ }
+ }
DBUG_RETURN(-3); // Abort nicely
+ }
}
else
{
@@ -4714,12 +5390,12 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
join->procedure->end_group();
if (idx < (int) join->send_group_parts)
{
- int error;
+ int error=0;
if (join->procedure)
{
if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having
- else
+ else if (join->do_send_rows)
error=join->procedure->send_row(*join->fields) ? 1 : 0;
if (end_of_records && join->procedure->end_of_records())
error= 1; // Fatal error
@@ -4734,15 +5410,25 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having
- else
+ else if (join->do_send_rows)
error=join->result->send_data(*join->fields) ? 1 : 0;
}
if (error > 0)
DBUG_RETURN(-1); /* purecov: inspected */
if (end_of_records)
+ {
+ join->send_records++;
DBUG_RETURN(0);
- if (!error && ++join->send_records >= join->thd->select_limit)
- DBUG_RETURN(-3); /* Abort nicely */
+ }
+ if (!error &&
+ ++join->send_records >= join->thd->select_limit &&
+ join->do_send_rows)
+ {
+ if (!(join->select_options & OPTION_FOUND_ROWS))
+ DBUG_RETURN(-3); // Abort nicely
+ join->do_send_rows=0;
+ join->thd->select_limit = HA_POS_ERROR;
+ }
}
}
else
@@ -4786,8 +5472,9 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!end_of_records)
{
copy_fields(&join->tmp_table_param);
- copy_funcs(join->tmp_table_param.funcs);
+ copy_funcs(join->tmp_table_param.items_to_copy);
+#ifdef TO_BE_DELETED
if (!table->uniques) // If not unique handling
{
/* Copy null values from group to row */
@@ -4798,10 +5485,11 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (item->maybe_null)
{
Field *field=item->tmp_table_field();
- field->ptr[-1]= (byte) (field->is_null() ? 0 : 1);
+ field->ptr[-1]= (byte) (field->is_null() ? 1 : 0);
}
}
}
+#endif
if (!join->having || join->having->val_int())
{
join->found_records++;
@@ -4810,11 +5498,19 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (error == HA_ERR_FOUND_DUPP_KEY ||
error == HA_ERR_FOUND_DUPP_UNIQUE)
goto end;
- if (create_myisam_from_heap(table, &join->tmp_table_param, error,1))
- DBUG_RETURN(1); // Not a table_is_full error
+ if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
+ error,1))
+ DBUG_RETURN(-1); // Not a table_is_full error
table->uniques=0; // To ensure rows are the same
- if (++join->send_records >= join->tmp_table_param.end_write_records)
+ }
+ if (++join->send_records >= join->tmp_table_param.end_write_records &&
+ join->do_send_rows)
+ {
+ if (!(join->select_options & OPTION_FOUND_ROWS))
DBUG_RETURN(-3);
+ join->do_send_rows=0;
+ join->thd->select_limit = HA_POS_ERROR;
+ DBUG_RETURN(0);
}
}
}
@@ -4877,10 +5573,11 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
memcpy(table->record[0]+key_part->offset, group->buff, key_part->length);
init_tmptable_sum_functions(join->sum_funcs);
- copy_funcs(join->tmp_table_param.funcs);
+ copy_funcs(join->tmp_table_param.items_to_copy);
if ((error=table->file->write_row(table->record[0])))
{
- if (create_myisam_from_heap(table, &join->tmp_table_param, error, 0))
+ if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
+ error, 0))
DBUG_RETURN(-1); // Not a table_is_full error
/* Change method to update rows */
table->file->index_init(0);
@@ -4910,7 +5607,7 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
init_tmptable_sum_functions(join->sum_funcs);
copy_fields(&join->tmp_table_param); // Groups are copied twice.
- copy_funcs(join->tmp_table_param.funcs);
+ copy_funcs(join->tmp_table_param.items_to_copy);
if (!(error=table->file->write_row(table->record[0])))
join->send_records++; // New group
@@ -4974,9 +5671,9 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if ((error=table->file->write_row(table->record[0])))
{
- if (create_myisam_from_heap(table, &join->tmp_table_param,
- error, 0))
- DBUG_RETURN(1); // Not a table_is_full error
+ if (create_myisam_from_heap(join->thd, table,
+ &join->tmp_table_param, error, 0))
+ DBUG_RETURN(-1); // Not a table_is_full error
}
else
join->send_records++;
@@ -4995,7 +5692,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (idx < (int) join->send_group_parts)
{
copy_fields(&join->tmp_table_param);
- copy_funcs(join->tmp_table_param.funcs);
+ copy_funcs(join->tmp_table_param.items_to_copy);
init_sum_functions(join->sum_funcs);
if (join->procedure)
join->procedure->add();
@@ -5011,11 +5708,11 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
/*****************************************************************************
-** Remove calculation with tables that aren't yet read. Remove also tests
-** against fields that are read through key where the table is not a
-** outer join table.
-** We can't remove tests that are made against columns which are stored
-** in sorted order.
+ Remove calculation with tables that aren't yet read. Remove also tests
+ against fields that are read through key where the table is not a
+ outer join table.
+ We can't remove tests that are made against columns which are stored
+ in sorted order.
*****************************************************************************/
/* Return 1 if right_item is used removable reference key on left_item */
@@ -5031,11 +5728,12 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
{
if (right_item->type() == Item::FIELD_ITEM)
return (field->eq_def(((Item_field *) right_item)->field));
- if (right_item->const_item() &&
- (right_item->val_int() || !right_item->null_value))
+ if (right_item->const_item() && !(right_item->is_null()))
{
- // We can remove binary fields and numerical fields except float,
- // as float comparison isn't 100 % secure
+ /*
+ We can remove binary fields and numerical fields except float,
+ as float comparison isn't 100 % secure
+ */
if (field->binary() &&
(field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0))
{
@@ -5057,6 +5755,7 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table)
{
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
{
+ /* Create new top level AND item */
Item_cond_and *new_cond=new Item_cond_and;
if (!new_cond)
return (COND*) 0; // OOM /* purecov: inspected */
@@ -5094,14 +5793,15 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table)
new_cond->argument_list()->push_back(fix);
}
new_cond->used_tables_cache=((Item_cond_or*) cond)->used_tables_cache;
+ new_cond->top_level_item();
return new_cond;
}
}
/*
- ** Because the following test takes a while and it can be done
- ** table_count times, we mark each item that we have examined with the result
- ** of the test
+ Because the following test takes a while and it can be done
+ table_count times, we mark each item that we have examined with the result
+ of the test
*/
if (cond->marker == 3 || (cond->used_tables() & ~tables))
@@ -5141,7 +5841,7 @@ part_of_refkey(TABLE *table,Field *field)
for (uint part=0 ; part < ref_parts ; part++,key_part++)
if (field->eq(key_part->field) &&
- !(key_part->key_part_flag & HA_PART_KEY))
+ !(key_part->key_part_flag & HA_PART_KEY_SEG))
return table->reginfo.join_tab->ref.items[part];
}
return (Item*) 0;
@@ -5149,13 +5849,15 @@ part_of_refkey(TABLE *table,Field *field)
/*****************************************************************************
-** Test if one can use the key to resolve ORDER BY
-** Returns: 1 if key is ok.
-** 0 if key can't be used
-** -1 if reverse key can be used
+ Test if one can use the key to resolve ORDER BY
+ Returns: 1 if key is ok.
+ 0 if key can't be used
+ -1 if reverse key can be used
+ used_key_parts is set to key parts used if length != 0
*****************************************************************************/
-static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx)
+static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
+ uint *used_key_parts)
{
KEY_PART_INFO *key_part,*key_part_end;
key_part=table->key_info[idx].key_part;
@@ -5187,6 +5889,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx)
reverse=flag; // Remember if reverse
key_part++;
}
+ *used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
return reverse;
}
@@ -5209,17 +5912,20 @@ static uint find_shortest_key(TABLE *table, key_map usable_keys)
}
-/*****************************************************************************
-** If not selecting by given key, create a index how records should be read
-** return: 0 ok
-** -1 some fatal error
-** 1 no records
-*****************************************************************************/
+/*
+ Test if we can skip the ORDER BY by using an index.
-/* Return 1 if we don't have to do file sorting */
+ If we can use an index, the JOIN_TAB / tab->select struct
+ is changed to use the index.
+
+ Return:
+ 0 We have to use filesort to do the sorting
+ 1 We can use an index.
+*/
static bool
-test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
+test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
+ bool no_changes)
{
int ref_key;
TABLE *table=tab->table;
@@ -5247,10 +5953,57 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
if (ref_key >= 0)
{
+ /*
+ We come here when there is a REF key.
+ */
+ int order_direction;
+ uint used_key_parts;
/* Check if we get the rows in requested sorted order by using the key */
if ((usable_keys & ((key_map) 1 << ref_key)) &&
- test_if_order_by_key(order,table,ref_key) == 1)
+ (order_direction = test_if_order_by_key(order,table,ref_key,
+ &used_key_parts)))
+ {
+ if (order_direction == -1) // If ORDER BY ... DESC
+ {
+ if (select && select->quick)
+ {
+ /*
+ Don't reverse the sort order, if it's already done.
+ (In some cases test_if_order_by_key() can be called multiple times
+ */
+ if (!select->quick->reverse_sorted())
+ {
+ if (table->file->index_flags(ref_key) & HA_NOT_READ_PREFIX_LAST)
+ DBUG_RETURN(0); // Use filesort
+ // ORDER BY range_key DESC
+ QUICK_SELECT_DESC *tmp=new QUICK_SELECT_DESC(select->quick,
+ used_key_parts);
+ if (!tmp || tmp->error)
+ {
+ delete tmp;
+ DBUG_RETURN(0); // Reverse sort not supported
+ }
+ select->quick=tmp;
+ }
+ DBUG_RETURN(1);
+ }
+ if (tab->ref.key_parts < used_key_parts)
+ {
+ /*
+ SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
+
+ Use a traversal function that starts by reading the last row
+ with key part (A) and then traverse the index backwards.
+ */
+ if (table->file->index_flags(ref_key) & HA_NOT_READ_PREFIX_LAST)
+ DBUG_RETURN(0); // Use filesort
+ tab->read_first_record= join_read_last_key;
+ tab->read_record.read_record= join_read_prev_same;
+ /* fall through */
+ }
+ }
DBUG_RETURN(1); /* No need to sort */
+ }
}
else
{
@@ -5269,20 +6022,24 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
for (nr=0; keys ; keys>>=1, nr++)
{
+ uint not_used;
if (keys & 1)
{
int flag;
- if ((flag=test_if_order_by_key(order,table,nr)))
+ if ((flag=test_if_order_by_key(order, table, nr, &not_used)))
{
- tab->index=nr;
- tab->read_first_record= (flag > 0 ? join_init_read_first_with_key:
- join_init_read_last_with_key);
- table->file->index_init(nr);
- tab->type=JT_NEXT; // Read with index_first(), index_next()
- if (table->used_keys & ((key_map) 1 << nr))
+ if (!no_changes)
{
- table->key_read=1;
- table->file->extra(HA_EXTRA_KEYREAD);
+ tab->index=nr;
+ tab->read_first_record= (flag > 0 ? join_read_first:
+ join_read_last);
+ table->file->index_init(nr);
+ tab->type=JT_NEXT; // Read with index_first(), index_next()
+ if (table->used_keys & ((key_map) 1 << nr))
+ {
+ table->key_read=1;
+ table->file->extra(HA_EXTRA_KEYREAD);
+ }
}
DBUG_RETURN(1);
}
@@ -5292,8 +6049,17 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
DBUG_RETURN(0); // Can't use index.
}
+
+/*****************************************************************************
+ If not selecting by given key, create an index how records should be read
+ return: 0 ok
+ -1 some fatal error
+ 1 no records
+*****************************************************************************/
+
static int
-create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
+create_sort_index(JOIN_TAB *tab, ORDER *order, ha_rows filesort_limit,
+ ha_rows select_limit)
{
SORT_FIELD *sortorder;
uint length;
@@ -5302,7 +6068,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
SQL_SELECT *select=tab->select;
DBUG_ENTER("create_sort_index");
- if (test_if_skip_sort_order(tab,order,select_limit))
+ if (test_if_skip_sort_order(tab,order,select_limit,0))
DBUG_RETURN(0);
if (!(sortorder=make_unireg_sortorder(order,&length)))
goto err; /* purecov: inspected */
@@ -5330,25 +6096,19 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
/*
We have a ref on a const; Change this to a range that filesort
can use.
+ For impossible ranges (like when doing a lookup on NULL on a NOT NULL
+ field, quick will contain an empty record set.
*/
- if (!(select->quick=get_ft_or_quick_select_for_ref(table, tab)))
- {
- if (current_thd->fatal_error)
- goto err; // End of memory
- /*
- Impossible range (for example lookup on NULL on not null field)
- Create empty result set
- */
- if (!(table->record_pointers= (byte*) my_malloc(1, MYF(MY_WME))))
- goto err;
- table->found_records= 0;
- goto end;
- }
+ if (!(select->quick=get_ft_or_quick_select_for_ref(tab->join->thd,
+ table, tab)))
+ goto err;
}
}
- table->found_records=filesort(&table,sortorder,length,
- select, 0L, select_limit, &examined_rows);
-end:
+ if (table->tmp_table)
+ table->file->info(HA_STATUS_VARIABLE); // Get record count
+ table->found_records=filesort(table,sortorder,length,
+ select, 0L, filesort_limit, &examined_rows);
+ tab->records=table->found_records; // For SQL_CALC_ROWS
delete select; // filesort did select
tab->select=0;
tab->select_cond=0;
@@ -5365,11 +6125,11 @@ err:
DBUG_RETURN(-1);
}
-
/*
-** Add the HAVING criteria to table->select
+ Add the HAVING criteria to table->select
*/
+#ifdef NOT_YET
static bool fix_having(JOIN *join, Item **having)
{
(*having)->update_used_tables(); // Some tables may have been const
@@ -5390,6 +6150,7 @@ static bool fix_having(JOIN *join, Item **having)
sort_table_cond)))
return 1;
table->select_cond=table->select->cond;
+ table->select_cond->top_level_item();
DBUG_EXECUTE("where",print_where(table->select_cond,
"select and having"););
*having=make_cond_for_table(*having,~ (table_map) 0,~used_tables);
@@ -5397,14 +6158,15 @@ static bool fix_having(JOIN *join, Item **having)
}
return 0;
}
+#endif
/*****************************************************************************
-** Remove duplicates from tmp table
-** This should be recoded to add a uniuqe index to the table and remove
-** dupplicates
-** Table is a locked single thread table
-** fields is the number of fields to check (from the end)
+ Remove duplicates from tmp table
+ This should be recoded to add a unique index to the table and remove
+ duplicates
+ Table is a locked single thread table
+ fields is the number of fields to check (from the end)
*****************************************************************************/
static bool compare_record(TABLE *table, Field **ptr)
@@ -5444,10 +6206,10 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
int error;
ulong reclength,offset;
uint field_count;
+ THD *thd= join->thd;
DBUG_ENTER("remove_duplicates");
entry->reginfo.lock_type=TL_WRITE;
- entry->file->extra(HA_EXTRA_NO_READCHECK);
/* Calculate how many saved fields there is in list */
field_count=0;
@@ -5461,7 +6223,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
if (!field_count)
{ // only const items
- join->thd->select_limit=1; // Only send first row
+ join->thd->select_limit=1; // Only send first row
DBUG_RETURN(0);
}
Field **first_field=entry->field+entry->fields - field_count;
@@ -5473,7 +6235,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
if (entry->db_type == DB_TYPE_HEAP ||
(!entry->blob_fields &&
((ALIGN_SIZE(reclength) +sizeof(HASH_LINK)) * entry->file->records <
- sortbuff_size)))
+ thd->variables.sortbuff_size)))
error=remove_dup_with_hash_index(join->thd, entry,
field_count, first_field,
reclength, having);
@@ -5633,7 +6395,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
if ((error=file->delete_row(record)))
goto err;
continue;
- }
+ }
/* copy fields to key buffer */
field_length=field_lengths;
@@ -5794,7 +6556,7 @@ join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
cache->length=length+blobs*sizeof(char*);
cache->blobs=blobs;
*blob_ptr=0; /* End sequentel */
- size=max(join_buff_size,cache->length);
+ size=max(thd->variables.join_buff_size, cache->length);
if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
cache->end=cache->buff+size;
@@ -5835,7 +6597,7 @@ store_record_in_cache(JOIN_CACHE *cache)
cache->ptr_record=cache->records;
/*
- ** There is room in cache. Put record there
+ There is room in cache. Put record there
*/
cache->records++;
for (copy=cache->field ; copy < end_field; copy++)
@@ -5961,13 +6723,13 @@ cp_buffer_from_ref(TABLE_REF *ref)
/*****************************************************************************
-** Group and order functions
+ Group and order functions
*****************************************************************************/
/*
-** Find order/group item in requested columns and change the item to point at
-** it. If item doesn't exists, add it first in the field list
-** Return 0 if ok.
+ Find order/group item in requested columns and change the item to point at
+ it. If item doesn't exists, add it first in the field list
+ Return 0 if ok.
*/
static int
@@ -6012,8 +6774,8 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List<Item> &fields,
/*
-** Change order to point at item in select list. If item isn't a number
-** and doesn't exits in the select list, add it the the field list.
+ Change order to point at item in select list. If item isn't a number
+ and doesn't exits in the select list, add it the the field list.
*/
int setup_order(THD *thd,TABLE_LIST *tables,List<Item> &fields,
@@ -6047,7 +6809,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
uint org_fields=all_fields.elements;
thd->where="group statement";
- for ( ; order; order=order->next)
+ for (; order; order=order->next)
{
if (find_order_in_list(thd,tables,order,fields,all_fields))
return 1;
@@ -6067,7 +6829,8 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
while ((item=li++))
{
- if (item->type() != Item::SUM_FUNC_ITEM && !item->marker)
+ if (item->type() != Item::SUM_FUNC_ITEM && !item->marker &&
+ !item->const_item())
{
my_printf_error(ER_WRONG_FIELD_WITH_GROUP,
ER(ER_WRONG_FIELD_WITH_GROUP),
@@ -6082,7 +6845,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
}
/*
-** Add fields with aren't used at start of field list. Return FALSE if ok
+ Add fields with aren't used at start of field list. Return FALSE if ok
*/
static bool
@@ -6094,7 +6857,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
thd->set_query_id=1; // Not really needed, but...
thd->where=0; // Don't give error
- for ( ; new_field ; new_field=new_field->next)
+ for (; new_field ; new_field=new_field->next)
{
if ((item=find_item_in_list(*new_field->item,fields)))
new_field->item=item; /* Change to shared Item */
@@ -6112,18 +6875,20 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
}
/*
-** Create a group by that consist of all non const fields. Try to use
-** the fields in the order given by 'order' to allow one to optimize
-** away 'order by'.
+ Create a group by that consist of all non const fields. Try to use
+ the fields in the order given by 'order' to allow one to optimize
+ away 'order by'.
*/
static ORDER *
-create_distinct_group(ORDER *order_list,List<Item> &fields)
+create_distinct_group(THD *thd, ORDER *order_list, List<Item> &fields,
+ bool *all_order_by_fields_used)
{
List_iterator<Item> li(fields);
Item *item;
ORDER *order,*group,**prev;
+ *all_order_by_fields_used= 1;
while ((item=li++))
item->marker=0; /* Marker that field is not used */
@@ -6132,13 +6897,15 @@ create_distinct_group(ORDER *order_list,List<Item> &fields)
{
if (order->in_field_list)
{
- ORDER *ord=(ORDER*) sql_memdup(order,sizeof(ORDER));
+ ORDER *ord=(ORDER*) thd->memdup((char*) order,sizeof(ORDER));
if (!ord)
return 0;
*prev=ord;
prev= &ord->next;
(*ord->item)->marker=1;
}
+ else
+ *all_order_by_fields_used= 0;
}
li.rewind();
@@ -6148,7 +6915,7 @@ create_distinct_group(ORDER *order_list,List<Item> &fields)
continue;
if (!item->marker)
{
- ORDER *ord=(ORDER*) sql_calloc(sizeof(ORDER));
+ ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
if (!ord)
return 0;
ord->item=li.ref();
@@ -6163,7 +6930,7 @@ create_distinct_group(ORDER *order_list,List<Item> &fields)
/*****************************************************************************
-** Update join with count of the different type of fields
+ Update join with count of the different type of fields
*****************************************************************************/
void
@@ -6173,7 +6940,7 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
List_iterator<Item> li(fields);
Item *field;
- param->field_count=param->sum_func_count=param->func_count=
+ param->field_count=param->sum_func_count=param->func_count=
param->hidden_field_count=0;
param->quick_group=1;
while ((field=li++))
@@ -6254,7 +7021,7 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
if (!map || (map & RAND_TABLE_BIT))
DBUG_RETURN(0);
- for ( ; !(map & tables->table->map) ; tables=tables->next) ;
+ for (; !(map & tables->table->map) ; tables=tables->next) ;
if (map != tables->table->map)
DBUG_RETURN(0); // More than one table
DBUG_PRINT("exit",("sort by table: %d",tables->table->tablenr));
@@ -6267,7 +7034,8 @@ get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
static void
calc_group_buffer(JOIN *join,ORDER *group)
{
- uint key_length=0,parts=0;
+ uint key_length=0, parts=0, null_parts=0;
+
if (group)
join->group= 1;
for (; group ; group=group->next)
@@ -6288,16 +7056,17 @@ calc_group_buffer(JOIN *join,ORDER *group)
key_length+=(*group->item)->max_length;
parts++;
if ((*group->item)->maybe_null)
- key_length++;
+ null_parts++;
}
- join->tmp_table_param.group_length=key_length;
+ join->tmp_table_param.group_length=key_length+null_parts;
join->tmp_table_param.group_parts=parts;
+ join->tmp_table_param.group_null_parts=null_parts;
}
/*
-** Get a list of buffers for saveing last group
-** Groups are saved in reverse order for easyer check loop
+ Get a list of buffers for saveing last group
+ Groups are saved in reverse order for easyer check loop
*/
static bool
@@ -6335,14 +7104,14 @@ test_if_group_changed(List<Item_buff> &list)
/*
-** Setup copy_fields to save fields at start of new group
-** Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
-** Change old item_field to use a new field with points at saved fieldvalue
-** This function is only called before use of send_fields
+ Setup copy_fields to save fields at start of new group
+ Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
+ Change old item_field to use a new field with points at saved fieldvalue
+ This function is only called before use of send_fields
*/
bool
-setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields)
+setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields)
{
Item *pos;
List_iterator<Item> li(fields);
@@ -6350,7 +7119,7 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields)
DBUG_ENTER("setup_copy_fields");
if (!(copy=param->copy_field= new Copy_field[param->field_count]))
- goto err;
+ goto err2;
param->copy_funcs.empty();
while ((pos=li++))
@@ -6370,7 +7139,7 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields)
/* set up save buffer and change result_field to point at saved value */
Field *field= item->field;
- item->result_field=field->new_field(field->table);
+ item->result_field=field->new_field(&thd->mem_root,field->table);
char *tmp=(char*) sql_alloc(field->pack_length()+1);
if (!tmp)
goto err;
@@ -6395,40 +7164,40 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields)
goto err;
}
}
- param->copy_field_count= (uint) (copy - param->copy_field);
+ param->copy_field_end= copy;
DBUG_RETURN(0);
err:
- delete [] param->copy_field;
+ delete [] param->copy_field; // This is never 0
param->copy_field=0;
+err2:
DBUG_RETURN(TRUE);
}
/*
-** Copy fields and null values between two tables
+ Copy fields and null values between two tables
*/
void
copy_fields(TMP_TABLE_PARAM *param)
{
Copy_field *ptr=param->copy_field;
- Copy_field *end=ptr+param->copy_field_count;
+ Copy_field *end=param->copy_field_end;
- for ( ; ptr != end; ptr++)
+ for (; ptr != end; ptr++)
(*ptr->do_copy)(ptr);
- List_iterator<Item> it(param->copy_funcs);
+ List_iterator_fast<Item> &it=param->copy_funcs_it;
+ it.rewind();
Item_copy_string *item;
while ((item = (Item_copy_string*) it++))
- {
item->copy();
- }
}
/*****************************************************************************
-** Make an array of pointer to sum_functions to speed up sum_func calculation
+ Make an array of pointer to sum_functions to speed up sum_func calculation
*****************************************************************************/
static bool
@@ -6460,7 +7229,7 @@ make_sum_func_list(JOIN *join,List<Item> &fields)
/*
-** Change all funcs and sum_funcs to fields in tmp table
+ Change all funcs and sum_funcs to fields in tmp table
*/
static bool
@@ -6510,8 +7279,8 @@ change_to_use_tmp_fields(List<Item> &items)
/*
-** Change all sum_func refs to fields to point at fields in tmp table
-** Change all funcs to be fields in tmp table
+ Change all sum_func refs to fields to point at fields in tmp table
+ Change all funcs to be fields in tmp table
*/
static bool
@@ -6567,7 +7336,7 @@ change_refs_to_tmp_fields(THD *thd,List<Item> &items)
/******************************************************************************
-** code for calculating functions
+ Code for calculating functions
******************************************************************************/
static void
@@ -6587,7 +7356,7 @@ update_tmptable_sum_func(Item_sum **func_ptr,
{
Item_sum *func;
while ((func= *(func_ptr++)))
- func->update_field(0);
+ func->update_field();
}
@@ -6598,7 +7367,7 @@ copy_sum_funcs(Item_sum **func_ptr)
{
Item_sum *func;
for (; (func = *func_ptr) ; func_ptr++)
- (void) func->save_in_field(func->result_field);
+ (void) func->save_in_result_field(1);
return;
}
@@ -6625,18 +7394,17 @@ update_sum_func(Item_sum **func_ptr)
/* Copy result of functions to record in tmp_table */
void
-copy_funcs(Item_result_field **func_ptr)
+copy_funcs(Item **func_ptr)
{
- Item_result_field *func;
+ Item *func;
for (; (func = *func_ptr) ; func_ptr++)
- (void) func->save_in_field(func->result_field);
- return;
+ func->save_in_result_field(1);
}
/*****************************************************************************
-** Create a condition for a const reference and add this to the
-** currenct select for the table
+ Create a condition for a const reference and add this to the
+ currenct select for the table
*****************************************************************************/
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
@@ -6677,178 +7445,200 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
}
/****************************************************************************
-** Send a description about what how the select will be done to stdout
+ Send a description about what how the select will be done to stdout
****************************************************************************/
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
- bool distinct)
+ bool distinct,const char *message)
{
List<Item> field_list;
Item *item;
+ List<Item> item_list;
THD *thd=join->thd;
+ MYSQL_LOCK *save_lock;
+ SELECT_LEX *select_lex = &(join->thd->lex.select_lex);
+ select_result *result=join->result;
+ Item *item_null= new Item_null();
DBUG_ENTER("select_describe");
/* Don't log this into the slow query log */
- join->thd->lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
- field_list.push_back(new Item_empty_string("table",NAME_LEN));
- field_list.push_back(new Item_empty_string("type",10));
- field_list.push_back(item=new Item_empty_string("possible_keys",
+ select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
+ thd->offset_limit=0;
+ if (thd->lex.select == select_lex)
+ {
+ field_list.push_back(new Item_empty_string("table",NAME_LEN));
+ field_list.push_back(new Item_empty_string("type",10));
+ field_list.push_back(item=new Item_empty_string("possible_keys",
NAME_LEN*MAX_KEY));
- item->maybe_null=1;
- field_list.push_back(item=new Item_empty_string("key",NAME_LEN));
- item->maybe_null=1;
- field_list.push_back(item=new Item_int("key_len",0,3));
- item->maybe_null=1;
- field_list.push_back(item=new Item_empty_string("ref",
- NAME_LEN*MAX_REF_PARTS));
- item->maybe_null=1;
- field_list.push_back(new Item_real("rows",0.0,0,10));
- field_list.push_back(new Item_empty_string("Extra",255));
- if (send_fields(thd,field_list,1))
- return; /* purecov: inspected */
+ item->maybe_null=1;
+ field_list.push_back(item=new Item_empty_string("key",NAME_LEN));
+ item->maybe_null=1;
+ field_list.push_back(item=new Item_int("key_len",0,3));
+ item->maybe_null=1;
+ field_list.push_back(item=new Item_empty_string("ref",
+ NAME_LEN*MAX_REF_PARTS));
+ item->maybe_null=1;
+ field_list.push_back(new Item_real("rows",0.0,0,10));
+ field_list.push_back(new Item_empty_string("Extra",255));
+ if (result->send_fields(field_list,1))
+ return;
+ }
- char buff[512],*buff_ptr;
- String tmp(buff,sizeof(buff)),*packet= &thd->packet;
- table_map used_tables=0;
- for (uint i=0 ; i < join->tables ; i++)
+ if (message)
{
- JOIN_TAB *tab=join->join_tab+i;
- TABLE *table=tab->table;
-
- if (tab->type == JT_ALL && tab->select && tab->select->quick)
- tab->type= JT_RANGE;
- packet->length(0);
- net_store_data(packet,table->table_name);
- net_store_data(packet,join_type_str[tab->type]);
- tmp.length(0);
- key_map bits;
- uint j;
- for (j=0,bits=tab->keys ; bits ; j++,bits>>=1)
- {
- if (bits & 1)
- {
- if (tmp.length())
- tmp.append(',');
- tmp.append(table->key_info[j].name);
- }
- }
- if (tmp.length())
- net_store_data(packet,tmp.ptr(),tmp.length());
- else
- net_store_null(packet);
- if (tab->ref.key_parts)
- {
- net_store_data(packet,table->key_info[tab->ref.key].name);
- net_store_data(packet,(uint32) tab->ref.key_length);
- tmp.length(0);
- for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
- {
- if (tmp.length())
- tmp.append(',');
- tmp.append((*ref)->name());
- }
- net_store_data(packet,tmp.ptr(),tmp.length());
- }
- else if (tab->type == JT_NEXT)
- {
- net_store_data(packet,table->key_info[tab->index].name);
- net_store_data(packet,(uint32) table->key_info[tab->index].key_length);
- net_store_null(packet);
- }
- else if (tab->select && tab->select->quick)
- {
- net_store_data(packet,table->key_info[tab->select->quick->index].name);;
- net_store_data(packet,(uint32) tab->select->quick->max_used_key_length);
- net_store_null(packet);
- }
- else
- {
- net_store_null(packet);
- net_store_null(packet);
- net_store_null(packet);
- }
- sprintf(buff,"%.0f",join->best_positions[i].records_read);
- net_store_data(packet,buff);
- my_bool key_read=table->key_read;
- if (tab->type == JT_NEXT &&
- ((table->used_keys & ((key_map) 1 << tab->index))))
- key_read=1;
-
- buff_ptr=buff;
- if (tab->info)
- net_store_data(packet,tab->info);
- else if (tab->select)
+ Item *empty= new Item_empty_string("",0);
+ for (uint i=0 ; i < 7; i++)
+ item_list.push_back(empty);
+ item_list.push_back(new Item_string(message,strlen(message)));
+ if (result->send_data(item_list))
+ result->send_error(0,NullS);
+ }
+ else
+ {
+ table_map used_tables=0;
+ for (uint i=0 ; i < join->tables ; i++)
{
- if (tab->use_quick == 2)
+ JOIN_TAB *tab=join->join_tab+i;
+ TABLE *table=tab->table;
+ char buff[512],*buff_ptr=buff;
+ char buff1[512], buff2[512], buff3[512];
+ String tmp1(buff1,sizeof(buff1));
+ String tmp2(buff2,sizeof(buff2));
+ tmp1.length(0);
+ tmp2.length(0);
+ item_list.empty();
+
+ if (tab->type == JT_ALL && tab->select && tab->select->quick)
+ tab->type= JT_RANGE;
+ item_list.push_back(new Item_string(table->table_name,
+ strlen(table->table_name)));
+ item_list.push_back(new Item_string(join_type_str[tab->type],
+ strlen(join_type_str[tab->type])));
+ key_map bits;
+ uint j;
+ for (j=0,bits=tab->keys ; bits ; j++,bits>>=1)
{
- sprintf(buff_ptr,"range checked for each record (index map: %u)",
- tab->keys);
- buff_ptr=strend(buff_ptr);
+ if (bits & 1)
+ {
+ if (tmp1.length())
+ tmp1.append(',');
+ tmp1.append(table->key_info[j].name);
+ }
}
+ if (tmp1.length())
+ item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length()));
else
- buff_ptr=strmov(buff_ptr,"where used");
- }
- if (key_read)
- {
- if (buff != buff_ptr)
+ item_list.push_back(item_null);
+ if (tab->ref.key_parts)
{
- buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ KEY *key_info=table->key_info+ tab->ref.key;
+ item_list.push_back(new Item_string(key_info->name,
+ strlen(key_info->name)));
+ item_list.push_back(new Item_int((int32) tab->ref.key_length));
+ for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
+ {
+ if (tmp2.length())
+ tmp2.append(',');
+ tmp2.append((*ref)->name());
+ }
+ item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length()));
}
- buff_ptr=strmov(buff_ptr,"Using index");
- }
- if (table->reginfo.not_exists_optimize)
- {
- if (buff != buff_ptr)
+ else if (tab->type == JT_NEXT)
{
- buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ KEY *key_info=table->key_info+ tab->index;
+ item_list.push_back(new Item_string(key_info->name,
+ strlen(key_info->name)));
+ item_list.push_back(new Item_int((int32) key_info->key_length));
+ item_list.push_back(item_null);
}
- buff_ptr=strmov(buff_ptr,"Not exists");
- }
- if (need_tmp_table)
- {
- need_tmp_table=0;
- if (buff != buff_ptr)
+ else if (tab->select && tab->select->quick)
{
- buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ KEY *key_info=table->key_info+ tab->select->quick->index;
+ item_list.push_back(new Item_string(key_info->name,
+ strlen(key_info->name)));
+ item_list.push_back(new Item_int((int32) tab->select->quick->max_used_key_length));
+ item_list.push_back(item_null);
}
- buff_ptr=strmov(buff_ptr,"Using temporary");
- }
- if (need_order)
- {
- need_order=0;
- if (buff != buff_ptr)
+ else
{
- buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ item_list.push_back(item_null);
+ item_list.push_back(item_null);
+ item_list.push_back(item_null);
}
- buff_ptr=strmov(buff_ptr,"Using filesort");
- }
- if (distinct & test_all_bits(used_tables,thd->used_tables))
- {
- if (buff != buff_ptr)
+ sprintf(buff3,"%.0f",join->best_positions[i].records_read);
+ item_list.push_back(new Item_string(buff3,strlen(buff3)));
+ my_bool key_read=table->key_read;
+ if (tab->type == JT_NEXT &&
+ ((table->used_keys & ((key_map) 1 << tab->index))))
+ key_read=1;
+
+ if (tab->info)
+ item_list.push_back(new Item_string(tab->info,strlen(tab->info)));
+ else
{
- buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2;
+ if (tab->select)
+ {
+ if (tab->use_quick == 2)
+ {
+ sprintf(buff_ptr,"; Range checked for each record (index map: %u)",
+ tab->keys);
+ buff_ptr=strend(buff_ptr);
+ }
+ else
+ buff_ptr=strmov(buff_ptr,"; Using where");
+ }
+ if (key_read)
+ buff_ptr= strmov(buff_ptr,"; Using index");
+ if (table->reginfo.not_exists_optimize)
+ buff_ptr= strmov(buff_ptr,"; Not exists");
+ if (need_tmp_table)
+ {
+ need_tmp_table=0;
+ buff_ptr= strmov(buff_ptr,"; Using temporary");
+ }
+ if (need_order)
+ {
+ need_order=0;
+ buff_ptr= strmov(buff_ptr,"; Using filesort");
+ }
+ if (distinct && test_all_bits(used_tables,thd->used_tables))
+ buff_ptr= strmov(buff_ptr,"; Distinct");
+ if (buff_ptr == buff)
+ buff_ptr+= 2;
+ item_list.push_back(new Item_string(buff+2,(uint) (buff_ptr - buff)-2));
}
- buff_ptr=strmov(buff_ptr,"Distinct");
+ // For next iteration
+ used_tables|=table->map;
+ if (result->send_data(item_list))
+ result->send_error(0,NullS);
}
- net_store_data(packet,buff,(uint) (buff_ptr - buff));
- if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
- DBUG_VOID_RETURN; /* purecov: inspected */
-
- // For next iteration
- used_tables|=table->map;
}
- send_eof(&thd->net);
+ if (!thd->lex.select->next) // Not union
+ {
+ save_lock=thd->lock;
+ thd->lock=(MYSQL_LOCK *)0;
+ result->send_eof();
+ thd->lock=save_lock;
+ }
DBUG_VOID_RETURN;
}
-static void describe_info(THD *thd, const char *info)
+static void describe_info(JOIN *join, const char *info)
{
+ THD *thd= join->thd;
+
+ if (thd->lex.select_lex.next) /* If in UNION */
+ {
+ select_describe(join,FALSE,FALSE,FALSE,info);
+ return;
+ }
List<Item> field_list;
String *packet= &thd->packet;
/* Don't log this into the slow query log */
- thd->lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
+ thd->lex.select_lex.options&= ~(QUERY_NO_INDEX_USED |
+ QUERY_NO_GOOD_INDEX_USED);
field_list.push_back(new Item_empty_string("Comment",80));
if (send_fields(thd,field_list,1))
return; /* purecov: inspected */
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 1bf7d7863eb..5c987e74163 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -115,22 +115,26 @@ typedef struct st_position { /* Used in find_best */
/* Param to create temporary tables when doing SELECT:s */
-class TMP_TABLE_PARAM {
+class TMP_TABLE_PARAM :public Sql_alloc
+{
public:
List<Item> copy_funcs;
- Copy_field *copy_field;
+ List_iterator_fast<Item> copy_funcs_it;
+ Copy_field *copy_field, *copy_field_end;
byte *group_buff;
- Item_result_field **funcs;
+ Item **items_to_copy; /* Fields in tmp table */
MI_COLUMNDEF *recinfo,*start_recinfo;
KEY *keyinfo;
ha_rows end_write_records;
- uint copy_field_count,field_count,sum_func_count,func_count;
+ uint field_count,sum_func_count,func_count;
uint hidden_field_count;
- uint group_parts,group_length;
+ uint group_parts,group_length,group_null_parts;
uint quick_group;
bool using_indirect_summary_function;
- TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0)
+ TMP_TABLE_PARAM()
+ :copy_funcs_it(copy_funcs), copy_field(0), group_parts(0),
+ group_length(0), group_null_parts(0)
{}
~TMP_TABLE_PARAM()
{
@@ -154,7 +158,8 @@ class JOIN {
uint tables,const_tables;
uint send_group_parts;
bool sort_and_group,first_record,full_join,group, no_field_update;
- table_map const_table_map,outer_join;
+ bool do_send_rows;
+ table_map const_table_map,found_const_table_map,outer_join;
ha_rows send_records,found_records,examined_rows,row_limit;
POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
double best_read;
@@ -183,15 +188,15 @@ void TEST_join(JOIN *join);
bool store_val_in_field(Field *field,Item *val);
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
- bool allow_distinct_limit, uint select_options);
+ bool allow_distinct_limit, ulong select_options);
void free_tmp_table(THD *thd, TABLE *entry);
void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
bool reset_with_sum_func);
-bool setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields);
+bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,List<Item> &fields);
void copy_fields(TMP_TABLE_PARAM *param);
-void copy_funcs(Item_result_field **func_ptr);
-bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error,
- bool ignore_last_dupp_error);
+void copy_funcs(Item **func_ptr);
+bool create_myisam_from_heap(THD *Thd, TABLE *table, TMP_TABLE_PARAM *param,
+ int error, bool ignore_last_dupp_error);
/* functions from opt_sum.cc */
int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds);
@@ -207,7 +212,7 @@ class store_key :public Sql_alloc
char *null_ptr;
char err;
public:
- store_key(Field *field_arg, char *ptr, char *null, uint length)
+ store_key(THD *thd, Field *field_arg, char *ptr, char *null, uint length)
:null_ptr(null),err(0)
{
if (field_arg->type() == FIELD_TYPE_BLOB)
@@ -216,7 +221,7 @@ class store_key :public Sql_alloc
field_arg->table, field_arg->binary());
else
{
- to_field=field_arg->new_field(field_arg->table);
+ to_field=field_arg->new_field(&thd->mem_root,field_arg->table);
if (to_field)
to_field->move_field(ptr, (uchar*) null, 1);
}
@@ -232,9 +237,9 @@ class store_key_field: public store_key
Copy_field copy_field;
const char *field_name;
public:
- store_key_field(Field *to_field_arg, char *ptr, char *null_ptr_arg,
+ store_key_field(THD *thd, Field *to_field_arg, char *ptr, char *null_ptr_arg,
uint length, Field *from_field, const char *name_arg)
- :store_key(to_field_arg,ptr,
+ :store_key(thd, to_field_arg,ptr,
null_ptr_arg ? null_ptr_arg : from_field->maybe_null() ? &err
: NullS,length), field_name(name_arg)
{
@@ -243,12 +248,12 @@ class store_key_field: public store_key
copy_field.set(to_field,from_field,0);
}
}
- bool copy()
- {
- copy_field.do_copy(&copy_field);
- return err != 0;
- }
- const char *name() const { return field_name; }
+ bool copy()
+ {
+ copy_field.do_copy(&copy_field);
+ return err != 0;
+ }
+ const char *name() const { return field_name; }
};
@@ -257,16 +262,15 @@ class store_key_item :public store_key
protected:
Item *item;
public:
- store_key_item(Field *to_field_arg, char *ptr, char *null_ptr_arg,
+ store_key_item(THD *thd, Field *to_field_arg, char *ptr, char *null_ptr_arg,
uint length, Item *item_arg)
- :store_key(to_field_arg,ptr,
+ :store_key(thd, to_field_arg,ptr,
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
&err : NullS, length), item(item_arg)
{}
bool copy()
{
- item->save_in_field(to_field);
- return err != 0;
+ return item->save_in_field(to_field, 1) || err != 0;
}
const char *name() const { return "func"; }
};
@@ -276,10 +280,10 @@ class store_key_const_item :public store_key_item
{
bool inited;
public:
- store_key_const_item(Field *to_field_arg, char *ptr,
+ store_key_const_item(THD *thd, Field *to_field_arg, char *ptr,
char *null_ptr_arg, uint length,
Item *item_arg)
- :store_key_item(to_field_arg,ptr,
+ :store_key_item(thd, to_field_arg,ptr,
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
&err : NullS, length, item_arg), inited(0)
{
@@ -289,7 +293,8 @@ public:
if (!inited)
{
inited=1;
- item->save_in_field(to_field);
+ if (item->save_in_field(to_field, 1))
+ err= 1;
}
return err != 0;
}
@@ -297,3 +302,4 @@ public:
};
bool cp_buffer_from_ref(TABLE_REF *ref);
+bool error_if_full_join(JOIN *join);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index f2d6dd8e058..3d727a33173 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -20,14 +20,13 @@
#include "mysql_priv.h"
#include "sql_select.h" // For select_describe
#include "sql_acl.h"
+#include "repl_failsafe.h"
#include <my_dir.h>
#ifdef HAVE_BERKELEY_DB
#include "ha_berkeley.h" // For berkeley_show_logs
#endif
-/* extern "C" pthread_mutex_t THR_LOCK_keycache; */
-
static const char *grant_names[]={
"select","insert","update","delete","create","drop","reload","shutdown",
"process","file","grant","references","index","alter"};
@@ -45,6 +44,8 @@ store_create_info(THD *thd, TABLE *table, String *packet);
static void
append_identifier(THD *thd, String *packet, const char *name);
+extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
+
/****************************************************************************
** Send list of databases
** A database is a directory in the mysql_data_home directory
@@ -72,16 +73,16 @@ mysqld_show_dbs(THD *thd,const char *wild)
DBUG_RETURN(1);
if (mysql_find_files(thd,&files,NullS,mysql_data_home,wild,1))
DBUG_RETURN(1);
- List_iterator<char> it(files);
+ List_iterator_fast<char> it(files);
while ((file_name=it++))
{
- if (!opt_safe_show_db || thd->master_access ||
+ if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
thd->priv_user, file_name) ||
(grant_option && !check_grant_db(thd, file_name)))
- {
+ {
thd->packet.length(0);
- net_store_data(&thd->packet,file_name);
+ net_store_data(&thd->packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
thd->packet.length()))
DBUG_RETURN(-1);
@@ -95,34 +96,31 @@ mysqld_show_dbs(THD *thd,const char *wild)
** List all open tables in a database
***************************************************************************/
-int mysqld_show_open_tables(THD *thd,const char *db,const char *wild)
+int mysqld_show_open_tables(THD *thd,const char *wild)
{
- Item_string *field=new Item_string("",0);
List<Item> field_list;
- char *end,*table_name;
- List<char> tables;
+ OPEN_TABLE_LIST *open_list;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_open_tables");
- field->name=(char*) thd->alloc(20+(uint) strlen(db)+(wild ? (uint) strlen(wild)+4:0));
- end=strxmov(field->name,"Open_tables_in_",db,NullS);
- if (wild && wild[0])
- strxmov(end," (",wild,")",NullS);
- field->max_length=NAME_LEN;
- field_list.push_back(field);
- field_list.push_back(new Item_empty_string("Comment",80));
+ field_list.push_back(new Item_empty_string("Database",NAME_LEN));
+ field_list.push_back(new Item_empty_string("Table",NAME_LEN));
+ field_list.push_back(new Item_int("In_use",0, 4));
+ field_list.push_back(new Item_int("Name_locked",0, 4));
if (send_fields(thd,field_list,1))
DBUG_RETURN(1);
- if (list_open_tables(thd,&tables,db,wild))
+ if (!(open_list=list_open_tables(thd,wild)) && thd->fatal_error)
DBUG_RETURN(-1);
- List_iterator<char> it(tables);
- while ((table_name=it++))
+ for (; open_list ; open_list=open_list->next)
{
thd->packet.length(0);
- net_store_data(&thd->packet,table_name);
- net_store_data(&thd->packet,query_table_status(thd,db,table_name));
+ net_store_data(&thd->packet,convert, open_list->db);
+ net_store_data(&thd->packet,convert, open_list->table);
+ net_store_data(&thd->packet,open_list->in_use);
+ net_store_data(&thd->packet,open_list->locked);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
{
DBUG_RETURN(-1);
@@ -159,11 +157,11 @@ int mysqld_show_tables(THD *thd,const char *db,const char *wild)
DBUG_RETURN(1);
if (mysql_find_files(thd,&files,db,path,wild,0))
DBUG_RETURN(-1);
- List_iterator<char> it(files);
+ List_iterator_fast<char> it(files);
while ((file_name=it++))
{
thd->packet.length(0);
- net_store_data(&thd->packet,file_name);
+ net_store_data(&thd->packet, thd->variables.convert_set, file_name);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1);
}
@@ -199,11 +197,23 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
#ifdef USE_SYMDIR
char *ext;
if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
+ {
+ /* Only show the sym file if it points to a directory */
+ char buff[FN_REFLEN], *end;
+ MY_STAT status;
*ext=0; /* Remove extension */
+ unpack_dirname(buff, file->name);
+ end= strend(buff);
+ if (end != buff && end[-1] == FN_LIBCHAR)
+ end[-1]= 0; // Remove end FN_LIBCHAR
+ if (!my_stat(buff, &status, MYF(0)) ||
+ !MY_S_ISDIR(status.st_mode))
+ continue;
+ }
else
#endif
{
- if (file->name[0] == '.' || !MY_S_ISDIR(file->mystat.st_mode) ||
+ if (file->name[0] == '.' || !MY_S_ISDIR(file->mystat->st_mode) ||
(wild && wild_compare(file->name,wild)))
continue;
}
@@ -259,6 +269,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
char *file_name;
TABLE *table;
String *packet= &thd->packet;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_extend_show_tables");
(void) sprintf(path,"%s/%s",mysql_data_home,db);
@@ -299,13 +310,13 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
if (mysql_find_files(thd,&files,db,path,wild,0))
DBUG_RETURN(-1);
- List_iterator<char> it(files);
+ List_iterator_fast<char> it(files);
while ((file_name=it++))
{
TABLE_LIST table_list;
bzero((char*) &table_list,sizeof(table_list));
packet->length(0);
- net_store_data(packet,file_name);
+ net_store_data(packet,convert, file_name);
table_list.db=(char*) db;
table_list.real_name= table_list.alias= file_name;
if (lower_case_table_names)
@@ -314,7 +325,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
{
for (uint i=2 ; i < field_list.elements ; i++)
net_store_null(packet);
- net_store_data(packet,thd->net.last_error);
+ net_store_data(packet,convert, thd->net.last_error);
thd->net.last_error[0]=0;
}
else
@@ -322,13 +333,12 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
struct tm tm_tmp;
handler *file=table->file;
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_NO_LOCK);
- net_store_data(packet, file->table_type());
- net_store_data(packet,
- (table->db_options_in_use & HA_OPTION_COMPRESS_RECORD)
- ? "Compressed" :
+ net_store_data(packet, convert, file->table_type());
+ net_store_data(packet, convert,
+ (table->db_options_in_use & HA_OPTION_COMPRESS_RECORD) ?
+ "Compressed" :
(table->db_options_in_use & HA_OPTION_PACK_RECORD) ?
"Dynamic" : "Fixed");
-
net_store_data(packet, (longlong) file->records);
net_store_data(packet, (uint32) file->mean_rec_length);
net_store_data(packet, (longlong) file->data_file_length);
@@ -405,7 +415,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
my_raid_type(file->raid_type), file->raid_chunks, file->raid_chunksize/RAID_BLOCK_SIZE);
ptr=strmov(ptr,buff);
}
- net_store_data(packet, option_buff+1,
+ net_store_data(packet, convert, option_buff+1,
(ptr == option_buff ? 0 : (uint) (ptr-option_buff)-1));
}
{
@@ -438,6 +448,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
handler *file;
char tmp[MAX_FIELD_WIDTH];
Item *item;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_fields");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->real_name));
@@ -480,11 +491,6 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
{
if (!wild || !wild[0] || !wild_case_compare(field->field_name,wild))
{
-#ifdef NOT_USED
- if (thd->col_access & TABLE_ACLS ||
- ! check_grant_column(thd,table,field->field_name,
- (uint) strlen(field->field_name),1))
-#endif
{
byte *pos;
uint flags=field->flags;
@@ -493,37 +499,47 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
bool null_default_value=0;
packet->length(0);
- net_store_data(packet,field->field_name);
+ net_store_data(packet,convert,field->field_name);
field->sql_type(type);
- net_store_data(packet,type.ptr(),type.length());
-
+ net_store_data(packet,convert,type.ptr(),type.length());
+
+ /*
+ Altough TIMESTAMP fields can't contain NULL as its value they
+ will accept NULL if you will try to insert such value and will
+ convert it to current TIMESTAMP. So YES here means that NULL
+ is allowed for assignment but can't be returned.
+ */
pos=(byte*) ((flags & NOT_NULL_FLAG) &&
field->type() != FIELD_TYPE_TIMESTAMP ?
"" : "YES");
- net_store_data(packet,(const char*) pos);
+ net_store_data(packet,convert,(const char*) pos);
pos=(byte*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
- net_store_data(packet,(char*) pos);
+ net_store_data(packet,convert,(char*) pos);
- if (field->type() == FIELD_TYPE_TIMESTAMP ||
+ /*
+ We handle first TIMESTAMP column in special way because its
+ default value is ignored and current timestamp used instead.
+ */
+ if (table->timestamp_field == field ||
field->unireg_check == Field::NEXT_NUMBER)
null_default_value=1;
if (!null_default_value && !field->is_null())
{ // Not null by default
type.set(tmp,sizeof(tmp));
field->val_str(&type,&type);
- net_store_data(packet,type.ptr(),type.length());
+ net_store_data(packet,convert,type.ptr(),type.length());
}
else if (field->maybe_null() || null_default_value)
net_store_null(packet); // Null as default
else
- net_store_data(packet,tmp,0);
+ net_store_data(packet,convert,tmp,0);
char *end=tmp;
if (field->unireg_check == Field::NEXT_NUMBER)
end=strmov(tmp,"auto_increment");
- net_store_data(packet,tmp,(uint) (end-tmp));
+ net_store_data(packet,convert,tmp,(uint) (end-tmp));
if (verbose)
{
@@ -538,7 +554,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
end=strmov(end,grant_types.type_names[bitnr]);
}
}
- net_store_data(packet,tmp+1,end == tmp ? 0 : (uint) (end-tmp-1));
+ net_store_data(packet,convert, tmp+1,end == tmp ? 0 : (uint) (end-tmp-1));
}
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
DBUG_RETURN(1);
@@ -553,6 +569,7 @@ int
mysqld_show_create(THD *thd, TABLE_LIST *table_list)
{
TABLE *table;
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_create");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->real_name));
@@ -567,7 +584,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
char buff[1024];
String packet(buff,sizeof(buff));
packet.length(0);
- net_store_data(&packet, table->table_name);
+ net_store_data(&packet,convert, table->table_name);
/*
A hack - we need to reserve some space for the length before
we know what it is - let's assume that the length of create table
@@ -640,6 +657,7 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
{
TABLE *table;
char buff[256];
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_show_keys");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->real_name));
@@ -659,12 +677,14 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
field_list.push_back(new Item_empty_string("Column_name",NAME_LEN));
field_list.push_back(item=new Item_empty_string("Collation",1));
item->maybe_null=1;
- field_list.push_back(item=new Item_int("Cardinality",0,11));
+ field_list.push_back(item=new Item_int("Cardinality",0,21));
item->maybe_null=1;
field_list.push_back(item=new Item_int("Sub_part",0,3));
item->maybe_null=1;
field_list.push_back(item=new Item_empty_string("Packed",10));
item->maybe_null=1;
+ field_list.push_back(new Item_empty_string("Null",3));
+ field_list.push_back(new Item_empty_string("Index_type",16));
field_list.push_back(new Item_empty_string("Comment",255));
item->maybe_null=1;
@@ -681,38 +701,51 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list)
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
{
packet->length(0);
- net_store_data(packet,table->table_name);
- net_store_data(packet,((key_info->flags & HA_NOSAME) ? "0" :"1"), 1);
- net_store_data(packet,key_info->name);
+ net_store_data(packet,convert,table->table_name);
+ net_store_data(packet,convert,((key_info->flags & HA_NOSAME) ? "0" :"1"), 1);
+ net_store_data(packet,convert,key_info->name);
end=int10_to_str((long) (j+1),(char*) buff,10);
- net_store_data(packet,buff,(uint) (end-buff));
- net_store_data(packet,key_part->field ? key_part->field->field_name :
+ net_store_data(packet,convert,buff,(uint) (end-buff));
+ net_store_data(packet,convert,
+ key_part->field ? key_part->field->field_name :
"?unknown field?");
- if (table->file->option_flag() & HA_READ_ORDER)
- net_store_data(packet,((key_part->key_part_flag & HA_REVERSE_SORT)
- ? "D" : "A"), 1);
+ if (table->file->index_flags(i) & HA_READ_ORDER)
+ net_store_data(packet,convert,
+ ((key_part->key_part_flag & HA_REVERSE_SORT) ?
+ "D" : "A"), 1);
else
net_store_null(packet); /* purecov: inspected */
KEY *key=table->key_info+i;
if (key->rec_per_key[j])
{
- ulong records=(table->file->records / key->rec_per_key[j]);
- end=int10_to_str((long) records, buff, 10);
- net_store_data(packet,buff,(uint) (end-buff));
+ ha_rows records=(table->file->records / key->rec_per_key[j]);
+ end=longlong10_to_str((longlong) records, buff, 10);
+ net_store_data(packet,convert,buff,(uint) (end-buff));
}
else
net_store_null(packet);
- if (!key_part->field ||
- key_part->length !=
- table->field[key_part->fieldnr-1]->key_length())
+
+ /* Check if we have a key part that only uses part of the field */
+ if (!(key_info->flags & HA_FULLTEXT) && (!key_part->field ||
+ key_part->length != table->field[key_part->fieldnr-1]->key_length()))
{
end=int10_to_str((long) key_part->length, buff,10); /* purecov: inspected */
- net_store_data(packet,buff,(uint) (end-buff)); /* purecov: inspected */
+ net_store_data(packet,convert,buff,(uint) (end-buff)); /* purecov: inspected */
}
else
net_store_null(packet);
net_store_null(packet); // No pack_information yet
- net_store_data(packet,key_info->flags & HA_FULLTEXT ? "FULLTEXT":"");
+
+ /* Null flag */
+ uint flags= key_part->field ? key_part->field->flags : 0;
+ char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
+ net_store_data(packet,convert,(const char*) pos);
+ net_store_data(packet,convert,table->file->index_type(i));
+ /* Comment */
+ if (!(table->keys_in_use & ((key_map) 1 << i)))
+ net_store_data(packet,convert,"disabled",8);
+ else
+ net_store_data(packet,convert,"");
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
DBUG_RETURN(1); /* purecov: inspected */
}
@@ -757,27 +790,29 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
int
mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
{
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_dump_create_info");
DBUG_PRINT("enter",("table: %s",table->real_name));
+
String* packet = &thd->packet;
packet->length(0);
-
- if(store_create_info(thd,table,packet))
+ if (store_create_info(thd,table,packet))
DBUG_RETURN(-1);
- if(fd < 0)
+ if (convert)
+ convert->convert((char*) packet->ptr(), packet->length());
+ if (fd < 0)
{
- if(my_net_write(&thd->net, (char*)packet->ptr(), packet->length()))
+ if (my_net_write(&thd->net, (char*)packet->ptr(), packet->length()))
DBUG_RETURN(-1);
VOID(net_flush(&thd->net));
}
else
{
- if(my_write(fd, (const byte*) packet->ptr(), packet->length(),
- MYF(MY_WME)))
+ if (my_write(fd, (const byte*) packet->ptr(), packet->length(),
+ MYF(MY_WME)))
DBUG_RETURN(-1);
}
-
DBUG_RETURN(0);
}
@@ -796,31 +831,56 @@ append_identifier(THD *thd, String *packet, const char *name)
}
}
+
+/* Append directory name (if exists) to CREATE INFO */
+
+static void append_directory(THD *thd, String *packet, const char *dir_type,
+ const char *filename)
+{
+ uint length;
+ if (filename && !(thd->sql_mode & MODE_NO_DIR_IN_CREATE))
+ {
+ length= dirname_length(filename);
+ packet->append(' ');
+ packet->append(dir_type);
+ packet->append(" DIRECTORY='", 12);
+ packet->append(filename, length);
+ packet->append('\'');
+ }
+}
+
+
static int
store_create_info(THD *thd, TABLE *table, String *packet)
{
+ List<Item> field_list;
+ char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], *end;
+ String type(tmp, sizeof(tmp));
+ Field **ptr,*field;
+ uint primary_key;
+ KEY *key_info;
+ handler *file= table->file;
+ HA_CREATE_INFO create_info;
DBUG_ENTER("store_create_info");
DBUG_PRINT("enter",("table: %s",table->real_name));
restore_record(table,2); // Get empty record
-
- List<Item> field_list;
- char tmp[MAX_FIELD_WIDTH];
- String type(tmp, sizeof(tmp));
if (table->tmp_table)
packet->append("CREATE TEMPORARY TABLE ", 23);
else
packet->append("CREATE TABLE ", 13);
- append_identifier(thd,packet,table->real_name);
+ append_identifier(thd,packet,
+ (lower_case_table_names == 2 ? table->table_name :
+ table->real_name));
packet->append(" (\n", 3);
- Field **ptr,*field;
for (ptr=table->field ; (field= *ptr); ptr++)
{
+ bool has_default;
+ uint flags = field->flags;
+
if (ptr != table->field)
packet->append(",\n", 2);
-
- uint flags = field->flags;
packet->append(" ", 2);
append_identifier(thd,packet,field->field_name);
packet->append(' ');
@@ -831,9 +891,9 @@ store_create_info(THD *thd, TABLE *table, String *packet)
field->sql_type(type);
packet->append(type.ptr(),type.length());
- bool has_default = (field->type() != FIELD_TYPE_BLOB &&
- field->type() != FIELD_TYPE_TIMESTAMP &&
- field->unireg_check != Field::NEXT_NUMBER);
+ has_default= (field->type() != FIELD_TYPE_BLOB &&
+ table->timestamp_field != field &&
+ field->unireg_check != Field::NEXT_NUMBER);
if (flags & NOT_NULL_FLAG)
packet->append(" NOT NULL", 9);
@@ -859,9 +919,11 @@ store_create_info(THD *thd, TABLE *table, String *packet)
packet->append(" auto_increment", 15 );
}
- KEY *key_info=table->key_info;
- table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
- uint primary_key = table->primary_key;
+ key_info= table->key_info;
+ file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
+ bzero((char*) &create_info, sizeof(create_info));
+ file->update_create_info(&create_info);
+ primary_key= table->primary_key;
for (uint i=0 ; i < table->keys ; i++,key_info++)
{
@@ -897,7 +959,6 @@ store_create_info(THD *thd, TABLE *table, String *packet)
table->field[key_part->fieldnr-1]->key_length() &&
!(key_info->flags & HA_FULLTEXT)))
{
- char buff[64];
buff[0] = '(';
char* end=int10_to_str((long) key_part->length, buff + 1,10);
*end++ = ')';
@@ -907,43 +968,38 @@ store_create_info(THD *thd, TABLE *table, String *packet)
packet->append(')');
}
- handler *file = table->file;
-
- /* Get possible foreign key definitions stored in InnoDB and append them
- to the CREATE TABLE statement */
-
- char* for_str = file->get_foreign_key_create_info();
-
- if (for_str) {
- packet->append(for_str, strlen(for_str));
+ /*
+ Get possible foreign key definitions stored in InnoDB and append them
+ to the CREATE TABLE statement
+ */
- file->free_foreign_key_create_info(for_str);
+ if ((for_str= file->get_foreign_key_create_info()))
+ {
+ packet->append(for_str, strlen(for_str));
+ file->free_foreign_key_create_info(for_str);
}
packet->append("\n)", 2);
packet->append(" TYPE=", 6);
packet->append(file->table_type());
- char buff[128];
- char* p;
if (table->min_rows)
{
packet->append(" MIN_ROWS=");
- p = longlong10_to_str(table->min_rows, buff, 10);
- packet->append(buff, (uint) (p - buff));
+ end= longlong10_to_str(table->min_rows, buff, 10);
+ packet->append(buff, (uint) (end- buff));
}
-
if (table->max_rows)
{
packet->append(" MAX_ROWS=");
- p = longlong10_to_str(table->max_rows, buff, 10);
- packet->append(buff, (uint) (p - buff));
+ end= longlong10_to_str(table->max_rows, buff, 10);
+ packet->append(buff, (uint) (end - buff));
}
if (table->avg_row_length)
{
packet->append(" AVG_ROW_LENGTH=");
- p=longlong10_to_str(table->avg_row_length, buff,10);
- packet->append(buff, (uint) (p - buff));
+ end= longlong10_to_str(table->avg_row_length, buff,10);
+ packet->append(buff, (uint) (end - buff));
}
if (table->db_create_options & HA_OPTION_PACK_KEYS)
@@ -968,11 +1024,15 @@ store_create_info(THD *thd, TABLE *table, String *packet)
}
if (file->raid_type)
{
- char buff[100];
- sprintf(buff," RAID_TYPE=%s RAID_CHUNKS=%d RAID_CHUNKSIZE=%ld",
- my_raid_type(file->raid_type), file->raid_chunks, file->raid_chunksize/RAID_BLOCK_SIZE);
- packet->append(buff);
+ uint length;
+ length= my_snprintf(buff,sizeof(buff),
+ " RAID_TYPE=%s RAID_CHUNKS=%d RAID_CHUNKSIZE=%ld",
+ my_raid_type(file->raid_type), file->raid_chunks,
+ file->raid_chunksize/RAID_BLOCK_SIZE);
+ packet->append(buff, length);
}
+ append_directory(thd, packet, "DATA", create_info.data_file_name);
+ append_directory(thd, packet, "INDEX", create_info.index_file_name);
DBUG_RETURN(0);
}
@@ -999,18 +1059,21 @@ public:
template class I_List<thread_info>;
#endif
+#define LIST_PROCESS_HOST_LEN 64
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
{
Item *field;
List<Item> field_list;
I_List<thread_info> thread_infos;
- ulong max_query_length= verbose ? max_allowed_packet : PROCESS_LIST_WIDTH;
+ ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
+ PROCESS_LIST_WIDTH);
+ CONVERT *convert=thd->variables.convert_set;
DBUG_ENTER("mysqld_list_processes");
field_list.push_back(new Item_int("Id",0,7));
field_list.push_back(new Item_empty_string("User",16));
- field_list.push_back(new Item_empty_string("Host",64));
+ field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
field_list.push_back(field=new Item_empty_string("db",NAME_LEN));
field->maybe_null=1;
field_list.push_back(new Item_empty_string("Command",16));
@@ -1036,11 +1099,17 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thread_info *thd_info=new thread_info;
thd_info->thread_id=tmp->thread_id;
- thd_info->user=thd->strdup(tmp->user ? tmp->user : (tmp->system_thread ?
- "system user" : "unauthenticated user"));
- thd_info->host=thd->strdup(tmp->host ? tmp->host : (tmp->ip ? tmp->ip :
- (tmp->system_thread ? "none" :
- "connecting host")));
+ thd_info->user=thd->strdup(tmp->user ? tmp->user :
+ (tmp->system_thread ?
+ "system user" : "unauthenticated user"));
+ if (tmp->peer_port && (tmp->host || tmp->ip) && thd->host_or_ip[0])
+ {
+ if ((thd_info->host= thd->alloc(LIST_PROCESS_HOST_LEN+1)))
+ my_snprintf((char *) thd_info->host, LIST_PROCESS_HOST_LEN,
+ "%s:%u", tmp->host_or_ip, tmp->peer_port);
+ }
+ else
+ thd_info->host= thd->strdup(tmp->host_or_ip);
if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command;
@@ -1072,9 +1141,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thd_info->query=0;
if (tmp->query)
{
- uint length=(uint) strlen(tmp->query);
- if (length > max_query_length)
- length=max_query_length;
+ /* query_length is always set before tmp->query */
+ uint length= min(max_query_length, tmp->query_length);
thd_info->query=(char*) thd->memdup(tmp->query,length+1);
thd_info->query[length]=0;
}
@@ -1091,28 +1159,28 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
char buff[20],*end;
packet->length(0);
end=int10_to_str((long) thd_info->thread_id, buff,10);
- net_store_data(packet,buff,(uint) (end-buff));
- net_store_data(packet,thd_info->user);
- net_store_data(packet,thd_info->host);
+ net_store_data(packet,convert,buff,(uint) (end-buff));
+ net_store_data(packet,convert,thd_info->user);
+ net_store_data(packet,convert,thd_info->host);
if (thd_info->db)
- net_store_data(packet,thd_info->db);
+ net_store_data(packet,convert,thd_info->db);
else
net_store_null(packet);
if (thd_info->proc_info)
- net_store_data(packet,thd_info->proc_info);
+ net_store_data(packet,convert,thd_info->proc_info);
else
- net_store_data(packet,command_name[thd_info->command]);
+ net_store_data(packet,convert,command_name[thd_info->command]);
if (thd_info->start_time)
- net_store_data(packet,(uint32)
- (time((time_t*) 0) - thd_info->start_time));
+ net_store_data(packet,
+ (uint32) (time((time_t*) 0) - thd_info->start_time));
else
net_store_null(packet);
if (thd_info->state_info)
- net_store_data(packet,thd_info->state_info);
+ net_store_data(packet,convert,thd_info->state_info);
else
net_store_null(packet);
if (thd_info->query)
- net_store_data(packet,thd_info->query);
+ net_store_data(packet,convert,thd_info->query);
else
net_store_null(packet);
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
@@ -1128,56 +1196,67 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
*****************************************************************************/
-int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
+int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
+ enum enum_var_type value_type,
+ pthread_mutex_t *mutex)
{
- uint i;
char buff[8192];
String packet2(buff,sizeof(buff));
List<Item> field_list;
+ CONVERT *convert=thd->variables.convert_set;
+
DBUG_ENTER("mysqld_show");
field_list.push_back(new Item_empty_string("Variable_name",30));
field_list.push_back(new Item_empty_string("Value",256));
if (send_fields(thd,field_list,1))
DBUG_RETURN(1); /* purecov: inspected */
- /* pthread_mutex_lock(&THR_LOCK_keycache); */
- pthread_mutex_lock(&LOCK_status);
- for (i=0; variables[i].name; i++)
+ pthread_mutex_lock(mutex);
+ for (; variables->name; variables++)
{
- if (!(wild && wild[0] && wild_case_compare(variables[i].name,wild)))
+ if (!(wild && wild[0] && wild_case_compare(variables->name,wild)))
{
packet2.length(0);
- net_store_data(&packet2,variables[i].name);
- switch (variables[i].type){
+ net_store_data(&packet2,convert,variables->name);
+ SHOW_TYPE show_type=variables->type;
+ char *value=variables->value;
+ if (show_type == SHOW_SYS)
+ {
+ show_type= ((sys_var*) value)->type();
+ value= (char*) ((sys_var*) value)->value_ptr(thd, value_type);
+ }
+
+ switch (show_type) {
case SHOW_LONG:
case SHOW_LONG_CONST:
- net_store_data(&packet2,(uint32) *(ulong*) variables[i].value);
+ net_store_data(&packet2,(uint32) *(ulong*) value);
break;
- case SHOW_LONG_AS_LONGLONG:
- net_store_data(&packet2,(longlong) *(ulong*) variables[i].value);
+ case SHOW_LONGLONG:
+ net_store_data(&packet2,(longlong) *(longlong*) value);
+ break;
+ case SHOW_HA_ROWS:
+ net_store_data(&packet2,(longlong) *(ha_rows*) value);
break;
case SHOW_BOOL:
- net_store_data(&packet2,(ulong) *(bool*) variables[i].value ?
- "ON" : "OFF");
+ net_store_data(&packet2,(ulong) *(bool*) value ? "ON" : "OFF");
break;
case SHOW_MY_BOOL:
- net_store_data(&packet2,(ulong) *(my_bool*) variables[i].value ?
- "ON" : "OFF");
+ net_store_data(&packet2,(ulong) *(my_bool*) value ? "ON" : "OFF");
break;
case SHOW_INT_CONST:
case SHOW_INT:
- net_store_data(&packet2,(uint32) *(int*) variables[i].value);
+ net_store_data(&packet2,(uint32) *(int*) value);
break;
case SHOW_HAVE:
{
- SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) variables[i].value;
+ SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
net_store_data(&packet2, (tmp == SHOW_OPTION_NO ? "NO" :
tmp == SHOW_OPTION_YES ? "YES" :
"DISABLED"));
break;
}
case SHOW_CHAR:
- net_store_data(&packet2,variables[i].value);
+ net_store_data(&packet2,convert, value);
break;
case SHOW_STARTTIME:
net_store_data(&packet2,(uint32) (thd->query_start() - start_time));
@@ -1185,32 +1264,205 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
case SHOW_QUESTION:
net_store_data(&packet2,(uint32) thd->query_id);
break;
+ case SHOW_RPL_STATUS:
+ net_store_data(&packet2, rpl_status_type[(int)rpl_status]);
+ break;
+#ifdef HAVE_REPLICATION
+ case SHOW_SLAVE_RUNNING:
+ {
+ LOCK_ACTIVE_MI;
+ net_store_data(&packet2, (active_mi->slave_running &&
+ active_mi->rli.slave_running)
+ ? "ON" : "OFF");
+ UNLOCK_ACTIVE_MI;
+ break;
+ }
+#endif
case SHOW_OPENTABLES:
net_store_data(&packet2,(uint32) cached_tables());
break;
case SHOW_CHAR_PTR:
- {
- char *value= *(char**) variables[i].value;
- net_store_data(&packet2,value ? value : "");
- break;
+ {
+ value= *(char**) value;
+ net_store_data(&packet2,convert, value ? value : "");
+ break;
+ }
+#ifdef HAVE_OPENSSL
+ /* First group - functions relying on CTX */
+ case SHOW_SSL_CTX_SESS_ACCEPT:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_ACCEPT_GOOD:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_CONNECT_GOOD:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_CB_HITS:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_HITS:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_CACHE_FULL:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_MISSES:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_TIMEOUTS:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_NUMBER:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_CONNECT:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_GET_VERIFY_MODE:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_GET_VERIFY_DEPTH:
+ net_store_data(&packet2,(uint32)
+ (!ssl_acceptor_fd ? 0 :
+ SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context)));
+ break;
+ case SHOW_SSL_CTX_GET_SESSION_CACHE_MODE:
+ if (!ssl_acceptor_fd)
+ {
+ net_store_data(&packet2,"NONE" );
+ break;
+ }
+ switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
+ {
+ case SSL_SESS_CACHE_OFF:
+ net_store_data(&packet2,"OFF" );
+ break;
+ case SSL_SESS_CACHE_CLIENT:
+ net_store_data(&packet2,"CLIENT" );
+ break;
+ case SSL_SESS_CACHE_SERVER:
+ net_store_data(&packet2,"SERVER" );
+ break;
+ case SSL_SESS_CACHE_BOTH:
+ net_store_data(&packet2,"BOTH" );
+ break;
+ case SSL_SESS_CACHE_NO_AUTO_CLEAR:
+ net_store_data(&packet2,"NO_AUTO_CLEAR" );
+ break;
+ case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
+ net_store_data(&packet2,"NO_INTERNAL_LOOKUP" );
+ break;
+ default:
+ net_store_data(&packet2,"Unknown");
+ break;
+ }
+ break;
+ /* First group - functions relying on SSL */
+ case SHOW_SSL_GET_VERSION:
+ net_store_data(&packet2, thd->net.vio->ssl_arg ?
+ SSL_get_version((SSL*) thd->net.vio->ssl_arg) : "");
+ break;
+ case SHOW_SSL_SESSION_REUSED:
+ net_store_data(&packet2,(uint32) (thd->net.vio->ssl_arg ?
+ SSL_session_reused((SSL*) thd->net.vio->ssl_arg) : 0));
+ break;
+ case SHOW_SSL_GET_DEFAULT_TIMEOUT:
+ net_store_data(&packet2,(uint32) (thd->net.vio->ssl_arg ?
+ SSL_get_default_timeout((SSL*) thd->net.vio->ssl_arg) :
+ 0));
+ break;
+ case SHOW_SSL_GET_VERIFY_MODE:
+ net_store_data(&packet2,(uint32) (thd->net.vio->ssl_arg ?
+ SSL_get_verify_mode((SSL*) thd->net.vio->ssl_arg):0));
+ break;
+ case SHOW_SSL_GET_VERIFY_DEPTH:
+ net_store_data(&packet2,(uint32) (thd->net.vio->ssl_arg ?
+ SSL_get_verify_depth((SSL*) thd->net.vio->ssl_arg):0));
+ break;
+ case SHOW_SSL_GET_CIPHER:
+ net_store_data(&packet2, thd->net.vio->ssl_arg ?
+ SSL_get_cipher((SSL*) thd->net.vio->ssl_arg) : "");
+ break;
+ case SHOW_SSL_GET_CIPHER_LIST:
+ if (thd->net.vio->ssl_arg)
+ {
+ char buf[1024], *pos;
+ pos=buf;
+ for (int i=0 ; i++ ;)
+ {
+ const char *p=SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i);
+ if (p == NULL)
+ break;
+ pos=strmov(pos, p);
+ *pos++= ':';
+ }
+ if (pos != buf)
+ pos--; // Remove last ':'
+ *pos=0;
+ net_store_data(&packet2, buf);
}
+ else
+ net_store_data(&packet2, "");
+ break;
+
+#endif /* HAVE_OPENSSL */
+ case SHOW_UNDEF: // Show never happen
+ case SHOW_SYS:
+ net_store_data(&packet2, ""); // Safety
+ break;
}
if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length()))
goto err; /* purecov: inspected */
}
}
- pthread_mutex_unlock(&LOCK_status);
- /* pthread_mutex_unlock(&THR_LOCK_keycache); */
+ pthread_mutex_unlock(mutex);
send_eof(&thd->net);
DBUG_RETURN(0);
err:
- pthread_mutex_unlock(&LOCK_status);
- /* pthread_mutex_unlock(&THR_LOCK_keycache); */
+ pthread_mutex_unlock(mutex);
DBUG_RETURN(1);
}
#ifdef __GNUC__
-template class List_iterator<char>;
+template class List_iterator_fast<char>;
template class List<char>;
#endif
diff --git a/sql/sql_sort.h b/sql/sql_sort.h
new file mode 100644
index 00000000000..62c5f1cb164
--- /dev/null
+++ b/sql/sql_sort.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Defines used by filesort and uniques */
+
+#define MERGEBUFF 7
+#define MERGEBUFF2 15
+
+typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
+ my_off_t file_pos; /* Where we are in the sort file */
+ uchar *base,*key; /* key pointers */
+ ha_rows count; /* Number of rows in table */
+ ulong mem_count; /* numbers of keys in memory */
+ ulong max_keys; /* Max keys in buffert */
+} BUFFPEK;
+
+
+typedef struct st_sort_param {
+ uint sort_length; /* Length of sort columns */
+ uint keys; /* Max keys / buffert */
+ uint ref_length; /* Length of record ref. */
+ ha_rows max_rows,examined_rows;
+ TABLE *sort_form; /* For quicker make_sortkey */
+ SORT_FIELD *local_sortorder;
+ SORT_FIELD *end;
+ uchar *unique_buff;
+ bool not_killable;
+#ifdef USE_STRCOLL
+ char* tmp_buffer;
+#endif
+} SORTPARAM;
+
+
+int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
+ BUFFPEK *buffpek,
+ uint *maxbuffer, IO_CACHE *t_file);
+uint read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
+ uint sort_length);
+int merge_buffers(SORTPARAM *param,IO_CACHE *from_file,
+ IO_CACHE *to_file, uchar *sort_buffer,
+ BUFFPEK *lastbuff,BUFFPEK *Fb,
+ BUFFPEK *Tb,int flag);
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index e6cdd089bf1..658cd6d2411 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This program file is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is originally from the mysql distribution. Coded by monty */
@@ -21,7 +20,7 @@
#pragma implementation // gcc: Class implementation
#endif
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
@@ -41,19 +40,16 @@ extern void sql_element_free(void *ptr);
bool String::real_alloc(uint32 arg_length)
{
arg_length=ALIGN_SIZE(arg_length+1);
+ str_length=0;
if (Alloced_length < arg_length)
{
free();
if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME))))
- {
- str_length=0;
return TRUE;
- }
Alloced_length=arg_length;
alloced=1;
}
Ptr[0]=0;
- str_length=0;
return FALSE;
}
@@ -362,6 +358,37 @@ skipp:
return -1;
}
+/*
+ Search after a string without regarding to case
+ This needs to be replaced when we have character sets per string
+*/
+
+int String::strstr_case(const String &s,uint32 offset)
+{
+ if (s.length()+offset <= str_length)
+ {
+ if (!s.length())
+ return ((int) offset); // Empty string is always found
+
+ register const char *str = Ptr+offset;
+ register const char *search=s.ptr();
+ const char *end=Ptr+str_length-s.length()+1;
+ const char *search_end=s.ptr()+s.length();
+skipp:
+ while (str != end)
+ {
+ if (my_sort_order[*str++] == my_sort_order[*search])
+ {
+ register char *i,*j;
+ i=(char*) str; j=(char*) search+1;
+ while (j != search_end)
+ if (my_sort_order[*i++] != my_sort_order[*j++]) goto skipp;
+ return (int) (str-Ptr) -1;
+ }
+ }
+ }
+ return -1;
+}
/*
** Search string from end. Offset is offset to the end of string
@@ -440,9 +467,9 @@ int sortcmp(const String *x,const String *y)
if (use_strcoll(default_charset_info))
{
#ifndef CMP_ENDSPACE
- while (x_len && isspace(s[x_len-1]))
+ while (x_len && s[x_len-1] == ' ')
x_len--;
- while (y_len && isspace(t[y_len-1]))
+ while (y_len && t[y_len-1] == ' ')
y_len--;
#endif
return my_strnncoll(default_charset_info,
@@ -466,14 +493,14 @@ int sortcmp(const String *x,const String *y)
{
const char *end=t+y_len;
for (; t != end ; t++)
- if (!isspace(*t))
+ if (*t != ' ')
return -1;
}
else
{
const char *end=s+x_len;
for (; s != end ; s++)
- if (!isspace(*s))
+ if (*s != ' ')
return 1;
}
return 0;
@@ -577,7 +604,7 @@ int wild_case_compare(const char *str,const char *str_end,
{
do
{
- if (str == str_end) // Skipp one char if possible
+ if (str == str_end) // Skip one char if possible
return (result);
INC_PTR(str,str_end);
} while (++wildstr < wildend && *wildstr == wild_one);
@@ -588,7 +615,7 @@ int wild_case_compare(const char *str,const char *str_end,
{ // Found wild_many
wildstr++;
/* Remove any '%' and '_' from the wild search string */
- for ( ; wildstr != wildend ; wildstr++)
+ for (; wildstr != wildend ; wildstr++)
{
if (*wildstr == wild_many)
continue;
@@ -668,8 +695,11 @@ int wild_case_compare(const char *str,const char *str_end,
int wild_case_compare(String &match,String &wild, char escape)
{
- return wild_case_compare(match.ptr(),match.ptr()+match.length(),
- wild.ptr(), wild.ptr()+wild.length(),escape);
+ DBUG_ENTER("wild_case_compare");
+ DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'"
+ ,match.ptr(),wild.ptr(),escape));
+ DBUG_RETURN(wild_case_compare(match.ptr(),match.ptr()+match.length(),
+ wild.ptr(), wild.ptr()+wild.length(),escape));
}
/*
@@ -679,6 +709,9 @@ int wild_case_compare(String &match,String &wild, char escape)
int wild_compare(const char *str,const char *str_end,
const char *wildstr,const char *wildend,char escape)
{
+ DBUG_ENTER("wild_compare");
+ DBUG_PRINT("enter",("str='%s', str_end='%s', wildstr='%s', wildend='%s', escape='%c'"
+ ,str,str_end,wildstr,wildend,escape));
int result= -1; // Not found, using wildcards
while (wildstr != wildend)
{
@@ -687,17 +720,21 @@ int wild_compare(const char *str,const char *str_end,
if (*wildstr == escape && wildstr+1 != wildend)
wildstr++;
if (str == str_end || *wildstr++ != *str++)
- return(1);
+ {
+ DBUG_RETURN(1);
+ }
if (wildstr == wildend)
- return (str != str_end); // Match if both are at end
+ {
+ DBUG_RETURN(str != str_end); // Match if both are at end
+ }
result=1; // Found an anchor char
}
if (*wildstr == wild_one)
{
do
{
- if (str == str_end) // Skipp one char if possible
- return (result);
+ if (str == str_end) // Skip one char if possible
+ DBUG_RETURN(result);
str++;
} while (*++wildstr == wild_one && wildstr != wildend);
if (wildstr == wildend)
@@ -707,24 +744,29 @@ int wild_compare(const char *str,const char *str_end,
{ // Found wild_many
wildstr++;
/* Remove any '%' and '_' from the wild search string */
- for ( ; wildstr != wildend ; wildstr++)
+ for (; wildstr != wildend ; wildstr++)
{
if (*wildstr == wild_many)
continue;
if (*wildstr == wild_one)
{
if (str == str_end)
- return (-1);
+ {
+ DBUG_RETURN(-1);
+ }
str++;
continue;
}
break; // Not a wild character
}
if (wildstr == wildend)
- return(0); // Ok if wild_many is last
+ {
+ DBUG_RETURN(0); // Ok if wild_many is last
+ }
if (str == str_end)
- return -1;
-
+ {
+ DBUG_RETURN(-1);
+ }
char cmp;
if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
cmp= *++wildstr;
@@ -733,22 +775,30 @@ int wild_compare(const char *str,const char *str_end,
{
while (str != str_end && *str != cmp)
str++;
- if (str++ == str_end) return (-1);
+ if (str++ == str_end)
+ {
+ DBUG_RETURN(-1);
+ }
{
int tmp=wild_compare(str,str_end,wildstr,wildend,escape);
if (tmp <= 0)
- return (tmp);
+ {
+ DBUG_RETURN(tmp);
+ }
}
} while (str != str_end && wildstr[0] != wild_many);
- return(-1);
+ DBUG_RETURN(-1);
}
}
- return (str != str_end ? 1 : 0);
+ DBUG_RETURN(str != str_end ? 1 : 0);
}
int wild_compare(String &match,String &wild, char escape)
{
- return wild_compare(match.ptr(),match.ptr()+match.length(),
- wild.ptr(), wild.ptr()+wild.length(),escape);
+ DBUG_ENTER("wild_compare");
+ DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'"
+ ,match.ptr(),wild.ptr(),escape));
+ DBUG_RETURN(wild_compare(match.ptr(),match.ptr()+match.length(),
+ wild.ptr(), wild.ptr()+wild.length(),escape));
}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 31dea9991cc..ad7455ecbf1 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is originally from the mysql distribution. Coded by monty */
@@ -161,6 +160,7 @@ public:
bool append(const char *s,uint32 arg_length=0);
bool append(IO_CACHE* file, uint32 arg_length);
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
+ int strstr_case(const String &s,uint32 offset=0);
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
bool replace(uint32 offset,uint32 arg_length,const String &to);
inline bool append(char chr)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 04dfd8a1fbd..9aa2180b5dd 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,17 +18,20 @@
/* drop and alter of tables */
#include "mysql_priv.h"
-#include <hash.h>
#ifdef HAVE_BERKELEY_DB
-#include <ha_berkeley.h>
+#include "ha_berkeley.h"
#endif
+#include <hash.h>
#include <myisam.h>
+#include <my_dir.h>
+#include <assert.h>
#ifdef __WIN__
#include <io.h>
#endif
extern HASH open_cache;
+static const char *primary_key_name="PRIMARY";
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
@@ -38,20 +41,32 @@ static int copy_data_between_tables(TABLE *from,TABLE *to,
ORDER *order,
ha_rows *copied,ha_rows *deleted);
-/*****************************************************************************
-** Remove all possbile tables and give a compact errormessage for all
-** wrong tables.
-** This will wait for all users to free the table before dropping it
-*****************************************************************************/
+/*
+ delete (drop) tables.
+
+ SYNOPSIS
+ mysql_rm_table()
+ thd Thread handle
+ tables List of tables to delete
+ if_exists If 1, don't give error if one table doesn't exists
+
+ NOTES
+ Will delete all tables that can be deleted and give a compact error
+ messages for tables that could not be deleted.
+ If a table is in use, we will wait for all users to free the table
+ before dropping it
+
+ Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set.
+
+ RETURN
+ 0 ok. In this case ok packet is sent to user
+ -1 Error (Error message given but not sent to user)
+
+*/
int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
{
- char path[FN_REFLEN];
- String wrong_tables;
- bool some_tables_deleted=0;
- uint error= 1;
- db_type table_type;
- TABLE_LIST *table;
+ int error= 0;
DBUG_ENTER("mysql_rm_table");
/* mark for close and remove all cached entries */
@@ -66,6 +81,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
{
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
tables->real_name);
+ error= 1;
goto err;
}
while (global_read_lock && ! thd->killed)
@@ -74,16 +90,96 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
}
}
-
+ error=mysql_rm_table_part2(thd,tables,if_exists,0);
+
+ err:
+ pthread_mutex_unlock(&LOCK_open);
+
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->mysys_var->current_mutex= 0;
+ thd->mysys_var->current_cond= 0;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
+
+ if (error)
+ DBUG_RETURN(-1);
+ send_ok(&thd->net);
+ DBUG_RETURN(0);
+}
+
+
+/*
+ delete (drop) tables.
+
+ SYNOPSIS
+ mysql_rm_table_part2_with_lock()
+ thd Thread handle
+ tables List of tables to delete
+ if_exists If 1, don't give error if one table doesn't exists
+ dont_log_query Don't write query to log files
+
+ NOTES
+ Works like documented in mysql_rm_table(), but don't check
+ global_read_lock and don't send_ok packet to server.
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
+int mysql_rm_table_part2_with_lock(THD *thd,
+ TABLE_LIST *tables, bool if_exists,
+ bool dont_log_query)
+{
+ int error;
+ thd->mysys_var->current_mutex= &LOCK_open;
+ thd->mysys_var->current_cond= &COND_refresh;
+ VOID(pthread_mutex_lock(&LOCK_open));
+
+ error=mysql_rm_table_part2(thd,tables, if_exists, dont_log_query);
+
+ pthread_mutex_unlock(&LOCK_open);
+
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->mysys_var->current_mutex= 0;
+ thd->mysys_var->current_cond= 0;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
+ return error;
+}
+
+
+/*
+ TODO:
+ When logging to the binary log, we should log
+ tmp_tables and transactional tables as separate statements if we
+ are in a transaction; This is needed to get these tables into the
+ cached binary log that is only written on COMMIT.
+
+ The current code only writes DROP statements that only uses temporary
+ tables to the cache binary log. This should be ok on most cases, but
+ not all.
+*/
+
+int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
+ bool dont_log_query)
+{
+ TABLE_LIST *table;
+ char path[FN_REFLEN], *alias;
+ String wrong_tables;
+ db_type table_type;
+ int error;
+ bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
+ DBUG_ENTER("mysql_rm_table_part2");
+
if (lock_table_names(thd, tables))
- goto err;
+ DBUG_RETURN(1);
for (table=tables ; table ; table=table->next)
{
- char *db=table->db ? table->db : (thd->db ? thd->db : (char*) "");
+ char *db=table->db;
+ mysql_ha_closeall(thd, table);
if (!close_temporary_table(thd, db, table->real_name))
{
- some_tables_deleted=1; // Log query
+ tmp_table_deleted=1;
continue; // removed temporary table
}
@@ -96,23 +192,13 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
}
drop_locked_tables(thd,db,table->real_name);
if (thd->killed)
- {
- VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
- VOID(pthread_mutex_unlock(&LOCK_open));
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
DBUG_RETURN(-1);
- }
+ alias= (lower_case_table_names == 2) ? table->alias : table->real_name;
/* remove form file and isam files */
- (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table->real_name,
- reg_ext);
+ strxmov(path, mysql_data_home, "/", db, "/", alias, reg_ext, NullS);
(void) unpack_filename(path,path);
error=0;
- table_type=get_table_type(path);
-
if (access(path,F_OK))
{
if (!if_exists)
@@ -121,10 +207,14 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
else
{
char *end;
- *(end=fn_ext(path))=0; // Remove extension
+ table_type= get_table_type(path);
+ *(end=fn_ext(path))=0; // Remove extension for delete
error=ha_delete_table(table_type, path);
if (error == ENOENT && if_exists)
error = 0;
+ if (error == HA_ERR_ROW_IS_REFERENCED)
+ foreign_key_error=1; /* the table is referenced by a foreign key
+ constraint */
if (!error || error == ENOENT)
{
/* Delete the table definition file */
@@ -140,36 +230,33 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
wrong_tables.append(String(table->real_name));
}
}
- if (some_tables_deleted)
+ if (some_tables_deleted || tmp_table_deleted)
{
- mysql_update_log.write(thd, thd->query,thd->query_length);
- if (mysql_bin_log.is_open())
+ query_cache_invalidate3(thd, tables, 0);
+ if (!dont_log_query)
{
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
+ mysql_update_log.write(thd, thd->query,thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ tmp_table_deleted && !some_tables_deleted);
+ mysql_bin_log.write(&qinfo);
+ }
}
}
-
- error = 0;
- unlock_table_names(thd, tables);
-
- err:
- pthread_mutex_unlock(&LOCK_open);
-
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
+ unlock_table_names(thd, tables);
+ error= 0;
if (wrong_tables.length())
{
- my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr());
- error=1;
+ if (!foreign_key_error)
+ my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr());
+ else
+ my_error(ER_ROW_IS_REFERENCED,MYF(0));
+ error= 1;
}
- if (error)
- DBUG_RETURN(-1);
- send_ok(&thd->net);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
@@ -187,10 +274,79 @@ int quick_rm_table(enum db_type base,const char *db,
return ha_delete_table(base,path) || error;
}
-/*****************************************************************************
- * Create a table.
- * If one creates a temporary table, this is automaticly opened
- ****************************************************************************/
+/*
+ Sort keys in the following order:
+ - PRIMARY KEY
+ - UNIQUE keyws where all column are NOT NULL
+ - Other UNIQUE keys
+ - Normal keys
+ - Fulltext keys
+
+ This will make checking for duplicated keys faster and ensure that
+ PRIMARY keys are prioritized.
+*/
+
+
+static int sort_keys(KEY *a, KEY *b)
+{
+ if (a->flags & HA_NOSAME)
+ {
+ if (!(b->flags & HA_NOSAME))
+ return -1;
+ if ((a->flags ^ b->flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
+ {
+ /* Sort NOT NULL keys before other keys */
+ return (a->flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
+ }
+ if (a->name == primary_key_name)
+ return -1;
+ if (b->name == primary_key_name)
+ return 1;
+ }
+ else if (b->flags & HA_NOSAME)
+ return 1; // Prefer b
+
+ if ((a->flags ^ b->flags) & HA_FULLTEXT)
+ {
+ return (a->flags & HA_FULLTEXT) ? 1 : -1;
+ }
+ /*
+ Prefer original key order. usable_key_parts contains here
+ the original key position.
+ */
+ return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
+ (a->usable_key_parts > b->usable_key_parts) ? 1 :
+ 0);
+}
+
+
+/*
+ Create a table
+
+ SYNOPSIS
+ mysql_create_table()
+ thd Thread object
+ db Database
+ table_name Table name
+ create_info Create information (like MAX_ROWS)
+ fields List of fields to create
+ keys List of keys to create
+ tmp_table Set to 1 if this is an internal temporary table
+ (From ALTER TABLE)
+ no_log Don't log the query to binary log.
+
+ DESCRIPTION
+ If one creates a temporary table, this is automaticly opened
+
+ no_log is needed for the case of CREATE ... SELECT,
+ as the logging will be done later in sql_insert.cc
+ select_field_count is also used for CREATE ... SELECT,
+ and must be zero for standard create of table.
+
+ RETURN VALUES
+ 0 ok
+ -1 error
+*/
int mysql_create_table(THD *thd,const char *db, const char *table_name,
HA_CREATE_INFO *create_info,
@@ -198,7 +354,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
List<Key> &keys,bool tmp_table,bool no_log)
{
char path[FN_REFLEN];
- const char *key_name;
+ const char *key_name, *alias;
create_field *sql_field,*dup_field;
int error= -1;
uint db_options,field,null_fields,blob_columns;
@@ -209,10 +365,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
handler *file;
DBUG_ENTER("mysql_create_table");
- /*
- ** Check for duplicate fields and check type of table to create
- */
-
+ /* Check for duplicate fields and check type of table to create */
if (!fields.elements)
{
my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0));
@@ -223,10 +376,11 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
db_options=create_info->table_options;
if (create_info->row_type == ROW_TYPE_DYNAMIC)
db_options|=HA_OPTION_PACK_RECORD;
+ alias= table_case_name(create_info, table_name);
file=get_new_handler((TABLE*) 0, create_info->db_type);
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
- (file->option_flag() & HA_NO_TEMP_TABLES))
+ (file->table_flags() & HA_NO_TEMP_TABLES))
{
my_error(ER_ILLEGAL_HA,MYF(0),table_name);
DBUG_RETURN(-1);
@@ -330,13 +484,13 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
if (auto_increment &&
- (file->option_flag() & HA_WRONG_ASCII_ORDER))
+ (file->table_flags() & HA_NO_AUTO_INCREMENT))
{
my_error(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,MYF(0));
DBUG_RETURN(-1);
}
- if (blob_columns && (file->option_flag() & HA_NO_BLOBS))
+ if (blob_columns && (file->table_flags() & HA_NO_BLOBS))
{
my_error(ER_TABLE_CANT_HANDLE_BLOB,MYF(0));
DBUG_RETURN(-1);
@@ -347,10 +501,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
List_iterator<Key> key_iterator(keys);
uint key_parts=0,key_count=keys.elements;
List<Key> keys_in_order; // Add new keys here
- Key *primary_key=0;
- bool unique_key=0;
+ bool primary_key=0,unique_key=0;
Key *key;
- uint tmp;
+ uint tmp, key_number;
tmp=min(file->max_keys(), MAX_KEY);
if (key_count > tmp)
{
@@ -358,12 +511,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
- /*
- Check keys;
- Put PRIMARY KEY first, then UNIQUE keys and other keys last
- This will make checking for duplicated keys faster and ensure that
- primary keys are prioritized.
- */
+ /* Calculate number of key segements */
while ((key=key_iterator++))
{
@@ -379,33 +527,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
key_parts+=key->columns.elements;
- if (key->type == Key::PRIMARY)
- {
- if (primary_key)
- {
- my_error(ER_MULTIPLE_PRI_KEY,MYF(0));
- DBUG_RETURN(-1);
- }
- primary_key=key;
- }
- else if (key->type == Key::UNIQUE)
- {
- unique_key=1;
- if (keys_in_order.push_front(key))
- DBUG_RETURN(-1);
- }
- else if (keys_in_order.push_back(key))
- DBUG_RETURN(-1);
- }
- if (primary_key)
- {
- if (keys_in_order.push_front(primary_key))
- DBUG_RETURN(-1);
- }
- else if (!unique_key && (file->option_flag() & HA_REQUIRE_PRIMARY_KEY))
- {
- my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0));
- DBUG_RETURN(-1);
}
key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)*key_count);
@@ -413,8 +534,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if (!key_info_buffer || ! key_part_info)
DBUG_RETURN(-1); // Out of memory
- List_iterator<Key> key_iterator_in_order(keys_in_order);
- for (; (key=key_iterator_in_order++) ; key_info++)
+ key_iterator.rewind();
+ key_number=0;
+ for (; (key=key_iterator++) ; key_info++, key_number++)
{
uint key_length=0;
key_part_spec *column;
@@ -423,10 +545,13 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
(key->type == Key::FULLTEXT) ? HA_FULLTEXT : HA_NOSAME;
key_info->key_parts=(uint8) key->columns.elements;
key_info->key_part=key_part_info;
+ key_info->usable_key_parts= key_number;
+ key_info->algorithm=key->algorithm;
+ /* TODO: Add proper checks if handler supports key_type and algorithm */
if (key->type == Key::FULLTEXT)
{
- if (file->option_flag() & HA_NO_FULLTEXT_KEY)
+ if (!(file->table_flags() & HA_CAN_FULLTEXT))
{
my_error(ER_TABLE_CANT_HANDLE_FULLTEXT, MYF(0));
DBUG_RETURN(-1);
@@ -448,9 +573,17 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
column->field_name);
DBUG_RETURN(-1);
}
+ /* for fulltext keys keyseg length is 1 for blobs (it's ignored in
+ ft code anyway, and 0 (set to column width later) for char's.
+ it has to be correct col width for char's, as char data are not
+ prefixed with length (unlike blobs, where ft code takes data length
+ from a data prefix, ignoring column->length).
+ */
+ if (key->type == Key::FULLTEXT)
+ column->length=test(f_is_blob(sql_field->pack_flag));
if (f_is_blob(sql_field->pack_flag))
{
- if (!(file->option_flag() & HA_BLOB_KEY))
+ if (!(file->table_flags() & HA_BLOB_KEY))
{
my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0),
column->field_name);
@@ -458,25 +591,23 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
if (!column->length)
{
- if (key->type == Key::FULLTEXT)
- column->length=1; /* ft-code ignores it anyway :-) */
- else
- {
- my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH,
- ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0),
- column->field_name);
- DBUG_RETURN(-1);
- }
+ my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH,
+ ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0),
+ column->field_name);
+ DBUG_RETURN(-1);
}
}
if (!(sql_field->flags & NOT_NULL_FLAG))
{
if (key->type == Key::PRIMARY)
{
- my_error(ER_PRIMARY_CANT_HAVE_NULL, MYF(0));
- DBUG_RETURN(-1);
+ /* Implicitly set primary key fields to NOT NULL for ISO conf. */
+ sql_field->flags|= NOT_NULL_FLAG;
+ sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
}
- if (!(file->option_flag() & HA_NULL_KEY))
+ else
+ key_info->flags|= HA_NULL_PART_KEY;
+ if (!(file->table_flags() & HA_NULL_KEY))
{
my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX),
MYF(0),column->field_name);
@@ -485,7 +616,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
{
- if (column_nr == 0 || (file->option_flag() & HA_AUTO_PART_KEY))
+ if (column_nr == 0 || (file->table_flags() & HA_AUTO_PART_KEY))
auto_increment--; // Field is used
}
key_part_info->fieldnr= field;
@@ -505,14 +636,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
else if (column->length > length ||
((f_is_packed(sql_field->pack_flag) ||
- ((file->option_flag() & HA_NO_PREFIX_CHAR_KEYS) &&
+ ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
(key_info->flags & HA_NOSAME))) &&
column->length != length))
{
my_error(ER_WRONG_SUB_KEY,MYF(0));
DBUG_RETURN(-1);
}
- if (!(file->option_flag() & HA_NO_PREFIX_CHAR_KEYS))
+ if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS))
length=column->length;
}
else if (length == 0)
@@ -541,7 +672,15 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if (column_nr == 0)
{
if (key->type == Key::PRIMARY)
- key_name="PRIMARY";
+ {
+ if (primary_key)
+ {
+ my_error(ER_MULTIPLE_PRI_KEY,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ key_name=primary_key_name;
+ primary_key=1;
+ }
else if (!(key_name = key->name()))
key_name=make_unique_key_name(sql_field->field_name,
key_info_buffer,key_info);
@@ -553,18 +692,29 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
key_info->name=(char*) key_name;
}
}
+ if (!(key_info->flags & HA_NULL_PART_KEY))
+ unique_key=1;
key_info->key_length=(uint16) key_length;
- if (key_length > file->max_key_length() && key->type != Key::FULLTEXT)
+ uint max_key_length= min(file->max_key_length(), MAX_KEY_LENGTH);
+ if (key_length > max_key_length && key->type != Key::FULLTEXT)
{
- my_error(ER_TOO_LONG_KEY,MYF(0),file->max_key_length());
+ my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
DBUG_RETURN(-1);
}
}
+ if (!unique_key && !primary_key &&
+ (file->table_flags() & HA_REQUIRE_PRIMARY_KEY))
+ {
+ my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0));
+ DBUG_RETURN(-1);
+ }
if (auto_increment > 0)
{
my_error(ER_WRONG_AUTO_KEY,MYF(0));
DBUG_RETURN(-1);
}
+ /* Sort keys in optimized order */
+ qsort((gptr) key_info_buffer, key_count, sizeof(KEY), (qsort_cmp) sort_keys);
/* Check if table exists */
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
@@ -574,14 +724,17 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
}
else
- (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table_name,reg_ext);
+ (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,alias,reg_ext);
unpack_filename(path,path);
/* Check if table already exists */
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE)
&& find_temporary_table(thd,db,table_name))
{
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
+ {
+ create_info->table_existed= 1; // Mark that table existed
DBUG_RETURN(0);
+ }
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
DBUG_RETURN(-1);
}
@@ -592,32 +745,28 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
{
VOID(pthread_mutex_unlock(&LOCK_open));
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
+ {
+ create_info->table_existed= 1; // Mark that table existed
DBUG_RETURN(0);
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
+ }
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0), alias);
DBUG_RETURN(-1);
}
}
thd->proc_info="creating table";
+ create_info->table_existed= 0; // Mark that table is created
- create_info->create_statement = thd->query;
+ if (thd->sql_mode & MODE_NO_DIR_IN_CREATE)
+ create_info->data_file_name= create_info->index_file_name= 0;
create_info->table_options=db_options;
+
if (rea_create_table(path, create_info, fields, key_count,
key_info_buffer))
{
/* my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,my_errno); */
goto end;
}
- if (!tmp_table && !no_log)
- {
- // Must be written before unlock
- mysql_update_log.write(thd,thd->query, thd->query_length);
- if (mysql_bin_log.is_open())
- {
- Query_log_event qinfo(thd, thd->query);
- mysql_bin_log.write(&qinfo);
- }
- }
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
/* Open table and put in temporary table list */
@@ -627,6 +776,19 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
goto end;
}
}
+ if (!tmp_table && !no_log)
+ {
+ // Must be written before unlock
+ mysql_update_log.write(thd,thd->query, thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ test(create_info->options &
+ HA_LEX_CREATE_TMP_TABLE));
+ mysql_bin_log.write(&qinfo);
+ }
+ }
error=0;
end:
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -681,7 +843,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
DBUG_ENTER("create_table_from_items");
/* Add selected items to field list */
- List_iterator<Item> it(*items);
+ List_iterator_fast<Item> it(*items);
Item *item;
Field *tmp_field;
tmp_table.db_create_options=0;
@@ -693,8 +855,12 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
while ((item=it++))
{
create_field *cr_field;
- Field *field=create_tmp_field(&tmp_table,item,item->type(),
- (Item_result_field***) 0, &tmp_field,0,0);
+ Field *field;
+ if (item->type() == Item::FUNC_ITEM)
+ field=item->tmp_table_field(&tmp_table);
+ else
+ field=create_tmp_field(thd, &tmp_table, item, item->type(),
+ (Item ***) 0, &tmp_field,0,0);
if (!field ||
!(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
((Item_field *)item)->field :
@@ -709,7 +875,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(0);
if (!(table=open_table(thd,db,name,name,(bool*) 0)))
{
- quick_rm_table(create_info->db_type,db,name);
+ quick_rm_table(create_info->db_type,db,table_case_name(create_info,name));
DBUG_RETURN(0);
}
table->reginfo.lock_type=TL_WRITE;
@@ -718,7 +884,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
VOID(pthread_mutex_lock(&LOCK_open));
hash_delete(&open_cache,(byte*) table);
VOID(pthread_mutex_unlock(&LOCK_open));
- quick_rm_table(create_info->db_type,db,name);
+ quick_rm_table(create_info->db_type,db,table_case_name(create_info, name));
DBUG_RETURN(0);
}
table->file->extra(HA_EXTRA_WRITE_CACHE);
@@ -733,18 +899,32 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
bool
mysql_rename_table(enum db_type base,
const char *old_db,
- const char * old_name,
+ const char *old_name,
const char *new_db,
- const char * new_name)
+ const char *new_name)
{
- char from[FN_REFLEN],to[FN_REFLEN];
+ char from[FN_REFLEN], to[FN_REFLEN];
+ char tmp_from[NAME_LEN+1], tmp_to[NAME_LEN+1];
handler *file=get_new_handler((TABLE*) 0, base);
int error=0;
DBUG_ENTER("mysql_rename_table");
+
+ if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
+ {
+ /* Table handler expects to get all file names as lower case */
+ strmov(tmp_from, old_name);
+ casedn_str(tmp_from);
+ old_name= tmp_from;
+
+ strmov(tmp_to, new_name);
+ casedn_str(tmp_to);
+ new_name= tmp_to;
+ }
(void) sprintf(from,"%s/%s/%s",mysql_data_home,old_db,old_name);
(void) sprintf(to,"%s/%s/%s",mysql_data_home,new_db,new_name);
fn_format(from,from,"","",4);
fn_format(to,to, "","",4);
+
if (!(error=file->rename_table((const char*) from,(const char *) to)))
{
if (rename_file_ext(from,to,reg_ext))
@@ -760,48 +940,81 @@ mysql_rename_table(enum db_type base,
DBUG_RETURN(error != 0);
}
+
/*
- close table in this thread and force close + reopen in other threads
- This assumes that the calling thread has lock on LOCK_open
- Win32 clients must also have a WRITE LOCK on the table !
+ Force all other threads to stop using the table
+
+ SYNOPSIS
+ wait_while_table_is_used()
+ thd Thread handler
+ table Table to remove from cache
+ function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted
+ HA_EXTRA_FORCE_REOPEN if table is not be used
+ NOTES
+ When returning, the table will be unusable for other threads until
+ the table is closed.
+
+ PREREQUISITES
+ Lock on LOCK_open
+ Win32 clients must also have a WRITE LOCK on the table !
*/
-bool close_cached_table(THD *thd,TABLE *table)
+static void wait_while_table_is_used(THD *thd,TABLE *table,
+ enum ha_extra_function function)
{
- bool result=0;
- DBUG_ENTER("close_cached_table");
- if (table)
+ DBUG_PRINT("enter",("table: %s", table->real_name));
+ DBUG_ENTER("wait_while_table_is_used");
+ safe_mutex_assert_owner(&LOCK_open);
+
+ VOID(table->file->extra(function));
+ /* Mark all tables that are in use as 'old' */
+ mysql_lock_abort(thd, table); // end threads waiting on lock
+
+ /* Wait until all there are no other threads that has this table open */
+ while (remove_table_from_cache(thd,table->table_cache_key,
+ table->real_name))
{
- DBUG_PRINT("enter",("table: %s", table->table_name));
- VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files
- /* Mark all tables that are in use as 'old' */
- mysql_lock_abort(thd,table); // end threads waiting on lock
+ dropping_tables++;
+ (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
+ dropping_tables--;
+ }
+ DBUG_VOID_RETURN;
+}
-#if defined(USING_TRANSACTIONS) || defined( __WIN__) || defined( __EMX__) || !defined(OS2)
- /* Wait until all there are no other threads that has this table open */
- while (remove_table_from_cache(thd,table->table_cache_key,
- table->real_name))
- {
- dropping_tables++;
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- dropping_tables--;
- }
-#else
- (void) remove_table_from_cache(thd,table->table_cache_key,
- table->real_name);
-#endif
- /* When lock on LOCK_open is freed other threads can continue */
- pthread_cond_broadcast(&COND_refresh);
+/*
+ Close a cached table
- /* Close lock if this is not got with LOCK TABLES */
- if (thd->lock)
- {
- mysql_unlock_tables(thd, thd->lock); thd->lock=0; // Start locked threads
- }
- /* Close all copies of 'table'. This also frees all LOCK TABLES lock */
- thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
+ SYNOPSIS
+ close_cached_table()
+ thd Thread handler
+ table Table to remove from cache
+
+ NOTES
+ Function ends by signaling threads waiting for the table to try to
+ reopen the table.
+
+ PREREQUISITES
+ Lock on LOCK_open
+ Win32 clients must also have a WRITE LOCK on the table !
+*/
+
+static bool close_cached_table(THD *thd, TABLE *table)
+{
+ DBUG_ENTER("close_cached_table");
+
+ wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE);
+ /* Close lock if this is not got with LOCK TABLES */
+ if (thd->lock)
+ {
+ mysql_unlock_tables(thd, thd->lock);
+ thd->lock=0; // Start locked threads
}
- DBUG_RETURN(result);
+ /* Close all copies of 'table'. This also frees all LOCK TABLES lock */
+ thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
+
+ /* When lock on LOCK_open is freed other threads can continue */
+ pthread_cond_broadcast(&COND_refresh);
+ DBUG_RETURN(0);
}
static int send_check_errmsg(THD* thd, TABLE_LIST* table,
@@ -822,7 +1035,9 @@ static int send_check_errmsg(THD* thd, TABLE_LIST* table,
return 1;
}
-static int prepare_for_restore(THD* thd, TABLE_LIST* table)
+
+static int prepare_for_restore(THD* thd, TABLE_LIST* table,
+ HA_CHECK_OPT *check_opt)
{
DBUG_ENTER("prepare_for_restore");
@@ -839,31 +1054,18 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
char* table_name = table->real_name;
char* db = thd->db ? thd->db : table->db;
- if (!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64))
+ if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
+ reg_ext))
DBUG_RETURN(-1); // protect buffer overflow
sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name);
- int lock_retcode;
- pthread_mutex_lock(&LOCK_open);
- if ((lock_retcode = lock_table_name(thd, table)) < 0)
- {
- pthread_mutex_unlock(&LOCK_open);
- DBUG_RETURN(-1);
- }
-
- if (lock_retcode && wait_for_locked_table_names(thd, table))
- {
- unlock_table_name(thd, table);
- pthread_mutex_unlock(&LOCK_open);
+ if (lock_and_wait_for_table_name(thd,table))
DBUG_RETURN(-1);
- }
- pthread_mutex_unlock(&LOCK_open);
if (my_copy(src_path,
- fn_format(dst_path, dst_path,"",
- reg_ext, 4),
- MYF(MY_WME)))
+ fn_format(dst_path, dst_path,"", reg_ext, 4),
+ MYF(MY_WME)))
{
pthread_mutex_lock(&LOCK_open);
unlock_table_name(thd, table);
@@ -871,33 +1073,143 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
"Failed copying .frm file"));
}
- bool save_no_send_ok = thd->net.no_send_ok;
- thd->net.no_send_ok = 1;
- // generate table will try to send OK which messes up the output
- // for the client
-
- if (generate_table(thd, table, 0))
+ if (mysql_truncate(thd, table, 1))
{
pthread_mutex_lock(&LOCK_open);
unlock_table_name(thd, table);
pthread_mutex_unlock(&LOCK_open);
- thd->net.no_send_ok = save_no_send_ok;
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
"Failed generating table from .frm file"));
}
-
- thd->net.no_send_ok = save_no_send_ok;
}
+ /*
+ Now we should be able to open the partially restored table
+ to finish the restore in the handler later on
+ */
+ if (!(table->table = reopen_name_locked_table(thd, table)))
+ {
+ pthread_mutex_lock(&LOCK_open);
+ unlock_table_name(thd, table);
+ pthread_mutex_unlock(&LOCK_open);
+ }
DBUG_RETURN(0);
}
+
+static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
+ HA_CHECK_OPT *check_opt)
+{
+ int error= 0;
+ TABLE tmp_table, *table;
+ DBUG_ENTER("prepare_for_repair");
+
+ if (!(check_opt->sql_flags & TT_USEFRM))
+ DBUG_RETURN(0);
+
+ if (!(table= table_list->table)) /* if open_ltable failed */
+ {
+ char name[FN_REFLEN];
+ strxmov(name, mysql_data_home, "/", table_list->db, "/",
+ table_list->real_name, NullS);
+ if (openfrm(name, "", 0, 0, 0, &tmp_table))
+ DBUG_RETURN(0); // Can't open frm file
+ table= &tmp_table;
+ }
+
+ /*
+ User gave us USE_FRM which means that the header in the index file is
+ trashed.
+ In this case we will try to fix the table the following way:
+ - Rename the data file to a temporary name
+ - Truncate the table
+ - Replace the new data file with the old one
+ - Run a normal repair using the new index file and the old data file
+ */
+
+ char from[FN_REFLEN],tmp[FN_REFLEN+32];
+ const char **ext= table->file->bas_ext();
+ MY_STAT stat_info;
+
+ /*
+ Check if this is a table type that stores index and data separately,
+ like ISAM or MyISAM
+ */
+ if (!ext[0] || !ext[1])
+ goto end; // No data file
+
+ strxmov(from, table->path, ext[1], NullS); // Name of data file
+ if (!my_stat(from, &stat_info, MYF(0)))
+ goto end; // Can't use USE_FRM flag
+
+ sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
+
+ /* If we could open the table, close it */
+ if (table_list->table)
+ {
+ pthread_mutex_lock(&LOCK_open);
+ close_cached_table(thd, table);
+ pthread_mutex_unlock(&LOCK_open);
+ }
+ if (lock_and_wait_for_table_name(thd,table_list))
+ {
+ error= -1;
+ goto end;
+ }
+ if (my_rename(from, tmp, MYF(MY_WME)))
+ {
+ pthread_mutex_lock(&LOCK_open);
+ unlock_table_name(thd, table_list);
+ pthread_mutex_unlock(&LOCK_open);
+ error= send_check_errmsg(thd, table_list, "repair",
+ "Failed renaming data file");
+ goto end;
+ }
+ if (mysql_truncate(thd, table_list, 1))
+ {
+ pthread_mutex_lock(&LOCK_open);
+ unlock_table_name(thd, table_list);
+ pthread_mutex_unlock(&LOCK_open);
+ error= send_check_errmsg(thd, table_list, "repair",
+ "Failed generating table from .frm file");
+ goto end;
+ }
+ if (my_rename(tmp, from, MYF(MY_WME)))
+ {
+ pthread_mutex_lock(&LOCK_open);
+ unlock_table_name(thd, table_list);
+ pthread_mutex_unlock(&LOCK_open);
+ error= send_check_errmsg(thd, table_list, "repair",
+ "Failed restoring .MYD file");
+ goto end;
+ }
+
+ /*
+ Now we should be able to open the partially repaired table
+ to finish the repair in the handler later on.
+ */
+ if (!(table_list->table = reopen_name_locked_table(thd, table_list)))
+ {
+ pthread_mutex_lock(&LOCK_open);
+ unlock_table_name(thd, table_list);
+ pthread_mutex_unlock(&LOCK_open);
+ }
+
+end:
+ if (table == &tmp_table)
+ closefrm(table); // Free allocated memory
+ DBUG_RETURN(error);
+}
+
+
static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
HA_CHECK_OPT* check_opt,
const char *operator_name,
thr_lock_type lock_type,
- bool open_for_modify, bool restore,
+ bool open_for_modify,
uint extra_open_options,
+ int (*prepare_func)(THD *, TABLE_LIST *,
+ HA_CHECK_OPT *),
int (handler::*operator_func)
(THD *, HA_CHECK_OPT *))
{
@@ -918,6 +1230,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (send_fields(thd, field_list, 1))
DBUG_RETURN(-1);
+ mysql_ha_closeall(thd, tables);
for (table = tables; table; table = table->next)
{
char table_name[NAME_LEN*2+2];
@@ -929,23 +1242,15 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
table->table = open_ltable(thd, table, lock_type);
thd->open_options&= ~extra_open_options;
packet->length(0);
- if (restore)
+ if (prepare_func)
{
- switch (prepare_for_restore(thd, table)) {
- case 1: continue; // error, message written to net
- case -1: goto err; // error, message could be written to net
- default: ;// should be 0 otherwise
- }
-
- // now we should be able to open the partially restored table
- // to finish the restore in the handler later on
- if (!(table->table = reopen_name_locked_table(thd, table)))
- {
- pthread_mutex_lock(&LOCK_open);
- unlock_table_name(thd, table);
- pthread_mutex_unlock(&LOCK_open);
+ switch ((*prepare_func)(thd, table, check_opt)) {
+ case 1: continue; // error, message written to net
+ case -1: goto err; // error, message could be written to net
+ default: ; // should be 0 otherwise
}
}
+
if (!table->table)
{
const char *err_msg;
@@ -970,6 +1275,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
sprintf(buff, ER(ER_OPEN_AS_READONLY), table_name);
net_store_data(packet, buff);
close_thread_tables(thd);
+ table->table=0; // For query cache
if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
packet->length()))
goto err;
@@ -1005,8 +1311,13 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
switch (result_code) {
case HA_ADMIN_NOT_IMPLEMENTED:
- net_store_data(packet, "error");
- net_store_data(packet, ER(ER_CHECK_NOT_IMPLEMENTED));
+ {
+ char buf[ERRMSGSIZE+20];
+ my_snprintf(buf, ERRMSGSIZE,
+ ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
+ net_store_data(packet, "error");
+ net_store_data(packet, buf);
+ }
break;
case HA_ADMIN_OK:
@@ -1049,8 +1360,11 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
remove_table_from_cache(thd, table->table->table_cache_key,
table->table->real_name);
pthread_mutex_unlock(&LOCK_open);
+ /* May be something modified consequently we have to invalidate cache */
+ query_cache_invalidate3(thd, table->table, 0);
}
close_thread_tables(thd);
+ table->table=0; // For query cache
if (my_net_write(&thd->net, (char*) packet->ptr(),
packet->length()))
goto err;
@@ -1060,9 +1374,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
DBUG_RETURN(0);
err:
close_thread_tables(thd); // Shouldn't be needed
+ if (table)
+ table->table=0;
DBUG_RETURN(-1);
}
+
int mysql_backup_table(THD* thd, TABLE_LIST* table_list)
{
DBUG_ENTER("mysql_backup_table");
@@ -1071,22 +1388,27 @@ int mysql_backup_table(THD* thd, TABLE_LIST* table_list)
&handler::backup));
}
+
int mysql_restore_table(THD* thd, TABLE_LIST* table_list)
{
DBUG_ENTER("mysql_restore_table");
DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
- "restore", TL_WRITE, 1, 1,0,
+ "restore", TL_WRITE, 1, 0,
+ &prepare_for_restore,
&handler::restore));
}
+
int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER("mysql_repair_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
- "repair", TL_WRITE, 1, 0, HA_OPEN_FOR_REPAIR,
+ "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR,
+ &prepare_for_repair,
&handler::repair));
}
+
int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER("mysql_optimize_table");
@@ -1122,7 +1444,7 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
DBUG_ENTER("mysql_check_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
"check", lock_type,
- 0, 0, HA_OPEN_FOR_REPAIR,
+ 0, HA_OPEN_FOR_REPAIR, 0,
&handler::check));
}
@@ -1135,25 +1457,32 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
List<Alter_column> &alter_list,
ORDER *order,
bool drop_primary,
- enum enum_duplicates handle_duplicates)
+ enum enum_duplicates handle_duplicates,
+ enum enum_enable_or_disable keys_onoff,
+ bool simple_alter)
{
TABLE *table,*new_table;
int error;
- char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN],
- *table_name,*db;
+ char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
+ char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
+ char index_file[FN_REFLEN], data_file[FN_REFLEN];
bool use_timestamp=0;
ha_rows copied,deleted;
ulonglong next_insert_id;
- uint save_time_stamp,db_create_options;
+ uint save_time_stamp,db_create_options, used_fields;
enum db_type old_db_type,new_db_type;
DBUG_ENTER("mysql_alter_table");
thd->proc_info="init";
table_name=table_list->real_name;
+ alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
+
db=table_list->db;
if (!new_db || !strcmp(new_db, db))
new_db=db;
-
+ used_fields=create_info->used_fields;
+
+ mysql_ha_closeall(thd, table_list);
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
DBUG_RETURN(-1);
@@ -1162,7 +1491,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
strmov(new_name_buff,new_name);
if (lower_case_table_names)
+ {
+ if (lower_case_table_names != 2)
+ {
+ casedn_str(new_name_buff);
+ new_alias= new_name; // Create lower case table name
+ }
casedn_str(new_name);
+ }
if (new_db == db &&
(lower_case_table_names &&
!my_strcasecmp(new_name_buff,table_name) ||
@@ -1173,7 +1509,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
Source and destination table names are equal: make later check
easier.
*/
- new_name= table_name;
+ new_alias= new_name= table_name;
}
else
{
@@ -1181,7 +1517,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
if (find_temporary_table(thd,new_db,new_name_buff))
{
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff);
DBUG_RETURN(-1);
}
}
@@ -1191,66 +1527,82 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
F_OK))
{
/* Table will be closed in do_command() */
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias);
DBUG_RETURN(-1);
}
}
}
}
else
- new_name=table_name;
+ new_alias= new_name= table_name;
old_db_type=table->db_type;
if (create_info->db_type == DB_TYPE_DEFAULT)
create_info->db_type=old_db_type;
new_db_type=create_info->db_type= ha_checktype(create_info->db_type);
- if (create_info->row_type == ROW_TYPE_DEFAULT)
+ if (create_info->row_type == ROW_TYPE_NOT_USED)
create_info->row_type=table->row_type;
- /* Check if the user only wants to do a simple RENAME */
+ /* In some simple cases we need not to recreate the table */
thd->proc_info="setup";
- if (new_name != table_name &&
- !fields.elements && !keys.elements && ! drop_list.elements &&
- !alter_list.elements && !drop_primary &&
- new_db_type == old_db_type && create_info->max_rows == 0 &&
- create_info->auto_increment_value == 0 && !table->tmp_table)
+ if (simple_alter && !table->tmp_table)
{
- thd->proc_info="rename";
- VOID(pthread_mutex_lock(&LOCK_open));
- /* Then do a 'simple' rename of the table */
error=0;
- if (!access(new_name_buff,F_OK))
+ if (new_name != table_name || new_db != db)
{
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
- error= -1;
- }
- else
- {
- *fn_ext(new_name)=0;
- close_cached_table(thd,table);
- if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name))
- error= -1;
+ thd->proc_info="rename";
+ VOID(pthread_mutex_lock(&LOCK_open));
+ /* Then do a 'simple' rename of the table */
+ error=0;
+ if (!access(new_name_buff,F_OK))
+ {
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
+ error= -1;
+ }
+ else
+ {
+ *fn_ext(new_name)=0;
+ close_cached_table(thd, table);
+ if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias))
+ error= -1;
+ }
+ VOID(pthread_mutex_unlock(&LOCK_open));
}
- if (!error && (error=ha_commit_rename(thd)))
+ if (!error)
{
- my_error(ER_GET_ERRNO,MYF(0),error);
- error=1;
+ switch (keys_onoff) {
+ case LEAVE_AS_IS:
+ break;
+ case ENABLE:
+ VOID(pthread_mutex_lock(&LOCK_open));
+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ error= table->file->activate_all_index(thd);
+ /* COND_refresh will be signaled in close_thread_tables() */
+ break;
+ case DISABLE:
+ VOID(pthread_mutex_lock(&LOCK_open));
+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ table->file->deactivate_non_unique_index(HA_POS_ERROR);
+ /* COND_refresh will be signaled in close_thread_tables() */
+ break;
+ }
}
-
- VOID(pthread_cond_broadcast(&COND_refresh));
- VOID(pthread_mutex_unlock(&LOCK_open));
if (!error)
{
mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query);
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
send_ok(&thd->net);
}
-
+ table_list->table=0; // For query cache
+ query_cache_invalidate3(thd, table_list, 0);
DBUG_RETURN(error);
}
@@ -1280,7 +1632,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
/* Reset auto_increment value if it was dropped */
if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
- !(create_info->used_fields & HA_CREATE_USED_AUTO))
+ !(used_fields & HA_CREATE_USED_AUTO))
{
create_info->auto_increment_value=0;
create_info->used_fields|=HA_CREATE_USED_AUTO;
@@ -1305,8 +1657,11 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
def->field=field;
if (def->sql_type == FIELD_TYPE_TIMESTAMP)
use_timestamp=1;
- create_list.push_back(def);
- def_it.remove();
+ if (!def->after)
+ {
+ create_list.push_back(def);
+ def_it.remove();
+ }
}
else
{ // Use old field value
@@ -1337,7 +1692,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
List_iterator<create_field> find_it(create_list);
while ((def=def_it++)) // Add new columns
{
- if (def->change)
+ if (def->change && ! def->field)
{
my_error(ER_BAD_FIELD_ERROR,MYF(0),def->change,table_name);
DBUG_RETURN(-1);
@@ -1375,8 +1730,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
/*
- ** Collect all keys which isn't in drop list. Add only those
- ** for which some fields exists.
+ Collect all keys which isn't in drop list. Add only those
+ for which some fields exists.
*/
List_iterator<Key> key_it(keys);
@@ -1466,20 +1821,25 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
goto err;
}
+ db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
(void) sprintf(tmp_name,"%s-%lx_%lx", tmp_file_prefix, current_pid,
thd->thread_id);
create_info->db_type=new_db_type;
- if (!create_info->max_rows)
- create_info->max_rows=table->max_rows;
- if (!create_info->avg_row_length)
- create_info->avg_row_length=table->avg_row_length;
- table->file->update_create_info(create_info);
if (!create_info->comment)
create_info->comment=table->comment;
+
/* let new create options override the old ones */
- db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
- if (create_info->table_options &
- (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS))
+ if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
+ create_info->min_rows=table->min_rows;
+ if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
+ create_info->max_rows=table->max_rows;
+ if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
+ create_info->avg_row_length=table->avg_row_length;
+
+ table->file->update_create_info(create_info);
+ if ((create_info->table_options &
+ (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) ||
+ (used_fields & HA_CREATE_USED_PACK_KEYS))
db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
if (create_info->table_options &
(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM))
@@ -1493,6 +1853,53 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (table->tmp_table)
create_info->options|=HA_LEX_CREATE_TMP_TABLE;
+ /*
+ Handling of symlinked tables:
+ If no rename:
+ Create new data file and index file on the same disk as the
+ old data and index files.
+ Copy data.
+ Rename new data file over old data file and new index file over
+ old index file.
+ Symlinks are not changed.
+
+ If rename:
+ Create new data file and index file on the same disk as the
+ old data and index files. Create also symlinks to point at
+ the new tables.
+ Copy data.
+ At end, rename temporary tables and symlinks to temporary table
+ to final table name.
+ Remove old table and old symlinks
+
+ If rename is made to another database:
+ Create new tables in new database.
+ Copy data.
+ Remove old table and symlinks.
+ */
+
+ if (!strcmp(db, new_db)) // Ignore symlink if db changed
+ {
+ if (create_info->index_file_name)
+ {
+ /* Fix index_file_name to have 'tmp_name' as basename */
+ strmov(index_file, tmp_name);
+ create_info->index_file_name=fn_same(index_file,
+ create_info->index_file_name,
+ 1);
+ }
+ if (create_info->data_file_name)
+ {
+ /* Fix data_file_name to have 'tmp_name' as basename */
+ strmov(data_file, tmp_name);
+ create_info->data_file_name=fn_same(data_file,
+ create_info->data_file_name,
+ 1);
+ }
+ }
+ else
+ create_info->data_file_name=create_info->index_file_name=0;
+
if ((error=mysql_create_table(thd, new_db, tmp_name,
create_info,
create_list,key_list,1,1))) // no logging
@@ -1550,7 +1957,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
/* Remove link to old table and rename the new one */
close_temporary_table(thd,table->table_cache_key,table_name);
- if (rename_temporary_table(thd, new_table, new_db, new_name))
+ if (rename_temporary_table(thd, new_table, new_db, new_alias))
{ // Fatal error
close_temporary_table(thd,new_db,tmp_name);
my_free((gptr) new_table,MYF(0));
@@ -1559,7 +1966,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
mysql_update_log.write(thd, thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query);
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
goto end_temporary;
@@ -1583,7 +1991,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
thd->proc_info="rename result table";
sprintf(old_name,"%s2-%lx-%lx", tmp_file_prefix, current_pid,
thd->thread_id);
- if (new_name != table_name)
+ if (new_name != table_name || new_db != db)
{
if (!access(new_name_buff,F_OK))
{
@@ -1601,10 +2009,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
/*
Win32 and InnoDB can't drop a table that is in use, so we must
- close all the original table at before doing the rename
+ close the original table at before doing the rename
*/
table_name=thd->strdup(table_name); // must be saved
- if (close_cached_table(thd,table))
+ if (close_cached_table(thd, table))
{ // Aborted
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -1625,33 +2033,41 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
}
else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db,
- new_name))
+ new_alias))
{ // Try to get everything back
error=1;
- VOID(quick_rm_table(new_db_type,new_db,new_name));
+ VOID(quick_rm_table(new_db_type,new_db,new_alias));
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
- VOID(mysql_rename_table(old_db_type,db,old_name,db,table_name));
+ VOID(mysql_rename_table(old_db_type,db,old_name,db,alias));
}
if (error)
{
- // This shouldn't happen. We solve this the safe way by
- // closing the locked table.
- close_cached_table(thd,table);
+ /*
+ This shouldn't happen. We solve this the safe way by
+ closing the locked table.
+ */
+ if (table)
+ close_cached_table(thd,table);
VOID(pthread_mutex_unlock(&LOCK_open));
goto err;
}
if (thd->lock || new_name != table_name) // True if WIN32
{
- // Not table locking or alter table with rename
- // free locks and remove old table
- close_cached_table(thd,table);
+ /*
+ Not table locking or alter table with rename
+ free locks and remove old table
+ */
+ if (table)
+ close_cached_table(thd,table);
VOID(quick_rm_table(old_db_type,db,old_name));
}
else
{
- // Using LOCK TABLES without rename.
- // This code is never executed on WIN32!
- // Remove old renamed table, reopen table and get new locks
+ /*
+ Using LOCK TABLES without rename.
+ This code is never executed on WIN32!
+ Remove old renamed table, reopen table and get new locks
+ */
if (table)
{
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file
@@ -1662,7 +2078,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (close_data_tables(thd,db,table_name) ||
reopen_tables(thd,1,0))
{ // This shouldn't happen
- close_cached_table(thd,table); // Remove lock for table
+ if (table)
+ close_cached_table(thd,table); // Remove lock for table
VOID(pthread_mutex_unlock(&LOCK_open));
goto err;
}
@@ -1682,7 +2099,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
mysql_update_log.write(thd, thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query);
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
mysql_bin_log.write(&qinfo);
}
VOID(pthread_cond_broadcast(&COND_refresh));
@@ -1710,6 +2128,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
(void) berkeley_flush_logs();
}
#endif
+ table_list->table=0; // For query cache
+ query_cache_invalidate3(thd, table_list, 0);
end_temporary:
sprintf(tmp_name,ER(ER_INSERT_INFO),(ulong) (copied+deleted),
@@ -1719,7 +2139,6 @@ end_temporary:
DBUG_RETURN(0);
err:
- (void) ha_commit_rename(thd); // Just for safety
DBUG_RETURN(-1);
}
@@ -1778,8 +2197,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (setup_order(thd, &tables, fields, all_fields, order) ||
!(sortorder=make_unireg_sortorder(order, &length)) ||
- (from->found_records = filesort(&from, sortorder, length,
- (SQL_SELECT *) 0, 0L, HA_POS_ERROR,
+ (from->found_records = filesort(from, sortorder, length,
+ (SQL_SELECT *) 0, 0L, HA_POS_ERROR,
&examined_rows))
== HA_POS_ERROR)
goto err;
@@ -1829,7 +2248,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}
end_read_record(&info);
free_io_cache(from);
- delete [] copy;
+ delete [] copy; // This is never 0
uint tmp_error;
if ((tmp_error=to->file->extra(HA_EXTRA_NO_CACHE)))
{
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index c4c2855a63e..a217d40246f 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -21,6 +21,12 @@
#include "mysql_priv.h"
#include "sql_select.h"
#include <hash.h>
+#include <thr_alarm.h>
+#if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_H)
+#include <malloc.h>
+#elif defined(HAVE_MALLINFO) && defined(HAVE_SYS_MALLOC_H)
+#include <sys/malloc.h>
+#endif
/* Intern key cache variables */
extern "C" pthread_mutex_t THR_LOCK_keycache;
@@ -96,8 +102,7 @@ void print_cached_tables(void)
}
-void TEST_filesort(TABLE **table,SORT_FIELD *sortorder,uint s_length,
- ha_rows special)
+void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special)
{
char buff[256],buff2[256];
String str(buff,sizeof(buff)),out(buff2,sizeof(buff2));
@@ -131,7 +136,7 @@ void TEST_filesort(TABLE **table,SORT_FIELD *sortorder,uint s_length,
DBUG_LOCK_FILE;
VOID(fputs("\nInfo about FILESORT\n",DBUG_FILE));
if (special)
- fprintf(DBUG_FILE,"Records to sort: %ld\n",special);
+ fprintf(DBUG_FILE,"Records to sort: %lu\n",(ulong) special);
fprintf(DBUG_FILE,"Sortorder: %s\n",out.ptr());
DBUG_UNLOCK_FILE;
DBUG_VOID_RETURN;
@@ -193,6 +198,8 @@ void mysql_print_status(THD *thd)
printf("\nStatus information:\n\n");
my_getwd(current_dir, sizeof(current_dir),MYF(0));
printf("Current dir: %s\n", current_dir);
+ printf("Running threads: %d Stack size: %ld\n", thread_count,
+ (long) thread_stack);
if (thd)
thd->proc_info="locks";
thr_print_locks(); // Write some debug info
@@ -240,11 +247,51 @@ Open streams: %10lu\n",
(ulong) cached_tables(),
(ulong) my_file_opened,
(ulong) my_stream_opened);
+
+ ALARM_INFO alarm_info;
+#ifndef DONT_USE_THR_ALARM
+ thr_alarm_info(&alarm_info);
+ printf("\nAlarm status:\n\
+Active alarms: %u\n\
+Max used alarms: %u\n\
+Next alarm time: %lu\n",
+ alarm_info.active_alarms,
+ alarm_info.max_used_alarms,
+ alarm_info.next_alarm_time);
+#endif
fflush(stdout);
if (thd)
thd->proc_info="malloc";
my_checkmalloc();
TERMINATE(stdout); // Write malloc information
+
+#ifdef HAVE_MALLINFO
+ struct mallinfo info= mallinfo();
+ printf("\nMemory status:\n\
+Non-mmapped space allocated from system: %d\n\
+Number of free chunks: %d\n\
+Number of fastbin blocks: %d\n\
+Number of mmapped regions: %d\n\
+Space in mmapped regions: %d\n\
+Maximum total allocated space: %d\n\
+Space available in freed fastbin blocks: %d\n\
+Total allocated space: %d\n\
+Total free space: %d\n\
+Top-most, releasable space: %d\n\
+Estimated memory (with thread stack): %ld\n",
+ (int) info.arena ,
+ (int) info.ordblks,
+ (int) info.smblks,
+ (int) info.hblks,
+ (int) info.hblkhd,
+ (int) info.usmblks,
+ (int) info.fsmblks,
+ (int) info.uordblks,
+ (int) info.fordblks,
+ (int) info.keepcost,
+ (long) (thread_count * thread_stack + info.hblkhd + info.arena));
+#endif
+ puts("");
if (thd)
thd->proc_info=0;
}
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 82a5e5bc002..431f8a13d28 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -1,21 +1,19 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2000 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-
/* This implements 'user defined functions' */
/*
@@ -52,11 +50,11 @@ extern "C"
{
FreeLibrary((HMODULE)lib);
}
-
+
#elif !defined(OS2)
#include <dlfcn.h>
#endif
-
+
#include <stdarg.h>
#include <hash.h>
}
@@ -100,8 +98,8 @@ static void init_syms(udf_func *tmp)
}
}
-static byte* get_hash_key(const byte *buff,uint *length,
- my_bool not_used __attribute__((unused)))
+extern "C" byte* get_hash_key(const byte *buff,uint *length,
+ my_bool not_used __attribute__((unused)))
{
udf_func *udf=(udf_func*) buff;
*length=(uint) udf->name_length;
@@ -118,6 +116,7 @@ void udf_init()
udf_func *tmp;
TABLE_LIST tables;
READ_RECORD read_record_info;
+ TABLE *table;
int error;
DBUG_ENTER("ufd_init");
@@ -126,7 +125,7 @@ void udf_init()
pthread_mutex_init(&THR_LOCK_udf,MY_MUTEX_INIT_SLOW);
- init_sql_alloc(&mem, 1024,0);
+ init_sql_alloc(&mem, UDF_ALLOC_BLOCK_SIZE, 0);
THD *new_thd = new THD;
if (!new_thd ||
hash_init(&udf_hash,32,0,0,get_hash_key, NULL, HASH_CASE_INSENSITIVE))
@@ -134,30 +133,27 @@ void udf_init()
sql_print_error("Can't allocate memory for udf structures");
hash_free(&udf_hash);
free_root(&mem,MYF(0));
+ delete new_thd;
DBUG_VOID_RETURN;
}
initialized = 1;
- new_thd->mysys_var=my_thread_var;
- new_thd->version = refresh_version; //current_thd->version;
- new_thd->current_tablenr = 0;
- new_thd->open_tables = 0;
- new_thd->db = my_strdup("mysql", MYF(0));
+ new_thd->store_globals();
+ new_thd->db= my_strdup("mysql", MYF(0));
+ new_thd->db_length=5;
bzero((gptr) &tables,sizeof(tables));
tables.alias= tables.real_name= (char*) "func";
tables.lock_type = TL_READ;
tables.db=new_thd->db;
- if (open_tables(new_thd, &tables))
+ if (open_and_lock_tables(new_thd, &tables))
{
DBUG_PRINT("error",("Can't open udf table"));
- sql_print_error("Can't open mysql/func table");
- close_thread_tables(new_thd);
- delete new_thd;
- DBUG_VOID_RETURN;
+ sql_print_error("Can't open the mysql/func table. Please run the mysql_install_db script to create it.");
+ goto end;
}
- TABLE *table = tables.table;
+ table= tables.table;
init_read_record(&read_record_info, new_thd, table, NULL,1,0);
while (!(error = read_record_info.read_record(&read_record_info)))
{
@@ -181,9 +177,10 @@ void udf_init()
{
if (!(dl = dlopen(tmp->dl, RTLD_NOW)))
{
+ /* Print warning to log */
sql_print_error(ER(ER_CANT_OPEN_LIBRARY),
tmp->dl,errno,dlerror());
- del_udf(tmp);
+ /* Keep the udf in the hash so that we can remove it later */
continue;
}
new_dl=1;
@@ -202,6 +199,8 @@ void udf_init()
sql_print_error(ER(ER_GET_ERRNO), my_errno);
end_read_record(&read_record_info);
new_thd->version--; // Force close to free memory
+
+end:
close_thread_tables(new_thd);
delete new_thd;
/* Remember that we don't have a THD */
@@ -217,19 +216,25 @@ void udf_free()
for (uint idx=0 ; idx < udf_hash.records ; idx++)
{
udf_func *udf=(udf_func*) hash_element(&udf_hash,idx);
- if (udf->dl)
+ if (udf->dlhandle) // Not closed before
{
+ /* Mark all versions using the same handler as closed */
for (uint j=idx+1 ; j < udf_hash.records ; j++)
{
udf_func *tmp=(udf_func*) hash_element(&udf_hash,j);
- if (tmp->dl && !strcmp(udf->dl,tmp->dl))
- tmp->dl=0;
+ if (udf->dlhandle == tmp->dlhandle)
+ tmp->dlhandle=0; // Already closed
}
+ dlclose(udf->dlhandle);
}
- dlclose(udf->dlhandle);
}
hash_free(&udf_hash);
free_root(&mem,MYF(0));
+ if (initialized)
+ {
+ initialized= 0;
+ pthread_mutex_destroy(&THR_LOCK_udf);
+ }
DBUG_VOID_RETURN;
}
@@ -245,9 +250,9 @@ static void del_udf(udf_func *udf)
else
{
/*
- ** The functions is in use ; Rename the functions instead of removing it.
- ** The functions will be automaticly removed when the least threads
- ** doesn't use it anymore
+ The functions is in use ; Rename the functions instead of removing it.
+ The functions will be automaticly removed when the least threads
+ doesn't use it anymore
*/
char *name= udf->name;
uint name_length=udf->name_length;
@@ -265,6 +270,10 @@ void free_udf(udf_func *udf)
pthread_mutex_lock(&THR_LOCK_udf);
if (!--udf->usage_count)
{
+ /*
+ We come here when someone has deleted the udf function
+ while another thread still was using the udf
+ */
hash_delete(&udf_hash,(byte*) udf);
using_udf_functions=udf_hash.records != 0;
if (!find_udf_dl(udf->dl))
@@ -274,6 +283,7 @@ void free_udf(udf_func *udf)
DBUG_VOID_RETURN;
}
+
/* This is only called if using_udf_functions != 0 */
udf_func *find_udf(const char *name,uint length,bool mark_used)
@@ -283,20 +293,26 @@ udf_func *find_udf(const char *name,uint length,bool mark_used)
/* TODO: This should be changed to reader locks someday! */
pthread_mutex_lock(&THR_LOCK_udf);
- udf=(udf_func*) hash_search(&udf_hash,(byte*) name,
- length ? length : (uint) strlen(name));
- if (mark_used)
- udf->usage_count++;
+ if ((udf=(udf_func*) hash_search(&udf_hash,(byte*) name,
+ length ? length : (uint) strlen(name))))
+ {
+ if (!udf->dlhandle)
+ udf=0; // Could not be opened
+ else if (mark_used)
+ udf->usage_count++;
+ }
pthread_mutex_unlock(&THR_LOCK_udf);
DBUG_RETURN(udf);
}
+
static void *find_udf_dl(const char *dl)
{
DBUG_ENTER("find_udf_dl");
- /* because only the function name is hashed, we have to search trough
- ** all rows to find the dl.
+ /*
+ Because only the function name is hashed, we have to search trough
+ all rows to find the dl.
*/
for (uint idx=0 ; idx < udf_hash.records ; idx++)
{
@@ -313,7 +329,7 @@ static void *find_udf_dl(const char *dl)
static udf_func *add_udf(char *name, Item_result ret, char *dl,
Item_udftype type)
{
- if (!name || !dl)
+ if (!name || !dl || !(uint) type || (uint) type > (uint) UDFTYPE_AGGREGATE)
return 0;
udf_func *tmp= (udf_func*) alloc_root(&mem, sizeof(udf_func));
if (!tmp)
@@ -365,7 +381,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
}
pthread_mutex_lock(&THR_LOCK_udf);
- if (hash_search(&udf_hash,(byte*) udf->name, udf->name_length))
+ if ((hash_search(&udf_hash,(byte*) udf->name, udf->name_length)))
{
net_printf(&thd->net, ER_UDF_EXISTS, udf->name);
goto err;
@@ -391,8 +407,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
}
udf->name=strdup_root(&mem,udf->name);
udf->dl=strdup_root(&mem,udf->dl);
- if (!udf->name || !udf->dl ||
- !(u_d=add_udf(udf->name,udf->returns,udf->dl,udf->type)))
+ if (!(u_d=add_udf(udf->name,udf->returns,udf->dl,udf->type)))
{
send_error(&thd->net,0); // End of memory
goto err;
@@ -451,13 +466,18 @@ int mysql_drop_function(THD *thd,const char *udf_name)
DBUG_RETURN(1);
}
pthread_mutex_lock(&THR_LOCK_udf);
- if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name, (uint) strlen(udf_name))))
+ if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name,
+ (uint) strlen(udf_name))))
{
net_printf(&thd->net, ER_FUNCTION_NOT_DEFINED, udf_name);
goto err;
}
del_udf(udf);
- if (!find_udf_dl(udf->dl))
+ /*
+ Close the handle if this was function that was found during boot or
+ CREATE FUNCTION and it's not in use by any other udf function
+ */
+ if (udf->dlhandle && !find_udf_dl(udf->dl))
dlclose(udf->dlhandle);
bzero((char*) &tables,sizeof(tables));
@@ -483,10 +503,3 @@ int mysql_drop_function(THD *thd,const char *udf_name)
}
#endif /* HAVE_DLOPEN */
-
-/*
-** Local variables:
-** tab-width: 8
-** c-basic-offset: 2
-** End:
-*/
diff --git a/sql/sql_udf.h b/sql/sql_udf.h
index d0b20f0a734..1ee9c44ce48 100644
--- a/sql/sql_udf.h
+++ b/sql/sql_udf.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
new file mode 100644
index 00000000000..34acd79f18b
--- /dev/null
+++ b/sql/sql_union.cc
@@ -0,0 +1,326 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/*
+ UNION of select's
+ UNION's were introduced by Monty and Sinisa <sinisa@mysql.com>
+*/
+
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+
+
+int mysql_union(THD *thd, LEX *lex,select_result *result)
+{
+ SELECT_LEX *sl, *last_sl, *lex_sl;
+ ORDER *order;
+ List<Item> item_list;
+ TABLE *table;
+ int res;
+ ulonglong add_rows= 0;
+ ulong found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS;
+ ulong describe= lex->select_lex.options & SELECT_DESCRIBE;
+ TABLE_LIST result_table_list;
+ TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first;
+ TMP_TABLE_PARAM tmp_table_param;
+ select_union *union_result;
+ DBUG_ENTER("mysql_union");
+
+ /* Fix tables 'to-be-unioned-from' list to point at opened tables */
+ last_sl= &lex->select_lex;
+ for (sl= last_sl;
+ sl && sl->linkage != NOT_A_SELECT;
+ last_sl=sl, sl=sl->next)
+ {
+ for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
+ cursor;
+ cursor=cursor->next)
+ {
+ cursor->table= (my_reinterpret_cast(TABLE_LIST*) (cursor->table))->table;
+ }
+ }
+
+ /* last_sel now points at the last select where the ORDER BY is stored */
+ if (sl)
+ {
+ /*
+ The found SL is an extra SELECT_LEX argument that contains
+ the ORDER BY and LIMIT parameter for the whole UNION
+ */
+ lex_sl= sl;
+ order= (ORDER *) lex_sl->order_list.first;
+ // This is done to eliminate unnecessary slowing down of the first query
+ if (!order || !describe)
+ last_sl->next=0; // Remove this extra element
+ }
+ else if (!last_sl->braces)
+ {
+ lex_sl= last_sl; // ORDER BY is here
+ order= (ORDER *) lex_sl->order_list.first;
+ }
+ else
+ {
+ lex_sl=0;
+ order=0;
+ }
+
+ if (describe)
+ {
+ Item *item;
+ item_list.push_back(new Item_empty_string("table",NAME_LEN));
+ item_list.push_back(new Item_empty_string("type",10));
+ item_list.push_back(item=new Item_empty_string("possible_keys",
+ NAME_LEN*MAX_KEY));
+ item->maybe_null=1;
+ item_list.push_back(item=new Item_empty_string("key",NAME_LEN));
+ item->maybe_null=1;
+ item_list.push_back(item=new Item_int("key_len",0,3));
+ item->maybe_null=1;
+ item_list.push_back(item=new Item_empty_string("ref",
+ NAME_LEN*MAX_REF_PARTS));
+ item->maybe_null=1;
+ item_list.push_back(new Item_real("rows",0.0,0,10));
+ item_list.push_back(new Item_empty_string("Extra",255));
+ }
+ else
+ {
+ Item *item;
+ List_iterator<Item> it(lex->select_lex.item_list);
+ TABLE_LIST *first_table= (TABLE_LIST*) lex->select_lex.table_list.first;
+
+ /* Create a list of items that will be in the result set */
+ while ((item= it++))
+ if (item_list.push_back(item))
+ DBUG_RETURN(-1);
+ if (setup_tables(first_table) ||
+ setup_fields(thd,first_table,item_list,0,0,1))
+ DBUG_RETURN(-1);
+ }
+
+ bzero((char*) &tmp_table_param,sizeof(tmp_table_param));
+ tmp_table_param.field_count=item_list.elements;
+ if (!(table=create_tmp_table(thd, &tmp_table_param, item_list,
+ (ORDER*) 0, !describe & !lex->union_option,
+ 1, 0,
+ (lex->select_lex.options | thd->options |
+ TMP_TABLE_ALL_COLUMNS))))
+ DBUG_RETURN(-1);
+ table->file->extra(HA_EXTRA_WRITE_CACHE);
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ bzero((char*) &result_table_list,sizeof(result_table_list));
+ result_table_list.db= (char*) "";
+ result_table_list.real_name=result_table_list.alias= (char*) "union";
+ result_table_list.table=table;
+
+ if (!(union_result=new select_union(table)))
+ {
+ res= -1;
+ goto exit;
+ }
+ union_result->not_describe= !describe;
+ union_result->tmp_table_param=&tmp_table_param;
+ for (sl= &lex->select_lex; sl; sl=sl->next)
+ {
+ ha_rows records_at_start;
+ lex->select=sl;
+ /* Don't use offset for the last union if there is no braces */
+ if (sl != lex_sl)
+ {
+ thd->offset_limit= sl->offset_limit;
+ thd->select_limit=sl->select_limit+sl->offset_limit;
+ }
+ else
+ {
+ thd->offset_limit= 0;
+ /*
+ We can't use LIMIT at this stage if we are using ORDER BY for the
+ whole query
+ */
+ thd->select_limit= HA_POS_ERROR;
+ if (! sl->order_list.first)
+ thd->select_limit= sl->select_limit+sl->offset_limit;
+ }
+ if (thd->select_limit < sl->select_limit)
+ thd->select_limit= HA_POS_ERROR; // no limit
+
+ /*
+ When using braces, SQL_CALC_FOUND_ROWS affects the whole query.
+ We don't calculate found_rows() per union part
+ */
+ if (thd->select_limit == HA_POS_ERROR || sl->braces)
+ sl->options&= ~OPTION_FOUND_ROWS;
+ else
+ {
+ /*
+ We are doing an union without braces. In this case
+ SQL_CALC_FOUND_ROWS should be done on all sub parts
+ */
+ sl->options|= found_rows_for_union;
+ }
+
+ records_at_start= table->file->records;
+ res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ?
+ first_table : (TABLE_LIST*) sl->table_list.first,
+ sl->item_list,
+ sl->where,
+ (sl->braces) ? (ORDER *)sl->order_list.first :
+ (ORDER *) 0,
+ (ORDER*) sl->group_list.first,
+ sl->having,
+ (ORDER*) NULL,
+ sl->options | thd->options | SELECT_NO_UNLOCK |
+ describe,
+ union_result);
+ if (res)
+ goto exit;
+ /* Needed for the following test and for records_at_start in next loop */
+ table->file->info(HA_STATUS_VARIABLE);
+ if (found_rows_for_union & sl->options)
+ {
+ /*
+ This is a union without braces. Remember the number of rows that could
+ also have been part of the result set.
+ We get this from the difference of between total number of possible
+ rows and actual rows added to the temporary table.
+ */
+ add_rows+= (ulonglong) (thd->limit_found_rows - (table->file->records -
+ records_at_start));
+ }
+ }
+ if (union_result->flush())
+ {
+ res= 1; // Error is already sent
+ goto exit;
+ }
+ delete union_result;
+
+ /* Send result to 'result' */
+ lex->select = &lex->select_lex;
+ res =-1;
+ {
+ /* Create a list of fields in the temporary table */
+ List_iterator<Item> it(item_list);
+ Field **field;
+ thd->lex.select_lex.ftfunc_list.empty();
+
+ for (field=table->field ; *field ; field++)
+ {
+ (void) it++;
+ (void) it.replace(new Item_field(*field));
+ }
+ if (!thd->fatal_error) // Check if EOM
+ {
+ if (lex_sl)
+ {
+ thd->offset_limit=lex_sl->offset_limit;
+ thd->select_limit=lex_sl->select_limit+lex_sl->offset_limit;
+ if (thd->select_limit < lex_sl->select_limit)
+ thd->select_limit= HA_POS_ERROR; // no limit
+ if (thd->select_limit == HA_POS_ERROR)
+ thd->options&= ~OPTION_FOUND_ROWS;
+ }
+ else
+ {
+ thd->offset_limit= 0;
+ thd->select_limit= thd->variables.select_limit;
+ if (found_rows_for_union && !describe)
+ thd->options|= OPTION_FOUND_ROWS;
+ }
+ if (describe)
+ thd->select_limit= HA_POS_ERROR; // no limit
+
+ res=mysql_select(thd,&result_table_list,
+ item_list, NULL, (describe) ? 0 : order,
+ (ORDER*) NULL, NULL, (ORDER*) NULL,
+ thd->options, result);
+ if (!res)
+ thd->limit_found_rows = (ulonglong)table->file->records + add_rows;
+ }
+ }
+
+exit:
+ free_tmp_table(thd,table);
+ DBUG_RETURN(res);
+}
+
+
+/***************************************************************************
+** store records in temporary table for UNION
+***************************************************************************/
+
+select_union::select_union(TABLE *table_par)
+ :table(table_par), not_describe(0)
+{
+ bzero((char*) &info,sizeof(info));
+ /*
+ We can always use DUP_IGNORE because the temporary table will only
+ contain a unique key if we are using not using UNION ALL
+ */
+ info.handle_duplicates=DUP_IGNORE;
+}
+
+select_union::~select_union()
+{
+}
+
+
+int select_union::prepare(List<Item> &list)
+{
+ if (not_describe && list.elements != table->fields)
+ {
+ my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
+ ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
+ return -1;
+ }
+ return 0;
+}
+
+bool select_union::send_data(List<Item> &values)
+{
+ if (thd->offset_limit)
+ { // using limit offset,count
+ thd->offset_limit--;
+ return 0;
+ }
+
+ fill_record(table->field, values, 1);
+ if ((write_record(table,&info)))
+ {
+ if (create_myisam_from_heap(thd, table, tmp_table_param, info.last_errno,
+ 1))
+ return 1;
+ }
+ return 0;
+}
+
+bool select_union::send_eof()
+{
+ return 0;
+}
+
+bool select_union::flush()
+{
+ int error;
+ if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
+ {
+ table->file->print_error(error,MYF(0));
+ ::send_error(&thd->net);
+ return 1;
+ }
+ return 0;
+}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 6a4cdb80e5d..d2ccd02051b 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1,24 +1,30 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Update of records */
+/*
+ Single table and multi table updates of tables.
+ Multi-table updates were introduced by Sinisa & Monty
+*/
#include "mysql_priv.h"
#include "sql_acl.h"
+#include "sql_select.h"
+
+static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields);
/* Return 0 if row hasn't changed */
@@ -26,10 +32,12 @@ static bool compare_record(TABLE *table, ulong query_id)
{
if (!table->blob_fields)
return cmp_record(table,1);
+ /* Compare null bits */
if (memcmp(table->null_flags,
table->null_flags+table->rec_buff_length,
table->null_bytes))
return 1; // Diff in NULL value
+ /* Compare updated fields */
for (Field **ptr=table->field ; *ptr ; ptr++)
{
if ((*ptr)->query_id == query_id &&
@@ -40,28 +48,35 @@ static bool compare_record(TABLE *table, ulong query_id)
}
-int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
- List<Item> &values, COND *conds,
+int mysql_update(THD *thd,
+ TABLE_LIST *table_list,
+ List<Item> &fields,
+ List<Item> &values,
+ COND *conds,
+ ORDER *order,
ha_rows limit,
- enum enum_duplicates handle_duplicates,
- thr_lock_type lock_type)
+ enum enum_duplicates handle_duplicates)
{
bool using_limit=limit != HA_POS_ERROR;
- bool used_key_is_modified, using_transactions;
+ bool safe_update= thd->options & OPTION_SAFE_UPDATES;
+ bool used_key_is_modified, transactional_table, log_delayed;
int error=0;
- uint save_time_stamp, used_index, want_privilege;
+ uint used_index, want_privilege;
ulong query_id=thd->query_id, timestamp_query_id;
+ ha_rows updated, found;
key_map old_used_keys;
TABLE *table;
SQL_SELECT *select;
READ_RECORD info;
+ TABLE_LIST tables;
+ List<Item> all_fields;
DBUG_ENTER("mysql_update");
+
LINT_INIT(used_index);
LINT_INIT(timestamp_query_id);
- if (!(table = open_ltable(thd,table_list,lock_type)))
+ if (!(table = open_ltable(thd,table_list,table_list->lock_type)))
DBUG_RETURN(-1); /* purecov: inspected */
- save_time_stamp=table->time_stamp;
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
thd->proc_info="init";
@@ -70,8 +85,14 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
table->quick_keys=0;
want_privilege=table->grant.want_privilege;
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
- if (setup_tables(table_list) || setup_conds(thd,table_list,&conds)
- || setup_ftfuncs(thd))
+
+ bzero((char*) &tables,sizeof(tables)); // For ORDER BY
+ tables.table= table;
+ tables.alias= table_list->alias;
+
+ if (setup_tables(table_list) || setup_conds(thd,table_list,&conds) ||
+ setup_order(thd, &tables, all_fields, all_fields, order) ||
+ setup_ftfuncs(thd))
DBUG_RETURN(-1); /* purecov: inspected */
old_used_keys=table->used_keys; // Keys used in WHERE
@@ -83,11 +104,12 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
{
timestamp_query_id=table->timestamp_field->query_id;
table->timestamp_field->query_id=thd->query_id-1;
+ table->time_stamp= table->timestamp_field->offset() +1;
}
/* Check the fields we are going to modify */
table->grant.want_privilege=want_privilege;
- if (setup_fields(thd,table_list,fields,1,0))
+ if (setup_fields(thd,table_list,fields,1,0,0))
DBUG_RETURN(-1); /* purecov: inspected */
if (table->timestamp_field)
{
@@ -100,9 +122,8 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
/* Check values */
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
- if (setup_fields(thd,table_list,values,0,0))
+ if (setup_fields(thd,table_list,values,0,0,0))
{
- table->time_stamp=save_time_stamp; // Restore timestamp pointer
DBUG_RETURN(-1); /* purecov: inspected */
}
@@ -110,12 +131,9 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
table->used_keys=0;
select=make_select(table,0,0,conds,&error);
if (error ||
- (select && select->check_quick(test(thd->options & OPTION_SAFE_UPDATES),
- limit)) ||
- !limit)
+ (select && select->check_quick(thd, safe_update, limit)) || !limit)
{
delete select;
- table->time_stamp=save_time_stamp; // Restore timestamp pointer
if (error)
{
DBUG_RETURN(-1); // Error in where
@@ -126,11 +144,10 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
/* If running in safe sql mode, don't allow updates without keys */
if (!table->quick_keys)
{
- thd->lex.options|=QUERY_NO_INDEX_USED;
- if ((thd->options & OPTION_SAFE_UPDATES) && limit == HA_POS_ERROR)
+ thd->lex.select_lex.options|=QUERY_NO_INDEX_USED;
+ if (safe_update && !using_limit)
{
delete select;
- table->time_stamp=save_time_stamp;
send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
DBUG_RETURN(1);
}
@@ -146,90 +163,118 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
used_key_is_modified=check_if_key_used(table, used_index, fields);
else
used_key_is_modified=0;
- if (used_key_is_modified)
+ if (used_key_is_modified || order)
{
/*
- ** We can't update table directly; We must first search after all
- ** matching rows before updating the table!
+ We can't update table directly; We must first search after all
+ matching rows before updating the table!
*/
table->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE);
- IO_CACHE tempfile;
- if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
- DISK_BUFFER_SIZE, MYF(MY_WME)))
- {
- delete select; /* purecov: inspected */
- table->time_stamp=save_time_stamp; // Restore timestamp pointer /* purecov: inspected */
- DBUG_RETURN(-1);
- }
if (old_used_keys & ((key_map) 1 << used_index))
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
- init_read_record(&info,thd,table,select,0,1);
- thd->proc_info="searching";
- while (!(error=info.read_record(&info)) && !thd->killed)
+ if (order)
{
- if (!(select && select->skipp_record()))
+ /*
+ Doing an ORDER BY; Let filesort find and sort the rows we are going
+ to update
+ */
+ uint length;
+ SORT_FIELD *sortorder;
+ ha_rows examined_rows;
+
+ table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
+ MYF(MY_FAE | MY_ZEROFILL));
+ if (!(sortorder=make_unireg_sortorder(order, &length)) ||
+ (table->found_records = filesort(table, sortorder, length,
+ select, 0L,
+ limit, &examined_rows)) ==
+ HA_POS_ERROR)
+ {
+ free_io_cache(table);
+ goto err;
+ }
+ /*
+ Filesort has already found and selected the rows we want to update,
+ so we don't need the where clause
+ */
+ delete select;
+ select= 0;
+ }
+ else
+ {
+ /*
+ We are doing a search on a key that is updated. In this case
+ we go trough the matching rows, save a pointer to them and
+ update these in a separate loop based on the pointer.
+ */
+
+ IO_CACHE tempfile;
+ if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
+ DISK_BUFFER_SIZE, MYF(MY_WME)))
+ goto err;
+
+ init_read_record(&info,thd,table,select,0,1);
+ thd->proc_info="Searching rows for update";
+ uint tmp_limit= limit;
+ while (!(error=info.read_record(&info)) && !thd->killed)
{
- table->file->position(table->record[0]);
- if (my_b_write(&tempfile,table->file->ref,
- table->file->ref_length))
+ if (!(select && select->skipp_record()))
{
- error=1; /* purecov: inspected */
- break; /* purecov: inspected */
+ table->file->position(table->record[0]);
+ if (my_b_write(&tempfile,table->file->ref,
+ table->file->ref_length))
+ {
+ error=1; /* purecov: inspected */
+ break; /* purecov: inspected */
+ }
+ if (!--limit && using_limit)
+ {
+ error= -1;
+ break;
+ }
}
}
+ limit= tmp_limit;
+ end_read_record(&info);
+ /* Change select to use tempfile */
+ if (select)
+ {
+ delete select->quick;
+ if (select->free_cond)
+ delete select->cond;
+ select->quick=0;
+ select->cond=0;
+ }
else
{
- if (!(test_flags & 512)) /* For debugging */
- {
- DBUG_DUMP("record",(char*) table->record[0],table->reclength);
- }
+ select= new SQL_SELECT;
+ select->head=table;
}
+ if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
+ error=1; /* purecov: inspected */
+ select->file=tempfile; // Read row ptrs from this file
+ if (error >= 0)
+ goto err;
}
- end_read_record(&info);
if (table->key_read)
{
table->key_read=0;
table->file->extra(HA_EXTRA_NO_KEYREAD);
}
- /* Change select to use tempfile */
- if (select)
- {
- delete select->quick;
- if (select->free_cond)
- delete select->cond;
- select->quick=0;
- select->cond=0;
- }
- else
- {
- select= new SQL_SELECT;
- select->head=table;
- }
- if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
- error=1; /* purecov: inspected */
- select->file=tempfile; // Read row ptrs from this file
- if (error >= 0)
- {
- delete select;
- table->time_stamp=save_time_stamp; // Restore timestamp pointer
- DBUG_RETURN(-1);
- }
}
- if (!(test_flags & TEST_READCHECK)) /* For debugging */
- VOID(table->file->extra(HA_EXTRA_NO_READCHECK));
if (handle_duplicates == DUP_IGNORE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
init_read_record(&info,thd,table,select,0,1);
- ha_rows updated=0L,found=0L;
+ updated= found= 0;
thd->count_cuted_fields=1; /* calc cuted fields */
thd->cuted_fields=0L;
- thd->proc_info="updating";
+ thd->proc_info="Updating";
query_id=thd->query_id;
while (!(error=info.read_record(&info)) && !thd->killed)
@@ -237,7 +282,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
if (!(select && select->skipp_record()))
{
store_record(table,1);
- if (fill_record(fields,values))
+ if (fill_record(fields, values, 0))
break; /* purecov: inspected */
found++;
if (compare_record(table, query_id))
@@ -246,11 +291,6 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
(byte*) table->record[0])))
{
updated++;
- if (!--limit && using_limit)
- {
- error= -1;
- break;
- }
}
else if (handle_duplicates != DUP_IGNORE ||
error != HA_ERR_FOUND_DUPP_KEY)
@@ -260,35 +300,56 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
break;
}
}
+ if (!--limit && using_limit)
+ {
+ error= -1; // Simulate end of file
+ break;
+ }
}
else
table->file->unlock_row();
}
end_read_record(&info);
+ free_io_cache(table); // If ORDER BY
thd->proc_info="end";
- VOID(table->file->extra(HA_EXTRA_READCHECK));
VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
- table->time_stamp=save_time_stamp; // Restore auto timestamp pointer
- using_transactions=table->file->has_transactions();
- if (updated && (error <= 0 || !using_transactions))
+ transactional_table= table->file->has_transactions();
+ log_delayed= (transactional_table || table->tmp_table);
+ if (updated && (error <= 0 || !transactional_table))
{
mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, using_transactions);
- if (mysql_bin_log.write(&qinfo) && using_transactions)
- error=1;
+ if (error <= 0)
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ log_delayed);
+ if (mysql_bin_log.write(&qinfo) && transactional_table)
+ error=1; // Rollback update
}
- if (!using_transactions)
+ if (!log_delayed)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (using_transactions && ha_autocommit_or_rollback(thd, error >= 0))
- error=1;
+ if (transactional_table)
+ {
+ if (ha_autocommit_or_rollback(thd, error >= 0))
+ error=1;
+ }
+
+ /*
+ Store table for future invalidation or invalidate it in
+ the query cache if something changed
+ */
+ if (updated)
+ {
+ query_cache_invalidate3(thd, table_list, 1);
+ }
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
+
delete select;
if (error >= 0)
send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */
@@ -303,5 +364,655 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List<Item> &fields,
DBUG_PRINT("info",("%d records updated",updated));
}
thd->count_cuted_fields=0; /* calc cuted fields */
+ free_io_cache(table);
DBUG_RETURN(0);
+
+err:
+ delete select;
+ if (table->key_read)
+ {
+ table->key_read=0;
+ table->file->extra(HA_EXTRA_NO_KEYREAD);
+ }
+ DBUG_RETURN(-1);
+}
+
+
+/***************************************************************************
+ Update multiple tables from join
+***************************************************************************/
+
+/*
+ Setup multi-update handling and call SELECT to do the join
+*/
+
+int mysql_multi_update(THD *thd,
+ TABLE_LIST *table_list,
+ List<Item> *fields,
+ List<Item> *values,
+ COND *conds,
+ ulong options,
+ enum enum_duplicates handle_duplicates)
+{
+ int res;
+ multi_update *result;
+ TABLE_LIST *tl;
+ DBUG_ENTER("mysql_multi_update");
+
+ if ((res=open_and_lock_tables(thd,table_list)))
+ DBUG_RETURN(res);
+
+ thd->select_limit=HA_POS_ERROR;
+
+ /*
+ Ensure that we have update privilege for all tables and columns in the
+ SET part
+ */
+ for (tl= table_list ; tl ; tl=tl->next)
+ {
+ TABLE *table= tl->table;
+ table->grant.want_privilege= (UPDATE_ACL & ~table->grant.privilege);
+ }
+
+ if (setup_fields(thd, table_list, *fields, 1, 0, 0))
+ DBUG_RETURN(-1);
+
+ /*
+ Count tables and setup timestamp handling
+ */
+ for (tl= table_list ; tl ; tl=tl->next)
+ {
+ TABLE *table= tl->table;
+
+ /* We only need SELECT privilege for columns in the values list */
+ table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege);
+ if (table->timestamp_field)
+ {
+ table->time_stamp=0;
+ // Only set timestamp column if this is not modified
+ if (table->timestamp_field->query_id != thd->query_id)
+ table->time_stamp= table->timestamp_field->offset() +1;
+ }
+ }
+
+ if (!(result=new multi_update(thd, table_list, fields, values,
+ handle_duplicates)))
+ DBUG_RETURN(-1);
+
+ List<Item> total_list;
+ res= mysql_select(thd,table_list,total_list,
+ conds, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
+ (ORDER *)NULL,
+ options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK,
+ result);
+ delete result;
+ DBUG_RETURN(res);
+}
+
+
+multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list,
+ List<Item> *field_list, List<Item> *value_list,
+ enum enum_duplicates handle_duplicates_arg)
+ :all_tables(table_list), update_tables(0), thd(thd_arg), tmp_tables(0),
+ updated(0), found(0), fields(field_list), values(value_list),
+ table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg),
+ do_update(1), trans_safe(0), transactional_tables(1)
+{}
+
+
+/*
+ Connect fields with tables and create list of tables that are updated
+*/
+
+int multi_update::prepare(List<Item> &not_used_values)
+{
+ TABLE_LIST *table_ref;
+ SQL_LIST update;
+ table_map tables_to_update= 0;
+ Item_field *item;
+ List_iterator_fast<Item> field_it(*fields);
+ List_iterator_fast<Item> value_it(*values);
+ uint i, max_fields;
+ DBUG_ENTER("multi_update::prepare");
+
+ thd->count_cuted_fields=1;
+ thd->cuted_fields=0L;
+ thd->proc_info="updating main table";
+
+ while ((item= (Item_field *) field_it++))
+ tables_to_update|= item->used_tables();
+
+ if (!tables_to_update)
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0),
+ "You didn't specify any tables to UPDATE");
+ DBUG_RETURN(1);
+ }
+
+ /*
+ We have to check values after setup_tables to get used_keys right in
+ reference tables
+ */
+
+ if (setup_fields(thd, all_tables, *values, 1,0,0))
+ DBUG_RETURN(1);
+
+ /*
+ Save tables beeing updated in update_tables
+ update_table->shared is position for table
+ Don't use key read on tables that are updated
+ */
+
+ update.empty();
+ for (table_ref= all_tables; table_ref; table_ref=table_ref->next)
+ {
+ TABLE *table=table_ref->table;
+ if (tables_to_update & table->map)
+ {
+ TABLE_LIST *tl= (TABLE_LIST*) thd->memdup((char*) table_ref,
+ sizeof(*tl));
+ if (!tl)
+ DBUG_RETURN(1);
+ update.link_in_list((byte*) tl, (byte**) &tl->next);
+ tl->shared= table_count++;
+ table->no_keyread=1;
+ table->used_keys=0;
+ table->pos_in_table_list= tl;
+ }
+ }
+
+
+ table_count= update.elements;
+ update_tables= (TABLE_LIST*) update.first;
+
+ tmp_tables = (TABLE **) thd->calloc(sizeof(TABLE *) * table_count);
+ tmp_table_param = (TMP_TABLE_PARAM*) thd->calloc(sizeof(TMP_TABLE_PARAM) *
+ table_count);
+ fields_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
+ table_count);
+ values_for_table= (List_item **) thd->alloc(sizeof(List_item *) *
+ table_count);
+ if (thd->fatal_error)
+ DBUG_RETURN(1);
+ for (i=0 ; i < table_count ; i++)
+ {
+ fields_for_table[i]= new List_item;
+ values_for_table[i]= new List_item;
+ }
+ if (thd->fatal_error)
+ DBUG_RETURN(1);
+
+ /* Split fields into fields_for_table[] and values_by_table[] */
+
+ field_it.rewind();
+ while ((item= (Item_field *) field_it++))
+ {
+ Item *value= value_it++;
+ uint offset= item->field->table->pos_in_table_list->shared;
+ fields_for_table[offset]->push_back(item);
+ values_for_table[offset]->push_back(value);
+ }
+ if (thd->fatal_error)
+ DBUG_RETURN(1);
+
+ /* Allocate copy fields */
+ max_fields=0;
+ for (i=0 ; i < table_count ; i++)
+ set_if_bigger(max_fields, fields_for_table[i]->elements);
+ copy_field= new Copy_field[max_fields];
+
+ /*
+ Mark all copies of tables that are updates to ensure that
+ init_read_record() will not try to enable a cache on them
+
+ The problem is that for queries like
+
+ UPDATE t1, t1 AS t2 SET t1.b=t2.c WHERE t1.a=t2.a;
+
+ the row buffer may contain things that doesn't match what is on disk
+ which will cause an error when reading a row.
+ (This issue is mostly relevent for MyISAM tables)
+ */
+ for (table_ref= all_tables; table_ref; table_ref=table_ref->next)
+ {
+ TABLE *table=table_ref->table;
+ if (!(tables_to_update & table->map) &&
+ check_dup(table_ref->db, table_ref->real_name, update_tables))
+ table->no_cache= 1; // Disable row cache
+ }
+ DBUG_RETURN(thd->fatal_error != 0);
+}
+
+
+/*
+ Initialize table for multi table
+
+ IMPLEMENTATION
+ - Update first table in join on the fly, if possible
+ - Create temporary tables to store changed values for all other tables
+ that are updated (and main_table if the above doesn't hold).
+*/
+
+bool
+multi_update::initialize_tables(JOIN *join)
+{
+ TABLE_LIST *table_ref;
+ DBUG_ENTER("initialize_tables");
+
+ if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
+ DBUG_RETURN(1);
+ main_table=join->join_tab->table;
+ trans_safe= transactional_tables= main_table->file->has_transactions();
+ log_delayed= trans_safe || main_table->tmp_table != NO_TMP_TABLE;
+ table_to_update= 0;
+
+ /* Create a temporary table for keys to all tables, except main table */
+ for (table_ref= update_tables; table_ref; table_ref=table_ref->next)
+ {
+ TABLE *table=table_ref->table;
+ uint cnt= table_ref->shared;
+ Item_field *If;
+ List<Item> temp_fields= *fields_for_table[cnt];
+ ORDER group;
+
+ if (table == main_table) // First table in join
+ {
+ if (safe_update_on_fly(join->join_tab, &temp_fields))
+ {
+ table_to_update= main_table; // Update table on the fly
+ continue;
+ }
+ }
+
+ TMP_TABLE_PARAM *tmp_param= tmp_table_param+cnt;
+
+ /*
+ Create a temporary table to store all fields that are changed for this
+ table. The first field in the temporary table is a pointer to the
+ original row so that we can find and update it
+ */
+
+ /* ok to be on stack as this is not referenced outside of this func */
+ Field_string offset(table->file->ref_length, 0, "offset",
+ table, 1);
+ if (!(If=new Item_field(((Field *) &offset))))
+ DBUG_RETURN(1);
+ If->maybe_null=0;
+ if (temp_fields.push_front(If))
+ DBUG_RETURN(1);
+
+ /* Make an unique key over the first field to avoid duplicated updates */
+ bzero((char*) &group, sizeof(group));
+ group.asc= 1;
+ group.item= (Item**) temp_fields.head_ref();
+
+ tmp_param->quick_group=1;
+ tmp_param->field_count=temp_fields.elements;
+ tmp_param->group_parts=1;
+ tmp_param->group_length= table->file->ref_length;
+ if (!(tmp_tables[cnt]=create_tmp_table(thd,
+ tmp_param,
+ temp_fields,
+ (ORDER*) &group, 0, 0, 0,
+ TMP_TABLE_ALL_COLUMNS)))
+ DBUG_RETURN(1);
+ tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE);
+ }
+ DBUG_RETURN(0);
+}
+
+/*
+ Check if table is safe to update on fly
+
+ SYNOPSIS
+ safe_update_on_fly
+ join_tab How table is used in join
+ fields Fields that are updated
+
+ NOTES
+ We can update the first table in join on the fly if we know that
+ a row in this tabel will never be read twice. This is true under
+ the folloing conditions:
+
+ - We are doing a table scan and the data is in a separate file (MyISAM) or
+ if we don't update a clustered key.
+
+ - We are doing a range scan and we don't update the scan key or
+ the primary key for a clustered table handler.
+
+ WARNING
+ This code is a bit dependent of how make_join_readinfo() works.
+
+ RETURN
+ 0 Not safe to update
+ 1 Safe to update
+*/
+
+static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields)
+{
+ TABLE *table= join_tab->table;
+ switch (join_tab->type) {
+ case JT_SYSTEM:
+ case JT_CONST:
+ case JT_EQ_REF:
+ return 1; // At most one matching row
+ case JT_REF:
+ return !check_if_key_used(table, join_tab->ref.key, *fields);
+ case JT_ALL:
+ /* If range search on index */
+ if (join_tab->quick)
+ return !check_if_key_used(table, join_tab->quick->index,
+ *fields);
+ /* If scanning in clustered key */
+ if ((table->file->table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
+ table->primary_key < MAX_KEY)
+ return !check_if_key_used(table, table->primary_key, *fields);
+ return 1;
+ default:
+ break; // Avoid compler warning
+ }
+ return 0;
+}
+
+
+
+multi_update::~multi_update()
+{
+ TABLE_LIST *table;
+ for (table= update_tables ; table; table= table->next)
+ table->table->no_keyread= table->table->no_cache= 0;
+
+ if (tmp_tables)
+ {
+ for (uint cnt = 0; cnt < table_count; cnt++)
+ {
+ if (tmp_tables[cnt])
+ {
+ free_tmp_table(thd, tmp_tables[cnt]);
+ tmp_table_param[cnt].cleanup();
+ }
+ }
+ }
+ if (copy_field)
+ delete [] copy_field;
+ thd->count_cuted_fields=0; // Restore this setting
+ if (!trans_safe)
+ thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+}
+
+
+bool multi_update::send_data(List<Item> &not_used_values)
+{
+ TABLE_LIST *cur_table;
+ DBUG_ENTER("multi_update::send_data");
+
+ for (cur_table= update_tables; cur_table ; cur_table= cur_table->next)
+ {
+ TABLE *table= cur_table->table;
+ /*
+ Check if we are using outer join and we didn't find the row
+ or if we have already updated this row in the previous call to this
+ function.
+
+ The same row may be presented here several times in a join of type
+ UPDATE t1 FROM t1,t2 SET t1.a=t2.a
+
+ In this case we will do the update for the first found row combination.
+ The join algorithm guarantees that we will not find the a row in
+ t1 several times.
+ */
+ if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
+ continue;
+
+ uint offset= cur_table->shared;
+ table->file->position(table->record[0]);
+ if (table == table_to_update)
+ {
+ table->status|= STATUS_UPDATED;
+ store_record(table,1);
+ if (fill_record(*fields_for_table[offset], *values_for_table[offset],0 ))
+ DBUG_RETURN(1);
+ found++;
+ if (compare_record(table, thd->query_id))
+ {
+ int error;
+ if (!updated++)
+ {
+ /*
+ Inform the main table that we are going to update the table even
+ while we may be scanning it. This will flush the read cache
+ if it's used.
+ */
+ main_table->file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
+ }
+ if ((error=table->file->update_row(table->record[1],
+ table->record[0])))
+ {
+ table->file->print_error(error,MYF(0));
+ updated--;
+ DBUG_RETURN(1);
+ }
+ }
+ }
+ else
+ {
+ int error;
+ TABLE *tmp_table= tmp_tables[offset];
+ fill_record(tmp_table->field+1, *values_for_table[offset], 1);
+ found++;
+ /* Store pointer to row */
+ memcpy((char*) tmp_table->field[0]->ptr,
+ (char*) table->file->ref, table->file->ref_length);
+ /* Write row, ignoring duplicated updates to a row */
+ if ((error= tmp_table->file->write_row(tmp_table->record[0])) &&
+ (error != HA_ERR_FOUND_DUPP_KEY &&
+ error != HA_ERR_FOUND_DUPP_UNIQUE))
+ {
+ if (create_myisam_from_heap(thd, tmp_table, tmp_table_param + offset,
+ error, 1))
+ {
+ do_update=0;
+ DBUG_RETURN(1); // Not a table_is_full error
+ }
+ }
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
+void multi_update::send_error(uint errcode,const char *err)
+{
+ /* First send error what ever it is ... */
+ ::send_error(&thd->net,errcode,err);
+
+ /* If nothing updated return */
+ if (!updated)
+ return;
+
+ /* Something already updated so we have to invalidate cache */
+ query_cache_invalidate3(thd, update_tables, 1);
+
+ /*
+ If all tables that has been updated are trans safe then just do rollback.
+ If not attempt to do remaining updates.
+ */
+
+ if (trans_safe)
+ ha_rollback_stmt(thd);
+ else if (do_update && table_count > 1)
+ {
+ /* Add warning here */
+ VOID(do_updates(0));
+ }
+}
+
+
+int multi_update::do_updates(bool from_send_error)
+{
+ TABLE_LIST *cur_table;
+ int local_error;
+ ha_rows org_updated;
+ TABLE *table;
+ DBUG_ENTER("do_updates");
+
+
+ do_update= 0; // Don't retry this function
+ if (!found)
+ DBUG_RETURN(0);
+ for (cur_table= update_tables; cur_table ; cur_table= cur_table->next)
+ {
+ table = cur_table->table;
+ if (table == table_to_update)
+ continue; // Already updated
+
+ org_updated= updated;
+ byte *ref_pos;
+ TABLE *tmp_table= tmp_tables[cur_table->shared];
+ tmp_table->file->extra(HA_EXTRA_CACHE); // Change to read cache
+ table->file->extra(HA_EXTRA_NO_CACHE);
+
+ /*
+ Setup copy functions to copy fields from temporary table
+ */
+ List_iterator_fast<Item> field_it(*fields_for_table[cur_table->shared]);
+ Field **field= tmp_table->field+1; // Skip row pointer
+ Copy_field *copy_field_ptr= copy_field, *copy_field_end;
+ for ( ; *field ; field++)
+ {
+ Item_field *item= (Item_field* ) field_it++;
+ (copy_field_ptr++)->set(item->field, *field, 0);
+ }
+ copy_field_end=copy_field_ptr;
+
+ if ((local_error = tmp_table->file->rnd_init(1)))
+ goto err;
+
+ ref_pos= (byte*) tmp_table->field[0]->ptr;
+ for (;;)
+ {
+ if (thd->killed && trans_safe)
+ goto err;
+ if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
+ {
+ if (local_error == HA_ERR_END_OF_FILE)
+ break;
+ if (local_error == HA_ERR_RECORD_DELETED)
+ continue; // May happen on dup key
+ goto err;
+ }
+ if ((local_error= table->file->rnd_pos(table->record[0], ref_pos)))
+ goto err;
+ table->status|= STATUS_UPDATED;
+ store_record(table,1);
+
+ /* Copy data from temporary table to current table */
+ for (copy_field_ptr=copy_field;
+ copy_field_ptr != copy_field_end;
+ copy_field_ptr++)
+ (*copy_field_ptr->do_copy)(copy_field_ptr);
+
+ if (compare_record(table, thd->query_id))
+ {
+ if ((local_error=table->file->update_row(table->record[1],
+ table->record[0])))
+ {
+ if (local_error != HA_ERR_FOUND_DUPP_KEY ||
+ handle_duplicates != DUP_IGNORE)
+ goto err;
+ }
+ updated++;
+ if (table->tmp_table != NO_TMP_TABLE)
+ log_delayed= 1;
+ }
+ }
+
+ if (updated != org_updated)
+ {
+ if (table->tmp_table != NO_TMP_TABLE)
+ log_delayed= 1; // Tmp tables forces delay log
+ if (table->file->has_transactions())
+ log_delayed= transactional_tables= 1;
+ else
+ trans_safe= 0; // Can't do safe rollback
+ }
+ }
+ DBUG_RETURN(0);
+
+err:
+ if (!from_send_error)
+ table->file->print_error(local_error,MYF(0));
+
+ if (updated != org_updated)
+ {
+ if (table->tmp_table != NO_TMP_TABLE)
+ log_delayed= 1;
+ if (table->file->has_transactions())
+ log_delayed= transactional_tables= 1;
+ else
+ trans_safe= 0;
+ }
+ DBUG_RETURN(1);
+}
+
+
+/* out: 1 if error, 0 if success */
+
+bool multi_update::send_eof()
+{
+ char buff[80];
+ thd->proc_info="updating reference tables";
+
+ /* Does updates for the last n - 1 tables, returns 0 if ok */
+ int local_error = (table_count) ? do_updates(0) : 0;
+ thd->proc_info= "end";
+
+ /*
+ Write the SQL statement to the binlog if we updated
+ rows and we succeeded or if we updated some non
+ transacational tables
+ */
+
+ if (updated && (local_error <= 0 || !trans_safe))
+ {
+ mysql_update_log.write(thd,thd->query,thd->query_length);
+ if (mysql_bin_log.is_open())
+ {
+ if (local_error <= 0)
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ log_delayed);
+ if (mysql_bin_log.write(&qinfo) && trans_safe)
+ local_error= 1; // Rollback update
+ }
+ if (!log_delayed)
+ thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+ }
+
+ if (transactional_tables)
+ {
+ if (ha_autocommit_or_rollback(thd, local_error != 0))
+ local_error=1;
+ }
+
+ if (local_error > 0) // if the above log write did not fail ...
+ {
+ /* Safety: If we haven't got an error before (should not happen) */
+ my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update",
+ MYF(0));
+ ::send_error(&thd->net);
+ return 1;
+ }
+
+
+ sprintf(buff,ER(ER_UPDATE_INFO), (long) found, (long) updated,
+ (long) thd->cuted_fields);
+ if (updated)
+ {
+ query_cache_invalidate3(thd, update_tables, 1);
+ }
+ ::send_ok(&thd->net,
+ (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
+ thd->insert_id_used ? thd->insert_id() : 0L,buff);
+ return 0;
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d751dcd0927..991a5f500e6 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,11 +21,13 @@
#define YYINITDEPTH 100
#define YYMAXDEPTH 3200 /* Because of 64K stack */
#define Lex current_lex
+#define Select Lex->select
#include "mysql_priv.h"
-#include "slave.h"
+#include "slave.h"
#include "sql_acl.h"
#include "lex_symbol.h"
#include <myisam.h>
+#include <myisammrg.h>
extern void yyerror(const char*);
int yylex(void *yylval);
@@ -42,7 +44,7 @@ inline Item *or_or_concat(Item* A, Item* B)
%union {
int num;
ulong ulong_num;
- ulonglong ulonglong_num;
+ ulonglong ulonglong_number;
LEX_STRING lex_str;
LEX_STRING *lex_str_ptr;
LEX_SYMBOL symbol;
@@ -51,17 +53,21 @@ inline Item *or_or_concat(Item* A, Item* B)
Item *item;
List<Item> *item_list;
List<String> *string_list;
- Key::Keytype key_type;
- enum db_type db_type;
- enum row_type row_type;
- enum enum_tx_isolation tx_isolation;
String *string;
key_part_spec *key_part;
TABLE_LIST *table_list;
udf_func *udf;
- interval_type interval;
LEX_USER *lex_user;
+ sys_var *variable;
+ Key::Keytype key_type;
+ enum db_type db_type;
+ enum row_type row_type;
+ enum ha_rkey_function ha_rkey_mode;
+ enum enum_tx_isolation tx_isolation;
+ enum Item_cast cast_type;
enum Item_udftype udf_type;
+ thr_lock_type lock_type;
+ interval_type interval;
}
%{
@@ -72,6 +78,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token END_OF_INPUT
+%token CLOSE_SYM
+%token HANDLER_SYM
+%token LAST_SYM
+%token NEXT_SYM
+%token PREV_SYM
+
%token EQ
%token EQUAL_SYM
%token GE
@@ -84,46 +96,58 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SHIFT_RIGHT
%token SET_VAR
-%token AVG_SYM
-%token COUNT_SYM
-%token MAX_SYM
-%token MIN_SYM
-%token SUM_SYM
-%token STD_SYM
-
+%token ABORT_SYM
%token ADD
-%token ALTER
%token AFTER_SYM
-%token ANALYZE_SYM
-%token BEGIN_SYM
+%token ALTER
+%token ANALYZE_SYM
+%token AVG_SYM
+%token BEGIN_SYM
+%token BINLOG_SYM
%token CHANGE
-%token COMMENT_SYM
-%token COMMIT_SYM
+%token CLIENT_SYM
+%token COMMENT_SYM
+%token COMMIT_SYM
+%token COUNT_SYM
%token CREATE
%token CROSS
+%token CUBE_SYM
%token DELETE_SYM
%token DO_SYM
%token DROP
-%token INSERT
+%token EVENTS_SYM
+%token EXECUTE_SYM
%token FLUSH_SYM
-%token SELECT_SYM
-%token MASTER_SYM
-%token REPAIR
-%token RESET_SYM
-%token PURGE
-%token SLAVE
-%token START_SYM
-%token STOP_SYM
-%token TRUNCATE_SYM
-%token ROLLBACK_SYM
-%token OPTIMIZE
-%token SHOW
-%token UPDATE_SYM
+%token INSERT
+%token IO_THREAD
%token KILL_SYM
%token LOAD
-%token LOCK_SYM
%token LOCKS_SYM
+%token LOCK_SYM
+%token MASTER_SYM
+%token MAX_SYM
+%token MIN_SYM
+%token NONE_SYM
+%token OPTIMIZE
+%token PURGE
+%token REPAIR
+%token REPLICATION
+%token RESET_SYM
+%token ROLLBACK_SYM
+%token ROLLUP_SYM
+%token SAVEPOINT_SYM
+%token SELECT_SYM
+%token SHOW
+%token SLAVE
+%token SQL_THREAD
+%token START_SYM
+%token STD_SYM
+%token STOP_SYM
+%token SUM_SYM
+%token SUPER_SYM
+%token TRUNCATE_SYM
%token UNLOCK_SYM
+%token UPDATE_SYM
%token ACTION
%token AGGREGATE_SYM
@@ -132,16 +156,19 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token AS
%token ASC
%token AUTO_INC
-%token AUTOCOMMIT
%token AVG_ROW_LENGTH
-%token BACKUP_SYM
+%token BACKUP_SYM
%token BERKELEY_DB_SYM
%token BINARY
%token BIT_SYM
%token BOOL_SYM
+%token BOOLEAN_SYM
%token BOTH
%token BY
+%token CACHE_SYM
%token CASCADE
+%token CAST_SYM
+%token CHARSET
%token CHECKSUM_SYM
%token CHECK_SYM
%token COMMITTED_SYM
@@ -149,6 +176,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token COLUMN_SYM
%token CONCURRENT
%token CONSTRAINT
+%token CONVERT_SYM
%token DATABASES
%token DATA_SYM
%token DEFAULT
@@ -156,10 +184,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DELAY_KEY_WRITE_SYM
%token DESC
%token DESCRIBE
+%token DES_KEY_FILE
+%token DISABLE_SYM
%token DISTINCT
%token DYNAMIC_SYM
+%token ENABLE_SYM
%token ENCLOSED
%token ESCAPED
+%token DIRECTORY_SYM
%token ESCAPE_SYM
%token EXISTS
%token EXTENDED_SYM
@@ -167,13 +199,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token FIRST_SYM
%token FIXED_SYM
%token FLOAT_NUM
+%token FORCE_SYM
%token FOREIGN
%token FROM
%token FULL
-%token FULLTEXT_SYM
-%token GEMINI_SYM
-%token GEMINI_SPIN_RETRIES
-%token GLOBAL_SYM
+%token FULLTEXT_SYM
+%token GLOBAL_SYM
%token GRANT
%token GRANTS
%token GREATEST_SYM
@@ -186,48 +217,58 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token IDENT
%token IGNORE_SYM
%token INDEX
+%token INDEXES
%token INFILE
%token INNER_SYM
%token INNOBASE_SYM
%token INTO
%token IN_SYM
-%token ISOLATION
+%token ISOLATION
%token ISAM_SYM
%token JOIN_SYM
%token KEYS
%token KEY_SYM
%token LEADING
%token LEAST_SYM
-%token LEVEL_SYM
+%token LEVEL_SYM
%token LEX_HOSTNAME
%token LIKE
%token LINES
%token LOCAL_SYM
+%token LOG_SYM
%token LOGS_SYM
%token LONG_NUM
%token LONG_SYM
%token LOW_PRIORITY
-%token MASTER_HOST_SYM
-%token MASTER_USER_SYM
-%token MASTER_LOG_FILE_SYM
-%token MASTER_LOG_POS_SYM
-%token MASTER_PASSWORD_SYM
-%token MASTER_PORT_SYM
-%token MASTER_CONNECT_RETRY_SYM
+%token MASTER_HOST_SYM
+%token MASTER_USER_SYM
+%token MASTER_LOG_FILE_SYM
+%token MASTER_LOG_POS_SYM
+%token MASTER_PASSWORD_SYM
+%token MASTER_PORT_SYM
+%token MASTER_CONNECT_RETRY_SYM
+%token MASTER_SERVER_ID_SYM
+%token RELAY_LOG_FILE_SYM
+%token RELAY_LOG_POS_SYM
%token MATCH
%token MAX_ROWS
+%token MAX_CONNECTIONS_PER_HOUR
+%token MAX_QUERIES_PER_HOUR
+%token MAX_UPDATES_PER_HOUR
%token MEDIUM_SYM
%token MERGE_SYM
+%token MEMORY_SYM
%token MIN_ROWS
%token MYISAM_SYM
%token NATIONAL_SYM
%token NATURAL
+%token NEW_SYM
%token NCHAR_SYM
%token NOT
-%token FOREIGN_KEY_CHECKS
%token NO_SYM
%token NULL_SYM
%token NUM
+%token OFFSET_SYM
%token ON
%token OPEN_SYM
%token OPTION
@@ -237,13 +278,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token ORDER_SYM
%token OUTER
%token OUTFILE
-%token DUMPFILE
+%token DUMPFILE
%token PACK_KEYS_SYM
%token PARTIAL
%token PRIMARY_SYM
%token PRIVILEGES
%token PROCESS
%token PROCESSLIST_SYM
+%token QUERY_SYM
%token RAID_0_SYM
%token RAID_STRIPED_SYM
%token RAID_TYPE
@@ -256,7 +298,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token RELOAD
%token RENAME
%token REPEATABLE_SYM
-%token RESTORE_SYM
+%token REQUIRE_SYM
+%token RESOURCES
+%token RESTORE_SYM
%token RESTRICT
%token REVOKE
%token ROWS_SYM
@@ -266,9 +310,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SERIALIZABLE_SYM
%token SESSION_SYM
%token SHUTDOWN
+%token SSL_SYM
%token STARTING
%token STATUS_SYM
%token STRAIGHT_JOIN
+%token SUBJECT_SYM
%token TABLES
%token TABLE_SYM
%token TEMPORARY
@@ -285,11 +331,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token UDF_RETURNS_SYM
%token UDF_SONAME_SYM
%token UDF_SYM
-%token UNCOMMITTED_SYM
+%token UNCOMMITTED_SYM
%token UNION_SYM
%token UNIQUE_SYM
-%token UNIQUE_CHECKS
%token USAGE
+%token USE_FRM
%token USE_SYM
%token USING
%token VALUES
@@ -297,12 +343,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token WHERE
%token WITH
%token WRITE_SYM
-%token COMPRESSED_SYM
+%token X509_SYM
+%token XOR
+%token COMPRESSED_SYM
%token BIGINT
%token BLOB_SYM
%token CHAR_SYM
-%token CHANGED
+%token CHANGED
%token COALESCE
%token DATETIME
%token DATE_SYM
@@ -320,8 +368,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MEDIUMTEXT
%token NUMERIC_SYM
%token PRECISION
-%token QUICK
+%token QUICK
%token REAL
+%token SIGNED_SYM
%token SMALLINT
%token STRING_SYM
%token TEXT_SYM
@@ -330,20 +379,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token TINYBLOB
%token TINYINT
%token TINYTEXT
+%token ULONGLONG_NUM
%token UNSIGNED
%token VARBINARY
%token VARCHAR
%token VARYING
%token ZEROFILL
-%token AGAINST
+%token AGAINST
%token ATAN
%token BETWEEN_SYM
%token BIT_AND
%token BIT_OR
%token CASE_SYM
%token CONCAT
-%token CONCAT_WS
+%token CONCAT_WS
%token CURDATE
%token CURTIME
%token DATABASE
@@ -354,6 +404,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DAY_SECOND_SYM
%token DAY_SYM
%token DECODE_SYM
+%token DES_ENCRYPT_SYM
+%token DES_DECRYPT_SYM
%token ELSE
%token ELT_FUNC
%token ENCODE_SYM
@@ -370,15 +422,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token HOUR_SYM
%token IDENTIFIED_SYM
%token IF
-%token INSERT_ID
+%token INSERT_METHOD
%token INTERVAL_SYM
%token LAST_INSERT_ID
%token LEFT
%token LOCATE
%token MAKE_SET_SYM
+%token MASTER_POS_WAIT
%token MINUTE_SECOND_SYM
%token MINUTE_SYM
-%token MODE_SYM
+%token MODE_SYM
%token MODIFY_SYM
%token MONTH_SYM
%token NOW_SYM
@@ -405,30 +458,24 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token USER
%token WEEK_SYM
%token WHEN_SYM
-%token WORK_SYM
+%token WORK_SYM
%token YEAR_MONTH_SYM
%token YEAR_SYM
%token YEARWEEK
-%token BENCHMARK_SYM
-%token END
-%token THEN_SYM
-
-%token SQL_BIG_TABLES
-%token SQL_BIG_SELECTS
-%token SQL_SELECT_LIMIT
-%token SQL_MAX_JOIN_SIZE
-%token SQL_LOG_BIN
-%token SQL_LOG_OFF
-%token SQL_LOG_UPDATE
-%token SQL_LOW_PRIORITY_UPDATES
-%token SQL_SMALL_RESULT
+%token BENCHMARK_SYM
+%token END
+%token THEN_SYM
+
%token SQL_BIG_RESULT
+%token SQL_CACHE_SYM
+%token SQL_CALC_FOUND_ROWS
+%token SQL_NO_CACHE_SYM
+%token SQL_SMALL_RESULT
%token SQL_BUFFER_RESULT
-%token SQL_WARNINGS
-%token SQL_AUTO_IS_NULL
-%token SQL_SAFE_UPDATES
-%token SQL_QUOTE_SHOW_CREATE
-%token SQL_SLAVE_SKIP_COUNTER
+
+%token ISSUER_SYM
+%token SUBJECT_SYM
+%token CIPHER_SYM
%left SET_VAR
%left OR_OR_CONCAT OR
@@ -441,45 +488,51 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%left '-' '+'
%left '*' '/' '%'
%left NEG '~'
+%left XOR
+%left '^'
%right NOT
%right BINARY
%type <lex_str>
IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME
- field_ident select_alias ident ident_or_text
+ ULONGLONG_NUM field_ident select_alias ident ident_or_text
%type <lex_str_ptr>
opt_table_alias
%type <table>
- table_ident
+ table_ident table_ident_ref
%type <simple_string>
remember_name remember_end opt_len opt_ident opt_db text_or_password
opt_escape
%type <string>
- text_string
+ text_string
%type <num>
- type int_type real_type order_dir opt_field_spec set_option lock_option
+ type int_type real_type order_dir opt_field_spec lock_option
udf_type if_exists opt_local opt_table_options table_options
- table_option opt_if_not_exists
+ table_option opt_if_not_exists opt_var_type opt_var_ident_type
+ opt_temporary
%type <ulong_num>
- ULONG_NUM raid_types
+ ULONG_NUM raid_types merge_insert_types
-%type <ulonglong_num>
- ULONGLONG_NUM
+%type <ulonglong_number>
+ ulonglong_num
+
+%type <lock_type>
+ replace_lock_option opt_low_priority insert_lock_option load_data_lock
%type <item>
literal text_literal insert_ident order_ident
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr
- using_list
+ using_list expr_or_default set_expr_or_default
%type <item_list>
- expr_list udf_expr_list when_list ident_list
+ expr_list udf_expr_list when_list ident_list ident_list_arg
%type <key_type>
key_type opt_unique_or_fulltext
@@ -503,7 +556,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <row_type> row_types
-%type <tx_isolation> tx_isolation isolation_types
+%type <tx_isolation> isolation_types
+
+%type <ha_rkey_mode> handler_rkey_mode
+
+%type <cast_type> cast_type
%type <udf_type> udf_func_type
@@ -511,31 +568,37 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <lex_user> user grant_user
+%type <variable> internal_variable_name
+
%type <NONE>
query verb_clause create change select do drop insert replace insert2
insert_values update delete truncate rename
show describe load alter optimize flush
- reset purge begin commit rollback slave master_def master_defs
- repair restore backup analyze check
- field_list field_list_item field_spec kill
+ reset purge begin commit rollback savepoint
+ slave master_def master_defs
+ repair restore backup analyze check start
+ field_list field_list_item field_spec kill column_def key_def
select_item_list select_item values_list no_braces
limit_clause delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item
- when_list2 expr_list2
+ when_list2 expr_list2 handler
opt_precision opt_ignore opt_column opt_restrict
grant revoke set lock unlock string_list field_options field_option
field_opt_list opt_binary table_lock_list table_lock varchar
references opt_on_delete opt_on_delete_list opt_on_delete_item use
opt_delete_options opt_delete_option
- opt_outer table_list table opt_option opt_place opt_low_priority
+ opt_outer table_list table_name opt_option opt_place
opt_attribute opt_attribute_list attribute column_list column_list_id
opt_column_list grant_privileges opt_table user_list grant_option
grant_privilege grant_privilege_list
- flush_options flush_option insert_lock_option replace_lock_option
+ flush_options flush_option
equal optional_braces opt_key_definition key_usage_list2
opt_mi_check_type opt_to mi_check_types normal_join
table_to_table_list table_to_table opt_table_list opt_as
- END_OF_INPUT
+ handler_rkey_function handler_read_or_scan
+ single_multi table_wild_list table_wild_one opt_wild opt_union union_list
+ precision union_option opt_and
+END_OF_INPUT
%type <NONE>
'-' '+' '*' '/' '%' '(' ')'
@@ -548,7 +611,7 @@ query:
{
THD *thd=current_thd;
if (!thd->bootstrap &&
- (!(thd->lex.options & OPTION_FOUND_COMMENT)))
+ (!(thd->lex.select_lex.options & OPTION_FOUND_COMMENT)))
{
send_error(&current_thd->net,ER_EMPTY_QUERY);
YYABORT;
@@ -558,8 +621,7 @@ query:
thd->lex.sql_command = SQLCOM_EMPTY_QUERY;
}
}
- | verb_clause END_OF_INPUT {}
- ;
+ | verb_clause END_OF_INPUT {};
verb_clause:
alter
@@ -589,15 +651,17 @@ verb_clause:
| restore
| revoke
| rollback
+ | savepoint
| select
| set
| slave
+ | start
| show
| truncate
+ | handler
| unlock
| update
- | use
- ;
+ | use;
/* change master */
@@ -606,16 +670,15 @@ change:
{
LEX *lex = Lex;
lex->sql_command = SQLCOM_CHANGE_MASTER;
- memset(&lex->mi, 0, sizeof(lex->mi));
- } master_defs
+ bzero((char*) &lex->mi, sizeof(lex->mi));
+ }
+ master_defs
{}
- ;
+ ;
master_defs:
- master_def
- |
- master_defs ',' master_def
- ;
+ master_def
+ | master_defs ',' master_def;
master_def:
MASTER_HOST_SYM EQ TEXT_STRING
@@ -643,16 +706,39 @@ master_def:
Lex->mi.port = $3;
}
|
- MASTER_LOG_POS_SYM EQ ULONGLONG_NUM
+ MASTER_LOG_POS_SYM EQ ulonglong_num
{
Lex->mi.pos = $3;
+ /*
+ If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it
+ instead of causing subsequent errors.
+ We need to do it in this file, because only there we know that
+ MASTER_LOG_POS has been explicitely specified. On the contrary
+ in change_master() (sql_repl.cc) we cannot distinguish between 0
+ (MASTER_LOG_POS explicitely specified as 0) and 0 (unspecified),
+ whereas we want to distinguish (specified 0 means "read the binlog
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+ Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
}
|
MASTER_CONNECT_RETRY_SYM EQ ULONG_NUM
{
Lex->mi.connect_retry = $3;
}
- ;
+ |
+ RELAY_LOG_FILE_SYM EQ TEXT_STRING
+ {
+ Lex->mi.relay_log_name = $3.str;
+ }
+ |
+ RELAY_LOG_POS_SYM EQ ULONG_NUM
+ {
+ Lex->mi.relay_log_pos = $3;
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+ Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ };
/* create a table */
@@ -664,7 +750,8 @@ create:
lex->sql_command= SQLCOM_CREATE_TABLE;
if (!add_table_to_list($5,
($2 & HA_LEX_CREATE_TMP_TABLE ?
- &tmp_table_alias : (LEX_STRING*) 0),1))
+ &tmp_table_alias : (LEX_STRING*) 0),
+ TL_OPTION_UPDATING))
YYABORT;
lex->create_list.empty();
lex->key_list.empty();
@@ -672,103 +759,119 @@ create:
lex->change=NullS;
bzero((char*) &lex->create_info,sizeof(lex->create_info));
lex->create_info.options=$2 | $4;
- lex->create_info.db_type= default_table_type;
+ lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type;
}
create2
- {}
+ {Lex->select= &Lex->select_lex;}
| CREATE opt_unique_or_fulltext INDEX ident ON table_ident
{
- Lex->sql_command= SQLCOM_CREATE_INDEX;
- if (!add_table_to_list($6,NULL,1))
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_CREATE_INDEX;
+ if (!add_table_to_list($6, NULL, TL_OPTION_UPDATING))
YYABORT;
- Lex->create_list.empty();
- Lex->key_list.empty();
- Lex->col_list.empty();
- Lex->change=NullS;
+ lex->create_list.empty();
+ lex->key_list.empty();
+ lex->col_list.empty();
+ lex->change=NullS;
}
'(' key_list ')'
{
- Lex->key_list.push_back(new Key($2,$4.str,Lex->col_list));
- Lex->col_list.empty();
+ LEX *lex=Lex;
+ lex->key_list.push_back(new Key($2,$4.str,lex->col_list));
+ lex->col_list.empty();
}
| CREATE DATABASE opt_if_not_exists ident
{
- Lex->sql_command=SQLCOM_CREATE_DB;
- Lex->name=$4.str;
- Lex->create_info.options=$3;
+ LEX *lex=Lex;
+ lex->sql_command=SQLCOM_CREATE_DB;
+ lex->name=$4.str;
+ lex->create_info.options=$3;
}
| CREATE udf_func_type UDF_SYM ident
{
- Lex->sql_command = SQLCOM_CREATE_FUNCTION;
- Lex->udf.name=$4.str;
- Lex->udf.name_length=$4.length;
- Lex->udf.type= $2;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_CREATE_FUNCTION;
+ lex->udf.name=$4.str;
+ lex->udf.name_length=$4.length;
+ lex->udf.type= $2;
}
UDF_RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING
{
- Lex->udf.returns=(Item_result) $7;
- Lex->udf.dl=$9.str;
- }
- ;
+ LEX *lex=Lex;
+ lex->udf.returns=(Item_result) $7;
+ lex->udf.dl=$9.str;
+ };
create2:
- '(' field_list ')' opt_create_table_options create3 {}
- | opt_create_table_options create3 {}
- ;
+ '(' create2a {}
+ | opt_create_table_options create3 {};
+
+create2a:
+ field_list ')' opt_create_table_options create3 {}
+ | create_select ')' { Select->braces= 1;} union_opt {}
+ ;
create3:
/* empty */ {}
- | opt_duplicate opt_as SELECT_SYM
+ | opt_duplicate opt_as create_select
+ { Select->braces= 0;} opt_union {}
+ | opt_duplicate opt_as '(' create_select ')'
+ { Select->braces= 1;} union_opt {}
+ ;
+
+create_select:
+ SELECT_SYM
{
- Lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
- mysql_init_select(Lex);
+ LEX *lex=Lex;
+ lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
+ if (lex->sql_command == SQLCOM_INSERT)
+ lex->sql_command= SQLCOM_INSERT_SELECT;
+ else if (lex->sql_command == SQLCOM_REPLACE)
+ lex->sql_command= SQLCOM_REPLACE_SELECT;
+ lex->select->table_list.save_and_clear(&lex->save_list);
+ mysql_init_select(lex);
}
- select_options select_item_list opt_select_from {}
- ;
+ select_options select_item_list opt_select_from
+ { Lex->select->table_list.push_front(&Lex->save_list); }
+ ;
opt_as:
/* empty */ {}
- | AS {}
- ;
+ | AS {};
opt_table_options:
/* empty */ { $$= 0; }
- | table_options { $$= $1;}
- ;
+ | table_options { $$= $1;};
table_options:
table_option { $$=$1; }
- | table_option table_options { $$= $1 | $2; }
- ;
+ | table_option table_options { $$= $1 | $2; };
table_option:
- TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; }
- ;
+ TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; };
opt_if_not_exists:
/* empty */ { $$= 0; }
- | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }
- ;
+ | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; };
opt_create_table_options:
/* empty */
- | create_table_options
- ;
+ | create_table_options;
create_table_options:
create_table_option
- | create_table_option create_table_options
- ;
+ | create_table_option create_table_options;
create_table_option:
TYPE_SYM EQ table_types { Lex->create_info.db_type= $3; }
- | MAX_ROWS EQ ULONGLONG_NUM { Lex->create_info.max_rows= $3; }
- | MIN_ROWS EQ ULONGLONG_NUM { Lex->create_info.min_rows= $3; }
- | AVG_ROW_LENGTH EQ ULONG_NUM { Lex->create_info.avg_row_length=$3; }
+ | MAX_ROWS EQ ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
+ | MIN_ROWS EQ ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
+ | AVG_ROW_LENGTH EQ ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
| PASSWORD EQ TEXT_STRING { Lex->create_info.password=$3.str; }
| COMMENT_SYM EQ TEXT_STRING { Lex->create_info.comment=$3.str; }
- | AUTO_INC EQ ULONGLONG_NUM { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
- | PACK_KEYS_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; }
+ | AUTO_INC EQ ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
+ | PACK_KEYS_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
+ | PACK_KEYS_SYM EQ DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
| CHECKSUM_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; }
| DELAY_KEY_WRITE_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; }
| ROW_FORMAT_SYM EQ row_types { Lex->create_info.row_type= $3; }
@@ -779,103 +882,120 @@ create_table_option:
{
/* Move the union list to the merge_list */
LEX *lex=Lex;
- TABLE_LIST *table_list= (TABLE_LIST*) lex->table_list.first;
- lex->create_info.merge_list= lex->table_list;
+ TABLE_LIST *table_list= (TABLE_LIST*) lex->select->table_list.first;
+ lex->create_info.merge_list= lex->select->table_list;
lex->create_info.merge_list.elements--;
lex->create_info.merge_list.first= (byte*) (table_list->next);
- lex->table_list.elements=1;
- lex->table_list.next= (byte**) &(table_list->next);
+ lex->select->table_list.elements=1;
+ lex->select->table_list.next= (byte**) &(table_list->next);
table_list->next=0;
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
}
- ;
+ | CHARSET opt_equal ident {}
+ | CHAR_SYM SET opt_equal ident {}
+ | INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
+ | DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; }
+ | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; };
table_types:
ISAM_SYM { $$= DB_TYPE_ISAM; }
| MYISAM_SYM { $$= DB_TYPE_MYISAM; }
| MERGE_SYM { $$= DB_TYPE_MRG_MYISAM; }
| HEAP_SYM { $$= DB_TYPE_HEAP; }
+ | MEMORY_SYM { $$= DB_TYPE_HEAP; }
| BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; }
- | INNOBASE_SYM { $$= DB_TYPE_INNOBASE; }
- | GEMINI_SYM { $$= DB_TYPE_GEMINI; }
- ;
+ | INNOBASE_SYM { $$= DB_TYPE_INNODB; };
row_types:
DEFAULT { $$= ROW_TYPE_DEFAULT; }
| FIXED_SYM { $$= ROW_TYPE_FIXED; }
| DYNAMIC_SYM { $$= ROW_TYPE_DYNAMIC; }
- | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }
- ;
+ | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; };
raid_types:
RAID_STRIPED_SYM { $$= RAID_TYPE_0; }
| RAID_0_SYM { $$= RAID_TYPE_0; }
- | ULONG_NUM { $$=$1;}
- ;
+ | ULONG_NUM { $$=$1;};
+
+merge_insert_types:
+ NO_SYM { $$= MERGE_INSERT_DISABLED; }
+ | FIRST_SYM { $$= MERGE_INSERT_TO_FIRST; }
+ | LAST_SYM { $$= MERGE_INSERT_TO_LAST; };
opt_select_from:
/* empty */
- | select_from select_lock_type
- ;
+ | select_from select_lock_type;
udf_func_type:
/* empty */ { $$ = UDFTYPE_FUNCTION; }
- | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; }
- ;
+ | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; };
udf_type:
STRING_SYM {$$ = (int) STRING_RESULT; }
| REAL {$$ = (int) REAL_RESULT; }
- | INT_SYM {$$ = (int) INT_RESULT; }
- ;
+ | INT_SYM {$$ = (int) INT_RESULT; };
field_list:
field_list_item
- | field_list ',' field_list_item
- ;
+ | field_list ',' field_list_item;
+
field_list_item:
- field_spec
+ column_def
+ | key_def
+ ;
+
+column_def:
+ field_spec check_constraint
| field_spec references
{
Lex->col_list.empty(); /* Alloced by sql_alloc */
}
- | key_type opt_ident '(' key_list ')'
+ ;
+
+key_def:
+ key_type opt_ident '(' key_list ')'
{
- Lex->key_list.push_back(new Key($1,$2,Lex->col_list));
- Lex->col_list.empty(); /* Alloced by sql_alloc */
+ LEX *lex=Lex;
+ lex->key_list.push_back(new Key($1,$2,lex->col_list));
+ lex->col_list.empty(); /* Alloced by sql_alloc */
}
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
{
Lex->col_list.empty(); /* Alloced by sql_alloc */
}
- | opt_constraint CHECK_SYM '(' expr ')'
+ | opt_constraint check_constraint
{
Lex->col_list.empty(); /* Alloced by sql_alloc */
}
;
-opt_constraint:
+check_constraint:
/* empty */
- | CONSTRAINT opt_ident
+ | CHECK_SYM expr
;
+opt_constraint:
+ /* empty */
+ | CONSTRAINT opt_ident;
+
field_spec:
field_ident
{
- Lex->length=Lex->dec=0; Lex->type=0; Lex->interval=0;
- Lex->default_value=0;
+ LEX *lex=Lex;
+ lex->length=lex->dec=0; lex->type=0; lex->interval=0;
+ lex->default_value=0;
}
type opt_attribute
{
+ LEX *lex=Lex;
if (add_field_to_list($1.str,
(enum enum_field_types) $3,
- Lex->length,Lex->dec,Lex->type,
- Lex->default_value,Lex->change,
- Lex->interval))
+ lex->length,lex->dec,lex->type,
+ lex->default_value,lex->change,
+ lex->interval))
YYABORT;
- }
- ;
+ };
type:
int_type opt_len field_options { Lex->length=$2; $$=$1; }
@@ -925,84 +1045,82 @@ type:
{ $$=FIELD_TYPE_DECIMAL;}
| ENUM {Lex->interval_list.empty();} '(' string_list ')'
{
- Lex->interval=typelib(Lex->interval_list);
+ LEX *lex=Lex;
+ lex->interval=typelib(lex->interval_list);
$$=FIELD_TYPE_ENUM;
}
| SET { Lex->interval_list.empty();} '(' string_list ')'
{
- Lex->interval=typelib(Lex->interval_list);
+ LEX *lex=Lex;
+ lex->interval=typelib(lex->interval_list);
$$=FIELD_TYPE_SET;
- }
- ;
+ };
char:
CHAR_SYM {}
| NCHAR_SYM {}
- | NATIONAL_SYM CHAR_SYM {}
- ;
+ | NATIONAL_SYM CHAR_SYM {};
varchar:
char VARYING {}
| VARCHAR {}
| NATIONAL_SYM VARCHAR {}
- | NCHAR_SYM VARCHAR {}
- ;
+ | NCHAR_SYM VARCHAR {};
int_type:
INT_SYM { $$=FIELD_TYPE_LONG; }
| TINYINT { $$=FIELD_TYPE_TINY; }
| SMALLINT { $$=FIELD_TYPE_SHORT; }
| MEDIUMINT { $$=FIELD_TYPE_INT24; }
- | BIGINT { $$=FIELD_TYPE_LONGLONG; }
- ;
+ | BIGINT { $$=FIELD_TYPE_LONGLONG; };
real_type:
REAL { $$= current_thd->sql_mode & MODE_REAL_AS_FLOAT ?
FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; }
| DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; }
- | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }
- ;
+ | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; };
+
float_options:
/* empty */ {}
| '(' NUM ')' { Lex->length=$2.str; }
- | '(' NUM ',' NUM ')' { Lex->length=$2.str; Lex->dec=$4.str; }
- ;
+ | precision {};
+
+precision:
+ '(' NUM ',' NUM ')'
+ {
+ LEX *lex=Lex;
+ lex->length=$2.str; lex->dec=$4.str;
+ };
field_options:
/* empty */ {}
- | field_opt_list {}
- ;
+ | field_opt_list {};
field_opt_list:
field_opt_list field_option {}
- | field_option {}
- ;
+ | field_option {};
field_option:
- UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
- | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
- ;
+ SIGNED_SYM {}
+ | UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
+ | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; };
opt_len:
/* empty */ { $$=(char*) 0; } /* use default length */
- | '(' NUM ')' { $$=$2.str; }
- ;
+ | '(' NUM ')' { $$=$2.str; };
opt_precision:
/* empty */ {}
- | '(' NUM ',' NUM ')' { Lex->length=$2.str; Lex->dec=$4.str; }
- ;
+ | precision {};
opt_attribute:
/* empty */ {}
- | opt_attribute_list {}
- ;
+ | opt_attribute_list {};
opt_attribute_list:
opt_attribute_list attribute {}
- | attribute
- ;
+ | attribute;
attribute:
NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
@@ -1012,11 +1130,12 @@ attribute:
| PRIMARY_SYM KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; }
| UNIQUE_SYM { Lex->type|= UNIQUE_FLAG; }
| UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; }
- ;
+ | COMMENT_SYM text_literal {};
opt_binary:
/* empty */ {}
| BINARY { Lex->type|=BINARY_FLAG; }
+ | CHAR_SYM SET opt_equal ident {}
;
references:
@@ -1024,33 +1143,29 @@ references:
| REFERENCES table_ident '(' key_list ')' opt_on_delete
{
Lex->col_list.empty(); /* Alloced by sql_alloc */
- }
- ;
+ };
opt_on_delete:
/* empty */ {}
- | opt_on_delete_list {}
- ;
+ | opt_on_delete_list {};
opt_on_delete_list:
opt_on_delete_list opt_on_delete_item {}
- | opt_on_delete_item {}
- ;
+ | opt_on_delete_item {};
+
opt_on_delete_item:
ON DELETE_SYM delete_option {}
| ON UPDATE_SYM delete_option {}
| MATCH FULL {}
- | MATCH PARTIAL {}
- ;
+ | MATCH PARTIAL {};
delete_option:
RESTRICT {}
| CASCADE {}
| SET NULL_SYM {}
| NO_SYM ACTION {}
- | SET DEFAULT {}
- ;
+ | SET DEFAULT {};
key_type:
opt_constraint PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; }
@@ -1058,44 +1173,37 @@ key_type:
| FULLTEXT_SYM { $$= Key::FULLTEXT; }
| FULLTEXT_SYM key_or_index { $$= Key::FULLTEXT; }
| opt_constraint UNIQUE_SYM { $$= Key::UNIQUE; }
- | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; }
- ;
+ | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; };
key_or_index:
KEY_SYM {}
- | INDEX {}
- ;
+ | INDEX {};
keys_or_index:
KEYS {}
| INDEX {}
- ;
+ | INDEXES {};
opt_unique_or_fulltext:
/* empty */ { $$= Key::MULTIPLE; }
| UNIQUE_SYM { $$= Key::UNIQUE; }
- | FULLTEXT_SYM { $$= Key::FULLTEXT; }
- ;
+ | FULLTEXT_SYM { $$= Key::FULLTEXT; };
key_list:
key_list ',' key_part order_dir { Lex->col_list.push_back($3); }
- | key_part order_dir { Lex->col_list.push_back($1); }
- ;
+ | key_part order_dir { Lex->col_list.push_back($1); };
key_part:
ident { $$=new key_part_spec($1.str); }
- | ident '(' NUM ')' { $$=new key_part_spec($1.str,(uint) atoi($3.str)); }
- ;
+ | ident '(' NUM ')' { $$=new key_part_spec($1.str,(uint) atoi($3.str)); };
opt_ident:
/* empty */ { $$=(char*) 0; } /* Defaultlength */
- | field_ident { $$=$1.str; }
- ;
+ | field_ident { $$=$1.str; };
string_list:
text_string { Lex->interval_list.push_back($1); }
- | string_list ',' text_string { Lex->interval_list.push_back($3); }
- ;
+ | string_list ',' text_string { Lex->interval_list.push_back($3); };
/*
** Alter table
@@ -1107,7 +1215,7 @@ alter:
LEX *lex=Lex;
lex->sql_command = SQLCOM_ALTER_TABLE;
lex->name=0;
- if (!add_table_to_list($4, NULL,1))
+ if (!add_table_to_list($4, NULL, TL_OPTION_UPDATING))
YYABORT;
lex->drop_primary=0;
lex->create_list.empty();
@@ -1115,12 +1223,15 @@ alter:
lex->col_list.empty();
lex->drop_list.empty();
lex->alter_list.empty();
- lex->order_list.elements=0;
- lex->order_list.first=0;
- lex->order_list.next= (byte**) &lex->order_list.first;
- lex->db=lex->name=0;
+ lex->select->order_list.elements=0;
+ lex->select->order_list.first=0;
+ lex->select->order_list.next= (byte**) &lex->select->order_list.first;
+ lex->select->db=lex->name=0;
bzero((char*) &lex->create_info,sizeof(lex->create_info));
lex->create_info.db_type= DB_TYPE_DEFAULT;
+ lex->create_info.row_type= ROW_TYPE_NOT_USED;
+ lex->alter_keys_onoff=LEAVE_AS_IS;
+ lex->simple_alter=1;
}
alter_list
{}
@@ -1128,91 +1239,152 @@ alter:
alter_list:
| alter_list_item
- | alter_list ',' alter_list_item
- ;
+ | alter_list ',' alter_list_item;
add_column:
- ADD opt_column { Lex->change=0;}
- ;
+ ADD opt_column { Lex->change=0; };
alter_list_item:
- add_column field_list_item opt_place
- | add_column '(' field_list ')'
- | CHANGE opt_column field_ident { Lex->change= $3.str; } field_spec
+ add_column column_def opt_place { Lex->simple_alter=0; }
+ | ADD key_def { Lex->simple_alter=0; }
+ | add_column '(' field_list ')' { Lex->simple_alter=0; }
+ | CHANGE opt_column field_ident
+ {
+ LEX *lex=Lex;
+ lex->change= $3.str; lex->simple_alter=0;
+ }
+ field_spec opt_place
| MODIFY_SYM opt_column field_ident
{
- Lex->length=Lex->dec=0; Lex->type=0; Lex->interval=0;
- Lex->default_value=0;
+ LEX *lex=Lex;
+ lex->length=lex->dec=0; lex->type=0; lex->interval=0;
+ lex->default_value=0;
+ lex->simple_alter=0;
}
type opt_attribute
{
+ LEX *lex=Lex;
if (add_field_to_list($3.str,
(enum enum_field_types) $5,
- Lex->length,Lex->dec,Lex->type,
- Lex->default_value, $3.str,
- Lex->interval))
- YYABORT;
+ lex->length,lex->dec,lex->type,
+ lex->default_value, $3.str,
+ lex->interval))
+ YYABORT;
}
+ opt_place
| DROP opt_column field_ident opt_restrict
- { Lex->drop_list.push_back(new Alter_drop(Alter_drop::COLUMN,
- $3.str)); }
- | DROP PRIMARY_SYM KEY_SYM { Lex->drop_primary=1; }
- | DROP FOREIGN KEY_SYM opt_ident {}
+ {
+ LEX *lex=Lex;
+ lex->drop_list.push_back(new Alter_drop(Alter_drop::COLUMN,
+ $3.str)); lex->simple_alter=0;
+ }
+ | DROP PRIMARY_SYM KEY_SYM
+ {
+ LEX *lex=Lex;
+ lex->drop_primary=1; lex->simple_alter=0;
+ }
+ | DROP FOREIGN KEY_SYM opt_ident { Lex->simple_alter=0; }
| DROP key_or_index field_ident
- { Lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
- $3.str)); }
+ {
+ LEX *lex=Lex;
+ lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
+ $3.str));
+ lex->simple_alter=0;
+ }
+ | DISABLE_SYM KEYS { Lex->alter_keys_onoff=DISABLE; }
+ | ENABLE_SYM KEYS { Lex->alter_keys_onoff=ENABLE; }
| ALTER opt_column field_ident SET DEFAULT literal
- { Lex->alter_list.push_back(new Alter_column($3.str,$6)); }
+ {
+ LEX *lex=Lex;
+ lex->alter_list.push_back(new Alter_column($3.str,$6));
+ lex->simple_alter=0;
+ }
| ALTER opt_column field_ident DROP DEFAULT
- { Lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); }
- | RENAME opt_to table_alias table_ident
- { Lex->db=$4->db.str ; Lex->name= $4->table.str; }
- | create_table_options
- | order_clause
- ;
+ {
+ LEX *lex=Lex;
+ lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0));
+ lex->simple_alter=0;
+ }
+ | RENAME opt_to table_ident
+ {
+ LEX *lex=Lex;
+ lex->select->db=$3->db.str;
+ lex->name= $3->table.str;
+ }
+ | create_table_options { Lex->simple_alter=0; }
+ | order_clause { Lex->simple_alter=0; };
opt_column:
/* empty */ {}
- | COLUMN_SYM {}
- ;
+ | COLUMN_SYM {};
opt_ignore:
/* empty */ { Lex->duplicates=DUP_ERROR; }
- | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }
- ;
+ | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; };
opt_restrict:
/* empty */ {}
| RESTRICT {}
- | CASCADE {}
- ;
+ | CASCADE {};
opt_place:
/* empty */ {}
| AFTER_SYM ident { store_position_for_column($2.str); }
- | FIRST_SYM { store_position_for_column(first_keyword); }
- ;
+ | FIRST_SYM { store_position_for_column(first_keyword); };
opt_to:
/* empty */ {}
| TO_SYM {}
- | AS {}
- ;
+ | EQ {}
+ | AS {};
+/*
+ * The first two deprecate the last two--delete the last two for 4.1 release
+ */
slave:
- SLAVE START_SYM
+ START_SYM SLAVE slave_thread_opts
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_SLAVE_START;
+ lex->type = 0;
+ }
+ |
+ STOP_SYM SLAVE slave_thread_opts
{
- Lex->sql_command = SQLCOM_SLAVE_START;
- Lex->type = 0;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_SLAVE_STOP;
+ lex->type = 0;
}
|
- SLAVE STOP_SYM
+ SLAVE START_SYM slave_thread_opts
{
- Lex->sql_command = SQLCOM_SLAVE_STOP;
- Lex->type = 0;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_SLAVE_START;
+ lex->type = 0;
}
+ |
+ SLAVE STOP_SYM slave_thread_opts
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_SLAVE_STOP;
+ lex->type = 0;
+ };
+
+start:
+ START_SYM TRANSACTION_SYM { Lex->sql_command = SQLCOM_BEGIN;}
+ {}
;
+slave_thread_opts:
+ slave_thread_opt
+ | slave_thread_opts ',' slave_thread_opt;
+
+slave_thread_opt:
+ /*empty*/ {}
+ | SQL_THREAD { Lex->slave_thd_opt|=SLAVE_SQL; }
+ | IO_THREAD { Lex->slave_thd_opt|=SLAVE_IO; }
+ ;
+
restore:
RESTORE_SYM table_or_tables
{
@@ -1221,8 +1393,7 @@ restore:
table_list FROM TEXT_STRING
{
Lex->backup_dir = $6.str;
- }
- ;
+ };
backup:
BACKUP_SYM table_or_tables
@@ -1232,43 +1403,38 @@ backup:
table_list TO_SYM TEXT_STRING
{
Lex->backup_dir = $6.str;
- }
- ;
+ };
repair:
REPAIR table_or_tables
{
- Lex->sql_command = SQLCOM_REPAIR;
- Lex->check_opt.init();
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_REPAIR;
+ lex->check_opt.init();
}
- table_list opt_mi_check_type
+ table_list opt_mi_repair_type
{}
;
-opt_mi_check_type:
+opt_mi_repair_type:
/* empty */ { Lex->check_opt.flags = T_MEDIUM; }
- | TYPE_SYM EQ mi_check_types {}
- | mi_check_types {}
- ;
+ | mi_repair_types {};
-mi_check_types:
- mi_check_type {}
- | mi_check_type mi_check_types {}
- ;
+mi_repair_types:
+ mi_repair_type {}
+ | mi_repair_type mi_repair_types {};
-mi_check_type:
- QUICK { Lex->check_opt.quick = 1; }
- | FAST_SYM { Lex->check_opt.flags|= T_FAST; }
- | MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; }
+mi_repair_type:
+ QUICK { Lex->check_opt.flags|= T_QUICK; }
| EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
- | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }
- ;
+ | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; };
analyze:
ANALYZE_SYM table_or_tables
{
- Lex->sql_command = SQLCOM_ANALYZE;
- Lex->check_opt.init();
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_ANALYZE;
+ lex->check_opt.init();
}
table_list opt_mi_check_type
{}
@@ -1277,18 +1443,35 @@ analyze:
check:
CHECK_SYM table_or_tables
{
- Lex->sql_command = SQLCOM_CHECK;
- Lex->check_opt.init();
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_CHECK;
+ lex->check_opt.init();
}
table_list opt_mi_check_type
{}
;
+opt_mi_check_type:
+ /* empty */ { Lex->check_opt.flags = T_MEDIUM; }
+ | mi_check_types {};
+
+mi_check_types:
+ mi_check_type {}
+ | mi_check_type mi_check_types {};
+
+mi_check_type:
+ QUICK { Lex->check_opt.flags|= T_QUICK; }
+ | FAST_SYM { Lex->check_opt.flags|= T_FAST; }
+ | MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; }
+ | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
+ | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; };
+
optimize:
OPTIMIZE table_or_tables
{
- Lex->sql_command = SQLCOM_OPTIMIZE;
- Lex->check_opt.init();
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_OPTIMIZE;
+ lex->check_opt.init();
}
table_list opt_mi_check_type
{}
@@ -1305,17 +1488,15 @@ rename:
table_to_table_list:
table_to_table
- | table_to_table_list ',' table_to_table
- {}
- ;
+ | table_to_table_list ',' table_to_table;
table_to_table:
table_ident TO_SYM table_ident
- { if (!add_table_to_list($1,NULL,1,TL_IGNORE) ||
- !add_table_to_list($3,NULL,1,TL_IGNORE))
+ {
+ if (!add_table_to_list($1, NULL, TL_OPTION_UPDATING, TL_IGNORE) ||
+ !add_table_to_list($3, NULL, TL_OPTION_UPDATING, TL_IGNORE))
YYABORT;
- }
- ;
+ };
/*
Select : retrieve data from table
@@ -1323,54 +1504,89 @@ table_to_table:
select:
- SELECT_SYM
+ select_init { Lex->sql_command=SQLCOM_SELECT; };
+
+select_init:
+ SELECT_SYM select_part2 { Select->braces= 0; } opt_union
+ |
+ '(' SELECT_SYM select_part2 ')' { Select->braces= 1;} union_opt;
+
+
+select_part2:
{
LEX *lex=Lex;
- lex->sql_command= SQLCOM_SELECT;
lex->lock_option=TL_READ;
- mysql_init_select(lex);
+ mysql_init_select(lex);
}
- select_options select_item_list select_into select_lock_type
- {}
- ;
+ select_options select_item_list select_into select_lock_type;
select_into:
- /* empty */
+ limit_clause {}
| select_from
| opt_into select_from
- | select_from opt_into
- ;
+ | select_from opt_into;
select_from:
- FROM join_table_list where_clause group_clause having_clause opt_order_clause limit_clause procedure_clause
- ;
+ FROM join_table_list where_clause group_clause having_clause opt_order_clause limit_clause procedure_clause;
+
select_options:
/* empty*/
- | select_option_list
- ;
+ | select_option_list;
select_option_list:
select_option_list select_option
- | select_option
- ;
+ | select_option;
select_option:
- STRAIGHT_JOIN { Lex->options|= SELECT_STRAIGHT_JOIN; }
- | HIGH_PRIORITY { Lex->lock_option= TL_READ_HIGH_PRIORITY; }
- | DISTINCT { Lex->options|= SELECT_DISTINCT; }
- | SQL_SMALL_RESULT { Lex->options|= SELECT_SMALL_RESULT; }
- | SQL_BIG_RESULT { Lex->options|= SELECT_BIG_RESULT; }
- | SQL_BUFFER_RESULT { Lex->options|= OPTION_BUFFER_RESULT; }
+ STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; }
+ | HIGH_PRIORITY
+ {
+ if (check_simple_select())
+ YYABORT;
+ Lex->lock_option= TL_READ_HIGH_PRIORITY;
+ }
+ | DISTINCT { Select->options|= SELECT_DISTINCT; }
+ | SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; }
+ | SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; }
+ | SQL_BUFFER_RESULT
+ {
+ if (check_simple_select())
+ YYABORT;
+ Select->options|= OPTION_BUFFER_RESULT;
+ }
+ | SQL_CALC_FOUND_ROWS
+ {
+ if (check_simple_select())
+ YYABORT;
+ Select->options|= OPTION_FOUND_ROWS;
+ }
+ | SQL_NO_CACHE_SYM { current_thd->safe_to_cache_query=0; }
+ | SQL_CACHE_SYM
+ {
+ Lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
+ }
| ALL {}
;
select_lock_type:
/* empty */
| FOR_SYM UPDATE_SYM
- { Lex->lock_option= TL_WRITE; }
+ {
+ LEX *lex=Lex;
+ if (check_simple_select())
+ YYABORT;
+ lex->lock_option= TL_WRITE;
+ lex->thd->safe_to_cache_query=0;
+ }
| LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
- { Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; }
+ {
+ LEX *lex=Lex;
+ if (check_simple_select())
+ YYABORT;
+ lex->lock_option= TL_READ_WITH_SHARED_LOCKS;
+ lex->thd->safe_to_cache_query=0;
+ }
;
select_item_list:
@@ -1380,8 +1596,8 @@ select_item_list:
{
if (add_item_to_list(new Item_field(NULL,NULL,"*")))
YYABORT;
- }
- ;
+ };
+
select_item:
remember_name select_item2 remember_end select_alias
@@ -1392,39 +1608,32 @@ select_item:
$2->set_name($4.str);
else if (!$2->name)
$2->set_name($1,(uint) ($3 - $1));
- }
- ;
+ };
remember_name:
- { $$=(char*) Lex->tok_start; }
- ;
+ { $$=(char*) Lex->tok_start; };
remember_end:
- { $$=(char*) Lex->tok_end; }
- ;
+ { $$=(char*) Lex->tok_end; };
select_item2:
table_wild { $$=$1; } /* table.* */
- | expr { $$=$1; }
- ;
+ | expr { $$=$1; };
select_alias:
{ $$.str=0;}
| AS ident { $$=$2; }
| AS TEXT_STRING { $$=$2; }
| ident { $$=$1; }
- | TEXT_STRING { $$=$1; }
- ;
+ | TEXT_STRING { $$=$1; };
optional_braces:
/* empty */ {}
- | '(' ')' {}
- ;
+ | '(' ')' {};
/* all possible expressions */
expr: expr_expr {$$ = $1; }
- | simple_expr {$$ = $1; }
- ;
+ | simple_expr {$$ = $1; };
/* expressions that begin with 'expr' */
expr_expr:
@@ -1438,6 +1647,7 @@ expr_expr:
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| expr OR_OR_CONCAT expr { $$= or_or_concat($1,$3); }
| expr OR expr { $$= new Item_cond_or($1,$3); }
+ | expr XOR expr { $$= new Item_cond_xor($1,$3); }
| expr AND expr { $$= new Item_cond_and($1,$3); }
| expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
| expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5));}
@@ -1459,13 +1669,13 @@ expr_expr:
| expr '*' expr { $$= new Item_func_mul($1,$3); }
| expr '/' expr { $$= new Item_func_div($1,$3); }
| expr '|' expr { $$= new Item_func_bit_or($1,$3); }
+ | expr '^' expr { $$= new Item_func_bit_xor($1,$3); }
| expr '&' expr { $$= new Item_func_bit_and($1,$3); }
| expr '%' expr { $$= new Item_func_mod($1,$3); }
| expr '+' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,0); }
| expr '-' INTERVAL_SYM expr interval
- { $$= new Item_date_add_interval($1,$4,$5,1); }
- ;
+ { $$= new Item_date_add_interval($1,$4,$5,1); };
/* expressions that begin with 'expr' that do NOT follow IN_SYM */
no_in_expr:
@@ -1475,6 +1685,7 @@ no_in_expr:
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| no_in_expr OR_OR_CONCAT expr { $$= or_or_concat($1,$3); }
| no_in_expr OR expr { $$= new Item_cond_or($1,$3); }
+ | no_in_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_in_expr AND expr { $$= new Item_cond_and($1,$3); }
| no_in_expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
| no_in_expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
@@ -1496,14 +1707,14 @@ no_in_expr:
| no_in_expr '*' expr { $$= new Item_func_mul($1,$3); }
| no_in_expr '/' expr { $$= new Item_func_div($1,$3); }
| no_in_expr '|' expr { $$= new Item_func_bit_or($1,$3); }
+ | no_in_expr '^' expr { $$= new Item_func_bit_xor($1,$3); }
| no_in_expr '&' expr { $$= new Item_func_bit_and($1,$3); }
| no_in_expr '%' expr { $$= new Item_func_mod($1,$3); }
| no_in_expr '+' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,0); }
| no_in_expr '-' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,1); }
- | simple_expr
- ;
+ | simple_expr;
/* expressions that begin with 'expr' that does NOT follow AND */
no_and_expr:
@@ -1517,6 +1728,7 @@ no_and_expr:
{ $$= new Item_func_not(new Item_func_between($1,$4,$6)); }
| no_and_expr OR_OR_CONCAT expr { $$= or_or_concat($1,$3); }
| no_and_expr OR expr { $$= new Item_cond_or($1,$3); }
+ | no_and_expr XOR expr { $$= new Item_cond_xor($1,$3); }
| no_and_expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); }
| no_and_expr NOT LIKE simple_expr opt_escape { $$= new Item_func_not(new Item_func_like($1,$4,$5)); }
| no_and_expr REGEXP expr { $$= new Item_func_regex($1,$3); }
@@ -1537,21 +1749,33 @@ no_and_expr:
| no_and_expr '*' expr { $$= new Item_func_mul($1,$3); }
| no_and_expr '/' expr { $$= new Item_func_div($1,$3); }
| no_and_expr '|' expr { $$= new Item_func_bit_or($1,$3); }
+ | no_and_expr '^' expr { $$= new Item_func_bit_xor($1,$3); }
| no_and_expr '&' expr { $$= new Item_func_bit_and($1,$3); }
| no_and_expr '%' expr { $$= new Item_func_mod($1,$3); }
| no_and_expr '+' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,0); }
| no_and_expr '-' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,1); }
- | simple_expr
- ;
+ | simple_expr;
simple_expr:
simple_ident
| literal
- | '@' ident_or_text SET_VAR expr { $$= new Item_func_set_user_var($2,$4); }
- | '@' ident_or_text { $$= new Item_func_get_user_var($2); }
- | '@' '@' ident_or_text { if (!($$= get_system_var($3))) YYABORT; }
+ | '@' ident_or_text SET_VAR expr
+ {
+ $$= new Item_func_set_user_var($2,$4);
+ current_thd->safe_to_cache_query=0;
+ }
+ | '@' ident_or_text
+ {
+ $$= new Item_func_get_user_var($2);
+ current_thd->safe_to_cache_query=0;
+ }
+ | '@' '@' opt_var_ident_type ident_or_text
+ {
+ if (!($$= get_system_var((enum_var_type) $3, $4)))
+ YYABORT;
+ }
| sum_expr
| '-' expr %prec NEG { $$= new Item_func_neg($2); }
| '~' expr %prec NEG { $$= new Item_func_bit_neg($2); }
@@ -1559,15 +1783,17 @@ simple_expr:
| '!' expr %prec NEG { $$= new Item_func_not($2); }
| '(' expr ')' { $$= $2; }
| '{' ident expr '}' { $$= $3; }
- | MATCH '(' ident_list ')' AGAINST '(' expr ')'
- { Lex->ftfunc_list.push_back(
- (Item_func_match *)($$=new Item_func_match(*$3,$7))); }
- | MATCH ident_list AGAINST '(' expr ')'
- { Lex->ftfunc_list.push_back(
- (Item_func_match *)($$=new Item_func_match(*$2,$5))); }
+ | MATCH ident_list_arg AGAINST '(' expr ')'
+ { Select->ftfunc_list.push_back((Item_func_match *)
+ ($$=new Item_func_match_nl(*$2,$5))); }
+ | MATCH ident_list_arg AGAINST '(' expr IN_SYM BOOLEAN_SYM MODE_SYM ')'
+ { Select->ftfunc_list.push_back((Item_func_match *)
+ ($$=new Item_func_match_bool(*$2,$5))); }
| BINARY expr %prec NEG { $$= new Item_func_binary($2); }
+ | CAST_SYM '(' expr AS cast_type ')' { $$= create_func_cast($3, $5); }
| CASE_SYM opt_expr WHEN_SYM when_list opt_else END
{ $$= new Item_func_case(* $4, $2, $5 ); }
+ | CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); }
| FUNC_ARG0 '(' ')'
{ $$= ((Item*(*)(void))($1.symbol->create_func))();}
| FUNC_ARG1 '(' expr ')'
@@ -1589,27 +1815,45 @@ simple_expr:
| CONCAT_WS '(' expr ',' expr_list ')'
{ $$= new Item_func_concat_ws($3, *$5); }
| CURDATE optional_braces
- { $$= new Item_func_curdate(); }
+ { $$= new Item_func_curdate(); current_thd->safe_to_cache_query=0; }
| CURTIME optional_braces
- { $$= new Item_func_curtime(); }
+ { $$= new Item_func_curtime(); current_thd->safe_to_cache_query=0; }
| CURTIME '(' expr ')'
- { $$= new Item_func_curtime($3); }
+ {
+ $$= new Item_func_curtime($3);
+ current_thd->safe_to_cache_query=0;
+ }
| DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
{ $$= new Item_date_add_interval($3,$6,$7,0); }
| DATE_SUB_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
{ $$= new Item_date_add_interval($3,$6,$7,1); }
| DATABASE '(' ')'
- { $$= new Item_func_database(); }
+ {
+ $$= new Item_func_database();
+ current_thd->safe_to_cache_query=0;
+ }
| ELT_FUNC '(' expr ',' expr_list ')'
{ $$= new Item_func_elt($3, *$5); }
| MAKE_SET_SYM '(' expr ',' expr_list ')'
{ $$= new Item_func_make_set($3, *$5); }
- | ENCRYPT '(' expr ')' { $$= new Item_func_encrypt($3); }
+ | ENCRYPT '(' expr ')'
+ {
+ $$= new Item_func_encrypt($3);
+ current_thd->safe_to_cache_query=0;
+ }
| ENCRYPT '(' expr ',' expr ')' { $$= new Item_func_encrypt($3,$5); }
| DECODE_SYM '(' expr ',' TEXT_STRING ')'
{ $$= new Item_func_decode($3,$5.str); }
| ENCODE_SYM '(' expr ',' TEXT_STRING ')'
{ $$= new Item_func_encode($3,$5.str); }
+ | DES_DECRYPT_SYM '(' expr ')'
+ { $$= new Item_func_des_decrypt($3); }
+ | DES_DECRYPT_SYM '(' expr ',' expr ')'
+ { $$= new Item_func_des_decrypt($3,$5); }
+ | DES_ENCRYPT_SYM '(' expr ')'
+ { $$= new Item_func_des_encrypt($3); }
+ | DES_ENCRYPT_SYM '(' expr ',' expr ')'
+ { $$= new Item_func_des_encrypt($3,$5); }
| EXPORT_SET '(' expr ',' expr ',' expr ')'
{ $$= new Item_func_export_set($3, $5, $7); }
| EXPORT_SET '(' expr ',' expr ',' expr ',' expr ')'
@@ -1622,7 +1866,7 @@ simple_expr:
{ $$= new Item_func_from_unixtime($3); }
| FROM_UNIXTIME '(' expr ',' expr ')'
{
- $$= new Item_func_date_format(new Item_func_from_unixtime($3),$5,0);
+ $$= new Item_func_date_format (new Item_func_from_unixtime($3),$5,0);
}
| FIELD_FUNC '(' expr ',' expr_list ')'
{ $$= new Item_func_field($3, *$5); }
@@ -1641,10 +1885,12 @@ simple_expr:
{
$$= new Item_int((char*) "last_insert_id()",
current_thd->insert_id(),21);
+ current_thd->safe_to_cache_query=0;
}
| LAST_INSERT_ID '(' expr ')'
{
$$= new Item_func_set_last_insert_id($3);
+ current_thd->safe_to_cache_query=0;
}
| LEFT '(' expr ',' expr ')'
{ $$= new Item_func_left($3,$5); }
@@ -1656,19 +1902,38 @@ simple_expr:
{ $5->push_front($3); $$= new Item_func_max(*$5); }
| LEAST_SYM '(' expr ',' expr_list ')'
{ $5->push_front($3); $$= new Item_func_min(*$5); }
+ | LOG_SYM '(' expr ')'
+ { $$= new Item_func_log($3); }
+ | LOG_SYM '(' expr ',' expr ')'
+ { $$= new Item_func_log($3, $5); }
+ | MASTER_POS_WAIT '(' expr ',' expr ')'
+ {
+ $$= new Item_master_pos_wait($3, $5);
+ current_thd->safe_to_cache_query=0;
+ }
+ | MASTER_POS_WAIT '(' expr ',' expr ',' expr ')'
+ {
+ $$= new Item_master_pos_wait($3, $5, $7);
+ current_thd->safe_to_cache_query=0;
+ }
| MINUTE_SYM '(' expr ')'
{ $$= new Item_func_minute($3); }
| MONTH_SYM '(' expr ')'
{ $$= new Item_func_month($3); }
| NOW_SYM optional_braces
- { $$= new Item_func_now(); }
+ { $$= new Item_func_now(); current_thd->safe_to_cache_query=0;}
| NOW_SYM '(' expr ')'
- { $$= new Item_func_now($3); }
- | PASSWORD '(' expr ')' { $$= new Item_func_password($3); }
+ { $$= new Item_func_now($3); current_thd->safe_to_cache_query=0;}
+ | PASSWORD '(' expr ')'
+ {
+ $$= new Item_func_password($3);
+ }
| POSITION_SYM '(' no_in_expr IN_SYM expr ')'
{ $$ = new Item_func_locate($5,$3); }
- | RAND '(' expr ')' { $$= new Item_func_rand($3); }
- | RAND '(' ')' { $$= new Item_func_rand(); }
+ | RAND '(' expr ')'
+ { $$= new Item_func_rand($3); current_thd->safe_to_cache_query=0;}
+ | RAND '(' ')'
+ { $$= new Item_func_rand(); current_thd->safe_to_cache_query=0;}
| REPLACE '(' expr ',' expr ',' expr ')'
{ $$= new Item_func_replace($3,$5,$7); }
| RIGHT '(' expr ',' expr ')'
@@ -1743,15 +2008,24 @@ simple_expr:
$$ = new Item_func_udf_int($1);
}
| UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')'
- { $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9); }
+ {
+ $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9);
+ }
| UNIX_TIMESTAMP '(' ')'
- { $$= new Item_func_unix_timestamp(); }
+ {
+ $$= new Item_func_unix_timestamp();
+ current_thd->safe_to_cache_query=0;
+ }
| UNIX_TIMESTAMP '(' expr ')'
{ $$= new Item_func_unix_timestamp($3); }
| USER '(' ')'
- { $$= new Item_func_user(); }
+ { $$= new Item_func_user(); current_thd->safe_to_cache_query=0; }
| WEEK_SYM '(' expr ')'
- { $$= new Item_func_week($3,new Item_int((char*) "0",0,1)); }
+ {
+ LEX *lex=Lex;
+ $$= new Item_func_week($3,new Item_int((char*) "0",
+ lex->thd->variables.default_week_format,1));
+ }
| WEEK_SYM '(' expr ',' expr ')'
{ $$= new Item_func_week($3,$5); }
| YEAR_SYM '(' expr ')'
@@ -1761,15 +2035,16 @@ simple_expr:
| YEARWEEK '(' expr ',' expr ')'
{ $$= new Item_func_yearweek($3, $5); }
| BENCHMARK_SYM '(' ULONG_NUM ',' expr ')'
- { $$=new Item_func_benchmark($3,$5); }
+ {
+ $$=new Item_func_benchmark($3,$5);
+ current_thd->safe_to_cache_query=0;
+ }
| EXTRACT_SYM '(' interval FROM expr ')'
- { $$=new Item_extract( $3, $5); }
- ;
+ { $$=new Item_extract( $3, $5); };
udf_expr_list:
/* empty */ { $$= NULL; }
- | expr_list { $$= $1;}
- ;
+ | expr_list { $$= $1;};
sum_expr:
AVG_SYM '(' in_sum_expr ')'
@@ -1778,12 +2053,16 @@ sum_expr:
{ $$=new Item_sum_and($3); }
| BIT_OR '(' in_sum_expr ')'
{ $$=new Item_sum_or($3); }
- | COUNT_SYM '(' '*' ')'
+ | COUNT_SYM '(' opt_all '*' ')'
{ $$=new Item_sum_count(new Item_int((int32) 0L,1)); }
| COUNT_SYM '(' in_sum_expr ')'
{ $$=new Item_sum_count($3); }
- | COUNT_SYM '(' DISTINCT expr_list ')'
- { $$=new Item_sum_count_distinct(* $4); }
+ | COUNT_SYM '(' DISTINCT
+ { Select->in_sum_expr++; }
+ expr_list
+ { Select->in_sum_expr--; }
+ ')'
+ { $$=new Item_sum_count_distinct(* $5); }
| GROUP_UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' in_sum_expr ')'
{ $$= new Item_sum_unique_users($3,atoi($5.str),atoi($7.str),$9); }
| MIN_SYM '(' in_sum_expr ')'
@@ -1793,161 +2072,211 @@ sum_expr:
| STD_SYM '(' in_sum_expr ')'
{ $$=new Item_sum_std($3); }
| SUM_SYM '(' in_sum_expr ')'
- { $$=new Item_sum_sum($3); }
- ;
+ { $$=new Item_sum_sum($3); };
in_sum_expr:
- { Lex->in_sum_expr++; }
+ opt_all
+ { Select->in_sum_expr++; }
expr
{
- Lex->in_sum_expr--;
- $$=$2;
- }
+ Select->in_sum_expr--;
+ $$=$3;
+ };
+
+cast_type:
+ BINARY { $$=ITEM_CAST_BINARY; }
+ | CHAR_SYM { $$=ITEM_CAST_CHAR; }
+ | SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; }
+ | SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; }
+ | UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; }
+ | UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; }
+ | DATE_SYM { $$=ITEM_CAST_DATE; }
+ | TIME_SYM { $$=ITEM_CAST_TIME; }
+ | DATETIME { $$=ITEM_CAST_DATETIME; }
;
expr_list:
- { Lex->expr_list.push_front(new List<Item>); }
+ { Select->expr_list.push_front(new List<Item>); }
expr_list2
- { $$= Lex->expr_list.pop(); }
- ;
+ { $$= Select->expr_list.pop(); };
expr_list2:
- expr { Lex->expr_list.head()->push_back($1); }
- | expr_list2 ',' expr { Lex->expr_list.head()->push_back($3); }
- ;
+ expr { Select->expr_list.head()->push_back($1); }
+ | expr_list2 ',' expr { Select->expr_list.head()->push_back($3); };
+
+ident_list_arg:
+ ident_list { $$= $1; }
+ | '(' ident_list ')' { $$= $2; };
ident_list:
- { Lex->expr_list.push_front(new List<Item>); }
+ { Select->expr_list.push_front(new List<Item>); }
ident_list2
- { $$= Lex->expr_list.pop(); }
- ;
+ { $$= Select->expr_list.pop(); };
ident_list2:
- simple_ident { Lex->expr_list.head()->push_back($1); }
- | ident_list2 ',' simple_ident { Lex->expr_list.head()->push_back($3); }
- ;
+ simple_ident { Select->expr_list.head()->push_back($1); }
+ | ident_list2 ',' simple_ident { Select->expr_list.head()->push_back($3); };
opt_expr:
/* empty */ { $$= NULL; }
- | expr { $$= $1; }
- ;
+ | expr { $$= $1; };
opt_else:
/* empty */ { $$= NULL; }
- | ELSE expr { $$= $2; }
- ;
+ | ELSE expr { $$= $2; };
when_list:
- { Lex->when_list.push_front(new List<Item>); }
+ { Select->when_list.push_front(new List<Item>); }
when_list2
- { $$= Lex->when_list.pop(); }
- ;
+ { $$= Select->when_list.pop(); };
when_list2:
expr THEN_SYM expr
{
- Lex->when_list.head()->push_back($1);
- Lex->when_list.head()->push_back($3);
+ SELECT_LEX *sel=Select;
+ sel->when_list.head()->push_back($1);
+ sel->when_list.head()->push_back($3);
}
| when_list2 WHEN_SYM expr THEN_SYM expr
{
- Lex->when_list.head()->push_back($3);
- Lex->when_list.head()->push_back($5);
- }
- ;
+ SELECT_LEX *sel=Select;
+ sel->when_list.head()->push_back($3);
+ sel->when_list.head()->push_back($5);
+ };
opt_pad:
/* empty */ { $$=new Item_string(" ",1); }
- | expr { $$=$1; }
- ;
+ | expr { $$=$1; };
join_table_list:
'(' join_table_list ')' { $$=$2; }
| join_table { $$=$1; }
- | join_table_list normal_join join_table { $$=$3; }
- | join_table_list STRAIGHT_JOIN join_table { $$=$3 ; $$->straight=1; }
- | join_table_list INNER_SYM JOIN_SYM join_table ON expr
- { add_join_on($4,$6); $$=$4; }
- | join_table_list INNER_SYM JOIN_SYM join_table
- { Lex->db1=$1->db; Lex->table1=$1->alias;
- Lex->db2=$4->db; Lex->table2=$4->alias; }
- USING '(' using_list ')'
- { add_join_on($4,$8); $$=$4; }
- | join_table_list LEFT opt_outer JOIN_SYM join_table ON expr
+ | join_table_list ',' join_table_list { $$=$3; }
+ | join_table_list normal_join join_table_list { $$=$3; }
+ | join_table_list STRAIGHT_JOIN join_table_list
+ { $$=$3 ; $1->next->straight=1; }
+ | join_table_list normal_join join_table_list ON expr
+ { add_join_on($3,$5); $$=$3; }
+ | join_table_list normal_join join_table_list
+ USING
+ {
+ SELECT_LEX *sel=Select;
+ sel->db1=$1->db; sel->table1=$1->alias;
+ sel->db2=$3->db; sel->table2=$3->alias;
+ }
+ '(' using_list ')'
+ { add_join_on($3,$7); $$=$3; }
+
+ | join_table_list LEFT opt_outer JOIN_SYM join_table_list ON expr
{ add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
- | join_table_list LEFT opt_outer JOIN_SYM join_table
- { Lex->db1=$1->db; Lex->table1=$1->alias;
- Lex->db2=$5->db; Lex->table2=$5->alias; }
+ | join_table_list LEFT opt_outer JOIN_SYM join_table_list
+ {
+ SELECT_LEX *sel=Select;
+ sel->db1=$1->db; sel->table1=$1->alias;
+ sel->db2=$5->db; sel->table2=$5->alias;
+ }
USING '(' using_list ')'
{ add_join_on($5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
- | join_table_list NATURAL LEFT opt_outer JOIN_SYM join_table
- { add_join_natural($1,$6); $6->outer_join|=JOIN_TYPE_LEFT; $$=$6; }
- | join_table_list RIGHT opt_outer JOIN_SYM join_table ON expr
- { add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; }
- | join_table_list RIGHT opt_outer JOIN_SYM join_table
- { Lex->db1=$1->db; Lex->table1=$1->alias;
- Lex->db2=$5->db; Lex->table2=$5->alias; }
+ | join_table_list NATURAL LEFT opt_outer JOIN_SYM join_table_list
+ {
+ add_join_natural($1,$1->next);
+ $1->next->outer_join|=JOIN_TYPE_LEFT;
+ $$=$6;
+ }
+ | join_table_list RIGHT opt_outer JOIN_SYM join_table_list ON expr
+ { add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$5; }
+ | join_table_list RIGHT opt_outer JOIN_SYM join_table_list
+ {
+ SELECT_LEX *sel=Select;
+ sel->db1=$1->db; sel->table1=$1->alias;
+ sel->db2=$5->db; sel->table2=$5->alias;
+ }
USING '(' using_list ')'
- { add_join_on($1,$9); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; }
- | join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table
- { add_join_natural($6,$1); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; }
- | join_table_list NATURAL JOIN_SYM join_table
- { add_join_natural($1,$4); $$=$4; }
- ;
+ { add_join_on($1,$9); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$5; }
+ | join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table_list
+ {
+ add_join_natural($1->next,$1);
+ $1->outer_join|=JOIN_TYPE_RIGHT;
+ $$=$6;
+ }
+ | join_table_list NATURAL JOIN_SYM join_table_list
+ { add_join_natural($1,$1->next); $$=$4; };
normal_join:
- ',' {}
- | JOIN_SYM {}
- | CROSS JOIN_SYM {}
+ JOIN_SYM {}
+ | INNER_SYM JOIN_SYM {}
+ | CROSS JOIN_SYM {}
;
join_table:
- { Lex->use_index_ptr=Lex->ignore_index_ptr=0; }
+ {
+ SELECT_LEX *sel=Select;
+ sel->use_index_ptr=sel->ignore_index_ptr=0;
+ sel->table_join_options= 0;
+ }
table_ident opt_table_alias opt_key_definition
- { if (!($$=add_table_to_list($2,$3,0,TL_UNLOCK, Lex->use_index_ptr,
- Lex->ignore_index_ptr))) YYABORT; }
+ {
+ SELECT_LEX *sel=Select;
+ if (!($$=add_table_to_list($2, $3, sel->table_join_options,
+ TL_UNLOCK, sel->use_index_ptr,
+ sel->ignore_index_ptr)))
+ YYABORT;
+ }
| '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}'
- { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; }
- ;
+ { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; };
opt_outer:
/* empty */ {}
- | OUTER {}
- ;
+ | OUTER {};
opt_key_definition:
/* empty */ {}
| USE_SYM key_usage_list
- { Lex->use_index= *$2; Lex->use_index_ptr= &Lex->use_index; }
+ {
+ SELECT_LEX *sel=Select;
+ sel->use_index= *$2;
+ sel->use_index_ptr= &sel->use_index;
+ }
+ | FORCE_SYM key_usage_list
+ {
+ SELECT_LEX *sel=Select;
+ sel->use_index= *$2;
+ sel->use_index_ptr= &sel->use_index;
+ sel->table_join_options|= TL_OPTION_FORCE_INDEX;
+ }
| IGNORE_SYM key_usage_list
- { Lex->ignore_index= *$2; Lex->ignore_index_ptr= &Lex->ignore_index;}
+ {
+ SELECT_LEX *sel=Select;
+ sel->ignore_index= *$2;
+ sel->ignore_index_ptr= &sel->ignore_index;
+ }
;
key_usage_list:
- key_or_index { Lex->interval_list.empty(); } '(' key_usage_list2 ')'
- { $$= &Lex->interval_list; }
- ;
+ key_or_index { Select->interval_list.empty(); } '(' key_usage_list2 ')'
+ { $$= &Select->interval_list; };
key_usage_list2:
key_usage_list2 ',' ident
- { Lex->interval_list.push_back(new String((const char*) $3.str,$3.length)); }
+ { Select->interval_list.push_back(new String((const char*) $3.str,$3.length)); }
| ident
- { Lex->interval_list.push_back(new String((const char*) $1.str,$1.length)); }
+ { Select->interval_list.push_back(new String((const char*) $1.str,$1.length)); }
| PRIMARY_SYM
- { Lex->interval_list.push_back(new String("PRIMARY",7)); }
- ;
+ { Select->interval_list.push_back(new String("PRIMARY",7)); };
using_list:
ident
- { if (!($$= new Item_func_eq(new Item_field(Lex->db1,Lex->table1, $1.str), new Item_field(Lex->db2,Lex->table2,$1.str))))
+ {
+ SELECT_LEX *sel=Select;
+ if (!($$= new Item_func_eq(new Item_field(sel->db1,sel->table1, $1.str), new Item_field(sel->db2,sel->table2,$1.str))))
YYABORT;
}
| using_list ',' ident
{
- if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(Lex->db1,Lex->table1,$3.str), new Item_field(Lex->db2,Lex->table2,$3.str)), $1)))
+ SELECT_LEX *sel=Select;
+ if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(sel->db1,sel->table1,$3.str), new Item_field(sel->db2,sel->table2,$3.str)), $1)))
YYABORT;
- }
- ;
+ };
interval:
DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; }
@@ -1962,36 +2291,49 @@ interval:
| MONTH_SYM { $$=INTERVAL_MONTH; }
| SECOND_SYM { $$=INTERVAL_SECOND; }
| YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; }
- | YEAR_SYM { $$=INTERVAL_YEAR; }
- ;
+ | YEAR_SYM { $$=INTERVAL_YEAR; };
table_alias:
/* empty */
| AS
- | EQ
- ;
+ | EQ;
opt_table_alias:
/* empty */ { $$=0; }
| table_alias ident
- { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); }
+ { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); };
+
+opt_all:
+ /* empty */
+ | ALL
;
where_clause:
- /* empty */ { Lex->where= 0; }
- | WHERE expr { Lex->where= $2; }
- ;
+ /* empty */ { Select->where= 0; }
+ | WHERE expr
+ {
+ Select->where= $2;
+ if ($2)
+ $2->top_level_item();
+ }
+ ;
having_clause:
/* empty */
- | HAVING { Lex->create_refs=1; } expr
- { Lex->having= $3; Lex->create_refs=0; }
+ | HAVING { Select->create_refs=1; } expr
+ {
+ SELECT_LEX *sel=Select;
+ sel->having= $3;
+ sel->create_refs=0;
+ if ($3)
+ $3->top_level_item();
+ }
;
opt_escape:
ESCAPE_SYM TEXT_STRING { $$= $2.str; }
- | /* empty */ { $$= (char*) "\\"; }
- ;
+ | /* empty */ { $$= (char*) "\\"; };
+
/*
group by statement in select
@@ -1999,14 +2341,28 @@ opt_escape:
group_clause:
/* empty */
- | GROUP BY group_list
- ;
+ | GROUP BY group_list olap_opt;
group_list:
group_list ',' order_ident order_dir
{ if (add_group_to_list($3,(bool) $4)) YYABORT; }
| order_ident order_dir
- { if (add_group_to_list($1,(bool) $2)) YYABORT; }
+ { if (add_group_to_list($1,(bool) $2)) YYABORT; };
+
+olap_opt:
+ /* empty */ {}
+ | WITH CUBE_SYM
+ {
+ LEX *lex=Lex;
+ net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "CUBE");
+ YYABORT; /* To be deleted in 4.1 */
+ }
+ | WITH ROLLUP_SYM
+ {
+ LEX *lex=Lex;
+ net_printf(&lex->thd->net, ER_NOT_SUPPORTED_YET, "ROLLUP");
+ YYABORT; /* To be deleted in 4.1 */
+ }
;
/*
@@ -2015,59 +2371,93 @@ group_list:
opt_order_clause:
/* empty */
- | order_clause
- ;
+ | order_clause;
order_clause:
- ORDER_SYM BY order_list
- ;
+ ORDER_SYM BY
+ {
+ LEX *lex=Lex;
+ if (lex->select->olap != UNSPECIFIED_OLAP_TYPE)
+ {
+ net_printf(&lex->thd->net, ER_WRONG_USAGE,
+ "CUBE/ROLLUP",
+ "ORDER BY");
+ YYABORT;
+ }
+ lex->select->sort_default=1;
+ } order_list;
order_list:
order_list ',' order_ident order_dir
{ if (add_order_to_list($3,(bool) $4)) YYABORT; }
| order_ident order_dir
- { if (add_order_to_list($1,(bool) $2)) YYABORT; }
- ;
+ { if (add_order_to_list($1,(bool) $2)) YYABORT; };
order_dir:
/* empty */ { $$ = 1; }
| ASC { $$ =1; }
- | DESC { $$ =0; }
- ;
+ | DESC { $$ =0; };
+
limit_clause:
- /* empty */
- {
- Lex->select_limit= current_thd->default_select_limit;
- Lex->offset_limit= 0L;
- }
- | LIMIT ULONG_NUM
- { Lex->select_limit= $2; Lex->offset_limit=0L; }
- | LIMIT ULONG_NUM ',' ULONG_NUM
- { Lex->select_limit= $4; Lex->offset_limit=$2; }
+ /* empty */ {}
+ | LIMIT
+ {
+ LEX *lex=Lex;
+ if (lex->select->olap != UNSPECIFIED_OLAP_TYPE)
+ {
+ net_printf(&lex->thd->net, ER_WRONG_USAGE, "CUBE/ROLLUP",
+ "LIMIT");
+ YYABORT;
+ }
+ }
+ limit_options
+ {}
+ ;
+
+limit_options:
+ ULONG_NUM
+ {
+ SELECT_LEX *sel= Select;
+ sel->select_limit= $1;
+ sel->offset_limit= 0L;
+ }
+ | ULONG_NUM ',' ULONG_NUM
+ {
+ SELECT_LEX *sel= Select;
+ sel->select_limit= $3;
+ sel->offset_limit= $1;
+ }
+ | ULONG_NUM OFFSET_SYM ULONG_NUM
+ {
+ SELECT_LEX *sel= Select;
+ sel->select_limit= $1;
+ sel->offset_limit= $3;
+ }
;
delete_limit_clause:
/* empty */
{
- Lex->select_limit= HA_POS_ERROR;
+ LEX *lex=Lex;
+ lex->select->select_limit= HA_POS_ERROR;
}
- | LIMIT ULONGLONG_NUM
- { Lex->select_limit= (ha_rows) $2; }
- ;
+ | LIMIT ulonglong_num
+ { Select->select_limit= (ha_rows) $2; };
ULONG_NUM:
- NUM { $$= strtoul($1.str,NULL,10); }
- | REAL_NUM { $$= strtoul($1.str,NULL,10); }
- | FLOAT_NUM { $$= strtoul($1.str,NULL,10); }
- ;
-
-ULONGLONG_NUM:
- NUM { $$= (ulonglong) strtoul($1.str,NULL,10); }
- | LONG_NUM { $$= strtoull($1.str,NULL,10); }
- | REAL_NUM { $$= strtoull($1.str,NULL,10); }
- | FLOAT_NUM { $$= strtoull($1.str,NULL,10); }
- ;
+ NUM { $$= strtoul($1.str,NULL,10); }
+ | LONG_NUM { $$= (ulong) strtoll($1.str,NULL,10); }
+ | ULONGLONG_NUM { $$= (ulong) strtoull($1.str,NULL,10); }
+ | REAL_NUM { $$= strtoul($1.str,NULL,10); }
+ | FLOAT_NUM { $$= strtoul($1.str,NULL,10); };
+
+ulonglong_num:
+ NUM { $$= (ulonglong) strtoul($1.str,NULL,10); }
+ | ULONGLONG_NUM { $$= strtoull($1.str,NULL,10); }
+ | LONG_NUM { $$= (ulonglong) strtoll($1.str,NULL,10); }
+ | REAL_NUM { $$= strtoull($1.str,NULL,10); }
+ | FLOAT_NUM { $$= strtoull($1.str,NULL,10); };
procedure_clause:
/* empty */
@@ -2077,45 +2467,47 @@ procedure_clause:
lex->proc_list.elements=0;
lex->proc_list.first=0;
lex->proc_list.next= (byte**) &lex->proc_list.first;
- if (add_proc_to_list(new Item_field(NULL,NULL,$2.str)))
+ if (add_proc_to_list(lex->thd, new Item_field(NULL,NULL,$2.str)))
YYABORT;
+ current_thd->safe_to_cache_query=0;
}
- '(' procedure_list ')'
- ;
+ '(' procedure_list ')';
+
procedure_list:
/* empty */ {}
- | procedure_list2 {}
- ;
+ | procedure_list2 {};
procedure_list2:
procedure_list2 ',' procedure_item
- | procedure_item
- ;
+ | procedure_item;
procedure_item:
remember_name expr
{
- if (add_proc_to_list($2))
+ LEX *lex= Lex;
+ if (add_proc_to_list(lex->thd, $2))
YYABORT;
if (!$2->name)
- $2->set_name($1,(uint) ((char*) Lex->tok_end - $1));
- }
- ;
+ $2->set_name($1,(uint) ((char*) lex->tok_end - $1));
+ };
opt_into:
INTO OUTFILE TEXT_STRING
{
- if (!(Lex->exchange= new sql_exchange($3.str,0)))
+ THD *thd= current_thd;
+ thd->safe_to_cache_query= 0;
+ if (!(thd->lex.exchange= new sql_exchange($3.str,0)))
YYABORT;
}
opt_field_term opt_line_term
| INTO DUMPFILE TEXT_STRING
{
- if (!(Lex->exchange= new sql_exchange($3.str,1)))
+ THD *thd= current_thd;
+ thd->safe_to_cache_query= 0;
+ if (!(thd->lex.exchange= new sql_exchange($3.str,1)))
YYABORT;
- }
- ;
+ };
/*
DO statement
@@ -2137,147 +2529,165 @@ do: DO_SYM
*/
drop:
- DROP TABLE_SYM if_exists table_list opt_restrict
+ DROP opt_temporary TABLE_SYM if_exists table_list opt_restrict
{
- Lex->sql_command = SQLCOM_DROP_TABLE;
- Lex->drop_if_exists = $3;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_DROP_TABLE;
+ lex->drop_temporary= $2;
+ lex->drop_if_exists= $4;
}
| DROP INDEX ident ON table_ident {}
{
- Lex->sql_command= SQLCOM_DROP_INDEX;
- Lex->drop_list.empty();
- Lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_DROP_INDEX;
+ lex->drop_list.empty();
+ lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
$3.str));
- if (!add_table_to_list($5,NULL, 1))
+ if (!add_table_to_list($5, NULL, TL_OPTION_UPDATING))
YYABORT;
}
| DROP DATABASE if_exists ident
{
- Lex->sql_command= SQLCOM_DROP_DB;
- Lex->drop_if_exists=$3;
- Lex->name=$4.str;
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_DROP_DB;
+ lex->drop_if_exists=$3;
+ lex->name=$4.str;
}
| DROP UDF_SYM ident
{
- Lex->sql_command = SQLCOM_DROP_FUNCTION;
- Lex->udf.name=$3.str;
- }
- ;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_DROP_FUNCTION;
+ lex->udf.name=$3.str;
+ };
+
table_list:
- table
- | table_list ',' table
- ;
+ table_name
+ | table_list ',' table_name;
-table:
+table_name:
table_ident
- { if (!add_table_to_list($1,NULL,1)) YYABORT; }
- ;
+ { if (!add_table_to_list($1,NULL,TL_OPTION_UPDATING)) YYABORT; };
if_exists:
- /* empty */ { $$=0; }
+ /* empty */ { $$= 0; }
| IF EXISTS { $$= 1; }
;
+opt_temporary:
+ /* empty */ { $$= 0; }
+ | TEMPORARY { $$= 1; }
+ ;
/*
** Insert : add new data to table
*/
insert:
- INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option opt_ignore insert2 insert_field_spec
+ INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option
+ opt_ignore insert2
+ {
+ set_lock_for_tables($3);
+ Lex->select= &Lex->select_lex;
+ }
+ insert_field_spec
{}
;
replace:
- REPLACE { Lex->sql_command = SQLCOM_REPLACE; } replace_lock_option insert2 insert_field_spec
+ REPLACE
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_REPLACE;
+ lex->duplicates= DUP_REPLACE;
+ }
+ replace_lock_option insert2
+ {
+ set_lock_for_tables($3);
+ Lex->select= &Lex->select_lex;
+ }
+ insert_field_spec
{}
;
insert_lock_option:
- /* empty */ { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT; }
- | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
- | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; }
- | HIGH_PRIORITY { Lex->lock_option= TL_WRITE; }
+ /* empty */ { $$= TL_WRITE_CONCURRENT_INSERT; }
+ | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
+ | DELAYED_SYM { $$= TL_WRITE_DELAYED; }
+ | HIGH_PRIORITY { $$= TL_WRITE; }
;
replace_lock_option:
- opt_low_priority {}
- | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; }
- ;
+ opt_low_priority { $$= $1; }
+ | DELAYED_SYM { $$= TL_WRITE_DELAYED; };
insert2:
INTO insert_table {}
- | insert_table {}
- ;
+ | insert_table {};
insert_table:
- table
+ table_name
{
- Lex->field_list.empty();
- Lex->many_values.empty();
- Lex->insert_list=0;
- }
- ;
+ LEX *lex=Lex;
+ lex->field_list.empty();
+ lex->many_values.empty();
+ lex->insert_list=0;
+ };
insert_field_spec:
- opt_field_spec insert_values {}
+ insert_values {}
+ | '(' ')' insert_values {}
+ | '(' fields ')' insert_values {}
| SET
{
- if (!(Lex->insert_list = new List_item) ||
- Lex->many_values.push_back(Lex->insert_list))
+ LEX *lex=Lex;
+ if (!(lex->insert_list = new List_item) ||
+ lex->many_values.push_back(lex->insert_list))
YYABORT;
}
- ident_eq_list
- ;
+ ident_eq_list;
opt_field_spec:
/* empty */ { }
| '(' fields ')' { }
- | '(' ')' { }
- ;
+ | '(' ')' { };
fields:
fields ',' insert_ident { Lex->field_list.push_back($3); }
- | insert_ident { Lex->field_list.push_back($1); }
- ;
+ | insert_ident { Lex->field_list.push_back($1); };
insert_values:
VALUES values_list {}
- | SELECT_SYM
- {
- LEX *lex=Lex;
- lex->sql_command = (lex->sql_command == SQLCOM_INSERT ?
- SQLCOM_INSERT_SELECT : SQLCOM_REPLACE_SELECT);
- lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
- mysql_init_select(lex);
- }
- select_options select_item_list select_from select_lock_type {}
- ;
+ | create_select { Select->braces= 0;} opt_union {}
+ | '(' create_select ')' { Select->braces= 1;} union_opt {}
+ ;
values_list:
values_list ',' no_braces
- | no_braces
- ;
+ | no_braces;
ident_eq_list:
ident_eq_list ',' ident_eq_value
|
- ident_eq_value
- ;
+ ident_eq_value;
ident_eq_value:
- simple_ident equal expr
+ simple_ident equal expr_or_default
{
- if (Lex->field_list.push_back($1) ||
- Lex->insert_list->push_back($3))
+ LEX *lex=Lex;
+ if (lex->field_list.push_back($1) ||
+ lex->insert_list->push_back($3))
YYABORT;
- }
- ;
+ };
equal: EQ {}
| SET_VAR {}
;
+opt_equal:
+ /* empty */ {}
+ | equal {}
+ ;
+
no_braces:
'('
{
@@ -2286,34 +2696,49 @@ no_braces:
}
opt_values ')'
{
- if (Lex->many_values.push_back(Lex->insert_list))
+ LEX *lex=Lex;
+ if (lex->many_values.push_back(lex->insert_list))
YYABORT;
- }
- ;
+ };
opt_values:
/* empty */ {}
- | values
- ;
+ | values;
values:
- values ',' expr
+ values ',' expr_or_default
{
if (Lex->insert_list->push_back($3))
YYABORT;
}
- | expr
- {
- if (Lex->insert_list->push_back($1))
- YYABORT;
- }
+ | expr_or_default
+ {
+ if (Lex->insert_list->push_back($1))
+ YYABORT;
+ }
+ ;
+
+expr_or_default:
+ expr { $$= $1;}
+ | DEFAULT {$$= new Item_default(); }
;
/* Update rows in a table */
update:
- UPDATE_SYM opt_low_priority opt_ignore table SET update_list where_clause delete_limit_clause
- { Lex->sql_command = SQLCOM_UPDATE; }
+ UPDATE_SYM
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_UPDATE;
+ lex->select->order_list.elements=0;
+ lex->select->order_list.first=0;
+ lex->select->order_list.next= (byte**) &lex->select->order_list.first;
+ }
+ opt_low_priority opt_ignore join_table_list
+ SET update_list where_clause opt_order_clause delete_limit_clause
+ {
+ set_lock_for_tables($3);
+ }
;
update_list:
@@ -2326,48 +2751,94 @@ update_list:
{
if (add_item_to_list($1) || add_value_to_list($3))
YYABORT;
- }
- ;
+ };
opt_low_priority:
- /* empty */ { Lex->lock_option= current_thd->update_lock_default; }
- | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
- ;
+ /* empty */ { $$= current_thd->update_lock_default; }
+ | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; };
/* Delete rows from a table */
delete:
DELETE_SYM
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_DELETE; lex->select->options=0;
+ lex->lock_option= lex->thd->update_lock_default;
+ lex->select->order_list.elements=0;
+ lex->select->order_list.first=0;
+ lex->select->order_list.next= (byte**) &lex->select->order_list.first;
+ }
+ opt_delete_options single_multi {}
+ ;
+
+single_multi:
+ FROM table_ident
{
- Lex->sql_command= SQLCOM_DELETE; Lex->options=0;
- Lex->lock_option= current_thd->update_lock_default;
+ if (!add_table_to_list($2, NULL, TL_OPTION_UPDATING,
+ Lex->lock_option))
+ YYABORT;
}
- opt_delete_options FROM table
- where_clause delete_limit_clause
- {}
+ where_clause opt_order_clause
+ delete_limit_clause {}
+ | table_wild_list
+ { mysql_init_multi_delete(Lex); }
+ FROM join_table_list where_clause
+ | FROM table_wild_list
+ { mysql_init_multi_delete(Lex); }
+ USING join_table_list where_clause
+ {}
+ ;
+
+table_wild_list:
+ table_wild_one {}
+ | table_wild_list ',' table_wild_one {};
+
+table_wild_one:
+ ident opt_wild
+ {
+ if (!add_table_to_list(new Table_ident($1), NULL,
+ TL_OPTION_UPDATING, Lex->lock_option))
+ YYABORT;
+ }
+ | ident '.' ident opt_wild
+ {
+ if (!add_table_to_list(new Table_ident($1,$3,0), NULL,
+ TL_OPTION_UPDATING,
+ Lex->lock_option))
+ YYABORT;
+ }
;
+opt_wild:
+ /* empty */ {}
+ | '.' '*' {};
+
+
opt_delete_options:
- /* empty */ {}
- | opt_delete_option opt_delete_options {}
- ;
+ /* empty */ {}
+ | opt_delete_option opt_delete_options {};
opt_delete_option:
- QUICK { Lex->options|= OPTION_QUICK; }
- | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
- ;
+ QUICK { Select->options|= OPTION_QUICK; }
+ | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; };
truncate:
- TRUNCATE_SYM opt_table_sym table
- { Lex->sql_command= SQLCOM_TRUNCATE; Lex->options=0;
- Lex->lock_option= current_thd->update_lock_default; }
+ TRUNCATE_SYM opt_table_sym table_name
+ {
+ LEX* lex = Lex;
+ lex->sql_command= SQLCOM_TRUNCATE;
+ lex->select->options=0;
+ lex->select->order_list.elements=0;
+ lex->select->order_list.first=0;
+ lex->select->order_list.next= (byte**) &lex->select->order_list.first;
+ }
;
opt_table_sym:
/* empty */
- | TABLE_SYM
- ;
-
+ | TABLE_SYM;
+
/* Show things */
show: SHOW { Lex->wild=0;} show_param
@@ -2378,35 +2849,64 @@ show_param:
DATABASES wild
{ Lex->sql_command= SQLCOM_SHOW_DATABASES; }
| TABLES opt_db wild
- { Lex->sql_command= SQLCOM_SHOW_TABLES; Lex->db= $2; Lex->options=0;}
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_SHOW_TABLES;
+ lex->select->db= $2; lex->select->options=0;
+ }
| TABLE_SYM STATUS_SYM opt_db wild
- { Lex->sql_command= SQLCOM_SHOW_TABLES;
- Lex->options|= SELECT_DESCRIBE;
- Lex->db= $3;
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_SHOW_TABLES;
+ lex->select->options|= SELECT_DESCRIBE;
+ lex->select->db= $3;
}
| OPEN_SYM TABLES opt_db wild
- { Lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
- Lex->db= $3;
- Lex->options=0;
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
+ lex->select->db= $3;
+ lex->select->options=0;
}
- | opt_full COLUMNS FROM table_ident opt_db wild
+ | opt_full COLUMNS from_or_in table_ident opt_db wild
{
Lex->sql_command= SQLCOM_SHOW_FIELDS;
if ($5)
$4->change_db($5);
- if (!add_table_to_list($4,NULL,0))
+ if (!add_table_to_list($4, NULL, 0))
YYABORT;
}
+ | NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
+ TEXT_STRING AND MASTER_LOG_POS_SYM EQ ulonglong_num
+ AND MASTER_SERVER_ID_SYM EQ
+ ULONG_NUM
+ {
+ Lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
+ Lex->mi.log_file_name = $8.str;
+ Lex->mi.pos = $12;
+ Lex->mi.server_id = $16;
+ }
| MASTER_SYM LOGS_SYM
{
Lex->sql_command = SQLCOM_SHOW_BINLOGS;
- }
+ }
+ | SLAVE HOSTS_SYM
+ {
+ Lex->sql_command = SQLCOM_SHOW_SLAVE_HOSTS;
+ }
+ | BINLOG_SYM EVENTS_SYM binlog_in binlog_from
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_SHOW_BINLOG_EVENTS;
+ lex->select->select_limit= lex->thd->variables.select_limit;
+ lex->select->offset_limit= 0L;
+ } limit_clause
| keys_or_index FROM table_ident opt_db
{
Lex->sql_command= SQLCOM_SHOW_KEYS;
if ($4)
$3->change_db($4);
- if (!add_table_to_list($3,NULL,0))
+ if (!add_table_to_list($3, NULL, 0))
YYABORT;
}
| STATUS_SYM wild
@@ -2415,17 +2915,25 @@ show_param:
{ Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS;}
| opt_full PROCESSLIST_SYM
{ Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;}
- | VARIABLES wild
- { Lex->sql_command= SQLCOM_SHOW_VARIABLES; }
+ | opt_var_type VARIABLES wild
+ {
+ THD *thd= current_thd;
+ thd->lex.sql_command= SQLCOM_SHOW_VARIABLES;
+ thd->lex.option_type= (enum_var_type) $1;
+ }
| LOGS_SYM
{ Lex->sql_command= SQLCOM_SHOW_LOGS; }
| GRANTS FOR_SYM user
- { Lex->sql_command= SQLCOM_SHOW_GRANTS;
- Lex->grant_user=$3; Lex->grant_user->password.str=NullS; }
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_SHOW_GRANTS;
+ lex->grant_user=$3;
+ lex->grant_user->password.str=NullS;
+ }
| CREATE TABLE_SYM table_ident
{
Lex->sql_command = SQLCOM_SHOW_CREATE;
- if(!add_table_to_list($3, NULL,0))
+ if(!add_table_to_list($3, NULL, 0))
YYABORT;
}
| MASTER_SYM STATUS_SYM
@@ -2435,211 +2943,235 @@ show_param:
| SLAVE STATUS_SYM
{
Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
- }
- ;
+ };
opt_db:
/* empty */ { $$= 0; }
- | FROM ident { $$= $2.str; }
- ;
+ | from_or_in ident { $$= $2.str; };
wild:
/* empty */
- | LIKE text_string { Lex->wild= $2; }
- ;
+ | LIKE text_string { Lex->wild= $2; };
opt_full:
/* empty */ { Lex->verbose=0; }
- | FULL { Lex->verbose=1; }
- ;
+ | FULL { Lex->verbose=1; };
+
+from_or_in:
+ FROM
+ | IN_SYM;
+
+binlog_in:
+ /* empty */ { Lex->mi.log_file_name = 0; }
+ | IN_SYM TEXT_STRING { Lex->mi.log_file_name = $2.str; };
+
+binlog_from:
+ /* empty */ { Lex->mi.pos = 4; /* skip magic number */ }
+ | FROM ulonglong_num { Lex->mi.pos = $2; };
+
/* A Oracle compatible synonym for show */
describe:
describe_command table_ident
{
- Lex->wild=0;
- Lex->verbose=0;
- Lex->sql_command=SQLCOM_SHOW_FIELDS;
- if (!add_table_to_list($2, NULL,0))
+ LEX *lex=Lex;
+ lex->wild=0;
+ lex->verbose=0;
+ lex->sql_command=SQLCOM_SHOW_FIELDS;
+ if (!add_table_to_list($2, NULL, 0))
YYABORT;
}
opt_describe_column {}
- | describe_command select { Lex->options|= SELECT_DESCRIBE; }
- ;
+ | describe_command select
+ { Lex->select_lex.options|= SELECT_DESCRIBE; };
+
describe_command:
DESC
- | DESCRIBE
- ;
+ | DESCRIBE;
opt_describe_column:
/* empty */ {}
| text_string { Lex->wild= $1; }
- | ident { Lex->wild= new String((const char*) $1.str,$1.length); }
- ;
+ | ident
+ { Lex->wild= new String((const char*) $1.str,$1.length); };
+
/* flush things */
flush:
- FLUSH_SYM {Lex->sql_command= SQLCOM_FLUSH; Lex->type=0; } flush_options
+ FLUSH_SYM
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_FLUSH; lex->type=0;
+ }
+ flush_options
{}
;
flush_options:
flush_options ',' flush_option
- | flush_option
- ;
+ | flush_option;
flush_option:
table_or_tables { Lex->type|= REFRESH_TABLES; } opt_table_list {}
| TABLES WITH READ_SYM LOCK_SYM { Lex->type|= REFRESH_TABLES | REFRESH_READ_LOCK; }
+ | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE_FREE; }
| HOSTS_SYM { Lex->type|= REFRESH_HOSTS; }
| PRIVILEGES { Lex->type|= REFRESH_GRANT; }
| LOGS_SYM { Lex->type|= REFRESH_LOG; }
| STATUS_SYM { Lex->type|= REFRESH_STATUS; }
| SLAVE { Lex->type|= REFRESH_SLAVE; }
| MASTER_SYM { Lex->type|= REFRESH_MASTER; }
- ;
+ | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; }
+ | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; };
opt_table_list:
- /* empty */ {}
- | table_list {}
- ;
+ /* empty */ {;}
+ | table_list {;};
reset:
- RESET_SYM {Lex->sql_command= SQLCOM_RESET; Lex->type=0; } reset_options
+ RESET_SYM
+ {
+ LEX *lex=Lex;
+ lex->sql_command= SQLCOM_RESET; lex->type=0;
+ } reset_options
{}
;
reset_options:
reset_options ',' reset_option
- | reset_option
- ;
+ | reset_option;
reset_option:
- SLAVE { Lex->type|= REFRESH_SLAVE; }
- | MASTER_SYM { Lex->type|= REFRESH_MASTER; }
- ;
+ SLAVE { Lex->type|= REFRESH_SLAVE; }
+ | MASTER_SYM { Lex->type|= REFRESH_MASTER; }
+ | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;};
purge:
- PURGE { Lex->sql_command = SQLCOM_PURGE; Lex->type=0;}
+ PURGE
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_PURGE;
+ lex->type=0;
+ }
MASTER_SYM LOGS_SYM TO_SYM TEXT_STRING
{
Lex->to_log = $6.str;
- }
- ;
+ } ;
/* kill threads */
kill:
KILL_SYM expr
{
- if ($2->fix_fields(current_thd,0))
- {
- send_error(&current_thd->net, ER_SET_CONSTANTS_ONLY);
- YYABORT;
- }
- Lex->sql_command=SQLCOM_KILL;
- Lex->thread_id= (ulong) $2->val_int();
- }
- ;
+ LEX *lex=Lex;
+ if ($2->fix_fields(lex->thd,0))
+ {
+ send_error(&lex->thd->net, ER_SET_CONSTANTS_ONLY);
+ YYABORT;
+ }
+ lex->sql_command=SQLCOM_KILL;
+ lex->thread_id= (ulong) $2->val_int();
+ };
/* change database */
use: USE_SYM ident
- { Lex->sql_command=SQLCOM_CHANGE_DB; Lex->db= $2.str; }
- ;
+ {
+ LEX *lex=Lex;
+ lex->sql_command=SQLCOM_CHANGE_DB; lex->select->db= $2.str;
+ };
/* import, export of files */
load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING
{
- LEX *lex= Lex;
+ LEX *lex=Lex;
lex->sql_command= SQLCOM_LOAD;
- lex->local_file= $4;
- if (!(Lex->exchange= new sql_exchange($6.str,0)))
+ lex->lock_option= $3;
+ lex->local_file= $4;
+ if (!(lex->exchange= new sql_exchange($6.str,0)))
YYABORT;
- Lex->field_list.empty();
+ lex->field_list.empty();
}
opt_duplicate INTO TABLE_SYM table_ident opt_field_term opt_line_term
opt_ignore_lines opt_field_spec
{
- if (!add_table_to_list($11,NULL,1))
+ if (!add_table_to_list($11, NULL, TL_OPTION_UPDATING))
YYABORT;
}
|
LOAD TABLE_SYM table_ident FROM MASTER_SYM
{
Lex->sql_command = SQLCOM_LOAD_MASTER_TABLE;
- if (!add_table_to_list($3,NULL,1))
+ if (!add_table_to_list($3, NULL, TL_OPTION_UPDATING))
YYABORT;
}
- ;
+ |
+ LOAD DATA_SYM FROM MASTER_SYM
+ {
+ Lex->sql_command = SQLCOM_LOAD_MASTER_DATA;
+ };
opt_local:
/* empty */ { $$=0;}
- | LOCAL_SYM { $$=1;}
- ;
+ | LOCAL_SYM { $$=1;};
load_data_lock:
- /* empty */ { Lex->lock_option= current_thd->update_lock_default; }
- | CONCURRENT { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT ; }
- | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
- ;
+ /* empty */ { $$= current_thd->update_lock_default; }
+ | CONCURRENT { $$= TL_WRITE_CONCURRENT_INSERT ; }
+ | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; };
+
opt_duplicate:
/* empty */ { Lex->duplicates=DUP_ERROR; }
| REPLACE { Lex->duplicates=DUP_REPLACE; }
- | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }
- ;
+ | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; };
opt_field_term:
/* empty */
- | COLUMNS field_term_list
- ;
+ | COLUMNS field_term_list;
field_term_list:
field_term_list field_term
- | field_term
- ;
+ | field_term;
field_term:
TERMINATED BY text_string { Lex->exchange->field_term= $3;}
| OPTIONALLY ENCLOSED BY text_string
- { Lex->exchange->enclosed= $4; Lex->exchange->opt_enclosed=1;}
+ {
+ LEX *lex=Lex;
+ lex->exchange->enclosed= $4;
+ lex->exchange->opt_enclosed=1;
+ }
| ENCLOSED BY text_string { Lex->exchange->enclosed= $3;}
- | ESCAPED BY text_string { Lex->exchange->escaped= $3;}
- ;
+ | ESCAPED BY text_string { Lex->exchange->escaped= $3;};
opt_line_term:
/* empty */
- | LINES line_term_list
- ;
+ | LINES line_term_list;
line_term_list:
line_term_list line_term
- | line_term
- ;
+ | line_term;
line_term:
TERMINATED BY text_string { Lex->exchange->line_term= $3;}
- | STARTING BY text_string { Lex->exchange->line_start= $3;}
- ;
+ | STARTING BY text_string { Lex->exchange->line_start= $3;};
opt_ignore_lines:
/* empty */
| IGNORE_SYM NUM LINES
- { Lex->exchange->skip_lines=atol($2.str); }
- ;
+ { Lex->exchange->skip_lines=atol($2.str); };
/* Common definitions */
text_literal:
TEXT_STRING { $$ = new Item_string($1.str,$1.length); }
| text_literal TEXT_STRING
- { ((Item_string*) $1)->append($2.str,$2.length); }
- ;
+ { ((Item_string*) $1)->append($2.str,$2.length); };
text_string:
TEXT_STRING { $$= new String($1.str,$1.length); }
@@ -2647,22 +3179,21 @@ text_string:
{
Item *tmp = new Item_varbinary($1.str,$1.length);
$$= tmp ? tmp->val_str((String*) 0) : (String*) 0;
- }
- ;
+ };
literal:
text_literal { $$ = $1; }
- | NUM { $$ = new Item_int($1.str, (longlong) atol($1.str),$1.length); }
- | LONG_NUM { $$ = new Item_int($1.str); }
+ | NUM { $$ = new Item_int($1.str, (longlong) strtol($1.str, NULL, 10),$1.length); }
+ | LONG_NUM { $$ = new Item_int($1.str, (longlong) strtoll($1.str,NULL,10), $1.length); }
+ | ULONGLONG_NUM { $$ = new Item_uint($1.str, $1.length); }
| REAL_NUM { $$ = new Item_real($1.str, $1.length); }
| FLOAT_NUM { $$ = new Item_float($1.str, $1.length); }
| NULL_SYM { $$ = new Item_null();
Lex->next_state=STATE_OPERATOR_OR_IDENT;}
- | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length); }
+ | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length);}
| DATE_SYM text_literal { $$ = $2; }
| TIME_SYM text_literal { $$ = $2; }
- | TIMESTAMP text_literal { $$ = $2; }
- ;
+ | TIMESTAMP text_literal { $$ = $2; };
/**********************************************************************
** Createing different items.
@@ -2670,58 +3201,72 @@ literal:
insert_ident:
simple_ident { $$=$1; }
- | table_wild { $$=$1; }
- ;
+ | table_wild { $$=$1; };
table_wild:
ident '.' '*' { $$ = new Item_field(NullS,$1.str,"*"); }
| ident '.' ident '.' '*'
- { $$ = new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); }
- ;
+ { $$ = new Item_field((current_thd->client_capabilities &
+ CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); };
order_ident:
- expr { $$=$1; }
- ;
+ expr { $$=$1; };
simple_ident:
ident
- { $$ = !Lex->create_refs || Lex->in_sum_expr > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str); }
+ {
+ SELECT_LEX *sel=Select;
+ $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str);
+ }
| ident '.' ident
- { $$ = !Lex->create_refs || Lex->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str); }
+ {
+ SELECT_LEX *sel=Select;
+ $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str);
+ }
| '.' ident '.' ident
- { $$ = !Lex->create_refs || Lex->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str); }
+ {
+ SELECT_LEX *sel=Select;
+ $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str);
+ }
| ident '.' ident '.' ident
- { $$ = !Lex->create_refs || Lex->in_sum_expr > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); }
- ;
+ {
+ SELECT_LEX *sel=Select;
+ $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str);
+ };
+
field_ident:
ident { $$=$1;}
| ident '.' ident { $$=$3;} /* Skipp schema name in create*/
- | '.' ident { $$=$2;} /* For Delphi */
- ;
+ | '.' ident { $$=$2;} /* For Delphi */;
table_ident:
ident { $$=new Table_ident($1); }
| ident '.' ident { $$=new Table_ident($1,$3,0);}
- | '.' ident { $$=new Table_ident($2);} /* For Delphi */
- ;
+ | '.' ident { $$=new Table_ident($2);} /* For Delphi */
+ ;
+
+table_ident_ref:
+ ident { LEX_STRING db={"",0}; $$=new Table_ident(db,$1,0); }
+ | ident '.' ident { $$=new Table_ident($1,$3,0);}
+ ;
ident:
IDENT { $$=$1; }
| keyword
{
- $$.str=sql_strmake($1.str,$1.length);
+ LEX *lex= Lex;
+ $$.str= lex->thd->strmake($1.str,$1.length);
$$.length=$1.length;
- if (Lex->next_state != STATE_END)
- Lex->next_state=STATE_OPERATOR_OR_IDENT;
+ if (lex->next_state != STATE_END)
+ lex->next_state=STATE_OPERATOR_OR_IDENT;
}
;
ident_or_text:
ident { $$=$1;}
| TEXT_STRING { $$=$1;}
- | LEX_HOSTNAME { $$=$1;}
- ;
+ | LEX_HOSTNAME { $$=$1;};
user:
ident_or_text
@@ -2735,8 +3280,7 @@ user:
if (!($$=(LEX_USER*) sql_alloc(sizeof(st_lex_user))))
YYABORT;
$$->user = $1; $$->host=$3;
- }
- ;
+ };
/* Keyword that we allow for identifiers */
@@ -2745,51 +3289,68 @@ keyword:
| AFTER_SYM {}
| AGAINST {}
| AGGREGATE_SYM {}
- | AUTOCOMMIT {}
| AUTO_INC {}
| AVG_ROW_LENGTH {}
| AVG_SYM {}
| BACKUP_SYM {}
| BEGIN_SYM {}
| BERKELEY_DB_SYM {}
+ | BINLOG_SYM {}
| BIT_SYM {}
| BOOL_SYM {}
+ | BOOLEAN_SYM {}
+ | CACHE_SYM {}
| CHANGED {}
+ | CHARSET {}
| CHECKSUM_SYM {}
- | CHECK_SYM {}
+ | CIPHER_SYM {}
+ | CLIENT_SYM {}
+ | CLOSE_SYM {}
| COMMENT_SYM {}
- | COMMIT_SYM {}
| COMMITTED_SYM {}
+ | COMMIT_SYM {}
| COMPRESSED_SYM {}
| CONCURRENT {}
+ | CUBE_SYM {}
| DATA_SYM {}
| DATETIME {}
| DATE_SYM {}
| DAY_SYM {}
| DELAY_KEY_WRITE_SYM {}
+ | DES_KEY_FILE {}
+ | DIRECTORY_SYM {}
| DO_SYM {}
| DUMPFILE {}
| DYNAMIC_SYM {}
| END {}
| ENUM {}
| ESCAPE_SYM {}
+ | EVENTS_SYM {}
+ | EXECUTE_SYM {}
| EXTENDED_SYM {}
| FAST_SYM {}
+ | DISABLE_SYM {}
+ | ENABLE_SYM {}
| FULL {}
| FILE_SYM {}
| FIRST_SYM {}
| FIXED_SYM {}
| FLUSH_SYM {}
| GRANTS {}
- | GEMINI_SYM {}
| GLOBAL_SYM {}
| HEAP_SYM {}
+ | HANDLER_SYM {}
| HOSTS_SYM {}
| HOUR_SYM {}
| IDENTIFIED_SYM {}
+ | INDEXES {}
| ISOLATION {}
| ISAM_SYM {}
+ | ISSUER_SYM {}
| INNOBASE_SYM {}
+ | INSERT_METHOD {}
+ | IO_THREAD {}
+ | LAST_SYM {}
| LEVEL_SYM {}
| LOCAL_SYM {}
| LOCKS_SYM {}
@@ -2803,8 +3364,12 @@ keyword:
| MASTER_USER_SYM {}
| MASTER_PASSWORD_SYM {}
| MASTER_CONNECT_RETRY_SYM {}
+ | MAX_CONNECTIONS_PER_HOUR {}
+ | MAX_QUERIES_PER_HOUR {}
+ | MAX_UPDATES_PER_HOUR {}
| MEDIUM_SYM {}
| MERGE_SYM {}
+ | MEMORY_SYM {}
| MINUTE_SYM {}
| MIN_ROWS {}
| MODIFY_SYM {}
@@ -2813,38 +3378,56 @@ keyword:
| MYISAM_SYM {}
| NATIONAL_SYM {}
| NCHAR_SYM {}
- | FOREIGN_KEY_CHECKS {}
+ | NEXT_SYM {}
+ | NEW_SYM {}
| NO_SYM {}
+ | NONE_SYM {}
+ | OFFSET_SYM {}
| OPEN_SYM {}
| PACK_KEYS_SYM {}
| PASSWORD {}
+ | PREV_SYM {}
| PROCESS {}
| PROCESSLIST_SYM {}
+ | QUERY_SYM {}
| QUICK {}
| RAID_0_SYM {}
| RAID_CHUNKS {}
| RAID_CHUNKSIZE {}
| RAID_STRIPED_SYM {}
| RAID_TYPE {}
- | UNIQUE_CHECKS {}
+ | RELAY_LOG_FILE_SYM {}
+ | RELAY_LOG_POS_SYM {}
| RELOAD {}
| REPAIR {}
| REPEATABLE_SYM {}
+ | REPLICATION {}
| RESET_SYM {}
+ | RESOURCES {}
| RESTORE_SYM {}
| ROLLBACK_SYM {}
+ | ROLLUP_SYM {}
| ROWS_SYM {}
| ROW_FORMAT_SYM {}
| ROW_SYM {}
+ | SAVEPOINT_SYM {}
| SECOND_SYM {}
| SERIALIZABLE_SYM {}
| SESSION_SYM {}
+ | SIGNED_SYM {}
| SHARE_SYM {}
| SHUTDOWN {}
+ | SLAVE {}
+ | SQL_CACHE_SYM {}
+ | SQL_BUFFER_RESULT {}
+ | SQL_NO_CACHE_SYM {}
+ | SQL_THREAD {}
| START_SYM {}
| STATUS_SYM {}
| STOP_SYM {}
| STRING_SYM {}
+ | SUBJECT_SYM {}
+ | SUPER_SYM {}
| TEMPORARY {}
| TEXT_SYM {}
| TRANSACTION_SYM {}
@@ -2854,24 +3437,21 @@ keyword:
| TYPE_SYM {}
| UDF_SYM {}
| UNCOMMITTED_SYM {}
+ | USE_FRM {}
| VARIABLES {}
| WORK_SYM {}
- | YEAR_SYM {}
- | SLAVE {}
- ;
+ | X509_SYM {}
+ | YEAR_SYM {};
/* Option functions */
set:
SET opt_option
{
- THD *thd=current_thd;
- LEX *lex= &thd->lex;
+ LEX *lex=Lex;
lex->sql_command= SQLCOM_SET_OPTION;
- lex->options=thd->options;
- lex->select_limit=thd->default_select_limit;
- lex->gemini_spin_retries=thd->gemini_spin_retries;
- lex->tx_isolation=thd->tx_isolation;
+ lex->option_type=OPT_DEFAULT;
+ lex->var_list.empty();
}
option_value_list
{}
@@ -2879,132 +3459,95 @@ set:
opt_option:
/* empty */ {}
- | OPTION {}
- ;
+ | OPTION {};
option_value_list:
- option_value
- | option_value_list ',' option_value
+ option_type option_value
+ | option_value_list ',' option_type option_value;
+
+option_type:
+ /* empty */ {}
+ | GLOBAL_SYM { Lex->option_type= OPT_GLOBAL; }
+ | LOCAL_SYM { Lex->option_type= OPT_SESSION; }
+ | SESSION_SYM { Lex->option_type= OPT_SESSION; }
+ ;
+
+opt_var_type:
+ /* empty */ { $$=OPT_SESSION; }
+ | LOCAL_SYM { $$=OPT_SESSION; }
+ | SESSION_SYM { $$=OPT_SESSION; }
+ | GLOBAL_SYM { $$=OPT_GLOBAL; }
+ ;
+
+opt_var_ident_type:
+ /* empty */ { $$=OPT_DEFAULT; }
+ | LOCAL_SYM '.' { $$=OPT_SESSION; }
+ | SESSION_SYM '.' { $$=OPT_SESSION; }
+ | GLOBAL_SYM '.' { $$=OPT_GLOBAL; }
;
option_value:
- set_option equal NUM
- {
- if (atoi($3.str) == 0)
- Lex->options&= ~$1;
- else
- Lex->options|= $1;
- }
- | set_isolation
- | AUTOCOMMIT equal NUM
- {
- if (atoi($3.str) != 0) /* Test NOT AUTOCOMMIT */
- Lex->options&= ~(OPTION_NOT_AUTO_COMMIT);
- else
- Lex->options|= OPTION_NOT_AUTO_COMMIT;
- }
- | SQL_SELECT_LIMIT equal ULONG_NUM
- {
- Lex->select_limit= $3;
- }
- | SQL_SELECT_LIMIT equal DEFAULT
- {
- Lex->select_limit= HA_POS_ERROR;
- }
- | SQL_MAX_JOIN_SIZE equal ULONG_NUM
- {
- current_thd->max_join_size= $3;
- Lex->options&= ~OPTION_BIG_SELECTS;
- }
- | SQL_MAX_JOIN_SIZE equal DEFAULT
- {
- current_thd->max_join_size= HA_POS_ERROR;
- }
- | TIMESTAMP equal ULONG_NUM
- {
- current_thd->set_time((time_t) $3);
- }
- | TIMESTAMP equal DEFAULT
- {
- current_thd->user_time=0;
- }
- | LAST_INSERT_ID equal ULONGLONG_NUM
+ '@' ident_or_text equal expr
{
- current_thd->insert_id($3);
+ Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4)));
}
- | INSERT_ID equal ULONGLONG_NUM
- {
- current_thd->next_insert_id=$3;
- }
- | GEMINI_SPIN_RETRIES equal ULONG_NUM
- {
- Lex->gemini_spin_retries= $3;
- }
- | GEMINI_SPIN_RETRIES equal DEFAULT
- {
- Lex->gemini_spin_retries= 1;
- }
- | CHAR_SYM SET IDENT
- {
- CONVERT *tmp;
- if (!(tmp=get_convert_set($3.str)))
+ | internal_variable_name equal set_expr_or_default
{
- net_printf(&current_thd->net,ER_UNKNOWN_CHARACTER_SET,$3);
- YYABORT;
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var(lex->option_type, $1, $3));
}
- current_thd->convert_set=tmp;
- }
- | CHAR_SYM SET DEFAULT
+ | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
+ {
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var((enum_var_type) $3, $4, $6));
+ }
+ | TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
+ {
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var(lex->option_type,
+ find_sys_var("tx_isolation"),
+ new Item_int((int32) $4)));
+ }
+ | CHAR_SYM SET opt_equal set_expr_or_default
{
- current_thd->convert_set=0;
+ LEX *lex=Lex;
+ lex->var_list.push_back(new set_var(lex->option_type,
+ find_sys_var("convert_character_set"),
+ $4));
}
| PASSWORD equal text_or_password
- {
- if (change_password(current_thd,current_thd->host,
- current_thd->priv_user,$3))
- YYABORT;
- }
- | PASSWORD FOR_SYM user equal text_or_password
- {
- if (change_password(current_thd,
- $3->host.str ? $3->host.str : current_thd->host,
- $3->user.str,$5))
- YYABORT;
- }
- | '@' ident_or_text equal expr
- {
- Item_func_set_user_var *item = new Item_func_set_user_var($2,$4);
- if (item->fix_fields(current_thd,0) || item->update())
- {
- send_error(&current_thd->net, ER_SET_CONSTANTS_ONLY);
- YYABORT;
- }
- }
- | SQL_SLAVE_SKIP_COUNTER equal ULONG_NUM
- {
- pthread_mutex_lock(&LOCK_slave);
- if(slave_running)
- send_error(&current_thd->net, ER_SLAVE_MUST_STOP);
- else
- slave_skip_counter = $3;
- pthread_mutex_unlock(&LOCK_slave);
- }
- | FOREIGN_KEY_CHECKS equal NUM
{
- if (atoi($3.str) == 0)
- Lex->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
- else
- Lex->options&= ~(OPTION_NO_FOREIGN_KEY_CHECKS);
+ THD *thd=current_thd;
+ LEX_USER *user;
+ if (!(user=(LEX_USER*) sql_alloc(sizeof(LEX_USER))))
+ YYABORT;
+ user->host.str=0;
+ user->user.str=thd->priv_user;
+ thd->lex.var_list.push_back(new set_var_password(user, $3));
}
- | UNIQUE_CHECKS equal NUM
+ | PASSWORD FOR_SYM user equal text_or_password
{
- if (atoi($3.str) == 0)
- Lex->options|= OPTION_RELAXED_UNIQUE_CHECKS;
- else
- Lex->options&= ~(OPTION_RELAXED_UNIQUE_CHECKS);
+ Lex->var_list.push_back(new set_var_password($3,$5));
}
;
+internal_variable_name:
+ ident
+ {
+ sys_var *tmp=find_sys_var($1.str, $1.length);
+ if (!tmp)
+ YYABORT;
+ $$=tmp;
+ }
+ ;
+
+isolation_types:
+ READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
+ | READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; }
+ | REPEATABLE_SYM READ_SYM { $$= ISO_REPEATABLE_READ; }
+ | SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; }
+ ;
+
text_or_password:
TEXT_STRING { $$=$1.str;}
| PASSWORD '(' TEXT_STRING ')'
@@ -3017,57 +3560,16 @@ text_or_password:
make_scrambled_password(buff,$3.str);
$$=buff;
}
- }
- ;
+ };
-set_option:
- SQL_BIG_TABLES { $$= OPTION_BIG_TABLES; }
- | SQL_BIG_SELECTS { $$= OPTION_BIG_SELECTS; }
- | SQL_LOG_OFF { $$= OPTION_LOG_OFF; }
- | SQL_LOG_UPDATE
- {
- $$= (opt_sql_bin_update)?
- OPTION_UPDATE_LOG|OPTION_BIN_LOG:
- OPTION_UPDATE_LOG ;
- }
- | SQL_LOG_BIN
- {
- $$= (opt_sql_bin_update)?
- OPTION_UPDATE_LOG|OPTION_BIN_LOG:
- OPTION_BIN_LOG ;
- }
- | SQL_WARNINGS { $$= OPTION_WARNINGS; }
- | SQL_LOW_PRIORITY_UPDATES { $$= OPTION_LOW_PRIORITY_UPDATES; }
- | SQL_AUTO_IS_NULL { $$= OPTION_AUTO_IS_NULL; }
- | SQL_SAFE_UPDATES { $$= OPTION_SAFE_UPDATES; }
- | SQL_BUFFER_RESULT { $$= OPTION_BUFFER_RESULT; }
- | SQL_QUOTE_SHOW_CREATE { $$= OPTION_QUOTE_SHOW_CREATE; }
- ;
-
-set_isolation:
- GLOBAL_SYM tx_isolation
- {
- if (check_process_priv())
- YYABORT;
- default_tx_isolation= $2;
- default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
- }
- | SESSION_SYM tx_isolation
- { current_thd->session_tx_isolation= Lex->tx_isolation= $2; }
- | tx_isolation
- { Lex->tx_isolation= $1; }
- ;
-tx_isolation:
- TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types { $$=$4; }
+set_expr_or_default:
+ expr { $$=$1; }
+ | DEFAULT { $$=0; }
+ | ON { $$=new Item_string("ON",2); }
+ | ALL { $$=new Item_string("ALL",3); }
;
-isolation_types:
- READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
- | READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; }
- | REPEATABLE_SYM READ_SYM { $$= ISO_REPEATABLE_READ; }
- | SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; }
- ;
/* Lock function */
@@ -3082,40 +3584,98 @@ lock:
table_or_tables:
TABLE_SYM
- | TABLES
- ;
+ | TABLES;
table_lock_list:
table_lock
- | table_lock_list ',' table_lock
- ;
+ | table_lock_list ',' table_lock;
table_lock:
table_ident opt_table_alias lock_option
- { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; }
- ;
+ { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; };
lock_option:
READ_SYM { $$=TL_READ_NO_INSERT; }
| WRITE_SYM { $$=current_thd->update_lock_default; }
| LOW_PRIORITY WRITE_SYM { $$=TL_WRITE_LOW_PRIORITY; }
- | READ_SYM LOCAL_SYM { $$= TL_READ; }
- ;
+ | READ_SYM LOCAL_SYM { $$= TL_READ; };
unlock:
- UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; }
- ;
+ UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; };
+
+
+/*
+** Handler: direct access to ISAM functions
+*/
+
+handler:
+ HANDLER_SYM table_ident OPEN_SYM opt_table_alias
+ {
+ Lex->sql_command = SQLCOM_HA_OPEN;
+ if (!add_table_to_list($2,$4,0))
+ YYABORT;
+ }
+ | HANDLER_SYM table_ident_ref CLOSE_SYM
+ {
+ Lex->sql_command = SQLCOM_HA_CLOSE;
+ if (!add_table_to_list($2,0,0))
+ YYABORT;
+ }
+ | HANDLER_SYM table_ident_ref READ_SYM
+ {
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_HA_READ;
+ lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */
+ lex->select->select_limit= 1;
+ lex->select->offset_limit= 0L;
+ if (!add_table_to_list($2,0,0))
+ YYABORT;
+ }
+ handler_read_or_scan where_clause limit_clause { };
+
+handler_read_or_scan:
+ handler_scan_function { Lex->backup_dir= 0; }
+ | ident handler_rkey_function { Lex->backup_dir= $1.str; };
+
+handler_scan_function:
+ FIRST_SYM { Lex->ha_read_mode = RFIRST; }
+ | NEXT_SYM { Lex->ha_read_mode = RNEXT; };
+
+handler_rkey_function:
+ FIRST_SYM { Lex->ha_read_mode = RFIRST; }
+ | NEXT_SYM { Lex->ha_read_mode = RNEXT; }
+ | PREV_SYM { Lex->ha_read_mode = RPREV; }
+ | LAST_SYM { Lex->ha_read_mode = RLAST; }
+ | handler_rkey_mode
+ {
+ LEX *lex=Lex;
+ lex->ha_read_mode = RKEY;
+ lex->ha_rkey_mode=$1;
+ if (!(lex->insert_list = new List_item))
+ YYABORT;
+ } '(' values ')' { };
+
+handler_rkey_mode:
+ EQ { $$=HA_READ_KEY_EXACT; }
+ | GE { $$=HA_READ_KEY_OR_NEXT; }
+ | LE { $$=HA_READ_KEY_OR_PREV; }
+ | GT_SYM { $$=HA_READ_AFTER_KEY; }
+ | LT { $$=HA_READ_BEFORE_KEY; };
/* GRANT / REVOKE */
revoke:
REVOKE
{
- Lex->sql_command = SQLCOM_REVOKE;
- Lex->users_list.empty();
- Lex->columns.empty();
- Lex->grant= Lex->grant_tot_col=0;
- Lex->db=0;
+ LEX *lex=Lex;
+ lex->sql_command = SQLCOM_REVOKE;
+ lex->users_list.empty();
+ lex->columns.empty();
+ lex->grant= lex->grant_tot_col=0;
+ lex->select->db=0;
+ lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
+ lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
+ bzero((char*) &lex->mqh, sizeof(lex->mqh));
}
grant_privileges ON opt_table FROM user_list
{}
@@ -3124,101 +3684,156 @@ revoke:
grant:
GRANT
{
- Lex->sql_command = SQLCOM_GRANT;
- Lex->users_list.empty();
- Lex->columns.empty();
- Lex->grant= Lex->grant_tot_col=0;
- Lex->db=0;
+ LEX *lex=Lex;
+ lex->users_list.empty();
+ lex->columns.empty();
+ lex->sql_command = SQLCOM_GRANT;
+ lex->grant= lex->grant_tot_col= 0;
+ lex->select->db= 0;
+ lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
+ lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
+ bzero((char *)&(lex->mqh),sizeof(lex->mqh));
}
grant_privileges ON opt_table TO_SYM user_list
- grant_option
+ require_clause grant_options
{}
;
grant_privileges:
grant_privilege_list {}
- | ALL PRIVILEGES { Lex->grant = UINT_MAX;}
- | ALL { Lex->grant = UINT_MAX;}
- ;
+ | ALL PRIVILEGES { Lex->grant = GLOBAL_ACLS;}
+ | ALL { Lex->grant = GLOBAL_ACLS;};
grant_privilege_list:
grant_privilege
- | grant_privilege_list ',' grant_privilege
- {}
- ;
+ | grant_privilege_list ',' grant_privilege;
grant_privilege:
- SELECT_SYM
- { Lex->which_columns = SELECT_ACL;}
- opt_column_list {}
- | INSERT
- { Lex->which_columns = INSERT_ACL; }
- opt_column_list {}
- | UPDATE_SYM
- { Lex->which_columns = UPDATE_ACL; }
- opt_column_list {}
- | DELETE_SYM { Lex->grant |= DELETE_ACL;}
- | REFERENCES { Lex->which_columns = REFERENCES_ACL;} opt_column_list {}
- | USAGE {}
+ SELECT_SYM { Lex->which_columns = SELECT_ACL;} opt_column_list {}
+ | INSERT { Lex->which_columns = INSERT_ACL;} opt_column_list {}
+ | UPDATE_SYM { Lex->which_columns = UPDATE_ACL; } opt_column_list {}
+ | REFERENCES { Lex->which_columns = REFERENCES_ACL;} opt_column_list {}
+ | DELETE_SYM { Lex->grant |= DELETE_ACL;}
+ | USAGE {}
| INDEX { Lex->grant |= INDEX_ACL;}
| ALTER { Lex->grant |= ALTER_ACL;}
| CREATE { Lex->grant |= CREATE_ACL;}
| DROP { Lex->grant |= DROP_ACL;}
+ | EXECUTE_SYM { Lex->grant |= EXECUTE_ACL;}
| RELOAD { Lex->grant |= RELOAD_ACL;}
| SHUTDOWN { Lex->grant |= SHUTDOWN_ACL;}
| PROCESS { Lex->grant |= PROCESS_ACL;}
| FILE_SYM { Lex->grant |= FILE_ACL;}
| GRANT OPTION { Lex->grant |= GRANT_ACL;}
+ | SHOW DATABASES { Lex->grant |= SHOW_DB_ACL;}
+ | SUPER_SYM { Lex->grant |= SUPER_ACL;}
+ | CREATE TEMPORARY TABLES { Lex->grant |= CREATE_TMP_ACL;}
+ | LOCK_SYM TABLES { Lex->grant |= LOCK_TABLES_ACL; }
+ | REPLICATION SLAVE { Lex->grant |= REPL_SLAVE_ACL;}
+ | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL;}
;
+
+opt_and:
+ /* empty */ {}
+ | AND {}
+ ;
+
+require_list:
+ require_list_element opt_and require_list
+ | require_list_element
+ ;
+
+require_list_element:
+ SUBJECT_SYM TEXT_STRING
+ {
+ LEX *lex=Lex;
+ if (lex->x509_subject)
+ {
+ net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "SUBJECT");
+ YYABORT;
+ }
+ lex->x509_subject=$2.str;
+ }
+ | ISSUER_SYM TEXT_STRING
+ {
+ LEX *lex=Lex;
+ if (lex->x509_issuer)
+ {
+ net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "ISSUER");
+ YYABORT;
+ }
+ lex->x509_issuer=$2.str;
+ }
+ | CIPHER_SYM TEXT_STRING
+ {
+ LEX *lex=Lex;
+ if (lex->ssl_cipher)
+ {
+ net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "CIPHER");
+ YYABORT;
+ }
+ lex->ssl_cipher=$2.str;
+ }
+ ;
+
opt_table:
'*'
{
- Lex->db=current_thd->db;
- if (Lex->grant == UINT_MAX)
- Lex->grant = DB_ACLS & ~GRANT_ACL;
- else if (Lex->columns.elements)
+ LEX *lex=Lex;
+ lex->select->db=lex->thd->db;
+ if (lex->grant == GLOBAL_ACLS)
+ lex->grant = DB_ACLS & ~GRANT_ACL;
+ else if (lex->columns.elements)
{
- net_printf(&current_thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
- YYABORT;
- }
+ send_error(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
+ YYABORT;
+ }
}
| ident '.' '*'
{
- Lex->db = $1.str;
- if (Lex->grant == UINT_MAX)
- Lex->grant = DB_ACLS & ~GRANT_ACL;
- else if (Lex->columns.elements)
+ LEX *lex=Lex;
+ lex->select->db = $1.str;
+ if (lex->grant == GLOBAL_ACLS)
+ lex->grant = DB_ACLS & ~GRANT_ACL;
+ else if (lex->columns.elements)
{
- net_printf(&current_thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
+ send_error(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
YYABORT;
}
}
| '*' '.' '*'
{
- Lex->db = NULL;
- if (Lex->grant == UINT_MAX)
- Lex->grant = GLOBAL_ACLS & ~GRANT_ACL;
- else if (Lex->columns.elements)
+ LEX *lex=Lex;
+ lex->select->db = NULL;
+ if (lex->grant == GLOBAL_ACLS)
+ lex->grant= GLOBAL_ACLS & ~GRANT_ACL;
+ else if (lex->columns.elements)
{
- net_printf(&current_thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
+ send_error(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
YYABORT;
}
}
| table_ident
{
+ LEX *lex=Lex;
if (!add_table_to_list($1,NULL,0))
YYABORT;
- if (Lex->grant == UINT_MAX)
- Lex->grant = TABLE_ACLS & ~GRANT_ACL;
- }
- ;
+ if (lex->grant == GLOBAL_ACLS)
+ lex->grant = TABLE_ACLS & ~GRANT_ACL;
+ };
+
user_list:
- grant_user { if (Lex->users_list.push_back($1)) YYABORT;}
- | user_list ',' grant_user { if (Lex->users_list.push_back($3)) YYABORT;}
+ grant_user { if (Lex->users_list.push_back($1)) YYABORT;}
+ | user_list ',' grant_user
+ {
+ if (Lex->users_list.push_back($3))
+ YYABORT;
+ }
;
+
grant_user:
user IDENTIFIED_SYM BY TEXT_STRING
{
@@ -3237,18 +3852,20 @@ grant_user:
| user IDENTIFIED_SYM BY PASSWORD TEXT_STRING
{ $$=$1; $1->password=$5 ; }
| user
- { $$=$1; $1->password.str=NullS; }
- ;
+ { $$=$1; $1->password.str=NullS; };
+
opt_column_list:
- /* empty */ { Lex->grant |= Lex->which_columns; }
- | '(' column_list ')'
- ;
+ /* empty */
+ {
+ LEX *lex=Lex;
+ lex->grant |= lex->which_columns;
+ }
+ | '(' column_list ')';
column_list:
column_list ',' column_list_id
- | column_list_id
- ;
+ | column_list_id;
column_list_id:
ident
@@ -3256,23 +3873,64 @@ column_list_id:
String *new_str = new String((const char*) $1.str,$1.length);
List_iterator <LEX_COLUMN> iter(Lex->columns);
class LEX_COLUMN *point;
+ LEX *lex=Lex;
while ((point=iter++))
{
if (!my_strcasecmp(point->column.ptr(),new_str->ptr()))
break;
}
- Lex->grant_tot_col|= Lex->which_columns;
+ lex->grant_tot_col|= lex->which_columns;
if (point)
- point->rights |= Lex->which_columns;
+ point->rights |= lex->which_columns;
else
- Lex->columns.push_back(new LEX_COLUMN (*new_str,Lex->which_columns));
- }
+ lex->columns.push_back(new LEX_COLUMN (*new_str,lex->which_columns));
+ };
+
+
+require_clause: /* empty */
+ | REQUIRE_SYM require_list
+ {
+ Lex->ssl_type=SSL_TYPE_SPECIFIED;
+ }
+ | REQUIRE_SYM SSL_SYM
+ {
+ Lex->ssl_type=SSL_TYPE_ANY;
+ }
+ | REQUIRE_SYM X509_SYM
+ {
+ Lex->ssl_type=SSL_TYPE_X509;
+ }
+ | REQUIRE_SYM NONE_SYM
+ {
+ Lex->ssl_type=SSL_TYPE_NONE;
+ }
;
-grant_option:
+grant_options:
/* empty */ {}
- | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;}
- ;
+ | WITH grant_option_list;
+
+grant_option_list:
+ grant_option_list grant_option {}
+ | grant_option {};
+
+grant_option:
+ GRANT OPTION { Lex->grant |= GRANT_ACL;}
+ | MAX_QUERIES_PER_HOUR ULONG_NUM
+ {
+ Lex->mqh.questions=$2;
+ Lex->mqh.bits |= 1;
+ }
+ | MAX_UPDATES_PER_HOUR ULONG_NUM
+ {
+ Lex->mqh.updates=$2;
+ Lex->mqh.bits |= 2;
+ }
+ | MAX_CONNECTIONS_PER_HOUR ULONG_NUM
+ {
+ Lex->mqh.connections=$2;
+ Lex->mqh.bits |= 4;
+ };
begin:
BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work {}
@@ -3280,13 +3938,87 @@ begin:
opt_work:
/* empty */ {}
- | WORK_SYM {}
- ;
+ | WORK_SYM {;};
commit:
- COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;}
- ;
+ COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;};
rollback:
- ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK;}
+ ROLLBACK_SYM
+ {
+ Lex->sql_command = SQLCOM_ROLLBACK;
+ }
+ | ROLLBACK_SYM TO_SYM SAVEPOINT_SYM ident
+ {
+ Lex->sql_command = SQLCOM_ROLLBACK_TO_SAVEPOINT;
+ Lex->savepoint_name = $4.str;
+ };
+savepoint:
+ SAVEPOINT_SYM ident
+ {
+ Lex->sql_command = SQLCOM_SAVEPOINT;
+ Lex->savepoint_name = $2.str;
+ };
+
+/*
+** UNIONS : glue selects together
+*/
+
+
+opt_union:
+ /* empty */ {}
+ | union_list;
+
+union_list:
+ UNION_SYM union_option
+ {
+ LEX *lex=Lex;
+ if (lex->exchange)
+ {
+ /* Only the last SELECT can have INTO...... */
+ net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO");
+ YYABORT;
+ }
+ if (lex->select->linkage == NOT_A_SELECT)
+ {
+ send_error(&lex->thd->net, ER_SYNTAX_ERROR);
+ YYABORT;
+ }
+ if (mysql_new_select(lex))
+ YYABORT;
+ lex->select->linkage=UNION_TYPE;
+ }
+ select_init {}
+ ;
+
+union_opt:
+ union_list {}
+ | optional_order_or_limit {};
+
+optional_order_or_limit:
+ /* empty
+ intentional reduce/reduce conflict here !!!
+ { code } below should not be executed
+ when neither ORDER BY nor LIMIT are used */ {}
+ |
+ {
+ LEX *lex=Lex;
+ if (!lex->select->braces)
+ {
+ send_error(&lex->thd->net, ER_SYNTAX_ERROR);
+ YYABORT;
+ }
+ if (mysql_new_select(lex))
+ YYABORT;
+ mysql_init_select(lex);
+ lex->select->linkage=NOT_A_SELECT;
+ lex->select->select_limit=lex->thd->variables.select_limit;
+ }
+ opt_order_clause limit_clause
+ ;
+
+union_option:
+ /* empty */ {}
+ | DISTINCT {}
+ | ALL { Lex->union_option=1; }
;
diff --git a/sql/stacktrace.c b/sql/stacktrace.c
index d5711bcd78e..73a7ecdc7ba 100644
--- a/sql/stacktrace.c
+++ b/sql/stacktrace.c
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include <global.h>
+#include <my_global.h>
#include "stacktrace.h"
#include <signal.h>
#include <my_pthread.h>
@@ -122,8 +122,8 @@ terribly wrong...\n");
return;
}
#endif /* __alpha__ */
-
- if (!stack_bottom)
+
+ if (!stack_bottom || (gptr) stack_bottom > (gptr) &fp)
{
ulong tmp= min(0x10000,thread_stack);
/* Assume that the stack starts at the previous even 65K */
@@ -145,12 +145,12 @@ terribly wrong...\n");
fprintf(stderr, "Warning: Alpha stacks are difficult -\
will be taking some wild guesses, stack trace may be incorrect or \
terminate abruptly\n");
- // On Alpha, we need to get pc
+ /* On Alpha, we need to get pc */
__asm __volatile__ ("bsr %0, do_next; do_next: "
:"=r"(pc)
:"r"(pc));
#endif /* __alpha__ */
-
+
while (fp < (uchar**) stack_bottom)
{
#ifdef __i386__
@@ -165,7 +165,7 @@ terribly wrong...\n");
{
new_fp += 90;
}
-
+
if (fp && pc)
{
pc = find_prev_pc(pc, fp);
@@ -195,9 +195,9 @@ terribly wrong...\n");
}
fprintf(stderr, "Stack trace seems successful - bottom reached\n");
-
+
end:
- fprintf(stderr, "Please read http://www.mysql.com/doc/U/s/Using_stack_trace.html and follow instructions on how to resolve the stack trace. Resolved\n\
+ fprintf(stderr, "Please read http://www.mysql.com/doc/en/Using_stack_trace.html and follow instructions on how to resolve the stack trace. Resolved\n\
stack trace is much more helpful in diagnosing the problem, so please do \n\
resolve it\n");
}
@@ -210,8 +210,8 @@ resolve it\n");
void write_core(int sig)
{
signal(sig, SIG_DFL);
- if (fork() != 0) exit(1); // Abort main program
- // Core will be written at exit
+ if (fork() != 0) exit(1); /* Abort main program */
+ /* Core will be written at exit */
}
#else
void write_core(int sig)
diff --git a/sql/structs.h b/sql/structs.h
index 90924b842d6..77fed422d21 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -50,14 +50,14 @@ typedef struct st_keyfile_info { /* used with ha_info() */
typedef struct st_key_part_info { /* Info about a key part */
Field *field;
uint offset; /* offset in record (from 0) */
- uint null_offset; // Offset to null_bit in record
+ uint null_offset; /* Offset to null_bit in record */
uint16 length; /* Length of key_part */
uint16 store_length;
uint16 key_type;
uint16 fieldnr; /* Fieldnum in UNIREG */
uint8 key_part_flag; /* 0 or HA_REVERSE_SORT */
uint8 type;
- uint8 null_bit; // Position to null_bit
+ uint8 null_bit; /* Position to null_bit */
} KEY_PART_INFO ;
@@ -67,6 +67,7 @@ typedef struct st_key {
uint key_parts; /* How many key_parts */
uint extra_length;
uint usable_key_parts; /* Should normally be = key_parts */
+ enum ha_key_alg algorithm;
KEY_PART_INFO *key_part;
char *name; /* Name of key */
ulong *rec_per_key; /* Key part distribution */
@@ -105,7 +106,7 @@ typedef struct st_read_record { /* Parameter to read_record */
byte *record;
byte *cache,*cache_pos,*cache_end,*read_positions;
IO_CACHE *io_cache;
- bool print_error;
+ bool print_error, ignore_not_found_rows;
} READ_RECORD;
enum timestamp_type { TIMESTAMP_NONE, TIMESTAMP_DATE, TIMESTAMP_FULL,
@@ -123,17 +124,37 @@ typedef struct {
} INTERVAL;
-enum SHOW_TYPE { SHOW_LONG,SHOW_CHAR,SHOW_INT,SHOW_CHAR_PTR,SHOW_BOOL,
- SHOW_MY_BOOL,SHOW_OPENTABLES,SHOW_STARTTIME,SHOW_QUESTION,
- SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_LONG_AS_LONGLONG};
+enum SHOW_TYPE
+{
+ SHOW_UNDEF,
+ SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_BOOL,
+ SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUESTION,
+ SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS,
+#ifdef HAVE_OPENSSL
+ SHOW_SSL_CTX_SESS_ACCEPT, SHOW_SSL_CTX_SESS_ACCEPT_GOOD,
+ SHOW_SSL_GET_VERSION, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE,
+ SHOW_SSL_CTX_SESS_CB_HITS, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE,
+ SHOW_SSL_CTX_SESS_NUMBER, SHOW_SSL_SESSION_REUSED,
+ SHOW_SSL_CTX_SESS_GET_CACHE_SIZE, SHOW_SSL_GET_CIPHER,
+ SHOW_SSL_GET_DEFAULT_TIMEOUT, SHOW_SSL_GET_VERIFY_MODE,
+ SHOW_SSL_CTX_GET_VERIFY_MODE, SHOW_SSL_GET_VERIFY_DEPTH,
+ SHOW_SSL_CTX_GET_VERIFY_DEPTH, SHOW_SSL_CTX_SESS_CONNECT,
+ SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE, SHOW_SSL_CTX_SESS_CONNECT_GOOD,
+ SHOW_SSL_CTX_SESS_HITS, SHOW_SSL_CTX_SESS_MISSES,
+ SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL,
+ SHOW_SSL_GET_CIPHER_LIST,
+#endif /* HAVE_OPENSSL */
+ SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING
+};
enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
+typedef int *(*update_var)(THD *, struct show_var_st *);
-struct show_var_st {
+typedef struct show_var_st {
const char *name;
char *value;
SHOW_TYPE type;
-};
+} SHOW_VAR;
typedef struct lex_string {
char *str;
@@ -144,6 +165,17 @@ typedef struct st_lex_user {
LEX_STRING user, host, password;
} LEX_USER;
+
+typedef struct user_resources {
+ uint questions, updates, connections, bits;
+} USER_RESOURCES;
+
+typedef struct user_conn {
+ char *user, *host;
+ uint len, connections, conn_per_hour, updates, questions, user_len;
+ USER_RESOURCES user_resources;
+ time_t intime;
+} USER_CONN;
/* Bits in form->update */
#define REG_MAKE_DUPP 1 /* Make a copy of record when read */
#define REG_NEW_RECORD 2 /* Write a new record if not found */
@@ -154,13 +186,14 @@ typedef struct st_lex_user {
#define REG_MAY_BE_UPDATED 64
#define REG_AUTO_UPDATE 64 /* Used in D-forms for scroll-tables */
#define REG_OVERWRITE 128
-#define REG_SKIPP_DUPP 256
+#define REG_SKIP_DUP 256
/* Bits in form->status */
#define STATUS_NO_RECORD (1+2) /* Record isn't usably */
#define STATUS_GARBAGE 1
-#define STATUS_NOT_FOUND 2 /* No record in database when neaded */
+#define STATUS_NOT_FOUND 2 /* No record in database when needed */
#define STATUS_NO_PARENT 4 /* Parent record wasn't found */
#define STATUS_NOT_READ 8 /* Record isn't read */
#define STATUS_UPDATED 16 /* Record is updated by formula */
#define STATUS_NULL_ROW 32 /* table->null_row is set */
+#define STATUS_DELETED 64
diff --git a/sql/table.cc b/sql/table.cc
index 5503dddf085..a90220fa55b 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -46,19 +46,20 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
reg2 uchar *strpos;
int j,error;
uint rec_buff_length,n_length,int_length,records,key_parts,keys,
- interval_count,interval_parts,read_length,db_create_options;
+ interval_count,interval_parts,read_length,db_create_options;
+ uint key_info_length, com_length;
ulong pos;
- char index_file[FN_REFLEN], *names,*keynames;
+ char index_file[FN_REFLEN], *names, *keynames;
uchar head[288],*disk_buff,new_field_pack_flag;
my_string record;
const char **int_array;
- bool new_frm_ver,use_hash, null_field_first;
+ bool use_hash, null_field_first;
File file;
Field **field_ptr,*reg_field;
KEY *keyinfo;
KEY_PART_INFO *key_part;
uchar *null_pos;
- uint null_bit;
+ uint null_bit, new_frm_ver, field_pack_length;
SQL_CRYPT *crypted=0;
DBUG_ENTER("openfrm");
DBUG_PRINT("enter",("name: '%s' form: %lx",name,outparam));
@@ -69,7 +70,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
outparam->db_stat = db_stat;
error=1;
- init_sql_alloc(&outparam->mem_root,1024,0);
+ init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC,&outparam->mem_root);
@@ -94,14 +95,15 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (my_read(file,(byte*) head,64,MYF(MY_NABP))) goto err_not_open;
if (head[0] != (uchar) 254 || head[1] != 1 ||
- (head[2] != FRM_VER && head[2] != FRM_VER+1))
- goto err_not_open; /* purecov: inspected */
+ (head[2] != FRM_VER && head[2] != FRM_VER+1 && head[2] != FRM_VER+3))
+ goto err_not_open; /* purecov: inspected */
new_field_pack_flag=head[27];
- new_frm_ver= (head[2] == FRM_VER+1);
+ new_frm_ver= (head[2] - FRM_VER);
+ field_pack_length= new_frm_ver < 2 ? 11 : 17;
error=3;
if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
- goto err_not_open; /* purecov: inspected */
+ goto err_not_open; /* purecov: inspected */
*fn_ext(index_file)='\0'; // Remove .frm extension
outparam->db_type=ha_checktype((enum db_type) (uint) *(head+3));
@@ -127,11 +129,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
outparam->min_rows=uint4korr(head+22);
/* Read keyinformation */
+ key_info_length= (uint) uint2korr(head+28);
VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
- if (read_string(file,(gptr*) &disk_buff,(uint) uint2korr(head+28)))
+ if (read_string(file,(gptr*) &disk_buff,key_info_length))
goto err_not_open; /* purecov: inspected */
outparam->keys=keys= disk_buff[0];
- outparam->keys_in_use= set_bits(key_map, keys);
+ outparam->keys_for_keyread= outparam->keys_in_use= set_bits(key_map, keys);
outparam->key_parts=key_parts=disk_buff[1];
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
@@ -140,8 +143,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
goto err_not_open; /* purecov: inspected */
bzero((char*) keyinfo,n_length);
outparam->key_info=keyinfo;
- outparam->max_key_length=0;
- key_part= (KEY_PART_INFO*) (keyinfo+keys);
+ outparam->max_key_length= outparam->total_key_length= 0;
+ key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
strpos=disk_buff+6;
ulong *rec_per_key;
@@ -151,9 +154,23 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
for (i=0 ; i < keys ; i++, keyinfo++)
{
- keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME;
- keyinfo->key_length= (uint) uint2korr(strpos+1);
- keyinfo->key_parts= (uint) strpos[3]; strpos+=4;
+ if (new_frm_ver == 3)
+ {
+ keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
+ keyinfo->key_length= (uint) uint2korr(strpos+2);
+ keyinfo->key_parts= (uint) strpos[4];
+ keyinfo->algorithm= (enum ha_key_alg) strpos[5];
+ strpos+=8;
+ }
+ else
+ {
+ keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME;
+ keyinfo->key_length= (uint) uint2korr(strpos+1);
+ keyinfo->key_parts= (uint) strpos[3];
+ keyinfo->algorithm= HA_KEY_ALG_UNDEF;
+ strpos+=4;
+ }
+
keyinfo->key_part= key_part;
keyinfo->rec_per_key= rec_per_key;
for (j=keyinfo->key_parts ; j-- ; key_part++)
@@ -163,7 +180,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
key_part->offset= (uint) uint2korr(strpos+2)-1;
key_part->key_type= (uint) uint2korr(strpos+5);
// key_part->field= (Field*) 0; // Will be fixed later
- if (new_frm_ver)
+ if (new_frm_ver >= 1)
{
key_part->key_part_flag= *(strpos+4);
key_part->length= (uint) uint2korr(strpos+7);
@@ -184,11 +201,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
}
set_if_bigger(outparam->max_key_length,keyinfo->key_length+
keyinfo->key_parts);
+ outparam->total_key_length+= keyinfo->key_length;
if (keyinfo->flags & HA_NOSAME)
set_if_bigger(outparam->max_unique_length,keyinfo->key_length);
}
+ keynames=(char*) key_part;
+ strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
- (void) strmov(keynames= (char *) key_part,(char *) strpos);
outparam->reclength = uint2korr((head+16));
if (*(head+26) == 1)
outparam->system=1; /* one-record-database */
@@ -256,10 +275,11 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
interval_parts=uint2korr(head+272);
int_length=uint2korr(head+274);
outparam->null_fields=uint2korr(head+282);
+ com_length=uint2korr(head+284);
outparam->comment=strdup_root(&outparam->mem_root,
(char*) head+47);
- DBUG_PRINT("form",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d", interval_count,interval_parts, outparam->keys,n_length,int_length));
+ DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d", interval_count,interval_parts, outparam->keys,n_length,int_length));
if (!(field_ptr = (Field **)
alloc_root(&outparam->mem_root,
@@ -267,12 +287,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
interval_count*sizeof(TYPELIB)+
(outparam->fields+interval_parts+
keys+3)*sizeof(my_string)+
- (n_length+int_length)))))
+ (n_length+int_length+com_length)))))
goto err_not_open; /* purecov: inspected */
outparam->field=field_ptr;
- read_length=((uint) (outparam->fields*11)+pos+
- (uint) (n_length+int_length));
+ read_length=(uint) (outparam->fields * field_pack_length +
+ pos+ (uint) (n_length+int_length+com_length));
if (read_string(file,(gptr*) &disk_buff,read_length))
goto err_not_open; /* purecov: inspected */
if (crypted)
@@ -288,7 +308,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
names= (char*) (int_array+outparam->fields+interval_parts+keys+3);
if (!interval_count)
outparam->intervals=0; // For better debugging
- memcpy((char*) names, strpos+(outparam->fields*11),
+ memcpy((char*) names, strpos+(outparam->fields*field_pack_length),
(uint) (n_length+int_length));
fix_type_pointers(&int_array,&outparam->fieldnames,1,&names);
@@ -321,22 +341,49 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
(hash_get_key) get_field_name,0,
HASH_CASE_INSENSITIVE);
- for (i=0 ; i < outparam->fields; i++, strpos+= 11, field_ptr++)
+ for (i=0 ; i < outparam->fields; i++, strpos+=field_pack_length, field_ptr++)
{
- uint pack_flag= uint2korr(strpos+6);
- uint interval_nr= (uint) strpos[10];
+ uint pack_flag, interval_nr, unireg_type, recpos, field_length;
+ enum_field_types field_type;
+
+ if (new_frm_ver == 3)
+ {
+ /* new frm file in 4.1 */
+ field_length= uint2korr(strpos+3);
+ recpos= uint3korr(strpos+5);
+ pack_flag= uint2korr(strpos+8);
+ unireg_type= (uint) strpos[10];
+ interval_nr= (uint) strpos[12];
+ field_type= (enum_field_types) (uint) strpos[13];
+ }
+ else
+ {
+ /* old frm file */
+ field_length= (uint) strpos[3];
+ recpos= uint2korr(strpos+4),
+ pack_flag= uint2korr(strpos+6);
+ unireg_type= (uint) strpos[8];
+ interval_nr= (uint) strpos[10];
+ field_type= (enum_field_types) f_packtype(pack_flag);
+ }
*field_ptr=reg_field=
- make_field(record+uint2korr(strpos+4),
- (uint32) strpos[3], // field_length
+ make_field(record+recpos,
+ (uint32) field_length,
null_pos,null_bit,
pack_flag,
- (Field::utype) MTYP_TYPENR((uint) strpos[8]),
+ field_type,
+ (Field::utype) MTYP_TYPENR(unireg_type),
(interval_nr ?
outparam->intervals+interval_nr-1 :
(TYPELIB*) 0),
outparam->fieldnames.type_names[i],
outparam);
+ if (!*field_ptr) // Field in 4.1
+ {
+ error= 4;
+ goto err_not_open; /* purecov: inspected */
+ }
if (!(reg_field->flags & NOT_NULL_FLAG))
{
if ((null_bit<<=1) == 256)
@@ -359,25 +406,41 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
{
uint primary_key=(uint) (find_type((char*) "PRIMARY",&outparam->keynames,
3)-1);
- uint ha_option=outparam->file->option_flag();
+ uint ha_option=outparam->file->table_flags();
keyinfo=outparam->key_info;
key_part=keyinfo->key_part;
for (uint key=0 ; key < outparam->keys ; key++,keyinfo++)
{
uint usable_parts=0;
+ ulong index_flags;
keyinfo->name=(char*) outparam->keynames.type_names[key];
+ /* Fix fulltext keys for old .frm files */
+ if (outparam->key_info[key].flags & HA_FULLTEXT)
+ outparam->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
+
+ /* This has to be done after the above fulltext correction */
+ index_flags=outparam->file->index_flags(key);
+ if (!(index_flags & HA_KEY_READ_ONLY))
+ {
+ outparam->read_only_keys|= ((key_map) 1 << key);
+ outparam->keys_for_keyread&= ~((key_map) 1 << key);
+ }
+
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
{
/*
- If the UNIQUE key don't have NULL columns, declare this as
- a primary key.
+ If the UNIQUE key doesn't have NULL columns and is not a part key
+ declare this as a primary key.
*/
primary_key=key;
for (i=0 ; i < keyinfo->key_parts ;i++)
{
- if (!key_part[i].fieldnr ||
- outparam->field[key_part[i].fieldnr-1]->null_ptr)
+ uint fieldnr= key_part[i].fieldnr;
+ if (!fieldnr ||
+ outparam->field[fieldnr-1]->null_ptr ||
+ outparam->field[fieldnr-1]->key_length() !=
+ key_part[i].length)
{
primary_key=MAX_KEY; // Can't be used
break;
@@ -416,6 +479,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
key_part->store_length+=HA_KEY_BLOB_LENGTH;
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
+ /*
+ Mark that there may be many matching values for one key
+ combination ('a', 'a ', 'a '...)
+ */
+ if (!(field->flags & BINARY_FLAG))
+ keyinfo->flags|= HA_END_SPACE_KEY;
}
if (i == 0 && key != primary_key)
field->flags |=
@@ -424,16 +493,18 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
keyinfo->key_length ? UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
if (i == 0)
field->key_start|= ((key_map) 1 << key);
- if ((ha_option & HA_HAVE_KEY_READ_ONLY) &&
+ if ((index_flags & HA_KEY_READ_ONLY) &&
field->key_length() == key_part->length &&
field->type() != FIELD_TYPE_BLOB)
{
if (field->key_type() != HA_KEYTYPE_TEXT ||
- (!(ha_option & HA_KEY_READ_WRONG_STR) &&
+ ((!(ha_option & HA_KEY_READ_WRONG_STR) ||
+ field->flags & BINARY_FLAG) &&
!(keyinfo->flags & HA_FULLTEXT)))
field->part_of_key|= ((key_map) 1 << key);
- if (field->key_type() != HA_KEYTYPE_TEXT ||
- !(keyinfo->flags & HA_FULLTEXT))
+ if ((field->key_type() != HA_KEYTYPE_TEXT ||
+ !(keyinfo->flags & HA_FULLTEXT)) &&
+ !(index_flags & HA_WRONG_ASCII_ORDER))
field->part_of_sortkey|= ((key_map) 1 << key);
}
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
@@ -443,15 +514,20 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (key == primary_key)
{
field->flags|= PRI_KEY_FLAG;
+ /*
+ If this field is part of the primary key and all keys contains
+ the primary key, then we can use any key to find this column
+ */
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
- field->part_of_key|= ((key_map) 1 << primary_key);
+ field->part_of_key= outparam->keys_in_use;
}
if (field->key_length() != key_part->length)
{
- key_part->key_part_flag|= HA_PART_KEY;
+ key_part->key_part_flag|= HA_PART_KEY_SEG;
if (field->type() != FIELD_TYPE_BLOB)
{ // Create a new field
- field=key_part->field=field->new_field(outparam);
+ field=key_part->field=field->new_field(&outparam->mem_root,
+ outparam);
field->field_length=key_part->length;
}
}
@@ -461,7 +537,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
as we need to test for NULL = NULL.
*/
if (field->real_maybe_null())
- key_part->key_part_flag|= HA_PART_KEY;
+ key_part->key_part_flag|= HA_PART_KEY_SEG;
}
else
{ // Error: shorten key
@@ -475,8 +551,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
(outparam->keys_in_use & ((key_map) 1 << primary_key)))
{
outparam->primary_key=primary_key;
- if (outparam->file->option_flag() & HA_PRIMARY_KEY_IN_READ_INDEX)
- outparam->ref_primary_key= (key_map) 1 << primary_key;
/*
If we are using an integer as the primary key then allow the user to
refer to it as '_rowid'
@@ -504,6 +578,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
bfill(outparam->null_flags+outparam->rec_buff_length*2,null_length,255);
}
+
if ((reg_field=outparam->found_next_number_field))
{
if ((int) (outparam->next_number_index= (uint)
@@ -757,7 +832,7 @@ ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames,
int2store(fileinfo+8,names+1);
int2store(fileinfo+4,n_length+length);
- VOID(my_chsize(file,newpos,MYF(MY_WME))); /* Append file with '\0' */
+ VOID(my_chsize(file, newpos, 0, MYF(MY_WME)));/* Append file with '\0' */
DBUG_RETURN(newpos);
} /* make_new_entry */
@@ -831,7 +906,7 @@ fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
*type_name= '\0'; /* End string */
ptr=type_name;
}
- ptr+=2; /* Skipp end mark and last 0 */
+ ptr+=2; /* Skip end mark and last 0 */
}
else
ptr++;
@@ -917,7 +992,7 @@ ulong next_io_size(register ulong pos)
void append_unescaped(String *res,const char *pos)
{
- for ( ; *pos ; pos++)
+ for (; *pos ; pos++)
{
switch (*pos) {
case 0: /* Must be escaped for 'mysql' */
@@ -1005,6 +1080,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo,
void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
{
+ DBUG_ENTER("update_create_info_from_table");
create_info->max_rows=table->max_rows;
create_info->min_rows=table->min_rows;
create_info->table_options=table->db_create_options;
@@ -1013,7 +1089,8 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
create_info->raid_type=table->raid_type;
create_info->raid_chunks=table->raid_chunks;
create_info->raid_chunksize=table->raid_chunksize;
-}
+ DBUG_VOID_RETURN;
+}
int
rename_file_ext(const char * from,const char * to,const char * ext)
@@ -1033,13 +1110,12 @@ rename_file_ext(const char * from,const char * to,const char * ext)
char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr)
{
Field *field=table->field[fieldnr];
- char buff[MAX_FIELD_WIDTH];
+ char buff[MAX_FIELD_WIDTH], *to;
String str(buff,sizeof(buff));
field->val_str(&str,&str);
uint length=str.length();
- if (!length)
+ if (!length || !(to= (char*) alloc_root(mem,length+1)))
return NullS;
- char *to= (char*) alloc_root(mem,length+1);
memcpy(to,str.ptr(),(uint) length);
to[length]=0;
return to;
@@ -1081,7 +1157,8 @@ bool check_db_name(char *name)
}
}
#endif
- if (*name == '/' || *name == FN_LIBCHAR || *name == FN_EXTCHAR)
+ if (*name == '/' || *name == '\\' || *name == FN_LIBCHAR ||
+ *name == FN_EXTCHAR)
return 1;
name++;
}
@@ -1115,7 +1192,7 @@ bool check_table_name(const char *name, uint length)
}
}
#endif
- if (*name == '/' || *name == FN_LIBCHAR || *name == FN_EXTCHAR)
+ if (*name == '/' || *name == '\\' || *name == FN_EXTCHAR)
return 1;
name++;
}
@@ -1164,7 +1241,7 @@ db_type get_table_type(const char *name)
error=my_read(file,(byte*) head,4,MYF(MY_NABP));
my_close(file,MYF(0));
if (error || head[0] != (uchar) 254 || head[1] != 1 ||
- (head[2] != FRM_VER && head[2] != FRM_VER+1))
+ (head[2] != FRM_VER && head[2] != FRM_VER+1 && head[2] != FRM_VER+3))
DBUG_RETURN(DB_TYPE_UNKNOWN);
DBUG_RETURN(ha_checktype((enum db_type) (uint) *(head+3)));
}
diff --git a/sql/table.h b/sql/table.h
index 4302e3a3f27..f3b0e148cc0 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -37,8 +37,8 @@ typedef struct st_grant_info
{
GRANT_TABLE *grant_table;
uint version;
- uint privilege;
- uint want_privilege;
+ ulong privilege;
+ ulong want_privilege;
} GRANT_INFO;
enum tmp_table_type {NO_TMP_TABLE=0, TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2};
@@ -58,10 +58,12 @@ struct st_table {
uint reclength; /* Recordlength */
uint rec_buff_length;
uint keys,key_parts,primary_key,max_key_length,max_unique_length;
+ uint total_key_length;
uint uniques;
uint null_fields; /* number of null fields */
uint blob_fields; /* number of blob fields */
- key_map keys_in_use, keys_in_use_for_query;
+ key_map keys_in_use, keys_for_keyread, read_only_keys;
+ key_map quick_keys, used_keys, keys_in_use_for_query;
KEY *key_info; /* data of keys in database */
TYPELIB keynames; /* Pointers to keynames */
ha_rows max_rows; /* create information */
@@ -89,8 +91,9 @@ struct st_table {
my_bool copy_blobs; /* copy_blobs when storing */
my_bool null_row; /* All columns are null */
my_bool maybe_null,outer_join; /* Used with OUTER JOIN */
- my_bool distinct,const_table;
- my_bool key_read;
+ my_bool force_index;
+ my_bool distinct,const_table,no_rows;
+ my_bool key_read, bulk_insert;
my_bool crypted;
my_bool db_low_byte_first; /* Portable row format */
my_bool locked_by_flush;
@@ -98,6 +101,7 @@ struct st_table {
my_bool fulltext_searched;
my_bool crashed;
my_bool is_view;
+ my_bool no_keyread, no_cache;
Field *next_number_field, /* Set if next_number is activated */
*found_next_number_field, /* Set on open */
*rowid_field;
@@ -111,22 +115,25 @@ struct st_table {
char *table_name,*real_name,*path;
uint key_length; /* Length of key */
uint tablenr,used_fields,null_bytes;
- table_map map;
+ table_map map; /* ID bit of table (1,2,4,8,16...) */
ulong version,flush_version;
uchar *null_flags;
- IO_CACHE *io_cache; /* If sorted trough file*/
- byte *record_pointers; /* If sorted in memory */
- ha_rows found_records; /* How many records in sort */
+ IO_CACHE *io_cache; /* If sorted trough file*/
+ byte *record_pointers; /* If sorted in memory */
+ ha_rows found_records; /* How many records in sort */
ORDER *group;
- key_map quick_keys, used_keys, ref_primary_key;
ha_rows quick_rows[MAX_KEY];
uint quick_key_parts[MAX_KEY];
key_part_map const_key_parts[MAX_KEY];
ulong query_id;
- uint temp_pool_slot;
+ union /* Temporary variables */
+ {
+ uint temp_pool_slot; /* Used by intern temp tables */
+ struct st_table_list *pos_in_table_list;
+ };
- THD *in_use; /* Which thread uses this */
+ THD *in_use; /* Which thread uses this */
struct st_table *next,*prev;
};
@@ -134,16 +141,37 @@ struct st_table {
#define JOIN_TYPE_LEFT 1
#define JOIN_TYPE_RIGHT 2
-typedef struct st_table_list {
+typedef struct st_table_list
+{
struct st_table_list *next;
- char *db,*alias,*real_name;
- Item *on_expr; /* Used with outer join */
- struct st_table_list *natural_join; /* natural join on this table*/
- List<String> *use_index,*ignore_index;
+ char *db, *alias, *real_name;
+ Item *on_expr; /* Used with outer join */
+ struct st_table_list *natural_join; /* natural join on this table*/
+ /* ... join ... USE INDEX ... IGNORE INDEX */
+ List<String> *use_index,*ignore_index;
TABLE *table;
GRANT_INFO grant;
thr_lock_type lock_type;
- uint outer_join; /* Which join type */
- bool straight; /* optimize with prev table */
- bool updating; /* for replicate-do/ignore table */
+ uint outer_join; /* Which join type */
+ uint shared; /* Used in union or in multi-upd */
+ uint32 db_length, real_name_length;
+ bool straight; /* optimize with prev table */
+ bool updating; /* for replicate-do/ignore table */
+ bool force_index; /* Prefer index over table scan */
} TABLE_LIST;
+
+
+typedef struct st_changed_table_list
+{
+ struct st_changed_table_list *next;
+ char *key;
+ uint32 key_length;
+} CHANGED_TABLE_LIST;
+
+
+typedef struct st_open_table_list
+{
+ struct st_open_table_list *next;
+ char *db,*table;
+ uint32 in_use,locked;
+} OPEN_TABLE_LIST;
diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc
index deb304443df..8b9baa6f045 100644
--- a/sql/thr_malloc.cc
+++ b/sql/thr_malloc.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -22,7 +22,9 @@
extern "C" {
void sql_alloc_error_handler(void)
{
- current_thd->fatal_error=1; /* purecov: inspected */
+ THD *thd=current_thd;
+ if (thd) // QQ; To be removed
+ thd->fatal_error=1; /* purecov: inspected */
sql_print_error(ER(ER_OUT_OF_RESOURCES));
}
}
diff --git a/sql/time.cc b/sql/time.cc
index 1d7e055f682..0363d764100 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -24,11 +24,10 @@ static ulong const days_at_timestart=719528; /* daynr at 1970.01.01 */
uchar *days_in_month= (uchar*) "\037\034\037\036\037\036\037\037\036\037\036\037";
- /* Init some variabels neaded when using my_local_time */
+ /* Init some variabels needed when using my_local_time */
/* Currently only my_time_zone is inited */
static long my_time_zone=0;
-pthread_mutex_t LOCK_timezone;
void init_time(void)
{
@@ -39,14 +38,14 @@ void init_time(void)
seconds= (time_t) time((time_t*) 0);
localtime_r(&seconds,&tm_tmp);
l_time= &tm_tmp;
- my_time_zone=0;
+ my_time_zone= 3600; /* Comp. for -3600 in my_gmt_sec */
my_time.year= (uint) l_time->tm_year+1900;
my_time.month= (uint) l_time->tm_mon+1;
my_time.day= (uint) l_time->tm_mday;
my_time.hour= (uint) l_time->tm_hour;
my_time.minute= (uint) l_time->tm_min;
- my_time.second= (uint) l_time->tm_sec;
- VOID(my_gmt_sec(&my_time)); /* Init my_time_zone */
+ my_time.second= (uint) l_time->tm_sec;
+ my_gmt_sec(&my_time, &my_time_zone); /* Init my_time_zone */
}
/*
@@ -54,29 +53,45 @@ void init_time(void)
This code handles also day light saving time.
The idea is to cache the time zone (including daylight saving time)
for the next call to make things faster.
-
+
*/
-long my_gmt_sec(TIME *t)
+long my_gmt_sec(TIME *t, long *my_timezone)
{
uint loop;
time_t tmp;
struct tm *l_time,tm_tmp;
- long diff;
+ long diff, current_timezone;
+ if (t->year > TIMESTAMP_MAX_YEAR || t->year < TIMESTAMP_MIN_YEAR)
+ return 0;
+
if (t->hour >= 24)
{ /* Fix for time-loop */
t->day+=t->hour/24;
t->hour%=24;
}
- pthread_mutex_lock(&LOCK_timezone);
- tmp=(time_t) ((calc_daynr((uint) t->year,(uint) t->month,(uint) t->day) -
- (long) days_at_timestart)*86400L + (long) t->hour*3600L +
- (long) (t->minute*60 + t->second)) + (time_t) my_time_zone;
+
+ /*
+ Calculate the gmt time based on current time and timezone
+ The -1 on the end is to ensure that if have a date that exists twice
+ (like 2002-10-27 02:00:0 MET), we will find the initial date.
+
+ By doing -3600 we will have to call localtime_r() several times, but
+ I couldn't come up with a better way to get a repeatable result :(
+
+ We can't use mktime() as it's buggy on many platforms and not thread safe.
+ */
+ tmp=(time_t) (((calc_daynr((uint) t->year,(uint) t->month,(uint) t->day) -
+ (long) days_at_timestart)*86400L + (long) t->hour*3600L +
+ (long) (t->minute*60 + t->second)) + (time_t) my_time_zone -
+ 3600);
+ current_timezone= my_time_zone;
+
localtime_r(&tmp,&tm_tmp);
l_time=&tm_tmp;
for (loop=0;
- loop < 3 &&
+ loop < 2 &&
(t->hour != (uint) l_time->tm_hour ||
t->minute != (uint) l_time->tm_min);
loop++)
@@ -89,14 +104,16 @@ long my_gmt_sec(TIME *t)
days= -1;
diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour)) +
(long) (60*((int) t->minute - (int) l_time->tm_min)));
- my_time_zone+=diff;
- tmp+=(time_t) diff;
+ current_timezone+= diff+3600; // Compensate for -3600 above
+ tmp+= (time_t) diff;
localtime_r(&tmp,&tm_tmp);
l_time=&tm_tmp;
}
- /* Fix that if we are in the not existing daylight saving time hour
- we move the start of the next real hour */
- if (loop == 3 && t->hour != (uint) l_time->tm_hour)
+ /*
+ Fix that if we are in the not existing daylight saving time hour
+ we move the start of the next real hour
+ */
+ if (loop == 2 && t->hour != (uint) l_time->tm_hour)
{
int days= t->day - l_time->tm_mday;
if (days < -1)
@@ -108,11 +125,13 @@ long my_gmt_sec(TIME *t)
if (diff == 3600)
tmp+=3600 - t->minute*60 - t->second; // Move to next hour
else if (diff == -3600)
- tmp-=t->minute*60 + t->second; // Move to next hour
+ tmp-=t->minute*60 + t->second; // Move to previous hour
}
- if ((my_time_zone >=0 ? my_time_zone: -my_time_zone) > 3600L*12)
- my_time_zone=0; /* Wrong date */
- pthread_mutex_unlock(&LOCK_timezone);
+ *my_timezone= current_timezone;
+
+ if (tmp < TIMESTAMP_MIN_VALUE || tmp > TIMESTAMP_MAX_VALUE)
+ tmp= 0;
+
return (long) tmp;
} /* my_gmt_sec */
@@ -128,7 +147,7 @@ long calc_daynr(uint year,uint month,uint day)
DBUG_ENTER("calc_daynr");
if (year == 0 && month == 0 && day == 0)
- DBUG_RETURN(0); /* Skipp errors */
+ DBUG_RETURN(0); /* Skip errors */
if (year < 200)
{
if ((year=year+1900) < 1900+YY_PART_YEAR)
@@ -163,39 +182,72 @@ uint calc_days_in_year(uint year)
366 : 365;
}
-/* Calculate week. If 'with_year' is not set, then return a week 0-53, where
- 0 means that it's the last week of the previous year.
- If 'with_year' is set then the week will always be in the range 1-53 and
- the year out parameter will contain the year for the week */
-uint calc_week(TIME *l_time, bool with_year, bool sunday_first_day_of_week,
- uint *year)
+/*
+ The bits in week_format has the following meaning:
+ WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
+ If set Monday is first day of week
+ WEEK_YEAR (1) If not set Week is in range 0-53
+
+ Week 0 is returned for the the last week of the previous year (for
+ a date at start of january) In this case one can get 53 for the
+ first week of next year. This flag ensures that the week is
+ relevant for the given year. Note that this flag is only
+ releveant if WEEK_JANUARY is not set.
+
+ If set Week is in range 1-53.
+
+ In this case one may get week 53 for a date in January (when
+ the week is that last week of previous year) and week 1 for a
+ date in December.
+
+ WEEK_FIRST_WEEKDAY (2) If not set Weeks are numbered according
+ to ISO 8601:1988
+ If set The week that contains the first
+ 'first-day-of-week' is week 1.
+
+ ISO 8601:1988 means that if the week containing January 1 has
+ four or more days in the new year, then it is week 1;
+ Otherwise it is the last week of the previous year, and the
+ next week is week 1.
+*/
+
+uint calc_week(TIME *l_time, uint week_behaviour, uint *year)
{
uint days;
ulong daynr=calc_daynr(l_time->year,l_time->month,l_time->day);
ulong first_daynr=calc_daynr(l_time->year,1,1);
- uint weekday=calc_weekday(first_daynr,sunday_first_day_of_week);
+ bool monday_first= test(week_behaviour & WEEK_MONDAY_FIRST);
+ bool week_year= test(week_behaviour & WEEK_YEAR);
+ bool first_weekday= test(week_behaviour & WEEK_FIRST_WEEKDAY);
+
+ uint weekday=calc_weekday(first_daynr, !monday_first);
*year=l_time->year;
- if (l_time->month == 1 && weekday >= 4 && l_time->day <= 7-weekday)
+
+ if (l_time->month == 1 && l_time->day <= 7-weekday)
{
- /* Last week of the previous year */
- if (!with_year)
+ if (!week_year &&
+ (first_weekday && weekday != 0 ||
+ !first_weekday && weekday >= 4))
return 0;
- with_year=0; // Don't check the week again
+ week_year= 1;
(*year)--;
first_daynr-= (days=calc_days_in_year(*year));
weekday= (weekday + 53*7- days) % 7;
}
- if (weekday >= 4)
+
+ if ((first_weekday && weekday != 0) ||
+ (!first_weekday && weekday >= 4))
days= daynr - (first_daynr+ (7-weekday));
else
days= daynr - (first_daynr - weekday);
- if (with_year && days >= 52*7)
+
+ if (week_year && days >= 52*7)
{
- /* Check if we are on the first week of the next year (or week 53) */
weekday= (weekday + calc_days_in_year(*year)) % 7;
- if (weekday < 4)
- { // We are at first week on next year
+ if (!first_weekday && weekday < 4 ||
+ first_weekday && weekday == 0)
+ {
(*year)++;
return 1;
}
@@ -248,144 +300,6 @@ void get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month,
DBUG_VOID_RETURN;
}
-/* find date from string and put it in vektor
- Input: pos = "YYMMDD" OR "YYYYMMDD" in any order or
- "xxxxx YYxxxMMxxxDD xxxx" where xxx is anything exept
- a number. Month or day mustn't exeed 2 digits, year may be 4 digits.
-*/
-
-
-#ifdef NOT_NEEDED
-
-void find_date(string pos,uint *vek,uint flag)
-{
- uint length,value;
- string start;
- DBUG_ENTER("find_date");
- DBUG_PRINT("enter",("pos: '%s' flag: %d",pos,flag));
-
- bzero((char*) vek,sizeof(int)*4);
- while (*pos && !isdigit(*pos))
- pos++;
- length=(uint) strlen(pos);
- for (uint i=0 ; i< 3; i++)
- {
- start=pos; value=0;
- while (isdigit(pos[0]) &&
- ((pos-start) < 2 || ((pos-start) < 4 && length >= 8 &&
- !(flag & 3))))
- {
- value=value*10 + (uint) (uchar) (*pos - '0');
- pos++;
- }
- vek[flag & 3]=value; flag>>=2;
- while (*pos && (ispunct(*pos) || isspace(*pos)))
- pos++;
- }
- DBUG_PRINT("exit",("year: %d month: %d day: %d",vek[0],vek[1],vek[2]));
- DBUG_VOID_RETURN;
-} /* find_date */
-
-
- /* Outputs YYMMDD if input year < 100 or YYYYMMDD else */
-
-static long calc_daynr_from_week(uint year,uint week,uint day)
-{
- long daynr;
- int weekday;
-
- daynr=calc_daynr(year,1,1);
- if ((weekday= calc_weekday(daynr,0)) >= 3)
- daynr+= (7-weekday);
- else
- daynr-=weekday;
-
- return (daynr+week*7+day-8);
-}
-
-void convert_week_to_date(string date,uint flag,uint *res_length)
-{
- string format;
- uint year,vek[4];
-
- find_date(date,vek,(uint) (1*4+2*16)); /* YY-WW-DD */
- year=vek[0];
-
- get_date_from_daynr(calc_daynr_from_week(vek[0],vek[1],vek[2]),
- &vek[0],&vek[1],&vek[2]);
- *res_length=8;
- format="%04d%02d%02d";
- if (year < 100)
- {
- vek[0]= vek[0]%100;
- *res_length=6;
- format="%02d%02d%02d";
- }
- sprintf(date,format,vek[flag & 3],vek[(flag >> 2) & 3],
- vek[(flag >> 4) & 3]);
- return;
-}
-
- /* returns YYWWDD or YYYYWWDD according to input year */
- /* flag only reflects format of input date */
-
-void convert_date_to_week(string date,uint flag,uint *res_length)
-{
- uint vek[4],weekday,days,year,week,day;
- long daynr,first_daynr;
- char buff[256],*format;
-
- if (! date[0])
- {
- get_date(buff,0,0L); /* Use current date */
- find_date(buff+2,vek,(uint) (1*4+2*16)); /* YY-MM-DD */
- }
- else
- find_date(date,vek,flag);
-
- year= vek[0];
- daynr= calc_daynr(year,vek[1],vek[2]);
- first_daynr=calc_daynr(year,1,1);
-
- /* Caculate year and first daynr of year */
- if (vek[1] == 1 && (weekday=calc_weekday(first_daynr,0)) >= 3 &&
- vek[2] <= 7-weekday)
- {
- if (!year--)
- year=99;
- first_daynr=first_daynr-calc_days_in_year(year);
- }
- else if (vek[1] == 12 &&
- (weekday=calc_weekday(first_daynr+calc_days_in_year(year)),0) < 3 &&
- vek[2] > 31-weekday)
- {
- first_daynr=first_daynr+calc_days_in_year(year);
- if (year++ == 99)
- year=0;
- }
-
- /* Calulate daynr of first day of week 1 */
- if ((weekday= calc_weekday(first_daynr,0)) >= 3)
- first_daynr+= (7-weekday);
- else
- first_daynr-=weekday;
-
- days=(int) (daynr-first_daynr);
- week=days/7+1 ; day=calc_weekday(daynr,0)+1;
-
- *res_length=8;
- format="%04d%02d%02d";
- if (year < 100)
- {
- *res_length=6;
- format="%02d%02d%02d";
- }
- sprintf(date,format,year,week,day);
- return;
-}
-
-#endif
-
/* Functions to handle periods */
ulong convert_period_to_month(ulong period)
@@ -426,12 +340,13 @@ timestamp_type
str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
{
uint field_length,year_length,digits,i,number_of_fields,date[7];
+ uint not_zero_date;
const char *pos;
const char *end=str+length;
DBUG_ENTER("str_to_TIME");
DBUG_PRINT("enter",("str: %.*s",length,str));
- for (; str != end && !isdigit(*str) ; str++) ; // Skipp garbage
+ for (; str != end && !isdigit(*str) ; str++) ; // Skip garbage
if (str == end)
DBUG_RETURN(TIMESTAMP_NONE);
/*
@@ -443,6 +358,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
digits= (uint) (pos-str);
year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2;
field_length=year_length-1;
+ not_zero_date= 0;
for (i=0 ; i < 6 && str != end && isdigit(*str) ; i++)
{
uint tmp_value=(uint) (uchar) (*str++ - '0');
@@ -452,6 +368,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
str++;
}
date[i]=tmp_value;
+ not_zero_date|= tmp_value;
if (i == 2 && str != end && *str == 'T')
str++; // ISO8601: CCYYMMDDThhmmss
else if ( i != 5 ) // Skip inter-field delimiters
@@ -475,25 +392,39 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
while (str++ != end && isdigit(str[0]) && field_length--)
tmp_value=tmp_value*10 + (uint) (uchar) (*str - '0');
date[6]=tmp_value;
+ not_zero_date|= tmp_value;
}
else
date[6]=0;
- if (year_length == 2)
+ if (year_length == 2 && i >=2 && (date[1] || date[2]))
date[0]+= (date[0] < YY_PART_YEAR ? 2000 : 1900);
number_of_fields=i;
while (i < 6)
date[i++]=0;
if (number_of_fields < 3 || date[1] > 12 ||
date[2] > 31 || date[3] > 23 || date[4] > 59 || date[5] > 59 ||
- !fuzzy_date && (date[1] == 0 || date[2] == 0))
+ (!fuzzy_date && (date[1] == 0 || date[2] == 0)))
{
- current_thd->cuted_fields++;
+ /* Only give warning for a zero date if there is some garbage after */
+ if (!not_zero_date) // If zero date
+ {
+ for (; str != end ; str++)
+ {
+ if (!isspace(*str))
+ {
+ not_zero_date= 1; // Give warning
+ break;
+ }
+ }
+ }
+ if (not_zero_date)
+ current_thd->cuted_fields++;
DBUG_RETURN(TIMESTAMP_NONE);
}
if (str != end && current_thd->count_cuted_fields)
{
- for ( ; str != end ; str++)
+ for (; str != end ; str++)
{
if (!isspace(*str))
{
@@ -517,14 +448,14 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
time_t str_to_timestamp(const char *str,uint length)
{
TIME l_time;
- if (str_to_TIME(str,length,&l_time,0) == TIMESTAMP_NONE)
- return(0);
- if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR)
- {
+ long not_used;
+ time_t timestamp= 0;
+
+ if (str_to_TIME(str,length,&l_time,0) != TIMESTAMP_NONE &&
+ !(timestamp= my_gmt_sec(&l_time, &not_used)))
current_thd->cuted_fields++;
- return(0);
- }
- return(my_gmt_sec(&l_time));
+
+ return timestamp;
}
@@ -591,7 +522,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
date[0]=value;
state=1; // Assume next is hours
found_days=1;
- str++; // Skipp space;
+ str++; // Skip space;
}
else if ((end-str) > 1 && *str == ':' && isdigit(str[1]))
{
@@ -599,7 +530,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
date[1]=value;
state=2;
found_hours=1;
- str++; // skipp ':'
+ str++; // skip ':'
}
else
{
@@ -620,7 +551,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
date[state++]=value;
if (state == 4 || (end-str) < 2 || *str != ':' || !isdigit(str[1]))
break;
- str++; // Skipp ':'
+ str++; // Skip ':'
}
if (state != 4)
diff --git a/sql/udf_example.cc b/sql/udf_example.cc
index a91db5ee1cc..176ddeb10a3 100644
--- a/sql/udf_example.cc
+++ b/sql/udf_example.cc
@@ -1,15 +1,15 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+/* Copyright (C) 2002 MySQL AB
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -61,7 +61,7 @@
** On the end is a couple of functions that converts hostnames to ip and
** vice versa.
**
-** A dynamicly loadable file should be compiled sharable
+** A dynamicly loadable file should be compiled shared.
** (something like: gcc -shared -o my_func.so myfunc.cc).
** You can easily get all switches right by doing:
** cd sql ; make udf_example.o
@@ -69,6 +69,8 @@
** the line and add -shared -o udf_example.so to the end of the compile line.
** The resulting library (udf_example.so) should be copied to some dir
** searched by ld. (/usr/lib ?)
+** If you are using gcc, then you should be able to create the udf_example.so
+** by simply doing 'make udf_example.so'.
**
** After the library is made one must notify mysqld about the new
** functions with the commands:
@@ -109,8 +111,15 @@
#ifdef STANDARD
#include <stdio.h>
#include <string.h>
+#ifdef __WIN__
+typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */
+typedef __int64 longlong;
#else
-#include <global.h>
+typedef unsigned long long ulonglong;
+typedef long long longlong;
+#endif /*__WIN__*/
+#else
+#include <my_global.h>
#include <my_sys.h>
#endif
#include <mysql.h>
@@ -133,7 +142,7 @@ longlong myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
char *error);
my_bool sequence_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
void sequence_deinit(UDF_INIT *initid);
-long long sequence(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
+longlong sequence(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
char *error);
my_bool avgcost_init( UDF_INIT* initid, UDF_ARGS* args, char* message );
void avgcost_deinit( UDF_INIT* initid );
@@ -271,7 +280,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
* characters and converting to uppercase.
*-------------------------------------------------------*/
- for ( n = ntrans + 1, n_end = ntrans + sizeof(ntrans)-2;
+ for (n = ntrans + 1, n_end = ntrans + sizeof(ntrans)-2;
word != w_end && n < n_end; word++ )
if ( isalpha ( *word ))
*n++ = toupper ( *word );
@@ -324,7 +333,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
KSflag = 0; /* state flag for KS translation */
- for ( metaph_end = result + MAXMETAPH, n_start = n;
+ for (metaph_end = result + MAXMETAPH, n_start = n;
n <= n_end && result < metaph_end; n++ )
{
@@ -402,7 +411,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
n[2] != 'G' ) ?
(char)'J' : (char)'K';
else
- if( n[1] == 'H' &&
+ if ( n[1] == 'H' &&
!NOGHTOF( *( n - 3 )) &&
*( n - 4 ) != 'H')
*result++ = 'F';
@@ -440,7 +449,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
case 'T': /* TIO, TIA = X ("sh" sound) */
/* TH = 0, ("th" sound ) */
- if( *( n + 1 ) == 'I' && ( n[2] == 'O'
+ if ( *( n + 1 ) == 'I' && ( n[2] == 'O'
|| n[2] == 'A') )
*result++ = 'X';
else
@@ -556,10 +565,10 @@ double myfunc_double(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
/* This function returns the sum of all arguments */
-long long myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
+longlong myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
char *error)
{
- long long val = 0;
+ longlong val = 0;
for (uint i = 0; i < args->arg_count; i++)
{
if (args->args[i] == NULL)
@@ -569,10 +578,10 @@ long long myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
val += args->lengths[i];
break;
case INT_RESULT: // Add numbers
- val += *((long long*) args->args[i]);
+ val += *((longlong*) args->args[i]);
break;
- case REAL_RESULT: // Add numers as long long
- val += (long long) *((double*) args->args[i]);
+ case REAL_RESULT: // Add numers as longlong
+ val += (longlong) *((double*) args->args[i]);
break;
}
}
@@ -615,12 +624,12 @@ void sequence_deinit(UDF_INIT *initid)
free(initid->ptr);
}
-long long sequence(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
+longlong sequence(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
char *error)
{
ulonglong val=0;
if (args->arg_count)
- val= *((long long*) args->args[0]);
+ val= *((longlong*) args->args[0]);
return ++ *((longlong*) initid->ptr) + val;
}
@@ -741,10 +750,10 @@ char *reverse_lookup(UDF_INIT *initid, UDF_ARGS *args, char *result,
return 0;
}
sprintf(result,"%d.%d.%d.%d",
- (int) *((long long*) args->args[0]),
- (int) *((long long*) args->args[1]),
- (int) *((long long*) args->args[2]),
- (int) *((long long*) args->args[3]));
+ (int) *((longlong*) args->args[0]),
+ (int) *((longlong*) args->args[1]),
+ (int) *((longlong*) args->args[2]),
+ (int) *((longlong*) args->args[3]));
}
else
{ // string argument
@@ -793,9 +802,9 @@ char *reverse_lookup(UDF_INIT *initid, UDF_ARGS *args, char *result,
struct avgcost_data
{
- unsigned long long count;
- long long totalquantity;
- double totalprice;
+ ulonglong count;
+ longlong totalquantity;
+ double totalprice;
};
@@ -869,8 +878,8 @@ avgcost_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message )
if (args->args[0] && args->args[1])
{
struct avgcost_data* data = (struct avgcost_data*)initid->ptr;
- long long quantity = *((long long*)args->args[0]);
- long long newquantity = data->totalquantity + quantity;
+ longlong quantity = *((longlong*)args->args[0]);
+ longlong newquantity = data->totalquantity + quantity;
double price = *((double*)args->args[1]);
data->count++;
diff --git a/sql/uniques.cc b/sql/uniques.cc
new file mode 100644
index 00000000000..967392d12d5
--- /dev/null
+++ b/sql/uniques.cc
@@ -0,0 +1,173 @@
+/* Copyright (C) 2001 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Function to handle quick removal of duplicates
+ This code is used when doing multi-table deletes to find the rows in
+ reference tables that needs to be deleted.
+
+ The basic idea is as follows:
+
+ Store first all strings in a binary tree, ignoring duplicates.
+ When the tree uses more memory than 'max_heap_table_size',
+ write the tree (in sorted order) out to disk and start with a new tree.
+ When all data has been generated, merge the trees (removing any found
+ duplicates).
+
+ The unique entries will be returned in sort order, to ensure that we do the
+ deletes in disk order.
+*/
+
+#include "mysql_priv.h"
+#include "sql_sort.h"
+
+
+int unique_write_to_file(gptr key, element_count count, Unique *unique)
+{
+ /*
+ Use unique->size (size of element stored in the tree) and not
+ unique->tree.size_of_element. The latter is different from unique->size
+ when tree implementation chooses to store pointer to key in TREE_ELEMENT
+ (instead of storing the element itself there)
+ */
+ return my_b_write(&unique->file, (byte*) key,
+ unique->size) ? 1 : 0;
+}
+
+int unique_write_to_ptrs(gptr key, element_count count, Unique *unique)
+{
+ memcpy(unique->record_pointers, key, unique->size);
+ unique->record_pointers+=unique->size;
+ return 0;
+}
+
+Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
+ uint size_arg, ulong max_in_memory_size_arg)
+ :max_in_memory_size(max_in_memory_size_arg), size(size_arg), elements(0)
+{
+ my_b_clear(&file);
+ init_tree(&tree, max_in_memory_size / 16, 0, size, comp_func, 0, NULL,
+ comp_func_fixed_arg);
+ /* If the following fail's the next add will also fail */
+ my_init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16);
+ max_elements= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size);
+ open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
+ MYF(MY_WME));
+}
+
+
+Unique::~Unique()
+{
+ close_cached_file(&file);
+ delete_tree(&tree);
+ delete_dynamic(&file_ptrs);
+}
+
+
+ /* Write tree to disk; clear tree */
+bool Unique::flush()
+{
+ BUFFPEK file_ptr;
+ elements+= tree.elements_in_tree;
+ file_ptr.count=tree.elements_in_tree;
+ file_ptr.file_pos=my_b_tell(&file);
+ if (tree_walk(&tree, (tree_walk_action) unique_write_to_file,
+ (void*) this, left_root_right) ||
+ insert_dynamic(&file_ptrs, (gptr) &file_ptr))
+ return 1;
+ delete_tree(&tree);
+ return 0;
+}
+
+
+/*
+ Modify the TABLE element so that when one calls init_records()
+ the rows will be read in priority order.
+*/
+
+bool Unique::get(TABLE *table)
+{
+ SORTPARAM sort_param;
+ table->found_records=elements+tree.elements_in_tree;
+
+ if (my_b_tell(&file) == 0)
+ {
+ /* Whole tree is in memory; Don't use disk if you don't need to */
+ if ((record_pointers=table->record_pointers= (byte*)
+ my_malloc(size * tree.elements_in_tree, MYF(0))))
+ {
+ (void) tree_walk(&tree, (tree_walk_action) unique_write_to_ptrs,
+ this, left_root_right);
+ return 0;
+ }
+ }
+ /* Not enough memory; Save the result to file */
+ if (flush())
+ return 1;
+
+ IO_CACHE *outfile=table->io_cache;
+ BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer;
+ uint maxbuffer= file_ptrs.elements - 1;
+ uchar *sort_buffer;
+ my_off_t save_pos;
+ bool error=1;
+
+ /* Open cached file if it isn't open */
+ outfile=table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
+ MYF(MY_ZEROFILL));
+
+ if (!outfile || ! my_b_inited(outfile) &&
+ open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
+ MYF(MY_WME)))
+ return 1;
+ reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
+
+ bzero((char*) &sort_param,sizeof(sort_param));
+ sort_param.max_rows= elements;
+ sort_param.sort_form=table;
+ sort_param.sort_length=sort_param.ref_length=size;
+ sort_param.keys= max_in_memory_size / sort_param.sort_length;
+ sort_param.not_killable=1;
+
+ if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) *
+ sort_param.sort_length,
+ MYF(0))))
+ return 1;
+ sort_param.unique_buff= sort_buffer+(sort_param.keys*
+ sort_param.sort_length);
+
+ /* Merge the buffers to one file, removing duplicates */
+ if (merge_many_buff(&sort_param,sort_buffer,file_ptr,&maxbuffer,&file))
+ goto err;
+ if (flush_io_cache(&file) ||
+ reinit_io_cache(&file,READ_CACHE,0L,0,0))
+ goto err;
+ if (merge_buffers(&sort_param, &file, outfile, sort_buffer, file_ptr,
+ file_ptr, file_ptr+maxbuffer,0))
+ goto err;
+ error=0;
+err:
+ x_free((gptr) sort_buffer);
+ if (flush_io_cache(outfile))
+ error=1;
+
+ /* Setup io_cache for reading */
+ save_pos=outfile->pos_in_file;
+ if (reinit_io_cache(outfile,READ_CACHE,0L,0,0))
+ error=1;
+ outfile->end_of_file=save_pos;
+ return error;
+}
diff --git a/sql/unireg.cc b/sql/unireg.cc
index f7b040adebe..955e5cfda8a 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -20,7 +20,7 @@
struct.
In the following functions FIELD * is an ordinary field-structure with
the following exeptions:
- sc_length,typepos,row,kol,dtype,regnr and field nead not to be set.
+ sc_length,typepos,row,kol,dtype,regnr and field need not to be set.
str is a (long) to record position where 0 is the first position.
*/
@@ -105,7 +105,7 @@ int rea_create_table(my_string file_name,
fileinfo[26]= (uchar) test((create_info->max_rows == 1) &&
(create_info->min_rows == 1) && (keys == 0));
int2store(fileinfo+28,key_info_length);
- strnmov((char*) forminfo+47,create_info->comment ? create_info->comment : "",
+ strmake((char*) forminfo+47,create_info->comment ? create_info->comment : "",
60);
forminfo[46]=(uchar) strlen((char*)forminfo+47); // Length of comment
@@ -150,16 +150,19 @@ int rea_create_table(my_string file_name,
my_free((gptr) screen_buff,MYF(0));
my_afree((gptr) keybuff);
- VOID(my_close(file,MYF(MY_WME)));
- if (ha_create_table(file_name,create_info,0))
+ if (opt_sync_frm && my_sync(file, MYF(MY_WME)))
goto err2;
+ if (my_close(file,MYF(MY_WME)) ||
+ ha_create_table(file_name,create_info,0))
+ goto err3;
DBUG_RETURN(0);
err:
my_free((gptr) screen_buff,MYF(0));
my_afree((gptr) keybuff);
+err2:
VOID(my_close(file,MYF(MY_WME)));
- err2:
+err3:
my_delete(file_name,MYF(0));
DBUG_RETURN(1);
} /* rea_create_table */
@@ -246,7 +249,7 @@ static uchar * pack_screens(List<create_field> &create_fields,
static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo)
{
uint key_parts,length;
- uchar *pos,*keyname_pos;
+ uchar *pos, *keyname_pos, *key_alg_pos;
KEY *key,*end;
KEY_PART_INFO *key_part,*key_part_end;
DBUG_ENTER("pack_keys");
@@ -290,11 +293,18 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo)
}
*(pos++)=0;
+ /* For MySQL 4.0; Store key algoritms last */
+ key_alg_pos= pos;
+ for (key=keyinfo ; key != end ; key++)
+ {
+ *(pos++)= (uchar) key->algorithm;
+ }
+
keybuff[0]=(uchar) key_count;
keybuff[1]=(uchar) key_parts;
length=(uint) (keyname_pos-keybuff);
int2store(keybuff+2,length);
- length=(uint) (pos-keyname_pos);
+ length=(uint) (key_alg_pos-keyname_pos);
int2store(keybuff+4,length);
DBUG_RETURN((uint) (pos-keybuff));
} /* pack_keys */
@@ -391,8 +401,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
int2store(forminfo+272,int_parts);
int2store(forminfo+274,int_length);
int2store(forminfo+276,time_stamp_pos);
- int2store(forminfo+278,80); /* Columns neaded */
- int2store(forminfo+280,22); /* Rows neaded */
+ int2store(forminfo+278,80); /* Columns needed */
+ int2store(forminfo+280,22); /* Rows needed */
int2store(forminfo+282,null_fields);
DBUG_RETURN(0);
} /* pack_header */
@@ -550,6 +560,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
null_pos+null_count/8,
1 << (null_count & 7),
field->pack_flag,
+ field->sql_type,
field->unireg_check,
field->interval,
field->field_name,
@@ -566,7 +577,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
if (field->def &&
(regfield->real_type() != FIELD_TYPE_YEAR ||
field->def->val_int() != 0))
- field->def->save_in_field(regfield);
+ field->def->save_in_field(regfield, 1);
else if (regfield->real_type() == FIELD_TYPE_ENUM &&
(field->flags & NOT_NULL_FLAG))
{
diff --git a/sql/unireg.h b/sql/unireg.h
index f8f5edd5156..37157311e15 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
@@ -43,17 +43,19 @@
#define ERRMAPP 1 /* Errormap f|r my_error */
#define LIBLEN FN_REFLEN-FN_LEN /* Max l{ngd p} dev */
-#define MAX_DBKEY_LENGTH (FN_LEN*2+6) /* extra 4 bytes for slave tmp
+#define MAX_DBKEY_LENGTH (FN_LEN*2+1+1+4+4) /* extra 4+4 bytes for slave tmp
* tables */
#define MAX_FIELD_NAME 34 /* Max colum name length +2 */
+#define MAX_SYS_VAR_LENGTH 32
#define MAX_KEY 32 /* Max used keys */
#define MAX_REF_PARTS 16 /* Max parts used as ref */
-#define MAX_KEY_LENGTH 500 /* max possible key */
+#define MAX_KEY_LENGTH 1024 /* max possible key */
#if SIZEOF_OFF_T > 4
#define MAX_REFLENGTH 8 /* Max length for record ref */
#else
#define MAX_REFLENGTH 4 /* Max length for record ref */
#endif
+#define MAX_HOSTNAME 61 /* len+1 in mysql.user */
#define MAX_FIELD_WIDTH 256 /* Max column width +1 */
#define MAX_TABLES (sizeof(table_map)*8-1) /* Max tables in join */
@@ -80,8 +82,8 @@
#define MYF_RW MYF(MY_WME+MY_NABP) /* Vid my_read & my_write */
#define SPECIAL_USE_LOCKS 1 /* Lock used databases */
-#define SPECIAL_NO_NEW_FUNC 2 /* Skipp new functions */
-#define SPECIAL_NEW_FUNC 4 /* New nonstandard functions */
+#define SPECIAL_NO_NEW_FUNC 2 /* Skip new functions */
+#define SPECIAL_SKIP_SHOW_DB 4 /* Don't allow 'show db' */
#define SPECIAL_WAIT_IF_LOCKED 8 /* Wait if locked database */
#define SPECIAL_SAME_DB_NAME 16 /* form name = file name */
#define SPECIAL_ENGLISH 32 /* English error messages */
@@ -91,7 +93,6 @@
#define SPECIAL_NO_HOST_CACHE 512 /* Don't cache hosts */
#define SPECIAL_LONG_LOG_FORMAT 1024
#define SPECIAL_SAFE_MODE 2048
-#define SPECIAL_SKIP_SHOW_DB 4096 /* Don't allow 'show db' */
/* Extern defines */
#define store_record(A,B) bmove_allign((A)->record[B],(A)->record[0],(size_t) (A)->reclength)
@@ -122,6 +123,21 @@ bfill((A)->null_flags,(A)->null_bytes,255);\
#define TE_INFO_LENGTH 3
#define MTYP_NOEMPTY_BIT 128
+/*
+ * Minimum length pattern before Turbo Boyer-Moore is used
+ * for SELECT "text" LIKE "%pattern%", excluding the two
+ * wildcards in class Item_func_like.
+ */
+#define MIN_TURBOBM_PATTERN_LEN 3
+
+/*
+ Defines for binary logging.
+ Do not decrease the value of BIN_LOG_HEADER_SIZE.
+ Do not even increase it before checking code.
+*/
+
+#define BIN_LOG_HEADER_SIZE 4
+
/* Include prototypes for unireg */
#include "mysqld_error.h"
diff --git a/sql/violite.c b/sql/violite.c
deleted file mode 100644
index 37fee6fad3d..00000000000
--- a/sql/violite.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/*
- Note that we can't have assertion on file descriptors; The reason for
- this is that during mysql shutdown, another thread can close a file
- we are working on. In this case we should just return read errors from
- the file descriptior.
-*/
-
-#include <global.h>
-
-#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
-
-#include <errno.h>
-#include <assert.h>
-#include <violite.h>
-#include <my_sys.h>
-#include <my_net.h>
-#include <m_string.h>
-#ifdef HAVE_POLL
-#include <sys/poll.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) && !defined(__FreeBSD__)
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#if !defined(alpha_linux_port)
-#include <netinet/tcp.h>
-#endif
-#endif
-
-#if defined(__EMX__) || defined(OS2)
-#define ioctlsocket ioctl
-#endif /* defined(__EMX__) */
-
-#if defined(MSDOS) || defined(__WIN__)
-#define O_NONBLOCK 1 /* For emulation of fcntl() */
-#endif
-#ifndef EWOULDBLOCK
-#define SOCKET_EWOULDBLOCK SOCKET_EAGAIN
-#endif
-
-#ifndef __WIN__
-#define HANDLE void *
-#endif
-
-struct st_vio
-{
- my_socket sd; /* my_socket - real or imaginary */
- HANDLE hPipe;
- my_bool localhost; /* Are we from localhost? */
- int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
- struct sockaddr_in local; /* Local internet address */
- struct sockaddr_in remote; /* Remote internet address */
- enum enum_vio_type type; /* Type of connection */
- char desc[30]; /* String description */
-};
-
-typedef void *vio_ptr;
-typedef char *vio_cstring;
-
-/*
- * Helper to fill most of the Vio* with defaults.
- */
-
-static void vio_reset(Vio* vio, enum enum_vio_type type,
- my_socket sd, HANDLE hPipe,
- my_bool localhost)
-{
- bzero((char*) vio, sizeof(*vio));
- vio->type = type;
- vio->sd = sd;
- vio->hPipe = hPipe;
- vio->localhost= localhost;
-}
-
-/* Open the socket or TCP/IP connection and read the fnctl() status */
-
-Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
-{
- Vio *vio;
- DBUG_ENTER("vio_new");
- DBUG_PRINT("enter", ("sd=%d", sd));
- if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
- {
- vio_reset(vio, type, sd, 0, localhost);
- sprintf(vio->desc,
- (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
- vio->sd);
-#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
-#if !defined(NO_FCNTL_NONBLOCK)
- vio->fcntl_mode = fcntl(sd, F_GETFL);
-#elif defined(HAVE_SYS_IOCTL_H) /* hpux */
- /* Non blocking sockets doesn't work good on HPUX 11.0 */
- (void) ioctl(sd,FIOSNBIO,0);
-#endif
-#else /* !defined(__WIN__) && !defined(__EMX__) */
- {
- /* set to blocking mode by default */
- ulong arg=0, r;
- r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
- }
-#endif
- }
- DBUG_RETURN(vio);
-}
-
-
-#ifdef __WIN__
-
-Vio *vio_new_win32pipe(HANDLE hPipe)
-{
- Vio *vio;
- DBUG_ENTER("vio_new_handle");
- if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
- {
- vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
- strmov(vio->desc, "named pipe");
- }
- DBUG_RETURN(vio);
-}
-
-#endif
-
-void vio_delete(Vio * vio)
-{
- /* It must be safe to delete null pointers. */
- /* This matches the semantics of C++'s delete operator. */
- if (vio)
- {
- if (vio->type != VIO_CLOSED)
- vio_close(vio);
- my_free((gptr) vio,MYF(0));
- }
-}
-
-int vio_errno(Vio *vio __attribute__((unused)))
-{
- return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
-}
-
-
-int vio_read(Vio * vio, gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_read");
- DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
-#if defined( __WIN__) || defined(OS2)
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
-#ifdef OS2
- if (!DosRead((HFILE)vio->hPipe, buf, size, &length))
- DBUG_RETURN(-1);
-#else
- if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
- DBUG_RETURN(-1);
-#endif
- DBUG_RETURN(length);
- }
- r = recv(vio->sd, buf, size,0);
-#else
- errno=0; /* For linux */
- r = read(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("vio_error", ("Got error %d during read",socket_errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_write(Vio * vio, const gptr buf, int size)
-{
- int r;
- DBUG_ENTER("vio_write");
- DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
-#if defined( __WIN__) || defined(OS2)
- if ( vio->type == VIO_TYPE_NAMEDPIPE)
- {
- DWORD length;
-#ifdef OS2
- if (!DosWrite((HFILE)vio->hPipe, (char*) buf, size, &length))
- DBUG_RETURN(-1);
-#else
- if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
- DBUG_RETURN(-1);
-#endif
- DBUG_RETURN(length);
- }
- r = send(vio->sd, buf, size,0);
-#else
- r = write(vio->sd, buf, size);
-#endif /* __WIN__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_blocking(Vio * vio, my_bool set_blocking_mode)
-{
- int r=0;
- DBUG_ENTER("vio_blocking");
- DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
-
-#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
-#if !defined(NO_FCNTL_NONBLOCK)
-
- if (vio->sd >= 0)
- {
- int old_fcntl=vio->fcntl_mode;
- if (set_blocking_mode)
- vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
- else
- vio->fcntl_mode |= O_NONBLOCK; /* set bit */
- if (old_fcntl != vio->fcntl_mode)
- r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
- }
-#endif /* !defined(NO_FCNTL_NONBLOCK) */
-#else /* !defined(__WIN__) && !defined(__EMX__) */
-#ifndef __EMX__
- if (vio->type != VIO_TYPE_NAMEDPIPE)
-#endif
- {
- ulong arg;
- int old_fcntl=vio->fcntl_mode;
- if (set_blocking_mode)
- {
- arg = 0;
- vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
- }
- else
- {
- arg = 1;
- vio->fcntl_mode |= O_NONBLOCK; /* set bit */
- }
- if (old_fcntl != vio->fcntl_mode)
- r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
- }
-#endif /* !defined(__WIN__) && !defined(__EMX__) */
- DBUG_RETURN(r);
-}
-
-my_bool
-vio_is_blocking(Vio * vio)
-{
- my_bool r;
- DBUG_ENTER("vio_is_blocking");
- r = !(vio->fcntl_mode & O_NONBLOCK);
- DBUG_PRINT("exit", ("%d", (int) r));
- DBUG_RETURN(r);
-}
-
-
-int vio_fastsend(Vio * vio __attribute__((unused)))
-{
- int r=0;
- DBUG_ENTER("vio_fastsend");
-
-#ifdef IPTOS_THROUGHPUT
- {
-#ifndef __EMX__
- int tos = IPTOS_THROUGHPUT;
- if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
-#endif /* !__EMX__ */
- {
- int nodelay = 1;
- if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
- sizeof(nodelay))) {
- DBUG_PRINT("warning",
- ("Couldn't set socket option for fast send"));
- r= -1;
- }
- }
- }
-#endif /* IPTOS_THROUGHPUT */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-int vio_keepalive(Vio* vio, my_bool set_keep_alive)
-{
- int r=0;
- uint opt = 0;
- DBUG_ENTER("vio_keepalive");
- DBUG_PRINT("enter", ("sd=%d set_keep_alive=%d", vio->sd, (int)
- set_keep_alive));
- if (vio->type != VIO_TYPE_NAMEDPIPE)
- {
- if (set_keep_alive)
- opt = 1;
- r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
- sizeof(opt));
- }
- DBUG_RETURN(r);
-}
-
-
-my_bool
-vio_should_retry(Vio * vio __attribute__((unused)))
-{
- int en = socket_errno;
- return en == SOCKET_EAGAIN || en == SOCKET_EINTR || en == SOCKET_EWOULDBLOCK;
-}
-
-
-int vio_close(Vio * vio)
-{
- int r;
- DBUG_ENTER("vio_close");
-#ifdef __WIN__
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
-#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIo(vio->hPipe);
- DisconnectNamedPipe(vio->hPipe);
-#endif
- r=CloseHandle(vio->hPipe);
- }
- else if (vio->type != VIO_CLOSED)
-#endif /* __WIN__ */
- {
- r=0;
- if (shutdown(vio->sd,2))
- r= -1;
- if (closesocket(vio->sd))
- r= -1;
- }
- if (r)
- {
- DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno));
- /* FIXME: error handling (not critical for MySQL) */
- }
- vio->type= VIO_CLOSED;
- vio->sd= -1;
- DBUG_RETURN(r);
-}
-
-
-const char *vio_description(Vio * vio)
-{
- return vio->desc;
-}
-
-enum enum_vio_type vio_type(Vio* vio)
-{
- return vio->type;
-}
-
-my_socket vio_fd(Vio* vio)
-{
- return vio->sd;
-}
-
-
-my_bool vio_peer_addr(Vio * vio, char *buf)
-{
- DBUG_ENTER("vio_peer_addr");
- DBUG_PRINT("enter", ("sd=%d", vio->sd));
- if (vio->localhost)
- {
- strmov(buf,"127.0.0.1");
- }
- else
- {
- size_socket addrLen = sizeof(struct sockaddr);
- if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
- &addrLen) != 0)
- {
- DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
- DBUG_RETURN(1);
- }
- my_inet_ntoa(vio->remote.sin_addr,buf);
- }
- DBUG_PRINT("exit", ("addr=%s", buf));
- DBUG_RETURN(0);
-}
-
-
-void vio_in_addr(Vio *vio, struct in_addr *in)
-{
- DBUG_ENTER("vio_in_addr");
- if (vio->localhost)
- bzero((char*) in, sizeof(*in)); /* This should never be executed */
- else
- *in=vio->remote.sin_addr;
- DBUG_VOID_RETURN;
-}
-
-
-/* Return 0 if there is data to be read */
-
-my_bool vio_poll_read(Vio *vio,uint timeout)
-{
-#ifndef HAVE_POLL
- return 0;
-#else
- struct pollfd fds;
- int res;
- DBUG_ENTER("vio_poll");
- fds.fd=vio->sd;
- fds.events=POLLIN;
- fds.revents=0;
- if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
- {
- DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
- }
- DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
-#endif
-}
-
-#endif /* HAVE_VIO */
diff --git a/strings/Makefile.am b/strings/Makefile.am
index 1acd3365100..89b5d8c03e9 100644
--- a/strings/Makefile.am
+++ b/strings/Makefile.am
@@ -22,13 +22,13 @@ pkglib_LIBRARIES = libmystrings.a
# Exact one of ASSEMBLER_X
if ASSEMBLER_x86
ASRCS = strings-x86.s longlong2str-x86.s
-CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c llstr.c ctype.c strnlen.c
+CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c ctype.c strnlen.c
else
-if ASSEMBLER_sparc
+if ASSEMBLER_sparc32
# These file MUST all be on the same line!! Otherwise automake
# generats a very broken makefile
-ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s strxmov-sparc.s
-CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c ctype.c strnlen.c
+ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
+CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c ctype.c strnlen.c strxmov.c
else
#no assembler
ASRCS =
@@ -44,7 +44,7 @@ DISTCLEANFILES = ctype_autoconf.c
# Default charset definitions
EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c \
ctype-gb2312.c ctype-gbk.c ctype-sjis.c \
- ctype-tis620.c ctype-ujis.c \
+ ctype-tis620.c ctype-ujis.c ctype-latin1_de.c \
strto.c strings-x86.s \
longlong2str.c longlong2str-x86.s \
strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
@@ -76,8 +76,11 @@ clean-local:
if ASSEMBLER
# On Linux gcc can compile the assembly files
%.o : %.s
- $(AS) -o $@ $<
+ $(AS) $(ASFLAGS) -o $@ $<
endif
+str_test: str_test.c $(LIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/str_test.c $(LDADD) $(LIBS)
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/strings/atof.c b/strings/atof.c
index 1ce16027089..0e0aa598718 100644
--- a/strings/atof.c
+++ b/strings/atof.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
A quicker atof. About 2-10 times faster than standard atof on sparc.
@@ -23,7 +22,7 @@
Must be inited with init_my_atof to handle possibly overflows.
*/
-#include <global.h>
+#include <my_global.h>
#ifdef USE_MY_ATOF /* Skipp if we don't want it */
#include <m_ctype.h>
#include <floatingpoint.h>
diff --git a/strings/bchange.c b/strings/bchange.c
index 99066cf1e95..034dd3382e1 100644
--- a/strings/bchange.c
+++ b/strings/bchange.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : bchange.c
Author : Michael widenius
@@ -25,10 +24,11 @@
src in a buffer with tot_length bytes.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
-void bchange(register char *dst, uint old_length, register const char *src, uint new_length, uint tot_length)
+void bchange(register char *dst, uint old_length, register const char *src,
+ uint new_length, uint tot_length)
{
uint rest=tot_length-old_length;
if (old_length < new_length)
diff --git a/strings/bcmp.c b/strings/bcmp.c
index 3dce5025b64..64a6b72c443 100644
--- a/strings/bcmp.c
+++ b/strings/bcmp.c
@@ -1,30 +1,35 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
bcmp(s1, s2, len) returns 0 if the "len" bytes starting at "s1" are
identical to the "len" bytes starting at "s2", non-zero if they are
different.
- Now only used with purify.
+ Now only used with purify because purify gives wrong warnings when
+ comparing a shorter string with bcmp.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
+#ifdef HAVE_purify
+#undef bcmp
+#undef HAVE_BCMP
+#endif
+
#if !defined(bcmp) && !defined(HAVE_BCMP)
#if defined(MC68000) && defined(DS90)
@@ -46,14 +51,11 @@ uint len; /* 0 <= len <= 65535 */
#else
-#ifdef HAVE_purify
-int my_bcmp(s1, s2, len)
+#ifndef HAVE_purify
+int bcmp(register const char *s1,register const char *s2, register uint len)
#else
-int bcmp(s1, s2, len)
+int my_bcmp(register const char *s1,register const char *s2, register uint len)
#endif
- register const char *s1;
- register const char *s2;
- register uint len;
{
while (len-- != 0 && *s1++ == *s2++) ;
return len+1;
diff --git a/strings/bcopy-duff.c b/strings/bcopy-duff.c
index 2f5a709c3a0..5ac6a716dab 100644
--- a/strings/bcopy-duff.c
+++ b/strings/bcopy-duff.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define IFACTOR 4
diff --git a/strings/bfill.c b/strings/bfill.c
index 9f5db7201d0..85d21483b41 100644
--- a/strings/bfill.c
+++ b/strings/bfill.c
@@ -29,7 +29,7 @@
code is presented for your interest and amusement.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if !defined(bfill) && !defined(HAVE_BFILL)
diff --git a/strings/bmove.c b/strings/bmove.c
index 466bf74db75..09fe067adcd 100644
--- a/strings/bmove.c
+++ b/strings/bmove.c
@@ -36,7 +36,7 @@
code is presented for your interest and amusement.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if !defined(HAVE_BMOVE) && !defined(bmove)
diff --git a/strings/bmove512.c b/strings/bmove512.c
index 11dc282d05c..30ac4b744b6 100644
--- a/strings/bmove512.c
+++ b/strings/bmove512.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : bmove512.c
Author : Michael Widenius;
@@ -27,7 +26,7 @@
fastest way to move a mutiple of 512 byte.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#ifndef bmove512
diff --git a/strings/bmove_upp-sparc.s b/strings/bmove_upp-sparc.s
index 4fae7f5cc7c..f38c391f8ab 100644
--- a/strings/bmove_upp-sparc.s
+++ b/strings/bmove_upp-sparc.s
@@ -27,11 +27,11 @@ bmove_upp:
nop
.loop:
sub %o1, 1, %o1
- ldub [%o1], %g2
+ ldub [%o1], %o3
sub %o0, 1, %o0
subcc %o2, 1, %o2
bcc .loop
- stb %g2, [%o0]
+ stb %o3, [%o0]
.end:
retl
nop
diff --git a/strings/bmove_upp.c b/strings/bmove_upp.c
index af6575ebf41..5319cd9611a 100644
--- a/strings/bmove_upp.c
+++ b/strings/bmove_upp.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : bmove.c
Author : Michael widenius
@@ -24,7 +23,7 @@
"src-len" to the destination "dst-len" counting downwards.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if defined(MC68000) && defined(DS90)
diff --git a/strings/bzero.c b/strings/bzero.c
index cc628e05277..a2b780cb396 100644
--- a/strings/bzero.c
+++ b/strings/bzero.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : bzero.c
Author : Richard A. O'Keefe.
Michael Widenius; ifdef MC68000
diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c
index 89415d31820..22e04337b14 100644
--- a/strings/conf_to_src.c
+++ b/strings/conf_to_src.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* can't use -lmysys because this prog is used to create -lstrings */
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index cccf6730046..1f82c844a50 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* This file is basicly usa7 character sets with some extra functions
@@ -28,7 +27,7 @@
* .configure. mbmaxlen_big5=2
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
@@ -357,7 +356,7 @@ my_bool my_like_range_big5(const char *ptr,uint ptr_length,pchar escape,
*min_length= (uint) (min_str-min_org);
*max_length= res_length;
do {
- *min_str++ = '\0'; /* Because if key compression */
+ *min_str++ = ' '; /* Because if key compression */
*max_str++ = max_sort_char;
} while (min_str != min_end);
return 0;
diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c
index b47eaf3a63f..70f95e0d5d6 100644
--- a/strings/ctype-czech.c
+++ b/strings/ctype-czech.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File strings/ctype-czech.c for MySQL.
@@ -67,7 +66,7 @@
#ifdef REAL_MYSQL
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#else
@@ -427,7 +426,7 @@ my_bool my_like_range_czech(const char *ptr,uint ptr_length,pchar escape,
*
* definition table reworked by Jaromir Dolecek <dolecek@ics.muni.cz>
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uchar NEAR ctype_czech[257] = {
diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c
index df6f8c496bc..d05ca518283 100644
--- a/strings/ctype-euc_kr.c
+++ b/strings/ctype-euc_kr.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* This file is for Korean EUC charset, and created by powerm90@tinc.co.kr.
@@ -27,7 +26,7 @@
* .configure. mbmaxlen_euc_kr=2
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uchar NEAR ctype_euc_kr[257] =
diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c
index a587d72905e..28717d98403 100644
--- a/strings/ctype-gb2312.c
+++ b/strings/ctype-gb2312.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is for Chinese EUC character sets (GB2312), and created by Miles Tsai (net-bull@126.com).
*/
@@ -25,7 +24,7 @@
* .configure. mbmaxlen_gb2312=2
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uchar NEAR ctype_gb2312[257] =
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index a5d55789bb8..9fccce175d8 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is for Chinese character sets GBK, created by Wei He
(hewei@mail.ied.ac.cn)
@@ -28,7 +27,7 @@
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
@@ -2629,12 +2628,12 @@ int my_strnxfrm_gbk(uchar * dest, const uchar * src, int len, int srclen)
}
return srclen;
}
-
+
int my_strxfrm_gbk(uchar * dest, const uchar * src, int len)
{
return my_strnxfrm_gbk(dest,src,len,(uint) strlen((char*) src));
}
-
+
/*
** Calculate min_str and max_str that ranges a LIKE string.
** Arguments:
diff --git a/strings/ctype-latin1_de.c b/strings/ctype-latin1_de.c
new file mode 100644
index 00000000000..5b7a68fb967
--- /dev/null
+++ b/strings/ctype-latin1_de.c
@@ -0,0 +1,302 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ * This file is the latin1 character set with German sorting
+ *
+ * The modern sort order is used, where:
+ *
+ * 'ä' -> "ae"
+ * 'ö' -> "oe"
+ * 'ü' -> "ue"
+ * 'ß' -> "ss"
+ */
+
+/*
+ * This comment is parsed by configure to create ctype.c,
+ * so don't change it unless you know what you are doing.
+ *
+ * .configure. strxfrm_multiply_latin1_de=2
+ */
+
+#include <my_global.h>
+#include "m_string.h"
+#include "m_ctype.h"
+
+uchar ctype_latin1_de[] = {
+ 0,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16,
+ 16,129,129,129,129,129,129, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16,
+ 16,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2
+};
+
+uchar to_lower_latin1_de[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,120,121,122, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,215,248,249,250,251,252,253,254,223,
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
+};
+
+uchar to_upper_latin1_de[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255
+};
+
+/*
+ * This is a simple latin1 mapping table, which maps all accented
+ * characters to their non-accented equivalents. Note: in this
+ * table, 'ä' is mapped to 'A', 'ÿ' is mapped to 'Y', etc. - all
+ * accented characters except the following are treated the same way.
+ * Ü, ü, Ö, ö, Ä, ä
+ */
+
+/* QQ: why it is necessary ? */
+uchar sort_order_latin1_de[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 65, 65, 65, 65,196, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
+ 68, 78, 79, 79, 79, 79,214,215,216, 85, 85, 85,220, 89,222,223,
+ 65, 65, 65, 65,196, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
+ 68, 78, 79, 79, 79, 79,214,247,216, 85, 85, 85,220, 89,222, 89
+};
+
+
+/* same as sort_order_latin_de, but maps ALL accented chars to unacented ones */
+uchar combo1map[]={
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 65, 65, 65, 65, 65, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
+ 68, 78, 79, 79, 79, 79, 79,215,216, 85, 85, 85, 85, 89,222, 83,
+ 65, 65, 65, 65, 65, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73,
+ 68, 78, 79, 79, 79, 79, 79,247,216, 85, 85, 85, 85, 89,222, 89
+};
+
+uchar combo2map[]={
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0,69, 0, 0,83, 0, 0, 0, 0,69, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0,69, 0, 0, 0, 0
+};
+
+/* no longer needed
+#define L1_AE 196
+#define L1_ae 228
+#define L1_OE 214
+#define L1_oe 246
+#define L1_UE 220
+#define L1_ue 252
+#define L1_ss 223
+*/
+
+/*
+ Some notes about the following comparison rules:
+ By definition, my_strnncoll_latin_de must works exactly as if had called
+ my_strnxfrm_latin_de() on both strings and compared the result strings.
+
+ This means that:
+ Ä must also matches ÁE and Aè, because my_strxn_frm_latin_de() will convert
+ both to AE.
+
+ The other option would be to not do any accent removal in
+ sort_order_latin_de[] at all
+*/
+
+int my_strnncoll_latin1_de(const uchar * s1, int len1,
+ const uchar * s2, int len2)
+{
+ const uchar *e1 = s1 + len1;
+ const uchar *e2 = s2 + len2;
+ uchar c1, c12=0, c2, c22=0;
+
+ while ((s1 < e1 || c12) && (s2 < e2 || c22))
+ {
+ if (c12) { c1=c12; c12=0; } else { c12=combo2map[*s1]; c1=combo1map[*s1++]; }
+ if (c22) { c2=c22; c22=0; } else { c22=combo2map[*s2]; c2=combo1map[*s2++]; }
+ if (c1 != c2) return (int)c1 - (int)c2;
+ }
+
+ /* A simple test of string lengths won't work -- we test to see
+ * which string ran out first */
+ return (s1 < e1 || c12)? 1 : (s2 < e2 || c22)? -1 : 0;
+}
+
+
+int my_strnxfrm_latin1_de(uchar * dest, const uchar * src, int len, int srclen)
+{
+ const uchar *dest_orig = dest;
+ const uchar *de = dest + len;
+ const uchar *se = src + srclen;
+ for ( ; src < se && dest < de ; src++)
+ {
+ uchar chr=combo1map[*src];
+ *dest++=chr;
+ if ((chr=combo2map[*src]) && dest < de)
+ *dest++=chr;
+ }
+ return dest - dest_orig;
+}
+
+
+int my_strcoll_latin1_de(const uchar * s1, const uchar * s2)
+{
+ /* XXX QQ: This should be fixed to not call strlen */
+ return my_strnncoll_latin1_de(s1, strlen((char*) s1),
+ s2, strlen((char*) s2));
+}
+
+int my_strxfrm_latin1_de(uchar * dest, const uchar * src, int len)
+{
+ /* XXX QQ: This should be fixed to not call strlen */
+ return my_strnxfrm_latin1_de(dest, src, len, strlen((char*) src));
+}
+
+/*
+ * Calculate min_str and max_str that ranges a LIKE string.
+ * Arguments:
+ * ptr IN: Pointer to LIKE string.
+ * ptr_length IN: Length of LIKE string.
+ * escape IN: Escape character in LIKE. (Normally '\').
+ * No escape characters should appear in min_str or max_str
+ * res_length IN: Length of min_str and max_str.
+ * min_str IN/OUT: Smallest case sensitive string that ranges LIKE.
+ * Should be space padded to res_length.
+ * max_str IN/OUT: Largest case sensitive string that ranges LIKE.
+ * Normally padded with the biggest character sort value.
+ * min_length OUT: Length of min_str without space padding.
+ * max_length OUT: Length of max_str without space padding.
+ *
+ * The function should return 0 if ok and 1 if the LIKE string can't be
+ * optimized !
+ */
+
+#define min_sort_char ((char) 0)
+#define max_sort_char ((char) 255)
+#define wild_one '_'
+#define wild_many '%'
+
+my_bool my_like_range_latin1_de(const char *ptr, uint ptr_length,
+ pchar escape, uint res_length,
+ char *min_str, char *max_str,
+ uint *min_length, uint *max_length)
+{
+ const char *end = ptr + ptr_length;
+ char *min_org = min_str;
+ char *min_end = min_str + res_length;
+
+ for (; ptr != end && min_str != min_end; ptr++)
+ {
+ if (*ptr == escape && ptr + 1 != end)
+ {
+ ptr++; /* Skip escape */
+ *min_str++ = *max_str++ = *ptr;
+ continue;
+ }
+ if (*ptr == wild_one) /* '_' in SQL */
+ {
+ *min_str++ = min_sort_char;
+ *max_str++ = max_sort_char;
+ continue;
+ }
+ if (*ptr == wild_many) /* '%' in SQL */
+ {
+ *min_length = (uint)(min_str - min_org);
+ *max_length = res_length;
+ do {
+ *min_str++ = ' '; /* Because if key compression */
+ *max_str++ = max_sort_char;
+ } while (min_str != min_end);
+ return 0;
+ }
+ *min_str++ = *max_str++ = *ptr;
+ }
+ *min_length = *max_length = (uint) (min_str - min_org);
+
+ /* Temporary fix for handling wild_one at end of string (key compression) */
+ {
+ char *tmp;
+ for (tmp= min_str ; tmp > min_org && tmp[-1] == '\0';)
+ *--tmp=' ';
+ }
+
+ while (min_str != min_end)
+ *min_str++ = *max_str++ = ' '; /* Because if key compression */
+ return 0;
+}
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index 9f23d69eb12..5d5f64cc5fe 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -1,24 +1,23 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file is for Shift JIS charset, and created by tommy@valley.ne.jp.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c
index c39930179cf..671aa74d806 100644
--- a/strings/ctype-tis620.c
+++ b/strings/ctype-tis620.c
@@ -1,4 +1,24 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/*
+ Copyright (C) 2003 by Sathit Jittanupat <jsat66@hotmail.com,jsat66@yahoo.com>
+ * solving bug crash with long text field string
+ * sorting with different number of space or sign char. within string
+
Copyright (C) 2001 by Korakot Chaovavanich <korakot@iname.com> and
Apisilp Trunganont <apisilp@pantip.inet.co.th>
Copyright (C) 1998, 1999 by Pruet Boonma <pruet@eng.cmu.ac.th>
@@ -27,16 +47,12 @@
* .configure. strxfrm_multiply_tis620=4
*/
-#include <global.h>
+#include <my_global.h>
#include <my_sys.h>
#include "m_string.h"
#include "m_ctype.h"
#include "t_ctype.h"
-static uchar* thai2sortable(const uchar *tstr,uint len);
-
-#define BUFFER_MULTIPLY 4
-#define buffsize(s) (BUFFER_MULTIPLY * (strlen(s) + 1))
#define M L_MIDDLE
#define U L_UPPER
#define L L_LOWER
@@ -433,167 +449,160 @@ uchar NEAR sort_order_tis620[]=
(uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377',
};
-/* Convert thai string to "Standard C String Function" sortable string
- Arg: const source string and length of converted string
- Ret: Sortable string
+
+/*
+ Convert thai string to "Standard C String Function" sortable string
+ Arg: const source string and length of converted string
+ Ret: Sortable string
*/
-static uchar* thai2sortable(const uchar * tstr,uint len)
+static void _thai2sortable(uchar *tstr)
{
-/* We use only 3 levels (neglect capitalization). */
-
- const uchar* p = tstr;
- uchar *outBuf;
-/* uchar *pRight1, *pRight2, *pRight3, *pRight4; */
-/* uchar *pLeft1, *pLeft2, *pLeft3, *pLeft4; */
- uchar *pRight1, *pRight2, *pRight3;
- uchar *pLeft1, *pLeft2, *pLeft3;
- uint bufSize;
-
- len = (uint) strnlen((char*) tstr,len);
- bufSize = (uint) buffsize((char*) tstr);
- if(!(pRight1 = (uchar *)malloc(sizeof(uchar) * bufSize))) {
- return( (uchar*) tstr);
- }
- pLeft1 = pRight1;
- outBuf = pRight1;
- if(!(pRight2 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) {
- free(pRight1);
- return((uchar*) tstr);
- }
- pLeft2 = pRight2;
- if(!(pRight3 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) {
- free(pRight1);
- free(pRight2);
- return((uchar*) tstr);
- }
- pLeft3 = pRight3;
-/* if(!(pRight4 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) {
- free(pRight1);
- free(pRight2);
- free(pRight3);
- return((uchar*) tstr);
- }
- pLeft4 = pRight4;*/
- while(len--) {
- if(isldvowel(*p) && isconsnt(p[1])) {
- *pRight1++ = t_ctype[p[1]][0];
- *pRight2++ = t_ctype[p[1]][1];
- *pRight3++ = t_ctype[p[1]][2];
-/* *pRight4++ = t_ctype[p[1]][3]; */
- *pRight1++ = t_ctype[*p][0];
- *pRight2++ = t_ctype[*p][1];
- *pRight3++ = t_ctype[*p][2];
-/* *pRight4++ = t_ctype[*p][3]; */
- len--;
- p += 2;
- } else {
- *pRight1 = t_ctype[*p][0];
- if(*pRight1 != IGNORE) pRight1++;
- *pRight2 = t_ctype[*p][1];
- if(*pRight2 != IGNORE) pRight2++;
- *pRight3 = t_ctype[*p][2];
- if(*pRight3 != IGNORE) pRight3++;
-/* *pRight4 = t_ctype[*p][3];
- if(*pRight4 != IGNORE) pRight4++;*/
- p++;
+ uchar *p;
+ int len, tlen;
+ uchar l2bias;
+
+ tlen= len= strlen (tstr);
+ l2bias= 256 - 8;
+ for (p= tstr; tlen > 0; p++, tlen--)
+ {
+ uchar c= *p;
+
+ if (isthai(c))
+ {
+ int *t_ctype0= t_ctype[c];
+
+ if (isconsnt(c))
+ l2bias -= 8;
+ if (isldvowel(c) && isconsnt(p[1]))
+ {
+ /* simply swap between leading-vowel and consonant */
+ *p= p[1];
+ p[1]= c;
+ tlen--;
+ p++;
+ continue;
+ }
+
+ /* if found level 2 char (L2_GARAN,L2_TONE*,L2_TYKHU) move to last */
+ if (t_ctype0[1] >= L2_GARAN)
+ {
+ /*
+ l2bias use to control position weight of l2char
+ example (*=l2char) XX*X must come before X*XX
+ */
+ strmov(p,p+1);
+ tstr[len-1]= l2bias + t_ctype0[1]- L2_GARAN +1;
+ p--;
+ continue;
+ }
+ }
+ else
+ {
+ l2bias-= 8;
+ *p= to_lower_tis620[c];
}
}
- *pRight1++ = L2_BLANK;
- *pRight2++ = L3_BLANK;
-/* *pRight3++ = L4_BLANK; */
- *pRight3++ = '\0';
-/* *pRight4++ = '\0'; */
- memcpy(pRight1, pLeft2, pRight2 - pLeft2);
- pRight1 += pRight2 - pLeft2;
- memcpy(pRight1, pLeft3, pRight3 - pLeft3);
-/* pRight1 += pRight3 - pLeft3; */
-/* memcpy(pRight1, pLeft4, pRight4 - pLeft4); */
- free(pLeft2);
- free(pLeft3);
-/* free(pLeft4); */
- return(outBuf);
}
-/* strncoll() replacement, compare 2 string, both are conveted to sortable string
- Arg: 2 Strings and it compare length
- Ret: strcmp result
+
+/*
+ strncoll() replacement, compare 2 string, both are converted to sortable
+ string
+
+ Arg: 2 Strings and it compare length
+ Ret: strcmp result
*/
+
int my_strnncoll_tis620(const uchar * s1, int len1, const uchar * s2, int len2)
{
+ uchar buf[80] ;
uchar *tc1, *tc2;
int i;
- tc1 = thai2sortable(s1, len1);
- tc2 = thai2sortable(s2, len2);
- i = strcmp((char*)tc1, (char*)tc2);
- free(tc1);
- free(tc2);
- return(i);
+
+ len1= (int) strnlen((char*) s1,len1);
+ len2= (int) strnlen((char*) s2,len2);
+ tc1= buf;
+ if ((len1 + len2 +2) > (int) sizeof(buf))
+ tc1= (uchar*) malloc(len1+len2);
+ tc2= tc1 + len1+1;
+ memcpy((char*) tc1, (char*) s1, len1);
+ tc1[len1]= 0; /* if length(s1)> len1, need to put 'end of string' */
+ memcpy((char *)tc2, (char *)s2, len2);
+ tc2[len2]= 0; /* put end of string */
+ _thai2sortable(tc1);
+ _thai2sortable(tc2);
+ i= strcmp((char*)tc1, (char*)tc2);
+ if (tc1 != buf)
+ free(tc1);
+ return i;
}
-/* strnxfrm replacment, convert Thai string to sortable string
- Arg: Destination buffer, source string, dest length and source length
- Ret: Conveted string size
+
+/*
+ strnxfrm replacment, convert Thai string to sortable string
+
+ Arg: Destination buffer, source string, dest length and source length
+ Ret: Conveted string size
*/
+
int my_strnxfrm_tis620(uchar * dest, const uchar * src, int len, int srclen)
{
- uint bufSize;
- uchar *tmp;
- bufSize = (uint) buffsize((char*)src);
- tmp = thai2sortable(src,srclen);
- set_if_smaller(bufSize,(uint) len);
- memcpy((uchar *)dest, tmp, bufSize);
- free(tmp);
- return (int) bufSize;
+ if (len > srclen)
+ len= srclen ;
+ strnmov(dest, src, len) ;
+ dest[len]= 0; /* if length(src) > len, need to put 'end of string' */
+ _thai2sortable(dest);
+ return strlen(dest);
}
-/* strcoll replacment, compare 2 strings
- Arg: 2 strings
- Ret: strcmp result
+
+/*
+ strcoll replacment, compare 2 strings
+ Arg: 2 strings
+ Ret: strcmp result
*/
+
int my_strcoll_tis620(const uchar * s1, const uchar * s2)
{
- uchar *tc1, *tc2;
- int i;
- tc1 = thai2sortable(s1, (uint) strlen((char*)s1));
- tc2 = thai2sortable(s2, (uint) strlen((char*)s2));
- i = strcmp((char*)tc1, (char*)tc2);
- free(tc1);
- free(tc2);
- return(i);
+ return my_strnncoll_tis620(s1, strlen((char *)s1),s2,strlen((char *)s2));
}
-/* strxfrm replacment, convert Thai string to sortable string
- Arg: Destination buffer, String and dest buffer size
- Ret: Converting string size
+
+/*
+ strxfrm replacment, convert Thai string to sortable string
+
+ Arg: Destination buffer, String and dest buffer size
+ Ret: Converting string size
*/
+
int my_strxfrm_tis620(uchar * dest, const uchar * src, int len)
{
- uint bufSize;
- uchar *tmp;
-
- bufSize = (uint) buffsize((char*) src);
- tmp = thai2sortable(src, len);
- memcpy((uchar *) dest, tmp, bufSize);
- free(tmp);
- return bufSize;
+ return my_strnxfrm_tis620(dest,src,len,strlen((char *)src));
}
-/* Convert SQL like string to C string
- Arg: String, its length, escape character, resource length, minimal string and maximum string
- Ret: Alway 0
+
+/*
+ Convert SQL LIKE string to C string
+
+ Arg: String, its length, escape character, resource length,
+ minimal string and maximum string
+ Ret: Always 0
+*/
+
+/*
+ We just copy this function from opt_range.cc. No need to convert to
+ thai2sortable string. min_str and max_str will be use for comparison and
+ converted there.
*/
-/* We just copy this function from opt_range.cc. No need to convert to
- thai2sortable string. min_str and max_str will be use for comparison and
- converted there. */
#define max_sort_chr ((char) 255)
#define wild_one '_'
#define wild_many '%'
my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
- uint res_length, char *min_str, char *max_str,
- uint *min_length, uint *max_length)
+ uint res_length, char *min_str, char *max_str,
+ uint *min_length, uint *max_length)
{
const char *end=ptr+ptr_length;
char *min_org=min_str;
@@ -604,7 +613,7 @@ my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
if (*ptr == escape && ptr+1 != end)
{
ptr++; /* Skipp escape */
- *min_str++= *max_str++ = *ptr;
+ *min_str++ = *max_str++ = *ptr;
continue;
}
if (*ptr == wild_one) /* '_' in SQL */
@@ -618,7 +627,7 @@ my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
*min_length= (uint) (min_str - min_org);
*max_length=res_length;
do {
- *min_str++ = ' '; /* Because if key compression */
+ *min_str++ = ' '; /* Because of key compression */
*max_str++ = max_sort_chr;
} while (min_str != min_end);
return 0;
@@ -628,36 +637,43 @@ my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
*min_length= *max_length = (uint) (min_str - min_org);
while (min_str != min_end)
- *min_str++ = *max_str++ = ' '; /* Because if key compression */
+ *min_str++= *max_str++ = ' '; /* Because of key compression */
return 0;
}
-/* Thai normalization for input sub system
- Arg: Buffer, 's length, String, 'length
- Ret: Void
+
+/*
+ Thai normalization for input sub system
+
+ Arg: Buffer, 's length, String, 'length
*/
+
void ThNormalize(uchar* ptr, uint field_length, const uchar* from, uint length)
{
- const uchar* fr = from;
- uchar* p = ptr;
+ const uchar *fr= from;
+ uchar *p= ptr;
+ uint i;
- if(length > field_length) {
- length = field_length;
- }
- while (length--)
+ if (length > field_length)
+ length= field_length;
+
+ for (i=0;i<length;i++,p++,fr++)
{
- if((istone(*fr) || isdiacrt1(*fr)) &&
- (islwrvowel(fr[1]) || isuprvowel(fr[1])))
- {
- *p = fr[1];
- p[1] = *fr;
- fr += 2;
- p += 2;
- length--;
- }
- else
+ *p= *fr ;
+
+ /* Sathit's NOTE: it's better idea not to do any normalize */
+ if (istone(*fr) || isdiacrt1(*fr))
{
- *p++ = *fr++;
+ if (i > 0 && (islwrvowel(fr[-1]) || isuprvowel(fr[-1])))
+ continue;
+ if(islwrvowel(fr[1]) || isuprvowel(fr[1]))
+ {
+ *p= fr[1];
+ p[1]= *fr;
+ fr++;
+ p++;
+ i++;
+ }
}
}
}
diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c
index 5356978976f..650182bfda1 100644
--- a/strings/ctype-ujis.c
+++ b/strings/ctype-ujis.c
@@ -25,7 +25,7 @@
* .configure. mbmaxlen_ujis=3
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uchar NEAR ctype_ujis[257] =
diff --git a/strings/ctype.c b/strings/ctype.c
index e66c9771d78..8e3571b1b88 100644
--- a/strings/ctype.c
+++ b/strings/ctype.c
@@ -1,23 +1,24 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include <global.h>
+#include <my_global.h>
#include <m_ctype.h>
+#ifndef SCO
#include <m_string.h>
+#endif
/* generated by make, using conf_to_src */
#include "ctype_extra_sources.c"
diff --git a/strings/do_ctype.c b/strings/do_ctype.c
index e05926bf8d3..f51770e3633 100644
--- a/strings/do_ctype.c
+++ b/strings/do_ctype.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Prints case-convert and sort-convert tabell on stdout. This is used to
make _ctype.c easyer */
@@ -22,7 +21,7 @@
#undef DBUG_OFF
#endif
-#include <global.h>
+#include <my_global.h>
#include <ctype.h>
#include <my_sys.h>
#include "m_string.h"
@@ -146,7 +145,7 @@ void init_case_convert()
higher_pos= (uchar * ) "\217\216\231\232\220"; /* Extra chars to konv. */
lower_pos= (uchar * ) "\206\204\224\201\202";
#else
-#if defined(HPUX) && ASCII_BITS_USED == 8
+#if defined(HPUX10) && ASCII_BITS_USED == 8
higher_pos= (uchar * ) "\xd0\xd8\xda\xdb\xdc\xd3";
lower_pos= (uchar * ) "\xd4\xcc\xce\xdf\xc9\xd7";
#else
@@ -161,7 +160,7 @@ void init_case_convert()
lower_pos= (uchar * ) "{}|`~";
#endif
#endif /* USE_INTERNAL_CTYPE */
-#endif /* HPUX */
+#endif /* HPUX10 */
#endif /* MSDOS */
while (*higher_pos)
@@ -177,7 +176,7 @@ void init_case_convert()
higher_pos= (uchar *) "\217\216\231\232\220";
lower_pos= (uchar *) "\216\217\231YE";
#else
-#if defined(HPUX) && ASCII_BITS_USED == 8
+#if defined(HPUX10) && ASCII_BITS_USED == 8
higher_pos= lower_pos= (uchar *) ""; /* Tecknen i r{tt ordning */
#else
#ifdef USE_ISO_8859_1 /* As in USG5 ICL-386 */
@@ -187,7 +186,7 @@ void init_case_convert()
higher_pos= (uchar *) "][\\~`"; /* R{tt ordning p} tecknen */
lower_pos= (uchar *) "[\\]YE"; /* Ordning enligt ascii */
#endif /* USE_ISO_8859_1 */
-#endif /* HPUX */
+#endif /* HPUX10 */
#endif /* MSDOS */
while (*higher_pos)
diff --git a/strings/int2str.c b/strings/int2str.c
index 4003e8a6167..38e8a5182a3 100644
--- a/strings/int2str.c
+++ b/strings/int2str.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Defines: int2str(), itoa(), ltoa()
@@ -39,7 +38,7 @@
itoa assumes that 10 -base numbers are allways signed and other arn't.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
char NEAR _dig_vec[] =
diff --git a/strings/is_prefix.c b/strings/is_prefix.c
index d3f2b148de2..37d8002703b 100644
--- a/strings/is_prefix.c
+++ b/strings/is_prefix.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : is_prefix.c
Author : Michael Widenius
@@ -23,7 +22,7 @@
A empty t is allways a prefix.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
int is_prefix(register const char *s, register const char *t)
diff --git a/strings/llstr.c b/strings/llstr.c
index 470645a4f65..966b347ac7e 100644
--- a/strings/llstr.c
+++ b/strings/llstr.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Defines: llstr();
@@ -26,7 +25,7 @@
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
char *llstr(longlong value,char *buff)
diff --git a/strings/longlong2str.c b/strings/longlong2str.c
index 5c4eaf98c85..a991c57b4d9 100644
--- a/strings/longlong2str.c
+++ b/strings/longlong2str.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Defines: longlong2str();
@@ -39,7 +38,7 @@
itoa assumes that 10 -base numbers are allways signed and other arn't.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if defined(HAVE_LONG_LONG) && !defined(longlong2str) && !defined(HAVE_LONGLONG2STR)
diff --git a/strings/memcmp.c b/strings/memcmp.c
index 1bb8deaeac0..2f1e4e2ea1f 100644
--- a/strings/memcmp.c
+++ b/strings/memcmp.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* memcmp(lhs, rhs, len)
compares the two memory areas lhs[0..len-1] ?? rhs[0..len-1]. It
diff --git a/strings/memcpy.c b/strings/memcpy.c
index 4fc84fb6052..de79e43ae72 100644
--- a/strings/memcpy.c
+++ b/strings/memcpy.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
memcpy(dst, src, len)
diff --git a/strings/memset.c b/strings/memset.c
index 57c8fea5ebe..53383beb170 100644
--- a/strings/memset.c
+++ b/strings/memset.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : memset.c
Author : Richard A. O'Keefe.
Updated: 25 May 1984
@@ -27,7 +43,7 @@ char *memset(char *dst,int chr, int len)
char *memset(char *dst, register pchar chr, register int len)
{
register char *d;
-
+
for (d = dst; --len >= 0; *d++ = chr) ;
return dst;
}
diff --git a/strings/r_strinstr.c b/strings/r_strinstr.c
index 882a4eda412..76d310a3fda 100644
--- a/strings/r_strinstr.c
+++ b/strings/r_strinstr.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Author : David
@@ -24,7 +23,7 @@
the pattern counted from the begining of the string.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uint r_strinstr(reg1 my_string str,int from, reg4 my_string search)
diff --git a/strings/str2int.c b/strings/str2int.c
index 55fcd56adb9..58669287473 100644
--- a/strings/str2int.c
+++ b/strings/str2int.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
str2int(src, radix, lower, upper, &val)
@@ -39,7 +38,7 @@
call has no problems.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
#include "my_sys.h" /* defines errno */
@@ -50,7 +49,8 @@
X >= 'a' && X <= 'z' ? X-'a'+10 :\
'\177')
-char *str2int(register const char *src, register int radix, long int lower, long int upper, long int *val)
+char *str2int(register const char *src, register int radix, long int lower,
+ long int upper, long int *val)
{
int sign; /* is number negative (+1) or positive (-1) */
int n; /* number of digits yet to be converted */
diff --git a/strings/str_test.c b/strings/str_test.c
index bd54bc6d806..0c3ff471ad7 100644
--- a/strings/str_test.c
+++ b/strings/str_test.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Test of all stringfunktions that is coded in assembler */
-#include <global.h>
+#include <my_global.h>
#include <stdarg.h>
#include "m_string.h"
@@ -131,9 +130,6 @@ int main(void)
if (errors)
fputs("--- Some functions doesn't work!! Fix them\n",stderr);
return(errors > 0);
-
- fputs("Fatal error\n",stderr);
- return(2);
} /* main */
diff --git a/strings/strappend-sparc.s b/strings/strappend-sparc.s
index 69bb555aa47..30b621c3fce 100644
--- a/strings/strappend-sparc.s
+++ b/strings/strappend-sparc.s
@@ -22,28 +22,28 @@
.type strappend,#function
.proc 020
strappend:
- add %o0, %o1, %g3 ! g3 = endpos
- ldsb [%o0], %g2
+ add %o0, %o1, %o3 ! o3 = endpos
+ ldsb [%o0], %o4
.loop1:
add %o0, 1, %o0 ! find end of str
- cmp %g2, 0
+ cmp %o4, 0
bne,a .loop1
- ldsb [%o0], %g2
+ ldsb [%o0], %o4
sub %o0, 1, %o0
- cmp %o0, %g3
+ cmp %o0, %o3
bgeu .end
nop
stb %o2, [%o0]
.loop2:
add %o0, 1, %o0
- cmp %o0, %g3
+ cmp %o0, %o3
blu,a .loop2
stb %o2, [%o0]
.end:
retl
- stb %g0, [%g3]
+ stb %g0, [%o3]
.strappend_end:
.size strappend,.strappend_end-strappend
.ident "Matt Wagner & Monty"
diff --git a/strings/strappend.c b/strings/strappend.c
index d5defaeb0bf..9912bd5197d 100644
--- a/strings/strappend.c
+++ b/strings/strappend.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strappend.c
Author : Monty
@@ -25,7 +24,7 @@
trunked. The des+len character is allways set to NULL.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
@@ -39,5 +38,3 @@ void strappend(register char *s, uint len, pchar fill)
while (s<endpos) *(s++) = fill;
*(endpos) = '\0';
} /* strappend */
-
-
diff --git a/strings/strcat.c b/strings/strcat.c
index 699729cd7b5..3c571514701 100644
--- a/strings/strcat.c
+++ b/strings/strcat.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strcat.c
Author : Richard A. O'Keefe.
Updated: 10 April 1984
diff --git a/strings/strcend.c b/strings/strcend.c
index 246b81d7f7b..a3f00a1057b 100644
--- a/strings/strcend.c
+++ b/strings/strcend.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strcend.c
Author : Michael Widenius: ifdef MC68000
@@ -24,7 +23,7 @@
occurs, or a pointer to the end-null of s if c does not occur in s.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if defined(MC68000) && defined(DS90)
diff --git a/strings/strchr.c b/strings/strchr.c
index ef117d85635..3f1a569c296 100644
--- a/strings/strchr.c
+++ b/strings/strchr.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strchr.c
Author : Richard A. O'Keefe.
Michael Widenius: ifdef MC68000
diff --git a/strings/strcmp.c b/strings/strcmp.c
index d911b2daa17..d673c035dbc 100644
--- a/strings/strcmp.c
+++ b/strings/strcmp.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strcmp.c
Author : Richard A. O'Keefe.
Updated: 10 April 1984
diff --git a/strings/strcont.c b/strings/strcont.c
index 5c7d5d2e55f..1d89be89517 100644
--- a/strings/strcont.c
+++ b/strings/strcont.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strcont.c
Author : Monty
@@ -26,7 +25,7 @@
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
my_string strcont(reg1 const char *str,reg2 const char *set)
diff --git a/strings/strend-sparc.s b/strings/strend-sparc.s
index fd1dba4d36f..0f19f6a435a 100644
--- a/strings/strend-sparc.s
+++ b/strings/strend-sparc.s
@@ -22,12 +22,12 @@
.type strend,#function
.proc 0102
strend:
- ldsb [%o0], %g2 ! Handle first char differently to make
+ ldsb [%o0], %o3 ! Handle first char differently to make
.loop: ! a faster loop
add %o0, 1, %o0
- cmp %g2, 0
+ cmp %o3, 0
bne,a .loop
- ldsb [%o0], %g2
+ ldsb [%o0], %o3
retl
sub %o0,1,%o0
.strend_end:
diff --git a/strings/strend.c b/strings/strend.c
index 3affb9bd5f6..0e9c0333fc8 100644
--- a/strings/strend.c
+++ b/strings/strend.c
@@ -27,7 +27,7 @@
Beware: the asm version works only if strlen(s) < 65535.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#if VaxAsm
diff --git a/strings/strfill.c b/strings/strfill.c
index ef0ccb567d1..0ef56a67706 100644
--- a/strings/strfill.c
+++ b/strings/strfill.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strfill.c
Author : Monty
@@ -25,7 +24,7 @@
strfill() returns pointer to dest+len;
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
my_string strfill(my_string s,uint len,pchar fill)
diff --git a/strings/strings-not-used.h b/strings/strings-not-used.h
index fa4dff318f5..e0dc1eac3a5 100644
--- a/strings/strings-not-used.h
+++ b/strings/strings-not-used.h
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strings.h
Author : Richard A. O'Keefe.
Updated: 1 June 1984
@@ -13,7 +29,7 @@
#ifndef NullS
-#include <global.h> /* Define standar vars */
+#include <my_global.h> /* Define standar vars */
#include "m_string.h"
#define NUL '\0'
diff --git a/strings/strinstr.c b/strings/strinstr.c
index e1d502f4004..1c814d19d47 100644
--- a/strings/strinstr.c
+++ b/strings/strinstr.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strinstr.c
Author : Monty & David
@@ -27,7 +26,7 @@
char is 1.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
uint strinstr(reg1 const char *str,reg4 const char *search)
diff --git a/strings/strlen.c b/strings/strlen.c
index c142a7f2b14..b9be374fa6e 100644
--- a/strings/strlen.c
+++ b/strings/strlen.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strlen.c
Author : Richard A. O'Keefe. / Monty
Michael Widenius; ifdef MC68000
diff --git a/strings/strmake-sparc.s b/strings/strmake-sparc.s
index 9fe72a9f9a2..4effe95774e 100644
--- a/strings/strmake-sparc.s
+++ b/strings/strmake-sparc.s
@@ -25,16 +25,16 @@ strmake:
orcc %g0,%o2,%g0
be,a .end
nop
- ldsb [%o1],%g2
+ ldsb [%o1],%o3
.loop:
- stb %g2,[%o0]
- cmp %g2,0
+ stb %o3,[%o0]
+ cmp %o3,0
be .end ! Jump to end on end of string
add %o1,1,%o1
add %o0,1,%o0
subcc %o2,1,%o2
bne,a .loop
- ldsb [%o1],%g2
+ ldsb [%o1],%o3
.end:
retl
stb %g0,[%o0]
diff --git a/strings/strmake.c b/strings/strmake.c
index 66a230338a1..d2252f648f6 100644
--- a/strings/strmake.c
+++ b/strings/strmake.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strmake.c
Author : Michael Widenius
@@ -22,11 +21,11 @@
strmake(dst,src,length) moves length characters, or until end, of src to
dst and appends a closing NUL to dst.
- Note that is strlen(src) >= length then dst[length] will be set to \0
+ Note that if strlen(src) >= length then dst[length] will be set to \0
strmake() returns pointer to closing null
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#ifdef BAD_STRING_COMPILER
diff --git a/strings/strmov-sparc.s b/strings/strmov-sparc.s
index 6114b0bf6e2..3536685b47b 100644
--- a/strings/strmov-sparc.s
+++ b/strings/strmov-sparc.s
@@ -23,10 +23,10 @@
.proc 0102
strmov:
.loop:
- ldub [%o1], %g2
- stb %g2, [%o0]
+ ldub [%o1], %o3
+ stb %o3, [%o0]
add %o1, 1, %o1
- cmp %g2, 0
+ cmp %o3, 0
bne,a .loop
add %o0, 1, %o0
retl
diff --git a/strings/strmov.c b/strings/strmov.c
index 8f5beb41f41..507c2b6d997 100644
--- a/strings/strmov.c
+++ b/strings/strmov.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
strmov(dst, src) moves all the characters of src (including the
@@ -23,7 +22,7 @@
into dst, which seems useful.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#ifdef BAD_STRING_COMPILER
diff --git a/strings/strnlen.c b/strings/strnlen.c
index 3d625f7d48a..fc8879b3a41 100644
--- a/strings/strnlen.c
+++ b/strings/strnlen.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* File : strnlen.c
Author : Michael Widenius
@@ -22,7 +21,7 @@
strnlen(s, len) returns the length of s or len if s is longer than len.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#ifndef HAVE_STRNLEN
diff --git a/strings/strnmov-sparc.s b/strings/strnmov-sparc.s
index 2dfcb95ab76..f681318f410 100644
--- a/strings/strnmov-sparc.s
+++ b/strings/strnmov-sparc.s
@@ -25,16 +25,16 @@ strnmov:
orcc %g0,%o2,%g0
be,a .end
nop
- ldsb [%o1],%g2
+ ldsb [%o1],%o3
.loop:
- stb %g2,[%o0]
- cmp %g2,0
+ stb %o3,[%o0]
+ cmp %o3,0
be .end ! Jump to end on end of string
add %o1,1,%o1
add %o0,1,%o0
subcc %o2,1,%o2
bne,a .loop
- ldsb [%o1],%g2
+ ldsb [%o1],%o3
.end:
retl
nop
diff --git a/strings/strnmov.c b/strings/strnmov.c
index ffc4a62f75e..362f3d6c4a8 100644
--- a/strings/strnmov.c
+++ b/strings/strnmov.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
strnmov(dst,src,length) moves length characters, or until end, of src to
@@ -22,7 +21,7 @@
truncated.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
char *strnmov(register char *dst, register const char *src, uint n)
diff --git a/strings/strrchr.c b/strings/strrchr.c
index 5a045ac3740..fb588c015f2 100644
--- a/strings/strrchr.c
+++ b/strings/strrchr.c
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/* File : strrchr.c
Author : Richard A. O'Keefe.
Updated: 10 April 1984
diff --git a/strings/strstr-sparc.s b/strings/strstr-sparc.s
index 1263236f107..eb658e9f7f0 100644
--- a/strings/strstr-sparc.s
+++ b/strings/strstr-sparc.s
@@ -33,10 +33,10 @@ strstr:
ldsb [%o1],%o2 ! o2= First char of search
.top:
- ldsb [%o0],%g3 ! g3= First char of rest of str
- cmp %g3,0
+ ldsb [%o0],%o4 ! o4= First char of rest of str
+ cmp %o4,0
be .abort ! Found end null ;
- cmp %g3,%o2
+ cmp %o4,%o2
bne .top
add %o0,1,%o0
@@ -45,20 +45,20 @@ strstr:
! while (*j)
! if (*i++ != *j++) goto skipp;
- or %g0,%o0,%g2
- add %o1,1,%g3 ! g3= search+1
+ or %g0,%o0,%o3
+ add %o1,1,%o4 ! o4= search+1
ldsb [%o0],%o5 ! o5= [current_str+1]
.loop2:
- ldsb [%g3],%g4
- add %g3,1,%g3
+ ldsb [%o4],%g4
+ add %o4,1,%o4
cmp %g4,0
be .end
cmp %o5,%g4
bne .top
- add %g2,1,%g2
+ add %o3,1,%o3
ba .loop2
- ldsb [%g2],%o5
+ ldsb [%o3],%o5
.end:
retl
diff --git a/strings/strstr.c b/strings/strstr.c
index 01b29db0068..ca845568ddb 100644
--- a/strings/strstr.c
+++ b/strings/strstr.c
@@ -27,7 +27,7 @@
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#ifndef HAVE_STRSTR
diff --git a/strings/strto.c b/strings/strto.c
index 54ff2214f60..c98b19a7e67 100644
--- a/strings/strto.c
+++ b/strings/strto.c
@@ -1,19 +1,18 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
strtol,strtoul,strtoll,strtoull
@@ -36,9 +35,7 @@
it can be compiled with the UNSIGNED and/or LONGLONG flag set
*/
-#define strtoll glob_strtoll /* Fix for True64 */
-
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
#include "my_sys.h" /* defines errno */
@@ -106,6 +103,7 @@ function (const char *nptr,char **endptr,int base)
}
/* Check for a sign. */
+ negative= 0;
if (*s == '-')
{
negative = 1;
@@ -113,11 +111,9 @@ function (const char *nptr,char **endptr,int base)
}
else if (*s == '+')
{
- negative = 0;
++s;
}
- else
- negative = 0;
+
if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
s += 2;
diff --git a/strings/strtol.c b/strings/strtol.c
index 87fe0d22cf3..10d7f8f9da6 100644
--- a/strings/strtol.c
+++ b/strings/strtol.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This defines strtol() if neaded */
-#include <global.h>
+#include <my_global.h>
#if !defined(MSDOS) && !defined(HAVE_STRTOL) && !defined(__WIN__)
#include "strto.c"
#endif
diff --git a/strings/strtoll.c b/strings/strtoll.c
index 678c28649ef..b0b4ef328fc 100644
--- a/strings/strtoll.c
+++ b/strings/strtoll.c
@@ -1,24 +1,24 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This is defines strtoll() if neaded */
-#include <global.h>
-#include <m_string.h>
+#define strtoll glob_strtoll /* Fix for True64 */
+
+#include <my_global.h>
#if !defined(HAVE_STRTOLL) && defined(HAVE_LONG_LONG)
#define USE_LONGLONG
#include "strto.c"
diff --git a/strings/strtoul.c b/strings/strtoul.c
index e49a9ebea6a..00e1f820942 100644
--- a/strings/strtoul.c
+++ b/strings/strtoul.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This is defines strtoul() if neaded */
-#include <global.h>
+#include <my_global.h>
#if !defined(MSDOS) && !defined(HAVE_STRTOUL)
#define USE_UNSIGNED
#include "strto.c"
diff --git a/strings/strtoull.c b/strings/strtoull.c
index 74dab95b801..f4f3ce19bf7 100644
--- a/strings/strtoull.c
+++ b/strings/strtoull.c
@@ -1,24 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This is defines strtoull() */
-#include <global.h>
-#include <m_string.h>
+#include <my_global.h>
#if !defined(HAVE_STRTOULL) && defined(HAVE_LONG_LONG)
#define USE_UNSIGNED
#define USE_LONGLONG
diff --git a/strings/strxmov-sparc.s b/strings/strxmov-sparc.s
index e65b56d317d..b4ca531d2e4 100644
--- a/strings/strxmov-sparc.s
+++ b/strings/strxmov-sparc.s
@@ -15,12 +15,17 @@
! Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
! MA 02111-1307, USA
+!
+! Note that this function only works on 32 bit sparc systems
+! on 64 bits the offsets to %sp are different !
+
.file "strxmov-sparc.s"
.section ".text"
.align 4
.global strxmov
.type strxmov,#function
.proc 0102
+
strxmov:
st %o2, [%sp+76] ! store 3rd param before other params
st %o3, [%sp+80] ! store 4th param " "
@@ -28,18 +33,18 @@ strxmov:
st %o4, [%sp+84] ! store 5th param
be .end
st %o5, [%sp+88] ! store last
- add %sp, 76, %g2 ! put pointer to 3rd arg
+ add %sp, 76, %o4 ! put pointer to 3rd arg
.loop:
- ldub [%o1], %g1 ! set values of src (o1)
+ ldub [%o1], %o5 ! set values of src (o1)
add %o1, 1, %o1 ! inc src
- stb %g1, [%o0] ! and dst (o2) equal
- cmp %g1, 0 ! second while cmp
+ stb %o5, [%o0] ! and dst (o2) equal
+ cmp %o5, 0 ! second while cmp
bne,a .loop
add %o0, 1, %o0 ! inc dst
- ld [%g2], %o1 ! get next param
+ ld [%o4], %o1 ! get next param
cmp %o1, 0 ! check if last param
bne .loop
- add %g2, 4, %g2 ! advance to next param
+ add %o4, 4, %o4 ! advance to next param
.end:
retl
stb %g0, [%o0]
diff --git a/strings/strxmov.c b/strings/strxmov.c
index 3ef120a691e..fe1e88c13d0 100644
--- a/strings/strxmov.c
+++ b/strings/strxmov.c
@@ -30,7 +30,7 @@
character pointer, or not the same bit pattern as NullS.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include <stdarg.h>
diff --git a/strings/strxnmov.c b/strings/strxnmov.c
index ec3b6fe71e8..3ef0e57650c 100644
--- a/strings/strxnmov.c
+++ b/strings/strxnmov.c
@@ -37,7 +37,7 @@
needed.
*/
-#include <global.h>
+#include <my_global.h>
#include "m_string.h"
#include <stdarg.h>
diff --git a/strings/t_ctype.h b/strings/t_ctype.h
index 6699244c1f4..4f6f78cd188 100644
--- a/strings/t_ctype.h
+++ b/strings/t_ctype.h
@@ -1,3 +1,19 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
/*
Copyright (C) 1998, 1999 by Pruet Boonma, all rights reserved.
Copyright (C) 1998 by Theppitak Karoonboonyanan, all rights reserved.
@@ -24,7 +40,7 @@ typedef unsigned char tchar;
#define IGNORE 0
-// level 1 symbols & order
+/* level 1 symbols & order */
enum l1_symbols {
L1_08 = TOT_LEVELS,
L1_18,
@@ -125,8 +141,8 @@ enum l1_symbols {
L1_SARA_AI_MAIMUAN,
L1_SARA_AI_MAIMALAI
};
-
-// level 2 symbols & order
+
+/* level 2 symbols & order */
enum l2_symbols {
L2_BLANK = TOT_LEVELS,
L2_THAII,
@@ -139,8 +155,8 @@ enum l2_symbols {
L2_TONE3,
L2_TONE4
};
-
-// level 3 symbols & order
+
+/* level 3 symbols & order */
enum l3_symbols {
L3_BLANK = TOT_LEVELS,
L3_SPACE,
@@ -185,7 +201,7 @@ enum l3_symbols {
L3_V_LINE
};
-// level 4 symbols & order
+/* level 4 symbols & order */
enum l4_symbols {
L4_BLANK = TOT_LEVELS,
L4_MIN,
diff --git a/strings/udiv.c b/strings/udiv.c
index 07af323a706..25f3f4685f0 100644
--- a/strings/udiv.c
+++ b/strings/udiv.c
@@ -1,23 +1,22 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Do udiv and urem if machine dosn't have it */
-#include <global.h>
+#include <my_global.h>
#include <math.h>
unsigned long udiv(long unsigned int a, long unsigned int b)
diff --git a/support-files/MacOSX/Description.plist.sh b/support-files/MacOSX/Description.plist.sh
new file mode 100644
index 00000000000..03212dfdeff
--- /dev/null
+++ b/support-files/MacOSX/Description.plist.sh
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IFPkgDescriptionDeleteWarning</key>
+ <string></string>
+ <key>IFPkgDescriptionDescription</key>
+ <string>MySQL @VERSION@@MYSQL_SERVER_SUFFIX@ for Mac OS X</string>
+ <key>IFPkgDescriptionTitle</key>
+ <string>MySQL @VERSION@@MYSQL_SERVER_SUFFIX@ for Mac OS X</string>
+ <key>IFPkgDescriptionVersion</key>
+ <string>@VERSION@@MYSQL_SERVER_SUFFIX@</string>
+ </dict>
+</plist>
diff --git a/support-files/MacOSX/Info.plist.sh b/support-files/MacOSX/Info.plist.sh
new file mode 100644
index 00000000000..f14902ff379
--- /dev/null
+++ b/support-files/MacOSX/Info.plist.sh
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleGetInfoString</key>
+ <string>MySQL @VERSION@@MYSQL_SERVER_SUFFIX@</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.mysql.mysql</string>
+ <key>CFBundleName</key>
+ <string>MySQL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>@VERSION@</string>
+ <key>IFMajorVersion</key>
+ <integer>4</integer>
+ <key>IFMinorVersion</key>
+ <integer>0</integer>
+ <key>IFPkgFlagAllowBackRev</key>
+ <false/>
+ <key>IFPkgFlagAuthorizationAction</key>
+ <string>RootAuthorization</string>
+ <key>IFPkgFlagDefaultLocation</key>
+ <string>/usr/local</string>
+ <key>IFPkgFlagInstallFat</key>
+ <false/>
+ <key>IFPkgFlagIsRequired</key>
+ <false/>
+ <key>IFPkgFlagRelocatable</key>
+ <false/>
+ <key>IFPkgFlagRestartAction</key>
+ <string>NoRestart</string>
+ <key>IFPkgFlagRootVolumeOnly</key>
+ <true/>
+ <key>IFPkgFlagUpdateInstalledLanguages</key>
+ <false/>
+ <key>IFPkgFormatVersion</key>
+ <real>0.10000000149011612</real>
+</dict>
+</plist>
diff --git a/support-files/MacOSX/Makefile.am b/support-files/MacOSX/Makefile.am
new file mode 100644
index 00000000000..ff16fa3235a
--- /dev/null
+++ b/support-files/MacOSX/Makefile.am
@@ -0,0 +1,57 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA
+
+## Process this file with automake to create Makefile.in
+
+EXTRA_DIST = Info.plist.sh \
+ Description.plist.sh \
+ StartupParameters.plist.sh \
+ postinstall.sh \
+ preinstall.sh \
+ ReadMe.txt \
+ MySQL \
+ StartupItem.Description.plist \
+ StartupItem.Info.plist \
+ StartupItem.postinstall
+
+pkgdata_DATA = Info.plist \
+ Description.plist \
+ StartupParameters.plist \
+ postinstall \
+ preinstall
+
+CLEANFILES = Info.plist \
+ Description.plist \
+ StartupParameters.plist \
+ postinstall \
+ preinstall \
+ ReadMe.txt
+
+SUFFIXES = .sh
+
+.sh:
+ @RM@ -f $@ $@-t
+ @SED@ \
+ -e 's!@''prefix''@!$(prefix)!g' \
+ -e 's!@''VERSION''@!@VERSION@!' \
+ -e 's!@''MYSQL_SERVER_SUFFIX''@!@MYSQL_SERVER_SUFFIX@!' \
+ -e 's!@''MYSQLD_USER''@!@MYSQLD_USER@!' \
+ $< > $@-t
+ @MV@ $@-t $@
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/support-files/MacOSX/MySQL b/support-files/MacOSX/MySQL
new file mode 100755
index 00000000000..f6579700384
--- /dev/null
+++ b/support-files/MacOSX/MySQL
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# /Library/StartupItems/MySQL/MySQL
+#
+# A script to automatically start up MySQL on system bootup
+# for Mac OS X. This is actually just a wrapper script around
+# the standard mysql.server init script, which is included in
+# the binary distribution.
+#
+# (c) 2003 MySQL AB
+# Written by Lenz Grimmer <lenz@mysql.com>
+#
+
+# Suppress the annoying "$1: unbound variable" error when no option
+# was given
+if [ -z $1 ] ; then
+ echo "Usage: $0 [start|stop|restart] "
+ exit 1
+fi
+
+# Source the common setup functions for startup scripts
+test -r /etc/rc.common || exit 1
+. /etc/rc.common
+
+# The path to the mysql.server init script. The official MySQL
+# Mac OS X packages are being installed into /usr/local/mysql.
+SCRIPT="/usr/local/mysql/support-files/mysql.server"
+
+StartService ()
+{
+ if [ "${MYSQLCOM:=-NO-}" = "-YES-" ] ; then
+ ConsoleMessage "Starting MySQL database server"
+ $SCRIPT start > /dev/null 2>&1
+ fi
+}
+
+StopService ()
+{
+ ConsoleMessage "Stopping MySQL database server"
+ $SCRIPT stop > /dev/null 2>&1
+}
+
+RestartService ()
+{
+ ConsoleMessage "Restarting MySQL database server"
+ $SCRIPT restart > /dev/null 2>&1
+}
+
+if test -x $SCRIPT ; then
+ RunService "$1"
+else
+ ConsoleMessage "Could not find MySQL startup script!"
+fi
diff --git a/support-files/MacOSX/StartupItem.Description.plist b/support-files/MacOSX/StartupItem.Description.plist
new file mode 100644
index 00000000000..1f0023bde0d
--- /dev/null
+++ b/support-files/MacOSX/StartupItem.Description.plist
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IFPkgDescriptionDeleteWarning</key>
+ <string></string>
+ <key>IFPkgDescriptionDescription</key>
+ <string>This package enables MySQL to be started up automatically
+ on system bootup.</string>
+ <key>IFPkgDescriptionTitle</key>
+ <string>MySQL Startup Item</string>
+ <key>IFPkgDescriptionVersion</key>
+ <string>1.0</string>
+</dict>
+</plist>
diff --git a/support-files/MacOSX/StartupItem.Info.plist b/support-files/MacOSX/StartupItem.Info.plist
new file mode 100644
index 00000000000..f403fbe7e84
--- /dev/null
+++ b/support-files/MacOSX/StartupItem.Info.plist
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleGetInfoString</key>
+ <string>MySQL Startup Item</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.mysql.mysqlstartup</string>
+ <key>CFBundleName</key>
+ <string>MySQL Startup Item</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>IFMajorVersion</key>
+ <integer>1</integer>
+ <key>IFMinorVersion</key>
+ <integer>0</integer>
+ <key>IFPkgFlagAllowBackRev</key>
+ <false/>
+ <key>IFPkgFlagAuthorizationAction</key>
+ <string>RootAuthorization</string>
+ <key>IFPkgFlagDefaultLocation</key>
+ <string>/Library/StartupItems</string>
+ <key>IFPkgFlagInstallFat</key>
+ <false/>
+ <key>IFPkgFlagIsRequired</key>
+ <false/>
+ <key>IFPkgFlagRelocatable</key>
+ <false/>
+ <key>IFPkgFlagRestartAction</key>
+ <string>NoRestart</string>
+ <key>IFPkgFlagRootVolumeOnly</key>
+ <true/>
+ <key>IFPkgFlagUpdateInstalledLanguages</key>
+ <false/>
+ <key>IFPkgFormatVersion</key>
+ <real>0.10000000149011612</real>
+</dict>
+</plist>
diff --git a/support-files/MacOSX/StartupItem.postinstall b/support-files/MacOSX/StartupItem.postinstall
new file mode 100755
index 00000000000..f6f6f46f211
--- /dev/null
+++ b/support-files/MacOSX/StartupItem.postinstall
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# postinstall script for the MySQL Startup Item Installation package
+#
+# This script modifies /etc/hostconfig in the following ways:
+#
+# - On Mac OS X Server, it disables the startup of the default MySQL
+# installation by changing the "MYSQL" start variable to "-NO-".
+# - If not existent already, it adds a "MYSQLCOM" start variable, which
+# defaults to "-YES-". An already existing MYSQLCOM variable will remain
+# untouched.
+#
+# (c) 2003 MySQL AB
+# Author: Lenz Grimmer <lenz@mysql.com>
+#
+
+CONFFILE="/etc/hostconfig"
+TMPFILE=`basename $CONFFILE` || exit 1
+TMPFILE=`mktemp -t $TMPFILE.tmp` || exit 1
+
+test -e $CONFFILE || exit 1
+
+# Disable the startup of the default MySQL installation that ships with
+# Mac OS X Server to avoid conflicts with our installation on bootup
+sed -e s/^MYSQL=-YES-/MYSQL=-NO-/g < $CONFFILE > $TMPFILE
+
+# Add our MYSQLCOM startup variable (enabled by default)
+grep -q "^MYSQLCOM" $CONFFILE > /dev/null 2>&1
+if [ $? -ne 0 ] ; then
+ echo "MYSQLCOM=-YES-" >> $TMPFILE
+fi
+
+# Install the modified file into the default location
+cp -f $CONFFILE $CONFFILE~ || exit 1
+mv -f $TMPFILE $CONFFILE || echo "Error while installing new $CONFFILE!"
+chmod 644 $CONFFILE
diff --git a/support-files/MacOSX/StartupParameters.plist.sh b/support-files/MacOSX/StartupParameters.plist.sh
new file mode 100644
index 00000000000..f5620c73f5f
--- /dev/null
+++ b/support-files/MacOSX/StartupParameters.plist.sh
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Description</key>
+ <string>MySQL @VERSION@@MYSQL_SERVER_SUFFIX@</string>
+ <key>OrderPreference</key>
+ <string>None</string>
+ <key>Provides</key>
+ <array>
+ <string>MySQL</string>
+ </array>
+ <key>Uses</key>
+ <array>
+ <string>Network</string>
+ <string>Resolver</string>
+ </array>
+ </dict>
+</plist>
diff --git a/support-files/MacOSX/make_mysql_pkg.pl b/support-files/MacOSX/make_mysql_pkg.pl
new file mode 100644
index 00000000000..22283d57098
--- /dev/null
+++ b/support-files/MacOSX/make_mysql_pkg.pl
@@ -0,0 +1,475 @@
+#!/usr/bin/perl -w
+#
+#
+# make_mysql_pkg.pl
+#
+# This script creates a Mac OS X installation package
+# of MySQL for Apple's Installer application.
+#
+# To use it:
+#
+# 1.) Unpack the mysql source tarball and cd into the directory
+# 2.) execute this script
+#
+#
+# Written by Marc Liyanage (http://www.entropy.ch)
+#
+# History:
+#
+# When Who What
+# ------------------------------------------------------------------
+# 2001-09-16 Marc Liyanage First version
+# 2001-11-18 Marc Liyanage Improved configure directory options
+#
+
+use strict;
+use DirHandle;
+
+my $data = {};
+
+$data->{PREFIX_DIR} = "/usr/local/mysql";
+$data->{CONFIG} = join(" ",
+ "--prefix=$data->{PREFIX_DIR}",
+ "--localstatedir=$data->{PREFIX_DIR}/data",
+ "--libdir=$data->{PREFIX_DIR}/lib",
+ "--includedir=$data->{PREFIX_DIR}/include",
+ "--with-named-z-libs=/usr/local/libz.a",
+ "--with-innodb",
+ "--with-server-suffix='-entropy.ch'",
+ "--with-comment='http://www.entropy.ch/software/macosx/mysql/'",
+ "--with-mysqld-user=mysql",
+ "--enable-assembler",
+ "CFLAGS=\"-DHAVE_BROKEN_REALPATH -lncurses\"",
+);
+
+
+
+
+
+prepare($data);
+configure_source($data);
+make($data);
+make_binary_distribution($data);
+create_pax_root($data);
+create_package($data);
+cleanup($data);
+
+print "Package $data->{PACKAGE_TARBALL_FILENAME} created\n";
+
+
+
+
+
+
+# Subroutines follow here...
+
+
+
+
+# Prepares data in the global $data hash, like version numbers,
+# directory names etc. Also makes sure that no old stuff
+# is in our way.
+#
+sub prepare {
+
+ my ($data) = @_;
+
+ # Keep the current wd for reference
+ #
+ $data->{OLDWD} = `pwd`;
+ chomp($data->{OLDWD});
+
+ # Look for configure script
+ #
+ unless (-f "configure") {
+ abort($data, "Unable to find 'configure', make sure you're in the MySQL source toplevel directory!");
+ }
+
+ # Try to find version number there
+ #
+ my $mysql_version_h = `cat configure`;
+ ($data->{VERSION}) = $mysql_version_h =~ /^VERSION=(.+?)$/m;
+
+ unless ($data->{VERSION} =~ /\d+/) {
+ abort($data, "Unable to find MySQL version number!");
+ }
+
+ debug($data, "found MySQL version number $data->{VERSION}");
+
+
+ # PAXROOT_DIR is where we will build our own little
+ # fake /usr/local directory. Make sure it doesn't exist,
+ # then try to create it.
+ #
+ $data->{PAXROOT_DIR} = "/tmp/mysql-$data->{VERSION}-paxroot";
+
+ if (-e $data->{PAXROOT_DIR}) {
+ abort($data, "$data->{PAXROOT_DIR} exists, please remove first");
+ }
+
+ if (system("mkdir $data->{PAXROOT_DIR}")) {
+ abort($data, "Unable to mkdir $data->{PAXROOT_DIR}, please make sure you have the right permissions!");
+ }
+
+
+ # PACKAGE_DIR is where we will build the package directory
+ # hierarchy, according to the standard .pkg layout.
+ #
+ $data->{PACKAGE_NAME} = "mysql-$data->{VERSION}.pkg";
+ $data->{PACKAGE_DIR} = "/tmp/$data->{PACKAGE_NAME}";
+
+ if (-e $data->{PACKAGE_DIR}) {
+ abort($data, "$data->{PACKAGE_DIR} exists, please remove first");
+ }
+
+ if (system("mkdir $data->{PACKAGE_DIR}")) {
+ abort($data, "Unable to mkdir $data->{PACKAGE_DIR}, please make sure you have the right permissions!");
+ }
+
+
+}
+
+
+
+# Configure the MySQL source with our options
+#
+sub configure_source {
+
+ my ($data) = @_;
+
+ if (system("./configure $data->{CONFIG}")) {
+ abort($data, "Unable to configure!");
+ }
+
+}
+
+
+
+
+# Build the software
+#
+sub make {
+
+ my ($data) = @_;
+
+ if (system("make")) {
+ abort($data, "Unable to make!");
+ }
+
+}
+
+
+
+# We don't ever install the software, but instead we use an
+# included script to create a binary distribution
+# tarball.
+#
+sub make_binary_distribution {
+
+ my ($data) = @_;
+
+ if (system("./scripts/make_binary_distribution > make_binary_distribution.out")) {
+ abort($data, "Unable to make_binary_distribution!");
+ }
+
+ my @output = `cat make_binary_distribution.out`;
+ my $last_line = $output[-1];
+ unlink("make_binary_distribution.out");
+
+ my ($tarball_filename, $tarball_directory) = $last_line =~ /^((.+)\.tar\.gz) created/i;
+
+ unless ($tarball_filename and -f $tarball_filename) {
+ abort($data, "Unable determine the output filename of scripts/make_binary_distribution!");
+ }
+
+ $data->{BINARY_TARBALL_FILENAME} = $tarball_filename;
+ $data->{BINARY_TARBALL_DIRECTORY} = $tarball_directory;
+
+}
+
+
+
+
+# Now we build a fake /usr/local directory hierarchy.
+# This will be fed to the pax tool to create the archive.
+#
+sub create_pax_root {
+
+ my ($data) = @_;
+
+ # Go there and try to extract the binary distribution
+ # tarball which we created in the previous step.
+ #
+ chdir($data->{PAXROOT_DIR});
+ my $tarfile = "$data->{OLDWD}/$data->{BINARY_TARBALL_FILENAME}";
+
+ if (system("tar -xzf $tarfile")) {
+ abort($data, "Unable to extract $tarfile inside $data->{PAXROOT_DIR}");
+ }
+
+ # Rename it to what we want it to be in the
+ # installed /usr/local directory later on, i.e.
+ # mysql-<version>. Then create a symlink from
+ # mysql to mysql-<version>
+ #
+ rename($data->{BINARY_TARBALL_DIRECTORY}, "mysql-$data->{VERSION}");
+ symlink("mysql-$data->{VERSION}", "mysql");
+
+
+ # We create a bunch of symlinks in /usr/local/bin and
+ # /usr/local/share/man so that the end-user will not
+ # have to adjust PATH and MANPATH to include the
+ # /usr/local/mysql/bin and man directories.
+ #
+ system("mkdir -p $_") foreach qw(bin share/man);
+
+
+ # First create the symlinks in the bin directory
+ #
+ # 2001-02-13: we no longer use symlinks for the binaries, we
+ # use small dummy scripts instead because the
+ # mysql scripts do a lot of guesswork with their
+ # own path and that will not work when called via the symlink
+ #
+# symlink("../mysql/bin/$_", "$_") foreach (grep {$_ !~ /^\.+$/} DirHandle->new("../mysql/bin")->read());
+
+ chdir("bin");
+
+ foreach my $command (grep {$_ !~ /^\.+$/} DirHandle->new("../mysql/bin")->read()) {
+
+ my $scriptcode = qq+#!/bin/sh\n# Part of the entropy.ch mysql package\ncd /usr/local/mysql/\nexec ./bin/$command "\$\@"\n+;
+ open(SCRIPTFILE, ">$command") or die "Unable to write open $command\n";
+ print SCRIPTFILE $scriptcode;
+ close(SCRIPTFILE);
+ chmod(0755, $command);
+
+ }
+
+
+
+
+
+
+
+ # Now include the man pages. Two problems here:
+ # 1.) the make_binary_distribution script does not seem
+ # to include the man pages, so we have to copy them over
+ # now. [outdated, was fixed by MySQL!]
+ # 2.) The man pages could be in different sections, so
+ # we have to recursively copy *and* symlink them.
+ #
+
+ # First find out what's there in the source distribution.
+ # Store the names of the manpages in anonymous
+ # arrays which in turn will be stored in a hash, using
+ # the section numbers as hash keys.
+ #
+ chdir("$data->{PAXROOT_DIR}/mysql");
+ my %man_sections;
+ foreach my $manpage (grep {$_ =~ /^.+\.(\d+)$/} DirHandle->new("man")->read()) {
+
+ my ($section) = $manpage =~ /\.(\d+)$/;
+
+ $man_sections{$section} ||= [];
+ push @{$man_sections{$section}}, "$manpage";
+
+ }
+
+
+ # Now iterate through the sections and man pages,
+ # and copy/symlink the man pages
+ #
+ chdir("$data->{PAXROOT_DIR}/share/man/");
+
+ foreach my $section (keys(%man_sections)) {
+
+ system("mkdir -p man$section");
+ chdir("man$section");
+
+ foreach my $manpage (@{$man_sections{$section}}) {
+
+ symlink("../../../mysql/man/$manpage", $manpage)
+
+ }
+
+ chdir("..");
+
+ }
+
+
+
+ # Fix up the library and lib directories. They are packed up wrong in the
+ # binary distribution tarball.
+ #
+ # (no longer needed as of 3.23.47)
+ # (oops, still needed because 3.23.47 is broken...)
+ #
+# if (-d "$data->{PAXROOT_DIR}/mysql/lib/mysql") {
+# abort($data, "$data->{PAXROOT_DIR}/mysql/lib/mysql exists, layout has changed!");
+# }
+# chdir("$data->{PAXROOT_DIR}/mysql/lib/");
+# system("mkdir -p mysql");
+# system("mv * mysql");
+
+# if (-d "$data->{PAXROOT_DIR}/mysql/include/mysql") {
+# abort($data, "$data->{PAXROOT_DIR}/mysql/include/mysql exists, layout has changed!");
+# }
+# chdir("$data->{PAXROOT_DIR}/mysql/include/");
+# system("mkdir -p mysql");
+# system("mv * mysql");
+
+
+
+
+
+
+
+
+
+}
+
+
+
+# Take the pax root directory, create a few auxiliary
+# files and then pack everything up into a tarball
+#
+sub create_package {
+
+ my ($data) = @_;
+
+ # Create the resources directory in which all
+ # interesting files for this package will be stored
+ #
+ $data->{PKG_RESOURCES_DIR} = "$data->{PACKAGE_DIR}/Contents/Resources";
+
+ if (system("mkdir -p $data->{PKG_RESOURCES_DIR}")) {
+ abort("Unable to create package resources dir $data->{PKG_RESOURCES_DIR}");
+ }
+
+
+ # Create the big archive with all the files using
+ # the pax tool
+ #
+ chdir($data->{PAXROOT_DIR});
+ if(system("pax -w . | gzip -c > $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.pax.gz")) {
+ abort("Unable to create package pax file");
+ }
+
+
+ # Create the "Bill Of Materials" (bom) file.
+ #
+ if(system("mkbom . $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.bom")) {
+ abort("Unable to create package bom file");
+ }
+
+
+ # Create the ".sizes" file with some information about the package
+ #
+ my $size_uncompressed = `du -sk $data->{PAXROOT_DIR} | cut -f 1`;
+ chomp($size_uncompressed);
+
+ my $size_compressed = `du -sk $data->{PACKAGE_DIR} | cut -f 1`;
+ chomp($size_compressed);
+
+ my $numfiles = `find /tmp/mysql-$data->{VERSION}-paxroot | wc -l`;
+ $numfiles--;
+
+ open(SIZESFILE, ">$data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.sizes") or abort("Unable to write open sizes file $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.sizes");
+ print SIZESFILE "NumFiles $numfiles\n";
+ print SIZESFILE "InstalledSize $size_uncompressed\n";
+ print SIZESFILE "CompressedSize $size_compressed\n";
+ close(SIZESFILE);
+
+
+ # Create the ".info" file with more information abou the package.
+ #
+ open(INFOFILE, ">$data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.info") or abort("Unable to write open sizes file $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.info");
+ my $infodata = join("", <DATA>);
+ $infodata =~ s/<%(.+?)%>/$data->{$1}/eg;
+ abort("Unable to get info file data from __DATA__!") unless ($infodata =~ /\w+/);
+ print INFOFILE $infodata;
+ close(INFOFILE);
+
+
+
+ # Finally, create the .tar.gz file for the package,
+ # this is our end result
+ #
+ chdir($data->{PACKAGE_DIR});
+ chdir("..");
+
+ $data->{PACKAGE_TARBALL_FILENAME} = "$data->{PACKAGE_NAME}.tar.gz";
+
+ if(system("tar -czf $data->{OLDWD}/$data->{PACKAGE_TARBALL_FILENAME} $data->{PACKAGE_NAME}")) {
+ abort("Unable to create package tar file $data->{OLDWD}/$data->{PACKAGE_TARBALL_FILENAME}");
+ }
+
+
+
+}
+
+
+# Abort with an error message
+#
+sub abort {
+
+ my ($data, $errormessage) = @_;
+
+ my ($caller) = (caller(1))[3];
+ $caller =~ s/^main:://;
+
+ print "*** Error: $caller(): $errormessage\n";
+
+ exit 1;
+
+}
+
+
+# Output informative messages
+#
+sub debug {
+
+ my ($data, $message) = @_;
+
+ my ($caller) = (caller(1))[3];
+ $caller =~ s/^main:://;
+
+ print "*** Info: $caller(): $message\n";
+
+}
+
+
+
+# Remove temporary items
+#
+sub cleanup {
+
+ my ($data) = @_;
+
+ chdir($data->{OLDWD});
+
+ system("rm -rf $data->{PACKAGE_DIR}");
+ system("rm -rf $data->{PAXROOT_DIR}");
+ system("rm $data->{BINARY_TARBALL_FILENAME}");
+
+}
+
+
+
+
+__DATA__
+Title MySQL
+Version <%VERSION%>
+Description The MySQL database server in a convenient Mac OS X package. Some additional configuration is necessary, please see http://www.entropy.ch/software/macosx/mysql/
+DefaultLocation /usr/local
+Diskname (null)
+DeleteWarning
+NeedsAuthorization YES
+DisableStop NO
+UseUserMask NO
+Application NO
+Relocatable NO
+Required NO
+InstallOnly NO
+RequiresReboot NO
+InstallFat NO
diff --git a/support-files/MacOSX/postinstall.sh b/support-files/MacOSX/postinstall.sh
new file mode 100644
index 00000000000..f46f4480e3e
--- /dev/null
+++ b/support-files/MacOSX/postinstall.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# postinstall - this script will be executed after the MySQL PKG
+# installation has been performed.
+#
+# This script will install the MySQL privilege tables using the
+# "mysql_install_db" script and will correct the ownerships of these files
+# afterwards.
+#
+
+if cd @prefix@ ; then
+ if [ ! -f data/mysql/db.frm ] ; then
+ ./scripts/mysql_install_db -IN-RPM
+ fi
+
+ if [ -d data ] ; then
+ chown -R @MYSQLD_USER@ data
+ fi
+else
+ exit $?
+fi
diff --git a/support-files/MacOSX/preinstall.sh b/support-files/MacOSX/preinstall.sh
new file mode 100644
index 00000000000..62772573c46
--- /dev/null
+++ b/support-files/MacOSX/preinstall.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# preinstall - this script will be executed before the MySQL PKG
+# installation will be performed.
+#
+# If this package has been compiled with a prefix ending with "mysql" (e.g.
+# /usr/local/mysql or /opt/mysql), it will rename any previosuly existing
+# directory with this name before installing the new package (which includes
+# a symlink named "mysql", pointing to the newly installed directory, which
+# is named mysql-<version>)
+#
+
+PREFIX="@prefix@"
+BASENAME=`basename $PREFIX`
+
+if [ -d $PREFIX -a ! -L $PREFIX -a $BASENAME = "mysql" ] ; then
+ mv $PREFIX $PREFIX.bak
+fi
diff --git a/support-files/Makefile.am b/support-files/Makefile.am
index 00e8b13b12c..79ba6eec763 100644
--- a/support-files/Makefile.am
+++ b/support-files/Makefile.am
@@ -25,7 +25,10 @@ EXTRA_DIST = mysql.spec.sh \
mysql-log-rotate.sh \
mysql.server.sh \
binary-configure.sh \
- magic
+ magic \
+ MySQL-shared-compat.spec.sh
+
+SUBDIRS = MacOSX
pkgdata_DATA = my-small.cnf \
my-medium.cnf \
@@ -33,7 +36,8 @@ pkgdata_DATA = my-small.cnf \
my-huge.cnf \
mysql-log-rotate \
mysql-@VERSION@.spec \
- binary-configure
+ binary-configure \
+ MySQL-shared-compat.spec
pkgdata_SCRIPTS = mysql.server
@@ -45,7 +49,8 @@ CLEANFILES = my-small.cnf \
mysql-@VERSION@.spec \
mysql-log-rotate \
mysql.server \
- binary-configure
+ binary-configure \
+ MySQL-shared-compat.spec
mysql-@VERSION@.spec: mysql.spec
diff --git a/support-files/MySQL-shared-compat.spec.sh b/support-files/MySQL-shared-compat.spec.sh
new file mode 100644
index 00000000000..2a257a601a1
--- /dev/null
+++ b/support-files/MySQL-shared-compat.spec.sh
@@ -0,0 +1,72 @@
+#
+# MySQL-shared-compat.spec
+#
+# RPM build instructions to create a "meta" package that includes two
+# versions of the MySQL shared libraries (for compatibility with
+# distributions that ship older versions of MySQL and do not provide a
+# separate "MySQL-shared" package. This spec file simply repackages two
+# already existing MySQL-shared RPMs into a single package.
+#
+# Copyright (C) 2003 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc., 59
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#
+# Change this to match the version of the shared libs you want to include
+#
+%define version4 @VERSION@
+%define version3 3.23.56
+
+Name: MySQL-shared-compat
+Packager: Lenz Grimmer <build@mysql.com>
+Vendor: MySQL AB
+License: GPL
+Group: Applications/Databases
+URL: http://www.mysql.com/
+Autoreqprov: on
+Version: %{version4}
+Release: 0
+BuildRoot: %{_tmppath}/%{name}-%{version}-build
+Obsoletes: MySQL-shared, mysql-shared
+Provides: MySQL-shared
+Summary: MySQL shared libraries for MySQL %{version4} and %{version3}
+Source0: MySQL-shared-%{version4}-0.%{_arch}.rpm
+Source1: MySQL-shared-%{version3}-1.%{_arch}.rpm
+# No need to include the RPMs once more - they can be downloaded seperately
+# if you want to rebuild this package
+NoSource: 0
+NoSource: 1
+BuildRoot: %{_tmppath}/%{name}-%{version}-build
+
+%description
+This package includes the shared libraries for both MySQL %{version3} and
+MySQL %{version4}. Install this package instead of "MySQL-shared", if you
+have applications installed that are dynamically linked against MySQL
+3.23.xx but you want to upgrade to MySQL 4.0.xx without breaking the library
+dependencies.
+
+%install
+[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT;
+mkdir -p $RPM_BUILD_ROOT
+cd $RPM_BUILD_ROOT
+rpm2cpio %{SOURCE0} | cpio -iv --make-directories
+rpm2cpio %{SOURCE1} | cpio -iv --make-directories
+
+%clean
+[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT;
+
+%files
+%defattr(-, root, root)
+%{_libdir}/libmysqlclient*
diff --git a/support-files/PKG/INSTALL.sh b/support-files/SCO/INSTALL.sh
index 979f33f3f06..979f33f3f06 100755
--- a/support-files/PKG/INSTALL.sh
+++ b/support-files/SCO/INSTALL.sh
diff --git a/support-files/PKG/compile.sh b/support-files/SCO/compile.sh
index 5281ccde02d..5281ccde02d 100644
--- a/support-files/PKG/compile.sh
+++ b/support-files/SCO/compile.sh
diff --git a/support-files/PKG/doc.sh b/support-files/SCO/doc.sh
index 9ef17166a6f..9ef17166a6f 100644
--- a/support-files/PKG/doc.sh
+++ b/support-files/SCO/doc.sh
diff --git a/support-files/PKG/mkpkg.sh b/support-files/SCO/mkpkg.sh
index 5a38113138d..5a38113138d 100644
--- a/support-files/PKG/mkpkg.sh
+++ b/support-files/SCO/mkpkg.sh
diff --git a/support-files/PKG/patch b/support-files/SCO/patch
index 373eb8518c6..373eb8518c6 100644
--- a/support-files/PKG/patch
+++ b/support-files/SCO/patch
diff --git a/support-files/PKG/pkginfo.ini b/support-files/SCO/pkginfo.ini
index 13b8b6adb09..13b8b6adb09 100644
--- a/support-files/PKG/pkginfo.ini
+++ b/support-files/SCO/pkginfo.ini
diff --git a/support-files/PKG/postinstall b/support-files/SCO/postinstall
index 2e199b9af82..2e199b9af82 100644
--- a/support-files/PKG/postinstall
+++ b/support-files/SCO/postinstall
diff --git a/support-files/PKG/preinstall b/support-files/SCO/preinstall
index c1175561a99..c1175561a99 100644
--- a/support-files/PKG/preinstall
+++ b/support-files/SCO/preinstall
diff --git a/support-files/PKG/preremove b/support-files/SCO/preremove
index a89648431c1..a89648431c1 100644
--- a/support-files/PKG/preremove
+++ b/support-files/SCO/preremove
diff --git a/support-files/PKG/prototype.ini b/support-files/SCO/prototype.ini
index ca88bb67a90..ca88bb67a90 100644
--- a/support-files/PKG/prototype.ini
+++ b/support-files/SCO/prototype.ini
diff --git a/support-files/PKG/version b/support-files/SCO/version
index f9dc296b71b..f9dc296b71b 100644
--- a/support-files/PKG/version
+++ b/support-files/SCO/version
diff --git a/support-files/binary-configure.sh b/support-files/binary-configure.sh
index 682ea570b25..107f468bffc 100644
--- a/support-files/binary-configure.sh
+++ b/support-files/binary-configure.sh
@@ -20,5 +20,5 @@ then
echo "Starting the mysqld server. You can test that it is up and running"
echo "with the command:"
echo "./bin/mysqladmin version"
- ./bin/safe_mysqld &
+ ./bin/mysqld_safe &
fi
diff --git a/support-files/build-tags b/support-files/build-tags
new file mode 100755
index 00000000000..d5f9fbf5100
--- /dev/null
+++ b/support-files/build-tags
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+rm -f TAGS
+filter='\.cc$\|\.c$\|\.h$\|\.yy$'
+files=`bk -r sfiles -gU | grep $filter `
+for f in $files ;
+do
+ etags -o TAGS --append $f
+done
diff --git a/support-files/make_mysql_pkg.pl b/support-files/make_mysql_pkg.pl
deleted file mode 100644
index 75345c7275b..00000000000
--- a/support-files/make_mysql_pkg.pl
+++ /dev/null
@@ -1,414 +0,0 @@
-#!/usr/bin/perl -w
-#
-#
-# make_mysql_pkg.pl
-#
-# This script creates a Mac OS X installation package
-# of MySQL for Apple's Installer application.
-#
-# To use it:
-#
-# 1.) Unpack the mysql source tarball and cd into the directory
-# 2.) execute this script
-#
-#
-# Written by Marc Liyanage (http://www.entropy.ch)
-#
-# History:
-#
-# When Who What
-# -------------------------------------------------------------
-# 2001-09-16 Marc Liyanage First version
-
-use strict;
-use DirHandle;
-
-my $data = {};
-
-$data->{PREFIX_DIR} = "/usr/local";
-$data->{CONFIG} = "--prefix=$data->{PREFIX_DIR} --with-innodb";
-
-
-
-
-
-prepare($data);
-configure_source($data);
-make($data);
-make_binary_distribution($data);
-create_pax_root($data);
-create_package($data);
-cleanup($data);
-
-print "Package $data->{PACKAGE_TARBALL_FILENAME} created\n";
-
-
-
-
-
-
-# Subroutines follow here...
-
-
-
-
-# Prepares data in the global $data hash, like version numbers,
-# directory names etc. Also makes sure that no old stuff
-# is in our way.
-#
-sub prepare {
-
- my ($data) = @_;
-
- # Keep the current wd for reference
- #
- $data->{OLDWD} = `pwd`;
- chomp($data->{OLDWD});
-
- # Look for configure script
- #
- unless (-f "configure") {
- abort($data, "Unable to find 'configure', make sure you're in the MySQL source toplevel directory!");
- }
-
- # Try to find version number there
- #
- my $mysql_version_h = `cat configure`;
- ($data->{VERSION}) = $mysql_version_h =~ /^VERSION=(.+?)$/m;
-
- unless ($data->{VERSION} =~ /\d+/) {
- abort($data, "Unable to find MySQL version number!");
- }
-
- debug($data, "found MySQL version number $data->{VERSION}");
-
-
- # PAXROOT_DIR is where we will build our own little
- # fake /usr/local directory. Make sure it doesn't exist,
- # then try to create it.
- #
- $data->{PAXROOT_DIR} = "/tmp/mysql-$data->{VERSION}-paxroot";
-
- if (-e $data->{PAXROOT_DIR}) {
- abort($data, "$data->{PAXROOT_DIR} exists, please remove first");
- }
-
- if (system("mkdir $data->{PAXROOT_DIR}")) {
- abort($data, "Unable to mkdir $data->{PAXROOT_DIR}, please make sure you have the right permissions!");
- }
-
-
- # PACKAGE_DIR is where we will build the package directory
- # hierarchy, according to the standard .pkg layout.
- #
- $data->{PACKAGE_NAME} = "mysql-$data->{VERSION}.pkg";
- $data->{PACKAGE_DIR} = "/tmp/$data->{PACKAGE_NAME}";
-
- if (-e $data->{PACKAGE_DIR}) {
- abort($data, "$data->{PACKAGE_DIR} exists, please remove first");
- }
-
- if (system("mkdir $data->{PACKAGE_DIR}")) {
- abort($data, "Unable to mkdir $data->{PACKAGE_DIR}, please make sure you have the right permissions!");
- }
-
-
-}
-
-
-
-# Configure the MySQL source with our options
-#
-sub configure_source {
-
- my ($data) = @_;
-
- if (system("./configure $data->{CONFIG}")) {
- abort($data, "Unable to configure!");
- }
-
-}
-
-
-
-
-# Build the software
-#
-sub make {
-
- my ($data) = @_;
-
- if (system("make")) {
- abort($data, "Unable to make!");
- }
-
-}
-
-
-
-# We don't ever install the software, but instead we use an
-# included script to create a binary distribution
-# tarball.
-#
-sub make_binary_distribution {
-
- my ($data) = @_;
-
- if (system("./scripts/make_binary_distribution > make_binary_distribution.out")) {
- abort($data, "Unable to make_binary_distribution!");
- }
-
- my @output = `cat make_binary_distribution.out`;
- my $last_line = $output[-1];
- unlink("make_binary_distribution.out");
-
- my ($tarball_filename, $tarball_directory) = $last_line =~ /^((.+)\.tar\.gz) created/i;
-
- unless ($tarball_filename and -f $tarball_filename) {
- abort($data, "Unable determine the output filename of scripts/make_binary_distribution!");
- }
-
- $data->{BINARY_TARBALL_FILENAME} = $tarball_filename;
- $data->{BINARY_TARBALL_DIRECTORY} = $tarball_directory;
-
-}
-
-
-
-
-# Now we build a fake /usr/local directory hierarchy.
-# This will be fed to the pax tool to create
-# the archive.
-#
-sub create_pax_root {
-
- my ($data) = @_;
-
- # Go there and try to extract the binary distribution
- # tarball which we created in the previous step.
- #
- chdir($data->{PAXROOT_DIR});
- my $tarfile = "$data->{OLDWD}/$data->{BINARY_TARBALL_FILENAME}";
-
- if(system("tar -xzf $tarfile")) {
- abort($data, "Unable to extract $tarfile inside $data->{PAXROOT_DIR}");
- }
-
- # Rename it to what we want it to be in the
- # installed /usr/local directory later on, i.e.
- # mysql-<version>. Then create a symlink from
- # mysql to mysql-<version>
- #
- rename($data->{BINARY_TARBALL_DIRECTORY}, "mysql-$data->{VERSION}");
- symlink("mysql-$data->{VERSION}", "mysql");
-
-
- # We create a bunch of symlinks in /usr/local/bin and
- # /usr/local/share/man so that the end-user will not
- # have to adjust PATH and MANPATH to include the
- # /usr/local/mysql/bin and man directories.
- #
- system("mkdir -p $_") foreach qw(bin share/man);
-
-
- # First create the symlinks in the bin directory
- #
- chdir("bin");
- symlink("../mysql/bin/$_", "$_") foreach (grep {$_ !~ /^\.+$/} DirHandle->new("../mysql/bin")->read());
-
-
- # Now include the man pages. Two problems here:
- # 1.) the make_binary_distribution script does not seem
- # to include the man pages, so we have to copy them over
- # now.
- # 2.) The man pages could be in different sections, so
- # we have to recursively copy *and* symlink them.
- #
-
- # First find out what's there in the source distribution.
- # Store the names of the manpages in anonymous
- # arrays which in turn will be stored in a hash, using
- # the section numbers as hash keys.
- #
- chdir($data->{OLDWD});
- my %man_sections;
- foreach my $manpage (grep {$_ =~ /^.+\.(\d+)$/} DirHandle->new("man")->read()) {
-
- my ($section) = $manpage =~ /\.(\d+)$/;
-
- $man_sections{$section} ||= [];
- push @{$man_sections{$section}}, "$manpage";
-
- }
-
-
- # Now iterate through the sections and man pages,
- # and copy/symlink the man pages
- #
- chdir("$data->{PAXROOT_DIR}/share/man/");
-
- foreach my $section (keys(%man_sections)) {
-
- system("mkdir -p $data->{PAXROOT_DIR}/mysql/man/man$section/");
- system("mkdir -p man$section");
- chdir("man$section");
-
- foreach my $manpage (@{$man_sections{$section}}) {
-
- system("cp $data->{OLDWD}/man/$manpage $data->{PAXROOT_DIR}/mysql/man/man$section/");
- symlink("../../../mysql/man/man$section/$manpage", $manpage)
-
- }
-
- chdir("..");
-
- }
-
-
-}
-
-
-
-# Take the pax root directory, create a few auxiliary
-# files and then pack everything up into a tarball
-#
-sub create_package {
-
- my ($data) = @_;
-
- # Create the resources directory in which all
- # interesting files for this package will be stored
- #
- $data->{PKG_RESOURCES_DIR} = "$data->{PACKAGE_DIR}/Contents/Resources";
-
- if (system("mkdir -p $data->{PKG_RESOURCES_DIR}")) {
- abort("Unable to create package resources dir $data->{PKG_RESOURCES_DIR}");
- }
-
-
- # Create the big archive with all the files using
- # the pax tool
- #
- chdir($data->{PAXROOT_DIR});
- if(system("pax -w . | gzip -c > $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.pax.gz")) {
- abort("Unable to create package pax file");
- }
-
-
- # Create the "Bill Of Materials" (bom) file.
- #
- if(system("mkbom . $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.bom")) {
- abort("Unable to create package bom file");
- }
-
-
- # Create the ".sizes" file with some information about the package
- #
- my $size_uncompressed = `du -sk $data->{PAXROOT_DIR} | cut -f 1`;
- chomp($size_uncompressed);
-
- my $size_compressed = `du -sk $data->{PACKAGE_DIR} | cut -f 1`;
- chomp($size_compressed);
-
- my $numfiles = `find /tmp/mysql-3.23.42-paxroot/ | wc -l`;
- $numfiles--;
-
- open(SIZESFILE, ">$data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.sizes") or abort("Unable to write open sizes file $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.sizes");
- print SIZESFILE "NumFiles $numfiles\n";
- print SIZESFILE "InstalledSize $size_uncompressed\n";
- print SIZESFILE "CompressedSize $size_compressed\n";
- close(SIZESFILE);
-
-
- # Create the ".info" file with more information abou the package.
- #
- open(INFOFILE, ">$data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.info") or abort("Unable to write open sizes file $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.info");
- my $infodata = join("", <DATA>);
- $infodata =~ s/<%(.+?)%>/$data->{$1}/eg;
- abort("Unable to get info file data from __DATA__!") unless ($infodata =~ /\w+/);
- print INFOFILE $infodata;
- close(INFOFILE);
-
-
-
- # Finally, create the .tar.gz file for the package,
- # this is our end result
- #
- chdir($data->{PACKAGE_DIR});
- chdir("..");
-
- $data->{PACKAGE_TARBALL_FILENAME} = "$data->{PACKAGE_NAME}.tar.gz";
-
- if(system("tar -czf $data->{OLDWD}/$data->{PACKAGE_TARBALL_FILENAME} $data->{PACKAGE_NAME}")) {
- abort("Unable to create package tar file $data->{OLDWD}/$data->{PACKAGE_TARBALL_FILENAME}");
- }
-
-
-
-}
-
-
-# Abort with an error message
-#
-sub abort {
-
- my ($data, $errormessage) = @_;
-
- my ($caller) = (caller(1))[3];
- $caller =~ s/^main:://;
-
- print "*** Error: $caller(): $errormessage\n";
-
- exit 1;
-
-}
-
-
-# Output informative messages
-#
-sub debug {
-
- my ($data, $message) = @_;
-
- my ($caller) = (caller(1))[3];
- $caller =~ s/^main:://;
-
- print "*** Info: $caller(): $message\n";
-
-}
-
-
-
-# Remove temporary items
-#
-sub cleanup {
-
- my ($data) = @_;
-
- chdir($data->{OLDWD});
-
- system("rm -rf $data->{PACKAGE_DIR}");
- system("rm -rf $data->{PAXROOT_DIR}");
- system("rm $data->{BINARY_TARBALL_FILENAME}");
-
-}
-
-
-
-
-__DATA__
-Title MySQL
-Version <%VERSION%>
-Description The MySQL database server in a convenient Mac OS X package. Some additional configuration is necessary, please see http://www.entropy.ch/software/macosx/mysql/
-DefaultLocation /usr/local
-Diskname (null)
-DeleteWarning
-NeedsAuthorization YES
-DisableStop NO
-UseUserMask NO
-Application NO
-Relocatable NO
-Required NO
-InstallOnly NO
-RequiresReboot NO
-InstallFat NO \ No newline at end of file
diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh
index 6c204abd4c7..18e926b1400 100644
--- a/support-files/my-huge.cnf.sh
+++ b/support-files/my-huge.cnf.sh
@@ -26,25 +26,96 @@ socket = @MYSQL_UNIX_ADDR@
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@
skip-locking
-set-variable = key_buffer=384M
-set-variable = max_allowed_packet=1M
-set-variable = table_cache=512
-set-variable = sort_buffer=2M
-set-variable = record_buffer=2M
-set-variable = thread_cache=8
+key_buffer = 384M
+max_allowed_packet = 1M
+table_cache = 512
+sort_buffer_size = 2M
+read_buffer_size = 2M
+myisam_sort_buffer_size = 64M
+thread_cache = 8
+query_cache_size = 32M
# Try number of CPU's*2 for thread_concurrency
-set-variable = thread_concurrency=8
-set-variable = myisam_sort_buffer_size=64M
+thread_concurrency = 8
+
+# Don't listen on a TCP/IP port at all. This can be a security enhancement,
+# if all processes that need to connect to mysqld run on the same host.
+# All interaction with mysqld must be made via Unix sockets or named pipes.
+# Note that using this option without enabling named pipes on Windows
+# (via the "enable-named-pipe" option) will render mysqld useless!
+#
+#skip-networking
+
+# Replication Master Server (default)
+# binary logging is required for replication
log-bin
+
+# required unique id between 1 and 2^32 - 1
+# defaults to 1 if master-host is not set
+# but will not function as a master if omitted
server-id = 1
+# Replication Slave (comment out master section to use this)
+#
+# To configure this host as a replication slave, you can choose between
+# two methods :
+#
+# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
+# the syntax is:
+#
+# CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,
+# MASTER_USER=<user>, MASTER_PASSWORD=<password> ;
+#
+# where you replace <host>, <user>, <password> by quoted strings and
+# <port> by the master's port number (3306 by default).
+#
+# Example:
+#
+# CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
+# MASTER_USER='joe', MASTER_PASSWORD='secret';
+#
+# OR
+#
+# 2) Set the variables below. However, in case you choose this method, then
+# start replication for the first time (even unsuccessfully, for example
+# if you mistyped the password in master-password and the slave fails to
+# connect), the slave will create a master.info file, and any later
+# change in this file to the variables' values below will be ignored and
+# overridden by the content of the master.info file, unless you shutdown
+# the slave server, delete master.info and restart the slaver server.
+# For that reason, you may want to leave the lines below untouched
+# (commented) and instead use CHANGE MASTER TO (see above)
+#
+# required unique id between 2 and 2^32 - 1
+# (and different from the master)
+# defaults to 2 if master-host is set
+# but will not function as a slave if omitted
+#server-id = 2
+#
+# The replication master for this slave - required
+#master-host = <hostname>
+#
+# The username the slave will use for authentication when connecting
+# to the master - required
+#master-user = <username>
+#
+# The password the slave will authenticate with when connecting to
+# the master - required
+#master-password = <password>
+#
+# The port the master is listening on.
+# optional - defaults to 3306
+#master-port = <port>
+#
+# binary logging - not required for slaves, but recommended
+#log-bin
+
# Point the following paths to different dedicated disks
#tmpdir = /tmp/
#log-update = /path-to-dedicated-directory/hostname
# Uncomment the following if you are using BDB tables
-#set-variable = bdb_cache_size=384M
-#set-variable = bdb_max_lock=100000
+#bdb_cache_size = 384M
+#bdb_max_lock = 100000
# Uncomment the following if you are using InnoDB tables
#innodb_data_home_dir = @localstatedir@/
@@ -53,17 +124,17 @@ server-id = 1
#innodb_log_arch_dir = @localstatedir@/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
-#set-variable = innodb_buffer_pool_size=384M
-#set-variable = innodb_additional_mem_pool_size=20M
+#innodb_buffer_pool_size = 384M
+#innodb_additional_mem_pool_size = 20M
# Set .._log_file_size to 25 % of buffer pool size
-#set-variable = innodb_log_file_size=100M
-#set-variable = innodb_log_buffer_size=8M
-#innodb_flush_log_at_trx_commit=1
-#set-variable = innodb_lock_wait_timeout=50
+#innodb_log_file_size = 100M
+#innodb_log_buffer_size = 8M
+#innodb_flush_log_at_trx_commit = 1
+#innodb_lock_wait_timeout = 50
[mysqldump]
quick
-set-variable = max_allowed_packet=16M
+max_allowed_packet = 16M
[mysql]
no-auto-rehash
@@ -71,16 +142,16 @@ no-auto-rehash
#safe-updates
[isamchk]
-set-variable = key_buffer=256M
-set-variable = sort_buffer=256M
-set-variable = read_buffer=2M
-set-variable = write_buffer=2M
+key_buffer = 256M
+sort_buffer_size = 256M
+read_buffer = 2M
+write_buffer = 2M
[myisamchk]
-set-variable = key_buffer=256M
-set-variable = sort_buffer=256M
-set-variable = read_buffer=2M
-set-variable = write_buffer=2M
+key_buffer = 256M
+sort_buffer_size = 256M
+read_buffer = 2M
+write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
diff --git a/support-files/my-innodb-heavy-4G.cnf.sh b/support-files/my-innodb-heavy-4G.cnf.sh
new file mode 100644
index 00000000000..ed2c2ce9dfd
--- /dev/null
+++ b/support-files/my-innodb-heavy-4G.cnf.sh
@@ -0,0 +1,509 @@
+#BEGIN CONFIG INFO
+#DESCR: 4GB RAM, InnoDB only, ACID, few connections, heavy queries
+#TYPE: SYSTEM
+#END CONFIG INFO
+
+#
+# This is a MySQL example config file for systems with 4GB of memory
+# running mostly MySQL using InnoDB only tables and performing complex
+# queries with few connections.
+#
+# You can copy this file to /etc/my.cnf to set global options,
+# mysql-data-dir/my.cnf to set server-specific options
+# (@localstatedir@ for this installation) or to
+# ~/.my.cnf to set user-specific options.
+#
+# In this file, you can use all long options that the program supports.
+# If you want to know the options a program supports, run the program
+# with the "--help" option.
+#
+# More detailed information about the individual options can also be
+# found in the manual.
+#
+
+#
+# The following options will be read by MySQL client applications.
+# Note that only client applications shipped by MySQL are guaranteed
+# to read this section. If you want your own MySQL client program to
+# honor these values, you need to specify it as an option during the
+# MySQL client library initialization.
+#
+[client]
+#password = [your_password]
+port = @MYSQL_TCP_PORT@
+socket = @MYSQL_UNIX_ADDR@
+
+# *** Application-specific options follow here ***
+
+#
+# The MySQL server
+#
+[mysqld]
+
+# generic configuration options
+port = @MYSQL_TCP_PORT@
+socket = @MYSQL_UNIX_ADDR@
+
+# back_log is the number of connections the operating system can keep in
+# the listen queue, before the MySQL connection manager thread has
+# processed them. If you have a very high connection rate and experience
+# "connection refused" errors, you might need to increase this value.
+# Check your OS documentation for the maximum value of this parameter.
+# Attempting to set back_log higher than your operating system limit
+# will have no effect.
+back_log = 50
+
+# Don't listen on a TCP/IP port at all. This can be a security
+# enhancement, if all processes that need to connect to mysqld run
+# on the same host. All interaction with mysqld must be made via Unix
+# sockets or named pipes.
+# Note that using this option without enabling named pipes on Windows
+# (via the "enable-named-pipe" option) will render mysqld useless!
+#skip-networking
+
+# The maximum amount of concurrent sessions the MySQL server will
+# allow. One of these connections will be reserved for a user with
+# SUPER privileges to allow the administrator to login even if the
+# connection limit has been reached.
+max_connections = 100
+
+# Maximum amount of errors allowed per host. If this limit is reached,
+# the host will be blocked from connecting to the MySQL server until
+# "FLUSH HOSTS" has been run or the server was restarted. Invalid
+# passwords and other errors during the connect phase result in
+# increasing this value. See the "Aborted_Connects" status variable for
+# global counter.
+max_connect_errors = 10
+
+# The number of open tables for all threads. Increasing this value
+# increases the number of file descriptors that mysqld requires.
+# Therefore you have to make sure to set the amount of open files
+# allowed to at least 4096 in the variable "open-files-limit" in
+# section [mysqld_safe]
+table_cache = 2048
+
+# Enable external file level locking. Enabled file locking will have a
+# negative impact on performance, so only use it in case you have
+# multiple database instances running on the same files (note some
+# restrictions still apply!) or if you use other software relying on
+# locking MyISAM tables on file level.
+#external-locking
+
+# The maximum size of a query packet the server can handle as well as
+# maximum query size server can process (Important when working with
+# large BLOBs). enlarged dynamically, for each connection.
+max_allowed_packet = 16M
+
+# The size of the cache to hold the SQL statements for the binary log
+# during a transaction. If you often use big, multi-statement
+# transactions you can increase this value to get more performance. All
+# statements from transactions are buffered in the binary log cache and
+# are being written to the binary log at once after the COMMIT. If the
+# transaction is larger than this value, temporary file on disk is used
+# instead. This buffer is allocated per connection on first update
+# statement in transaction
+binlog_cache_size = 1M
+
+# Maximum allowed size for a single HEAP (in memory) table. This option
+# is a protection against the accidential creation of a very large HEAP
+# table which could otherwise use up all memory resources.
+max_heap_table_size = 64M
+
+# Sort buffer is used to perform sorts for some ORDER BY and GROUP BY
+# queries. If sorted data does not fit into the sort buffer, a disk
+# based merge sort is used instead - See "sort_merge_passes". Allocated
+# per thread if sort is needed.
+sort_buffer_size = 8M
+
+# This buffer is used for the optimization of full JOINs (JOINs without
+# indexes). Such JOINs are very bad for performance in most cases
+# anyway, but setting this variable to a large value reduces the
+# performance impact. See the "select_full_join" status variable for a
+# count of full JOINs. Allocated per thread if full join is found
+join_buffer_size = 8M
+
+# How many threads we should keep in a cache for reuse. When a client
+# disconnects, the client's threads are put in the cache if there aren't
+# more than thread_cache_size threads from before. This greatly reduces
+# the amount of thread creations needed if you have a lot of new
+# connections. (Normally this doesn't give a notable performance
+# improvement if you have a good thread implementation.)
+thread_cache = 8
+
+# This permits the application to give the threads system a hint for the
+# desired number of threads that should be run at the same time. This
+# value only makes sense on systems that support the thread_concurrency()
+# function call (Sun Solaris, for example).
+# You should try [number of CPUs]*(2..4) for thread_concurrency
+thread_concurrency = 8
+
+# Query cache is used to cache SELECT results and later return them
+# without actual executing the same query once again. Having the query
+# cache enabled may result in significant speed improvements, if your
+# have a lot of identical queries and rarely changing tables. See the
+# "Qcache_lowmem_prunes" status variable to check if the current value
+# is high enough for your load.
+# Note: In case your tables change very often or if your queries are
+# textually different every time, the query cache may result in a
+# slowdown instead of a performance improvement.
+query_cache_size = 64M
+
+# Only cache result sets that are smaller than this limit. This is to
+# protect the query cache of a very large result set overwriting all
+# other query results.
+query_cache_limit = 2M
+
+# Minimum word length to be indexed by the full text search index.
+# You might wish to decrease it if you need to search for shorter words.
+# Note that you need to rebuild your FULLTEXT index, after you have
+# modified this value.
+ft_min_word_len = 4
+
+# If your system supports the memlock() function call, you might want to
+# enable this option while running MySQL to keep it locked in memory and
+# to avoid potential swapping out in case of high memory pressure. Good
+# for performance.
+#memlock
+
+# Table type which is used by default when creating new tables, if not
+# specified differently during the CREATE TABLE statement.
+default_table_type = MYISAM
+
+# Thread stack size to use. This amount of memory is always reserved at
+# connection time. MySQL itself usually needs no more than 64K of
+# memory, while if you use your own stack hungry UDF functions or your
+# OS requires more stack for some operations, you might need to set this
+# to a higher value.
+thread_stack = 192K
+
+# Set the default transaction isolation level. Levels available are:
+# READ-UNCOMMITED, READ-COMMITED, REPEATABLE-READ, SERIALIZABLE
+transaction_isolation = REPEATABLE-READ
+
+# Maximum size for internal (in-memory) temporary tables. If a table
+# grows larger than this value, it is automatically converted to disk
+# based table This limitation is for a single table. There can be many
+# of them.
+tmp_table_size = 64M
+
+# Enable binary logging. This is required for acting as a MASTER in a
+# replication configuration. You also need the binary log if you need
+# the ability to do point in time recovery from your latest backup.
+log_bin
+
+# If you're using replication with chained slaves (A->B->C), you need to
+# enable this option on server B. It enables logging of updates done by
+# the slave thread into the slave's binary log.
+#log_slave_updates
+
+# Enable the full query log. Every query (even ones with incorrect
+# syntax) that the server receives will be logged. This is useful for
+# debugging, it is usually disabled in production use.
+#log
+
+# Print warnings to the error log file. If you have any problem with
+# MySQL you should enable logging of warnings and examine the error log
+# for possible explanations.
+#log_warnings
+
+# Log slow queries. Slow queries are queries which take more than the
+# amount of time defined in "long_query_time" or which do not use
+# indexes well, if log_long_format is enabled. It is normally good idea
+# to have this turned on if you frequently add new queries to the
+# system.
+log_slow_queries
+
+# All queries taking more than this amount of time (in seconds) will be
+# trated as slow. Do not use "1" as a value here, as this will result in
+# even very fast queries being logged from time to time (as MySQL
+# currently measures time with second accuracy only).
+long_query_time = 2
+
+# Log more information in the slow query log. Normally it is good to
+# have this turned on. This will enable logging of queries that are not
+# using indexes in addition to long running queries.
+log_long_format
+
+# The directory used by MySQL for storing temporary files. For example,
+# it is used to perform disk based large sorts, as well as for internal
+# and explicit temporary tables. It might be good to put it on a
+# swapfs/tmpfs filesystem, if you do not create very large temporary
+# files. Alternatively you can put it on dedicated disk. You can
+# specify multiple paths here by separating them by ";" - they will then
+# be used in a round-robin fashion.
+#tmpdir = /tmp
+
+
+# *** Replication related settings
+
+
+# Unique server identification number between 1 and 2^32-1. This value
+# is required for both master and slave hosts. It defaults to 1 if
+# "master-host" is not set, but will MySQL will not function as a master
+# if it is omitted.
+server-id = 1
+
+# Replication Slave (comment out master section to use this)
+#
+# To configure this host as a replication slave, you can choose between
+# two methods :
+#
+# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
+# the syntax is:
+#
+# CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,
+# MASTER_USER=<user>, MASTER_PASSWORD=<password> ;
+#
+# where you replace <host>, <user>, <password> by quoted strings and
+# <port> by the master's port number (3306 by default).
+#
+# Example:
+#
+# CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
+# MASTER_USER='joe', MASTER_PASSWORD='secret';
+#
+# OR
+#
+# 2) Set the variables below. However, in case you choose this method, then
+# start replication for the first time (even unsuccessfully, for example
+# if you mistyped the password in master-password and the slave fails to
+# connect), the slave will create a master.info file, and any later
+# changes in this file to the variable values below will be ignored and
+# overridden by the content of the master.info file, unless you shutdown
+# the slave server, delete master.info and restart the slaver server.
+# For that reason, you may want to leave the lines below untouched
+# (commented) and instead use CHANGE MASTER TO (see above)
+#
+# required unique id between 2 and 2^32 - 1
+# (and different from the master)
+# defaults to 2 if master-host is set
+# but will not function as a slave if omitted
+#server-id = 2
+#
+# The replication master for this slave - required
+#master-host = <hostname>
+#
+# The username the slave will use for authentication when connecting
+# to the master - required
+#master-user = <username>
+#
+# The password the slave will authenticate with when connecting to
+# the master - required
+#master-password = <password>
+#
+# The port the master is listening on.
+# optional - defaults to 3306
+#master-port = <port>
+
+# Make the slave read-only. Only users with the SUPER privilege and the
+# replication slave thread will be able to modify data on it. You can
+# use this to ensure that no applications will accidently modify data on
+# the slave instead of the master
+#read_only
+
+
+#*** MyISAM Specific options
+
+
+# Size of the Key Buffer, used to cache index blocks for MyISAM tables.
+# Do not set it larger than 30% of your available memory, as some memory
+# is also required by the OS to cache rows. Even if you're not using
+# MyISAM tables, you should still set it to 8-64M as it will also be
+# used for internal temporary disk tables.
+key_buffer_size = 32M
+
+# Size of the buffer used for doing full table scans of MyISAM tables.
+# Allocated per thread, if a full scan is needed.
+read_buffer_size = 2M
+
+# When reading rows in sorted order after a sort, the rows are read
+# through this buffer to avoid a disk seeks. You can improve ORDER BY
+# performance a lot, if set this to a high value.
+# Allocated per thread, when needed.
+read_rnd_buffer_size = 16M
+
+# MyISAM uses special tree-like cache to make bulk inserts (that is,
+# INSERT ... SELECT, INSERT ... VALUES (...), (...), ..., and LOAD DATA
+# INFILE) faster. This variable limits the size of the cache tree in
+# bytes per thread. Setting it to 0 will disable this optimisation. Do
+# not set it larger than "key_buffer_size" for optimal performance.
+# This buffer is allocated when a bulk insert is detected.
+bulk_insert_buffer_size = 64M
+
+# This buffer is allocated when MySQL needs to rebuild the index in
+# REPAIR, OPTIMZE, ALTER table statements as well as in LOAD DATA INFILE
+# into an empty table. It is allocated per thread so be careful with
+# large settings.
+myisam_sort_buffer_size = 128M
+
+# The maximum size of the temporary file MySQL is allowed to use while
+# recreating the index (during REPAIR, ALTER TABLE or LOAD DATA INFILE.
+# If the file-size would be bigger than this, the index will be created
+# through the key cache (which is slower).
+myisam_max_sort_file_size = 10G
+
+# If the temporary file used for fast index creation would be bigger
+# than using the key cache by the amount specified here, then prefer the
+# key cache method. This is mainly used to force long character keys in
+# large tables to use the slower key cache method to create the index.
+myisam_max_extra_sort_file_size = 10G
+
+# If a table has more than one index, MyISAM can use more than one
+# thread to repair them by sorting in parallel. This makes sense if you
+# have multiple CPUs and plenty of memory.
+myisam_repair_threads = 1
+
+# Automatically check and repair not properly closed MyISAM tables.
+myisam_recover
+
+
+# *** BDB Specific options ***
+
+# Use this option if you run a MySQL server with BDB support enabled but
+# you do not plan to use it. This will save memory and may speed up some
+# things.
+skip-bdb
+
+
+# *** INNODB Specific options ***
+
+# Use this option if you have a MySQL server with InnoDB support enabled
+# but you do not plan to use it. This will save memory and disk space
+# and speed up some things.
+#skip-innodb
+
+# Additional memory pool that is used by InnoDB to store metadata
+# information. If InnoDB requires more memory for this purpose it will
+# start to allocate it from the OS. As this is fast enough on most
+# recent operating systems, you normally do not need to change this
+# value. SHOW INNODB STATUS will display the current amount used.
+innodb_additional_mem_pool_size = 16M
+
+# InnoDB, unlike MyISAM, uses a buffer pool to cache both indexes and
+# row data. The bigger you set this the less disk I/O is needed to
+# access data in tables. On a dedicated database server you may set this
+# parameter up to 80% of the machine physical memory size. Do not set it
+# too large, though, because competition of the physical memory may
+# cause paging in the operating system. Note that on 32bit systems you
+# might be limited to 2-3.5G of user level memory per process, so do not
+# set it too high.
+innodb_buffer_pool_size = 2G
+
+# InnoDB stores data in one or more data files forming the tablespace.
+# If you have a single logical drive for your data, a single
+# autoextending file would be good enough. In other cases, a single file
+# per device is often a good choice. You can configure InnoDB to use raw
+# disk partitions as well - please refer to the manual for more info
+# about this.
+innodb_data_file_path = ibdata1:10M:autoextend
+
+# Set this option if you would like the InnoDB tablespace files to be
+# stored in another location. By default this is the MySQL datadir.
+#innodb_data_home_dir = <directory>
+
+# Number of IO threads to use for async IO operations. This value is
+# hardcoded to 4 on Unix, but on Windows disk I/O may benefit from a
+# larger number.
+innodb_file_io_threads = 4
+
+# If you run into InnoDB tablespace corruption, setting this to a nonzero
+# value will likely help you to dump your tables. Start from value 1 and
+# increase it until you're able to dump the table successfully.
+#innodb_force_recovery=1
+
+# Number of threads allowed inside the InnoDB kernel. The optimal value
+# depends highly on the application, hardware as well as the OS
+# scheduler properties. A too high value may lead to thread thrashing.
+innodb_thread_concurrency = 16
+
+# If set to 1, InnoDB will flush (fsync) the transaction logs to the
+# disk at each commit, which offers full ACID behavior. If you are
+# willing to compromise this safety, and you are running small
+# transactions, you may set this to 0 or 2 to reduce disk I/O to the
+# logs. Value 0 means that the log is only written to the log file and
+# the log file flushed to disk approximately once per second. Value 2
+# means the log is written to the log file at each commit, but the log
+# file is only flushed to disk approximately once per second.
+innodb_flush_log_at_trx_commit = 1
+
+# Speed up InnoDB shutdown. This will disable InnoDB to do a full purge
+# and insert buffer merge on shutdown. It may increase shutdown time a
+# lot, but InnoDB will have to do it on the next startup instead.
+#innodb_fast_shutdown
+
+# The size of the buffer InnoDB uses for buffering log data. As soon as
+# it is full, InnoDB will have to flush it to disk. As it is flushed
+# once per second anyway, it does not make sense to have it very large
+# (even with long transactions).
+innodb_log_buffer_size = 8M
+
+# Size of each log file in a log group. You should set the combined size
+# of log files to about 25%-100% of your buffer pool size to avoid
+# unneeded buffer pool flush activity on log file overwrite. However,
+# note that a larger logfile size will increase the time needed for the
+# recovery process.
+innodb_log_file_size = 256M
+
+# Total number of files in the log group. A value of 2-3 is usually good
+# enough.
+innodb_log_files_in_group = 3
+
+# Location of the InnoDB log files. Default is the MySQL datadir. You
+# may wish to point it to a dedicated hard drive or a RAID1 volume for
+# improved performance
+#innodb_log_group_home_dir
+
+# Maximum allowed percentage of dirty pages in the InnoDB buffer pool.
+# If it is reached, InnoDB will start flushing them out agressively to
+# not run out of clean pages at all. This is a soft limit, not
+# guaranteed to be held.
+innodb_max_dirty_pages_pct = 90
+
+# The flush method InnoDB will use for Log. The tablespace always uses
+# doublewrite flush logic. The default value is "fdatasync", another
+# option is "O_DSYNC".
+#innodb_flush_method=O_DSYNC
+
+# How long an InnoDB transaction should wait for a lock to be granted
+# before being rolled back. InnoDB automatically detects transaction
+# deadlocks in its own lock table and rolls back the transaction. If you
+# use the LOCK TABLES command, or other transaction-safe storage engines
+# than InnoDB in the same transaction, then a deadlock may arise which
+# InnoDB cannot notice. In cases like this the timeout is useful to
+# resolve the situation.
+innodb_lock_wait_timeout = 120
+
+
+[mysqldump]
+# Do not buffer the whole result set in memory before writing it to
+# file. Required for dumping very large tables
+quick
+
+max_allowed_packet = 16M
+
+[mysql]
+no-auto-rehash
+
+# Only allow UPDATEs and DELETEs that use keys.
+#safe-updates
+
+[isamchk]
+key_buffer = 512M
+sort_buffer_size = 512M
+read_buffer = 8M
+write_buffer = 8M
+
+[myisamchk]
+key_buffer = 512M
+sort_buffer_size = 512M
+read_buffer = 8M
+write_buffer = 8M
+
+[mysqlhotcopy]
+interactive-timeout
+
+[mysqld_safe]
+# Increase the amount of open files allowed per process. Warning: Make
+# sure you have set the global system limit high enough! The high value
+# is required for a large number of opened tables
+open-files-limit = 8192
diff --git a/support-files/my-large.cnf.sh b/support-files/my-large.cnf.sh
index 3c388d611d8..2b92dc61053 100644
--- a/support-files/my-large.cnf.sh
+++ b/support-files/my-large.cnf.sh
@@ -26,21 +26,96 @@ socket = @MYSQL_UNIX_ADDR@
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@
skip-locking
-set-variable = key_buffer=256M
-set-variable = max_allowed_packet=1M
-set-variable = table_cache=256
-set-variable = sort_buffer=1M
-set-variable = record_buffer=1M
-set-variable = myisam_sort_buffer_size=64M
-set-variable = thread_cache=8
+key_buffer = 256M
+max_allowed_packet = 1M
+table_cache = 256
+sort_buffer_size = 1M
+read_buffer_size = 1M
+myisam_sort_buffer_size = 64M
+thread_cache = 8
+query_cache_size= 16M
# Try number of CPU's*2 for thread_concurrency
-set-variable = thread_concurrency=8
+thread_concurrency = 8
+
+# Don't listen on a TCP/IP port at all. This can be a security enhancement,
+# if all processes that need to connect to mysqld run on the same host.
+# All interaction with mysqld must be made via Unix sockets or named pipes.
+# Note that using this option without enabling named pipes on Windows
+# (via the "enable-named-pipe" option) will render mysqld useless!
+#
+#skip-networking
+
+# Replication Master Server (default)
+# binary logging is required for replication
log-bin
+
+# required unique id between 1 and 2^32 - 1
+# defaults to 1 if master-host is not set
+# but will not function as a master if omitted
server-id = 1
+# Replication Slave (comment out master section to use this)
+#
+# To configure this host as a replication slave, you can choose between
+# two methods :
+#
+# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
+# the syntax is:
+#
+# CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,
+# MASTER_USER=<user>, MASTER_PASSWORD=<password> ;
+#
+# where you replace <host>, <user>, <password> by quoted strings and
+# <port> by the master's port number (3306 by default).
+#
+# Example:
+#
+# CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
+# MASTER_USER='joe', MASTER_PASSWORD='secret';
+#
+# OR
+#
+# 2) Set the variables below. However, in case you choose this method, then
+# start replication for the first time (even unsuccessfully, for example
+# if you mistyped the password in master-password and the slave fails to
+# connect), the slave will create a master.info file, and any later
+# change in this file to the variables' values below will be ignored and
+# overridden by the content of the master.info file, unless you shutdown
+# the slave server, delete master.info and restart the slaver server.
+# For that reason, you may want to leave the lines below untouched
+# (commented) and instead use CHANGE MASTER TO (see above)
+#
+# required unique id between 2 and 2^32 - 1
+# (and different from the master)
+# defaults to 2 if master-host is set
+# but will not function as a slave if omitted
+#server-id = 2
+#
+# The replication master for this slave - required
+#master-host = <hostname>
+#
+# The username the slave will use for authentication when connecting
+# to the master - required
+#master-user = <username>
+#
+# The password the slave will authenticate with when connecting to
+# the master - required
+#master-password = <password>
+#
+# The port the master is listening on.
+# optional - defaults to 3306
+#master-port = <port>
+#
+# binary logging - not required for slaves, but recommended
+#log-bin
+
+# Point the following paths to different dedicated disks
+#tmpdir = /tmp/
+#log-update = /path-to-dedicated-directory/hostname
+
# Uncomment the following if you are using BDB tables
-#set-variable = bdb_cache_size=64M
-#set-variable = bdb_max_lock=100000
+#bdb_cache_size = 64M
+#bdb_max_lock = 100000
# Uncomment the following if you are using InnoDB tables
#innodb_data_home_dir = @localstatedir@/
@@ -49,21 +124,17 @@ server-id = 1
#innodb_log_arch_dir = @localstatedir@/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
-#set-variable = innodb_buffer_pool_size=256M
-#set-variable = innodb_additional_mem_pool_size=20M
+#innodb_buffer_pool_size = 256M
+#innodb_additional_mem_pool_size = 20M
# Set .._log_file_size to 25 % of buffer pool size
-#set-variable = innodb_log_file_size=64M
-#set-variable = innodb_log_buffer_size=8M
-#innodb_flush_log_at_trx_commit=1
-#set-variable = innodb_lock_wait_timeout=50
-
-# Point the following paths to different dedicated disks
-#tmpdir = /tmp/
-#log-update = /path-to-dedicated-directory/hostname
+#innodb_log_file_size = 64M
+#innodb_log_buffer_size = 8M
+#innodb_flush_log_at_trx_commit = 1
+#innodb_lock_wait_timeout = 50
[mysqldump]
quick
-set-variable = max_allowed_packet=16M
+max_allowed_packet = 16M
[mysql]
no-auto-rehash
@@ -71,16 +142,16 @@ no-auto-rehash
#safe-updates
[isamchk]
-set-variable = key_buffer=128M
-set-variable = sort_buffer=128M
-set-variable = read_buffer=2M
-set-variable = write_buffer=2M
+key_buffer = 128M
+sort_buffer_size = 128M
+read_buffer = 2M
+write_buffer = 2M
[myisamchk]
-set-variable = key_buffer=128M
-set-variable = sort_buffer=128M
-set-variable = read_buffer=2M
-set-variable = write_buffer=2M
+key_buffer = 128M
+sort_buffer_size = 128M
+read_buffer = 2M
+write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
diff --git a/support-files/my-medium.cnf.sh b/support-files/my-medium.cnf.sh
index a92494358cb..601ffc503c0 100644
--- a/support-files/my-medium.cnf.sh
+++ b/support-files/my-medium.cnf.sh
@@ -27,22 +27,92 @@ socket = @MYSQL_UNIX_ADDR@
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@
skip-locking
-set-variable = key_buffer=16M
-set-variable = max_allowed_packet=1M
-set-variable = table_cache=64
-set-variable = sort_buffer=512K
-set-variable = net_buffer_length=8K
-set-variable = myisam_sort_buffer_size=8M
+key_buffer = 16M
+max_allowed_packet = 1M
+table_cache = 64
+sort_buffer_size = 512K
+net_buffer_length = 8K
+myisam_sort_buffer_size = 8M
+
+# Don't listen on a TCP/IP port at all. This can be a security enhancement,
+# if all processes that need to connect to mysqld run on the same host.
+# All interaction with mysqld must be made via Unix sockets or named pipes.
+# Note that using this option without enabling named pipes on Windows
+# (via the "enable-named-pipe" option) will render mysqld useless!
+#
+#skip-networking
+
+# Replication Master Server (default)
+# binary logging is required for replication
log-bin
+
+# required unique id between 1 and 2^32 - 1
+# defaults to 1 if master-host is not set
+# but will not function as a master if omitted
server-id = 1
+# Replication Slave (comment out master section to use this)
+#
+# To configure this host as a replication slave, you can choose between
+# two methods :
+#
+# 1) Use the CHANGE MASTER TO command (fully described in our manual) -
+# the syntax is:
+#
+# CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,
+# MASTER_USER=<user>, MASTER_PASSWORD=<password> ;
+#
+# where you replace <host>, <user>, <password> by quoted strings and
+# <port> by the master's port number (3306 by default).
+#
+# Example:
+#
+# CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,
+# MASTER_USER='joe', MASTER_PASSWORD='secret';
+#
+# OR
+#
+# 2) Set the variables below. However, in case you choose this method, then
+# start replication for the first time (even unsuccessfully, for example
+# if you mistyped the password in master-password and the slave fails to
+# connect), the slave will create a master.info file, and any later
+# change in this file to the variables' values below will be ignored and
+# overridden by the content of the master.info file, unless you shutdown
+# the slave server, delete master.info and restart the slaver server.
+# For that reason, you may want to leave the lines below untouched
+# (commented) and instead use CHANGE MASTER TO (see above)
+#
+# required unique id between 2 and 2^32 - 1
+# (and different from the master)
+# defaults to 2 if master-host is set
+# but will not function as a slave if omitted
+#server-id = 2
+#
+# The replication master for this slave - required
+#master-host = <hostname>
+#
+# The username the slave will use for authentication when connecting
+# to the master - required
+#master-user = <username>
+#
+# The password the slave will authenticate with when connecting to
+# the master - required
+#master-password = <password>
+#
+# The port the master is listening on.
+# optional - defaults to 3306
+#master-port = <port>
+#
+# binary logging - not required for slaves, but recommended
+#log-bin
+
# Point the following paths to different dedicated disks
#tmpdir = /tmp/
#log-update = /path-to-dedicated-directory/hostname
# Uncomment the following if you are using BDB tables
-#set-variable = bdb_cache_size=4M
-#set-variable = bdb_max_lock=10000
+#bdb_cache_size = 4M
+#bdb_max_lock = 10000
# Uncomment the following if you are using InnoDB tables
#innodb_data_home_dir = @localstatedir@/
@@ -51,17 +121,17 @@ server-id = 1
#innodb_log_arch_dir = @localstatedir@/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
-#set-variable = innodb_buffer_pool_size=16M
-#set-variable = innodb_additional_mem_pool_size=2M
+#innodb_buffer_pool_size = 16M
+#innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
-#set-variable = innodb_log_file_size=5M
-#set-variable = innodb_log_buffer_size=8M
-#innodb_flush_log_at_trx_commit=1
-#set-variable = innodb_lock_wait_timeout=50
+#innodb_log_file_size = 5M
+#innodb_log_buffer_size = 8M
+#innodb_flush_log_at_trx_commit = 1
+#innodb_lock_wait_timeout = 50
[mysqldump]
quick
-set-variable = max_allowed_packet=16M
+max_allowed_packet = 16M
[mysql]
no-auto-rehash
@@ -69,16 +139,16 @@ no-auto-rehash
#safe-updates
[isamchk]
-set-variable = key_buffer=20M
-set-variable = sort_buffer=20M
-set-variable = read_buffer=2M
-set-variable = write_buffer=2M
+key_buffer = 20M
+sort_buffer_size = 20M
+read_buffer = 2M
+write_buffer = 2M
[myisamchk]
-set-variable = key_buffer=20M
-set-variable = sort_buffer=20M
-set-variable = read_buffer=2M
-set-variable = write_buffer=2M
+key_buffer = 20M
+sort_buffer_size = 20M
+read_buffer = 2M
+write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
diff --git a/support-files/my-small.cnf.sh b/support-files/my-small.cnf.sh
index b8941184fe0..3c4cafa688f 100644
--- a/support-files/my-small.cnf.sh
+++ b/support-files/my-small.cnf.sh
@@ -1,7 +1,7 @@
# Example mysql config file for small systems.
#
# This is for a system with little memory (<= 64M) where MySQL is only used
-# from time to time and it's important that the mysqld deamon
+# from time to time and it's important that the mysqld daemon
# doesn't use much resources.
#
# You can copy this file to
@@ -27,12 +27,20 @@ socket = @MYSQL_UNIX_ADDR@
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@
skip-locking
-set-variable = key_buffer=16K
-set-variable = max_allowed_packet=1M
-set-variable = thread_stack=64K
-set-variable = table_cache=4
-set-variable = sort_buffer=64K
-set-variable = net_buffer_length=2K
+key_buffer = 16K
+max_allowed_packet = 1M
+table_cache = 4
+sort_buffer_size = 64K
+net_buffer_length = 2K
+thread_stack = 64K
+
+# Don't listen on a TCP/IP port at all. This can be a security enhancement,
+# if all processes that need to connect to mysqld run on the same host.
+# All interaction with mysqld must be made via Unix sockets or named pipes.
+# Note that using this option without enabling named pipes on Windows
+# (using the "enable-named-pipe" option) will render mysqld useless!
+#
+#skip-networking
server-id = 1
# Uncomment the following if you want to log updates
@@ -48,17 +56,17 @@ server-id = 1
#innodb_log_arch_dir = @localstatedir@/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
-#set-variable = innodb_buffer_pool_size=16M
-#set-variable = innodb_additional_mem_pool_size=2M
+#innodb_buffer_pool_size = 16M
+#innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
-#set-variable = innodb_log_file_size=5M
-#set-variable = innodb_log_buffer_size=8M
-#innodb_flush_log_at_trx_commit=1
-#set-variable = innodb_lock_wait_timeout=50
+#innodb_log_file_size = 5M
+#innodb_log_buffer_size = 8M
+#innodb_flush_log_at_trx_commit = 1
+#innodb_lock_wait_timeout = 50
[mysqldump]
quick
-set-variable = max_allowed_packet=16M
+max_allowed_packet = 16M
[mysql]
no-auto-rehash
@@ -66,12 +74,12 @@ no-auto-rehash
#safe-updates
[isamchk]
-set-variable = key_buffer=8M
-set-variable = sort_buffer=8M
+key_buffer = 8M
+sort_buffer_size = 8M
[myisamchk]
-set-variable = key_buffer=8M
-set-variable = sort_buffer=8M
+key_buffer = 8M
+sort_buffer_size = 8M
[mysqlhotcopy]
interactive-timeout
diff --git a/support-files/mysql-max.spec.sh b/support-files/mysql-max.spec.sh
index 49f131154c0..5c4b16f0e9d 100644
--- a/support-files/mysql-max.spec.sh
+++ b/support-files/mysql-max.spec.sh
@@ -208,7 +208,7 @@ chmod -R og-rw $mysql_datadir/mysql
# Restart in the same way that mysqld will be started normally.
/etc/rc.d/init.d/mysql start
-# Allow safe_mysqld to start mysqld and print a message before we exit
+# Allow mysqld_safe to start mysqld and print a message before we exit
sleep 2
%preun
@@ -244,7 +244,7 @@ fi
%attr(755, root, root) /usr/bin/perror
%attr(755, root, root) /usr/bin/replace
%attr(755, root, root) /usr/bin/resolveip
-%attr(755, root, root) /usr/bin/safe_mysqld
+%attr(755, root, root) /usr/bin/mysqld_safe
%attr(755, root, root) /usr/bin/mysqld_multi
%attr(755, root, root) /usr/bin/my_print_defaults
diff --git a/support-files/mysql-multi.server.sh b/support-files/mysql-multi.server.sh
index 6c940630427..31020029354 100644
--- a/support-files/mysql-multi.server.sh
+++ b/support-files/mysql-multi.server.sh
@@ -133,14 +133,14 @@ case "$mode" in
'start')
# Start daemon
- if test -x $bindir/safe_mysqld
+ if test -x $bindir/mysqld_safe
then
# We only need to specify datadir and pid-file here and we
# get all other instance-specific config from $datadir/my.cnf.
# We have to explicitly pass --defaults-extra-file because it
# reads the config files before the command line options.
- # Also it must be first because of the way safe_mysqld works.
- $bindir/safe_mysqld --defaults-extra-file=$datadir/my.cnf \
+ # Also it must be first because of the way mysqld_safe works.
+ $bindir/mysqld_safe --defaults-extra-file=$datadir/my.cnf \
--datadir=$datadir --pid-file=$pid_file &
# Make lock for RedHat / SuSE
if test -d /var/lock/subsys
@@ -148,7 +148,7 @@ case "$mode" in
touch /var/lock/subsys/mysql
fi
else
- echo "Can't execute $bindir/safe_mysqld"
+ echo "Can't execute $bindir/mysqld_safe"
fi
;;
diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh
index f438899b3bf..7f4987be3a8 100644
--- a/support-files/mysql.server.sh
+++ b/support-files/mysql.server.sh
@@ -10,7 +10,7 @@
# started and shut down when the systems goes down.
# Comments to support chkconfig on RedHat Linux
-# chkconfig: 2345 90 90
+# chkconfig: 2345 90 20
# description: A very fast and reliable SQL database engine.
# Comments to support LSB init script conventions
@@ -18,8 +18,8 @@
# Provides: mysql
# Required-Start: $local_fs $network $remote_fs
# Required-Stop: $local_fs $network $remote_fs
-# Default-Start: 3 5
-# Default-Stop: 3 5
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
# Short-Description: start and stop MySQL
# Description: MySQL is a very fast and reliable SQL database engine.
### END INIT INFO
@@ -57,18 +57,14 @@ fi
PATH=/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin
export PATH
-if test -z "$pid_file"
-then
- pid_file=$datadir/`@HOSTNAME@`.pid
-else
- case "$pid_file" in
- /* ) ;;
- * ) pid_file="$datadir/$pid_file" ;;
- esac
-fi
-
mode=$1 # start or stop
+case `echo "testing\c"`,`echo -n testing` in
+ *c*,-n*) echo_n= echo_c= ;;
+ *c*,*) echo_n=-n echo_c= ;;
+ *) echo_n= echo_c='\c' ;;
+esac
+
parse_arguments() {
for arg do
case "$arg" in
@@ -118,7 +114,31 @@ else
test -z "$print_defaults" && print_defaults="my_print_defaults"
fi
-parse_arguments `$print_defaults mysqld mysql_server mysql.server`
+#
+# Test if someone changed datadir; In this case we should also read the
+# default arguments from this directory
+#
+
+extra_args=""
+if test "$datadir" != "@localstatedir@"
+then
+ extra_args="-e $datadir/my.cnf"
+fi
+
+parse_arguments `$print_defaults $extra_args mysqld mysql_server mysql.server`
+
+#
+# Set pid file if not given
+#
+if test -z "$pid_file"
+then
+ pid_file=$datadir/`@HOSTNAME@`.pid
+else
+ case "$pid_file" in
+ /* ) ;;
+ * ) pid_file="$datadir/$pid_file" ;;
+ esac
+fi
# Safeguard (relative paths, core dumps..)
cd $basedir
@@ -127,18 +147,18 @@ case "$mode" in
'start')
# Start daemon
- if test -x $bindir/safe_mysqld
+ if test -x $bindir/mysqld_safe
then
# Give extra arguments to mysqld with the my.cnf file. This script may
# be overwritten at next upgrade.
- $bindir/safe_mysqld --datadir=$datadir --pid-file=$pid_file &
+ $bindir/mysqld_safe --datadir=$datadir --pid-file=$pid_file >/dev/null 2>&1 &
# Make lock for RedHat / SuSE
if test -w /var/lock/subsys
then
touch /var/lock/subsys/mysql
fi
else
- echo "Can't execute $bindir/safe_mysqld from dir $basedir"
+ echo "Can't execute $bindir/mysqld_safe from dir $basedir"
fi
;;
@@ -155,7 +175,7 @@ case "$mode" in
sleep 1
while [ -s $pid_file -a "$flags" != aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ]
do
- [ -z "$flags" ] && echo "Wait for mysqld to exit\c" || echo ".\c"
+ [ -z "$flags" ] && echo $echo_n "Wait for mysqld to exit$echo_c" || echo $echo_n ".$echo_c"
flags=a$flags
sleep 1
done
@@ -167,16 +187,23 @@ case "$mode" in
# delete lock for RedHat / SuSE
if test -f /var/lock/subsys/mysql
then
- rm /var/lock/subsys/mysql
+ rm -f /var/lock/subsys/mysql
fi
else
echo "No mysqld pid file found. Looked for $pid_file."
fi
;;
+ 'restart')
+ # Stop the service and regardless of whether it was
+ # running or not, start it again.
+ $0 stop
+ $0 start
+ ;;
+
*)
# usage
- echo "usage: $0 start|stop"
+ echo "Usage: $0 start|stop|restart"
exit 1
;;
esac
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 721e928930e..3ee602e7504 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -1,22 +1,25 @@
%define mysql_version @VERSION@
-%define shared_lib_version @SHARED_LIB_VERSION@
-%define release 1
+%define release 0
%define mysqld_user mysql
+%define server_suffix -standard
+
+# We don't package all files installed into the build root by intention -
+# See BUG#998 for details.
+%define _unpackaged_files_terminate_build 0
%define see_base For a description of MySQL see the base MySQL RPM or http://www.mysql.com
Name: MySQL
-Summary: MySQL: a very fast and reliable SQL database engine
+Summary: MySQL: a very fast and reliable SQL database server
Group: Applications/Databases
Summary(pt_BR): MySQL: Um servidor SQL rápido e confiável.
Group(pt_BR): Aplicações/Banco_de_Dados
Version: @MYSQL_NO_DASH_VERSION@
Release: %{release}
-Copyright: GPL / LGPL
+Copyright: GPL
Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/mysql-%{mysql_version}.tar.gz
-Icon: mysql.gif
URL: http://www.mysql.com/
-Packager: Lenz Grimmer <lenz@mysql.com>
+Packager: Lenz Grimmer <build@mysql.com>
Vendor: MySQL AB
Requires: fileutils sh-utils
Provides: msqlormysql MySQL-server mysql
@@ -45,6 +48,41 @@ The MySQL web site (http://www.mysql.com/) provides the latest
news and information about the MySQL software. Also please see the
documentation and the manual for more information.
+%package server
+Release: %{release}
+Summary: MySQL: a very fast and reliable SQL database server
+Group: Applications/Databases
+Summary(pt_BR): MySQL: Um servidor SQL rápido e confiável.
+Group(pt_BR): Aplicações/Banco_de_Dados
+Requires: fileutils sh-utils
+Provides: msqlormysql mysql-server mysql MySQL
+Obsoletes: MySQL mysql mysql-server
+
+%description server
+The MySQL(TM) software delivers a very fast, multi-threaded, multi-user,
+and robust SQL (Structured Query Language) database server. MySQL Server
+is intended for mission-critical, heavy-load production systems as well
+as for embedding into mass-deployed software. MySQL is a trademark of
+MySQL AB.
+
+The MySQL software has Dual Licensing, which means you can use the MySQL
+software free of charge under the GNU General Public License
+(http://www.gnu.org/licenses/). You can also purchase commercial MySQL
+licenses from MySQL AB if you do not wish to be bound by the terms of
+the GPL. See the chapter "Licensing and Support" in the manual for
+further info.
+
+The MySQL web site (http://www.mysql.com/) provides the latest
+news and information about the MySQL software. Also please see the
+documentation and the manual for more information.
+
+This package includes the MySQL server binary (statically linked,
+compiled with InnoDB support) as well as related utilities to run
+and administrate a MySQL server.
+
+If you want to access and work with the database, you have to install
+package "MySQL-client" as well!
+
%package client
Release: %{release}
Summary: MySQL - Client
@@ -55,7 +93,7 @@ Obsoletes: mysql-client
Provides: mysql-client
%description client
-This package contains the standard MySQL clients.
+This package contains the standard MySQL clients and administration tools.
%{see_base}
@@ -64,7 +102,7 @@ Este pacote contém os clientes padrão para o MySQL.
%package bench
Release: %{release}
-Requires: %{name}-client MySQL-DBI-perl-bin perl
+Requires: %{name}-client perl-DBI perl
Summary: MySQL - Benchmarks and test system
Group: Applications/Databases
Summary(pt_BR): MySQL - Medições de desempenho
@@ -82,7 +120,6 @@ Este pacote contém medições de desempenho de scripts e dados do MySQL.
%package devel
Release: %{release}
-Requires: %{name}-client
Summary: MySQL - Development header files and libraries
Group: Applications/Databases
Summary(pt_BR): MySQL - Medições de desempenho
@@ -111,16 +148,41 @@ languages and applications need to dynamically load and use MySQL.
%package Max
Release: %{release}
-Summary: MySQL - server with Berkeley DB and Innodb support
+Summary: MySQL - server with Berkeley BD, RAID and UDF support
Group: Applications/Databases
Provides: mysql-Max
Obsoletes: mysql-Max
-Requires: MySQL = %{version}
+Requires: MySQL >= 4.0
%description Max
-Optional MySQL server binary that supports features
-like transactional tables. To active this binary, just install this
-package after the MySQL package.
+Optional MySQL server binary that supports additional features like
+Berkeley DB, RAID and User Defined Functions (UDFs).
+To activate this binary, just install this package in addition to
+the standard MySQL package.
+
+Please note that this is a dynamically linked binary!
+
+%package embedded
+Release: %{release}
+Requires: %{name}-devel
+Summary: MySQL - embedded library
+Group: Applications/Databases
+Summary(pt_BR): MySQL - Medições de desempenho
+Group(pt_BR): Aplicações/Banco_de_Dados
+Obsoletes: mysql-embedded
+
+%description embedded
+This package contains the MySQL server as an embedded library.
+
+The embedded MySQL server library makes it possible to run a
+full-featured MySQL server inside the client application.
+The main benefits are increased speed and more simple management
+for embedded applications.
+
+The API is identical for the embedded MySQL version and the
+client/server version.
+
+%{see_base}
%prep
%setup -n mysql-%{mysql_version}
@@ -133,11 +195,11 @@ package after the MySQL package.
BuildMySQL() {
# The --enable-assembler simply does nothing on systems that does not
# support assembler speedups.
-sh -c "PATH=\"${MYSQL_BUILD_PATH:-/bin:/usr/bin}\" \
- CC=\"${MYSQL_BUILD_CC:-gcc}\" \
- CFLAGS=\"${MYSQL_BUILD_CFLAGS:- -O3}\" \
- CXX=\"${MYSQL_BUILD_CXX:-gcc}\" \
- CXXFLAGS=\"${MYSQL_BUILD_CXXFLAGS:- -O3 \
+sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \
+ CC=\"${CC:-$MYSQL_BUILD_CC}\" \
+ CXX=\"${CXX:-$MYSQL_BUILD_CXX}\" \
+ CFLAGS=\"${MYSQL_BUILD_CFLAGS:-$RPM_OPT_FLAGS}\" \
+ CXXFLAGS=\"${MYSQL_BUILD_CXXFLAGS:-$RPM_OPT_FLAGS \
-felide-constructors -fno-exceptions -fno-rtti \
}\" \
./configure \
@@ -148,14 +210,16 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-/bin:/usr/bin}\" \
--with-unix-socket-path=/var/lib/mysql/mysql.sock \
--prefix=/ \
--with-extra-charsets=complex \
- --exec-prefix=/usr \
- --libexecdir=/usr/sbin \
- --sysconfdir=/etc \
- --datadir=/usr/share \
+ --exec-prefix=%{_exec_prefix} \
+ --libexecdir=%{_sbindir} \
+ --libdir=%{_libdir} \
+ --sysconfdir=%{_sysconfdir} \
+ --datadir=%{_datadir} \
--localstatedir=/var/lib/mysql \
--infodir=%{_infodir} \
- --includedir=/usr/include \
+ --includedir=%{_includedir} \
--mandir=%{_mandir} \
+ --enable-thread-safe-client \
--with-comment=\"Official MySQL RPM\";
# Add this for more debugging support
# --with-debug
@@ -183,7 +247,7 @@ MBD=$RPM_BUILD_DIR/mysql-%{mysql_version}
# Clean up the BuildRoot first
[ "$RBR" != "/" ] && [ -d $RBR ] && rm -rf $RBR;
-mkdir -p $RBR
+mkdir -p $RBR%{_libdir}/mysql
#
# Use MYSQL_BUILD_PATH so that we can use a dedicated version of gcc
@@ -191,10 +255,22 @@ mkdir -p $RBR
PATH=${MYSQL_BUILD_PATH:-/bin:/usr/bin}
export PATH
-# We need to build shared libraries separate from mysqld-max because we
-# are using --with-other-libc
+# Build the 4.0 Max binary (includes BDB and UDFs and therefore
+# cannot be linked statically against the patched glibc)
+
+# If we want to compile with RAID using gcc 3, we need to use
+# gcc instead of g++ to avoid linking problems (RAID code is written in C++)
+test -z $CXX && test -z $CC && if gcc -v 2>&1 | grep 'gcc version 3' > /dev/null 2>&1
+then
+ export CXX="gcc"
+fi
-BuildMySQL "--disable-shared $USE_OTHER_LIBC_DIR --with-berkeley-db --with-innodb --with-mysqld-ldflags='-all-static' --with-server-suffix='-Max'"
+BuildMySQL "--enable-shared \
+ --with-berkeley-db \
+ --with-innodb \
+ --with-raid \
+ --with-embedded-server \
+ --with-server-suffix='-Max'"
# Save everything for debug
# tar cf $RBR/all.tar .
@@ -203,13 +279,10 @@ BuildMySQL "--disable-shared $USE_OTHER_LIBC_DIR --with-berkeley-db --with-innod
mv sql/mysqld sql/mysqld-max
nm --numeric-sort sql/mysqld-max > sql/mysqld-max.sym
-# Save manual to avoid rebuilding
-mv Docs/manual.ps Docs/manual.ps.save
-make distclean
-mv Docs/manual.ps.save Docs/manual.ps
+# Install embedded server library in the build root
+install -m 644 libmysqld/libmysqld.a $RBR%{_libdir}/mysql
-#now build and save shared libraries
-BuildMySQL "--enable-shared --enable-thread-safe-client --without-server "
+# Save libraries
(cd libmysql/.libs; tar cf $RBR/shared-libs.tar *.so*)
(cd libmysql_r/.libs; tar rf $RBR/shared-libs.tar *.so*)
@@ -219,60 +292,97 @@ make distclean
mv Docs/manual.ps.save Docs/manual.ps
# RPM:s destroys Makefile.in files, so we generate them here
-automake
-
-BuildMySQL "--disable-shared" \
- "--with-mysqld-ldflags='-all-static'" \
- "--with-client-ldflags='-all-static'" \
- "$USE_OTHER_LIBC_DIR" \
- "--without-berkeley-db --without-innodb"
+# aclocal; autoheader; aclocal; automake; autoconf
+# (cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
+
+# Now build the statically linked 4.0 binary (which includes InnoDB)
+BuildMySQL "--disable-shared \
+ --with-mysqld-ldflags='-all-static' \
+ --with-client-ldflags='-all-static' \
+ $USE_OTHER_LIBC_DIR \
+ --with-server-suffix='%{server_suffix}' \
+ --without-embedded-server \
+ --without-berkeley-db \
+ --with-innodb \
+ --without-vio \
+ --without-openssl"
nm --numeric-sort sql/mysqld > sql/mysqld.sym
-%install -n mysql-%{mysql_version}
+%install
RBR=$RPM_BUILD_ROOT
MBD=$RPM_BUILD_DIR/mysql-%{mysql_version}
+
# Ensure that needed directories exists
-install -d $RBR/etc/{logrotate.d,rc.d/init.d}
+install -d $RBR%{_sysconfdir}/{logrotate.d,init.d}
install -d $RBR/var/lib/mysql/mysql
-install -d $RBR/usr/share/{sql-bench,mysql-test}
+install -d $RBR%{_datadir}/{sql-bench,mysql-test}
+install -d $RBR%{_includedir}
+install -d $RBR%{_libdir}
install -d $RBR%{_mandir}
-install -d $RBR/usr/{sbin,lib,include}
+install -d $RBR%{_sbindir}
-# Install all binaries stripped
-make install-strip DESTDIR=$RBR benchdir_root=/usr/share/
+
+# Install all binaries stripped
+make install-strip DESTDIR=$RBR benchdir_root=%{_datadir}
# Install shared libraries (Disable for architectures that don't support it)
-(cd $RBR/usr/lib; tar xf $RBR/shared-libs.tar)
+(cd $RBR%{_libdir}; tar xf $RBR/shared-libs.tar; rm -f $RBR/shared-libs.tar)
-# install and strip saved mysqld-max
-install -s -m755 $MBD/sql/mysqld-max $RBR/usr/sbin/mysqld-max
+# install saved mysqld-max
+install -s -m755 $MBD/sql/mysqld-max $RBR%{_sbindir}/mysqld-max
# install symbol files ( for stack trace resolution)
-install -m644 $MBD/sql/mysqld-max.sym $RBR/usr/lib/mysql/mysqld-max.sym
-install -m644 $MBD/sql/mysqld.sym $RBR/usr/lib/mysql/mysqld.sym
+install -m644 $MBD/sql/mysqld-max.sym $RBR%{_libdir}/mysql/mysqld-max.sym
+install -m644 $MBD/sql/mysqld.sym $RBR%{_libdir}/mysql/mysqld.sym
# Install logrotate and autostart
-install -m644 $MBD/support-files/mysql-log-rotate $RBR/etc/logrotate.d/mysql
-install -m755 $MBD/support-files/mysql.server $RBR/etc/rc.d/init.d/mysql
+install -m644 $MBD/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql
+install -m755 $MBD/support-files/mysql.server $RBR%{_sysconfdir}/init.d/mysql
+
+# Create a symlink "rcmysql", pointing to the init.script. SuSE users
+# will appreciate that, as all services usually offer this.
+ln -s %{_sysconfdir}/init.d/mysql $RPM_BUILD_ROOT%{_sbindir}/rcmysql
+
+# Create symbolic compatibility link safe_mysqld -> mysqld_safe
+# (safe_mysqld will be gone in MySQL 4.1)
+ln -sf ./mysqld_safe $RBR%{_bindir}/safe_mysqld
-%pre
-if test -x /etc/rc.d/init.d/mysql
+# Touch the place where the my.cnf config file might be located
+# Just to make sure it's in the file list and marked as a config file
+touch $RBR%{_sysconfdir}/my.cnf
+
+%pre server
+# Shut down a previously installed server first
+if test -x %{_sysconfdir}/init.d/mysql
+then
+ %{_sysconfdir}/init.d/mysql stop > /dev/null 2>&1
+ echo "Giving mysqld a couple of seconds to exit nicely"
+ sleep 5
+elif test -x %{_sysconfdir}/rc.d/init.d/mysql
then
- /etc/rc.d/init.d/mysql stop > /dev/null 2>&1
+ %{_sysconfdir}/rc.d/init.d/mysql stop > /dev/null 2>&1
echo "Giving mysqld a couple of seconds to exit nicely"
sleep 5
fi
-%post
+%post server
mysql_datadir=/var/lib/mysql
# Create data directory if needed
-if test ! -d $mysql_datadir; then mkdir $mysql_datadir; fi
-if test ! -d $mysql_datadir/mysql; then mkdir $mysql_datadir/mysql; fi
-if test ! -d $mysql_datadir/test; then mkdir $mysql_datadir/test; fi
+if test ! -d $mysql_datadir; then mkdir -m755 $mysql_datadir; fi
+if test ! -d $mysql_datadir/mysql; then mkdir $mysql_datadir/mysql; fi
+if test ! -d $mysql_datadir/test; then mkdir $mysql_datadir/test; fi
# Make MySQL start/shutdown automatically when the machine does it.
-/sbin/chkconfig --add mysql
+# use insserv for older SuSE Linux versions
+if test -x /sbin/insserv
+then
+ /sbin/insserv %{_sysconfdir}/init.d/mysql
+# use chkconfig on Red Hat and newer SuSE releases
+elif test -x /sbin/chkconfig
+then
+ /sbin/chkconfig --add mysql
+fi
# Create a MySQL user. Do not report any problems if it already
# exists. This is redhat specific and should be handled more portable
@@ -293,42 +403,51 @@ chown -R mysql $mysql_datadir
chmod -R og-rw $mysql_datadir/mysql
# Restart in the same way that mysqld will be started normally.
-/etc/rc.d/init.d/mysql start
+%{_sysconfdir}/init.d/mysql start
# Allow safe_mysqld to start mysqld and print a message before we exit
sleep 2
%post Max
# Restart mysqld, to use the new binary.
-# There may be a better way to handle this.
-/etc/rc.d/init.d/mysql stop > /dev/null 2>&1
-echo "Giving mysqld a couple of seconds to restart"
-sleep 5
-/etc/rc.d/init.d/mysql start
-sleep 2
+echo "Restarting mysqld."
+%{_sysconfdir}/init.d/mysql restart > /dev/null 2>&1
-%preun
+%preun server
if test $1 = 0
then
- if test -x /etc/rc.d/init.d/mysql
+ # Stop MySQL before uninstalling it
+ if test -x %{_sysconfdir}/init.d/mysql
then
- /etc/rc.d/init.d/mysql stop > /dev/null
+ %{_sysconfdir}/init.d/mysql stop > /dev/null
fi
# Remove autostart of mysql
- /sbin/chkconfig --del mysql
+ # for older SuSE Linux versions
+ if test -x /sbin/insserv
+ then
+ /sbin/insserv -r %{_sysconfdir}/init.d/mysql
+ # use chkconfig on Red Hat and newer SuSE releases
+ elif test -x /sbin/chkconfig
+ then
+ /sbin/chkconfig --del mysql
+ fi
fi
+
# We do not remove the mysql user since it may still own a lot of
# database files.
+# Clean up the BuildRoot
%clean
[ "$RBR" != "/" ] && [ -d $RBR ] && rm -rf $RBR;
-%files
-%defattr(-, root, root)
-%doc %attr(644, root, root) COPYING COPYING.LIB README
-%doc %attr(644, root, root) Docs/manual.{html,ps,texi,txt} Docs/manual_toc.html
-%doc %attr(644, root, root) support-files/my-*.cnf
+%files server
+%defattr(-,root,root,0755)
+
+%doc COPYING README
+%doc Docs/manual.{html,ps,texi,txt}
+%doc Docs/manual_toc.html
+%doc support-files/my-*.cnf
%doc %attr(644, root, root) %{_infodir}/mysql.info*
@@ -336,54 +455,65 @@ fi
%doc %attr(644, root, man) %{_mandir}/man1/isamlog.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqld.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysql_fix_privilege_tables.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqld_multi.1*
-%doc %attr(644, root, man) %{_mandir}/man1/safe_mysqld.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysqld_safe.1*
%doc %attr(644, root, man) %{_mandir}/man1/perror.1*
%doc %attr(644, root, man) %{_mandir}/man1/replace.1*
-%attr(755, root, root) /usr/bin/isamchk
-%attr(755, root, root) /usr/bin/isamlog
-%attr(755, root, root) /usr/bin/my_print_defaults
-%attr(755, root, root) /usr/bin/myisamchk
-%attr(755, root, root) /usr/bin/myisamlog
-%attr(755, root, root) /usr/bin/myisampack
-%attr(755, root, root) /usr/bin/mysql_convert_table_format
-%attr(755, root, root) /usr/bin/mysql_fix_privilege_tables
-%attr(755, root, root) /usr/bin/mysql_install_db
-%attr(755, root, root) /usr/bin/mysql_setpermission
-%attr(755, root, root) /usr/bin/mysql_zap
-%attr(755, root, root) /usr/bin/mysqlbug
-%attr(755, root, root) /usr/bin/mysqld_multi
-%attr(755, root, root) /usr/bin/mysqldumpslow
-%attr(755, root, root) /usr/bin/mysqlhotcopy
-%attr(755, root, root) /usr/bin/mysqltest
-%attr(755, root, root) /usr/bin/pack_isam
-%attr(755, root, root) /usr/bin/perror
-%attr(755, root, root) /usr/bin/replace
-%attr(755, root, root) /usr/bin/resolve_stack_dump
-%attr(755, root, root) /usr/bin/resolveip
-%attr(755, root, root) /usr/bin/safe_mysqld
-
-%attr(755, root, root) /usr/sbin/mysqld
-%attr(644, root, root) /usr/lib/mysql/mysqld.sym
-
-%attr(644, root, root) /etc/logrotate.d/mysql
-%attr(755, root, root) /etc/rc.d/init.d/mysql
-
-%attr(755, root, root) /usr/share/mysql/
+%ghost %config(noreplace,missingok) %{_sysconfdir}/my.cnf
+
+%attr(755, root, root) %{_bindir}/isamchk
+%attr(755, root, root) %{_bindir}/isamlog
+%attr(755, root, root) %{_bindir}/my_print_defaults
+%attr(755, root, root) %{_bindir}/myisamchk
+%attr(755, root, root) %{_bindir}/myisam_ftdump
+%attr(755, root, root) %{_bindir}/myisamlog
+%attr(755, root, root) %{_bindir}/myisampack
+%attr(755, root, root) %{_bindir}/mysql_convert_table_format
+%attr(755, root, root) %{_bindir}/mysql_explain_log
+%attr(755, root, root) %{_bindir}/mysql_fix_extensions
+%attr(755, root, root) %{_bindir}/mysql_fix_privilege_tables
+%attr(755, root, root) %{_bindir}/mysql_install_db
+%attr(755, root, root) %{_bindir}/mysql_secure_installation
+%attr(755, root, root) %{_bindir}/mysql_setpermission
+%attr(755, root, root) %{_bindir}/mysql_zap
+%attr(755, root, root) %{_bindir}/mysqlbug
+%attr(755, root, root) %{_bindir}/mysqld_multi
+%attr(755, root, root) %{_bindir}/mysqld_safe
+%attr(755, root, root) %{_bindir}/mysqlhotcopy
+%attr(755, root, root) %{_bindir}/mysqltest
+%attr(755, root, root) %{_bindir}/pack_isam
+%attr(755, root, root) %{_bindir}/perror
+%attr(755, root, root) %{_bindir}/replace
+%attr(755, root, root) %{_bindir}/resolve_stack_dump
+%attr(755, root, root) %{_bindir}/resolveip
+%attr(755, root, root) %{_bindir}/safe_mysqld
+
+%attr(755, root, root) %{_sbindir}/mysqld
+%attr(755, root, root) %{_sbindir}/rcmysql
+%attr(644, root, root) %{_libdir}/mysql/mysqld.sym
+
+%attr(644, root, root) %config(noreplace,missingok) %{_sysconfdir}/logrotate.d/mysql
+%attr(755, root, root) %{_sysconfdir}/init.d/mysql
+
+%attr(755, root, root) %{_datadir}/mysql/
%files client
-%defattr(-, root, root)
-%attr(755, root, root) /usr/bin/msql2mysql
-%attr(755, root, root) /usr/bin/mysql
-%attr(755, root, root) /usr/bin/mysql_find_rows
-%attr(755, root, root) /usr/bin/mysqlaccess
-%attr(755, root, root) /usr/bin/mysqladmin
-%attr(755, root, root) /usr/bin/mysqlbinlog
-%attr(755, root, root) /usr/bin/mysqlcheck
-%attr(755, root, root) /usr/bin/mysqldump
-%attr(755, root, root) /usr/bin/mysqlimport
-%attr(755, root, root) /usr/bin/mysqlshow
+%defattr(-, root, root, 0755)
+%attr(755, root, root) %{_bindir}/msql2mysql
+%attr(755, root, root) %{_bindir}/mysql
+%attr(755, root, root) %{_bindir}/mysql_find_rows
+%attr(755, root, root) %{_bindir}/mysql_tableinfo
+%attr(755, root, root) %{_bindir}/mysql_waitpid
+%attr(755, root, root) %{_bindir}/mysqlaccess
+%attr(755, root, root) %{_bindir}/mysqladmin
+%attr(755, root, root) %{_bindir}/mysqlbinlog
+%attr(755, root, root) %{_bindir}/mysqlcheck
+%attr(755, root, root) %{_bindir}/mysqldump
+%attr(755, root, root) %{_bindir}/mysqldumpslow
+%attr(755, root, root) %{_bindir}/mysqlimport
+%attr(755, root, root) %{_bindir}/mysqlshow
%doc %attr(644, root, man) %{_mandir}/man1/mysql.1*
%doc %attr(644, root, man) %{_mandir}/man1/mysqlaccess.1*
@@ -398,53 +528,183 @@ fi
/sbin/ldconfig
%files devel
-%defattr(644 root, root)
-%attr(755, root, root) /usr/bin/comp_err
-%attr(755, root, root) /usr/bin/mysql_config
-%dir %attr(755, root, root) /usr/include/mysql
-%dir %attr(755, root, root) /usr/lib/mysql
-/usr/include/mysql/*
-/usr/lib/mysql/*.a
+%defattr(-, root, root, 0755)
+%attr(755, root, root) %{_bindir}/comp_err
+%attr(755, root, root) %{_bindir}/mysql_config
+%dir %attr(755, root, root) %{_includedir}/mysql
+%dir %attr(755, root, root) %{_libdir}/mysql
+%{_includedir}/mysql/*
+%{_libdir}/mysql/libdbug.a
+%{_libdir}/mysql/libheap.a
+%{_libdir}/mysql/libmerge.a
+%{_libdir}/mysql/libmyisam.a
+%{_libdir}/mysql/libmyisammrg.a
+%{_libdir}/mysql/libmysqlclient.a
+%{_libdir}/mysql/libmysqlclient.la
+%{_libdir}/mysql/libmysqlclient_r.a
+%{_libdir}/mysql/libmysqlclient_r.la
+%{_libdir}/mysql/libmystrings.a
+%{_libdir}/mysql/libmysys.a
+%{_libdir}/mysql/libnisam.a
+%{_libdir}/mysql/libvio.a
%files shared
-%defattr(755 root, root)
+%defattr(-, root, root, 0755)
# Shared libraries (omit for architectures that don't support them)
-/usr/lib/*.so*
+%{_libdir}/*.so*
%files bench
-%defattr(-, root, root)
-%attr(-, root, root) /usr/share/sql-bench
-%attr(-, root, root) /usr/share/mysql-test
+%defattr(-, root, root, 0755)
+%attr(-, root, root) %{_datadir}/sql-bench
+%attr(-, root, root) %{_datadir}/mysql-test
+%attr(755, root, root) %{_bindir}/mysqlmanager
+%attr(755, root, root) %{_bindir}/mysqlmanager-pwgen
+%attr(755, root, root) %{_bindir}/mysqlmanagerc
%files Max
-%defattr(-, root, root)
-%attr(755, root, root) /usr/sbin/mysqld-max
-%attr(644, root, root) /usr/lib/mysql/mysqld-max.sym
+%defattr(-, root, root, 0755)
+%attr(755, root, root) %{_sbindir}/mysqld-max
+%attr(644, root, root) %{_libdir}/mysql/mysqld-max.sym
+
+%files embedded
+%defattr(-, root, root, 0755)
+%attr(644, root, root) %{_libdir}/mysql/libmysqld.a
+# The spec file changelog only includes changes made to the spec file
+# itself
%changelog
+* Tue Feb 03 2004 Lenz Grimmer <lenz@mysql.com>
+
+- added myisam_ftdump to the Server package
+
+* Mon Dec 22 2003 Lenz Grimmer <lenz@mysql.com>
+
+- marked /etc/logrotate.d/mysql as a config file (BUG 2156)
+
+* Fri Dec 13 2003 Lenz Grimmer <lenz@mysql.com>
+
+- fixed file permissions (BUG 1672)
+
+* Thu Dec 11 2003 Lenz Grimmer <lenz@mysql.com>
+
+- made testing for gcc3 a bit more robust
+
+* Fri Nov 21 2003 Lenz Grimmer <lenz@mysql.com>
+
+- removed dependency on MySQL-client from the MySQL-devel subpackage
+ as it is not really required. (BUG 1610)
-* Tue Sep 24 2002 Lenz Grimmer <lenz@mysql.com>
+* Fri Aug 29 2003 Lenz Grimmer <lenz@mysql.com>
-- MySQL-Max now requires MySQL to be the same version (to
- avoid version mismatches e.g. mixing 3.23.xx and 4.0 packages)
+- Fixed BUG 1162 (removed macro names from the changelog)
+- Really fixed BUG 998 (disable the checking for installed but
+ unpackaged files)
-* Thu Jul 30 2002 Lenz Grimmer <lenz@mysql.com>
+* Tue Aug 05 2003 Lenz Grimmer <lenz@mysql.com>
-- Use some more macros (mandir and infodir)
-- Updated package description
-- Install binaries stripped to save disk space
-- Rearranged file list (make sure man pages are in
- the same package as the binaries)
+- Fixed BUG 959 (libmysqld not being compiled properly)
+- Fixed BUG 998 (RPM build errors): added missing files to the
+ distribution (mysql_fix_extensions, mysql_tableinfo, mysqldumpslow,
+ mysql_fix_privilege_tables.1), removed "-n" from install section.
+
+* Wed Jul 09 2003 Lenz Grimmer <lenz@mysql.com>
+
+- removed the GIF Icon (file was not included in the sources anyway)
+- removed unused variable shared_lib_version
+- do not run automake before building the standard binary
+ (should not be necessary)
+- add server suffix '-standard' to standard binary (to be in line
+ with the binary tarball distributions)
+- Use more RPM macros (_exec_prefix, _sbindir, _libdir, _sysconfdir,
+ _datadir, _includedir) throughout the spec file.
+- allow overriding CC and CXX (required when building with other compilers)
+
+* Fri May 16 2003 Lenz Grimmer <lenz@mysql.com>
+
+- re-enabled RAID again
+
+* Wed Apr 30 2003 Lenz Grimmer <lenz@mysql.com>
+
+- disabled MyISAM RAID (--with-raid) - it throws an assertion which
+ needs to be investigated first.
+
+* Mon Mar 10 2003 Lenz Grimmer <lenz@mysql.com>
+
+- added missing file mysql_secure_installation to server subpackage
+ (BUG 141)
+
+* Tue Feb 11 2003 Lenz Grimmer <lenz@mysql.com>
+
+- re-added missing pre- and post(un)install scripts to server subpackage
+- added config file /etc/my.cnf to the file list (just for completeness)
+- make sure to create the datadir with 755 permissions
+
+* Mon Jan 27 2003 Lenz Grimmer <lenz@mysql.com>
+
+- removed unused CC and CXX variables
+- CFLAGS and CXXFLAGS should honor RPM_OPT_FLAGS
+
+* Fri Jan 24 2003 Lenz Grimmer <lenz@mysql.com>
+
+- renamed package "MySQL" to "MySQL-server"
+- fixed Copyright tag
+- added mysql_waitpid to client subpackage (required for mysql-test-run)
+
+* Wed Nov 27 2002 Lenz Grimmer <lenz@mysql.com>
+
+- moved init script from /etc/rc.d/init.d to /etc/init.d (the majority of
+ Linux distributions now support this scheme as proposed by the LSB either
+ directly or via a compatibility symlink)
+- Use new "restart" init script action instead of starting and stopping
+ separately
+- Be more flexible in activating the automatic bootup - use insserv (on
+ older SuSE versions) or chkconfig (Red Hat, newer SuSE versions and
+ others) to create the respective symlinks
+
+* Wed Sep 25 2002 Lenz Grimmer <lenz@mysql.com>
+
+- MySQL-Max now requires MySQL >= 4.0 to avoid version mismatches
+ (mixing 3.23 and 4.0 packages)
+
+* Fri Aug 09 2002 Lenz Grimmer <lenz@mysql.com>
+
+- Turn off OpenSSL in MySQL-Max for now until it works properly again
+- enable RAID for the Max binary instead
+- added compatibility link: safe_mysqld -> mysqld_safe to ease the
+ transition from 3.23
+
+* Thu Jul 18 2002 Lenz Grimmer <lenz@mysql.com>
+
+- Reworked the build steps a little bit: the Max binary is supposed
+ to include OpenSSL, which cannot be linked statically, thus trying
+ to statically link against a special glibc is futile anyway
+- because of this, it is not required to make yet another build run
+ just to compile the shared libs (saves a lot of time)
+- updated package description of the Max subpackage
- clean up the BuildRoot directory afterwards
-- added mysqldumpslow to the server package
* Mon Jul 15 2002 Lenz Grimmer <lenz@mysql.com>
-- updated Packager tag
+- Updated Packager information
+- Fixed the build options: the regular package is supposed to
+ include InnoDB and linked statically, while the Max package
+ should include BDB and SSL support
+
+* Fri May 03 2002 Lenz Grimmer <lenz@mysql.com>
+
+- Use more RPM macros (e.g. infodir, mandir) to make the spec
+ file more portable
+- reorganized the installation of documentation files: let RPM
+ take care of this
+- reorganized the file list: actually install man pages along
+ with the binaries of the respective subpackage
+- do not include libmysqld.a in the devel subpackage as well, if we
+ have a special "embedded" subpackage
+- reworked the package descriptions
-* Fri Feb 15 2002 Sasha
+* Mon Oct 8 2001 Monty
-- changed build to use --with-other-libc
+- Added embedded server as a separate RPM
* Fri Apr 13 2001 Monty
diff --git a/tests/Makefile.am b/tests/Makefile.am
index cdb623fa2a0..356da61ed57 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -24,7 +24,7 @@ EXTRA_DIST = auto_increment.res auto_increment.tst \
insert_and_repair.pl \
grant.pl grant.res test_delayed_insert.pl \
pmail.pl mail_to_db.pl table_types.pl \
- udf_test udf_test.res
+ udf_test udf_test.res myisam-big-rows.tst
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/tests/big_record.pl b/tests/big_record.pl
index 52d3dca5f7b..fbe94e3540f 100755
--- a/tests/big_record.pl
+++ b/tests/big_record.pl
@@ -1,58 +1,96 @@
#!/usr/bin/perl
-# This is a test with stores big records in a blob
+# This is a test with stores big records in a blob.
# Note that for the default test the mysql server should have been
-# started with at least 'mysqld -O max_allowed_packet=200k'
-
-$host= shift || "";
-$test_db="test";
-$opt_user=$opt_password="";
+# started with at least 'mysqld -O max_allowed_packet=30M' and you should have
+# at least 256M memory in your computer.
use DBI;
-$|= 1; # Autoflush
+use Getopt::Long;
+
+$opt_host="";
+$opt_user=$opt_password="";
+$opt_db="test";
+$opt_rows=20; # Test of blobs up to ($rows-1)*100000+1 bytes
+$opt_compress=0;
+$opt_table="test_big_record";
+$opt_loop_count=100000; # Change this to make test harder/easier
-$table="test_big_record";
-$rows=20; # Test of blobs up to ($rows-1)*10000+1 bytes
+GetOptions("host=s","db=s","user=s", "password=s", "table=s", "rows=i",
+ "compress", "loop-count=i") || die "Aborted";
print "Connection to database $test_db\n";
-$dbh = DBI->connect("DBI:mysql:$test_db:$host",$opt_user,$opt_password) || die "Can't connect: $DBI::errstr\n";
+$extra_options="";
+$extra_options.=":mysql_compression=1" if ($opt_compress);
-$dbh->do("drop table if exists $table");
+$dbh = DBI->connect("DBI:mysql:$opt_db:$host$extra_options",$opt_user,$opt_password) || die "Can't connect: $DBI::errstr\n";
-print "Creating table $table\n";
+$dbh->do("drop table if exists $opt_table");
+
+print "Creating table $opt_table\n";
($dbh->do("\
-CREATE TABLE $table (
+CREATE TABLE $opt_table (
auto int(5) unsigned NOT NULL DEFAULT '0' auto_increment,
- test mediumblob,
+ test longblob,
PRIMARY KEY (auto))")) or die $DBI::errstr;
-print "Inserting $rows records\n";
+print "Inserting $opt_rows records\n";
+
+$|=1; # Flush output to stdout to be able to monitor process
-for ($i=0 ; $i < $rows ; $i++)
+for ($i=0 ; $i < $opt_rows ; $i++)
{
- $tmp= chr(65+$i) x ($i*10000+1);
+ $tmp= chr(65+($i % 16)) x ($i*100000+1);
$tmp= $dbh->quote($tmp);
- $dbh->do("insert into $table (test) values ($tmp)") or die $DBI::errstr;
+ $dbh->do("insert into $opt_table (test) values ($tmp)") or die $DBI::errstr;
+ print ".";
}
-print "Testing records\n";
+print "\nReading records\n";
+
+$sth=$dbh->prepare("select * from $opt_table", { "mysql_use_result" => 1}) or die $dbh->errstr;
-$sth=$dbh->prepare("select * from $table") or die $dbh->errstr;
$sth->execute() or die $sth->errstr;
$i=0;
while (($row = $sth->fetchrow_arrayref))
{
- print $row->[0]," ",length($row->[1]),"\n";
- die "Record $i had wrong data in blob" if ($row->[1] ne (chr(65+$i)) x ($i*10000+1));
+ die "Record $i had wrong data in blob" if ($row->[1] ne (chr(65+($i % 16)) x ($i*100000+1)));
$i++;
}
-die "Didn't get all rows from server" if ($i != $rows);
+die "Didn't get all rows from server" if ($i != $opt_rows);
+
+#
+# Test by insert/updating/deleting random rows for a while
+#
+
+print "Testing insert/update/delete\n";
+
+$max_row_id= $rows;
+for ($i= 0 ; $i < $opt_loop_count ; $i++)
+{
+ $length= int(rand 65535);
+ $tmp= chr(65+($i % 16)) x $length;
+ $tmp= $dbh->quote($tmp);
+ $dbh->do("insert into $opt_table (test) values ($tmp)") or die $DBI::errstr;
+ $max_row_id++;
+ $length=int(rand 65535);
+ $tmp= chr(65+($i % 16)) x $length;
+ $tmp= $dbh->quote($tmp);
+ $id= int(rand $max_row_id);
+ $dbh->do("update $opt_table set test= $tmp where auto= $id") or die $DBI::errstr;
+ if (($i % 2) == 1)
+ {
+ $id= int(rand $max_row_id);
+ $dbh->do("delete from $opt_table where auto= $id") or die $DBI::errstr;
+ }
+ print "." if ($i % ($opt_loop_count/100) == 1);
+}
-$dbh->do("drop table $table") or die $DBI::errstr;
+# $dbh->do("drop table $opt_table") or die $DBI::errstr;
-print "Test ok\n";
+print "\nTest ok\n";
exit 0;
diff --git a/tests/fork2_test.pl b/tests/fork2_test.pl
index b5564e99c3f..19fab5a67d6 100755
--- a/tests/fork2_test.pl
+++ b/tests/fork2_test.pl
@@ -92,7 +92,7 @@ $errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
- print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}
diff --git a/tests/fork_big.pl b/tests/fork_big.pl
index e082225604c..c72eb59946b 100755
--- a/tests/fork_big.pl
+++ b/tests/fork_big.pl
@@ -106,7 +106,7 @@ $running_insert_threads=$opt_threads+$numtables;
while (($pid=wait()) != -1)
{
$ret=$?/256;
- print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
if ($work{$pid} =~ /^insert/)
{
if (!--$running_insert_threads)
diff --git a/tests/function.res b/tests/function.res
index a2322020d74..acd34f41a3e 100644
--- a/tests/function.res
+++ b/tests/function.res
@@ -11,11 +11,11 @@ select floor(5.5),floor(-5.5),ceiling(5.5),ceiling(-5.5),round(5.5),round(-5.5)
floor(5.5) floor(-5.5) ceiling(5.5) ceiling(-5.5) round(5.5) round(-5.5)
5 -6 6 -5 6 -6
--------------
-select abs(-10),log(exp(10)),exp(log(sqrt(10))*2),pow(10,log10(10)),rand(999999),rand()
+select abs(-10),log(exp(10)),ln(exp(10)),log2(65535),log(2,65535),exp(log(sqrt(10))*2),pow(10,log10(10)),rand(999999),rand()
--------------
-abs(-10) log(exp(10)) exp(log(sqrt(10))*2) pow(10,log10(10)) rand(999999) rand()
-10 10.000000 10.000000 10.000000 0.1844 0.7637
+abs(-10) log(exp(10)) ln(exp(10)) log2(65535) log(2,65535) exp(log(sqrt(10))*2) pow(10,log10(10)) rand(999999) rand()
+10 10.000000 10.000000 2.000000 2.000000 10.000000 10.000000 0.1844 0.7637
--------------
select least(6,1.0,2.0),greatest(3,4,5,0)
--------------
diff --git a/tests/function.tst b/tests/function.tst
index 5b8746e8d3c..17e1cb6c8ac 100644
--- a/tests/function.tst
+++ b/tests/function.tst
@@ -7,7 +7,7 @@
#
select 1+1,1-1,1+1*2,8/5,8%5,mod(8,5),mod(8,5)|0,-(1+1)*-2,sign(-5) ;
select floor(5.5),floor(-5.5),ceiling(5.5),ceiling(-5.5),round(5.5),round(-5.5);
-select abs(-10),log(exp(10)),exp(log(sqrt(10))*2),pow(10,log10(10)),rand(999999),rand();
+select abs(-10),log(exp(10)),ln(exp(10)),log2(65535),log(2,65535),exp(log(sqrt(10))*2),pow(10,log10(10)),rand(999999),rand();
select least(6,1.0,2.0),greatest(3,4,5,0) ;
select 1 | (1+1),5 & 3,bit_count(7) ;
#
diff --git a/tests/grant.pl b/tests/grant.pl
index 8ec83c85349..eb2d00f3e1d 100644
--- a/tests/grant.pl
+++ b/tests/grant.pl
@@ -11,7 +11,7 @@ use strict;
use vars qw($dbh $user_dbh $opt_help $opt_Information $opt_force $opt_debug
$opt_verbose $opt_server $opt_root_user $opt_password $opt_user
$opt_database $opt_host $version $user $tables_cols $columns_cols
- $opt_silent);
+ $tmp_table $opt_silent);
$version="1.1";
$opt_help=$opt_Information=$opt_force=$opt_debug=$opt_verbose=$opt_silent=0;
@@ -36,6 +36,8 @@ $|=1;
$tables_cols="Host, Db, User, Table_name, Grantor, Table_priv, Column_priv";
$columns_cols="Host, Db, User, Table_name, Column_name, Column_priv";
+$tmp_table="/tmp/mysql-grant.test"; # Can't use $$ as we are logging result
+unlink($tmp_table);
#
# clear grant tables
@@ -52,7 +54,7 @@ safe_query("delete from columns_priv");
safe_query("lock tables mysql.user write"); # Test lock tables
safe_query("flush privileges");
safe_query("unlock tables"); # should already be unlocked
-safe_query("drop database $opt_database",2);
+safe_query("drop database $opt_database",3); # Don't print possible error
safe_query("create database $opt_database");
# check that the user can't login yet
@@ -61,6 +63,12 @@ user_connect(1);
#goto test;
#
+# Enable column grant code
+#
+safe_query("grant select(user) on mysql.user to $user");
+safe_query("revoke select(user) on mysql.user from $user");
+
+#
# Test grants on user level
#
@@ -73,6 +81,8 @@ user_connect(0);
user_query("select * from mysql.user where user = '$opt_user'");
user_query("select * from mysql.db where user = '$opt_user'");
safe_query("grant select on *.* to $user,$user");
+safe_query("show grants for $user");
+user_connect(0);
# The following should fail
user_query("insert into mysql.user (host,user) values ('error','$opt_user')",1);
@@ -86,16 +96,21 @@ safe_query("grant select on $opt_database.not_exists to $opt_user",1);
safe_query("grant FILE on $opt_database.test to $opt_user",1);
safe_query("grant select on *.* to wrong___________user_name",1);
safe_query("grant select on $opt_database.* to wrong___________user_name",1);
+user_connect(0);
user_query("grant select on $opt_database.test to $opt_user with grant option",1);
safe_query("set password FOR ''\@''=''",1);
user_query("set password FOR root\@$opt_host = password('test')",1);
# Change privileges for user
safe_query("revoke select on *.* from $user");
-safe_query("grant create on *.* to $user");
+safe_query("grant create,update on *.* to $user");
user_connect(0);
+safe_query("flush privileges");
user_query("create table $opt_database.test (a int,b int)");
-
+user_query("update $opt_database.test set b=b+1 where a > 0",1);
+safe_query("show grants for $user");
+safe_query("revoke update on *.* from $user");
+user_connect(0);
safe_query("grant select(c) on $opt_database.test to $user",1);
safe_query("revoke select(c) on $opt_database.test from $user",1);
safe_query("grant select on $opt_database.test to wrong___________user_name",1);
@@ -171,6 +186,7 @@ user_query("delete from $opt_database.test where a=3");
user_query("create table $opt_database.test2 (a int not null)");
user_query("alter table $opt_database.test2 add b int");
user_query("create index dummy on $opt_database.test2 (a)");
+user_query("update test,test2 SET test.a=test2.a where test.a=test2.a");
user_query("drop table $opt_database.test2");
user_query("show tables from grant_test");
# These should fail
@@ -180,6 +196,20 @@ user_query("insert into mysql.user (host,user) values ('error','$opt_user',0)",1
safe_query("revoke ALL PRIVILEGES on $opt_database.* from $user");
safe_query("select * from mysql.user where user = '$opt_user'");
safe_query("select * from mysql.db where user = '$opt_user'");
+
+# Test multi-updates
+safe_query("grant CREATE,UPDATE,DROP on $opt_database.* to $user");
+user_connect(0);
+user_query("create table $opt_database.test2 (a int not null)");
+user_query("update test,test2 SET test.a=1 where 1");
+user_query("update test,test2 SET test.a=test2.a where 1",1);
+safe_query("grant SELECT on $opt_database.* to $user");
+user_connect(0);
+user_query("update test,test2 SET test.a=test2.a where test2.a=test.a");
+user_query("drop table $opt_database.test2");
+
+# Revoke database privileges
+safe_query("revoke ALL PRIVILEGES on $opt_database.* from $user");
user_connect(1);
#
@@ -201,11 +231,18 @@ user_query("insert into $opt_database.test values (8,0)");
user_query("update $opt_database.test set b=1",1);
safe_query("grant update on $opt_database.test to $user");
user_query("update $opt_database.test set b=2");
+
+user_query("update $opt_database.test,test2 SET test.b=3",1);
+safe_query("grant select on $opt_database.test2 to $user");
+user_query("update $opt_database.test,test2 SET test.b=3");
+safe_query("revoke select on $opt_database.test2 from $user");
+
user_query("delete from $opt_database.test",1);
safe_query("grant delete on $opt_database.test to $user");
user_query("delete from $opt_database.test where a=1",1);
user_query("update $opt_database.test set b=3 where b=1",1);
user_query("update $opt_database.test set b=b+1",1);
+user_query("update $opt_database.test,test2 SET test.a=test2.a",1);
#
# Test global SELECT privilege combined with table level privileges
@@ -215,6 +252,8 @@ safe_query("grant SELECT on *.* to $user");
user_connect(0);
user_query("update $opt_database.test set b=b+1");
user_query("update $opt_database.test set b=b+1 where a > 0");
+user_query("update $opt_database.test,test2 SET test.a=test2.a");
+user_query("update $opt_database.test,test2 SET test2.a=test.a",1);
safe_query("revoke SELECT on *.* from $user");
safe_query("grant SELECT on $opt_database.* to $user");
user_connect(0);
@@ -237,6 +276,9 @@ user_query("delete from $opt_database.test where a=1");
user_query("update $opt_database.test set b=2 where b=1");
user_query("update $opt_database.test set b=b+1");
user_query("select count(*) from test");
+user_query("update test,test2 SET test.b=4",1);
+user_query("update test,test2 SET test2.a=test.a",1);
+user_query("update test,test2 SET test.a=test2.a",1);
user_query("create table $opt_database.test3 (a int)",1);
user_query("alter table $opt_database.test2 add c int",1);
@@ -255,10 +297,27 @@ user_query("select count(*) from test2,test",1);
user_query("select count(*) from test,test2",1);
user_query("replace into test2 SELECT a from test",1);
safe_query("grant update on $opt_database.test2 to $user");
+user_query("update test,test2 SET test2.a=test.a");
+user_query("update test,test2 SET test.b=test2.a where 0",1);
+user_query("update test,test2 SET test.a=2 where test2.a>100",1);
+user_query("update test,test2 SET test.a=test2.a",1);
user_query("replace into test2 SELECT a,a from test",1);
safe_query("grant DELETE on $opt_database.test2 to $user");
user_query("replace into test2 SELECT a,a from test");
user_query("insert into test (a) SELECT a from test2",1);
+safe_query("grant SELECT on $opt_database.test2 to $user");
+user_query("update test,test2 SET test.b=test2.a where 0");
+user_query("update test,test2 SET test.a=test2.a where test2.a>100");
+
+safe_query("revoke UPDATE on $opt_database.test2 from $user");
+safe_query("grant UPDATE (c) on $opt_database.test2 to $user");
+user_query("update test,test2 SET test.b=test2.a where 0");
+user_query("update test,test2 SET test.a=test2.a where test2.a>100");
+user_query("update test,test2 SET test2.a=test2.a where test2.a>100",1);
+user_query("update test,test2 SET test2.c=test2.a where test2.a>100");
+
+safe_query("revoke SELECT,UPDATE on $opt_database.test2 from $user");
+safe_query("grant UPDATE on $opt_database.test2 to $user");
user_query("drop table $opt_database.test2",1);
user_query("grant select on $opt_database.test2 to $user with grant option",1);
@@ -300,9 +359,13 @@ user_query("select count(a) from test",1);
# Test some grants on column level
#
+safe_query("grant create,update on $opt_database.test2 to $user");
+user_query("create table $opt_database.test2 (a int not null)");
user_query("delete from $opt_database.test where a=2",1);
user_query("delete from $opt_database.test where A=2",1);
user_query("update test set b=5 where b>0",1);
+user_query("update test,test2 SET test.b=5 where b>0",1);
+
safe_query("grant update(b),delete on $opt_database.test to $user");
safe_query("revoke update(a) on $opt_database.test from $user",1);
user_query("delete from $opt_database.test where a=2",1);
@@ -312,12 +375,19 @@ user_query("delete from $opt_database.test where a=2");
user_query("delete from $opt_database.test where A=2");
user_query("update test set b=5 where b>0");
user_query("update test set a=11 where b>5",1);
+user_query("update test,test2 SET test.b=5 where b>0");
+user_query("update test,test2 SET test.a=11 where b>0",1);
+user_query("update test,test2 SET test.b=test2.a where b>0",1);
+user_query("update test,test2 SET test.b=11 where test2.a>0",1);
user_query("select a,A from test");
safe_query("select $tables_cols from mysql.tables_priv");
safe_query("revoke ALL PRIVILEGES on $opt_database.test from $user");
safe_query("select $tables_cols from mysql.tables_priv");
safe_query("revoke GRANT OPTION on $opt_database.test from $user",1);
+safe_query("drop table $opt_database.test2");
+safe_query("revoke create,update on $opt_database.test2 from $user");
+
#
# Test grants on database level
#
@@ -396,26 +466,95 @@ safe_query("select $columns_cols from mysql.columns_priv where user = '$opt_user
safe_query("revoke ALL PRIVILEGES on $opt_database.test from $user");
user_query("select count(a) from test",1);
-user_query("select * from mysql.user",1);
+user_query("select * from mysql.user order by hostname",1);
safe_query("select * from mysql.db where user = '$opt_user'");
safe_query("select $tables_cols from mysql.tables_priv where user = '$opt_user'");
safe_query("select $columns_cols from mysql.columns_priv where user = '$opt_user'");
#
-# Test IDENTIFIED BY
-#
+# Clear up privileges to make future tests easier
safe_query("delete from user where user='$opt_user'");
+safe_query("delete from db where user='$opt_user'");
safe_query("flush privileges");
+safe_query("show grants for $user",1);
+
+#
+# Test IDENTIFIED BY
+#
+
safe_query("grant ALL PRIVILEGES on $opt_database.test to $user identified by 'dummy', ${opt_user}\@127.0.0.1 identified by 'dummy2'");
user_connect(0,"dummy");
safe_query("grant SELECT on $opt_database.* to $user identified by ''");
user_connect(0);
+safe_query("revoke ALL PRIVILEGES on $opt_database.test from $user identified by '', ${opt_user}\@127.0.0.1 identified by 'dummy2'");
+safe_query("revoke ALL PRIVILEGES on $opt_database.* from $user identified by ''");
+
+safe_query("show grants for $user");
+
+#
+# Test bug reported in SELECT INTO OUTFILE
+#
+
+safe_query("create table $opt_database.test3 (a int, b int)");
+safe_query("grant SELECT on $opt_database.test3 to $user");
+safe_query("grant FILE on *.* to $user");
+safe_query("insert into $opt_database.test3 values (1,1)");
+user_connect(0);
+user_query("select * into outfile '$tmp_table' from $opt_database.test3");
+safe_query("revoke SELECT on $opt_database.test3 from $user");
+safe_query("grant SELECT(a) on $opt_database.test3 to $user");
+user_query("select a from $opt_database.test3");
+user_query("select * from $opt_database.test3",1);
+user_query("select a,b from $opt_database.test3",1);
+user_query("select b from $opt_database.test3",1);
+
+safe_query("revoke SELECT(a) on $opt_database.test3 from $user");
+safe_query("revoke FILE on *.* from $user");
+safe_query("drop table $opt_database.test3");
+
+#
+# Test privileges needed for LOCK TABLES
+#
+
+safe_query("create table $opt_database.test3 (a int)");
+user_connect(1);
+safe_query("grant INSERT on $opt_database.test3 to $user");
+user_connect(0);
+user_query("select * into outfile '$tmp_table' from $opt_database.test3",1);
+safe_query("grant SELECT on $opt_database.test3 to $user");
+user_connect(0);
+user_query("LOCK TABLES $opt_database.test3 READ",1);
+safe_query("grant LOCK TABLES on *.* to $user");
+safe_query("show grants for $user");
+safe_query("select * from mysql.user where user='$opt_user'");
+user_connect(0);
+user_query("LOCK TABLES $opt_database.test3 READ");
+user_query("UNLOCK TABLES");
+safe_query("revoke SELECT,INSERT,UPDATE,DELETE on $opt_database.test3 from $user");
+user_connect(0);
+safe_query("revoke LOCK TABLES on *.* from $user");
+user_connect(1);
+safe_query("drop table $opt_database.test3");
+
+#
+# test new privileges in 4.0.2
+#
+
+safe_query("show grants for $user");
+safe_query("grant all on *.* to $user WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3");
+safe_query("show grants for $user");
+safe_query("revoke LOCK TABLES on *.* from $user");
+safe_query("flush privileges");
+safe_query("show grants for $user");
+safe_query("revoke ALL PRIVILEGES on *.* from $user");
+safe_query("show grants for $user");
#
# Clean up things
#
+unlink($tmp_table);
safe_query("drop database $opt_database");
safe_query("delete from user where user='$opt_user'");
safe_query("delete from db where user='$opt_user'");
@@ -540,7 +679,7 @@ sub user_query
{
if (!defined($ignore_error))
{
- die "The above should not have failed!";
+ die "Query '$query' should not have failed!";
}
}
elsif (defined($ignore_error) && $ignore_error == 1)
@@ -564,7 +703,7 @@ sub do_query
if (!$sth->execute)
{
$fatal_error= ($DBI::errstr =~ /parse error/);
- if (!$ignore_error || $opt_verbose || $fatal_error)
+ if (!$ignore_error || ($opt_verbose && $ignore_error != 3) || $fatal_error)
{
print "Error in execute: $DBI::errstr\n";
}
diff --git a/tests/grant.res b/tests/grant.res
index 086111ce567..e2832d27817 100644
--- a/tests/grant.res
+++ b/tests/grant.res
@@ -6,31 +6,36 @@ lock tables mysql.user write
flush privileges
unlock tables
drop database grant_test
-Error in execute: Can't drop database 'grant_test'. Database doesn't exist
create database grant_test
Connecting grant_user
-Error on connect: Access denied for user: '@localhost' to database 'grant_test'
+Error on connect: Access denied for user: ''@'localhost' to database 'grant_test'
+grant select(user) on mysql.user to grant_user@localhost
+revoke select(user) on mysql.user from grant_user@localhost
grant select on *.* to grant_user@localhost
set password FOR grant_user2@localhost = password('test')
Error in execute: Can't find any matching row in the user table
set password FOR grant_user=password('test')
Connecting grant_user
-Error on connect: Access denied for user: 'grant_user@localhost' (Using password: NO)
+Error on connect: Access denied for user: 'grant_user'@'localhost' (Using password: NO)
set password FOR grant_user=''
Connecting grant_user
select * from mysql.user where user = 'grant_user'
-localhost grant_user Y N N N N N N N N N N N N N
+localhost grant_user Y N N N N N N N N N N N N N N N N N N N N 0 0 0
select * from mysql.db where user = 'grant_user'
grant select on *.* to grant_user@localhost,grant_user@localhost
+show grants for grant_user@localhost
+GRANT SELECT ON *.* TO 'grant_user'@'localhost'
+
+Connecting grant_user
insert into mysql.user (host,user) values ('error','grant_user')
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
+Error in execute: insert command denied to user: 'grant_user'@'localhost' for table 'user'
update mysql.user set host='error' WHERE user='grant_user'
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
+Error in execute: update command denied to user: 'grant_user'@'localhost' for table 'user'
create table grant_test.test (a int,b int)
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: create command denied to user: 'grant_user'@'localhost' for table 'test'
grant select on *.* to grant_user2@localhost
-Error in execute: Access denied for user: 'grant_user@localhost' (Using password: NO)
+Error in execute: Access denied for user: 'grant_user'@'localhost' (Using password: NO)
revoke select on grant_test.test from grant_user@opt_host
Error in execute: There is no such grant defined for user 'grant_user' on host 'opt_host'
revoke select on grant_test.* from grant_user@opt_host
@@ -40,21 +45,30 @@ Error in execute: There is no such grant defined for user 'grant_user' on host '
grant select on grant_test.not_exists to grant_user
Error in execute: Table 'grant_test.not_exists' doesn't exist
grant FILE on grant_test.test to grant_user
-Error in execute: Illegal GRANT/REVOKE command. Please consult the manual which privileges can be used.
+Error in execute: Illegal GRANT/REVOKE command. Please consult the manual which privileges can be used
grant select on *.* to wrong___________user_name
Error in execute: The host or user argument to GRANT is too long
grant select on grant_test.* to wrong___________user_name
Error in execute: The host or user argument to GRANT is too long
+Connecting grant_user
grant select on grant_test.test to grant_user with grant option
-Error in execute: grant command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: grant command denied to user: 'grant_user'@'localhost' for table 'test'
set password FOR ''@''=''
Error in execute: Can't find any matching row in the user table
set password FOR root@localhost = password('test')
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'mysql'
revoke select on *.* from grant_user@localhost
-grant create on *.* to grant_user@localhost
+grant create,update on *.* to grant_user@localhost
Connecting grant_user
+flush privileges
create table grant_test.test (a int,b int)
+update grant_test.test set b=b+1 where a > 0
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test'
+show grants for grant_user@localhost
+GRANT UPDATE, CREATE ON *.* TO 'grant_user'@'localhost'
+
+revoke update on *.* from grant_user@localhost
+Connecting grant_user
grant select(c) on grant_test.test to grant_user@localhost
Error in execute: Unknown column 'c' in 'test'
revoke select(c) on grant_test.test from grant_user@localhost
@@ -62,12 +76,12 @@ Error in execute: There is no such grant defined for user 'grant_user' on host '
grant select on grant_test.test to wrong___________user_name
Error in execute: The host or user argument to GRANT is too long
INSERT INTO grant_test.test values (2,0)
-Error in execute: insert command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: insert command denied to user: 'grant_user'@'localhost' for table 'test'
grant ALL PRIVILEGES on *.* to grant_user@localhost
REVOKE INSERT on *.* from grant_user@localhost
Connecting grant_user
INSERT INTO grant_test.test values (1,0)
-Error in execute: insert command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: insert command denied to user: 'grant_user'@'localhost' for table 'test'
grant INSERT on *.* to grant_user@localhost
Connecting grant_user
INSERT INTO grant_test.test values (2,0)
@@ -77,7 +91,7 @@ select count(*) from grant_test.test
revoke SELECT on *.* from grant_user@localhost
Connecting grant_user
select count(*) from grant_test.test
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test'
INSERT INTO grant_test.test values (3,0)
grant SELECT on *.* to grant_user@localhost
Connecting grant_user
@@ -86,40 +100,40 @@ select count(*) from grant_test.test
revoke ALL PRIVILEGES on *.* from grant_user@localhost
Connecting grant_user
-Error on connect: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error on connect: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
delete from user where user='grant_user'
flush privileges
delete from user where user='grant_user'
flush privileges
grant select on grant_test.* to grant_user@localhost
select * from mysql.user where user = 'grant_user'
-localhost grant_user N N N N N N N N N N N N N N
+localhost grant_user N N N N N N N N N N N N N N N N N N N N N 0 0 0
select * from mysql.db where user = 'grant_user'
-localhost grant_test grant_user Y N N N N N N N N N
+localhost grant_test grant_user Y N N N N N N N N N N N
Connecting grant_user
select count(*) from grant_test.test
2
select * from mysql.user where user = 'grant_user'
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'mysql'
insert into grant_test.test values (4,0)
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
update grant_test.test set a=1
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
delete from grant_test.test
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
create table grant_test.test2 (a int)
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
ALTER TABLE grant_test.test add c int
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
CREATE INDEX dummy ON grant_test.test (a)
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
drop table grant_test.test
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
grant ALL PRIVILEGES on grant_test.* to grant_user2@localhost
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
grant ALL PRIVILEGES on grant_test.* to grant_user@localhost WITH GRANT OPTION
Connecting grant_user
insert into grant_test.test values (5,0)
@@ -130,33 +144,45 @@ REVOKE ALL PRIVILEGES on grant_test.* from grant_user@localhost
REVOKE ALL PRIVILEGES on grant_test.* from grant_user@localhost
Connecting grant_user
insert into grant_test.test values (6,0)
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
REVOKE GRANT OPTION on grant_test.* from grant_user@localhost
Connecting grant_user
-Error on connect: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error on connect: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
grant ALL PRIVILEGES on grant_test.* to grant_user@localhost
Connecting grant_user
select * from mysql.user where user = 'grant_user'
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'mysql'
insert into grant_test.test values (7,0)
update grant_test.test set a=3 where a=2
delete from grant_test.test where a=3
create table grant_test.test2 (a int not null)
alter table grant_test.test2 add b int
create index dummy on grant_test.test2 (a)
+update test,test2 SET test.a=test2.a where test.a=test2.a
drop table grant_test.test2
show tables from grant_test
test
insert into mysql.user (host,user) values ('error','grant_user',0)
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'mysql'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'mysql'
revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost
select * from mysql.user where user = 'grant_user'
-localhost grant_user N N N N N N N N N N N N N N
+localhost grant_user N N N N N N N N N N N N N N N N N N N N N 0 0 0
select * from mysql.db where user = 'grant_user'
+grant CREATE,UPDATE,DROP on grant_test.* to grant_user@localhost
+Connecting grant_user
+create table grant_test.test2 (a int not null)
+update test,test2 SET test.a=1 where 1
+update test,test2 SET test.a=test2.a where 1
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test2'
+grant SELECT on grant_test.* to grant_user@localhost
Connecting grant_user
-Error on connect: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+update test,test2 SET test.a=test2.a where test2.a=test.a
+drop table grant_test.test2
+revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost
+Connecting grant_user
+Error on connect: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
grant create on grant_test.test2 to grant_user@localhost
Connecting grant_user
create table grant_test.test2 (a int not null)
@@ -164,15 +190,15 @@ show tables
test2
show columns from test
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test'
show keys from test
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test'
show columns from test2
a int(11) 0
show keys from test2
select * from test
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test'
grant insert on grant_test.test to grant_user@localhost
show tables
test
@@ -180,22 +206,32 @@ test2
insert into grant_test.test values (8,0)
update grant_test.test set b=1
-Error in execute: update command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: update command denied to user: 'grant_user'@'localhost' for table 'test'
grant update on grant_test.test to grant_user@localhost
update grant_test.test set b=2
+update grant_test.test,test2 SET test.b=3
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test2'
+grant select on grant_test.test2 to grant_user@localhost
+update grant_test.test,test2 SET test.b=3
+revoke select on grant_test.test2 from grant_user@localhost
delete from grant_test.test
-Error in execute: delete command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: delete command denied to user: 'grant_user'@'localhost' for table 'test'
grant delete on grant_test.test to grant_user@localhost
delete from grant_test.test where a=1
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'a' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test'
update grant_test.test set b=3 where b=1
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
update grant_test.test set b=b+1
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
+update grant_test.test,test2 SET test.a=test2.a
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test2'
grant SELECT on *.* to grant_user@localhost
Connecting grant_user
update grant_test.test set b=b+1
update grant_test.test set b=b+1 where a > 0
+update grant_test.test,test2 SET test.a=test2.a
+update grant_test.test,test2 SET test2.a=test.a
+Error in execute: UPDATE command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test2'
revoke SELECT on *.* from grant_user@localhost
grant SELECT on grant_test.* to grant_user@localhost
Connecting grant_user
@@ -209,11 +245,11 @@ revoke UPDATE on *.* from grant_user@localhost
revoke SELECT on grant_test.* from grant_user@localhost
Connecting grant_user
update grant_test.test set b=b+1 where a > 0
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'a' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test'
update grant_test.test set b=b+1
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
select * from test
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test'
grant select on grant_test.test to grant_user@localhost
delete from grant_test.test where a=1
update grant_test.test set b=2 where b=1
@@ -221,70 +257,95 @@ update grant_test.test set b=b+1
select count(*) from test
3
+update test,test2 SET test.b=4
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test2'
+update test,test2 SET test2.a=test.a
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test2'
+update test,test2 SET test.a=test2.a
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test2'
create table grant_test.test3 (a int)
-Error in execute: create command denied to user: 'grant_user@localhost' for table 'test3'
+Error in execute: create command denied to user: 'grant_user'@'localhost' for table 'test3'
alter table grant_test.test2 add c int
-Error in execute: alter command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: alter command denied to user: 'grant_user'@'localhost' for table 'test2'
grant alter on grant_test.test2 to grant_user@localhost
alter table grant_test.test2 add c int
create index dummy ON grant_test.test (a)
-Error in execute: index command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: index command denied to user: 'grant_user'@'localhost' for table 'test'
grant index on grant_test.test2 to grant_user@localhost
create index dummy ON grant_test.test2 (a)
insert into test2 SELECT a,a from test
-Error in execute: insert command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: insert command denied to user: 'grant_user'@'localhost' for table 'test2'
grant insert on test2 to grant_user@localhost
Error in execute: Table 'mysql.test2' doesn't exist
grant insert(a) on grant_test.test2 to grant_user@localhost
insert into test2 SELECT a,a from test
-Error in execute: insert command denied to user: 'grant_user@localhost' for column 'c' in table 'test2'
+Error in execute: insert command denied to user: 'grant_user'@'localhost' for column 'c' in table 'test2'
grant insert(c) on grant_test.test2 to grant_user@localhost
insert into test2 SELECT a,a from test
select count(*) from test2,test
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test2'
select count(*) from test,test2
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test2'
replace into test2 SELECT a from test
-Error in execute: update command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: delete command denied to user: 'grant_user'@'localhost' for table 'test2'
grant update on grant_test.test2 to grant_user@localhost
+update test,test2 SET test2.a=test.a
+update test,test2 SET test.b=test2.a where 0
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test2'
+update test,test2 SET test.a=2 where test2.a>100
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test2'
+update test,test2 SET test.a=test2.a
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test2'
replace into test2 SELECT a,a from test
-Error in execute: delete command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: delete command denied to user: 'grant_user'@'localhost' for table 'test2'
grant DELETE on grant_test.test2 to grant_user@localhost
replace into test2 SELECT a,a from test
insert into test (a) SELECT a from test2
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test2'
+grant SELECT on grant_test.test2 to grant_user@localhost
+update test,test2 SET test.b=test2.a where 0
+update test,test2 SET test.a=test2.a where test2.a>100
+revoke UPDATE on grant_test.test2 from grant_user@localhost
+grant UPDATE (c) on grant_test.test2 to grant_user@localhost
+update test,test2 SET test.b=test2.a where 0
+update test,test2 SET test.a=test2.a where test2.a>100
+update test,test2 SET test2.a=test2.a where test2.a>100
+Error in execute: UPDATE command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test2'
+update test,test2 SET test2.c=test2.a where test2.a>100
+revoke SELECT,UPDATE on grant_test.test2 from grant_user@localhost
+grant UPDATE on grant_test.test2 to grant_user@localhost
drop table grant_test.test2
-Error in execute: drop command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: drop command denied to user: 'grant_user'@'localhost' for table 'test2'
grant select on grant_test.test2 to grant_user@localhost with grant option
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test2'
grant drop on grant_test.test2 to grant_user@localhost with grant option
grant drop on grant_test.test2 to grant_user@localhost with grant option
grant select on grant_test.test2 to grant_user@localhost with grant option
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test2'
rename table grant_test.test2 to grant_test.test3
-Error in execute: insert command denied to user: 'grant_user@localhost' for table 'test3'
+Error in execute: insert command denied to user: 'grant_user'@'localhost' for table 'test3'
grant CREATE,DROP on grant_test.test3 to grant_user@localhost
rename table grant_test.test2 to grant_test.test3
-Error in execute: insert command denied to user: 'grant_user@localhost' for table 'test3'
+Error in execute: insert command denied to user: 'grant_user'@'localhost' for table 'test3'
create table grant_test.test3 (a int)
grant INSERT on grant_test.test3 to grant_user@localhost
drop table grant_test.test3
rename table grant_test.test2 to grant_test.test3
rename table grant_test.test3 to grant_test.test2
-Error in execute: alter command denied to user: 'grant_user@localhost' for table 'test3'
+Error in execute: alter command denied to user: 'grant_user'@'localhost' for table 'test3'
grant ALTER on grant_test.test3 to grant_user@localhost
rename table grant_test.test3 to grant_test.test2
revoke DROP on grant_test.test2 from grant_user@localhost
rename table grant_test.test2 to grant_test.test3
drop table if exists grant_test.test2,grant_test.test3
-Error in execute: drop command denied to user: 'grant_user@localhost' for table 'test2'
+Error in execute: drop command denied to user: 'grant_user'@'localhost' for table 'test2'
drop table if exists grant_test.test2,grant_test.test3
create database grant_test
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
drop database grant_test
-Error in execute: Access denied for user: 'grant_user@localhost' to database 'grant_test'
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
flush tables
-Error in execute: Access denied for user: 'grant_user@localhost' (Using password: NO)
+Error in execute: Access denied. You need the RELOAD privilege for this operation
flush privileges
select Host, Db, User, Table_name, Grantor, Table_priv, Column_priv from mysql.tables_priv
localhost grant_test grant_user test2 root@localhost Update,Delete,Create,Grant,Index,Alter Insert
@@ -297,38 +358,54 @@ revoke ALL PRIVILEGES on grant_test.test3 from grant_user@localhost
revoke GRANT OPTION on grant_test.test2 from grant_user@localhost
select Host, Db, User, Table_name, Grantor, Table_priv, Column_priv from mysql.tables_priv
select count(a) from test
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test'
+grant create,update on grant_test.test2 to grant_user@localhost
+create table grant_test.test2 (a int not null)
delete from grant_test.test where a=2
-Error in execute: delete command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: delete command denied to user: 'grant_user'@'localhost' for table 'test'
delete from grant_test.test where A=2
-Error in execute: delete command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: delete command denied to user: 'grant_user'@'localhost' for table 'test'
update test set b=5 where b>0
-Error in execute: update command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: update command denied to user: 'grant_user'@'localhost' for table 'test'
+update test,test2 SET test.b=5 where b>0
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test'
grant update(b),delete on grant_test.test to grant_user@localhost
revoke update(a) on grant_test.test from grant_user@localhost
Error in execute: There is no such grant defined for user 'grant_user' on host 'localhost' on table 'test'
delete from grant_test.test where a=2
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'a' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test'
update test set b=5 where b>0
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
grant select(a),select(b) on grant_test.test to grant_user@localhost
delete from grant_test.test where a=2
delete from grant_test.test where A=2
update test set b=5 where b>0
update test set a=11 where b>5
-Error in execute: update command denied to user: 'grant_user@localhost' for column 'a' in table 'test'
+Error in execute: UPDATE command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test'
+update test,test2 SET test.b=5 where b>0
+update test,test2 SET test.a=11 where b>0
+Error in execute: UPDATE command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test'
+update test,test2 SET test.b=test2.a where b>0
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test2'
+update test,test2 SET test.b=11 where test2.a>0
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test2'
select a,A from test
8 8
5 5
7 7
select Host, Db, User, Table_name, Grantor, Table_priv, Column_priv from mysql.tables_priv
+localhost grant_test grant_user test2 root@localhost Update,Create
localhost grant_test grant_user test root@localhost Delete Select,Update
revoke ALL PRIVILEGES on grant_test.test from grant_user@localhost
select Host, Db, User, Table_name, Grantor, Table_priv, Column_priv from mysql.tables_priv
+localhost grant_test grant_user test2 root@localhost Update,Create
+
revoke GRANT OPTION on grant_test.test from grant_user@localhost
Error in execute: There is no such grant defined for user 'grant_user' on host 'localhost' on table 'test'
+drop table grant_test.test2
+revoke create,update on grant_test.test2 from grant_user@localhost
grant select(a) on grant_test.test to grant_user@localhost
show full columns from test
a int(11) YES NULL select
@@ -348,21 +425,21 @@ insert into test (b) values (5)
insert into test (b) values (a)
update test set b=3 where a > 0
select * from test
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
select b from test
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
select a from test where b > 0
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
insert into test (a) values (10)
-Error in execute: insert command denied to user: 'grant_user@localhost' for column 'a' in table 'test'
+Error in execute: INSERT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test'
insert into test (b) values (b)
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
insert into test (a,b) values (1,5)
-Error in execute: insert command denied to user: 'grant_user@localhost' for column 'a' in table 'test'
+Error in execute: INSERT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test'
insert into test (b) values (1),(b)
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
update test set b=3 where b > 0
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
select Host, Db, User, Table_name, Grantor, Table_priv, Column_priv from mysql.tables_priv
localhost grant_test grant_user test root@localhost Select,Insert,Update
@@ -378,9 +455,9 @@ select Host, Db, User, Table_name, Column_name, Column_priv from mysql.columns_p
localhost grant_test grant_user test b Insert
select count(a) from test
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test'
update test set b=4
-Error in execute: update command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: update command denied to user: 'grant_user'@'localhost' for table 'test'
grant select(a,b), update (a,b) on grant_test.test to grant_user@localhost
select count(a),count(b) from test where a+b > 0
3 3
@@ -396,13 +473,13 @@ localhost grant_test grant_user test b Select,Insert,Update
localhost grant_test grant_user test a Select,Update
insert into test (a,b) values (12,12)
-Error in execute: insert command denied to user: 'grant_user@localhost' for column 'a' in table 'test'
+Error in execute: INSERT command denied to user: 'grant_user'@'localhost' for column 'a' in table 'test'
grant insert on grant_test.* to grant_user@localhost
Connecting grant_user
insert into test (a,b) values (13,13)
revoke select(b) on grant_test.test from grant_user@localhost
select count(a) from test where a+b > 0
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
update test set b=5 where a=2
grant select on grant_test.test to grant_user@localhost
Connecting grant_user
@@ -416,10 +493,10 @@ select count(a) from test where a+b > 0
revoke select on grant_test.test from grant_user@localhost
Connecting grant_user
select count(a) from test where a+b > 0
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test'
grant select(a) on grant_test.test to grant_user@localhost
select count(a) from test where a+b > 0
-Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test'
grant select on *.* to grant_user@localhost
Connecting grant_user
select count(a) from test where a+b > 0
@@ -432,7 +509,7 @@ select count(a) from test where a+b > 0
4
select * from mysql.db where user = 'grant_user'
-localhost grant_test grant_user N Y N N N N N N N N
+localhost grant_test grant_user N Y N N N N N N N N N N
select Host, Db, User, Table_name, Grantor, Table_priv, Column_priv from mysql.tables_priv where user = 'grant_user'
localhost grant_test grant_user test root@localhost Select,Insert,Update
@@ -443,20 +520,93 @@ localhost grant_test grant_user test a Select,Update
revoke ALL PRIVILEGES on grant_test.test from grant_user@localhost
select count(a) from test
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
-select * from mysql.user
-Error in execute: select command denied to user: 'grant_user@localhost' for table 'user'
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'test'
+select * from mysql.user order by hostname
+Error in execute: select command denied to user: 'grant_user'@'localhost' for table 'user'
select * from mysql.db where user = 'grant_user'
-localhost grant_test grant_user N Y N N N N N N N N
+localhost grant_test grant_user N Y N N N N N N N N N N
select Host, Db, User, Table_name, Grantor, Table_priv, Column_priv from mysql.tables_priv where user = 'grant_user'
select Host, Db, User, Table_name, Column_name, Column_priv from mysql.columns_priv where user = 'grant_user'
delete from user where user='grant_user'
+delete from db where user='grant_user'
flush privileges
+show grants for grant_user@localhost
+Error in execute: There is no such grant defined for user 'grant_user' on host 'localhost'
grant ALL PRIVILEGES on grant_test.test to grant_user@localhost identified by 'dummy', grant_user@127.0.0.1 identified by 'dummy2'
Connecting grant_user
grant SELECT on grant_test.* to grant_user@localhost identified by ''
Connecting grant_user
+revoke ALL PRIVILEGES on grant_test.test from grant_user@localhost identified by '', grant_user@127.0.0.1 identified by 'dummy2'
+revoke ALL PRIVILEGES on grant_test.* from grant_user@localhost identified by ''
+show grants for grant_user@localhost
+GRANT USAGE ON *.* TO 'grant_user'@'localhost'
+
+create table grant_test.test3 (a int, b int)
+grant SELECT on grant_test.test3 to grant_user@localhost
+grant FILE on *.* to grant_user@localhost
+insert into grant_test.test3 values (1,1)
+Connecting grant_user
+select * into outfile '/tmp/mysql-grant.test' from grant_test.test3
+revoke SELECT on grant_test.test3 from grant_user@localhost
+grant SELECT(a) on grant_test.test3 to grant_user@localhost
+select a from grant_test.test3
+1
+
+select * from grant_test.test3
+Error in execute: select command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test3'
+select a,b from grant_test.test3
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test3'
+select b from grant_test.test3
+Error in execute: SELECT command denied to user: 'grant_user'@'localhost' for column 'b' in table 'test3'
+revoke SELECT(a) on grant_test.test3 from grant_user@localhost
+revoke FILE on *.* from grant_user@localhost
+drop table grant_test.test3
+create table grant_test.test3 (a int)
+Connecting grant_user
+Error on connect: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
+grant INSERT on grant_test.test3 to grant_user@localhost
+Connecting grant_user
+select * into outfile '/tmp/mysql-grant.test' from grant_test.test3
+Error in execute: Access denied for user: 'grant_user'@'localhost' (Using password: NO)
+grant SELECT on grant_test.test3 to grant_user@localhost
+Connecting grant_user
+LOCK TABLES grant_test.test3 READ
+Error in execute: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
+grant LOCK TABLES on *.* to grant_user@localhost
+show grants for grant_user@localhost
+GRANT LOCK TABLES ON *.* TO 'grant_user'@'localhost'
+GRANT SELECT, INSERT ON `grant_test`.`test3` TO 'grant_user'@'localhost'
+
+select * from mysql.user where user='grant_user'
+127.0.0.1 grant_user 7f70e8b858ee6782 N N N N N N N N N N N N N N N N N N N N N 0 0 0
+localhost grant_user N N N N N N N N N N N N N N N N N Y N N N 0 0 0
+
+Connecting grant_user
+LOCK TABLES grant_test.test3 READ
+UNLOCK TABLES
+revoke SELECT,INSERT,UPDATE,DELETE on grant_test.test3 from grant_user@localhost
+Connecting grant_user
+revoke LOCK TABLES on *.* from grant_user@localhost
+Connecting grant_user
+Error on connect: Access denied for user: 'grant_user'@'localhost' to database 'grant_test'
+drop table grant_test.test3
+show grants for grant_user@localhost
+GRANT USAGE ON *.* TO 'grant_user'@'localhost'
+
+grant all on *.* to grant_user@localhost WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3
+show grants for grant_user@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'grant_user'@'localhost' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3
+
+revoke LOCK TABLES on *.* from grant_user@localhost
+flush privileges
+show grants for grant_user@localhost
+GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'grant_user'@'localhost' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3
+
+revoke ALL PRIVILEGES on *.* from grant_user@localhost
+show grants for grant_user@localhost
+GRANT USAGE ON *.* TO 'grant_user'@'localhost' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 2 MAX_CONNECTIONS_PER_HOUR 3
+
drop database grant_test
delete from user where user='grant_user'
delete from db where user='grant_user'
diff --git a/tests/insert_and_repair.pl b/tests/insert_and_repair.pl
index 4d68c2ab9a0..1c7186bb651 100755
--- a/tests/insert_and_repair.pl
+++ b/tests/insert_and_repair.pl
@@ -56,7 +56,7 @@ $errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
- print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}
diff --git a/tests/mail_to_db.pl b/tests/mail_to_db.pl
index b758a171c77..dc40fb3ede6 100755
--- a/tests/mail_to_db.pl
+++ b/tests/mail_to_db.pl
@@ -17,7 +17,7 @@ use DBI;
use Getopt::Long;
$| = 1;
-$VER = "2.3";
+$VER = "2.6";
$opt_help = 0;
$opt_version = 0;
@@ -25,8 +25,8 @@ $opt_debug = 0;
$opt_host = undef();
$opt_port = undef();
$opt_socket = undef();
-$opt_db = undef();
-$opt_table = undef();
+$opt_db = "mail";
+$opt_table = "mails";
$opt_user = undef();
$opt_password = undef();
$opt_max_mail_size = 65536;
@@ -152,19 +152,77 @@ sub main
$dbh->disconnect if (!$opt_test);
$ignored = ($mail_no_from_f + $mail_no_subject_f + $mail_no_txt_f +
- $mail_too_big + $mail_duplicates);
- print "Mails inserted:\t\t\t$mail_inserted\n";
- print "Mails ignored:\t\t\t$ignored\n";
- print "Mails without \"From:\" -field:\t$mail_no_from_f\n";
- print "Mails without message:\t\t$mail_no_txt_f\n";
- print "Mails without subject:\t\t$mail_no_subject_f\n";
- print "Too big mails (> $opt_max_mail_size):\t$mail_too_big\n";
- print "Duplicate mails:\t\t$mail_duplicates\n";
- print "Forwarded mails:\t\t$mail_forwarded\n";
- print "Total number of mails:\t\t";
+ $mail_too_big + $mail_duplicates + $mail_fixed);
+ print "################################ Mail Report #################################\n\n";
+ print "Mails inserted:\t\t\t\t\t$mail_inserted\n";
+ print "--------------- ";
+ print "=" . "=" x length("$mail_inserted") . "=\n\n";
+ if ($ignored)
+ {
+ print "Ignored mails\n";
+ print "-------------\n";
+ if ($mail_no_from_f)
+ {
+ print "Reason: mail without \"From:\" -field:\t\t$mail_no_from_f\n";
+ }
+ else
+ {
+ print "";
+ }
+ if ($mail_no_txt_f)
+ {
+ print "Reason: mail without message:\t\t\t$mail_no_txt_f\n";
+ }
+ else
+ {
+ print "";
+ }
+ if ($mail_no_subject_f)
+ {
+ print "Reason: mail without subject:\t\t\t$mail_no_subject_f\n";
+ }
+ else
+ {
+ print "";
+ }
+ if ($mail_too_big)
+ {
+ print "Reason: mail too big, over $opt_max_mail_size bytes:\t\t";
+ print $mail_too_big;
+ print " (see --max_mail_size=#)\n";
+ }
+ else
+ {
+ print "";
+ }
+ if ($mail_duplicates)
+ {
+ print "Reason: duplicate mail, or in db already:\t$mail_duplicates\n";
+ }
+ else
+ {
+ print "";
+ }
+ if ($mail_fixed)
+ {
+ print "Reason: mail was an unsubscribe - mail:\t\t$mail_fixed\n";
+ }
+ else
+ {
+ print "";
+ }
+ print " ";
+ print "=" . "=" x length("$ignored") . "=\n";
+ print "Total number of ignored mails:\t\t\t$ignored\n\n";
+ }
+ print "Total number of mails:\t\t\t\t";
print $mail_inserted + $ignored;
- print "\n";
- print "Mails with unsubscribe removed:\t$mail_fixed\n";
+ print " (OK: ";
+ print sprintf("%.1f", (($mail_inserted / ($mail_inserted+$ignored)) * 100));
+ print "% Ignored: ";
+ print sprintf("%.1f", (($ignored / ($mail_inserted + $ignored)) * 100));
+ print "%)\n";
+ print "################################ End Report ##################################\n";
exit(0);
}
@@ -213,10 +271,10 @@ sub process_mail_file
%values = ();
$type = "";
$check = 0;
-
while (<FILE>)
{
chop;
+ chop if (substr($_, -1, 1) eq "\r");
if ($type ne "message")
{
if (/^Reply-To: (.*)/i)
@@ -269,7 +327,8 @@ sub process_mail_file
$values{$type} .= "\n" . $_;
$check--;
}
- elsif (/^From .* \d\d:\d\d:\d\d\s\d\d\d\d$/)
+ elsif (/^From .* \d\d:\d\d:\d\d\s\d\d\d\d/ ||
+ /^From .* \d\d\d\d\s\d\d:\d\d:\d\d/)
{
$values{'hash'} = checksum("$values{'message'}");
update_table($dbh, $file_name, \%values);
@@ -288,8 +347,11 @@ sub process_mail_file
$values{$type} .= "\n" . $_;
}
}
- $values{'hash'} = checksum("$values{'message'}");
- update_table($dbh, $file_name, \%values);
+ if (defined($values{'message'}))
+ {
+ $values{'hash'} = checksum("$values{'message'}");
+ update_table($dbh, $file_name, \%values);
+ }
}
####
@@ -335,26 +397,26 @@ sub date_parser
sub update_table
{
my($dbh, $file_name, $values) = @_;
- my($q,$tail,$message);
+ my($q, $tail, $message);
if (!defined($values->{'subject'}) || !defined($values->{'to'}))
{
$mail_no_subject_f++;
return; # Ignore these
}
- $message=$values->{'message'};
- $message =~ s/^\s*//; #removes whitespaces from the beginning
+ $message = $values->{'message'};
+ $message =~ s/^\s*//; # removes whitespaces from the beginning
restart:
- $message =~ s/[\s\n>]*$//; #removes whitespaces and '>' from the end
- $values->{'message'}=$message;
+ $message =~ s/[\s\n>]*$//; # removes whitespaces and '>' from the end
+ $values->{'message'} = $message;
foreach $tail (@remove_tail)
{
$message =~ s/$tail//;
}
if ($message ne $values->{'message'})
{
- $message =~ s/\s*$//; #removes whitespaces from the end
+ $message =~ s/\s*$//; # removes whitespaces from the end
$mail_fixed++;
goto restart; # Some mails may have duplicated messages
}
@@ -442,7 +504,7 @@ sub update_table
sub checksum
{
my ($txt)= @_;
- my ($crc,$i,$count);
+ my ($crc, $i, $count);
$count = length($txt);
for ($crc = $i = 0; $i < $count ; $i++)
{
diff --git a/tests/myisam-big-rows.tst b/tests/myisam-big-rows.tst
new file mode 100644
index 00000000000..56c06f4820f
--- /dev/null
+++ b/tests/myisam-big-rows.tst
@@ -0,0 +1,72 @@
+#
+# Test rows with length above > 16M
+# Note that for this to work, you should start mysqld with
+# -O max_allowed_packet=32M
+#
+
+drop table if exists t1;
+create table t1 (a tinyint not null auto_increment, b longblob not null, primary key (a)) checksum=1;
+
+insert into t1 (b) values(repeat(char(65),10));
+insert into t1 (b) values(repeat(char(66),10));
+insert into t1 (b) values(repeat(char(67),10));
+update t1 set b=repeat(char(68),16777216) where a=1;
+check table t1;
+update t1 set b=repeat(char(69),16777000) where a=2;
+update t1 set b=repeat(char(70),167) where a=3;
+update t1 set b=repeat(char(71),16778000) where a=1;
+update t1 set b=repeat(char(72),16778000) where a=3;
+select a,length(b) from t1;
+set @a=1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+update t1 set b=('A') where a=5;
+delete from t1 where a=7;
+set @a=@a+1;
+insert into t1 (b) values (repeat(char(73+@a),16777200+@a));
+update t1 set b=repeat(char(73+@a+1),17000000+@a) where a=last_insert_id();
+
+select a,mid(b,1,5),length(b) from t1;
+check table t1;
+repair table t1;
+check table t1;
+select a from table where b<>repeat(mid(b,1,1),length(b));
+delete from t1 where (a & 1);
+select a from table where b<>repeat(mid(b,1,1),length(b));
+check table t1;
+repair table t1;
+check table t1;
+drop table t1;
diff --git a/tests/rename_test.pl b/tests/rename_test.pl
index bdfb14be927..edf3216a62f 100755
--- a/tests/rename_test.pl
+++ b/tests/rename_test.pl
@@ -79,7 +79,7 @@ print "Total time: " .
exit(0);
#
-# Insert records in the table. Delete table when test is finnished
+# Insert records in the table. Delete table when test is finished
#
sub test_insert
diff --git a/tests/table_types.pl b/tests/table_types.pl
index 8198cd9ba86..4dbcdcb975c 100755
--- a/tests/table_types.pl
+++ b/tests/table_types.pl
@@ -66,13 +66,6 @@ $dbh = $server->connect();
####
$table_name="bench1";
-<<<<<<< table_types.pl
-||||||| 1.2
-test("n","type=isam","char"); test("m","type=myisam pack_keys=1","char"); exit(1);
-
-=======
-
->>>>>>> /tmp/T4a17019
test($table_name,"type=isam","char");
test($table_name,"type=myisam pack_keys=0","char");
test($table_name,"type=myisam pack_keys=0","char");
@@ -91,7 +84,7 @@ exit (0);
sub test {
my ($name,$options,$chartype)=@_;
-
+
print "\nTesting with options: '$options'\n";
$dbh->do("drop table $name");
do_many($dbh,$server->create("$name",
@@ -102,23 +95,23 @@ sub test {
["primary key (id,id2)",
"index index_id3 (id3)"],
$options));
-
+
if ($opt_lock_tables)
{
$sth = $dbh->do("LOCK TABLES $name WRITE") || die $DBI::errstr;
}
-
+
if ($opt_fast && defined($server->{vacuum}))
{
$server->vacuum(\$dbh,1);
}
-
+
####
#### Insert $total_rows records in order, in reverse order and random.
####
-
+
$loop_time=new Benchmark;
-
+
if ($opt_fast_insert)
{
$query="insert into $name values ";
@@ -127,11 +120,11 @@ sub test {
{
$query="insert into $name (id,id2,id3,dummy1) values ";
}
-
+
if (($opt_fast || $opt_fast_insert) && $limits->{'multi_value_insert'})
{
$query_size=$server->{'limits'}->{'query_size'};
-
+
print "Inserting $opt_loop_count multiple-value rows in order\n";
$res=$query;
for ($i=0 ; $i < $opt_loop_count ; $i++)
@@ -186,7 +179,7 @@ sub test {
{
$sth = $dbh->do($query . "($i,$i,$i,'ABCDEFGHIJ')") or die $DBI::errstr;
}
-
+
print "Inserting $opt_loop_count rows in reverse order\n";
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
@@ -195,25 +188,25 @@ sub test {
($total_rows-1-$i) . ",'BCDEFGHIJK')")
or die $DBI::errstr;
}
-
+
print "Inserting $opt_loop_count rows in random order\n";
-
+
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$sth = $dbh->do($query . "(". $random[$i] . "," . $random[$i] .
"," . $random[$i] . ",'CDEFGHIJKL')") or die $DBI::errstr;
}
}
-
+
$end_time=new Benchmark;
print "Time for insert (" . ($total_rows) . "): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
-
+
if ($opt_fast && defined($server->{vacuum}))
{
$server->vacuum(\$dbh,1);
}
-
+
$sth=$dbh->prepare("show table status like '$name'");
$sth->execute || die "Show table status returned error: $DBI::errstr\n";
while (@row = $sth->fetchrow_array)
diff --git a/tests/test_delayed_insert.pl b/tests/test_delayed_insert.pl
index e49d73a19bd..c7a8f0ca4b7 100755
--- a/tests/test_delayed_insert.pl
+++ b/tests/test_delayed_insert.pl
@@ -65,7 +65,7 @@ $errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
- print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}
diff --git a/tests/truncate.pl b/tests/truncate.pl
new file mode 100755
index 00000000000..57b50cf96b6
--- /dev/null
+++ b/tests/truncate.pl
@@ -0,0 +1,125 @@
+#!/usr/bin/perl -w
+#
+# This is a test with uses many processes to test a MySQL server.
+#
+
+$opt_loop_count=10000; # Change this to make test harder/easier
+
+##################### Standard benchmark inits ##############################
+
+use DBI;
+use Getopt::Long;
+use Benchmark;
+
+package main;
+
+$opt_skip_create=$opt_skip_in=$opt_verbose=$opt_fast_insert=
+$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=0;
+$opt_threads=2;
+$opt_host=$opt_user=$opt_password=""; $opt_db="test";
+
+GetOptions("host=s","db=s","user=s","password=s","loop-count=i","skip-create","skip-in","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","threads=i") || die "Aborted";
+$opt_verbose=$opt_debug=$opt_lock_tables=$opt_fast_insert=$opt_fast=$opt_skip_in=$opt_force=undef; # Ignore warnings from these
+
+print "Testing truncate from $opt_threads multiple connections $opt_loop_count times\n";
+
+@testtables = ( ["bench_f31", "type=heap"]);
+
+####
+#### Start timeing and start test
+####
+
+$start_time=new Benchmark;
+$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
+ $opt_user, $opt_password,
+ { PrintError => 0}) || die $DBI::errstr;
+if (!$opt_skip_create)
+{
+ my $table_def;
+ foreach $table_def (@testtables)
+ {
+ my ($table,$extra)= ($table_def->[0], $table_def->[1]);
+ print "Creating table $table in database $opt_db\n";
+ $dbh->do("drop table if exists $table");
+ $dbh->do("create table $table".
+ " (id int(6) not null,".
+ " info varchar(32)," .
+ " marker timestamp," .
+ " flag int not null," .
+ " primary key(id)) $extra")
+
+ or die $DBI::errstr;
+ }
+}
+
+$dbh->disconnect; $dbh=0; # Close handler
+$|= 1; # Autoflush
+
+####
+#### Start the tests
+####
+
+for ($i=0 ; $i < $opt_threads ; $i ++)
+{
+ test_truncate() if (($pid=fork()) == 0); $work{$pid}="truncate";
+}
+
+print "Started $opt_threads threads\n";
+
+$errors=0;
+$running_insert_threads=$opt_threads;
+while (($pid=wait()) != -1)
+{
+ $ret=$?/256;
+ print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
+ --$running_insert_threads;
+ $errors++ if ($ret != 0);
+}
+
+#
+# Cleanup
+#
+
+if (!$opt_skip_delete && !$errors)
+{
+ my $table_def;
+ $dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
+ $opt_user, $opt_password,
+ { PrintError => 0}) || die $DBI::errstr;
+
+ foreach $table_def (@testtables)
+ {
+ $dbh->do("drop table " . $table_def->[0]);
+ }
+ $dbh->disconnect; $dbh=0; # Close handler
+}
+
+print ($errors ? "Test failed\n" :"Test ok\n");
+$end_time=new Benchmark;
+print "Total time: " .
+ timestr(timediff($end_time, $start_time),"noc") . "\n";
+
+exit(0);
+
+
+#
+# Insert records in the table
+#
+
+sub test_truncate
+{
+ my ($dbh,$i,$j,$count,$table_def,$table);
+
+ $dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
+ $opt_user, $opt_password,
+ { PrintError => 0}) || die $DBI::errstr;
+
+ for ($count=0; $count < $opt_loop_count ; $count++)
+ {
+ my ($table)= ($testtables[0]->[0]);
+ $dbh->do("truncate table $table") || die "Got error on truncate: $DBI::errstr\n";
+ }
+ $dbh->disconnect; $dbh=0;
+ print "Test_truncate: Run $count times\n";
+ exit(0);
+}
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 00000000000..3c786dc9281
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,10 @@
+INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include \
+ $(openssl_includes) -I../include
+LDADD= @CLIENT_EXTRA_LDFLAGS@ ../libmysql_r/libmysqlclient_r.la @openssl_libs@
+bin_PROGRAMS= mysqlmanager
+mysqlmanager_SOURCES= mysqlmanager.c
+mysqlmanager_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
+DEF= -DUNDEF_THREADS_HACK
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/tools/managertest1.nc b/tools/managertest1.nc
new file mode 100644
index 00000000000..bf1b82ed406
--- /dev/null
+++ b/tools/managertest1.nc
@@ -0,0 +1,16 @@
+def_exec server /usr/sbin/mysqld --socket=/tmp/temp.sock --skip-grant --skip-net --datadir=/tmp
+set_exec_con server root localhost /tmp/temp.sock
+set_exec_stdout server /tmp/mysqld.err
+set_exec_stderr server /tmp/mysqld.err
+start_exec server 3
+show_exec
+query server show variables like '%max_heap%';
+stop_exec server 3
+def_exec server /usr/sbin/mysqld --socket=/tmp/temp.sock --skip-grant --skip-net --datadir=/tmp -O max_heap_table_size=5000
+show_exec
+start_exec server 3
+query server show variables like '%max_heap%';
+show_exec
+stop_exec server 3
+show_exec
+quit
diff --git a/tools/mysqlmanager-sample.pwd b/tools/mysqlmanager-sample.pwd
new file mode 100644
index 00000000000..51c1ade1b77
--- /dev/null
+++ b/tools/mysqlmanager-sample.pwd
@@ -0,0 +1 @@
+root:5ebe2294ecd0e0f08eab7690d2a6ee69
diff --git a/tools/mysqlmanager.c b/tools/mysqlmanager.c
new file mode 100644
index 00000000000..790a5d56b5a
--- /dev/null
+++ b/tools/mysqlmanager.c
@@ -0,0 +1,1848 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ MySQL server management daemon
+
+ Written by:
+ Sasha Pachev <sasha@mysql.com>
+*/
+
+#include <my_global.h>
+#include <my_pthread.h>
+#include <mysql.h>
+#include <mysql_version.h>
+#include <mysqld_error.h>
+#include <my_sys.h>
+#include <my_dir.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include <hash.h>
+#include <my_getopt.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <violite.h>
+#include <md5.h>
+#include <signal.h>
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#define MANAGER_VERSION "1.2"
+#define MANAGER_GREETING "MySQL Server Management Daemon v. 1.2"
+
+#define LOG_ERR 1
+#define LOG_WARN 2
+#define LOG_INFO 3
+#define LOG_DEBUG 4
+
+#define CHILD_START 1
+#define CHILD_STOP 2
+
+#ifndef MANAGER_PORT
+#define MANAGER_PORT 23546
+#endif
+
+#ifndef MANAGER_CONNECT_RETRIES
+#define MANAGER_CONNECT_RETRIES 5
+#endif
+
+#ifndef MANAGER_MAX_CMD_LEN
+#define MANAGER_MAX_CMD_LEN 16384
+#endif
+
+#ifndef MANAGER_LOG_FILE
+#define MANAGER_LOG_FILE "/var/log/mysqlmanager.log"
+#endif
+
+#ifndef MANAGER_BACK_LOG
+#define MANAGER_BACK_LOG 50
+#endif
+
+#ifndef MAX_USER_NAME
+#define MAX_USER_NAME 16
+#endif
+
+#ifndef MANAGER_PW_FILE
+#define MANAGER_PW_FILE "/etc/mysqlmanager.passwd"
+#endif
+
+#ifndef MAX_HOST
+#define MAX_HOST 128
+#endif
+
+#ifndef MAX_LAUNCHER_MSG
+#define MAX_LAUNCHER_MSG 256
+#endif
+
+#define MAX_RETRY_COUNT 100
+
+/*
+ Variable naming convention - if starts with manager_, either is set
+ directly by the user, or used closely in ocnjunction with a variable
+ set by the user
+*/
+
+#if defined(__i386__) && defined(HAVE_LINUXTHREADS)
+#define DO_STACKTRACE 1
+#endif
+
+uint manager_port;
+FILE* errfp;
+const char* manager_log_file = MANAGER_LOG_FILE;
+pthread_mutex_t lock_log,lock_shutdown,lock_exec_hash,lock_launch_thd;
+pthread_cond_t cond_launch_thd;
+pthread_t loop_th,launch_msg_th;
+int manager_sock = -1;
+uchar* stack_bottom=0;
+struct sockaddr_in manager_addr;
+ulong manager_bind_addr;
+int manager_back_log;
+int in_shutdown = 0, shutdown_requested=0;
+int manager_connect_retries;
+const char* manager_greeting = MANAGER_GREETING;
+uint manager_max_cmd_len;
+const char* manager_pw_file=MANAGER_PW_FILE;
+my_bool one_thread; /* for debugging */
+
+typedef enum {PARAM_STDOUT,PARAM_STDERR} PARAM_TYPE;
+
+/* messages */
+
+#define MAX_CLIENT_MSG_LEN 256
+#define NET_BLOCK 2048
+#define MD5_LEN 16
+#define ESCAPE_CHAR '\\'
+#define EOL_CHAR '\n'
+
+/* access flags */
+
+#define PRIV_SHUTDOWN 1
+
+struct manager_thd
+{
+ NET net;
+ char user[MAX_USER_NAME+1];
+ int priv_flags;
+ char* cmd_buf;
+ int fatal,finished;
+};
+
+struct manager_user
+{
+ char user[MAX_USER_NAME+1];
+ char md5_pass[MD5_LEN];
+ int user_len;
+ const char* error;
+};
+
+HASH exec_hash,user_hash;
+struct manager_exec* cur_launch_exec=0;
+
+static struct manager_thd* manager_thd_new(Vio* vio);
+
+static struct manager_exec* manager_exec_new(char* arg_start,char* arg_end);
+static void manager_exec_print(NET* net,struct manager_exec* e);
+static void manager_thd_free(struct manager_thd* thd);
+static void manager_exec_free(void* e);
+static void manager_exec_connect(struct manager_exec* e);
+static int manager_exec_launch(struct manager_exec* e);
+static struct manager_exec* manager_exec_by_pid(pid_t pid);
+
+static struct manager_user* manager_user_new(char* buf);
+static void manager_user_free(void* u);
+
+static char* arg_strmov(char* dest, const char* src, int n);
+static byte* get_exec_key(const byte* e, uint* len,
+ my_bool __attribute__((unused)) t);
+static byte* get_user_key(const byte* u, uint* len,
+ my_bool __attribute__((unused)) t);
+static uint tokenize_args(char* arg_start,char** arg_end);
+static void init_arg_array(char* arg_str,char** args,uint arg_count);
+static int hex_val(char c);
+static int open_and_dup(int fd,char* path);
+static void update_req_len(struct manager_exec* e);
+
+typedef int (*manager_cmd_handler)(struct manager_thd*,char*,char*);
+
+static void handle_child(int __attribute__((unused)) sig);
+static void handle_sigpipe(int __attribute__((unused)) sig);
+
+/*
+ exec() in a threaded application is full of problems.
+ To solve this, we fork off a launcher at the very start
+ and communicate with it through a pipe
+*/
+
+static void fork_launcher();
+static void run_launcher_loop();
+int to_launcher_pipe[2],from_launcher_pipe[2];
+pid_t launcher_pid;
+int in_segfault=0;
+const char* pid_file = "/var/run/mysqlmanager.pid";
+int created_pid_file = 0;
+
+struct manager_cmd
+{
+ const char* name;
+ const char* help;
+ manager_cmd_handler handler_func;
+ int len;
+};
+
+struct manager_exec
+{
+ char* ident;
+ int ident_len;
+ const char* error;
+ char* bin_path;
+ char** args;
+ char con_user[16];
+ char con_pass[16];
+ int con_port;
+ pid_t pid;
+ int exit_code;
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+ pthread_t th;
+ char con_sock[FN_REFLEN];
+ char con_host[MAX_HOST];
+ char stderr_path[FN_REFLEN];
+ char stdout_path[FN_REFLEN];
+ MYSQL mysql;
+ char* data_buf;
+ int req_len;
+ int start_wait_timeout;
+ int stderr_path_size,stdout_path_size,data_buf_size;
+ int num_args;
+};
+
+static int set_exec_param(struct manager_thd* thd, char* args_start,
+ char* args_end, PARAM_TYPE param_type);
+
+#define HANDLE_DECL(com) \
+static int com(struct manager_thd* thd, char* args_start,char* args_end)
+#define HANDLE_NOARG_DECL(com) \
+static int com(struct manager_thd *thd,\
+ char *args_start __attribute__((unused)),\
+ char* args_end __attribute__((unused)))
+
+HANDLE_NOARG_DECL(handle_ping);
+HANDLE_NOARG_DECL(handle_quit);
+HANDLE_NOARG_DECL(handle_help);
+HANDLE_NOARG_DECL(handle_shutdown);
+HANDLE_DECL(handle_def_exec);
+HANDLE_DECL(handle_start_exec);
+HANDLE_DECL(handle_stop_exec);
+HANDLE_DECL(handle_set_exec_con);
+HANDLE_DECL(handle_set_exec_stdout);
+HANDLE_DECL(handle_set_exec_stderr);
+HANDLE_NOARG_DECL(handle_show_exec);
+HANDLE_DECL(handle_query);
+
+
+struct manager_cmd commands[] =
+{
+ {"ping", "Check if this server is alive", handle_ping,4},
+ {"quit", "Finish session", handle_quit,4},
+ {"shutdown", "Shutdown this server", handle_shutdown,8},
+ {"def_exec", "Define executable entry", handle_def_exec,8},
+ {"start_exec", "Launch process defined by executable entry",
+ handle_start_exec,10},
+ {"stop_exec", "Stop process defined by executable entry",
+ handle_stop_exec,9},
+ {"set_exec_con", "Set connection parameters for executable entry",
+ handle_set_exec_con,12},
+ {"set_exec_stdout", "Set stdout path for executable entry",
+ handle_set_exec_stdout,15},
+ {"set_exec_stderr", "Set stderr path for executable entry",
+ handle_set_exec_stderr,15},
+ {"query","Run query against MySQL server",handle_query,5},
+ {"show_exec","Show defined executable entries",handle_show_exec,9},
+ {"help", "Print this message", handle_help,4},
+ {0,0,0,0}
+};
+
+
+static struct my_option my_long_options[] =
+{
+#ifndef DBUG_OFF
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to listen on.", (gptr*) &manager_port,
+ (gptr*) &manager_port, 0, GET_UINT, REQUIRED_ARG, MANAGER_PORT, 0, 0, 0,
+ 0, 0},
+ {"log", 'l', "Path to log file.", (gptr*) &manager_log_file,
+ (gptr*) &manager_log_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"bind-address", 'b', "Address to listen on.", (gptr*) &manager_bind_addr,
+ (gptr*) &manager_bind_addr, 0, GET_ULONG, REQUIRED_ARG, INADDR_ANY, 0,
+ 0, 0, 0, 0},
+ {"tcp-backlog", 'B', "Size of TCP/IP listen queue.",
+ (gptr*) &manager_back_log, (gptr*) &manager_back_log, 0, GET_INT,
+ REQUIRED_ARG, MANAGER_BACK_LOG, 0, 0, 0, 0, 0},
+ {"greeting", 'g', "Set greeting on connect", (gptr*) &manager_greeting,
+ (gptr*) &manager_greeting, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"max-command-len", 'm', "Maximum command length",
+ (gptr*) &manager_max_cmd_len, (gptr*) &manager_max_cmd_len, 0, GET_UINT,
+ REQUIRED_ARG, MANAGER_MAX_CMD_LEN, 0, 0, 0, 0, 0},
+ {"one-thread", 'd', "Use one thread ( for debugging)", (gptr*) &one_thread,
+ (gptr*) &one_thread, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"connect-retries", 'C', "Number of attempts to establish MySQL connection",
+ (gptr*) &manager_connect_retries, (gptr*) &manager_connect_retries, 0,
+ GET_INT, REQUIRED_ARG, MANAGER_CONNECT_RETRIES, 0, 0, 0, 0, 0},
+ {"password-file", 'p', "Password file for manager",
+ (gptr*) &manager_pw_file, (gptr*) &manager_pw_file, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"pid-file", 'f', "Pid file to use", (gptr*) &pid_file, (gptr*) &pid_file,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+static void die(const char* fmt,...);
+static void print_time(FILE* fp);
+static void clean_up();
+static struct manager_cmd* lookup_cmd(char* s,int len);
+static int client_msg(NET* net,int err_code,const char* fmt,...);
+static int client_msg_pre(NET* net,int err_code,const char* fmt,...);
+static int client_msg_raw(NET* net,int err_code,int pre,const char* fmt,
+ va_list args);
+static int authenticate(struct manager_thd* thd);
+/* returns pointer to end of line */
+static char* read_line(struct manager_thd* thd);
+static pthread_handler_decl(process_connection, arg);
+static pthread_handler_decl(process_launcher_messages, arg);
+static int exec_line(struct manager_thd* thd,char* buf,char* buf_end);
+
+#ifdef DO_STACKTRACE
+void print_stacktrace();
+#endif
+
+static void log_msg(const char* fmt, int msg_type, va_list args);
+
+/* No 'inline' here becasue functions with ... can't do that portable */
+#define LOG_MSG_FUNC(type,TYPE) static void type \
+ (const char* fmt,...) { \
+ va_list args; \
+ va_start(args,fmt); \
+ log_msg(fmt,TYPE,args);\
+ }
+
+LOG_MSG_FUNC(log_err,LOG_ERR)
+LOG_MSG_FUNC(log_warn,LOG_WARN)
+LOG_MSG_FUNC(log_info,LOG_INFO)
+
+#ifndef DBUG_OFF
+LOG_MSG_FUNC(log_debug,LOG_DEBUG)
+#else
+void log_debug(const char* __attribute__((unused)) fmt,...) {}
+#endif
+
+static void handle_sigterm(int sig __attribute__((unused)))
+{
+ log_info("Got SIGTERM");
+ if (!one_thread)
+ {
+ kill(launcher_pid,SIGTERM);
+ pthread_kill(loop_th,SIGTERM);
+ }
+ clean_up();
+ exit(0);
+}
+
+#ifdef DO_STACKTRACE
+static void handle_segfault(int sig)
+{
+ if (in_segfault)
+ exit(1);
+ in_segfault=1;
+ fprintf(errfp,"Got fatal signal %d\n",sig);
+ print_stacktrace();
+ exit(1);
+}
+#endif
+
+static void handle_sigpipe(int __attribute__((unused)) sig)
+{
+ signal(SIGPIPE,handle_sigpipe);
+}
+
+#ifdef DO_STACKTRACE
+
+#define MAX_DEPTH 25
+#define SIGRETURN_FRAME_COUNT 1
+
+void print_stacktrace()
+{
+ uchar** fp;
+ int i;
+ LINT_INIT(fp);
+ fprintf(errfp,"Fatal errror, stacktrace follows:\n");
+#ifdef __i386__
+ __asm__ __volatile__("movl %%ebp,%0" :"=r"(fp) :"r"(fp));
+#endif
+ if (!fp)
+ {
+ fprintf(errfp,"frame points is NULL, cannot trace stack\n");
+ return;
+ }
+ for (i=0;i<MAX_DEPTH && fp<(uchar**)stack_bottom;i++)
+ {
+#ifdef __i386__
+ uchar** new_fp = (uchar**)*fp;
+ fprintf(errfp, "%p\n", i == SIGRETURN_FRAME_COUNT ?
+ *(fp+17) : *(fp+1));
+#endif /* __386__ */
+ if (new_fp <= fp )
+ {
+ fprintf(errfp, "New value of fp=%p failed sanity check,\
+ terminating stack trace!\n", new_fp);
+ return;
+ }
+ fp = new_fp;
+ }
+ fprintf(errfp,"Stack trace successful\n");
+ fflush(errfp);
+}
+#endif
+
+static int exec_line(struct manager_thd* thd,char* buf,char* buf_end)
+{
+ char* p=buf;
+ struct manager_cmd* cmd;
+ for (;p<buf_end && !isspace(*p);p++)
+ *p=tolower(*p);
+ log_info("Command '%s'", buf);
+ if (!(cmd=lookup_cmd(buf,(int)(p-buf))))
+ {
+ if (client_msg(&thd->net,MANAGER_CLIENT_ERR,
+ "Unrecognized command '%s', type help to see list of supported\
+ commands", buf))
+ thd->fatal=1;
+ return 1;
+ }
+ for (;p<buf_end && isspace(*p);p++);
+ return cmd->handler_func(thd,p,buf_end);
+}
+
+static struct manager_cmd* lookup_cmd(char* s,int len)
+{
+ struct manager_cmd* cmd = commands;
+ for (;cmd->name;cmd++)
+ {
+ if (cmd->len == len && !memcmp(cmd->name,s,len))
+ return cmd;
+ }
+ return 0;
+}
+
+HANDLE_NOARG_DECL(handle_ping)
+{
+ client_msg(&thd->net,MANAGER_OK,"Server management daemon is alive");
+ return 0;
+}
+
+HANDLE_NOARG_DECL(handle_quit)
+{
+ client_msg(&thd->net,MANAGER_OK,"Goodbye");
+ thd->finished=1;
+ return 0;
+}
+
+HANDLE_NOARG_DECL(handle_help)
+{
+ struct manager_cmd* cmd = commands;
+ NET* net = &thd->net;
+ client_msg_pre(net,MANAGER_INFO,"Available commands:");
+ for (;cmd->name;cmd++)
+ {
+ client_msg_pre(net,MANAGER_INFO,"%s - %s", cmd->name, cmd->help);
+ }
+ client_msg_pre(net,MANAGER_INFO,"End of help");
+ return 0;
+}
+
+HANDLE_NOARG_DECL(handle_shutdown)
+{
+ client_msg(&thd->net,MANAGER_OK,"Shutdown started, goodbye");
+ thd->finished=1;
+ shutdown_requested = 1;
+ if (!one_thread)
+ {
+ kill(launcher_pid,SIGTERM);
+ pthread_kill(loop_th,SIGTERM);
+ }
+ return 0;
+}
+
+HANDLE_DECL(handle_set_exec_con)
+{
+ int num_args;
+ const char* error=0;
+ struct manager_exec* e;
+ char* arg_p;
+ if ((num_args=tokenize_args(args_start,&args_end))<2)
+ {
+ error="Too few arguments";
+ goto err;
+ }
+ arg_p=args_start;
+ pthread_mutex_lock(&lock_exec_hash);
+ if (!(e=(struct manager_exec*)hash_search(&exec_hash,arg_p,
+ strlen(arg_p))))
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Exec definition entry does not exist";
+ goto err;
+ }
+ arg_p+=strlen(arg_p)+1;
+ arg_p+=(strnmov(e->con_user,arg_p,sizeof(e->con_user))-e->con_user)+1;
+ if (num_args >= 3)
+ {
+ arg_p+=(strnmov(e->con_host,arg_p,sizeof(e->con_host))-e->con_host)+1;
+ if (num_args == 4)
+ {
+ if (!(e->con_port=atoi(arg_p)))
+ strnmov(e->con_sock,arg_p,sizeof(e->con_sock));
+ else
+ e->con_sock[0]=0;
+ }
+ else if (num_args > 4)
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Too many arguments";
+ goto err;
+ }
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ client_msg(&thd->net,MANAGER_OK,"Entry updated");
+ return 0;
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ return 1;
+}
+
+HANDLE_DECL(handle_set_exec_stdout)
+{
+ return set_exec_param(thd,args_start,args_end,PARAM_STDOUT);
+}
+
+HANDLE_DECL(handle_set_exec_stderr)
+{
+ return set_exec_param(thd,args_start,args_end,PARAM_STDERR);
+}
+
+static int set_exec_param(struct manager_thd* thd, char* args_start,
+ char* args_end, PARAM_TYPE param_type)
+{
+ int num_args;
+ const char* error=0;
+ struct manager_exec* e;
+ char* arg_p;
+ char* param;
+ int param_size;
+
+ if ((num_args=tokenize_args(args_start,&args_end))<2)
+ {
+ error="Too few arguments";
+ goto err;
+ }
+ arg_p=args_start;
+ pthread_mutex_lock(&lock_exec_hash);
+ if (!(e=(struct manager_exec*)hash_search(&exec_hash,arg_p,
+ strlen(arg_p))))
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Exec definition entry does not exist";
+ goto err;
+ }
+ arg_p+=strlen(arg_p)+1;
+ param_size=strlen(arg_p)+1;
+ switch (param_type) {
+ case PARAM_STDOUT:
+ param=e->stdout_path;
+ e->req_len+=(param_size-e->stdout_path_size);
+ e->stdout_path_size=param_size;
+ break;
+ case PARAM_STDERR:
+ param=e->stderr_path;
+ e->req_len+=(param_size-e->stderr_path_size);
+ e->stderr_path_size=param_size;
+ break;
+ default:
+ error="Internal error";
+ goto err;
+ }
+ strnmov(param,arg_p,FN_REFLEN);
+ pthread_mutex_unlock(&lock_exec_hash);
+ client_msg(&thd->net,MANAGER_OK,"Entry updated");
+ return 0;
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ return 1;
+}
+
+
+HANDLE_DECL(handle_start_exec)
+{
+ int num_args;
+ struct manager_exec* e;
+ int ident_len;
+ const char* error=0;
+ struct timespec t;
+ if ((num_args=tokenize_args(args_start,&args_end))<1)
+ {
+ error="Too few arguments";
+ goto err;
+ }
+ ident_len=strlen(args_start);
+ pthread_mutex_lock(&lock_exec_hash);
+ if (!(e=(struct manager_exec*)hash_search(&exec_hash,args_start,
+ ident_len)))
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Exec definition entry does not exist";
+ goto err;
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ manager_exec_launch(e);
+ if ((error=e->error))
+ goto err;
+ pthread_mutex_lock(&e->lock);
+ t.tv_sec=time(0)+(e->start_wait_timeout=atoi(args_start+ident_len+1));
+ t.tv_nsec=0;
+ if (!e->pid)
+ pthread_cond_timedwait(&e->cond,&e->lock,&t);
+ if (!e->pid)
+ {
+ pthread_mutex_unlock(&e->lock);
+ error="Process failed to start withing alotted time";
+ goto err;
+ }
+ mysql_close(&e->mysql);
+ manager_exec_connect(e);
+ error=e->error;
+ pthread_mutex_unlock(&e->lock);
+ if (error)
+ goto err;
+ client_msg(&thd->net,MANAGER_OK,"'%s' started",e->ident);
+ return 0;
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ return 1;
+}
+
+HANDLE_DECL(handle_stop_exec)
+{
+ int num_args;
+ struct timespec abstime;
+ struct manager_exec* e;
+ int ident_len;
+ const char* error=0;
+ if ((num_args=tokenize_args(args_start,&args_end))<2)
+ {
+ error="Too few arguments";
+ goto err;
+ }
+ ident_len=strlen(args_start);
+ abstime.tv_sec=time(0)+atoi(args_start+1+ident_len);
+ abstime.tv_nsec=0;
+ pthread_mutex_lock(&lock_exec_hash);
+ if (!(e=(struct manager_exec*)hash_search(&exec_hash,args_start,
+ ident_len)))
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Exec definition entry does not exist";
+ goto err;
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ pthread_mutex_lock(&e->lock);
+ e->th=pthread_self();
+ if (!e->pid)
+ {
+ /* e->th=0; */ /* th may be a struct */
+ pthread_mutex_unlock(&e->lock);
+ error="Process not running";
+ goto err;
+ }
+ if (mysql_shutdown(&e->mysql))
+ {
+ /* e->th=0; */ /* th may be a struct */
+ pthread_mutex_unlock(&e->lock);
+ error="Could not send shutdown command";
+ goto err;
+ }
+ if (e->pid)
+ pthread_cond_timedwait(&e->cond,&e->lock,&abstime);
+ if (e->pid)
+ error="Process failed to terminate within alotted time";
+ /* e->th=0; */ /* th may be a struct */
+ pthread_mutex_unlock(&e->lock);
+ if (!error)
+ {
+ client_msg(&thd->net,MANAGER_OK,"'%s' terminated",e->ident);
+ return 0;
+ }
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ return 1;
+}
+
+HANDLE_DECL(handle_query)
+{
+ const char* error=0;
+ struct manager_exec* e;
+ MYSQL_RES* res=0;
+ MYSQL_ROW row;
+ MYSQL_FIELD* fields;
+ int num_fields,i,ident_len;
+ char* ident,*query;
+ query=ident=args_start;
+ while (!isspace(*query))
+ query++;
+ if (query == ident)
+ {
+ error="Missing server identifier";
+ goto err;
+ }
+ ident_len=(int)(query-ident);
+ while (query<args_end && isspace(*query))
+ query++;
+ if (query == args_end)
+ {
+ error="Missing query";
+ goto err;
+ }
+ pthread_mutex_lock(&lock_exec_hash);
+ if (!(e=(struct manager_exec*)hash_search(&exec_hash,ident,
+ ident_len)))
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ error="Exec definition entry does not exist";
+ goto err;
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ pthread_mutex_lock(&e->lock);
+ if (!e->pid)
+ {
+ error="Process is not running";
+ pthread_mutex_unlock(&e->lock);
+ goto err;
+ }
+
+ if (mysql_query(&e->mysql,query))
+ {
+ error=mysql_error(&e->mysql);
+ pthread_mutex_unlock(&e->lock);
+ goto err;
+ }
+ if ((res=mysql_store_result(&e->mysql)))
+ {
+ char buf[MAX_CLIENT_MSG_LEN],*p,*buf_end;
+ fields=mysql_fetch_fields(res);
+ num_fields=mysql_num_fields(res);
+ p=buf;
+ buf_end=buf+sizeof(buf);
+ for (i=0;i<num_fields && p<buf_end-2;i++)
+ {
+ p=arg_strmov(p,fields[i].name,buf_end-p-2);
+ *p++='\t';
+ }
+ *p=0;
+ client_msg_pre(&thd->net,MANAGER_OK,buf);
+
+ while ((row=mysql_fetch_row(res)))
+ {
+ p=buf;
+ for (i=0;i<num_fields && p<buf_end-2;i++)
+ {
+ p=arg_strmov(p,row[i],buf_end-p-2);
+ *p++='\t';
+ }
+ *p=0;
+ client_msg_pre(&thd->net,MANAGER_OK,buf);
+ }
+ }
+ pthread_mutex_unlock(&e->lock);
+ client_msg(&thd->net,MANAGER_OK,"End");
+ return 0;
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ return 1;
+}
+
+HANDLE_DECL(handle_def_exec)
+{
+ struct manager_exec* e=0,*old_e;
+ const char* error=0;
+ if (!(e=manager_exec_new(args_start,args_end)))
+ {
+ error="Out of memory";
+ goto err;
+ }
+ if (e->error)
+ {
+ error=e->error;
+ goto err;
+ }
+ pthread_mutex_lock(&lock_exec_hash);
+ if ((old_e=(struct manager_exec*)hash_search(&exec_hash,(byte*)e->ident,
+ e->ident_len)))
+ {
+ strnmov(e->stdout_path,old_e->stdout_path,sizeof(e->stdout_path));
+ strnmov(e->stderr_path,old_e->stderr_path,sizeof(e->stderr_path));
+ strnmov(e->con_user,old_e->con_user,sizeof(e->con_user));
+ strnmov(e->con_host,old_e->con_host,sizeof(e->con_host));
+ strnmov(e->con_sock,old_e->con_sock,sizeof(e->con_sock));
+ e->con_port=old_e->con_port;
+ update_req_len(e);
+ hash_delete(&exec_hash,(byte*)old_e);
+ }
+ hash_insert(&exec_hash,(byte*)e);
+ pthread_mutex_unlock(&lock_exec_hash);
+ client_msg(&thd->net,MANAGER_OK,"Exec definition created");
+ return 0;
+err:
+ client_msg(&thd->net,MANAGER_CLIENT_ERR,error);
+ if (e)
+ manager_exec_free(e);
+ return 1;
+}
+
+HANDLE_NOARG_DECL(handle_show_exec)
+{
+ uint i;
+ client_msg_pre(&thd->net,MANAGER_INFO,"Exec_def\tPid\tExit_status\tCon_info\
+\tStdout\tStderr\tArguments");
+ pthread_mutex_lock(&lock_exec_hash);
+ for (i=0;i<exec_hash.records;i++)
+ {
+ struct manager_exec* e=(struct manager_exec*)hash_element(&exec_hash,i);
+ manager_exec_print(&thd->net,e);
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ client_msg(&thd->net,MANAGER_INFO,"End");
+ return 0;
+}
+
+static struct manager_exec* manager_exec_by_pid(pid_t pid)
+{
+ struct manager_exec* e;
+ uint i;
+ pthread_mutex_lock(&lock_exec_hash);
+ for (i=0;i<exec_hash.records;i++)
+ {
+ e=(struct manager_exec*)hash_element(&exec_hash,i);
+ if (e->pid==pid)
+ {
+ pthread_mutex_unlock(&lock_exec_hash);
+ return e;
+ }
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ return 0;
+}
+
+static void manager_exec_connect(struct manager_exec* e)
+{
+ int i;
+ int connect_retries;
+
+ if (!(connect_retries=e->start_wait_timeout))
+ connect_retries=manager_connect_retries;
+
+ for (i=0;i<connect_retries;i++)
+ {
+ if (mysql_real_connect(&e->mysql,e->con_host,e->con_user,e->con_pass,0,
+ e->con_port,e->con_sock,0))
+ return;
+ sleep(1);
+ }
+ e->error="Could not connect to MySQL server withing the number of tries";
+}
+
+static int manager_exec_launch(struct manager_exec* e)
+{
+ if (one_thread)
+ {
+ pid_t tmp_pid;
+ switch ((tmp_pid=fork())) {
+ case -1:
+ e->error="Cannot fork";
+ return 1;
+ case 0:
+ {
+ int err_code;
+ close(manager_sock);
+ err_code=execv(e->bin_path,e->args);
+ exit(err_code);
+ }
+ default:
+ e->pid=tmp_pid;
+ manager_exec_connect(e);
+ return 0;
+ }
+ }
+ else
+ {
+ if (my_write(to_launcher_pipe[1],(byte*)&e->req_len,
+ sizeof(int),MYF(MY_NABP))||
+ my_write(to_launcher_pipe[1],(byte*)&e->num_args,
+ sizeof(int),MYF(MY_NABP)) ||
+ my_write(to_launcher_pipe[1],e->stdout_path,e->stdout_path_size,
+ MYF(MY_NABP)) ||
+ my_write(to_launcher_pipe[1],e->stderr_path,e->stderr_path_size,
+ MYF(MY_NABP)) ||
+ my_write(to_launcher_pipe[1],e->data_buf,e->data_buf_size,
+ MYF(MY_NABP)))
+ {
+ e->error="Failed write request to launcher";
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static char* arg_strmov(char* dest, const char* src, int n)
+{
+ char* dest_end = dest+n-1;
+ char c;
+ for (;dest<dest_end && (c=*src++);)
+ {
+ if (c=='%')
+ *dest++='%';
+ *dest++=c;
+ }
+ return dest;
+}
+
+static void manager_exec_print(NET* net,struct manager_exec* e)
+{
+ char buf[MAX_MYSQL_MANAGER_MSG];
+ char* p=buf,*buf_end=buf+sizeof(buf)-1;
+ char** args=e->args;
+
+ p=arg_strmov(p,e->ident,(int)(buf_end-p)-1);
+ *p++='\t';
+ if (p>buf_end-15)
+ goto end;
+ p=int10_to_str(e->pid,p,10);
+ *p++='\t';
+ p=int10_to_str(e->exit_code,p,10);
+ *p++='\t';
+
+ p=arg_strmov(p,e->con_user,(int)(buf_end-p)-1);
+ *p++='@';
+ if (p==buf_end)
+ goto end;
+ p=arg_strmov(p,e->con_host,(int)(buf_end-p)-11);
+ *p++=':';
+ if (p==buf_end-10)
+ goto end;
+ if (e->con_sock[0])
+ {
+ p=arg_strmov(p,e->con_sock,(int)(buf_end-p)-1);
+ }
+ else
+ {
+ p=int10_to_str(e->con_port,p,10);
+ }
+ *p++='\t';
+ p=arg_strmov(p,e->stdout_path,(int)(buf_end-p)-1);
+ if (p==buf_end-1)
+ goto end;
+ *p++='\t';
+ p=arg_strmov(p,e->stderr_path,(int)(buf_end-p)-1);
+ if (p==buf_end-1)
+ goto end;
+ *p++='\t';
+
+ for (;p<buf_end && *args;args++)
+ {
+ p=arg_strmov(p,*args,(int)(buf_end-p)-1);
+ *p++='\t';
+ }
+end:
+ *p=0;
+ client_msg_pre(net,MANAGER_INFO,buf);
+ return;
+}
+
+static int authenticate(struct manager_thd* thd)
+{
+ char* buf_end,*buf,*p,*p_end;
+ my_MD5_CTX context;
+ uchar digest[MD5_LEN];
+ struct manager_user* u;
+ char c;
+
+ client_msg(&thd->net,MANAGER_INFO, manager_greeting);
+ if (!(buf_end=read_line(thd)))
+ return -1;
+ for (buf=thd->cmd_buf,p=thd->user,p_end=p+MAX_USER_NAME;
+ buf<buf_end && (c=*buf) && p<p_end; buf++,p++)
+ {
+ if (isspace(c))
+ {
+ *p=0;
+ break;
+ }
+ else
+ *p=c;
+ }
+ if (p==p_end || buf==buf_end)
+ return 1;
+ if (!(u=(struct manager_user*)hash_search(&user_hash,thd->user,
+ (uint)(p-thd->user))))
+ return 1;
+ for (;isspace(*buf) && buf<buf_end;buf++) /* empty */;
+
+ my_MD5Init(&context);
+ my_MD5Update(&context,(uchar*) buf,(uint)(buf_end-buf));
+ my_MD5Final(digest,&context);
+ if (memcmp(u->md5_pass,digest,MD5_LEN))
+ return 1;
+ client_msg(&thd->net,MANAGER_OK,"OK");
+ return 0;
+}
+
+static void print_time(FILE* fp)
+{
+ struct tm now;
+ time_t t;
+ time(&t);
+ localtime_r(&t,&now);
+ fprintf(fp,"[%d-%02d-%02d %02d:%02d:%02d] ", now.tm_year+1900,
+ now.tm_mon+1,now.tm_mday,now.tm_hour,now.tm_min,
+ now.tm_sec);
+}
+
+static void die(const char* fmt, ...)
+{
+ va_list args;
+ va_start(args,fmt);
+ if (fmt)
+ {
+ if (errfp==stderr)
+ fprintf(errfp, "%s: ", my_progname);
+ else
+ {
+ print_time(errfp);
+ fprintf(errfp,"Fatal error: ");
+ }
+ vfprintf(errfp, fmt, args);
+ if (errno)
+ fprintf(errfp, " errno=%d", errno);
+ fprintf(errfp, "\n");
+ fflush(errfp);
+ }
+ va_end(args);
+ clean_up();
+ exit(1);
+}
+
+void print_msg_type(int msg_type)
+{
+ const char* msg;
+ switch (msg_type) {
+ case LOG_ERR: msg = "ERROR"; break;
+ case LOG_WARN: msg = "WARNING"; break;
+ case LOG_INFO: msg = "INFO"; break;
+#ifndef DBUG_OFF
+ case LOG_DEBUG: msg = "DEBUG"; break;
+#endif
+ default: msg = "UNKNOWN TYPE"; break;
+ }
+ fprintf(errfp," %s: ", msg);
+}
+
+static void log_msg(const char* fmt, int msg_type, va_list args)
+{
+ pthread_mutex_lock(&lock_log);
+ print_time(errfp);
+ print_msg_type(msg_type);
+ vfprintf(errfp,fmt,args);
+ fputc('\n',errfp);
+ fflush(errfp);
+ pthread_mutex_unlock(&lock_log);
+}
+
+static pthread_handler_decl(process_launcher_messages,
+ args __attribute__((unused)))
+{
+ my_thread_init();
+ for (;!in_shutdown;)
+ {
+ pid_t pid;
+ struct manager_exec* e;
+ char buf[MAX_LAUNCHER_MSG];
+ if (read(from_launcher_pipe[0],buf,MAX_LAUNCHER_MSG)<0)
+ {
+ log_err("error reading launcher message");
+ sleep(1);
+ continue;
+ }
+ switch (buf[0]) {
+ case CHILD_START:
+ {
+ char* ident=buf+1;
+ int ident_len=strlen(ident);
+ memcpy(&pid,ident+ident_len+1,sizeof(pid));
+ log_debug("process message - ident=%s ident_len=%d pid=%d",ident,
+ ident_len,pid);
+ pthread_mutex_lock(&lock_exec_hash);
+ log_debug("hash has %d records",exec_hash.records);
+ e=(struct manager_exec*)hash_search(&exec_hash,ident,ident_len);
+ if (e)
+ {
+ pthread_mutex_lock(&e->lock);
+ e->pid=pid;
+ pthread_cond_broadcast(&e->cond);
+ pthread_mutex_unlock(&e->lock);
+ }
+ pthread_mutex_unlock(&lock_exec_hash);
+ log_debug("unlocked mutex");
+ break;
+ }
+ case CHILD_STOP:
+ memcpy(&pid,buf+1,sizeof(pid));
+ e=manager_exec_by_pid(pid);
+ if (e)
+ {
+ pthread_mutex_lock(&e->lock);
+ e->pid=0;
+ memcpy(&e->exit_code,buf+1+sizeof(pid),sizeof(int));
+ pthread_cond_broadcast(&e->cond);
+ pthread_mutex_unlock(&e->lock);
+ }
+ break;
+ default:
+ log_err("Got invalid launcher message");
+ break;
+ }
+ }
+ return 0;
+}
+
+static pthread_handler_decl(process_connection,arg)
+{
+ struct manager_thd* thd = (struct manager_thd*)arg;
+ my_thread_init();
+ pthread_detach_this_thread();
+ for (;!thd->finished;)
+ {
+ char* buf_end;
+ if ((!(buf_end=read_line(thd)) || exec_line(thd,thd->cmd_buf,buf_end))
+ && thd->fatal)
+ {
+ log_err("Thread aborted");
+ break;
+ }
+ }
+ manager_thd_free(thd);
+ pthread_exit(0);
+ return 0; /* Don't get cc warning */
+}
+
+static int client_msg_raw(NET* net, int err_code, int pre, const char* fmt,
+ va_list args)
+{
+ char buf[MAX_CLIENT_MSG_LEN],*p,*buf_end;
+ p=buf;
+ buf_end=buf+sizeof(buf);
+ p=int10_to_str(err_code,p,10);
+ if (pre)
+ *p++='-';
+ *p++=' ';
+ p+=my_vsnprintf(p,buf_end-p,fmt,args);
+ if (p>buf_end-2)
+ p=buf_end - 2;
+ *p++='\r';
+ *p++='\n';
+ log_debug("message to client: %-.*s",p-buf-2,buf);
+ if (my_net_write(net,buf,(uint)(p-buf)) || net_flush(net))
+ {
+ p[-2]=0;
+ log_err("Failed writing '%s' to client: errno=%d",buf,errno);
+ net_end(net);
+ return 1;
+ }
+ return 0;
+}
+
+static int client_msg(NET* net, int err_code, const char* fmt, ...)
+{
+ va_list args;
+ va_start(args,fmt);
+ return client_msg_raw(net,err_code,0,fmt,args);
+}
+
+static int client_msg_pre(NET* net, int err_code, const char* fmt, ...)
+{
+ va_list args;
+ va_start(args,fmt);
+ return client_msg_raw(net,err_code,1,fmt,args);
+}
+
+static char* read_line(struct manager_thd* thd)
+{
+ int len;
+ char* p, *buf_end;
+ if ((len=my_net_read(&thd->net)) == (int)packet_error || !len)
+ {
+ log_err("Error reading command from client (Error: %d)",
+ errno);
+ thd->fatal=1;
+ return 0;
+ }
+ buf_end=thd->cmd_buf+len;
+ for (p=thd->cmd_buf;p<buf_end;p++)
+ if (*p == '\r' || *p == '\n')
+ {
+ *p=0;
+ break;
+ }
+
+ return p;
+}
+
+static void handle_child(int __attribute__((unused)) sig)
+{
+ pid_t child;
+ int child_status;
+
+ for (;(child=waitpid(-1,&child_status,WNOHANG))>0;)
+ {
+ char msg_buf[1+sizeof(int)+sizeof(int)];
+ msg_buf[0]=CHILD_STOP;
+ memcpy(msg_buf+1,&child,sizeof(int));
+ memcpy(msg_buf+1+sizeof(int),&child_status,sizeof(int));
+ if (write(from_launcher_pipe[1],msg_buf,sizeof(msg_buf))!=sizeof(msg_buf))
+ log_err("launcher: error writing message on child exit");
+ }
+ signal(SIGCHLD,handle_child);
+}
+
+static struct manager_thd* manager_thd_new(Vio* vio)
+{
+ struct manager_thd* tmp;
+ if (!(tmp=(struct manager_thd*)my_malloc(sizeof(*tmp),
+ MYF(0))))
+ {
+ log_err("Out of memory in manager_thd_new");
+ return 0;
+ }
+ my_net_init(&tmp->net,vio);
+ tmp->user[0]=0;
+ tmp->priv_flags=0;
+ tmp->fatal=tmp->finished=0;
+ tmp->cmd_buf= (char*) tmp->net.read_pos;
+ return tmp;
+}
+
+static void manager_thd_free(struct manager_thd* thd)
+{
+ NET* net=&thd->net;
+ if (net->vio)
+ {
+ vio_delete(net->vio);
+ net->vio=0;
+ }
+ net_end(&thd->net);
+}
+
+static void clean_up()
+{
+ pthread_mutex_lock(&lock_shutdown);
+ if (in_shutdown)
+ {
+ pthread_mutex_unlock(&lock_shutdown);
+ return;
+ }
+ in_shutdown = 1;
+ pthread_mutex_unlock(&lock_shutdown);
+ log_info("Shutdown started");
+ if (manager_sock)
+ close(manager_sock);
+ log_info("Ended");
+ if (errfp != stderr)
+ my_fclose(errfp, MYF(0));
+ hash_free(&exec_hash);
+ if (created_pid_file)
+ my_delete(pid_file, MYF(0));
+}
+
+static void print_version(void)
+{
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,MANAGER_VERSION,
+ MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+
+static void usage()
+{
+ print_version();
+ printf("MySQL AB, by Sasha\n");
+ printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
+ printf("Manages instances of MySQL server.\n\n");
+ printf("Usage: %s [OPTIONS]\n\n", my_progname);
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case '#':
+ DBUG_PUSH(argument ? argument : "d:t:O,/tmp/mysqlmgrd.trace");
+ break;
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ usage();
+ exit(0);
+ }
+ return 0;
+}
+
+
+static int parse_args(int argc, char **argv)
+{
+ int ho_error;
+
+ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ return 0;
+}
+
+static int init_server()
+{
+ int arg=1;
+ log_info("Started");
+ if ((manager_sock=socket(PF_INET,SOCK_STREAM,0)) < 0)
+ die("Could not create socket");
+ bzero((char*) &manager_addr, sizeof(manager_addr));
+ manager_addr.sin_family = AF_INET;
+ manager_addr.sin_addr.s_addr = manager_bind_addr;
+ manager_addr.sin_port = htons(manager_port);
+ setsockopt(manager_sock,SOL_SOCKET, SO_REUSEADDR,(char*)&arg,sizeof(arg));
+ if (bind(manager_sock,(struct sockaddr*)&manager_addr, sizeof(manager_addr))
+ < 0)
+ die("Could not bind");
+ if (listen(manager_sock,manager_back_log) < 0)
+ die("Could not listen");
+
+ return 0;
+}
+
+static int run_server_loop()
+{
+ pthread_t th;
+ struct manager_thd *thd;
+ int client_sock;
+ Vio* vio;
+ pthread_attr_t thr_attr;
+ (void) pthread_attr_init(&thr_attr);
+#if !defined(HAVE_DEC_3_2_THREADS)
+ pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
+ (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
+#endif
+
+ for (;!shutdown_requested;)
+ {
+ size_socket len=sizeof(struct sockaddr_in);
+ if ((client_sock=accept(manager_sock,(struct sockaddr*)&manager_addr,
+ &len)) <0)
+ {
+ if (shutdown_requested)
+ break;
+ if (errno != EAGAIN)
+ {
+ log_warn("Error in accept, errno=%d", errno);
+ sleep(1); /* avoid tying up CPU if accept is broken */
+ }
+ continue;
+ }
+ if (shutdown_requested)
+ break;
+ if (!(vio=vio_new(client_sock,VIO_TYPE_TCPIP,FALSE)))
+ {
+ log_err("Could not create I/O object");
+ close(client_sock);
+ continue;
+ }
+ if (!(thd=manager_thd_new(vio)))
+ {
+ log_err("Could not create thread object");
+ vio_close(vio);
+ continue;
+ }
+ if (authenticate(thd))
+ {
+ client_msg(&thd->net,MANAGER_ACCESS, "Access denied");
+ manager_thd_free(thd);
+ log_info("Client failed to authenticate");
+ continue;
+ }
+ if (shutdown_requested)
+ {
+ manager_thd_free(thd);
+ break;
+ }
+ if (one_thread)
+ {
+ process_connection((void*)thd);
+ manager_thd_free(thd);
+ continue;
+ }
+ else if (pthread_create(&th,&thr_attr,process_connection,(void*)thd))
+ {
+ client_msg(&thd->net,MANAGER_INTERNAL_ERR,
+ "Could not create thread, errno=%d",
+ errno);
+ manager_thd_free(thd);
+ continue;
+ }
+ }
+ (void) pthread_attr_destroy(&thr_attr);
+ return 0;
+}
+
+static FILE* open_log_stream()
+{
+ FILE* fp;
+ if (!(fp=my_fopen(manager_log_file, O_APPEND | FILE_BINARY, MYF(MY_WME))))
+ {
+ clean_up();
+ exit(1);
+ }
+ return fp;
+}
+
+static byte* get_user_key(const byte* u, uint* len,
+ my_bool __attribute__((unused)) t)
+{
+ register const char* key;
+ key = ((struct manager_user*)u)->user;
+ *len = ((struct manager_user*)u)->user_len;
+ return (byte*)key;
+}
+
+static byte* get_exec_key(const byte* e, uint* len,
+ my_bool __attribute__((unused)) t)
+{
+ register const char* key;
+ key = ((struct manager_exec*)e)->ident;
+ *len = ((struct manager_exec*)e)->ident_len;
+ return (byte*)key;
+}
+
+static void init_arg_array(char* arg_str,char** args,uint arg_count)
+{
+ char* p = arg_str;
+ for (;arg_count>0;arg_count--)
+ {
+ *args++=p;
+ p += strlen(p)+1;
+ }
+ *args=0;
+}
+
+static uint tokenize_args(char* arg_start,char** arg_end)
+{
+ char* p, *p_write,*p_end;
+ uint arg_count=0;
+ int quoted=0,escaped=0,last_space=0;
+ p_end=*arg_end;
+ p_write=p=arg_start;
+ for (; p < p_end ; p++)
+ {
+ char c = *p;
+ switch (c) {
+ case ' ':
+ case '\r':
+ case '\n':
+ if (!quoted)
+ {
+ if (!last_space)
+ {
+ *p_write++=0;
+ arg_count++;
+ last_space=1;
+ }
+ }
+ else
+ *p_write++=c;
+ escaped=0;
+ break;
+ case '"':
+ if (!escaped)
+ quoted=!quoted;
+ else
+ *p_write++=c;
+ last_space=0;
+ escaped=0;
+ break;
+ case '\\':
+ if (!escaped)
+ escaped=1;
+ else
+ {
+ *p_write++=c;
+ escaped=0;
+ }
+ last_space=0;
+ break;
+ default:
+ escaped=last_space=0;
+ *p_write++=c;
+ break;
+ }
+ }
+ if (!last_space && p_write>arg_start)
+ arg_count++;
+ *p_write=0;
+ *arg_end=p_write;
+ log_debug("arg_count: %d arg_start: '%s'",arg_count,arg_start);
+ return arg_count;
+}
+
+static void update_req_len(struct manager_exec* e)
+{
+ e->req_len=(e->data_buf_size+
+ (e->stdout_path_size=strlen(e->stdout_path)+1)+
+ (e->stderr_path_size=strlen(e->stderr_path)+1));
+}
+
+static struct manager_exec* manager_exec_new(char* arg_start,char* arg_end)
+{
+ struct manager_exec* tmp;
+ char* first_arg;
+ uint arg_len,num_args;
+ num_args=tokenize_args(arg_start,&arg_end);
+ arg_len=(uint)(arg_end-arg_start)+1; /* include \0 terminator*/
+ if (!(tmp=(struct manager_exec*)my_malloc(sizeof(*tmp)+arg_len+
+ sizeof(char*)*num_args,
+ MYF(MY_ZEROFILL))))
+ return 0;
+ if (num_args<2)
+ {
+ tmp->error="Too few arguments";
+ return tmp;
+ }
+ /* We have to allocate 'args' first as this must be alligned */
+ tmp->args=(char**)(tmp +1);
+ tmp->data_buf= (char*) (tmp->args + num_args);
+ memcpy(tmp->data_buf,arg_start,arg_len);
+ tmp->data_buf_size=arg_len;
+ tmp->num_args=num_args;
+ tmp->ident=tmp->data_buf;
+ tmp->ident_len=strlen(tmp->ident);
+ first_arg=tmp->ident+tmp->ident_len+1;
+ init_arg_array(first_arg,tmp->args,num_args-1);
+ strmov(tmp->con_user,"root");
+ tmp->con_port=MYSQL_PORT;
+ memcpy(tmp->con_host,"localhost",10);
+ tmp->bin_path=tmp->args[0];
+ tmp->stdout_path_size=tmp->stderr_path_size=1;
+ tmp->req_len=tmp->data_buf_size+2;
+ pthread_mutex_init(&tmp->lock,0);
+ pthread_cond_init(&tmp->cond,0);
+ mysql_init(&tmp->mysql);
+ return tmp;
+}
+
+static void manager_exec_free(void* e)
+{
+ mysql_close(&((struct manager_exec*)e)->mysql);
+ my_free(e,MYF(0));
+}
+
+static int hex_val(char c)
+{
+ if (isdigit(c))
+ return c-'0';
+ c=tolower(c);
+ return c-'a'+10;
+}
+
+static struct manager_user* manager_user_new(char* buf)
+{
+ struct manager_user* tmp;
+ char* p,*user_end,*p_end;
+ char c;
+ if (!(tmp=(struct manager_user*)my_malloc(sizeof(*tmp),MYF(0))))
+ return 0;
+ p=tmp->user;
+ tmp->error=0;
+ user_end=p+MAX_USER_NAME;
+ for (;(c=*buf) && p<user_end;buf++)
+ {
+ if (c == ':')
+ {
+ *p=0;
+ tmp->user_len=p-tmp->user;
+ buf++;
+ break;
+ }
+ else
+ *p++=c;
+ }
+ if (!c)
+ tmp->error="Missing ':'";
+ if (p == user_end)
+ tmp->error="Username too long";
+ if (tmp->error)
+ return tmp;
+ if (strlen(buf) < 2*MD5_LEN)
+ {
+ tmp->error="Invalid MD5 sum, too short";
+ return tmp;
+ }
+ p=tmp->md5_pass;
+ p_end=p+MD5_LEN;
+ for (; p<p_end;p++,buf+=2)
+ {
+ *p=hex_val(*buf)*16+hex_val(buf[1]);
+ }
+
+ return tmp;
+}
+
+static void manager_user_free(void* u)
+{
+ my_free((gptr)u,MYF(0));
+}
+
+static void init_user_hash()
+{
+ FILE* f;
+ char buf[80];
+ int line_num=1;
+ if (hash_init(&user_hash,1024,0,0,get_user_key,manager_user_free,MYF(0)))
+ die("Could not initialize user hash");
+ if (!(f=my_fopen(manager_pw_file, O_RDONLY | O_BINARY, MYF(MY_WME))))
+ {
+ clean_up();
+ exit(1);
+ }
+ for (;;line_num++)
+ {
+ struct manager_user* u;
+ if (!fgets(buf,sizeof(buf),f) || feof(f))
+ break;
+ if (buf[0] == '#')
+ continue;
+ if (!(u=manager_user_new(buf)))
+ die("Out of memory while reading user line");
+ if (u->error)
+ {
+ die("Error on line %d of '%s': %s",line_num,manager_pw_file, u->error);
+ }
+ else
+ {
+ hash_insert(&user_hash,(gptr)u);
+ }
+ }
+ my_fclose(f, MYF(0));
+}
+
+
+static void init_pid_file()
+{
+ FILE* fp = my_fopen(pid_file, O_WRONLY | O_BINARY, MYF(MY_WME));
+ if (!fp)
+ {
+ clean_up();
+ exit(1);
+ }
+ created_pid_file=1;
+ fprintf(fp, "%d\n", (int) getpid());
+ my_fclose(fp, MYF(0));
+}
+
+
+static void init_globals()
+{
+ pthread_attr_t thr_attr;
+ if (hash_init(&exec_hash,1024,0,0,get_exec_key,manager_exec_free,MYF(0)))
+ die("Exec hash initialization failed");
+ if (!one_thread)
+ {
+ (void) pthread_attr_init(&thr_attr);
+#if !defined(HAVE_DEC_3_2_THREADS)
+ pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
+ (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
+#endif
+ fork_launcher();
+ if (pthread_create(&launch_msg_th,&thr_attr,process_launcher_messages,0))
+ die("Could not start launcher message handler thread");
+ /* (void) pthread_attr_destroy(&thr_attr); */
+ }
+ init_user_hash();
+ init_pid_file();
+ loop_th=pthread_self();
+ signal(SIGPIPE,handle_sigpipe);
+ signal(SIGTERM,handle_sigterm);
+}
+
+static int open_and_dup(int fd,char* path)
+{
+ int old_fd;
+ if ((old_fd=my_open(path,O_WRONLY|O_APPEND|O_CREAT,MYF(0)))<0)
+ {
+ log_err("Could not open '%s' for append, errno=%d",path,errno);
+ return 1;
+ }
+ if (dup2(old_fd,fd)<0)
+ {
+ log_err("Failed in dup2(), errno=%d",errno);
+ return 1;
+ }
+ my_close(old_fd,MYF(0));
+ return 0;
+}
+
+static void run_launcher_loop()
+{
+ for (;;)
+ {
+ int req_len,ident_len,num_args;
+ char* request_buf=0;
+ pid_t pid;
+ char* exec_path,*ident,*stdout_path,*stderr_path;
+ char** args=0;
+
+ if (my_read(to_launcher_pipe[0],(byte*)&req_len,
+ sizeof(int),MYF(MY_NABP|MY_FULL_IO)) ||
+ my_read(to_launcher_pipe[0],(byte*)&num_args,
+ sizeof(int),MYF(MY_NABP|MY_FULL_IO)) ||
+ !(request_buf=(char*)my_malloc(req_len+sizeof(pid)+2,MYF(0))) ||
+ !(args=(char**)my_malloc(num_args*sizeof(char*),MYF(0))) ||
+ my_read(to_launcher_pipe[0],request_buf,req_len,
+ MYF(MY_NABP|MY_FULL_IO)))
+ {
+ log_err("launcher: Error reading request");
+ my_free((gptr)request_buf,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((gptr)args,MYF(MY_ALLOW_ZERO_PTR));
+ sleep(1);
+ continue;
+ }
+ stdout_path=request_buf;
+ stderr_path=stdout_path+strlen(stdout_path)+1;
+ request_buf=stderr_path+strlen(stderr_path); /* black magic */
+ ident=request_buf+1;
+ ident_len=strlen(ident);
+ exec_path=ident+ident_len+1;
+ log_debug("num_args=%d,req_len=%d,ident=%s,ident_len=%d,exec_path=%s,\
+stdout_path=%s,stderr_path=%s",
+ num_args,
+ req_len,ident,ident_len,exec_path,stdout_path,stderr_path);
+ init_arg_array(exec_path,args,num_args-1);
+
+ switch ((pid=fork())) {
+ case -1:
+ log_err("launcher: cannot fork");
+ sleep(1);
+ break;
+ case 0:
+ if (open_and_dup(1,stdout_path) || open_and_dup(2,stderr_path))
+ exit(1);
+ if (execv(exec_path,args))
+ log_err("launcher: cannot exec %s",exec_path);
+ exit(1);
+ default:
+ request_buf[0]=CHILD_START;
+ memcpy(request_buf+ident_len+2,&pid,sizeof(pid));
+ if (write(from_launcher_pipe[1],request_buf,ident_len+2+sizeof(pid))<0)
+ log_err("launcher: error sending launch status report");
+ break;
+ }
+ my_free((gptr)(stdout_path),MYF(0));
+ my_free((gptr)args,MYF(0));
+ }
+}
+
+static void fork_launcher()
+{
+ if (pipe(to_launcher_pipe) || pipe(from_launcher_pipe))
+ die("Could not create launcher pipes");
+ switch ((launcher_pid=fork())) {
+ case 0:
+ signal(SIGCHLD,handle_child);
+ run_launcher_loop();
+ exit(0);
+ case -1: die("Could not fork the launcher");
+ default: return;
+ }
+}
+
+static int daemonize()
+{
+ switch (fork()) {
+ case -1:
+ die("Cannot fork");
+ case 0:
+ errfp = open_log_stream();
+ init_globals();
+ close(0);
+ close(1);
+ close(2);
+ init_server();
+ run_server_loop();
+ clean_up();
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+ char c;
+ stack_bottom= (uchar *) &c;
+ MY_INIT(argv[0]);
+ errfp = stderr;
+ parse_args(argc,argv);
+ pthread_mutex_init(&lock_log,0);
+ pthread_mutex_init(&lock_shutdown,0);
+ pthread_mutex_init(&lock_exec_hash,0);
+ pthread_mutex_init(&lock_launch_thd,0);
+ pthread_cond_init(&cond_launch_thd,0);
+#ifdef DO_STACKTRACE
+ signal(SIGSEGV,handle_segfault);
+#endif
+ if (one_thread)
+ {
+ init_globals();
+ init_server();
+ run_server_loop();
+ clean_up();
+ return 0;
+ }
+ else
+ return daemonize();
+}
diff --git a/vio/Makefile.am b/vio/Makefile.am
index d60a59ee3a5..56ab21e8922 100644
--- a/vio/Makefile.am
+++ b/vio/Makefile.am
@@ -14,20 +14,24 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-INCLUDES = -I$(srcdir)/../include -I../include \
- @OPENSSL_INCLUDES@
-LDADD = libvio.la
-pkglib_LTLIBRARIES = libvio.la
-noinst_PROGRAMS =
-noinst_HEADERS =
-libvio_la_SOURCES = \
- Vio.cc VioAcceptorFd.cc \
- VioConnectorFd.cc VioFd.cc \
- VioHandle.cc VioSSL.cc \
- VioSSLFactoriesFd.cc VioSocket.cc \
- auto.cc hostnamexx.cc \
- vdbug.cc version.cc \
- vmem.cc violitexx.cc
+INCLUDES= -I$(srcdir)/../include -I../include $(openssl_includes)
+LDADD= @CLIENT_EXTRA_LDFLAGS@ $(openssl_libs)
+pkglib_LIBRARIES= libvio.a
+noinst_PROGRAMS = test-ssl test-sslserver test-sslclient
+noinst_HEADERS= vio_priv.h
+test_ssl_SOURCES= test-ssl.c
+test_ssl_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \
+ ../mysys/libmysys.a ../strings/libmystrings.a \
+ $(openssl_libs)
+test_sslserver_SOURCES= test-sslserver.c
+test_sslserver_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \
+ ../mysys/libmysys.a ../strings/libmystrings.a \
+ $(openssl_libs)
+test_sslclient_SOURCES= test-sslclient.c
+test_sslclient_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \
+ ../mysys/libmysys.a ../strings/libmystrings.a \
+ $(openssl_libs)
+libvio_a_SOURCES= vio.c viosocket.c viossl.c viosslfactories.c
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/vio/Vio.cc b/vio/Vio.cc
deleted file mode 100644
index b15f9cfa6d2..00000000000
--- a/vio/Vio.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-#include "vio-global.h"
-
-VIO_NS_BEGIN
-
-void
-Vio::release()
-{
- delete this;
-}
-
-Vio::~Vio()
-{
-}
-
-VIO_NS_END
diff --git a/vio/Vio.h b/vio/Vio.h
deleted file mode 100644
index 959d472873f..00000000000
--- a/vio/Vio.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Abstract Virtual IO interface - class Vio. Heavily
- * influenced by Berkeley sockets and oriented toward MySQL.
- */
-
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-** Modified by Monty
-*/
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
- VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
-
-class Vio {
-public:
- virtual bool is_open() const = 0;
- virtual int read(vio_ptr buf, int size) = 0;
- virtual int write(const vio_ptr buf, int size) = 0;
- virtual int blocking(bool onoff) = 0;
- virtual bool blocking() const = 0;
- virtual bool fcntl() const = 0;
- virtual int fastsend(bool onoff = true) = 0;
- virtual int keepalive(bool onoff) = 0;
- virtual bool should_retry() const = 0;
- virtual int close() = 0;
- virtual void release();
- virtual const char* description() const = 0;
- virtual bool peer_addr(char *buf) const = 0;
- virtual const char* cipher_description() const = 0;
- virtual int vio_errno();
- virtual ~Vio();
-};
-
-/* Macros to simulate the violite C interface */
-
-
-Vio *vio_new(my_socket sd, enum enum_vio_type type,
- my_bool localhost);
-#ifdef __WIN__
-Vio* vio_new_win32pipe(HANDLE hPipe);
-#endif
-
-#define vio_delete(vio) delete vio
-#define vio_read(vio,buf,size) vio->read(buf,size)
-#define vio_write(vio,buf,size) vio->write(buf,size)
-#define vio_blocking(vio,mode) vio->blocking(mode)
-#define vio_is_blocking(vio) vio->is_blocking()
-#define vio_fastsend(vio,mode) vio->fastsend(mode)
-#define vio_keepalive(vio,mode) vio->keepalive(mode)
-#define vio_shouldretry(vio) vio->shouldretry(mode)
-#define vio_close(vio) vio->close()
-#define vio_description(vio) vio->description()
-#define vio_errno(Vio *vio) vio->errno()
-#define vio_peer_addr(vio,buf) vio->peer_addr(buf)
-#define vio_in_addr(vio,in) vio->in_addr(in)
-
-VIO_NS_END
diff --git a/vio/VioAcceptorFd.cc b/vio/VioAcceptorFd.cc
deleted file mode 100644
index 4572e2cb71b..00000000000
--- a/vio/VioAcceptorFd.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-#include "vio-global.h"
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-VIO_NS_BEGIN
-
-VioAcceptorFd::~VioAcceptorFd()
-{
-}
-
-VIO_NS_END
diff --git a/vio/VioAcceptorFd.h b/vio/VioAcceptorFd.h
deleted file mode 100644
index e0441780db9..00000000000
--- a/vio/VioAcceptorFd.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-/*
- * Abstract acceptor.
- */
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioAcceptorFd
-{
-public:
- virtual ~VioAcceptorFd();
- virtual Vio* accept( int fd) = 0;
-};
-
-VIO_NS_END
diff --git a/vio/VioConnectorFd.cc b/vio/VioConnectorFd.cc
deleted file mode 100644
index 49f81077a84..00000000000
--- a/vio/VioConnectorFd.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-
-/*
- * Unneccessary virtual destructor.
- */
-
-#include "vio-global.h"
-#include <unistd.h>
-#include <fcntl.h>
-#include <assert.h>
-
-#include "viotypes.h"
-#include "Vio.h"
-#include "VioConnectorFd.h"
-
-VIO_NS_BEGIN
-
-VioConnectorFd::~VioConnectorFd()
-{
-}
-
-VIO_NS_END
-
diff --git a/vio/VioConnectorFd.h b/vio/VioConnectorFd.h
deleted file mode 100644
index da684df5f1b..00000000000
--- a/vio/VioConnectorFd.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Abstract connector. The file (or socket) descriptor has to be
- * prepared.
- */
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioConnectorFd
-{
-public:
- virtual ~VioConnectorFd();
- virtual Vio* connect(int fd) = 0;
-};
-
-VIO_NS_END
diff --git a/vio/VioFd.cc b/vio/VioFd.cc
deleted file mode 100644
index da59798fc25..00000000000
--- a/vio/VioFd.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
-** Virtual I/O library for files
-** Written by Andrei Errapart <andreie@no.spam.ee>
-** Checked and modfied by Monty
-*/
-
-#include "vio-global.h"
-#include <assert.h>
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-VIO_NS_BEGIN
-
-VioFd::VioFd( int fd) : fd_(fd)
-{
- sprintf(desc_, "VioFd(%d)", fd_);
-}
-
-VioFd:: ~VioFd()
-{
- if (fd_ >= 0)
- {
- it r = ::close(fd_);
- if ( r < 0)
- {
- /* FIXME: error handling (Not Critical for MySQL) */
- }
- }
-}
-
-
-bool
-VioFd::open() const
-{
- return fd_ >= 0;
-}
-
-int
-VioFd::read(vio_ptr buf, int size)
-{
- assert(fd_>=0);
- return ::read(fd_, buf, size);
-}
-
-int
-VioFd::write(const vio_ptr buf, int size)
-{
- assert(fd_>=0);
- return ::write(fd_, buf, size);
-}
-
-int
-VioFd::blocking(bool onoff)
-{
- if (onoff)
- return 0;
- else
- return -1;
-}
-
-bool
-VioFd::blocking() const
-{
- return true;
-}
-
-int
-VioFd::fastsend(bool tmp)
-{
- return 0;
-}
-
-
-int
-VioFd::keepalive(boolonoff)
-{
- return -2; // Why -2 ? (monty)
-}
-
-bool
-VioFd::fcntl() const
-{
- return FALSE;
-}
-
-bool
-VioFd::should_retry() const
-{
- return FALSE;
-}
-
-int
-VioFd::fcntl(int cmd)
-{
- assert(fd_>=0);
- return ::fcntl(fd_, cmd);
-}
-
-int
-VioFd::fcntl(int cmd, long arg)
-{
- assert(fd_>=0);
- return ::fcntl(fd_, cmd, arg);
-}
-
-int
-VioFd::fcntl(int cmd, struct flock* lock)
-{
- assert(fd_>=0);
- return ::fcntl(fd_, cmd, lock);
-}
-
-int
-VioFd::close()
-{
- int r = -2;
- if (fd_>=0)
- {
-
- if ((r= ::close(fd_)) == 0)
- fd_ = -1;
- }
- else
- {
- /* FIXME: error handling */
- }
- return r;
-}
-
-const char*
-VioFd::description() const
-{
- return desc_;
-}
-
-const char*
-VioFd::peer_addr() const
-{
- return "";
-}
-
-const char*
-VioFd::peer_name() const
-{
- return "localhost";
-}
-
-const char*
-VioFd::cipher_description() const
-{
- return "";
-}
-
-VIO_NS_END
diff --git a/vio/VioFd.h b/vio/VioFd.h
deleted file mode 100644
index f1c009d848c..00000000000
--- a/vio/VioFd.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Concrete Vio around a file descriptor.
- */
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioFd : public Vio
-{
-public:
- VioFd( int fd);
- virtual ~VioFd();
- virtual bool open() const;
- virtual int read( vio_ptr buf, int size);
- virtual int write( const vio_ptr buf, int size);
- virtual bool blocking() const;
- virtual int blocking(bool onoff);
- virtual int fastsend(bool onoff=true);
- virtual int keepalive( bool onoff);
- virtual bool fcntl() const;
- virtual bool should_retry() const;
- virtual int fcntl( int cmd);
- virtual int fcntl( int cmd, long arg);
- virtual int fcntl( int cmd, struct flock* lock);
- virtual int close();
- virtual const char* description() const;
- virtual const char* peer_addr() const;
- virtual bool peer_name(char *buf) const;
- virtual const char* cipher_description() const;
-private:
- int fd_;
- char desc_[100];
-};
-
-VIO_NS_END
diff --git a/vio/VioPipe.cc b/vio/VioPipe.cc
deleted file mode 100644
index 5d6f9f36496..00000000000
--- a/vio/VioPipe.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-** Virtual I/O library for Windows named pipes
-** Written by Monty
-*/
-
-
-#ifdef __WIN32__
-#include "vio-global.h"
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-VIO_NS_BEGIN
-
-
-
-
-
-
-
-
-VIO_NS_END
-
-#endif /* WIN32 */
diff --git a/vio/VioPipe.h b/vio/VioPipe.h
deleted file mode 100644
index a6bb587c548..00000000000
--- a/vio/VioPipe.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Concrete Vio around Handle.
- */
-
-#ifdef __WIN__
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioPipe : public Vio
-{
-public:
- VioPipe(int fd);
- virtual ~VioPipe();
- virtual bool is_open() const;
- virtual int read(vio_ptr buf, int size);
- virtual int write(const vio_ptr buf, int size);
- virtual int blocking(bool onoff);
- virtual bool blocking() const;
- virtual bool fcntl() const;
- virtual int fastsend(bool onoff = true);
- virtual int keepalive(bool onoff);
- virtual bool should_retry() const;
- virtual int close();
- virtual void release();
- virtual const char* description() const;
- virtual bool peer_addr(char *buf) const;
- virtual const char* cipher_description() const { return "";}
- virtual int vio_errno();
-private:
-};
-
-VIO_NS_END
-
-#endif /* WIN32 */
diff --git a/vio/VioSSL.cc b/vio/VioSSL.cc
deleted file mode 100644
index 15964c09aba..00000000000
--- a/vio/VioSSL.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
-** Virtual I/O library for SSL wrapper
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-/*
- * This file has some huge DBUG_ statements. Boy, this is silly...
- */
-
-#include "vio-global.h"
-#ifdef VIO_HAVE_OPENSSL
-#include <assert.h>
-#include <netinet/in.h>
-#include <openssl/x509.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-VIO_NS_BEGIN
-
-#define this_ssl_con my_static_cast(SSL*)(this->ssl_con_)
-#define this_bio my_static_cast(BIO*)(this->bio_)
-typedef char* dataptr_t;
-
-static void
-report_errors()
-{
- unsigned long l;
- const char* file;
- const char* data;
- int line,flags;
- DBUG_ENTER("VioSSLConnectorFd::report_errors");
-
- while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
- {
- char buf[200];
- DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
- file,line,(flags&ERR_TXT_STRING)?data:"")) ;
- }
- DBUG_VOID_RETURN;
-}
-
-//FIXME: duplicate code!
-VioSSL::VioSSL(int fd,
- vio_ptr ssl_context,
- int state)
- : bio_(0), ssl_con_(0), open_(FALSE), sd_(new VioSocket(fd))
-{
- DBUG_ENTER("VioSSL::VioSSL");
- DBUG_PRINT("enter", ("this=%p, fd=%d, ssl_context=%p, state=%d",
- this, fd, ssl_context, state));
- assert(fd!=0);
- assert(ssl_context!=0);
- assert(state==state_connect || state==state_accept);
-
- if (!init_bio_(fd, ssl_context, state, BIO_NOCLOSE))
- open_ = true;
- DBUG_VOID_RETURN;
-}
-
-
-VioSSL::VioSSL(VioSocket* sd,
- vio_ptr ssl_context,
- int state)
- :bio_(0), ssl_con_(0), open_(FALSE), sd_(sd)
-{
- DBUG_ENTER("VioSSL::VioSSL");
- DBUG_PRINT("enter",
- ("this=%p, sd=%s, ssl_context=%p, state=%d",
- this, sd ? sd->description() : "0", ssl_context, state));
- assert(sd != 0);
- assert(ssl_context != 0);
- assert(state == state_connect || state==state_accept);
-
- if (!init_bio_(sd->sd_, ssl_context, state, BIO_NOCLOSE))
- open_ = true;
- DBUG_VOID_RETURN;
-}
-
-VioSSL::~VioSSL()
-{
- DBUG_ENTER("VioSSL::~VioSSL");
- DBUG_PRINT("enter", ("this=%p", this));
- if (ssl_con_!=0)
- {
- SSL_shutdown(this_ssl_con);
- SSL_free(this_ssl_con);
- }
- if (sd_!=0)
- delete sd_;
- /* FIXME: no need to close bio? */
- /*
- if (bio_!=0)
- BIO_free(this_bio);
- */
- DBUG_VOID_RETURN;
-}
-
-bool
-VioSSL::is_open() const
-{
- return open_;
-}
-
-int
-VioSSL::read(vio_ptr buf, int size)
-{
- int r;
- DBUG_ENTER("VioSSL::read");
- DBUG_PRINT("enter", ("this=%p, buf=%p, size=%d", this, buf, size));
- assert(this_ssl_con != 0);
- r = SSL_read(this_ssl_con, my_static_cast(dataptr_t)(buf), size);
- if ( r< 0)
- report_errors();
- DBUG_PRINT("exit", ("r=%d", r));
- DBUG_RETURN(r);
-}
-
-int
-VioSSL::write(const vio_ptr buf, int size)
-{
- int r;
- DBUG_ENTER("VioSSL::write");
- DBUG_PRINT("enter", ("this=%p, buf=%p, size=%d", this, buf, size));
- assert(this_ssl_con!=0);
- r = SSL_write(this_ssl_con, my_static_cast(dataptr_t)(buf), size);
- if (r<0)
- report_errors();
- DBUG_PRINT("exit", ("r=%d", r));
- DBUG_RETURN(r);
-}
-
-int
-VioSSL::blocking(bool onoff)
-{
- int r;
- DBUG_ENTER("VioSSL::blocking");
- DBUG_PRINT("enter", ("this=%p, onoff=%s", this, onoff?"true":"false"));
- r = sd_->blocking(onoff);
- DBUG_PRINT("exit", ("r=%d", (int)r ));
- DBUG_RETURN(r);
-}
-
-bool
-VioSSL::blocking() const
-{
- bool r;
- DBUG_ENTER("VioSSL::blocking");
- DBUG_PRINT("enter", ("this=%p", this));
- r = sd_->blocking();
- DBUG_PRINT("exit", ("r=%d", (int)r ));
- DBUG_RETURN(r);
-}
-
-int
-VioSSL::fastsend(bool onoff)
-{
- int r;
- DBUG_ENTER("VioSSL::fastsend");
- DBUG_PRINT("enter", ("this=%p, onoff=%d", this, (int) onoff));
- r = sd_->fastsend(onoff);
- DBUG_PRINT("exit", ("r=%d", (int)r ));
- DBUG_RETURN(r);
-}
-
-int VioSSL::keepalive(bool onoff)
-{
- int r;
- DBUG_ENTER("VioSSL::keepalive");
- DBUG_PRINT("enter", ("this=%p, onoff=%d", this, (int) onoff));
- r = sd_->keepalive(onoff);
- DBUG_PRINT("exit", ("r=%d", int(r) ));
- DBUG_RETURN(r);
-}
-
-bool
-VioSSL::fcntl() const
-{
- bool r;
- DBUG_ENTER("VioSSL::fcntl");
- DBUG_PRINT("enter", ("this=%p", this));
- r = sd_->fcntl();
- DBUG_PRINT("exit", ("r=%d", (int)r ));
- DBUG_RETURN(r);
-}
-
-bool
-VioSSL::should_retry() const
-{
- bool r;
- DBUG_ENTER("VioSSL::should_retry");
- DBUG_PRINT("enter", ("this=%p", this));
- r = sd_->should_retry();
- DBUG_PRINT("exit", ("r=%d", (int)r ));
- DBUG_RETURN(r);
-}
-
-int
-VioSSL::close()
-{
- int r= -2;
- DBUG_ENTER("VioSSL::close");
- DBUG_PRINT("enter", ("this=%p", this));
- if (ssl_con)
- {
- r = SSL_shutdown(this_ssl_con);
- SSL_free(this_ssl_con);
- ssl_con_ = 0;
- BIO_free(this_bio);
- bio_ = 0;
- }
- DBUG_PRINT("exit", ("r=%d", r));
- DBUG_RETURN(r);
-}
-
-const char*
-VioSSL::description() const
-{
- return desc_;
-}
-
-const char*
-VioSSL::peer_addr() const
-{
- if (sd_!=0)
- return sd != 0 ? sd_->peer_addr() : "";
-}
-
-const char*
-VioSSL::peer_name() const
-{
- return sd != 0 ? sd_->peer_name() : "";
-}
-
-const char*
-VioSSL::cipher_description() const
-{
- return SSL_get_cipher_name(this_ssl_con);
-}
-
-
-int
-VioSSL::init_bio_(int fd,
- vio_ptr ssl_context,
- int state,
- int bio_flags)
-{
- DBUG_ENTER("VioSSL::init_bio_");
- DBUG_PRINT("enter",
- ("this=%p, fd=%p, ssl_context=%p, state=%d, bio_flags=%d",
- this, fd, ssl_context, state, bio_flags));
-
-
- if (!(ssl_con_ = SSL_new(my_static_cast(SSL_CTX*)(ssl_context))))
- {
- DBUG_PRINT("error", ("SSL_new failure"));
- report_errors();
- DBUG_RETURN(-1);
- }
- if (!(bio_ = BIO_new_socket(fd, bio_flags)))
- {
- DBUG_PRINT("error", ("BIO_new_socket failure"));
- report_errors();
- SSL_free(ssl_con_);
- ssl_con_ =0;
- DBUG_RETURN(-1);
- }
- SSL_set_bio(this_ssl_con, this_bio, this_bio);
- switch(state) {
- case state_connect:
- SSL_set_connect_state(this_ssl_con);
- break;
- case state_accept:
- SSL_set_accept_state(this_ssl_con);
- break;
- default:
- assert(0);
- }
- sprintf(desc_, "VioSSL(%d)", fd);
- ssl_cip_ = new SSL_CIPHER ;
- DBUG_RETURN(0);
-}
-
-
-VIO_NS_END
-
-#endif /* VIO_HAVE_OPENSSL */
-
diff --git a/vio/VioSSL.h b/vio/VioSSL.h
deleted file mode 100644
index 6446c10700e..00000000000
--- a/vio/VioSSL.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Concrete Vio around OpenSSL's SSL structure.
- */
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioSocket;
-
-class VioSSL : public Vio
-{
-public:
- enum {
- state_connect = 1,
- state_accept = 2
- };
-public:
- VioSSL(int fd, vio_ptr ssl_context, int state);
- VioSSL(VioSocket* sd, vio_ptr ssl_context, int state);
- virtual ~VioSSL();
- virtual bool open() const;
- virtual int read( vio_ptr buf, int size);
- virtual int write( const vio_ptr buf, int size);
- virtual bool blocking() const;
- virtual int blocking(bool onoff);
- virtual int fastsend(bool onoff=true);
- virtual int keepalive(bool onoff);
- virtual bool fcntl() const;
- virtual bool should_retry() const;
- virtual int close();
- virtual const char* description() const;
- virtual const char* peer_addr() const;
- virtual const char* peer_name() const;
- virtual const char* cipher_description() const;
-
-private:
- int init_bio_(int fd,
- vio_ptr ssl_context,
- int state,
- int bio_flags);
- vio_ptr bio_;
- vio_ptr ssl_con_;
- vio_ptr ssl_cip_;
- char desc_[100];
- bool open_;
- VioSocket* sd_;
-};
-
-VIO_NS_END
-
-#endif /* VIO_HAVE_OPENSSL */
diff --git a/vio/VioSSLAcceptorFd.cc b/vio/VioSSLAcceptorFd.cc
deleted file mode 100644
index f821685430e..00000000000
--- a/vio/VioSSLAcceptorFd.cc
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
diff --git a/vio/VioSSLFactoriesFd.cc b/vio/VioSSLFactoriesFd.cc
deleted file mode 100644
index bd64202770a..00000000000
--- a/vio/VioSSLFactoriesFd.cc
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-#include "vio-global.h"
-
-#ifdef VIO_HAVE_OPENSSL
-
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-
-#include <netinet/in.h>
-#include <openssl/x509.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/asn1.h>
-
-VIO_NS_BEGIN
-
-#define this_ssl_method my_static_cast(SSL_METHOD*)(this->ssl_method_)
-#define this_ssl_context my_static_cast(SSL_CTX*)(this->ssl_context_)
-typedef unsigned char* ssl_data_ptr_t;
-
-static bool ssl_algorithms_added = FALSE;
-static bool ssl_error_strings_loaded= FALSE;
-static int verify_depth = 0;
-static int verify_error = X509_V_OK;
-
-static int
-vio_verify_callback(int ok, X509_STORE_CTX *ctx)
-{
- DBUG_ENTER("vio_verify_callback");
- DBUG_PRINT("enter", ("ok=%d, ctx=%p", ok, ctx));
- char buf[256];
- X509* err_cert;
- int err,depth;
-
- err_cert=X509_STORE_CTX_get_current_cert(ctx);
- err= X509_STORE_CTX_get_error(ctx);
- depth= X509_STORE_CTX_get_error_depth(ctx);
-
- X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buff));
- if (!ok)
- {
- DBUG_PRINT("error",("verify error:num=%d:%s\n",err,
- X509_verify_cert_error_string(err)));
- if (verify_depth >= depth)
- {
- ok=1;
- verify_error=X509_V_OK;
- }
- else
- {
- ok=0;
- verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
- }
- }
- switch (ctx->error) {
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
- DBUG_PRINT("info",("issuer= %s\n",buf));
- break;
- case X509_V_ERR_CERT_NOT_YET_VALID:
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- DBUG_PRINT("error", ("notBefore"));
- //ASN1_TIME_print_fp(stderr,X509_get_notBefore(ctx->current_cert));
- break;
- case X509_V_ERR_CERT_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- DBUG_PRINT("error", ("notAfter error"));
- //ASN1_TIME_print_fp(stderr,X509_get_notAfter(ctx->current_cert));
- break;
- }
- DBUG_PRINT("exit", ("r=%d", ok));
- DBUG_RETURN(ok);
-}
-
-
-static int
-vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
-{
- DBUG_ENTER("vio_set_cert_stuff");
- DBUG_PRINT("enter", ("ctx=%p, cert_file=%p, key_file=%p",
- ctx, cert_file, key_file));
- if (cert_file != NULL)
- {
- if (SSL_CTX_use_certificate_file(ctx,cert_file,SSL_FILETYPE_PEM) <= 0)
- {
- DBUG_PRINT("error",("unable to get certificate from '%s'\n",cert_file));
- /* FIX stderr */
- ERR_print_errors_fp(stderr);
- DBUG_RETURN(0);
- }
- if (key_file == NULL)
- key_file = cert_file;
- if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
- SSL_FILETYPE_PEM) <= 0)
- {
- DBUG_PRINT("error", ("unable to get private key from '%s'\n",key_file));
- /* FIX stderr */
- ERR_print_errors_fp(stderr);
- DBUG_RETURN(0);
- }
-
- /* If we are using DSA, we can copy the parameters from
- * the private key */
- /* Now we know that a key and cert have been set against
- * the SSL context */
- if (!SSL_CTX_check_private_key(ctx))
- {
- DBUG_PRINT("error", ("Private key does not match the certificate public key\n"));
- DBUG_RETURN(0);
- }
- }
- DBUG_RETURN(1);
-}
-
-/************************ VioSSLConnectorFd **********************************/
-VioSSLConnectorFd::VioSSLConnectorFd(const char* key_file,
- const char* cert_file,
- const char* ca_file,
- const char* ca_path)
-:ssl_context_(0),ssl_method_(0)
-{
- DBUG_ENTER("VioSSLConnectorFd::VioSSLConnectorFd");
- DBUG_PRINT("enter",
- ("this=%p, key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s",
- this, key_file, cert_file, ca_path, ca_file));
-
- /* FIXME: constants! */
- int verify = SSL_VERIFY_PEER;
-
- if (!ssl_algorithms_added)
- {
- DBUG_PRINT("info", ("todo: SSLeay_add_ssl_algorithms()"));
- ssl_algorithms_added = true;
- SSLeay_add_ssl_algorithms();
- }
- if (!ssl_error_strings_loaded)
- {
- DBUG_PRINT("info", ("todo:SSL_load_error_strings()"));
- ssl_error_strings_loaded = true;
- SSL_load_error_strings();
- }
- ssl_method_ = SSLv3_client_method();
- ssl_context_ = SSL_CTX_new(this_ssl_method);
- if (ssl_context_ == 0)
- {
- DBUG_PRINT("error", ("SSL_CTX_new failed"));
- report_errors();
- goto ctor_failure;
- }
- /*
- * SSL_CTX_set_options
- * SSL_CTX_set_info_callback
- * SSL_CTX_set_cipher_list
- */
- SSL_CTX_set_verify(this_ssl_context, verify, vio_verify_callback);
- if (vio_set_cert_stuff(this_ssl_context, cert_file, key_file) == -1)
- {
- DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
- report_errors();
- goto ctor_failure;
- }
- if (SSL_CTX_load_verify_locations( this_ssl_context, ca_file,ca_path)==0)
- {
- DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
- if (SSL_CTX_set_default_verify_paths(this_ssl_context)==0)
- {
- DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
- report_errors();
- goto ctor_failure;
- }
- }
- DBUG_VOID_RETURN;
-ctor_failure:
- DBUG_PRINT("exit", ("there was an error"));
- DBUG_VOID_RETURN;
-}
-
-VioSSLConnectorFd::~VioSSLConnectorFd()
-{
- DBUG_ENTER("VioSSLConnectorFd::~VioSSLConnectorFd");
- DBUG_PRINT("enter", ("this=%p", this));
- if (ssl_context_!=0)
- SSL_CTX_free(this_ssl_context);
- DBUG_VOID_RETURN;
-}
-
-VioSSL* VioSSLConnectorFd::connect( int fd)
-{
- DBUG_ENTER("VioSSLConnectorFd::connect");
- DBUG_PRINT("enter", ("this=%p, fd=%d", this, fd));
- DBUG_RETURN(new VioSSL(fd, ssl_context_, VioSSL::state_connect));
-}
-
-VioSSL*
-VioSSLConnectorFd::connect( VioSocket* sd)
-{
- DBUG_ENTER("VioSSLConnectorFd::connect");
- DBUG_PRINT("enter", ("this=%p, sd=%s", this, sd->description()));
- DBUG_RETURN(new VioSSL(sd, ssl_context_, VioSSL::state_connect));
-}
-
-void
-VioSSLConnectorFd::report_errors()
-{
- unsigned long l;
- const char* file;
- const char* data;
- int line,flags;
-
- DBUG_ENTER("VioSSLConnectorFd::report_errors");
- DBUG_PRINT("enter", ("this=%p", this));
-
- while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
- {
- char buf[200];
- DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
- file,line,(flags&ERR_TXT_STRING)?data:"")) ;
- }
- DBUG_VOID_RETURN;
-}
-
-/************************ VioSSLAcceptorFd **********************************/
-
-VioSSLAcceptorFd::VioSSLAcceptorFd(const char* key_file,
- const char* cert_file,
- const char* ca_file,
- const char* ca_path)
- :ssl_context_(0), ssl_method_(0)
-{
- DBUG_ENTER("VioSSLAcceptorFd::VioSSLAcceptorFd");
- DBUG_PRINT("enter",
- ("this=%p, key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s",
- this, key_file, cert_file, ca_path, ca_file));
-
- /* FIXME: constants! */
- int verify = (SSL_VERIFY_PEER |
- SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
- SSL_VERIFY_CLIENT_ONCE);
- session_id_context_ = static_cast<vio_ptr>(this);
-
- if (!ssl_algorithms_added)
- {
- DBUG_PRINT("info", ("todo: SSLeay_add_ssl_algorithms()"));
- ssl_algorithms_added = true;
- SSLeay_add_ssl_algorithms();
- }
- if (!ssl_error_strings_loaded)
- {
- DBUG_PRINT("info", ("todo: SSL_load_error_strings()"));
- ssl_error_strings_loaded = true;
- SSL_load_error_strings();
- }
- ssl_method_ = SSLv3_server_method();
- ssl_context_ = SSL_CTX_new(this_ssl_method);
- if (ssl_context_==0)
- {
- DBUG_PRINT("error", ("SSL_CTX_new failed"));
- report_errors();
- goto ctor_failure;
- }
- /*
- * SSL_CTX_set_quiet_shutdown(ctx,1);
- *
- */
- SSL_CTX_sess_set_cache_size(this_ssl_context,128);
-
- /* DH?
- */
- SSL_CTX_set_verify(this_ssl_context, verify, vio_verify_callback);
- /*
- * Double cast needed at least for egcs-1.1.2 to
- * supress warnings:
- * 1) ANSI C++ blaah implicit cast from 'void*' to 'unsigned char*'
- * 2) static_cast from 'void**' to 'unsigned char*'
- * Wish I had a copy of standard handy...
- */
- SSL_CTX_set_session_id_context(this_ssl_context,
- my_static_cast(ssl_data_ptr_t)
- (my_static_cast(void*)(&session_id_context_)),
- sizeof(session_id_context_));
-
- /*
- * SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
- */
- if (vio_set_cert_stuff(this_ssl_context, cert_file, key_file) == -1)
- {
- DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
- report_errors();
- goto ctor_failure;
- }
- if (SSL_CTX_load_verify_locations( this_ssl_context, ca_file, ca_path)==0)
- {
- DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
- if (SSL_CTX_set_default_verify_paths(this_ssl_context)==0)
- {
- DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
- report_errors();
- goto ctor_failure;
- }
- }
- DBUG_VOID_RETURN;
-ctor_failure:
- DBUG_PRINT("exit", ("there was an error"));
- DBUG_VOID_RETURN;
-}
-
-VioSSLAcceptorFd::~VioSSLAcceptorFd()
-{
- DBUG_ENTER("VioSSLAcceptorFd::~VioSSLAcceptorFd");
- DBUG_PRINT("enter", ("this=%p", this));
- if (ssl_context_!=0)
- SSL_CTX_free(this_ssl_context);
- DBUG_VOID_RETURN;
-}
-
-VioSSL*
-VioSSLAcceptorFd::accept(int fd)
-{
- DBUG_ENTER("VioSSLAcceptorFd::accept");
- DBUG_PRINT("enter", ("this=%p, fd=%d", this, fd));
- DBUG_RETURN(new VioSSL(fd, ssl_context_, VioSSL::state_accept));
-}
-
-VioSSL*
-VioSSLAcceptorFd::accept(VioSocket* sd)
-{
- DBUG_ENTER("VioSSLAcceptorFd::accept");
- DBUG_PRINT("enter", ("this=%p, sd=%s", this, sd->description()));
- DBUG_RETURN(new VioSSL(sd, ssl_context_, VioSSL::state_accept));
-}
-
-void
-VioSSLAcceptorFd::report_errors()
-{
- unsigned long l;
- const char* file;
- const char* data;
- int line,flags;
-
- DBUG_ENTER("VioSSLConnectorFd::report_errors");
- DBUG_PRINT("enter", ("this=%p", this));
-
- while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
- {
- char buf[200];
- DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
- file,line,(flags&ERR_TXT_STRING)?data:"")) ;
- }
- DBUG_VOID_RETURN;
-}
-
-VIO_NS_END
-
-#endif /* VIO_HAVE_OPENSSL */
diff --git a/vio/VioSSLFactoriesFd.h b/vio/VioSSLFactoriesFd.h
deleted file mode 100644
index ed5a24f6b4a..00000000000
--- a/vio/VioSSLFactoriesFd.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Wrapper around SSL_CTX.
- */
-
-#ifdef VIO_HAVE_OPENSSL
-
-#ifdef __GNUC__
-#pragma interface /* gcc class implementation */
-#endif
-
-VIO_NS_BEGIN
-
-class VioSSLAcceptorFd : public VioAcceptorFd
-{
-public:
- VioSSLAcceptorFd(const char* key_file,
- const char* cert_file,
- const char* ca_file,
- const char* ca_path);
-
- virtual ~VioSSLAcceptorFd();
- virtual VioSSL* accept(int fd);
- virtual VioSSL* accept(VioSocket* sd);
-private:
- VioSSLAcceptorFd(const VioSSLAcceptorFd& rhs);//undefined
- VioSSLAcceptorFd& operator=(const VioSSLAcceptorFd& rhs);//undefined
-private:
- void report_errors();
- vio_ptr ssl_;
- vio_ptr ssl_context_;
- vio_ptr ssl_method_;
- vio_ptr session_id_context_;
-};
-
-VIO_NS_END
-
-/*
- * The Factory where Vio's are made!
- */
-
-class VioSSLConnectorFd : public VioConnectorFd
-{
-public:
- VioSSLConnectorFd(const char* key_file,
- const char* cert_file,
- const char* ca_file,
- const char* ca_path);
-
- virtual ~VioSSLConnectorFd();
- virtual VioSSL* connect(int fd);
- virtual VioSSL* connect(VioSocket* sd);
-private:
- VioSSLConnectorFd(const VioSSLConnectorFd& rhs);//undefined
- VioSSLConnectorFd& operator=(const VioSSLConnectorFd& rhs);//undefined
-private:
- void report_errors();
- vio_ptr ssl_context_;
- vio_ptr ssl_method_;
- vio_ptr ssl_;
-};
-
-VIO_NS_END
-
-#endif /* VIO_HAVE_OPENSSL */
diff --git a/vio/VioSocket.cc b/vio/VioSocket.cc
deleted file mode 100644
index e8390edb98a..00000000000
--- a/vio/VioSocket.cc
+++ /dev/null
@@ -1,326 +0,0 @@
-/* Copyright Abandoned 2000 Monty Program KB
-
- This file is public domain and comes with NO WARRANTY of any kind */
-
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-#include "vio-global.h"
-#ifdef __GNUC__
-#pragma implementation // gcc: Class implementation
-#endif
-#include <assert.h>
-
-/*
- * Probably no need to clean this up
- */
-
-#ifdef _WIN32
-#include <winsock.h>
-#endif
-#include <sys/types.h>
-#if !defined(__WIN32__) && !defined(MSDOS)
-#include <sys/socket.h>
-#endif
-#if !defined(MSDOS) && !defined(__WIN32__) && !defined(HAVE_BROKEN_NETINET_INCLUDES)
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#if !defined(alpha_linux_port)
-#include <netinet/tcp.h>
-#endif
-#if defined(__EMX__)
-#include <sys/ioctl.h>
-#define ioctlsocket(A,B,C) ioctl((A),(B),(void *)(C),sizeof(*(C)))
-#undef HAVE_FCNTL
-#endif
-#endif
-
-#if defined(MSDOS) || defined(__WIN32__)
-#ifdef __WIN32__
-#undef errno
-#undef EINTR
-#undef EAGAIN
-#define errno WSAGetLastError()
-#define EINTR WSAEINTR
-#define EAGAIN WSAEINPROGRESS
-#endif
-#endif
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK EAGAIN
-#endif
-
-#ifdef __cplusplus
-extern "C" { // Because of SCO 3.2V4.2
-#endif
-#ifndef __WIN32__
-#include <sys/resource.h>
-#ifdef HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
-#include <netdb.h>
-#include <sys/utsname.h>
-#endif // __WIN32__
-#ifdef __cplusplus
-}
-#endif
-
-VIO_NS_BEGIN
-
-#define this_ssl_cip my_static_cast(SSL_CIPHER*)(this->ssl_cip_)
-
-VioSocket::VioSocket(vio_socket sd, enum_vio_type type, bool localhost)
-:sd_(sd), localhost_(localhost), fcntl_(0),
- fcntl_set_(FALSE), cipher_description_(0)
-{
- DBUG_ENTER("VioSocket::VioSocket");
- DBUG_PRINT("enter", ("sd=%d", sd));
- if (type == VIO_TYPE_SOCKET)
- sprintf(desc_,"Socket (%d)",sd_);
- else
- sprintf(desc_,"TCP/IP (%d)",sd_);
- DBUG_VOID_RETURN;
-}
-
-VioSocket::~VioSocket()
-{
- DBUG_ENTER("VioSocket::~VioSocket");
- DBUG_PRINT("enter", ("sd_=%d", sd_));
- if (sd_>=0)
- close();
- DBUG_VOID_RETURN;
-}
-
-bool
-VioSocket::is_open() const
-{
- return sd_>=0;
-}
-
-int
-VioSocket::read(vio_ptr buf, int size)
-{
- int r;
- DBUG_ENTER("VioSocket::read");
- DBUG_PRINT("enter", ("sd_=%d, buf=%p, size=%d", sd_, buf, size));
- assert(sd_>=0);
-#if defined(MSDOS) || defined(__WIN32__)
- r = ::recv(sd_, buf, size,0);
-#else
- r = ::read(sd_, buf, size);
-#endif
-#ifndef DBUG_OFF
- if ( r < 0)
- {
- DBUG_PRINT("error", ("Got error %d during read",errno));
- }
-#endif /* DBUG_OFF */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-int
-VioSocket::write(vio_ptr buf, int size)
-{
- int r;
- DBUG_ENTER("VioSocket::write");
- DBUG_PRINT("enter", ("sd_=%d, buf=%p, size=%d", sd_, buf, size));
- assert(sd_>=0);
-#if defined(__WIN32__)
- r = ::send(sd_, buf, size,0);
-#else
- r = ::write(sd_, buf, size);
-#endif /* __WIN32__ */
-#ifndef DBUG_OFF
- if (r < 0)
- {
- DBUG_PRINT("error", ("Got error %d on write",errno));
- }
-#endif /* DBUG_OFF */
- DBUG_RETURN(r);
-}
-
-int
-VioSocket::blocking(bool set_blocking_mode)
-{
- int r= 0;
- DBUG_ENTER("VioSocket::blocking");
- DBUG_PRINT("enter", ("set_blocking_mode: %d", (int) set_blocking_mode));
-
-#if !defined(___WIN32__) && !defined(__EMX__)
-#if !defined(NO_FCNTL_NONBLOCK)
- assert(sd_>=0);
-
- int old_fcntl=fcntl_;
- if (!fcntl_set_)
- {
- fcntl_set_ = true;
- old_fcntl= fcntl_ = fcntl(F_GETFL);
- }
- if (set_blocking_mode)
- fcntl_&=~O_NONBLOCK; //clear bit
- else
- fcntl_|=O_NONBLOCK; //set bit
- if (old_fcntl != fcntl_)
- r = ::fcntl(sd_, F_SETFL, fcntl_);
-#endif /* !defined(NO_FCNTL_NONBLOCK) */
-#else /* !defined(__WIN32__) && !defined(__EMX__) */
- {
- ulong arg;
- int old_fcntl=vio->fcntl_mode;
- if (!vio->fcntl_set)
- {
- vio->fcntl_set = TRUE;
- old_fnctl=vio->fcntl_mode=0;
- }
- if (set_blocking_mode)
- {
- arg = 0;
- fcntl_&=~ O_NONBLOCK; //clear bit
- }
- else
- {
- arg = 1;
- fcntl_|= O_NONBLOCK; //set bit
- }
- if (old_fcntl != fcntl_)
- r = ioctlsocket(sd_,FIONBIO,(void*)&arg,sizeof(arg));
- }
-#endif
- DBUG_RETURN(r);
-}
-
-bool
-VioSocket::blocking() const
-{
- DBUG_ENTER("VioSocket::blocking");
- bool r = !(fcntl_ & O_NONBLOCK);
- DBUG_PRINT("exit", ("%d", (int)r));
- DBUG_RETURN(r);
-}
-
-int
-VioSocket::fastsend(bool onoff)
-{
- int r=0;
- DBUG_ENTER("VioSocket::fastsend");
- DBUG_PRINT("enter", ("onoff:%d", (int)onoff));
- assert(sd_>=0);
-
-#ifdef IPTOS_THROUGHPUT
-#ifndef __EMX__
- int tos = IPTOS_THROUGHPUT;
- if (!setsockopt(sd_, IPPROTO_IP, IP_TOS, (void*) &tos, sizeof(tos)))
-#endif /* !__EMX__ */
- {
- int nodelay = 1;
- if (setsockopt(sd_, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay,
- sizeof(nodelay)))
- {
- DBUG_PRINT("warning",
- ("Couldn't set socket option for fast send"));
- r= -1;
- }
- }
-#endif /* IPTOS_THROUGHPUT */
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(0);
-}
-
-
-int
-VioSocket::keepalive(bool set_keep_alive)
-{
- DBUG_ENTER("VioSocket::keepalive");
- DBUG_PRINT("enter", ("sd_=%d, set_keep_alive=%d", sd_,
- (int) set_keep_alive));
- assert(sd_>=0);
- uint opt= set_keep_alive ? 1 : 0;
- DBUG_RETURN(setsockopt(sd_, SOL_SOCKET, SO_KEEPALIVE, (char*) &opt,
- sizeof(opt)));
-}
-
-
-bool
-VioSocket::should_retry() const
-{
- int en = errno;
- return en == EAGAIN || en == EINTR || en == EWOULDBLOCK;
-}
-
-int
-VioSocket::close()
-{
- DBUG_ENTER("VioSocket::close");
- assert(sd_>=0);
- int r=0;
- if (::shutdown(sd_,2))
- r= -1;
- if (::closesocket(sd_))
- r= -1;
- if (r)
- {
- DBUG_PRINT("error", ("close() failed, error: %d",errno));
- /* FIXME: error handling (not critical for MySQL) */
- }
- sd_ = -1;
- DBUG_RETURN(r);
-}
-
-
-int
-VioSocket::shutdown(int how)
-{
- DBUG_ENTER("VioSocket::shutdown");
- DBUG_PRINT("enter", ("how=%d", how));
- assert(sd_>=0);
- int r = ::shutdown(sd_, how);
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-const char*
-VioSocket::description() const
-{
- return desc_;
-}
-
-
-bool
-VioSocket::peer_addr(char *buf) const
-{
- DBUG_ENTER("VioSocket::peer_addr");
- DBUG_PRINT("enter", ("sd_=%d", sd_));
- if (localhost_)
- {
- strmov(buf,"127.0.0.1");
- }
- else
- {
- size_socket addrLen= sizeof(struct sockaddr);
- if (getpeername(sd_, my_reinterpret_cast(struct sockaddr *) (&remote_),
- &addrLen) != 0)
- {
- DBUG_PRINT("exit", ("getpeername, error: %d", errno));
- DBUG_RETURN(1);
- }
- my_inet_ntoa(remote_.sin_addr,buf);
- }
- DBUG_PRINT("exit", ("addr=%s", buf));
- DBUG_RETURN(0);
-}
-
-
-const char*
-VioSocket::cipher_description() const
-{
- DBUG_ENTER("VioSocket::cipher_description");
- char *r = cipher_description_ ? cipher_description_:"";
- DBUG_PRINT("exit", ("name: %s", r));
- DBUG_RETURN(r);
-}
-
-VIO_NS_END
diff --git a/vio/VioSocket.h b/vio/VioSocket.h
deleted file mode 100644
index e2c6eafa516..00000000000
--- a/vio/VioSocket.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-/*
- * Concrete Vio around socket. Doesn't differ much from VioFd.
- */
-
-#ifdef WIN32
- typedef SOCKET vio_socket;
-#else
- typedef int vio_socket;
-#endif /* WIN32 */
-
-VIO_NS_BEGIN
-
-class VioSSL;
-class VioSocket : public Vio
-{
-public:
- VioSocket(vio_socket sd, bool localhost=true);
- virtual ~VioSocket();
- virtual bool is_open() const;
- virtual int read(vio_ptr buf, int size);
- virtual int write(const vio_ptr buf, int size);
- virtual int blocking(bool onoff);
- virtual bool blocking() const;
- virtual int fastsend(bool onoff=true);
- virtual int keepalive(bool onoff);
- virtual bool should_retry() const;
- virtual int close();
- virtual const char* description() const;
- virtual bool peer_addr(char *buf) const;
- virtual const char* cipher_description() const;
- virtual int vio_errno();
- int shutdown(int how);
-
-private:
- vio_socket sd_;
- const bool localhost_;
- int fcntl_;
- bool fcntl_set_;
- char desc_[30];
- mutable struct sockaddr_in local_;
- mutable struct sockaddr_in remote_;
- mutable char* cipher_description_;
-
- friend class VioSSL; // he wants to tinker with this->sd_;
-};
-
-VIO_NS_END
-
-#endif /* vio_VioSocket_h_ */
-
diff --git a/vio/docs/COPYING.dbug b/vio/docs/COPYING.dbug
deleted file mode 100644
index e1b6463c09b..00000000000
--- a/vio/docs/COPYING.dbug
+++ /dev/null
@@ -1,29 +0,0 @@
-/******************************************************************************
- * *
- * N O T I C E *
- * *
- * Copyright Abandoned, 1987, Fred Fish *
- * *
- * *
- * This previously copyrighted work has been placed into the public *
- * domain by the author and may be freely used for any purpose, *
- * private or commercial. *
- * *
- * Because of the number of inquiries I was receiving about the use *
- * of this product in commercially developed works I have decided to *
- * simply make it public domain to further its unrestricted use. I *
- * specifically would be most happy to see this material become a *
- * part of the standard Unix distributions by AT&T and the Berkeley *
- * Computer Science Research Group, and a standard part of the GNU *
- * system from the Free Software Foundation. *
- * *
- * I would appreciate it, as a courtesy, if this notice is left in *
- * all copies and derivative works. Thank you. *
- * *
- * The author makes no warranty of any kind with respect to this *
- * product and explicitly disclaims any implied warranties of mer- *
- * chantability or fitness for any particular purpose. *
- * *
- ******************************************************************************
- */
-
diff --git a/vio/docs/COPYING.mysql b/vio/docs/COPYING.mysql
deleted file mode 100644
index c2028f07298..00000000000
--- a/vio/docs/COPYING.mysql
+++ /dev/null
@@ -1,193 +0,0 @@
-The *MySQL* server license for non Microsoft operating systems
-**************************************************************
-
- *MySQL FREE PUBLIC LICENSE*
-
- (Version 4, March 5, 1995)
-
- Copyright (C) 1995, 1996 TcX AB & Monty Program KB & Detron HB
-
- Stockholm SWEDEN, Helsingfors FINLAND and Uppsala SWEDEN
-
- All rights reserved.
-
-NOTE: This license is not the same as any of the GNU Licenses published
-by the Free Software Foundation. Its terms are substantially different
-from those of the GNU Licenses. If you are familiar with the GNU
-Licenses, please read this license with extra care.
-
-This License applies to the computer program known as "MySQL". The
-"Program", below, refers to such program, and a "work based on the
-Program" means either the Program or any derivative work of the Program,
-as defined in the United States Copyright Act of 1976, such as a
-translation or a modification. The Program is a copyrighted work whose
-copyright is held by TcX Datakonsult AB and Monty Program KB and Detron
-HB.
-
-This License does not apply when running "MySQL" on any Microsoft
-operating system. Microsoft operating systems include all versions of
-Microsoft Windows NT and Microsoft Windows.
-
-BY MODIFYING OR DISTRIBUTING THE PROGRAM (OR ANY WORK BASED ON THE
-PROGRAM), YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL
-ITS TERMS AND CONDITIONS FOR COPYING, DISTRIBUTING OR MODIFYING THE
-PROGRAM OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS
-YOU PERMISSION TO MODIFY OR DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE
-WORKS. THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE
-TERMS AND CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM.
-
- 1. Licenses.
-
- Licensor hereby grants you the following rights, provided that you
- comply with all of the restrictions set forth in this License and
- provided, further, that you distribute an unmodified copy of this
- License with the Program:
-
- a. You may copy and distribute literal (i.e., verbatim) copies
- of the Program's source code as you receive it throughout the
- world, in any medium.
-
- b. You may modify the Program, create works based on the Program
- and distribute copies of such throughout the world, in any
- medium.
-
- 2. Restrictions.
-
- This license is subject to the following restrictions:
- a. Distribution of the Program or any work based on the Program
- by a commercial organization to any third party is prohibited
- if any payment is made in connection with such distribution,
- whether directly (as in payment for a copy of the Program) or
- indirectly (as in payment for some service related to the
- Program, or payment for some product or service that includes
- a copy of the Program "without charge"; these are only
- examples, and not an exhaustive enumeration of prohibited
- activities). However, the following methods of distribution
- involving payment shall not in and of themselves be a
- violation of this restriction:
-
- A. Posting the Program on a public access information
- storage and retrieval service for which a fee is
- received for retrieving information (such as an on-line
- service), provided that the fee is not content-dependent
- (i.e., the fee would be the same for retrieving the same
- volume of information consisting of random data).
-
- B. Distributing the Program on a CD-ROM, provided that the
- files containing the Program are reproduced entirely and
- verbatim on such CD-ROM, and provided further that all
- information on such CD-ROM be redistributable for
- non-commercial purposes without charge.
-
- b. Activities other than copying, distribution and modification
- of the Program are not subject to this License and they are
- outside its scope. Functional use (running) of the Program
- is not restricted, and any output produced through the use of
- the Program is subject to this license only if its contents
- constitute a work based on the Program (independent of having
- been made by running the Program).
-
- c. You must meet all of the following conditions with respect to
- the distribution of any work based on the Program:
- A. If you have modified the Program, you must cause your
- work to carry prominent notices stating that you have
- modified the Program's files and the date of any change;
-
- B. You must cause any work that you distribute or publish,
- that in whole or in part contains or is derived from the
- Program or any part thereof, to be licensed as a whole
- and at no charge to all third parties under the terms of
- this License;
-
- C. If the modified program normally reads commands
- interactively when run, you must cause it, at each time
- the modified program commences operation, to print or
- display an announcement including an appropriate
- copyright notice and a notice that there is no warranty
- (or else, saying that you provide a warranty). Such
- notice must also state that users may redistribute the
- Program only under the conditions of this License and
- tell the user how to view the copy of this License
- included with the Program. (Exception: if the Program
- itself is interactive but does not normally print such
- an announcement, your work based on the Program is not
- required to print an announcement.);
-
- D. You must accompany any such work based on the Program
- with the complete corresponding machine-readable source
- code, delivered on a medium customarily used for
- software interchange. The source code for a work means
- the preferred form of the work for making modifications
- to it. For an executable work, complete source code
- means all the source code for all modules it contains,
- plus any associated interface definition files, plus the
- scripts used to control compilation and installation of
- the executable code. However, the source code
- distributed need not include anything that is normally
- distributed (in either source or binary form) with the
- major components (compiler, kernel, and so on) of the
- operating system on which the executable runs, unless
- that component itself accompanies the executable code;
-
- E. If you distribute any written or printed material at all
- with the Program or any work based on the Program, such
- material must include either a written copy of this
- License, or a prominent written indication that the
- Program or the work based on the Program is covered by
- this License and written instructions for printing
- and/or displaying the copy of the License on the
- distribution medium;
-
- F. You may not impose any further restrictions on the
- recipient's exercise of the rights granted herein.
-
- If distribution of executable or object code is made by
- offering the equivalent ability to copy from a
- designated place, then offering equivalent ability to
- copy the source code from the same place counts as
- distribution of the source code, even though third
- parties are not compelled to copy the source code along
- with the object code.
-
- 3. Reservation of Rights.
-
- No rights are granted to the Program except as expressly set forth
- herein. You may not copy, modify, sublicense, or distribute the
- Program except as expressly provided under this License. Any
- attempt otherwise to copy, modify, sublicense or distribute the
- Program is void, and will automatically terminate your rights
- under this License. However, parties who have received copies, or
- rights, from you under this License will not have their licenses
- terminated so long as such parties remain in full compliance.
-
- 4. Other Restrictions.
-
- If the distribution and/or use of the Program is restricted in
- certain countries for any reason, Licensor may add an explicit
- geographical distribution limitation excluding those countries, so
- that distribution is permitted only in or among countries not thus
- excluded. In such case, this License incorporates the limitation
- as if written in the body of this License.
-
- 5. Limitations.
-
- THE PROGRAM IS PROVIDED TO YOU "AS IS," WITHOUT WARRANTY. THERE IS
- NO WARRANTY FOR THE PROGRAM, EITHER EXPRESSED OR IMPLIED,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
- QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
- PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
- SERVICING, REPAIR OR CORRECTION.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
- WRITING WILL LICENSOR, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
- DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
- CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
- THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
- BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
- PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
- PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
- THE POSSIBILITY OF SUCH DAMAGES.
-
diff --git a/vio/docs/CodingStyle b/vio/docs/CodingStyle
deleted file mode 100644
index 7231b369d18..00000000000
--- a/vio/docs/CodingStyle
+++ /dev/null
@@ -1,8 +0,0 @@
-Roughly the same as "Linux Kernel Coding Style", which is
-included in file LinuxKernelCodingStyle.
-
-Some methods are meant to be used as set/get, for example, there
-are:
-virtual bool Vio::blocking();
-virtual int Vio::blocking(bool block);
-
diff --git a/vio/docs/README b/vio/docs/README
deleted file mode 100644
index 9fb3255236f..00000000000
--- a/vio/docs/README
+++ /dev/null
@@ -1,18 +0,0 @@
-Virtual IO library.
-IO wrappers for sockets, fd-s, SSL.
-Languages:C++
-
-This library is based on work of many others.
-They have different policies and I haven't thought up
-about resulting licence - GPL, L(essen)GPL, BSD-style, whatever.
-The licences are here for reference:
-COPYING.mysql: MySQL licence. Some socket functions.
-COPYING.dbug: Fred Fish's dbug library. I use it extensively ;=)
-COPYING.openssl:OpenSSL licence. SSL wrappers.
-
-At the moment there is no real 'Makefile', just config.mk/targets.mk
-and Makefile.am to build it as a module in MySQL. Therefore, there
-is currently no possibility to build it as a separate library, but
-with MySQL-s root Makefile it should just a matter of leaving
-everything else out.
-
diff --git a/vio/test-ssl.c b/vio/test-ssl.c
new file mode 100644
index 00000000000..84bae5fa0c7
--- /dev/null
+++ b/vio/test-ssl.c
@@ -0,0 +1,150 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#ifdef HAVE_OPENSSL
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+#include "errmsg.h"
+#include <my_dir.h>
+#include <my_getopt.h>
+#include <signal.h>
+#include <violite.h>
+
+const char *VER="0.2";
+
+
+#ifndef DBUG_OFF
+const char *default_dbug_option="d:t:O,-";
+#endif
+
+void
+fatal_error( const char* r)
+{
+ perror(r);
+ exit(0);
+}
+
+void
+print_usage()
+{
+ printf("viossl-test: testing SSL virtual IO. Usage:\n");
+ printf("viossl-test server-key server-cert client-key client-cert [CAfile] [CApath]\n");
+}
+
+
+int
+main(int argc, char** argv)
+{
+ char* server_key = 0, *server_cert = 0;
+ char* client_key = 0, *client_cert = 0;
+ char* ca_file = 0, *ca_path = 0;
+ char* cipher=0;
+ int child_pid,sv[2];
+ my_bool unused;
+ struct st_VioSSLAcceptorFd* ssl_acceptor=0;
+ struct st_VioSSLConnectorFd* ssl_connector=0;
+ Vio* client_vio=0, *server_vio=0;
+ MY_INIT(argv[0]);
+ DBUG_PROCESS(argv[0]);
+ DBUG_PUSH(default_dbug_option);
+
+ if (argc<5)
+ {
+ print_usage();
+ return 1;
+ }
+
+ server_key = argv[1];
+ server_cert = argv[2];
+ client_key = argv[3];
+ client_cert = argv[4];
+ if (argc>5)
+ ca_file = argv[5];
+ if (argc>6)
+ ca_path = argv[6];
+ printf("Server key/cert : %s/%s\n", server_key, server_cert);
+ printf("Client key/cert : %s/%s\n", client_key, client_cert);
+ if (ca_file!=0)
+ printf("CAfile : %s\n", ca_file);
+ if (ca_path!=0)
+ printf("CApath : %s\n", ca_path);
+
+
+ if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1)
+ fatal_error("socketpair");
+
+ ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file,
+ ca_path, cipher);
+ ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file,
+ ca_path, cipher);
+
+ client_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0));
+ client_vio->sd = sv[0];
+ client_vio->vioblocking(client_vio, 0, &unused);
+ sslconnect(ssl_connector,client_vio,60L);
+ server_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0));
+ server_vio->sd = sv[1];
+ server_vio->vioblocking(client_vio, 0, &unused);
+ sslaccept(ssl_acceptor,server_vio,60L);
+
+ printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd);
+
+ child_pid = fork();
+ if (child_pid==-1) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("fork");
+ }
+ if (child_pid==0)
+ {
+ /* child, therefore, client */
+ char xbuf[100];
+ int r = client_vio->read(client_vio,xbuf, sizeof(xbuf));
+ if (r<=0) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("client:SSL_read");
+ }
+ xbuf[r] = 0;
+ printf("client:got %s\n", xbuf);
+ my_free((gptr)client_vio,MYF(0));
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ }
+ else
+ {
+ const char* s = "Huhuhuh";
+ int r = server_vio->write(server_vio,(gptr)s, strlen(s));
+ if (r<=0) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("server:SSL_write");
+ }
+ my_free((gptr)server_vio,MYF(0));
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ }
+ return 0;
+}
+#else /* HAVE_OPENSSL */
+
+int main() {
+return 0;
+}
+#endif /* HAVE_OPENSSL */
diff --git a/vio/test-sslclient.c b/vio/test-sslclient.c
new file mode 100644
index 00000000000..231ce056d8c
--- /dev/null
+++ b/vio/test-sslclient.c
@@ -0,0 +1,102 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#ifdef HAVE_OPENSSL
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+#include "errmsg.h"
+#include <my_dir.h>
+#include <my_getopt.h>
+#include <signal.h>
+#include <violite.h>
+
+const char *VER="0.2";
+
+
+#ifndef DBUG_OFF
+const char *default_dbug_option="d:t:O,-";
+#endif
+
+void
+fatal_error( const char* r)
+{
+ perror(r);
+ exit(0);
+}
+
+int
+main( int argc __attribute__((unused)),
+ char** argv)
+{
+ char client_key[] = "../SSL/client-key.pem", client_cert[] = "../SSL/client-cert.pem";
+ char ca_file[] = "../SSL/cacert.pem", *ca_path = 0, *cipher=0;
+ struct st_VioSSLConnectorFd* ssl_connector=0;
+ struct sockaddr_in sa;
+ Vio* client_vio=0;
+ int err;
+ char xbuf[100]="Ohohhhhoh1234";
+ MY_INIT(argv[0]);
+ DBUG_PROCESS(argv[0]);
+ DBUG_PUSH(default_dbug_option);
+
+ printf("Client key/cert : %s/%s\n", client_key, client_cert);
+ if (ca_file!=0)
+ printf("CAfile : %s\n", ca_file);
+ if (ca_path!=0)
+ printf("CApath : %s\n", ca_path);
+
+ ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher);
+ if(!ssl_connector) {
+ fatal_error("client:new_VioSSLConnectorFd failed");
+ }
+
+ /* ----------------------------------------------- */
+ /* Create a socket and connect to server using normal socket calls. */
+
+ client_vio = vio_new(socket (AF_INET, SOCK_STREAM, 0), VIO_TYPE_TCPIP, TRUE);
+
+ memset (&sa, '\0', sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = inet_addr ("127.0.0.1"); /* Server IP */
+ sa.sin_port = htons (1111); /* Server Port number */
+
+ err = connect(client_vio->sd, (struct sockaddr*) &sa,
+ sizeof(sa));
+
+ /* ----------------------------------------------- */
+ /* Now we have TCP conncetion. Start SSL negotiation. */
+ read(client_vio->sd,xbuf, sizeof(xbuf));
+ sslconnect(ssl_connector,client_vio,60L);
+ err = client_vio->read(client_vio,xbuf, sizeof(xbuf));
+ if (err<=0) {
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("client:SSL_read");
+ }
+ xbuf[err] = 0;
+ printf("client:got %s\n", xbuf);
+ my_free((gptr)client_vio,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ return 0;
+}
+#else /* HAVE_OPENSSL */
+
+int main() {
+return 0;
+}
+#endif /* HAVE_OPENSSL */
diff --git a/vio/test-sslserver.c b/vio/test-sslserver.c
new file mode 100644
index 00000000000..71b194838c7
--- /dev/null
+++ b/vio/test-sslserver.c
@@ -0,0 +1,156 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#ifdef HAVE_OPENSSL
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+#include "errmsg.h"
+#include <my_dir.h>
+#include <my_getopt.h>
+#include <signal.h>
+#include <violite.h>
+
+const char *VER="0.2";
+
+
+#ifndef DBUG_OFF
+const char *default_dbug_option="d:t:O,-";
+#endif
+
+#if 0
+static void
+fatal_error( const char* r)
+{
+ perror(r);
+ exit(0);
+}
+#endif
+
+typedef struct {
+ int sd;
+ struct st_VioSSLAcceptorFd* ssl_acceptor;
+} TH_ARGS;
+
+static void
+do_ssl_stuff( TH_ARGS* args)
+{
+ const char* s = "Huhuhuhuuu";
+ Vio* server_vio;
+ int err;
+ DBUG_ENTER("do_ssl_stuff");
+
+ server_vio = vio_new(args->sd, VIO_TYPE_TCPIP, TRUE);
+
+ /* ----------------------------------------------- */
+ /* TCP connection is ready. Do server side SSL. */
+
+ err = write(server_vio->sd,(gptr)s, strlen(s));
+ sslaccept(args->ssl_acceptor,server_vio,60L);
+ err = server_vio->write(server_vio,(gptr)s, strlen(s));
+ DBUG_VOID_RETURN;
+}
+
+static void*
+client_thread( void* arg)
+{
+ my_thread_init();
+ do_ssl_stuff((TH_ARGS*)arg);
+ return 0;
+}
+
+int
+main(int argc __attribute__((unused)), char** argv)
+{
+ char server_key[] = "../SSL/server-key.pem",
+ server_cert[] = "../SSL/server-cert.pem";
+ char ca_file[] = "../SSL/cacert.pem",
+ *ca_path = 0,
+ *cipher = 0;
+ struct st_VioSSLAcceptorFd* ssl_acceptor;
+ pthread_t th;
+ TH_ARGS th_args;
+
+
+ struct sockaddr_in sa_serv;
+ struct sockaddr_in sa_cli;
+ int listen_sd;
+ int err;
+ size_t client_len;
+ int reuseaddr = 1; /* better testing, uh? */
+
+ MY_INIT(argv[0]);
+ DBUG_PROCESS(argv[0]);
+ DBUG_PUSH(default_dbug_option);
+
+ printf("Server key/cert : %s/%s\n", server_key, server_cert);
+ if (ca_file!=0)
+
+ printf("CAfile : %s\n", ca_file);
+ if (ca_path!=0)
+ printf("CApath : %s\n", ca_path);
+
+ th_args.ssl_acceptor = ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path,cipher);
+
+ /* ----------------------------------------------- */
+ /* Prepare TCP socket for receiving connections */
+
+ listen_sd = socket (AF_INET, SOCK_STREAM, 0);
+ setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(&reuseaddr));
+
+ memset (&sa_serv, '\0', sizeof(sa_serv));
+ sa_serv.sin_family = AF_INET;
+ sa_serv.sin_addr.s_addr = INADDR_ANY;
+ sa_serv.sin_port = htons (1111); /* Server Port number */
+
+ err = bind(listen_sd, (struct sockaddr*) &sa_serv,
+ sizeof (sa_serv));
+
+ /* Receive a TCP connection. */
+
+ err = listen (listen_sd, 5);
+ client_len = sizeof(sa_cli);
+ th_args.sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
+ close (listen_sd);
+
+ printf ("Connection from %lx, port %x\n",
+ (long)sa_cli.sin_addr.s_addr, sa_cli.sin_port);
+
+ /* ----------------------------------------------- */
+ /* TCP connection is ready. Do server side SSL. */
+
+ err = pthread_create(&th, NULL, client_thread, (void*)&th_args);
+ DBUG_PRINT("info", ("pthread_create: %d", err));
+ pthread_join(th, NULL);
+
+#if 0
+ if (err<=0) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ fatal_error("server:SSL_write");
+ }
+#endif /* 0 */
+
+ my_free((gptr)ssl_acceptor,MYF(0));
+ return 0;
+}
+#else /* HAVE_OPENSSL */
+
+int main() {
+return 0;
+}
+#endif /* HAVE_OPENSSL */
diff --git a/vio/version.cc b/vio/version.cc
deleted file mode 100644
index 7c09d431a9d..00000000000
--- a/vio/version.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "vio-global.h"
-
-extern "C" const char*
-vio_version()
-{
- return "0.2";
-}
diff --git a/vio/vio-global.h b/vio/vio-global.h
deleted file mode 100644
index 0c3d279695d..00000000000
--- a/vio/vio-global.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <global.h>
-
-#if !defined(VIO_HAVE_OPENSSL) && defined(HAVE_OPENSSL)
-#define VIO_HAVE_OPENSSL HAVE_OPENSSL
-#endif /* !defined(VIO_HAVE_OPENSSL) && defined(HAVE_OPENSSL) */
-
-#include "viotypes.h"
-#include "Vio.h"
-#include "VioAcceptorFd.h"
-#include "VioFd.h"
-#include "VioPipe.h"
-#include "VioSocket.h"
-#ifdef VIO_HAVE_OPENSSL
-#include "VioSSL.h"
-#include "VioSSLFactoriesFd.h"
-#endif /* VIO_HAVE_OPENSSL */
-
-
-#if VIO_HAVE_NAMESPACES
-#define VIO_STD_NS std
-#define VIO_STD_NS_USING using namespace std;
-#define VIO_NS VirtualIO
-#define VIO_NS_BEGIN namespace VIO_NS {
-#define VIO_NS_END }
-#define VIO_NS_USING using namespace VIO_NS;
-#else
-#define VIO_STD_NS
-#define VIO_STD_NS_USING
-#define VIO_NS
-#define VIO_NS_BEGIN
-#define VIO_NS_END
-#define VIO_NS_USING
-#endif
diff --git a/vio/vio.c b/vio/vio.c
new file mode 100644
index 00000000000..2b745ab3ec6
--- /dev/null
+++ b/vio/vio.c
@@ -0,0 +1,133 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Note that we can't have assertion on file descriptors; The reason for
+ this is that during mysql shutdown, another thread can close a file
+ we are working on. In this case we should just return read errors from
+ the file descriptior.
+*/
+
+#include "vio_priv.h"
+
+/*
+ * Helper to fill most of the Vio* with defaults.
+ */
+
+void vio_reset(Vio* vio, enum enum_vio_type type,
+ my_socket sd, HANDLE hPipe,
+ my_bool localhost)
+{
+ DBUG_ENTER("vio_reset");
+ DBUG_PRINT("enter", ("type=%d sd=%d localhost=%d", type, sd, localhost));
+
+ bzero((char*) vio, sizeof(*vio));
+ vio->type = type;
+ vio->sd = sd;
+ vio->hPipe = hPipe;
+ vio->localhost= localhost;
+#ifdef HAVE_VIO
+#ifdef HAVE_OPENSSL
+ if (type == VIO_TYPE_SSL)
+ {
+ vio->viodelete =vio_ssl_delete;
+ vio->vioerrno =vio_ssl_errno;
+ vio->read =vio_ssl_read;
+ vio->write =vio_ssl_write;
+ vio->fastsend =vio_ssl_fastsend;
+ vio->viokeepalive =vio_ssl_keepalive;
+ vio->should_retry =vio_ssl_should_retry;
+ vio->vioclose =vio_ssl_close;
+ vio->peer_addr =vio_ssl_peer_addr;
+ vio->in_addr =vio_ssl_in_addr;
+ vio->vioblocking =vio_ssl_blocking;
+ vio->is_blocking =vio_is_blocking;
+ vio->timeout =vio_ssl_timeout;
+ }
+ else /* default is VIO_TYPE_TCPIP */
+#endif /* HAVE_OPENSSL */
+ {
+ vio->viodelete =vio_delete;
+ vio->vioerrno =vio_errno;
+ vio->read =vio_read;
+ vio->write =vio_write;
+ vio->fastsend =vio_fastsend;
+ vio->viokeepalive =vio_keepalive;
+ vio->should_retry =vio_should_retry;
+ vio->vioclose =vio_close;
+ vio->peer_addr =vio_peer_addr;
+ vio->in_addr =vio_in_addr;
+ vio->vioblocking =vio_blocking;
+ vio->is_blocking =vio_is_blocking;
+ vio->timeout =vio_timeout;
+ }
+#endif /* HAVE_VIO */
+ DBUG_VOID_RETURN;
+}
+
+
+/* Open the socket or TCP/IP connection and read the fnctl() status */
+
+Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
+{
+ Vio *vio;
+ DBUG_ENTER("vio_new");
+ DBUG_PRINT("enter", ("sd=%d", sd));
+ if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
+ {
+ vio_reset(vio, type, sd, 0, localhost);
+ sprintf(vio->desc,
+ (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
+ vio->sd);
+#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
+#if !defined(NO_FCNTL_NONBLOCK)
+#if defined(__FreeBSD__)
+ fcntl(sd, F_SETFL, vio->fcntl_mode); /* Yahoo! FreeBSD patch */
+#endif
+ vio->fcntl_mode = fcntl(sd, F_GETFL);
+#elif defined(HAVE_SYS_IOCTL_H) /* hpux */
+ /* Non blocking sockets doesn't work good on HPUX 11.0 */
+ (void) ioctl(sd,FIOSNBIO,0);
+ vio->fcntl_mode &= ~O_NONBLOCK;
+#endif
+#else /* !defined(__WIN__) && !defined(__EMX__) */
+ {
+ /* set to blocking mode by default */
+ ulong arg=0, r;
+ r = ioctlsocket(sd,FIONBIO,(void*) &arg, sizeof(arg));
+ vio->fcntl_mode &= ~O_NONBLOCK;
+ }
+#endif
+ }
+ DBUG_RETURN(vio);
+}
+
+
+#ifdef __WIN__
+
+Vio *vio_new_win32pipe(HANDLE hPipe)
+{
+ Vio *vio;
+ DBUG_ENTER("vio_new_handle");
+ if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
+ {
+ vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
+ strmov(vio->desc, "named pipe");
+ }
+ DBUG_RETURN(vio);
+}
+
+#endif
diff --git a/vio/vio_priv.h b/vio/vio_priv.h
new file mode 100644
index 00000000000..66a9bde4e0d
--- /dev/null
+++ b/vio/vio_priv.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Structures and functions private to the vio package */
+
+#define DONT_MAP_VIO
+#include <my_global.h>
+#include <mysql_com.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <violite.h>
+
+#ifdef HAVE_OPENSSL
+#include "my_net.h" /* needed because of struct in_addr */
+
+void vio_ssl_delete(Vio* vio);
+int vio_ssl_read(Vio *vio,gptr buf, int size);
+int vio_ssl_write(Vio *vio,const gptr buf,int size);
+void vio_ssl_timeout(Vio *vio, uint timeout);
+
+/* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. */
+int vio_ssl_fastsend(Vio *vio);
+/* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible. */
+int vio_ssl_keepalive(Vio *vio, my_bool onoff);
+/* Whenever we should retry the last read/write operation. */
+my_bool vio_ssl_should_retry(Vio *vio);
+/* When the workday is over... */
+int vio_ssl_close(Vio *vio);
+/* Return last error number */
+int vio_ssl_errno(Vio *vio);
+my_bool vio_ssl_peer_addr(Vio *vio, char *buf, uint16 *port);
+void vio_ssl_in_addr(Vio *vio, struct in_addr *in);
+int vio_ssl_blocking(Vio *vio, my_bool set_blocking_mode, my_bool *old_mode);
+
+/* Single copy for server */
+enum vio_ssl_acceptorfd_state
+{
+ state_connect = 1,
+ state_accept = 2
+};
+#endif /* HAVE_OPENSSL */
diff --git a/vio/vioelitexx.cc b/vio/vioelitexx.cc
deleted file mode 100644
index 0eac28eaf55..00000000000
--- a/vio/vioelitexx.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright Abandoned 2000 Monty Program KB
- This file is public domain and comes with NO WARRANTY of any kind */
-
-/*
- * Renamed of violite.cc to violitexx.cc because of clashes
- * with violite.c
- * This file implements the same functions as in violite.c, but now using
- * the Vio class
- */
-
-#include "vio-global.h"
-
-Vio*
-vio_new(my_socket sd, enum_vio_type type, my_bool localhost)
-{
- return my_reinterpret_cast(Vio*) (new VioSocket(sd, type, localhost));
-}
-
-
-#ifdef __WIN32__
-Vio
-*vio_new_win32pipe(HANDLE hPipe)
-{
- return my_reinterpret_cast(Vio*) (new VioPipe(hPipe));
-}
-#endif
diff --git a/vio/violite.h b/vio/violite.h
deleted file mode 100644
index fc480f59db1..00000000000
--- a/vio/violite.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright Abandoned 2000 Monty Program KB
- This file is public domain and comes with NO WARRANTY of any kind */
-
-/*
- * Vio Lite.
- * Purpose: include file for Vio that will work with C and C++
- */
-
-#ifndef vio_violite_h_
-#define vio_violite_h_
-
-#include "my_net.h" /* needed because of struct in_addr */
-
-#ifdef HAVE_VIO
-#include <Vio.h> /* Full VIO interface */
-#else
-
-/* Simple vio interface in C; The functions are implemented in violite.c */
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#ifndef Vio_defined
-#define Vio_defined
-struct st_vio; /* Only C */
-typedef struct st_vio Vio;
-#endif
-
-enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
- VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
-
-Vio* vio_new(my_socket sd,
- enum enum_vio_type type,
- my_bool localhost);
-#ifdef __WIN__
-Vio* vio_new_win32pipe(HANDLE hPipe);
-#endif
-void vio_delete(Vio* vio);
-
-/*
- * vio_read and vio_write should have the same semantics
- * as read(2) and write(2).
- */
-int vio_read( Vio* vio,
- gptr buf, int size);
-int vio_write( Vio* vio,
- const gptr buf,
- int size);
-/*
- * Whenever the socket is set to blocking mode or not.
- */
-int vio_blocking( Vio* vio,
- my_bool onoff);
-my_bool vio_is_blocking( Vio* vio);
-/*
- * setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible.
- */
-int vio_fastsend( Vio* vio,
- my_bool onoff);
-/*
- * setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible.
- */
-int vio_keepalive( Vio* vio,
- my_bool onoff);
-/*
- * Whenever we should retry the last read/write operation.
- */
-my_bool vio_should_retry( Vio* vio);
-/*
- * When the workday is over...
- */
-int vio_close( Vio* vio);
-/*
- * Short text description of the socket for those, who are curious..
- */
-const char* vio_description( Vio* vio);
-
-/* Return the type of the connection */
- enum enum_vio_type vio_type(Vio* vio);
-
-/* Return last error number */
-int vio_errno(Vio *vio);
-
-/* Get socket number */
-my_socket vio_fd(Vio *vio);
-
-/*
- * Remote peer's address and name in text form.
- */
-my_bool vio_peer_addr(Vio * vio, char *buf);
-
-/* Remotes in_addr */
-
-void vio_in_addr(Vio *vio, struct in_addr *in);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* HAVE_VIO */
-#endif /* vio_violite_h_ */
diff --git a/vio/viosocket.c b/vio/viosocket.c
new file mode 100644
index 00000000000..ad156fc33bf
--- /dev/null
+++ b/vio/viosocket.c
@@ -0,0 +1,335 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Note that we can't have assertion on file descriptors; The reason for
+ this is that during mysql shutdown, another thread can close a file
+ we are working on. In this case we should just return read errors from
+ the file descriptior.
+*/
+
+#include "vio_priv.h"
+
+void vio_delete(Vio* vio)
+{
+ /* It must be safe to delete null pointers. */
+ /* This matches the semantics of C++'s delete operator. */
+ if (vio)
+ {
+ if (vio->type != VIO_CLOSED)
+ vio_close(vio);
+ my_free((gptr) vio,MYF(0));
+ }
+}
+
+int vio_errno(Vio *vio __attribute__((unused)))
+{
+ return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
+}
+
+
+int vio_read(Vio * vio, gptr buf, int size)
+{
+ int r;
+ DBUG_ENTER("vio_read");
+ DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
+#ifdef __WIN__
+ if (vio->type == VIO_TYPE_NAMEDPIPE)
+ {
+ DWORD length;
+ if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
+ DBUG_RETURN(-1);
+ DBUG_RETURN(length);
+ }
+ r = recv(vio->sd, buf, size,0);
+#else
+ errno=0; /* For linux */
+ r = read(vio->sd, buf, size);
+#endif /* __WIN__ */
+#ifndef DBUG_OFF
+ if (r < 0)
+ {
+ DBUG_PRINT("vio_error", ("Got error %d during read",errno));
+ }
+#endif /* DBUG_OFF */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_write(Vio * vio, const gptr buf, int size)
+{
+ int r;
+ DBUG_ENTER("vio_write");
+ DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
+#if defined( __WIN__)
+ if ( vio->type == VIO_TYPE_NAMEDPIPE)
+ {
+ DWORD length;
+ if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
+ DBUG_RETURN(-1);
+ DBUG_RETURN(length);
+ }
+ r = send(vio->sd, buf, size, 0);
+#else
+ r = write(vio->sd, buf, size);
+#endif /* __WIN__ */
+#ifndef DBUG_OFF
+ if (r < 0)
+ {
+ DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno));
+ }
+#endif /* DBUG_OFF */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode,
+ my_bool *old_mode)
+{
+ int r=0;
+ DBUG_ENTER("vio_blocking");
+
+ *old_mode= test(!(vio->fcntl_mode & O_NONBLOCK));
+ DBUG_PRINT("enter", ("set_blocking_mode: %d old_mode: %d",
+ (int) set_blocking_mode, (int) *old_mode));
+
+#if !defined(___WIN__) && !defined(__EMX__)
+#if !defined(NO_FCNTL_NONBLOCK)
+ if (vio->sd >= 0)
+ {
+ int old_fcntl=vio->fcntl_mode;
+ if (set_blocking_mode)
+ vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
+ else
+ vio->fcntl_mode |= O_NONBLOCK; /* set bit */
+ if (old_fcntl != vio->fcntl_mode)
+ r = fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
+ }
+#else
+ r= set_blocking_mode ? 0 : 1;
+#endif /* !defined(NO_FCNTL_NONBLOCK) */
+#else /* !defined(__WIN__) && !defined(__EMX__) */
+#ifndef __EMX__
+ if (vio->type != VIO_TYPE_NAMEDPIPE)
+#endif
+ {
+ ulong arg;
+ int old_fcntl=vio->fcntl_mode;
+ if (set_blocking_mode)
+ {
+ arg = 0;
+ vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
+ }
+ else
+ {
+ arg = 1;
+ vio->fcntl_mode |= O_NONBLOCK; /* set bit */
+ }
+ if (old_fcntl != vio->fcntl_mode)
+ r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
+ }
+#ifndef __EMX__
+ else
+ r= test(!(vio->fcntl_mode & O_NONBLOCK)) != set_blocking_mode;
+#endif /* __EMX__ */
+#endif /* !defined(__WIN__) && !defined(__EMX__) */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+my_bool
+vio_is_blocking(Vio * vio)
+{
+ my_bool r;
+ DBUG_ENTER("vio_is_blocking");
+ r = !(vio->fcntl_mode & O_NONBLOCK);
+ DBUG_PRINT("exit", ("%d", (int) r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_fastsend(Vio * vio __attribute__((unused)))
+{
+ int r=0;
+ DBUG_ENTER("vio_fastsend");
+
+#ifdef IPTOS_THROUGHPUT
+ {
+#ifndef __EMX__
+ int tos = IPTOS_THROUGHPUT;
+ if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
+#endif /* !__EMX__ */
+ {
+ int nodelay = 1;
+ if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
+ sizeof(nodelay))) {
+ DBUG_PRINT("warning",
+ ("Couldn't set socket option for fast send"));
+ r= -1;
+ }
+ }
+ }
+#endif /* IPTOS_THROUGHPUT */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+int vio_keepalive(Vio* vio, my_bool set_keep_alive)
+{
+ int r=0;
+ uint opt = 0;
+ DBUG_ENTER("vio_keepalive");
+ DBUG_PRINT("enter", ("sd=%d, set_keep_alive=%d", vio->sd, (int)
+ set_keep_alive));
+ if (vio->type != VIO_TYPE_NAMEDPIPE)
+ {
+ if (set_keep_alive)
+ opt = 1;
+ r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
+ sizeof(opt));
+ }
+ DBUG_RETURN(r);
+}
+
+
+my_bool
+vio_should_retry(Vio * vio __attribute__((unused)))
+{
+ int en = socket_errno;
+ return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
+ en == SOCKET_EWOULDBLOCK);
+}
+
+
+int vio_close(Vio * vio)
+{
+ int r;
+ DBUG_ENTER("vio_close");
+#ifdef __WIN__
+ if (vio->type == VIO_TYPE_NAMEDPIPE)
+ {
+#if defined(__NT__) && defined(MYSQL_SERVER)
+ CancelIo(vio->hPipe);
+ DisconnectNamedPipe(vio->hPipe);
+#endif
+ r=CloseHandle(vio->hPipe);
+ }
+ else if (vio->type != VIO_CLOSED)
+#endif /* __WIN__ */
+ {
+ r=0;
+ if (shutdown(vio->sd,2))
+ r= -1;
+ if (closesocket(vio->sd))
+ r= -1;
+ }
+ if (r)
+ {
+ DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno));
+ /* FIXME: error handling (not critical for MySQL) */
+ }
+ vio->type= VIO_CLOSED;
+ vio->sd= -1;
+ DBUG_RETURN(r);
+}
+
+
+const char *vio_description(Vio * vio)
+{
+ return vio->desc;
+}
+
+enum enum_vio_type vio_type(Vio* vio)
+{
+ return vio->type;
+}
+
+my_socket vio_fd(Vio* vio)
+{
+ return vio->sd;
+}
+
+
+my_bool vio_peer_addr(Vio * vio, char *buf, uint16 *port)
+{
+ DBUG_ENTER("vio_peer_addr");
+ DBUG_PRINT("enter", ("sd: %d", vio->sd));
+ if (vio->localhost)
+ {
+ strmov(buf,"127.0.0.1");
+ *port= 0;
+ }
+ else
+ {
+ size_socket addrLen = sizeof(struct sockaddr);
+ if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
+ &addrLen) != 0)
+ {
+ DBUG_PRINT("exit", ("getpeername gave error: %d", socket_errno));
+ DBUG_RETURN(1);
+ }
+ my_inet_ntoa(vio->remote.sin_addr,buf);
+ *port= ntohs(vio->remote.sin_port);
+ }
+ DBUG_PRINT("exit", ("addr: %s", buf));
+ DBUG_RETURN(0);
+}
+
+
+void vio_in_addr(Vio *vio, struct in_addr *in)
+{
+ DBUG_ENTER("vio_in_addr");
+ if (vio->localhost)
+ bzero((char*) in, sizeof(*in)); /* This should never be executed */
+ else
+ *in=vio->remote.sin_addr;
+ DBUG_VOID_RETURN;
+}
+
+
+/* Return 0 if there is data to be read */
+
+my_bool vio_poll_read(Vio *vio,uint timeout)
+{
+#ifndef HAVE_POLL
+ return 0;
+#else
+ struct pollfd fds;
+ int res;
+ DBUG_ENTER("vio_poll");
+ fds.fd=vio->sd;
+ fds.events=POLLIN;
+ fds.revents=0;
+ if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
+ {
+ DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
+ }
+ DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
+#endif
+}
+
+
+void vio_timeout(Vio *vio __attribute__((unused)),
+ uint timeout __attribute__((unused)))
+{
+#ifdef __WIN__
+ ulong wait_timeout= (ulong) timeout * 1000;
+ (void) setsockopt(vio->sd, SOL_SOCKET, SO_RCVTIMEO, (char*) &wait_timeout,
+ sizeof(wait_timeout));
+#endif /* __WIN__ */
+}
diff --git a/vio/viossl.c b/vio/viossl.c
new file mode 100644
index 00000000000..fafe48b7a84
--- /dev/null
+++ b/vio/viossl.c
@@ -0,0 +1,403 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Note that we can't have assertion on file descriptors; The reason for
+ this is that during mysql shutdown, another thread can close a file
+ we are working on. In this case we should just return read errors from
+ the file descriptior.
+*/
+
+#include "vio_priv.h"
+
+#ifdef HAVE_OPENSSL
+
+static void
+report_errors()
+{
+ unsigned long l;
+ const char* file;
+ const char* data;
+ int line,flags;
+ DBUG_ENTER("report_errors");
+
+ while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)))
+ {
+ char buf[512];
+ DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
+ file,line,(flags&ERR_TXT_STRING)?data:"")) ;
+ }
+ DBUG_PRINT("info", ("errno: %d", socket_errno));
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Delete a vio object
+
+ SYNPOSIS
+ vio_ssl_delete()
+ vio Vio object. May be 0.
+*/
+
+
+void vio_ssl_delete(Vio * vio)
+{
+ if (vio)
+ {
+ if (vio->type != VIO_CLOSED)
+ vio_close(vio);
+ my_free((gptr) vio,MYF(0));
+ }
+}
+
+
+int vio_ssl_errno(Vio *vio __attribute__((unused)))
+{
+ return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
+}
+
+
+int vio_ssl_read(Vio * vio, gptr buf, int size)
+{
+ int r;
+ DBUG_ENTER("vio_ssl_read");
+ DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d, ssl_=%p",
+ vio->sd, buf, size, vio->ssl_arg));
+
+ if ((r= SSL_read((SSL*) vio->ssl_arg, buf, size)) < 0)
+ {
+ int err= SSL_get_error((SSL*) vio->ssl_arg, r);
+ DBUG_PRINT("error",("SSL_read(): %d SSL_get_error(): %d", r, err));
+ report_errors();
+ }
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_ssl_write(Vio * vio, const gptr buf, int size)
+{
+ int r;
+ DBUG_ENTER("vio_ssl_write");
+ DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
+
+ if ((r= SSL_write((SSL*) vio->ssl_arg, buf, size)) < 0)
+ report_errors();
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_ssl_fastsend(Vio * vio __attribute__((unused)))
+{
+ int r= 0;
+ DBUG_ENTER("vio_ssl_fastsend");
+
+#ifdef IPTOS_THROUGHPUT
+ {
+#ifndef __EMX__
+ int tos = IPTOS_THROUGHPUT;
+ if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
+#endif /* !__EMX__ */
+ {
+ int nodelay = 1;
+ if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
+ sizeof(nodelay))) {
+ DBUG_PRINT("warning",
+ ("Couldn't set socket option for fast send"));
+ r= -1;
+ }
+ }
+ }
+#endif /* IPTOS_THROUGHPUT */
+ DBUG_PRINT("exit", ("%d", r));
+ DBUG_RETURN(r);
+}
+
+
+int vio_ssl_keepalive(Vio* vio, my_bool set_keep_alive)
+{
+ int r=0;
+ DBUG_ENTER("vio_ssl_keepalive");
+ DBUG_PRINT("enter", ("sd=%d, set_keep_alive=%d", vio->sd, (int)
+ set_keep_alive));
+ if (vio->type != VIO_TYPE_NAMEDPIPE)
+ {
+ uint opt = (set_keep_alive) ? 1 : 0;
+ r= setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
+ sizeof(opt));
+ }
+ DBUG_RETURN(r);
+}
+
+
+my_bool
+vio_ssl_should_retry(Vio * vio __attribute__((unused)))
+{
+ int en = socket_errno;
+ return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
+ en == SOCKET_EWOULDBLOCK);
+}
+
+
+int vio_ssl_close(Vio * vio)
+{
+ int r;
+ DBUG_ENTER("vio_ssl_close");
+ r=0;
+ if ((SSL*) vio->ssl_arg)
+ {
+ r = SSL_shutdown((SSL*) vio->ssl_arg);
+ SSL_free((SSL*) vio->ssl_arg);
+ vio->ssl_arg= 0;
+ }
+ if (vio->sd >= 0)
+ {
+ if (shutdown(vio->sd, 2))
+ r= -1;
+ if (closesocket(vio->sd))
+ r= -1;
+ }
+ if (r)
+ {
+ DBUG_PRINT("error", ("close() failed, error: %d",socket_errno));
+ report_errors();
+ /* FIXME: error handling (not critical for MySQL) */
+ }
+ vio->type= VIO_CLOSED;
+ vio->sd= -1;
+ DBUG_RETURN(r);
+}
+
+
+const char *vio_ssl_description(Vio * vio)
+{
+ return vio->desc;
+}
+
+enum enum_vio_type vio_ssl_type(Vio* vio)
+{
+ return vio->type;
+}
+
+my_socket vio_ssl_fd(Vio* vio)
+{
+ return vio->sd;
+}
+
+
+my_bool vio_ssl_peer_addr(Vio * vio, char *buf, uint16 *port)
+{
+ DBUG_ENTER("vio_ssl_peer_addr");
+ DBUG_PRINT("enter", ("sd=%d", vio->sd));
+ if (vio->localhost)
+ {
+ strmov(buf,"127.0.0.1");
+ *port=0;
+ }
+ else
+ {
+ size_socket addrLen = sizeof(struct sockaddr);
+ if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
+ &addrLen) != 0)
+ {
+ DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
+ DBUG_RETURN(1);
+ }
+#ifdef TO_BE_FIXED
+ my_inet_ntoa(vio->remote.sin_addr,buf);
+ *port= 0;
+#else
+ strmov(buf, "unknown");
+ *port= 0;
+#endif
+ }
+ DBUG_PRINT("exit", ("addr=%s", buf));
+ DBUG_RETURN(0);
+}
+
+
+void vio_ssl_in_addr(Vio *vio, struct in_addr *in)
+{
+ DBUG_ENTER("vio_ssl_in_addr");
+ if (vio->localhost)
+ bzero((char*) in, sizeof(*in)); /* This should never be executed */
+ else
+ *in=vio->remote.sin_addr;
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ TODO: Add documentation
+*/
+
+int sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout)
+{
+ char *str;
+ char buf[1024];
+ X509* client_cert;
+ my_bool unused;
+ my_bool net_blocking;
+ enum enum_vio_type old_type;
+ DBUG_ENTER("sslaccept");
+ DBUG_PRINT("enter", ("sd=%d ptr=%p", vio->sd,ptr));
+
+ old_type= vio->type;
+ net_blocking = vio_is_blocking(vio);
+ vio_blocking(vio, 1, &unused); /* Must be called before reset */
+ vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
+ vio->ssl_arg= 0;
+ if (!(vio->ssl_arg= (void*) SSL_new(ptr->ssl_context)))
+ {
+ DBUG_PRINT("error", ("SSL_new failure"));
+ report_errors();
+ vio_reset(vio, old_type,vio->sd,0,FALSE);
+ vio_blocking(vio, net_blocking, &unused);
+ DBUG_RETURN(1);
+ }
+ DBUG_PRINT("info", ("ssl_=%p timeout=%ld",(SSL*) vio->ssl_arg, timeout));
+ SSL_clear((SSL*) vio->ssl_arg);
+ SSL_SESSION_set_timeout(SSL_get_session((SSL*) vio->ssl_arg), timeout);
+ SSL_set_fd((SSL*) vio->ssl_arg,vio->sd);
+ SSL_set_accept_state((SSL*) vio->ssl_arg);
+ if (SSL_do_handshake((SSL*) vio->ssl_arg) < 1)
+ {
+ DBUG_PRINT("error", ("SSL_do_handshake failure"));
+ report_errors();
+ SSL_free((SSL*) vio->ssl_arg);
+ vio->ssl_arg= 0;
+ vio_reset(vio, old_type,vio->sd,0,FALSE);
+ vio_blocking(vio, net_blocking, &unused);
+ DBUG_RETURN(1);
+ }
+#ifndef DBUF_OFF
+ DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
+ ,SSL_get_cipher_name((SSL*) vio->ssl_arg)));
+ client_cert = SSL_get_peer_certificate ((SSL*) vio->ssl_arg);
+ if (client_cert != NULL)
+ {
+ DBUG_PRINT("info",("Client certificate:"));
+ str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
+ DBUG_PRINT("info",("\t subject: %s", str));
+ free (str);
+
+ str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0);
+ DBUG_PRINT("info",("\t issuer: %s", str));
+ free (str);
+
+ X509_free (client_cert);
+ }
+ else
+ DBUG_PRINT("info",("Client does not have certificate."));
+
+ str=SSL_get_shared_ciphers((SSL*) vio->ssl_arg, buf, sizeof(buf));
+ if (str)
+ {
+ DBUG_PRINT("info",("SSL_get_shared_ciphers() returned '%s'",str));
+ }
+ else
+ {
+ DBUG_PRINT("info",("no shared ciphers!"));
+ }
+
+#endif
+ DBUG_RETURN(0);
+}
+
+
+int sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout)
+{
+ char *str;
+ X509* server_cert;
+ my_bool unused;
+ my_bool net_blocking;
+ enum enum_vio_type old_type;
+ DBUG_ENTER("sslconnect");
+ DBUG_PRINT("enter", ("sd=%d ptr=%p ctx: %p", vio->sd,ptr,ptr->ssl_context));
+
+ old_type= vio->type;
+ net_blocking = vio_is_blocking(vio);
+ vio_blocking(vio, 1, &unused); /* Must be called before reset */
+ vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
+ vio->ssl_arg= 0;
+ if (!(vio->ssl_arg = SSL_new(ptr->ssl_context)))
+ {
+ DBUG_PRINT("error", ("SSL_new failure"));
+ report_errors();
+ vio_reset(vio, old_type,vio->sd,0,FALSE);
+ vio_blocking(vio, net_blocking, &unused);
+ DBUG_RETURN(1);
+ }
+ DBUG_PRINT("info", ("ssl_=%p timeout=%ld",(SSL*) vio->ssl_arg, timeout));
+ SSL_clear((SSL*) vio->ssl_arg);
+ SSL_SESSION_set_timeout(SSL_get_session((SSL*) vio->ssl_arg), timeout);
+ SSL_set_fd ((SSL*) vio->ssl_arg, vio->sd);
+ SSL_set_connect_state((SSL*) vio->ssl_arg);
+ if (SSL_do_handshake((SSL*) vio->ssl_arg) < 1)
+ {
+ DBUG_PRINT("error", ("SSL_do_handshake failure"));
+ report_errors();
+ SSL_free((SSL*) vio->ssl_arg);
+ vio->ssl_arg= 0;
+ vio_reset(vio, old_type,vio->sd,0,FALSE);
+ vio_blocking(vio, net_blocking, &unused);
+ DBUG_RETURN(1);
+ }
+#ifndef DBUG_OFF
+ DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
+ ,SSL_get_cipher_name((SSL*) vio->ssl_arg)));
+ server_cert = SSL_get_peer_certificate ((SSL*) vio->ssl_arg);
+ if (server_cert != NULL)
+ {
+ DBUG_PRINT("info",("Server certificate:"));
+ str = X509_NAME_oneline (X509_get_subject_name (server_cert), 0, 0);
+ DBUG_PRINT("info",("\t subject: %s", str));
+ free(str);
+
+ str = X509_NAME_oneline (X509_get_issuer_name (server_cert), 0, 0);
+ DBUG_PRINT("info",("\t issuer: %s", str));
+ free(str);
+
+ /*
+ We could do all sorts of certificate verification stuff here before
+ deallocating the certificate.
+ */
+ X509_free (server_cert);
+ }
+ else
+ DBUG_PRINT("info",("Server does not have certificate."));
+#endif
+ DBUG_RETURN(0);
+}
+
+
+int vio_ssl_blocking(Vio * vio __attribute__((unused)),
+ my_bool set_blocking_mode,
+ my_bool *old_mode)
+{
+ /* Return error if we try to change to non_blocking mode */
+ *old_mode=1; /* Mode is always blocking */
+ return set_blocking_mode ? 0 : 1;
+}
+
+
+void vio_ssl_timeout(Vio *vio __attribute__((unused)),
+ uint timeout __attribute__((unused)))
+{
+ /* Not yet implemented (non critical) */
+}
+#endif /* HAVE_OPENSSL */
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
new file mode 100644
index 00000000000..0997e3909db
--- /dev/null
+++ b/vio/viosslfactories.c
@@ -0,0 +1,360 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "vio_priv.h"
+
+#ifdef HAVE_OPENSSL
+
+static bool ssl_algorithms_added = FALSE;
+static bool ssl_error_strings_loaded= FALSE;
+static int verify_depth = 0;
+static int verify_error = X509_V_OK;
+
+static unsigned char dh512_p[]=
+{
+ 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
+ 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
+ 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
+ 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
+ 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
+ 0x47,0x74,0xE8,0x33,
+};
+
+static unsigned char dh512_g[]={
+ 0x02,
+};
+
+static DH *get_dh512(void)
+{
+ DH *dh;
+ if ((dh=DH_new()))
+ {
+ dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
+ dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
+ if (! dh->p || ! dh->g)
+ {
+ DH_free(dh);
+ dh=0;
+ }
+ }
+ return(dh);
+}
+
+
+static void
+report_errors()
+{
+ unsigned long l;
+ const char* file;
+ const char* data;
+ int line,flags;
+
+ DBUG_ENTER("report_errors");
+
+ while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
+ {
+#ifndef DBUG_OFF /* Avoid warning */
+ char buf[200];
+ DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
+ file,line,(flags & ERR_TXT_STRING) ? data : "")) ;
+#endif
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+static int
+vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
+{
+ DBUG_ENTER("vio_set_cert_stuff");
+ DBUG_PRINT("enter", ("ctx=%p, cert_file=%s, key_file=%s",
+ ctx, cert_file, key_file));
+ if (cert_file != NULL)
+ {
+ if (SSL_CTX_use_certificate_file(ctx,cert_file,SSL_FILETYPE_PEM) <= 0)
+ {
+ DBUG_PRINT("error",("unable to get certificate from '%s'\n",cert_file));
+ /* FIX stderr */
+ fprintf(stderr,"Error when connection to server using SSL:");
+ ERR_print_errors_fp(stderr);
+ fprintf(stderr,"Unable to get certificate from '%s'\n", cert_file);
+ fflush(stderr);
+ DBUG_RETURN(0);
+ }
+ if (key_file == NULL)
+ key_file = cert_file;
+ if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
+ SSL_FILETYPE_PEM) <= 0)
+ {
+ DBUG_PRINT("error", ("unable to get private key from '%s'\n",key_file));
+ /* FIX stderr */
+ fprintf(stderr,"Error when connection to server using SSL:");
+ ERR_print_errors_fp(stderr);
+ fprintf(stderr,"Unable to get private key from '%s'\n", cert_file);
+ fflush(stderr);
+ DBUG_RETURN(0);
+ }
+
+ /*
+ If we are using DSA, we can copy the parameters from the private key
+ Now we know that a key and cert have been set against the SSL context
+ */
+ if (!SSL_CTX_check_private_key(ctx))
+ {
+ DBUG_PRINT("error",
+ ("Private key does not match the certificate public key\n"));
+ DBUG_RETURN(0);
+ }
+ }
+ DBUG_RETURN(1);
+}
+
+
+static int
+vio_verify_callback(int ok, X509_STORE_CTX *ctx)
+{
+ char buf[256];
+ X509* err_cert;
+ int err,depth;
+
+ DBUG_ENTER("vio_verify_callback");
+ DBUG_PRINT("enter", ("ok=%d, ctx=%p", ok, ctx));
+ err_cert=X509_STORE_CTX_get_current_cert(ctx);
+ err= X509_STORE_CTX_get_error(ctx);
+ depth= X509_STORE_CTX_get_error_depth(ctx);
+
+ X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf));
+ if (!ok)
+ {
+ DBUG_PRINT("error",("verify error: num: %d : '%s'\n",err,
+ X509_verify_cert_error_string(err)));
+ if (verify_depth >= depth)
+ {
+ ok=1;
+ verify_error=X509_V_OK;
+ }
+ else
+ {
+ verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ }
+ }
+ switch (ctx->error) {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
+ DBUG_PRINT("info",("issuer= %s\n",buf));
+ break;
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ DBUG_PRINT("error", ("notBefore"));
+ /*ASN1_TIME_print_fp(stderr,X509_get_notBefore(ctx->current_cert));*/
+ break;
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ DBUG_PRINT("error", ("notAfter error"));
+ /*ASN1_TIME_print_fp(stderr,X509_get_notAfter(ctx->current_cert));*/
+ break;
+ }
+ DBUG_PRINT("exit", ("%d", ok));
+ DBUG_RETURN(ok);
+}
+
+
+/************************ VioSSLConnectorFd **********************************/
+/*
+ TODO:
+ Add option --verify to mysql to be able to change verification mode
+*/
+
+struct st_VioSSLConnectorFd *
+new_VioSSLConnectorFd(const char* key_file,
+ const char* cert_file,
+ const char* ca_file,
+ const char* ca_path,
+ const char* cipher)
+{
+ int verify = SSL_VERIFY_NONE;
+ struct st_VioSSLConnectorFd* ptr;
+ int result;
+ DH *dh=NULL;
+ DBUG_ENTER("new_VioSSLConnectorFd");
+ DBUG_PRINT("enter",
+ ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s",
+ key_file, cert_file, ca_path, ca_file, cipher));
+
+ if (!(ptr=((struct st_VioSSLConnectorFd*)
+ my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0)))))
+ DBUG_RETURN(0);
+
+ ptr->ssl_context= 0;
+ ptr->ssl_method= 0;
+ /* FIXME: constants! */
+
+ if (!ssl_algorithms_added)
+ {
+ DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
+ ssl_algorithms_added = TRUE;
+ OpenSSL_add_all_algorithms();
+ }
+ if (!ssl_error_strings_loaded)
+ {
+ DBUG_PRINT("info", ("todo:SSL_load_error_strings()"));
+ ssl_error_strings_loaded = TRUE;
+ SSL_load_error_strings();
+ }
+ ptr->ssl_method = TLSv1_client_method();
+ ptr->ssl_context = SSL_CTX_new(ptr->ssl_method);
+ DBUG_PRINT("info", ("ssl_context: %p",ptr->ssl_context));
+ if (ptr->ssl_context == 0)
+ {
+ DBUG_PRINT("error", ("SSL_CTX_new failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ /*
+ SSL_CTX_set_options
+ SSL_CTX_set_info_callback
+ */
+ if (cipher)
+ {
+ result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher);
+ DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
+ }
+ SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback);
+ if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1)
+ {
+ DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file,ca_path) == 0)
+ {
+ DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
+ if (SSL_CTX_set_default_verify_paths(ptr->ssl_context) == 0)
+ {
+ DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ }
+
+ /* DH stuff */
+ dh=get_dh512();
+ SSL_CTX_set_tmp_dh(ptr->ssl_context,dh);
+ DH_free(dh);
+
+ DBUG_RETURN(ptr);
+ctor_failure:
+ DBUG_PRINT("exit", ("there was an error"));
+ my_free((gptr)ptr,MYF(0));
+ DBUG_RETURN(0);
+}
+
+
+/************************ VioSSLAcceptorFd **********************************/
+/*
+ TODO:
+ Add option --verify to mysqld to be able to change verification mode
+*/
+struct st_VioSSLAcceptorFd*
+new_VioSSLAcceptorFd(const char *key_file,
+ const char *cert_file,
+ const char *ca_file,
+ const char *ca_path,
+ const char *cipher)
+{
+ int verify = (SSL_VERIFY_PEER |
+ SSL_VERIFY_CLIENT_ONCE);
+ struct st_VioSSLAcceptorFd* ptr;
+ int result;
+ DH *dh=NULL;
+ DBUG_ENTER("new_VioSSLAcceptorFd");
+ DBUG_PRINT("enter",
+ ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s",
+ key_file, cert_file, ca_path, ca_file, cipher));
+
+ ptr= ((struct st_VioSSLAcceptorFd*)
+ my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0)));
+ ptr->ssl_context=0;
+ ptr->ssl_method=0;
+ /* FIXME: constants! */
+ ptr->session_id_context= ptr;
+
+ if (!ssl_algorithms_added)
+ {
+ DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
+ ssl_algorithms_added = TRUE;
+ OpenSSL_add_all_algorithms();
+
+ }
+ if (!ssl_error_strings_loaded)
+ {
+ DBUG_PRINT("info", ("todo: SSL_load_error_strings()"));
+ ssl_error_strings_loaded = TRUE;
+ SSL_load_error_strings();
+ }
+ ptr->ssl_method= TLSv1_server_method();
+ ptr->ssl_context= SSL_CTX_new(ptr->ssl_method);
+ if (ptr->ssl_context == 0)
+ {
+ DBUG_PRINT("error", ("SSL_CTX_new failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ if (cipher)
+ {
+ result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher);
+ DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
+ }
+ /* SSL_CTX_set_quiet_shutdown(ctx,1); */
+ SSL_CTX_sess_set_cache_size(ptr->ssl_context,128);
+
+ /* DH? */
+ SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback);
+ SSL_CTX_set_session_id_context(ptr->ssl_context,
+ (const uchar*) &(ptr->session_id_context),
+ sizeof(ptr->session_id_context));
+
+ /*
+ SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
+ */
+ if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1)
+ {
+ DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file, ca_path) == 0)
+ {
+ DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
+ if (SSL_CTX_set_default_verify_paths(ptr->ssl_context)==0)
+ {
+ DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
+ report_errors();
+ goto ctor_failure;
+ }
+ }
+ /* DH stuff */
+ dh=get_dh512();
+ SSL_CTX_set_tmp_dh(ptr->ssl_context,dh);
+ DH_free(dh);
+ DBUG_RETURN(ptr);
+
+ctor_failure:
+ DBUG_PRINT("exit", ("there was an error"));
+ my_free((gptr) ptr,MYF(0));
+ DBUG_RETURN(0);
+}
+#endif /* HAVE_OPENSSL */
diff --git a/vio/viotest-ssl.c b/vio/viotest-ssl.c
new file mode 100644
index 00000000000..b4a191a1e2f
--- /dev/null
+++ b/vio/viotest-ssl.c
@@ -0,0 +1,152 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#ifdef HAVE_OPENSSL
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+#include "mysql.h"
+#include "errmsg.h"
+#include <my_dir.h>
+#include <my_getopt.h>
+#include <signal.h>
+#include <violite.h>
+
+const char *VER="0.2";
+
+
+#ifndef DBUG_OFF
+const char *default_dbug_option="d:t:O,/tmp/viotest-ssl.trace";
+#endif
+
+void
+fatal_error(const char *r)
+{
+ perror(r);
+ exit(0);
+}
+
+void
+print_usage()
+{
+ printf("viossl-test: testing SSL virtual IO. Usage:\n");
+ printf("viossl-test server-key server-cert client-key client-cert [CAfile] [CApath]\n");
+}
+
+
+int main(int argc, char **argv)
+{
+ char* server_key = 0;
+ char* server_cert = 0;
+ char* client_key = 0;
+ char* client_cert = 0;
+ char* ca_file = 0;
+ char* ca_path = 0;
+ int child_pid,sv[2];
+ struct st_VioSSLAcceptorFd* ssl_acceptor=0;
+ struct st_VioSSLConnectorFd* ssl_connector=0;
+ Vio* client_vio=0;
+ Vio* server_vio=0;
+ MY_INIT(argv[0]);
+ DBUG_PROCESS(argv[0]);
+ DBUG_PUSH(default_dbug_option);
+
+ if (argc<5)
+ {
+ print_usage();
+ return 1;
+ }
+
+ server_key = argv[1];
+ server_cert = argv[2];
+ client_key = argv[3];
+ client_cert = argv[4];
+ if (argc>5)
+ ca_file = argv[5];
+ if (argc>6)
+ ca_path = argv[6];
+ printf("Server key/cert : %s/%s\n", server_key, server_cert);
+ printf("Client key/cert : %s/%s\n", client_key, client_cert);
+ if (ca_file!=0)
+ printf("CAfile : %s\n", ca_file);
+ if (ca_path!=0)
+ printf("CApath : %s\n", ca_path);
+
+
+ if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1)
+ fatal_error("socketpair");
+
+ ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file,
+ ca_path);
+ ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file,
+ ca_path);
+
+ client_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0));
+ client_vio->sd = sv[0];
+ sslconnect(ssl_connector,client_vio);
+ server_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0));
+ server_vio->sd = sv[1];
+ sslaccept(ssl_acceptor,server_vio);
+
+ printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd);
+
+ child_pid = fork();
+ if (child_pid==-1)
+ {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("fork");
+ }
+ if (child_pid==0)
+ {
+ /* child, therefore, client */
+ char xbuf[100];
+ int r = vio_ssl_read(client_vio,xbuf, sizeof(xbuf));
+ if (r<=0) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("client:SSL_read");
+ }
+ xbuf[r] = 0;
+ printf("client:got %s\n", xbuf);
+ my_free((gptr)client_vio,MYF(0));
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ sleep(1);
+ }
+ else
+ {
+ const char* s = "Huhuhuh";
+ int r = vio_ssl_write(server_vio,(gptr)s, strlen(s));
+ if (r<=0) {
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ fatal_error("server:SSL_write");
+ }
+ my_free((gptr)server_vio,MYF(0));
+ my_free((gptr)ssl_acceptor,MYF(0));
+ my_free((gptr)ssl_connector,MYF(0));
+ sleep(1);
+ }
+ return 0;
+}
+#else /* HAVE_OPENSSL */
+
+int main() {
+return 0;
+}
+#endif /* HAVE_OPENSSL */
diff --git a/vio/viotest-ssl.cc b/vio/viotest-ssl.cc
deleted file mode 100644
index a3ad92a7c9c..00000000000
--- a/vio/viotest-ssl.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "all.h"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdio.h>
-#include <unistd.h>
-
-
-void
-fatal_error( const char* r)
-{
- perror(r);
- exit(0);
-}
-
-void
-print_usage()
-{
- printf("viossltest: testing SSL virtual IO. Usage:\n");
- printf("viossltest server-key server-cert client-key client-cert [CAfile] [CApath]\n");
-}
-
-int
-main( int argc,
- char** argv)
-{
- char* server_key = 0;
- char* server_cert = 0;
- char* client_key = 0;
- char* client_cert = 0;
- char* ca_file = 0;
- char* ca_path = 0;
- int sv[2];
-
- if (argc<5)
- {
- print_usage();
- return 1;
- }
-
- if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1)
- fatal_error("socketpair");
-
- server_key = argv[1];
- server_cert = argv[2];
- client_key = argv[3];
- client_cert = argv[4];
- if (argc>5)
- ca_file = argv[5];
- if (argc>6)
- ca_path = argv[6];
- printf("Server key/cert : %s/%s\n", server_key, server_cert);
- printf("Client key/cert : %s/%s\n", client_key, client_cert);
- if (ca_file!=0)
- printf("CAfile : %s\n", ca_file);
- if (ca_path!=0)
- printf("CApath : %s\n", ca_path);
-
- VIO_NS::VioSSLAcceptorFd* ssl_acceptor = new VIO_NS::VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path);
- VIO_NS::VioSSLConnectorFd* ssl_connector = new VIO_NS::VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path);
-
- printf("Socketpair: %d , %d\n", sv[0], sv[1]);
-
- VIO_NS::VioSSL* client_vio = ssl_connector->connect(sv[0]);
- VIO_NS::VioSSL* server_vio = ssl_acceptor->accept(sv[1]);
-
-
- int child_pid = fork();
- if (child_pid==-1) {
- delete ssl_acceptor;
- delete ssl_connector;
- fatal_error("fork");
- }
- if (child_pid==0) {
- //child, therefore, client
- char xbuf[100];
- int r = client_vio->read(xbuf, sizeof(xbuf));
- if (r<=0) {
- delete ssl_acceptor;
- delete ssl_connector;
- fatal_error("client:SSL_read");
- }
- printf("*** client cipher %s\n",client_vio->cipher_description());
- xbuf[r] = 0;
- printf("client:got %s\n", xbuf);
- delete client_vio;
- delete ssl_acceptor;
- delete ssl_connector;
- sleep(1);
- } else {
- const char* s = "Huhuhuh";
- int r = server_vio->write((void *)s, strlen(s));
- if (r<=0) {
- delete ssl_acceptor;
- delete ssl_connector;
- fatal_error("server:SSL_write");
- }
- printf("*** server cipher %s\n",server_vio->cipher_description());
- delete server_vio;
- delete ssl_acceptor;
- delete ssl_connector;
- sleep(1);
- }
-}
diff --git a/vio/viotypes.h b/vio/viotypes.h
deleted file mode 100644
index 8d36a35c86f..00000000000
--- a/vio/viotypes.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-** Virtual I/O library
-** Written by Andrei Errapart <andreie@no.spam.ee>
-*/
-
-/*
- * Some typedefs to external types.
- */
-#ifndef vio_viotypes_h_
-#define vio_viotypes_h_
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-typedef int vio_bool_t;
-typedef void* vio_ptr_t;
-
-#ifdef __cplusplus
-VIO_NS_BEGIN
-
-typedef vio_ptr_t vio_ptr;
-typedef char* vio_cstring;
-typedef int32_t vio_int32;
-typedef u_int32_t vio_uint32;
-typedef vio_bool_t vio_bool;
-
-VIO_NS_END
-#endif /* __cplusplus */
-
-#endif /* vio_types_h_ */
-